From 02de1cd2f11b3c0b86afaf6bdabb327f49ca5e21 Mon Sep 17 00:00:00 2001 From: Guus Sliepen Date: Mon, 26 Aug 2019 13:44:49 +0200 Subject: [PATCH 01/13] Import Upstream version 1.1~pre2 --- COPYING | 2 +- ChangeLog | 14433 +++++++++++++--- INSTALL | 317 +- Makefile.am | 20 +- Makefile.in | 475 +- NEWS | 248 +- README | 95 +- README.android | 25 - THANKS | 77 +- aclocal.m4 | 1005 +- compile | 348 - config.guess | 929 +- config.h.in | 119 +- config.sub | 463 +- configure | 3761 ++-- configure.ac | 247 - configure.in | 177 + depcomp | 531 +- doc/Makefile.am | 51 +- doc/Makefile.in | 405 +- doc/sample-config.tar.gz | Bin 0 -> 1246 bytes doc/sample-config/hosts/alpha | 15 - doc/sample-config/hosts/beta | 16 - doc/sample-config/rsa_key.priv | 1 - doc/sample-config/tinc-down | 4 - doc/sample-config/tinc-up | 11 - doc/sample-config/tinc.conf | 22 - doc/texinfo.tex | 7136 +++----- doc/tinc-gui.8.in | 57 + doc/tinc.conf.5.in | 335 +- doc/tinc.info | 2035 ++- doc/tinc.texi | 780 +- doc/tincctl.8.in | 194 + doc/tincd.8.in | 67 +- doc/tincinclude.texi | 5 - doc/tincinclude.texi.in | 1 - gui/Makefile.am | 3 + {systemd => gui}/Makefile.in | 258 +- gui/tinc-gui | 537 + src/have.h => have.h | 42 +- install-sh | 406 +- m4/Makefile.am | 4 + m4/Makefile.in | 335 + m4/README | 8 + m4/attribute.m4 | 4 +- m4/ax_append_flag.m4 | 69 - m4/ax_cflags_warn_all.m4 | 122 - m4/ax_check_compile_flag.m4 | 72 - m4/ax_check_link_flag.m4 | 71 - m4/ax_require_defined.m4 | 37 - m4/curses.m4 | 41 + m4/libevent.m4 | 33 + m4/openssl.m4 | 24 +- missing | 463 +- src/Makefile.am | 101 +- src/Makefile.in | 728 +- src/avl_tree.c | 757 - src/avl_tree.h | 142 - src/bsd/device.c | 578 +- src/bsd/tunemu.c | 233 +- src/bsd/tunemu.h | 8 +- src/buffer.c | 108 + src/buffer.h | 18 + src/conf.c | 410 +- src/conf.h | 52 +- src/connection.c | 143 +- src/connection.h | 135 +- src/control.c | 182 + src/control.h | 27 + src/control_common.h | 46 + src/cygwin/device.c | 118 +- src/device.h | 36 +- src/dropin.c | 45 +- src/dropin.h | 16 +- src/dummy_device.c | 66 - src/edge.c | 56 +- src/edge.h | 36 +- src/ethernet.h | 36 +- src/event.c | 121 - src/fake-gai-errnos.h | 19 + src/fake-getaddrinfo.c | 54 +- src/fake-getaddrinfo.h | 36 +- src/fake-getnameinfo.c | 30 +- src/fake-getnameinfo.h | 8 +- src/gcrypt/cipher.c | 280 + src/gcrypt/cipher.h | 52 + src/gcrypt/crypto.c | 34 + src/gcrypt/crypto.h | 27 + src/gcrypt/digest.c | 173 + src/gcrypt/digest.h | 45 + src/gcrypt/rsa.c | 302 + src/gcrypt/rsa.h | 39 + src/gcrypt/rsagen.c | 220 + src/gcrypt/rsagen.h | 29 + src/getopt.c | 1321 +- src/getopt.h | 151 +- src/getopt1.c | 182 +- src/graph.c | 311 +- src/graph.h | 10 +- src/ipv4.h | 32 +- src/ipv6.h | 30 +- src/linux/device.c | 236 +- src/list.c | 77 +- src/list.h | 38 +- src/logger.c | 150 +- src/logger.h | 47 +- src/meta.c | 247 +- src/meta.h | 15 +- src/mingw/common.h | 2 +- src/mingw/device.c | 185 +- src/multicast_device.c | 247 - src/net.c | 729 +- src/net.h | 81 +- src/net_packet.c | 552 +- src/net_setup.c | 1119 +- src/net_socket.c | 487 +- src/netutl.c | 177 +- src/netutl.h | 37 +- src/node.c | 133 +- src/node.h | 117 +- src/openssl/cipher.c | 146 + src/openssl/cipher.h | 46 + src/openssl/crypto.c | 43 + src/openssl/crypto.h | 27 + src/openssl/digest.c | 124 + src/openssl/digest.h | 45 + src/openssl/ecdh.c | 84 + src/{proxy.h => openssl/ecdh.h} | 33 +- src/openssl/ecdsa.c | 130 + src/openssl/ecdsa.h | 37 + src/openssl/ecdsagen.c | 75 + src/openssl/ecdsagen.h | 30 + src/openssl/prf.c | 76 + src/openssl/prf.h | 25 + src/openssl/rsa.c | 101 + src/{event.h => openssl/rsa.h} | 39 +- src/openssl/rsagen.c | 83 + src/openssl/rsagen.h | 29 + src/pidfile.c | 142 - src/pidfile.h | 57 - src/process.c | 559 +- src/process.h | 13 +- src/protocol.c | 165 +- src/protocol.h | 101 +- src/protocol_auth.c | 620 +- src/protocol_edge.c | 107 +- src/protocol_key.c | 349 +- src/protocol_misc.c | 95 +- src/protocol_subnet.c | 88 +- src/proxy.c | 366 - .../device.c} | 86 +- src/route.c | 1055 +- src/route.h | 22 +- src/solaris/device.c | 395 +- src/splay_tree.c | 561 + src/splay_tree.h | 107 + src/subnet.c | 416 +- src/subnet.h | 49 +- src/tincctl.c | 833 + src/tincctl.h | 27 + src/tincd.c | 694 +- src/top.c | 319 + src/top.h | 26 + src/{uml_device.c => uml_socket/device.c} | 222 +- src/utils.c | 145 +- src/utils.h | 24 +- src/vde_device.c | 147 - src/xalloc.h | 53 +- src/system.h => system.h | 16 +- systemd/Makefile.am | 18 - systemd/tinc.service.in | 20 - systemd/tinc@.service.in | 20 - 172 files changed, 32291 insertions(+), 25994 deletions(-) delete mode 100644 README.android delete mode 100755 compile delete mode 100644 configure.ac create mode 100644 configure.in create mode 100644 doc/sample-config.tar.gz delete mode 100644 doc/sample-config/hosts/alpha delete mode 100644 doc/sample-config/hosts/beta delete mode 100644 doc/sample-config/rsa_key.priv delete mode 100644 doc/sample-config/tinc-down delete mode 100644 doc/sample-config/tinc-up delete mode 100644 doc/sample-config/tinc.conf create mode 100644 doc/tinc-gui.8.in create mode 100644 doc/tincctl.8.in delete mode 100644 doc/tincinclude.texi create mode 100644 gui/Makefile.am rename {systemd => gui}/Makefile.in (58%) create mode 100755 gui/tinc-gui rename src/have.h => have.h (88%) create mode 100644 m4/Makefile.am create mode 100644 m4/Makefile.in create mode 100644 m4/README delete mode 100644 m4/ax_append_flag.m4 delete mode 100644 m4/ax_cflags_warn_all.m4 delete mode 100644 m4/ax_check_compile_flag.m4 delete mode 100644 m4/ax_check_link_flag.m4 delete mode 100644 m4/ax_require_defined.m4 create mode 100644 m4/curses.m4 create mode 100644 m4/libevent.m4 delete mode 100644 src/avl_tree.c delete mode 100644 src/avl_tree.h create mode 100644 src/buffer.c create mode 100644 src/buffer.h create mode 100644 src/control.c create mode 100644 src/control.h create mode 100644 src/control_common.h delete mode 100644 src/dummy_device.c delete mode 100644 src/event.c create mode 100644 src/fake-gai-errnos.h create mode 100644 src/gcrypt/cipher.c create mode 100644 src/gcrypt/cipher.h create mode 100644 src/gcrypt/crypto.c create mode 100644 src/gcrypt/crypto.h create mode 100644 src/gcrypt/digest.c create mode 100644 src/gcrypt/digest.h create mode 100644 src/gcrypt/rsa.c create mode 100644 src/gcrypt/rsa.h create mode 100644 src/gcrypt/rsagen.c create mode 100644 src/gcrypt/rsagen.h delete mode 100644 src/multicast_device.c create mode 100644 src/openssl/cipher.c create mode 100644 src/openssl/cipher.h create mode 100644 src/openssl/crypto.c create mode 100644 src/openssl/crypto.h create mode 100644 src/openssl/digest.c create mode 100644 src/openssl/digest.h create mode 100644 src/openssl/ecdh.c rename src/{proxy.h => openssl/ecdh.h} (58%) create mode 100644 src/openssl/ecdsa.c create mode 100644 src/openssl/ecdsa.h create mode 100644 src/openssl/ecdsagen.c create mode 100644 src/openssl/ecdsagen.h create mode 100644 src/openssl/prf.c create mode 100644 src/openssl/prf.h create mode 100644 src/openssl/rsa.c rename src/{event.h => openssl/rsa.h} (50%) create mode 100644 src/openssl/rsagen.c create mode 100644 src/openssl/rsagen.h delete mode 100644 src/pidfile.c delete mode 100644 src/pidfile.h delete mode 100644 src/proxy.c rename src/{raw_socket_device.c => raw_socket/device.c} (61%) create mode 100644 src/splay_tree.c create mode 100644 src/splay_tree.h create mode 100644 src/tincctl.c create mode 100644 src/tincctl.h create mode 100644 src/top.c create mode 100644 src/top.h rename src/{uml_device.c => uml_socket/device.c} (53%) delete mode 100644 src/vde_device.c rename src/system.h => system.h (85%) delete mode 100644 systemd/Makefile.am delete mode 100644 systemd/tinc.service.in delete mode 100644 systemd/tinc@.service.in diff --git a/COPYING b/COPYING index 1a88dcf..74fe22a 100644 --- a/COPYING +++ b/COPYING @@ -1,4 +1,4 @@ -Copyright (C) 1998-2018 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/ChangeLog b/ChangeLog index f2f43d9..859f691 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,2201 +1,12234 @@ -Version 1.0.35 October 05 2018 ------------------------------------------------------------------------- - -Guus Sliepen (12): - Prevent oracle attacks (CVE-2018-16737, CVE-2018-16738) - Prevent a MITM from forcing a NULL cipher for UDP (CVE-2018-16758) - Check the return value from snprintf(). - Check the return values from BN_hex2bn() and RAND_load_file(). - Fix all warnings when compiling with -Wall -W -pedantic. - Fix two small memory leaks. - Don't check for NULL-pointers before calling free(). - Update THANKS. - Fix checks for Cygwin-related macros. - Fix spelling errors. - Update README and links to required libraries. - Releasing 1.0.35. - -AMRI Amine (1): - Fixing typo - -Rafael Sadowski (1): - OpenBSD has a proper tap device. - -Version 1.0.34 June 12 2018 ------------------------------------------------------------------------- - -Guus Sliepen (10): - Add missing thanks to the NEWS message. - Fix building documentation when using OpenBSD's make. - Fix #ifdefs that were broken due to commit d178b58. - Don't use SOL_IP and SOL_IPV6. - Make systemd service file handling identical to tinc 1.1. - Rename distro/ to systemd/. - Document how to enable tinc at boot time using systemd. - Fix all spelling errors found by codespell. - Properly implement tinc.texi's dependency on tincinclude.texi. - Releasing 1.0.34. - -Maximilian Stein (1): - Fix SEGFAULT when trying to connect to IPv6 peer in non-IPv6 environment - -wangliushuai (1): - Remove redundant 'break'. - -Version 1.0.33 November 04 2017 ------------------------------------------------------------------------- - -Guus Sliepen (31): - Udpate THANKS. - Fix a potential memory leak. - Use AC_CONFIG_MACRO_DIR(). - Give absolute path for #include to AC_CHECK_HEADERS(). - Prepare for automatic code formatting using Artistic Style. - Never remove items from cmdline_conf. - Use stack-allocated strings for temporary filenames. - Fix a few minor memory leaks. - Remove unused/obsolete checks from configure.ac. - Use getcwd() instead of get_current_dir_name(). - Remove xmalloc.c, backport xalloc.h from tinc 1.1. - Update all header guards. - Convert sizeof foo to sizeof(foo). - Reformat all code using astyle. - Don't call ERR_remove_state(). - Unconditionally include stdbool.h and inttypes.h. - Remove more obsolete autoconf checks. - Remove obsolete m4/README. - Fix some "make distcheck" errors. - Add some information about the requirements of a chroot environment. - Handle tun/tap device returning EPERM or EBUSY. - Disable PMTU discovery when TCPOnly is used. - Fix all -Wall -W compiler warnings. - Realign comments. - Remove unused functions. - Ensure all parameters have names in header files. - Support autoconf's --runstatedir option. - Const correctness. - Fix compilation errors when --enable-uml is used. - Update THANKS. - Releasing 1.0.33. - -Rafael Sadowski (1): - fix tinc.conf for OpenBSD - -nemunaire (1): - Allow compilation from a build directory - -Version 1.0.32 September 02 2017 ------------------------------------------------------------------------- - -Guus Sliepen (13): - Don't dereference myself->incipher if it's NULL. - Merge remote-tracking branch 'VittGam/master' - Use /dev/udp instead of /dev/ip on Solaris. - Use getmsg()/putmsg() instead of read()/write() on Solaris. - Fix Solaris DeviceType = tap in router Mode. - Bind outgoing TCP sockets. - Move logging of "would block" messages to debug level 4. - Set KillMode=mixed in the systemd service file. - Don't forget about outgoing connections on host file read errors. - Fix Proxy = exec. - Set status.proxy_passed early for Proxy = exec. - Don't try to bind Proxy = exec sockets to an address. - Releasing 1.0.32. - -Vittorio Gambaletta (VittGam) (1): - route: Support ToS/DiffServ priority inheritance when routing IPv6 packets. - -Version 1.0.31 January 15 2017 ------------------------------------------------------------------------- - -Guus Sliepen (1): - Releasing 1.0.31. - -Élie Bouttier (1): - Remove ExecStop in tinc@.service - -Version 1.0.30 October 30 2016 ------------------------------------------------------------------------- - -Guus Sliepen (11): - Allow non-empty lines after status code from a HTTP proxy. - Fix proxy reply parsing broken by the previous commit. - Log only the first line of a proxy request rejection message. - Delay sending the real ID request until after a proxy request is granted. - Use AES256 and SHA256 by default, also for the meta-connections. - Enforce maximum amount of bytes sent/received on meta-connections. - Fix bit shifting arithmetic so the code actually does what the last commit message says. - Really fix byte budget calculation. - Use AES in CTR mode instead of OFB mode for meta-connections. - Use CFB mode for meta-connections to improve security. - Releasing 1.0.30. - -Version 1.0.29 October 09 2016 ------------------------------------------------------------------------- - -Guus Sliepen (11): - Preserve IPv6 scope_id in edges. - Ensure compatibility with OpenSSL 1.1.0. - Add -Wall to CFLAGS. - Check return value of RSA_generate_key_ex(). - Force nul-termination of strings after vsnprintf(). - Log warnings about dropped packets only with debug level 5 or higher. - Add a copy of ax_append_flag.m4. - Add ax_require_defined.m4. - Fix possibly unitialized variable. - Fix compiler warnings about format string errors on BSD. - Releasing 1.0.29. - -Version 1.0.28 April 10 2016 ------------------------------------------------------------------------- - -Guus Sliepen (8): - Fix compiling bsd/device.c on systems without utun. - Really remove use of __DATE__ and __TIME__ to facilitate reproducible builds. - Add systemd service files. - Update .gitignore. - Ensure the service files are in the tarball. - Explicitly mention that LibreSSL can be used as well. - Update links in the documentation. - Releasing 1.0.28. - -Version 1.0.27 April 10 2016 ------------------------------------------------------------------------- - -Guus Sliepen (26): - Add missing AM_PROG_CC_C_O to configure.ac. - Attribution for various contributors. - Update "now" after connect() when making outgoing connections. - Add ability to use proxies to connect to hostnames when there is no nameserver. - Only add a reflexive address when we're sure it's working. - Fix compatibility with TAP-Win32 9.0.0.21 and later. - Fix warnings from the Clang Static Analyzer. - Improve performance of edge updates. - Clarify that scripts are called synchronously. - Small fixes for the documentation. - Add warnings for bad combinations of Device and Interface. - Fix forwarding of edge updates. - Don't compile getopt*.c if the system provides getopt_long(). - Update .gitignore. - Update THANKS. - Use iface instead of interface. - Update copyright notices. - Remove use of __DATE__ and __TIME__ to facilitate reproducible builds. - Cast 0xff to char before comparing it to another char. - Get rid of a warning when compiling tinc using MinGW. - Every BSD flavor has a tap device nowadays. - Use devname() if available to support devfs cloning on BSD. - Use SIOCGIFADDR on BSDs that support it. - Enable silent builds by default. - Add support for OS X utun interfaces. - Releasing 1.0.27. - -Vittorio Gambaletta (VittGam) (6): - Fix DecrementTTL option. - Fix source IP address for ICMP unreachable packets generated by tinc. - Try to reply with node address only when decrementing the TTL. - Fix DecrementTTL option for packets destined to the local node. - s/broadcast_packet_helper/route_broadcast/ - Remove forward declaration for do_decrement_ttl. - -LunarShaddow (3): - fix typo - re-arrange include sequence to avoid a mingw introduced bug. - Proofing README. - -Florian Weik (1): - Fix NAME variable in subnet-* scripts for local subnets. - -Nathan Stratton Treadway (1): - Fix invalid checksum generation. - -Version 1.0.26 July 05 2015 ------------------------------------------------------------------------- - -Guus Sliepen (14): - Use VittGam's real name. - Attribution for Saverio Proto. - Always call res_init() before getaddrinfo(). - Fix --logfile without a filename on Windows. - Never call putenv() with data on the stack. - Return non-zero exit code when encountering configuration errors during startup. - Fix autoconf check for function attributes. - Fix spelling of FORTIFY_SOURCE. - Update copyright notices. - Attribution for various contributors. - Only check for -fno-strict-overflow if -fwrapv does not work. - Fix unputenv() on Windows. - Don't try to call res_init() if ./configure told us it doesn't exist. - Releasing 1.0.26. - -Jo-Philipp Wich (1): - fix musl compatibility - -Version 1.0.25 December 22 2014 ------------------------------------------------------------------------- - -Guus Sliepen (7): - Fix date of last NEWS entry. - Remember ToS/Diffserv priority for each socket individually. - Attribution for various contributors. - Automatically choose a tap device on Mac OS X when using switch Mode. - Update documentation for Mac OS X. - Check whether res_init() really lives in libresolv. - Releasing 1.0.25. - -Borg (3): - Fixed scripts calling under Win32. - Get MAC of TAP device. - Fixed tinc-up script calling on Win32. - -Alexis Hildebrandt (1): - Add support to link against libresolv Mac OS X - -Baptiste Jonglez (1): - Use the description from the 1.1 man page for the IndirectData option - -David Pflug (1): - Update README.android - -Jochen Voss (1): - Fix some typos in the manual. - -Tomislav Čohar (1): - Configure minimum reconnect timeouts. - -VittGam (1): - Support ToS/DiffServ priority handling for IPv6 meta and UDP connections. - -Version 1.0.24 May 11 2014 ------------------------------------------------------------------------- - -Guus Sliepen (13): - Remove useless variable 'hard' from try_harder(). - Merge pull request #14 from luckyhacky/master - Add an autoconf check for res_init(). - Nexthop calculation should always use the shortest path. - Fix issues found by Coverity. - Fix warnings found by GCC 4.9. - Fix a few more issues found by Coverity. - Fix a few more issues found by Coverity. - Drop h and hh length modifiers from printf format strings. - Fix a bug that could prevent tinc from starting correctly on Windows. - FIx the autoconf checks for res_init(). - Remove the warnings when IP_DONTFRAGMENT/IPV6-DONTFRAG is not supported. - Releasing 1.0.24. - -Steffan Karger (3): - Use constant time memcmp() when comparing packet HMACs. - Use cryptographically strong random when generating keys. - Check RAND_bytes() return value, fail when getting random fails. - -Armin Fisslthaler (1): - reload /etc/resolv.conf in SIGALRM handler - -Loic Dachary (1): - fix documentation typo - -luckyhacky (1): - update to openssl version 1.0.1g due to lack of heartbleed bug in prior version of openssl - -refs/tags/1.0.23-android-1 March 11 2014 ------------------------------------------------------------------------- - -Guus Sliepen (13): - Mention in the manual that multiple Address staments are allowed. - If no Port is specified, set myport to actual port of first listening socket. - Enable compiler hardening flags by default. - Update support for Solaris. - Include for PATH_MAX. - Stricter check for raw socket support. - Use hardcoded value for TUNNEWPPA if net/if_tun.h is missing on Solaris. - Fix incorrectly merged bits from 80cd2ff73071941a5356555b85a00ee90dfd0e16. - Don't enable -fstack-protector-all. - Remove or lower the priority of some debug messages. - Clarify StrictSubnets. - Attribution for various contributors. - Handle errors from TAP-Win32/64 adapter in a better way. - -Florent Clairambault (2): - Adding "conf.d" configuration dir support. - Adding some documentation around the /etc/tinc/$NET/conf.d directory. - -Vilbrekin (1): - Update android build instructions. Disable PIE as this is not supported on some devices. - -Version 1.0.23 October 19 2013 ------------------------------------------------------------------------- - -Guus Sliepen (9): - Check for writability when waiting for a socket to finish connecting. - Don't send PING requests on connections which are not active yet. - Fix segfault when Name = $HOST but $HOST is not set. - Fix typos in the documentation. - Modernize the build system. - Get rid of the splay tree implementation. - Add description of IffOneQueue and MaxTimeout to the info manual. - Clean up child processes from proxy type exec. - Releasing 1.0.23. - -Version 1.0.22 August 13 2013 ------------------------------------------------------------------------- - -Guus Sliepen (7): - Better optional argument handling. - Fix a typo. - Set $NAME when calling host-up/down and subnet-up/down scripts. - Don't use vasprintf() anymore on Windows. - Don't echo broadcast packets back when Broadcast = direct. - Update copyright notices. - Releasing 1.0.22. - -Etienne Dechamps (1): - Fix combination of Mode = router and DeviceType = tap on Linux. - -Version 1.0.21 April 22 2013 ------------------------------------------------------------------------- - -Guus Sliepen (2): - Drop packets forwarded via TCP if they are too big (CVE-2013-1428). - Releasing 1.0.21. - -Version 1.0.20 March 03 2013 ------------------------------------------------------------------------- - -Guus Sliepen (30): - Use /dev/tap0 by default on FreeBSD and NetBSD when using Mode = switch. - Document how to load the tap driver on FreeBSD. - Update THANKS file. - Also clarify hostnames=[yes|no] in tinc.conf(5). - Attribution for Vil Brekin and some code style cleanups. - Don't ignore Makefile.am. - Fix links in documenation. - Attribution for Martin Schürrer. - Add strict checks to hex to binary conversions. - Clear connection options and status fields in free_connection_partially(). - Fix warnings from cppcheck. - Clear Ethernet header when reading packets from a tun device. - Clear status and options fields of unreachable nodes. - Fix warnings from groff. - Using alloca() for a constant sized buffer is very silly. - Make sure PMTU discovery works in switch mode with VLAN tags. - Mention in the manual that support for LZO and zlib can be disabled. - Fix configure script help text for --enable options. - Don't take the address of a variable whose scope is about to disappear. - Send broadcast packets using a random socket, and properly support IPv6. - Remove text saying you must have one of PrivateKey or PrivateKeyFile in tinc.conf. - Fix support for tunemu on iOS devices. - Make sure PriorityInheritance also works in switch mode. - Detect increases in PMTU. - Fix a compiler warning. - Fix segmentation fault when trying to connect via a SOCKS5 proxy. - Don't send proxy requests for incoming connections. - Fix compiler warnings on Windows. - Fix detection of rejected SOCKS5 proxy requests. - Releasing 1.0.20. - -Vilbrekin (5): - Basic patch for android cross-compilation. - Replace hard-code with new ScriptsInterpreter configuration property. - Add basic .gitignore file, cleaning (most) files generated by autotools. - Use __ANDROID__ define rather than dirty hard-code to allow android NDK cross-compilation. - Android cross-compilation instructions. - -Martin Schürrer (1): - Output details of encryption errors - -Mesar Hameed (1): - Minor clarification, tinc.conf hostnames=[yes|no] variable only resolves names for logging purposes. - -Version 1.0.19 June 25 2012 ------------------------------------------------------------------------- - -Guus Sliepen (14): - Support :: in IPv6 Subnets. - Remove newline from log message. - Add support for systemd style socket activation. - Allow environment variables to be used for Name. - Allow broadcast packets to be sent directly instead of via the MST. - Add basic support for SOCKS 4 and HTTP CONNECT proxies. - Add support for SOCKS 5 proxies. - Add support for proxying through an external command. - Document new proxy types. - Small fixes in proxy code. - #include on Windows. - Fix compiler warnings. - Fix crash when using Broadcast = direct. - Releasing 1.0.19. - -Anthony G. Basile (1): - configure.in: fix AC_ARG_ENABLE and AC_ARG_WITH - -Michael Tokarev (1): - add (errnum) in front of windows error messages - -Version 1.0.18 March 25 2012 ------------------------------------------------------------------------- - -Guus Sliepen (13): - Always try next Address when an outgoing connection fails to authenticate. - Allow a port to be specified in BindToAddress statements. - Add support for multicast communication with UML/QEMU/KVM. - Set default value of DecrementTTL to "no". - Add #ifdefs in case not all platforms support IPv4 and IPv6 multicast. - Allow scoped addresses to be used for IPv6 multicast socket. - Fix compiler warnings. - Fix return value type of vde_send(). - Fix some more compiler warnings. - Document OpenBSD "ifconfig link0" and Linux "ip tuntap" commands. - Fix return type of vde_recv() as well. - Mark DecrementTTL option experimental. - Releasing 1.0.18. - -Version 1.0.17 March 10 2012 ------------------------------------------------------------------------- - -Guus Sliepen (32): - Prevent read_rsa_public_key() from returning an uninitialized RSA structure. - Return false instead of void when there is an error. - Fix compilation of VDE and UML interfaces. - Add vde/device.c to the tarball. - Fix a few small memory leaks. - Allow linking with multiple device drivers. - Set FD_CLOEXEC flag on all sockets. - Allow multiple BindToAddress statements. - Merge branch 'master' of black:tinc - Send packets back using the same socket as they were received on. - Allow setting DeviceType to tun or tap on Linux. - Merge branch 'master' of black:tinc - Only compile raw socket code when it is supported on that platform. - Decrement TTL of incoming packets. - Don't bind outgoing TCP sockets anymore. - Rename connection_t *broadcast to everyone. - Allow disabling of broadcast packets. - Move initialization of char *priority up to prevent freeing an uninitialized pointer. - Document the command line flag -o and provide --option as well. - Fix a bug that caused tinc to ignore all but the last listening socket. - Fix check for raw socket support. - Pass index into listen_socket[] to handle_incoming_vpn_data(). - Add LocalDiscovery option which tries to detect peers on the local network. - Don't send ICMP Time Exceeded messages for other Time Exceeded messages. - Stricter checks against routing loops. - Only use broadcast at the start of the PMTU discovery phase. - Only log errors sending UDP packets when debug level >= 5. - Accept Subnets passed with the -o option when StrictSubnets = yes. - Add missing ICMP6 message type definitions. - Make sure disabling old RSA keys works on Windows. - Update copyright notices. - Releasing 1.0.17. - -Nick Hibma (1): - Add missing ICMP message type definitions. - -Version 1.0.16 July 23 2011 ------------------------------------------------------------------------- - -Guus Sliepen (4): - Make code to detect two nodes with the same Name less triggerhappy. - Flush output buffer in send_tcppacket(). - Use usleep() instead of sleep(), MinGW complained. - Releasing 1.0.16. - -Version 1.0.15 June 24 2011 ------------------------------------------------------------------------- - -Guus Sliepen (9): - Reorder checks for libraries to allow ./configure LDFLAGS=-static. - Make return value of SetPriorityClass() behave the same as setpriority(). - Fix sparse warnings and add an extra sprinkling of const. - Remove newlines from log messages. - Remove a few unnecessary #includes. - Attribution for Loïc Grenié. - Improved --logfile option. - Remove redundant @CFLAGS@ from AM_CFLAGS. - Releasing 1.0.15. - -Loïc Grenié (1): - Nearly tickless tinc. - -Version 1.0.14 May 08 2011 ------------------------------------------------------------------------- - -Guus Sliepen (48): - Fix reading configuration files that do not end with a newline. Again. - Define WINVER before including any other header file on Windows. - Use intptr_t instead of long to store a pointer. - OpenSSL 1.0.0 compiled for 64 bit Windows requires linking with -lcrypt32. - Fix all warnings when compiling with mingw64. - Use strrchr() insteaad of rindex(). - Detect and prevent two nodes with the same Name being on the VPN simultaneously. - Use 64 bit counters to keep track of bytes sent/received from the virtual network interface. - Do not append an address to ANS_KEY messages if we don't know any address. - Merge local host configuration with server configuration. - Remove duplicate command-line option parsing. - Attribution for Julien Muchembled. - Attribution for Timothy Redaelli. - Ensure there is a newline character before a PEM key is written. - Abort disabling old PEM keys on I/O errors. - Remove unused variables. - Quit when there are too many consecutive errors on the tun/tap device. - Read error counter must be static. - Add short options -R and -U to the tincd(8) manpage. - Don't use strlen() on a NULL pointer. - Provide usleep() for Windows. - Use variable length arrays instead of alloca(). - Fix warning message when setting SO_RCVBUF or SO_SNDBUF fails. - Free replay window when freeing a node_t. - Fix variable length array declaration. - Attribution for Brandon Black. - Use setpriority() instead of nice() on UNIX-like systems. - Always send MTU probes at least once every PingInterval. - Close all filedescriptors in Solaris close_device(). - Limit field width when scanning PID file. - Replace bogus #else with #endif. - Remove unused variables. - Document the behavior of "-n." - Update the manual. - Update the NEWS. - Proper check and dropin replacement for usleep(). - Fix typo spotted by Andrew Scheller. - Add support for VDE through libvdeplug. - Fix spurious misidentification of incoming UDP packets. - Prevent anything from updating our own UDP address. - Do not set indirect flag on edges from nodes with multiple addresses. - Increase threshold for detecting two nodes with the same Name. - Always use the default signal handler for ABRT signals. - Check for EVP_EncryptInit_ex instead of SHA1_Version in OpenSSL. - Update THANKS and copyright information. - Ensure proper linking with OpenSSL with recent versions of MinGW. - Include when using intptr_t. - Releasing 1.0.14. - -Brandon L Black (4): - Experimental IFF_ONE_QUEUE support for Linux - Configurable SO_RCVBUF/SO_SNDBUF for the UDP socket - Configurable ReplayWindow size, zero disables - Improved handling of queue-jumping packets on receive - -Julien Muchembled (2): - New '-o' option to configure server or hosts from command line - Fix command-line '-o' option for host configuration - -Timothy Redaelli (2): - Fix warnings showed using -D_FORTIFY_SOURCE=2 - Fix warnings under BSD - -Michael Tokarev (1): - Treat netname="." in a special way. - -Rumko (1): - DragonFlyBSD support - -Version 1.0.13 April 11 2010 ------------------------------------------------------------------------- - -Guus Sliepen (20): - Clamp MSS to miminum MTU in both directions. - Simplify reading lines from configuration files. - Check for dirent.h. - Preload all Subnets in TunnelServer mode. - Add the StrictSubnets option. - Add the Forwarding option. - Add the DirectOnly option. - Fixes for the Forwarding option. - ConnectTo does not mean tinc does not listen for incoming connections anymore. - Log unauthorized Subnets when StrictSubnets is set. - Fix typo. - Convert Port to numeric form before sending it to other nodes. - Ensure ICMP_NET_ANO is defined. - Reload Subnets when getting a HUP signal and StrictSubnets is used. - Fix reloading Subnets when StrictSubnets is set. - Ensure subnet-up/down scripts are called after HUP when necessary. - Fixes for definitions under Windows. - Don't redefine MAX if it already exists. - Mark Forwarding and DirectOnly options as being experimental. - Releasing 1.0.13. - -Timothy Redaelli (2): - Add --disable-lzo configure option - Add --disable-zlib configure option - -Sven-Haegar Koch (1): - Never delete Subnets when StrictSubnets is set - -Version 1.0.12 February 03 2010 ------------------------------------------------------------------------- - -Guus Sliepen (21): - When learning MAC addresses, only check our own Subnets for previous entries. - Remove unused variable in lookup_subnet_*() functions. - Forget addresses of unreachable nodes. - Do not fragment packets smaller than RFC defined minimum MTUs. - Allow port to be specified in Address statements. - Use xstrdup() instead of xasprintf() to copy static strings. - Allow Port and PMTUDiscovery options in tinc.conf, always enable PMTUDiscovery by default. - Clamp MSS of IPv4 SYN packets. - Ping nodes immediately when receiving SIGALRM. - Optimise handling of select() returning <= 0. - Also clamp MSS of TCP over IPv6 packets. - Make MSS clamping configurable, but enabled by default. - Fix subnet-up/down scripts being called with an empty SUBNET. - Run subnet-up/down scripts for local MAC addresses as well. - Be liberal in accepting KEY_CHANGED/REQ_KEY/ANS_KEY requests. - Determine peer's reflexive address and port when exchanging keys. - Immediately exchange keys when establishing a meta connection. - Try to set DF bit on BSDs as well. - Update copyright notices. - Ensure peers with a meta connection always have our key. - Releasing 1.0.12. - -Version 1.0.11 November 01 2009 ------------------------------------------------------------------------- - -Guus Sliepen (16): - Fix a possible crash when sending the HUP signal. - Starting to work towards 1.0.11. - Handle weighted Subnets in switch and hub modes. - Clarify and increase level of log message about MTU probes to unreachable nodes. - Add dummy device. - Use uint32_t instead of long int for connection options. - Allow UDP packets with an address different from the corresponding TCP connection. - Always reply to MTU probes via UDP. - Make maxmtu equal to minmtu when fixing the path MTU to a node. - Forward packets to not directly reachable hosts via UDP if possible. - Use IP_DONTFRAGMENT instead of IP_MTU_DISCOVER on Windows. - Use WSAGetLastError() to determine cause of network errors on Windows. - Move socket error interpretation to utils.h. - Fast handoff of roaming MAC addresses. - Start a tinc service if it already exists. - Releasing 1.0.11. - -Michael Tokarev (1): - Remove localedir leftovers. - -Version 1.0.10 October 18 2009 ------------------------------------------------------------------------- - -Guus Sliepen (78): - Update documentation for git. - Consistently allocate device and iface variables on the heap. - Only send packets via UDP if UDP communication is possible. - Move free()s at the end om main() to the proper destructor functions. - Change flush_events() to expire_events(). - Add missing cleanup functions in close_network_connections(). - Use a global list to track outgoing connections. - Remove unused definitions from net.h. - Allow reading config files with CRLF endings on Unix systems. - Validate Name before using it in a filename when generating a keypair. - Disable old RSA keys when generating new ones. - Handle neighbor solicitation requests without link layer addresses. - Allow weight to be assigned to Subnets. - Update THANKS and copyright information. - Disable PMTUDiscovery in switch and hub modes. - Use a simple Random Early Drop algorithm in send_tcppacket(). - Handle UDP packets from different and ports than advertised. - If PMTUDiscovery is not set, do not forward packets via TCP unnecessarily. - Fix link to Mattias Nissler's tun/tap driver for MacOS/X. - Fix initialisation of packet decryption context broken by commit 3308d13e7e3bf20cfeaf6f2ab17228a9820cea66. - Use xrealloc instead of if(ptr) ptr = xmalloc(). - Add declaration for sockaddrcmp_noport(). - Use packet size before decompression to calculate path MTU. - Do not forward broadcast packets when TunnelServer is enabled. - Add ProcessPriority option. - Add some const where appropriate. - Properly set HMAC length for incoming packets. - Don't try to send MTU probes to unreachable nodes. - Remove pending MTU probe events when a node's reachability status changes. - Do not log errors when recvfrom() returns EAGAIN or EINTR. - Change level of some debug messages, zero pointer after freeing hostname. - Always remove a node from the UDP tree before freeing it. - Add xasprintf() and xvasprintf(). - Check the return value of fscanf() when reading a PID file. - Replace asprintf() by xasprintf(). - UNIX signal numbers start at 1. - Ensure tinc compiles with gcc -std=c99. - Convert bitfields to integers in a safe way. - Add the GPL license to the repository. - Another safe bitfield conversion. - Add support for iPhones and recent iPods. - Don't stat() on iPhone/iPod. - Put Subnet weight in a separate environment variable. - Allow PMTUDiscovery in switch and hub modes again. - Handle unicast packets larger than PMTU in switch mode. - Remove superfluous call to avl_delete(). - Apparently it's impolite to ask GCC to subtract two pointers. - Use only rand(), not random(). - Also do not use drand48(), it is not available on Windows. - Allow compiling for Windows XP and higher. - Remove dropin random() function, as it is not used anymore. - Use access() instead of stat() for checking whether scripts exist. - Raise default crypto algorithms to AES256 and SHA256. - Remove extra {. - Use a mutex to allow the TAP reader to process packets faster on Windows. - Raise default RSA key length to 2048 bits. - Send large packets we cannot handle properly via TCP. - Update copyright information. - Remove all occurences of $Id$. - Remove Ivo's old email addresses. - Update the address of the Free Software Foundation in all copyright headers. - K&R style braces. - Remove checkpoint tracing. - Drop support for localisation. - Add more authors to the copyright headers. - Update the NEWS. - Remove autogenerated files from EXTRA_DIST. - Don't disconnect clients in TunnelServer mode who send unauthorised ADD_SUBNETs. - Remove code duplication when checking ADD_EDGE/DEL_EDGE messages. - Revert "Raise default crypto algorithms to AES256 and SHA256." - Ensure that the texinfo manual can be converted to HTML. - Small updates to the documentation. - Use MTU probes to regularly ping other nodes over UDP. - Allow the cloning /dev/tap interface to be used on FreeBSD and NetBSD. - Remove debugging message when reading packets from a BSD device. - Include missing header. - Fix description of the WEIGHT environment variable. - Releasing 1.0.10. - -Michael Tokarev (17): - Allow tunnelserver to work with clients that have other peers. - Enable PMTUDiscovery only if BOTH sides wants it. - Rename setup_network_connections() and split out try_outgoing_connections() - Implement privilege dropping - bugfix: initialize pid (as read from pidfile) to zero - bugfix: move mlock to after detach() so it works for child, not parent - bugfix: chdir(/) after chroot - change error messages in droppriv code to match the rest - format 'not supported on this platform' error message - TunnelServer: Don't disconnect client on DEL_SUBNET too - ignore indirect edge registrations in tunnelserver mode - don't log every strange packet coming to the UDP port - Fix ans_key exchange in recent changes - tunnelserver: log which ADD_SUBNET was refused - cleanup setpriority thing to make it readable - try outgoing connections before chroot/drop_privs - Remove extra semicolon in my definition of setpriority() - -Florian Forster (2): - src/linux/device.c: Fix segfault when running without `--net'. - src/net_socket.c: Bind outgoing TCP sockets to `BindToAddress'. - -Borg (1): - Removed last gettext function. - -Version 1.0.9 December 26 2008 ------------------------------------------------------------------------- - -Guus Sliepen (18): - Handle SERVICE_CONTROL_INTERROGATE requests. Thanks to Carsten Ralle for noticing this. - Make sure the prefixlength of subnets is sane. - Fix reading configuration files that do not end with a newline. - Do not try to send REQ_KEY or ANS_KEY requests to unreachable nodes. - Prevent freeing a NULL pointer when a hostname is unresolvable. - Correct debug message. - Treat virtual network device as tap if Mode = switch or hub. - Use TUNIFHEAD by default on FreeBSD to make sure IPv6 works. - Make sure IPv6 sockets are IPv6 only. - Update Dutch translation. - Update copyright information. - Enable PMTU discovery by default. - Update documentation. - Update the manpage as well, and some whitespace to make its source more legible. - Handle broadcast and multicast packets in router mode. - Apply patch from Max Rijevski fixing a memory leak when closing connections. - Add missing parentheses in check for IPv4 multicast addresses. - Releasing 1.0.9. - -Version 1.0.8 May 16 2007 ------------------------------------------------------------------------- - -Guus Sliepen (8): - Apply patch from Scott Lamb preventing an infinite loop when sending SIGALRM. - Apply patch from Scott Lamb fixing some memory and resource leaks. - Close the proper filedescriptor (if it exists). - Apply patch from "dnk" making sockets non-blocking under Windows. - Make sure connection->name is never NULL. - Update dutch translation. - Don't free struct addrinfo too early. Spotted by Christian Cier-Zniewski. - Releasing 1.0.8. - -Version 1.0.7 January 05 2007 ------------------------------------------------------------------------- - -Guus Sliepen (7): - Use a ringbuffer in shared memory to transfer packets from the tapreader thread to the main thread. - Tapreader socket should be bound to localhost only. - Fix generic BSD tun device to write only the actual packet length. - rename() cannot replace existing files on Windows. - No things to do for the 1.0 branch except bugfixing. - Update copyright notices. - Releasing 1.0.7. - -Version 1.0.6 December 18 2006 ------------------------------------------------------------------------- - -Guus Sliepen (13): - Make sure resolved addressed for outgoing connections are freed, if there are any. - Search for lzo/lzo1x.h, lzo2/lzo1x.h and lzo1x.h. - When building the minimum spanning tree, make sure we start from a reachable node. - Use the correct next pointer. - Remove unnecessary stuff from configure.in. - Remove old Spanish translation. - Fix rule that creates html version of manpages. - Use standard autoconf macros instead of our own. - We do properly check for malloc and realloc. - Remove the test for linux/if_tun.h. - Do a simple test for linux/if_tun.h instead of no test at all. - Prevent compiler warnings about redefinition of EAI_FAMILY on FreeBSD 6.1. - Releasing 1.0.6. - -Version 1.0.5 November 14 2006 ------------------------------------------------------------------------- - -Guus Sliepen (32): - Prevent possible buffer overflows when using very large (>= 8192 bit) RSA keys. - Add alloca.h to the list of necessary header files. - Enable OpenSSL ENGINE, so crypto hardware gets used. Thanks to Andreas van Cranenburgh. - EVP_Cleanup() when quitting. - Apply patch from Scott Lamb unifying configuration of TCP socket options. - Apply patch from Scott Lamb adding an output buffer for the TCP sockets. - Make sure $NAME is set correctly when executing tinc-down script. - Missing #include. - Export flush_meta(). - Fix signedness compiler warnings. - Fix a bug in handling prefixlengths that are not a multiple of 4. - Update copyright notices, remove Ivo's email address. - Restore length of the original packet in send_udppacket(). - Use memcpy() to copy sockaddrs returned by getaddrinfo(). - Add generic host-up and host-down scripts. - Do not break strict aliasing of status_t structs. - Fix format string warnings. - Remove unused variables. - Remove unused parameter from maskcmp(). - Remove unused variable. - memcpy() addresses from packet headers before calling the lookup functions. - The "active" bit in node.status is not used. - Added graph dumping ability based on Markus Goetz's patch. - popen() requires pclose(). - Support and autodetect LZO version 2.0 and later. - Support and autodetect LZO version 2.0 and later. - Document GraphDumpFile option. - Update Dutch translation. - Nodes use events, so event system should be initialised first and destroyed last. - When deleting an entire tree, start at head, not at root. - EWOULDBLOCK does not exist on platforms without O_NONBLOCK - Releasing 1.0.5. - -Version 1.0.4 May 04 2005 ------------------------------------------------------------------------- - -Guus Sliepen (17): - Make sure broadcast packet reach the local network interface. - Fix splay tree code. - subnet-up/down hooks - subnet-up/down hooks, use list_t for the todo list. - Small fix. - Free memory used by connection_t after it is deleted from the connection tree. - Use the proper free function. - Correct size argument for strncat(). - Nodes should only be in the node_udp_tree if they are reachable. - Don't try to add a non-existing node back to the node_udp_tree. - Remove unused (and potentially segfaulting) net2str() call. - Be on the safe side with initialisation of c->name. - Searching through splay trees may change the tree variable. - Several splay tree fixes. - Describe subnet-up/down scripts in documentation. - Update copyright notices. - Releasing 1.0.4. - -Version 1.0.3 November 11 2004 ------------------------------------------------------------------------- - -Guus Sliepen (77): - Removed items in TODO list that are already implemented. Only two items - Applied patch from Jamie Briggs for bash2 conformance. - Added another semicolon for bash2 compliance (thanks to Jamie Briggs) - Adding even more stuff from the CABAL branch. - Synchronise HEAD with CABAL branch. - This will become 2.0. - Some device.c files weren't synchronised. - Makevars file was accidentily removed. - Forgot to synchronise po/ directory... - Add description of new authentication scheme. - Add Opaque option which prevent information from being forwarded to certain nodes. - Replace Opaque and Strict options with a TunnelServer option. - Complain if pid file cannot be created. - Read MaxTimeout from tinc.conf like the manpage says. - Missing space between words. - Don't retry if configuration is wrong from the beginning. - Fix proxy-neighborsolicitation. - Code beautification, start of multicast support. - Forget multicast. Always inline some function. - Let tinc figure out the exact MTU of the link. - More sensible name, and try to set PMTU discovery on IPv6 sockets as well. - Describe the TunnelServer and PMTUDiscovery options. - Better name, show probed MTU in dump. - Improvements for PMTU discovery and IPv4 packet fragmentation. - Missing definitions. - Small fixes for PMTU discovery. - Don't forget to update destination MAC address. - Small updates. - Remove autogen.sh, the autoreconf program does exactly that. - Replace cvs-clean with a much better svn-clean. - Remove CVS related cruft. - Eat trailing whitespace in config files. - Only read our public key if it wasn't already in the private key file. - Updating dutch translation. - Even better svn-clean command. - Applied Martin Kihlgren's IdentityGenerosity patch, - Fix declaration of update_node_address(). - Use Subversion to create ChangeLog, better svn-clean rule. - Revert Martin Kihlgren's patch, it doesn't work the way it should. - Move CABAL branch to its rightful place: the trunk. - Update copyrights, links, email addresses and let Subversion update $Id$ keywords. - Increase MTU by 4 bytes to allow VLAN tagged Ethernet frames in hub and switch mode. - Clean up environment after executing scripts. - Handle timeouts during connecting the same way as other errors. - Added UML network socket handling. - Don't set $INTERFACE automatically, don't quit on EINTR/EAGAIN. - Marking potential late packets was in the wrong place. - Remove duplicate #include "system.h" - Move all #ifdef HAVE_HEADER_H #include to have.h, - Fix several #includes. - strndupa() is too arcane for some environments. - Allow tinc to work with the latest TAP-Win32 driver. - Correct return value. - Don't let tinc service depend on NDIS component. - Support alternative tun/tap driver from http://www-user.rhrk.uni-kl.de/~nissler/tuntap/ - Generic device driver for *BSD and MacOS/X - static - Check for sys/uio.h, net/if_tun.h and net/if_tap.h - Don't include .svn directory in sample configuration. - Splay trees. - Hoopjumping to get the default directories in the manuals properly. - Update to make it compile again. - Fixed another bug in late packet handling. - Hopefully this really fixes late packet handling. - Missing check for NULL-pointer. - Use the generic BSD tun/tap code. - Fix order of arguments for tar. - Let compiler decide when to inline. - Support tunneling IPv6 on Solaris. - Add BlockingTCP option, useful when using TCPOnly on slow or congested links. - Update documentation. - Set BSD tuns to broadcast mode. On OpenBSD, this enables IPv6 on the tun device! - Remove duplication. - Updated dutch translation. - Short readme about how to compile tinc from a Subversion checkout. - Add more people who have contributed to tinc. - Releasing 1.0.3. - -Ivo Timmermans (52): - Check for __gmpz_powm for libgmp3. - Changed version number to 1.0pre3. - Autogenerated by gettextize. - Bring head revision up to date with cabal (try #3) - Add check for the syslog function - Generalized error handling functions - Add all the new files to the sources list for the utility library - New function: xalloc_and_zero() - Generalized list and hash handling functions - First try to create a graphical frontend for tinc configuration - Updating HEAD branch #1; removing obsolete files. - Updating HEAD branch #2; removing debian/ dir. - Updating HEAD branch #3; more obsolete files removed. - Updating HEAD branch #4; Merging CABAL -> HEAD. - Updating HEAD branch #5; Last files from CABAL. - Ok, I forgot these ;) - More updates - More... - Last bits (hopefully) - Main pokey interface files. - Pokey interface definition - Write src/pokey/Makefile - Also compile in pokey/ - Remove debug level declaration - Update copyright info - Remove debug_lvl - New logging system to replace syslog() calls with a generic function. - Rename log_message to log - Add syslog() wrapper - Add syslog wrapper - Some magic - Added priority definitions from syslog.h - log_default_hook was renamed to log_default - Added prototype for log_syslog - Use logging.h instead of syslog.h - Compile in logging.c - Things to ignore... - Use new logging system - Include logging.h - Renamed libvpn to libtinc - Rename libvpn to libtinc - ... - Print newline when writing to stderr - *** empty log message *** - Moving files, first attempt at gcrypt compatibility, more interface - Commit diff test - Another file moved; random interface stuff. - Callbacks - Moved event.c/h - test - test 2 - Hm. - -Wessel Dankers (5): - Initial revision. Lots of loose ends, not usable yet. - added bit on config file, split up sections, added Id: tag - Added extra bit about keys. - More about keys - This file is now only in the CABAL revision. - -cvs2svn (1): - This commit was generated by cvs2svn to compensate for changes in r1352, - -Version 1.0.2 November 08 2003 ------------------------------------------------------------------------- - -Guus Sliepen (47): - Simplify fake getname/addrinfo() functions, possibly fixing freeing a NULL pointer. - stat() batch files under Windows. - Don't getsockopt() SO_ERROR. We get the error from send()/recv() anyway. - Fix fake getnameinfo() and check more arguments. - Fix --logfile under Windows. - Use the event log under Windows. - Compilation fix. - Do what the SDK documentation tells. - If we're not in main_loop() and the service is stopped, exit immediately. - Allow tinc to handle unknown type addresses from other tinc daemons. - Don't overwrite the first " when installing a service. - Add checkpoints. - When purging nodes, only delete them if nobody references them anymore. - Remove debug message. - Add license exception from Markus Oberhumer. - Remove old edges from unreachable nodes to us. This prevents the hosts/NAME-up - We don't have to tell GCC how to cast. - Prevent multiple inclusions. - Remove pidfile when exitting. - Update translations. - Check for short packets from the tun/tap device and from other tinc daemons. - Generate keys with 0x10001 as public exponent, which has less prime factors - Better length checks. - Copy structs from packets to the stack before using them, to prevent - const - Ethernet protocol types. - Unused variable in struct. - Don't confuse users with "Address family not supported" warnings. - Use CPPFLAGS, LDFLAGS and LIBS as appropiate. - PIDs are of type pid_t, and use %ld when reading/writing them to the pidfile. - Make sure type of AF_UNKNOWN is sa_family_t. - Forgot to #include "xalloc.h" - Update missing definitions, structs describing headers get __packed__ attribute. - Missing declaration. - Set media status for newer TAP-Win32 driver. - Some platforms don't know sa_family_t or define it other than uint16_t. - Update documentation. - Fix ASCII art. - Check return value of EVP_* functions, and check if length before en/decryption - Check all EVP_ function calls. - Parentheses in the wrong spots. - Fix bug that could lead to an assertion failure in libcrypto when multiple - Small fixes in documentation. - Fix another bug in meta.c. - Update dutch translation. - Add missing definitions. - Release notes for 1.0.2 - -Version 1.0.1 August 14 2003 ------------------------------------------------------------------------- - -Guus Sliepen (24): - Windows uses backslashes... - Tell windows to be patient. - Remove unused stuff from doc/. - Correct error message when remote host closed connection. - Simplify execute_script(). It will probably work under Windows as well. - Allow empty lines in config files. - Make rule for sample-config.tar.gz. - Readd quotes. - Typo. - Better error messages under Windows. - Log error first, try to close later. - Quote when needed and don't try stuff that doesn't work under Windows. - Under Windows, the installation directory can be found in the registry. - Better error checking and reporting. - Small things. - Simpler checking of permissions on private RSA key and other fixes. - Check for fchmod(). - Only system() needs script name quoted. - Update documentation. - Add a description for the Service control panel. - Updated dutch translation. - Small fixes. - Fix permissions check for rsa_key.priv. - Update. - -Version 1.0 August 08 2003 ------------------------------------------------------------------------- - -Guus Sliepen (111): - Thank some more people. - Run graph() after edge_del() when updating an edge. - Add documentation for BindToAddress. - Fix PriorityInheritance. - PrivateKeyFile instead of PrivateKey. - Run graph algorithm when replacing a second connection from the same host - Add $NAME for tinc-up/down scripts. - - Fix indentation in some places. - Various fixes for autoconf and OpenSSL 0.9.7 and a missing header. - Make sure send_meta() writes everything. - Typo. - - Avoid memory leak caused by OpenSSL 0.9.7a. - - Speed up checksumming - Don't copy more than necessary. - Checksums must also work for uneven number of bytes. - HUP signal now closes connections to hosts if their host config file is - Better handling of late packets. - Make sure outgoing_t is completely freed. - - Per-node EVP_CIPHER_CTX to avoid initialisation overhead. - Small fixes to make LZO compression work. - Small fixes. - Fix links. - Fix warning and add missing checks for LZO library. - Call make_names() before doing anything else. - If we have a Linux tun/tap device and we are in router mode, open the device - AddressFamily is "any" by default. - Remove mymac stuff from device.c. - Fixes from Wessel Danker's libavl. - More braces to make gcc happy. - Update documentation. - Update dutch translation. - Typo and conversion to UTF-8. - There are two lzo compression levels. - Really make tinc default to any addressfamily. - This subtle pointer arithmetic thingy is (I'm very sure of it) the cause - - simplify configure.in - Check for IPv6 header files. - Define logger(), cleans up source code and allows us to write log entries - Sprinkling the source with static and attributes. - Provide all missing IPv6 definitions in lib/ipv6.h. - Actually add ipv6.h. - More missing definitions. - More missing IPv6 definitions and autoconf checks to make sure it compiles - Simplify logging, update copyrights and some minor cleanups. - Update copyrights. - Removing distribution specific files from CVS. - Format string checking for logger(). - Export mymac. - Make use of the CIPE driver. Woohoo, tinc for Windows! - Windows headers declare a struct interface somewhere. - Big header file cleanup: everything that has to do with standard system - Even more missing definitions. - Remove all #ifndefs from route.c - Update all device.c files. - Check for ethernet/ipv4/ipv6 related structures. - Use iface instead of interface because it might already be declared in - Oops. - No UNIX style permissions under Windows. - Be consistent. - Oops. - Check for sys/mman.h. - Use functions from logger.c - Copy cygwin driver to mingw directory. It doesn't work (yet). - Add section about configuring Cygwin and CIPE on Windows. - Option to specify pidfile location. - Use bools and enums where appropriate. - Run setup_device() after parsing configuration but before claiming we're ready. - Don't initialise a CIPHER_CTX if cipher == NULL. - Sprinkle around a lot of const and some C99 initialisers. - More generic handling of tap device under Windows. - More checks for missing functions. - Fix compile errors and warnings. - Update dutch translation and make sure all device drivers are included in - Update configure scripts. - Make sure it works. - Make sure (at least) the MinGW device driver works. - Native Windows support. - Cleanups. - Update documentation and remove stuff that's too outdated. - Remove doc/es/ and src/device.c from the distribution. - No C99 initialisers, gcc 2.95.3 doesn't like it. - Replacement for stdbool.h - Prevent definitions from messing up attributes. - Check if the compiler knows about the __malloc__ attribute. - Wrong argument. - Remove forgotten braces. - No easy way to properly detect header files... - Woops! - Wrong function... - Prevent system headers from including our own headers. - Allow whitespace in values. - Oops. - Windows has no symbolic links as we know it. - When compiling with MinGW, link with ws2_32. - Install tinc as a service under Windows (MinGW). Remove cleanup_and_exit(), - Error messages. - Cleanups and error messages. - Missing include. - Oops. - Updated dutch translation. - Explain how tinc detaches and how it is "killed" under Windows. - Typo and another thing to think about. - Clean up last part of main(). - Old gcc compilers don't like declarations in the middle of a function. - Cygwin needs windows.h. - Keep Windows happy. - Remove newlines from log messages. - Update dutch translation - Simplify translation - Use our own port when connecting to ourself. - Sync CABAL branch with release-1_0 branch. - -Ivo Timmermans (2): - Fix saving of debug level for startup level 0 - Call RSA_blinding_on(), as advised in the paper on - -Wessel Dankers (1): - its: Engels voor "van het" - 3e persoon enkelvoud, genitief, onzijdig - -Version 1.0pre8 September 16 2002 ------------------------------------------------------------------------- - -Guus Sliepen (73): - Support for MaxOS/X. - Add BindToAddress variable, similar to the late BindToIP. - Added Nick Patavalis for his RedHat package. - Informative log message if execl() failed. - Fix very stupid bug in node_del(), which might have caused corruption of - Only purge once when there are no more connections. - Support RSA_PUBKEYs (as opposed to RSAPublicKeys) so tinc accepts - Make it work correctly with NetBSD tun device. - Use correct includes on NetBSD. - Cleanup: - Use inttypes.h instead of stdint.h. - - netinet/* include files depend on netinet/in_systm.h. - Added Darwin (MacOS/X) tun device handling. - Use darwin/device.c when compiling on MacOS/X. - Include darwin/device.c in distribution. - Autoconf cleanup. Works for both 2.13 and 2.53, although running autoconf - Add configuration details for NetBSD and Darwin (MacOS/X). - Reset listen_sockets after SIGHUP. - Update comments about IPv6 autoconfiguration. - s/sliepen.warande.net/sliepen.eu.org/g - Fix for prefixlengths of 32 (IPv4) and 128 (IPv6) bits. - Allow list of environment variables to be passed to execute_script(). - Allow identical subnets from different owners. - Clear subnets before using them. - Started port to Cygwin. - Added stub device.c for Cygwin. - Include complete fake-getname/addrinfo from OpenSSH. - Allow tincd to be locked into main memory. - Don't bother to chown, and correctly document ConnectTo. - Added support for raw sockets. This can be used instead of tun/tap devices. - Gettext 1.11.5 compatibility. - Check for ranlib. - Replacement for the current routing algorithm. - Make sure setlocale() is available. - Drop graph and edge stuff. Use new node stuff instead. - A reachable node is always more preferable to an unreachable one... - Woops. - Reduce KEY_CHANGED traffic. - Prevent looping DEL_NODE/ADD_NODE messages after a node disconnects. - Don't forget to set prevhop to myself for new connections. - Just ignore wrong ADD_NODEs instead of replying with a DEL_NODE, in the - Revert to edge and graph stuff. This time, use a directed graph. - Small fixes. - Generalized request broadcasting/forwarding. - Updated dutch translation. - Small updates. - Run autopoint and libtoolize before creating initial makefiles. - Add missing headers. - Typo. - Only reset seqno's when a key is sent or received. - Remove global edge_tree. - edge_weight_compare() shouldn't rely on edge_compare(). - Reset the *correct* seqnos. - Fix MST algorithm. - Why don't these connection_t's get cleaned up? - Cleanups: - Switch to K&R style indentation. - Switch to K&R style indentation. - Remove redundant spaces. - Let GCC check format string and arguments of send_request(). - Fix compiler warnings. - Clean up after indent. - Link with libintl if necessary. - Fix placement of #include "config.h" - Make sure malloc() is declared. - What was I thinking? - MacOS/X needs #define _P1003_1B_VISIBLE in order to use mlockall(). - port_t isn't used anymore and conflicts with MacOS/X headers. - Small fixes so tinc compiles out of the box on SunOS 5.8 - Updated dutch translation. - Use /dev/net/tun as default for tun/tap device under Linux. - Update documentation. - Remarks about 1.0pre8 release. - -Ivo Timmermans (9): - Put #ifndef checks for HAVE_RAND_PSEUDO_BYTES in the correct places. - Typo - OSX support - getnameinfo fixes - Add /sw/{include,lib} to search paths if they exist - Include a few more header files - Include netbsd's device.c in make dist - Added Alessandro Gatti - Added AM_MAINTAINER_MODE - -Wessel Dankers (1): - This should work much better. - -Version 1.0pre7 April 09 2002 ------------------------------------------------------------------------- - -Guus Sliepen (9): - Make configure --help output look nicer. - Don't check_network_activity() if select() is interrupted by a signal. - check_rsa() is broken, I don't know why, just remove it for now. - Fix maskcheck() and maskcmp(). - Automake forgets about depcomp, remind it. - masklength is better known as prefixlength. - masklength is better known as prefixlength - Updated dutch translation. - Remarks about 1.0pre7 release. - -Version 1.0pre6 March 27 2002 ------------------------------------------------------------------------- - -Guus Sliepen (91): - Forgot to merge new files from pre5. - Last bits of the merger. - Sensible defaults for $INTERFACE. - - If no PrivateKeyFile is specified, /etc/tinc/netname/rsa_key.priv is assumed. - Small fix. - Added support for packet compression, thanks to Mark Glines. - Don't use sa_sigaction (which NetBSD doesn't like) at all if we don't use siginfo. - Get rid of sys/signal.h. - Added device.c for NetBSD, actually a copy of the OpenBSD one. - Add check for NetBSD. - - Non-blocking connect()s. - Fix segfault when receiving HUP signal. - Use AF_UNSPEC for listening sockets if AddressFamily = any. - Forward packets in router mode. - Fix maskcmp() and maskcpy(). - Cache results of lookup_subnet_...(). - Protocol now also exchanges cipher/digest/maclength/compression for the - Preserve inpkt->len, needed for broadcasts. - - Use gai_strerror() where appropriate - - Change SA_LEN to SALEN, former one is already defined on some platforms. - Tweaking IPv6 support. - Allow multiple listening sockets. - Fix send_request() bug. - Make BindToInterface work. - Fix listening sockets. - If "PriorityInheritance = yes" is specified in tinc.conf, the value of the - Create/bind TCP and UDP listening sockets in pairs. - Updated documentation. - Updated dutch translation. - - Global time_t now, so that we don't have to call time() too often. - Document and clean up MAC address expiry. - Woops. - Check if BindToDevice and PriorityInheritance are supported. - Fix forwarding of IPv6 packets. - po/POTFILES and po/Makefile should not be generated by configure. - Autodetect $MAKE/gmake/make. - Small fixes to improve portability. - Don't retry to make outgoing connections when exitting. - Cleanups, spelling fixes, allow symbol names for signals (-k option), - prune_connections() before build_fdset(). - Try to reply to neighbor solicitation requests. - New strategy: forward icmp6 neighbor solicitations to intended target. - Simplified implementation of Kruskal's minimum spanning tree algorithm. - Packet sequence number/authentication warnings only if debug_lvl >= 5. - Remove silly cache thingy. - Put #ifdef NEIGHBORSOL around corresponding code. - Revert changes to Kruskal's algo. - Neighbor solicitation requests now work (I think). - Oops, don't forget to actually put the checksum in the response packet. - Different way of detecting neighbor solicitation requests. - Typo. - Unmap v4mapped sockaddrs. - Only unmap IPv6 addresses. - #define s6_addr32, needed for FreeBSD. - Fix #define s6_addr32. - Remember sockaddrs of listening sockets, use appropriate one when sending - Cleanup. - Don't use s6_addr[16|32] anymore. - Updated dutch translation. - Updated SSSP algorithm to automatically detect indirect links (if a node uses - Put a break on requests that run around in circles. - - Added support for jumbograms. - Fix add_edge_h(). - Fix compiler warnings, strictly use long int and %lx for options. - send_ack() was broken. - free() request strings when deleting past requests from the tree. - Don't run graph algorithms if no edge is deleted in terminate_connection(). - Reset retry timeout when receiving the first PONG, not right after receiving the ACK. - Don't try to execute scripts unless they exist. - Execute hosts/name-up when a node becomes reachable, and hosts/name-down - Set $INTERFACE correctly when using ethertap while compiled with tun/tap support. - Updated dutch translation. - Respect type field. - OpenBSD tun device uses address family number instead of Ethernet type. - Configuration variables were still handled case sensitively. - Set myself->status.reachable. - Updated documentation. - Tell a little bit more about security. - Send REQ_KEY only once until ANS_KEY has arrived. - Fix execute_script(). - Small correction. - Merge do_prune() with build_fdset(). Probably fixes the invalid filedescriptor error. - Extend list_t with the number of elements in the list. - Limit the amount of packets in a queue to 8. - Small updates. - Remove cruft. - Recent automake uses $(AMTAR) instead of $(TAR) - Remove symlink to device.c when doing a make dist. - Fix format strings. - Update dutch translation. - Update with information about the pre6 release. - -Version 1.0pre5 February 10 2002 ------------------------------------------------------------------------- - -Guus Sliepen (109): - Small fixes to allow correct compilation under FreeBSD (tested with 4.3) - Make sure Solaris is happy too. - Fix subnet_lookup() for overlapping subnets. Needs rethinking. - Added proxy-arp support. No more ifconfig -arp needed. Works like a charm - - tinc can now act as a switch or a hub too (as opposed to a router only) - Changed some stuff to allow correct generation of po/Makefile after a - Updated dutch translation. - - This oneliner removes the need for ifconfig tap? hw ether fe:fd:0:0:0:0 - Fix bug where lookup_subnet_ipv4() could go into an infinite loop. - You can now put an option "Mode" in tinc.conf, and choose from: - Add missing? counting of total_socket_in. - Log and warn about duplicate subnet_add()'s for the same subnet. - Fixes to make switching work between hosts that have no meta-connection. - Save configure cache more often. - Changed drastically because it didn't work correctly: - Only reset seconds_till_retry when we activate the outgoing connection. - Woops - big bug in send_key_changed fixed. - - Solaris compile fixes - Check for and add -ldl. - Remove #warnings I used for debugging stuff. - Reinstated search for if_tun.h in kernel source tree, because apparently - Spanish translation removed. Nobody maintains it, and it is severely - ABOUT-NLS is created by autogen.sh. - Don't build Spanish translation. - Execute tinc-down BEFORE tap device is closed. This is a. more symmetric - es.po revived. - Also remove po/Makefile.in.in, which is generated by autogen.sh. - Log error if two hosts connect with same IP/port tuple. - Fix gcc 3.0 warnings. - Check for dlopen in standard libraries first (needed for DEC OSF). - It appears that autogen.sh doesn't like es.po if it isn't mentioned in - Update of RedHat build scripts. - Dutch translation updated. - More items marked as done. - Fix printf format bug. - Fix compiler warning. - Check for all potential duplicate entries in the id tree. - - Always use instead of just - Don't load table of verbose OpenSSL errormessages. - Correct inclusion of standard if_tun.h header file. - Split connection list into two lists: - Correctly use the active_tree. - Remove all unnecessary status.meta and status.active checks. - Added purge_tree for connection_t's which are no longer in the connection, - Updated terminate_connection() so you can choose if DEL_HOSTs should be - Always close all sockets in terminate_connection(). - Woohoo! tinc now compiles, runs and actually *works* on Solaris! - Started writing a document about how daemons connect to each other. - Described problem in more detail. - Small update. - Correctie. - Written down a possible solution. - Discuss how sending ADD_EDGEs would be better than sending ADD_HOSTs. - More on edges. - Don't use %m in fprintf(). - Write public key to rsa_key.pub instead of rsa_key.priv (if not host - The val variable in a config_t is never used as a long. - Explicitly log which type of tunnel device is used. - Don't send DEL_HOSTs when !status.meta - Fix signed comparison bug in lookup_subnet_ipv4(). - Remove IndirectData support for now, new implementation will be added - Revised reconnection mechanism, always try out all ConnectTo lines. - Optional signal number for -k option. - config_t* is a const parameter in get_config_val(). - - Try old TUN/TAP ioctl() request if the one from if_tun.h fails. - Not only keep track of nexthop, but also of lastbutonehop. If destination cl - Show next- and lastbutonehop when dumping connectionlist to syslog. - Try next connectto instead of the same over and over. - Fill in next- and lastbutonehop for myself. - - Renamed lastbutonehop to prevhop. - Fix bug where tinc would crash because of a portscan or a connection from a - - Use ping timeout mechanism to close connections that don't authenticate - Fix bug when dropping an old connection in favour of a new one from the - Updated dutch translation. - Started implementing doc/CONNECTIVITY. - Small corrections. - Further implementation of doc/CONNECTIVITY. connection.[ch] is now split into a - Removed everything from connection.c that has already been moved to node.c and - Revamp configuration handling: - More updates to new node/vertex/connection combo. - - Split tap device stuff out of net.[ch] - Added FreeBSD tap device handling. - Solaris tun device handling cleaned up a bit and added. - Forgot to remove some old #ifdef stuff. - Added OpenBSD tun device handling. Untested though. - Forgot the tun specific stuff. - Support new files (node/vertex/device.[ch]) and OpenBSD. - Big bad commit: - Make sure everything links. - Various small fixes to make tinc runnable again. - What was I thinking? s/vertex/edge/g. - - More s/vertex/edge/g - - More changes needed for Kruskal's algorithm - Working version of Kruskal's algorithm. The running time is very bad though. - Various fixes, tinc is now somewhat capable of actually working again. - More updates to protocol handlers and reimplemented terminate_connection(). - - Small fixes to graph algorithms - Don't forget to read public RSA key when making an outgoing connection. - Show cfg->variable instead of cfg->value when complaining about wrong type. - Avoid connecting to another node twice, and check name of outgoing connections. - Some very small fixes - Use PEM functions as suggested by OpenSSL docs. - Several bugfixes. - *** empty log message *** - Be liberal in what you accept: allow unknown edges to be deleted. - Correctly check if subnet owner exists. - Various fixes needed for Solaris. - More fixes for Solaris. - Merging of the entire pre5 branch. - -Ivo Timmermans (32): - New make target: `make release' - Changed version number to 1.0-cvs - Don't distribute autogen.sh in a release - Don't include the debian/ dir in a release - Small fix to make it compile again - Killing tincd with SIGINT causes it to toggle between the current - Check for getaddrinfo - Check for getnameinfo, gai_strerror, freeaddrinfo - Credit OpenSSH - Check for struct addrinfo - Deprecated get_config_ip and get_config_port - Use struct addrinfo in connection_t to hold all host data such as IP - Changed prototype for lookup_connection to use struct addrinfo - Changed lookup_connection to use struct addrinfo - Removed definitions of ipv4_t, ipv6_t, port_t - Obsoleted all IP types in favor of struct addrinfo - Changed to use struct addrinfo where needed. - get_config_{ip,port} removed. - Don't compile/link netutl.c. - Obsoleted. - Don't include netutl.h. - (re)added port to struct node_t - Added HAVE_STRUCT_ADDRINFO - Added dropin replacements for get*info and helper functions. - First part of rewriting things to use struct addrinfo. - lookup_node_udp changed. - Don't include netutl.h. - route_ipv4 and route_ipv6 replaced by route_ip. - get_config_subnet needs to be fixed. - Fixed silly typo: "np" instead of "no" - Don't include netutl.h. - Conversion to struct addrinfo is almost complete for this file. - -Wessel Dankers (1): - make is not always GNU make. - -Version 1.0pre4 May 25 2001 ------------------------------------------------------------------------- - -Guus Sliepen (97): - Porting to FreeBSD: - - Added balanced tree management stuff as well. (It is not finished yet.) - - Simplified do_detach - - Removed stray @INCLUDE@ (how did that get there?) - - Fixed searching - - Implemented deletions - - Fix tree head/tail upon insertion - - Fixed a lot of small things. Tested everything except deletions. - - Deletion also works now. - - Small fixes - - Integrate rbl trees into tinc. - - Proper initialization of rbltree structures. - - Various small fixes. - - More fixes. - - Check for NULL tree->delete callback - - Cleaned up and checked for some more NULL pointers in rbl.c - - Write pidfile AFTER detaching... - - No more %as. - - Work with the correct key buffer in ans_key_h - - More porting to FreeBSD and Solaris. - - Fixed all (except 2) compiler warnings gcc -Wall gave. - - #include instead of - - Don't link with -ldl anymore - Another big & bad commit: - - Added Armijn to the list - - Added daemon() replacement. - - Use only one socket for all UDP traffic (for compatibility) - - Don't even think about using sscanf with %as anymore - - AVL tree routines: faster than RBL, and also more stable. - - Doubled size of trace buffer for easier debugging. - - Let user choose whether keys are in the config files or separate - - Updated dutch translation. - - Check and follow symlinks in is_safe_path - - Changed license of AVL tree library to GPL. - - Updated manual pages. - - Updated texinfo manual. - - Typo. - - Changed list routines to give it the same look'n'feel as the rbl and - - Reinstated a queue for outgoing packets. - - Added header file for route.c. The routing routines in it are not used - - Description of protocol and authentication updated. - - It's 2001, all copyright notices are updated. - - Fixed IPv6 subnet lookup routine. - - Added indirectdata and tcponly functionality. - - Squashed another nasty bug. - - Sign was wrong in search_closest_smaller/greater - - Cleaned up subnet_t - - Only send out DEL_HOSTs for hosts with a meta connection - Added sample configuration directory. - - Copy entire sample-config directory to /etc/tinc/example upon installing. - - Allow ASN1 style keys to be in the config files. - FreeBSD compile fixes (thanks to XeF4) - Fix memory leak in avl_insert() if item was already inserted. - Updated dutch translation. - Removed another local definition of the variable "errno" - Added .cvsignore files to get rid of warnings and prevent autogenerated - Ignore file for src/ - - Updated CVS_CREATED to remove intl/ directory and some other - Added description of the proposed new authentication scheme. - Corrected check for errors after read() calls. - Add missing \n. - Free node->data and node, not node->data twice. - Copy packets before putting them in the queue. - Encrypt network packets in CBC mode instead of CFB mode. - Implemented new authentication scheme from doc/SECURITY2. - Added process.c to the translated files. - - Make sure METAKEY is smaller than the modulus of the RSA key - Don't forget to reconnect if outgoing connection fails during - - Fixed Interface option (untested) - Removed lots of compiler warnings. - Removed compiler warning. - Various small fixes. - Added explaination of our key exchange using RSA encryption. - - route.c is now used to determine destination - Updated translation. - Added a description of what is going on in net.c and route.c, and how - Fixed a race condition triggered by receive_meta() and the new - Fixed bug in setup_signals() that would make tinc die when unexpected - Ignore alarm signals if we do not need to respond to them. - Check indirectdata option before forwarding certain requests. - Depend on new ssl package and install alias for universal TUN/TAP module. - Correctly cycle through ConnectTo variables. - - s/ip_t/ipv4_t/g - - Make sure correct information is supplied for both old kernels (with - More revisions to the documentation: - Changed URL from kernelnotes.org to linuxdoc.org. - Add randomness to PING/PONG packets to prevent crypto attacks on quiet - Since this is incompatible with some earlier versions, PROT_CURRENT is - All features for 1.0 are implemented now, we just have to check the - Only send key_changed if it was previously requested. - Small fixes: - Small corrections to the manuals. - With recent kernels the tun device file is located in /dev/net. - TCPonly now works (in a relatively clean way too). - Merged PROTOCOL, NETWORK and SECURITY2 with the texinfo manual. - Documents are merged. Now we only need to check the ports and the TCPonly - Fix sample configuration to show keys in PEM format and correct tapdevice. - -Ivo Timmermans (88): - Add a check for openssl that accepts explicit file locations. - Identify version as 1.0pre4-cvs - Better checks for OpenSSL. I think it can now detect almost all conceivable installations. - Oops, small error. - Get rid of the annoying empty line - Also check for rand.h and err.h. If any of these files does not - Also check for sha.h. - Use the HAVE_OPENSSL_xxx_H defined from m4/openssl.m4 during - Let the output from an executed script in execute_script() go to - List management and manipulation routines. - Keep a list of running children, and in each loop in main_loop(), - Move all process-related functions into process.c. - New function: xmalloc_and_zero, which initialises the allocated memory - Delete struct ifr - Move more functions from tincd.c into process.c. - Use proper prototypes. - Added this release - More function and header checks - Also include process.h - Get rid of all libtool references at once. libtool was only used by - Honor the --localstatedir option to configure, instead of hardcoded /var. - Add more checks to ensure that filedescriptors are right in - Declare fd. - Do not use the C library's daemon() call. - Do not check for the daemon() system call - Do not attempt to retreive ChangeLog information only from the CABAL - Set localstatedir to /var - Use cvs2cl instead of rcs2log to generate the ChangeLog. - Set CFLAGS to -O2 -Wall when running configure - Alter CFLAGS, somehow INCLUDES doesn't propagate properly. Still - Set errno to 0 before trying to kill the other process. - Explain how to tell configure where OpenSSL lives. - Call autogen.sh instead of configure alone; and make cvs-clean instead - Add default tinc-up and tinc-down scripts for a Debian system. These - Updated Spanish translation, provided by Enrique Zanardi. - Give an error message if daemon() failed. - Check for the function strsignal, and define it to "" if it is not - Sort items to either 1.0 or future release goals. - Use sigaction to set signal handlers, the previous commit (1.1.2.16) - Save RSA public and private keys to a separate file, instead of - dropin.c/h contain a set of drop-in replacements for non-standard C - Check for get_current_dir_name. There is a replacement function in - Added a check for a scanf that knows about %as. - Implemented a readline() function that will read an entire line into a - xstrdup now takes a const pointer as an argument. - Use readline() in read_config_file() instead of fgets. - Also free the pointer returned by readline(). - Updated Dutch translation - Implemented is_safe_path, and extended ask_and_safe_open. - Read the PEM file pointed to by the configuration directive - The file is safe if it doesn't exist. - In readline(): initialise the line to zero length; - Better error checking when reading the RSA private key. - Avoid printing duplicate messages from read_rsa_keys - New function read_rsa_public_key(); - All full stops have two spaces after them. (Silly commit, I know.) - Tagged `Storing private key in separate file' as done. - readline() accepts two extra parameters, buf and buflen, to avoid - Use buffer instead of line in read_config_file(), line may be assigned - Stated that distributing executables linked with OpenSSL is permitted - Include COPYING.README in the distribution. - Added documentation merger - Sort configuration directives - Option -d accepts an argument to set the debug level immediately. - Massive long awaited documentation update. It's not finished yet, - Oops. I did some VERY wrong things with readline(). Fixed now. - Tiny bits of code beautifying - Install a file in /etc/modutils/tinc, containing all necessary aliases - Ported it back to /bin/sh. - Give a warning about having to re-create the keys - Re-introduced MyVirtualIP and VpnMask, as dummy options. - Various small changes. - Include autogen.sh (needed for the Debian package). - Forget router.c - Added lint target, requires lclint. - Fix error reporting of read_config - Set Architecture to `any' - Change version to 1.0pre4 - Second draft of the release notes - Merged documentation with various updates I had lying around - Get the Debian changelog up to date - Get the PO files up to date with the current source - Fixed some errors - Distribute the sample config as a .tar.gz - Unpack sample-config.tar.gz when installing - More files to ignore in CVS - tinc_TUNTAP now substitutes the values outside the AC_CACHE_CHECK - Authentication done - -Wessel Dankers (1): - Important bugfix in avl_insert_before() and avl_insert_after() - -Version 1.0pre3 November 09 2000 ------------------------------------------------------------------------- - -Guus Sliepen (119): - Debian init.d script automatically sets tap device's MTU to 1448 now. - First step for implementation of the "indirectdata" directive. This should - If we have "indirectdata" flag set, we only send data to our uplink. - Large cleanup: - Added CVS Id tags to header files. - - Log possible spoofing attacks. - Hostnames are back! - Hostlookup() is actually being called now. - - More verbose connection list - Fixes some hostlookups. Fixes indirectdata for real now (hopefully). - - Indirectdata finally REALLY REALLY works now! - - Moved all connection messages to debug level 1, without -d's only the - - Fixed KEY_CHANGED notification. A lot of notify_others() calls were - - Fixed indirectdata=no problem - - Improved handling of errors on connection attempts. - - Purge old connections that are ADD_HOSTed. - - Fixes a silly little insignificant buglet. - - Extra check op EINTR bij inlezen requests - - Fixed some spelling errors. - - Fixed missing " in nl.po - - Fixed a message in nl.po - - Added log message when SIGCHLD is received ("thanks" to Ivo van Dong) - - Updated Dutch translation. - - Removed all IP_ADDR_S macros, because gettext doesn't like them. Each - - New semantics for BASIC_INFO, ADD_HOST and DEL_HOST requests. This will - - Fixed memory leak. - - Removed segfault bug in conf.c (must have been there for ages!) - - Instead of logging an error when remote end closes the connection, - - Made tinc even more silent if no -d flag is given at all. - - Added documentation for the protocols (most important the meta protocol) - - Removed a single unused bit from status_bits_t. - - Updated PROTOCOL (a bit) - - Forgot to mention ourselves in the tincd manual page! :) - - Added Spanish translation from Enrique Zanardi. - - Updated THANKS file - - Delayed address resolving for ConnectTo lines in configuration file to - - Fixed typo. - - Added experimental hackish tunneling-over-TCP support. - - Lots o' buglets fixed (-Wall helps) - Fixed PACKET read loop. - Removed calling add_queue for tcponly packets. - - Added date/time of build and protocol number to --version output. - - Moved TCP packet reception to meta handler: less kludgy and less buggy! - - Reinstated O_NONBLOCK for meta socket - - Added two extra configuration options, Interface and InterfaceIP, to - Fixed all sprintf() spl01ts. - Ran update-po and updated dutch translation. - Commented on some size calculations. - Updated the manual: - Updated tinc.conf manual. - Fix rules (thanks to Laurence) - - Use strerror() instead of sys_errlist[] for increased portability - - New protocol. Will break everything else for now. - - Added more function skeletons for the new protocol. - - Lots of functions added for the new protocol. - - Some key exchange stuff. (Last commit before going to bed.) - - Fixed modulo in keylength check - - Lots of small changes. - Added document about the used cryptographic algorithms and the reasons - - Included authentication scheme from protocol.c - - Updated authentication scheme. - - Severe code reduction and simplification of challenge requests - - Removed options "string" stuff. It was a bad idea... - - Very detailed example of the authentication phase. - - Added meta.c which contains functions to send, receive and broadcast - - Added subnet handling code - Removing cipher directory (all will be covered by OpenSSL). - Big and bad commit of my current tree... - - Changed genauth to produce rsa keypairs instead of random passphrases. - - Generalized config file parsing to support multiple configuration trees. - - Fixing-things pass: every source file compiles into an object file now, - - Second fixing-things pass: it even links now. - - The daemon actually runs now (somewhat) - Corrected #ifdefs for tun/tap support. - - Fixing little things - - More fixing. Tinc daemons can now even create activated connections. - - Seed the PRNG using /dev/random before generating the keys. - - tinc now really does public/private key encryption! It even works, whee! - - Made Makefile.am stub for doc/es/ - - Removed last reference to genauth from Makefile.am - - Fixed all debug levels. - - route.c will contain the routing logic. - - Lots of little stuff modified - - Updated subnet list handling. Subnets are added to two lists now, the - - Lots of small fixes - - Fixed offsets when reading/writing from/to tap device - - Override destination ethernet address on incoming packets with - - Very big cleanup. - - Fixed ans_key_h - - Hit people who can't figure out subnet address/mask pairs with a - - Enforce correct order of authentication requests - - Moved connlist stuff to the proper header file. - - Updated dutch translation. - - Removed old encr stuff - - Small fixes - - Use CFB mode for encrypting packets: it works and we don't need padding. - - Finishing touch: encrypt the meta connections - - Small cleanups - - Fixed some spelling mistakes and terminology here and there. - - Update. - Removed config file parsing and interface setup. This will be handled by - - Removed unused MAC strip/add functions. - - Removed even more warnings. - - Resolve scriptname after fork() - - Removed manpage for no longer existing genauth. - - connlist.c added to translation - - Don't forget to set packet cipher for added hosts. - - Forward keys in hex notation, not as binary data. - - Check for packets that are looping back. - - Simplified ping mechanism. - - Prepended config_ to all configuration option names, because it confused - Changed execution of tinc-up: - - Open UDP connection for all known hosts. Comments please. - Porting to SunOS 5.8: - Porting to SunOS 5.8: - - Fixed --config - - Applied Jamie Brigg's patch (close sockets after error) - - Add Jamie :) - - Make checkpoint tracing a compile time option (off by default) - -Ivo Timmermans (77): - Alphabetized the list, added Lubom�r Bulej, removed Sander Smeenk and Tijs van Bakel, put merits after all names. - Don't touch VPNMASK if it's defined, otherwise use $MSK. - These files are created by gettextize (run by autogen.sh) (should have known that). - Include ../intl in the include path, and add @INTLLIBS@ to the list of libraries. - Merge changes from 1.6-1.8. - Configuration directive `IndirectData'. - Changed version number to 1.0pre3. - Version 1.0pre3. - Removed Free Software Foundation copyright, because Guus Sliepen contributed significantly. - Oops, and mention Guus too. - Include the Spanish translation in the distribution/build process. - (Quoting Laurence Lane:) - Also chomp $VPNMASK - Added a rule to create an rpm - Changed CVSROOT path in `make ChangeLog' - Link with OpenSSL crypto libraries instead of own blowfish library - Updated text, removed protocol flowchart - Include openssl/blowfish.h - Support for -lsocket and -lnsl on SunOS - Correct filenames for passphrases given in the example - Add Guus' name and shift out old protocol requests - Better checks for SunOS libraries - Added some structures and types that are needed for the overhaul. - New directive: Name. - First round of needed fixes after the overhaul - Second round of fixes - Added Spanish translation of the docs by Matias Carrasco - Many updates, parts rewritten, added, shuffled around. - Link with OpenSSL, forget libGMP - Updated new requirements, pointers to the manual - Don't look for GMP header files - Update Depends lines to reflect the dependencies on OpenSSL - Fix `Requirements'-section for GMP and OpenSSL libraries. - Add CVS id lines - Add checks for the presence of the universal tun/tap device driver. - Wrap the tun/tap code in #ifdef HAVE_TUNTAP - Linearized checks for if_tun.h - Really #include the if_tun.h files now - Output doc/es/Makefile - Process subdir es/ - Don't declare cp_file and cp_line in xmalloc() - Get the head revision up to date with cabal - Changed changelog - Include linux/sockios.h and net/if.h anyway, regardless of the value of HAVE_TUNTAP. - read_server_config: Check for result of read_config_file. - Oops, echelon change committed to cabal... :) - Skip the check for Linux kernel sources - This file is no longer needed. - - Synchronized changelog with the package's changelog. - Do not include $(top_srcdir)/cipher, it does no longer exist. - Added a perl example to turn an IP address into a MAC address. - Only check for linux/if_tun.h once - Changed `I' to `We' - small change, lots of difference :) - More exhaustive list of changes - perhaps it can be worded differently? - Change wsl to Wessel's name and email address in the ChangeLog creation - Mention fileutils, add a pointer to THANKS for more details - Changed a few messages wrt. system calls; updated and changed the Dutch translation a bit. - Don't include shlibs, as it no longer exists. - Oops, and include doc-base.tinc (new file). - - If necessary, patch po/Makefile.in from po-Makefile.in.in.diff to - Minor cosmetic change. - Save the environment on startup. - Run the scripts tinc-up and tinc-down from a separate function, which - Warnings removal pass: always include config.h first; add a few - Small change to the way the environment is copied. - Use putenv() instead of clumsy do-it-yourself in execute_script. - Do not include the passphrases directory - In execute_script: - Add route.c to the list of source files. - Updated Dutch translation - Build-depends on libtool - Build-Depends on gettext - Final release notes added, also edited release notes for 1.0pre2 to what the announcement on the mailing list looked like. - Wrapped text to 70 (72?) columns for easy reading - Bop version number to 1.0pre3-1 - Updates, updates - Add prototype for destroy_queue - -Wessel Dankers (3): - File added to CABAL (hopefully) - Grrr, recommit - Added architecture section, made a start with the kernel section. - -Version 1.0pre2 May 31 2000 ------------------------------------------------------------------------- - -Ivo Timmermans (56): - Deleted the protocol description. - Perl version of the system startup script. - Only print an error with send_termreq if debug_lvl is 2 or more. - Add check for mpz_powm in libgmp3. - Version 1.0pre1-0.1. - Changed version to 1.0pre2. - Give IP address instead of hex number when connecting tcp socket failed. - Add shlibs control file for the blowfish library. - Inserted useful content. - Add initscript, tincd->tinc. - Add description, better dependancies. - Mention both upstream authors. - tincd->tinc - .deb version number 1.0pre2-0.4. - Updated to newer version. - Exit with zero status if is empty. - Unlimited length in the config file, thanks to Cris van Pelt. - Depend on perl5. - *** empty log message *** - Look if the tap devices exist before bluntly remaking them. - Use the new VpnMask directive to add a route to the rest of the VPN. - This file is generated with dpkg-buildpackage. - Read /etc/tinc/nets.boot to find the networks that have to be started. - Create a default /etc/tinc/nets.boot after installation, containing all directories under /etc/tinc by default. - Version 1.0pre2-0.3 - Don't distribute the file files. - Find networks in instead of . - Include postinst in the distribution. - Errors will not terminate the script or result in a nonzero exit code. - Updated copyright notice. - Fixed typo. - Mask the vpn net with the vpn netmask, route would give an error if the netmask didn't match the net. - When VpnMask is not present in the config file, silently use $MSK as vpnmask. - Add an example of using VpnMask. - Use /etc/tinc/example as a base directory for an example. /etc/tinc/example/README points to /usr/share/doc/tinc/README.Debian. - Create an empty /etc/tinc/nets.boot. - Updated by Lubomir Bulej and Mads Kiilerich: it uses /etc/tinc/nets.boot and the VpnMask directive in the config files. - Internationalization of tinc. - Include intl/ directory in the list of subdirs. - Include system.h and ABOUT-NLS. - Update acconfig.h to include values for gettext inclusion. - Include GNU gettext checks. - Define LOCALEDIR in CFLAGS. - Dutch translation of tinc. - Bounds check for request id (between 0 and 255). - Updated changes list for version 1.0pre2. - Added new configuration directive `Hostnames', which controls the resolving of IP addresses to hostnames. - When a connection is terminated, all hosts that are still connected get notified of the lost connections. - In terminate_connection, only send a notification to hosts that are directly connected to us. (DEL_HOST gets forwarded automatically.) - Only accept an ADD_HOST request for a host that already exists in our conn_list if the nexthop field matches the sender. This is a workaround for older clients. - Include news for 1.0pre2. - Tell about /etc/tinc/nets.boot. - Updated Dutch translation. - Version 1.0pre2-1. - Handle locale settings. - Miscellaneous copyright updates. - -Guus Sliepen (16): - Proxymode removed. - Cleanups. - Changed ping behaviour (backwards compatible). If we don't have any data - Fixed typos. - Test for existence of configured tinc networks. This will also make - Stub for VpnMask config directive. - TODO file reinstated: - VpnMask truely works now. - Typo. - Fixed last typo. Init.d now uses ifconfig command to set both the tap's IP - Documentation updates. Removed all references to configuration variable - Fix for a DoS attack: - Fixed typos. When terminating a connection, it's status is not only set to - Made tinc persistent. If no outgoing connection can be established right - Terminate a connection on any error. Furthermore, disallow del_host, - Only activate a connection upon receiving it's public key if it's an - -Version 1.0pre1 May 08 2000 ------------------------------------------------------------------------- - -Ivo Timmermans (84): - Get rid of the message `zxnrbl\'. - Upon regeneration, free the old encryption key `securely\' by overwriting it. - Kill the parent after any error conditions in detach(). - Ignore SIGCHLD. - New option -D, don't detach. - Moved to version number 1.0. - Only one round of reading bits out of urandom; - Pass the requested size from xmalloc() and xrealloc() on to xalloc_fail_func() - Check for an illegal length of passphrase in read_passphrase(). - Check if stdout is a terminal, if so, print a verbose message. - Default passphrase length of 1024, added -h/--help options. - Submitted by Mads Kiilerich. - New manpage for genauth. - Updated manpages. - Address for bugreports changed to tinc@nl.linux.org. - Include the directory redhat in the build process. - Include genauth.8 in the distribution. - Submitted changes by Mads Kiilerich. - A short notice from Mads Kiilerich. - Keep make dist(dir) happy. - Added cvs-clean. - These files are not needed in release 1.0. - Don't compile in `idea'. - Don't include idea/idea.h. - Don't try to create cipher/idea/Makefile. - The shell script autogen.sh can create all these removed files, but be - s/Gnome/tinc/g - This file is obsolete, most of the ideas are already in echelon. - Remove check for bigendianness. - Don't define HAVE_NAMESPACES and HAVE_STL. - Use `make ChangeLog' to create this file from the CVS logs. - Remove test for GNOME. - Changes largely from Mads Kiilerich. - Added Mads Kiilerich, removed Guus Sliepen. - *** empty log message *** - Generate this Makefile.am from Makefile.am.in. - Contributed by Mads Kiilerich. - Spelling fixes. - Delete all the files that are created by autogen.sh on a `make cvs-clean'. - Propagate CFLAGS from configure to gcc. - Don't include TODO in the dist. - Remove ChangeLog with a `make cvs-clean'. - Initial CVS. - *** empty log message *** - Create a ChangeLog file, automake requires it. - *** empty log message *** - Debug level tweaking. - From Mads Kiilerich. - The make command is in /usr/bin. - Add an entry to dir. - Omit TODO. - Version to 1.0pre1; - Filled in the details, license from libblowfish copied. - Updated version number to 1.0. - Default config file name is tinc.conf, and pidfile is tinc.pid. - More updates wrt. the change from tincd->tinc. - Added `deb' target. - Filled up the protocol structs with unused bytes. - Got rid of the nasty hacks... and replaced it by another one. - Initially, the vpn_mask of a connection is 255.255.255.255 to avoid confusion with lookup_conn. - Replaced check for status.active by status.dataopen in check_network_activity. - New way of handling the meta protocol. - Read public keys the right way (tm). - Removed debug messages. - Read one less byte from an ANS_KEY request. - Send one less byte from an ANS_KEY request. - Protocol fix (ANS_KEY). This breaks 0.3.3 protocol compatibility. - Key forwarding, write one byte extra. - Committed by Lubom�r Bulej. - Updates by Mads Kiilerich. - Committed by Mads Kiilerich. - Fixed meta protocol. - More tincd->tinc updates. - Mentioned new metaprotocol. - Fix a typo, better handling of the info document. (from Mads Kiilerich) - Don't use error.h or error(), put #error in front of cpp errors. - getopt_long() support for platforms that don't have it. - Include stdio.h for fprintf. - More for getopt support. - Check for the existance of libdl. - Don't link in libdl. - Include sys/types.h. - Copied most of the code from the redhat script. - Added semicolons required by bash2 (Mads Kiilerich). - -Guus Sliepen (18): - Added extra checks for desynchronized connection lists. Hopefully this will - Bug found! Wrong pointer was used for handling multiple ADD_HOST requests - Added checkpoints to beginning and ending of every function. - Packet queues fixed. They caused the trouble when resending keys. - Fixed typo and removed some unnecessary variables. - When trying to talk to a host that is in the netmask of a tinc server but - Converted every &variable[0] to variable. - Cleanups: - Removed write_n() function. - Oops! Reference to write_n() removed and changed into neat write() call. - Meta protocol overhaul. Tinc is now incompatible with previous versions, - Fixed small mistake that would prevent forwarding requests. - Previous fix fixed. Meta protocol should be really flawless from now on! - Replaced sprintf() by safer snprintf(), removed possible buffer overflow - Outgoing packets now use network byte order in header. - Fixes typo and UDP network byte order. - Squashed gcc warning. - Added new config variable "ProxyMode". If enabled, all outgoing packets +commit f8d94f34fc5d7fe9ed4a076a2fd77eacbd83adca +Author: Guus Sliepen +Date: Sun Jul 17 20:09:08 2011 +0200 + Releasing 1.1pre2. + +commit c259d552fa89c3e4a962d9adf2b237f24bc077da +Author: Guus Sliepen +Date: Sun Jul 17 20:06:06 2011 +0200 + + Add missing newline. + +commit f6020a5224c9c4c17c11c5f9d2c8441638ac04fc +Author: Guus Sliepen +Date: Sun Jul 17 20:01:24 2011 +0200 + + Write loopback address instead of "any" address in pidfile. + +commit 25091454da21941dd92375ddbee7dd6151343058 +Author: Guus Sliepen +Date: Sun Jul 17 19:23:52 2011 +0200 + + "tincctl stop" now removes the tinc service on Windows. + +commit c6c989cfa175154f4cd3830c5a77fbd2071f52af +Author: Guus Sliepen +Date: Sun Jul 17 18:02:56 2011 +0200 + + Fix declaration of usleep(). + +commit 18e9839dc861c368141bbbc9a963f719a83eba3e +Author: Guus Sliepen +Date: Sun Jul 17 10:59:54 2011 +0200 + + Ensure symlinked files do not end up in the tarball. + +commit fa4a01e4a27dd4b3a57077acbd0e69f95d55944a +Author: Guus Sliepen +Date: Sat Jul 16 22:38:50 2011 +0200 + + Use const pointer to source in base64 and hex routines. + +commit 574b380dfc75ef13ee4accba1f2416165c58a5a2 +Author: Guus Sliepen +Date: Sat Jul 16 22:38:22 2011 +0200 + + Use usleep() instead of sleep(), MinGW complained. + +commit 8efc8dc961865ceddb74cb36f0b4a2ebde39cc55 +Author: Guus Sliepen +Date: Sat Jul 16 21:44:17 2011 +0200 + + Update info manual. + +commit cff27a258f3b3a97b5d2e309c264eceea41dff3a +Author: Guus Sliepen +Date: Sat Jul 16 20:21:44 2011 +0200 + + Use ECDSA to sign ECDH key exchange for UDP session keys. + + The ECDSA public keys will also be included in the ANS_KEY requests, + but are only used when no ECDSA public key is known yet. + +commit 03ac48ea19914e4162f17a2fb0f742b99ae32499 +Author: Guus Sliepen +Date: Sat Jul 16 15:21:37 2011 +0200 + + Use the same logic as tinc 1.0.x for detecting two nodes with the same Name. + +commit 2ba61742d4c2ab82525efb806dc654a6d95d335e +Author: Guus Sliepen +Date: Sat Jul 16 15:15:29 2011 +0200 + + Use the correct direction flag when setting cipher keys. + + The flag was set incorrectly, but for most ciphers this does not have + any effect. AES in any of the block modes is picky about it though. + +commit 303dd1e70219a7542921f6e63d9391ab326d434f +Author: Guus Sliepen +Date: Wed Jul 13 22:52:52 2011 +0200 + + Fix compiler warnings. + +commit 791c1898ea8f92b07f1d79e90540c257ac38298d +Author: Guus Sliepen +Date: Wed Jul 13 22:29:30 2011 +0200 + + Remove unnecessary variables and functions. + +commit fec279a9c54ec8a13bd1ba4c7bec0d2a15454992 +Author: Guus Sliepen +Date: Tue Jul 12 23:43:12 2011 +0200 + + Make use of the improved hex and base64 functions. + + Also, use base64 for all EC related data, it is shorter and easy to + distinguish from the legacy protocol. + +commit 06b8271ed5d56c9bd3de459d95907d0ef4f0ea3c +Author: Guus Sliepen +Date: Tue Jul 12 22:54:49 2011 +0200 + + Make hexadecimal and base64 routines behave the same. + + The length parameter for the encoding functions is the length of the + binary input, and for the decoding functions it is the maximum size of + the binary output. + + The return value is always the length of the resulting output, excluding + the terminating NULL character for the encoding routines. + + All functions can encode and decode in-place. The encoding functions + will always write a terminating NULL character, and the decoding + functions will stop at a NULL character. + +commit c108c79a22118ef7246a3d7b3bc20e205e11d179 +Author: Guus Sliepen +Date: Mon Jul 11 22:14:06 2011 +0200 + + Don't use wildcards in filenames in configure.in. + +commit bbeab00f46a6c856573fe0d2b9b85bce35728403 +Author: Guus Sliepen +Date: Mon Jul 11 21:54:01 2011 +0200 + + Require ExperimentalProtocol = yes for new features, update documentation. + +commit d1cd3c81455ecb32149cbaa424b7870075b2b2fc +Author: Guus Sliepen +Date: Sun Jul 10 22:46:43 2011 +0200 + + Close meta connection socket after cleaning up event structures. + + Epoll doesn't like it when an already closed filedescriptor is being + removed, so we defer closing the socket until after all else is cleaned + up. + +commit 30ef2a981e1d62692b3a2363e0b3a0e8711d9604 +Author: Guus Sliepen +Date: Sun Jul 10 22:34:17 2011 +0200 + + Automatically exchange ECDSA keys and upgrade to new authentication protocol. + + If we don't have ECDSA keys for the node we connect to, set protocol_minor + to 1, to indicate this to the other end. This will first complete the + old way of authentication with RSA keys, and will then exchange ECDSA keys. + The connection will be terminated right afterwards, and the next attempt + will use ECDSA keys. + +commit 027228debee2ea6f31cd176e456c13d626380066 +Author: Guus Sliepen +Date: Sun Jul 10 21:02:34 2011 +0200 + + Free ECDSA and RSA structures when freeing a connection_t. + +commit 73863fab8ae1ecd8307aaeef486919cc76b85d63 +Author: Guus Sliepen +Date: Fri Jul 8 18:17:34 2011 +0200 + + Hash input before signing it with ECDSA. + +commit 8132be8fbd6c45be309c63a117f418ad12ced094 +Author: Guus Sliepen +Date: Thu Jul 7 22:30:55 2011 +0200 + + Very primitive ECDSA signed ECDH key exchange for the meta protocol. + + Nonces and hash of the ID requests should be included in the seed for the PRF. + +commit 210b5ceeeebdf742a74dcf95a0a13d69623ee001 +Author: Guus Sliepen +Date: Thu Jul 7 22:28:25 2011 +0200 + + Read ECDSA keys. + +commit 03582eb669494cb778ebea7b0fe3b1b841335750 +Author: Guus Sliepen +Date: Thu Jul 7 22:27:17 2011 +0200 + + Implement ECDSA sign and verify operations. + + Very basic at the moment, doesn't hash the input first, + and uses OpenSSL's DER encoded signature as output. + +commit 86d83bd9bd69e2129f4e4e8397f1c7e223685e2f +Author: Guus Sliepen +Date: Tue Jul 5 21:29:31 2011 +0200 + + Bump minor protocol to indicate ECDH capability for UDP session keys. + +commit 9708bbfa8e3094de8932a30b1d24c661558d8a03 +Author: Guus Sliepen +Date: Tue Jul 5 21:19:48 2011 +0200 + + Add a minor number to the protocol version. + +commit b99656d84a88dad7935d5981fcdb43a5b2bfa417 +Author: Guus Sliepen +Date: Mon Jul 4 07:51:47 2011 +0200 + + Round up the size of the secret parts after splitting it in two. + +commit 95e1cc36d320b47408ac3ec6f89df54e55a010d4 +Author: Guus Sliepen +Date: Sun Jul 3 23:44:43 2011 +0200 + + Add ECDSA key import. + +commit 1e2d9b08991861c8770aa2c5a73d86dc02e3067d +Author: Guus Sliepen +Date: Sun Jul 3 23:33:56 2011 +0200 + + Finish base64 decoding routine. + +commit 80b81c00b129b006981b76bdb734df3296317d6f +Author: Guus Sliepen +Date: Sun Jul 3 22:25:29 2011 +0200 + + Have tincctl generate ECDSA keys. + + The generate-keys command now generates both an RSA and an ECDSA keypair, + but one can generate-rsa-keys or generate-ecdsa-keys to just generate one type. + +commit 8ace7f3e5771957fbdda8b817fa26951d9d62c28 +Author: Guus Sliepen +Date: Sun Jul 3 22:15:00 2011 +0200 + + Add ECDSA key generation. + +commit 1d92dd62a786ecabbc05dfba5195f3f08e0f9585 +Author: Guus Sliepen +Date: Sun Jul 3 22:13:58 2011 +0200 + + Base64 encoding and decoding functions. + +commit c385d115331845e8a844322e66571d74d833e822 +Author: Guus Sliepen +Date: Sun Jul 3 22:13:34 2011 +0200 + + Cleanups in ECDH code. + +commit 895f868714f9422a757a95650345e0c662d12b49 +Author: Guus Sliepen +Date: Sun Jul 3 21:21:37 2011 +0200 + + No need to keep around pointers to EC_GROUP. + +commit ac163120d7f0300c8d555f76ace3368ce2ffa655 +Author: Guus Sliepen +Date: Sun Jul 3 16:30:49 2011 +0200 + + Proper use of PRF. + +commit 82f00ea07bffc10985ccb1a15723e6daa0ab4969 +Author: Guus Sliepen +Date: Sun Jul 3 15:59:49 2011 +0200 + + Use PRF. + +commit feb3f22fffa2620b9b11a509ce51ff9fa3be9418 +Author: Guus Sliepen +Date: Sun Jul 3 15:26:58 2011 +0200 + + Add PRF to derive key material from the ECDH shared secret. + + It is modelled after the pseudorandom function from RFC4346 (TLS 1.1), the only + significant change is the use of SHA512 and Whirlpool instead of MD5 and SHA1. + +commit 8dfa072733feab737cabf69f000c70657719826a +Author: Guus Sliepen +Date: Sun Jul 3 13:17:28 2011 +0200 + + Support ECDH key exchange. + + REQ_KEY requests have an extra field indicating key exchange version. + If it is present and > 0, the sender supports ECDH. If the receiver also + does, then it will generate a new keypair and sends the public key in a + ANS_KEY request with "ECDH:" prefixed. The ans_key_h() function will + compute the shared secret, which, at the moment,is used as is to set the + cipher and HMAC keys. However, this must be changed to use a proper KDF. + In the future, the ECDH key exchange must also be signed. + +commit ee8a214318fd6dbe6bc5d6b510896f30d92d46c6 +Author: Guus Sliepen +Date: Mon Jun 27 21:52:23 2011 +0200 + + Preliminary implementation of Elliptic Curve Diffie-Hellman Ephemeral key exchange. + +commit 6c21b5716b8e9e5ff5def8070f92b76a0f353cb0 +Author: Guus Sliepen +Date: Sun Jun 26 13:15:44 2011 +0200 + + Add manpage for tinc-gui. + +commit 4c934d0903a32e71ae83ffdf344957bd06b7164d +Author: Guus Sliepen +Date: Sun Jun 26 13:14:48 2011 +0200 + + Remove debug messages that were printed to stdout. + +commit e73052b05444679d922dbdf3d0c507873110957e +Author: Guus Sliepen +Date: Sun Jun 26 12:59:11 2011 +0200 + + Update documentation to mention pidfiles instead of controlcookies. + +commit 8c953b1bfef3c6ebee7c537c2c2f144807d0311a +Author: Guus Sliepen +Date: Sun Jun 26 12:58:50 2011 +0200 + + Don't react to escape character in tincctl top. + + Not only the ESC key generates an escape character, but many other keys + do as well, such as arrow keys. + +commit 27e6a89b155b171b0b026d5e24ee0cc68f43d010 +Author: Guus Sliepen +Date: Sun Jun 26 12:51:25 2011 +0200 + + Use pidfile in tinc-gui as well. + +commit 660f530a6ff733f96f81eefa69b38e2ea685f890 +Author: Guus Sliepen +Date: Sat Jun 25 22:20:39 2011 +0200 + + Really stable sorting of tincctl top output. + +commit 810766e1394f18b8709e9f0c75a41a2c348e3fad +Author: Guus Sliepen +Date: Sat Jun 25 21:38:59 2011 +0200 + + Add +git to the version string. + +commit ab4d289fafd1d391583935ab4c306f1f508ea1d0 +Author: Guus Sliepen +Date: Sat Jun 25 21:35:27 2011 +0200 + + Make pid files backwards compatible and add address of listening socket. + + The pid is now written first, so that a version 1.0.x tincd can be used to stop + a running version 1.1 tincd. Getsockname() is used to determine the address of + the first listening socket, so that tincctl can connect to the local tincd even + if AddressFamily = ipv6, or if BindToAddress or BindToInterface is used. + +commit a05fa7f88264599a43f9e411287e018259dc22b1 +Author: Guus Sliepen +Date: Sat Jun 25 21:21:36 2011 +0200 + + Rename controlcookie file to pidfile. + +commit c64f64b875879591873d68faf2d3cd8e9d644101 +Author: Guus Sliepen +Date: Sat Jun 25 21:16:13 2011 +0200 + + Don't call exit_control() if we didn't do init_control(). + +commit 3b237afbda86bc95703ed25386cc9a26695d4602 +Author: Guus Sliepen +Date: Sat Jun 25 20:20:07 2011 +0200 + + Re-add support for SIGALRM. + +commit 386c1aff08a3ce6e295931e2fcf4bfc607053ff0 +Author: Guus Sliepen +Date: Sat Jun 25 17:39:02 2011 +0200 + + Merge Tinc.py into tinc-gui to simplify make install. + + Autoconf/automake's Python support is strange. + +commit c4c32f40599eb8e75b1160083020d924c5807ac8 +Author: Guus Sliepen +Date: Sat Jun 25 17:11:05 2011 +0200 + + Thank Scott Lamb, Sven-Haegar Koch and Loïc Grenié in the NEWS file. + +commit 8733110dec28967d67a3c00d00cdfa608dbeb9c4 +Author: Guus Sliepen +Date: Sat Jun 25 17:08:40 2011 +0200 + + Ensure the right files end up in the tarball after make dist. + +commit e4f65db89726ac06ba7e787d420db4422d9a6e98 +Author: Guus Sliepen +Date: Sat Jun 25 15:28:54 2011 +0200 + + Releasing 1.1pre1. + +commit 2c5ded652035bfaa204a7e1cc6766efb87135569 +Author: Guus Sliepen +Date: Sat Jun 25 15:28:13 2011 +0200 + + Ensure that the texinfo manual can be converted to HTML. + + Somehow commit 2c30af6c90926340a89748c63cc453b1c0b5a589 was not properly + merged. + +commit e8deda0b23463599a7533e82cf038a01062956a7 +Author: Guus Sliepen +Date: Sat Jun 25 14:52:47 2011 +0200 + + Update manpages and info manual. + +commit 47393b5de42120dfb7d01f8b77aff16ac68177ec +Author: Guus Sliepen +Date: Sat Jun 25 00:32:45 2011 +0200 + + Add Makefile.am in gui/. + + This ensures the gui source will be included in the tarball with make dist, + and will be installed with make install. + +commit 7944cce19e4de4207a4ef20569155118acebd406 +Author: Guus Sliepen +Date: Sat Jun 25 00:06:06 2011 +0200 + + Don't use AM_CONDITIONAL for CURSES. + + For some reason, this doesn't work when cross-compiling for Windows. + +commit 365f60f3f8a8ff85a616d5014d555b470740d395 +Author: Guus Sliepen +Date: Fri Jun 24 22:49:18 2011 +0200 + + Don't call event_del() from the mtuevent handler, always send_mtu_probe() in ans_key_h(). + +commit 1fe8ba2f06c39d7c8b81f0e451bdbac94ae9375f +Author: Guus Sliepen +Date: Fri Jun 24 22:10:03 2011 +0200 + + Delete mtuevent if it is not used. + + Keeping it around prevents ans_key_h() from restarting PMTU discovery. + +commit 79e9a4f743b7b59fed968575f6b36171cf4a0063 +Merge: fb5b260 05260f9 +Author: Guus Sliepen +Date: Fri Jun 24 21:40:55 2011 +0200 + + Merge branch 'master' of git://tinc-vpn.org/tinc into 1.1 + + Conflicts: + NEWS + README + configure.in + src/Makefile.am + +commit 05260f941c2a24eb3f09070a2550cf15e431266a +Author: Guus Sliepen +Date: Fri Jun 24 14:50:20 2011 +0200 + + Releasing 1.0.15. + +commit 3c0511984f0041f79e64bcc55d58680f86e8e408 +Author: Guus Sliepen +Date: Fri Jun 24 12:27:04 2011 +0200 + + Remove redundant @CFLAGS@ from AM_CFLAGS. + +commit fb5b260190b1c6d07ec822154094aee7416f292e +Author: Guus Sliepen +Date: Tue Jun 21 23:08:05 2011 +0200 + + No need to check for pselect() in tinc 1.1. + +commit 532557beeaa60d96ac423248ff62d2cc03205c22 +Author: Guus Sliepen +Date: Tue Jun 21 23:06:53 2011 +0200 + + Only log UDP address changes at the appropriate debug levels. + +commit 60ed7fe598ccf3ac11fab616c9c85492c576b722 +Author: Guus Sliepen +Date: Mon Jun 6 21:19:30 2011 +0200 + + Reopen log file after SIGHUP. + + This was missed by the previous merge. + +commit 33f241d97852d7a171f1aaf1bda7f66356ff889e +Merge: 601f3b2 4b3fd94 +Author: Guus Sliepen +Date: Mon Jun 6 20:42:15 2011 +0200 + + Merge branch 'master' of git://tinc-vpn.org/tinc into 1.1 + + Conflicts: + NEWS + configure.in + doc/tincd.8.in + lib/pidfile.c + lib/pidfile.h + lib/xalloc.h + lib/xmalloc.c + src/conf.c + src/conf.h + src/connection.c + src/connection.h + src/event.c + src/graph.c + src/graph.h + src/net.c + src/net.h + src/node.h + src/openssl/crypto.c + src/process.c + src/protocol.c + src/protocol_key.c + src/route.c + +commit 601f3b2dd746ff5726eca256861f2ecf662b3a55 +Author: Guus Sliepen +Date: Mon Jun 6 20:12:33 2011 +0200 + + Clean up digests when freeing a connection_t. + +commit 4b3fd94b1cc79c24c4092b6b10ed4627a2648d26 +Author: Guus Sliepen +Date: Mon Jun 6 16:26:11 2011 +0200 + + Improved --logfile option. + + Instead of UNIX time, the log messages now start with the time in RFC3339 + format, which human-readable and still easy for the computer to parse and sort. + The HUP signal will also cause the log file to be closed and reopened, which is + useful when log rotation is used. If there is an error while opening the log + file, this is logged to stderr. + +commit b3bbeab6e669795f6f5a6b98590da359178bfdce +Author: Guus Sliepen +Date: Sat Jun 4 11:27:54 2011 +0200 + + Attribution for Loïc Grenié. + +commit 50af33d01f425983dd2b1d7b61092a6325be3f41 +Author: Loïc Grenié +Date: Sat Jun 4 09:05:23 2011 +0200 + + Nearly tickless tinc. + + Use pselect instead of select in main_loop (if available). This lets + tincd sleeps as long as there is nothing to do. + +commit 8b3cc695b56d4ab5e51c7e194153894f920b307f +Author: Guus Sliepen +Date: Fri Jun 3 15:50:20 2011 +0200 + + Don't ignore SIGCHLD, system() needs it. + + But we do ignore SIGPIPE, and tinc 1.0.x signals that are no longer used + (SIGUSR1 and SIGUSR2), since the default handler of these signals is to + terminate tincd immediately. + +commit 5989a29d7b53b25e8ed2f60bc3a0e089e423c02c +Author: Guus Sliepen +Date: Fri Jun 3 00:46:56 2011 +0200 + + Fix format strings for Windows. + + Windows doesn't like %zd, so cast (s)size_t to int. Also, some shorts were + incorrectly printed with %d instead of %hd. + +commit 3ade33bfac11715190ed3e6cc3589d1a738ce257 +Author: Guus Sliepen +Date: Fri Jun 3 00:34:30 2011 +0200 + + Use send() when writing to sockets, and the return type is ssize_t. + +commit 5f4d57e846b566e80557c57a72e2bad562f66e7b +Author: Guus Sliepen +Date: Thu Jun 2 23:40:27 2011 +0200 + + Small fixes for Windows. + +commit 2adc789401153ffde847f76155e07665fbf909ac +Author: Guus Sliepen +Date: Thu Jun 2 22:14:53 2011 +0200 + + Even simpler signal handling. + +commit 2f42896789a1798e71374fa2ddf555fe2fa46c44 +Author: Guus Sliepen +Date: Thu Jun 2 21:29:11 2011 +0200 + + Remove debugging message that was accidentily left in. + +commit c6b0e102ad7caabae6876849c97f8acaecf5bc1a +Author: Guus Sliepen +Date: Thu Jun 2 21:16:57 2011 +0200 + + Don't treat packets coming in via TCP as having zero length. + +commit 80ca91769d48e546d3e4cde03c2eb2820c03acc4 +Author: Guus Sliepen +Date: Thu Jun 2 21:14:50 2011 +0200 + + Fix nodes joining the VPN after tincctl top started. + +commit 311f60f4f0bdf974d4890d7eb4a752299d1c9458 +Author: Guus Sliepen +Date: Thu Jun 2 20:48:18 2011 +0200 + + Make traffic statistics more readable with configurable scaling. + +commit a8f0d21330b40993d52421327b1aa33a6ea7acb7 +Author: Guus Sliepen +Date: Thu Jun 2 20:27:16 2011 +0200 + + More stable sorting in tincctl top. + + Although we use qsort(), which is not guaranteed to be stable, resorting the + previously sorted array is more stable than recreating and resorting the array + each time. + +commit 2bda2aa8855ff3ae42aba7aa86e1d7ff2b7a3b34 +Author: Guus Sliepen +Date: Thu Jun 2 18:22:26 2011 +0200 + + Fix some compiler and cppcheck warnings. + +commit 809dfd2f5b08ecbfe55d1a06d267abeef0044b0b +Author: Guus Sliepen +Date: Thu Jun 2 18:07:50 2011 +0200 + + Remove support for the Ethertap device. + +commit af2e0c9a32642065aedd2e67ca1f5791ca7a407d +Author: Guus Sliepen +Date: Thu Jun 2 17:57:53 2011 +0200 + + Remove unused functions and variables. + +commit 9eca49329db0c3b0a80114045cf214eaeaf3d5c2 +Author: Guus Sliepen +Date: Thu Jun 2 17:55:29 2011 +0200 + + Don't #include anymore. + +commit b7754e5aaa3cc453582d6c8c2e66483fdcd1ac0d +Author: Guus Sliepen +Date: Thu Jun 2 17:53:35 2011 +0200 + + Drop the GNU memcmp.c implementation. + +commit 25b467638a23ad03524719329027225ae1da75bc +Author: Guus Sliepen +Date: Thu Jun 2 17:45:06 2011 +0200 + + Drop the GNU malloc.c, realloc.c, and xmalloc.c. + + We live in the 21st century, and we require C99 semantics, so we do not need to + work around buggy libcs. The xmalloc() and related functions are now static + inline functions. + +commit e452a933f9c53fd58db9d932afd15319129dd988 +Author: Guus Sliepen +Date: Thu Jun 2 17:14:30 2011 +0200 + + Simplify signal handling. + + We don't override any signal handlers anymore except those for SIGPIPE and + SIGCHLD. Fatal signals (SIGSEGV, SIGBUS etc.) will terminate tincd and + optionally dump core. The previous behaviour was to terminate gracefully and + try to restart, but that usually failed and made any core dump useless. + +commit 4d440336c3ce68719e23b2fc51fac368e23352ad +Author: Guus Sliepen +Date: Sun May 29 22:34:19 2011 +0200 + + Remove outgoing event in free_connection(). + +commit d29bfc9a450b4758e44757a71675bac631dd3c55 +Author: Guus Sliepen +Date: Sun May 29 22:14:35 2011 +0200 + + Initialise priority field to zero for packets read from the VPN interface. + +commit 4c403840ffdeb2a2ff04c9b7780a407920b2b794 +Author: Guus Sliepen +Date: Sun May 29 22:12:37 2011 +0200 + + Cosmetic fix when pressing 's' in tincctl top. + +commit b3aeaf0f917a895332ff937c7ab64638eacc0eae +Author: Guus Sliepen +Date: Sun May 29 22:10:54 2011 +0200 + + Show hostname and port in error message when connecting to a running tincd. + +commit 04de15984f1479d0142bdfa5bd968274aea2209e +Author: Sven-Haegar Koch +Date: Sun May 29 21:53:21 2011 +0200 + + do_outgoing_connection() may delete a failed connection, and the structure + must not be accessed afterwards. + +commit 82109868b5acd55e452569c565ab6dc090ea1de0 +Author: Sven-Haegar Koch +Date: Sun May 29 21:35:31 2011 +0200 + + src/net_socket.c bind_to_address(): Use after free in error path. + +commit 5bc957074a35e58f49cbcf8d1fb5d6237d37363d +Author: Guus Sliepen +Date: Sun May 29 14:41:05 2011 +0200 + + Allow tincctl to connect to something besides localhost. + + This would allow tincctl to connect to a remote tincd, or to a local tincd that + isn't listening on localhost, for example if it is using the BindToInterface or + BindToAddress options. + +commit 64771f73ebbff04262defcde59263e98f89f0fa1 +Author: Guus Sliepen +Date: Sat May 28 23:46:56 2011 +0200 + + Remove a few unnecessary #includes. + + Some spotted by Michael Tokarev. + +commit 5cff8c47c1781a88123c128a4cec6cdd39925aa5 +Author: Guus Sliepen +Date: Sat May 28 23:42:18 2011 +0200 + + Remove newlines from log messages. + +commit 6d08eb1614b59d5f86a43edda9db06fca72b76cd +Author: Guus Sliepen +Date: Sat May 28 23:36:52 2011 +0200 + + Fix sparse warnings and add an extra sprinkling of const. + + This is more or less the equivalent of Sven-Haegar Koch's fixes in the 1.1 + branch. + +commit e6b21e1a510691a86dcc1ecdf71a80a7c62ff17f +Author: Sven-Haegar Koch +Date: Sat May 28 03:48:07 2011 +0200 + + fgets() returns NULL on error, not < 0 + +commit 434e57ae5ee79b3d990c4d75358047bad641998b +Author: Sven-Haegar Koch +Date: Sat May 28 03:46:39 2011 +0200 + + sparse fixup: warning: Using plain integer as NULL pointer + +commit f4010694b3b16453e5e6298c208910264e326978 +Author: Sven-Haegar Koch +Date: Sat May 28 03:57:20 2011 +0200 + + sparse fixup: warning: non-ANSI function declaration of function '...' + +commit d772289f6d6adfb8932658b533349d43f08ec326 +Author: Sven-Haegar Koch +Date: Sat May 28 03:56:06 2011 +0200 + + sparse fixup: warning: symbol '...' was not declared. Should it be static? + +commit 02e32cf61ee25d3d0e2fc1fef5cd98cbfa1c9a2f +Author: Sven-Haegar Koch +Date: Sat May 28 03:12:03 2011 +0200 + + sparse fixup: error: too many arguments for function send_key_changed + +commit b995243ac3d9605003996ba879808ddcbc77ae15 +Author: Sven-Haegar Koch +Date: Sat May 28 03:08:31 2011 +0200 + + sparse fixup: error: dubious one-bit signed bitfield + +commit bbd0025ae323e7141ba04a5371ec2f3f75f9b059 +Author: Sven-Haegar Koch +Date: Sat May 28 02:57:40 2011 +0200 + + Use same definition for xalloc_fail_func as is really used. + +commit 3fca2cad485ef70360bca085c5c4d052b6deb15b +Author: Sven-Haegar Koch +Date: Sat May 28 01:36:10 2011 +0200 + + Removed two newlines from the end of log messages which created empty lines. + +commit 9cce44dfe3401867f753778b73fd1e7ac1ee3122 +Author: Sven-Haegar Koch +Date: Sat May 28 01:33:45 2011 +0200 + + Fixed error logging on "Input buffer full" condition. + +commit 07ffb1a19859791d419b83a876ba552dadedbf46 +Author: Guus Sliepen +Date: Sun May 22 15:56:04 2011 +0200 + + Make return value of SetPriorityClass() behave the same as setpriority(). + +commit 453c44e7b27d4259461795ab4ec6ef264085dd28 +Author: Guus Sliepen +Date: Sun May 22 14:17:30 2011 +0200 + + Add the ability to dump all traffic going through route() over a control connection. + + One can get the packet stream in pcap format, which can be decoded using + tcpdump, for example: + + tincctl -n pcap | tcpdump -r - + +commit 54c900e961de6065f607f5661edeb7c84be29ea5 +Author: Guus Sliepen +Date: Sun May 22 14:02:27 2011 +0200 + + Reset tcplen after use. + +commit 8ddcad5fa1908727f68abb461b615c666616064f +Author: Guus Sliepen +Date: Sun May 22 13:15:27 2011 +0200 + + Check if an event is initialized before calling event_del(). + + Libevent prints a warning to stderr if we do that. + +commit 931e30f91a9241ab8aa705c911c92ba8943f80fd +Author: Guus Sliepen +Date: Sun May 22 13:15:05 2011 +0200 + + Always compact the buffer if it has reached MAXBUFSIZE. + +commit 90c7fafe594cf6d03c15a072a3d749f3e4d78482 +Author: Guus Sliepen +Date: Sun May 22 12:56:51 2011 +0200 + + Compact input buffer before trying to read instead of after. + + Also log an error when the input buffer contains more than MAXBUFSIZE bytes + already, instead of silently claiming the other side closed the connection. + +commit 8de8f1d9e2c2c02d4a14a5506e7d0d914dc328da +Author: Guus Sliepen +Date: Tue May 17 10:58:22 2011 +0200 + + Fix some compiler warnings. + +commit a80c18dd20e5303b26d5283e6cb5062a1812ddc3 +Author: Guus Sliepen +Date: Tue May 17 10:57:30 2011 +0200 + + Use GetItemCount() on ListCtrls instead of directly accessing ItemCount. + +commit f536504a7de90927b09d16f3bf0d3c6adead9955 +Author: Guus Sliepen +Date: Mon May 16 09:48:19 2011 +0200 + + Add top.h. + +commit e272fab858d5d3eeb43ff9f36268d25d3c6d32f1 +Author: Guus Sliepen +Date: Mon May 16 09:46:54 2011 +0200 + + Add tincctl.h. + +commit 6d97cb1e229c22d1d34aa9889aeaf17644ff06dc +Author: Guus Sliepen +Date: Sun May 15 16:30:13 2011 +0200 + + Nicer top command. + + - Configurable refresh interval. + - Switch between cumulative count or current rate. + - Configurable sorting. + +commit 4574b04f79d79d53492b7e0eb592d64ff9b2362b +Author: Guus Sliepen +Date: Sun May 15 16:29:54 2011 +0200 + + Allow inserting items in the middle of a list. + +commit 97355690b9cf8d8b56a316e01f73f8ff1fee68c8 +Author: Guus Sliepen +Date: Sun May 15 13:16:48 2011 +0200 + + Add a very primitive "top" command to tincctl. + +commit ec495b2f15fc5ae22136c226c7966caf51f643f8 +Author: Guus Sliepen +Date: Sun May 15 12:06:21 2011 +0200 + + Add an autoconf check for the curses library. + +commit 362d8a6358019cb97456c8133832f18798cea41f +Author: Guus Sliepen +Date: Sun May 15 11:59:13 2011 +0200 + + Dump traffic statistics over control sockets. + +commit f5843e7d649f4a7f72cb3fd356bc935457aa492f +Author: Guus Sliepen +Date: Sun May 15 00:42:29 2011 +0200 + + Add per-node traffic counters. + +commit ffa3a443b9f01d3ea0fcb3c4fc6928a5c695cf4a +Author: Guus Sliepen +Date: Sat May 14 22:30:23 2011 +0200 + + Several fixes for the buffer code. + +commit cdb793f687262b9f56823ca9046523a609a758af +Author: Guus Sliepen +Date: Sat May 14 19:20:56 2011 +0200 + + Remove use of bufferevent and eventbuffers, use our own buffering instead. + +commit f431fcb35f400be388a905ae0f7f50c1f5c4cd5d +Author: Guus Sliepen +Date: Sat May 14 19:15:04 2011 +0200 + + Add simple buffer management code. + + Libevent 2.0's buffer code is not completely backward compatible with 1.4's. + In order to not (mis)use it anymore, we implement it ourselves. The buffers + are automatically expanding when necessary. When consuming data from the + buffer, no memmove()s are performed. Only when adding to the buffer would + write past the end do we shift everything back to the start. + +commit 3794e551c7db9aa81405f65f7b04a9951c4120b2 +Author: Guus Sliepen +Date: Sat May 14 11:52:35 2011 +0200 + + Fix check for event initialization due to the merge. + +commit 03b7118139f57033659730afb740bf5cef7c961c +Author: Guus Sliepen +Date: Fri May 13 12:37:26 2011 +0200 + + Reorder checks for libraries to allow ./configure LDFLAGS=-static. + + OpenSSL depends on libdl and libz. When linking dynamically, libcrypto will + automatically link with the other two libraries. However, when linking + statically, these libraries need to be specified explicitly while linking. By + moving the autoconf checks for libdl and libz before those for libcrypto, we + ensure the latter test will be done with the proper libraries. + +commit ce8775000ab38229a78ecf3dc26bab008ca0f332 +Merge: 3f59a26 5686ad8 +Author: Guus Sliepen +Date: Mon May 9 21:35:14 2011 +0200 + + Merge branch 'master' of git://tinc-vpn.org/tinc into 1.1 + + Conflicts: + NEWS + README + configure.in + doc/tincd.8.in + lib/pidfile.c + src/bsd/device.c + src/dropin.h + src/net.c + src/net_packet.c + src/node.c + src/process.c + src/tincd.c + +commit 5686ad80b545afa3de9ed2f4176a5346e289aaa8 +Author: Guus Sliepen +Date: Sun May 8 23:17:46 2011 +0200 + + Releasing 1.0.14. + +commit 0d906489f2ce9faf81dc230f7db6ab5378573554 +Author: Guus Sliepen +Date: Sun May 8 23:12:44 2011 +0200 + + Include when using intptr_t. + +commit dc887f5011834d5a9a6ec5deb8781c6bfd88c474 +Author: Guus Sliepen +Date: Sun May 8 23:12:06 2011 +0200 + + Ensure proper linking with OpenSSL with recent versions of MinGW. + +commit 67766d65f06854ee894d784f638c5c9cd2b50bca +Author: Guus Sliepen +Date: Sun May 8 21:22:20 2011 +0200 + + Update THANKS and copyright information. + +commit 6e6b037ef4fd9877aeb1d947da7364409fa8cbb7 +Author: Guus Sliepen +Date: Sun May 8 21:06:06 2011 +0200 + + Check for EVP_EncryptInit_ex instead of SHA1_Version in OpenSSL. + + The latter function disappeared, and wasn't actually used in tinc, so now we + check on a function that we do use. + +commit 257cb6ac60bb0924720de9e252cdf7f4759bf741 +Author: Guus Sliepen +Date: Sun May 8 12:40:44 2011 +0200 + + Always use the default signal handler for ABRT signals. + + This will allow coredumps to be generated when tinc is daemonized. + Also add the -kABRT option. + +commit eacb5a28fb4c1515633f2b8a206e7067bc7b8f0c +Author: Guus Sliepen +Date: Sun May 8 12:16:26 2011 +0200 + + Increase threshold for detecting two nodes with the same Name. + + In commit 4a21aabada23d1d2c8a10f54dd7248171c4ec82f, code was added to detect + contradicting ADD_EDGE and DEL_EDGE messages being sent, which is an indication + of two nodes with the same Name connected to the same VPN. However, these + contradictory messages can also happen when there is a network partitioning. In + the former case a loop happens which causes many contradictory message, while + in the latter case only a few of those messages will be sent. So, now we + increase the threshold to at least 10 of both ADD_EDGE and DEL_EDGE messages. + +commit f11c6101f30df645223920bef3eb7592de9bcb79 +Author: Julien Muchembled +Date: Thu Apr 28 13:21:55 2011 +0200 + + Fix command-line '-o' option for host configuration + + This fixes a regression introduced by commit 667b1ba while refactoring option + parsing code. + +commit 0aa86d4b8b3010522e6de8842f5bd29004ba3df6 +Author: Guus Sliepen +Date: Wed Mar 9 09:34:56 2011 +0100 + + Do not set indirect flag on edges from nodes with multiple addresses. + + Since tinc now handles UDP packets with a different source address and port + than used for TCP connections, the heuristic to treat edges as indirect when + tinc could detect that multiple addresses were used does not make sense + anymore, and can actually reduce performance. + +commit 7cf68b5e35c002511cc7468967de6a75934cc998 +Author: Guus Sliepen +Date: Fri Feb 18 23:11:43 2011 +0100 + + Prevent anything from updating our own UDP address. + + Because we don't want to keep track of that, and this will cause the node + structure from being relinked into the node tree, which results in myself + pointing to an invalid address. + +commit cdbbbfabea173894bd2fb5f28135a04ddc5e3fd7 +Author: Guus Sliepen +Date: Fri Feb 18 23:02:11 2011 +0100 + + Fix spurious misidentification of incoming UDP packets. + + When a UDP packet was received with an unknown source address/port, and if it + failed a HMAC check against known keys, it could still incorrectly assign that + UDP address to another node. This would temporarily cause outgoing UDP packets + to go to the wrong destination address, until packets from the correct address + were received again. + +commit 046d83bf91e01bc7a32e66a02758caf228bc4601 +Author: Rumko +Date: Sat Feb 12 18:22:14 2011 +0100 + + DragonFlyBSD support + + * added DragonFly BSD support + * added a check for sys/resource.h (needed on DragonFly) + +commit f017c7f98f8f68d6ca50ebe247f4115aadd93635 +Author: Guus Sliepen +Date: Mon Feb 7 18:34:55 2011 +0100 + + Add support for VDE through libvdeplug. + + When compiled with vde/device.c, tinc will connect to a vde_switch instance + instead of using a tun/tap device. + +commit 8d18cc6c4e625625a2437d26c587f9f382a0c589 +Author: Guus Sliepen +Date: Sat Jan 29 10:49:44 2011 +0100 + + Fix typo spotted by Andrew Scheller. + +commit b3731c04097e66a6b8908bb893c5da831d89c04d +Author: Guus Sliepen +Date: Wed Jan 12 20:57:14 2011 +0100 + + Proper check and dropin replacement for usleep(). + +commit 4b8a5993036fccc2108fcc2550649d9b78fb1ab7 +Author: Guus Sliepen +Date: Sun Jan 2 17:25:24 2011 +0100 + + Update the NEWS. + +commit c228da54d47657811dfb679e7f138cbba58a9f67 +Author: Guus Sliepen +Date: Sun Jan 2 17:25:03 2011 +0100 + + Update the manual. + +commit 4575c6c7dffe228ce302776022a2075b7ef37ab0 +Author: Guus Sliepen +Date: Sun Jan 2 17:24:23 2011 +0100 + + Document the behavior of "-n." + +commit 6c05bf082b1ce9acfc0ebb5c6f32c2ece41c7f80 +Author: Guus Sliepen +Date: Sun Jan 2 16:59:42 2011 +0100 + + Remove unused variables. + +commit 6a51d89cf706bcefce1861a1a66d40ef7d7db43b +Author: Guus Sliepen +Date: Sun Jan 2 16:55:42 2011 +0100 + + Replace bogus #else with #endif. + + Found by cppcheck, which complained about lenin not being initialized, but the + real problem is that reading packets would fail when using code compiled with + --tunemu on a normal tun device. + +commit d7636352ce359e807b392a6e5ac0a6aeff4a63d2 +Author: Guus Sliepen +Date: Sun Jan 2 16:52:36 2011 +0100 + + Limit field width when scanning PID file. + + Cppcheck warns that scanf() might otherwise crash when presented with a huge, + bogus PID file. + +commit 3ce5e292da8bab3a1316faf1ca18625f05074467 +Author: Guus Sliepen +Date: Sun Jan 2 16:50:24 2011 +0100 + + Close all filedescriptors in Solaris close_device(). + +commit f99661a4ca5bacff47239ce7978b9c9948917c54 +Author: Guus Sliepen +Date: Sun Jan 2 15:02:23 2011 +0100 + + Always send MTU probes at least once every PingInterval. + + Before, if MTU probes failed, tinc would stop sending probes until the next + time keys were regenerated (by default, once every hour). Now it continues to + send them every PingInterval, so it recovers faster from temporary failures. + +commit cac0a5c651535e8317839b0deff1ee98086a8184 +Author: Guus Sliepen +Date: Sat Nov 20 14:31:11 2010 +0000 + + Use setpriority() instead of nice() on UNIX-like systems. + + The return value of nice() can not reliably indicate errors. The return value + of the setpriority() call is well-defined. + +commit 3f59a26d8098b8b0902b8746715508360b347f47 +Author: Guus Sliepen +Date: Fri Nov 19 12:26:20 2010 +0000 + + Do not try to dereference myself->connection->config_tree. + + This was a bug introduced due to an incomplete merge (commit + ff71f289022ccb91abc2726f16522d55b5ccf0f6). + +commit 886a6f61a1f4cc48a77b42d10f34f9126377d904 +Merge: 23dddc2 d91903e +Author: Guus Sliepen +Date: Fri Nov 19 12:22:48 2010 +0000 + + Merge branch 'master' into 1.1 + + Conflicts: + src/net_packet.c + src/openssl/rsagen.h + src/protocol_auth.c + src/protocol_key.c + +commit d91903ef3c2a1f4481ae8757bb2b14282f2b7e68 +Author: Guus Sliepen +Date: Tue Nov 16 17:28:41 2010 +0100 + + Attribution for Brandon Black. + +commit e764ff7be9949c91865aff72844357e76ae6dd78 +Author: Guus Sliepen +Date: Tue Nov 16 16:45:36 2010 +0100 + + Fix variable length array declaration. + +commit 5eb0440110f99f0a49838cc00a0686c7a7595663 +Author: Guus Sliepen +Date: Sat Nov 13 21:36:51 2010 +0100 + + Free replay window when freeing a node_t. + +commit a9445e38f25bd24eca289768fc46e44e36b842ac +Author: Guus Sliepen +Date: Sat Nov 13 21:34:59 2010 +0100 + + Fix warning message when setting SO_RCVBUF or SO_SNDBUF fails. + +commit 0d61d4ae1358553fc8dde350747542f137f5cb8b +Author: Brandon L Black +Date: Sat Nov 13 12:05:51 2010 -0600 + + Improved handling of queue-jumping packets on receive + +commit 23acc19bc090051156ad895caed61848f5afb144 +Author: Brandon L Black +Date: Sat Nov 13 12:05:50 2010 -0600 + + Configurable ReplayWindow size, zero disables + +commit 8dfe1b374e165ecba5d3ae324ee834d337476be8 +Author: Brandon L Black +Date: Sat Nov 13 12:05:49 2010 -0600 + + Configurable SO_RCVBUF/SO_SNDBUF for the UDP socket + +commit 3f410e2f8f7c365630f226adf4904935698f9e0d +Author: Brandon L Black +Date: Sat Nov 13 12:05:48 2010 -0600 + + Experimental IFF_ONE_QUEUE support for Linux + +commit 9e3ca397735077f85bbde48c36e1b3e0fa950988 +Author: Guus Sliepen +Date: Sat Nov 13 15:55:38 2010 +0100 + + Use variable length arrays instead of alloca(). + +commit e2e6ec8050274b0a8678d6fc263e7dc4ef66feae +Author: Guus Sliepen +Date: Sat Nov 13 15:50:39 2010 +0100 + + Provide usleep() for Windows. + +commit 23dddc25930bc9033e5a2ac659376032aff44d82 +Author: Guus Sliepen +Date: Sat Nov 13 15:46:19 2010 +0100 + + Link tincctl with dropin.o. + +commit a22041922f160667573e9a5ae3f4195e1668906a +Merge: 8b70c5b 930bf74 +Author: Guus Sliepen +Date: Fri Nov 12 16:15:29 2010 +0100 + + Merge branch 'master' into 1.1 + + Conflicts: + doc/tincd.8.in + lib/pidfile.c + src/graph.c + src/net.c + src/net.h + src/net_packet.c + src/net_setup.c + src/net_socket.c + src/netutl.c + src/node.c + src/node.h + src/protocol_auth.c + src/protocol_key.c + src/tincd.c + +commit 930bf74fbe5ce8363b6cc2ae3a3e960e910e0996 +Author: Guus Sliepen +Date: Fri Nov 12 11:38:05 2010 +0100 + + Don't use strlen() on a NULL pointer. + + A bug introduced in commit 667b1bac77b134cf32c98d5dc25619e8c3303f52 caused tinc + to crash on startup. + +commit a07aa92176571eb7f063708640d0d486280808ef +Author: Guus Sliepen +Date: Fri Nov 12 11:33:01 2010 +0100 + + Add short options -R and -U to the tincd(8) manpage. + +commit 66b7aea294896a99df289231143a506b422b994c +Author: Guus Sliepen +Date: Tue Nov 2 14:23:43 2010 +0100 + + Read error counter must be static. + +commit a91bf2dfcd0f5857905e59da7d944654e0875503 +Author: Guus Sliepen +Date: Tue Nov 2 14:18:35 2010 +0100 + + Quit when there are too many consecutive errors on the tun/tap device. + + Although transient errors sometimes happen on the tun/tap device (for example, + if the kernel is temporarily out of buffer space), there are situations where + the tun/tap device becomes permanently broken. Instead of endlessly spamming + the syslog, we now sleep an increasing amount of time between consecutive read + errors, and if reads still fail after 10 attempts (approximately 3 seconds), + tinc will quit. + +commit aca70cd3c3fe787e62c618849e43f67b3870ac20 +Author: Michael Tokarev +Date: Sun Oct 24 15:23:10 2010 +0400 + + Treat netname="." in a special way. + + Treat netname "." in a special way as if there was no netname + specified. Before, f.e. tincd -n. -k didn't work as it tried + to open /var/run/tinc-.pid. Now -n. works as if there was no + -n option is specified. + + Signed-Off-By: Michael Tokarev + +commit 5f729f76f5a63114df582fc29f4189140c1e5ead +Author: Guus Sliepen +Date: Fri Oct 22 22:46:44 2010 +0200 + + Remove unused variables. + + These were caused by commit 667b1bac77b134cf32c98d5dc25619e8c3303f52. + +commit 20ae7dd8c12390f7360eb28cc17e1b8a8a706b06 +Author: Guus Sliepen +Date: Fri Oct 22 22:43:50 2010 +0200 + + Abort disabling old PEM keys on I/O errors. + +commit a08462bf845973016e061b8ca1233142d80416f6 +Author: Guus Sliepen +Date: Fri Oct 22 22:42:21 2010 +0200 + + Ensure there is a newline character before a PEM key is written. + +commit c6ccbadfcf93a7bd4a88dee8ff146b4db7f85e71 +Author: Guus Sliepen +Date: Fri Oct 22 13:40:04 2010 +0200 + + Attribution for Timothy Redaelli. + +commit 1c2cd7ed273ee1538ff8a13d036c68aa9992c4aa +Author: Guus Sliepen +Date: Fri Oct 22 13:17:42 2010 +0200 + + Attribution for Julien Muchembled. + +commit 667b1bac77b134cf32c98d5dc25619e8c3303f52 +Author: Guus Sliepen +Date: Fri Oct 22 13:06:06 2010 +0200 + + Remove duplicate command-line option parsing. + + Also fix parsing of command-line host configuration options for the local node. + +commit ff71f289022ccb91abc2726f16522d55b5ccf0f6 +Author: Guus Sliepen +Date: Fri Oct 22 12:47:12 2010 +0200 + + Merge local host configuration with server configuration. + + With some exceptions, tinc only accepted host configuration options for the + local node from the corresponding host configuration file. Although this is + documented, many people expect that they can also put those options in + tinc.conf. Tinc now internally merges the contents of both tinc.conf and the + local host configuration file. + +commit 8c3105283ac53f8cc9cc4dde25957ec1cf6b53a0 +Author: Julien Muchembled +Date: Fri Sep 3 13:34:22 2010 +0200 + + New '-o' option to configure server or hosts from command line + + Options given on the command line have precedence over configuration from files. + + This can be useful, for example, for a roaming node, for which 'ConnectTo' and + .Address depends on its location. + +commit 4b6a9f1c1f645ce5989692655337d9e23ca28648 +Author: Guus Sliepen +Date: Fri Jun 4 16:03:19 2010 +0200 + + Do not append an address to ANS_KEY messages if we don't know any address. + + This would let tinc raise an exception when an ANS_KEY request crossed a + DEL_EDGE request for the node sending the key. + +commit 798fa2f04c52b0639713f74b1195847bec40c16a +Author: Guus Sliepen +Date: Fri Jun 4 15:04:08 2010 +0200 + + Use 64 bit counters to keep track of bytes sent/received from the virtual network interface. + +commit 4a21aabada23d1d2c8a10f54dd7248171c4ec82f +Author: Guus Sliepen +Date: Fri Jun 4 14:53:52 2010 +0200 + + Detect and prevent two nodes with the same Name being on the VPN simultaneously. + + In this situation, the two nodes will start fighting over the edges they announced. + When we have to contradict both ADD_EDGE and DEL_EDGE messages, we log a warning, + and with 25% chance per PingTimeout we quit. + +commit dbf3d168b720045328d476f3b9e5f5e45b4ab6de +Author: Guus Sliepen +Date: Fri May 7 12:24:49 2010 +0200 + + Use strrchr() insteaad of rindex(). + + The latter function is deprecated, some build environments do not support. + +commit eda71798749e8b0abf5e8b3cbc11da82aa607f00 +Author: Timothy Redaelli +Date: Tue May 4 15:43:48 2010 +0200 + + Fix warnings under BSD + +commit df985256a766ee90f2fa4269b95fa0565c969dda +Author: Timothy Redaelli +Date: Tue May 4 00:27:44 2010 +0200 + + Fix warnings showed using -D_FORTIFY_SOURCE=2 + +commit f5122ccecee095b9185b2324dea7bcd9655462ee +Author: Guus Sliepen +Date: Sat May 1 15:39:59 2010 +0200 + + Fix all warnings when compiling with mingw64. + +commit ef92a5725c47c6e8e801e07190dd7dd3f9cb3a17 +Author: Guus Sliepen +Date: Sat May 1 15:39:03 2010 +0200 + + OpenSSL 1.0.0 compiled for 64 bit Windows requires linking with -lcrypt32. + +commit 0fdd7da52077d77a11a3646eb3e7d5b6ffa178e8 +Author: Guus Sliepen +Date: Sat May 1 15:38:04 2010 +0200 + + Use intptr_t instead of long to store a pointer. + +commit c94ede3b8708cdf105a3fecfc119a558e1583f27 +Author: Guus Sliepen +Date: Sat May 1 15:37:11 2010 +0200 + + Define WINVER before including any other header file on Windows. + +commit 8b70c5be9bc762d81354f9cd77c3748a44a4956d +Author: Guus Sliepen +Date: Fri Apr 30 23:18:22 2010 +0200 + + Remove obsolete lib/ directory. + +commit ee427cac0d04c60d09cc235c04664eab8b0c6527 +Author: Guus Sliepen +Date: Fri Apr 30 23:13:02 2010 +0200 + + Do not try to free NULL pointers. + +commit 113458c2864ec8c046ab7d63ff1b417252c8e4df +Author: Guus Sliepen +Date: Fri Apr 30 23:11:48 2010 +0200 + + Use correct digest length when checking a received key. + +commit 76b41ba20dc9783ff0d21dd738739a81d62142e7 +Author: Guus Sliepen +Date: Sat Apr 17 12:33:36 2010 +0200 + + Add missing return statement. + +commit 2911af6e23d0dba6d771fcd590551a84bd9dc932 +Author: Guus Sliepen +Date: Sat Apr 17 12:33:15 2010 +0200 + + Fix merge of commit 4a0b9981513059755b9fd15b38fc198f46a0d6f2. + +commit 79e46d08a46f2fef2ee4e8eac7ba487007160564 +Merge: 4ce4af4 4766359 +Author: Guus Sliepen +Date: Sat Apr 17 12:21:53 2010 +0200 + + Merge branch 'master' into 1.1 + + Conflicts: + NEWS + README + configure.in + src/net.c + src/net.h + +commit 4ce4af4c712c80d08630767ec34787253da1021b +Author: Guus Sliepen +Date: Sat Apr 17 12:03:08 2010 +0200 + + Fix experimental GUI when reading hexadecimal values. + +commit 4766359e1426bdf1383c898d6103d8760e5e296d +Author: Guus Sliepen +Date: Sat Apr 17 12:01:38 2010 +0200 + + Fix reading configuration files that do not end with a newline. Again. + +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 e49891e188f618a0e98f1d30bcbf240286e8ad5c +Author: Sven-Haegar Koch +Date: Wed Mar 31 03:56:53 2010 +0200 + + Fixed metadata protokoll corruption on forwarded requests + + When forwarding a metadata request through forward_request() we were + adding the required newline char to our buffer, but then sending the + data without it - this results in the forwarded request and the next one + to be garbled together. + + Additionally while at it add a warning comment that request string is + not zero terminated anymore after a call to the forward_request() + function - for now this is ok as it is not used by any caller after this. + +commit 0310deb225cad21c458fb32fd589027e3f844735 +Author: Sven-Haegar Koch +Date: Fri Mar 26 17:25:18 2010 +0100 + + Demote all LOG_EMERG to LOG_ERR, spamming all xterms is bad. + +commit d5654f568dcaf81341395b52b2711f68c0417ec6 +Author: Sven-Haegar Koch +Date: Fri Mar 26 16:54:13 2010 +0100 + + README.git: tinc 1.1 needs libevent + +commit 685509ffe10d1bf9c409e5ba90f46cd747f2d9cd +Author: Sven-Haegar Koch +Date: Sun Mar 28 17:51:26 2010 +0200 + + Function flush_meta() does not exist anymore. + +commit c6d2b9d734859ccbd9582b28351983a12b04abb0 +Author: Sven-Haegar Koch +Date: Fri Mar 26 17:07:30 2010 +0100 + + Add missing AC_CHECK_HEADERS([dirent.h]) to configure.in + +commit ffa1dc73dcd62a856325641972a13d398aa8121c +Author: Sven-Haegar Koch +Date: Fri Mar 26 17:18:04 2010 +0100 + + Fixed 1.0 miss-merges + +commit 103543aa2c15d9f1e2aa313a2e593a7524cce484 +Merge: 35b1c25 2923549 +Author: Sven-Haegar Koch +Date: Fri Mar 26 16:51:03 2010 +0100 + + Merge branch 'master' into 1.1 + + Conflicts: + NEWS + README + configure.in + have.h + src/conf.c + src/conf.h + src/net.c + src/net_packet.c + src/protocol_key.c + src/protocol_subnet.c + src/route.c + src/tincd.c + +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 + + 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 35b1c25093a478d20e01f0ff391c9cdc9c41c2b8 +Author: Guus Sliepen +Date: Thu Dec 31 13:19:13 2009 +0100 + + Move source from lib/ to src/. + + The utility functions in the lib/ directory do not really form a library. + Also, now that we build two binaries, tincctl does not need everything that was + in libvpn.a, so it is wasteful to link to it. + +commit 41497246eeccbcc417f93c2ae087e927751c6914 +Author: Guus Sliepen +Date: Thu Dec 31 13:09:14 2009 +0100 + + Remove unused AVL tree library. + +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 36261650024ba8e18f9c77396f1d7a4e51f20602 +Author: Guus Sliepen +Date: Sat Dec 19 23:23:25 2009 +0100 + + Do not use hardcoded cipher block length when padding. + +commit f542ef8f9e645bf30e11e196dd768fac4f957eac +Author: Guus Sliepen +Date: Sat Dec 19 22:17:39 2009 +0100 + + Fix alignment of results of RSA operations when using libgcrypt. + + If the result of an RSA encryption or decryption operation can be represented + in less bytes than given, gcry_mpi_print() will not add leading zero bytes. Fix + this by adding those ourself. + +commit 4c68a8cb60eb0a4c05d9ce98963b930a976b55ee +Author: Guus Sliepen +Date: Sat Dec 19 20:53:48 2009 +0100 + + Do not consider unreachable nodes when trying to determine packet origin. + +commit 74e50d52e0e23c9dd1e21fb447f1e1a59d02d0b2 +Author: Guus Sliepen +Date: Sat Dec 19 20:52:19 2009 +0100 + + recv() and recvfrom() return int, do not prematurely cast the return value. + +commit 0bfd69a2736cb98470b47c1f6cba617b58bb86ef +Author: Guus Sliepen +Date: Sat Dec 19 20:26:30 2009 +0100 + + Fix reading raw RSA keys with libgcrypt. + +commit 0ff44fc2417217d542bf0e9a7ecfd20020893bc7 +Author: Guus Sliepen +Date: Sat Dec 19 20:10:38 2009 +0100 + + Reinitialise block cipher IV each time we encrypt a packet when using libgcrypt. + +commit 3c90be7678566203d38624c4a6fe3affaffbe5e3 +Author: Guus Sliepen +Date: Sat Dec 19 18:57:54 2009 +0100 + + Fix block cipher padding when using libgcrypt. + +commit c845bc109c85e6fb350096c63e13ef8e617ee29b +Author: Guus Sliepen +Date: Fri Dec 18 01:15:25 2009 +0100 + + Fix packet authentication. + + This wasn't working at all, since we didn't do HMAC but just a plain hash. + Also, verification of packets failed because it was checking the whole packet, + not the packet minus the HMAC. + +commit 10d609b1f0dd9eeb024cd40359683d48542aecbf +Author: Guus Sliepen +Date: Wed Dec 16 21:18:21 2009 +0100 + + Start of a GUI for tinc. + +commit 55ef2f806f9840103bceb472564a711b22e73d58 +Author: Guus Sliepen +Date: Wed Dec 16 21:16:56 2009 +0100 + + Allow connections to be closed. + + This only closes existing meta connections, it may not affect node + reachability. + +commit f12c36afd5293ddbecccf13f36edb8d36e56f040 +Author: Guus Sliepen +Date: Mon Dec 14 21:25:06 2009 +0100 + + Include missing header files and source directories. + +commit 2a410cd26d25cc01b96d255644df3ad138eae776 +Author: Guus Sliepen +Date: Mon Dec 14 21:20:56 2009 +0100 + + Do not include OpenSSL headers directly. + +commit 5d78e497f1c352c8d490eed1d44d128523a34572 +Author: Guus Sliepen +Date: Fri Dec 11 22:38:06 2009 +0100 + + Fix compiler warnings. + +commit d6c50eb73ad49bd2eac67214995dff76b7a20661 +Merge: fec1479 369fe1a +Author: Guus Sliepen +Date: Fri Dec 11 22:31:27 2009 +0100 + + Merge branch 'master' into 1.1 + + Conflicts: + src/subnet.c + +commit fec14791e869180bb7994ca38ca7006cc2e957fb +Author: Guus Sliepen +Date: Fri Dec 11 22:24:07 2009 +0100 + + Only call ioctlsocket() on Windows. + +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 edebf579f2ea29e6e84360cb13731f5858a1555b +Author: Guus Sliepen +Date: Sat Nov 7 23:43:25 2009 +0100 + + Use the TCP socket infrastructure for control sockets. + + The control socket code was completely different from how meta connections are + handled, resulting in lots of extra code to handle requests. Also, not every + operating system has UNIX sockets, so we have to resort to another type of + sockets or pipes for those anyway. To reduce code duplication and make control + sockets work the same on all platforms, we now just connect to the TCP port + where tincd is already listening on. + + To authenticate, the program that wants to control a running tinc daemon must + send the contents of a cookie file. The cookie is a random 256 bits number that + is regenerated every time tincd starts. The cookie file should only be readable + by the same user that can start a tincd. + + Instead of the binary-ish protocol previously used, we now use an ASCII + protocol similar to that of the meta connections, but this can still change. + +commit c388527e341658dc915dd67c90bbc9b52b8539c0 +Author: Guus Sliepen +Date: Sat Nov 7 16:09:56 2009 +0100 + + Small fixes to get really working control sockets on Windows. + +commit 5c5548fc7185cc1462602dadcd39a53cef481d29 +Author: Guus Sliepen +Date: Sat Nov 7 14:35:48 2009 +0100 + + Better integration of libevent in build system. + + Since event.h is not part of tinc, we include it in have.h were all other + system header files are included. We also ensure -levent comes before -lgdi32 + when compiling with MinGW, apparently it doesn't work when the order is + reversed. + +commit 075264a9e18f9fd58cad044c064a91557e9ed429 +Author: Guus Sliepen +Date: Thu Nov 5 23:29:28 2009 +0100 + + Make sure the 1.1 branch compiles in a MinGW environment. + + UNIX domain sockets, of course, don't exist on Windows. For now, when compiling + tinc in a MinGW environment, try to use a TCP socket bound to localhost as an + alternative. + +commit 08615e420b2dd5054dd978bf53c88b8dde6e4788 +Author: Guus Sliepen +Date: Thu Nov 5 00:02:42 2009 +0100 + + Handle PKCS#5 padding in the gcrypt backend. + +commit d9b2ac6767f85927a26e2b95bba69c052ac503ac +Author: Guus Sliepen +Date: Thu Nov 5 00:01:25 2009 +0100 + + Handle truncated message authentication codes with gcrypt. + + Commit 4124b9682f8f890acb25d0c92f2583eef670274a did not update the gcrypt + backend. + +commit c4afc481541bff4db7f57c81796b7a5f61cdb1b5 +Author: Guus Sliepen +Date: Wed Nov 4 16:19:08 2009 +0100 + + Use %x instead of %lx where appropriate. + + Some conversions were not properly merged from the master branch. + +commit 37ccb325af5c7865eb16716780121a8a6dce8abd +Author: Guus Sliepen +Date: Wed Nov 4 16:18:08 2009 +0100 + + Don't enable device events when there is no valid filedescriptor. + +commit 108b238915c5f58b3d94ab433dc5d04e064c2b11 +Merge: 761517c 44834d0 +Author: Guus Sliepen +Date: Mon Nov 2 14:24:27 2009 +0100 + + Merge branch 'master' into 1.1 + + Conflicts: + NEWS + README + configure.in + doc/tinc.texi + doc/tincd.8.in + src/Makefile.am + src/connection.c + src/edge.c + src/meta.c + src/net.c + src/net.h + src/net_packet.c + src/net_setup.c + src/net_socket.c + src/node.c + src/openssl/rsagen.h + src/protocol_auth.c + src/protocol_edge.c + src/subnet.c + +commit 44834d030464bbe1f7733caba8d96c678f1d6cf2 +Author: Guus Sliepen +Date: Sun Nov 1 16:24:39 2009 +0100 + + Releasing 1.0.11. + +commit d331f04e4598824afc7de33ac1228cf441ae9872 +Author: Guus Sliepen +Date: Sun Nov 1 15:57:28 2009 +0100 + + Start a tinc service if it already exists. + +commit 6f6f426b353596edca77829c0477268fc2fc1925 +Author: Guus Sliepen +Date: Tue Oct 27 23:53:49 2009 +0100 + + Fast handoff of roaming MAC addresses. + + In switch mode, if a known MAC address is claimed by a second node before it + expired at the first node, it is likely that this is because a computer has + roamed from the LAN of the first node to that of the second node. To ensure + packets for that computer are routed to the second node, the first node should + delete its corresponding Subnet as soon as possible, without waiting for the + normal expiry timeout. + +commit e00b44cb98e4d50a0d426048ba01dbd80bcb5941 +Author: Guus Sliepen +Date: Sun Oct 25 01:40:07 2009 +0200 + + Move socket error interpretation to utils.h. + +commit c11dc8079b60d9f8c5b1c7e8fecd90d0fac5a20c +Author: Guus Sliepen +Date: Sun Oct 25 00:50:09 2009 +0200 + + Use WSAGetLastError() to determine cause of network errors on Windows. + + This reduces log spam and lets path MTU discovery work faster. + +commit 1bca167b7e24a9cb00ad6130c24f0bb60e208f1f +Author: Michael Tokarev +Date: Sun Oct 18 21:27:24 2009 +0400 + + Remove localedir leftovers. + +commit c3acae034c4da2d1c70f31b852b14ca098c0eeb9 +Author: Guus Sliepen +Date: Sat Oct 24 22:32:35 2009 +0200 + + Use IP_DONTFRAGMENT instead of IP_MTU_DISCOVER on Windows. + + This ensures the DF bit on outgoing UDP packets gets set on Windows when path + MTU discovery is enabled, reducing fragmentation. + +commit 242c4e2ca67d0b5c78dfe6e68a5ddcd27be1de99 +Author: Guus Sliepen +Date: Sat Oct 24 21:53:01 2009 +0200 + + Forward packets to not directly reachable hosts via UDP if possible. + + If MTU probing discovered a node was not reachable via UDP, packets for it were + forwarded to the next hop, but always via TCP, even if the next hop was + reachable via UDP. This is now fixed by retrying to send the packet using + send_packet() if the destination is not the same as the nexthop. + +commit d922db253cd098bc038449e5c591cc94c1019952 +Author: Guus Sliepen +Date: Sat Oct 24 21:35:40 2009 +0200 + + Make maxmtu equal to minmtu when fixing the path MTU to a node. + + This ensures MTU probes used to ping nodes are not too large, and prevents + restarting MTU probing unnecessarily. + +commit a8f7fccbc2b5f1c4c39fc2804abaa358b31a5080 +Author: Guus Sliepen +Date: Sat Oct 24 21:32:06 2009 +0200 + + Always reply to MTU probes via UDP. + + It could sometime happen that a node would return MTU probes via TCP, which + does not make a lot of sense. + +commit cddcdc9af34afb388a8e4bdfff6882f568b98313 +Author: Guus Sliepen +Date: Sat Oct 24 20:54:44 2009 +0200 + + Allow UDP packets with an address different from the corresponding TCP connection. + +commit 5cbddc68bade0d1f8ded1b784bb27bb44c5dc5dc +Author: Guus Sliepen +Date: Sat Oct 24 16:15:24 2009 +0200 + + Use uint32_t instead of long int for connection options. + + Options should have a fixed width anyway, but this also fixes a possible MinGW + compiler bug where %lx tries to print a 64 bit value, even though a long int is + only 32 bits. + +commit 468f393c4fabf9223a1bd15adfb3906cde90d547 +Author: Guus Sliepen +Date: Sat Oct 24 16:05:12 2009 +0200 + + Add dummy device. + +commit b6543af7626403516b5fc54c24b11d3a242a2992 +Author: Guus Sliepen +Date: Tue Oct 20 22:39:07 2009 +0200 + + Clarify and increase level of log message about MTU probes to unreachable nodes. + +commit 43a6e786648fb666a9b7be8f05c8a173031c9110 +Author: Guus Sliepen +Date: Tue Oct 20 22:33:16 2009 +0200 + + Handle weighted Subnets in switch and hub modes. + + We now handle MAC Subnets in exactly the same way as IPv4 and IPv6 Subnets. + This also fixes a problem that causes unncessary broadcasting of unicast + packets in VPNs where some daemons run 1.0.10 and some run other versions. + +commit 3a925479c2883a6a9711f7b6931863d7f2a2c09b +Author: Guus Sliepen +Date: Tue Oct 20 22:22:59 2009 +0200 + + Starting to work towards 1.0.11. + +commit 35af4051c3749cd2c2137a7eb57171a1fbb12af7 +Author: Guus Sliepen +Date: Tue Oct 20 22:14:47 2009 +0200 + + Fix a possible crash when sending the HUP signal. + + When the HUP signal is sent while some outgoing connections have not been made + yet, or are being retried, a NULL pointer could be dereferenced resulting in + tinc crashing. We fix this by more careful handling of outgoing_ts, and by + deleting all connections that have not been fully activated yet at the HUP + signal is received. + +commit 8c267d3d558ac97a4ce7381a37abb6cc4b46b133 +Author: Guus Sliepen +Date: Sun Oct 18 16:45:13 2009 +0200 + + Releasing 1.0.10. + +commit 3849de9a331ad132ed9d01c9f0cac47196624b3e +Author: Guus Sliepen +Date: Sun Oct 18 16:44:32 2009 +0200 + + Fix description of the WEIGHT environment variable. + +commit 87364c16564c897b1a2d306615804d68ea5a9ba1 +Author: Guus Sliepen +Date: Sun Oct 18 14:22:20 2009 +0200 + + Include missing header. + +commit c7fdc7d5b8d728c744b13a823e7eef9d2432c61e +Author: Guus Sliepen +Date: Mon Oct 12 23:51:57 2009 +0200 + + Remove debugging message when reading packets from a BSD device. + + This was inadvertently introduced by commit + 4a5d42178cc0954efba8b24058da9c70cc77c35a. + +commit ec4c8bcb18c1f463cf4544126e027fc8ec9b3a39 +Author: Guus Sliepen +Date: Mon Oct 12 22:14:47 2009 +0200 + + Allow the cloning /dev/tap interface to be used on FreeBSD and NetBSD. + + This device works like /dev/tun on Linux, automatically creating a new tap + interface when a program opens it. We now pass the actual name of the newly + created interface in $INTERFACE. + +commit 92b8abc921dd15b710f67335562210eb713fbb39 +Author: Guus Sliepen +Date: Sun Oct 11 18:57:58 2009 +0200 + + Use MTU probes to regularly ping other nodes over UDP. + + This keeps NAT mappings for UDP alive, and will also detect when a node is not + reachable via UDP anymore or if the path MTU is decreasing. Tinc will fall back + to TCP if the node has become unreachable. + + If UDP communication is impossible, we stop sending probes, but we retry if it + changes its keys. + + We also decouple the UDP and TCP ping mechanisms completely, to ensure tinc + properly detects failure of either method. + +commit 927064e5fd0ebf29a7ea768a7f9c4226da626a72 +Author: Guus Sliepen +Date: Sun Oct 11 15:46:52 2009 +0200 + + Small updates to the documentation. + + Mention that TCPOnly is not necessary anymore since tinc will autodetect + whether it can send via UDP or not. Also mention the WEIGHT environment + variable and the new default value (2048 bits) of RSA keys. + +commit 2c30af6c90926340a89748c63cc453b1c0b5a589 +Author: Guus Sliepen +Date: Sun Oct 11 14:20:14 2009 +0200 + + Ensure that the texinfo manual can be converted to HTML. + + The top node was made conditional with the @iftex command, since it should not + appear in PostScript and PDF output. However, it is still necessary for + texi2html, so we have to use @ifnottex instead. + + Texi2html also complains about the use of @cindex in the copyright statement, + so we remove that. + +commit a4f132770dc136d456c67b01d209e73f5f4d7a65 +Author: Guus Sliepen +Date: Sun Oct 11 13:56:04 2009 +0200 + + Revert "Raise default crypto algorithms to AES256 and SHA256." + + Although it would be better to have the new defaults, only the most recent + releases of most of the platforms supported by tinc come with a version of + OpenSSL that supports SHA256. To ensure people can compile tinc and that nodes + can interact with each other, we revert the default back to Blowfish and SHA1. + + This reverts commit 4bb3793e38b7c7f24dd308801e7f6dbb02cf02d2. + +commit 2762509be179dcb21d855f3d6f90d3ee686e3910 +Author: Guus Sliepen +Date: Sun Oct 11 13:54:05 2009 +0200 + + Remove code duplication when checking ADD_EDGE/DEL_EDGE messages. + +commit 5cddf5e52aeb20e50c887356ad23aec354e04151 +Author: Guus Sliepen +Date: Sun Oct 11 13:51:10 2009 +0200 + + Don't disconnect clients in TunnelServer mode who send unauthorised ADD_SUBNETs. + + So that we are liberal in what we accept. + +commit 430c90412c521c534113b3c4e5fc883e9b7ecff0 +Author: Borg +Date: Sat Oct 3 13:06:00 2009 +0200 + + Removed last gettext function. + +commit 3282375f4d64d9402141ac4bf142629ec2e1cd53 +Author: Guus Sliepen +Date: Tue Sep 29 16:25:20 2009 +0200 + + Remove autogenerated files from EXTRA_DIST. + + Apparently they were once necessary, but autoconf now includes them + automatically. Some of them are not used anymore, and this caused make dist to + fail. + +commit 761517c21c37a808a19b487aa116c3c19439feca +Author: Guus Sliepen +Date: Tue Sep 29 15:33:58 2009 +0200 + + Update FSF address in files not covered by the merge. + +commit 07a560eab66b575f382428a956550817697e25e2 +Author: Guus Sliepen +Date: Tue Sep 29 15:19:55 2009 +0200 + + Drop localisation and checkpoint tracing in files not covered by the merge. + +commit 7ea85043ac1fb2096baea44f6b0af27ac0d0b2cf +Merge: f1fec46 9a2b0f8 +Author: Guus Sliepen +Date: Tue Sep 29 14:55:29 2009 +0200 + + Merge branch 'master' into 1.1 + + Conflicts: + NEWS + configure.in + lib/Makefile.am + lib/pidfile.c + lib/pidfile.h + lib/utils.c + po/POTFILES.in + po/nl.po + src/Makefile.am + src/bsd/device.c + src/conf.c + src/connection.c + src/cygwin/device.c + src/edge.c + src/event.c + src/graph.c + src/linux/device.c + src/meta.c + src/mingw/device.c + src/net.c + src/net_packet.c + src/net_setup.c + src/net_socket.c + src/netutl.c + src/node.c + src/process.c + src/protocol.c + src/protocol_auth.c + src/protocol_edge.c + src/protocol_key.c + src/protocol_misc.c + src/protocol_subnet.c + src/raw_socket/device.c + src/route.c + src/solaris/device.c + src/subnet.c + src/tincd.c + src/uml_socket/device.c + +commit 9a2b0f88a9cae753ebc81c939d01403178b18a35 +Author: Guus Sliepen +Date: Sat Sep 26 12:51:52 2009 +0200 + + Update the NEWS. + +commit 46e481dc945c5572eb6091a3660f6bf258ee0cfa +Author: Guus Sliepen +Date: Fri Sep 25 21:14:56 2009 +0200 + + Add more authors to the copyright headers. + + Git's log and blame tools were used to find out which files had significant + contributions from authors who sent in patches that were applied before we used + git. + +commit 4c85542894f7fca823b119b05e07179deb24229a +Author: Guus Sliepen +Date: Fri Sep 25 00:54:07 2009 +0200 + + Drop support for localisation. + + Localised messages don't make much sense for a daemon, and there is only the + Dutch translation which costs time to maintain. + +commit a227843b739d279b63adcf3736ebb03d856080c4 +Author: Guus Sliepen +Date: Fri Sep 25 00:33:04 2009 +0200 + + Remove checkpoint tracing. + + This feature is not necessary anymore since we have tools like valgrind today + that can catch stack overflow errors before they make a backtrace in gdb + impossible. + +commit 5dde6461a321ee47b06e33f8203f2acf00a31a51 +Author: Guus Sliepen +Date: Fri Sep 25 00:14:03 2009 +0200 + + K&R style braces. + + This is essentially commit f02d3ed3e135b5326003e7f69f8331ff6a3cc219 from the + 1.1 branch, making it easier to merge between master and 1.1. + +commit ab7c61b06f6c6e991225f2fcc32d02b8e1084aee +Author: Guus Sliepen +Date: Fri Sep 25 00:01:00 2009 +0200 + + Update the address of the Free Software Foundation in all copyright headers. + +commit 0e6856b1379e278aa5ed116d0911851339a6064c +Author: Guus Sliepen +Date: Thu Sep 24 23:42:30 2009 +0200 + + Remove Ivo's old email addresses. + +commit c217d214f4f071c235bc7c463a1da6124e2570a6 +Author: Guus Sliepen +Date: Thu Sep 24 23:39:16 2009 +0200 + + Remove all occurences of $Id$. + +commit c23fcf555ee4b69f03b76a0ffb731c3a475a77e7 +Author: Guus Sliepen +Date: Thu Sep 24 23:29:46 2009 +0200 + + Update copyright information. + + - Update year numbers in copyright headers. + - Add copyright information for Michael Tokarev and Florian Forster to the + copyright headers of files to which they have contributed significantly. + - Mention Michael and Florian in AUTHORS. + - Mention that tinc is GPLv3 or later if compiled with the --enable-tunemu + flag. + +commit f1fec466e232c00c668422014029dce9114d3add +Author: Guus Sliepen +Date: Wed Sep 16 23:43:19 2009 +0200 + + Add a better autoconf check for libevent. + +commit 4bdf0e80ee4cd0d40eb6522dab05df9346a5b3d0 +Author: Guus Sliepen +Date: Wed Sep 16 20:28:30 2009 +0200 + + Replace asprintf()s not covered by the merge to xasprintf(). + +commit 1cbddbd573d786f6b2bf9812dda89d1ea5b7e021 +Author: Guus Sliepen +Date: Wed Sep 16 20:17:11 2009 +0200 + + Use correct format specifiers. + +commit 2f97bdb46b1ed0a669619e0b9acf76f43dfa648b +Author: Guus Sliepen +Date: Wed Sep 16 20:16:54 2009 +0200 + + Add missing #include. + +commit 075e6828a7533e7daa790225f17aa6bb39703278 +Merge: 9b129c0 b5ccce2 +Author: Guus Sliepen +Date: Wed Sep 16 19:55:47 2009 +0200 + + Merge branch 'master' into 1.1 + + Conflicts: + have.h + lib/dropin.c + lib/fake-getaddrinfo.c + lib/pidfile.c + src/Makefile.am + src/bsd/device.c + src/conf.c + src/connection.c + src/connection.h + src/graph.c + src/mingw/device.c + src/net.c + src/net_setup.c + src/node.c + src/protocol_key.c + src/protocol_misc.c + src/tincd.c + +commit b5ccce296848aab72d574ca3de14af5fdf3efa4d +Author: Guus Sliepen +Date: Tue Sep 15 23:22:13 2009 +0200 + + Send large packets we cannot handle properly via TCP. + + During the path MTU discovery phase, we might not know the maximum MTU yet, but + we do know a safe minimum. If we encounter a packet that is larger than that + the minimum, we now send it via TCP instead to ensure it arrives. We also + allow large packets that we cannot fragment or create ICMP replies for to be + sent via TCP. + +commit d273efb177738d429e3cef7d8db8ee5cc8dcada7 +Author: Guus Sliepen +Date: Tue Sep 15 23:04:52 2009 +0200 + + Raise default RSA key length to 2048 bits. + +commit b47c17bcdeb70b63ad9346dc97ba575597cbd803 +Author: Guus Sliepen +Date: Tue Sep 15 22:59:01 2009 +0200 + + Use a mutex to allow the TAP reader to process packets faster on Windows. + + The TAP-Win32 device is not a socket, and select() under Windows only works + with sockets. Tinc used a separate thread to read from the TAP-Win32 device, + and passed this via a local socket to the main thread which could then select() + from it. We now use a global mutex, which is only unlocked when the main thread + is waiting for select(), to allow the TAP reader thread to process packets + directly. + +commit 802a50ffcd5f39bfc6424ac841de4e41154092fc +Author: Guus Sliepen +Date: Tue Sep 15 22:58:16 2009 +0200 + + Remove extra {. + +commit 4bb3793e38b7c7f24dd308801e7f6dbb02cf02d2 +Author: Guus Sliepen +Date: Tue Sep 15 12:08:05 2009 +0200 + + Raise default crypto algorithms to AES256 and SHA256. + + In light of the recent improvements of attacks on SHA1, the default hash + algorithm in tinc is now SHA256. At the same time, the default symmetric + encryption algorithm has been changed to AES256. + +commit 633c0cf1b067d118d5453bc8522fab65ffc82d2c +Author: Guus Sliepen +Date: Tue Sep 15 00:36:07 2009 +0200 + + Use access() instead of stat() for checking whether scripts exist. + +commit 6f1e0ece4e61f30612ed84ca4640635a02892cc8 +Author: Guus Sliepen +Date: Tue Sep 15 00:28:20 2009 +0200 + + Remove dropin random() function, as it is not used anymore. + +commit fa9bedd47cf8c143e801889c78f0a0979ac4d2fc +Author: Guus Sliepen +Date: Tue Sep 15 00:24:31 2009 +0200 + + Allow compiling for Windows XP and higher. + + This allows us to use getaddrinfo(), getnameinfo() and related functions, which + allow tinc to make connections over existing IPv6 networks. These functions are + not available on Windows 2000 however. By default, support is enabled, but when + compiling for Windows 2000 the configure switch --with-windows2000 should be + used. + + Since getaddrinfo() et al. are not functions but macros on Windows, we have to + use AC_CHECK_DECLS() instead of AC_CHECK_FUNCS() in configure.in. + +commit f80bf14f28925df6eaa56f3ed77adaf418ab9890 +Author: Guus Sliepen +Date: Mon Sep 14 23:28:28 2009 +0200 + + Also do not use drand48(), it is not available on Windows. + +commit 35e87b903e08fc51975a8cc97f06251d5153a424 +Author: Guus Sliepen +Date: Mon Sep 14 23:06:00 2009 +0200 + + Use only rand(), not random(). + + We used both rand() and random() in our code. Since it returns an int, we have + to use %x in our format strings instead of %lx. This fixes a crash under + Windows when cross-compiling tinc with a recent version of MinGW. + +commit 75773efe2689d347a2f219c5f27e4a82eef1236b +Author: Guus Sliepen +Date: Sun Sep 13 14:08:59 2009 +0200 + + Apparently it's impolite to ask GCC to subtract two pointers. + + If two pointers do not belong to the same array, pointer subtraction gives + nonsensical results, depending on the level of optimisation and the + architecture one is compiling for. It is apparently not just subtracting the + pointer values and dividing by the size of the object, but uses some kind of + higher magic not intended for mere mortals. GCC will not warn about this at + all. Casting to void * is also a no-no, because then GCC does warn that strict + aliasing rules are being broken. The only safe way to query the ordering of two + pointers is to use the (in)equality operators. + + The unsafe implementation of connection_compare() has probably caused the "old + connection_t for ... still lingering" messages. Our implementation of AVL trees + is augmented with a doubly linked list, which is normally what is traversed. + Only when deleting an old connection the tree itself is traversed. + +commit 23e151aeed6b3ffe0fab10f51ffdb134deb7a852 +Author: Guus Sliepen +Date: Sun Sep 13 14:07:40 2009 +0200 + + Remove superfluous call to avl_delete(). + +commit 9915f2abbedb7f1aa2b9e2f81d52ddcfca60e82d +Author: Guus Sliepen +Date: Sat Sep 12 14:19:36 2009 +0200 + + Handle unicast packets larger than PMTU in switch mode. + + If PMTUDiscovery is enabled, and we see a unicast packet that is larger than + the path MTU in switch mode, treat it just like we would do in router mode. + +commit 7242868b64f9d6f62b6c5bbf1526eb632ed9a4d6 +Author: Guus Sliepen +Date: Sat Sep 12 13:40:32 2009 +0200 + + Allow PMTUDiscovery in switch and hub modes again. + + PMTUDiscovery was disabled in commit d5b56bbba56480b5565ffb38496175a7c1df60ac + because tinc did not handle packets larger than the path MTU in switch and hub + modes. We now allow it again in preparation of proper support, but default to + off. + +commit 052ff8b2c598358d1c5febaa9f9f5fc5d384cfd3 +Author: Guus Sliepen +Date: Sat Sep 12 13:34:11 2009 +0200 + + Put Subnet weight in a separate environment variable. + + Commit 5674bba5c54c1aee3a4ac5b3aba6b3ebded91bbc introduced weighted Subnets, + but the weight was included in the SUBNET variable passed to subnet-up/down + scripts. This makes it harder to use in those scripts. The weight is now + stripped from the SUBNET variable and put in the WEIGHT variabel. + +commit a60a0a1f1357508063ee565d672c39898a787e33 +Author: Guus Sliepen +Date: Thu Sep 10 19:51:08 2009 +0200 + + Don't stat() on iPhone/iPod. + + Grzegorz Dymarek noted that tinc segfaults at the stat() call in + execute_script() on the iPhone. We can omit the stat() call for the moment, + the subsequent call to system() will fail with just a warning. + +commit 4a5d42178cc0954efba8b24058da9c70cc77c35a +Author: Guus Sliepen +Date: Thu Sep 10 19:32:54 2009 +0200 + + Add support for iPhones and recent iPods. + + This is a slightly modified patch from Grzegorz Dymarek that allows tinc to use + the tunemu device, which allows tinc to be compiled for iPhones and recent + iPods. To enable support for tunemu, the --enable-tunemu option has to be used + when running the configure script. + +commit ff946d0423fe547ea42bb11acfb3035c3b8aee4e +Author: Guus Sliepen +Date: Wed Sep 9 14:51:36 2009 +0200 + + Another safe bitfield conversion. + +commit dd6226062c2356d2a3679e2c7972be71233cb9de +Author: Guus Sliepen +Date: Wed Sep 9 13:23:16 2009 +0200 + + Add the GPL license to the repository. + + Tinc is licensed under the GPL version 2 or later. To ensure autoconf does not + install the wrong license if COPYING is missing, we have to put the right one + in place. + +commit 81afa26e4ad53bea00da18a7666f63d33cf3f588 +Author: Guus Sliepen +Date: Wed Sep 9 12:04:08 2009 +0200 + + Convert bitfields to integers in a safe way. + + This is commit eb391c52eed46f3f03b404553df417851fc0cb90 redone, but without the + non-standard anonymous union. + +commit 9b394bc887695da6db74f4b9796b4823e553f8cc +Author: Guus Sliepen +Date: Tue Sep 8 21:45:24 2009 +0200 + + Ensure tinc compiles with gcc -std=c99. + + We use a lot of C99 features already, but also some extensions which are not in + the standard. + +commit f52ea0a7eb0383cc2a5f41db1bf24c39424fdb04 +Author: Guus Sliepen +Date: Tue Sep 8 18:21:52 2009 +0200 + + UNIX signal numbers start at 1. + +commit 73d77dd416b87b7c4e9b6aa450f64846235cd2b4 +Author: Guus Sliepen +Date: Tue Sep 8 18:18:36 2009 +0200 + + Replace asprintf() by xasprintf(). + +commit 3e55dc77f4ba19fd9e79f3d5ce9d28bb6b05019e +Author: Guus Sliepen +Date: Tue Sep 8 18:18:16 2009 +0200 + + Check the return value of fscanf() when reading a PID file. + +commit 5e0efd53e797a2b5468b91b41b6122f3b942efb2 +Author: Guus Sliepen +Date: Tue Sep 8 18:16:58 2009 +0200 + + Add xasprintf() and xvasprintf(). + + These functions wrap asprintf() and vasprintf(), and check the return value. If + the function failed, tinc will exit with an error message, similar to xmalloc() + and friends. + +commit 63fe89e9eb8ef9077bfe3cd416c86820715eb33b +Author: Michael Tokarev +Date: Sat Sep 5 17:24:41 2009 +0400 + + Remove extra semicolon in my definition of setpriority() + +commit 5a7fc58012da10b96073804994777255463d1b8d +Author: Guus Sliepen +Date: Tue Sep 8 16:35:28 2009 +0200 + + Always remove a node from the UDP tree before freeing it. + + Valgrind caught tinc reading free'd memory during a purge(). This was caused by + first removing it from the main node tree, which will already call free_node(), + and then removing it from the UDP tree. This might cause spurious segmentation + faults. + +commit de029ce46056e02908b5390da9b71a6a59133f26 +Author: Guus Sliepen +Date: Thu Jun 11 19:39:25 2009 +0200 + + Change level of some debug messages, zero pointer after freeing hostname. + +commit 66be914d35cb7e7ea4dd4aed68ae9e41addd9f70 +Author: Guus Sliepen +Date: Thu Jun 11 19:26:34 2009 +0200 + + Do not log errors when recvfrom() returns EAGAIN or EINTR. + + Although we select() before we call recvfrom(), it sometimes happens that + select() tells us we can read but a subsequent read fails anyway. This is + harmless. + +commit df4add94a4a6461758b218a9ad257efc735062fe +Author: Guus Sliepen +Date: Thu Jun 11 19:07:54 2009 +0200 + + Remove pending MTU probe events when a node's reachability status changes. + +commit 36f8e4da8b1708474505f5a1fa8cf1ba848921de +Author: Guus Sliepen +Date: Thu Jun 11 18:36:08 2009 +0200 + + Don't try to send MTU probes to unreachable nodes. + + If there is an outstanding MTU probe event for a node which is not reachable + anymore, a UDP packet would be sent to that node, which caused a key request to + be sent to that node, which triggered a NULL pointer dereference. Probes and + other UDP packets to unreachable nodes are now dropped. + +commit 9b129c07e273ae113f3c67a9feeee82e8146f3a1 +Author: Guus Sliepen +Date: Sat Jun 6 20:14:51 2009 +0200 + + Fix pointer arithmetic when creating and verifying message authentication codes. + +commit 4124b9682f8f890acb25d0c92f2583eef670274a +Author: Guus Sliepen +Date: Sat Jun 6 19:04:04 2009 +0200 + + Handle truncated message authentication codes. + +commit 5a132550deb58473285e5f91705d286aef47be71 +Merge: 08aabbf 591c38e +Author: Guus Sliepen +Date: Fri Jun 5 23:03:28 2009 +0200 + + Merge branch 'master' into 1.1 + + Conflicts: + doc/tincd.8.in + lib/pidfile.c + src/graph.c + src/net.c + src/net.h + src/net_packet.c + src/net_setup.c + src/net_socket.c + src/netutl.c + src/node.c + src/node.h + src/protocol_auth.c + src/protocol_key.c + src/tincd.c + +commit 261d1eac1c5bbe6c87aa707566f290e611169432 +Author: Guus Sliepen +Date: Fri Jun 5 16:14:31 2009 +0200 + + Properly set HMAC length for incoming packets. + +commit 591c38eb38dbf0851bdebdd50b08d1bcbf6d7b0f +Author: Michael Tokarev +Date: Fri Jun 5 13:33:58 2009 +0400 + + try outgoing connections before chroot/drop_privs + + When chrooted, we either need to force-initialize resolver + and/or nsswitch somehow (no clean way) or resolve all the + names we want before entering chroot jail. The latter + looks cleaner, easier and it is actually safe because + we still don't talk with the remote nodes there, only + initiating outgoing connections. + +commit a42a8dde45fe95aa3fd3f7f15a74c5166efe3633 +Author: Michael Tokarev +Date: Fri Jun 5 11:58:17 2009 +0400 + + cleanup setpriority thing to make it readable + +commit a5fb0d8c6c384b9ea1074fb469c0a3dd5b874e98 +Author: Guus Sliepen +Date: Thu May 28 23:18:22 2009 +0200 + + Add some const where appropriate. + +commit 41c10c5a966000531099c79d6006429253ff8fd6 +Author: Guus Sliepen +Date: Thu May 28 22:51:30 2009 +0200 + + Add ProcessPriority option. + + This option can be set to low, normal or high. On UNIX flavours, this changes + the nice value of the process by +10, 0 and -10 respectively. On Windows, it + sets the priority to BELOW_NORMAL_PRIORITY_CLASS, NORMAL_PRIORITY_CLASS and + HIGH_PRIORITY_CLASS respectively. + + A high priority might help to reduce latency and packet loss on the VPN. + +commit 41a05f59ba2c3eb5caab555f096ed1b9fbe69ee3 +Author: Florian Forster +Date: Wed May 27 14:20:24 2009 +0200 + + src/net_socket.c: Bind outgoing TCP sockets to `BindToAddress'. + + If a host has multiple addresses on an interface, the source address of the TCP + connection(s) was picked by the operating system while the UDP packets used a + bound socket, i. e. the source address was the address specified by the user. + This caused problems because the receiving code requires the TCP connection and + the UDP connection to originate from the same IP address. + + This patch adds support for the `BindToInterface' and `BindToAddress' options + to the setup of outgoing TCP connections. + + Tested with Debian Etch on x86 and Debian Lenny on x86_64. + + Signed-off-by: Florian Forster + +commit 6b415a1a7f5bad2fff7b133ef2a2febccb96d6e5 +Author: Florian Forster +Date: Wed May 27 09:27:44 2009 +0200 + + src/linux/device.c: Fix segfault when running without `--net'. + + If running without `--net', the (global) variable `netname' is NULL. This + creates a segmentation fault because this NULL-pointer is passed to strdup: + + Program terminated with signal 11, Segmentation fault. + #0 0xb7d30463 in strlen () from /lib/tls/i686/cmov/libc.so.6 + (gdb) bt + #0 0xb7d30463 in strlen () from /lib/tls/i686/cmov/libc.so.6 + #1 0xb7d30175 in strdup () from /lib/tls/i686/cmov/libc.so.6 + #2 0x0805bf47 in xstrdup (s=0x0) at xmalloc.c:118 <--- + #3 0x0805be33 in setup_device () at device.c:66 + #4 0x0805072e in setup_myself () at net_setup.c:432 + #5 0x08050db2 in setup_network () at net_setup.c:536 + #6 0x0805b27f in main (argc=Cannot access memory at address 0x0) at tincd.c:580 + + This patch fixes this by checking `netname' in `setup_device'. An alternative + would be to check for NULL-pointers in `xstrdup' and return NULL in this case. + + Signed-off-by: Florian Forster + +commit a8a65cee083a27afe42cab360596e1453e7141b9 +Author: Michael Tokarev +Date: Sun May 24 17:23:24 2009 +0400 + + tunnelserver: log which ADD_SUBNET was refused + + Add some logging about refused ADD_SUBNET + (it causes subsequent client disconnect so it's + important to know which subnet was at fault). + + Maybe we should just ignore it completely. + +commit 4e9e3ca89dba68cbacaaa15ddfb298b181a969da +Author: Guus Sliepen +Date: Mon May 25 15:04:33 2009 +0200 + + Do not forward broadcast packets when TunnelServer is enabled. + + First of all, the idea behind the TunnelServer option is to hide all other + nodes from each other, so we shouldn't forward broadcast packets from them + anyway. The other reason is that since edges from other nodes are ignored, the + calculated minimum spanning tree might not be correct, which can result in + routing loops. + +commit 7fc69bc73b15349dafc193a50464caeb2f978369 +Author: Guus Sliepen +Date: Mon May 25 12:19:37 2009 +0200 + + Use packet size before decompression to calculate path MTU. + + Since compression can either grow or shrink a packet, the size of an MTU probe + after decompression might not reflect the real path MTU. Now we use the size + before decompression, which is independent of the compression algorithm, and + substract a safety margin such that the calculated path MTU will be safe even + for packets which grow as much as possible after compression. + +commit 1b3add6c29f8eb424a62837e89fe7d384fc94a48 +Author: Guus Sliepen +Date: Mon May 25 12:19:08 2009 +0200 + + Add declaration for sockaddrcmp_noport(). + +commit ca5b67111e4d797d15623c2163f67fe489dc3bf2 +Author: Michael Tokarev +Date: Sun May 24 22:32:24 2009 +0400 + + Fix ans_key exchange in recent changes + + send_ans_key() was using the wrong in vs. outkeylength to + terminate the key being sent, so it was always empty. + +commit 7034338bc36d9ea96d152091b9d58c2afc3f0c20 +Author: Guus Sliepen +Date: Sun May 24 19:35:51 2009 +0200 + + Use xrealloc instead of if(ptr) ptr = xmalloc(). + +commit e012e752f4f1a2b06dfab4640bbbea8f084999ff +Author: Guus Sliepen +Date: Sun May 24 19:31:31 2009 +0200 + + Fix initialisation of packet decryption context broken by commit 3308d13e7e3bf20cfeaf6f2ab17228a9820cea66. + + Instead of a single, global decryption context, each node has its own context. + However, in send_ans_key(), the global context was initialised. This commit + fixes that and removes the global context completely. + + Also only set status.validkey after all checks have been evaluated. + +commit 0246939ce18e1af9660b782b6814be182a7af9da +Author: Michael Tokarev +Date: Fri May 22 01:10:16 2009 +0400 + + don't log every strange packet coming to the UDP port + + it's a sure way to fill up syslog. Only log those if + debug level is up to PROTOCOL + +commit 576899ef0dec3aaede9b8ac101d189798587a646 +Author: Guus Sliepen +Date: Sun May 24 17:13:00 2009 +0200 + + Fix link to Mattias Nissler's tun/tap driver for MacOS/X. + + Thanks to Martin Christof Kindsmüller for spotting. + +commit 2c67eafc6e6c5e210636c0d2bad15827bf2d7cf0 +Author: Guus Sliepen +Date: Sun May 24 15:58:47 2009 +0200 + + If PMTUDiscovery is not set, do not forward packets via TCP unnecessarily. + +commit 7e4d57adf54ce369e4111bde0ccd3ea4b9e853ee +Author: Michael Tokarev +Date: Fri May 22 01:01:35 2009 +0400 + + ignore indirect edge registrations in tunnelserver mode + + In tunnelserver mode we're not interested to hear about + our client edges, just like in case of subnets. Just + ignore all requests which are not about our node or the + client node. + + The fix is very similar to what was done for subnets. + + Note that we don't need to add the "unknown" nodes to + the list in tunnelserver mode too, so move allocation + of new nodes down the line. + +commit 3759aa5f7745709c43f81faa36510ff650b4bf99 +Author: Michael Tokarev +Date: Wed May 20 18:40:04 2009 +0400 + + TunnelServer: Don't disconnect client on DEL_SUBNET too + + Similar changes as was in 2327d3f6eb5982bcc922ff1ab1ec436ba6aeffdc + but for del_subnet_h(). + + Before, we vere returning false (and causing disconnect of the + client) in case of tunnelserver and the client sending DEL_SUBNET + for non-his subnet or for subnet which owner isn't in our connection + list. + + After the mentioned change to add_subnet_h() that routine does not + add such indirect owners to the connection list anymore, so that + was ok (owner == NULL and we return true). + + But if we too has a connection with the node about which the client + is sending DEL_SUBNET notification, say, because that client lost + connection with that other node, we'll disconnect this client from + us too, returning false for indirect DEL_SUBNET. + + Fix that by allowing and ignoring indirect DEL_SUBNET in tunnelserver + mode. + + Also rearranged the function a bit, to match add_subnet_h() (in + particular, syntax-check everything first, see if we've seen this + request before). + + And also fix some comments. + +commit 218adee785df7c79ac18395d056a2eb6d63c407f +Author: Michael Tokarev +Date: Mon May 18 17:34:30 2009 +0400 + + format 'not supported on this platform' error message + + Format it in a similar way in all places, to make translation happier. + No functional changes. + +commit 54cb6b1aecb06a1ca44a7a60c74dd0d65b0043dd +Author: Michael Tokarev +Date: Mon May 18 17:00:00 2009 +0400 + + change error messages in droppriv code to match the rest + + Change formatting of error messages about failed syscalls + to be the same as in other places in tincd. + + Also suggest a change in "$foo not supported on this platform" + message as it's now used more than once. + +commit d4f9863635d06665cfbd3c46dc482344de240e97 +Author: Michael Tokarev +Date: Mon May 18 16:53:08 2009 +0400 + + bugfix: chdir(/) after chroot + + Fix the famous chdir(".") vs chdir("/") after chroot(something). + +commit 6be5d4f5b67764115b37528d2fe01bd245b3cd3e +Author: Michael Tokarev +Date: Mon May 18 16:49:39 2009 +0400 + + bugfix: move mlock to after detach() so it works for child, not parent + + mlock()/mlockall() are not persistent across fork(), and it's + done in parent process before daemon() which does fork(). So + basically, current --mlock does nothing useful. + + Move mlock() to after detach() so it works for child process + instead of parent. + + Also, check if the platform supports mlock right when processing + options (since else we'll have to die after startup, not at + startup, the error message will be in log only). + +commit cdf7f13c31310da0c40819fd812e19519bf4318c +Author: Michael Tokarev +Date: Mon May 18 16:28:55 2009 +0400 + + bugfix: initialize pid (as read from pidfile) to zero + + If we didn't read any number from a pid file, we'll return + an unitialized variable to the caller, and it will treat + that garbage as a pid of a process (possible to kill). + + Fix that. + +commit ec316aa32e8567395a88c4583007f01ffae008ce +Author: Michael Tokarev +Date: Mon May 18 16:25:41 2009 +0400 + + Implement privilege dropping + + Add two options, -R/--chroot and -U/--user=user, to chroot to the + config directory (where tinc.conf is located) and to perform + setuid to the user specified, after all the initialization is done. + + What's left is handling of pid file since we can't remove it anymore. + +commit 6698f7c390a5ae2f262e30560d9df59f9d5c418d +Author: Michael Tokarev +Date: Mon May 18 16:25:10 2009 +0400 + + Rename setup_network_connections() and split out try_outgoing_connections() + + In preparation of chroot/setuid operations, split out call to + try_outgoing_connections() from setup_network_connections() + (which was the last call in setup_network_connections()). + This is because dropping privileges should be done in-between + setup_network_connections() and try_outgoing_connections(). + + This patch renames setup_network_connections() to setup_network() + and moves call to try_outgoing_connections() into main routine. + + No functional changes. + +commit 3308d13e7e3bf20cfeaf6f2ab17228a9820cea66 +Author: Guus Sliepen +Date: Fri Apr 3 01:05:23 2009 +0200 + + Handle UDP packets from different and ports than advertised. + + Previously, tinc used a fixed address and port for each node for UDP packet + exchange. The port was the one advertised by that node as its listening port. + However, due to NAT the port might be different. Now, tinc sends a different + session key to each node. This way, the sending node can be determined from + incoming packets by checking the MAC against all session keys. If a match is + found, the address and port for that node are updated. + +commit 08aabbf9317806bc50a9a6693ca866c8936ce26b +Merge: 551cd19 43fa728 +Author: Guus Sliepen +Date: Mon Mar 9 19:02:24 2009 +0100 + + Merge branch 'master' into 1.1 + + Conflicts: + NEWS + README + doc/tinc.conf.5.in + doc/tinc.texi + po/nl.po + src/conf.c + src/connection.c + src/event.c + src/graph.c + src/net.c + src/net_packet.c + src/net_socket.c + src/node.c + src/node.h + src/openssl/rsagen.h + src/protocol_auth.c + src/protocol_key.c + src/protocol_misc.c + src/subnet.c + src/subnet.h + src/tincd.c + +commit 43fa7283ac01f2ecc95381b519ef6b3342546f35 +Author: Guus Sliepen +Date: Mon Mar 9 14:04:31 2009 +0100 + + Use a simple Random Early Drop algorithm in send_tcppacket(). + +commit d5b56bbba56480b5565ffb38496175a7c1df60ac +Author: Guus Sliepen +Date: Mon Mar 9 13:48:54 2009 +0100 + + Disable PMTUDiscovery in switch and hub modes. + + In switch and hub modes, tinc does not generate ICMP packets in response to + packets that are larger than the path MTU. However, if PMTUDiscovery is + enabled, the IP_MTU_DISCOVER and IPV6_MTU_DISCOVER option is set on the UDP + sockets, which causes all UDP packets to be sent with the DF bit set, causing + large packets to be dropped, even if they would otherwise be routed fine. + +commit 78fc59e994c764d072bf0045177f690a378d1308 +Author: Guus Sliepen +Date: Thu Mar 5 14:12:36 2009 +0100 + + Update THANKS and copyright information. + +commit 5674bba5c54c1aee3a4ac5b3aba6b3ebded91bbc +Author: Guus Sliepen +Date: Thu Mar 5 13:34:13 2009 +0100 + + Allow weight to be assigned to Subnets. + + Tinc allows multiple nodes to own the same Subnet, but did not have a sensible + way to decide which one to send packets to. Tinc also did not check the + reachability of nodes when deciding where to route packets to, so it would not + automatically fail over to a reachable node. + + Tinc now assigns a weight to each Subnet. The default weight is 10, with lower + weights having higher priority. The Subnets are now internally sorted in the + same way as the kernel's routing table, and the Subnets are search linearly, + skipping those of unreachable nodes. A small cache of recently used addresses + is used to speed up the lookup functions. + +commit 76a1bcaffcf1f1abf81fdda379b703a004640cb4 +Author: Michael Tokarev +Date: Sat Feb 28 16:37:51 2009 +0300 + + Enable PMTUDiscovery only if BOTH sides wants it. + + Don't enable PMTUDiscovery if at least one side does not support it. + Before it was enabled if at least one side supported it, now both are required. + +commit 1c1a67fd93530b9d16538ab2897c3911d3b16574 +Author: Guus Sliepen +Date: Tue Feb 17 14:43:05 2009 +0100 + + Handle neighbor solicitation requests without link layer addresses. + + Apparently FreeBSD likes to send out neighbor solicitation requests, even on a + tun interface where this is completely pointless. These requests do not have an + option header containing a link layer address, so the proxy-neighborsol code + was treating these requests as invalid. We now handle such requests, and send + back equally pointless replies, also without a link layer address. This seems + to satisfy FreeBSD. + +commit 2327d3f6eb5982bcc922ff1ab1ec436ba6aeffdc +Author: Michael Tokarev +Date: Mon Feb 9 23:51:10 2009 +0100 + + Allow tunnelserver to work with clients that have other peers. + + In TunnelServer mode, tinc server disconnects any client if it announces + indirect subnets -- subnets that are not theirs (e.g. subnets for nodes + the CLIENT has connections now, even if those nodes are known to the server + too). Fix that by ignoring such (indirect) announces instead. + + While we're at it, move check for such indirect subnet registration to + before allocating new node structure, as in TunnelServer mode we don't + really need to know that other node. + +commit 23730375f27c32e0fe1a59c7a761dd85296a7a4a +Author: Guus Sliepen +Date: Tue Feb 3 14:54:45 2009 +0100 + + Disable old RSA keys when generating new ones. + + When generating an RSA keypair, the new public and private keys are appended to + files. However, when OpenSSL reads keys it only reads the first in a file, not + the last. Instead of printing an easily ignored warning, tinc now disables old + keys when appending new ones. + +commit 0d0dfd0852e9b2c9a7660880966a3c84790d5ea2 +Author: Guus Sliepen +Date: Tue Jan 20 14:21:50 2009 +0100 + + Validate Name before using it in a filename when generating a keypair. + +commit 0966cca8ab6dcde2747c717f21d73fd332e04242 +Author: Guus Sliepen +Date: Tue Jan 20 14:20:44 2009 +0100 + + Allow reading config files with CRLF endings on Unix systems. + +commit d1910ac198232573c1b18d8238a27bc29bc73f8a +Author: Guus Sliepen +Date: Tue Jan 20 13:19:31 2009 +0100 + + Remove unused definitions from net.h. + +commit 503c32eb0ef9d6329e931559082f4ddf6d487dc6 +Author: Guus Sliepen +Date: Tue Jan 20 13:12:41 2009 +0100 + + Use a global list to track outgoing connections. + + Previously an outgoing_t was maintained for each outgoing connection, + but the pointer to it was either stored in a connection_t or in an event_t. + This made it very hard to keep track of and to clean up. + + Now a list is created when tinc starts and reads all the ConnectTo variables, + and which is recreated when tinc receives a HUP signal. + +commit a7e793c94ec414eb71ec2aa3debc9e2e5ed5cfef +Author: Guus Sliepen +Date: Mon Jan 19 23:17:28 2009 +0100 + + Add missing cleanup functions in close_network_connections(). + +commit 116065afe352221ac6c2c8e34c109252004d6a59 +Author: Guus Sliepen +Date: Mon Jan 19 22:50:05 2009 +0100 + + Change flush_events() to expire_events(). + + The former function made a totally bogus shallow copy of the event_tree, called + the handler of each event and then deleted the whole tree. This should've + caused tinc to crash when an ALARM signal was sent more than once, but for some + reason it didn't. It also behaved incorrectly when a handler added a new event. + + The new function just moves the expiration time of all events to the past. + +commit a39a9506cd041a7092a98498b362eaacfd2f33c3 +Author: Guus Sliepen +Date: Fri Jan 9 12:36:06 2009 +0100 + + Move free()s at the end om main() to the proper destructor functions. + +commit 67df7fb7e1c9eefe4bbc920fdc68b595ef28abd9 +Author: Guus Sliepen +Date: Sat Jan 3 22:33:55 2009 +0100 + + Only send packets via UDP if UDP communication is possible. + + When no session key is known for a node, or when it is doing PMTU discovery but + no MTU probes have returned yet, packets are sent via TCP. Some logic is added + to make sure intermediate nodes continue forwarding via TCP. The per-node + packet queue is now no longer necessary and has been removed. + +commit b069da90d67b49dce041f513a3855b8da3d82f80 +Author: Guus Sliepen +Date: Sat Jan 3 22:06:10 2009 +0100 + + Consistently allocate device and iface variables on the heap. + + This fixes a segfault when no Device has been specified and tinc exits, and it + would try to free() a static string. Thanks to Borg for spottin. + +commit f81cea3bdc8683b27188cd8f24a2de906a29eb81 +Author: Guus Sliepen +Date: Sat Dec 27 11:09:43 2008 +0100 + + Update documentation for git. + +commit c81f90b91a054eeafcc3c8c45abc52045e4a8146 +Author: Guus Sliepen +Date: Fri Dec 26 13:47:34 2008 +0000 + + Releasing 1.0.9. + +commit a4d99ebf5042dedb609359cbbfc3fa4630b5fc70 +Author: Guus Sliepen +Date: Fri Dec 26 12:46:45 2008 +0000 + + Add missing parentheses in check for IPv4 multicast addresses. + +commit 099bc56f53e7d3cb7b799d26ff9535673ff03e1c +Author: Guus Sliepen +Date: Tue Dec 23 23:14:37 2008 +0000 + + Apply patch from Max Rijevski fixing a memory leak when closing connections. + It also cleans up more when stopping tinc, helping tools like valgrind. + +commit de032054dee67bcc406b4a15fb9e957a766d016a +Author: Guus Sliepen +Date: Tue Dec 23 22:31:38 2008 +0000 + + Handle broadcast and multicast packets in router mode. + Multicast packets are treated as broadcast packets. + Based on a patch from Max Rijevski. + +commit a5f899a9794f215e8174455ead04862a2c14a5b1 +Author: Guus Sliepen +Date: Mon Dec 22 21:49:23 2008 +0000 + + Update the manpage as well, and some whitespace to make its source more legible. + +commit e8f08ced76bf1b9a94dd0dc874ad22761ad8900b +Author: Guus Sliepen +Date: Mon Dec 22 21:29:21 2008 +0000 + + Update documentation. + - TCPOnly is not experimental. + - Do not mention old Linux kernels and Ethertap anymore. + - Document the DeviceType, PMTU and PMTUDiscovery options. + +commit 0e4d419aae8a82f2ae4552f755894a9bc70c83d2 +Author: Guus Sliepen +Date: Mon Dec 22 20:35:45 2008 +0000 + + Enable PMTU discovery by default. + +commit e9576632dc4b780b867044269d06cc50f76d8c05 +Author: Guus Sliepen +Date: Mon Dec 22 20:27:52 2008 +0000 + + Update copyright information. + +commit f50dc972cde2644588eabf35a2422fe0e372a024 +Author: Guus Sliepen +Date: Mon Dec 22 19:43:49 2008 +0000 + + Update Dutch translation. + +commit 26b490e86bc305b150200c0b08cd8e9c3bd605fb +Author: Guus Sliepen +Date: Mon Dec 22 19:40:40 2008 +0000 + + Make sure IPv6 sockets are IPv6 only. + This will get rid of the "Can't bind to 0.0.0.0 port 655/tcp: Address already + in use" message on Linux. + +commit c6830ba821e6387be961ca68b32992382a74a0e9 +Author: Guus Sliepen +Date: Mon Dec 22 19:33:37 2008 +0000 + + Use TUNIFHEAD by default on FreeBSD to make sure IPv6 works. + +commit a269ec4193900feee01ac83f0e18a6e2b98e751f +Author: Guus Sliepen +Date: Sun Dec 21 16:19:31 2008 +0000 + + Treat virtual network device as tap if Mode = switch or hub. + On OpenBSD, the link0 flag should still be set in tinc-up or by other means. + +commit 551cd19406a560d0d206bff5b4e9da064ec222b6 +Author: Guus Sliepen +Date: Sun Dec 14 12:47:26 2008 +0000 + + Move RSA key generation into the wrappers. + +commit 911c05f873ad967c40d04aa7347b1067fe62c055 +Author: Guus Sliepen +Date: Thu Dec 11 20:49:14 2008 +0000 + + Make sure IPv6 sockets are IPv6 only. + +commit 6e80da3370249caa1082c23c3ef55f338d1e9e74 +Author: Guus Sliepen +Date: Thu Dec 11 18:07:26 2008 +0000 + + Use Dijkstra's algorithm. Based on patches from Max Rijevskiy. + +commit 26a228e3025c3970fd461af777013e3807b0fc58 +Author: Guus Sliepen +Date: Thu Dec 11 18:05:59 2008 +0000 + + Remove wrong checks. + +commit 636200d1a2024982fe5b3062153daa72a8253015 +Author: Guus Sliepen +Date: Thu Dec 11 15:56:18 2008 +0000 + + Remove unnecessary parentheses from sizeof, apply sizeof to variables instead of types whereever possible. + +commit a9bdfb424e7a469d15156aa44bbe2fd0b8e28531 +Author: Guus Sliepen +Date: Thu Dec 11 15:42:46 2008 +0000 + + Fix compiler warnings. + +commit 76165488f8201a59e649b4eec02ee31398b3fb92 +Author: Guus Sliepen +Date: Thu Dec 11 15:21:40 2008 +0000 + + Backport fixes from trunk since revision 1555. + +commit 046158a216e78a0412186ec8463157f6bce45d5d +Author: Guus Sliepen +Date: Thu Dec 11 14:44:44 2008 +0000 + + Use the crypto wrappers again instead of calling OpenSSL directly. + This theoretically allows other cryptographic libraries to be used, + and it improves the readability of the code. + +commit 8c69f42d7d9b4d9d5f6b6656cfc1bf1e1abee854 +Author: Guus Sliepen +Date: Thu Dec 11 14:43:13 2008 +0000 + + Move AC_GNU_SOURCE up to make autoconf happy. + Also bump libgcrypt dependency to 1.4.0, because that version supports the OFB cipher mode. + +commit 8e8fe805c81d3edc974c12c468f793ea0c1e5ee7 +Author: Guus Sliepen +Date: Thu Dec 11 14:03:52 2008 +0000 + + Only show meta connection related debug messages when debug level >= 4 + +commit 40bebbb19fd69fa094e2f6c3c1474adc0105b048 +Author: Guus Sliepen +Date: Thu Dec 11 13:59:46 2008 +0000 + + Look in the configured sbin directory for the tincd binary. + +commit 38c2d6c1dae3f09c68baa37fd24caa2e0ec6d8ad +Author: Guus Sliepen +Date: Fri Dec 5 14:17:39 2008 +0000 + + Correct debug message. + +commit a36259435c17f76cf12476234a56f40fcd8faf41 +Author: Guus Sliepen +Date: Tue Nov 18 15:11:27 2008 +0000 + + Prevent freeing a NULL pointer when a hostname is unresolvable. + +commit 4a1740ede7c1992f7f3da5e197db9975c0344ac3 +Author: Guus Sliepen +Date: Sat Oct 25 19:54:00 2008 +0000 + + Do not try to send REQ_KEY or ANS_KEY requests to unreachable nodes. + +commit cb52aa06833a69e57b5e26337e51a4d375b6d8fb +Author: Guus Sliepen +Date: Sat Oct 25 18:10:08 2008 +0000 + + Fix reading configuration files that do not end with a newline. + +commit b2cee41b187d79c095914d1097b8ff34a0609ec3 +Author: Guus Sliepen +Date: Fri Dec 14 21:17:08 2007 +0000 + + Make sure the prefixlength of subnets is sane. + Thanks to Sven-Haegar Koch for spotting the bug and providing a fix. + +commit fe2f1fceb546ca4326435cac26bcf3f513e82b43 +Author: Scott Lamb +Date: Thu Nov 8 19:18:44 2007 +0000 + + Use a control socket directory to restrict access + + This provides reasonable security even on Solaris. The sysadmin is + responsible for securing the control socket's ancestors from the + grandparent on. + + We could add a cryptographic handshake later if desired. + +commit b1f8c65a2cfa307d9b8ed8cc3c8d4819f605e4f6 +Author: Scott Lamb +Date: Wed Nov 7 06:45:28 2007 +0000 + + Coding style corrections + +commit d82fcc88f355e3c8144478a860dfae0b299004a9 +Author: Scott Lamb +Date: Wed Nov 7 02:51:24 2007 +0000 + + Reload configuration through control socket + + I also kept the SIGHUP handler, which many people will expect to see. + The control socket is better, though - it will tell you if there is a + problem. + +commit f0a57eab4cfd64d4f8261b1885a2072177f9e76b +Author: Scott Lamb +Date: Wed Nov 7 02:50:58 2007 +0000 + + Retry connections through control socket + +commit a62a6825a8a69e279ee0688a4cd9e51fbc52054b +Author: Scott Lamb +Date: Wed Nov 7 02:50:27 2007 +0000 + + Alter debugging levels through control socket + +commit 1065879c8c6e8cdf8d3755024241f31eaabd4138 +Author: Scott Lamb +Date: Wed Nov 7 02:49:57 2007 +0000 + + Purge through the control socket + +commit 6eaefb4dbce240334e35f67d9f3db5d4f44e49c9 +Author: Scott Lamb +Date: Wed Nov 7 02:49:25 2007 +0000 + + Dump through control socket + + Note this removes SIGUSR1, SIGUSR2, and the graph dumping config option. + It seems cleaner to do everything through the control socket. + +commit 50ad3f2a895c38f8d546f87490ca96ab7d9e011e +Author: Scott Lamb +Date: Wed Nov 7 02:48:33 2007 +0000 + + Fancier protocol for control socket + + * pass error status back + * pass message boundaries + +commit b0b52991849073de059a188800d1b2f03663a188 +Author: Scott Lamb +Date: Wed Nov 7 02:48:15 2007 +0000 + + Fix reload crash + + sighup_handler was expecting the connection_tree to stay the same across + terminate_connection(), which hasn't been true since r1539. + +commit da81da064a093f94e460fc1c359b5cfab26d6b5b +Author: Scott Lamb +Date: Wed Nov 7 02:48:00 2007 +0000 + + Update documentation to match tincctl changes + + (Most of this was done in r1559, but it looks like tincctl.8.in got missed.) + +commit 40731d030fef793c6b6405efd9b3e64c26c00045 +Author: Scott Lamb +Date: Wed Nov 7 02:47:05 2007 +0000 + + Temporarily revert to old crypto code + + (The new code is still segfaulting for me, and I'd like to proceed with other + work.) + + This largely rolls back to the revision 1545 state of the existing code + (new crypto layer is still there with no callers), though I reintroduced + the segfault fix of revision 1562. + +commit 269892f70bf357de6ad66ca89daa34b225ee9e37 +Author: Guus Sliepen +Date: Sat Oct 20 11:21:44 2007 +0000 + + Prevent double free() of a used challenge nonce. + +commit b0709d2649ebd7ad01d6e24851dcdfc2707d09c5 +Author: Guus Sliepen +Date: Fri Oct 19 19:07:30 2007 +0000 + + Fix meta data segfault when receiving a partial command. + +commit 67d9a72ea2f10f1a2d2eb7c04a41183359d5e1cc +Author: Guus Sliepen +Date: Fri Oct 19 18:54:43 2007 +0000 + + Use a dummy function as the read callback for connection bufferevents. Should not be triggered. + +commit 54892b2e3efcbbbd65b26a32f487829bbb8d787c +Author: Guus Sliepen +Date: Fri Oct 19 18:53:48 2007 +0000 + + Fix connection weight estimation. + +commit 6c453769fd16125ec18e8e6d102a3eaa09d370c7 +Author: Guus Sliepen +Date: Tue Sep 4 15:06:35 2007 +0000 + + Apply patch from Scott Lamb: Update documentation to match tincctl changes + +commit 86358fabfedca395b60310799a648b4875596efb +Author: Guus Sliepen +Date: Tue Sep 4 14:58:52 2007 +0000 + + Small fixes to make gcrypt routines compile. + +commit f8733d1935ed83399c4851a31f4be710eb8c825f +Author: Guus Sliepen +Date: Tue Sep 4 14:58:11 2007 +0000 + + Fix formatting of --help output. + +commit 65375289dff849f00b3429dfe4be7e66efe48444 +Author: Guus Sliepen +Date: Tue Sep 4 14:57:37 2007 +0000 + + Only check for libgcrypt if --with-gcrypt is used. + +commit d7ca0300a3f004e9dc7d97ffb6fa6bdeda890fda +Author: Guus Sliepen +Date: Fri Aug 17 22:09:00 2007 +0000 + + Handle SERVICE_CONTROL_INTERROGATE requests. Thanks to Carsten Ralle for noticing this. + +commit 1fd1d5bd9330e02ab5dc32ad027f654ff2620099 +Author: Scott Lamb +Date: Fri Jul 20 20:10:46 2007 +0000 + + const correctness + + cipher_encrypt and cipher_decrypt should take "const void *" data + +commit 35d865a6348cd62d2992bb3d353e37471d902889 +Author: Scott Lamb +Date: Wed Jul 18 16:44:05 2007 +0000 + + Updated svn:ignores list for new symlinked sources and tincctl. + +commit dd299c06dccceeb9b4db09eee17268cf5631fa41 +Author: Scott Lamb +Date: Wed Jul 18 16:40:41 2007 +0000 + + Refresh po/POTFILES.in. + + In particular, remove lib/pidfile.c which was causing failures. Also sort + for diffability with "find . -type f -name '*.c' | cut -c3- | sort" output. + +commit 46018a1a16579ce00b02eb6a991a70615ab9bc3e +Author: Scott Lamb +Date: Wed Jul 18 16:40:29 2007 +0000 + + Revert to only requiring autoconf 2.59. + + The new autoconf macros introduced at the same time (AC_GNU_SOURCE, + AC_FUNC_MALLOC, AC_FUNC_REALLOC) exist in the autoconf 2.59 documentation, + and autoconf 2.59 appears to still work. This is more convenient, as RHEL 5 + ships with autoconf 2.59. + +commit 1b8f8918360b40a2749d40355266ed7dedbe41b5 +Author: Guus Sliepen +Date: Wed May 23 13:45:49 2007 +0000 + + Finish crypto wrapping. Also provide wrappers for OpenSSL. + Disable libgcrypt by default. Since it doesn't support the OFB cipher mode, + we can't use it in a backwards compatible way. + +commit f42e57f663a2663c830c4fb4c01927c2d3c89c09 +Author: Guus Sliepen +Date: Tue May 22 23:41:22 2007 +0000 + + Some more crypto wrapper functions are needed. + +commit 19413a8048fd851866c551ab8035f008f0c7e806 +Author: Guus Sliepen +Date: Tue May 22 21:44:17 2007 +0000 + + Make sure the crypto wrapper functions can actually be compiled. + +commit e8689a4753ca2b1665e131cc40217da6c033ebd3 +Author: Guus Sliepen +Date: Tue May 22 21:32:48 2007 +0000 + + Create wrappers for the cryptographic operations used in tinc. + Implement them using libgcrypt. + +commit 465837dd7f7b727d489b354e4b75489dd49fd6e3 +Author: Guus Sliepen +Date: Sun May 20 22:28:49 2007 +0000 + + Parse PEM RSA keys ourself, and use libgcrypt to do RSA encryption and decryption. + +commit fbf305c09d91bf34b1504b58d50392df2e6bcfba +Author: Guus Sliepen +Date: Sat May 19 22:23:02 2007 +0000 + + Use libevent for meta socket input/output buffering. + +commit 59108e4e4f7aa4632c510d16961edd8c551a6542 +Author: Guus Sliepen +Date: Sat May 19 16:21:52 2007 +0000 + + Use bufferevents to handle control socket buffering. + +commit 8c6131deda546452386f3703af968ee664cadfbd +Author: Guus Sliepen +Date: Sat May 19 15:21:26 2007 +0000 + + Implement "stop" command, and allow tincctl to retrieve a running tincd's PID. + +commit e9043e17c76f92b787c9ecdaf1a2ae7916f690a6 +Author: Guus Sliepen +Date: Sat May 19 14:55:35 2007 +0000 + + Move key generation to tincctl. + +commit bf8e3ce13dba6109757c14dc0013a315a75d2ba3 +Author: Guus Sliepen +Date: Sat May 19 14:13:21 2007 +0000 + + Remove pidfile in favour of control socket. + +commit bc0a24ec810cb911610ae7aafa245e47d1268cd2 +Author: Guus Sliepen +Date: Sat May 19 13:34:32 2007 +0000 + + Fix retrying outgoing connections. + +commit ce976717ea9756aa985699547fdbf132b694748d +Author: Guus Sliepen +Date: Sat May 19 12:07:30 2007 +0000 + + We can safely delete a connection_t in terminate_connection() now. + +commit 01f47c46af514a9d7f39c143e4558a8426a0d3eb +Author: Guus Sliepen +Date: Fri May 18 16:52:34 2007 +0000 + + Start of control socket implementation. + +commit 6ded8a3f089a22c98d2a06b960d65b44e60188d6 +Author: Guus Sliepen +Date: Fri May 18 11:54:16 2007 +0000 + + Update documentation. + +commit 86586594334e951a99845d92baed1966e394aafa +Author: Guus Sliepen +Date: Fri May 18 11:35:21 2007 +0000 + + Show branch version number. + +commit e37ef57a956507cc29e80930201731562b4266e5 +Author: Guus Sliepen +Date: Fri May 18 11:19:31 2007 +0000 + + More consistent variable naming. + +commit 29fbce4497357580fc0aa00f087e8f1a538a2a50 +Author: Guus Sliepen +Date: Fri May 18 10:29:10 2007 +0000 + + Detect duplicate outgoing connections. + +commit fb0cfccf7dc2240b576011edcf74fd5b058916cb +Author: Guus Sliepen +Date: Fri May 18 10:05:26 2007 +0000 + + Use splay trees instead of AVL trees. + +commit f02d3ed3e135b5326003e7f69f8331ff6a3cc219 +Author: Guus Sliepen +Date: Fri May 18 10:00:00 2007 +0000 + + K&R style braces + +commit 760dd966efe7dbff316a8c638e40dee162848256 +Author: Guus Sliepen +Date: Fri May 18 09:51:54 2007 +0000 + + Remove last references to the global variable "running". + +commit 3909b8e51b27b11c6d54541220cb7767bf25569c +Author: Guus Sliepen +Date: Fri May 18 09:43:52 2007 +0000 + + Remove the last bits of the legacy main_loop(). + +commit ddc6a81a854023e38b563f213aa9a449ee91add8 +Author: Guus Sliepen +Date: Fri May 18 09:34:06 2007 +0000 + + Remove global variable "now". + +commit 7e1117197ca4fc62af93fda50e28e0ff06cb736c +Author: Guus Sliepen +Date: Thu May 17 23:57:48 2007 +0000 + + Move key regeneration handling to net_setup.c. + +commit 563577a1479549fa0c20dcda45831a0fff8c7513 +Author: Guus Sliepen +Date: Thu May 17 23:33:07 2007 +0000 + + Use libevent to handle key expiration. + +commit 8852d4407d87cf5dcf2c212d352279015aa050c0 +Author: Guus Sliepen +Date: Thu May 17 23:24:40 2007 +0000 + + Use libevent to age learned MAC addresses. + +commit a530f94e7c4acd94d1cd568b384931eec6f60563 +Author: Guus Sliepen +Date: Thu May 17 23:14:42 2007 +0000 + + Use libevent to age past requests. + +commit aaf1851315023c2f960c58a0d977085a485298e7 +Author: Guus Sliepen +Date: Thu May 17 23:04:02 2007 +0000 + + Redo SIGALRM handling. + +commit 6d19ebd612e6387ba34419cce5cd4d5d861b9a9e +Author: Guus Sliepen +Date: Thu May 17 22:41:34 2007 +0000 + + Use libevent to handle all non-fatal signals. + +commit 531d5a904a3a91bca8b7d373fb6ab2869b31e7fa +Author: Guus Sliepen +Date: Thu May 17 22:17:24 2007 +0000 + + Properly use the timeout_initialized() macro. + +commit bf6490825eabdf4eda6e64f2e5fcd690db7b72ce +Author: Guus Sliepen +Date: Thu May 17 22:13:12 2007 +0000 + + Remove legacy event system. + +commit a67ab277c9fdbcfc8c0550e9046df2a00b5fed81 +Author: Guus Sliepen +Date: Thu May 17 22:09:55 2007 +0000 + + Use libevent for retrying outgoing connections. + +commit 3321591d93d00326eee01fa7c78fb0d56b3d0fba +Author: Guus Sliepen +Date: Thu May 17 22:01:07 2007 +0000 + + Use libevent to send MTU probes. + +commit ee7844905f63872e12cd12f5a3d1a62220594831 +Author: Guus Sliepen +Date: Thu May 17 21:47:27 2007 +0000 + + Configure events after obtaining a socket. + +commit 294ce72441e44c0561556c2984f0e26a74230347 +Author: Guus Sliepen +Date: Thu May 17 21:34:58 2007 +0000 + + Use libevent to handle HUP signal. + +commit 4d0621b1f39537699b0ec4655b0c6e6b84581c9a +Author: Guus Sliepen +Date: Thu May 17 21:14:30 2007 +0000 + + Use libevent to dump graphs when necessary. + event_add() can be called repeatedly, the second and later calls are ignored if + the event hasn't been removed yet. + +commit 0f6f54ff8aa96d981f68b5b71c7126b8fdbead6c +Author: Guus Sliepen +Date: Thu May 17 20:20:10 2007 +0000 + + Use a separate event structure to handle meta data writes. + Make meta socket events persistent. + +commit 17c8033029d50ce4a30b6e3585c0ee28ef45bc97 +Author: Guus Sliepen +Date: Thu May 17 19:52:12 2007 +0000 + + 128 listener sockets is way too much. + +commit d8dea8091fa2260071f775db58ba277d4ce44ea7 +Author: Guus Sliepen +Date: Thu May 17 19:51:26 2007 +0000 + + Properly delete listener socket events on shutdown. + +commit 6ea1dfc995f386b3a9406c7935642524dc755c51 +Author: Guus Sliepen +Date: Thu May 17 19:15:48 2007 +0000 + + Port fixes from release 1.0.8. + +commit cf2be574948fdd02db0503d9639d3b6e268dd4ff +Author: Guus Sliepen +Date: Wed May 16 17:16:09 2007 +0000 + + Releasing 1.0.8. + +commit 6af8900f8e1c7f2fe6a50a991ae6cbd0fd7edd43 +Author: Guus Sliepen +Date: Wed May 16 14:46:25 2007 +0000 + + Don't free struct addrinfo too early. Spotted by Christian Cier-Zniewski. + +commit 31a190dc7db21aa9bb97792563dd83e7c41b831c +Author: Guus Sliepen +Date: Wed May 16 14:42:41 2007 +0000 + + Update dutch translation. + +commit 480dd127c8a539036ff82a3810a0ad83136944f8 +Author: Guus Sliepen +Date: Wed May 16 14:42:08 2007 +0000 + + Make sure connection->name is never NULL. + +commit f0cf4991e2bd0e618c7020511fb12cb0b5c59a40 +Author: Guus Sliepen +Date: Mon May 14 09:21:09 2007 +0000 + + Apply patch from "dnk" making sockets non-blocking under Windows. + +commit 3730156165fd1aa7c8810cd8e390aba6a8badcfa +Author: Guus Sliepen +Date: Mon Mar 12 17:55:43 2007 +0000 + + Only free members of connection_t that have been allocated. + +commit 39f6d59b4b81dc2d754329e6c9f885e8211c5e70 +Author: Scott Lamb +Date: Tue Feb 27 08:13:41 2007 +0000 + + Lots of svn:ignore entries + +commit 38c25d62c2bc76908bd95fb21c8f5e39ad269884 +Author: Scott Lamb +Date: Tue Feb 27 01:57:01 2007 +0000 + + Convert to libevent. + + This is a quick initial conversion that doesn't yet show much advantage: + - We roll our own timeouts. + - We roll our own signal handling. + - We build up the meta connection fd events on each loop rather than + on state changes. + +commit 834290b00f859412ee48bef454a07083cb727130 +Author: Scott Lamb +Date: Tue Feb 27 01:30:57 2007 +0000 + + A couple missed tevent things. + (Sorry; had a couple changes queued.) + +commit 6362b12df725044f3404faceff113e469d8ac860 +Author: Scott Lamb +Date: Tue Feb 27 01:26:11 2007 +0000 + + Rename "event_t" to "tevent_t", along with associated functions. + This relieves some confusion and problems during the libevent transition. + In particular, "event_add" was defined by both. + (The 't' stands for 'timeout', 'tinc', 'temporary', or some such.) + +commit 54431094d95f3989084755fdb91883b24cf5a9f4 +Author: Guus Sliepen +Date: Sat Feb 24 22:50:42 2007 +0000 + + Created the 1.1 branch where large code changes can take place, + at the same time keeping compatibility with 1.0. + +commit ab6f76f6a9fc8028fff96322a52b770710ffa1a9 +Author: Guus Sliepen +Date: Wed Feb 14 09:32:16 2007 +0000 + + Close the proper filedescriptor (if it exists). + +commit 45fca3c723302868de3225e7509d2292008948f7 +Author: Guus Sliepen +Date: Wed Feb 14 09:21:34 2007 +0000 + + Apply patch from Scott Lamb fixing some memory and resource leaks. + +commit 6c6535a4161d04accb3a22c51477e9f92ae34086 +Author: Guus Sliepen +Date: Wed Feb 14 09:20:20 2007 +0000 + + Apply patch from Scott Lamb preventing an infinite loop when sending SIGALRM. + +commit 16c8b0e5bb7c05a0559b2d799a32204bfa0a0e3f +Author: Guus Sliepen +Date: Fri Jan 5 15:03:07 2007 +0000 + + Releasing 1.0.7. + +commit a1e72f84d08b76784c11ff723666ceeaef2756eb +Author: Guus Sliepen +Date: Fri Jan 5 13:18:36 2007 +0000 + + Update copyright notices. + +commit a22ef25f9b81993226a74b193377c7d6baf910ca +Author: Guus Sliepen +Date: Fri Jan 5 13:17:33 2007 +0000 + + No things to do for the 1.0 branch except bugfixing. + +commit d80cc7a5cc918a1dbf8dd789d2125f55c4949d27 +Author: Guus Sliepen +Date: Fri Jan 5 05:44:01 2007 +0000 + + rename() cannot replace existing files on Windows. + +commit 5214ece03009a916159c710cf436af1e92909f41 +Author: Guus Sliepen +Date: Fri Jan 5 04:49:02 2007 +0000 + + Fix generic BSD tun device to write only the actual packet length. + Due to a copy&paste bug, it tried to write a packet with the maximum size. + This was not a problem until the maximum size was increased to support VLANs. + +commit 40f02ff8eee359dc0ccc898f8da319f56af161ad +Author: Guus Sliepen +Date: Thu Jan 4 15:28:36 2007 +0000 + + Tapreader socket should be bound to localhost only. + +commit 03f3fc01e8d9402c4a14904fded883ff8cc574f6 +Author: Guus Sliepen +Date: Wed Jan 3 18:18:54 2007 +0000 + + Use a ringbuffer in shared memory to transfer packets from the tapreader thread to the main thread. + It's a wonder it ever worked before. The socket that is created is not of a + datagram type, therefore packet boundaries were not preserved, which becomes + a problem as soon as the TAP-Win32 device receives packets in fast succession. + +commit 52787a73b0211bcb4cb3cdd308b1a4c53a60f8ce +Author: Guus Sliepen +Date: Mon Dec 18 17:38:05 2006 +0000 + + Releasing 1.0.6. + +commit b32c22cf54e47677726d15a5fca7eecc2fa42754 +Author: Guus Sliepen +Date: Mon Dec 18 11:41:53 2006 +0000 + + Prevent compiler warnings about redefinition of EAI_FAMILY on FreeBSD 6.1. + +commit 855806b2f75fc1c566cfaac01c788cdc625b4687 +Author: Guus Sliepen +Date: Sat Dec 16 16:53:58 2006 +0000 + + Do a simple test for linux/if_tun.h instead of no test at all. + +commit 0322c0883b76257c0893aa75a510e264056ac15b +Author: Guus Sliepen +Date: Sat Dec 16 16:40:09 2006 +0000 + + Remove the test for linux/if_tun.h. + It has been available for years on any decent Linux distribution. + Although linux/if_tun.h is now required to compile tinc, + you can still run it on systems which only support Ethertap. + +commit b55813dc0b4a6a1f70c0f8d5f0512c8cebb4a5ba +Author: Guus Sliepen +Date: Sat Dec 16 16:34:04 2006 +0000 + + We do properly check for malloc and realloc. + +commit 5219ee25a248fe26055e54215c5027cbf8483439 +Author: Guus Sliepen +Date: Sat Dec 16 16:26:57 2006 +0000 + + Use standard autoconf macros instead of our own. + +commit 9d469a19691f9749b5d729a1ae903d7aa224a6e8 +Author: Guus Sliepen +Date: Sat Dec 16 16:26:08 2006 +0000 + + Fix rule that creates html version of manpages. + +commit dd03a003962788eb21910c3faabbda0e84eff5eb +Author: Guus Sliepen +Date: Fri Dec 15 20:44:33 2006 +0000 + + Remove old Spanish translation. + +commit 031e09f865e2c634f30fb0ed4e0b6a1f6df57588 +Author: Guus Sliepen +Date: Fri Dec 15 20:43:39 2006 +0000 + + Remove unnecessary stuff from configure.in. + +commit b834d67d7cc7d7f5d8b729b340ec0c809c7d54b6 +Author: Guus Sliepen +Date: Tue Dec 12 14:54:39 2006 +0000 + + Use the correct next pointer. + +commit 8b55dfacb199d152391aa5f7adbbbe35bceea7d7 +Author: Guus Sliepen +Date: Tue Dec 12 14:49:09 2006 +0000 + + When building the minimum spanning tree, make sure we start from a reachable node. + +commit 47d916ec5eb61fa396c0ec6962afed7885141478 +Author: Guus Sliepen +Date: Wed Nov 29 17:18:39 2006 +0000 + + Search for lzo/lzo1x.h, lzo2/lzo1x.h and lzo1x.h. + +commit 1bb5a284fec8c538f8ba243d4f9b2e46f68cd7e8 +Author: Guus Sliepen +Date: Wed Nov 29 16:57:46 2006 +0000 + + Make sure resolved addressed for outgoing connections are freed, if there are any. + +commit 5c69c390a17fc2b37218881e7285b639b79cfc5a +Author: Guus Sliepen +Date: Tue Nov 14 15:43:28 2006 +0000 + + Releasing 1.0.5. + +commit e5b1b5cefb82531e8a700c2ee251da1bb0a06fbf +Author: Guus Sliepen +Date: Tue Nov 14 12:28:04 2006 +0000 + + EWOULDBLOCK does not exist on platforms without O_NONBLOCK + +commit 3353ab37c2d6fb3652fbf7a85d85997be1c0c1b5 +Author: Guus Sliepen +Date: Sat Nov 11 22:45:45 2006 +0000 + + When deleting an entire tree, start at head, not at root. + +commit 0714ac6c59099a398e67770ad9c72fcec615812b +Author: Guus Sliepen +Date: Sat Nov 11 22:44:15 2006 +0000 + + Nodes use events, so event system should be initialised first and destroyed last. + +commit 35e4096120236db8d64a767f1ccdd6bf03a091fc +Author: Guus Sliepen +Date: Sat Nov 11 21:37:22 2006 +0000 + + Update Dutch translation. + +commit 315ef3e42bf16e03cfbea763442a52389a16b832 +Author: Guus Sliepen +Date: Sat Nov 11 20:37:58 2006 +0000 + + Document GraphDumpFile option. + +commit 8d393b30a922110ec77d5b243347416b50cd2160 +Author: Guus Sliepen +Date: Sat Nov 11 20:10:46 2006 +0000 + + Support and autodetect LZO version 2.0 and later. + +commit bdb3c24cea06e9557738b42e3c37cd036613b58d +Author: Guus Sliepen +Date: Sat Nov 11 20:06:14 2006 +0000 + + Support and autodetect LZO version 2.0 and later. + +commit 0d1ac68c59db87141616f69bcd3d79c705b1ecd0 +Author: Guus Sliepen +Date: Sat Nov 11 14:37:03 2006 +0000 + + popen() requires pclose(). + +commit 0200d3cd5d773d9b101c33264532d2a301c2af32 +Author: Guus Sliepen +Date: Sat Nov 11 14:11:16 2006 +0000 + + Added graph dumping ability based on Markus Goetz's patch. + +commit 1728d5b2c43b33700a9997f97fe8503ad1cf3585 +Author: Guus Sliepen +Date: Sat Nov 11 13:43:00 2006 +0000 + + The "active" bit in node.status is not used. + +commit 134dc8995b296b0bd8b346617c705204b0f3125c +Author: Guus Sliepen +Date: Wed Aug 9 22:31:10 2006 +0000 + + memcpy() addresses from packet headers before calling the lookup functions. + This probably fixes a problem on the ARM architecture that causes tinc to fail to lookup IPv4 addresses. + +commit 64e0519cb5042b251e7345f07429e8b82e2ac09b +Author: Guus Sliepen +Date: Tue Aug 8 13:50:58 2006 +0000 + + Remove unused variable. + +commit ddcf079cad3351f0823fc07af15787d02e5f1901 +Author: Guus Sliepen +Date: Tue Aug 8 13:44:37 2006 +0000 + + Remove unused parameter from maskcmp(). + +commit c620df3c1511643aa533ca31afc17db75b7255b8 +Author: Guus Sliepen +Date: Tue Aug 8 13:44:19 2006 +0000 + + Remove unused variables. + +commit 9fa27097dd82e20299f5277ecb4efffb4a99669c +Author: Guus Sliepen +Date: Tue Aug 8 13:29:17 2006 +0000 + + Fix format string warnings. + +commit eb391c52eed46f3f03b404553df417851fc0cb90 +Author: Guus Sliepen +Date: Tue Aug 8 13:21:08 2006 +0000 + + Do not break strict aliasing of status_t structs. + +commit 2077451e07f93edc520cf5bc31815624a2b03fdd +Author: Guus Sliepen +Date: Mon Jun 12 21:45:39 2006 +0000 + + Add generic host-up and host-down scripts. + Thanks to Menno Smits for a patch. + +commit f88c9942e1e3d4d463ec71ba5a60d045381bda8f +Author: Guus Sliepen +Date: Sun Jun 11 18:53:27 2006 +0000 + + Use memcpy() to copy sockaddrs returned by getaddrinfo(). + Thanks to Miles Nordin for spotting this. + +commit 412f3fb5101514d9a7d4d9e5729ee9c665a07cb6 +Author: Guus Sliepen +Date: Wed Apr 26 16:29:47 2006 +0000 + + Restore length of the original packet in send_udppacket(). + +commit de78d79db84c486afcc353884ec1770866beb653 +Author: Guus Sliepen +Date: Wed Apr 26 13:52:58 2006 +0000 + + Update copyright notices, remove Ivo's email address. + +commit 8ebb017a10cd85406ddf5ab60d8ef1f56df526ff +Author: Guus Sliepen +Date: Wed Apr 12 08:38:35 2006 +0000 + + Fix a bug in handling prefixlengths that are not a multiple of 4. + Thanks to Sven-Haegar Koch for spotting the bug and providing the fix. + +commit af95368c0f30955f0e13b587d5d6d4989fd5a83e +Author: Guus Sliepen +Date: Sun Mar 19 13:06:21 2006 +0000 + + Fix signedness compiler warnings. + +commit fb1cda2ca4ca74a85e88c39c11b97340e6495a08 +Author: Guus Sliepen +Date: Sun Mar 19 12:43:45 2006 +0000 + + Export flush_meta(). + +commit 098090468a9e1e8c5cdb0aeefa277329ff5f3406 +Author: Guus Sliepen +Date: Sun Mar 19 12:43:28 2006 +0000 + + Missing #include. + +commit a90f1b652c0fb52950f3b0783a7e2b7f2e0cf2db +Author: Guus Sliepen +Date: Mon Feb 6 12:30:51 2006 +0000 + + Make sure $NAME is set correctly when executing tinc-down script. + +commit 228e7a5c8f0e517dcede50f886965a44fca39853 +Author: Guus Sliepen +Date: Thu Jan 19 17:13:18 2006 +0000 + + Apply patch from Scott Lamb adding an output buffer for the TCP sockets. + This helps coalescing multiple send_meta() commands into one TCP packet. + Also limit the size of the output buffer before dropping PACKETs. + +commit a5a4d2b865879b8694760c0a5b5909c9a3675027 +Author: Guus Sliepen +Date: Fri Jan 13 11:21:59 2006 +0000 + + Apply patch from Scott Lamb unifying configuration of TCP socket options. + +commit e02f13cdb3133c33ac84d9582e2f47ca5ebd35bf +Author: Guus Sliepen +Date: Fri Jan 13 11:09:19 2006 +0000 + + EVP_Cleanup() when quitting. + +commit 0912260755021b9b836830dd99ae128c5fd912d9 +Author: Guus Sliepen +Date: Wed Nov 16 10:45:11 2005 +0000 + + Enable OpenSSL ENGINE, so crypto hardware gets used. Thanks to Andreas van Cranenburgh. + +commit 64e4c12778697f71ad3fcf33ee6cf1066322caa5 +Author: Guus Sliepen +Date: Fri Jun 3 10:56:02 2005 +0000 + + Add alloca.h to the list of necessary header files. + +commit e810545dc2ae158745624c1575b76c55f883c892 +Author: Guus Sliepen +Date: Fri Jun 3 10:16:03 2005 +0000 + + Prevent possible buffer overflows when using very large (>= 8192 bit) RSA keys. + Thanks to Tonnerre Lombard for noticing! + +commit 02746165a21a4a495d0069526c9a2355110a5784 +Author: Guus Sliepen +Date: Wed May 4 19:38:28 2005 +0000 + + Releasing 1.0.4. + +commit df3220a1549f992cbf4a9b6e67c1e67b69896c7d +Author: Guus Sliepen +Date: Wed May 4 18:09:30 2005 +0000 + + Update copyright notices. + +commit 54a30e30ad41d7c0e73fcc4e6ff23c3e85af75c4 +Author: Guus Sliepen +Date: Wed May 4 16:53:11 2005 +0000 + + Describe subnet-up/down scripts in documentation. + +commit bded1b74cc23c60e7319ed9e7465413b94a7914e +Author: Guus Sliepen +Date: Wed May 4 15:56:25 2005 +0000 + + Several splay tree fixes. + +commit faaaa1ef38dcdf19d5d5d73ab66806b15467c043 +Author: Guus Sliepen +Date: Wed May 4 15:52:55 2005 +0000 + + Searching through splay trees may change the tree variable. + +commit dc09f6fe896f5e35fffe8cc2004781b2e1b6fd5a +Author: Guus Sliepen +Date: Wed May 4 15:51:45 2005 +0000 + + Be on the safe side with initialisation of c->name. + +commit 92c4a28d7d43b68a324cf2eca741298ed6b692d6 +Author: Guus Sliepen +Date: Wed Apr 6 20:43:37 2005 +0000 + + Remove unused (and potentially segfaulting) net2str() call. + +commit 6363ed4d9c675b8b9301b694c4e4dd9c892e04e2 +Author: Guus Sliepen +Date: Thu Jan 20 15:14:25 2005 +0000 + + Don't try to add a non-existing node back to the node_udp_tree. + +commit 39fe3b445c2f20b325ee492dd1845877777b25c8 +Author: Guus Sliepen +Date: Tue Jan 4 22:19:56 2005 +0000 + + Nodes should only be in the node_udp_tree if they are reachable. + +commit fe0bfa3e65049d6e7cd46cf6caea7eb91b478008 +Author: Guus Sliepen +Date: Tue Jan 4 22:18:58 2005 +0000 + + Correct size argument for strncat(). + +commit 56c36a14d87b58c14dbc48df4d3d977207e2c06e +Author: Guus Sliepen +Date: Fri Dec 3 13:27:33 2004 +0000 + + Use the proper free function. + +commit 18c617ecf29b9dfb95227e764c76fff0f9d7af96 +Author: Guus Sliepen +Date: Fri Dec 3 13:22:18 2004 +0000 + + Free memory used by connection_t after it is deleted from the connection tree. + +commit 672ad5634cbedfbd6345e887935eed3e806f1e2d +Author: Guus Sliepen +Date: Wed Dec 1 21:26:51 2004 +0000 + + Small fix. + +commit 40b1692940a8d588c08fb6b8f24ded7c33b041b1 +Author: Guus Sliepen +Date: Wed Dec 1 20:06:39 2004 +0000 + + subnet-up/down hooks, use list_t for the todo list. + +commit c46f56a8b8bb865dd8951441b5acf4701b5b5b09 +Author: Guus Sliepen +Date: Wed Dec 1 20:06:05 2004 +0000 + + subnet-up/down hooks + +commit f08baa3072e7cd6cee7a2a7cde35b46c85363baf +Author: Guus Sliepen +Date: Thu Nov 18 20:34:48 2004 +0000 + + Fix splay tree code. + +commit 0077cfaae112b63d6af6aa1e5d079cebdde84b74 +Author: Guus Sliepen +Date: Tue Nov 16 19:02:54 2004 +0000 + + Make sure broadcast packet reach the local network interface. + +commit 79c48cfafd75dfc86a382f6454a9f009d3c099b6 +Author: Guus Sliepen +Date: Thu Nov 11 19:42:25 2004 +0000 + + Releasing 1.0.3. + +commit 2771691bfc85b2544b30ccaee8a709bd26c7e1ab +Author: Guus Sliepen +Date: Thu Nov 11 19:39:28 2004 +0000 + + Add more people who have contributed to tinc. + Remove details and sort on name; + the details were not always equally accurate and are hard to maintain. + +commit 4f3f6f07b234b4abd32bf3bae1be0551bc7dd9dc +Author: Guus Sliepen +Date: Thu Nov 11 11:17:04 2004 +0000 + + Short readme about how to compile tinc from a Subversion checkout. + +commit 704c3707c2c400b7e35ef4ac2c1d21e0f2de0187 +Author: Guus Sliepen +Date: Wed Nov 10 23:28:32 2004 +0000 + + Updated dutch translation. + +commit a20eb05714f828be7dc0f78c1a07f218a3482dff +Author: Guus Sliepen +Date: Wed Nov 10 23:21:41 2004 +0000 + + Remove duplication. + +commit d8fe2ecdd8dc5caf6f8d6acf2923a0baed64735f +Author: Guus Sliepen +Date: Wed Nov 10 23:20:59 2004 +0000 + + Set BSD tuns to broadcast mode. On OpenBSD, this enables IPv6 on the tun device! + +commit 2369b0ab09a008c519cd4307b634fd294c66014e +Author: Guus Sliepen +Date: Wed Nov 10 21:57:04 2004 +0000 + + Update documentation. + +commit 4fe7aff4d1b8605d4997b842481cc78bd062fe2a +Author: Guus Sliepen +Date: Wed Nov 10 21:56:31 2004 +0000 + + Add BlockingTCP option, useful when using TCPOnly on slow or congested links. + +commit 5bba3124c8c23568def7a4804651a53f3a6b4fd2 +Author: Guus Sliepen +Date: Wed Nov 10 21:14:08 2004 +0000 + + Support tunneling IPv6 on Solaris. + +commit d02d81ff9dbb12253957065752c56785aedccee3 +Author: Guus Sliepen +Date: Wed Nov 10 19:36:02 2004 +0000 + + Let compiler decide when to inline. + +commit db68db4b0e0f8b776f2d3dc938fb81dac975fdd8 +Author: Guus Sliepen +Date: Wed Nov 10 19:34:38 2004 +0000 + + Fix order of arguments for tar. + +commit 923abcfa35c7282251d507af83d6163df76c943b +Author: Guus Sliepen +Date: Wed Nov 10 18:11:44 2004 +0000 + + Use the generic BSD tun/tap code. + +commit e8b11b1cca11f7f50542a7b34f4251f43447db0d +Author: Guus Sliepen +Date: Wed Nov 10 18:10:59 2004 +0000 + + Missing check for NULL-pointer. + +commit ca7948fc06fd0495dc8104d7f55948f702ac09e2 +Author: Guus Sliepen +Date: Tue Nov 9 09:51:35 2004 +0000 + + Hopefully this really fixes late packet handling. + +commit f7b9761000000063bd00460af4b57117db7361e4 +Author: Guus Sliepen +Date: Mon Nov 8 22:30:13 2004 +0000 + + Fixed another bug in late packet handling. + +commit 14eab178295768311d4518289533005991add8ba +Author: Guus Sliepen +Date: Mon Nov 8 22:11:33 2004 +0000 + + Update to make it compile again. + +commit 804b2892a5e26a2dc46d19397cc8b321b43b8add +Author: Guus Sliepen +Date: Mon Nov 8 22:03:28 2004 +0000 + + Hoopjumping to get the default directories in the manuals properly. + +commit 719cb95ea4fa7a2e6f4291aed607323f290c7a91 +Author: Guus Sliepen +Date: Tue Nov 2 20:50:53 2004 +0000 + + Splay trees. + +commit 2af1538976c9c85c40becfdd8601b421ad2ab057 +Author: Guus Sliepen +Date: Mon Nov 1 17:05:09 2004 +0000 + + Don't include .svn directory in sample configuration. + +commit dced64c5c3625f6d2f0674e9fed14455aabc635e +Author: Guus Sliepen +Date: Mon Nov 1 17:04:28 2004 +0000 + + Check for sys/uio.h, net/if_tun.h and net/if_tap.h + +commit 1f00810da336f3b7132df17b7fe4625748ff4b63 +Author: Guus Sliepen +Date: Mon Nov 1 17:02:19 2004 +0000 + + static + +commit 82b29e9a3b1dc6b2104ab92ed78bf431a4e55649 +Author: Guus Sliepen +Date: Mon Nov 1 17:01:56 2004 +0000 + + Generic device driver for *BSD and MacOS/X + +commit 922e5b7beaad5bb3fcbfa6b8dd13c05bda29e5fa +Author: Guus Sliepen +Date: Mon Nov 1 15:18:53 2004 +0000 + + Support alternative tun/tap driver from http://www-user.rhrk.uni-kl.de/~nissler/tuntap/ + +commit faff6498821555e6afb3dc5e4e3b61d448a4fef1 +Author: Guus Sliepen +Date: Mon Nov 1 15:18:22 2004 +0000 + + Don't let tinc service depend on NDIS component. + +commit 396ac4be802f8b75c5a2ab5925925427c61c1da3 +Author: Guus Sliepen +Date: Mon Nov 1 15:16:12 2004 +0000 + + Correct return value. + +commit 58153cca98fd43c37ae52d3cf69474c3d736c431 +Author: Guus Sliepen +Date: Fri Oct 1 18:26:15 2004 +0000 + + Allow tinc to work with the latest TAP-Win32 driver. + +commit 6411e0d8bda8abc2cef87ca852255502f9bb03d0 +Author: Guus Sliepen +Date: Fri Oct 1 18:24:41 2004 +0000 + + strndupa() is too arcane for some environments. + +commit b0a80007e8945a11d7ce25aab096c5ee58ce0ad5 +Author: Guus Sliepen +Date: Fri Oct 1 18:23:08 2004 +0000 + + Fix several #includes. + +commit 2c40495747945bc497dac65b734a4995ab3400a3 +Author: Guus Sliepen +Date: Fri Oct 1 18:22:06 2004 +0000 + + Move all #ifdef HAVE_HEADER_H #include to have.h, + this allows for simplification of configure.in. + +commit 7717cb0c54cc1b736b9f210b180c3cb3f4663ded +Author: Guus Sliepen +Date: Mon Sep 20 20:56:14 2004 +0000 + + Remove duplicate #include "system.h" + +commit 5373129344d349ff6aeb2b3d21f947f5ecbbcfaf +Author: Guus Sliepen +Date: Mon Sep 20 20:55:49 2004 +0000 + + Marking potential late packets was in the wrong place. + +commit c44f69a30243a94ab93bd15915dbfa71db698bde +Author: Guus Sliepen +Date: Sat Jul 17 12:04:30 2004 +0000 + + Don't set $INTERFACE automatically, don't quit on EINTR/EAGAIN. + +commit dcec713675b604f5ef82e64d0671727e3f5ea518 +Author: Guus Sliepen +Date: Sat Jul 17 00:09:14 2004 +0000 + + Added UML network socket handling. + Now you can use tinc instead of uml_switch. + +commit fe84fafcb684391739a1b3366705c58683210392 +Author: Guus Sliepen +Date: Mon Jun 21 14:37:52 2004 +0000 + + Handle timeouts during connecting the same way as other errors. + +commit e5e0dd7534be5fb96032fb733ca36a09cb067f17 +Author: Guus Sliepen +Date: Mon Jun 14 14:32:10 2004 +0000 + + Clean up environment after executing scripts. + +commit 9e44f116bf0f72d1dd4f099440a351dbe0a74573 +Author: Guus Sliepen +Date: Thu Apr 15 14:09:56 2004 +0000 + + Increase MTU by 4 bytes to allow VLAN tagged Ethernet frames in hub and switch mode. + +commit 7926a156e5b118d06295228e57de0cc9de0433b4 +Author: Guus Sliepen +Date: Sun Mar 21 14:21:22 2004 +0000 + + Update copyrights, links, email addresses and let Subversion update $Id$ keywords. + +commit 42e01abd54bd36ee84a45a2b646cfa27034de8d1 +Merge: 5ca64f8 af86a32 +Author: Guus Sliepen +Date: Sun Mar 21 13:22:24 2004 +0000 + + Move CABAL branch to its rightful place: the trunk. + +commit af86a3226ea42375644b3f99c182c778d327de1e +Author: Guus Sliepen +Date: Sat Mar 20 22:23:42 2004 +0000 + + Revert Martin Kihlgren's patch, it doesn't work the way it should. + +commit 27c304940a5dbe83fb0f655c5c43150bafed3b63 +Author: Guus Sliepen +Date: Sat Mar 20 15:40:26 2004 +0000 + + Use Subversion to create ChangeLog, better svn-clean rule. + +commit 8df22248293a8cd5e6056415b6e08740e40aa2bc +Author: Guus Sliepen +Date: Sat Mar 20 15:33:07 2004 +0000 + + Fix declaration of update_node_address(). + +commit 56aad1bb486675ff9aba31418708cc179eea0381 +Author: Guus Sliepen +Date: Sat Mar 20 15:28:55 2004 +0000 + + Applied Martin Kihlgren's IdentityGenerosity patch, + simplified and renamed to StrictSource. + +commit 8c189c2a9b77fb326ab5f27a05bf2601e16af017 +Author: Guus Sliepen +Date: Mon Mar 15 19:09:52 2004 +0000 + + Even better svn-clean command. + +commit b05df3fcbfb8dbef4c87691d118c5b68aeb79e4a +Author: Guus Sliepen +Date: Mon Mar 15 18:36:14 2004 +0000 + + Updating dutch translation. + +commit a92c471a2bc0773a7473ef0361d1a51fafee50d4 +Author: Guus Sliepen +Date: Mon Mar 15 18:15:02 2004 +0000 + + Only read our public key if it wasn't already in the private key file. + +commit a67a21ef3c17d32af95373e921138429a7fc507e +Author: Guus Sliepen +Date: Mon Mar 15 18:05:41 2004 +0000 + + Eat trailing whitespace in config files. + +commit 4350704d6578656af98195b26006c6b6d6a798e3 +Author: Guus Sliepen +Date: Mon Mar 15 17:54:19 2004 +0000 + + Remove CVS related cruft. + +commit 538595f7350ba6c7d11aba7d9f481ea1641e1857 +Author: Guus Sliepen +Date: Mon Mar 15 17:53:17 2004 +0000 + + Replace cvs-clean with a much better svn-clean. + +commit 5ca64f89be71131e77a29661827dc8866a5f278c +Author: cvs2svn +Date: Sat Jan 10 23:21:36 2004 +0000 + + This commit was generated by cvs2svn to compensate for changes in r1352, + which included commits to RCS files with non-trunk default branches. + +commit fcd836c609568fab323f4af6dd525de957a6f4cc +Author: Guus Sliepen +Date: Sat Jan 10 23:21:36 2004 +0000 + + Remove autogen.sh, the autoreconf program does exactly that. + Update everything for the latest autoconf and automake versions. + +commit f2aa7466e6db9777090583ef26d923fc0a4fcea8 +Author: Guus Sliepen +Date: Sat Jan 10 23:19:20 2004 +0000 + + Small updates. + +commit 519d63bedbdcc533dd7839aae02b4d7bc2debfb0 +Author: Guus Sliepen +Date: Sat Dec 27 16:32:52 2003 +0000 + + Don't forget to update destination MAC address. + +commit aebc97a77f37ec63fbd36721f9b284c975e54270 +Author: Guus Sliepen +Date: Wed Dec 24 10:48:15 2003 +0000 + + Small fixes for PMTU discovery. + +commit 2c7ce7de12d16cb407fd40224b6cb802528ee942 +Author: Guus Sliepen +Date: Mon Dec 22 11:05:23 2003 +0000 + + Missing definitions. + +commit 35399784b695c9ac692beba7be7930ee9f24412f +Author: Guus Sliepen +Date: Mon Dec 22 11:04:17 2003 +0000 + + Improvements for PMTU discovery and IPv4 packet fragmentation. + +commit 6d41b429a26dd1acaa7c56b2124f2daf55b5b97c +Author: Guus Sliepen +Date: Sat Dec 20 21:25:17 2003 +0000 + + Better name, show probed MTU in dump. + +commit af490a745d4ddc8994ceca546b5f9139f6a6ebe2 +Author: Guus Sliepen +Date: Sat Dec 20 21:20:10 2003 +0000 + + Describe the TunnelServer and PMTUDiscovery options. + +commit 9bab08e972ae0ca4b904a659d9aed46aaa9b5dd5 +Author: Guus Sliepen +Date: Sat Dec 20 21:09:33 2003 +0000 + + More sensible name, and try to set PMTU discovery on IPv6 sockets as well. + +commit 6b12bea62fe2e4bd8b5b6bd0e5ca7f53318705db +Author: Guus Sliepen +Date: Sat Dec 20 19:47:53 2003 +0000 + + Let tinc figure out the exact MTU of the link. + +commit e8fbef5de653e4df35eee49aae6e1ac92d6466e6 +Author: Guus Sliepen +Date: Sat Dec 13 21:50:26 2003 +0000 + + Forget multicast. Always inline some function. + +commit 5a1406adefd8b51981af0da5ac0ebec830eb43b4 +Author: Guus Sliepen +Date: Fri Dec 12 19:52:25 2003 +0000 + + Code beautification, start of multicast support. + +commit 354b7ab20e04736b368985a9e9dfd54ff5b7584e +Author: Guus Sliepen +Date: Mon Dec 8 12:00:40 2003 +0000 + + Fix proxy-neighborsolicitation. + +commit 331cef948db4b3cca245ab62cb0fafb5b1e5ebb3 +Author: Guus Sliepen +Date: Sun Dec 7 14:31:09 2003 +0000 + + Don't retry if configuration is wrong from the beginning. + +commit a3cd273751fdcef90a43108a5d2e669877b0bccb +Author: Guus Sliepen +Date: Sun Dec 7 14:29:02 2003 +0000 + + Missing space between words. + +commit 25447b384173cc3c99660c784fd784c787917e80 +Author: Guus Sliepen +Date: Sun Dec 7 14:28:39 2003 +0000 + + Read MaxTimeout from tinc.conf like the manpage says. + +commit 0b5e6cf04ec0c7e3c54c74a54a32b30e6e3c1f83 +Author: Guus Sliepen +Date: Thu Nov 27 23:24:59 2003 +0000 + + Complain if pid file cannot be created. + +commit e3220cacb5bc79fc56167e61b7a342f88a33a479 +Author: Guus Sliepen +Date: Mon Nov 17 15:30:18 2003 +0000 + + Replace Opaque and Strict options with a TunnelServer option. + +commit 0e59fb022c6c015a5be7ed70e0378cb011be98b5 +Author: Guus Sliepen +Date: Mon Nov 10 22:31:53 2003 +0000 + + Add Opaque option which prevent information from being forwarded to certain nodes. + +commit a8f415e67fd316d929f9b9e6661e0d3d66fc197b +Author: Guus Sliepen +Date: Sat Nov 8 15:29:40 2003 +0000 + + Release notes for 1.0.2 + +commit 507a83c74635955f803bb26c450f3e83dd4809f9 +Author: Guus Sliepen +Date: Sat Nov 8 15:09:03 2003 +0000 + + Add missing definitions. + +commit 0271de0e80459bdebcac50d38c053d4aaf657e9a +Author: Guus Sliepen +Date: Sat Nov 8 12:56:24 2003 +0000 + + Update dutch translation. + +commit d35a510fff65a7a3318036f27c11b956526b26f6 +Author: Guus Sliepen +Date: Sun Oct 12 11:40:00 2003 +0000 + + Fix another bug in meta.c. + +commit e88ea7277a97d46fa2c3ba1896cf0d0c62bdf128 +Author: Guus Sliepen +Date: Sat Oct 11 14:42:30 2003 +0000 + + Small fixes in documentation. + +commit ffb7327c20952cefcb5578e40f9802295172c5c2 +Author: Guus Sliepen +Date: Sat Oct 11 14:18:52 2003 +0000 + + Fix bug that could lead to an assertion failure in libcrypto when multiple + requests arrive and TCP packets are heavily fragmented. + +commit 258b7ce220607bb3f2a24bb7cab5fcd19e82314a +Author: Guus Sliepen +Date: Sat Oct 11 12:28:48 2003 +0000 + + Parentheses in the wrong spots. + +commit a1ab57e2755df6c1a8fab95a0886fea368200b96 +Author: Guus Sliepen +Date: Sat Oct 11 12:16:13 2003 +0000 + + Check all EVP_ function calls. + +commit b0dd705a264f0f72a7afba6de85200598cbe083b +Author: Guus Sliepen +Date: Fri Oct 10 16:24:24 2003 +0000 + + Check return value of EVP_* functions, and check if length before en/decryption + matches that after in meta.c. + +commit 9d2bf718f233672c11a9740ed2a1539eaab1509b +Author: Guus Sliepen +Date: Fri Oct 10 16:23:30 2003 +0000 + + Fix ASCII art. + +commit e33307fc9f5354933554d26de618db1b08fc04c0 +Author: Guus Sliepen +Date: Thu Oct 9 21:33:15 2003 +0000 + + Update documentation. + +commit 98edfb14fcc7167d24d440ed2772d0755daac3b7 +Author: Guus Sliepen +Date: Wed Oct 8 12:09:37 2003 +0000 + + Some platforms don't know sa_family_t or define it other than uint16_t. + +commit f2ebdf75806d8c04138db0eb30727f846541ed75 +Author: Guus Sliepen +Date: Wed Oct 8 11:37:53 2003 +0000 + + Set media status for newer TAP-Win32 driver. + +commit acf5f9c968d17ad3e31129d2184309de06d72eed +Author: Guus Sliepen +Date: Wed Oct 8 11:37:20 2003 +0000 + + Missing declaration. + +commit 1d7706a8506d8073def0965da809960c6ad8bf9a +Author: Guus Sliepen +Date: Wed Oct 8 11:34:55 2003 +0000 + + Update missing definitions, structs describing headers get __packed__ attribute. + +commit 5b556c0971e847580b85268e57f0b29dbde5499c +Author: Guus Sliepen +Date: Wed Oct 8 11:33:54 2003 +0000 + + Forgot to #include "xalloc.h" + +commit ad39db95fecf760297b4e320ef2f6d6d9fdad605 +Author: Guus Sliepen +Date: Mon Oct 6 16:49:42 2003 +0000 + + Make sure type of AF_UNKNOWN is sa_family_t. + +commit 5900c07fab39d2833ea66429ad652ca49a91a508 +Author: Guus Sliepen +Date: Mon Oct 6 16:13:08 2003 +0000 + + PIDs are of type pid_t, and use %ld when reading/writing them to the pidfile. + +commit e898b930dcd0694a49dc8cdcf373e0fc125c9fde +Author: Guus Sliepen +Date: Mon Oct 6 16:05:30 2003 +0000 + + Use CPPFLAGS, LDFLAGS and LIBS as appropiate. + +commit 6350334aa44f85e737c1eb0b55e0392766aa1e84 +Author: Guus Sliepen +Date: Mon Oct 6 14:41:45 2003 +0000 + + Don't confuse users with "Address family not supported" warnings. + +commit 0842998c0bd46855d198923acc2c13cff7430ffe +Author: Guus Sliepen +Date: Mon Oct 6 14:33:04 2003 +0000 + + Unused variable in struct. + +commit 77cb10dac0abbfa4389a7588f51797152d91ac22 +Author: Guus Sliepen +Date: Mon Oct 6 14:16:51 2003 +0000 + + Ethernet protocol types. + +commit c97b8827ed34284535706e8017c962ff8f3a4383 +Author: Guus Sliepen +Date: Mon Oct 6 13:57:12 2003 +0000 + + const + +commit 60943122f7b3a5896ce64c9000e119931484c12c +Author: Guus Sliepen +Date: Mon Oct 6 13:49:57 2003 +0000 + + Copy structs from packets to the stack before using them, to prevent + alignment issues. + +commit 5713fb07b3e831b78d8841d56a53c2a2698fe738 +Author: Guus Sliepen +Date: Wed Oct 1 09:43:01 2003 +0000 + + Add description of new authentication scheme. + +commit acbb9d6692614539260749c7b763eca5a6f81f07 +Author: Guus Sliepen +Date: Wed Oct 1 09:14:01 2003 +0000 + + Better length checks. + +commit eeb97e3ef4eb9089851f7b71d5393df24313c993 +Author: Guus Sliepen +Date: Thu Sep 25 10:34:16 2003 +0000 + + Generate keys with 0x10001 as public exponent, which has less prime factors + than 0xFFFF. + +commit 288d956728ab4d4aabe9bc59b87991420dbda151 +Author: Guus Sliepen +Date: Tue Sep 23 20:59:01 2003 +0000 + + Check for short packets from the tun/tap device and from other tinc daemons. + +commit 4e80612ac0f38daa0f2280c293427c7f25dac278 +Author: Guus Sliepen +Date: Tue Sep 9 15:47:59 2003 +0000 + + Update translations. + +commit cbf5a741aa2af937b3db606f0894990703f77bcb +Author: Guus Sliepen +Date: Mon Sep 8 21:52:47 2003 +0000 + + Remove pidfile when exitting. + +commit 0dba26267c76982a422984b61a3196ed2cd2b04a +Author: Guus Sliepen +Date: Wed Sep 3 16:20:33 2003 +0000 + + Prevent multiple inclusions. + +commit 6c5f3d8b74ffea1522a727ef189a5ba65a939e07 +Author: Guus Sliepen +Date: Thu Aug 28 21:05:11 2003 +0000 + + We don't have to tell GCC how to cast. + +commit 762cc2d2797d62ab593ea64d8ceeb4fe96be2a0d +Author: Guus Sliepen +Date: Thu Aug 28 15:27:12 2003 +0000 + + Remove old edges from unreachable nodes to us. This prevents the hosts/NAME-up + script from being called twice in some situations. + +commit a6dc69e7f30522bf885714f6b663960b6fbfff6a +Author: Guus Sliepen +Date: Wed Aug 27 13:58:29 2003 +0000 + + Forgot to synchronise po/ directory... + +commit 62349da6f2617c7250a77af6610344ec0dbfc4f2 +Author: Guus Sliepen +Date: Wed Aug 27 13:57:04 2003 +0000 + + Makevars file was accidentily removed. + +commit dc3b7d47f3297e22161787a1d6e06205140cf0fb +Author: Guus Sliepen +Date: Wed Aug 27 13:47:52 2003 +0000 + + Some device.c files weren't synchronised. + +commit 9e81a6ab5f50df4f5ca36d5303b91a8d5a0e753e +Author: Guus Sliepen +Date: Sun Aug 24 20:50:30 2003 +0000 + + This will become 2.0. + +commit 013a2e159e42c46808ea8d0b6abd57525db30a50 +Author: Guus Sliepen +Date: Sun Aug 24 20:38:31 2003 +0000 + + Synchronise HEAD with CABAL branch. + +commit ffb55e6904426a31c03b56c3bd87bb60db0624c6 +Author: Guus Sliepen +Date: Fri Aug 22 21:32:45 2003 +0000 + + Add license exception from Markus Oberhumer. + +commit 3e0b28b0c4d874934dde7b487a56cfacc956e3b4 +Author: Guus Sliepen +Date: Fri Aug 22 15:07:57 2003 +0000 + + Remove debug message. + +commit 89c9f3ed8fddb316d0f9ef7de30bdc76fba39e41 +Author: Guus Sliepen +Date: Fri Aug 22 15:04:26 2003 +0000 + + When purging nodes, only delete them if nobody references them anymore. + +commit 22dd23b650eb9b760bc68ab3a9227caf3b449140 +Author: Guus Sliepen +Date: Fri Aug 22 15:03:59 2003 +0000 + + Add checkpoints. + +commit 570e7e9c615388cfba263c7a7c66cbc3d092d6e7 +Author: Guus Sliepen +Date: Fri Aug 22 15:05:01 2003 +0000 + + Don't overwrite the first " when installing a service. + +commit 72bdc05cb7e246e56ed21a25256d441c45fccca8 +Author: Guus Sliepen +Date: Fri Aug 22 11:18:42 2003 +0000 + + Allow tinc to handle unknown type addresses from other tinc daemons. + +commit 5ac4179df66747a7013a10d576c23531d2b4fc58 +Author: Guus Sliepen +Date: Sun Aug 17 12:05:08 2003 +0000 + + If we're not in main_loop() and the service is stopped, exit immediately. + +commit 46cfe6199449a86eb58abaeac45b4021ffa7e178 +Author: Guus Sliepen +Date: Sun Aug 17 12:04:35 2003 +0000 + + Do what the SDK documentation tells. + +commit 107448698fc078bbd4cdbacdfbf51298ddc9ea65 +Author: Guus Sliepen +Date: Sun Aug 17 12:03:40 2003 +0000 + + Compilation fix. + +commit 3112e6a863b4421eb1a0b32632b86c55e47f989e +Author: Guus Sliepen +Date: Sun Aug 17 09:04:00 2003 +0000 + + Use the event log under Windows. + +commit 5e7c52610f8c8b9c38e437ef166a08372d5b8a61 +Author: Guus Sliepen +Date: Sun Aug 17 09:03:30 2003 +0000 + + Fix --logfile under Windows. + +commit 2236e05e518c9e317d82c027596bea5228725214 +Author: Guus Sliepen +Date: Sun Aug 17 08:32:39 2003 +0000 + + Fix fake getnameinfo() and check more arguments. + +commit f4e80cc5e0d1689bcdd828ac7f158bd634b7dd20 +Author: Guus Sliepen +Date: Sat Aug 16 12:40:01 2003 +0000 + + Don't getsockopt() SO_ERROR. We get the error from send()/recv() anyway. + +commit fd40130eb6bbba34176d34936a01bb6a6f9121d4 +Author: Guus Sliepen +Date: Sat Aug 16 12:11:11 2003 +0000 + + stat() batch files under Windows. + +commit 03995ca52ee31ed505902a3c8c3d1119988c8497 +Author: Guus Sliepen +Date: Sat Aug 16 12:10:28 2003 +0000 + + Simplify fake getname/addrinfo() functions, possibly fixing freeing a NULL pointer. + +commit dbfd6f284e0ff0aa04e6d6e62b902966912da516 +Author: Guus Sliepen +Date: Thu Aug 14 14:32:34 2003 +0000 + + Update. + +commit 7ed25590257b6ed33dfa879d187a09b0d790794f +Author: Guus Sliepen +Date: Thu Aug 14 14:21:35 2003 +0000 + + Fix permissions check for rsa_key.priv. + +commit 1f2670aab295dfd09c8c655611d2a5b820cb00fc +Author: Guus Sliepen +Date: Tue Aug 12 14:48:13 2003 +0000 + + Small fixes. + +commit b038e8db376969e70f1315840428b8a14ec8420f +Author: Guus Sliepen +Date: Tue Aug 12 12:35:53 2003 +0000 + + Updated dutch translation. + +commit ae070b917066f612e9aba8611c7a5da88e19a51a +Author: Guus Sliepen +Date: Sun Aug 10 13:35:05 2003 +0000 + + Add a description for the Service control panel. + +commit 9b579eb9ffdc1fd4a3d0cacb0728ec0796526bc5 +Author: Guus Sliepen +Date: Sat Aug 9 00:53:22 2003 +0000 + + Update documentation. + +commit 7eed829d288d0fdec2f31709a18ec420e489c2e4 +Author: Guus Sliepen +Date: Fri Aug 8 22:45:46 2003 +0000 + + Only system() needs script name quoted. + +commit 91f65c277483b47343b1b64d0f4edd497a8045a3 +Author: Guus Sliepen +Date: Fri Aug 8 22:13:50 2003 +0000 + + Check for fchmod(). + +commit 9bde92ce97d5503ff2d31dcc6f0648902580ec14 +Author: Guus Sliepen +Date: Fri Aug 8 22:11:54 2003 +0000 + + Simpler checking of permissions on private RSA key and other fixes. + +commit 96f5d98fc299a53fcdad304a56eb3a77a2c229e7 +Author: Guus Sliepen +Date: Fri Aug 8 19:56:11 2003 +0000 + + Small things. + +commit ef65a64443f740e3b22d9e903f764d9a58ce0ff0 +Author: Guus Sliepen +Date: Fri Aug 8 19:49:47 2003 +0000 + + Better error checking and reporting. + +commit bb2f18a3fc8acb7802f30e06153def30eb97a994 +Author: Guus Sliepen +Date: Fri Aug 8 19:45:21 2003 +0000 + + Under Windows, the installation directory can be found in the registry. + +commit 7f05445047c6479b81b7d393543ff73a95ee0dc8 +Author: Guus Sliepen +Date: Fri Aug 8 19:43:47 2003 +0000 + + Quote when needed and don't try stuff that doesn't work under Windows. + +commit b4c913aaa926d80a72aeb97459f84f992b65d1ed +Author: Guus Sliepen +Date: Fri Aug 8 19:42:35 2003 +0000 + + Log error first, try to close later. + +commit b0825f36b7b5dade1693fdbddfec7eef3f5ed86f +Author: Guus Sliepen +Date: Fri Aug 8 19:39:41 2003 +0000 + + Better error messages under Windows. + +commit 6f3099595530280028f6ec3d0b310df523e75f98 +Author: Guus Sliepen +Date: Fri Aug 8 17:20:12 2003 +0000 + + Typo. + +commit 691907caaeb348dee3dbe8a85f3590241f2cc992 +Author: Guus Sliepen +Date: Fri Aug 8 17:17:13 2003 +0000 + + Readd quotes. + +commit f956a28147ec8596c9a51b0c1535bb4b8c87692c +Author: Guus Sliepen +Date: Fri Aug 8 16:49:29 2003 +0000 + + Make rule for sample-config.tar.gz. + +commit 7e74e00d167da659ba6c3db3e8822008d27c081b +Author: Guus Sliepen +Date: Fri Aug 8 14:59:27 2003 +0000 + + Allow empty lines in config files. + +commit 863349638beb1eaab09e2a3d537c20a7913aef30 +Author: Guus Sliepen +Date: Fri Aug 8 14:48:33 2003 +0000 + + Simplify execute_script(). It will probably work under Windows as well. + +commit deba3ed900eb4453d27412606cecfaf89b5a5643 +Author: Guus Sliepen +Date: Fri Aug 8 14:24:09 2003 +0000 + + Correct error message when remote host closed connection. + +commit 0c2256670fc0822cc5a86bca754186c50f943a1c +Author: Guus Sliepen +Date: Fri Aug 8 14:07:12 2003 +0000 + + Remove unused stuff from doc/. + Let configure update pathnames in documentation. + +commit 070aee3be16b8d8078b049c5bb43dce7b18123df +Author: Guus Sliepen +Date: Fri Aug 8 12:55:05 2003 +0000 + + Tell windows to be patient. + +commit adb68b9c2aa7ad72dd5c38b95c083c47599cb65a +Author: Guus Sliepen +Date: Fri Aug 8 12:24:52 2003 +0000 + + Windows uses backslashes... + +commit ef091d1ddb1f7ab5244db96841274dc769e85167 +Author: Guus Sliepen +Date: Fri Aug 8 11:45:37 2003 +0000 + + Sync CABAL branch with release-1_0 branch. + +commit 5193a14ddea4c20ffc708dc629a2f91f1e4ccea3 +Author: Guus Sliepen +Date: Sun Aug 3 21:45:41 2003 +0000 + + Use our own port when connecting to ourself. + +commit 62a7fa9a7bfd1cd1592fd7c381ea28aac0ed7936 +Author: Guus Sliepen +Date: Sun Aug 3 21:45:13 2003 +0000 + + Simplify translation + +commit 98f97da9d7d80b528d9a2b2f03f710cdd2b293d0 +Author: Guus Sliepen +Date: Sun Aug 3 21:43:19 2003 +0000 + + Update dutch translation + +commit e220187f484f3549df3ad3a04939b9a38051d1a0 +Author: Guus Sliepen +Date: Sun Aug 3 12:38:43 2003 +0000 + + Remove newlines from log messages. + +commit 3671ed806d7371fb6b14a5909451b20e54a1b14a +Author: Guus Sliepen +Date: Sun Aug 3 12:38:18 2003 +0000 + + Keep Windows happy. + +commit 7bed2a7099fc7359f6ec24e5f2d7050c7d63b6ac +Author: Guus Sliepen +Date: Sun Aug 3 12:37:55 2003 +0000 + + Cygwin needs windows.h. + +commit fa9c00733e4b793691bf5a068ff7f2f391854fb4 +Author: Guus Sliepen +Date: Sun Aug 3 09:55:20 2003 +0000 + + Old gcc compilers don't like declarations in the middle of a function. + +commit a65011b3c54cd4ddc66f20909ca0e495de0d6eb0 +Author: Guus Sliepen +Date: Sun Aug 3 09:08:52 2003 +0000 + + Clean up last part of main(). + +commit e20ac7b52da8e3f7da292836c6e2551fc9f64617 +Author: Guus Sliepen +Date: Sat Aug 2 22:01:50 2003 +0000 + + Typo and another thing to think about. + +commit 92938c07b17fdd30f4e7f9ae1b884b05c7aa312c +Author: Guus Sliepen +Date: Sat Aug 2 21:55:12 2003 +0000 + + Explain how tinc detaches and how it is "killed" under Windows. + +commit 8a1969bc8319761e3821fc76a7c2f7037ffb8850 +Author: Guus Sliepen +Date: Sat Aug 2 21:39:11 2003 +0000 + + Updated dutch translation. + +commit f605ec47bed26362e24ffacf71c7ae5aeed3c230 +Author: Guus Sliepen +Date: Sat Aug 2 21:34:10 2003 +0000 + + Oops. + +commit e6e32814584f82ee61f658a71cb435bbb491bd39 +Author: Guus Sliepen +Date: Sat Aug 2 21:33:52 2003 +0000 + + Missing include. + +commit c044d12dfd54c033bc5ad9fbf9f889724762f76c +Author: Guus Sliepen +Date: Sat Aug 2 21:33:19 2003 +0000 + + Cleanups and error messages. + +commit 3fd96ebec7e44a0a7288c60da1cdec2d4fe03e8c +Author: Guus Sliepen +Date: Sat Aug 2 21:01:50 2003 +0000 + + Error messages. + +commit f08fc359a0b7f638e73a8f866119b016b7dff8de +Author: Guus Sliepen +Date: Sat Aug 2 20:50:38 2003 +0000 + + Install tinc as a service under Windows (MinGW). Remove cleanup_and_exit(), + either exit() directly on errors or let main_loop() shutdown gracefully. + +commit 7c34122af7ed4667748ceae4966bd5b519ac8ad7 +Author: Guus Sliepen +Date: Sat Aug 2 16:05:33 2003 +0000 + + When compiling with MinGW, link with ws2_32. + +commit 9a491a10eee55b243dd1030ee9016ec510908a10 +Author: Guus Sliepen +Date: Sat Aug 2 15:32:57 2003 +0000 + + Windows has no symbolic links as we know it. + +commit 9c2d5d9f9212dee5ee988f4824e5e4afedb7a2dd +Author: Guus Sliepen +Date: Sat Aug 2 15:29:06 2003 +0000 + + Oops. + +commit c7bf64c7946ece3e1a6a7cdd7bce00045bddb9cd +Author: Guus Sliepen +Date: Sat Aug 2 15:27:24 2003 +0000 + + Allow whitespace in values. + +commit b79e55b183898911e2c2b7b151b281aef8d474e1 +Author: Guus Sliepen +Date: Sat Aug 2 15:13:08 2003 +0000 + + Prevent system headers from including our own headers. + +commit 998ac634d456567e7caf99fe879d4ef1602f36bf +Author: Guus Sliepen +Date: Fri Aug 1 08:18:22 2003 +0000 + + Wrong function... + +commit 2531ff59b73af3a6de85fdc33d744758a6ab9449 +Author: Guus Sliepen +Date: Thu Jul 31 14:24:19 2003 +0000 + + Woops! + +commit 1fe56637874a1e93882a2ca6ffb8c50a773f80e4 +Author: Guus Sliepen +Date: Thu Jul 31 13:18:34 2003 +0000 + + No easy way to properly detect header files... + +commit 8eca27e863d9cb139a1e4039f63aaac3c9afc3c6 +Author: Guus Sliepen +Date: Thu Jul 31 11:31:51 2003 +0000 + + Remove forgotten braces. + +commit 5c29d066688691dd1664597ba1c76195634f06c0 +Author: Guus Sliepen +Date: Thu Jul 31 11:20:32 2003 +0000 + + Wrong argument. + +commit da3078c63a3b658573f6e2f986f69ed4d7993b3a +Author: Guus Sliepen +Date: Thu Jul 31 11:17:39 2003 +0000 + + Check if the compiler knows about the __malloc__ attribute. + +commit d798b8b3d832f8c69769e08cfd64a4d8355faf0e +Author: Guus Sliepen +Date: Wed Jul 30 21:52:41 2003 +0000 + + Prevent definitions from messing up attributes. + +commit 2edc764a333764e7e5c4d3420131c13e9c81ecf7 +Author: Guus Sliepen +Date: Wed Jul 30 16:00:59 2003 +0000 + + Replacement for stdbool.h + +commit fcbe29bc4cc67530581a36cf1a3a1445c741b8e5 +Author: Guus Sliepen +Date: Wed Jul 30 11:50:45 2003 +0000 + + No C99 initialisers, gcc 2.95.3 doesn't like it. + Also make sure getopt.h is included. + +commit de223b51b94c58d1674f1ef56e9d485ff48d366d +Author: Guus Sliepen +Date: Wed Jul 30 09:45:21 2003 +0000 + + Remove doc/es/ and src/device.c from the distribution. + +commit 63568bb6bca20b4d2b2068a6367084a273eabac8 +Author: Guus Sliepen +Date: Wed Jul 30 09:22:29 2003 +0000 + + Update documentation and remove stuff that's too outdated. + +commit 2ed154e73192d5e162544bc570abbb3a1df3ec83 +Author: Guus Sliepen +Date: Tue Jul 29 23:21:01 2003 +0000 + + Cleanups. + +commit 721e4caee0f7c6e003c297c95fb6d93bd4102219 +Author: Guus Sliepen +Date: Tue Jul 29 22:59:01 2003 +0000 + + Native Windows support. + +commit 586f15ed20682413d1bddbb4518dd2714c96b255 +Author: Guus Sliepen +Date: Tue Jul 29 12:38:49 2003 +0000 + + Make sure (at least) the MinGW device driver works. + +commit 6f7cce69479f9b2796d81f458bf836287b74462e +Author: Guus Sliepen +Date: Tue Jul 29 12:18:35 2003 +0000 + + Make sure it works. + +commit 4370b98bb1dfa9eb1e400549cb6fcb6711aa1b29 +Author: Guus Sliepen +Date: Tue Jul 29 11:50:39 2003 +0000 + + Update configure scripts. + +commit ae50b0077e27c4c4d81a98da46c66865ffa069be +Author: Guus Sliepen +Date: Tue Jul 29 11:06:23 2003 +0000 + + Update dutch translation and make sure all device drivers are included in + the translation and distribution. + +commit 714fb32d0377ed9f5643ed8f0bd914843d12266b +Author: Guus Sliepen +Date: Tue Jul 29 10:50:15 2003 +0000 + + Fix compile errors and warnings. + +commit 0e945413315c9d15a3eb013fa3731dd978a8c7b8 +Author: Guus Sliepen +Date: Mon Jul 28 22:06:09 2003 +0000 + + More checks for missing functions. + +commit c15e8a96bf7e45adf750b7a36b0e8446ea049468 +Author: Guus Sliepen +Date: Mon Jul 28 21:54:03 2003 +0000 + + More generic handling of tap device under Windows. + +commit 83263b74460656ba557fd9bb84dc27258549e9cd +Author: Guus Sliepen +Date: Thu Jul 24 12:08:16 2003 +0000 + + Sprinkle around a lot of const and some C99 initialisers. + +commit 5cb147135184e3748c6f5e6e6203d22ab9f904f8 +Author: Guus Sliepen +Date: Wed Jul 23 22:17:31 2003 +0000 + + Don't initialise a CIPHER_CTX if cipher == NULL. + +commit 4aadb9500d9198f9c271deb048a2d36000bfae34 +Author: Guus Sliepen +Date: Tue Jul 22 21:13:23 2003 +0000 + + Run setup_device() after parsing configuration but before claiming we're ready. + +commit eefa28059ab989c915a7d95fb4ae728abd7ce713 +Author: Guus Sliepen +Date: Tue Jul 22 20:55:21 2003 +0000 + + Use bools and enums where appropriate. + +commit 471308e1636e7a06e1d9ebc98e82b1c0c5150dde +Author: Guus Sliepen +Date: Tue Jul 22 12:58:34 2003 +0000 + + Option to specify pidfile location. + +commit c96900f378966ca1be96ddb1c43f855c74083b70 +Author: Guus Sliepen +Date: Mon Jul 21 19:58:58 2003 +0000 + + Add section about configuring Cygwin and CIPE on Windows. + +commit bad82522ecfc1f3c72c600cbca6e8fa7e950c3bf +Author: Guus Sliepen +Date: Mon Jul 21 15:51:00 2003 +0000 + + Copy cygwin driver to mingw directory. It doesn't work (yet). + +commit e169244e4b10dbcc1910c0f7fd811304d5b1a5a5 +Author: Guus Sliepen +Date: Mon Jul 21 14:47:43 2003 +0000 + + Use functions from logger.c + +commit 2f2defc4525befd5b5cb69d03b7887db35e9e46c +Author: Guus Sliepen +Date: Mon Jul 21 13:18:44 2003 +0000 + + Check for sys/mman.h. + +commit 64fd25aa6b794bb1d957b50d48705f30ed47c878 +Author: Guus Sliepen +Date: Mon Jul 21 13:15:36 2003 +0000 + + Oops. + +commit c1e8152f4fe5e4557784d8411e50006d461b8786 +Author: Guus Sliepen +Date: Mon Jul 21 13:14:02 2003 +0000 + + Be consistent. + +commit b657f0519456d05bcea5742017165793f79e56df +Author: Guus Sliepen +Date: Fri Jul 18 14:10:27 2003 +0000 + + No UNIX style permissions under Windows. + +commit 38aa0319ef79124e59b587e6d55f37a79a9d847c +Author: Guus Sliepen +Date: Fri Jul 18 14:09:47 2003 +0000 + + Oops. + +commit 123bb765d10453fdccbe363a02e3042c588729cc +Author: Guus Sliepen +Date: Fri Jul 18 13:45:06 2003 +0000 + + Use iface instead of interface because it might already be declared in + system header files. + +commit 96ee04b678143defa1040f2defdd3424efedea11 +Author: Guus Sliepen +Date: Fri Jul 18 13:42:35 2003 +0000 + + Check for ethernet/ipv4/ipv6 related structures. + +commit 00ddbf5723511d80fbd2522fc503bd409dc6189a +Author: Guus Sliepen +Date: Fri Jul 18 13:41:37 2003 +0000 + + Update all device.c files. + +commit 271d3537fed28b3e76cf0e76082b44c8771ac5da +Author: Guus Sliepen +Date: Fri Jul 18 12:21:03 2003 +0000 + + Remove all #ifndefs from route.c + +commit b0a4f7b5551cae6fb5af2eb4bcb0dfb3443f7d89 +Author: Guus Sliepen +Date: Fri Jul 18 12:16:24 2003 +0000 + + Even more missing definitions. + +commit e449d94caef963809d417f16497f6f978e10d731 +Author: Guus Sliepen +Date: Thu Jul 17 15:06:27 2003 +0000 + + Big header file cleanup: everything that has to do with standard system + libraries is moved to system.h. + +commit 47721be760c495ec13d68181bc03b151ffc1399c +Author: Guus Sliepen +Date: Tue Jul 15 16:38:18 2003 +0000 + + Windows headers declare a struct interface somewhere. + +commit 4c52febc57f2e34f5a187f0e57782903fe1eb95e +Author: Guus Sliepen +Date: Tue Jul 15 16:27:39 2003 +0000 + + Make use of the CIPE driver. Woohoo, tinc for Windows! + +commit d26a4af4561ce4236b8224919cf4f3636f57b4c1 +Author: Guus Sliepen +Date: Tue Jul 15 16:26:18 2003 +0000 + + Export mymac. + +commit 784db4e70d2573468c82ff5dfee723b77a20322f +Author: Guus Sliepen +Date: Sat Jul 12 20:24:04 2003 +0000 + + Format string checking for logger(). + +commit a438ac911e7e60e54d7d1fc4f84373fab7e055af +Author: Guus Sliepen +Date: Sat Jul 12 20:19:22 2003 +0000 + + Removing distribution specific files from CVS. + +commit 085d33e6265e139bb08cdfda3d7498993190d187 +Author: Guus Sliepen +Date: Sat Jul 12 17:48:38 2003 +0000 + + Update copyrights. + +commit 5db596c6844169f1eb5f804b72abe99d067aaa5a +Author: Guus Sliepen +Date: Sat Jul 12 17:41:48 2003 +0000 + + Simplify logging, update copyrights and some minor cleanups. + +commit 2a7f11c0e90f5f0465bbc3c75de715454066ff72 +Author: Guus Sliepen +Date: Fri Jul 11 16:13:00 2003 +0000 + + More missing IPv6 definitions and autoconf checks to make sure it compiles + under Solaris 2.6. + +commit 71f8124ea49f2a0e00e0cedbb1b76e49e9f1425d +Author: Guus Sliepen +Date: Mon Jul 7 11:50:52 2003 +0000 + + More missing definitions. + +commit a88f1edf297152580a7729c6f3d274ba2bff7360 +Author: Guus Sliepen +Date: Mon Jul 7 11:13:31 2003 +0000 + + Actually add ipv6.h. + +commit 30c0381d71d333a99f6c83ff9d03ef4a0857f423 +Author: Guus Sliepen +Date: Mon Jul 7 11:11:33 2003 +0000 + + Provide all missing IPv6 definitions in lib/ipv6.h. + +commit 1401faf608e1c8af0d0754e545b0ec79d2bd5d93 +Author: Guus Sliepen +Date: Sun Jul 6 23:16:29 2003 +0000 + + Sprinkling the source with static and attributes. + +commit 0b9175e998c2180e5d73ef3d644a49d620c68cad +Author: Guus Sliepen +Date: Sun Jul 6 22:11:37 2003 +0000 + + Define logger(), cleans up source code and allows us to write log entries + to a separate file. + +commit 868104703003605711582c984b57f8933bf361ee +Author: Guus Sliepen +Date: Sun Jul 6 17:49:49 2003 +0000 + + Check for IPv6 header files. + +commit 81f5713ab71944d51703653eab7f364fba0c482e +Author: Guus Sliepen +Date: Sun Jul 6 17:15:25 2003 +0000 + + - simplify configure.in + - drop support for OpenSSL < 0.9.7 + - add some missing definitions/includes + +commit 6c7172d694dcb80e538518282b6c4bd51818f1d2 +Author: Guus Sliepen +Date: Wed Jun 25 20:55:05 2003 +0000 + + This subtle pointer arithmetic thingy is (I'm very sure of it) the cause + of the lingering connections problem. Hopefully it is fixed now... + +commit 9528a63c35da77ba5b825068aeffbc5587816dd5 +Author: Guus Sliepen +Date: Wed Jun 25 20:52:59 2003 +0000 + + Really make tinc default to any addressfamily. + +commit 8bfa554af97ee0694919b9f5b78ada89c6af62f5 +Author: Guus Sliepen +Date: Thu Jun 12 11:08:40 2003 +0000 + + There are two lzo compression levels. + +commit c3593491d44e8e8f239bb297f5d5f6541d581b78 +Author: Guus Sliepen +Date: Wed Jun 11 20:36:36 2003 +0000 + + Typo and conversion to UTF-8. + +commit 636e650261712e3687048fe19987fd50ce84b093 +Author: Guus Sliepen +Date: Wed Jun 11 20:19:46 2003 +0000 + + Update dutch translation. + +commit 9279b3c69982b066e2aaea4e444892b51332881a +Author: Guus Sliepen +Date: Wed Jun 11 20:18:48 2003 +0000 + + Update documentation. + +commit 0a9aef2da749f7b7d1ca183daad88f6433579b9f +Author: Guus Sliepen +Date: Wed Jun 11 19:40:43 2003 +0000 + + More braces to make gcc happy. + +commit cf63cbef2bcb6a1f21ded439cbb09842581b9020 +Author: Guus Sliepen +Date: Wed Jun 11 19:39:02 2003 +0000 + + Fixes from Wessel Danker's libavl. + +commit 12de5a8eedd985f4732e88de6185f77a8244612c +Author: Guus Sliepen +Date: Wed Jun 11 19:28:38 2003 +0000 + + Remove mymac stuff from device.c. + +commit 31f17d43346a9175aec7c29ce41c71b1d08f725e +Author: Guus Sliepen +Date: Wed Jun 11 19:27:35 2003 +0000 + + AddressFamily is "any" by default. + +commit 451800eda87e886021fabd1888e486c51e97902a +Author: Guus Sliepen +Date: Wed Jun 11 19:09:52 2003 +0000 + + If we have a Linux tun/tap device and we are in router mode, open the device + in tun mode. + +commit 9e02a3d5631b687833e4cdcde18cda66e38138fc +Author: Guus Sliepen +Date: Wed Jun 11 19:07:56 2003 +0000 + + Call make_names() before doing anything else. + +commit 4b0e5a03fe89529ebe5d471a82c29c153a12116b +Author: Guus Sliepen +Date: Sat Jun 7 13:18:32 2003 +0000 + + Fix warning and add missing checks for LZO library. + +commit f238c209f4a0ced889b8fb443753ed2cdb3548b3 +Author: Guus Sliepen +Date: Sat May 17 22:12:52 2003 +0000 + + Fix links. + +commit 249933350bda2c3fa09c7ce8eb36bf84ee30a1cb +Author: Guus Sliepen +Date: Wed May 7 11:21:58 2003 +0000 + + Small fixes. + +commit 6ba4e2da55001e17aec6a7ee71002130555ff439 +Author: Guus Sliepen +Date: Tue May 6 23:14:45 2003 +0000 + + Small fixes to make LZO compression work. + +commit c70f52087bf6f7514684bbc859b83aec2ca17ae4 +Author: Guus Sliepen +Date: Tue May 6 21:13:18 2003 +0000 + + - Per-node EVP_CIPHER_CTX to avoid initialisation overhead. + - LZO compression, thanks to Teemu Kiviniemi. + - Updated dutch translation. + +commit 1ad2394b8468593030653bbfd0dee879fb711432 +Author: Guus Sliepen +Date: Sat Apr 19 11:12:45 2003 +0000 + + Make sure outgoing_t is completely freed. + +commit bc9e78250ef6fb5169d03565b7d8d9caf309eb98 +Author: Guus Sliepen +Date: Fri Apr 18 21:18:36 2003 +0000 + + Better handling of late packets. + +commit 51a1bcf00143319c74ffb58a66a19c41be422c21 +Author: Guus Sliepen +Date: Thu Apr 3 11:43:17 2003 +0000 + + HUP signal now closes connections to hosts if their host config file is + gone or changed. The tinc.conf file is reread for changes in the ConnectTo + lines. + +commit 8285827da127e38728b60b5c5484e5cdabff2f21 +Author: Guus Sliepen +Date: Sat Mar 29 22:11:22 2003 +0000 + + Checksums must also work for uneven number of bytes. + +commit c3ad3731a8dfa34535a156a7cfdb4e18afaa8bce +Author: Guus Sliepen +Date: Sat Mar 29 21:58:35 2003 +0000 + + Don't copy more than necessary. + +commit 7d21a8d1c7fd8909fe02385dbb4717c074db4648 +Author: Guus Sliepen +Date: Sat Mar 29 21:51:21 2003 +0000 + + - Speed up checksumming + - If a destination is not found in the subnet list or the destination node + is unreachable, respond with an appropiate ICMP message. + +commit 9792ba2cac35cb50cc99b72dd4cb9d3ef350dbd4 +Author: Guus Sliepen +Date: Fri Mar 28 13:41:49 2003 +0000 + + - Avoid memory leak caused by OpenSSL 0.9.7a. + - Disable RSA_blinding_on() because it segfaults. + +commit 69158563e9f790777eb27aeb8484a86d12385af4 +Author: Guus Sliepen +Date: Wed Mar 19 11:45:05 2003 +0000 + + Typo. + +commit 88ae2e9e0c1eb62d9b74c4b38d9c0e93557fed9f +Author: Guus Sliepen +Date: Wed Mar 19 11:43:42 2003 +0000 + + Make sure send_meta() writes everything. + +commit 2fff0a91a7e3e5f44e97255b6dd5807656b255a8 +Author: Ivo Timmermans +Date: Fri Mar 14 09:43:10 2003 +0000 + + Call RSA_blinding_on(), as advised in the paper on + http://crypto.stanford.edu/~dabo/abstracts/ssl-timing.html + to offer some resistance against timing attacks. + +commit 1783a3aaa9b692ab64260a9c2adf588ed6083a1c +Author: Guus Sliepen +Date: Fri Jan 17 00:43:58 2003 +0000 + + Various fixes for autoconf and OpenSSL 0.9.7 and a missing header. + +commit c08858baa91a00e38c0f5482dbb0817dbd0361f1 +Author: Guus Sliepen +Date: Fri Jan 17 00:37:20 2003 +0000 + + - Fix indentation in some places. + - Optimise select loop. + - Remove unused function setup_outgoing_socket(). + - Clear EVP_CIPHER_CTX structures before using them. + +commit 38f562fdfcacb50d34b9a48bfaea7faa132f493a +Author: Guus Sliepen +Date: Tue Jan 14 12:53:59 2003 +0000 + + Add $NAME for tinc-up/down scripts. + +commit 44b87ddb7ac90be13ef3e3d5118acaa158184853 +Author: Guus Sliepen +Date: Sun Jan 12 17:02:23 2003 +0000 + + Run graph algorithm when replacing a second connection from the same host + replaces an older one. + +commit 4c88ff86bcd32735d4768ef3464812cd77c500be +Author: Guus Sliepen +Date: Fri Dec 27 19:32:33 2002 +0000 + + PrivateKeyFile instead of PrivateKey. + +commit 5b2a62ebb6317cd88e491ee958c54670f381aee8 +Author: Guus Sliepen +Date: Thu Nov 14 22:09:03 2002 +0000 + + Fix PriorityInheritance. + +commit 07db46a44feb283c1c17bcce918ab49274a3b11f +Author: Guus Sliepen +Date: Mon Oct 7 07:32:31 2002 +0000 + + Add documentation for BindToAddress. + +commit e310cc82d3f9c9bdb3b827daa149861a41e2e00a +Author: Ivo Timmermans +Date: Mon Sep 30 19:04:37 2002 +0000 + + Fix saving of debug level for startup level 0 + +commit 006591efe5b3e6c64040d267f8c0477468abf2bf +Author: Guus Sliepen +Date: Tue Sep 24 11:43:34 2002 +0000 + + Run graph() after edge_del() when updating an edge. + +commit 6904e0469ef52aa6100f0185d579bc205bd07be8 +Author: Wessel Dankers +Date: Mon Sep 16 14:08:04 2002 +0000 + + its: Engels voor "van het" - 3e persoon enkelvoud, genitief, onzijdig + it's: Engels voor "het is". Dus niet "van het". + +commit 4f3395ee4dad3cdd23706af180ebddfa5e576012 +Author: Guus Sliepen +Date: Sun Sep 15 22:37:59 2002 +0000 + + Thank some more people. + +commit b216297a004f083336c633aaccecb4ab175360b3 +Author: Guus Sliepen +Date: Sun Sep 15 22:34:25 2002 +0000 + + Remarks about 1.0pre8 release. + +commit 1dcbdf48eb4a642e4d70a9e67aaca78deacf352d +Author: Guus Sliepen +Date: Sun Sep 15 22:19:38 2002 +0000 + + Update documentation. + +commit bf3a11898898c0618cd1b2e7a792b7d7fe56aecb +Author: Guus Sliepen +Date: Sun Sep 15 22:19:19 2002 +0000 + + Use /dev/net/tun as default for tun/tap device under Linux. + +commit 7d76ceaebd5180f4ef37086980c799199eb7de16 +Author: Guus Sliepen +Date: Sun Sep 15 17:40:00 2002 +0000 + + Updated dutch translation. + +commit 5eca9520d93bced1275d45e5e2a933d69354cd6d +Author: Guus Sliepen +Date: Sun Sep 15 14:55:54 2002 +0000 + + Small fixes so tinc compiles out of the box on SunOS 5.8 + +commit 8d472a415e9c5fdb878386005d29cdfd97b8a404 +Author: Guus Sliepen +Date: Sun Sep 15 12:26:24 2002 +0000 + + port_t isn't used anymore and conflicts with MacOS/X headers. + +commit 38c80bdd46fab68c686a293e2820041291972f3a +Author: Guus Sliepen +Date: Sun Sep 15 12:26:04 2002 +0000 + + MacOS/X needs #define _P1003_1B_VISIBLE in order to use mlockall(). + +commit 3e3b4a3190cf950c265a8c62d577812a22b11dcc +Author: Guus Sliepen +Date: Wed Sep 11 22:25:58 2002 +0000 + + What was I thinking? + +commit f6905582d0e70ac5b44369780aaa921d9c721197 +Author: Guus Sliepen +Date: Tue Sep 10 22:13:22 2002 +0000 + + Make sure malloc() is declared. + +commit eaf1208e9d5c5a15e4b23de936830520bf3b5685 +Author: Guus Sliepen +Date: Tue Sep 10 22:13:01 2002 +0000 + + Fix placement of #include "config.h" + +commit dd888ca685176128bf41034208f3dbb220f9d832 +Author: Guus Sliepen +Date: Tue Sep 10 21:46:05 2002 +0000 + + Link with libintl if necessary. + +commit c01f78ed3603eecaec8e3649a3bfb3de9742fd24 +Author: Guus Sliepen +Date: Tue Sep 10 21:29:42 2002 +0000 + + Clean up after indent. + +commit 161f917dd03c174742fb8c6722f430a93b506cb1 +Author: Guus Sliepen +Date: Tue Sep 10 09:40:25 2002 +0000 + + Fix compiler warnings. + +commit 3bc554347560a9c24e68bb2c7c7749be07bbec3d +Author: Guus Sliepen +Date: Mon Sep 9 22:41:56 2002 +0000 + + Let GCC check format string and arguments of send_request(). + +commit 6f9f6779e6bd1dd7bb795b42dad550863a386ca8 +Author: Guus Sliepen +Date: Mon Sep 9 22:33:31 2002 +0000 + + Remove redundant spaces. + +commit 9f38e394636a177c00a4545de2a99c661de36386 +Author: Guus Sliepen +Date: Mon Sep 9 21:49:16 2002 +0000 + + Switch to K&R style indentation. + +commit f75dcef72a81a337e847adf0bae54198894f65b9 +Author: Guus Sliepen +Date: Mon Sep 9 21:25:28 2002 +0000 + + Switch to K&R style indentation. + +commit 5fc1ed17f41f0c535cf57a4b7e00cd6d45759503 +Author: Guus Sliepen +Date: Mon Sep 9 19:40:12 2002 +0000 + + Cleanups: + - Convert cp to cp(); so that automatic indenters work. + - Convert constructions like if(x == NULL) to if(!x). + - Move all assignments out of conditions. + +commit 5638b9830f9cfe43f545c37cfd7ccf1d4b4bfcc6 +Author: Guus Sliepen +Date: Fri Sep 6 21:22:35 2002 +0000 + + Why don't these connection_t's get cleaned up? + +commit a8ddba42b99d7694359f1387235596b84d297b9e +Author: Guus Sliepen +Date: Fri Sep 6 21:02:36 2002 +0000 + + Fix MST algorithm. + +commit 66741978e16cc407e5c760621c34d1aabb753cd2 +Author: Guus Sliepen +Date: Fri Sep 6 14:31:12 2002 +0000 + + Reset the *correct* seqnos. + +commit d5b61fc0cd249fd2b2751a1ff77b321323a17beb +Author: Guus Sliepen +Date: Fri Sep 6 12:19:16 2002 +0000 + + edge_weight_compare() shouldn't rely on edge_compare(). + +commit fc7116a32b798589e7731db9f9db66345c8c3e01 +Author: Ivo Timmermans +Date: Fri Sep 6 11:08:21 2002 +0000 + + Added AM_MAINTAINER_MODE + +commit fbf8a47879671541939cfdc6beb93b02b9eee303 +Author: Guus Sliepen +Date: Fri Sep 6 10:23:52 2002 +0000 + + Remove global edge_tree. + +commit 641705df90b4c41e7f5083f6cd601cbbfb1c2c85 +Author: Guus Sliepen +Date: Fri Sep 6 09:48:39 2002 +0000 + + Only reset seqno's when a key is sent or received. + +commit e4d85a6557ee45870bee0c5a16807e48b7a3c243 +Author: Guus Sliepen +Date: Wed Sep 4 23:11:58 2002 +0000 + + Typo. + +commit b4f87952bf2d37524c705b32864f802144f94d68 +Author: Guus Sliepen +Date: Wed Sep 4 23:05:49 2002 +0000 + + Add missing headers. + +commit b18bd211bec84a804f58da5f2d2908e54de3fe40 +Author: Guus Sliepen +Date: Wed Sep 4 23:04:52 2002 +0000 + + Run autopoint and libtoolize before creating initial makefiles. + +commit 6fdaa8e1caff4edb44a105b03c79403b743e9bd2 +Author: Guus Sliepen +Date: Wed Sep 4 19:57:53 2002 +0000 + + Small updates. + +commit d4277e9ee8affa59ac9b3475245360bd14af1fa8 +Author: Guus Sliepen +Date: Wed Sep 4 16:36:03 2002 +0000 + + Updated dutch translation. + +commit 8b2b67e26c5b971761f5015764d5e188f6343bc4 +Author: Guus Sliepen +Date: Wed Sep 4 16:26:45 2002 +0000 + + Generalized request broadcasting/forwarding. + +commit 431fa10b37e78172a03c952e28a0364cc0e438f0 +Author: Guus Sliepen +Date: Wed Sep 4 14:17:28 2002 +0000 + + Small fixes. + +commit 82ebfc923ddb050c88bdf5d65ac943a15ca8748a +Author: Guus Sliepen +Date: Wed Sep 4 13:48:52 2002 +0000 + + Revert to edge and graph stuff. This time, use a directed graph. + +commit 973530db628fb91106d6fb7a17151e1d036e40a2 +Author: Guus Sliepen +Date: Wed Sep 4 08:48:03 2002 +0000 + + Just ignore wrong ADD_NODEs instead of replying with a DEL_NODE, in the + hope other DEL_NODEs will catch up eventually. + +commit 2af0bcc8fd39ca34a7ff856d539cdf38728a8c25 +Author: Guus Sliepen +Date: Wed Sep 4 08:36:34 2002 +0000 + + Don't forget to set prevhop to myself for new connections. + +commit 698d6ddac6ab32d5a4b802941b02232793442684 +Author: Guus Sliepen +Date: Wed Sep 4 08:33:08 2002 +0000 + + Prevent looping DEL_NODE/ADD_NODE messages after a node disconnects. + +commit 4a7c2026aec6966f934b60d75bc472d28f8587d8 +Author: Guus Sliepen +Date: Wed Sep 4 08:02:33 2002 +0000 + + Reduce KEY_CHANGED traffic. + +commit ddb96301a39dd3dac8d3df4e2e189b13b75e0b6e +Author: Guus Sliepen +Date: Tue Sep 3 22:49:55 2002 +0000 + + Woops. + +commit b5bb06200eda170c9836e1b4474d6f5b920c2151 +Author: Guus Sliepen +Date: Tue Sep 3 22:37:49 2002 +0000 + + A reachable node is always more preferable to an unreachable one... + +commit d134c4542d4e890e1c1007f32b866742319853c5 +Author: Guus Sliepen +Date: Tue Sep 3 20:43:26 2002 +0000 + + Drop graph and edge stuff. Use new node stuff instead. + +commit 856de4c5fe8acd779aa9277d4554e34ff3625e97 +Author: Guus Sliepen +Date: Tue Sep 3 20:42:05 2002 +0000 + + Make sure setlocale() is available. + +commit 2cb21f8810a6e0241a80623e991c8308b603ae95 +Author: Guus Sliepen +Date: Mon Sep 2 22:40:42 2002 +0000 + + Replacement for the current routing algorithm. + +commit f2c2443bbcfd5e09518bd87f3fd8d4a727d73ae2 +Author: Guus Sliepen +Date: Sat Aug 24 12:54:55 2002 +0000 + + Check for ranlib. + +commit 912e7e968f4888d62b3c620893a70e825599973b +Author: Guus Sliepen +Date: Sat Aug 24 12:11:40 2002 +0000 + + Gettext 1.11.5 compatibility. + +commit 18948c5784bfedf0dd5a371e41bc2cceee76d92e +Author: Guus Sliepen +Date: Thu Jul 18 14:30:45 2002 +0000 + + Added support for raw sockets. This can be used instead of tun/tap devices. + +commit 9f370893fafaeacdd78f5488cfa8b76fdee0d224 +Author: Guus Sliepen +Date: Tue Jul 16 13:18:27 2002 +0000 + + Don't bother to chown, and correctly document ConnectTo. + +commit 227ccd3a8a5602e4c31add8da1bfd8b35c6a801f +Author: Guus Sliepen +Date: Tue Jul 16 13:12:49 2002 +0000 + + Allow tincd to be locked into main memory. + +commit c4cd19935763b379e730a6fdf53dc1ca98d0b938 +Author: Guus Sliepen +Date: Fri Jul 12 11:45:21 2002 +0000 + + Include complete fake-getname/addrinfo from OpenSSH. + +commit afabbd6b9020dd6555a7ecd320a7b3e96119d538 +Author: Guus Sliepen +Date: Thu Jul 11 12:57:06 2002 +0000 + + Added stub device.c for Cygwin. + +commit 8949404db08f4ab594e60778bb76a9061426d7cc +Author: Guus Sliepen +Date: Thu Jul 11 12:55:58 2002 +0000 + + Started port to Cygwin. + +commit c98db1b861d62430e23f26b0da18e7b3ec875767 +Author: Guus Sliepen +Date: Thu Jul 11 12:42:43 2002 +0000 + + Clear subnets before using them. + +commit 8dd09568f1604f1ac8cc0d8d5120d986f5654900 +Author: Guus Sliepen +Date: Wed Jul 10 11:32:33 2002 +0000 + + Allow identical subnets from different owners. + +commit 36cbaa32f480b481bf2ee99fd4835586a02ebc60 +Author: Guus Sliepen +Date: Wed Jul 10 11:27:06 2002 +0000 + + Allow list of environment variables to be passed to execute_script(). + When executing host-up/down scripts, include the address and port of the + remote host. + +commit a1bd878e11ae7e66e7e9a4040c3b19f9b7bc50f4 +Author: Guus Sliepen +Date: Fri Jun 21 17:49:48 2002 +0000 + + Fix for prefixlengths of 32 (IPv4) and 128 (IPv6) bits. + +commit 627f7c22b447bd464b536cd016278545674df93d +Author: Guus Sliepen +Date: Fri Jun 21 10:11:37 2002 +0000 + + s/sliepen.warande.net/sliepen.eu.org/g + s/itimmermans@bigfoot.com/ivo@o2w.nl/g + +commit faabd163adf89bd0580cd40b8735ef8d9028a942 +Author: Guus Sliepen +Date: Fri Jun 14 11:51:29 2002 +0000 + + Update comments about IPv6 autoconfiguration. + +commit 940fcb6701d055f49530f12c93371f0280efce80 +Author: Guus Sliepen +Date: Thu Jun 13 16:12:40 2002 +0000 + + Reset listen_sockets after SIGHUP. + +commit 3a3adf5b690e9be1390a5df3caee6af64b25838f +Author: Guus Sliepen +Date: Wed Jun 12 13:45:23 2002 +0000 + + Add configuration details for NetBSD and Darwin (MacOS/X). + +commit 8988b127e18435054e48cbcca8ac712ddda3d6d2 +Author: Guus Sliepen +Date: Tue Jun 11 11:03:17 2002 +0000 + + Autoconf cleanup. Works for both 2.13 and 2.53, although running autoconf + 2.53 still gives some errors. + +commit de6835a9dd1891b6435c128cc6c2293950a4d7a7 +Author: Guus Sliepen +Date: Mon Jun 10 15:08:23 2002 +0000 + + Include darwin/device.c in distribution. + +commit 40ac473cb10f9c6a59739ce70032b746d8e0bf68 +Author: Guus Sliepen +Date: Mon Jun 10 14:35:18 2002 +0000 + + Use darwin/device.c when compiling on MacOS/X. + +commit 69b758879ee6d322e89143141b98d52167845c26 +Author: Guus Sliepen +Date: Mon Jun 10 14:33:40 2002 +0000 + + Added Darwin (MacOS/X) tun device handling. + +commit bd72e14138185f342885c0ed1c0f2c5dbf571132 +Author: Ivo Timmermans +Date: Sun Jun 9 16:23:12 2002 +0000 + + Added Alessandro Gatti + +commit 944df3eeee50972fcac84cfc8eefb36033bf04ad +Author: Ivo Timmermans +Date: Sun Jun 9 16:19:20 2002 +0000 + + Include netbsd's device.c in make dist + +commit 7608136a8dae24f2df30eac8644efd0d7cd57dc9 +Author: Ivo Timmermans +Date: Sun Jun 9 16:12:04 2002 +0000 + + Include a few more header files + +commit cd3601c5df57c7544ece00bf79e82b36499a26ff +Author: Ivo Timmermans +Date: Sun Jun 9 15:58:05 2002 +0000 + + Add /sw/{include,lib} to search paths if they exist + +commit 548551fd05f58863dfbbaaf147febfab0a22889b +Author: Ivo Timmermans +Date: Sun Jun 9 15:50:12 2002 +0000 + + getnameinfo fixes + +commit 9d769e0bf2ce266e8533e5e7c16bf07e44a9be34 +Author: Ivo Timmermans +Date: Sun Jun 9 15:26:10 2002 +0000 + + OSX support + +commit 78e88521845ae3bdd963ae5a414cb9c251963fa2 +Author: Guus Sliepen +Date: Sat Jun 8 14:08:57 2002 +0000 + + - netinet/* include files depend on netinet/in_systm.h. + - Squash bashism in configure.in. + +commit e47e51e9d17416e2b614287d14a5518881decd44 +Author: Guus Sliepen +Date: Sat Jun 8 13:46:43 2002 +0000 + + Use inttypes.h instead of stdint.h. + +commit 116ba3b3da73fb857cf75b5c92c6aacd70d94dd9 +Author: Guus Sliepen +Date: Sat Jun 8 12:57:10 2002 +0000 + + Cleanup: + - Remove checks for specific OS's, instead check for #defines/#includes. + - Use uint??_t where appropriate. + - Mask handling functions use void pointers to get rid of silly casts. + +commit d333fca4d611b85dd922ddf35bd9eddcb8095c85 +Author: Wessel Dankers +Date: Fri Jun 7 11:14:05 2002 +0000 + + This should work much better. + +commit 14e570f5eeff631c1312b11fcc5d22230ec27aff +Author: Guus Sliepen +Date: Wed Jun 5 00:25:55 2002 +0000 + + Use correct includes on NetBSD. + +commit 5886b6a10d0d2edf20ff53c4926ec4e41a36b8c0 +Author: Guus Sliepen +Date: Wed Jun 5 00:20:40 2002 +0000 + + Make it work correctly with NetBSD tun device. + +commit 4856d8e1f8398780a49545f35ba9b5746c9fc060 +Author: Guus Sliepen +Date: Sun Jun 2 16:06:33 2002 +0000 + + Support RSA_PUBKEYs (as opposed to RSAPublicKeys) so tinc accepts + public keys generated by the OpenSSL command line tools. + +commit efa5148bc76effb440d807d653dda02de050fde0 +Author: Ivo Timmermans +Date: Tue May 7 14:48:41 2002 +0000 + + Hm. + +commit 151ab8c9708534e012447688ed44d711d5b5fa2d +Author: Ivo Timmermans +Date: Thu May 2 13:23:58 2002 +0000 + + test 2 + +commit be04387a0c868b22ee4427822573df8b3b479bbe +Author: Ivo Timmermans +Date: Thu May 2 13:22:44 2002 +0000 + + test + +commit a9bb66367df82d062175f2b9b4bf236d77ae3ff1 +Author: Ivo Timmermans +Date: Thu May 2 13:11:55 2002 +0000 + + Moved event.c/h + +commit 474aab6325bf94724874cb74a9b56d9da739e1b8 +Author: Ivo Timmermans +Date: Thu May 2 11:52:28 2002 +0000 + + Callbacks + +commit 4c1a4e8a790584e4c7d5c0f2485706f4c01e1911 +Author: Ivo Timmermans +Date: Thu May 2 11:50:07 2002 +0000 + + Another file moved; random interface stuff. + +commit 2be8e69ca16e1558463c39c48af76d3d4a4674b7 +Author: Guus Sliepen +Date: Wed May 1 09:15:58 2002 +0000 + + Only purge once when there are no more connections. + +commit a77b35e748b7cf4cf7ac31750cefab7b2b0325f5 +Author: Ivo Timmermans +Date: Mon Apr 29 20:19:42 2002 +0000 + + Commit diff test + +commit 7caa253df4a34e594438e3fbe80c2bddab9a2b4a +Author: Guus Sliepen +Date: Mon Apr 29 20:05:07 2002 +0000 + + Fix very stupid bug in node_del(), which might have caused corruption of + subnets. + +commit 04d33be4bd102de67bb6dba5c449e12fea0db4d2 +Author: Ivo Timmermans +Date: Sun Apr 28 12:46:26 2002 +0000 + + Moving files, first attempt at gcrypt compatibility, more interface + abstraction + +commit b0a676988a8da3120e64ef0e1a4ea4c28b1511e1 +Author: Ivo Timmermans +Date: Sun Apr 28 12:43:40 2002 +0000 + + *** empty log message *** + +commit 67a6d7bcc4891c627663c639c0e02315bd4cf437 +Author: Guus Sliepen +Date: Sat Apr 27 11:40:45 2002 +0000 + + Informative log message if execl() failed. + +commit e6a67fc439fc3b46157647bed1af59b7519adb80 +Author: Ivo Timmermans +Date: Fri Apr 26 18:13:00 2002 +0000 + + Typo + +commit 01747d73a217f7ddf2107b086476702a9d04d683 +Author: Guus Sliepen +Date: Thu Apr 25 19:17:24 2002 +0000 + + Added Nick Patavalis for his RedHat package. + +commit b6ad4ce35a4434c209ee26015f15a18180987bac +Author: Guus Sliepen +Date: Tue Apr 23 07:49:38 2002 +0000 + + Add BindToAddress variable, similar to the late BindToIP. + +commit 40c2e36a96a3f5c34d4851b30f3561123f3906b5 +Author: Guus Sliepen +Date: Fri Apr 19 14:06:40 2002 +0000 + + Support for MaxOS/X. + +commit 97d492d9e23f43fe4c8a5ca8c95747088cf32f98 +Author: Ivo Timmermans +Date: Thu Apr 18 20:09:05 2002 +0000 + + Put #ifndef checks for HAVE_RAND_PSEUDO_BYTES in the correct places. + +commit fa8faff84bbbeb818adaea80d7bf9e12e0074978 +Author: Ivo Timmermans +Date: Sat Apr 13 18:01:58 2002 +0000 + + Print newline when writing to stderr + +commit fbebc5b65606119c01e9e1e3fcc7b2cc4cfd1daf +Author: Ivo Timmermans +Date: Sat Apr 13 11:24:25 2002 +0000 + + ... + +commit 7c75090025a4b06290663e0033a62414f3368f7c +Author: Ivo Timmermans +Date: Sat Apr 13 11:23:46 2002 +0000 + + Rename libvpn to libtinc + +commit 55385cacbfb0c743fc518e54854e24b7b05a623c +Author: Ivo Timmermans +Date: Sat Apr 13 11:23:19 2002 +0000 + + Renamed libvpn to libtinc + +commit 2389dcd573d909f21c8ec2d349b079075af6c7d3 +Author: Ivo Timmermans +Date: Sat Apr 13 11:21:58 2002 +0000 + + Include logging.h + +commit 246ce12c92ccc7badbb8c8c9a88fa03a7de9811f +Author: Ivo Timmermans +Date: Sat Apr 13 11:21:01 2002 +0000 + + Use new logging system + +commit a5b3ec41214ac8aea9b82734f92b5953e04a0c09 +Author: Ivo Timmermans +Date: Sat Apr 13 11:15:43 2002 +0000 + + Things to ignore... + +commit e239504524589a0f1549ca174f927afd07d563ba +Author: Ivo Timmermans +Date: Sat Apr 13 11:14:50 2002 +0000 + + Compile in logging.c + +commit e26dd564163fca001ab1694a51e7412f9ac970de +Author: Ivo Timmermans +Date: Sat Apr 13 11:08:31 2002 +0000 + + Use logging.h instead of syslog.h + +commit 72cd8938e2c759905666ea7d2c90dc1f0b2e2cd5 +Author: Ivo Timmermans +Date: Sat Apr 13 11:00:41 2002 +0000 + + Added prototype for log_syslog + +commit 48b80c93d30d5fae4273b0b496252bbc884abe53 +Author: Ivo Timmermans +Date: Sat Apr 13 10:55:42 2002 +0000 + + log_default_hook was renamed to log_default + +commit b63c3a1f0002675b6bedbd0b235e0ad0a708d4e3 +Author: Ivo Timmermans +Date: Sat Apr 13 10:50:48 2002 +0000 + + Added priority definitions from syslog.h + +commit 490b13edcfcae0422b6bd77fdb2a7f0181b14307 +Author: Ivo Timmermans +Date: Sat Apr 13 10:45:56 2002 +0000 + + Some magic + +commit 738389581b1ba29a181f639f3d20e3e24ff546f5 +Author: Ivo Timmermans +Date: Sat Apr 13 10:43:10 2002 +0000 + + Add syslog wrapper + +commit efa59f7cf4d416c8416866baeaa72cba7e936568 +Author: Ivo Timmermans +Date: Sat Apr 13 10:40:09 2002 +0000 + + Add syslog() wrapper + +commit 8822481d7b11db72d5400717d6b491b5f36bcb1f +Author: Ivo Timmermans +Date: Sat Apr 13 10:29:07 2002 +0000 + + Rename log_message to log + +commit cc603e2765f17555ecdc2b74c27ebf96e6691bf6 +Author: Ivo Timmermans +Date: Sat Apr 13 10:25:38 2002 +0000 + + New logging system to replace syslog() calls with a generic function. + +commit 131327a729216de8ae86da0c3c4d65d409741b7b +Author: Ivo Timmermans +Date: Sat Apr 13 10:04:46 2002 +0000 + + Remove debug_lvl + +commit e3c51b61caabc1a55772f7a52e75aab642c200ed +Author: Ivo Timmermans +Date: Sat Apr 13 10:02:48 2002 +0000 + + Update copyright info + +commit 9e8468f54aa5ecdb8b63c60449791427b59a474d +Author: Ivo Timmermans +Date: Sat Apr 13 10:02:16 2002 +0000 + + Remove debug level declaration + +commit 9f2c50e159caea1884c6a7aaa33f8098539ae0f5 +Author: Guus Sliepen +Date: Fri Apr 12 08:25:01 2002 +0000 + + Adding even more stuff from the CABAL branch. + +commit 191dcd5add0afba8b5d3aaa1e188c562c621712e +Author: Ivo Timmermans +Date: Thu Apr 11 20:18:02 2002 +0000 + + Also compile in pokey/ + +commit 39e93f473d34d6cdf6f4a7f0390a3b50cbd7b564 +Author: Ivo Timmermans +Date: Thu Apr 11 20:17:33 2002 +0000 + + Write src/pokey/Makefile + +commit c351b9e25b9f7b168a47fd8e6b60c66377e1824c +Author: Ivo Timmermans +Date: Thu Apr 11 14:27:35 2002 +0000 + + Pokey interface definition + +commit 17b308f0f0879c01f6864265af2e63595e965993 +Author: Ivo Timmermans +Date: Thu Apr 11 14:23:56 2002 +0000 + + Main pokey interface files. + +commit b5b38381c643632aa88c677236cace8c60e8344e +Author: Ivo Timmermans +Date: Tue Apr 9 16:11:48 2002 +0000 + + Last bits (hopefully) + +commit 77dd7b55801a3c7c2c6221664204ffdd7b83836a +Author: Ivo Timmermans +Date: Tue Apr 9 15:51:26 2002 +0000 + + More... + +commit 58c1df4028429ed6de4dad9455e3c92928450ffe +Author: Ivo Timmermans +Date: Tue Apr 9 15:48:54 2002 +0000 + + More updates + +commit 86dc60b9808d3aac70eccda80607a91ffd2e5292 +Author: Ivo Timmermans +Date: Tue Apr 9 15:32:14 2002 +0000 + + Ok, I forgot these ;) + +commit af23dfa5efb82b35eb00b94bda56390c9e2aac6f +Author: Ivo Timmermans +Date: Tue Apr 9 15:28:45 2002 +0000 + + Updating HEAD branch #5; Last files from CABAL. + +commit 462ab530e546f5732dfd51134751da6f6910d679 +Author: Ivo Timmermans +Date: Tue Apr 9 15:26:01 2002 +0000 + + Updating HEAD branch #4; Merging CABAL -> HEAD. + +commit e64ef59df44d39c76c00dee22841bbcce7c24e47 +Author: Ivo Timmermans +Date: Tue Apr 9 15:07:27 2002 +0000 + + Updating HEAD branch #3; more obsolete files removed. + +commit db59cbfa47aa152bcfa807754189aa18f28cb569 +Author: Ivo Timmermans +Date: Tue Apr 9 14:58:14 2002 +0000 + + Updating HEAD branch #2; removing debian/ dir. + +commit 50f2afec7e6dab3d809fc1b82820d1069205b69b +Author: Ivo Timmermans +Date: Tue Apr 9 14:54:37 2002 +0000 + + Updating HEAD branch #1; removing obsolete files. + +commit e69d2258032362c85c5936a5c137c70227e59332 +Author: Guus Sliepen +Date: Tue Apr 9 11:44:47 2002 +0000 + + Remarks about 1.0pre7 release. + +commit f2a3fcbdda250e5982c3ef36808568f996f8fff1 +Author: Guus Sliepen +Date: Tue Apr 9 11:43:45 2002 +0000 + + Updated dutch translation. + +commit b1322d244ff24e900f2298b8aa775d825c8ab00b +Author: Guus Sliepen +Date: Tue Apr 9 11:43:29 2002 +0000 + + masklength is better known as prefixlength + +commit 5df8a8cb3f4a0d2290f6677b44bbcaaf27a60bbc +Author: Guus Sliepen +Date: Tue Apr 9 11:42:48 2002 +0000 + + masklength is better known as prefixlength. + +commit 630dd023b990e076fdab890ff90783dc1ac7c13f +Author: Guus Sliepen +Date: Mon Apr 8 13:27:09 2002 +0000 + + Automake forgets about depcomp, remind it. + +commit ad6b1203490699ecc708290b2af1a45e134a5e20 +Author: Guus Sliepen +Date: Fri Apr 5 09:11:38 2002 +0000 + + Fix maskcheck() and maskcmp(). + +commit d8c249008a0b2abd44e652ed70e69b3dbc05b9d8 +Author: Guus Sliepen +Date: Mon Apr 1 21:28:39 2002 +0000 + + check_rsa() is broken, I don't know why, just remove it for now. + +commit 438419734ebee38dc3f7390e5c8ae8e6ca2cb6cf +Author: Guus Sliepen +Date: Mon Apr 1 21:28:05 2002 +0000 + + Don't check_network_activity() if select() is interrupted by a signal. + +commit 3d8a373bb3a788efffc555122b9d0569b96c5944 +Author: Guus Sliepen +Date: Wed Mar 27 19:43:50 2002 +0000 + + Make configure --help output look nicer. + +commit 9a03e7fa3d52ea062b4a3ff88b5d87ee95d24772 +Author: Guus Sliepen +Date: Wed Mar 27 16:26:26 2002 +0000 + + Update with information about the pre6 release. + +commit 33d3bad87d5f3e00e3ed81b75bca2ef21fd6e983 +Author: Guus Sliepen +Date: Wed Mar 27 16:00:49 2002 +0000 + + Update dutch translation. + +commit 0fe3dc38ed0527a5cfda9218114c8ee10422086b +Author: Guus Sliepen +Date: Wed Mar 27 16:00:38 2002 +0000 + + Fix format strings. + +commit 420f46acb0551a290b3263e39347b694286b2fa4 +Author: Guus Sliepen +Date: Wed Mar 27 15:47:06 2002 +0000 + + Remove symlink to device.c when doing a make dist. + +commit a5d8be8b1a9978d58c251d1020bb730bb1dc8ea1 +Author: Guus Sliepen +Date: Wed Mar 27 15:35:07 2002 +0000 + + Recent automake uses $(AMTAR) instead of $(TAR) + +commit c6d2f6c620beae387e8f9fc995ed7c8e8a5bc3dc +Author: Guus Sliepen +Date: Wed Mar 27 15:26:44 2002 +0000 + + Remove cruft. + +commit efd29fde85481e080a676f2ba780a528a90a9925 +Author: Guus Sliepen +Date: Wed Mar 27 15:26:29 2002 +0000 + + Small updates. + +commit 5eba1e1f6feadb3f7efb1261bd65e1e9e40b7f2b +Author: Guus Sliepen +Date: Wed Mar 27 15:01:37 2002 +0000 + + Limit the amount of packets in a queue to 8. + +commit 61cb593e670107ca3041f582c5486c243d5eda9e +Author: Guus Sliepen +Date: Wed Mar 27 15:01:16 2002 +0000 + + Extend list_t with the number of elements in the list. + +commit 0e7136027ce05bfeca977f2f64f3b228ea4fda87 +Author: Guus Sliepen +Date: Wed Mar 27 14:02:36 2002 +0000 + + Merge do_prune() with build_fdset(). Probably fixes the invalid filedescriptor error. + +commit e2238047d39eacc69da5732937021c38171ec7b9 +Author: Guus Sliepen +Date: Tue Mar 26 13:19:56 2002 +0000 + + Small correction. + +commit 7d07df71f9b82afdcf23494867bb8899198a6223 +Author: Guus Sliepen +Date: Tue Mar 26 12:00:38 2002 +0000 + + Fix execute_script(). + +commit 2de5e0eef911b9ff723d562ef9c62d833f3cdc45 +Author: Guus Sliepen +Date: Mon Mar 25 15:51:58 2002 +0000 + + Send REQ_KEY only once until ANS_KEY has arrived. + +commit a0c1696515fabd2183da7d8d83fd68410d2ec834 +Author: Guus Sliepen +Date: Mon Mar 25 15:12:09 2002 +0000 + + Tell a little bit more about security. + +commit 89a2f761a6d8ae4912c2dd2e9178589001487ef5 +Author: Guus Sliepen +Date: Mon Mar 25 15:01:32 2002 +0000 + + Updated documentation. + +commit 33d8747021d57c5827c6a755739756f95c7527c8 +Author: Guus Sliepen +Date: Mon Mar 25 13:54:49 2002 +0000 + + Set myself->status.reachable. + +commit 2749b997df33749f13d05e294db0e1e327e81d12 +Author: Guus Sliepen +Date: Sun Mar 24 17:14:01 2002 +0000 + + Configuration variables were still handled case sensitively. + +commit c73bdd6bc8e213b7e27848b97307228c01570a1d +Author: Guus Sliepen +Date: Sun Mar 24 17:08:38 2002 +0000 + + OpenBSD tun device uses address family number instead of Ethernet type. + +commit 8379c14b7f7a9b1400dd3776fc21dc9ccddd991d +Author: Guus Sliepen +Date: Sun Mar 24 16:50:58 2002 +0000 + + Respect type field. + +commit ad4f5cbc5fbce23893b7d42669ba907f18cc8ff4 +Author: Guus Sliepen +Date: Sun Mar 24 16:40:14 2002 +0000 + + Updated dutch translation. + +commit 4252ae83a43ea81382ce71ba614e2d1655f2e189 +Author: Guus Sliepen +Date: Sun Mar 24 16:36:56 2002 +0000 + + Set $INTERFACE correctly when using ethertap while compiled with tun/tap support. + +commit d699f3079c658e05f928c358d110d1d27849ea71 +Author: Guus Sliepen +Date: Sun Mar 24 16:28:27 2002 +0000 + + Execute hosts/name-up when a node becomes reachable, and hosts/name-down + when it becomes unreachable. + +commit 6ad5dd1a9adb1c1322ceb44d6f0fd160229e72ff +Author: Guus Sliepen +Date: Sun Mar 24 16:22:59 2002 +0000 + + Don't try to execute scripts unless they exist. + +commit 594d5b5d15551bd802c43926c7cb8863b7531654 +Author: Guus Sliepen +Date: Sat Mar 23 20:21:10 2002 +0000 + + Reset retry timeout when receiving the first PONG, not right after receiving the ACK. + +commit cbd8133ab4a2ea8a0c46224a5f1ae79e92819e5f +Author: Guus Sliepen +Date: Sat Mar 23 20:13:56 2002 +0000 + + Don't run graph algorithms if no edge is deleted in terminate_connection(). + +commit 6aee1ad021092d37538e15da22367789a4d4a763 +Author: Guus Sliepen +Date: Sat Mar 23 20:12:29 2002 +0000 + + free() request strings when deleting past requests from the tree. + +commit ccea26e0044ea59a9722385c9d69b1bc703e884f +Author: Guus Sliepen +Date: Sat Mar 23 20:01:05 2002 +0000 + + send_ack() was broken. + +commit 3c5655f59e85d312d11fa04489123e604920f95b +Author: Guus Sliepen +Date: Fri Mar 22 13:31:18 2002 +0000 + + Fix compiler warnings, strictly use long int and %lx for options. + +commit d6b70ed6f8b7ed65f64193fcfcdb6c8f4625e03c +Author: Guus Sliepen +Date: Fri Mar 22 12:41:54 2002 +0000 + + Fix add_edge_h(). + +commit 52e7699273a3009fe4d91e608522401076922785 +Author: Guus Sliepen +Date: Fri Mar 22 11:43:48 2002 +0000 + + - Added support for jumbograms. + - Remove tcpaddress from edges, it is not used at all. + - Last bits of code to prevent looping requests. + +commit 9da5390666ad532825d820b3554da3f39d3bc511 +Author: Guus Sliepen +Date: Thu Mar 21 23:11:53 2002 +0000 + + Put a break on requests that run around in circles. + +commit f48f8f4fedba365ceea30e1133bf1c560e9a522a +Author: Guus Sliepen +Date: Tue Mar 19 22:48:25 2002 +0000 + + Updated SSSP algorithm to automatically detect indirect links (if a node uses + different addresses for connections to other nodes). + +commit 5a88a27742d305be48498a297b90ee3fbdd935bf +Author: Guus Sliepen +Date: Tue Mar 19 00:08:34 2002 +0000 + + Updated dutch translation. + +commit 5c2d74de86d1acb3774a20357ad815d000f8a7f6 +Author: Guus Sliepen +Date: Tue Mar 19 00:08:23 2002 +0000 + + Don't use s6_addr[16|32] anymore. + +commit 9d99a789c38e8a1694537e427e8d4313c948b02b +Author: Guus Sliepen +Date: Tue Mar 19 00:07:09 2002 +0000 + + Cleanup. + +commit 305505f5ec4bb738f175cd897fa409f08d2971a3 +Author: Guus Sliepen +Date: Mon Mar 18 22:47:20 2002 +0000 + + Remember sockaddrs of listening sockets, use appropriate one when sending + UDP packets. + +commit 106fc2b769a635142bf5f9233a2f03e3a0f26b7f +Author: Guus Sliepen +Date: Mon Mar 18 14:39:37 2002 +0000 + + Fix #define s6_addr32. + +commit 813c369a8faca94fc38bc66afafad063fa00f928 +Author: Guus Sliepen +Date: Mon Mar 18 14:19:02 2002 +0000 + + #define s6_addr32, needed for FreeBSD. + +commit b2579385de427c3c03d28520d3a93bd5f9bc9488 +Author: Guus Sliepen +Date: Sun Mar 17 16:08:39 2002 +0000 + + Only unmap IPv6 addresses. + +commit 8b84c44175fedb81ca38107e0067ddea750add00 +Author: Guus Sliepen +Date: Sun Mar 17 15:59:29 2002 +0000 + + Unmap v4mapped sockaddrs. + +commit 07e37f8da03fa315be39623e62d8acba617aa226 +Author: Guus Sliepen +Date: Fri Mar 15 15:50:14 2002 +0000 + + Typo. + +commit e0dee537705cdbd005f6ab1fbef5ac71dc8411c0 +Author: Guus Sliepen +Date: Fri Mar 15 15:40:40 2002 +0000 + + Different way of detecting neighbor solicitation requests. + +commit 0e93f0aa02274481c16fc9f30b795d4f063bd1c3 +Author: Guus Sliepen +Date: Fri Mar 15 15:08:21 2002 +0000 + + Oops, don't forget to actually put the checksum in the response packet. + +commit e1de9ca990ea638c7e297c5335be415e44c250c1 +Author: Guus Sliepen +Date: Fri Mar 15 14:41:57 2002 +0000 + + Neighbor solicitation requests now work (I think). + +commit 4b3aef9e6992ca78f1b17b179a3051d3fec0473d +Author: Guus Sliepen +Date: Tue Mar 12 16:30:15 2002 +0000 + + Revert changes to Kruskal's algo. + +commit f219f156cf13fd30369d7cd4632c406ffd6ff628 +Author: Guus Sliepen +Date: Tue Mar 12 14:25:04 2002 +0000 + + Put #ifdef NEIGHBORSOL around corresponding code. + +commit ecad9e9289162faec7b678be54178d22876b5d90 +Author: Guus Sliepen +Date: Tue Mar 12 14:20:44 2002 +0000 + + Remove silly cache thingy. + +commit d6c2c4f2b7a94ef6a4db0de134d015bc8d21ffb1 +Author: Guus Sliepen +Date: Tue Mar 12 14:19:51 2002 +0000 + + Packet sequence number/authentication warnings only if debug_lvl >= 5. + +commit 2e7db2a6936a77baa0a81eb566674bd76d204951 +Author: Guus Sliepen +Date: Tue Mar 12 13:42:23 2002 +0000 + + Simplified implementation of Kruskal's minimum spanning tree algorithm. + +commit d2e0ed533c8aa3c6ab538d87e004108c631cb0be +Author: Guus Sliepen +Date: Mon Mar 11 13:56:00 2002 +0000 + + New strategy: forward icmp6 neighbor solicitations to intended target. + +commit 46fa10cec7b6bf26773f5e86e7b8118d9075e807 +Author: Guus Sliepen +Date: Mon Mar 11 13:14:53 2002 +0000 + + Try to reply to neighbor solicitation requests. + +commit c2713ba7a5ff12e270d66a5d3188a3640873830e +Author: Guus Sliepen +Date: Mon Mar 11 11:45:12 2002 +0000 + + prune_connections() before build_fdset(). + +commit 4fda4560bbdd41e217ce0e1a90ba98c79e4f3519 +Author: Guus Sliepen +Date: Mon Mar 11 11:23:04 2002 +0000 + + Cleanups, spelling fixes, allow symbol names for signals (-k option), + don't remove pidfile if other tincd is still running. + +commit 5ffeb13d65313d5a191a605690a4f8fdf1604b48 +Author: Guus Sliepen +Date: Sun Mar 10 16:09:15 2002 +0000 + + Don't retry to make outgoing connections when exitting. + +commit 3cbe67a8de1da7bd042474de4d16cb4f7e9822ab +Author: Guus Sliepen +Date: Sun Mar 10 15:40:27 2002 +0000 + + Small fixes to improve portability. + +commit 9de7470bfdabacec5f3769bf5cfa97ef4e481ba0 +Author: Guus Sliepen +Date: Sun Mar 10 14:07:08 2002 +0000 + + Autodetect $MAKE/gmake/make. + +commit 0c34478cc03167208c84f3d6d2ed6e53172b4711 +Author: Guus Sliepen +Date: Sun Mar 10 14:05:35 2002 +0000 + + po/POTFILES and po/Makefile should not be generated by configure. + +commit 024ab44d98883d78cefe2c622cec9831c7f19c13 +Author: Guus Sliepen +Date: Sun Mar 10 14:04:48 2002 +0000 + + Fix forwarding of IPv6 packets. + +commit 0c16add71c6432c882c6d8f538a4b2db0026ec24 +Author: Guus Sliepen +Date: Fri Mar 1 15:14:29 2002 +0000 + + Check if BindToDevice and PriorityInheritance are supported. + +commit 7d5741859e681e6b0d0e32b978da6f309c456729 +Author: Guus Sliepen +Date: Fri Mar 1 14:33:48 2002 +0000 + + Woops. + +commit ab90fa9bd1a653a330be7ef11293000721a0e7b4 +Author: Guus Sliepen +Date: Fri Mar 1 14:25:10 2002 +0000 + + Document and clean up MAC address expiry. + +commit 14979f835df4214a7c2510852f7ffedc9e08c2c0 +Author: Guus Sliepen +Date: Fri Mar 1 14:09:31 2002 +0000 + + - Global time_t now, so that we don't have to call time() too often. + - MAC addresses expire after a time configurable by MACExpire (default 600 + seconds) + +commit 7496ecc45ab6205bcce4e576c23b9afb52004e39 +Author: Guus Sliepen +Date: Fri Mar 1 13:38:15 2002 +0000 + + Updated dutch translation. + +commit 0c879b8eeed3477b0f1cdd2f232e67e38bd9bce6 +Author: Guus Sliepen +Date: Fri Mar 1 13:38:02 2002 +0000 + + Updated documentation. + +commit f93b1334e087dd7af1b87f475b2d398fdd4d56ab +Author: Guus Sliepen +Date: Fri Mar 1 13:18:54 2002 +0000 + + Create/bind TCP and UDP listening sockets in pairs. + +commit c2b738e7b51fbec2b11fbbf030b9a5a36df55fc4 +Author: Guus Sliepen +Date: Fri Mar 1 12:26:56 2002 +0000 + + If "PriorityInheritance = yes" is specified in tinc.conf, the value of the + TOS field of the tunneled packets will be passed on to the UDP packets tinc + sends out. + +commit 80ea653e8d8050878380fbc1446571cbaf578297 +Author: Guus Sliepen +Date: Fri Mar 1 12:25:58 2002 +0000 + + Fix listening sockets. + +commit 7f58ed7685f9fcd5271359a8c896670a835e1f95 +Author: Guus Sliepen +Date: Fri Mar 1 11:18:34 2002 +0000 + + Make BindToInterface work. + +commit 17bc5220c332fdd083fd47fc600010f85171adc7 +Author: Guus Sliepen +Date: Wed Feb 27 22:37:55 2002 +0000 + + Fix send_request() bug. + +commit 50403909b6bf6536924d4693bb1f32c248f17fda +Author: Guus Sliepen +Date: Tue Feb 26 23:26:41 2002 +0000 + + Allow multiple listening sockets. + +commit 2ac7be0d51a112108dc6c2b1c6f46da022f72f40 +Author: Guus Sliepen +Date: Tue Feb 26 22:47:51 2002 +0000 + + Tweaking IPv6 support. + +commit 23fda5688e8a109f8a50511538b14e4fbe4f738c +Author: Guus Sliepen +Date: Wed Feb 20 22:37:38 2002 +0000 + + - Change SA_LEN to SALEN, former one is already defined on some platforms. + - Use SALEN everywhere appropriate. + +commit dbc5b5bb5eb3096ad930aa6b590deaba2a103dfc +Author: Guus Sliepen +Date: Wed Feb 20 22:15:32 2002 +0000 + + - Use gai_strerror() where appropriate + - Clear hints before using them with getaddrinfo() + - Use sa_len on platforms that support them + +commit 28cc9a6488f78c72152251f6fa2ee84d417223e8 +Author: Guus Sliepen +Date: Wed Feb 20 19:31:15 2002 +0000 + + Preserve inpkt->len, needed for broadcasts. + +commit c6d01588312bec7691e72b42cf20c59ffe2749c2 +Author: Guus Sliepen +Date: Wed Feb 20 19:25:09 2002 +0000 + + Protocol now also exchanges cipher/digest/maclength/compression for the + meta connection. + +commit 626d5956d2bb0660ba315fba77da6cec9776fd3b +Author: Guus Sliepen +Date: Wed Feb 20 17:16:15 2002 +0000 + + Cache results of lookup_subnet_...(). + +commit e8e69460a7090aaf6ecda8970d3060695de81b00 +Author: Guus Sliepen +Date: Wed Feb 20 17:15:33 2002 +0000 + + Fix maskcmp() and maskcpy(). + +commit ed509312906625acee4007da6262de3898846888 +Author: Guus Sliepen +Date: Wed Feb 20 16:04:59 2002 +0000 + + Forward packets in router mode. + +commit 8c91fac31570594b6249d632cefe768f33c54b19 +Author: Guus Sliepen +Date: Wed Feb 20 16:04:39 2002 +0000 + + Use AF_UNSPEC for listening sockets if AddressFamily = any. + +commit 76f01453dfa157b0070751b1025e55a1e36ebdca +Author: Guus Sliepen +Date: Wed Feb 20 16:04:07 2002 +0000 + + Fix segfault when receiving HUP signal. + +commit c2b9c06062d36bde859b630b99a08c7b7428e721 +Author: Guus Sliepen +Date: Mon Feb 18 16:25:19 2002 +0000 + + - Non-blocking connect()s. + - Socket handling revamped to use sockaddr_t. + - tinc can now tunnel over IPv6. + - Handle all addresses and subnets in network byte order. + Only convert them when they need to be printed. + - IPv6 subnets bigger than /128 now work. + - Use %s and strerror(errno) instead of %m. + +commit fc674eaae14ed2e07abc0df1285b1bd70e0d27cc +Author: Guus Sliepen +Date: Tue Feb 12 14:42:37 2002 +0000 + + Add check for NetBSD. + +commit 2fb8a62edef7cb0988e44f92c3948cde6f34875e +Author: Guus Sliepen +Date: Tue Feb 12 14:40:12 2002 +0000 + + Added device.c for NetBSD, actually a copy of the OpenBSD one. + +commit f64b41a73b3b432aae17ba990414e0be2f61ce62 +Author: Guus Sliepen +Date: Tue Feb 12 14:36:45 2002 +0000 + + Get rid of sys/signal.h. + +commit dd611fb4f91b9b17c20c458694d2765b22814c5f +Author: Guus Sliepen +Date: Tue Feb 12 14:29:00 2002 +0000 + + Don't use sa_sigaction (which NetBSD doesn't like) at all if we don't use siginfo. + +commit d9a62c6354d1e2ad78ee8c610518ae9f9ab012d1 +Author: Guus Sliepen +Date: Mon Feb 11 15:59:18 2002 +0000 + + Added support for packet compression, thanks to Mark Glines. + Add "Compression = " to the host config files, where level can be + 0 (off), or any integer between 1 (fast) and 9 (best). + +commit 94b171b3051b999e619ae19e1c9c29d356606788 +Author: Guus Sliepen +Date: Mon Feb 11 14:20:46 2002 +0000 + + Small fix. + +commit 1708997bc8ab55122f9de9cc8b81397d3a003ea9 +Author: Guus Sliepen +Date: Mon Feb 11 14:20:21 2002 +0000 + + - If no PrivateKeyFile is specified, /etc/tinc/netname/rsa_key.priv is assumed. + - Check RSA key before using it. + +commit 1c34ba7fb8580949f3bd3a0d804747bbaea28e36 +Author: Guus Sliepen +Date: Mon Feb 11 12:33:01 2002 +0000 + + Sensible defaults for $INTERFACE. + +commit 24cc2a9065a4e962fb05addac47322930099a4b5 +Author: Guus Sliepen +Date: Mon Feb 11 10:16:18 2002 +0000 + + Last bits of the merger. + +commit 5bf4b88666ecafe190e8ed71d6c14c9de8d16e1f +Author: Guus Sliepen +Date: Mon Feb 11 10:05:58 2002 +0000 + + Forgot to merge new files from pre5. + +commit f0aa9641e82fb6e09c1e485366d14dddaa7f7c36 +Author: Guus Sliepen +Date: Sun Feb 10 21:57:54 2002 +0000 + + Merging of the entire pre5 branch. + +commit c2752b961c9262386b940c2c053b9909bee22859 +Author: Ivo Timmermans +Date: Fri Nov 16 22:41:38 2001 +0000 + + Conversion to struct addrinfo is almost complete for this file. + +commit 4f47da5b87ef7da608c7e44026122f3d95deb2eb +Author: Ivo Timmermans +Date: Fri Nov 16 22:40:26 2001 +0000 + + Don't include netutl.h. + +commit a59bbc72317c9cd97243a9cbf49db01ff249eb1e +Author: Ivo Timmermans +Date: Fri Nov 16 22:31:41 2001 +0000 + + Fixed silly typo: "np" instead of "no" + +commit bf664c054fdabc30679367a752a27bb769655e4d +Author: Ivo Timmermans +Date: Fri Nov 16 22:31:15 2001 +0000 + + get_config_subnet needs to be fixed. + +commit 9b2b3747340173590b8f6f5fbdd060b42985f026 +Author: Ivo Timmermans +Date: Fri Nov 16 17:40:50 2001 +0000 + + route_ipv4 and route_ipv6 replaced by route_ip. + +commit a4938b22e7502579ce44cac42410111db11256eb +Author: Ivo Timmermans +Date: Fri Nov 16 17:39:59 2001 +0000 + + Don't include netutl.h. + +commit ccda709f8243949a3c0ffcc6133d8d8fc5125f2e +Author: Ivo Timmermans +Date: Fri Nov 16 17:39:38 2001 +0000 + + lookup_node_udp changed. + +commit 836766d4c5bc47682ab69c57337157c879517670 +Author: Ivo Timmermans +Date: Fri Nov 16 17:38:39 2001 +0000 + + First part of rewriting things to use struct addrinfo. + +commit 2ec5b5f8621d9fb91181ab155084daa1bb2d1a54 +Author: Ivo Timmermans +Date: Fri Nov 16 17:37:08 2001 +0000 + + Added dropin replacements for get*info and helper functions. + +commit aabe59f6305cdd46220e95d8927a1636d4b4819d +Author: Ivo Timmermans +Date: Fri Nov 16 16:16:33 2001 +0000 + + Added HAVE_STRUCT_ADDRINFO + +commit 251f87c842b62cf770129d8a953fb06ef5d0e466 +Author: Ivo Timmermans +Date: Fri Nov 16 15:56:44 2001 +0000 + + (re)added port to struct node_t + +commit 6cf744e4b29cfe3b135b6553851816802ba3d8a8 +Author: Ivo Timmermans +Date: Fri Nov 16 12:22:02 2001 +0000 + + Don't include netutl.h. + +commit a79252af4383b8cd71cf0d13f1ae040d518517bf +Author: Ivo Timmermans +Date: Fri Nov 16 12:21:22 2001 +0000 + + Obsoleted. + +commit 331d9402e892b4baa9cadbbb364073ae10b58d99 +Author: Ivo Timmermans +Date: Fri Nov 16 12:16:28 2001 +0000 + + Don't compile/link netutl.c. + +commit f95e6ca8f6976d7a15f4623e25c85e1c7f82c04b +Author: Ivo Timmermans +Date: Fri Nov 16 12:14:20 2001 +0000 + + get_config_{ip,port} removed. + +commit 31db57bb4a00f5ca3743b89f8bb2fbd39919bf28 +Author: Ivo Timmermans +Date: Fri Nov 16 12:13:34 2001 +0000 + + Changed to use struct addrinfo where needed. + +commit f1b20b3ded5b360e426e094cf79df3bf97f350b4 +Author: Ivo Timmermans +Date: Fri Nov 16 12:10:54 2001 +0000 + + Obsoleted all IP types in favor of struct addrinfo + +commit fb6dc0b0890ebae2471e00e7a3e1d86c1fc3d646 +Author: Ivo Timmermans +Date: Fri Nov 16 12:08:38 2001 +0000 + + Removed definitions of ipv4_t, ipv6_t, port_t + +commit 3ef15f2554d1819d6c7d2573dac6039f2e76b638 +Author: Ivo Timmermans +Date: Fri Nov 16 12:02:17 2001 +0000 + + Changed lookup_connection to use struct addrinfo + +commit 74e1299fb58025f7506c7e2608c353a76f98d8df +Author: Ivo Timmermans +Date: Fri Nov 16 12:01:48 2001 +0000 + + Changed prototype for lookup_connection to use struct addrinfo + +commit 51b72b75f254c956b62be9dfca642145b199415f +Author: Ivo Timmermans +Date: Fri Nov 16 00:23:28 2001 +0000 + + Use struct addrinfo in connection_t to hold all host data such as IP + address and port + +commit 72395f989cb44132d7c756c91b3a6d8ba63517e5 +Author: Ivo Timmermans +Date: Fri Nov 16 00:13:08 2001 +0000 + + Deprecated get_config_ip and get_config_port + +commit 93cd0e33defba46f8e51d9a98a94599ceb0d521c +Author: Ivo Timmermans +Date: Thu Nov 15 23:49:46 2001 +0000 + + Check for struct addrinfo + +commit b16bf68a6dc27b364cb76156a7be0208594f1e94 +Author: Ivo Timmermans +Date: Thu Nov 15 23:28:58 2001 +0000 + + Credit OpenSSH + +commit 18269cfbe831902b97a6171ba0346fd323583e48 +Author: Ivo Timmermans +Date: Thu Nov 15 23:26:27 2001 +0000 + + Check for getnameinfo, gai_strerror, freeaddrinfo + +commit ae11e7c3d71893c5200b12682839538a52df37b8 +Author: Ivo Timmermans +Date: Thu Nov 15 23:05:34 2001 +0000 + + Check for getaddrinfo + +commit e06415e3d9d08cd33c5983a2c49c4101377160c2 +Author: Guus Sliepen +Date: Mon Nov 5 19:09:08 2001 +0000 + + More fixes for Solaris. + +commit 25a804c94ef0dbc4e5582ea6d8459d5f9a3fe06c +Author: Guus Sliepen +Date: Mon Nov 5 19:06:07 2001 +0000 + + Various fixes needed for Solaris. + +commit b2d5002ff1ccd44fbf3a94e4c41909ab6141f3bb +Author: Guus Sliepen +Date: Sun Nov 4 23:48:27 2001 +0000 + + Correctly check if subnet owner exists. + +commit ede6671c1354eeab86936efda32f6cdb3b3fd8d5 +Author: Guus Sliepen +Date: Sun Nov 4 23:29:50 2001 +0000 + + Be liberal in what you accept: allow unknown edges to be deleted. + +commit cf0e133e191cb40954bf5b6ee0a579442fe4b60b +Author: Guus Sliepen +Date: Sat Nov 3 22:53:02 2001 +0000 + + *** empty log message *** + +commit e5047d2835f0828a9c334cc3d928c2322abfefb7 +Author: Guus Sliepen +Date: Sat Nov 3 21:22:02 2001 +0000 + + Several bugfixes. + +commit 8910cbd67e13450e93816ecafa0cc5be5e4c2378 +Author: Guus Sliepen +Date: Sat Nov 3 21:21:04 2001 +0000 + + Use PEM functions as suggested by OpenSSL docs. + +commit 8e74c5bee48f2ef363193044d5309a65e91c70d8 +Author: Guus Sliepen +Date: Wed Oct 31 20:37:54 2001 +0000 + + Some very small fixes + +commit ffb88ff6410f33de92db108bd1e0c3a915368214 +Author: Guus Sliepen +Date: Wed Oct 31 20:22:52 2001 +0000 + + Avoid connecting to another node twice, and check name of outgoing connections. + +commit 6d333ad680465c26953ad4c8ca9140e27da868c5 +Author: Guus Sliepen +Date: Wed Oct 31 20:07:17 2001 +0000 + + Show cfg->variable instead of cfg->value when complaining about wrong type. + +commit 54b756f7dfb71c5622b7738fd449e126da959864 +Author: Guus Sliepen +Date: Wed Oct 31 20:02:06 2001 +0000 + + Don't forget to read public RSA key when making an outgoing connection. + +commit c0a3f67a5d66088aaf526f1461986f9e86d5dd1f +Author: Guus Sliepen +Date: Wed Oct 31 12:50:24 2001 +0000 + + - Small fixes to graph algorithms + - More control over tap device, ability to set interface name to something + other than the netname. + - Export NETNAME, DEVICE and INTERFACE environment variables to scripts. + +commit 2165931c62f0433fd97bd3ac6aefea3627218946 +Author: Guus Sliepen +Date: Tue Oct 30 16:34:32 2001 +0000 + + More updates to protocol handlers and reimplemented terminate_connection(). + +commit 87ad5c97a9a73a65050ad7adce34503f856d8665 +Author: Guus Sliepen +Date: Tue Oct 30 12:59:12 2001 +0000 + + Various fixes, tinc is now somewhat capable of actually working again. + +commit cc9473d8c6467e9eaa82fe8a639d8edba232ee76 +Author: Guus Sliepen +Date: Mon Oct 29 13:14:57 2001 +0000 + + Working version of Kruskal's algorithm. The running time is very bad though. + +commit b6298e2c082035b8238ea08673ced15d0fb7b89a +Author: Guus Sliepen +Date: Sun Oct 28 22:42:49 2001 +0000 + + - More changes needed for Kruskal's algorithm + - Implemented a breadth-first search algorithm as a cheap substitution for a + single-source shortest path algorithm. + +commit 66067cc9c1347fb2de35660d531fdd4be8aede6a +Author: Guus Sliepen +Date: Sun Oct 28 10:16:18 2001 +0000 + + - More s/vertex/edge/g + - Implementation of Kruskal's minimum spanning tree algorithm. + +commit 94497336efc1cc60561575e74d420e9e8e8c657e +Author: Guus Sliepen +Date: Sun Oct 28 08:41:19 2001 +0000 + + What was I thinking? s/vertex/edge/g. + +commit b98d9787fdde54f33dcdb376e1e018cd418aff8d +Author: Guus Sliepen +Date: Sat Oct 27 15:19:13 2001 +0000 + + Various small fixes to make tinc runnable again. + +commit ac066bb057dcb187bf91670793ba5e6ca456e052 +Author: Guus Sliepen +Date: Sat Oct 27 13:13:35 2001 +0000 + + Make sure everything links. + +commit 82e383710980534d38bb9a8ef22f20677cd85861 +Author: Guus Sliepen +Date: Sat Oct 27 12:13:17 2001 +0000 + + Big bad commit: + - Transition to new node/vertex/connection structures + - Use new configuration handling everywhere + - Linux tun/tap device handling cleanup + - Start of IPv6 support in route.c + + It compiles, but it won't link. + +commit 1935c44a1e8ab7c31c836f90215e3c5b5f8dd776 +Author: Guus Sliepen +Date: Sat Oct 13 13:53:07 2001 +0000 + + Support new files (node/vertex/device.[ch]) and OpenBSD. + +commit 26e517dd37e995fe9db518f7ebeff023fc73ff1b +Author: Guus Sliepen +Date: Fri Oct 12 15:52:03 2001 +0000 + + Forgot the tun specific stuff. + +commit ad61c20f42d2bee5cc7976bec4370cf4747b42c3 +Author: Guus Sliepen +Date: Fri Oct 12 15:49:11 2001 +0000 + + Added OpenBSD tun device handling. Untested though. + +commit 0c6321a67f92981d3adbaf4f5c2b9867c7968964 +Author: Guus Sliepen +Date: Fri Oct 12 15:38:35 2001 +0000 + + Forgot to remove some old #ifdef stuff. + +commit 6014c7e6374089bfccea7467c2c7f4b23fefa265 +Author: Guus Sliepen +Date: Fri Oct 12 15:33:21 2001 +0000 + + Solaris tun device handling cleaned up a bit and added. + +commit 623c7ee0308aede8eada552d6ae33710ae24d176 +Author: Guus Sliepen +Date: Fri Oct 12 15:22:59 2001 +0000 + + Added FreeBSD tap device handling. + +commit ec34f25228d7a0007ce6bcb1e97f263868e9129d +Author: Guus Sliepen +Date: Fri Oct 12 15:16:03 2001 +0000 + + - Split tap device stuff out of net.[ch] + - Each OS gets it's own device.c to get rid of evil #ifdefs. + - Cleaned up Linux ethertap and tun/tap handling. + +commit 0bbace18e96cd6fc32dfa23ffd55f73ff96e8c6f +Author: Guus Sliepen +Date: Wed Oct 10 20:35:10 2001 +0000 + + More updates to new node/vertex/connection combo. + +commit ea607d2d9292d3969f9d164b432dc64a33c2dade +Author: Guus Sliepen +Date: Wed Oct 10 20:34:27 2001 +0000 + + Revamp configuration handling: + - Store everything in AVL trees (fast lookup) + - No need for hazahaza anymore + - Parse values when needed + - This simplifies a lot of config variable lookups. + +commit 5904806dc80830d4eddca857a41db2fc25598201 +Author: Guus Sliepen +Date: Wed Oct 10 09:42:29 2001 +0000 + + Removed everything from connection.c that has already been moved to node.c and + vertex.c. + +commit ec0c16b9b63f361b11a757ee1641d562e4811f93 +Author: Guus Sliepen +Date: Wed Oct 10 08:49:47 2001 +0000 + + Further implementation of doc/CONNECTIVITY. connection.[ch] is now split into a + node, vertex and connection part. + +commit 75e1ae3a287642ca4281792c94ecd07332f39c08 +Author: Wessel Dankers +Date: Tue Oct 9 19:41:56 2001 +0000 + + make is not always GNU make. + +commit f22b9417510cca258785f8958c8dfed90e26d81b +Author: Guus Sliepen +Date: Tue Oct 9 19:37:10 2001 +0000 + + Small corrections. + +commit 49a2cd806c73cff1ab6a712a996c7f7d4e1f32c0 +Author: Guus Sliepen +Date: Tue Oct 9 19:30:30 2001 +0000 + + Started implementing doc/CONNECTIVITY. + +commit 5926c82b9a29031a8c619432869d1549b51b62a0 +Author: Guus Sliepen +Date: Mon Oct 8 15:47:30 2001 +0000 + + Updated dutch translation. + +commit fcc3ded75fe9f831aeb8678ee5e3926bf4168906 +Author: Guus Sliepen +Date: Mon Oct 8 15:37:14 2001 +0000 + + Fix bug when dropping an old connection in favour of a new one from the + same host. + +commit 1ef90a87fd9fd53c25a43455ffaac5274a63dc08 +Author: Guus Sliepen +Date: Mon Oct 8 13:37:30 2001 +0000 + + - Use ping timeout mechanism to close connections that don't authenticate + in time. + - Fix potential segmentation fault in check_dead_connections(). + +commit ce9fd32c04adf83cbaf668ee42a29575ba256002 +Author: Guus Sliepen +Date: Mon Oct 8 11:59:08 2001 +0000 + + Fix bug where tinc would crash because of a portscan or a connection from a + tinc daemon with a different version. + +commit 21027b1d5702c331b1ebb262bb149c75be1f24b1 +Author: Guus Sliepen +Date: Mon Oct 8 11:47:55 2001 +0000 + + - Renamed lastbutonehop to prevhop. + - Added connection_t *via to connection_t, this keeps record of where + to send UDP packets to. + +commit 18d1233c40a5705e9123edd6f4c6764a5178003b +Author: Guus Sliepen +Date: Tue Sep 25 13:39:11 2001 +0000 + + Fill in next- and lastbutonehop for myself. + +commit ec100a58b44e412a3d2606e5213af9ec5f30235b +Author: Guus Sliepen +Date: Tue Sep 25 13:35:45 2001 +0000 + + Try next connectto instead of the same over and over. + +commit 4d3de3b6a9b55bc783c649ff33e5415b0c7b5f25 +Author: Guus Sliepen +Date: Mon Sep 24 14:16:29 2001 +0000 + + Show next- and lastbutonehop when dumping connectionlist to syslog. + +commit 24a2c7e51a0b080c4bdb55f697b3f0458ebc3fb1 +Author: Guus Sliepen +Date: Mon Sep 24 14:12:00 2001 +0000 + + Not only keep track of nexthop, but also of lastbutonehop. If destination cl + wants indirectdata, send it to the lastbutonehop instead, unless it too has + requested so, and so on. + +commit 154733927af0b27cdadb83f03b845301ce8bfbfd +Author: Guus Sliepen +Date: Mon Sep 24 13:31:15 2001 +0000 + + - Try old TUN/TAP ioctl() request if the one from if_tun.h fails. + - Be more verbose about the kind of tap device used. + +commit 950c934e0bda28e5952d699d6008ee783d81982b +Author: Ivo Timmermans +Date: Wed Sep 5 18:38:09 2001 +0000 + + Killing tincd with SIGINT causes it to toggle between the current + debug level and level 5. Useful to debug a running tincd. + +commit a54ec980e047d13ecff7f1f337aa2665072febfd +Author: Guus Sliepen +Date: Sat Sep 1 12:46:49 2001 +0000 + + config_t* is a const parameter in get_config_val(). + +commit 68e23b1c9e69b2a218b3be821ad1ba3b3b6a64f2 +Author: Guus Sliepen +Date: Sat Sep 1 12:36:53 2001 +0000 + + Optional signal number for -k option. + +commit 8ed27d40f358581d021319cc26313c9f6ddf9a71 +Author: Guus Sliepen +Date: Sat Sep 1 12:36:06 2001 +0000 + + Revised reconnection mechanism, always try out all ConnectTo lines. + +commit ef1facc60709e9474197aa3fde9d517dfd96dc87 +Author: Guus Sliepen +Date: Sat Sep 1 12:02:39 2001 +0000 + + Remove IndirectData support for now, new implementation will be added + later. + +commit 8b5e4211304aaa5d39bc95f04398bd5ecaa887d8 +Author: Guus Sliepen +Date: Tue Aug 28 20:52:39 2001 +0000 + + Fix signed comparison bug in lookup_subnet_ipv4(). + +commit e1184ad15d6b2e7d58bdcb4489026dd0a35b4e5f +Author: Guus Sliepen +Date: Fri Aug 17 18:14:04 2001 +0000 + + Don't send DEL_HOSTs when !status.meta + +commit 30d22474ccc8da9a5685a90e0b2304ec627475af +Author: Guus Sliepen +Date: Tue Jul 24 20:14:30 2001 +0000 + + Explicitly log which type of tunnel device is used. + +commit 7e86cf91e3399905e19882bcf2d5677d7986aca5 +Author: Guus Sliepen +Date: Tue Jul 24 20:13:42 2001 +0000 + + The val variable in a config_t is never used as a long. + +commit 43923d2b106bfbe9300cc8e364cf098444cd649e +Author: Guus Sliepen +Date: Tue Jul 24 20:04:22 2001 +0000 + + Write public key to rsa_key.pub instead of rsa_key.priv (if not host + configuration file is found). + +commit 44e9d6a2872fac55f7eb701ba576ed9f39a22e08 +Author: Guus Sliepen +Date: Tue Jul 24 20:03:40 2001 +0000 + + Don't use %m in fprintf(). + +commit cbd03caece25d45015a4526b94b04a34ab87b0f2 +Author: Guus Sliepen +Date: Tue Jul 24 08:51:36 2001 +0000 + + More on edges. + +commit 3cd238f4e338f257ff61d58a9979b54344ee462f +Author: Guus Sliepen +Date: Mon Jul 23 22:06:22 2001 +0000 + + Discuss how sending ADD_EDGEs would be better than sending ADD_HOSTs. + +commit 5333cada0dfc4dfc3be728e6c78d8d42dc2ace52 +Author: Guus Sliepen +Date: Sun Jul 22 17:41:52 2001 +0000 + + Written down a possible solution. + +commit 995ab86fce506e9fabcf5a9ead7d43b30f12ab09 +Author: Guus Sliepen +Date: Sun Jul 22 15:25:13 2001 +0000 + + Correctie. + +commit d7b4de0e73baf664964f6daaf63526606b6a890b +Author: Guus Sliepen +Date: Sun Jul 22 14:58:18 2001 +0000 + + Small update. + +commit 71b9041f484128219f81cbf4f22a4e11388f879d +Author: Guus Sliepen +Date: Sun Jul 22 14:46:11 2001 +0000 + + Described problem in more detail. + +commit c1a98cd37ea20f6020487b2a5586e6de432398e7 +Author: Guus Sliepen +Date: Sun Jul 22 14:04:38 2001 +0000 + + Started writing a document about how daemons connect to each other. + +commit fcbe215d64d7e2f3b159fff6422d750417877ac4 +Author: Guus Sliepen +Date: Sat Jul 21 20:21:25 2001 +0000 + + Woohoo! tinc now compiles, runs and actually *works* on Solaris! + Tested on a SparcStation 20MP running Solaris 7. (Thanks, jiggel!) + +commit 533ee1206fb6433a1f0e616db999b3655addfaf2 +Author: Guus Sliepen +Date: Sat Jul 21 15:46:34 2001 +0000 + + Always close all sockets in terminate_connection(). + +commit acb853205d6d582d919c59879393b301ad4f4fde +Author: Guus Sliepen +Date: Sat Jul 21 15:34:18 2001 +0000 + + Updated terminate_connection() so you can choose if DEL_HOSTs should be + sent or not. + +commit 12f6b80429bc05a828051d72cc46f173e4657180 +Author: Guus Sliepen +Date: Fri Jul 20 20:25:10 2001 +0000 + + Added purge_tree for connection_t's which are no longer in the connection, + active or id trees, but which may still be referenced. This tree is flushed + when it is safe, this replaces purge_connection_tree(). + + Also lots of bugfixes related to the new trees. + +commit 37ed4265fa73d4c06c74362514d78c92029b2f05 +Author: Guus Sliepen +Date: Fri Jul 20 13:54:19 2001 +0000 + + Remove all unnecessary status.meta and status.active checks. + +commit 5e2ded68bfc7b3a1bfa600c1ce46144eb50e57a2 +Author: Guus Sliepen +Date: Thu Jul 19 12:29:40 2001 +0000 + + Correctly use the active_tree. + +commit 319e0cb48eb00565a11c85b901f54141f8160334 +Author: Guus Sliepen +Date: Sun Jul 15 18:07:31 2001 +0000 + + Split connection list into two lists: + - one list to handle all incoming/outgoing TCP connections + - another list to handle all UDP connections + + This will prevent race conditions. + +commit b3074590b184c141419cf4926820dc0d78380535 +Author: Guus Sliepen +Date: Sun Jul 15 14:21:12 2001 +0000 + + Correct inclusion of standard if_tun.h header file. + +commit 5dc4ade0b9c127a3c144d9c59894bf13527fe060 +Author: Guus Sliepen +Date: Wed Jul 4 08:43:32 2001 +0000 + + Don't load table of verbose OpenSSL errormessages. + +commit 1e2bdc2b6d28c76c63fc9fd36169b90fa0994388 +Author: Guus Sliepen +Date: Wed Jul 4 08:41:36 2001 +0000 + + - Always use instead of just + - Check if RAND_pseudo_bytes() exists, otherwise just use RAND_bytes() + +commit 6bd93e4c064578b545cb6dcaa28fffb229c929ff +Author: Guus Sliepen +Date: Sun Jul 1 21:42:13 2001 +0000 + + Check for all potential duplicate entries in the id tree. + +commit 9645cabc8e8364ed4df187fab8065b0991afa6af +Author: Guus Sliepen +Date: Sun Jul 1 09:21:14 2001 +0000 + + Fix compiler warning. + +commit 6365d0627b9b1e9a31371ec891db0d2cfb4d6ed4 +Author: Guus Sliepen +Date: Sun Jul 1 09:21:01 2001 +0000 + + Fix printf format bug. + +commit 33d6de0cd5c05cbf37211924a45e4231fec3a416 +Author: Guus Sliepen +Date: Sun Jul 1 09:06:17 2001 +0000 + + More items marked as done. + +commit a111593a082ff1df26f54168ab00f83ab3a1ab49 +Author: Guus Sliepen +Date: Fri Jun 29 15:38:40 2001 +0000 + + Dutch translation updated. + +commit 748dabdbe93f7439ed7eddf491a556279250e7ac +Author: Guus Sliepen +Date: Fri Jun 29 15:33:18 2001 +0000 + + Update of RedHat build scripts. + +commit 343c8fb6388ffd4f5c41cebd666aa8a045b20bdd +Author: Guus Sliepen +Date: Fri Jun 29 15:32:26 2001 +0000 + + It appears that autogen.sh doesn't like es.po if it isn't mentioned in + the makefile/configure scripts. + +commit 9391efe4e88077723840a7c085388ba2765ca17c +Author: Guus Sliepen +Date: Fri Jun 29 14:15:46 2001 +0000 + + Check for dlopen in standard libraries first (needed for DEC OSF). + +commit c9591bd1de1abcfe10459bd8c8cdd81a7b441ec0 +Author: Guus Sliepen +Date: Fri Jun 29 13:09:55 2001 +0000 + + Fix gcc 3.0 warnings. + +commit 402b85c48284a06fbfc56aca102b33be3a4260b0 +Author: Guus Sliepen +Date: Fri Jun 29 13:09:32 2001 +0000 + + Log error if two hosts connect with same IP/port tuple. + +commit 0d3bd912acdb00dc0a8015e337f981c942aa21bc +Author: Guus Sliepen +Date: Fri Jun 29 11:09:13 2001 +0000 + + Also remove po/Makefile.in.in, which is generated by autogen.sh. + +commit 67c16924c10b25d37957843a69d993b934dd1776 +Author: Guus Sliepen +Date: Fri Jun 29 11:03:27 2001 +0000 + + es.po revived. + +commit 5d3450357482176ce92ed4832ec944519d197744 +Author: Guus Sliepen +Date: Fri Jun 29 10:30:18 2001 +0000 + + Execute tinc-down BEFORE tap device is closed. This is a. more symmetric + (tinc-up is started after tap device is opened) and b. is needed for + tun/tap device, where the interface does not exist anymore after the + device file is closed. + +commit 6666acd0012c82c0bb4d1abae87332cec3dda77a +Author: Guus Sliepen +Date: Fri Jun 29 10:27:57 2001 +0000 + + Don't build Spanish translation. + +commit 77f635e871060f63c3e62fcf879d184326c690a4 +Author: Guus Sliepen +Date: Fri Jun 29 10:27:33 2001 +0000 + + ABOUT-NLS is created by autogen.sh. + +commit 333be8fbb8790237577761e580126a6d757a46e4 +Author: Guus Sliepen +Date: Fri Jun 29 10:23:46 2001 +0000 + + Spanish translation removed. Nobody maintains it, and it is severely + outdated. + +commit 3503ba995012f658f087a196dad0cb9fd45eff3b +Author: Ivo Timmermans +Date: Tue Jun 26 22:00:57 2001 +0000 + + Small fix to make it compile again + +commit 7fc068fe5421f7ec556b0b7db6f814e18b3326a4 +Author: Guus Sliepen +Date: Thu Jun 21 18:28:52 2001 +0000 + + Reinstated search for if_tun.h in kernel source tree, because apparently + /usr/include/linux does not always have the same contents as the include + files from the currently running kernel. + +commit 9e96840da810437c45af1c4b139578f7d74d65db +Author: Guus Sliepen +Date: Thu Jun 21 16:37:47 2001 +0000 + + Remove #warnings I used for debugging stuff. + +commit b1e97ece9c495ac67e54b8c2675b1eacc645eb1c +Author: Guus Sliepen +Date: Thu Jun 21 16:37:05 2001 +0000 + + Check for and add -ldl. + +commit 04ec0b82ab9c6a2662300a9257a5aff1c4dd56e7 +Author: Guus Sliepen +Date: Thu Jun 21 16:16:32 2001 +0000 + + - Solaris compile fixes + - Set mymac to broadcast MAC so that ifconfig hw ether <...> is really not + needed anymore. + - Forwarding of indirect packets when in switch mode (because the kernel + will not do it for us then). + +commit 353a9230bb70b70028f2dc6c651a28e30b13dc63 +Author: Ivo Timmermans +Date: Wed Jun 20 21:32:40 2001 +0000 + + Don't include the debian/ dir in a release + +commit 9a0a50cd3cf2570b39e00edf1a92123acbac41b4 +Author: Guus Sliepen +Date: Sat Jun 9 10:00:34 2001 +0000 + + Woops - big bug in send_key_changed fixed. + +commit ba918dce287788aaf6a90b3c7a9f349b197068d6 +Author: Guus Sliepen +Date: Fri Jun 8 18:02:10 2001 +0000 + + Only reset seconds_till_retry when we activate the outgoing connection. + +commit c5c02a0861bf540e07fe64704cb97aae29c4cacf +Author: Guus Sliepen +Date: Thu Jun 7 07:51:04 2001 +0000 + + Changed drastically because it didn't work correctly: + - Don't cache the --with-openssl-* option arguments + - Only search for openssl/*.h, the openssl include files include other + files only from an openssl/ directory too + - Set CPPFLAGS before AC_CHECK_HEADERS + +commit 053e78654097cf353aa59b4d34e608726edd5dad +Author: Guus Sliepen +Date: Thu Jun 7 07:48:11 2001 +0000 + + Save configure cache more often. + +commit 96ef7becdd71fc63c3489e3696117c1f137eade5 +Author: Guus Sliepen +Date: Wed Jun 6 19:12:38 2001 +0000 + + Fixes to make switching work between hosts that have no meta-connection. + +commit ce6c8e6d089abac81520c517185c6ef81b09f051 +Author: Guus Sliepen +Date: Wed Jun 6 19:11:16 2001 +0000 + + Log and warn about duplicate subnet_add()'s for the same subnet. + +commit 9cd9b0392388e24ade19a43206221081b61806e7 +Author: Guus Sliepen +Date: Tue Jun 5 19:45:47 2001 +0000 + + Add missing? counting of total_socket_in. + +commit 7bd7f5b4363f222340e5c058c243d31c576fba88 +Author: Guus Sliepen +Date: Tue Jun 5 19:39:54 2001 +0000 + + You can now put an option "Mode" in tinc.conf, and choose from: + + - Mode = router (default, work like tinc has always worked) + - Mode = switch (work like a switch) + - Mode = hub (work like a hub, broadcasting everything) + +commit edd6734faa37d043b8a2cc75b125db3b1c2130fa +Author: Guus Sliepen +Date: Tue Jun 5 18:07:14 2001 +0000 + + Fix bug where lookup_subnet_ipv4() could go into an infinite loop. + +commit fa376fbd4e5151ae43e86441a1e99073eeaf46a5 +Author: Guus Sliepen +Date: Tue Jun 5 16:31:59 2001 +0000 + + - This oneliner removes the need for ifconfig tap? hw ether fe:fd:0:0:0:0 + +commit 7a736d47b264065371f35cd9da64485d798cbc80 +Author: Guus Sliepen +Date: Tue Jun 5 16:15:48 2001 +0000 + + Updated dutch translation. + +commit 92924e8482f000eb33130ce9feadc08450ff349d +Author: Guus Sliepen +Date: Tue Jun 5 16:13:41 2001 +0000 + + Changed some stuff to allow correct generation of po/Makefile after a + make cvs-clean. + +commit 4f9dad0972ac0f665a1b6050b059bd52f93e6221 +Author: Guus Sliepen +Date: Tue Jun 5 16:09:55 2001 +0000 + + - tinc can now act as a switch or a hub too (as opposed to a router only) + - cleaner initialisation of "UNKNOWN" and "MYSELF" names + +commit 428482d86f860d1fb09de722c1b6576ec2eef1ce +Author: Guus Sliepen +Date: Mon Jun 4 11:14:35 2001 +0000 + + Added proxy-arp support. No more ifconfig -arp needed. Works like a charm + under FreeBSD now :). + +commit 0a3c8cefd4a154948799baaaa246cf0eba050eff +Author: Guus Sliepen +Date: Fri Jun 1 08:02:09 2001 +0000 + + Fix subnet_lookup() for overlapping subnets. Needs rethinking. + +commit 7db1b999c82611d6c68a5d79b4754db19669d5c6 +Author: Guus Sliepen +Date: Mon May 28 08:56:57 2001 +0000 + + Make sure Solaris is happy too. + +commit 65247c063b36a76dd68156fe17b017c7460d982f +Author: Guus Sliepen +Date: Mon May 28 08:21:43 2001 +0000 + + Small fixes to allow correct compilation under FreeBSD (tested with 4.3) + +commit 4e959ee40542733e647c36831c1fc87ed8098233 +Author: Ivo Timmermans +Date: Sat May 26 09:35:28 2001 +0000 + + Don't distribute autogen.sh in a release + +commit 514f8f579d5c0608aee8ca4a43d7414ecee5c11c +Author: Ivo Timmermans +Date: Sat May 26 09:35:00 2001 +0000 + + Changed version number to 1.0-cvs + +commit 20c2b62b1802390c0f5a1757641a0a1cea8103a8 +Author: Ivo Timmermans +Date: Sat May 26 09:34:11 2001 +0000 + + New make target: `make release' + +commit 8d307c2fbf2c20eb53909f74c81e03db838fb55e +Author: Guus Sliepen +Date: Fri May 25 18:57:37 2001 +0000 + + Fix sample configuration to show keys in PEM format and correct tapdevice. + +commit e12d41f39d8dd1cd30058d08effd2e5b66cdd4fd +Author: Guus Sliepen +Date: Fri May 25 13:24:34 2001 +0000 + + Documents are merged. Now we only need to check the ports and the TCPonly + and IndirectData options. + +commit f0c64a3dac3b0469ea05fa5d44a1e7bdbfa64900 +Author: Guus Sliepen +Date: Fri May 25 12:45:37 2001 +0000 + + Merged PROTOCOL, NETWORK and SECURITY2 with the texinfo manual. + +commit fcf869cd4250a240ea8d443f70fa373e4fbacf07 +Author: Guus Sliepen +Date: Fri May 25 11:54:28 2001 +0000 + + TCPonly now works (in a relatively clean way too). + +commit a5e2ae6b2b2e1629cf05bb2a57df75f13c0f120a +Author: Guus Sliepen +Date: Fri May 25 10:08:11 2001 +0000 + + With recent kernels the tun device file is located in /dev/net. + +commit 6e09c2a99c8ac3c1391f4f2eee16d6c235c10e90 +Author: Guus Sliepen +Date: Fri May 25 10:06:13 2001 +0000 + + Small corrections to the manuals. + +commit 4dee76522e177dcb4af5d6d844a5f3b74070e4b7 +Author: Guus Sliepen +Date: Fri May 25 08:36:11 2001 +0000 + + Small fixes: + + - Fix compiler warnings (one was a real (but harmless) bug) + - Don't send PING packets if there is UDP traffic + - Correctly terminate strings containing salt for PING/PONG packets + +commit bfc5d6014e3c1563f7b6a2f10698e9ba23ba3e96 +Author: Guus Sliepen +Date: Thu May 24 21:52:26 2001 +0000 + + Only send key_changed if it was previously requested. + +commit 1a248fd5bd5aa24fa0f6a2c395f05dd569f0898d +Author: Guus Sliepen +Date: Thu May 24 21:32:30 2001 +0000 + + All features for 1.0 are implemented now, we just have to check the + FreeBSD and Solaris ports and merge some docs. + +commit 58893f0875369aafff8481825af271683c975a2a +Author: Guus Sliepen +Date: Thu May 24 21:30:36 2001 +0000 + + Since this is incompatible with some earlier versions, PROT_CURRENT is + increased. + +commit d1b597758eab68bb80d97855f25cb6dda55eeb0b +Author: Guus Sliepen +Date: Thu May 24 21:29:09 2001 +0000 + + Add randomness to PING/PONG packets to prevent crypto attacks on quiet + tunnels. + +commit 4493b0650bd487990ca9d2802496ad0ee7c06247 +Author: Guus Sliepen +Date: Thu May 24 20:40:13 2001 +0000 + + Changed URL from kernelnotes.org to linuxdoc.org. + +commit 3360c6270bcc19a8b3d81da185266fc33b5c5421 +Author: Guus Sliepen +Date: Thu May 24 20:24:12 2001 +0000 + + More revisions to the documentation: + + - Removed cruft + - Reordered some sections to make it more logical for the beginner + - Added small examples and hints about configuration files + +commit 6f7f8659a2048fd6d616f4286ccdd0e661084493 +Author: Guus Sliepen +Date: Sat May 19 15:50:51 2001 +0000 + + - Make sure correct information is supplied for both old kernels (with + ethertap) and for new kernels (with TUN/TAP driver). + - Revised example configuration and made it conform to latest (CVS) version of + tinc. + +commit e4f3d93ec62871d1ae11b460627aef0da1b23cd2 +Author: Guus Sliepen +Date: Mon May 7 19:08:46 2001 +0000 + + - s/ip_t/ipv4_t/g + - Add "salt" to the beginning of UDP packets. Replaces length field which + is not useful anyway. + +commit a26081467c197cc6b26a0c36c4508361b242fc85 +Author: Guus Sliepen +Date: Fri May 4 18:45:02 2001 +0000 + + Correctly cycle through ConnectTo variables. + +commit 80b4a851a6b62cbbf503c2225f93305966f058c0 +Author: Guus Sliepen +Date: Fri Apr 13 10:30:04 2001 +0000 + + Depend on new ssl package and install alias for universal TUN/TAP module. + +commit 156ec676525ed789364b7a77926dd0717d0cf5d7 +Author: Guus Sliepen +Date: Tue Mar 13 21:33:31 2001 +0000 + + Check indirectdata option before forwarding certain requests. + +commit c426e981eeaed3fa4801221720ee8f74d40e9223 +Author: Guus Sliepen +Date: Tue Mar 13 21:32:24 2001 +0000 + + Ignore alarm signals if we do not need to respond to them. + +commit b413257e10ae0645da43583dd8f84a1f74df5bd7 +Author: Guus Sliepen +Date: Tue Mar 13 09:55:14 2001 +0000 + + Fixed bug in setup_signals() that would make tinc die when unexpected + signals were caught. + +commit f1a082823c48d00171b814f7e14e07e6dd4632fb +Author: Guus Sliepen +Date: Mon Mar 12 23:58:19 2001 +0000 + + Fixed a race condition triggered by receive_meta() and the new + authentication scheme. + +commit f4887b981f109fc4264f50170b2d12c4033bf5e9 +Author: Guus Sliepen +Date: Sun Mar 4 14:00:24 2001 +0000 + + Added a description of what is going on in net.c and route.c, and how + packets flow through tinc. + +commit 9d5c9bf6ba74e4e8bbd12b97fdda6c665155fec6 +Author: Guus Sliepen +Date: Sun Mar 4 13:59:53 2001 +0000 + + Updated translation. + +commit 34f9e6cf2d6d2b81eb63f9f28963b447a2157740 +Author: Guus Sliepen +Date: Sun Mar 4 13:59:32 2001 +0000 + + - route.c is now used to determine destination + - flags are removed, since they were not used at all. Use options instead. + - indirectdata works now, tcponly almost... + - made functions that don't return useful information void + +commit d2a54597e029f9d4f7bd29837be1be33909d78b1 +Author: Guus Sliepen +Date: Fri Mar 2 11:25:56 2001 +0000 + + Added explaination of our key exchange using RSA encryption. + +commit 125c4978812cffa5154ce5378a276f43f78417d8 +Author: Guus Sliepen +Date: Thu Mar 1 21:32:04 2001 +0000 + + Various small fixes. + +commit 099cc867c1a0831add7f1b4046f22ad6bfa5a1ef +Author: Guus Sliepen +Date: Tue Feb 27 16:50:29 2001 +0000 + + Removed compiler warning. + +commit 4fa12eb85d72f039df5004abc201f01f5573c2e4 +Author: Guus Sliepen +Date: Tue Feb 27 16:37:31 2001 +0000 + + Removed lots of compiler warnings. + +commit 173d606514d82fc5ae7895a178238d0abcaf6606 +Author: Guus Sliepen +Date: Tue Feb 27 16:17:04 2001 +0000 + + - Fixed Interface option (untested) + - Removed error handling for non-critical socket options + - Added TCP_NODELAY and IPTOS_LOWDELAY options for meta sockets. + +commit fb4ba9b265666d9949b03209a3ff52ff1263226b +Author: Ivo Timmermans +Date: Tue Feb 27 16:15:14 2001 +0000 + + Authentication done + +commit 24fa68585923d2b52718390f3f38d1aaacef12f0 +Author: Guus Sliepen +Date: Tue Feb 27 15:33:39 2001 +0000 + + Don't forget to reconnect if outgoing connection fails during + authentication. + +commit 34b7a876c3583f7a34585cff6a694bc9e35cdc87 +Author: Guus Sliepen +Date: Mon Feb 26 11:37:20 2001 +0000 + + - Make sure METAKEY is smaller than the modulus of the RSA key + - Get symmetric key from the least significant bytes of the RSA message + +commit 4b0ad4d97abd3643c44f45841d52f3000a34ba60 +Author: Guus Sliepen +Date: Sun Feb 25 20:17:46 2001 +0000 + + Added process.c to the translated files. + +commit 82455be966027a087a2ac23e3464594c81d7b111 +Author: Guus Sliepen +Date: Sun Feb 25 19:09:45 2001 +0000 + + Implemented new authentication scheme from doc/SECURITY2. + +commit 54881faf6fdbf04fb5ee56b7809439fbc50c65cb +Author: Guus Sliepen +Date: Sun Feb 25 16:34:19 2001 +0000 + + Encrypt network packets in CBC mode instead of CFB mode. + (This breaks compatibility with all previous versions!) + +commit 9de5787574b21e94c80ddc60def2b3e514aff755 +Author: Guus Sliepen +Date: Sun Feb 25 16:04:00 2001 +0000 + + Copy packets before putting them in the queue. + +commit 38adc479a44b64afcb220cd757f77ab105cb9bcd +Author: Guus Sliepen +Date: Sun Feb 25 15:34:50 2001 +0000 + + Free node->data and node, not node->data twice. + +commit e250d64300cea2a83059866e7cbabcb33684160e +Author: Guus Sliepen +Date: Sun Feb 25 14:51:42 2001 +0000 + + Add missing \n. + +commit 153fc35e57c0104aa4ea9103bcdbca3665e4934c +Author: Guus Sliepen +Date: Sun Feb 25 11:09:29 2001 +0000 + + Corrected check for errors after read() calls. + +commit 0b0c2a372ff5d11f73af172e07a93b2656374a42 +Author: Wessel Dankers +Date: Tue Feb 20 21:53:18 2001 +0000 + + Important bugfix in avl_insert_before() and avl_insert_after() + +commit 11f8465dd9a4f81b43a31f1cb6a7fc2d76bb7838 +Author: Ivo Timmermans +Date: Sun Feb 18 02:13:26 2001 +0000 + + tinc_TUNTAP now substitutes the values outside the AC_CACHE_CHECK + block. configure should now correctly set HAVE_TUNTAP. + +commit bb0870498037565209e24fbb2ffa07b815350a0b +Author: Guus Sliepen +Date: Tue Feb 13 09:54:29 2001 +0000 + + Added description of the proposed new authentication scheme. + +commit cebb6efeb0f39bf05ca7836b7a393c8385b49335 +Author: Ivo Timmermans +Date: Sun Feb 11 11:55:28 2001 +0000 + + More files to ignore in CVS + +commit 603781831f251d2e8111e8282d8e624b8e40b175 +Author: Guus Sliepen +Date: Sun Feb 11 11:50:09 2001 +0000 + + - Updated CVS_CREATED to remove intl/ directory and some other + autogenerated files. + - Checked if all INCLUDES/LIBS/etc directives inherit the global variables. + +commit 88dfdc9dbac3f5d0aa70b77509b4a87513433987 +Author: Guus Sliepen +Date: Sun Feb 11 11:46:14 2001 +0000 + + Ignore file for src/ + +commit ef0fc4f687fc25e97551e589941d6a2a2d8ade42 +Author: Guus Sliepen +Date: Sun Feb 11 11:44:32 2001 +0000 + + Added .cvsignore files to get rid of warnings and prevent autogenerated + files from being added accidentaly. + +commit f1cb3d8fa5f69840f353ca5a62f363dad47eb46f +Author: Guus Sliepen +Date: Tue Feb 6 10:42:27 2001 +0000 + + Removed another local definition of the variable "errno" + +commit 0f715887c617723e4b450083f8b77641f8b62e80 +Author: Guus Sliepen +Date: Tue Feb 6 10:13:44 2001 +0000 + + Updated dutch translation. + +commit 4bc394a3e29f2f90434bbbfc9f23d5587398471b +Author: Guus Sliepen +Date: Tue Feb 6 10:13:22 2001 +0000 + + Fix memory leak in avl_insert() if item was already inserted. + +commit f777c1807d663eaef3e36c395094451214886898 +Author: Guus Sliepen +Date: Tue Feb 6 10:12:51 2001 +0000 + + FreeBSD compile fixes (thanks to XeF4) + +commit bb4457d6caf6e424aeaf9b09222d4e62cab939da +Author: Ivo Timmermans +Date: Thu Jan 18 13:02:34 2001 +0000 + + Unpack sample-config.tar.gz when installing + +commit fe61e1ffef186aa509a50be3be83955fe1cbb514 +Author: Ivo Timmermans +Date: Thu Jan 18 13:01:42 2001 +0000 + + Distribute the sample config as a .tar.gz + +commit a73ec9caa45bda7738376a610030c8ba9b934445 +Author: Ivo Timmermans +Date: Thu Jan 18 13:00:57 2001 +0000 + + Fixed some errors + +commit b33c5f6640e63cc4cd35285367bcb2827b732229 +Author: Ivo Timmermans +Date: Wed Jan 17 16:24:24 2001 +0000 + + First try to create a graphical frontend for tinc configuration + +commit 6bc77a7710adcbc33331c45e1b6adf7089a42075 +Author: Ivo Timmermans +Date: Wed Jan 17 01:48:44 2001 +0000 + + Get the PO files up to date with the current source + +commit 664f7e5c0b9056d88e2b63b3626ea33c4894387b +Author: Ivo Timmermans +Date: Wed Jan 17 01:47:39 2001 +0000 + + Get the Debian changelog up to date + +commit 1d898e00a964ef922617683a1d29ff24e56ed8ff +Author: Ivo Timmermans +Date: Wed Jan 17 01:40:46 2001 +0000 + + Merged documentation with various updates I had lying around + +commit 457c6fa7b63a7f2971314d8d63af71c880ec6f53 +Author: Ivo Timmermans +Date: Wed Jan 17 01:34:08 2001 +0000 + + Second draft of the release notes + +commit b236ddb1df16f8eb025d485b75153c4f25f4afc6 +Author: Ivo Timmermans +Date: Wed Jan 17 01:31:56 2001 +0000 + + Change version to 1.0pre4 + +commit a893b05cb017c04871c2faf4099f104985f4ad75 +Author: Ivo Timmermans +Date: Wed Jan 17 01:30:32 2001 +0000 + + Set Architecture to `any' + +commit 54e19d34663cfe4af05e9e1dac94f76e39858f18 +Author: Ivo Timmermans +Date: Wed Jan 17 01:30:05 2001 +0000 + + Fix error reporting of read_config + +commit a56df1e06be3f47a775919e564c147687e961b5d +Author: Guus Sliepen +Date: Sat Jan 13 16:36:23 2001 +0000 + + - Allow ASN1 style keys to be in the config files. + Note: tinc ignores private key in the main config file, tinc.conf, + because it should really be in a separate file. + - When generating new keys, check if name is known and by default append + the public key to the host configuration file (otherwise rsa_key.pub). + +commit 44c85ab07ed07165b80140da4e2910ca51fa8887 +Author: Guus Sliepen +Date: Sat Jan 13 14:56:46 2001 +0000 + + - Copy entire sample-config directory to /etc/tinc/example upon installing. + +commit b195e8815f0abb2c5527119221886b524d719019 +Author: Guus Sliepen +Date: Sat Jan 13 14:38:18 2001 +0000 + + Added sample configuration directory. + +commit d646f4e094b63720f97bfd37bb3489bd9d6231a0 +Author: Guus Sliepen +Date: Thu Jan 11 11:19:08 2001 +0000 + + - Only send out DEL_HOSTs for hosts with a meta connection + +commit c8beaf35ee923c209ee23bedcb3dc892d2c2dae3 +Author: Guus Sliepen +Date: Mon Jan 8 21:32:30 2001 +0000 + + - Cleaned up subnet_t + +commit e5e1c20a99b0d72792f28e9a075a9f4a7e8b2c95 +Author: Guus Sliepen +Date: Mon Jan 8 21:32:00 2001 +0000 + + - Sign was wrong in search_closest_smaller/greater + +commit 11f3e9d138daf6b726631cc124b14d66dfa4d1f7 +Author: Guus Sliepen +Date: Mon Jan 8 20:35:30 2001 +0000 + + - Squashed another nasty bug. + +commit 447a43d63960802a7a29201c512246be11eb9c94 +Author: Guus Sliepen +Date: Sun Jan 7 20:19:35 2001 +0000 + + - Added indirectdata and tcponly functionality. + +commit 7cd2baedc6027ef6a5b941342bc6d3931d7220ba +Author: Guus Sliepen +Date: Sun Jan 7 20:19:08 2001 +0000 + + - Fixed IPv6 subnet lookup routine. + +commit d3f889c8076dff9c00ebfe1459cb36425f8da41d +Author: Guus Sliepen +Date: Sun Jan 7 17:09:07 2001 +0000 + + - It's 2001, all copyright notices are updated. + +commit 96b6f958bc733c3963dd164caacd42513be47a86 +Author: Guus Sliepen +Date: Sun Jan 7 17:08:03 2001 +0000 + + - Description of protocol and authentication updated. + +commit 7109526c6789c73a18bbe6b228ca35f0374c8d36 +Author: Guus Sliepen +Date: Sun Jan 7 15:27:30 2001 +0000 + + - Added header file for route.c. The routing routines in it are not used + yet, but have a look at the source for the ideas behind it. + +commit 07a08f5539f441e66946d1db1711dc584f8621c4 +Author: Guus Sliepen +Date: Sun Jan 7 15:25:49 2001 +0000 + + - Reinstated a queue for outgoing packets. + +commit 049ff67817e0db5afbba30930531d8ea3f7f2d18 +Author: Guus Sliepen +Date: Sun Jan 7 15:24:52 2001 +0000 + + - Changed list routines to give it the same look'n'feel as the rbl and + avl tree library. + +commit 8b4bc5b3a7e31c198c001610c99c2993e1612376 +Author: Guus Sliepen +Date: Sat Jan 6 20:43:03 2001 +0000 + + - Typo. + +commit 3d7289cf743f89cab4c71815482a4837a21f6703 +Author: Guus Sliepen +Date: Sat Jan 6 20:02:21 2001 +0000 + + - Updated texinfo manual. + +commit 0d99ae59bd7c640d396ce978045f0911567fb9bf +Author: Guus Sliepen +Date: Sat Jan 6 18:44:55 2001 +0000 + + - Updated manual pages. + +commit 90bf1b21fa7e94d73719da0593e7c0356d05e18f +Author: Guus Sliepen +Date: Sat Jan 6 18:21:17 2001 +0000 + + - Changed license of AVL tree library to GPL. + +commit f7bb205022e02c02c02733cd43544c231373115d +Author: Guus Sliepen +Date: Sat Jan 6 18:03:41 2001 +0000 + + - Check and follow symlinks in is_safe_path + - By default write keys to tinc config directory + - Small fix in protocol.c + +commit 1398edec37336853bfca6ea3dcca7c402f102ea2 +Author: Guus Sliepen +Date: Sat Jan 6 16:51:14 2001 +0000 + + - Updated dutch translation. + +commit e924096f62655d711cd2d114a8d1ef0fecbb593b +Author: Guus Sliepen +Date: Fri Jan 5 23:53:53 2001 +0000 + + - Let user choose whether keys are in the config files or separate + - Use AVL trees instead of RBL trees + - Fixed a lot of annoying subtle bugs! Thanks to gdb... + +commit 052fbc0bdf36e0dbe2a0867ce770d426c9a44841 +Author: Guus Sliepen +Date: Fri Jan 5 23:51:41 2001 +0000 + + - Doubled size of trace buffer for easier debugging. + +commit 77509da76c61b881c9967bfb7cdafeaf6b56eb6d +Author: Guus Sliepen +Date: Fri Jan 5 23:50:56 2001 +0000 + + - AVL tree routines: faster than RBL, and also more stable. + +commit e1707f7739f450c729e26b921e459d5da07602f9 +Author: Guus Sliepen +Date: Fri Dec 22 21:34:24 2000 +0000 + + - Don't even think about using sscanf with %as anymore + - Allow keys to be inside the config files or in a seperate file + - Small fixes + +commit ecae72de94222302aa326888f70cfacdbd775b23 +Author: Ivo Timmermans +Date: Fri Dec 22 17:15:26 2000 +0000 + + Added lint target, requires lclint. + +commit c5fac35c6ce9b9fcc47508810d69aeab83d08c25 +Author: Ivo Timmermans +Date: Fri Dec 22 17:10:25 2000 +0000 + + Forget router.c + +commit 37544990e96fe5ea161e644f6417f505d666cd00 +Author: Ivo Timmermans +Date: Fri Dec 22 16:59:16 2000 +0000 + + Include autogen.sh (needed for the Debian package). + +commit 8a4daf4ea7758270a47a358f43ad97a64eb1c3ff +Author: Ivo Timmermans +Date: Fri Dec 22 16:54:56 2000 +0000 + + Various small changes. + +commit e469fca4d78e9d23698fe1e6b29b232198cc499e +Author: Ivo Timmermans +Date: Wed Dec 6 13:33:49 2000 +0000 + + Re-introduced MyVirtualIP and VpnMask, as dummy options. + +commit e50e4a54d6b40b988041a7e9bfdfbf708657f3a5 +Author: Ivo Timmermans +Date: Tue Dec 5 09:04:32 2000 +0000 + + Give a warning about having to re-create the keys + +commit 4610d98c04641fce65747e07d65cbdd03fb6fe30 +Author: Ivo Timmermans +Date: Tue Dec 5 09:03:41 2000 +0000 + + Ported it back to /bin/sh. + +commit 1e38dcc3fa6c0da2fdb21f83a588338fa8a41818 +Author: Ivo Timmermans +Date: Tue Dec 5 09:03:19 2000 +0000 + + Install a file in /etc/modutils/tinc, containing all necessary aliases + and options for kernel modules. + +commit 6327f32f43dc9109fad9952fd50a23876d0acaf0 +Author: Ivo Timmermans +Date: Tue Dec 5 08:59:30 2000 +0000 + + Tiny bits of code beautifying + +commit 9267bed9f516244b00d5c86c8dae44b7eb78a96c +Author: Ivo Timmermans +Date: Tue Dec 5 08:56:44 2000 +0000 + + Oops. I did some VERY wrong things with readline(). Fixed now. + +commit 6ddc9109d7313503895227c7876309b36681393d +Author: Ivo Timmermans +Date: Tue Dec 5 08:54:22 2000 +0000 + + Massive long awaited documentation update. It's not finished yet, + most notably the example configuration is still old. + +commit bc22ee16e6903d2caf9d22afa85020d1e3e10b56 +Author: Ivo Timmermans +Date: Sun Dec 3 12:23:06 2000 +0000 + + Option -d accepts an argument to set the debug level immediately. + +commit 01d23601a273d128ebfd13c2ffa10892e9b13094 +Author: Ivo Timmermans +Date: Sun Dec 3 12:22:19 2000 +0000 + + Sort configuration directives + +commit d6b77e18b58ad8f9bcd9b60864b95cd2a74482c5 +Author: Ivo Timmermans +Date: Sun Dec 3 12:21:20 2000 +0000 + + Added documentation merger + +commit e985f6d3cdbebdeb17333bbd3d3c20d4618128cf +Author: Ivo Timmermans +Date: Fri Dec 1 13:46:26 2000 +0000 + + Include COPYING.README in the distribution. + +commit 94192b3db10fe51ce45fa569ec068423a4491b0b +Author: Ivo Timmermans +Date: Fri Dec 1 13:45:46 2000 +0000 + + Stated that distributing executables linked with OpenSSL is permitted + provided that all other requirements of the GPL are complied with. + +commit 52575a573c1d87ee125a54a2e0b4044698904cae +Author: Ivo Timmermans +Date: Fri Dec 1 12:38:42 2000 +0000 + + Use buffer instead of line in read_config_file(), line may be assigned + NULL, so buffer always holds the pointer to the allocated space. + +commit ab33c1aa6081f07333bf1de00e4036dd2b4628a6 +Author: Ivo Timmermans +Date: Fri Dec 1 12:36:36 2000 +0000 + + readline() accepts two extra parameters, buf and buflen, to avoid + mallocing and freeing for every line that is read. + +commit 6c56a8416eded8f19076a619a27ad7b153dd91f3 +Author: Ivo Timmermans +Date: Thu Nov 30 23:44:07 2000 +0000 + + Tagged `Storing private key in separate file' as done. + +commit 8fe83e98da043e930a88ddd6b2de6c14aa791335 +Author: Ivo Timmermans +Date: Thu Nov 30 23:39:55 2000 +0000 + + All full stops have two spaces after them. (Silly commit, I know.) + +commit a0f7af3ed79c55d9680cbb0a569b3c8987581d43 +Author: Ivo Timmermans +Date: Thu Nov 30 23:18:21 2000 +0000 + + New function read_rsa_public_key(); + In net.c/setup_myself deleted old code to read the public key (which + is now implicitly read in together with the private key). + +commit 28deaeac14d619efb9830d03fd61dc7cca70a701 +Author: Ivo Timmermans +Date: Thu Nov 30 22:48:48 2000 +0000 + + Avoid printing duplicate messages from read_rsa_keys + +commit 2293304748f7e4e9a18ee848b8264bdecebae37f +Author: Ivo Timmermans +Date: Thu Nov 30 22:33:16 2000 +0000 + + Better error checking when reading the RSA private key. + +commit bf4e969899bb6cdeb05570d96a567c2833ac83bd +Author: Ivo Timmermans +Date: Thu Nov 30 22:32:14 2000 +0000 + + In readline(): initialise the line to zero length; + In read_config_file(): Test for EOF, and print the variable name that + caused an error. + +commit 113198d9c0b3be9904057673cfed165406803f86 +Author: Ivo Timmermans +Date: Thu Nov 30 21:11:03 2000 +0000 + + The file is safe if it doesn't exist. + +commit 09260b43d1ff037c22f86c82a6af830e9a6d6ae5 +Author: Ivo Timmermans +Date: Thu Nov 30 20:08:41 2000 +0000 + + Read the PEM file pointed to by the configuration directive + PrivateKey. This means thatt he meaning of this variable has changed, + it no longer should contain the private key directly. + + WARNING: This code is untested. + +commit 8ccb1ede92fbd55481fa2317c2450bb9dd94a180 +Author: Ivo Timmermans +Date: Thu Nov 30 00:24:13 2000 +0000 + + Implemented is_safe_path, and extended ask_and_safe_open. + + is_safe_path needs more work before it is useable. + +commit 75e3c296b4fa1eb02df2f5f84a1280e791f88603 +Author: Ivo Timmermans +Date: Wed Nov 29 15:22:04 2000 +0000 + + Updated Dutch translation + +commit d36da1948abdd27e9d0740c2baceb0bd155c18c6 +Author: Ivo Timmermans +Date: Wed Nov 29 14:30:07 2000 +0000 + + Also free the pointer returned by readline(). + +commit 9e55426d72fd77fda891edd0023dab2f9909639e +Author: Ivo Timmermans +Date: Wed Nov 29 14:27:24 2000 +0000 + + Use readline() in read_config_file() instead of fgets. + +commit 8ea23d9ec3f2fe0c113eac5caafb7c2bd03f3016 +Author: Ivo Timmermans +Date: Wed Nov 29 14:23:08 2000 +0000 + + xstrdup now takes a const pointer as an argument. + +commit 54ef13bf75a7a1e787716ce395ffe847fa74673f +Author: Ivo Timmermans +Date: Wed Nov 29 14:24:40 2000 +0000 + + Implemented a readline() function that will read an entire line into a + dynamically allocated buffer; + + Ask for a file name in ask_and_safe_open(). + +commit 9175d2048382c617a639fd3d437a9e06baa66d0f +Author: Ivo Timmermans +Date: Wed Nov 29 01:37:50 2000 +0000 + + Added a check for a scanf that knows about %as. + +commit 1ca04711aeab615161746c6bbb5d137388c73263 +Author: Ivo Timmermans +Date: Wed Nov 29 00:33:15 2000 +0000 + + Check for get_current_dir_name. There is a replacement function in + dropin.c. + +commit c94f7637427f4c89d56c41fe4c75f2970b664a63 +Author: Ivo Timmermans +Date: Tue Nov 28 23:23:41 2000 +0000 + + dropin.c/h contain a set of drop-in replacements for non-standard C + library functions (read: GNU extensions). + +commit 3ff76eb10acc55b6f269c1075de6bbaa5bc83516 +Author: Ivo Timmermans +Date: Tue Nov 28 23:12:57 2000 +0000 + + Save RSA public and private keys to a separate file, instead of + wanting to copy them into a configuration file. + +commit 4c502b005bfd24821e817c134e8a442a5f4606de +Author: Ivo Timmermans +Date: Tue Nov 28 08:59:27 2000 +0000 + + Use sigaction to set signal handlers, the previous commit (1.1.2.16) + already contained a large portion of what should have gone in this + one. + +commit e44dc004b3d1ce8f857971f479c917931eda7091 +Author: Ivo Timmermans +Date: Mon Nov 27 20:52:55 2000 +0000 + + Sort items to either 1.0 or future release goals. + +commit 699f3b4c93482055c0832c9a6b76dc0294967003 +Author: Ivo Timmermans +Date: Sun Nov 26 22:46:53 2000 +0000 + + Check for the function strsignal, and define it to "" if it is not + available. + +commit 67a4abda707b28b9c77cb35ff1e800e6a5b0991c +Author: Ivo Timmermans +Date: Sun Nov 26 22:42:34 2000 +0000 + + Give an error message if daemon() failed. + +commit 702e55306dfebe5c6f9a6587ed029c3bc3efbe8f +Author: Ivo Timmermans +Date: Sun Nov 26 22:32:52 2000 +0000 + + Updated Spanish translation, provided by Enrique Zanardi. + +commit 1eedf54681d4556c6874f7baee8e810cab867756 +Author: Guus Sliepen +Date: Sat Nov 25 13:33:33 2000 +0000 + + - Use only one socket for all UDP traffic (for compatibility) + - Write pidfile again after detaching + - Check OS (for handling FreeBSD/Solaris tun/tap stuff) + +commit 0806605ce383b7e89fa26eda56f8a5f3bbed9dd3 +Author: Guus Sliepen +Date: Fri Nov 24 23:30:50 2000 +0000 + + - Added daemon() replacement. + +commit cfb828784ebbcf4b3e40eb9bb351b6ed10a84b35 +Author: Guus Sliepen +Date: Fri Nov 24 23:14:52 2000 +0000 + + - Added Armijn to the list + +commit cf49b2c0647554613874cce495e4a7937a9f7863 +Author: Guus Sliepen +Date: Fri Nov 24 23:13:07 2000 +0000 + + Another big & bad commit: + - Added some extra search functions to rbl routines + - Fix subnet_lookup() + - Reorder some syslog messages to make more sense + - daemon() is back + - Don't let scripts execute in parallel (gives race conditions, and + anyway something MIGHT just be configured which is necessary for further + execution of tinc itself) + - Accidently merged check_child() with execute_script(). + - Small fixes + +commit 97c54ffb35312caf38034952b9ed2733f7e374f9 +Author: Ivo Timmermans +Date: Fri Nov 24 16:52:57 2000 +0000 + + Add default tinc-up and tinc-down scripts for a Debian system. These + do not yet work, it's just old code from init.d. + +commit b42c9abafdc102db0641f3d444bdb30fbc29140a +Author: Ivo Timmermans +Date: Fri Nov 24 14:15:20 2000 +0000 + + Call autogen.sh instead of configure alone; and make cvs-clean instead + of distclean. This way you can just cvs checkout && dpkg-buildpackage + in one go. + +commit edb9b4cad09855a9bb3c57c5d4b1b174fde1de6c +Author: Ivo Timmermans +Date: Fri Nov 24 14:13:51 2000 +0000 + + Explain how to tell configure where OpenSSL lives. + +commit 4cb4a7d298d560593f84d974bf77d0ee8a911a50 +Author: Ivo Timmermans +Date: Fri Nov 24 14:13:06 2000 +0000 + + Set errno to 0 before trying to kill the other process. + +commit ef88db63120503a8c9d34d86073795c99dedc3a9 +Author: Ivo Timmermans +Date: Fri Nov 24 14:12:31 2000 +0000 + + Alter CFLAGS, somehow INCLUDES doesn't propagate properly. Still + doesn't work exactly like it should, but getting there. + +commit b17822840150f5ba8cfb8e5a44fc10d66bd15a97 +Author: Ivo Timmermans +Date: Fri Nov 24 14:04:49 2000 +0000 + + Set CFLAGS to -O2 -Wall when running configure + +commit eb36b0c1ef7b5ed8ff59c3b41cbb361ed37d5f01 +Author: Ivo Timmermans +Date: Fri Nov 24 14:00:32 2000 +0000 + + Use cvs2cl instead of rcs2log to generate the ChangeLog. + +commit 2f37f2bd8ab6b89eb6b6c2b4bdd6ffe449b1aa98 +Author: Ivo Timmermans +Date: Fri Nov 24 14:03:13 2000 +0000 + + Set localstatedir to /var + +commit 31aa4298463498cbb755db747e901e4269cd1ef6 +Author: Ivo Timmermans +Date: Fri Nov 24 13:33:48 2000 +0000 + + Do not attempt to retreive ChangeLog information only from the CABAL + tag, it doesn't work anyway. + +commit f2dd7bb42c1f4bfa708f542e430f4a56fd43e74f +Author: Ivo Timmermans +Date: Fri Nov 24 13:32:26 2000 +0000 + + Do not check for the daemon() system call + +commit b0ff879e7c68edd447328f3d806c1ad9e336fece +Author: Ivo Timmermans +Date: Fri Nov 24 12:44:39 2000 +0000 + + Do not use the C library's daemon() call. + +commit cebcf78b9a24f70902009bea23514e55d84b096a +Author: Guus Sliepen +Date: Thu Nov 23 09:30:33 2000 +0000 + + - Don't link with -ldl anymore + - Let's not use bash' built-in pwd function anymore... it does not follow + symlinks. + +commit 7aa7895629d72391eccfcb23f3cb6290a9e3abc3 +Author: Guus Sliepen +Date: Wed Nov 22 23:09:38 2000 +0000 + + - #include instead of + +commit dac256505e1af78505c9f905bd55c11d4b87345c +Author: Guus Sliepen +Date: Wed Nov 22 22:18:03 2000 +0000 + + - Fixed all (except 2) compiler warnings gcc -Wall gave. + +commit 6f373e690236334d8f8333710b61f97ccad54bf1 +Author: Guus Sliepen +Date: Wed Nov 22 22:05:37 2000 +0000 + + - More porting to FreeBSD and Solaris. + +commit 5971e352dae2cf189f1cbdeacffa4ccdd1e98304 +Author: Guus Sliepen +Date: Wed Nov 22 20:25:27 2000 +0000 + + - Work with the correct key buffer in ans_key_h + +commit a07602c4fddfca9894f1d738959ae359695f5bf9 +Author: Guus Sliepen +Date: Wed Nov 22 19:55:53 2000 +0000 + + - No more %as. + +commit 394ed3fb174bb629bfb4b441fe58842562f955de +Author: Guus Sliepen +Date: Wed Nov 22 19:14:09 2000 +0000 + + - Write pidfile AFTER detaching... + - Minor cleanups + +commit f8b4a000d008082e5c7e511a49318b8dea8fd08d +Author: Guus Sliepen +Date: Wed Nov 22 18:54:08 2000 +0000 + + - Cleaned up and checked for some more NULL pointers in rbl.c + - Two connection lists: one for incoming connections, sorted on ip/port, + one for connections whose identity we know, sorted on id ofcourse... + +commit 785684f0ec5c9250788b4b32c0eab3f358c9db61 +Author: Ivo Timmermans +Date: Wed Nov 22 17:49:16 2000 +0000 + + Declare fd. + +commit e42255ae1374fe65e92de72de4508a84bdb91fa1 +Author: Ivo Timmermans +Date: Wed Nov 22 17:48:15 2000 +0000 + + Add more checks to ensure that filedescriptors are right in + _execute_script(). + +commit 2ed68134047a19e708c2a2af32c58968835a7043 +Author: Ivo Timmermans +Date: Wed Nov 22 16:19:07 2000 +0000 + + Honor the --localstatedir option to configure, instead of hardcoded /var. + +commit 9e9e1925b901dff87518f0e1534a33e48eab8303 +Author: Guus Sliepen +Date: Tue Nov 21 09:13:59 2000 +0000 + + - Check for NULL tree->delete callback + - Add xstrdup() function + +commit da9a1e8084a9b73306bdbc541ee8af938c3e7754 +Author: Guus Sliepen +Date: Mon Nov 20 23:29:47 2000 +0000 + + - More fixes. + +commit 3a6200c1e39b61b249db3d1f9bcffa77351863bd +Author: Guus Sliepen +Date: Mon Nov 20 22:13:14 2000 +0000 + + - Various small fixes. + +commit 06afd357b0cf4aab778b1ccabbd1be61a9500d10 +Author: Ivo Timmermans +Date: Mon Nov 20 19:56:01 2000 +0000 + + Get rid of all libtool references at once. libtool was only used by + libblowfish, which was superseded by openssl. + +commit 1857b3c97c261dda9978a67d07b315bb3ca68841 +Author: Guus Sliepen +Date: Mon Nov 20 19:41:13 2000 +0000 + + - Proper initialization of rbltree structures. + +commit 408ca91766088b6c2d38e198b0692bf394b41248 +Author: Guus Sliepen +Date: Mon Nov 20 19:12:17 2000 +0000 + + - Integrate rbl trees into tinc. + +commit 9024e01ce649b89d304a4aa5b1d6ef0b56b5a12c +Author: Ivo Timmermans +Date: Mon Nov 20 18:06:17 2000 +0000 + + Also include process.h + +commit 3cc063d23a6e3a23fd01f03b0bc99825c2b13e16 +Author: Ivo Timmermans +Date: Mon Nov 20 18:05:34 2000 +0000 + + More function and header checks + +commit 59aa15d3d1db4e948113f202dd2183f4bb23970d +Author: Ivo Timmermans +Date: Mon Nov 20 18:02:15 2000 +0000 + + Added this release + +commit 8f273f0ee265c75dd8eea65b2f1cd60a79691cd6 +Author: Guus Sliepen +Date: Sun Nov 19 22:12:46 2000 +0000 + + - Small fixes + +commit cc7c078774db955cece9b263022e6c1ca955fc10 +Author: Guus Sliepen +Date: Sun Nov 19 11:05:59 2000 +0000 + + - Deletion also works now. + +commit 3526f1e151b7a189f075d88c9d88cacaece31d02 +Author: Guus Sliepen +Date: Sun Nov 19 02:04:29 2000 +0000 + + - Fixed a lot of small things. Tested everything except deletions. + +commit 4f68e5b6133480478edba0959cb87d4eb149a8e7 +Author: Guus Sliepen +Date: Sat Nov 18 23:22:44 2000 +0000 + + - Fix tree head/tail upon insertion + +commit 880cd6f1a94ef76ebebc5bd96dd26d62e3d829f4 +Author: Guus Sliepen +Date: Sat Nov 18 23:21:01 2000 +0000 + + - Implemented deletions + - Added rbl_foreach() function + +commit 00e5d572621ad5f0263999dbfbfcb11e023bf48b +Author: Guus Sliepen +Date: Sat Nov 18 18:14:57 2000 +0000 + + - Fixed searching + - Insertion implemented + +commit 7fcc0c6415488ed6ce0089a67ab7cfdd5d0d83ca +Author: Guus Sliepen +Date: Fri Nov 17 10:03:02 2000 +0000 + + - Removed stray @INCLUDE@ (how did that get there?) + - Use 0 instead of FALSE + +commit 44cbd13e5248880b074b5068df14a4634204a1d3 +Author: Guus Sliepen +Date: Fri Nov 17 00:56:49 2000 +0000 + + - Simplified do_detach + +commit 2626c641aa714a8d776f1bb16340586d935aa6b1 +Author: Ivo Timmermans +Date: Thu Nov 16 22:13:09 2000 +0000 + + Use proper prototypes. + +commit 5d1145f2c4b3b8261ca0aa0e89a2daf321640f0b +Author: Ivo Timmermans +Date: Thu Nov 16 22:12:23 2000 +0000 + + Move more functions from tincd.c into process.c. + +commit 485f7a5043a4b3345bd02e5063502603550b4c76 +Author: Ivo Timmermans +Date: Thu Nov 16 22:11:40 2000 +0000 + + Delete struct ifr + +commit 30f34015ee11bbe1106c07e381288a702f12dac5 +Author: Ivo Timmermans +Date: Thu Nov 16 18:06:39 2000 +0000 + + New function: xmalloc_and_zero, which initialises the allocated memory + to all zeroes. + +commit 2764532ea72200d0a27ad2d79e6e299c00c62404 +Author: Ivo Timmermans +Date: Thu Nov 16 17:54:29 2000 +0000 + + Move all process-related functions into process.c. + +commit aa755206da4bcce3261ecd5dbfa41570a0155c73 +Author: Guus Sliepen +Date: Thu Nov 16 09:18:38 2000 +0000 + + - Added balanced tree management stuff as well. (It is not finished yet.) + +commit 7f87c3d9134612041d56180ea7fc3e6c37991f6b +Author: Ivo Timmermans +Date: Wed Nov 15 22:07:36 2000 +0000 + + Keep a list of running children, and in each loop in main_loop(), + check if one has exited. + +commit d9ce5a7f3f5eddb193b6a9b5974c7c49eac41ea1 +Author: Ivo Timmermans +Date: Wed Nov 15 22:04:48 2000 +0000 + + List management and manipulation routines. + +commit e118ba0a648000c48d6a401c9b9249a844d6dbcf +Author: Guus Sliepen +Date: Wed Nov 15 13:33:27 2000 +0000 + + Porting to FreeBSD: + - Reorganized and added some #includes + +commit 596e248bc588323cc7ee751286dbcaf677b5c653 +Author: Ivo Timmermans +Date: Wed Nov 15 01:28:21 2000 +0000 + + Let the output from an executed script in execute_script() go to + syslog, with proper error detection. + +commit bb2495e569fb161b42efd633eb1c471b8222b1fb +Author: Ivo Timmermans +Date: Wed Nov 15 01:06:13 2000 +0000 + + Use the HAVE_OPENSSL_xxx_H defined from m4/openssl.m4 during + configure. + +commit 6fb4a5b6be5628ece9b391b46e7858fdf5957a80 +Author: Ivo Timmermans +Date: Wed Nov 15 01:02:30 2000 +0000 + + Also check for sha.h. + +commit 8eb60d0ccde2f1de6fd917db7300e537f271783e +Author: Ivo Timmermans +Date: Wed Nov 15 00:57:26 2000 +0000 + + Also check for rand.h and err.h. If any of these files does not + exist, try the next alternative path. + +commit c5c8e99afd3fae3868f20b5c7a4f8754498b39ad +Author: Ivo Timmermans +Date: Tue Nov 14 23:18:19 2000 +0000 + + Get rid of the annoying empty line + +commit c467ee02d3ef8bed7ec2cc52cb1527ec60cdc93a +Author: Ivo Timmermans +Date: Tue Nov 14 23:02:08 2000 +0000 + + Oops, small error. + +commit 9ddb37cee0f754ef88a55f692a508010fe18c782 +Author: Ivo Timmermans +Date: Tue Nov 14 22:57:19 2000 +0000 + + Better checks for OpenSSL. I think it can now detect almost all conceivable installations. + +commit 72c3776d6ac103fa25d216c42847ecba3a4f58e5 +Author: Ivo Timmermans +Date: Mon Nov 13 22:29:22 2000 +0000 + + Identify version as 1.0pre4-cvs + +commit 5344832be1126967ff340cf6bd270a377bb8e487 +Author: Ivo Timmermans +Date: Mon Nov 13 22:01:27 2000 +0000 + + Add a check for openssl that accepts explicit file locations. + +commit 5b74909ea070fbd482340dc42193e33366a9dddb +Author: Ivo Timmermans +Date: Thu Nov 9 21:33:18 2000 +0000 + + Add prototype for destroy_queue + +commit 6e27618708233998db7e5886ed9afaa21bb9d938 +Author: Ivo Timmermans +Date: Thu Nov 9 21:29:58 2000 +0000 + + Updates, updates + +commit a91eae538d9cff8aed399a175c0bbc7d744cd22a +Author: Ivo Timmermans +Date: Thu Nov 9 20:59:35 2000 +0000 + + Bop version number to 1.0pre3-1 + +commit e65a93053cca3f8aebf63094cf160835c3108e25 +Author: Ivo Timmermans +Date: Thu Nov 9 20:42:16 2000 +0000 + + Wrapped text to 70 (72?) columns for easy reading + +commit 4310b17be9cefcc1814ddef471e4c5cd8f9f867e +Author: Ivo Timmermans +Date: Thu Nov 9 20:41:13 2000 +0000 + + Final release notes added, also edited release notes for 1.0pre2 to what the announcement on the mailing list looked like. + +commit 16847ea255fa8a7c0ed922af80a2f36b7bdf4b3b +Author: Guus Sliepen +Date: Wed Nov 8 20:52:37 2000 +0000 + + - Make checkpoint tracing a compile time option (off by default) + +commit 55d7b5a2bb1df6f55f0a93e9cfed77c1da337588 +Author: Guus Sliepen +Date: Wed Nov 8 18:05:06 2000 +0000 + + - Add Jamie :) + +commit 5055e1dedc9fe984c497448c1b2ffc4afdf18aa3 +Author: Guus Sliepen +Date: Wed Nov 8 17:56:34 2000 +0000 + + - Applied Jamie Brigg's patch (close sockets after error) + +commit 74326df7adc514798565df0a8719421adbb5fef3 +Author: Guus Sliepen +Date: Wed Nov 8 00:20:06 2000 +0000 + + - Fixed --config + - Show warning when both netname and config directory are given. + +commit f8f1007bf469d44480d95d0d78ddc156d00e059f +Author: Guus Sliepen +Date: Wed Nov 8 00:10:50 2000 +0000 + + Porting to SunOS 5.8: + - More #includes Linux doesn't seem to need + - Don't do unsetenv() on SunOS + - Use a replacement asprintf() in case the OS doesn't support it + It now compiles properly under SunOS. + +commit 56bd0864e4c5680fee59af48228b1ec3fb97b57b +Author: Guus Sliepen +Date: Tue Nov 7 22:33:33 2000 +0000 + + Porting to SunOS 5.8: + - Include all header files necessary + - Check for flock() function + +commit 7d0f82bd4b7044a5151835e25e830fd28dfaaebd +Author: Guus Sliepen +Date: Tue Nov 7 22:02:14 2000 +0000 + + - Open UDP connection for all known hosts. Comments please. + +commit f95cc86d0c14ca4c47e5459af4bb6d1170baa9f5 +Author: Guus Sliepen +Date: Tue Nov 7 21:43:28 2000 +0000 + + Changed execution of tinc-up: + - Do not free() strings that have been putenv()d, see man page of the + latter. + - Do not set IFNAME anymore, it appears that the ioctl to get the name of + the interface does not work at all. Since it is set to NETNAME in case + of tun/tap and it is known beforehand in case of ethertap, there is no + need for it anyway... (though it would've simplified things). + +commit efc3a2a466937da942afc84dde080ba8b1731140 +Author: Ivo Timmermans +Date: Sun Nov 5 02:19:58 2000 +0000 + + Build-Depends on gettext + +commit 698191fd2f512f3618e2d60592fcd57cd750b965 +Author: Guus Sliepen +Date: Sat Nov 4 22:57:33 2000 +0000 + + - Prepended config_ to all configuration option names, because it confused + everything (including myself). + - Use connection oriented UDP sockets for both incoming and outgoing + packets. + +commit afc05797077641baa33b024ffeaafd6cad3ff7a7 +Author: Guus Sliepen +Date: Sat Nov 4 20:44:28 2000 +0000 + + - Simplified ping mechanism. + +commit 2191d894bfd615e8fa7857d031ea630edc12a854 +Author: Ivo Timmermans +Date: Sat Nov 4 17:29:45 2000 +0000 + + Build-depends on libtool + +commit 5019dd879177b5ab9413e5c0aa72a15d0e585acf +Author: Guus Sliepen +Date: Sat Nov 4 17:09:10 2000 +0000 + + - Check for packets that are looping back. + +commit 20dd5aff4d2898d8b59f371671cc110b870fa09c +Author: Ivo Timmermans +Date: Sat Nov 4 17:04:17 2000 +0000 + + Updated Dutch translation + +commit 3f177e9bf02b6121055414a2cc7fd3f4cff01cba +Author: Ivo Timmermans +Date: Sat Nov 4 17:01:55 2000 +0000 + + Add route.c to the list of source files. + +commit ac47586552710425417ed80878f8f853c313b421 +Author: Guus Sliepen +Date: Sat Nov 4 16:54:21 2000 +0000 + + - Forward keys in hex notation, not as binary data. + +commit 3f8f067e8b559366b9b41dee6a4312702c82042f +Author: Guus Sliepen +Date: Sat Nov 4 16:39:19 2000 +0000 + + - Don't forget to set packet cipher for added hosts. + +commit 433858d410c1fedf8d2a5f2b4ecd7c980dd79dd2 +Author: Guus Sliepen +Date: Sat Nov 4 15:34:07 2000 +0000 + + - connlist.c added to translation + +commit 15246df85d6171c92478541a835effb96d6085c4 +Author: Ivo Timmermans +Date: Sat Nov 4 15:32:05 2000 +0000 + + In execute_script: + - add an environment variable NETNAME. + - chdir to the configuration directory before execing the script. + +commit 69618c01385eb7226cd6eab0918d1f30b0ed6c66 +Author: Ivo Timmermans +Date: Sat Nov 4 15:18:58 2000 +0000 + + Do not include the passphrases directory + +commit 417f36a07990ff9bc7de7d4e63e57146bef0dd75 +Author: Guus Sliepen +Date: Sat Nov 4 15:17:02 2000 +0000 + + - Removed manpage for no longer existing genauth. + +commit 3d7189a444fe3efed58dc93a071129007041aebf +Author: Guus Sliepen +Date: Sat Nov 4 14:52:40 2000 +0000 + + - Resolve scriptname after fork() + +commit d38772ebc42f5ad1d946ee89d955f5d43bb2fe8c +Author: Ivo Timmermans +Date: Sat Nov 4 14:16:46 2000 +0000 + + Use putenv() instead of clumsy do-it-yourself in execute_script. + +commit f83803c1bf6557d5af93982e7cd987e151eba401 +Author: Ivo Timmermans +Date: Sat Nov 4 13:25:15 2000 +0000 + + Small change to the way the environment is copied. + +commit ed0bf283e37642f9f7673f664713a16d916bd70f +Author: Guus Sliepen +Date: Sat Nov 4 11:49:58 2000 +0000 + + - Removed even more warnings. + +commit dc699f8b1265deb7606d553e36326527dbd29746 +Author: Guus Sliepen +Date: Sat Nov 4 10:37:27 2000 +0000 + + - Removed unused MAC strip/add functions. + +commit 5065ea32c32e27478d93c00a1bba0c812b7a2b8c +Author: Ivo Timmermans +Date: Fri Nov 3 22:35:12 2000 +0000 + + Warnings removal pass: always include config.h first; add a few + prototypes in the header files. + + This also fixes a few lint errors/warnings. + +commit 73aa7fbf7e1b623398d1bc1493f567ce4d846f22 +Author: Ivo Timmermans +Date: Fri Nov 3 22:33:16 2000 +0000 + + Run the scripts tinc-up and tinc-down from a separate function, which + sets the environment as it should be and checks for errors. + +commit 4ad1e382d6f10acf94ce59d85b80925cee7553a6 +Author: Ivo Timmermans +Date: Fri Nov 3 22:31:55 2000 +0000 + + Save the environment on startup. + +commit 7612c6da3890ce5a0730e4dfde9d5ba07bdbf5b3 +Author: Ivo Timmermans +Date: Thu Nov 2 23:02:49 2000 +0000 + + Minor cosmetic change. + +commit 6a10e42f734e8bec9848a11e73bc2a8211a9f401 +Author: Ivo Timmermans +Date: Thu Nov 2 22:51:16 2000 +0000 + + - If necessary, patch po/Makefile.in from po-Makefile.in.in.diff to + get DESTDIR installation (required to get locales installed + correctly). + - Use dh_perl to get accurate perl dependencies. + +commit ef12849c1a03b3aaf85dd46786d6631f66b104bd +Author: Ivo Timmermans +Date: Thu Nov 2 22:11:18 2000 +0000 + + Oops, and include doc-base.tinc (new file). + +commit 5672ddd6cb9116420a1904f7741fdbed89c2ec54 +Author: Ivo Timmermans +Date: Thu Nov 2 22:10:09 2000 +0000 + + Don't include shlibs, as it no longer exists. + +commit 013fcb0e9f9c0222f4f63ddf42a2f25bfc4a5546 +Author: Ivo Timmermans +Date: Thu Nov 2 22:05:36 2000 +0000 + + Changed a few messages wrt. system calls; updated and changed the Dutch translation a bit. + +commit c444305c0bb965aa515a503406844ceeb483c285 +Author: Ivo Timmermans +Date: Thu Nov 2 21:43:03 2000 +0000 + + Mention fileutils, add a pointer to THANKS for more details + +commit 84c842def74c5d0e9c4a69e4f584fe9eb66eb728 +Author: Ivo Timmermans +Date: Thu Nov 2 21:41:53 2000 +0000 + + Change wsl to Wessel's name and email address in the ChangeLog creation + +commit 5b6815751e581bedd64bfc63aea5b42c746bbceb +Author: Ivo Timmermans +Date: Thu Nov 2 21:40:33 2000 +0000 + + More exhaustive list of changes - perhaps it can be worded differently? + +commit e954fc8f0c731e7116fd27f38c176b83cca519f7 +Author: Ivo Timmermans +Date: Thu Nov 2 21:39:57 2000 +0000 + + Changed `I' to `We' - small change, lots of difference :) + +commit 3db3a41667f90ce74bfd0197fc867cc71a087e50 +Author: Ivo Timmermans +Date: Thu Nov 2 21:38:55 2000 +0000 + + Only check for linux/if_tun.h once + +commit 1b11bcb0128ca65580cbf28ffb16078c81e6d678 +Author: Ivo Timmermans +Date: Thu Nov 2 21:34:45 2000 +0000 + + Added a perl example to turn an IP address into a MAC address. + +commit cadf81fe67aed424504758865c2ea2bb263c76fb +Author: Ivo Timmermans +Date: Thu Nov 2 21:26:51 2000 +0000 + + Do not include $(top_srcdir)/cipher, it does no longer exist. + +commit fd32d771a84765281ea4ab8a5d9dbf5cebfa2911 +Author: Ivo Timmermans +Date: Thu Nov 2 20:29:03 2000 +0000 + + - Synchronized changelog with the package's changelog. + - Changed maintainer email address. + - New file doc-base.tinc. + - Better Build-Depends and Depends lines. + +commit a13d9c9da7434154b33e666c2236844011b87d46 +Author: Ivo Timmermans +Date: Thu Nov 2 20:25:35 2000 +0000 + + This file is no longer needed. + +commit 59528ec892e8b9a599f2b39bf432a3d842e963fe +Author: Guus Sliepen +Date: Tue Oct 31 16:22:49 2000 +0000 + + Removed config file parsing and interface setup. This will be handled by + the tinc-up and tinc-down scripts from now on. + +commit af565d00220b7536b9987c48e2a71459b45027b4 +Author: Guus Sliepen +Date: Tue Oct 31 16:10:17 2000 +0000 + + - Update. + +commit b4c1d4e2d3287acd7ca438455c64e50a2828ad24 +Author: Guus Sliepen +Date: Mon Oct 30 10:19:06 2000 +0000 + + - Fixed some spelling mistakes and terminology here and there. + +commit 4811afa073c871f2a52dfd5139bd0171046365eb +Author: Guus Sliepen +Date: Mon Oct 30 00:22:54 2000 +0000 + + - Small cleanups + - Updated dutch translation + - Updated man pages + +commit b7d4d4c17712e0bb9ee8bd497a2f525b79d5f40d +Author: Guus Sliepen +Date: Sun Oct 29 22:55:15 2000 +0000 + + - Finishing touch: encrypt the meta connections + +commit ec12269355f7979fdc0783dc15d109832f1e83cd +Author: Guus Sliepen +Date: Sun Oct 29 22:10:44 2000 +0000 + + - Use CFB mode for encrypting packets: it works and we don't need padding. + +commit cea3d8f3056d3c6aaaef473443240b8470c8ea2d +Author: Guus Sliepen +Date: Sun Oct 29 10:39:08 2000 +0000 + + - Small fixes + - Do proper key exchange + - Encrypt packets - it works, but there is something wrong with the MAC + header after decryption... + +commit 8fa9bc017d89b53798903df3fa98311067d4de90 +Author: Guus Sliepen +Date: Sun Oct 29 09:19:27 2000 +0000 + + - Removed old encr stuff + +commit a26d371d0df3bee1bdc6e9d7046e949ee29e6de7 +Author: Guus Sliepen +Date: Sun Oct 29 02:07:41 2000 +0000 + + - Updated dutch translation. + - Shutdown properly. + +commit e8391bd49975aa29fa62d6ae1d2d2ee398e0eb3e +Author: Guus Sliepen +Date: Sun Oct 29 01:27:23 2000 +0000 + + - Moved connlist stuff to the proper header file. + +commit 2689690dc37c384c4a022d03ab80f2cfb7fb9553 +Author: Guus Sliepen +Date: Sun Oct 29 01:08:09 2000 +0000 + + - Enforce correct order of authentication requests + +commit 3b9802a542f1fa439321d3386763ec33989194b5 +Author: Guus Sliepen +Date: Sun Oct 29 00:46:43 2000 +0000 + + - Hit people who can't figure out subnet address/mask pairs with a + (clue)bat. + +commit 7398002ade1397bd857953f009f4aed65ffc9218 +Author: Guus Sliepen +Date: Sun Oct 29 00:24:31 2000 +0000 + + - Fixed ans_key_h + - Removed tapsubnet configuration option. + +commit 35932fe6c8cb481eb687f98424776ce429570c21 +Author: Guus Sliepen +Date: Sun Oct 29 00:02:20 2000 +0000 + + - Very big cleanup. + +commit db21f015161aac244ec5600c4d0ff685549892c2 +Author: Guus Sliepen +Date: Sat Oct 28 21:52:22 2000 +0000 + + - Override destination ethernet address on incoming packets with + FE:FD:00:00:00:00 + +commit 8738c007b15eea024bc4ca6ee0f972b2f5bf259f +Author: Guus Sliepen +Date: Sat Oct 28 21:25:21 2000 +0000 + + - Fixed offsets when reading/writing from/to tap device + +commit f25868fd2b58bc0b350a5cfaf342480f28f804cf +Author: Guus Sliepen +Date: Sat Oct 28 21:05:20 2000 +0000 + + - Lots of small fixes + - Exchange subnets on acknowledgement of connection + - Do proper lookup when incoming packets from tap + - off-by-a small number-error when reading/sending tap packets + +commit ba6b8005ebe3a53877590c242ff581dc5dee5eae +Author: Ivo Timmermans +Date: Sat Oct 28 19:34:53 2000 +0000 + + Skip the check for Linux kernel sources + +commit d47d5932a3bbc4940aa6453ebfe617ef330783c8 +Author: Guus Sliepen +Date: Sat Oct 28 16:41:40 2000 +0000 + + - Updated subnet list handling. Subnets are added to two lists now, the + owner's list and a global list. It is all fucked up but it probably + works anyway, good enough for pre3 :). + +commit 9c2f805255fa36b05e8fe9391f639581d938b653 +Author: Guus Sliepen +Date: Tue Oct 24 15:46:18 2000 +0000 + + - Lots of little stuff modified + - Succesfully reads in subnets from host config file now and adds them to + the list. + +commit 60401d99b18ae01d91ca65faf8d2b32fac2b4474 +Author: Ivo Timmermans +Date: Mon Oct 23 21:56:56 2000 +0000 + + Oops, echelon change committed to cabal... :) + +commit c46e84837d1c84a8590e0e3507227670368884a7 +Author: Guus Sliepen +Date: Mon Oct 23 13:52:54 2000 +0000 + + - route.c will contain the routing logic. + +commit 76d794eaf7c1664a47f4d0080fcd80e4a551740b +Author: Ivo Timmermans +Date: Sun Oct 22 13:47:41 2000 +0000 + + read_server_config: Check for result of read_config_file. + +commit 56d8e862409ae91c63a27968b01a48a94aafb205 +Author: Ivo Timmermans +Date: Sun Oct 22 13:37:15 2000 +0000 + + Include linux/sockios.h and net/if.h anyway, regardless of the value of HAVE_TUNTAP. + +commit 52b842f8076d507d3a6ea07045d085ae21d1aa10 +Author: Guus Sliepen +Date: Sat Oct 21 11:52:08 2000 +0000 + + - Fixed all debug levels. + - Seed PRNG before generating a challenge + - Strange thing in challenge decryption: it fails if first bit is set!? + +commit 73f7efddd723b25c1477ec1139dc7211307ff660 +Author: Guus Sliepen +Date: Fri Oct 20 19:46:58 2000 +0000 + + - Removed last reference to genauth from Makefile.am + - Tinc spawns tinc-up and tinc-down scripts which can be used to configure + the network device. The environment variable IFNAME is set to the name + of the interface. + +commit fba19c30c92d39e74f5fd5594053793b036f30f4 +Author: Guus Sliepen +Date: Fri Oct 20 16:49:20 2000 +0000 + + - Made Makefile.am stub for doc/es/ + - Merged genauth into tincd + - Updated dutch translation + +commit 97ec5685b92ea727fe8f8b4bb8cf289a20f8580b +Author: Ivo Timmermans +Date: Fri Oct 20 16:44:32 2000 +0000 + + Generalized list and hash handling functions + +commit 699e159a7a1711034f1d16d68ad1974a82e12dfc +Author: Ivo Timmermans +Date: Fri Oct 20 16:43:13 2000 +0000 + + New function: xalloc_and_zero() + +commit 4059151732afb7d8fb52121d80e54f2ee325d30e +Author: Ivo Timmermans +Date: Fri Oct 20 16:42:22 2000 +0000 + + Add all the new files to the sources list for the utility library + +commit 9f64499e40a95a8c05c82924219517aa017fc411 +Author: Guus Sliepen +Date: Fri Oct 20 15:34:38 2000 +0000 + + - tinc now really does public/private key encryption! It even works, whee! + +commit 71f05ff8956cb2e62181fcef763709b0de8faa68 +Author: Ivo Timmermans +Date: Thu Oct 19 20:56:49 2000 +0000 + + Generalized error handling functions + +commit 95f4e8620ef8e2cdec1cc3b2ccb8cc8e3ce94e40 +Author: Ivo Timmermans +Date: Thu Oct 19 20:39:04 2000 +0000 + + Add check for the syslog function + +commit 430e14162918864f9f18aad0ec0badc1ccc3e01f +Author: Ivo Timmermans +Date: Thu Oct 19 17:29:22 2000 +0000 + + Changed changelog + +commit d5fd1344e668da0bc8536e798f347041d5377843 +Author: Guus Sliepen +Date: Thu Oct 19 14:42:00 2000 +0000 + + - Seed the PRNG using /dev/random before generating the keys. + +commit 30df5e95dbe585c6076d743d3771a42ad7c78590 +Author: Ivo Timmermans +Date: Wed Oct 18 20:12:10 2000 +0000 + + Bring head revision up to date with cabal (try #3) + +commit 571cfb5846c710a0a3cdbdddce8936f6b34f1cf1 +Author: Ivo Timmermans +Date: Wed Oct 18 19:44:11 2000 +0000 + + Get the head revision up to date with cabal + +commit e75315dae609f32041ca5ed939fd2a1b69d32d3e +Author: Ivo Timmermans +Date: Tue Oct 17 10:15:20 2000 +0000 + + Don't declare cp_file and cp_line in xmalloc() + +commit 31c543ad0fa1d19667a03a9bd183c668def23da0 +Author: Ivo Timmermans +Date: Tue Oct 17 10:14:25 2000 +0000 + + Process subdir es/ + +commit 20301888b7a0a206119d2cfc48ccf1a667bb4add +Author: Guus Sliepen +Date: Mon Oct 16 19:04:47 2000 +0000 + + - More fixing. Tinc daemons can now even create activated connections. + +commit bb3d18d56fa0dd2bc5146d0a0044b6ef0880bdb4 +Author: Guus Sliepen +Date: Mon Oct 16 16:33:30 2000 +0000 + + - Fixing little things + - Two tinc daemons can connect to eachother now (but they disconnect right + after the ACKs). + +commit 6e32b870ee127555888a115163922362c99009f9 +Author: Ivo Timmermans +Date: Mon Oct 16 11:35:10 2000 +0000 + + Output doc/es/Makefile + +commit baeac83bf465a47d46082e1de40ea14dcf1d39af +Author: Guus Sliepen +Date: Sun Oct 15 20:30:39 2000 +0000 + + Corrected #ifdefs for tun/tap support. + +commit 782171fd2c59b7cc5568d2d4b33ce041834710ec +Author: Ivo Timmermans +Date: Sun Oct 15 20:21:27 2000 +0000 + + Really #include the if_tun.h files now + +commit 8a54c51238672abd7a72c1dbdc7d17b9956a0d35 +Author: Ivo Timmermans +Date: Sun Oct 15 20:13:55 2000 +0000 + + Linearized checks for if_tun.h + +commit e5130495d7d4083d58ab76c26001aa27f5fc13db +Author: Ivo Timmermans +Date: Sun Oct 15 19:53:15 2000 +0000 + + Wrap the tun/tap code in #ifdef HAVE_TUNTAP + +commit 3b455b8f318528206b08121f5ce93d16e4ea01df +Author: Ivo Timmermans +Date: Sun Oct 15 17:26:31 2000 +0000 + + Add checks for the presence of the universal tun/tap device driver. + +commit 85adeef21275633b78a234b2660cbe3bc9dd2c33 +Author: Guus Sliepen +Date: Sun Oct 15 00:59:37 2000 +0000 + + - The daemon actually runs now (somewhat) + - Added support for tun/tap driver (autodetect!) + - More sophisticated checkpoint functionality + - Updated dutch translation + +commit 97ce045189e330e121873d1b4be1959c60062cbb +Author: Ivo Timmermans +Date: Sat Oct 14 22:22:06 2000 +0000 + + Add CVS id lines + +commit 2e159d0139e77041ad82e96bf0abef6aaf64a258 +Author: Ivo Timmermans +Date: Sat Oct 14 22:17:29 2000 +0000 + + Fix `Requirements'-section for GMP and OpenSSL libraries. + +commit 1d5bb49f261b4346b5a440ae6bbf58fe391ea46e +Author: Ivo Timmermans +Date: Sat Oct 14 22:00:09 2000 +0000 + + Update Depends lines to reflect the dependencies on OpenSSL + +commit e9635ae38e0e2e3eb92568a1e234f8348856dd69 +Author: Guus Sliepen +Date: Sat Oct 14 17:04:16 2000 +0000 + + - Second fixing-things pass: it even links now. + - Lots of FIXME comments added to the source code. + +commit 6a8c2e346e6125e58aab428e6730c18a949abe12 +Author: Ivo Timmermans +Date: Fri Oct 13 23:34:56 2000 +0000 + + Don't look for GMP header files + +commit f18e30dab3c208fd353af11e365791035534f444 +Author: Ivo Timmermans +Date: Fri Oct 13 23:30:11 2000 +0000 + + Updated new requirements, pointers to the manual + +commit a96f2f0fc8a02593d4cda5976df3c76fc5c99eae +Author: Ivo Timmermans +Date: Fri Oct 13 23:29:35 2000 +0000 + + Link with OpenSSL, forget libGMP + +commit 183a8edd22ba4bc682392c73ae02fc9e121eda68 +Author: Guus Sliepen +Date: Wed Oct 11 22:01:02 2000 +0000 + + - Fixing-things pass: every source file compiles into an object file now, + but linking tincd does not work yet (must link with openssl libs and + define some missing functions). + +commit 6e39481d8f2406e60b5e329ace08b5a005d5cc43 +Author: Guus Sliepen +Date: Wed Oct 11 13:42:52 2000 +0000 + + - Generalized config file parsing to support multiple configuration trees. + +commit 451e9e3e7a968151de541de68603a01f0922b415 +Author: Guus Sliepen +Date: Wed Oct 11 12:07:27 2000 +0000 + + - Changed genauth to produce rsa keypairs instead of random passphrases. + +commit 950fb8e916b0e248dcaa72c96859acd6046683aa +Author: Guus Sliepen +Date: Wed Oct 11 10:35:17 2000 +0000 + + Big and bad commit of my current tree... + - Added seperate file for connection list handling + - Updating everything to use connlist, meta and subnet files + - Removed dependency on libgmp + - Lots of other stuff... + +commit 73d0dcfcc1019ee745a422982b4e3ede9d59dd91 +Author: Guus Sliepen +Date: Wed Oct 4 15:09:57 2000 +0000 + + Removing cipher directory (all will be covered by OpenSSL). + +commit 2228b16159a7aff64e6559ee1635716154e67fe6 +Author: Guus Sliepen +Date: Sun Oct 1 03:21:49 2000 +0000 + + - Added subnet handling code + - Other small changes to header files + +commit 676b1c0ea111406eb94a74ae12878dfd5ad9f56d +Author: Ivo Timmermans +Date: Wed Sep 27 20:32:29 2000 +0000 + + Many updates, parts rewritten, added, shuffled around. + +commit c78a204f06182f50b0812c8e4fef6163e82097bf +Author: Guus Sliepen +Date: Tue Sep 26 14:06:11 2000 +0000 + + - Added meta.c which contains functions to send, receive and broadcast + metadata. It will also handle encryption and decryption, and possibly + compression and checksumming. + - Moved request dispatcher to protocol.c. + +commit 2c412009e5805f04c650889b19fcb38531f2aa50 +Author: Guus Sliepen +Date: Mon Sep 25 20:08:50 2000 +0000 + + - Very detailed example of the authentication phase. + +commit 361690b18c1f5464db7b9cef235c648784780dfb +Author: Guus Sliepen +Date: Fri Sep 22 16:20:07 2000 +0000 + + - Removed options "string" stuff. It was a bad idea... + - free() everything that is allocated. + +commit 5afc1e98f436c4a2ed5da4b64293275b09632c79 +Author: Guus Sliepen +Date: Fri Sep 22 15:06:28 2000 +0000 + + - Severe code reduction and simplification of challenge requests + - "Finished" [add|del]_subnet_h + - Added lots of sanity checks to [add|del]_host_h + +commit 5d0b3516d5e8a46ca2268bdb32657b72295501ec +Author: Guus Sliepen +Date: Sun Sep 17 21:42:05 2000 +0000 + + - Updated authentication scheme. + - Removed all trailing spaces from all lines. + - Added things to add_ and del_subnet_h. + +commit 84f210edd9e72a65ca8b034a0d3bbc12e506c580 +Author: Guus Sliepen +Date: Sun Sep 17 20:11:59 2000 +0000 + + - Included authentication scheme from protocol.c + - Added a few comments about the symmetric cipher. + +commit 2863134a4113b7805a662f45a21a1be0ae9606cb +Author: Guus Sliepen +Date: Sun Sep 17 19:57:39 2000 +0000 + + Added document about the used cryptographic algorithms and the reasons + behind them. Feel very free to comment on this! + +commit 33a5b4547141c11b5128d9f4863fcf6cf8e33452 +Author: Ivo Timmermans +Date: Sun Sep 17 10:28:57 2000 +0000 + + Added Spanish translation of the docs by Matias Carrasco + +commit 7f3ab38c222809b15da2fe8dd655d35432eaafe0 +Author: Ivo Timmermans +Date: Fri Sep 15 12:58:40 2000 +0000 + + Second round of fixes + +commit ed397b6ac676329b237e219c806143cccf456b3c +Author: Ivo Timmermans +Date: Thu Sep 14 21:51:21 2000 +0000 + + First round of needed fixes after the overhaul + +commit 296171d115614d61480d896cd77898f5393c191d +Author: Ivo Timmermans +Date: Thu Sep 14 14:34:38 2000 +0000 + + New directive: Name. + +commit d335c6d0d7328fd86154dc60b22deb7953ab0228 +Author: Ivo Timmermans +Date: Thu Sep 14 14:32:34 2000 +0000 + + Added some structures and types that are needed for the overhaul. + +commit c04c84c98055c6b9e9e7890d3992648a3b715a1a +Author: Guus Sliepen +Date: Thu Sep 14 11:54:51 2000 +0000 + + - Lots of small changes. + +commit cd6695df82c55454a3f5b644f5c20a8ed31e7c97 +Author: Ivo Timmermans +Date: Mon Sep 11 11:40:46 2000 +0000 + + Better checks for SunOS libraries + +commit 9c75350ac6c14886195b6d368af2f118fd5d60e0 +Author: Guus Sliepen +Date: Mon Sep 11 10:05:35 2000 +0000 + + - Fixed modulo in keylength check + - Updated header file to reflect new protocol code + +commit 76b5f255c6cb0c5dfb5a870c371ec6f7c7879bb2 +Author: Guus Sliepen +Date: Sun Sep 10 23:11:37 2000 +0000 + + - Some key exchange stuff. (Last commit before going to bed.) + +commit 675ed08a71ec28d8ae99e10e993d5c7cb717f017 +Author: Guus Sliepen +Date: Sun Sep 10 22:49:46 2000 +0000 + + - Lots of functions added for the new protocol. + +commit 9926dae4646a96ee647a2ca7d728e91600dd1cca +Author: Ivo Timmermans +Date: Sun Sep 10 21:57:11 2000 +0000 + + Add Guus' name and shift out old protocol requests + +commit 74157d3f4501f4d1ec913a986b7167d2b847e41e +Author: Ivo Timmermans +Date: Sun Sep 10 18:37:46 2000 +0000 + + Correct filenames for passphrases given in the example + +commit 6b9ec9ed1e818d5e50dda4418ffb4d02c898bcba +Author: Guus Sliepen +Date: Sun Sep 10 16:15:35 2000 +0000 + + - Added more function skeletons for the new protocol. + +commit 28cc30159565a7eda4f66215a5994d84b46b47ad +Author: Guus Sliepen +Date: Sun Sep 10 15:18:03 2000 +0000 + + - New protocol. Will break everything else for now. + +commit 7884d3ecaf78006b3f288d99f10ef541fc97087e +Author: Ivo Timmermans +Date: Sun Sep 10 15:16:07 2000 +0000 + + Support for -lsocket and -lnsl on SunOS + +commit 14554e6f421e881b01be20879e9279545f375154 +Author: Ivo Timmermans +Date: Sun Sep 10 15:15:38 2000 +0000 + + Include openssl/blowfish.h + +commit 45ea3ca432a031ff1b8072d934709aadaae12534 +Author: Ivo Timmermans +Date: Sun Sep 10 15:07:41 2000 +0000 + + Updated text, removed protocol flowchart + +commit ae17572e6b94c6e7a2123ddeb45bf66d389ac7a0 +Author: Ivo Timmermans +Date: Sun Sep 10 15:05:45 2000 +0000 + + Link with OpenSSL crypto libraries instead of own blowfish library + +commit 4dde583bc91985c3ff19ac1d1f1bc791b50658ff +Author: Guus Sliepen +Date: Wed Sep 6 11:49:05 2000 +0000 + + - Use strerror() instead of sys_errlist[] for increased portability + (Needed for SunOS) + +commit 66e535a729dd5a9e45600ab74dc19c2b4062ee96 +Author: Ivo Timmermans +Date: Sun Aug 27 11:05:47 2000 +0000 + + Changed CVSROOT path in `make ChangeLog' + +commit 39e159fbe6bbffb3229542258f956fc412bd871c +Author: Guus Sliepen +Date: Tue Aug 22 14:55:04 2000 +0000 + + Fix rules (thanks to Laurence) + +commit 47992fe59f4c1b4116e4872d59251b143edc6763 +Author: Ivo Timmermans +Date: Mon Aug 21 20:35:47 2000 +0000 + + Added a rule to create an rpm + +commit d9af4f32330a495789d8eecdabbbb49928f074a7 +Author: Guus Sliepen +Date: Mon Aug 21 12:50:15 2000 +0000 + + Updated tinc.conf manual. + +commit 94a32c4b2d2ff5d4bb1376fe5ec96c6dec55f630 +Author: Ivo Timmermans +Date: Sun Aug 20 23:08:17 2000 +0000 + + Also chomp $VPNMASK + +commit 861e808fef1f6796d837215f9ad135fb4cb50f5c +Author: Ivo Timmermans +Date: Sun Aug 20 23:07:18 2000 +0000 + + (Quoting Laurence Lane:) + + The prefix is correctly set for /usr, but is + overridden with the current make install. DESTDIR is the clean way to + relocate the installation into the debian/tmp build dir. + +commit d3f41b803bf3c38910f24f1f268f182466723149 +Author: Guus Sliepen +Date: Fri Aug 18 14:45:38 2000 +0000 + + Updated the manual: + - incorporated comments from Stefan Hartsuiker + - updated configuration variables section + - added some text about key types + +commit 5c78e158d414595ab32399645678a43bb4469be6 +Author: Guus Sliepen +Date: Fri Aug 18 11:17:09 2000 +0000 + + Commented on some size calculations. + +commit d2c062a0a440d2871939b4ffdc2dbb137a4d45e7 +Author: Guus Sliepen +Date: Thu Aug 17 17:22:01 2000 +0000 + + Ran update-po and updated dutch translation. + +commit 3831f51a53088bfcc1d148fd54b3083afe7fde32 +Author: Guus Sliepen +Date: Thu Aug 17 16:51:08 2000 +0000 + + Fixed all sprintf() spl01ts. + +commit 9acd4379f705edc8b736e21b9011434e63f7dd95 +Author: Guus Sliepen +Date: Wed Aug 9 14:02:16 2000 +0000 + + - Added two extra configuration options, Interface and InterfaceIP, to + bind the listen socket to a network device or a specific IP. + +commit f6d79366b3efaef0a458717aac5e6754630dd434 +Author: Guus Sliepen +Date: Wed Aug 9 09:34:21 2000 +0000 + + - Reinstated O_NONBLOCK for meta socket + - Set SO_KEEPALIVE on meta socket + +commit 3cfc9424f255c26f2a7775b6fa059f1e3e47a76e +Author: Guus Sliepen +Date: Tue Aug 8 17:07:48 2000 +0000 + + - Moved TCP packet reception to meta handler: less kludgy and less buggy! + +commit e092d15be17db1d69c37f2aba46c66e03631c099 +Author: Guus Sliepen +Date: Tue Aug 8 14:54:57 2000 +0000 + + - Added date/time of build and protocol number to --version output. + +commit ff87f385c3a81499eff6b848aed8548cf6e5132e +Author: Guus Sliepen +Date: Tue Aug 8 13:47:57 2000 +0000 + + Removed calling add_queue for tcponly packets. + +commit ac73c72488dd8b33464fac1f392e89df48f7a23b +Author: Guus Sliepen +Date: Tue Aug 8 08:48:50 2000 +0000 + + Fixed PACKET read loop. + +commit b6997b0050e78a2f2e517beba3ff01d9232b3d1f +Author: Guus Sliepen +Date: Mon Aug 7 16:27:29 2000 +0000 + + - Lots o' buglets fixed (-Wall helps) + - Made TCPonly work :) + +commit fdc6a2f106315cd9ed22943d8c0bd279631e66b4 +Author: Guus Sliepen +Date: Mon Aug 7 14:52:16 2000 +0000 + + - Added experimental hackish tunneling-over-TCP support. + Just use TCPonly = true in the configuration file. + +commit 42455e97a057fb4386f9d8fb2f8963b2ec6ddf24 +Author: Guus Sliepen +Date: Sun Jul 2 13:40:57 2000 +0000 + + - Fixed typo. + +commit b1ecbf977722ec473fc8007acd39eb0de581de1a +Author: Guus Sliepen +Date: Sun Jul 2 13:36:18 2000 +0000 + + - Delayed address resolving for ConnectTo lines in configuration file to + allow DynDNS to work without restarting tincd. + +commit 6642ec2ea4e97a2fb3e737653ab1b9351ac759e9 +Author: Guus Sliepen +Date: Sun Jul 2 12:48:04 2000 +0000 + + - Updated THANKS file + +commit e0de803c7e80621600409a0c760241a3d97617bd +Author: Ivo Timmermans +Date: Sun Jul 2 12:41:03 2000 +0000 + + Include the Spanish translation in the distribution/build process. + +commit 721d85f77277813345bdb63a610e984cec996613 +Author: Guus Sliepen +Date: Sun Jul 2 12:35:28 2000 +0000 + + - Added Spanish translation from Enrique Zanardi. + +commit e821a22876d15c921a4c1fbc0f792d83e90916f6 +Author: Guus Sliepen +Date: Sat Jul 1 14:40:56 2000 +0000 + + - Forgot to mention ourselves in the tincd manual page! :) + +commit 09f4ec190119298187cec09dd5049af8fd8bad94 +Author: Guus Sliepen +Date: Sat Jul 1 14:32:24 2000 +0000 + + - Updated PROTOCOL (a bit) + - Included a real tincd.8 describing the options, signals, debug levels + and files used by tincd. + +commit d3ea434b3684093d6d160b8077c1f51a50ac7f61 +Author: Ivo Timmermans +Date: Sat Jul 1 10:39:28 2000 +0000 + + Autogenerated by gettextize. + +commit 1b28f88808b9ac3193cf9a0db7a81a89eed8b4ef +Author: Guus Sliepen +Date: Sat Jul 1 07:49:21 2000 +0000 + + - Removed a single unused bit from status_bits_t. + +commit 7fdc881b86fe379216f09dd5703bb88d398c87a8 +Author: Wessel Dankers +Date: Sat Jul 1 07:29:32 2000 +0000 + + Added architecture section, made a start with the kernel section. + ToDo: install tinc myself to see if everything is as I say =) + +commit 8ec648abf438bb5fcfe84e3a1c6a31192dc32b2e +Author: Guus Sliepen +Date: Fri Jun 30 22:38:58 2000 +0000 + + - Added documentation for the protocols (most important the meta protocol) + used by tinc. + +commit ce72275a4342ff4e21d21bb740ee88dca1ddb5f1 +Author: Wessel Dankers +Date: Fri Jun 30 21:16:52 2000 +0000 + + Grrr, recommit + +commit bbbdda255d6e7a8730906a1b6c2bfdd2ce1b94cf +Author: Wessel Dankers +Date: Fri Jun 30 21:11:34 2000 +0000 + + This file is now only in the CABAL revision. + +commit 28a140668f892873b01afe104d21db4adb8fd8c7 +Author: Wessel Dankers +Date: Fri Jun 30 21:09:32 2000 +0000 + + More about keys + +commit 1a1ebefd572c18d6af187750847b024ce07551ae +Author: Guus Sliepen +Date: Fri Jun 30 21:03:51 2000 +0000 + + - Made tinc even more silent if no -d flag is given at all. + +commit 79ad21c392e56cad2556e7693b9639d8e2346a59 +Author: Wessel Dankers +Date: Fri Jun 30 20:57:30 2000 +0000 + + Added extra bit about keys. + +commit 8309e9b869c25677d674f5cecb8b7ac5469d1758 +Author: Wessel Dankers +Date: Fri Jun 30 20:50:47 2000 +0000 + + File added to CABAL (hopefully) + +commit 5cd0f940c7334959534d3ab4e1f3c7cac67ee38a +Author: Wessel Dankers +Date: Fri Jun 30 20:42:07 2000 +0000 + + added bit on config file, split up sections, added Id: tag + +commit 6f5aac4e39cd6fb2fb76c0121de3f3782f72f18e +Author: Wessel Dankers +Date: Fri Jun 30 20:16:15 2000 +0000 + + Initial revision. Lots of loose ends, not usable yet. + +commit c5737583c8a5d099a71174e1eb997e0972ae03e9 +Author: Guus Sliepen +Date: Fri Jun 30 12:41:06 2000 +0000 + + - Instead of logging an error when remote end closes the connection, + we print a nice message if appropiate debug level is set. + - If we get ADD_HOSTs or DEL_HOSTs for ourself, then connection lists + are really messed up. We restart, and hope our problems go away. + +commit 24874d0806bac5d75663ea9de67a71171bfc97b6 +Author: Guus Sliepen +Date: Fri Jun 30 11:45:16 2000 +0000 + + - Removed segfault bug in conf.c (must have been there for ages!) + - Made main_loop() signal proof + - #defined MAXTIMEOUT (15 minutes) + - If something really really bad happens, close all connections, wait + for MAXTIMEOUT seconds, and then restart tinc + +commit 0f9ad1f047efec53590dc43f07d225e5f20456cb +Author: Guus Sliepen +Date: Thu Jun 29 19:47:04 2000 +0000 + + - Fixed memory leak. + - Implemented SIGHUP configuration file reloading. + - Other small changes. + +commit 18c85caac36f7236454deef11b9eba74328dbd96 +Author: Guus Sliepen +Date: Thu Jun 29 17:09:08 2000 +0000 + + - New semantics for BASIC_INFO, ADD_HOST and DEL_HOST requests. This will + improve connection list consistency, ensures the tree property, and + allows for recovery from situations where track of connections is lost. + +commit e8e7379311ca3bf6e1fdd7d0f477a43e510e2317 +Author: Guus Sliepen +Date: Thu Jun 29 13:04:15 2000 +0000 + + - Removed all IP_ADDR_S macros, because gettext doesn't like them. Each + connection now has two hostnames: real_hostname (replacing the old), + and vpn_hostname. In those places where hostnames really aren't usefull + IP_ADDR_S has been replaced by %d.%d.%d.%d. + +commit e0ddb638d1fb7abf19969ac887f3b7a2bd8225c1 +Author: Guus Sliepen +Date: Thu Jun 29 07:11:23 2000 +0000 + + - Updated Dutch translation. + +commit 0a155580a3d55633bbc3a1e7dcbe8906f41913be +Author: Ivo Timmermans +Date: Wed Jun 28 21:06:40 2000 +0000 + + Oops, and mention Guus too. + +commit f2c9e7f3bbada3fbfe80f622ebc06540afb60c21 +Author: Ivo Timmermans +Date: Wed Jun 28 21:01:45 2000 +0000 + + Removed Free Software Foundation copyright, because Guus Sliepen contributed significantly. + +commit 3df9b89204626afdd514d5b7323801af76a5cd26 +Author: Guus Sliepen +Date: Wed Jun 28 14:34:40 2000 +0000 + + - Added log message when SIGCHLD is received ("thanks" to Ivo van Dong) + +commit 8c6c60adf3d5942c6368bafe9a4d4377ffad1abe +Author: Guus Sliepen +Date: Wed Jun 28 13:41:02 2000 +0000 + + - Fixed a message in nl.po + - Woops, we forgot to send our connection list to our uplink when we + connect to it... Fixed. + +commit 63c5192d570e2ba5952b4e5a807e4ab4d6fdad76 +Author: Guus Sliepen +Date: Wed Jun 28 11:39:40 2000 +0000 + + - Fixed missing " in nl.po + +commit ea40d3f1a05e9edf4ccfb77f4e9e0f8355e94a83 +Author: Guus Sliepen +Date: Wed Jun 28 11:38:01 2000 +0000 + + - Fixed some spelling errors. + - Paar zpelvautjes gerepareerd, en de Nederlandse vertaling weer bij de + tijd gebracht. + +commit dba2995db73313b1c0a56ce13395dac0bc7571a5 +Author: Guus Sliepen +Date: Wed Jun 28 10:11:10 2000 +0000 + + - Extra check op EINTR bij inlezen requests + +commit 4ee53e7dac93d1edad8664edffdfaf142438b85d +Author: Guus Sliepen +Date: Tue Jun 27 21:05:07 2000 +0000 + + - Fixes a silly little insignificant buglet. + +commit 070ad08118a33755835b31174e2b04e84f75556e +Author: Guus Sliepen +Date: Tue Jun 27 20:55:12 2000 +0000 + + - Purge old connections that are ADD_HOSTed. + +commit 4aeaea5e590fbd38aebbfacf2672304d04ba4ad1 +Author: Guus Sliepen +Date: Tue Jun 27 20:10:48 2000 +0000 + + - Improved handling of errors on connection attempts. + +commit 45a28b1e893d4da9d7977945a35ec6a8e4554830 +Author: Guus Sliepen +Date: Tue Jun 27 15:08:58 2000 +0000 + + - Fixed indirectdata=no problem + - Added support for multiple ConnectTo lines in tinc.conf. + +commit 4faed1b8546563def6a426c563cec2a26d927eda +Author: Guus Sliepen +Date: Tue Jun 27 12:58:04 2000 +0000 + + - Fixed KEY_CHANGED notification. A lot of notify_others() calls were + wrong (first two arguments swapped). Should probably be doublechecked. + - Don't retry to connect to hosts with different protocol versions. + +commit 04cb206298df033d254ca007205d13f9a670c402 +Author: Guus Sliepen +Date: Mon Jun 26 20:30:21 2000 +0000 + + - Moved all connection messages to debug level 1, without -d's only the + startup message will be logged. + - Fixed DEL_HOST rebound. + +commit 783c8298610d5670f6e118f49bd3d1fdfa61ae1d +Author: Guus Sliepen +Date: Mon Jun 26 19:39:34 2000 +0000 + + - Indirectdata finally REALLY REALLY works now! + - More precise debug messages + +commit b3681ebf6c255daf082ed254282cbf493af8fa93 +Author: Guus Sliepen +Date: Mon Jun 26 17:20:58 2000 +0000 + + Fixes some hostlookups. Fixes indirectdata for real now (hopefully). + +commit 03af6d8c8056d0b7006f7d8fb19bb33d303ac8f9 +Author: Ivo Timmermans +Date: Sun Jun 25 20:52:29 2000 +0000 + + Version 1.0pre3. + +commit a473ece8a0d83be5f7992888a6a3ff938dc4fb72 +Author: Guus Sliepen +Date: Sun Jun 25 16:39:17 2000 +0000 + + - More verbose connection list + - Added "myself" as hostname when logging indirect ADD_HOSTs + +commit f1f901112e44beaecd3037dae27407ea83edd86e +Author: Guus Sliepen +Date: Sun Jun 25 16:20:27 2000 +0000 + + Hostlookup() is actually being called now. + +commit 54079bdf03e74c686f556f86082b9d14b5be227c +Author: Guus Sliepen +Date: Sun Jun 25 16:01:12 2000 +0000 + + Hostnames are back! + +commit e4b586ed070908f866a450292f9759004e6affa8 +Author: Guus Sliepen +Date: Sun Jun 25 15:45:09 2000 +0000 + + - Log possible spoofing attacks. + - Don't broadcast DEL_HOSTs for hosts that haven't been activated yet. + - If a host sends a TERMREQ, deactivate them. + +commit 9a1103a7be86de3da5548fd6446e6e4fe554cc08 +Author: Ivo Timmermans +Date: Sun Jun 25 15:42:40 2000 +0000 + + Changed version number to 1.0pre3. + +commit d8d2b83350e890adae9c9cede6e21ea4169abe00 +Author: Ivo Timmermans +Date: Sun Jun 25 15:42:40 2000 +0000 + + Changed version number to 1.0pre3. + +commit 7648bc606596851942dd6437ddaa93f53ab20f09 +Author: Guus Sliepen +Date: Sun Jun 25 15:22:16 2000 +0000 + + Added CVS Id tags to header files. + +commit 7f7e158aae8df5c65211bcfa82516e7c243cdd2e +Author: Guus Sliepen +Date: Sun Jun 25 15:16:12 2000 +0000 + + Large cleanup: + - Removed hostname lookup (it blocks, and you can always do it yourself) + - Reorganized debug levels (after hints from Axel M�ller): + 0 Startup message and errors + 1 Connection logging + 2 Meta protocol information + 3 Verbose meta protocol (includes copy of transmitted requests) + 4 Packet information (logs transmission/errors of UDP packets) + 5 Verbose packet information (every single byte, not implemented yet + to protect ourselves from filling up /var/log directories) + - Made log messages more consistent + +commit 3c54a513b0c0a3acac60e03403ab4abfa0688c62 +Author: Guus Sliepen +Date: Sat Jun 24 12:35:42 2000 +0000 + + If we have "indirectdata" flag set, we only send data to our uplink. + +commit d8e2f7104c3203edbf23d2349656c765a4310dee +Author: Guus Sliepen +Date: Fri Jun 23 19:27:03 2000 +0000 + + First step for implementation of the "indirectdata" directive. This should + allow _leaf_ tincds to be behind firewalls. + The protocol has changed and is INCOMPATIBLE with previous versions. The + PROT_CURRENT value has been incremented. + +commit 33c3a25a66251606cbf20d3bd5b392d8837116e3 +Author: Ivo Timmermans +Date: Sat Jun 17 20:55:54 2000 +0000 + + Configuration directive `IndirectData'. + +commit 1c8adb5e1f12894fc9a478fbf29678fb662e03ab +Author: Ivo Timmermans +Date: Sat Jun 17 20:30:44 2000 +0000 + + Merge changes from 1.6-1.8. + +commit 0d167e1f5d8778674a9a77b2256050e3afe2896e +Author: Guus Sliepen +Date: Sat Jun 17 08:30:45 2000 +0000 + + Added another semicolon for bash2 compliance (thanks to Jamie Briggs) + +commit 00f316810aa808368cdff620b1a1efdd1fcade20 +Author: Guus Sliepen +Date: Fri Jun 16 05:44:26 2000 +0000 + + Applied patch from Jamie Briggs for bash2 conformance. + +commit ef294a69678bc7cba6d2ee0be96f683249672222 +Author: Ivo Timmermans +Date: Tue Jun 6 10:24:33 2000 +0000 + + Include ../intl in the include path, and add @INTLLIBS@ to the list of libraries. + +commit 66e98068051bc52fa064650710260f89c09f8cfd +Author: Ivo Timmermans +Date: Sun Jun 4 12:14:31 2000 +0000 + + These files are created by gettextize (run by autogen.sh) (should have known that). + +commit d1d4a524dee9d75b067ac8e25770557cf22f4afe +Author: Ivo Timmermans +Date: Sun Jun 4 11:50:46 2000 +0000 + + Check for __gmpz_powm for libgmp3. + +commit 377c4df245ceb8c19cabfe6d7a7c76841c07ba52 +Author: Ivo Timmermans +Date: Sat Jun 3 23:32:03 2000 +0000 + + Don't touch VPNMASK if it's defined, otherwise use $MSK. + +commit 9193aee8159ce53b349557ba1ad8ed23111042bb +Author: Guus Sliepen +Date: Sat Jun 3 08:27:16 2000 +0000 + + Removed items in TODO list that are already implemented. Only two items + left. + +commit 5796d2f5b7310fa8841f76bbc7bbcf2385d960c3 +Author: Ivo Timmermans +Date: Fri Jun 2 17:30:33 2000 +0000 + + Alphabetized the list, added Lubom�r Bulej, removed Sander Smeenk and Tijs van Bakel, put merits after all names. + +commit 18b3084d2525c59f62b75346fa657ccce6459712 +Author: Guus Sliepen +Date: Thu Jun 1 20:21:27 2000 +0000 + + Debian init.d script automatically sets tap device's MTU to 1448 now. + +commit 77be52422d8c28735f787b1c233b4cec73d4db56 +Author: Ivo Timmermans +Date: Wed May 31 18:23:06 2000 +0000 + + Miscellaneous copyright updates. + +commit 8cb4bb619d777022a55255c5fa17a1a55a270ff3 +Author: Ivo Timmermans +Date: Wed May 31 18:21:27 2000 +0000 + + Handle locale settings. + +commit f20df109a638ac3a86efa70fac39e1dae8e87208 +Author: Ivo Timmermans +Date: Wed May 31 18:19:33 2000 +0000 + + Version 1.0pre2-1. + +commit 4ae74c50b7faadf31086bc61af0f8158a465e521 +Author: Ivo Timmermans +Date: Wed May 31 18:18:21 2000 +0000 + + Updated Dutch translation. + +commit 7037286586151e28b7c5f1fe09dd6c5faca18cdc +Author: Ivo Timmermans +Date: Wed May 31 18:17:45 2000 +0000 + + Tell about /etc/tinc/nets.boot. + +commit 65a9eedb05387b8cf77dbbbc56347b44a28de624 +Author: Ivo Timmermans +Date: Wed May 31 18:17:27 2000 +0000 + + Include news for 1.0pre2. + +commit 17fa07510ad74d0f96f9700538d32eb8e7b2a0ce +Author: Ivo Timmermans +Date: Tue May 30 21:36:16 2000 +0000 + + Only accept an ADD_HOST request for a host that already exists in our conn_list if the nexthop field matches the sender. This is a workaround for older clients. + +commit e7f22d2f5f0a5fcd52da7512ab734b0ba52c623f +Author: Ivo Timmermans +Date: Tue May 30 12:38:15 2000 +0000 + + In terminate_connection, only send a notification to hosts that are directly connected to us. (DEL_HOST gets forwarded automatically.) + +commit 2fdda8e4fa6c6ace5f7e9421f0644a3ffec388c9 +Author: Ivo Timmermans +Date: Tue May 30 12:31:41 2000 +0000 + + When a connection is terminated, all hosts that are still connected get notified of the lost connections. + +commit f826301889e1fa1a22770919f0385c3ca04c740a +Author: Ivo Timmermans +Date: Tue May 30 11:18:12 2000 +0000 + + Added new configuration directive `Hostnames', which controls the resolving of IP addresses to hostnames. + +commit a7ad161d2b115b6a2a69c5dc8ddd33008d3562d0 +Author: Guus Sliepen +Date: Mon May 29 23:40:05 2000 +0000 + + Only activate a connection upon receiving it's public key if it's an + incoming connection. When it's outgoing, we need to receive an ack first. + +commit 5654e156a31d05ac3026790f7749d0401b2eaabc +Author: Ivo Timmermans +Date: Mon May 29 22:27:15 2000 +0000 + + Updated changes list for version 1.0pre2. + +commit a822c7466aa91a819c498336f91c63d224c3af11 +Author: Ivo Timmermans +Date: Mon May 29 22:20:04 2000 +0000 + + Bounds check for request id (between 0 and 255). + +commit 0f2cf48d304e20abb9b3cded2aaa693828c9d412 +Author: Ivo Timmermans +Date: Mon May 29 22:15:38 2000 +0000 + + Dutch translation of tinc. + +commit 386a62ff57f283b415fd757a8c4645b24c3bd3bb +Author: Ivo Timmermans +Date: Mon May 29 21:40:51 2000 +0000 + + Define LOCALEDIR in CFLAGS. + +commit 4cd009f774e4c50cdacc06d351cac19ca3247b6b +Author: Ivo Timmermans +Date: Mon May 29 21:40:20 2000 +0000 + + Include GNU gettext checks. + +commit 5814939c9d0e801bdbed6c96092fd90b6dcd859c +Author: Ivo Timmermans +Date: Mon May 29 21:38:02 2000 +0000 + + Update acconfig.h to include values for gettext inclusion. + +commit b200b0d812763563dbe09e5da116c55e45f89e4f +Author: Ivo Timmermans +Date: Mon May 29 21:36:28 2000 +0000 + + Include system.h and ABOUT-NLS. + +commit b9ea0633c7243de552d581f4486902c67aefd695 +Author: Ivo Timmermans +Date: Mon May 29 21:04:55 2000 +0000 + + Include intl/ directory in the list of subdirs. + +commit 9fd02ffcb0cacf3de26e876de5f30510bff137a3 +Author: Ivo Timmermans +Date: Mon May 29 21:01:26 2000 +0000 + + Internationalization of tinc. + +commit 61e71ab74ad9b5edb044b84ccf1111a33eb468cb +Author: Guus Sliepen +Date: Sat May 27 20:23:01 2000 +0000 + + Terminate a connection on any error. Furthermore, disallow del_host, + add_host and other important requests until remote host has properly + authenticated itself. + +commit cc01b18bc6d0bfb12e6770fc0a007c278f355d9e +Author: Guus Sliepen +Date: Sat May 27 19:44:04 2000 +0000 + + Made tinc persistent. If no outgoing connection can be established right + after the start of the daemon, it won't quit anymore but will retry in 5 + minutes. Also, 5 minutes is now the maximum time to wait for a retry. + +commit 028659bfbf164cb7a72831506896e291010b251f +Author: Guus Sliepen +Date: Sat May 27 19:23:20 2000 +0000 + + Fixed typos. When terminating a connection, it's status is not only set to + remove=1 but also active=0. + +commit e4ff969a9868ecc25a85daab620f97227de8d493 +Author: Guus Sliepen +Date: Sat May 27 19:04:12 2000 +0000 + + Fix for a DoS attack: + A remote user could telnet to the tinc daemon and type only this line: + 61 6 00000000/00000000:28f + This would deny any packets to be sent to other tinc networks (except + for to the hosts that run tincd's themselves). Solution is to skip + hosts in lookup_conn() that have not been activated yet. + Fixed potential conn_list table corruption: + If a new connection is accepted but a connection with the same subnet + would already exist in the connection list, the OLD connection is + terminated. + +commit 4d71de15e8abd137702a5dc04a743d246c3f1110 +Author: Guus Sliepen +Date: Sat May 27 13:21:20 2000 +0000 + + Documentation updates. Removed all references to configuration variable + "AllowConnect", since it is NOT used in tinc. Added information about + "VpnMask". Elaborated a bit about "private" and "virtual" networks. + +commit 85e3c1f2716c622ca8cada83d833703bf8a3ecc6 +Author: Ivo Timmermans +Date: Fri May 26 11:25:59 2000 +0000 + + Updated by Lubomir Bulej and Mads Kiilerich: it uses /etc/tinc/nets.boot and the VpnMask directive in the config files. + +commit 3a6ffe6895b681377a9553c01e3777f499b90d4a +Author: Ivo Timmermans +Date: Sun May 21 23:01:28 2000 +0000 + + Create an empty /etc/tinc/nets.boot. + +commit b9a86ec70ed4ffe5009c4979454f0d99c8559b45 +Author: Ivo Timmermans +Date: Sun May 21 22:40:41 2000 +0000 + + Use /etc/tinc/example as a base directory for an example. /etc/tinc/example/README points to /usr/share/doc/tinc/README.Debian. + +commit 63847abdfdad03a69bfd967929336e113cdeb09e +Author: Ivo Timmermans +Date: Sun May 21 22:38:01 2000 +0000 + + Add an example of using VpnMask. + +commit 2469acc0900edeb8f1e3263fbf58bf74639c1b12 +Author: Ivo Timmermans +Date: Sun May 21 22:27:31 2000 +0000 + + When VpnMask is not present in the config file, silently use $MSK as vpnmask. + +commit 73b3e7ce03cacb644a8101610933b221fdf432d6 +Author: Guus Sliepen +Date: Sun May 21 22:21:38 2000 +0000 + + Fixed last typo. Init.d now uses ifconfig command to set both the tap's IP + address as well as the correct route. Furthermore, if no VpnMask is given, + a default of 255.255.0.0 is chosen and a warning issued. + +commit 2ad4f1cc5b6013be2deee82b0cb3f731adb51616 +Author: Guus Sliepen +Date: Sun May 21 22:08:21 2000 +0000 + + Typo. + +commit e25fc3a3dc4bc407bd0645fb9891ac127a83f468 +Author: Guus Sliepen +Date: Sun May 21 22:04:56 2000 +0000 + + VpnMask truely works now. + +commit 9ec4decec17f95cc7d5be66cc18bb040cce84d47 +Author: Ivo Timmermans +Date: Fri May 19 01:17:32 2000 +0000 + + Mask the vpn net with the vpn netmask, route would give an error if the netmask didn't match the net. + +commit 20e404ab5716b06b53a4a5443f8098f227770907 +Author: Ivo Timmermans +Date: Fri May 19 00:58:01 2000 +0000 + + Fixed typo. + +commit 44af1094be90878bd6fc09c40882cf2463046908 +Author: Ivo Timmermans +Date: Fri May 19 00:33:44 2000 +0000 + + Updated copyright notice. + +commit 01352f4c525862f05988ed8687f26210c5ba10a2 +Author: Ivo Timmermans +Date: Fri May 19 00:15:37 2000 +0000 + + Errors will not terminate the script or result in a nonzero exit code. + +commit 4ef2a8cfdb13c7eb2d811fc8c9f04df8970293c5 +Author: Ivo Timmermans +Date: Fri May 19 00:14:34 2000 +0000 + + Include postinst in the distribution. + +commit 59ca017df4c9d0f7861693b4d2ec4b7dc8c98b1e +Author: Ivo Timmermans +Date: Fri May 19 00:09:20 2000 +0000 + + Find networks in instead of . + +commit 0354962c9885f04801d8469214c172cc012cdcec +Author: Ivo Timmermans +Date: Thu May 18 23:33:44 2000 +0000 + + Don't distribute the file files. + +commit b56705e18ceec9234578d7ac12939f7c59cff066 +Author: Ivo Timmermans +Date: Thu May 18 23:28:51 2000 +0000 + + Version 1.0pre2-0.3 + +commit cbf6efb617f45ffc608fe5f61d09abdd85f444ad +Author: Ivo Timmermans +Date: Thu May 18 23:18:54 2000 +0000 + + Create a default /etc/tinc/nets.boot after installation, containing all directories under /etc/tinc by default. + +commit e7d583adfaa50370d20f4cfe88ba5b6da399911d +Author: Ivo Timmermans +Date: Thu May 18 23:09:31 2000 +0000 + + Read /etc/tinc/nets.boot to find the networks that have to be started. + +commit 8d4ab991b8c35382c9cd46dd65af873d9d08f63f +Author: Ivo Timmermans +Date: Wed May 17 23:13:51 2000 +0000 + + This file is generated with dpkg-buildpackage. + +commit ffc79bcd20b2b8085c906a446318817808bc36ae +Author: Guus Sliepen +Date: Tue May 16 16:07:15 2000 +0000 + + TODO file reinstated: + - Append your name to items if you're working on them. + - Remove them if you fixed the problem/implemented that feature. + - Add any (suspected) bugs. + +commit cdab82d6fb7d7d32194cb2162a814fbc89b7db4c +Author: Ivo Timmermans +Date: Tue May 16 14:34:44 2000 +0000 + + Use the new VpnMask directive to add a route to the rest of the VPN. + +commit 85963f4c857abc2d9a4c5a3245cc11257140b9a6 +Author: Guus Sliepen +Date: Tue May 16 13:09:15 2000 +0000 + + Stub for VpnMask config directive. + +commit 30aff5ea2aebcfc0e97e60e73ed3edc2363634a0 +Author: Ivo Timmermans +Date: Tue May 16 13:03:32 2000 +0000 + + Look if the tap devices exist before bluntly remaking them. + +commit 0761eed64c4d6d2b8e9fa6a335ccdca8ea4b95db +Author: Ivo Timmermans +Date: Tue May 16 07:56:05 2000 +0000 + + *** empty log message *** + +commit 0a2e2b0c8d20baf22b550f735b1fe63b0a1d377a +Author: Ivo Timmermans +Date: Mon May 15 19:48:46 2000 +0000 + + Depend on perl5. + +commit 7e817fcf0fdd25aae58259930006c61048b017cd +Author: Ivo Timmermans +Date: Mon May 15 18:28:45 2000 +0000 + + Unlimited length in the config file, thanks to Cris van Pelt. + +commit b18af982af810ff4c050891ad2026960c43620a0 +Author: Ivo Timmermans +Date: Mon May 15 17:15:52 2000 +0000 + + Exit with zero status if is empty. + +commit 4711a87922c84241e9bb312755d7b943ea8ae4b6 +Author: Ivo Timmermans +Date: Mon May 15 15:54:37 2000 +0000 + + Updated to newer version. + +commit a0c4e7fe6d46988f3fb1100ef00db7b747c86f72 +Author: Guus Sliepen +Date: Mon May 15 09:41:34 2000 +0000 + + Test for existence of configured tinc networks. This will also make + first install of tinc possible without errors. + +commit 265bda08cd00feebb68243d4079854916b03638e +Author: Ivo Timmermans +Date: Sun May 14 23:03:37 2000 +0000 + + .deb version number 1.0pre2-0.4. + +commit 7a450d704b5a242f8bf9129af60593c90c63df5a +Author: Ivo Timmermans +Date: Sun May 14 23:00:44 2000 +0000 + + tincd->tinc + Delete libblowfish.y not be in the .deb. + +commit 7fbfa990fcd38b8241281ce6f1a4e2992239986f +Author: Ivo Timmermans +Date: Sun May 14 22:59:47 2000 +0000 + + Mention both upstream authors. + +commit f7b04ea142623a43413f74e19b1b6a9a247647ff +Author: Ivo Timmermans +Date: Sun May 14 22:59:19 2000 +0000 + + Add description, better dependancies. + +commit 9f07fe55dc4930920b9a5909d7057ca7bc16bad9 +Author: Ivo Timmermans +Date: Sun May 14 22:58:47 2000 +0000 + + Add initscript, tincd->tinc. + +commit df10baa50c3b421b03ac9eeaed4a4a19a47f611e +Author: Ivo Timmermans +Date: Sun May 14 21:18:10 2000 +0000 + + Inserted useful content. + +commit 6c722da77cc9185e48e22818ef88f2a88cf2efc7 +Author: Ivo Timmermans +Date: Sun May 14 21:14:23 2000 +0000 + + Add shlibs control file for the blowfish library. + +commit 803f908078e87f433727a3ddf2d61734e1ed9233 +Author: Ivo Timmermans +Date: Sun May 14 21:07:16 2000 +0000 + + Give IP address instead of hex number when connecting tcp socket failed. + +commit 4b1a1c2123626b50bd1a5382867986260440e9e7 +Author: Ivo Timmermans +Date: Sun May 14 21:04:53 2000 +0000 + + Changed version to 1.0pre2. + +commit ca900d388b996c629f0c87c7a62efb52bd219065 +Author: Ivo Timmermans +Date: Sun May 14 20:58:34 2000 +0000 + + Version 1.0pre1-0.1. + +commit 7d433ebd7610e0ff7e7b4c59979c446c0a1dfd03 +Author: Ivo Timmermans +Date: Sun May 14 20:56:41 2000 +0000 + + Add check for mpz_powm in libgmp3. + +commit de09916eadd4c558937d1a6367f5319ca26ed07c +Author: Ivo Timmermans +Date: Sun May 14 13:50:10 2000 +0000 + + Only print an error with send_termreq if debug_lvl is 2 or more. + +commit 9d023b1f2e7750f4a0e506c0f61498a44c0b95a8 +Author: Guus Sliepen +Date: Sun May 14 13:06:52 2000 +0000 + + Fixed typos. + +commit e20e143f1e99bdc0a7d92e97da1bd0dc40e8a83b +Author: Guus Sliepen +Date: Sun May 14 13:02:20 2000 +0000 + + Changed ping behaviour (backwards compatible). If we don't have any data + to send, we don't need to check if the connection is still alive. + Furthermore, if we receive any kind of data from the other end, we know + it's alive, so we don't need to check it either. So, PING requests are + only sent if we send packets but there is no response. + +commit ee96ccabbbf0180d5631d3c22838456f28ee9c15 +Author: Guus Sliepen +Date: Sun May 14 12:22:42 2000 +0000 + + Cleanups. + +commit 8caa1b9d750bb7467d1c3330780b05ac2bbf9883 +Author: Guus Sliepen +Date: Sun May 14 11:39:18 2000 +0000 + + Proxymode removed. + +commit 269067bb22e8f80deb43d3ac903f4e0d67af63d2 +Author: Ivo Timmermans +Date: Sat May 13 00:54:27 2000 +0000 + + Perl version of the system startup script. + +commit 12adf1af548b7d2f2baa4be16d2df956048b7855 +Author: Ivo Timmermans +Date: Fri May 12 13:31:00 2000 +0000 + + Deleted the protocol description. + +commit d0ba34ccae02d07051bc3f7012a6c116cfb3b653 +Author: Guus Sliepen +Date: Mon May 8 18:44:15 2000 +0000 + + Added new config variable "ProxyMode". If enabled, all outgoing packets + are sent to the uplink (ConnectTo), which will have to forward them for + us (kernel should do that). This is for people behind firewalls. + +commit 92387475ace9b06af39987c71ac563cf29427009 +Author: Ivo Timmermans +Date: Fri May 5 10:48:54 2000 +0000 + + Added semicolons required by bash2 (Mads Kiilerich). + +commit bce2179fe350bf34cde0caab97f72c0930539840 +Author: Ivo Timmermans +Date: Thu May 4 23:26:24 2000 +0000 + + Copied most of the code from the redhat script. + +commit 74b0cbecce5194dc5c594cc4e2aa3e97c14ea6c1 +Author: Ivo Timmermans +Date: Thu May 4 23:17:02 2000 +0000 + + Include sys/types.h. + +commit 2f7e532d703bbf6997ae04658379df0b0d844f62 +Author: Ivo Timmermans +Date: Thu May 4 23:16:43 2000 +0000 + + Don't link in libdl. + +commit d4ef7ea0e79ee0d2b7063893f7af5ece886d838b +Author: Ivo Timmermans +Date: Thu May 4 00:01:05 2000 +0000 + + Check for the existance of libdl. + +commit 87ccd613cab1947878ef60e3c927f717df089233 +Author: Ivo Timmermans +Date: Thu May 4 00:00:50 2000 +0000 + + More for getopt support. + +commit 6182664859383a86a47846cafdc1f6fcd73b5a76 +Author: Ivo Timmermans +Date: Thu May 4 00:00:06 2000 +0000 + + Include stdio.h for fprintf. + +commit 88a8826cf72297a784d597ba5a2b47058e1faf72 +Author: Ivo Timmermans +Date: Wed May 3 23:47:06 2000 +0000 + + getopt_long() support for platforms that don't have it. + +commit 3d218a31145cf6a4c625ed287cdf3f99e4fd9a03 +Author: Ivo Timmermans +Date: Wed May 3 23:00:38 2000 +0000 + + Don't use error.h or error(), put #error in front of cpp errors. + +commit a083b1cf305f3d241f2f4b36968a5b1ed9117612 +Author: Guus Sliepen +Date: Wed May 3 18:02:15 2000 +0000 + + Squashed gcc warning. + +commit 78532475238b23eb52ac88d905fbf966d97a79d2 +Author: Guus Sliepen +Date: Wed May 3 17:59:07 2000 +0000 + + Fixes typo and UDP network byte order. + +commit 505b5ec2cd9d6cf3dc655284a8c4041ce8527a07 +Author: Guus Sliepen +Date: Wed May 3 15:37:32 2000 +0000 + + Outgoing packets now use network byte order in header. + +commit 2bc7a0c92831802eec167ad193515962a63690dd +Author: Ivo Timmermans +Date: Wed May 3 15:01:54 2000 +0000 + + Fix a typo, better handling of the info document. (from Mads Kiilerich) + +commit 89610e3fbada1dee79769b8146a500c8357fd81d +Author: Guus Sliepen +Date: Tue May 2 10:16:50 2000 +0000 + + Replaced sprintf() by safer snprintf(), removed possible buffer overflow + by one byte. + +commit aeccaca829842910b4a5c8a5fa61e1738492bea6 +Author: Guus Sliepen +Date: Tue May 2 09:55:34 2000 +0000 + + Previous fix fixed. Meta protocol should be really flawless from now on! + +commit 989d7edc07fd407e7f7838b45986f4e37359ef97 +Author: Guus Sliepen +Date: Tue May 2 09:10:33 2000 +0000 + + Fixed small mistake that would prevent forwarding requests. + +commit 069c146656b8f952e465492c53ab5b514e959565 +Author: Ivo Timmermans +Date: Mon May 1 22:00:02 2000 +0000 + + Mentioned new metaprotocol. + +commit bd0325655867b1dff740d52d0505773bba0606a6 +Author: Ivo Timmermans +Date: Mon May 1 21:47:12 2000 +0000 + + More tincd->tinc updates. + +commit a9247e6f2c57bda9dc62ed050f41048847109e83 +Author: Ivo Timmermans +Date: Mon May 1 21:31:59 2000 +0000 + + Fixed meta protocol. + +commit 9ea27f76fab3663c9c83a7fe7de95f74cbfd59be +Author: Ivo Timmermans +Date: Mon May 1 21:31:17 2000 +0000 + + Committed by Mads Kiilerich. + +commit a92604fa5dffef589fc3042c5ae09ae8878e8cff +Author: Ivo Timmermans +Date: Mon May 1 19:17:09 2000 +0000 + + Updates by Mads Kiilerich. + +commit ca6abd41ea0cdf2ca6491c3945fb3c62fd40ab98 +Author: Guus Sliepen +Date: Mon May 1 18:07:12 2000 +0000 + + Meta protocol overhaul. Tinc is now incompatible with previous versions, + furthermore this version does NOT work yet because of a problem with + sending keys (these should be converted to base36 or something like that). + It is possible to telnet to the tinc daemon now and type some commands + by hand though :). + +commit 3219be5770716bdb0c8b6e9e4c674a447c5085f2 +Author: Ivo Timmermans +Date: Mon May 1 16:28:28 2000 +0000 + + Committed by Lubom�r Bulej. + +commit 33cfdf43f4309c17d6df811b3c5d0af3a1c8679f +Author: Ivo Timmermans +Date: Sun Apr 30 20:48:48 2000 +0000 + + Key forwarding, write one byte extra. + +commit 75d351eaf1264cfb7aa47166469e8ec722712a89 +Author: Ivo Timmermans +Date: Sun Apr 30 19:49:49 2000 +0000 + + Protocol fix (ANS_KEY). This breaks 0.3.3 protocol compatibility. + +commit b4290c3f4360f3cf01bb44957da0d8a20eac75f3 +Author: Ivo Timmermans +Date: Sun Apr 30 19:03:00 2000 +0000 + + Send one less byte from an ANS_KEY request. + +commit d878230ebef5f1a14a23c266dc425666d9e805eb +Author: Ivo Timmermans +Date: Sun Apr 30 18:57:16 2000 +0000 + + Read one less byte from an ANS_KEY request. + +commit 789a4c4f400de31d43b9c5f349f1de417443074a +Author: Ivo Timmermans +Date: Sun Apr 30 16:34:31 2000 +0000 + + Removed debug messages. + +commit eb1c9814e6b2a5206be1fadf19e0dc779690a69e +Author: Ivo Timmermans +Date: Sun Apr 30 16:31:23 2000 +0000 + + Read public keys the right way (tm). + +commit ca73b722cbad5a08ec9bb5026ed5129da9a24bd8 +Author: Ivo Timmermans +Date: Sun Apr 30 16:11:05 2000 +0000 + + New way of handling the meta protocol. + +commit cd12345032e8547a50a1f7450814364f39f0c4ec +Author: Ivo Timmermans +Date: Sun Apr 30 13:23:53 2000 +0000 + + Replaced check for status.active by status.dataopen in check_network_activity. + +commit 4b076ee87fcf8aaf1d9a2bd3c27524b4e3840167 +Author: Ivo Timmermans +Date: Sun Apr 30 01:16:51 2000 +0000 + + Initially, the vpn_mask of a connection is 255.255.255.255 to avoid confusion with lookup_conn. + +commit 1c007c0627ad5e71b8218fcb086240970e955c87 +Author: Ivo Timmermans +Date: Sun Apr 30 01:15:47 2000 +0000 + + Got rid of the nasty hacks... and replaced it by another one. + +commit c02745991422ac3d8097b126e8b256a9b33ad24b +Author: Ivo Timmermans +Date: Sat Apr 29 20:39:36 2000 +0000 + + Filled up the protocol structs with unused bytes. + +commit d3e8e8ca54928e48400584d8a70c42bbf4ae6aeb +Author: Ivo Timmermans +Date: Sat Apr 29 20:38:23 2000 +0000 + + Added `deb' target. + +commit 4dbf7022a25e678969856a38501318db4d420936 +Author: Ivo Timmermans +Date: Sat Apr 29 13:56:06 2000 +0000 + + More updates wrt. the change from tincd->tinc. + +commit 23715510149179089952eef0a2d6f87571ac0e7e +Author: Guus Sliepen +Date: Fri Apr 28 11:33:25 2000 +0000 + + Oops! Reference to write_n() removed and changed into neat write() call. + +commit bb8fff92e1bc594a085c2cbd12b215d334695feb +Author: Guus Sliepen +Date: Thu Apr 27 20:57:18 2000 +0000 + + Removed write_n() function. + +commit 4fec0cc45774ba313d1823cc64c3afdda3204a2e +Author: Ivo Timmermans +Date: Thu Apr 27 13:47:51 2000 +0000 + + Default config file name is tinc.conf, and pidfile is tinc.pid. + +commit eebb708cb29a121ea8d58bb6ca6caf41dea3c3b4 +Author: Ivo Timmermans +Date: Thu Apr 27 00:07:17 2000 +0000 + + Updated version number to 1.0. + +commit 5797d3fcb1ff56ad3ff577f7eb988b70f9d4d709 +Author: Ivo Timmermans +Date: Thu Apr 27 00:01:00 2000 +0000 + + Filled in the details, license from libblowfish copied. + +commit a3ccc15ac0979c4103f98e740b525634e8e17a0a +Author: Ivo Timmermans +Date: Wed Apr 26 23:56:22 2000 +0000 + + Version to 1.0pre1; + Create Makefile and build in debian/. + +commit d928703db1c4aa6caa6e4fbb0894037b10dce820 +Author: Ivo Timmermans +Date: Wed Apr 26 23:23:01 2000 +0000 + + Omit TODO. + +commit d0ea9c8ff287e879e531af9f1b52529421c0512f +Author: Ivo Timmermans +Date: Wed Apr 26 22:42:15 2000 +0000 + + Add an entry to dir. + +commit e5a7291543d41d435cc0fae56e52dc62a119a225 +Author: Ivo Timmermans +Date: Wed Apr 26 22:01:01 2000 +0000 + + The make command is in /usr/bin. + +commit 44f9449888344866406c75b178eff83b392b3530 +Author: Guus Sliepen +Date: Wed Apr 26 17:42:55 2000 +0000 + + Cleanups: + - Changed recv/send calls into read/write calls for streams + - Made all sizeof() functions use a variable name instead of type + +commit fca84d8a7d116c62423faf88e841daf1bee714e1 +Author: Ivo Timmermans +Date: Wed Apr 26 14:54:43 2000 +0000 + + From Mads Kiilerich. + +commit 8efe4874dabdfdf03a747ea98cf38b11cb591ef5 +Author: Guus Sliepen +Date: Tue Apr 25 22:15:28 2000 +0000 + + Converted every &variable[0] to variable. + +commit 643d8712eb2f82bde21f206306cdb6491eee7e08 +Author: Ivo Timmermans +Date: Tue Apr 25 22:00:49 2000 +0000 + + Debug level tweaking. + +commit 468f1d2efcce53937b7f5e0540269ae18f29ebac +Author: Guus Sliepen +Date: Tue Apr 25 20:50:59 2000 +0000 + + When trying to talk to a host that is in the netmask of a tinc server but + not the tinc server itself, and no keys have been exchanged yet, the key + request would be directed to the host instead of the server. Fixed. + +commit 6461a4b607f5e422b5809acb772e4bfe810b5570 +Author: Ivo Timmermans +Date: Tue Apr 25 20:42:54 2000 +0000 + + *** empty log message *** + +commit dad90e82d3c7af95820b1c04903bed7074e2b175 +Author: Guus Sliepen +Date: Tue Apr 25 20:17:44 2000 +0000 + + Fixed typo and removed some unnecessary variables. + +commit 5b7242285795f5143770b663055b87ebb5dd15b8 +Author: Guus Sliepen +Date: Tue Apr 25 20:10:37 2000 +0000 + + Packet queues fixed. They caused the trouble when resending keys. + +commit 04db888b1a94a7d63fdf9800cfd722aa9c16cd26 +Author: Ivo Timmermans +Date: Tue Apr 25 19:23:23 2000 +0000 + + Create a ChangeLog file, automake requires it. + +commit c78b76c53f516cf944ee738fad3e7d4607f282ab +Author: Ivo Timmermans +Date: Tue Apr 25 19:21:19 2000 +0000 + + *** empty log message *** + +commit 45b275e2542b4e8e7deac9e5e9eeddacfdbce90f +Author: Ivo Timmermans +Date: Tue Apr 25 19:11:02 2000 +0000 + + Initial CVS. + +commit 3a3356865267ff4c1e4f7d73f6d1486952d641b5 +Author: Guus Sliepen +Date: Tue Apr 25 18:57:23 2000 +0000 + + Added checkpoints to beginning and ending of every function. + +commit b6bdb9079a9e80b77443efe6c8b6da19e57e8505 +Author: Ivo Timmermans +Date: Tue Apr 25 17:38:54 2000 +0000 + + Remove ChangeLog with a `make cvs-clean'. + +commit ca373c61944a7bd2fe26faf081edea136104d326 +Author: Ivo Timmermans +Date: Tue Apr 25 17:35:45 2000 +0000 + + Don't include TODO in the dist. + +commit e1e590fe9a8c5c767933c68979418911f36d3a89 +Author: Ivo Timmermans +Date: Tue Apr 25 15:08:10 2000 +0000 + + Propagate CFLAGS from configure to gcc. + +commit 8a90de94a1b0e6cdaf51559d44f04a75d5f9ab0e +Author: Ivo Timmermans +Date: Tue Apr 25 15:07:21 2000 +0000 + + Delete all the files that are created by autogen.sh on a `make cvs-clean'. + +commit 24ee68b683de9937e917898075c62ff5f43ee46a +Author: Ivo Timmermans +Date: Tue Apr 25 10:40:08 2000 +0000 + + Spelling fixes. + +commit 4d85552c5bf134ada1d1083ec86dabbe41497c4a +Author: Ivo Timmermans +Date: Tue Apr 25 10:27:44 2000 +0000 + + Contributed by Mads Kiilerich. + +commit 94921d6e57e01b378ab8b1d8ea9cf3da9511fbef +Author: Ivo Timmermans +Date: Tue Apr 25 10:22:26 2000 +0000 + + Generate this Makefile.am from Makefile.am.in. + +commit 8c2b6537d32720b38554815181009c3098423414 +Author: Ivo Timmermans +Date: Tue Apr 25 09:43:50 2000 +0000 + + *** empty log message *** + +commit 03fa76dbf9965cc174eebe8a152307b8fbb63079 +Author: Ivo Timmermans +Date: Tue Apr 25 09:42:52 2000 +0000 + + Added Mads Kiilerich, removed Guus Sliepen. + +commit 7c665712d69d5a502d4c2f098ad85df3b17bfb92 +Author: Ivo Timmermans +Date: Tue Apr 25 01:45:34 2000 +0000 + + Changes largely from Mads Kiilerich. + Removed section about encryption. + +commit ce98ee1ed4121fbbf5d0e13e158511064ced6b16 +Author: Ivo Timmermans +Date: Tue Apr 25 01:26:35 2000 +0000 + + Remove test for GNOME. + +commit 6c99feb3e3cf6d69bcf52ae87b6c64ddbf3ffca5 +Author: Ivo Timmermans +Date: Tue Apr 25 01:25:18 2000 +0000 + + Use `make ChangeLog' to create this file from the CVS logs. + +commit f9eef5210dbc9c0fe54637cc4c3c0be134a51409 +Author: Ivo Timmermans +Date: Tue Apr 25 01:23:31 2000 +0000 + + Don't define HAVE_NAMESPACES and HAVE_STL. + +commit ea9d2f379a170077f93569a957c713452768d0a4 +Author: Ivo Timmermans +Date: Tue Apr 25 01:22:01 2000 +0000 + + Remove check for bigendianness. + +commit 18b204d17a054e991d90b7c4047ea106df64cdaf +Author: Ivo Timmermans +Date: Tue Apr 25 01:15:28 2000 +0000 + + This file is obsolete, most of the ideas are already in echelon. + +commit 62d5384ee01ae818906f2f8ba1456372a13a2420 +Author: Ivo Timmermans +Date: Tue Apr 25 01:10:38 2000 +0000 + + s/Gnome/tinc/g + +commit f0101589959496593db672c6a35704ea5fb33238 +Author: Ivo Timmermans +Date: Tue Apr 25 00:50:48 2000 +0000 + + The shell script autogen.sh can create all these removed files, but be + sure to have autoconf, automake, libtool and more installed. + +commit 6990a7455521665d3b67518e3f2297968108190b +Author: Ivo Timmermans +Date: Tue Apr 25 00:11:33 2000 +0000 + + Don't try to create cipher/idea/Makefile. + +commit cfecc82c9a3f5e8c4648eec058da2c6427cd76af +Author: Ivo Timmermans +Date: Mon Apr 24 21:12:32 2000 +0000 + + Don't include idea/idea.h. + +commit 63540ceff5c7bb7c76d96a4cef4ba803ce915ce1 +Author: Ivo Timmermans +Date: Mon Apr 24 21:10:33 2000 +0000 + + Don't compile in `idea'. + +commit 74315f4218ba50cc5ba32b6ecc8e8afa2b5cd704 +Author: Ivo Timmermans +Date: Mon Apr 24 20:57:22 2000 +0000 + + These files are not needed in release 1.0. + +commit 16d581be68bb52c08569e34e8a6b87f66b87e8ee +Author: Guus Sliepen +Date: Mon Apr 24 09:39:50 2000 +0000 + + Bug found! Wrong pointer was used for handling multiple ADD_HOST requests + at once. (See line 606.) + +commit f6802d349d946090bf9d1b6c761077c80065afa5 +Author: Guus Sliepen +Date: Mon Apr 24 08:32:57 2000 +0000 + + Added extra checks for desynchronized connection lists. Hopefully this will + fix those strange segmentation faults. + +commit 10749179127c681ce040fcf612038174b2bd474a +Author: Ivo Timmermans +Date: Thu Apr 20 22:50:48 2000 +0000 + + Added cvs-clean. + +commit c92701fcf007b67725d82a23ffaef3e6e5c2b0e1 +Author: Ivo Timmermans +Date: Thu Apr 20 19:14:09 2000 +0000 + + Keep make dist(dir) happy. + +commit 7db17968fc84127212ebba0fbccec1e75ced2bdc +Author: Ivo Timmermans +Date: Tue Apr 18 20:44:29 2000 +0000 + + A short notice from Mads Kiilerich. + +commit 2c5a555d7aefcf5699c68cb5d5f00f604b2542c7 +Author: Ivo Timmermans +Date: Tue Apr 18 20:43:24 2000 +0000 + + Submitted changes by Mads Kiilerich. + +commit 375b668dbc1e0268b49ea12901da72bbf5247ce5 +Author: Ivo Timmermans +Date: Tue Apr 18 20:30:20 2000 +0000 + + Include genauth.8 in the distribution. + +commit 57d8c30e4cbecea3b4216e4e650c4c0a3e160ed2 +Author: Ivo Timmermans +Date: Tue Apr 18 20:26:49 2000 +0000 + + Include the directory redhat in the build process. + +commit 0b02ebc4d98182cf79c670e7e556ac7f4f859b75 +Author: Ivo Timmermans +Date: Tue Apr 18 16:04:10 2000 +0000 + + Address for bugreports changed to tinc@nl.linux.org. + +commit 8770211c84cfb69f71bd204926593900d74ab579 +Author: Ivo Timmermans +Date: Tue Apr 18 15:59:42 2000 +0000 + + Updated manpages. + +commit 8cdb84951019feb6d4954cd11eb9663c5b9ce363 +Author: Ivo Timmermans +Date: Tue Apr 18 15:59:22 2000 +0000 + + New manpage for genauth. + +commit d11cfcec74e25ee2b88acea62ca5ef973ab7204b +Author: Ivo Timmermans +Date: Tue Apr 18 15:09:11 2000 +0000 + + Submitted by Mads Kiilerich. + +commit 93287d2b2c77d4b9e3f85f36ef4f9230fe3bf9b3 +Author: Ivo Timmermans +Date: Mon Apr 17 17:04:33 2000 +0000 + + Default passphrase length of 1024, added -h/--help options. + +commit 9c2ac77594d83a810c53faf6979e0b76006ecd0e +Author: Ivo Timmermans +Date: Mon Apr 17 16:59:42 2000 +0000 + + Check if stdout is a terminal, if so, print a verbose message. + +commit c9246896901ff1ebad91ac399a4ea79fad941f75 +Author: Ivo Timmermans +Date: Mon Apr 17 16:52:58 2000 +0000 + + Check for an illegal length of passphrase in read_passphrase(). + +commit baebae274913d912d76ba1d545f337dfb945fc5c +Author: Ivo Timmermans +Date: Mon Apr 17 16:23:29 2000 +0000 + + Pass the requested size from xmalloc() and xrealloc() on to xalloc_fail_func() + +commit 210a92cae90deb5b4a410b1b7d5c625c5c5f2ffb +Author: Ivo Timmermans +Date: Mon Apr 17 15:38:47 2000 +0000 + + Only one round of reading bits out of urandom; + Reading `bytes' bytes out of it; + Print a newline after completion. + +commit 5b44b91eb408d76af646b031da2364a769b44771 +Author: Ivo Timmermans +Date: Wed Apr 12 16:22:39 2000 +0000 + + Moved to version number 1.0. + +commit 18e044bde3b508c991910218989b4bacc3a4934e +Author: Ivo Timmermans +Date: Thu Apr 6 18:28:29 2000 +0000 + + New option -D, don't detach. + +commit 523c80c4e35b7ff8ad94b41a6071dbe2b8ff6ec7 +Author: Ivo Timmermans +Date: Tue Mar 28 19:16:27 2000 +0000 + + Ignore SIGCHLD. + +commit f2076e3e7031ac8ad87eb6aab0cea40f379dd0c6 +Author: Ivo Timmermans +Date: Tue Mar 28 19:09:52 2000 +0000 + + Kill the parent after any error conditions in detach(). + +commit 98de35c742498878a27fb29becd3b7154525a60f +Author: Ivo Timmermans +Date: Mon Mar 27 22:59:16 2000 +0000 + + Upon regeneration, free the old encryption key `securely\' by overwriting it. + +commit b50523dc44bbb32f03d24573e195c071cbff3fc4 +Author: Ivo Timmermans +Date: Mon Mar 27 22:30:27 2000 +0000 + + Get rid of the message `zxnrbl\'. + +commit 1243156a5e03a666b36bc4400f1402243a85c9a7 +Author: Ivo Timmermans +Date: Sun Mar 26 00:33:07 2000 +0000 + + Initial revision diff --git a/INSTALL b/INSTALL index 8865734..7d1c323 100644 --- a/INSTALL +++ b/INSTALL @@ -1,8 +1,8 @@ Installation Instructions ************************* - Copyright (C) 1994-1996, 1999-2002, 2004-2016 Free Software -Foundation, Inc. +Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005, +2006, 2007, 2008, 2009 Free Software Foundation, Inc. Copying and distribution of this file, with or without modification, are permitted in any medium without royalty provided the copyright @@ -12,96 +12,97 @@ without warranty of any kind. Basic Installation ================== - Briefly, the shell command './configure && make && make install' -should configure, build, and install this package. The following -more-detailed instructions are generic; see the 'README' file for + 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. Some packages provide this -'INSTALL' file but do not implement all of the features documented +`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 + The `configure' shell script attempts to guess correct values for various system-dependent variables used during compilation. It uses -those values to create a 'Makefile' in each directory of the package. -It may also create one or more '.h' files containing system-dependent -definitions. Finally, it creates a shell script 'config.status' that +those values to create a `Makefile' in each directory of the package. +It may also create one or more `.h' files containing system-dependent +definitions. Finally, it creates a shell script `config.status' that you can run in the future to recreate the current configuration, and a -file 'config.log' containing compiler output (useful mainly for -debugging 'configure'). +file `config.log' containing compiler output (useful mainly for +debugging `configure'). - It can also use an optional file (typically called 'config.cache' and -enabled with '--cache-file=config.cache' or simply '-C') that saves the -results of its tests to speed up reconfiguring. Caching is disabled by -default to prevent problems with accidental use of stale cache files. + It can also use an optional file (typically called `config.cache' +and enabled with `--cache-file=config.cache' or simply `-C') that saves +the results of its tests to speed up reconfiguring. Caching is +disabled by default to prevent problems with accidental use of stale +cache files. If you need to do unusual things to compile the package, please try -to figure out how 'configure' could check whether to do them, and mail -diffs or instructions to the address given in the 'README' so they can +to figure out how `configure' could check whether to do them, and mail +diffs or instructions to the address given in the `README' so they can be considered for the next release. If you are using the cache, and at -some point 'config.cache' contains results you don't want to keep, you +some point `config.cache' contains results you don't want to keep, you may remove or edit it. - The file 'configure.ac' (or 'configure.in') is used to create -'configure' by a program called 'autoconf'. You need 'configure.ac' if -you want to change it or regenerate 'configure' using a newer version of -'autoconf'. + The file `configure.ac' (or `configure.in') is used to create +`configure' by a program called `autoconf'. You need `configure.ac' if +you want to change it or regenerate `configure' using a newer version +of `autoconf'. 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. + 1. `cd' to the directory containing the package's source code and type + `./configure' to configure the package for your system. - Running 'configure' might take a while. While running, it prints + Running `configure' might take a while. While running, it prints some messages telling which features it is checking for. - 2. Type 'make' to compile the package. + 2. Type `make' to compile the package. - 3. Optionally, type 'make check' to run any self-tests that come with + 3. Optionally, type `make check' to run any self-tests that come with the package, generally using the just-built uninstalled binaries. - 4. Type 'make install' to install the programs and any data files and + 4. Type `make install' to install the programs and any data files and 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 + user, and only the `make install' phase executed with root privileges. - 5. Optionally, type 'make installcheck' to repeat any self-tests, but + 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 + 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 - also a 'make maintainer-clean' target, but that is intended mainly + 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 + also a `make maintainer-clean' target, but that is intended mainly for the package's developers. If you use it, you may have to get all sorts of other programs in order to regenerate files that came with the distribution. - 7. Often, you can also type 'make uninstall' to remove the installed + 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 + 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. + targets like `make install' and `make uninstall' work correctly. This target is generally not run by end users. Compilers and Options ===================== Some systems require unusual options for compilation or linking that -the 'configure' script does not know about. Run './configure --help' +the `configure' script does not know about. Run `./configure --help' for details on some of the pertinent environment variables. - You can give 'configure' initial values for configuration parameters -by setting variables in the command line or in the environment. Here is -an example: + You can give `configure' initial values for configuration parameters +by setting variables in the command line or in the environment. Here +is an example: ./configure CC=c99 CFLAGS=-g LIBS=-lposix @@ -112,21 +113,21 @@ Compiling For Multiple Architectures You can compile the package for more than one kind of computer at the 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 +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 '..'. This is known -as a "VPATH" build. +the `configure' script. `configure' automatically checks for the +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 + 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 -installed the package for one architecture, use 'make distclean' before +installed the package for one architecture, use `make distclean' before reconfiguring for another architecture. On MacOS X 10.5 and later systems, you can create libraries and executables that work on multiple system types--known as "fat" or -"universal" binaries--by specifying multiple '-arch' options to the -compiler but only a single '-arch' option to the preprocessor. Like +"universal" binaries--by specifying multiple `-arch' options to the +compiler but only a single `-arch' option to the preprocessor. Like this: ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ @@ -135,104 +136,100 @@ this: This is not guaranteed to produce working output in all cases, you may have to build one architecture at a time and combine the results -using the 'lipo' tool if you have problems. +using the `lipo' tool if you have problems. 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', where PREFIX must be an + 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', where PREFIX must be an absolute file name. You can specify separate installation prefixes for architecture-specific files and architecture-independent files. If you -pass the option '--exec-prefix=PREFIX' to 'configure', the package uses +pass the option `--exec-prefix=PREFIX' to `configure', the package uses PREFIX as the prefix for installing programs and libraries. 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. 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 +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. 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 +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 +`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 +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. +`${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 + 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. +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'. +with an extra prefix or suffix on their names by giving `configure' the +option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. - 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 -is something like 'gnu-as' or 'x' (for the X Window System). The -'README' should mention any '--enable-' and '--with-' options that the + 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 +is something like `gnu-as' or `x' (for the X Window System). The +`README' should mention any `--enable-' and `--with-' options that the package recognizes. - For packages that use the X Window System, 'configure' can usually + For packages that use the X Window System, `configure' can usually 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. +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 +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 +overridden with `make V=1'; while running `./configure --disable-silent-rules' sets the default to verbose, which can be -overridden with 'make V=0'. +overridden with `make V=0'. Particular systems ================== - On HP-UX, the default C compiler is not ANSI C compatible. If GNU CC -is not installed, it is recommended to use the following options in + On HP-UX, the default C compiler is not ANSI C compatible. If GNU +CC is not installed, it is recommended to use the following options in order to use an ANSI C compiler: ./configure CC="cc -Ae -D_XOPEN_SOURCE=500" and if that doesn't work, install pre-built binaries of GCC for HP-UX. - HP-UX 'make' updates targets which have the same time stamps as their -prerequisites, which makes it generally unusable when shipped generated -files such as 'configure' are involved. Use GNU 'make' instead. - On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot -parse its '' header file. The option '-nodtk' can be used as a -workaround. If GNU CC is not installed, it is therefore recommended to -try +parse its `' header file. The option `-nodtk' can be used as +a workaround. If GNU CC is not installed, it is therefore recommended +to try ./configure CC="cc" @@ -240,26 +237,26 @@ and if that doesn't work, try ./configure CC="cc -nodtk" - On Solaris, don't put '/usr/ucb' early in your 'PATH'. This + On Solaris, don't put `/usr/ucb' early in your `PATH'. This directory contains several dysfunctional programs; working variants of -these programs are available in '/usr/bin'. So, if you need '/usr/ucb' -in your 'PATH', put it _after_ '/usr/bin'. +these programs are available in `/usr/bin'. So, if you need `/usr/ucb' +in your `PATH', put it _after_ `/usr/bin'. - On Haiku, software installed for all users goes in '/boot/common', -not '/usr/local'. It is recommended to use the following options: + On Haiku, software installed for all users goes in `/boot/common', +not `/usr/local'. It is recommended to use the following options: ./configure --prefix=/boot/common Specifying the System Type ========================== - There may be some features 'configure' cannot figure out + There may be some features `configure' cannot figure out automatically, but needs to determine by the type of machine the package will run on. Usually, assuming the package is built to be run on the -_same_ architectures, 'configure' can figure that out, but if it prints +_same_ architectures, `configure' can figure that out, but if it prints a message saying it cannot guess the machine type, give it the -'--build=TYPE' option. TYPE can either be a short name for the system -type, such as 'sun4', or a canonical name which has the form: +`--build=TYPE' option. TYPE can either be a short name for the system +type, such as `sun4', or a canonical name which has the form: CPU-COMPANY-SYSTEM @@ -268,101 +265,101 @@ where SYSTEM can have one of these forms: OS KERNEL-OS - See the file 'config.sub' for the possible values of each field. If -'config.sub' isn't included in this package, then this package doesn't + See the file `config.sub' for the possible values of each field. If +`config.sub' isn't included in this package, then this package doesn't need to know the machine type. If you are _building_ compiler tools for cross-compiling, you should -use the option '--target=TYPE' to select the type of system they will +use the option `--target=TYPE' to select the type of system they will produce code for. If you want to _use_ a cross compiler, that generates code for a platform different from the build platform, you should specify the "host" platform (i.e., that on which the generated programs will -eventually be run) with '--host=TYPE'. +eventually be run) with `--host=TYPE'. Sharing Defaults ================ - If you want to set default values for 'configure' scripts to share, -you can create a site shell script called 'config.site' that gives -default values for variables like 'CC', 'cache_file', and 'prefix'. -'configure' looks for 'PREFIX/share/config.site' if it exists, then -'PREFIX/etc/config.site' if it exists. Or, you can set the -'CONFIG_SITE' environment variable to the location of the site script. -A warning: not all 'configure' scripts look for a site script. + If you want to set default values for `configure' scripts to share, +you can create a site shell script called `config.site' that gives +default values for variables like `CC', `cache_file', and `prefix'. +`configure' looks for `PREFIX/share/config.site' if it exists, then +`PREFIX/etc/config.site' if it exists. Or, you can set the +`CONFIG_SITE' environment variable to the location of the site script. +A warning: not all `configure' scripts look for a site script. Defining Variables ================== Variables not defined in a site shell script can be set in the -environment passed to 'configure'. However, some packages may run +environment passed to `configure'. However, some packages may run configure again during the build, and the customized values of these variables may be lost. In order to avoid this problem, you should set -them in the 'configure' command line, using 'VAR=value'. For example: +them in the `configure' command line, using `VAR=value'. For example: ./configure CC=/usr/local2/bin/gcc -causes the specified 'gcc' to be used as the C compiler (unless it is +causes the specified `gcc' to be used as the C compiler (unless it is overridden in the site shell script). -Unfortunately, this technique does not work for 'CONFIG_SHELL' due to an -Autoconf limitation. Until the limitation is lifted, you can use this -workaround: +Unfortunately, this technique does not work for `CONFIG_SHELL' due to +an Autoconf bug. Until the bug is fixed you can use this workaround: - CONFIG_SHELL=/bin/bash ./configure CONFIG_SHELL=/bin/bash + CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash -'configure' Invocation +`configure' Invocation ====================== - 'configure' recognizes the following options to control how it + `configure' recognizes the following options to control how it operates. -'--help' -'-h' - Print a summary of all of the options to 'configure', and exit. +`--help' +`-h' + Print a summary of all of the options to `configure', and exit. -'--help=short' -'--help=recursive' +`--help=short' +`--help=recursive' Print a summary of the options unique to this package's - 'configure', and exit. The 'short' variant lists options used only - in the top level, while the 'recursive' variant lists options also - present in any nested packages. + `configure', and exit. The `short' variant lists options used + only in the top level, while the `recursive' variant lists options + also present in any nested packages. -'--version' -'-V' - Print the version of Autoconf used to generate the 'configure' +`--version' +`-V' + Print the version of Autoconf used to generate the `configure' script, and exit. -'--cache-file=FILE' +`--cache-file=FILE' Enable the cache: use and save the results of the tests in FILE, - traditionally 'config.cache'. FILE defaults to '/dev/null' to + traditionally `config.cache'. FILE defaults to `/dev/null' to disable caching. -'--config-cache' -'-C' - Alias for '--cache-file=config.cache'. +`--config-cache' +`-C' + Alias for `--cache-file=config.cache'. -'--quiet' -'--silent' -'-q' +`--quiet' +`--silent' +`-q' Do not print messages saying which checks are being made. To - suppress all normal output, redirect it to '/dev/null' (any error + suppress all normal output, redirect it to `/dev/null' (any error messages will still be shown). -'--srcdir=DIR' +`--srcdir=DIR' Look for the package's source code in directory DIR. Usually - 'configure' can determine that directory automatically. + `configure' can determine that directory automatically. -'--prefix=DIR' - Use DIR as the installation prefix. *note Installation Names:: for - more details, including other options available for fine-tuning the - installation locations. +`--prefix=DIR' + Use DIR as the installation prefix. *note Installation Names:: + for more details, including other options available for fine-tuning + the installation locations. -'--no-create' -'-n' +`--no-create' +`-n' Run the configure checks, but stop before creating any output files. -'configure' also accepts some other, not widely useful, options. Run -'configure --help' for more details. +`configure' also accepts some other, not widely useful, options. Run +`configure --help' for more details. + diff --git a/Makefile.am b/Makefile.am index 8e43fe5..e37864d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -2,14 +2,26 @@ AUTOMAKE_OPTIONS = gnu -SUBDIRS = src doc systemd +SUBDIRS = m4 src doc gui ACLOCAL_AMFLAGS = -I m4 -EXTRA_DIST = COPYING.README README.android +EXTRA_DIST = have.h system.h COPYING.README ChangeLog: git log > ChangeLog -astyle: - astyle --options=.astylerc -nQ src/*.[ch] src/*/*.[ch] +deb: + dpkg-buildpackage -rfakeroot + +rpm: dist + cp $(distdir).tar.gz /usr/src/redhat/SOURCES/ + cp redhat/tinc.spec /usr/src/redhat/SOURCES/ + cd /usr/src/redhat/SOURCES/ && rpm -bb tinc.spec + +release: + rm -f ChangeLog + $(MAKE) ChangeLog + echo "Please edit the NEWS file now..." + /usr/bin/editor NEWS + $(MAKE) dist diff --git a/Makefile.in b/Makefile.in index 526846b..baa5005 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1,8 +1,9 @@ -# Makefile.in generated by automake 1.16.1 from Makefile.am. +# Makefile.in generated by automake 1.11.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2018 Free Software Foundation, Inc. - +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -14,61 +15,6 @@ @SET_MAKE@ VPATH = @srcdir@ -am__is_gnu_make = { \ - if test -z '$(MAKELEVEL)'; then \ - false; \ - elif test -n '$(MAKE_HOST)'; then \ - true; \ - elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ - true; \ - else \ - false; \ - fi; \ -} -am__make_running_with_option = \ - case $${target_option-} in \ - ?) ;; \ - *) echo "am__make_running_with_option: internal error: invalid" \ - "target option '$${target_option-}' specified" >&2; \ - exit 1;; \ - esac; \ - has_opt=no; \ - sane_makeflags=$$MAKEFLAGS; \ - if $(am__is_gnu_make); then \ - sane_makeflags=$$MFLAGS; \ - else \ - case $$MAKEFLAGS in \ - *\\[\ \ ]*) \ - bs=\\; \ - sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ - | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ - esac; \ - fi; \ - skip_next=no; \ - strip_trailopt () \ - { \ - flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ - }; \ - for flg in $$sane_makeflags; do \ - test $$skip_next = yes && { skip_next=no; continue; }; \ - case $$flg in \ - *=*|--*) continue;; \ - -*I) strip_trailopt 'I'; skip_next=yes;; \ - -*I?*) strip_trailopt 'I';; \ - -*O) strip_trailopt 'O'; skip_next=yes;; \ - -*O?*) strip_trailopt 'O';; \ - -*l) strip_trailopt 'l'; skip_next=yes;; \ - -*l?*) strip_trailopt 'l';; \ - -[dEDm]) skip_next=yes;; \ - -[JT]) skip_next=yes;; \ - esac; \ - case $$flg in \ - *$$target_option*) has_opt=yes; break;; \ - esac; \ - done; \ - test $$has_opt = yes -am__make_dryrun = (target_option=n; $(am__make_running_with_option)) -am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ @@ -88,95 +34,47 @@ POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = . +DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \ + $(srcdir)/Makefile.in $(srcdir)/config.h.in \ + $(top_srcdir)/configure AUTHORS COPYING ChangeLog INSTALL NEWS \ + THANKS config.guess config.sub depcomp install-sh missing ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \ - $(top_srcdir)/m4/ax_append_flag.m4 \ - $(top_srcdir)/m4/ax_cflags_warn_all.m4 \ - $(top_srcdir)/m4/ax_check_compile_flag.m4 \ - $(top_srcdir)/m4/ax_check_link_flag.m4 \ - $(top_srcdir)/m4/ax_require_defined.m4 $(top_srcdir)/m4/lzo.m4 \ - $(top_srcdir)/m4/openssl.m4 $(top_srcdir)/m4/zlib.m4 \ - $(top_srcdir)/configure.ac + $(top_srcdir)/m4/curses.m4 $(top_srcdir)/m4/libevent.m4 \ + $(top_srcdir)/m4/lzo.m4 $(top_srcdir)/m4/openssl.m4 \ + $(top_srcdir)/m4/zlib.m4 $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) -DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \ - $(am__configure_deps) $(am__DIST_COMMON) am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ configure.lineno config.status.lineno mkinstalldirs = $(install_sh) -d CONFIG_HEADER = config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = -AM_V_P = $(am__v_P_@AM_V@) -am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) -am__v_P_0 = false -am__v_P_1 = : -AM_V_GEN = $(am__v_GEN_@AM_V@) -am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) -am__v_GEN_0 = @echo " GEN " $@; -am__v_GEN_1 = -AM_V_at = $(am__v_at_@AM_V@) -am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) -am__v_at_0 = @ -am__v_at_1 = SOURCES = DIST_SOURCES = -RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ - ctags-recursive dvi-recursive html-recursive info-recursive \ - install-data-recursive install-dvi-recursive \ - install-exec-recursive install-html-recursive \ - install-info-recursive install-pdf-recursive \ - install-ps-recursive install-recursive installcheck-recursive \ - installdirs-recursive pdf-recursive ps-recursive \ - tags-recursive uninstall-recursive -am__can_run_installinfo = \ - case $$AM_UPDATE_INFO_DIR in \ - n|no|NO) false;; \ - *) (install-info --version) >/dev/null 2>&1;; \ - esac +RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ + html-recursive info-recursive install-data-recursive \ + install-dvi-recursive install-exec-recursive \ + install-html-recursive install-info-recursive \ + install-pdf-recursive install-ps-recursive install-recursive \ + installcheck-recursive installdirs-recursive pdf-recursive \ + ps-recursive uninstall-recursive RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive -am__recursive_targets = \ - $(RECURSIVE_TARGETS) \ - $(RECURSIVE_CLEAN_TARGETS) \ - $(am__extra_recursive_targets) -AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ - cscope distdir distdir-am dist dist-all distcheck -am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \ - $(LISP)config.h.in -# Read a list of newline-separated strings from the standard input, -# and print each of them once, without duplicates. Input order is -# *not* preserved. -am__uniquify_input = $(AWK) '\ - BEGIN { nonempty = 0; } \ - { items[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in items) print i; }; } \ -' -# Make sure the list of sources is unique. This is necessary because, -# e.g., the same source file might be shared among _SOURCES variables -# for different programs/libraries. -am__define_uniq_tagged_files = \ - list='$(am__tagged_files)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | $(am__uniquify_input)` +AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ + $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \ + distdir dist dist-all distcheck ETAGS = etags CTAGS = ctags -CSCOPE = cscope DIST_SUBDIRS = $(SUBDIRS) -am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/config.h.in AUTHORS \ - COPYING ChangeLog INSTALL NEWS README THANKS compile \ - config.guess config.sub install-sh missing DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) top_distdir = $(distdir) am__remove_distdir = \ - if test -d "$(distdir)"; then \ - find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ - && rm -rf "$(distdir)" \ - || { sleep 5 && rm -rf "$(distdir)"; }; \ - else :; fi -am__post_remove_distdir = $(am__remove_distdir) + { test ! -d "$(distdir)" \ + || { find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ + && rm -fr "$(distdir)"; }; } am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ @@ -204,14 +102,10 @@ am__relativize = \ reldir="$$dir2" DIST_ARCHIVES = $(distdir).tar.gz GZIP_ENV = --best -DIST_TARGETS = dist-gzip distuninstallcheck_listfiles = find . -type f -print -am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ - | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' distcleancheck_listfiles = find . -type f -print ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ -AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ @@ -221,6 +115,7 @@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ +CURSES_LIBS = @CURSES_LIBS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ @@ -230,15 +125,21 @@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ GREP = @GREP@ +INCLUDES = @INCLUDES@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ +LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ +LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ +LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ +LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ OBJEXT = @OBJEXT@ @@ -250,6 +151,7 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ @@ -296,27 +198,25 @@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ -runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ -systemd_path = @systemd_path@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ AUTOMAKE_OPTIONS = gnu -SUBDIRS = src doc systemd +SUBDIRS = m4 src doc gui ACLOCAL_AMFLAGS = -I m4 -EXTRA_DIST = COPYING.README README.android +EXTRA_DIST = have.h system.h COPYING.README all: config.h $(MAKE) $(AM_MAKEFLAGS) all-recursive .SUFFIXES: -am--refresh: Makefile +am--refresh: @: -$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ @@ -329,33 +229,36 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu Makefile +.PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ echo ' $(SHELL) ./config.status'; \ $(SHELL) ./config.status;; \ *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__maybe_remake_depfiles)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__maybe_remake_depfiles);; \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) $(SHELL) ./config.status --recheck -$(top_srcdir)/configure: $(am__configure_deps) +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) $(am__cd) $(srcdir) && $(AUTOCONF) -$(ACLOCAL_M4): $(am__aclocal_m4_deps) +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) $(am__aclocal_m4_deps): config.h: stamp-h1 - @test -f $@ || rm -f stamp-h1 - @test -f $@ || $(MAKE) $(AM_MAKEFLAGS) stamp-h1 + @if test ! -f $@; then \ + rm -f stamp-h1; \ + $(MAKE) $(AM_MAKEFLAGS) stamp-h1; \ + else :; fi stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status @rm -f stamp-h1 cd $(top_builddir) && $(SHELL) ./config.status config.h -$(srcdir)/config.h.in: $(am__configure_deps) +$(srcdir)/config.h.in: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) ($(am__cd) $(top_srcdir) && $(AUTOHEADER)) rm -f stamp-h1 touch $@ @@ -364,25 +267,22 @@ distclean-hdr: -rm -f config.h stamp-h1 # This directory's subdirectories are mostly independent; you can cd -# into them and run 'make' without going through this Makefile. -# To change the values of 'make' variables: instead of editing Makefiles, -# (1) if the variable is set in 'config.status', edit 'config.status' -# (which will cause the Makefiles to be regenerated when you run 'make'); -# (2) otherwise, pass the desired values on the 'make' command line. -$(am__recursive_targets): - @fail=; \ - if $(am__make_keepgoing); then \ - failcom='fail=yes'; \ - else \ - failcom='exit 1'; \ - fi; \ +# into them and run `make' without going through this Makefile. +# To change the values of `make' variables: instead of editing Makefiles, +# (1) if the variable is set in `config.status', edit `config.status' +# (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): + @fail= failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ - case "$@" in \ - distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ - *) list='$(SUBDIRS)' ;; \ - esac; \ - for subdir in $$list; do \ + list='$(SUBDIRS)'; for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ @@ -397,12 +297,57 @@ $(am__recursive_targets): $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" -ID: $(am__tagged_files) - $(am__define_uniq_tagged_files); mkid -fID $$unique -tags: tags-recursive -TAGS: tags +$(RECURSIVE_CLEAN_TARGETS): + @fail= failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + rev=''; for subdir in $$list; do \ + if test "$$subdir" = "."; then :; else \ + rev="$$subdir $$rev"; \ + fi; \ + done; \ + rev="$$rev ."; \ + target=`echo $@ | sed s/-recursive//`; \ + for subdir in $$rev; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done && test -z "$$fail" +tags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ + done +ctags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ + done -tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ @@ -418,7 +363,12 @@ tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ - $(am__define_uniq_tagged_files); \ + list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ @@ -430,11 +380,15 @@ tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $$unique; \ fi; \ fi -ctags: ctags-recursive - -CTAGS: ctags -ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - $(am__define_uniq_tagged_files); \ +ctags: CTAGS +CTAGS: ctags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique @@ -443,42 +397,11 @@ GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" -cscope: cscope.files - test ! -s cscope.files \ - || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS) -clean-cscope: - -rm -f cscope.files -cscope.files: clean-cscope cscopelist -cscopelist: cscopelist-recursive - -cscopelist-am: $(am__tagged_files) - list='$(am__tagged_files)'; \ - case "$(srcdir)" in \ - [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ - *) sdir=$(subdir)/$(srcdir) ;; \ - esac; \ - for i in $$list; do \ - if test -f "$$i"; then \ - echo "$(subdir)/$$i"; \ - else \ - echo "$$sdir/$$i"; \ - fi; \ - done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags - -rm -f cscope.out cscope.in.out cscope.po.out cscope.files -distdir: $(BUILT_SOURCES) - $(MAKE) $(AM_MAKEFLAGS) distdir-am - -distdir-am: $(DISTFILES) - @case `sed 15q $(srcdir)/NEWS` in \ - *"$(VERSION)"*) : ;; \ - *) \ - echo "NEWS not updated; not releasing" 1>&2; \ - exit 1;; \ - esac +distdir: $(DISTFILES) $(am__remove_distdir) test -d "$(distdir)" || mkdir "$(distdir)" @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ @@ -512,10 +435,13 @@ distdir-am: $(DISTFILES) done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ - $(am__make_dryrun) \ - || test -d "$(distdir)/$$subdir" \ - || $(MKDIR_P) "$(distdir)/$$subdir" \ - || exit 1; \ + test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ @@ -543,43 +469,37 @@ distdir-am: $(DISTFILES) ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ || chmod -R a+r "$(distdir)" dist-gzip: distdir - tardir=$(distdir) && $(am__tar) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).tar.gz - $(am__post_remove_distdir) + tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz + $(am__remove_distdir) dist-bzip2: distdir - tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2 - $(am__post_remove_distdir) + tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2 + $(am__remove_distdir) -dist-lzip: distdir - tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz - $(am__post_remove_distdir) +dist-lzma: distdir + tardir=$(distdir) && $(am__tar) | lzma -9 -c >$(distdir).tar.lzma + $(am__remove_distdir) dist-xz: distdir - tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz - $(am__post_remove_distdir) + tardir=$(distdir) && $(am__tar) | xz -c >$(distdir).tar.xz + $(am__remove_distdir) dist-tarZ: distdir - @echo WARNING: "Support for distribution archives compressed with" \ - "legacy program 'compress' is deprecated." >&2 - @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z - $(am__post_remove_distdir) + $(am__remove_distdir) dist-shar: distdir - @echo WARNING: "Support for shar distribution archives is" \ - "deprecated." >&2 - @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 - shar $(distdir) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).shar.gz - $(am__post_remove_distdir) + shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz + $(am__remove_distdir) dist-zip: distdir -rm -f $(distdir).zip zip -rq $(distdir).zip $(distdir) - $(am__post_remove_distdir) + $(am__remove_distdir) -dist dist-all: - $(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:' - $(am__post_remove_distdir) +dist dist-all: distdir + tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz + $(am__remove_distdir) # This target untars the dist file and tries a VPATH configuration. Then # it guarantees that the distribution is self-contained by making another @@ -587,33 +507,31 @@ dist dist-all: distcheck: dist case '$(DIST_ARCHIVES)' in \ *.tar.gz*) \ - eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).tar.gz | $(am__untar) ;;\ + GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\ *.tar.bz2*) \ bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ - *.tar.lz*) \ - lzip -dc $(distdir).tar.lz | $(am__untar) ;;\ + *.tar.lzma*) \ + 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*) \ - eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).shar.gz | unshar ;;\ + GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\ *.zip*) \ unzip $(distdir).zip ;;\ esac - chmod -R a-w $(distdir) - chmod u+w $(distdir) - mkdir $(distdir)/_build $(distdir)/_build/sub $(distdir)/_inst + chmod -R a-w $(distdir); chmod a+w $(distdir) + mkdir $(distdir)/_build + mkdir $(distdir)/_inst chmod a-w $(distdir) test -d $(distdir)/_build || exit 0; \ dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ && am__cwd=`pwd` \ - && $(am__cd) $(distdir)/_build/sub \ - && ../../configure \ - $(AM_DISTCHECK_CONFIGURE_FLAGS) \ + && $(am__cd) $(distdir)/_build \ + && ../configure --srcdir=.. --prefix="$$dc_install_base" \ $(DISTCHECK_CONFIGURE_FLAGS) \ - --srcdir=../.. --prefix="$$dc_install_base" \ && $(MAKE) $(AM_MAKEFLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) dvi \ && $(MAKE) $(AM_MAKEFLAGS) check \ @@ -636,21 +554,13 @@ distcheck: dist && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ && cd "$$am__cwd" \ || exit 1 - $(am__post_remove_distdir) + $(am__remove_distdir) @(echo "$(distdir) archives ready for distribution: "; \ list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' distuninstallcheck: - @test -n '$(distuninstallcheck_dir)' || { \ - echo 'ERROR: trying to run $@ with an empty' \ - '$$(distuninstallcheck_dir)' >&2; \ - exit 1; \ - }; \ - $(am__cd) '$(distuninstallcheck_dir)' || { \ - echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \ - exit 1; \ - }; \ - test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \ + @$(am__cd) '$(distuninstallcheck_dir)' \ + && test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \ || { echo "ERROR: files left after uninstall:" ; \ if test -n "$(DESTDIR)"; then \ echo " (check DESTDIR support)"; \ @@ -681,15 +591,10 @@ install-am: all-am installcheck: installcheck-recursive install-strip: - if test -z '$(STRIP)'; then \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - install; \ - else \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ - fi + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: @@ -770,32 +675,42 @@ ps-am: uninstall-am: -.MAKE: $(am__recursive_targets) all install-am install-strip +.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) all \ + ctags-recursive install-am install-strip tags-recursive -.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \ - am--refresh check check-am clean clean-cscope clean-generic \ - cscope cscopelist-am ctags ctags-am dist dist-all dist-bzip2 \ - dist-gzip dist-lzip dist-shar dist-tarZ dist-xz dist-zip \ - distcheck distclean distclean-generic distclean-hdr \ - distclean-tags distcleancheck distdir distuninstallcheck dvi \ - dvi-am html html-am info info-am install install-am \ - install-data install-data-am install-dvi install-dvi-am \ - install-exec install-exec-am install-html install-html-am \ - install-info install-info-am install-man install-pdf \ - install-pdf-am install-ps install-ps-am install-strip \ - installcheck installcheck-am installdirs installdirs-am \ - maintainer-clean maintainer-clean-generic mostlyclean \ - mostlyclean-generic pdf pdf-am ps ps-am tags tags-am uninstall \ - uninstall-am - -.PRECIOUS: Makefile +.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ + all all-am am--refresh check check-am clean clean-generic \ + ctags ctags-recursive dist dist-all dist-bzip2 dist-gzip \ + dist-lzma dist-shar dist-tarZ dist-xz dist-zip distcheck \ + distclean distclean-generic distclean-hdr distclean-tags \ + distcleancheck distdir distuninstallcheck dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs installdirs-am maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-generic pdf \ + pdf-am ps ps-am tags tags-recursive uninstall uninstall-am ChangeLog: git log > ChangeLog -astyle: - astyle --options=.astylerc -nQ src/*.[ch] src/*/*.[ch] +deb: + dpkg-buildpackage -rfakeroot + +rpm: dist + cp $(distdir).tar.gz /usr/src/redhat/SOURCES/ + cp redhat/tinc.spec /usr/src/redhat/SOURCES/ + cd /usr/src/redhat/SOURCES/ && rpm -bb tinc.spec + +release: + rm -f ChangeLog + $(MAKE) ChangeLog + echo "Please edit the NEWS file now..." + /usr/bin/editor NEWS + $(MAKE) dist # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. diff --git a/NEWS b/NEWS index 4a342f7..679040b 100644 --- a/NEWS +++ b/NEWS @@ -1,238 +1,32 @@ -Version 1.0.35 October 5 2018 +Version 1.1pre2 Juli 17 2011 - * Prevent oracle attacks (CVE-2018-16737, CVE-2018-16738). - * Prevent a MITM from forcing a NULL cipher for UDP (CVE-2018-16758). + * .cookie files are renamed to .pid files, which are compatible with 1.0.x. -Version 1.0.34 June 12 2018 + * Experimental protocol enhancements that can be enabled with the option + ExperimentalProtocol = yes: - * Fix a potential segmentation fault when connecting to an IPv6 peer via a - proxy. - * Minor improvements to the build system. - * Make the systemd service file identical to the one from the 1.1 branch. - * Fix a potential problem causing IPv4 sockets to not work on macOS. + * Ephemeral ECDH key exchange will be used for both the meta protocol and + UDP session keys. + * Key exchanges are signed with ECDSA. + * ECDSA public keys are automatically exchanged after RSA authentication if + nodes do not know each other's ECDSA public key yet. -Thanks to Maximilian Stein and Wang Liu Shuai for their contributions to this -version of tinc. +Version 1.1pre1 June 25 2011 -Version 1.0.33 November 4 2017 + * Control interface allows control of a running tinc daemon. Used by: + * tincctl, a commandline utility + * tinc-gui, a preliminary GUI implemented in Python/wxWidgets - * Allow compilation from a build directory. - * Source code cleanups. - * Fix some options specified on the command line not surviving a HUP signal. - * Handle tun/tap device returning EPERM or EBUSY. - * Disable PMTUDiscovery when TCPOnly is used. - * Support the --runstatedir option of the autoconf 2.70. + * Code cleanups and reorganization. -Thanks to Rafael Sadowski and Pierre-Olivier Mercier for their contributions to -this version of tinc. + * Repleacable cryptography backend, currently supports OpenSSL and libgcrypt. -Version 1.0.32 September 2 2017 + * Use libevent to handle I/O events and timeouts. - * Fix segmentation fault when using Cipher = none. - * Fix Proxy = exec. - * Support PriorityInheritance for IPv6 packets. - * Fixes for Solaris tun/tap support. - * Bind outgoing TCP sockets when ListenAddress is used. + * Use splay trees instead of AVL trees to manage internal datastructures. -Thanks to Vittorio Gambaletta for his contribution to this version of tinc. - -Version 1.0.31 January 15 2017 - - * Remove ExecStop in tinc@.service. - -Thanks to Élie Bouttier for his contribution to this version of tinc. - -Version 1.0.30 October 30 2016 - - * Fix troubles connecting to some HTTP proxies. - - * Add mitigations for the Sweet32 attack when using a 64-bit block cipher. - - * Use AES256 and SHA256 as the default encryption and digest algorithms. - -Version 1.0.29 October 9 2016 - - * Fix UDP communication with peers with link-local IPv6 addresses. - - * Ensure compatibility with OpenSSL 1.1.0. - - * Ensure autoreconf can be run without requiring autoconf-archive. - - * Log warnings about dropped packets only at debug level 5. - -Version 1.0.28 April 10 2016 - - * Fix compilation on BSD platforms. - - * Add systemd service files. - -Version 1.0.27 April 10 2016 - - * When using Proxy, let the proxy resolve hostnames if tinc can't. - - * Fixes and improvements of the DecrementTTL option. - - * Fixed the $NAME variable in subnet-up/down scripts for the local Subnets. - - * Fixed potentially wrong checksum generation when clamping the MSS. - - * Properly choose between the system's or our own copy of getopt. - - * Fixed compiling tinc for Cygwin with MinGW installed. - - * Added support for OS X utun interfaces. - - * Documentation updates and minor fixes. - -Thanks to Vittorio Gambaletta, LunarShaddow, Florian Weik and Nathan Stratton -Treadway for their contributions to this version of tinc. - -Version 1.0.26 July 5 2015 - - * Tinc now forces glibc to reload /etc/resolv.conf for every hostname lookup. - - * Fixed --logfile without a filename on Windows. - - * Ensure tinc can be compiled when using musl libc. - -Thanks to Jo-Philipp Wich for his contribution to this version of tinc. - -Version 1.0.25 December 22 2014 - - * Documentation updates. - - * Support linking against -lresolv on Mac OS X. - - * Fix scripts on Windows when using the ScriptsInterpreter option. - - * Allow a minimum reconnect timeout to be specified. - - * Support PriorityInheritance on IPv6 sockets. - -Thanks to David Pflug, Baptiste Jonglez, Alexis Hildebrandt, Borg, Jochen Voss, -Tomislav Čohar and VittGam for their contributions to this version of tinc. - -Version 1.0.24 May 11 2014 - - * Various compiler hardening flags are enabled by default. - - * Updated support for Solaris, allowing switch mode on Solaris 11. - - * Configuration will now also be read from a conf.d directory. - - * Various updates to the documentation. - - * Tinc now forces glibc to reload /etc/resolv.conf after it receives SIGALRM. - - * Fixed a potential routing loop when IndirectData or TCPOnly is used and - broadcast packets are being sent. - - * Improved security with constant time memcmp and stricter use of OpenSSL's - RNG functions. - - * Fixed all issues found by Coverity. - -Thanks to Florent Clairambault, Vilbrekin, luckyhacky, Armin Fisslthaler, Loïc -Dachary and Steffan Karger for their contributions to this version of tinc. - -Version 1.0.23 October 19 2013 - - * Start authentication immediately on outgoing connections (useful for sslh). - - * Fixed segfault when Name = $HOST but $HOST is not set. - - * Updated the build system and the documentation. - - * Clean up child processes left over from Proxy = exec. - -Version 1.0.22 August 13 2013 - - * Fixed the combination of Mode = router and DeviceType = tap. - - * The $NAME variable is now set in subnet-up/down scripts. - - * Tinc now gives an error when unknown options are given on the command line. - - * Tinc now correctly handles a space between a short command line option and - an optional argument. - -Thanks to Etienne Dechamps for his contribution to this version of tinc. - -Version 1.0.21 April 22 2013 - - * Drop packets forwarded via TCP if they are too big (CVE-2013-1428). - -Thanks to Martin Schobert for auditing tinc and reporting this vulnerability. - -Version 1.0.20 March 03 2013 - - * Use /dev/tap0 by default on FreeBSD and NetBSD when using switch mode. - - * Minor improvements and clarifications in the documentation. - - * Allow tinc to be cross-compiled with Android's NDK. - - * The discovered PMTU is now also applied to VLAN tagged traffic. - - * The LocalDiscovery option now makes use of all addresses tinc is bound to. - - * Fixed support for tunemu on iOS devices. - - * The PriorityInheritance option now also works with switch mode. - - * Fixed tinc crashing when using a SOCKS5 proxy. - -Thanks to Mesar Hameed, Vilbrekin and Martin Schürrer for their contributions -to this version of tinc. - -Version 1.0.19 June 25 2012 - - * Allow :: notation in IPv6 Subnets. - - * Add support for systemd style socket activation. - - * Allow environment variables to be used for the Name option. - - * Add basic support for SOCKS proxies, HTTP proxies, and proxying through an - external command. - -Thanks to Anthony G. Basile and Michael Tokarev for their contributions to -this version of tinc. - -Version 1.0.18 March 25 2012 - - * Fixed IPv6 in switch mode by turning off DecrementTTL by default. - - * Allow a port number to be specified in BindToAddress, which also allows tinc - to listen on multiple ports. - - * Add support for multicast communication with UML/QEMU/KVM. - -Version 1.0.17 March 10 2012 - - * The DeviceType option can now be used to select dummy, raw socket, UML and - VDE devices without needing to recompile tinc. - - * Allow multiple BindToAddress statements. - - * Decrement TTL value of IPv4 and IPv6 packets. - - * Add LocalDiscovery option allowing tinc to detect peers that are behind the - same NAT. - - * Accept Subnets passed with the -o option when StrictSubnets = yes. - - * Disabling old RSA keys when generating new ones now also works properly on - Windows. - -Thanks to Nick Hibma for his contribution to this version of tinc. - -Version 1.0.16 July 23 2011 - - * Fixed a performance issue with TCP communication under Windows. - - * Fixed code that, during network outages, would cause tinc to exit when it - thought two nodes with identical Names were on the VPN. + Thanks to Scott Lamb and Sven-Haegar Koch for their contributions to this + version of tinc. Version 1.0.15 June 24 2011 @@ -242,6 +36,8 @@ Version 1.0.15 June 24 2011 * Fixed ProcessPriority option under Windows. + Thanks to Loïc Grenié for his contribution to this version of tinc. + Version 1.0.14 May 8 2011 * Fixed reading configuration files that do not end with a newline. Again. @@ -357,7 +153,7 @@ Version 1.0.9 Dec 26 2008 * Enable path MTU discovery by default. - * Fixed a memory leak that occurred when connections were closed. + * Fixed a memory leak that occured when connections were closed. Thanks to Max Rijevski for his contributions to this version of tinc. diff --git a/README b/README index f47cc29..09f6e6e 100644 --- a/README +++ b/README @@ -1,7 +1,7 @@ -This is the README file for tinc version 1.0.35. Installation +This is the README file for tinc version 1.1pre2. Installation instructions may be found in the INSTALL file. -tinc is Copyright (C) 1998-2018 by: +tinc is Copyright (C) 1998-2011 by: Ivo Timmermans, Guus Sliepen , @@ -15,74 +15,51 @@ the Free Software Foundation; either version 2 of the License, or (at your option) any later version. See the file COPYING for more details. +This is a pre-release +--------------------- + +Please note that this is NOT a stable release. Until version 1.1.0 is released, +please use one of the 1.0.x versions if you need a stable version of tinc. + +Although tinc 1.1 will be protocol compatible with tinc 1.0.x, the +functionality of the tincctl program may still change, and the control socket +protocol is not fixed yet. + + Security statement ------------------ -In August 2000, we discovered the existence of a security hole in all versions -of tinc up to and including 1.0pre2. This had to do with the way we exchanged -keys. Since then, we have been working on a new authentication scheme to make -tinc as secure as possible. The current version uses the OpenSSL library and -uses strong authentication with RSA keys. - -On the 29th of December 2001, Jerome Etienne posted a security analysis of tinc -1.0pre4. Due to a lack of sequence numbers and a message authentication code -for each packet, an attacker could possibly disrupt certain network services or -launch a denial of service attack by replaying intercepted packets. The current -version adds sequence numbers and message authentication codes to prevent such -attacks. - -On September the 15th of 2003, Peter Gutmann contacted us and showed us a -writeup describing various security issues in several VPN daemons. He showed -that tinc lacks perfect forward security, the connection authentication could -be done more properly, that the sequence number we use as an IV is not the best -practice and that the default length of the HMAC for packets is too short in -his opinion. We do not know of a way to exploit these weaknesses, but these -issues are being addressed in the tinc 1.1 branch. - -The Sweet32 attack affects versions of tinc prior to 1.0.30. - -On September 6th, 2018, Michael Yonly contacted us and provided -proof-of-concept code that allowed a remote attacker to create an -authenticated, one-way connection with a node, and also that there was a -possibility for a man-in-the-middle to force UDP packets from a node to be sent -in plaintext. The first issue was trivial to exploit on tinc versions prior to -1.0.30, but the changes in 1.0.30 to mitigate the Sweet32 attack made this -weakness much harder to exploit. These issues have been fixed in tinc 1.0.35. -The new protocol in the tinc 1.1 branch is not susceptible to these issues. - -Cryptography is a hard thing to get right. We cannot make any -guarantees. Time, review and feedback are the only things that can -prove the security of any cryptographic product. If you wish to review -tinc or give us feedback, you are strongly encouraged to do so. +This version uses an experimental and unfinished cryptographic protocol. Use +it at your own risk. Compatibility ------------- -Version 1.0.35 is compatible with 1.0pre8, 1.0 and later, but not with older -versions of tinc. Note that since version 1.0.30, tinc requires all nodes in -the VPN to be compiled with a version of LibreSSL or OpenSSL that supports the -AES256 and SHA256 algorithms. +Version 1.1pre2 is compatible with 1.0pre8, 1.0 and later, but not with older +versions of tinc. + +When the ExperimentalProtocol option is used, tinc is still compatible with +1.0.X and 1.1pre2 itself, but not with any other 1.1preX version. Requirements ------------ -The OpenSSL library is used for all cryptographic functions. You can find it at -https://www.openssl.org/. You will need version 1.0.1 or later with support for -AES256 and SHA256 enabled. If this library is not installed on your system, the -configure script will fail. The manual in doc/tinc.texi contains more detailed -information on how to install this library. Alternatively, you may also use the -LibreSSL library. +Either OpenSSL (http://www.openssl.org/) or libgcrypt +(http://www.gnupg.org/download/#libgcrypt). -The zlib library is used for optional compression. You can -find it at https://zlib.net/. Because of a possible exploit in -earlier versions we recommend that you download version 1.1.4 or later. +The zlib library is used for optional compression. You can find it at +http://www.gzip.org/zlib/. -The LZO library is also used for optional compression. You can -find it at https://www.oberhumer.com/opensource/lzo/. +The lzo library is also used for optional compression. You can find it at +http://www.oberhumer.com/opensource/lzo/. -In order to compile tinc, you will need a C99 compliant compiler. +Since 1.1, the libevent library is used for the main event loop. You can find +it at http://monkey.org/~provos/libevent/. + +In order to compile tinc, you will need a GNU C compiler environment. Please +ensure you have the latest stable versions of all the required libraries. Features @@ -112,14 +89,14 @@ Linux, FreeBSD and Windows. The algorithms used for encryption and generating message authentication codes can now be changed in the configuration files. All cipher and digest algorithms supported by OpenSSL can be used. Useful ciphers are "blowfish" (default), -"bf-ofb", "des", "des3", et cetera. Useful digests are "sha1" (default), "md5", -et cetera. +"bf-ofb", "des", "des3", etcetera. Useful digests are "sha1" (default), "md5", +etcetera. Support for routing IPv6 packets has been added. Just add Subnet lines with IPv6 addresses (without using :: abbreviations) and use ifconfig or ip (from the iproute package) to give the virtual network interface corresponding IPv6 -addresses. tinc does not provide autoconfiguration for IPv6 hosts. Consider -using radvd or zebra if you need it. +addresses. tinc does not provide autoconfiguration for IPv6 hosts, if you need +it use radvd or zebra. It is also possible to make tunnels to other tinc daemons over IPv6 networks, if the operating system supports IPv6. tinc will automatically use both IPv6 @@ -127,7 +104,7 @@ and IPv4 when available, but this can be changed by adding the option "AddressFamily = ipv4" or "AddressFamily = ipv6" to the tinc.conf file. Normally, when started tinc will detach and run in the background. In a native -Windows environment this means tinc will install itself as a service, which will +Windows environment this means tinc will intall itself as a service, which will restart after reboots. To prevent tinc from detaching or running as a service, use the -D option. diff --git a/README.android b/README.android deleted file mode 100644 index 7925bdb..0000000 --- a/README.android +++ /dev/null @@ -1,25 +0,0 @@ -Quick how-to cross compile tinc for android (done from $HOME/android/): - -- Download android NDK and setup local ARM toolchain: -wget http://dl.google.com/android/ndk/android-ndk-r9d-linux-x86.tar.bz2 -tar xfj android-ndk-r9d-linux-x86.tar.bz2 -./android-ndk-r9d/build/tools/make-standalone-toolchain.sh --platform=android-5 --install-dir=/tmp/my-android-toolchain - -- Download and cross-compile openSSL for ARM: -wget http://www.openssl.org/source/openssl-1.0.1h.tar.gz -tar xfz openssl-1.0.1h.tar.gz -cd openssl-1.0.1h -./Configure dist -make CC=/tmp/my-android-toolchain/bin/arm-linux-androideabi-gcc AR="/tmp/my-android-toolchain/bin/arm-linux-androideabi-ar r" RANLIB=/tmp/my-android-toolchain/bin/arm-linux-androideabi-ranlib -cd - - -- Clone and cross-compile tinc: -git clone git://tinc-vpn.org/tinc -cd tinc -autoreconf -fsi -CC=/tmp/my-android-toolchain/bin/arm-linux-androideabi-gcc ./configure --host=arm-linux --disable-lzo --with-openssl-lib=$HOME/android/openssl-1.0.1g --with-openssl-include=$HOME/android/openssl-1.0.1g/include/ --disable-hardening -make -j5 - -- Strip tincd binary to make it smaller -/tmp/my-android-toolchain/bin/arm-linux-androideabi-strip src/tincd - diff --git a/THANKS b/THANKS index d6f4af7..4a6eae2 100644 --- a/THANKS +++ b/THANKS @@ -1,120 +1,49 @@ We would like to thank the following people for their contributions to tinc: * Alexander Reil and Gemeinde Berg -* Alexander Ried -* Alexis Hildebrandt * Allesandro Gatti * Andreas van Cranenburgh -* Andrew Hahn -* Anthony G. Basile * Armijn Hemel -* Armin Fisslthaler -* Aron Cowan -* Ashish Bajaj -* Baptiste Jonglez -* Borg * Brandon Black -* Cheng LI * Cris van Pelt -* Darius Jahandarie -* Dato Simó -* David Pflug * Delf Eldkraft -* Dennis Joachimsthaler * dnk -* Élie Bouttier * Enrique Zanardi -* Erik Tews -* Etienne Dechamps -* Florent Clairambault -* Florian Forster -* Florian Klink -* Florian Weik * Flynn Marquardt -* Franz Pletz -* Gary Kessler and Claudia Gonzalez * Grzegorz Dymarek -* Gusariev Oleksandr * Hans Bayle -* Harvest * Ivo van Dong -* Ivo Smits -* James Cook * James MacLean * Jamie Briggs * Jason Harper -* Jason Livesay -* Jasper Krijgsman -* Jelle de Jong -* Jeroen Domburg * Jeroen Ubbink * Jerome Etienne -* Jo-Philipp Wich -* Jochen Voss * Julien Muchembled -* Lavrans Laading -* Loïc Dachary * Loïc Grenié * Lubomír Bulej -* luckyhacky -* LunarShaddow * Mads Kiilerich * Marc A. Lehmann * Mark Glines -* Mark Petryk * Markus Goetz * Martin Kihlgren -* Martin Schobert -* Martin Schürrer -* Martin Weinelt * Matias Carrasco * Max Rijevski * Menno Smits -* Mesar Hameed * Michael Tokarev -* Michael Yonli * Miles Nordin -* Nathan Stratton Treadway -* Murat Donmez -* Nick Hibma * Nick Patavalis * Paul Littlefield -* Philipp Babel -* Pierre Emeriaud -* Pierre-Olivier Mercier -* Rafael Sadowski -* Rafał Leśniak -* Rhosyn Celyn * Robert van der Meulen * Rumko -* Ryan Miller -* Sam Bryan -* Samuel Thibault -* Saverio Proto * Scott Lamb -* Steffan Karger -* Stig Fagrell * Sven-Haegar Koch * Teemu Kiviniemi -* Thomas Tsiakalakis * Timothy Redaelli -* Tomasz Fortuna -* Tomislav Čohar -* Tommy Arnkværn * Tonnerre Lombard -* Ulrich Seifert -* Vil Brekin -* Vittorio Gambaletta -* Wendy Willard * Wessel Dankers -* William A. Kennington III -* William McArthur * Wouter van Heyst -* xentec -* 戴 鸣 -And everyone we forgot (if we did, please let us know). Thank you! +And everyone we forgot. Thank you! ---- -Ivo Timmermans, -Guus Sliepen. +Ivo Timmermans +Guus Sliepen diff --git a/aclocal.m4 b/aclocal.m4 index 06685b5..3e5708a 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -1,7 +1,7 @@ -# generated automatically by aclocal 1.16.1 -*- Autoconf -*- - -# Copyright (C) 1996-2018 Free Software Foundation, Inc. +# 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. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -11,16 +11,139 @@ # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. -m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])]) m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl -m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],, -[m4_warning([this file was generated for autoconf 2.69. +m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.68],, +[m4_warning([this file was generated for autoconf 2.68. 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'.])]) +To do so, use the procedure documented by the package, typically `autoreconf'.])]) -# Copyright (C) 2002-2018 Free Software Foundation, Inc. +dnl Autoconf macros for libgcrypt +dnl Copyright (C) 2002, 2004 Free Software Foundation, Inc. +dnl +dnl This file is free software; as a special exception the author gives +dnl unlimited permission to copy and/or distribute it, with or without +dnl modifications, as long as this notice is preserved. +dnl +dnl This file is distributed in the hope that it will be useful, but +dnl WITHOUT ANY WARRANTY, to the extent permitted by law; without even the +dnl implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + +dnl AM_PATH_LIBGCRYPT([MINIMUM-VERSION, +dnl [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND ]]]) +dnl Test for libgcrypt and define LIBGCRYPT_CFLAGS and LIBGCRYPT_LIBS. +dnl MINIMUN-VERSION is a string with the version number optionalliy prefixed +dnl with the API version to also check the API compatibility. Example: +dnl a MINIMUN-VERSION of 1:1.2.5 won't pass the test unless the installed +dnl version of libgcrypt is at least 1.2.5 *and* the API number is 1. Using +dnl this features allows to prevent build against newer versions of libgcrypt +dnl with a changed API. +dnl +AC_DEFUN([AM_PATH_LIBGCRYPT], +[ AC_ARG_WITH(libgcrypt-prefix, + AC_HELP_STRING([--with-libgcrypt-prefix=PFX], + [prefix where LIBGCRYPT is installed (optional)]), + libgcrypt_config_prefix="$withval", libgcrypt_config_prefix="") + if test x$libgcrypt_config_prefix != x ; then + if test x${LIBGCRYPT_CONFIG+set} != xset ; then + LIBGCRYPT_CONFIG=$libgcrypt_config_prefix/bin/libgcrypt-config + fi + fi + + AC_PATH_TOOL(LIBGCRYPT_CONFIG, libgcrypt-config, no) + tmp=ifelse([$1], ,1:1.2.0,$1) + if echo "$tmp" | grep ':' >/dev/null 2>/dev/null ; then + req_libgcrypt_api=`echo "$tmp" | sed 's/\(.*\):\(.*\)/\1/'` + min_libgcrypt_version=`echo "$tmp" | sed 's/\(.*\):\(.*\)/\2/'` + else + req_libgcrypt_api=0 + min_libgcrypt_version="$tmp" + fi + + AC_MSG_CHECKING(for LIBGCRYPT - version >= $min_libgcrypt_version) + ok=no + if test "$LIBGCRYPT_CONFIG" != "no" ; then + req_major=`echo $min_libgcrypt_version | \ + sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\1/'` + req_minor=`echo $min_libgcrypt_version | \ + sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\2/'` + req_micro=`echo $min_libgcrypt_version | \ + sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\3/'` + libgcrypt_config_version=`$LIBGCRYPT_CONFIG --version` + major=`echo $libgcrypt_config_version | \ + sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*/\1/'` + minor=`echo $libgcrypt_config_version | \ + sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*/\2/'` + micro=`echo $libgcrypt_config_version | \ + sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*/\3/'` + if test "$major" -gt "$req_major"; then + ok=yes + else + if test "$major" -eq "$req_major"; then + if test "$minor" -gt "$req_minor"; then + ok=yes + else + if test "$minor" -eq "$req_minor"; then + if test "$micro" -ge "$req_micro"; then + ok=yes + fi + fi + fi + fi + fi + fi + if test $ok = yes; then + AC_MSG_RESULT([yes ($libgcrypt_config_version)]) + else + AC_MSG_RESULT(no) + fi + if test $ok = yes; then + # If we have a recent libgcrypt, we should also check that the + # API is compatible + if test "$req_libgcrypt_api" -gt 0 ; then + tmp=`$LIBGCRYPT_CONFIG --api-version 2>/dev/null || echo 0` + if test "$tmp" -gt 0 ; then + AC_MSG_CHECKING([LIBGCRYPT API version]) + if test "$req_libgcrypt_api" -eq "$tmp" ; then + AC_MSG_RESULT([okay]) + else + ok=no + AC_MSG_RESULT([does not match. want=$req_libgcrypt_api got=$tmp]) + fi + fi + fi + fi + if test $ok = yes; then + LIBGCRYPT_CFLAGS=`$LIBGCRYPT_CONFIG --cflags` + LIBGCRYPT_LIBS=`$LIBGCRYPT_CONFIG --libs` + ifelse([$2], , :, [$2]) + if test x"$host" != x ; then + libgcrypt_config_host=`$LIBGCRYPT_CONFIG --host 2>/dev/null || echo none` + if test x"$libgcrypt_config_host" != xnone ; then + if test x"$libgcrypt_config_host" != x"$host" ; then + AC_MSG_WARN([[ +*** +*** The config script $LIBGCRYPT_CONFIG was +*** built for $libgcrypt_config_host and thus may not match the +*** used host $host. +*** You may want to use the configure option --with-libgcrypt-prefix +*** to specify a matching config script. +***]]) + fi + fi + fi + else + LIBGCRYPT_CFLAGS="" + LIBGCRYPT_LIBS="" + ifelse([$3], , :, [$3]) + fi + AC_SUBST(LIBGCRYPT_CFLAGS) + AC_SUBST(LIBGCRYPT_LIBS) +]) + +# Copyright (C) 2002, 2003, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -32,10 +155,10 @@ To do so, use the procedure documented by the package, typically 'autoreconf'.]) # generated from the m4 files accompanying Automake X.Y. # (This private macro should not be called outside this file.) AC_DEFUN([AM_AUTOMAKE_VERSION], -[am__api_version='1.16' +[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.16.1], [], +m4_if([$1], [1.11.1], [], [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl ]) @@ -51,22 +174,22 @@ 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.16.1])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]))]) # AM_AUX_DIR_EXPAND -*- Autoconf -*- -# Copyright (C) 2001-2018 Free Software Foundation, Inc. +# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets -# $ac_aux_dir to '$srcdir/foo'. In other projects, it is set to -# '$srcdir', '$srcdir/..', or '$srcdir/../..'. +# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to +# `$srcdir', `$srcdir/..', or `$srcdir/../..'. # # Of course, Automake must honor this variable whenever it calls a # tool from the auxiliary directory. The problem is that $srcdir (and @@ -85,7 +208,7 @@ _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) # # The reason of the latter failure is that $top_srcdir and $ac_aux_dir # are both prefixed by $srcdir. In an in-source build this is usually -# harmless because $srcdir is '.', but things will broke when you +# harmless because $srcdir is `.', but things will broke when you # start a VPATH build or use an absolute $srcdir. # # So we could use something similar to $top_srcdir/$ac_aux_dir/missing, @@ -103,26 +226,30 @@ _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) # configured tree to be moved without reconfiguration. AC_DEFUN([AM_AUX_DIR_EXPAND], -[AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl -# Expand $ac_aux_dir to an absolute path. -am_aux_dir=`cd "$ac_aux_dir" && pwd` +[dnl Rely on autoconf to set up CDPATH properly. +AC_PREREQ([2.50])dnl +# expand $ac_aux_dir to an absolute path +am_aux_dir=`cd $ac_aux_dir && pwd` ]) # AM_CONDITIONAL -*- Autoconf -*- -# Copyright (C) 1997-2018 Free Software Foundation, Inc. +# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005, 2006, 2008 +# Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. +# serial 9 + # AM_CONDITIONAL(NAME, SHELL-CONDITION) # ------------------------------------- # Define a conditional. AC_DEFUN([AM_CONDITIONAL], -[AC_PREREQ([2.52])dnl - m4_if([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], - [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl +[AC_PREREQ(2.52)dnl + ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], + [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl AC_SUBST([$1_TRUE])dnl AC_SUBST([$1_FALSE])dnl _AM_SUBST_NOTMAKE([$1_TRUE])dnl @@ -141,14 +268,16 @@ AC_CONFIG_COMMANDS_PRE( Usually this means the macro was only invoked conditionally.]]) fi])]) -# Copyright (C) 1999-2018 Free Software Foundation, Inc. +# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2009 +# Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. +# serial 10 -# There are a few dirty hacks below to avoid letting 'AC_PROG_CC' be +# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be # written in clear, in which case automake, when reading aclocal.m4, # will think it sees a *use*, and therefore will trigger all it's # C support machinery. Also note that it means that autoscan, seeing @@ -158,7 +287,7 @@ fi])]) # _AM_DEPENDENCIES(NAME) # ---------------------- # See how the compiler implements dependency checking. -# NAME is "CC", "CXX", "OBJC", "OBJCXX", "UPC", or "GJC". +# NAME is "CC", "CXX", "GCJ", or "OBJC". # We try a few techniques and use that to set a single cache variable. # # We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was @@ -171,13 +300,12 @@ AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl AC_REQUIRE([AM_MAKE_INCLUDE])dnl AC_REQUIRE([AM_DEP_TRACK])dnl -m4_if([$1], [CC], [depcc="$CC" am_compiler_list=], - [$1], [CXX], [depcc="$CXX" am_compiler_list=], - [$1], [OBJC], [depcc="$OBJC" am_compiler_list='gcc3 gcc'], - [$1], [OBJCXX], [depcc="$OBJCXX" am_compiler_list='gcc3 gcc'], - [$1], [UPC], [depcc="$UPC" am_compiler_list=], - [$1], [GCJ], [depcc="$GCJ" am_compiler_list='gcc3 gcc'], - [depcc="$$1" am_compiler_list=]) +ifelse([$1], CC, [depcc="$CC" am_compiler_list=], + [$1], CXX, [depcc="$CXX" am_compiler_list=], + [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'], + [$1], UPC, [depcc="$UPC" am_compiler_list=], + [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'], + [depcc="$$1" am_compiler_list=]) AC_CACHE_CHECK([dependency style of $depcc], [am_cv_$1_dependencies_compiler_type], @@ -185,9 +313,8 @@ AC_CACHE_CHECK([dependency style of $depcc], # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up - # making a dummy file named 'D' -- because '-MD' means "put the output - # in D". - rm -rf conftest.dir + # making a dummy file named `D' -- because `-MD' means `put the output + # in D'. mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. @@ -226,16 +353,16 @@ AC_CACHE_CHECK([dependency style of $depcc], : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c - # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with - # Solaris 10 /bin/sh. - echo '/* dummy */' > sub/conftst$i.h + # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with + # Solaris 8's {/usr,}/bin/sh. + touch sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf - # We check with '-c' and '-o' for the sake of the "dashmstdout" + # We check with `-c' and `-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly - # handle '-M -o', and we need to detect this. Also, some Intel - # versions had trouble with output in subdirs. + # handle `-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in @@ -244,16 +371,16 @@ AC_CACHE_CHECK([dependency style of $depcc], test "$am__universal" = false || continue ;; nosideeffect) - # After this tag, mechanisms are not by side-effect, so they'll - # only be used when explicitly requested. + # after this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; - msvc7 | msvc7msys | msvisualcpp | msvcmsys) - # This compiler won't grok '-c -o', but also, the minuso test has + msvisualcpp | msvcmsys) + # This compiler won't grok `-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} @@ -301,7 +428,7 @@ AM_CONDITIONAL([am__fastdep$1], [ # AM_SET_DEPDIR # ------------- # Choose a directory name for dependency files. -# This macro is AC_REQUIREd in _AM_DEPENDENCIES. +# This macro is AC_REQUIREd in _AM_DEPENDENCIES AC_DEFUN([AM_SET_DEPDIR], [AC_REQUIRE([AM_SET_LEADING_DOT])dnl AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl @@ -311,75 +438,81 @@ AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl # AM_DEP_TRACK # ------------ AC_DEFUN([AM_DEP_TRACK], -[AC_ARG_ENABLE([dependency-tracking], [dnl -AS_HELP_STRING( - [--enable-dependency-tracking], - [do not reject slow dependency extractors]) -AS_HELP_STRING( - [--disable-dependency-tracking], - [speeds up one-time build])]) +[AC_ARG_ENABLE(dependency-tracking, +[ --disable-dependency-tracking speeds up one-time build + --enable-dependency-tracking do not reject slow dependency extractors]) if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' - am__nodep='_no' fi AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) AC_SUBST([AMDEPBACKSLASH])dnl _AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl -AC_SUBST([am__nodep])dnl -_AM_SUBST_NOTMAKE([am__nodep])dnl ]) # Generate code to set up dependency tracking. -*- Autoconf -*- -# Copyright (C) 1999-2018 Free Software Foundation, Inc. +# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2008 +# Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. +#serial 5 + # _AM_OUTPUT_DEPENDENCY_COMMANDS # ------------------------------ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], [{ - # Older Autoconf quotes --file arguments for eval, but not when files + # Autoconf 2.62 quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. - # TODO: see whether this extra hack can be removed once we start - # requiring Autoconf 2.70 or later. - AS_CASE([$CONFIG_FILES], - [*\'*], [eval set x "$CONFIG_FILES"], - [*], [set x $CONFIG_FILES]) + case $CONFIG_FILES in + *\'*) eval set x "$CONFIG_FILES" ;; + *) set x $CONFIG_FILES ;; + esac shift - # Used to flag and report bootstrapping failures. - am_rc=0 - for am_mf + for mf do # Strip MF so we end up with the name of the file. - am_mf=`AS_ECHO(["$am_mf"]) | sed -e 's/:.*$//'` - # Check whether this is an Automake generated Makefile which includes - # dependency-tracking related rules and includes. - # Grep'ing the whole file directly is not great: AIX grep has a line + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named `Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # Grep'ing the whole file is not good either: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. - sed -n 's,^am--depfiles:.*,X,p' "$am_mf" | grep X >/dev/null 2>&1 \ - || continue - am_dirpart=`AS_DIRNAME(["$am_mf"])` - am_filepart=`AS_BASENAME(["$am_mf"])` - AM_RUN_LOG([cd "$am_dirpart" \ - && sed -e '/# am--include-marker/d' "$am_filepart" \ - | $MAKE -f - am--depfiles]) || am_rc=$? + if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then + dirpart=`AS_DIRNAME("$mf")` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running `make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # When using ansi2knr, U may be empty or an underscore; expand it + U=`sed -n 's/^U = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`AS_DIRNAME(["$file"])` + AS_MKDIR_P([$dirpart/$fdir]) + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done done - if test $am_rc -ne 0; then - AC_MSG_FAILURE([Something went wrong bootstrapping makefile fragments - for automatic dependency tracking. Try re-running configure with the - '--disable-dependency-tracking' option to at least be able to build - the package (albeit without support for automatic dependency tracking).]) - fi - AS_UNSET([am_dirpart]) - AS_UNSET([am_filepart]) - AS_UNSET([am_mf]) - AS_UNSET([am_rc]) - rm -f conftest-deps.mk } ])# _AM_OUTPUT_DEPENDENCY_COMMANDS @@ -388,31 +521,29 @@ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], # ----------------------------- # This macro should only be invoked once -- use via AC_REQUIRE. # -# This code is only required when automatic dependency tracking is enabled. -# This creates each '.Po' and '.Plo' makefile fragment that we'll need in -# order to bootstrap the dependency handling code. +# This code is only required when automatic dependency tracking +# is enabled. FIXME. This creates each `.P' file that we will +# need in order to bootstrap the dependency handling code. AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], [AC_CONFIG_COMMANDS([depfiles], [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], - [AMDEP_TRUE="$AMDEP_TRUE" MAKE="${MAKE-make}"])]) + [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) +]) # Do all the work for Automake. -*- Autoconf -*- -# Copyright (C) 1996-2018 Free Software Foundation, Inc. +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, +# 2005, 2006, 2008, 2009 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. +# serial 16 + # This macro actually does too much. Some checks are only needed if # your package does certain things. But this isn't really a big deal. -dnl Redefine AC_PROG_CC to automatically invoke _AM_PROG_CC_C_O. -m4_define([AC_PROG_CC], -m4_defn([AC_PROG_CC]) -[_AM_PROG_CC_C_O -]) - # AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) # AM_INIT_AUTOMAKE([OPTIONS]) # ----------------------------------------------- @@ -425,7 +556,7 @@ m4_defn([AC_PROG_CC]) # arguments mandatory, and then we can depend on a new Autoconf # release and drop the old call support. AC_DEFUN([AM_INIT_AUTOMAKE], -[AC_PREREQ([2.65])dnl +[AC_PREREQ([2.62])dnl dnl Autoconf wants to disallow AM_ names. We explicitly allow dnl the ones we care about. m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl @@ -454,42 +585,33 @@ AC_SUBST([CYGPATH_W]) # Define the identity of the package. dnl Distinguish between old-style and new-style calls. m4_ifval([$2], -[AC_DIAGNOSE([obsolete], - [$0: two- and three-arguments forms are deprecated.]) -m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl +[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl AC_SUBST([PACKAGE], [$1])dnl AC_SUBST([VERSION], [$2])], [_AM_SET_OPTIONS([$1])dnl dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. -m4_if( - m4_ifdef([AC_PACKAGE_NAME], [ok]):m4_ifdef([AC_PACKAGE_VERSION], [ok]), - [ok:ok],, +m4_if(m4_ifdef([AC_PACKAGE_NAME], 1)m4_ifdef([AC_PACKAGE_VERSION], 1), 11,, [m4_fatal([AC_INIT should be called with package and version arguments])])dnl AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl _AM_IF_OPTION([no-define],, -[AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package]) - AC_DEFINE_UNQUOTED([VERSION], ["$VERSION"], [Version number of package])])dnl +[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) + AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl # Some tools Automake needs. AC_REQUIRE([AM_SANITY_CHECK])dnl AC_REQUIRE([AC_ARG_PROGRAM])dnl -AM_MISSING_PROG([ACLOCAL], [aclocal-${am__api_version}]) -AM_MISSING_PROG([AUTOCONF], [autoconf]) -AM_MISSING_PROG([AUTOMAKE], [automake-${am__api_version}]) -AM_MISSING_PROG([AUTOHEADER], [autoheader]) -AM_MISSING_PROG([MAKEINFO], [makeinfo]) +AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version}) +AM_MISSING_PROG(AUTOCONF, autoconf) +AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version}) +AM_MISSING_PROG(AUTOHEADER, autoheader) +AM_MISSING_PROG(MAKEINFO, makeinfo) AC_REQUIRE([AM_PROG_INSTALL_SH])dnl AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl -AC_REQUIRE([AC_PROG_MKDIR_P])dnl -# For better backward compatibility. To be removed once Automake 1.9.x -# dies out for good. For more background, see: -# -# -AC_SUBST([mkdir_p], ['$(MKDIR_P)']) -# We need awk for the "check" target (and possibly the TAP driver). The -# system "awk" is bad on some platforms. +AC_REQUIRE([AM_PROG_MKDIR_P])dnl +# We need awk for the "check" target. The system "awk" is bad on +# some platforms. AC_REQUIRE([AC_PROG_AWK])dnl AC_REQUIRE([AC_PROG_MAKE_SET])dnl AC_REQUIRE([AM_SET_LEADING_DOT])dnl @@ -498,82 +620,34 @@ _AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], [_AM_PROG_TAR([v7])])]) _AM_IF_OPTION([no-dependencies],, [AC_PROVIDE_IFELSE([AC_PROG_CC], - [_AM_DEPENDENCIES([CC])], - [m4_define([AC_PROG_CC], - m4_defn([AC_PROG_CC])[_AM_DEPENDENCIES([CC])])])dnl + [_AM_DEPENDENCIES(CC)], + [define([AC_PROG_CC], + defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl AC_PROVIDE_IFELSE([AC_PROG_CXX], - [_AM_DEPENDENCIES([CXX])], - [m4_define([AC_PROG_CXX], - m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl + [_AM_DEPENDENCIES(CXX)], + [define([AC_PROG_CXX], + defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl AC_PROVIDE_IFELSE([AC_PROG_OBJC], - [_AM_DEPENDENCIES([OBJC])], - [m4_define([AC_PROG_OBJC], - m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl -AC_PROVIDE_IFELSE([AC_PROG_OBJCXX], - [_AM_DEPENDENCIES([OBJCXX])], - [m4_define([AC_PROG_OBJCXX], - m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl + [_AM_DEPENDENCIES(OBJC)], + [define([AC_PROG_OBJC], + defn([AC_PROG_OBJC])[_AM_DEPENDENCIES(OBJC)])])dnl ]) -AC_REQUIRE([AM_SILENT_RULES])dnl -dnl The testsuite driver may need to know about EXEEXT, so add the -dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This -dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below. +_AM_IF_OPTION([silent-rules], [AC_REQUIRE([AM_SILENT_RULES])])dnl +dnl The `parallel-tests' driver may need to know about EXEEXT, so add the +dnl `am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This macro +dnl is hooked onto _AC_COMPILER_EXEEXT early, see below. AC_CONFIG_COMMANDS_PRE(dnl [m4_provide_if([_AM_COMPILER_EXEEXT], [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl - -# POSIX will say in a future version that running "rm -f" with no argument -# is OK; and we want to be able to make that assumption in our Makefile -# recipes. So use an aggressive probe to check that the usage we want is -# actually supported "in the wild" to an acceptable degree. -# See automake bug#10828. -# To make any issue more visible, cause the running configure to be aborted -# by default if the 'rm' program in use doesn't match our expectations; the -# user can still override this though. -if rm -f && rm -fr && rm -rf; then : OK; else - cat >&2 <<'END' -Oops! - -Your 'rm' program seems unable to run without file operands specified -on the command line, even when the '-f' option is present. This is contrary -to the behaviour of most rm programs out there, and not conforming with -the upcoming POSIX standard: - -Please tell bug-automake@gnu.org about your system, including the value -of your $PATH and any error possibly output before this message. This -can help us improve future automake versions. - -END - if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then - echo 'Configuration will proceed anyway, since you have set the' >&2 - echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 - echo >&2 - else - cat >&2 <<'END' -Aborting the configuration process, to ensure you take notice of the issue. - -You can download and install GNU coreutils to get an 'rm' implementation -that behaves properly: . - -If you want to complete the configuration process using your problematic -'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM -to "yes", and re-run configure. - -END - AC_MSG_ERROR([Your 'rm' program is bad, sorry.]) - fi -fi -dnl The trailing newline in this macro's definition is deliberate, for -dnl backward compatibility and to allow trailing 'dnl'-style comments -dnl after the AM_INIT_AUTOMAKE invocation. See automake bug#16841. ]) -dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not +dnl Hook into `_AC_COMPILER_EXEEXT' early to learn its expansion. Do not dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further dnl mangled by Autoconf and run in a shell conditional statement. m4_define([_AC_COMPILER_EXEEXT], m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) + # When config.status generates a header, we must update the stamp-h file. # This file resides in the same directory as the config header # that is generated. The stamp files are numbered to have different names. @@ -595,7 +669,7 @@ for _am_header in $config_headers :; do done echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) -# Copyright (C) 2001-2018 Free Software Foundation, Inc. +# Copyright (C) 2001, 2003, 2005, 2008 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -606,7 +680,7 @@ echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_co # Define $install_sh. AC_DEFUN([AM_PROG_INSTALL_SH], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl -if test x"${install_sh+set}" != xset; then +if test x"${install_sh}" != xset; then case $am_aux_dir in *\ * | *\ *) install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; @@ -614,14 +688,16 @@ if test x"${install_sh+set}" != xset; then install_sh="\${SHELL} $am_aux_dir/install-sh" esac fi -AC_SUBST([install_sh])]) +AC_SUBST(install_sh)]) -# Copyright (C) 2003-2018 Free Software Foundation, Inc. +# Copyright (C) 2003, 2005 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. +# serial 2 + # Check whether the underlying file-system supports filenames # with a leading dot. For instance MS-DOS doesn't. AC_DEFUN([AM_SET_LEADING_DOT], @@ -635,57 +711,109 @@ fi rmdir .tst 2>/dev/null AC_SUBST([am__leading_dot])]) -# Check to see how 'make' treats includes. -*- Autoconf -*- +# Add --enable-maintainer-mode option to configure. -*- Autoconf -*- +# From Jim Meyering -# Copyright (C) 2001-2018 Free Software Foundation, Inc. +# Copyright (C) 1996, 1998, 2000, 2001, 2002, 2003, 2004, 2005, 2008 +# Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. +# serial 5 + +# AM_MAINTAINER_MODE([DEFAULT-MODE]) +# ---------------------------------- +# Control maintainer-specific portions of Makefiles. +# Default is to disable them, unless `enable' is passed literally. +# For symmetry, `disable' may be passed as well. Anyway, the user +# can override the default with the --enable/--disable switch. +AC_DEFUN([AM_MAINTAINER_MODE], +[m4_case(m4_default([$1], [disable]), + [enable], [m4_define([am_maintainer_other], [disable])], + [disable], [m4_define([am_maintainer_other], [enable])], + [m4_define([am_maintainer_other], [enable]) + m4_warn([syntax], [unexpected argument to AM@&t@_MAINTAINER_MODE: $1])]) +AC_MSG_CHECKING([whether to am_maintainer_other maintainer-specific portions of Makefiles]) + dnl maintainer-mode's default is 'disable' unless 'enable' is passed + AC_ARG_ENABLE([maintainer-mode], +[ --][am_maintainer_other][-maintainer-mode am_maintainer_other make rules and dependencies not useful + (and sometimes confusing) to the casual installer], + [USE_MAINTAINER_MODE=$enableval], + [USE_MAINTAINER_MODE=]m4_if(am_maintainer_other, [enable], [no], [yes])) + AC_MSG_RESULT([$USE_MAINTAINER_MODE]) + AM_CONDITIONAL([MAINTAINER_MODE], [test $USE_MAINTAINER_MODE = yes]) + MAINT=$MAINTAINER_MODE_TRUE + AC_SUBST([MAINT])dnl +] +) + +AU_DEFUN([jm_MAINTAINER_MODE], [AM_MAINTAINER_MODE]) + +# Check to see how 'make' treats includes. -*- Autoconf -*- + +# Copyright (C) 2001, 2002, 2003, 2005, 2009 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 4 + # AM_MAKE_INCLUDE() # ----------------- -# Check whether make has an 'include' directive that can support all -# the idioms we need for our automatic dependency tracking code. +# Check to see how make treats includes. AC_DEFUN([AM_MAKE_INCLUDE], -[AC_MSG_CHECKING([whether ${MAKE-make} supports the include directive]) -cat > confinc.mk << 'END' +[am_make=${MAKE-make} +cat > confinc << 'END' am__doit: - @echo this is the am__doit target >confinc.out + @echo this is the am__doit target .PHONY: am__doit END +# If we don't find an include directive, just comment out the code. +AC_MSG_CHECKING([for style of include used by $am_make]) am__include="#" am__quote= -# BSD make does it like this. -echo '.include "confinc.mk" # ignored' > confmf.BSD -# Other make implementations (GNU, Solaris 10, AIX) do it like this. -echo 'include confinc.mk # ignored' > confmf.GNU -_am_result=no -for s in GNU BSD; do - AM_RUN_LOG([${MAKE-make} -f confmf.$s && cat confinc.out]) - AS_CASE([$?:`cat confinc.out 2>/dev/null`], - ['0:this is the am__doit target'], - [AS_CASE([$s], - [BSD], [am__include='.include' am__quote='"'], - [am__include='include' am__quote=''])]) - if test "$am__include" != "#"; then - _am_result="yes ($s style)" - break - fi -done -rm -f confinc.* confmf.* -AC_MSG_RESULT([${_am_result}]) -AC_SUBST([am__include])]) -AC_SUBST([am__quote])]) +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# Ignore all kinds of additional output from `make'. +case `$am_make -s -f confmf 2> /dev/null` in #( +*the\ am__doit\ target*) + am__include=include + am__quote= + _am_result=GNU + ;; +esac +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + case `$am_make -s -f confmf 2> /dev/null` in #( + *the\ am__doit\ target*) + am__include=.include + am__quote="\"" + _am_result=BSD + ;; + esac +fi +AC_SUBST([am__include]) +AC_SUBST([am__quote]) +AC_MSG_RESULT([$_am_result]) +rm -f confinc confmf +]) # Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- -# Copyright (C) 1997-2018 Free Software Foundation, Inc. +# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2004, 2005, 2008 +# Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. +# serial 6 + # AM_MISSING_PROG(NAME, PROGRAM) # ------------------------------ AC_DEFUN([AM_MISSING_PROG], @@ -693,10 +821,11 @@ AC_DEFUN([AM_MISSING_PROG], $1=${$1-"${am_missing_run}$2"} AC_SUBST($1)]) + # AM_MISSING_HAS_RUN # ------------------ -# Define MISSING if not defined so far and test if it is modern enough. -# If it is, set am_missing_run to use it, otherwise, to nothing. +# Define MISSING if not defined so far and test if it supports --run. +# If it does, set am_missing_run to use it, otherwise, to nothing. AC_DEFUN([AM_MISSING_HAS_RUN], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([missing])dnl @@ -709,35 +838,63 @@ if test x"${MISSING+set}" != xset; then esac fi # Use eval to expand $SHELL -if eval "$MISSING --is-lightweight"; then - am_missing_run="$MISSING " +if eval "$MISSING --run true"; then + am_missing_run="$MISSING --run " else am_missing_run= - AC_MSG_WARN(['missing' script is too old or missing]) + AC_MSG_WARN([`missing' script is too old or missing]) fi ]) -# Helper functions for option handling. -*- Autoconf -*- - -# Copyright (C) 2001-2018 Free Software Foundation, Inc. +# Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. +# AM_PROG_MKDIR_P +# --------------- +# Check for `mkdir -p'. +AC_DEFUN([AM_PROG_MKDIR_P], +[AC_PREREQ([2.60])dnl +AC_REQUIRE([AC_PROG_MKDIR_P])dnl +dnl Automake 1.8 to 1.9.6 used to define mkdir_p. We now use MKDIR_P, +dnl while keeping a definition of mkdir_p for backward compatibility. +dnl @MKDIR_P@ is magic: AC_OUTPUT adjusts its value for each Makefile. +dnl However we cannot define mkdir_p as $(MKDIR_P) for the sake of +dnl Makefile.ins that do not define MKDIR_P, so we do our own +dnl adjustment using top_builddir (which is defined more often than +dnl MKDIR_P). +AC_SUBST([mkdir_p], ["$MKDIR_P"])dnl +case $mkdir_p in + [[\\/$]]* | ?:[[\\/]]*) ;; + */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; +esac +]) + +# Helper functions for option handling. -*- Autoconf -*- + +# Copyright (C) 2001, 2002, 2003, 2005, 2008 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 4 + # _AM_MANGLE_OPTION(NAME) # ----------------------- AC_DEFUN([_AM_MANGLE_OPTION], [[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) # _AM_SET_OPTION(NAME) -# -------------------- +# ------------------------------ # Set option NAME. Presently that only means defining a flag for this option. AC_DEFUN([_AM_SET_OPTION], -[m4_define(_AM_MANGLE_OPTION([$1]), [1])]) +[m4_define(_AM_MANGLE_OPTION([$1]), 1)]) # _AM_SET_OPTIONS(OPTIONS) -# ------------------------ +# ---------------------------------- # OPTIONS is a space-separated list of Automake options. AC_DEFUN([_AM_SET_OPTIONS], [m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) @@ -748,82 +905,24 @@ AC_DEFUN([_AM_SET_OPTIONS], AC_DEFUN([_AM_IF_OPTION], [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) -# Copyright (C) 1999-2018 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# _AM_PROG_CC_C_O -# --------------- -# Like AC_PROG_CC_C_O, but changed for automake. We rewrite AC_PROG_CC -# to automatically call this. -AC_DEFUN([_AM_PROG_CC_C_O], -[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl -AC_REQUIRE_AUX_FILE([compile])dnl -AC_LANG_PUSH([C])dnl -AC_CACHE_CHECK( - [whether $CC understands -c and -o together], - [am_cv_prog_cc_c_o], - [AC_LANG_CONFTEST([AC_LANG_PROGRAM([])]) - # Make sure it works both with $CC and with simple cc. - # Following AC_PROG_CC_C_O, we do the test twice because some - # compilers refuse to overwrite an existing .o file with -o, - # though they will create one. - am_cv_prog_cc_c_o=yes - for am_i in 1 2; do - if AM_RUN_LOG([$CC -c conftest.$ac_ext -o conftest2.$ac_objext]) \ - && test -f conftest2.$ac_objext; then - : OK - else - am_cv_prog_cc_c_o=no - break - fi - done - rm -f core conftest* - unset am_i]) -if test "$am_cv_prog_cc_c_o" != yes; then - # Losing compiler, so override with the script. - # FIXME: It is wrong to rewrite CC. - # But if we don't then we get into trouble of one sort or another. - # A longer-term fix would be to have automake use am__CC in this case, - # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" - CC="$am_aux_dir/compile $CC" -fi -AC_LANG_POP([C])]) - -# For backward compatibility. -AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])]) - -# Copyright (C) 2001-2018 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# AM_RUN_LOG(COMMAND) -# ------------------- -# Run COMMAND, save the exit status in ac_status, and log it. -# (This has been adapted from Autoconf's _AC_RUN_LOG macro.) -AC_DEFUN([AM_RUN_LOG], -[{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD - ($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD - (exit $ac_status); }]) - # Check to make sure that the build environment is sane. -*- Autoconf -*- -# Copyright (C) 1996-2018 Free Software Foundation, Inc. +# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005, 2008 +# Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. +# serial 5 + # AM_SANITY_CHECK # --------------- AC_DEFUN([AM_SANITY_CHECK], [AC_MSG_CHECKING([whether build environment is sane]) +# Just in case +sleep 1 +echo timestamp > conftest.file # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' @@ -834,40 +933,32 @@ case `pwd` in esac case $srcdir in *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) - AC_MSG_ERROR([unsafe srcdir value: '$srcdir']);; + AC_MSG_ERROR([unsafe srcdir value: `$srcdir']);; esac -# Do 'set' in a subshell so we don't clobber the current shell's +# Do `set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( - am_has_slept=no - for am_try in 1 2; do - echo "timestamp, slept: $am_has_slept" > conftest.file - set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` - if test "$[*]" = "X"; then - # -L didn't work. - set X `ls -t "$srcdir/configure" conftest.file` - fi - if test "$[*]" != "X $srcdir/configure conftest.file" \ - && test "$[*]" != "X conftest.file $srcdir/configure"; then + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$[*]" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + rm -f conftest.file + if test "$[*]" != "X $srcdir/configure conftest.file" \ + && test "$[*]" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken +alias in your environment]) + fi - # If neither matched, then we have a broken ls. This can happen - # if, for instance, CONFIG_SHELL is bash and it inherits a - # broken ls alias from the environment. This has actually - # happened. Such a system could not be considered "sane". - AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken - alias in your environment]) - fi - if test "$[2]" = conftest.file || test $am_try -eq 2; then - break - fi - # Just in case. - sleep 1 - am_has_slept=yes - done test "$[2]" = conftest.file ) then @@ -877,85 +968,9 @@ else AC_MSG_ERROR([newly created file is older than distributed files! Check your system clock]) fi -AC_MSG_RESULT([yes]) -# If we didn't sleep, we still need to ensure time stamps of config.status and -# generated files are strictly newer. -am_sleep_pid= -if grep 'slept: no' conftest.file >/dev/null 2>&1; then - ( sleep 1 ) & - am_sleep_pid=$! -fi -AC_CONFIG_COMMANDS_PRE( - [AC_MSG_CHECKING([that generated files are newer than configure]) - if test -n "$am_sleep_pid"; then - # Hide warnings about reused PIDs. - wait $am_sleep_pid 2>/dev/null - fi - AC_MSG_RESULT([done])]) -rm -f conftest.file -]) +AC_MSG_RESULT(yes)]) -# Copyright (C) 2009-2018 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# AM_SILENT_RULES([DEFAULT]) -# -------------------------- -# Enable less verbose build rules; with the default set to DEFAULT -# ("yes" being less verbose, "no" or empty being verbose). -AC_DEFUN([AM_SILENT_RULES], -[AC_ARG_ENABLE([silent-rules], [dnl -AS_HELP_STRING( - [--enable-silent-rules], - [less verbose build output (undo: "make V=1")]) -AS_HELP_STRING( - [--disable-silent-rules], - [verbose build output (undo: "make V=0")])dnl -]) -case $enable_silent_rules in @%:@ ((( - yes) AM_DEFAULT_VERBOSITY=0;; - no) AM_DEFAULT_VERBOSITY=1;; - *) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);; -esac -dnl -dnl A few 'make' implementations (e.g., NonStop OS and NextStep) -dnl do not support nested variable expansions. -dnl See automake bug#9928 and bug#10237. -am_make=${MAKE-make} -AC_CACHE_CHECK([whether $am_make supports nested variables], - [am_cv_make_support_nested_variables], - [if AS_ECHO([['TRUE=$(BAR$(V)) -BAR0=false -BAR1=true -V=1 -am__doit: - @$(TRUE) -.PHONY: am__doit']]) | $am_make -f - >/dev/null 2>&1; then - am_cv_make_support_nested_variables=yes -else - am_cv_make_support_nested_variables=no -fi]) -if test $am_cv_make_support_nested_variables = yes; then - dnl Using '$V' instead of '$(V)' breaks IRIX make. - AM_V='$(V)' - AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' -else - AM_V=$AM_DEFAULT_VERBOSITY - AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY -fi -AC_SUBST([AM_V])dnl -AM_SUBST_NOTMAKE([AM_V])dnl -AC_SUBST([AM_DEFAULT_V])dnl -AM_SUBST_NOTMAKE([AM_DEFAULT_V])dnl -AC_SUBST([AM_DEFAULT_VERBOSITY])dnl -AM_BACKSLASH='\' -AC_SUBST([AM_BACKSLASH])dnl -_AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl -]) - -# Copyright (C) 2001-2018 Free Software Foundation, Inc. +# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -963,32 +978,34 @@ _AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl # AM_PROG_INSTALL_STRIP # --------------------- -# One issue with vendor 'install' (even GNU) is that you can't +# One issue with vendor `install' (even GNU) is that you can't # specify the program used to strip binaries. This is especially # annoying in cross-compiling environments, where the build's strip # is unlikely to handle the host's binaries. # Fortunately install-sh will honor a STRIPPROG variable, so we -# always use install-sh in "make install-strip", and initialize +# always use install-sh in `make install-strip', and initialize # STRIPPROG with the value of the STRIP variable (set by the user). AC_DEFUN([AM_PROG_INSTALL_STRIP], [AC_REQUIRE([AM_PROG_INSTALL_SH])dnl -# Installed binaries are usually stripped using 'strip' when the user -# run "make install-strip". However 'strip' might not be the right +# Installed binaries are usually stripped using `strip' when the user +# run `make install-strip'. However `strip' might not be the right # tool to use in cross-compilation environments, therefore Automake -# will honor the 'STRIP' environment variable to overrule this program. -dnl Don't test for $cross_compiling = yes, because it might be 'maybe'. +# will honor the `STRIP' environment variable to overrule this program. +dnl Don't test for $cross_compiling = yes, because it might be `maybe'. if test "$cross_compiling" != no; then AC_CHECK_TOOL([STRIP], [strip], :) fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" AC_SUBST([INSTALL_STRIP_PROGRAM])]) -# Copyright (C) 2006-2018 Free Software Foundation, Inc. +# Copyright (C) 2006, 2008 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. +# serial 2 + # _AM_SUBST_NOTMAKE(VARIABLE) # --------------------------- # Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. @@ -996,22 +1013,24 @@ AC_SUBST([INSTALL_STRIP_PROGRAM])]) AC_DEFUN([_AM_SUBST_NOTMAKE]) # AM_SUBST_NOTMAKE(VARIABLE) -# -------------------------- +# --------------------------- # Public sister of _AM_SUBST_NOTMAKE. AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) # Check how to create a tarball. -*- Autoconf -*- -# Copyright (C) 2004-2018 Free Software Foundation, Inc. +# Copyright (C) 2004, 2005 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. +# serial 2 + # _AM_PROG_TAR(FORMAT) # -------------------- # Check how to create a tarball in format FORMAT. -# FORMAT should be one of 'v7', 'ustar', or 'pax'. +# FORMAT should be one of `v7', `ustar', or `pax'. # # Substitute a variable $(am__tar) that is a command # writing to stdout a FORMAT-tarball containing the directory @@ -1021,124 +1040,82 @@ AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) # Substitute a variable $(am__untar) that extract such # a tarball read from stdin. # $(am__untar) < result.tar -# AC_DEFUN([_AM_PROG_TAR], -[# Always define AMTAR for backward compatibility. Yes, it's still used -# in the wild :-( We should find a proper way to deprecate it ... -AC_SUBST([AMTAR], ['$${TAR-tar}']) - -# We'll loop over all known methods to create a tar archive until one works. -_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' - +[# Always define AMTAR for backward compatibility. +AM_MISSING_PROG([AMTAR], [tar]) m4_if([$1], [v7], - [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'], + [am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'], + [m4_case([$1], [ustar],, [pax],, + [m4_fatal([Unknown tar format])]) +AC_MSG_CHECKING([how to create a $1 tar archive]) +# Loop over all known methods to create a tar archive until one works. +_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' +_am_tools=${am_cv_prog_tar_$1-$_am_tools} +# Do not fold the above two line into one, because Tru64 sh and +# Solaris sh will not grok spaces in the rhs of `-'. +for _am_tool in $_am_tools +do + case $_am_tool in + gnutar) + for _am_tar in tar gnutar gtar; + do + AM_RUN_LOG([$_am_tar --version]) && break + done + am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' + am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' + am__untar="$_am_tar -xf -" + ;; + plaintar) + # Must skip GNU tar: if it does not support --format= it doesn't create + # ustar tarball either. + (tar --version) >/dev/null 2>&1 && continue + am__tar='tar chf - "$$tardir"' + am__tar_='tar chf - "$tardir"' + am__untar='tar xf -' + ;; + pax) + am__tar='pax -L -x $1 -w "$$tardir"' + am__tar_='pax -L -x $1 -w "$tardir"' + am__untar='pax -r' + ;; + cpio) + am__tar='find "$$tardir" -print | cpio -o -H $1 -L' + am__tar_='find "$tardir" -print | cpio -o -H $1 -L' + am__untar='cpio -i -H $1 -d' + ;; + none) + am__tar=false + am__tar_=false + am__untar=false + ;; + esac - [m4_case([$1], - [ustar], - [# The POSIX 1988 'ustar' format is defined with fixed-size fields. - # There is notably a 21 bits limit for the UID and the GID. In fact, - # the 'pax' utility can hang on bigger UID/GID (see automake bug#8343 - # and bug#13588). - am_max_uid=2097151 # 2^21 - 1 - am_max_gid=$am_max_uid - # The $UID and $GID variables are not portable, so we need to resort - # to the POSIX-mandated id(1) utility. Errors in the 'id' calls - # below are definitely unexpected, so allow the users to see them - # (that is, avoid stderr redirection). - am_uid=`id -u || echo unknown` - am_gid=`id -g || echo unknown` - AC_MSG_CHECKING([whether UID '$am_uid' is supported by ustar format]) - if test $am_uid -le $am_max_uid; then - AC_MSG_RESULT([yes]) - else - AC_MSG_RESULT([no]) - _am_tools=none - fi - AC_MSG_CHECKING([whether GID '$am_gid' is supported by ustar format]) - if test $am_gid -le $am_max_gid; then - AC_MSG_RESULT([yes]) - else - AC_MSG_RESULT([no]) - _am_tools=none - fi], + # If the value was cached, stop now. We just wanted to have am__tar + # and am__untar set. + test -n "${am_cv_prog_tar_$1}" && break - [pax], - [], - - [m4_fatal([Unknown tar format])]) - - AC_MSG_CHECKING([how to create a $1 tar archive]) - - # Go ahead even if we have the value already cached. We do so because we - # need to set the values for the 'am__tar' and 'am__untar' variables. - _am_tools=${am_cv_prog_tar_$1-$_am_tools} - - for _am_tool in $_am_tools; do - case $_am_tool in - gnutar) - for _am_tar in tar gnutar gtar; do - AM_RUN_LOG([$_am_tar --version]) && break - done - am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' - am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' - am__untar="$_am_tar -xf -" - ;; - plaintar) - # Must skip GNU tar: if it does not support --format= it doesn't create - # ustar tarball either. - (tar --version) >/dev/null 2>&1 && continue - am__tar='tar chf - "$$tardir"' - am__tar_='tar chf - "$tardir"' - am__untar='tar xf -' - ;; - pax) - am__tar='pax -L -x $1 -w "$$tardir"' - am__tar_='pax -L -x $1 -w "$tardir"' - am__untar='pax -r' - ;; - cpio) - am__tar='find "$$tardir" -print | cpio -o -H $1 -L' - am__tar_='find "$tardir" -print | cpio -o -H $1 -L' - am__untar='cpio -i -H $1 -d' - ;; - none) - am__tar=false - am__tar_=false - am__untar=false - ;; - esac - - # If the value was cached, stop now. We just wanted to have am__tar - # and am__untar set. - test -n "${am_cv_prog_tar_$1}" && break - - # tar/untar a dummy directory, and stop if the command works. - rm -rf conftest.dir - mkdir conftest.dir - echo GrepMe > conftest.dir/file - AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) - rm -rf conftest.dir - if test -s conftest.tar; then - AM_RUN_LOG([$am__untar /dev/null 2>&1 && break - fi - done + # tar/untar a dummy directory, and stop if the command works rm -rf conftest.dir + mkdir conftest.dir + echo GrepMe > conftest.dir/file + AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) + rm -rf conftest.dir + if test -s conftest.tar; then + AM_RUN_LOG([$am__untar /dev/null 2>&1 && break + fi +done +rm -rf conftest.dir - AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) - AC_MSG_RESULT([$am_cv_prog_tar_$1])]) - +AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) +AC_MSG_RESULT([$am_cv_prog_tar_$1])]) AC_SUBST([am__tar]) AC_SUBST([am__untar]) ]) # _AM_PROG_TAR m4_include([m4/attribute.m4]) -m4_include([m4/ax_append_flag.m4]) -m4_include([m4/ax_cflags_warn_all.m4]) -m4_include([m4/ax_check_compile_flag.m4]) -m4_include([m4/ax_check_link_flag.m4]) -m4_include([m4/ax_require_defined.m4]) +m4_include([m4/curses.m4]) +m4_include([m4/libevent.m4]) m4_include([m4/lzo.m4]) m4_include([m4/openssl.m4]) m4_include([m4/zlib.m4]) diff --git a/compile b/compile deleted file mode 100755 index 99e5052..0000000 --- a/compile +++ /dev/null @@ -1,348 +0,0 @@ -#! /bin/sh -# Wrapper for compilers which do not understand '-c -o'. - -scriptversion=2018-03-07.03; # UTC - -# Copyright (C) 1999-2018 Free Software Foundation, Inc. -# Written by Tom Tromey . -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - -# This file is maintained in Automake, please report -# bugs to or send patches to -# . - -nl=' -' - -# We need space, tab and new line, in precisely that order. Quoting is -# there to prevent tools from complaining about whitespace usage. -IFS=" "" $nl" - -file_conv= - -# func_file_conv build_file lazy -# Convert a $build file to $host form and store it in $file -# Currently only supports Windows hosts. If the determined conversion -# type is listed in (the comma separated) LAZY, no conversion will -# take place. -func_file_conv () -{ - file=$1 - case $file in - / | /[!/]*) # absolute file, and not a UNC file - if test -z "$file_conv"; then - # lazily determine how to convert abs files - case `uname -s` in - MINGW*) - file_conv=mingw - ;; - CYGWIN*) - file_conv=cygwin - ;; - *) - file_conv=wine - ;; - esac - fi - case $file_conv/,$2, in - *,$file_conv,*) - ;; - mingw/*) - file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'` - ;; - cygwin/*) - file=`cygpath -m "$file" || echo "$file"` - ;; - wine/*) - file=`winepath -w "$file" || echo "$file"` - ;; - esac - ;; - esac -} - -# func_cl_dashL linkdir -# Make cl look for libraries in LINKDIR -func_cl_dashL () -{ - func_file_conv "$1" - if test -z "$lib_path"; then - lib_path=$file - else - lib_path="$lib_path;$file" - fi - linker_opts="$linker_opts -LIBPATH:$file" -} - -# func_cl_dashl library -# Do a library search-path lookup for cl -func_cl_dashl () -{ - lib=$1 - found=no - save_IFS=$IFS - IFS=';' - for dir in $lib_path $LIB - do - IFS=$save_IFS - if $shared && test -f "$dir/$lib.dll.lib"; then - found=yes - lib=$dir/$lib.dll.lib - break - fi - if test -f "$dir/$lib.lib"; then - found=yes - lib=$dir/$lib.lib - break - fi - if test -f "$dir/lib$lib.a"; then - found=yes - lib=$dir/lib$lib.a - break - fi - done - IFS=$save_IFS - - if test "$found" != yes; then - lib=$lib.lib - fi -} - -# func_cl_wrapper cl arg... -# Adjust compile command to suit cl -func_cl_wrapper () -{ - # Assume a capable shell - lib_path= - shared=: - linker_opts= - for arg - do - if test -n "$eat"; then - eat= - else - case $1 in - -o) - # configure might choose to run compile as 'compile cc -o foo foo.c'. - eat=1 - case $2 in - *.o | *.[oO][bB][jJ]) - func_file_conv "$2" - set x "$@" -Fo"$file" - shift - ;; - *) - func_file_conv "$2" - set x "$@" -Fe"$file" - shift - ;; - esac - ;; - -I) - eat=1 - func_file_conv "$2" mingw - set x "$@" -I"$file" - shift - ;; - -I*) - func_file_conv "${1#-I}" mingw - set x "$@" -I"$file" - shift - ;; - -l) - eat=1 - func_cl_dashl "$2" - set x "$@" "$lib" - shift - ;; - -l*) - func_cl_dashl "${1#-l}" - set x "$@" "$lib" - shift - ;; - -L) - eat=1 - func_cl_dashL "$2" - ;; - -L*) - func_cl_dashL "${1#-L}" - ;; - -static) - shared=false - ;; - -Wl,*) - arg=${1#-Wl,} - save_ifs="$IFS"; IFS=',' - for flag in $arg; do - IFS="$save_ifs" - linker_opts="$linker_opts $flag" - done - IFS="$save_ifs" - ;; - -Xlinker) - eat=1 - linker_opts="$linker_opts $2" - ;; - -*) - set x "$@" "$1" - shift - ;; - *.cc | *.CC | *.cxx | *.CXX | *.[cC]++) - func_file_conv "$1" - set x "$@" -Tp"$file" - shift - ;; - *.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO]) - func_file_conv "$1" mingw - set x "$@" "$file" - shift - ;; - *) - set x "$@" "$1" - shift - ;; - esac - fi - shift - done - if test -n "$linker_opts"; then - linker_opts="-link$linker_opts" - fi - exec "$@" $linker_opts - exit 1 -} - -eat= - -case $1 in - '') - echo "$0: No command. Try '$0 --help' for more information." 1>&2 - exit 1; - ;; - -h | --h*) - cat <<\EOF -Usage: compile [--help] [--version] PROGRAM [ARGS] - -Wrapper for compilers which do not understand '-c -o'. -Remove '-o dest.o' from ARGS, run PROGRAM with the remaining -arguments, and rename the output as expected. - -If you are trying to build a whole package this is not the -right script to run: please start by reading the file 'INSTALL'. - -Report bugs to . -EOF - exit $? - ;; - -v | --v*) - echo "compile $scriptversion" - exit $? - ;; - cl | *[/\\]cl | cl.exe | *[/\\]cl.exe | \ - icl | *[/\\]icl | icl.exe | *[/\\]icl.exe ) - func_cl_wrapper "$@" # Doesn't return... - ;; -esac - -ofile= -cfile= - -for arg -do - if test -n "$eat"; then - eat= - else - case $1 in - -o) - # configure might choose to run compile as 'compile cc -o foo foo.c'. - # So we strip '-o arg' only if arg is an object. - eat=1 - case $2 in - *.o | *.obj) - ofile=$2 - ;; - *) - set x "$@" -o "$2" - shift - ;; - esac - ;; - *.c) - cfile=$1 - set x "$@" "$1" - shift - ;; - *) - set x "$@" "$1" - shift - ;; - esac - fi - shift -done - -if test -z "$ofile" || test -z "$cfile"; then - # If no '-o' option was seen then we might have been invoked from a - # pattern rule where we don't need one. That is ok -- this is a - # normal compilation that the losing compiler can handle. If no - # '.c' file was seen then we are probably linking. That is also - # ok. - exec "$@" -fi - -# Name of file we expect compiler to create. -cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'` - -# Create the lock directory. -# Note: use '[/\\:.-]' here to ensure that we don't use the same name -# that we are using for the .o file. Also, base the name on the expected -# object file name, since that is what matters with a parallel build. -lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d -while true; do - if mkdir "$lockdir" >/dev/null 2>&1; then - break - fi - sleep 1 -done -# FIXME: race condition here if user kills between mkdir and trap. -trap "rmdir '$lockdir'; exit 1" 1 2 15 - -# Run the compile. -"$@" -ret=$? - -if test -f "$cofile"; then - test "$cofile" = "$ofile" || mv "$cofile" "$ofile" -elif test -f "${cofile}bj"; then - test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile" -fi - -rmdir "$lockdir" -exit $ret - -# Local Variables: -# mode: shell-script -# sh-indentation: 2 -# eval: (add-hook 'before-save-hook 'time-stamp) -# time-stamp-start: "scriptversion=" -# time-stamp-format: "%:y-%02m-%02d.%02H" -# time-stamp-time-zone: "UTC0" -# time-stamp-end: "; # UTC" -# End: diff --git a/config.guess b/config.guess index f50dcdb..40eaed4 100755 --- a/config.guess +++ b/config.guess @@ -1,12 +1,14 @@ #! /bin/sh # Attempt to guess a canonical system name. -# Copyright 1992-2018 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, +# 2011 Free Software Foundation, Inc. -timestamp='2018-02-24' +timestamp='2011-05-11' # 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 -# the Free Software Foundation; either version 3 of the License, or +# the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but @@ -15,22 +17,26 @@ timestamp='2018-02-24' # General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with this program; if not, see . +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA +# 02110-1301, USA. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that -# program. This Exception is an additional permission under section 7 -# of the GNU General Public License, version 3 ("GPLv3"). +# the same distribution terms that you use for the rest of that program. + + +# Originally written by Per Bothner. Please send patches (context +# diff format) to and include a ChangeLog +# entry. # -# Originally written by Per Bothner; maintained since 2000 by Ben Elliston. +# 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. # # You can get the latest version of this script from: -# https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess -# -# Please send patches to . - +# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD me=`echo "$0" | sed -e 's,.*/,,'` @@ -39,7 +45,7 @@ Usage: $0 [OPTION] Output the configuration name of the system \`$me' is run on. -Options: +Operation modes: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit @@ -50,7 +56,9 @@ version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. -Copyright 1992-2018 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, 2011 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." @@ -107,9 +115,9 @@ trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; dummy=$tmp/dummy ; tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; case $CC_FOR_BUILD,$HOST_CC,$CC in - ,,) echo "int x;" > "$dummy.c" ; + ,,) echo "int x;" > $dummy.c ; for c in cc gcc c89 c99 ; do - if ($c -c -o "$dummy.o" "$dummy.c") >/dev/null 2>&1 ; then + if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then CC_FOR_BUILD="$c"; break ; fi ; done ; @@ -132,40 +140,12 @@ UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown -case "$UNAME_SYSTEM" in -Linux|GNU|GNU/*) - # If the system lacks a compiler, then just pick glibc. - # We could probably try harder. - LIBC=gnu - - eval "$set_cc_for_build" - cat <<-EOF > "$dummy.c" - #include - #if defined(__UCLIBC__) - LIBC=uclibc - #elif defined(__dietlibc__) - LIBC=dietlibc - #else - LIBC=gnu - #endif - EOF - eval "`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`" - - # If ldd exists, use it to detect musl libc. - if command -v ldd >/dev/null && \ - ldd --version 2>&1 | grep -q ^musl - then - LIBC=musl - fi - ;; -esac - # Note: order is significant - the case branches are not exclusive. -case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in +case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in *:NetBSD:*:*) # NetBSD (nbsd) targets should (where applicable) match one or - # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, + # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently # switched to ELF, *-*-netbsd* would select the old # object file format. This provides both forward @@ -175,31 +155,21 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in # Note: NetBSD doesn't particularly care about the vendor # portion of the name. We always set it to "unknown". sysctl="sysctl -n hw.machine_arch" - UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \ - "/sbin/$sysctl" 2>/dev/null || \ - "/usr/sbin/$sysctl" 2>/dev/null || \ - echo unknown)` - case "$UNAME_MACHINE_ARCH" in + UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ + /usr/sbin/$sysctl 2>/dev/null || echo unknown)` + case "${UNAME_MACHINE_ARCH}" in armeb) machine=armeb-unknown ;; arm*) machine=arm-unknown ;; sh3el) machine=shl-unknown ;; sh3eb) machine=sh-unknown ;; sh5el) machine=sh5le-unknown ;; - earmv*) - arch=`echo "$UNAME_MACHINE_ARCH" | sed -e 's,^e\(armv[0-9]\).*$,\1,'` - endian=`echo "$UNAME_MACHINE_ARCH" | sed -ne 's,^.*\(eb\)$,\1,p'` - machine="${arch}${endian}"-unknown - ;; - *) machine="$UNAME_MACHINE_ARCH"-unknown ;; + *) machine=${UNAME_MACHINE_ARCH}-unknown ;; esac # The Operating System including object format, if it has switched - # to ELF recently (or will in the future) and ABI. - case "$UNAME_MACHINE_ARCH" in - earm*) - os=netbsdelf - ;; + # to ELF recently, or will in the future. + case "${UNAME_MACHINE_ARCH}" in arm*|i386|m68k|ns32k|sh3*|sparc|vax) - eval "$set_cc_for_build" + eval $set_cc_for_build if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ELF__ then @@ -214,67 +184,40 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in os=netbsd ;; esac - # Determine ABI tags. - case "$UNAME_MACHINE_ARCH" in - earm*) - expr='s/^earmv[0-9]/-eabi/;s/eb$//' - abi=`echo "$UNAME_MACHINE_ARCH" | sed -e "$expr"` - ;; - esac # The OS release # Debian GNU/NetBSD machines have a different userland, and # thus, need a distinct triplet. However, they do not need # kernel version information, so it can be replaced with a # suitable tag, in the style of linux-gnu. - case "$UNAME_VERSION" in + case "${UNAME_VERSION}" in Debian*) release='-gnu' ;; *) - release=`echo "$UNAME_RELEASE" | sed -e 's/[-_].*//' | cut -d. -f1,2` + release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` ;; esac # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: # contains redundant information, the shorter form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. - echo "$machine-${os}${release}${abi}" - exit ;; - *:Bitrig:*:*) - UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` - echo "$UNAME_MACHINE_ARCH"-unknown-bitrig"$UNAME_RELEASE" + echo "${machine}-${os}${release}" exit ;; *:OpenBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` - echo "$UNAME_MACHINE_ARCH"-unknown-openbsd"$UNAME_RELEASE" - exit ;; - *:LibertyBSD:*:*) - UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'` - echo "$UNAME_MACHINE_ARCH"-unknown-libertybsd"$UNAME_RELEASE" - exit ;; - *:MidnightBSD:*:*) - echo "$UNAME_MACHINE"-unknown-midnightbsd"$UNAME_RELEASE" + echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} exit ;; *:ekkoBSD:*:*) - echo "$UNAME_MACHINE"-unknown-ekkobsd"$UNAME_RELEASE" + echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} exit ;; *:SolidBSD:*:*) - echo "$UNAME_MACHINE"-unknown-solidbsd"$UNAME_RELEASE" + echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} exit ;; macppc:MirBSD:*:*) - echo powerpc-unknown-mirbsd"$UNAME_RELEASE" + echo powerpc-unknown-mirbsd${UNAME_RELEASE} exit ;; *:MirBSD:*:*) - echo "$UNAME_MACHINE"-unknown-mirbsd"$UNAME_RELEASE" + echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} exit ;; - *:Sortix:*:*) - echo "$UNAME_MACHINE"-unknown-sortix - exit ;; - *:Redox:*:*) - echo "$UNAME_MACHINE"-unknown-redox - exit ;; - mips:OSF1:*.*) - echo mips-dec-osf1 - exit ;; alpha:OSF1:*:*) case $UNAME_RELEASE in *4.0) @@ -291,54 +234,63 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` case "$ALPHA_CPU_TYPE" in "EV4 (21064)") - UNAME_MACHINE=alpha ;; + UNAME_MACHINE="alpha" ;; "EV4.5 (21064)") - UNAME_MACHINE=alpha ;; + UNAME_MACHINE="alpha" ;; "LCA4 (21066/21068)") - UNAME_MACHINE=alpha ;; + UNAME_MACHINE="alpha" ;; "EV5 (21164)") - UNAME_MACHINE=alphaev5 ;; + UNAME_MACHINE="alphaev5" ;; "EV5.6 (21164A)") - UNAME_MACHINE=alphaev56 ;; + UNAME_MACHINE="alphaev56" ;; "EV5.6 (21164PC)") - UNAME_MACHINE=alphapca56 ;; + UNAME_MACHINE="alphapca56" ;; "EV5.7 (21164PC)") - UNAME_MACHINE=alphapca57 ;; + UNAME_MACHINE="alphapca57" ;; "EV6 (21264)") - UNAME_MACHINE=alphaev6 ;; + UNAME_MACHINE="alphaev6" ;; "EV6.7 (21264A)") - UNAME_MACHINE=alphaev67 ;; + UNAME_MACHINE="alphaev67" ;; "EV6.8CB (21264C)") - UNAME_MACHINE=alphaev68 ;; + UNAME_MACHINE="alphaev68" ;; "EV6.8AL (21264B)") - UNAME_MACHINE=alphaev68 ;; + UNAME_MACHINE="alphaev68" ;; "EV6.8CX (21264D)") - UNAME_MACHINE=alphaev68 ;; + UNAME_MACHINE="alphaev68" ;; "EV6.9A (21264/EV69A)") - UNAME_MACHINE=alphaev69 ;; + UNAME_MACHINE="alphaev69" ;; "EV7 (21364)") - UNAME_MACHINE=alphaev7 ;; + UNAME_MACHINE="alphaev7" ;; "EV7.9 (21364A)") - UNAME_MACHINE=alphaev79 ;; + UNAME_MACHINE="alphaev79" ;; esac # A Pn.n version is a patched version. # A Vn.n version is a released version. # A Tn.n version is a released field test version. # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. - echo "$UNAME_MACHINE"-dec-osf"`echo "$UNAME_RELEASE" | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`" + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` # Reset EXIT trap before exiting to avoid spurious non-zero exit code. exitcode=$? trap '' 0 exit $exitcode ;; + Alpha\ *:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # Should we change UNAME_MACHINE based on the output of uname instead + # of the specific Alpha model? + echo alpha-pc-interix + exit ;; + 21064:Windows_NT:50:3) + echo alpha-dec-winnt3.5 + exit ;; Amiga*:UNIX_System_V:4.0:*) echo m68k-unknown-sysv4 exit ;; *:[Aa]miga[Oo][Ss]:*:*) - echo "$UNAME_MACHINE"-unknown-amigaos + echo ${UNAME_MACHINE}-unknown-amigaos exit ;; *:[Mm]orph[Oo][Ss]:*:*) - echo "$UNAME_MACHINE"-unknown-morphos + echo ${UNAME_MACHINE}-unknown-morphos exit ;; *:OS/390:*:*) echo i370-ibm-openedition @@ -350,9 +302,9 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in echo powerpc-ibm-os400 exit ;; arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) - echo arm-acorn-riscix"$UNAME_RELEASE" + echo arm-acorn-riscix${UNAME_RELEASE} exit ;; - arm*:riscos:*:*|arm*:RISCOS:*:*) + arm:riscos:*:*|arm:RISCOS:*:*) echo arm-unknown-riscos exit ;; SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) @@ -377,38 +329,38 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in sparc) echo sparc-icl-nx7; exit ;; esac ;; s390x:SunOS:*:*) - echo "$UNAME_MACHINE"-ibm-solaris2"`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`" + echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4H:SunOS:5.*:*) - echo sparc-hal-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" + echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) - echo sparc-sun-solaris2"`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`" + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) - echo i386-pc-auroraux"$UNAME_RELEASE" + echo i386-pc-auroraux${UNAME_RELEASE} exit ;; i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) - eval "$set_cc_for_build" - SUN_ARCH=i386 + eval $set_cc_for_build + SUN_ARCH="i386" # If there is a compiler, see if it is configured for 64-bit objects. # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. # This test works for both compilers. - if [ "$CC_FOR_BUILD" != no_compiler_found ]; then + if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ - (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ + (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then - SUN_ARCH=x86_64 + SUN_ARCH="x86_64" fi fi - echo "$SUN_ARCH"-pc-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" + echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:6*:*) # According to config.sub, this is the proper way to canonicalize # SunOS6. Hard to guess exactly what SunOS6 will be like, but # it's likely to be more like Solaris than SunOS4. - echo sparc-sun-solaris3"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" + echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:*:*) case "`/usr/bin/arch -k`" in @@ -417,25 +369,25 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in ;; esac # Japanese Language versions have a version number like `4.1.3-JL'. - echo sparc-sun-sunos"`echo "$UNAME_RELEASE"|sed -e 's/-/_/'`" + echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` exit ;; sun3*:SunOS:*:*) - echo m68k-sun-sunos"$UNAME_RELEASE" + echo m68k-sun-sunos${UNAME_RELEASE} exit ;; sun*:*:4.2BSD:*) UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` - test "x$UNAME_RELEASE" = x && UNAME_RELEASE=3 + test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 case "`/bin/arch`" in sun3) - echo m68k-sun-sunos"$UNAME_RELEASE" + echo m68k-sun-sunos${UNAME_RELEASE} ;; sun4) - echo sparc-sun-sunos"$UNAME_RELEASE" + echo sparc-sun-sunos${UNAME_RELEASE} ;; esac exit ;; aushp:SunOS:*:*) - echo sparc-auspex-sunos"$UNAME_RELEASE" + echo sparc-auspex-sunos${UNAME_RELEASE} exit ;; # The situation for MiNT is a little confusing. The machine name # can be virtually everything (everything which is not @@ -446,44 +398,44 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in # MiNT. But MiNT is downward compatible to TOS, so this should # be no problem. atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) - echo m68k-atari-mint"$UNAME_RELEASE" + echo m68k-atari-mint${UNAME_RELEASE} exit ;; atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) - echo m68k-atari-mint"$UNAME_RELEASE" + echo m68k-atari-mint${UNAME_RELEASE} exit ;; *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) - echo m68k-atari-mint"$UNAME_RELEASE" + echo m68k-atari-mint${UNAME_RELEASE} exit ;; milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) - echo m68k-milan-mint"$UNAME_RELEASE" + echo m68k-milan-mint${UNAME_RELEASE} exit ;; hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) - echo m68k-hades-mint"$UNAME_RELEASE" + echo m68k-hades-mint${UNAME_RELEASE} exit ;; *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) - echo m68k-unknown-mint"$UNAME_RELEASE" + echo m68k-unknown-mint${UNAME_RELEASE} exit ;; m68k:machten:*:*) - echo m68k-apple-machten"$UNAME_RELEASE" + echo m68k-apple-machten${UNAME_RELEASE} exit ;; powerpc:machten:*:*) - echo powerpc-apple-machten"$UNAME_RELEASE" + echo powerpc-apple-machten${UNAME_RELEASE} exit ;; RISC*:Mach:*:*) echo mips-dec-mach_bsd4.3 exit ;; RISC*:ULTRIX:*:*) - echo mips-dec-ultrix"$UNAME_RELEASE" + echo mips-dec-ultrix${UNAME_RELEASE} exit ;; VAX*:ULTRIX*:*:*) - echo vax-dec-ultrix"$UNAME_RELEASE" + echo vax-dec-ultrix${UNAME_RELEASE} exit ;; 2020:CLIX:*:* | 2430:CLIX:*:*) - echo clipper-intergraph-clix"$UNAME_RELEASE" + echo clipper-intergraph-clix${UNAME_RELEASE} exit ;; mips:*:*:UMIPS | mips:*:*:RISCos) - eval "$set_cc_for_build" - sed 's/^ //' << EOF > "$dummy.c" + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c #ifdef __cplusplus #include /* for printf() prototype */ int main (int argc, char *argv[]) { @@ -492,23 +444,23 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in #endif #if defined (host_mips) && defined (MIPSEB) #if defined (SYSTYPE_SYSV) - printf ("mips-mips-riscos%ssysv\\n", argv[1]); exit (0); + printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_SVR4) - printf ("mips-mips-riscos%ssvr4\\n", argv[1]); exit (0); + printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) - printf ("mips-mips-riscos%sbsd\\n", argv[1]); exit (0); + printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); #endif #endif exit (-1); } EOF - $CC_FOR_BUILD -o "$dummy" "$dummy.c" && - dummyarg=`echo "$UNAME_RELEASE" | sed -n 's/\([0-9]*\).*/\1/p'` && - SYSTEM_NAME=`"$dummy" "$dummyarg"` && + $CC_FOR_BUILD -o $dummy $dummy.c && + dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && + SYSTEM_NAME=`$dummy $dummyarg` && { echo "$SYSTEM_NAME"; exit; } - echo mips-mips-riscos"$UNAME_RELEASE" + echo mips-mips-riscos${UNAME_RELEASE} exit ;; Motorola:PowerMAX_OS:*:*) echo powerpc-motorola-powermax @@ -534,17 +486,17 @@ EOF AViiON:dgux:*:*) # DG/UX returns AViiON for all architectures UNAME_PROCESSOR=`/usr/bin/uname -p` - if [ "$UNAME_PROCESSOR" = mc88100 ] || [ "$UNAME_PROCESSOR" = mc88110 ] + if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] then - if [ "$TARGET_BINARY_INTERFACE"x = m88kdguxelfx ] || \ - [ "$TARGET_BINARY_INTERFACE"x = x ] + if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ + [ ${TARGET_BINARY_INTERFACE}x = x ] then - echo m88k-dg-dgux"$UNAME_RELEASE" + echo m88k-dg-dgux${UNAME_RELEASE} else - echo m88k-dg-dguxbcs"$UNAME_RELEASE" + echo m88k-dg-dguxbcs${UNAME_RELEASE} fi else - echo i586-dg-dgux"$UNAME_RELEASE" + echo i586-dg-dgux${UNAME_RELEASE} fi exit ;; M88*:DolphinOS:*:*) # DolphinOS (SVR3) @@ -561,7 +513,7 @@ EOF echo m68k-tektronix-bsd exit ;; *:IRIX*:*:*) - echo mips-sgi-irix"`echo "$UNAME_RELEASE"|sed -e 's/-/_/g'`" + echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` exit ;; ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id @@ -573,14 +525,14 @@ EOF if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else - IBM_REV="$UNAME_VERSION.$UNAME_RELEASE" + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi - echo "$UNAME_MACHINE"-ibm-aix"$IBM_REV" + echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} exit ;; *:AIX:2:3) if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then - eval "$set_cc_for_build" - sed 's/^ //' << EOF > "$dummy.c" + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c #include main() @@ -591,7 +543,7 @@ EOF exit(0); } EOF - if $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` + if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` then echo "$SYSTEM_NAME" else @@ -605,27 +557,26 @@ EOF exit ;; *:AIX:*:[4567]) IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` - if /usr/sbin/lsattr -El "$IBM_CPU_ID" | grep ' POWER' >/dev/null 2>&1; then + if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then IBM_ARCH=rs6000 else IBM_ARCH=powerpc fi - if [ -x /usr/bin/lslpp ] ; then - IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc | - awk -F: '{ print $3 }' | sed s/[0-9]*$/0/` + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` else - IBM_REV="$UNAME_VERSION.$UNAME_RELEASE" + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi - echo "$IBM_ARCH"-ibm-aix"$IBM_REV" + echo ${IBM_ARCH}-ibm-aix${IBM_REV} exit ;; *:AIX:*:*) echo rs6000-ibm-aix exit ;; - ibmrt:4.4BSD:*|romp-ibm:4.4BSD:*) + ibmrt:4.4BSD:*|romp-ibm:BSD:*) echo romp-ibm-bsd4.4 exit ;; ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and - echo romp-ibm-bsd"$UNAME_RELEASE" # 4.3 with uname added to + echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to exit ;; # report: romp-ibm BSD 4.3 *:BOSX:*:*) echo rs6000-bull-bosx @@ -640,28 +591,28 @@ EOF echo m68k-hp-bsd4.4 exit ;; 9000/[34678]??:HP-UX:*:*) - HPUX_REV=`echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//'` - case "$UNAME_MACHINE" in - 9000/31?) HP_ARCH=m68000 ;; - 9000/[34]??) HP_ARCH=m68k ;; + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + case "${UNAME_MACHINE}" in + 9000/31? ) HP_ARCH=m68000 ;; + 9000/[34]?? ) HP_ARCH=m68k ;; 9000/[678][0-9][0-9]) if [ -x /usr/bin/getconf ]; then sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` - case "$sc_cpu_version" in - 523) HP_ARCH=hppa1.0 ;; # CPU_PA_RISC1_0 - 528) HP_ARCH=hppa1.1 ;; # CPU_PA_RISC1_1 + case "${sc_cpu_version}" in + 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 + 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 532) # CPU_PA_RISC2_0 - case "$sc_kernel_bits" in - 32) HP_ARCH=hppa2.0n ;; - 64) HP_ARCH=hppa2.0w ;; - '') HP_ARCH=hppa2.0 ;; # HP-UX 10.20 + case "${sc_kernel_bits}" in + 32) HP_ARCH="hppa2.0n" ;; + 64) HP_ARCH="hppa2.0w" ;; + '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 esac ;; esac fi - if [ "$HP_ARCH" = "" ]; then - eval "$set_cc_for_build" - sed 's/^ //' << EOF > "$dummy.c" + if [ "${HP_ARCH}" = "" ]; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c #define _HPUX_SOURCE #include @@ -694,13 +645,13 @@ EOF exit (0); } EOF - (CCOPTS="" $CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null) && HP_ARCH=`"$dummy"` + (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` test -z "$HP_ARCH" && HP_ARCH=hppa fi ;; esac - if [ "$HP_ARCH" = hppa2.0w ] + if [ ${HP_ARCH} = "hppa2.0w" ] then - eval "$set_cc_for_build" + eval $set_cc_for_build # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler @@ -711,23 +662,23 @@ EOF # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess # => hppa64-hp-hpux11.23 - if echo __LP64__ | (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | + if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | grep -q __LP64__ then - HP_ARCH=hppa2.0w + HP_ARCH="hppa2.0w" else - HP_ARCH=hppa64 + HP_ARCH="hppa64" fi fi - echo "$HP_ARCH"-hp-hpux"$HPUX_REV" + echo ${HP_ARCH}-hp-hpux${HPUX_REV} exit ;; ia64:HP-UX:*:*) - HPUX_REV=`echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//'` - echo ia64-hp-hpux"$HPUX_REV" + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux${HPUX_REV} exit ;; 3050*:HI-UX:*:*) - eval "$set_cc_for_build" - sed 's/^ //' << EOF > "$dummy.c" + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c #include int main () @@ -752,11 +703,11 @@ EOF exit (0); } EOF - $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` && + $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && { echo "$SYSTEM_NAME"; exit; } echo unknown-hitachi-hiuxwe2 exit ;; - 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:*) + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) echo hppa1.1-hp-bsd exit ;; 9000/8??:4.3bsd:*:*) @@ -765,7 +716,7 @@ EOF *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) echo hppa1.0-hp-mpeix exit ;; - hp7??:OSF1:*:* | hp8?[79]:OSF1:*:*) + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) echo hppa1.1-hp-osf exit ;; hp8??:OSF1:*:*) @@ -773,9 +724,9 @@ EOF exit ;; i*86:OSF1:*:*) if [ -x /usr/sbin/sysversion ] ; then - echo "$UNAME_MACHINE"-unknown-osf1mk + echo ${UNAME_MACHINE}-unknown-osf1mk else - echo "$UNAME_MACHINE"-unknown-osf1 + echo ${UNAME_MACHINE}-unknown-osf1 fi exit ;; parisc*:Lites*:*:*) @@ -800,109 +751,115 @@ EOF echo c4-convex-bsd exit ;; CRAY*Y-MP:*:*:*) - echo ymp-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' + echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*[A-Z]90:*:*:*) - echo "$UNAME_MACHINE"-cray-unicos"$UNAME_RELEASE" \ + echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ -e 's/\.[^.]*$/.X/' exit ;; CRAY*TS:*:*:*) - echo t90-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' + echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*T3E:*:*:*) - echo alphaev5-cray-unicosmk"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' + echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*SV1:*:*:*) - echo sv1-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' + echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; *:UNICOS/mp:*:*) - echo craynv-cray-unicosmp"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' + echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) - FUJITSU_PROC=`uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` - FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` - FUJITSU_REL=`echo "$UNAME_RELEASE" | sed -e 's/ /_/'` + FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; 5000:UNIX_System_V:4.*:*) - FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` - FUJITSU_REL=`echo "$UNAME_RELEASE" | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'` + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) - echo "$UNAME_MACHINE"-pc-bsdi"$UNAME_RELEASE" + echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} exit ;; sparc*:BSD/OS:*:*) - echo sparc-unknown-bsdi"$UNAME_RELEASE" + echo sparc-unknown-bsdi${UNAME_RELEASE} exit ;; *:BSD/OS:*:*) - echo "$UNAME_MACHINE"-unknown-bsdi"$UNAME_RELEASE" + echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} exit ;; *:FreeBSD:*:*) - UNAME_PROCESSOR=`/usr/bin/uname -p` - case "$UNAME_PROCESSOR" in + case ${UNAME_MACHINE} in + pc98) + echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; amd64) - UNAME_PROCESSOR=x86_64 ;; - i386) - UNAME_PROCESSOR=i586 ;; + echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + *) + echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; esac - echo "$UNAME_PROCESSOR"-unknown-freebsd"`echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`" exit ;; i*:CYGWIN*:*) - echo "$UNAME_MACHINE"-pc-cygwin - exit ;; - *:MINGW64*:*) - echo "$UNAME_MACHINE"-pc-mingw64 + echo ${UNAME_MACHINE}-pc-cygwin exit ;; *:MINGW*:*) - echo "$UNAME_MACHINE"-pc-mingw32 + echo ${UNAME_MACHINE}-pc-mingw32 exit ;; - *:MSYS*:*) - echo "$UNAME_MACHINE"-pc-msys + i*:windows32*:*) + # uname -m includes "-pc" on this system. + echo ${UNAME_MACHINE}-mingw32 exit ;; i*:PW*:*) - echo "$UNAME_MACHINE"-pc-pw32 + echo ${UNAME_MACHINE}-pc-pw32 exit ;; *:Interix*:*) - case "$UNAME_MACHINE" in + case ${UNAME_MACHINE} in x86) - echo i586-pc-interix"$UNAME_RELEASE" + echo i586-pc-interix${UNAME_RELEASE} exit ;; authenticamd | genuineintel | EM64T) - echo x86_64-unknown-interix"$UNAME_RELEASE" + echo x86_64-unknown-interix${UNAME_RELEASE} exit ;; IA64) - echo ia64-unknown-interix"$UNAME_RELEASE" + echo ia64-unknown-interix${UNAME_RELEASE} exit ;; esac ;; + [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) + echo i${UNAME_MACHINE}-pc-mks + exit ;; + 8664:Windows_NT:*) + echo x86_64-pc-mks + exit ;; + i*:Windows_NT*:* | Pentium*:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we + # UNAME_MACHINE based on the output of uname instead of i386? + echo i586-pc-interix + exit ;; i*:UWIN*:*) - echo "$UNAME_MACHINE"-pc-uwin + echo ${UNAME_MACHINE}-pc-uwin exit ;; amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) echo x86_64-unknown-cygwin exit ;; + p*:CYGWIN*:*) + echo powerpcle-unknown-cygwin + exit ;; prep*:SunOS:5.*:*) - echo powerpcle-unknown-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" + echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; *:GNU:*:*) # the GNU system - echo "`echo "$UNAME_MACHINE"|sed -e 's,[-/].*$,,'`-unknown-$LIBC`echo "$UNAME_RELEASE"|sed -e 's,/.*$,,'`" + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` exit ;; *:GNU/*:*:*) # other systems with GNU libc and userland - echo "$UNAME_MACHINE-unknown-`echo "$UNAME_SYSTEM" | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"``echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`-$LIBC" + echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu exit ;; i*86:Minix:*:*) - echo "$UNAME_MACHINE"-pc-minix - exit ;; - aarch64:Linux:*:*) - echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" - exit ;; - aarch64_be:Linux:*:*) - UNAME_MACHINE=aarch64_be - echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + echo ${UNAME_MACHINE}-pc-minix exit ;; alpha:Linux:*:*) case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in @@ -915,64 +872,60 @@ EOF EV68*) UNAME_MACHINE=alphaev68 ;; esac objdump --private-headers /bin/sh | grep -q ld.so.1 - if test "$?" = 0 ; then LIBC=gnulibc1 ; fi - echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" - exit ;; - arc:Linux:*:* | arceb:Linux:*:*) - echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi + echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} exit ;; arm*:Linux:*:*) - eval "$set_cc_for_build" + eval $set_cc_for_build if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_EABI__ then - echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + echo ${UNAME_MACHINE}-unknown-linux-gnu else if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_PCS_VFP then - echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"eabi + echo ${UNAME_MACHINE}-unknown-linux-gnueabi else - echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"eabihf + echo ${UNAME_MACHINE}-unknown-linux-gnueabihf fi fi exit ;; avr32*:Linux:*:*) - echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; cris:Linux:*:*) - echo "$UNAME_MACHINE"-axis-linux-"$LIBC" + echo cris-axis-linux-gnu exit ;; crisv32:Linux:*:*) - echo "$UNAME_MACHINE"-axis-linux-"$LIBC" - exit ;; - e2k:Linux:*:*) - echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + echo crisv32-axis-linux-gnu exit ;; frv:Linux:*:*) - echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" - exit ;; - hexagon:Linux:*:*) - echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + echo frv-unknown-linux-gnu exit ;; i*86:Linux:*:*) - echo "$UNAME_MACHINE"-pc-linux-"$LIBC" + 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-"$LIBC" - exit ;; - k1om:Linux:*:*) - echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; m32r*:Linux:*:*) - echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; m68*:Linux:*:*) - echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; mips:Linux:*:* | mips64:Linux:*:*) - eval "$set_cc_for_build" - sed 's/^ //' << EOF > "$dummy.c" + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c #undef CPU #undef ${UNAME_MACHINE} #undef ${UNAME_MACHINE}el @@ -986,74 +939,55 @@ EOF #endif #endif EOF - eval "`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^CPU'`" - test "x$CPU" != x && { echo "$CPU-unknown-linux-$LIBC"; exit; } + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` + test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } ;; - mips64el:Linux:*:*) - echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" - exit ;; - openrisc*:Linux:*:*) - echo or1k-unknown-linux-"$LIBC" - exit ;; - or32:Linux:*:* | or1k*:Linux:*:*) - echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + or32:Linux:*:*) + echo or32-unknown-linux-gnu exit ;; padre:Linux:*:*) - echo sparc-unknown-linux-"$LIBC" + echo sparc-unknown-linux-gnu exit ;; parisc64:Linux:*:* | hppa64:Linux:*:*) - echo hppa64-unknown-linux-"$LIBC" + 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 - PA7*) echo hppa1.1-unknown-linux-"$LIBC" ;; - PA8*) echo hppa2.0-unknown-linux-"$LIBC" ;; - *) echo hppa-unknown-linux-"$LIBC" ;; + PA7*) echo hppa1.1-unknown-linux-gnu ;; + PA8*) echo hppa2.0-unknown-linux-gnu ;; + *) echo hppa-unknown-linux-gnu ;; esac exit ;; ppc64:Linux:*:*) - echo powerpc64-unknown-linux-"$LIBC" + echo powerpc64-unknown-linux-gnu exit ;; ppc:Linux:*:*) - echo powerpc-unknown-linux-"$LIBC" - exit ;; - ppc64le:Linux:*:*) - echo powerpc64le-unknown-linux-"$LIBC" - exit ;; - ppcle:Linux:*:*) - echo powerpcle-unknown-linux-"$LIBC" - exit ;; - riscv32:Linux:*:* | riscv64:Linux:*:*) - echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + echo powerpc-unknown-linux-gnu exit ;; s390:Linux:*:* | s390x:Linux:*:*) - echo "$UNAME_MACHINE"-ibm-linux-"$LIBC" + echo ${UNAME_MACHINE}-ibm-linux exit ;; sh64*:Linux:*:*) - echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; sh*:Linux:*:*) - echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; sparc:Linux:*:* | sparc64:Linux:*:*) - echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; tile*:Linux:*:*) - echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + echo ${UNAME_MACHINE}-tilera-linux-gnu exit ;; vax:Linux:*:*) - echo "$UNAME_MACHINE"-dec-linux-"$LIBC" + echo ${UNAME_MACHINE}-dec-linux-gnu exit ;; x86_64:Linux:*:*) - if objdump -f /bin/sh | grep -q elf32-x86-64; then - echo "$UNAME_MACHINE"-pc-linux-"$LIBC"x32 - else - echo "$UNAME_MACHINE"-pc-linux-"$LIBC" - fi + echo x86_64-unknown-linux-gnu exit ;; xtensa*:Linux:*:*) - echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; i*86:DYNIX/ptx:4*:*) # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. @@ -1067,34 +1001,34 @@ EOF # I am not positive that other SVR4 systems won't match this, # I just have to hope. -- rms. # Use sysv4.2uw... so that sysv4* matches it. - echo "$UNAME_MACHINE"-pc-sysv4.2uw"$UNAME_VERSION" + echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} exit ;; i*86:OS/2:*:*) # If we were able to find `uname', then EMX Unix compatibility # is probably installed. - echo "$UNAME_MACHINE"-pc-os2-emx + echo ${UNAME_MACHINE}-pc-os2-emx exit ;; i*86:XTS-300:*:STOP) - echo "$UNAME_MACHINE"-unknown-stop + echo ${UNAME_MACHINE}-unknown-stop exit ;; i*86:atheos:*:*) - echo "$UNAME_MACHINE"-unknown-atheos + echo ${UNAME_MACHINE}-unknown-atheos exit ;; i*86:syllable:*:*) - echo "$UNAME_MACHINE"-pc-syllable + echo ${UNAME_MACHINE}-pc-syllable exit ;; i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) - echo i386-unknown-lynxos"$UNAME_RELEASE" + echo i386-unknown-lynxos${UNAME_RELEASE} exit ;; i*86:*DOS:*:*) - echo "$UNAME_MACHINE"-pc-msdosdjgpp + echo ${UNAME_MACHINE}-pc-msdosdjgpp exit ;; - i*86:*:4.*:*) - UNAME_REL=`echo "$UNAME_RELEASE" | sed 's/\/MP$//'` + i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) + UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then - echo "$UNAME_MACHINE"-univel-sysv"$UNAME_REL" + echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} else - echo "$UNAME_MACHINE"-pc-sysv"$UNAME_REL" + echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} fi exit ;; i*86:*:5:[678]*) @@ -1104,12 +1038,12 @@ EOF *Pentium) UNAME_MACHINE=i586 ;; *Pent*|*Celeron) UNAME_MACHINE=i686 ;; esac - echo "$UNAME_MACHINE-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}{$UNAME_VERSION}" + echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} exit ;; i*86:*:3.2:*) if test -f /usr/options/cb.name; then UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 @@ -1119,9 +1053,9 @@ EOF && UNAME_MACHINE=i686 (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ && UNAME_MACHINE=i686 - echo "$UNAME_MACHINE"-pc-sco"$UNAME_REL" + echo ${UNAME_MACHINE}-pc-sco$UNAME_REL else - echo "$UNAME_MACHINE"-pc-sysv32 + echo ${UNAME_MACHINE}-pc-sysv32 fi exit ;; pc:*:*:*) @@ -1129,7 +1063,7 @@ EOF # uname -m prints for DJGPP always 'pc', but it prints nothing about # the processor, so we play safe by assuming i586. # Note: whatever this is, it MUST be the same as what config.sub - # prints for the "djgpp" host, or else GDB configure will decide that + # prints for the "djgpp" host, or else GDB configury will decide that # this is a cross-build. echo i586-pc-msdosdjgpp exit ;; @@ -1141,9 +1075,9 @@ EOF exit ;; i860:*:4.*:*) # i860-SVR4 if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then - echo i860-stardent-sysv"$UNAME_RELEASE" # Stardent Vistra i860-SVR4 + echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 else # Add other i860-SVR4 vendors below as they are discovered. - echo i860-unknown-sysv"$UNAME_RELEASE" # Unknown i860-SVR4 + echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 fi exit ;; mini*:CTIX:SYS*5:*) @@ -1163,9 +1097,9 @@ EOF test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && { echo i486-ncr-sysv4.3"$OS_REL"; exit; } + && { echo i486-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ - && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;; + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4; exit; } ;; @@ -1174,28 +1108,28 @@ EOF test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && { echo i486-ncr-sysv4.3"$OS_REL"; exit; } + && { echo i486-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ - && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ - && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;; + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) - echo m68k-unknown-lynxos"$UNAME_RELEASE" + echo m68k-unknown-lynxos${UNAME_RELEASE} exit ;; mc68030:UNIX_System_V:4.*:*) echo m68k-atari-sysv4 exit ;; TSUNAMI:LynxOS:2.*:*) - echo sparc-unknown-lynxos"$UNAME_RELEASE" + echo sparc-unknown-lynxos${UNAME_RELEASE} exit ;; rs6000:LynxOS:2.*:*) - echo rs6000-unknown-lynxos"$UNAME_RELEASE" + echo rs6000-unknown-lynxos${UNAME_RELEASE} exit ;; PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) - echo powerpc-unknown-lynxos"$UNAME_RELEASE" + echo powerpc-unknown-lynxos${UNAME_RELEASE} exit ;; SM[BE]S:UNIX_SV:*:*) - echo mips-dde-sysv"$UNAME_RELEASE" + echo mips-dde-sysv${UNAME_RELEASE} exit ;; RM*:ReliantUNIX-*:*:*) echo mips-sni-sysv4 @@ -1206,7 +1140,7 @@ EOF *:SINIX-*:*:*) if uname -p 2>/dev/null >/dev/null ; then UNAME_MACHINE=`(uname -p) 2>/dev/null` - echo "$UNAME_MACHINE"-sni-sysv4 + echo ${UNAME_MACHINE}-sni-sysv4 else echo ns32k-sni-sysv fi @@ -1226,23 +1160,23 @@ EOF exit ;; i*86:VOS:*:*) # From Paul.Green@stratus.com. - echo "$UNAME_MACHINE"-stratus-vos + echo ${UNAME_MACHINE}-stratus-vos exit ;; *:VOS:*:*) # From Paul.Green@stratus.com. echo hppa1.1-stratus-vos exit ;; mc68*:A/UX:*:*) - echo m68k-apple-aux"$UNAME_RELEASE" + echo m68k-apple-aux${UNAME_RELEASE} exit ;; news*:NEWS-OS:6*:*) echo mips-sony-newsos6 exit ;; R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) if [ -d /usr/nec ]; then - echo mips-nec-sysv"$UNAME_RELEASE" + echo mips-nec-sysv${UNAME_RELEASE} else - echo mips-unknown-sysv"$UNAME_RELEASE" + echo mips-unknown-sysv${UNAME_RELEASE} fi exit ;; BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. @@ -1257,97 +1191,66 @@ EOF BePC:Haiku:*:*) # Haiku running on Intel PC compatible. echo i586-pc-haiku exit ;; - x86_64:Haiku:*:*) - echo x86_64-unknown-haiku - exit ;; SX-4:SUPER-UX:*:*) - echo sx4-nec-superux"$UNAME_RELEASE" + echo sx4-nec-superux${UNAME_RELEASE} exit ;; SX-5:SUPER-UX:*:*) - echo sx5-nec-superux"$UNAME_RELEASE" + echo sx5-nec-superux${UNAME_RELEASE} exit ;; SX-6:SUPER-UX:*:*) - echo sx6-nec-superux"$UNAME_RELEASE" + echo sx6-nec-superux${UNAME_RELEASE} exit ;; SX-7:SUPER-UX:*:*) - echo sx7-nec-superux"$UNAME_RELEASE" + echo sx7-nec-superux${UNAME_RELEASE} exit ;; SX-8:SUPER-UX:*:*) - echo sx8-nec-superux"$UNAME_RELEASE" + echo sx8-nec-superux${UNAME_RELEASE} exit ;; SX-8R:SUPER-UX:*:*) - echo sx8r-nec-superux"$UNAME_RELEASE" - exit ;; - SX-ACE:SUPER-UX:*:*) - echo sxace-nec-superux"$UNAME_RELEASE" + echo sx8r-nec-superux${UNAME_RELEASE} exit ;; Power*:Rhapsody:*:*) - echo powerpc-apple-rhapsody"$UNAME_RELEASE" + echo powerpc-apple-rhapsody${UNAME_RELEASE} exit ;; *:Rhapsody:*:*) - echo "$UNAME_MACHINE"-apple-rhapsody"$UNAME_RELEASE" + echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} exit ;; *:Darwin:*:*) UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown - eval "$set_cc_for_build" - if test "$UNAME_PROCESSOR" = unknown ; then - UNAME_PROCESSOR=powerpc - fi - if test "`echo "$UNAME_RELEASE" | sed -e 's/\..*//'`" -le 10 ; then - 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 - case $UNAME_PROCESSOR in - i386) UNAME_PROCESSOR=x86_64 ;; - powerpc) UNAME_PROCESSOR=powerpc64 ;; - esac - fi - # On 10.4-10.6 one might compile for PowerPC via gcc -arch ppc - if (echo '#ifdef __POWERPC__'; echo IS_PPC; echo '#endif') | \ - (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ - grep IS_PPC >/dev/null - then - UNAME_PROCESSOR=powerpc - fi - fi - elif test "$UNAME_PROCESSOR" = i386 ; then - # Avoid executing cc on OS X 10.9, as it ships with a stub - # that puts up a graphical alert prompting to install - # developer tools. Any system running Mac OS X 10.7 or - # later (Darwin 11 and later) is required to have a 64-bit - # processor. This is not true of the ARM version of Darwin - # that Apple uses in portable devices. - UNAME_PROCESSOR=x86_64 - fi - echo "$UNAME_PROCESSOR"-apple-darwin"$UNAME_RELEASE" + 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} exit ;; *:procnto*:*:* | *:QNX:[0123456789]*:*) UNAME_PROCESSOR=`uname -p` - if test "$UNAME_PROCESSOR" = x86; then + if test "$UNAME_PROCESSOR" = "x86"; then UNAME_PROCESSOR=i386 UNAME_MACHINE=pc fi - echo "$UNAME_PROCESSOR"-"$UNAME_MACHINE"-nto-qnx"$UNAME_RELEASE" + echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} exit ;; *:QNX:*:4*) echo i386-pc-qnx exit ;; - NEO-*:NONSTOP_KERNEL:*:*) - echo neo-tandem-nsk"$UNAME_RELEASE" + NEO-?:NONSTOP_KERNEL:*:*) + echo neo-tandem-nsk${UNAME_RELEASE} exit ;; - NSE-*:NONSTOP_KERNEL:*:*) - echo nse-tandem-nsk"$UNAME_RELEASE" + NSE-?:NONSTOP_KERNEL:*:*) + echo nse-tandem-nsk${UNAME_RELEASE} exit ;; - NSR-*:NONSTOP_KERNEL:*:*) - echo nsr-tandem-nsk"$UNAME_RELEASE" - exit ;; - NSV-*:NONSTOP_KERNEL:*:*) - echo nsv-tandem-nsk"$UNAME_RELEASE" - exit ;; - NSX-*:NONSTOP_KERNEL:*:*) - echo nsx-tandem-nsk"$UNAME_RELEASE" + NSR-?:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk${UNAME_RELEASE} exit ;; *:NonStop-UX:*:*) echo mips-compaq-nonstopux @@ -1356,18 +1259,18 @@ EOF echo bs2000-siemens-sysv exit ;; DS/*:UNIX_System_V:*:*) - echo "$UNAME_MACHINE"-"$UNAME_SYSTEM"-"$UNAME_RELEASE" + echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} exit ;; *:Plan9:*:*) # "uname -m" is not consistent, so use $cputype instead. 386 # is converted to i386 for consistency with other x86 # operating systems. - if test "$cputype" = 386; then + if test "$cputype" = "386"; then UNAME_MACHINE=i386 else UNAME_MACHINE="$cputype" fi - echo "$UNAME_MACHINE"-unknown-plan9 + echo ${UNAME_MACHINE}-unknown-plan9 exit ;; *:TOPS-10:*:*) echo pdp10-unknown-tops10 @@ -1388,14 +1291,14 @@ EOF echo pdp10-unknown-its exit ;; SEI:*:*:SEIUX) - echo mips-sei-seiux"$UNAME_RELEASE" + echo mips-sei-seiux${UNAME_RELEASE} exit ;; *:DragonFly:*:*) - echo "$UNAME_MACHINE"-unknown-dragonfly"`echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`" + echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` exit ;; *:*VMS:*:*) UNAME_MACHINE=`(uname -p) 2>/dev/null` - case "$UNAME_MACHINE" in + case "${UNAME_MACHINE}" in A*) echo alpha-dec-vms ; exit ;; I*) echo ia64-dec-vms ; exit ;; V*) echo vax-dec-vms ; exit ;; @@ -1404,48 +1307,182 @@ EOF echo i386-pc-xenix exit ;; i*86:skyos:*:*) - echo "$UNAME_MACHINE"-pc-skyos"`echo "$UNAME_RELEASE" | sed -e 's/ .*$//'`" + echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' exit ;; i*86:rdos:*:*) - echo "$UNAME_MACHINE"-pc-rdos + echo ${UNAME_MACHINE}-pc-rdos exit ;; i*86:AROS:*:*) - echo "$UNAME_MACHINE"-pc-aros - exit ;; - x86_64:VMkernel:*:*) - echo "$UNAME_MACHINE"-unknown-esx - exit ;; - amd64:Isilon\ OneFS:*:*) - echo x86_64-unknown-onefs + echo ${UNAME_MACHINE}-pc-aros exit ;; esac -echo "$0: unable to guess system type" >&2 +#echo '(No uname command or uname output not recognized.)' 1>&2 +#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 -case "$UNAME_MACHINE:$UNAME_SYSTEM" in - mips:Linux | mips64:Linux) - # If we got here on MIPS GNU/Linux, output extra information. - cat >&2 <$dummy.c < +# include +#endif +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif -NOTE: MIPS GNU/Linux systems require a C compiler to fully recognize -the system type. Please install a C compiler and try again. +#if defined (__arm) && defined (__acorn) && defined (__unix) + printf ("arm-acorn-riscix\n"); exit (0); +#endif + +#if defined (hp300) && !defined (hpux) + printf ("m68k-hp-bsd\n"); exit (0); +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + if (version < 4) + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + else + printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-pc-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); + +#endif + +#if defined (vax) +# if !defined (ultrix) +# include +# if defined (BSD) +# if BSD == 43 + printf ("vax-dec-bsd4.3\n"); exit (0); +# else +# if BSD == 199006 + printf ("vax-dec-bsd4.3reno\n"); exit (0); +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# endif +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# else + printf ("vax-dec-ultrix\n"); exit (0); +# endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} EOF - ;; -esac + +$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + +# Apollos put the system type in the environment. + +test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } + +# Convex versions that predate uname can use getsysinfo(1) + +if [ -x /usr/convex/getsysinfo ] +then + case `getsysinfo -f cpu_type` in + c1*) + echo c1-convex-bsd + exit ;; + c2*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + c34*) + echo c34-convex-bsd + exit ;; + c38*) + echo c38-convex-bsd + exit ;; + c4*) + echo c4-convex-bsd + exit ;; + esac +fi cat >&2 < in order to provide the needed +information to handle your system. config.guess timestamp = $timestamp @@ -1464,16 +1501,16 @@ hostinfo = `(hostinfo) 2>/dev/null` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` -UNAME_MACHINE = "$UNAME_MACHINE" -UNAME_RELEASE = "$UNAME_RELEASE" -UNAME_SYSTEM = "$UNAME_SYSTEM" -UNAME_VERSION = "$UNAME_VERSION" +UNAME_MACHINE = ${UNAME_MACHINE} +UNAME_RELEASE = ${UNAME_RELEASE} +UNAME_SYSTEM = ${UNAME_SYSTEM} +UNAME_VERSION = ${UNAME_VERSION} EOF exit 1 # Local variables: -# eval: (add-hook 'write-file-functions 'time-stamp) +# eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" diff --git a/config.h.in b/config.h.in index cc68348..3d4493a 100644 --- a/config.h.in +++ b/config.h.in @@ -1,4 +1,4 @@ -/* config.h.in. Generated from configure.ac by autoheader. */ +/* config.h.in. Generated from configure.in by autoheader. */ /* Support for jumbograms (packets up to 9000 bytes) */ #undef ENABLE_JUMBOGRAMS @@ -6,27 +6,21 @@ /* Support for tunemu */ #undef ENABLE_TUNEMU -/* Support for UML */ -#undef ENABLE_UML - -/* Support for VDE */ -#undef ENABLE_VDE - /* Define to 1 if you have the header file. */ #undef HAVE_ARPA_INET_H -/* Define to 1 if you have the header file. */ -#undef HAVE_ARPA_NAMESER_H - /* Define to 1 if you have the `asprintf' function. */ #undef HAVE_ASPRINTF -/* Define to 1 if you have the `BN_GENCB_new' function. */ -#undef HAVE_BN_GENCB_NEW - /* Unknown BSD variant */ #undef HAVE_BSD +/* have curses support */ +#undef HAVE_CURSES + +/* Define to 1 if you have the header file. */ +#undef HAVE_CURSES_H + /* Cygwin */ #undef HAVE_CYGWIN @@ -36,10 +30,6 @@ /* Darwin (MacOS/X) */ #undef HAVE_DARWIN -/* Define to 1 if you have the declaration of `EVP_aes_256_cfb', and to 0 if - you don't. */ -#undef HAVE_DECL_EVP_AES_256_CFB - /* Define to 1 if you have the declaration of `freeaddrinfo', and to 0 if you don't. */ #undef HAVE_DECL_FREEADDRINFO @@ -56,25 +46,14 @@ don't. */ #undef HAVE_DECL_GETNAMEINFO -/* Define to 1 if you have the declaration of `OpenSSL_add_all_algorithms', - and to 0 if you don't. */ -#undef HAVE_DECL_OPENSSL_ADD_ALL_ALGORITHMS - -/* Define to 1 if you have the declaration of `res_init', and to 0 if you - don't. */ -#undef HAVE_DECL_RES_INIT - -/* Define to 1 if you have the `devname' function. */ -#undef HAVE_DEVNAME - /* Define to 1 if you have the header file. */ #undef HAVE_DIRENT_H /* DragonFly */ #undef HAVE_DRAGONFLY -/* Define to 1 if you have the `EVP_CIPHER_CTX_new' function. */ -#undef HAVE_EVP_CIPHER_CTX_NEW +/* Define to 1 if you have the header file. */ +#undef HAVE_EVENT_H /* Define to 1 if you have the `EVP_EncryptInit_ex' function. */ #undef HAVE_EVP_ENCRYPTINIT_EX @@ -82,9 +61,6 @@ /* Define to 1 if you have the `fchmod' function. */ #undef HAVE_FCHMOD -/* Define to 1 if you have the `fdevname' function. */ -#undef HAVE_FDEVNAME - /* Define to 1 if you have the `flock' function. */ #undef HAVE_FLOCK @@ -94,30 +70,24 @@ /* FreeBSD */ #undef HAVE_FREEBSD -/* Define to 1 if you have the header file. */ -#undef HAVE_GETOPT_H - -/* getopt_long() */ -#undef HAVE_GETOPT_LONG +/* Define to 1 if you have the `ftime' function. */ +#undef HAVE_FTIME /* Define to 1 if you have the `gettimeofday' function. */ #undef HAVE_GETTIMEOFDAY +/* Define to 1 if you have the `get_current_dir_name' function. */ +#undef HAVE_GET_CURRENT_DIR_NAME + /* Define to 1 if you have the header file. */ #undef HAVE_INTTYPES_H /* Define to 1 if you have the `nsl' library (-lnsl). */ #undef HAVE_LIBNSL -/* Define to 1 if you have the `resolv' library (-lresolv). */ -#undef HAVE_LIBRESOLV - /* Define to 1 if you have the `socket' library (-lsocket). */ #undef HAVE_LIBSOCKET -/* Define to 1 if you have the header file. */ -#undef HAVE_LIBVDEPLUG_DYN_H - /* Linux */ #undef HAVE_LINUX @@ -178,9 +148,6 @@ /* Define to 1 if you have the header file. */ #undef HAVE_NETINET_TCP_H -/* Define to 1 if you have the header file. */ -#undef HAVE_NETPACKET_PACKET_H - /* Define to 1 if you have the header file. */ #undef HAVE_NET_ETHERNET_H @@ -199,9 +166,6 @@ /* Define to 1 if you have the header file. */ #undef HAVE_NET_IF_TYPES_H -/* Define to 1 if you have the header file. */ -#undef HAVE_NET_IF_UTUN_H - /* Define to 1 if you have the header file. */ #undef HAVE_NET_TAP_IF_TAP_H @@ -232,20 +196,17 @@ /* Define to 1 if you have the header file. */ #undef HAVE_OPENSSL_SHA_H -/* Define to 1 if you have the `pselect' function. */ -#undef HAVE_PSELECT - /* Define to 1 if you have the `putenv' function. */ #undef HAVE_PUTENV -/* Define to 1 if you have the `RAND_bytes' function. */ -#undef HAVE_RAND_BYTES +/* Define to 1 if you have the `random' function. */ +#undef HAVE_RANDOM -/* Define to 1 if you have the header file. */ -#undef HAVE_RESOLV_H +/* Define to 1 if you have the `RAND_pseudo_bytes' function. */ +#undef HAVE_RAND_PSEUDO_BYTES -/* Define to 1 if you have the `RSA_set0_key' function. */ -#undef HAVE_RSA_SET0_KEY +/* Define to 1 if you have the `select' function. */ +#undef HAVE_SELECT /* Define to 1 if the system has the type `socklen_t'. */ #undef HAVE_SOCKLEN_T @@ -253,12 +214,21 @@ /* Solaris/SunOS */ #undef HAVE_SOLARIS +/* Define to 1 if you have the header file. */ +#undef HAVE_STDBOOL_H + /* Define to 1 if you have the header file. */ #undef HAVE_STDINT_H /* Define to 1 if you have the header file. */ #undef HAVE_STDLIB_H +/* Define to 1 if you have the `strdup' function. */ +#undef HAVE_STRDUP + +/* Define to 1 if you have the `strerror' function. */ +#undef HAVE_STRERROR + /* Define to 1 if you have the header file. */ #undef HAVE_STRINGS_H @@ -268,6 +238,9 @@ /* Define to 1 if you have the `strsignal' function. */ #undef HAVE_STRSIGNAL +/* Define to 1 if you have the `strtol' function. */ +#undef HAVE_STRTOL + /* Define to 1 if the system has the type `struct addrinfo'. */ #undef HAVE_STRUCT_ADDRINFO @@ -343,9 +316,18 @@ /* Define to 1 if you have the header file. */ #undef HAVE_SYS_UIO_H +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_UN_H + /* Define to 1 if you have the header file. */ #undef HAVE_SYS_WAIT_H +/* Define to 1 if you have the `time' function. */ +#undef HAVE_TIME + +/* Define to 1 if you have the header file. */ +#undef HAVE_TIME_H + /* Define to 1 if you have the header file. */ #undef HAVE_UNISTD_H @@ -358,6 +340,9 @@ /* Define to 1 if you have the `vsyslog' function. */ #undef HAVE_VSYSLOG +/* Define to 1 if you have the `writev' function. */ +#undef HAVE_WRITEV + /* have zlib compression support */ #undef HAVE_ZLIB @@ -394,6 +379,12 @@ /* Define to 1 if you have the ANSI C header files. */ #undef STDC_HEADERS +/* Define to 1 if you can safely include both and . */ +#undef TIME_WITH_SYS_TIME + +/* Define to 1 if your declares `struct tm'. */ +#undef TM_IN_SYS_TIME + /* Enable extensions on AIX 3, Interix. */ #ifndef _ALL_SOURCE # undef _ALL_SOURCE @@ -438,5 +429,15 @@ /* Defined if the __malloc__ attribute is not supported. */ #undef __malloc__ +/* Define to empty if `const' does not conform to ANSI C. */ +#undef const + /* Define to `int' if does not define. */ #undef pid_t + +/* Define to `unsigned int' if does not define. */ +#undef size_t + +/* Define to empty if the keyword `volatile' does not work. Warning: valid + code using `volatile' can become incorrect without. Disable with care. */ +#undef volatile diff --git a/config.sub b/config.sub index 1d8e98b..30fdca8 100755 --- a/config.sub +++ b/config.sub @@ -1,31 +1,38 @@ #! /bin/sh # Configuration validation subroutine script. -# Copyright 1992-2018 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, +# 2011 Free Software Foundation, Inc. -timestamp='2018-02-22' +timestamp='2011-03-23' -# 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 -# the Free Software Foundation; either version 3 of the License, or +# This file is (in principle) common to ALL GNU software. +# The presence of a machine in this file suggests that SOME GNU software +# can handle that machine. It does not imply ALL GNU software can. +# +# 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 +# the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with this program; if not, see . +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA +# 02110-1301, USA. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that -# program. This Exception is an additional permission under section 7 -# of the GNU General Public License, version 3 ("GPLv3"). +# the same distribution terms that you use for the rest of that program. -# Please send patches to . +# Please send patches to . Submit a context +# 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. @@ -33,7 +40,7 @@ timestamp='2018-02-22' # Otherwise, we print the canonical config type on stdout and succeed. # You can get the latest version of this script from: -# https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub +# 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 @@ -53,11 +60,12 @@ timestamp='2018-02-22' me=`echo "$0" | sed -e 's,.*/,,'` usage="\ -Usage: $0 [OPTION] CPU-MFR-OPSYS or ALIAS +Usage: $0 [OPTION] CPU-MFR-OPSYS + $0 [OPTION] ALIAS Canonicalize a configuration name. -Options: +Operation modes: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit @@ -67,7 +75,9 @@ Report bugs and patches to ." version="\ GNU config.sub ($timestamp) -Copyright 1992-2018 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, 2011 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." @@ -94,7 +104,7 @@ while test $# -gt 0 ; do *local*) # First pass through any local machine types. - echo "$1" + echo $1 exit ;; * ) @@ -112,24 +122,20 @@ esac # Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). # Here we must recognize all the valid KERNEL-OS combinations. -maybe_os=`echo "$1" | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` +maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` case $maybe_os in nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ - linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ - knetbsd*-gnu* | netbsd*-gnu* | netbsd*-eabi* | \ - kopensolaris*-gnu* | cloudabi*-eabi* | \ + linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ + knetbsd*-gnu* | netbsd*-gnu* | \ + kopensolaris*-gnu* | \ storm-chaos* | os2-emx* | rtmk-nova*) os=-$maybe_os - basic_machine=`echo "$1" | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` - ;; - android-linux) - os=-linux-android - basic_machine=`echo "$1" | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` ;; *) - basic_machine=`echo "$1" | sed 's/-[^-]*$//'` - if [ "$basic_machine" != "$1" ] - then os=`echo "$1" | sed 's/.*-/-/'` + basic_machine=`echo $1 | sed 's/-[^-]*$//'` + if [ $basic_machine != $1 ] + then os=`echo $1 | sed 's/.*-/-/'` else os=; fi ;; esac @@ -148,7 +154,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 | -microblaze*) + -apple | -axis | -knuth | -cray | -microblaze) os= basic_machine=$1 ;; @@ -178,56 +184,53 @@ case $os in ;; -sco6) os=-sco5v6 - basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco5) os=-sco3.2v5 - basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco4) os=-sco3.2v4 - basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2.[4-9]*) os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` - basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2v[4-9]*) # Don't forget version if it is 3.2v4 or newer. - basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco5v6*) # Don't forget version if it is 3.2v4 or newer. - basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco*) os=-sco3.2v2 - basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -udk*) - basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -isc) os=-isc2.2 - basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -clix*) basic_machine=clipper-intergraph ;; -isc*) - basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` - ;; - -lynx*178) - os=-lynxos178 - ;; - -lynx*5) - os=-lynxos5 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -lynx*) os=-lynxos ;; -ptx*) - basic_machine=`echo "$1" | sed -e 's/86-.*/86-sequent/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` + ;; + -windowsnt*) + os=`echo $os | sed -e 's/windowsnt/winnt/'` ;; -psos*) os=-psos @@ -244,29 +247,20 @@ case $basic_machine in # Some are omitted here because they have special meanings below. 1750a | 580 \ | a29k \ - | aarch64 | aarch64_be \ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ | am33_2.0 \ - | arc | arceb \ - | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \ - | avr | avr32 \ - | ba \ - | be32 | be64 \ + | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \ | bfin \ - | c4x | c8051 | clipper \ + | c4x | clipper \ | d10v | d30v | dlx | dsp16xx \ - | e2k | epiphany \ - | fido | fr30 | frv | ft32 \ + | fido | fr30 | frv \ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ - | hexagon \ - | i370 | i860 | i960 | ia16 | ia64 \ + | i370 | i860 | i960 | ia64 \ | ip2k | iq2000 \ - | k1om \ - | le32 | le64 \ | lm32 \ | m32c | m32r | m32rle | m68000 | m68k | m88k \ - | maxq | mb | microblaze | microblazeel | mcore | mep | metag \ + | maxq | mb | microblaze | mcore | mep | metag \ | mips | mipsbe | mipseb | mipsel | mipsle \ | mips16 \ | mips64 | mips64el \ @@ -280,39 +274,34 @@ case $basic_machine in | mips64vr5900 | mips64vr5900el \ | mipsisa32 | mipsisa32el \ | mipsisa32r2 | mipsisa32r2el \ - | mipsisa32r6 | mipsisa32r6el \ | mipsisa64 | mipsisa64el \ | mipsisa64r2 | mipsisa64r2el \ - | mipsisa64r6 | mipsisa64r6el \ | mipsisa64sb1 | mipsisa64sb1el \ | mipsisa64sr71k | mipsisa64sr71kel \ - | mipsr5900 | mipsr5900el \ | mipstx39 | mipstx39el \ | mn10200 | mn10300 \ | moxie \ | mt \ | msp430 \ | nds32 | nds32le | nds32be \ - | nios | nios2 | nios2eb | nios2el \ + | nios | nios2 \ | ns16k | ns32k \ - | open8 | or1k | or1knd | or32 \ - | pdp10 | pj | pjl \ + | open8 \ + | or32 \ + | pdp10 | pdp11 | pj | pjl \ | powerpc | powerpc64 | powerpc64le | powerpcle \ - | pru \ | pyramid \ - | riscv32 | riscv64 \ - | rl78 | rx \ + | rx \ | score \ - | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[234]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ + | 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 \ | spu \ | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ | ubicom32 \ - | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ - | visium \ - | wasm32 \ + | v850 | v850e \ + | we32k \ | x86 | xc16x | xstormy16 | xtensa \ | z8k | z80) basic_machine=$basic_machine-unknown @@ -326,14 +315,12 @@ case $basic_machine in c6x) basic_machine=tic6x-unknown ;; - leon|leon[3-9]) - basic_machine=sparc-$basic_machine - ;; - m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip) + m6811 | m68hc11 | m6812 | m68hc12 | picochip) + # Motorola 68HC11/12. basic_machine=$basic_machine-unknown os=-none ;; - m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65) + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) ;; ms1) basic_machine=mt-unknown @@ -342,10 +329,7 @@ case $basic_machine in strongarm | thumb | xscale) basic_machine=arm-unknown ;; - xgate) - basic_machine=$basic_machine-unknown - os=-none - ;; + xscaleeb) basic_machine=armeb-unknown ;; @@ -362,38 +346,31 @@ case $basic_machine in ;; # Object if more than one company name word. *-*-*) - echo Invalid configuration \`"$1"\': machine \`"$basic_machine"\' not recognized 1>&2 + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; # Recognize the basic CPU types with company name. 580-* \ | a29k-* \ - | aarch64-* | aarch64_be-* \ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ - | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \ + | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ | avr-* | avr32-* \ - | ba-* \ - | be32-* | be64-* \ | bfin-* | bs2000-* \ | c[123]* | c30-* | [cjt]90-* | c4x-* \ - | c8051-* | clipper-* | craynv-* | cydra-* \ + | clipper-* | craynv-* | cydra-* \ | d10v-* | d30v-* | dlx-* \ - | e2k-* | elxsi-* \ + | elxsi-* \ | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ | h8300-* | h8500-* \ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ - | hexagon-* \ - | i*86-* | i860-* | i960-* | ia16-* | ia64-* \ + | i*86-* | i860-* | i960-* | ia64-* \ | ip2k-* | iq2000-* \ - | k1om-* \ - | le32-* | le64-* \ | lm32-* \ | m32c-* | m32r-* | m32rle-* \ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ - | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \ - | microblaze-* | microblazeel-* \ + | m88110-* | m88k-* | maxq-* | mcore-* | metag-* | microblaze-* \ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ | mips16-* \ | mips64-* | mips64el-* \ @@ -407,43 +384,34 @@ case $basic_machine in | mips64vr5900-* | mips64vr5900el-* \ | mipsisa32-* | mipsisa32el-* \ | mipsisa32r2-* | mipsisa32r2el-* \ - | mipsisa32r6-* | mipsisa32r6el-* \ | mipsisa64-* | mipsisa64el-* \ | mipsisa64r2-* | mipsisa64r2el-* \ - | mipsisa64r6-* | mipsisa64r6el-* \ | mipsisa64sb1-* | mipsisa64sb1el-* \ | mipsisa64sr71k-* | mipsisa64sr71kel-* \ - | mipsr5900-* | mipsr5900el-* \ | mipstx39-* | mipstx39el-* \ | mmix-* \ | mt-* \ | msp430-* \ | nds32-* | nds32le-* | nds32be-* \ - | nios-* | nios2-* | nios2eb-* | nios2el-* \ + | nios-* | nios2-* \ | none-* | np1-* | ns16k-* | ns32k-* \ | open8-* \ - | or1k*-* \ | orion-* \ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ - | pru-* \ | pyramid-* \ - | riscv32-* | riscv64-* \ - | rl78-* | romp-* | rs6000-* | rx-* \ + | 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-* | sv1-* | sx*-* \ + | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \ | tahoe-* \ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ - | tile*-* \ + | tile-* | tilegx-* \ | tron-* \ | ubicom32-* \ - | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ - | vax-* \ - | visium-* \ - | wasm32-* \ + | v850-* | v850e-* | vax-* \ | we32k-* \ | x86-* | x86_64-* | xc16x-* | xps100-* \ | xstormy16-* | xtensa*-* \ @@ -457,7 +425,7 @@ case $basic_machine in # Recognize the various machine names and aliases which stand # for a CPU type and a company and sometimes even an OS. 386bsd) - basic_machine=i386-pc + basic_machine=i386-unknown os=-bsd ;; 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) @@ -491,7 +459,7 @@ case $basic_machine in basic_machine=x86_64-pc ;; amd64-*) - basic_machine=x86_64-`echo "$basic_machine" | sed 's/^[^-]*-//'` + basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; amdahl) basic_machine=580-amdahl @@ -520,9 +488,6 @@ case $basic_machine in basic_machine=i386-pc os=-aros ;; - asmjs) - basic_machine=asmjs-unknown - ;; aux) basic_machine=m68k-apple os=-aux @@ -536,7 +501,7 @@ case $basic_machine in os=-linux ;; blackfin-*) - basic_machine=bfin-`echo "$basic_machine" | sed 's/^[^-]*-//'` + basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; bluegene*) @@ -544,13 +509,13 @@ case $basic_machine in os=-cnk ;; c54x-*) - basic_machine=tic54x-`echo "$basic_machine" | sed 's/^[^-]*-//'` + basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'` ;; c55x-*) - basic_machine=tic55x-`echo "$basic_machine" | sed 's/^[^-]*-//'` + basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'` ;; c6x-*) - basic_machine=tic6x-`echo "$basic_machine" | sed 's/^[^-]*-//'` + basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'` ;; c90) basic_machine=c90-cray @@ -639,18 +604,10 @@ case $basic_machine in basic_machine=rs6000-bull os=-bosx ;; - dpx2*) + dpx2* | dpx2*-bull) basic_machine=m68k-bull os=-sysv3 ;; - e500v[12]) - basic_machine=powerpc-unknown - os=$os"spe" - ;; - e500v[12]-*) - basic_machine=powerpc-`echo "$basic_machine" | sed 's/^[^-]*-//'` - os=$os"spe" - ;; ebmon29k) basic_machine=a29k-amd os=-ebmon @@ -740,6 +697,9 @@ case $basic_machine in hp9k8[0-9][0-9] | hp8[0-9][0-9]) basic_machine=hppa1.0-hp ;; + hppa-next) + os=-nextstep3 + ;; hppaosf) basic_machine=hppa1.1-hp os=-osf @@ -751,27 +711,28 @@ case $basic_machine in i370-ibm* | ibm*) basic_machine=i370-ibm ;; +# I'm not sure what "Sysv32" means. Should this be sysv3.2? i*86v32) - basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'` + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv32 ;; i*86v4*) - basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'` + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv4 ;; i*86v) - basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'` + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv ;; i*86sol2) - basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'` + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-solaris2 ;; i386mach) basic_machine=i386-mach os=-mach ;; - vsta) + i386-vsta | vsta) basic_machine=i386-unknown os=-vsta ;; @@ -789,17 +750,17 @@ case $basic_machine in basic_machine=m68k-isi os=-sysv ;; - leon-*|leon[3-9]-*) - basic_machine=sparc-`echo "$basic_machine" | sed 's/-.*//'` - ;; m68knommu) basic_machine=m68k-unknown os=-linux ;; m68knommu-*) - basic_machine=m68k-`echo "$basic_machine" | sed 's/^[^-]*-//'` + basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; + m88k-omron*) + basic_machine=m88k-omron + ;; magnum | m3230) basic_machine=mips-mips os=-sysv @@ -808,15 +769,11 @@ case $basic_machine in basic_machine=ns32k-utek os=-sysv ;; - microblaze*) + microblaze) basic_machine=microblaze-xilinx ;; - mingw64) - basic_machine=x86_64-pc - os=-mingw64 - ;; mingw32) - basic_machine=i686-pc + basic_machine=i386-pc os=-mingw32 ;; mingw32ce) @@ -831,10 +788,10 @@ case $basic_machine in os=-mint ;; mips3*-*) - basic_machine=`echo "$basic_machine" | sed -e 's/mips3/mips64/'` + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` ;; mips3*) - basic_machine=`echo "$basic_machine" | sed -e 's/mips3/mips64/'`-unknown + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown ;; monitor) basic_machine=m68k-rom68k @@ -844,29 +801,17 @@ case $basic_machine in basic_machine=powerpc-unknown os=-morphos ;; - moxiebox) - basic_machine=moxie-unknown - os=-moxiebox - ;; msdos) basic_machine=i386-pc os=-msdos ;; ms1-*) - basic_machine=`echo "$basic_machine" | sed -e 's/ms1-/mt-/'` - ;; - msys) - basic_machine=i686-pc - os=-msys + basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` ;; mvs) basic_machine=i370-ibm os=-mvs ;; - nacl) - basic_machine=le32-unknown - os=-nacl - ;; ncr3000) basic_machine=i486-ncr os=-sysv4 @@ -895,7 +840,7 @@ case $basic_machine in basic_machine=v70-nec os=-sysv ;; - next | m*-next) + next | m*-next ) basic_machine=m68k-next case $os in -nextstep* ) @@ -940,12 +885,6 @@ case $basic_machine in nsr-tandem) basic_machine=nsr-tandem ;; - nsv-tandem) - basic_machine=nsv-tandem - ;; - nsx-tandem) - basic_machine=nsx-tandem - ;; op50n-* | op60c-*) basic_machine=hppa1.1-oki os=-proelf @@ -978,7 +917,7 @@ case $basic_machine in os=-linux ;; parisc-*) - basic_machine=hppa-`echo "$basic_machine" | sed 's/^[^-]*-//'` + basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; pbd) @@ -994,7 +933,7 @@ case $basic_machine in basic_machine=i386-pc ;; pc98-*) - basic_machine=i386-`echo "$basic_machine" | sed 's/^[^-]*-//'` + basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentium | p5 | k5 | k6 | nexgen | viac3) basic_machine=i586-pc @@ -1009,16 +948,16 @@ case $basic_machine in basic_machine=i786-pc ;; pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) - basic_machine=i586-`echo "$basic_machine" | sed 's/^[^-]*-//'` + basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumpro-* | p6-* | 6x86-* | athlon-*) - basic_machine=i686-`echo "$basic_machine" | sed 's/^[^-]*-//'` + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) - basic_machine=i686-`echo "$basic_machine" | sed 's/^[^-]*-//'` + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentium4-*) - basic_machine=i786-`echo "$basic_machine" | sed 's/^[^-]*-//'` + basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pn) basic_machine=pn-gould @@ -1028,23 +967,23 @@ case $basic_machine in ppc | ppcbe) basic_machine=powerpc-unknown ;; ppc-* | ppcbe-*) - basic_machine=powerpc-`echo "$basic_machine" | sed 's/^[^-]*-//'` + basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` ;; - ppcle | powerpclittle) + ppcle | powerpclittle | ppc-le | powerpc-little) basic_machine=powerpcle-unknown ;; ppcle-* | powerpclittle-*) - basic_machine=powerpcle-`echo "$basic_machine" | sed 's/^[^-]*-//'` + basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64) basic_machine=powerpc64-unknown ;; - ppc64-*) basic_machine=powerpc64-`echo "$basic_machine" | sed 's/^[^-]*-//'` + ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; - ppc64le | powerpc64little) + ppc64le | powerpc64little | ppc64-le | powerpc64-little) basic_machine=powerpc64le-unknown ;; ppc64le-* | powerpc64little-*) - basic_machine=powerpc64le-`echo "$basic_machine" | sed 's/^[^-]*-//'` + basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ps2) basic_machine=i386-ibm @@ -1053,11 +992,7 @@ case $basic_machine in basic_machine=i586-unknown os=-pw32 ;; - rdos | rdos64) - basic_machine=x86_64-pc - os=-rdos - ;; - rdos32) + rdos) basic_machine=i386-pc os=-rdos ;; @@ -1098,10 +1033,17 @@ case $basic_machine in sequent) basic_machine=i386-sequent ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; sh5el) basic_machine=sh5le-unknown ;; - simso-wrs) + sh64) + basic_machine=sh64-unknown + ;; + sparclite-wrs | simso-wrs) basic_machine=sparclite-wrs os=-vxworks ;; @@ -1120,7 +1062,7 @@ case $basic_machine in os=-sysv4 ;; strongarm-* | thumb-*) - basic_machine=arm-`echo "$basic_machine" | sed 's/^[^-]*-//'` + basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'` ;; sun2) basic_machine=m68000-sun @@ -1178,8 +1120,13 @@ case $basic_machine in basic_machine=t90-cray os=-unicos ;; + # This must be matched before tile*. + tilegx*) + basic_machine=tilegx-unknown + os=-linux-gnu + ;; tile*) - basic_machine=$basic_machine-unknown + basic_machine=tile-unknown os=-linux-gnu ;; tx39) @@ -1242,9 +1189,6 @@ case $basic_machine in basic_machine=hppa1.1-winbond os=-proelf ;; - x64) - basic_machine=x86_64-pc - ;; xbox) basic_machine=i686-pc os=-mingw32 @@ -1253,12 +1197,20 @@ case $basic_machine in basic_machine=xps100-honeywell ;; xscale-* | xscalee[bl]-*) - basic_machine=`echo "$basic_machine" | sed 's/^xscale/arm/'` + basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'` ;; ymp) basic_machine=ymp-cray os=-unicos ;; + z8k-*-coff) + basic_machine=z8k-unknown + os=-sim + ;; + z80-*-coff) + basic_machine=z80-unknown + os=-sim + ;; none) basic_machine=none-none os=-none @@ -1287,6 +1239,10 @@ case $basic_machine in vax) basic_machine=vax-dec ;; + pdp10) + # there are many clones, so DEC is not a safe bet + basic_machine=pdp10-unknown + ;; pdp11) basic_machine=pdp11-dec ;; @@ -1296,6 +1252,9 @@ case $basic_machine in sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) basic_machine=sh-unknown ;; + sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) + basic_machine=sparc-sun + ;; cydra) basic_machine=cydra-cydrome ;; @@ -1315,7 +1274,7 @@ case $basic_machine in # Make sure to match an already-canonicalized machine name. ;; *) - echo Invalid configuration \`"$1"\': machine \`"$basic_machine"\' not recognized 1>&2 + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; esac @@ -1323,10 +1282,10 @@ esac # Here we canonicalize certain aliases for manufacturers. case $basic_machine in *-digital*) - basic_machine=`echo "$basic_machine" | sed 's/digital.*/dec/'` + basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` ;; *-commodore*) - basic_machine=`echo "$basic_machine" | sed 's/commodore.*/cbm/'` + basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` ;; *) ;; @@ -1337,8 +1296,8 @@ esac if [ x"$os" != x"" ] then case $os in - # First match some system type aliases that might get confused - # with valid system types. + # 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 @@ -1349,48 +1308,45 @@ case $os in -solaris) os=-solaris2 ;; + -svr4*) + os=-sysv4 + ;; -unixware*) os=-sysv4.2uw ;; -gnu/linux*) os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` ;; - # es1800 is here to avoid being matched by es* (a different OS) - -es1800*) - os=-ose - ;; - # Now accept the basic system types. + # First accept the basic system types. # The portable systems comes first. - # Each alternative MUST end in a * to match a version number. + # Each alternative MUST END IN A *, to match a version number. # -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* | -auroraux* | -solaris* \ - | -sym* | -kopensolaris* | -plan9* \ + | -sym* | -kopensolaris* \ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ - | -aos* | -aros* | -cloudabi* | -sortix* \ + | -aos* | -aros* \ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ - | -hiux* | -knetbsd* | -mirbsd* | -netbsd* \ - | -bitrig* | -openbsd* | -solidbsd* | -libertybsd* \ + | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ + | -openbsd* | -solidbsd* \ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ - | -chorusos* | -chorusrdb* | -cegcc* | -glidix* \ - | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ - | -midipix* | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \ - | -linux-newlib* | -linux-musl* | -linux-uclibc* \ - | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \ - | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* \ + | -chorusos* | -chorusrdb* | -cegcc* \ + | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -linux-gnu* | -linux-android* \ + | -linux-newlib* | -linux-uclibc* \ + | -uxpv* | -beos* | -mpeix* | -udk* \ + | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ - | -morphos* | -superux* | -rtmk* | -windiss* \ + | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ - | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* \ - | -onefs* | -tirtos* | -phoenix* | -fuchsia* | -redox* | -bme* \ - | -midnightbsd*) + | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*) # Remember, each alternative MUST END IN *, to match a version number. ;; -qnx*) @@ -1407,12 +1363,12 @@ case $os in -nto*) os=`echo $os | sed -e 's|nto|nto-qnx|'` ;; - -sim | -xray | -os68k* | -v88r* \ - | -windows* | -osx | -abug | -netware* | -os9* \ + -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) ;; -mac*) - os=`echo "$os" | sed -e 's|mac|macos|'` + os=`echo $os | sed -e 's|mac|macos|'` ;; -linux-dietlibc) os=-linux-dietlibc @@ -1421,10 +1377,10 @@ case $os in os=`echo $os | sed -e 's|linux|linux-gnu|'` ;; -sunos5*) - os=`echo "$os" | sed -e 's|sunos5|solaris2|'` + os=`echo $os | sed -e 's|sunos5|solaris2|'` ;; -sunos6*) - os=`echo "$os" | sed -e 's|sunos6|solaris3|'` + os=`echo $os | sed -e 's|sunos6|solaris3|'` ;; -opened*) os=-openedition @@ -1435,6 +1391,12 @@ case $os in -wince*) os=-wince ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; -utek*) os=-bsd ;; @@ -1459,7 +1421,7 @@ case $os in -nova*) os=-rtmk-nova ;; - -ns2) + -ns2 ) os=-nextstep2 ;; -nsk*) @@ -1481,7 +1443,7 @@ case $os in -oss*) os=-sysv3 ;; - -svr4*) + -svr4) os=-sysv4 ;; -svr3) @@ -1496,38 +1458,35 @@ case $os in -ose*) os=-ose ;; + -es1800*) + os=-ose + ;; + -xenix) + os=-xenix + ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) os=-mint ;; + -aros*) + os=-aros + ;; + -kaos*) + os=-kaos + ;; -zvmoe) os=-zvmoe ;; -dicos*) os=-dicos ;; - -pikeos*) - # Until real need of OS specific support for - # particular features comes up, bare metal - # configurations are quite functional. - case $basic_machine in - arm*) - os=-eabi - ;; - *) - os=-elf - ;; - esac - ;; -nacl*) ;; - -ios) - ;; -none) ;; *) # Get rid of the `-' at the beginning of $os. os=`echo $os | sed 's/[^-]*-//'` - echo Invalid configuration \`"$1"\': system \`"$os"\' not recognized 1>&2 + echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 exit 1 ;; esac @@ -1562,12 +1521,6 @@ case $basic_machine in c4x-* | tic4x-*) os=-coff ;; - c8051-*) - os=-elf - ;; - hexagon-*) - os=-elf - ;; tic54x-*) os=-coff ;; @@ -1595,6 +1548,9 @@ case $basic_machine in ;; m68000-sun) os=-sunos3 + # This also exists in the configure program, but was not the + # default. + # os=-sunos4 ;; m68*-cisco) os=-aout @@ -1617,12 +1573,12 @@ case $basic_machine in sparc-* | *-sun) os=-sunos4.1.1 ;; - pru-*) - os=-elf - ;; *-be) os=-beos ;; + *-haiku) + os=-haiku + ;; *-ibm) os=-aix ;; @@ -1662,7 +1618,7 @@ case $basic_machine in m88k-omron*) os=-luna ;; - *-next) + *-next ) os=-nextstep ;; *-sequent) @@ -1677,6 +1633,9 @@ case $basic_machine in i370-*) os=-mvs ;; + *-next) + os=-nextstep3 + ;; *-gould) os=-sysv ;; @@ -1786,15 +1745,15 @@ case $basic_machine in vendor=stratus ;; esac - basic_machine=`echo "$basic_machine" | sed "s/unknown/$vendor/"` + basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` ;; esac -echo "$basic_machine$os" +echo $basic_machine$os exit # Local variables: -# eval: (add-hook 'write-file-functions 'time-stamp) +# eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" diff --git a/configure b/configure index 26dd965..a87b0e9 100755 --- a/configure +++ b/configure @@ -1,9 +1,11 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for tinc 1.0.35. +# Generated by GNU Autoconf 2.68. # # -# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, +# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software +# Foundation, Inc. # # # This configure script is free software; the Free Software Foundation @@ -132,31 +134,6 @@ export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH -# Use a proper internal environment variable to ensure we don't fall - # into an infinite loop, continuously re-executing ourselves. - if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then - _as_can_reexec=no; export _as_can_reexec; - # We cannot yet assume a decent shell, so we have to provide a -# neutralization value for shells without unset; and this also -# works around shells that cannot unset nonexistent variables. -# Preserve -v and -x to the replacement shell. -BASH_ENV=/dev/null -ENV=/dev/null -(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV -case $- in # (((( - *v*x* | *x*v* ) as_opts=-vx ;; - *v* ) as_opts=-v ;; - *x* ) as_opts=-x ;; - * ) as_opts= ;; -esac -exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} -# Admittedly, this is quite paranoid, since all the known shells bail -# out after a failed `exec'. -$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 -as_fn_exit 255 - fi - # We don't want this to propagate to other subprocesses. - { _as_can_reexec=; unset _as_can_reexec;} if test "x$CONFIG_SHELL" = x; then as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : emulate sh @@ -190,8 +167,7 @@ if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : else exitcode=1; echo positional parameters were not saved. fi -test x\$exitcode = x0 || exit 1 -test -x / || exit 1" +test x\$exitcode = x0 || exit 1" as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && @@ -236,25 +212,21 @@ IFS=$as_save_IFS if test "x$CONFIG_SHELL" != x; then : - export CONFIG_SHELL - # We cannot yet assume a decent shell, so we have to provide a -# neutralization value for shells without unset; and this also -# works around shells that cannot unset nonexistent variables. -# Preserve -v and -x to the replacement shell. -BASH_ENV=/dev/null -ENV=/dev/null -(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV -case $- in # (((( - *v*x* | *x*v* ) as_opts=-vx ;; - *v* ) as_opts=-v ;; - *x* ) as_opts=-x ;; - * ) as_opts= ;; -esac -exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} -# Admittedly, this is quite paranoid, since all the known shells bail -# out after a failed `exec'. -$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 -exit 255 + # We cannot yet assume a decent shell, so we have to provide a + # neutralization value for shells without unset; and this also + # works around shells that cannot unset nonexistent variables. + # Preserve -v and -x to the replacement shell. + BASH_ENV=/dev/null + ENV=/dev/null + (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV + export CONFIG_SHELL + case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; + esac + exec "$CONFIG_SHELL" $as_opts "$as_myself" ${1+"$@"} fi if test x$as_have_required = xno; then : @@ -356,14 +328,6 @@ $as_echo X"$as_dir" | } # as_fn_mkdir_p - -# as_fn_executable_p FILE -# ----------------------- -# Test if FILE is an executable regular file. -as_fn_executable_p () -{ - test -f "$1" && test -x "$1" -} # as_fn_executable_p # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take @@ -485,10 +449,6 @@ as_cr_alnum=$as_cr_Letters$as_cr_digits chmod +x "$as_me.lineno" || { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } - # If we had to re-execute with $CONFIG_SHELL, we're ensured to have - # already done that, so ensure we don't try to do so again and fall - # in an infinite loop. This has already happened in practice. - _as_can_reexec=no; export _as_can_reexec # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). @@ -523,16 +483,16 @@ if (echo >conf$$.file) 2>/dev/null; then # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. - # In both cases, we have to default to `cp -pR'. + # In both cases, we have to default to `cp -p'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || - as_ln_s='cp -pR' + as_ln_s='cp -p' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else - as_ln_s='cp -pR' + as_ln_s='cp -p' fi else - as_ln_s='cp -pR' + as_ln_s='cp -p' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null @@ -544,8 +504,28 @@ else as_mkdir_p=false fi -as_test_x='test -x' -as_executable_p=as_fn_executable_p +if test -x / >/dev/null 2>&1; then + as_test_x='test -x' +else + if ls -dL / >/dev/null 2>&1; then + as_ls_L_option=L + else + as_ls_L_option= + fi + as_test_x=' + eval sh -c '\'' + if test -d "$1"; then + test -d "$1/."; + else + case $1 in #( + -*)set "./$1";; + esac; + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( + ???[sx]*):;;*)false;;esac;fi + '\'' sh + ' +fi +as_executable_p=$as_test_x # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" @@ -575,12 +555,12 @@ MFLAGS= MAKEFLAGS= # Identity of this package. -PACKAGE_NAME='tinc' -PACKAGE_TARNAME='tinc' -PACKAGE_VERSION='1.0.35' -PACKAGE_STRING='tinc 1.0.35' -PACKAGE_BUGREPORT='' -PACKAGE_URL='' +PACKAGE_NAME= +PACKAGE_TARNAME= +PACKAGE_VERSION= +PACKAGE_STRING= +PACKAGE_BUGREPORT= +PACKAGE_URL= ac_unique_file="src/tincd.c" # Factoring default headers for most tests. @@ -623,27 +603,13 @@ ac_subst_vars='am__EXEEXT_FALSE am__EXEEXT_TRUE LTLIBOBJS LIBOBJS -GETOPT_FALSE -GETOPT_TRUE -WITH_SYSTEMD_FALSE -WITH_SYSTEMD_TRUE +INCLUDES +LIBGCRYPT_LIBS +LIBGCRYPT_CFLAGS +LIBGCRYPT_CONFIG +CURSES_LIBS TUNEMU_FALSE TUNEMU_TRUE -VDE_FALSE -VDE_TRUE -UML_FALSE -UML_TRUE -CYGWIN_FALSE -CYGWIN_TRUE -MINGW_FALSE -MINGW_TRUE -SOLARIS_FALSE -SOLARIS_TRUE -BSD_FALSE -BSD_TRUE -LINUX_FALSE -LINUX_TRUE -systemd_path host_os host_vendor host_cpu @@ -652,29 +618,20 @@ build_os build_vendor build_cpu build -EGREP -GREP -CPP +RANLIB +LN_S +MAINT +MAINTAINER_MODE_FALSE +MAINTAINER_MODE_TRUE am__fastdepCC_FALSE am__fastdepCC_TRUE CCDEPMODE -am__nodep AMDEPBACKSLASH AMDEP_FALSE AMDEP_TRUE +am__quote am__include DEPDIR -OBJEXT -EXEEXT -ac_ct_CC -CPPFLAGS -LDFLAGS -CFLAGS -CC -AM_BACKSLASH -AM_DEFAULT_VERBOSITY -AM_DEFAULT_V -AM_V am__untar am__tar AMTAR @@ -698,6 +655,16 @@ am__isrc INSTALL_DATA INSTALL_SCRIPT INSTALL_PROGRAM +EGREP +GREP +CPP +OBJEXT +EXEEXT +ac_ct_CC +CPPFLAGS +LDFLAGS +CFLAGS +CC target_alias host_alias build_alias @@ -717,7 +684,6 @@ infodir docdir oldincludedir includedir -runstatedir localstatedir sharedstatedir sysconfdir @@ -736,19 +702,22 @@ PACKAGE_VERSION PACKAGE_TARNAME PACKAGE_NAME PATH_SEPARATOR -SHELL -am__quote' +SHELL' ac_subst_files='' ac_user_opts=' enable_option_checking -enable_silent_rules enable_dependency_tracking -enable_uml -enable_vde +enable_maintainer_mode enable_tunemu with_windows2000 -with_systemd -enable_hardening +with_libgcrypt +enable_curses +with_curses +with_curses_include +with_curses_lib +with_libevent +with_libevent_include +with_libevent_lib enable_zlib with_zlib with_zlib_include @@ -757,6 +726,7 @@ enable_lzo with_lzo with_lzo_include with_lzo_lib +with_libgcrypt_prefix with_openssl with_openssl_include with_openssl_lib @@ -809,10 +779,9 @@ datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' -runstatedir='${localstatedir}/run' includedir='${prefix}/include' oldincludedir='/usr/include' -docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' +docdir='${datarootdir}/doc/${PACKAGE}' infodir='${datarootdir}/info' htmldir='${docdir}' dvidir='${docdir}' @@ -1062,15 +1031,6 @@ do | -silent | --silent | --silen | --sile | --sil) silent=yes ;; - -runstatedir | --runstatedir | --runstatedi | --runstated \ - | --runstate | --runstat | --runsta | --runst | --runs \ - | --run | --ru | --r) - ac_prev=runstatedir ;; - -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ - | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ - | --run=* | --ru=* | --r=*) - runstatedir=$ac_optarg ;; - -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ @@ -1208,7 +1168,7 @@ fi for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ - libdir localedir mandir runstatedir + libdir localedir mandir do eval ac_val=\$$ac_var # Remove trailing slashes. @@ -1236,6 +1196,8 @@ target=$target_alias if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe + $as_echo "$as_me: WARNING: if you wanted to set the --build type, don't use --host. + If a cross compiler is detected then cross compile mode will be used" >&2 elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi @@ -1321,7 +1283,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures tinc 1.0.35 to adapt to many kinds of systems. +\`configure' configures this package to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1361,7 +1323,6 @@ Fine tuning of the installation directories: --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] - --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] @@ -1370,7 +1331,7 @@ Fine tuning of the installation directories: --infodir=DIR info documentation [DATAROOTDIR/info] --localedir=DIR locale-dependent data [DATAROOTDIR/locale] --mandir=DIR man documentation [DATAROOTDIR/man] - --docdir=DIR documentation root [DATAROOTDIR/doc/tinc] + --docdir=DIR documentation root [DATAROOTDIR/doc/PACKAGE] --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] @@ -1391,25 +1352,19 @@ _ACEOF fi if test -n "$ac_init_help"; then - case $ac_init_help in - short | recursive ) echo "Configuration of tinc 1.0.35:";; - esac + cat <<\_ACEOF Optional Features: --disable-option-checking ignore unrecognized --enable/--with options --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] - --enable-silent-rules less verbose build output (undo: "make V=1") - --disable-silent-rules verbose build output (undo: "make V=0") - --enable-dependency-tracking - do not reject slow dependency extractors - --disable-dependency-tracking - speeds up one-time build - --enable-uml enable support for User Mode Linux - --enable-vde enable support for Virtual Distributed Ethernet + --disable-dependency-tracking speeds up one-time build + --enable-dependency-tracking do not reject slow dependency extractors + --enable-maintainer-mode enable make rules and dependencies not useful + (and sometimes confusing) to the casual installer --enable-tunemu enable support for the tunemu driver - --disable-hardening disable compiler and linker hardening flags + --disable-curses disable curses support --disable-zlib disable zlib compression support --disable-lzo disable lzo compression support --enable-jumbograms enable support for jumbograms (packets up to 9000 @@ -1420,18 +1375,28 @@ Optional Packages: --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --with-windows2000 compile with support for Windows 2000. This disables support for tunneling over existing IPv6 networks. - --with-systemd[=DIR] install systemd service files [to DIR if specified] + --with-libgcrypt enable use of libgcrypt instead of OpenSSL] + --with-curses=DIR curses base directory, or: + --with-curses-include=DIR + curses headers directory + --with-curses-lib=DIR curses library directory + --with-libevent=DIR libevent base directory, or: + --with-libevent-include=DIR + libevent headers directory + --with-libevent-lib=DIR libevent library directory --with-zlib=DIR zlib base directory, or: --with-zlib-include=DIR zlib headers directory --with-zlib-lib=DIR zlib library directory --with-lzo=DIR lzo base directory, or: --with-lzo-include=DIR lzo headers directory --with-lzo-lib=DIR lzo library directory - --with-openssl=DIR LibreSSL/OpenSSL base directory, or: + --with-libgcrypt-prefix=PFX + prefix where LIBGCRYPT is installed (optional) + --with-openssl=DIR OpenSSL base directory, or: --with-openssl-include=DIR - LibreSSL/OpenSSL headers directory (without trailing + OpenSSL headers directory (without trailing /openssl) - --with-openssl-lib=DIR LibreSSL/OpenSSL library directory + --with-openssl-lib=DIR OpenSSL library directory Some influential environment variables: CC C compiler command @@ -1509,10 +1474,10 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -tinc configure 1.0.35 -generated by GNU Autoconf 2.69 +configure +generated by GNU Autoconf 2.68 -Copyright (C) 2012 Free Software Foundation, Inc. +Copyright (C) 2010 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF @@ -1758,52 +1723,6 @@ $as_echo "$ac_res" >&6; } } # ac_fn_c_check_header_compile -# ac_fn_c_try_link LINENO -# ----------------------- -# Try to link conftest.$ac_ext, and return whether this succeeded. -ac_fn_c_try_link () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - rm -f conftest.$ac_objext conftest$ac_exeext - if { { 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>conftest.err - ac_status=$? - if test -s conftest.err; then - grep -v '^ *+' conftest.err >conftest.er1 - cat conftest.er1 >&5 - mv -f conftest.er1 conftest.err - fi - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && { - test "$cross_compiling" = yes || - test -x conftest$ac_exeext - }; then : - ac_retval=0 -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_retval=1 -fi - # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information - # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would - # interfere with the next link command; also delete a directory that is - # 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; ${as_lineno_stack:+:} unset as_lineno - as_fn_set_status $ac_retval - -} # ac_fn_c_try_link - # ac_fn_c_check_type LINENO TYPE VAR INCLUDES # ------------------------------------------- # Tests whether TYPE exists after having included INCLUDES, setting cache @@ -1858,6 +1777,52 @@ $as_echo "$ac_res" >&6; } } # ac_fn_c_check_type +# ac_fn_c_try_link LINENO +# ----------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_link () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext conftest$ac_exeext + if { { 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>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information + # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would + # interfere with the next link command; also delete a directory that is + # 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; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_link + # ac_fn_c_check_func LINENO FUNC VAR # ---------------------------------- # Tests whether FUNC exists, setting the cache variable VAR accordingly @@ -1974,8 +1939,8 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by tinc $as_me 1.0.35, which was -generated by GNU Autoconf 2.69. Invocation command line was +It was created by $as_me, which was +generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2323,723 +2288,6 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu -am__api_version='1.16' - -ac_aux_dir= -for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do - if test -f "$ac_dir/install-sh"; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/install-sh -c" - break - elif test -f "$ac_dir/install.sh"; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/install.sh -c" - break - elif test -f "$ac_dir/shtool"; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/shtool install -c" - break - fi -done -if test -z "$ac_aux_dir"; then - as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 -fi - -# These three variables are undocumented and unsupported, -# and are intended to be withdrawn in a future Autoconf release. -# They can cause serious problems if a builder's source tree is in a directory -# whose full name contains unusual characters. -ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. -ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. -ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. - - -# Find a good install program. We prefer a C program (faster), -# so one script is as good as another. But avoid the broken or -# incompatible versions: -# SysV /etc/install, /usr/sbin/install -# SunOS /usr/etc/install -# IRIX /sbin/install -# AIX /bin/install -# AmigaOS /C/install, which installs bootblocks on floppy discs -# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag -# AFS /usr/afsws/bin/install, which mishandles nonexistent args -# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" -# OS/2's system install, which has a completely different semantic -# ./install, which can be erroneously created by make from ./install.sh. -# Reject install programs that cannot install multiple files. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 -$as_echo_n "checking for a BSD-compatible install... " >&6; } -if test -z "$INSTALL"; then -if ${ac_cv_path_install+:} false; then : - $as_echo_n "(cached) " >&6 -else - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - # Account for people who put trailing slashes in PATH elements. -case $as_dir/ in #(( - ./ | .// | /[cC]/* | \ - /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ - ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ - /usr/ucb/* ) ;; - *) - # OSF1 and SCO ODT 3.0 have their own names for install. - # Don't use installbsd from OSF since it installs stuff as root - # by default. - for ac_prog in ginstall scoinst install; do - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then - if test $ac_prog = install && - grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then - # AIX install. It has an incompatible calling convention. - : - elif test $ac_prog = install && - grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then - # program-specific install script used by HP pwplus--don't use. - : - else - rm -rf conftest.one conftest.two conftest.dir - echo one > conftest.one - echo two > conftest.two - mkdir conftest.dir - if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && - test -s conftest.one && test -s conftest.two && - test -s conftest.dir/conftest.one && - test -s conftest.dir/conftest.two - then - ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" - break 3 - fi - fi - fi - done - done - ;; -esac - - done -IFS=$as_save_IFS - -rm -rf conftest.one conftest.two conftest.dir - -fi - if test "${ac_cv_path_install+set}" = set; then - INSTALL=$ac_cv_path_install - else - # As a last resort, use the slow shell script. Don't cache a - # value for INSTALL 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. - INSTALL=$ac_install_sh - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 -$as_echo "$INSTALL" >&6; } - -# Use test -z because SunOS4 sh mishandles braces in ${var-val}. -# It thinks the first close brace ends the variable substitution. -test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' - -test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' - -test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 -$as_echo_n "checking whether build environment is sane... " >&6; } -# Reject unsafe characters in $srcdir or the absolute working directory -# name. Accept space and tab only in the latter. -am_lf=' -' -case `pwd` in - *[\\\"\#\$\&\'\`$am_lf]*) - as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;; -esac -case $srcdir in - *[\\\"\#\$\&\'\`$am_lf\ \ ]*) - as_fn_error $? "unsafe srcdir value: '$srcdir'" "$LINENO" 5;; -esac - -# Do 'set' in a subshell so we don't clobber the current shell's -# arguments. Must try -L first in case configure is actually a -# symlink; some systems play weird games with the mod time of symlinks -# (eg FreeBSD returns the mod time of the symlink's containing -# directory). -if ( - am_has_slept=no - for am_try in 1 2; do - echo "timestamp, slept: $am_has_slept" > conftest.file - set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` - if test "$*" = "X"; then - # -L didn't work. - set X `ls -t "$srcdir/configure" conftest.file` - fi - if test "$*" != "X $srcdir/configure conftest.file" \ - && test "$*" != "X conftest.file $srcdir/configure"; then - - # If neither matched, then we have a broken ls. This can happen - # if, for instance, CONFIG_SHELL is bash and it inherits a - # broken ls alias from the environment. This has actually - # happened. Such a system could not be considered "sane". - as_fn_error $? "ls -t appears to fail. Make sure there is not a broken - alias in your environment" "$LINENO" 5 - fi - if test "$2" = conftest.file || test $am_try -eq 2; then - break - fi - # Just in case. - sleep 1 - am_has_slept=yes - done - test "$2" = conftest.file - ) -then - # Ok. - : -else - as_fn_error $? "newly created file is older than distributed files! -Check your system clock" "$LINENO" 5 -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } -# If we didn't sleep, we still need to ensure time stamps of config.status and -# generated files are strictly newer. -am_sleep_pid= -if grep 'slept: no' conftest.file >/dev/null 2>&1; then - ( sleep 1 ) & - am_sleep_pid=$! -fi - -rm -f conftest.file - -test "$program_prefix" != NONE && - program_transform_name="s&^&$program_prefix&;$program_transform_name" -# Use a double $ so make ignores it. -test "$program_suffix" != NONE && - program_transform_name="s&\$&$program_suffix&;$program_transform_name" -# Double any \ or $. -# By default was `s,x,x', remove it if useless. -ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' -program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` - -# Expand $ac_aux_dir to an absolute path. -am_aux_dir=`cd "$ac_aux_dir" && pwd` - -if test x"${MISSING+set}" != xset; then - case $am_aux_dir in - *\ * | *\ *) - MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; - *) - MISSING="\${SHELL} $am_aux_dir/missing" ;; - esac -fi -# Use eval to expand $SHELL -if eval "$MISSING --is-lightweight"; then - am_missing_run="$MISSING " -else - am_missing_run= - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5 -$as_echo "$as_me: WARNING: 'missing' script is too old or missing" >&2;} -fi - -if test x"${install_sh+set}" != xset; then - case $am_aux_dir in - *\ * | *\ *) - install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; - *) - install_sh="\${SHELL} $am_aux_dir/install-sh" - esac -fi - -# Installed binaries are usually stripped using 'strip' when the user -# run "make install-strip". However 'strip' might not be the right -# tool to use in cross-compilation environments, therefore Automake -# will honor the 'STRIP' environment variable to overrule this program. -if test "$cross_compiling" != no; then - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. -set dummy ${ac_tool_prefix}strip; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_STRIP+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$STRIP"; then - ac_cv_prog_STRIP="$STRIP" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_STRIP="${ac_tool_prefix}strip" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -STRIP=$ac_cv_prog_STRIP -if test -n "$STRIP"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 -$as_echo "$STRIP" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_STRIP"; then - ac_ct_STRIP=$STRIP - # Extract the first word of "strip", so it can be a program name with args. -set dummy strip; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_STRIP+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_STRIP"; then - ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_STRIP="strip" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP -if test -n "$ac_ct_STRIP"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 -$as_echo "$ac_ct_STRIP" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_STRIP" = x; then - STRIP=":" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - STRIP=$ac_ct_STRIP - fi -else - STRIP="$ac_cv_prog_STRIP" -fi - -fi -INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5 -$as_echo_n "checking for a thread-safe mkdir -p... " >&6; } -if test -z "$MKDIR_P"; then - if ${ac_cv_path_mkdir+:} false; then : - $as_echo_n "(cached) " >&6 -else - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_prog in mkdir gmkdir; do - for ac_exec_ext in '' $ac_executable_extensions; do - as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext" || continue - case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( - 'mkdir (GNU coreutils) '* | \ - 'mkdir (coreutils) '* | \ - 'mkdir (fileutils) '4.1*) - ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext - break 3;; - esac - done - done - done -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 - # As a last resort, use the slow shell script. Don't cache a - # 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. - MKDIR_P="$ac_install_sh -d" - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 -$as_echo "$MKDIR_P" >&6; } - -for ac_prog in gawk mawk nawk awk -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_AWK+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$AWK"; then - ac_cv_prog_AWK="$AWK" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_AWK="$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -AWK=$ac_cv_prog_AWK -if test -n "$AWK"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 -$as_echo "$AWK" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$AWK" && break -done - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 -$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } -set x ${MAKE-make} -ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` -if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat >conftest.make <<\_ACEOF -SHELL = /bin/sh -all: - @echo '@@@%%%=$(MAKE)=@@@%%%' -_ACEOF -# GNU make sometimes prints "make[1]: Entering ...", which would confuse us. -case `${MAKE-make} -f conftest.make 2>/dev/null` in - *@@@%%%=?*=@@@%%%*) - eval ac_cv_prog_make_${ac_make}_set=yes;; - *) - eval ac_cv_prog_make_${ac_make}_set=no;; -esac -rm -f conftest.make -fi -if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - SET_MAKE= -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - SET_MAKE="MAKE=${MAKE-make}" -fi - -rm -rf .tst 2>/dev/null -mkdir .tst 2>/dev/null -if test -d .tst; then - am__leading_dot=. -else - am__leading_dot=_ -fi -rmdir .tst 2>/dev/null - -# Check whether --enable-silent-rules was given. -if test "${enable_silent_rules+set}" = set; then : - enableval=$enable_silent_rules; -fi - -case $enable_silent_rules in # ((( - yes) AM_DEFAULT_VERBOSITY=0;; - no) AM_DEFAULT_VERBOSITY=1;; - *) AM_DEFAULT_VERBOSITY=1;; -esac -am_make=${MAKE-make} -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 -$as_echo_n "checking whether $am_make supports nested variables... " >&6; } -if ${am_cv_make_support_nested_variables+:} false; then : - $as_echo_n "(cached) " >&6 -else - if $as_echo 'TRUE=$(BAR$(V)) -BAR0=false -BAR1=true -V=1 -am__doit: - @$(TRUE) -.PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then - am_cv_make_support_nested_variables=yes -else - am_cv_make_support_nested_variables=no -fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 -$as_echo "$am_cv_make_support_nested_variables" >&6; } -if test $am_cv_make_support_nested_variables = yes; then - AM_V='$(V)' - AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' -else - AM_V=$AM_DEFAULT_VERBOSITY - AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY -fi -AM_BACKSLASH='\' - -if test "`cd $srcdir && pwd`" != "`pwd`"; then - # Use -I$(srcdir) only when $(srcdir) != ., so that make's output - # is not polluted with repeated "-I." - am__isrc=' -I$(srcdir)' - # test to see if srcdir already configured - if test -f $srcdir/config.status; then - as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 - fi -fi - -# test whether we have cygpath -if test -z "$CYGPATH_W"; then - if (cygpath --version) >/dev/null 2>/dev/null; then - CYGPATH_W='cygpath -w' - else - CYGPATH_W=echo - fi -fi - - -# Define the identity of the package. - PACKAGE='tinc' - VERSION='1.0.35' - - -cat >>confdefs.h <<_ACEOF -#define PACKAGE "$PACKAGE" -_ACEOF - - -cat >>confdefs.h <<_ACEOF -#define VERSION "$VERSION" -_ACEOF - -# Some tools Automake needs. - -ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} - - -AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} - - -AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} - - -AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} - - -MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} - -# For better backward compatibility. To be removed once Automake 1.9.x -# dies out for good. For more background, see: -# -# -mkdir_p='$(MKDIR_P)' - -# We need awk for the "check" target (and possibly the TAP driver). The -# system "awk" is bad on some platforms. -# Always define AMTAR for backward compatibility. Yes, it's still used -# in the wild :-( We should find a proper way to deprecate it ... -AMTAR='$${TAR-tar}' - - -# We'll loop over all known methods to create a tar archive until one works. -_am_tools='gnutar pax cpio none' - -am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -' - - - - - - -# POSIX will say in a future version that running "rm -f" with no argument -# is OK; and we want to be able to make that assumption in our Makefile -# recipes. So use an aggressive probe to check that the usage we want is -# actually supported "in the wild" to an acceptable degree. -# See automake bug#10828. -# To make any issue more visible, cause the running configure to be aborted -# by default if the 'rm' program in use doesn't match our expectations; the -# user can still override this though. -if rm -f && rm -fr && rm -rf; then : OK; else - cat >&2 <<'END' -Oops! - -Your 'rm' program seems unable to run without file operands specified -on the command line, even when the '-f' option is present. This is contrary -to the behaviour of most rm programs out there, and not conforming with -the upcoming POSIX standard: - -Please tell bug-automake@gnu.org about your system, including the value -of your $PATH and any error possibly output before this message. This -can help us improve future automake versions. - -END - if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then - echo 'Configuration will proceed anyway, since you have set the' >&2 - echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 - echo >&2 - else - cat >&2 <<'END' -Aborting the configuration process, to ensure you take notice of the issue. - -You can download and install GNU coreutils to get an 'rm' implementation -that behaves properly: . - -If you want to complete the configuration process using your problematic -'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM -to "yes", and re-run configure. - -END - as_fn_error $? "Your 'rm' program is bad, sorry." "$LINENO" 5 - fi -fi - -ac_config_headers="$ac_config_headers config.h" - - -# Check whether --enable-silent-rules was given. -if test "${enable_silent_rules+set}" = set; then : - enableval=$enable_silent_rules; -fi - -case $enable_silent_rules in # ((( - yes) AM_DEFAULT_VERBOSITY=0;; - no) AM_DEFAULT_VERBOSITY=1;; - *) AM_DEFAULT_VERBOSITY=0;; -esac -am_make=${MAKE-make} -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 -$as_echo_n "checking whether $am_make supports nested variables... " >&6; } -if ${am_cv_make_support_nested_variables+:} false; then : - $as_echo_n "(cached) " >&6 -else - if $as_echo 'TRUE=$(BAR$(V)) -BAR0=false -BAR1=true -V=1 -am__doit: - @$(TRUE) -.PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then - am_cv_make_support_nested_variables=yes -else - am_cv_make_support_nested_variables=no -fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 -$as_echo "$am_cv_make_support_nested_variables" >&6; } -if test $am_cv_make_support_nested_variables = yes; then - AM_V='$(V)' - AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' -else - AM_V=$AM_DEFAULT_VERBOSITY - AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY -fi -AM_BACKSLASH='\' - - -# Enable GNU extensions. -# Define this here, not in acconfig's @TOP@ section, since definitions -# in the latter don't make it into the configure-time tests. -DEPDIR="${am__leading_dot}deps" - -ac_config_commands="$ac_config_commands depfiles" - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} supports the include directive" >&5 -$as_echo_n "checking whether ${MAKE-make} supports the include directive... " >&6; } -cat > confinc.mk << 'END' -am__doit: - @echo this is the am__doit target >confinc.out -.PHONY: am__doit -END -am__include="#" -am__quote= -# BSD make does it like this. -echo '.include "confinc.mk" # ignored' > confmf.BSD -# Other make implementations (GNU, Solaris 10, AIX) do it like this. -echo 'include confinc.mk # ignored' > confmf.GNU -_am_result=no -for s in GNU BSD; do - { echo "$as_me:$LINENO: ${MAKE-make} -f confmf.$s && cat confinc.out" >&5 - (${MAKE-make} -f confmf.$s && cat confinc.out) >&5 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } - case $?:`cat confinc.out 2>/dev/null` in #( - '0:this is the am__doit target') : - case $s in #( - BSD) : - am__include='.include' am__quote='"' ;; #( - *) : - am__include='include' am__quote='' ;; -esac ;; #( - *) : - ;; -esac - if test "$am__include" != "#"; then - _am_result="yes ($s style)" - break - fi -done -rm -f confinc.* confmf.* -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: ${_am_result}" >&5 -$as_echo "${_am_result}" >&6; } - -# Check whether --enable-dependency-tracking was given. -if test "${enable_dependency_tracking+set}" = set; then : - enableval=$enable_dependency_tracking; -fi - -if test "x$enable_dependency_tracking" != xno; then - am_depcomp="$ac_aux_dir/depcomp" - AMDEPBACKSLASH='\' - am__nodep='_no' -fi - if test "x$enable_dependency_tracking" != xno; then - AMDEP_TRUE= - AMDEP_FALSE='#' -else - AMDEP_TRUE='#' - AMDEP_FALSE= -fi - - ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' @@ -3062,7 +2310,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="${ac_tool_prefix}gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -3102,7 +2350,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CC="gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -3155,7 +2403,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="${ac_tool_prefix}cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -3196,7 +2444,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue @@ -3254,7 +2502,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -3298,7 +2546,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CC="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -3744,7 +2992,8 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include -struct stat; +#include +#include /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); @@ -3829,193 +3078,6 @@ ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5 -$as_echo_n "checking whether $CC understands -c and -o together... " >&6; } -if ${am_cv_prog_cc_c_o+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF - # Make sure it works both with $CC and with simple cc. - # Following AC_PROG_CC_C_O, we do the test twice because some - # compilers refuse to overwrite an existing .o file with -o, - # though they will create one. - am_cv_prog_cc_c_o=yes - for am_i in 1 2; do - if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5 - ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } \ - && test -f conftest2.$ac_objext; then - : OK - else - am_cv_prog_cc_c_o=no - break - fi - done - rm -f core conftest* - unset am_i -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5 -$as_echo "$am_cv_prog_cc_c_o" >&6; } -if test "$am_cv_prog_cc_c_o" != yes; then - # Losing compiler, so override with the script. - # FIXME: It is wrong to rewrite CC. - # But if we don't then we get into trouble of one sort or another. - # A longer-term fix would be to have automake use am__CC in this case, - # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" - CC="$am_aux_dir/compile $CC" -fi -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - -depcc="$CC" am_compiler_list= - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 -$as_echo_n "checking dependency style of $depcc... " >&6; } -if ${am_cv_CC_dependencies_compiler_type+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then - # We make a subdir and do the tests there. Otherwise we can end up - # making bogus files that we don't know about and never remove. For - # instance it was reported that on HP-UX the gcc test will end up - # making a dummy file named 'D' -- because '-MD' means "put the output - # in D". - rm -rf conftest.dir - mkdir conftest.dir - # Copy depcomp to subdir because otherwise we won't find it if we're - # using a relative directory. - cp "$am_depcomp" conftest.dir - cd conftest.dir - # We will build objects and dependencies in a subdirectory because - # it helps to detect inapplicable dependency modes. For instance - # both Tru64's cc and ICC support -MD to output dependencies as a - # side effect of compilation, but ICC will put the dependencies in - # the current directory while Tru64 will put them in the object - # directory. - mkdir sub - - am_cv_CC_dependencies_compiler_type=none - if test "$am_compiler_list" = ""; then - am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` - fi - am__universal=false - case " $depcc " in #( - *\ -arch\ *\ -arch\ *) am__universal=true ;; - esac - - for depmode in $am_compiler_list; do - # Setup a source with many dependencies, because some compilers - # like to wrap large dependency lists on column 80 (with \), and - # we should not choose a depcomp mode which is confused by this. - # - # We need to recreate these files for each test, as the compiler may - # overwrite some of them when testing with obscure command lines. - # This happens at least with the AIX C compiler. - : > sub/conftest.c - for i in 1 2 3 4 5 6; do - echo '#include "conftst'$i'.h"' >> sub/conftest.c - # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with - # Solaris 10 /bin/sh. - echo '/* dummy */' > sub/conftst$i.h - done - echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf - - # We check with '-c' and '-o' for the sake of the "dashmstdout" - # mode. It turns out that the SunPro C++ compiler does not properly - # handle '-M -o', and we need to detect this. Also, some Intel - # versions had trouble with output in subdirs. - am__obj=sub/conftest.${OBJEXT-o} - am__minus_obj="-o $am__obj" - case $depmode in - gcc) - # This depmode causes a compiler race in universal mode. - test "$am__universal" = false || continue - ;; - nosideeffect) - # After this tag, mechanisms are not by side-effect, so they'll - # only be used when explicitly requested. - if test "x$enable_dependency_tracking" = xyes; then - continue - else - break - fi - ;; - msvc7 | msvc7msys | msvisualcpp | msvcmsys) - # This compiler won't grok '-c -o', but also, the minuso test has - # not run yet. These depmodes are late enough in the game, and - # so weak that their functioning should not be impacted. - am__obj=conftest.${OBJEXT-o} - am__minus_obj= - ;; - none) break ;; - esac - if depmode=$depmode \ - source=sub/conftest.c object=$am__obj \ - depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ - $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ - >/dev/null 2>conftest.err && - grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && - grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && - grep $am__obj sub/conftest.Po > /dev/null 2>&1 && - ${MAKE-make} -s -f confmf > /dev/null 2>&1; then - # icc doesn't choke on unknown options, it will just issue warnings - # or remarks (even with -Werror). So we grep stderr for any message - # that says an option was ignored or not supported. - # When given -MP, icc 7.0 and 7.1 complain thusly: - # icc: Command line warning: ignoring option '-M'; no argument required - # The diagnosis changed in icc 8.0: - # icc: Command line remark: option '-MP' not supported - if (grep 'ignoring option' conftest.err || - grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else - am_cv_CC_dependencies_compiler_type=$depmode - break - fi - fi - done - - cd .. - rm -rf conftest.dir -else - am_cv_CC_dependencies_compiler_type=none -fi - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 -$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } -CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type - - if - test "x$enable_dependency_tracking" != xno \ - && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then - am__fastdepCC_TRUE= - am__fastdepCC_FALSE='#' -else - am__fastdepCC_TRUE='#' - am__fastdepCC_FALSE= -fi - - ac_ext=c ac_cpp='$CPP $CPPFLAGS' @@ -4171,7 +3233,7 @@ do for ac_prog in grep ggrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" - as_fn_executable_p "$ac_path_GREP" || continue + { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue # Check for GNU ac_path_GREP and select it if it is found. # Check for GNU $ac_path_GREP case `"$ac_path_GREP" --version 2>&1` in @@ -4237,7 +3299,7 @@ do for ac_prog in egrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" - as_fn_executable_p "$ac_path_EGREP" || continue + { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue # Check for GNU ac_path_EGREP and select it if it is found. # Check for GNU $ac_path_EGREP case `"$ac_path_EGREP" --version 2>&1` in @@ -4444,8 +3506,8 @@ else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -# define __EXTENSIONS__ 1 - $ac_includes_default +# define __EXTENSIONS__ 1 + $ac_includes_default int main () { @@ -4476,6 +3538,732 @@ $as_echo "$ac_cv_safe_to_define___extensions__" >&6; } +am__api_version='1.11' + +ac_aux_dir= +for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do + if test -f "$ac_dir/install-sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f "$ac_dir/install.sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + elif test -f "$ac_dir/shtool"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/shtool install -c" + break + fi +done +if test -z "$ac_aux_dir"; then + as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 +fi + +# These three variables are undocumented and unsupported, +# and are intended to be withdrawn in a future Autoconf release. +# They can cause serious problems if a builder's source tree is in a directory +# whose full name contains unusual characters. +ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. +ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. +ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. + + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AmigaOS /C/install, which installs bootblocks on floppy discs +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# OS/2's system install, which has a completely different semantic +# ./install, which can be erroneously created by make from ./install.sh. +# Reject install programs that cannot install multiple files. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 +$as_echo_n "checking for a BSD-compatible install... " >&6; } +if test -z "$INSTALL"; then +if ${ac_cv_path_install+:} false; then : + $as_echo_n "(cached) " >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + # Account for people who put trailing slashes in PATH elements. +case $as_dir/ in #(( + ./ | .// | /[cC]/* | \ + /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ + ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ + /usr/ucb/* ) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then + if test $ac_prog = install && + grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + rm -rf conftest.one conftest.two conftest.dir + echo one > conftest.one + echo two > conftest.two + mkdir conftest.dir + if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && + test -s conftest.one && test -s conftest.two && + test -s conftest.dir/conftest.one && + test -s conftest.dir/conftest.two + then + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + fi + done + done + ;; +esac + + done +IFS=$as_save_IFS + +rm -rf conftest.one conftest.two conftest.dir + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL=$ac_cv_path_install + else + # As a last resort, use the slow shell script. Don't cache a + # value for INSTALL 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. + INSTALL=$ac_install_sh + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 +$as_echo "$INSTALL" >&6; } + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 +$as_echo_n "checking whether build environment is sane... " >&6; } +# Just in case +sleep 1 +echo timestamp > conftest.file +# Reject unsafe characters in $srcdir or the absolute working directory +# name. Accept space and tab only in the latter. +am_lf=' +' +case `pwd` in + *[\\\"\#\$\&\'\`$am_lf]*) + as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;; +esac +case $srcdir in + *[\\\"\#\$\&\'\`$am_lf\ \ ]*) + as_fn_error $? "unsafe srcdir value: \`$srcdir'" "$LINENO" 5;; +esac + +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$*" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + rm -f conftest.file + if test "$*" != "X $srcdir/configure conftest.file" \ + && test "$*" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + as_fn_error $? "ls -t appears to fail. Make sure there is not a broken +alias in your environment" "$LINENO" 5 + fi + + test "$2" = conftest.file + ) +then + # Ok. + : +else + as_fn_error $? "newly created file is older than distributed files! +Check your system clock" "$LINENO" 5 +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +test "$program_prefix" != NONE && + program_transform_name="s&^&$program_prefix&;$program_transform_name" +# Use a double $ so make ignores it. +test "$program_suffix" != NONE && + program_transform_name="s&\$&$program_suffix&;$program_transform_name" +# Double any \ or $. +# By default was `s,x,x', remove it if useless. +ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' +program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` + +# expand $ac_aux_dir to an absolute path +am_aux_dir=`cd $ac_aux_dir && pwd` + +if test x"${MISSING+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; + *) + MISSING="\${SHELL} $am_aux_dir/missing" ;; + esac +fi +# Use eval to expand $SHELL +if eval "$MISSING --run true"; then + am_missing_run="$MISSING --run " +else + am_missing_run= + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`missing' script is too old or missing" >&5 +$as_echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;} +fi + +if test x"${install_sh}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; + *) + install_sh="\${SHELL} $am_aux_dir/install-sh" + esac +fi + +# Installed binaries are usually stripped using `strip' when the user +# run `make install-strip'. However `strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the `STRIP' environment variable to overrule this program. +if test "$cross_compiling" != no; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 +$as_echo "$STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_STRIP="strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 +$as_echo "$ac_ct_STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_STRIP" = x; then + STRIP=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + STRIP=$ac_ct_STRIP + fi +else + STRIP="$ac_cv_prog_STRIP" +fi + +fi +INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5 +$as_echo_n "checking for a thread-safe mkdir -p... " >&6; } +if test -z "$MKDIR_P"; then + if ${ac_cv_path_mkdir+:} false; then : + $as_echo_n "(cached) " >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in mkdir gmkdir; do + for ac_exec_ext in '' $ac_executable_extensions; do + { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; } || continue + case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( + 'mkdir (GNU coreutils) '* | \ + 'mkdir (coreutils) '* | \ + 'mkdir (fileutils) '4.1*) + ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext + break 3;; + esac + done + done + done +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 + # As a last resort, use the slow shell script. Don't cache a + # 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. + MKDIR_P="$ac_install_sh -d" + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 +$as_echo "$MKDIR_P" >&6; } + +mkdir_p="$MKDIR_P" +case $mkdir_p in + [\\/$]* | ?:[\\/]*) ;; + */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; +esac + +for ac_prog in gawk mawk nawk awk +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_AWK+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AWK"; then + ac_cv_prog_AWK="$AWK" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_AWK="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AWK=$ac_cv_prog_AWK +if test -n "$AWK"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 +$as_echo "$AWK" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$AWK" && break +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 +$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } +set x ${MAKE-make} +ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` +if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat >conftest.make <<\_ACEOF +SHELL = /bin/sh +all: + @echo '@@@%%%=$(MAKE)=@@@%%%' +_ACEOF +# GNU make sometimes prints "make[1]: Entering ...", which would confuse us. +case `${MAKE-make} -f conftest.make 2>/dev/null` in + *@@@%%%=?*=@@@%%%*) + eval ac_cv_prog_make_${ac_make}_set=yes;; + *) + eval ac_cv_prog_make_${ac_make}_set=no;; +esac +rm -f conftest.make +fi +if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + SET_MAKE= +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + SET_MAKE="MAKE=${MAKE-make}" +fi + +rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null + +DEPDIR="${am__leading_dot}deps" + +ac_config_commands="$ac_config_commands depfiles" + + +am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo this is the am__doit target +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5 +$as_echo_n "checking for style of include used by $am_make... " >&6; } +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# Ignore all kinds of additional output from `make'. +case `$am_make -s -f confmf 2> /dev/null` in #( +*the\ am__doit\ target*) + am__include=include + am__quote= + _am_result=GNU + ;; +esac +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + case `$am_make -s -f confmf 2> /dev/null` in #( + *the\ am__doit\ target*) + am__include=.include + am__quote="\"" + _am_result=BSD + ;; + esac +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5 +$as_echo "$_am_result" >&6; } +rm -f confinc confmf + +# Check whether --enable-dependency-tracking was given. +if test "${enable_dependency_tracking+set}" = set; then : + enableval=$enable_dependency_tracking; +fi + +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' +fi + if test "x$enable_dependency_tracking" != xno; then + AMDEP_TRUE= + AMDEP_FALSE='#' +else + AMDEP_TRUE='#' + AMDEP_FALSE= +fi + + +if test "`cd $srcdir && pwd`" != "`pwd`"; then + # Use -I$(srcdir) only when $(srcdir) != ., so that make's output + # is not polluted with repeated "-I." + am__isrc=' -I$(srcdir)' + # test to see if srcdir already configured + if test -f $srcdir/config.status; then + as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 + fi +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi + + +# Define the identity of the package. + PACKAGE=tinc + VERSION=1.1pre2 + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE "$PACKAGE" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define VERSION "$VERSION" +_ACEOF + +# Some tools Automake needs. + +ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} + + +AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} + + +AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} + + +AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} + + +MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} + +# We need awk for the "check" target. The system "awk" is bad on +# some platforms. +# Always define AMTAR for backward compatibility. + +AMTAR=${AMTAR-"${am_missing_run}tar"} + +am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -' + + + + +depcc="$CC" am_compiler_list= + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 +$as_echo_n "checking dependency style of $depcc... " >&6; } +if ${am_cv_CC_dependencies_compiler_type+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named `D' -- because `-MD' means `put the output + # in D'. + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CC_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + am__universal=false + case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with + # Solaris 8's {/usr,}/bin/sh. + touch sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with `-c' and `-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle `-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # after this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvisualcpp | msvcmsys) + # This compiler won't grok `-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CC_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CC_dependencies_compiler_type=none +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 +$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } +CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type + + if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then + am__fastdepCC_TRUE= + am__fastdepCC_FALSE='#' +else + am__fastdepCC_TRUE='#' + am__fastdepCC_FALSE= +fi + + + +ac_config_headers="$ac_config_headers config.h" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable maintainer-specific portions of Makefiles" >&5 +$as_echo_n "checking whether to enable maintainer-specific portions of Makefiles... " >&6; } + # Check whether --enable-maintainer-mode was given. +if test "${enable_maintainer_mode+set}" = set; then : + enableval=$enable_maintainer_mode; USE_MAINTAINER_MODE=$enableval +else + USE_MAINTAINER_MODE=no +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $USE_MAINTAINER_MODE" >&5 +$as_echo "$USE_MAINTAINER_MODE" >&6; } + if test $USE_MAINTAINER_MODE = yes; then + MAINTAINER_MODE_TRUE= + MAINTAINER_MODE_FALSE='#' +else + MAINTAINER_MODE_TRUE='#' + MAINTAINER_MODE_FALSE= +fi + + MAINT=$MAINTAINER_MODE_TRUE + + + +# Enable GNU extensions. +# Define this here, not in acconfig's @TOP@ section, since definitions +# in the latter don't make it into the configure-time tests. + $as_echo "#define __USE_BSD 1" >>confdefs.h @@ -4626,7 +4414,7 @@ main () return 0; } _ACEOF -for ac_arg in '' -std=gnu99 -std=c99 -c99 -AC99 -D_STDC_C99= -qlanglvl=extc99 +for ac_arg in '' -std=gnu99 -std=c99 -c99 -AC99 -xc99=all -qlanglvl=extc99 do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO"; then : @@ -4795,7 +4583,108 @@ ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $ ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 +$as_echo_n "checking whether ln -s works... " >&6; } +LN_S=$as_ln_s +if test "$LN_S" = "ln -s"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 +$as_echo "no, using $LN_S" >&6; } +fi +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. +set dummy ${ac_tool_prefix}ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_RANLIB+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +RANLIB=$ac_cv_prog_RANLIB +if test -n "$RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 +$as_echo "$RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_RANLIB"; then + ac_ct_RANLIB=$RANLIB + # Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_RANLIB+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_RANLIB"; then + ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_RANLIB="ranlib" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB +if test -n "$ac_ct_RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 +$as_echo "$ac_ct_RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_RANLIB" = x; then + RANLIB=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + RANLIB=$ac_ct_RANLIB + fi +else + RANLIB="$ac_cv_prog_RANLIB" +fi @@ -4873,66 +4762,66 @@ case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac case $host_os in *linux*) - linux=true $as_echo "#define HAVE_LINUX 1" >>confdefs.h + rm -f src/device.c; ln -sf linux/device.c src/device.c ;; *freebsd*) - bsd=true $as_echo "#define HAVE_FREEBSD 1" >>confdefs.h + rm -f src/device.c; ln -sf bsd/device.c src/device.c ;; *darwin*) - bsd=true $as_echo "#define HAVE_DARWIN 1" >>confdefs.h + rm -f src/device.c; ln -sf bsd/device.c src/device.c ;; *solaris*) - solaris=true $as_echo "#define HAVE_SOLARIS 1" >>confdefs.h + rm -f src/device.c; ln -sf solaris/device.c src/device.c ;; *openbsd*) - bsd=true $as_echo "#define HAVE_OPENBSD 1" >>confdefs.h + rm -f src/device.c; ln -sf bsd/device.c src/device.c ;; *netbsd*) - bsd=true $as_echo "#define HAVE_NETBSD 1" >>confdefs.h + rm -f src/device.c; ln -sf bsd/device.c src/device.c ;; *dragonfly*) - bsd=true $as_echo "#define HAVE_DRAGONFLY 1" >>confdefs.h + rm -f src/device.c; ln -sf bsd/device.c src/device.c ;; *bsd*) - bsd=true { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \"Unknown BSD variant" >&5 $as_echo "$as_me: WARNING: \"Unknown BSD variant" >&2;} $as_echo "#define HAVE_BSD 1" >>confdefs.h + rm -f src/device.c; ln -sf bsd/device.c src/device.c ;; *cygwin*) - cygwin=true $as_echo "#define HAVE_CYGWIN 1" >>confdefs.h + rm -f src/device.c; ln -sf cygwin/device.c src/device.c ;; *mingw*) - mingw=true $as_echo "#define HAVE_MINGW 1" >>confdefs.h + rm -f src/device.c; cp -f src/mingw/device.c src/device.c LIBS="$LIBS -lws2_32 -lgdi32 -lcrypt32" ;; *) @@ -4940,70 +4829,13 @@ $as_echo "#define HAVE_MINGW 1" >>confdefs.h ;; esac -# Check whether --enable-uml was given. -if test "${enable_uml+set}" = set; then : - enableval=$enable_uml; if test "x$enable_uml" = "xyes"; then : - -$as_echo "#define ENABLE_UML 1" >>confdefs.h - - uml=true - -else - uml=false -fi - -else - uml=false - -fi - - -# Check whether --enable-vde was given. -if test "${enable_vde+set}" = set; then : - enableval=$enable_vde; if test "x$enable_vde" = "xyes"; then : - for ac_header in libvdeplug_dyn.h -do : - ac_fn_c_check_header_mongrel "$LINENO" "libvdeplug_dyn.h" "ac_cv_header_libvdeplug_dyn_h" "$ac_includes_default" -if test "x$ac_cv_header_libvdeplug_dyn_h" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBVDEPLUG_DYN_H 1 -_ACEOF - -else - as_fn_error $? "VDE plug header files not found." "$LINENO" 5; break -fi - -done - - -$as_echo "#define ENABLE_VDE 1" >>confdefs.h - - vde=true - -else - vde=false -fi - -else - vde=false - -fi - - # Check whether --enable-tunemu was given. if test "${enable_tunemu+set}" = set; then : - enableval=$enable_tunemu; if test "x$enable_tunemu" = "xyes"; then : - + enableval=$enable_tunemu; $as_echo "#define ENABLE_TUNEMU 1" >>confdefs.h - tunemu=true + tunemu=true -else - tunemu=false -fi - -else - tunemu=false fi @@ -5011,93 +4843,13 @@ fi # Check whether --with-windows2000 was given. if test "${with_windows2000+set}" = set; then : - withval=$with_windows2000; if test "x$with_windows2000" = "xyes"; then : - + withval=$with_windows2000; $as_echo "#define WITH_WINDOWS2000 1" >>confdefs.h -fi - fi - -# Check whether --with-systemd was given. -if test "${with_systemd+set}" = set; then : - withval=$with_systemd; systemd=true; systemd_path="$with_systemd" -else - systemd=false - -fi - - -if test "x$with_systemd" = "xyes"; then : - systemd_path="\${libdir}/systemd/system" -else - if test "x$with_systemd" = "xno"; then : - systemd=false -fi -fi - -systemd_path=$systemd_path - - - if test "$linux" = true; then - LINUX_TRUE= - LINUX_FALSE='#' -else - LINUX_TRUE='#' - LINUX_FALSE= -fi - - if test "$bsd" = true; then - BSD_TRUE= - BSD_FALSE='#' -else - BSD_TRUE='#' - BSD_FALSE= -fi - - if test "$solaris" = true; then - SOLARIS_TRUE= - SOLARIS_FALSE='#' -else - SOLARIS_TRUE='#' - SOLARIS_FALSE= -fi - - if test "$mingw" = true; then - MINGW_TRUE= - MINGW_FALSE='#' -else - MINGW_TRUE='#' - MINGW_FALSE= -fi - - if test "$cygwin" = true; then - CYGWIN_TRUE= - CYGWIN_FALSE='#' -else - CYGWIN_TRUE='#' - CYGWIN_FALSE= -fi - - if test "$uml" = true; then - UML_TRUE= - UML_FALSE='#' -else - UML_TRUE='#' - UML_FALSE= -fi - - if test "$vde" = true; then - VDE_TRUE= - VDE_FALSE='#' -else - VDE_TRUE='#' - VDE_FALSE= -fi - if test "$tunemu" = true; then TUNEMU_TRUE= TUNEMU_FALSE='#' @@ -5106,14 +4858,6 @@ else TUNEMU_FALSE= fi - if test "$systemd" = true; then - WITH_SYSTEMD_TRUE= - WITH_SYSTEMD_FALSE='#' -else - WITH_SYSTEMD_TRUE='#' - WITH_SYSTEMD_FALSE= -fi - cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure @@ -5209,23 +4953,17 @@ if test -d /sw/lib ; then fi -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking CFLAGS for maximum warnings" >&5 -$as_echo_n "checking CFLAGS for maximum warnings... " >&6; } -if ${ac_cv_cflags_warn_all+:} false; then : +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 +$as_echo_n "checking for ANSI C header files... " >&6; } +if ${ac_cv_header_stdc+:} false; then : $as_echo_n "(cached) " >&6 else - ac_cv_cflags_warn_all="no, unknown" -ac_save_CFLAGS="$CFLAGS" -for ac_arg in "-warn all % -warn all" "-pedantic % -Wall" "-xstrconst % -v" "-std1 % -verbose -w0 -warnprotos" "-qlanglvl=ansi % -qsrcmsg -qinfo=all:noppt:noppc:noobs:nocnd" "-ansi -ansiE % -fullwarn" "+ESlit % +w1" "-Xc % -pvctl,fullmsg" "-h conform % -h msglevel 2" # -do CFLAGS="$ac_save_CFLAGS "`echo $ac_arg | sed -e 's,%%.*,,' -e 's,%,,'` - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ +#include +#include +#include +#include int main () @@ -5236,390 +4974,98 @@ main () } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_cflags_warn_all=`echo $ac_arg | sed -e 's,.*% *,,'` ; break + ac_cv_header_stdc=yes +else + ac_cv_header_stdc=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -done -CFLAGS="$ac_save_CFLAGS" -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cflags_warn_all" >&5 -$as_echo "$ac_cv_cflags_warn_all" >&6; } - - -case ".$ac_cv_cflags_warn_all" in - .ok|.ok,*) ;; - .|.no|.no,*) ;; - *) if ${CFLAGS+:} false; then : - case " $CFLAGS " in - *" $ac_cv_cflags_warn_all "*) - { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS already contains \$ac_cv_cflags_warn_all"; } >&5 - (: CFLAGS already contains $ac_cv_cflags_warn_all) 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } - ;; - *) - { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS=\"\$CFLAGS \$ac_cv_cflags_warn_all\""; } >&5 - (: CFLAGS="$CFLAGS $ac_cv_cflags_warn_all") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } - CFLAGS="$CFLAGS $ac_cv_cflags_warn_all" - ;; - esac -else - CFLAGS="$ac_cv_cflags_warn_all" -fi - ;; -esac - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - - -# Check whether --enable-hardening was given. -if test "${enable_hardening+set}" = set; then : - enableval=$enable_hardening; -fi - -if test "x$enable_hardening" != "xno"; then : - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -DFORTIFY_SOURCE=2" >&5 -$as_echo_n "checking whether C compiler accepts -DFORTIFY_SOURCE=2... " >&6; } -if ${ax_cv_check_cflags___DFORTIFY_SOURCE_2+:} false; then : - $as_echo_n "(cached) " >&6 -else - - ax_check_save_flags=$CFLAGS - CFLAGS="$CFLAGS -DFORTIFY_SOURCE=2" +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ +#include -int -main () -{ - - ; - return 0; -} _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ax_cv_check_cflags___DFORTIFY_SOURCE_2=yes +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then : + else - ax_cv_check_cflags___DFORTIFY_SOURCE_2=no + ac_cv_header_stdc=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - CFLAGS=$ax_check_save_flags +rm -f conftest* + fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___DFORTIFY_SOURCE_2" >&5 -$as_echo "$ax_cv_check_cflags___DFORTIFY_SOURCE_2" >&6; } -if test x"$ax_cv_check_cflags___DFORTIFY_SOURCE_2" = xyes; then : - CPPFLAGS="$CPPFLAGS -DFORTIFY_SOURCE=2" + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then : + else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then : : -fi - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -fwrapv" >&5 -$as_echo_n "checking whether C compiler accepts -fwrapv... " >&6; } -if ${ax_cv_check_cflags___fwrapv+:} false; then : - $as_echo_n "(cached) " >&6 else - - ax_check_save_flags=$CFLAGS - CFLAGS="$CFLAGS -fwrapv" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ +#include +#include +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) \ + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { - - ; + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + return 2; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ax_cv_check_cflags___fwrapv=yes +if ac_fn_c_try_run "$LINENO"; then : + else - ax_cv_check_cflags___fwrapv=no + ac_cv_header_stdc=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - CFLAGS=$ax_check_save_flags -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___fwrapv" >&5 -$as_echo "$ax_cv_check_cflags___fwrapv" >&6; } -if test x"$ax_cv_check_cflags___fwrapv" = xyes; then : - CPPFLAGS="$CPPFLAGS -fwrapv" -else - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -fno-strict-overflow" >&5 -$as_echo_n "checking whether C compiler accepts -fno-strict-overflow... " >&6; } -if ${ax_cv_check_cflags___fno_strict_overflow+:} false; then : - $as_echo_n "(cached) " >&6 -else - - ax_check_save_flags=$CFLAGS - CFLAGS="$CFLAGS -fno-strict-overflow" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ax_cv_check_cflags___fno_strict_overflow=yes -else - ax_cv_check_cflags___fno_strict_overflow=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - CFLAGS=$ax_check_save_flags -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___fno_strict_overflow" >&5 -$as_echo "$ax_cv_check_cflags___fno_strict_overflow" >&6; } -if test x"$ax_cv_check_cflags___fno_strict_overflow" = xyes; then : - CPPFLAGS="$CPPFLAGS -fno-strict-overflow" -else - : +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi - - case $host_os in - *mingw*) - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the linker accepts -Wl,--dynamicbase" >&5 -$as_echo_n "checking whether the linker accepts -Wl,--dynamicbase... " >&6; } -if ${ax_cv_check_ldflags___Wl___dynamicbase+:} false; then : - $as_echo_n "(cached) " >&6 -else - - ax_check_save_flags=$LDFLAGS - LDFLAGS="$LDFLAGS -Wl,--dynamicbase" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ax_cv_check_ldflags___Wl___dynamicbase=yes -else - ax_cv_check_ldflags___Wl___dynamicbase=no fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - LDFLAGS=$ax_check_save_flags -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_ldflags___Wl___dynamicbase" >&5 -$as_echo "$ax_cv_check_ldflags___Wl___dynamicbase" >&6; } -if test x"$ax_cv_check_ldflags___Wl___dynamicbase" = xyes; then : - LDFLAGS="$LDFLAGS -Wl,--dynamicbase" -else - : +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 +$as_echo "$ac_cv_header_stdc" >&6; } +if test $ac_cv_header_stdc = yes; then + +$as_echo "#define STDC_HEADERS 1" >>confdefs.h + fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the linker accepts -Wl,--nxcompat" >&5 -$as_echo_n "checking whether the linker accepts -Wl,--nxcompat... " >&6; } -if ${ax_cv_check_ldflags___Wl___nxcompat+:} false; then : - $as_echo_n "(cached) " >&6 -else - - ax_check_save_flags=$LDFLAGS - LDFLAGS="$LDFLAGS -Wl,--nxcompat" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ax_cv_check_ldflags___Wl___nxcompat=yes -else - ax_cv_check_ldflags___Wl___nxcompat=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - LDFLAGS=$ax_check_save_flags -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_ldflags___Wl___nxcompat" >&5 -$as_echo "$ax_cv_check_ldflags___Wl___nxcompat" >&6; } -if test x"$ax_cv_check_ldflags___Wl___nxcompat" = xyes; then : - LDFLAGS="$LDFLAGS -Wl,--nxcompat" -else - : -fi - - ;; - *) - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -fPIE" >&5 -$as_echo_n "checking whether C compiler accepts -fPIE... " >&6; } -if ${ax_cv_check_cflags___fPIE+:} false; then : - $as_echo_n "(cached) " >&6 -else - - ax_check_save_flags=$CFLAGS - CFLAGS="$CFLAGS -fPIE" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ax_cv_check_cflags___fPIE=yes -else - ax_cv_check_cflags___fPIE=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - CFLAGS=$ax_check_save_flags -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___fPIE" >&5 -$as_echo "$ax_cv_check_cflags___fPIE" >&6; } -if test x"$ax_cv_check_cflags___fPIE" = xyes; then : - CPPFLAGS="$CPPFLAGS -fPIE" -else - : -fi - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the linker accepts -pie" >&5 -$as_echo_n "checking whether the linker accepts -pie... " >&6; } -if ${ax_cv_check_ldflags___pie+:} false; then : - $as_echo_n "(cached) " >&6 -else - - ax_check_save_flags=$LDFLAGS - LDFLAGS="$LDFLAGS -pie" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ax_cv_check_ldflags___pie=yes -else - ax_cv_check_ldflags___pie=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - LDFLAGS=$ax_check_save_flags -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_ldflags___pie" >&5 -$as_echo "$ax_cv_check_ldflags___pie" >&6; } -if test x"$ax_cv_check_ldflags___pie" = xyes; then : - LDFLAGS="$LDFLAGS -pie" -else - : -fi - - ;; - esac - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the linker accepts -Wl,-z,relro" >&5 -$as_echo_n "checking whether the linker accepts -Wl,-z,relro... " >&6; } -if ${ax_cv_check_ldflags___Wl__z_relro+:} false; then : - $as_echo_n "(cached) " >&6 -else - - ax_check_save_flags=$LDFLAGS - LDFLAGS="$LDFLAGS -Wl,-z,relro" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ax_cv_check_ldflags___Wl__z_relro=yes -else - ax_cv_check_ldflags___Wl__z_relro=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - LDFLAGS=$ax_check_save_flags -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_ldflags___Wl__z_relro" >&5 -$as_echo "$ax_cv_check_ldflags___Wl__z_relro" >&6; } -if test x"$ax_cv_check_ldflags___Wl__z_relro" = xyes; then : - LDFLAGS="$LDFLAGS -Wl,-z,relro" -else - : -fi - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the linker accepts -Wl,-z,now" >&5 -$as_echo_n "checking whether the linker accepts -Wl,-z,now... " >&6; } -if ${ax_cv_check_ldflags___Wl__z_now+:} false; then : - $as_echo_n "(cached) " >&6 -else - - ax_check_save_flags=$LDFLAGS - LDFLAGS="$LDFLAGS -Wl,-z,now" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ax_cv_check_ldflags___Wl__z_now=yes -else - ax_cv_check_ldflags___Wl__z_now=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - LDFLAGS=$ax_check_save_flags -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_ldflags___Wl__z_now" >&5 -$as_echo "$ax_cv_check_ldflags___Wl__z_now" >&6; } -if test x"$ax_cv_check_ldflags___Wl__z_now" = xyes; then : - LDFLAGS="$LDFLAGS -Wl,-z,now" -else - : -fi - - - -fi; - - - -for ac_header in syslog.h sys/file.h sys/ioctl.h sys/mman.h sys/param.h sys/resource.h sys/socket.h sys/time.h sys/uio.h sys/wait.h netdb.h arpa/inet.h arpa/nameser.h dirent.h getopt.h +for ac_header in stdbool.h syslog.h sys/file.h sys/ioctl.h sys/mman.h sys/param.h sys/resource.h sys/socket.h sys/time.h sys/uio.h sys/un.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" @@ -5632,10 +5078,10 @@ fi done -for ac_header in net/if.h net/if_types.h linux/if_tun.h net/if_tun.h net/if_utun.h net/tun/if_tun.h net/if_tap.h net/tap/if_tap.h net/ethernet.h net/if_arp.h netinet/in_systm.h netinet/in.h netinet/in6.h netpacket/packet.h +for ac_header in net/if.h net/if_types.h linux/if_tun.h net/if_tun.h net/tun/if_tun.h net/if_tap.h net/tap/if_tap.h net/ethernet.h net/if_arp.h netinet/in_systm.h netinet/in.h netinet/in6.h time.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` -ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "#include \"$srcdir/src/have.h\" +ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "#include \"have.h\" " if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : @@ -5647,10 +5093,10 @@ fi done -for ac_header in netinet/if_ether.h netinet/ip.h netinet/ip6.h resolv.h +for ac_header in netinet/if_ether.h netinet/ip.h netinet/ip6.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` -ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "#include \"$srcdir/src/have.h\" +ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "#include \"have.h\" " if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : @@ -5665,7 +5111,7 @@ done for ac_header in netinet/tcp.h netinet/ip_icmp.h netinet/icmp6.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` -ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "#include \"$srcdir/src/have.h\" +ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "#include \"have.h\" " if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : @@ -5678,6 +5124,120 @@ fi done +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5 +$as_echo_n "checking for an ANSI C-conforming const... " >&6; } +if ${ac_cv_c_const+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +/* FIXME: Include the comments suggested by Paul. */ +#ifndef __cplusplus + /* Ultrix mips cc rejects this. */ + typedef int charset[2]; + const charset cs; + /* SunOS 4.1.1 cc rejects this. */ + char const *const *pcpcc; + char **ppc; + /* NEC SVR4.0.2 mips cc rejects this. */ + struct point {int x, y;}; + static struct point const zero = {0,0}; + /* AIX XL C 1.02.0.0 rejects this. + It does not let you subtract one const X* pointer from another in + an arm of an if-expression whose if-part is not a constant + expression */ + const char *g = "string"; + pcpcc = &g + (g ? g-g : 0); + /* HPUX 7.0 cc rejects these. */ + ++pcpcc; + ppc = (char**) pcpcc; + pcpcc = (char const *const *) ppc; + { /* SCO 3.2v4 cc rejects this. */ + char *t; + char const *s = 0 ? (char *) 0 : (char const *) 0; + + *t++ = 0; + if (s) return 0; + } + { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ + int x[] = {25, 17}; + const int *foo = &x[0]; + ++foo; + } + { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ + typedef const int *iptr; + iptr p = 0; + ++p; + } + { /* AIX XL C 1.02.0.0 rejects this saying + "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ + struct s { int j; const int *ap[3]; }; + struct s *b; b->j = 5; + } + { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ + const int foo = 10; + if (!foo) return 0; + } + return !cs[0] && !zero.x; +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_c_const=yes +else + ac_cv_c_const=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_const" >&5 +$as_echo "$ac_cv_c_const" >&6; } +if test $ac_cv_c_const = no; then + +$as_echo "#define const /**/" >>confdefs.h + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for working volatile" >&5 +$as_echo_n "checking for working volatile... " >&6; } +if ${ac_cv_c_volatile+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + +volatile int x; +int * volatile y = (int *) 0; +return !x && !y; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_c_volatile=yes +else + ac_cv_c_volatile=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_volatile" >&5 +$as_echo "$ac_cv_c_volatile" >&6; } +if test $ac_cv_c_volatile = no; then + +$as_echo "#define volatile /**/" >>confdefs.h + +fi + ac_fn_c_check_type "$LINENO" "pid_t" "ac_cv_type_pid_t" "$ac_includes_default" if test "x$ac_cv_type_pid_t" = xyes; then : @@ -5687,6 +5247,87 @@ cat >>confdefs.h <<_ACEOF #define pid_t int _ACEOF +fi + +ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default" +if test "x$ac_cv_type_size_t" = xyes; then : + +else + +cat >>confdefs.h <<_ACEOF +#define size_t unsigned int +_ACEOF + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether time.h and sys/time.h may both be included" >&5 +$as_echo_n "checking whether time.h and sys/time.h may both be included... " >&6; } +if ${ac_cv_header_time+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#include + +int +main () +{ +if ((struct tm *) 0) +return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_header_time=yes +else + ac_cv_header_time=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_time" >&5 +$as_echo "$ac_cv_header_time" >&6; } +if test $ac_cv_header_time = yes; then + +$as_echo "#define TIME_WITH_SYS_TIME 1" >>confdefs.h + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether struct tm is in sys/time.h or time.h" >&5 +$as_echo_n "checking whether struct tm is in sys/time.h or time.h... " >&6; } +if ${ac_cv_struct_tm+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include + +int +main () +{ +struct tm tm; + int *p = &tm.tm_sec; + return !p; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_struct_tm=time.h +else + ac_cv_struct_tm=sys/time.h +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_struct_tm" >&5 +$as_echo "$ac_cv_struct_tm" >&6; } +if test $ac_cv_struct_tm = sys/time.h; then + +$as_echo "#define TM_IN_SYS_TIME 1" >>confdefs.h + fi @@ -5701,8 +5342,8 @@ else CFLAGS="$CFLAGS -Wall -Werror" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -void *test(void) __attribute__ ((__malloc__)); - void *test(void) { return (void *)0; } +void test(void) __attribute__ ((__malloc__)); + void test(void) { return; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : @@ -5725,7 +5366,7 @@ $as_echo "#define __malloc__ /**/" >>confdefs.h fi -ac_fn_c_check_type "$LINENO" "socklen_t" "ac_cv_type_socklen_t" "#include \"$srcdir/src/have.h\" +ac_fn_c_check_type "$LINENO" "socklen_t" "ac_cv_type_socklen_t" "#include \"have.h\" " if test "x$ac_cv_type_socklen_t" = xyes; then : @@ -5736,7 +5377,7 @@ _ACEOF fi -ac_fn_c_check_type "$LINENO" "struct ether_header" "ac_cv_type_struct_ether_header" "#include \"$srcdir/src/have.h\" +ac_fn_c_check_type "$LINENO" "struct ether_header" "ac_cv_type_struct_ether_header" "#include \"have.h\" " if test "x$ac_cv_type_struct_ether_header" = xyes; then : @@ -5747,7 +5388,7 @@ _ACEOF fi -ac_fn_c_check_type "$LINENO" "struct arphdr" "ac_cv_type_struct_arphdr" "#include \"$srcdir/src/have.h\" +ac_fn_c_check_type "$LINENO" "struct arphdr" "ac_cv_type_struct_arphdr" "#include \"have.h\" " if test "x$ac_cv_type_struct_arphdr" = xyes; then : @@ -5758,7 +5399,7 @@ _ACEOF fi -ac_fn_c_check_type "$LINENO" "struct ether_arp" "ac_cv_type_struct_ether_arp" "#include \"$srcdir/src/have.h\" +ac_fn_c_check_type "$LINENO" "struct ether_arp" "ac_cv_type_struct_ether_arp" "#include \"have.h\" " if test "x$ac_cv_type_struct_ether_arp" = xyes; then : @@ -5769,7 +5410,7 @@ _ACEOF fi -ac_fn_c_check_type "$LINENO" "struct in_addr" "ac_cv_type_struct_in_addr" "#include \"$srcdir/src/have.h\" +ac_fn_c_check_type "$LINENO" "struct in_addr" "ac_cv_type_struct_in_addr" "#include \"have.h\" " if test "x$ac_cv_type_struct_in_addr" = xyes; then : @@ -5780,7 +5421,7 @@ _ACEOF fi -ac_fn_c_check_type "$LINENO" "struct addrinfo" "ac_cv_type_struct_addrinfo" "#include \"$srcdir/src/have.h\" +ac_fn_c_check_type "$LINENO" "struct addrinfo" "ac_cv_type_struct_addrinfo" "#include \"have.h\" " if test "x$ac_cv_type_struct_addrinfo" = xyes; then : @@ -5791,7 +5432,7 @@ _ACEOF fi -ac_fn_c_check_type "$LINENO" "struct ip" "ac_cv_type_struct_ip" "#include \"$srcdir/src/have.h\" +ac_fn_c_check_type "$LINENO" "struct ip" "ac_cv_type_struct_ip" "#include \"have.h\" " if test "x$ac_cv_type_struct_ip" = xyes; then : @@ -5802,7 +5443,7 @@ _ACEOF fi -ac_fn_c_check_type "$LINENO" "struct icmp" "ac_cv_type_struct_icmp" "#include \"$srcdir/src/have.h\" +ac_fn_c_check_type "$LINENO" "struct icmp" "ac_cv_type_struct_icmp" "#include \"have.h\" " if test "x$ac_cv_type_struct_icmp" = xyes; then : @@ -5813,7 +5454,7 @@ _ACEOF fi -ac_fn_c_check_type "$LINENO" "struct in6_addr" "ac_cv_type_struct_in6_addr" "#include \"$srcdir/src/have.h\" +ac_fn_c_check_type "$LINENO" "struct in6_addr" "ac_cv_type_struct_in6_addr" "#include \"have.h\" " if test "x$ac_cv_type_struct_in6_addr" = xyes; then : @@ -5824,7 +5465,7 @@ _ACEOF fi -ac_fn_c_check_type "$LINENO" "struct sockaddr_in6" "ac_cv_type_struct_sockaddr_in6" "#include \"$srcdir/src/have.h\" +ac_fn_c_check_type "$LINENO" "struct sockaddr_in6" "ac_cv_type_struct_sockaddr_in6" "#include \"have.h\" " if test "x$ac_cv_type_struct_sockaddr_in6" = xyes; then : @@ -5835,7 +5476,7 @@ _ACEOF fi -ac_fn_c_check_type "$LINENO" "struct ip6_hdr" "ac_cv_type_struct_ip6_hdr" "#include \"$srcdir/src/have.h\" +ac_fn_c_check_type "$LINENO" "struct ip6_hdr" "ac_cv_type_struct_ip6_hdr" "#include \"have.h\" " if test "x$ac_cv_type_struct_ip6_hdr" = xyes; then : @@ -5846,7 +5487,7 @@ _ACEOF fi -ac_fn_c_check_type "$LINENO" "struct icmp6_hdr" "ac_cv_type_struct_icmp6_hdr" "#include \"$srcdir/src/have.h\" +ac_fn_c_check_type "$LINENO" "struct icmp6_hdr" "ac_cv_type_struct_icmp6_hdr" "#include \"have.h\" " if test "x$ac_cv_type_struct_icmp6_hdr" = xyes; then : @@ -5857,7 +5498,7 @@ _ACEOF fi -ac_fn_c_check_type "$LINENO" "struct nd_neighbor_solicit" "ac_cv_type_struct_nd_neighbor_solicit" "#include \"$srcdir/src/have.h\" +ac_fn_c_check_type "$LINENO" "struct nd_neighbor_solicit" "ac_cv_type_struct_nd_neighbor_solicit" "#include \"have.h\" " if test "x$ac_cv_type_struct_nd_neighbor_solicit" = xyes; then : @@ -5868,7 +5509,7 @@ _ACEOF fi -ac_fn_c_check_type "$LINENO" "struct nd_opt_hdr" "ac_cv_type_struct_nd_opt_hdr" "#include \"$srcdir/src/have.h\" +ac_fn_c_check_type "$LINENO" "struct nd_opt_hdr" "ac_cv_type_struct_nd_opt_hdr" "#include \"have.h\" " if test "x$ac_cv_type_struct_nd_opt_hdr" = xyes; then : @@ -5914,7 +5555,7 @@ cat >>confdefs.h <<_ACEOF _ACEOF -for ac_func in asprintf daemon fchmod flock fork gettimeofday mlockall pselect putenv strsignal system unsetenv usleep vsyslog devname fdevname +for ac_func in asprintf daemon fchmod flock ftime fork get_current_dir_name gettimeofday mlockall putenv random select strdup strerror strsignal strtol system time usleep unsetenv vsyslog writev do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" @@ -5927,24 +5568,6 @@ fi done -ac_fn_c_check_func "$LINENO" "getopt_long" "ac_cv_func_getopt_long" -if test "x$ac_cv_func_getopt_long" = xyes; then : - getopt=true; -$as_echo "#define HAVE_GETOPT_LONG 1" >>confdefs.h - -else - getopt=false -fi - - if test "$getopt" = true; then - GETOPT_TRUE= - GETOPT_FALSE='#' -else - GETOPT_TRUE='#' - GETOPT_FALSE= -fi - - ac_fn_c_check_func "$LINENO" "socket" "ac_cv_func_socket" if test "x$ac_cv_func_socket" = xyes; then : @@ -6053,7 +5676,7 @@ fi fi -ac_fn_c_check_decl "$LINENO" "freeaddrinfo" "ac_cv_have_decl_freeaddrinfo" "#include \"$srcdir/src/have.h\" +ac_fn_c_check_decl "$LINENO" "freeaddrinfo" "ac_cv_have_decl_freeaddrinfo" "#include \"have.h\" " if test "x$ac_cv_have_decl_freeaddrinfo" = xyes; then : @@ -6065,7 +5688,7 @@ fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_FREEADDRINFO $ac_have_decl _ACEOF -ac_fn_c_check_decl "$LINENO" "gai_strerror" "ac_cv_have_decl_gai_strerror" "#include \"$srcdir/src/have.h\" +ac_fn_c_check_decl "$LINENO" "gai_strerror" "ac_cv_have_decl_gai_strerror" "#include \"have.h\" " if test "x$ac_cv_have_decl_gai_strerror" = xyes; then : @@ -6077,7 +5700,7 @@ fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_GAI_STRERROR $ac_have_decl _ACEOF -ac_fn_c_check_decl "$LINENO" "getaddrinfo" "ac_cv_have_decl_getaddrinfo" "#include \"$srcdir/src/have.h\" +ac_fn_c_check_decl "$LINENO" "getaddrinfo" "ac_cv_have_decl_getaddrinfo" "#include \"have.h\" " if test "x$ac_cv_have_decl_getaddrinfo" = xyes; then : @@ -6089,7 +5712,7 @@ fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_GETADDRINFO $ac_have_decl _ACEOF -ac_fn_c_check_decl "$LINENO" "getnameinfo" "ac_cv_have_decl_getnameinfo" "#include \"$srcdir/src/have.h\" +ac_fn_c_check_decl "$LINENO" "getnameinfo" "ac_cv_have_decl_getnameinfo" "#include \"have.h\" " if test "x$ac_cv_have_decl_getnameinfo" = xyes; then : @@ -6103,69 +5726,6 @@ cat >>confdefs.h <<_ACEOF _ACEOF -ac_fn_c_check_decl "$LINENO" "res_init" "ac_cv_have_decl_res_init" " - #include - #include - -" -if test "x$ac_cv_have_decl_res_init" = xyes; then : - ac_have_decl=1 -else - ac_have_decl=0 -fi - -cat >>confdefs.h <<_ACEOF -#define HAVE_DECL_RES_INIT $ac_have_decl -_ACEOF -if test $ac_have_decl = 1; then : - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for res_init in -lresolv" >&5 -$as_echo_n "checking for res_init in -lresolv... " >&6; } -if ${ac_cv_lib_resolv_res_init+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lresolv $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char res_init (); -int -main () -{ -return res_init (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_resolv_res_init=yes -else - ac_cv_lib_resolv_res_init=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_resolv_res_init" >&5 -$as_echo "$ac_cv_lib_resolv_res_init" >&6; } -if test "x$ac_cv_lib_resolv_res_init" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBRESOLV 1 -_ACEOF - - LIBS="-lresolv $LIBS" - -fi - -fi - - cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure @@ -6254,6 +5814,206 @@ rm -f confcache +# Check whether --with-libgcrypt was given. +if test "${with_libgcrypt+set}" = set; then : + withval=$with_libgcrypt; +fi + + + + # Check whether --enable-curses was given. +if test "${enable_curses+set}" = set; then : + enableval=$enable_curses; +fi + + if test "x$enable_curses" != "xno"; then : + + +$as_echo "#define HAVE_CURSES 1" >>confdefs.h + + curses=true + +# Check whether --with-curses was given. +if test "${with_curses+set}" = set; then : + withval=$with_curses; curses="$withval" + CPPFLAGS="$CPPFLAGS -I$withval/include" + LDFLAGS="$LDFLAGS -L$withval/lib" + +fi + + + +# Check whether --with-curses-include was given. +if test "${with_curses_include+set}" = set; then : + withval=$with_curses_include; curses_include="$withval" + CPPFLAGS="$CPPFLAGS -I$withval" + +fi + + + +# Check whether --with-curses-lib was given. +if test "${with_curses_lib+set}" = set; then : + withval=$with_curses_lib; curses_lib="$withval" + LDFLAGS="$LDFLAGS -L$withval" + +fi + + + for ac_header in curses.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "curses.h" "ac_cv_header_curses_h" "$ac_includes_default" +if test "x$ac_cv_header_curses_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_CURSES_H 1 +_ACEOF + +else + as_fn_error $? "\"curses header files not found.\"" "$LINENO" 5; break + +fi + +done + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for initscr in -lcurses" >&5 +$as_echo_n "checking for initscr in -lcurses... " >&6; } +if ${ac_cv_lib_curses_initscr+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lcurses $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char initscr (); +int +main () +{ +return initscr (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_curses_initscr=yes +else + ac_cv_lib_curses_initscr=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_curses_initscr" >&5 +$as_echo "$ac_cv_lib_curses_initscr" >&6; } +if test "x$ac_cv_lib_curses_initscr" = xyes; then : + CURSES_LIBS="-lcurses" +else + as_fn_error $? "\"curses libraries not found.\"" "$LINENO" 5 + +fi + + +fi + + + + + +# Check whether --with-libevent was given. +if test "${with_libevent+set}" = set; then : + withval=$with_libevent; libevent="$withval" + CPPFLAGS="$CPPFLAGS -I$withval/include" + LDFLAGS="$LDFLAGS -L$withval/lib" + +fi + + + +# Check whether --with-libevent-include was given. +if test "${with_libevent_include+set}" = set; then : + withval=$with_libevent_include; libevent_include="$withval" + CPPFLAGS="$CPPFLAGS -I$withval" + +fi + + + +# Check whether --with-libevent-lib was given. +if test "${with_libevent_lib+set}" = set; then : + withval=$with_libevent_lib; libevent_lib="$withval" + LDFLAGS="$LDFLAGS -L$withval" + +fi + + + for ac_header in event.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "event.h" "ac_cv_header_event_h" "$ac_includes_default" +if test "x$ac_cv_header_event_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_EVENT_H 1 +_ACEOF + +else + as_fn_error $? "\"libevent header files not found.\"" "$LINENO" 5; break + +fi + +done + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for event_init in -levent" >&5 +$as_echo_n "checking for event_init in -levent... " >&6; } +if ${ac_cv_lib_event_event_init+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-levent $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char event_init (); +int +main () +{ +return event_init (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_event_event_init=yes +else + ac_cv_lib_event_event_init=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_event_event_init" >&5 +$as_echo "$ac_cv_lib_event_event_init" >&6; } +if test "x$ac_cv_lib_event_event_init" = xyes; then : + LIBS="-levent $LIBS" +else + as_fn_error $? "\"libevent libraries not found.\"" "$LINENO" 5 + +fi + + + # Check whether --enable-zlib was given. if test "${enable_zlib+set}" = set; then : enableval=$enable_zlib; @@ -6532,6 +6292,225 @@ done fi +if test "$with_libgcrypt" = yes; then + +# Check whether --with-libgcrypt-prefix was given. +if test "${with_libgcrypt_prefix+set}" = set; then : + withval=$with_libgcrypt_prefix; libgcrypt_config_prefix="$withval" +else + libgcrypt_config_prefix="" +fi + + if test x$libgcrypt_config_prefix != x ; then + if test x${LIBGCRYPT_CONFIG+set} != xset ; then + LIBGCRYPT_CONFIG=$libgcrypt_config_prefix/bin/libgcrypt-config + fi + fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}libgcrypt-config", so it can be a program name with args. +set dummy ${ac_tool_prefix}libgcrypt-config; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_LIBGCRYPT_CONFIG+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $LIBGCRYPT_CONFIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_LIBGCRYPT_CONFIG="$LIBGCRYPT_CONFIG" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_LIBGCRYPT_CONFIG="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +LIBGCRYPT_CONFIG=$ac_cv_path_LIBGCRYPT_CONFIG +if test -n "$LIBGCRYPT_CONFIG"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIBGCRYPT_CONFIG" >&5 +$as_echo "$LIBGCRYPT_CONFIG" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_path_LIBGCRYPT_CONFIG"; then + ac_pt_LIBGCRYPT_CONFIG=$LIBGCRYPT_CONFIG + # Extract the first word of "libgcrypt-config", so it can be a program name with args. +set dummy libgcrypt-config; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_ac_pt_LIBGCRYPT_CONFIG+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $ac_pt_LIBGCRYPT_CONFIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_ac_pt_LIBGCRYPT_CONFIG="$ac_pt_LIBGCRYPT_CONFIG" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_ac_pt_LIBGCRYPT_CONFIG="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +ac_pt_LIBGCRYPT_CONFIG=$ac_cv_path_ac_pt_LIBGCRYPT_CONFIG +if test -n "$ac_pt_LIBGCRYPT_CONFIG"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_LIBGCRYPT_CONFIG" >&5 +$as_echo "$ac_pt_LIBGCRYPT_CONFIG" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_pt_LIBGCRYPT_CONFIG" = x; then + LIBGCRYPT_CONFIG="no" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + LIBGCRYPT_CONFIG=$ac_pt_LIBGCRYPT_CONFIG + fi +else + LIBGCRYPT_CONFIG="$ac_cv_path_LIBGCRYPT_CONFIG" +fi + + tmp=1.4.0 + if echo "$tmp" | grep ':' >/dev/null 2>/dev/null ; then + req_libgcrypt_api=`echo "$tmp" | sed 's/\(.*\):\(.*\)/\1/'` + min_libgcrypt_version=`echo "$tmp" | sed 's/\(.*\):\(.*\)/\2/'` + else + req_libgcrypt_api=0 + min_libgcrypt_version="$tmp" + fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for LIBGCRYPT - version >= $min_libgcrypt_version" >&5 +$as_echo_n "checking for LIBGCRYPT - version >= $min_libgcrypt_version... " >&6; } + ok=no + if test "$LIBGCRYPT_CONFIG" != "no" ; then + req_major=`echo $min_libgcrypt_version | \ + sed 's/\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\)/\1/'` + req_minor=`echo $min_libgcrypt_version | \ + sed 's/\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\)/\2/'` + req_micro=`echo $min_libgcrypt_version | \ + sed 's/\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\)/\3/'` + libgcrypt_config_version=`$LIBGCRYPT_CONFIG --version` + major=`echo $libgcrypt_config_version | \ + sed 's/\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\).*/\1/'` + minor=`echo $libgcrypt_config_version | \ + sed 's/\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\).*/\2/'` + micro=`echo $libgcrypt_config_version | \ + sed 's/\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\).*/\3/'` + if test "$major" -gt "$req_major"; then + ok=yes + else + if test "$major" -eq "$req_major"; then + if test "$minor" -gt "$req_minor"; then + ok=yes + else + if test "$minor" -eq "$req_minor"; then + if test "$micro" -ge "$req_micro"; then + ok=yes + fi + fi + fi + fi + fi + fi + if test $ok = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes ($libgcrypt_config_version)" >&5 +$as_echo "yes ($libgcrypt_config_version)" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + fi + if test $ok = yes; then + # If we have a recent libgcrypt, we should also check that the + # API is compatible + if test "$req_libgcrypt_api" -gt 0 ; then + tmp=`$LIBGCRYPT_CONFIG --api-version 2>/dev/null || echo 0` + if test "$tmp" -gt 0 ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking LIBGCRYPT API version" >&5 +$as_echo_n "checking LIBGCRYPT API version... " >&6; } + if test "$req_libgcrypt_api" -eq "$tmp" ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: okay" >&5 +$as_echo "okay" >&6; } + else + ok=no + { $as_echo "$as_me:${as_lineno-$LINENO}: result: does not match. want=$req_libgcrypt_api got=$tmp" >&5 +$as_echo "does not match. want=$req_libgcrypt_api got=$tmp" >&6; } + fi + fi + fi + fi + if test $ok = yes; then + LIBGCRYPT_CFLAGS=`$LIBGCRYPT_CONFIG --cflags` + LIBGCRYPT_LIBS=`$LIBGCRYPT_CONFIG --libs` + : + if test x"$host" != x ; then + libgcrypt_config_host=`$LIBGCRYPT_CONFIG --host 2>/dev/null || echo none` + if test x"$libgcrypt_config_host" != xnone ; then + if test x"$libgcrypt_config_host" != x"$host" ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: +*** +*** The config script $LIBGCRYPT_CONFIG was +*** built for $libgcrypt_config_host and thus may not match the +*** used host $host. +*** You may want to use the configure option --with-libgcrypt-prefix +*** to specify a matching config script. +***" >&5 +$as_echo "$as_me: WARNING: +*** +*** The config script $LIBGCRYPT_CONFIG was +*** built for $libgcrypt_config_host and thus may not match the +*** used host $host. +*** You may want to use the configure option --with-libgcrypt-prefix +*** to specify a matching config script. +***" >&2;} + fi + fi + fi + else + LIBGCRYPT_CFLAGS="" + LIBGCRYPT_LIBS="" + : + fi + + + + ln -sf gcrypt/cipher.c gcrypt/cipher.h gcrypt/crypto.c gcrypt/crypto.h gcrypt/digest.c gcrypt/digest.h gcrypt/ecdh.c gcrypt/ecdh.h gcrypt/ecdsa.c gcrypt/ecdsa.h gcrypt/ecdsagen.c gcrypt/ecdsagen.h gcrypt/prf.c gcrypt/prf.h gcrypt/rsa.c gcrypt/rsa.h gcrypt/rsagen.c gcrypt/rsagen.h src/ +else + case $host_os in *mingw*) ;; @@ -6579,7 +6558,7 @@ $as_echo "$ac_cv_lib_dl_dlopen" >&6; } if test "x$ac_cv_lib_dl_dlopen" = xyes; then : LIBS="$LIBS -ldl" else - as_fn_error $? "LibreSSL/OpenSSL depends on libdl." "$LINENO" 5; break + as_fn_error $? "OpenSSL depends on libdl." "$LINENO" 5; break fi @@ -6627,7 +6606,7 @@ if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : _ACEOF else - as_fn_error $? "LibreSSL/OpenSSL header files not found." "$LINENO" 5; break + as_fn_error $? "OpenSSL header files not found." "$LINENO" 5; break fi @@ -6673,12 +6652,12 @@ $as_echo "$ac_cv_lib_crypto_EVP_EncryptInit_ex" >&6; } if test "x$ac_cv_lib_crypto_EVP_EncryptInit_ex" = xyes; then : LIBS="-lcrypto $LIBS" else - as_fn_error $? "LibreSSL/OpenSSL libraries not found." "$LINENO" 5 + as_fn_error $? "OpenSSL libraries not found." "$LINENO" 5 fi - for ac_func in RAND_bytes EVP_EncryptInit_ex EVP_CIPHER_CTX_new + for ac_func in RAND_pseudo_bytes EVP_EncryptInit_ex do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" @@ -6688,7 +6667,7 @@ if eval test \"x\$"$as_ac_var"\" = x"yes"; then : _ACEOF else - as_fn_error $? "Missing LibreSSL/OpenSSL functionality, make sure you have installed the latest version." "$LINENO" 5; break + as_fn_error $? "Missing OpenSSL functionality, make sure you have installed the latest version." "$LINENO" 5; break fi done @@ -6697,70 +6676,28 @@ done " if test "x$ac_cv_have_decl_OpenSSL_add_all_algorithms" = xyes; then : - ac_have_decl=1 -else - ac_have_decl=0 -fi - -cat >>confdefs.h <<_ACEOF -#define HAVE_DECL_OPENSSL_ADD_ALL_ALGORITHMS $ac_have_decl -_ACEOF -if test $ac_have_decl = 1; then : else - as_fn_error $? "Missing LibreSSL/OpenSSL functionality, make sure you have installed the latest version." "$LINENO" 5; break -fi -ac_fn_c_check_decl "$LINENO" "EVP_aes_256_cfb" "ac_cv_have_decl_EVP_aes_256_cfb" "#include - -" -if test "x$ac_cv_have_decl_EVP_aes_256_cfb" = xyes; then : - ac_have_decl=1 -else - ac_have_decl=0 -fi - -cat >>confdefs.h <<_ACEOF -#define HAVE_DECL_EVP_AES_256_CFB $ac_have_decl -_ACEOF -if test $ac_have_decl = 1; then : - -else - as_fn_error $? "Missing LibreSSL/OpenSSL functionality, make sure you have installed the latest version." "$LINENO" 5; break + as_fn_error $? "Missing OpenSSL functionality, make sure you have installed the latest version." "$LINENO" 5; break fi - for ac_func in BN_GENCB_new RSA_set0_key -do : - as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` -ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" -if eval test \"x\$"$as_ac_var"\" = x"yes"; then : - cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 -_ACEOF - + ln -sf openssl/cipher.c openssl/cipher.h openssl/crypto.c openssl/crypto.h openssl/digest.c openssl/digest.h openssl/ecdh.c openssl/ecdh.h openssl/ecdsa.c openssl/ecdsa.h openssl/ecdsagen.c openssl/ecdsagen.h openssl/prf.c openssl/prf.h openssl/rsa.c openssl/rsa.h openssl/rsagen.c openssl/rsagen.h src/ fi -done - # Check whether --enable-jumbograms was given. if test "${enable_jumbograms+set}" = set; then : - enableval=$enable_jumbograms; if test "x$enable_jumbograms" = "xyes"; then : - + enableval=$enable_jumbograms; $as_echo "#define ENABLE_JUMBOGRAMS 1" >>confdefs.h -fi - fi -if test "x$runstatedir" = "x"; then - runstatedir='${localstatedir}/run' -fi -ac_config_files="$ac_config_files Makefile src/Makefile doc/Makefile systemd/Makefile" +ac_config_files="$ac_config_files Makefile src/Makefile doc/Makefile m4/Makefile gui/Makefile" cat >confcache <<\_ACEOF @@ -6872,22 +6809,6 @@ LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5 -$as_echo_n "checking that generated files are newer than configure... " >&6; } - if test -n "$am_sleep_pid"; then - # Hide warnings about reused PIDs. - wait $am_sleep_pid 2>/dev/null - fi - { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5 -$as_echo "done" >&6; } - if test -n "$EXEEXT"; then - am__EXEEXT_TRUE= - am__EXEEXT_FALSE='#' -else - am__EXEEXT_TRUE='#' - am__EXEEXT_FALSE= -fi - if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then as_fn_error $? "conditional \"AMDEP\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 @@ -6896,46 +6817,22 @@ if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then as_fn_error $? "conditional \"am__fastdepCC\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi -if test -z "${LINUX_TRUE}" && test -z "${LINUX_FALSE}"; then - as_fn_error $? "conditional \"LINUX\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 + if test -n "$EXEEXT"; then + am__EXEEXT_TRUE= + am__EXEEXT_FALSE='#' +else + am__EXEEXT_TRUE='#' + am__EXEEXT_FALSE= fi -if test -z "${BSD_TRUE}" && test -z "${BSD_FALSE}"; then - as_fn_error $? "conditional \"BSD\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${SOLARIS_TRUE}" && test -z "${SOLARIS_FALSE}"; then - as_fn_error $? "conditional \"SOLARIS\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${MINGW_TRUE}" && test -z "${MINGW_FALSE}"; then - as_fn_error $? "conditional \"MINGW\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${CYGWIN_TRUE}" && test -z "${CYGWIN_FALSE}"; then - as_fn_error $? "conditional \"CYGWIN\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${UML_TRUE}" && test -z "${UML_FALSE}"; then - as_fn_error $? "conditional \"UML\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${VDE_TRUE}" && test -z "${VDE_FALSE}"; then - as_fn_error $? "conditional \"VDE\" was never defined. + +if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then + as_fn_error $? "conditional \"MAINTAINER_MODE\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${TUNEMU_TRUE}" && test -z "${TUNEMU_FALSE}"; then as_fn_error $? "conditional \"TUNEMU\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi -if test -z "${WITH_SYSTEMD_TRUE}" && test -z "${WITH_SYSTEMD_FALSE}"; then - as_fn_error $? "conditional \"WITH_SYSTEMD\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${GETOPT_TRUE}" && test -z "${GETOPT_FALSE}"; then - as_fn_error $? "conditional \"GETOPT\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi : "${CONFIG_STATUS=./config.status}" ac_write_fail=0 @@ -7234,16 +7131,16 @@ if (echo >conf$$.file) 2>/dev/null; then # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. - # In both cases, we have to default to `cp -pR'. + # In both cases, we have to default to `cp -p'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || - as_ln_s='cp -pR' + as_ln_s='cp -p' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else - as_ln_s='cp -pR' + as_ln_s='cp -p' fi else - as_ln_s='cp -pR' + as_ln_s='cp -p' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null @@ -7303,16 +7200,28 @@ else as_mkdir_p=false fi - -# as_fn_executable_p FILE -# ----------------------- -# Test if FILE is an executable regular file. -as_fn_executable_p () -{ - test -f "$1" && test -x "$1" -} # as_fn_executable_p -as_test_x='test -x' -as_executable_p=as_fn_executable_p +if test -x / >/dev/null 2>&1; then + as_test_x='test -x' +else + if ls -dL / >/dev/null 2>&1; then + as_ls_L_option=L + else + as_ls_L_option= + fi + as_test_x=' + eval sh -c '\'' + if test -d "$1"; then + test -d "$1/."; + else + case $1 in #( + -*)set "./$1";; + esac; + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( + ???[sx]*):;;*)false;;esac;fi + '\'' sh + ' +fi +as_executable_p=$as_test_x # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" @@ -7333,8 +7242,8 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by tinc $as_me 1.0.35, which was -generated by GNU Autoconf 2.69. Invocation command line was +This file was extended by $as_me, which was +generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS @@ -7399,11 +7308,11 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -tinc config.status 1.0.35 -configured by $0, generated by GNU Autoconf 2.69, +config.status +configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" -Copyright (C) 2012 Free Software Foundation, Inc. +Copyright (C) 2010 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." @@ -7494,7 +7403,7 @@ fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 if \$ac_cs_recheck; then - set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion + set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion shift \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 CONFIG_SHELL='$SHELL' @@ -7518,7 +7427,7 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # # INIT-COMMANDS # -AMDEP_TRUE="$AMDEP_TRUE" MAKE="${MAKE-make}" +AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" _ACEOF @@ -7528,12 +7437,13 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 for ac_config_target in $ac_config_targets do case $ac_config_target in - "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; + "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; "src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;; "doc/Makefile") CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;; - "systemd/Makefile") CONFIG_FILES="$CONFIG_FILES systemd/Makefile" ;; + "m4/Makefile") CONFIG_FILES="$CONFIG_FILES m4/Makefile" ;; + "gui/Makefile") CONFIG_FILES="$CONFIG_FILES gui/Makefile" ;; *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; esac @@ -8130,38 +8040,32 @@ $as_echo "$as_me: executing $ac_file commands" >&6;} case $ac_file$ac_mode in "depfiles":C) test x"$AMDEP_TRUE" != x"" || { - # Older Autoconf quotes --file arguments for eval, but not when files + # Autoconf 2.62 quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. - # TODO: see whether this extra hack can be removed once we start - # requiring Autoconf 2.70 or later. - case $CONFIG_FILES in #( - *\'*) : - eval set x "$CONFIG_FILES" ;; #( - *) : - set x $CONFIG_FILES ;; #( - *) : - ;; -esac + case $CONFIG_FILES in + *\'*) eval set x "$CONFIG_FILES" ;; + *) set x $CONFIG_FILES ;; + esac shift - # Used to flag and report bootstrapping failures. - am_rc=0 - for am_mf + for mf do # Strip MF so we end up with the name of the file. - am_mf=`$as_echo "$am_mf" | sed -e 's/:.*$//'` - # Check whether this is an Automake generated Makefile which includes - # dependency-tracking related rules and includes. - # Grep'ing the whole file directly is not great: AIX grep has a line + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named `Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # Grep'ing the whole file is not good either: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. - sed -n 's,^am--depfiles:.*,X,p' "$am_mf" | grep X >/dev/null 2>&1 \ - || continue - am_dirpart=`$as_dirname -- "$am_mf" || -$as_expr X"$am_mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$am_mf" : 'X\(//\)[^/]' \| \ - X"$am_mf" : 'X\(//\)$' \| \ - X"$am_mf" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$am_mf" | + if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then + dirpart=`$as_dirname -- "$mf" || +$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$mf" : 'X\(//\)[^/]' \| \ + X"$mf" : 'X\(//\)$' \| \ + X"$mf" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$mf" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q @@ -8179,48 +8083,55 @@ $as_echo X"$am_mf" | q } s/.*/./; q'` - am_filepart=`$as_basename -- "$am_mf" || -$as_expr X/"$am_mf" : '.*/\([^/][^/]*\)/*$' \| \ - X"$am_mf" : 'X\(//\)$' \| \ - X"$am_mf" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X/"$am_mf" | - sed '/^.*\/\([^/][^/]*\)\/*$/{ + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running `make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # When using ansi2knr, U may be empty or an underscore; expand it + U=`sed -n 's/^U = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`$as_dirname -- "$file" || +$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$file" : 'X\(//\)[^/]' \| \ + X"$file" : 'X\(//\)$' \| \ + X"$file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } - /^X\/\(\/\/\)$/{ + /^X\(\/\/\)[^/].*/{ s//\1/ q } - /^X\/\(\/\).*/{ + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` - { echo "$as_me:$LINENO: cd "$am_dirpart" \ - && sed -e '/# am--include-marker/d' "$am_filepart" \ - | $MAKE -f - am--depfiles" >&5 - (cd "$am_dirpart" \ - && sed -e '/# am--include-marker/d' "$am_filepart" \ - | $MAKE -f - am--depfiles) >&5 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } || am_rc=$? + as_dir=$dirpart/$fdir; as_fn_mkdir_p + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done done - if test $am_rc -ne 0; then - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "Something went wrong bootstrapping makefile fragments - for automatic dependency tracking. Try re-running configure with the - '--disable-dependency-tracking' option to at least be able to build - the package (albeit without support for automatic dependency tracking). -See \`config.log' for more details" "$LINENO" 5; } - fi - { am_dirpart=; unset am_dirpart;} - { am_filepart=; unset am_filepart;} - { am_mf=; unset am_mf;} - { am_rc=; unset am_rc;} - rm -f conftest-deps.mk } ;; diff --git a/configure.ac b/configure.ac deleted file mode 100644 index 6de0313..0000000 --- a/configure.ac +++ /dev/null @@ -1,247 +0,0 @@ -dnl Process this file with autoconf to produce a configure script. - -AC_PREREQ(2.61) -AC_INIT([tinc], [1.0.35]) -AC_CONFIG_SRCDIR([src/tincd.c]) -AM_INIT_AUTOMAKE([1.11 check-news std-options subdir-objects nostdinc silent-rules -Wall]) -AC_CONFIG_HEADERS([config.h]) -AC_CONFIG_MACRO_DIR([m4]) -AM_SILENT_RULES([yes]) - -# Enable GNU extensions. -# Define this here, not in acconfig's @TOP@ section, since definitions -# in the latter don't make it into the configure-time tests. -AC_GNU_SOURCE -AC_DEFINE([__USE_BSD], 1, [Enable BSD extensions]) - -dnl Checks for programs. -AC_PROG_CC_C99 -AC_PROG_CPP -AC_PROG_INSTALL - -AM_PROG_CC_C_O - -dnl Check and set OS - -AC_CANONICAL_HOST - -case $host_os in - *linux*) - linux=true - AC_DEFINE(HAVE_LINUX, 1, [Linux]) - ;; - *freebsd*) - bsd=true - AC_DEFINE(HAVE_FREEBSD, 1, [FreeBSD]) - ;; - *darwin*) - bsd=true - AC_DEFINE(HAVE_DARWIN, 1, [Darwin (MacOS/X)]) - ;; - *solaris*) - solaris=true - AC_DEFINE(HAVE_SOLARIS, 1, [Solaris/SunOS]) - ;; - *openbsd*) - bsd=true - AC_DEFINE(HAVE_OPENBSD, 1, [OpenBSD]) - ;; - *netbsd*) - bsd=true - AC_DEFINE(HAVE_NETBSD, 1, [NetBSD]) - ;; - *dragonfly*) - bsd=true - AC_DEFINE(HAVE_DRAGONFLY, 1, [DragonFly]) - ;; - *bsd*) - bsd=true - AC_MSG_WARN("Unknown BSD variant, tinc might not compile or work!") - AC_DEFINE(HAVE_BSD, 1, [Unknown BSD variant]) - ;; - *cygwin*) - cygwin=true - AC_DEFINE(HAVE_CYGWIN, 1, [Cygwin]) - ;; - *mingw*) - mingw=true - AC_DEFINE(HAVE_MINGW, 1, [MinGW]) - LIBS="$LIBS -lws2_32 -lgdi32 -lcrypt32" - ;; - *) - AC_MSG_ERROR("Unknown operating system.") - ;; -esac - -AC_ARG_ENABLE(uml, - AS_HELP_STRING([--enable-uml], [enable support for User Mode Linux]), - [ AS_IF([test "x$enable_uml" = "xyes"], - [ AC_DEFINE(ENABLE_UML, 1, [Support for UML]) - uml=true - ], - [uml=false]) - ], - [uml=false] -) - -AC_ARG_ENABLE(vde, - AS_HELP_STRING([--enable-vde], [enable support for Virtual Distributed Ethernet]), - [ AS_IF([test "x$enable_vde" = "xyes"], - [ AC_CHECK_HEADERS(libvdeplug_dyn.h, [], [AC_MSG_ERROR([VDE plug header files not found.]); break]) - AC_DEFINE(ENABLE_VDE, 1, [Support for VDE]) - vde=true - ], - [vde=false]) - ], - [vde=false] -) - -AC_ARG_ENABLE(tunemu, - AS_HELP_STRING([--enable-tunemu], [enable support for the tunemu driver]), - [ AS_IF([test "x$enable_tunemu" = "xyes"], - [ AC_DEFINE(ENABLE_TUNEMU, 1, [Support for tunemu]) - tunemu=true - ], - [tunemu=false]) - ], - [tunemu=false] -) - -AC_ARG_WITH(windows2000, - AS_HELP_STRING([--with-windows2000], [compile with support for Windows 2000. This disables support for tunneling over existing IPv6 networks.]), - [ AS_IF([test "x$with_windows2000" = "xyes"], - [AC_DEFINE(WITH_WINDOWS2000, 1, [Compile with support for Windows 2000])]) - ] -) - -AC_ARG_WITH(systemd, - AS_HELP_STRING([--with-systemd@<:@=DIR@:>@], [install systemd service files @<:@to DIR if specified@:>@]), - [ systemd=true; systemd_path="$with_systemd" ], - [ systemd=false ] -) - -AS_IF([test "x$with_systemd" = "xyes"], [systemd_path="\${libdir}/systemd/system"], - [AS_IF([test "x$with_systemd" = "xno"], [systemd=false])]) - -AC_SUBST(systemd_path, $systemd_path) - -AM_CONDITIONAL(LINUX, test "$linux" = true) -AM_CONDITIONAL(BSD, test "$bsd" = true) -AM_CONDITIONAL(SOLARIS, test "$solaris" = true) -AM_CONDITIONAL(MINGW, test "$mingw" = true) -AM_CONDITIONAL(CYGWIN, test "$cygwin" = true) -AM_CONDITIONAL(UML, test "$uml" = true) -AM_CONDITIONAL(VDE, test "$vde" = true) -AM_CONDITIONAL(TUNEMU, test "$tunemu" = true) -AM_CONDITIONAL(WITH_SYSTEMD, test "$systemd" = true) - -AC_CACHE_SAVE - -if test -d /sw/include ; then - CPPFLAGS="$CPPFLAGS -I/sw/include" -fi -if test -d /sw/lib ; then - LIBS="$LIBS -L/sw/lib" -fi - -dnl Compiler hardening flags -dnl No -fstack-protector-all because it doesn't work on all platforms or architectures. - -AX_CFLAGS_WARN_ALL(CFLAGS) - -AC_ARG_ENABLE([hardening], AS_HELP_STRING([--disable-hardening], [disable compiler and linker hardening flags])) -AS_IF([test "x$enable_hardening" != "xno"], - [AX_CHECK_COMPILE_FLAG([-DFORTIFY_SOURCE=2], [CPPFLAGS="$CPPFLAGS -DFORTIFY_SOURCE=2"]) - AX_CHECK_COMPILE_FLAG([-fwrapv], [CPPFLAGS="$CPPFLAGS -fwrapv"], - AX_CHECK_COMPILE_FLAG([-fno-strict-overflow], [CPPFLAGS="$CPPFLAGS -fno-strict-overflow"])) - case $host_os in - *mingw*) - AX_CHECK_LINK_FLAG([-Wl,--dynamicbase], [LDFLAGS="$LDFLAGS -Wl,--dynamicbase"]) - AX_CHECK_LINK_FLAG([-Wl,--nxcompat], [LDFLAGS="$LDFLAGS -Wl,--nxcompat"]) - ;; - *) - AX_CHECK_COMPILE_FLAG([-fPIE], [CPPFLAGS="$CPPFLAGS -fPIE"]) - AX_CHECK_LINK_FLAG([-pie], [LDFLAGS="$LDFLAGS -pie"]) - ;; - esac - AX_CHECK_LINK_FLAG([-Wl,-z,relro], [LDFLAGS="$LDFLAGS -Wl,-z,relro"]) - AX_CHECK_LINK_FLAG([-Wl,-z,now], [LDFLAGS="$LDFLAGS -Wl,-z,now"]) - ] -); - -dnl Checks for libraries. - -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_CHECK_HEADERS([syslog.h sys/file.h sys/ioctl.h sys/mman.h sys/param.h sys/resource.h sys/socket.h sys/time.h sys/uio.h sys/wait.h netdb.h arpa/inet.h arpa/nameser.h dirent.h getopt.h]) -AC_CHECK_HEADERS([net/if.h net/if_types.h linux/if_tun.h net/if_tun.h net/if_utun.h net/tun/if_tun.h net/if_tap.h net/tap/if_tap.h net/ethernet.h net/if_arp.h netinet/in_systm.h netinet/in.h netinet/in6.h netpacket/packet.h], - [], [], [#include "$srcdir/src/have.h"] -) -AC_CHECK_HEADERS([netinet/if_ether.h netinet/ip.h netinet/ip6.h resolv.h], - [], [], [#include "$srcdir/src/have.h"] -) -AC_CHECK_HEADERS([netinet/tcp.h netinet/ip_icmp.h netinet/icmp6.h], - [], [], [#include "$srcdir/src/have.h"] -) - -dnl Checks for typedefs, structures, and compiler characteristics. -AC_TYPE_PID_T - -tinc_ATTRIBUTE(__malloc__) - -AC_CHECK_TYPES([socklen_t, struct ether_header, struct arphdr, struct ether_arp, struct in_addr, struct addrinfo, struct ip, struct icmp, struct in6_addr, struct sockaddr_in6, struct ip6_hdr, struct icmp6_hdr, struct nd_neighbor_solicit, struct nd_opt_hdr], , , - [#include "$srcdir/src/have.h"] -) - -dnl Checks for library functions. -AC_TYPE_SIGNAL -AC_CHECK_FUNCS([asprintf daemon fchmod flock fork gettimeofday mlockall pselect putenv strsignal system unsetenv usleep vsyslog devname fdevname], - [], [], [#include "$srcdir/src/have.h"] -) - -AC_CHECK_FUNC(getopt_long, [getopt=true; AC_DEFINE(HAVE_GETOPT_LONG, 1, [getopt_long()])], [getopt=false]) -AM_CONDITIONAL(GETOPT, test "$getopt" = true) - -dnl Support for SunOS - -AC_CHECK_FUNC(socket, [], [ - AC_CHECK_LIB(socket, connect) -]) -AC_CHECK_FUNC(gethostbyname, [], [ - AC_CHECK_LIB(nsl, gethostbyname) -]) - -AC_CHECK_DECLS([freeaddrinfo, gai_strerror, getaddrinfo, getnameinfo], - [], [], [#include "$srcdir/src/have.h"] -) - -AC_CHECK_DECLS([res_init], [AC_CHECK_LIB(resolv, res_init)], [], [ - #include - #include -]) - -AC_CACHE_SAVE - -dnl These are defined in files in m4/ - -tinc_ZLIB -tinc_LZO -tinc_OPENSSL - -dnl Check if support for jumbograms is requested -AC_ARG_ENABLE(jumbograms, - AS_HELP_STRING([--enable-jumbograms], [enable support for jumbograms (packets up to 9000 bytes)]), - [ AS_IF([test "x$enable_jumbograms" = "xyes"], - [ AC_DEFINE(ENABLE_JUMBOGRAMS, 1, [Support for jumbograms (packets up to 9000 bytes)]) ]) - ] -) - -dnl Ensure runstatedir is set if we are using a version of autoconf that does not suppport it -if test "x$runstatedir" = "x"; then - AC_SUBST([runstatedir], ['${localstatedir}/run']) -fi - -AC_CONFIG_FILES([Makefile src/Makefile doc/Makefile systemd/Makefile]) - -AC_OUTPUT diff --git a/configure.in b/configure.in new file mode 100644 index 0000000..2e519b0 --- /dev/null +++ b/configure.in @@ -0,0 +1,177 @@ +dnl Process this file with autoconf to produce a configure script. + +AC_PREREQ(2.61) +AC_INIT +AC_CONFIG_SRCDIR([src/tincd.c]) +AC_GNU_SOURCE +AM_INIT_AUTOMAKE(tinc, 1.1pre2) +AC_CONFIG_HEADERS([config.h]) +AM_MAINTAINER_MODE + +# Enable GNU extensions. +# Define this here, not in acconfig's @TOP@ section, since definitions +# in the latter don't make it into the configure-time tests. +AC_GNU_SOURCE +AC_DEFINE([__USE_BSD], 1, [Enable BSD extensions]) + +dnl Checks for programs. +AC_PROG_CC_C99 +AC_PROG_CPP +AC_PROG_INSTALL +AC_PROG_LN_S +AC_PROG_RANLIB + +dnl Check and set OS + +AC_CANONICAL_HOST + +case $host_os in + *linux*) + AC_DEFINE(HAVE_LINUX, 1, [Linux]) + [ rm -f src/device.c; ln -sf linux/device.c src/device.c ] + ;; + *freebsd*) + AC_DEFINE(HAVE_FREEBSD, 1, [FreeBSD]) + [ rm -f src/device.c; ln -sf bsd/device.c src/device.c ] + ;; + *darwin*) + AC_DEFINE(HAVE_DARWIN, 1, [Darwin (MacOS/X)]) + [ rm -f src/device.c; ln -sf bsd/device.c src/device.c ] + ;; + *solaris*) + AC_DEFINE(HAVE_SOLARIS, 1, [Solaris/SunOS]) + [ rm -f src/device.c; ln -sf solaris/device.c src/device.c ] + ;; + *openbsd*) + AC_DEFINE(HAVE_OPENBSD, 1, [OpenBSD]) + [ rm -f src/device.c; ln -sf bsd/device.c src/device.c ] + ;; + *netbsd*) + AC_DEFINE(HAVE_NETBSD, 1, [NetBSD]) + [ rm -f src/device.c; ln -sf bsd/device.c src/device.c ] + ;; + *dragonfly*) + AC_DEFINE(HAVE_DRAGONFLY, 1, [DragonFly]) + [ rm -f src/device.c; ln -sf bsd/device.c src/device.c ] + ;; + *bsd*) + AC_MSG_WARN("Unknown BSD variant, tinc might not compile or work!") + AC_DEFINE(HAVE_BSD, 1, [Unknown BSD variant]) + [ rm -f src/device.c; ln -sf bsd/device.c src/device.c ] + ;; + *cygwin*) + AC_DEFINE(HAVE_CYGWIN, 1, [Cygwin]) + [ rm -f src/device.c; ln -sf cygwin/device.c src/device.c ] + ;; + *mingw*) + AC_DEFINE(HAVE_MINGW, 1, [MinGW]) + [ rm -f src/device.c; cp -f src/mingw/device.c src/device.c ] + LIBS="$LIBS -lws2_32 -lgdi32 -lcrypt32" + ;; + *) + AC_MSG_ERROR("Unknown operating system.") + ;; +esac + +AC_ARG_ENABLE(tunemu, + AS_HELP_STRING([--enable-tunemu], [enable support for the tunemu driver]), + [ AC_DEFINE(ENABLE_TUNEMU, 1, [Support for tunemu]) + tunemu=true + ] +) + +AC_ARG_WITH(windows2000, + AS_HELP_STRING([--with-windows2000], [compile with support for Windows 2000. This disables support for tunneling over existing IPv6 networks.]), + [AC_DEFINE(WITH_WINDOWS2000, 1, [Compile with support for Windows 2000])] +) + +AM_CONDITIONAL(TUNEMU, test "$tunemu" = true) + +AC_CACHE_SAVE + +if test -d /sw/include ; then + CPPFLAGS="$CPPFLAGS -I/sw/include" +fi +if test -d /sw/lib ; then + LIBS="$LIBS -L/sw/lib" +fi + +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/resource.h sys/socket.h sys/time.h sys/uio.h sys/un.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/tun/if_tun.h net/if_tap.h net/tap/if_tap.h net/ethernet.h net/if_arp.h netinet/in_systm.h netinet/in.h netinet/in6.h time.h], + [], [], [#include "have.h"] +) +AC_CHECK_HEADERS([netinet/if_ether.h netinet/ip.h netinet/ip6.h], + [], [], [#include "have.h"] +) +AC_CHECK_HEADERS([netinet/tcp.h netinet/ip_icmp.h netinet/icmp6.h], + [], [], [#include "have.h"] +) + +dnl Checks for typedefs, structures, and compiler characteristics. +AC_C_CONST +AC_C_VOLATILE +AC_TYPE_PID_T +AC_TYPE_SIZE_T +AC_HEADER_TIME +AC_STRUCT_TM + +tinc_ATTRIBUTE(__malloc__) + +AC_CHECK_TYPES([socklen_t, struct ether_header, struct arphdr, struct ether_arp, struct in_addr, struct addrinfo, struct ip, struct icmp, struct in6_addr, struct sockaddr_in6, struct ip6_hdr, struct icmp6_hdr, struct nd_neighbor_solicit, struct nd_opt_hdr], , , + [#include "have.h"] +) + +dnl Checks for library functions. +AC_TYPE_SIGNAL +AC_CHECK_FUNCS([asprintf daemon fchmod flock ftime fork get_current_dir_name gettimeofday mlockall putenv random select strdup strerror strsignal strtol system time usleep unsetenv vsyslog writev], + [], [], [#include "have.h"] +) + +dnl Support for SunOS + +AC_CHECK_FUNC(socket, [], [ + AC_CHECK_LIB(socket, connect) +]) +AC_CHECK_FUNC(gethostbyname, [], [ + AC_CHECK_LIB(nsl, gethostbyname) +]) + +AC_CHECK_DECLS([freeaddrinfo, gai_strerror, getaddrinfo, getnameinfo], + [], [], [#include "have.h"] +) + +AC_CACHE_SAVE + +dnl These are defined in files in m4/ + +AC_ARG_WITH(libgcrypt, AC_HELP_STRING([--with-libgcrypt], [enable use of libgcrypt instead of OpenSSL])], []) + +tinc_CURSES +tinc_LIBEVENT +tinc_ZLIB +tinc_LZO + +if test "$with_libgcrypt" = yes; then + AM_PATH_LIBGCRYPT([1.4.0], [], []) + ln -sf gcrypt/cipher.c gcrypt/cipher.h gcrypt/crypto.c gcrypt/crypto.h gcrypt/digest.c gcrypt/digest.h gcrypt/ecdh.c gcrypt/ecdh.h gcrypt/ecdsa.c gcrypt/ecdsa.h gcrypt/ecdsagen.c gcrypt/ecdsagen.h gcrypt/prf.c gcrypt/prf.h gcrypt/rsa.c gcrypt/rsa.h gcrypt/rsagen.c gcrypt/rsagen.h src/ +else + tinc_OPENSSL + ln -sf openssl/cipher.c openssl/cipher.h openssl/crypto.c openssl/crypto.h openssl/digest.c openssl/digest.h openssl/ecdh.c openssl/ecdh.h openssl/ecdsa.c openssl/ecdsa.h openssl/ecdsagen.c openssl/ecdsagen.h openssl/prf.c openssl/prf.h openssl/rsa.c openssl/rsa.h openssl/rsagen.c openssl/rsagen.h src/ +fi + + +dnl Check if support for jumbograms is requested +AC_ARG_ENABLE(jumbograms, + AS_HELP_STRING([--enable-jumbograms], [enable support for jumbograms (packets up to 9000 bytes)]), + [ AC_DEFINE(ENABLE_JUMBOGRAMS, 1, [Support for jumbograms (packets up to 9000 bytes)]) ] +) + +AC_SUBST(INCLUDES) + +AC_CONFIG_FILES([Makefile src/Makefile doc/Makefile m4/Makefile gui/Makefile]) + +AC_OUTPUT diff --git a/depcomp b/depcomp index 65cbf70..df8eea7 100755 --- a/depcomp +++ b/depcomp @@ -1,9 +1,10 @@ #! /bin/sh # depcomp - compile a program generating dependencies as side-effects -scriptversion=2018-03-07.03; # UTC +scriptversion=2009-04-28.21; # UTC -# Copyright (C) 1999-2018 Free Software Foundation, Inc. +# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006, 2007, 2009 Free +# Software Foundation, Inc. # 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 @@ -16,7 +17,7 @@ scriptversion=2018-03-07.03; # UTC # GNU General Public License for more details. # You should have received a copy of the GNU General Public License -# along with this program. If not, see . +# along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a @@ -27,9 +28,9 @@ scriptversion=2018-03-07.03; # UTC case $1 in '') - echo "$0: No command. Try '$0 --help' for more information." 1>&2 - exit 1; - ;; + echo "$0: No command. Try \`$0 --help' for more information." 1>&2 + exit 1; + ;; -h | --h*) cat <<\EOF Usage: depcomp [--help] [--version] PROGRAM [ARGS] @@ -39,11 +40,11 @@ as side-effects. Environment variables: depmode Dependency tracking mode. - source Source file read by 'PROGRAMS ARGS'. - object Object file output by 'PROGRAMS ARGS'. + source Source file read by `PROGRAMS ARGS'. + object Object file output by `PROGRAMS ARGS'. DEPDIR directory where to store dependencies. depfile Dependency file to output. - tmpdepfile Temporary file to use when outputting dependencies. + tmpdepfile Temporary file to use when outputing dependencies. libtool Whether libtool is used (yes/no). Report bugs to . @@ -56,66 +57,6 @@ EOF ;; esac -# Get the directory component of the given path, and save it in the -# global variables '$dir'. Note that this directory component will -# be either empty or ending with a '/' character. This is deliberate. -set_dir_from () -{ - case $1 in - */*) dir=`echo "$1" | sed -e 's|/[^/]*$|/|'`;; - *) dir=;; - esac -} - -# Get the suffix-stripped basename of the given path, and save it the -# global variable '$base'. -set_base_from () -{ - base=`echo "$1" | sed -e 's|^.*/||' -e 's/\.[^.]*$//'` -} - -# If no dependency file was actually created by the compiler invocation, -# we still have to create a dummy depfile, to avoid errors with the -# Makefile "include basename.Plo" scheme. -make_dummy_depfile () -{ - echo "#dummy" > "$depfile" -} - -# Factor out some common post-processing of the generated depfile. -# Requires the auxiliary global variable '$tmpdepfile' to be set. -aix_post_process_depfile () -{ - # If the compiler actually managed to produce a dependency file, - # post-process it. - if test -f "$tmpdepfile"; then - # Each line is of the form 'foo.o: dependency.h'. - # Do two passes, one to just change these to - # $object: dependency.h - # and one to simply output - # dependency.h: - # which is needed to avoid the deleted-header problem. - { sed -e "s,^.*\.[$lower]*:,$object:," < "$tmpdepfile" - sed -e "s,^.*\.[$lower]*:[$tab ]*,," -e 's,$,:,' < "$tmpdepfile" - } > "$depfile" - rm -f "$tmpdepfile" - else - make_dummy_depfile - fi -} - -# A tabulation character. -tab=' ' -# A newline character. -nl=' -' -# Character ranges might be problematic outside the C locale. -# These definitions help. -upper=ABCDEFGHIJKLMNOPQRSTUVWXYZ -lower=abcdefghijklmnopqrstuvwxyz -digits=0123456789 -alpha=${upper}${lower} - if test -z "$depmode" || test -z "$source" || test -z "$object"; then echo "depcomp: Variables source, object and depmode must be set" 1>&2 exit 1 @@ -128,9 +69,6 @@ tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} rm -f "$tmpdepfile" -# Avoid interferences from the environment. -gccflag= dashmflag= - # Some modes work just like other modes, but use different flags. We # parameterize here, but still list the modes in the big case below, # to make depend.m4 easier to write. Note that we *cannot* use a case @@ -142,32 +80,18 @@ if test "$depmode" = hp; then fi if test "$depmode" = dashXmstdout; then - # This is just like dashmstdout with a different argument. - dashmflag=-xM - depmode=dashmstdout + # This is just like dashmstdout with a different argument. + dashmflag=-xM + depmode=dashmstdout fi cygpath_u="cygpath -u -f -" if test "$depmode" = msvcmsys; then - # This is just like msvisualcpp but w/o cygpath translation. - # Just convert the backslash-escaped backslashes to single forward - # slashes to satisfy depend.m4 - cygpath_u='sed s,\\\\,/,g' - depmode=msvisualcpp -fi - -if test "$depmode" = msvc7msys; then - # This is just like msvc7 but w/o cygpath translation. - # Just convert the backslash-escaped backslashes to single forward - # slashes to satisfy depend.m4 - cygpath_u='sed s,\\\\,/,g' - depmode=msvc7 -fi - -if test "$depmode" = xlc; then - # IBM C/C++ Compilers xlc/xlC can output gcc-like dependency information. - gccflag=-qmakedep=gcc,-MF - depmode=gcc + # This is just like msvisualcpp but w/o cygpath translation. + # Just convert the backslash-escaped backslashes to single forward + # slashes to satisfy depend.m4 + cygpath_u="sed s,\\\\\\\\,/,g" + depmode=msvisualcpp fi case "$depmode" in @@ -190,7 +114,8 @@ gcc3) done "$@" stat=$? - if test $stat -ne 0; then + if test $stat -eq 0; then : + else rm -f "$tmpdepfile" exit $stat fi @@ -198,17 +123,13 @@ gcc3) ;; gcc) -## Note that this doesn't just cater to obsosete pre-3.x GCC compilers. -## but also to in-use compilers like IMB xlc/xlC and the HP C compiler. -## (see the conditional assignment to $gccflag above). ## There are various ways to get dependency output from gcc. Here's ## why we pick this rather obscure method: ## - Don't want to use -MD because we'd like the dependencies to end ## up in a subdir. Having to rename by hand is ugly. ## (We might end up doing this anyway to support other compilers.) ## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like -## -MM, not -M (despite what the docs say). Also, it might not be -## supported by the other compilers which use the 'gcc' depmode. +## -MM, not -M (despite what the docs say). ## - Using -M directly means running the compiler twice (even worse ## than renaming). if test -z "$gccflag"; then @@ -216,31 +137,31 @@ gcc) fi "$@" -Wp,"$gccflag$tmpdepfile" stat=$? - if test $stat -ne 0; then + if test $stat -eq 0; then : + else rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" echo "$object : \\" > "$depfile" - # The second -e expression handles DOS-style file names with drive - # letters. + alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz +## The second -e expression handles DOS-style file names with drive letters. sed -e 's/^[^:]*: / /' \ -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" -## This next piece of magic avoids the "deleted header file" problem. +## This next piece of magic avoids the `deleted header file' problem. ## The problem is that when a header file which appears in a .P file ## is deleted, the dependency causes make to die (because there is ## typically no way to rebuild the header). We avoid this by adding ## dummy dependencies for each header file. Too bad gcc doesn't do ## this for us directly. -## Some versions of gcc put a space before the ':'. On the theory + tr ' ' ' +' < "$tmpdepfile" | +## Some versions of gcc put a space before the `:'. On the theory ## that the space means something, we add a space to the output as -## well. hp depmode also adds that space, but also prefixes the VPATH -## to the object. Take care to not repeat it in the output. +## well. ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. - tr ' ' "$nl" < "$tmpdepfile" \ - | sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \ - | sed -e 's/$/ :/' >> "$depfile" + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; @@ -258,7 +179,8 @@ sgi) "$@" -MDupdate "$tmpdepfile" fi stat=$? - if test $stat -ne 0; then + if test $stat -eq 0; then : + else rm -f "$tmpdepfile" exit $stat fi @@ -266,41 +188,43 @@ sgi) if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files echo "$object : \\" > "$depfile" + # Clip off the initial element (the dependent). Don't try to be # clever and replace this with sed code, as IRIX sed won't handle # lines with more than a fixed number of characters (4096 in # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; - # the IRIX cc adds comments like '#:fec' to the end of the + # the IRIX cc adds comments like `#:fec' to the end of the # dependency line. - tr ' ' "$nl" < "$tmpdepfile" \ - | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' \ - | tr "$nl" ' ' >> "$depfile" + tr ' ' ' +' < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \ + tr ' +' ' ' >> "$depfile" echo >> "$depfile" + # The second pass generates a dummy entry for each header file. - tr ' ' "$nl" < "$tmpdepfile" \ - | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ - >> "$depfile" + tr ' ' ' +' < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ + >> "$depfile" else - make_dummy_depfile + # The sourcefile does not contain any dependencies, so just + # store a dummy comment line, to avoid errors with the Makefile + # "include basename.Plo" scheme. + echo "#dummy" > "$depfile" fi rm -f "$tmpdepfile" ;; -xlc) - # This case exists only to let depend.m4 do its work. It works by - # looking at the text of this script. This case will never be run, - # since it is checked for above. - exit 1 - ;; - aix) # The C for AIX Compiler uses -M and outputs the dependencies # in a .u file. In older versions, this file always lives in the - # current directory. Also, the AIX compiler puts '$object:' at the + # current directory. Also, the AIX compiler puts `$object:' at the # start of each line; $object doesn't have directory information. # Version 6 uses the directory in both cases. - set_dir_from "$object" - set_base_from "$object" + dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` + test "x$dir" = "x$object" && dir= + base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` if test "$libtool" = yes; then tmpdepfile1=$dir$base.u tmpdepfile2=$base.u @@ -313,7 +237,9 @@ aix) "$@" -M fi stat=$? - if test $stat -ne 0; then + + if test $stat -eq 0; then : + else rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" exit $stat fi @@ -322,100 +248,44 @@ aix) do test -f "$tmpdepfile" && break done - aix_post_process_depfile - ;; - -tcc) - # tcc (Tiny C Compiler) understand '-MD -MF file' since version 0.9.26 - # FIXME: That version still under development at the moment of writing. - # Make that this statement remains true also for stable, released - # versions. - # It will wrap lines (doesn't matter whether long or short) with a - # trailing '\', as in: - # - # foo.o : \ - # foo.c \ - # foo.h \ - # - # It will put a trailing '\' even on the last line, and will use leading - # spaces rather than leading tabs (at least since its commit 0394caf7 - # "Emit spaces for -MD"). - "$@" -MD -MF "$tmpdepfile" - stat=$? - if test $stat -ne 0; then - rm -f "$tmpdepfile" - exit $stat + if test -f "$tmpdepfile"; then + # Each line is of the form `foo.o: dependent.h'. + # Do two passes, one to just change these to + # `$object: dependent.h' and one to simply `dependent.h:'. + sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" + # That's a tab and a space in the []. + sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" + else + # The sourcefile does not contain any dependencies, so just + # store a dummy comment line, to avoid errors with the Makefile + # "include basename.Plo" scheme. + echo "#dummy" > "$depfile" fi - rm -f "$depfile" - # Each non-empty line is of the form 'foo.o : \' or ' dep.h \'. - # We have to change lines of the first kind to '$object: \'. - sed -e "s|.*:|$object :|" < "$tmpdepfile" > "$depfile" - # And for each line of the second kind, we have to emit a 'dep.h:' - # dummy dependency, to avoid the deleted-header problem. - sed -n -e 's|^ *\(.*\) *\\$|\1:|p' < "$tmpdepfile" >> "$depfile" rm -f "$tmpdepfile" ;; -## The order of this option in the case statement is important, since the -## shell code in configure will try each of these formats in the order -## listed in this file. A plain '-MD' option would be understood by many -## compilers, so we must ensure this comes after the gcc and icc options. -pgcc) - # Portland's C compiler understands '-MD'. - # Will always output deps to 'file.d' where file is the root name of the - # source file under compilation, even if file resides in a subdirectory. - # The object file name does not affect the name of the '.d' file. - # pgcc 10.2 will output +icc) + # Intel's C compiler understands `-MD -MF file'. However on + # icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c + # ICC 7.0 will fill foo.d with something like + # foo.o: sub/foo.c + # foo.o: sub/foo.h + # which is wrong. We want: + # sub/foo.o: sub/foo.c + # sub/foo.o: sub/foo.h + # sub/foo.c: + # sub/foo.h: + # ICC 7.1 will output # foo.o: sub/foo.c sub/foo.h - # and will wrap long lines using '\' : + # and will wrap long lines using \ : # foo.o: sub/foo.c ... \ # sub/foo.h ... \ # ... - set_dir_from "$object" - # Use the source, not the object, to determine the base name, since - # that's sadly what pgcc will do too. - set_base_from "$source" - tmpdepfile=$base.d - # For projects that build the same source file twice into different object - # files, the pgcc approach of using the *source* file root name can cause - # problems in parallel builds. Use a locking strategy to avoid stomping on - # the same $tmpdepfile. - lockdir=$base.d-lock - trap " - echo '$0: caught signal, cleaning up...' >&2 - rmdir '$lockdir' - exit 1 - " 1 2 13 15 - numtries=100 - i=$numtries - while test $i -gt 0; do - # mkdir is a portable test-and-set. - if mkdir "$lockdir" 2>/dev/null; then - # This process acquired the lock. - "$@" -MD - stat=$? - # Release the lock. - rmdir "$lockdir" - break - else - # If the lock is being held by a different process, wait - # until the winning process is done or we timeout. - while test -d "$lockdir" && test $i -gt 0; do - sleep 1 - i=`expr $i - 1` - done - fi - i=`expr $i - 1` - done - trap - 1 2 13 15 - if test $i -le 0; then - echo "$0: failed to acquire lock after $numtries attempts" >&2 - echo "$0: check lockdir '$lockdir'" >&2 - exit 1 - fi - - if test $stat -ne 0; then + "$@" -MD -MF "$tmpdepfile" + stat=$? + if test $stat -eq 0; then : + else rm -f "$tmpdepfile" exit $stat fi @@ -427,8 +297,8 @@ pgcc) sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" # Some versions of the HPUX 10.20 sed can't process this invocation # correctly. Breaking it into two sed invocations is a workaround. - sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" \ - | sed -e 's/$/ :/' >> "$depfile" + sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" | + sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; @@ -439,8 +309,9 @@ hp2) # 'foo.d', which lands next to the object file, wherever that # happens to be. # Much of this is similar to the tru64 case; see comments there. - set_dir_from "$object" - set_base_from "$object" + dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` + test "x$dir" = "x$object" && dir= + base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` if test "$libtool" = yes; then tmpdepfile1=$dir$base.d tmpdepfile2=$dir.libs/$base.d @@ -451,7 +322,8 @@ hp2) "$@" +Maked fi stat=$? - if test $stat -ne 0; then + if test $stat -eq 0; then : + else rm -f "$tmpdepfile1" "$tmpdepfile2" exit $stat fi @@ -461,107 +333,77 @@ hp2) test -f "$tmpdepfile" && break done if test -f "$tmpdepfile"; then - sed -e "s,^.*\.[$lower]*:,$object:," "$tmpdepfile" > "$depfile" - # Add 'dependent.h:' lines. + sed -e "s,^.*\.[a-z]*:,$object:," "$tmpdepfile" > "$depfile" + # Add `dependent.h:' lines. sed -ne '2,${ - s/^ *// - s/ \\*$// - s/$/:/ - p - }' "$tmpdepfile" >> "$depfile" + s/^ *// + s/ \\*$// + s/$/:/ + p + }' "$tmpdepfile" >> "$depfile" else - make_dummy_depfile + echo "#dummy" > "$depfile" fi rm -f "$tmpdepfile" "$tmpdepfile2" ;; tru64) - # The Tru64 compiler uses -MD to generate dependencies as a side - # effect. 'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'. - # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put - # dependencies in 'foo.d' instead, so we check for that too. - # Subdirectories are respected. - set_dir_from "$object" - set_base_from "$object" + # The Tru64 compiler uses -MD to generate dependencies as a side + # effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'. + # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put + # dependencies in `foo.d' instead, so we check for that too. + # Subdirectories are respected. + dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` + test "x$dir" = "x$object" && dir= + base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` - if test "$libtool" = yes; then - # Libtool generates 2 separate objects for the 2 libraries. These - # two compilations output dependencies in $dir.libs/$base.o.d and - # in $dir$base.o.d. We have to check for both files, because - # one of the two compilations can be disabled. We should prefer - # $dir$base.o.d over $dir.libs/$base.o.d because the latter is - # automatically cleaned when .libs/ is deleted, while ignoring - # the former would cause a distcleancheck panic. - tmpdepfile1=$dir$base.o.d # libtool 1.5 - tmpdepfile2=$dir.libs/$base.o.d # Likewise. - tmpdepfile3=$dir.libs/$base.d # Compaq CCC V6.2-504 - "$@" -Wc,-MD - else - tmpdepfile1=$dir$base.d - tmpdepfile2=$dir$base.d - tmpdepfile3=$dir$base.d - "$@" -MD - fi + if test "$libtool" = yes; then + # With Tru64 cc, shared objects can also be used to make a + # static library. This mechanism is used in libtool 1.4 series to + # handle both shared and static libraries in a single compilation. + # With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d. + # + # With libtool 1.5 this exception was removed, and libtool now + # generates 2 separate objects for the 2 libraries. These two + # compilations output dependencies in $dir.libs/$base.o.d and + # in $dir$base.o.d. We have to check for both files, because + # one of the two compilations can be disabled. We should prefer + # $dir$base.o.d over $dir.libs/$base.o.d because the latter is + # automatically cleaned when .libs/ is deleted, while ignoring + # the former would cause a distcleancheck panic. + tmpdepfile1=$dir.libs/$base.lo.d # libtool 1.4 + tmpdepfile2=$dir$base.o.d # libtool 1.5 + tmpdepfile3=$dir.libs/$base.o.d # libtool 1.5 + tmpdepfile4=$dir.libs/$base.d # Compaq CCC V6.2-504 + "$@" -Wc,-MD + else + tmpdepfile1=$dir$base.o.d + tmpdepfile2=$dir$base.d + tmpdepfile3=$dir$base.d + tmpdepfile4=$dir$base.d + "$@" -MD + fi - stat=$? - if test $stat -ne 0; then - rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" - exit $stat - fi + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" + exit $stat + fi - for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" - do - test -f "$tmpdepfile" && break - done - # Same post-processing that is required for AIX mode. - aix_post_process_depfile - ;; - -msvc7) - if test "$libtool" = yes; then - showIncludes=-Wc,-showIncludes - else - showIncludes=-showIncludes - fi - "$@" $showIncludes > "$tmpdepfile" - stat=$? - grep -v '^Note: including file: ' "$tmpdepfile" - if test $stat -ne 0; then - rm -f "$tmpdepfile" - exit $stat - fi - rm -f "$depfile" - echo "$object : \\" > "$depfile" - # The first sed program below extracts the file names and escapes - # backslashes for cygpath. The second sed program outputs the file - # name when reading, but also accumulates all include files in the - # hold buffer in order to output them again at the end. This only - # works with sed implementations that can handle large buffers. - sed < "$tmpdepfile" -n ' -/^Note: including file: *\(.*\)/ { - s//\1/ - s/\\/\\\\/g - p -}' | $cygpath_u | sort -u | sed -n ' -s/ /\\ /g -s/\(.*\)/'"$tab"'\1 \\/p -s/.\(.*\) \\/\1:/ -H -$ { - s/.*/'"$tab"'/ - G - p -}' >> "$depfile" - echo >> "$depfile" # make sure the fragment doesn't end with a backslash - rm -f "$tmpdepfile" - ;; - -msvc7msys) - # This case exists only to let depend.m4 do its work. It works by - # looking at the text of this script. This case will never be run, - # since it is checked for above. - exit 1 - ;; + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" + do + test -f "$tmpdepfile" && break + done + if test -f "$tmpdepfile"; then + sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" + # That's a tab and a space in the []. + sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" + else + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; #nosideeffect) # This comment above is used by automake to tell side-effect @@ -580,7 +422,7 @@ dashmstdout) shift fi - # Remove '-o $object'. + # Remove `-o $object'. IFS=" " for arg do @@ -600,18 +442,18 @@ dashmstdout) done test -z "$dashmflag" && dashmflag=-M - # Require at least two characters before searching for ':' + # Require at least two characters before searching for `:' # in the target name. This is to cope with DOS-style filenames: - # a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise. + # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise. "$@" $dashmflag | - sed "s|^[$tab ]*[^:$tab ][^:][^:]*:[$tab ]*|$object: |" > "$tmpdepfile" + sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile" rm -f "$depfile" cat < "$tmpdepfile" > "$depfile" - # Some versions of the HPUX 10.20 sed can't process this sed invocation - # correctly. Breaking it into two sed invocations is a workaround. - tr ' ' "$nl" < "$tmpdepfile" \ - | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ - | sed -e 's/$/ :/' >> "$depfile" + tr ' ' ' +' < "$tmpdepfile" | \ +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; @@ -661,15 +503,12 @@ makedepend) touch "$tmpdepfile" ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" rm -f "$depfile" - # makedepend may prepend the VPATH from the source file name to the object. - # No need to regex-escape $object, excess matching of '.' is harmless. - sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile" - # Some versions of the HPUX 10.20 sed can't process the last invocation - # correctly. Breaking it into two sed invocations is a workaround. - sed '1,2d' "$tmpdepfile" \ - | tr ' ' "$nl" \ - | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ - | sed -e 's/$/ :/' >> "$depfile" + cat < "$tmpdepfile" > "$depfile" + sed '1,2d' "$tmpdepfile" | tr ' ' ' +' | \ +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" "$tmpdepfile".bak ;; @@ -686,7 +525,7 @@ cpp) shift fi - # Remove '-o $object'. + # Remove `-o $object'. IFS=" " for arg do @@ -705,10 +544,10 @@ cpp) esac done - "$@" -E \ - | sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ - -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ - | sed '$ s: \\$::' > "$tmpdepfile" + "$@" -E | + sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ + -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' | + sed '$ s: \\$::' > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" cat < "$tmpdepfile" >> "$depfile" @@ -740,23 +579,23 @@ msvisualcpp) shift ;; "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") - set fnord "$@" - shift - shift - ;; + set fnord "$@" + shift + shift + ;; *) - set fnord "$@" "$arg" - shift - shift - ;; + set fnord "$@" "$arg" + shift + shift + ;; esac done "$@" -E 2>/dev/null | sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" - sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile" - echo "$tab" >> "$depfile" + sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile" + echo " " >> "$depfile" sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile" rm -f "$tmpdepfile" ;; @@ -783,9 +622,9 @@ exit 0 # Local Variables: # mode: shell-script # sh-indentation: 2 -# eval: (add-hook 'before-save-hook 'time-stamp) +# eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" -# time-stamp-time-zone: "UTC0" +# time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: diff --git a/doc/Makefile.am b/doc/Makefile.am index 29d6ffd..8f0305e 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -1,35 +1,58 @@ ## Process this file with automake to get Makefile.in info_TEXINFOS = tinc.texi -tinc_TEXINFOS = tincinclude.texi -man_MANS = tincd.8 tinc.conf.5 +man_MANS = tincd.8 tincctl.8 tinc.conf.5 tinc-gui.8 -EXTRA_DIST = tincinclude.texi.in tincd.8.in tinc.conf.5.in sample-config +EXTRA_DIST = tincinclude.texi.in tincd.8.in tincctl.8.in tinc.conf.5.in tinc-gui.8.in sample-config.tar.gz -CLEANFILES = *.html tincd.8 tinc.conf.5 tincinclude.texi +CLEANFILES = *.html tinc.info tincd.8 tincctl.8 tinc.conf.5 tinc-gui.8 tincinclude.texi + +# Use `ginstall' in the definition of man_MANS to avoid +# confusion with the `install' target. The install rule transforms `ginstall' +# to install before applying any user-specified name transformations. +transform = s/ginstall/install/; @program_transform_name@ + +# For additional rules usually of interest only to the maintainer, +# see GNUmakefile and Makefile.maint. + +sample-config.tar.gz: sample-config + GZIP=$(GZIP_ENV) $(AMTAR) chozf sample-config.tar.gz --exclude .svn sample-config texi2html: tinc.texi - $(AM_V_GEN)texi2html -split=chapter $< + texi2html -split=chapter tinc.texi tincd.8.html: tincd.8 - $(AM_V_GEN)w3mman2html $< > $@ + w3mman2html $< > $@ + +tincctl.8.html: tincctl.8 + w3mman2html $< > $@ + +tinc-gui.8.html: tinc-gui.8 + w3mman2html $< > $@ tinc.conf.5.html: tinc.conf.5 - $(AM_V_GEN)w3mman2html $< > $@ + w3mman2html $< > $@ substitute = sed \ -e s,'@PACKAGE\@',"$(PACKAGE)",g \ -e s,'@VERSION\@',"$(VERSION)",g \ -e s,'@sysconfdir\@',"$(sysconfdir)",g \ - -e s,'@runstatedir\@',"$(runstatedir)",g \ -e s,'@localstatedir\@',"$(localstatedir)",g -tincd.8: $(srcdir)/tincd.8.in - $(AM_V_GEN)$(substitute) $(srcdir)/tincd.8.in > $@ +tincd.8: tincd.8.in + $(substitute) $< > $@ -tinc.conf.5: $(srcdir)/tinc.conf.5.in - $(AM_V_GEN)$(substitute) $(srcdir)/tinc.conf.5.in > $@ +tincctl.8: tincctl.8.in + $(substitute) $< > $@ -tincinclude.texi: $(srcdir)/tincinclude.texi.in - $(AM_V_GEN)$(substitute) $(srcdir)/tincinclude.texi.in > $@ +tinc-gui.8: tinc-gui.8.in + $(substitute) $< > $@ + +tinc.conf.5: tinc.conf.5.in + $(substitute) $< > $@ + +tincinclude.texi: tincinclude.texi.in + $(substitute) $< > $@ + +tinc.texi: tincinclude.texi diff --git a/doc/Makefile.in b/doc/Makefile.in index 86497e4..b80f326 100644 --- a/doc/Makefile.in +++ b/doc/Makefile.in @@ -1,8 +1,9 @@ -# Makefile.in generated by automake 1.16.1 from Makefile.am. +# Makefile.in generated by automake 1.11.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2018 Free Software Foundation, Inc. - +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -14,61 +15,6 @@ @SET_MAKE@ VPATH = @srcdir@ -am__is_gnu_make = { \ - if test -z '$(MAKELEVEL)'; then \ - false; \ - elif test -n '$(MAKE_HOST)'; then \ - true; \ - elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ - true; \ - else \ - false; \ - fi; \ -} -am__make_running_with_option = \ - case $${target_option-} in \ - ?) ;; \ - *) echo "am__make_running_with_option: internal error: invalid" \ - "target option '$${target_option-}' specified" >&2; \ - exit 1;; \ - esac; \ - has_opt=no; \ - sane_makeflags=$$MAKEFLAGS; \ - if $(am__is_gnu_make); then \ - sane_makeflags=$$MFLAGS; \ - else \ - case $$MAKEFLAGS in \ - *\\[\ \ ]*) \ - bs=\\; \ - sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ - | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ - esac; \ - fi; \ - skip_next=no; \ - strip_trailopt () \ - { \ - flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ - }; \ - for flg in $$sane_makeflags; do \ - test $$skip_next = yes && { skip_next=no; continue; }; \ - case $$flg in \ - *=*|--*) continue;; \ - -*I) strip_trailopt 'I'; skip_next=yes;; \ - -*I?*) strip_trailopt 'I';; \ - -*O) strip_trailopt 'O'; skip_next=yes;; \ - -*O?*) strip_trailopt 'O';; \ - -*l) strip_trailopt 'l'; skip_next=yes;; \ - -*l?*) strip_trailopt 'l';; \ - -[dEDm]) skip_next=yes;; \ - -[JT]) skip_next=yes;; \ - esac; \ - case $$flg in \ - *$$target_option*) has_opt=yes; break;; \ - esac; \ - done; \ - test $$has_opt = yes -am__make_dryrun = (target_option=n; $(am__make_running_with_option)) -am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ @@ -78,7 +24,6 @@ install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) -transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : @@ -88,65 +33,21 @@ POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = doc +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in texinfo.tex ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \ - $(top_srcdir)/m4/ax_append_flag.m4 \ - $(top_srcdir)/m4/ax_cflags_warn_all.m4 \ - $(top_srcdir)/m4/ax_check_compile_flag.m4 \ - $(top_srcdir)/m4/ax_check_link_flag.m4 \ - $(top_srcdir)/m4/ax_require_defined.m4 $(top_srcdir)/m4/lzo.m4 \ - $(top_srcdir)/m4/openssl.m4 $(top_srcdir)/m4/zlib.m4 \ - $(top_srcdir)/configure.ac + $(top_srcdir)/m4/curses.m4 $(top_srcdir)/m4/libevent.m4 \ + $(top_srcdir)/m4/lzo.m4 $(top_srcdir)/m4/openssl.m4 \ + $(top_srcdir)/m4/zlib.m4 $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) -DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = -AM_V_P = $(am__v_P_@AM_V@) -am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) -am__v_P_0 = false -am__v_P_1 = : -AM_V_GEN = $(am__v_GEN_@AM_V@) -am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) -am__v_GEN_0 = @echo " GEN " $@; -am__v_GEN_1 = -AM_V_at = $(am__v_at_@AM_V@) -am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) -am__v_at_0 = @ -am__v_at_1 = SOURCES = DIST_SOURCES = -AM_V_DVIPS = $(am__v_DVIPS_@AM_V@) -am__v_DVIPS_ = $(am__v_DVIPS_@AM_DEFAULT_V@) -am__v_DVIPS_0 = @echo " DVIPS " $@; -am__v_DVIPS_1 = -AM_V_MAKEINFO = $(am__v_MAKEINFO_@AM_V@) -am__v_MAKEINFO_ = $(am__v_MAKEINFO_@AM_DEFAULT_V@) -am__v_MAKEINFO_0 = @echo " MAKEINFO" $@; -am__v_MAKEINFO_1 = -AM_V_INFOHTML = $(am__v_INFOHTML_@AM_V@) -am__v_INFOHTML_ = $(am__v_INFOHTML_@AM_DEFAULT_V@) -am__v_INFOHTML_0 = @echo " INFOHTML" $@; -am__v_INFOHTML_1 = -AM_V_TEXI2DVI = $(am__v_TEXI2DVI_@AM_V@) -am__v_TEXI2DVI_ = $(am__v_TEXI2DVI_@AM_DEFAULT_V@) -am__v_TEXI2DVI_0 = @echo " TEXI2DVI" $@; -am__v_TEXI2DVI_1 = -AM_V_TEXI2PDF = $(am__v_TEXI2PDF_@AM_V@) -am__v_TEXI2PDF_ = $(am__v_TEXI2PDF_@AM_DEFAULT_V@) -am__v_TEXI2PDF_0 = @echo " TEXI2PDF" $@; -am__v_TEXI2PDF_1 = -AM_V_texinfo = $(am__v_texinfo_@AM_V@) -am__v_texinfo_ = $(am__v_texinfo_@AM_DEFAULT_V@) -am__v_texinfo_0 = -q -am__v_texinfo_1 = -AM_V_texidevnull = $(am__v_texidevnull_@AM_V@) -am__v_texidevnull_ = $(am__v_texidevnull_@AM_DEFAULT_V@) -am__v_texidevnull_0 = > /dev/null -am__v_texidevnull_1 = -INFO_DEPS = $(srcdir)/tinc.info +INFO_DEPS = tinc.info am__TEXINFO_TEX_DIR = $(srcdir) DVIS = tinc.dvi PDFS = tinc.pdf @@ -158,11 +59,6 @@ TEXI2PDF = $(TEXI2DVI) --pdf --batch MAKEINFOHTML = $(MAKEINFO) --html AM_MAKEINFOHTMLFLAGS = $(AM_MAKEINFOFLAGS) DVIPS = dvips -am__can_run_installinfo = \ - case $$AM_UPDATE_INFO_DIR in \ - n|no|NO) false;; \ - *) (install-info --version) >/dev/null 2>&1;; \ - esac am__installdirs = "$(DESTDIR)$(infodir)" "$(DESTDIR)$(man5dir)" \ "$(DESTDIR)$(man8dir)" am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; @@ -186,22 +82,18 @@ am__nobase_list = $(am__nobase_strip_setup); \ am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' -am__uninstall_files_from_dir = { \ - test -z "$$files" \ - || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ - || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ - $(am__cd) "$$dir" && rm -f $$files; }; \ - } man5dir = $(mandir)/man5 man8dir = $(mandir)/man8 NROFF = nroff MANS = $(man_MANS) -am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) -am__DIST_COMMON = $(srcdir)/Makefile.in $(tinc_TEXINFOS) texinfo.tex DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) + +# Use `ginstall' in the definition of man_MANS to avoid +# confusion with the `install' target. The install rule transforms `ginstall' +# to install before applying any user-specified name transformations. +transform = s/ginstall/install/; @program_transform_name@ ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ -AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ @@ -211,6 +103,7 @@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ +CURSES_LIBS = @CURSES_LIBS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ @@ -220,15 +113,21 @@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ GREP = @GREP@ +INCLUDES = @INCLUDES@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ +LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ +LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ +LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ +LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ OBJEXT = @OBJEXT@ @@ -240,6 +139,7 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ @@ -286,33 +186,29 @@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ -runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ -systemd_path = @systemd_path@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ info_TEXINFOS = tinc.texi -tinc_TEXINFOS = tincinclude.texi -man_MANS = tincd.8 tinc.conf.5 -EXTRA_DIST = tincinclude.texi.in tincd.8.in tinc.conf.5.in sample-config -CLEANFILES = *.html tincd.8 tinc.conf.5 tincinclude.texi +man_MANS = tincd.8 tincctl.8 tinc.conf.5 tinc-gui.8 +EXTRA_DIST = tincinclude.texi.in tincd.8.in tincctl.8.in tinc.conf.5.in tinc-gui.8.in sample-config.tar.gz +CLEANFILES = *.html tinc.info tincd.8 tincctl.8 tinc.conf.5 tinc-gui.8 tincinclude.texi substitute = sed \ -e s,'@PACKAGE\@',"$(PACKAGE)",g \ -e s,'@VERSION\@',"$(VERSION)",g \ -e s,'@sysconfdir\@',"$(sysconfdir)",g \ - -e s,'@runstatedir\@',"$(runstatedir)",g \ -e s,'@localstatedir\@',"$(localstatedir)",g all: all-am .SUFFIXES: -.SUFFIXES: .dvi .html .info .pdf .ps .texi -$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) +.SUFFIXES: .dvi .ps +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ @@ -324,74 +220,69 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu doc/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu doc/Makefile +.PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(top_srcdir)/configure: $(am__configure_deps) +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(ACLOCAL_M4): $(am__aclocal_m4_deps) +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): -.texi.info: - $(AM_V_MAKEINFO)restore=: && backupdir="$(am__leading_dot)am$$$$" && \ - am__cwd=`pwd` && $(am__cd) $(srcdir) && \ +tinc.info: tinc.texi + restore=: && backupdir="$(am__leading_dot)am$$$$" && \ rm -rf $$backupdir && mkdir $$backupdir && \ if ($(MAKEINFO) --version) >/dev/null 2>&1; then \ for f in $@ $@-[0-9] $@-[0-9][0-9] $(@:.info=).i[0-9] $(@:.info=).i[0-9][0-9]; do \ if test -f $$f; then mv $$f $$backupdir; restore=mv; else :; fi; \ done; \ else :; fi && \ - cd "$$am__cwd"; \ if $(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir) \ - -o $@ $<; \ + -o $@ `test -f 'tinc.texi' || echo '$(srcdir)/'`tinc.texi; \ then \ rc=0; \ - $(am__cd) $(srcdir); \ else \ rc=$$?; \ - $(am__cd) $(srcdir) && \ $$restore $$backupdir/* `echo "./$@" | sed 's|[^/]*$$||'`; \ fi; \ rm -rf $$backupdir; exit $$rc -.texi.dvi: - $(AM_V_TEXI2DVI)TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \ +tinc.dvi: tinc.texi + TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \ MAKEINFO='$(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir)' \ - $(TEXI2DVI) $(AM_V_texinfo) --build-dir=$(@:.dvi=.t2d) -o $@ $(AM_V_texidevnull) \ - $< + $(TEXI2DVI) -o $@ `test -f 'tinc.texi' || echo '$(srcdir)/'`tinc.texi -.texi.pdf: - $(AM_V_TEXI2PDF)TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \ +tinc.pdf: tinc.texi + TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \ MAKEINFO='$(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir)' \ - $(TEXI2PDF) $(AM_V_texinfo) --build-dir=$(@:.pdf=.t2p) -o $@ $(AM_V_texidevnull) \ - $< + $(TEXI2PDF) -o $@ `test -f 'tinc.texi' || echo '$(srcdir)/'`tinc.texi -.texi.html: - $(AM_V_MAKEINFO)rm -rf $(@:.html=.htp) - $(AM_V_at)if $(MAKEINFOHTML) $(AM_MAKEINFOHTMLFLAGS) $(MAKEINFOFLAGS) -I $(srcdir) \ - -o $(@:.html=.htp) $<; \ +tinc.html: tinc.texi + rm -rf $(@:.html=.htp) + if $(MAKEINFOHTML) $(AM_MAKEINFOHTMLFLAGS) $(MAKEINFOFLAGS) -I $(srcdir) \ + -o $(@:.html=.htp) `test -f 'tinc.texi' || echo '$(srcdir)/'`tinc.texi; \ then \ - rm -rf $@ && mv $(@:.html=.htp) $@; \ + rm -rf $@; \ + if test ! -d $(@:.html=.htp) && test -d $(@:.html=); then \ + mv $(@:.html=) $@; else mv $(@:.html=.htp) $@; fi; \ else \ - rm -rf $(@:.html=.htp); exit 1; \ + if test ! -d $(@:.html=.htp) && test -d $(@:.html=); then \ + rm -rf $(@:.html=); else rm -Rf $(@:.html=.htp) $@; fi; \ + exit 1; \ fi -$(srcdir)/tinc.info: tinc.texi $(tinc_TEXINFOS) -tinc.dvi: tinc.texi $(tinc_TEXINFOS) -tinc.pdf: tinc.texi $(tinc_TEXINFOS) -tinc.html: tinc.texi $(tinc_TEXINFOS) .dvi.ps: - $(AM_V_DVIPS)TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \ - $(DVIPS) $(AM_V_texinfo) -o $@ $< + TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \ + $(DVIPS) -o $@ $< uninstall-dvi-am: @$(NORMAL_UNINSTALL) @@ -413,7 +304,9 @@ uninstall-html-am: uninstall-info-am: @$(PRE_UNINSTALL) - @if test -d '$(DESTDIR)$(infodir)' && $(am__can_run_installinfo); then \ + @if test -d '$(DESTDIR)$(infodir)' && \ + (install-info --version && \ + install-info --version 2>&1 | sed 1q | grep -i -v debian) >/dev/null 2>&1; then \ list='$(INFO_DEPS)'; \ for file in $$list; do \ relfile=`echo "$$file" | sed 's|^.*/||'`; \ @@ -470,7 +363,9 @@ dist-info: $(INFO_DEPS) done mostlyclean-aminfo: - -rm -rf tinc.t2d tinc.t2p + -rm -rf tinc.aux tinc.cp tinc.cps tinc.fn tinc.fns tinc.ky tinc.kys \ + tinc.log tinc.pg tinc.pgs tinc.tmp tinc.toc tinc.tp tinc.tps \ + tinc.vr tinc.vrs clean-aminfo: -test -z "tinc.dvi tinc.pdf tinc.ps tinc.html" \ @@ -484,18 +379,11 @@ maintainer-clean-aminfo: done install-man5: $(man_MANS) @$(NORMAL_INSTALL) - @list1=''; \ - list2='$(man_MANS)'; \ - test -n "$(man5dir)" \ - && test -n "`echo $$list1$$list2`" \ - || exit 0; \ - echo " $(MKDIR_P) '$(DESTDIR)$(man5dir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(man5dir)" || exit 1; \ - { for i in $$list1; do echo "$$i"; done; \ - if test -n "$$list2"; then \ - for i in $$list2; do echo "$$i"; done \ - | sed -n '/\.5[a-z]*$$/p'; \ - fi; \ + test -z "$(man5dir)" || $(MKDIR_P) "$(DESTDIR)$(man5dir)" + @list=''; test -n "$(man5dir)" || exit 0; \ + { for i in $$list; do echo "$$i"; done; \ + l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ + sed -n '/\.5[a-z]*$$/p'; \ } | while read p; do \ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; echo "$$p"; \ @@ -524,21 +412,16 @@ uninstall-man5: sed -n '/\.5[a-z]*$$/p'; \ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^5][0-9a-z]*$$,5,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ - dir='$(DESTDIR)$(man5dir)'; $(am__uninstall_files_from_dir) + test -z "$$files" || { \ + echo " ( cd '$(DESTDIR)$(man5dir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(man5dir)" && rm -f $$files; } install-man8: $(man_MANS) @$(NORMAL_INSTALL) - @list1=''; \ - list2='$(man_MANS)'; \ - test -n "$(man8dir)" \ - && test -n "`echo $$list1$$list2`" \ - || exit 0; \ - echo " $(MKDIR_P) '$(DESTDIR)$(man8dir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(man8dir)" || exit 1; \ - { for i in $$list1; do echo "$$i"; done; \ - if test -n "$$list2"; then \ - for i in $$list2; do echo "$$i"; done \ - | sed -n '/\.8[a-z]*$$/p'; \ - fi; \ + test -z "$(man8dir)" || $(MKDIR_P) "$(DESTDIR)$(man8dir)" + @list=''; test -n "$(man8dir)" || exit 0; \ + { for i in $$list; do echo "$$i"; done; \ + l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ + sed -n '/\.8[a-z]*$$/p'; \ } | while read p; do \ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; echo "$$p"; \ @@ -567,18 +450,30 @@ uninstall-man8: sed -n '/\.8[a-z]*$$/p'; \ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ - dir='$(DESTDIR)$(man8dir)'; $(am__uninstall_files_from_dir) -tags TAGS: + test -z "$$files" || { \ + echo " ( cd '$(DESTDIR)$(man8dir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(man8dir)" && rm -f $$files; } +tags: TAGS +TAGS: -ctags CTAGS: - -cscope cscopelist: +ctags: CTAGS +CTAGS: -distdir: $(BUILT_SOURCES) - $(MAKE) $(AM_MAKEFLAGS) distdir-am - -distdir-am: $(DISTFILES) +distdir: $(DISTFILES) + @list='$(MANS)'; if test -n "$$list"; then \ + list=`for p in $$list; do \ + if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ + if test -f "$$d$$p"; then echo "$$d$$p"; else :; fi; done`; \ + if test -n "$$list" && \ + grep 'ab help2man is required to generate this page' $$list >/dev/null; then \ + echo "error: found man pages containing the \`missing help2man' replacement text:" >&2; \ + grep -l 'ab help2man is required to generate this page' $$list | sed 's/^/ /' >&2; \ + echo " to fix them, install help2man, remove and regenerate the man pages;" >&2; \ + echo " typically \`make maintainer-clean' will remove them" >&2; \ + exit 1; \ + else :; fi; \ + else :; fi @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ @@ -628,15 +523,10 @@ install-am: all-am installcheck: installcheck-am install-strip: - if test -z '$(STRIP)'; then \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - install; \ - else \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ - fi + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: @@ -675,11 +565,8 @@ install-dvi: install-dvi-am install-dvi-am: $(DVIS) @$(NORMAL_INSTALL) + test -z "$(dvidir)" || $(MKDIR_P) "$(DESTDIR)$(dvidir)" @list='$(DVIS)'; test -n "$(dvidir)" || list=; \ - if test -n "$$list"; then \ - echo " $(MKDIR_P) '$(DESTDIR)$(dvidir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(dvidir)" || exit 1; \ - fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ @@ -694,22 +581,18 @@ install-html: install-html-am install-html-am: $(HTMLS) @$(NORMAL_INSTALL) + test -z "$(htmldir)" || $(MKDIR_P) "$(DESTDIR)$(htmldir)" @list='$(HTMLS)'; list2=; test -n "$(htmldir)" || list=; \ - if test -n "$$list"; then \ - echo " $(MKDIR_P) '$(DESTDIR)$(htmldir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(htmldir)" || exit 1; \ - fi; \ for p in $$list; do \ if test -f "$$p" || test -d "$$p"; then d=; else d="$(srcdir)/"; fi; \ $(am__strip_dir) \ - d2=$$d$$p; \ - if test -d "$$d2"; then \ + if test -d "$$d$$p"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(htmldir)/$$f'"; \ $(MKDIR_P) "$(DESTDIR)$(htmldir)/$$f" || exit 1; \ - echo " $(INSTALL_DATA) '$$d2'/* '$(DESTDIR)$(htmldir)/$$f'"; \ - $(INSTALL_DATA) "$$d2"/* "$(DESTDIR)$(htmldir)/$$f" || exit $$?; \ + echo " $(INSTALL_DATA) '$$d$$p'/* '$(DESTDIR)$(htmldir)/$$f'"; \ + $(INSTALL_DATA) "$$d$$p"/* "$(DESTDIR)$(htmldir)/$$f" || exit $$?; \ else \ - list2="$$list2 $$d2"; \ + list2="$$list2 $$d$$p"; \ fi; \ done; \ test -z "$$list2" || { echo "$$list2" | $(am__base_list) | \ @@ -721,12 +604,9 @@ install-info: install-info-am install-info-am: $(INFO_DEPS) @$(NORMAL_INSTALL) + test -z "$(infodir)" || $(MKDIR_P) "$(DESTDIR)$(infodir)" @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ list='$(INFO_DEPS)'; test -n "$(infodir)" || list=; \ - if test -n "$$list"; then \ - echo " $(MKDIR_P) '$(DESTDIR)$(infodir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(infodir)" || exit 1; \ - fi; \ for file in $$list; do \ case $$file in \ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ @@ -744,7 +624,8 @@ install-info-am: $(INFO_DEPS) echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(infodir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(infodir)" || exit $$?; done @$(POST_INSTALL) - @if $(am__can_run_installinfo); then \ + @if (install-info --version && \ + install-info --version 2>&1 | sed 1q | grep -i -v debian) >/dev/null 2>&1; then \ list='$(INFO_DEPS)'; test -n "$(infodir)" || list=; \ for file in $$list; do \ relfile=`echo "$$file" | sed 's|^.*/||'`; \ @@ -758,11 +639,8 @@ install-pdf: install-pdf-am install-pdf-am: $(PDFS) @$(NORMAL_INSTALL) + test -z "$(pdfdir)" || $(MKDIR_P) "$(DESTDIR)$(pdfdir)" @list='$(PDFS)'; test -n "$(pdfdir)" || list=; \ - if test -n "$$list"; then \ - echo " $(MKDIR_P) '$(DESTDIR)$(pdfdir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(pdfdir)" || exit 1; \ - fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ @@ -774,11 +652,8 @@ install-ps: install-ps-am install-ps-am: $(PSS) @$(NORMAL_INSTALL) + test -z "$(psdir)" || $(MKDIR_P) "$(DESTDIR)$(psdir)" @list='$(PSS)'; test -n "$(psdir)" || list=; \ - if test -n "$$list"; then \ - echo " $(MKDIR_P) '$(DESTDIR)$(psdir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(psdir)" || exit 1; \ - fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ @@ -813,40 +688,58 @@ uninstall-man: uninstall-man5 uninstall-man8 .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-aminfo clean-generic \ - cscopelist-am ctags-am dist-info distclean distclean-generic \ - distdir dvi dvi-am html html-am info info-am install \ - install-am install-data install-data-am install-dvi \ - install-dvi-am install-exec install-exec-am install-html \ - install-html-am install-info install-info-am install-man \ - install-man5 install-man8 install-pdf install-pdf-am \ - install-ps install-ps-am install-strip installcheck \ - installcheck-am installdirs maintainer-clean \ - maintainer-clean-aminfo maintainer-clean-generic mostlyclean \ - mostlyclean-aminfo mostlyclean-generic pdf pdf-am ps ps-am \ - tags-am uninstall uninstall-am uninstall-dvi-am \ - uninstall-html-am uninstall-info-am uninstall-man \ - uninstall-man5 uninstall-man8 uninstall-pdf-am uninstall-ps-am + dist-info distclean distclean-generic distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-man5 install-man8 \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-aminfo \ + maintainer-clean-generic mostlyclean mostlyclean-aminfo \ + mostlyclean-generic pdf pdf-am ps ps-am uninstall uninstall-am \ + uninstall-dvi-am uninstall-html-am uninstall-info-am \ + uninstall-man uninstall-man5 uninstall-man8 uninstall-pdf-am \ + uninstall-ps-am -.PRECIOUS: Makefile +# For additional rules usually of interest only to the maintainer, +# see GNUmakefile and Makefile.maint. + +sample-config.tar.gz: sample-config + GZIP=$(GZIP_ENV) $(AMTAR) chozf sample-config.tar.gz --exclude .svn sample-config texi2html: tinc.texi - $(AM_V_GEN)texi2html -split=chapter $< + texi2html -split=chapter tinc.texi tincd.8.html: tincd.8 - $(AM_V_GEN)w3mman2html $< > $@ + w3mman2html $< > $@ + +tincctl.8.html: tincctl.8 + w3mman2html $< > $@ + +tinc-gui.8.html: tinc-gui.8 + w3mman2html $< > $@ tinc.conf.5.html: tinc.conf.5 - $(AM_V_GEN)w3mman2html $< > $@ + w3mman2html $< > $@ -tincd.8: $(srcdir)/tincd.8.in - $(AM_V_GEN)$(substitute) $(srcdir)/tincd.8.in > $@ +tincd.8: tincd.8.in + $(substitute) $< > $@ -tinc.conf.5: $(srcdir)/tinc.conf.5.in - $(AM_V_GEN)$(substitute) $(srcdir)/tinc.conf.5.in > $@ +tincctl.8: tincctl.8.in + $(substitute) $< > $@ -tincinclude.texi: $(srcdir)/tincinclude.texi.in - $(AM_V_GEN)$(substitute) $(srcdir)/tincinclude.texi.in > $@ +tinc-gui.8: tinc-gui.8.in + $(substitute) $< > $@ + +tinc.conf.5: tinc.conf.5.in + $(substitute) $< > $@ + +tincinclude.texi: tincinclude.texi.in + $(substitute) $< > $@ + +tinc.texi: tincinclude.texi # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. diff --git a/doc/sample-config.tar.gz b/doc/sample-config.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..3ad2d9a525b44c970be6c10d0ba1759bbd78531e GIT binary patch literal 1246 zcmV<41R?t$iwFQZ1S3uW1MQe!Z`(Kw!26s}!J!8X2Q-fD#K|_G5B;|x*sfPJ-2r>L z$+nURwI!bcP-|v|k}wtpZ?z8LW-1KeAH(Nm$)yeO z%TdKLj^D`~EKBi1bKr$2g=CiJfivT93`R^O8q2p9jMXBu#R4QpQ^WKE%@{Qj0DJ)bCC0oFpNsC^rf`YRd2Vp@-V8&gPl~ywxUUQbSR20H4;KT2z{uk4Nr8pnS zO75ewsDvRw#teFqhD#%?nDL;s43bnqjWGb6q|3up85_Vg|ECt3CUZ#|$H0ne%2rlF zTCOFxPMN~Qe2ce zrJ+X8H5%KsD4A4vtJeZW?LRPKDJR_=tqLprl2QuBN@JSxTINhq;FU&yJ-y1aj|2gFFO(zwyW2UPe&^OR;Pr64kRgvHK1}JhkS+{G$C}GGU}^rrHm|@iD2P@OL!2Z5{f9xg?ADw0uMPYA zmM?-zi`nk>*i-e7zxE&0e>dz$P5nQI;5O%y<7VRi=Z`CYSF_*gWspN#0{`KEBDOz& zZ{G2*Og8JE8jRWbDd4Z4|3!mdbN=@%vTgn8RA855Jjs9YBmPU`r0M_9A$RA0KVgdv zESw{fOqQ>U9MXk1qU~~bmZmu}%1qPQFM zlAu2bqId6Uh%2S7tckfCIHHj%2{-SL&P=d=TGdC`X^{~+>nCAIK1NGU^Gt<|X^FcC zdFU;Ok31L>o}q_AW%$%nD&G17x222YJIIQIuoL%INvP_y5E&pzZKiA6EA_48SgSOu zU?O;{O>%niX?O|OqZ7FLdirH}2A?m!xd*Kv2)xS0<@r{HUt9le_3w^3ceux%s{eix zJ*@u$RuJqkg#F8Ft^d8%b=>U*U8?Q>Uf0RK$~t. +% along with this program. If not, see . % % As a special exception, when this file is read by TeX when processing % a Texinfo source document, you may use the result without -% restriction. This Exception is an additional permission under section 7 -% of the GNU General Public License, version 3 ("GPLv3"). +% restriction. (This has been our intent since Texinfo was invented.) % % Please try the latest version of texinfo.tex before submitting bug % reports; you can get the latest version from: -% https://ftp.gnu.org/gnu/texinfo/ (the Texinfo release area), or -% https://ftpmirror.gnu.org/texinfo/ (same, via a mirror), or -% https://www.gnu.org/software/texinfo/ (the Texinfo home page) +% http://www.gnu.org/software/texinfo/ (the Texinfo home page), or +% ftp://tug.org/tex/texinfo.tex +% (and all CTAN mirrors, see http://www.ctan.org). % The texinfo.tex in any given distribution could well be out % of date, so if that's what you're using, please check. % @@ -56,7 +54,7 @@ % extent. You can get the existing language-specific files from the % full Texinfo distribution. % -% The GNU Texinfo home page is https://www.gnu.org/software/texinfo. +% The GNU Texinfo home page is http://www.gnu.org/software/texinfo. \message{Loading texinfo [version \texinfoversion]:} @@ -67,9 +65,6 @@ \everyjob{\message{[Texinfo version \texinfoversion]}% \catcode`+=\active \catcode`\_=\active} -% LaTeX's \typeout. This ensures that the messages it is used for -% are identical in format to the corresponding ones from latex/pdflatex. -\def\typeout{\immediate\write17}% \chardef\other=12 @@ -98,15 +93,14 @@ \let\ptexnewwrite\newwrite \let\ptexnoindent=\noindent \let\ptexplus=+ -\let\ptexraggedright=\raggedright \let\ptexrbrace=\} \let\ptexslash=\/ -\let\ptexsp=\sp \let\ptexstar=\* -\let\ptexsup=\sup \let\ptext=\t \let\ptextop=\top -{\catcode`\'=\active \global\let\ptexquoteright'}% active in plain's math mode +{\catcode`\'=\active +\global\let\ptexquoteright'}% Math-mode def from plain.tex. +\let\ptexraggedright=\raggedright % If this character appears in an error message or help string, it % starts a new line in the output. @@ -124,11 +118,10 @@ % Set up fixed words for English if not already set. \ifx\putwordAppendix\undefined \gdef\putwordAppendix{Appendix}\fi \ifx\putwordChapter\undefined \gdef\putwordChapter{Chapter}\fi -\ifx\putworderror\undefined \gdef\putworderror{error}\fi \ifx\putwordfile\undefined \gdef\putwordfile{file}\fi \ifx\putwordin\undefined \gdef\putwordin{in}\fi -\ifx\putwordIndexIsEmpty\undefined \gdef\putwordIndexIsEmpty{(Index is empty)}\fi -\ifx\putwordIndexNonexistent\undefined \gdef\putwordIndexNonexistent{(Index is nonexistent)}\fi +\ifx\putwordIndexIsEmpty\undefined \gdef\putwordIndexIsEmpty{(Index is empty)}\fi +\ifx\putwordIndexNonexistent\undefined \gdef\putwordIndexNonexistent{(Index is nonexistent)}\fi \ifx\putwordInfo\undefined \gdef\putwordInfo{Info}\fi \ifx\putwordInstanceVariableof\undefined \gdef\putwordInstanceVariableof{Instance Variable of}\fi \ifx\putwordMethodon\undefined \gdef\putwordMethodon{Method on}\fi @@ -162,14 +155,20 @@ \ifx\putwordDefopt\undefined \gdef\putwordDefopt{User Option}\fi \ifx\putwordDeffunc\undefined \gdef\putwordDeffunc{Function}\fi -% Give the space character the catcode for a space. -\def\spaceisspace{\catcode`\ =10\relax} - -% Likewise for ^^M, the end of line character. -\def\endlineisspace{\catcode13=10\relax} +% Since the category of space is not known, we have to be careful. +\chardef\spacecat = 10 +\def\spaceisspace{\catcode`\ =\spacecat} +% sometimes characters are active, so we need control sequences. +\chardef\colonChar = `\: +\chardef\commaChar = `\, \chardef\dashChar = `\- -\chardef\slashChar = `\/ +\chardef\dotChar = `\. +\chardef\exclamChar= `\! +\chardef\lquoteChar= `\` +\chardef\questChar = `\? +\chardef\rquoteChar= `\' +\chardef\semiChar = `\; \chardef\underChar = `\_ % Ignore a token. @@ -182,7 +181,7 @@ % Hyphenation fixes. \hyphenation{ Flor-i-da Ghost-script Ghost-view Mac-OS Post-Script - auto-ma-ti-cal-ly ap-pen-dix bit-map bit-maps + ap-pen-dix bit-map bit-maps data-base data-bases eshell fall-ing half-way long-est man-u-script man-u-scripts mini-buf-fer mini-buf-fers over-view par-a-digm par-a-digms rath-er rec-tan-gu-lar ro-bot-ics se-vere-ly set-up spa-ces @@ -191,6 +190,46 @@ wide-spread wrap-around } +% Margin to add to right of even pages, to left of odd pages. +\newdimen\bindingoffset +\newdimen\normaloffset +\newdimen\pagewidth \newdimen\pageheight + +% For a final copy, take out the rectangles +% that mark overfull boxes (in case you have decided +% that the text looks ok even though it passes the margin). +% +\def\finalout{\overfullrule=0pt} + +% @| inserts a changebar to the left of the current line. It should +% surround any changed text. This approach does *not* work if the +% change spans more than two lines of output. To handle that, we would +% have adopt a much more difficult approach (putting marks into the main +% vertical list for the beginning and end of each change). +% +\def\|{% + % \vadjust can only be used in horizontal mode. + \leavevmode + % + % Append this vertical mode material after the current line in the output. + \vadjust{% + % We want to insert a rule with the height and depth of the current + % leading; that is exactly what \strutbox is supposed to record. + \vskip-\baselineskip + % + % \vadjust-items are inserted at the left edge of the type. So + % the \llap here moves out into the left-hand margin. + \llap{% + % + % For a thicker or thinner bar, change the `1pt'. + \vrule height\baselineskip width1pt + % + % This is the space between the bar and the text. + \hskip 12pt + }% + }% +} + % Sometimes it is convenient to have everything in the transcript file % and nothing on the terminal. We don't just call \tracingall here, % since that produces some useless output on the terminal. We also make @@ -207,7 +246,7 @@ \tracingmacros2 \tracingrestores1 \showboxbreadth\maxdimen \showboxdepth\maxdimen - \ifx\eTeXversion\thisisundefined\else % etex gives us more logging + \ifx\eTeXversion\undefined\else % etex gives us more logging \tracingscantokens1 \tracingifs1 \tracinggroups1 @@ -218,13 +257,6 @@ \errorcontextlines16 }% -% @errormsg{MSG}. Do the index-like expansions on MSG, but if things -% aren't perfect, it's not the end of the world, being an error message, -% after all. -% -\def\errormsg{\begingroup \indexnofonts \doerrormsg} -\def\doerrormsg#1{\errmessage{#1}} - % add check for \lastpenalty to plain's definitions. If the last thing % we did was a \nobreak, we don't want to insert more space. % @@ -235,15 +267,7 @@ \def\bigbreak{\ifnum\lastpenalty<10000\par\ifdim\lastskip<\bigskipamount \removelastskip\penalty-200\bigskip\fi\fi} -% Output routine -% - -% For a final copy, take out the rectangles -% that mark overfull boxes (in case you have decided -% that the text looks ok even though it passes the margin). -% -\def\finalout{\overfullrule=0pt } - +% For @cropmarks command. % Do @cropmarks to get crop marks. % \newif\ifcropmarks @@ -266,18 +290,10 @@ % % Another complication is to let the user choose whether \thischapter % (\thissection) refers to the chapter (section) in effect at the top -% of a page, or that at the bottom of a page. - -% \domark is called twice inside \chapmacro, to add one -% mark before the section break, and one after. -% In the second call \prevchapterdefs is the same as \lastchapterdefs, -% and \prevsectiondefs is the same as \lastsectiondefs. -% Then if the page is not broken at the mark, some of the previous -% section appears on the page, and we can get the name of this section -% from \firstmark for @everyheadingmarks top. -% @everyheadingmarks bottom uses \botmark. -% -% See page 260 of The TeXbook. +% of a page, or that at the bottom of a page. The solution is +% described on page 260 of The TeXbook. It involves outputting two +% marks for the sectioning macros, one before the section break, and +% one after. I won't pretend I can describe this better than DEK... \def\domark{% \toks0=\expandafter{\lastchapterdefs}% \toks2=\expandafter{\lastsectiondefs}% @@ -285,15 +301,11 @@ \toks6=\expandafter{\prevsectiondefs}% \toks8=\expandafter{\lastcolordefs}% \mark{% - \the\toks0 \the\toks2 % 0: marks for @everyheadingmarks top - \noexpand\or \the\toks4 \the\toks6 % 1: for @everyheadingmarks bottom - \noexpand\else \the\toks8 % 2: color marks + \the\toks0 \the\toks2 + \noexpand\or \the\toks4 \the\toks6 + \noexpand\else \the\toks8 }% } - -% \gettopheadingmarks, \getbottomheadingmarks, -% \getcolormarks - extract needed part of mark. -% % \topmark doesn't work for the very first chapter (after the title % page or the contents), so we use \firstmark there -- this gets us % the mark with the chapter defs, unless the user sneaks in, e.g., @@ -309,67 +321,33 @@ % Avoid "undefined control sequence" errors. \def\lastchapterdefs{} \def\lastsectiondefs{} -\def\lastsection{} \def\prevchapterdefs{} \def\prevsectiondefs{} \def\lastcolordefs{} -% Margin to add to right of even pages, to left of odd pages. -\newdimen\bindingoffset -\newdimen\normaloffset -\newdimen\txipagewidth \newdimen\txipageheight - % Main output routine. -% \chardef\PAGE = 255 \output = {\onepageout{\pagecontents\PAGE}} \newbox\headlinebox \newbox\footlinebox -% \onepageout takes a vbox as an argument. -% \shipout a vbox for a single page, adding an optional header, footer, -% cropmarks, and footnote. This also causes index entries for this page -% to be written to the auxiliary files. -% +% \onepageout takes a vbox as an argument. Note that \pagecontents +% does insertions, but you have to call it yourself. \def\onepageout#1{% \ifcropmarks \hoffset=0pt \else \hoffset=\normaloffset \fi % \ifodd\pageno \advance\hoffset by \bindingoffset \else \advance\hoffset by -\bindingoffset\fi % - % Common context changes for both heading and footing. % Do this outside of the \shipout so @code etc. will be expanded in % the headline as they should be, not taken literally (outputting ''code). - \def\commmonheadfootline{\let\hsize=\txipagewidth \texinfochars} - % - % Retrieve the information for the headings from the marks in the page, - % and call Plain TeX's \makeheadline and \makefootline, which use the - % values in \headline and \footline. - % - % This is used to check if we are on the first page of a chapter. - \ifcase1\topmark\fi - \let\prevchaptername\thischaptername - \ifcase0\firstmark\fi - \let\curchaptername\thischaptername - % \ifodd\pageno \getoddheadingmarks \else \getevenheadingmarks \fi + \setbox\headlinebox = \vbox{\let\hsize=\pagewidth \makeheadline}% \ifodd\pageno \getoddfootingmarks \else \getevenfootingmarks \fi - % - \ifx\curchaptername\prevchaptername - \let\thischapterheading\thischapter - \else - % \thischapterheading is the same as \thischapter except it is blank - % for the first page of a chapter. This is to prevent the chapter name - % being shown twice. - \def\thischapterheading{}% - \fi - % - \global\setbox\headlinebox = \vbox{\commmonheadfootline \makeheadline}% - \global\setbox\footlinebox = \vbox{\commmonheadfootline \makefootline}% + \setbox\footlinebox = \vbox{\let\hsize=\pagewidth \makefootline}% % {% - % Set context for writing to auxiliary files like index files. % Have to do this stuff outside the \shipout because we want it to % take effect in \write's, yet the group defined by the \vbox ends % before the \shipout runs. @@ -378,10 +356,10 @@ \normalturnoffactive % \ in index entries must not stay \, e.g., if % the page break happens to be in the middle of an example. % We don't want .vr (or whatever) entries like this: - % \entry{{\indexbackslash }acronym}{32}{\code {\acronym}} + % \entry{{\tt \indexbackslash }acronym}{32}{\code {\acronym}} % "\acronym" won't work when it's read back in; % it needs to be - % {\code {{\backslashcurfont }acronym} + % {\code {{\tt \backslashcurfont }acronym} \shipout\vbox{% % Do this early so pdf references go to the beginning of the page. \ifpdfmakepagedest \pdfdest name{\the\pageno} xyz\fi @@ -439,8 +417,7 @@ \newinsert\margin \dimen\margin=\maxdimen -% Main part of page, including any footnotes -\def\pagebody#1{\vbox to\txipageheight{\boxmaxdepth=\maxdepth #1}} +\def\pagebody#1{\vbox to\pageheight{\boxmaxdepth=\maxdepth #1}} {\catcode`\@ =11 \gdef\pagecontents#1{\ifvoid\topins\else\unvbox\topins\fi % marginal hacks, juha@viisa.uucp (Juha Takala) @@ -462,13 +439,9 @@ \def\nsbot{\vbox {\hrule height\cornerlong depth\cornerthick width\cornerthick}} - -% Argument parsing - % Parse an argument, then pass it to #1. The argument is the rest of % the input line (except we remove a trailing comment). #1 should be a % macro which expects an ordinary undelimited TeX argument. -% For example, \def\foo{\parsearg\fooxxx}. % \def\parsearg{\parseargusing{}} \def\parseargusing#1#2{% @@ -487,11 +460,9 @@ }% } -% First remove any @comment, then any @c comment. Also remove a @texinfoc -% comment (see \scanmacro for details). Pass the result on to \argcheckspaces. +% First remove any @comment, then any @c comment. \def\argremovecomment#1\comment#2\ArgTerm{\argremovec #1\c\ArgTerm} -\def\argremovec#1\c#2\ArgTerm{\argremovetexinfoc #1\texinfoc\ArgTerm} -\def\argremovetexinfoc#1\texinfoc#2\ArgTerm{\argcheckspaces#1\^^M\ArgTerm} +\def\argremovec#1\c#2\ArgTerm{\argcheckspaces#1\^^M\ArgTerm} % Each occurrence of `\^^M' or `\^^M' is replaced by a single space. % @@ -526,13 +497,14 @@ % \def\finishparsearg#1 \ArgTerm{\expandafter\argtorun\expandafter{#1}} - -% \parseargdef - define a command taking an argument on the line -% % \parseargdef\foo{...} % is roughly equivalent to % \def\foo{\parsearg\Xfoo} % \def\Xfoo#1{...} +% +% Actually, I use \csname\string\foo\endcsname, ie. \\foo, as it is my +% favourite TeX trick. --kasal, 16nov03 + \def\parseargdef#1{% \expandafter \doparseargdef \csname\string#1\endcsname #1% } @@ -605,7 +577,7 @@ } \def\inenvironment#1{% \ifx#1\empty - outside of any environment% + out of any environment% \else in environment \expandafter\string#1% \fi @@ -617,7 +589,7 @@ \parseargdef\end{% \if 1\csname iscond.#1\endcsname \else - % The general wording of \badenverr may not be ideal. + % The general wording of \badenverr may not be ideal, but... --kasal, 06nov03 \expandafter\checkenv\csname#1\endcsname \csname E#1\endcsname \endgroup @@ -627,6 +599,85 @@ \newhelp\EMsimple{Press RETURN to continue.} +%% Simple single-character @ commands + +% @@ prints an @ +% Kludge this until the fonts are right (grr). +\def\@{{\tt\char64}} + +% This is turned off because it was never documented +% and you can use @w{...} around a quote to suppress ligatures. +%% Define @` and @' to be the same as ` and ' +%% but suppressing ligatures. +%\def\`{{`}} +%\def\'{{'}} + +% Used to generate quoted braces. +\def\mylbrace {{\tt\char123}} +\def\myrbrace {{\tt\char125}} +\let\{=\mylbrace +\let\}=\myrbrace +\begingroup + % Definitions to produce \{ and \} commands for indices, + % and @{ and @} for the aux/toc files. + \catcode`\{ = \other \catcode`\} = \other + \catcode`\[ = 1 \catcode`\] = 2 + \catcode`\! = 0 \catcode`\\ = \other + !gdef!lbracecmd[\{]% + !gdef!rbracecmd[\}]% + !gdef!lbraceatcmd[@{]% + !gdef!rbraceatcmd[@}]% +!endgroup + +% @comma{} to avoid , parsing problems. +\let\comma = , + +% Accents: @, @dotaccent @ringaccent @ubaraccent @udotaccent +% Others are defined by plain TeX: @` @' @" @^ @~ @= @u @v @H. +\let\, = \c +\let\dotaccent = \. +\def\ringaccent#1{{\accent23 #1}} +\let\tieaccent = \t +\let\ubaraccent = \b +\let\udotaccent = \d + +% Other special characters: @questiondown @exclamdown @ordf @ordm +% Plain TeX defines: @AA @AE @O @OE @L (plus lowercase versions) @ss. +\def\questiondown{?`} +\def\exclamdown{!`} +\def\ordf{\leavevmode\raise1ex\hbox{\selectfonts\lllsize \underbar{a}}} +\def\ordm{\leavevmode\raise1ex\hbox{\selectfonts\lllsize \underbar{o}}} + +% Dotless i and dotless j, used for accents. +\def\imacro{i} +\def\jmacro{j} +\def\dotless#1{% + \def\temp{#1}% + \ifx\temp\imacro \ifmmode\imath \else\ptexi \fi + \else\ifx\temp\jmacro \ifmmode\jmath \else\j \fi + \else \errmessage{@dotless can be used only with i or j}% + \fi\fi +} + +% The \TeX{} logo, as in plain, but resetting the spacing so that a +% period following counts as ending a sentence. (Idea found in latex.) +% +\edef\TeX{\TeX \spacefactor=1000 } + +% @LaTeX{} logo. Not quite the same results as the definition in +% latex.ltx, since we use a different font for the raised A; it's most +% convenient for us to use an explicitly smaller font, rather than using +% the \scriptstyle font (since we don't reset \scriptstyle and +% \scriptscriptstyle). +% +\def\LaTeX{% + L\kern-.36em + {\setbox0=\hbox{T}% + \vbox to \ht0{\hbox{\selectfonts\lllsize A}\vss}}% + \kern-.15em + \TeX +} + % Be sure we're in horizontal mode when doing a tie, since we make space % equivalent to this in @example-like environments. Otherwise, a space % at the beginning of a line will start with \penalty -- and @@ -643,7 +694,7 @@ \def\:{\spacefactor=1000 } % @* forces a line break. -\def\*{\unskip\hfil\break\hbox{}\ignorespaces} +\def\*{\hfil\break\hbox{}\ignorespaces} % @/ allows a line break. \let\/=\allowbreak @@ -668,7 +719,7 @@ \else\ifx\temp\offword \plainnonfrenchspacing \else \errhelp = \EMsimple - \errmessage{Unknown @frenchspacing option `\temp', must be on|off}% + \errmessage{Unknown @frenchspacing option `\temp', must be on/off}% \fi\fi } @@ -722,26 +773,21 @@ \endgraf % Not \par, as it may have been set to \lisppar. \global\dimen1 = \prevdepth \egroup % End the \vtop. - \addgroupbox - \prevdepth = \dimen1 - \checkinserts -} - -\def\addgroupbox{ % \dimen0 is the vertical size of the group's box. \dimen0 = \ht\groupbox \advance\dimen0 by \dp\groupbox % \dimen2 is how much space is left on the page (more or less). - \dimen2 = \txipageheight \advance\dimen2 by -\pagetotal + \dimen2 = \pageheight \advance\dimen2 by -\pagetotal % if the group doesn't fit on the current page, and it's a big big % group, force a page break. \ifdim \dimen0 > \dimen2 - \ifdim \pagetotal < \vfilllimit\txipageheight + \ifdim \pagetotal < \vfilllimit\pageheight \page \fi \fi \box\groupbox + \prevdepth = \dimen1 + \checkinserts } - % % TeX puts in an \escapechar (i.e., `@') at the beginning of the help % message, so this ends up printing `@group can only ...'. @@ -755,6 +801,15 @@ where each line of input produces a line of output.} \newdimen\mil \mil=0.001in +% Old definition--didn't work. +%\parseargdef\need{\par % +%% This method tries to make TeX break the page naturally +%% if the depth of the box does not fit. +%{\baselineskip=0pt% +%\vtop to #1\mil{\vfil}\kern -#1\mil\nobreak +%\prevdepth=-1000pt +%}} + \parseargdef\need{% % Ensure vertical mode, so we don't make a big box in the middle of a % paragraph. @@ -818,7 +873,7 @@ where each line of input produces a line of output.} % @inmargin{WHICH}{TEXT} puts TEXT in the WHICH margin next to the current % paragraph. For more general purposes, use the \margin insertion -% class. WHICH is `l' or `r'. Not documented, written for gawk manual. +% class. WHICH is `l' or `r'. % \newskip\inmarginspacing \inmarginspacing=1cm \def\strutdepth{\dp\strutbox} @@ -875,7 +930,6 @@ where each line of input produces a line of output.} \makevalueexpandable % we want to expand any @value in FILE. \turnoffactive % and allow special characters in the expansion \indexnofonts % Allow `@@' and other weird things in file names. - \wlog{texinfo.tex: doing @include of #1^^J}% \edef\temp{\noexpand\input #1 }% % % This trickery is to read FILE outside of a group, in case it makes @@ -911,7 +965,7 @@ where each line of input produces a line of output.} \def\popthisfilestack{\errthisfilestackempty} \def\errthisfilestackempty{\errmessage{Internal error: the stack of filenames is empty.}} -% + \def\thisfile{} % @center line @@ -919,48 +973,37 @@ where each line of input produces a line of output.} % \parseargdef\center{% \ifhmode - \let\centersub\centerH + \let\next\centerH \else - \let\centersub\centerV + \let\next\centerV \fi - \centersub{\hfil \ignorespaces#1\unskip \hfil}% - \let\centersub\relax % don't let the definition persist, just in case + \next{\hfil \ignorespaces#1\unskip \hfil}% } -\def\centerH#1{{% - \hfil\break - \advance\hsize by -\leftskip - \advance\hsize by -\rightskip - \line{#1}% - \break -}} -% -\newcount\centerpenalty -\def\centerV#1{% - % The idea here is the same as in \startdefun, \cartouche, etc.: if - % @center is the first thing after a section heading, we need to wipe - % out the negative parskip inserted by \sectionheading, but still - % prevent a page break here. - \centerpenalty = \lastpenalty - \ifnum\centerpenalty>10000 \vskip\parskip \fi - \ifnum\centerpenalty>9999 \penalty\centerpenalty \fi - \line{\kern\leftskip #1\kern\rightskip}% +\def\centerH#1{% + {% + \hfil\break + \advance\hsize by -\leftskip + \advance\hsize by -\rightskip + \line{#1}% + \break + }% } +\def\centerV#1{\line{\kern\leftskip #1\kern\rightskip}} % @sp n outputs n lines of vertical space -% + \parseargdef\sp{\vskip #1\baselineskip} % @comment ...line which is ignored... % @c is the same as @comment % @ignore ... @end ignore is another way to write a comment - -\def\c{\begingroup \catcode`\^^M=\active% +\def\comment{\begingroup \catcode`\^^M=\other% \catcode`\@=\other \catcode`\{=\other \catcode`\}=\other% -\cxxx} -{\catcode`\^^M=\active \gdef\cxxx#1^^M{\endgroup}} -% -\let\comment\c +\commentxxx} +{\catcode`\^^M=\other \gdef\commentxxx#1^^M{\endgroup}} + +\let\c=\comment % @paragraphindent NCHARS % We'll use ems for NCHARS, close enough. @@ -1031,23 +1074,172 @@ where each line of input produces a line of output.} % paragraph. % \gdef\dosuppressfirstparagraphindent{% - \gdef\indent {\restorefirstparagraphindent \indent}% - \gdef\noindent{\restorefirstparagraphindent \noindent}% - \global\everypar = {\kern -\parindent \restorefirstparagraphindent}% -} -% -\gdef\restorefirstparagraphindent{% - \global\let\indent = \ptexindent - \global\let\noindent = \ptexnoindent - \global\everypar = {}% + \gdef\indent{% + \restorefirstparagraphindent + \indent + }% + \gdef\noindent{% + \restorefirstparagraphindent + \noindent + }% + \global\everypar = {% + \kern -\parindent + \restorefirstparagraphindent + }% } +\gdef\restorefirstparagraphindent{% + \global \let \indent = \ptexindent + \global \let \noindent = \ptexnoindent + \global \everypar = {}% +} + + +% @asis just yields its argument. Used with @table, for example. +% +\def\asis#1{#1} + +% @math outputs its argument in math mode. +% +% One complication: _ usually means subscripts, but it could also mean +% an actual _ character, as in @math{@var{some_variable} + 1}. So make +% _ active, and distinguish by seeing if the current family is \slfam, +% which is what @var uses. +{ + \catcode`\_ = \active + \gdef\mathunderscore{% + \catcode`\_=\active + \def_{\ifnum\fam=\slfam \_\else\sb\fi}% + } +} +% Another complication: we want \\ (and @\) to output a \ character. +% FYI, plain.tex uses \\ as a temporary control sequence (why?), but +% this is not advertised and we don't care. Texinfo does not +% otherwise define @\. +% +% The \mathchar is class=0=ordinary, family=7=ttfam, position=5C=\. +\def\mathbackslash{\ifnum\fam=\ttfam \mathchar"075C \else\backslash \fi} +% +\def\math{% + \tex + \mathunderscore + \let\\ = \mathbackslash + \mathactive + % make the texinfo accent commands work in math mode + \let\"=\ddot + \let\'=\acute + \let\==\bar + \let\^=\hat + \let\`=\grave + \let\u=\breve + \let\v=\check + \let\~=\tilde + \let\dotaccent=\dot + $\finishmath +} +\def\finishmath#1{#1$\endgroup} % Close the group opened by \tex. + +% Some active characters (such as <) are spaced differently in math. +% We have to reset their definitions in case the @math was an argument +% to a command which sets the catcodes (such as @item or @section). +% +{ + \catcode`^ = \active + \catcode`< = \active + \catcode`> = \active + \catcode`+ = \active + \catcode`' = \active + \gdef\mathactive{% + \let^ = \ptexhat + \let< = \ptexless + \let> = \ptexgtr + \let+ = \ptexplus + \let' = \ptexquoteright + } +} + +% Some math mode symbols. +\def\bullet{$\ptexbullet$} +\def\geq{\ifmmode \ge\else $\ge$\fi} +\def\leq{\ifmmode \le\else $\le$\fi} +\def\minus{\ifmmode -\else $-$\fi} + +% @dots{} outputs an ellipsis using the current font. +% We do .5em per period so that it has the same spacing in the cm +% typewriter fonts as three actual period characters; on the other hand, +% in other typewriter fonts three periods are wider than 1.5em. So do +% whichever is larger. +% +\def\dots{% + \leavevmode + \setbox0=\hbox{...}% get width of three periods + \ifdim\wd0 > 1.5em + \dimen0 = \wd0 + \else + \dimen0 = 1.5em + \fi + \hbox to \dimen0{% + \hskip 0pt plus.25fil + .\hskip 0pt plus1fil + .\hskip 0pt plus1fil + .\hskip 0pt plus.5fil + }% +} + +% @enddots{} is an end-of-sentence ellipsis. +% +\def\enddots{% + \dots + \spacefactor=\endofsentencespacefactor +} + +% @comma{} is so commas can be inserted into text without messing up +% Texinfo's parsing. +% +\let\comma = , % @refill is a no-op. \let\refill=\relax -% @setfilename INFO-FILENAME - ignored -\let\setfilename=\comment +% If working on a large document in chapters, it is convenient to +% be able to disable indexing, cross-referencing, and contents, for test runs. +% This is done with @novalidate (before @setfilename). +% +\newif\iflinks \linkstrue % by default we want the aux files. +\let\novalidate = \linksfalse + +% @setfilename is done at the beginning of every texinfo file. +% So open here the files we need to have open while reading the input. +% This makes it possible to make a .fmt file for texinfo. +\def\setfilename{% + \fixbackslash % Turn off hack to swallow `\input texinfo'. + \iflinks + \tryauxfile + % Open the new aux file. TeX will close it automatically at exit. + \immediate\openout\auxfile=\jobname.aux + \fi % \openindices needs to do some work in any case. + \openindices + \let\setfilename=\comment % Ignore extra @setfilename cmds. + % + % If texinfo.cnf is present on the system, read it. + % Useful for site-wide @afourpaper, etc. + \openin 1 texinfo.cnf + \ifeof 1 \else \input texinfo.cnf \fi + \closein 1 + % + \comment % Ignore the actual filename. +} + +% Called from \setfilename. +% +\def\openindices{% + \newindex{cp}% + \newcodeindex{fn}% + \newcodeindex{vr}% + \newcodeindex{tp}% + \newcodeindex{ky}% + \newcodeindex{pg}% +} % @bye. \outer\def\bye{\pagealignmacro\tracingstats=1\ptexend} @@ -1065,94 +1257,14 @@ where each line of input produces a line of output.} \newtoks\toksC \newtoks\toksD \newbox\boxA -\newbox\boxB \newcount\countA \newif\ifpdf \newif\ifpdfmakepagedest -% -% For LuaTeX -% - -\newif\iftxiuseunicodedestname -\txiuseunicodedestnamefalse % For pdfTeX etc. - -\ifx\luatexversion\thisisundefined -\else - % Use Unicode destination names - \txiuseunicodedestnametrue - % Escape PDF strings with converting UTF-16 from UTF-8 - \begingroup - \catcode`\%=12 - \directlua{ - function UTF16oct(str) - tex.sprint(string.char(0x5c) .. '376' .. string.char(0x5c) .. '377') - for c in string.utfvalues(str) do - if c < 0x10000 then - tex.sprint( - string.format(string.char(0x5c) .. string.char(0x25) .. '03o' .. - string.char(0x5c) .. string.char(0x25) .. '03o', - (c / 256), (c % 256))) - else - c = c - 0x10000 - local c_hi = c / 1024 + 0xd800 - local c_lo = c % 1024 + 0xdc00 - tex.sprint( - string.format(string.char(0x5c) .. string.char(0x25) .. '03o' .. - string.char(0x5c) .. string.char(0x25) .. '03o' .. - string.char(0x5c) .. string.char(0x25) .. '03o' .. - string.char(0x5c) .. string.char(0x25) .. '03o', - (c_hi / 256), (c_hi % 256), - (c_lo / 256), (c_lo % 256))) - end - end - end - } - \endgroup - \def\pdfescapestrutfsixteen#1{\directlua{UTF16oct('\luaescapestring{#1}')}} - % Escape PDF strings without converting - \begingroup - \directlua{ - function PDFescstr(str) - for c in string.bytes(str) do - if c <= 0x20 or c >= 0x80 or c == 0x28 or c == 0x29 or c == 0x5c then - tex.sprint( - string.format(string.char(0x5c) .. string.char(0x25) .. '03o', - c)) - else - tex.sprint(string.char(c)) - end - end - end - } - \endgroup - \def\pdfescapestring#1{\directlua{PDFescstr('\luaescapestring{#1}')}} - \ifnum\luatexversion>84 - % For LuaTeX >= 0.85 - \def\pdfdest{\pdfextension dest} - \let\pdfoutput\outputmode - \def\pdfliteral{\pdfextension literal} - \def\pdfcatalog{\pdfextension catalog} - \def\pdftexversion{\numexpr\pdffeedback version\relax} - \let\pdfximage\saveimageresource - \let\pdfrefximage\useimageresource - \let\pdflastximage\lastsavedimageresourceindex - \def\pdfendlink{\pdfextension endlink\relax} - \def\pdfoutline{\pdfextension outline} - \def\pdfstartlink{\pdfextension startlink} - \def\pdffontattr{\pdfextension fontattr} - \def\pdfobj{\pdfextension obj} - \def\pdflastobj{\numexpr\pdffeedback lastobj\relax} - \let\pdfpagewidth\pagewidth - \let\pdfpageheight\pageheight - \edef\pdfhorigin{\pdfvariable horigin} - \edef\pdfvorigin{\pdfvariable vorigin} - \fi -\fi - % when pdftex is run in dvi mode, \pdfoutput is defined (so \pdfoutput=1 -% can be set). So we test for \relax and 0 as well as being undefined. -\ifx\pdfoutput\thisisundefined +% can be set). So we test for \relax and 0 as well as \undefined, +% borrowed from ifpdf.sty. +\ifx\pdfoutput\undefined \else \ifx\pdfoutput\relax \else @@ -1167,33 +1279,50 @@ where each line of input produces a line of output.} % for display in the outlines, and in other places. Thus, we have to % double any backslashes. Otherwise, a name like "\node" will be % interpreted as a newline (\n), followed by o, d, e. Not good. -% -% See http://www.ntg.nl/pipermail/ntg-pdftex/2004-July/000654.html and -% related messages. The final outcome is that it is up to the TeX user -% to double the backslashes and otherwise make the string valid, so -% that's what we do. pdftex 1.30.0 (ca.2005) introduced a primitive to -% do this reliably, so we use it. +% http://www.ntg.nl/pipermail/ntg-pdftex/2004-July/000654.html +% (and related messages, the final outcome is that it is up to the TeX +% user to double the backslashes and otherwise make the string valid, so +% that's what we do). -% #1 is a control sequence in which to do the replacements, -% which we \xdef. -\def\txiescapepdf#1{% - \ifx\pdfescapestring\thisisundefined - % No primitive available; should we give a warning or log? - % Many times it won't matter. - \xdef#1{#1}% - \else - % The expandable \pdfescapestring primitive escapes parentheses, - % backslashes, and other special chars. - \xdef#1{\pdfescapestring{#1}}% - \fi +% double active backslashes. +% +{\catcode`\@=0 \catcode`\\=\active + @gdef@activebackslashdouble{% + @catcode`@\=@active + @let\=@doublebackslash} } -\def\txiescapepdfutfsixteen#1{% - \ifx\pdfescapestrutfsixteen\thisisundefined - % No UTF-16 converting macro available. - \txiescapepdf{#1}% - \else - \xdef#1{\pdfescapestrutfsixteen{#1}}% - \fi + +% To handle parens, we must adopt a different approach, since parens are +% not active characters. hyperref.dtx (which has the same problem as +% us) handles it with this amazing macro to replace tokens, with minor +% changes for Texinfo. It is included here under the GPL by permission +% from the author, Heiko Oberdiek. +% +% #1 is the tokens to replace. +% #2 is the replacement. +% #3 is the control sequence with the string. +% +\def\HyPsdSubst#1#2#3{% + \def\HyPsdReplace##1#1##2\END{% + ##1% + \ifx\\##2\\% + \else + #2% + \HyReturnAfterFi{% + \HyPsdReplace##2\END + }% + \fi + }% + \xdef#3{\expandafter\HyPsdReplace#3#1\END}% +} +\long\def\HyReturnAfterFi#1\fi{\fi#1} + +% #1 is a control sequence in which to do the replacements. +\def\backslashparens#1{% + \xdef#1{#1}% redefine it as its expansion; the definition is simply + % \lastnode when called from \setref -> \pdfmkdest. + \HyPsdSubst{(}{\realbackslash(}{#1}% + \HyPsdSubst{)}{\realbackslash)}{#1}% } \newhelp\nopdfimagehelp{Texinfo supports .png, .jpg, .jpeg, and .pdf images @@ -1203,17 +1332,15 @@ output) for that.)} \ifpdf % - % Color manipulation macros using ideas from pdfcolor.tex, + % 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. The dark red here is dark enough to print on paper as - % nearly black, but still distinguishable for online viewing. We use - % black by default, though. + % of actual black. \def\rgbDarkRed{0.50 0.09 0.12} \def\rgbBlack{0 0 0} % - % rg sets the color for filling (usual text, etc.); - % RG sets the color for stroking (thin rules, e.g., normal _'s). + % 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 rg #1 RG}} % % Set color, and create a mark which defines \thiscolor accordingly, @@ -1254,34 +1381,32 @@ output) for that.)} % % #1 is image name, #2 width (might be empty/whitespace), #3 height (ditto). \def\dopdfimage#1#2#3{% - \def\pdfimagewidth{#2}\setbox0 = \hbox{\ignorespaces #2}% - \def\pdfimageheight{#3}\setbox2 = \hbox{\ignorespaces #3}% + \def\imagewidth{#2}\setbox0 = \hbox{\ignorespaces #2}% + \def\imageheight{#3}\setbox2 = \hbox{\ignorespaces #3}% % - % pdftex (and the PDF format) support .pdf, .png, .jpg (among - % others). Let's try in that order, PDF first since if - % someone has a scalable image, presumably better to use that than a - % bitmap. + % pdftex (and the PDF format) support .png, .jpg, .pdf (among + % others). Let's try in that order. \let\pdfimgext=\empty \begingroup - \openin 1 #1.pdf \ifeof 1 - \openin 1 #1.PDF \ifeof 1 - \openin 1 #1.png \ifeof 1 - \openin 1 #1.jpg \ifeof 1 - \openin 1 #1.jpeg \ifeof 1 - \openin 1 #1.JPG \ifeof 1 + \openin 1 #1.png \ifeof 1 + \openin 1 #1.jpg \ifeof 1 + \openin 1 #1.jpeg \ifeof 1 + \openin 1 #1.JPG \ifeof 1 + \openin 1 #1.pdf \ifeof 1 + \openin 1 #1.PDF \ifeof 1 \errhelp = \nopdfimagehelp \errmessage{Could not find image file #1 for pdf}% - \else \gdef\pdfimgext{JPG}% + \else \gdef\pdfimgext{PDF}% \fi - \else \gdef\pdfimgext{jpeg}% + \else \gdef\pdfimgext{pdf}% \fi - \else \gdef\pdfimgext{jpg}% + \else \gdef\pdfimgext{JPG}% \fi - \else \gdef\pdfimgext{png}% + \else \gdef\pdfimgext{jpeg}% \fi - \else \gdef\pdfimgext{PDF}% + \else \gdef\pdfimgext{jpg}% \fi - \else \gdef\pdfimgext{pdf}% + \else \gdef\pdfimgext{png}% \fi \closein 1 \endgroup @@ -1293,8 +1418,8 @@ output) for that.)} \else \immediate\pdfximage \fi - \ifdim \wd0 >0pt width \pdfimagewidth \fi - \ifdim \wd2 >0pt height \pdfimageheight \fi + \ifdim \wd0 >0pt width \imagewidth \fi + \ifdim \wd2 >0pt height \imageheight \fi \ifnum\pdftexversion<13 #1.\pdfimgext \else @@ -1304,83 +1429,25 @@ output) for that.)} \pdfrefximage \pdflastximage \fi} % - \def\setpdfdestname#1{{% + \def\pdfmkdest#1{{% % We have to set dummies so commands such as @code, and characters % such as \, aren't expanded when present in a section title. \indexnofonts - \makevalueexpandable \turnoffactive - \iftxiuseunicodedestname - \ifx \declaredencoding \latone - % Pass through Latin-1 characters. - % LuaTeX with byte wise I/O converts Latin-1 characters to Unicode. - \else - \ifx \declaredencoding \utfeight - % Pass through Unicode characters. - \else - % Use ASCII approximations in destination names. - \passthroughcharsfalse - \fi - \fi - \else - % Use ASCII approximations in destination names. - \passthroughcharsfalse - \fi + \activebackslashdouble + \makevalueexpandable \def\pdfdestname{#1}% - \txiescapepdf\pdfdestname - }} - % - \def\setpdfoutlinetext#1{{% - \indexnofonts - \makevalueexpandable - \turnoffactive - \ifx \declaredencoding \latone - % The PDF format can use an extended form of Latin-1 in bookmark - % strings. See Appendix D of the PDF Reference, Sixth Edition, for - % the "PDFDocEncoding". - \passthroughcharstrue - % Pass through Latin-1 characters. - % LuaTeX: Convert to Unicode - % pdfTeX: Use Latin-1 as PDFDocEncoding - \def\pdfoutlinetext{#1}% - \else - \ifx \declaredencoding \utfeight - \ifx\luatexversion\thisisundefined - % For pdfTeX with UTF-8. - % TODO: the PDF format can use UTF-16 in bookmark strings, - % but the code for this isn't done yet. - % Use ASCII approximations. - \passthroughcharsfalse - \def\pdfoutlinetext{#1}% - \else - % For LuaTeX with UTF-8. - % Pass through Unicode characters for title texts. - \passthroughcharstrue - \def\pdfoutlinetext{#1}% - \fi - \else - % For non-Latin-1 or non-UTF-8 encodings. - % Use ASCII approximations. - \passthroughcharsfalse - \def\pdfoutlinetext{#1}% - \fi - \fi - % LuaTeX: Convert to UTF-16 - % pdfTeX: Use Latin-1 as PDFDocEncoding - \txiescapepdfutfsixteen\pdfoutlinetext - }} - % - \def\pdfmkdest#1{% - \setpdfdestname{#1}% + \backslashparens\pdfdestname \safewhatsit{\pdfdest name{\pdfdestname} xyz}% - } + }} % % used to mark target names; must be expandable. \def\pdfmkpgn#1{#1} % - % by default, use black for everything. - \def\urlcolor{\rgbBlack} - \def\linkcolor{\rgbBlack} + % by default, use a color that is dark enough to print on paper as + % nearly black, but still distinguishable for online viewing. + \def\urlcolor{\rgbDarkRed} + \def\linkcolor{\rgbDarkRed} \def\endlink{\setcolor{\maincolor}\pdfendlink} % % Adding outlines to PDF; macros for calculating structure of outlines @@ -1402,19 +1469,29 @@ output) for that.)} % page number. We could generate a destination for the section % text in the case where a section has no node, but it doesn't % seem worth the trouble, since most documents are normally structured. - \setpdfoutlinetext{#1} - \setpdfdestname{#3} - \ifx\pdfdestname\empty - \def\pdfdestname{#4}% + \def\pdfoutlinedest{#3}% + \ifx\pdfoutlinedest\empty + \def\pdfoutlinedest{#4}% + \else + % Doubled backslashes in the name. + {\activebackslashdouble \xdef\pdfoutlinedest{#3}% + \backslashparens\pdfoutlinedest}% \fi % - \pdfoutline goto name{\pdfmkpgn{\pdfdestname}}#2{\pdfoutlinetext}% + % Also double the backslashes in the display string. + {\activebackslashdouble \xdef\pdfoutlinetext{#1}% + \backslashparens\pdfoutlinetext}% + % + \pdfoutline goto name{\pdfmkpgn{\pdfoutlinedest}}#2{\pdfoutlinetext}% } % \def\pdfmakeoutlines{% \begingroup + % Thanh's hack / proper braces in bookmarks + \edef\mylbrace{\iftrue \string{\else}\fi}\let\{=\mylbrace + \edef\myrbrace{\iffalse{\else\string}\fi}\let\}=\myrbrace + % % Read toc silently, to get counts of subentries for \pdfoutline. - \def\partentry##1##2##3##4{}% ignore parts in the outlines \def\numchapentry##1##2##3##4{% \def\thischapnum{##2}% \def\thissecnum{0}% @@ -1468,41 +1545,25 @@ output) for that.)} % Latin 2 (0xea) gets translated to a | character. Info from % Staszek Wawrykiewicz, 19 Jan 2004 04:09:24 +0100. % - % TODO this right, we have to translate 8-bit characters to - % their "best" equivalent, based on the @documentencoding. Too - % much work for too little return. Just use the ASCII equivalents - % we use for the index sort strings. - % + % xx to do this right, we have to translate 8-bit characters to + % their "best" equivalent, based on the @documentencoding. Right + % now, I guess we'll just let the pdf reader have its way. \indexnofonts \setupdatafile - % We can have normal brace characters in the PDF outlines, unlike - % Texinfo index files. So set that up. - \def\{{\lbracecharliteral}% - \def\}{\rbracecharliteral}% \catcode`\\=\active \otherbackslash \input \tocreadfilename \endgroup } - {\catcode`[=1 \catcode`]=2 - \catcode`{=\other \catcode`}=\other - \gdef\lbracecharliteral[{]% - \gdef\rbracecharliteral[}]% - ] % \def\skipspaces#1{\def\PP{#1}\def\D{|}% \ifx\PP\D\let\nextsp\relax \else\let\nextsp\skipspaces - \addtokens{\filename}{\PP}% - \advance\filenamelength by 1 + \ifx\p\space\else\addtokens{\filename}{\PP}% + \advance\filenamelength by 1 + \fi \fi \nextsp} - \def\getfilename#1{% - \filenamelength=0 - % If we don't expand the argument now, \skipspaces will get - % snagged on things like "@value{foo}". - \edef\temp{#1}% - \expandafter\skipspaces\temp|\relax - } + \def\getfilename#1{\filenamelength=0\expandafter\skipspaces#1|\relax} \ifnum\pdftexversion < 14 \let \startlink \pdfannotlink \else @@ -1563,298 +1624,45 @@ output) for that.)} \let\pdfmakeoutlines = \relax \fi % \ifx\pdfoutput -% -% For XeTeX -% -\ifx\XeTeXrevision\thisisundefined -\else - % - % XeTeX version check - % - \ifnum\strcmp{\the\XeTeXversion\XeTeXrevision}{0.99996}>-1 - % TeX Live 2016 contains XeTeX 0.99996 and xdvipdfmx 20160307. - % It can use the `dvipdfmx:config' special (from TeX Live SVN r40941). - % For avoiding PDF destination name replacement, we use this special - % instead of xdvipdfmx's command line option `-C 0x0010'. - \special{dvipdfmx:config C 0x0010} - % XeTeX 0.99995+ comes with xdvipdfmx 20160307+. - % It can handle Unicode destination names for PDF. - \txiuseunicodedestnametrue - \else - % XeTeX < 0.99996 (TeX Live < 2016) cannot use the - % `dvipdfmx:config' special. - % So for avoiding PDF destination name replacement, - % xdvipdfmx's command line option `-C 0x0010' is necessary. - % - % XeTeX < 0.99995 can not handle Unicode destination names for PDF - % because xdvipdfmx 20150315 has a UTF-16 conversion issue. - % It is fixed by xdvipdfmx 20160106 (TeX Live SVN r39753). - \txiuseunicodedestnamefalse - \fi - % - % Color support - % - \def\rgbDarkRed{0.50 0.09 0.12} - \def\rgbBlack{0 0 0} - % - \def\pdfsetcolor#1{\special{pdf:scolor [#1]}} - % - % Set color, and create a mark which defines \thiscolor accordingly, - % so that \makeheadline knows which color to restore. - \def\setcolor#1{% - \xdef\lastcolordefs{\gdef\noexpand\thiscolor{#1}}% - \domark - \pdfsetcolor{#1}% - } - % - \def\maincolor{\rgbBlack} - \pdfsetcolor{\maincolor} - \edef\thiscolor{\maincolor} - \def\lastcolordefs{} - % - \def\makefootline{% - \baselineskip24pt - \line{\pdfsetcolor{\maincolor}\the\footline}% - } - % - \def\makeheadline{% - \vbox to 0pt{% - \vskip-22.5pt - \line{% - \vbox to8.5pt{}% - % Extract \thiscolor definition from the marks. - \getcolormarks - % Typeset the headline with \maincolor, then restore the color. - \pdfsetcolor{\maincolor}\the\headline\pdfsetcolor{\thiscolor}% - }% - \vss - }% - \nointerlineskip - } - % - % PDF outline support - % - % Emulate pdfTeX primitive - \def\pdfdest name#1 xyz{% - \special{pdf:dest (#1) [@thispage /XYZ @xpos @ypos null]}% - } - % - \def\setpdfdestname#1{{% - % We have to set dummies so commands such as @code, and characters - % such as \, aren't expanded when present in a section title. - \indexnofonts - \makevalueexpandable - \turnoffactive - \iftxiuseunicodedestname - % Pass through Unicode characters. - \else - % Use ASCII approximations in destination names. - \passthroughcharsfalse - \fi - \def\pdfdestname{#1}% - \txiescapepdf\pdfdestname - }} - % - \def\setpdfoutlinetext#1{{% - \turnoffactive - % Always use Unicode characters in title texts. - \def\pdfoutlinetext{#1}% - % For XeTeX, xdvipdfmx converts to UTF-16. - % So we do not convert. - \txiescapepdf\pdfoutlinetext - }} - % - \def\pdfmkdest#1{% - \setpdfdestname{#1}% - \safewhatsit{\pdfdest name{\pdfdestname} xyz}% - } - % - % by default, use black for everything. - \def\urlcolor{\rgbBlack} - \def\linkcolor{\rgbBlack} - \def\endlink{\setcolor{\maincolor}\pdfendlink} - % - \def\dopdfoutline#1#2#3#4{% - \setpdfoutlinetext{#1} - \setpdfdestname{#3} - \ifx\pdfdestname\empty - \def\pdfdestname{#4}% - \fi - % - \special{pdf:out [-] #2 << /Title (\pdfoutlinetext) /A - << /S /GoTo /D (\pdfdestname) >> >> }% - } - % - \def\pdfmakeoutlines{% - \begingroup - % - % For XeTeX, counts of subentries are not necessary. - % Therefore, we read toc only once. - % - % We use node names as destinations. - \def\partentry##1##2##3##4{}% ignore parts in the outlines - \def\numchapentry##1##2##3##4{% - \dopdfoutline{##1}{1}{##3}{##4}}% - \def\numsecentry##1##2##3##4{% - \dopdfoutline{##1}{2}{##3}{##4}}% - \def\numsubsecentry##1##2##3##4{% - \dopdfoutline{##1}{3}{##3}{##4}}% - \def\numsubsubsecentry##1##2##3##4{% - \dopdfoutline{##1}{4}{##3}{##4}}% - % - \let\appentry\numchapentry% - \let\appsecentry\numsecentry% - \let\appsubsecentry\numsubsecentry% - \let\appsubsubsecentry\numsubsubsecentry% - \let\unnchapentry\numchapentry% - \let\unnsecentry\numsecentry% - \let\unnsubsecentry\numsubsecentry% - \let\unnsubsubsecentry\numsubsubsecentry% - % - % For XeTeX, xdvipdfmx converts strings to UTF-16. - % Therefore, the encoding and the language may not be considered. - % - \indexnofonts - \setupdatafile - % We can have normal brace characters in the PDF outlines, unlike - % Texinfo index files. So set that up. - \def\{{\lbracecharliteral}% - \def\}{\rbracecharliteral}% - \catcode`\\=\active \otherbackslash - \input \tocreadfilename - \endgroup - } - {\catcode`[=1 \catcode`]=2 - \catcode`{=\other \catcode`}=\other - \gdef\lbracecharliteral[{]% - \gdef\rbracecharliteral[}]% - ] - \special{pdf:docview << /PageMode /UseOutlines >> } - % ``\special{pdf:tounicode ...}'' is not necessary - % because xdvipdfmx converts strings from UTF-8 to UTF-16 without it. - % However, due to a UTF-16 conversion issue of xdvipdfmx 20150315, - % ``\special{pdf:dest ...}'' cannot handle non-ASCII strings. - % It is fixed by xdvipdfmx 20160106 (TeX Live SVN r39753). -% - \def\skipspaces#1{\def\PP{#1}\def\D{|}% - \ifx\PP\D\let\nextsp\relax - \else\let\nextsp\skipspaces - \addtokens{\filename}{\PP}% - \advance\filenamelength by 1 - \fi - \nextsp} - \def\getfilename#1{% - \filenamelength=0 - % If we don't expand the argument now, \skipspaces will get - % snagged on things like "@value{foo}". - \edef\temp{#1}% - \expandafter\skipspaces\temp|\relax - } - % make a live url in pdf output. - \def\pdfurl#1{% - \begingroup - % it seems we really need yet another set of dummies; have not - % tried to figure out what each command should do in the context - % of @url. for now, just make @/ a no-op, that's the only one - % people have actually reported a problem with. - % - \normalturnoffactive - \def\@{@}% - \let\/=\empty - \makevalueexpandable - % do we want to go so far as to use \indexnofonts instead of just - % special-casing \var here? - \def\var##1{##1}% - % - \leavevmode\setcolor{\urlcolor}% - \special{pdf:bann << /Border [0 0 0] - /Subtype /Link /A << /S /URI /URI (#1) >> >>}% - \endgroup} - \def\endlink{\setcolor{\maincolor}\special{pdf:eann}} - \def\pdfgettoks#1.{\setbox\boxA=\hbox{\toksA={#1.}\toksB={}\maketoks}} - \def\addtokens#1#2{\edef\addtoks{\noexpand#1={\the#1#2}}\addtoks} - \def\adn#1{\addtokens{\toksC}{#1}\global\countA=1\let\next=\maketoks} - \def\poptoks#1#2|ENDTOKS|{\let\first=#1\toksD={#1}\toksA={#2}} - \def\maketoks{% - \expandafter\poptoks\the\toksA|ENDTOKS|\relax - \ifx\first0\adn0 - \else\ifx\first1\adn1 \else\ifx\first2\adn2 \else\ifx\first3\adn3 - \else\ifx\first4\adn4 \else\ifx\first5\adn5 \else\ifx\first6\adn6 - \else\ifx\first7\adn7 \else\ifx\first8\adn8 \else\ifx\first9\adn9 - \else - \ifnum0=\countA\else\makelink\fi - \ifx\first.\let\next=\done\else - \let\next=\maketoks - \addtokens{\toksB}{\the\toksD} - \ifx\first,\addtokens{\toksB}{\space}\fi - \fi - \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi - \next} - \def\makelink{\addtokens{\toksB}% - {\noexpand\pdflink{\the\toksC}}\toksC={}\global\countA=0} - \def\pdflink#1{% - \special{pdf:bann << /Border [0 0 0] - /Type /Annot /Subtype /Link /A << /S /GoTo /D (#1) >> >>}% - \setcolor{\linkcolor}#1\endlink} - \def\done{\edef\st{\global\noexpand\toksA={\the\toksB}}\st} -% - % - % @image support - % - % #1 is image name, #2 width (might be empty/whitespace), #3 height (ditto). - \def\doxeteximage#1#2#3{% - \def\xeteximagewidth{#2}\setbox0 = \hbox{\ignorespaces #2}% - \def\xeteximageheight{#3}\setbox2 = \hbox{\ignorespaces #3}% - % - % XeTeX (and the PDF format) supports .pdf, .png, .jpg (among - % others). Let's try in that order, PDF first since if - % someone has a scalable image, presumably better to use that than a - % bitmap. - \let\xeteximgext=\empty - \begingroup - \openin 1 #1.pdf \ifeof 1 - \openin 1 #1.PDF \ifeof 1 - \openin 1 #1.png \ifeof 1 - \openin 1 #1.jpg \ifeof 1 - \openin 1 #1.jpeg \ifeof 1 - \openin 1 #1.JPG \ifeof 1 - \errmessage{Could not find image file #1 for XeTeX}% - \else \gdef\xeteximgext{JPG}% - \fi - \else \gdef\xeteximgext{jpeg}% - \fi - \else \gdef\xeteximgext{jpg}% - \fi - \else \gdef\xeteximgext{png}% - \fi - \else \gdef\xeteximgext{PDF}% - \fi - \else \gdef\xeteximgext{pdf}% - \fi - \closein 1 - \endgroup - % - \def\xetexpdfext{pdf}% - \ifx\xeteximgext\xetexpdfext - \XeTeXpdffile "#1".\xeteximgext "" - \else - \def\xetexpdfext{PDF}% - \ifx\xeteximgext\xetexpdfext - \XeTeXpdffile "#1".\xeteximgext "" - \else - \XeTeXpicfile "#1".\xeteximgext "" - \fi - \fi - \ifdim \wd0 >0pt width \xeteximagewidth \fi - \ifdim \wd2 >0pt height \xeteximageheight \fi \relax - } -\fi - - -% \message{fonts,} +% Change the current font style to #1, remembering it in \curfontstyle. +% For now, we do not accumulate font styles: @b{@i{foo}} prints foo in +% italics, not bold italics. +% +\def\setfontstyle#1{% + \def\curfontstyle{#1}% not as a control sequence, because we are \edef'd. + \csname ten#1\endcsname % change the current font +} + +% Select #1 fonts with the current style. +% +\def\selectfonts#1{\csname #1fonts\endcsname \csname\curfontstyle\endcsname} + +\def\rm{\fam=0 \setfontstyle{rm}} +\def\it{\fam=\itfam \setfontstyle{it}} +\def\sl{\fam=\slfam \setfontstyle{sl}} +\def\bf{\fam=\bffam \setfontstyle{bf}}\def\bfstylename{bf} +\def\tt{\fam=\ttfam \setfontstyle{tt}} + +% Unfortunately, we have to override this for titles and the like, since +% in those cases "rm" is bold. Sigh. +\def\rmisbold{\rm\def\curfontstyle{bf}} + +% Texinfo sort of supports the sans serif font style, which plain TeX does not. +% So we set up a \sf. +\newfam\sffam +\def\sf{\fam=\sffam \setfontstyle{sf}} +\let\li = \sf % Sometimes we call it \li, not \sf. + +% We don't need math for this font style. +\def\ttsl{\setfontstyle{ttsl}} + + +% Default leading. +\newdimen\textleading \textleading = 13.2pt + % Set the baselineskip to #1, and the lineskip and strut size % correspondingly. There is no deep meaning behind these magic numbers % used as factors; they just match (closely enough) what Knuth defined. @@ -1866,7 +1674,6 @@ output) for that.)} % can get a sort of poor man's double spacing by redefining this. \def\baselinefactor{1} % -\newdimen\textleading \def\setleading#1{% \dimen0 = #1\relax \normalbaselineskip = \baselinefactor\dimen0 @@ -1888,7 +1695,7 @@ output) for that.)} % if we are producing pdf, and we have \pdffontattr, then define cmaps. % (\pdffontattr was introduced many years ago, but people still run % older pdftex's; it's easy to conditionalize, so we do.) -\ifpdf \ifx\pdffontattr\thisisundefined \else +\ifpdf \ifx\pdffontattr\undefined \else \begingroup \catcode`\^^M=\active \def^^M{^^J}% Output line endings as the ^^J char. \catcode`\%=12 \immediate\pdfobj stream {%!PS-Adobe-3.0 Resource-CMap @@ -2139,34 +1946,28 @@ end \fi\fi -% Set the font macro #1 to the font named \fontprefix#2. +% Set the font macro #1 to the font named #2, adding on the +% specified font prefix (normally `cm'). % #3 is the font's design size, #4 is a scale factor, #5 is the CMap -% encoding (only OT1, OT1IT and OT1TT are allowed, or empty to omit). -% Example: -% #1 = \textrm -% #2 = \rmshape -% #3 = 10 -% #4 = \mainmagstep -% #5 = OT1 -% +% encoding (currently only OT1, OT1IT and OT1TT are allowed, pass +% empty to omit). \def\setfont#1#2#3#4#5{% \font#1=\fontprefix#2#3 scaled #4 \csname cmap#5\endcsname#1% } % This is what gets called when #5 of \setfont is empty. \let\cmap\gobble -% -% (end of cmaps) +% emacs-page end of cmaps % Use cm as the default font prefix. % To specify the font prefix, you must define \fontprefix % before you read in texinfo.tex. -\ifx\fontprefix\thisisundefined +\ifx\fontprefix\undefined \def\fontprefix{cm} \fi % Support font families that don't use the same naming scheme as CM. \def\rmshape{r} -\def\rmbshape{bx} % where the normal face is bold +\def\rmbshape{bx} %where the normal face is bold \def\bfshape{b} \def\bxshape{bx} \def\ttshape{tt} @@ -2181,7 +1982,8 @@ end \def\scshape{csc} \def\scbshape{csc} -% Definitions for a main text size of 11pt. (The default in Texinfo.) +% Definitions for a main text size of 11pt. This is the default in +% Texinfo. % \def\definetextfontsizexi{% % Text fonts (11.2pt, magstep1). @@ -2202,10 +2004,8 @@ end % A few fonts for @defun names and args. \setfont\defbf\bfshape{10}{\magstep1}{OT1} \setfont\deftt\ttshape{10}{\magstep1}{OT1TT} -\setfont\defsl\slshape{10}{\magstep1}{OT1TT} \setfont\defttsl\ttslshape{10}{\magstep1}{OT1TT} -\def\df{\let\ttfont=\deftt \let\bffont = \defbf -\let\ttslfont=\defttsl \let\slfont=\defsl \bf} +\def\df{\let\tentt=\deftt \let\tenbf = \defbf \let\tenttsl=\defttsl \bf} % Fonts for indices, footnotes, small examples (9pt). \def\smallnominalsize{9pt} @@ -2235,20 +2035,6 @@ end \font\smallersy=cmsy8 \def\smallerecsize{0800} -% Fonts for math mode superscripts (7pt). -\def\sevennominalsize{7pt} -\setfont\sevenrm\rmshape{7}{1000}{OT1} -\setfont\seventt\ttshape{10}{700}{OT1TT} -\setfont\sevenbf\bfshape{10}{700}{OT1} -\setfont\sevenit\itshape{7}{1000}{OT1IT} -\setfont\sevensl\slshape{10}{700}{OT1} -\setfont\sevensf\sfshape{10}{700}{OT1} -\setfont\sevensc\scshape{10}{700}{OT1} -\setfont\seventtsl\ttslshape{10}{700}{OT1TT} -\font\seveni=cmmi7 -\font\sevensy=cmsy7 -\def\sevenecsize{0700} - % Fonts for title page (20.4pt): \def\titlenominalsize{20pt} \setfont\titlerm\rmbshape{12}{\magstep3}{OT1} @@ -2280,7 +2066,6 @@ end % Section fonts (14.4pt). \def\secnominalsize{14pt} \setfont\secrm\rmbshape{12}{\magstep1}{OT1} -\setfont\secrmnotbold\rmshape{12}{\magstep1}{OT1} \setfont\secit\itbshape{10}{\magstep2}{OT1IT} \setfont\secsl\slbshape{10}{\magstep2}{OT1} \setfont\sectt\ttbshape{12}{\magstep1}{OT1TT} @@ -2306,7 +2091,7 @@ end \font\ssecsy=cmsy10 scaled 1315 \def\ssececsize{1200} -% Reduced fonts for @acronym in text (10pt). +% Reduced fonts for @acro in text (10pt). \def\reducednominalsize{10pt} \setfont\reducedrm\rmshape{10}{1000}{OT1} \setfont\reducedtt\ttshape{10}{1000}{OT1TT} @@ -2320,10 +2105,10 @@ end \font\reducedsy=cmsy10 \def\reducedecsize{1000} -\textleading = 13.2pt % line spacing for 11pt CM -\textfonts % reset the current fonts +% reset the current fonts +\textfonts \rm -} % end of 11pt text font size definitions, \definetextfontsizexi +} % end of 11pt text font size definitions % Definitions to make the main text be 10pt Computer Modern, with @@ -2350,10 +2135,8 @@ end % A few fonts for @defun names and args. \setfont\defbf\bfshape{10}{\magstephalf}{OT1} \setfont\deftt\ttshape{10}{\magstephalf}{OT1TT} -\setfont\defsl\slshape{10}{\magstephalf}{OT1TT} \setfont\defttsl\ttslshape{10}{\magstephalf}{OT1TT} -\def\df{\let\ttfont=\deftt \let\bffont = \defbf -\let\slfont=\defsl \let\ttslfont=\defttsl \bf} +\def\df{\let\tentt=\deftt \let\tenbf = \defbf \let\tenttsl=\defttsl \bf} % Fonts for indices, footnotes, small examples (9pt). \def\smallnominalsize{9pt} @@ -2383,20 +2166,6 @@ end \font\smallersy=cmsy8 \def\smallerecsize{0800} -% Fonts for math mode superscripts (7pt). -\def\sevennominalsize{7pt} -\setfont\sevenrm\rmshape{7}{1000}{OT1} -\setfont\seventt\ttshape{10}{700}{OT1TT} -\setfont\sevenbf\bfshape{10}{700}{OT1} -\setfont\sevenit\itshape{7}{1000}{OT1IT} -\setfont\sevensl\slshape{10}{700}{OT1} -\setfont\sevensf\sfshape{10}{700}{OT1} -\setfont\sevensc\scshape{10}{700}{OT1} -\setfont\seventtsl\ttslshape{10}{700}{OT1TT} -\font\seveni=cmmi7 -\font\sevensy=cmsy7 -\def\sevenecsize{0700} - % Fonts for title page (20.4pt): \def\titlenominalsize{20pt} \setfont\titlerm\rmbshape{12}{\magstep3}{OT1} @@ -2453,7 +2222,7 @@ end \font\ssecsy=cmsy10 \def\ssececsize{1000} -% Reduced fonts for @acronym in text (9pt). +% Reduced fonts for @acro in text (9pt). \def\reducednominalsize{9pt} \setfont\reducedrm\rmshape{9}{1000}{OT1} \setfont\reducedtt\ttshape{9}{1000}{OT1TT} @@ -2467,30 +2236,25 @@ end \font\reducedsy=cmsy9 \def\reducedecsize{0900} -\divide\parskip by 2 % reduce space between paragraphs -\textleading = 12pt % line spacing for 10pt CM -\textfonts % reset the current fonts -\rm -} % end of 10pt text font size definitions, \definetextfontsizex +% reduce space between paragraphs +\divide\parskip by 2 -% Fonts for short table of contents. -\setfont\shortcontrm\rmshape{12}{1000}{OT1} -\setfont\shortcontbf\bfshape{10}{\magstep1}{OT1} % no cmb12 -\setfont\shortcontsl\slshape{12}{1000}{OT1} -\setfont\shortconttt\ttshape{12}{1000}{OT1TT} +% reset the current fonts +\textfonts +\rm +} % end of 10pt text font size definitions % We provide the user-level command % @fonttextsize 10 % (or 11) to redefine the text font size. pt is assumed. % -\def\xiword{11} \def\xword{10} -\def\xwordpt{10pt} +\def\xiword{11} % \parseargdef\fonttextsize{% \def\textsizearg{#1}% - %\wlog{doing @fonttextsize \textsizearg}% + \wlog{doing @fonttextsize \textsizearg}% % % Set \globaldefs so that documents can use this inside @tex, since % makeinfo 4.8 does not support it, but we need it nonetheless. @@ -2505,121 +2269,102 @@ end \endgroup } -% -% Change the current font style to #1, remembering it in \curfontstyle. -% For now, we do not accumulate font styles: @b{@i{foo}} prints foo in -% italics, not bold italics. -% -\def\setfontstyle#1{% - \def\curfontstyle{#1}% not as a control sequence, because we are \edef'd. - \csname #1font\endcsname % change the current font -} - -\def\rm{\fam=0 \setfontstyle{rm}} -\def\it{\fam=\itfam \setfontstyle{it}} -\def\sl{\fam=\slfam \setfontstyle{sl}} -\def\bf{\fam=\bffam \setfontstyle{bf}}\def\bfstylename{bf} -\def\tt{\fam=\ttfam \setfontstyle{tt}} - -% Texinfo sort of supports the sans serif font style, which plain TeX does not. -% So we set up a \sf. -\newfam\sffam -\def\sf{\fam=\sffam \setfontstyle{sf}} - -% We don't need math for this font style. -\def\ttsl{\setfontstyle{ttsl}} - % In order for the font changes to affect most math symbols and letters, -% we have to define the \textfont of the standard families. -% We don't bother to reset \scriptscriptfont; awaiting user need. +% we have to define the \textfont of the standard families. Since +% texinfo doesn't allow for producing subscripts and superscripts except +% in the main text, we don't bother to reset \scriptfont and +% \scriptscriptfont (which would also require loading a lot more fonts). % \def\resetmathfonts{% - \textfont0=\rmfont \textfont1=\ifont \textfont2=\syfont - \textfont\itfam=\itfont \textfont\slfam=\slfont \textfont\bffam=\bffont - \textfont\ttfam=\ttfont \textfont\sffam=\sffont - % - % Fonts for superscript. Note that the 7pt fonts are used regardless - % of the current font size. - \scriptfont0=\sevenrm \scriptfont1=\seveni \scriptfont2=\sevensy - \scriptfont\itfam=\sevenit \scriptfont\slfam=\sevensl - \scriptfont\bffam=\sevenbf \scriptfont\ttfam=\seventt - \scriptfont\sffam=\sevensf + \textfont0=\tenrm \textfont1=\teni \textfont2=\tensy + \textfont\itfam=\tenit \textfont\slfam=\tensl \textfont\bffam=\tenbf + \textfont\ttfam=\tentt \textfont\sffam=\tensf } -% - -% The font-changing commands (all called \...fonts) redefine the meanings -% of \STYLEfont, instead of just \STYLE. We do this because \STYLE needs -% to also set the current \fam for math mode. Our \STYLE (e.g., \rm) -% commands hardwire \STYLEfont to set the current font. -% -% The fonts used for \ifont are for "math italics" (\itfont is for italics -% in regular text). \syfont is also used in math mode only. +% The font-changing commands redefine the meanings of \tenSTYLE, instead +% of just \STYLE. We do this because \STYLE needs to also set the +% current \fam for math mode. Our \STYLE (e.g., \rm) commands hardwire +% \tenSTYLE to set the current font. % % Each font-changing command also sets the names \lsize (one size lower) -% and \lllsize (three sizes lower). These relative commands are used -% in, e.g., the LaTeX logo and acronyms. +% and \lllsize (three sizes lower). These relative commands are used in +% the LaTeX logo and acronyms. % % This all needs generalizing, badly. % +\def\textfonts{% + \let\tenrm=\textrm \let\tenit=\textit \let\tensl=\textsl + \let\tenbf=\textbf \let\tentt=\texttt \let\smallcaps=\textsc + \let\tensf=\textsf \let\teni=\texti \let\tensy=\textsy + \let\tenttsl=\textttsl + \def\curfontsize{text}% + \def\lsize{reduced}\def\lllsize{smaller}% + \resetmathfonts \setleading{\textleading}} +\def\titlefonts{% + \let\tenrm=\titlerm \let\tenit=\titleit \let\tensl=\titlesl + \let\tenbf=\titlebf \let\tentt=\titlett \let\smallcaps=\titlesc + \let\tensf=\titlesf \let\teni=\titlei \let\tensy=\titlesy + \let\tenttsl=\titlettsl + \def\curfontsize{title}% + \def\lsize{chap}\def\lllsize{subsec}% + \resetmathfonts \setleading{25pt}} +\def\titlefont#1{{\titlefonts\rmisbold #1}} +\def\chapfonts{% + \let\tenrm=\chaprm \let\tenit=\chapit \let\tensl=\chapsl + \let\tenbf=\chapbf \let\tentt=\chaptt \let\smallcaps=\chapsc + \let\tensf=\chapsf \let\teni=\chapi \let\tensy=\chapsy + \let\tenttsl=\chapttsl + \def\curfontsize{chap}% + \def\lsize{sec}\def\lllsize{text}% + \resetmathfonts \setleading{19pt}} +\def\secfonts{% + \let\tenrm=\secrm \let\tenit=\secit \let\tensl=\secsl + \let\tenbf=\secbf \let\tentt=\sectt \let\smallcaps=\secsc + \let\tensf=\secsf \let\teni=\seci \let\tensy=\secsy + \let\tenttsl=\secttsl + \def\curfontsize{sec}% + \def\lsize{subsec}\def\lllsize{reduced}% + \resetmathfonts \setleading{16pt}} +\def\subsecfonts{% + \let\tenrm=\ssecrm \let\tenit=\ssecit \let\tensl=\ssecsl + \let\tenbf=\ssecbf \let\tentt=\ssectt \let\smallcaps=\ssecsc + \let\tensf=\ssecsf \let\teni=\sseci \let\tensy=\ssecsy + \let\tenttsl=\ssecttsl + \def\curfontsize{ssec}% + \def\lsize{text}\def\lllsize{small}% + \resetmathfonts \setleading{15pt}} +\let\subsubsecfonts = \subsecfonts +\def\reducedfonts{% + \let\tenrm=\reducedrm \let\tenit=\reducedit \let\tensl=\reducedsl + \let\tenbf=\reducedbf \let\tentt=\reducedtt \let\reducedcaps=\reducedsc + \let\tensf=\reducedsf \let\teni=\reducedi \let\tensy=\reducedsy + \let\tenttsl=\reducedttsl + \def\curfontsize{reduced}% + \def\lsize{small}\def\lllsize{smaller}% + \resetmathfonts \setleading{10.5pt}} +\def\smallfonts{% + \let\tenrm=\smallrm \let\tenit=\smallit \let\tensl=\smallsl + \let\tenbf=\smallbf \let\tentt=\smalltt \let\smallcaps=\smallsc + \let\tensf=\smallsf \let\teni=\smalli \let\tensy=\smallsy + \let\tenttsl=\smallttsl + \def\curfontsize{small}% + \def\lsize{smaller}\def\lllsize{smaller}% + \resetmathfonts \setleading{10.5pt}} +\def\smallerfonts{% + \let\tenrm=\smallerrm \let\tenit=\smallerit \let\tensl=\smallersl + \let\tenbf=\smallerbf \let\tentt=\smallertt \let\smallcaps=\smallersc + \let\tensf=\smallersf \let\teni=\smalleri \let\tensy=\smallersy + \let\tenttsl=\smallerttsl + \def\curfontsize{smaller}% + \def\lsize{smaller}\def\lllsize{smaller}% + \resetmathfonts \setleading{9.5pt}} -\def\assignfonts#1{% - \expandafter\let\expandafter\rmfont\csname #1rm\endcsname - \expandafter\let\expandafter\itfont\csname #1it\endcsname - \expandafter\let\expandafter\slfont\csname #1sl\endcsname - \expandafter\let\expandafter\bffont\csname #1bf\endcsname - \expandafter\let\expandafter\ttfont\csname #1tt\endcsname - \expandafter\let\expandafter\smallcaps\csname #1sc\endcsname - \expandafter\let\expandafter\sffont \csname #1sf\endcsname - \expandafter\let\expandafter\ifont \csname #1i\endcsname - \expandafter\let\expandafter\syfont \csname #1sy\endcsname - \expandafter\let\expandafter\ttslfont\csname #1ttsl\endcsname -} - -\newif\ifrmisbold - -% Select smaller font size with the current style. Used to change font size -% in, e.g., the LaTeX logo and acronyms. If we are using bold fonts for -% normal roman text, also use bold fonts for roman text in the smaller size. -\def\switchtolllsize{% - \expandafter\assignfonts\expandafter{\lllsize}% - \ifrmisbold - \let\rmfont\bffont - \fi - \csname\curfontstyle\endcsname -}% - -\def\switchtolsize{% - \expandafter\assignfonts\expandafter{\lsize}% - \ifrmisbold - \let\rmfont\bffont - \fi - \csname\curfontstyle\endcsname -}% - -\def\definefontsetatsize#1#2#3#4#5{% -\expandafter\def\csname #1fonts\endcsname{% - \def\curfontsize{#1}% - \def\lsize{#2}\def\lllsize{#3}% - \csname rmisbold#5\endcsname - \assignfonts{#1}% - \resetmathfonts - \setleading{#4}% -}} - -\definefontsetatsize{text} {reduced}{smaller}{\textleading}{false} -\definefontsetatsize{title} {chap} {subsec} {27pt} {true} -\definefontsetatsize{chap} {sec} {text} {19pt} {true} -\definefontsetatsize{sec} {subsec} {reduced}{17pt} {true} -\definefontsetatsize{ssec} {text} {small} {15pt} {true} -\definefontsetatsize{reduced}{small} {smaller}{10.5pt}{false} -\definefontsetatsize{small} {smaller}{smaller}{10.5pt}{false} -\definefontsetatsize{smaller}{smaller}{smaller}{9.5pt} {false} - -\def\titlefont#1{{\titlefonts\rm #1}} -\let\subsecfonts = \ssecfonts -\let\subsubsecfonts = \ssecfonts +% Fonts for short table of contents. +\setfont\shortcontrm\rmshape{12}{1000}{OT1} +\setfont\shortcontbf\bfshape{10}{\magstep1}{OT1} % no cmb12 +\setfont\shortcontsl\slshape{12}{1000}{OT1} +\setfont\shortconttt\ttshape{12}{1000}{OT1TT} % Define these just so they can be easily changed for other fonts. \def\angleleft{$\langle$} @@ -2657,11 +2402,26 @@ end % Markup style infrastructure. \defmarkupstylesetup\INITMACRO will % define and register \INITMACRO to be called on markup style changes. % \INITMACRO can check \currentmarkupstyle for the innermost -% style. +% style and the set of \ifmarkupSTYLE switches for all styles +% currently in effect. +\newif\ifmarkupvar +\newif\ifmarkupsamp +\newif\ifmarkupkey +%\newif\ifmarkupfile % @file == @samp. +%\newif\ifmarkupoption % @option == @samp. +\newif\ifmarkupcode +\newif\ifmarkupkbd +%\newif\ifmarkupenv % @env == @code. +%\newif\ifmarkupcommand % @command == @code. +\newif\ifmarkuptex % @tex (and part of @math, for now). +\newif\ifmarkupexample +\newif\ifmarkupverb +\newif\ifmarkupverbatim \let\currentmarkupstyle\empty \def\setupmarkupstyle#1{% + \csname markup#1true\endcsname \def\currentmarkupstyle{#1}% \markupstylesetup } @@ -2676,14 +2436,12 @@ end % Markup style setup for left and right quotes. \defmarkupstylesetup\markupsetuplq{% - \expandafter\let\expandafter \temp - \csname markupsetuplq\currentmarkupstyle\endcsname + \expandafter\let\expandafter \temp \csname markupsetuplq\currentmarkupstyle\endcsname \ifx\temp\relax \markupsetuplqdefault \else \temp \fi } \defmarkupstylesetup\markupsetuprq{% - \expandafter\let\expandafter \temp - \csname markupsetuprq\currentmarkupstyle\endcsname + \expandafter\let\expandafter \temp \csname markupsetuprq\currentmarkupstyle\endcsname \ifx\temp\relax \markupsetuprqdefault \else \temp \fi } @@ -2696,42 +2454,35 @@ end \gdef\markupsetcodequoteleft{\let`\codequoteleft} \gdef\markupsetcodequoteright{\let'\codequoteright} + +\gdef\markupsetnoligaturesquoteleft{\let`\noligaturesquoteleft} } \let\markupsetuplqcode \markupsetcodequoteleft \let\markupsetuprqcode \markupsetcodequoteright -% \let\markupsetuplqexample \markupsetcodequoteleft \let\markupsetuprqexample \markupsetcodequoteright -% -\let\markupsetuplqkbd \markupsetcodequoteleft -\let\markupsetuprqkbd \markupsetcodequoteright -% -\let\markupsetuplqsamp \markupsetcodequoteleft -\let\markupsetuprqsamp \markupsetcodequoteright -% \let\markupsetuplqverb \markupsetcodequoteleft \let\markupsetuprqverb \markupsetcodequoteright -% \let\markupsetuplqverbatim \markupsetcodequoteleft \let\markupsetuprqverbatim \markupsetcodequoteright -% Allow an option to not use regular directed right quote/apostrophe -% (char 0x27), but instead the undirected quote from cmtt (char 0x0d). -% The undirected quote is ugly, so don't make it the default, but it -% works for pasting with more pdf viewers (at least evince), the -% lilypond developers report. xpdf does work with the regular 0x27. +\let\markupsetuplqsamp \markupsetnoligaturesquoteleft +\let\markupsetuplqkbd \markupsetnoligaturesquoteleft + +% Allow an option to not replace quotes with a regular directed right +% quote/apostrophe (char 0x27), but instead use the undirected quote +% from cmtt (char 0x0d). The undirected quote is ugly, so don't make it +% the default, but it works for pasting with more pdf viewers (at least +% evince), the lilypond developers report. xpdf does work with the +% regular 0x27. % \def\codequoteright{% - \ifmonospace - \expandafter\ifx\csname SETtxicodequoteundirected\endcsname\relax - \expandafter\ifx\csname SETcodequoteundirected\endcsname\relax - '% - \else \char'15 \fi + \expandafter\ifx\csname SETtxicodequoteundirected\endcsname\relax + \expandafter\ifx\csname SETcodequoteundirected\endcsname\relax + '% \else \char'15 \fi - \else - '% - \fi + \else \char'15 \fi } % % and a similar option for the left quote char vs. a grave accent. @@ -2739,47 +2490,13 @@ end % the code environments to do likewise. % \def\codequoteleft{% - \ifmonospace - \expandafter\ifx\csname SETtxicodequotebacktick\endcsname\relax - \expandafter\ifx\csname SETcodequotebacktick\endcsname\relax - % [Knuth] pp. 380,381,391 - % \relax disables Spanish ligatures ?` and !` of \tt font. - \relax`% - \else \char'22 \fi + \expandafter\ifx\csname SETtxicodequotebacktick\endcsname\relax + \expandafter\ifx\csname SETcodequotebacktick\endcsname\relax + % [Knuth] pp. 380,381,391 + % \relax disables Spanish ligatures ?` and !` of \tt font. + \relax`% \else \char'22 \fi - \else - \relax`% - \fi -} - -% Commands to set the quote options. -% -\parseargdef\codequoteundirected{% - \def\temp{#1}% - \ifx\temp\onword - \expandafter\let\csname SETtxicodequoteundirected\endcsname - = t% - \else\ifx\temp\offword - \expandafter\let\csname SETtxicodequoteundirected\endcsname - = \relax - \else - \errhelp = \EMsimple - \errmessage{Unknown @codequoteundirected value `\temp', must be on|off}% - \fi\fi -} -% -\parseargdef\codequotebacktick{% - \def\temp{#1}% - \ifx\temp\onword - \expandafter\let\csname SETtxicodequotebacktick\endcsname - = t% - \else\ifx\temp\offword - \expandafter\let\csname SETtxicodequotebacktick\endcsname - = \relax - \else - \errhelp = \EMsimple - \errmessage{Unknown @codequotebacktick value `\temp', must be on|off}% - \fi\fi + \else \char'22 \fi } % [Knuth] pp. 380,381,391, disable Spanish ligatures ?` and !` of \tt font. @@ -2788,49 +2505,27 @@ end % Count depth in font-changes, for error checks \newcount\fontdepth \fontdepth=0 -% Font commands. +%% Add scribe-like font environments, plus @l for inline lisp (usually sans +%% serif) and @ii for TeX italic -% #1 is the font command (\sl or \it), #2 is the text to slant. -% If we are in a monospaced environment, however, 1) always use \ttsl, -% and 2) do not add an italic correction. -\def\dosmartslant#1#2{% - \ifusingtt - {{\ttsl #2}\let\next=\relax}% - {\def\next{{#1#2}\futurelet\next\smartitaliccorrection}}% - \next -} -\def\smartslanted{\dosmartslant\sl} -\def\smartitalic{\dosmartslant\it} +% \smartitalic{ARG} outputs arg in italics, followed by an italic correction +% unless the following character is such as not to need one. +\def\smartitalicx{\ifx\next,\else\ifx\next-\else\ifx\next.\else + \ptexslash\fi\fi\fi} +\def\smartslanted#1{{\ifusingtt\ttsl\sl #1}\futurelet\next\smartitalicx} +\def\smartitalic#1{{\ifusingtt\ttsl\it #1}\futurelet\next\smartitalicx} -% Output an italic correction unless \next (presumed to be the following -% character) is such as not to need one. -\def\smartitaliccorrection{% - \ifx\next,% - \else\ifx\next-% - \else\ifx\next.% - \else\ifx\next\.% - \else\ifx\next\comma% - \else\ptexslash - \fi\fi\fi\fi\fi - \aftersmartic -} - -% Unconditional use \ttsl, and no ic. @var is set to this for defuns. -\def\ttslanted#1{{\ttsl #1}} +% like \smartslanted except unconditionally uses \ttsl. +% @var is set to this for defun arguments. +\def\ttslanted#1{{\ttsl #1}\futurelet\next\smartitalicx} % @cite is like \smartslanted except unconditionally use \sl. We never want % ttsl for book titles, do we? -\def\cite#1{{\sl #1}\futurelet\next\smartitaliccorrection} - -\def\aftersmartic{} -\def\var#1{% - \let\saveaftersmartic = \aftersmartic - \def\aftersmartic{\null\let\aftersmartic=\saveaftersmartic}% - \smartslanted{#1}% -} +\def\cite#1{{\sl #1}\futurelet\next\smartitalicx} \let\i=\smartitalic \let\slanted=\smartslanted +\def\var#1{{\setupmarkupstyle{var}\smartslanted{#1}}} \let\dfn=\smartslanted \let\emph=\smartitalic @@ -2859,8 +2554,8 @@ end % \catcode`@=11 \def\plainfrenchspacing{% - \sfcode`\.=\@m \sfcode`\?=\@m \sfcode`\!=\@m - \sfcode`\:=\@m \sfcode`\;=\@m \sfcode`\,=\@m + \sfcode\dotChar =\@m \sfcode\questChar=\@m \sfcode\exclamChar=\@m + \sfcode\colonChar=\@m \sfcode\semiChar =\@m \sfcode\commaChar =\@m \def\endofsentencespacefactor{1000}% for @. and friends } \def\plainnonfrenchspacing{% @@ -2880,326 +2575,6 @@ end % @samp. \def\samp#1{{\setupmarkupstyle{samp}\lq\tclose{#1}\rq\null}} -% @indicateurl is \samp, that is, with quotes. -\let\indicateurl=\samp - -% @code (and similar) prints in typewriter, but with spaces the same -% size as normal in the surrounding text, without hyphenation, etc. -% This is a subroutine for that. -\def\tclose#1{% - {% - % Change normal interword space to be same as for the current font. - \spaceskip = \fontdimen2\font - % - % Switch to typewriter. - \tt - % - % But `\ ' produces the large typewriter interword space. - \def\ {{\spaceskip = 0pt{} }}% - % - % Turn off hyphenation. - \nohyphenation - % - \rawbackslash - \plainfrenchspacing - #1% - }% - \null % reset spacefactor to 1000 -} - -% We *must* turn on hyphenation at `-' and `_' in @code. -% (But see \codedashfinish below.) -% Otherwise, it is too hard to avoid overfull hboxes -% in the Emacs manual, the Library manual, etc. -% -% Unfortunately, TeX uses one parameter (\hyphenchar) to control -% both hyphenation at - and hyphenation within words. -% We must therefore turn them both off (\tclose does that) -% and arrange explicitly to hyphenate at a dash. -- rms. -{ - \catcode`\-=\active \catcode`\_=\active - \catcode`\'=\active \catcode`\`=\active - \global\let'=\rq \global\let`=\lq % default definitions - % - \global\def\code{\begingroup - \setupmarkupstyle{code}% - % The following should really be moved into \setupmarkupstyle handlers. - \catcode\dashChar=\active \catcode\underChar=\active - \ifallowcodebreaks - \let-\codedash - \let_\codeunder - \else - \let-\normaldash - \let_\realunder - \fi - % Given -foo (with a single dash), we do not want to allow a break - % after the hyphen. - \global\let\codedashprev=\codedash - % - \codex - } - % - \gdef\codedash{\futurelet\next\codedashfinish} - \gdef\codedashfinish{% - \normaldash % always output the dash character itself. - % - % Now, output a discretionary to allow a line break, unless - % (a) the next character is a -, or - % (b) the preceding character is a -. - % E.g., given --posix, we do not want to allow a break after either -. - % Given --foo-bar, we do want to allow a break between the - and the b. - \ifx\next\codedash \else - \ifx\codedashprev\codedash - \else \discretionary{}{}{}\fi - \fi - % we need the space after the = for the case when \next itself is a - % space token; it would get swallowed otherwise. As in @code{- a}. - \global\let\codedashprev= \next - } -} -\def\normaldash{-} -% -\def\codex #1{\tclose{#1}\endgroup} - -\def\codeunder{% - % this is all so @math{@code{var_name}+1} can work. In math mode, _ - % is "active" (mathcode"8000) and \normalunderscore (or \char95, etc.) - % will therefore expand the active definition of _, which is us - % (inside @code that is), therefore an endless loop. - \ifusingtt{\ifmmode - \mathchar"075F % class 0=ordinary, family 7=ttfam, pos 0x5F=_. - \else\normalunderscore \fi - \discretionary{}{}{}}% - {\_}% -} - -% An additional complication: the above will allow breaks after, e.g., -% each of the four underscores in __typeof__. This is bad. -% @allowcodebreaks provides a document-level way to turn breaking at - -% and _ on and off. -% -\newif\ifallowcodebreaks \allowcodebreakstrue - -\def\keywordtrue{true} -\def\keywordfalse{false} - -\parseargdef\allowcodebreaks{% - \def\txiarg{#1}% - \ifx\txiarg\keywordtrue - \allowcodebreakstrue - \else\ifx\txiarg\keywordfalse - \allowcodebreaksfalse - \else - \errhelp = \EMsimple - \errmessage{Unknown @allowcodebreaks option `\txiarg', must be true|false}% - \fi\fi -} - -% For @command, @env, @file, @option quotes seem unnecessary, -% so use \code rather than \samp. -\let\command=\code -\let\env=\code -\let\file=\code -\let\option=\code - -% @uref (abbreviation for `urlref') aka @url takes an optional -% (comma-separated) second argument specifying the text to display and -% an optional third arg as text to display instead of (rather than in -% addition to) the url itself. First (mandatory) arg is the url. - -% TeX-only option to allow changing PDF output to show only the second -% arg (if given), and not the url (which is then just the link target). -\newif\ifurefurlonlylink - -% The main macro is \urefbreak, which allows breaking at expected -% places within the url. (There used to be another version, which -% didn't support automatic breaking.) -\def\urefbreak{\begingroup \urefcatcodes \dourefbreak} -\let\uref=\urefbreak -% -\def\dourefbreak#1{\urefbreakfinish #1,,,\finish} -\def\urefbreakfinish#1,#2,#3,#4\finish{% doesn't work in @example - \unsepspaces - \pdfurl{#1}% - \setbox0 = \hbox{\ignorespaces #3}% - \ifdim\wd0 > 0pt - \unhbox0 % third arg given, show only that - \else - \setbox0 = \hbox{\ignorespaces #2}% look for second arg - \ifdim\wd0 > 0pt - \ifpdf - % For pdfTeX and LuaTeX - \ifurefurlonlylink - % PDF plus option to not display url, show just arg - \unhbox0 - \else - % PDF, normally display both arg and url for consistency, - % visibility, if the pdf is eventually used to print, etc. - \unhbox0\ (\urefcode{#1})% - \fi - \else - \ifx\XeTeXrevision\thisisundefined - \unhbox0\ (\urefcode{#1})% DVI, always show arg and url - \else - % For XeTeX - \ifurefurlonlylink - % PDF plus option to not display url, show just arg - \unhbox0 - \else - % PDF, normally display both arg and url for consistency, - % visibility, if the pdf is eventually used to print, etc. - \unhbox0\ (\urefcode{#1})% - \fi - \fi - \fi - \else - \urefcode{#1}% only url given, so show it - \fi - \fi - \endlink -\endgroup} - -% Allow line breaks around only a few characters (only). -\def\urefcatcodes{% - \catcode`\&=\active \catcode`\.=\active - \catcode`\#=\active \catcode`\?=\active - \catcode`\/=\active -} -{ - \urefcatcodes - % - \global\def\urefcode{\begingroup - \setupmarkupstyle{code}% - \urefcatcodes - \let&\urefcodeamp - \let.\urefcodedot - \let#\urefcodehash - \let?\urefcodequest - \let/\urefcodeslash - \codex - } - % - % By default, they are just regular characters. - \global\def&{\normalamp} - \global\def.{\normaldot} - \global\def#{\normalhash} - \global\def?{\normalquest} - \global\def/{\normalslash} -} - -% we put a little stretch before and after the breakable chars, to help -% line breaking of long url's. The unequal skips make look better in -% cmtt at least, especially for dots. -\def\urefprestretchamount{.13em} -\def\urefpoststretchamount{.1em} -\def\urefprestretch{\urefprebreak \hskip0pt plus\urefprestretchamount\relax} -\def\urefpoststretch{\urefpostbreak \hskip0pt plus\urefprestretchamount\relax} -% -\def\urefcodeamp{\urefprestretch \&\urefpoststretch} -\def\urefcodedot{\urefprestretch .\urefpoststretch} -\def\urefcodehash{\urefprestretch \#\urefpoststretch} -\def\urefcodequest{\urefprestretch ?\urefpoststretch} -\def\urefcodeslash{\futurelet\next\urefcodeslashfinish} -{ - \catcode`\/=\active - \global\def\urefcodeslashfinish{% - \urefprestretch \slashChar - % Allow line break only after the final / in a sequence of - % slashes, to avoid line break between the slashes in http://. - \ifx\next/\else \urefpoststretch \fi - } -} - -% One more complication: by default we'll break after the special -% characters, but some people like to break before the special chars, so -% allow that. Also allow no breaking at all, for manual control. -% -\parseargdef\urefbreakstyle{% - \def\txiarg{#1}% - \ifx\txiarg\wordnone - \def\urefprebreak{\nobreak}\def\urefpostbreak{\nobreak} - \else\ifx\txiarg\wordbefore - \def\urefprebreak{\allowbreak}\def\urefpostbreak{\nobreak} - \else\ifx\txiarg\wordafter - \def\urefprebreak{\nobreak}\def\urefpostbreak{\allowbreak} - \else - \errhelp = \EMsimple - \errmessage{Unknown @urefbreakstyle setting `\txiarg'}% - \fi\fi\fi -} -\def\wordafter{after} -\def\wordbefore{before} -\def\wordnone{none} - -\urefbreakstyle after - -% @url synonym for @uref, since that's how everyone uses it. -% -\let\url=\uref - -% rms does not like angle brackets --karl, 17may97. -% So now @email is just like @uref, unless we are pdf. -% -%\def\email#1{\angleleft{\tt #1}\angleright} -\ifpdf - \def\email#1{\doemail#1,,\finish} - \def\doemail#1,#2,#3\finish{\begingroup - \unsepspaces - \pdfurl{mailto:#1}% - \setbox0 = \hbox{\ignorespaces #2}% - \ifdim\wd0>0pt\unhbox0\else\code{#1}\fi - \endlink - \endgroup} -\else - \ifx\XeTeXrevision\thisisundefined - \let\email=\uref - \else - \def\email#1{\doemail#1,,\finish} - \def\doemail#1,#2,#3\finish{\begingroup - \unsepspaces - \pdfurl{mailto:#1}% - \setbox0 = \hbox{\ignorespaces #2}% - \ifdim\wd0>0pt\unhbox0\else\code{#1}\fi - \endlink - \endgroup} - \fi -\fi - -% @kbdinputstyle -- arg is `distinct' (@kbd uses slanted tty font always), -% `example' (@kbd uses ttsl only inside of @example and friends), -% or `code' (@kbd uses normal tty font always). -\parseargdef\kbdinputstyle{% - \def\txiarg{#1}% - \ifx\txiarg\worddistinct - \gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\ttsl}% - \else\ifx\txiarg\wordexample - \gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\tt}% - \else\ifx\txiarg\wordcode - \gdef\kbdexamplefont{\tt}\gdef\kbdfont{\tt}% - \else - \errhelp = \EMsimple - \errmessage{Unknown @kbdinputstyle setting `\txiarg'}% - \fi\fi\fi -} -\def\worddistinct{distinct} -\def\wordexample{example} -\def\wordcode{code} - -% Default is `distinct'. -\kbdinputstyle distinct - -% @kbd is like @code, except that if the argument is just one @key command, -% then @kbd has no effect. -\def\kbd#1{{\def\look{#1}\expandafter\kbdsub\look??\par}} - -\def\xkey{\key} -\def\kbdsub#1#2#3\par{% - \def\one{#1}\def\three{#3}\def\threex{??}% - \ifx\one\xkey\ifx\threex\three \key{#2}% - \else{\tclose{\kbdfont\setupmarkupstyle{kbd}\look}}\fi - \else{\tclose{\kbdfont\setupmarkupstyle{kbd}\look}}\fi -} - % definition of @key that produces a lozenge. Doesn't adjust to text size. %\setfont\keyrm\rmshape{8}{1000}{OT1} %\font\keysy=cmsy9 @@ -3219,6 +2594,140 @@ end \ifmonospace\else\tt\fi #1}\null} +% ctrl is no longer a Texinfo command. +\def\ctrl #1{{\tt \rawbackslash \hat}#1} + +% @file, @option are the same as @samp. +\let\file=\samp +\let\option=\samp + +% @code is a modification of @t, +% which makes spaces the same size as normal in the surrounding text. +\def\tclose#1{% + {% + % Change normal interword space to be same as for the current font. + \spaceskip = \fontdimen2\font + % + % Switch to typewriter. + \tt + % + % But `\ ' produces the large typewriter interword space. + \def\ {{\spaceskip = 0pt{} }}% + % + % Turn off hyphenation. + \nohyphenation + % + \rawbackslash + \plainfrenchspacing + #1% + }% + \null +} + +% We *must* turn on hyphenation at `-' and `_' in @code. +% Otherwise, it is too hard to avoid overfull hboxes +% in the Emacs manual, the Library manual, etc. + +% Unfortunately, TeX uses one parameter (\hyphenchar) to control +% both hyphenation at - and hyphenation within words. +% We must therefore turn them both off (\tclose does that) +% and arrange explicitly to hyphenate at a dash. +% -- rms. +{ + \catcode`\-=\active \catcode`\_=\active + \catcode`\'=\active \catcode`\`=\active + \global\let'=\rq \global\let`=\lq % default definitions + % + \global\def\code{\begingroup + \setupmarkupstyle{code}% + % The following should really be moved into \setupmarkupstyle handlers. + \catcode\dashChar=\active \catcode\underChar=\active + \ifallowcodebreaks + \let-\codedash + \let_\codeunder + \else + \let-\realdash + \let_\realunder + \fi + \codex + } +} + +\def\realdash{-} +\def\codedash{-\discretionary{}{}{}} +\def\codeunder{% + % this is all so @math{@code{var_name}+1} can work. In math mode, _ + % is "active" (mathcode"8000) and \normalunderscore (or \char95, etc.) + % will therefore expand the active definition of _, which is us + % (inside @code that is), therefore an endless loop. + \ifusingtt{\ifmmode + \mathchar"075F % class 0=ordinary, family 7=ttfam, pos 0x5F=_. + \else\normalunderscore \fi + \discretionary{}{}{}}% + {\_}% +} +\def\codex #1{\tclose{#1}\endgroup} + +% An additional complication: the above will allow breaks after, e.g., +% each of the four underscores in __typeof__. This is undesirable in +% some manuals, especially if they don't have long identifiers in +% general. @allowcodebreaks provides a way to control this. +% +\newif\ifallowcodebreaks \allowcodebreakstrue + +\def\keywordtrue{true} +\def\keywordfalse{false} + +\parseargdef\allowcodebreaks{% + \def\txiarg{#1}% + \ifx\txiarg\keywordtrue + \allowcodebreakstrue + \else\ifx\txiarg\keywordfalse + \allowcodebreaksfalse + \else + \errhelp = \EMsimple + \errmessage{Unknown @allowcodebreaks option `\txiarg'}% + \fi\fi +} + +% @kbd is like @code, except that if the argument is just one @key command, +% then @kbd has no effect. +\def\kbd#1{{\setupmarkupstyle{kbd}\def\look{#1}\expandafter\kbdfoo\look??\par}} + +% @kbdinputstyle -- arg is `distinct' (@kbd uses slanted tty font always), +% `example' (@kbd uses ttsl only inside of @example and friends), +% or `code' (@kbd uses normal tty font always). +\parseargdef\kbdinputstyle{% + \def\txiarg{#1}% + \ifx\txiarg\worddistinct + \gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\ttsl}% + \else\ifx\txiarg\wordexample + \gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\tt}% + \else\ifx\txiarg\wordcode + \gdef\kbdexamplefont{\tt}\gdef\kbdfont{\tt}% + \else + \errhelp = \EMsimple + \errmessage{Unknown @kbdinputstyle option `\txiarg'}% + \fi\fi\fi +} +\def\worddistinct{distinct} +\def\wordexample{example} +\def\wordcode{code} + +% Default is `distinct'. +\kbdinputstyle distinct + +\def\xkey{\key} +\def\kbdfoo#1#2#3\par{\def\one{#1}\def\three{#3}\def\threex{??}% +\ifx\one\xkey\ifx\threex\three \key{#2}% +\else{\tclose{\kbdfont\setupmarkupstyle{kbd}\look}}\fi +\else{\tclose{\kbdfont\setupmarkupstyle{kbd}\look}}\fi} + +% For @indicateurl, @env, @command quotes seem unnecessary, so use \code. +\let\indicateurl=\code +\let\env=\code +\let\command=\code + % @clicksequence{File @click{} Open ...} \def\clicksequence#1{\begingroup #1\endgroup} @@ -3226,23 +2735,76 @@ end \parseargdef\clickstyle{\def\click{#1}} \def\click{\arrow} +% @uref (abbreviation for `urlref') takes an optional (comma-separated) +% second argument specifying the text to display and an optional third +% arg as text to display instead of (rather than in addition to) the url +% itself. First (mandatory) arg is the url. Perhaps eventually put in +% a hypertex \special here. +% +\def\uref#1{\douref #1,,,\finish} +\def\douref#1,#2,#3,#4\finish{\begingroup + \unsepspaces + \pdfurl{#1}% + \setbox0 = \hbox{\ignorespaces #3}% + \ifdim\wd0 > 0pt + \unhbox0 % third arg given, show only that + \else + \setbox0 = \hbox{\ignorespaces #2}% + \ifdim\wd0 > 0pt + \ifpdf + \unhbox0 % PDF: 2nd arg given, show only it + \else + \unhbox0\ (\code{#1})% DVI: 2nd arg given, show both it and url + \fi + \else + \code{#1}% only url given, so show it + \fi + \fi + \endlink +\endgroup} + +% @url synonym for @uref, since that's how everyone uses it. +% +\let\url=\uref + +% rms does not like angle brackets --karl, 17may97. +% So now @email is just like @uref, unless we are pdf. +% +%\def\email#1{\angleleft{\tt #1}\angleright} +\ifpdf + \def\email#1{\doemail#1,,\finish} + \def\doemail#1,#2,#3\finish{\begingroup + \unsepspaces + \pdfurl{mailto:#1}% + \setbox0 = \hbox{\ignorespaces #2}% + \ifdim\wd0>0pt\unhbox0\else\code{#1}\fi + \endlink + \endgroup} +\else + \let\email=\uref +\fi + % Typeset a dimension, e.g., `in' or `pt'. The only reason for the % argument is to make the input look right: @dmn{pt} instead of @dmn{}pt. % \def\dmn#1{\thinspace #1} +% @l was never documented to mean ``switch to the Lisp font'', +% and it is not used as such in any manual I can find. We need it for +% Polish suppressed-l. --karl, 22sep96. +%\def\l#1{{\li #1}\null} + % @acronym for "FBI", "NATO", and the like. % We print this one point size smaller, since it's intended for % all-uppercase. % \def\acronym#1{\doacronym #1,,\finish} \def\doacronym#1,#2,#3\finish{% - {\switchtolsize #1}% + {\selectfonts\lsize #1}% \def\temp{#2}% \ifx\temp\empty \else \space ({\unsepspaces \ignorespaces \temp \unskip})% \fi - \null % reset \spacefactor=1000 } % @abbr for "Comput. J." and the like. @@ -3255,252 +2817,10 @@ end \ifx\temp\empty \else \space ({\unsepspaces \ignorespaces \temp \unskip})% \fi - \null % reset \spacefactor=1000 -} - -% @asis just yields its argument. Used with @table, for example. -% -\def\asis#1{#1} - -% @math outputs its argument in math mode. -% -% One complication: _ usually means subscripts, but it could also mean -% an actual _ character, as in @math{@var{some_variable} + 1}. So make -% _ active, and distinguish by seeing if the current family is \slfam, -% which is what @var uses. -{ - \catcode`\_ = \active - \gdef\mathunderscore{% - \catcode`\_=\active - \def_{\ifnum\fam=\slfam \_\else\sb\fi}% - } -} -% Another complication: we want \\ (and @\) to output a math (or tt) \. -% FYI, plain.tex uses \\ as a temporary control sequence (for no -% particular reason), but this is not advertised and we don't care. -% -% The \mathchar is class=0=ordinary, family=7=ttfam, position=5C=\. -\def\mathbackslash{\ifnum\fam=\ttfam \mathchar"075C \else\backslash \fi} -% -\def\math{% - \ifmmode\else % only go into math if not in math mode already - \tex - \mathunderscore - \let\\ = \mathbackslash - \mathactive - % make the texinfo accent commands work in math mode - \let\"=\ddot - \let\'=\acute - \let\==\bar - \let\^=\hat - \let\`=\grave - \let\u=\breve - \let\v=\check - \let\~=\tilde - \let\dotaccent=\dot - % have to provide another name for sup operator - \let\mathopsup=\sup - $\expandafter\finishmath\fi -} -\def\finishmath#1{#1$\endgroup} % Close the group opened by \tex. - -% Some active characters (such as <) are spaced differently in math. -% We have to reset their definitions in case the @math was an argument -% to a command which sets the catcodes (such as @item or @section). -% -{ - \catcode`^ = \active - \catcode`< = \active - \catcode`> = \active - \catcode`+ = \active - \catcode`' = \active - \gdef\mathactive{% - \let^ = \ptexhat - \let< = \ptexless - \let> = \ptexgtr - \let+ = \ptexplus - \let' = \ptexquoteright - } -} - -% for @sub and @sup, if in math mode, just do a normal sub/superscript. -% If in text, use math to place as sub/superscript, but switch -% into text mode, with smaller fonts. This is a different font than the -% one used for real math sub/superscripts (8pt vs. 7pt), but let's not -% fix it (significant additions to font machinery) until someone notices. -% -\def\sub{\ifmmode \expandafter\sb \else \expandafter\finishsub\fi} -\def\finishsub#1{$\sb{\hbox{\switchtolllsize #1}}$}% -% -\def\sup{\ifmmode \expandafter\ptexsp \else \expandafter\finishsup\fi} -\def\finishsup#1{$\ptexsp{\hbox{\switchtolllsize #1}}$}% - -% @inlinefmt{FMTNAME,PROCESSED-TEXT} and @inlineraw{FMTNAME,RAW-TEXT}. -% Ignore unless FMTNAME == tex; then it is like @iftex and @tex, -% except specified as a normal braced arg, so no newlines to worry about. -% -\def\outfmtnametex{tex} -% -\long\def\inlinefmt#1{\doinlinefmt #1,\finish} -\long\def\doinlinefmt#1,#2,\finish{% - \def\inlinefmtname{#1}% - \ifx\inlinefmtname\outfmtnametex \ignorespaces #2\fi -} -% -% @inlinefmtifelse{FMTNAME,THEN-TEXT,ELSE-TEXT} expands THEN-TEXT if -% FMTNAME is tex, else ELSE-TEXT. -\long\def\inlinefmtifelse#1{\doinlinefmtifelse #1,,,\finish} -\long\def\doinlinefmtifelse#1,#2,#3,#4,\finish{% - \def\inlinefmtname{#1}% - \ifx\inlinefmtname\outfmtnametex \ignorespaces #2\else \ignorespaces #3\fi -} -% -% For raw, must switch into @tex before parsing the argument, to avoid -% setting catcodes prematurely. Doing it this way means that, for -% example, @inlineraw{html, foo{bar} gets a parse error instead of being -% ignored. But this isn't important because if people want a literal -% *right* brace they would have to use a command anyway, so they may as -% well use a command to get a left brace too. We could re-use the -% delimiter character idea from \verb, but it seems like overkill. -% -\long\def\inlineraw{\tex \doinlineraw} -\long\def\doinlineraw#1{\doinlinerawtwo #1,\finish} -\def\doinlinerawtwo#1,#2,\finish{% - \def\inlinerawname{#1}% - \ifx\inlinerawname\outfmtnametex \ignorespaces #2\fi - \endgroup % close group opened by \tex. -} - -% @inlineifset{VAR, TEXT} expands TEXT if VAR is @set. -% -\long\def\inlineifset#1{\doinlineifset #1,\finish} -\long\def\doinlineifset#1,#2,\finish{% - \def\inlinevarname{#1}% - \expandafter\ifx\csname SET\inlinevarname\endcsname\relax - \else\ignorespaces#2\fi -} - -% @inlineifclear{VAR, TEXT} expands TEXT if VAR is not @set. -% -\long\def\inlineifclear#1{\doinlineifclear #1,\finish} -\long\def\doinlineifclear#1,#2,\finish{% - \def\inlinevarname{#1}% - \expandafter\ifx\csname SET\inlinevarname\endcsname\relax \ignorespaces#2\fi } \message{glyphs,} -% and logos. - -% @@ prints an @, as does @atchar{}. -\def\@{\char64 } -\let\atchar=\@ - -% @{ @} @lbracechar{} @rbracechar{} all generate brace characters. -\def\lbracechar{{\ifmonospace\char123\else\ensuremath\lbrace\fi}} -\def\rbracechar{{\ifmonospace\char125\else\ensuremath\rbrace\fi}} -\let\{=\lbracechar -\let\}=\rbracechar - -% @comma{} to avoid , parsing problems. -\let\comma = , - -% Accents: @, @dotaccent @ringaccent @ubaraccent @udotaccent -% Others are defined by plain TeX: @` @' @" @^ @~ @= @u @v @H. -\let\, = \ptexc -\let\dotaccent = \ptexdot -\def\ringaccent#1{{\accent23 #1}} -\let\tieaccent = \ptext -\let\ubaraccent = \ptexb -\let\udotaccent = \d - -% Other special characters: @questiondown @exclamdown @ordf @ordm -% Plain TeX defines: @AA @AE @O @OE @L (plus lowercase versions) @ss. -\def\questiondown{?`} -\def\exclamdown{!`} -\def\ordf{\leavevmode\raise1ex\hbox{\switchtolllsize \underbar{a}}} -\def\ordm{\leavevmode\raise1ex\hbox{\switchtolllsize \underbar{o}}} - -% Dotless i and dotless j, used for accents. -\def\imacro{i} -\def\jmacro{j} -\def\dotless#1{% - \def\temp{#1}% - \ifx\temp\imacro \ifmmode\imath \else\ptexi \fi - \else\ifx\temp\jmacro \ifmmode\jmath \else\j \fi - \else \errmessage{@dotless can be used only with i or j}% - \fi\fi -} - -% The \TeX{} logo, as in plain, but resetting the spacing so that a -% period following counts as ending a sentence. (Idea found in latex.) -% -\edef\TeX{\TeX \spacefactor=1000 } - -% @LaTeX{} logo. Not quite the same results as the definition in -% latex.ltx, since we use a different font for the raised A; it's most -% convenient for us to use an explicitly smaller font, rather than using -% the \scriptstyle font (since we don't reset \scriptstyle and -% \scriptscriptstyle). -% -\def\LaTeX{% - L\kern-.36em - {\setbox0=\hbox{T}% - \vbox to \ht0{\hbox{% - \ifx\textnominalsize\xwordpt - % for 10pt running text, lllsize (8pt) is too small for the A in LaTeX. - % Revert to plain's \scriptsize, which is 7pt. - \count255=\the\fam $\fam\count255 \scriptstyle A$% - \else - % For 11pt, we can use our lllsize. - \switchtolllsize A% - \fi - }% - \vss - }}% - \kern-.15em - \TeX -} - -% Some math mode symbols. Define \ensuremath to switch into math mode -% unless we are already there. Expansion tricks may not be needed here, -% but safer, and can't hurt. -\def\ensuremath{\ifmmode \expandafter\asis \else\expandafter\ensuredmath \fi} -\def\ensuredmath#1{$\relax#1$} -% -\def\bullet{\ensuremath\ptexbullet} -\def\geq{\ensuremath\ge} -\def\leq{\ensuremath\le} -\def\minus{\ensuremath-} - -% @dots{} outputs an ellipsis using the current font. -% We do .5em per period so that it has the same spacing in the cm -% typewriter fonts as three actual period characters; on the other hand, -% in other typewriter fonts three periods are wider than 1.5em. So do -% whichever is larger. -% -\def\dots{% - \leavevmode - \setbox0=\hbox{...}% get width of three periods - \ifdim\wd0 > 1.5em - \dimen0 = \wd0 - \else - \dimen0 = 1.5em - \fi - \hbox to \dimen0{% - \hskip 0pt plus.25fil - .\hskip 0pt plus1fil - .\hskip 0pt plus1fil - .\hskip 0pt plus.5fil - }% -} - -% @enddots{} is an end-of-sentence ellipsis. -% -\def\enddots{% - \dots - \spacefactor=\endofsentencespacefactor -} % @point{}, @result{}, @expansion{}, @print{}, @equiv{}. % @@ -3519,10 +2839,10 @@ end % \newbox\errorbox % -{\ttfont \global\dimen0 = 3em}% Width of the box. +{\tentt \global\dimen0 = 3em}% Width of the box. \dimen2 = .55pt % Thickness of rules % The text. (`r' is open on the right, `e' somewhat less so on the left.) -\setbox0 = \hbox{\kern-.75pt \reducedsf \putworderror\kern-1.5pt} +\setbox0 = \hbox{\kern-.75pt \reducedsf error\kern-1.5pt} % \setbox\errorbox=\hbox to \dimen0{\hfil \hsize = \dimen0 \advance\hsize by -5.8pt % Space to left+right. @@ -3635,32 +2955,20 @@ end \def\Eogonek{{\ecfont \char"86}}\def\macrocharE{E} \def\eogonek{{\ecfont \char"A6}}\def\macrochare{e} % -% Use the European Computer Modern fonts (cm-super in outline format) -% for non-CM glyphs. That is ec* for regular text and tc* for the text -% companion symbols (LaTeX TS1 encoding). Both are part of the ec -% package and follow the same conventions. -% -\def\ecfont{\etcfont{e}} -\def\tcfont{\etcfont{t}} -% -\def\etcfont#1{% +% Use the ec* fonts (cm-super in outline format) for non-CM glyphs. +\def\ecfont{% % We can't distinguish serif/sans and italic/slanted, but this % is used for crude hacks anyway (like adding French and German % quotes to documents typeset with CM, where we lose kerning), so % hopefully nobody will notice/care. \edef\ecsize{\csname\curfontsize ecsize\endcsname}% \edef\nominalsize{\csname\curfontsize nominalsize\endcsname}% - \ifmonospace - % typewriter: - \font\thisecfont = #1ctt\ecsize \space at \nominalsize + \ifx\curfontstyle\bfstylename + % bold: + \font\thisecfont = ecb\ifusingit{i}{x}\ecsize \space at \nominalsize \else - \ifx\curfontstyle\bfstylename - % bold: - \font\thisecfont = #1cb\ifusingit{i}{x}\ecsize \space at \nominalsize - \else - % regular: - \font\thisecfont = #1c\ifusingit{ti}{rm}\ecsize \space at \nominalsize - \fi + % regular: + \font\thisecfont = ec\ifusingit{ti}{rm}\ecsize \space at \nominalsize \fi \thisecfont } @@ -3670,7 +2978,7 @@ end % Adapted from the plain.tex definition of \copyright. % \def\registeredsymbol{% - $^{{\ooalign{\hfil\raise.07ex\hbox{\switchtolllsize R}% + $^{{\ooalign{\hfil\raise.07ex\hbox{\selectfonts\lllsize R}% \hfil\crcr\Orb}}% }$% } @@ -3683,7 +2991,7 @@ end % Textures 1.7.7 (preloaded format=plain 93.10.14) (68K) 16 APR 2004 02:38 % so we'll define it if necessary. % -\ifx\Orb\thisisundefined +\ifx\Orb\undefined \def\Orb{\mathhexbox20D} \fi @@ -3703,20 +3011,16 @@ end \newif\ifseenauthor \newif\iffinishedtitlepage -% @setcontentsaftertitlepage used to do an implicit @contents or -% @shortcontents after @end titlepage, but it is now obsolete. -\def\setcontentsaftertitlepage{% - \errmessage{@setcontentsaftertitlepage has been removed as a Texinfo - command; move your @contents command if you want the contents - after the title page.}}% -\def\setshortcontentsaftertitlepage{% - \errmessage{@setshortcontentsaftertitlepage has been removed as a Texinfo - command; move your @shortcontents and @contents commands if you - want the contents after the title page.}}% +% Do an implicit @contents or @shortcontents after @end titlepage if the +% user says @setcontentsaftertitlepage or @setshortcontentsaftertitlepage. +% +\newif\ifsetcontentsaftertitlepage + \let\setcontentsaftertitlepage = \setcontentsaftertitlepagetrue +\newif\ifsetshortcontentsaftertitlepage + \let\setshortcontentsaftertitlepage = \setshortcontentsaftertitlepagetrue -\parseargdef\shorttitlepage{% - \begingroup \hbox{}\vskip 1.5in \chaprm \centerline{#1}% - \endgroup\page\hbox{}\page} +\parseargdef\shorttitlepage{\begingroup\hbox{}\vskip 1.5in \chaprm \centerline{#1}% + \endgroup\page\hbox{}\page} \envdef\titlepage{% % Open one extra group, as we want to close it in the middle of \Etitlepage. @@ -3754,6 +3058,20 @@ end % Need this before the \...aftertitlepage checks so that if they are % in effect the toc pages will come out with page numbers. \HEADINGSon + % + % If they want short, they certainly want long too. + \ifsetshortcontentsaftertitlepage + \shortcontents + \contents + \global\let\shortcontents = \relax + \global\let\contents = \relax + \fi + % + \ifsetcontentsaftertitlepage + \contents + \global\let\contents = \relax + \global\let\shortcontents = \relax + \fi } \def\finishtitlepage{% @@ -3762,27 +3080,14 @@ end \finishedtitlepagetrue } -% Settings used for typesetting titles: no hyphenation, no indentation, -% don't worry much about spacing, ragged right. This should be used -% inside a \vbox, and fonts need to be set appropriately first. \par should -% be specified before the end of the \vbox, since a vbox is a group. -% -\def\raggedtitlesettings{% - \rm - \hyphenpenalty=10000 - \parindent=0pt - \tolerance=5000 - \ptexraggedright -} +%%% Macros to be used within @titlepage: -% Macros to be used within @titlepage: - -\let\subtitlerm=\rmfont +\let\subtitlerm=\tenrm \def\subtitlefont{\subtitlerm \normalbaselineskip = 13pt \normalbaselines} \parseargdef\title{% \checkenv\titlepage - \vbox{\titlefonts \raggedtitlesettings #1\par}% + \leftline{\titlefonts\rmisbold #1} % print a rule at the page bottom also. \finishedtitlepagefalse \vskip4pt \hrule height 4pt width \hsize \vskip4pt @@ -3803,12 +3108,12 @@ end \else \checkenv\titlepage \ifseenauthor\else \vskip 0pt plus 1filll \seenauthortrue \fi - {\secfonts\rm \leftline{#1}}% + {\secfonts\rmisbold \leftline{#1}}% \fi } -% Set up page headings and footings. +%%% Set up page headings and footings. \let\thispage=\folio @@ -3817,7 +3122,7 @@ end \newtoks\evenfootline % footline on even pages \newtoks\oddfootline % footline on odd pages -% Now make \makeheadline and \makefootline in Plain TeX use those variables +% Now make TeX use those variables \headline={{\textfonts\rm \ifodd\pageno \the\oddheadline \else \the\evenheadline \fi}} \footline={{\textfonts\rm \ifodd\pageno \the\oddfootline @@ -3856,7 +3161,7 @@ end % % Leave some space for the footline. Hopefully ok to assume % @evenfooting will not be used by itself. - \global\advance\txipageheight by -12pt + \global\advance\pageheight by -12pt \global\advance\vsize by -12pt } @@ -3873,17 +3178,13 @@ end % @everyheadingmarks % @everyfootingmarks -% These define \getoddheadingmarks, \getevenheadingmarks, -% \getoddfootingmarks, and \getevenfootingmarks, each to one of -% \gettopheadingmarks, \getbottomheadingmarks. -% \def\evenheadingmarks{\headingmarks{even}{heading}} \def\oddheadingmarks{\headingmarks{odd}{heading}} \def\evenfootingmarks{\headingmarks{even}{footing}} \def\oddfootingmarks{\headingmarks{odd}{footing}} -\parseargdef\everyheadingmarks{\headingmarks{even}{heading}{#1} +\def\everyheadingmarks#1 {\headingmarks{even}{heading}{#1} \headingmarks{odd}{heading}{#1} } -\parseargdef\everyfootingmarks{\headingmarks{even}{footing}{#1} +\def\everyfootingmarks#1 {\headingmarks{even}{footing}{#1} \headingmarks{odd}{footing}{#1} } % #1 = even/odd, #2 = heading/footing, #3 = top/bottom. \def\headingmarks#1#2#3 {% @@ -3904,16 +3205,12 @@ end % By default, they are off at the start of a document, % and turned `on' after @end titlepage. -\parseargdef\headings{\csname HEADINGS#1\endcsname} - -\def\headingsoff{% non-global headings elimination - \evenheadline={\hfil}\evenfootline={\hfil}% - \oddheadline={\hfil}\oddfootline={\hfil}% -} - -\def\HEADINGSoff{{\globaldefs=1 \headingsoff}} % global setting -\HEADINGSoff % it's the default +\def\headings #1 {\csname HEADINGS#1\endcsname} +\def\HEADINGSoff{% +\global\evenheadline={\hfil} \global\evenfootline={\hfil} +\global\oddheadline={\hfil} \global\oddfootline={\hfil}} +\HEADINGSoff % When we turn headings on, set the page number to 1. % For double-sided printing, put current file name in lower left corner, % chapter name on inside top of right hand pages, document @@ -3924,7 +3221,7 @@ end \global\evenfootline={\hfil} \global\oddfootline={\hfil} \global\evenheadline={\line{\folio\hfil\thistitle}} -\global\oddheadline={\line{\thischapterheading\hfil\folio}} +\global\oddheadline={\line{\thischapter\hfil\folio}} \global\let\contentsalignmacro = \chapoddpage } \let\contentsalignmacro = \chappager @@ -3935,8 +3232,8 @@ end \global\pageno=1 \global\evenfootline={\hfil} \global\oddfootline={\hfil} -\global\evenheadline={\line{\thischapterheading\hfil\folio}} -\global\oddheadline={\line{\thischapterheading\hfil\folio}} +\global\evenheadline={\line{\thischapter\hfil\folio}} +\global\oddheadline={\line{\thischapter\hfil\folio}} \global\let\contentsalignmacro = \chappager } \def\HEADINGSon{\HEADINGSdouble} @@ -3947,7 +3244,7 @@ end \global\evenfootline={\hfil} \global\oddfootline={\hfil} \global\evenheadline={\line{\folio\hfil\thistitle}} -\global\oddheadline={\line{\thischapterheading\hfil\folio}} +\global\oddheadline={\line{\thischapter\hfil\folio}} \global\let\contentsalignmacro = \chapoddpage } @@ -3955,8 +3252,8 @@ end \def\HEADINGSsinglex{% \global\evenfootline={\hfil} \global\oddfootline={\hfil} -\global\evenheadline={\line{\thischapterheading\hfil\folio}} -\global\oddheadline={\line{\thischapterheading\hfil\folio}} +\global\evenheadline={\line{\thischapter\hfil\folio}} +\global\oddheadline={\line{\thischapter\hfil\folio}} \global\let\contentsalignmacro = \chappager } @@ -3964,7 +3261,7 @@ end % This produces Day Month Year style of output. % Only define if not already defined, in case a txi-??.tex file has set % up a different format (e.g., txi-cs.tex does this). -\ifx\today\thisisundefined +\ifx\today\undefined \def\today{% \number\day\space \ifcase\month @@ -4025,7 +3322,7 @@ end \begingroup \advance\leftskip by-\tableindent \advance\hsize by\tableindent - \advance\rightskip by0pt plus1fil\relax + \advance\rightskip by0pt plus1fil \leavevmode\unhbox0\par \endgroup % @@ -4134,7 +3431,7 @@ end \parskip=\smallskipamount \ifdim\parskip=0pt \parskip=2pt \fi % - % Try typesetting the item mark so that if the document erroneously says + % Try typesetting the item mark that if the document erroneously says % something like @itemize @samp (intending @table), there's an error % right away at the @itemize. It's not the best error message in the % world, but it's better than leaving it to the @item. This means if @@ -4166,12 +3463,7 @@ end \noindent \hbox to 0pt{\hss \itemcontents \kern\itemmargin}% % - \ifinner\else - \vadjust{\penalty 1200}% not good to break after first line of item. - \fi - % We can be in inner vertical mode in a footnote, although an - % @itemize looks awful there. - }% + \vadjust{\penalty 1200}}% not good to break after first line of item. \flushcr } @@ -4389,23 +3681,19 @@ end } % multitable-only commands. -% -% @headitem starts a heading row, which we typeset in bold. Assignments -% have to be global since we are inside the implicit group of an -% alignment entry. \everycr below resets \everytab so we don't have to +% +% @headitem starts a heading row, which we typeset in bold. +% Assignments have to be global since we are inside the implicit group +% of an alignment entry. \everycr resets \everytab so we don't have to % undo it ourselves. \def\headitemfont{\b}% for people to use in the template row; not changeable \def\headitem{% \checkenv\multitable \crcr - \gdef\headitemcrhook{\nobreak}% attempt to avoid page break after headings \global\everytab={\bf}% can't use \headitemfont since the parsing differs \the\everytab % for the first item }% % -% default for tables with no headings. -\let\headitemcrhook=\relax -% % A \tab used to include \hskip1sp. But then the space in a template % line is not enough. That is bad. So let's go back to just `&' until % we again encounter the problem the 1sp was intended to solve. @@ -4436,15 +3724,15 @@ end % \everycr = {% \noalign{% - \global\everytab={}% Reset from possible headitem. + \global\everytab={}% \global\colcount=0 % Reset the column counter. - % - % Check for saved footnotes, etc.: + % Check for saved footnotes, etc. \checkinserts - % - % Perhaps a \nobreak, then reset: - \headitemcrhook - \global\let\headitemcrhook=\relax + % Keeps underfull box messages off when table breaks over pages. + %\filbreak + % Maybe so, but it also creates really weird page breaks when the + % table breaks over pages. Wouldn't \vfil be better? Wait until the + % problem manifests itself, so it can be fixed for real --karl. }% }% % @@ -4520,18 +3808,18 @@ end \setbox0=\vbox{X}\global\multitablelinespace=\the\baselineskip \global\advance\multitablelinespace by-\ht0 \fi -% Test to see if parskip is larger than space between lines of -% table. If not, do nothing. -% If so, set to same dimension as multitablelinespace. +%% Test to see if parskip is larger than space between lines of +%% table. If not, do nothing. +%% If so, set to same dimension as multitablelinespace. \ifdim\multitableparskip>\multitablelinespace \global\multitableparskip=\multitablelinespace -\global\advance\multitableparskip-7pt % to keep parskip somewhat smaller - % than skip between lines in the table. +\global\advance\multitableparskip-7pt %% to keep parskip somewhat smaller + %% than skip between lines in the table. \fi% \ifdim\multitableparskip=0pt \global\multitableparskip=\multitablelinespace -\global\advance\multitableparskip-7pt % to keep parskip somewhat smaller - % than skip between lines in the table. +\global\advance\multitableparskip-7pt %% to keep parskip somewhat smaller + %% than skip between lines in the table. \fi} @@ -4683,7 +3971,7 @@ end \def\value{\begingroup\makevalueexpandable\valuexxx} \def\valuexxx#1{\expandablevalue{#1}\endgroup} { - \catcode`\-=\active \catcode`\_=\active + \catcode`\- = \active \catcode`\_ = \active % \gdef\makevalueexpandable{% \let\value = \expandablevalue @@ -4692,7 +3980,7 @@ end % ..., but we might end up with active ones in the argument if % we're called from @code, as @code{@value{foo-bar_}}, though. % So \let them to their normal equivalents. - \let-\normaldash \let_\normalunderscore + \let-\realdash \let_\normalunderscore } } @@ -4703,12 +3991,7 @@ end % variable's value contains other Texinfo commands, it's almost certain % it will fail (although perhaps we could fix that with sufficient work % to do a one-level expansion on the result, instead of complete). -% -% Unfortunately, this has the consequence that when _ is in the *value* -% of an @set, it does not print properly in the roman fonts (get the cmr -% dot accent at position 126 instead). No fix comes to mind, and it's -% been this way since 2003 or earlier, so just ignore it. -% +% \def\expandablevalue#1{% \expandafter\ifx\csname SET#1\endcsname\relax {[No value for ``#1'']}% @@ -4718,36 +4001,10 @@ end \fi } -% Like \expandablevalue, but completely expandable (the \message in the -% definition above operates at the execution level of TeX). Used when -% writing to auxiliary files, due to the expansion that \write does. -% If flag is undefined, pass through an unexpanded @value command: maybe it -% will be set by the time it is read back in. -% -% NB flag names containing - or _ may not work here. -\def\dummyvalue#1{% - \expandafter\ifx\csname SET#1\endcsname\relax - \noexpand\value{#1}% - \else - \csname SET#1\endcsname - \fi -} - -% Used for @value's in index entries to form the sort key: expand the @value -% if possible, otherwise sort late. -\def\indexnofontsvalue#1{% - \expandafter\ifx\csname SET#1\endcsname\relax - ZZZZZZZ - \else - \csname SET#1\endcsname - \fi -} - % @ifset VAR ... @end ifset reads the `...' iff VAR has been defined % with @set. -% -% To get the special treatment we need for `@end ifset,' we call -% \makecond and then redefine. +% +% To get special treatment of `@end ifset,' call \makeond and the redefine. % \makecond{ifset} \def\ifset{\parsearg{\doifset{\let\next=\ifsetfail}}} @@ -4763,7 +4020,7 @@ end } \def\ifsetfail{\doignore{ifset}} -% @ifclear VAR ... @end executes the `...' iff VAR has never been +% @ifclear VAR ... @end ifclear reads the `...' iff VAR has never been % defined with @set, or has been undefined with @clear. % % The `\else' inside the `\doifset' parameter is a trick to reuse the @@ -4774,35 +4031,6 @@ end \def\ifclear{\parsearg{\doifset{\else \let\next=\ifclearfail}}} \def\ifclearfail{\doignore{ifclear}} -% @ifcommandisdefined CMD ... @end executes the `...' if CMD (written -% without the @) is in fact defined. We can only feasibly check at the -% TeX level, so something like `mathcode' is going to considered -% defined even though it is not a Texinfo command. -% -\makecond{ifcommanddefined} -\def\ifcommanddefined{\parsearg{\doifcmddefined{\let\next=\ifcmddefinedfail}}} -% -\def\doifcmddefined#1#2{{% - \makevalueexpandable - \let\next=\empty - \expandafter\ifx\csname #2\endcsname\relax - #1% If not defined, \let\next as above. - \fi - \expandafter - }\next -} -\def\ifcmddefinedfail{\doignore{ifcommanddefined}} - -% @ifcommandnotdefined CMD ... handled similar to @ifclear above. -\makecond{ifcommandnotdefined} -\def\ifcommandnotdefined{% - \parsearg{\doifcmddefined{\else \let\next=\ifcmdnotdefinedfail}}} -\def\ifcmdnotdefinedfail{\doignore{ifcommandnotdefined}} - -% Set the `txicommandconditionals' variable, so documents have a way to -% test if the @ifcommand...defined conditionals are available. -\set txicommandconditionals - % @dircategory CATEGORY -- specify a category of the dir file % which this file should belong to. Ignore this in TeX. \let\dircategory=\comment @@ -4818,16 +4046,19 @@ end % except not \outer, so it can be used within macros and \if's. \edef\newwrite{\makecsname{ptexnewwrite}} -% \newindex {foo} defines an index named IX. -% It automatically defines \IXindex such that -% \IXindex ...rest of line... puts an entry in the index IX. -% It also defines \IXindfile to be the number of the output channel for -% the file that accumulates this index. The file's extension is IX. +% \newindex {foo} defines an index named foo. +% It automatically defines \fooindex such that +% \fooindex ...rest of line... puts an entry in the index foo. +% It also defines \fooindfile to be the number of the output channel for +% the file that accumulates this index. The file's extension is foo. % The name of an index should be no more than 2 characters long % for the sake of vms. % \def\newindex#1{% - \expandafter\chardef\csname#1indfile\endcsname=0 + \iflinks + \expandafter\newwrite \csname#1indfile\endcsname + \openout \csname#1indfile\endcsname \jobname.#1 % Open the file + \fi \expandafter\xdef\csname#1index\endcsname{% % Define @#1index \noexpand\doindex{#1}} } @@ -4841,19 +4072,14 @@ end \def\defcodeindex{\parsearg\newcodeindex} % \def\newcodeindex#1{% - \expandafter\chardef\csname#1indfile\endcsname=0 + \iflinks + \expandafter\newwrite \csname#1indfile\endcsname + \openout \csname#1indfile\endcsname \jobname.#1 + \fi \expandafter\xdef\csname#1index\endcsname{% \noexpand\docodeindex{#1}}% } -% The default indices: -\newindex{cp}% concepts, -\newcodeindex{fn}% functions, -\newcodeindex{vr}% variables, -\newcodeindex{tp}% types, -\newcodeindex{ky}% keys -\newcodeindex{pg}% and programs. - % @synindex foo bar makes index foo feed into index bar. % Do this instead of @defindex foo if you don't want it as a separate index. @@ -4867,7 +4093,14 @@ end % #1 is \doindex or \docodeindex, #2 the index getting redefined (foo), % #3 the target index (bar). \def\dosynindex#1#2#3{% - \requireopenindexfile{#3}% + % Only do \closeout if we haven't already done it, else we'll end up + % closing the target index. + \expandafter \ifx\csname donesynindex#2\endcsname \relax + % The \closeout helps reduce unnecessary open files; the limit on the + % Acorn RISC OS is a mere 16 files. + \expandafter\closeout\csname#2indfile\endcsname + \expandafter\let\csname donesynindex#2\endcsname = 1 + \fi % redefine \fooindfile: \expandafter\let\expandafter\temp\expandafter=\csname#3indfile\endcsname \expandafter\let\csname#2indfile\endcsname=\temp @@ -4875,76 +4108,108 @@ end \expandafter\xdef\csname#2index\endcsname{\noexpand#1{#3}}% } -% Define \doindex, the driver for all index macros. +% Define \doindex, the driver for all \fooindex macros. % Argument #1 is generated by the calling \fooindex macro, -% and it is the two-letter name of the index. +% and it is "foo", the name of the index. -\def\doindex#1{\edef\indexname{#1}\parsearg\doindexxxx} -\def\doindexxxx #1{\doind{\indexname}{#1}} +% \doindex just uses \parsearg; it calls \doind for the actual work. +% This is because \doind is more useful to call from other macros. + +% There is also \dosubind {index}{topic}{subtopic} +% which makes an entry in a two-level index such as the operation index. + +\def\doindex#1{\edef\indexname{#1}\parsearg\singleindexer} +\def\singleindexer #1{\doind{\indexname}{#1}} % like the previous two, but they put @code around the argument. -\def\docodeindex#1{\edef\indexname{#1}\parsearg\docodeindexxxx} -\def\docodeindexxxx #1{\doind{\indexname}{\code{#1}}} +\def\docodeindex#1{\edef\indexname{#1}\parsearg\singlecodeindexer} +\def\singlecodeindexer #1{\doind{\indexname}{\code{#1}}} - -% Used when writing an index entry out to an index file to prevent -% expansion of Texinfo commands that can appear in an index entry. +% Take care of Texinfo commands that can appear in an index entry. +% Since there are some commands we want to expand, and others we don't, +% we have to laboriously prevent expansion for those that we don't. % \def\indexdummies{% \escapechar = `\\ % use backslash in output files. - \definedummyletter\@% - \definedummyletter\ % + \def\@{@}% change to @@ when we switch to @ as escape char in index files. + \def\ {\realbackslash\space }% % - % For texindex which always views { and } as separators. - \def\{{\lbracechar{}}% - \def\}{\rbracechar{}}% + % Need these in case \tex is in effect and \{ is a \delimiter again. + % But can't use \lbracecmd and \rbracecmd because texindex assumes + % braces and backslashes are used only as delimiters. + \let\{ = \mylbrace + \let\} = \myrbrace + % + % I don't entirely understand this, but when an index entry is + % generated from a macro call, the \endinput which \scanmacro inserts + % causes processing to be prematurely terminated. This is, + % apparently, because \indexsorttmp is fully expanded, and \endinput + % is an expandable command. The redefinition below makes \endinput + % disappear altogether for that purpose -- although logging shows that + % processing continues to some further point. On the other hand, it + % seems \endinput does not hurt in the printed index arg, since that + % is still getting written without apparent harm. + % + % Sample source (mac-idx3.tex, reported by Graham Percival to + % help-texinfo, 22may06): + % @macro funindex {WORD} + % @findex xyz + % @end macro + % ... + % @funindex commtest + % + % The above is not enough to reproduce the bug, but it gives the flavor. + % + % Sample whatsit resulting: + % .@write3{\entry{xyz}{@folio }{@code {xyz@endinput }}} + % + % So: + \let\endinput = \empty % % Do the redefinitions. - \definedummies + \commondummies } -% Used for the aux and toc files, where @ is the escape character. +% For the aux and toc files, @ is the escape character. So we want to +% redefine everything using @ as the escape character (instead of +% \realbackslash, still used for index files). When everything uses @, +% this will be simpler. % \def\atdummies{% - \definedummyletter\@% - \definedummyletter\ % - \definedummyletter\{% - \definedummyletter\}% + \def\@{@@}% + \def\ {@ }% + \let\{ = \lbraceatcmd + \let\} = \rbraceatcmd % % Do the redefinitions. - \definedummies + \commondummies \otherbackslash } -% \definedummyword defines \#1 as \string\#1\space, thus effectively -% preventing its expansion. This is used only for control words, -% not control letters, because the \space would be incorrect for -% control characters, but is needed to separate the control word -% from whatever follows. +% Called from \indexdummies and \atdummies. % -% These can be used both for control words that take an argument and -% those that do not. If it is followed by {arg} in the input, then -% that will dutifully get written to the index (or wherever). -% -% For control letters, we have \definedummyletter, which omits the -% space. -% -\def\definedummyword #1{\def#1{\string#1\space}}% -\def\definedummyletter#1{\def#1{\string#1}}% -\let\definedummyaccent\definedummyletter - -% Called from \indexdummies and \atdummies, to effectively prevent -% the expansion of commands. -% -\def\definedummies{% +\def\commondummies{% + % + % \definedummyword defines \#1 as \string\#1\space, thus effectively + % preventing its expansion. This is used only for control% words, + % not control letters, because the \space would be incorrect for + % control characters, but is needed to separate the control word + % from whatever follows. + % + % For control letters, we have \definedummyletter, which omits the + % space. + % + % These can be used both for control words that take an argument and + % those that do not. If it is followed by {arg} in the input, then + % that will dutifully get written to the index (or wherever). + % + \def\definedummyword ##1{\def##1{\string##1\space}}% + \def\definedummyletter##1{\def##1{\string##1}}% + \let\definedummyaccent\definedummyletter % - \let\commondummyword\definedummyword - \let\commondummyletter\definedummyletter - \let\commondummyaccent\definedummyaccent \commondummiesnofonts % \definedummyletter\_% - \definedummyletter\-% % % Non-English letters. \definedummyword\AA @@ -4981,27 +4246,20 @@ end \definedummyword\TeX % % Assorted special characters. - \definedummyword\atchar - \definedummyword\arrow \definedummyword\bullet \definedummyword\comma \definedummyword\copyright \definedummyword\registeredsymbol \definedummyword\dots \definedummyword\enddots - \definedummyword\entrybreak \definedummyword\equiv \definedummyword\error \definedummyword\euro - \definedummyword\expansion - \definedummyword\geq \definedummyword\guillemetleft \definedummyword\guillemetright \definedummyword\guilsinglleft \definedummyword\guilsinglright - \definedummyword\lbracechar - \definedummyword\leq - \definedummyword\mathopsup + \definedummyword\expansion \definedummyword\minus \definedummyword\ogonek \definedummyword\pounds @@ -5013,138 +4271,81 @@ end \definedummyword\quoteleft \definedummyword\quoteright \definedummyword\quotesinglbase - \definedummyword\rbracechar \definedummyword\result - \definedummyword\sub - \definedummyword\sup \definedummyword\textdegree % % We want to disable all macros so that they are not expanded by \write. \macrolist - \let\value\dummyvalue % \normalturnoffactive + % + % Handle some cases of @value -- where it does not contain any + % (non-fully-expandable) commands. + \makevalueexpandable } -% \commondummiesnofonts: common to \definedummies and \indexnofonts. -% Define \commondummyletter, \commondummyaccent and \commondummyword before -% using. Used for accents, font commands, and various control letters. +% \commondummiesnofonts: common to \commondummies and \indexnofonts. % \def\commondummiesnofonts{% % Control letters and accents. - \commondummyletter\!% - \commondummyaccent\"% - \commondummyaccent\'% - \commondummyletter\*% - \commondummyaccent\,% - \commondummyletter\.% - \commondummyletter\/% - \commondummyletter\:% - \commondummyaccent\=% - \commondummyletter\?% - \commondummyaccent\^% - \commondummyaccent\`% - \commondummyaccent\~% - \commondummyword\u - \commondummyword\v - \commondummyword\H - \commondummyword\dotaccent - \commondummyword\ogonek - \commondummyword\ringaccent - \commondummyword\tieaccent - \commondummyword\ubaraccent - \commondummyword\udotaccent - \commondummyword\dotless + \definedummyletter\!% + \definedummyaccent\"% + \definedummyaccent\'% + \definedummyletter\*% + \definedummyaccent\,% + \definedummyletter\.% + \definedummyletter\/% + \definedummyletter\:% + \definedummyaccent\=% + \definedummyletter\?% + \definedummyaccent\^% + \definedummyaccent\`% + \definedummyaccent\~% + \definedummyword\u + \definedummyword\v + \definedummyword\H + \definedummyword\dotaccent + \definedummyword\ogonek + \definedummyword\ringaccent + \definedummyword\tieaccent + \definedummyword\ubaraccent + \definedummyword\udotaccent + \definedummyword\dotless % % Texinfo font commands. - \commondummyword\b - \commondummyword\i - \commondummyword\r - \commondummyword\sansserif - \commondummyword\sc - \commondummyword\slanted - \commondummyword\t + \definedummyword\b + \definedummyword\i + \definedummyword\r + \definedummyword\sc + \definedummyword\t % % Commands that take arguments. - \commondummyword\abbr - \commondummyword\acronym - \commondummyword\anchor - \commondummyword\cite - \commondummyword\code - \commondummyword\command - \commondummyword\dfn - \commondummyword\dmn - \commondummyword\email - \commondummyword\emph - \commondummyword\env - \commondummyword\file - \commondummyword\image - \commondummyword\indicateurl - \commondummyword\inforef - \commondummyword\kbd - \commondummyword\key - \commondummyword\math - \commondummyword\option - \commondummyword\pxref - \commondummyword\ref - \commondummyword\samp - \commondummyword\strong - \commondummyword\tie - \commondummyword\U - \commondummyword\uref - \commondummyword\url - \commondummyword\var - \commondummyword\verb - \commondummyword\w - \commondummyword\xref + \definedummyword\acronym + \definedummyword\cite + \definedummyword\code + \definedummyword\command + \definedummyword\dfn + \definedummyword\email + \definedummyword\emph + \definedummyword\env + \definedummyword\file + \definedummyword\kbd + \definedummyword\key + \definedummyword\math + \definedummyword\option + \definedummyword\pxref + \definedummyword\ref + \definedummyword\samp + \definedummyword\strong + \definedummyword\tie + \definedummyword\uref + \definedummyword\url + \definedummyword\var + \definedummyword\verb + \definedummyword\w + \definedummyword\xref } -% For testing: output @{ and @} in index sort strings as \{ and \}. -\newif\ifusebracesinindexes - -\let\indexlbrace\relax -\let\indexrbrace\relax - -{\catcode`\@=0 -\catcode`\\=13 - @gdef@backslashdisappear{@def\{}} -} - -{ -\catcode`\<=13 -\catcode`\-=13 -\catcode`\`=13 - \gdef\indexnonalnumdisappear{% - \expandafter\ifx\csname SETtxiindexlquoteignore\endcsname\relax\else - % @set txiindexlquoteignore makes us ignore left quotes in the sort term. - % (Introduced for FSFS 2nd ed.) - \let`=\empty - \fi - % - \expandafter\ifx\csname SETtxiindexbackslashignore\endcsname\relax\else - \backslashdisappear - \fi - % - \expandafter\ifx\csname SETtxiindexhyphenignore\endcsname\relax\else - \def-{}% - \fi - \expandafter\ifx\csname SETtxiindexlessthanignore\endcsname\relax\else - \def<{}% - \fi - \expandafter\ifx\csname SETtxiindexatsignignore\endcsname\relax\else - \def\@{}% - \fi - } - - \gdef\indexnonalnumreappear{% - \useindexbackslash - \let-\normaldash - \let<\normalless - \def\@{@}% - } -} - - % \indexnofonts is used when outputting the strings to sort the index % by, and when constructing control sequence names. It eliminates all % control sequences and just writes whatever the best ASCII sort string @@ -5152,11 +4353,12 @@ end % \def\indexnofonts{% % Accent commands should become @asis. - \def\commondummyaccent##1{\let##1\asis}% + \def\definedummyaccent##1{\let##1\asis}% % We can just ignore other control letters. - \def\commondummyletter##1{\let##1\empty}% - % All control words become @asis by default; overrides below. - \let\commondummyword\commondummyaccent + \def\definedummyletter##1{\let##1\empty}% + % Hopefully, all control words can become @asis. + \let\definedummyword\definedummyaccent + % \commondummiesnofonts % % Don't no-op \tt, since it isn't a user-level command @@ -5166,13 +4368,8 @@ end % \def\ { }% \def\@{@}% + % how to handle braces? \def\_{\normalunderscore}% - \def\-{}% @- shouldn't affect sorting - % - \uccode`\1=`\{ \uppercase{\def\{{1}}% - \uccode`\1=`\} \uppercase{\def\}{1}}% - \let\lbracechar\{% - \let\rbracechar\}% % % Non-English letters. \def\AA{AA}% @@ -5181,7 +4378,7 @@ end \def\L{L}% \def\OE{OE}% \def\O{O}% - \def\TH{TH}% + \def\TH{ZZZ}% \def\aa{aa}% \def\ae{ae}% \def\dh{dzz}% @@ -5193,45 +4390,39 @@ end \def\o{o}% \def\questiondown{?}% \def\ss{ss}% - \def\th{th}% + \def\th{zzz}% % \def\LaTeX{LaTeX}% \def\TeX{TeX}% % - % Assorted special characters. \defglyph gives the control sequence a - % definition that removes the {} that follows its use. - \defglyph\atchar{@}% - \defglyph\arrow{->}% - \defglyph\bullet{bullet}% - \defglyph\comma{,}% - \defglyph\copyright{copyright}% - \defglyph\dots{...}% - \defglyph\enddots{...}% - \defglyph\equiv{==}% - \defglyph\error{error}% - \defglyph\euro{euro}% - \defglyph\expansion{==>}% - \defglyph\geq{>=}% - \defglyph\guillemetleft{<<}% - \defglyph\guillemetright{>>}% - \defglyph\guilsinglleft{<}% - \defglyph\guilsinglright{>}% - \defglyph\leq{<=}% - \defglyph\lbracechar{\{}% - \defglyph\minus{-}% - \defglyph\point{.}% - \defglyph\pounds{pounds}% - \defglyph\print{-|}% - \defglyph\quotedblbase{"}% - \defglyph\quotedblleft{"}% - \defglyph\quotedblright{"}% - \defglyph\quoteleft{`}% - \defglyph\quoteright{'}% - \defglyph\quotesinglbase{,}% - \defglyph\rbracechar{\}}% - \defglyph\registeredsymbol{R}% - \defglyph\result{=>}% - \defglyph\textdegree{o}% + % Assorted special characters. + % (The following {} will end up in the sort string, but that's ok.) + \def\bullet{bullet}% + \def\comma{,}% + \def\copyright{copyright}% + \def\dots{...}% + \def\enddots{...}% + \def\equiv{==}% + \def\error{error}% + \def\euro{euro}% + \def\expansion{==>}% + \def\guillemetleft{<<}% + \def\guillemetright{>>}% + \def\guilsinglleft{<}% + \def\guilsinglright{>}% + \def\minus{-}% + \def\point{.}% + \def\pounds{pounds}% + \def\print{-|}% + \def\quotedblbase{"}% + \def\quotedblleft{"}% + \def\quotedblright{"}% + \def\quoteleft{`}% + \def\quoteright{'}% + \def\quotesinglbase{,}% + \def\registeredsymbol{R}% + \def\result{=>}% + \def\textdegree{o}% % % We need to get rid of all macros, leaving only the arguments (if present). % Of course this is not nearly correct, but it is the best we can do for now. @@ -5244,24 +4435,16 @@ end % goes to end-of-line is not handled. % \macrolist - \let\value\indexnofontsvalue } -\def\defglyph#1#2{\def#1##1{#2}} % see above - - - +\let\indexbackslash=0 %overridden during \printindex. \let\SETmarginindex=\relax % put index entries in margin (undocumented)? % Most index entries go through here, but \dosubind is the general case. % #1 is the index name, #2 is the entry text. \def\doind#1#2{\dosubind{#1}{#2}{}} -% There is also \dosubind {index}{topic}{subtopic} -% which makes an entry in a two-level index such as the operation index. -% TODO: Two-level index? Operation index? - -% Workhorse for all indexes. +% Workhorse for all \fooindexes. % #1 is name of index, #2 is stuff to put there, #3 is subentry -- % empty if called from \doind, as we usually are (the main exception % is with most defuns, which call us directly). @@ -5269,7 +4452,6 @@ end \def\dosubind#1#2#3{% \iflinks {% - \requireopenindexfile{#1}% % Store the main index entry text (including the third arg). \toks0 = {#2}% % If third arg is present, precede it with a space. @@ -5285,50 +4467,7 @@ end \fi } -% Check if an index file has been opened, and if not, open it. -\def\requireopenindexfile#1{% -\ifnum\csname #1indfile\endcsname=0 - \expandafter\newwrite \csname#1indfile\endcsname - \edef\suffix{#1}% - % A .fls suffix would conflict with the file extension for the output - % of -recorder, so use .f1s instead. - \ifx\suffix\indexisfl\def\suffix{f1}\fi - % Open the file - \immediate\openout\csname#1indfile\endcsname \jobname.\suffix - % Using \immediate above here prevents an object entering into the current - % box, which could confound checks such as those in \safewhatsit for - % preceding skips. - \typeout{Writing index file \jobname.\suffix}% -\fi} -\def\indexisfl{fl} - -% Output \ as {\indexbackslash}, because \ is an escape character in -% the index files. -\let\indexbackslash=\relax -{\catcode`\@=0 \catcode`\\=\active - @gdef@useindexbackslash{@def\{{@indexbackslash}}} -} - -% Definition for writing index entry text. -\def\sortas#1{\ignorespaces}% - -% Definition for writing index entry sort key. Should occur at the at -% the beginning of the index entry, like -% @cindex @sortas{september} \september -% The \ignorespaces takes care of following space, but there's no way -% to remove space before it. -{ -\catcode`\-=13 -\gdef\indexwritesortas{% - \begingroup - \indexnonalnumreappear - \indexwritesortasxxx} -\gdef\indexwritesortasxxx#1{% - \xdef\indexsortkey{#1}\endgroup} -} - - -% Write the entry in \toks0 to the index file. +% Write the entry in \toks0 to the index file: % \def\dosubindwrite{% % Put the index entry in the margin if desired. @@ -5338,26 +4477,14 @@ end % % Remember, we are within a group. \indexdummies % Must do this here, since \bf, etc expand at this stage - \useindexbackslash % \indexbackslash isn't defined now so it will be output - % as is; and it will print as backslash. - % The braces around \indexbrace are recognized by texindex. + \def\backslashcurfont{\indexbackslash}% \indexbackslash isn't defined now + % so it will be output as is; and it will print as backslash. % - % Get the string to sort by, by processing the index entry with all - % font commands turned off. + % Process the index entry with all font commands turned off, to + % get the string to sort by. {\indexnofonts - \def\lbracechar{{\indexlbrace}}% - \def\rbracechar{{\indexrbrace}}% - \let\{=\lbracechar - \let\}=\rbracechar - \indexnonalnumdisappear - \xdef\indexsortkey{}% - \let\sortas=\indexwritesortas - \edef\temp{\the\toks0}% - \setbox\dummybox = \hbox{\temp}% Make sure to execute any \sortas - \ifx\indexsortkey\empty - \xdef\indexsortkey{\temp}% - \ifx\indexsortkey\empty\xdef\indexsortkey{ }\fi - \fi + \edef\temp{\the\toks0}% need full expansion + \xdef\indexsorttmp{\temp}% }% % % Set up the complete index entry, with both the sort key and @@ -5367,11 +4494,10 @@ end % sorted result. \edef\temp{% \write\writeto{% - \string\entry{\indexsortkey}{\noexpand\folio}{\the\toks0}}% + \string\entry{\indexsorttmp}{\noexpand\folio}{\the\toks0}}% }% \temp } -\newbox\dummybox % used above % Take care of unwanted page breaks/skips around a whatsit: % @@ -5408,9 +4534,10 @@ end % % ..., ready, GO: % -\def\safewhatsit#1{\ifhmode +\def\safewhatsit#1{% +\ifhmode #1% - \else +\else % \lastskip and \lastpenalty cannot both be nonzero simultaneously. \whatsitskip = \lastskip \edef\lastskipmacro{\the\lastskip}% @@ -5434,6 +4561,7 @@ end % to re-insert the same penalty (values >10000 are used for various % signals); since we just inserted a non-discardable item, any % following glue (such as a \parskip) would be a breakpoint. For example: + % % @deffn deffn-whatever % @vindex index-whatever % Description. @@ -5446,7 +4574,8 @@ end % (the whatsit from the \write), so we must insert a \nobreak. \nobreak\vskip\whatsitskip \fi -\fi} +\fi +} % The index entry written in the file actually looks like % \entry {sortstring}{page}{topic} @@ -5496,113 +4625,52 @@ end % \initial {@} % as its first line, TeX doesn't complain about mismatched braces % (because it thinks @} is a control sequence). - \catcode`\@ = 12 - % See comment in \requireopenindexfile. - \def\indexname{#1}\ifx\indexname\indexisfl\def\indexname{f1}\fi - \openin 1 \jobname.\indexname s + \catcode`\@ = 11 + \openin 1 \jobname.#1s \ifeof 1 % \enddoublecolumns gets confused if there is no text in the index, % and it loses the chapter title and the aux file entries for the % index. The easiest way to prevent this problem is to make sure % there is some text. \putwordIndexNonexistent - \typeout{No file \jobname.\indexname s.}% \else - \catcode`\\ = 0 % % If the index file exists but is empty, then \openin leaves \ifeof % false. We have to make TeX try to read something from the file, so % it can discover if there is anything in it. - \read 1 to \thisline + \read 1 to \temp \ifeof 1 \putwordIndexIsEmpty \else % Index files are almost Texinfo source, but we use \ as the escape % character. It would be better to use @, but that's too big a change % to make right now. - \def\indexbackslash{\ttbackslash}% - \let\indexlbrace\{ % Likewise, set these sequences for braces - \let\indexrbrace\} % used in the sort key. + \def\indexbackslash{\backslashcurfont}% + \catcode`\\ = 0 + \escapechar = `\\ \begindoublecolumns - \let\dotheinsertentrybox\dotheinsertentryboxwithpenalty - % - % Read input from the index file line by line. - \loopdo - \ifeof1 \else - \read 1 to \nextline - \fi - % - \indexinputprocessing - \thisline - % - \ifeof1\else - \let\thisline\nextline - \repeat - %% + \input \jobname.#1s \enddoublecolumns \fi \fi \closein 1 \endgroup} -\def\loopdo#1\repeat{\def\body{#1}\loopdoxxx} -\def\loopdoxxx{\let\next=\relax\body\let\next=\loopdoxxx\fi\next} - -\def\indexinputprocessing{% - \ifeof1 - \let\firsttoken\relax - \else - \edef\act{\gdef\noexpand\firsttoken{\getfirsttoken\nextline}}% - \act - \fi -} -\def\getfirsttoken#1{\expandafter\getfirsttokenx#1\endfirsttoken} -\long\def\getfirsttokenx#1#2\endfirsttoken{\noexpand#1} - % These macros are used by the sorted index file itself. % Change them to control the appearance of the index. -{\catcode`\/=13 \catcode`\-=13 \catcode`\^=13 \catcode`\~=13 \catcode`\_=13 -\catcode`\|=13 \catcode`\<=13 \catcode`\>=13 \catcode`\+=13 \catcode`\"=13 -\catcode`\$=3 -\gdef\initialglyphs{% - % Some changes for non-alphabetic characters. Using the glyphs from the - % math fonts looks more consistent than the typewriter font used elsewhere - % for these characters. - \def\indexbackslash{\math{\backslash}}% - \let\\=\indexbackslash +\def\initial#1{{% + % Some minor font changes for the special characters. + \let\tentt=\sectt \let\tt=\sectt \let\sf=\sectt % - % Can't get bold backslash so don't use bold forward slash - \catcode`\/=13 - \def/{{\secrmnotbold \normalslash}}% - \def-{{\normaldash\normaldash}}% en dash `--' - \def^{{\chapbf \normalcaret}}% - \def~{{\chapbf \normaltilde}}% - \def\_{% - \leavevmode \kern.07em \vbox{\hrule width.3em height.1ex}\kern .07em }% - \def|{$\vert$}% - \def<{$\less$}% - \def>{$\gtr$}% - \def+{$\normalplus$}% -}} - -\def\initial{% - \bgroup - \initialglyphs - \initialx -} - -\def\initialx#1{% % Remove any glue we may have, we'll be inserting our own. \removelastskip % % We like breaks before the index initials, so insert a bonus. - % The glue before the bonus allows a little bit of space at the - % bottom of a column to reduce an increase in inter-line spacing. \nobreak - \vskip 0pt plus 5\baselineskip - \penalty -300 - \vskip 0pt plus -5\baselineskip + \vskip 0pt plus 3\baselineskip + \penalty 0 + \vskip 0pt plus -3\baselineskip % % Typeset the initial. Making this add up to a whole number of % baselineskips increases the chance of the dots lining up from column @@ -5610,214 +4678,103 @@ end % we need before each entry, but it's better. % % No shrink because it confuses \balancecolumns. - \vskip 1.67\baselineskip plus 1\baselineskip - \leftline{\secfonts \kern-0.05em \secbf #1}% - % \secfonts is inside the argument of \leftline so that the change of - % \baselineskip will not affect any glue inserted before the vbox that - % \leftline creates. + \vskip 1.67\baselineskip plus .5\baselineskip + \leftline{\secbf #1}% % Do our best not to break after the initial. \nobreak \vskip .33\baselineskip plus .1\baselineskip - \egroup % \initialglyphs -} - -\newdimen\entryrightmargin -\entryrightmargin=0pt +}} % \entry typesets a paragraph consisting of the text (#1), dot leaders, and % then page number (#2) flushed to the right margin. It is used for index % and table of contents entries. The paragraph is indented by \leftskip. % +% A straightforward implementation would start like this: +% \def\entry#1#2{... +% But this freezes the catcodes in the argument, and can cause problems to +% @code, which sets - active. This problem was fixed by a kludge--- +% ``-'' was active throughout whole index, but this isn't really right. +% +% The right solution is to prevent \entry from swallowing the whole text. +% --kasal, 21nov03 \def\entry{% \begingroup - % - % For pdfTeX and XeTeX. - % The redefinition of \domark stops marks being added in \pdflink to - % preserve coloured links across page boundaries. Otherwise the marks - % would get in the way of \lastbox in \insertentrybox. - \let\domark\relax % % Start a new paragraph if necessary, so our assignments below can't % affect previous text. \par % + % Do not fill out the last line with white space. + \parfillskip = 0in + % % No extra space above this paragraph. \parskip = 0in % - % When reading the text of entry, convert explicit line breaks - % from @* into spaces. The user might give these in long section - % titles, for instance. - \def\*{\unskip\space\ignorespaces}% - \def\entrybreak{\hfil\break}% An undocumented command + % Do not prefer a separate line ending with a hyphen to fewer lines. + \finalhyphendemerits = 0 + % + % \hangindent is only relevant when the entry text and page number + % don't both fit on one line. In that case, bob suggests starting the + % dots pretty far over on the line. Unfortunately, a large + % indentation looks wrong when the entry text itself is broken across + % lines. So we use a small indentation and put up with long leaders. + % + % \hangafter is reset to 1 (which is the value we want) at the start + % of each paragraph, so we need not do anything with that. + \hangindent = 2em + % + % When the entry text needs to be broken, just fill out the first line + % with blank space. + \rightskip = 0pt plus1fil + % + % A bit of stretch before each entry for the benefit of balancing + % columns. + \vskip 0pt plus1pt % % Swallow the left brace of the text (first parameter): \afterassignment\doentry \let\temp = } -\def\entrybreak{\unskip\space\ignorespaces}% \def\doentry{% - % Save the text of the entry - \global\setbox\boxA=\hbox\bgroup \bgroup % Instead of the swallowed brace. \noindent \aftergroup\finishentry % And now comes the text of the entry. - % Not absorbing as a macro argument reduces the chance of problems - % with catcodes occurring. } -{\catcode`\@=11 -\gdef\finishentry#1{% - \egroup % end box A - \dimen@ = \wd\boxA % Length of text of entry - \global\setbox\boxA=\hbox\bgroup\unhbox\boxA +\def\finishentry#1{% % #1 is the page number. % - % Get the width of the page numbers, and only use - % leaders if they are present. - \global\setbox\boxB = \hbox{#1}% - \ifdim\wd\boxB = 0pt - \null\nobreak\hfill\ % + % The following is kludged to not output a line of dots in the index if + % there are no page numbers. The next person who breaks this will be + % cursed by a Unix daemon. + \setbox\boxA = \hbox{#1}% + \ifdim\wd\boxA = 0pt + \ % \else % + % If we must, put the page number on a line of its own, and fill out + % this line with blank space. (The \hfil is overwhelmed with the + % fill leaders glue in \indexdotfill if the page number does fit.) + \hfil\penalty50 \null\nobreak\indexdotfill % Have leaders before the page number. % + % The `\ ' here is removed by the implicit \unskip that TeX does as + % part of (the primitive) \par. Without it, a spurious underfull + % \hbox ensues. \ifpdf - \pdfgettoks#1.% - \hskip\skip\thinshrinkable\the\toksA + \pdfgettoks#1.% + \ \the\toksA \else - \ifx\XeTeXrevision\thisisundefined - \hskip\skip\thinshrinkable #1% - \else - \pdfgettoks#1.% - \hskip\skip\thinshrinkable\the\toksA - \fi + \ #1% \fi \fi - \egroup % end \boxA - \ifdim\wd\boxB = 0pt - \global\setbox\entrybox=\vbox{\unhbox\boxA}% - \else - \global\setbox\entrybox=\vbox\bgroup - % We want the text of the entries to be aligned to the left, and the - % page numbers to be aligned to the right. - % - \parindent = 0pt - \advance\leftskip by 0pt plus 1fil - \advance\leftskip by 0pt plus -1fill - \rightskip = 0pt plus -1fil - \advance\rightskip by 0pt plus 1fill - % Cause last line, which could consist of page numbers on their own - % if the list of page numbers is long, to be aligned to the right. - \parfillskip=0pt plus -1fill - % - \advance\rightskip by \entryrightmargin - % Determine how far we can stretch into the margin. - % This allows, e.g., "Appendix H GNU Free Documentation License" to - % fit on one line in @letterpaper format. - \ifdim\entryrightmargin>2.1em - \dimen@i=2.1em - \else - \dimen@i=0em - \fi - \advance \parfillskip by 0pt minus 1\dimen@i - % - \dimen@ii = \hsize - \advance\dimen@ii by -1\leftskip - \advance\dimen@ii by -1\entryrightmargin - \advance\dimen@ii by 1\dimen@i - \ifdim\wd\boxA > \dimen@ii % If the entry doesn't fit in one line - \ifdim\dimen@ > 0.8\dimen@ii % due to long index text - % Try to split the text roughly evenly. \dimen@ will be the length of - % the first line. - \dimen@ = 0.7\dimen@ - \dimen@ii = \hsize - \ifnum\dimen@>\dimen@ii - % If the entry is too long (for example, if it needs more than - % two lines), use all the space in the first line. - \dimen@ = \dimen@ii - \fi - \advance\leftskip by 0pt plus 1fill % ragged right - \advance \dimen@ by 1\rightskip - \parshape = 2 0pt \dimen@ 0em \dimen@ii - % Ideally we'd add a finite glue at the end of the first line only, - % instead of using \parshape with explicit line lengths, but TeX - % doesn't seem to provide a way to do such a thing. - % - % Indent all lines but the first one. - \advance\leftskip by 1em - \advance\parindent by -1em - \fi\fi - \indent % start paragraph - \unhbox\boxA - % - % Do not prefer a separate line ending with a hyphen to fewer lines. - \finalhyphendemerits = 0 - % - % Word spacing - no stretch - \spaceskip=\fontdimen2\font minus \fontdimen4\font - % - \linepenalty=1000 % Discourage line breaks. - \hyphenpenalty=5000 % Discourage hyphenation. - % - \par % format the paragraph - \egroup % The \vbox - \fi + \par \endgroup - \dotheinsertentrybox -}} - -\newskip\thinshrinkable -\skip\thinshrinkable=.15em minus .15em - -\newbox\entrybox -\def\insertentrybox{% - \ourunvbox\entrybox } -% default definition -\let\dotheinsertentrybox\insertentrybox - -% Use \lastbox to take apart vbox box by box, and add each sub-box -% to the current vertical list. -\def\ourunvbox#1{% -\bgroup % for local binding of \delayedbox - % Remove the last box from box #1 - \global\setbox#1=\vbox{% - \unvbox#1% - \unskip % remove any glue - \unpenalty - \global\setbox\interbox=\lastbox - }% - \setbox\delayedbox=\box\interbox - \ifdim\ht#1=0pt\else - \ourunvbox#1 % Repeat on what's left of the box - \nobreak - \fi - \box\delayedbox -\egroup -} -\newbox\delayedbox -\newbox\interbox - -% Used from \printindex. \firsttoken should be the first token -% after the \entry. If it's not another \entry, we are at the last -% line of a group of index entries, so insert a penalty to discourage -% widowed index entries. -\def\dotheinsertentryboxwithpenalty{% - \ifx\firsttoken\isentry - \else - \penalty 9000 - \fi - \insertentrybox -} -\def\isentry{\entry}% - % Like plain.tex's \dotfill, except uses up at least 1 em. -% The filll stretch here overpowers both the fil and fill stretch to push -% the page number to the right. \def\indexdotfill{\cleaders - \hbox{$\mathsurround=0pt \mkern1.5mu.\mkern1.5mu$}\hskip 1em plus 1filll} - + \hbox{$\mathsurround=0pt \mkern1.5mu.\mkern1.5mu$}\hskip 1em plus 1fill} \def\primary #1{\line{#1\hfil}} @@ -5831,11 +4788,7 @@ end \ifpdf \pdfgettoks#2.\ \the\toksA % The page number ends the paragraph. \else - \ifx\XeTeXrevision\thisisundefined - #2 - \else - \pdfgettoks#2.\ \the\toksA % The page number ends the paragraph. - \fi + #2 \fi \par }} @@ -5843,37 +4796,12 @@ end % Define two-column mode, which we use to typeset indexes. % Adapted from the TeXbook, page 416, which is to say, % the manmac.tex format used to print the TeXbook itself. -\catcode`\@=11 % private names +\catcode`\@=11 \newbox\partialpage \newdimen\doublecolumnhsize -% Use inside an output routine to save \topmark and \firstmark -\def\savemarks{% - \global\savedtopmark=\expandafter{\topmark }% - \global\savedfirstmark=\expandafter{\firstmark }% -} -\newtoks\savedtopmark -\newtoks\savedfirstmark - -% Set \topmark and \firstmark for next time \output runs. -% Can't be run from withinside \output (because any material -% added while an output routine is active, including -% penalties, is saved for after it finishes). The page so far -% should be empty, otherwise what's on it will be thrown away. -\def\restoremarks{% - \mark{\the\savedtopmark}% - \bgroup\output = {% - \setbox\dummybox=\box\PAGE - }abc\eject\egroup - % "abc" because output routine doesn't fire for a completely empty page. - \mark{\the\savedfirstmark}% -} - \def\begindoublecolumns{\begingroup % ended by \enddoublecolumns - % If not much space left on page, start a new page. - \ifdim\pagetotal>0.8\vsize\vfill\eject\fi - % % Grab any single-column material above us. \output = {% % @@ -5893,15 +4821,8 @@ end \unvbox\PAGE \kern-\topskip \kern\baselineskip }% - \savemarks }% \eject % run that output routine to set \partialpage - \restoremarks - % - % We recover the two marks that the last output routine saved in order - % to propagate the information in marks added around a chapter heading, - % which could be otherwise be lost by the time the final page is output. - % % % Use the double-column output routine for subsequent pages. \output = {\doublecolumnout}% @@ -5927,31 +4848,27 @@ end \divide\doublecolumnhsize by 2 \hsize = \doublecolumnhsize % - % Double the \vsize as well. - \advance\vsize by -\ht\partialpage + % Double the \vsize as well. (We don't need a separate register here, + % since nobody clobbers \vsize.) \vsize = 2\vsize - % - % For the benefit of balancing columns - \advance\baselineskip by 0pt plus 0.5pt } % The double-column output routine for all double-column pages except -% the last, which is done by \balancecolumns. +% the last. % \def\doublecolumnout{% - % \splittopskip=\topskip \splitmaxdepth=\maxdepth % Get the available space for the double columns -- the normal % (undoubled) page height minus any material left over from the % previous page. \dimen@ = \vsize \divide\dimen@ by 2 + \advance\dimen@ by -\ht\partialpage % % box0 will be the left-hand column, box2 the right. - \setbox0=\vsplit\PAGE to\dimen@ \setbox2=\vsplit\PAGE to\dimen@ - \global\advance\vsize by 2\ht\partialpage + \setbox0=\vsplit255 to\dimen@ \setbox2=\vsplit255 to\dimen@ \onepageout\pagesofar - \unvbox\PAGE + \unvbox255 \penalty\outputpenalty } % @@ -5962,11 +4879,10 @@ end % \hsize = \doublecolumnhsize \wd0=\hsize \wd2=\hsize - \hbox to\txipagewidth{\box0\hfil\box2}% + \hbox to\pagewidth{\box0\hfil\box2}% } - - -% Finished with with double columns. +% +% All done with double columns. \def\enddoublecolumns{% % The following penalty ensures that the page builder is exercised % _before_ we change the output routine. This is necessary in the @@ -5989,7 +4905,7 @@ end % goal. When TeX sees \eject from below which follows the final % section, it invokes the new output routine that we've set after % \balancecolumns below; \onepageout will try to fit the two columns - % and the final section into the vbox of \txipageheight (see + % and the final section into the vbox of \pageheight (see % \pagebody), causing an overfull box. % % Note that glue won't work here, because glue does not exercise the @@ -5997,88 +4913,53 @@ end \penalty0 % \output = {% - % Split the last of the double-column material. - \savemarks + % Split the last of the double-column material. Leave it on the + % current page, no automatic page break. \balancecolumns - }% - \eject % call the \output just set - \ifdim\pagetotal=0pt - % Having called \balancecolumns once, we do not + % + % If we end up splitting too much material for the current page, + % though, there will be another page break right after this \output + % invocation ends. Having called \balancecolumns once, we do not % want to call it again. Therefore, reset \output to its normal - % definition right away. + % definition right away. (We hope \balancecolumns will never be + % called on to balance too much material, but if it is, this makes + % the output somewhat more palatable.) \global\output = {\onepageout{\pagecontents\PAGE}}% - % - \endgroup % started in \begindoublecolumns - \restoremarks - % Leave the double-column material on the current page, no automatic - % page break. - \box\balancedcolumns - % - % \pagegoal was set to the doubled \vsize above, since we restarted - % the current page. We're now back to normal single-column - % typesetting, so reset \pagegoal to the normal \vsize. - \global\vsize = \txipageheight % - \pagegoal = \txipageheight % - \else - % We had some left-over material. This might happen when \doublecolumnout - % is called in \balancecolumns. Try again. - \expandafter\enddoublecolumns - \fi + }% + \eject + \endgroup % started in \begindoublecolumns + % + % \pagegoal was set to the doubled \vsize above, since we restarted + % the current page. We're now back to normal single-column + % typesetting, so reset \pagegoal to the normal \vsize (after the + % \endgroup where \vsize got restored). + \pagegoal = \vsize } -\newbox\balancedcolumns -\setbox\balancedcolumns=\vbox{shouldnt see this}% % -% Only called for the last of the double column material. \doublecolumnout -% does the others. +% Called at the end of the double column material. \def\balancecolumns{% - \setbox0 = \vbox{\unvbox\PAGE}% like \box255 but more efficient, see p.120. + \setbox0 = \vbox{\unvbox255}% like \box255 but more efficient, see p.120. \dimen@ = \ht0 \advance\dimen@ by \topskip \advance\dimen@ by-\baselineskip - \ifdim\dimen@<5\baselineskip - % Don't split a short final column in two. - \setbox2=\vbox{}% - \global\setbox\balancedcolumns=\vbox{\pagesofar}% - \else - \divide\dimen@ by 2 % target to split to - \dimen@ii = \dimen@ - \splittopskip = \topskip - % Loop until left column is at least as high as the right column. - {% - \vbadness = 10000 - \loop - \global\setbox3 = \copy0 - \global\setbox1 = \vsplit3 to \dimen@ - \ifdim\ht1<\ht3 - \global\advance\dimen@ by 1pt - \repeat - }% - % Now the left column is in box 1, and the right column in box 3. - % - % Check whether the left column has come out higher than the page itself. - % (Note that we have doubled \vsize for the double columns, so - % the actual height of the page is 0.5\vsize). - \ifdim2\ht1>\vsize - % It appears that we have been called upon to balance too much material. - % Output some of it with \doublecolumnout, leaving the rest on the page. - \setbox\PAGE=\box0 - \doublecolumnout - \else - % Compare the heights of the two columns. - \ifdim4\ht1>5\ht3 - % Column heights are too different, so don't make their bottoms - % flush with each other. - \setbox2=\vbox to \ht1 {\unvbox3\vfill}% - \setbox0=\vbox to \ht1 {\unvbox1\vfill}% - \else - % Make column bottoms flush with each other. - \setbox2=\vbox to\ht1{\unvbox3\unskip}% - \setbox0=\vbox to\ht1{\unvbox1\unskip}% - \fi - \global\setbox\balancedcolumns=\vbox{\pagesofar}% - \fi - \fi + \divide\dimen@ by 2 % target to split to + %debug\message{final 2-column material height=\the\ht0, target=\the\dimen@.}% + \splittopskip = \topskip + % Loop until we get a decent breakpoint. + {% + \vbadness = 10000 + \loop + \global\setbox3 = \copy0 + \global\setbox1 = \vsplit3 to \dimen@ + \ifdim\ht3>\dimen@ + \global\advance\dimen@ by 1pt + \repeat + }% + %debug\message{split to \the\dimen@, column heights: \the\ht1, \the\ht3.}% + \setbox0=\vbox to\dimen@{\unvbox1}% + \setbox2=\vbox to\dimen@{\unvbox3}% % + \pagesofar } \catcode`\@ = \other @@ -6086,26 +4967,7 @@ end \message{sectioning,} % Chapters, sections, etc. -% Let's start with @part. -\outer\parseargdef\part{\partzzz{#1}} -\def\partzzz#1{% - \chapoddpage - \null - \vskip.3\vsize % move it down on the page a bit - \begingroup - \noindent \titlefonts\rm #1\par % the text - \let\lastnode=\empty % no node to associate with - \writetocentry{part}{#1}{}% but put it in the toc - \headingsoff % no headline or footline on the part page - % This outputs a mark at the end of the page that clears \thischapter - % and \thissection, as is done in \startcontents. - \let\pchapsepmacro\relax - \chapmacro{}{Yomitfromtoc}{}% - \chapoddpage - \endgroup -} - -% \unnumberedno is an oxymoron. But we count the unnumbered +% \unnumberedno is an oxymoron, of course. But we count the unnumbered % sections so that we can refer to them unambiguously in the pdf % outlines by their "section number". We avoid collisions with chapter % numbers by starting them at 10000. (If a document ever has 10000 @@ -6184,8 +5046,8 @@ end \chardef\maxseclevel = 3 % % A numbered section within an unnumbered changes to unnumbered too. -% To achieve this, remember the "biggest" unnum. sec. we are currently in: -\chardef\unnlevel = \maxseclevel +% To achive this, remember the "biggest" unnum. sec. we are currently in: +\chardef\unmlevel = \maxseclevel % % Trace whether the current chapter is an appendix or not: % \chapheadtype is "N" or "A", unnumbered chapters are ignored. @@ -6210,8 +5072,8 @@ end % The heading type: \def\headtype{#1}% \if \headtype U% - \ifnum \absseclevel < \unnlevel - \chardef\unnlevel = \absseclevel + \ifnum \absseclevel < \unmlevel + \chardef\unmlevel = \absseclevel \fi \else % Check for appendix sections: @@ -6223,10 +5085,10 @@ end \fi\fi \fi % Check for numbered within unnumbered: - \ifnum \absseclevel > \unnlevel + \ifnum \absseclevel > \unmlevel \def\headtype{U}% \else - \chardef\unnlevel = 3 + \chardef\unmlevel = 3 \fi \fi % Now print the heading: @@ -6312,8 +5174,7 @@ end \global\let\subsubsection = \appendixsubsubsec } -% normally unnmhead0 calls unnumberedzzz: -\outer\parseargdef\unnumbered{\unnmhead0{#1}} +\outer\parseargdef\unnumbered{\unnmhead0{#1}} % normally unnmhead0 calls unnumberedzzz \def\unnumberedzzz#1{% \global\secno=0 \global\subsecno=0 \global\subsubsecno=0 \global\advance\unnumberedno by 1 @@ -6345,6 +5206,9 @@ end % @centerchap is like @unnumbered, but the heading is centered. \outer\parseargdef\centerchap{% + % Well, we could do the following in a group, but that would break + % an assumption that \chapmacro is called at the outermost level. + % Thus we are safer this way: --kasal, 24feb04 \let\centerparametersmaybe = \centerparameters \unnmhead0{#1}% \let\centerparametersmaybe = \relax @@ -6354,47 +5218,40 @@ end \let\top\unnumbered % Sections. -% \outer\parseargdef\numberedsec{\numhead1{#1}} % normally calls seczzz \def\seczzz#1{% \global\subsecno=0 \global\subsubsecno=0 \global\advance\secno by 1 \sectionheading{#1}{sec}{Ynumbered}{\the\chapno.\the\secno}% } -% normally calls appendixsectionzzz: -\outer\parseargdef\appendixsection{\apphead1{#1}} +\outer\parseargdef\appendixsection{\apphead1{#1}} % normally calls appendixsectionzzz \def\appendixsectionzzz#1{% \global\subsecno=0 \global\subsubsecno=0 \global\advance\secno by 1 \sectionheading{#1}{sec}{Yappendix}{\appendixletter.\the\secno}% } \let\appendixsec\appendixsection -% normally calls unnumberedseczzz: -\outer\parseargdef\unnumberedsec{\unnmhead1{#1}} +\outer\parseargdef\unnumberedsec{\unnmhead1{#1}} % normally calls unnumberedseczzz \def\unnumberedseczzz#1{% \global\subsecno=0 \global\subsubsecno=0 \global\advance\secno by 1 \sectionheading{#1}{sec}{Ynothing}{\the\unnumberedno.\the\secno}% } % Subsections. -% -% normally calls numberedsubseczzz: -\outer\parseargdef\numberedsubsec{\numhead2{#1}} +\outer\parseargdef\numberedsubsec{\numhead2{#1}} % normally calls numberedsubseczzz \def\numberedsubseczzz#1{% \global\subsubsecno=0 \global\advance\subsecno by 1 \sectionheading{#1}{subsec}{Ynumbered}{\the\chapno.\the\secno.\the\subsecno}% } -% normally calls appendixsubseczzz: -\outer\parseargdef\appendixsubsec{\apphead2{#1}} +\outer\parseargdef\appendixsubsec{\apphead2{#1}} % normally calls appendixsubseczzz \def\appendixsubseczzz#1{% \global\subsubsecno=0 \global\advance\subsecno by 1 \sectionheading{#1}{subsec}{Yappendix}% {\appendixletter.\the\secno.\the\subsecno}% } -% normally calls unnumberedsubseczzz: -\outer\parseargdef\unnumberedsubsec{\unnmhead2{#1}} +\outer\parseargdef\unnumberedsubsec{\unnmhead2{#1}} %normally calls unnumberedsubseczzz \def\unnumberedsubseczzz#1{% \global\subsubsecno=0 \global\advance\subsecno by 1 \sectionheading{#1}{subsec}{Ynothing}% @@ -6402,25 +5259,21 @@ end } % Subsubsections. -% -% normally numberedsubsubseczzz: -\outer\parseargdef\numberedsubsubsec{\numhead3{#1}} +\outer\parseargdef\numberedsubsubsec{\numhead3{#1}} % normally numberedsubsubseczzz \def\numberedsubsubseczzz#1{% \global\advance\subsubsecno by 1 \sectionheading{#1}{subsubsec}{Ynumbered}% {\the\chapno.\the\secno.\the\subsecno.\the\subsubsecno}% } -% normally appendixsubsubseczzz: -\outer\parseargdef\appendixsubsubsec{\apphead3{#1}} +\outer\parseargdef\appendixsubsubsec{\apphead3{#1}} % normally appendixsubsubseczzz \def\appendixsubsubseczzz#1{% \global\advance\subsubsecno by 1 \sectionheading{#1}{subsubsec}{Yappendix}% {\appendixletter.\the\secno.\the\subsecno.\the\subsubsecno}% } -% normally unnumberedsubsubseczzz: -\outer\parseargdef\unnumberedsubsubsec{\unnmhead3{#1}} +\outer\parseargdef\unnumberedsubsubsec{\unnmhead3{#1}} %normally unnumberedsubsubseczzz \def\unnumberedsubsubseczzz#1{% \global\advance\subsubsecno by 1 \sectionheading{#1}{subsubsec}{Ynothing}% @@ -6436,6 +5289,14 @@ end % Define @majorheading, @heading and @subheading +% NOTE on use of \vbox for chapter headings, section headings, and such: +% 1) We use \vbox rather than the earlier \line to permit +% overlong headings to fold. +% 2) \hyphenpenalty is set to 10000 because hyphenation in a +% heading is obnoxious; this forbids it. +% 3) Likewise, headings look best if no \parindent is used, and +% if justification is not attempted. Hence \raggedright. + \def\majorheading{% {\advance\chapheadingskip by 10pt \chapbreak }% \parsearg\chapheadingzzz @@ -6443,8 +5304,10 @@ end \def\chapheading{\chapbreak \parsearg\chapheadingzzz} \def\chapheadingzzz#1{% - \vbox{\chapfonts \raggedtitlesettings #1\par}% - \nobreak\bigskip \nobreak + {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000 + \parindent=0pt\ptexraggedright + \rmisbold #1\hfill}}% + \bigskip \par\penalty 200\relax \suppressfirstparagraphindent } @@ -6460,19 +5323,16 @@ end % (including whitespace, linebreaking, etc. around it), % given all the information in convenient, parsed form. -% Args are the skip and penalty (usually negative) +%%% Args are the skip and penalty (usually negative) \def\dobreak#1#2{\par\ifdim\lastskip<#1\removelastskip\penalty#2\vskip#1\fi} +%%% Define plain chapter starts, and page on/off switching for it % Parameter controlling skip before chapter headings (if needed) + \newskip\chapheadingskip -% Define plain chapter starts, and page on/off switching for it. \def\chapbreak{\dobreak \chapheadingskip {-4000}} - -% Start a new page \def\chappager{\par\vfill\supereject} - -% \chapoddpage - start on an odd page for a new chapter % Because \domark is called before \chapoddpage, the filler page will % get the headings for the next chapter, which is wrong. But we don't % care -- we just disable all headings on the filler page. @@ -6480,14 +5340,15 @@ end \chappager \ifodd\pageno \else \begingroup - \headingsoff - \null + \evenheadline={\hfil}\evenfootline={\hfil}% + \oddheadline={\hfil}\oddfootline={\hfil}% + \hbox to 0pt{}% \chappager \endgroup \fi } -\parseargdef\setchapternewpage{\csname CHAPPAG#1\endcsname} +\def\setchapternewpage #1 {\csname CHAPPAG#1\endcsname} \def\CHAPPAGoff{% \global\let\contentsalignmacro = \chappager @@ -6508,26 +5369,17 @@ end \CHAPPAGon -% \chapmacro - Chapter opening. +% Chapter opening. % % #1 is the text, #2 is the section type (Ynumbered, Ynothing, % Yappendix, Yomitfromtoc), #3 the chapter number. -% Not used for @heading series. % % To test against our argument. \def\Ynothingkeyword{Ynothing} -\def\Yappendixkeyword{Yappendix} \def\Yomitfromtockeyword{Yomitfromtoc} +\def\Yappendixkeyword{Yappendix} % \def\chapmacro#1#2#3{% - \expandafter\ifx\thisenv\titlepage\else - \checkenv{}% chapters, etc., should not start inside an environment. - \fi - % FIXME: \chapmacro is currently called from inside \titlepage when - % \setcontentsaftertitlepage to print the "Table of Contents" heading, but - % this should probably be done by \sectionheading with an option to print - % in chapter size. - % % Insert the first mark before the heading break (see notes for \domark). \let\prevchapterdefs=\lastchapterdefs \let\prevsectiondefs=\lastsectiondefs @@ -6579,8 +5431,7 @@ end \domark % {% - \chapfonts \rm - \let\footnote=\errfootnoteheading % give better error message + \chapfonts \rmisbold % % Have to define \lastsection before calling \donoderef, because the % xref code eventually uses it. On the other hand, it has to be called @@ -6617,7 +5468,8 @@ end % % Typeset the actual heading. \nobreak % Avoid page breaks at the interline glue. - \vbox{\raggedtitlesettings \hangindent=\wd0 \centerparametersmaybe + \vbox{\hyphenpenalty=10000 \tolerance=5000 \parindent=0pt \ptexraggedright + \hangindent=\wd0 \centerparametersmaybe \unhbox0 #1\par}% }% \nobreak\bigskip % no page break after a chapter title @@ -6633,6 +5485,30 @@ end } +% I don't think this chapter style is supported any more, so I'm not +% updating it with the new noderef stuff. We'll see. --karl, 11aug03. +% +\def\setchapterstyle #1 {\csname CHAPF#1\endcsname} +% +\def\unnchfopen #1{% +\chapoddpage {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000 + \parindent=0pt\ptexraggedright + \rmisbold #1\hfill}}\bigskip \par\nobreak +} +\def\chfopen #1#2{\chapoddpage {\chapfonts +\vbox to 3in{\vfil \hbox to\hsize{\hfil #2} \hbox to\hsize{\hfil #1} \vfil}}% +\par\penalty 5000 % +} +\def\centerchfopen #1{% +\chapoddpage {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000 + \parindent=0pt + \hfill {\rmisbold #1}\hfill}}\bigskip \par\nobreak +} +\def\CHAPFopen{% + \global\let\chapmacro=\chfopen + \global\let\centerchapmacro=\centerchfopen} + + % Section titles. These macros combine the section number parts and % call the generic \sectionheading to do the printing. % @@ -6650,29 +5526,20 @@ end % Print any size, any type, section title. % -% #1 is the text of the title, -% #2 is the section level (sec/subsec/subsubsec), -% #3 is the section type (Ynumbered, Ynothing, Yappendix, Yomitfromtoc), -% #4 is the section number. +% #1 is the text, #2 is the section level (sec/subsec/subsubsec), #3 is +% the section type for xrefs (Ynumbered, Ynothing, Yappendix), #4 is the +% section number. % \def\seckeyword{sec} % \def\sectionheading#1#2#3#4{% {% + % Switch to the right set of fonts. + \csname #2fonts\endcsname \rmisbold + % \def\sectionlevel{#2}% \def\temptype{#3}% % - % It is ok for the @heading series commands to appear inside an - % environment (it's been historically allowed, though the logic is - % dubious), but not the others. - \ifx\temptype\Yomitfromtockeyword\else - \checkenv{}% non-@*heading should not be in an environment. - \fi - \let\footnote=\errfootnoteheading - % - % Switch to the right set of fonts. - \csname #2fonts\endcsname \rm - % % Insert first mark before the heading break (see notes for \domark). \let\prevsectiondefs=\lastsectiondefs \ifx\temptype\Ynothingkeyword @@ -6724,7 +5591,7 @@ end % % Now the second mark, after the heading break. No break points % between here and the heading. - \global\let\prevsectiondefs=\lastsectiondefs + \let\prevsectiondefs=\lastsectiondefs \domark % % Only insert the space after the number if we have a section number. @@ -6778,15 +5645,15 @@ end % % We'll almost certainly start a paragraph next, so don't let that % glue accumulate. (Not a breakpoint because it's preceded by a - % discardable item.) However, when a paragraph is not started next - % (\startdefun, \cartouche, \center, etc.), this needs to be wiped out - % or the negative glue will cause weirdly wrong output, typically - % obscuring the section heading with something else. + % discardable item.) \vskip-\parskip % - % This is so the last item on the main vertical list is a known - % \penalty > 10000, so \startdefun, etc., can recognize the situation - % and do the needful. + % This is purely so the last item on the list is a known \penalty > + % 10000. This is so \startdefun can avoid allowing breakpoints after + % section headings. Otherwise, it would insert a valid breakpoint between: + % + % @section sec-whatever + % @deffn def-whatever \penalty 10001 } @@ -6835,14 +5702,7 @@ end % 1 and 2 (the page numbers aren't printed), and so are the first % two pages of the document. Thus, we'd have two destinations named % `1', and two named `2'. - \ifpdf - \global\pdfmakepagedesttrue - \else - \ifx\XeTeXrevision\thisisundefined - \else - \global\pdfmakepagedesttrue - \fi - \fi + \ifpdf \global\pdfmakepagedesttrue \fi } @@ -6891,7 +5751,7 @@ end \savepageno = \pageno \begingroup % Set up to handle contents files properly. \raggedbottom % Worry more about breakpoints than the bottom. - \entryrightmargin=\contentsrightmargin % Don't use the full line length. + \advance\hsize by -\contentsrightmargin % Don't use the full line length. % % Roman numerals for page numbers. \ifnum \pageno>0 \global\pageno = \lastnegativepageno \fi @@ -6925,7 +5785,6 @@ end \def\summarycontents{% \startcontents{\putwordShortTOC}% % - \let\partentry = \shortpartentry \let\numchapentry = \shortchapentry \let\appentry = \shortchapentry \let\unnchapentry = \shortunnchapentry @@ -6981,30 +5840,9 @@ end % The last argument is the page number. % The arguments in between are the chapter number, section number, ... -% Parts, in the main contents. Replace the part number, which doesn't -% exist, with an empty box. Let's hope all the numbers have the same width. -% Also ignore the page number, which is conventionally not printed. -\def\numeralbox{\setbox0=\hbox{8}\hbox to \wd0{\hfil}} -\def\partentry#1#2#3#4{% - % Add stretch and a bonus for breaking the page before the part heading. - % This reduces the chance of the page being broken immediately after the - % part heading, before a following chapter heading. - \vskip 0pt plus 5\baselineskip - \penalty-300 - \vskip 0pt plus -5\baselineskip - \dochapentry{\numeralbox\labelspace#1}{}% -} -% -% Parts, in the short toc. -\def\shortpartentry#1#2#3#4{% - \penalty-300 - \vskip.5\baselineskip plus.15\baselineskip minus.1\baselineskip - \shortchapentry{{\bf #1}}{\numeralbox}{}{}% -} - % Chapters, in the main contents. \def\numchapentry#1#2#3#4{\dochapentry{#2\labelspace#1}{#4}} - +% % Chapters, in the short toc. % See comments in \dochapentry re vbox and related settings. \def\shortchapentry#1#2#3#4{% @@ -7019,7 +5857,7 @@ end \setbox0 = \hbox{\putwordAppendix{} M}% \hbox to \wd0{\putwordAppendix{} #1\hss}} % -\def\appentry#1#2#3#4{\dochapentry{\appendixbox{#2}\hskip.7em#1}{#4}} +\def\appentry#1#2#3#4{\dochapentry{\appendixbox{#2}\labelspace#1}{#4}} % Unnumbered chapters. \def\unnchapentry#1#2#3#4{\dochapentry{#1}{#4}} @@ -7052,8 +5890,6 @@ end \def\dochapentry#1#2{% \penalty-300 \vskip1\baselineskip plus.33\baselineskip minus.25\baselineskip \begingroup - % Move the page numbers slightly to the right - \advance\entryrightmargin by -0.05em \chapentryfonts \tocentry{#1}{\dopageno\bgroup#2\egroup}% \endgroup @@ -7093,9 +5929,9 @@ end \message{environments,} % @foo ... @end foo. -% @tex ... @end tex escapes into raw TeX temporarily. +% @tex ... @end tex escapes into raw Tex temporarily. % One exception: @ is still an escape character, so that @end tex works. -% But \@ or @@ will get a plain @ character. +% But \@ or @@ will get a plain tex @ character. \envdef\tex{% \setupmarkupstyle{tex}% @@ -7108,14 +5944,10 @@ end \catcode `\|=\other \catcode `\<=\other \catcode `\>=\other - \catcode `\`=\other - \catcode `\'=\other + \catcode`\`=\other + \catcode`\'=\other + \escapechar=`\\ % - % ' is active in math mode (mathcode"8000). So reset it, and all our - % other math active characters (just in case), to plain's definitions. - \mathactive - % - % Inverse of the list at the beginning of the file. \let\b=\ptexb \let\bullet=\ptexbullet \let\c=\ptexc @@ -7131,11 +5963,9 @@ end \let\+=\tabalign \let\}=\ptexrbrace \let\/=\ptexslash - \let\sp=\ptexsp \let\*=\ptexstar - %\let\sup=\ptexsup % do not redefine, we want @sup to work in math mode \let\t=\ptext - \expandafter \let\csname top\endcsname=\ptextop % we've made it outer + \expandafter \let\csname top\endcsname=\ptextop % outer \let\frenchspacing=\plainfrenchspacing % \def\endldots{\mathinner{\ldots\ldots\ldots\ldots}}% @@ -7165,24 +5995,6 @@ end % start of the next paragraph will insert \parskip. % \def\aboveenvbreak{{% - % =10000 instead of <10000 because of a special case in \itemzzz and - % \sectionheading, q.v. - \ifnum \lastpenalty=10000 \else - \advance\envskipamount by \parskip - \endgraf - \ifdim\lastskip<\envskipamount - \removelastskip - \ifnum\lastpenalty<10000 - % Penalize breaking before the environment, because preceding text - % often leads into it. - \penalty100 - \fi - \vskip\envskipamount - \fi - \fi -}} - -\def\afterenvbreak{{% % =10000 instead of <10000 because of a special case in \itemzzz and % \sectionheading, q.v. \ifnum \lastpenalty=10000 \else @@ -7198,6 +6010,8 @@ end \fi }} +\let\afterenvbreak = \aboveenvbreak + % \nonarrowing is a flag. If "set", @lisp etc don't narrow margins; it will % also clear it, so that its embedded environments do the narrowing again. \let\nonarrowing=\relax @@ -7235,13 +6049,9 @@ end % side, and for 6pt waste from % each corner char, and rule thickness \normbskip=\baselineskip \normpskip=\parskip \normlskip=\lineskip - % - % If this cartouche directly follows a sectioning command, we need the - % \parskip glue (backspaced over by default) or the cartouche can - % collide with the section heading. - \ifnum\lastpenalty>10000 \vskip\parskip \penalty\lastpenalty \fi - % - \setbox\groupbox=\vbox\bgroup + % Flag to tell @lisp, etc., not to narrow margin. + \let\nonarrowing = t% + \vbox\bgroup \baselineskip=0pt\parskip=0pt\lineskip=0pt \carttop \hbox\bgroup @@ -7254,7 +6064,7 @@ end \lineskip=\normlskip \parskip=\normpskip \vskip -\parskip - \comment % For explanation, see the end of def\group. + \comment % For explanation, see the end of \def\group. } \def\Ecartouche{% \ifhmode\par\fi @@ -7265,7 +6075,6 @@ end \egroup \cartbot \egroup - \addgroupbox \checkinserts } @@ -7275,7 +6084,7 @@ end \newdimen\nonfillparindent \def\nonfillstart{% \aboveenvbreak - \ifdim\hfuzz < 12pt \hfuzz = 12pt \fi % Don't be fussy + \hfuzz = 12pt % Don't be fussy \sepspaces % Make spaces be word-separators rather than space tokens. \let\par = \lisppar % don't ignore blank lines \obeylines % each line of input is a line of output @@ -7341,42 +6150,41 @@ end } % We often define two environments, @foo and @smallfoo. -% Let's do it in one command. #1 is the env name, #2 the definition. -\def\makedispenvdef#1#2{% - \expandafter\envdef\csname#1\endcsname {\setnormaldispenv #2}% - \expandafter\envdef\csname small#1\endcsname {\setsmalldispenv #2}% +% Let's do it by one command: +\def\makedispenv #1#2{ + \expandafter\envdef\csname#1\endcsname {\setnormaldispenv #2} + \expandafter\envdef\csname small#1\endcsname {\setsmalldispenv #2} \expandafter\let\csname E#1\endcsname \afterenvbreak \expandafter\let\csname Esmall#1\endcsname \afterenvbreak } -% Define two environment synonyms (#1 and #2) for an environment. -\def\maketwodispenvdef#1#2#3{% - \makedispenvdef{#1}{#3}% - \makedispenvdef{#2}{#3}% +% Define two synonyms: +\def\maketwodispenvs #1#2#3{ + \makedispenv{#1}{#3} + \makedispenv{#2}{#3} } -% -% @lisp: indented, narrowed, typewriter font; -% @example: same as @lisp. + +% @lisp: indented, narrowed, typewriter font; @example: same as @lisp. % % @smallexample and @smalllisp: use smaller fonts. % Originally contributed by Pavel@xerox. % -\maketwodispenvdef{lisp}{example}{% +\maketwodispenvs {lisp}{example}{% \nonfillstart \tt\setupmarkupstyle{example}% \let\kbdfont = \kbdexamplefont % Allow @kbd to do something special. - \gobble % eat return + \gobble % eat return } % @display/@smalldisplay: same as @lisp except keep current font. % -\makedispenvdef{display}{% +\makedispenv {display}{% \nonfillstart \gobble } % @format/@smallformat: same as @display except don't narrow margins. % -\makedispenvdef{format}{% +\makedispenv{format}{% \let\nonarrowing = t% \nonfillstart \gobble @@ -7395,20 +6203,16 @@ end \envdef\flushright{% \let\nonarrowing = t% \nonfillstart - \advance\leftskip by 0pt plus 1fill\relax + \advance\leftskip by 0pt plus 1fill \gobble } \let\Eflushright = \afterenvbreak % @raggedright does more-or-less normal line breaking but no right -% justification. From plain.tex. Don't stretch around special -% characters in urls in this environment, since the stretch at the right -% should be enough. +% justification. From plain.tex. \envdef\raggedright{% - \rightskip0pt plus2.4em \spaceskip.3333em \xspaceskip.5em\relax - \def\urefprestretchamount{0pt}% - \def\urefpoststretchamount{0pt}% + \rightskip0pt plus2em \spaceskip.3333em \xspaceskip.5em\relax } \let\Eraggedright\par @@ -7434,28 +6238,43 @@ end % we're doing normal filling. So, when using \aboveenvbreak and % \afterenvbreak, temporarily make \parskip 0. % -\makedispenvdef{quotation}{\quotationstart} -% \def\quotationstart{% - \indentedblockstart % same as \indentedblock, but increase right margin too. + {\parskip=0pt \aboveenvbreak}% because \aboveenvbreak inserts \parskip + \parindent=0pt + % + % @cartouche defines \nonarrowing to inhibit narrowing at next level down. \ifx\nonarrowing\relax + \advance\leftskip by \lispnarrowing \advance\rightskip by \lispnarrowing + \exdentamount = \lispnarrowing + \else + \let\nonarrowing = \relax \fi \parsearg\quotationlabel } +\envdef\quotation{% + \setnormaldispenv + \quotationstart +} + +\envdef\smallquotation{% + \setsmalldispenv + \quotationstart +} +\let\Esmallquotation = \Equotation + % We have retained a nonzero parskip for the environment, since we're % doing normal filling. % \def\Equotation{% \par - \ifx\quotationauthor\thisisundefined\else + \ifx\quotationauthor\undefined\else % indent a bit. \leftline{\kern 2\leftskip \sl ---\quotationauthor}% \fi {\parskip=0pt \afterenvbreak}% } -\def\Esmallquotation{\Equotation} % If we're given an argument, typeset it in bold with a colon after. \def\quotationlabel#1{% @@ -7465,32 +6284,6 @@ end \fi } -% @indentedblock is like @quotation, but indents only on the left and -% has no optional argument. -% -\makedispenvdef{indentedblock}{\indentedblockstart} -% -\def\indentedblockstart{% - {\parskip=0pt \aboveenvbreak}% because \aboveenvbreak inserts \parskip - \parindent=0pt - % - % @cartouche defines \nonarrowing to inhibit narrowing at next level down. - \ifx\nonarrowing\relax - \advance\leftskip by \lispnarrowing - \exdentamount = \lispnarrowing - \else - \let\nonarrowing = \relax - \fi -} - -% Keep a nonzero parskip for the environment, since we're doing normal filling. -% -\def\Eindentedblock{% - \par - {\parskip=0pt \afterenvbreak}% -} -\def\Esmallindentedblock{\Eindentedblock} - % LaTeX-like @verbatim...@end verbatim and @verb{...} % If we want to allow any as delimiter, @@ -7538,28 +6331,21 @@ end % Setup for the @verbatim environment % -% Real tab expansion. +% Real tab expansion \newdimen\tabw \setbox0=\hbox{\tt\space} \tabw=8\wd0 % tab amount % -% We typeset each line of the verbatim in an \hbox, so we can handle -% tabs. The \global is in case the verbatim line starts with an accent, -% or some other command that starts with a begin-group. Otherwise, the -% entire \verbbox would disappear at the corresponding end-group, before -% it is typeset. Meanwhile, we can't have nested verbatim commands -% (can we?), so the \global won't be overwriting itself. -\newbox\verbbox -\def\starttabbox{\global\setbox\verbbox=\hbox\bgroup} +\def\starttabbox{\setbox0=\hbox\bgroup} % \begingroup \catcode`\^^I=\active \gdef\tabexpand{% \catcode`\^^I=\active \def^^I{\leavevmode\egroup - \dimen\verbbox=\wd\verbbox % the width so far, or since the previous tab - \divide\dimen\verbbox by\tabw - \multiply\dimen\verbbox by\tabw % compute previous multiple of \tabw - \advance\dimen\verbbox by\tabw % advance to next multiple of \tabw - \wd\verbbox=\dimen\verbbox \box\verbbox \starttabbox + \dimen0=\wd0 % the width so far, or since the previous tab + \divide\dimen0 by\tabw + \multiply\dimen0 by\tabw % compute previous multiple of \tabw + \advance\dimen0 by\tabw % advance to next multiple of \tabw + \wd0=\dimen0 \box0 \starttabbox }% } \endgroup @@ -7568,16 +6354,15 @@ end \def\setupverbatim{% \let\nonarrowing = t% \nonfillstart - \tt % easiest (and conventionally used) font for verbatim - % The \leavevmode here is for blank lines. Otherwise, we would - % never \starttabox and the \egroup would end verbatim mode. - \def\par{\leavevmode\egroup\box\verbbox\endgraf}% + % Easiest (and conventionally used) font for verbatim + \tt + \def\par{\leavevmode\egroup\box0\endgraf}% \tabexpand \setupmarkupstyle{verbatim}% % Respect line breaks, % print special symbols as themselves, and - % make each space count. - % Must do in this order: + % make each space count + % must do in this order: \obeylines \uncatcodespecials \sepspaces \everypar{\starttabbox}% } @@ -7634,7 +6419,6 @@ end \makevalueexpandable \setupverbatim \indexnofonts % Allow `@@' and other weird things in file names. - \wlog{texinfo.tex: doing @verbatiminclude of #1^^J}% \input #1 \afterenvbreak }% @@ -7648,7 +6432,7 @@ end % typesetting commands (@smallbook, font changes, etc.) have to be done % beforehand -- and a) we want @copying to be done first in the source % file; b) letting users define the frontmatter in as flexible order as -% possible is desirable. +% possible is very desirable. % \def\copying{\checkenv{}\begingroup\scanargctxt\docopying} \def\docopying#1@end copying{\endgroup\def\copyingtext{#1}} @@ -7684,7 +6468,7 @@ end % commands also insert a nobreak penalty, and we don't want to allow % a break between a section heading and a defun. % - % As a further refinement, we avoid "club" headers by signalling + % As a minor refinement, we avoid "club" headers by signalling % with penalty of 10003 after the very first @deffn in the % sequence (see above), and penalty of 10002 after any following % @def command. @@ -7721,7 +6505,7 @@ end #1#2 \endheader % common ending: \interlinepenalty = 10000 - \advance\rightskip by 0pt plus 1fil\relax + \advance\rightskip by 0pt plus 1fil \endgraf \nobreak\vskip -\parskip \penalty\defunpenalty % signal to \startdefun and \dodefunx @@ -7743,7 +6527,7 @@ end \temp } -% \domakedefun \deffn \deffnx \deffnheader { (defn. of \deffnheader) } +% \domakedefun \deffn \deffnx \deffnheader % % Define \deffn and \deffnx, without parameters. % \deffnheader has to be defined explicitly. @@ -7751,36 +6535,13 @@ end \def\domakedefun#1#2#3{% \envdef#1{% \startdefun - \doingtypefnfalse % distinguish typed functions from all else \parseargusing\activeparens{\printdefunline#3}% }% \def#2{\dodefunx#1}% \def#3% } -\newif\ifdoingtypefn % doing typed function? -\newif\ifrettypeownline % typeset return type on its own line? - -% @deftypefnnewline on|off says whether the return type of typed functions -% are printed on their own line. This affects @deftypefn, @deftypefun, -% @deftypeop, and @deftypemethod. -% -\parseargdef\deftypefnnewline{% - \def\temp{#1}% - \ifx\temp\onword - \expandafter\let\csname SETtxideftypefnnl\endcsname - = \empty - \else\ifx\temp\offword - \expandafter\let\csname SETtxideftypefnnl\endcsname - = \relax - \else - \errhelp = \EMsimple - \errmessage{Unknown @txideftypefnnl value `\temp', - must be on|off}% - \fi\fi -} - -% Untyped functions: +%%% Untyped functions: % @deffn category name args \makedefun{deffn}{\deffngeneral{}} @@ -7799,7 +6560,7 @@ end \defname{#2}{}{#3}\magicamp\defunargs{#4\unskip}% } -% Typed functions: +%%% Typed functions: % @deftypefn category type name args \makedefun{deftypefn}{\deftypefngeneral{}} @@ -7814,11 +6575,10 @@ end % \def\deftypefngeneral#1#2 #3 #4 #5\endheader{% \dosubind{fn}{\code{#4}}{#1}% - \doingtypefntrue \defname{#2}{#3}{#4}\defunargs{#5\unskip}% } -% Typed variables: +%%% Typed variables: % @deftypevr category type var args \makedefun{deftypevr}{\deftypecvgeneral{}} @@ -7836,7 +6596,7 @@ end \defname{#2}{#3}{#4}\defunargs{#5\unskip}% } -% Untyped variables: +%%% Untyped variables: % @defvr category var args \makedefun{defvr}#1 {\deftypevrheader{#1} {} } @@ -7847,8 +6607,7 @@ end % \defcvof {category of}class var args \def\defcvof#1#2 {\deftypecvof{#1}#2 {} } -% Types: - +%%% Type: % @deftp category name args \makedefun{deftp}#1 #2 #3\endheader{% \doind{tp}{\code{#2}}% @@ -7876,49 +6635,25 @@ end % We are followed by (but not passed) the arguments, if any. % \def\defname#1#2#3{% - \par % Get the values of \leftskip and \rightskip as they were outside the @def... \advance\leftskip by -\defbodyindent % - % Determine if we are typesetting the return type of a typed function - % on a line by itself. - \rettypeownlinefalse - \ifdoingtypefn % doing a typed function specifically? - % then check user option for putting return type on its own line: - \expandafter\ifx\csname SETtxideftypefnnl\endcsname\relax \else - \rettypeownlinetrue - \fi - \fi - % - % How we'll format the category name. Putting it in brackets helps + % How we'll format the type name. Putting it in brackets helps % distinguish it from the body text that may end up on the next line % just below it. \def\temp{#1}% \setbox0=\hbox{\kern\deflastargmargin \ifx\temp\empty\else [\rm\temp]\fi} % - % Figure out line sizes for the paragraph shape. We'll always have at - % least two. - \tempnum = 2 - % + % Figure out line sizes for the paragraph shape. % The first line needs space for \box0; but if \rightskip is nonzero, % we need only space for the part of \box0 which exceeds it: \dimen0=\hsize \advance\dimen0 by -\wd0 \advance\dimen0 by \rightskip - % - % If doing a return type on its own line, we'll have another line. - \ifrettypeownline - \advance\tempnum by 1 - \def\maybeshapeline{0in \hsize}% - \else - \def\maybeshapeline{}% - \fi - % % The continuations: \dimen2=\hsize \advance\dimen2 by -\defargsindent + % (plain.tex says that \dimen1 should be used only as global.) + \parshape 2 0in \dimen0 \defargsindent \dimen2 % - % The final paragraph shape: - \parshape \tempnum 0in \dimen0 \maybeshapeline \defargsindent \dimen2 - % - % Put the category name at the right margin. + % Put the type name to the right margin. \noindent \hbox to 0pt{% \hfil\box0 \kern-\hsize @@ -7940,19 +6675,11 @@ end % . this still does not fix the ?` and !` ligatures, but so far no % one has made identifiers using them :). \df \tt - \def\temp{#2}% text of the return type - \ifx\temp\empty\else - \tclose{\temp}% typeset the return type - \ifrettypeownline - % put return type on its own line; prohibit line break following: - \hfil\vadjust{\nobreak}\break - \else - \space % type on same line, so just followed by a space - \fi - \fi % no return type + \def\temp{#2}% return value type + \ifx\temp\empty\else \tclose{\temp} \fi #3% output function name }% - {\rm\enskip}% hskip 0.5 em of \rmfont + {\rm\enskip}% hskip 0.5 em of \tenrm % \boldbrax % arguments will be output next, if any. @@ -7969,10 +6696,7 @@ end \df \sl \hyphenchar\font=0 % % On the other hand, if an argument has two dashes (for instance), we - % want a way to get ttsl. We used to recommend @var for that, so - % leave the code in, but it's strange for @var to lead to typewriter. - % Nowadays we recommend @code, since the difference between a ttsl hyphen - % and a tt hyphen is pretty tiny. @code also disables ?` !`. + % want a way to get ttsl. Let's try @var for that. \def\var##1{{\setupmarkupstyle{var}\ttslanted{##1}}}% #1% \sl\hyphenchar\font=45 @@ -8070,7 +6794,7 @@ end % To do this right we need a feature of e-TeX, \scantokens, % which we arrange to emulate with a temporary file in ordinary TeX. -\ifx\eTeXversion\thisisundefined +\ifx\eTeXversion\undefined \newwrite\macscribble \def\scantokens#1{% \toks0={#1}% @@ -8081,41 +6805,29 @@ end } \fi -% alias because \c means cedilla in @tex or @math -\let\texinfoc=\c - -\newcount\savedcatcodeone -\newcount\savedcatcodetwo - -% Used at the time of macro expansion. -% Argument is macro body with arguments substituted \def\scanmacro#1{% - \newlinechar`\^^M - \def\xeatspaces{\eatspaces}% - % - % Temporarily undo catcode changes of \printindex. Set catcode of @ to - % 0 so that @-commands in macro expansions aren't printed literally when - % formatting an index file, where \ is used as the escape character. - \savedcatcodeone=\catcode`\@ - \savedcatcodetwo=\catcode`\\ - \catcode`\@=0 - \catcode`\\=\active - % - % Process the macro body under the current catcode regime. - \scantokens{#1@texinfoc}% - % - \catcode`\@=\savedcatcodeone - \catcode`\\=\savedcatcodetwo - % - % The \texinfoc is to remove the \newlinechar added by \scantokens, and - % can be noticed by \parsearg. - % We avoid surrounding the call to \scantokens with \bgroup and \egroup - % to allow macros to open or close groups themselves. + \begingroup + \newlinechar`\^^M + \let\xeatspaces\eatspaces + % Undo catcode changes of \startcontents and \doprintindex + % When called from @insertcopying or (short)caption, we need active + % backslash to get it printed correctly. Previously, we had + % \catcode`\\=\other instead. We'll see whether a problem appears + % with macro expansion. --kasal, 19aug04 + \catcode`\@=0 \catcode`\\=\active \escapechar=`\@ + % ... and \example + \spaceisspace + % + % Append \endinput to make sure that TeX does not see the ending newline. + % I've verified that it is necessary both for e-TeX and for ordinary TeX + % --kasal, 29nov03 + \scantokens{#1\endinput}% + \endgroup } -% Used for copying and captions \def\scanexp#1{% - \expandafter\scanmacro\expandafter{#1}% + \edef\temp{\noexpand\scanmacro{#1}}% + \temp } \newcount\paramno % Count of parameters @@ -8123,7 +6835,7 @@ end \newif\ifrecursive % Is it recursive? % List of all defined macros in the form -% \commondummyword\macro1\commondummyword\macro2... +% \definedummyword\macro1\definedummyword\macro2... % Currently is also contains all @aliases; the list can be split % if there is a need. \def\macrolist{} @@ -8131,7 +6843,7 @@ end % Add the macro to \macrolist \def\addtomacrolist#1{\expandafter \addtomacrolistxxx \csname#1\endcsname} \def\addtomacrolistxxx#1{% - \toks0 = \expandafter{\macrolist\commondummyword#1}% + \toks0 = \expandafter{\macrolist\definedummyword#1}% \xdef\macrolist{\the\toks0}% } @@ -8165,60 +6877,46 @@ end % Macro bodies are absorbed as an argument in a context where % all characters are catcode 10, 11 or 12, except \ which is active -% (as in normal texinfo). It is necessary to change the definition of \ -% to recognize macro arguments; this is the job of \mbodybackslash. -% +% (as in normal texinfo). It is necessary to change the definition of \. + % Non-ASCII encodings make 8-bit characters active, so un-activate % them to avoid their expansion. Must do this non-globally, to % confine the change to the current group. -% + % It's necessary to have hard CRs when the macro is executed. This is -% done by making ^^M (\endlinechar) catcode 12 when reading the macro +% done by making ^^M (\endlinechar) catcode 12 when reading the macro % body, and then making it the \newlinechar in \scanmacro. -% -\def\scanctxt{% used as subroutine + +\def\scanctxt{% \catcode`\"=\other \catcode`\+=\other \catcode`\<=\other \catcode`\>=\other + \catcode`\@=\other \catcode`\^=\other \catcode`\_=\other \catcode`\|=\other \catcode`\~=\other - \passthroughcharstrue + \ifx\declaredencoding\ascii \else \setnonasciicharscatcodenonglobal\other \fi } -\def\scanargctxt{% used for copying and captions, not macros. +\def\scanargctxt{% \scanctxt - \catcode`\@=\other \catcode`\\=\other \catcode`\^^M=\other } -\def\macrobodyctxt{% used for @macro definitions +\def\macrobodyctxt{% \scanctxt - \catcode`\ =\other - \catcode`\@=\other \catcode`\{=\other \catcode`\}=\other \catcode`\^^M=\other \usembodybackslash } -% Used when scanning braced macro arguments. Note, however, that catcode -% changes here are ineffectual if the macro invocation was nested inside -% an argument to another Texinfo command. \def\macroargctxt{% \scanctxt - \catcode`\ =\active - \catcode`\^^M=\other - \catcode`\\=\active -} - -\def\macrolineargctxt{% used for whole-line arguments without braces - \scanctxt - \catcode`\{=\other - \catcode`\}=\other + \catcode`\\=\other } % \mbodybackslash is the definition of \ in @macro bodies. @@ -8226,30 +6924,22 @@ end % where N is the macro parameter number. % We define \csname macarg.\endcsname to be \realbackslash, so % \\ in macro replacement text gets you a backslash. -% + {\catcode`@=0 @catcode`@\=@active @gdef@usembodybackslash{@let\=@mbodybackslash} @gdef@mbodybackslash#1\{@csname macarg.#1@endcsname} } \expandafter\def\csname macarg.\endcsname{\realbackslash} -\def\margbackslash#1{\char`\#1 } - \def\macro{\recursivefalse\parsearg\macroxxx} \def\rmacro{\recursivetrue\parsearg\macroxxx} \def\macroxxx#1{% - \getargs{#1}% now \macname is the macname and \argl the arglist + \getargs{#1}% now \macname is the macname and \argl the arglist \ifx\argl\empty % no arguments - \paramno=0\relax + \paramno=0% \else \expandafter\parsemargdef \argl;% - \if\paramno>256\relax - \ifx\eTeXversion\thisisundefined - \errhelp = \EMsimple - \errmessage{You need eTeX to compile a file with macros with more than 256 arguments} - \fi - \fi \fi \if1\csname ismacro.\the\macname\endcsname \message{Warning: redefining \the\macname}% @@ -8272,7 +6962,7 @@ end % Remove the macro name from \macrolist: \begingroup \expandafter\let\csname#1\endcsname \relax - \let\commondummyword\unmacrodo + \let\definedummyword\unmacrodo \xdef\macrolist{\macrolist}% \endgroup \else @@ -8287,464 +6977,129 @@ end \ifx #1\relax % remove this \else - \noexpand\commondummyword \noexpand#1% + \noexpand\definedummyword \noexpand#1% \fi } -% \getargs -- Parse the arguments to a @macro line. Set \macname to -% the name of the macro, and \argl to the braced argument list. -\def\getargs#1{\getargsxxx#1{}} -\def\getargsxxx#1#{\getmacname #1 \relax\getmacargs} -\def\getmacname#1 #2\relax{\macname={#1}} -\def\getmacargs#1{\def\argl{#1}} -% This made use of the feature that if the last token of a +% This makes use of the obscure feature that if the last token of a % is #, then the preceding argument is delimited by % an opening brace, and that opening brace is not consumed. +\def\getargs#1{\getargsxxx#1{}} +\def\getargsxxx#1#{\getmacname #1 \relax\getmacargs} +\def\getmacname #1 #2\relax{\macname={#1}} +\def\getmacargs#1{\def\argl{#1}} -% Parse the optional {params} list to @macro or @rmacro. -% Set \paramno to the number of arguments, -% and \paramlist to a parameter text for the macro (e.g. #1,#2,#3 for a -% three-param macro.) Define \macarg.BLAH for each BLAH in the params -% list to some hook where the argument is to be expanded. If there are -% less than 10 arguments that hook is to be replaced by ##N where N -% is the position in that list, that is to say the macro arguments are to be -% defined `a la TeX in the macro body. -% +% Parse the optional {params} list. Set up \paramno and \paramlist +% so \defmacro knows what to do. Define \macarg.blah for each blah +% in the params list, to be ##N where N is the position in that list. % That gets used by \mbodybackslash (above). + +% We need to get `macro parameter char #' into several definitions. +% The technique used is stolen from LaTeX: let \hash be something +% unexpandable, insert that wherever you need a #, and then redefine +% it to # just before using the token list produced. % -% If there are 10 or more arguments, a different technique is used: see -% \parsemmanyargdef. -% -\def\parsemargdef#1;{% - \paramno=0\def\paramlist{}% - \let\hash\relax - % \hash is redefined to `#' later to get it into definitions - \let\xeatspaces\relax - \parsemargdefxxx#1,;,% - \ifnum\paramno<10\relax\else - \paramno0\relax - \parsemmanyargdef@@#1,;,% 10 or more arguments - \fi -} +% The same technique is used to protect \eatspaces till just before +% the macro is used. + +\def\parsemargdef#1;{\paramno=0\def\paramlist{}% + \let\hash\relax\let\xeatspaces\relax\parsemargdefxxx#1,;,} \def\parsemargdefxxx#1,{% \if#1;\let\next=\relax \else \let\next=\parsemargdefxxx - \advance\paramno by 1 + \advance\paramno by 1% \expandafter\edef\csname macarg.\eatspaces{#1}\endcsname {\xeatspaces{\hash\the\paramno}}% \edef\paramlist{\paramlist\hash\the\paramno,}% \fi\next} -% \parsemacbody, \parsermacbody -% -% Read recursive and nonrecursive macro bodies. (They're different since -% rec and nonrec macros end differently.) -% -% We are in \macrobodyctxt, and the \xdef causes backslashshes in the macro -% body to be transformed. -% Set \macrobody to the body of the macro, and call \defmacro. -% -{\catcode`\ =\other\long\gdef\parsemacbody#1@end macro{% -\xdef\macrobody{\eatcr{#1}}\endgroup\defmacro}}% -{\catcode`\ =\other\long\gdef\parsermacbody#1@end rmacro{% -\xdef\macrobody{\eatcr{#1}}\endgroup\defmacro}}% +% These two commands read recursive and nonrecursive macro bodies. +% (They're different since rec and nonrec macros end differently.) -% Make @ a letter, so that we can make private-to-Texinfo macro names. -\edef\texiatcatcode{\the\catcode`\@} -\catcode `@=11\relax +\long\def\parsemacbody#1@end macro% +{\xdef\temp{\eatcr{#1}}\endgroup\defmacro}% +\long\def\parsermacbody#1@end rmacro% +{\xdef\temp{\eatcr{#1}}\endgroup\defmacro}% -%%%%%%%%%%%%%% Code for > 10 arguments only %%%%%%%%%%%%%%%%%% - -% If there are 10 or more arguments, a different technique is used, where the -% hook remains in the body, and when macro is to be expanded the body is -% processed again to replace the arguments. -% -% In that case, the hook is \the\toks N-1, and we simply set \toks N-1 to the -% argument N value and then \edef the body (nothing else will expand because of -% the catcode regime under which the body was input). -% -% If you compile with TeX (not eTeX), and you have macros with 10 or more -% arguments, no macro can have more than 256 arguments (else error). -% -% In case that there are 10 or more arguments we parse again the arguments -% list to set new definitions for the \macarg.BLAH macros corresponding to -% each BLAH argument. It was anyhow needed to parse already once this list -% in order to count the arguments, and as macros with at most 9 arguments -% are by far more frequent than macro with 10 or more arguments, defining -% twice the \macarg.BLAH macros does not cost too much processing power. -\def\parsemmanyargdef@@#1,{% - \if#1;\let\next=\relax - \else - \let\next=\parsemmanyargdef@@ - \edef\tempb{\eatspaces{#1}}% - \expandafter\def\expandafter\tempa - \expandafter{\csname macarg.\tempb\endcsname}% - % Note that we need some extra \noexpand\noexpand, this is because we - % don't want \the to be expanded in the \parsermacbody as it uses an - % \xdef . - \expandafter\edef\tempa - {\noexpand\noexpand\noexpand\the\toks\the\paramno}% - \advance\paramno by 1\relax - \fi\next} - - -\let\endargs@\relax -\let\nil@\relax -\def\nilm@{\nil@}% -\long\def\nillm@{\nil@}% - -% This macro is expanded during the Texinfo macro expansion, not during its -% definition. It gets all the arguments' values and assigns them to macros -% macarg.ARGNAME -% -% #1 is the macro name -% #2 is the list of argument names -% #3 is the list of argument values -\def\getargvals@#1#2#3{% - \def\macargdeflist@{}% - \def\saveparamlist@{#2}% Need to keep a copy for parameter expansion. - \def\paramlist{#2,\nil@}% - \def\macroname{#1}% - \begingroup - \macroargctxt - \def\argvaluelist{#3,\nil@}% - \def\@tempa{#3}% - \ifx\@tempa\empty - \setemptyargvalues@ - \else - \getargvals@@ - \fi -} -\def\getargvals@@{% - \ifx\paramlist\nilm@ - % Some sanity check needed here that \argvaluelist is also empty. - \ifx\argvaluelist\nillm@ - \else - \errhelp = \EMsimple - \errmessage{Too many arguments in macro `\macroname'!}% - \fi - \let\next\macargexpandinbody@ - \else - \ifx\argvaluelist\nillm@ - % No more arguments values passed to macro. Set remaining named-arg - % macros to empty. - \let\next\setemptyargvalues@ - \else - % pop current arg name into \@tempb - \def\@tempa##1{\pop@{\@tempb}{\paramlist}##1\endargs@}% - \expandafter\@tempa\expandafter{\paramlist}% - % pop current argument value into \@tempc - \def\@tempa##1{\longpop@{\@tempc}{\argvaluelist}##1\endargs@}% - \expandafter\@tempa\expandafter{\argvaluelist}% - % Here \@tempb is the current arg name and \@tempc is the current arg value. - % First place the new argument macro definition into \@tempd - \expandafter\macname\expandafter{\@tempc}% - \expandafter\let\csname macarg.\@tempb\endcsname\relax - \expandafter\def\expandafter\@tempe\expandafter{% - \csname macarg.\@tempb\endcsname}% - \edef\@tempd{\long\def\@tempe{\the\macname}}% - \push@\@tempd\macargdeflist@ - \let\next\getargvals@@ - \fi - \fi - \next -} - -\def\push@#1#2{% - \expandafter\expandafter\expandafter\def - \expandafter\expandafter\expandafter#2% - \expandafter\expandafter\expandafter{% - \expandafter#1#2}% -} - -% Replace arguments by their values in the macro body, and place the result -% in macro \@tempa. -% -\def\macvalstoargs@{% - % To do this we use the property that token registers that are \the'ed - % within an \edef expand only once. So we are going to place all argument - % values into respective token registers. - % - % First we save the token context, and initialize argument numbering. - \begingroup - \paramno0\relax - % Then, for each argument number #N, we place the corresponding argument - % value into a new token list register \toks#N - \expandafter\putargsintokens@\saveparamlist@,;,% - % Then, we expand the body so that argument are replaced by their - % values. The trick for values not to be expanded themselves is that they - % are within tokens and that tokens expand only once in an \edef . - \edef\@tempc{\csname mac.\macroname .body\endcsname}% - % Now we restore the token stack pointer to free the token list registers - % which we have used, but we make sure that expanded body is saved after - % group. - \expandafter - \endgroup - \expandafter\def\expandafter\@tempa\expandafter{\@tempc}% - } - -% Define the named-macro outside of this group and then close this group. -% -\def\macargexpandinbody@{% - \expandafter - \endgroup - \macargdeflist@ - % First the replace in body the macro arguments by their values, the result - % is in \@tempa . - \macvalstoargs@ - % Then we point at the \norecurse or \gobble (for recursive) macro value - % with \@tempb . - \expandafter\let\expandafter\@tempb\csname mac.\macroname .recurse\endcsname - % Depending on whether it is recursive or not, we need some tailing - % \egroup . - \ifx\@tempb\gobble - \let\@tempc\relax - \else - \let\@tempc\egroup - \fi - % And now we do the real job: - \edef\@tempd{\noexpand\@tempb{\macroname}\noexpand\scanmacro{\@tempa}\@tempc}% - \@tempd -} - -\def\putargsintokens@#1,{% - \if#1;\let\next\relax - \else - \let\next\putargsintokens@ - % First we allocate the new token list register, and give it a temporary - % alias \@tempb . - \toksdef\@tempb\the\paramno - % Then we place the argument value into that token list register. - \expandafter\let\expandafter\@tempa\csname macarg.#1\endcsname - \expandafter\@tempb\expandafter{\@tempa}% - \advance\paramno by 1\relax - \fi - \next -} - -% Trailing missing arguments are set to empty. -% -\def\setemptyargvalues@{% - \ifx\paramlist\nilm@ - \let\next\macargexpandinbody@ - \else - \expandafter\setemptyargvaluesparser@\paramlist\endargs@ - \let\next\setemptyargvalues@ - \fi - \next -} - -\def\setemptyargvaluesparser@#1,#2\endargs@{% - \expandafter\def\expandafter\@tempa\expandafter{% - \expandafter\def\csname macarg.#1\endcsname{}}% - \push@\@tempa\macargdeflist@ - \def\paramlist{#2}% -} - -% #1 is the element target macro -% #2 is the list macro -% #3,#4\endargs@ is the list value -\def\pop@#1#2#3,#4\endargs@{% - \def#1{#3}% - \def#2{#4}% -} -\long\def\longpop@#1#2#3,#4\endargs@{% - \long\def#1{#3}% - \long\def#2{#4}% -} - - -%%%%%%%%%%%%%% End of code for > 10 arguments %%%%%%%%%%%%%%%%%% - - -% This defines a Texinfo @macro or @rmacro, called by \parsemacbody. -% \macrobody has the body of the macro in it, with placeholders for -% its parameters, looking like "\xeatspaces{\hash 1}". -% \paramno is the number of parameters -% \paramlist is a TeX parameter text, e.g. "#1,#2,#3," -% There are four cases: macros of zero, one, up to nine, and many arguments. +% This defines the macro itself. There are six cases: recursive and +% nonrecursive macros of zero, one, and many arguments. +% Much magic with \expandafter here. % \xdef is used so that macro definitions will survive the file -% they're defined in: @include reads the file inside a group. -% +% they're defined in; @include reads the file inside a group. \def\defmacro{% \let\hash=##% convert placeholders to macro parameter chars - \ifnum\paramno=1 - \def\xeatspaces##1{##1}% - % This removes the pair of braces around the argument. We don't - % use \eatspaces, because this can cause ends of lines to be lost - % when the argument to \eatspaces is read, leading to line-based - % commands like "@itemize" not being read correctly. - \else - \let\xeatspaces\relax % suppress expansion - \fi - \ifcase\paramno - % 0 - \expandafter\xdef\csname\the\macname\endcsname{% - \bgroup - \noexpand\spaceisspace - \noexpand\endlineisspace - \noexpand\expandafter % skip any whitespace after the macro name. - \expandafter\noexpand\csname\the\macname @@@\endcsname}% - \expandafter\xdef\csname\the\macname @@@\endcsname{% - \egroup - \noexpand\scanmacro{\macrobody}}% - \or % 1 - \expandafter\xdef\csname\the\macname\endcsname{% - \bgroup - \noexpand\braceorline - \expandafter\noexpand\csname\the\macname @@@\endcsname}% - \expandafter\xdef\csname\the\macname @@@\endcsname##1{% - \egroup - \noexpand\scanmacro{\macrobody}% - }% - \else % at most 9 - \ifnum\paramno<10\relax - % @MACNAME sets the context for reading the macro argument - % @MACNAME@@ gets the argument, processes backslashes and appends a - % comma. - % @MACNAME@@@ removes braces surrounding the argument list. - % @MACNAME@@@@ scans the macro body with arguments substituted. + \ifrecursive + \ifcase\paramno + % 0 \expandafter\xdef\csname\the\macname\endcsname{% - \bgroup - \noexpand\expandafter % This \expandafter skip any spaces after the - \noexpand\macroargctxt % macro before we change the catcode of space. - \noexpand\expandafter - \expandafter\noexpand\csname\the\macname @@\endcsname}% - \expandafter\xdef\csname\the\macname @@\endcsname##1{% - \noexpand\passargtomacro - \expandafter\noexpand\csname\the\macname @@@\endcsname{##1,}}% - \expandafter\xdef\csname\the\macname @@@\endcsname##1{% - \expandafter\noexpand\csname\the\macname @@@@\endcsname ##1}% + \noexpand\scanmacro{\temp}}% + \or % 1 + \expandafter\xdef\csname\the\macname\endcsname{% + \bgroup\noexpand\macroargctxt + \noexpand\braceorline + \expandafter\noexpand\csname\the\macname xxx\endcsname}% + \expandafter\xdef\csname\the\macname xxx\endcsname##1{% + \egroup\noexpand\scanmacro{\temp}}% + \else % many + \expandafter\xdef\csname\the\macname\endcsname{% + \bgroup\noexpand\macroargctxt + \noexpand\csname\the\macname xx\endcsname}% + \expandafter\xdef\csname\the\macname xx\endcsname##1{% + \expandafter\noexpand\csname\the\macname xxx\endcsname ##1,}% \expandafter\expandafter \expandafter\xdef \expandafter\expandafter - \csname\the\macname @@@@\endcsname\paramlist{% - \egroup\noexpand\scanmacro{\macrobody}}% - \else % 10 or more: + \csname\the\macname xxx\endcsname + \paramlist{\egroup\noexpand\scanmacro{\temp}}% + \fi + \else + \ifcase\paramno + % 0 \expandafter\xdef\csname\the\macname\endcsname{% - \noexpand\getargvals@{\the\macname}{\argl}% - }% - \global\expandafter\let\csname mac.\the\macname .body\endcsname\macrobody - \global\expandafter\let\csname mac.\the\macname .recurse\endcsname\gobble + \noexpand\norecurse{\the\macname}% + \noexpand\scanmacro{\temp}\egroup}% + \or % 1 + \expandafter\xdef\csname\the\macname\endcsname{% + \bgroup\noexpand\macroargctxt + \noexpand\braceorline + \expandafter\noexpand\csname\the\macname xxx\endcsname}% + \expandafter\xdef\csname\the\macname xxx\endcsname##1{% + \egroup + \noexpand\norecurse{\the\macname}% + \noexpand\scanmacro{\temp}\egroup}% + \else % many + \expandafter\xdef\csname\the\macname\endcsname{% + \bgroup\noexpand\macroargctxt + \expandafter\noexpand\csname\the\macname xx\endcsname}% + \expandafter\xdef\csname\the\macname xx\endcsname##1{% + \expandafter\noexpand\csname\the\macname xxx\endcsname ##1,}% + \expandafter\expandafter + \expandafter\xdef + \expandafter\expandafter + \csname\the\macname xxx\endcsname + \paramlist{% + \egroup + \noexpand\norecurse{\the\macname}% + \noexpand\scanmacro{\temp}\egroup}% \fi \fi} -\catcode `\@\texiatcatcode\relax % end private-to-Texinfo catcodes - \def\norecurse#1{\bgroup\cslet{#1}{macsave.#1}} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% -{\catcode`\@=0 \catcode`\\=13 % We need to manipulate \ so use @ as escape -@catcode`@_=11 % private names -@catcode`@!=11 % used as argument separator - -% \passargtomacro#1#2 - -% Call #1 with a list of tokens #2, with any doubled backslashes in #2 -% compressed to one. -% -% This implementation works by expansion, and not execution (so we cannot use -% \def or similar). This reduces the risk of this failing in contexts where -% complete expansion is done with no execution (for example, in writing out to -% an auxiliary file for an index entry). -% -% State is kept in the input stream: the argument passed to -% @look_ahead, @gobble_and_check_finish and @add_segment is -% -% THE_MACRO ARG_RESULT ! {PENDING_BS} NEXT_TOKEN (... rest of input) -% -% where: -% THE_MACRO - name of the macro we want to call -% ARG_RESULT - argument list we build to pass to that macro -% PENDING_BS - either a backslash or nothing -% NEXT_TOKEN - used to look ahead in the input stream to see what's coming next - -@gdef@passargtomacro#1#2{% - @add_segment #1!{}@relax#2\@_finish\% -} -@gdef@_finish{@_finishx} @global@let@_finishx@relax - -% #1 - THE_MACRO ARG_RESULT -% #2 - PENDING_BS -% #3 - NEXT_TOKEN -% #4 used to look ahead -% -% If the next token is not a backslash, process the rest of the argument; -% otherwise, remove the next token. -@gdef@look_ahead#1!#2#3#4{% - @ifx#4\% - @expandafter@gobble_and_check_finish - @else - @expandafter@add_segment - @fi#1!{#2}#4#4% -} - -% #1 - THE_MACRO ARG_RESULT -% #2 - PENDING_BS -% #3 - NEXT_TOKEN -% #4 should be a backslash, which is gobbled. -% #5 looks ahead -% -% Double backslash found. Add a single backslash, and look ahead. -@gdef@gobble_and_check_finish#1!#2#3#4#5{% - @add_segment#1\!{}#5#5% -} - -@gdef@is_fi{@fi} - -% #1 - THE_MACRO ARG_RESULT -% #2 - PENDING_BS -% #3 - NEXT_TOKEN -% #4 is input stream until next backslash -% -% Input stream is either at the start of the argument, or just after a -% backslash sequence, either a lone backslash, or a doubled backslash. -% NEXT_TOKEN contains the first token in the input stream: if it is \finish, -% finish; otherwise, append to ARG_RESULT the segment of the argument up until -% the next backslash. PENDING_BACKSLASH contains a backslash to represent -% a backslash just before the start of the input stream that has not been -% added to ARG_RESULT. -@gdef@add_segment#1!#2#3#4\{% -@ifx#3@_finish - @call_the_macro#1!% -@else - % append the pending backslash to the result, followed by the next segment - @expandafter@is_fi@look_ahead#1#2#4!{\}@fi - % this @fi is discarded by @look_ahead. - % we can't get rid of it with \expandafter because we don't know how - % long #4 is. -} - -% #1 - THE_MACRO -% #2 - ARG_RESULT -% #3 discards the res of the conditional in @add_segment, and @is_fi ends the -% conditional. -@gdef@call_the_macro#1#2!#3@fi{@is_fi #1{#2}} - -} -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -% \braceorline MAC is used for a one-argument macro MAC. It checks -% whether the next non-whitespace character is a {. It sets the context -% for reading the argument (slightly different in the two cases). Then, -% to read the argument, in the whole-line case, it then calls the regular -% \parsearg MAC; in the lbrace case, it calls \passargtomacro MAC. -% +% \braceorline decides whether the next nonwhitespace character is a +% {. If so it reads up to the closing }, if not, it reads the whole +% line. Whatever was read is then fed to the next control sequence +% as an argument (by \parsebrace or \parsearg) \def\braceorline#1{\let\macnamexxx=#1\futurelet\nchar\braceorlinexxx} \def\braceorlinexxx{% - \ifx\nchar\bgroup - \macroargctxt - \expandafter\passargtomacro - \else - \macrolineargctxt\expandafter\parsearg + \ifx\nchar\bgroup\else + \expandafter\parsearg \fi \macnamexxx} % @alias. % We need some trickery to remove the optional spaces around the equal -% sign. Make them active and then expand them all to nothing. -% +% sign. Just make them active and then expand them all to nothing. \def\alias{\parseargusing\obeyspaces\aliasxxx} \def\aliasxxx #1{\aliasyyy#1\relax} \def\aliasyyy #1=#2\relax{% @@ -8765,8 +7120,7 @@ end % @inforef is relatively simple. \def\inforef #1{\inforefzzz #1,,,,**} -\def\inforefzzz #1,#2,#3,#4**{% - \putwordSee{} \putwordInfo{} \putwordfile{} \file{\ignorespaces #3{}}, +\def\inforefzzz #1,#2,#3,#4**{\putwordSee{} \putwordInfo{} \putwordfile{} \file{\ignorespaces #3{}}, node \samp{\ignorespaces#1{}}} % @node's only job in TeX is to define \lastnode, which is used in @@ -8819,10 +7173,7 @@ end \pdfmkdest{#1}% \iflinks {% - \requireauxfile \atdummies % preserve commands, but don't expand them - % match definition in \xrdef, \refx, \xrefX. - \def\value##1{##1}% \edef\writexrdef##1##2{% \write\auxfile{@xrdef{#1-% #1 of \setref, expanded by the \edef ##1}{##2}}% these are parameters of \writexrdef @@ -8830,78 +7181,39 @@ end \toks0 = \expandafter{\lastsection}% \immediate \writexrdef{title}{\the\toks0 }% \immediate \writexrdef{snt}{\csname #2\endcsname}% \Ynumbered etc. - \safewhatsit{\writexrdef{pg}{\folio}}% will be written later, at \shipout + \safewhatsit{\writexrdef{pg}{\folio}}% will be written later, during \shipout }% \fi } -% @xrefautosectiontitle on|off says whether @section(ing) names are used -% automatically in xrefs, if the third arg is not explicitly specified. -% This was provided as a "secret" @set xref-automatic-section-title -% variable, now it's official. -% -\parseargdef\xrefautomaticsectiontitle{% - \def\temp{#1}% - \ifx\temp\onword - \expandafter\let\csname SETxref-automatic-section-title\endcsname - = \empty - \else\ifx\temp\offword - \expandafter\let\csname SETxref-automatic-section-title\endcsname - = \relax - \else - \errhelp = \EMsimple - \errmessage{Unknown @xrefautomaticsectiontitle value `\temp', - must be on|off}% - \fi\fi -} - -% % @xref, @pxref, and @ref generate cross-references. For \xrefX, #1 is % the node name, #2 the name of the Info cross-reference, #3 the printed % node name, #4 the name of the Info file, #5 the name of the printed % manual. All but the node name can be omitted. % -\def\pxref{\putwordsee{} \xrefXX} -\def\xref{\putwordSee{} \xrefXX} -\def\ref{\xrefXX} - -\def\xrefXX#1{\def\xrefXXarg{#1}\futurelet\tokenafterxref\xrefXXX} -\def\xrefXXX{\expandafter\xrefX\expandafter[\xrefXXarg,,,,,,,]} -% -\newbox\toprefbox -\newbox\printedrefnamebox -\newbox\infofilenamebox -\newbox\printedmanualbox -% +\def\pxref#1{\putwordsee{} \xrefX[#1,,,,,,,]} +\def\xref#1{\putwordSee{} \xrefX[#1,,,,,,,]} +\def\ref#1{\xrefX[#1,,,,,,,]} \def\xrefX[#1,#2,#3,#4,#5,#6]{\begingroup \unsepspaces - % - % Get args without leading/trailing spaces. - \def\printedrefname{\ignorespaces #3}% - \setbox\printedrefnamebox = \hbox{\printedrefname\unskip}% - % - \def\infofilename{\ignorespaces #4}% - \setbox\infofilenamebox = \hbox{\infofilename\unskip}% - % \def\printedmanual{\ignorespaces #5}% - \setbox\printedmanualbox = \hbox{\printedmanual\unskip}% - % - % If the printed reference name (arg #3) was not explicitly given in - % the @xref, figure out what we want to use. - \ifdim \wd\printedrefnamebox = 0pt + \def\printedrefname{\ignorespaces #3}% + \setbox1=\hbox{\printedmanual\unskip}% + \setbox0=\hbox{\printedrefname\unskip}% + \ifdim \wd0 = 0pt % No printed node name was explicitly given. - \expandafter\ifx\csname SETxref-automatic-section-title\endcsname \relax - % Not auto section-title: use node name inside the square brackets. + \expandafter\ifx\csname SETxref-automatic-section-title\endcsname\relax + % Use the node name inside the square brackets. \def\printedrefname{\ignorespaces #1}% \else - % Auto section-title: use chapter/section title inside - % the square brackets if we have it. - \ifdim \wd\printedmanualbox > 0pt - % It is in another manual, so we don't have it; use node name. + % Use the actual chapter/section title appear inside + % the square brackets. Use the real section title if we have it. + \ifdim \wd1 > 0pt + % It is in another manual, so we don't have it. \def\printedrefname{\ignorespaces #1}% \else \ifhavexrefs - % We (should) know the real title if we have the xref values. + % We know the real title if we have the xref values. \def\printedrefname{\refx{#1-title}{}}% \else % Otherwise just copy the Info node name. @@ -8913,124 +7225,64 @@ end % % Make link in pdf output. \ifpdf - % For pdfTeX and LuaTeX {\indexnofonts - \makevalueexpandable \turnoffactive % This expands tokens, so do it after making catcode changes, so _ - % etc. don't get their TeX definitions. This ignores all spaces in - % #4, including (wrongly) those in the middle of the filename. + % etc. don't get their TeX definitions. \getfilename{#4}% % - % This (wrongly) does not take account of leading or trailing - % spaces in #1, which should be ignored. - \setpdfdestname{#1}% - % - \ifx\pdfdestname\empty - \def\pdfdestname{Top}% no empty targets - \fi + % See comments at \activebackslashdouble. + {\activebackslashdouble \xdef\pdfxrefdest{#1}% + \backslashparens\pdfxrefdest}% % \leavevmode \startlink attr{/Border [0 0 0]}% \ifnum\filenamelength>0 - goto file{\the\filename.pdf} name{\pdfdestname}% + goto file{\the\filename.pdf} name{\pdfxrefdest}% \else - goto name{\pdfmkpgn{\pdfdestname}}% + goto name{\pdfmkpgn{\pdfxrefdest}}% \fi }% \setcolor{\linkcolor}% - \else - \ifx\XeTeXrevision\thisisundefined - \else - % For XeTeX - {\indexnofonts - \makevalueexpandable - \turnoffactive - % This expands tokens, so do it after making catcode changes, so _ - % etc. don't get their TeX definitions. This ignores all spaces in - % #4, including (wrongly) those in the middle of the filename. - \getfilename{#4}% - % - % This (wrongly) does not take account of leading or trailing - % spaces in #1, which should be ignored. - \setpdfdestname{#1}% - % - \ifx\pdfdestname\empty - \def\pdfdestname{Top}% no empty targets - \fi - % - \leavevmode - \ifnum\filenamelength>0 - % With default settings, - % XeTeX (xdvipdfmx) replaces link destination names with integers. - % In this case, the replaced destination names of - % remote PDFs are no longer known. In order to avoid a replacement, - % you can use xdvipdfmx's command line option `-C 0x0010'. - % If you use XeTeX 0.99996+ (TeX Live 2016+), - % this command line option is no longer necessary - % because we can use the `dvipdfmx:config' special. - \special{pdf:bann << /Border [0 0 0] /Type /Annot /Subtype /Link /A - << /S /GoToR /F (\the\filename.pdf) /D (\pdfdestname) >> >>}% - \else - \special{pdf:bann << /Border [0 0 0] /Type /Annot /Subtype /Link /A - << /S /GoTo /D (\pdfdestname) >> >>}% - \fi - }% - \setcolor{\linkcolor}% - \fi \fi + % + % Float references are printed completely differently: "Figure 1.2" + % instead of "[somenode], p.3". We distinguish them by the + % LABEL-title being set to a magic string. {% % Have to otherify everything special to allow the \csname to % include an _ in the xref name, etc. \indexnofonts \turnoffactive - \def\value##1{##1}% \expandafter\global\expandafter\let\expandafter\Xthisreftitle \csname XR#1-title\endcsname }% - % - % Float references are printed completely differently: "Figure 1.2" - % instead of "[somenode], p.3". \iffloat distinguishes them by - % \Xthisreftitle being set to a magic string. \iffloat\Xthisreftitle % If the user specified the print name (third arg) to the ref, % print it instead of our usual "Figure 1.2". - \ifdim\wd\printedrefnamebox = 0pt + \ifdim\wd0 = 0pt \refx{#1-snt}{}% \else \printedrefname \fi % - % If the user also gave the printed manual name (fifth arg), append + % if the user also gave the printed manual name (fifth arg), append % "in MANUALNAME". - \ifdim \wd\printedmanualbox > 0pt + \ifdim \wd1 > 0pt \space \putwordin{} \cite{\printedmanual}% \fi \else % node/anchor (non-float) references. - % - % If we use \unhbox to print the node names, TeX does not insert - % empty discretionaries after hyphens, which means that it will not - % find a line break at a hyphen in a node names. Since some manuals - % are best written with fairly long node names, containing hyphens, - % this is a loss. Therefore, we give the text of the node name - % again, so it is as if TeX is seeing it for the first time. - % - \ifdim \wd\printedmanualbox > 0pt - % Cross-manual reference with a printed manual name. - % - \crossmanualxref{\cite{\printedmanual\unskip}}% - % - \else\ifdim \wd\infofilenamebox > 0pt - % Cross-manual reference with only an info filename (arg 4), no - % printed manual name (arg 5). This is essentially the same as - % the case above; we output the filename, since we have nothing else. - % - \crossmanualxref{\code{\infofilename\unskip}}% % + % If we use \unhbox0 and \unhbox1 to print the node names, TeX does not + % insert empty discretionaries after hyphens, which means that it will + % not find a line break at a hyphen in a node names. Since some manuals + % are best written with fairly long node names, containing hyphens, this + % is a loss. Therefore, we give the text of the node name again, so it + % is as if TeX is seeing it for the first time. + \ifdim \wd1 > 0pt + \putwordSection{} ``\printedrefname'' \putwordin{} \cite{\printedmanual}% \else - % Reference within this manual. - % % _ (for example) has to be the character _ for the purposes of the % control sequence corresponding to the node, but it has to expand % into the usual \leavevmode...\vrule stuff for purposes of @@ -9042,7 +7294,7 @@ end \setbox2 = \hbox{\ignorespaces \refx{#1-snt}{}}% \ifdim \wd2 > 0pt \refx{#1-snt}\space\fi }% - % output the `[mynode]' via the macro below so it can be overridden. + % output the `[mynode]' via a macro so it can be overridden. \xrefprintnodename\printedrefname % % But we always want a comma and a space: @@ -9050,46 +7302,11 @@ end % % output the `page 3'. \turnoffactive \putwordpage\tie\refx{#1-pg}{}% - % Add a , if xref followed by a space - \if\space\noexpand\tokenafterxref ,% - \else\ifx\ \tokenafterxref ,% @TAB - \else\ifx\*\tokenafterxref ,% @* - \else\ifx\ \tokenafterxref ,% @SPACE - \else\ifx\ - \tokenafterxref ,% @NL - \else\ifx\tie\tokenafterxref ,% @tie - \fi\fi\fi\fi\fi\fi - \fi\fi + \fi \fi \endlink \endgroup} -% Output a cross-manual xref to #1. Used just above (twice). -% -% Only include the text "Section ``foo'' in" if the foo is neither -% missing or Top. Thus, @xref{,,,foo,The Foo Manual} outputs simply -% "see The Foo Manual", the idea being to refer to the whole manual. -% -% But, this being TeX, we can't easily compare our node name against the -% string "Top" while ignoring the possible spaces before and after in -% the input. By adding the arbitrary 7sp below, we make it much less -% likely that a real node name would have the same width as "Top" (e.g., -% in a monospaced font). Hopefully it will never happen in practice. -% -% For the same basic reason, we retypeset the "Top" at every -% reference, since the current font is indeterminate. -% -\def\crossmanualxref#1{% - \setbox\toprefbox = \hbox{Top\kern7sp}% - \setbox2 = \hbox{\ignorespaces \printedrefname \unskip \kern7sp}% - \ifdim \wd2 > 7sp % nonempty? - \ifdim \wd2 = \wd\toprefbox \else % same as Top? - \putwordSection{} ``\printedrefname'' \putwordin{}\space - \fi - \fi - #1% -} - % This macro is called from \xrefX for the `[nodename]' part of xref % output. It's a separate macro only so it can be changed more easily, % since square brackets don't work well in some documents. Particularly @@ -9125,14 +7342,13 @@ end \fi\fi\fi } -% \refx{NAME}{SUFFIX} - reference a cross-reference string named NAME. SUFFIX -% is output afterwards if non-empty. +% Define \refx{NAME}{SUFFIX} to reference a cross-reference string named NAME. +% If its value is nonempty, SUFFIX is output afterward. +% \def\refx#1#2{% - \requireauxfile {% \indexnofonts \otherbackslash - \def\value##1{##1}% \expandafter\global\expandafter\let\expandafter\thisrefX \csname XR#1\endcsname }% @@ -9141,8 +7357,7 @@ end \angleleft un\-de\-fined\angleright \iflinks \ifhavexrefs - {\toks0 = {#1}% avoid expansion of possibly-complex value - \message{\linenumber Undefined cross reference `\the\toks0'.}}% + \message{\linenumber Undefined cross reference `#1'.}% \else \ifwarnedxrefs\else \global\warnedxrefstrue @@ -9157,28 +7372,20 @@ end #2% Output the suffix in any case. } -% This is the macro invoked by entries in the aux file. Define a control -% sequence for a cross-reference target (we prepend XR to the control sequence -% name to avoid collisions). The value is the page number. If this is a float -% type, we have more work to do. +% This is the macro invoked by entries in the aux file. Usually it's +% just a \def (we prepend XR to the control sequence name to avoid +% collisions). But if this is a float type, we have more work to do. % \def\xrdef#1#2{% - {% Expand the node or anchor name to remove control sequences. - % \turnoffactive stops 8-bit characters being changed to commands - % like @'e. \refx does the same to retrieve the value in the definition. + {% The node name might contain 8-bit characters, which in our current + % implementation are changed to commands like @'e. Don't let these + % mess up the control sequence name. \indexnofonts \turnoffactive - \def\value##1{##1}% \xdef\safexrefname{#1}% }% % - \bgroup - \expandafter\gdef\csname XR\safexrefname\endcsname{#2}% - \egroup - % We put the \gdef inside a group to avoid the definitions building up on - % TeX's save stack, which can cause it to run out of space for aux files with - % thousands of lines. \gdef doesn't use the save stack, but \csname does - % when it defines an unknown control sequence as \relax. + \expandafter\gdef\csname XR\safexrefname\endcsname{#2}% remember this xref % % Was that xref control sequence that we just defined for a float? \expandafter\iffloat\csname XR\safexrefname\endcsname @@ -9201,23 +7408,6 @@ end \fi } -% If working on a large document in chapters, it is convenient to -% be able to disable indexing, cross-referencing, and contents, for test runs. -% This is done with @novalidate at the beginning of the file. -% -\newif\iflinks \linkstrue % by default we want the aux files. -\let\novalidate = \linksfalse - -% Used when writing to the aux file, or when using data from it. -\def\requireauxfile{% - \iflinks - \tryauxfile - % Open the new aux file. TeX will close it automatically at exit. - \immediate\openout\auxfile=\jobname.aux - \fi - \global\let\requireauxfile=\relax % Only do this once. -} - % Read the last existing aux file, if any. No error if none exists. % \def\tryauxfile{% @@ -9296,6 +7486,16 @@ end % now. --karl, 15jan04. \catcode`\\=\other % + % Make the characters 128-255 be printing characters. + {% + \count1=128 + \def\loop{% + \catcode\count1=\other + \advance\count1 by 1 + \ifnum \count1<256 \loop \fi + }% + }% + % % @ is our escape character in .aux files, and we need braces. \catcode`\{=1 \catcode`\}=2 @@ -9321,13 +7521,15 @@ end % space to prevent strange expansion errors.) \def\supereject{\par\penalty -20000\footnoteno =0 } -% @footnotestyle is meaningful for Info output only. +% @footnotestyle is meaningful for info output only. \let\footnotestyle=\comment {\catcode `\@=11 % % Auto-number footnotes. Otherwise like plain. \gdef\footnote{% + \let\indent=\ptexindent + \let\noindent=\ptexnoindent \global\advance\footnoteno by \@ne \edef\thisfootno{$^{\the\footnoteno}$}% % @@ -9351,15 +7553,10 @@ end % \gdef\dofootnote{% \insert\footins\bgroup - % - % Nested footnotes are not supported in TeX, that would take a lot - % more work. (\startsavinginserts does not suffice.) - \let\footnote=\errfootnotenest - % % We want to typeset this text as a normal paragraph, even if the % footnote reference occurs in (for example) a display environment. % So reset some parameters. - \hsize=\txipagewidth + \hsize=\pagewidth \interlinepenalty\interfootnotelinepenalty \splittopskip\ht\strutbox % top baseline for broken footnotes \splitmaxdepth\dp\strutbox @@ -9387,30 +7584,17 @@ end % expands into a box, it must come within the paragraph, lest it % provide a place where TeX can split the footnote. \footstrut - % - % Invoke rest of plain TeX footnote routine. \futurelet\next\fo@t } }%end \catcode `\@=11 -\def\errfootnotenest{% - \errhelp=\EMsimple - \errmessage{Nested footnotes not supported in texinfo.tex, - even though they work in makeinfo; sorry} -} - -\def\errfootnoteheading{% - \errhelp=\EMsimple - \errmessage{Footnotes in chapters, sections, etc., are not supported} -} - % In case a @footnote appears in a vbox, save the footnote text and create % the real \insert just after the vbox finished. Otherwise, the insertion % would be lost. % Similarly, if a @footnote appears inside an alignment, save the footnote % text to a box and make the \insert when a row of the table is finished. % And the same can be done for other insert classes. --kasal, 16nov03. -% + % Replace the \insert primitive by a cheating macro. % Deeper inside, just make sure that the saved insertions are not spilled % out prematurely. @@ -9484,10 +7668,10 @@ end \newif\ifwarnednoepsf \newhelp\noepsfhelp{epsf.tex must be installed for images to work. It is also included in the Texinfo distribution, or you can get - it from https://ctan.org/texarchive/macros/texinfo/texinfo/doc/epsf.tex.} + it from ftp://tug.org/tex/epsf.tex.} % \def\image#1{% - \ifx\epsfbox\thisisundefined + \ifx\epsfbox\undefined \ifwarnednoepsf \else \errhelp = \noepsfhelp \errmessage{epsf.tex not found, images will be ignored}% @@ -9503,22 +7687,14 @@ end % #2 is (optional) width, #3 is (optional) height. % #4 is (ignored optional) html alt text. % #5 is (ignored optional) extension. -% #6 is just the usual extra ignored arg for parsing stuff. +% #6 is just the usual extra ignored arg for parsing this stuff. \newif\ifimagevmode \def\imagexxx#1,#2,#3,#4,#5,#6\finish{\begingroup \catcode`\^^M = 5 % in case we're inside an example \normalturnoffactive % allow _ et al. in names - \def\xprocessmacroarg{\eatspaces}% in case we are being used via a macro % If the image is by itself, center it. \ifvmode \imagevmodetrue - \else \ifx\centersub\centerV - % for @center @image, we need a vbox so we can have our vertical space - \imagevmodetrue - \vbox\bgroup % vbox has better behavior than vtop herev - \fi\fi - % - \ifimagevmode \nobreak\medskip % Usually we'll have text after the image which will insert % \parskip glue, so insert it here too to equalize the space @@ -9528,37 +7704,21 @@ end \fi % % Leave vertical mode so that indentation from an enclosing - % environment such as @quotation is respected. - % However, if we're at the top level, we don't want the - % normal paragraph indentation. - % On the other hand, if we are in the case of @center @image, we don't - % want to start a paragraph, which will create a hsize-width box and - % eradicate the centering. - \ifx\centersub\centerV\else \noindent \fi + % environment such as @quotation is respected. On the other hand, if + % it's at the top level, we don't want the normal paragraph indentation. + \noindent % % Output the image. \ifpdf - % For pdfTeX and LuaTeX <= 0.80 \dopdfimage{#1}{#2}{#3}% \else - \ifx\XeTeXrevision\thisisundefined - % For epsf.tex - % \epsfbox itself resets \epsf?size at each figure. - \setbox0 = \hbox{\ignorespaces #2}% - \ifdim\wd0 > 0pt \epsfxsize=#2\relax \fi - \setbox0 = \hbox{\ignorespaces #3}% - \ifdim\wd0 > 0pt \epsfysize=#3\relax \fi - \epsfbox{#1.eps}% - \else - % For XeTeX - \doxeteximage{#1}{#2}{#3}% - \fi + % \epsfbox itself resets \epsf?size at each figure. + \setbox0 = \hbox{\ignorespaces #2}\ifdim\wd0 > 0pt \epsfxsize=#2\relax \fi + \setbox0 = \hbox{\ignorespaces #3}\ifdim\wd0 > 0pt \epsfysize=#3\relax \fi + \epsfbox{#1.eps}% \fi % - \ifimagevmode - \medskip % space after a standalone image - \fi - \ifx\centersub\centerV \egroup \fi + \ifimagevmode \medskip \fi % space after the standalone image \endgroup} @@ -9674,7 +7834,7 @@ end % \ifx\thiscaption\empty \else \ifx\floatident\empty \else - \appendtomacro\captionline{: }% had ident, so need a colon between + \appendtomacro\captionline{: }% had ident, so need a colon between \fi % % caption text. @@ -9698,20 +7858,32 @@ end % \floatlabel-lof. Besides \floatident, we include the short % caption if specified, else the full caption if specified, else nothing. {% - \requireauxfile \atdummies % - \ifx\thisshortcaption\empty - \def\gtemp{\thiscaption}% - \else - \def\gtemp{\thisshortcaption}% - \fi + % since we read the caption text in the macro world, where ^^M + % is turned into a normal character, we have to scan it back, so + % we don't write the literal three characters "^^M" into the aux file. + \scanexp{% + \xdef\noexpand\gtemp{% + \ifx\thisshortcaption\empty + \thiscaption + \else + \thisshortcaption + \fi + }% + }% \immediate\write\auxfile{@xrdef{\floatlabel-lof}{\floatident - \ifx\gtemp\empty \else : \gtemp \fi}}% + \ifx\gtemp\empty \else : \gtemp \fi}}% }% \fi \egroup % end of \vtop % + % place the captured inserts + % + % BEWARE: when the floats start floating, we have to issue warning + % whenever an insert appears inside a float which could possibly + % float. --kasal, 26may04 + % \checkinserts } @@ -9825,20 +7997,20 @@ end { \catcode`\_ = \active \globaldefs=1 -\parseargdef\documentlanguage{% +\parseargdef\documentlanguage{\begingroup + \let_=\normalunderscore % normal _ character for filenames \tex % read txi-??.tex file in plain TeX. % Read the file by the name they passed if it exists. - \let_ = \normalunderscore % normal _ character for filename test \openin 1 txi-#1.tex \ifeof 1 - \documentlanguagetrywithoutunderscore #1_\finish + \documentlanguagetrywithoutunderscore{#1_\finish}% \else \globaldefs = 1 % everything in the txi-LL files needs to persist \input txi-#1.tex \fi \closein 1 \endgroup % end raw TeX -} +\endgroup} % % If they passed de_DE, and txi-de_DE.tex doesn't exist, % try txi-de.tex. @@ -9886,70 +8058,6 @@ directory should work if nowhere else does.} \global\righthyphenmin = #3\relax } -% XeTeX and LuaTeX can handle Unicode natively. -% Their default I/O uses UTF-8 sequences instead of a byte-wise operation. -% Other TeX engines' I/O (pdfTeX, etc.) is byte-wise. -% -\newif\iftxinativeunicodecapable -\newif\iftxiusebytewiseio - -\ifx\XeTeXrevision\thisisundefined - \ifx\luatexversion\thisisundefined - \txinativeunicodecapablefalse - \txiusebytewiseiotrue - \else - \txinativeunicodecapabletrue - \txiusebytewiseiofalse - \fi -\else - \txinativeunicodecapabletrue - \txiusebytewiseiofalse -\fi - -% Set I/O by bytes instead of UTF-8 sequence for XeTeX and LuaTex -% for non-UTF-8 (byte-wise) encodings. -% -\def\setbytewiseio{% - \ifx\XeTeXrevision\thisisundefined - \else - \XeTeXdefaultencoding "bytes" % For subsequent files to be read - \XeTeXinputencoding "bytes" % For document root file - % Unfortunately, there seems to be no corresponding XeTeX command for - % output encoding. This is a problem for auxiliary index and TOC files. - % The only solution would be perhaps to write out @U{...} sequences in - % place of non-ASCII characters. - \fi - - \ifx\luatexversion\thisisundefined - \else - \directlua{ - local utf8_char, byte, gsub = unicode.utf8.char, string.byte, string.gsub - local function convert_char (char) - return utf8_char(byte(char)) - end - - local function convert_line (line) - return gsub(line, ".", convert_char) - end - - callback.register("process_input_buffer", convert_line) - - local function convert_line_out (line) - local line_out = "" - for c in string.utfvalues(line) do - line_out = line_out .. string.char(c) - end - return line_out - end - - callback.register("process_output_buffer", convert_line_out) - } - \fi - - \txiusebytewiseiotrue -} - - % Helpers for encodings. % Set the catcode of characters 128 through 255 to the specified number. % @@ -9972,9 +8080,7 @@ directory should work if nowhere else does.} % @documentencoding sets the definition of non-ASCII characters % according to the specified encoding. % -\def\documentencoding{\parseargusing\filenamecatcodes\documentencodingzzz} -\def\documentencodingzzz#1{% - % +\parseargdef\documentencoding{% % Encoding being declared for the document. \def\declaredencoding{\csname #1.enc\endcsname}% % @@ -9990,66 +8096,35 @@ directory should work if nowhere else does.} \asciichardefs % \else \ifx \declaredencoding \lattwo - \iftxinativeunicodecapable - \setbytewiseio - \fi \setnonasciicharscatcode\active \lattwochardefs % \else \ifx \declaredencoding \latone - \iftxinativeunicodecapable - \setbytewiseio - \fi \setnonasciicharscatcode\active \latonechardefs % \else \ifx \declaredencoding \latnine - \iftxinativeunicodecapable - \setbytewiseio - \fi \setnonasciicharscatcode\active \latninechardefs % \else \ifx \declaredencoding \utfeight - \iftxinativeunicodecapable - % For native Unicode handling (XeTeX and LuaTeX) - \nativeunicodechardefs - \else - % For treating UTF-8 as byte sequences (TeX, eTeX and pdfTeX) - \setnonasciicharscatcode\active - % since we already invoked \utfeightchardefs at the top level - % (below), do not re-invoke it, otherwise our check for duplicated - % definitions gets triggered. Making non-ascii chars active is - % sufficient. - \fi + \setnonasciicharscatcode\active + \utfeightchardefs % \else - \message{Ignoring unknown document encoding: #1.}% + \message{Unknown document encoding #1, ignoring.}% % \fi % utfeight \fi % latnine \fi % latone \fi % lattwo \fi % ascii - % - \ifx\XeTeXrevision\thisisundefined - \else - \ifx \declaredencoding \utfeight - \else - \ifx \declaredencoding \ascii - \else - \message{Warning: XeTeX with non-UTF-8 encodings cannot handle % - non-ASCII characters in auxiliary files.}% - \fi - \fi - \fi } -% emacs-page % A message to be logged when using a character that isn't available % the default font encoding (OT1). % -\def\missingcharmsg#1{\message{Character missing, sorry: #1.}} +\def\missingcharmsg#1{\message{Character missing in OT1 encoding: #1.}} % Take account of \c (plain) vs. \, (Texinfo) difference. \def\cedilla#1{\ifx\c\ptexc\c{#1}\else\,{#1}\fi} @@ -10059,119 +8134,111 @@ directory should work if nowhere else does.} % macros containing the character definitions. \setnonasciicharscatcode\active % - -\def\gdefchar#1#2{% -\gdef#1{% - \ifpassthroughchars - \string#1% - \else - #2% - \fi -}} - % Latin1 (ISO-8859-1) character definitions. \def\latonechardefs{% - \gdefchar^^a0{\tie} - \gdefchar^^a1{\exclamdown} - \gdefchar^^a2{{\tcfont \char162}} % cent - \gdefchar^^a3{\pounds{}} - \gdefchar^^a4{{\tcfont \char164}} % currency - \gdefchar^^a5{{\tcfont \char165}} % yen - \gdefchar^^a6{{\tcfont \char166}} % broken bar - \gdefchar^^a7{\S} - \gdefchar^^a8{\"{}} - \gdefchar^^a9{\copyright{}} - \gdefchar^^aa{\ordf} - \gdefchar^^ab{\guillemetleft{}} - \gdefchar^^ac{\ensuremath\lnot} - \gdefchar^^ad{\-} - \gdefchar^^ae{\registeredsymbol{}} - \gdefchar^^af{\={}} + \gdef^^a0{~} + \gdef^^a1{\exclamdown} + \gdef^^a2{\missingcharmsg{CENT SIGN}} + \gdef^^a3{{\pounds}} + \gdef^^a4{\missingcharmsg{CURRENCY SIGN}} + \gdef^^a5{\missingcharmsg{YEN SIGN}} + \gdef^^a6{\missingcharmsg{BROKEN BAR}} + \gdef^^a7{\S} + \gdef^^a8{\"{}} + \gdef^^a9{\copyright} + \gdef^^aa{\ordf} + \gdef^^ab{\guillemetleft} + \gdef^^ac{$\lnot$} + \gdef^^ad{\-} + \gdef^^ae{\registeredsymbol} + \gdef^^af{\={}} % - \gdefchar^^b0{\textdegree} - \gdefchar^^b1{$\pm$} - \gdefchar^^b2{$^2$} - \gdefchar^^b3{$^3$} - \gdefchar^^b4{\'{}} - \gdefchar^^b5{$\mu$} - \gdefchar^^b6{\P} - \gdefchar^^b7{\ensuremath\cdot} - \gdefchar^^b8{\cedilla\ } - \gdefchar^^b9{$^1$} - \gdefchar^^ba{\ordm} - \gdefchar^^bb{\guillemetright{}} - \gdefchar^^bc{$1\over4$} - \gdefchar^^bd{$1\over2$} - \gdefchar^^be{$3\over4$} - \gdefchar^^bf{\questiondown} + \gdef^^b0{\textdegree} + \gdef^^b1{$\pm$} + \gdef^^b2{$^2$} + \gdef^^b3{$^3$} + \gdef^^b4{\'{}} + \gdef^^b5{$\mu$} + \gdef^^b6{\P} % - \gdefchar^^c0{\`A} - \gdefchar^^c1{\'A} - \gdefchar^^c2{\^A} - \gdefchar^^c3{\~A} - \gdefchar^^c4{\"A} - \gdefchar^^c5{\ringaccent A} - \gdefchar^^c6{\AE} - \gdefchar^^c7{\cedilla C} - \gdefchar^^c8{\`E} - \gdefchar^^c9{\'E} - \gdefchar^^ca{\^E} - \gdefchar^^cb{\"E} - \gdefchar^^cc{\`I} - \gdefchar^^cd{\'I} - \gdefchar^^ce{\^I} - \gdefchar^^cf{\"I} + \gdef^^b7{$^.$} + \gdef^^b8{\cedilla\ } + \gdef^^b9{$^1$} + \gdef^^ba{\ordm} % - \gdefchar^^d0{\DH} - \gdefchar^^d1{\~N} - \gdefchar^^d2{\`O} - \gdefchar^^d3{\'O} - \gdefchar^^d4{\^O} - \gdefchar^^d5{\~O} - \gdefchar^^d6{\"O} - \gdefchar^^d7{$\times$} - \gdefchar^^d8{\O} - \gdefchar^^d9{\`U} - \gdefchar^^da{\'U} - \gdefchar^^db{\^U} - \gdefchar^^dc{\"U} - \gdefchar^^dd{\'Y} - \gdefchar^^de{\TH} - \gdefchar^^df{\ss} + \gdef^^bb{\guilletright} + \gdef^^bc{$1\over4$} + \gdef^^bd{$1\over2$} + \gdef^^be{$3\over4$} + \gdef^^bf{\questiondown} % - \gdefchar^^e0{\`a} - \gdefchar^^e1{\'a} - \gdefchar^^e2{\^a} - \gdefchar^^e3{\~a} - \gdefchar^^e4{\"a} - \gdefchar^^e5{\ringaccent a} - \gdefchar^^e6{\ae} - \gdefchar^^e7{\cedilla c} - \gdefchar^^e8{\`e} - \gdefchar^^e9{\'e} - \gdefchar^^ea{\^e} - \gdefchar^^eb{\"e} - \gdefchar^^ec{\`{\dotless i}} - \gdefchar^^ed{\'{\dotless i}} - \gdefchar^^ee{\^{\dotless i}} - \gdefchar^^ef{\"{\dotless i}} + \gdef^^c0{\`A} + \gdef^^c1{\'A} + \gdef^^c2{\^A} + \gdef^^c3{\~A} + \gdef^^c4{\"A} + \gdef^^c5{\ringaccent A} + \gdef^^c6{\AE} + \gdef^^c7{\cedilla C} + \gdef^^c8{\`E} + \gdef^^c9{\'E} + \gdef^^ca{\^E} + \gdef^^cb{\"E} + \gdef^^cc{\`I} + \gdef^^cd{\'I} + \gdef^^ce{\^I} + \gdef^^cf{\"I} % - \gdefchar^^f0{\dh} - \gdefchar^^f1{\~n} - \gdefchar^^f2{\`o} - \gdefchar^^f3{\'o} - \gdefchar^^f4{\^o} - \gdefchar^^f5{\~o} - \gdefchar^^f6{\"o} - \gdefchar^^f7{$\div$} - \gdefchar^^f8{\o} - \gdefchar^^f9{\`u} - \gdefchar^^fa{\'u} - \gdefchar^^fb{\^u} - \gdefchar^^fc{\"u} - \gdefchar^^fd{\'y} - \gdefchar^^fe{\th} - \gdefchar^^ff{\"y} + \gdef^^d0{\DH} + \gdef^^d1{\~N} + \gdef^^d2{\`O} + \gdef^^d3{\'O} + \gdef^^d4{\^O} + \gdef^^d5{\~O} + \gdef^^d6{\"O} + \gdef^^d7{$\times$} + \gdef^^d8{\O} + \gdef^^d9{\`U} + \gdef^^da{\'U} + \gdef^^db{\^U} + \gdef^^dc{\"U} + \gdef^^dd{\'Y} + \gdef^^de{\TH} + \gdef^^df{\ss} + % + \gdef^^e0{\`a} + \gdef^^e1{\'a} + \gdef^^e2{\^a} + \gdef^^e3{\~a} + \gdef^^e4{\"a} + \gdef^^e5{\ringaccent a} + \gdef^^e6{\ae} + \gdef^^e7{\cedilla c} + \gdef^^e8{\`e} + \gdef^^e9{\'e} + \gdef^^ea{\^e} + \gdef^^eb{\"e} + \gdef^^ec{\`{\dotless i}} + \gdef^^ed{\'{\dotless i}} + \gdef^^ee{\^{\dotless i}} + \gdef^^ef{\"{\dotless i}} + % + \gdef^^f0{\dh} + \gdef^^f1{\~n} + \gdef^^f2{\`o} + \gdef^^f3{\'o} + \gdef^^f4{\^o} + \gdef^^f5{\~o} + \gdef^^f6{\"o} + \gdef^^f7{$\div$} + \gdef^^f8{\o} + \gdef^^f9{\`u} + \gdef^^fa{\'u} + \gdef^^fb{\^u} + \gdef^^fc{\"u} + \gdef^^fd{\'y} + \gdef^^fe{\th} + \gdef^^ff{\"y} } % Latin9 (ISO-8859-15) encoding character definitions. @@ -10179,119 +8246,119 @@ directory should work if nowhere else does.} % Encoding is almost identical to Latin1. \latonechardefs % - \gdefchar^^a4{\euro{}} - \gdefchar^^a6{\v S} - \gdefchar^^a8{\v s} - \gdefchar^^b4{\v Z} - \gdefchar^^b8{\v z} - \gdefchar^^bc{\OE} - \gdefchar^^bd{\oe} - \gdefchar^^be{\"Y} + \gdef^^a4{\euro} + \gdef^^a6{\v S} + \gdef^^a8{\v s} + \gdef^^b4{\v Z} + \gdef^^b8{\v z} + \gdef^^bc{\OE} + \gdef^^bd{\oe} + \gdef^^be{\"Y} } % Latin2 (ISO-8859-2) character definitions. \def\lattwochardefs{% - \gdefchar^^a0{\tie} - \gdefchar^^a1{\ogonek{A}} - \gdefchar^^a2{\u{}} - \gdefchar^^a3{\L} - \gdefchar^^a4{\missingcharmsg{CURRENCY SIGN}} - \gdefchar^^a5{\v L} - \gdefchar^^a6{\'S} - \gdefchar^^a7{\S} - \gdefchar^^a8{\"{}} - \gdefchar^^a9{\v S} - \gdefchar^^aa{\cedilla S} - \gdefchar^^ab{\v T} - \gdefchar^^ac{\'Z} - \gdefchar^^ad{\-} - \gdefchar^^ae{\v Z} - \gdefchar^^af{\dotaccent Z} + \gdef^^a0{~} + \gdef^^a1{\ogonek{A}} + \gdef^^a2{\u{}} + \gdef^^a3{\L} + \gdef^^a4{\missingcharmsg{CURRENCY SIGN}} + \gdef^^a5{\v L} + \gdef^^a6{\'S} + \gdef^^a7{\S} + \gdef^^a8{\"{}} + \gdef^^a9{\v S} + \gdef^^aa{\cedilla S} + \gdef^^ab{\v T} + \gdef^^ac{\'Z} + \gdef^^ad{\-} + \gdef^^ae{\v Z} + \gdef^^af{\dotaccent Z} % - \gdefchar^^b0{\textdegree{}} - \gdefchar^^b1{\ogonek{a}} - \gdefchar^^b2{\ogonek{ }} - \gdefchar^^b3{\l} - \gdefchar^^b4{\'{}} - \gdefchar^^b5{\v l} - \gdefchar^^b6{\'s} - \gdefchar^^b7{\v{}} - \gdefchar^^b8{\cedilla\ } - \gdefchar^^b9{\v s} - \gdefchar^^ba{\cedilla s} - \gdefchar^^bb{\v t} - \gdefchar^^bc{\'z} - \gdefchar^^bd{\H{}} - \gdefchar^^be{\v z} - \gdefchar^^bf{\dotaccent z} + \gdef^^b0{\textdegree} + \gdef^^b1{\ogonek{a}} + \gdef^^b2{\ogonek{ }} + \gdef^^b3{\l} + \gdef^^b4{\'{}} + \gdef^^b5{\v l} + \gdef^^b6{\'s} + \gdef^^b7{\v{}} + \gdef^^b8{\cedilla\ } + \gdef^^b9{\v s} + \gdef^^ba{\cedilla s} + \gdef^^bb{\v t} + \gdef^^bc{\'z} + \gdef^^bd{\H{}} + \gdef^^be{\v z} + \gdef^^bf{\dotaccent z} % - \gdefchar^^c0{\'R} - \gdefchar^^c1{\'A} - \gdefchar^^c2{\^A} - \gdefchar^^c3{\u A} - \gdefchar^^c4{\"A} - \gdefchar^^c5{\'L} - \gdefchar^^c6{\'C} - \gdefchar^^c7{\cedilla C} - \gdefchar^^c8{\v C} - \gdefchar^^c9{\'E} - \gdefchar^^ca{\ogonek{E}} - \gdefchar^^cb{\"E} - \gdefchar^^cc{\v E} - \gdefchar^^cd{\'I} - \gdefchar^^ce{\^I} - \gdefchar^^cf{\v D} + \gdef^^c0{\'R} + \gdef^^c1{\'A} + \gdef^^c2{\^A} + \gdef^^c3{\u A} + \gdef^^c4{\"A} + \gdef^^c5{\'L} + \gdef^^c6{\'C} + \gdef^^c7{\cedilla C} + \gdef^^c8{\v C} + \gdef^^c9{\'E} + \gdef^^ca{\ogonek{E}} + \gdef^^cb{\"E} + \gdef^^cc{\v E} + \gdef^^cd{\'I} + \gdef^^ce{\^I} + \gdef^^cf{\v D} % - \gdefchar^^d0{\DH} - \gdefchar^^d1{\'N} - \gdefchar^^d2{\v N} - \gdefchar^^d3{\'O} - \gdefchar^^d4{\^O} - \gdefchar^^d5{\H O} - \gdefchar^^d6{\"O} - \gdefchar^^d7{$\times$} - \gdefchar^^d8{\v R} - \gdefchar^^d9{\ringaccent U} - \gdefchar^^da{\'U} - \gdefchar^^db{\H U} - \gdefchar^^dc{\"U} - \gdefchar^^dd{\'Y} - \gdefchar^^de{\cedilla T} - \gdefchar^^df{\ss} + \gdef^^d0{\DH} + \gdef^^d1{\'N} + \gdef^^d2{\v N} + \gdef^^d3{\'O} + \gdef^^d4{\^O} + \gdef^^d5{\H O} + \gdef^^d6{\"O} + \gdef^^d7{$\times$} + \gdef^^d8{\v R} + \gdef^^d9{\ringaccent U} + \gdef^^da{\'U} + \gdef^^db{\H U} + \gdef^^dc{\"U} + \gdef^^dd{\'Y} + \gdef^^de{\cedilla T} + \gdef^^df{\ss} % - \gdefchar^^e0{\'r} - \gdefchar^^e1{\'a} - \gdefchar^^e2{\^a} - \gdefchar^^e3{\u a} - \gdefchar^^e4{\"a} - \gdefchar^^e5{\'l} - \gdefchar^^e6{\'c} - \gdefchar^^e7{\cedilla c} - \gdefchar^^e8{\v c} - \gdefchar^^e9{\'e} - \gdefchar^^ea{\ogonek{e}} - \gdefchar^^eb{\"e} - \gdefchar^^ec{\v e} - \gdefchar^^ed{\'{\dotless{i}}} - \gdefchar^^ee{\^{\dotless{i}}} - \gdefchar^^ef{\v d} + \gdef^^e0{\'r} + \gdef^^e1{\'a} + \gdef^^e2{\^a} + \gdef^^e3{\u a} + \gdef^^e4{\"a} + \gdef^^e5{\'l} + \gdef^^e6{\'c} + \gdef^^e7{\cedilla c} + \gdef^^e8{\v c} + \gdef^^e9{\'e} + \gdef^^ea{\ogonek{e}} + \gdef^^eb{\"e} + \gdef^^ec{\v e} + \gdef^^ed{\'\i} + \gdef^^ee{\^\i} + \gdef^^ef{\v d} % - \gdefchar^^f0{\dh} - \gdefchar^^f1{\'n} - \gdefchar^^f2{\v n} - \gdefchar^^f3{\'o} - \gdefchar^^f4{\^o} - \gdefchar^^f5{\H o} - \gdefchar^^f6{\"o} - \gdefchar^^f7{$\div$} - \gdefchar^^f8{\v r} - \gdefchar^^f9{\ringaccent u} - \gdefchar^^fa{\'u} - \gdefchar^^fb{\H u} - \gdefchar^^fc{\"u} - \gdefchar^^fd{\'y} - \gdefchar^^fe{\cedilla t} - \gdefchar^^ff{\dotaccent{}} + \gdef^^f0{\dh} + \gdef^^f1{\'n} + \gdef^^f2{\v n} + \gdef^^f3{\'o} + \gdef^^f4{\^o} + \gdef^^f5{\H o} + \gdef^^f6{\"o} + \gdef^^f7{$\div$} + \gdef^^f8{\v r} + \gdef^^f9{\ringaccent u} + \gdef^^fa{\'u} + \gdef^^fb{\H u} + \gdef^^fc{\"u} + \gdef^^fd{\'y} + \gdef^^fe{\cedilla t} + \gdef^^ff{\dotaccent{}} } % UTF-8 character definitions. @@ -10321,94 +8388,38 @@ directory should work if nowhere else does.} \fi } -% Give non-ASCII bytes the active definitions for processing UTF-8 sequences \begingroup \catcode`\~13 - \catcode`\$12 \catcode`\"12 - % Loop from \countUTFx to \countUTFy, performing \UTFviiiTmp - % substituting ~ and $ with a character token of that value. \def\UTFviiiLoop{% \global\catcode\countUTFx\active \uccode`\~\countUTFx - \uccode`\$\countUTFx \uppercase\expandafter{\UTFviiiTmp}% \advance\countUTFx by 1 \ifnum\countUTFx < \countUTFy \expandafter\UTFviiiLoop \fi} - % For bytes other than the first in a UTF-8 sequence. Not expected to - % be expanded except when writing to auxiliary files. - \countUTFx = "80 - \countUTFy = "C2 - \def\UTFviiiTmp{% - \gdef~{% - \ifpassthroughchars $\fi}}% - \UTFviiiLoop - \countUTFx = "C2 \countUTFy = "E0 \def\UTFviiiTmp{% - \gdef~{% - \ifpassthroughchars $% - \else\expandafter\UTFviiiTwoOctets\expandafter$\fi}}% + \xdef~{\noexpand\UTFviiiTwoOctets\string~}} \UTFviiiLoop \countUTFx = "E0 \countUTFy = "F0 \def\UTFviiiTmp{% - \gdef~{% - \ifpassthroughchars $% - \else\expandafter\UTFviiiThreeOctets\expandafter$\fi}}% + \xdef~{\noexpand\UTFviiiThreeOctets\string~}} \UTFviiiLoop \countUTFx = "F0 \countUTFy = "F4 \def\UTFviiiTmp{% - \gdef~{% - \ifpassthroughchars $% - \else\expandafter\UTFviiiFourOctets\expandafter$\fi - }}% + \xdef~{\noexpand\UTFviiiFourOctets\string~}} \UTFviiiLoop \endgroup -\def\globallet{\global\let} % save some \expandafter's below - -% @U{xxxx} to produce U+xxxx, if we support it. -\def\U#1{% - \expandafter\ifx\csname uni:#1\endcsname \relax - \iftxinativeunicodecapable - % All Unicode characters can be used if native Unicode handling is - % active. However, if the font does not have the glyph, - % letters are missing. - \begingroup - \uccode`\.="#1\relax - \uppercase{.} - \endgroup - \else - \errhelp = \EMsimple - \errmessage{Unicode character U+#1 not supported, sorry}% - \fi - \else - \csname uni:#1\endcsname - \fi -} - -% These macros are used here to construct the name of a control -% sequence to be defined. -\def\UTFviiiTwoOctetsName#1#2{% - \csname u8:#1\string #2\endcsname}% -\def\UTFviiiThreeOctetsName#1#2#3{% - \csname u8:#1\string #2\string #3\endcsname}% -\def\UTFviiiFourOctetsName#1#2#3#4{% - \csname u8:#1\string #2\string #3\string #4\endcsname}% - -% For UTF-8 byte sequences (TeX, e-TeX and pdfTeX), -% provide a definition macro to replace a Unicode character; -% this gets used by the @U command -% \begingroup \catcode`\"=12 \catcode`\<=12 @@ -10417,839 +8428,459 @@ directory should work if nowhere else does.} \catcode`\;=12 \catcode`\!=12 \catcode`\~=13 - \gdef\DeclareUnicodeCharacterUTFviii#1#2{% + + \gdef\DeclareUnicodeCharacter#1#2{% \countUTFz = "#1\relax + \wlog{\space\space defining Unicode char U+#1 (decimal \the\countUTFz)}% \begingroup \parseXMLCharref - - % Give \u8:... its definition. The sequence of seven \expandafter's - % expands after the \gdef three times, e.g. - % - % 1. \UTFviiTwoOctetsName B1 B2 - % 2. \csname u8:B1 \string B2 \endcsname - % 3. \u8: B1 B2 (a single control sequence token) - % - \expandafter\expandafter - \expandafter\expandafter - \expandafter\expandafter - \expandafter\gdef \UTFviiiTmp{#2}% - % - \expandafter\ifx\csname uni:#1\endcsname \relax \else - \message{Internal error, already defined: #1}% - \fi - % - % define an additional control sequence for this code point. - \expandafter\globallet\csname uni:#1\endcsname \UTFviiiTmp + \def\UTFviiiTwoOctets##1##2{% + \csname u8:##1\string ##2\endcsname}% + \def\UTFviiiThreeOctets##1##2##3{% + \csname u8:##1\string ##2\string ##3\endcsname}% + \def\UTFviiiFourOctets##1##2##3##4{% + \csname u8:##1\string ##2\string ##3\string ##4\endcsname}% + \expandafter\expandafter\expandafter\expandafter + \expandafter\expandafter\expandafter + \gdef\UTFviiiTmp{#2}% \endgroup} - % - % Given the value in \countUTFz as a Unicode code point, set \UTFviiiTmp - % to the corresponding UTF-8 sequence. + \gdef\parseXMLCharref{% \ifnum\countUTFz < "A0\relax \errhelp = \EMsimple \errmessage{Cannot define Unicode char value < 00A0}% \else\ifnum\countUTFz < "800\relax \parseUTFviiiA,% - \parseUTFviiiB C\UTFviiiTwoOctetsName.,% + \parseUTFviiiB C\UTFviiiTwoOctets.,% \else\ifnum\countUTFz < "10000\relax \parseUTFviiiA;% \parseUTFviiiA,% - \parseUTFviiiB E\UTFviiiThreeOctetsName.{,;}% + \parseUTFviiiB E\UTFviiiThreeOctets.{,;}% \else \parseUTFviiiA;% \parseUTFviiiA,% \parseUTFviiiA!% - \parseUTFviiiB F\UTFviiiFourOctetsName.{!,;}% + \parseUTFviiiB F\UTFviiiFourOctets.{!,;}% \fi\fi\fi } - % Extract a byte from the end of the UTF-8 representation of \countUTFx. - % It must be a non-initial byte in the sequence. - % Change \uccode of #1 for it to be used in \parseUTFviiiB as one - % of the bytes. \gdef\parseUTFviiiA#1{% \countUTFx = \countUTFz \divide\countUTFz by 64 - \countUTFy = \countUTFz % Save to be the future value of \countUTFz. + \countUTFy = \countUTFz \multiply\countUTFz by 64 - - % \countUTFz is now \countUTFx with the last 5 bits cleared. Subtract - % in order to get the last five bits. \advance\countUTFx by -\countUTFz - - % Convert this to the byte in the UTF-8 sequence. \advance\countUTFx by 128 \uccode `#1\countUTFx \countUTFz = \countUTFy} - % Used to put a UTF-8 byte sequence into \UTFviiiTmp - % #1 is the increment for \countUTFz to yield a the first byte of the UTF-8 - % sequence. - % #2 is one of the \UTFviii*OctetsName macros. - % #3 is always a full stop (.) - % #4 is a template for the other bytes in the sequence. The values for these - % bytes is substituted in here with \uppercase using the \uccode's. \gdef\parseUTFviiiB#1#2#3#4{% \advance\countUTFz by "#10\relax \uccode `#3\countUTFz \uppercase{\gdef\UTFviiiTmp{#2#3#4}}} \endgroup -% For native Unicode handling (XeTeX and LuaTeX), -% provide a definition macro that sets a catcode to `other' non-globally -% -\def\DeclareUnicodeCharacterNativeOther#1#2{% - \catcode"#1=\other -} - -% https://en.wikipedia.org/wiki/Plane_(Unicode)#Basic_M -% U+0000..U+007F = https://en.wikipedia.org/wiki/Basic_Latin_(Unicode_block) -% U+0080..U+00FF = https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block) -% U+0100..U+017F = https://en.wikipedia.org/wiki/Latin_Extended-A -% U+0180..U+024F = https://en.wikipedia.org/wiki/Latin_Extended-B -% -% Many of our renditions are less than wonderful, and all the missing -% characters are available somewhere. Loading the necessary fonts -% awaits user request. We can't truly support Unicode without -% reimplementing everything that's been done in LaTeX for many years, -% plus probably using luatex or xetex, and who knows what else. -% We won't be doing that here in this simple file. But we can try to at -% least make most of the characters not bomb out. -% -\def\unicodechardefs{% - \DeclareUnicodeCharacter{00A0}{\tie}% - \DeclareUnicodeCharacter{00A1}{\exclamdown}% - \DeclareUnicodeCharacter{00A2}{{\tcfont \char162}}% 0242=cent - \DeclareUnicodeCharacter{00A3}{\pounds{}}% - \DeclareUnicodeCharacter{00A4}{{\tcfont \char164}}% 0244=currency - \DeclareUnicodeCharacter{00A5}{{\tcfont \char165}}% 0245=yen - \DeclareUnicodeCharacter{00A6}{{\tcfont \char166}}% 0246=brokenbar - \DeclareUnicodeCharacter{00A7}{\S}% - \DeclareUnicodeCharacter{00A8}{\"{ }}% - \DeclareUnicodeCharacter{00A9}{\copyright{}}% - \DeclareUnicodeCharacter{00AA}{\ordf}% - \DeclareUnicodeCharacter{00AB}{\guillemetleft{}}% - \DeclareUnicodeCharacter{00AC}{\ensuremath\lnot}% - \DeclareUnicodeCharacter{00AD}{\-}% - \DeclareUnicodeCharacter{00AE}{\registeredsymbol{}}% - \DeclareUnicodeCharacter{00AF}{\={ }}% - % - \DeclareUnicodeCharacter{00B0}{\ringaccent{ }}% - \DeclareUnicodeCharacter{00B1}{\ensuremath\pm}% - \DeclareUnicodeCharacter{00B2}{$^2$}% - \DeclareUnicodeCharacter{00B3}{$^3$}% - \DeclareUnicodeCharacter{00B4}{\'{ }}% - \DeclareUnicodeCharacter{00B5}{$\mu$}% - \DeclareUnicodeCharacter{00B6}{\P}% - \DeclareUnicodeCharacter{00B7}{\ensuremath\cdot}% - \DeclareUnicodeCharacter{00B8}{\cedilla{ }}% - \DeclareUnicodeCharacter{00B9}{$^1$}% - \DeclareUnicodeCharacter{00BA}{\ordm}% - \DeclareUnicodeCharacter{00BB}{\guillemetright{}}% - \DeclareUnicodeCharacter{00BC}{$1\over4$}% - \DeclareUnicodeCharacter{00BD}{$1\over2$}% - \DeclareUnicodeCharacter{00BE}{$3\over4$}% - \DeclareUnicodeCharacter{00BF}{\questiondown}% - % - \DeclareUnicodeCharacter{00C0}{\`A}% - \DeclareUnicodeCharacter{00C1}{\'A}% - \DeclareUnicodeCharacter{00C2}{\^A}% - \DeclareUnicodeCharacter{00C3}{\~A}% - \DeclareUnicodeCharacter{00C4}{\"A}% - \DeclareUnicodeCharacter{00C5}{\AA}% - \DeclareUnicodeCharacter{00C6}{\AE}% - \DeclareUnicodeCharacter{00C7}{\cedilla{C}}% - \DeclareUnicodeCharacter{00C8}{\`E}% - \DeclareUnicodeCharacter{00C9}{\'E}% - \DeclareUnicodeCharacter{00CA}{\^E}% - \DeclareUnicodeCharacter{00CB}{\"E}% - \DeclareUnicodeCharacter{00CC}{\`I}% - \DeclareUnicodeCharacter{00CD}{\'I}% - \DeclareUnicodeCharacter{00CE}{\^I}% - \DeclareUnicodeCharacter{00CF}{\"I}% - % - \DeclareUnicodeCharacter{00D0}{\DH}% - \DeclareUnicodeCharacter{00D1}{\~N}% - \DeclareUnicodeCharacter{00D2}{\`O}% - \DeclareUnicodeCharacter{00D3}{\'O}% - \DeclareUnicodeCharacter{00D4}{\^O}% - \DeclareUnicodeCharacter{00D5}{\~O}% - \DeclareUnicodeCharacter{00D6}{\"O}% - \DeclareUnicodeCharacter{00D7}{\ensuremath\times}% - \DeclareUnicodeCharacter{00D8}{\O}% - \DeclareUnicodeCharacter{00D9}{\`U}% - \DeclareUnicodeCharacter{00DA}{\'U}% - \DeclareUnicodeCharacter{00DB}{\^U}% - \DeclareUnicodeCharacter{00DC}{\"U}% - \DeclareUnicodeCharacter{00DD}{\'Y}% - \DeclareUnicodeCharacter{00DE}{\TH}% - \DeclareUnicodeCharacter{00DF}{\ss}% - % - \DeclareUnicodeCharacter{00E0}{\`a}% - \DeclareUnicodeCharacter{00E1}{\'a}% - \DeclareUnicodeCharacter{00E2}{\^a}% - \DeclareUnicodeCharacter{00E3}{\~a}% - \DeclareUnicodeCharacter{00E4}{\"a}% - \DeclareUnicodeCharacter{00E5}{\aa}% - \DeclareUnicodeCharacter{00E6}{\ae}% - \DeclareUnicodeCharacter{00E7}{\cedilla{c}}% - \DeclareUnicodeCharacter{00E8}{\`e}% - \DeclareUnicodeCharacter{00E9}{\'e}% - \DeclareUnicodeCharacter{00EA}{\^e}% - \DeclareUnicodeCharacter{00EB}{\"e}% - \DeclareUnicodeCharacter{00EC}{\`{\dotless{i}}}% - \DeclareUnicodeCharacter{00ED}{\'{\dotless{i}}}% - \DeclareUnicodeCharacter{00EE}{\^{\dotless{i}}}% - \DeclareUnicodeCharacter{00EF}{\"{\dotless{i}}}% - % - \DeclareUnicodeCharacter{00F0}{\dh}% - \DeclareUnicodeCharacter{00F1}{\~n}% - \DeclareUnicodeCharacter{00F2}{\`o}% - \DeclareUnicodeCharacter{00F3}{\'o}% - \DeclareUnicodeCharacter{00F4}{\^o}% - \DeclareUnicodeCharacter{00F5}{\~o}% - \DeclareUnicodeCharacter{00F6}{\"o}% - \DeclareUnicodeCharacter{00F7}{\ensuremath\div}% - \DeclareUnicodeCharacter{00F8}{\o}% - \DeclareUnicodeCharacter{00F9}{\`u}% - \DeclareUnicodeCharacter{00FA}{\'u}% - \DeclareUnicodeCharacter{00FB}{\^u}% - \DeclareUnicodeCharacter{00FC}{\"u}% - \DeclareUnicodeCharacter{00FD}{\'y}% - \DeclareUnicodeCharacter{00FE}{\th}% - \DeclareUnicodeCharacter{00FF}{\"y}% - % - \DeclareUnicodeCharacter{0100}{\=A}% - \DeclareUnicodeCharacter{0101}{\=a}% - \DeclareUnicodeCharacter{0102}{\u{A}}% - \DeclareUnicodeCharacter{0103}{\u{a}}% - \DeclareUnicodeCharacter{0104}{\ogonek{A}}% - \DeclareUnicodeCharacter{0105}{\ogonek{a}}% - \DeclareUnicodeCharacter{0106}{\'C}% - \DeclareUnicodeCharacter{0107}{\'c}% - \DeclareUnicodeCharacter{0108}{\^C}% - \DeclareUnicodeCharacter{0109}{\^c}% - \DeclareUnicodeCharacter{010A}{\dotaccent{C}}% - \DeclareUnicodeCharacter{010B}{\dotaccent{c}}% - \DeclareUnicodeCharacter{010C}{\v{C}}% - \DeclareUnicodeCharacter{010D}{\v{c}}% - \DeclareUnicodeCharacter{010E}{\v{D}}% - \DeclareUnicodeCharacter{010F}{d'}% - % - \DeclareUnicodeCharacter{0110}{\DH}% - \DeclareUnicodeCharacter{0111}{\dh}% - \DeclareUnicodeCharacter{0112}{\=E}% - \DeclareUnicodeCharacter{0113}{\=e}% - \DeclareUnicodeCharacter{0114}{\u{E}}% - \DeclareUnicodeCharacter{0115}{\u{e}}% - \DeclareUnicodeCharacter{0116}{\dotaccent{E}}% - \DeclareUnicodeCharacter{0117}{\dotaccent{e}}% - \DeclareUnicodeCharacter{0118}{\ogonek{E}}% - \DeclareUnicodeCharacter{0119}{\ogonek{e}}% - \DeclareUnicodeCharacter{011A}{\v{E}}% - \DeclareUnicodeCharacter{011B}{\v{e}}% - \DeclareUnicodeCharacter{011C}{\^G}% - \DeclareUnicodeCharacter{011D}{\^g}% - \DeclareUnicodeCharacter{011E}{\u{G}}% - \DeclareUnicodeCharacter{011F}{\u{g}}% - % - \DeclareUnicodeCharacter{0120}{\dotaccent{G}}% - \DeclareUnicodeCharacter{0121}{\dotaccent{g}}% - \DeclareUnicodeCharacter{0122}{\cedilla{G}}% - \DeclareUnicodeCharacter{0123}{\cedilla{g}}% - \DeclareUnicodeCharacter{0124}{\^H}% - \DeclareUnicodeCharacter{0125}{\^h}% - \DeclareUnicodeCharacter{0126}{\missingcharmsg{H WITH STROKE}}% - \DeclareUnicodeCharacter{0127}{\missingcharmsg{h WITH STROKE}}% - \DeclareUnicodeCharacter{0128}{\~I}% - \DeclareUnicodeCharacter{0129}{\~{\dotless{i}}}% - \DeclareUnicodeCharacter{012A}{\=I}% - \DeclareUnicodeCharacter{012B}{\={\dotless{i}}}% - \DeclareUnicodeCharacter{012C}{\u{I}}% - \DeclareUnicodeCharacter{012D}{\u{\dotless{i}}}% - \DeclareUnicodeCharacter{012E}{\ogonek{I}}% - \DeclareUnicodeCharacter{012F}{\ogonek{i}}% - % - \DeclareUnicodeCharacter{0130}{\dotaccent{I}}% - \DeclareUnicodeCharacter{0131}{\dotless{i}}% - \DeclareUnicodeCharacter{0132}{IJ}% - \DeclareUnicodeCharacter{0133}{ij}% - \DeclareUnicodeCharacter{0134}{\^J}% - \DeclareUnicodeCharacter{0135}{\^{\dotless{j}}}% - \DeclareUnicodeCharacter{0136}{\cedilla{K}}% - \DeclareUnicodeCharacter{0137}{\cedilla{k}}% - \DeclareUnicodeCharacter{0138}{\ensuremath\kappa}% - \DeclareUnicodeCharacter{0139}{\'L}% - \DeclareUnicodeCharacter{013A}{\'l}% - \DeclareUnicodeCharacter{013B}{\cedilla{L}}% - \DeclareUnicodeCharacter{013C}{\cedilla{l}}% - \DeclareUnicodeCharacter{013D}{L'}% should kern - \DeclareUnicodeCharacter{013E}{l'}% should kern - \DeclareUnicodeCharacter{013F}{L\U{00B7}}% - % - \DeclareUnicodeCharacter{0140}{l\U{00B7}}% - \DeclareUnicodeCharacter{0141}{\L}% - \DeclareUnicodeCharacter{0142}{\l}% - \DeclareUnicodeCharacter{0143}{\'N}% - \DeclareUnicodeCharacter{0144}{\'n}% - \DeclareUnicodeCharacter{0145}{\cedilla{N}}% - \DeclareUnicodeCharacter{0146}{\cedilla{n}}% - \DeclareUnicodeCharacter{0147}{\v{N}}% - \DeclareUnicodeCharacter{0148}{\v{n}}% - \DeclareUnicodeCharacter{0149}{'n}% - \DeclareUnicodeCharacter{014A}{\missingcharmsg{ENG}}% - \DeclareUnicodeCharacter{014B}{\missingcharmsg{eng}}% - \DeclareUnicodeCharacter{014C}{\=O}% - \DeclareUnicodeCharacter{014D}{\=o}% - \DeclareUnicodeCharacter{014E}{\u{O}}% - \DeclareUnicodeCharacter{014F}{\u{o}}% - % - \DeclareUnicodeCharacter{0150}{\H{O}}% - \DeclareUnicodeCharacter{0151}{\H{o}}% - \DeclareUnicodeCharacter{0152}{\OE}% - \DeclareUnicodeCharacter{0153}{\oe}% - \DeclareUnicodeCharacter{0154}{\'R}% - \DeclareUnicodeCharacter{0155}{\'r}% - \DeclareUnicodeCharacter{0156}{\cedilla{R}}% - \DeclareUnicodeCharacter{0157}{\cedilla{r}}% - \DeclareUnicodeCharacter{0158}{\v{R}}% - \DeclareUnicodeCharacter{0159}{\v{r}}% - \DeclareUnicodeCharacter{015A}{\'S}% - \DeclareUnicodeCharacter{015B}{\'s}% - \DeclareUnicodeCharacter{015C}{\^S}% - \DeclareUnicodeCharacter{015D}{\^s}% - \DeclareUnicodeCharacter{015E}{\cedilla{S}}% - \DeclareUnicodeCharacter{015F}{\cedilla{s}}% - % - \DeclareUnicodeCharacter{0160}{\v{S}}% - \DeclareUnicodeCharacter{0161}{\v{s}}% - \DeclareUnicodeCharacter{0162}{\cedilla{T}}% - \DeclareUnicodeCharacter{0163}{\cedilla{t}}% - \DeclareUnicodeCharacter{0164}{\v{T}}% - \DeclareUnicodeCharacter{0165}{\v{t}}% - \DeclareUnicodeCharacter{0166}{\missingcharmsg{H WITH STROKE}}% - \DeclareUnicodeCharacter{0167}{\missingcharmsg{h WITH STROKE}}% - \DeclareUnicodeCharacter{0168}{\~U}% - \DeclareUnicodeCharacter{0169}{\~u}% - \DeclareUnicodeCharacter{016A}{\=U}% - \DeclareUnicodeCharacter{016B}{\=u}% - \DeclareUnicodeCharacter{016C}{\u{U}}% - \DeclareUnicodeCharacter{016D}{\u{u}}% - \DeclareUnicodeCharacter{016E}{\ringaccent{U}}% - \DeclareUnicodeCharacter{016F}{\ringaccent{u}}% - % - \DeclareUnicodeCharacter{0170}{\H{U}}% - \DeclareUnicodeCharacter{0171}{\H{u}}% - \DeclareUnicodeCharacter{0172}{\ogonek{U}}% - \DeclareUnicodeCharacter{0173}{\ogonek{u}}% - \DeclareUnicodeCharacter{0174}{\^W}% - \DeclareUnicodeCharacter{0175}{\^w}% - \DeclareUnicodeCharacter{0176}{\^Y}% - \DeclareUnicodeCharacter{0177}{\^y}% - \DeclareUnicodeCharacter{0178}{\"Y}% - \DeclareUnicodeCharacter{0179}{\'Z}% - \DeclareUnicodeCharacter{017A}{\'z}% - \DeclareUnicodeCharacter{017B}{\dotaccent{Z}}% - \DeclareUnicodeCharacter{017C}{\dotaccent{z}}% - \DeclareUnicodeCharacter{017D}{\v{Z}}% - \DeclareUnicodeCharacter{017E}{\v{z}}% - \DeclareUnicodeCharacter{017F}{\missingcharmsg{LONG S}}% - % - \DeclareUnicodeCharacter{01C4}{D\v{Z}}% - \DeclareUnicodeCharacter{01C5}{D\v{z}}% - \DeclareUnicodeCharacter{01C6}{d\v{z}}% - \DeclareUnicodeCharacter{01C7}{LJ}% - \DeclareUnicodeCharacter{01C8}{Lj}% - \DeclareUnicodeCharacter{01C9}{lj}% - \DeclareUnicodeCharacter{01CA}{NJ}% - \DeclareUnicodeCharacter{01CB}{Nj}% - \DeclareUnicodeCharacter{01CC}{nj}% - \DeclareUnicodeCharacter{01CD}{\v{A}}% - \DeclareUnicodeCharacter{01CE}{\v{a}}% - \DeclareUnicodeCharacter{01CF}{\v{I}}% - % - \DeclareUnicodeCharacter{01D0}{\v{\dotless{i}}}% - \DeclareUnicodeCharacter{01D1}{\v{O}}% - \DeclareUnicodeCharacter{01D2}{\v{o}}% - \DeclareUnicodeCharacter{01D3}{\v{U}}% - \DeclareUnicodeCharacter{01D4}{\v{u}}% - % - \DeclareUnicodeCharacter{01E2}{\={\AE}}% - \DeclareUnicodeCharacter{01E3}{\={\ae}}% - \DeclareUnicodeCharacter{01E6}{\v{G}}% - \DeclareUnicodeCharacter{01E7}{\v{g}}% - \DeclareUnicodeCharacter{01E8}{\v{K}}% - \DeclareUnicodeCharacter{01E9}{\v{k}}% - % - \DeclareUnicodeCharacter{01F0}{\v{\dotless{j}}}% - \DeclareUnicodeCharacter{01F1}{DZ}% - \DeclareUnicodeCharacter{01F2}{Dz}% - \DeclareUnicodeCharacter{01F3}{dz}% - \DeclareUnicodeCharacter{01F4}{\'G}% - \DeclareUnicodeCharacter{01F5}{\'g}% - \DeclareUnicodeCharacter{01F8}{\`N}% - \DeclareUnicodeCharacter{01F9}{\`n}% - \DeclareUnicodeCharacter{01FC}{\'{\AE}}% - \DeclareUnicodeCharacter{01FD}{\'{\ae}}% - \DeclareUnicodeCharacter{01FE}{\'{\O}}% - \DeclareUnicodeCharacter{01FF}{\'{\o}}% - % - \DeclareUnicodeCharacter{021E}{\v{H}}% - \DeclareUnicodeCharacter{021F}{\v{h}}% - % - \DeclareUnicodeCharacter{0226}{\dotaccent{A}}% - \DeclareUnicodeCharacter{0227}{\dotaccent{a}}% - \DeclareUnicodeCharacter{0228}{\cedilla{E}}% - \DeclareUnicodeCharacter{0229}{\cedilla{e}}% - \DeclareUnicodeCharacter{022E}{\dotaccent{O}}% - \DeclareUnicodeCharacter{022F}{\dotaccent{o}}% - % - \DeclareUnicodeCharacter{0232}{\=Y}% - \DeclareUnicodeCharacter{0233}{\=y}% - \DeclareUnicodeCharacter{0237}{\dotless{j}}% - % - \DeclareUnicodeCharacter{02DB}{\ogonek{ }}% - % - % Greek letters upper case - \DeclareUnicodeCharacter{0391}{{\it A}}% - \DeclareUnicodeCharacter{0392}{{\it B}}% - \DeclareUnicodeCharacter{0393}{\ensuremath{\mit\Gamma}}% - \DeclareUnicodeCharacter{0394}{\ensuremath{\mit\Delta}}% - \DeclareUnicodeCharacter{0395}{{\it E}}% - \DeclareUnicodeCharacter{0396}{{\it Z}}% - \DeclareUnicodeCharacter{0397}{{\it H}}% - \DeclareUnicodeCharacter{0398}{\ensuremath{\mit\Theta}}% - \DeclareUnicodeCharacter{0399}{{\it I}}% - \DeclareUnicodeCharacter{039A}{{\it K}}% - \DeclareUnicodeCharacter{039B}{\ensuremath{\mit\Lambda}}% - \DeclareUnicodeCharacter{039C}{{\it M}}% - \DeclareUnicodeCharacter{039D}{{\it N}}% - \DeclareUnicodeCharacter{039E}{\ensuremath{\mit\Xi}}% - \DeclareUnicodeCharacter{039F}{{\it O}}% - \DeclareUnicodeCharacter{03A0}{\ensuremath{\mit\Pi}}% - \DeclareUnicodeCharacter{03A1}{{\it P}}% - %\DeclareUnicodeCharacter{03A2}{} % none - corresponds to final sigma - \DeclareUnicodeCharacter{03A3}{\ensuremath{\mit\Sigma}}% - \DeclareUnicodeCharacter{03A4}{{\it T}}% - \DeclareUnicodeCharacter{03A5}{\ensuremath{\mit\Upsilon}}% - \DeclareUnicodeCharacter{03A6}{\ensuremath{\mit\Phi}}% - \DeclareUnicodeCharacter{03A7}{{\it X}}% - \DeclareUnicodeCharacter{03A8}{\ensuremath{\mit\Psi}}% - \DeclareUnicodeCharacter{03A9}{\ensuremath{\mit\Omega}}% - % - % Vowels with accents - \DeclareUnicodeCharacter{0390}{\ensuremath{\ddot{\acute\iota}}}% - \DeclareUnicodeCharacter{03AC}{\ensuremath{\acute\alpha}}% - \DeclareUnicodeCharacter{03AD}{\ensuremath{\acute\epsilon}}% - \DeclareUnicodeCharacter{03AE}{\ensuremath{\acute\eta}}% - \DeclareUnicodeCharacter{03AF}{\ensuremath{\acute\iota}}% - \DeclareUnicodeCharacter{03B0}{\ensuremath{\acute{\ddot\upsilon}}}% - % - % Standalone accent - \DeclareUnicodeCharacter{0384}{\ensuremath{\acute{\ }}}% - % - % Greek letters lower case - \DeclareUnicodeCharacter{03B1}{\ensuremath\alpha}% - \DeclareUnicodeCharacter{03B2}{\ensuremath\beta}% - \DeclareUnicodeCharacter{03B3}{\ensuremath\gamma}% - \DeclareUnicodeCharacter{03B4}{\ensuremath\delta}% - \DeclareUnicodeCharacter{03B5}{\ensuremath\epsilon}% - \DeclareUnicodeCharacter{03B6}{\ensuremath\zeta}% - \DeclareUnicodeCharacter{03B7}{\ensuremath\eta}% - \DeclareUnicodeCharacter{03B8}{\ensuremath\theta}% - \DeclareUnicodeCharacter{03B9}{\ensuremath\iota}% - \DeclareUnicodeCharacter{03BA}{\ensuremath\kappa}% - \DeclareUnicodeCharacter{03BB}{\ensuremath\lambda}% - \DeclareUnicodeCharacter{03BC}{\ensuremath\mu}% - \DeclareUnicodeCharacter{03BD}{\ensuremath\nu}% - \DeclareUnicodeCharacter{03BE}{\ensuremath\xi}% - \DeclareUnicodeCharacter{03BF}{{\it o}}% omicron - \DeclareUnicodeCharacter{03C0}{\ensuremath\pi}% - \DeclareUnicodeCharacter{03C1}{\ensuremath\rho}% - \DeclareUnicodeCharacter{03C2}{\ensuremath\varsigma}% - \DeclareUnicodeCharacter{03C3}{\ensuremath\sigma}% - \DeclareUnicodeCharacter{03C4}{\ensuremath\tau}% - \DeclareUnicodeCharacter{03C5}{\ensuremath\upsilon}% - \DeclareUnicodeCharacter{03C6}{\ensuremath\phi}% - \DeclareUnicodeCharacter{03C7}{\ensuremath\chi}% - \DeclareUnicodeCharacter{03C8}{\ensuremath\psi}% - \DeclareUnicodeCharacter{03C9}{\ensuremath\omega}% - % - % More Greek vowels with accents - \DeclareUnicodeCharacter{03CA}{\ensuremath{\ddot\iota}}% - \DeclareUnicodeCharacter{03CB}{\ensuremath{\ddot\upsilon}}% - \DeclareUnicodeCharacter{03CC}{\ensuremath{\acute o}}% - \DeclareUnicodeCharacter{03CD}{\ensuremath{\acute\upsilon}}% - \DeclareUnicodeCharacter{03CE}{\ensuremath{\acute\omega}}% - % - % Variant Greek letters - \DeclareUnicodeCharacter{03D1}{\ensuremath\vartheta}% - \DeclareUnicodeCharacter{03D6}{\ensuremath\varpi}% - \DeclareUnicodeCharacter{03F1}{\ensuremath\varrho}% - % - \DeclareUnicodeCharacter{1E02}{\dotaccent{B}}% - \DeclareUnicodeCharacter{1E03}{\dotaccent{b}}% - \DeclareUnicodeCharacter{1E04}{\udotaccent{B}}% - \DeclareUnicodeCharacter{1E05}{\udotaccent{b}}% - \DeclareUnicodeCharacter{1E06}{\ubaraccent{B}}% - \DeclareUnicodeCharacter{1E07}{\ubaraccent{b}}% - \DeclareUnicodeCharacter{1E0A}{\dotaccent{D}}% - \DeclareUnicodeCharacter{1E0B}{\dotaccent{d}}% - \DeclareUnicodeCharacter{1E0C}{\udotaccent{D}}% - \DeclareUnicodeCharacter{1E0D}{\udotaccent{d}}% - \DeclareUnicodeCharacter{1E0E}{\ubaraccent{D}}% - \DeclareUnicodeCharacter{1E0F}{\ubaraccent{d}}% - % - \DeclareUnicodeCharacter{1E1E}{\dotaccent{F}}% - \DeclareUnicodeCharacter{1E1F}{\dotaccent{f}}% - % - \DeclareUnicodeCharacter{1E20}{\=G}% - \DeclareUnicodeCharacter{1E21}{\=g}% - \DeclareUnicodeCharacter{1E22}{\dotaccent{H}}% - \DeclareUnicodeCharacter{1E23}{\dotaccent{h}}% - \DeclareUnicodeCharacter{1E24}{\udotaccent{H}}% - \DeclareUnicodeCharacter{1E25}{\udotaccent{h}}% - \DeclareUnicodeCharacter{1E26}{\"H}% - \DeclareUnicodeCharacter{1E27}{\"h}% - % - \DeclareUnicodeCharacter{1E30}{\'K}% - \DeclareUnicodeCharacter{1E31}{\'k}% - \DeclareUnicodeCharacter{1E32}{\udotaccent{K}}% - \DeclareUnicodeCharacter{1E33}{\udotaccent{k}}% - \DeclareUnicodeCharacter{1E34}{\ubaraccent{K}}% - \DeclareUnicodeCharacter{1E35}{\ubaraccent{k}}% - \DeclareUnicodeCharacter{1E36}{\udotaccent{L}}% - \DeclareUnicodeCharacter{1E37}{\udotaccent{l}}% - \DeclareUnicodeCharacter{1E3A}{\ubaraccent{L}}% - \DeclareUnicodeCharacter{1E3B}{\ubaraccent{l}}% - \DeclareUnicodeCharacter{1E3E}{\'M}% - \DeclareUnicodeCharacter{1E3F}{\'m}% - % - \DeclareUnicodeCharacter{1E40}{\dotaccent{M}}% - \DeclareUnicodeCharacter{1E41}{\dotaccent{m}}% - \DeclareUnicodeCharacter{1E42}{\udotaccent{M}}% - \DeclareUnicodeCharacter{1E43}{\udotaccent{m}}% - \DeclareUnicodeCharacter{1E44}{\dotaccent{N}}% - \DeclareUnicodeCharacter{1E45}{\dotaccent{n}}% - \DeclareUnicodeCharacter{1E46}{\udotaccent{N}}% - \DeclareUnicodeCharacter{1E47}{\udotaccent{n}}% - \DeclareUnicodeCharacter{1E48}{\ubaraccent{N}}% - \DeclareUnicodeCharacter{1E49}{\ubaraccent{n}}% - % - \DeclareUnicodeCharacter{1E54}{\'P}% - \DeclareUnicodeCharacter{1E55}{\'p}% - \DeclareUnicodeCharacter{1E56}{\dotaccent{P}}% - \DeclareUnicodeCharacter{1E57}{\dotaccent{p}}% - \DeclareUnicodeCharacter{1E58}{\dotaccent{R}}% - \DeclareUnicodeCharacter{1E59}{\dotaccent{r}}% - \DeclareUnicodeCharacter{1E5A}{\udotaccent{R}}% - \DeclareUnicodeCharacter{1E5B}{\udotaccent{r}}% - \DeclareUnicodeCharacter{1E5E}{\ubaraccent{R}}% - \DeclareUnicodeCharacter{1E5F}{\ubaraccent{r}}% - % - \DeclareUnicodeCharacter{1E60}{\dotaccent{S}}% - \DeclareUnicodeCharacter{1E61}{\dotaccent{s}}% - \DeclareUnicodeCharacter{1E62}{\udotaccent{S}}% - \DeclareUnicodeCharacter{1E63}{\udotaccent{s}}% - \DeclareUnicodeCharacter{1E6A}{\dotaccent{T}}% - \DeclareUnicodeCharacter{1E6B}{\dotaccent{t}}% - \DeclareUnicodeCharacter{1E6C}{\udotaccent{T}}% - \DeclareUnicodeCharacter{1E6D}{\udotaccent{t}}% - \DeclareUnicodeCharacter{1E6E}{\ubaraccent{T}}% - \DeclareUnicodeCharacter{1E6F}{\ubaraccent{t}}% - % - \DeclareUnicodeCharacter{1E7C}{\~V}% - \DeclareUnicodeCharacter{1E7D}{\~v}% - \DeclareUnicodeCharacter{1E7E}{\udotaccent{V}}% - \DeclareUnicodeCharacter{1E7F}{\udotaccent{v}}% - % - \DeclareUnicodeCharacter{1E80}{\`W}% - \DeclareUnicodeCharacter{1E81}{\`w}% - \DeclareUnicodeCharacter{1E82}{\'W}% - \DeclareUnicodeCharacter{1E83}{\'w}% - \DeclareUnicodeCharacter{1E84}{\"W}% - \DeclareUnicodeCharacter{1E85}{\"w}% - \DeclareUnicodeCharacter{1E86}{\dotaccent{W}}% - \DeclareUnicodeCharacter{1E87}{\dotaccent{w}}% - \DeclareUnicodeCharacter{1E88}{\udotaccent{W}}% - \DeclareUnicodeCharacter{1E89}{\udotaccent{w}}% - \DeclareUnicodeCharacter{1E8A}{\dotaccent{X}}% - \DeclareUnicodeCharacter{1E8B}{\dotaccent{x}}% - \DeclareUnicodeCharacter{1E8C}{\"X}% - \DeclareUnicodeCharacter{1E8D}{\"x}% - \DeclareUnicodeCharacter{1E8E}{\dotaccent{Y}}% - \DeclareUnicodeCharacter{1E8F}{\dotaccent{y}}% - % - \DeclareUnicodeCharacter{1E90}{\^Z}% - \DeclareUnicodeCharacter{1E91}{\^z}% - \DeclareUnicodeCharacter{1E92}{\udotaccent{Z}}% - \DeclareUnicodeCharacter{1E93}{\udotaccent{z}}% - \DeclareUnicodeCharacter{1E94}{\ubaraccent{Z}}% - \DeclareUnicodeCharacter{1E95}{\ubaraccent{z}}% - \DeclareUnicodeCharacter{1E96}{\ubaraccent{h}}% - \DeclareUnicodeCharacter{1E97}{\"t}% - \DeclareUnicodeCharacter{1E98}{\ringaccent{w}}% - \DeclareUnicodeCharacter{1E99}{\ringaccent{y}}% - % - \DeclareUnicodeCharacter{1EA0}{\udotaccent{A}}% - \DeclareUnicodeCharacter{1EA1}{\udotaccent{a}}% - % - \DeclareUnicodeCharacter{1EB8}{\udotaccent{E}}% - \DeclareUnicodeCharacter{1EB9}{\udotaccent{e}}% - \DeclareUnicodeCharacter{1EBC}{\~E}% - \DeclareUnicodeCharacter{1EBD}{\~e}% - % - \DeclareUnicodeCharacter{1ECA}{\udotaccent{I}}% - \DeclareUnicodeCharacter{1ECB}{\udotaccent{i}}% - \DeclareUnicodeCharacter{1ECC}{\udotaccent{O}}% - \DeclareUnicodeCharacter{1ECD}{\udotaccent{o}}% - % - \DeclareUnicodeCharacter{1EE4}{\udotaccent{U}}% - \DeclareUnicodeCharacter{1EE5}{\udotaccent{u}}% - % - \DeclareUnicodeCharacter{1EF2}{\`Y}% - \DeclareUnicodeCharacter{1EF3}{\`y}% - \DeclareUnicodeCharacter{1EF4}{\udotaccent{Y}}% - % - \DeclareUnicodeCharacter{1EF8}{\~Y}% - \DeclareUnicodeCharacter{1EF9}{\~y}% - % - % Punctuation - \DeclareUnicodeCharacter{2013}{--}% - \DeclareUnicodeCharacter{2014}{---}% - \DeclareUnicodeCharacter{2018}{\quoteleft{}}% - \DeclareUnicodeCharacter{2019}{\quoteright{}}% - \DeclareUnicodeCharacter{201A}{\quotesinglbase{}}% - \DeclareUnicodeCharacter{201C}{\quotedblleft{}}% - \DeclareUnicodeCharacter{201D}{\quotedblright{}}% - \DeclareUnicodeCharacter{201E}{\quotedblbase{}}% - \DeclareUnicodeCharacter{2020}{\ensuremath\dagger}% - \DeclareUnicodeCharacter{2021}{\ensuremath\ddagger}% - \DeclareUnicodeCharacter{2022}{\bullet{}}% - \DeclareUnicodeCharacter{202F}{\thinspace}% - \DeclareUnicodeCharacter{2026}{\dots{}}% - \DeclareUnicodeCharacter{2039}{\guilsinglleft{}}% - \DeclareUnicodeCharacter{203A}{\guilsinglright{}}% - % - \DeclareUnicodeCharacter{20AC}{\euro{}}% - % - \DeclareUnicodeCharacter{2192}{\expansion{}}% - \DeclareUnicodeCharacter{21D2}{\result{}}% - % - % Mathematical symbols - \DeclareUnicodeCharacter{2200}{\ensuremath\forall}% - \DeclareUnicodeCharacter{2203}{\ensuremath\exists}% - \DeclareUnicodeCharacter{2208}{\ensuremath\in}% - \DeclareUnicodeCharacter{2212}{\minus{}}% - \DeclareUnicodeCharacter{2217}{\ast}% - \DeclareUnicodeCharacter{221E}{\ensuremath\infty}% - \DeclareUnicodeCharacter{2225}{\ensuremath\parallel}% - \DeclareUnicodeCharacter{2227}{\ensuremath\wedge}% - \DeclareUnicodeCharacter{2229}{\ensuremath\cap}% - \DeclareUnicodeCharacter{2261}{\equiv{}}% - \DeclareUnicodeCharacter{2264}{\ensuremath\leq}% - \DeclareUnicodeCharacter{2265}{\ensuremath\geq}% - \DeclareUnicodeCharacter{2282}{\ensuremath\subset}% - \DeclareUnicodeCharacter{2287}{\ensuremath\supseteq}% - % - \DeclareUnicodeCharacter{2016}{\ensuremath\Vert}% - \DeclareUnicodeCharacter{2032}{\ensuremath\prime}% - \DeclareUnicodeCharacter{210F}{\ensuremath\hbar}% - \DeclareUnicodeCharacter{2111}{\ensuremath\Im}% - \DeclareUnicodeCharacter{2113}{\ensuremath\ell}% - \DeclareUnicodeCharacter{2118}{\ensuremath\wp}% - \DeclareUnicodeCharacter{211C}{\ensuremath\Re}% - \DeclareUnicodeCharacter{2135}{\ensuremath\aleph}% - \DeclareUnicodeCharacter{2190}{\ensuremath\leftarrow}% - \DeclareUnicodeCharacter{2191}{\ensuremath\uparrow}% - \DeclareUnicodeCharacter{2193}{\ensuremath\downarrow}% - \DeclareUnicodeCharacter{2194}{\ensuremath\leftrightarrow}% - \DeclareUnicodeCharacter{2195}{\ensuremath\updownarrow}% - \DeclareUnicodeCharacter{2196}{\ensuremath\nwarrow}% - \DeclareUnicodeCharacter{2197}{\ensuremath\nearrow}% - \DeclareUnicodeCharacter{2198}{\ensuremath\searrow}% - \DeclareUnicodeCharacter{2199}{\ensuremath\swarrow}% - \DeclareUnicodeCharacter{21A6}{\ensuremath\mapsto}% - \DeclareUnicodeCharacter{21A9}{\ensuremath\hookleftarrow}% - \DeclareUnicodeCharacter{21AA}{\ensuremath\hookrightarrow}% - \DeclareUnicodeCharacter{21BC}{\ensuremath\leftharpoonup}% - \DeclareUnicodeCharacter{21BD}{\ensuremath\leftharpoondown}% - \DeclareUnicodeCharacter{21C0}{\ensuremath\rightharpoonup}% - \DeclareUnicodeCharacter{21C1}{\ensuremath\rightharpoondown}% - \DeclareUnicodeCharacter{21CC}{\ensuremath\rightleftharpoons}% - \DeclareUnicodeCharacter{21D0}{\ensuremath\Leftarrow}% - \DeclareUnicodeCharacter{21D1}{\ensuremath\Uparrow}% - \DeclareUnicodeCharacter{21D3}{\ensuremath\Downarrow}% - \DeclareUnicodeCharacter{21D4}{\ensuremath\Leftrightarrow}% - \DeclareUnicodeCharacter{21D5}{\ensuremath\Updownarrow}% - \DeclareUnicodeCharacter{2202}{\ensuremath\partial}% - \DeclareUnicodeCharacter{2205}{\ensuremath\emptyset}% - \DeclareUnicodeCharacter{2207}{\ensuremath\nabla}% - \DeclareUnicodeCharacter{2209}{\ensuremath\notin}% - \DeclareUnicodeCharacter{220B}{\ensuremath\owns}% - \DeclareUnicodeCharacter{220F}{\ensuremath\prod}% - \DeclareUnicodeCharacter{2210}{\ensuremath\coprod}% - \DeclareUnicodeCharacter{2211}{\ensuremath\sum}% - \DeclareUnicodeCharacter{2213}{\ensuremath\mp}% - \DeclareUnicodeCharacter{2218}{\ensuremath\circ}% - \DeclareUnicodeCharacter{221A}{\ensuremath\surd}% - \DeclareUnicodeCharacter{221D}{\ensuremath\propto}% - \DeclareUnicodeCharacter{2220}{\ensuremath\angle}% - \DeclareUnicodeCharacter{2223}{\ensuremath\mid}% - \DeclareUnicodeCharacter{2228}{\ensuremath\vee}% - \DeclareUnicodeCharacter{222A}{\ensuremath\cup}% - \DeclareUnicodeCharacter{222B}{\ensuremath\smallint}% - \DeclareUnicodeCharacter{222E}{\ensuremath\oint}% - \DeclareUnicodeCharacter{223C}{\ensuremath\sim}% - \DeclareUnicodeCharacter{2240}{\ensuremath\wr}% - \DeclareUnicodeCharacter{2243}{\ensuremath\simeq}% - \DeclareUnicodeCharacter{2245}{\ensuremath\cong}% - \DeclareUnicodeCharacter{2248}{\ensuremath\approx}% - \DeclareUnicodeCharacter{224D}{\ensuremath\asymp}% - \DeclareUnicodeCharacter{2250}{\ensuremath\doteq}% - \DeclareUnicodeCharacter{2260}{\ensuremath\neq}% - \DeclareUnicodeCharacter{226A}{\ensuremath\ll}% - \DeclareUnicodeCharacter{226B}{\ensuremath\gg}% - \DeclareUnicodeCharacter{227A}{\ensuremath\prec}% - \DeclareUnicodeCharacter{227B}{\ensuremath\succ}% - \DeclareUnicodeCharacter{2283}{\ensuremath\supset}% - \DeclareUnicodeCharacter{2286}{\ensuremath\subseteq}% - \DeclareUnicodeCharacter{228E}{\ensuremath\uplus}% - \DeclareUnicodeCharacter{2291}{\ensuremath\sqsubseteq}% - \DeclareUnicodeCharacter{2292}{\ensuremath\sqsupseteq}% - \DeclareUnicodeCharacter{2293}{\ensuremath\sqcap}% - \DeclareUnicodeCharacter{2294}{\ensuremath\sqcup}% - \DeclareUnicodeCharacter{2295}{\ensuremath\oplus}% - \DeclareUnicodeCharacter{2296}{\ensuremath\ominus}% - \DeclareUnicodeCharacter{2297}{\ensuremath\otimes}% - \DeclareUnicodeCharacter{2298}{\ensuremath\oslash}% - \DeclareUnicodeCharacter{2299}{\ensuremath\odot}% - \DeclareUnicodeCharacter{22A2}{\ensuremath\vdash}% - \DeclareUnicodeCharacter{22A3}{\ensuremath\dashv}% - \DeclareUnicodeCharacter{22A4}{\ensuremath\ptextop}% - \DeclareUnicodeCharacter{22A5}{\ensuremath\bot}% - \DeclareUnicodeCharacter{22A8}{\ensuremath\models}% - \DeclareUnicodeCharacter{22C0}{\ensuremath\bigwedge}% - \DeclareUnicodeCharacter{22C1}{\ensuremath\bigvee}% - \DeclareUnicodeCharacter{22C2}{\ensuremath\bigcap}% - \DeclareUnicodeCharacter{22C3}{\ensuremath\bigcup}% - \DeclareUnicodeCharacter{22C4}{\ensuremath\diamond}% - \DeclareUnicodeCharacter{22C5}{\ensuremath\cdot}% - \DeclareUnicodeCharacter{22C6}{\ensuremath\star}% - \DeclareUnicodeCharacter{22C8}{\ensuremath\bowtie}% - \DeclareUnicodeCharacter{2308}{\ensuremath\lceil}% - \DeclareUnicodeCharacter{2309}{\ensuremath\rceil}% - \DeclareUnicodeCharacter{230A}{\ensuremath\lfloor}% - \DeclareUnicodeCharacter{230B}{\ensuremath\rfloor}% - \DeclareUnicodeCharacter{2322}{\ensuremath\frown}% - \DeclareUnicodeCharacter{2323}{\ensuremath\smile}% - % - \DeclareUnicodeCharacter{25B3}{\ensuremath\triangle}% - \DeclareUnicodeCharacter{25B7}{\ensuremath\triangleright}% - \DeclareUnicodeCharacter{25BD}{\ensuremath\bigtriangledown}% - \DeclareUnicodeCharacter{25C1}{\ensuremath\triangleleft}% - \DeclareUnicodeCharacter{25C7}{\ensuremath\diamond}% - \DeclareUnicodeCharacter{2660}{\ensuremath\spadesuit}% - \DeclareUnicodeCharacter{2661}{\ensuremath\heartsuit}% - \DeclareUnicodeCharacter{2662}{\ensuremath\diamondsuit}% - \DeclareUnicodeCharacter{2663}{\ensuremath\clubsuit}% - \DeclareUnicodeCharacter{266D}{\ensuremath\flat}% - \DeclareUnicodeCharacter{266E}{\ensuremath\natural}% - \DeclareUnicodeCharacter{266F}{\ensuremath\sharp}% - \DeclareUnicodeCharacter{26AA}{\ensuremath\bigcirc}% - \DeclareUnicodeCharacter{27B9}{\ensuremath\rangle}% - \DeclareUnicodeCharacter{27C2}{\ensuremath\perp}% - \DeclareUnicodeCharacter{27E8}{\ensuremath\langle}% - \DeclareUnicodeCharacter{27F5}{\ensuremath\longleftarrow}% - \DeclareUnicodeCharacter{27F6}{\ensuremath\longrightarrow}% - \DeclareUnicodeCharacter{27F7}{\ensuremath\longleftrightarrow}% - \DeclareUnicodeCharacter{27FC}{\ensuremath\longmapsto}% - \DeclareUnicodeCharacter{29F5}{\ensuremath\setminus}% - \DeclareUnicodeCharacter{2A00}{\ensuremath\bigodot}% - \DeclareUnicodeCharacter{2A01}{\ensuremath\bigoplus}% - \DeclareUnicodeCharacter{2A02}{\ensuremath\bigotimes}% - \DeclareUnicodeCharacter{2A04}{\ensuremath\biguplus}% - \DeclareUnicodeCharacter{2A06}{\ensuremath\bigsqcup}% - \DeclareUnicodeCharacter{2A3F}{\ensuremath\amalg}% - \DeclareUnicodeCharacter{2AAF}{\ensuremath\preceq}% - \DeclareUnicodeCharacter{2AB0}{\ensuremath\succeq}% - % - \global\mathchardef\checkmark="1370% actually the square root sign - \DeclareUnicodeCharacter{2713}{\ensuremath\checkmark}% -}% end of \unicodechardefs - -% UTF-8 byte sequence (pdfTeX) definitions (replacing and @U command) -% It makes the setting that replace UTF-8 byte sequence. \def\utfeightchardefs{% - \let\DeclareUnicodeCharacter\DeclareUnicodeCharacterUTFviii - \unicodechardefs -} + \DeclareUnicodeCharacter{00A0}{\tie} + \DeclareUnicodeCharacter{00A1}{\exclamdown} + \DeclareUnicodeCharacter{00A3}{\pounds} + \DeclareUnicodeCharacter{00A8}{\"{ }} + \DeclareUnicodeCharacter{00A9}{\copyright} + \DeclareUnicodeCharacter{00AA}{\ordf} + \DeclareUnicodeCharacter{00AB}{\guillemetleft} + \DeclareUnicodeCharacter{00AD}{\-} + \DeclareUnicodeCharacter{00AE}{\registeredsymbol} + \DeclareUnicodeCharacter{00AF}{\={ }} -% Whether the active definitions of non-ASCII characters expand to -% non-active tokens with the same character code. This is used to -% write characters literally, instead of using active definitions for -% printing the correct glyphs. -\newif\ifpassthroughchars -\passthroughcharsfalse + \DeclareUnicodeCharacter{00B0}{\ringaccent{ }} + \DeclareUnicodeCharacter{00B4}{\'{ }} + \DeclareUnicodeCharacter{00B8}{\cedilla{ }} + \DeclareUnicodeCharacter{00BA}{\ordm} + \DeclareUnicodeCharacter{00BB}{\guillemetright} + \DeclareUnicodeCharacter{00BF}{\questiondown} -% For native Unicode handling (XeTeX and LuaTeX), -% provide a definition macro to replace/pass-through a Unicode character -% -\def\DeclareUnicodeCharacterNative#1#2{% - \catcode"#1=\active - \def\dodeclareunicodecharacternative##1##2##3{% - \begingroup - \uccode`\~="##2\relax - \uppercase{\gdef~}{% - \ifpassthroughchars - ##1% - \else - ##3% - \fi - } - \endgroup - } - \begingroup - \uccode`\.="#1\relax - \uppercase{\def\UTFNativeTmp{.}}% - \expandafter\dodeclareunicodecharacternative\UTFNativeTmp{#1}{#2}% - \endgroup -} + \DeclareUnicodeCharacter{00C0}{\`A} + \DeclareUnicodeCharacter{00C1}{\'A} + \DeclareUnicodeCharacter{00C2}{\^A} + \DeclareUnicodeCharacter{00C3}{\~A} + \DeclareUnicodeCharacter{00C4}{\"A} + \DeclareUnicodeCharacter{00C5}{\AA} + \DeclareUnicodeCharacter{00C6}{\AE} + \DeclareUnicodeCharacter{00C7}{\cedilla{C}} + \DeclareUnicodeCharacter{00C8}{\`E} + \DeclareUnicodeCharacter{00C9}{\'E} + \DeclareUnicodeCharacter{00CA}{\^E} + \DeclareUnicodeCharacter{00CB}{\"E} + \DeclareUnicodeCharacter{00CC}{\`I} + \DeclareUnicodeCharacter{00CD}{\'I} + \DeclareUnicodeCharacter{00CE}{\^I} + \DeclareUnicodeCharacter{00CF}{\"I} -% Native Unicode handling (XeTeX and LuaTeX) character replacing definition. -% It activates the setting that replaces Unicode characters. -\def\nativeunicodechardefs{% - \let\DeclareUnicodeCharacter\DeclareUnicodeCharacterNative - \unicodechardefs -} + \DeclareUnicodeCharacter{00D0}{\DH} + \DeclareUnicodeCharacter{00D1}{\~N} + \DeclareUnicodeCharacter{00D2}{\`O} + \DeclareUnicodeCharacter{00D3}{\'O} + \DeclareUnicodeCharacter{00D4}{\^O} + \DeclareUnicodeCharacter{00D5}{\~O} + \DeclareUnicodeCharacter{00D6}{\"O} + \DeclareUnicodeCharacter{00D8}{\O} + \DeclareUnicodeCharacter{00D9}{\`U} + \DeclareUnicodeCharacter{00DA}{\'U} + \DeclareUnicodeCharacter{00DB}{\^U} + \DeclareUnicodeCharacter{00DC}{\"U} + \DeclareUnicodeCharacter{00DD}{\'Y} + \DeclareUnicodeCharacter{00DE}{\TH} + \DeclareUnicodeCharacter{00DF}{\ss} -% For native Unicode handling (XeTeX and LuaTeX), -% make the character token expand -% to the sequences given in \unicodechardefs for printing. -\def\DeclareUnicodeCharacterNativeAtU#1#2{% - \def\UTFAtUTmp{#2} - \expandafter\globallet\csname uni:#1\endcsname \UTFAtUTmp -} + \DeclareUnicodeCharacter{00E0}{\`a} + \DeclareUnicodeCharacter{00E1}{\'a} + \DeclareUnicodeCharacter{00E2}{\^a} + \DeclareUnicodeCharacter{00E3}{\~a} + \DeclareUnicodeCharacter{00E4}{\"a} + \DeclareUnicodeCharacter{00E5}{\aa} + \DeclareUnicodeCharacter{00E6}{\ae} + \DeclareUnicodeCharacter{00E7}{\cedilla{c}} + \DeclareUnicodeCharacter{00E8}{\`e} + \DeclareUnicodeCharacter{00E9}{\'e} + \DeclareUnicodeCharacter{00EA}{\^e} + \DeclareUnicodeCharacter{00EB}{\"e} + \DeclareUnicodeCharacter{00EC}{\`{\dotless{i}}} + \DeclareUnicodeCharacter{00ED}{\'{\dotless{i}}} + \DeclareUnicodeCharacter{00EE}{\^{\dotless{i}}} + \DeclareUnicodeCharacter{00EF}{\"{\dotless{i}}} + + \DeclareUnicodeCharacter{00F0}{\dh} + \DeclareUnicodeCharacter{00F1}{\~n} + \DeclareUnicodeCharacter{00F2}{\`o} + \DeclareUnicodeCharacter{00F3}{\'o} + \DeclareUnicodeCharacter{00F4}{\^o} + \DeclareUnicodeCharacter{00F5}{\~o} + \DeclareUnicodeCharacter{00F6}{\"o} + \DeclareUnicodeCharacter{00F8}{\o} + \DeclareUnicodeCharacter{00F9}{\`u} + \DeclareUnicodeCharacter{00FA}{\'u} + \DeclareUnicodeCharacter{00FB}{\^u} + \DeclareUnicodeCharacter{00FC}{\"u} + \DeclareUnicodeCharacter{00FD}{\'y} + \DeclareUnicodeCharacter{00FE}{\th} + \DeclareUnicodeCharacter{00FF}{\"y} + + \DeclareUnicodeCharacter{0100}{\=A} + \DeclareUnicodeCharacter{0101}{\=a} + \DeclareUnicodeCharacter{0102}{\u{A}} + \DeclareUnicodeCharacter{0103}{\u{a}} + \DeclareUnicodeCharacter{0104}{\ogonek{A}} + \DeclareUnicodeCharacter{0105}{\ogonek{a}} + \DeclareUnicodeCharacter{0106}{\'C} + \DeclareUnicodeCharacter{0107}{\'c} + \DeclareUnicodeCharacter{0108}{\^C} + \DeclareUnicodeCharacter{0109}{\^c} + \DeclareUnicodeCharacter{0118}{\ogonek{E}} + \DeclareUnicodeCharacter{0119}{\ogonek{e}} + \DeclareUnicodeCharacter{010A}{\dotaccent{C}} + \DeclareUnicodeCharacter{010B}{\dotaccent{c}} + \DeclareUnicodeCharacter{010C}{\v{C}} + \DeclareUnicodeCharacter{010D}{\v{c}} + \DeclareUnicodeCharacter{010E}{\v{D}} + + \DeclareUnicodeCharacter{0112}{\=E} + \DeclareUnicodeCharacter{0113}{\=e} + \DeclareUnicodeCharacter{0114}{\u{E}} + \DeclareUnicodeCharacter{0115}{\u{e}} + \DeclareUnicodeCharacter{0116}{\dotaccent{E}} + \DeclareUnicodeCharacter{0117}{\dotaccent{e}} + \DeclareUnicodeCharacter{011A}{\v{E}} + \DeclareUnicodeCharacter{011B}{\v{e}} + \DeclareUnicodeCharacter{011C}{\^G} + \DeclareUnicodeCharacter{011D}{\^g} + \DeclareUnicodeCharacter{011E}{\u{G}} + \DeclareUnicodeCharacter{011F}{\u{g}} + + \DeclareUnicodeCharacter{0120}{\dotaccent{G}} + \DeclareUnicodeCharacter{0121}{\dotaccent{g}} + \DeclareUnicodeCharacter{0124}{\^H} + \DeclareUnicodeCharacter{0125}{\^h} + \DeclareUnicodeCharacter{0128}{\~I} + \DeclareUnicodeCharacter{0129}{\~{\dotless{i}}} + \DeclareUnicodeCharacter{012A}{\=I} + \DeclareUnicodeCharacter{012B}{\={\dotless{i}}} + \DeclareUnicodeCharacter{012C}{\u{I}} + \DeclareUnicodeCharacter{012D}{\u{\dotless{i}}} + + \DeclareUnicodeCharacter{0130}{\dotaccent{I}} + \DeclareUnicodeCharacter{0131}{\dotless{i}} + \DeclareUnicodeCharacter{0132}{IJ} + \DeclareUnicodeCharacter{0133}{ij} + \DeclareUnicodeCharacter{0134}{\^J} + \DeclareUnicodeCharacter{0135}{\^{\dotless{j}}} + \DeclareUnicodeCharacter{0139}{\'L} + \DeclareUnicodeCharacter{013A}{\'l} + + \DeclareUnicodeCharacter{0141}{\L} + \DeclareUnicodeCharacter{0142}{\l} + \DeclareUnicodeCharacter{0143}{\'N} + \DeclareUnicodeCharacter{0144}{\'n} + \DeclareUnicodeCharacter{0147}{\v{N}} + \DeclareUnicodeCharacter{0148}{\v{n}} + \DeclareUnicodeCharacter{014C}{\=O} + \DeclareUnicodeCharacter{014D}{\=o} + \DeclareUnicodeCharacter{014E}{\u{O}} + \DeclareUnicodeCharacter{014F}{\u{o}} + + \DeclareUnicodeCharacter{0150}{\H{O}} + \DeclareUnicodeCharacter{0151}{\H{o}} + \DeclareUnicodeCharacter{0152}{\OE} + \DeclareUnicodeCharacter{0153}{\oe} + \DeclareUnicodeCharacter{0154}{\'R} + \DeclareUnicodeCharacter{0155}{\'r} + \DeclareUnicodeCharacter{0158}{\v{R}} + \DeclareUnicodeCharacter{0159}{\v{r}} + \DeclareUnicodeCharacter{015A}{\'S} + \DeclareUnicodeCharacter{015B}{\'s} + \DeclareUnicodeCharacter{015C}{\^S} + \DeclareUnicodeCharacter{015D}{\^s} + \DeclareUnicodeCharacter{015E}{\cedilla{S}} + \DeclareUnicodeCharacter{015F}{\cedilla{s}} + + \DeclareUnicodeCharacter{0160}{\v{S}} + \DeclareUnicodeCharacter{0161}{\v{s}} + \DeclareUnicodeCharacter{0162}{\cedilla{t}} + \DeclareUnicodeCharacter{0163}{\cedilla{T}} + \DeclareUnicodeCharacter{0164}{\v{T}} + + \DeclareUnicodeCharacter{0168}{\~U} + \DeclareUnicodeCharacter{0169}{\~u} + \DeclareUnicodeCharacter{016A}{\=U} + \DeclareUnicodeCharacter{016B}{\=u} + \DeclareUnicodeCharacter{016C}{\u{U}} + \DeclareUnicodeCharacter{016D}{\u{u}} + \DeclareUnicodeCharacter{016E}{\ringaccent{U}} + \DeclareUnicodeCharacter{016F}{\ringaccent{u}} + + \DeclareUnicodeCharacter{0170}{\H{U}} + \DeclareUnicodeCharacter{0171}{\H{u}} + \DeclareUnicodeCharacter{0174}{\^W} + \DeclareUnicodeCharacter{0175}{\^w} + \DeclareUnicodeCharacter{0176}{\^Y} + \DeclareUnicodeCharacter{0177}{\^y} + \DeclareUnicodeCharacter{0178}{\"Y} + \DeclareUnicodeCharacter{0179}{\'Z} + \DeclareUnicodeCharacter{017A}{\'z} + \DeclareUnicodeCharacter{017B}{\dotaccent{Z}} + \DeclareUnicodeCharacter{017C}{\dotaccent{z}} + \DeclareUnicodeCharacter{017D}{\v{Z}} + \DeclareUnicodeCharacter{017E}{\v{z}} + + \DeclareUnicodeCharacter{01C4}{D\v{Z}} + \DeclareUnicodeCharacter{01C5}{D\v{z}} + \DeclareUnicodeCharacter{01C6}{d\v{z}} + \DeclareUnicodeCharacter{01C7}{LJ} + \DeclareUnicodeCharacter{01C8}{Lj} + \DeclareUnicodeCharacter{01C9}{lj} + \DeclareUnicodeCharacter{01CA}{NJ} + \DeclareUnicodeCharacter{01CB}{Nj} + \DeclareUnicodeCharacter{01CC}{nj} + \DeclareUnicodeCharacter{01CD}{\v{A}} + \DeclareUnicodeCharacter{01CE}{\v{a}} + \DeclareUnicodeCharacter{01CF}{\v{I}} + + \DeclareUnicodeCharacter{01D0}{\v{\dotless{i}}} + \DeclareUnicodeCharacter{01D1}{\v{O}} + \DeclareUnicodeCharacter{01D2}{\v{o}} + \DeclareUnicodeCharacter{01D3}{\v{U}} + \DeclareUnicodeCharacter{01D4}{\v{u}} + + \DeclareUnicodeCharacter{01E2}{\={\AE}} + \DeclareUnicodeCharacter{01E3}{\={\ae}} + \DeclareUnicodeCharacter{01E6}{\v{G}} + \DeclareUnicodeCharacter{01E7}{\v{g}} + \DeclareUnicodeCharacter{01E8}{\v{K}} + \DeclareUnicodeCharacter{01E9}{\v{k}} + + \DeclareUnicodeCharacter{01F0}{\v{\dotless{j}}} + \DeclareUnicodeCharacter{01F1}{DZ} + \DeclareUnicodeCharacter{01F2}{Dz} + \DeclareUnicodeCharacter{01F3}{dz} + \DeclareUnicodeCharacter{01F4}{\'G} + \DeclareUnicodeCharacter{01F5}{\'g} + \DeclareUnicodeCharacter{01F8}{\`N} + \DeclareUnicodeCharacter{01F9}{\`n} + \DeclareUnicodeCharacter{01FC}{\'{\AE}} + \DeclareUnicodeCharacter{01FD}{\'{\ae}} + \DeclareUnicodeCharacter{01FE}{\'{\O}} + \DeclareUnicodeCharacter{01FF}{\'{\o}} + + \DeclareUnicodeCharacter{021E}{\v{H}} + \DeclareUnicodeCharacter{021F}{\v{h}} + + \DeclareUnicodeCharacter{0226}{\dotaccent{A}} + \DeclareUnicodeCharacter{0227}{\dotaccent{a}} + \DeclareUnicodeCharacter{0228}{\cedilla{E}} + \DeclareUnicodeCharacter{0229}{\cedilla{e}} + \DeclareUnicodeCharacter{022E}{\dotaccent{O}} + \DeclareUnicodeCharacter{022F}{\dotaccent{o}} + + \DeclareUnicodeCharacter{0232}{\=Y} + \DeclareUnicodeCharacter{0233}{\=y} + \DeclareUnicodeCharacter{0237}{\dotless{j}} + + \DeclareUnicodeCharacter{02DB}{\ogonek{ }} + + \DeclareUnicodeCharacter{1E02}{\dotaccent{B}} + \DeclareUnicodeCharacter{1E03}{\dotaccent{b}} + \DeclareUnicodeCharacter{1E04}{\udotaccent{B}} + \DeclareUnicodeCharacter{1E05}{\udotaccent{b}} + \DeclareUnicodeCharacter{1E06}{\ubaraccent{B}} + \DeclareUnicodeCharacter{1E07}{\ubaraccent{b}} + \DeclareUnicodeCharacter{1E0A}{\dotaccent{D}} + \DeclareUnicodeCharacter{1E0B}{\dotaccent{d}} + \DeclareUnicodeCharacter{1E0C}{\udotaccent{D}} + \DeclareUnicodeCharacter{1E0D}{\udotaccent{d}} + \DeclareUnicodeCharacter{1E0E}{\ubaraccent{D}} + \DeclareUnicodeCharacter{1E0F}{\ubaraccent{d}} + + \DeclareUnicodeCharacter{1E1E}{\dotaccent{F}} + \DeclareUnicodeCharacter{1E1F}{\dotaccent{f}} + + \DeclareUnicodeCharacter{1E20}{\=G} + \DeclareUnicodeCharacter{1E21}{\=g} + \DeclareUnicodeCharacter{1E22}{\dotaccent{H}} + \DeclareUnicodeCharacter{1E23}{\dotaccent{h}} + \DeclareUnicodeCharacter{1E24}{\udotaccent{H}} + \DeclareUnicodeCharacter{1E25}{\udotaccent{h}} + \DeclareUnicodeCharacter{1E26}{\"H} + \DeclareUnicodeCharacter{1E27}{\"h} + + \DeclareUnicodeCharacter{1E30}{\'K} + \DeclareUnicodeCharacter{1E31}{\'k} + \DeclareUnicodeCharacter{1E32}{\udotaccent{K}} + \DeclareUnicodeCharacter{1E33}{\udotaccent{k}} + \DeclareUnicodeCharacter{1E34}{\ubaraccent{K}} + \DeclareUnicodeCharacter{1E35}{\ubaraccent{k}} + \DeclareUnicodeCharacter{1E36}{\udotaccent{L}} + \DeclareUnicodeCharacter{1E37}{\udotaccent{l}} + \DeclareUnicodeCharacter{1E3A}{\ubaraccent{L}} + \DeclareUnicodeCharacter{1E3B}{\ubaraccent{l}} + \DeclareUnicodeCharacter{1E3E}{\'M} + \DeclareUnicodeCharacter{1E3F}{\'m} + + \DeclareUnicodeCharacter{1E40}{\dotaccent{M}} + \DeclareUnicodeCharacter{1E41}{\dotaccent{m}} + \DeclareUnicodeCharacter{1E42}{\udotaccent{M}} + \DeclareUnicodeCharacter{1E43}{\udotaccent{m}} + \DeclareUnicodeCharacter{1E44}{\dotaccent{N}} + \DeclareUnicodeCharacter{1E45}{\dotaccent{n}} + \DeclareUnicodeCharacter{1E46}{\udotaccent{N}} + \DeclareUnicodeCharacter{1E47}{\udotaccent{n}} + \DeclareUnicodeCharacter{1E48}{\ubaraccent{N}} + \DeclareUnicodeCharacter{1E49}{\ubaraccent{n}} + + \DeclareUnicodeCharacter{1E54}{\'P} + \DeclareUnicodeCharacter{1E55}{\'p} + \DeclareUnicodeCharacter{1E56}{\dotaccent{P}} + \DeclareUnicodeCharacter{1E57}{\dotaccent{p}} + \DeclareUnicodeCharacter{1E58}{\dotaccent{R}} + \DeclareUnicodeCharacter{1E59}{\dotaccent{r}} + \DeclareUnicodeCharacter{1E5A}{\udotaccent{R}} + \DeclareUnicodeCharacter{1E5B}{\udotaccent{r}} + \DeclareUnicodeCharacter{1E5E}{\ubaraccent{R}} + \DeclareUnicodeCharacter{1E5F}{\ubaraccent{r}} + + \DeclareUnicodeCharacter{1E60}{\dotaccent{S}} + \DeclareUnicodeCharacter{1E61}{\dotaccent{s}} + \DeclareUnicodeCharacter{1E62}{\udotaccent{S}} + \DeclareUnicodeCharacter{1E63}{\udotaccent{s}} + \DeclareUnicodeCharacter{1E6A}{\dotaccent{T}} + \DeclareUnicodeCharacter{1E6B}{\dotaccent{t}} + \DeclareUnicodeCharacter{1E6C}{\udotaccent{T}} + \DeclareUnicodeCharacter{1E6D}{\udotaccent{t}} + \DeclareUnicodeCharacter{1E6E}{\ubaraccent{T}} + \DeclareUnicodeCharacter{1E6F}{\ubaraccent{t}} + + \DeclareUnicodeCharacter{1E7C}{\~V} + \DeclareUnicodeCharacter{1E7D}{\~v} + \DeclareUnicodeCharacter{1E7E}{\udotaccent{V}} + \DeclareUnicodeCharacter{1E7F}{\udotaccent{v}} + + \DeclareUnicodeCharacter{1E80}{\`W} + \DeclareUnicodeCharacter{1E81}{\`w} + \DeclareUnicodeCharacter{1E82}{\'W} + \DeclareUnicodeCharacter{1E83}{\'w} + \DeclareUnicodeCharacter{1E84}{\"W} + \DeclareUnicodeCharacter{1E85}{\"w} + \DeclareUnicodeCharacter{1E86}{\dotaccent{W}} + \DeclareUnicodeCharacter{1E87}{\dotaccent{w}} + \DeclareUnicodeCharacter{1E88}{\udotaccent{W}} + \DeclareUnicodeCharacter{1E89}{\udotaccent{w}} + \DeclareUnicodeCharacter{1E8A}{\dotaccent{X}} + \DeclareUnicodeCharacter{1E8B}{\dotaccent{x}} + \DeclareUnicodeCharacter{1E8C}{\"X} + \DeclareUnicodeCharacter{1E8D}{\"x} + \DeclareUnicodeCharacter{1E8E}{\dotaccent{Y}} + \DeclareUnicodeCharacter{1E8F}{\dotaccent{y}} + + \DeclareUnicodeCharacter{1E90}{\^Z} + \DeclareUnicodeCharacter{1E91}{\^z} + \DeclareUnicodeCharacter{1E92}{\udotaccent{Z}} + \DeclareUnicodeCharacter{1E93}{\udotaccent{z}} + \DeclareUnicodeCharacter{1E94}{\ubaraccent{Z}} + \DeclareUnicodeCharacter{1E95}{\ubaraccent{z}} + \DeclareUnicodeCharacter{1E96}{\ubaraccent{h}} + \DeclareUnicodeCharacter{1E97}{\"t} + \DeclareUnicodeCharacter{1E98}{\ringaccent{w}} + \DeclareUnicodeCharacter{1E99}{\ringaccent{y}} + + \DeclareUnicodeCharacter{1EA0}{\udotaccent{A}} + \DeclareUnicodeCharacter{1EA1}{\udotaccent{a}} + + \DeclareUnicodeCharacter{1EB8}{\udotaccent{E}} + \DeclareUnicodeCharacter{1EB9}{\udotaccent{e}} + \DeclareUnicodeCharacter{1EBC}{\~E} + \DeclareUnicodeCharacter{1EBD}{\~e} + + \DeclareUnicodeCharacter{1ECA}{\udotaccent{I}} + \DeclareUnicodeCharacter{1ECB}{\udotaccent{i}} + \DeclareUnicodeCharacter{1ECC}{\udotaccent{O}} + \DeclareUnicodeCharacter{1ECD}{\udotaccent{o}} + + \DeclareUnicodeCharacter{1EE4}{\udotaccent{U}} + \DeclareUnicodeCharacter{1EE5}{\udotaccent{u}} + + \DeclareUnicodeCharacter{1EF2}{\`Y} + \DeclareUnicodeCharacter{1EF3}{\`y} + \DeclareUnicodeCharacter{1EF4}{\udotaccent{Y}} + + \DeclareUnicodeCharacter{1EF8}{\~Y} + \DeclareUnicodeCharacter{1EF9}{\~y} + + \DeclareUnicodeCharacter{2013}{--} + \DeclareUnicodeCharacter{2014}{---} + \DeclareUnicodeCharacter{2018}{\quoteleft} + \DeclareUnicodeCharacter{2019}{\quoteright} + \DeclareUnicodeCharacter{201A}{\quotesinglbase} + \DeclareUnicodeCharacter{201C}{\quotedblleft} + \DeclareUnicodeCharacter{201D}{\quotedblright} + \DeclareUnicodeCharacter{201E}{\quotedblbase} + \DeclareUnicodeCharacter{2022}{\bullet} + \DeclareUnicodeCharacter{2026}{\dots} + \DeclareUnicodeCharacter{2039}{\guilsinglleft} + \DeclareUnicodeCharacter{203A}{\guilsinglright} + \DeclareUnicodeCharacter{20AC}{\euro} + + \DeclareUnicodeCharacter{2192}{\expansion} + \DeclareUnicodeCharacter{21D2}{\result} + + \DeclareUnicodeCharacter{2212}{\minus} + \DeclareUnicodeCharacter{2217}{\point} + \DeclareUnicodeCharacter{2261}{\equiv} +}% end of \utfeightchardefs -% @U command definitions for native Unicode handling (XeTeX and LuaTeX). -\def\nativeunicodechardefsatu{% - \let\DeclareUnicodeCharacter\DeclareUnicodeCharacterNativeAtU - \unicodechardefs -} % US-ASCII character definitions. \def\asciichardefs{% nothing need be done \relax } -% define all Unicode characters we know about, for the sake of @U. -\iftxinativeunicodecapable - \nativeunicodechardefsatu -\else - \utfeightchardefs -\fi - - % Make non-ASCII characters printable again for compatibility with % existing Texinfo documents that may use them, even without declaring a % document encoding. @@ -11268,8 +8899,8 @@ directory should work if nowhere else does.} % Prevent underfull vbox error messages. \vbadness = 10000 -% Don't be very finicky about underfull hboxes, either. -\hbadness = 6666 +% Don't be so finicky about underfull hboxes, either. +\hbadness = 2000 % Following George Bush, get rid of widows and orphans. \widowpenalty=10000 @@ -11305,12 +8936,12 @@ directory should work if nowhere else does.} \advance\vsize by \topskip \outervsize = \vsize \advance\outervsize by 2\topandbottommargin - \txipageheight = \vsize + \pageheight = \vsize % \hsize = #2\relax \outerhsize = \hsize \advance\outerhsize by 0.5in - \txipagewidth = \hsize + \pagewidth = \hsize % \normaloffset = #4\relax \bindingoffset = #5\relax @@ -11322,14 +8953,6 @@ directory should work if nowhere else does.} % whatever layout pdftex was dumped with. \pdfhorigin = 1 true in \pdfvorigin = 1 true in - \else - \ifx\XeTeXrevision\thisisundefined - \special{papersize=#8,#7}% - \else - \pdfpageheight #7\relax - \pdfpagewidth #8\relax - % XeTeX does not have \pdfhorigin and \pdfvorigin. - \fi \fi % \setleading{\textleading} @@ -11362,6 +8985,7 @@ directory should work if nowhere else does.} % \lispnarrowing = 0.3in \tolerance = 700 + \hfuzz = 1pt \contentsrightmargin = 0pt \defbodyindent = .5cm }} @@ -11379,6 +9003,7 @@ directory should work if nowhere else does.} % \lispnarrowing = 0.25in \tolerance = 700 + \hfuzz = 1pt \contentsrightmargin = 0pt \defbodyindent = .4cm }} @@ -11404,6 +9029,7 @@ directory should work if nowhere else does.} {297mm}{210mm}% % \tolerance = 700 + \hfuzz = 1pt \contentsrightmargin = 0pt \defbodyindent = 5mm }} @@ -11422,6 +9048,7 @@ directory should work if nowhere else does.} % \lispnarrowing = 0.2in \tolerance = 800 + \hfuzz = 1.2pt \contentsrightmargin = 0pt \defbodyindent = 2mm \tableindent = 12mm @@ -11463,11 +9090,9 @@ directory should work if nowhere else does.} % \dimen0 = #1\relax \advance\dimen0 by \voffset - \advance\dimen0 by 1in % reference point for DVI is 1 inch from top of page % \dimen2 = \hsize \advance\dimen2 by \normaloffset - \advance\dimen2 by 1in % reference point is 1 inch from left edge of page % \internalpagesizes{#1}{\hsize}% {\voffset}{\normaloffset}% @@ -11479,27 +9104,31 @@ directory should work if nowhere else does.} % \letterpaper -% Default value of \hfuzz, for suppressing warnings about overfull hboxes. -\hfuzz = 1pt - \message{and turning on texinfo input format.} -\def^^L{\par} % remove \outer, so ^L can appear in an @comment - % DEL is a comment character, in case @c does not suffice. \catcode`\^^? = 14 % Define macros to output various characters with catcode for normal text. -\catcode`\"=\other \def\normaldoublequote{"} -\catcode`\$=\other \def\normaldollar{$}%$ font-lock fix -\catcode`\+=\other \def\normalplus{+} -\catcode`\<=\other \def\normalless{<} -\catcode`\>=\other \def\normalgreater{>} -\catcode`\^=\other \def\normalcaret{^} -\catcode`\_=\other \def\normalunderscore{_} -\catcode`\|=\other \def\normalverticalbar{|} -\catcode`\~=\other \def\normaltilde{~} +\catcode`\"=\other +\catcode`\~=\other +\catcode`\^=\other +\catcode`\_=\other +\catcode`\|=\other +\catcode`\<=\other +\catcode`\>=\other +\catcode`\+=\other +\catcode`\$=\other +\def\normaldoublequote{"} +\def\normaltilde{~} +\def\normalcaret{^} +\def\normalunderscore{_} +\def\normalverticalbar{|} +\def\normalless{<} +\def\normalgreater{>} +\def\normalplus{+} +\def\normaldollar{$}%$ font-lock fix % This macro is used to make a character print one way in \tt % (where it can probably be output as-is), and another way in other fonts, @@ -11518,47 +9147,44 @@ directory should work if nowhere else does.} % this is not a problem. \def\ifusingit#1#2{\ifdim \fontdimen1\font>0pt #1\else #2\fi} -% Set catcodes for Texinfo file - -% Active characters for printing the wanted glyph. +% Turn off all special characters except @ +% (and those which the user can use as if they were ordinary). % Most of these we simply print from the \tt font, but for some, we can % use math or other variants that look better in normal text. -% + \catcode`\"=\active \def\activedoublequote{{\tt\char34}} \let"=\activedoublequote -\catcode`\~=\active \def\activetilde{{\tt\char126}} \let~ = \activetilde -\chardef\hatchar=`\^ -\catcode`\^=\active \def\activehat{{\tt \hatchar}} \let^ = \activehat +\catcode`\~=\active +\def~{{\tt\char126}} +\chardef\hat=`\^ +\catcode`\^=\active +\def^{{\tt \hat}} \catcode`\_=\active \def_{\ifusingtt\normalunderscore\_} -\def\_{\leavevmode \kern.07em \vbox{\hrule width.3em height.1ex}\kern .07em } \let\realunder=_ +% Subroutine for the previous macro. +\def\_{\leavevmode \kern.07em \vbox{\hrule width.3em height.1ex}\kern .07em } -\catcode`\|=\active \def|{{\tt\char124}} - +\catcode`\|=\active +\def|{{\tt\char124}} \chardef \less=`\< -\catcode`\<=\active \def\activeless{{\tt \less}}\let< = \activeless +\catcode`\<=\active +\def<{{\tt \less}} \chardef \gtr=`\> -\catcode`\>=\active \def\activegtr{{\tt \gtr}}\let> = \activegtr -\catcode`\+=\active \def+{{\tt \char 43}} -\catcode`\$=\active \def${\ifusingit{{\sl\$}}\normaldollar}%$ font-lock fix -\catcode`\-=\active \let-=\normaldash +\catcode`\>=\active +\def>{{\tt \gtr}} +\catcode`\+=\active +\def+{{\tt \char 43}} +\catcode`\$=\active +\def${\ifusingit{{\sl\$}}\normaldollar}%$ font-lock fix - -% used for headline/footline in the output routine, in case the page -% breaks in the middle of an @tex block. -\def\texinfochars{% - \let< = \activeless - \let> = \activegtr - \let~ = \activetilde - \let^ = \activehat - \markupsetuplqdefault \markupsetuprqdefault - \let\b = \strong - \let\i = \smartitalic - % in principle, all other definitions in \tex have to be undone too. -} +% If a .fmt file is being used, characters that might appear in a file +% name cannot be active until we have parsed the command line. +% So turn them off again, and have \everyjob (or @setfilename) turn them on. +% \otherifyactive is called near the end of this file. +\def\otherifyactive{\catcode`+=\other \catcode`\_=\other} % Used sometimes to turn off (effectively) the active characters even after % parsing them. @@ -11578,132 +9204,68 @@ directory should work if nowhere else does.} % \doublebackslash is two of them (for the pdf outlines). {\catcode`\\=\other @gdef@realbackslash{\} @gdef@doublebackslash{\\}} -% In Texinfo, backslash is an active character; it prints the backslash +% In texinfo, backslash is an active character; it prints the backslash % in fixed width font. -\catcode`\\=\active % @ for escape char from now on. - -% Print a typewriter backslash. For math mode, we can't simply use -% \backslashcurfont: the story here is that in math mode, the \char -% of \backslashcurfont ends up printing the roman \ from the math symbol -% font (because \char in math mode uses the \mathcode, and plain.tex -% sets \mathcode`\\="026E). Hence we use an explicit \mathchar, -% which is the decimal equivalent of "715c (class 7, e.g., use \fam; -% ignored family value; char position "5C). We can't use " for the -% usual hex value because it has already been made active. - -@def@ttbackslash{{@tt @ifmmode @mathchar29020 @else @backslashcurfont @fi}} -@let@backslashchar = @ttbackslash % @backslashchar{} is for user documents. +\catcode`\\=\active +@def@normalbackslash{{@tt@backslashcurfont}} +% On startup, @fixbackslash assigns: +% @let \ = @normalbackslash % \rawbackslash defines an active \ to do \backslashcurfont. % \otherbackslash defines an active \ to be a literal `\' character with -% catcode other. We switch back and forth between these. +% catcode other. @gdef@rawbackslash{@let\=@backslashcurfont} @gdef@otherbackslash{@let\=@realbackslash} % Same as @turnoffactive except outputs \ as {\tt\char`\\} instead of % the literal character `\'. % -{@catcode`- = @active - @gdef@normalturnoffactive{% - @passthroughcharstrue - @let-=@normaldash - @let"=@normaldoublequote - @let$=@normaldollar %$ font-lock fix - @let+=@normalplus - @let<=@normalless - @let>=@normalgreater - @let^=@normalcaret - @let_=@normalunderscore - @let|=@normalverticalbar - @let~=@normaltilde - @let\=@ttbackslash - @markupsetuplqdefault - @markupsetuprqdefault - @unsepspaces - } +@def@normalturnoffactive{% + @let\=@normalbackslash + @let"=@normaldoublequote + @let~=@normaltilde + @let^=@normalcaret + @let_=@normalunderscore + @let|=@normalverticalbar + @let<=@normalless + @let>=@normalgreater + @let+=@normalplus + @let$=@normaldollar %$ font-lock fix + @markupsetuplqdefault + @markupsetuprqdefault + @unsepspaces } -% If a .fmt file is being used, characters that might appear in a file -% name cannot be active until we have parsed the command line. -% So turn them off again, and have @fixbackslash turn them back on. -@catcode`+=@other @catcode`@_=@other +% Make _ and + \other characters, temporarily. +% This is canceled by @fixbackslash. +@otherifyactive -% \enablebackslashhack - allow file to begin `\input texinfo' -% % If a .fmt file is being used, we don't want the `\input texinfo' to show up. % That is what \eatinput is for; after that, the `\' should revert to printing % a backslash. -% If the file did not have a `\input texinfo', then it is turned off after -% the first line; otherwise the first `\' in the file would cause an error. -% This is used on the very last line of this file, texinfo.tex. -% We also use @c to call @fixbackslash, in case ends of lines are hidden. -{ -@catcode`@^=7 -@catcode`@^^M=13@gdef@enablebackslashhack{% - @global@let\ = @eatinput% - @catcode`@^^M=13% - @def@c{@fixbackslash@c}% - % Definition for the newline at the end of this file. - @def ^^M{@let^^M@secondlinenl}% - % Definition for a newline in the main Texinfo file. - @gdef @secondlinenl{@fixbackslash}% - % In case the first line has a whole-line command on it - @let@originalparsearg@parsearg - @def@parsearg{@fixbackslash@originalparsearg} -}} - -{@catcode`@^=7 @catcode`@^^M=13% -@gdef@eatinput input texinfo#1^^M{@fixbackslash}} - -% Emergency active definition of newline, in case an active newline token -% appears by mistake. -{@catcode`@^=7 @catcode13=13% -@gdef@enableemergencynewline{% - @gdef^^M{% - @par% - %@par% -}}} - +% +@gdef@eatinput input texinfo{@fixbackslash} +@global@let\ = @eatinput +% On the other hand, perhaps the file did not have a `\input texinfo'. Then +% the first `\' in the file would cause an error. This macro tries to fix +% that, assuming it is called before the first `\' could plausibly occur. +% Also turn back on active characters that might appear in the input +% file name, in case not using a pre-dumped format. +% @gdef@fixbackslash{% - @ifx\@eatinput @let\ = @ttbackslash @fi - @catcode13=5 % regular end of line - @enableemergencynewline - @let@c=@texinfoc - @let@parsearg@originalparsearg - % Also turn back on active characters that might appear in the input - % file name, in case not using a pre-dumped format. + @ifx\@eatinput @let\ = @normalbackslash @fi @catcode`+=@active @catcode`@_=@active - % - % If texinfo.cnf is present on the system, read it. - % Useful for site-wide @afourpaper, etc. This macro, @fixbackslash, gets - % called at the beginning of every Texinfo file. Not opening texinfo.cnf - % directly in this file, texinfo.tex, makes it possible to make a format - % file for Texinfo. - % - @openin 1 texinfo.cnf - @ifeof 1 @else @input texinfo.cnf @fi - @closein 1 } - % Say @foo, not \foo, in error messages. @escapechar = `@@ -% These (along with & and #) are made active for url-breaking, so need -% active definitions as the normal characters. -@def@normaldot{.} -@def@normalquest{?} -@def@normalslash{/} - % These look ok in all fonts, so just make them not special. -% @hashchar{} gets its own user-level command, because of #line. -@catcode`@& = @other @def@normalamp{&} -@catcode`@# = @other @def@normalhash{#} -@catcode`@% = @other @def@normalpercent{%} - -@let @hashchar = @normalhash +@catcode`@& = @other +@catcode`@# = @other +@catcode`@% = @other @c Finally, make ` and ' active, so that txicodequoteundirected and @c txicodequotebacktick work right in, e.g., @w{@code{`foo'}}. If we @@ -11716,7 +9278,7 @@ directory should work if nowhere else does.} @c Local variables: @c eval: (add-hook 'write-file-hooks 'time-stamp) -@c page-delimiter: "^\\\\message\\|emacs-page" +@c page-delimiter: "^\\\\message" @c time-stamp-start: "def\\\\texinfoversion{" @c time-stamp-format: "%:y-%02m-%02d.%02H" @c time-stamp-end: "}" @@ -11724,4 +9286,6 @@ directory should work if nowhere else does.} @c vim:sw=2: -@enablebackslashhack +@ignore + arch-tag: e1b36e32-c96e-4135-a41a-0b2efa2ea115 +@end ignore diff --git a/doc/tinc-gui.8.in b/doc/tinc-gui.8.in new file mode 100644 index 0000000..f5ebadb --- /dev/null +++ b/doc/tinc-gui.8.in @@ -0,0 +1,57 @@ +.Dd 2011-06-26 +.Dt TINC-GUI 8 +.\" Manual page created by: +.\" Guus Sliepen +.Sh NAME +.Nm tinc-gui +.Nd tinc GUI +.Sh SYNOPSIS +.Nm +.Op Fl n +.Op Fl -net Ns = Ns Ar NETNAME +.Op Fl -pidfile Ns = Ns Ar FILENAME +.Op Fl -help +.Sh DESCRIPTION +This is a Python/wxWidgets based graphical user interface for tinc, a secure virtual private network (VPN) project. +.Nm +communicates with +.Xr tincd 8 +to alter and inspect the running VPN's state. +It can show the current settings, the list of connections, nodes, subnets, and edges. +For now, the debug level can be changed from the GUI, and by right-clicking on a node in the list of connections, +a pop-up menu will appear that allows one to disconnect that node. +.Sh OPTIONS +.Bl -tag -width indent +.It Fl n, -net Ns = Ns Ar NETNAME +Communicate with tincd(8) connected with +.Ar NETNAME . +.It Fl -pidfile Ns = Ns Ar FILENAME +Use the cookie from +.Ar FILENAME +to authenticate with a running tinc daemon. +If unspecified, the default is +.Pa @localstatedir@/run/tinc. Ns Ar NETNAME Ns Pa .pid. +.It Fl -help +Display short list of options. +.El +.Sh BUGS +The GUI is not finished yet, the final version will have much more functionality. +If you find any bugs, report them to tinc@tinc-vpn.org. +.Sh SEE ALSO +.Xr tincd 8 , +.Pa http://www.tinc-vpn.org/ . +.Pp +The full documentation for tinc is maintained as a Texinfo manual. +If the info and tinc programs are properly installed at your site, +the command +.Ic info tinc +should give you access to the complete manual. +.Pp +tinc comes with ABSOLUTELY NO WARRANTY. +This is free software, and you are welcome to redistribute it under certain conditions; +see the file COPYING for details. +.Sh AUTHORS +.An "Ivo Timmermans" +.An "Guus Sliepen" Aq guus@tinc-vpn.org +.Pp +And thanks to many others for their contributions to tinc! diff --git a/doc/tinc.conf.5.in b/doc/tinc.conf.5.in index cd7d1a0..a44f27c 100644 --- a/doc/tinc.conf.5.in +++ b/doc/tinc.conf.5.in @@ -1,21 +1,25 @@ -.Dd 2016-10-29 +.Dd 2010-01-16 .Dt TINC.CONF 5 .\" Manual page created by: .\" Ivo Timmermans .\" Guus Sliepen + .Sh NAME .Nm tinc.conf .Nd tinc daemon configuration + .Sh DESCRIPTION The files in the .Pa @sysconfdir@/tinc/ directory contain runtime and security information for the tinc daemon. + .Sh NETWORKS It is perfectly ok for you to run more than one tinc daemon. However, in its default form, you will soon notice that you can't use two different configuration files without the .Fl c option. + .Pp We have thought of another way of dealing with this: network names. This means that you call @@ -23,6 +27,7 @@ This means that you call with the .Fl n option, which will assign a name to this daemon. + .Pp The effect of this is that the daemon will set its configuration root to .Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa / , @@ -33,6 +38,7 @@ is your argument to the option. You'll notice that messages appear in syslog as coming from .Nm tincd. Ns Ar NETNAME . + .Pp However, it is not strictly necessary that you call tinc with the .Fl n @@ -48,21 +54,25 @@ the configuration file should be .Pa @sysconfdir@/tinc/tinc.conf , and the host configuration files are now expected to be in .Pa @sysconfdir@/tinc/hosts/ . + .Pp But it is highly recommended that you use this feature of .Nm tinc , because it will be so much clearer whom your daemon talks to. Hence, we will assume that you use it. + .Sh NAMES -Each tinc daemon must have a name that is unique in the network which it will be part of. +Each tinc daemon should have a name that is unique in the network which it will be part of. The name will be used by other tinc daemons for identification. The name has to be declared in the .Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /tinc.conf file. + .Pp To make things easy, choose something that will give unique and easy to remember names to your tinc daemon(s). You could try things like hostnames, owner surnames or location names. + .Sh PUBLIC/PRIVATE KEYS You should use .Ic tincd -K @@ -81,14 +91,17 @@ The public key should be stored in the host configuration file .Va NAME stands for the name of the local tinc daemon (see .Sx NAMES ) . + .Sh SERVER CONFIGURATION The server configuration of the daemon is done in the file .Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /tinc.conf . This file consists of comments (lines started with a .Li # ) or assignments in the form of: + .Pp .Va Variable Li = Ar Value . + .Pp The variable names are case insensitive, and any spaces, tabs, newlines and carriage returns are ignored. @@ -96,67 +109,44 @@ Note: it is not required that you put in the .Li = sign, but doing so improves readability. If you leave it out, remember to replace it with at least one space character. + .Pp The server configuration is complemented with host specific configuration (see the next section). Although all configuration options for the local host listed in this document can also be put in .Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /tinc.conf , it is recommended to put host specific configuration options in the host configuration file, as this makes it easy to exchange with other nodes. + .Pp Here are all valid variables, listed in alphabetical order. The default value is given between parentheses. .Bl -tag -width indent + .It Va AddressFamily Li = ipv4 | ipv6 | any Pq any This option affects the address family of listening and outgoing sockets. If .Qq any is selected, then depending on the operating system both IPv4 and IPv6 or just IPv6 listening sockets will be created. -.It Va BindToAddress Li = Ar address Oo Ar port Oc Bq experimental + +.It Va BindToAddress Li = Ar address Bq experimental If your computer has more than one IPv4 or IPv6 address, .Nm tinc will by default listen on all of them for incoming connections. -Multiple -.Va BindToAddress -variables may be specified, -in which case listening sockets for each specified address are made. -.Pp -If no -.Ar port -is specified, the socket will be bound to the port specified by the -.Va Port -option, or to port 655 if neither is given. -To only bind to a specific port but not to a specific address, use -.Li * -for the -.Ar address . +It is possible to bind only to a single address with this variable. + .Pp This option may not work on all platforms. + .It Va BindToInterface Li = Ar interface Bq experimental If your computer has more than one network interface, .Nm tinc will by default listen on all of them for incoming connections. It is possible to bind only to a single interface with this variable. + .Pp This option may not work on all platforms. -Also, on some platforms it will not actually bind to an interface, -but rather to the address that the interface has at the moment a socket is created. -.It Va Broadcast Li = no | mst | direct Po mst Pc Bq experimental -This option selects the way broadcast packets are sent to other daemons. -NOTE: all nodes in a VPN must use the same -.Va Broadcast -mode, otherwise routing loops can form. -.Bl -tag -width indent -.It no -Broadcast packets are never sent to other nodes. -.It mst -Broadcast packets are sent and forwarded via the VPN's Minimum Spanning Tree. -This ensures broadcast packets reach all nodes. -.It direct -Broadcast packets are sent directly to all nodes that can be reached directly. -Broadcast packets received from other nodes are never forwarded. -If the IndirectData option is also set, broadcast packets will only be sent to nodes which we have a meta connection to. -.El + .It Va ConnectTo Li = Ar name Specifies which other tinc daemon to connect to on startup. Multiple @@ -167,21 +157,14 @@ The names should be known to this tinc daemon (i.e., there should be a host configuration file for the name on the .Va ConnectTo line). + .Pp If you don't specify a host with .Va ConnectTo , .Nm tinc won't try to connect to other daemons at all, and will instead just listen for incoming connections. -.It Va DecrementTTL Li = yes | no Po no Pc Bq experimental -When enabled, -.Nm tinc -will decrement the Time To Live field in IPv4 packets, or the Hop Limit field in IPv6 packets, -before forwarding a received packet to the virtual network device or to another node, -and will drop packets that have a TTL value of zero, -in which case it will send an ICMP Time Exceeded packet back. -.Pp -Do not use this option if you use switch mode and want to use IPv6. + .It Va Device Li = Ar device Po Pa /dev/tap0 , Pa /dev/net/tun No or other depending on platform Pc The virtual network device to use. .Nm tinc @@ -193,92 +176,77 @@ instead of .Va Device . The info pages of the tinc package contain more information about configuring the virtual network device. -.It Va DeviceType Li = Ar type Pq platform dependent + +.It Va DeviceType Li = tun | tunnohead | tunifhead | tap Po only supported on BSD platforms Pc The type of the virtual network device. -Tinc will normally automatically select the right type of tun/tap interface, and this option should not be used. -However, this option can be used to select one of the special interface types, if support for them is compiled in. +Tinc will normally automatically select the right type, and this option should not be used. +However, in case tinc does not seem to correctly interpret packets received from the virtual network device, +using this option might help. .Bl -tag -width indent -.It dummy -Use a dummy interface. -No packets are ever read or written to a virtual network device. -Useful for testing, or when setting up a node that only forwards packets for other nodes. -.It raw_socket -Open a raw socket, and bind it to a pre-existing -.Va Interface -(eth0 by default). -All packets are read from this interface. -Packets received for the local node are written to the raw socket. -However, at least on Linux, the operating system does not process IP packets destined for the local host. -.It multicast -Open a multicast UDP socket and bind it to the address and port (separated by spaces) and optionally a TTL value specified using -.Va Device . -Packets are read from and written to this multicast socket. -This can be used to connect to UML, QEMU or KVM instances listening on the same multicast address. -Do NOT connect multiple -.Nm tinc -daemons to the same multicast address, this will very likely cause routing loops. -Also note that this can cause decrypted VPN packets to be sent out on a real network if misconfigured. -.It uml Pq not compiled in by default -Create a UNIX socket with the filename specified by -.Va Device , -or -.Pa @runstatedir@/ Ns Ar NETNAME Ns Pa .umlsocket -if not specified. -.Nm tinc -will wait for a User Mode Linux instance to connect to this socket. -.It vde Pq not compiled in by default -Uses the libvdeplug library to connect to a Virtual Distributed Ethernet switch, -using the UNIX socket specified by -.Va Device , -or -.Pa @runstatedir@/vde.ctl -if not specified. -.El -Also, in case tinc does not seem to correctly interpret packets received from the virtual network device, -it can be used to change the way packets are interpreted: -.Bl -tag -width indent -.It tun Pq BSD and Linux + +.It tun Set type to tun. Depending on the platform, this can either be with or without an address family header (see below). -.It tunnohead Pq BSD + +.It tunnohead Set type to tun without an address family header. Tinc will expect packets read from the virtual network device to start with an IP header. On some platforms IPv6 packets cannot be read from or written to the device in this mode. -.It tunifhead Pq BSD + +.It tunifhead Set type to tun with an address family header. Tinc will expect packets read from the virtual network device to start with a four byte header containing the address family, followed by an IP header. This mode should support both IPv4 and IPv6 packets. -.It utun Pq OS X -Set type to utun. -This is only supported on OS X version 10.6.8 and higher, but doesn't require the tuntaposx module. -This mode should support both IPv4 and IPv6 packets. -.It tap Pq BSD and Linux + +.It tap Set type to tap. 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 ECDSAPrivateKeyFile Li = Ar filename Po Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /ecdsa_key.priv Pc +The file in which the private ECDSA key of this tinc daemon resides. +This is only used if +.Va ExperimentalProtocol +is enabled. + +.It Va ExperimentalProtocol Li = yes | no Po no Pc Bq experimental +When this option is enabled, experimental protocol enhancements will be used. +Ephemeral ECDH will be used for key exchanges, +and ECDSA will be used instead of RSA for authentication. +When enabled, an ECDSA key must have been generated before with +.Nm tincctl generate-ecdsa-keys . +The experimental protocol may change at any time, +and there is no guarantee that tinc will run stable when it is used. + .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 @@ -291,16 +259,20 @@ If starts with a pipe symbol |, then the rest of the filename is interpreted as a shell command that is executed, the graph is then sent to stdin. + .It Va Hostnames Li = yes | no Pq no This option selects whether IP addresses (both real and on the VPN) should be resolved. Since DNS lookups are blocking, it might affect tinc's efficiency, even stopping the daemon for a few seconds every time it does a lookup if your DNS server is not responding. + .Pp This does not affect resolving hostnames to IP addresses from the -host configuration files, but whether hostnames should be resolved while logging. +host configuration files. + .It Va IffOneQueue Li = yes | no Po no Pc Bq experimental (Linux only) Set IFF_ONE_QUEUE flag on TUN/TAP devices. + .It Va Interface Li = Ar interface Defines the name of the interface corresponding to the virtual network device. Depending on the operating system and the type of device this may or may not actually set the name of the interface. @@ -308,117 +280,85 @@ Under Windows, this variable is used to select which network interface will be u If you specified a .Va Device , this variable is almost always already correctly set. + .It Va KeyExpire Li = Ar seconds Pq 3600 This option controls the period the encryption keys used to encrypt the data are valid. It is common practice to change keys at regular intervals to make it even harder for crackers, even though it is thought to be nearly impossible to crack a single key. -.It Va LocalDiscovery Li = yes | no Po no Pc Bq experimental -When enabled, -.Nm tinc -will try to detect peers that are on the same local network. -This will allow direct communication using LAN addresses, even if both peers are behind a NAT -and they only ConnectTo a third node outside the NAT, -which normally would prevent the peers from learning each other's LAN address. -.Pp -Currently, local discovery is implemented by sending broadcast packets to the LAN during path MTU discovery. -This feature may not work in all possible situations. + .It Va MACExpire Li = Ar seconds Pq 600 This option controls the amount of time MAC addresses are kept before they are removed. This only has effect when .Va Mode is set to .Qq switch . + .It Va MaxTimeout Li = Ar seconds Pq 900 This is the maximum delay before trying to reconnect to other tinc daemons. + .It Va Mode Li = router | switch | hub Pq router This option selects the way packets are routed to other daemons. .Bl -tag -width indent + .It router In this mode .Va Subnet variables in the host configuration files will be used to form a routing table. Only unicast packets of routable protocols (IPv4 and IPv6) are supported in this mode. + .Pp This is the default mode, and unless you really know you need another mode, don't change it. + .It switch In this mode the MAC addresses of the packets on the VPN will be used to dynamically create a routing table just like an Ethernet switch does. Unicast, multicast and broadcast packets of every protocol that runs over Ethernet are supported in this mode at the cost of frequent broadcast ARP requests and routing table updates. + .Pp This mode is primarily useful if you want to bridge Ethernet segments. + .It hub This mode is almost the same as the switch mode, but instead every packet will be broadcast to the other daemons while no routing table is managed. .El + .It Va Name Li = Ar name Bq required This is the name which identifies this tinc daemon. It must be unique for the virtual private network this daemon will connect to. -The Name may only consist of alphanumeric and underscore characters. -If -.Va Name -starts with a -.Li $ , -then the contents of the environment variable that follows will be used. -In that case, invalid characters will be converted to underscores. -If -.Va Name -is -.Li $HOST , -but no such environment variable exist, the hostname will be read using the gethostname() system call. + .It Va PingInterval Li = Ar seconds Pq 60 The number of seconds of inactivity that .Nm tinc will wait before sending a probe to the other end. + .It Va PingTimeout Li = Ar seconds Pq 5 The number of seconds to wait for a response to pings or to allow meta connections to block. If the other end doesn't respond within this time, the connection is terminated, and the others will be notified of this. + .It Va PriorityInheritance Li = yes | no Po no Pc Bq experimental When this option is enabled the value of the TOS field of tunneled IPv4 packets will be inherited by the UDP packets that are sent out. + .It Va PrivateKey Li = Ar key Bq obsolete The private RSA key of this tinc daemon. It will allow this tinc daemon to authenticate itself to other daemons. + .It Va PrivateKeyFile Li = Ar filename Po Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /rsa_key.priv Pc The file in which the private RSA key of this tinc daemon resides. +Note that there must be exactly one of +.Va PrivateKey +or +.Va PrivateKeyFile +specified in the configuration file. + .It Va ProcessPriority Li = low | normal | high 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 Proxy Li = socks4 | socks5 | http | exec Ar ... Bq experimental -Use a proxy when making outgoing connections. -The following proxy types are currently supported: -.Bl -tag -width indent -.It socks4 Ar address Ar port Op Ar username -Connects to the proxy using the SOCKS version 4 protocol. -Optionally, a -.Ar username -can be supplied which will be passed on to the proxy server. -Only IPv4 connections can be proxied using SOCKS 4. -.It socks5 Ar address Ar port Op Ar username Ar password -Connect to the proxy using the SOCKS version 5 protocol. -If a -.Ar username -and -.Ar password -are given, basic username/password authentication will be used, -otherwise no authentication will be used. -.It http Ar address Ar port -Connects to the proxy and sends a HTTP CONNECT request. -.It exec Ar command -Executes the given -.Ar command -which should set up the outgoing connection. -The environment variables -.Ev NAME , -.Ev NODE , -.Ev REMOTEADDRES -and -.Ev REMOTEPORT -are available. -.El + .It Va ReplayWindow Li = Ar bytes Pq 16 This is the size of the replay tracking window for each remote node, in bytes. The window is a bitfield which tracks 1 packet per bit, so for example @@ -428,30 +368,35 @@ the interaction of replay tracking with underlying real packet loss and/or reordering. Setting this to zero will disable replay tracking completely and pass all traffic, but leaves tinc vulnerable to replay-based attacks on your traffic. + .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. Subnets learned via connections to other nodes and which are not -present in the local host config files are ignored. +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. + .It Va UDPRcvBuf Li = Ar bytes Pq OS default Sets the socket receive buffer size for the UDP socket, in bytes. If unset, the default buffer size will be used by the operating system. + .It Va UDPSndBuf Li = Ar bytes Pq OS default Sets the socket send buffer size for the UDP socket, in bytes. If unset, the default buffer size will be used by the operating system. .El + .Sh HOST CONFIGURATION FILES The host configuration files contain all information needed to establish a connection to those hosts. A host configuration file is also required for the local tinc daemon, it will use it to read in it's listen port, public key and subnets. + .Pp The idea is that these files are portable. You can safely mail your own host configuration file to someone else. @@ -460,7 +405,8 @@ and now his tinc daemon will be able to connect to your tinc daemon. 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 Oo Ar port Oc 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. @@ -468,51 +414,66 @@ Multiple .Va Address variables can be specified, in which case each address will be tried until a working connection has been established. -.It Va Cipher Li = Ar cipher Pq aes-256-cbc + +.It Va Cipher Li = Ar cipher Pq blowfish The symmetric cipher algorithm used to encrypt UDP packets. -Any cipher supported by LibreSSL or OpenSSL is recognised. +Any cipher supported by OpenSSL is recognised. Furthermore, specifying .Qq none 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), 10 (fast lzo) and 11 (best lzo). -.It Va Digest Li = Ar digest Pq sha256 + +.It Va Digest Li = Ar digest Pq sha1 The digest algorithm used to authenticate UDP packets. -Any digest supported by LibreSSL or OpenSSL is recognised. +Any digest supported by OpenSSL is recognised. Furthermore, specifying .Qq none will turn off packet authentication. + .It Va IndirectData Li = yes | no Pq no -When set to yes, only nodes which already have a meta connection to you -will try to establish direct communication with you. -It is best to leave this option out or set it to no. +This option specifies whether other tinc daemons besides the one you specified with +.Va ConnectTo +can make a direct connection to you. +This is especially useful if you are behind a firewall +and it is impossible to make a connection from the outside to your tinc daemon. +Otherwise, it is best to leave this option out or set it to no. + .It Va MACLength Li = Ar length Pq 4 The length of the message authentication code used to authenticate UDP packets. Can be anything from .Qq 0 up to the length of the digest produced by the digest algorithm. + .It Va PMTU Li = Ar mtu Po 1514 Pc This option controls the initial path MTU to this node. + .It Va PMTUDiscovery Li = yes | no Po yes Pc 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, 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. It will be used to cryptographically verify it's identity and to set up a secure connection. + .It Va PublicKeyFile Li = Ar filename Bq obsolete The file in which the public RSA key of this tinc daemon resides. + .Pp From version 1.0pre4 on .Nm tinc @@ -521,6 +482,7 @@ the above two options then are not necessary. Either the PEM format is used, or exactly one of the above two options must be specified in each host configuration file, if you want to be able to establish a connection with that host. + .It Va Subnet Li = Ar address Ns Op Li / Ns Ar prefixlength Ns Op Li # Ns Ar weight The subnet which this tinc daemon will serve. .Nm tinc @@ -530,22 +492,26 @@ it will be sent to the daemon who has this subnet in his host configuration file Multiple .Va Subnet variables can be specified. + .Pp Subnets can either be single MAC, IPv4 or IPv6 addresses, in which case a subnet consisting of only that single address is assumed, or they can be a IPv4 or IPv6 network address with a prefixlength. +Shorthand notations are not supported. For example, IPv4 subnets must be in a form like 192.168.1.0/24, where 192.168.1.0 is the network address and 24 is the number of bits set in the netmask. Note that subnets like 192.168.1.1/24 are invalid! Read a networking HOWTO/FAQ/guide if you don't understand this. -IPv6 subnets are notated like fec0:0:0:1::/64. +IPv6 subnets are notated like fec0:0:0:1:0:0:0:0/64. MAC addresses are notated like 0:1a:2b:3c:4d:5e. + .Pp A Subnet can be given a weight to indicate its priority over identical Subnets owned by different nodes. The default weight is 10. Lower values indicate higher priority. Packets will be sent to the node with the highest priority, unless that node is not reachable, in which case the node with the next highest priority will be tried, and so on. + .It Va TCPOnly Li = yes | no Pq no Bq obsolete If this variable is set to yes, then the packets are tunnelled over the TCP connection instead of a UDP connection. @@ -553,51 +519,53 @@ This is especially useful for those who want to run a tinc daemon from behind a masquerading firewall, or if UDP packet routing is disabled somehow. Setting this options also implicitly sets IndirectData. + .Pp Since version 1.0.10, tinc will automatically detect whether communication via UDP is possible or not. .El + .Sh SCRIPTS Apart from reading the server and host configuration files, tinc can also run scripts at certain moments. -Below is a list of filenames of scripts and a description of when they are run. -A script is only run if it exists and if it is executable. -.Pp -Scripts are run synchronously; -this means that tinc will temporarily stop processing packets until the called script finishes executing. -This guarantees that scripts will execute in the exact same order as the events that trigger them. -If you need to run commands asynchronously, you have to ensure yourself that they are being run in the background. -.Pp -Under Windows (not Cygwin), the scripts must have the extension +Under Windows (not Cygwin), the scripts should have the extension .Pa .bat . .Bl -tag -width indent + .It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /tinc-up This is the most important script. If it is present it will be executed right after the tinc daemon has been started and has connected to the virtual network device. It should be used to set up the corresponding network interface, but can also be used to start other things. -.Pp Under Windows you can use the Network Connections control panel instead of creating this script. + .It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /tinc-down This script is started right before the tinc daemon quits. + .It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /hosts/ Ns Ar HOST Ns Pa -up This script is started when the tinc daemon with name .Ar HOST becomes reachable. + .It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /hosts/ Ns Ar HOST Ns Pa -down This script is started when the tinc daemon with name .Ar HOST becomes unreachable. + .It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /host-up This script is started when any host becomes reachable. + .It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /host-down This script is started when any host becomes unreachable. + .It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /subnet-up This script is started when a Subnet becomes reachable. The Subnet and the node it belongs to are passed in environment variables. + .It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /subnet-down This script is started when a Subnet becomes unreachable. .El + .Pp The scripts are started without command line arguments, but can make use of certain environment variables. Under UNIX like operating systems the names of environment variables must be preceded by a @@ -609,56 +577,68 @@ files, they have to be put between .Li % signs. .Bl -tag -width indent + .It Ev NETNAME If a netname was specified, this environment variable contains it. + .It Ev NAME Contains the name of this tinc daemon. + .It Ev DEVICE Contains the name of the virtual network device that tinc uses. + .It Ev INTERFACE Contains the name of the virtual network interface that tinc uses. This should be used for commands like .Pa ifconfig . + .It Ev NODE When a host becomes (un)reachable, this is set to its name. If a subnet becomes (un)reachable, this is set to the owner of that subnet. + .It Ev REMOTEADDRESS When a host becomes (un)reachable, this is set to its real address. + .It Ev REMOTEPORT When a host becomes (un)reachable, this is set to the port number it uses for communication with other tinc daemons. + .It Ev SUBNET When a subnet becomes (un)reachable, this is set to the subnet. + .It Ev WEIGHT When a subnet becomes (un)reachable, this is set to the subnet weight. .El -.Pp -Do not forget that under UNIX operating systems, you have to make the scripts executable, using the command -.Nm chmod Li a+x Pa script . + .Sh FILES The most important files are: .Bl -tag -width indent + .It Pa @sysconfdir@/tinc/ The top directory for configuration files. + .It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /tinc.conf The default name of the server configuration file for net .Ar NETNAME . -.It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /conf.d/ -Optional directory from which any *.conf file will be loaded + .It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /hosts/ Host configuration files are kept in this directory. + .It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /tinc-up If an executable file with this name exists, it will be executed right after the tinc daemon has connected to the virtual network device. It can be used to set up the corresponding network interface. + .It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /tinc-down If an executable file with this name exists, it will be executed right before the tinc daemon is going to close its connection to the virtual network device. .El + .Sh SEE ALSO .Xr tincd 8 , -.Pa https://www.tinc-vpn.org/ , -.Pa http://www.tldp.org/LDP/nag2/ . +.Pa http://www.tinc-vpn.org/ , +.Pa http://www.linuxdoc.org/LDP/nag2/ . + .Pp The full documentation for .Nm tinc @@ -666,6 +646,7 @@ is maintained as a Texinfo manual. If the info and tinc programs are properly installed at your site, the command .Ic info tinc should give you access to the complete manual. + .Pp .Nm tinc comes with ABSOLUTELY NO WARRANTY. diff --git a/doc/tinc.info b/doc/tinc.info index 97caea4..f6c0548 100644 --- a/doc/tinc.info +++ b/doc/tinc.info @@ -1,14 +1,14 @@ -This is tinc.info, produced by makeinfo version 6.5 from tinc.texi. +This is tinc.info, produced by makeinfo version 4.13 from tinc.texi. INFO-DIR-SECTION Networking tools START-INFO-DIR-ENTRY * tinc: (tinc). The tinc Manual. END-INFO-DIR-ENTRY -This is the info manual for tinc version 1.0.35, a Virtual Private + This is the info manual for tinc version 1.1pre2, a Virtual Private Network daemon. - Copyright (C) 1998-2018 Ivo Timmermans, Guus Sliepen + Copyright (C) 1998-2011 Ivo Timmermans, Guus Sliepen and Wessel Dankers . Permission is granted to make and distribute verbatim copies of this @@ -33,6 +33,7 @@ Top * Installation:: * Configuration:: * Running tinc:: +* Controlling tinc:: * Technical information:: * Platform specific information:: * About us:: @@ -73,12 +74,12 @@ A Virtual Private Network or VPN is a network that can only be accessed by a few elected computers that participate. This goal is achievable in more than just one way. - Private networks can consist of a single stand-alone Ethernet LAN. Or -even two computers hooked up using a null-modem cable. In these cases, -it is obvious that the network is _private_, no one can access it from -the outside. But if your computers are linked to the Internet, the -network is not private anymore, unless one uses firewalls to block all -private traffic. But then, there is no way to send private data to + Private networks can consist of a single stand-alone Ethernet LAN. +Or even two computers hooked up using a null-modem cable. In these +cases, it is obvious that the network is _private_, no one can access +it from the outside. But if your computers are linked to the Internet, +the network is not private anymore, unless one uses firewalls to block +all private traffic. But then, there is no way to send private data to trusted computers on the other end of the Internet. This problem can be solved by using _virtual_ networks. Virtual @@ -93,10 +94,10 @@ has to go through the Internet, where other people can look at it. worse, alter data. Hence it's probably advisable to encrypt the data that flows over the network. - When one introduces encryption, we can form a true VPN. Other people -may see encrypted traffic, but if they don't know how to decipher it -(they need to know the key for that), they cannot read the information -that flows through the VPN. This is what tinc was made for. + When one introduces encryption, we can form a true VPN. Other +people may see encrypted traffic, but if they don't know how to +decipher it (they need to know the key for that), they cannot read the +information that flows through the VPN. This is what tinc was made for.  File: tinc.info, Node: tinc, Next: Supported platforms, Prev: Virtual Private Networks, Up: Introduction @@ -107,8 +108,8 @@ File: tinc.info, Node: tinc, Next: Supported platforms, Prev: Virtual Private I really don't quite remember what got us started, but it must have been Guus' idea. He wrote a simple implementation (about 50 lines of C) that used the ethertap device that Linux knows of since somewhere about -kernel 2.1.60. It didn't work immediately and he improved it a bit. At -this stage, the project was still simply called "vpnd". +kernel 2.1.60. It didn't work immediately and he improved it a bit. +At this stage, the project was still simply called "vpnd". Since then, a lot has changed--to say the least. @@ -117,14 +118,14 @@ for both the receiving and sending end, it has become largely runtime-configurable--in short, it has become a full-fledged professional package. - Tinc also allows more than two sites to connect to eachother and form -a single VPN. Traditionally VPNs are created by making tunnels, which -only have two endpoints. Larger VPNs with more sites are created by -adding more tunnels. Tinc takes another approach: only endpoints are -specified, the software itself will take care of creating the tunnels. -This allows for easier configuration and improved scalability. + Tinc also allows more than two sites to connect to eachother and +form a single VPN. Traditionally VPNs are created by making tunnels, +which only have two endpoints. Larger VPNs with more sites are created +by adding more tunnels. Tinc takes another approach: only endpoints +are specified, the software itself will take care of creating the +tunnels. This allows for easier configuration and improved scalability. - A lot can--and will be--changed. We have a number of things that we + A lot can--and will be--changed. We have a number of things that we would like to see in the future releases of tinc. Not everything will be available in the near future. Our first objective is to make tinc work perfectly as it stands, and then add more advanced features. @@ -139,7 +140,7 @@ File: tinc.info, Node: Supported platforms, Prev: tinc, Up: Introduction ======================= Tinc has been verified to work under Linux, FreeBSD, OpenBSD, NetBSD, -Mac OS X (Darwin), Solaris, and Windows (both natively and in a Cygwin +MacOS/X (Darwin), Solaris, and Windows (both natively and in a Cygwin environment), with various hardware architectures. These are some of the platforms that are supported by the universal tun/tap device driver or other virtual network device drivers. Without such a driver, tinc @@ -147,7 +148,7 @@ will most likely compile and run, but it will not be able to send or receive data packets. For an up to date list of supported platforms, please check the list -on our website: . +on our website: `http://www.tinc-vpn.org/platforms'.  File: tinc.info, Node: Preparations, Next: Installation, Prev: Introduction, Up: Top @@ -176,7 +177,7 @@ File: tinc.info, Node: Configuring the kernel, Next: Libraries, Up: Preparati * Configuration of OpenBSD kernels:: * Configuration of NetBSD kernels:: * Configuration of Solaris kernels:: -* Configuration of Darwin (Mac OS X) kernels:: +* Configuration of Darwin (MacOS/X) kernels:: * Configuration of Windows::  @@ -198,7 +199,7 @@ Here are the options you have to turn on when configuring a new kernel: are going to run more than one instance of tinc. If you decide to build the tun/tap driver as a kernel module, add -these lines to '/etc/modules.conf': +these lines to `/etc/modules.conf': alias char-major-10-200 tun @@ -209,9 +210,7 @@ File: tinc.info, Node: Configuration of FreeBSD kernels, Next: Configuration o -------------------------------------- For FreeBSD version 4.1 and higher, tun and tap drivers are included in -the default kernel configuration. The tap driver can be loaded with -'kldload if_tap', or by adding 'if_tap_load="YES"' to -'/boot/loader.conf'. +the default kernel configuration. Using tap devices is recommended.  File: tinc.info, Node: Configuration of OpenBSD kernels, Next: Configuration of NetBSD kernels, Prev: Configuration of FreeBSD kernels, Up: Configuring the kernel @@ -219,8 +218,12 @@ File: tinc.info, Node: Configuration of OpenBSD kernels, Next: Configuration o 2.1.3 Configuration of OpenBSD kernels -------------------------------------- -Recent versions of OpenBSD come with both tun and tap devices enabled in -the default kernel configuration. +For OpenBSD version 2.9 and higher, the tun driver is included in the +default kernel configuration. There is also a kernel patch from +`http://diehard.n-r-g.com/stuff/openbsd/' which adds a tap device to +OpenBSD which should work with tinc, but with recent versions of +OpenBSD, a tun device can act as a tap device by setting the link0 +option with ifconfig.  File: tinc.info, Node: Configuration of NetBSD kernels, Next: Configuration of Solaris kernels, Prev: Configuration of OpenBSD kernels, Up: Configuring the kernel @@ -234,44 +237,42 @@ default kernel configuration. Tunneling IPv6 may not work on NetBSD's tun device.  -File: tinc.info, Node: Configuration of Solaris kernels, Next: Configuration of Darwin (Mac OS X) kernels, Prev: Configuration of NetBSD kernels, Up: Configuring the kernel +File: tinc.info, Node: Configuration of Solaris kernels, Next: Configuration of Darwin (MacOS/X) kernels, Prev: Configuration of NetBSD kernels, Up: Configuring the kernel 2.1.5 Configuration of Solaris kernels -------------------------------------- For Solaris 8 (SunOS 5.8) and higher, the tun driver may or may not be included in the default kernel configuration. If it isn't, the source -can be downloaded from . For x86 and +can be downloaded from `http://vtun.sourceforge.net/tun/'. For x86 and sparc64 architectures, precompiled versions can be found at -. If the 'net/if_tun.h' +`http://www.monkey.org/~dugsong/fragroute/'. If the `net/if_tun.h' header file is missing, install it from the source package.  -File: tinc.info, Node: Configuration of Darwin (Mac OS X) kernels, Next: Configuration of Windows, Prev: Configuration of Solaris kernels, Up: Configuring the kernel +File: tinc.info, Node: Configuration of Darwin (MacOS/X) kernels, Next: Configuration of Windows, Prev: Configuration of Solaris kernels, Up: Configuring the kernel -2.1.6 Configuration of Darwin (Mac OS X) kernels ------------------------------------------------- +2.1.6 Configuration of Darwin (MacOS/X) kernels +----------------------------------------------- Tinc on Darwin relies on a tunnel driver for its data acquisition from -the kernel. OS X version 10.6.8 and later have a built-in tun driver -called "utun". Tinc also supports the driver from -, which supports both tun and tap -style devices. +the kernel. Tinc supports either the driver from +`http://tuntaposx.sourceforge.net/', which supports both tun and tap +style devices, and also the driver from from +`http://chrisp.de/en/projects/tunnel.html'. The former driver is +recommended. The tunnel driver must be loaded before starting tinc +with the following command: - By default, tinc expects the tuntaposx driver to be installed. To -use the utun driver, set add 'Device = utunX' to 'tinc.conf', where X is -the desired number for the utun interface. You can also omit the -number, in which case the first free number will be chosen. + kmodload tunnel  -File: tinc.info, Node: Configuration of Windows, Prev: Configuration of Darwin (Mac OS X) kernels, Up: Configuring the kernel +File: tinc.info, Node: Configuration of Windows, Prev: Configuration of Darwin (MacOS/X) kernels, Up: Configuring the kernel 2.1.7 Configuration of Windows ------------------------------ -You will need to install the latest TAP-Win32 driver from OpenVPN. You -can download it from -. Using the +You will need to install the latest TAP-Win32 driver from OpenVPN. You +can download it from `http://openvpn.sourceforge.net'. Using the Network Connections control panel, configure the TAP-Win32 network interface in the same way as you would do from the tinc-up script, as explained in the rest of the documentation. @@ -282,50 +283,49 @@ File: tinc.info, Node: Libraries, Prev: Configuring the kernel, Up: Preparati 2.2 Libraries ============= -Before you can configure or build tinc, you need to have the LibreSSL or -OpenSSL, zlib and lzo libraries installed on your system. If you try to -configure tinc without having them installed, configure will give you an -error message, and stop. +Before you can configure or build tinc, you need to have the OpenSSL, +zlib and lzo libraries installed on your system. If you try to +configure tinc without having them installed, configure will give you +an error message, and stop. * Menu: -* LibreSSL/OpenSSL:: +* OpenSSL:: * zlib:: * lzo:: +* libevent::  -File: tinc.info, Node: LibreSSL/OpenSSL, Next: zlib, Up: Libraries +File: tinc.info, Node: OpenSSL, Next: zlib, Up: Libraries -2.2.1 LibreSSL/OpenSSL ----------------------- +2.2.1 OpenSSL +------------- For all cryptography-related functions, tinc uses the functions provided -by the LibreSSL or the OpenSSL library. +by the OpenSSL library. - If this library is not installed, you will get an error when -configuring tinc for build. Support for running tinc with other -cryptographic libraries installed _may_ be added in the future. + If this library is not installed, you wil get an error when +configuring tinc for build. Support for running tinc without having +OpenSSL installed _may_ be added in the future. You can use your operating system's package manager to install this if available. Make sure you install the development AND runtime versions of this package. - If your operating system comes neither with LibreSSL or OpenSSL, you -have to install one manually. It is recommended that you get the latest -version of LibreSSL from . Instructions on -how to configure, build and install this package are included within the -package. Please make sure you build development and runtime libraries -(which is the default). + If you have to install OpenSSL manually, you can get the source code +from `http://www.openssl.org/'. Instructions on how to configure, +build and install this package are included within the package. Please +make sure you build development and runtime libraries (which is the +default). - If you installed the LibreSSL or OpenSSL libraries from source, it -may be necessary to let configure know where they are, by passing -configure one of the -with-openssl-* parameters. Note that you even -have to use -with-openssl-* if you are using LibreSSL. + If you installed the OpenSSL libraries from source, it may be +necessary to let configure know where they are, by passing configure +one of the -with-openssl-* parameters. - --with-openssl=DIR LibreSSL/OpenSSL library and headers prefix - --with-openssl-include=DIR LibreSSL/OpenSSL headers directory + --with-openssl=DIR OpenSSL library and headers prefix + --with-openssl-include=DIR OpenSSL headers directory (Default is OPENSSL_DIR/include) - --with-openssl-lib=DIR LibreSSL/OpenSSL library directory + --with-openssl-lib=DIR OpenSSL library directory (Default is OPENSSL_DIR/lib) License @@ -334,26 +334,26 @@ License The complete source code of tinc is covered by the GNU GPL version 2. Since the license under which OpenSSL is distributed is not directly compatible with the terms of the GNU GPL -, we include an +`http://www.openssl.org/support/faq.html#LEGAL2', we include an exemption to the GPL (see also the file COPYING.README) to allow everyone to create a statically or dynamically linked executable: This program is released under the GPL with the additional - exemption that compiling, linking, and/or using OpenSSL is allowed. - You may provide binary packages linked to the OpenSSL libraries, - provided that all other requirements of the GPL are met. + exemption that compiling, linking, and/or using OpenSSL is + allowed. You may provide binary packages linked to the OpenSSL + libraries, provided that all other requirements of the GPL are met. Since the LZO library used by tinc is also covered by the GPL, we also present the following exemption: Hereby I grant a special exception to the tinc VPN project - (https://www.tinc-vpn.org/) to link the LZO library with the - OpenSSL library (https://www.openssl.org). + (http://www.tinc-vpn.org/) to link the LZO library with the + OpenSSL library (http://www.openssl.org). Markus F.X.J. Oberhumer  -File: tinc.info, Node: zlib, Next: lzo, Prev: LibreSSL/OpenSSL, Up: Libraries +File: tinc.info, Node: zlib, Next: lzo, Prev: OpenSSL, Up: Libraries 2.2.2 zlib ---------- @@ -361,43 +361,59 @@ File: tinc.info, Node: zlib, Next: lzo, Prev: LibreSSL/OpenSSL, Up: Librarie For the optional compression of UDP packets, tinc uses the functions provided by the zlib library. - If this library is not installed, you will get an error when running -the configure script. You can either install the zlib library, or -disable support for zlib compression by using the "-disable-zlib" option -when running the configure script. Note that if you disable support for -zlib, the resulting binary will not work correctly on VPNs where zlib -compression is used. + If this library is not installed, you wil get an error when +configuring tinc for build. Support for running tinc without having +zlib installed _may_ be added in the future. You can use your operating system's package manager to install this if available. Make sure you install the development AND runtime versions of this package. If you have to install zlib manually, you can get the source code -from . Instructions on how to configure, build and -install this package are included within the package. Please make sure -you build development and runtime libraries (which is the default). +from `http://www.gzip.org/zlib/'. Instructions on how to configure, +build and install this package are included within the package. Please +make sure you build development and runtime libraries (which is the +default).  -File: tinc.info, Node: lzo, Prev: zlib, Up: Libraries +File: tinc.info, Node: lzo, Next: libevent, Prev: zlib, Up: Libraries 2.2.3 lzo --------- -Another form of compression is offered using the LZO library. +Another form of compression is offered using the lzo library. - If this library is not installed, you will get an error when running -the configure script. You can either install the LZO library, or -disable support for LZO compression by using the "-disable-lzo" option -when running the configure script. Note that if you disable support for -LZO, the resulting binary will not work correctly on VPNs where LZO -compression is used. + If this library is not installed, you wil get an error when +configuring tinc for build. Support for running tinc without having lzo +installed _may_ be added in the future. You can use your operating system's package manager to install this if available. Make sure you install the development AND runtime versions of this package. - If you have to install lzo manually, you can get the source code from -. Instructions on how to + If you have to install lzo manually, you can get the source code +from `http://www.oberhumer.com/opensource/lzo/'. Instructions on how +to configure, build and install this package are included within the +package. Please make sure you build development and runtime libraries +(which is the default). + + +File: tinc.info, Node: libevent, Prev: lzo, Up: Libraries + +2.2.4 libevent +-------------- + +For the main event loop, tinc uses the libevent library. + + If this library is not installed, you wil get an error when +configuring tinc for build. + + You can use your operating system's package manager to install this +if available. Make sure you install the development AND runtime +versions of this package. + + If you have to install libevent manually, you can get the source code +from `http://monkey.org/~provos/libevent/'. Instructions on how to configure, build and install this package are included within the package. Please make sure you build development and runtime libraries (which is the default). @@ -414,13 +430,15 @@ startup scripts and sample configurations. If you cannot use one of the precompiled packages, or you want to compile tinc for yourself, you can use the source. The source is -distributed under the GNU General Public License (GPL). Download the -source from the download page (https://www.tinc-vpn.org/download/). +distributed under the GNU General Public License (GPL). Download the +source from the download page (http://www.tinc-vpn.org/download), which +has the checksums of these files listed; you may wish to check these +with md5sum before continuing. Tinc comes in a convenient autoconf/automake package, which you can just treat the same as any other package. Which is just untar it, type -'./configure' and then 'make'. More detailed instructions are in the -file 'INSTALL', which is included in the source distribution. +`./configure' and then `make'. More detailed instructions are in the +file `INSTALL', which is included in the source distribution. * Menu: @@ -434,7 +452,7 @@ File: tinc.info, Node: Building and installing tinc, Next: System files, Up: ================================ Detailed instructions on configuring the source, building tinc and -installing tinc can be found in the file called 'INSTALL'. +installing tinc can be found in the file called `INSTALL'. If you happen to have a binary package for tinc for your distribution, you can use the package management tools of that @@ -443,36 +461,36 @@ your distribution will tell you how to do that. * Menu: -* Darwin (Mac OS X) build environment:: +* Darwin (MacOS/X) build environment:: * Cygwin (Windows) build environment:: * MinGW (Windows) build environment::  -File: tinc.info, Node: Darwin (Mac OS X) build environment, Next: Cygwin (Windows) build environment, Up: Building and installing tinc +File: tinc.info, Node: Darwin (MacOS/X) build environment, Next: Cygwin (Windows) build environment, Up: Building and installing tinc -3.1.1 Darwin (Mac OS X) build environment ------------------------------------------ +3.1.1 Darwin (MacOS/X) build environment +---------------------------------------- -In order to build tinc on Darwin, you need to install Xcode from -. It might also help to install a -recent version of Fink from . +In order to build tinc on Darwin, you need to install the MacOS/X +Developer Tools from +`http://developer.apple.com/tools/macosxtools.html' and a recent +version of Fink from `http://fink.sourceforge.net/'. - You need to download and install LibreSSL (or OpenSSL) and LZO, -either directly from their websites (see *note Libraries::) or using -Fink. + After installation use fink to download and install the following +packages: autoconf25, automake, dlcompat, m4, openssl, zlib and lzo.  -File: tinc.info, Node: Cygwin (Windows) build environment, Next: MinGW (Windows) build environment, Prev: Darwin (Mac OS X) build environment, Up: Building and installing tinc +File: tinc.info, Node: Cygwin (Windows) build environment, Next: MinGW (Windows) build environment, Prev: Darwin (MacOS/X) build environment, Up: Building and installing tinc 3.1.2 Cygwin (Windows) build environment ---------------------------------------- If Cygwin hasn't already been installed, install it directly from -. +`http://www.cygwin.com/'. When tinc is compiled in a Cygwin environment, it can only be run in this environment, but all programs, including those started outside the -Cygwin environment, will be able to use the VPN. It will also support +Cygwin environment, will be able to use the VPN. It will also support all features.  @@ -482,8 +500,7 @@ File: tinc.info, Node: MinGW (Windows) build environment, Prev: Cygwin (Window --------------------------------------- You will need to install the MinGW environment from -. You also need to download and install LibreSSL -(or OpenSSL) and LZO. +`http://www.mingw.org'. When tinc is compiled using MinGW it runs natively under Windows, it is not necessary to keep MinGW installed. @@ -525,20 +542,20 @@ File: tinc.info, Node: Other files, Prev: Device files, Up: System files 3.2.2 Other files ----------------- -'/etc/networks' +`/etc/networks' ............... -You may add a line to '/etc/networks' so that your VPN will get a +You may add a line to `/etc/networks' so that your VPN will get a symbolic name. For example: myvpn 10.0.0.0 -'/etc/services' +`/etc/services' ............... -You may add this line to '/etc/services'. The effect is that you may -supply a 'tinc' as a valid port number to some programs. The number 655 -is registered with the IANA. +You may add this line to `/etc/services'. The effect is that you may +supply a `tinc' as a valid port number to some programs. The number +655 is registered with the IANA. tinc 655/tcp TINC tinc 655/udp TINC @@ -570,17 +587,17 @@ Before actually starting to configure tinc and editing files, make sure you have read this entire section so you know what to expect. Then, make it clear to yourself how you want to organize your VPN: What are the nodes (computers running tinc)? What IP addresses/subnets do they -have? What is the network mask of the entire VPN? Do you need special +have? What is the network mask of the entire VPN? Do you need special firewall rules? Do you have to set up masquerading or forwarding rules? Do you want to run tinc in router mode or switch mode? These questions can only be answered by yourself, you will not find the answers in this -documentation. Make sure you have an adequate understanding of networks -in general. A good resource on networking is the Linux Network -Administrators Guide (http://www.tldp.org/LDP/nag2/). +documentation. Make sure you have an adequate understanding of +networks in general. A good resource on networking is the Linux +Network Administrators Guide (http://www.linuxdoc.org/LDP/nag2/). If you have everything clearly pictured in your mind, proceed in the -following order: First, generate the configuration files ('tinc.conf', -your host configuration file, 'tinc-up' and perhaps 'tinc-down'). Then +following order: First, generate the configuration files (`tinc.conf', +your host configuration file, `tinc-up' and perhaps `tinc-down'). Then generate the keypairs. Finally, distribute the host configuration files. These steps are described in the subsections below. @@ -592,28 +609,28 @@ File: tinc.info, Node: Multiple networks, Next: How connections work, Prev: C In order to allow you to run more than one tinc daemon on one computer, for instance if your computer is part of more than one VPN, you can -assign a NETNAME to your VPN. It is not required if you only run one +assign a NETNAME to your VPN. It is not required if you only run one tinc daemon, it doesn't even have to be the same on all the sites of your VPN, but it is recommended that you choose one anyway. - We will assume you use a netname throughout this document. This + We will asume you use a netname throughout this document. This means that you call tincd with the -n argument, which will assign a netname to this daemon. - The effect of this is that the daemon will set its configuration root -to '/etc/tinc/NETNAME/', where NETNAME is your argument to the -n -option. You'll notice that it appears in syslog as 'tinc.NETNAME'. + The effect of this is that the daemon will set its configuration +root to `/etc/tinc/NETNAME/', where NETNAME is your argument to the -n +option. You'll notice that it appears in syslog as `tinc.NETNAME'. However, it is not strictly necessary that you call tinc with the -n option. In this case, the network name would just be empty, and it will -be used as such. tinc now looks for files in '/etc/tinc/', instead of -'/etc/tinc/NETNAME/'; the configuration file should be -'/etc/tinc/tinc.conf', and the host configuration files are now expected -to be in '/etc/tinc/hosts/'. +be used as such. tinc now looks for files in `/etc/tinc/', instead of +`/etc/tinc/NETNAME/'; the configuration file should be +`/etc/tinc/tinc.conf', and the host configuration files are now +expected to be in `/etc/tinc/hosts/'. But it is highly recommended that you use this feature of tinc, -because it will be so much clearer whom your daemon talks to. Hence, we -will assume that you use it. +because it will be so much clearer whom your daemon talks to. Hence, +we will assume that you use it.  File: tinc.info, Node: How connections work, Next: Configuration files, Prev: Multiple networks, Up: Configuration @@ -622,22 +639,22 @@ File: tinc.info, Node: How connections work, Next: Configuration files, Prev: ======================== When tinc starts up, it parses the command-line options and then reads -in the configuration file tinc.conf. If it sees one or more 'ConnectTo' -values pointing to other tinc daemons in that file, it will try to -connect to those other daemons. Whether this succeeds or not and -whether 'ConnectTo' is specified or not, tinc will listen for incoming -connection from other daemons. If you did specify a 'ConnectTo' value -and the other side is not responding, tinc will keep retrying. This -means that once started, tinc will stay running until you tell it to -stop, and failures to connect to other tinc daemons will not stop your -tinc daemon for trying again later. This means you don't have to -intervene if there are temporary network problems. +in the configuration file tinc.conf. If it sees one or more +`ConnectTo' values pointing to other tinc daemons in that file, it will +try to connect to those other daemons. Whether this succeeds or not +and whether `ConnectTo' is specified or not, tinc will listen for +incoming connection from other deamons. If you did specify a +`ConnectTo' value and the other side is not responding, tinc will keep +retrying. This means that once started, tinc will stay running until +you tell it to stop, and failures to connect to other tinc daemons will +not stop your tinc daemon for trying again later. This means you don't +have to intervene if there are temporary network problems. There is no real distinction between a server and a client in tinc. -If you wish, you can view a tinc daemon without a 'ConnectTo' value as a -server, and one which does specify such a value as a client. It does -not matter if two tinc daemons have a 'ConnectTo' value pointing to each -other however. +If you wish, you can view a tinc daemon without a `ConnectTo' value as +a server, and one which does specify such a value as a client. It does +not matter if two tinc daemons have a `ConnectTo' value pointing to +each other however.  File: tinc.info, Node: Configuration files, Next: Generating keypairs, Prev: How connections work, Up: Configuration @@ -646,11 +663,8 @@ File: tinc.info, Node: Configuration files, Next: Generating keypairs, Prev: ======================= The actual configuration of the daemon is done in the file -'/etc/tinc/NETNAME/tinc.conf' and at least one other file in the -directory '/etc/tinc/NETNAME/hosts/'. - - An optional directory '/etc/tinc/NETNAME/conf.d' can be added from -which any .conf file will be read. +`/etc/tinc/NETNAME/tinc.conf' and at least one other file in the +directory `/etc/tinc/NETNAME/hosts/'. These file consists of comments (lines started with a #) or assignments in the form of @@ -659,13 +673,14 @@ assignments in the form of The variable names are case insensitive, and any spaces, tabs, newlines and carriage returns are ignored. Note: it is not required -that you put in the '=' sign, but doing so improves readability. If you -leave it out, remember to replace it with at least one space character. +that you put in the `=' sign, but doing so improves readability. If +you leave it out, remember to replace it with at least one space +character. The server configuration is complemented with host specific -configuration (see the next section). Although all host configuration +configuration (see the next section). Although all host configuration options for the local node listed in this document can also be put in -'/etc/tinc/NETNAME/tinc.conf', it is recommended to put host specific +`/etc/tinc/NETNAME/tinc.conf', it is recommended to put host specific configuration options in the host configuration file, as this makes it easy to exchange with other nodes. @@ -692,47 +707,21 @@ AddressFamily = (any) system both IPv4 and IPv6 or just IPv6 listening sockets will be created. -BindToAddress =
[] [experimental] +BindToAddress =
[experimental] If your computer has more than one IPv4 or IPv6 address, tinc will - by default listen on all of them for incoming connections. - Multiple BindToAddress variables may be specified, in which case - listening sockets for each specified address are made. - - If no PORT is specified, the socket will be bound to the port - specified by the Port option, or to port 655 if neither is given. - To only bind to a specific port but not to a specific address, use - "*" for the ADDRESS. + by default listen on all of them for incoming connections. It is + possible to bind only to a single address with this variable. This option may not work on all platforms. BindToInterface = [experimental] If you have more than one network interface in your computer, tinc - will by default listen on all of them for incoming connections. It - is possible to bind tinc to a single interface like eth0 or ppp0 - with this variable. + will by default listen on all of them for incoming connections. + It is possible to bind tinc to a single interface like eth0 or + ppp0 with this variable. This option may not work on all platforms. -Broadcast = (mst) [experimental] - This option selects the way broadcast packets are sent to other - daemons. _NOTE: all nodes in a VPN must use the same Broadcast - mode, otherwise routing loops can form._ - - no - Broadcast packets are never sent to other nodes. - - mst - Broadcast packets are sent and forwarded via the VPN's Minimum - Spanning Tree. This ensures broadcast packets reach all - nodes. - - direct - Broadcast packets are sent directly to all nodes that can be - reached directly. Broadcast packets received from other nodes - are never forwarded. If the IndirectData option is also set, - broadcast packets will only be sent to nodes which we have a - meta connection to. - ConnectTo = Specifies which other tinc daemon to connect to on startup. Multiple ConnectTo variables may be specified, in which case @@ -744,139 +733,98 @@ ConnectTo = connect to other daemons at all, and will instead just listen for incoming connections. -DecrementTTL = (no) [experimental] - When enabled, tinc will decrement the Time To Live field in IPv4 - packets, or the Hop Limit field in IPv6 packets, before forwarding - a received packet to the virtual network device or to another node, - and will drop packets that have a TTL value of zero, in which case - it will send an ICMP Time Exceeded packet back. - - Do not use this option if you use switch mode and want to use IPv6. - -Device = ('/dev/tap0', '/dev/net/tun' or other depending on platform) +Device = (`/dev/tap0', `/dev/net/tun' or other depending on platform) The virtual network device to use. Tinc will automatically detect - what kind of device it is. Under Windows, use INTERFACE instead of - DEVICE. Note that you can only use one device per daemon. See - also *note Device files::. + what kind of device it is. Note that you can only use one device + per daemon. Under Windows, use INTERFACE instead of DEVICE. Note + that you can only use one device per daemon. See also *note + Device files::. -DeviceType = (platform dependent) +DeviceType = (only supported on BSD platforms) The type of the virtual network device. Tinc will normally - automatically select the right type of tun/tap interface, and this - option should not be used. However, this option can be used to - select one of the special interface types, if support for them is - compiled in. + automatically select the right type, and this option should not be + used. However, in case tinc does not seem to correctly interpret + packets received from the virtual network device, using this + option might help. - dummy - Use a dummy interface. No packets are ever read or written to - a virtual network device. Useful for testing, or when setting - up a node that only forwards packets for other nodes. - - raw_socket - Open a raw socket, and bind it to a pre-existing INTERFACE - (eth0 by default). All packets are read from this interface. - Packets received for the local node are written to the raw - socket. However, at least on Linux, the operating system does - not process IP packets destined for the local host. - - multicast - Open a multicast UDP socket and bind it to the address and - port (separated by spaces) and optionally a TTL value - specified using DEVICE. Packets are read from and written to - this multicast socket. This can be used to connect to UML, - QEMU or KVM instances listening on the same multicast address. - Do NOT connect multiple tinc daemons to the same multicast - address, this will very likely cause routing loops. Also note - that this can cause decrypted VPN packets to be sent out on a - real network if misconfigured. - - uml (not compiled in by default) - Create a UNIX socket with the filename specified by DEVICE, or - '/var/run/NETNAME.umlsocket' if not specified. Tinc will wait - for a User Mode Linux instance to connect to this socket. - - vde (not compiled in by default) - Uses the libvdeplug library to connect to a Virtual - Distributed Ethernet switch, using the UNIX socket specified - by DEVICE, or '/var/run/vde.ctl' if not specified. - - Also, in case tinc does not seem to correctly interpret packets - received from the virtual network device, it can be used to change - the way packets are interpreted: - - tun (BSD and Linux) + tun Set type to tun. Depending on the platform, this can either be with or without an address family header (see below). - tunnohead (BSD) + tunnohead Set type to tun without an address family header. Tinc will expect packets read from the virtual network device to start with an IP header. On some platforms IPv6 packets cannot be read from or written to the device in this mode. - tunifhead (BSD) + tunifhead Set type to tun with an address family header. Tinc will expect packets read from the virtual network device to start with a four byte header containing the address family, followed by an IP header. This mode should support both IPv4 and IPv6 packets. - utun (OS X) - Set type to utun. This is only supported on OS X version - 10.6.8 and higher, but doesn't require the tuntaposx module. - This mode should support both IPv4 and IPv6 packets. - - tap (BSD and Linux) + tap 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 + 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. +ECDSAPrivateKeyFile = (`/etc/tinc/NETNAME/ecdsa_key.priv') + The file in which the private ECDSA key of this tinc daemon + resides. This is only used if ExperimentalProtocol is enabled. + +ExperimentalProtocol = (no) [experimental] + When this option is enabled, experimental protocol enhancements + will be used. Ephemeral ECDH will be used for key exchanges, and + ECDSA will be used instead of RSA for authentication. When + enabled, an ECDSA key must have been generated before with + `tincctl generate-ecdsa-keys'. The experimental protocol may + change at any time, and there is no guarantee that tinc will run + stable when it is used. + Forwarding = (internal) [experimental] This option selects the way indirect packets are forwarded. - off + 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. + 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 + 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 changes to - the graph. The file is in a format that can be read by graphviz - tools. If FILENAME starts with a pipe symbol |, then the rest of - the filename is interpreted as a shell command that is executed, - the graph is then sent to stdin. + If this option is present, tinc will dump the current network + graph to the file FILENAME every minute, unless there were no + changes to the graph. The file is in a format that can be read by + graphviz tools. If FILENAME starts with a pipe symbol |, then the + rest of the filename is interpreted as a shell command that is + executed, the graph is then sent to stdin. Hostnames = (no) This option selects whether IP addresses (both real and on the VPN) should be resolved. Since DNS lookups are blocking, it might affect tinc's efficiency, even stopping the daemon for a few - seconds every time it does a lookup if your DNS server is not + seconds everytime it does a lookup if your DNS server is not responding. This does not affect resolving hostnames to IP addresses from the - configuration file, but whether hostnames should be resolved while - logging. - -IffOneQueue = (no) [experimental] - (Linux only) Set IFF_ONE_QUEUE flag on TUN/TAP devices. + configuration file. Interface = Defines the name of the interface corresponding to the virtual @@ -886,44 +834,19 @@ Interface = interface will be used. If you specified a Device, this variable is almost always already correctly set. -KeyExpire = (3600) - This option controls the time the encryption keys used to encrypt - the data are valid. It is common practice to change keys at - regular intervals to make it even harder for crackers, even though - it is thought to be nearly impossible to crack a single key. - -LocalDiscovery = (no) [experimental] - When enabled, tinc will try to detect peers that are on the same - local network. This will allow direct communication using LAN - addresses, even if both peers are behind a NAT and they only - ConnectTo a third node outside the NAT, which normally would - prevent the peers from learning each other's LAN address. - - Currently, local discovery is implemented by sending broadcast - packets to the LAN during path MTU discovery. This feature may not - work in all possible situations. - -MACExpire = (600) - This option controls the amount of time MAC addresses are kept - before they are removed. This only has effect when Mode is set to - "switch". - -MaxTimeout = (900) - This is the maximum delay before trying to reconnect to other tinc - daemons. - Mode = (router) This option selects the way packets are routed to other daemons. - router + router In this mode Subnet variables in the host configuration files - will be used to form a routing table. Only unicast packets of - routable protocols (IPv4 and IPv6) are supported in this mode. + will be used to form a routing table. Only unicast packets + of routable protocols (IPv4 and IPv6) are supported in this + mode. This is the default mode, and unless you really know you need another mode, don't change it. - switch + switch In this mode the MAC addresses of the packets on the VPN will be used to dynamically create a routing table just like an Ethernet switch does. Unicast, multicast and broadcast @@ -934,21 +857,26 @@ Mode = (router) This mode is primarily useful if you want to bridge Ethernet segments. - hub + hub This mode is almost the same as the switch mode, but instead every packet will be broadcast to the other daemons while no routing table is managed. -Name = [required] - This is a symbolic name for this connection. The name must consist - only of alphanumeric and underscore characters (a-z, A-Z, 0-9 and - _). +KeyExpire = (3600) + This option controls the time the encryption keys used to encrypt + the data are valid. It is common practice to change keys at + regular intervals to make it even harder for crackers, even though + it is thought to be nearly impossible to crack a single key. - If Name starts with a $, then the contents of the environment - variable that follows will be used. In that case, invalid - characters will be converted to underscores. If Name is $HOST, but - no such environment variable exist, the hostname will be read using - the gethostname() system call. +MACExpire = (600) + This option controls the amount of time MAC addresses are kept + before they are removed. This only has effect when Mode is set to + "switch". + +Name = [required] + This is a symbolic name for this connection. The name should + consist only of alfanumeric and underscore characters (a-z, A-Z, + 0-9 and _). PingInterval = (60) The number of seconds of inactivity that tinc will wait before @@ -956,7 +884,7 @@ PingInterval = (60) PingTimeout = (5) The number of seconds to wait for a response to pings or to allow - meta connections to block. If the other end doesn't respond within + meta connections to block. If the other end doesn't respond within this time, the connection is terminated, and the others will be notified of this. @@ -966,68 +894,46 @@ PriorityInheritance = (no) [experimental] out. PrivateKey = [obsolete] - This is the RSA private key for tinc. However, for safety reasons + This is the RSA private key for tinc. However, for safety reasons it is advised to store private keys of any kind in separate files. - This prevents accidental eavesdropping if you are editing the + This prevents accidental eavesdropping if you are editting the configuration file. -PrivateKeyFile = ('/etc/tinc/NETNAME/rsa_key.priv') +PrivateKeyFile = (`/etc/tinc/NETNAME/rsa_key.priv') This is the full path name of the RSA private key file that was - generated by 'tincd --generate-keys'. It must be a full path, not + generated by `tincctl generate-keys'. It must be a full path, not a relative directory. + Note that there must be exactly one of PrivateKey or PrivateKeyFile + specified in the configuration file. + ProcessPriority = 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. -Proxy = socks4 | socks5 | http | exec ... [experimental] - Use a proxy when making outgoing connections. The following proxy - types are currently supported: - - socks4
[] - Connects to the proxy using the SOCKS version 4 protocol. - Optionally, a USERNAME can be supplied which will be passed on - to the proxy server. - - socks5
[ ] - Connect to the proxy using the SOCKS version 5 protocol. If a - USERNAME and PASSWORD are given, basic username/password - authentication will be used, otherwise no authentication will - be used. - - http
- Connects to the proxy and sends a HTTP CONNECT request. - - exec - Executes the given command which should set up the outgoing - connection. The environment variables 'NAME', 'NODE', - 'REMOTEADDRES' and 'REMOTEPORT' are available. - ReplayWindow = (16) This is the size of the replay tracking window for each remote - node, in bytes. The window is a bitfield which tracks 1 packet per - bit, so for example the default setting of 16 will track up to 128 - packets in the window. In high bandwidth scenarios, setting this - to a higher value can reduce packet loss from the interaction of - replay tracking with underlying real packet loss and/or reordering. - Setting this to zero will disable replay tracking completely and - pass all traffic, but leaves tinc vulnerable to replay-based - attacks on your traffic. + node, in bytes. The window is a bitfield which tracks 1 packet + per bit, so for example the default setting of 16 will track up to + 128 packets in the window. In high bandwidth scenarios, setting + this to a higher value can reduce packet loss from the interaction + of replay tracking with underlying real packet loss and/or + reordering. Setting this to zero will disable replay tracking + completely and pass all traffic, but leaves tinc vulnerable to + replay-based attacks on your traffic. -StrictSubnets = (no) [experimental] +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. Subnets learned via - connections to other nodes and which are not present in the local - host config files are ignored. + `/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 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. + 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 `/etc/tinc/NETNAME/hosts/' directory. Setting this + options also implicitly sets StrictSubnets. UDPRcvBuf = (OS default) Sets the socket receive buffer size for the UDP socket, in bytes. @@ -1039,6 +945,7 @@ UDPSndBuf = Pq OS default unset, the default buffer size will be used by the operating system. +  File: tinc.info, Node: Host configuration variables, Next: Scripts, Prev: Main configuration variables, Up: Configuration files @@ -1046,34 +953,32 @@ File: tinc.info, Node: Host configuration variables, Next: Scripts, Prev: Mai ---------------------------------- 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. If no port is - specified, the default Port is used. Multiple Address variables - can be specified, in which case each address will be tried until a - working connection has been established. + 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. -Cipher = (aes-256-cbc) +Cipher = (blowfish) The symmetric cipher algorithm used to encrypt UDP packets. Any - cipher supported by LibreSSL or OpenSSL is recognized. - Furthermore, specifying "none" will turn off packet encryption. It - is best to use only those ciphers which support CBC mode. + 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. 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. + 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 (best zlib), 10 (fast lzo) and 11 (best lzo). -Digest = (sha256) +Digest = (sha1) The digest algorithm used to authenticate UDP packets. Any digest - supported by LibreSSL or OpenSSL is recognized. Furthermore, - specifying "none" will turn off packet authentication. + supported by OpenSSL is recognized. Furthermore, specifying + "none" will turn off packet authentication. IndirectData = (no) This option specifies whether other tinc daemons besides the one @@ -1085,32 +990,32 @@ IndirectData = (no) MACLength = (4) The length of the message authentication code used to authenticate - UDP packets. Can be anything from 0 up to the length of the digest - produced by the digest algorithm. + UDP packets. Can be anything from 0 up to the length of the + digest produced by the digest algorithm. PMTU = (1514) This option controls the initial path MTU to this node. PMTUDiscovery = (yes) - 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. + 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. Port = (655) This is the port this tinc daemon listens on. You can use decimal - portnumbers or symbolic names (as listed in '/etc/services'). + portnumbers or symbolic names (as listed in `/etc/services'). PublicKey = [obsolete] This is the RSA public key for this host. PublicKeyFile = [obsolete] This is the full path name of the RSA public key file that was - generated by 'tincd --generate-keys'. It must be a full path, not + generated by `tincctl generate-keys'. It must be a full path, not a relative directory. From version 1.0pre4 on tinc will store the public key directly into the host configuration file in PEM format, the above two - options then are not necessary. Either the PEM format is used, or + options then are not necessary. Either the PEM format is used, or exactly *one of the above two options* must be specified in each host configuration file, if you want to be able to establish a connection with that host. @@ -1118,41 +1023,40 @@ PublicKeyFile = [obsolete] Subnet = The subnet which this tinc daemon will serve. Tinc tries to look up which other daemon it should send a packet to by searching the - appropriate subnet. If the packet matches a subnet, it will be + appropiate subnet. If the packet matches a subnet, it will be sent to the daemon who has this subnet in his host configuration file. Multiple subnet lines can be specified for each daemon. Subnets can either be single MAC, IPv4 or IPv6 addresses, in which - case a subnet consisting of only that single address is assumed, or - they can be a IPv4 or IPv6 network address with a prefixlength. - For example, IPv4 subnets must be in a form like 192.168.1.0/24, - where 192.168.1.0 is the network address and 24 is the number of - bits set in the netmask. Note that subnets like 192.168.1.1/24 are - invalid! Read a networking HOWTO/FAQ/guide if you don't understand - this. IPv6 subnets are notated like fec0:0:0:1::/64. MAC - addresses are notated like 0:1a:2b:3c:4d:5e. + case a subnet consisting of only that single address is assumed, + or they can be a IPv4 or IPv6 network address with a prefixlength. + Shorthand notations are not supported. For example, IPv4 subnets + must be in a form like 192.168.1.0/24, where 192.168.1.0 is the + network address and 24 is the number of bits set in the netmask. + Note that subnets like 192.168.1.1/24 are invalid! Read a + networking HOWTO/FAQ/guide if you don't understand this. IPv6 + subnets are notated like fec0:0:0:1:0:0:0:0/64. MAC addresses are + notated like 0:1a:2b:3c:4d:5e. Prefixlength is the number of bits set to 1 in the netmask part; for example: netmask 255.255.255.0 would become /24, 255.255.252.0 - becomes /22. This conforms to standard CIDR notation as described - in RFC1519 (https://www.ietf.org/rfc/rfc1519.txt) + becomes /22. This conforms to standard CIDR notation as described + in RFC1519 (ftp://ftp.isi.edu/in-notes/rfc1519.txt) A Subnet can be given a weight to indicate its priority over - identical Subnets owned by different nodes. The default weight is - 10. Lower values indicate higher priority. Packets will be sent - to the node with the highest priority, unless that node is not + identical Subnets owned by different nodes. The default weight is + 10. Lower values indicate higher priority. Packets will be sent to + the node with the highest priority, unless that node is not reachable, in which case the node with the next highest priority will be tried, and so on. -TCPonly = (no) [deprecated] - If this variable is set to yes, then the packets are tunnelled over - a TCP connection instead of a UDP connection. This is especially - useful for those who want to run a tinc daemon from behind a - masquerading firewall, or if UDP packet routing is disabled - somehow. Setting this options also implicitly sets IndirectData. - - Since version 1.0.10, tinc will automatically detect whether - communication via UDP is possible or not. +TCPonly = (no) + If this variable is set to yes, then the packets are tunnelled + over a TCP connection instead of a UDP connection. This is + especially useful for those who want to run a tinc daemon from + behind a masquerading firewall, or if UDP packet routing is + disabled somehow. Setting this options also implicitly sets + IndirectData.  File: tinc.info, Node: Scripts, Next: How to configure, Prev: Host configuration variables, Up: Configuration files @@ -1161,88 +1065,76 @@ File: tinc.info, Node: Scripts, Next: How to configure, Prev: Host configurat ------------- Apart from reading the server and host configuration files, tinc can -also run scripts at certain moments. Below is a list of filenames of -scripts and a description of when they are run. A script is only run if -it exists and if it is executable. +also run scripts at certain moments. Under Windows (not Cygwin), the +scripts should have the extension .bat. - Scripts are run synchronously; this means that tinc will temporarily -stop processing packets until the called script finishes executing. -This guarantees that scripts will execute in the exact same order as the -events that trigger them. If you need to run commands asynchronously, -you have to ensure yourself that they are being run in the background. - - Under Windows (not Cygwin), the scripts must have the extension .bat. - -'/etc/tinc/NETNAME/tinc-up' +`/etc/tinc/NETNAME/tinc-up' This is the most important script. If it is present it will be executed right after the tinc daemon has been started and has connected to the virtual network device. It should be used to set up the corresponding network interface, but can also be used to - start other things. + start other things. Under Windows you can use the Network + Connections control panel instead of creating this script. - Under Windows you can use the Network Connections control panel - instead of creating this script. - -'/etc/tinc/NETNAME/tinc-down' +`/etc/tinc/NETNAME/tinc-down' This script is started right before the tinc daemon quits. -'/etc/tinc/NETNAME/hosts/HOST-up' +`/etc/tinc/NETNAME/hosts/HOST-up' This script is started when the tinc daemon with name HOST becomes reachable. -'/etc/tinc/NETNAME/hosts/HOST-down' +`/etc/tinc/NETNAME/hosts/HOST-down' This script is started when the tinc daemon with name HOST becomes unreachable. -'/etc/tinc/NETNAME/host-up' +`/etc/tinc/NETNAME/host-up' This script is started when any host becomes reachable. -'/etc/tinc/NETNAME/host-down' +`/etc/tinc/NETNAME/host-down' This script is started when any host becomes unreachable. -'/etc/tinc/NETNAME/subnet-up' - This script is started when a subnet becomes reachable. The Subnet - and the node it belongs to are passed in environment variables. +`/etc/tinc/NETNAME/subnet-up' + This script is started when a Subnet becomes reachable. The + Subnet and the node it belongs to are passed in environment + variables. -'/etc/tinc/NETNAME/subnet-down' - This script is started when a subnet becomes unreachable. +`/etc/tinc/NETNAME/subnet-down' + This script is started when a Subnet becomes unreachable. The scripts are started without command line arguments, but can make -use of certain environment variables. Under UNIX like operating systems -the names of environment variables must be preceded by a $ in scripts. -Under Windows, in '.bat' files, they have to be put between % signs. +use of certain environment variables. Under UNIX like operating +systems the names of environment variables must be preceded by a $ in +scripts. Under Windows, in `.bat' files, they have to be put between % +signs. -'NETNAME' +`NETNAME' If a netname was specified, this environment variable contains it. -'NAME' +`NAME' Contains the name of this tinc daemon. -'DEVICE' +`DEVICE' Contains the name of the virtual network device that tinc uses. -'INTERFACE' +`INTERFACE' Contains the name of the virtual network interface that tinc uses. This should be used for commands like ifconfig. -'NODE' +`NODE' When a host becomes (un)reachable, this is set to its name. If a subnet becomes (un)reachable, this is set to the owner of that subnet. -'REMOTEADDRESS' +`REMOTEADDRESS' When a host becomes (un)reachable, this is set to its real address. -'REMOTEPORT' +`REMOTEPORT' When a host becomes (un)reachable, this is set to the port number it uses for communication with other tinc daemons. -'SUBNET' +`SUBNET' When a subnet becomes (un)reachable, this is set to the subnet. -'WEIGHT' - When a subnet becomes (un)reachable, this is set to the subnet - weight.  File: tinc.info, Node: How to configure, Prev: Scripts, Up: Configuration files @@ -1250,35 +1142,35 @@ File: tinc.info, Node: How to configure, Prev: Scripts, Up: Configuration fil 4.4.4 How to configure ---------------------- -Step 1. Creating the main configuration file -............................................ +Step 1. Creating the main configuration file +............................................. The main configuration file will be called -'/etc/tinc/NETNAME/tinc.conf'. Adapt the following example to create a +`/etc/tinc/NETNAME/tinc.conf'. Adapt the following example to create a basic configuration file: Name = YOURNAME - Device = /dev/tap0 + Device = `/dev/tap0' Then, if you know to which other tinc daemon(s) yours is going to -connect, add 'ConnectTo' values. +connect, add `ConnectTo' values. -Step 2. Creating your host configuration file -............................................. +Step 2. Creating your host configuration file +.............................................. -If you added a line containing 'Name = yourname' in the main -configuration file, you will need to create a host configuration file -'/etc/tinc/NETNAME/hosts/yourname'. Adapt the following example to +If you added a line containing `Name = yourname' in the main +configuarion file, you will need to create a host configuration file +`/etc/tinc/NETNAME/hosts/yourname'. Adapt the following example to create a host configuration file: Address = your.real.hostname.org Subnet = 192.168.1.0/24 - You can also use an IP address instead of a hostname. The 'Subnet' + You can also use an IP address instead of a hostname. The `Subnet' specifies the address range that is local for _your part of the VPN only_. If you have multiple address ranges you can specify more than -one 'Subnet'. You might also need to add a 'Port' if you want your tinc -daemon to run on a different port number than the default (655). +one `Subnet'. You might also need to add a `Port' if you want your +tinc daemon to run on a different port number than the default (655).  File: tinc.info, Node: Generating keypairs, Next: Network interfaces, Prev: Configuration files, Up: Configuration @@ -1290,7 +1182,7 @@ Now that you have already created the main configuration file and your host configuration file, you can easily create a public/private keypair by entering the following command: - tincd -n NETNAME -K + tincctl -n NETNAME generate-keys Tinc will generate a public and a private key and ask you where to put them. Just press enter to accept the defaults. @@ -1307,27 +1199,28 @@ the virtual network interface. First, decide which IP addresses you want to have associated with these devices, and what network mask they must have. - Tinc will open a virtual network device ('/dev/tun', '/dev/tap0' or + Tinc will open a virtual network device (`/dev/tun', `/dev/tap0' or similar), which will also create a network interface called something -like 'tun0', 'tap0'. If you are using the Linux tun/tap driver, the +like `tun0', `tap0'. If you are using the Linux tun/tap driver, the network interface will by default have the same name as the NETNAME. Under Windows you can change the name of the network interface from the Network Connections control panel. - You can configure the network interface by putting ordinary ifconfig, -route, and other commands to a script named '/etc/tinc/NETNAME/tinc-up'. -When tinc starts, this script will be executed. When tinc exits, it -will execute the script named '/etc/tinc/NETNAME/tinc-down', but -normally you don't need to create that script. + You can configure the network interface by putting ordinary +ifconfig, route, and other commands to a script named +`/etc/tinc/NETNAME/tinc-up'. When tinc starts, this script will be +executed. When tinc exits, it will execute the script named +`/etc/tinc/NETNAME/tinc-down', but normally you don't need to create +that script. - An example 'tinc-up' script: + An example `tinc-up' script: #!/bin/sh ifconfig $INTERFACE 192.168.1.1 netmask 255.255.0.0 This script gives the interface an IP address and a netmask. The kernel will also automatically add a route to this interface, so -normally you don't need to add route commands to the 'tinc-up' script. +normally you don't need to add route commands to the `tinc-up' script. The kernel will also bring the interface up after this command. The netmask is the mask of the _entire_ VPN network, not just your own subnet. @@ -1344,12 +1237,12 @@ File: tinc.info, Node: Example configuration, Prev: Network interfaces, Up: C 4.7 Example configuration ========================= -Imagine the following situation. Branch A of our example 'company' +Imagine the following situation. Branch A of our example `company' wants to connect three branch offices in B, C and D using the Internet. All four offices have a 24/7 connection to the Internet. A is going to serve as the center of the network. B and C will -connect to A, and D will connect to C. Each office will be assigned +connect to A, and D will connect to C. Each office will be assigned their own IP network, 10.x.0.0. A: net 10.1.0.0 mask 255.255.0.0 gateway 10.1.54.1 internet IP 1.2.3.4 @@ -1362,31 +1255,31 @@ the tincd, and "internet IP" is the IP address of the firewall, which does not need to run tincd, but it must do a port forwarding of TCP and UDP on port 655 (unless otherwise configured). - In this example, it is assumed that eth0 is the interface that points -to the inner (physical) LAN of the office, although this could also be -the same as the interface that leads to the Internet. The configuration -of the real interface is also shown as a comment, to give you an idea of -how these example host is set up. All branches use the netname -'company' for this particular VPN. + In this example, it is assumed that eth0 is the interface that +points to the inner (physical) LAN of the office, although this could +also be the same as the interface that leads to the Internet. The +configuration of the real interface is also shown as a comment, to give +you an idea of how these example host is set up. All branches use the +netname `company' for this particular VPN. For Branch A ............ _BranchA_ would be configured like this: - In '/etc/tinc/company/tinc-up': + In `/etc/tinc/company/tinc-up': # Real interface of internal network: # ifconfig eth0 10.1.54.1 netmask 255.255.0.0 ifconfig $INTERFACE 10.1.54.1 netmask 255.0.0.0 - and in '/etc/tinc/company/tinc.conf': + and in `/etc/tinc/company/tinc.conf': Name = BranchA Device = /dev/tap0 - On all hosts, '/etc/tinc/company/hosts/BranchA' contains: + On all hosts, `/etc/tinc/company/hosts/BranchA' contains: Subnet = 10.1.0.0/16 Address = 1.2.3.4 @@ -1396,22 +1289,22 @@ _BranchA_ would be configured like this: -----END RSA PUBLIC KEY----- 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 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. +quite possible, if you make sure that the netmasks of the interfaces +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 ............ -In '/etc/tinc/company/tinc-up': +In `/etc/tinc/company/tinc-up': # Real interface of internal network: # ifconfig eth0 10.2.43.8 netmask 255.255.0.0 ifconfig $INTERFACE 10.2.1.12 netmask 255.0.0.0 - and in '/etc/tinc/company/tinc.conf': + and in `/etc/tinc/company/tinc.conf': Name = BranchB ConnectTo = BranchA @@ -1420,7 +1313,7 @@ In '/etc/tinc/company/tinc-up': 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': + On all hosts, in `/etc/tinc/company/hosts/BranchB': Subnet = 10.2.0.0/16 Address = 2.3.4.5 @@ -1432,24 +1325,24 @@ will always try to connect to BranchA. For Branch C ............ -In '/etc/tinc/company/tinc-up': +In `/etc/tinc/company/tinc-up': # Real interface of internal network: # ifconfig eth0 10.3.69.254 netmask 255.255.0.0 ifconfig $INTERFACE 10.3.69.254 netmask 255.0.0.0 - and in '/etc/tinc/company/tinc.conf': + and in `/etc/tinc/company/tinc.conf': Name = BranchC ConnectTo = BranchA Device = /dev/tap1 C already has another daemon that runs on port 655, so they have to -reserve another port for tinc. It knows the portnumber it has to listen +reserve another port for tinc. It knows the portnumber it has to listen on from it's own host configuration file. - On all hosts, in '/etc/tinc/company/hosts/BranchC': + On all hosts, in `/etc/tinc/company/hosts/BranchC': Address = 3.4.5.6 Subnet = 10.3.0.0/16 @@ -1462,26 +1355,26 @@ on from it's own host configuration file. For Branch D ............ -In '/etc/tinc/company/tinc-up': +In `/etc/tinc/company/tinc-up': # Real interface of internal network: # ifconfig eth0 10.4.3.32 netmask 255.255.0.0 ifconfig $INTERFACE 10.4.3.32 netmask 255.0.0.0 - and in '/etc/tinc/company/tinc.conf': + and in `/etc/tinc/company/tinc.conf': Name = BranchD ConnectTo = BranchC Device = /dev/net/tun - D will be connecting to C, which has a tincd running for this network -on port 2000. It knows the port number from the host configuration -file. Also note that since D uses the tun/tap driver, the network -interface will not be called 'tun' or 'tap0' or something like that, but -will have the same name as netname. + D will be connecting to C, which has a tincd running for this +network on port 2000. It knows the port number from the host +configuration file. Also note that since D uses the tun/tap driver, +the network interface will not be called `tun' or `tap0' or something +like that, but will have the same name as netname. - On all hosts, in '/etc/tinc/company/hosts/BranchD': + On all hosts, in `/etc/tinc/company/hosts/BranchD': Subnet = 10.4.0.0/16 Address = 4.5.6.7 @@ -1496,13 +1389,13 @@ Key files A, B, C and D all have generated a public/private keypair with the following command: - tincd -n company -K + tincctl -n company generate-keys - The private key is stored in '/etc/tinc/company/rsa_key.priv', the + The private key is stored in `/etc/tinc/company/rsa_key.priv', the public key is put into the host configuration file in the -'/etc/tinc/company/hosts/' directory. During key generation, tinc -automatically guesses the right filenames based on the -n option and the -Name directive in the 'tinc.conf' file (if it is available). +`/etc/tinc/company/hosts/' directory. During key generation, tinc +automatically guesses the right filenames based on the -n option and +the Name directive in the `tinc.conf' file (if it is available). Starting ........ @@ -1514,7 +1407,7 @@ have started their daemons, tinc will try connecting until they are available.  -File: tinc.info, Node: Running tinc, Next: Technical information, Prev: Configuration, Up: Top +File: tinc.info, Node: Running tinc, Next: Controlling tinc, Prev: Configuration, Up: Top 5 Running tinc ************** @@ -1547,90 +1440,67 @@ File: tinc.info, Node: Runtime options, Next: Signals, Up: Running tinc Besides the settings in the configuration file, tinc also accepts some command line options. -'-c, --config=PATH' +`-c, --config=PATH' Read configuration options from the directory PATH. The default is - '/etc/tinc/NETNAME/'. + `/etc/tinc/NETNAME/'. -'-D, --no-detach' +`-D, --no-detach' Don't fork and detach. This will also disable the automatic restart mechanism for fatal errors. -'-d, --debug=LEVEL' +`-d, --debug=LEVEL' Set debug level to LEVEL. The higher the debug level, the more gets logged. Everything goes via syslog. -'-k, --kill[=SIGNAL]' - Attempt to kill a running tincd (optionally with the specified - SIGNAL instead of SIGTERM) and exit. Use it in conjunction with - the -n option to make sure you kill the right tinc daemon. Under - native Windows the optional argument is ignored, the service will - always be stopped and removed. - -'-n, --net=NETNAME' +`-n, --net=NETNAME' Use configuration for net NETNAME. This will let tinc read all - configuration files from '/etc/tinc/NETNAME/'. Specifying . for + configuration files from `/etc/tinc/NETNAME/'. Specifying . for NETNAME is the same as not specifying any NETNAME. *Note Multiple networks::. -'-K, --generate-keys[=BITS]' - Generate public/private keypair of BITS length. If BITS is not - specified, 2048 is the default. tinc will ask where you want to - store the files, but will default to the configuration directory - (you can use the -c or -n option in combination with -K). After - that, tinc will quit. +`--pidfile=FILENAME' + Store a cookie in FILENAME which allows tincctl to authenticate. + If unspecified, the default is `/var/run/tinc.NETNAME.pid'. -'-o, --option=[HOST.]KEY=VALUE' - Without specifying a HOST, this will set server configuration - variable KEY to VALUE. If specified as HOST.KEY=VALUE, this will - set the host configuration variable KEY of the host named HOST to - VALUE. This option can be used more than once to specify multiple - configuration variables. - -'-L, --mlock' +`-L, --mlock' Lock tinc into main memory. This will prevent sensitive data like shared private keys to be written to the system swap files/partitions. -'--logfile[=FILE]' +`--logfile[=FILE]' Write log entries to a file instead of to the system logging facility. If FILE is omitted, the default is - '/var/log/tinc.NETNAME.log'. + `/var/log/tinc.NETNAME.log'. -'--pidfile=FILE' - Write PID to FILE instead of '/var/run/tinc.NETNAME.pid'. - -'--bypass-security' +`--bypass-security' Disables encryption and authentication. Only useful for debugging. -'-R, --chroot' +`-R, --chroot' Change process root directory to the directory where the config - file is located ('/etc/tinc/NETNAME/' as determined by -n/-net + file is located (`/etc/tinc/NETNAME/' as determined by -n/-net option or as given by -c/-config option), for added security. The chroot is performed after all the initialization is done, after writing pid files and opening network sockets. - This option is best used in combination with the -U/-user option - described below. + Note that this option alone does not do any good without -U/-user, + below. - You will need to ensure the chroot environment contains all the - files necessary for tinc to run correctly. Most importantly, for - tinc to be able to resolve hostnames inside the chroot environment, - you must copy '/etc/resolv.conf' into the chroot directory. If you - want to be able to run scripts other than 'tinc-up' in the chroot, - you must ensure the appropriate shell is also installed in the - chroot, along with all its dependencies. + Note also that tinc can't run scripts anymore (such as tinc-down + or host-up), unless it's setup to be runnable inside chroot + environment. -'-U, --user=USER' +`-U, --user=USER' Switch to the given USER after initialization, at the same time as chroot is performed (see -chroot above). With this option tinc drops privileges, for added security. -'--help' +`--help' Display a short reminder of these runtime options and terminate. -'--version' +`--version' Output version information and exit. +  File: tinc.info, Node: Signals, Next: Debug levels, Prev: Runtime options, Up: Running tinc @@ -1639,33 +1509,20 @@ File: tinc.info, Node: Signals, Next: Debug levels, Prev: Runtime options, U You can also send the following signals to a running tincd process: -'ALRM' +`ALRM' Forces tinc to try to connect to all uplinks immediately. Usually tinc attempts to do this itself, but increases the time it waits between the attempts each time it failed, and if tinc didn't - succeed to connect to an uplink the first time after it started, it - defaults to the maximum time of 15 minutes. + succeed to connect to an uplink the first time after it started, + it defaults to the maximum time of 15 minutes. -'HUP' +`HUP' Partially rereads configuration files. Connections to hosts whose host config file are removed are closed. New outgoing connections - specified in 'tinc.conf' will be made. If the -logfile option is - used, this will also close and reopen the log file, useful when log - rotation is used. + specified in `tinc.conf' will be made. If the -logfile option is + used, this will also close and reopen the log file, useful when + log rotation is used. -'INT' - Temporarily increases debug level to 5. Send this signal again to - revert to the original level. - -'USR1' - Dumps the connection list to syslog. - -'USR2' - Dumps virtual network device statistics, all known nodes, edges and - subnets to syslog. - -'WINCH' - Purges all information remembered about unreachable nodes.  File: tinc.info, Node: Debug levels, Next: Solving problems, Prev: Signals, Up: Running tinc @@ -1674,32 +1531,33 @@ File: tinc.info, Node: Debug levels, Next: Solving problems, Prev: Signals, ================ The tinc daemon can send a lot of messages to the syslog. The higher -the debug level, the more messages it will log. Each level inherits all -messages of the previous level: +the debug level, the more messages it will log. Each level inherits +all messages of the previous level: -'0' +`0' This will log a message indicating tinc has started along with a version number. It will also log any serious error. -'1' +`1' This will log all connections that are made with other tinc daemons. -'2' - This will log status and error messages from scripts and other tinc - daemons. +`2' + This will log status and error messages from scripts and other + tinc daemons. -'3' +`3' This will log all requests that are exchanged with other tinc - daemons. These include authentication, key exchange and connection + daemons. These include authentication, key exchange and connection list updates. -'4' +`4' This will log a copy of everything received on the meta socket. -'5' +`5' This will log all network traffic over the virtual private network. +  File: tinc.info, Node: Solving problems, Next: Error messages, Prev: Debug levels, Up: Running tinc @@ -1713,10 +1571,10 @@ directly see everything tinc logs: tincd -n NETNAME -d5 -D - If tinc does not log any error messages, then you might want to check -the following things: + If tinc does not log any error messages, then you might want to +check the following things: - * 'tinc-up' script Does this script contain the right commands? + * `tinc-up' script Does this script contain the right commands? Normally you must give the interface the address of this host on the VPN, and the netmask must be big enough so that the entire VPN is covered. @@ -1730,11 +1588,10 @@ the following things: masquerading)? If so, check that it allows TCP and UDP traffic on port 655. If it masquerades and the host running tinc is behind it, make sure that it forwards TCP and UDP traffic to port 655 to - the host running tinc. You can add 'TCPOnly = yes' to your host - config file to force tinc to only use a single TCP connection, this - works through most firewalls and NATs. Since version 1.0.10, tinc - will automatically fall back to TCP if direct communication via UDP - is not possible. + the host running tinc. You can add `TCPOnly = yes' to your host + config file to force tinc to only use a single TCP connection, + this works through most firewalls and NATs. +  File: tinc.info, Node: Error messages, Next: Sending bug reports, Prev: Solving problems, Up: Running tinc @@ -1746,93 +1603,98 @@ What follows is a list of the most common error messages you might find in the logs. Some of them will only be visible if the debug level is high enough. -'Could not open /dev/tap0: No such device' +`Could not open /dev/tap0: No such device' + * You forgot to `modprobe netlink_dev' or `modprobe ethertap'. - * You forgot to 'modprobe netlink_dev' or 'modprobe ethertap'. - * You forgot to compile 'Netlink device emulation' in the + * You forgot to compile `Netlink device emulation' in the kernel. -'Can't write to /dev/net/tun: No such device' +`Can't write to /dev/net/tun: No such device' + * You forgot to `modprobe tun'. - * You forgot to 'modprobe tun'. - * You forgot to compile 'Universal TUN/TAP driver' in the + * You forgot to compile `Universal TUN/TAP driver' in the kernel. - * The tun device is located somewhere else in '/dev/'. -'Network address and prefix length do not match!' + * The tun device is located somewhere else in `/dev/'. +`Network address and prefix length do not match!' * The Subnet field must contain a _network_ address, trailing bits should be 0. + * If you only want to use one IP address, set the netmask to /32. -'Error reading RSA key file `rsa_key.priv': No such file or directory' - +`Error reading RSA key file `rsa_key.priv': No such file or directory' * You forgot to create a public/private keypair. - * Specify the complete pathname to the private key file with the - 'PrivateKeyFile' option. -'Warning: insecure file permissions for RSA private key file `rsa_key.priv'!' + * Specify the complete pathname to the private key file with + the `PrivateKeyFile' option. +`Warning: insecure file permissions for RSA private key file `rsa_key.priv'!' * The private key file is readable by users other than root. Use chmod to correct the file permissions. -'Creating metasocket failed: Address family not supported' - +`Creating metasocket failed: Address family not supported' * By default tinc tries to create both IPv4 and IPv6 sockets. On some platforms this might not be implemented. If the logs - show 'Ready' later on, then at least one metasocket was + show `Ready' later on, then at least one metasocket was created, and you can ignore this message. You can add - 'AddressFamily = ipv4' to 'tinc.conf' to prevent this from + `AddressFamily = ipv4' to `tinc.conf' to prevent this from happening. -'Cannot route packet: unknown IPv4 destination 1.2.3.4' - +`Cannot route packet: unknown IPv4 destination 1.2.3.4' * You try to send traffic to a host on the VPN for which no Subnet is known. + * If it is a broadcast address (ending in .255), it probably is a samba server or a Windows host sending broadcast packets. You can ignore it. -'Cannot route packet: ARP request for unknown address 1.2.3.4' - +`Cannot route packet: ARP request for unknown address 1.2.3.4' * You try to send traffic to a host on the VPN for which no Subnet is known. -'Packet with destination 1.2.3.4 is looping back to us!' - - * Something is not configured right. Packets are being sent out +`Packet with destination 1.2.3.4 is looping back to us!' + * Something is not configured right. Packets are being sent out to the virtual network device, but according to the Subnet directives in your host configuration file, those packets - should go to your own host. Most common mistake is that you + should go to your own host. Most common mistake is that you have a Subnet line in your host configuration file with a prefix length which is just as large as the prefix of the - virtual network interface. The latter should in almost all - cases be larger. Rethink your configuration. Note that you - will only see this message if you specified a debug level of 5 - or higher! - * Chances are that a 'Subnet = ...' line in the host - configuration file of this tinc daemon is wrong. Change it to - a subnet that is accepted locally by another interface, or if - that is not the case, try changing the prefix length into /32. + virtual network interface. The latter should in almost all + cases be larger. Rethink your configuration. Note that you + will only see this message if you specified a debug level of + 5 or higher! -'Node foo (1.2.3.4) is not reachable' + * Chances are that a `Subnet = ...' line in the host + configuration file of this tinc daemon is wrong. Change it + to a subnet that is accepted locally by another interface, or + if that is not the case, try changing the prefix length into + /32. +`Node foo (1.2.3.4) is not reachable' * Node foo does not have a connection anymore, its tinc daemon is not running or its connection to the Internet is broken. -'Received UDP packet from unknown source 1.2.3.4 (port 12345)' - +`Received UDP packet from unknown source 1.2.3.4 (port 12345)' * If you see this only sporadically, it is harmless and caused by a node sending packets using an old key. -'Got bad/bogus/unauthorized REQUEST from foo (1.2.3.4 port 12345)' + * If you see this often and another node is not reachable + anymore, then a NAT (masquerading firewall) is changing the + source address of UDP packets. You can add `TCPOnly = yes' + to host configuration files to force all VPN traffic to go + over a TCP connection. +`Got bad/bogus/unauthorized REQUEST from foo (1.2.3.4 port 12345)' * Node foo does not have the right public/private keypair. Generate new keypairs and distribute them again. + * An attacker tries to gain access to your VPN. + * A network error caused corruption of metadata sent from foo. +  File: tinc.info, Node: Sending bug reports, Prev: Error messages, Up: Running tinc @@ -1846,21 +1708,217 @@ bugreport: * A clear description of what you are trying to achieve and what the problem is. + * What platform (operating system, version, hardware architecture) and which version of tinc you use. - * If compiling tinc fails, a copy of 'config.log' and the error + + * If compiling tinc fails, a copy of `config.log' and the error messages you get. - * Otherwise, a copy of 'tinc.conf', 'tinc-up' and all files in the - 'hosts/' directory. - * The output of the commands 'ifconfig -a' and 'route -n' (or - 'netstat -rn' if that doesn't work). + + * Otherwise, a copy of `tinc.conf', `tinc-up' and all files in the + `hosts/' directory. + + * The output of the commands `ifconfig -a' and `route -n' (or + `netstat -rn' if that doesn't work). + * The output of any command that fails to work as it should (like ping or traceroute).  -File: tinc.info, Node: Technical information, Next: Platform specific information, Prev: Running tinc, Up: Top +File: tinc.info, Node: Controlling tinc, Next: Technical information, Prev: Running tinc, Up: Top -6 Technical information +6 Controlling tinc +****************** + +You can control and inspect a running tincd through the tincctl +command. A quick example: + + tincctl -n NETNAME reload + +* Menu: + +* tincctl runtime options:: +* tincctl commands:: +* tincctl examples:: +* tincctl top:: + + +File: tinc.info, Node: tincctl runtime options, Next: tincctl commands, Up: Controlling tinc + +6.1 tincctl runtime options +=========================== + +`-c, --config=PATH' + Read configuration options from the directory PATH. The default is + `/etc/tinc/NETNAME/'. + +`-n, --net=NETNAME' + Use configuration for net NETNAME. *Note Multiple networks::. + +`--pidfile=FILENAME' + Use the cookie from FILENAME to authenticate with a running tinc + daemon. If unspecified, the default is + `/var/run/tinc.NETNAME.pid'. + +`--help' + Display a short reminder of runtime options and commands, then + terminate. + +`--version' + Output version information and exit. + + + +File: tinc.info, Node: tincctl commands, Next: tincctl examples, Prev: tincctl runtime options, Up: Controlling tinc + +6.2 tincctl commands +==================== + +`start' + Start `tincd'. + +`stop' + Stop `tincd'. + +`restart' + Restart `tincd'. + +`reload' + Partially rereads configuration files. Connections to hosts whose + host config files are removed are closed. New outgoing connections + specified in `tinc.conf' will be made. + +`pid' + Shows the PID of the currently running `tincd'. + +`generate-keys [BITS]' + Generate public/private keypair of BITS length. If BITS is not + specified, 1024 is the default. tinc will ask where you want to + store the files, but will default to the configuration directory + (you can use the -c or -n option). + +`dump nodes' + Dump a list of all known nodes in the VPN. + +`dump edges' + Dump a list of all known connections in the VPN. + +`dump subnets' + Dump a list of all known subnets in the VPN. + +`dump connections' + Dump a list of all meta connections with ourself. + +`dump graph' + Dump a graph of the VPN in dotty format. + +`purge' + Purges all information remembered about unreachable nodes. + +`debug LEVEL' + Sets debug level to LEVEL. + +`retry' + Forces tinc to try to connect to all uplinks immediately. Usually + tinc attempts to do this itself, but increases the time it waits + between the attempts each time it failed, and if tinc didn't + succeed to connect to an uplink the first time after it started, + it defaults to the maximum time of 15 minutes. + +`disconnect NODE' + Closes the meta connection with the given NODE. + +`top' + If tincctl is compiled with libcurses support, this will display + live traffic statistics for all the known nodes, similar to the + UNIX top command. See below for more information. + +`pcap' + Dump VPN traffic going through the local tinc node in + pcap-savefile format to standard output, from where it can be + redirected to a file or piped through a program that can parse it + directly, such as tcpdump. + + + +File: tinc.info, Node: tincctl examples, Next: tincctl top, Prev: tincctl commands, Up: Controlling tinc + +6.3 tincctl examples +==================== + +Examples of some commands: + + tincctl -n vpn dump graph | circo -Txlib + tincctl -n vpn pcap | tcpdump -r - + tincctl -n vpn top + + +File: tinc.info, Node: tincctl top, Prev: tincctl examples, Up: Controlling tinc + +6.4 tincctl top +=============== + +The top command connects to a running tinc daemon and repeatedly +queries its per-node traffic counters. It displays a list of all the +known nodes in the left-most column, and the amount of bytes and +packets read from and sent to each node in the other columns. By +default, the information is updated every second. The behaviour of the +top command can be changed using the following keys: + + + Change the interval between updates. After pressing the key, + enter the desired interval in seconds, followed by enter. + Fractional seconds are honored. Intervals lower than 0.1 seconds + are not allowed. + + + Toggle between displaying current traffic rates (in packets and + bytes per second) and cummulative traffic (total packets and bytes + since the tinc daemon started). + + + Sort the list of nodes by name. + + + Sort the list of nodes by incoming amount of bytes. + + + Sort the list of nodes by incoming amount of packets. + + + Sort the list of nodes by outgoing amount of bytes. + + + Sort the list of nodes by outgoing amount of packets. + + + Sort the list of nodes by sum of incoming and outgoing amount of + bytes. + + + Sort the list of nodes by sum of incoming and outgoing amount of + packets. + + + Show amount of traffic in bytes. + + + Show amount of traffic in kilobytes. + + + Show amount of traffic in megabytes. + + + Show amount of traffic in gigabytes. + + + Quit. + + + +File: tinc.info, Node: Technical information, Next: Platform specific information, Prev: Controlling tinc, Up: Top + +7 Technical information *********************** * Menu: @@ -1872,7 +1930,7 @@ File: tinc.info, Node: Technical information, Next: Platform specific informat  File: tinc.info, Node: The connection, Next: The meta-protocol, Up: Technical information -6.1 The connection +7.1 The connection ================== Tinc is a daemon that takes VPN data and transmit that to another host @@ -1886,65 +1944,66 @@ computer over the existing Internet infrastructure.  File: tinc.info, Node: The UDP tunnel, Next: The meta-connection, Up: The connection -6.1.1 The UDP tunnel +7.1.1 The UDP tunnel -------------------- The data itself is read from a character device file, the so-called _virtual network device_. This device is associated with a network interface. Any data sent to this interface can be read from the device, and any data written to the device gets sent from the interface. There -are two possible types of virtual network devices: 'tun' style, which +are two possible types of virtual network devices: `tun' style, which are point-to-point devices which can only handle IPv4 and/or IPv6 -packets, and 'tap' style, which are Ethernet devices and handle complete -Ethernet frames. +packets, and `tap' style, which are Ethernet devices and handle +complete Ethernet frames. So when tinc reads an Ethernet frame from the device, it determines -its type. When tinc is in its default routing mode, it can handle IPv4 -and IPv6 packets. Depending on the Subnet lines, it will send the -packets off to their destination IP address. In the 'switch' and 'hub' +its type. When tinc is in it's default routing mode, it can handle IPv4 +and IPv6 packets. Depending on the Subnet lines, it will send the +packets off to their destination IP address. In the `switch' and `hub' mode, tinc will use broadcasts and MAC address discovery to deduce the destination of the packets. Since the latter modes only depend on the link layer information, any protocol that runs over Ethernet is -supported (for instance IPX and Appletalk). However, only 'tap' style +supported (for instance IPX and Appletalk). However, only `tap' style devices provide this information. After the destination has been determined, the packet will be compressed (optionally), a sequence number will be added to the packet, -the packet will then be encrypted and a message authentication code will -be appended. +the packet will then be encrypted and a message authentication code +will be appended. When that is done, time has come to actually transport the packet to the destination computer. We do this by sending the packet over an UDP -connection to the destination host. This is called _encapsulating_, the -VPN packet (though now encrypted) is encapsulated in another IP +connection to the destination host. This is called _encapsulating_, +the VPN packet (though now encrypted) is encapsulated in another IP datagram. When the destination receives this packet, the same thing happens, -only in reverse. So it checks the message authentication code, decrypts -the contents of the UDP datagram, checks the sequence number and writes -the decrypted information to its own virtual network device. +only in reverse. So it checks the message authentication code, +decrypts the contents of the UDP datagram, checks the sequence number +and writes the decrypted information to its own virtual network device. - If the virtual network device is a 'tun' device (a point-to-point + If the virtual network device is a `tun' device (a point-to-point tunnel), there is no problem for the kernel to accept a packet. -However, if it is a 'tap' device (this is the only available type on +However, if it is a `tap' device (this is the only available type on FreeBSD), the destination MAC address must match that of the virtual -network interface. If tinc is in its default routing mode, ARP does not -work, so the correct destination MAC can not be known by the sending -host. Tinc solves this by letting the receiving end detect the MAC -address of its own virtual network interface and overwriting the +network interface. If tinc is in it's default routing mode, ARP does +not work, so the correct destination MAC can not be known by the +sending host. Tinc solves this by letting the receiving end detect the +MAC address of its own virtual network interface and overwriting the destination MAC address of the received packet. In switch or hub modes ARP does work so the sender already knows the correct destination MAC address. In those modes every interface should have a unique MAC address, so make sure they are not the same. Because switch and hub modes rely on MAC addresses to function correctly, these -modes cannot be used on the following operating systems which don't have -a 'tap' style virtual network device: NetBSD, Darwin and Solaris. +modes cannot be used on the following operating systems which don't +have a `tap' style virtual network device: OpenBSD, NetBSD, Darwin and +Solaris.  File: tinc.info, Node: The meta-connection, Prev: The UDP tunnel, Up: The connection -6.1.2 The meta-connection +7.1.2 The meta-connection ------------------------- Having only a UDP connection available is not enough. Though suitable @@ -1954,8 +2013,8 @@ information, such as routing and session key information to somebody. TCP is a better alternative, because it already contains protection against information being lost, unlike UDP. - So we establish two connections. One for the encrypted VPN data, and -one for other information, the meta-data. Hence, we call the second + So we establish two connections. One for the encrypted VPN data, +and one for other information, the meta-data. Hence, we call the second connection the meta-connection. We can now be sure that the meta-information doesn't get lost on the way to another computer. @@ -1976,11 +2035,12 @@ re-sending packets.  File: tinc.info, Node: The meta-protocol, Next: Security, Prev: The connection, Up: Technical information -6.2 The meta-protocol +7.2 The meta-protocol ===================== -The meta protocol is used to tie all tinc daemons together, and exchange -information about which tinc daemon serves which virtual subnet. +The meta protocol is used to tie all tinc daemons together, and +exchange information about which tinc daemon serves which virtual +subnet. The meta protocol consists of requests that can be sent to the other side. Each request has a unique number and several parameters. All @@ -1990,10 +2050,10 @@ daemon started with the -bypass-security option and to read and write requests by hand, provided that one understands the numeric codes sent. The authentication scheme is described in *note Authentication -protocol::. After a successful authentication, the server and the +protocol::. After a successful authentication, the server and the client will exchange all the information about other tinc daemons and -subnets they know of, so that both sides (and all the other tinc daemons -behind them) have their information synchronised. +subnets they know of, so that both sides (and all the other tinc +daemons behind them) have their information synchronised. message ------------------------------------------------------------------ @@ -2012,11 +2072,11 @@ behind them) have their information synchronised. ------------------------------------------------------------------ The ADD_EDGE messages are to inform other tinc daemons that a -connection between two nodes exist. The address of the destination node +connection between two nodes exist. The address of the destination node is available so that VPN packets can be sent directly to that node. The ADD_SUBNET messages inform other tinc daemons that certain -subnets belong to certain nodes. tinc will use it to determine to which +subnets belong to certain nodes. tinc will use it to determine to which node a VPN packet has to be sent. message @@ -2054,12 +2114,12 @@ unreachable if there isn't any. +--> daemon that has changed it's packet key ------------------------------------------------------------------ - The keys used to encrypt VPN packets are not sent out directly. This -is because it would generate a lot of traffic on VPNs with many daemons, -and chances are that not every tinc daemon will ever send a packet to -every other daemon. Instead, if a daemon needs a key it sends a request -for it via the meta connection of the nearest hop in the direction of -the destination. + The keys used to encrypt VPN packets are not sent out directly. This +is because it would generate a lot of traffic on VPNs with many +daemons, and chances are that not every tinc daemon will ever send a +packet to every other daemon. Instead, if a daemon needs a key it sends +a request for it via the meta connection of the nearest hop in the +direction of the destination. daemon message ------------------------------------------------------------------ @@ -2067,11 +2127,11 @@ the destination. dest. PONG ------------------------------------------------------------------ - There is also a mechanism to check if hosts are still alive. Since + There is also a mechanism to check if hosts are still alive. Since network failures or a crash can cause a daemon to be killed without properly shutting down the TCP connection, this is necessary to keep an -up to date connection list. PINGs are sent at regular intervals, except -when there is also some other traffic. A little bit of salt (random +up to date connection list. PINGs are sent at regular intervals, except +when there is also some other traffic. A little bit of salt (random data) is added with each PING and PONG message, to make sure that long sequences of PING/PONG messages without any other traffic won't result in known plaintext. @@ -2081,13 +2141,13 @@ in known plaintext.  File: tinc.info, Node: Security, Prev: The meta-protocol, Up: Technical information -6.3 Security +7.3 Security ============ Tinc got its name from "TINC," short for _There Is No Cabal_; the alleged Cabal was/is an organisation that was said to keep an eye on the -entire Internet. As this is exactly what you _don't_ want, we named the -tinc project after TINC. +entire Internet. As this is exactly what you _don't_ want, we named +the tinc project after TINC. But in order to be "immune" to eavesdropping, you'll have to encrypt your data. Because tinc is a _Secure_ VPN (SVPN) daemon, it does @@ -2095,11 +2155,10 @@ exactly that: encrypt. Tinc by default uses blowfish encryption with 128 bit keys in CBC mode, 32 bit sequence numbers and 4 byte long message authentication codes to make sure eavesdroppers cannot get and cannot change any information at all from the packets they can -intercept. The encryption algorithm and message authentication -algorithm can be changed in the configuration. The length of the -message authentication codes is also adjustable. The length of the key -for the encryption algorithm is always the default length used by -LibreSSL/OpenSSL. +intercept. The encryption algorithm and message authentication +algorithm can be changed in the configuration. The length of the message +authentication codes is also adjustable. The length of the key for the +encryption algorithm is always the default length used by OpenSSL. * Menu: @@ -2110,7 +2169,7 @@ LibreSSL/OpenSSL.  File: tinc.info, Node: Authentication protocol, Next: Encryption of network packets, Up: Security -6.3.1 Authentication protocol +7.3.1 Authentication protocol ----------------------------- A new scheme for authentication in tinc has been devised, which offers @@ -2164,54 +2223,54 @@ Explanation is below. client ACK 655 123 0 | | +-> options - | +----> estimated weight - +--------> listening port of client + | +----> estimated weight + +--------> listening port of client server ACK 655 321 0 | | +-> options - | +----> estimated weight - +--------> listening port of server + | +----> estimated weight + +--------> listening port of server -------------------------------------------------------------------------- This new scheme has several improvements, both in efficiency and security. - First of all, the server sends exactly the same kind of messages over -the wire as the client. The previous versions of tinc first -authenticated the client, and then the server. This scheme even allows + First of all, the server sends exactly the same kind of messages +over the wire as the client. The previous versions of tinc first +authenticated the client, and then the server. This scheme even allows both sides to send their messages simultaneously, there is no need to wait for the other to send something first. This means that any calculations that need to be done upon sending or receiving a message -can also be done in parallel. This is especially important when doing -RSA encryption/decryption. Given that these calculations are the main +can also be done in parallel. This is especially important when doing +RSA encryption/decryption. Given that these calculations are the main part of the CPU time spent for the authentication, speed is improved by a factor 2. - Second, only one RSA encrypted message is sent instead of two. This + Second, only one RSA encrypted message is sent instead of two. This reduces the amount of information attackers can see (and thus use for a -cryptographic attack). It also improves speed by a factor two, making +cryptographic attack). It also improves speed by a factor two, making the total speedup a factor 4. Third, and most important: The symmetric cipher keys are exchanged -first, the challenge is done afterwards. In the previous authentication +first, the challenge is done afterwards. In the previous authentication scheme, because a man-in-the-middle could pass the challenge/chal_reply phase (by just copying the messages between the two real tinc daemons), -but no information was exchanged that was really needed to read the rest -of the messages, the challenge/chal_reply phase was of no real use. The -man-in-the-middle was only stopped by the fact that only after the ACK -messages were encrypted with the symmetric cipher. Potentially, it -could even send it's own symmetric key to the server (if it knew the -server's public key) and read some of the metadata the server would send -it (it was impossible for the mitm to read actual network packets -though). The new scheme however prevents this. +but no information was exchanged that was really needed to read the +rest of the messages, the challenge/chal_reply phase was of no real +use. The man-in-the-middle was only stopped by the fact that only after +the ACK messages were encrypted with the symmetric cipher. Potentially, +it could even send it's own symmetric key to the server (if it knew the +server's public key) and read some of the metadata the server would +send it (it was impossible for the mitm to read actual network packets +though). The new scheme however prevents this. This new scheme makes sure that first of all, symmetric keys are -exchanged. The rest of the messages are then encrypted with the -symmetric cipher. Then, each side can only read received messages if -they have their private key. The challenge is there to let the other +exchanged. The rest of the messages are then encrypted with the +symmetric cipher. Then, each side can only read received messages if +they have their private key. The challenge is there to let the other side know that the private key is really known, because a challenge -reply can only be sent back if the challenge is decrypted correctly, and -that can only be done with knowledge of the private key. +reply can only be sent back if the challenge is decrypted correctly, +and that can only be done with knowledge of the private key. Fourth: the first thing that is sent via the symmetric cipher encrypted connection is a totally random string, so that there is no @@ -2221,14 +2280,14 @@ stream.  File: tinc.info, Node: Encryption of network packets, Next: Security issues, Prev: Authentication protocol, Up: Security -6.3.2 Encryption of network packets +7.3.2 Encryption of network packets ----------------------------------- A data packet can only be sent if the encryption key is known to both -parties, and the connection is activated. If the encryption key is not -known, a request is sent to the destination using the meta connection to -retrieve it. The packet is stored in a queue while waiting for the key -to arrive. +parties, and the connection is activated. If the encryption key is not +known, a request is sent to the destination using the meta connection +to retrieve it. The packet is stored in a queue while waiting for the +key to arrive. The UDP packet containing the network packet from the VPN has the following layout: @@ -2240,62 +2299,61 @@ following layout: Encrypted with symmetric cipher So, the entire VPN packet is encrypted using a symmetric cipher, -including a 32 bits sequence number that is added in front of the actual -VPN packet, to act as a unique IV for each packet and to prevent replay -attacks. A message authentication code is added to the UDP packet to -prevent alteration of packets. By default the first 4 bytes of the -digest are used for this, but this can be changed using the MACLength -configuration variable. +including a 32 bits sequence number that is added in front of the +actual VPN packet, to act as a unique IV for each packet and to prevent +replay attacks. A message authentication code is added to the UDP +packet to prevent alteration of packets. By default the first 4 bytes +of the digest are used for this, but this can be changed using the +MACLength configuration variable.  File: tinc.info, Node: Security issues, Prev: Encryption of network packets, Up: Security -6.3.3 Security issues +7.3.3 Security issues --------------------- In August 2000, we discovered the existence of a security hole in all -versions of tinc up to and including 1.0pre2. This had to do with the -way we exchanged keys. Since then, we have been working on a new -authentication scheme to make tinc as secure as possible. The current -version uses the LibreSSL or OpenSSL library and uses strong -authentication with RSA keys. +versions of tinc up to and including 1.0pre2. This had to do with the +way we exchanged keys. Since then, we have been working on a new +authentication scheme to make tinc as secure as possible. The current +version uses the OpenSSL library and uses strong authentication with +RSA keys. On the 29th of December 2001, Jerome Etienne posted a security -analysis of tinc 1.0pre4. Due to a lack of sequence numbers and a +analysis of tinc 1.0pre4. Due to a lack of sequence numbers and a message authentication code for each packet, an attacker could possibly -disrupt certain network services or launch a denial of service attack by -replaying intercepted packets. The current version adds sequence +disrupt certain network services or launch a denial of service attack +by replaying intercepted packets. The current version adds sequence numbers and message authentication codes to prevent such attacks. On the 15th of September 2003, Peter Gutmann posted a security -analysis of tinc 1.0.1. He argues that the 32 bit sequence number used +analysis of tinc 1.0.1. He argues that the 32 bit sequence number used by tinc is not a good IV, that tinc's default length of 4 bytes for the MAC is too short, and he doesn't like tinc's use of RSA during -authentication. We do not know of a security hole in this version of +authentication. We do not know of a security hole in this version of tinc, but tinc's security is not as strong as TLS or IPsec. We will address these issues in tinc 2.0. - Cryptography is a hard thing to get right. We cannot make any -guarantees. Time, review and feedback are the only things that can -prove the security of any cryptographic product. If you wish to review + Cryptography is a hard thing to get right. We cannot make any +guarantees. Time, review and feedback are the only things that can +prove the security of any cryptographic product. If you wish to review tinc or give us feedback, you are stronly encouraged to do so.  File: tinc.info, Node: Platform specific information, Next: About us, Prev: Technical information, Up: Top -7 Platform specific information +8 Platform specific information ******************************* * Menu: * Interface configuration:: * Routes:: -* Automatically starting tinc::  File: tinc.info, Node: Interface configuration, Next: Routes, Up: Platform specific information -7.1 Interface configuration +8.1 Interface configuration =========================== When configuring an interface, one normally assigns it an address and a @@ -2309,140 +2367,66 @@ that it encompasses the entire VPN. For IPv4 addresses: -Linux 'ifconfig' INTERFACE ADDRESS 'netmask' NETMASK -Linux iproute2 'ip addr add' ADDRESS'/'PREFIXLENGTH 'dev' INTERFACE -FreeBSD 'ifconfig' INTERFACE ADDRESS 'netmask' NETMASK -OpenBSD 'ifconfig' INTERFACE ADDRESS 'netmask' NETMASK -NetBSD 'ifconfig' INTERFACE ADDRESS 'netmask' NETMASK -Solaris 'ifconfig' INTERFACE ADDRESS 'netmask' NETMASK -Darwin (Mac OS X) 'ifconfig' INTERFACE ADDRESS 'netmask' NETMASK -Windows 'netsh interface ip set address' INTERFACE 'static' ADDRESS NETMASK +Linux `ifconfig' INTERFACE ADDRESS `netmask' NETMASK +Linux iproute2 `ip addr add' ADDRESS`/'PREFIXLENGTH `dev' INTERFACE +FreeBSD `ifconfig' INTERFACE ADDRESS `netmask' NETMASK +OpenBSD `ifconfig' INTERFACE ADDRESS `netmask' NETMASK +NetBSD `ifconfig' INTERFACE ADDRESS `netmask' NETMASK +Solaris `ifconfig' INTERFACE ADDRESS `netmask' NETMASK +Darwin (MacOS/X) `ifconfig' INTERFACE ADDRESS `netmask' NETMASK +Windows `netsh interface ip set address' INTERFACE `static' ADDRESS NETMASK For IPv6 addresses: -Linux 'ifconfig' INTERFACE 'add' ADDRESS'/'PREFIXLENGTH -FreeBSD 'ifconfig' INTERFACE 'inet6' ADDRESS 'prefixlen' PREFIXLENGTH -OpenBSD 'ifconfig' INTERFACE 'inet6' ADDRESS 'prefixlen' PREFIXLENGTH -NetBSD 'ifconfig' INTERFACE 'inet6' ADDRESS 'prefixlen' PREFIXLENGTH -Solaris 'ifconfig' INTERFACE 'inet6 plumb up' - 'ifconfig' INTERFACE 'inet6 addif' ADDRESS ADDRESS -Darwin (Mac OS X) 'ifconfig' INTERFACE 'inet6' ADDRESS 'prefixlen' PREFIXLENGTH -Windows 'netsh interface ipv6 add address' INTERFACE 'static' ADDRESS/PREFIXLENGTH - - On Linux, it is possible to create a persistent tun/tap interface -which will continue to exist even if tinc quit, although this is -normally not required. It can be useful to set up a tun/tap interface -owned by a non-root user, so tinc can be started without needing any -root privileges at all. - -Linux 'ip tuntap add dev' INTERFACE 'mode' TUN|TAP 'user' USERNAME +Linux `ifconfig' INTERFACE `add' ADDRESS`/'PREFIXLENGTH +FreeBSD `ifconfig' INTERFACE `inet6' ADDRESS `prefixlen' PREFIXLENGTH +OpenBSD `ifconfig' INTERFACE `inet6' ADDRESS `prefixlen' PREFIXLENGTH +NetBSD `ifconfig' INTERFACE `inet6' ADDRESS `prefixlen' PREFIXLENGTH +Solaris `ifconfig' INTERFACE `inet6 plumb up' + `ifconfig' INTERFACE `inet6 addif' ADDRESS ADDRESS +Darwin (MacOS/X) `ifconfig' INTERFACE `inet6' ADDRESS `prefixlen' PREFIXLENGTH +Windows `netsh interface ipv6 add address' INTERFACE `static' ADDRESS/PREFIXLENGTH  -File: tinc.info, Node: Routes, Next: Automatically starting tinc, Prev: Interface configuration, Up: Platform specific information +File: tinc.info, Node: Routes, Prev: Interface configuration, Up: Platform specific information -7.2 Routes +8.2 Routes ========== In some cases it might be necessary to add more routes to the virtual network interface. There are two ways to indicate which interface a packet should go to, one is to use the name of the interface itself, another way is to specify the (local) address that is assigned to that -interface (LOCAL_ADDRESS). The former way is unambiguous and therefore +interface (LOCAL_ADDRESS). The former way is unambiguous and therefore preferable, but not all platforms support this. Adding routes to IPv4 subnets: -Linux 'route add -net' NETWORK_ADDRESS 'netmask' NETMASK INTERFACE -Linux iproute2 'ip route add' NETWORK_ADDRESS'/'PREFIXLENGTH 'dev' INTERFACE -FreeBSD 'route add' NETWORK_ADDRESS'/'PREFIXLENGTH LOCAL_ADDRESS -OpenBSD 'route add' NETWORK_ADDRESS'/'PREFIXLENGTH LOCAL_ADDRESS -NetBSD 'route add' NETWORK_ADDRESS'/'PREFIXLENGTH LOCAL_ADDRESS -Solaris 'route add' NETWORK_ADDRESS'/'PREFIXLENGTH LOCAL_ADDRESS '-interface' -Darwin (Mac OS X) 'route add' NETWORK_ADDRESS'/'PREFIXLENGTH '-interface' INTERFACE -Windows 'netsh routing ip add persistentroute' NETWORK_ADDRESS NETMASK INTERFACE - LOCAL_ADDRESS +Linux `route add -net' NETWORK_ADDRESS `netmask' NETMASK INTERFACE +Linux iproute2 `ip route add' NETWORK_ADDRESS`/'PREFIXLENGTH `dev' INTERFACE +FreeBSD `route add' NETWORK_ADDRESS`/'PREFIXLENGTH LOCAL_ADDRESS +OpenBSD `route add' NETWORK_ADDRESS`/'PREFIXLENGTH LOCAL_ADDRESS +NetBSD `route add' NETWORK_ADDRESS`/'PREFIXLENGTH LOCAL_ADDRESS +Solaris `route add' NETWORK_ADDRESS`/'PREFIXLENGTH LOCAL_ADDRESS `-interface' +Darwin (MacOS/X) `route add' NETWORK_ADDRESS`/'PREFIXLENGTH LOCAL_ADDRESS +Windows `netsh routing ip add persistentroute' NETWORK_ADDRESS NETMASK INTERFACE + LOCAL_ADDRESS Adding routes to IPv6 subnets: -Linux 'route add -A inet6' NETWORK_ADDRESS'/'PREFIXLENGTH INTERFACE -Linux iproute2 'ip route add' NETWORK_ADDRESS'/'PREFIXLENGTH 'dev' INTERFACE -FreeBSD 'route add -inet6' NETWORK_ADDRESS'/'PREFIXLENGTH LOCAL_ADDRESS -OpenBSD 'route add -inet6' NETWORK_ADDRESS LOCAL_ADDRESS '-prefixlen' PREFIXLENGTH -NetBSD 'route add -inet6' NETWORK_ADDRESS LOCAL_ADDRESS '-prefixlen' PREFIXLENGTH -Solaris 'route add -inet6' NETWORK_ADDRESS'/'PREFIXLENGTH LOCAL_ADDRESS '-interface' -Darwin (Mac OS X) 'route add -inet6' NETWORK_ADDRESS'/'PREFIXLENGTH '-interface' INTERFACE -Windows 'netsh interface ipv6 add route' NETWORK ADDRESS/PREFIXLENGTH INTERFACE - - -File: tinc.info, Node: Automatically starting tinc, Prev: Routes, Up: Platform specific information - -7.3 Automatically starting tinc -=============================== - -* Menu: - -* Linux:: -* Windows:: -* Other platforms:: - - -File: tinc.info, Node: Linux, Next: Windows, Up: Automatically starting tinc - -7.3.1 Linux ------------ - -There are many Linux distributions, and historically, many of them had -their own way of starting programs at boot time. Today, a number of -major Linux distributions have chosen to use systemd as their init -system. Tinc ships with systemd service files that allow you to start -and stop tinc using systemd. There are two service files: -'tinc.service' is used to globally enable or disable all tinc daemons -managed by systemd, and 'tinc@NETNAME.service' is used to enable or -disable specific tinc daemons. So if one has created a tinc network -with netname 'foo', then you have to run the following two commands to -ensure it is started at boot time: - - systemctl enable tinc - systemctl enable tinc@foo - - To start the tinc daemon immediately if it wasn't already running, -use the following command: - - systemctl start tinc@foo - - You can also use 'systemctl start tinc', this will start all tinc -daemons that are enabled. You can stop and disable tinc networks in the -same way. - - If your system is not using systemd, then you have to look up your -distribution's way of starting tinc at boot time. - - -File: tinc.info, Node: Windows, Next: Other platforms, Prev: Linux, Up: Automatically starting tinc - -7.3.2 Windows -------------- - -On Windows, if tinc is started without the '-D' or '--no-detach' option, -it will automatically register itself as a service that is started at -boot time. When tinc is stopped using the '-k' or '--kill', it will -also automatically unregister itself. Once tinc is registered as a -service, it is also possible to stop and start tinc using the Windows -Services Manager. - - -File: tinc.info, Node: Other platforms, Prev: Windows, Up: Automatically starting tinc - -7.3.3 Other platforms ---------------------- - -On platforms other than the ones mentioned in the earlier sections, you -have to look up your platform's way of starting programs at boot time. +Linux `route add -A inet6' NETWORK_ADDRESS`/'PREFIXLENGTH INTERFACE +Linux iproute2 `ip route add' NETWORK_ADDRESS`/'PREFIXLENGTH `dev' INTERFACE +FreeBSD `route add -inet6' NETWORK_ADDRESS`/'PREFIXLENGTH LOCAL_ADDRESS +OpenBSD `route add -inet6' NETWORK_ADDRESS LOCAL_ADDRESS `-prefixlen' PREFIXLENGTH +NetBSD `route add -inet6' NETWORK_ADDRESS LOCAL_ADDRESS `-prefixlen' PREFIXLENGTH +Solaris `route add -inet6' NETWORK_ADDRESS`/'PREFIXLENGTH LOCAL_ADDRESS `-interface' +Darwin (MacOS/X) ? +Windows `netsh interface ipv6 add route' NETWORK ADDRESS/PREFIXLENGTH INTERFACE  File: tinc.info, Node: About us, Next: Concept Index, Prev: Platform specific information, Up: Top -8 About us +9 About us ********** * Menu: @@ -2453,28 +2437,29 @@ File: tinc.info, Node: About us, Next: Concept Index, Prev: Platform specific  File: tinc.info, Node: Contact information, Next: Authors, Up: About us -8.1 Contact information +9.1 Contact information ======================= -Tinc's website is at , this server is located +Tinc's website is at `http://www.tinc-vpn.org/', this server is located in the Netherlands. We have an IRC channel on the FreeNode and OFTC IRC networks. -Connect to irc.freenode.net (https://freenode.net/) or irc.oftc.net -(https://www.oftc.net/) and join channel #tinc. +Connect to irc.freenode.net (http://www.freenode.net/) or irc.oftc.net +(http://www.oftc.net/) and join channel #tinc.  File: tinc.info, Node: Authors, Prev: Contact information, Up: About us -8.2 Authors +9.2 Authors =========== Ivo Timmermans (zarq) + Guus Sliepen (guus) () We have received a lot of valuable input from users. With their -help, tinc has become the flexible and robust tool that it is today. We -have composed a list of contributions, in the file called 'THANKS' in +help, tinc has become the flexible and robust tool that it is today. +We have composed a list of contributions, in the file called `THANKS' in the source distribution.  @@ -2488,13 +2473,13 @@ Concept Index * ACK: Authentication protocol. (line 10) +* ADD_EDGE: The meta-protocol. (line 23) +* ADD_SUBNET: The meta-protocol. (line 23) * Address: Host configuration variables. (line 6) * AddressFamily: Main configuration variables. (line 6) -* ADD_EDGE: The meta-protocol. (line 22) -* ADD_SUBNET: The meta-protocol. (line 22) -* ANS_KEY: The meta-protocol. (line 63) +* ANS_KEY: The meta-protocol. (line 64) * authentication: Authentication protocol. (line 6) * binary package: Building and installing tinc. @@ -2502,207 +2487,176 @@ Concept Index * BindToAddress: Main configuration variables. (line 12) * BindToInterface: Main configuration variables. - (line 25) -* Broadcast: Main configuration variables. - (line 33) + (line 19) * Cabal: Security. (line 6) -* CHALLENGE: Authentication protocol. - (line 10) * CHAL_REPLY: Authentication protocol. (line 10) +* CHALLENGE: Authentication protocol. + (line 10) * CIDR notation: Host configuration variables. - (line 93) + (line 92) * Cipher: Host configuration variables. - (line 14) + (line 12) * ClampMSS: Host configuration variables. - (line 20) + (line 18) * client: How connections work. (line 18) * command line: Runtime options. (line 9) * Compression: Host configuration variables. - (line 26) + (line 24) * connection: The connection. (line 6) * ConnectTo: Main configuration variables. - (line 53) + (line 27) * daemon: Running tinc. (line 11) * data-protocol: The meta-connection. (line 18) * debug level: Runtime options. (line 17) * debug levels: Debug levels. (line 6) -* DecrementTTL: Main configuration variables. - (line 64) -* DEL_EDGE: The meta-protocol. (line 46) -* DEL_SUBNET: The meta-protocol. (line 46) +* DEL_EDGE: The meta-protocol. (line 47) +* DEL_SUBNET: The meta-protocol. (line 47) +* DEVICE: Scripts. (line 55) * Device: Main configuration variables. - (line 73) -* DEVICE: Scripts. (line 64) + (line 38) * device files: Device files. (line 6) * DeviceType: Main configuration variables. - (line 79) + (line 45) * Digest: Host configuration variables. - (line 31) + (line 29) * DirectOnly: Main configuration variables. - (line 149) -* dummy: Main configuration variables. - (line 86) + (line 73) +* ECDSAPrivateKeyFile: Main configuration variables. + (line 80) * encapsulating: The UDP tunnel. (line 30) * encryption: Encryption of network packets. (line 6) -* environment variables: Scripts. (line 53) +* environment variables: Scripts. (line 43) * example: Example configuration. (line 6) -* exec: Main configuration variables. - (line 319) +* ExperimentalProtocol: Main configuration variables. + (line 84) * Forwarding: Main configuration variables. - (line 156) + (line 93) * frame type: The UDP tunnel. (line 6) * GraphDumpFile: Main configuration variables. - (line 176) + (line 113) * Hostnames: Main configuration variables. - (line 184) -* http: Main configuration variables. - (line 316) + (line 121) * hub: Main configuration variables. - (line 254) + (line 162) * ID: Authentication protocol. (line 10) -* IffOneQueue: Main configuration variables. - (line 195) * IndirectData: Host configuration variables. - (line 36) + (line 34) +* INTERFACE: Scripts. (line 58) * Interface: Main configuration variables. - (line 198) -* INTERFACE: Scripts. (line 67) + (line 131) * IRC: Contact information. (line 9) * key generation: Generating keypairs. (line 6) +* KEY_CHANGED: The meta-protocol. (line 64) * KeyExpire: Main configuration variables. - (line 206) -* KEY_CHANGED: The meta-protocol. (line 63) + (line 167) +* libevent: libevent. (line 6) * libraries: Libraries. (line 6) -* LibreSSL: LibreSSL/OpenSSL. (line 6) -* license: LibreSSL/OpenSSL. (line 38) -* LocalDiscovery: Main configuration variables. - (line 212) +* license: OpenSSL. (line 36) * lzo: lzo. (line 6) * MACExpire: Main configuration variables. - (line 223) + (line 173) * MACLength: Host configuration variables. - (line 44) -* MaxTimeout: Main configuration variables. - (line 228) + (line 42) * meta-protocol: The meta-connection. (line 18) * META_KEY: Authentication protocol. (line 10) * Mode: Main configuration variables. - (line 232) -* multicast: Main configuration variables. - (line 98) + (line 139) * multiple networks: Multiple networks. (line 6) +* NAME: Scripts. (line 52) * Name: Main configuration variables. - (line 259) -* NAME: Scripts. (line 61) -* netmask: Network interfaces. (line 33) + (line 178) +* netmask: Network interfaces. (line 34) +* NETNAME: Scripts. (line 49) * netname: Multiple networks. (line 6) -* NETNAME: Scripts. (line 58) * Network Administrators Guide: Configuration introduction. (line 15) -* NODE: Scripts. (line 71) -* OpenSSL: LibreSSL/OpenSSL. (line 6) +* NODE: Scripts. (line 62) +* OpenSSL: OpenSSL. (line 6) * options: Runtime options. (line 9) * PEM format: Host configuration variables. - (line 69) -* PING: The meta-protocol. (line 88) + (line 67) +* PING: The meta-protocol. (line 89) * PingInterval: Main configuration variables. - (line 270) + (line 183) * PingTimeout: Main configuration variables. - (line 274) + (line 187) * platforms: Supported platforms. (line 6) * PMTU: Host configuration variables. - (line 49) + (line 47) * PMTUDiscovery: Host configuration variables. - (line 52) -* PONG: The meta-protocol. (line 88) + (line 50) +* PONG: The meta-protocol. (line 89) * Port: Host configuration variables. - (line 57) + (line 55) * port numbers: Other files. (line 17) * PriorityInheritance: Main configuration variables. - (line 280) + (line 193) * private: Virtual Private Networks. (line 10) * PrivateKey: Main configuration variables. - (line 285) + (line 198) * PrivateKeyFile: Main configuration variables. - (line 291) + (line 204) * ProcessPriority: Main configuration variables. - (line 296) -* Proxy: Main configuration variables. - (line 301) + (line 212) * PublicKey: Host configuration variables. - (line 61) + (line 59) * PublicKeyFile: Host configuration variables. - (line 64) -* raw_socket: Main configuration variables. - (line 91) + (line 62) * release: Supported platforms. (line 14) -* REMOTEADDRESS: Scripts. (line 76) -* REMOTEPORT: Scripts. (line 79) +* REMOTEADDRESS: Scripts. (line 67) +* REMOTEPORT: Scripts. (line 70) * ReplayWindow: Main configuration variables. - (line 324) + (line 217) +* REQ_KEY: The meta-protocol. (line 64) * requirements: Libraries. (line 6) -* REQ_KEY: The meta-protocol. (line 63) * router: Main configuration variables. - (line 235) + (line 142) * runtime options: Runtime options. (line 9) * scalability: tinc. (line 19) * scripts: Scripts. (line 6) * server: How connections work. (line 18) * signals: Signals. (line 6) -* socks4: Main configuration variables. - (line 305) -* socks5: Main configuration variables. - (line 310) * StrictSubnets: Main configuration variables. - (line 335) + (line 228) +* SUBNET: Scripts. (line 74) * Subnet: Host configuration variables. - (line 76) -* SUBNET: Scripts. (line 83) -* Subnet weight: Host configuration variables. - (line 98) + (line 74) * SVPN: Security. (line 11) * switch: Main configuration variables. - (line 243) -* systemd: Linux. (line 6) + (line 151) * TCP: The meta-connection. (line 10) * TCPonly: Host configuration variables. - (line 105) -* tinc: Introduction. (line 6) + (line 104) * TINC: Security. (line 6) -* tinc-down: Scripts. (line 29) -* tinc-up: Scripts. (line 19) +* tinc: Introduction. (line 6) +* tinc-down: Scripts. (line 18) * tinc-up <1>: Network interfaces. (line 19) +* tinc-up: Scripts. (line 10) * tincd: tinc. (line 14) * traditional VPNs: tinc. (line 19) * tunifhead: Main configuration variables. - (line 133) + (line 62) * TunnelServer: Main configuration variables. - (line 342) + (line 233) * tunnohead: Main configuration variables. - (line 127) -* UDP: The UDP tunnel. (line 30) + (line 56) * UDP <1>: Encryption of network packets. (line 12) +* UDP: The UDP tunnel. (line 30) * UDPRcvBuf: Main configuration variables. - (line 349) + (line 240) * UDPSndBuf: Main configuration variables. - (line 354) -* UML: Main configuration variables. - (line 109) + (line 245) * Universal tun/tap: Configuration of Linux kernels. (line 6) -* utun: Main configuration variables. - (line 140) -* VDE: Main configuration variables. - (line 114) * virtual: Virtual Private Networks. (line 18) * virtual network device: The UDP tunnel. (line 6) @@ -2710,76 +2664,77 @@ Concept Index (line 6) * vpnd: tinc. (line 6) * website: Contact information. (line 6) -* WEIGHT: Scripts. (line 86) * zlib: zlib. (line 6)  Tag Table: -Node: Top806 -Node: Introduction1105 -Node: Virtual Private Networks1915 -Node: tinc3639 -Node: Supported platforms5166 -Node: Preparations5867 -Node: Configuring the kernel6123 -Node: Configuration of Linux kernels6533 -Node: Configuration of FreeBSD kernels7388 -Node: Configuration of OpenBSD kernels7853 -Node: Configuration of NetBSD kernels8210 -Node: Configuration of Solaris kernels8615 -Node: Configuration of Darwin (Mac OS X) kernels9278 -Node: Configuration of Windows10097 -Node: Libraries10637 -Node: LibreSSL/OpenSSL11046 -Node: zlib13588 -Node: lzo14617 -Node: Installation15600 -Node: Building and installing tinc16510 -Node: Darwin (Mac OS X) build environment17170 -Node: Cygwin (Windows) build environment17735 -Node: MinGW (Windows) build environment18324 -Node: System files18918 -Node: Device files19183 -Node: Other files19599 -Node: Configuration20212 -Node: Configuration introduction20523 -Node: Multiple networks21791 -Node: How connections work23217 -Node: Configuration files24439 -Node: Main configuration variables25933 -Node: Host configuration variables42189 -Node: Scripts47721 -Node: How to configure50987 -Node: Generating keypairs52245 -Node: Network interfaces52744 -Node: Example configuration54592 -Node: Running tinc59917 -Node: Runtime options60507 -Node: Signals64136 -Node: Debug levels65327 -Node: Solving problems66263 -Node: Error messages67815 -Node: Sending bug reports71824 -Node: Technical information72771 -Node: The connection73002 -Node: The UDP tunnel73314 -Node: The meta-connection76366 -Node: The meta-protocol77835 -Node: Security82852 -Node: Authentication protocol83994 -Node: Encryption of network packets89039 -Node: Security issues90415 -Node: Platform specific information92054 -Node: Interface configuration92314 -Node: Routes94610 -Node: Automatically starting tinc96660 -Node: Linux96883 -Node: Windows98104 -Node: Other platforms98609 -Node: About us98891 -Node: Contact information99066 -Node: Authors99469 -Node: Concept Index99874 +Node: Top811 +Node: Introduction1131 +Node: Virtual Private Networks1941 +Node: tinc3667 +Node: Supported platforms5194 +Node: Preparations5892 +Node: Configuring the kernel6148 +Node: Configuration of Linux kernels6557 +Node: Configuration of FreeBSD kernels7412 +Node: Configuration of OpenBSD kernels7802 +Node: Configuration of NetBSD kernels8410 +Node: Configuration of Solaris kernels8815 +Node: Configuration of Darwin (MacOS/X) kernels9476 +Node: Configuration of Windows10165 +Node: Libraries10679 +Node: OpenSSL11080 +Node: zlib13356 +Node: lzo14185 +Node: libevent14989 +Node: Installation15700 +Node: Building and installing tinc16715 +Node: Darwin (MacOS/X) build environment17374 +Node: Cygwin (Windows) build environment17942 +Node: MinGW (Windows) build environment18530 +Node: System files19054 +Node: Device files19319 +Node: Other files19735 +Node: Configuration20348 +Node: Configuration introduction20659 +Node: Multiple networks21932 +Node: How connections work23358 +Node: Configuration files24580 +Node: Main configuration variables25967 +Node: Host configuration variables37161 +Node: Scripts42445 +Node: How to configure45124 +Node: Generating keypairs46387 +Node: Network interfaces46899 +Node: Example configuration48747 +Node: Running tinc54083 +Node: Runtime options54668 +Node: Signals57028 +Node: Debug levels57878 +Node: Solving problems58814 +Node: Error messages60244 +Node: Sending bug reports64566 +Node: Controlling tinc65518 +Node: tincctl runtime options65881 +Node: tincctl commands66567 +Node: tincctl examples68653 +Node: tincctl top68947 +Node: Technical information70545 +Node: The connection70780 +Node: The UDP tunnel71092 +Node: The meta-connection74153 +Node: The meta-protocol75622 +Node: Security80631 +Node: Authentication protocol81761 +Node: Encryption of network packets86765 +Node: Security issues88138 +Node: Platform specific information89755 +Node: Interface configuration89983 +Node: Routes91882 +Node: About us93798 +Node: Contact information93973 +Node: Authors94377 +Node: Concept Index94782  End Tag Table diff --git a/doc/tinc.texi b/doc/tinc.texi index b1f5d9d..69e5a2b 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-2018 Ivo Timmermans, +Copyright @copyright{} 1998-2011 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-2018 Ivo Timmermans, +Copyright @copyright{} 1998-2011 Ivo Timmermans, Guus Sliepen and Wessel Dankers . @@ -65,6 +65,7 @@ permission notice identical to this one. * Installation:: * Configuration:: * Running tinc:: +* Controlling tinc:: * Technical information:: * Platform specific information:: * About us:: @@ -176,7 +177,7 @@ available too. @section Supported platforms @cindex platforms -Tinc has been verified to work under Linux, FreeBSD, OpenBSD, NetBSD, Mac OS X (Darwin), Solaris, and Windows (both natively and in a Cygwin environment), +Tinc has been verified to work under Linux, FreeBSD, OpenBSD, NetBSD, MacOS/X (Darwin), Solaris, and Windows (both natively and in a Cygwin environment), with various hardware architectures. These are some of the platforms that are supported by the universal tun/tap device driver or other virtual network device drivers. Without such a driver, tinc will most @@ -186,7 +187,7 @@ packets. @cindex release For an up to date list of supported platforms, please check the list on our website: -@uref{https://www.tinc-vpn.org/platforms/}. +@uref{http://www.tinc-vpn.org/platforms}. @c @c @@ -224,7 +225,7 @@ support tinc. * Configuration of OpenBSD kernels:: * Configuration of NetBSD kernels:: * Configuration of Solaris kernels:: -* Configuration of Darwin (Mac OS X) kernels:: +* Configuration of Darwin (MacOS/X) kernels:: * Configuration of Windows:: @end menu @@ -261,15 +262,19 @@ alias char-major-10-200 tun @subsection Configuration of FreeBSD kernels For FreeBSD version 4.1 and higher, tun and tap drivers are included in the default kernel configuration. -The tap driver can be loaded with @code{kldload if_tap}, or by adding @code{if_tap_load="YES"} to @file{/boot/loader.conf}. +Using tap devices is recommended. @c ================================================================== @node Configuration of OpenBSD kernels @subsection Configuration of OpenBSD kernels -Recent versions of OpenBSD come with both tun and tap devices enabled in the default kernel configuration. - +For OpenBSD version 2.9 and higher, +the tun driver is included in the default kernel configuration. +There is also a kernel patch from @uref{http://diehard.n-r-g.com/stuff/openbsd/} +which adds a tap device to OpenBSD which should work with tinc, +but with recent versions of OpenBSD, +a tun device can act as a tap device by setting the link0 option with ifconfig. @c ================================================================== @node Configuration of NetBSD kernels @@ -288,23 +293,24 @@ Tunneling IPv6 may not work on NetBSD's tun device. For Solaris 8 (SunOS 5.8) and higher, the tun driver may or may not be included in the default kernel configuration. If it isn't, the source can be downloaded from @uref{http://vtun.sourceforge.net/tun/}. -For x86 and sparc64 architectures, precompiled versions can be found at @uref{https://www.monkey.org/~dugsong/fragroute/}. +For x86 and sparc64 architectures, precompiled versions can be found at @uref{http://www.monkey.org/~dugsong/fragroute/}. If the @file{net/if_tun.h} header file is missing, install it from the source package. @c ================================================================== -@node Configuration of Darwin (Mac OS X) kernels -@subsection Configuration of Darwin (Mac OS X) kernels +@node Configuration of Darwin (MacOS/X) kernels +@subsection Configuration of Darwin (MacOS/X) kernels Tinc on Darwin relies on a tunnel driver for its data acquisition from the kernel. -OS X version 10.6.8 and later have a built-in tun driver called "utun". -Tinc also supports the driver from @uref{http://tuntaposx.sourceforge.net/}, -which supports both tun and tap style devices. +Tinc supports either the driver from @uref{http://tuntaposx.sourceforge.net/}, +which supports both tun and tap style devices, +and also the driver from from @uref{http://chrisp.de/en/projects/tunnel.html}. +The former driver is recommended. +The tunnel driver must be loaded before starting tinc with the following command: -By default, tinc expects the tuntaposx driver to be installed. -To use the utun driver, set add @code{Device = utunX} to @file{tinc.conf}, -where X is the desired number for the utun interface. -You can also omit the number, in which case the first free number will be chosen. +@example +kmodload tunnel +@end example @c ================================================================== @@ -312,7 +318,7 @@ You can also omit the number, in which case the first free number will be chosen @subsection Configuration of Windows You will need to install the latest TAP-Win32 driver from OpenVPN. -You can download it from @uref{https://openvpn.net/index.php/open-source/downloads.html}. +You can download it from @uref{http://openvpn.sourceforge.net}. Using the Network Connections control panel, configure the TAP-Win32 network interface in the same way as you would do from the tinc-up script, as explained in the rest of the documentation. @@ -324,51 +330,49 @@ as explained in the rest of the documentation. @cindex requirements @cindex libraries -Before you can configure or build tinc, you need to have the LibreSSL or OpenSSL, +Before you can configure or build tinc, you need to have the OpenSSL, zlib and lzo libraries installed on your system. If you try to configure tinc without having them installed, configure will give you an error message, and stop. @menu -* LibreSSL/OpenSSL:: +* OpenSSL:: * zlib:: * lzo:: +* libevent:: @end menu @c ================================================================== -@node LibreSSL/OpenSSL -@subsection LibreSSL/OpenSSL +@node OpenSSL +@subsection OpenSSL -@cindex LibreSSL @cindex OpenSSL For all cryptography-related functions, tinc uses the functions provided -by the LibreSSL or the OpenSSL library. +by the OpenSSL library. -If this library is not installed, you will get an error when configuring -tinc for build. Support for running tinc with other cryptographic libraries +If this library is not installed, you wil get an error when configuring +tinc for build. Support for running tinc without having OpenSSL installed @emph{may} be added in the future. You can use your operating system's package manager to install this if available. Make sure you install the development AND runtime versions of this package. -If your operating system comes neither with LibreSSL or OpenSSL, you have to -install one manually. It is recommended that you get the latest version of -LibreSSL from @url{http://www.libressl.org/}. Instructions on how to -configure, build and install this package are included within the package. -Please make sure you build development and runtime libraries (which is the +If you have to install OpenSSL manually, you can get the source code +from @url{http://www.openssl.org/}. Instructions on how to configure, +build and install this package are included within the package. Please +make sure you build development and runtime libraries (which is the default). -If you installed the LibreSSL or OpenSSL libraries from source, it may be necessary +If you installed the OpenSSL libraries from source, it may be necessary to let configure know where they are, by passing configure one of the ---with-openssl-* parameters. Note that you even have to use --with-openssl-* if you -are using LibreSSL. +--with-openssl-* parameters. @example ---with-openssl=DIR LibreSSL/OpenSSL library and headers prefix ---with-openssl-include=DIR LibreSSL/OpenSSL headers directory +--with-openssl=DIR OpenSSL library and headers prefix +--with-openssl-include=DIR OpenSSL headers directory (Default is OPENSSL_DIR/include) ---with-openssl-lib=DIR LibreSSL/OpenSSL library directory +--with-openssl-lib=DIR OpenSSL library directory (Default is OPENSSL_DIR/lib) @end example @@ -379,7 +383,7 @@ are using LibreSSL. The complete source code of tinc is covered by the GNU GPL version 2. Since the license under which OpenSSL is distributed is not directly compatible with the terms of the GNU GPL -@uref{https://www.openssl.org/support/faq.html#LEGAL2}, we +@uref{http://www.openssl.org/support/faq.html#LEGAL2}, we include an exemption to the GPL (see also the file COPYING.README) to allow everyone to create a statically or dynamically linked executable: @@ -395,8 +399,8 @@ we also present the following exemption: @quotation Hereby I grant a special exception to the tinc VPN project -(https://www.tinc-vpn.org/) to link the LZO library with the OpenSSL library -(https://www.openssl.org). +(http://www.tinc-vpn.org/) to link the LZO library with the OpenSSL library +(http://www.openssl.org). Markus F.X.J. Oberhumer @end quotation @@ -410,18 +414,16 @@ Markus F.X.J. Oberhumer For the optional compression of UDP packets, tinc uses the functions provided by the zlib library. -If this library is not installed, you will get an error when running the -configure script. You can either install the zlib library, or disable support -for zlib compression by using the "--disable-zlib" option when running the -configure script. Note that if you disable support for zlib, the resulting -binary will not work correctly on VPNs where zlib compression is used. +If this library is not installed, you wil get an error when configuring +tinc for build. Support for running tinc without having zlib +installed @emph{may} be added in the future. You can use your operating system's package manager to install this if available. Make sure you install the development AND runtime versions of this package. If you have to install zlib manually, you can get the source code -from @url{https://zlib.net/}. Instructions on how to configure, +from @url{http://www.gzip.org/zlib/}. Instructions on how to configure, build and install this package are included within the package. Please make sure you build development and runtime libraries (which is the default). @@ -432,20 +434,39 @@ default). @subsection lzo @cindex lzo -Another form of compression is offered using the LZO library. +Another form of compression is offered using the lzo library. -If this library is not installed, you will get an error when running the -configure script. You can either install the LZO library, or disable support -for LZO compression by using the "--disable-lzo" option when running the -configure script. Note that if you disable support for LZO, the resulting -binary will not work correctly on VPNs where LZO compression is used. +If this library is not installed, you wil get an error when configuring +tinc for build. Support for running tinc without having lzo +installed @emph{may} be added in the future. You can use your operating system's package manager to install this if available. Make sure you install the development AND runtime versions of this package. If you have to install lzo manually, you can get the source code -from @url{https://www.oberhumer.com/opensource/lzo/}. Instructions on how to configure, +from @url{http://www.oberhumer.com/opensource/lzo/}. Instructions on how to configure, +build and install this package are included within the package. Please +make sure you build development and runtime libraries (which is the +default). + + +@c ================================================================== +@node libevent +@subsection libevent + +@cindex libevent +For the main event loop, tinc uses the libevent library. + +If this library is not installed, you wil get an error when configuring +tinc for build. + +You can use your operating system's package manager to install this if +available. Make sure you install the development AND runtime versions +of this package. + +If you have to install libevent manually, you can get the source code +from @url{http://monkey.org/~provos/libevent/}. Instructions on how to configure, build and install this package are included within the package. Please make sure you build development and runtime libraries (which is the default). @@ -471,7 +492,9 @@ system startup scripts and sample configurations. If you cannot use one of the precompiled packages, or you want to compile tinc for yourself, you can use the source. The source is distributed under the GNU General Public License (GPL). Download the source from the -@uref{https://www.tinc-vpn.org/download/, download page}. +@uref{http://www.tinc-vpn.org/download, download page}, which has +the checksums of these files listed; you may wish to check these with +md5sum before continuing. Tinc comes in a convenient autoconf/automake package, which you can just treat the same as any other package. Which is just untar it, type @@ -498,28 +521,29 @@ you can use the package management tools of that distribution to install tinc. The documentation that comes along with your distribution will tell you how to do that. @menu -* Darwin (Mac OS X) build environment:: +* Darwin (MacOS/X) build environment:: * Cygwin (Windows) build environment:: * MinGW (Windows) build environment:: @end menu @c ================================================================== -@node Darwin (Mac OS X) build environment -@subsection Darwin (Mac OS X) build environment +@node Darwin (MacOS/X) build environment +@subsection Darwin (MacOS/X) build environment -In order to build tinc on Darwin, you need to install Xcode from @uref{https://developer.apple.com/xcode/}. -It might also help to install a recent version of Fink from @uref{http://www.finkproject.org/}. +In order to build tinc on Darwin, you need to install the MacOS/X Developer Tools +from @uref{http://developer.apple.com/tools/macosxtools.html} and +a recent version of Fink from @uref{http://fink.sourceforge.net/}. -You need to download and install LibreSSL (or OpenSSL) and LZO, -either directly from their websites (see @ref{Libraries}) or using Fink. +After installation use fink to download and install the following packages: +autoconf25, automake, dlcompat, m4, openssl, zlib and lzo. @c ================================================================== @node Cygwin (Windows) build environment @subsection Cygwin (Windows) build environment If Cygwin hasn't already been installed, install it directly from -@uref{https://www.cygwin.com/}. +@uref{http://www.cygwin.com/}. When tinc is compiled in a Cygwin environment, it can only be run in this environment, but all programs, including those started outside the Cygwin environment, will be able to use the VPN. @@ -530,7 +554,6 @@ It will also support all features. @subsection MinGW (Windows) build environment You will need to install the MinGW environment from @uref{http://www.mingw.org}. -You also need to download and install LibreSSL (or OpenSSL) and LZO. When tinc is compiled using MinGW it runs natively under Windows, it is not necessary to keep MinGW installed. @@ -638,7 +661,7 @@ you will not find the answers in this documentation. Make sure you have an adequate understanding of networks in general. @cindex Network Administrators Guide A good resource on networking is the -@uref{http://www.tldp.org/LDP/nag2/, Linux Network Administrators Guide}. +@uref{http://www.linuxdoc.org/LDP/nag2/, Linux Network Administrators Guide}. If you have everything clearly pictured in your mind, proceed in the following order: @@ -661,7 +684,7 @@ It is not required if you only run one tinc daemon, it doesn't even have to be the same on all the sites of your VPN, but it is recommended that you choose one anyway. -We will assume you use a netname throughout this document. +We will asume you use a netname throughout this document. This means that you call tincd with the -n argument, which will assign a netname to this daemon. @@ -689,7 +712,7 @@ reads in the configuration file tinc.conf. If it sees one or more `ConnectTo' values pointing to other tinc daemons in that file, it will try to connect to those other daemons. Whether this succeeds or not and whether `ConnectTo' is specified or not, -tinc will listen for incoming connection from other daemons. +tinc will listen for incoming connection from other deamons. If you did specify a `ConnectTo' value and the other side is not responding, tinc will keep retrying. This means that once started, tinc will stay running until you tell it to stop, @@ -713,9 +736,6 @@ The actual configuration of the daemon is done in the file @file{@value{sysconfdir}/tinc/@var{netname}/tinc.conf} and at least one other file in the directory @file{@value{sysconfdir}/tinc/@var{netname}/hosts/}. -An optional directory @file{@value{sysconfdir}/tinc/@var{netname}/conf.d} can be added from which -any .conf file will be read. - These file consists of comments (lines started with a #) or assignments in the form of @@ -759,15 +779,10 @@ If any is selected, then depending on the operating system both IPv4 and IPv6 or just IPv6 listening sockets will be created. @cindex BindToAddress -@item BindToAddress = <@var{address}> [<@var{port}>] [experimental] +@item BindToAddress = <@var{address}> [experimental] If your computer has more than one IPv4 or IPv6 address, tinc will by default listen on all of them for incoming connections. -Multiple BindToAddress variables may be specified, -in which case listening sockets for each specified address are made. - -If no @var{port} is specified, the socket will be bound to the port specified by the Port option, -or to port 655 if neither is given. -To only bind to a specific port but not to a specific address, use "*" for the @var{address}. +It is possible to bind only to a single address with this variable. This option may not work on all platforms. @@ -780,25 +795,6 @@ variable. This option may not work on all platforms. -@cindex Broadcast -@item Broadcast = (mst) [experimental] -This option selects the way broadcast packets are sent to other daemons. -@emph{NOTE: all nodes in a VPN must use the same Broadcast mode, otherwise routing loops can form.} - -@table @asis -@item no -Broadcast packets are never sent to other nodes. - -@item mst -Broadcast packets are sent and forwarded via the VPN's Minimum Spanning Tree. -This ensures broadcast packets reach all nodes. - -@item direct -Broadcast packets are sent directly to all nodes that can be reached directly. -Broadcast packets received from other nodes are never forwarded. -If the IndirectData option is also set, broadcast packets will only be sent to nodes which we have a meta connection to. -@end table - @cindex ConnectTo @item ConnectTo = <@var{name}> Specifies which other tinc daemon to connect to on startup. @@ -811,96 +807,42 @@ If you don't specify a host with ConnectTo, tinc won't try to connect to other daemons at all, and will instead just listen for incoming connections. -@cindex DecrementTTL -@item DecrementTTL = (no) [experimental] -When enabled, tinc will decrement the Time To Live field in IPv4 packets, or the Hop Limit field in IPv6 packets, -before forwarding a received packet to the virtual network device or to another node, -and will drop packets that have a TTL value of zero, -in which case it will send an ICMP Time Exceeded packet back. - -Do not use this option if you use switch mode and want to use IPv6. - @cindex Device @item Device = <@var{device}> (@file{/dev/tap0}, @file{/dev/net/tun} or other depending on platform) The virtual network device to use. Tinc will automatically detect what kind of device it is. +Note that you can only use one device per daemon. Under Windows, use @var{Interface} instead of @var{Device}. Note that you can only use one device per daemon. See also @ref{Device files}. @cindex DeviceType -@item DeviceType = <@var{type}> (platform dependent) +@item DeviceType = (only supported on BSD platforms) The type of the virtual network device. -Tinc will normally automatically select the right type of tun/tap interface, and this option should not be used. -However, this option can be used to select one of the special interface types, if support for them is compiled in. +Tinc will normally automatically select the right type, and this option should not be used. +However, in case tinc does not seem to correctly interpret packets received from the virtual network device, +using this option might help. @table @asis -@cindex dummy -@item dummy -Use a dummy interface. -No packets are ever read or written to a virtual network device. -Useful for testing, or when setting up a node that only forwards packets for other nodes. - -@cindex raw_socket -@item raw_socket -Open a raw socket, and bind it to a pre-existing -@var{Interface} (eth0 by default). -All packets are read from this interface. -Packets received for the local node are written to the raw socket. -However, at least on Linux, the operating system does not process IP packets destined for the local host. - -@cindex multicast -@item multicast -Open a multicast UDP socket and bind it to the address and port (separated by spaces) and optionally a TTL value specified using @var{Device}. -Packets are read from and written to this multicast socket. -This can be used to connect to UML, QEMU or KVM instances listening on the same multicast address. -Do NOT connect multiple tinc daemons to the same multicast address, this will very likely cause routing loops. -Also note that this can cause decrypted VPN packets to be sent out on a real network if misconfigured. - -@cindex UML -@item uml (not compiled in by default) -Create a UNIX socket with the filename specified by -@var{Device}, or @file{@value{runstatedir}/@var{netname}.umlsocket} -if not specified. -Tinc will wait for a User Mode Linux instance to connect to this socket. - -@cindex VDE -@item vde (not compiled in by default) -Uses the libvdeplug library to connect to a Virtual Distributed Ethernet switch, -using the UNIX socket specified by -@var{Device}, or @file{@value{runstatedir}/vde.ctl} -if not specified. -@end table - -Also, in case tinc does not seem to correctly interpret packets received from the virtual network device, -it can be used to change the way packets are interpreted: - -@table @asis -@item tun (BSD and Linux) +@item tun Set type to tun. Depending on the platform, this can either be with or without an address family header (see below). @cindex tunnohead -@item tunnohead (BSD) +@item tunnohead Set type to tun without an address family header. Tinc will expect packets read from the virtual network device to start with an IP header. On some platforms IPv6 packets cannot be read from or written to the device in this mode. @cindex tunifhead -@item tunifhead (BSD) +@item tunifhead Set type to tun with an address family header. Tinc will expect packets read from the virtual network device to start with a four byte header containing the address family, followed by an IP header. This mode should support both IPv4 and IPv6 packets. -@cindex utun -@item utun (OS X) -Set type to utun. -This is only supported on OS X version 10.6.8 and higher, but doesn't require the tuntaposx module. -This mode should support both IPv4 and IPv6 packets. - -@item tap (BSD and Linux) +@item tap Set type to tap. Tinc will expect packets read from the virtual network device to start with an Ethernet header. @@ -913,6 +855,21 @@ but which would have to be forwarded by an intermediate node, are dropped instea When combined with the IndirectData option, packets for nodes for which we do not have a meta connection with are also dropped. +@cindex ECDSAPrivateKeyFile +@item ECDSAPrivateKeyFile = <@var{path}> (@file{@value{sysconfdir}/tinc/@var{netname}/ecdsa_key.priv}) +The file in which the private ECDSA key of this tinc daemon resides. +This is only used if ExperimentalProtocol is enabled. + +@cindex ExperimentalProtocol +@item ExperimentalProtocol = (no) [experimental] +When this option is enabled, experimental protocol enhancements will be used. +Ephemeral ECDH will be used for key exchanges, +and ECDSA will be used instead of RSA for authentication. +When enabled, an ECDSA key must have been generated before with +@samp{tincctl generate-ecdsa-keys}. +The experimental protocol may change at any time, +and there is no guarantee that tinc will run stable when it is used. + @cindex Forwarding @item Forwarding = (internal) [experimental] This option selects the way indirect packets are forwarded. @@ -947,15 +904,11 @@ that is executed, the graph is then sent to stdin. @item Hostnames = (no) This option selects whether IP addresses (both real and on the VPN) should be resolved. Since DNS lookups are blocking, it might affect -tinc's efficiency, even stopping the daemon for a few seconds every time +tinc's efficiency, even stopping the daemon for a few seconds everytime it does a lookup if your DNS server is not responding. This does not affect resolving hostnames to IP addresses from the -configuration file, but whether hostnames should be resolved while logging. - -@cindex IffOneQueue -@item IffOneQueue = (no) [experimental] -(Linux only) Set IFF_ONE_QUEUE flag on TUN/TAP devices. +configuration file. @cindex Interface @item Interface = <@var{interface}> @@ -964,32 +917,6 @@ Depending on the operating system and the type of device this may or may not act Under Windows, this variable is used to select which network interface will be used. If you specified a Device, this variable is almost always already correctly set. -@cindex KeyExpire -@item KeyExpire = <@var{seconds}> (3600) -This option controls the time the encryption keys used to encrypt the data -are valid. It is common practice to change keys at regular intervals to -make it even harder for crackers, even though it is thought to be nearly -impossible to crack a single key. - -@cindex LocalDiscovery -@item LocalDiscovery = (no) [experimental] -When enabled, tinc will try to detect peers that are on the same local network. -This will allow direct communication using LAN addresses, even if both peers are behind a NAT -and they only ConnectTo a third node outside the NAT, -which normally would prevent the peers from learning each other's LAN address. - -Currently, local discovery is implemented by sending broadcast packets to the LAN during path MTU discovery. -This feature may not work in all possible situations. - -@cindex MACExpire -@item MACExpire = <@var{seconds}> (600) -This option controls the amount of time MAC addresses are kept before they are removed. -This only has effect when Mode is set to "switch". - -@cindex MaxTimeout -@item MaxTimeout = <@var{seconds}> (900) -This is the maximum delay before trying to reconnect to other tinc daemons. - @cindex Mode @item Mode = (router) This option selects the way packets are routed to other daemons. @@ -1019,15 +946,22 @@ every packet will be broadcast to the other daemons while no routing table is managed. @end table +@cindex KeyExpire +@item KeyExpire = <@var{seconds}> (3600) +This option controls the time the encryption keys used to encrypt the data +are valid. It is common practice to change keys at regular intervals to +make it even harder for crackers, even though it is thought to be nearly +impossible to crack a single key. + +@cindex MACExpire +@item MACExpire = <@var{seconds}> (600) +This option controls the amount of time MAC addresses are kept before they are removed. +This only has effect when Mode is set to "switch". + @cindex Name @item Name = <@var{name}> [required] This is a symbolic name for this connection. -The name must consist only of alphanumeric and underscore characters (a-z, A-Z, 0-9 and _). - -If Name starts with a $, then the contents of the environment variable that follows will be used. -In that case, invalid characters will be converted to underscores. -If Name is $HOST, but no such environment variable exist, -the hostname will be read using the gethostname() system call. +The name should consist only of alfanumeric and underscore characters (a-z, A-Z, 0-9 and _). @cindex PingInterval @item PingInterval = <@var{seconds}> (60) @@ -1049,46 +983,23 @@ will be inherited by the UDP packets that are sent out. @item PrivateKey = <@var{key}> [obsolete] This is the RSA private key for tinc. However, for safety reasons it is advised to store private keys of any kind in separate files. This prevents -accidental eavesdropping if you are editing the configuration file. +accidental eavesdropping if you are editting the configuration file. @cindex PrivateKeyFile @item PrivateKeyFile = <@var{path}> (@file{@value{sysconfdir}/tinc/@var{netname}/rsa_key.priv}) This is the full path name of the RSA private key file that was -generated by @samp{tincd --generate-keys}. It must be a full path, not a +generated by @samp{tincctl generate-keys}. It must be a full path, not a relative directory. +Note that there must be exactly one of PrivateKey +or PrivateKeyFile +specified in the configuration file. + @cindex ProcessPriority @item ProcessPriority = 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 Proxy -@item Proxy = socks4 | socks5 | http | exec @var{...} [experimental] -Use a proxy when making outgoing connections. -The following proxy types are currently supported: - -@table @asis -@cindex socks4 -@item socks4 <@var{address}> <@var{port}> [<@var{username}>] -Connects to the proxy using the SOCKS version 4 protocol. -Optionally, a @var{username} can be supplied which will be passed on to the proxy server. - -@cindex socks5 -@item socks5 <@var{address}> <@var{port}> [<@var{username}> <@var{password}>] -Connect to the proxy using the SOCKS version 5 protocol. -If a @var{username} and @var{password} are given, basic username/password authentication will be used, -otherwise no authentication will be used. - -@cindex http -@item http <@var{address}> <@var{port}> -Connects to the proxy and sends a HTTP CONNECT request. - -@cindex exec -@item exec <@var{command}> -Executes the given command which should set up the outgoing connection. -The environment variables @env{NAME}, @env{NODE}, @env{REMOTEADDRES} and @env{REMOTEPORT} are available. -@end table - @cindex ReplayWindow @item ReplayWindow = (16) This is the size of the replay tracking window for each remote node, in bytes. @@ -1100,13 +1011,12 @@ reordering. Setting this to zero will disable replay tracking completely and pass all traffic, but leaves tinc vulnerable to replay-based attacks on your traffic. + @cindex StrictSubnets -@item StrictSubnets = (no) [experimental] +@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. -Subnets learned via connections to other nodes and which are not -present in the local host config files are ignored. @cindex TunnelServer @item TunnelServer = (no) [experimental] @@ -1139,13 +1049,11 @@ 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. -Multiple Address variables can be specified, in which case each address will be -tried until a working connection has been established. @cindex Cipher -@item Cipher = <@var{cipher}> (aes-256-cbc) +@item Cipher = <@var{cipher}> (blowfish) The symmetric cipher algorithm used to encrypt UDP packets. -Any cipher supported by LibreSSL or OpenSSL is recognized. +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. @@ -1162,9 +1070,9 @@ Possible values are 0 (off), 1 (fast zlib) and any integer up to 9 (best zlib), 10 (fast lzo) and 11 (best lzo). @cindex Digest -@item Digest = <@var{digest}> (sha256) +@item Digest = <@var{digest}> (sha1) The digest algorithm used to authenticate UDP packets. -Any digest supported by LibreSSL or OpenSSL is recognized. +Any digest supported by OpenSSL is recognized. Furthermore, specifying "none" will turn off packet authentication. @cindex IndirectData @@ -1202,7 +1110,7 @@ This is the RSA public key for this host. @cindex PublicKeyFile @item PublicKeyFile = <@var{path}> [obsolete] This is the full path name of the RSA public key file that was generated -by @samp{tincd --generate-keys}. It must be a full path, not a relative +by @samp{tincctl generate-keys}. It must be a full path, not a relative directory. @cindex PEM format @@ -1216,7 +1124,7 @@ connection with that host. @cindex Subnet @item Subnet = <@var{address}[/@var{prefixlength}[#@var{weight}]]> The subnet which this tinc daemon will serve. -Tinc tries to look up which other daemon it should send a packet to by searching the appropriate subnet. +Tinc tries to look up which other daemon it should send a packet to by searching the appropiate subnet. If the packet matches a subnet, it will be sent to the daemon who has this subnet in his host configuration file. Multiple subnet lines can be specified for each daemon. @@ -1224,20 +1132,20 @@ Multiple subnet lines can be specified for each daemon. Subnets can either be single MAC, IPv4 or IPv6 addresses, in which case a subnet consisting of only that single address is assumed, or they can be a IPv4 or IPv6 network address with a prefixlength. +Shorthand notations are not supported. For example, IPv4 subnets must be in a form like 192.168.1.0/24, where 192.168.1.0 is the network address and 24 is the number of bits set in the netmask. Note that subnets like 192.168.1.1/24 are invalid! Read a networking HOWTO/FAQ/guide if you don't understand this. -IPv6 subnets are notated like fec0:0:0:1::/64. +IPv6 subnets are notated like fec0:0:0:1:0:0:0:0/64. MAC addresses are notated like 0:1a:2b:3c:4d:5e. @cindex CIDR notation Prefixlength is the number of bits set to 1 in the netmask part; for example: netmask 255.255.255.0 would become /24, 255.255.252.0 becomes /22. This conforms to standard CIDR notation as described in -@uref{https://www.ietf.org/rfc/rfc1519.txt, RFC1519} +@uref{ftp://ftp.isi.edu/in-notes/rfc1519.txt, RFC1519} -@cindex Subnet weight A Subnet can be given a weight to indicate its priority over identical Subnets owned by different nodes. The default weight is 10. Lower values indicate higher priority. Packets will be sent to the node with the highest priority, @@ -1245,15 +1153,12 @@ unless that node is not reachable, in which case the node with the next highest priority will be tried, and so on. @cindex TCPonly -@item TCPonly = (no) [deprecated] +@item TCPonly = (no) If this variable is set to yes, then the packets are tunnelled over a TCP connection instead of a UDP connection. This is especially useful for those who want to run a tinc daemon from behind a masquerading firewall, or if UDP packet routing is disabled somehow. Setting this options also implicitly sets IndirectData. - -Since version 1.0.10, tinc will automatically detect whether communication via -UDP is possible or not. @end table @@ -1264,15 +1169,7 @@ UDP is possible or not. @cindex scripts Apart from reading the server and host configuration files, tinc can also run scripts at certain moments. -Below is a list of filenames of scripts and a description of when they are run. -A script is only run if it exists and if it is executable. - -Scripts are run synchronously; -this means that tinc will temporarily stop processing packets until the called script finishes executing. -This guarantees that scripts will execute in the exact same order as the events that trigger them. -If you need to run commands asynchronously, you have to ensure yourself that they are being run in the background. - -Under Windows (not Cygwin), the scripts must have the extension .bat. +Under Windows (not Cygwin), the scripts should have the extension .bat. @table @file @cindex tinc-up @@ -1282,7 +1179,6 @@ If it is present it will be executed right after the tinc daemon has been started and has connected to the virtual network device. It should be used to set up the corresponding network interface, but can also be used to start other things. - Under Windows you can use the Network Connections control panel instead of creating this script. @cindex tinc-down @@ -1302,11 +1198,11 @@ This script is started when any host becomes reachable. This script is started when any host becomes unreachable. @item @value{sysconfdir}/tinc/@var{netname}/subnet-up -This script is started when a subnet becomes reachable. +This script is started when a Subnet becomes reachable. The Subnet and the node it belongs to are passed in environment variables. @item @value{sysconfdir}/tinc/@var{netname}/subnet-down -This script is started when a subnet becomes unreachable. +This script is started when a Subnet becomes unreachable. @end table @cindex environment variables @@ -1351,10 +1247,6 @@ this is set to the port number it uses for communication with other tinc daemons @item SUBNET When a subnet becomes (un)reachable, this is set to the subnet. -@cindex WEIGHT -@item WEIGHT -When a subnet becomes (un)reachable, this is set to the subnet weight. - @end table @@ -1377,7 +1269,7 @@ add `ConnectTo' values. @subsubheading Step 2. Creating your host configuration file -If you added a line containing `Name = yourname' in the main configuration file, +If you added a line containing `Name = yourname' in the main configuarion file, you will need to create a host configuration file @file{@value{sysconfdir}/tinc/@var{netname}/hosts/yourname}. Adapt the following example to create a host configuration file: @@ -1401,7 +1293,7 @@ Now that you have already created the main configuration file and your host conf you can easily create a public/private keypair by entering the following command: @example -tincd -n @var{netname} -K +tincctl -n @var{netname} generate-keys @end example Tinc will generate a public and a private key and ask you where to put them. @@ -1630,7 +1522,7 @@ Address = 4.5.6.7 A, B, C and D all have generated a public/private keypair with the following command: @example -tincd -n company -K +tincctl -n company generate-keys @end example The private key is stored in @file{@value{sysconfdir}/tinc/company/rsa_key.priv}, @@ -1696,12 +1588,6 @@ This will also disable the automatic restart mechanism for fatal errors. Set debug level to @var{level}. The higher the debug level, the more gets logged. Everything goes via syslog. -@item -k, --kill[=@var{signal}] -Attempt to kill a running tincd (optionally with the specified @var{signal} instead of SIGTERM) and exit. -Use it in conjunction with the -n option to make sure you kill the right tinc daemon. -Under native Windows the optional argument is ignored, -the service will always be stopped and removed. - @item -n, --net=@var{netname} Use configuration for net @var{netname}. This will let tinc read all configuration files from @@ -1709,17 +1595,10 @@ This will let tinc read all configuration files from Specifying . for @var{netname} is the same as not specifying any @var{netname}. @xref{Multiple networks}. -@item -K, --generate-keys[=@var{bits}] -Generate public/private keypair of @var{bits} length. If @var{bits} is not specified, -2048 is the default. tinc will ask where you want to store the files, -but will default to the configuration directory (you can use the -c or -n option -in combination with -K). After that, tinc will quit. - -@item -o, --option=[@var{HOST}.]@var{KEY}=@var{VALUE} -Without specifying a @var{HOST}, this will set server configuration variable @var{KEY} to @var{VALUE}. -If specified as @var{HOST}.@var{KEY}=@var{VALUE}, -this will set the host configuration variable @var{KEY} of the host named @var{HOST} to @var{VALUE}. -This option can be used more than once to specify multiple configuration variables. +@item --pidfile=@var{filename} +Store a cookie in @var{filename} which allows tincctl to authenticate. +If unspecified, the default is +@file{@value{localstatedir}/run/tinc.@var{netname}.pid}. @item -L, --mlock Lock tinc into main memory. @@ -1729,9 +1608,6 @@ This will prevent sensitive data like shared private keys to be written to the s Write log entries to a file instead of to the system logging facility. If @var{file} is omitted, the default is @file{@value{localstatedir}/log/tinc.@var{netname}.log}. -@item --pidfile=@var{file} -Write PID to @var{file} instead of @file{@value{runstatedir}/tinc.@var{netname}.pid}. - @item --bypass-security Disables encryption and authentication. Only useful for debugging. @@ -1743,14 +1619,10 @@ located (@file{@value{sysconfdir}/tinc/@var{netname}/} as determined by The chroot is performed after all the initialization is done, after writing pid files and opening network sockets. -This option is best used in combination with the -U/--user option described below. +Note that this option alone does not do any good without -U/--user, below. -You will need to ensure the chroot environment contains all the files necessary -for tinc to run correctly. -Most importantly, for tinc to be able to resolve hostnames inside the chroot environment, -you must copy @file{/etc/resolv.conf} into the chroot directory. -If you want to be able to run scripts other than @file{tinc-up} in the chroot, -you must ensure the appropriate shell is also installed in the chroot, along with all its dependencies. +Note also that tinc can't run scripts anymore (such as tinc-down or host-up), +unless it's setup to be runnable inside chroot environment. @item -U, --user=@var{user} Switch to the given @var{user} after initialization, at the same time as @@ -1789,19 +1661,6 @@ New outgoing connections specified in @file{tinc.conf} will be made. If the --logfile option is used, this will also close and reopen the log file, useful when log rotation is used. -@item INT -Temporarily increases debug level to 5. -Send this signal again to revert to the original level. - -@item USR1 -Dumps the connection list to syslog. - -@item USR2 -Dumps virtual network device statistics, all known nodes, edges and subnets to syslog. - -@item WINCH -Purges all information remembered about unreachable nodes. - @end table @c ================================================================== @@ -1865,7 +1724,7 @@ Do you have a firewall or a NAT device (a masquerading firewall or perhaps an AD If so, check that it allows TCP and UDP traffic on port 655. If it masquerades and the host running tinc is behind it, make sure that it forwards TCP and UDP traffic to port 655 to the host running tinc. You can add @samp{TCPOnly = yes} to your host config file to force tinc to only use a single TCP connection, -this works through most firewalls and NATs. Since version 1.0.10, tinc will automatically fall back to TCP if direct communication via UDP is not possible. +this works through most firewalls and NATs. @end itemize @@ -1951,7 +1810,7 @@ Note that you will only see this message if you specified a debug level of 5 or higher! @item Chances are that a @samp{Subnet = ...} line in the host configuration file of this tinc daemon is wrong. Change it to a subnet that is accepted locally by another interface, -or if that is not the case, try changing the prefix length into /32. +or if that is not the case, try changing the prefix length into /32. @end itemize @item Node foo (1.2.3.4) is not reachable @@ -1964,6 +1823,8 @@ or if that is not the case, try changing the prefix length into /32. @itemize @item If you see this only sporadically, it is harmless and caused by a node sending packets using an old key. +@item If you see this often and another node is not reachable anymore, then a NAT (masquerading firewall) is changing the source address of UDP packets. +You can add @samp{TCPOnly = yes} to host configuration files to force all VPN traffic to go over a TCP connection. @end itemize @item Got bad/bogus/unauthorized REQUEST from foo (1.2.3.4 port 12345) @@ -1994,6 +1855,198 @@ Be sure to include the following information in your bugreport: @item The output of any command that fails to work as it should (like ping or traceroute). @end itemize +@c ================================================================== +@node Controlling tinc +@chapter Controlling tinc + +You can control and inspect a running tincd through the tincctl +command. A quick example: + +@example +tincctl -n @var{netname} reload +@end example + +@menu +* tincctl runtime options:: +* tincctl commands:: +* tincctl examples:: +* tincctl top:: +@end menu + + +@c ================================================================== +@node tincctl runtime options +@section tincctl runtime options + +@c from the manpage +@table @option +@item -c, --config=@var{path} +Read configuration options from the directory @var{path}. The default is +@file{@value{sysconfdir}/tinc/@var{netname}/}. + +@item -n, --net=@var{netname} +Use configuration for net @var{netname}. @xref{Multiple networks}. + +@item --pidfile=@var{filename} +Use the cookie from @var{filename} to authenticate with a running tinc daemon. +If unspecified, the default is +@file{@value{localstatedir}/run/tinc.@var{netname}.pid}. + +@item --help +Display a short reminder of runtime options and commands, then terminate. + +@item --version +Output version information and exit. + +@end table + + +@c ================================================================== +@node tincctl commands +@section tincctl commands + +@c from the manpage +@table @code + +@item start +Start @samp{tincd}. + +@item stop +Stop @samp{tincd}. + +@item restart +Restart @samp{tincd}. + +@item reload +Partially rereads configuration files. Connections to hosts whose host +config files are removed are closed. New outgoing connections specified +in @file{tinc.conf} will be made. + +@item pid +Shows the PID of the currently running @samp{tincd}. + +@item generate-keys [@var{bits}] +Generate public/private keypair of @var{bits} length. If @var{bits} is not specified, +1024 is the default. tinc will ask where you want to store the files, +but will default to the configuration directory (you can use the -c or -n +option). + +@item dump nodes +Dump a list of all known nodes in the VPN. + +@item dump edges +Dump a list of all known connections in the VPN. + +@item dump subnets +Dump a list of all known subnets in the VPN. + +@item dump connections +Dump a list of all meta connections with ourself. + +@item dump graph +Dump a graph of the VPN in dotty format. + +@item purge +Purges all information remembered about unreachable nodes. + +@item debug @var{level} +Sets debug level to @var{level}. + +@item retry +Forces tinc to try to connect to all uplinks immediately. +Usually tinc attempts to do this itself, +but increases the time it waits between the attempts each time it failed, +and if tinc didn't succeed to connect to an uplink the first time after it started, +it defaults to the maximum time of 15 minutes. + +@item disconnect @var{node} +Closes the meta connection with the given @var{node}. + +@item top +If tincctl is compiled with libcurses support, this will display live traffic statistics for all the known nodes, +similar to the UNIX top command. +See below for more information. + +@item pcap +Dump VPN traffic going through the local tinc node in pcap-savefile format to standard output, +from where it can be redirected to a file or piped through a program that can parse it directly, +such as tcpdump. + +@end table + +@c ================================================================== +@node tincctl examples +@section tincctl examples + +Examples of some commands: + +@example +tincctl -n vpn dump graph | circo -Txlib +tincctl -n vpn pcap | tcpdump -r - +tincctl -n vpn top +@end example + +@c ================================================================== +@node tincctl top +@section tincctl top + +The top command connects to a running tinc daemon and repeatedly queries its per-node traffic counters. +It displays a list of all the known nodes in the left-most column, +and the amount of bytes and packets read from and sent to each node in the other columns. +By default, the information is updated every second. +The behaviour of the top command can be changed using the following keys: + +@table @key + +@item s +Change the interval between updates. +After pressing the @key{s} key, enter the desired interval in seconds, followed by enter. +Fractional seconds are honored. +Intervals lower than 0.1 seconds are not allowed. + +@item c +Toggle between displaying current traffic rates (in packets and bytes per second) +and cummulative traffic (total packets and bytes since the tinc daemon started). + +@item n +Sort the list of nodes by name. + +@item i +Sort the list of nodes by incoming amount of bytes. + +@item I +Sort the list of nodes by incoming amount of packets. + +@item o +Sort the list of nodes by outgoing amount of bytes. + +@item O +Sort the list of nodes by outgoing amount of packets. + +@item t +Sort the list of nodes by sum of incoming and outgoing amount of bytes. + +@item T +Sort the list of nodes by sum of incoming and outgoing amount of packets. + +@item b +Show amount of traffic in bytes. + +@item k +Show amount of traffic in kilobytes. + +@item M +Show amount of traffic in megabytes. + +@item G +Show amount of traffic in gigabytes. + +@item q +Quit. + +@end table + + @c ================================================================== @node Technical information @chapter Technical information @@ -2035,7 +2088,7 @@ There are two possible types of virtual network devices: and `tap' style, which are Ethernet devices and handle complete Ethernet frames. So when tinc reads an Ethernet frame from the device, it determines its -type. When tinc is in its default routing mode, it can handle IPv4 and IPv6 +type. When tinc is in it's default routing mode, it can handle IPv4 and IPv6 packets. Depending on the Subnet lines, it will send the packets off to their destination IP address. In the `switch' and `hub' mode, tinc will use broadcasts and MAC address discovery to deduce the destination of the packets. @@ -2066,7 +2119,7 @@ If the virtual network device is a `tun' device (a point-to-point tunnel), there is no problem for the kernel to accept a packet. However, if it is a `tap' device (this is the only available type on FreeBSD), the destination MAC address must match that of the virtual network interface. -If tinc is in its default routing mode, ARP does not work, so the correct destination MAC +If tinc is in it's default routing mode, ARP does not work, so the correct destination MAC can not be known by the sending host. Tinc solves this by letting the receiving end detect the MAC address of its own virtual network interface and overwriting the destination MAC address of the received packet. @@ -2075,7 +2128,7 @@ In switch or hub modes ARP does work so the sender already knows the correct des In those modes every interface should have a unique MAC address, so make sure they are not the same. Because switch and hub modes rely on MAC addresses to function correctly, these modes cannot be used on the following operating systems which don't have a `tap' style virtual network device: -NetBSD, Darwin and Solaris. +OpenBSD, NetBSD, Darwin and Solaris. @c ================================================================== @@ -2190,7 +2243,7 @@ message ------------------------------------------------------------------ REQ_KEY origin destination | +--> name of the tinc daemon it wants the key from - +----------> name of the daemon that wants the key + +----------> name of the daemon that wants the key ANS_KEY origin destination 4ae0b0a82d6e0078 91 64 4 | | \______________/ | | +--> MAC length @@ -2254,7 +2307,7 @@ eavesdroppers cannot get and cannot change any information at all from the packets they can intercept. The encryption algorithm and message authentication algorithm can be changed in the configuration. The length of the message authentication codes is also adjustable. The length of the key for the -encryption algorithm is always the default length used by LibreSSL/OpenSSL. +encryption algorithm is always the default length used by OpenSSL. @menu * Authentication protocol:: @@ -2325,13 +2378,13 @@ their identity. Further information is exchanged. client ACK 655 123 0 | | +-> options - | +----> estimated weight - +--------> listening port of client + | +----> estimated weight + +--------> listening port of client server ACK 655 321 0 | | +-> options - | +----> estimated weight - +--------> listening port of server + | +----> estimated weight + +--------> listening port of server -------------------------------------------------------------------------- @end example @@ -2413,7 +2466,7 @@ the MACLength configuration variable. In August 2000, we discovered the existence of a security hole in all versions of tinc up to and including 1.0pre2. This had to do with the way we exchanged keys. Since then, we have been working on a new authentication scheme to make -tinc as secure as possible. The current version uses the LibreSSL or OpenSSL library and +tinc as secure as possible. The current version uses the OpenSSL library and uses strong authentication with RSA keys. On the 29th of December 2001, Jerome Etienne posted a security analysis of tinc @@ -2443,7 +2496,6 @@ tinc or give us feedback, you are stronly encouraged to do so. @menu * Interface configuration:: * Routes:: -* Automatically starting tinc:: @end menu @c ================================================================== @@ -2460,7 +2512,7 @@ netmask should be such that it encompasses the entire VPN. For IPv4 addresses: -@multitable {Darwin (Mac OS X)} {ifconfig route add -bla network address netmask netmask prefixlength interface} +@multitable {Darwin (MacOS/X)} {ifconfig route add -bla network address netmask netmask prefixlength interface} @item Linux @tab @code{ifconfig} @var{interface} @var{address} @code{netmask} @var{netmask} @item Linux iproute2 @@ -2473,15 +2525,16 @@ For IPv4 addresses: @tab @code{ifconfig} @var{interface} @var{address} @code{netmask} @var{netmask} @item Solaris @tab @code{ifconfig} @var{interface} @var{address} @code{netmask} @var{netmask} -@item Darwin (Mac OS X) +@item Darwin (MacOS/X) @tab @code{ifconfig} @var{interface} @var{address} @code{netmask} @var{netmask} @item Windows @tab @code{netsh interface ip set address} @var{interface} @code{static} @var{address} @var{netmask} @end multitable + For IPv6 addresses: -@multitable {Darwin (Mac OS X)} {ifconfig route add -bla network address netmask netmask prefixlength interface} +@multitable {Darwin (MacOS/X)} {ifconfig route add -bla network address netmask netmask prefixlength interface} @item Linux @tab @code{ifconfig} @var{interface} @code{add} @var{address}@code{/}@var{prefixlength} @item FreeBSD @@ -2494,21 +2547,12 @@ For IPv6 addresses: @tab @code{ifconfig} @var{interface} @code{inet6 plumb up} @item @tab @code{ifconfig} @var{interface} @code{inet6 addif} @var{address} @var{address} -@item Darwin (Mac OS X) +@item Darwin (MacOS/X) @tab @code{ifconfig} @var{interface} @code{inet6} @var{address} @code{prefixlen} @var{prefixlength} @item Windows @tab @code{netsh interface ipv6 add address} @var{interface} @code{static} @var{address}/@var{prefixlength} @end multitable -On Linux, it is possible to create a persistent tun/tap interface which will -continue to exist even if tinc quit, although this is normally not required. -It can be useful to set up a tun/tap interface owned by a non-root user, so -tinc can be started without needing any root privileges at all. - -@multitable {Darwin (Mac OS X)} {ifconfig route add -bla network address netmask netmask prefixlength interface} -@item Linux -@tab @code{ip tuntap add dev} @var{interface} @code{mode} @var{tun|tap} @code{user} @var{username} -@end multitable @c ================================================================== @node Routes @@ -2523,7 +2567,7 @@ support this. Adding routes to IPv4 subnets: -@multitable {Darwin (Mac OS X)} {ifconfig route add -bla network address netmask netmask prefixlength interface} +@multitable {Darwin (MacOS/X)} {ifconfig route add -bla network address netmask netmask prefixlength interface} @item Linux @tab @code{route add -net} @var{network_address} @code{netmask} @var{netmask} @var{interface} @item Linux iproute2 @@ -2536,15 +2580,15 @@ Adding routes to IPv4 subnets: @tab @code{route add} @var{network_address}@code{/}@var{prefixlength} @var{local_address} @item Solaris @tab @code{route add} @var{network_address}@code{/}@var{prefixlength} @var{local_address} @code{-interface} -@item Darwin (Mac OS X) -@tab @code{route add} @var{network_address}@code{/}@var{prefixlength} @code{-interface} @var{interface} +@item Darwin (MacOS/X) +@tab @code{route add} @var{network_address}@code{/}@var{prefixlength} @var{local_address} @item Windows @tab @code{netsh routing ip add persistentroute} @var{network_address} @var{netmask} @var{interface} @var{local_address} @end multitable Adding routes to IPv6 subnets: -@multitable {Darwin (Mac OS X)} {ifconfig route add -bla network address netmask netmask prefixlength interface} +@multitable {Darwin (MacOS/X)} {ifconfig route add -bla network address netmask netmask prefixlength interface} @item Linux @tab @code{route add -A inet6} @var{network_address}@code{/}@var{prefixlength} @var{interface} @item Linux iproute2 @@ -2557,72 +2601,12 @@ Adding routes to IPv6 subnets: @tab @code{route add -inet6} @var{network_address} @var{local_address} @code{-prefixlen} @var{prefixlength} @item Solaris @tab @code{route add -inet6} @var{network_address}@code{/}@var{prefixlength} @var{local_address} @code{-interface} -@item Darwin (Mac OS X) -@tab @code{route add -inet6} @var{network_address}@code{/}@var{prefixlength} @code{-interface} @var{interface} +@item Darwin (MacOS/X) +@tab ? @item Windows @tab @code{netsh interface ipv6 add route} @var{network address}/@var{prefixlength} @var{interface} @end multitable -@c ================================================================== -@node Automatically starting tinc -@section Automatically starting tinc - -@menu -* Linux:: -* Windows:: -* Other platforms:: -@end menu - -@c ================================================================== -@node Linux -@subsection Linux - -@cindex systemd -There are many Linux distributions, and historically, many of them had their -own way of starting programs at boot time. Today, a number of major Linux -distributions have chosen to use systemd as their init system. Tinc ships with -systemd service files that allow you to start and stop tinc using systemd. -There are two service files: @code{tinc.service} is used to globally enable or -disable all tinc daemons managed by systemd, and -@code{tinc@@@var{netname}.service} is used to enable or disable specific tinc -daemons. So if one has created a tinc network with netname @code{foo}, then -you have to run the following two commands to ensure it is started at boot -time: - -@example -systemctl enable tinc -systemctl enable tinc@@foo -@end example - -To start the tinc daemon immediately if it wasn't already running, use the -following command: - -@example -systemctl start tinc@@foo -@end example - -You can also use @samp{systemctl start tinc}, this will start all tinc daemons -that are enabled. You can stop and disable tinc networks in the same way. - -If your system is not using systemd, then you have to look up your -distribution's way of starting tinc at boot time. - -@c ================================================================== -@node Windows -@subsection Windows - -On Windows, if tinc is started without the @code{-D} or @code{--no-detach} -option, it will automatically register itself as a service that is started at -boot time. When tinc is stopped using the @code{-k} or @code{--kill}, it will -also automatically unregister itself. Once tinc is registered as a service, it -is also possible to stop and start tinc using the Windows Services Manager. - -@c ================================================================== -@node Other platforms -@subsection Other platforms - -On platforms other than the ones mentioned in the earlier sections, you have to -look up your platform's way of starting programs at boot time. @c ================================================================== @node About us @@ -2640,14 +2624,14 @@ look up your platform's way of starting programs at boot time. @section Contact information @cindex website -Tinc's website is at @url{https://www.tinc-vpn.org/}, +Tinc's website is at @url{http://www.tinc-vpn.org/}, this server is located in the Netherlands. @cindex IRC We have an IRC channel on the FreeNode and OFTC IRC networks. Connect to -@uref{https://freenode.net/, irc.freenode.net} +@uref{http://www.freenode.net/, irc.freenode.net} or -@uref{https://www.oftc.net/, irc.oftc.net} +@uref{http://www.oftc.net/, irc.oftc.net} and join channel #tinc. diff --git a/doc/tincctl.8.in b/doc/tincctl.8.in new file mode 100644 index 0000000..bbc8dba --- /dev/null +++ b/doc/tincctl.8.in @@ -0,0 +1,194 @@ +.Dd 2011-06-25 +.Dt TINCCTL 8 +.\" Manual page created by: +.\" Scott Lamb +.Sh NAME +.Nm tincctl +.Nd tinc VPN control +.Sh SYNOPSIS +.Nm +.Op Fl cn +.Op Fl -config Ns = Ns Ar DIR +.Op Fl -net Ns = Ns Ar NETNAME +.Op Fl -pidfile Ns = Ns Ar FILENAME +.Op Fl -help +.Op Fl -version +.Ar COMMAND +.Sh DESCRIPTION +This is the control program of tinc, a secure virtual private network (VPN) +project. +.Nm +communicates with +.Xr tincd 8 +to alter and inspect the running VPN's state. +.Sh OPTIONS +.Bl -tag -width indent +.It Fl n, -net Ns = Ns Ar NETNAME +Communicate with tincd(8) connected with +.Ar NETNAME . +.It Fl -pidfile Ns = Ns Ar FILENAME +Use the cookie from +.Ar FILENAME +to authenticate with a running tinc daemon. +If unspecified, the default is +.Pa @localstatedir@/run/tinc. Ns Ar NETNAME Ns Pa .pid. +.It Fl -help +Display short list of options. +.It Fl -version +Output version information and exit. +.El +.Sh COMMANDS +.zZ +.Bl -tag -width indent +.It start +Start +.Xr tincd 8 . +.It stop +Stop +.Xr tincd 8 . +.It restart +Restart +.Xr tincd 8 . +.It reload +Partially rereads configuration files. Connections to hosts whose host +config files are removed are closed. New outgoing connections specified +in +.Xr tinc.conf 5 +will be made. +.It pid +Shows the PID of the currently running +.Xr tincd 8 . +.It generate-keys Op bits +Generate both RSA and ECDSA keypairs (see below) and exit. +.It generate-ecdsa-keys +Generate public/private ECDSA keypair and exit. +.It generate-rsa-keys Op bits +Generate public/private RSA keypair and exit. +If +.Ar bits +is omitted, the default length will be 2048 bits. +When saving keys to existing files, tinc will not delete the old keys; +you have to remove them manually. +.It dump nodes +Dump a list of all known nodes in the VPN. +.It dump edges +Dump a list of all known connections in the VPN. +.It dump subnets +Dump a list of all known subnets in the VPN. +.It dump connections +Dump a list of all meta connections with ourself. +.It dump graph +Dump a graph of the VPN in +.Xr dotty 1 +format. +.It purge +Purges all information remembered about unreachable nodes. +.It debug Ar N +Sets debug level to +.Ar N . +.It retry +Forces +.Xr tincd 8 +to try to connect to all uplinks immediately. +Usually +.Xr tincd 8 +attempts to do this itself, +but increases the time it waits between the attempts each time it failed, +and if +.Xr tincd 8 +didn't succeed to connect to an uplink the first time after it started, +it defaults to the maximum time of 15 minutes. +.It disconnect Ar NODE +Closes the meta connection with the given +.Ar NODE . +.It top +If +.Nm +is compiled with libcurses support, this will display live traffic statistics +for all the known nodes, similar to the UNIX +.Xr top 1 +command. +See below for more information. +.It pcap +Dump VPN traffic going through the local tinc node in +.Xr pcap-savefile 5 +format to standard output, +from where it can be redirected to a file or piped through a program that can parse it directly, +such as +.Xr tcpdump 8 . +.El +.Sh EXAMPLES +Examples of some commands: +.Bd -literal -offset indent +tincctl -n vpn dump graph | circo -Txlib +tincctl -n vpn pcap | tcpdump -r - +tincctl -n vpn top +.Ed +.Sh TOP +The top command connects to a running tinc daemon and repeatedly queries its per-node traffic counters. +It displays a list of all the known nodes in the left-most column, +and the amount of bytes and packets read from and sent to each node in the other columns. +By default, the information is updated every second. +The behaviour of the top command can be changed using the following keys: +.Bl -tag +.It Ic s +Change the interval between updates. +After pressing the +.Ic s +key, enter the desired interval in seconds, followed by enter. +Fractional seconds are honored. +Intervals lower than 0.1 seconds are not allowed. +.It Ic c +Toggle between displaying current traffic rates (in packets and bytes per second) +and cummulative traffic (total packets and bytes since the tinc daemon started). +.It Ic n +Sort the list of nodes by name. +.It Ic i +Sort the list of nodes by incoming amount of bytes. +.It Ic I +Sort the list of nodes by incoming amount of packets. +.It Ic o +Sort the list of nodes by outgoing amount of bytes. +.It Ic O +Sort the list of nodes by outgoing amount of packets. +.It Ic t +Sort the list of nodes by sum of incoming and outgoing amount of bytes. +.It Ic T +Sort the list of nodes by sum of incoming and outgoing amount of packets. +.It Ic b +Show amount of traffic in bytes. +.It Ic k +Show amount of traffic in kilobytes. +.It Ic M +Show amount of traffic in megabytes. +.It Ic G +Show amount of traffic in gigabytes. +.It Ic q +Quit. +.El +.Sh BUGS +If you find any bugs, report them to tinc@tinc-vpn.org. +.Sh SEE ALSO +.Xr tincd 8 , +.Xr tinc.conf 5 , +.Xr dotty 1 , +.Xr pcap-savefile 7 , +.Xr tcpdump 8 , +.Xr top 1 , +.Pa http://www.tinc-vpn.org/ , +.Pa http://www.cabal.org/ . +.Pp +The full documentation for tinc is maintained as a Texinfo manual. +If the info and tinc programs are properly installed at your site, +the command +.Ic info tinc +should give you access to the complete manual. +.Pp +tinc comes with ABSOLUTELY NO WARRANTY. +This is free software, and you are welcome to redistribute it under certain conditions; +see the file COPYING for details. +.Sh AUTHORS +.An "Ivo Timmermans" +.An "Guus Sliepen" Aq guus@tinc-vpn.org +.Pp +And thanks to many others for their contributions to tinc! diff --git a/doc/tincd.8.in b/doc/tincd.8.in index bdccf9d..bb4aa48 100644 --- a/doc/tincd.8.in +++ b/doc/tincd.8.in @@ -1,4 +1,4 @@ -.Dd 2014-05-11 +.Dd 2011-06-25 .Dt TINCD 8 .\" Manual page created by: .\" Ivo Timmermans @@ -8,17 +8,13 @@ .Nd tinc VPN daemon .Sh SYNOPSIS .Nm -.Op Fl cdDkKnoLRU +.Op Fl cdDKnLRU .Op Fl -config Ns = Ns Ar DIR .Op Fl -no-detach .Op Fl -debug Ns Op = Ns Ar LEVEL -.Op Fl -kill Ns Op = Ns Ar SIGNAL .Op Fl -net Ns = Ns Ar NETNAME -.Op Fl -generate-keys Ns Op = Ns Ar BITS -.Op Fl -option Ns = Ns Ar [HOST.]KEY=VALUE .Op Fl -mlock .Op Fl -logfile Ns Op = Ns Ar FILE -.Op Fl -pidfile Ns = Ns Ar FILE .Op Fl -bypass-security .Op Fl -chroot .Op Fl -user Ns = Ns Ar USER @@ -54,14 +50,6 @@ If not mentioned otherwise, this will show log messages on the standard error ou Increase debug level or set it to .Ar LEVEL (see below). -.It Fl k, -kill Ns Op = Ns Ar SIGNAL -Attempt to kill a running -.Nm -(optionally with the specified -.Ar SIGNAL -instead of SIGTERM) and exit. -Under Windows (not Cygwin) the optional argument is ignored, -the service will always be stopped and removed. .It Fl n, -net Ns = Ns Ar NETNAME Connect to net .Ar NETNAME . @@ -73,29 +61,6 @@ for .Ar NETNAME is the same as not specifying any .Ar NETNAME . -.It Fl K, -generate-keys Ns Op = Ns Ar BITS -Generate public/private RSA keypair and exit. -If -.Ar BITS -is omitted, the default length will be 2048 bits. -When saving keys to existing files, tinc will not delete the old keys, -you have to remove them manually. -.It Fl o, -option Ns = Ns Ar [HOST.]KEY=VALUE -Without specifying a -.Ar HOST , -this will set server configuration variable -.Ar KEY -to -.Ar VALUE . -If specified as -.Ar HOST.KEY=VALUE , -this will set the host configuration variable -.Ar KEY -of the host named -.Ar HOST -to -.Ar VALUE . -This option can be used more than once to specify multiple configuration variables. .It Fl L, -mlock Lock tinc into main memory. This will prevent sensitive data like shared private keys to be written to the system swap files/partitions. @@ -105,12 +70,16 @@ If .Ar FILE is omitted, the default is .Pa @localstatedir@/log/tinc. Ns Ar NETNAME Ns Pa .log. -.It Fl -pidfile Ns = Ns Ar FILE -Write PID to +.It Fl -pidfile Ns = Ns Ar FILENAME +Store a cookie in +.Ar FILENAME +which allows +.Xr tincctl 8 +to authenticate. +If .Ar FILE -instead of -.Pa @runstatedir@/tinc. Ns Ar NETNAME Ns Pa .pid. -Under Windows this option will be ignored. +is omitted, the default is +.Pa @localstatedir@/run/tinc. Ns Ar NETNAME Ns Pa .pid. .It Fl -bypass-security Disables encryption and authentication of the meta protocol. Only useful for debugging. @@ -151,15 +120,6 @@ If the .Fl -logfile option is used, this will also close and reopen the log file, useful when log rotation is used. -.It INT -Temporarily increases debug level to 5. -Send this signal again to revert to the original level. -.It USR1 -Dumps the connection list to syslog. -.It USR2 -Dumps virtual network device statistics, all known nodes, edges and subnets to syslog. -.It WINCH -Purges all information remembered about unreachable nodes. .El .Sh DEBUG LEVELS The tinc daemon can send a lot of messages to the syslog. @@ -190,7 +150,7 @@ This will log all network traffic over the virtual private network. Directory containing the configuration files tinc uses. For more information, see .Xr tinc.conf 5 . -.It Pa @runstatedir@/tinc. Ns Ar NETNAME Ns Pa .pid +.It Pa @localstatedir@/run/tinc. Ns Ar NETNAME Ns Pa .pid The PID of the currently running .Nm is stored in this file. @@ -206,8 +166,9 @@ If you find any bugs, report them to tinc@tinc-vpn.org. .Sh TODO A lot, especially security auditing. .Sh SEE ALSO +.Xr tincctl 8 , .Xr tinc.conf 5 , -.Pa https://www.tinc-vpn.org/ , +.Pa http://www.tinc-vpn.org/ , .Pa http://www.cabal.org/ . .Pp The full documentation for tinc is maintained as a Texinfo manual. diff --git a/doc/tincinclude.texi b/doc/tincinclude.texi deleted file mode 100644 index 93d7ad2..0000000 --- a/doc/tincinclude.texi +++ /dev/null @@ -1,5 +0,0 @@ -@set VERSION 1.0.35 -@set PACKAGE tinc -@set sysconfdir /etc -@set localstatedir /var -@set runstatedir /var/run diff --git a/doc/tincinclude.texi.in b/doc/tincinclude.texi.in index 01fee35..da4adc5 100644 --- a/doc/tincinclude.texi.in +++ b/doc/tincinclude.texi.in @@ -2,4 +2,3 @@ @set PACKAGE @PACKAGE@ @set sysconfdir @sysconfdir@ @set localstatedir @localstatedir@ -@set runstatedir @runstatedir@ diff --git a/gui/Makefile.am b/gui/Makefile.am new file mode 100644 index 0000000..4f2c7fe --- /dev/null +++ b/gui/Makefile.am @@ -0,0 +1,3 @@ +dist_bin_SCRIPTS = tinc-gui + +extra_DIST = README.gui diff --git a/systemd/Makefile.in b/gui/Makefile.in similarity index 58% rename from systemd/Makefile.in rename to gui/Makefile.in index 376a668..632fd78 100644 --- a/systemd/Makefile.in +++ b/gui/Makefile.in @@ -1,8 +1,9 @@ -# Makefile.in generated by automake 1.16.1 from Makefile.am. +# Makefile.in generated by automake 1.11.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2018 Free Software Foundation, Inc. - +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -15,61 +16,6 @@ @SET_MAKE@ VPATH = @srcdir@ -am__is_gnu_make = { \ - if test -z '$(MAKELEVEL)'; then \ - false; \ - elif test -n '$(MAKE_HOST)'; then \ - true; \ - elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ - true; \ - else \ - false; \ - fi; \ -} -am__make_running_with_option = \ - case $${target_option-} in \ - ?) ;; \ - *) echo "am__make_running_with_option: internal error: invalid" \ - "target option '$${target_option-}' specified" >&2; \ - exit 1;; \ - esac; \ - has_opt=no; \ - sane_makeflags=$$MAKEFLAGS; \ - if $(am__is_gnu_make); then \ - sane_makeflags=$$MFLAGS; \ - else \ - case $$MAKEFLAGS in \ - *\\[\ \ ]*) \ - bs=\\; \ - sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ - | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ - esac; \ - fi; \ - skip_next=no; \ - strip_trailopt () \ - { \ - flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ - }; \ - for flg in $$sane_makeflags; do \ - test $$skip_next = yes && { skip_next=no; continue; }; \ - case $$flg in \ - *=*|--*) continue;; \ - -*I) strip_trailopt 'I'; skip_next=yes;; \ - -*I?*) strip_trailopt 'I';; \ - -*O) strip_trailopt 'O'; skip_next=yes;; \ - -*O?*) strip_trailopt 'O';; \ - -*l) strip_trailopt 'l'; skip_next=yes;; \ - -*l?*) strip_trailopt 'l';; \ - -[dEDm]) skip_next=yes;; \ - -[JT]) skip_next=yes;; \ - esac; \ - case $$flg in \ - *$$target_option*) has_opt=yes; break;; \ - esac; \ - done; \ - test $$has_opt = yes -am__make_dryrun = (target_option=n; $(am__make_running_with_option)) -am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ @@ -88,42 +34,20 @@ PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ -subdir = systemd +subdir = gui +DIST_COMMON = $(dist_bin_SCRIPTS) $(srcdir)/Makefile.am \ + $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \ - $(top_srcdir)/m4/ax_append_flag.m4 \ - $(top_srcdir)/m4/ax_cflags_warn_all.m4 \ - $(top_srcdir)/m4/ax_check_compile_flag.m4 \ - $(top_srcdir)/m4/ax_check_link_flag.m4 \ - $(top_srcdir)/m4/ax_require_defined.m4 $(top_srcdir)/m4/lzo.m4 \ - $(top_srcdir)/m4/openssl.m4 $(top_srcdir)/m4/zlib.m4 \ - $(top_srcdir)/configure.ac + $(top_srcdir)/m4/curses.m4 $(top_srcdir)/m4/libevent.m4 \ + $(top_srcdir)/m4/lzo.m4 $(top_srcdir)/m4/openssl.m4 \ + $(top_srcdir)/m4/zlib.m4 $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) -DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = -AM_V_P = $(am__v_P_@AM_V@) -am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) -am__v_P_0 = false -am__v_P_1 = : -AM_V_GEN = $(am__v_GEN_@AM_V@) -am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) -am__v_GEN_0 = @echo " GEN " $@; -am__v_GEN_1 = -AM_V_at = $(am__v_at_@AM_V@) -am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) -am__v_at_0 = @ -am__v_at_1 = -SOURCES = -DIST_SOURCES = -am__can_run_installinfo = \ - case $$AM_UPDATE_INFO_DIR in \ - n|no|NO) false;; \ - *) (install-info --version) >/dev/null 2>&1;; \ - esac am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ @@ -145,20 +69,13 @@ am__nobase_list = $(am__nobase_strip_setup); \ am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' -am__uninstall_files_from_dir = { \ - test -z "$$files" \ - || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ - || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ - $(am__cd) "$$dir" && rm -f $$files; }; \ - } -am__installdirs = "$(DESTDIR)$(systemddir)" -DATA = $(nodist_systemd_DATA) -am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) -am__DIST_COMMON = $(srcdir)/Makefile.in +am__installdirs = "$(DESTDIR)$(bindir)" +SCRIPTS = $(dist_bin_SCRIPTS) +SOURCES = +DIST_SOURCES = DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ -AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ @@ -168,6 +85,7 @@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ +CURSES_LIBS = @CURSES_LIBS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ @@ -177,15 +95,21 @@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ GREP = @GREP@ +INCLUDES = @INCLUDES@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ +LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ +LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ +LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ +LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ OBJEXT = @OBJEXT@ @@ -197,6 +121,7 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ @@ -243,28 +168,20 @@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ -runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ -systemd_path = @systemd_path@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ -EXTRA_DIST = tinc.service.in tinc@.service.in -CLEANFILES = tinc.service tinc@.service -@WITH_SYSTEMD_TRUE@systemddir = @systemd_path@ -@WITH_SYSTEMD_TRUE@nodist_systemd_DATA = tinc.service tinc@.service -substitute = sed \ - -e s,'@sbindir\@',"$(sbindir)",g \ - -e s,'@sysconfdir\@',"$(sysconfdir)",g - +dist_bin_SCRIPTS = tinc-gui +extra_DIST = README.gui all: all-am .SUFFIXES: -$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ @@ -273,58 +190,69 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) exit 1;; \ esac; \ done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu systemd/Makefile'; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu gui/Makefile'; \ $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --gnu systemd/Makefile + $(AUTOMAKE) --gnu gui/Makefile +.PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(top_srcdir)/configure: $(am__configure_deps) +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(ACLOCAL_M4): $(am__aclocal_m4_deps) +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): -install-nodist_systemdDATA: $(nodist_systemd_DATA) +install-dist_binSCRIPTS: $(dist_bin_SCRIPTS) @$(NORMAL_INSTALL) - @list='$(nodist_systemd_DATA)'; test -n "$(systemddir)" || list=; \ - if test -n "$$list"; then \ - echo " $(MKDIR_P) '$(DESTDIR)$(systemddir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(systemddir)" || exit 1; \ - fi; \ + test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)" + @list='$(dist_bin_SCRIPTS)'; test -n "$(bindir)" || list=; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ - echo "$$d$$p"; \ - done | $(am__base_list) | \ - while read files; do \ - echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(systemddir)'"; \ - $(INSTALL_DATA) $$files "$(DESTDIR)$(systemddir)" || exit $$?; \ - done + if test -f "$$d$$p"; then echo "$$d$$p"; echo "$$p"; else :; fi; \ + done | \ + sed -e 'p;s,.*/,,;n' \ + -e 'h;s|.*|.|' \ + -e 'p;x;s,.*/,,;$(transform)' | sed 'N;N;N;s,\n, ,g' | \ + $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1; } \ + { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ + if ($$2 == $$4) { files[d] = files[d] " " $$1; \ + if (++n[d] == $(am__install_max)) { \ + print "f", d, files[d]; n[d] = 0; files[d] = "" } } \ + else { print "f", d "/" $$4, $$1 } } \ + END { for (d in files) print "f", d, files[d] }' | \ + while read type dir files; do \ + if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ + test -z "$$files" || { \ + echo " $(INSTALL_SCRIPT) $$files '$(DESTDIR)$(bindir)$$dir'"; \ + $(INSTALL_SCRIPT) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ + } \ + ; done -uninstall-nodist_systemdDATA: +uninstall-dist_binSCRIPTS: @$(NORMAL_UNINSTALL) - @list='$(nodist_systemd_DATA)'; test -n "$(systemddir)" || list=; \ - files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ - dir='$(DESTDIR)$(systemddir)'; $(am__uninstall_files_from_dir) -tags TAGS: + @list='$(dist_bin_SCRIPTS)'; test -n "$(bindir)" || exit 0; \ + files=`for p in $$list; do echo "$$p"; done | \ + sed -e 's,.*/,,;$(transform)'`; \ + test -n "$$list" || exit 0; \ + echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(bindir)" && rm -f $$files +tags: TAGS +TAGS: -ctags CTAGS: - -cscope cscopelist: +ctags: CTAGS +CTAGS: -distdir: $(BUILT_SOURCES) - $(MAKE) $(AM_MAKEFLAGS) distdir-am - -distdir-am: $(DISTFILES) +distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ @@ -356,9 +284,9 @@ distdir-am: $(DISTFILES) done check-am: all-am check: check-am -all-am: Makefile $(DATA) +all-am: Makefile $(SCRIPTS) installdirs: - for dir in "$(DESTDIR)$(systemddir)"; do \ + for dir in "$(DESTDIR)$(bindir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am @@ -371,19 +299,13 @@ install-am: all-am installcheck: installcheck-am install-strip: - if test -z '$(STRIP)'; then \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - install; \ - else \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ - fi + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: - -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) @@ -412,13 +334,13 @@ info: info-am info-am: -install-data-am: install-nodist_systemdDATA +install-data-am: install-dvi: install-dvi-am install-dvi-am: -install-exec-am: +install-exec-am: install-dist_binSCRIPTS install-html: install-html-am @@ -456,30 +378,22 @@ ps: ps-am ps-am: -uninstall-am: uninstall-nodist_systemdDATA +uninstall-am: uninstall-dist_binSCRIPTS .MAKE: install-am install-strip -.PHONY: all all-am check check-am clean clean-generic cscopelist-am \ - ctags-am distclean distclean-generic distdir dvi dvi-am html \ - html-am info info-am install install-am install-data \ - install-data-am install-dvi install-dvi-am install-exec \ - install-exec-am install-html install-html-am install-info \ - install-info-am install-man install-nodist_systemdDATA \ - install-pdf install-pdf-am install-ps install-ps-am \ - install-strip installcheck installcheck-am installdirs \ - maintainer-clean maintainer-clean-generic mostlyclean \ - mostlyclean-generic pdf pdf-am ps ps-am tags-am uninstall \ - uninstall-am uninstall-nodist_systemdDATA +.PHONY: all all-am check check-am clean clean-generic distclean \ + distclean-generic distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am \ + install-dist_binSCRIPTS install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-ps install-ps-am install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-generic pdf \ + pdf-am ps ps-am uninstall uninstall-am \ + uninstall-dist_binSCRIPTS -.PRECIOUS: Makefile - - -tinc.service: $(srcdir)/tinc.service.in - $(AM_V_GEN)$(substitute) $(srcdir)/tinc.service.in > $@ - -tinc@.service: $(srcdir)/tinc@.service.in - $(AM_V_GEN)$(substitute) $(srcdir)/tinc@.service.in > $@ # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. diff --git a/gui/tinc-gui b/gui/tinc-gui new file mode 100755 index 0000000..c0f1cb1 --- /dev/null +++ b/gui/tinc-gui @@ -0,0 +1,537 @@ +#!/usr/bin/python + +import string +import socket +import wx +import sys +from wx.lib.mixins.listctrl import ColumnSorterMixin +from wx.lib.mixins.listctrl import ListCtrlAutoWidthMixin + +# Classes to interface with a running tinc daemon + +REQ_STOP = 0 +REQ_RELOAD = 1 +REQ_RESTART = 2 +REQ_DUMP_NODES = 3 +REQ_DUMP_EDGES = 4 +REQ_DUMP_SUBNETS = 5 +REQ_DUMP_CONNECTIONS = 6 +REQ_DUMP_GRAPH = 7 +REQ_PURGE = 8 +REQ_SET_DEBUG = 9 +REQ_RETRY = 10 +REQ_CONNECT = 11 +REQ_DISCONNECT = 12 + +ID = 0 +ACK = 4 +CONTROL = 18 + +class Node: + def parse(self, args): + self.name = args[0] + self.address = args[2] + if args[3] != 'port': + args.insert(3, 'port') + args.insert(4, '') + self.port = args[4] + self.cipher = int(args[6]) + self.digest = int(args[8]) + self.maclength = int(args[10]) + self.compression = int(args[12]) + self.options = int(args[14], 0x10) + self.status = int(args[16], 0x10) + self.nexthop = args[18] + self.via = args[20] + self.distance = int(args[22]) + self.pmtu = int(args[24]) + self.minmtu = int(args[26]) + self.maxmtu = int(args[28][:-1]) + + self.subnets = {} + +class Edge: + def parse(self, args): + self.fr = args[0] + self.to = args[2] + self.address = args[4] + self.port = args[6] + self.options = int(args[8], 16) + self.weight = int(args[10]) + +class Subnet: + def parse(self, args): + if args[0].find('#') >= 0: + (address, self.weight) = args[0].split('#', 1) + else: + self.weight = 10 + address = args[0] + + if address.find('/') >= 0: + (self.address, self.prefixlen) = address.split('/', 1) + else: + self.address = address + self.prefixlen = '48' + + self.owner = args[2] + +class Connection: + def parse(self, args): + self.name = args[0] + self.address = args[2] + if args[3] != 'port': + args.insert(3, 'port') + args.insert(4, '') + self.port = args[4] + self.options = int(args[6], 0x10) + self.socket = int(args[8]) + self.status = int(args[10], 0x10) + self.weight = 123 + +class VPN: + confdir = '/etc/tinc' + piddir = '/var/run/' + + def connect(self): + f = open(self.pidfile) + info = string.split(f.readline()) + f.close() + s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + s.connect((info[2], int(info[4]))) + self.sf = s.makefile() + s.close() + hello = string.split(self.sf.readline()) + self.name = hello[1] + self.sf.write('0 ^' + info[1] + ' 17\r\n') + self.sf.flush() + resp = string.split(self.sf.readline()) + self.port = info[4] + self.nodes = {} + self.edges = {} + self.subnets = {} + self.connections = {} + self.refresh() + + def refresh(self): + self.sf.write('18 3\r\n18 4\r\n18 5\r\n18 6\r\n') + self.sf.flush() + + for node in self.nodes.values(): + node.visited = False + for edge in self.edges.values(): + edge.visited = False + for subnet in self.subnets.values(): + subnet.visited = False + for connections in self.connections.values(): + connections.visited = False + + while True: + resp = string.split(self.sf.readline()) + if len(resp) < 2: + break + if resp[0] != '18': + break + if resp[1] == '3': + if len(resp) < 3: + continue + node = self.nodes.get(resp[2]) or Node() + node.parse(resp[2:]) + node.visited = True + self.nodes[resp[2]] = node + elif resp[1] == '4': + if len(resp) < 5: + continue + edge = self.nodes.get((resp[2], resp[4])) or Edge() + edge.parse(resp[2:]) + edge.visited = True + self.edges[(resp[2], resp[4])] = edge + elif resp[1] == '5': + if len(resp) < 5: + continue + subnet = self.subnets.get((resp[2], resp[4])) or Subnet() + subnet.parse(resp[2:]) + subnet.visited = True + self.subnets[(resp[2], resp[4])] = subnet + self.nodes[subnet.owner].subnets[resp[2]] = subnet + elif resp[1] == '6': + if len(resp) < 5: + break + connection = self.connections.get((resp[2], resp[4])) or Connection() + connection.parse(resp[2:]) + connection.visited = True + self.connections[(resp[2], resp[4])] = connection + else: + break + + for key, subnet in self.subnets.items(): + if not subnet.visited: + del self.subnets[key] + + for key, edge in self.edges.items(): + if not edge.visited: + del self.edges[key] + + for key, node in self.nodes.items(): + if not node.visited: + del self.nodes[key] + else: + for key, subnet in node.subnets.items(): + if not subnet.visited: + del node.subnets[key] + + for key, connection in self.connections.items(): + if not connection.visited: + del self.connections[key] + + def close(self): + self.sf.close() + + def disconnect(self, name): + self.sf.write('18 12 ' + name + '\r\n') + self.sf.flush() + resp = string.split(self.sf.readline()) + + def debug(self, level = -1): + self.sf.write('18 9 ' + str(level) + '\r\n') + self.sf.flush() + resp = string.split(self.sf.readline()) + return int(resp[2]) + + def __init__(self, netname = None, pidfile = None): + self.tincconf = VPN.confdir + '/' + + if netname: + self.netname = netname + self.tincconf += netname + '/' + + self.tincconf += 'tinc.conf' + + if pidfile is not None: + self.pidfile = pidfile + else: + self.pidfile = VPN.piddir + 'tinc.' + if netname: + self.pidfile += netname + '.' + self.pidfile += 'pid' + +# GUI starts here + +argv0 = sys.argv[0] +del sys.argv[0] +net = None +pidfile = None + +def usage(exitcode = 0): + print('Usage: ' + argv0 + ' [options]') + print('\nValid options are:') + print(' -n, --net=NETNAME Connect to net NETNAME.') + print(' --pidfile=FILENAME Read control cookie from FILENAME.') + print(' --help Display this help and exit.') + print('\nReport bugs to tinc@tinc-vpn.org.') + sys.exit(exitcode) + +while len(sys.argv): + if sys.argv[0] in ('-n', '--net'): + del sys.argv[0] + net = sys.argv[0] + elif sys.argv[0] in ('--pidfile'): + del sys.argv[0] + pidfile = sys.argv[0] + elif sys.argv[0] in ('--help'): + usage(0) + else: + print(argv0 + ': unrecognized option \'' + sys.argv[0] + '\'') + usage(1) + + del sys.argv[0] + +vpn = VPN(net, pidfile) +vpn.connect() + +class SuperListCtrl(wx.ListCtrl, ColumnSorterMixin, ListCtrlAutoWidthMixin): + def __init__(self, parent, style): + wx.ListCtrl.__init__(self, parent, -1, style=wx.LC_REPORT | wx.LC_HRULES | wx.LC_VRULES) + ListCtrlAutoWidthMixin.__init__(self) + ColumnSorterMixin.__init__(self, 14) + + def GetListCtrl(self): + return self + + +class SettingsPage(wx.Panel): + def OnDebugLevel(self, event): + vpn.debug(self.debug.GetValue()) + + def __init__(self, parent, id): + wx.Panel.__init__(self, parent, id) + grid = wx.FlexGridSizer(cols = 2) + grid.AddGrowableCol(0, 1) + + namelabel = wx.StaticText(self, -1, 'Name:') + self.name = wx.TextCtrl(self, -1, vpn.name) + grid.Add(namelabel) + grid.Add(self.name) + + portlabel = wx.StaticText(self, -1, 'Port:') + self.port = wx.TextCtrl(self, -1, vpn.port) + grid.Add(portlabel) + grid.Add(self.port) + + debuglabel = wx.StaticText(self, -1, 'Debug level:') + self.debug = wx.SpinCtrl(self, min = 0, max = 5, initial = vpn.debug()) + self.debug.Bind(wx.EVT_SPINCTRL, self.OnDebugLevel) + grid.Add(debuglabel) + grid.Add(self.debug) + + modelabel = wx.StaticText(self, -1, 'Mode:') + self.mode = wx.ComboBox(self, -1, style = wx.CB_READONLY, value = 'Router', choices = ['Router', 'Switch', 'Hub']) + grid.Add(modelabel) + grid.Add(self.mode) + + self.SetSizer(grid) + +class ConnectionsPage(wx.Panel): + def __init__(self, parent, id): + wx.Panel.__init__(self, parent, id) + self.list = wx.ListCtrl(self, id, style=wx.LC_REPORT | wx.LC_HRULES | wx.LC_VRULES) + self.list.InsertColumn(0, 'Name') + self.list.InsertColumn(1, 'Address') + self.list.InsertColumn(2, 'Port') + self.list.InsertColumn(3, 'Options') + self.list.InsertColumn(4, 'Weight') + + hbox = wx.BoxSizer(wx.HORIZONTAL) + hbox.Add(self.list, 1, wx.EXPAND) + self.SetSizer(hbox) + self.refresh() + + class ContextMenu(wx.Menu): + def __init__(self, item): + wx.Menu.__init__(self) + + self.item = item + + disconnect = wx.MenuItem(self, -1, 'Disconnect') + self.AppendItem(disconnect) + self.Bind(wx.EVT_MENU, self.OnDisconnect, id=disconnect.GetId()) + + def OnDisconnect(self, event): + vpn.disconnect(self.item[0]) + + def OnContext(self, event): + i = event.GetIndex() + self.PopupMenu(self.ContextMenu(self.list.itemDataMap[event.GetIndex()]), event.GetPosition()) + + def refresh(self): + self.list.itemDataMap = {} + i = 0 + + for key, connection in vpn.connections.items(): + if self.list.GetItemCount() <= i: + self.list.InsertStringItem(i, connection.name) + else: + self.list.SetStringItem(i, 0, connection.name) + self.list.SetStringItem(i, 1, connection.address) + self.list.SetStringItem(i, 2, connection.port) + self.list.SetStringItem(i, 3, str(connection.options)) + self.list.SetStringItem(i, 4, str(connection.weight)) + self.list.itemDataMap[i] = (connection.name, connection.address, connection.port, connection.options, connection.weight) + self.list.Bind(wx.EVT_LIST_ITEM_RIGHT_CLICK, self.OnContext) + i += 1 + + while self.list.GetItemCount() > i: + self.list.DeleteItem(self.list.GetItemCount() - 1) + + +class NodesPage(wx.Panel): + def __init__(self, parent, id): + wx.Panel.__init__(self, parent, id) + self.list = SuperListCtrl(self, id) + self.list.InsertColumn( 0, 'Name') + self.list.InsertColumn( 1, 'Address') + self.list.InsertColumn( 2, 'Port') + self.list.InsertColumn( 3, 'Cipher') + self.list.InsertColumn( 4, 'Digest') + self.list.InsertColumn( 5, 'MACLength') + self.list.InsertColumn( 6, 'Compression') + self.list.InsertColumn( 7, 'Options') + self.list.InsertColumn( 8, 'Status') + self.list.InsertColumn( 9, 'Nexthop') + self.list.InsertColumn(10, 'Via') + self.list.InsertColumn(11, 'Distance') + self.list.InsertColumn(12, 'PMTU') + self.list.InsertColumn(13, 'Min MTU') + self.list.InsertColumn(14, 'Max MTU') + + hbox = wx.BoxSizer(wx.HORIZONTAL) + hbox.Add(self.list, 1, wx.EXPAND) + self.SetSizer(hbox) + self.refresh() + + def refresh(self): + self.list.itemDataMap = {} + i = 0 + + for key, node in vpn.nodes.items(): + if self.list.GetItemCount() <= i: + self.list.InsertStringItem(i, node.name) + else: + self.list.SetStringItem(i, 0, node.name) + self.list.SetStringItem(i, 1, node.address) + self.list.SetStringItem(i, 2, node.port) + self.list.SetStringItem(i, 3, str(node.cipher)) + self.list.SetStringItem(i, 4, str(node.digest)) + self.list.SetStringItem(i, 5, str(node.maclength)) + self.list.SetStringItem(i, 6, str(node.compression)) + self.list.SetStringItem(i, 7, str(node.options)) + self.list.SetStringItem(i, 8, str(node.status)) + self.list.SetStringItem(i, 9, node.nexthop) + self.list.SetStringItem(i, 10, node.via) + self.list.SetStringItem(i, 11, str(node.distance)) + self.list.SetStringItem(i, 12, str(node.pmtu)) + self.list.SetStringItem(i, 13, str(node.minmtu)) + self.list.SetStringItem(i, 14, str(node.maxmtu)) + self.list.itemDataMap[i] = (node.name, node.address, node.port, node.cipher, node.digest, node.maclength, node.compression, node.options, node.status, node.nexthop, node.via, node.distance, node.pmtu, node.minmtu, node.maxmtu) + self.list.SetItemData(i, i) + i += 1 + + while self.list.GetItemCount() > i: + self.list.DeleteItem(self.list.GetItemCount() - 1) + +class EdgesPage(wx.Panel): + def __init__(self, parent, id): + wx.Panel.__init__(self, parent, id) + self.list = wx.ListCtrl(self, id, style=wx.LC_REPORT | wx.LC_HRULES | wx.LC_VRULES) + self.list.InsertColumn(0, 'From') + self.list.InsertColumn(1, 'To') + self.list.InsertColumn(2, 'Address') + self.list.InsertColumn(3, 'Port') + self.list.InsertColumn(4, 'Options') + self.list.InsertColumn(5, 'Weight') + + hbox = wx.BoxSizer(wx.HORIZONTAL) + hbox.Add(self.list, 1, wx.EXPAND) + self.SetSizer(hbox) + self.refresh() + + def refresh(self): + self.list.itemDataMap = {} + i = 0 + + for key, edge in vpn.edges.items(): + if self.list.GetItemCount() <= i: + self.list.InsertStringItem(i, edge.fr) + else: + self.list.SetStringItem(i, 0, edge.fr) + self.list.SetStringItem(i, 1, edge.to) + self.list.SetStringItem(i, 2, edge.address) + self.list.SetStringItem(i, 3, edge.port) + self.list.SetStringItem(i, 4, str(edge.options)) + self.list.SetStringItem(i, 5, str(edge.weight)) + self.list.itemDataMap[i] = (edge.fr, edge.to, edge.address, edge.port, edge.options, edge.weight) + i += 1 + + while self.list.GetItemCount() > i: + self.list.DeleteItem(self.list.GetItemCount() - 1) + +class SubnetsPage(wx.Panel): + def __init__(self, parent, id): + wx.Panel.__init__(self, parent, id) + self.list = SuperListCtrl(self, id) + self.list.InsertColumn(0, 'Subnet', wx.LIST_FORMAT_RIGHT) + self.list.InsertColumn(1, 'Weight', wx.LIST_FORMAT_RIGHT) + self.list.InsertColumn(2, 'Owner') + hbox = wx.BoxSizer(wx.HORIZONTAL) + hbox.Add(self.list, 1, wx.EXPAND) + self.SetSizer(hbox) + self.refresh() + + def refresh(self): + self.list.itemDataMap = {} + i = 0 + + for key, subnet in vpn.subnets.items(): + if self.list.GetItemCount() <= i: + self.list.InsertStringItem(i, subnet.address + '/' + subnet.prefixlen) + else: + self.list.SetStringItem(i, 0, subnet.address + '/' + subnet.prefixlen) + self.list.SetStringItem(i, 1, subnet.weight) + self.list.SetStringItem(i, 2, subnet.owner) + self.list.itemDataMap[i] = (subnet.address + '/' + subnet.prefixlen, subnet.weight, subnet.owner) + i = i + 1 + + while self.list.GetItemCount() > i: + self.list.DeleteItem(self.list.GetItemCount() - 1) + +class StatusPage(wx.Panel): + def __init__(self, parent, id): + wx.Panel.__init__(self, parent, id) + +class GraphPage(wx.Window): + def __init__(self, parent, id): + wx.Window.__init__(self, parent, id) + +class NetPage(wx.Notebook): + def __init__(self, parent, id): + wx.Notebook.__init__(self, parent) + self.settings = SettingsPage(self, id) + self.connections = ConnectionsPage(self, id) + self.nodes = NodesPage(self, id) + self.edges = EdgesPage(self, id) + self.subnets = SubnetsPage(self, id) + self.graph = GraphPage(self, id) + self.status = StatusPage(self, id) + + self.AddPage(self.settings, 'Settings') + #self.AddPage(self.status, 'Status') + self.AddPage(self.connections, 'Connections') + self.AddPage(self.nodes, 'Nodes') + self.AddPage(self.edges, 'Edges') + self.AddPage(self.subnets, 'Subnets') + #self.AddPage(self.graph, 'Graph') + + +class MainWindow(wx.Frame): + def OnQuit(self, event): + self.Close(True) + + def OnTimer(self, event): + vpn.refresh() + self.np.nodes.refresh() + self.np.subnets.refresh() + self.np.edges.refresh() + self.np.connections.refresh() + + def __init__(self, parent, id, title): + wx.Frame.__init__(self, parent, id, title) + + menubar = wx.MenuBar() + file = wx.Menu() + file.Append(1, '&Quit\tCtrl-X', 'Quit tinc GUI') + menubar.Append(file, '&File') + + #nb = wx.Notebook(self, -1) + #nb.SetPadding((0, 0)) + self.np = NetPage(self, -1) + #nb.AddPage(np, 'VPN') + + self.timer = wx.Timer(self, -1) + self.Bind(wx.EVT_TIMER, self.OnTimer, self.timer) + self.timer.Start(1000) + self.Bind(wx.EVT_MENU, self.OnQuit, id=1) + self.SetMenuBar(menubar) + self.Show() + +app = wx.App() +mw = MainWindow(None, -1, 'Tinc GUI') + +#def OnTaskBarIcon(event): +# mw.Raise() +# +#icon = wx.Icon("tincgui.ico", wx.BITMAP_TYPE_PNG) +#taskbaricon = wx.TaskBarIcon() +#taskbaricon.SetIcon(icon, 'Tinc GUI') +#wx.EVT_TASKBAR_RIGHT_UP(taskbaricon, OnTaskBarIcon) + +app.MainLoop() +vpn.close() diff --git a/src/have.h b/have.h similarity index 88% rename from src/have.h rename to have.h index 11fa56a..0ab8134 100644 --- a/src/have.h +++ b/have.h @@ -1,10 +1,7 @@ -#ifndef TINC_HAVE_H -#define TINC_HAVE_H - /* have.h -- include headers which are known to exist Copyright (C) 1998-2005 Ivo Timmermans - 2003-2015 Guus Sliepen + 2003-2011 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 @@ -21,32 +18,30 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +#ifndef __TINC_HAVE_H__ +#define __TINC_HAVE_H__ + #ifdef HAVE_MINGW #ifdef WITH_WINDOWS2000 #define WINVER Windows2000 #else #define WINVER WindowsXP #endif +#define WIN32_LEAN_AND_MEAN #endif #include -#include -#include -#include #include #include #include #include +#include #include -#include - #include #include -#include #ifdef HAVE_MINGW #include -#include #include #include #endif @@ -59,8 +54,8 @@ #include #endif -#ifdef HAVE_ALLOCA_H -#include +#ifdef HAVE_INTTYPES_H +#include #endif /* Include system specific headers */ @@ -109,6 +104,10 @@ #include #endif +#ifdef HAVE_SYS_UN_H +#include +#endif + #ifdef HAVE_DIRENT_H #include #endif @@ -196,19 +195,8 @@ #include #endif -#ifdef HAVE_ARPA_NAMESER_H -#include -#ifdef STATUS -#undef STATUS -#endif +#ifdef HAVE_EVENT_H +#include #endif -#ifdef HAVE_RESOLV_H -#include -#endif - -#ifdef HAVE_LINUX_IF_TUN_H -#include -#endif - -#endif +#endif /* __TINC_SYSTEM_H__ */ diff --git a/install-sh b/install-sh index 8175c64..6781b98 100755 --- a/install-sh +++ b/install-sh @@ -1,7 +1,7 @@ #!/bin/sh # install - install a program, script, or datafile -scriptversion=2018-03-11.20; # UTC +scriptversion=2009-04-28.21; # UTC # This originates from X11R5 (mit/util/scripts/install.sh), which was # later released in X11R6 (xc/config/util/install.sh) with the @@ -35,21 +35,25 @@ scriptversion=2018-03-11.20; # UTC # FSF changes to this file are in the public domain. # # Calling this script install-sh is preferred over install.sh, to prevent -# 'make' implicit rules from creating a file called install from it +# `make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. -tab=' ' nl=' ' -IFS=" $tab$nl" +IFS=" "" $nl" -# Set DOITPROG to "echo" to test this script. +# set DOITPROG to echo to test this script +# Don't use :- since 4.3BSD and earlier shells don't like it. doit=${DOITPROG-} -doit_exec=${doit:-exec} +if test -z "$doit"; then + doit_exec=exec +else + doit_exec=$doit +fi # Put in absolute file names if you don't have them in your path; # or use environment vars. @@ -64,6 +68,17 @@ mvprog=${MVPROG-mv} rmprog=${RMPROG-rm} stripprog=${STRIPPROG-strip} +posix_glob='?' +initialize_posix_glob=' + test "$posix_glob" != "?" || { + if (set -f) 2>/dev/null; then + posix_glob= + else + posix_glob=: + fi + } +' + posix_mkdir= # Desired mode of installed file. @@ -82,7 +97,7 @@ dir_arg= dst_arg= copy_on_change=false -is_target_a_directory=possibly +no_target_directory= usage="\ Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE @@ -122,57 +137,42 @@ while test $# -ne 0; do -d) dir_arg=true;; -g) chgrpcmd="$chgrpprog $2" - shift;; + shift;; --help) echo "$usage"; exit $?;; -m) mode=$2 - case $mode in - *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*) - echo "$0: invalid mode: $mode" >&2 - exit 1;; - esac - shift;; + case $mode in + *' '* | *' '* | *' +'* | *'*'* | *'?'* | *'['*) + echo "$0: invalid mode: $mode" >&2 + exit 1;; + esac + shift;; -o) chowncmd="$chownprog $2" - shift;; + shift;; -s) stripcmd=$stripprog;; - -t) - is_target_a_directory=always - dst_arg=$2 - # Protect names problematic for 'test' and other utilities. - case $dst_arg in - -* | [=\(\)!]) dst_arg=./$dst_arg;; - esac - shift;; + -t) dst_arg=$2 + shift;; - -T) is_target_a_directory=never;; + -T) no_target_directory=true;; --version) echo "$0 $scriptversion"; exit $?;; - --) shift - break;; + --) shift + break;; - -*) echo "$0: invalid option: $1" >&2 - exit 1;; + -*) echo "$0: invalid option: $1" >&2 + exit 1;; *) break;; esac shift done -# We allow the use of options -d and -T together, by making -d -# take the precedence; this is for compatibility with GNU install. - -if test -n "$dir_arg"; then - if test -n "$dst_arg"; then - echo "$0: target directory not allowed when installing a directory." >&2 - exit 1 - fi -fi - if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then # When -d is used, all remaining arguments are directories to create. # When -t is used, the destination is already specified. @@ -186,10 +186,6 @@ if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then fi shift # arg dst_arg=$arg - # Protect names problematic for 'test' and other utilities. - case $dst_arg in - -* | [=\(\)!]) dst_arg=./$dst_arg;; - esac done fi @@ -198,26 +194,13 @@ if test $# -eq 0; then echo "$0: no input file specified." >&2 exit 1 fi - # It's OK to call 'install-sh -d' without argument. + # It's OK to call `install-sh -d' without argument. # This can happen when creating conditional directories. exit 0 fi if test -z "$dir_arg"; then - if test $# -gt 1 || test "$is_target_a_directory" = always; then - if test ! -d "$dst_arg"; then - echo "$0: $dst_arg: Is not a directory." >&2 - exit 1 - fi - fi -fi - -if test -z "$dir_arg"; then - do_exit='(exit $ret); exit $ret' - trap "ret=129; $do_exit" 1 - trap "ret=130; $do_exit" 2 - trap "ret=141; $do_exit" 13 - trap "ret=143; $do_exit" 15 + trap '(exit $?); exit' 1 2 13 15 # Set umask so as not to create temps with too-generous modes. # However, 'strip' requires both read and write access to temps. @@ -228,16 +211,16 @@ if test -z "$dir_arg"; then *[0-7]) if test -z "$stripcmd"; then - u_plus_rw= + u_plus_rw= else - u_plus_rw='% 200' + u_plus_rw='% 200' fi cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; *) if test -z "$stripcmd"; then - u_plus_rw= + u_plus_rw= else - u_plus_rw=,u+rw + u_plus_rw=,u+rw fi cp_umask=$mode$u_plus_rw;; esac @@ -245,9 +228,9 @@ fi for src do - # Protect names problematic for 'test' and other utilities. + # Protect names starting with `-'. case $src in - -* | [=\(\)!]) src=./$src;; + -*) src=./$src;; esac if test -n "$dir_arg"; then @@ -269,115 +252,129 @@ do echo "$0: no destination specified." >&2 exit 1 fi - dst=$dst_arg - # If destination is a directory, append the input filename. + dst=$dst_arg + # Protect names starting with `-'. + case $dst in + -*) dst=./$dst;; + esac + + # If destination is a directory, append the input filename; won't work + # if double slashes aren't ignored. if test -d "$dst"; then - if test "$is_target_a_directory" = never; then - echo "$0: $dst_arg: Is a directory" >&2 - exit 1 + if test -n "$no_target_directory"; then + echo "$0: $dst_arg: Is a directory" >&2 + exit 1 fi dstdir=$dst - dstbase=`basename "$src"` - case $dst in - */) dst=$dst$dstbase;; - *) dst=$dst/$dstbase;; - esac + dst=$dstdir/`basename "$src"` dstdir_status=0 else - dstdir=`dirname "$dst"` + # Prefer dirname, but fall back on a substitute if dirname fails. + dstdir=` + (dirname "$dst") 2>/dev/null || + expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$dst" : 'X\(//\)[^/]' \| \ + X"$dst" : 'X\(//\)$' \| \ + X"$dst" : 'X\(/\)' \| . 2>/dev/null || + echo X"$dst" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q' + ` + test -d "$dstdir" dstdir_status=$? fi fi - case $dstdir in - */) dstdirslash=$dstdir;; - *) dstdirslash=$dstdir/;; - esac - obsolete_mkdir_used=false if test $dstdir_status != 0; then case $posix_mkdir in '') - # Create intermediate dirs using mode 755 as modified by the umask. - # This is like FreeBSD 'install' as of 1997-10-28. - umask=`umask` - case $stripcmd.$umask in - # Optimize common cases. - *[2367][2367]) mkdir_umask=$umask;; - .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; + # Create intermediate dirs using mode 755 as modified by the umask. + # This is like FreeBSD 'install' as of 1997-10-28. + umask=`umask` + case $stripcmd.$umask in + # Optimize common cases. + *[2367][2367]) mkdir_umask=$umask;; + .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; - *[0-7]) - mkdir_umask=`expr $umask + 22 \ - - $umask % 100 % 40 + $umask % 20 \ - - $umask % 10 % 4 + $umask % 2 - `;; - *) mkdir_umask=$umask,go-w;; - esac + *[0-7]) + mkdir_umask=`expr $umask + 22 \ + - $umask % 100 % 40 + $umask % 20 \ + - $umask % 10 % 4 + $umask % 2 + `;; + *) mkdir_umask=$umask,go-w;; + esac - # With -d, create the new directory with the user-specified mode. - # Otherwise, rely on $mkdir_umask. - if test -n "$dir_arg"; then - mkdir_mode=-m$mode - else - mkdir_mode= - fi + # With -d, create the new directory with the user-specified mode. + # Otherwise, rely on $mkdir_umask. + if test -n "$dir_arg"; then + mkdir_mode=-m$mode + else + mkdir_mode= + fi - posix_mkdir=false - case $umask in - *[123567][0-7][0-7]) - # POSIX mkdir -p sets u+wx bits regardless of umask, which - # is incompatible with FreeBSD 'install' when (umask & 300) != 0. - ;; - *) - # Note that $RANDOM variable is not portable (e.g. dash); Use it - # here however when possible just to lower collision chance. - tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ + posix_mkdir=false + case $umask in + *[123567][0-7][0-7]) + # POSIX mkdir -p sets u+wx bits regardless of umask, which + # is incompatible with FreeBSD 'install' when (umask & 300) != 0. + ;; + *) + tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ + trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 - trap 'ret=$?; rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null; exit $ret' 0 - - # Because "mkdir -p" follows existing symlinks and we likely work - # directly in world-writeable /tmp, make sure that the '$tmpdir' - # directory is successfully created first before we actually test - # 'mkdir -p' feature. - if (umask $mkdir_umask && - $mkdirprog $mkdir_mode "$tmpdir" && - exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1 - then - if test -z "$dir_arg" || { - # Check for POSIX incompatibilities with -m. - # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or - # other-writable bit of parent directory when it shouldn't. - # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. - test_tmpdir="$tmpdir/a" - ls_ld_tmpdir=`ls -ld "$test_tmpdir"` - case $ls_ld_tmpdir in - d????-?r-*) different_mode=700;; - d????-?--*) different_mode=755;; - *) false;; - esac && - $mkdirprog -m$different_mode -p -- "$test_tmpdir" && { - ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"` - test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" - } - } - then posix_mkdir=: - fi - rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" - else - # Remove any dirs left behind by ancient mkdir implementations. - rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null - fi - trap '' 0;; - esac;; + if (umask $mkdir_umask && + exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 + then + if test -z "$dir_arg" || { + # Check for POSIX incompatibilities with -m. + # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or + # other-writeable bit of parent directory when it shouldn't. + # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. + ls_ld_tmpdir=`ls -ld "$tmpdir"` + case $ls_ld_tmpdir in + d????-?r-*) different_mode=700;; + d????-?--*) different_mode=755;; + *) false;; + esac && + $mkdirprog -m$different_mode -p -- "$tmpdir" && { + ls_ld_tmpdir_1=`ls -ld "$tmpdir"` + test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" + } + } + then posix_mkdir=: + fi + rmdir "$tmpdir/d" "$tmpdir" + else + # Remove any dirs left behind by ancient mkdir implementations. + rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null + fi + trap '' 0;; + esac;; esac if $posix_mkdir && ( - umask $mkdir_umask && - $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" + umask $mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" ) then : else @@ -387,51 +384,53 @@ do # directory the slow way, step by step, checking for races as we go. case $dstdir in - /*) prefix='/';; - [-=\(\)!]*) prefix='./';; - *) prefix='';; + /*) prefix='/';; + -*) prefix='./';; + *) prefix='';; esac + eval "$initialize_posix_glob" + oIFS=$IFS IFS=/ - set -f + $posix_glob set -f set fnord $dstdir shift - set +f + $posix_glob set +f IFS=$oIFS prefixes= for d do - test X"$d" = X && continue + test -z "$d" && continue - prefix=$prefix$d - if test -d "$prefix"; then - prefixes= - else - if $posix_mkdir; then - (umask=$mkdir_umask && - $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break - # Don't fail if two instances are running concurrently. - test -d "$prefix" || exit 1 - else - case $prefix in - *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; - *) qprefix=$prefix;; - esac - prefixes="$prefixes '$qprefix'" - fi - fi - prefix=$prefix/ + prefix=$prefix$d + if test -d "$prefix"; then + prefixes= + else + if $posix_mkdir; then + (umask=$mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break + # Don't fail if two instances are running concurrently. + test -d "$prefix" || exit 1 + else + case $prefix in + *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; + *) qprefix=$prefix;; + esac + prefixes="$prefixes '$qprefix'" + fi + fi + prefix=$prefix/ done if test -n "$prefixes"; then - # Don't fail if two instances are running concurrently. - (umask $mkdir_umask && - eval "\$doit_exec \$mkdirprog $prefixes") || - test -d "$dstdir" || exit 1 - obsolete_mkdir_used=true + # Don't fail if two instances are running concurrently. + (umask $mkdir_umask && + eval "\$doit_exec \$mkdirprog $prefixes") || + test -d "$dstdir" || exit 1 + obsolete_mkdir_used=true fi fi fi @@ -444,8 +443,8 @@ do else # Make a couple of temp file names in the proper directory. - dsttmp=${dstdirslash}_inst.$$_ - rmtmp=${dstdirslash}_rm.$$_ + dsttmp=$dstdir/_inst.$$_ + rmtmp=$dstdir/_rm.$$_ # Trap to clean up those temp files at exit. trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 @@ -466,12 +465,15 @@ do # If -C, don't bother to copy if it wouldn't change the file. if $copy_on_change && - old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && - new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && - set -f && + old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && + new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && + + eval "$initialize_posix_glob" && + $posix_glob set -f && set X $old && old=:$2:$4:$5:$6 && set X $new && new=:$2:$4:$5:$6 && - set +f && + $posix_glob set +f && + test "$old" = "$new" && $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 then @@ -484,24 +486,24 @@ do # to itself, or perhaps because mv is so ancient that it does not # support -f. { - # Now remove or move aside any old file at destination location. - # We try this two ways since rm can't unlink itself on some - # systems and the destination file might be busy for other - # reasons. In this case, the final cleanup might fail but the new - # file should still install successfully. - { - test ! -f "$dst" || - $doit $rmcmd -f "$dst" 2>/dev/null || - { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && - { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } - } || - { echo "$0: cannot unlink or rename $dst" >&2 - (exit 1); exit 1 - } - } && + # Now remove or move aside any old file at destination location. + # We try this two ways since rm can't unlink itself on some + # systems and the destination file might be busy for other + # reasons. In this case, the final cleanup might fail but the new + # file should still install successfully. + { + test ! -f "$dst" || + $doit $rmcmd -f "$dst" 2>/dev/null || + { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && + { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } + } || + { echo "$0: cannot unlink or rename $dst" >&2 + (exit 1); exit 1 + } + } && - # Now rename the file to the real destination. - $doit $mvcmd "$dsttmp" "$dst" + # Now rename the file to the real destination. + $doit $mvcmd "$dsttmp" "$dst" } fi || exit 1 @@ -510,9 +512,9 @@ do done # Local variables: -# eval: (add-hook 'before-save-hook 'time-stamp) +# eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" -# time-stamp-time-zone: "UTC0" +# time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: diff --git a/m4/Makefile.am b/m4/Makefile.am new file mode 100644 index 0000000..0f58aef --- /dev/null +++ b/m4/Makefile.am @@ -0,0 +1,4 @@ +## Process this file with automake to produce Makefile.in -*-Makefile-*- + +EXTRA_DIST = README *.m4 + diff --git a/m4/Makefile.in b/m4/Makefile.in new file mode 100644 index 0000000..17af65a --- /dev/null +++ b/m4/Makefile.in @@ -0,0 +1,335 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = m4 +DIST_COMMON = README $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \ + $(top_srcdir)/m4/curses.m4 $(top_srcdir)/m4/libevent.m4 \ + $(top_srcdir)/m4/lzo.m4 $(top_srcdir)/m4/openssl.m4 \ + $(top_srcdir)/m4/zlib.m4 $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +SOURCES = +DIST_SOURCES = +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CURSES_LIBS = @CURSES_LIBS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +GREP = @GREP@ +INCLUDES = @INCLUDES@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ +LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ +LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +EXTRA_DIST = README *.m4 +all: all-am + +.SUFFIXES: +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu m4/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu m4/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): +tags: TAGS +TAGS: + +ctags: CTAGS +CTAGS: + + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: all all-am check check-am clean clean-generic distclean \ + distclean-generic distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-generic pdf pdf-am ps ps-am uninstall uninstall-am + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/m4/README b/m4/README new file mode 100644 index 0000000..df032df --- /dev/null +++ b/m4/README @@ -0,0 +1,8 @@ +These files are used by a program called aclocal (part of the GNU automake +package). aclocal uses these files to create aclocal.m4 which is in turn +used by autoconf to create the configure script at the the top level in +this distribution. + +The Makefile.am file in this directory is automatically generated +from the template file, Makefile.am.in. The generation will fail +if you don't have all the right tools. diff --git a/m4/attribute.m4 b/m4/attribute.m4 index 9d673e9..6a8f555 100644 --- a/m4/attribute.m4 +++ b/m4/attribute.m4 @@ -9,8 +9,8 @@ AC_DEFUN([tinc_ATTRIBUTE], CFLAGS="$CFLAGS -Wall -Werror" AC_COMPILE_IFELSE( [AC_LANG_SOURCE( - [void *test(void) __attribute__ (($1)); - void *test(void) { return (void *)0; } + [void test(void) __attribute__ (($1)); + void test(void) { return; } ], )], [tinc_cv_attribute_$1=yes], diff --git a/m4/ax_append_flag.m4 b/m4/ax_append_flag.m4 deleted file mode 100644 index 1d38b76..0000000 --- a/m4/ax_append_flag.m4 +++ /dev/null @@ -1,69 +0,0 @@ -# =========================================================================== -# http://www.gnu.org/software/autoconf-archive/ax_append_flag.html -# =========================================================================== -# -# SYNOPSIS -# -# AX_APPEND_FLAG(FLAG, [FLAGS-VARIABLE]) -# -# DESCRIPTION -# -# FLAG is appended to the FLAGS-VARIABLE shell variable, with a space -# added in between. -# -# If FLAGS-VARIABLE is not specified, the current language's flags (e.g. -# CFLAGS) is used. FLAGS-VARIABLE is not changed if it already contains -# FLAG. If FLAGS-VARIABLE is unset in the shell, it is set to exactly -# FLAG. -# -# NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. -# -# LICENSE -# -# Copyright (c) 2008 Guido U. Draheim -# Copyright (c) 2011 Maarten Bosmans -# -# This program is free software: you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation, either version 3 of the License, or (at your -# option) any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General -# Public License for more details. -# -# You should have received a copy of the GNU General Public License along -# with this program. If not, see . -# -# As a special exception, the respective Autoconf Macro's copyright owner -# gives unlimited permission to copy, distribute and modify the configure -# scripts that are the output of Autoconf when processing the Macro. You -# need not follow the terms of the GNU General Public License when using -# or distributing such scripts, even though portions of the text of the -# Macro appear in them. The GNU General Public License (GPL) does govern -# all other use of the material that constitutes the Autoconf Macro. -# -# This special exception to the GPL applies to versions of the Autoconf -# Macro released by the Autoconf Archive. When you make and distribute a -# modified version of the Autoconf Macro, you may extend this special -# exception to the GPL to apply to your modified version as well. - -#serial 2 - -AC_DEFUN([AX_APPEND_FLAG], -[AC_PREREQ(2.59)dnl for _AC_LANG_PREFIX -AS_VAR_PUSHDEF([FLAGS], [m4_default($2,_AC_LANG_PREFIX[FLAGS])])dnl -AS_VAR_SET_IF(FLAGS, - [case " AS_VAR_GET(FLAGS) " in - *" $1 "*) - AC_RUN_LOG([: FLAGS already contains $1]) - ;; - *) - AC_RUN_LOG([: FLAGS="$FLAGS $1"]) - AS_VAR_SET(FLAGS, ["AS_VAR_GET(FLAGS) $1"]) - ;; - esac], - [AS_VAR_SET(FLAGS,["$1"])]) -AS_VAR_POPDEF([FLAGS])dnl -])dnl AX_APPEND_FLAG diff --git a/m4/ax_cflags_warn_all.m4 b/m4/ax_cflags_warn_all.m4 deleted file mode 100644 index 1f07799..0000000 --- a/m4/ax_cflags_warn_all.m4 +++ /dev/null @@ -1,122 +0,0 @@ -# =========================================================================== -# http://www.gnu.org/software/autoconf-archive/ax_cflags_warn_all.html -# =========================================================================== -# -# SYNOPSIS -# -# AX_CFLAGS_WARN_ALL [(shellvar [,default, [A/NA]])] -# AX_CXXFLAGS_WARN_ALL [(shellvar [,default, [A/NA]])] -# AX_FCFLAGS_WARN_ALL [(shellvar [,default, [A/NA]])] -# -# DESCRIPTION -# -# Try to find a compiler option that enables most reasonable warnings. -# -# For the GNU compiler it will be -Wall (and -ansi -pedantic) The result -# is added to the shellvar being CFLAGS, CXXFLAGS, or FCFLAGS by default. -# -# Currently this macro knows about the GCC, Solaris, Digital Unix, AIX, -# HP-UX, IRIX, NEC SX-5 (Super-UX 10), Cray J90 (Unicos 10.0.0.8), and -# Intel compilers. For a given compiler, the Fortran flags are much more -# experimental than their C equivalents. -# -# - $1 shell-variable-to-add-to : CFLAGS, CXXFLAGS, or FCFLAGS -# - $2 add-value-if-not-found : nothing -# - $3 action-if-found : add value to shellvariable -# - $4 action-if-not-found : nothing -# -# NOTE: These macros depend on AX_APPEND_FLAG. -# -# LICENSE -# -# Copyright (c) 2008 Guido U. Draheim -# Copyright (c) 2010 Rhys Ulerich -# -# This program is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation; either version 3 of the License, or (at your -# option) any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General -# Public License for more details. -# -# You should have received a copy of the GNU General Public License along -# with this program. If not, see . -# -# As a special exception, the respective Autoconf Macro's copyright owner -# gives unlimited permission to copy, distribute and modify the configure -# scripts that are the output of Autoconf when processing the Macro. You -# need not follow the terms of the GNU General Public License when using -# or distributing such scripts, even though portions of the text of the -# Macro appear in them. The GNU General Public License (GPL) does govern -# all other use of the material that constitutes the Autoconf Macro. -# -# This special exception to the GPL applies to versions of the Autoconf -# Macro released by the Autoconf Archive. When you make and distribute a -# modified version of the Autoconf Macro, you may extend this special -# exception to the GPL to apply to your modified version as well. - -#serial 15 - -AC_DEFUN([AX_FLAGS_WARN_ALL],[dnl -AS_VAR_PUSHDEF([FLAGS],[_AC_LANG_PREFIX[]FLAGS])dnl -AS_VAR_PUSHDEF([VAR],[ac_cv_[]_AC_LANG_ABBREV[]flags_warn_all])dnl -AC_CACHE_CHECK([m4_ifval($1,$1,FLAGS) for maximum warnings], -VAR,[VAR="no, unknown" -ac_save_[]FLAGS="$[]FLAGS" -for ac_arg dnl -in "-warn all % -warn all" dnl Intel - "-pedantic % -Wall" dnl GCC - "-xstrconst % -v" dnl Solaris C - "-std1 % -verbose -w0 -warnprotos" dnl Digital Unix - "-qlanglvl=ansi % -qsrcmsg -qinfo=all:noppt:noppc:noobs:nocnd" dnl AIX - "-ansi -ansiE % -fullwarn" dnl IRIX - "+ESlit % +w1" dnl HP-UX C - "-Xc % -pvctl[,]fullmsg" dnl NEC SX-5 (Super-UX 10) - "-h conform % -h msglevel 2" dnl Cray C (Unicos) - # -do FLAGS="$ac_save_[]FLAGS "`echo $ac_arg | sed -e 's,%%.*,,' -e 's,%,,'` - AC_COMPILE_IFELSE([AC_LANG_PROGRAM], - [VAR=`echo $ac_arg | sed -e 's,.*% *,,'` ; break]) -done -FLAGS="$ac_save_[]FLAGS" -]) -AS_VAR_POPDEF([FLAGS])dnl -AX_REQUIRE_DEFINED([AX_APPEND_FLAG]) -case ".$VAR" in - .ok|.ok,*) m4_ifvaln($3,$3) ;; - .|.no|.no,*) m4_default($4,[m4_ifval($2,[AX_APPEND_FLAG([$2], [$1])])]) ;; - *) m4_default($3,[AX_APPEND_FLAG([$VAR], [$1])]) ;; -esac -AS_VAR_POPDEF([VAR])dnl -])dnl AX_FLAGS_WARN_ALL -dnl implementation tactics: -dnl the for-argument contains a list of options. The first part of -dnl these does only exist to detect the compiler - usually it is -dnl a global option to enable -ansi or -extrawarnings. All other -dnl compilers will fail about it. That was needed since a lot of -dnl compilers will give false positives for some option-syntax -dnl like -Woption or -Xoption as they think of it is a pass-through -dnl to later compile stages or something. The "%" is used as a -dnl delimiter. A non-option comment can be given after "%%" marks -dnl which will be shown but not added to the respective C/CXXFLAGS. - -AC_DEFUN([AX_CFLAGS_WARN_ALL],[dnl -AC_LANG_PUSH([C]) -AX_FLAGS_WARN_ALL([$1], [$2], [$3], [$4]) -AC_LANG_POP([C]) -]) - -AC_DEFUN([AX_CXXFLAGS_WARN_ALL],[dnl -AC_LANG_PUSH([C++]) -AX_FLAGS_WARN_ALL([$1], [$2], [$3], [$4]) -AC_LANG_POP([C++]) -]) - -AC_DEFUN([AX_FCFLAGS_WARN_ALL],[dnl -AC_LANG_PUSH([Fortran]) -AX_FLAGS_WARN_ALL([$1], [$2], [$3], [$4]) -AC_LANG_POP([Fortran]) -]) diff --git a/m4/ax_check_compile_flag.m4 b/m4/ax_check_compile_flag.m4 deleted file mode 100644 index c3a8d69..0000000 --- a/m4/ax_check_compile_flag.m4 +++ /dev/null @@ -1,72 +0,0 @@ -# =========================================================================== -# http://www.gnu.org/software/autoconf-archive/ax_check_compile_flag.html -# =========================================================================== -# -# SYNOPSIS -# -# AX_CHECK_COMPILE_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS]) -# -# DESCRIPTION -# -# Check whether the given FLAG works with the current language's compiler -# or gives an error. (Warnings, however, are ignored) -# -# ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on -# success/failure. -# -# If EXTRA-FLAGS is defined, it is added to the current language's default -# flags (e.g. CFLAGS) when the check is done. The check is thus made with -# the flags: "CFLAGS EXTRA-FLAGS FLAG". This can for example be used to -# force the compiler to issue an error when a bad flag is given. -# -# NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this -# macro in sync with AX_CHECK_{PREPROC,LINK}_FLAG. -# -# LICENSE -# -# Copyright (c) 2008 Guido U. Draheim -# Copyright (c) 2011 Maarten Bosmans -# -# This program is free software: you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation, either version 3 of the License, or (at your -# option) any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General -# Public License for more details. -# -# You should have received a copy of the GNU General Public License along -# with this program. If not, see . -# -# As a special exception, the respective Autoconf Macro's copyright owner -# gives unlimited permission to copy, distribute and modify the configure -# scripts that are the output of Autoconf when processing the Macro. You -# need not follow the terms of the GNU General Public License when using -# or distributing such scripts, even though portions of the text of the -# Macro appear in them. The GNU General Public License (GPL) does govern -# all other use of the material that constitutes the Autoconf Macro. -# -# This special exception to the GPL applies to versions of the Autoconf -# Macro released by the Autoconf Archive. When you make and distribute a -# modified version of the Autoconf Macro, you may extend this special -# exception to the GPL to apply to your modified version as well. - -#serial 2 - -AC_DEFUN([AX_CHECK_COMPILE_FLAG], -[AC_PREREQ(2.59)dnl for _AC_LANG_PREFIX -AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_[]_AC_LANG_ABBREV[]flags_$4_$1])dnl -AC_CACHE_CHECK([whether _AC_LANG compiler accepts $1], CACHEVAR, [ - ax_check_save_flags=$[]_AC_LANG_PREFIX[]FLAGS - _AC_LANG_PREFIX[]FLAGS="$[]_AC_LANG_PREFIX[]FLAGS $4 $1" - AC_COMPILE_IFELSE([AC_LANG_PROGRAM()], - [AS_VAR_SET(CACHEVAR,[yes])], - [AS_VAR_SET(CACHEVAR,[no])]) - _AC_LANG_PREFIX[]FLAGS=$ax_check_save_flags]) -AS_IF([test x"AS_VAR_GET(CACHEVAR)" = xyes], - [m4_default([$2], :)], - [m4_default([$3], :)]) -AS_VAR_POPDEF([CACHEVAR])dnl -])dnl AX_CHECK_COMPILE_FLAGS diff --git a/m4/ax_check_link_flag.m4 b/m4/ax_check_link_flag.m4 deleted file mode 100644 index e2d0d36..0000000 --- a/m4/ax_check_link_flag.m4 +++ /dev/null @@ -1,71 +0,0 @@ -# =========================================================================== -# http://www.gnu.org/software/autoconf-archive/ax_check_link_flag.html -# =========================================================================== -# -# SYNOPSIS -# -# AX_CHECK_LINK_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS]) -# -# DESCRIPTION -# -# Check whether the given FLAG works with the linker or gives an error. -# (Warnings, however, are ignored) -# -# ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on -# success/failure. -# -# If EXTRA-FLAGS is defined, it is added to the linker's default flags -# when the check is done. The check is thus made with the flags: "LDFLAGS -# EXTRA-FLAGS FLAG". This can for example be used to force the linker to -# issue an error when a bad flag is given. -# -# NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this -# macro in sync with AX_CHECK_{PREPROC,COMPILE}_FLAG. -# -# LICENSE -# -# Copyright (c) 2008 Guido U. Draheim -# Copyright (c) 2011 Maarten Bosmans -# -# This program is free software: you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation, either version 3 of the License, or (at your -# option) any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General -# Public License for more details. -# -# You should have received a copy of the GNU General Public License along -# with this program. If not, see . -# -# As a special exception, the respective Autoconf Macro's copyright owner -# gives unlimited permission to copy, distribute and modify the configure -# scripts that are the output of Autoconf when processing the Macro. You -# need not follow the terms of the GNU General Public License when using -# or distributing such scripts, even though portions of the text of the -# Macro appear in them. The GNU General Public License (GPL) does govern -# all other use of the material that constitutes the Autoconf Macro. -# -# This special exception to the GPL applies to versions of the Autoconf -# Macro released by the Autoconf Archive. When you make and distribute a -# modified version of the Autoconf Macro, you may extend this special -# exception to the GPL to apply to your modified version as well. - -#serial 2 - -AC_DEFUN([AX_CHECK_LINK_FLAG], -[AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_ldflags_$4_$1])dnl -AC_CACHE_CHECK([whether the linker accepts $1], CACHEVAR, [ - ax_check_save_flags=$LDFLAGS - LDFLAGS="$LDFLAGS $4 $1" - AC_LINK_IFELSE([AC_LANG_PROGRAM()], - [AS_VAR_SET(CACHEVAR,[yes])], - [AS_VAR_SET(CACHEVAR,[no])]) - LDFLAGS=$ax_check_save_flags]) -AS_IF([test x"AS_VAR_GET(CACHEVAR)" = xyes], - [m4_default([$2], :)], - [m4_default([$3], :)]) -AS_VAR_POPDEF([CACHEVAR])dnl -])dnl AX_CHECK_LINK_FLAGS diff --git a/m4/ax_require_defined.m4 b/m4/ax_require_defined.m4 deleted file mode 100644 index cae1111..0000000 --- a/m4/ax_require_defined.m4 +++ /dev/null @@ -1,37 +0,0 @@ -# =========================================================================== -# http://www.gnu.org/software/autoconf-archive/ax_require_defined.html -# =========================================================================== -# -# SYNOPSIS -# -# AX_REQUIRE_DEFINED(MACRO) -# -# DESCRIPTION -# -# AX_REQUIRE_DEFINED is a simple helper for making sure other macros have -# been defined and thus are available for use. This avoids random issues -# where a macro isn't expanded. Instead the configure script emits a -# non-fatal: -# -# ./configure: line 1673: AX_CFLAGS_WARN_ALL: command not found -# -# It's like AC_REQUIRE except it doesn't expand the required macro. -# -# Here's an example: -# -# AX_REQUIRE_DEFINED([AX_CHECK_LINK_FLAG]) -# -# LICENSE -# -# Copyright (c) 2014 Mike Frysinger -# -# 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 any -# warranty. - -#serial 1 - -AC_DEFUN([AX_REQUIRE_DEFINED], [dnl - m4_ifndef([$1], [m4_fatal([macro ]$1[ is not defined; is a m4 file missing?])]) -])dnl AX_REQUIRE_DEFINED diff --git a/m4/curses.m4 b/m4/curses.m4 new file mode 100644 index 0000000..50a90a5 --- /dev/null +++ b/m4/curses.m4 @@ -0,0 +1,41 @@ +dnl Check to find the curses headers/libraries + +AC_DEFUN([tinc_CURSES], +[ + AC_ARG_ENABLE([curses], + AS_HELP_STRING([--disable-curses], [disable curses support])) + AS_IF([test "x$enable_curses" != "xno"], [ + AC_DEFINE(HAVE_CURSES, 1, [have curses support]) + curses=true + AC_ARG_WITH(curses, + AS_HELP_STRING([--with-curses=DIR], [curses base directory, or:]), + [curses="$withval" + CPPFLAGS="$CPPFLAGS -I$withval/include" + LDFLAGS="$LDFLAGS -L$withval/lib"] + ) + + AC_ARG_WITH(curses-include, + AS_HELP_STRING([--with-curses-include=DIR], [curses headers directory]), + [curses_include="$withval" + CPPFLAGS="$CPPFLAGS -I$withval"] + ) + + AC_ARG_WITH(curses-lib, + AS_HELP_STRING([--with-curses-lib=DIR], [curses library directory]), + [curses_lib="$withval" + LDFLAGS="$LDFLAGS -L$withval"] + ) + + AC_CHECK_HEADERS(curses.h, + [], + [AC_MSG_ERROR("curses header files not found."); break] + ) + + AC_CHECK_LIB(curses, initscr, + [CURSES_LIBS="-lcurses"], + [AC_MSG_ERROR("curses libraries not found.")] + ) + ]) + + AC_SUBST(CURSES_LIBS) +]) diff --git a/m4/libevent.m4 b/m4/libevent.m4 new file mode 100644 index 0000000..34bdef7 --- /dev/null +++ b/m4/libevent.m4 @@ -0,0 +1,33 @@ +dnl Check to find the libevent headers/libraries + +AC_DEFUN([tinc_LIBEVENT], +[ + AC_ARG_WITH(libevent, + AS_HELP_STRING([--with-libevent=DIR], [libevent base directory, or:]), + [libevent="$withval" + CPPFLAGS="$CPPFLAGS -I$withval/include" + LDFLAGS="$LDFLAGS -L$withval/lib"] + ) + + AC_ARG_WITH(libevent-include, + AS_HELP_STRING([--with-libevent-include=DIR], [libevent headers directory]), + [libevent_include="$withval" + CPPFLAGS="$CPPFLAGS -I$withval"] + ) + + AC_ARG_WITH(libevent-lib, + AS_HELP_STRING([--with-libevent-lib=DIR], [libevent library directory]), + [libevent_lib="$withval" + LDFLAGS="$LDFLAGS -L$withval"] + ) + + AC_CHECK_HEADERS(event.h, + [], + [AC_MSG_ERROR("libevent header files not found."); break] + ) + + AC_CHECK_LIB(event, event_init, + [LIBS="-levent $LIBS"], + [AC_MSG_ERROR("libevent libraries not found.")] + ) +]) diff --git a/m4/openssl.m4 b/m4/openssl.m4 index 895c31a..254ea4f 100644 --- a/m4/openssl.m4 +++ b/m4/openssl.m4 @@ -1,4 +1,4 @@ -dnl Check to find the LibreSSL/OpenSSL headers/libraries +dnl Check to find the OpenSSL headers/libraries AC_DEFUN([tinc_OPENSSL], [ @@ -10,49 +10,47 @@ AC_DEFUN([tinc_OPENSSL], [], [AC_CHECK_LIB(dl, dlopen, [LIBS="$LIBS -ldl"], - [AC_MSG_ERROR([LibreSSL/OpenSSL depends on libdl.]); break] + [AC_MSG_ERROR([OpenSSL depends on libdl.]); break] )] ) ;; esac AC_ARG_WITH(openssl, - AS_HELP_STRING([--with-openssl=DIR], [LibreSSL/OpenSSL base directory, or:]), + AS_HELP_STRING([--with-openssl=DIR], [OpenSSL base directory, or:]), [openssl="$withval" CPPFLAGS="$CPPFLAGS -I$withval/include" LDFLAGS="$LDFLAGS -L$withval/lib"] ) AC_ARG_WITH(openssl-include, - AS_HELP_STRING([--with-openssl-include=DIR], [LibreSSL/OpenSSL headers directory (without trailing /openssl)]), + AS_HELP_STRING([--with-openssl-include=DIR], [OpenSSL headers directory (without trailing /openssl)]), [openssl_include="$withval" CPPFLAGS="$CPPFLAGS -I$withval"] ) AC_ARG_WITH(openssl-lib, - AS_HELP_STRING([--with-openssl-lib=DIR], [LibreSSL/OpenSSL library directory]), + AS_HELP_STRING([--with-openssl-lib=DIR], [OpenSSL library directory]), [openssl_lib="$withval" LDFLAGS="$LDFLAGS -L$withval"] ) AC_CHECK_HEADERS(openssl/evp.h openssl/rsa.h openssl/rand.h openssl/err.h openssl/sha.h openssl/pem.h openssl/engine.h, [], - [AC_MSG_ERROR([LibreSSL/OpenSSL header files not found.]); break] + [AC_MSG_ERROR([OpenSSL header files not found.]); break] ) AC_CHECK_LIB(crypto, EVP_EncryptInit_ex, [LIBS="-lcrypto $LIBS"], - [AC_MSG_ERROR([LibreSSL/OpenSSL libraries not found.])] + [AC_MSG_ERROR([OpenSSL libraries not found.])] ) - AC_CHECK_FUNCS([RAND_bytes EVP_EncryptInit_ex EVP_CIPHER_CTX_new], , - [AC_MSG_ERROR([Missing LibreSSL/OpenSSL functionality, make sure you have installed the latest version.]); break], + AC_CHECK_FUNCS([RAND_pseudo_bytes EVP_EncryptInit_ex], , + [AC_MSG_ERROR([Missing OpenSSL functionality, make sure you have installed the latest version.]); break], ) - AC_CHECK_DECLS([OpenSSL_add_all_algorithms, EVP_aes_256_cfb], , - [AC_MSG_ERROR([Missing LibreSSL/OpenSSL functionality, make sure you have installed the latest version.]); break], + AC_CHECK_DECL([OpenSSL_add_all_algorithms], , + [AC_MSG_ERROR([Missing OpenSSL functionality, make sure you have installed the latest version.]); break], [#include ] ) - - AC_CHECK_FUNCS([BN_GENCB_new RSA_set0_key], , , [#include ]) ]) diff --git a/missing b/missing index 625aeb1..28055d2 100755 --- a/missing +++ b/missing @@ -1,10 +1,11 @@ #! /bin/sh -# Common wrapper for a few potentially missing GNU programs. +# Common stub for a few missing GNU programs while installing. -scriptversion=2018-03-07.03; # UTC +scriptversion=2009-04-28.21; # UTC -# Copyright (C) 1996-2018 Free Software Foundation, Inc. -# Originally written by Fran,cois Pinard , 1996. +# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006, +# 2008, 2009 Free Software Foundation, Inc. +# Originally by Fran,cois Pinard , 1996. # 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 @@ -17,7 +18,7 @@ scriptversion=2018-03-07.03; # UTC # GNU General Public License for more details. # You should have received a copy of the GNU General Public License -# along with this program. If not, see . +# along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a @@ -25,40 +26,69 @@ scriptversion=2018-03-07.03; # UTC # the same distribution terms that you use for the rest of that program. if test $# -eq 0; then - echo 1>&2 "Try '$0 --help' for more information" + echo 1>&2 "Try \`$0 --help' for more information" exit 1 fi +run=: +sed_output='s/.* --output[ =]\([^ ]*\).*/\1/p' +sed_minuso='s/.* -o \([^ ]*\).*/\1/p' + +# In the cases where this matters, `missing' is being run in the +# srcdir already. +if test -f configure.ac; then + configure_ac=configure.ac +else + configure_ac=configure.in +fi + +msg="missing on your system" + case $1 in - - --is-lightweight) - # Used by our autoconf macros to check whether the available missing - # script is modern enough. - exit 0 - ;; - - --run) - # Back-compat with the calling convention used by older automake. - shift - ;; +--run) + # Try to run requested program, and just exit if it succeeds. + run= + shift + "$@" && exit 0 + # Exit code 63 means version mismatch. This often happens + # when the user try to use an ancient version of a tool on + # a file that requires a minimum version. In this case we + # we should proceed has if the program had been absent, or + # if --run hadn't been passed. + if test $? = 63; then + run=: + msg="probably too old" + fi + ;; -h|--h|--he|--hel|--help) echo "\ $0 [OPTION]... PROGRAM [ARGUMENT]... -Run 'PROGRAM [ARGUMENT]...', returning a proper advice when this fails due -to PROGRAM being missing or too old. +Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an +error status if there is no known handling for PROGRAM. Options: -h, --help display this help and exit -v, --version output version information and exit + --run try to run the given command, and emulate it if it fails Supported PROGRAM values: - aclocal autoconf autoheader autom4te automake makeinfo - bison yacc flex lex help2man + aclocal touch file \`aclocal.m4' + autoconf touch file \`configure' + autoheader touch file \`config.h.in' + autom4te touch the output file, or create a stub one + automake touch all \`Makefile.in' files + bison create \`y.tab.[ch]', if possible, from existing .[ch] + flex create \`lex.yy.c', if possible, from existing .c + help2man touch the output file + lex create \`lex.yy.c', if possible, from existing .c + makeinfo touch the output file + tar try tar, gnutar, gtar, then tar without non-portable flags + yacc create \`y.tab.[ch]', if possible, from existing .[ch] -Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and -'g' are ignored when checking the name. +Version suffixes to PROGRAM as well as the prefixes \`gnu-', \`gnu', and +\`g' are ignored when checking the name. Send bug reports to ." exit $? @@ -70,146 +100,277 @@ Send bug reports to ." ;; -*) - echo 1>&2 "$0: unknown '$1' option" - echo 1>&2 "Try '$0 --help' for more information" + echo 1>&2 "$0: Unknown \`$1' option" + echo 1>&2 "Try \`$0 --help' for more information" exit 1 ;; esac -# Run the given program, remember its exit status. -"$@"; st=$? +# normalize program name to check for. +program=`echo "$1" | sed ' + s/^gnu-//; t + s/^gnu//; t + s/^g//; t'` -# If it succeeded, we are done. -test $st -eq 0 && exit 0 - -# Also exit now if we it failed (or wasn't found), and '--version' was -# passed; such an option is passed most likely to detect whether the -# program is present and works. -case $2 in --version|--help) exit $st;; esac - -# Exit code 63 means version mismatch. This often happens when the user -# tries to use an ancient version of a tool on a file that requires a -# minimum version. -if test $st -eq 63; then - msg="probably too old" -elif test $st -eq 127; then - # Program was missing. - msg="missing on your system" -else - # Program was found and executed, but failed. Give up. - exit $st -fi - -perl_URL=https://www.perl.org/ -flex_URL=https://github.com/westes/flex -gnu_software_URL=https://www.gnu.org/software - -program_details () -{ - case $1 in - aclocal|automake) - echo "The '$1' program is part of the GNU Automake package:" - echo "<$gnu_software_URL/automake>" - echo "It also requires GNU Autoconf, GNU m4 and Perl in order to run:" - echo "<$gnu_software_URL/autoconf>" - echo "<$gnu_software_URL/m4/>" - echo "<$perl_URL>" - ;; - autoconf|autom4te|autoheader) - echo "The '$1' program is part of the GNU Autoconf package:" - echo "<$gnu_software_URL/autoconf/>" - echo "It also requires GNU m4 and Perl in order to run:" - echo "<$gnu_software_URL/m4/>" - echo "<$perl_URL>" - ;; - esac -} - -give_advice () -{ - # Normalize program name to check for. - normalized_program=`echo "$1" | sed ' - s/^gnu-//; t - s/^gnu//; t - s/^g//; t'` - - printf '%s\n' "'$1' is $msg." - - configure_deps="'configure.ac' or m4 files included by 'configure.ac'" - case $normalized_program in - autoconf*) - echo "You should only need it if you modified 'configure.ac'," - echo "or m4 files included by it." - program_details 'autoconf' - ;; - autoheader*) - echo "You should only need it if you modified 'acconfig.h' or" - echo "$configure_deps." - program_details 'autoheader' - ;; - automake*) - echo "You should only need it if you modified 'Makefile.am' or" - echo "$configure_deps." - program_details 'automake' - ;; - aclocal*) - echo "You should only need it if you modified 'acinclude.m4' or" - echo "$configure_deps." - program_details 'aclocal' - ;; - autom4te*) - echo "You might have modified some maintainer files that require" - echo "the 'autom4te' program to be rebuilt." - program_details 'autom4te' - ;; - bison*|yacc*) - echo "You should only need it if you modified a '.y' file." - echo "You may want to install the GNU Bison package:" - echo "<$gnu_software_URL/bison/>" - ;; - lex*|flex*) - echo "You should only need it if you modified a '.l' file." - echo "You may want to install the Fast Lexical Analyzer package:" - echo "<$flex_URL>" - ;; - help2man*) - echo "You should only need it if you modified a dependency" \ - "of a man page." - echo "You may want to install the GNU Help2man package:" - echo "<$gnu_software_URL/help2man/>" +# Now exit if we have it, but it failed. Also exit now if we +# don't have it and --version was passed (most likely to detect +# the program). This is about non-GNU programs, so use $1 not +# $program. +case $1 in + lex*|yacc*) + # Not GNU programs, they don't have --version. ;; - makeinfo*) - echo "You should only need it if you modified a '.texi' file, or" - echo "any other file indirectly affecting the aspect of the manual." - echo "You might want to install the Texinfo package:" - echo "<$gnu_software_URL/texinfo/>" - echo "The spurious makeinfo call might also be the consequence of" - echo "using a buggy 'make' (AIX, DU, IRIX), in which case you might" - echo "want to install GNU make:" - echo "<$gnu_software_URL/make/>" - ;; - *) - echo "You might have modified some files without having the proper" - echo "tools for further handling them. Check the 'README' file, it" - echo "often tells you about the needed prerequisites for installing" - echo "this package. You may also peek at any GNU archive site, in" - echo "case some other package contains this missing '$1' program." - ;; - esac -} -give_advice "$1" | sed -e '1s/^/WARNING: /' \ - -e '2,$s/^/ /' >&2 + tar*) + if test -n "$run"; then + echo 1>&2 "ERROR: \`tar' requires --run" + exit 1 + elif test "x$2" = "x--version" || test "x$2" = "x--help"; then + exit 1 + fi + ;; -# Propagate the correct exit status (expected to be 127 for a program -# not found, 63 for a program that failed due to version mismatch). -exit $st + *) + if test -z "$run" && ($1 --version) > /dev/null 2>&1; then + # We have it, but it failed. + exit 1 + elif test "x$2" = "x--version" || test "x$2" = "x--help"; then + # Could not run --version or --help. This is probably someone + # running `$TOOL --version' or `$TOOL --help' to check whether + # $TOOL exists and not knowing $TOOL uses missing. + exit 1 + fi + ;; +esac + +# If it does not exist, or fails to run (possibly an outdated version), +# try to emulate it. +case $program in + aclocal*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`acinclude.m4' or \`${configure_ac}'. You might want + to install the \`Automake' and \`Perl' packages. Grab them from + any GNU archive site." + touch aclocal.m4 + ;; + + autoconf*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`${configure_ac}'. You might want to install the + \`Autoconf' and \`GNU m4' packages. Grab them from any GNU + archive site." + touch configure + ;; + + autoheader*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`acconfig.h' or \`${configure_ac}'. You might want + to install the \`Autoconf' and \`GNU m4' packages. Grab them + from any GNU archive site." + files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}` + test -z "$files" && files="config.h" + touch_files= + for f in $files; do + case $f in + *:*) touch_files="$touch_files "`echo "$f" | + sed -e 's/^[^:]*://' -e 's/:.*//'`;; + *) touch_files="$touch_files $f.in";; + esac + done + touch $touch_files + ;; + + automake*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'. + You might want to install the \`Automake' and \`Perl' packages. + Grab them from any GNU archive site." + find . -type f -name Makefile.am -print | + sed 's/\.am$/.in/' | + while read f; do touch "$f"; done + ;; + + autom4te*) + echo 1>&2 "\ +WARNING: \`$1' is needed, but is $msg. + You might have modified some files without having the + proper tools for further handling them. + You can get \`$1' as part of \`Autoconf' from any GNU + archive site." + + file=`echo "$*" | sed -n "$sed_output"` + test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` + if test -f "$file"; then + touch $file + else + test -z "$file" || exec >$file + echo "#! /bin/sh" + echo "# Created by GNU Automake missing as a replacement of" + echo "# $ $@" + echo "exit 0" + chmod +x $file + exit 1 + fi + ;; + + bison*|yacc*) + echo 1>&2 "\ +WARNING: \`$1' $msg. You should only need it if + you modified a \`.y' file. You may need the \`Bison' package + in order for those modifications to take effect. You can get + \`Bison' from any GNU archive site." + rm -f y.tab.c y.tab.h + if test $# -ne 1; then + eval LASTARG="\${$#}" + case $LASTARG in + *.y) + SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` + if test -f "$SRCFILE"; then + cp "$SRCFILE" y.tab.c + fi + SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` + if test -f "$SRCFILE"; then + cp "$SRCFILE" y.tab.h + fi + ;; + esac + fi + if test ! -f y.tab.h; then + echo >y.tab.h + fi + if test ! -f y.tab.c; then + echo 'main() { return 0; }' >y.tab.c + fi + ;; + + lex*|flex*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified a \`.l' file. You may need the \`Flex' package + in order for those modifications to take effect. You can get + \`Flex' from any GNU archive site." + rm -f lex.yy.c + if test $# -ne 1; then + eval LASTARG="\${$#}" + case $LASTARG in + *.l) + SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` + if test -f "$SRCFILE"; then + cp "$SRCFILE" lex.yy.c + fi + ;; + esac + fi + if test ! -f lex.yy.c; then + echo 'main() { return 0; }' >lex.yy.c + fi + ;; + + help2man*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified a dependency of a manual page. You may need the + \`Help2man' package in order for those modifications to take + effect. You can get \`Help2man' from any GNU archive site." + + file=`echo "$*" | sed -n "$sed_output"` + test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` + if test -f "$file"; then + touch $file + else + test -z "$file" || exec >$file + echo ".ab help2man is required to generate this page" + exit $? + fi + ;; + + makeinfo*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified a \`.texi' or \`.texinfo' file, or any other file + indirectly affecting the aspect of the manual. The spurious + call might also be the consequence of using a buggy \`make' (AIX, + DU, IRIX). You might want to install the \`Texinfo' package or + the \`GNU make' package. Grab either from any GNU archive site." + # The file to touch is that specified with -o ... + file=`echo "$*" | sed -n "$sed_output"` + test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` + if test -z "$file"; then + # ... or it is the one specified with @setfilename ... + infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` + file=`sed -n ' + /^@setfilename/{ + s/.* \([^ ]*\) *$/\1/ + p + q + }' $infile` + # ... or it is derived from the source name (dir/f.texi becomes f.info) + test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info + fi + # If the file does not exist, the user really needs makeinfo; + # let's fail without touching anything. + test -f $file || exit 1 + touch $file + ;; + + tar*) + shift + + # We have already tried tar in the generic part. + # Look for gnutar/gtar before invocation to avoid ugly error + # messages. + if (gnutar --version > /dev/null 2>&1); then + gnutar "$@" && exit 0 + fi + if (gtar --version > /dev/null 2>&1); then + gtar "$@" && exit 0 + fi + firstarg="$1" + if shift; then + case $firstarg in + *o*) + firstarg=`echo "$firstarg" | sed s/o//` + tar "$firstarg" "$@" && exit 0 + ;; + esac + case $firstarg in + *h*) + firstarg=`echo "$firstarg" | sed s/h//` + tar "$firstarg" "$@" && exit 0 + ;; + esac + fi + + echo 1>&2 "\ +WARNING: I can't seem to be able to run \`tar' with the given arguments. + You may want to install GNU tar or Free paxutils, or check the + command line arguments." + exit 1 + ;; + + *) + echo 1>&2 "\ +WARNING: \`$1' is needed, and is $msg. + You might have modified some files without having the + proper tools for further handling them. Check the \`README' file, + it often tells you about the needed prerequisites for installing + this package. You may also peek at any GNU archive site, in case + some other package would contain this missing \`$1' program." + exit 1 + ;; +esac + +exit 0 # Local variables: -# eval: (add-hook 'before-save-hook 'time-stamp) +# eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" -# time-stamp-time-zone: "UTC0" +# time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: diff --git a/src/Makefile.am b/src/Makefile.am index 7b3dd97..186c042 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,89 +1,50 @@ ## Produce this file with automake to get Makefile.in -sbin_PROGRAMS = tincd +sbin_PROGRAMS = tincd tincctl + +EXTRA_DIST = linux bsd solaris cygwin mingw raw_socket uml_socket openssl gcrypt tincd_SOURCES = \ - have.h \ - system.h \ - avl_tree.c avl_tree.h \ - conf.c conf.h \ - connection.c connection.h \ - device.h \ - dropin.c dropin.h \ - dummy_device.c \ - edge.c edge.h \ - ethernet.h \ - event.c event.h \ - fake-getaddrinfo.c fake-getaddrinfo.h \ - fake-getnameinfo.c fake-getnameinfo.h \ - graph.c graph.h \ - ipv4.h \ - ipv6.h \ - list.c list.h \ - logger.c logger.h \ - meta.c meta.h \ - multicast_device.c \ - net.c net.h \ - net_packet.c \ - net_setup.c \ - net_socket.c \ - netutl.c netutl.h \ - node.c node.h \ - pidfile.c pidfile.h \ - process.c process.h \ - protocol.c protocol.h \ - protocol_auth.c \ - protocol_edge.c \ - protocol_misc.c \ - protocol_key.c \ - protocol_subnet.c \ - proxy.c proxy.h \ - raw_socket_device.c \ - route.c route.h \ - subnet.c subnet.h \ - tincd.c \ - utils.c utils.h \ - xalloc.h + utils.c getopt.c getopt1.c list.c splay_tree.c dropin.c fake-getaddrinfo.c fake-getnameinfo.c \ + buffer.c conf.c connection.c control.c edge.c graph.c logger.c meta.c net.c net_packet.c net_setup.c \ + net_socket.c netutl.c node.c process.c protocol.c protocol_auth.c protocol_edge.c protocol_misc.c \ + protocol_key.c protocol_subnet.c route.c subnet.c tincd.c -if !GETOPT -tincd_SOURCES += \ - getopt.c getopt.h \ - getopt1.c -endif +nodist_tincd_SOURCES = \ + device.c cipher.c crypto.c ecdh.c ecdsa.c digest.c prf.c rsa.c -if LINUX -tincd_SOURCES += linux/device.c -endif +tincctl_SOURCES = \ + utils.c getopt.c getopt1.c dropin.c \ + list.c tincctl.c top.c + +nodist_tincctl_SOURCES = \ + ecdsagen.c rsagen.c -if BSD -tincd_SOURCES += bsd/device.c if TUNEMU -tincd_SOURCES += bsd/tunemu.c bsd/tunemu.h -endif +tincd_SOURCES += bsd/tunemu.c endif -if SOLARIS -tincd_SOURCES += solaris/device.c -endif +tincctl_LDADD = $(CURSES_LIBS) -if MINGW -tincd_SOURCES += mingw/device.c mingw/common.h -endif +DEFAULT_INCLUDES = -if CYGWIN -tincd_SOURCES += cygwin/device.c -endif +INCLUDES = @INCLUDES@ -I$(top_builddir) -if UML -tincd_SOURCES += uml_device.c -endif +noinst_HEADERS = \ + xalloc.h utils.h getopt.h list.h splay_tree.h dropin.h fake-getaddrinfo.h fake-getnameinfo.h fake-gai-errnos.h ipv6.h ipv4.h ethernet.h \ + buffer.h conf.h connection.h control.h control_common.h device.h edge.h graph.h logger.h meta.h net.h netutl.h node.h process.h \ + protocol.h route.h subnet.h tincctl.h top.h bsd/tunemu.h -if VDE -tincd_SOURCES += vde_device.c -endif +nodist_noinst_HEADERS = \ + cipher.h crypto.h ecdh.h ecdsa.h digest.h prf.h rsa.h ecdsagen.h rsagen.h + +LIBS = @LIBS@ @LIBGCRYPT_LIBS@ if TUNEMU LIBS += -lpcap endif -AM_CPPFLAGS = -DCONFDIR=\"$(sysconfdir)\" -DRUNSTATEDIR=\"$(runstatedir)\" -DLOCALSTATEDIR=\"$(localstatedir)\" -I $(abs_top_builddir)/ +AM_CFLAGS = -DCONFDIR=\"$(sysconfdir)\" -DLOCALSTATEDIR=\"$(localstatedir)\" -DSBINDIR=\"$(sbindir)\" + +dist-hook: + rm -f `find . -type l` diff --git a/src/Makefile.in b/src/Makefile.in index 93039a2..d7e2afd 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -1,8 +1,9 @@ -# Makefile.in generated by automake 1.16.1 from Makefile.am. +# Makefile.in generated by automake 1.11.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2018 Free Software Foundation, Inc. - +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -14,62 +15,8 @@ @SET_MAKE@ + VPATH = @srcdir@ -am__is_gnu_make = { \ - if test -z '$(MAKELEVEL)'; then \ - false; \ - elif test -n '$(MAKE_HOST)'; then \ - true; \ - elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ - true; \ - else \ - false; \ - fi; \ -} -am__make_running_with_option = \ - case $${target_option-} in \ - ?) ;; \ - *) echo "am__make_running_with_option: internal error: invalid" \ - "target option '$${target_option-}' specified" >&2; \ - exit 1;; \ - esac; \ - has_opt=no; \ - sane_makeflags=$$MAKEFLAGS; \ - if $(am__is_gnu_make); then \ - sane_makeflags=$$MFLAGS; \ - else \ - case $$MAKEFLAGS in \ - *\\[\ \ ]*) \ - bs=\\; \ - sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ - | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ - esac; \ - fi; \ - skip_next=no; \ - strip_trailopt () \ - { \ - flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ - }; \ - for flg in $$sane_makeflags; do \ - test $$skip_next = yes && { skip_next=no; continue; }; \ - case $$flg in \ - *=*|--*) continue;; \ - -*I) strip_trailopt 'I'; skip_next=yes;; \ - -*I?*) strip_trailopt 'I';; \ - -*O) strip_trailopt 'O'; skip_next=yes;; \ - -*O?*) strip_trailopt 'O';; \ - -*l) strip_trailopt 'l'; skip_next=yes;; \ - -*l?*) strip_trailopt 'l';; \ - -[dEDm]) skip_next=yes;; \ - -[JT]) skip_next=yes;; \ - esac; \ - case $$flg in \ - *$$target_option*) has_opt=yes; break;; \ - esac; \ - done; \ - test $$has_opt = yes -am__make_dryrun = (target_option=n; $(am__make_running_with_option)) -am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ @@ -88,163 +35,74 @@ PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ -sbin_PROGRAMS = tincd$(EXEEXT) -@GETOPT_FALSE@am__append_1 = \ -@GETOPT_FALSE@ getopt.c getopt.h \ -@GETOPT_FALSE@ getopt1.c - -@LINUX_TRUE@am__append_2 = linux/device.c -@BSD_TRUE@am__append_3 = bsd/device.c -@BSD_TRUE@@TUNEMU_TRUE@am__append_4 = bsd/tunemu.c bsd/tunemu.h -@SOLARIS_TRUE@am__append_5 = solaris/device.c -@MINGW_TRUE@am__append_6 = mingw/device.c mingw/common.h -@CYGWIN_TRUE@am__append_7 = cygwin/device.c -@UML_TRUE@am__append_8 = uml_device.c -@VDE_TRUE@am__append_9 = vde_device.c -@TUNEMU_TRUE@am__append_10 = -lpcap +sbin_PROGRAMS = tincd$(EXEEXT) tincctl$(EXEEXT) +@TUNEMU_TRUE@am__append_1 = bsd/tunemu.c +@TUNEMU_TRUE@am__append_2 = -lpcap subdir = src +DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \ + $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \ - $(top_srcdir)/m4/ax_append_flag.m4 \ - $(top_srcdir)/m4/ax_cflags_warn_all.m4 \ - $(top_srcdir)/m4/ax_check_compile_flag.m4 \ - $(top_srcdir)/m4/ax_check_link_flag.m4 \ - $(top_srcdir)/m4/ax_require_defined.m4 $(top_srcdir)/m4/lzo.m4 \ - $(top_srcdir)/m4/openssl.m4 $(top_srcdir)/m4/zlib.m4 \ - $(top_srcdir)/configure.ac + $(top_srcdir)/m4/curses.m4 $(top_srcdir)/m4/libevent.m4 \ + $(top_srcdir)/m4/lzo.m4 $(top_srcdir)/m4/openssl.m4 \ + $(top_srcdir)/m4/zlib.m4 $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) -DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__installdirs = "$(DESTDIR)$(sbindir)" PROGRAMS = $(sbin_PROGRAMS) -am__tincd_SOURCES_DIST = have.h system.h avl_tree.c avl_tree.h conf.c \ - conf.h connection.c connection.h device.h dropin.c dropin.h \ - dummy_device.c edge.c edge.h ethernet.h event.c event.h \ - fake-getaddrinfo.c fake-getaddrinfo.h fake-getnameinfo.c \ - fake-getnameinfo.h graph.c graph.h ipv4.h ipv6.h list.c list.h \ - logger.c logger.h meta.c meta.h multicast_device.c net.c net.h \ - net_packet.c net_setup.c net_socket.c netutl.c netutl.h node.c \ - node.h pidfile.c pidfile.h process.c process.h protocol.c \ - protocol.h protocol_auth.c protocol_edge.c protocol_misc.c \ - protocol_key.c protocol_subnet.c proxy.c proxy.h \ - raw_socket_device.c route.c route.h subnet.c subnet.h tincd.c \ - utils.c utils.h xalloc.h getopt.c getopt.h getopt1.c \ - linux/device.c bsd/device.c bsd/tunemu.c bsd/tunemu.h \ - solaris/device.c mingw/device.c mingw/common.h cygwin/device.c \ - uml_device.c vde_device.c -@GETOPT_FALSE@am__objects_1 = getopt.$(OBJEXT) getopt1.$(OBJEXT) -am__dirstamp = $(am__leading_dot)dirstamp -@LINUX_TRUE@am__objects_2 = linux/device.$(OBJEXT) -@BSD_TRUE@am__objects_3 = bsd/device.$(OBJEXT) -@BSD_TRUE@@TUNEMU_TRUE@am__objects_4 = bsd/tunemu.$(OBJEXT) -@SOLARIS_TRUE@am__objects_5 = solaris/device.$(OBJEXT) -@MINGW_TRUE@am__objects_6 = mingw/device.$(OBJEXT) -@CYGWIN_TRUE@am__objects_7 = cygwin/device.$(OBJEXT) -@UML_TRUE@am__objects_8 = uml_device.$(OBJEXT) -@VDE_TRUE@am__objects_9 = vde_device.$(OBJEXT) -am_tincd_OBJECTS = avl_tree.$(OBJEXT) conf.$(OBJEXT) \ - connection.$(OBJEXT) dropin.$(OBJEXT) dummy_device.$(OBJEXT) \ - edge.$(OBJEXT) event.$(OBJEXT) fake-getaddrinfo.$(OBJEXT) \ - fake-getnameinfo.$(OBJEXT) graph.$(OBJEXT) list.$(OBJEXT) \ - logger.$(OBJEXT) meta.$(OBJEXT) multicast_device.$(OBJEXT) \ - net.$(OBJEXT) net_packet.$(OBJEXT) net_setup.$(OBJEXT) \ - net_socket.$(OBJEXT) netutl.$(OBJEXT) node.$(OBJEXT) \ - pidfile.$(OBJEXT) process.$(OBJEXT) protocol.$(OBJEXT) \ - protocol_auth.$(OBJEXT) protocol_edge.$(OBJEXT) \ - protocol_misc.$(OBJEXT) protocol_key.$(OBJEXT) \ - protocol_subnet.$(OBJEXT) proxy.$(OBJEXT) \ - raw_socket_device.$(OBJEXT) route.$(OBJEXT) subnet.$(OBJEXT) \ - tincd.$(OBJEXT) utils.$(OBJEXT) $(am__objects_1) \ - $(am__objects_2) $(am__objects_3) $(am__objects_4) \ - $(am__objects_5) $(am__objects_6) $(am__objects_7) \ - $(am__objects_8) $(am__objects_9) -tincd_OBJECTS = $(am_tincd_OBJECTS) +am_tincctl_OBJECTS = utils.$(OBJEXT) getopt.$(OBJEXT) \ + getopt1.$(OBJEXT) dropin.$(OBJEXT) list.$(OBJEXT) \ + tincctl.$(OBJEXT) top.$(OBJEXT) +nodist_tincctl_OBJECTS = ecdsagen.$(OBJEXT) rsagen.$(OBJEXT) +tincctl_OBJECTS = $(am_tincctl_OBJECTS) $(nodist_tincctl_OBJECTS) +am__DEPENDENCIES_1 = +tincctl_DEPENDENCIES = $(am__DEPENDENCIES_1) +am__tincd_SOURCES_DIST = utils.c getopt.c getopt1.c list.c \ + splay_tree.c dropin.c fake-getaddrinfo.c fake-getnameinfo.c \ + buffer.c conf.c connection.c control.c edge.c graph.c logger.c \ + meta.c net.c net_packet.c net_setup.c net_socket.c netutl.c \ + node.c process.c protocol.c protocol_auth.c protocol_edge.c \ + protocol_misc.c protocol_key.c protocol_subnet.c route.c \ + subnet.c tincd.c bsd/tunemu.c +@TUNEMU_TRUE@am__objects_1 = tunemu.$(OBJEXT) +am_tincd_OBJECTS = utils.$(OBJEXT) getopt.$(OBJEXT) getopt1.$(OBJEXT) \ + list.$(OBJEXT) splay_tree.$(OBJEXT) dropin.$(OBJEXT) \ + fake-getaddrinfo.$(OBJEXT) fake-getnameinfo.$(OBJEXT) \ + buffer.$(OBJEXT) conf.$(OBJEXT) connection.$(OBJEXT) \ + control.$(OBJEXT) edge.$(OBJEXT) graph.$(OBJEXT) \ + logger.$(OBJEXT) meta.$(OBJEXT) net.$(OBJEXT) \ + net_packet.$(OBJEXT) net_setup.$(OBJEXT) net_socket.$(OBJEXT) \ + netutl.$(OBJEXT) node.$(OBJEXT) process.$(OBJEXT) \ + protocol.$(OBJEXT) protocol_auth.$(OBJEXT) \ + protocol_edge.$(OBJEXT) protocol_misc.$(OBJEXT) \ + protocol_key.$(OBJEXT) protocol_subnet.$(OBJEXT) \ + route.$(OBJEXT) subnet.$(OBJEXT) tincd.$(OBJEXT) \ + $(am__objects_1) +nodist_tincd_OBJECTS = device.$(OBJEXT) cipher.$(OBJEXT) \ + crypto.$(OBJEXT) ecdh.$(OBJEXT) ecdsa.$(OBJEXT) \ + digest.$(OBJEXT) prf.$(OBJEXT) rsa.$(OBJEXT) +tincd_OBJECTS = $(am_tincd_OBJECTS) $(nodist_tincd_OBJECTS) tincd_LDADD = $(LDADD) -AM_V_P = $(am__v_P_@AM_V@) -am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) -am__v_P_0 = false -am__v_P_1 = : -AM_V_GEN = $(am__v_GEN_@AM_V@) -am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) -am__v_GEN_0 = @echo " GEN " $@; -am__v_GEN_1 = -AM_V_at = $(am__v_at_@AM_V@) -am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) -am__v_at_0 = @ -am__v_at_1 = -DEFAULT_INCLUDES = depcomp = $(SHELL) $(top_srcdir)/depcomp -am__maybe_remake_depfiles = depfiles -am__depfiles_remade = ./$(DEPDIR)/avl_tree.Po ./$(DEPDIR)/conf.Po \ - ./$(DEPDIR)/connection.Po ./$(DEPDIR)/dropin.Po \ - ./$(DEPDIR)/dummy_device.Po ./$(DEPDIR)/edge.Po \ - ./$(DEPDIR)/event.Po ./$(DEPDIR)/fake-getaddrinfo.Po \ - ./$(DEPDIR)/fake-getnameinfo.Po ./$(DEPDIR)/getopt.Po \ - ./$(DEPDIR)/getopt1.Po ./$(DEPDIR)/graph.Po \ - ./$(DEPDIR)/list.Po ./$(DEPDIR)/logger.Po ./$(DEPDIR)/meta.Po \ - ./$(DEPDIR)/multicast_device.Po ./$(DEPDIR)/net.Po \ - ./$(DEPDIR)/net_packet.Po ./$(DEPDIR)/net_setup.Po \ - ./$(DEPDIR)/net_socket.Po ./$(DEPDIR)/netutl.Po \ - ./$(DEPDIR)/node.Po ./$(DEPDIR)/pidfile.Po \ - ./$(DEPDIR)/process.Po ./$(DEPDIR)/protocol.Po \ - ./$(DEPDIR)/protocol_auth.Po ./$(DEPDIR)/protocol_edge.Po \ - ./$(DEPDIR)/protocol_key.Po ./$(DEPDIR)/protocol_misc.Po \ - ./$(DEPDIR)/protocol_subnet.Po ./$(DEPDIR)/proxy.Po \ - ./$(DEPDIR)/raw_socket_device.Po ./$(DEPDIR)/route.Po \ - ./$(DEPDIR)/subnet.Po ./$(DEPDIR)/tincd.Po \ - ./$(DEPDIR)/uml_device.Po ./$(DEPDIR)/utils.Po \ - ./$(DEPDIR)/vde_device.Po bsd/$(DEPDIR)/device.Po \ - bsd/$(DEPDIR)/tunemu.Po cygwin/$(DEPDIR)/device.Po \ - linux/$(DEPDIR)/device.Po mingw/$(DEPDIR)/device.Po \ - solaris/$(DEPDIR)/device.Po +am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -AM_V_CC = $(am__v_CC_@AM_V@) -am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) -am__v_CC_0 = @echo " CC " $@; -am__v_CC_1 = CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ -AM_V_CCLD = $(am__v_CCLD_@AM_V@) -am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) -am__v_CCLD_0 = @echo " CCLD " $@; -am__v_CCLD_1 = -SOURCES = $(tincd_SOURCES) -DIST_SOURCES = $(am__tincd_SOURCES_DIST) -am__can_run_installinfo = \ - case $$AM_UPDATE_INFO_DIR in \ - n|no|NO) false;; \ - *) (install-info --version) >/dev/null 2>&1;; \ - esac -am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) -# Read a list of newline-separated strings from the standard input, -# and print each of them once, without duplicates. Input order is -# *not* preserved. -am__uniquify_input = $(AWK) '\ - BEGIN { nonempty = 0; } \ - { items[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in items) print i; }; } \ -' -# Make sure the list of sources is unique. This is necessary because, -# e.g., the same source file might be shared among _SOURCES variables -# for different programs/libraries. -am__define_uniq_tagged_files = \ - list='$(am__tagged_files)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | $(am__uniquify_input)` +SOURCES = $(tincctl_SOURCES) $(nodist_tincctl_SOURCES) \ + $(tincd_SOURCES) $(nodist_tincd_SOURCES) +DIST_SOURCES = $(tincctl_SOURCES) $(am__tincd_SOURCES_DIST) +HEADERS = $(nodist_noinst_HEADERS) $(noinst_HEADERS) ETAGS = etags CTAGS = ctags -am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ -AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ @@ -254,6 +112,7 @@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ +CURSES_LIBS = @CURSES_LIBS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ @@ -263,15 +122,21 @@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ GREP = @GREP@ +INCLUDES = @INCLUDES@ -I$(top_builddir) INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ +LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ +LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ +LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ LIBOBJS = @LIBOBJS@ -LIBS = @LIBS@ $(am__append_10) +LIBS = @LIBS@ @LIBGCRYPT_LIBS@ $(am__append_2) +LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ OBJEXT = @OBJEXT@ @@ -283,6 +148,7 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ @@ -329,37 +195,48 @@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ -runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ -systemd_path = @systemd_path@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ -tincd_SOURCES = have.h system.h avl_tree.c avl_tree.h conf.c conf.h \ - connection.c connection.h device.h dropin.c dropin.h \ - dummy_device.c edge.c edge.h ethernet.h event.c event.h \ - fake-getaddrinfo.c fake-getaddrinfo.h fake-getnameinfo.c \ - fake-getnameinfo.h graph.c graph.h ipv4.h ipv6.h list.c list.h \ - logger.c logger.h meta.c meta.h multicast_device.c net.c net.h \ - net_packet.c net_setup.c net_socket.c netutl.c netutl.h node.c \ - node.h pidfile.c pidfile.h process.c process.h protocol.c \ - protocol.h protocol_auth.c protocol_edge.c protocol_misc.c \ - protocol_key.c protocol_subnet.c proxy.c proxy.h \ - raw_socket_device.c route.c route.h subnet.c subnet.h tincd.c \ - utils.c utils.h xalloc.h $(am__append_1) $(am__append_2) \ - $(am__append_3) $(am__append_4) $(am__append_5) \ - $(am__append_6) $(am__append_7) $(am__append_8) \ - $(am__append_9) -AM_CPPFLAGS = -DCONFDIR=\"$(sysconfdir)\" -DRUNSTATEDIR=\"$(runstatedir)\" -DLOCALSTATEDIR=\"$(localstatedir)\" -I $(abs_top_builddir)/ +EXTRA_DIST = linux bsd solaris cygwin mingw raw_socket uml_socket openssl gcrypt +tincd_SOURCES = utils.c getopt.c getopt1.c list.c splay_tree.c \ + dropin.c fake-getaddrinfo.c fake-getnameinfo.c buffer.c conf.c \ + connection.c control.c edge.c graph.c logger.c meta.c net.c \ + net_packet.c net_setup.c net_socket.c netutl.c node.c \ + process.c protocol.c protocol_auth.c protocol_edge.c \ + protocol_misc.c protocol_key.c protocol_subnet.c route.c \ + subnet.c tincd.c $(am__append_1) +nodist_tincd_SOURCES = \ + device.c cipher.c crypto.c ecdh.c ecdsa.c digest.c prf.c rsa.c + +tincctl_SOURCES = \ + utils.c getopt.c getopt1.c dropin.c \ + list.c tincctl.c top.c + +nodist_tincctl_SOURCES = \ + ecdsagen.c rsagen.c + +tincctl_LDADD = $(CURSES_LIBS) +DEFAULT_INCLUDES = +noinst_HEADERS = \ + xalloc.h utils.h getopt.h list.h splay_tree.h dropin.h fake-getaddrinfo.h fake-getnameinfo.h fake-gai-errnos.h ipv6.h ipv4.h ethernet.h \ + buffer.h conf.h connection.h control.h control_common.h device.h edge.h graph.h logger.h meta.h net.h netutl.h node.h process.h \ + protocol.h route.h subnet.h tincctl.h top.h bsd/tunemu.h + +nodist_noinst_HEADERS = \ + cipher.h crypto.h ecdh.h ecdsa.h digest.h prf.h rsa.h ecdsagen.h rsagen.h + +AM_CFLAGS = -DCONFDIR=\"$(sysconfdir)\" -DLOCALSTATEDIR=\"$(localstatedir)\" -DSBINDIR=\"$(sbindir)\" all: all-am .SUFFIXES: .SUFFIXES: .c .o .obj -$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ @@ -371,37 +248,34 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu src/Makefile +.PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(top_srcdir)/configure: $(am__configure_deps) +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(ACLOCAL_M4): $(am__aclocal_m4_deps) +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-sbinPROGRAMS: $(sbin_PROGRAMS) @$(NORMAL_INSTALL) + test -z "$(sbindir)" || $(MKDIR_P) "$(DESTDIR)$(sbindir)" @list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \ - if test -n "$$list"; then \ - echo " $(MKDIR_P) '$(DESTDIR)$(sbindir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(sbindir)" || exit 1; \ - fi; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ - while read p p1; do if test -f $$p \ - ; then echo "$$p"; echo "$$p"; else :; fi; \ + while read p p1; do if test -f $$p; \ + then echo "$$p"; echo "$$p"; else :; fi; \ done | \ - sed -e 'p;s,.*/,,;n;h' \ - -e 's|.*|.|' \ + sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ @@ -422,164 +296,120 @@ uninstall-sbinPROGRAMS: @list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ - -e 's/$$/$(EXEEXT)/' \ - `; \ + -e 's/$$/$(EXEEXT)/' `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(sbindir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(sbindir)" && rm -f $$files clean-sbinPROGRAMS: -test -z "$(sbin_PROGRAMS)" || rm -f $(sbin_PROGRAMS) - -installcheck-sbinPROGRAMS: $(sbin_PROGRAMS) - bad=0; pid=$$$$; list="$(sbin_PROGRAMS)"; for p in $$list; do \ - case ' $(AM_INSTALLCHECK_STD_OPTIONS_EXEMPT) ' in \ - *" $$p "* | *" $(srcdir)/$$p "*) continue;; \ - esac; \ - f=`echo "$$p" | \ - sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \ - for opt in --help --version; do \ - if "$(DESTDIR)$(sbindir)/$$f" $$opt >c$${pid}_.out \ - 2>c$${pid}_.err &2; bad=1; fi; \ - done; \ - done; rm -f c$${pid}_.???; exit $$bad -linux/$(am__dirstamp): - @$(MKDIR_P) linux - @: > linux/$(am__dirstamp) -linux/$(DEPDIR)/$(am__dirstamp): - @$(MKDIR_P) linux/$(DEPDIR) - @: > linux/$(DEPDIR)/$(am__dirstamp) -linux/device.$(OBJEXT): linux/$(am__dirstamp) \ - linux/$(DEPDIR)/$(am__dirstamp) -bsd/$(am__dirstamp): - @$(MKDIR_P) bsd - @: > bsd/$(am__dirstamp) -bsd/$(DEPDIR)/$(am__dirstamp): - @$(MKDIR_P) bsd/$(DEPDIR) - @: > bsd/$(DEPDIR)/$(am__dirstamp) -bsd/device.$(OBJEXT): bsd/$(am__dirstamp) \ - bsd/$(DEPDIR)/$(am__dirstamp) -bsd/tunemu.$(OBJEXT): bsd/$(am__dirstamp) \ - bsd/$(DEPDIR)/$(am__dirstamp) -solaris/$(am__dirstamp): - @$(MKDIR_P) solaris - @: > solaris/$(am__dirstamp) -solaris/$(DEPDIR)/$(am__dirstamp): - @$(MKDIR_P) solaris/$(DEPDIR) - @: > solaris/$(DEPDIR)/$(am__dirstamp) -solaris/device.$(OBJEXT): solaris/$(am__dirstamp) \ - solaris/$(DEPDIR)/$(am__dirstamp) -mingw/$(am__dirstamp): - @$(MKDIR_P) mingw - @: > mingw/$(am__dirstamp) -mingw/$(DEPDIR)/$(am__dirstamp): - @$(MKDIR_P) mingw/$(DEPDIR) - @: > mingw/$(DEPDIR)/$(am__dirstamp) -mingw/device.$(OBJEXT): mingw/$(am__dirstamp) \ - mingw/$(DEPDIR)/$(am__dirstamp) -cygwin/$(am__dirstamp): - @$(MKDIR_P) cygwin - @: > cygwin/$(am__dirstamp) -cygwin/$(DEPDIR)/$(am__dirstamp): - @$(MKDIR_P) cygwin/$(DEPDIR) - @: > cygwin/$(DEPDIR)/$(am__dirstamp) -cygwin/device.$(OBJEXT): cygwin/$(am__dirstamp) \ - cygwin/$(DEPDIR)/$(am__dirstamp) - -tincd$(EXEEXT): $(tincd_OBJECTS) $(tincd_DEPENDENCIES) $(EXTRA_tincd_DEPENDENCIES) +tincctl$(EXEEXT): $(tincctl_OBJECTS) $(tincctl_DEPENDENCIES) + @rm -f tincctl$(EXEEXT) + $(LINK) $(tincctl_OBJECTS) $(tincctl_LDADD) $(LIBS) +tincd$(EXEEXT): $(tincd_OBJECTS) $(tincd_DEPENDENCIES) @rm -f tincd$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(tincd_OBJECTS) $(tincd_LDADD) $(LIBS) + $(LINK) $(tincd_OBJECTS) $(tincd_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) - -rm -f bsd/*.$(OBJEXT) - -rm -f cygwin/*.$(OBJEXT) - -rm -f linux/*.$(OBJEXT) - -rm -f mingw/*.$(OBJEXT) - -rm -f solaris/*.$(OBJEXT) distclean-compile: -rm -f *.tab.c -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/avl_tree.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/conf.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/connection.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dropin.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dummy_device.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/edge.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/event.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fake-getaddrinfo.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fake-getnameinfo.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getopt.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getopt1.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/graph.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/list.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/logger.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/meta.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/multicast_device.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/net.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/net_packet.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/net_setup.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/net_socket.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/netutl.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/node.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pidfile.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/process.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protocol.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protocol_auth.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protocol_edge.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protocol_key.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protocol_misc.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protocol_subnet.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/proxy.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/raw_socket_device.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/route.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/subnet.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tincd.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uml_device.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/utils.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vde_device.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@bsd/$(DEPDIR)/device.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@bsd/$(DEPDIR)/tunemu.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@cygwin/$(DEPDIR)/device.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@linux/$(DEPDIR)/device.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@mingw/$(DEPDIR)/device.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@solaris/$(DEPDIR)/device.Po@am__quote@ # am--include-marker - -$(am__depfiles_remade): - @$(MKDIR_P) $(@D) - @echo '# dummy' >$@-t && $(am__mv) $@-t $@ - -am--depfiles: $(am__depfiles_remade) +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/buffer.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cipher.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/conf.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/connection.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/control.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/crypto.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/device.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/digest.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dropin.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ecdh.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ecdsa.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ecdsagen.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/edge.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fake-getaddrinfo.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fake-getnameinfo.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getopt.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getopt1.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/graph.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/list.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/logger.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/meta.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/net.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/net_packet.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/net_setup.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/net_socket.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/netutl.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/node.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/prf.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/process.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protocol.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protocol_auth.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protocol_edge.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protocol_key.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protocol_misc.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protocol_subnet.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/route.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rsa.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rsagen.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/splay_tree.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/subnet.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tincctl.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tincd.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/top.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tunemu.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/utils.Po@am__quote@ .c.o: -@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ -@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< +@am__fastdepCC_FALSE@ $(COMPILE) -c $< .c.obj: -@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ -@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` -ID: $(am__tagged_files) - $(am__define_uniq_tagged_files); mkid -fID $$unique -tags: tags-am -TAGS: tags +tunemu.o: bsd/tunemu.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tunemu.o -MD -MP -MF $(DEPDIR)/tunemu.Tpo -c -o tunemu.o `test -f 'bsd/tunemu.c' || echo '$(srcdir)/'`bsd/tunemu.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/tunemu.Tpo $(DEPDIR)/tunemu.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='bsd/tunemu.c' object='tunemu.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tunemu.o `test -f 'bsd/tunemu.c' || echo '$(srcdir)/'`bsd/tunemu.c -tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) +tunemu.obj: bsd/tunemu.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tunemu.obj -MD -MP -MF $(DEPDIR)/tunemu.Tpo -c -o tunemu.obj `if test -f 'bsd/tunemu.c'; then $(CYGPATH_W) 'bsd/tunemu.c'; else $(CYGPATH_W) '$(srcdir)/bsd/tunemu.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/tunemu.Tpo $(DEPDIR)/tunemu.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='bsd/tunemu.c' object='tunemu.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tunemu.obj `if test -f 'bsd/tunemu.c'; then $(CYGPATH_W) 'bsd/tunemu.c'; else $(CYGPATH_W) '$(srcdir)/bsd/tunemu.c'; fi` + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ - $(am__define_uniq_tagged_files); \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ @@ -591,11 +421,15 @@ tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $$unique; \ fi; \ fi -ctags: ctags-am - -CTAGS: ctags -ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - $(am__define_uniq_tagged_files); \ +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique @@ -604,29 +438,11 @@ GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" -cscopelist: cscopelist-am - -cscopelist-am: $(am__tagged_files) - list='$(am__tagged_files)'; \ - case "$(srcdir)" in \ - [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ - *) sdir=$(subdir)/$(srcdir) ;; \ - esac; \ - for i in $$list; do \ - if test -f "$$i"; then \ - echo "$(subdir)/$$i"; \ - else \ - echo "$$sdir/$$i"; \ - fi; \ - done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags -distdir: $(BUILT_SOURCES) - $(MAKE) $(AM_MAKEFLAGS) distdir-am - -distdir-am: $(DISTFILES) +distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ @@ -656,9 +472,12 @@ distdir-am: $(DISTFILES) || exit 1; \ fi; \ done + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$(top_distdir)" distdir="$(distdir)" \ + dist-hook check-am: all-am check: check-am -all-am: Makefile $(PROGRAMS) +all-am: Makefile $(PROGRAMS) $(HEADERS) installdirs: for dir in "$(DESTDIR)$(sbindir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ @@ -673,15 +492,10 @@ install-am: all-am installcheck: installcheck-am install-strip: - if test -z '$(STRIP)'; then \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - install; \ - else \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ - fi + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: @@ -689,16 +503,6 @@ clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) - -rm -f bsd/$(DEPDIR)/$(am__dirstamp) - -rm -f bsd/$(am__dirstamp) - -rm -f cygwin/$(DEPDIR)/$(am__dirstamp) - -rm -f cygwin/$(am__dirstamp) - -rm -f linux/$(DEPDIR)/$(am__dirstamp) - -rm -f linux/$(am__dirstamp) - -rm -f mingw/$(DEPDIR)/$(am__dirstamp) - -rm -f mingw/$(am__dirstamp) - -rm -f solaris/$(DEPDIR)/$(am__dirstamp) - -rm -f solaris/$(am__dirstamp) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @@ -708,50 +512,7 @@ clean: clean-am clean-am: clean-generic clean-sbinPROGRAMS mostlyclean-am distclean: distclean-am - -rm -f ./$(DEPDIR)/avl_tree.Po - -rm -f ./$(DEPDIR)/conf.Po - -rm -f ./$(DEPDIR)/connection.Po - -rm -f ./$(DEPDIR)/dropin.Po - -rm -f ./$(DEPDIR)/dummy_device.Po - -rm -f ./$(DEPDIR)/edge.Po - -rm -f ./$(DEPDIR)/event.Po - -rm -f ./$(DEPDIR)/fake-getaddrinfo.Po - -rm -f ./$(DEPDIR)/fake-getnameinfo.Po - -rm -f ./$(DEPDIR)/getopt.Po - -rm -f ./$(DEPDIR)/getopt1.Po - -rm -f ./$(DEPDIR)/graph.Po - -rm -f ./$(DEPDIR)/list.Po - -rm -f ./$(DEPDIR)/logger.Po - -rm -f ./$(DEPDIR)/meta.Po - -rm -f ./$(DEPDIR)/multicast_device.Po - -rm -f ./$(DEPDIR)/net.Po - -rm -f ./$(DEPDIR)/net_packet.Po - -rm -f ./$(DEPDIR)/net_setup.Po - -rm -f ./$(DEPDIR)/net_socket.Po - -rm -f ./$(DEPDIR)/netutl.Po - -rm -f ./$(DEPDIR)/node.Po - -rm -f ./$(DEPDIR)/pidfile.Po - -rm -f ./$(DEPDIR)/process.Po - -rm -f ./$(DEPDIR)/protocol.Po - -rm -f ./$(DEPDIR)/protocol_auth.Po - -rm -f ./$(DEPDIR)/protocol_edge.Po - -rm -f ./$(DEPDIR)/protocol_key.Po - -rm -f ./$(DEPDIR)/protocol_misc.Po - -rm -f ./$(DEPDIR)/protocol_subnet.Po - -rm -f ./$(DEPDIR)/proxy.Po - -rm -f ./$(DEPDIR)/raw_socket_device.Po - -rm -f ./$(DEPDIR)/route.Po - -rm -f ./$(DEPDIR)/subnet.Po - -rm -f ./$(DEPDIR)/tincd.Po - -rm -f ./$(DEPDIR)/uml_device.Po - -rm -f ./$(DEPDIR)/utils.Po - -rm -f ./$(DEPDIR)/vde_device.Po - -rm -f bsd/$(DEPDIR)/device.Po - -rm -f bsd/$(DEPDIR)/tunemu.Po - -rm -f cygwin/$(DEPDIR)/device.Po - -rm -f linux/$(DEPDIR)/device.Po - -rm -f mingw/$(DEPDIR)/device.Po - -rm -f solaris/$(DEPDIR)/device.Po + -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags @@ -794,53 +555,10 @@ install-ps: install-ps-am install-ps-am: -installcheck-am: installcheck-sbinPROGRAMS +installcheck-am: maintainer-clean: maintainer-clean-am - -rm -f ./$(DEPDIR)/avl_tree.Po - -rm -f ./$(DEPDIR)/conf.Po - -rm -f ./$(DEPDIR)/connection.Po - -rm -f ./$(DEPDIR)/dropin.Po - -rm -f ./$(DEPDIR)/dummy_device.Po - -rm -f ./$(DEPDIR)/edge.Po - -rm -f ./$(DEPDIR)/event.Po - -rm -f ./$(DEPDIR)/fake-getaddrinfo.Po - -rm -f ./$(DEPDIR)/fake-getnameinfo.Po - -rm -f ./$(DEPDIR)/getopt.Po - -rm -f ./$(DEPDIR)/getopt1.Po - -rm -f ./$(DEPDIR)/graph.Po - -rm -f ./$(DEPDIR)/list.Po - -rm -f ./$(DEPDIR)/logger.Po - -rm -f ./$(DEPDIR)/meta.Po - -rm -f ./$(DEPDIR)/multicast_device.Po - -rm -f ./$(DEPDIR)/net.Po - -rm -f ./$(DEPDIR)/net_packet.Po - -rm -f ./$(DEPDIR)/net_setup.Po - -rm -f ./$(DEPDIR)/net_socket.Po - -rm -f ./$(DEPDIR)/netutl.Po - -rm -f ./$(DEPDIR)/node.Po - -rm -f ./$(DEPDIR)/pidfile.Po - -rm -f ./$(DEPDIR)/process.Po - -rm -f ./$(DEPDIR)/protocol.Po - -rm -f ./$(DEPDIR)/protocol_auth.Po - -rm -f ./$(DEPDIR)/protocol_edge.Po - -rm -f ./$(DEPDIR)/protocol_key.Po - -rm -f ./$(DEPDIR)/protocol_misc.Po - -rm -f ./$(DEPDIR)/protocol_subnet.Po - -rm -f ./$(DEPDIR)/proxy.Po - -rm -f ./$(DEPDIR)/raw_socket_device.Po - -rm -f ./$(DEPDIR)/route.Po - -rm -f ./$(DEPDIR)/subnet.Po - -rm -f ./$(DEPDIR)/tincd.Po - -rm -f ./$(DEPDIR)/uml_device.Po - -rm -f ./$(DEPDIR)/utils.Po - -rm -f ./$(DEPDIR)/vde_device.Po - -rm -f bsd/$(DEPDIR)/device.Po - -rm -f bsd/$(DEPDIR)/tunemu.Po - -rm -f cygwin/$(DEPDIR)/device.Po - -rm -f linux/$(DEPDIR)/device.Po - -rm -f mingw/$(DEPDIR)/device.Po - -rm -f solaris/$(DEPDIR)/device.Po + -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic @@ -860,22 +578,22 @@ uninstall-am: uninstall-sbinPROGRAMS .MAKE: install-am install-strip -.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ - clean-generic clean-sbinPROGRAMS cscopelist-am ctags ctags-am \ - distclean distclean-compile distclean-generic distclean-tags \ - distdir dvi dvi-am html html-am info info-am install \ - install-am install-data install-data-am install-dvi \ - install-dvi-am install-exec install-exec-am install-html \ - install-html-am install-info install-info-am install-man \ - install-pdf install-pdf-am install-ps install-ps-am \ - install-sbinPROGRAMS install-strip installcheck \ - installcheck-am installcheck-sbinPROGRAMS installdirs \ - maintainer-clean maintainer-clean-generic mostlyclean \ - mostlyclean-compile mostlyclean-generic pdf pdf-am ps ps-am \ - tags tags-am uninstall uninstall-am uninstall-sbinPROGRAMS +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-sbinPROGRAMS ctags dist-hook distclean distclean-compile \ + distclean-generic distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-ps install-ps-am install-sbinPROGRAMS install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \ + uninstall-am uninstall-sbinPROGRAMS -.PRECIOUS: Makefile +dist-hook: + rm -f `find . -type l` # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. diff --git a/src/avl_tree.c b/src/avl_tree.c deleted file mode 100644 index 96d3d43..0000000 --- a/src/avl_tree.c +++ /dev/null @@ -1,757 +0,0 @@ -/* - avl_tree.c -- avl_ tree and linked list convenience - Copyright (C) 1998 Michael H. Buselli - 2000-2005 Ivo Timmermans, - 2000-2015 Guus Sliepen - 2000-2005 Wessel Dankers - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - - Original AVL tree library by Michael H. Buselli . - - Modified 2000-11-28 by Wessel Dankers to use counts - instead of depths, to add the ->next and ->prev and to generally obfuscate - the code. Mail me if you found a bug. - - Cleaned up and incorporated some of the ideas from the red-black tree - library for inclusion into tinc (https://www.tinc-vpn.org/) by - Guus Sliepen . -*/ - -#include "system.h" - -#include "avl_tree.h" -#include "xalloc.h" - -#ifdef AVL_COUNT -#define AVL_NODE_COUNT(n) ((n) ? (n)->count : 0) -#define AVL_L_COUNT(n) (AVL_NODE_COUNT((n)->left)) -#define AVL_R_COUNT(n) (AVL_NODE_COUNT((n)->right)) -#define AVL_CALC_COUNT(n) (AVL_L_COUNT(n) + AVL_R_COUNT(n) + 1) -#endif - -#ifdef AVL_DEPTH -#define AVL_NODE_DEPTH(n) ((n) ? (n)->depth : 0) -#define L_AVL_DEPTH(n) (AVL_NODE_DEPTH((n)->left)) -#define R_AVL_DEPTH(n) (AVL_NODE_DEPTH((n)->right)) -#define AVL_CALC_DEPTH(n) ((L_AVL_DEPTH(n)>R_AVL_DEPTH(n)?L_AVL_DEPTH(n):R_AVL_DEPTH(n)) + 1) -#endif - -#ifndef AVL_DEPTH -static int lg(unsigned int u) __attribute__((__const__)); - -static int lg(unsigned int u) { - int r = 1; - - if(!u) { - return 0; - } - - if(u & 0xffff0000) { - u >>= 16; - r += 16; - } - - if(u & 0x0000ff00) { - u >>= 8; - r += 8; - } - - if(u & 0x000000f0) { - u >>= 4; - r += 4; - } - - if(u & 0x0000000c) { - u >>= 2; - r += 2; - } - - if(u & 0x00000002) { - r++; - } - - return r; -} -#endif - -/* Internal helper functions */ - -static int avl_check_balance(const avl_node_t *node) { -#ifdef AVL_DEPTH - int d; - - d = R_AVL_DEPTH(node) - L_AVL_DEPTH(node); - - return d < -1 ? -1 : d > 1 ? 1 : 0; -#else - /* int d; - * d = lg(AVL_R_COUNT(node)) - lg(AVL_L_COUNT(node)); - * d = d<-1?-1:d>1?1:0; - */ - int pl, r; - - pl = lg(AVL_L_COUNT(node)); - r = AVL_R_COUNT(node); - - if(r >> pl + 1) { - return 1; - } - - if(pl < 2 || r >> pl - 2) { - return 0; - } - - return -1; -#endif -} - -static void avl_rebalance(avl_tree_t *tree, avl_node_t *node) { - avl_node_t *child; - avl_node_t *gchild; - avl_node_t *parent; - avl_node_t **superparent; - - while(node) { - parent = node->parent; - - superparent = - parent ? node == - parent->left ? &parent->left : &parent->right : &tree->root; - - switch(avl_check_balance(node)) { - case -1: - child = node->left; -#ifdef AVL_DEPTH - - if(L_AVL_DEPTH(child) >= R_AVL_DEPTH(child)) { -#else - - if(AVL_L_COUNT(child) >= AVL_R_COUNT(child)) { -#endif - node->left = child->right; - - if(node->left) { - node->left->parent = node; - } - - child->right = node; - node->parent = child; - *superparent = child; - child->parent = parent; -#ifdef AVL_COUNT - node->count = AVL_CALC_COUNT(node); - child->count = AVL_CALC_COUNT(child); -#endif -#ifdef AVL_DEPTH - node->depth = AVL_CALC_DEPTH(node); - child->depth = AVL_CALC_DEPTH(child); -#endif - } else { - gchild = child->right; - node->left = gchild->right; - - if(node->left) { - node->left->parent = node; - } - - child->right = gchild->left; - - if(child->right) { - child->right->parent = child; - } - - gchild->right = node; - - gchild->right->parent = gchild; - gchild->left = child; - - gchild->left->parent = gchild; - - *superparent = gchild; - gchild->parent = parent; -#ifdef AVL_COUNT - node->count = AVL_CALC_COUNT(node); - child->count = AVL_CALC_COUNT(child); - gchild->count = AVL_CALC_COUNT(gchild); -#endif -#ifdef AVL_DEPTH - node->depth = AVL_CALC_DEPTH(node); - child->depth = AVL_CALC_DEPTH(child); - gchild->depth = AVL_CALC_DEPTH(gchild); -#endif - } - - break; - - case 1: - child = node->right; -#ifdef AVL_DEPTH - - if(R_AVL_DEPTH(child) >= L_AVL_DEPTH(child)) { -#else - - if(AVL_R_COUNT(child) >= AVL_L_COUNT(child)) { -#endif - node->right = child->left; - - if(node->right) { - node->right->parent = node; - } - - child->left = node; - node->parent = child; - *superparent = child; - child->parent = parent; -#ifdef AVL_COUNT - node->count = AVL_CALC_COUNT(node); - child->count = AVL_CALC_COUNT(child); -#endif -#ifdef AVL_DEPTH - node->depth = AVL_CALC_DEPTH(node); - child->depth = AVL_CALC_DEPTH(child); -#endif - } else { - gchild = child->left; - node->right = gchild->left; - - if(node->right) { - node->right->parent = node; - } - - child->left = gchild->right; - - if(child->left) { - child->left->parent = child; - } - - gchild->left = node; - - gchild->left->parent = gchild; - gchild->right = child; - - gchild->right->parent = gchild; - - *superparent = gchild; - gchild->parent = parent; -#ifdef AVL_COUNT - node->count = AVL_CALC_COUNT(node); - child->count = AVL_CALC_COUNT(child); - gchild->count = AVL_CALC_COUNT(gchild); -#endif -#ifdef AVL_DEPTH - node->depth = AVL_CALC_DEPTH(node); - child->depth = AVL_CALC_DEPTH(child); - gchild->depth = AVL_CALC_DEPTH(gchild); -#endif - } - - break; - - default: -#ifdef AVL_COUNT - node->count = AVL_CALC_COUNT(node); -#endif -#ifdef AVL_DEPTH - node->depth = AVL_CALC_DEPTH(node); -#endif - } - - node = parent; - } -} - -/* (De)constructors */ - -avl_tree_t *avl_alloc_tree(avl_compare_t compare, avl_action_t delete) { - avl_tree_t *tree; - - tree = xmalloc_and_zero(sizeof(avl_tree_t)); - tree->compare = compare; - tree->delete = delete; - - return tree; -} - -void avl_free_tree(avl_tree_t *tree) { - free(tree); -} - -avl_node_t *avl_alloc_node(void) { - return xmalloc_and_zero(sizeof(avl_node_t)); -} - -void avl_free_node(avl_tree_t *tree, avl_node_t *node) { - if(node->data && tree->delete) { - tree->delete(node->data); - } - - free(node); -} - -/* Searching */ - -void *avl_search(const avl_tree_t *tree, const void *data) { - avl_node_t *node; - - node = avl_search_node(tree, data); - - return node ? node->data : NULL; -} - -void *avl_search_closest(const avl_tree_t *tree, const void *data, int *result) { - avl_node_t *node; - - node = avl_search_closest_node(tree, data, result); - - return node ? node->data : NULL; -} - -void *avl_search_closest_smaller(const avl_tree_t *tree, const void *data) { - avl_node_t *node; - - node = avl_search_closest_smaller_node(tree, data); - - return node ? node->data : NULL; -} - -void *avl_search_closest_greater(const avl_tree_t *tree, const void *data) { - avl_node_t *node; - - node = avl_search_closest_greater_node(tree, data); - - return node ? node->data : NULL; -} - -avl_node_t *avl_search_node(const avl_tree_t *tree, const void *data) { - avl_node_t *node; - int result; - - node = avl_search_closest_node(tree, data, &result); - - return result ? NULL : node; -} - -avl_node_t *avl_search_closest_node(const avl_tree_t *tree, const void *data, - int *result) { - avl_node_t *node; - int c; - - node = tree->root; - - if(!node) { - if(result) { - *result = 0; - } - - return NULL; - } - - for(;;) { - c = tree->compare(data, node->data); - - if(c < 0) { - if(node->left) { - node = node->left; - } else { - if(result) { - *result = -1; - } - - break; - } - } else if(c > 0) { - if(node->right) { - node = node->right; - } else { - if(result) { - *result = 1; - } - - break; - } - } else { - if(result) { - *result = 0; - } - - break; - } - } - - return node; -} - -avl_node_t *avl_search_closest_smaller_node(const avl_tree_t *tree, - const void *data) { - avl_node_t *node; - int result; - - node = avl_search_closest_node(tree, data, &result); - - if(result < 0) { - node = node->prev; - } - - return node; -} - -avl_node_t *avl_search_closest_greater_node(const avl_tree_t *tree, - const void *data) { - avl_node_t *node; - int result; - - node = avl_search_closest_node(tree, data, &result); - - if(result > 0) { - node = node->next; - } - - return node; -} - -/* Insertion and deletion */ - -avl_node_t *avl_insert(avl_tree_t *tree, void *data) { - avl_node_t *closest, *new; - int result; - - if(!tree->root) { - new = avl_alloc_node(); - new->data = data; - avl_insert_top(tree, new); - } else { - closest = avl_search_closest_node(tree, data, &result); - - switch(result) { - case -1: - new = avl_alloc_node(); - new->data = data; - avl_insert_before(tree, closest, new); - break; - - case 1: - new = avl_alloc_node(); - new->data = data; - avl_insert_after(tree, closest, new); - break; - - default: - return NULL; - } - } - -#ifdef AVL_COUNT - new->count = 1; -#endif -#ifdef AVL_DEPTH - new->depth = 1; -#endif - - return new; -} - -avl_node_t *avl_insert_node(avl_tree_t *tree, avl_node_t *node) { - avl_node_t *closest; - int result; - - if(!tree->root) { - avl_insert_top(tree, node); - } else { - closest = avl_search_closest_node(tree, node->data, &result); - - switch(result) { - case -1: - avl_insert_before(tree, closest, node); - break; - - case 1: - avl_insert_after(tree, closest, node); - break; - - case 0: - return NULL; - } - } - -#ifdef AVL_COUNT - node->count = 1; -#endif -#ifdef AVL_DEPTH - node->depth = 1; -#endif - - return node; -} - -void avl_insert_top(avl_tree_t *tree, avl_node_t *node) { - node->prev = node->next = node->parent = NULL; - tree->head = tree->tail = tree->root = node; -} - -void avl_insert_before(avl_tree_t *tree, avl_node_t *before, - avl_node_t *node) { - if(!before) { - if(tree->tail) { - avl_insert_after(tree, tree->tail, node); - } else { - avl_insert_top(tree, node); - } - - return; - } - - node->next = before; - node->parent = before; - node->prev = before->prev; - - if(before->left) { - avl_insert_after(tree, before->prev, node); - return; - } - - if(before->prev) { - before->prev->next = node; - } else { - tree->head = node; - } - - before->prev = node; - before->left = node; - - avl_rebalance(tree, before); -} - -void avl_insert_after(avl_tree_t *tree, avl_node_t *after, avl_node_t *node) { - if(!after) { - if(tree->head) { - avl_insert_before(tree, tree->head, node); - } else { - avl_insert_top(tree, node); - } - - return; - } - - if(after->right) { - avl_insert_before(tree, after->next, node); - return; - } - - node->prev = after; - node->parent = after; - node->next = after->next; - - if(after->next) { - after->next->prev = node; - } else { - tree->tail = node; - } - - after->next = node; - after->right = node; - - avl_rebalance(tree, after); -} - -avl_node_t *avl_unlink(avl_tree_t *tree, void *data) { - avl_node_t *node; - - node = avl_search_node(tree, data); - - if(node) { - avl_unlink_node(tree, node); - } - - return node; -} - -void avl_unlink_node(avl_tree_t *tree, avl_node_t *node) { - avl_node_t *parent; - avl_node_t **superparent; - avl_node_t *subst, *left, *right; - avl_node_t *balnode; - - if(node->prev) { - node->prev->next = node->next; - } else { - tree->head = node->next; - } - - if(node->next) { - node->next->prev = node->prev; - } else { - tree->tail = node->prev; - } - - parent = node->parent; - - superparent = - parent ? node == - parent->left ? &parent->left : &parent->right : &tree->root; - - left = node->left; - right = node->right; - - if(!left) { - *superparent = right; - - if(right) { - right->parent = parent; - } - - balnode = parent; - } else if(!right) { - *superparent = left; - left->parent = parent; - balnode = parent; - } else { - subst = node->prev; - - if(!subst) { // This only happens if node is not actually in a tree at all. - abort(); - } - - if(subst == left) { - balnode = subst; - } else { - balnode = subst->parent; - balnode->right = subst->left; - - if(balnode->right) { - balnode->right->parent = balnode; - } - - subst->left = left; - left->parent = subst; - } - - subst->right = right; - subst->parent = parent; - right->parent = subst; - *superparent = subst; - } - - avl_rebalance(tree, balnode); - - node->next = node->prev = node->parent = node->left = node->right = NULL; - -#ifdef AVL_COUNT - node->count = 0; -#endif -#ifdef AVL_DEPTH - node->depth = 0; -#endif -} - -void avl_delete_node(avl_tree_t *tree, avl_node_t *node) { - avl_unlink_node(tree, node); - avl_free_node(tree, node); -} - -void avl_delete(avl_tree_t *tree, void *data) { - avl_node_t *node; - - node = avl_search_node(tree, data); - - if(node) { - avl_delete_node(tree, node); - } -} - -/* Fast tree cleanup */ - -void avl_delete_tree(avl_tree_t *tree) { - avl_node_t *node, *next; - - for(node = tree->head; node; node = next) { - next = node->next; - avl_free_node(tree, node); - } - - avl_free_tree(tree); -} - -/* Tree walking */ - -void avl_foreach(const avl_tree_t *tree, avl_action_t action) { - avl_node_t *node, *next; - - for(node = tree->head; node; node = next) { - next = node->next; - action(node->data); - } -} - -void avl_foreach_node(const avl_tree_t *tree, avl_action_t action) { - avl_node_t *node, *next; - - for(node = tree->head; node; node = next) { - next = node->next; - action(node); - } -} - -/* Indexing */ - -#ifdef AVL_COUNT -unsigned int avl_count(const avl_tree_t *tree) { - return AVL_NODE_COUNT(tree->root); -} - -avl_node_t *avl_get_node(const avl_tree_t *tree, unsigned int index) { - avl_node_t *node; - unsigned int c; - - node = tree->root; - - while(node) { - c = AVL_L_COUNT(node); - - if(index < c) { - node = node->left; - } else if(index > c) { - node = node->right; - index -= c + 1; - } else { - return node; - } - } - - return NULL; -} - -unsigned int avl_index(const avl_node_t *node) { - avl_node_t *next; - unsigned int index; - - index = AVL_L_COUNT(node); - - while((next = node->parent)) { - if(node == next->right) { - index += AVL_L_COUNT(next) + 1; - } - - node = next; - } - - return index; -} -#endif -#ifdef AVL_DEPTH -unsigned int avl_depth(const avl_tree_t *tree) { - return AVL_NODE_DEPTH(tree->root); -} -#endif diff --git a/src/avl_tree.h b/src/avl_tree.h deleted file mode 100644 index e8cefcf..0000000 --- a/src/avl_tree.h +++ /dev/null @@ -1,142 +0,0 @@ -#ifndef TINC_AVL_TREE_H -#define TINC_AVL_TREE_H - -/* - avl_tree.h -- header file for avl_tree.c - Copyright (C) 1998 Michael H. Buselli - 2000-2005 Ivo Timmermans, - 2000-2006 Guus Sliepen - 2000-2005 Wessel Dankers - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - - Original AVL tree library by Michael H. Buselli . - - Modified 2000-11-28 by Wessel Dankers to use counts - instead of depths, to add the ->next and ->prev and to generally obfuscate - the code. Mail me if you found a bug. - - Cleaned up and incorporated some of the ideas from the red-black tree - library for inclusion into tinc (https://www.tinc-vpn.org/) by - Guus Sliepen . -*/ - -#ifndef AVL_DEPTH -#ifndef AVL_COUNT -#define AVL_DEPTH -#endif -#endif - -typedef struct avl_node_t { - - /* Linked list part */ - - struct avl_node_t *next; - struct avl_node_t *prev; - - /* Tree part */ - - struct avl_node_t *parent; - struct avl_node_t *left; - struct avl_node_t *right; - -#ifdef AVL_COUNT - unsigned int count; -#endif -#ifdef AVL_DEPTH - unsigned char depth; -#endif - - /* Payload */ - - void *data; - -} avl_node_t; - -typedef int (*avl_compare_t)(const void *data1, const void *data2); -typedef void (*avl_action_t)(const void *data); -typedef void (*avl_action_node_t)(const avl_node_t *node); - -typedef struct avl_tree_t { - - /* Linked list part */ - - avl_node_t *head; - avl_node_t *tail; - - /* Tree part */ - - avl_node_t *root; - - avl_compare_t compare; - avl_action_t delete; - -} avl_tree_t; - -/* (De)constructors */ - -extern avl_tree_t *avl_alloc_tree(avl_compare_t compare, avl_action_t delete); -extern void avl_free_tree(avl_tree_t *tree); - -extern avl_node_t *avl_alloc_node(void); -extern void avl_free_node(avl_tree_t *tree, avl_node_t *node); - -/* Insertion and deletion */ - -extern avl_node_t *avl_insert(avl_tree_t *tree, void *data); -extern avl_node_t *avl_insert_node(avl_tree_t *tree, avl_node_t *node); - -extern void avl_insert_top(avl_tree_t *tree, avl_node_t *node); -extern void avl_insert_before(avl_tree_t *tree, avl_node_t *before, avl_node_t *node); -extern void avl_insert_after(avl_tree_t *tree, avl_node_t *after, avl_node_t *node); - -extern avl_node_t *avl_unlink(avl_tree_t *tree, void *data); -extern void avl_unlink_node(avl_tree_t *tree, avl_node_t *node); -extern void avl_delete(avl_tree_t *tree, void *data); -extern void avl_delete_node(avl_tree_t *tree, avl_node_t *node); - -/* Fast tree cleanup */ - -extern void avl_delete_tree(avl_tree_t *tree); - -/* Searching */ - -extern void *avl_search(const avl_tree_t *tree, const void *data); -extern void *avl_search_closest(const avl_tree_t *tree, const void *data, int *result); -extern void *avl_search_closest_smaller(const avl_tree_t *tree, const void *data); -extern void *avl_search_closest_greater(const avl_tree_t *tree, const void *data); - -extern avl_node_t *avl_search_node(const avl_tree_t *tree, const void *data); -extern avl_node_t *avl_search_closest_node(const avl_tree_t *tree, const void *data, int *result); -extern avl_node_t *avl_search_closest_smaller_node(const avl_tree_t *tree, const void *data); -extern avl_node_t *avl_search_closest_greater_node(const avl_tree_t *tree, const void *data); - -/* Tree walking */ - -extern void avl_foreach(const avl_tree_t *tree, avl_action_t action); -extern void avl_foreach_node(const avl_tree_t *tree, avl_action_t action); - -/* Indexing */ - -#ifdef AVL_COUNT -extern unsigned int avl_count(const avl_tree_t *tree); -extern avl_node_t *avl_get_node(const avl_tree_t *tree, unsigned int index); -extern unsigned int avl_index(const avl_node_t *node); -#endif -#ifdef AVL_DEPTH -extern unsigned int avl_depth(const avl_tree_t *tree); -#endif - -#endif diff --git a/src/bsd/device.c b/src/bsd/device.c index 23d6d69..9c3009d 100644 --- a/src/bsd/device.c +++ b/src/bsd/device.c @@ -1,7 +1,7 @@ /* device.c -- Interaction BSD tun/tap device Copyright (C) 2001-2005 Ivo Timmermans, - 2001-2016 Guus Sliepen + 2001-2011 Guus Sliepen 2009 Grzegorz Dymarek This program is free software; you can redistribute it and/or modify @@ -19,46 +19,38 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#include "../system.h" +#include "system.h" -#include "../conf.h" -#include "../device.h" -#include "../logger.h" -#include "../net.h" -#include "../route.h" -#include "../utils.h" -#include "../xalloc.h" +#include "conf.h" +#include "device.h" +#include "logger.h" +#include "net.h" +#include "route.h" +#include "utils.h" +#include "xalloc.h" -#ifdef ENABLE_TUNEMU -#include "tunemu.h" +#ifdef HAVE_TUNEMU +#include "bsd/tunemu.h" #endif -#ifdef HAVE_NET_IF_UTUN_H -#include -#include -#include -#endif - -#define DEFAULT_TUN_DEVICE "/dev/tun0" -#define DEFAULT_TAP_DEVICE "/dev/tap0" +#define DEFAULT_DEVICE "/dev/tun0" typedef enum device_type { DEVICE_TYPE_TUN, DEVICE_TYPE_TUNIFHEAD, DEVICE_TYPE_TAP, -#ifdef ENABLE_TUNEMU +#ifdef HAVE_TUNEMU DEVICE_TYPE_TUNEMU, #endif - DEVICE_TYPE_UTUN, } device_type_t; int device_fd = -1; char *device = NULL; char *iface = NULL; -static const char *device_info = "OS X utun device"; +static char *device_info = NULL; static uint64_t device_total_in = 0; static uint64_t device_total_out = 0; -#if defined(ENABLE_TUNEMU) +#if defined(TUNEMU) static device_type_t device_type = DEVICE_TYPE_TUNEMU; #elif defined(HAVE_OPENBSD) || defined(HAVE_FREEBSD) || defined(HAVE_DRAGONFLY) static device_type_t device_type = DEVICE_TYPE_TUNIFHEAD; @@ -66,140 +58,47 @@ static device_type_t device_type = DEVICE_TYPE_TUNIFHEAD; static device_type_t device_type = DEVICE_TYPE_TUN; #endif -#ifdef HAVE_NET_IF_UTUN_H -static bool setup_utun(void) { - device_fd = socket(PF_SYSTEM, SOCK_DGRAM, SYSPROTO_CONTROL); - - if(device_fd == -1) { - logger(LOG_ERR, "Could not open PF_SYSTEM socket: %s\n", strerror(errno)); - return false; - } - - struct ctl_info info = {}; - - strlcpy(info.ctl_name, UTUN_CONTROL_NAME, sizeof(info.ctl_name)); - - if(ioctl(device_fd, CTLIOCGINFO, &info) == -1) { - logger(LOG_ERR, "ioctl(CTLIOCGINFO) failed: %s", strerror(errno)); - return false; - } - - int unit = -1; - char *p = strstr(device, "utun"), *e = NULL; - - if(p) { - unit = strtol(p + 4, &e, 10); - - if(!e) { - unit = -1; - } - } - - struct sockaddr_ctl sc = { - .sc_id = info.ctl_id, - .sc_len = sizeof(sc), - .sc_family = AF_SYSTEM, - .ss_sysaddr = AF_SYS_CONTROL, - .sc_unit = unit + 1, - }; - - if(connect(device_fd, (struct sockaddr *)&sc, sizeof(sc)) == -1) { - logger(LOG_ERR, "Could not connect utun socket: %s\n", strerror(errno)); - return false; - } - - char name[64] = ""; - socklen_t len = sizeof(name); - - if(getsockopt(device_fd, SYSPROTO_CONTROL, UTUN_OPT_IFNAME, name, &len)) { - iface = xstrdup(device); - } else { - iface = xstrdup(name); - } - - logger(LOG_INFO, "%s is a %s", device, device_info); - - return true; -} -#endif - -static bool setup_device(void) { - // Find out which device file to open - - if(!get_config_string(lookup_config(config_tree, "Device"), &device)) { - if(routing_mode == RMODE_ROUTER) { - device = xstrdup(DEFAULT_TUN_DEVICE); - } else { - device = xstrdup(DEFAULT_TAP_DEVICE); - } - } - - // Find out if it's supposed to be a tun or a tap device - +bool setup_device(void) { char *type; + if(!get_config_string(lookup_config(config_tree, "Device"), &device)) + device = xstrdup(DEFAULT_DEVICE); + + if(!get_config_string(lookup_config(config_tree, "Interface"), &iface)) + iface = xstrdup(strrchr(device, '/') ? strrchr(device, '/') + 1 : device); + if(get_config_string(lookup_config(config_tree, "DeviceType"), &type)) { if(!strcasecmp(type, "tun")) - /* use default */; - -#ifdef ENABLE_TUNEMU - else if(!strcasecmp(type, "tunemu")) { + /* use default */; +#ifdef HAVE_TUNEMU + else if(!strcasecmp(type, "tunemu")) device_type = DEVICE_TYPE_TUNEMU; - } - #endif -#ifdef HAVE_NET_IF_UTUN_H - else if(!strcasecmp(type, "utun")) { - device_type = DEVICE_TYPE_UTUN; - } - -#endif - else if(!strcasecmp(type, "tunnohead")) { + else if(!strcasecmp(type, "tunnohead")) device_type = DEVICE_TYPE_TUN; - } else if(!strcasecmp(type, "tunifhead")) { + else if(!strcasecmp(type, "tunifhead")) device_type = DEVICE_TYPE_TUNIFHEAD; - } else if(!strcasecmp(type, "tap")) { + else if(!strcasecmp(type, "tap")) device_type = DEVICE_TYPE_TAP; - } else { + else { logger(LOG_ERR, "Unknown device type %s!", type); return false; } } else { -#ifdef HAVE_NET_IF_UTUN_H - - if(strncmp(device, "utun", 4) == 0 || strncmp(device, "/dev/utun", 9) == 0) { - device_type = DEVICE_TYPE_UTUN; - } else -#endif - if(strstr(device, "tap") || routing_mode != RMODE_ROUTER) { - device_type = DEVICE_TYPE_TAP; - } + if(strstr(device, "tap") || routing_mode != RMODE_ROUTER) + device_type = DEVICE_TYPE_TAP; } - if(routing_mode == RMODE_SWITCH && device_type != DEVICE_TYPE_TAP) { - logger(LOG_ERR, "Only tap devices support switch mode!"); - return false; - } - - // Open the device - switch(device_type) { -#ifdef ENABLE_TUNEMU - - case DEVICE_TYPE_TUNEMU: { - char dynamic_name[256] = ""; - device_fd = tunemu_open(dynamic_name); - } - break; +#ifdef HAVE_TUNEMU + case DEVICE_TYPE_TUNEMU: { + char dynamic_name[256] = ""; + device_fd = tunemu_open(dynamic_name); + } + break; #endif -#ifdef HAVE_NET_IF_UTUN_H - - case DEVICE_TYPE_UTUN: - return setup_utun(); -#endif - - default: - device_fd = open(device, O_RDWR | O_NONBLOCK); + default: + device_fd = open(device, O_RDWR | O_NONBLOCK); } if(device_fd < 0) { @@ -207,307 +106,244 @@ static bool setup_device(void) { return false; } -#ifdef FD_CLOEXEC - fcntl(device_fd, F_SETFD, FD_CLOEXEC); -#endif - - // Guess what the corresponding interface is called - - char *realname = NULL; - -#if defined(HAVE_FDEVNAME) - realname = fdevname(device_fd); -#elif defined(HAVE_DEVNAME) - struct stat buf; - - if(!fstat(device_fd, &buf)) { - realname = devname(buf.st_rdev, S_IFCHR); - } - -#endif - - if(!realname) { - realname = device; - } - - if(!get_config_string(lookup_config(config_tree, "Interface"), &iface)) { - iface = xstrdup(strrchr(realname, '/') ? strrchr(realname, '/') + 1 : realname); - } else if(strcmp(iface, strrchr(realname, '/') ? strrchr(realname, '/') + 1 : realname)) { - logger(LOG_WARNING, "Warning: Interface does not match Device. $INTERFACE might be set incorrectly."); - } - - // Configure the device as best as we can - switch(device_type) { - default: - device_type = DEVICE_TYPE_TUN; - - case DEVICE_TYPE_TUN: + default: + device_type = DEVICE_TYPE_TUN; + case DEVICE_TYPE_TUN: #ifdef TUNSIFHEAD - { + { const int zero = 0; - - if(ioctl(device_fd, TUNSIFHEAD, &zero, sizeof(zero)) == -1) { + if(ioctl(device_fd, TUNSIFHEAD, &zero, sizeof zero) == -1) { logger(LOG_ERR, "System call `%s' failed: %s", "ioctl", strerror(errno)); return false; } } - #endif #if defined(TUNSIFMODE) && defined(IFF_BROADCAST) && defined(IFF_MULTICAST) { const int mode = IFF_BROADCAST | IFF_MULTICAST; - ioctl(device_fd, TUNSIFMODE, &mode, sizeof(mode)); + ioctl(device_fd, TUNSIFMODE, &mode, sizeof mode); } #endif - device_info = "Generic BSD tun device"; - break; - - case DEVICE_TYPE_TUNIFHEAD: + device_info = "Generic BSD tun device"; + break; + case DEVICE_TYPE_TUNIFHEAD: #ifdef TUNSIFHEAD { const int one = 1; - - if(ioctl(device_fd, TUNSIFHEAD, &one, sizeof(one)) == -1) { + if(ioctl(device_fd, TUNSIFHEAD, &one, sizeof one) == -1) { logger(LOG_ERR, "System call `%s' failed: %s", "ioctl", strerror(errno)); return false; } } - #endif #if defined(TUNSIFMODE) && defined(IFF_BROADCAST) && defined(IFF_MULTICAST) { - const int mode = IFF_BROADCAST | IFF_MULTICAST; - ioctl(device_fd, TUNSIFMODE, &mode, sizeof(mode)); + const int mode = IFF_BROADCAST | IFF_MULTICAST; + ioctl(device_fd, TUNSIFMODE, &mode, sizeof mode); } #endif - device_info = "Generic BSD tun device"; - break; - - case DEVICE_TYPE_TAP: - if(routing_mode == RMODE_ROUTER) { - overwrite_mac = true; - } - - device_info = "Generic BSD tap device"; + device_info = "Generic BSD tun device"; + break; + case DEVICE_TYPE_TAP: + if(routing_mode == RMODE_ROUTER) + overwrite_mac = true; + device_info = "Generic BSD tap device"; #ifdef TAPGIFNAME - { - struct ifreq ifr; - - if(ioctl(device_fd, TAPGIFNAME, (void *)&ifr) == 0) { - if(iface) { - free(iface); + { + struct ifreq ifr; + if(ioctl(device_fd, TAPGIFNAME, (void*)&ifr) == 0) { + if(iface) + free(iface); + iface = xstrdup(ifr.ifr_name); } - - iface = xstrdup(ifr.ifr_name); } - } - + #endif - break; -#ifdef ENABLE_TUNEMU - - case DEVICE_TYPE_TUNEMU: - device_info = "BSD tunemu device"; - break; + break; +#ifdef HAVE_TUNEMU + case DEVICE_TYPE_TUNEMU: + device_info = "BSD tunemu device"; + break; #endif } -#ifdef SIOCGIFADDR - - if(overwrite_mac) { - ioctl(device_fd, SIOCGIFADDR, mymac.x); - } - -#endif - logger(LOG_INFO, "%s is a %s", device, device_info); return true; } -static void close_device(void) { +void close_device(void) { switch(device_type) { -#ifdef ENABLE_TUNEMU - - case DEVICE_TYPE_TUNEMU: - tunemu_close(device_fd); - break; +#ifdef HAVE_TUNEMU + case DEVICE_TYPE_TUNEMU: + tunemu_close(device_fd); + break; #endif - - default: - close(device_fd); + default: + close(device_fd); } free(device); free(iface); } -static bool read_packet(vpn_packet_t *packet) { - int lenin; +bool read_packet(vpn_packet_t *packet) { + int inlen; switch(device_type) { - case DEVICE_TYPE_TUN: -#ifdef ENABLE_TUNEMU - case DEVICE_TYPE_TUNEMU: - if(device_type == DEVICE_TYPE_TUNEMU) { - lenin = tunemu_read(device_fd, packet->data + 14, MTU - 14); - } else + case DEVICE_TYPE_TUN: +#ifdef HAVE_TUNEMU + case DEVICE_TYPE_TUNEMU: + if(device_type == DEVICE_TYPE_TUNEMU) + inlen = tunemu_read(device_fd, packet->data + 14, MTU - 14); + else #endif - lenin = read(device_fd, packet->data + 14, MTU - 14); + inlen = read(device_fd, packet->data + 14, MTU - 14); - if(lenin <= 0) { - logger(LOG_ERR, "Error while reading from %s %s: %s", device_info, - device, strerror(errno)); - return false; - } + if(inlen <= 0) { + logger(LOG_ERR, "Error while reading from %s %s: %s", device_info, + device, strerror(errno)); + return false; + } - switch(packet->data[14] >> 4) { - case 4: - packet->data[12] = 0x08; - packet->data[13] = 0x00; + switch(packet->data[14] >> 4) { + case 4: + packet->data[12] = 0x08; + packet->data[13] = 0x00; + break; + case 6: + packet->data[12] = 0x86; + packet->data[13] = 0xDD; + break; + default: + ifdebug(TRAFFIC) logger(LOG_ERR, + "Unknown IP version %d while reading packet from %s %s", + packet->data[14] >> 4, device_info, device); + return false; + } + + packet->len = inlen + 14; break; - case 6: - packet->data[12] = 0x86; - packet->data[13] = 0xDD; + case DEVICE_TYPE_TUNIFHEAD: { + u_int32_t type; + struct iovec vector[2] = {{&type, sizeof type}, {packet->data + 14, MTU - 14}}; + + if((inlen = readv(device_fd, vector, 2)) <= 0) { + logger(LOG_ERR, "Error while reading from %s %s: %s", device_info, + device, strerror(errno)); + return false; + } + + switch (ntohl(type)) { + case AF_INET: + packet->data[12] = 0x08; + packet->data[13] = 0x00; + break; + + case AF_INET6: + packet->data[12] = 0x86; + packet->data[13] = 0xDD; + break; + + default: + ifdebug(TRAFFIC) logger(LOG_ERR, + "Unknown address family %x while reading packet from %s %s", + ntohl(type), device_info, device); + return false; + } + + packet->len = inlen + 10; + break; + } + + case DEVICE_TYPE_TAP: + if((inlen = read(device_fd, packet->data, MTU)) <= 0) { + logger(LOG_ERR, "Error while reading from %s %s: %s", device_info, + device, strerror(errno)); + return false; + } + + packet->len = inlen; break; default: - ifdebug(TRAFFIC) logger(LOG_ERR, - "Unknown IP version %d while reading packet from %s %s", - packet->data[14] >> 4, device_info, device); return false; - } - - memset(packet->data, 0, 12); - packet->len = lenin + 14; - break; - - case DEVICE_TYPE_UTUN: - case DEVICE_TYPE_TUNIFHEAD: { - if((lenin = read(device_fd, packet->data + 10, MTU - 10)) <= 0) { - logger(LOG_ERR, "Error while reading from %s %s: %s", device_info, - device, strerror(errno)); - return false; - } - - switch(packet->data[14] >> 4) { - case 4: - packet->data[12] = 0x08; - packet->data[13] = 0x00; - break; - - case 6: - packet->data[12] = 0x86; - packet->data[13] = 0xDD; - break; - - default: - ifdebug(TRAFFIC) logger(LOG_ERR, - "Unknown IP version %d while reading packet from %s %s", - packet->data[14] >> 4, device_info, device); - return false; - } - - memset(packet->data, 0, 12); - packet->len = lenin + 10; - break; } - - case DEVICE_TYPE_TAP: - if((lenin = read(device_fd, packet->data, MTU)) <= 0) { - logger(LOG_ERR, "Error while reading from %s %s: %s", device_info, - device, strerror(errno)); - return false; - } - - packet->len = lenin; - break; - - default: - return false; - } - + device_total_in += packet->len; ifdebug(TRAFFIC) logger(LOG_DEBUG, "Read packet of %d bytes from %s", - packet->len, device_info); + packet->len, device_info); return true; } -static bool write_packet(vpn_packet_t *packet) { +bool write_packet(vpn_packet_t *packet) { ifdebug(TRAFFIC) logger(LOG_DEBUG, "Writing packet of %d bytes to %s", - packet->len, device_info); + packet->len, device_info); switch(device_type) { - case DEVICE_TYPE_TUN: - if(write(device_fd, packet->data + 14, packet->len - 14) < 0) { - logger(LOG_ERR, "Error while writing to %s %s: %s", device_info, - device, strerror(errno)); - return false; - } - - break; - - case DEVICE_TYPE_UTUN: - case DEVICE_TYPE_TUNIFHEAD: { - int af = (packet->data[12] << 8) + packet->data[13]; - uint32_t type; - - switch(af) { - case 0x0800: - type = htonl(AF_INET); + case DEVICE_TYPE_TUN: + if(write(device_fd, packet->data + 14, packet->len - 14) < 0) { + logger(LOG_ERR, "Error while writing to %s %s: %s", device_info, + device, strerror(errno)); + return false; + } break; - case 0x86DD: - type = htonl(AF_INET6); + case DEVICE_TYPE_TUNIFHEAD: { + u_int32_t type; + struct iovec vector[2] = {{&type, sizeof type}, {packet->data + 14, packet->len - 14}}; + int af; + + af = (packet->data[12] << 8) + packet->data[13]; + + switch (af) { + case 0x0800: + type = htonl(AF_INET); + break; + case 0x86DD: + type = htonl(AF_INET6); + break; + default: + ifdebug(TRAFFIC) logger(LOG_ERR, + "Unknown address family %x while writing packet to %s %s", + af, device_info, device); + return false; + } + + if(writev(device_fd, vector, 2) < 0) { + logger(LOG_ERR, "Can't write to %s %s: %s", device_info, device, + strerror(errno)); + return false; + } + break; + } + + case DEVICE_TYPE_TAP: + if(write(device_fd, packet->data, packet->len) < 0) { + logger(LOG_ERR, "Error while writing to %s %s: %s", device_info, + device, strerror(errno)); + return false; + } break; - default: - ifdebug(TRAFFIC) logger(LOG_ERR, - "Unknown address family %x while writing packet to %s %s", - af, device_info, device); - return false; - } - - memcpy(packet->data + 10, &type, sizeof(type)); - - if(write(device_fd, packet->data + 10, packet->len - 10) < 0) { - logger(LOG_ERR, "Can't write to %s %s: %s", device_info, device, - strerror(errno)); - return false; - } - - break; - } - - case DEVICE_TYPE_TAP: - if(write(device_fd, packet->data, packet->len) < 0) { - logger(LOG_ERR, "Error while writing to %s %s: %s", device_info, - device, strerror(errno)); - return false; - } - - break; - -#ifdef ENABLE_TUNEMU - - case DEVICE_TYPE_TUNEMU: - if(tunemu_write(device_fd, packet->data + 14, packet->len - 14) < 0) { - logger(LOG_ERR, "Error while writing to %s %s: %s", device_info, - device, strerror(errno)); - return false; - } - - break; +#ifdef HAVE_TUNEMU + case DEVICE_TYPE_TUNEMU: + if(tunemu_write(device_fd, packet->data + 14, packet->len - 14) < 0) { + logger(LOG_ERR, "Error while writing to %s %s: %s", device_info, + device, strerror(errno)); + return false; + } + break; #endif - default: - return false; + default: + return false; } device_total_out += packet->len; @@ -515,16 +351,8 @@ static bool write_packet(vpn_packet_t *packet) { return true; } -static void dump_device_stats(void) { +void dump_device_stats(void) { logger(LOG_DEBUG, "Statistics for %s %s:", device_info, device); logger(LOG_DEBUG, " total bytes in: %10"PRIu64, device_total_in); logger(LOG_DEBUG, " total bytes out: %10"PRIu64, device_total_out); } - -const devops_t os_devops = { - .setup = setup_device, - .close = close_device, - .read = read_packet, - .write = write_packet, - .dump_stats = dump_device_stats, -}; diff --git a/src/bsd/tunemu.c b/src/bsd/tunemu.c index 7ff6f72..f532b04 100644 --- a/src/bsd/tunemu.c +++ b/src/bsd/tunemu.c @@ -1,20 +1,20 @@ /* * tunemu - Tun device emulation for Darwin * Copyright (C) 2009 Friedrich Schöller - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program. If not, see . - * + * */ #include "tunemu.h" @@ -36,34 +36,37 @@ #define PPPPROTO_CTL 1 -#define PPP_IP 0x21 -#define PPP_IPV6 0x57 +#define PPP_IP 0x21 +#define PPP_IPV6 0x57 #define SC_LOOP_TRAFFIC 0x00000200 -#define PPPIOCNEWUNIT _IOWR('t', 62, int) -#define PPPIOCSFLAGS _IOW('t', 89, int) -#define PPPIOCSNPMODE _IOW('t', 75, struct npioctl) -#define PPPIOCATTCHAN _IOW('t', 56, int) -#define PPPIOCGCHAN _IOR('t', 55, int) -#define PPPIOCCONNECT _IOW('t', 58, int) -#define PPPIOCGUNIT _IOR('t', 86, int) +#define PPPIOCNEWUNIT _IOWR('t', 62, int) +#define PPPIOCSFLAGS _IOW('t', 89, int) +#define PPPIOCSNPMODE _IOW('t', 75, struct npioctl) +#define PPPIOCATTCHAN _IOW('t', 56, int) +#define PPPIOCGCHAN _IOR('t', 55, int) +#define PPPIOCCONNECT _IOW('t', 58, int) +#define PPPIOCGUNIT _IOR('t', 86, int) -struct sockaddr_ppp { +struct sockaddr_ppp +{ u_int8_t ppp_len; u_int8_t ppp_family; u_int16_t ppp_proto; u_int32_t ppp_cookie; }; -enum NPmode { +enum NPmode +{ NPMODE_PASS, - NPMODE_DROP, - NPMODE_ERROR, - NPMODE_QUEUE + NPMODE_DROP, + NPMODE_ERROR, + NPMODE_QUEUE }; -struct npioctl { +struct npioctl +{ int protocol; enum NPmode mode; }; @@ -80,55 +83,58 @@ static pcap_t *pcap = NULL; static int data_buffer_length = 0; static char *data_buffer = NULL; -static void tun_error(char *format, ...) { +static void tun_error(char *format, ...) +{ va_list vl; va_start(vl, format); vsnprintf(tunemu_error, ERROR_BUFFER_SIZE, format, vl); va_end(vl); } -static void tun_noerror() { +static void tun_noerror() +{ *tunemu_error = 0; } -static void closeall() { - int fd = getdtablesize(); - - while(fd--) { +static void closeall() +{ + int fd = getdtablesize(); + while (fd--) close(fd); - } - open("/dev/null", O_RDWR, 0); - dup(0); - dup(0); + open("/dev/null", O_RDWR, 0); + dup(0); + dup(0); } -static int ppp_load_kext() { +static int ppp_load_kext() +{ int pid = fork(); - - if(pid < 0) { + if (pid < 0) + { tun_error("fork for ppp kext: %s", strerror(errno)); return -1; } - if(pid == 0) { + if (pid == 0) + { closeall(); execle("/sbin/kextload", "kextload", PPP_KEXT_PATH, NULL, NULL); exit(1); } int status; - - while(waitpid(pid, &status, 0) < 0) { - if(errno == EINTR) { + while (waitpid(pid, &status, 0) < 0) + { + if (errno == EINTR) continue; - } tun_error("waitpid for ppp kext: %s", strerror(errno)); return -1; } - if(WEXITSTATUS(status) != 0) { + if (WEXITSTATUS(status) != 0) + { tun_error("could not load ppp kext \"%s\"", PPP_KEXT_PATH); return -1; } @@ -137,73 +143,74 @@ static int ppp_load_kext() { return 0; } -static int ppp_new_instance() { +static int ppp_new_instance() +{ // create ppp socket - int ppp_sockfd = socket(PF_PPP, SOCK_RAW, PPPPROTO_CTL); - - if(ppp_sockfd < 0) { - if(ppp_load_kext() < 0) { + int ppp_sockfd = socket(PF_PPP, SOCK_RAW, PPPPROTO_CTL); + if (ppp_sockfd < 0) + { + if (ppp_load_kext() < 0) return -1; - } ppp_sockfd = socket(PF_PPP, SOCK_RAW, PPPPROTO_CTL); - - if(ppp_sockfd < 0) { + if (ppp_sockfd < 0) + { tun_error("creating ppp socket: %s", strerror(errno)); return -1; } } // connect to ppp procotol - struct sockaddr_ppp pppaddr; - pppaddr.ppp_len = sizeof(struct sockaddr_ppp); - pppaddr.ppp_family = AF_PPP; - pppaddr.ppp_proto = PPPPROTO_CTL; - pppaddr.ppp_cookie = 0; - - if(connect(ppp_sockfd, (struct sockaddr *)&pppaddr, sizeof(struct sockaddr_ppp)) < 0) { + struct sockaddr_ppp pppaddr; + pppaddr.ppp_len = sizeof(struct sockaddr_ppp); + pppaddr.ppp_family = AF_PPP; + pppaddr.ppp_proto = PPPPROTO_CTL; + pppaddr.ppp_cookie = 0; + if (connect(ppp_sockfd, (struct sockaddr *)&pppaddr, sizeof(struct sockaddr_ppp)) < 0) + { tun_error("connecting ppp socket: %s", strerror(errno)); close(ppp_sockfd); return -1; - } + } tun_noerror(); return ppp_sockfd; } -static int ppp_new_unit(int *unit_number) { +static int ppp_new_unit(int *unit_number) +{ int fd = ppp_new_instance(); - - if(fd < 0) { + if (fd < 0) return -1; - } // create ppp unit - if(ioctl(fd, PPPIOCNEWUNIT, unit_number) < 0) { + if (ioctl(fd, PPPIOCNEWUNIT, unit_number) < 0) + { tun_error("creating ppp unit: %s", strerror(errno)); close(fd); return -1; - } + } tun_noerror(); return fd; } -static int ppp_setup_unit(int unit_fd) { +static int ppp_setup_unit(int unit_fd) +{ // send traffic to program int flags = SC_LOOP_TRAFFIC; - - if(ioctl(unit_fd, PPPIOCSFLAGS, &flags) < 0) { + if (ioctl(unit_fd, PPPIOCSFLAGS, &flags) < 0) + { tun_error("setting ppp loopback mode: %s", strerror(errno)); return -1; - } + } // allow packets struct npioctl npi; npi.protocol = PPP_IP; npi.mode = NPMODE_PASS; - - if(ioctl(unit_fd, PPPIOCSNPMODE, &npi) < 0) { + if (ioctl(unit_fd, PPPIOCSNPMODE, &npi) < 0) + { tun_error("starting ppp unit: %s", strerror(errno)); return -1; } @@ -212,8 +219,10 @@ static int ppp_setup_unit(int unit_fd) { return 0; } -static int open_pcap() { - if(pcap != NULL) { +static int open_pcap() +{ + if (pcap != NULL) + { pcap_use_count++; return 0; } @@ -222,7 +231,8 @@ static int open_pcap() { pcap = pcap_open_live("lo0", BUFSIZ, 0, 1, errbuf); pcap_use_count = 1; - if(pcap == NULL) { + if (pcap == NULL) + { tun_error("opening pcap: %s", errbuf); return -1; } @@ -231,57 +241,59 @@ static int open_pcap() { return 0; } -static void close_pcap() { - if(pcap == NULL) { +static void close_pcap() +{ + if (pcap == NULL) return; - } pcap_use_count--; - - if(pcap_use_count == 0) { + if (pcap_use_count == 0) + { pcap_close(pcap); pcap = NULL; } } -static void allocate_data_buffer(int size) { - if(data_buffer_length < size) { +static void allocate_data_buffer(int size) +{ + if (data_buffer_length < size) + { free(data_buffer); data_buffer_length = size; data_buffer = malloc(data_buffer_length); } } -static void make_device_name(tunemu_device device, int unit_number) { +static void make_device_name(tunemu_device device, int unit_number) +{ snprintf(device, sizeof(tunemu_device), "ppp%d", unit_number); } -static int check_device_name(tunemu_device device) { - if(strlen(device) < 4) { +static int check_device_name(tunemu_device device) +{ + if (strlen(device) < 4) return -1; - } int unit_number = atoi(device + 3); - - if(unit_number < 0 || unit_number > 999) { + if (unit_number < 0 || unit_number > 999) return -1; - } tunemu_device compare; make_device_name(compare, unit_number); - if(strcmp(device, compare) != 0) { + if (strcmp(device, compare) != 0) return -1; - } return 0; } -int tunemu_open(tunemu_device device) { +int tunemu_open(tunemu_device device) +{ int ppp_unit_number = -1; - - if(device[0] != 0) { - if(check_device_name(device) < 0) { + if (device[0] != 0) + { + if (check_device_name(device) < 0) + { tun_error("invalid device name \"%s\"", device); return -1; } @@ -290,17 +302,17 @@ int tunemu_open(tunemu_device device) { } int ppp_unit_fd = ppp_new_unit(&ppp_unit_number); - - if(ppp_unit_fd < 0) { + if (ppp_unit_fd < 0) return -1; - } - if(ppp_setup_unit(ppp_unit_fd) < 0) { + if (ppp_setup_unit(ppp_unit_fd) < 0) + { close(ppp_unit_fd); return -1; } - if(open_pcap() < 0) { + if (open_pcap() < 0) + { close(ppp_unit_fd); return -1; } @@ -310,40 +322,39 @@ int tunemu_open(tunemu_device device) { return ppp_unit_fd; } -int tunemu_close(int ppp_sockfd) { +int tunemu_close(int ppp_sockfd) +{ int ret = close(ppp_sockfd); - if(ret == 0) { + if (ret == 0) close_pcap(); - } return ret; } -int tunemu_read(int ppp_sockfd, char *buffer, int length) { +int tunemu_read(int ppp_sockfd, char *buffer, int length) +{ allocate_data_buffer(length + 2); length = read(ppp_sockfd, data_buffer, length + 2); - - if(length < 0) { + if (length < 0) + { tun_error("reading packet: %s", strerror(errno)); return length; } - tun_noerror(); length -= 2; - - if(length < 0) { + if (length < 0) return 0; - } memcpy(buffer, data_buffer + 2, length); return length; } -int tunemu_write(int ppp_sockfd, char *buffer, int length) { +int tunemu_write(int ppp_sockfd, char *buffer, int length) +{ allocate_data_buffer(length + 4); data_buffer[0] = 0x02; @@ -353,25 +364,23 @@ int tunemu_write(int ppp_sockfd, char *buffer, int length) { memcpy(data_buffer + 4, buffer, length); - if(pcap == NULL) { + if (pcap == NULL) + { tun_error("pcap not open"); return -1; } length = pcap_inject(pcap, data_buffer, length + 4); - - if(length < 0) { + if (length < 0) + { tun_error("injecting packet: %s", pcap_geterr(pcap)); return length; } - tun_noerror(); length -= 4; - - if(length < 0) { + if (length < 0) return 0; - } return length; } diff --git a/src/bsd/tunemu.h b/src/bsd/tunemu.h index e0452a8..42b1785 100644 --- a/src/bsd/tunemu.h +++ b/src/bsd/tunemu.h @@ -1,20 +1,20 @@ /* * tunemu - Tun device emulation for Darwin * Copyright (C) 2009 Friedrich Schöller - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program. If not, see . - * + * */ #ifndef TUNEMU_H diff --git a/src/buffer.c b/src/buffer.c new file mode 100644 index 0000000..3d4c329 --- /dev/null +++ b/src/buffer.c @@ -0,0 +1,108 @@ +/* + buffer.c -- buffer management + Copyright (C) 2011 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "system.h" + +#include "buffer.h" +#include "xalloc.h" + +void buffer_compact(buffer_t *buffer, int maxsize) { + if(buffer->len >= maxsize || buffer->offset / 7 > buffer->len / 8) { + memmove(buffer->data, buffer->data + buffer->offset, buffer->len - buffer->offset); + buffer->len -= buffer->offset; + buffer->offset = 0; + } +} + +// Make sure we can add size bytes to the buffer, and return a pointer to the start of those bytes. + +char *buffer_prepare(buffer_t *buffer, int size) { + if(!buffer->data) { + buffer->maxlen = size; + buffer->data = xmalloc(size); + } else { + if(buffer->offset && buffer->len + size > buffer->maxlen) { + memmove(buffer->data, buffer->data + buffer->offset, buffer->len - buffer->offset); + buffer->len -= buffer->offset; + buffer->offset = 0; + } + + if(buffer->len + size > buffer->maxlen) { + buffer->maxlen = buffer->len + size; + buffer->data = xrealloc(buffer->data, buffer->maxlen); + } + } + + char *start = buffer->data + buffer->len; + + buffer->len += size; + + return start; +} + +// Copy data into the buffer. + +void buffer_add(buffer_t *buffer, const char *data, int size) { + memcpy(buffer_prepare(buffer, size), data, size); +} + +// Remove given number of bytes from the buffer, return a pointer to the start of them. + +static char *buffer_consume(buffer_t *buffer, int size) { + char *start = buffer->data + buffer->offset; + + buffer->offset += size; + + if(buffer->offset >= buffer->len) { + buffer->offset = 0; + buffer->len = 0; + } + + return start; +} + +// Check if there is a complete line in the buffer, and if so, return it NULL-terminated. + +char *buffer_readline(buffer_t *buffer) { + char *newline = memchr(buffer->data + buffer->offset, '\n', buffer->len - buffer->offset); + + if(!newline) + return NULL; + + int len = newline + 1 - (buffer->data + buffer->offset); + *newline = 0; + return buffer_consume(buffer, len); +} + +// Check if we have enough bytes in the buffer, and if so, return a pointer to the start of them. + +char *buffer_read(buffer_t *buffer, int size) { + if(buffer->len - buffer->offset < size) + return NULL; + + return buffer_consume(buffer, size); +} + +void buffer_clear(buffer_t *buffer) { + free(buffer->data); + buffer->data = NULL; + buffer->maxlen = 0; + buffer->len = 0; + buffer->offset = 0; +} diff --git a/src/buffer.h b/src/buffer.h new file mode 100644 index 0000000..a96c15a --- /dev/null +++ b/src/buffer.h @@ -0,0 +1,18 @@ +#ifndef __TINC_BUFFER_H__ +#define __TINC_BUFFER_H__ + +typedef struct buffer_t { + char *data; + int maxlen; + int len; + int offset; +} buffer_t; + +extern void buffer_compact(buffer_t *buffer, int maxsize); +extern char *buffer_prepare(buffer_t *buffer, int size); +extern void buffer_add(buffer_t *buffer, const char *data, int size); +extern char *buffer_readline(buffer_t *buffer); +extern char *buffer_read(buffer_t *buffer, int size); +extern void buffer_clear(buffer_t *buffer); + +#endif diff --git a/src/conf.c b/src/conf.c index 58d7b6d..f47faef 100644 --- a/src/conf.c +++ b/src/conf.c @@ -2,9 +2,9 @@ conf.c -- configuration code Copyright (C) 1998 Robert van der Meulen 1998-2005 Ivo Timmermans - 2000-2014 Guus Sliepen + 2000-2010 Guus Sliepen 2010-2011 Julien Muchembled - 2000 Cris van Pelt + 2000 Cris van Pelt 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 @@ -23,23 +23,23 @@ #include "system.h" -#include "avl_tree.h" +#include "splay_tree.h" #include "connection.h" #include "conf.h" #include "list.h" #include "logger.h" -#include "netutl.h" /* for str2address */ +#include "netutl.h" /* for str2address */ #include "protocol.h" -#include "utils.h" /* for cp */ +#include "utils.h" /* for cp */ #include "xalloc.h" -avl_tree_t *config_tree; +splay_tree_t *config_tree; -int pinginterval = 0; /* seconds between pings */ -int pingtimeout = 0; /* seconds to wait for response */ -char *confbase = NULL; /* directory in which all config files are */ -char *netname = NULL; /* name of the vpn network */ -list_t *cmdline_conf = NULL; /* global/host configuration values given at the command line */ +int pinginterval = 0; /* seconds between pings */ +int pingtimeout = 0; /* seconds to wait for response */ +char *confbase = NULL; /* directory in which all config files are */ +char *netname = NULL; /* name of the vpn network */ +list_t *cmdline_conf = NULL; /* global/host configuration values given at the command line */ static int config_compare(const config_t *a, const config_t *b) { @@ -47,32 +47,28 @@ static int config_compare(const config_t *a, const config_t *b) { result = strcasecmp(a->variable, b->variable); - if(result) { + if(result) return result; - } /* give priority to command line options */ result = !b->file - !a->file; - - if(result) { + if (result) return result; - } result = a->line - b->line; - if(result) { + if(result) return result; - } else { + else return a->file ? strcmp(a->file, b->file) : 0; - } } -void init_configuration(avl_tree_t **config_tree) { - *config_tree = avl_alloc_tree((avl_compare_t) config_compare, (avl_action_t) free_config); +void init_configuration(splay_tree_t ** config_tree) { + *config_tree = splay_alloc_tree((splay_compare_t) config_compare, (splay_action_t) free_config); } -void exit_configuration(avl_tree_t **config_tree) { - avl_delete_tree(*config_tree); +void exit_configuration(splay_tree_t ** config_tree) { + splay_delete_tree(*config_tree); *config_tree = NULL; } @@ -81,49 +77,52 @@ config_t *new_config(void) { } void free_config(config_t *cfg) { - free(cfg->variable); - free(cfg->value); - free(cfg->file); + if(cfg->variable) + free(cfg->variable); + + if(cfg->value) + free(cfg->value); + + if(cfg->file) + free(cfg->file); + free(cfg); } -void config_add(avl_tree_t *config_tree, config_t *cfg) { - avl_insert(config_tree, cfg); +void config_add(splay_tree_t *config_tree, config_t *cfg) { + splay_insert(config_tree, cfg); } -config_t *lookup_config(const avl_tree_t *config_tree, char *variable) { +config_t *lookup_config(splay_tree_t *config_tree, char *variable) { config_t cfg, *found; cfg.variable = variable; cfg.file = NULL; cfg.line = 0; - found = avl_search_closest_greater(config_tree, &cfg); + found = splay_search_closest_greater(config_tree, &cfg); - if(!found) { + if(!found) return NULL; - } - if(strcasecmp(found->variable, variable)) { + if(strcasecmp(found->variable, variable)) return NULL; - } return found; } -config_t *lookup_config_next(const avl_tree_t *config_tree, const config_t *cfg) { - avl_node_t *node; +config_t *lookup_config_next(splay_tree_t *config_tree, const config_t *cfg) { + splay_node_t *node; config_t *found; - node = avl_search_node(config_tree, cfg); + node = splay_search_node(config_tree, cfg); if(node) { if(node->next) { found = node->next->data; - if(!strcasecmp(found->variable, cfg->variable)) { + if(!strcasecmp(found->variable, cfg->variable)) return found; - } } } @@ -131,9 +130,8 @@ config_t *lookup_config_next(const avl_tree_t *config_tree, const config_t *cfg) } bool get_config_bool(const config_t *cfg, bool *result) { - if(!cfg) { + if(!cfg) return false; - } if(!strcasecmp(cfg->value, "yes")) { *result = true; @@ -144,30 +142,27 @@ bool get_config_bool(const config_t *cfg, bool *result) { } logger(LOG_ERR, "\"yes\" or \"no\" expected for configuration variable %s in %s line %d", - cfg->variable, cfg->file, cfg->line); + cfg->variable, cfg->file, cfg->line); return false; } bool get_config_int(const config_t *cfg, int *result) { - if(!cfg) { + if(!cfg) return false; - } - if(sscanf(cfg->value, "%d", result) == 1) { + if(sscanf(cfg->value, "%d", result) == 1) return true; - } logger(LOG_ERR, "Integer expected for configuration variable %s in %s line %d", - cfg->variable, cfg->file, cfg->line); + cfg->variable, cfg->file, cfg->line); return false; } bool get_config_string(const config_t *cfg, char **result) { - if(!cfg) { + if(!cfg) return false; - } *result = xstrdup(cfg->value); @@ -177,9 +172,8 @@ bool get_config_string(const config_t *cfg, char **result) { bool get_config_address(const config_t *cfg, struct addrinfo **result) { struct addrinfo *ai; - if(!cfg) { + if(!cfg) return false; - } ai = str2addrinfo(cfg->value, NULL, 0); @@ -189,32 +183,31 @@ bool get_config_address(const config_t *cfg, struct addrinfo **result) { } logger(LOG_ERR, "Hostname or IP address expected for configuration variable %s in %s line %d", - cfg->variable, cfg->file, cfg->line); + cfg->variable, cfg->file, cfg->line); return false; } -bool get_config_subnet(const config_t *cfg, subnet_t **result) { - subnet_t subnet = {0}; +bool get_config_subnet(const config_t *cfg, subnet_t ** result) { + subnet_t subnet = {NULL}; - if(!cfg) { + if(!cfg) return false; - } if(!str2net(&subnet, cfg->value)) { logger(LOG_ERR, "Subnet expected for configuration variable %s in %s line %d", - cfg->variable, cfg->file, cfg->line); + cfg->variable, cfg->file, cfg->line); return false; } /* Teach newbies what subnets are... */ if(((subnet.type == SUBNET_IPV4) - && !maskcheck(&subnet.net.ipv4.address, subnet.net.ipv4.prefixlength, sizeof(ipv4_t))) - || ((subnet.type == SUBNET_IPV6) - && !maskcheck(&subnet.net.ipv6.address, subnet.net.ipv6.prefixlength, sizeof(ipv6_t)))) { + && !maskcheck(&subnet.net.ipv4.address, subnet.net.ipv4.prefixlength, sizeof subnet.net.ipv4.address)) + || ((subnet.type == SUBNET_IPV6) + && !maskcheck(&subnet.net.ipv6.address, subnet.net.ipv6.prefixlength, sizeof subnet.net.ipv6.address))) { logger(LOG_ERR, "Network address and prefix length do not match for configuration variable %s in %s line %d", - cfg->variable, cfg->file, cfg->line); + cfg->variable, cfg->file, cfg->line); return false; } @@ -226,31 +219,26 @@ bool get_config_subnet(const config_t *cfg, subnet_t **result) { /* 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; - if(feof(fp)) { + if(feof(fp)) return NULL; - } p = fgets(buf, buflen, fp); - if(!p) { + if(!p) return NULL; - } newline = strchr(p, '\n'); - if(!newline) { + if(!newline) return buf; - } - *newline = '\0'; /* kill newline */ - - if(newline > p && newline[-1] == '\r') { /* and carriage return if necessary */ + *newline = '\0'; /* kill newline */ + if(newline > p && newline[-1] == '\r') /* and carriage return if necessary */ newline[-1] = '\0'; - } return buf; } @@ -262,32 +250,26 @@ config_t *parse_config_line(char *line, const char *fname, int lineno) { variable = value = line; eol = line + strlen(line); - - while(strchr("\t ", *--eol)) { + while(strchr("\t ", *--eol)) *eol = '\0'; - } len = strcspn(value, "\t ="); value += len; value += strspn(value, "\t "); - if(*value == '=') { value++; value += strspn(value, "\t "); } - variable[len] = '\0'; if(!*value) { const char err[] = "No value for variable"; - - if(fname) + if (fname) logger(LOG_ERR, "%s `%s' on line %d while reading config file %s", - err, variable, lineno, fname); + err, variable, lineno, fname); else logger(LOG_ERR, "%s `%s' in command line option %d", - err, variable, lineno); - + err, variable, lineno); return NULL; } @@ -304,7 +286,7 @@ config_t *parse_config_line(char *line, const char *fname, int lineno) { Parse a configuration file and put the results in the configuration tree starting at *base. */ -bool read_config_file(avl_tree_t *config_tree, const char *fname) { +bool read_config_file(splay_tree_t *config_tree, const char *fname) { FILE *fp; char buffer[MAX_STRING_SIZE]; char *line; @@ -321,41 +303,33 @@ bool read_config_file(avl_tree_t *config_tree, const char *fname) { } for(;;) { - line = readline(fp, buffer, sizeof(buffer)); + line = readline(fp, buffer, sizeof buffer); if(!line) { - if(feof(fp)) { + if(feof(fp)) result = true; - } - break; } lineno++; - if(!*line || *line == '#') { + if(!*line || *line == '#') continue; - } if(ignore) { - if(!strncmp(line, "-----END", 8)) { + if(!strncmp(line, "-----END", 8)) ignore = false; - } - continue; } - + if(!strncmp(line, "-----BEGIN", 10)) { ignore = true; continue; } cfg = parse_config_line(line, fname, lineno); - - if(!cfg) { + if (!cfg) break; - } - config_add(config_tree, cfg); } @@ -364,234 +338,122 @@ bool read_config_file(avl_tree_t *config_tree, const char *fname) { return result; } -void read_config_options(avl_tree_t *config_tree, const char *prefix) { +void read_config_options(splay_tree_t *config_tree, const char *prefix) { + list_node_t *node, *next; size_t prefix_len = prefix ? strlen(prefix) : 0; - for(const list_node_t *node = cmdline_conf->tail; node; node = node->prev) { - const config_t *cfg = node->data; + for(node = cmdline_conf->tail; node; node = next) { + config_t *orig_cfg, *cfg = (config_t *)node->data; + next = node->prev; if(!prefix) { - if(strchr(cfg->variable, '.')) { + if(strchr(cfg->variable, '.')) continue; - } + node->data = NULL; + list_unlink_node(cmdline_conf, node); } else { if(strncmp(prefix, cfg->variable, prefix_len) || - cfg->variable[prefix_len] != '.') { + cfg->variable[prefix_len] != '.') continue; - } + /* Because host configuration is parsed again when + reconnecting, nodes must not be freed when a prefix + is given. */ + orig_cfg = cfg; + cfg = new_config(); + cfg->variable = xstrdup(orig_cfg->variable + prefix_len + 1); + cfg->value = xstrdup(orig_cfg->value); + cfg->file = NULL; + cfg->line = orig_cfg->line; } - - config_t *new = new_config(); - - if(prefix) { - new->variable = xstrdup(cfg->variable + prefix_len + 1); - } else { - new->variable = xstrdup(cfg->variable); - } - - new->value = xstrdup(cfg->value); - new->file = NULL; - new->line = cfg->line; - - config_add(config_tree, new); + config_add(config_tree, cfg); } } bool read_server_config(void) { - char fname[PATH_MAX]; + char *fname; bool x; read_config_options(config_tree, NULL); - snprintf(fname, sizeof(fname), "%s/tinc.conf", confbase); - errno = 0; + xasprintf(&fname, "%s/tinc.conf", confbase); x = read_config_file(config_tree, fname); - // We will try to read the conf files in the "conf.d" dir - if(x) { - char dname[PATH_MAX]; - snprintf(dname, sizeof(dname), "%s/conf.d", confbase); - DIR *dir = opendir(dname); - - // If we can find this dir - if(dir) { - struct dirent *ep; - - // We list all the files in it - while(x && (ep = readdir(dir))) { - size_t l = strlen(ep->d_name); - - // And we try to read the ones that end with ".conf" - if(l > 5 && !strcmp(".conf", & ep->d_name[ l - 5 ])) { - if((size_t)snprintf(fname, sizeof(fname), "%s/%s", dname, ep->d_name) >= sizeof(fname)) { - logger(LOG_ERR, "Pathname too long: %s/%s", dname, ep->d_name); - return false; - } - - x = read_config_file(config_tree, fname); - } - } - - closedir(dir); - } - } - - if(!x && errno) { + if(!x) { /* System error: complain */ logger(LOG_ERR, "Failed to read `%s': %s", fname, strerror(errno)); } + free(fname); + return x; } bool read_connection_config(connection_t *c) { - char fname[PATH_MAX]; + char *fname; bool x; read_config_options(c->config_tree, c->name); - snprintf(fname, sizeof(fname), "%s/hosts/%s", confbase, c->name); + xasprintf(&fname, "%s/hosts/%s", confbase, c->name); x = read_config_file(c->config_tree, fname); + free(fname); return x; } -static void disable_old_keys(const char *filename) { - char tmpfile[PATH_MAX] = ""; - char buf[1024]; - bool disabled = false; - FILE *r, *w; +bool append_config_file(const char *name, const char *key, const char *value) { + char *fname; + xasprintf(&fname, "%s/hosts/%s", confbase, name); - r = fopen(filename, "r"); + FILE *fp = fopen(fname, "a"); - if(!r) { - return; + if(!fp) { + logger(LOG_ERR, "Cannot open config file %s: %s", fname, strerror(errno)); + } else { + fprintf(fp, "\n# The following line was automatically added by tinc\n%s = %s\n", key, value); + fclose(fp); } - snprintf(tmpfile, sizeof(tmpfile), "%s.tmp", filename); + free(fname); - w = fopen(tmpfile, "w"); + return fp; +} - while(fgets(buf, sizeof(buf), r)) { - if(!strncmp(buf, "-----BEGIN RSA", 14)) { +bool disable_old_keys(FILE *f) { + char buf[100]; + long pos; + bool disabled = false; + + rewind(f); + pos = ftell(f); + + if(pos < 0) + return false; + + while(fgets(buf, sizeof buf, f)) { + if(!strncmp(buf, "-----BEGIN RSA", 14)) { buf[11] = 'O'; buf[12] = 'L'; buf[13] = 'D'; + if(fseek(f, pos, SEEK_SET)) + break; + if(fputs(buf, f) <= 0) + break; disabled = true; - } else if(!strncmp(buf, "-----END RSA", 12)) { + } + else if(!strncmp(buf, "-----END RSA", 12)) { buf[ 9] = 'O'; buf[10] = 'L'; buf[11] = 'D'; + if(fseek(f, pos, SEEK_SET)) + break; + if(fputs(buf, f) <= 0) + break; disabled = true; } - - if(w && fputs(buf, w) < 0) { - disabled = false; + pos = ftell(f); + if(pos < 0) break; - } } - if(w) { - fclose(w); - } - - fclose(r); - - if(!w && disabled) { - fprintf(stderr, "Warning: old key(s) found, remove them by hand!\n"); - return; - } - - if(disabled) { -#ifdef HAVE_MINGW - // We cannot atomically replace files on Windows. - char bakfile[PATH_MAX] = ""; - snprintf(bakfile, sizeof(bakfile), "%s.bak", filename); - - if(rename(filename, bakfile) || rename(tmpfile, filename)) { - rename(bakfile, filename); -#else - - if(rename(tmpfile, filename)) { -#endif - fprintf(stderr, "Warning: old key(s) found, remove them by hand!\n"); - } else { -#ifdef HAVE_MINGW - unlink(bakfile); -#endif - fprintf(stderr, "Warning: old key(s) found and disabled.\n"); - } - } - - unlink(tmpfile); + return disabled; } - -FILE *ask_and_open(const char *filename, const char *what) { - FILE *r; - char directory[PATH_MAX]; - char line[PATH_MAX]; - char abspath[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 = 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, line, sizeof(line)); - - if(!fn) { - fprintf(stderr, "Error while reading stdin: %s\n", - strerror(errno)); - return NULL; - } - - if(!strlen(fn)) - /* User just pressed enter. */ - { - fn = filename; - } - } - -#ifdef HAVE_MINGW - - if(fn[0] != '\\' && fn[0] != '/' && !strchr(fn, ':')) { -#else - - if(fn[0] != '/') { -#endif - /* The directory is a relative path or a filename. */ - getcwd(directory, sizeof(directory)); - - if((size_t)snprintf(abspath, sizeof(abspath), "%s/%s", directory, fn) >= sizeof(abspath)) { - fprintf(stderr, "Pathname too long: %s/%s\n", directory, fn); - return NULL; - } - - fn = abspath; - } - - umask(0077); /* Disallow everything for group and other */ - - disable_old_keys(fn); - - /* Open it first to keep the inode busy */ - - r = fopen(fn, "a"); - - if(!r) { - fprintf(stderr, "Error opening file `%s': %s\n", - fn, strerror(errno)); - return NULL; - } - - return r; -} - - diff --git a/src/conf.h b/src/conf.h index 770ada7..bd3850b 100644 --- a/src/conf.h +++ b/src/conf.h @@ -1,10 +1,7 @@ -#ifndef TINC_CONF_H -#define TINC_CONF_H - /* conf.h -- header for conf.c Copyright (C) 1998-2005 Ivo Timmermans - 2000-2012 Guus Sliepen + 2000-2009 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 @@ -21,7 +18,10 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#include "avl_tree.h" +#ifndef __TINC_CONF_H__ +#define __TINC_CONF_H__ + +#include "splay_tree.h" #include "list.h" typedef struct config_t { @@ -33,35 +33,37 @@ typedef struct config_t { #include "subnet.h" -extern avl_tree_t *config_tree; +extern splay_tree_t *config_tree; extern int pinginterval; extern int pingtimeout; extern int maxtimeout; -extern int mintimeout; extern bool bypass_security; extern char *confbase; extern char *netname; extern list_t *cmdline_conf; -extern void init_configuration(avl_tree_t **config_tree); -extern void exit_configuration(avl_tree_t **config_tree); -extern config_t *new_config(void) __attribute__((__malloc__)); -extern void free_config(config_t *cfg); -extern void config_add(avl_tree_t *config_tree, config_t *cfg); -extern config_t *lookup_config(const avl_tree_t *config_tree, char *variable); -extern config_t *lookup_config_next(const avl_tree_t *config_tree, const config_t *cfg); -extern bool get_config_bool(const config_t *cfg, bool *result); -extern bool get_config_int(const config_t *cfg, int *result); -extern bool get_config_string(const config_t *cfg, char **result); -extern bool get_config_address(const config_t *cfg, struct addrinfo **result); -extern bool get_config_subnet(const config_t *cfg, struct subnet_t **result); +extern void init_configuration(splay_tree_t **); +extern void exit_configuration(splay_tree_t **); +extern config_t *new_config(void) __attribute__ ((__malloc__)); +extern void free_config(config_t *); +extern void config_add(splay_tree_t *, config_t *); +extern config_t *lookup_config(splay_tree_t *, char *); +extern config_t *lookup_config_next(splay_tree_t *, const config_t *); +extern bool get_config_bool(const config_t *, bool *); +extern bool get_config_int(const config_t *, int *); +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 config_t *parse_config_line(char *line, const char *fname, int lineno); -extern bool read_config_file(avl_tree_t *config_tree, const char *fname); -extern void read_config_options(avl_tree_t *config_tree, const char *prefix); +extern config_t *parse_config_line(char *, const char *, int); +extern bool read_config_file(splay_tree_t *, const char *); +extern void read_config_options(splay_tree_t *, const char *); extern bool read_server_config(void); -extern bool read_connection_config(struct connection_t *c); -extern FILE *ask_and_open(const char *fname, const char *what); +extern bool read_connection_config(struct connection_t *); +extern bool append_config_file(const char *, const char *, const char *); +extern FILE *ask_and_open(const char *, const char *, const char *); +extern bool is_safe_path(const char *); +extern bool disable_old_keys(FILE *); -#endif +#endif /* __TINC_CONF_H__ */ diff --git a/src/connection.c b/src/connection.c index 38b3ccf..bae86b9 100644 --- a/src/connection.c +++ b/src/connection.c @@ -1,6 +1,6 @@ /* connection.c -- connection list management - Copyright (C) 2000-2016 Guus Sliepen , + Copyright (C) 2000-2009 Guus Sliepen , 2000-2005 Ivo Timmermans 2008 Max Rijevski @@ -21,131 +21,98 @@ #include "system.h" -#include "avl_tree.h" +#include "splay_tree.h" +#include "cipher.h" #include "conf.h" +#include "control_common.h" +#include "list.h" #include "logger.h" #include "subnet.h" #include "utils.h" #include "xalloc.h" -avl_tree_t *connection_tree; /* Meta connections */ -connection_t *everyone; +splay_tree_t *connection_tree; /* Meta connections */ +connection_t *broadcast; static int connection_compare(const connection_t *a, const connection_t *b) { return a < b ? -1 : a == b ? 0 : 1; } void init_connections(void) { - connection_tree = avl_alloc_tree((avl_compare_t) connection_compare, (avl_action_t) free_connection); - everyone = new_connection(); - everyone->name = xstrdup("everyone"); - everyone->hostname = xstrdup("BROADCAST"); + connection_tree = splay_alloc_tree((splay_compare_t) connection_compare, (splay_action_t) free_connection); + broadcast = new_connection(); + broadcast->name = xstrdup("everyone"); + broadcast->hostname = xstrdup("BROADCAST"); } void exit_connections(void) { - avl_delete_tree(connection_tree); - free_connection(everyone); + splay_delete_tree(connection_tree); + free_connection(broadcast); } connection_t *new_connection(void) { - connection_t *c; - - c = xmalloc_and_zero(sizeof(connection_t)); - - if(!c) { - return NULL; - } - - gettimeofday(&c->start, NULL); - - return c; -} - -void free_connection_partially(connection_t *c) { - free(c->inkey); - free(c->outkey); - free(c->mychallenge); - free(c->hischallenge); - free(c->outbuf); - - c->inkey = NULL; - c->outkey = NULL; - c->mychallenge = NULL; - c->hischallenge = NULL; - c->outbuf = NULL; - - c->status.pinged = false; - c->status.active = false; - c->status.connecting = false; - c->status.timeout = false; - c->status.encryptout = false; - c->status.decryptin = false; - c->status.mst = false; - - c->options = 0; - c->buflen = 0; - c->reqlen = 0; - c->tcplen = 0; - c->allow_request = 0; - c->outbuflen = 0; - c->outbufsize = 0; - c->outbufstart = 0; - c->last_ping_time = 0; - c->last_flushed_time = 0; - c->inbudget = 0; - c->outbudget = 0; - - if(c->inctx) { - EVP_CIPHER_CTX_cleanup(c->inctx); - free(c->inctx); - c->inctx = NULL; - } - - if(c->outctx) { - EVP_CIPHER_CTX_cleanup(c->outctx); - free(c->outctx); - c->outctx = NULL; - } - - if(c->rsa_key) { - RSA_free(c->rsa_key); - c->rsa_key = NULL; - } + return xmalloc_and_zero(sizeof(connection_t)); } void free_connection(connection_t *c) { - free_connection_partially(c); + if(!c) + return; - free(c->name); - free(c->hostname); + if(c->name) + free(c->name); - if(c->config_tree) { + if(c->hostname) + free(c->hostname); + + cipher_close(&c->incipher); + digest_close(&c->indigest); + cipher_close(&c->outcipher); + digest_close(&c->outdigest); + + ecdh_free(&c->ecdh); + ecdsa_free(&c->ecdsa); + rsa_free(&c->rsa); + + if(c->hischallenge) + free(c->hischallenge); + + if(c->config_tree) exit_configuration(&c->config_tree); - } + + buffer_clear(&c->inbuf); + buffer_clear(&c->outbuf); + + if(event_initialized(&c->inevent)) + event_del(&c->inevent); + + if(event_initialized(&c->outevent)) + event_del(&c->outevent); + + if(c->socket > 0) + closesocket(c->socket); free(c); } void connection_add(connection_t *c) { - avl_insert(connection_tree, c); + splay_insert(connection_tree, c); } void connection_del(connection_t *c) { - avl_delete(connection_tree, c); + splay_delete(connection_tree, c); } -void dump_connections(void) { - avl_node_t *node; +bool dump_connections(connection_t *cdump) { + splay_node_t *node; connection_t *c; - logger(LOG_DEBUG, "Connections:"); - for(node = connection_tree->head; node; node = node->next) { c = node->data; - logger(LOG_DEBUG, " %s at %s options %x socket %d status %04x outbuf %d/%d/%d", - c->name, c->hostname, c->options, c->socket, bitfield_to_int(&c->status, sizeof(c->status)), - c->outbufsize, c->outbufstart, c->outbuflen); + send_request(cdump, "%d %d %s at %s options %x socket %d status %04x", + CONTROL, REQ_DUMP_CONNECTIONS, + c->name, c->hostname, c->options, c->socket, + bitfield_to_int(&c->status, sizeof c->status)); } - logger(LOG_DEBUG, "End of connections."); + return send_request(cdump, "%d %d", CONTROL, REQ_DUMP_CONNECTIONS); } diff --git a/src/connection.h b/src/connection.h index 629e16b..26aa3f0 100644 --- a/src/connection.h +++ b/src/connection.h @@ -1,9 +1,6 @@ -#ifndef TINC_CONNECTION_H -#define TINC_CONNECTION_H - /* connection.h -- header for connection.c - Copyright (C) 2000-2016 Guus Sliepen , + Copyright (C) 2000-2010 Guus Sliepen , 2000-2005 Ivo Timmermans This program is free software; you can redistribute it and/or modify @@ -21,99 +18,95 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#include -#include +#ifndef __TINC_CONNECTION_H__ +#define __TINC_CONNECTION_H__ -#include "avl_tree.h" +#include "buffer.h" +#include "cipher.h" +#include "digest.h" +#include "rsa.h" +#include "splay_tree.h" -#define OPTION_INDIRECT 0x0001 -#define OPTION_TCPONLY 0x0002 -#define OPTION_PMTU_DISCOVERY 0x0004 -#define OPTION_CLAMP_MSS 0x0008 +#define OPTION_INDIRECT 0x0001 +#define OPTION_TCPONLY 0x0002 +#define OPTION_PMTU_DISCOVERY 0x0004 +#define OPTION_CLAMP_MSS 0x0008 typedef struct connection_status_t { - unsigned int pinged: 1; /* sent ping */ - unsigned int active: 1; /* 1 if active.. */ - unsigned int connecting: 1; /* 1 if we are waiting for a non-blocking connect() to finish */ - unsigned int unused_termreq: 1; /* the termination of this connection was requested */ - unsigned int remove: 1; /* Set to 1 if you want this connection removed */ - unsigned int timeout: 1; /* 1 if gotten timeout */ - unsigned int encryptout: 1; /* 1 if we can encrypt outgoing traffic */ - unsigned int decryptin: 1; /* 1 if we have to decrypt incoming traffic */ - unsigned int mst: 1; /* 1 if this connection is part of a minimum spanning tree */ - unsigned int proxy_passed: 1; /* 1 if we are connecting via a proxy and we have finished talking with it */ - unsigned int tarpit: 1; /* 1 if the connection should be added to the tarpit */ - unsigned int unused: 21; + unsigned int pinged:1; /* sent ping */ + unsigned int active:1; /* 1 if active.. */ + unsigned int connecting:1; /* 1 if we are waiting for a non-blocking connect() to finish */ + unsigned int termreq:1; /* the termination of this connection was requested */ + unsigned int remove_unused:1; /* Set to 1 if you want this connection removed */ + unsigned int timeout_unused:1; /* 1 if gotten timeout */ + unsigned int encryptout:1; /* 1 if we can encrypt outgoing traffic */ + unsigned int decryptin:1; /* 1 if we have to decrypt incoming traffic */ + unsigned int mst:1; /* 1 if this connection is part of a minimum spanning tree */ + unsigned int control:1; + unsigned int pcap:1; + unsigned int unused:21; } connection_status_t; +#include "ecdh.h" +#include "ecdsa.h" #include "edge.h" #include "net.h" #include "node.h" typedef struct connection_t { - char *name; /* name he claims to have */ + char *name; /* name he claims to have */ - union sockaddr_t address; /* his real (internet) ip */ - char *hostname; /* the hostname of its real ip */ - int protocol_version; /* used protocol */ + union sockaddr_t address; /* his real (internet) ip */ + char *hostname; /* the hostname of its real ip */ + int protocol_major; /* used protocol */ + int protocol_minor; /* used protocol */ - int socket; /* socket used for this connection */ - uint32_t options; /* options for this connection */ - connection_status_t status; /* status info */ - int estimated_weight; /* estimation for the weight of the edge for this connection */ - struct timeval start; /* time this connection was started, used for above estimation */ - struct outgoing_t *outgoing; /* used to keep track of outgoing connections */ + int socket; /* socket used for this connection */ + uint32_t options; /* options for this connection */ + connection_status_t status; /* status info */ + int estimated_weight; /* estimation for the weight of the edge for this connection */ + struct timeval start; /* time this connection was started, used for above estimation */ + struct outgoing_t *outgoing; /* used to keep track of outgoing connections */ - struct node_t *node; /* node associated with the other end */ - struct edge_t *edge; /* edge associated with this connection */ + struct node_t *node; /* node associated with the other end */ + struct edge_t *edge; /* edge associated with this connection */ + + rsa_t rsa; /* his public RSA key */ + ecdsa_t ecdsa; /* his public ECDSA key */ + ecdsa_t ecdh; /* state for ECDH key exchange */ + cipher_t incipher; /* Cipher he will use to send data to us */ + cipher_t outcipher; /* Cipher we will use to send data to him */ + digest_t indigest; + digest_t outdigest; - RSA *rsa_key; /* his public/private key */ - const EVP_CIPHER *incipher; /* Cipher he will use to send data to us */ - const EVP_CIPHER *outcipher; /* Cipher we will use to send data to him */ - EVP_CIPHER_CTX *inctx; /* Context of encrypted meta data that will come from him to us */ - EVP_CIPHER_CTX *outctx; /* Context of encrypted meta data that will be sent from us to him */ - uint64_t inbudget; /* Encrypted bytes send budget */ - uint64_t outbudget; /* Encrypted bytes receive budget */ - char *inkey; /* His symmetric meta key + iv */ - char *outkey; /* Our symmetric meta key + iv */ - int inkeylength; /* Length of his key + iv */ - int outkeylength; /* Length of our key + iv */ - const EVP_MD *indigest; - const EVP_MD *outdigest; int inmaclength; int outmaclength; int incompression; int outcompression; - char *mychallenge; /* challenge we received from him */ - char *hischallenge; /* challenge we sent to him */ - char buffer[MAXBUFSIZE]; /* metadata input buffer */ - int buflen; /* bytes read into buffer */ - int reqlen; /* length of incoming request */ - length_t tcplen; /* length of incoming TCPpacket */ - int allow_request; /* defined if there's only one request possible */ + char *hischallenge; /* The challenge we sent to him */ - char *outbuf; /* metadata output buffer */ - int outbufstart; /* index of first meaningful byte in output buffer */ - int outbuflen; /* number of meaningful bytes in output buffer */ - int outbufsize; /* number of bytes allocated to output buffer */ + struct buffer_t inbuf; + struct buffer_t outbuf; + struct event inevent; /* input event on this metadata connection */ + struct event outevent; /* output event on this metadata connection */ + int tcplen; /* length of incoming TCPpacket */ + int allow_request; /* defined if there's only one request possible */ - time_t last_ping_time; /* last time we saw some activity from the other end or pinged them */ - time_t last_flushed_time; /* last time buffer was empty. Only meaningful if outbuflen > 0 */ + time_t last_ping_time; /* last time we saw some activity from the other end or pinged them */ - avl_tree_t *config_tree; /* Pointer to configuration tree belonging to him */ + splay_tree_t *config_tree; /* Pointer to configuration tree belonging to him */ } connection_t; -extern avl_tree_t *connection_tree; -extern connection_t *everyone; +extern splay_tree_t *connection_tree; +extern connection_t *broadcast; extern void init_connections(void); extern void exit_connections(void); -extern connection_t *new_connection(void) __attribute__((__malloc__)); -extern void free_connection(connection_t *c); -extern void free_connection_partially(connection_t *c); -extern void connection_add(connection_t *c); -extern void connection_del(connection_t *c); -extern void dump_connections(void); +extern connection_t *new_connection(void) __attribute__ ((__malloc__)); +extern void free_connection(connection_t *); +extern void connection_add(connection_t *); +extern void connection_del(connection_t *); +extern bool dump_connections(struct connection_t *); -#endif +#endif /* __TINC_CONNECTION_H__ */ diff --git a/src/control.c b/src/control.c new file mode 100644 index 0000000..86224c2 --- /dev/null +++ b/src/control.c @@ -0,0 +1,182 @@ +/* + control.c -- Control socket handling. + Copyright (C) 2007 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "system.h" +#include "crypto.h" +#include "conf.h" +#include "control.h" +#include "control_common.h" +#include "graph.h" +#include "logger.h" +#include "meta.h" +#include "net.h" +#include "netutl.h" +#include "protocol.h" +#include "route.h" +#include "splay_tree.h" +#include "utils.h" +#include "xalloc.h" + +char controlcookie[65]; +extern char *pidfilename; + +static bool control_return(connection_t *c, int type, int error) { + return send_request(c, "%d %d %d", CONTROL, type, error); +} + +static bool control_ok(connection_t *c, int type) { + return control_return(c, type, 0); +} + +bool control_h(connection_t *c, char *request) { + int type; + + if(!c->status.control || c->allow_request != CONTROL) { + logger(LOG_ERR, "Unauthorized control request from %s (%s)", c->name, c->hostname); + return false; + } + + if(sscanf(request, "%*d %d", &type) != 1) { + logger(LOG_ERR, "Got bad %s from %s (%s)", "CONTROL", c->name, c->hostname); + return false; + } + + switch (type) { + case REQ_STOP: + event_loopexit(NULL); + return control_ok(c, REQ_STOP); + + case REQ_DUMP_NODES: + return dump_nodes(c); + + case REQ_DUMP_EDGES: + return dump_edges(c); + + case REQ_DUMP_SUBNETS: + return dump_subnets(c); + + case REQ_DUMP_CONNECTIONS: + return dump_connections(c); + + case REQ_PURGE: + purge(); + return control_ok(c, REQ_PURGE); + + case REQ_SET_DEBUG: { + int new_level; + if(sscanf(request, "%*d %*d %d", &new_level) != 1) + return false; + send_request(c, "%d %d %d", CONTROL, REQ_SET_DEBUG, debug_level); + if(new_level >= 0) + debug_level = new_level; + return true; + } + + case REQ_RETRY: + retry(); + return control_ok(c, REQ_RETRY); + + case REQ_RELOAD: + logger(LOG_NOTICE, "Got '%s' command", "reload"); + int result = reload_configuration(); + return control_return(c, REQ_RELOAD, result); + + case REQ_DISCONNECT: { + char name[MAX_STRING_SIZE]; + connection_t *other; + splay_node_t *node, *next; + bool found = false; + + if(sscanf(request, "%*d %*d " MAX_STRING, name) != 1) + return control_return(c, REQ_DISCONNECT, -1); + + for(node = connection_tree->head; node; node = next) { + next = node->next; + other = node->data; + if(strcmp(other->name, name)) + continue; + terminate_connection(other, other->status.active); + found = true; + } + + return control_return(c, REQ_DISCONNECT, found ? 0 : -2); + } + + case REQ_DUMP_TRAFFIC: + return dump_traffic(c); + + case REQ_PCAP: + c->status.pcap = true; + pcap = true; + return true; + + default: + return send_request(c, "%d %d", CONTROL, REQ_INVALID); + } +} + +bool init_control(void) { + randomize(controlcookie, sizeof controlcookie / 2); + bin2hex(controlcookie, controlcookie, sizeof controlcookie / 2); + + FILE *f = fopen(pidfilename, "w"); + if(!f) { + logger(LOG_ERR, "Cannot write control socket cookie file %s: %s", pidfilename, strerror(errno)); + return false; + } + +#ifdef HAVE_FCHMOD + fchmod(fileno(f), 0600); +#else + chmod(pidfilename, 0600); +#endif + // Get the address and port of the first listening socket + + char *localhost = NULL; + sockaddr_t sa; + socklen_t len = sizeof sa; + + // Make sure we have a valid address, and map 0.0.0.0 and :: to 127.0.0.1 and ::1. + + if(getsockname(listen_socket[0].tcp, (struct sockaddr *)&sa, &len)) { + xasprintf(&localhost, "127.0.0.1 port %d", myport); + } else { + if(sa.sa.sa_family == AF_INET) { + if(sa.in.sin_addr.s_addr == 0) + sa.in.sin_addr.s_addr = htonl(0x7f000001); + } else if(sa.sa.sa_family == AF_INET6) { + static const uint8_t zero[16] = {0}; + if(!memcmp(sa.in6.sin6_addr.s6_addr, zero, sizeof zero)) + sa.in6.sin6_addr.s6_addr[15] = 1; + } + + localhost = sockaddr2hostname(&sa); + } + + fprintf(f, "%d %s %s\n", (int)getpid(), controlcookie, localhost); + + free(localhost); + fclose(f); + + return true; +} + +void exit_control(void) { + unlink(pidfilename); +} diff --git a/src/control.h b/src/control.h new file mode 100644 index 0000000..ce8145a --- /dev/null +++ b/src/control.h @@ -0,0 +1,27 @@ +/* + control.h -- header for control.c. + Copyright (C) 2007 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#ifndef __TINC_CONTROL_H__ +#define __TINC_CONTROL_H__ + +extern bool init_control(); +extern void exit_control(); +extern char controlcookie[]; + +#endif diff --git a/src/control_common.h b/src/control_common.h new file mode 100644 index 0000000..615e10a --- /dev/null +++ b/src/control_common.h @@ -0,0 +1,46 @@ +/* + control_protocol.h -- control socket protocol. + Copyright (C) 2007 Scott Lamb + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#ifndef __TINC_CONTROL_PROTOCOL_H__ +#define __TINC_CONTROL_PROTOCOL_H__ + +#include "protocol.h" + +enum request_type { + REQ_INVALID = -1, + REQ_STOP = 0, + REQ_RELOAD, + REQ_RESTART, + REQ_DUMP_NODES, + REQ_DUMP_EDGES, + REQ_DUMP_SUBNETS, + REQ_DUMP_CONNECTIONS, + REQ_DUMP_GRAPH, + REQ_PURGE, + REQ_SET_DEBUG, + REQ_RETRY, + REQ_CONNECT, + REQ_DISCONNECT, + REQ_DUMP_TRAFFIC, + REQ_PCAP, +}; + +#define TINC_CTL_VERSION_CURRENT 0 + +#endif diff --git a/src/cygwin/device.c b/src/cygwin/device.c index 1165d67..a4ab938 100644 --- a/src/cygwin/device.c +++ b/src/cygwin/device.c @@ -1,7 +1,7 @@ /* device.c -- Interaction with Windows tap driver in a Cygwin environment Copyright (C) 2002-2005 Ivo Timmermans, - 2002-2016 Guus Sliepen + 2002-2009 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 @@ -18,26 +18,26 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#include "../system.h" -#include "../net.h" +#include "system.h" #include #include -#include "../conf.h" -#include "../device.h" -#include "../logger.h" -#include "../route.h" -#include "../utils.h" -#include "../xalloc.h" +#include "conf.h" +#include "device.h" +#include "logger.h" +#include "net.h" +#include "route.h" +#include "utils.h" +#include "xalloc.h" -#include "../mingw/common.h" +#include "mingw/common.h" int device_fd = -1; static HANDLE device_handle = INVALID_HANDLE_VALUE; char *device = NULL; char *iface = NULL; -static const char *device_info = "Windows tap device"; +static char *device_info = NULL; static uint64_t device_total_in = 0; static uint64_t device_total_out = 0; @@ -45,7 +45,7 @@ static uint64_t device_total_out = 0; static pid_t reader_pid; static int sp[2]; -static bool setup_device(void) { +bool setup_device(void) { HKEY key, key2; int i, err; @@ -61,10 +61,6 @@ static bool setup_device(void) { get_config_string(lookup_config(config_tree, "Device"), &device); get_config_string(lookup_config(config_tree, "Interface"), &iface); - if(device && iface) { - logger(LOG_WARNING, "Warning: both Device and Interface specified, results may not be as expected"); - } - /* Open registry and look for network adapters */ if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, NETWORK_CONNECTIONS_KEY, 0, KEY_READ, &key)) { @@ -72,51 +68,44 @@ static bool setup_device(void) { return false; } - for(i = 0; ; i++) { - len = sizeof(adapterid); - - if(RegEnumKeyEx(key, i, adapterid, &len, 0, 0, 0, NULL)) { + for (i = 0; ; i++) { + len = sizeof adapterid; + if(RegEnumKeyEx(key, i, adapterid, &len, 0, 0, 0, NULL)) break; - } /* Find out more about this adapter */ - snprintf(regpath, sizeof(regpath), "%s\\%s\\Connection", NETWORK_CONNECTIONS_KEY, adapterid); + snprintf(regpath, sizeof regpath, "%s\\%s\\Connection", NETWORK_CONNECTIONS_KEY, adapterid); - if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, regpath, 0, KEY_READ, &key2)) { + if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, regpath, 0, KEY_READ, &key2)) continue; - } - len = sizeof(adaptername); + len = sizeof adaptername; err = RegQueryValueEx(key2, "Name", 0, 0, adaptername, &len); RegCloseKey(key2); - if(err) { + if(err) continue; - } if(device) { if(!strcmp(device, adapterid)) { found = true; break; - } else { + } else continue; - } } if(iface) { if(!strcmp(iface, adaptername)) { found = true; break; - } else { + } else continue; - } } - snprintf(tapname, sizeof(tapname), USERMODEDEVICEDIR "%s" TAPSUFFIX, adapterid); + snprintf(tapname, sizeof tapname, USERMODEDEVICEDIR "%s" TAPSUFFIX, adapterid); device_handle = CreateFile(tapname, GENERIC_WRITE | GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM, 0); - if(device_handle != INVALID_HANDLE_VALUE) { CloseHandle(device_handle); found = true; @@ -131,16 +120,14 @@ static bool setup_device(void) { return false; } - if(!device) { + if(!device) device = xstrdup(adapterid); - } - if(!iface) { + if(!iface) iface = xstrdup(adaptername); - } - - snprintf(tapname, sizeof(tapname), USERMODEDEVICEDIR "%s" TAPSUFFIX, device); + snprintf(tapname, sizeof tapname, USERMODEDEVICEDIR "%s" TAPSUFFIX, device); + /* Now we are going to open this device twice: once for reading and once for writing. We do this because apparently it isn't possible to check for activity in the select() loop. Furthermore I don't really know how to do it the "Windows" way. */ @@ -151,9 +138,9 @@ static bool setup_device(void) { } /* The parent opens the tap device for writing. */ - - device_handle = CreateFile(tapname, GENERIC_WRITE, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM, 0); - + + device_handle = CreateFile(tapname, GENERIC_WRITE, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM , 0); + if(device_handle == INVALID_HANDLE_VALUE) { logger(LOG_ERR, "Could not open Windows tap device %s (%s) for writing: %s", device, iface, winerror(GetLastError())); return false; @@ -163,7 +150,7 @@ static bool setup_device(void) { /* Get MAC address from tap device */ - if(!DeviceIoControl(device_handle, TAP_IOCTL_GET_MAC, mymac.x, sizeof(mymac.x), mymac.x, sizeof(mymac.x), &len, 0)) { + if(!DeviceIoControl(device_handle, TAP_IOCTL_GET_MAC, mymac.x, sizeof mymac.x, mymac.x, sizeof mymac.x, &len, 0)) { logger(LOG_ERR, "Could not get MAC address from Windows tap device %s (%s): %s", device, iface, winerror(GetLastError())); return false; } @@ -184,9 +171,9 @@ static bool setup_device(void) { if(!reader_pid) { /* The child opens the tap device for reading, blocking. It passes everything it reads to the socket. */ - + char buf[MTU]; - long lenin; + long inlen; CloseHandle(device_handle); @@ -209,24 +196,25 @@ static bool setup_device(void) { /* Pass packets */ for(;;) { - ReadFile(device_handle, buf, MTU, &lenin, NULL); - write(sp[1], buf, lenin); + ReadFile(device_handle, buf, MTU, &inlen, NULL); + write(sp[1], buf, inlen); } } read(device_fd, &gelukt, 1); - if(gelukt != 1) { logger(LOG_DEBUG, "Tap reader failed!"); return false; } + device_info = "Windows tap device"; + logger(LOG_INFO, "%s (%s) is a %s", device, iface, device_info); return true; } -static void close_device(void) { +void close_device(void) { close(sp[0]); close(sp[1]); CloseHandle(device_handle); @@ -237,32 +225,32 @@ static void close_device(void) { free(iface); } -static bool read_packet(vpn_packet_t *packet) { - int lenin; +bool read_packet(vpn_packet_t *packet) { + int inlen; - if((lenin = read(sp[0], packet->data, MTU)) <= 0) { + if((inlen = read(sp[0], packet->data, MTU)) <= 0) { logger(LOG_ERR, "Error while reading from %s %s: %s", device_info, - device, strerror(errno)); + device, strerror(errno)); return false; } - - packet->len = lenin; + + packet->len = inlen; device_total_in += packet->len; ifdebug(TRAFFIC) logger(LOG_DEBUG, "Read packet of %d bytes from %s", packet->len, - device_info); + device_info); return true; } -static bool write_packet(vpn_packet_t *packet) { - long lenout; +bool write_packet(vpn_packet_t *packet) { + long outlen; ifdebug(TRAFFIC) logger(LOG_DEBUG, "Writing packet of %d bytes to %s", - packet->len, device_info); + packet->len, device_info); - if(!WriteFile(device_handle, packet->data, packet->len, &lenout, NULL)) { + if(!WriteFile (device_handle, packet->data, packet->len, &outlen, NULL)) { logger(LOG_ERR, "Error while writing to %s %s: %s", device_info, device, winerror(GetLastError())); return false; } @@ -272,16 +260,8 @@ static bool write_packet(vpn_packet_t *packet) { return true; } -static void dump_device_stats(void) { +void dump_device_stats(void) { logger(LOG_DEBUG, "Statistics for %s %s:", device_info, device); logger(LOG_DEBUG, " total bytes in: %10"PRIu64, device_total_in); logger(LOG_DEBUG, " total bytes out: %10"PRIu64, device_total_out); } - -const devops_t os_devops = { - .setup = setup_device, - .close = close_device, - .read = read_packet, - .write = write_packet, - .dump_stats = dump_device_stats, -}; diff --git a/src/device.h b/src/device.h index 6bfc44d..16a2486 100644 --- a/src/device.h +++ b/src/device.h @@ -1,10 +1,7 @@ -#ifndef TINC_DEVICE_H -#define TINC_DEVICE_H - /* - device.h -- generic header for device.c + net.h -- generic header for device.c Copyright (C) 2001-2005 Ivo Timmermans - 2001-2012 Guus Sliepen + 2001-2006 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 @@ -21,27 +18,24 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +#ifndef __TINC_DEVICE_H__ +#define __TINC_DEVICE_H__ + #include "net.h" extern int device_fd; extern char *device; - extern char *iface; -typedef struct devops_t { - bool (*setup)(void); - void (*close)(void); - bool (*read)(struct vpn_packet_t *packet); - bool (*write)(struct vpn_packet_t *packet); - void (*dump_stats)(void); -} devops_t; +extern uint64_t device_in_packets; +extern uint64_t device_in_bytes; +extern uint64_t device_out_packets; +extern uint64_t device_out_bytes; -extern const devops_t os_devops; -extern const devops_t dummy_devops; -extern const devops_t raw_socket_devops; -extern const devops_t multicast_devops; -extern const devops_t uml_devops; -extern const devops_t vde_devops; -extern devops_t devops; +extern bool setup_device(void); +extern void close_device(void); +extern bool read_packet(struct vpn_packet_t *); +extern bool write_packet(struct vpn_packet_t *); +extern void dump_device_stats(void); -#endif +#endif /* __TINC_DEVICE_H__ */ diff --git a/src/dropin.c b/src/dropin.c index 93511f1..eb17aca 100644 --- a/src/dropin.c +++ b/src/dropin.c @@ -1,7 +1,7 @@ /* dropin.c -- a set of drop-in replacements for libc functions Copyright (C) 2000-2005 Ivo Timmermans, - 2000-2016 Guus Sliepen + 2000-2011 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 @@ -25,7 +25,7 @@ #ifndef HAVE_DAEMON /* Replacement for the daemon() function. - + The daemon() function is for programs wishing to detach themselves from the controlling terminal and run in the background as system daemons. @@ -50,9 +50,8 @@ int daemon(int nochdir, int noclose) { } /* If we are the parent, terminate */ - if(pid) { + if(pid) exit(0); - } /* Detach by becoming the new process group leader */ if(setsid() < 0) { @@ -87,6 +86,40 @@ int daemon(int nochdir, int noclose) { } #endif +#ifndef HAVE_GET_CURRENT_DIR_NAME +/* + Replacement for the GNU get_current_dir_name function: + + get_current_dir_name will malloc(3) an array big enough to hold the + current directory name. If the environment variable PWD is set, and + its value is correct, then that value will be returned. +*/ +char *get_current_dir_name(void) { + size_t size; + char *buf; + char *r; + + /* Start with 100 bytes. If this turns out to be insufficient to + contain the working directory, double the size. */ + size = 100; + buf = xmalloc(size); + + errno = 0; /* Success */ + r = getcwd(buf, size); + + /* getcwd returns NULL and sets errno to ERANGE if the bufferspace + is insufficient to contain the entire working directory. */ + while(r == NULL && errno == ERANGE) { + free(buf); + size <<= 1; /* double the size */ + buf = xmalloc(size); + r = getcwd(buf, size); + } + + return buf; +} +#endif + #ifndef HAVE_ASPRINTF int asprintf(char **buf, const char *fmt, ...) { int result; @@ -107,12 +140,10 @@ int vasprintf(char **buf, const char *fmt, va_list ap) { va_copy(aq, ap); status = vsnprintf(*buf, len, fmt, aq); - buf[len - 1] = 0; va_end(aq); - if(status >= 0) { + if(status >= 0) *buf = xrealloc(*buf, status + 1); - } if(status > len - 1) { len = status; diff --git a/src/dropin.h b/src/dropin.h index 012099b..3617b70 100644 --- a/src/dropin.h +++ b/src/dropin.h @@ -1,6 +1,3 @@ -#ifndef TINC_DROPIN_H -#define TINC_DROPIN_H - /* dropin.h -- header file for dropin.c Copyright (C) 2000-2005 Ivo Timmermans, @@ -21,11 +18,14 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +#ifndef __DROPIN_H__ +#define __DROPIN_H__ + #include "fake-getaddrinfo.h" #include "fake-getnameinfo.h" #ifndef HAVE_DAEMON -extern int daemon(int nochdir, int noclose); +extern int daemon(int, int); #endif #ifndef HAVE_GET_CURRENT_DIR_NAME @@ -33,16 +33,16 @@ extern char *get_current_dir_name(void); #endif #ifndef HAVE_ASPRINTF -extern int asprintf(char **buf, const char *fmt, ...); -extern int vasprintf(char **buf, const char *fmt, va_list ap); +extern int asprintf(char **, const char *, ...); +extern int vasprintf(char **, const char *, va_list ap); #endif #ifndef HAVE_GETTIMEOFDAY -extern int gettimeofday(struct timeval *tv, void *tz); +extern int gettimeofday(struct timeval *, void *); #endif #ifndef HAVE_USLEEP extern int usleep(long long usec); #endif -#endif +#endif /* __DROPIN_H__ */ diff --git a/src/dummy_device.c b/src/dummy_device.c deleted file mode 100644 index d1d751b..0000000 --- a/src/dummy_device.c +++ /dev/null @@ -1,66 +0,0 @@ -/* - device.c -- Dummy device - Copyright (C) 2011 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 - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include "system.h" - -#include "device.h" -#include "logger.h" -#include "net.h" -#include "xalloc.h" - -static const char *device_info = "dummy device"; - -static uint64_t device_total_in = 0; -static uint64_t device_total_out = 0; - -static bool setup_device(void) { - device = xstrdup("dummy"); - iface = xstrdup("dummy"); - logger(LOG_INFO, "%s (%s) is a %s", device, iface, device_info); - return true; -} - -static void close_device(void) { - free(device); - free(iface); -} - -static bool read_packet(vpn_packet_t *packet) { - (void)packet; - return false; -} - -static bool write_packet(vpn_packet_t *packet) { - device_total_out += packet->len; - return true; -} - -static void dump_device_stats(void) { - logger(LOG_DEBUG, "Statistics for %s %s:", device_info, device); - logger(LOG_DEBUG, " total bytes in: %10"PRIu64, device_total_in); - logger(LOG_DEBUG, " total bytes out: %10"PRIu64, device_total_out); -} - -const devops_t dummy_devops = { - .setup = setup_device, - .close = close_device, - .read = read_packet, - .write = write_packet, - .dump_stats = dump_device_stats, -}; diff --git a/src/edge.c b/src/edge.c index c30d6cc..f5aa099 100644 --- a/src/edge.c +++ b/src/edge.c @@ -20,7 +20,8 @@ #include "system.h" -#include "avl_tree.h" +#include "splay_tree.h" +#include "control_common.h" #include "edge.h" #include "logger.h" #include "netutl.h" @@ -28,7 +29,7 @@ #include "utils.h" #include "xalloc.h" -avl_tree_t *edge_weight_tree; /* Tree with all edges, sorted on weight */ +splay_tree_t *edge_weight_tree; /* Tree with all edges, sorted on weight */ static int edge_compare(const edge_t *a, const edge_t *b) { return strcmp(a->to->name, b->to->name); @@ -39,33 +40,31 @@ static int edge_weight_compare(const edge_t *a, const edge_t *b) { result = a->weight - b->weight; - if(result) { + if(result) return result; - } result = strcmp(a->from->name, b->from->name); - if(result) { + if(result) return result; - } return strcmp(a->to->name, b->to->name); } void init_edges(void) { - edge_weight_tree = avl_alloc_tree((avl_compare_t) edge_weight_compare, NULL); + edge_weight_tree = splay_alloc_tree((splay_compare_t) edge_weight_compare, NULL); } -avl_tree_t *new_edge_tree(void) { - return avl_alloc_tree((avl_compare_t) edge_compare, (avl_action_t) free_edge); +splay_tree_t *new_edge_tree(void) { + return splay_alloc_tree((splay_compare_t) edge_compare, (splay_action_t) free_edge); } -void free_edge_tree(avl_tree_t *edge_tree) { - avl_delete_tree(edge_tree); +void free_edge_tree(splay_tree_t *edge_tree) { + splay_delete_tree(edge_tree); } void exit_edges(void) { - avl_delete_tree(edge_weight_tree); + splay_delete_tree(edge_weight_tree); } /* Creation and deletion of connection elements */ @@ -81,53 +80,50 @@ void free_edge(edge_t *e) { } void edge_add(edge_t *e) { - avl_insert(edge_weight_tree, e); - avl_insert(e->from->edge_tree, e); + splay_insert(edge_weight_tree, e); + splay_insert(e->from->edge_tree, e); e->reverse = lookup_edge(e->to, e->from); - if(e->reverse) { + if(e->reverse) e->reverse->reverse = e; - } } void edge_del(edge_t *e) { - if(e->reverse) { + if(e->reverse) e->reverse->reverse = NULL; - } - avl_delete(edge_weight_tree, e); - avl_delete(e->from->edge_tree, e); + splay_delete(edge_weight_tree, e); + splay_delete(e->from->edge_tree, e); } edge_t *lookup_edge(node_t *from, node_t *to) { edge_t v; - + v.from = from; v.to = to; - return avl_search(from->edge_tree, &v); + return splay_search(from->edge_tree, &v); } -void dump_edges(void) { - avl_node_t *node, *node2; +bool dump_edges(connection_t *c) { + splay_node_t *node, *node2; node_t *n; edge_t *e; char *address; - logger(LOG_DEBUG, "Edges:"); - for(node = node_tree->head; node; node = node->next) { n = node->data; - for(node2 = n->edge_tree->head; node2; node2 = node2->next) { e = node2->data; address = sockaddr2hostname(&e->address); - logger(LOG_DEBUG, " %s to %s at %s options %x weight %d", - e->from->name, e->to->name, address, e->options, e->weight); + send_request(c, "%d %d %s to %s at %s options %x weight %d", + CONTROL, REQ_DUMP_EDGES, + e->from->name, e->to->name, address, + e->options, e->weight); free(address); } } - logger(LOG_DEBUG, "End of edges."); + return send_request(c, "%d %d", CONTROL, REQ_DUMP_EDGES); } diff --git a/src/edge.h b/src/edge.h index a7a6302..ea45f49 100644 --- a/src/edge.h +++ b/src/edge.h @@ -1,6 +1,3 @@ -#ifndef TINC_EDGE_H -#define TINC_EDGE_H - /* edge.h -- header for edge.c Copyright (C) 2001-2006 Guus Sliepen , @@ -21,7 +18,10 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#include "avl_tree.h" +#ifndef __TINC_EDGE_H__ +#define __TINC_EDGE_H__ + +#include "splay_tree.h" #include "connection.h" #include "net.h" #include "node.h" @@ -31,24 +31,24 @@ typedef struct edge_t { struct node_t *to; sockaddr_t address; - uint32_t options; /* options turned on for this edge */ - int weight; /* weight of this edge */ + uint32_t options; /* options turned on for this edge */ + int weight; /* weight of this edge */ - struct connection_t *connection; /* connection associated with this edge, if available */ - struct edge_t *reverse; /* edge in the opposite direction, if available */ + struct connection_t *connection; /* connection associated with this edge, if available */ + struct edge_t *reverse; /* edge in the opposite direction, if available */ } edge_t; -extern avl_tree_t *edge_weight_tree; /* Tree with all known edges sorted on weight */ +extern splay_tree_t *edge_weight_tree; /* Tree with all known edges sorted on weight */ extern void init_edges(void); extern void exit_edges(void); -extern edge_t *new_edge(void) __attribute__((__malloc__)); -extern void free_edge(edge_t *e); -extern avl_tree_t *new_edge_tree(void) __attribute__((__malloc__)); -extern void free_edge_tree(avl_tree_t *edge_tree); -extern void edge_add(edge_t *e); -extern void edge_del(edge_t *e); -extern edge_t *lookup_edge(struct node_t *from, struct node_t *to); -extern void dump_edges(void); +extern edge_t *new_edge(void) __attribute__ ((__malloc__)); +extern void free_edge(edge_t *); +extern splay_tree_t *new_edge_tree(void) __attribute__ ((__malloc__)); +extern void free_edge_tree(splay_tree_t *); +extern void edge_add(edge_t *); +extern void edge_del(edge_t *); +extern edge_t *lookup_edge(struct node_t *, struct node_t *); +extern bool dump_edges(struct connection_t *); -#endif +#endif /* __TINC_EDGE_H__ */ diff --git a/src/ethernet.h b/src/ethernet.h index 32f5553..eef5f42 100644 --- a/src/ethernet.h +++ b/src/ethernet.h @@ -1,6 +1,3 @@ -#ifndef TINC_ETHERNET_H -#define TINC_ETHERNET_H - /* ethernet.h -- missing Ethernet related definitions Copyright (C) 2005 Ivo Timmermans @@ -21,6 +18,9 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +#ifndef __TINC_ETHERNET_H__ +#define __TINC_ETHERNET_H__ + #ifndef ETH_ALEN #define ETH_ALEN 6 #endif @@ -41,16 +41,12 @@ #define ETH_P_IPV6 0x86DD #endif -#ifndef ETH_P_8021Q -#define ETH_P_8021Q 0x8100 -#endif - #ifndef HAVE_STRUCT_ETHER_HEADER struct ether_header { uint8_t ether_dhost[ETH_ALEN]; uint8_t ether_shost[ETH_ALEN]; uint16_t ether_type; -} __attribute__((__packed__)); +} __attribute__ ((__packed__)); #endif #ifndef HAVE_STRUCT_ARPHDR @@ -58,17 +54,17 @@ struct arphdr { uint16_t ar_hrd; uint16_t ar_pro; uint8_t ar_hln; - uint8_t ar_pln; - uint16_t ar_op; -} __attribute__((__packed__)); + uint8_t ar_pln; + uint16_t ar_op; +} __attribute__ ((__packed__)); -#define ARPOP_REQUEST 1 -#define ARPOP_REPLY 2 -#define ARPOP_RREQUEST 3 -#define ARPOP_RREPLY 4 -#define ARPOP_InREQUEST 8 -#define ARPOP_InREPLY 9 -#define ARPOP_NAK 10 +#define ARPOP_REQUEST 1 +#define ARPOP_REPLY 2 +#define ARPOP_RREQUEST 3 +#define ARPOP_RREPLY 4 +#define ARPOP_InREQUEST 8 +#define ARPOP_InREPLY 9 +#define ARPOP_NAK 10 #endif #ifndef HAVE_STRUCT_ETHER_ARP @@ -78,7 +74,7 @@ struct ether_arp { uint8_t arp_spa[4]; uint8_t arp_tha[ETH_ALEN]; uint8_t arp_tpa[4]; -} __attribute__((__packed__)); +} __attribute__ ((__packed__)); #define arp_hrd ea_hdr.ar_hrd #define arp_pro ea_hdr.ar_pro #define arp_hln ea_hdr.ar_hln @@ -86,4 +82,4 @@ struct ether_arp { #define arp_op ea_hdr.ar_op #endif -#endif +#endif /* __TINC_ETHERNET_H__ */ diff --git a/src/event.c b/src/event.c deleted file mode 100644 index 1223222..0000000 --- a/src/event.c +++ /dev/null @@ -1,121 +0,0 @@ -/* - event.c -- event queue - Copyright (C) 2002-2009 Guus Sliepen , - 2002-2005 Ivo Timmermans - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include "system.h" - -#include "avl_tree.h" -#include "event.h" -#include "utils.h" -#include "xalloc.h" - -avl_tree_t *event_tree; -extern time_t now; - -static int id; - -static int event_compare(const event_t *a, const event_t *b) { - if(a->time > b->time) { - return 1; - } - - if(a->time < b->time) { - return -1; - } - - return a->id - b->id; -} - -void init_events(void) { - event_tree = avl_alloc_tree((avl_compare_t) event_compare, (avl_action_t) free_event); -} - -void exit_events(void) { - avl_delete_tree(event_tree); -} - -void expire_events(void) { - avl_node_t *node; - event_t *event; - time_t diff; - - /* - * Make all events appear expired by subtracting the difference between - * the expiration time of the last event and the current time. - */ - - if(!event_tree->tail) { - return; - } - - event = event_tree->tail->data; - - if(event->time <= now) { - return; - } - - diff = event->time - now; - - for(node = event_tree->head; node; node = node->next) { - event = node->data; - event->time -= diff; - } -} - -event_t *new_event(void) { - return xmalloc_and_zero(sizeof(event_t)); -} - -void free_event(event_t *event) { - free(event); -} - -void event_add(event_t *event) { - event->id = ++id; - avl_insert(event_tree, event); -} - -void event_del(event_t *event) { - avl_delete(event_tree, event); -} - -event_t *get_expired_event(void) { - event_t *event; - - if(event_tree->head) { - event = event_tree->head->data; - - if(event->time <= now) { - avl_node_t *node = event_tree->head; - avl_unlink_node(event_tree, node); - free(node); - return event; - } - } - - return NULL; -} - -event_t *peek_next_event(void) { - if(event_tree->head) { - return event_tree->head->data; - } - - return NULL; -} diff --git a/src/fake-gai-errnos.h b/src/fake-gai-errnos.h new file mode 100644 index 0000000..4ffabb6 --- /dev/null +++ b/src/fake-gai-errnos.h @@ -0,0 +1,19 @@ +/* + * fake library for ssh + * + * This file is included in getaddrinfo.c and getnameinfo.c. + * See getaddrinfo.c and getnameinfo.c. + */ + +/* for old netdb.h */ +#ifndef EAI_NODATA +#define EAI_NODATA 1 +#endif + +#ifndef EAI_MEMORY +#define EAI_MEMORY 2 +#endif + +#ifndef EAI_FAMILY +#define EAI_FAMILY 3 +#endif diff --git a/src/fake-getaddrinfo.c b/src/fake-getaddrinfo.c index 1ee11c5..df3d347 100644 --- a/src/fake-getaddrinfo.c +++ b/src/fake-getaddrinfo.c @@ -2,10 +2,10 @@ * fake library for ssh * * This file includes getaddrinfo(), freeaddrinfo() and gai_strerror(). - * These functions are defined in rfc2133. + * These funtions are defined in rfc2133. * * But these functions are not implemented correctly. The minimum subset - * is implemented for ssh use only. For example, this routine assumes + * is implemented for ssh use only. For exapmle, this routine assumes * that ai_family is AF_INET. Don't use it for another purpose. */ @@ -16,22 +16,20 @@ #include "fake-getaddrinfo.h" #include "xalloc.h" + #if !HAVE_DECL_GAI_STRERROR char *gai_strerror(int ecode) { - switch(ecode) { - case EAI_NODATA: - return "No address associated with hostname"; - - case EAI_MEMORY: - return "Memory allocation failure"; - - case EAI_FAMILY: - return "Address family not supported"; - - default: - return "Unknown error"; + switch (ecode) { + case EAI_NODATA: + return "No address associated with hostname"; + case EAI_MEMORY: + return "Memory allocation failure"; + case EAI_FAMILY: + return "Address family not supported"; + default: + return "Unknown error"; } -} +} #endif /* !HAVE_GAI_STRERROR */ #if !HAVE_DECL_FREEADDRINFO @@ -51,14 +49,14 @@ static struct addrinfo *malloc_ai(uint16_t port, uint32_t addr) { struct addrinfo *ai; ai = xmalloc_and_zero(sizeof(struct addrinfo) + sizeof(struct sockaddr_in)); - + ai->ai_addr = (struct sockaddr *)(ai + 1); ai->ai_addrlen = sizeof(struct sockaddr_in); ai->ai_addr->sa_family = ai->ai_family = AF_INET; ((struct sockaddr_in *)(ai)->ai_addr)->sin_port = port; ((struct sockaddr_in *)(ai)->ai_addr)->sin_addr.s_addr = addr; - + return ai; } @@ -69,36 +67,32 @@ int getaddrinfo(const char *hostname, const char *servname, const struct addrinf int i; uint16_t port = 0; - if(hints && hints->ai_family != AF_INET && hints->ai_family != AF_UNSPEC) { + if(hints && hints->ai_family != AF_INET && hints->ai_family != AF_UNSPEC) return EAI_FAMILY; - } - if(servname) { + if (servname) port = htons(atoi(servname)); - } - if(hints && hints->ai_flags & AI_PASSIVE) { + if (hints && hints->ai_flags & AI_PASSIVE) { *res = malloc_ai(port, htonl(0x00000000)); return 0; } - - if(!hostname) { + + if (!hostname) { *res = malloc_ai(port, htonl(0x7f000001)); return 0; } - + hp = gethostbyname(hostname); - if(!hp || !hp->h_addr_list || !hp->h_addr_list[0]) { + if(!hp || !hp->h_addr_list || !hp->h_addr_list[0]) return EAI_NODATA; - } - for(i = 0; hp->h_addr_list[i]; i++) { + for (i = 0; hp->h_addr_list[i]; i++) { *res = malloc_ai(port, ((struct in_addr *)hp->h_addr_list[i])->s_addr); - if(prev) { + if(prev) prev->ai_next = *res; - } prev = *res; } diff --git a/src/fake-getaddrinfo.h b/src/fake-getaddrinfo.h index f10cb83..5af7491 100644 --- a/src/fake-getaddrinfo.h +++ b/src/fake-getaddrinfo.h @@ -1,17 +1,7 @@ -#ifndef TINC_FAKE_GETADDRINFO_H -#define TINC_FAKE_GETADDRINFO_H +#ifndef _FAKE_GETADDRINFO_H +#define _FAKE_GETADDRINFO_H -#ifndef EAI_NODATA -#define EAI_NODATA 1 -#endif - -#ifndef EAI_MEMORY -#define EAI_MEMORY 2 -#endif - -#ifndef EAI_FAMILY -#define EAI_FAMILY 3 -#endif +#include "fake-gai-errnos.h" #ifndef AI_PASSIVE # define AI_PASSIVE 1 @@ -30,19 +20,19 @@ #ifndef HAVE_STRUCT_ADDRINFO struct addrinfo { - int ai_flags; /* AI_PASSIVE, AI_CANONNAME */ - int ai_family; /* PF_xxx */ - int ai_socktype; /* SOCK_xxx */ - int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */ - size_t ai_addrlen; /* length of ai_addr */ - char *ai_canonname; /* canonical name for hostname */ - struct sockaddr *ai_addr; /* binary address */ - struct addrinfo *ai_next; /* next structure in linked list */ + int ai_flags; /* AI_PASSIVE, AI_CANONNAME */ + int ai_family; /* PF_xxx */ + int ai_socktype; /* SOCK_xxx */ + int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */ + size_t ai_addrlen; /* length of ai_addr */ + char *ai_canonname; /* canonical name for hostname */ + struct sockaddr *ai_addr; /* binary address */ + struct addrinfo *ai_next; /* next structure in linked list */ }; #endif /* !HAVE_STRUCT_ADDRINFO */ #if !HAVE_DECL_GETADDRINFO -int getaddrinfo(const char *hostname, const char *servname, +int getaddrinfo(const char *hostname, const char *servname, const struct addrinfo *hints, struct addrinfo **res); #endif /* !HAVE_GETADDRINFO */ @@ -54,4 +44,4 @@ char *gai_strerror(int ecode); void freeaddrinfo(struct addrinfo *ai); #endif /* !HAVE_FREEADDRINFO */ -#endif +#endif /* _FAKE_GETADDRINFO_H */ diff --git a/src/fake-getnameinfo.c b/src/fake-getnameinfo.c index e51bce2..1eba492 100644 --- a/src/fake-getnameinfo.c +++ b/src/fake-getnameinfo.c @@ -2,10 +2,10 @@ * fake library for ssh * * This file includes getnameinfo(). - * These functions are defined in rfc2133. + * These funtions are defined in rfc2133. * * But these functions are not implemented correctly. The minimum subset - * is implemented for ssh use only. For example, this routine assumes + * is implemented for ssh use only. For exapmle, this routine assumes * that ai_family is AF_INET. Don't use it for another purpose. */ @@ -21,43 +21,33 @@ int getnameinfo(const struct sockaddr *sa, size_t salen, char *host, size_t host struct hostent *hp; int len; - if(sa->sa_family != AF_INET) { + if(sa->sa_family != AF_INET) return EAI_FAMILY; - } if(serv && servlen) { len = snprintf(serv, servlen, "%d", ntohs(sin->sin_port)); - - if(len < 0 || len >= servlen) { + if(len < 0 || len >= servlen) return EAI_MEMORY; - } } - if(!host || !hostlen) { + if(!host || !hostlen) return 0; - } if(flags & NI_NUMERICHOST) { len = snprintf(host, hostlen, "%s", inet_ntoa(sin->sin_addr)); - - if(len < 0 || len >= hostlen) { + if(len < 0 || len >= hostlen) return EAI_MEMORY; - } - return 0; } hp = gethostbyaddr((char *)&sin->sin_addr, sizeof(struct in_addr), AF_INET); - - if(!hp || !hp->h_name || !hp->h_name[0]) { + + if(!hp || !hp->h_name || !hp->h_name[0]) return EAI_NODATA; - } - + len = snprintf(host, hostlen, "%s", hp->h_name); - - if(len < 0 || len >= hostlen) { + if(len < 0 || len >= hostlen) return EAI_MEMORY; - } return 0; } diff --git a/src/fake-getnameinfo.h b/src/fake-getnameinfo.h index 4f24ad1..4389a8f 100644 --- a/src/fake-getnameinfo.h +++ b/src/fake-getnameinfo.h @@ -1,8 +1,8 @@ -#ifndef TINC_FAKE_GETNAMEINFO_H -#define TINC_FAKE_GETNAMEINFO_H +#ifndef _FAKE_GETNAMEINFO_H +#define _FAKE_GETNAMEINFO_H #if !HAVE_DECL_GETNAMEINFO -int getnameinfo(const struct sockaddr *sa, size_t salen, char *host, +int getnameinfo(const struct sockaddr *sa, size_t salen, char *host, size_t hostlen, char *serv, size_t servlen, int flags); #endif /* !HAVE_GETNAMEINFO */ @@ -13,4 +13,4 @@ int getnameinfo(const struct sockaddr *sa, size_t salen, char *host, # define NI_MAXHOST 1025 #endif /* !NI_MAXHOST */ -#endif +#endif /* _FAKE_GETNAMEINFO_H */ diff --git a/src/gcrypt/cipher.c b/src/gcrypt/cipher.c new file mode 100644 index 0000000..6a2cc5a --- /dev/null +++ b/src/gcrypt/cipher.c @@ -0,0 +1,280 @@ +/* + cipher.c -- Symmetric block cipher handling + Copyright (C) 2007 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "system.h" + +#include "cipher.h" +#include "logger.h" +#include "xalloc.h" + +static struct { + const char *name; + int algo; + int mode; + int nid; +} ciphertable[] = { + {"none", GCRY_CIPHER_NONE, GCRY_CIPHER_MODE_NONE, 0}, + + {NULL, GCRY_CIPHER_BLOWFISH, GCRY_CIPHER_MODE_ECB, 92}, + {"blowfish", GCRY_CIPHER_BLOWFISH, GCRY_CIPHER_MODE_CBC, 91}, + {NULL, GCRY_CIPHER_BLOWFISH, GCRY_CIPHER_MODE_CFB, 93}, + {NULL, GCRY_CIPHER_BLOWFISH, GCRY_CIPHER_MODE_OFB, 94}, + + {NULL, GCRY_CIPHER_AES, GCRY_CIPHER_MODE_ECB, 418}, + {"aes", GCRY_CIPHER_AES, GCRY_CIPHER_MODE_CBC, 419}, + {NULL, GCRY_CIPHER_AES, GCRY_CIPHER_MODE_CFB, 421}, + {NULL, GCRY_CIPHER_AES, GCRY_CIPHER_MODE_OFB, 420}, + + {NULL, GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_ECB, 422}, + {"aes192", GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_CBC, 423}, + {NULL, GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_CFB, 425}, + {NULL, GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_OFB, 424}, + + {NULL, GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_ECB, 426}, + {"aes256", GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CBC, 427}, + {NULL, GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CFB, 429}, + {NULL, GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_OFB, 428}, +}; + +static bool nametocipher(const char *name, int *algo, int *mode) { + size_t i; + + for(i = 0; i < sizeof ciphertable / sizeof *ciphertable; i++) { + if(ciphertable[i].name && !strcasecmp(name, ciphertable[i].name)) { + *algo = ciphertable[i].algo; + *mode = ciphertable[i].mode; + return true; + } + } + + return false; +} + +static bool nidtocipher(int nid, int *algo, int *mode) { + size_t i; + + for(i = 0; i < sizeof ciphertable / sizeof *ciphertable; i++) { + if(nid == ciphertable[i].nid) { + *algo = ciphertable[i].algo; + *mode = ciphertable[i].mode; + return true; + } + } + + return false; +} + +static bool ciphertonid(int algo, int mode, int *nid) { + size_t i; + + for(i = 0; i < sizeof ciphertable / sizeof *ciphertable; i++) { + if(algo == ciphertable[i].algo && mode == ciphertable[i].mode) { + *nid = ciphertable[i].nid; + return true; + } + } + + return false; +} + +static bool cipher_open(cipher_t *cipher, int algo, int mode) { + gcry_error_t err; + + if(!ciphertonid(algo, mode, &cipher->nid)) { + logger(LOG_DEBUG, "Cipher %d mode %d has no corresponding nid!", algo, mode); + return false; + } + + if((err = gcry_cipher_open(&cipher->handle, algo, mode, 0))) { + logger(LOG_DEBUG, "Unable to intialise cipher %d mode %d: %s", algo, mode, gcry_strerror(err)); + return false; + } + + cipher->keylen = gcry_cipher_get_algo_keylen(algo); + cipher->blklen = gcry_cipher_get_algo_blklen(algo); + cipher->key = xmalloc(cipher->keylen + cipher->blklen); + cipher->padding = mode == GCRY_CIPHER_MODE_ECB || mode == GCRY_CIPHER_MODE_CBC; + + return true; +} + +bool cipher_open_by_name(cipher_t *cipher, const char *name) { + int algo, mode; + + if(!nametocipher(name, &algo, &mode)) { + logger(LOG_DEBUG, "Unknown cipher name '%s'!", name); + return false; + } + + return cipher_open(cipher, algo, mode); +} + +bool cipher_open_by_nid(cipher_t *cipher, int nid) { + int algo, mode; + + if(!nidtocipher(nid, &algo, &mode)) { + logger(LOG_DEBUG, "Unknown cipher ID %d!", nid); + return false; + } + + return cipher_open(cipher, algo, mode); +} + +bool cipher_open_blowfish_ofb(cipher_t *cipher) { + return cipher_open(cipher, GCRY_CIPHER_BLOWFISH, GCRY_CIPHER_MODE_OFB); +} + +void cipher_close(cipher_t *cipher) { + if(cipher->handle) { + gcry_cipher_close(cipher->handle); + cipher->handle = NULL; + } + + if(cipher->key) { + free(cipher->key); + cipher->key = NULL; + } +} + +size_t cipher_keylength(const cipher_t *cipher) { + return cipher->keylen + cipher->blklen; +} + +void cipher_get_key(const cipher_t *cipher, void *key) { + memcpy(key, cipher->key, cipher->keylen + cipher->blklen); +} + +bool cipher_set_key(cipher_t *cipher, void *key, bool encrypt) { + memcpy(cipher->key, key, cipher->keylen + cipher->blklen); + + gcry_cipher_setkey(cipher->handle, cipher->key, cipher->keylen); + gcry_cipher_setiv(cipher->handle, cipher->key + cipher->keylen, cipher->blklen); + + return true; +} + +bool cipher_set_key_from_rsa(cipher_t *cipher, void *key, size_t len, bool encrypt) { + memcpy(cipher->key, key + len - cipher->keylen, cipher->keylen + cipher->blklen); + memcpy(cipher->key + cipher->keylen, key + len - cipher->keylen - cipher->blklen, cipher->blklen); + + gcry_cipher_setkey(cipher->handle, cipher->key, cipher->keylen); + gcry_cipher_setiv(cipher->handle, cipher->key + cipher->keylen, cipher->blklen); + + return true; +} + +bool cipher_regenerate_key(cipher_t *cipher, bool encrypt) { + gcry_create_nonce(cipher->key, cipher->keylen + cipher->blklen); + + gcry_cipher_setkey(cipher->handle, cipher->key, cipher->keylen); + gcry_cipher_setiv(cipher->handle, cipher->key + cipher->keylen, cipher->blklen); + + return true; +} + +bool cipher_encrypt(cipher_t *cipher, const void *indata, size_t inlen, void *outdata, size_t *outlen, bool oneshot) { + gcry_error_t err; + uint8_t pad[cipher->blklen]; + + if(cipher->padding) { + if(!oneshot) + return false; + + size_t reqlen = ((inlen + cipher->blklen) / cipher->blklen) * cipher->blklen; + + if(*outlen < reqlen) { + logger(LOG_ERR, "Error while encrypting: not enough room for padding"); + return false; + } + + uint8_t padbyte = reqlen - inlen; + inlen = reqlen - cipher->blklen; + + for(int i = 0; i < cipher->blklen; i++) + if(i < cipher->blklen - padbyte) + pad[i] = ((uint8_t *)indata)[inlen + i]; + else + pad[i] = padbyte; + } + + if(oneshot) + gcry_cipher_setiv(cipher->handle, cipher->key + cipher->keylen, cipher->blklen); + + if((err = gcry_cipher_encrypt(cipher->handle, outdata, *outlen, indata, inlen))) { + logger(LOG_ERR, "Error while encrypting: %s", gcry_strerror(err)); + return false; + } + + if(cipher->padding) { + if((err = gcry_cipher_encrypt(cipher->handle, outdata + inlen, cipher->blklen, pad, cipher->blklen))) { + logger(LOG_ERR, "Error while encrypting: %s", gcry_strerror(err)); + return false; + } + + inlen += cipher->blklen; + } + + *outlen = inlen; + return true; +} + +bool cipher_decrypt(cipher_t *cipher, const void *indata, size_t inlen, void *outdata, size_t *outlen, bool oneshot) { + gcry_error_t err; + + if(oneshot) + gcry_cipher_setiv(cipher->handle, cipher->key + cipher->keylen, cipher->blklen); + + if((err = gcry_cipher_decrypt(cipher->handle, outdata, *outlen, indata, inlen))) { + logger(LOG_ERR, "Error while decrypting: %s", gcry_strerror(err)); + return false; + } + + if(cipher->padding) { + if(!oneshot) + return false; + + uint8_t padbyte = ((uint8_t *)outdata)[inlen - 1]; + + if(padbyte == 0 || padbyte > cipher->blklen || padbyte > inlen) { + logger(LOG_ERR, "Error while decrypting: invalid padding"); + return false; + } + + size_t origlen = inlen - padbyte; + + for(int i = inlen - 1; i >= origlen; i--) + if(((uint8_t *)outdata)[i] != padbyte) { + logger(LOG_ERR, "Error while decrypting: invalid padding"); + return false; + } + + *outlen = origlen; + } else + *outlen = inlen; + + return true; +} + +int cipher_get_nid(const cipher_t *cipher) { + return cipher->nid; +} + +bool cipher_active(const cipher_t *cipher) { + return cipher->nid != 0; +} diff --git a/src/gcrypt/cipher.h b/src/gcrypt/cipher.h new file mode 100644 index 0000000..8e4a2eb --- /dev/null +++ b/src/gcrypt/cipher.h @@ -0,0 +1,52 @@ +/* + cipher.h -- header file cipher.c + Copyright (C) 2007 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#ifndef __TINC_CIPHER_H__ +#define __TINC_CIPHER_H__ + +#include + +#define CIPHER_MAX_BLOCK_SIZE 32 +#define CIPHER_MAX_IV_SIZE 16 +#define CIPHER_MAX_KEY_SIZE 32 + +typedef struct cipher { + gcry_cipher_hd_t handle; + char *key; + int nid; + uint16_t keylen; + uint16_t blklen; + bool padding; +} cipher_t; + +extern bool cipher_open_by_name(struct cipher *, const char *); +extern bool cipher_open_by_nid(struct cipher *, int); +extern bool cipher_open_blowfish_ofb(struct cipher *); +extern void cipher_close(struct cipher *); +extern size_t cipher_keylength(const struct cipher *); +extern void cipher_get_key(const struct cipher *, void *); +extern bool cipher_set_key(struct cipher *, void *, bool); +extern bool cipher_set_key_from_rsa(struct cipher *, void *, size_t, bool); +extern bool cipher_regenerate_key(struct cipher *, bool); +extern bool cipher_encrypt(struct cipher *, const void *indata, size_t inlen, void *outdata, size_t *outlen, bool oneshot); +extern bool cipher_decrypt(struct cipher *, const void *indata, size_t inlen, void *outdata, size_t *outlen, bool oneshot); +extern int cipher_get_nid(const struct cipher *); +extern bool cipher_active(const struct cipher *); + +#endif diff --git a/src/gcrypt/crypto.c b/src/gcrypt/crypto.c new file mode 100644 index 0000000..dc92b3e --- /dev/null +++ b/src/gcrypt/crypto.c @@ -0,0 +1,34 @@ +/* + crypto.c -- Cryptographic miscellaneous functions and initialisation + Copyright (C) 2007 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "system.h" + +#include + +#include "crypto.h" + +void crypto_init() { +} + +void crypto_exit() { +} + +void randomize(void *out, size_t outlen) { + gcry_create_nonce(out, outlen); +} diff --git a/src/gcrypt/crypto.h b/src/gcrypt/crypto.h new file mode 100644 index 0000000..8047bfb --- /dev/null +++ b/src/gcrypt/crypto.h @@ -0,0 +1,27 @@ +/* + crypto.h -- header for crypto.c + Copyright (C) 2007 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#ifndef __TINC_CRYPTO_H__ +#define __TINC_CRYPTO_H__ + +extern void crypto_init(); +extern void crypto_exit(); +extern void randomize(void *, size_t); + +#endif diff --git a/src/gcrypt/digest.c b/src/gcrypt/digest.c new file mode 100644 index 0000000..066600f --- /dev/null +++ b/src/gcrypt/digest.c @@ -0,0 +1,173 @@ +/* + digest.c -- Digest handling + Copyright (C) 2007 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "system.h" + +#include "digest.h" +#include "logger.h" + +static struct { + const char *name; + int algo; + int nid; +} digesttable[] = { + {"none", GCRY_MD_NONE, 0}, + {"sha1", GCRY_MD_SHA1, 64}, + {"sha256", GCRY_MD_SHA256, 672}, + {"sha384", GCRY_MD_SHA384, 673}, + {"sha512", GCRY_MD_SHA512, 674}, +}; + +static bool nametodigest(const char *name, int *algo) { + int i; + + for(i = 0; i < sizeof digesttable / sizeof *digesttable; i++) { + if(digesttable[i].name && !strcasecmp(name, digesttable[i].name)) { + *algo = digesttable[i].algo; + return true; + } + } + + return false; +} + +static bool nidtodigest(int nid, int *algo) { + int i; + + for(i = 0; i < sizeof digesttable / sizeof *digesttable; i++) { + if(nid == digesttable[i].nid) { + *algo = digesttable[i].algo; + return true; + } + } + + return false; +} + +static bool digesttonid(int algo, int *nid) { + int i; + + for(i = 0; i < sizeof digesttable / sizeof *digesttable; i++) { + if(algo == digesttable[i].algo) { + *nid = digesttable[i].nid; + return true; + } + } + + return false; +} + +static bool digest_open(digest_t *digest, int algo, int maclength) { + if(!digesttonid(algo, &digest->nid)) { + logger(LOG_DEBUG, "Digest %d has no corresponding nid!", algo); + return false; + } + + unsigned int len = gcry_md_get_algo_dlen(algo); + + if(maclength > len || maclength < 0) + digest->maclength = len; + else + digest->maclength = maclength; + + digest->algo = algo; + digest->hmac = NULL; + + return true; +} + +bool digest_open_by_name(digest_t *digest, const char *name, int maclength) { + int algo; + + if(!nametodigest(name, &algo)) { + logger(LOG_DEBUG, "Unknown digest name '%s'!", name); + return false; + } + + return digest_open(digest, algo, maclength); +} + +bool digest_open_by_nid(digest_t *digest, int nid, int maclength) { + int algo; + + if(!nidtodigest(nid, &algo)) { + logger(LOG_DEBUG, "Unknown digest ID %d!", nid); + return false; + } + + return digest_open(digest, algo, maclength); +} + +bool digest_open_sha1(digest_t *digest, int maclength) { + return digest_open(digest, GCRY_MD_SHA1, maclength); +} + +void digest_close(digest_t *digest) { + if(digest->hmac) + gcry_md_close(digest->hmac); + digest->hmac = NULL; +} + +bool digest_set_key(digest_t *digest, const void *key, size_t len) { + if(!digest->hmac) + gcry_md_open(&digest->hmac, digest->algo, GCRY_MD_FLAG_HMAC); + if(!digest->hmac) + return false; + + return !gcry_md_setkey(digest->hmac, key, len); +} + +bool digest_create(digest_t *digest, const void *indata, size_t inlen, void *outdata) { + unsigned int len = gcry_md_get_algo_dlen(digest->algo); + + if(digest->hmac) { + char *tmpdata; + gcry_md_reset(digest->hmac); + gcry_md_write(digest->hmac, indata, inlen); + tmpdata = gcry_md_read(digest->hmac, digest->algo); + if(!tmpdata) + return false; + memcpy(outdata, tmpdata, digest->maclength); + } else { + char tmpdata[len]; + gcry_md_hash_buffer(digest->algo, tmpdata, indata, inlen); + memcpy(outdata, tmpdata, digest->maclength); + } + + return true; +} + +bool digest_verify(digest_t *digest, const void *indata, size_t inlen, const void *cmpdata) { + unsigned int len = digest->maclength; + char outdata[len]; + + return digest_create(digest, indata, inlen, outdata) && !memcmp(cmpdata, outdata, len); +} + +int digest_get_nid(const digest_t *digest) { + return digest->nid; +} + +size_t digest_length(const digest_t *digest) { + return digest->maclength; +} + +bool digest_active(const digest_t *digest) { + return digest->algo != GCRY_MD_NONE; +} diff --git a/src/gcrypt/digest.h b/src/gcrypt/digest.h new file mode 100644 index 0000000..1188496 --- /dev/null +++ b/src/gcrypt/digest.h @@ -0,0 +1,45 @@ +/* + digest.h -- header file digest.c + Copyright (C) 2007 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#ifndef __TINC_DIGEST_H__ +#define __TINC_DIGEST_H__ + +#include + +#define DIGEST_MAX_SIZE 64 + +typedef struct digest { + int algo; + int nid; + int maclength; + gcry_md_hd_t hmac; +} digest_t; + +extern bool digest_open_by_name(struct digest *, const char *name, int maclength); +extern bool digest_open_by_nid(struct digest *, int nid, int maclength); +extern bool digest_open_sha1(struct digest *, int maclength); +extern void digest_close(struct digest *); +extern bool digest_create(struct digest *, const void *indata, size_t inlen, void *outdata); +extern bool digest_verify(struct digest *, const void *indata, size_t inlen, const void *digestdata); +extern bool digest_set_key(struct digest *, const void *key, size_t len); +extern int digest_get_nid(const struct digest *); +extern size_t digest_length(const struct digest *); +extern bool digest_active(const struct digest *); + +#endif diff --git a/src/gcrypt/rsa.c b/src/gcrypt/rsa.c new file mode 100644 index 0000000..ceb1638 --- /dev/null +++ b/src/gcrypt/rsa.c @@ -0,0 +1,302 @@ +/* + rsa.c -- RSA key handling + Copyright (C) 2007 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "system.h" + +#include + +#include "logger.h" +#include "rsa.h" + +// Base64 decoding table + +static const uint8_t b64d[128] = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x3e, 0xff, 0xff, 0xff, 0x3f, + 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, + 0x3a, 0x3b, 0x3c, 0x3d, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, + 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, + 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, + 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, + 0x19, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, + 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, + 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, + 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, + 0x31, 0x32, 0x33, 0xff, 0xff, 0xff, + 0xff, 0xff +}; + +// PEM encoding/decoding functions + +static bool pem_decode(FILE *fp, const char *header, uint8_t *buf, size_t size, size_t *outsize) { + bool decode = false; + char line[1024]; + uint16_t word = 0; + int shift = 10; + size_t i, j = 0; + + while(!feof(fp)) { + if(!fgets(line, sizeof line, fp)) + return false; + + if(!decode && !strncmp(line, "-----BEGIN ", 11)) { + if(!strncmp(line + 11, header, strlen(header))) + decode = true; + continue; + } + + if(decode && !strncmp(line, "-----END", 8)) { + break; + } + + if(!decode) + continue; + + for(i = 0; line[i] >= ' '; i++) { + if((signed char)line[i] < 0 || b64d[(int)line[i]] == 0xff) + break; + word |= b64d[(int)line[i]] << shift; + shift -= 6; + if(shift <= 2) { + if(j > size) { + errno = ENOMEM; + return false; + } + + buf[j++] = word >> 8; + word <<= 8; + shift += 8; + } + } + } + + if(outsize) + *outsize = j; + return true; +} + + +// BER decoding functions + +static int ber_read_id(unsigned char **p, size_t *buflen) { + if(*buflen <= 0) + return -1; + + if((**p & 0x1f) == 0x1f) { + int id = 0; + bool more; + while(*buflen > 0) { + id <<= 7; + id |= **p & 0x7f; + more = *(*p)++ & 0x80; + (*buflen)--; + if(!more) + break; + } + return id; + } else { + (*buflen)--; + return *(*p)++ & 0x1f; + } +} + +static size_t ber_read_len(unsigned char **p, size_t *buflen) { + if(*buflen <= 0) + return -1; + + if(**p & 0x80) { + size_t result = 0; + int len = *(*p)++ & 0x7f; + (*buflen)--; + if(len > *buflen) + return 0; + + while(len--) { + result <<= 8; + result |= *(*p)++; + (*buflen)--; + } + + return result; + } else { + (*buflen)--; + return *(*p)++; + } +} + + +static bool ber_read_sequence(unsigned char **p, size_t *buflen, size_t *result) { + int tag = ber_read_id(p, buflen); + size_t len = ber_read_len(p, buflen); + + if(tag == 0x10) { + if(result) + *result = len; + return true; + } else { + return false; + } +} + +static bool ber_read_mpi(unsigned char **p, size_t *buflen, gcry_mpi_t *mpi) { + int tag = ber_read_id(p, buflen); + size_t len = ber_read_len(p, buflen); + gcry_error_t err = 0; + + if(tag != 0x02 || len > *buflen) + return false; + + if(mpi) + err = gcry_mpi_scan(mpi, GCRYMPI_FMT_USG, *p, len, NULL); + + *p += len; + *buflen -= len; + + return mpi ? !err : true; +} + +bool rsa_set_hex_public_key(rsa_t *rsa, char *n, char *e) { + gcry_error_t err = 0; + + err = gcry_mpi_scan(&rsa->n, GCRYMPI_FMT_HEX, n, 0, NULL) + ?: gcry_mpi_scan(&rsa->e, GCRYMPI_FMT_HEX, e, 0, NULL); + + if(err) { + logger(LOG_ERR, "Error while reading RSA public key: %s", gcry_strerror(errno)); + return false; + } + + return true; +} + +bool rsa_set_hex_private_key(rsa_t *rsa, char *n, char *e, char *d) { + gcry_error_t err = 0; + + err = gcry_mpi_scan(&rsa->n, GCRYMPI_FMT_HEX, n, 0, NULL) + ?: gcry_mpi_scan(&rsa->e, GCRYMPI_FMT_HEX, e, 0, NULL) + ?: gcry_mpi_scan(&rsa->d, GCRYMPI_FMT_HEX, d, 0, NULL); + + if(err) { + logger(LOG_ERR, "Error while reading RSA public key: %s", gcry_strerror(errno)); + return false; + } + + return true; +} + +// Read PEM RSA keys + +bool rsa_read_pem_public_key(rsa_t *rsa, FILE *fp) { + uint8_t derbuf[8096], *derp = derbuf; + size_t derlen; + + if(!pem_decode(fp, "RSA PUBLIC KEY", derbuf, sizeof derbuf, &derlen)) { + logger(LOG_ERR, "Unable to read RSA public key: %s", strerror(errno)); + return NULL; + } + + if(!ber_read_sequence(&derp, &derlen, NULL) + || !ber_read_mpi(&derp, &derlen, &rsa->n) + || !ber_read_mpi(&derp, &derlen, &rsa->e) + || derlen) { + logger(LOG_ERR, "Error while decoding RSA public key"); + return NULL; + } + + return true; +} + +bool rsa_read_pem_private_key(rsa_t *rsa, FILE *fp) { + uint8_t derbuf[8096], *derp = derbuf; + size_t derlen; + + if(!pem_decode(fp, "RSA PRIVATE KEY", derbuf, sizeof derbuf, &derlen)) { + logger(LOG_ERR, "Unable to read RSA private key: %s", strerror(errno)); + return NULL; + } + + if(!ber_read_sequence(&derp, &derlen, NULL) + || !ber_read_mpi(&derp, &derlen, NULL) + || !ber_read_mpi(&derp, &derlen, &rsa->n) + || !ber_read_mpi(&derp, &derlen, &rsa->e) + || !ber_read_mpi(&derp, &derlen, &rsa->d) + || !ber_read_mpi(&derp, &derlen, NULL) // p + || !ber_read_mpi(&derp, &derlen, NULL) // q + || !ber_read_mpi(&derp, &derlen, NULL) + || !ber_read_mpi(&derp, &derlen, NULL) + || !ber_read_mpi(&derp, &derlen, NULL) // u + || derlen) { + logger(LOG_ERR, "Error while decoding RSA private key"); + return NULL; + } + + return true; +} + +size_t rsa_size(rsa_t *rsa) { + return (gcry_mpi_get_nbits(rsa->n) + 7) / 8; +} + +/* Well, libgcrypt has functions to handle RSA keys, but they suck. + * So we just use libgcrypt's mpi functions, and do the math ourselves. + */ + +// TODO: get rid of this macro, properly clean up gcry_ structures after use +#define check(foo) { gcry_error_t err = (foo); if(err) {logger(LOG_ERR, "gcrypt error %s/%s at %s:%d", gcry_strsource(err), gcry_strerror(err), __FILE__, __LINE__); return false; }} + +bool rsa_public_encrypt(rsa_t *rsa, void *in, size_t len, void *out) { + gcry_mpi_t inmpi; + check(gcry_mpi_scan(&inmpi, GCRYMPI_FMT_USG, in, len, NULL)); + + gcry_mpi_t outmpi = gcry_mpi_new(len * 8); + gcry_mpi_powm(outmpi, inmpi, rsa->e, rsa->n); + + int pad = len - (gcry_mpi_get_nbits(outmpi) + 7) / 8; + while(pad--) + *(char *)out++ = 0; + + check(gcry_mpi_print(GCRYMPI_FMT_USG, out,len, NULL, outmpi)); + + return true; +} + +bool rsa_private_decrypt(rsa_t *rsa, void *in, size_t len, void *out) { + gcry_mpi_t inmpi; + check(gcry_mpi_scan(&inmpi, GCRYMPI_FMT_USG, in, len, NULL)); + + gcry_mpi_t outmpi = gcry_mpi_new(len * 8); + gcry_mpi_powm(outmpi, inmpi, rsa->d, rsa->n); + + int pad = len - (gcry_mpi_get_nbits(outmpi) + 7) / 8; + while(pad--) + *(char *)out++ = 0; + + check(gcry_mpi_print(GCRYMPI_FMT_USG, out,len, NULL, outmpi)); + + return true; +} diff --git a/src/gcrypt/rsa.h b/src/gcrypt/rsa.h new file mode 100644 index 0000000..143f015 --- /dev/null +++ b/src/gcrypt/rsa.h @@ -0,0 +1,39 @@ +/* + rsa.h -- RSA key handling + Copyright (C) 2007 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#ifndef __TINC_RSA_H__ +#define __TINC_RSA_H__ + +#include + +typedef struct rsa { + gcry_mpi_t n; + gcry_mpi_t e; + gcry_mpi_t d; +} rsa_t; + +extern bool rsa_set_hex_public_key(rsa_t *rsa, char *n, char *e); +extern bool rsa_set_hex_private_key(rsa_t *rsa, char *n, char *e, char *d); +extern bool rsa_read_pem_public_key(rsa_t *rsa, FILE *fp); +extern bool rsa_read_pem_private_key(rsa_t *rsa, FILE *fp); +extern size_t rsa_size(rsa_t *rsa); +extern bool rsa_public_encrypt(rsa_t *rsa, void *in, size_t len, void *out); +extern bool rsa_private_decrypt(rsa_t *rsa, void *in, size_t len, void *out); + +#endif diff --git a/src/gcrypt/rsagen.c b/src/gcrypt/rsagen.c new file mode 100644 index 0000000..7d37d19 --- /dev/null +++ b/src/gcrypt/rsagen.c @@ -0,0 +1,220 @@ +/* + rsagen.c -- RSA key generation and export + Copyright (C) 2008 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "system.h" + +#include + +#include "rsagen.h" + +#if 0 +// Base64 encoding table + +static const char b64e[64] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + +// PEM encoding + +static bool pem_encode(FILE *fp, const char *header, uint8_t *buf, size_t size) { + bool decode = false; + char line[1024]; + uint32_t word = 0; + int shift = 0; + size_t i, j = 0; + + fprintf(fp, "-----BEGIN %s-----\n", header); + + for(i = 0; i < size; i += 3) { + if(i <= size - 3) { + word = buf[i] << 16 | buf[i + 1] << 8 | buf[i + 2]; + } else { + word = buf[i] << 16; + if(i == size - 2) + word |= buf[i + 1] << 8; + } + + line[j++] = b64e[(word >> 18) ]; + line[j++] = b64e[(word >> 12) & 0x3f]; + line[j++] = b64e[(word >> 6) & 0x3f]; + line[j++] = b64e[(word ) & 0x3f]; + + if(j >= 64) { + line[j++] = '\n'; + line[j] = 0; + fputs(line, fp); + j = 0; + } + } + + if(size % 3 > 0) { + if(size % 3 > 1) + line[j++] = '='; + line[j++] = '='; + } + + if(j) { + line[j++] = '\n'; + line[j] = 0; + fputs(line, fp); + } + + fprintf(fp, "-----END %s-----\n", header); + + return true; +} + + +// BER encoding functions + +static bool ber_write_id(uint8_t **p, size_t *buflen, int id) { + if(*buflen <= 0) + return false; + + if(id >= 0x1f) { + while(id) { + if(*buflen <= 0) + return false; + + (*buflen)--; + **p = id & 0x7f; + id >>= 7; + if(id) + **p |= 0x80; + (*p)++; + } + } else { + (*buflen)--; + *(*p)++ = id; + } + + return true; +} + +static bool ber_write_len(uint8_t **p, size_t *buflen, size_t len) { + do { + if(*buflen <= 0) + return false; + + (*buflen)--; + **p = len & 0x7f; + len >>= 7; + if(len) + **p |= 0x80; + (*p)++; + } while(len); + + return true; +} + +static bool ber_write_sequence(uint8_t **p, size_t *buflen, uint8_t *seqbuf, size_t seqlen) { + if(!ber_write_id(p, buflen, 0x10) || !ber_write_len(p, buflen, seqlen) || *buflen < seqlen) + return false; + + memcpy(*p, seqbuf, seqlen); + *p += seqlen; + *buflen -= seqlen; + + return true; +} + +static bool ber_write_mpi(uint8_t **p, size_t *buflen, gcry_mpi_t mpi) { + uint8_t tmpbuf[1024]; + size_t tmplen = sizeof tmpbuf; + gcry_error_t err; + + err = gcry_mpi_aprint(GCRYMPI_FMT_USG, &tmpbuf, &tmplen, mpi); + if(err) + return false; + + if(!ber_write_id(p, buflen, 0x02) || !ber_write_len(p, buflen, tmplen) || *buflen < tmplen) + return false; + + memcpy(*p, tmpbuf, tmplen); + *p += tmplen; + *buflen -= tmplen; + + return true; +} + +// Write PEM RSA keys + +bool rsa_write_pem_public_key(rsa_t *rsa, FILE *fp) { + uint8_t derbuf1[8096]; + uint8_t derbuf2[8096]; + uint8_t *derp1 = derbuf1; + uint8_t *derp2 = derbuf2; + size_t derlen1 = sizeof derbuf1; + size_t derlen2 = sizeof derbuf2; + + if(!ber_write_mpi(&derp1, &derlen1, &rsa->n) + || !ber_write_mpi(&derp1, &derlen1, &rsa->e) + || !ber_write_sequence(&derp2, &derlen2, derbuf1, derlen1)) { + logger(LOG_ERR, "Error while encoding RSA public key"); + return false; + } + + if(!pem_encode(fp, "RSA PUBLIC KEY", derbuf2, derlen2)) { + logger(LOG_ERR, "Unable to write RSA public key: %s", strerror(errno)); + return false; + } + + return true; +} + +bool rsa_write_pem_private_key(rsa_t *rsa, FILE *fp) { + uint8_t derbuf1[8096]; + uint8_t derbuf2[8096]; + uint8_t *derp1 = derbuf1; + uint8_t *derp2 = derbuf2; + size_t derlen1 = sizeof derbuf1; + size_t derlen2 = sizeof derbuf2; + + if(!ber_write_mpi(&derp1, &derlen1, &bits) + || ber_write_mpi(&derp1, &derlen1, &rsa->n) // modulus + || ber_write_mpi(&derp1, &derlen1, &rsa->e) // public exponent + || ber_write_mpi(&derp1, &derlen1, &rsa->d) // private exponent + || ber_write_mpi(&derp1, &derlen1, &p) + || ber_write_mpi(&derp1, &derlen1, &q) + || ber_write_mpi(&derp1, &derlen1, &exp1) + || ber_write_mpi(&derp1, &derlen1, &exp2) + || ber_write_mpi(&derp1, &derlen1, &coeff)) + logger(LOG_ERR, "Error while encoding RSA private key"); + return false; + } + + if(!pem_encode(fp, "RSA PRIVATE KEY", derbuf2, derlen2)) { + logger(LOG_ERR, "Unable to write RSA private key: %s", strerror(errno)); + return false; + } + + return true; +} +#endif + +bool rsa_write_pem_public_key(rsa_t *rsa, FILE *fp) { + return false; +} + +bool rsa_write_pem_private_key(rsa_t *rsa, FILE *fp) { + return false; +} + +bool rsa_generate(rsa_t *rsa, size_t bits, unsigned long exponent) { + fprintf(stderr, "Generating RSA keys with libgcrypt not implemented yet\n"); + return false; +} diff --git a/src/gcrypt/rsagen.h b/src/gcrypt/rsagen.h new file mode 100644 index 0000000..422d156 --- /dev/null +++ b/src/gcrypt/rsagen.h @@ -0,0 +1,29 @@ +/* + rsagen.h -- RSA key generation and export + Copyright (C) 2008 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#ifndef __TINC_RSAGEN_H__ +#define __TINC_RSAGEN_H__ + +#include "rsa.h" + +extern bool rsa_generate(rsa_t *rsa, size_t bits, unsigned long exponent); +extern bool rsa_write_pem_public_key(rsa_t *rsa, FILE *fp); +extern bool rsa_write_pem_private_key(rsa_t *rsa, FILE *fp); + +#endif diff --git a/src/getopt.c b/src/getopt.c index 741c7f2..a6782ed 100644 --- a/src/getopt.c +++ b/src/getopt.c @@ -4,7 +4,7 @@ before changing it! Copyright (C) 1987, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97 - Free Software Foundation, Inc. + Free Software Foundation, Inc. NOTE: The canonical source of this file is maintained with the GNU C Library. Bugs can be reported to bug-glibc@prep.ai.mit.edu. @@ -31,7 +31,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #endif #ifdef HAVE_CONFIG_H -#include "../config.h" +#include #endif #if !defined (__STDC__) || !__STDC__ @@ -69,12 +69,12 @@ with this program; if not, write to the Free Software Foundation, Inc., /* This needs to come after some library #include to get __GNU_LIBRARY__ defined. */ -#ifdef __GNU_LIBRARY__ +#ifdef __GNU_LIBRARY__ /* Don't include stdlib.h for non-GNU C libraries because some of them contain conflicting prototypes for getopt. */ #include #include -#endif /* GNU C library. */ +#endif /* GNU C library. */ #ifdef VMS #include @@ -132,7 +132,7 @@ int optind = 1; causes problems with re-calling getopt as programs generally don't know that. */ -int getopt_initialized = 0; +int __getopt_initialized = 0; /* The next char to be scanned in the option-element in which the last option character we returned was found. @@ -183,41 +183,40 @@ int optopt = '?'; of the value of `ordering'. In the case of RETURN_IN_ORDER, only `--' can cause `getopt' to return -1 with `optind' != ARGC. */ -static enum { - REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER +static enum +{ + REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER } ordering; /* Value of POSIXLY_CORRECT environment variable. */ static char *posixly_correct; -#ifdef __GNU_LIBRARY__ +#ifdef __GNU_LIBRARY__ /* We want to avoid inclusion of string.h with non-GNU libraries because there are many ways it can cause trouble. On some systems, it contains special magic macros that don't work in GCC. */ #include -#define my_index strchr +#define my_index strchr #else /* Avoid depending on library functions or files whose names are inconsistent. */ -char *getenv(); +char *getenv (); static char * -my_index(str, chr) -const char *str; -int chr; +my_index (str, chr) + const char *str; + int chr; { - while(*str) { - if(*str == chr) { - return (char *) str; - } - - str++; - } - - return 0; + while (*str) + { + if (*str == chr) + return (char *) str; + str++; + } + return 0; } /* If using GCC, we can safely declare strlen this way. @@ -228,7 +227,7 @@ int chr; #if !defined (__STDC__) || !__STDC__ /* gcc with -traditional declares the built-in strlen to return int, and has done so at least since version 2.4.5. -- rms. */ -extern int strlen(const char *); +extern int strlen (const char *); #endif /* not __STDC__ */ #endif /* __GNUC__ */ @@ -248,7 +247,7 @@ static int last_nonopt; indicating ARGV elements that should not be considered arguments. */ /* Defined in getopt_init.c */ -extern char *getopt_nonoption_flags; +extern char *__getopt_nonoption_flags; static int nonoption_flags_max_len; static int nonoption_flags_len; @@ -256,31 +255,32 @@ static int nonoption_flags_len; static int original_argc; static char *const *original_argv; -extern pid_t libc_pid; +extern pid_t __libc_pid; /* Make sure the environment variable bash 2.0 puts in the environment is valid for the getopt call we must make sure that the ARGV passed to getopt is that one passed to the process. */ static void -__attribute__((__unused__)) -store_args_and_env(int argc, char *const *argv) { - /* XXX This is no good solution. We should rather copy the args so - that we can compare them later. But we must not use malloc(3). */ - original_argc = argc; - original_argv = argv; +__attribute__ ((__unused__)) +store_args_and_env (int argc, char *const *argv) +{ + /* XXX This is no good solution. We should rather copy the args so + that we can compare them later. But we must not use malloc(3). */ + original_argc = argc; + original_argv = argv; } -text_set_element(libc_subinit, store_args_and_env); +text_set_element (__libc_subinit, store_args_and_env); # define SWAP_FLAGS(ch1, ch2) \ - if (nonoption_flags_len > 0) \ - { \ - char tmp = getopt_nonoption_flags[ch1]; \ - getopt_nonoption_flags[ch1] = getopt_nonoption_flags[ch2]; \ - getopt_nonoption_flags[ch2] = tmp; \ - } -#else /* !_LIBC */ + if (nonoption_flags_len > 0) \ + { \ + char __tmp = __getopt_nonoption_flags[ch1]; \ + __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2]; \ + __getopt_nonoption_flags[ch2] = __tmp; \ + } +#else /* !_LIBC */ # define SWAP_FLAGS(ch1, ch2) -#endif /* _LIBC */ +#endif /* _LIBC */ /* Exchange two adjacent subsequences of ARGV. One subsequence is elements [first_nonopt,last_nonopt) @@ -292,158 +292,161 @@ text_set_element(libc_subinit, store_args_and_env); the new indices of the non-options in ARGV after they are moved. */ #if defined (__STDC__) && __STDC__ -static void exchange(char **); +static void exchange (char **); #endif static void -exchange(argv) -char **argv; +exchange (argv) + char **argv; { - int bottom = first_nonopt; - int middle = last_nonopt; - int top = optind; - char *tem; + int bottom = first_nonopt; + int middle = last_nonopt; + int top = optind; + char *tem; - /* Exchange the shorter segment with the far end of the longer segment. - That puts the shorter segment into the right place. - It leaves the longer segment in the right place overall, - but it consists of two parts that need to be swapped next. */ + /* Exchange the shorter segment with the far end of the longer segment. + That puts the shorter segment into the right place. + It leaves the longer segment in the right place overall, + but it consists of two parts that need to be swapped next. */ #ifdef _LIBC - - /* First make sure the handling of the `getopt_nonoption_flags' - string can work normally. Our top argument must be in the range - of the string. */ - if(nonoption_flags_len > 0 && top >= nonoption_flags_max_len) { - /* We must extend the array. The user plays games with us and - presents new arguments. */ - char *new_str = malloc(top + 1); - - if(new_str == NULL) { - nonoption_flags_len = nonoption_flags_max_len = 0; - } else { - memcpy(new_str, getopt_nonoption_flags, nonoption_flags_max_len); - memset(&new_str[nonoption_flags_max_len], '\0', - top + 1 - nonoption_flags_max_len); - nonoption_flags_max_len = top + 1; - getopt_nonoption_flags = new_str; - } + /* First make sure the handling of the `__getopt_nonoption_flags' + string can work normally. Our top argument must be in the range + of the string. */ + if (nonoption_flags_len > 0 && top >= nonoption_flags_max_len) + { + /* We must extend the array. The user plays games with us and + presents new arguments. */ + char *new_str = malloc (top + 1); + if (new_str == NULL) + nonoption_flags_len = nonoption_flags_max_len = 0; + else + { + memcpy (new_str, __getopt_nonoption_flags, nonoption_flags_max_len); + memset (&new_str[nonoption_flags_max_len], '\0', + top + 1 - nonoption_flags_max_len); + nonoption_flags_max_len = top + 1; + __getopt_nonoption_flags = new_str; } - + } #endif - while(top > middle && middle > bottom) { - if(top - middle > middle - bottom) { - /* Bottom segment is the short one. */ - int len = middle - bottom; - register int i; + while (top > middle && middle > bottom) + { + if (top - middle > middle - bottom) + { + /* Bottom segment is the short one. */ + int len = middle - bottom; + register int i; - /* Swap it with the top part of the top segment. */ - for(i = 0; i < len; i++) { - tem = argv[bottom + i]; - argv[bottom + i] = argv[top - (middle - bottom) + i]; - argv[top - (middle - bottom) + i] = tem; - SWAP_FLAGS(bottom + i, top - (middle - bottom) + i); - } - - /* Exclude the moved bottom segment from further swapping. */ - top -= len; - } else { - /* Top segment is the short one. */ - int len = top - middle; - register int i; - - /* Swap it with the bottom part of the bottom segment. */ - for(i = 0; i < len; i++) { - tem = argv[bottom + i]; - argv[bottom + i] = argv[middle + i]; - argv[middle + i] = tem; - SWAP_FLAGS(bottom + i, middle + i); - } - - /* Exclude the moved top segment from further swapping. */ - bottom += len; - } + /* Swap it with the top part of the top segment. */ + for (i = 0; i < len; i++) + { + tem = argv[bottom + i]; + argv[bottom + i] = argv[top - (middle - bottom) + i]; + argv[top - (middle - bottom) + i] = tem; + SWAP_FLAGS (bottom + i, top - (middle - bottom) + i); + } + /* Exclude the moved bottom segment from further swapping. */ + top -= len; } + else + { + /* Top segment is the short one. */ + int len = top - middle; + register int i; - /* Update records for the slots the non-options now occupy. */ + /* Swap it with the bottom part of the bottom segment. */ + for (i = 0; i < len; i++) + { + tem = argv[bottom + i]; + argv[bottom + i] = argv[middle + i]; + argv[middle + i] = tem; + SWAP_FLAGS (bottom + i, middle + i); + } + /* Exclude the moved top segment from further swapping. */ + bottom += len; + } + } - first_nonopt += (optind - last_nonopt); - last_nonopt = optind; + /* Update records for the slots the non-options now occupy. */ + + first_nonopt += (optind - last_nonopt); + last_nonopt = optind; } /* Initialize the internal data when the first call is made. */ #if defined (__STDC__) && __STDC__ -static const char *_getopt_initialize(int, char *const *, const char *); +static const char *_getopt_initialize (int, char *const *, const char *); #endif static const char * -_getopt_initialize(argc, argv, optstring) -int argc; -char *const *argv; -const char *optstring; +_getopt_initialize (argc, argv, optstring) + int argc; + char *const *argv; + const char *optstring; { - /* Start processing options with ARGV-element 1 (since ARGV-element 0 - is the program name); the sequence of previously skipped - non-option ARGV-elements is empty. */ + /* Start processing options with ARGV-element 1 (since ARGV-element 0 + is the program name); the sequence of previously skipped + non-option ARGV-elements is empty. */ - first_nonopt = last_nonopt = optind; + first_nonopt = last_nonopt = optind; - nextchar = NULL; + nextchar = NULL; - posixly_correct = getenv("POSIXLY_CORRECT"); + posixly_correct = getenv ("POSIXLY_CORRECT"); - /* Determine how to handle the ordering of options and nonoptions. */ + /* Determine how to handle the ordering of options and nonoptions. */ - if(optstring[0] == '-') { - ordering = RETURN_IN_ORDER; - ++optstring; - } else if(optstring[0] == '+') { - ordering = REQUIRE_ORDER; - ++optstring; - } else if(posixly_correct != NULL) { - ordering = REQUIRE_ORDER; - } else { - ordering = PERMUTE; - } + if (optstring[0] == '-') + { + ordering = RETURN_IN_ORDER; + ++optstring; + } + else if (optstring[0] == '+') + { + ordering = REQUIRE_ORDER; + ++optstring; + } + else if (posixly_correct != NULL) + ordering = REQUIRE_ORDER; + else + ordering = PERMUTE; #ifdef _LIBC - - if(posixly_correct == NULL - && argc == original_argc && argv == original_argv) { - if(nonoption_flags_max_len == 0) { - if(getopt_nonoption_flags == NULL - || getopt_nonoption_flags[0] == '\0') { - nonoption_flags_max_len = -1; - } else { - const char *orig_str = getopt_nonoption_flags; - int len = nonoption_flags_max_len = strlen(orig_str); - - if(nonoption_flags_max_len < argc) { - nonoption_flags_max_len = argc; - } - - getopt_nonoption_flags = - (char *) malloc(nonoption_flags_max_len); - - if(getopt_nonoption_flags == NULL) { - nonoption_flags_max_len = -1; - } else { - memcpy(getopt_nonoption_flags, orig_str, len); - memset(&getopt_nonoption_flags[len], '\0', - nonoption_flags_max_len - len); - } - } + if (posixly_correct == NULL + && argc == original_argc && argv == original_argv) + { + if (nonoption_flags_max_len == 0) + { + if (__getopt_nonoption_flags == NULL + || __getopt_nonoption_flags[0] == '\0') + nonoption_flags_max_len = -1; + else + { + const char *orig_str = __getopt_nonoption_flags; + int len = nonoption_flags_max_len = strlen (orig_str); + if (nonoption_flags_max_len < argc) + nonoption_flags_max_len = argc; + __getopt_nonoption_flags = + (char *) malloc (nonoption_flags_max_len); + if (__getopt_nonoption_flags == NULL) + nonoption_flags_max_len = -1; + else + { + memcpy (__getopt_nonoption_flags, orig_str, len); + memset (&__getopt_nonoption_flags[len], '\0', + nonoption_flags_max_len - len); } - - nonoption_flags_len = nonoption_flags_max_len; - } else { - nonoption_flags_len = 0; + } } - + nonoption_flags_len = nonoption_flags_max_len; + } + else + nonoption_flags_len = 0; #endif - return optstring; + return optstring; } /* Scan elements of ARGV (whose length is ARGC) for option characters @@ -503,476 +506,474 @@ const char *optstring; long-named options. */ int -_getopt_internal(argc, argv, optstring, longopts, longind, long_only) -int argc; -char *const *argv; -const char *optstring; -const struct option *longopts; -int *longind; -int long_only; +_getopt_internal (argc, argv, optstring, longopts, longind, long_only) + int argc; + char *const *argv; + const char *optstring; + const struct option *longopts; + int *longind; + int long_only; { - optarg = NULL; + optarg = NULL; - if(optind == 0 || !getopt_initialized) { - if(optind == 0) { - optind = 1; /* Don't scan ARGV[0], the program name. */ - } + if (optind == 0 || !__getopt_initialized) + { + if (optind == 0) + optind = 1; /* Don't scan ARGV[0], the program name. */ + optstring = _getopt_initialize (argc, argv, optstring); + __getopt_initialized = 1; + } - optstring = _getopt_initialize(argc, argv, optstring); - getopt_initialized = 1; - } - - /* Test whether ARGV[optind] points to a non-option argument. - Either it does not have option syntax, or there is an environment flag - from the shell indicating it is not an option. The later information - is only used when the used in the GNU libc. */ + /* Test whether ARGV[optind] points to a non-option argument. + Either it does not have option syntax, or there is an environment flag + from the shell indicating it is not an option. The later information + is only used when the used in the GNU libc. */ #ifdef _LIBC -#define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0' \ - || (optind < nonoption_flags_len \ - && getopt_nonoption_flags[optind] == '1')) +#define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0' \ + || (optind < nonoption_flags_len \ + && __getopt_nonoption_flags[optind] == '1')) #else #define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0') #endif - if(nextchar == NULL || *nextchar == '\0') { - /* Advance to the next ARGV-element. */ + if (nextchar == NULL || *nextchar == '\0') + { + /* Advance to the next ARGV-element. */ - /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been - moved back by the user (who may also have changed the arguments). */ - if(last_nonopt > optind) { - last_nonopt = optind; - } - - if(first_nonopt > optind) { - first_nonopt = optind; - } - - if(ordering == PERMUTE) { - /* If we have just processed some options following some non-options, - exchange them so that the options come first. */ - - if(first_nonopt != last_nonopt && last_nonopt != optind) { - exchange((char **) argv); - } else if(last_nonopt != optind) { - first_nonopt = optind; - } - - /* Skip any additional non-options - and extend the range of non-options previously skipped. */ - - while(optind < argc && NONOPTION_P) { - optind++; - } - - last_nonopt = optind; - } - - /* The special ARGV-element `--' means premature end of options. - Skip it like a null option, - then exchange with previous non-options as if it were an option, - then skip everything else like a non-option. */ - - if(optind != argc && !strcmp(argv[optind], "--")) { - optind++; - - if(first_nonopt != last_nonopt && last_nonopt != optind) { - exchange((char **) argv); - } else if(first_nonopt == last_nonopt) { - first_nonopt = optind; - } - - last_nonopt = argc; - - optind = argc; - } - - /* If we have done all the ARGV-elements, stop the scan - and back over any non-options that we skipped and permuted. */ - - if(optind == argc) { - /* Set the next-arg-index to point at the non-options - that we previously skipped, so the caller will digest them. */ - if(first_nonopt != last_nonopt) { - optind = first_nonopt; - } - - return -1; - } - - /* If we have come to a non-option and did not permute it, - either stop the scan or describe it to the caller and pass it by. */ - - if(NONOPTION_P) { - if(ordering == REQUIRE_ORDER) { - return -1; - } - - optarg = argv[optind++]; - return 1; - } - - /* We have found another option-ARGV-element. - Skip the initial punctuation. */ - - nextchar = (argv[optind] + 1 - + (longopts != NULL && argv[optind][1] == '-')); - } - - /* Decode the current option-ARGV-element. */ - - /* Check whether the ARGV-element is a long option. - - If long_only and the ARGV-element has the form "-f", where f is - a valid short option, don't consider it an abbreviated form of - a long option that starts with f. Otherwise there would be no - way to give the -f short option. - - On the other hand, if there's a long option "fubar" and - the ARGV-element is "-fu", do consider that an abbreviation of - the long option, just like "--fu", and not "-f" with arg "u". - - This distinction seems to be the most useful approach. */ - - if(longopts != NULL - && (argv[optind][1] == '-' - || (long_only && (argv[optind][2] || !my_index(optstring, argv[optind][1]))))) { - char *nameend; - const struct option *p; - const struct option *pfound = NULL; - int exact = 0; - int ambig = 0; - int indfound = -1; - int option_index; - - for(nameend = nextchar; *nameend && *nameend != '='; nameend++) - /* Do nothing. */ ; - - /* Test all long options for either exact match - or abbreviated matches. */ - for(p = longopts, option_index = 0; p->name; p++, option_index++) - if(!strncmp(p->name, nextchar, nameend - nextchar)) { - if((unsigned int)(nameend - nextchar) - == (unsigned int) strlen(p->name)) { - /* Exact match found. */ - pfound = p; - indfound = option_index; - exact = 1; - break; - } else if(pfound == NULL) { - /* First nonexact match found. */ - pfound = p; - indfound = option_index; - } else - /* Second or later nonexact match found. */ - { - ambig = 1; - } - } - - if(ambig && !exact) { - if(opterr) - fprintf(stderr, "%s: option `%s' is ambiguous\n", - argv[0], argv[optind]); - - nextchar += strlen(nextchar); - optind++; - optopt = 0; - return '?'; - } - - if(pfound != NULL) { - option_index = indfound; - optind++; - - if(*nameend) { - /* Don't test has_arg with >, because some C compilers don't - allow it to be used on enums. */ - if(pfound->has_arg) { - optarg = nameend + 1; - } else { - if(opterr) { - if(argv[optind - 1][1] == '-') - /* --option */ - fprintf(stderr, - "%s: option `--%s' doesn't allow an argument\n", - argv[0], pfound->name); - else - /* +option or -option */ - fprintf(stderr, - "%s: option `%c%s' doesn't allow an argument\n", - argv[0], argv[optind - 1][0], pfound->name); - } - - nextchar += strlen(nextchar); - - optopt = pfound->val; - return '?'; - } - } else if(pfound->has_arg == 1) { - if(optind < argc) { - optarg = argv[optind++]; - } else { - if(opterr) - fprintf(stderr, - "%s: option `%s' requires an argument\n", - argv[0], argv[optind - 1]); - - nextchar += strlen(nextchar); - optopt = pfound->val; - return optstring[0] == ':' ? ':' : '?'; - } - } - - nextchar += strlen(nextchar); - - if(longind != NULL) { - *longind = option_index; - } - - if(pfound->flag) { - *(pfound->flag) = pfound->val; - return 0; - } - - return pfound->val; - } - - /* Can't find it as a long option. If this is not getopt_long_only, - or the option starts with '--' or is not a valid short - option, then it's an error. - Otherwise interpret it as a short option. */ - if(!long_only || argv[optind][1] == '-' - || my_index(optstring, *nextchar) == NULL) { - if(opterr) { - if(argv[optind][1] == '-') - /* --option */ - fprintf(stderr, "%s: unrecognized option `--%s'\n", - argv[0], nextchar); - else - /* +option or -option */ - fprintf(stderr, "%s: unrecognized option `%c%s'\n", - argv[0], argv[optind][0], nextchar); - } - - nextchar = (char *) ""; - optind++; - optopt = 0; - return '?'; - } - } - - /* Look at and handle the next short option-character. */ + /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been + moved back by the user (who may also have changed the arguments). */ + if (last_nonopt > optind) + last_nonopt = optind; + if (first_nonopt > optind) + first_nonopt = optind; + if (ordering == PERMUTE) { - char c = *nextchar++; - char *temp = my_index(optstring, c); + /* If we have just processed some options following some non-options, + exchange them so that the options come first. */ - /* Increment `optind' when we start to process its last character. */ - if(*nextchar == '\0') { - ++optind; - } + if (first_nonopt != last_nonopt && last_nonopt != optind) + exchange ((char **) argv); + else if (last_nonopt != optind) + first_nonopt = optind; - if(temp == NULL || c == ':') { - if(opterr) { - if(posixly_correct) - /* 1003.2 specifies the format of this message. */ - fprintf(stderr, "%s: illegal option -- %c\n", - argv[0], c); - else - fprintf(stderr, "%s: invalid option -- %c\n", - argv[0], c); - } + /* Skip any additional non-options + and extend the range of non-options previously skipped. */ - optopt = c; - return '?'; - } - - /* Convenience. Treat POSIX -W foo same as long option --foo */ - if(temp[0] == 'W' && temp[1] == ';') { - char *nameend; - const struct option *p; - const struct option *pfound = NULL; - int exact = 0; - int ambig = 0; - int indfound = 0; - int option_index; - - /* This is an option that requires an argument. */ - if(*nextchar != '\0') { - optarg = nextchar; - /* If we end this ARGV-element by taking the rest as an arg, - we must advance to the next element now. */ - optind++; - } else if(optind == argc) { - if(opterr) { - /* 1003.2 specifies the format of this message. */ - fprintf(stderr, "%s: option requires an argument -- %c\n", - argv[0], c); - } - - optopt = c; - - if(optstring[0] == ':') { - c = ':'; - } else { - c = '?'; - } - - return c; - } else - /* We already incremented `optind' once; - increment it again when taking next ARGV-elt as argument. */ - { - optarg = argv[optind++]; - } - - /* optarg is now the argument, see if it's in the - table of longopts. */ - - for(nextchar = nameend = optarg; *nameend && *nameend != '='; nameend++) - /* Do nothing. */ ; - - /* Test all long options for either exact match - or abbreviated matches. */ - for(p = longopts, option_index = 0; p->name; p++, option_index++) - if(!strncmp(p->name, nextchar, nameend - nextchar)) { - if((unsigned int)(nameend - nextchar) == strlen(p->name)) { - /* Exact match found. */ - pfound = p; - indfound = option_index; - exact = 1; - break; - } else if(pfound == NULL) { - /* First nonexact match found. */ - pfound = p; - indfound = option_index; - } else - /* Second or later nonexact match found. */ - { - ambig = 1; - } - } - - if(ambig && !exact) { - if(opterr) - fprintf(stderr, "%s: option `-W %s' is ambiguous\n", - argv[0], argv[optind]); - - nextchar += strlen(nextchar); - optind++; - return '?'; - } - - if(pfound != NULL) { - option_index = indfound; - - if(*nameend) { - /* Don't test has_arg with >, because some C compilers don't - allow it to be used on enums. */ - if(pfound->has_arg) { - optarg = nameend + 1; - } else { - if(opterr) - fprintf(stderr, - "%s: option `-W %s' doesn't allow an argument\n", - argv[0], pfound->name); - - nextchar += strlen(nextchar); - return '?'; - } - } else if(pfound->has_arg == 1) { - if(optind < argc) { - optarg = argv[optind++]; - } else { - if(opterr) - fprintf(stderr, - "%s: option `%s' requires an argument\n", - argv[0], argv[optind - 1]); - - nextchar += strlen(nextchar); - return optstring[0] == ':' ? ':' : '?'; - } - } - - nextchar += strlen(nextchar); - - if(longind != NULL) { - *longind = option_index; - } - - if(pfound->flag) { - *(pfound->flag) = pfound->val; - return 0; - } - - return pfound->val; - } - - nextchar = NULL; - return 'W'; /* Let the application handle it. */ - } - - if(temp[1] == ':') { - if(temp[2] == ':') { - /* This is an option that accepts an argument optionally. */ - if(*nextchar != '\0') { - optarg = nextchar; - optind++; - } else { - optarg = NULL; - } - - nextchar = NULL; - } else { - /* This is an option that requires an argument. */ - if(*nextchar != '\0') { - optarg = nextchar; - /* If we end this ARGV-element by taking the rest as an arg, - we must advance to the next element now. */ - optind++; - } else if(optind == argc) { - if(opterr) { - /* 1003.2 specifies the format of this message. */ - fprintf(stderr, - "%s: option requires an argument -- %c\n", - argv[0], c); - } - - optopt = c; - - if(optstring[0] == ':') { - c = ':'; - } else { - c = '?'; - } - } else - /* We already incremented `optind' once; - increment it again when taking next ARGV-elt as argument. */ - { - optarg = argv[optind++]; - } - - nextchar = NULL; - } - } - - return c; + while (optind < argc && NONOPTION_P) + optind++; + last_nonopt = optind; } + + /* The special ARGV-element `--' means premature end of options. + Skip it like a null option, + then exchange with previous non-options as if it were an option, + then skip everything else like a non-option. */ + + if (optind != argc && !strcmp (argv[optind], "--")) + { + optind++; + + if (first_nonopt != last_nonopt && last_nonopt != optind) + exchange ((char **) argv); + else if (first_nonopt == last_nonopt) + first_nonopt = optind; + last_nonopt = argc; + + optind = argc; + } + + /* If we have done all the ARGV-elements, stop the scan + and back over any non-options that we skipped and permuted. */ + + if (optind == argc) + { + /* Set the next-arg-index to point at the non-options + that we previously skipped, so the caller will digest them. */ + if (first_nonopt != last_nonopt) + optind = first_nonopt; + return -1; + } + + /* If we have come to a non-option and did not permute it, + either stop the scan or describe it to the caller and pass it by. */ + + if (NONOPTION_P) + { + if (ordering == REQUIRE_ORDER) + return -1; + optarg = argv[optind++]; + return 1; + } + + /* We have found another option-ARGV-element. + Skip the initial punctuation. */ + + nextchar = (argv[optind] + 1 + + (longopts != NULL && argv[optind][1] == '-')); + } + + /* Decode the current option-ARGV-element. */ + + /* Check whether the ARGV-element is a long option. + + If long_only and the ARGV-element has the form "-f", where f is + a valid short option, don't consider it an abbreviated form of + a long option that starts with f. Otherwise there would be no + way to give the -f short option. + + On the other hand, if there's a long option "fubar" and + the ARGV-element is "-fu", do consider that an abbreviation of + the long option, just like "--fu", and not "-f" with arg "u". + + This distinction seems to be the most useful approach. */ + + if (longopts != NULL + && (argv[optind][1] == '-' + || (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1]))))) + { + char *nameend; + const struct option *p; + const struct option *pfound = NULL; + int exact = 0; + int ambig = 0; + int indfound = -1; + int option_index; + + for (nameend = nextchar; *nameend && *nameend != '='; nameend++) + /* Do nothing. */ ; + + /* Test all long options for either exact match + or abbreviated matches. */ + for (p = longopts, option_index = 0; p->name; p++, option_index++) + if (!strncmp (p->name, nextchar, nameend - nextchar)) + { + if ((unsigned int) (nameend - nextchar) + == (unsigned int) strlen (p->name)) + { + /* Exact match found. */ + pfound = p; + indfound = option_index; + exact = 1; + break; + } + else if (pfound == NULL) + { + /* First nonexact match found. */ + pfound = p; + indfound = option_index; + } + else + /* Second or later nonexact match found. */ + ambig = 1; + } + + if (ambig && !exact) + { + if (opterr) + fprintf (stderr, "%s: option `%s' is ambiguous\n", + argv[0], argv[optind]); + nextchar += strlen (nextchar); + optind++; + optopt = 0; + return '?'; + } + + if (pfound != NULL) + { + option_index = indfound; + optind++; + if (*nameend) + { + /* Don't test has_arg with >, because some C compilers don't + allow it to be used on enums. */ + if (pfound->has_arg) + optarg = nameend + 1; + else + { + if (opterr) + { + if (argv[optind - 1][1] == '-') + /* --option */ + fprintf (stderr, + "%s: option `--%s' doesn't allow an argument\n", + argv[0], pfound->name); + else + /* +option or -option */ + fprintf (stderr, + "%s: option `%c%s' doesn't allow an argument\n", + argv[0], argv[optind - 1][0], pfound->name); + } + + nextchar += strlen (nextchar); + + optopt = pfound->val; + return '?'; + } + } + else if (pfound->has_arg == 1) + { + if (optind < argc) + optarg = argv[optind++]; + else + { + if (opterr) + fprintf (stderr, + "%s: option `%s' requires an argument\n", + argv[0], argv[optind - 1]); + nextchar += strlen (nextchar); + optopt = pfound->val; + return optstring[0] == ':' ? ':' : '?'; + } + } + nextchar += strlen (nextchar); + if (longind != NULL) + *longind = option_index; + if (pfound->flag) + { + *(pfound->flag) = pfound->val; + return 0; + } + return pfound->val; + } + + /* Can't find it as a long option. If this is not getopt_long_only, + or the option starts with '--' or is not a valid short + option, then it's an error. + Otherwise interpret it as a short option. */ + if (!long_only || argv[optind][1] == '-' + || my_index (optstring, *nextchar) == NULL) + { + if (opterr) + { + if (argv[optind][1] == '-') + /* --option */ + fprintf (stderr, "%s: unrecognized option `--%s'\n", + argv[0], nextchar); + else + /* +option or -option */ + fprintf (stderr, "%s: unrecognized option `%c%s'\n", + argv[0], argv[optind][0], nextchar); + } + nextchar = (char *) ""; + optind++; + optopt = 0; + return '?'; + } + } + + /* Look at and handle the next short option-character. */ + + { + char c = *nextchar++; + char *temp = my_index (optstring, c); + + /* Increment `optind' when we start to process its last character. */ + if (*nextchar == '\0') + ++optind; + + if (temp == NULL || c == ':') + { + if (opterr) + { + if (posixly_correct) + /* 1003.2 specifies the format of this message. */ + fprintf (stderr, "%s: illegal option -- %c\n", + argv[0], c); + else + fprintf (stderr, "%s: invalid option -- %c\n", + argv[0], c); + } + optopt = c; + return '?'; + } + /* Convenience. Treat POSIX -W foo same as long option --foo */ + if (temp[0] == 'W' && temp[1] == ';') + { + char *nameend; + const struct option *p; + const struct option *pfound = NULL; + int exact = 0; + int ambig = 0; + int indfound = 0; + int option_index; + + /* This is an option that requires an argument. */ + if (*nextchar != '\0') + { + optarg = nextchar; + /* If we end this ARGV-element by taking the rest as an arg, + we must advance to the next element now. */ + optind++; + } + else if (optind == argc) + { + if (opterr) + { + /* 1003.2 specifies the format of this message. */ + fprintf (stderr, "%s: option requires an argument -- %c\n", + argv[0], c); + } + optopt = c; + if (optstring[0] == ':') + c = ':'; + else + c = '?'; + return c; + } + else + /* We already incremented `optind' once; + increment it again when taking next ARGV-elt as argument. */ + optarg = argv[optind++]; + + /* optarg is now the argument, see if it's in the + table of longopts. */ + + for (nextchar = nameend = optarg; *nameend && *nameend != '='; nameend++) + /* Do nothing. */ ; + + /* Test all long options for either exact match + or abbreviated matches. */ + for (p = longopts, option_index = 0; p->name; p++, option_index++) + if (!strncmp (p->name, nextchar, nameend - nextchar)) + { + if ((unsigned int) (nameend - nextchar) == strlen (p->name)) + { + /* Exact match found. */ + pfound = p; + indfound = option_index; + exact = 1; + break; + } + else if (pfound == NULL) + { + /* First nonexact match found. */ + pfound = p; + indfound = option_index; + } + else + /* Second or later nonexact match found. */ + ambig = 1; + } + if (ambig && !exact) + { + if (opterr) + fprintf (stderr, "%s: option `-W %s' is ambiguous\n", + argv[0], argv[optind]); + nextchar += strlen (nextchar); + optind++; + return '?'; + } + if (pfound != NULL) + { + option_index = indfound; + if (*nameend) + { + /* Don't test has_arg with >, because some C compilers don't + allow it to be used on enums. */ + if (pfound->has_arg) + optarg = nameend + 1; + else + { + if (opterr) + fprintf (stderr, + "%s: option `-W %s' doesn't allow an argument\n", + argv[0], pfound->name); + + nextchar += strlen (nextchar); + return '?'; + } + } + else if (pfound->has_arg == 1) + { + if (optind < argc) + optarg = argv[optind++]; + else + { + if (opterr) + fprintf (stderr, + "%s: option `%s' requires an argument\n", + argv[0], argv[optind - 1]); + nextchar += strlen (nextchar); + return optstring[0] == ':' ? ':' : '?'; + } + } + nextchar += strlen (nextchar); + if (longind != NULL) + *longind = option_index; + if (pfound->flag) + { + *(pfound->flag) = pfound->val; + return 0; + } + return pfound->val; + } + nextchar = NULL; + return 'W'; /* Let the application handle it. */ + } + if (temp[1] == ':') + { + if (temp[2] == ':') + { + /* This is an option that accepts an argument optionally. */ + if (*nextchar != '\0') + { + optarg = nextchar; + optind++; + } + else + optarg = NULL; + nextchar = NULL; + } + else + { + /* This is an option that requires an argument. */ + if (*nextchar != '\0') + { + optarg = nextchar; + /* If we end this ARGV-element by taking the rest as an arg, + we must advance to the next element now. */ + optind++; + } + else if (optind == argc) + { + if (opterr) + { + /* 1003.2 specifies the format of this message. */ + fprintf (stderr, + "%s: option requires an argument -- %c\n", + argv[0], c); + } + optopt = c; + if (optstring[0] == ':') + c = ':'; + else + c = '?'; + } + else + /* We already incremented `optind' once; + increment it again when taking next ARGV-elt as argument. */ + optarg = argv[optind++]; + nextchar = NULL; + } + } + return c; + } } int -getopt(argc, argv, optstring) -int argc; -char *const *argv; -const char *optstring; +getopt (argc, argv, optstring) + int argc; + char *const *argv; + const char *optstring; { - return _getopt_internal(argc, argv, optstring, - (const struct option *) 0, - (int *) 0, - 0); + return _getopt_internal (argc, argv, optstring, + (const struct option *) 0, + (int *) 0, + 0); } -#endif /* Not ELIDE_CODE. */ +#endif /* Not ELIDE_CODE. */ #ifdef TEST @@ -980,72 +981,68 @@ const char *optstring; the above definition of `getopt'. */ int -main(argc, argv) -int argc; -char **argv; +main (argc, argv) + int argc; + char **argv; { - int c; - int digit_optind = 0; + int c; + int digit_optind = 0; - while(1) { - int this_option_optind = optind ? optind : 1; + while (1) + { + int this_option_optind = optind ? optind : 1; - c = getopt(argc, argv, "abc:d:0123456789"); + c = getopt (argc, argv, "abc:d:0123456789"); + if (c == -1) + break; - if(c == -1) { - break; - } + switch (c) + { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + if (digit_optind != 0 && digit_optind != this_option_optind) + printf ("digits occur in two different argv-elements.\n"); + digit_optind = this_option_optind; + printf ("option %c\n", c); + break; - switch(c) { - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - if(digit_optind != 0 && digit_optind != this_option_optind) { - printf("digits occur in two different argv-elements.\n"); - } + case 'a': + printf ("option a\n"); + break; - digit_optind = this_option_optind; - printf("option %c\n", c); - break; + case 'b': + printf ("option b\n"); + break; - case 'a': - printf("option a\n"); - break; + case 'c': + printf ("option c with value `%s'\n", optarg); + break; - case 'b': - printf("option b\n"); - break; + case '?': + break; - case 'c': - printf("option c with value `%s'\n", optarg); - break; - - case '?': - break; - - default: - printf("?? getopt returned character code 0%o ??\n", c); - } + default: + printf ("?? getopt returned character code 0%o ??\n", c); } + } - if(optind < argc) { - printf("non-option ARGV-elements: "); + if (optind < argc) + { + printf ("non-option ARGV-elements: "); + while (optind < argc) + printf ("%s ", argv[optind++]); + printf ("\n"); + } - while(optind < argc) { - printf("%s ", argv[optind++]); - } - - printf("\n"); - } - - exit(0); + exit (0); } #endif /* TEST */ diff --git a/src/getopt.h b/src/getopt.h index ab1d40b..ddf6fdd 100644 --- a/src/getopt.h +++ b/src/getopt.h @@ -1,6 +1,3 @@ -#ifndef TINC_GETOPT_H -#define TINC_GETOPT_H - /* Declarations for getopt. Copyright (C) 1989,90,91,92,93,94,96,97 Free Software Foundation, Inc. @@ -22,111 +19,115 @@ with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#ifdef cplusplus +#ifndef _GETOPT_H +#define _GETOPT_H 1 + +#ifdef __cplusplus extern "C" { #endif - /* For communication from `getopt' to the caller. - When `getopt' finds an option that takes an argument, - the argument value is returned here. - Also, when `ordering' is RETURN_IN_ORDER, - each non-option ARGV-element is returned here. */ +/* For communication from `getopt' to the caller. + When `getopt' finds an option that takes an argument, + the argument value is returned here. + Also, when `ordering' is RETURN_IN_ORDER, + each non-option ARGV-element is returned here. */ - extern char *optarg; +extern char *optarg; - /* Index in ARGV of the next element to be scanned. - This is used for communication to and from the caller - and for communication between successive calls to `getopt'. +/* Index in ARGV of the next element to be scanned. + This is used for communication to and from the caller + and for communication between successive calls to `getopt'. - On entry to `getopt', zero means this is the first call; initialize. + On entry to `getopt', zero means this is the first call; initialize. - When `getopt' returns -1, this is the index of the first of the - non-option elements that the caller should itself scan. + When `getopt' returns -1, this is the index of the first of the + non-option elements that the caller should itself scan. - Otherwise, `optind' communicates from one call to the next - how much of ARGV has been scanned so far. */ + Otherwise, `optind' communicates from one call to the next + how much of ARGV has been scanned so far. */ - extern int optind; +extern int optind; - /* Callers store zero here to inhibit the error message `getopt' prints - for unrecognized options. */ +/* Callers store zero here to inhibit the error message `getopt' prints + for unrecognized options. */ - extern int opterr; +extern int opterr; - /* Set to an option character which was unrecognized. */ +/* Set to an option character which was unrecognized. */ - extern int optopt; +extern int optopt; - /* Describe the long-named options requested by the application. - The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector - of `struct option' terminated by an element containing a name which is - zero. +/* Describe the long-named options requested by the application. + The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector + of `struct option' terminated by an element containing a name which is + zero. - The field `has_arg' is: - no_argument (or 0) if the option does not take an argument, - required_argument (or 1) if the option requires an argument, - optional_argument (or 2) if the option takes an optional argument. + The field `has_arg' is: + no_argument (or 0) if the option does not take an argument, + required_argument (or 1) if the option requires an argument, + optional_argument (or 2) if the option takes an optional argument. - If the field `flag' is not NULL, it points to a variable that is set - to the value given in the field `val' when the option is found, but - left unchanged if the option is not found. + If the field `flag' is not NULL, it points to a variable that is set + to the value given in the field `val' when the option is found, but + left unchanged if the option is not found. - To have a long-named option do something other than set an `int' to - a compiled-in constant, such as set a value from `optarg', set the - option's `flag' field to zero and its `val' field to a nonzero - value (the equivalent single-letter option character, if there is - one). For long options that have a zero `flag' field, `getopt' - returns the contents of the `val' field. */ + To have a long-named option do something other than set an `int' to + a compiled-in constant, such as set a value from `optarg', set the + option's `flag' field to zero and its `val' field to a nonzero + value (the equivalent single-letter option character, if there is + one). For long options that have a zero `flag' field, `getopt' + returns the contents of the `val' field. */ - struct option { +struct option +{ #if defined (__STDC__) && __STDC__ - const char *name; + const char *name; #else - char *name; + char *name; #endif - /* has_arg can't be an enum because some compilers complain about - type mismatches in all the code that assumes it is an int. */ - int has_arg; - int *flag; - int val; - }; + /* has_arg can't be an enum because some compilers complain about + type mismatches in all the code that assumes it is an int. */ + int has_arg; + int *flag; + int val; +}; - /* Names for the values of the `has_arg' field of `struct option'. */ +/* Names for the values of the `has_arg' field of `struct option'. */ -#define no_argument 0 -#define required_argument 1 -#define optional_argument 2 +#define no_argument 0 +#define required_argument 1 +#define optional_argument 2 #if defined (__STDC__) && __STDC__ #ifdef __GNU_LIBRARY__ - /* Many other libraries have conflicting prototypes for getopt, with - differences in the consts, in stdlib.h. To avoid compilation - errors, only prototype getopt for the GNU C library. */ - extern int getopt(int argc, char *const *argv, const char *shortopts); +/* Many other libraries have conflicting prototypes for getopt, with + differences in the consts, in stdlib.h. To avoid compilation + errors, only prototype getopt for the GNU C library. */ +extern int getopt (int argc, char *const *argv, const char *shortopts); #else /* not __GNU_LIBRARY__ */ - extern int getopt(); +extern int getopt (); #endif /* __GNU_LIBRARY__ */ - extern int getopt_long(int argc, char *const *argv, const char *shortopts, - const struct option *longopts, int *longind); - extern int getopt_long_only(int argc, char *const *argv, - const char *shortopts, - const struct option *longopts, int *longind); +extern int getopt_long (int argc, char *const *argv, const char *shortopts, + const struct option *longopts, int *longind); +extern int getopt_long_only (int argc, char *const *argv, + const char *shortopts, + const struct option *longopts, int *longind); - /* Internal only. Users should not call this directly. */ - extern int _getopt_internal(int argc, char *const *argv, - const char *shortopts, - const struct option *longopts, int *longind, - int long_only); +/* Internal only. Users should not call this directly. */ +extern int _getopt_internal (int argc, char *const *argv, + const char *shortopts, + const struct option *longopts, int *longind, + int long_only); #else /* not __STDC__ */ - extern int getopt(); - extern int getopt_long(); - extern int getopt_long_only(); +extern int getopt (); +extern int getopt_long (); +extern int getopt_long_only (); - extern int _getopt_internal(); +extern int _getopt_internal (); #endif /* __STDC__ */ -#ifdef cplusplus +#ifdef __cplusplus } #endif -#endif +#endif /* _GETOPT_H */ diff --git a/src/getopt1.c b/src/getopt1.c index 3ccb150..86545f2 100644 --- a/src/getopt1.c +++ b/src/getopt1.c @@ -20,7 +20,7 @@ with this program; if not, write to the Free Software Foundation, Inc., */ #ifdef HAVE_CONFIG_H -#include "../config.h" +#include #endif #include "getopt.h" @@ -60,19 +60,19 @@ with this program; if not, write to the Free Software Foundation, Inc., #include #endif -#ifndef NULL +#ifndef NULL #define NULL 0 #endif int -getopt_long(argc, argv, options, long_options, opt_index) -int argc; -char *const *argv; -const char *options; -const struct option *long_options; -int *opt_index; +getopt_long (argc, argv, options, long_options, opt_index) + int argc; + char *const *argv; + const char *options; + const struct option *long_options; + int *opt_index; { - return _getopt_internal(argc, argv, options, long_options, opt_index, 0); + return _getopt_internal (argc, argv, options, long_options, opt_index, 0); } /* Like getopt_long, but '-' as well as '--' can indicate a long option. @@ -81,115 +81,109 @@ int *opt_index; instead. */ int -getopt_long_only(argc, argv, options, long_options, opt_index) -int argc; -char *const *argv; -const char *options; -const struct option *long_options; -int *opt_index; +getopt_long_only (argc, argv, options, long_options, opt_index) + int argc; + char *const *argv; + const char *options; + const struct option *long_options; + int *opt_index; { - return _getopt_internal(argc, argv, options, long_options, opt_index, 1); + return _getopt_internal (argc, argv, options, long_options, opt_index, 1); } -#endif /* Not ELIDE_CODE. */ +#endif /* Not ELIDE_CODE. */ #ifdef TEST #include int -main(argc, argv) -int argc; -char **argv; +main (argc, argv) + int argc; + char **argv; { - int c; - int digit_optind = 0; + int c; + int digit_optind = 0; - while(1) { - int this_option_optind = optind ? optind : 1; - int option_index = 0; - static struct option long_options[] = { - {"add", 1, 0, 0}, - {"append", 0, 0, 0}, - {"delete", 1, 0, 0}, - {"verbose", 0, 0, 0}, - {"create", 0, 0, 0}, - {"file", 1, 0, 0}, - {0, 0, 0, 0} - }; + while (1) + { + int this_option_optind = optind ? optind : 1; + int option_index = 0; + static struct option long_options[] = + { + {"add", 1, 0, 0}, + {"append", 0, 0, 0}, + {"delete", 1, 0, 0}, + {"verbose", 0, 0, 0}, + {"create", 0, 0, 0}, + {"file", 1, 0, 0}, + {0, 0, 0, 0} + }; - c = getopt_long(argc, argv, "abc:d:0123456789", - long_options, &option_index); + c = getopt_long (argc, argv, "abc:d:0123456789", + long_options, &option_index); + if (c == -1) + break; - if(c == -1) { - break; - } + switch (c) + { + case 0: + printf ("option %s", long_options[option_index].name); + if (optarg) + printf (" with arg %s", optarg); + printf ("\n"); + break; - switch(c) { - case 0: - printf("option %s", long_options[option_index].name); + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + if (digit_optind != 0 && digit_optind != this_option_optind) + printf ("digits occur in two different argv-elements.\n"); + digit_optind = this_option_optind; + printf ("option %c\n", c); + break; - if(optarg) { - printf(" with arg %s", optarg); - } + case 'a': + printf ("option a\n"); + break; - printf("\n"); - break; + case 'b': + printf ("option b\n"); + break; - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - if(digit_optind != 0 && digit_optind != this_option_optind) { - printf("digits occur in two different argv-elements.\n"); - } + case 'c': + printf ("option c with value `%s'\n", optarg); + break; - digit_optind = this_option_optind; - printf("option %c\n", c); - break; + case 'd': + printf ("option d with value `%s'\n", optarg); + break; - case 'a': - printf("option a\n"); - break; + case '?': + break; - case 'b': - printf("option b\n"); - break; - - case 'c': - printf("option c with value `%s'\n", optarg); - break; - - case 'd': - printf("option d with value `%s'\n", optarg); - break; - - case '?': - break; - - default: - printf("?? getopt returned character code 0%o ??\n", c); - } + default: + printf ("?? getopt returned character code 0%o ??\n", c); } + } - if(optind < argc) { - printf("non-option ARGV-elements: "); + if (optind < argc) + { + printf ("non-option ARGV-elements: "); + while (optind < argc) + printf ("%s ", argv[optind++]); + printf ("\n"); + } - while(optind < argc) { - printf("%s ", argv[optind++]); - } - - printf("\n"); - } - - exit(0); + exit (0); } #endif /* TEST */ diff --git a/src/graph.c b/src/graph.c index 3529d01..bb55dfd 100644 --- a/src/graph.c +++ b/src/graph.c @@ -1,6 +1,6 @@ /* graph.c -- graph algorithms - Copyright (C) 2001-2014 Guus Sliepen , + Copyright (C) 2001-2011 Guus Sliepen , 2001-2005 Ivo Timmermans This program is free software; you can redistribute it and/or modify @@ -44,8 +44,8 @@ #include "system.h" -#include "avl_tree.h" -#include "conf.h" +#include "splay_tree.h" +#include "config.h" #include "connection.h" #include "device.h" #include "edge.h" @@ -58,22 +58,18 @@ #include "subnet.h" #include "utils.h" #include "xalloc.h" - -static bool graph_changed = true; +#include "graph.h" /* Implementation of Kruskal's algorithm. - Running time: O(EN) + Running time: O(E) Please note that sorting on weight is already done by add_edge(). */ -static void mst_kruskal(void) { - avl_node_t *node, *next; +void mst_kruskal(void) { + splay_node_t *node, *next; edge_t *e; node_t *n; connection_t *c; - int nodes = 0; - int safe_edges = 0; - bool skipped; /* Clear MST status on connections */ @@ -82,12 +78,6 @@ static void mst_kruskal(void) { c->status.mst = false; } - /* Do we have something to do at all? */ - - if(!edge_weight_tree->head) { - return; - } - ifdebug(SCARY_THINGS) logger(LOG_DEBUG, "Running Kruskal's algorithm:"); /* Clear visited status on nodes */ @@ -95,73 +85,144 @@ static void mst_kruskal(void) { for(node = node_tree->head; node; node = node->next) { n = node->data; n->status.visited = false; - nodes++; - } - - /* Starting point */ - - for(node = edge_weight_tree->head; node; node = node->next) { - e = node->data; - - if(e->from->status.reachable) { - e->from->status.visited = true; - break; - } } /* Add safe edges */ - for(skipped = false, node = edge_weight_tree->head; node; node = next) { + for(node = edge_weight_tree->head; node; node = next) { next = node->next; e = node->data; - if(!e->reverse || e->from->status.visited == e->to->status.visited) { - skipped = true; + if(!e->reverse || (e->from->status.visited && e->to->status.visited)) continue; - } e->from->status.visited = true; e->to->status.visited = true; - if(e->connection) { + if(e->connection) e->connection->status.mst = true; - } - if(e->reverse->connection) { + if(e->reverse->connection) e->reverse->connection->status.mst = true; - } - - safe_edges++; ifdebug(SCARY_THINGS) logger(LOG_DEBUG, " Adding edge %s - %s weight %d", e->from->name, - e->to->name, e->weight); + e->to->name, e->weight); + } +} - if(skipped) { - skipped = false; - next = edge_weight_tree->head; - continue; +/* Implementation of Dijkstra's algorithm. + Running time: O(N^2) +*/ + +static void sssp_dijkstra(void) { + splay_node_t *node, *to; + edge_t *e; + node_t *n, *m; + list_t *todo_list; + list_node_t *lnode, *nnode; + bool indirect; + + todo_list = list_alloc(NULL); + + ifdebug(SCARY_THINGS) logger(LOG_DEBUG, "Running Dijkstra's algorithm:"); + + /* Clear visited status on nodes */ + + for(node = node_tree->head; node; node = node->next) { + n = node->data; + n->status.visited = false; + n->status.indirect = true; + n->distance = -1; + } + + /* Begin with myself */ + + myself->status.indirect = false; + myself->nexthop = myself; + myself->via = myself; + myself->distance = 0; + list_insert_head(todo_list, myself); + + /* Loop while todo_list is filled */ + + while(todo_list->head) { + n = NULL; + nnode = NULL; + + /* Select node from todo_list with smallest distance */ + + for(lnode = todo_list->head; lnode; lnode = lnode->next) { + m = lnode->data; + if(!n || m->status.indirect < n->status.indirect || m->distance < n->distance) { + n = m; + nnode = lnode; + } + } + + /* Mark this node as visited and remove it from the todo_list */ + + n->status.visited = true; + list_unlink_node(todo_list, nnode); + + /* Update distance of neighbours and add them to the todo_list */ + + for(to = n->edge_tree->head; to; to = to->next) { /* "to" is the edge connected to "from" */ + e = to->data; + + if(e->to->status.visited || !e->reverse) + continue; + + /* Situation: + + / + / + ----->(n)---e-->(e->to) + \ + \ + + Where e is an edge, (n) and (e->to) are nodes. + n->address is set to the e->address of the edge left of n to n. + We are currently examining the edge e right of n from n: + + - If edge e provides for better reachability of e->to, update e->to. + */ + + if(e->to->distance < 0) + list_insert_tail(todo_list, e->to); + + indirect = n->status.indirect || e->options & OPTION_INDIRECT || ((n != myself) && sockaddrcmp(&n->address, &e->reverse->address)); + + if(e->to->distance >= 0 && (!e->to->status.indirect || indirect) && e->to->distance <= n->distance + e->weight) + continue; + + e->to->distance = n->distance + e->weight; + e->to->status.indirect = indirect; + e->to->nexthop = (n->nexthop == myself) ? e->to : n->nexthop; + e->to->via = indirect ? n->via : e->to; + e->to->options = e->options; + + if(e->to->address.sa.sa_family == AF_UNSPEC && e->address.sa.sa_family != AF_UNKNOWN) + update_node_udp(e->to, &e->address); + + ifdebug(SCARY_THINGS) logger(LOG_DEBUG, " Updating edge %s - %s weight %d distance %d", e->from->name, + e->to->name, e->weight, e->to->distance); } } - ifdebug(SCARY_THINGS) logger(LOG_DEBUG, "Done, counted %d nodes and %d safe edges.", nodes, - safe_edges); + list_free(todo_list); } /* Implementation of a simple breadth-first search algorithm. Running time: O(E) */ -static void sssp_bfs(void) { - avl_node_t *node, *next, *to; +void sssp_bfs(void) { + splay_node_t *node, *to; edge_t *e; node_t *n; list_t *todo_list; list_node_t *from, *todonext; bool indirect; - char *name; - char *address, *port; - char *envp[8] = {NULL}; - int i; todo_list = list_alloc(NULL); @@ -178,29 +239,27 @@ static void sssp_bfs(void) { myself->status.visited = true; myself->status.indirect = false; myself->nexthop = myself; - myself->prevedge = NULL; myself->via = myself; list_insert_head(todo_list, myself); /* Loop while todo_list is filled */ - for(from = todo_list->head; from; from = todonext) { /* "from" is the node from which we start */ + for(from = todo_list->head; from; from = todonext) { /* "from" is the node from which we start */ n = from->data; - for(to = n->edge_tree->head; to; to = to->next) { /* "to" is the edge connected to "from" */ + for(to = n->edge_tree->head; to; to = to->next) { /* "to" is the edge connected to "from" */ e = to->data; - if(!e->reverse) { + if(!e->reverse) continue; - } /* Situation: - / - / + / + / ----->(n)---e-->(e->to) - \ - \ + \ + \ Where e is an edge, (n) and (e->to) are nodes. n->address is set to the e->address of the edge left of n to n. @@ -214,25 +273,17 @@ static void sssp_bfs(void) { indirect = n->status.indirect || e->options & OPTION_INDIRECT; if(e->to->status.visited - && (!e->to->status.indirect || indirect)) { + && (!e->to->status.indirect || indirect)) continue; - } - - // Only update nexthop the first time we visit this node. - - if(!e->to->status.visited) { - e->to->nexthop = (n->nexthop == myself) ? e->to : n->nexthop; - } e->to->status.visited = true; e->to->status.indirect = indirect; - e->to->prevedge = e; + e->to->nexthop = (n->nexthop == myself) ? e->to : n->nexthop; e->to->via = indirect ? n->via : e->to; e->to->options = e->options; - if(e->to->address.sa.sa_family == AF_UNSPEC && e->address.sa.sa_family != AF_UNKNOWN) { + if(e->to->address.sa.sa_family == AF_UNSPEC && e->address.sa.sa_family != AF_UNKNOWN) update_node_udp(e->to, &e->address); - } list_insert_tail(todo_list, e->to); } @@ -242,6 +293,15 @@ static void sssp_bfs(void) { } list_free(todo_list); +} + +static void check_reachability(void) { + splay_node_t *node, *next; + node_t *n; + char *name; + char *address, *port; + char *envp[7]; + int i; /* Check reachability status. */ @@ -254,10 +314,10 @@ static void sssp_bfs(void) { if(n->status.reachable) { ifdebug(TRAFFIC) logger(LOG_DEBUG, "Node %s (%s) became reachable", - n->name, n->hostname); + n->name, n->hostname); } else { ifdebug(TRAFFIC) logger(LOG_DEBUG, "Node %s (%s) became unreachable", - n->name, n->hostname); + n->name, n->hostname); } /* TODO: only clear status.validkey if node is unreachable? */ @@ -269,122 +329,45 @@ static void sssp_bfs(void) { n->minmtu = 0; n->mtuprobes = 0; - if(n->mtuevent) { - event_del(n->mtuevent); - n->mtuevent = NULL; - } + if(timeout_initialized(&n->mtuevent)) + event_del(&n->mtuevent); - xasprintf(&envp[0], "NETNAME=%s", netname ? netname : ""); - xasprintf(&envp[1], "DEVICE=%s", device ? device : ""); - xasprintf(&envp[2], "INTERFACE=%s", iface ? iface : ""); + xasprintf(&envp[0], "NETNAME=%s", netname ? : ""); + xasprintf(&envp[1], "DEVICE=%s", device ? : ""); + xasprintf(&envp[2], "INTERFACE=%s", iface ? : ""); xasprintf(&envp[3], "NODE=%s", n->name); sockaddr2str(&n->address, &address, &port); xasprintf(&envp[4], "REMOTEADDRESS=%s", address); xasprintf(&envp[5], "REMOTEPORT=%s", port); - xasprintf(&envp[6], "NAME=%s", myself->name); + envp[6] = NULL; execute_script(n->status.reachable ? "host-up" : "host-down", envp); xasprintf(&name, - n->status.reachable ? "hosts/%s-up" : "hosts/%s-down", - n->name); + n->status.reachable ? "hosts/%s-up" : "hosts/%s-down", + n->name); execute_script(name, envp); free(name); free(address); free(port); - for(i = 0; i < 7; i++) { + for(i = 0; i < 6; i++) free(envp[i]); - } subnet_update(n, NULL, n->status.reachable); - if(!n->status.reachable) { + if(!n->status.reachable) update_node_udp(n, NULL); - memset(&n->status, 0, sizeof(n->status)); - n->options = 0; - } else if(n->connection) { + else if(n->connection) send_ans_key(n); - } } } } void graph(void) { subnet_cache_flush(); - sssp_bfs(); + sssp_dijkstra(); + check_reachability(); mst_kruskal(); - graph_changed = true; -} - - - -/* Dump nodes and edges to a graphviz file. - - The file can be converted to an image with - dot -Tpng graph_filename -o image_filename.png -Gconcentrate=true -*/ - -void dump_graph(void) { - avl_node_t *node; - node_t *n; - edge_t *e; - char *filename = NULL, *tmpname = NULL; - FILE *file, *pipe = NULL; - - if(!graph_changed || !get_config_string(lookup_config(config_tree, "GraphDumpFile"), &filename)) { - return; - } - - graph_changed = false; - - ifdebug(PROTOCOL) logger(LOG_NOTICE, "Dumping graph"); - - if(filename[0] == '|') { - file = pipe = popen(filename + 1, "w"); - } else { - xasprintf(&tmpname, "%s.new", filename); - file = fopen(tmpname, "w"); - } - - if(!file) { - logger(LOG_ERR, "Unable to open graph dump file %s: %s", filename, strerror(errno)); - free(filename); - free(tmpname); - return; - } - - fprintf(file, "digraph {\n"); - - /* dump all nodes first */ - for(node = node_tree->head; node; node = node->next) { - n = node->data; - fprintf(file, " %s [label = \"%s\"];\n", n->name, n->name); - } - - /* now dump all edges */ - for(node = edge_weight_tree->head; node; node = node->next) { - e = node->data; - fprintf(file, " %s -> %s;\n", e->from->name, e->to->name); - } - - fprintf(file, "}\n"); - - if(pipe) { - pclose(pipe); - } else { - fclose(file); -#ifdef HAVE_MINGW - unlink(filename); -#endif - - if(rename(tmpname, filename)) { - logger(LOG_ERR, "Could not rename %s to %s: %s\n", tmpname, filename, strerror(errno)); - } - - free(tmpname); - } - - free(filename); } diff --git a/src/graph.h b/src/graph.h index fafffcb..fb41096 100644 --- a/src/graph.h +++ b/src/graph.h @@ -1,9 +1,6 @@ -#ifndef TINC_GRAPH_H -#define TINC_GRAPH_H - /* graph.h -- header for graph.c - Copyright (C) 2001-2012 Guus Sliepen , + Copyright (C) 2001-2006 Guus Sliepen , 2001-2005 Ivo Timmermans This program is free software; you can redistribute it and/or modify @@ -21,7 +18,10 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +#ifndef __TINC_GRAPH_H__ +#define __TINC_GRAPH_H__ + extern void graph(void); extern void dump_graph(void); -#endif +#endif /* __TINC_GRAPH_H__ */ diff --git a/src/ipv4.h b/src/ipv4.h index 7979f7d..940c239 100644 --- a/src/ipv4.h +++ b/src/ipv4.h @@ -1,10 +1,7 @@ -#ifndef TINC_IPV4_H -#define TINC_IPV4_H - /* ipv4.h -- missing IPv4 related definitions Copyright (C) 2005 Ivo Timmermans - 2006-2012 Guus Sliepen + 2006 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 @@ -21,6 +18,9 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +#ifndef __TINC_IPV4_H__ +#define __TINC_IPV4_H__ + #ifndef AF_INET #define AF_INET 2 #endif @@ -41,14 +41,6 @@ #define ICMP_NET_UNKNOWN 6 #endif -#ifndef ICMP_TIME_EXCEEDED -#define ICMP_TIME_EXCEEDED 11 -#endif - -#ifndef ICMP_EXC_TTL -#define ICMP_EXC_TTL 0 -#endif - #ifndef ICMP_NET_UNREACH #define ICMP_NET_UNREACH 0 #endif @@ -64,15 +56,15 @@ #ifndef HAVE_STRUCT_IP struct ip { #if __BYTE_ORDER == __LITTLE_ENDIAN - unsigned int ip_hl: 4; - unsigned int ip_v: 4; + unsigned int ip_hl:4; + unsigned int ip_v:4; #else - unsigned int ip_v: 4; - unsigned int ip_hl: 4; + unsigned int ip_v:4; + unsigned int ip_hl:4; #endif uint8_t ip_tos; uint16_t ip_len; - uint16_t ip_id; + uint16_t ip_id; uint16_t ip_off; #define IP_RF 0x8000 #define IP_DF 0x4000 @@ -81,7 +73,7 @@ struct ip { uint8_t ip_p; uint16_t ip_sum; struct in_addr ip_src, ip_dst; -} __attribute__((__packed__)); +} __attribute__ ((__packed__)); #endif #ifndef IP_OFFMASK @@ -143,7 +135,7 @@ struct icmp { #define icmp_radv icmp_dun.id_radv #define icmp_mask icmp_dun.id_mask #define icmp_data icmp_dun.id_data -} __attribute__((__packed__)); +} __attribute__ ((__packed__)); #endif -#endif +#endif /* __TINC_IPV4_H__ */ diff --git a/src/ipv6.h b/src/ipv6.h index 1642278..d98001d 100644 --- a/src/ipv6.h +++ b/src/ipv6.h @@ -1,10 +1,7 @@ -#ifndef TINC_IPV6_H -#define TINC_IPV6_H - /* ipv6.h -- missing IPv6 related definitions Copyright (C) 2005 Ivo Timmermans - 2006-2012 Guus Sliepen + 2006 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 @@ -21,6 +18,9 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +#ifndef __TINC_IPV6_H__ +#define __TINC_IPV6_H__ + #ifndef AF_INET6 #define AF_INET6 10 #endif @@ -36,7 +36,7 @@ struct in6_addr { uint16_t u6_addr16[8]; uint32_t u6_addr32[4]; } in6_u; -} __attribute__((__packed__)); +} __attribute__ ((__packed__)); #define s6_addr in6_u.u6_addr8 #define s6_addr16 in6_u.u6_addr16 #define s6_addr32 in6_u.u6_addr32 @@ -49,14 +49,14 @@ struct sockaddr_in6 { uint32_t sin6_flowinfo; struct in6_addr sin6_addr; uint32_t sin6_scope_id; -} __attribute__((__packed__)); +} __attribute__ ((__packed__)); #endif #ifndef IN6_IS_ADDR_V4MAPPED #define IN6_IS_ADDR_V4MAPPED(a) \ - ((((const uint32_t *) (a))[0] == 0) \ - && (((const uint32_t *) (a))[1] == 0) \ - && (((const uint32_t *) (a))[2] == htonl (0xffff))) + ((((__const uint32_t *) (a))[0] == 0) \ + && (((__const uint32_t *) (a))[1] == 0) \ + && (((__const uint32_t *) (a))[2] == htonl (0xffff))) #endif #ifndef HAVE_STRUCT_IP6_HDR @@ -72,7 +72,7 @@ struct ip6_hdr { } ip6_ctlun; struct in6_addr ip6_src; struct in6_addr ip6_dst; -} __attribute__((__packed__)); +} __attribute__ ((__packed__)); #define ip6_vfc ip6_ctlun.ip6_un2_vfc #define ip6_flow ip6_ctlun.ip6_un1.ip6_un1_flow #define ip6_plen ip6_ctlun.ip6_un1.ip6_un1_plen @@ -91,14 +91,12 @@ struct icmp6_hdr { uint16_t icmp6_un_data16[2]; uint8_t icmp6_un_data8[4]; } icmp6_dataun; -} __attribute__((__packed__)); +} __attribute__ ((__packed__)); #define ICMP6_DST_UNREACH_NOROUTE 0 #define ICMP6_DST_UNREACH 1 #define ICMP6_PACKET_TOO_BIG 2 -#define ICMP6_TIME_EXCEEDED 3 #define ICMP6_DST_UNREACH_ADMIN 1 #define ICMP6_DST_UNREACH_ADDR 3 -#define ICMP6_TIME_EXCEED_TRANSIT 0 #define ND_NEIGHBOR_SOLICIT 135 #define ND_NEIGHBOR_ADVERT 136 #define icmp6_data32 icmp6_dataun.icmp6_un_data32 @@ -111,7 +109,7 @@ struct icmp6_hdr { struct nd_neighbor_solicit { struct icmp6_hdr nd_ns_hdr; struct in6_addr nd_ns_target; -} __attribute__((__packed__)); +} __attribute__ ((__packed__)); #define ND_OPT_SOURCE_LINKADDR 1 #define ND_OPT_TARGET_LINKADDR 2 #define nd_ns_type nd_ns_hdr.icmp6_type @@ -124,7 +122,7 @@ struct nd_neighbor_solicit { struct nd_opt_hdr { uint8_t nd_opt_type; uint8_t nd_opt_len; -} __attribute__((__packed__)); +} __attribute__ ((__packed__)); #endif -#endif +#endif /* __TINC_IPV6_H__ */ diff --git a/src/linux/device.c b/src/linux/device.c index 38debe8..d36f3f6 100644 --- a/src/linux/device.c +++ b/src/linux/device.c @@ -1,7 +1,7 @@ /* device.c -- Interaction with Linux ethertap and tun/tap device Copyright (C) 2001-2005 Ivo Timmermans, - 2001-2014 Guus Sliepen + 2001-2009 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 @@ -18,25 +18,21 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#include "../system.h" +#include "system.h" -#ifdef HAVE_LINUX_IF_TUN_H #include #define DEFAULT_DEVICE "/dev/net/tun" -#else -#define DEFAULT_DEVICE "/dev/tap0" -#endif -#include "../conf.h" -#include "../device.h" -#include "../logger.h" -#include "../net.h" -#include "../route.h" -#include "../utils.h" -#include "../xalloc.h" +#include "conf.h" +#include "device.h" +#include "logger.h" +#include "net.h" +#include "route.h" +#include "utils.h" +#include "xalloc.h" +#include "device.h" typedef enum device_type_t { - DEVICE_TYPE_ETHERTAP, DEVICE_TYPE_TUN, DEVICE_TYPE_TAP, } device_type_t; @@ -45,27 +41,22 @@ int device_fd = -1; static device_type_t device_type; char *device = NULL; char *iface = NULL; -static char *type = NULL; static char ifrname[IFNAMSIZ]; -static const char *device_info; +static char *device_info; -static uint64_t device_total_in = 0; -static uint64_t device_total_out = 0; +uint64_t device_in_packets = 0; +uint64_t device_in_bytes = 0; +uint64_t device_out_packets = 0; +uint64_t device_out_bytes = 0; -static bool setup_device(void) { - struct ifreq ifr; - bool t1q = false; - - if(!get_config_string(lookup_config(config_tree, "Device"), &device)) { +bool setup_device(void) { + if(!get_config_string(lookup_config(config_tree, "Device"), &device)) device = xstrdup(DEFAULT_DEVICE); - } if(!get_config_string(lookup_config(config_tree, "Interface"), &iface)) #ifdef HAVE_LINUX_IF_TUN_H - if(netname != NULL) { + if (netname != NULL) iface = xstrdup(netname); - } - #else iface = xstrdup(strrchr(device, '/') ? strrchr(device, '/') + 1 : device); #endif @@ -76,79 +67,38 @@ static bool setup_device(void) { return false; } -#ifdef FD_CLOEXEC - fcntl(device_fd, F_SETFD, FD_CLOEXEC); -#endif + struct ifreq ifr = {{{0}}}; -#ifdef HAVE_LINUX_IF_TUN_H - /* Ok now check if this is an old ethertap or a new tun/tap thingie */ - - memset(&ifr, 0, sizeof(ifr)); - - get_config_string(lookup_config(config_tree, "DeviceType"), &type); - - if(type && strcasecmp(type, "tun") && strcasecmp(type, "tap")) { - logger(LOG_ERR, "Unknown device type %s!", type); - return false; - } - - if((type && !strcasecmp(type, "tun")) || (!type && routing_mode == RMODE_ROUTER)) { + if(routing_mode == RMODE_ROUTER) { ifr.ifr_flags = IFF_TUN; device_type = DEVICE_TYPE_TUN; device_info = "Linux tun/tap device (tun mode)"; } else { - if(routing_mode == RMODE_ROUTER) { - overwrite_mac = true; - } - ifr.ifr_flags = IFF_TAP | IFF_NO_PI; device_type = DEVICE_TYPE_TAP; device_info = "Linux tun/tap device (tap mode)"; } #ifdef IFF_ONE_QUEUE - /* Set IFF_ONE_QUEUE flag... */ - if(get_config_bool(lookup_config(config_tree, "IffOneQueue"), &t1q) && t1q) { - ifr.ifr_flags |= IFF_ONE_QUEUE; - } + bool t1q = false; + if(get_config_bool(lookup_config(config_tree, "IffOneQueue"), &t1q) && t1q) + ifr.ifr_flags |= IFF_ONE_QUEUE; #endif - if(iface) { + if(iface) strncpy(ifr.ifr_name, iface, IFNAMSIZ); - ifr.ifr_name[IFNAMSIZ - 1] = 0; - } if(!ioctl(device_fd, TUNSETIFF, &ifr)) { strncpy(ifrname, ifr.ifr_name, IFNAMSIZ); - ifrname[IFNAMSIZ - 1] = 0; - free(iface); + if(iface) free(iface); iface = xstrdup(ifrname); - } else if(errno == EPERM || errno == EBUSY) { - logger(LOG_ERR, "Error while trying to configure %s: %s", device, strerror(errno)); - return false; } else if(!ioctl(device_fd, (('T' << 8) | 202), &ifr)) { logger(LOG_WARNING, "Old ioctl() request was needed for %s", device); strncpy(ifrname, ifr.ifr_name, IFNAMSIZ); - ifrname[IFNAMSIZ - 1] = 0; - free(iface); + if(iface) free(iface); iface = xstrdup(ifrname); - } else -#endif - { - if(routing_mode == RMODE_ROUTER) { - overwrite_mac = true; - } - - device_info = "Linux ethertap device"; - device_type = DEVICE_TYPE_ETHERTAP; - free(iface); - iface = xstrdup(strrchr(device, '/') ? strrchr(device, '/') + 1 : device); - } - - if(overwrite_mac && !ioctl(device_fd, SIOCGIFHWADDR, &ifr)) { - memcpy(mymac.x, ifr.ifr_hwaddr.sa_data, ETH_ALEN); } logger(LOG_INFO, "%s is a %s", device, device_info); @@ -156,116 +106,84 @@ static bool setup_device(void) { return true; } -static void close_device(void) { +void close_device(void) { close(device_fd); - free(type); free(device); free(iface); } -static bool read_packet(vpn_packet_t *packet) { - int lenin; - +bool read_packet(vpn_packet_t *packet) { + int inlen; + switch(device_type) { - case DEVICE_TYPE_TUN: - lenin = read(device_fd, packet->data + 10, MTU - 10); + case DEVICE_TYPE_TUN: + inlen = read(device_fd, packet->data + 10, MTU - 10); - if(lenin <= 0) { - logger(LOG_ERR, "Error while reading from %s %s: %s", - device_info, device, strerror(errno)); - return false; - } + if(inlen <= 0) { + logger(LOG_ERR, "Error while reading from %s %s: %s", + device_info, device, strerror(errno)); + return false; + } - memset(packet->data, 0, 12); - packet->len = lenin + 10; - break; + packet->len = inlen + 10; + break; + case DEVICE_TYPE_TAP: + inlen = read(device_fd, packet->data, MTU); - case DEVICE_TYPE_TAP: - lenin = read(device_fd, packet->data, MTU); + if(inlen <= 0) { + logger(LOG_ERR, "Error while reading from %s %s: %s", + device_info, device, strerror(errno)); + return false; + } - if(lenin <= 0) { - logger(LOG_ERR, "Error while reading from %s %s: %s", - device_info, device, strerror(errno)); - return false; - } - - packet->len = lenin; - break; - - case DEVICE_TYPE_ETHERTAP: - lenin = read(device_fd, packet->data - 2, MTU + 2); - - if(lenin <= 0) { - logger(LOG_ERR, "Error while reading from %s %s: %s", - device_info, device, strerror(errno)); - return false; - } - - packet->len = lenin - 2; - break; + packet->len = inlen; + break; + default: + abort(); } - device_total_in += packet->len; + device_in_packets++; + device_in_bytes += packet->len; ifdebug(TRAFFIC) logger(LOG_DEBUG, "Read packet of %d bytes from %s", packet->len, - device_info); + device_info); return true; } -static bool write_packet(vpn_packet_t *packet) { +bool write_packet(vpn_packet_t *packet) { ifdebug(TRAFFIC) logger(LOG_DEBUG, "Writing packet of %d bytes to %s", - packet->len, device_info); + packet->len, device_info); switch(device_type) { - case DEVICE_TYPE_TUN: - packet->data[10] = packet->data[11] = 0; - - if(write(device_fd, packet->data + 10, packet->len - 10) < 0) { - logger(LOG_ERR, "Can't write to %s %s: %s", device_info, device, - strerror(errno)); - return false; - } - - break; - - case DEVICE_TYPE_TAP: - if(write(device_fd, packet->data, packet->len) < 0) { - logger(LOG_ERR, "Can't write to %s %s: %s", device_info, device, - strerror(errno)); - return false; - } - - break; - - case DEVICE_TYPE_ETHERTAP: - memcpy(packet->data - 2, &packet->len, 2); - - if(write(device_fd, packet->data - 2, packet->len + 2) < 0) { - logger(LOG_ERR, "Can't write to %s %s: %s", device_info, device, - strerror(errno)); - return false; - } - - break; + case DEVICE_TYPE_TUN: + packet->data[10] = packet->data[11] = 0; + if(write(device_fd, packet->data + 10, packet->len - 10) < 0) { + logger(LOG_ERR, "Can't write to %s %s: %s", device_info, device, + strerror(errno)); + return false; + } + break; + case DEVICE_TYPE_TAP: + if(write(device_fd, packet->data, packet->len) < 0) { + logger(LOG_ERR, "Can't write to %s %s: %s", device_info, device, + strerror(errno)); + return false; + } + break; + default: + abort(); } - device_total_out += packet->len; + device_out_packets++; + device_out_bytes += packet->len; return true; } -static void dump_device_stats(void) { +void dump_device_stats(void) { logger(LOG_DEBUG, "Statistics for %s %s:", device_info, device); - logger(LOG_DEBUG, " total bytes in: %10"PRIu64, device_total_in); - logger(LOG_DEBUG, " total bytes out: %10"PRIu64, device_total_out); + logger(LOG_DEBUG, " total bytes in: %10"PRIu64, device_in_bytes); + logger(LOG_DEBUG, " total bytes out: %10"PRIu64, device_out_bytes); } - -const devops_t os_devops = { - .setup = setup_device, - .close = close_device, - .read = read_packet, - .write = write_packet, - .dump_stats = dump_device_stats, -}; diff --git a/src/list.c b/src/list.c index a807c6d..9b67791 100644 --- a/src/list.c +++ b/src/list.c @@ -43,9 +43,8 @@ list_node_t *list_alloc_node(void) { } void list_free_node(list_t *list, list_node_t *node) { - if(node->data && list->delete) { + if(node->data && list->delete) list->delete(node->data); - } free(node); } @@ -62,11 +61,10 @@ list_node_t *list_insert_head(list_t *list, void *data) { node->next = list->head; list->head = node; - if(node->next) { + if(node->next) node->next->prev = node; - } else { + else list->tail = node; - } list->count++; @@ -83,11 +81,50 @@ list_node_t *list_insert_tail(list_t *list, void *data) { node->prev = list->tail; list->tail = node; - if(node->prev) { + if(node->prev) node->prev->next = node; - } else { + else + list->head = node; + + list->count++; + + return node; +} + +list_node_t *list_insert_after(list_t *list, list_node_t *after, void *data) { + list_node_t *node; + + node = list_alloc_node(); + + node->data = data; + node->next = after->next; + node->prev = after; + after->next = node; + + if(node->next) + node->next->prev = node; + else + list->tail = node; + + list->count++; + + return node; +} + +list_node_t *list_insert_before(list_t *list, list_node_t *before, void *data) { + list_node_t *node; + + node = list_alloc_node(); + + node->data = data; + node->next = before; + node->prev = before->prev; + before->prev = node; + + if(node->prev) + node->prev->next = node; + else list->head = node; - } list->count++; @@ -95,17 +132,15 @@ list_node_t *list_insert_tail(list_t *list, void *data) { } void list_unlink_node(list_t *list, list_node_t *node) { - if(node->prev) { + if(node->prev) node->prev->next = node->next; - } else { + else list->head = node->next; - } - if(node->next) { + if(node->next) node->next->prev = node->prev; - } else { + else list->tail = node->prev; - } list->count--; } @@ -126,19 +161,17 @@ void list_delete_tail(list_t *list) { /* Head/tail lookup */ void *list_get_head(list_t *list) { - if(list->head) { + if(list->head) return list->head->data; - } else { + else return NULL; - } } void *list_get_tail(list_t *list) { - if(list->tail) { + if(list->tail) return list->tail->data; - } else { + else return NULL; - } } /* Fast list deletion */ @@ -170,9 +203,7 @@ void list_foreach(list_t *list, list_action_t action) { for(node = list->head; node; node = next) { next = node->next; - - if(node->data) { + if(node->data) action(node->data); - } } } diff --git a/src/list.h b/src/list.h index b2a9b3d..4fe48db 100644 --- a/src/list.h +++ b/src/list.h @@ -1,6 +1,3 @@ -#ifndef TINC_LIST_H -#define TINC_LIST_H - /* list.h -- header file for list.c Copyright (C) 2000-2005 Ivo Timmermans @@ -21,6 +18,9 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +#ifndef __TINC_LIST_H__ +#define __TINC_LIST_H__ + typedef struct list_node_t { struct list_node_t *prev; struct list_node_t *next; @@ -45,34 +45,36 @@ typedef struct list_t { /* (De)constructors */ -extern list_t *list_alloc(list_action_t) __attribute__((__malloc__)); -extern void list_free(list_t *list); +extern list_t *list_alloc(list_action_t) __attribute__ ((__malloc__)); +extern void list_free(list_t *); extern list_node_t *list_alloc_node(void); -extern void list_free_node(list_t *list, list_node_t *node); +extern void list_free_node(list_t *, list_node_t *); /* Insertion and deletion */ -extern list_node_t *list_insert_head(list_t *list, void *data); -extern list_node_t *list_insert_tail(list_t *list, void *data); +extern list_node_t *list_insert_head(list_t *, void *); +extern list_node_t *list_insert_tail(list_t *, void *); +extern list_node_t *list_insert_after(list_t *, list_node_t *, void *); +extern list_node_t *list_insert_before(list_t *, list_node_t *, void *); -extern void list_unlink_node(list_t *list, list_node_t *node); -extern void list_delete_node(list_t *list, list_node_t *node); +extern void list_unlink_node(list_t *, list_node_t *); +extern void list_delete_node(list_t *, list_node_t *); -extern void list_delete_head(list_t *list); -extern void list_delete_tail(list_t *list); +extern void list_delete_head(list_t *); +extern void list_delete_tail(list_t *); /* Head/tail lookup */ -extern void *list_get_head(list_t *list); -extern void *list_get_tail(list_t *list); +extern void *list_get_head(list_t *); +extern void *list_get_tail(list_t *); /* Fast list deletion */ -extern void list_delete_list(list_t *list); +extern void list_delete_list(list_t *); /* Traversing */ -extern void list_foreach(list_t *list, list_action_t action); -extern void list_foreach_node(list_t *list, list_action_node_t action); +extern void list_foreach(list_t *, list_action_t); +extern void list_foreach_node(list_t *, list_action_node_t); -#endif +#endif /* __TINC_LIST_H__ */ diff --git a/src/logger.c b/src/logger.c index 8d4aea1..08f9795 100644 --- a/src/logger.c +++ b/src/logger.c @@ -1,6 +1,6 @@ /* logger.c -- logging code - Copyright (C) 2004-2016 Guus Sliepen + Copyright (C) 2004-2006 Guus Sliepen 2004-2005 Ivo Timmermans This program is free software; you can redistribute it and/or modify @@ -36,58 +36,48 @@ static const char *logident = NULL; void openlogger(const char *ident, logmode_t mode) { logident = ident; logmode = mode; - + switch(mode) { - case LOGMODE_STDERR: - logpid = getpid(); - break; - - case LOGMODE_FILE: - logpid = getpid(); - logfile = fopen(logfilename, "a"); - - if(!logfile) { - fprintf(stderr, "Could not open log file %s: %s\n", logfilename, strerror(errno)); - logmode = LOGMODE_NULL; - } - - break; - - case LOGMODE_SYSLOG: + case LOGMODE_STDERR: + logpid = getpid(); + break; + case LOGMODE_FILE: + logpid = getpid(); + logfile = fopen(logfilename, "a"); + if(!logfile) { + fprintf(stderr, "Could not open log file %s: %s\n", logfilename, strerror(errno)); + logmode = LOGMODE_NULL; + } + break; + case LOGMODE_SYSLOG: #ifdef HAVE_MINGW - loghandle = RegisterEventSource(NULL, logident); - - if(!loghandle) { - fprintf(stderr, "Could not open log handle!"); - logmode = LOGMODE_NULL; - } - - break; + loghandle = RegisterEventSource(NULL, logident); + if(!loghandle) { + fprintf(stderr, "Could not open log handle!"); + logmode = LOGMODE_NULL; + } + break; #else #ifdef HAVE_SYSLOG_H - openlog(logident, LOG_CONS | LOG_PID, LOG_DAEMON); - break; + openlog(logident, LOG_CONS | LOG_PID, LOG_DAEMON); + break; #endif #endif - - case LOGMODE_NULL: - break; + case LOGMODE_NULL: + break; } } void reopenlogger() { - if(logmode != LOGMODE_FILE) { + if(logmode != LOGMODE_FILE) return; - } fflush(logfile); FILE *newfile = fopen(logfilename, "a"); - if(!newfile) { - logger(LOG_ERR, "Unable to reopen log file %s: %s", logfilename, strerror(errno)); + logger(LOG_ERR, "Unable to reopen log file %s: %s\n", logfilename, strerror(errno)); return; } - fclose(logfile); logfile = newfile; } @@ -100,48 +90,43 @@ void logger(int priority, const char *format, ...) { va_start(ap, format); switch(logmode) { - case LOGMODE_STDERR: - vfprintf(stderr, format, ap); - fprintf(stderr, "\n"); - fflush(stderr); - break; - - case LOGMODE_FILE: - now = time(NULL); - strftime(timestr, sizeof(timestr), "%Y-%m-%d %H:%M:%S", localtime(&now)); - fprintf(logfile, "%s %s[%ld]: ", timestr, logident, (long)logpid); - vfprintf(logfile, format, ap); - fprintf(logfile, "\n"); - fflush(logfile); - break; - - case LOGMODE_SYSLOG: + case LOGMODE_STDERR: + vfprintf(stderr, format, ap); + fprintf(stderr, "\n"); + fflush(stderr); + break; + case LOGMODE_FILE: + now = time(NULL); + strftime(timestr, sizeof timestr, "%Y-%m-%d %H:%M:%S", localtime(&now)); + fprintf(logfile, "%s %s[%ld]: ", timestr, logident, (long)logpid); + vfprintf(logfile, format, ap); + fprintf(logfile, "\n"); + fflush(logfile); + break; + case LOGMODE_SYSLOG: #ifdef HAVE_MINGW - { - char message[4096]; - const char *messages[] = {message}; - vsnprintf(message, sizeof(message), format, ap); - message[sizeof(message) - 1] = 0; - ReportEvent(loghandle, priority, 0, 0, NULL, 1, 0, messages, NULL); - } - + { + char message[4096]; + const char *messages[] = {message}; + vsnprintf(message, sizeof message, format, ap); + ReportEvent(loghandle, priority, 0, 0, NULL, 1, 0, messages, NULL); + } #else #ifdef HAVE_SYSLOG_H #ifdef HAVE_VSYSLOG - vsyslog(priority, format, ap); + vsyslog(priority, format, ap); #else - { - char message[4096]; - vsnprintf(message, sizeof(message), format, ap); - syslog(priority, "%s", message); - } + { + char message[4096]; + vsnprintf(message, sizeof message, format, ap); + syslog(priority, "%s", message); + } #endif - break; + break; #endif #endif - - case LOGMODE_NULL: - break; + case LOGMODE_NULL: + break; } va_end(ap); @@ -149,23 +134,22 @@ void logger(int priority, const char *format, ...) { void closelogger(void) { switch(logmode) { - case LOGMODE_FILE: - fclose(logfile); - break; - - case LOGMODE_SYSLOG: + case LOGMODE_FILE: + fclose(logfile); + break; + case LOGMODE_SYSLOG: #ifdef HAVE_MINGW - DeregisterEventSource(loghandle); - break; + DeregisterEventSource(loghandle); + break; #else #ifdef HAVE_SYSLOG_H - closelog(); - break; + closelog(); + break; #endif #endif - - case LOGMODE_NULL: - case LOGMODE_STDERR: - break; + case LOGMODE_NULL: + case LOGMODE_STDERR: + break; + break; } } diff --git a/src/logger.h b/src/logger.h index 5a17ffb..ff2cb34 100644 --- a/src/logger.h +++ b/src/logger.h @@ -1,36 +1,17 @@ -#ifndef TINC_LOGGER_H -#define TINC_LOGGER_H - -/* - logger.h -- header file for logger.c - Copyright (C) 2003-2016 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 - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ +#ifndef __TINC_LOGGER_H__ +#define __TINC_LOGGER_H__ typedef enum debug_t { - DEBUG_NOTHING = 0, /* Quiet mode, only show starting/stopping of the daemon */ + DEBUG_NOTHING = 0, /* Quiet mode, only show starting/stopping of the daemon */ DEBUG_ALWAYS = 0, - DEBUG_CONNECTIONS = 1, /* Show (dis)connects of other tinc daemons via TCP */ - DEBUG_ERROR = 2, /* Show error messages received from other hosts */ - DEBUG_STATUS = 2, /* Show status messages received from other hosts */ - DEBUG_PROTOCOL = 3, /* Show the requests that are sent/received */ - DEBUG_META = 4, /* Show contents of every request that is sent/received */ - DEBUG_TRAFFIC = 5, /* Show network traffic information */ - DEBUG_PACKET = 6, /* Show contents of each packet that is being sent/received */ - DEBUG_SCARY_THINGS = 10, /* You have been warned */ + DEBUG_CONNECTIONS = 1, /* Show (dis)connects of other tinc daemons via TCP */ + DEBUG_ERROR = 2, /* Show error messages received from other hosts */ + DEBUG_STATUS = 2, /* Show status messages received from other hosts */ + DEBUG_PROTOCOL = 3, /* Show the requests that are sent/received */ + DEBUG_META = 4, /* Show contents of every request that is sent/received */ + DEBUG_TRAFFIC = 5, /* Show network traffic information */ + DEBUG_PACKET = 6, /* Show contents of each packet that is being sent/received */ + DEBUG_SCARY_THINGS = 10 /* You have been warned */ } debug_t; typedef enum logmode_t { @@ -65,11 +46,11 @@ enum { #endif extern debug_t debug_level; -extern void openlogger(const char *ident, logmode_t mode); +extern void openlogger(const char *, logmode_t); extern void reopenlogger(void); -extern void logger(int priority, const char *format, ...) __attribute__((__format__(printf, 2, 3))); +extern void logger(int, const char *, ...) __attribute__ ((__format__(printf, 2, 3))); extern void closelogger(void); #define ifdebug(l) if(debug_level >= DEBUG_##l) -#endif +#endif /* __TINC_LOGGER_H__ */ diff --git a/src/meta.c b/src/meta.c index ee55ecd..29dd824 100644 --- a/src/meta.c +++ b/src/meta.c @@ -1,6 +1,6 @@ /* meta.c -- handle the meta communication - Copyright (C) 2000-2017 Guus Sliepen , + Copyright (C) 2000-2009 Guus Sliepen , 2000-2005 Ivo Timmermans 2006 Scott Lamb @@ -21,125 +21,60 @@ #include "system.h" -#include -#include - -#include "avl_tree.h" +#include "splay_tree.h" +#include "cipher.h" #include "connection.h" #include "logger.h" #include "meta.h" #include "net.h" #include "protocol.h" -#include "proxy.h" #include "utils.h" #include "xalloc.h" bool send_meta(connection_t *c, const char *buffer, int length) { - int outlen; - int result; + if(!c) { + logger(LOG_ERR, "send_meta() called with NULL pointer!"); + abort(); + } ifdebug(META) logger(LOG_DEBUG, "Sending %d bytes of metadata to %s (%s)", length, - c->name, c->hostname); - - if(!c->outbuflen) { - c->last_flushed_time = now; - } - - /* Find room in connection's buffer */ - if(length + c->outbuflen > c->outbufsize) { - c->outbufsize = length + c->outbuflen; - c->outbuf = xrealloc(c->outbuf, c->outbufsize); - } - - if(length + c->outbuflen + c->outbufstart > c->outbufsize) { - memmove(c->outbuf, c->outbuf + c->outbufstart, c->outbuflen); - c->outbufstart = 0; - } + c->name, c->hostname); /* Add our data to buffer */ if(c->status.encryptout) { - /* Check encryption limits */ - if((uint64_t)length > c->outbudget) { - ifdebug(META) logger(LOG_ERR, "Byte limit exceeded for encryption to %s (%s)", c->name, c->hostname); + size_t outlen = length; + + if(!cipher_encrypt(&c->outcipher, buffer, length, buffer_prepare(&c->outbuf, length), &outlen, false) || outlen != length) { + logger(LOG_ERR, "Error while encrypting metadata to %s (%s)", + c->name, c->hostname); return false; - } else { - c->outbudget -= length; } - result = EVP_EncryptUpdate(c->outctx, (unsigned char *)c->outbuf + c->outbufstart + c->outbuflen, - &outlen, (unsigned char *)buffer, length); - - if(!result || outlen < length) { - logger(LOG_ERR, "Error while encrypting metadata to %s (%s): %s", - c->name, c->hostname, ERR_error_string(ERR_get_error(), NULL)); - return false; - } else if(outlen > length) { - logger(LOG_EMERG, "Encrypted data too long! Heap corrupted!"); - abort(); - } - - c->outbuflen += outlen; } else { - memcpy(c->outbuf + c->outbufstart + c->outbuflen, buffer, length); - c->outbuflen += length; + buffer_add(&c->outbuf, buffer, length); } - return true; -} + event_add(&c->outevent, NULL); -bool flush_meta(connection_t *c) { - int result; - - ifdebug(META) logger(LOG_DEBUG, "Flushing %d bytes to %s (%s)", - c->outbuflen, c->name, c->hostname); - - while(c->outbuflen) { - result = send(c->socket, c->outbuf + c->outbufstart, c->outbuflen, 0); - - if(result <= 0) { - if(!errno || errno == EPIPE) { - ifdebug(CONNECTIONS) logger(LOG_NOTICE, "Connection closed by %s (%s)", - c->name, c->hostname); - } else if(errno == EINTR) { - continue; - } else if(sockwouldblock(sockerrno)) { - ifdebug(META) logger(LOG_DEBUG, "Flushing %d bytes to %s (%s) would block", - c->outbuflen, c->name, c->hostname); - return true; - } else { - logger(LOG_ERR, "Flushing meta data to %s (%s) failed: %s", c->name, - c->hostname, sockstrerror(sockerrno)); - } - - return false; - } - - c->outbufstart += result; - c->outbuflen -= result; - } - - c->outbufstart = 0; /* avoid unnecessary memmoves */ return true; } void broadcast_meta(connection_t *from, const char *buffer, int length) { - avl_node_t *node; + splay_node_t *node; connection_t *c; for(node = connection_tree->head; node; node = node->next) { c = node->data; - if(c != from && c->status.active) { + if(c != from && c->status.active) send_meta(c, buffer, length); - } } } bool receive_meta(connection_t *c) { - int oldlen, i, result; - int lenin, lenout, reqlen; - bool decrypted = false; + int inlen; char inbuf[MAXBUFSIZE]; + char *bufp = inbuf, *endp; /* Strategy: - Read as much as possible from the TCP socket in one go. @@ -150,109 +85,79 @@ bool receive_meta(connection_t *c) { - If not, keep stuff in buffer and exit. */ - lenin = recv(c->socket, c->buffer + c->buflen, MAXBUFSIZE - c->buflen, 0); - - if(lenin <= 0) { - if(!lenin || !errno) { - ifdebug(CONNECTIONS) logger(LOG_NOTICE, "Connection closed by %s (%s)", - c->name, c->hostname); - } else if(sockwouldblock(sockerrno)) { - return true; - } else - logger(LOG_ERR, "Metadata socket read error for %s (%s): %s", - c->name, c->hostname, sockstrerror(sockerrno)); + buffer_compact(&c->inbuf, MAXBUFSIZE); + if(sizeof inbuf <= c->inbuf.len) { + logger(LOG_ERR, "Input buffer full for %s (%s)", c->name, c->hostname); return false; } - oldlen = c->buflen; - c->buflen += lenin; + inlen = recv(c->socket, inbuf, sizeof inbuf - c->inbuf.len, 0); - while(lenin > 0) { - reqlen = 0; + if(inlen <= 0) { + if(!inlen || !errno) { + ifdebug(CONNECTIONS) logger(LOG_NOTICE, "Connection closed by %s (%s)", + c->name, c->hostname); + } else if(sockwouldblock(sockerrno)) + return true; + else + logger(LOG_ERR, "Metadata socket read error for %s (%s): %s", + c->name, c->hostname, sockstrerror(sockerrno)); + return false; + } - /* Is it proxy metadata? */ + do { + if(!c->status.decryptin) { + endp = memchr(bufp, '\n', inlen); + if(endp) + endp++; + else + endp = bufp + inlen; - if(c->allow_request == PROXY) { - reqlen = receive_proxy_meta(c); + buffer_add(&c->inbuf, bufp, endp - bufp); - if(reqlen < 0) { - return false; - } - - goto consume; - } - - /* Decrypt */ - - if(c->status.decryptin && !decrypted) { - /* Check decryption limits */ - if((uint64_t)lenin > c->inbudget) { - ifdebug(META) logger(LOG_ERR, "Byte limit exceeded for decryption from %s (%s)", c->name, c->hostname); - return false; - } else { - c->inbudget -= lenin; - } - - result = EVP_DecryptUpdate(c->inctx, (unsigned char *)inbuf, &lenout, (unsigned char *)c->buffer + oldlen, lenin); - - if(!result || lenout != lenin) { - logger(LOG_ERR, "Error while decrypting metadata from %s (%s): %s", - c->name, c->hostname, ERR_error_string(ERR_get_error(), NULL)); - return false; - } - - memcpy(c->buffer + oldlen, inbuf, lenin); - decrypted = true; - } - - /* Are we receiving a TCPpacket? */ - - if(c->tcplen) { - if(c->tcplen <= c->buflen) { - if(c->allow_request != ALL) { - logger(LOG_ERR, "Got unauthorized TCP packet from %s (%s)", c->name, c->hostname); - return false; - } - - receive_tcppacket(c, c->buffer, c->tcplen); - reqlen = c->tcplen; - c->tcplen = 0; - } + inlen -= endp - bufp; + bufp = endp; } else { - /* Otherwise we are waiting for a request */ + size_t outlen = inlen; + ifdebug(META) logger(LOG_DEBUG, "Received encrypted %d bytes", inlen); - for(i = oldlen; i < c->buflen; i++) { - if(c->buffer[i] == '\n') { - c->buffer[i] = '\0'; /* replace end-of-line by end-of-string so we can use sscanf */ - c->reqlen = reqlen = i + 1; + if(!cipher_decrypt(&c->incipher, bufp, inlen, buffer_prepare(&c->inbuf, inlen), &outlen, false) || inlen != outlen) { + logger(LOG_ERR, "Error while decrypting metadata from %s (%s)", + c->name, c->hostname); + return false; + } + + inlen = 0; + } + + while(c->inbuf.len) { + /* Are we receiving a TCPpacket? */ + + if(c->tcplen) { + char *tcpbuffer = buffer_read(&c->inbuf, c->tcplen); + if(tcpbuffer) { + receive_tcppacket(c, tcpbuffer, c->tcplen); + c->tcplen = 0; + continue; + } else { break; } } - if(reqlen && !receive_request(c)) { - return false; + /* Otherwise we are waiting for a request */ + + char *request = buffer_readline(&c->inbuf); + if(request) { + bool result = receive_request(c, request); + if(!result) + return false; + continue; + } else { + break; } } - -consume: - - if(reqlen) { - c->buflen -= reqlen; - lenin -= reqlen - oldlen; - memmove(c->buffer, c->buffer + reqlen, c->buflen); - oldlen = 0; - continue; - } else { - break; - } - } - - if(c->buflen >= MAXBUFSIZE) { - logger(LOG_ERR, "Metadata read buffer overflow for %s (%s)", - c->name, c->hostname); - return false; - } + } while(inlen); return true; } diff --git a/src/meta.h b/src/meta.h index 36914f1..bc81a6a 100644 --- a/src/meta.h +++ b/src/meta.h @@ -1,6 +1,3 @@ -#ifndef TINC_META_H -#define TINC_META_H - /* meta.h -- header for meta.c Copyright (C) 2000-2006 Guus Sliepen , @@ -21,11 +18,13 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +#ifndef __TINC_META_H__ +#define __TINC_META_H__ + #include "connection.h" -extern bool send_meta(struct connection_t *c, const char *buffer, int length); -extern void broadcast_meta(struct connection_t *c, const char *buffer, int length); -extern bool flush_meta(struct connection_t *c); -extern bool receive_meta(struct connection_t *c); +extern bool send_meta(struct connection_t *, const char *, int); +extern void broadcast_meta(struct connection_t *, const char *, int); +extern bool receive_meta(struct connection_t *); -#endif +#endif /* __TINC_META_H__ */ diff --git a/src/mingw/common.h b/src/mingw/common.h index 41b9dc5..6e5e75c 100644 --- a/src/mingw/common.h +++ b/src/mingw/common.h @@ -37,7 +37,7 @@ //============= #define TAP_CONTROL_CODE(request,method) \ - CTL_CODE (FILE_DEVICE_UNKNOWN, request, method, FILE_ANY_ACCESS) + CTL_CODE (FILE_DEVICE_UNKNOWN, request, method, FILE_ANY_ACCESS) #define TAP_IOCTL_GET_MAC TAP_CONTROL_CODE (1, METHOD_BUFFERED) #define TAP_IOCTL_GET_VERSION TAP_CONTROL_CODE (2, METHOD_BUFFERED) diff --git a/src/mingw/device.c b/src/mingw/device.c index 321c515..bdca842 100644 --- a/src/mingw/device.c +++ b/src/mingw/device.c @@ -1,7 +1,7 @@ /* device.c -- Interaction with Windows tap driver in a MinGW environment Copyright (C) 2002-2005 Ivo Timmermans, - 2002-2016 Guus Sliepen + 2002-2011 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 @@ -18,87 +18,72 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#include "../system.h" +#include "system.h" #include #include -#include "../conf.h" -#include "../device.h" -#include "../logger.h" -#include "../net.h" -#include "../route.h" -#include "../utils.h" -#include "../xalloc.h" +#include "conf.h" +#include "device.h" +#include "logger.h" +#include "net.h" +#include "route.h" +#include "utils.h" +#include "xalloc.h" -#include "common.h" +#include "mingw/common.h" int device_fd = -1; static HANDLE device_handle = INVALID_HANDLE_VALUE; char *device = NULL; char *iface = NULL; -static const char *device_info = "Windows tap device"; +static char *device_info = NULL; static uint64_t device_total_in = 0; static uint64_t device_total_out = 0; extern char *myport; -OVERLAPPED r_overlapped; -OVERLAPPED w_overlapped; static DWORD WINAPI tapreader(void *bla) { int status; - DWORD len; + long len; + OVERLAPPED overlapped; vpn_packet_t packet; - int errors = 0; logger(LOG_DEBUG, "Tap reader running"); /* Read from tap device and send to parent */ - r_overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); for(;;) { - ResetEvent(r_overlapped.hEvent); + overlapped.Offset = 0; + overlapped.OffsetHigh = 0; + ResetEvent(overlapped.hEvent); - status = ReadFile(device_handle, packet.data, MTU, &len, &r_overlapped); + status = ReadFile(device_handle, packet.data, MTU, &len, &overlapped); if(!status) { if(GetLastError() == ERROR_IO_PENDING) { - WaitForSingleObject(r_overlapped.hEvent, INFINITE); - - if(!GetOverlappedResult(device_handle, &r_overlapped, &len, FALSE)) { + WaitForSingleObject(overlapped.hEvent, INFINITE); + if(!GetOverlappedResult(device_handle, &overlapped, &len, FALSE)) continue; - } } else { logger(LOG_ERR, "Error while reading from %s %s: %s", device_info, - device, strerror(errno)); - errors++; - - if(errors >= 10) { - EnterCriticalSection(&mutex); - running = false; - LeaveCriticalSection(&mutex); - } - - usleep(1000000); - continue; + device, strerror(errno)); + return -1; } } - errors = 0; + EnterCriticalSection(&mutex); packet.len = len; packet.priority = 0; - - EnterCriticalSection(&mutex); route(myself, &packet); LeaveCriticalSection(&mutex); } - - return 0; } -static bool setup_device(void) { +bool setup_device(void) { HKEY key, key2; int i; @@ -106,7 +91,7 @@ static bool setup_device(void) { char adapterid[1024]; char adaptername[1024]; char tapname[1024]; - DWORD len; + long len; unsigned long status; bool found = false; @@ -117,10 +102,6 @@ static bool setup_device(void) { get_config_string(lookup_config(config_tree, "Device"), &device); get_config_string(lookup_config(config_tree, "Interface"), &iface); - if(device && iface) { - logger(LOG_WARNING, "Warning: both Device and Interface specified, results may not be as expected"); - } - /* Open registry and look for network adapters */ if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, NETWORK_CONNECTIONS_KEY, 0, KEY_READ, &key)) { @@ -128,51 +109,44 @@ static bool setup_device(void) { return false; } - for(i = 0; ; i++) { - len = sizeof(adapterid); - - if(RegEnumKeyEx(key, i, adapterid, &len, 0, 0, 0, NULL)) { + for (i = 0; ; i++) { + len = sizeof adapterid; + if(RegEnumKeyEx(key, i, adapterid, &len, 0, 0, 0, NULL)) break; - } /* Find out more about this adapter */ - snprintf(regpath, sizeof(regpath), "%s\\%s\\Connection", NETWORK_CONNECTIONS_KEY, adapterid); + snprintf(regpath, sizeof regpath, "%s\\%s\\Connection", NETWORK_CONNECTIONS_KEY, adapterid); - if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, regpath, 0, KEY_READ, &key2)) { + if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, regpath, 0, KEY_READ, &key2)) continue; - } - len = sizeof(adaptername); - err = RegQueryValueEx(key2, "Name", 0, 0, (LPBYTE)adaptername, &len); + len = sizeof adaptername; + err = RegQueryValueEx(key2, "Name", 0, 0, adaptername, &len); RegCloseKey(key2); - if(err) { + if(err) continue; - } if(device) { if(!strcmp(device, adapterid)) { found = true; break; - } else { + } else continue; - } } if(iface) { if(!strcmp(iface, adaptername)) { found = true; break; - } else { + } else continue; - } } - snprintf(tapname, sizeof(tapname), USERMODEDEVICEDIR "%s" TAPSUFFIX, adapterid); + snprintf(tapname, sizeof tapname, USERMODEDEVICEDIR "%s" TAPSUFFIX, adapterid); device_handle = CreateFile(tapname, GENERIC_WRITE | GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED, 0); - if(device_handle != INVALID_HANDLE_VALUE) { found = true; break; @@ -186,21 +160,19 @@ static bool setup_device(void) { return false; } - if(!device) { + if(!device) device = xstrdup(adapterid); - } - if(!iface) { + if(!iface) iface = xstrdup(adaptername); - } /* Try to open the corresponding tap device */ if(device_handle == INVALID_HANDLE_VALUE) { - snprintf(tapname, sizeof(tapname), USERMODEDEVICEDIR "%s" TAPSUFFIX, device); + snprintf(tapname, sizeof tapname, USERMODEDEVICEDIR "%s" TAPSUFFIX, device); device_handle = CreateFile(tapname, GENERIC_WRITE | GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED, 0); } - + if(device_handle == INVALID_HANDLE_VALUE) { logger(LOG_ERR, "%s (%s) is not a usable Windows tap device: %s", device, iface, winerror(GetLastError())); return false; @@ -208,7 +180,7 @@ static bool setup_device(void) { /* Get MAC address from tap device */ - if(!DeviceIoControl(device_handle, TAP_IOCTL_GET_MAC, mymac.x, sizeof(mymac.x), mymac.x, sizeof(mymac.x), &len, 0)) { + if(!DeviceIoControl(device_handle, TAP_IOCTL_GET_MAC, mymac.x, sizeof mymac.x, mymac.x, sizeof mymac.x, &len, 0)) { logger(LOG_ERR, "Could not get MAC address from Windows tap device %s (%s): %s", device, iface, winerror(GetLastError())); return false; } @@ -217,11 +189,6 @@ static bool setup_device(void) { overwrite_mac = 1; } - /* Create overlapped events for tap I/O */ - - r_overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); - w_overlapped.hEvent = CreateEvent(NULL, TRUE, TRUE, NULL); - /* Start the tap reader */ thread = CreateThread(NULL, 0, tapreader, NULL, 0, NULL); @@ -234,72 +201,36 @@ static bool setup_device(void) { /* Set media status for newer TAP-Win32 devices */ status = true; - DeviceIoControl(device_handle, TAP_IOCTL_SET_MEDIA_STATUS, &status, sizeof(status), &status, sizeof(status), &len, NULL); + DeviceIoControl(device_handle, TAP_IOCTL_SET_MEDIA_STATUS, &status, sizeof status, &status, sizeof status, &len, NULL); + + device_info = "Windows tap device"; logger(LOG_INFO, "%s (%s) is a %s", device, iface, device_info); return true; } -static void close_device(void) { +void close_device(void) { CloseHandle(device_handle); free(device); free(iface); } -static bool read_packet(vpn_packet_t *packet) { +bool read_packet(vpn_packet_t *packet) { return false; } -static bool write_packet(vpn_packet_t *packet) { - DWORD lenout; - static vpn_packet_t queue; +bool write_packet(vpn_packet_t *packet) { + long outlen; + OVERLAPPED overlapped = {0}; ifdebug(TRAFFIC) logger(LOG_DEBUG, "Writing packet of %d bytes to %s", - packet->len, device_info); + packet->len, device_info); - /* Check if there is something in progress */ - - if(queue.len) { - DWORD size; - BOOL success = GetOverlappedResult(device_handle, &w_overlapped, &size, FALSE); - - if(success) { - ResetEvent(&w_overlapped); - queue.len = 0; - } else { - int err = GetLastError(); - - if(err != ERROR_IO_INCOMPLETE) { - ifdebug(TRAFFIC) logger(LOG_DEBUG, "Error completing previously queued write: %s", winerror(err)); - ResetEvent(&w_overlapped); - queue.len = 0; - } else { - ifdebug(TRAFFIC) logger(LOG_DEBUG, "Previous overlapped write still in progress"); - // drop this packet - return true; - } - } - } - - /* Otherwise, try to write. */ - - memcpy(queue.data, packet->data, packet->len); - - if(!WriteFile(device_handle, queue.data, packet->len, &lenout, &w_overlapped)) { - int err = GetLastError(); - - if(err != ERROR_IO_PENDING) { - logger(LOG_ERR, "Error while writing to %s %s: %s", device_info, device, winerror(err)); - return false; - } - - // Write is being done asynchronously. - queue.len = packet->len; - } else { - // Write was completed immediately. - ResetEvent(&w_overlapped); + if(!WriteFile(device_handle, packet->data, packet->len, &outlen, &overlapped)) { + logger(LOG_ERR, "Error while writing to %s %s: %s", device_info, device, winerror(GetLastError())); + return false; } device_total_out += packet->len; @@ -307,16 +238,8 @@ static bool write_packet(vpn_packet_t *packet) { return true; } -static void dump_device_stats(void) { +void dump_device_stats(void) { logger(LOG_DEBUG, "Statistics for %s %s:", device_info, device); logger(LOG_DEBUG, " total bytes in: %10"PRIu64, device_total_in); logger(LOG_DEBUG, " total bytes out: %10"PRIu64, device_total_out); } - -const devops_t os_devops = { - .setup = setup_device, - .close = close_device, - .read = read_packet, - .write = write_packet, - .dump_stats = dump_device_stats, -}; diff --git a/src/multicast_device.c b/src/multicast_device.c deleted file mode 100644 index 93a40c4..0000000 --- a/src/multicast_device.c +++ /dev/null @@ -1,247 +0,0 @@ -/* - device.c -- multicast socket - Copyright (C) 2002-2005 Ivo Timmermans, - 2002-2014 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 - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include "system.h" - -#include "conf.h" -#include "device.h" -#include "net.h" -#include "logger.h" -#include "netutl.h" -#include "utils.h" -#include "route.h" -#include "xalloc.h" - -static const char *device_info = "multicast socket"; - -static uint64_t device_total_in = 0; -static uint64_t device_total_out = 0; - -static struct addrinfo *ai = NULL; -static mac_t ignore_src = {{0}}; - -static bool setup_device(void) { - char *host; - char *port; - char *space; - int ttl = 1; - - get_config_string(lookup_config(config_tree, "Interface"), &iface); - - if(!get_config_string(lookup_config(config_tree, "Device"), &device)) { - logger(LOG_ERR, "Device variable required for %s", device_info); - return false; - } - - host = xstrdup(device); - space = strchr(host, ' '); - - if(!space) { - logger(LOG_ERR, "Port number required for %s", device_info); - free(host); - return false; - } - - *space++ = 0; - port = space; - space = strchr(port, ' '); - - if(space) { - *space++ = 0; - ttl = atoi(space); - } - - ai = str2addrinfo(host, port, SOCK_DGRAM); - - if(!ai) { - free(host); - return false; - } - - device_fd = socket(ai->ai_family, SOCK_DGRAM, IPPROTO_UDP); - - if(device_fd < 0) { - logger(LOG_ERR, "Creating socket failed: %s", sockstrerror(sockerrno)); - free(host); - return false; - } - -#ifdef FD_CLOEXEC - fcntl(device_fd, F_SETFD, FD_CLOEXEC); -#endif - - static const int one = 1; - setsockopt(device_fd, SOL_SOCKET, SO_REUSEADDR, (void *)&one, sizeof(one)); - - if(bind(device_fd, ai->ai_addr, ai->ai_addrlen)) { - closesocket(device_fd); - logger(LOG_ERR, "Can't bind to %s %s: %s", host, port, sockstrerror(sockerrno)); - free(host); - return false; - } - - switch(ai->ai_family) { -#ifdef IP_ADD_MEMBERSHIP - - case AF_INET: { - struct ip_mreq mreq; - struct sockaddr_in in; - memcpy(&in, ai->ai_addr, sizeof(in)); - mreq.imr_multiaddr.s_addr = in.sin_addr.s_addr; - mreq.imr_interface.s_addr = htonl(INADDR_ANY); - - if(setsockopt(device_fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (void *)&mreq, sizeof(mreq))) { - logger(LOG_ERR, "Cannot join multicast group %s %s: %s", host, port, sockstrerror(sockerrno)); - closesocket(device_fd); - free(host); - return false; - } - -#ifdef IP_MULTICAST_LOOP - setsockopt(device_fd, IPPROTO_IP, IP_MULTICAST_LOOP, (const void *)&one, sizeof(one)); -#endif -#ifdef IP_MULTICAST_TTL - setsockopt(device_fd, IPPROTO_IP, IP_MULTICAST_TTL, (void *)&ttl, sizeof(ttl)); -#endif - } - break; -#endif - -#ifdef IPV6_JOIN_GROUP - - case AF_INET6: { - struct ipv6_mreq mreq; - struct sockaddr_in6 in6; - memcpy(&in6, ai->ai_addr, sizeof(in6)); - memcpy(&mreq.ipv6mr_multiaddr, &in6.sin6_addr, sizeof(mreq.ipv6mr_multiaddr)); - mreq.ipv6mr_interface = in6.sin6_scope_id; - - if(setsockopt(device_fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, (void *)&mreq, sizeof(mreq))) { - logger(LOG_ERR, "Cannot join multicast group %s %s: %s", host, port, sockstrerror(sockerrno)); - closesocket(device_fd); - free(host); - return false; - } - -#ifdef IPV6_MULTICAST_LOOP - setsockopt(device_fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, (const void *)&one, sizeof(one)); -#endif -#ifdef IPV6_MULTICAST_HOPS - setsockopt(device_fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, (void *)&ttl, sizeof(ttl)); -#endif - } - break; -#endif - - default: - logger(LOG_ERR, "Multicast for address family %x unsupported", ai->ai_family); - closesocket(device_fd); - free(host); - return false; - } - - free(host); - logger(LOG_INFO, "%s is a %s", device, device_info); - - return true; -} - -static void close_device(void) { - close(device_fd); - - free(device); - free(iface); - - if(ai) { - freeaddrinfo(ai); - } -} - -static bool read_packet(vpn_packet_t *packet) { - int lenin; - - if((lenin = recv(device_fd, (void *)packet->data, MTU, 0)) <= 0) { - logger(LOG_ERR, "Error while reading from %s %s: %s", device_info, - device, strerror(errno)); - return false; - } - - if(!memcmp(&ignore_src, packet->data + 6, sizeof(ignore_src))) { - ifdebug(SCARY_THINGS) logger(LOG_DEBUG, "Ignoring loopback packet of %d bytes from %s", lenin, device_info); - packet->len = 0; - return true; - } - - packet->len = lenin; - - device_total_in += packet->len; - - ifdebug(TRAFFIC) logger(LOG_DEBUG, "Read packet of %d bytes from %s", packet->len, - device_info); - - return true; -} - -static bool write_packet(vpn_packet_t *packet) { - ifdebug(TRAFFIC) logger(LOG_DEBUG, "Writing packet of %d bytes to %s", - packet->len, device_info); - - if(sendto(device_fd, (void *)packet->data, packet->len, 0, ai->ai_addr, ai->ai_addrlen) < 0) { - logger(LOG_ERR, "Can't write to %s %s: %s", device_info, device, - strerror(errno)); - return false; - } - - device_total_out += packet->len; - - memcpy(&ignore_src, packet->data + 6, sizeof(ignore_src)); - - return true; -} - -static void dump_device_stats(void) { - logger(LOG_DEBUG, "Statistics for %s %s:", device_info, device); - logger(LOG_DEBUG, " total bytes in: %10"PRIu64, device_total_in); - logger(LOG_DEBUG, " total bytes out: %10"PRIu64, device_total_out); -} - -const devops_t multicast_devops = { - .setup = setup_device, - .close = close_device, - .read = read_packet, - .write = write_packet, - .dump_stats = dump_device_stats, -}; - -#if 0 - -static bool not_supported(void) { - logger(LOG_ERR, "Raw socket device not supported on this platform"); - return false; -} - -const devops_t multicast_devops = { - .setup = not_supported, - .close = NULL, - .read = NULL, - .write = NULL, - .dump_stats = NULL, -}; -#endif diff --git a/src/net.c b/src/net.c index 37ae116..f9020b3 100644 --- a/src/net.c +++ b/src/net.c @@ -1,9 +1,9 @@ /* net.c -- most of the network code Copyright (C) 1998-2005 Ivo Timmermans, - 2000-2015 Guus Sliepen + 2000-2011 Guus Sliepen 2006 Scott Lamb - 2011 Loïc Grenié + 2011 Loïc Grenié 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 @@ -22,14 +22,11 @@ #include "system.h" -#include - #include "utils.h" -#include "avl_tree.h" +#include "splay_tree.h" #include "conf.h" #include "connection.h" #include "device.h" -#include "event.h" #include "graph.h" #include "logger.h" #include "meta.h" @@ -37,25 +34,17 @@ #include "netutl.h" #include "process.h" #include "protocol.h" -#include "route.h" #include "subnet.h" #include "xalloc.h" -bool do_purge = false; -volatile bool running = false; -#ifdef HAVE_PSELECT -bool graph_dump = false; -#endif - -time_t now = 0; int contradicting_add_edge = 0; int contradicting_del_edge = 0; static int sleeptime = 10; /* Purge edges and subnets of unreachable nodes. Use carefully. */ -static void purge(void) { - avl_node_t *nnode, *nnext, *enode, *enext, *snode, *snext; +void purge(void) { + splay_node_t *nnode, *nnext, *enode, *enext, *snode, *snext; node_t *n; edge_t *e; subnet_t *s; @@ -70,26 +59,21 @@ static void purge(void) { if(!n->status.reachable) { ifdebug(SCARY_THINGS) logger(LOG_DEBUG, "Purging node %s (%s)", n->name, - n->hostname); + n->hostname); for(snode = n->subnet_tree->head; snode; snode = snext) { snext = snode->next; s = snode->data; - send_del_subnet(everyone, s); - - if(!strictsubnets) { + send_del_subnet(broadcast, s); + if(!strictsubnets) subnet_del(n, s); - } } for(enode = n->edge_tree->head; enode; enode = enext) { enext = enode->next; e = enode->data; - - if(!tunnelserver) { - send_del_edge(everyone, e); - } - + if(!tunnelserver) + send_del_edge(broadcast, e); edge_del(e); } } @@ -106,96 +90,17 @@ static void purge(void) { enext = enode->next; e = enode->data; - if(e->to == n) { + if(e->to == n) break; - } } if(!enode && (!strictsubnets || !n->subnet_tree->head)) /* in strictsubnets mode do not delete nodes with subnets */ - { node_del(n); - } } } } -/* - put all file descriptors in an fd_set array - While we're at it, purge stuff that needs to be removed. -*/ -static int build_fdset(fd_set *readset, fd_set *writeset) { - avl_node_t *node, *next; - connection_t *c; - int i, max = 0; - - FD_ZERO(readset); - FD_ZERO(writeset); - - for(node = connection_tree->head; node; node = next) { - next = node->next; - c = node->data; - - if(c->status.remove) { - connection_del(c); - - if(!connection_tree->head) { - purge(); - } - } else { - FD_SET(c->socket, readset); - - if(c->outbuflen > 0 || c->status.connecting) { - FD_SET(c->socket, writeset); - } - - if(c->socket > max) { - max = c->socket; - } - } - } - - for(i = 0; i < listen_sockets; i++) { - FD_SET(listen_socket[i].tcp, readset); - - if(listen_socket[i].tcp > max) { - max = listen_socket[i].tcp; - } - - FD_SET(listen_socket[i].udp, readset); - - if(listen_socket[i].udp > max) { - max = listen_socket[i].udp; - } - } - - if(device_fd >= 0) { - FD_SET(device_fd, readset); - } - - if(device_fd > max) { - max = device_fd; - } - - return max; -} - -/* Put a misbehaving connection in the tarpit */ -void tarpit(int fd) { - static int pits[10] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1}; - static int next_pit = 0; - - if(pits[next_pit] != -1) { - closesocket(pits[next_pit]); - } - - pits[next_pit++] = fd; - - if(next_pit >= (int)(sizeof pits / sizeof pits[0])) { - next_pit = 0; - } -} - /* Terminate a connection: - Close the socket @@ -204,41 +109,19 @@ void tarpit(int fd) { - Deactivate the host */ void terminate_connection(connection_t *c, bool report) { - if(c->status.remove) { - return; - } - ifdebug(CONNECTIONS) logger(LOG_NOTICE, "Closing connection with %s (%s)", - c->name, c->hostname); + c->name, c->hostname); - c->status.remove = true; c->status.active = false; - if(c->node) { + if(c->node) c->node->connection = NULL; - } - - if(c->socket) { - if(c->status.tarpit) { - tarpit(c->socket); - } else { - closesocket(c->socket); - } - } if(c->edge) { - if(!c->node) { - logger(LOG_ERR, "Connection to %s (%s) has an edge but node is NULL!", c->name, c->hostname); - // And that should never happen. - abort(); - } - - if(report && !tunnelserver) { - send_del_edge(everyone, c->edge); - } + if(report && !tunnelserver) + send_del_edge(broadcast, c->edge); edge_del(c->edge); - c->edge = NULL; /* Run MST and SSSP algorithms */ @@ -249,32 +132,20 @@ void terminate_connection(connection_t *c, bool report) { if(report && !c->node->status.reachable) { edge_t *e; e = lookup_edge(c->node, myself); - if(e) { - if(!tunnelserver) { - send_del_edge(everyone, e); - } - + if(!tunnelserver) + send_del_edge(broadcast, e); edge_del(e); } } } - free_connection_partially(c); - /* Check if this was our outgoing connection */ - if(c->outgoing) { - c->status.remove = false; - do_outgoing_connection(c); - } + if(c->outgoing) + retry_outgoing(c->outgoing); -#ifndef HAVE_MINGW - /* Clean up dead proxy processes */ - - while(waitpid(-1, NULL, WNOHANG) > 0); - -#endif + connection_del(c); } /* @@ -285,9 +156,10 @@ void terminate_connection(connection_t *c, bool report) { end does not reply in time, we consider them dead and close the connection. */ -static void check_dead_connections(void) { - avl_node_t *node, *next; +static void timeout_handler(int fd, short events, void *event) { + splay_node_t *node, *next; connection_t *c; + time_t now = time(NULL); for(node = connection_tree->head; node; node = next) { next = node->next; @@ -297,124 +169,182 @@ static void check_dead_connections(void) { if(c->status.active) { if(c->status.pinged) { ifdebug(CONNECTIONS) logger(LOG_INFO, "%s (%s) didn't respond to PING in %ld seconds", - c->name, c->hostname, (long)(now - c->last_ping_time)); - c->status.timeout = true; + c->name, c->hostname, now - c->last_ping_time); terminate_connection(c, true); + continue; } else if(c->last_ping_time + pinginterval <= now) { send_ping(c); } } else { - if(c->status.remove) { - logger(LOG_WARNING, "Old connection_t for %s (%s) status %04x still lingering, deleting...", - c->name, c->hostname, bitfield_to_int(&c->status, sizeof(c->status))); - connection_del(c); - continue; - } - - ifdebug(CONNECTIONS) logger(LOG_WARNING, "Timeout from %s (%s) during authentication", - c->name, c->hostname); - if(c->status.connecting) { + ifdebug(CONNECTIONS) + logger(LOG_WARNING, "Timeout while connecting to %s (%s)", c->name, c->hostname); c->status.connecting = false; closesocket(c->socket); do_outgoing_connection(c); } else { - c->status.tarpit = true; + ifdebug(CONNECTIONS) logger(LOG_WARNING, "Timeout from %s (%s) during authentication", c->name, c->hostname); terminate_connection(c, false); - } - } - } - - if(c->outbuflen > 0 && c->last_flushed_time + pingtimeout <= now) { - if(c->status.active) { - ifdebug(CONNECTIONS) logger(LOG_INFO, - "%s (%s) could not flush for %ld seconds (%d bytes remaining)", - c->name, c->hostname, (long)(now - c->last_flushed_time), c->outbuflen); - c->status.timeout = true; - terminate_connection(c, true); - } - } - } -} - -/* - check all connections to see if anything - happened on their sockets -*/ -static void check_network_activity(fd_set *readset, fd_set *writeset) { - connection_t *c; - avl_node_t *node; - int result, i; - socklen_t len = sizeof(result); - vpn_packet_t packet; - static int errors = 0; - - /* check input from kernel */ - if(device_fd >= 0 && FD_ISSET(device_fd, readset)) { - if(devops.read(&packet)) { - if(packet.len) { - errors = 0; - packet.priority = 0; - route(myself, &packet); - } - } else { - usleep(errors * 50000); - errors++; - - if(errors > 10) { - logger(LOG_ERR, "Too many errors from %s, exiting!", device); - running = false; - } - } - } - - /* check meta connections */ - for(node = connection_tree->head; node; node = node->next) { - c = node->data; - - if(c->status.remove) { - continue; - } - - if(FD_ISSET(c->socket, writeset)) { - if(c->status.connecting) { - c->status.connecting = false; - getsockopt(c->socket, SOL_SOCKET, SO_ERROR, (void *)&result, &len); - - if(!result) { - finish_connecting(c); - } else { - ifdebug(CONNECTIONS) logger(LOG_DEBUG, - "Error while connecting to %s (%s): %s", - c->name, c->hostname, sockstrerror(result)); - closesocket(c->socket); - do_outgoing_connection(c); continue; } } + } + } - if(!flush_meta(c)) { - terminate_connection(c, c->status.active); - continue; - } + if(contradicting_del_edge > 100 && contradicting_add_edge > 100) { + logger(LOG_WARNING, "Possible node with same Name as us! Sleeping %d seconds.", sleeptime); + usleep(sleeptime * 1000000LL); + sleeptime *= 2; + if(sleeptime < 0) + sleeptime = 3600; + } else { + sleeptime /= 2; + if(sleeptime < 10) + sleeptime = 10; + } + + contradicting_add_edge = 0; + contradicting_del_edge = 0; + + event_add(event, &(struct timeval){pingtimeout, 0}); +} + +void handle_meta_connection_data(int fd, short events, void *data) { + connection_t *c = data; + int result; + socklen_t len = sizeof result; + + if(c->status.connecting) { + c->status.connecting = false; + + getsockopt(c->socket, SOL_SOCKET, SO_ERROR, &result, &len); + + if(!result) + finish_connecting(c); + else { + ifdebug(CONNECTIONS) logger(LOG_DEBUG, + "Error while connecting to %s (%s): %s", + c->name, c->hostname, sockstrerror(result)); + closesocket(c->socket); + do_outgoing_connection(c); + return; + } + } + + if (!receive_meta(c)) { + terminate_connection(c, c->status.active); + return; + } +} + +static void sigterm_handler(int signal, short events, void *data) { + logger(LOG_NOTICE, "Got %s signal", strsignal(signal)); + event_loopexit(NULL); +} + +static void sighup_handler(int signal, short events, void *data) { + logger(LOG_NOTICE, "Got %s signal", strsignal(signal)); + reopenlogger(); + reload_configuration(); +} + +static void sigalrm_handler(int signal, short events, void *data) { + logger(LOG_NOTICE, "Got %s signal", strsignal(signal)); + retry(); +} + +int reload_configuration(void) { + connection_t *c; + splay_node_t *node, *next; + char *fname; + struct stat s; + static time_t last_config_check = 0; + + /* Reread our own configuration file */ + + exit_configuration(&config_tree); + init_configuration(&config_tree); + + if(!read_server_config()) { + logger(LOG_ERR, "Unable to reread configuration file, exitting."); + event_loopexit(NULL); + return EINVAL; + } + + /* Close connections to hosts that have a changed or deleted host config file */ + + for(node = connection_tree->head; node; node = next) { + c = node->data; + next = node->next; + + if(c->outgoing) { + free(c->outgoing->name); + if(c->outgoing->ai) + freeaddrinfo(c->outgoing->ai); + free(c->outgoing); + c->outgoing = NULL; + } + + xasprintf(&fname, "%s/hosts/%s", confbase, c->name); + if(stat(fname, &s) || s.st_mtime > last_config_check) + terminate_connection(c, c->status.active); + free(fname); + } + + last_config_check = time(NULL); + + /* 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; } - if(FD_ISSET(c->socket, readset)) { - if(!receive_meta(c)) { - c->status.tarpit = true; - terminate_connection(c, c->status.active); - continue; + 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); } } } - for(i = 0; i < listen_sockets; i++) { - if(FD_ISSET(listen_socket[i].udp, readset)) { - handle_incoming_vpn_data(i); - } + /* Try to make outgoing connections */ + + try_outgoing_connections(); - if(FD_ISSET(listen_socket[i].tcp, readset)) { - handle_new_meta_connection(listen_socket[i].tcp); + return 0; +} + +void retry(void) { + connection_t *c; + splay_node_t *node; + + for(node = connection_tree->head; node; node = node->next) { + c = node->data; + + if(c->outgoing && !c->node) { + if(timeout_initialized(&c->outgoing->ev)) + event_del(&c->outgoing->ev); + if(c->status.connecting) + close(c->socket); + c->outgoing->timeout = 0; + do_outgoing_connection(c); } } } @@ -423,289 +353,40 @@ static void check_network_activity(fd_set *readset, fd_set *writeset) { this is where it all happens... */ int main_loop(void) { - fd_set readset, writeset; -#ifdef HAVE_PSELECT - struct timespec tv; - sigset_t omask, block_mask; - time_t next_event; -#else - struct timeval tv; + struct event timeout_event; + + timeout_set(&timeout_event, timeout_handler, &timeout_event); + event_add(&timeout_event, &(struct timeval){pingtimeout, 0}); + +#ifndef HAVE_MINGW + struct event sighup_event; + struct event sigterm_event; + struct event sigquit_event; + struct event sigalrm_event; + + signal_set(&sighup_event, SIGHUP, sighup_handler, NULL); + signal_add(&sighup_event, NULL); + signal_set(&sigterm_event, SIGTERM, sigterm_handler, NULL); + signal_add(&sigterm_event, NULL); + signal_set(&sigquit_event, SIGQUIT, sigterm_handler, NULL); + signal_add(&sigquit_event, NULL); + signal_set(&sigalrm_event, SIGALRM, sigalrm_handler, NULL); + signal_add(&sigalrm_event, NULL); #endif - int r, maxfd; - time_t last_ping_check, last_config_check, last_graph_dump; - event_t *event; - last_ping_check = now; - last_config_check = now; - last_graph_dump = now; - - srand(now); - -#ifdef HAVE_PSELECT - - if(lookup_config(config_tree, "GraphDumpFile")) { - graph_dump = true; + if(event_loop(0) < 0) { + logger(LOG_ERR, "Error while waiting for input: %s", strerror(errno)); + return 1; } - /* Block SIGHUP & SIGALRM */ - sigemptyset(&block_mask); - sigaddset(&block_mask, SIGHUP); - sigaddset(&block_mask, SIGALRM); - sigprocmask(SIG_BLOCK, &block_mask, &omask); +#ifndef HAVE_MINGW + signal_del(&sighup_event); + signal_del(&sigterm_event); + signal_del(&sigquit_event); + signal_del(&sigalrm_event); #endif - running = true; - - while(running) { -#ifdef HAVE_PSELECT - next_event = last_ping_check + pingtimeout; - - if(graph_dump && next_event > last_graph_dump + 60) { - next_event = last_graph_dump + 60; - } - - if((event = peek_next_event()) && next_event > event->time) { - next_event = event->time; - } - - if(next_event <= now) { - tv.tv_sec = 0; - } else { - tv.tv_sec = next_event - now; - } - - tv.tv_nsec = 0; -#else - tv.tv_sec = 1; - tv.tv_usec = 0; -#endif - - maxfd = build_fdset(&readset, &writeset); - -#ifdef HAVE_MINGW - LeaveCriticalSection(&mutex); -#endif -#ifdef HAVE_PSELECT - r = pselect(maxfd + 1, &readset, &writeset, NULL, &tv, &omask); -#else - r = select(maxfd + 1, &readset, &writeset, NULL, &tv); -#endif - now = time(NULL); -#ifdef HAVE_MINGW - EnterCriticalSection(&mutex); -#endif - - if(r < 0) { - if(!sockwouldblock(sockerrno)) { - logger(LOG_ERR, "Error while waiting for input: %s", sockstrerror(sockerrno)); - dump_connections(); - return 1; - } - } - - if(r > 0) { - check_network_activity(&readset, &writeset); - } - - if(do_purge) { - purge(); - do_purge = false; - } - - /* Let's check if everybody is still alive */ - - if(last_ping_check + pingtimeout <= now) { - check_dead_connections(); - last_ping_check = now; - - if(routing_mode == RMODE_SWITCH) { - age_subnets(); - } - - age_past_requests(); - - /* Should we regenerate our key? */ - - if(keyexpires <= now) { - avl_node_t *node; - node_t *n; - - ifdebug(STATUS) logger(LOG_INFO, "Expiring symmetric keys"); - - for(node = node_tree->head; node; node = node->next) { - n = node->data; - - if(n->inkey) { - free(n->inkey); - n->inkey = NULL; - } - } - - send_key_changed(); - keyexpires = now + keylifetime; - } - - /* Detect ADD_EDGE/DEL_EDGE storms that are caused when - * two tinc daemons with the same name are on the VPN. - * If so, sleep a while. If this happens multiple times - * in a row, sleep longer. */ - - if(contradicting_del_edge > 100 && contradicting_add_edge > 100) { - logger(LOG_WARNING, "Possible node with same Name as us! Sleeping %d seconds.", sleeptime); - usleep(sleeptime * 1000000LL); - sleeptime *= 2; - - if(sleeptime < 0) { - sleeptime = 3600; - } - } else { - sleeptime /= 2; - - if(sleeptime < 10) { - sleeptime = 10; - } - } - - contradicting_add_edge = 0; - contradicting_del_edge = 0; - } - - 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; - - if(c->status.active) { - send_ping(c); - } - } - - sigalrm = false; - } - - while((event = get_expired_event())) { - event->handler(event->data); - free_event(event); - } - - if(sighup) { - connection_t *c; - avl_node_t *node, *next; - char *fname; - struct stat s; - - sighup = false; - - reopenlogger(); - - /* Reread our own configuration file */ - - exit_configuration(&config_tree); - init_configuration(&config_tree); - - if(!read_server_config()) { - logger(LOG_ERR, "Unable to reread configuration file, exitting."); - return 1; - } - - /* Cancel non-active outgoing connections */ - - for(node = connection_tree->head; node; node = next) { - next = node->next; - c = node->data; - - c->outgoing = NULL; - - if(c->status.connecting) { - terminate_connection(c, false); - connection_del(c); - } - } - - /* Wipe list of outgoing connections */ - - for(list_node_t *node = outgoing_list->head; node; node = node->next) { - outgoing_t *outgoing = node->data; - - if(outgoing->event) { - event_del(outgoing->event); - } - } - - list_delete_list(outgoing_list); - - /* Close connections to hosts that have a changed or deleted host config file */ - - for(node = connection_tree->head; node; node = node->next) { - c = node->data; - - xasprintf(&fname, "%s/hosts/%s", confbase, c->name); - - if(stat(fname, &s) || s.st_mtime > last_config_check) { - terminate_connection(c, c->status.active); - } - - free(fname); - } - - 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(everyone, 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(everyone, subnet); - - if(subnet->owner->status.reachable) { - subnet_update(subnet->owner, subnet, true); - } - } - } - } - - /* Try to make outgoing connections */ - - try_outgoing_connections(); - } - - /* Dump graph if wanted every 60 seconds*/ - - if(last_graph_dump + 60 <= now) { - dump_graph(); - last_graph_dump = now; - } - } - -#ifdef HAVE_PSELECT - /* Restore SIGHUP & SIGALARM mask */ - sigprocmask(SIG_SETMASK, &omask, NULL); -#endif + event_del(&timeout_event); return 0; } diff --git a/src/net.h b/src/net.h index a9becb6..c511a5f 100644 --- a/src/net.h +++ b/src/net.h @@ -1,10 +1,7 @@ -#ifndef TINC_NET_H -#define TINC_NET_H - /* net.h -- header for net.c Copyright (C) 1998-2005 Ivo Timmermans - 2000-2015 Guus Sliepen + 2000-2009 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 @@ -21,20 +18,23 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#include +#ifndef __TINC_NET_H__ +#define __TINC_NET_H__ #include "ipv6.h" +#include "cipher.h" +#include "digest.h" #ifdef ENABLE_JUMBOGRAMS -#define MTU 9018 /* 9000 bytes payload + 14 bytes ethernet header + 4 bytes VLAN tag */ +#define MTU 9018 /* 9000 bytes payload + 14 bytes ethernet header + 4 bytes VLAN tag */ #else -#define MTU 1518 /* 1500 bytes payload + 14 bytes ethernet header + 4 bytes VLAN tag */ +#define MTU 1518 /* 1500 bytes payload + 14 bytes ethernet header + 4 bytes VLAN tag */ #endif -#define MAXSIZE (MTU + 4 + EVP_MAX_BLOCK_LENGTH + EVP_MAX_MD_SIZE + MTU/64 + 20) /* MTU + seqno + padding + HMAC + compressor overhead */ -#define MAXBUFSIZE ((MAXSIZE > 2048 ? MAXSIZE : 2048) + 128) /* Enough room for a request with a MAXSIZEd packet or a 8192 bits RSA key */ +#define MAXSIZE (MTU + 4 + CIPHER_MAX_BLOCK_SIZE + DIGEST_MAX_SIZE + MTU/64 + 20) /* MTU + seqno + padding + HMAC + compressor overhead */ +#define MAXBUFSIZE ((MAXSIZE > 2048 ? MAXSIZE : 2048) + 128) /* Enough room for a request with a MAXSIZEd packet or a 8192 bits RSA key */ -#define MAXSOCKETS 128 /* Overkill... */ +#define MAXSOCKETS 8 /* Probably overkill... */ typedef struct mac_t { uint8_t x[6]; @@ -48,7 +48,7 @@ typedef struct ipv6_t { uint16_t x[8]; } ipv6_t; -typedef uint16_t length_t; +typedef short length_t; #define AF_UNKNOWN 255 @@ -77,17 +77,18 @@ typedef union sockaddr_t { #endif typedef struct vpn_packet_t { - length_t len; /* the actual number of bytes in the `data' field */ - int priority; /* priority or TOS */ - uint32_t seqno; /* 32 bits sequence number (network byte order of course) */ + length_t len; /* the actual number of bytes in the `data' field */ + int priority; /* priority or TOS */ + uint32_t seqno; /* 32 bits sequence number (network byte order of course) */ uint8_t data[MAXSIZE]; } vpn_packet_t; typedef struct listen_socket_t { + struct event ev_tcp; + struct event ev_udp; int tcp; int udp; sockaddr_t sa; - int priority; } listen_socket_t; #include "conf.h" @@ -99,7 +100,7 @@ typedef struct outgoing_t { struct config_t *cfg; struct addrinfo *ai; struct addrinfo *aip; - struct event *event; + struct event ev; } outgoing_t; extern list_t *outgoing_list; @@ -108,49 +109,49 @@ extern int maxoutbufsize; extern int seconds_till_retry; extern int addressfamily; extern unsigned replaywin; -extern bool localdiscovery; extern listen_socket_t listen_socket[MAXSOCKETS]; extern int listen_sockets; -extern int keyexpires; extern int keylifetime; extern int udp_rcvbuf; extern int udp_sndbuf; extern bool do_prune; -extern bool do_purge; extern char *myport; -extern time_t now; extern int contradicting_add_edge; extern int contradicting_del_edge; -extern volatile bool running; - /* Yes, very strange placement indeed, but otherwise the typedefs get all tangled up */ #include "connection.h" #include "node.h" -extern void retry_outgoing(outgoing_t *outgoing); -extern void handle_incoming_vpn_data(int sock); -extern void finish_connecting(struct connection_t *c); -extern void do_outgoing_connection(struct connection_t *c); -extern bool handle_new_meta_connection(int sock); -extern int setup_listen_socket(const sockaddr_t *sa); -extern int setup_vpn_in_socket(const sockaddr_t *sa); -extern void send_packet(const struct node_t *n, vpn_packet_t *packet); -extern void receive_tcppacket(struct connection_t *c, const char *buffer, length_t len); -extern void broadcast_packet(const struct node_t *, vpn_packet_t *packet); -extern char *get_name(void); +extern void retry_outgoing(outgoing_t *); +extern void handle_incoming_vpn_data(int, short, void *); +extern void finish_connecting(struct connection_t *); +extern bool do_outgoing_connection(struct connection_t *); +extern void handle_new_meta_connection(int, short, void *); +extern int setup_listen_socket(const sockaddr_t *); +extern int setup_vpn_in_socket(const sockaddr_t *); +extern void send_packet(struct node_t *, vpn_packet_t *); +extern void receive_tcppacket(struct connection_t *, const char *, int); +extern void broadcast_packet(const struct node_t *, vpn_packet_t *); extern bool setup_network(void); -extern void setup_outgoing_connection(struct outgoing_t *outgoing); +extern void setup_outgoing_connection(struct outgoing_t *); extern void try_outgoing_connections(void); extern void close_network_connections(void); extern int main_loop(void); -extern void terminate_connection(struct connection_t *c, bool report); -extern void flush_queue(struct node_t *n); -extern bool read_rsa_public_key(struct connection_t *c); -extern void send_mtu_probe(struct node_t *n); +extern void terminate_connection(struct connection_t *, bool); +extern void flush_queue(struct node_t *); +extern bool node_read_ecdsa_public_key(struct node_t *); +extern bool read_ecdsa_public_key(struct connection_t *); +extern bool read_rsa_public_key(struct connection_t *); +extern void send_mtu_probe(struct node_t *); +extern void handle_device_data(int, short, void *); +extern void handle_meta_connection_data(int, short, void *); +extern void regenerate_key(void); +extern void purge(void); +extern void retry(void); +extern int reload_configuration(void); extern void load_all_subnets(void); -extern void tarpit(int fd); #ifndef HAVE_MINGW #define closesocket(s) close(s) @@ -158,4 +159,4 @@ extern void tarpit(int fd); extern CRITICAL_SECTION mutex; #endif -#endif +#endif /* __TINC_NET_H__ */ diff --git a/src/net_packet.c b/src/net_packet.c index 938b3b6..3627f31 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-2016 Guus Sliepen + 2000-2011 Guus Sliepen 2010 Timothy Redaelli 2010 Brandon Black @@ -36,12 +36,14 @@ #include LZO1X_H #endif -#include "avl_tree.h" +#include "splay_tree.h" +#include "cipher.h" #include "conf.h" #include "connection.h" +#include "crypto.h" +#include "digest.h" #include "device.h" #include "ethernet.h" -#include "event.h" #include "graph.h" #include "logger.h" #include "net.h" @@ -53,7 +55,6 @@ #include "xalloc.h" 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 @@ -61,33 +62,21 @@ static char lzo_wrkmem[LZO1X_999_MEM_COMPRESS > LZO1X_1_MEM_COMPRESS ? LZO1X_999 static void send_udppacket(node_t *, vpn_packet_t *); unsigned replaywin = 16; -bool localdiscovery = false; #define MAX_SEQNO 1073741824 -/* mtuprobes == 1..30: initial discovery, send bursts with 1 second interval - mtuprobes == 31: sleep pinginterval seconds - mtuprobes == 32: send 1 burst, sleep pingtimeout second - mtuprobes == 33: no response from other side, restart PMTU discovery process +// mtuprobes == 1..30: initial discovery, send bursts with 1 second interval +// mtuprobes == 31: sleep pinginterval seconds +// mtuprobes == 32: send 1 burst, sleep pingtimeout second +// mtuprobes == 33: no response from other side, restart PMTU discovery process - Probes are sent in batches of at least three, with random sizes between the - lower and upper boundaries for the MTU thus far discovered. - - After the initial discovery, a fourth packet is added to each batch with a - size larger than the currently known PMTU, to test if the PMTU has increased. - - In case local discovery is enabled, another packet is added to each batch, - which will be broadcast to the local network. - -*/ - -void send_mtu_probe(node_t *n) { +static void send_mtu_probe_handler(int fd, short events, void *data) { + node_t *n = data; vpn_packet_t packet; int len, i; int timeout = 1; - + n->mtuprobes++; - n->mtuevent = NULL; if(!n->status.reachable || !n->status.validkey) { ifdebug(TRAFFIC) logger(LOG_INFO, "Trying to send MTU probe to unreachable or rekeying node %s (%s)", n->name, n->hostname); @@ -114,12 +103,10 @@ void send_mtu_probe(node_t *n) { } if(n->mtuprobes == 30 || (n->mtuprobes < 30 && n->minmtu >= n->maxmtu)) { - if(n->minmtu > n->maxmtu) { + if(n->minmtu > n->maxmtu) n->minmtu = n->maxmtu; - } else { + else n->maxmtu = n->minmtu; - } - n->mtu = n->minmtu; ifdebug(TRAFFIC) logger(LOG_INFO, "Fixing MTU of %s (%s) to %d after %d probes", n->name, n->hostname, n->mtu, n->mtuprobes); n->mtuprobes = 31; @@ -132,32 +119,19 @@ void send_mtu_probe(node_t *n) { timeout = pingtimeout; } - for(i = 0; i < 4 + localdiscovery; i++) { - if(i == 0) { - if(n->mtuprobes < 30 || n->maxmtu + 8 >= MTU) { - continue; - } - - len = n->maxmtu + 8; - } else if(n->maxmtu <= n->minmtu) { + for(i = 0; i < 3; i++) { + if(n->maxmtu <= n->minmtu) len = n->maxmtu; - } else { + else len = n->minmtu + 1 + rand() % (n->maxmtu - n->minmtu); - } - if(len < 64) { + if(len < 64) len = 64; - } - + memset(packet.data, 0, 14); - RAND_bytes(packet.data + 14, len - 14); + randomize(packet.data + 14, len - 14); packet.len = len; - - if(i >= 4 && n->mtuprobes <= 10) { - packet.priority = -1; - } else { - packet.priority = 0; - } + packet.priority = 0; ifdebug(TRAFFIC) logger(LOG_INFO, "Sending MTU probe length %d to %s (%s)", len, n->name, n->hostname); @@ -165,14 +139,16 @@ void send_mtu_probe(node_t *n) { } end: - n->mtuevent = new_event(); - n->mtuevent->handler = (event_handler_t)send_mtu_probe; - n->mtuevent->data = n; - n->mtuevent->time = now + timeout; - event_add(n->mtuevent); + event_add(&n->mtuevent, &(struct timeval){timeout, 0}); } -void mtu_probe_h(node_t *n, vpn_packet_t *packet, length_t len) { +void send_mtu_probe(node_t *n) { + if(!timeout_initialized(&n->mtuevent)) + timeout_set(&n->mtuevent, send_mtu_probe_handler, n); + send_mtu_probe_handler(0, 0, n); +} + +static void mtu_probe_h(node_t *n, vpn_packet_t *packet, length_t len) { ifdebug(TRAFFIC) logger(LOG_INFO, "Got MTU probe length %d from %s (%s)", packet->len, n->name, n->hostname); if(!packet->data[0]) { @@ -180,27 +156,16 @@ void mtu_probe_h(node_t *n, vpn_packet_t *packet, length_t len) { send_udppacket(n, packet); } else { if(n->mtuprobes > 30) { - if(len == n->maxmtu + 8) { - ifdebug(TRAFFIC) logger(LOG_INFO, "Increase in PMTU to %s (%s) detected, restarting PMTU discovery", n->name, n->hostname); - n->maxmtu = MTU; - n->mtuprobes = 10; - return; - } - - if(n->minmtu) { + if(n->minmtu) n->mtuprobes = 30; - } else { + else n->mtuprobes = 1; - } } - if(len > n->maxmtu) { + if(len > n->maxmtu) len = n->maxmtu; - } - - if(n->minmtu < len) { + if(n->minmtu < len) n->minmtu = len; - } } } @@ -214,28 +179,27 @@ static length_t compress_packet(uint8_t *dest, const uint8_t *source, length_t l lzo1x_1_compress(source, len, dest, &lzolen, lzo_wrkmem); return lzolen; #else - return 0; + return -1; #endif } else if(level < 10) { #ifdef HAVE_ZLIB unsigned long destlen = MAXSIZE; - - if(compress2(dest, &destlen, source, len, level) == Z_OK) { + if(compress2(dest, &destlen, source, len, level) == Z_OK) return destlen; - } else + else #endif - return 0; + return -1; } else { #ifdef HAVE_LZO lzo_uint lzolen = MAXSIZE; lzo1x_999_compress(source, len, dest, &lzolen, lzo_wrkmem); return lzolen; #else - return 0; + return -1; #endif } - - return 0; + + return -1; } static length_t uncompress_packet(uint8_t *dest, const uint8_t *source, length_t len, int level) { @@ -245,25 +209,20 @@ static length_t uncompress_packet(uint8_t *dest, const uint8_t *source, length_t } else if(level > 9) { #ifdef HAVE_LZO lzo_uint lzolen = MAXSIZE; - - if(lzo1x_decompress_safe(source, len, dest, &lzolen, NULL) == LZO_E_OK) { + if(lzo1x_decompress_safe(source, len, dest, &lzolen, NULL) == LZO_E_OK) return lzolen; - } else + else #endif - return 0; + return -1; } - #ifdef HAVE_ZLIB else { unsigned long destlen = MAXSIZE; - - if(uncompress(dest, &destlen, source, len) == Z_OK) { + if(uncompress(dest, &destlen, source, len) == Z_OK) return destlen; - } else { - return 0; - } + else + return -1; } - #endif return -1; @@ -273,104 +232,91 @@ static length_t uncompress_packet(uint8_t *dest, const uint8_t *source, length_t static void receive_packet(node_t *n, vpn_packet_t *packet) { ifdebug(TRAFFIC) logger(LOG_DEBUG, "Received packet of %d bytes from %s (%s)", - packet->len, n->name, n->hostname); + packet->len, n->name, n->hostname); + + n->in_packets++; + n->in_bytes += packet->len; route(n, packet); } -static bool try_mac(const node_t *n, const vpn_packet_t *inpkt) { - unsigned char hmac[EVP_MAX_MD_SIZE]; - - if(!n->indigest || !n->inmaclength || !n->inkey || inpkt->len < sizeof(inpkt->seqno) + n->inmaclength) { +static bool try_mac(node_t *n, const vpn_packet_t *inpkt) { + if(!digest_active(&n->indigest) || inpkt->len < sizeof inpkt->seqno + digest_length(&n->indigest)) return false; - } - HMAC(n->indigest, n->inkey, n->inkeylength, (unsigned char *) &inpkt->seqno, inpkt->len - n->inmaclength, (unsigned char *)hmac, NULL); - - return !memcmp_constant_time(hmac, (char *) &inpkt->seqno + inpkt->len - n->inmaclength, n->inmaclength); + return digest_verify(&n->indigest, &inpkt->seqno, inpkt->len - n->indigest.maclength, (const char *)&inpkt->seqno + inpkt->len - n->indigest.maclength); } static void receive_udppacket(node_t *n, vpn_packet_t *inpkt) { vpn_packet_t pkt1, pkt2; vpn_packet_t *pkt[] = { &pkt1, &pkt2, &pkt1, &pkt2 }; int nextpkt = 0; - vpn_packet_t *outpkt; - int outlen, outpad; - unsigned char hmac[EVP_MAX_MD_SIZE]; + vpn_packet_t *outpkt = pkt[0]; + size_t outlen; - if(!n->inkey) { + if(!cipher_active(&n->incipher)) { ifdebug(TRAFFIC) logger(LOG_DEBUG, "Got packet from %s (%s) but he hasn't got our key yet", - n->name, n->hostname); + n->name, n->hostname); return; } /* Check packet length */ - if(inpkt->len < sizeof(inpkt->seqno) + n->inmaclength) { + if(inpkt->len < sizeof inpkt->seqno + digest_length(&n->indigest)) { ifdebug(TRAFFIC) logger(LOG_DEBUG, "Got too short packet from %s (%s)", - n->name, n->hostname); + n->name, n->hostname); return; } /* Check the message authentication code */ - if(n->indigest && n->inmaclength) { - inpkt->len -= n->inmaclength; - HMAC(n->indigest, n->inkey, n->inkeylength, - (unsigned char *) &inpkt->seqno, inpkt->len, (unsigned char *)hmac, NULL); - - if(memcmp_constant_time(hmac, (char *) &inpkt->seqno + inpkt->len, n->inmaclength)) { - ifdebug(TRAFFIC) logger(LOG_DEBUG, "Got unauthenticated packet from %s (%s)", - n->name, n->hostname); + if(digest_active(&n->indigest)) { + inpkt->len -= n->indigest.maclength; + if(!digest_verify(&n->indigest, &inpkt->seqno, inpkt->len, (const char *)&inpkt->seqno + inpkt->len)) { + ifdebug(TRAFFIC) logger(LOG_DEBUG, "Got unauthenticated packet from %s (%s)", n->name, n->hostname); return; } } - /* Decrypt the packet */ - if(n->incipher) { + if(cipher_active(&n->incipher)) { outpkt = pkt[nextpkt++]; + outlen = MAXSIZE; - if(!EVP_DecryptInit_ex(n->inctx, NULL, NULL, NULL, NULL) - || !EVP_DecryptUpdate(n->inctx, (unsigned char *) &outpkt->seqno, &outlen, - (unsigned char *) &inpkt->seqno, inpkt->len) - || !EVP_DecryptFinal_ex(n->inctx, (unsigned char *) &outpkt->seqno + outlen, &outpad)) { - ifdebug(TRAFFIC) logger(LOG_DEBUG, "Error decrypting packet from %s (%s): %s", - n->name, n->hostname, ERR_error_string(ERR_get_error(), NULL)); + if(!cipher_decrypt(&n->incipher, &inpkt->seqno, inpkt->len, &outpkt->seqno, &outlen, true)) { + ifdebug(TRAFFIC) logger(LOG_DEBUG, "Error decrypting packet from %s (%s)", n->name, n->hostname); return; } - - outpkt->len = outlen + outpad; + + outpkt->len = outlen; inpkt = outpkt; } /* Check the sequence number */ - inpkt->len -= sizeof(inpkt->seqno); + inpkt->len -= sizeof inpkt->seqno; inpkt->seqno = ntohl(inpkt->seqno); if(replaywin) { if(inpkt->seqno != n->received_seqno + 1) { if(inpkt->seqno >= n->received_seqno + replaywin * 8) { if(n->farfuture++ < replaywin >> 2) { - ifdebug(TRAFFIC) logger(LOG_WARNING, "Packet from %s (%s) is %d seqs in the future, dropped (%u)", - n->name, n->hostname, inpkt->seqno - n->received_seqno - 1, n->farfuture); + logger(LOG_WARNING, "Packet from %s (%s) is %d seqs in the future, dropped (%u)", + n->name, n->hostname, inpkt->seqno - n->received_seqno - 1, n->farfuture); return; } - - ifdebug(TRAFFIC) logger(LOG_WARNING, "Lost %d packets from %s (%s)", - inpkt->seqno - n->received_seqno - 1, n->name, n->hostname); + logger(LOG_WARNING, "Lost %d packets from %s (%s)", + inpkt->seqno - n->received_seqno - 1, n->name, n->hostname); memset(n->late, 0, replaywin); - } else if(inpkt->seqno <= n->received_seqno) { + } else if (inpkt->seqno <= n->received_seqno) { if((n->received_seqno >= replaywin * 8 && inpkt->seqno <= n->received_seqno - replaywin * 8) || !(n->late[(inpkt->seqno / 8) % replaywin] & (1 << inpkt->seqno % 8))) { - ifdebug(TRAFFIC) logger(LOG_WARNING, "Got late or replayed packet from %s (%s), seqno %d, last received %d", - n->name, n->hostname, inpkt->seqno, n->received_seqno); + logger(LOG_WARNING, "Got late or replayed packet from %s (%s), seqno %d, last received %d", + n->name, n->hostname, inpkt->seqno, n->received_seqno); return; } } else { - for(uint32_t i = n->received_seqno + 1; i < inpkt->seqno; i++) { + for(int i = n->received_seqno + 1; i < inpkt->seqno; i++) n->late[(i / 8) % replaywin] |= 1 << i % 8; - } } } @@ -378,13 +324,11 @@ static void receive_udppacket(node_t *n, vpn_packet_t *inpkt) { n->late[(inpkt->seqno / 8) % replaywin] &= ~(1 << inpkt->seqno % 8); } - if(inpkt->seqno > n->received_seqno) { + if(inpkt->seqno > n->received_seqno) n->received_seqno = inpkt->seqno; - } - - if(n->received_seqno > MAX_SEQNO) { - keyexpires = 0; - } + + if(n->received_seqno > MAX_SEQNO) + regenerate_key(); /* Decompress the packet */ @@ -393,41 +337,33 @@ static void receive_udppacket(node_t *n, vpn_packet_t *inpkt) { if(n->incompression) { outpkt = pkt[nextpkt++]; - if(!(outpkt->len = uncompress_packet(outpkt->data, inpkt->data, inpkt->len, n->incompression))) { + if((outpkt->len = uncompress_packet(outpkt->data, inpkt->data, inpkt->len, n->incompression)) < 0) { ifdebug(TRAFFIC) logger(LOG_ERR, "Error while uncompressing packet from %s (%s)", - n->name, n->hostname); + n->name, n->hostname); return; } inpkt = outpkt; - origlen -= MTU / 64 + 20; + origlen -= MTU/64 + 20; } inpkt->priority = 0; - if(!inpkt->data[12] && !inpkt->data[13]) { + if(!inpkt->data[12] && !inpkt->data[13]) mtu_probe_h(n, inpkt, origlen); - } else { + else receive_packet(n, inpkt); - } } -void receive_tcppacket(connection_t *c, const char *buffer, length_t len) { +void receive_tcppacket(connection_t *c, const char *buffer, int len) { vpn_packet_t outpkt; - if(len > sizeof(outpkt.data)) { - return; - } - outpkt.len = len; - - if(c->options & OPTION_TCPONLY) { + if(c->options & OPTION_TCPONLY) outpkt.priority = 0; - } else { + else outpkt.priority = -1; - } - memcpy(outpkt.data, buffer, len); receive_packet(c->node, &outpkt); @@ -439,9 +375,13 @@ static void send_udppacket(node_t *n, vpn_packet_t *origpkt) { vpn_packet_t *inpkt = origpkt; int nextpkt = 0; vpn_packet_t *outpkt; - int origlen; - int outlen, outpad; - int origpriority; + int origlen = origpkt->len; + size_t outlen; +#if defined(SOL_IP) && defined(IP_TOS) + static int priority = 0; + int origpriority = origpkt->priority; +#endif + int sock; if(!n->status.reachable) { ifdebug(TRAFFIC) logger(LOG_INFO, "Trying to send UDP packet to unreachable node %s (%s)", n->name, n->hostname); @@ -451,9 +391,11 @@ static void send_udppacket(node_t *n, vpn_packet_t *origpkt) { /* Make sure we have a valid key */ if(!n->status.validkey) { + time_t now = time(NULL); + ifdebug(TRAFFIC) logger(LOG_INFO, - "No valid key known yet for %s (%s), forwarding via TCP", - n->name, n->hostname); + "No valid key known yet for %s (%s), forwarding via TCP", + n->name, n->hostname); if(n->last_req_key + 10 <= now) { send_req_key(n); @@ -467,29 +409,25 @@ static void send_udppacket(node_t *n, vpn_packet_t *origpkt) { if(n->options & OPTION_PMTU_DISCOVERY && inpkt->len > n->minmtu && (inpkt->data[12] | inpkt->data[13])) { ifdebug(TRAFFIC) logger(LOG_INFO, - "Packet for %s (%s) larger than minimum MTU, forwarding via %s", - n->name, n->hostname, n != n->nexthop ? n->nexthop->name : "TCP"); + "Packet for %s (%s) larger than minimum MTU, forwarding via %s", + n->name, n->hostname, n != n->nexthop ? n->nexthop->name : "TCP"); - if(n != n->nexthop) { + if(n != n->nexthop) send_packet(n->nexthop, origpkt); - } else { + else send_tcppacket(n->nexthop->connection, origpkt); - } return; } - origlen = inpkt->len; - origpriority = inpkt->priority; - /* Compress the packet */ if(n->outcompression) { outpkt = pkt[nextpkt++]; - if(!(outpkt->len = compress_packet(outpkt->data, inpkt->data, inpkt->len, n->outcompression))) { + if((outpkt->len = compress_packet(outpkt->data, inpkt->data, inpkt->len, n->outcompression)) < 0) { ifdebug(TRAFFIC) logger(LOG_ERR, "Error while compressing packet to %s (%s)", - n->name, n->hostname); + n->name, n->hostname); return; } @@ -499,127 +437,59 @@ static void send_udppacket(node_t *n, vpn_packet_t *origpkt) { /* Add sequence number */ inpkt->seqno = htonl(++(n->sent_seqno)); - inpkt->len += sizeof(inpkt->seqno); + inpkt->len += sizeof inpkt->seqno; /* Encrypt the packet */ - if(n->outcipher) { + if(cipher_active(&n->outcipher)) { outpkt = pkt[nextpkt++]; + outlen = MAXSIZE; - if(!EVP_EncryptInit_ex(n->outctx, NULL, NULL, NULL, NULL) - || !EVP_EncryptUpdate(n->outctx, (unsigned char *) &outpkt->seqno, &outlen, - (unsigned char *) &inpkt->seqno, inpkt->len) - || !EVP_EncryptFinal_ex(n->outctx, (unsigned char *) &outpkt->seqno + outlen, &outpad)) { - ifdebug(TRAFFIC) logger(LOG_ERR, "Error while encrypting packet to %s (%s): %s", - n->name, n->hostname, ERR_error_string(ERR_get_error(), NULL)); + if(!cipher_encrypt(&n->outcipher, &inpkt->seqno, inpkt->len, &outpkt->seqno, &outlen, true)) { + ifdebug(TRAFFIC) logger(LOG_ERR, "Error while encrypting packet to %s (%s)", n->name, n->hostname); goto end; } - outpkt->len = outlen + outpad; + outpkt->len = outlen; inpkt = outpkt; } /* Add the message authentication code */ - if(n->outdigest && n->outmaclength) { - HMAC(n->outdigest, n->outkey, n->outkeylength, (unsigned char *) &inpkt->seqno, - inpkt->len, (unsigned char *) &inpkt->seqno + inpkt->len, NULL); - inpkt->len += n->outmaclength; + if(digest_active(&n->outdigest)) { + digest_create(&n->outdigest, &inpkt->seqno, inpkt->len, (char *)&inpkt->seqno + inpkt->len); + inpkt->len += digest_length(&n->outdigest); } /* Determine which socket we have to use */ - if(n->address.sa.sa_family != listen_socket[n->sock].sa.sa.sa_family) { - for(int sock = 0; sock < listen_sockets; sock++) { - if(n->address.sa.sa_family == listen_socket[sock].sa.sa.sa_family) { - n->sock = sock; - break; - } - } - } + for(sock = 0; sock < listen_sockets; sock++) + if(n->address.sa.sa_family == listen_socket[sock].sa.sa.sa_family) + break; + + if(sock >= listen_sockets) + sock = 0; /* If none is available, just use the first and hope for the best. */ /* Send the packet */ - struct sockaddr *sa; - socklen_t sl; - int sock; - sockaddr_t broadcast; - - /* Overloaded use of priority field: -1 means local broadcast */ - - if(origpriority == -1 && n->prevedge) { - sock = rand() % listen_sockets; - memset(&broadcast, 0, sizeof(broadcast)); - - if(listen_socket[sock].sa.sa.sa_family == AF_INET6) { - broadcast.in6.sin6_family = AF_INET6; - broadcast.in6.sin6_addr.s6_addr[0x0] = 0xff; - broadcast.in6.sin6_addr.s6_addr[0x1] = 0x02; - broadcast.in6.sin6_addr.s6_addr[0xf] = 0x01; - broadcast.in6.sin6_port = n->prevedge->address.in.sin_port; - broadcast.in6.sin6_scope_id = listen_socket[sock].sa.in6.sin6_scope_id; - } else { - broadcast.in.sin_family = AF_INET; - broadcast.in.sin_addr.s_addr = -1; - broadcast.in.sin_port = n->prevedge->address.in.sin_port; - } - - sa = &broadcast.sa; - sl = SALEN(broadcast.sa); - } else { - if(origpriority == -1) { - origpriority = 0; - } - - sa = &(n->address.sa); - sl = SALEN(n->address.sa); - sock = n->sock; +#if defined(SOL_IP) && defined(IP_TOS) + if(priorityinheritance && origpriority != priority + && listen_socket[sock].sa.sa.sa_family == AF_INET) { + priority = origpriority; + ifdebug(TRAFFIC) logger(LOG_DEBUG, "Setting outgoing packet priority to %d", priority); + if(setsockopt(listen_socket[sock].udp, SOL_IP, IP_TOS, &priority, sizeof priority)) /* SO_PRIORITY doesn't seem to work */ + logger(LOG_ERR, "System call `%s' failed: %s", "setsockopt", strerror(errno)); } - - if(priorityinheritance && origpriority != listen_socket[n->sock].priority) { - listen_socket[n->sock].priority = origpriority; - - switch(listen_socket[n->sock].sa.sa.sa_family) { -#if defined(IP_TOS) - - case AF_INET: - ifdebug(TRAFFIC) logger(LOG_DEBUG, "Setting IPv4 outgoing packet priority to %d", origpriority); - - if(setsockopt(listen_socket[n->sock].udp, IPPROTO_IP, IP_TOS, (void *)&origpriority, sizeof(origpriority))) { /* SO_PRIORITY doesn't seem to work */ - logger(LOG_ERR, "System call `%s' failed: %s", "setsockopt", strerror(errno)); - } - - break; -#endif -#if defined(IPV6_TCLASS) - - case AF_INET6: - ifdebug(TRAFFIC) logger(LOG_DEBUG, "Setting IPv6 outgoing packet priority to %d", origpriority); - - if(setsockopt(listen_socket[n->sock].udp, IPPROTO_IPV6, IPV6_TCLASS, (void *)&origpriority, sizeof(origpriority))) { - logger(LOG_ERR, "System call `%s' failed: %s", "setsockopt", strerror(errno)); - } - - break; #endif - default: - break; - } - } - - if(sendto(listen_socket[sock].udp, (char *) &inpkt->seqno, inpkt->len, 0, sa, sl) < 0 && !sockwouldblock(sockerrno)) { + if(sendto(listen_socket[sock].udp, (char *) &inpkt->seqno, inpkt->len, 0, &(n->address.sa), SALEN(n->address.sa)) < 0 && !sockwouldblock(sockerrno)) { if(sockmsgsize(sockerrno)) { - if(n->maxmtu >= origlen) { + if(n->maxmtu >= origlen) n->maxmtu = origlen - 1; - } - - if(n->mtu >= origlen) { + if(n->mtu >= origlen) n->mtu = origlen - 1; - } - } else { - ifdebug(TRAFFIC) logger(LOG_WARNING, "Error sending packet to %s (%s): %s", n->name, n->hostname, sockstrerror(sockerrno)); - } + } else + logger(LOG_ERR, "Error sending packet to %s (%s): %s", n->name, n->hostname, sockstrerror(sockerrno)); } end: @@ -629,170 +499,154 @@ end: /* send a packet to the given vpn ip. */ -void send_packet(const node_t *n, vpn_packet_t *packet) { +void send_packet(node_t *n, vpn_packet_t *packet) { node_t *via; if(n == myself) { - if(overwrite_mac) { - memcpy(packet->data, mymac.x, ETH_ALEN); - } - - devops.write(packet); + if(overwrite_mac) + memcpy(packet->data, mymac.x, ETH_ALEN); + n->out_packets++; + n->out_bytes += packet->len; + write_packet(packet); return; } ifdebug(TRAFFIC) logger(LOG_ERR, "Sending packet of %d bytes to %s (%s)", - packet->len, n->name, n->hostname); + packet->len, n->name, n->hostname); if(!n->status.reachable) { ifdebug(TRAFFIC) logger(LOG_INFO, "Node %s (%s) is not reachable", - n->name, n->hostname); + n->name, n->hostname); return; } + n->out_packets++; + n->out_bytes += packet->len; + via = (packet->priority == -1 || n->via == myself) ? n->nexthop : n->via; if(via != n) ifdebug(TRAFFIC) logger(LOG_INFO, "Sending packet to %s via %s (%s)", - n->name, via->name, n->via->hostname); + n->name, via->name, n->via->hostname); if(packet->priority == -1 || ((myself->options | via->options) & OPTION_TCPONLY)) { - if(!send_tcppacket(via->connection, packet)) { + if(!send_tcppacket(via->connection, packet)) terminate_connection(via->connection, true); - } - } else { + } else send_udppacket(via, packet); - } } /* Broadcast a packet using the minimum spanning tree */ void broadcast_packet(const node_t *from, vpn_packet_t *packet) { - avl_node_t *node; + splay_node_t *node; connection_t *c; - node_t *n; - - // Always give ourself a copy of the packet. - if(from != myself) { - send_packet(myself, packet); - } - - // In TunnelServer mode, do not forward broadcast packets. - // The MST might not be valid and create loops. - if(tunnelserver || broadcast_mode == BMODE_NONE) { - return; - } ifdebug(TRAFFIC) logger(LOG_INFO, "Broadcasting packet of %d bytes from %s (%s)", - packet->len, from->name, from->hostname); + packet->len, from->name, from->hostname); - switch(broadcast_mode) { - // In MST mode, broadcast packets travel via the Minimum Spanning Tree. - // This guarantees all nodes receive the broadcast packet, and - // usually distributes the sending of broadcast packets over all nodes. - case BMODE_MST: - for(node = connection_tree->head; node; node = node->next) { - c = node->data; + if(from != myself) { + send_packet(myself, packet); - if(c->status.active && c->status.mst && c != from->nexthop->connection) { - send_packet(c->node, packet); - } - } + // In TunnelServer mode, do not forward broadcast packets. + // The MST might not be valid and create loops. + if(tunnelserver) + return; + } - break; + for(node = connection_tree->head; node; node = node->next) { + c = node->data; - // In direct mode, we send copies to each node we know of. - // However, this only reaches nodes that can be reached in a single hop. - // We don't have enough information to forward broadcast packets in this case. - case BMODE_DIRECT: - if(from != myself) { - break; - } - - for(node = node_udp_tree->head; node; node = node->next) { - n = node->data; - - if(n->status.reachable && n != myself && ((n->via == myself && n->nexthop == n) || n->via == n)) { - send_packet(n, packet); - } - } - - break; - - default: - break; + if(c->status.active && c->status.mst && c != from->nexthop->connection) + send_packet(c->node, packet); } } static node_t *try_harder(const sockaddr_t *from, const vpn_packet_t *pkt) { - avl_node_t *node; + splay_node_t *node; edge_t *e; node_t *n = NULL; + bool hard = false; static time_t last_hard_try = 0; + time_t now = time(NULL); + + if(last_hard_try == now) + return NULL; + else + last_hard_try = now; for(node = edge_weight_tree->head; node; node = node->next) { e = node->data; - if(e->to == myself) { + if(e->to == myself) continue; + + if(sockaddrcmp_noport(from, &e->address)) { + if(last_hard_try == now) + continue; + hard = true; } - if(last_hard_try == now && sockaddrcmp_noport(from, &e->address)) { + if(!try_mac(e->to, pkt)) continue; - } - - if(!try_mac(e->to, pkt)) { - continue; - } n = e->to; break; } - last_hard_try = now; + if(hard) + last_hard_try = now; + return n; } -void handle_incoming_vpn_data(int sock) { +void handle_incoming_vpn_data(int sock, short events, void *data) { vpn_packet_t pkt; char *hostname; sockaddr_t from; - socklen_t fromlen = sizeof(from); + socklen_t fromlen = sizeof from; node_t *n; + int len; - ssize_t len = recvfrom(listen_socket[sock].udp, (char *) &pkt.seqno, MAXSIZE, 0, &from.sa, &fromlen); + len = recvfrom(sock, (char *) &pkt.seqno, MAXSIZE, 0, &from.sa, &fromlen); - if(len <= 0 || len > UINT16_MAX) { - if(len >= 0) { - logger(LOG_ERR, "Receiving packet with invalid size"); - } else if(!sockwouldblock(sockerrno)) { + if(len <= 0 || len > MAXSIZE) { + if(!sockwouldblock(sockerrno)) logger(LOG_ERR, "Receiving packet failed: %s", sockstrerror(sockerrno)); - } - return; } pkt.len = len; - sockaddrunmap(&from); /* Some braindead IPv6 implementations do stupid things. */ + + sockaddrunmap(&from); /* Some braindead IPv6 implementations do stupid things. */ n = lookup_node_udp(&from); if(!n) { n = try_harder(&from, &pkt); - - if(n) { + if(n) update_node_udp(n, &from); - } else ifdebug(PROTOCOL) { + else ifdebug(PROTOCOL) { hostname = sockaddr2hostname(&from); logger(LOG_WARNING, "Received UDP packet from unknown source %s", hostname); free(hostname); return; - } else { - return; } + else + return; } - n->sock = sock; - receive_udppacket(n, &pkt); } + +void handle_device_data(int sock, short events, void *data) { + vpn_packet_t packet; + + packet.priority = 0; + + if(read_packet(&packet)) { + myself->in_packets++; + myself->in_bytes += packet.len; + route(myself, &packet); + } +} diff --git a/src/net_setup.c b/src/net_setup.c index cac7455..91f7609 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-2017 Guus Sliepen + 2000-2010 Guus Sliepen 2006 Scott Lamb 2010 Brandon Black @@ -22,219 +22,165 @@ #include "system.h" -#include -#include -#include -#include -#include - -#include "avl_tree.h" +#include "splay_tree.h" +#include "cipher.h" #include "conf.h" #include "connection.h" +#include "control.h" #include "device.h" -#include "event.h" +#include "digest.h" +#include "ecdsa.h" #include "graph.h" #include "logger.h" #include "net.h" #include "netutl.h" #include "process.h" #include "protocol.h" -#include "proxy.h" #include "route.h" +#include "rsa.h" #include "subnet.h" #include "utils.h" #include "xalloc.h" char *myport; -devops_t devops; +static struct event device_ev; -#ifndef HAVE_RSA_SET0_KEY -int RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d) { - BN_free(r->n); - r->n = n; - BN_free(r->e); - r->e = e; - BN_free(r->d); - r->d = d; - return 1; -} -#endif +bool node_read_ecdsa_public_key(node_t *n) { + if(ecdsa_active(&n->ecdsa)) + return true; -bool read_rsa_public_key(connection_t *c) { + splay_tree_t *config_tree; FILE *fp; - char *pubname; - char *hcfname; - char *key; - BIGNUM *n = NULL; - BIGNUM *e = NULL; + char *fname; + char *p; + bool result = false; - if(!c->rsa_key) { - c->rsa_key = RSA_new(); -// RSA_blinding_on(c->rsa_key, NULL); + xasprintf(&fname, "%s/hosts/%s", confbase, n->name); + + init_configuration(&config_tree); + if(!read_config_file(config_tree, fname)) + goto exit; + + /* First, check for simple ECDSAPublicKey statement */ + + if(get_config_string(lookup_config(config_tree, "ECDSAPublicKey"), &p)) { + result = ecdsa_set_base64_public_key(&n->ecdsa, p); + free(p); + goto exit; } - /* First, check for simple PublicKey statement */ + /* Else, check for ECDSAPublicKeyFile statement and read it */ - if(get_config_string(lookup_config(c->config_tree, "PublicKey"), &key)) { - if((size_t)BN_hex2bn(&n, key) != strlen(key)) { - free(key); - logger(LOG_ERR, "Invalid PublicKey for %s!", c->name); - return false; - } + free(fname); - free(key); - BN_hex2bn(&e, "FFFF"); - - if(!n || !e || RSA_set0_key(c->rsa_key, n, e, NULL) != 1) { - BN_free(e); - BN_free(n); - logger(LOG_ERR, "RSA_set0_key() failed with PublicKey for %s!", c->name); - return false; - } - - return true; - } - - /* Else, check for PublicKeyFile statement and read it */ - - if(get_config_string(lookup_config(c->config_tree, "PublicKeyFile"), &pubname)) { - fp = fopen(pubname, "r"); - - if(!fp) { - logger(LOG_ERR, "Error reading RSA public key file `%s': %s", pubname, strerror(errno)); - free(pubname); - return false; - } - - c->rsa_key = PEM_read_RSAPublicKey(fp, &c->rsa_key, NULL, NULL); - fclose(fp); - - if(c->rsa_key) { - free(pubname); - return true; /* Woohoo. */ - } - - /* If it fails, try PEM_read_RSA_PUBKEY. */ - fp = fopen(pubname, "r"); - - if(!fp) { - logger(LOG_ERR, "Error reading RSA public key file `%s': %s", pubname, strerror(errno)); - free(pubname); - return false; - } - - c->rsa_key = PEM_read_RSA_PUBKEY(fp, &c->rsa_key, NULL, NULL); - fclose(fp); - - if(c->rsa_key) { -// RSA_blinding_on(c->rsa_key, NULL); - free(pubname); - return true; - } - - logger(LOG_ERR, "Reading RSA public key file `%s' failed: %s", pubname, strerror(errno)); - free(pubname); - return false; - } - - /* Else, check if a harnessed public key is in the config file */ - - xasprintf(&hcfname, "%s/hosts/%s", confbase, c->name); - fp = fopen(hcfname, "r"); - - if(!fp) { - logger(LOG_ERR, "Error reading RSA public key file `%s': %s", hcfname, strerror(errno)); - free(hcfname); - return false; - } - - c->rsa_key = PEM_read_RSAPublicKey(fp, &c->rsa_key, NULL, NULL); - fclose(fp); - - if(c->rsa_key) { - free(hcfname); - return true; - } - - /* Try again with PEM_read_RSA_PUBKEY. */ - - fp = fopen(hcfname, "r"); - - if(!fp) { - logger(LOG_ERR, "Error reading RSA public key file `%s': %s", hcfname, strerror(errno)); - free(hcfname); - return false; - } - - free(hcfname); - c->rsa_key = PEM_read_RSA_PUBKEY(fp, &c->rsa_key, NULL, NULL); -// RSA_blinding_on(c->rsa_key, NULL); - fclose(fp); - - if(c->rsa_key) { - return true; - } - - logger(LOG_ERR, "No public key for %s specified!", c->name); - - return false; -} - -static bool read_rsa_private_key(void) { - FILE *fp; - char *fname, *key, *pubkey; - BIGNUM *n = NULL; - BIGNUM *e = NULL; - BIGNUM *d = NULL; - - if(get_config_string(lookup_config(config_tree, "PrivateKey"), &key)) { - myself->connection->rsa_key = RSA_new(); - -// RSA_blinding_on(myself->connection->rsa_key, NULL); - if((size_t)BN_hex2bn(&d, key) != strlen(key)) { - logger(LOG_ERR, "Invalid PrivateKey for myself!"); - free(key); - return false; - } - - free(key); - - if(!get_config_string(lookup_config(config_tree, "PublicKey"), &pubkey)) { - BN_free(d); - logger(LOG_ERR, "PrivateKey used but no PublicKey found!"); - return false; - } - - if((size_t)BN_hex2bn(&n, pubkey) != strlen(pubkey)) { - free(pubkey); - BN_free(d); - logger(LOG_ERR, "Invalid PublicKey for myself!"); - return false; - } - - free(pubkey); - BN_hex2bn(&e, "FFFF"); - - if(!n || !e || !d || RSA_set0_key(myself->connection->rsa_key, n, e, d) != 1) { - BN_free(d); - BN_free(e); - BN_free(n); - logger(LOG_ERR, "RSA_set0_key() failed with PrivateKey for myself!"); - return false; - } - - return true; - } - - if(!get_config_string(lookup_config(config_tree, "PrivateKeyFile"), &fname)) { - xasprintf(&fname, "%s/rsa_key.priv", confbase); - } + if(!get_config_string(lookup_config(config_tree, "ECDSAPublicKeyFile"), &fname)) + xasprintf(&fname, "%s/hosts/%s", confbase, n->name); fp = fopen(fname, "r"); if(!fp) { - logger(LOG_ERR, "Error reading RSA private key file `%s': %s", - fname, strerror(errno)); + logger(LOG_ERR, "Error reading ECDSA public key file `%s': %s", fname, strerror(errno)); + goto exit; + } + + result = ecdsa_read_pem_public_key(&n->ecdsa, fp); + fclose(fp); + +exit: + exit_configuration(&config_tree); + free(fname); + return result; +} + +bool read_ecdsa_public_key(connection_t *c) { + FILE *fp; + char *fname; + char *p; + bool result; + + /* First, check for simple ECDSAPublicKey statement */ + + if(get_config_string(lookup_config(c->config_tree, "ECDSAPublicKey"), &p)) { + result = ecdsa_set_base64_public_key(&c->ecdsa, p); + free(p); + return result; + } + + /* Else, check for ECDSAPublicKeyFile statement and read it */ + + if(!get_config_string(lookup_config(c->config_tree, "ECDSAPublicKeyFile"), &fname)) + xasprintf(&fname, "%s/hosts/%s", confbase, c->name); + + fp = fopen(fname, "r"); + + if(!fp) { + logger(LOG_ERR, "Error reading ECDSA public key file `%s': %s", + fname, strerror(errno)); + free(fname); + return false; + } + + result = ecdsa_read_pem_public_key(&c->ecdsa, fp); + fclose(fp); + + if(!result) + logger(LOG_ERR, "Reading ECDSA public key file `%s' failed: %s", fname, strerror(errno)); + free(fname); + return result; +} + +bool read_rsa_public_key(connection_t *c) { + FILE *fp; + char *fname; + char *n; + bool result; + + /* First, check for simple PublicKey statement */ + + if(get_config_string(lookup_config(c->config_tree, "PublicKey"), &n)) { + result = rsa_set_hex_public_key(&c->rsa, n, "FFFF"); + free(n); + return result; + } + + /* Else, check for PublicKeyFile statement and read it */ + + if(!get_config_string(lookup_config(c->config_tree, "PublicKeyFile"), &fname)) + xasprintf(&fname, "%s/hosts/%s", confbase, c->name); + + fp = fopen(fname, "r"); + + if(!fp) { + logger(LOG_ERR, "Error reading RSA public key file `%s': %s", + fname, strerror(errno)); + free(fname); + return false; + } + + result = rsa_read_pem_public_key(&c->rsa, fp); + fclose(fp); + + if(!result) + logger(LOG_ERR, "Reading RSA public key file `%s' failed: %s", fname, strerror(errno)); + free(fname); + return result; +} + +static bool read_ecdsa_private_key(void) { + FILE *fp; + char *fname; + bool result; + + /* Check for PrivateKeyFile statement and read it */ + + if(!get_config_string(lookup_config(config_tree, "ECDSAPrivateKeyFile"), &fname)) + xasprintf(&fname, "%s/ecdsa_key.priv", confbase); + + fp = fopen(fname, "r"); + + if(!fp) { + logger(LOG_ERR, "Error reading ECDSA private key file `%s': %s", + fname, strerror(errno)); free(fname); return false; } @@ -242,28 +188,97 @@ static bool read_rsa_private_key(void) { #if !defined(HAVE_MINGW) && !defined(HAVE_CYGWIN) struct stat s; - if(!fstat(fileno(fp), &s)) { - if(s.st_mode & ~0100700) { - logger(LOG_WARNING, "Warning: insecure file permissions for RSA private key file `%s'!", fname); - } - } else { - logger(LOG_WARNING, "Could not stat RSA private key file `%s': %s'", fname, strerror(errno)); - } - -#endif - - myself->connection->rsa_key = PEM_read_RSAPrivateKey(fp, NULL, NULL, NULL); - fclose(fp); - - if(!myself->connection->rsa_key) { - logger(LOG_ERR, "Reading RSA private key file `%s' failed: %s", - fname, strerror(errno)); + if(fstat(fileno(fp), &s)) { + logger(LOG_ERR, "Could not stat ECDSA private key file `%s': %s'", fname, strerror(errno)); free(fname); return false; } + if(s.st_mode & ~0100700) + logger(LOG_WARNING, "Warning: insecure file permissions for ECDSA private key file `%s'!", fname); +#endif + + result = ecdsa_read_pem_private_key(&myself->connection->ecdsa, fp); + fclose(fp); + + if(!result) + logger(LOG_ERR, "Reading ECDSA private key file `%s' failed: %s", fname, strerror(errno)); free(fname); - return true; + return result; +} + +static bool read_rsa_private_key(void) { + FILE *fp; + char *fname; + char *n, *d; + bool result; + + /* First, check for simple PrivateKey statement */ + + if(get_config_string(lookup_config(config_tree, "PrivateKey"), &d)) { + if(!get_config_string(lookup_config(config_tree, "PublicKey"), &n)) { + logger(LOG_ERR, "PrivateKey used but no PublicKey found!"); + free(d); + return false; + } + result = rsa_set_hex_private_key(&myself->connection->rsa, n, "FFFF", d); + free(n); + free(d); + return true; + } + + /* Else, check for PrivateKeyFile statement and read it */ + + if(!get_config_string(lookup_config(config_tree, "PrivateKeyFile"), &fname)) + xasprintf(&fname, "%s/rsa_key.priv", confbase); + + fp = fopen(fname, "r"); + + if(!fp) { + logger(LOG_ERR, "Error reading RSA private key file `%s': %s", + fname, strerror(errno)); + free(fname); + return false; + } + +#if !defined(HAVE_MINGW) && !defined(HAVE_CYGWIN) + struct stat s; + + if(fstat(fileno(fp), &s)) { + logger(LOG_ERR, "Could not stat RSA private key file `%s': %s'", fname, strerror(errno)); + free(fname); + return false; + } + + if(s.st_mode & ~0100700) + logger(LOG_WARNING, "Warning: insecure file permissions for RSA private key file `%s'!", fname); +#endif + + result = rsa_read_pem_private_key(&myself->connection->rsa, fp); + fclose(fp); + + if(!result) + logger(LOG_ERR, "Reading RSA private key file `%s' failed: %s", fname, strerror(errno)); + free(fname); + return result; +} + +static struct event keyexpire_event; + +static void keyexpire_handler(int fd, short events, void *data) { + regenerate_key(); +} + +void regenerate_key(void) { + if(timeout_initialized(&keyexpire_event)) { + ifdebug(STATUS) logger(LOG_INFO, "Expiring symmetric keys"); + event_del(&keyexpire_event); + send_key_changed(); + } else { + timeout_set(&keyexpire_event, keyexpire_handler, NULL); + } + + event_add(&keyexpire_event, &(struct timeval){keylifetime, 0}); } /* @@ -274,14 +289,14 @@ void load_all_subnets(void) { struct dirent *ent; char *dname; char *fname; - avl_tree_t *config_tree; + splay_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); @@ -289,21 +304,21 @@ void load_all_subnets(void) { } while((ent = readdir(dir))) { - if(!check_id(ent->d_name)) { + if(!check_id(ent->d_name)) continue; - } n = lookup_node(ent->d_name); -#ifdef _DIRENT_HAVE_D_TYPE + #ifdef _DIRENT_HAVE_D_TYPE //if(ent->d_type != DT_REG) - // continue; -#endif + // continue; + #endif xasprintf(&fname, "%s/hosts/%s", confbase, ent->d_name); init_configuration(&config_tree); - read_config_options(config_tree, ent->d_name); - read_config_file(config_tree, fname); + result = read_config_file(config_tree, fname); free(fname); + if(!result) + continue; if(!n) { n = new_node(); @@ -312,9 +327,8 @@ void load_all_subnets(void) { } for(cfg = lookup_config(config_tree, "Subnet"); cfg; cfg = lookup_config_next(config_tree, cfg)) { - if(!get_config_subnet(cfg, &s)) { + if(!get_config_subnet(cfg, &s)) continue; - } if((s2 = lookup_subnet(n, s))) { s2->expires = -1; @@ -329,71 +343,20 @@ void load_all_subnets(void) { closedir(dir); } -char *get_name(void) { - char *name = NULL; - - get_config_string(lookup_config(config_tree, "Name"), &name); - - if(!name) { - return NULL; - } - - if(*name == '$') { - char *envname = getenv(name + 1); - char hostname[32] = ""; - - if(!envname) { - if(strcmp(name + 1, "HOST")) { - fprintf(stderr, "Invalid Name: environment variable %s does not exist\n", name + 1); - free(name); - return false; - } - - if(gethostname(hostname, sizeof(hostname)) || !*hostname) { - fprintf(stderr, "Could not get hostname: %s\n", strerror(errno)); - free(name); - return false; - } - - hostname[31] = 0; - envname = hostname; - } - - free(name); - name = xstrdup(envname); - - for(char *c = name; *c; c++) - if(!isalnum(*c)) { - *c = '_'; - } - } - - if(!check_id(name)) { - logger(LOG_ERR, "Invalid name for myself!"); - free(name); - return false; - } - - return name; -} - /* Configure node_t myself and set up the local sockets (listen only) */ static bool setup_myself(void) { config_t *cfg; subnet_t *subnet; - char *name, *hostname, *mode, *afname, *cipher, *digest, *type; + char *name, *hostname, *mode, *afname, *cipher, *digest; char *fname = NULL; char *address = NULL; - char *proxy = NULL; - char *space; - char *envp[5] = {0}; + char *envp[5]; struct addrinfo *ai, *aip, hint = {0}; bool choice; int i, err; int replaywin_int; - bool port_specified = false; myself = new_node(); myself->connection = new_connection(); @@ -402,14 +365,19 @@ static bool setup_myself(void) { myself->connection->hostname = xstrdup("MYSELF"); myself->connection->options = 0; - myself->connection->protocol_version = PROT_CURRENT; + myself->connection->protocol_major = PROT_MAJOR; + myself->connection->protocol_minor = PROT_MINOR; - if(!(name = get_name())) { + if(!get_config_string(lookup_config(config_tree, "Name"), &name)) { /* Not acceptable */ logger(LOG_ERR, "Name for tinc daemon required!"); return false; } - /* Read tinc.conf and our own host config file */ + if(!check_id(name)) { + logger(LOG_ERR, "Invalid name for myself!"); + free(name); + return false; + } myself->name = name; myself->connection->name = xstrdup(name); @@ -418,118 +386,34 @@ static bool setup_myself(void) { read_config_file(config_tree, fname); free(fname); - if(!read_rsa_private_key()) { + get_config_bool(lookup_config(config_tree, "ExperimentalProtocol"), &experimental); + + if(experimental && !read_ecdsa_private_key()) return false; - } - if(!get_config_string(lookup_config(config_tree, "Port"), &myport)) { + if(!read_rsa_private_key()) + return false; + + if(!get_config_string(lookup_config(config_tree, "Port"), &myport)) myport = xstrdup("655"); - } else { - port_specified = true; - } - - /* Ensure myport is numeric */ if(!atoi(myport)) { struct addrinfo *ai = str2addrinfo("localhost", myport, SOCK_DGRAM); sockaddr_t sa; - - if(!ai || !ai->ai_addr) { + if(!ai || !ai->ai_addr) return false; - } - free(myport); memcpy(&sa, ai->ai_addr, ai->ai_addrlen); sockaddr2str(&sa, NULL, &myport); } - if(get_config_string(lookup_config(config_tree, "Proxy"), &proxy)) { - if((space = strchr(proxy, ' '))) { - *space++ = 0; - } - - if(!strcasecmp(proxy, "none")) { - proxytype = PROXY_NONE; - } else if(!strcasecmp(proxy, "socks4")) { - proxytype = PROXY_SOCKS4; - } else if(!strcasecmp(proxy, "socks4a")) { - proxytype = PROXY_SOCKS4A; - } else if(!strcasecmp(proxy, "socks5")) { - proxytype = PROXY_SOCKS5; - } else if(!strcasecmp(proxy, "http")) { - proxytype = PROXY_HTTP; - } else if(!strcasecmp(proxy, "exec")) { - proxytype = PROXY_EXEC; - } else { - logger(LOG_ERR, "Unknown proxy type %s!", proxy); - free(proxy); - return false; - } - - switch(proxytype) { - case PROXY_NONE: - default: - break; - - case PROXY_EXEC: - if(!space || !*space) { - logger(LOG_ERR, "Argument expected for proxy type exec!"); - free(proxy); - return false; - } - - proxyhost = xstrdup(space); - break; - - case PROXY_SOCKS4: - case PROXY_SOCKS4A: - case PROXY_SOCKS5: - case PROXY_HTTP: - proxyhost = space; - - if(space && (space = strchr(space, ' '))) { - *space++ = 0, proxyport = space; - } - - if(space && (space = strchr(space, ' '))) { - *space++ = 0, proxyuser = space; - } - - if(space && (space = strchr(space, ' '))) { - *space++ = 0, proxypass = space; - } - - if(!proxyhost || !*proxyhost || !proxyport || !*proxyport) { - logger(LOG_ERR, "Host and port argument expected for proxy!"); - free(proxy); - return false; - } - - proxyhost = xstrdup(proxyhost); - proxyport = xstrdup(proxyport); - - if(proxyuser && *proxyuser) { - proxyuser = xstrdup(proxyuser); - } - - if(proxypass && *proxypass) { - proxypass = xstrdup(proxypass); - } - - break; - } - - free(proxy); - } - /* Read in all the subnets specified in the host configuration file */ cfg = lookup_config(config_tree, "Subnet"); while(cfg) { - if(!get_config_subnet(cfg, &subnet)) { + if(!get_config_subnet(cfg, &subnet)) return false; - } subnet_add(myself, subnet); @@ -538,131 +422,75 @@ static bool setup_myself(void) { /* Check some options */ - if(get_config_bool(lookup_config(config_tree, "IndirectData"), &choice) && choice) { + if(get_config_bool(lookup_config(config_tree, "IndirectData"), &choice) && choice) myself->options |= OPTION_INDIRECT; - } - if(get_config_bool(lookup_config(config_tree, "TCPOnly"), &choice) && choice) { + if(get_config_bool(lookup_config(config_tree, "TCPOnly"), &choice) && choice) myself->options |= OPTION_TCPONLY; - } - if(myself->options & OPTION_TCPONLY) { + 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); - get_config_bool(lookup_config(config_tree, "LocalDiscovery"), &localdiscovery); strictsubnets |= tunnelserver; if(get_config_string(lookup_config(config_tree, "Mode"), &mode)) { - if(!strcasecmp(mode, "router")) { + if(!strcasecmp(mode, "router")) routing_mode = RMODE_ROUTER; - } else if(!strcasecmp(mode, "switch")) { + else if(!strcasecmp(mode, "switch")) routing_mode = RMODE_SWITCH; - } else if(!strcasecmp(mode, "hub")) { + else if(!strcasecmp(mode, "hub")) routing_mode = RMODE_HUB; - } else { + else { logger(LOG_ERR, "Invalid routing mode!"); - free(mode); return false; } - free(mode); } if(get_config_string(lookup_config(config_tree, "Forwarding"), &mode)) { - if(!strcasecmp(mode, "off")) { + if(!strcasecmp(mode, "off")) forwarding_mode = FMODE_OFF; - } else if(!strcasecmp(mode, "internal")) { + else if(!strcasecmp(mode, "internal")) forwarding_mode = FMODE_INTERNAL; - } else if(!strcasecmp(mode, "kernel")) { + else if(!strcasecmp(mode, "kernel")) forwarding_mode = FMODE_KERNEL; - } else { + else { logger(LOG_ERR, "Invalid forwarding mode!"); - free(mode); return false; } - free(mode); } - choice = !(myself->options & OPTION_TCPONLY); - 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(config_tree, "PMTUDiscovery"), &choice); + if(choice) + myself->options |= OPTION_PMTU_DISCOVERY; - if(choice) { + choice = true; + get_config_bool(lookup_config(config_tree, "ClampMSS"), &choice); + if(choice) myself->options |= OPTION_CLAMP_MSS; - } get_config_bool(lookup_config(config_tree, "PriorityInheritance"), &priorityinheritance); - get_config_bool(lookup_config(config_tree, "DecrementTTL"), &decrement_ttl); - - if(get_config_string(lookup_config(config_tree, "Broadcast"), &mode)) { - if(!strcasecmp(mode, "no")) { - broadcast_mode = BMODE_NONE; - } else if(!strcasecmp(mode, "yes") || !strcasecmp(mode, "mst")) { - broadcast_mode = BMODE_MST; - } else if(!strcasecmp(mode, "direct")) { - broadcast_mode = BMODE_DIRECT; - } else { - logger(LOG_ERR, "Invalid broadcast mode!"); - free(mode); - return false; - } - - free(mode); - } #if !defined(SOL_IP) || !defined(IP_TOS) - - if(priorityinheritance) { - logger(LOG_WARNING, "%s not supported on this platform for IPv4 connection", "PriorityInheritance"); - } - + if(priorityinheritance) + logger(LOG_WARNING, "%s not supported on this platform", "PriorityInheritance"); #endif -#if !defined(IPPROTO_IPV6) || !defined(IPV6_TCLASS) - - if(priorityinheritance) { - logger(LOG_WARNING, "%s not supported on this platform for IPv6 connection", "PriorityInheritance"); - } - -#endif - - if(!get_config_int(lookup_config(config_tree, "MACExpire"), &macexpire)) { + if(!get_config_int(lookup_config(config_tree, "MACExpire"), &macexpire)) macexpire = 600; - } if(get_config_int(lookup_config(config_tree, "MaxTimeout"), &maxtimeout)) { if(maxtimeout <= 0) { logger(LOG_ERR, "Bogus maximum timeout!"); return false; } - } else { + } else maxtimeout = 900; - } - - if(get_config_int(lookup_config(config_tree, "MinTimeout"), &mintimeout)) { - if(mintimeout < 0) { - logger(LOG_ERR, "Bogus minimum timeout!"); - return false; - } - - if(mintimeout > maxtimeout) { - logger(LOG_WARNING, "Minimum timeout (%d s) cannot be larger than maximum timeout (%d s). Correcting !", mintimeout, maxtimeout); - mintimeout = maxtimeout; - } - } else { - mintimeout = 0; - } if(get_config_int(lookup_config(config_tree, "UDPRcvBuf"), &udp_rcvbuf)) { if(udp_rcvbuf <= 0) { @@ -683,23 +511,20 @@ static bool setup_myself(void) { logger(LOG_ERR, "ReplayWindow cannot be negative!"); return false; } - replaywin = (unsigned)replaywin_int; } if(get_config_string(lookup_config(config_tree, "AddressFamily"), &afname)) { - if(!strcasecmp(afname, "IPv4")) { + if(!strcasecmp(afname, "IPv4")) addressfamily = AF_INET; - } else if(!strcasecmp(afname, "IPv6")) { + else if(!strcasecmp(afname, "IPv6")) addressfamily = AF_INET6; - } else if(!strcasecmp(afname, "any")) { + else if(!strcasecmp(afname, "any")) addressfamily = AF_UNSPEC; - } else { + else { logger(LOG_ERR, "Invalid address family!"); - free(afname); return false; } - free(afname); } @@ -707,92 +532,37 @@ static bool setup_myself(void) { /* Generate packet encryption key */ - if(get_config_string(lookup_config(config_tree, "Cipher"), &cipher)) { - if(!strcasecmp(cipher, "none")) { - myself->incipher = NULL; - } else { - myself->incipher = EVP_get_cipherbyname(cipher); + if(!get_config_string(lookup_config(config_tree, "Cipher"), &cipher)) + cipher = xstrdup("blowfish"); - if(!myself->incipher) { - logger(LOG_ERR, "Unrecognized cipher type!"); - free(cipher); - return false; - } - } - - free(cipher); - } else { - myself->incipher = EVP_aes_256_cbc(); + if(!cipher_open_by_name(&myself->incipher, cipher)) { + logger(LOG_ERR, "Unrecognized cipher type!"); + return false; } - if(myself->incipher) { - myself->inkeylength = EVP_CIPHER_key_length(myself->incipher) + EVP_CIPHER_iv_length(myself->incipher); - } else { - myself->inkeylength = 1; - } - - /* We need to use a stream mode for the meta protocol. Use AES for this, - but try to match the key size with the one from the cipher selected - by Cipher. - - If Cipher is set to none, still use a low level of encryption for the - meta protocol. - */ - - int keylen = myself->incipher ? EVP_CIPHER_key_length(myself->incipher) : 0; - - if(keylen <= 16) { - myself->connection->outcipher = EVP_aes_128_cfb(); - } else if(keylen <= 24) { - myself->connection->outcipher = EVP_aes_192_cfb(); - } else { - myself->connection->outcipher = EVP_aes_256_cfb(); - } - - if(!get_config_int(lookup_config(config_tree, "KeyExpire"), &keylifetime)) { + if(!get_config_int(lookup_config(config_tree, "KeyExpire"), &keylifetime)) keylifetime = 3600; - } - keyexpires = now + keylifetime; + regenerate_key(); /* Check if we want to use message authentication codes... */ - if(get_config_string(lookup_config(config_tree, "Digest"), &digest)) { - if(!strcasecmp(digest, "none")) { - myself->indigest = NULL; - } else { - myself->indigest = EVP_get_digestbyname(digest); + if(!get_config_string(lookup_config(config_tree, "Digest"), &digest)) + digest = xstrdup("sha1"); - if(!myself->indigest) { - logger(LOG_ERR, "Unrecognized digest type!"); - free(digest); - return false; - } - } + int maclength = 4; + get_config_int(lookup_config(config_tree, "MACLength"), &maclength); - free(digest); - } else { - myself->indigest = EVP_sha256(); + if(maclength < 0) { + logger(LOG_ERR, "Bogus MAC length!"); + return false; } - myself->connection->outdigest = EVP_sha256(); - - if(get_config_int(lookup_config(config_tree, "MACLength"), &myself->inmaclength)) { - if(myself->indigest) { - if(myself->inmaclength > EVP_MD_size(myself->indigest)) { - logger(LOG_ERR, "MAC length exceeds size of digest!"); - return false; - } else if(myself->inmaclength < 0) { - logger(LOG_ERR, "Bogus MAC length!"); - return false; - } - } - } else { - myself->inmaclength = 4; + if(!digest_open_by_name(&myself->indigest, digest, maclength)) { + logger(LOG_ERR, "Unrecognized digest type!"); + return false; } - myself->connection->outmaclength = 0; - /* Compression */ if(get_config_int(lookup_config(config_tree, "Compression"), &myself->incompression)) { @@ -800,9 +570,8 @@ static bool setup_myself(void) { logger(LOG_ERR, "Bogus compression level!"); return false; } - } else { + } else myself->incompression = 0; - } myself->connection->outcompression = 0; @@ -815,59 +584,35 @@ static bool setup_myself(void) { graph(); - if(strictsubnets) { + if(strictsubnets) load_all_subnets(); - } /* Open device */ - devops = os_devops; - - if(get_config_string(lookup_config(config_tree, "DeviceType"), &type)) { - if(!strcasecmp(type, "dummy")) { - devops = dummy_devops; - } else if(!strcasecmp(type, "raw_socket")) { - devops = raw_socket_devops; - } else if(!strcasecmp(type, "multicast")) { - devops = multicast_devops; - } - -#ifdef ENABLE_UML - else if(!strcasecmp(type, "uml")) { - devops = uml_devops; - } - -#endif -#ifdef ENABLE_VDE - else if(!strcasecmp(type, "vde")) { - devops = vde_devops; - } - -#endif - free(type); - } - - if(!devops.setup()) { + if(!setup_device()) return false; + + if(device_fd >= 0) { + event_set(&device_ev, device_fd, EV_READ|EV_PERSIST, handle_device_data, NULL); + + if (event_add(&device_ev, NULL) < 0) { + logger(LOG_ERR, "event_add failed: %s", strerror(errno)); + close_device(); + return false; + } } /* Run tinc-up script to further initialize the tap interface */ - xasprintf(&envp[0], "NETNAME=%s", netname ? netname : ""); - xasprintf(&envp[1], "DEVICE=%s", device ? device : ""); - xasprintf(&envp[2], "INTERFACE=%s", iface ? iface : ""); + xasprintf(&envp[0], "NETNAME=%s", netname ? : ""); + xasprintf(&envp[1], "DEVICE=%s", device ? : ""); + xasprintf(&envp[2], "INTERFACE=%s", iface ? : ""); xasprintf(&envp[3], "NAME=%s", myself->name); + envp[4] = NULL; -#ifdef HAVE_MINGW - Sleep(1000); -#endif -#ifdef HAVE_CYGWIN - sleep(1); -#endif execute_script("tinc-up", envp); - for(i = 0; i < 4; i++) { + for(i = 0; i < 4; i++) free(envp[i]); - } /* Run subnet-up scripts for our own subnets */ @@ -875,150 +620,80 @@ static bool setup_myself(void) { /* Open sockets */ - if(!do_detach && getenv("LISTEN_FDS")) { - sockaddr_t sa; - socklen_t salen; + get_config_string(lookup_config(config_tree, "BindToAddress"), &address); - listen_sockets = atoi(getenv("LISTEN_FDS")); -#ifdef HAVE_UNSETENV - unsetenv("LISTEN_FDS"); -#endif + hint.ai_family = addressfamily; + hint.ai_socktype = SOCK_STREAM; + hint.ai_protocol = IPPROTO_TCP; + hint.ai_flags = AI_PASSIVE; - if(listen_sockets > MAXSOCKETS) { - logger(LOG_ERR, "Too many listening sockets"); - return false; - } + err = getaddrinfo(address, myport, &hint, &ai); - for(i = 0; i < listen_sockets; i++) { - salen = sizeof(sa); - - if(getsockname(i + 3, &sa.sa, &salen) < 0) { - logger(LOG_ERR, "Could not get address of listen fd %d: %s", i + 3, sockstrerror(errno)); - return false; - } - - listen_socket[i].tcp = i + 3; - -#ifdef FD_CLOEXEC - fcntl(i + 3, F_SETFD, FD_CLOEXEC); -#endif - - listen_socket[i].udp = setup_vpn_in_socket(&sa); - - if(listen_socket[i].udp < 0) { - return false; - } - - ifdebug(CONNECTIONS) { - hostname = sockaddr2hostname(&sa); - logger(LOG_NOTICE, "Listening on %s", hostname); - free(hostname); - } - - memcpy(&listen_socket[i].sa, &sa, salen); - } - } else { - listen_sockets = 0; - cfg = lookup_config(config_tree, "BindToAddress"); - - do { - get_config_string(cfg, &address); - - if(cfg) { - cfg = lookup_config_next(config_tree, cfg); - } - - char *port = myport; - - if(address) { - char *space = strchr(address, ' '); - - if(space) { - *space++ = 0; - port = space; - } - - if(!strcmp(address, "*")) { - *address = 0; - } - } - - hint.ai_family = addressfamily; - hint.ai_socktype = SOCK_STREAM; - hint.ai_protocol = IPPROTO_TCP; - hint.ai_flags = AI_PASSIVE; - -#if HAVE_DECL_RES_INIT - // ensure glibc reloads /etc/resolv.conf. - res_init(); -#endif - err = getaddrinfo(address && *address ? address : NULL, port, &hint, &ai); - free(address); - - if(err || !ai) { - logger(LOG_ERR, "System call `%s' failed: %s", "getaddrinfo", - gai_strerror(err)); - return false; - } - - for(aip = ai; aip; aip = aip->ai_next) { - if(listen_sockets >= MAXSOCKETS) { - logger(LOG_ERR, "Too many listening sockets"); - return false; - } - - listen_socket[listen_sockets].tcp = - setup_listen_socket((sockaddr_t *) aip->ai_addr); - - if(listen_socket[listen_sockets].tcp < 0) { - continue; - } - - listen_socket[listen_sockets].udp = - setup_vpn_in_socket((sockaddr_t *) aip->ai_addr); - - if(listen_socket[listen_sockets].udp < 0) { - continue; - } - - ifdebug(CONNECTIONS) { - hostname = sockaddr2hostname((sockaddr_t *) aip->ai_addr); - logger(LOG_NOTICE, "Listening on %s", hostname); - free(hostname); - } - - memcpy(&listen_socket[listen_sockets].sa, aip->ai_addr, aip->ai_addrlen); - listen_sockets++; - } - - freeaddrinfo(ai); - } while(cfg); + if(err || !ai) { + logger(LOG_ERR, "System call `%s' failed: %s", "getaddrinfo", + gai_strerror(err)); + return false; } - if(!listen_sockets) { + listen_sockets = 0; + + for(aip = ai; aip; aip = aip->ai_next) { + listen_socket[listen_sockets].tcp = + setup_listen_socket((sockaddr_t *) aip->ai_addr); + + if(listen_socket[listen_sockets].tcp < 0) + continue; + + listen_socket[listen_sockets].udp = + setup_vpn_in_socket((sockaddr_t *) aip->ai_addr); + + if(listen_socket[listen_sockets].udp < 0) { + close(listen_socket[listen_sockets].tcp); + continue; + } + + event_set(&listen_socket[listen_sockets].ev_tcp, + listen_socket[listen_sockets].tcp, + EV_READ|EV_PERSIST, + handle_new_meta_connection, NULL); + if(event_add(&listen_socket[listen_sockets].ev_tcp, NULL) < 0) { + logger(LOG_ERR, "event_add failed: %s", strerror(errno)); + abort(); + } + + event_set(&listen_socket[listen_sockets].ev_udp, + listen_socket[listen_sockets].udp, + EV_READ|EV_PERSIST, + handle_incoming_vpn_data, NULL); + if(event_add(&listen_socket[listen_sockets].ev_udp, NULL) < 0) { + logger(LOG_ERR, "event_add failed: %s", strerror(errno)); + abort(); + } + + ifdebug(CONNECTIONS) { + hostname = sockaddr2hostname((sockaddr_t *) aip->ai_addr); + logger(LOG_NOTICE, "Listening on %s", hostname); + free(hostname); + } + + memcpy(&listen_socket[listen_sockets].sa, aip->ai_addr, aip->ai_addrlen); + listen_sockets++; + + if(listen_sockets >= MAXSOCKETS) { + logger(LOG_WARNING, "Maximum of %d listening sockets reached", MAXSOCKETS); + break; + } + } + + freeaddrinfo(ai); + + if(listen_sockets) + logger(LOG_NOTICE, "Ready"); + else { logger(LOG_ERR, "Unable to create any listening socket!"); return false; } - /* If no Port option was specified, set myport to the port used by the first listening socket. */ - - if(!port_specified) { - sockaddr_t sa; - socklen_t salen = sizeof(sa); - - if(!getsockname(listen_socket[0].udp, &sa.sa, &salen)) { - free(myport); - sockaddr2str(&sa, NULL, &myport); - - if(!myport) { - myport = xstrdup("655"); - } - } - } - - /* Done. */ - - logger(LOG_NOTICE, "Ready"); return true; } @@ -1026,9 +701,6 @@ static bool setup_myself(void) { initialize network */ bool setup_network(void) { - now = time(NULL); - - init_events(); init_connections(); init_subnets(); init_nodes(); @@ -1039,25 +711,19 @@ bool setup_network(void) { if(pinginterval < 1) { pinginterval = 86400; } - } else { + } else pinginterval = 60; - } - if(!get_config_int(lookup_config(config_tree, "PingTimeout"), &pingtimeout)) { + if(!get_config_int(lookup_config(config_tree, "PingTimeout"), &pingtimeout)) pingtimeout = 5; - } - - if(pingtimeout < 1 || pingtimeout > pinginterval) { + if(pingtimeout < 1 || pingtimeout > pinginterval) pingtimeout = pinginterval; - } - if(!get_config_int(lookup_config(config_tree, "MaxOutputBufferSize"), &maxoutbufsize)) { + if(!get_config_int(lookup_config(config_tree, "MaxOutputBufferSize"), &maxoutbufsize)) maxoutbufsize = 10 * MTU; - } - if(!setup_myself()) { + if(!setup_myself()) return false; - } return true; } @@ -1066,9 +732,9 @@ bool setup_network(void) { close all open network connections */ void close_network_connections(void) { - avl_node_t *node, *next; + splay_node_t *node, *next; connection_t *c; - char *envp[5] = {0}; + char *envp[5]; int i; for(node = connection_tree->head; node; node = next) { @@ -1078,14 +744,6 @@ void close_network_connections(void) { terminate_connection(c, false); } - for(list_node_t *node = outgoing_list->head; node; node = node->next) { - outgoing_t *outgoing = node->data; - - if(outgoing->event) { - event_del(outgoing->event); - } - } - list_delete_list(outgoing_list); if(myself && myself->connection) { @@ -1095,33 +753,32 @@ void close_network_connections(void) { } for(i = 0; i < listen_sockets; i++) { + event_del(&listen_socket[i].ev_tcp); + event_del(&listen_socket[i].ev_udp); close(listen_socket[i].tcp); close(listen_socket[i].udp); } - xasprintf(&envp[0], "NETNAME=%s", netname ? netname : ""); - xasprintf(&envp[1], "DEVICE=%s", device ? device : ""); - xasprintf(&envp[2], "INTERFACE=%s", iface ? iface : ""); + xasprintf(&envp[0], "NETNAME=%s", netname ? : ""); + xasprintf(&envp[1], "DEVICE=%s", device ? : ""); + xasprintf(&envp[2], "INTERFACE=%s", iface ? : ""); xasprintf(&envp[3], "NAME=%s", myself->name); + envp[4] = NULL; exit_requests(); exit_edges(); exit_subnets(); exit_nodes(); exit_connections(); - exit_events(); execute_script("tinc-down", envp); - if(myport) { - free(myport); - } + if(myport) free(myport); - for(i = 0; i < 4; i++) { + for(i = 0; i < 4; i++) free(envp[i]); - } - devops.close(); + close_device(); return; } diff --git a/src/net_socket.c b/src/net_socket.c index 6195c16..a1dfcd3 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-2017 Guus Sliepen + 2000-2010 Guus Sliepen 2006 Scott Lamb 2009 Florian Forster @@ -22,26 +22,25 @@ #include "system.h" -#include "avl_tree.h" +#include "splay_tree.h" #include "conf.h" #include "connection.h" -#include "event.h" #include "logger.h" #include "meta.h" #include "net.h" #include "netutl.h" #include "protocol.h" -#include "proxy.h" #include "utils.h" #include "xalloc.h" +#include + /* Needed on Mac OS/X */ #ifndef SOL_TCP #define SOL_TCP IPPROTO_TCP #endif int addressfamily = AF_UNSPEC; -int mintimeout = 0; int maxtimeout = 900; int seconds_till_retry = 5; int udp_rcvbuf = 0; @@ -62,29 +61,22 @@ static void configure_tcp(connection_t *c) { if(fcntl(c->socket, F_SETFL, flags | O_NONBLOCK) < 0) { logger(LOG_ERR, "fcntl for %s: %s", c->hostname, strerror(errno)); } - #elif defined(WIN32) unsigned long arg = 1; if(ioctlsocket(c->socket, FIONBIO, &arg) != 0) { - logger(LOG_ERR, "ioctlsocket for %s: %s", c->hostname, sockstrerror(sockerrno)); + logger(LOG_ERR, "ioctlsocket for %s: %d", c->hostname, sockstrerror(sockerrno)); } - #endif #if defined(SOL_TCP) && defined(TCP_NODELAY) option = 1; - setsockopt(c->socket, SOL_TCP, TCP_NODELAY, (void *)&option, sizeof(option)); + setsockopt(c->socket, SOL_TCP, TCP_NODELAY, (void *)&option, sizeof option); #endif -#if defined(IP_TOS) && defined(IPTOS_LOWDELAY) +#if defined(SOL_IP) && defined(IP_TOS) && defined(IPTOS_LOWDELAY) option = IPTOS_LOWDELAY; - setsockopt(c->socket, IPPROTO_IP, IP_TOS, (void *)&option, sizeof(option)); -#endif - -#if defined(IPV6_TCLASS) && defined(IPTOS_LOWDELAY) - option = IPTOS_LOWDELAY; - setsockopt(c->socket, IPPROTO_IPV6, IPV6_TCLASS, (void *)&option, sizeof(option)); + setsockopt(c->socket, SOL_IP, IP_TOS, (void *)&option, sizeof option); #endif } @@ -96,23 +88,20 @@ static bool bind_to_interface(int sd) { int status; #endif /* defined(SOL_SOCKET) && defined(SO_BINDTODEVICE) */ - if(!get_config_string(lookup_config(config_tree, "BindToInterface"), &iface)) { + if(!get_config_string (lookup_config (config_tree, "BindToInterface"), &iface)) return true; - } #if defined(SOL_SOCKET) && defined(SO_BINDTODEVICE) memset(&ifr, 0, sizeof(ifr)); strncpy(ifr.ifr_ifrn.ifrn_name, iface, IFNAMSIZ); ifr.ifr_ifrn.ifrn_name[IFNAMSIZ - 1] = 0; - free(iface); status = setsockopt(sd, SOL_SOCKET, SO_BINDTODEVICE, (void *)&ifr, sizeof(ifr)); - if(status) { - logger(LOG_ERR, "Can't bind to interface %s: %s", ifr.ifr_ifrn.ifrn_name, strerror(errno)); + logger(LOG_ERR, "Can't bind to interface %s: %s", iface, + strerror(errno)); return false; } - #else /* if !defined(SOL_SOCKET) || !defined(SO_BINDTODEVICE) */ logger(LOG_WARNING, "%s not supported on this platform", "BindToInterface"); #endif @@ -120,6 +109,63 @@ static bool bind_to_interface(int sd) { return true; } +static bool bind_to_address(connection_t *c) { + char *node; + struct addrinfo *ai_list; + struct addrinfo *ai_ptr; + struct addrinfo ai_hints; + int status; + + assert(c != NULL); + assert(c->socket >= 0); + + node = NULL; + if(!get_config_string(lookup_config(config_tree, "BindToAddress"), + &node)) + return true; + + assert(node != NULL); + + memset(&ai_hints, 0, sizeof(ai_hints)); + ai_hints.ai_family = c->address.sa.sa_family; + /* We're called from `do_outgoing_connection' only. */ + ai_hints.ai_socktype = SOCK_STREAM; + ai_hints.ai_protocol = IPPROTO_TCP; + + ai_list = NULL; + + status = getaddrinfo(node, /* service = */ NULL, + &ai_hints, &ai_list); + if(status) { + logger(LOG_WARNING, "Error looking up %s port %s: %s", + node, "any", gai_strerror(status)); + free(node); + return false; + } + assert(ai_list != NULL); + + status = -1; + for(ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next) { + status = bind(c->socket, + ai_list->ai_addr, ai_list->ai_addrlen); + if(!status) + break; + } + + + if(status) { + logger(LOG_ERR, "Can't bind to %s/tcp: %s", node, sockstrerror(sockerrno)); + } else ifdebug(CONNECTIONS) { + logger(LOG_DEBUG, "Successfully bound outgoing " + "TCP socket to %s", node); + } + + free(node); + freeaddrinfo(ai_list); + + return status ? false : true; +} + int setup_listen_socket(const sockaddr_t *sa) { int nfd; char *addrstr; @@ -133,40 +179,30 @@ int setup_listen_socket(const sockaddr_t *sa) { return -1; } -#ifdef FD_CLOEXEC - fcntl(nfd, F_SETFD, FD_CLOEXEC); -#endif - /* Optimize TCP settings */ option = 1; - setsockopt(nfd, SOL_SOCKET, SO_REUSEADDR, (void *)&option, sizeof(option)); + setsockopt(nfd, SOL_SOCKET, SO_REUSEADDR, (void *)&option, sizeof option); -#if defined(IPV6_V6ONLY) - - if(sa->sa.sa_family == AF_INET6) { - setsockopt(nfd, IPPROTO_IPV6, IPV6_V6ONLY, (void *)&option, sizeof(option)); - } - -#else -#warning IPV6_V6ONLY not defined +#if defined(SOL_IPV6) && defined(IPV6_V6ONLY) + if(sa->sa.sa_family == AF_INET6) + setsockopt(nfd, SOL_IPV6, IPV6_V6ONLY, (void *)&option, sizeof option); #endif - if(get_config_string(lookup_config(config_tree, "BindToInterface"), &iface)) { + if(get_config_string + (lookup_config(config_tree, "BindToInterface"), &iface)) { #if defined(SOL_SOCKET) && defined(SO_BINDTODEVICE) struct ifreq ifr; - memset(&ifr, 0, sizeof(ifr)); + memset(&ifr, 0, sizeof ifr); strncpy(ifr.ifr_ifrn.ifrn_name, iface, IFNAMSIZ); - ifr.ifr_ifrn.ifrn_name[IFNAMSIZ - 1] = 0; - free(iface); - if(setsockopt(nfd, SOL_SOCKET, SO_BINDTODEVICE, (void *)&ifr, sizeof(ifr))) { + if(setsockopt(nfd, SOL_SOCKET, SO_BINDTODEVICE, (void *)&ifr, sizeof ifr)) { closesocket(nfd); - logger(LOG_ERR, "Can't bind to interface %s: %s", ifr.ifr_ifrn.ifrn_name, strerror(sockerrno)); + logger(LOG_ERR, "Can't bind to interface %s: %s", iface, + strerror(sockerrno)); return -1; } - #else logger(LOG_WARNING, "%s not supported on this platform", "BindToInterface"); #endif @@ -201,10 +237,6 @@ int setup_vpn_in_socket(const sockaddr_t *sa) { return -1; } -#ifdef FD_CLOEXEC - fcntl(nfd, F_SETFD, FD_CLOEXEC); -#endif - #ifdef O_NONBLOCK { int flags = fcntl(nfd, F_GETFL); @@ -212,14 +244,13 @@ int setup_vpn_in_socket(const sockaddr_t *sa) { if(fcntl(nfd, F_SETFL, flags | O_NONBLOCK) < 0) { closesocket(nfd); logger(LOG_ERR, "System call `%s' failed: %s", "fcntl", - strerror(errno)); + strerror(errno)); return -1; } } #elif defined(WIN32) { unsigned long arg = 1; - if(ioctlsocket(nfd, FIONBIO, &arg) != 0) { closesocket(nfd); logger(LOG_ERR, "Call to `%s' failed: %s", "ioctlsocket", sockstrerror(sockerrno)); @@ -229,62 +260,52 @@ int setup_vpn_in_socket(const sockaddr_t *sa) { #endif option = 1; - setsockopt(nfd, SOL_SOCKET, SO_REUSEADDR, (void *)&option, sizeof(option)); - setsockopt(nfd, SOL_SOCKET, SO_BROADCAST, (void *)&option, sizeof(option)); + setsockopt(nfd, SOL_SOCKET, SO_REUSEADDR, (void *)&option, sizeof option); - if(udp_rcvbuf && setsockopt(nfd, SOL_SOCKET, SO_RCVBUF, (void *)&udp_rcvbuf, sizeof(udp_rcvbuf))) { + if(udp_rcvbuf && setsockopt(nfd, SOL_SOCKET, SO_RCVBUF, (void *)&udp_rcvbuf, sizeof(udp_rcvbuf))) logger(LOG_WARNING, "Can't set UDP SO_RCVBUF to %i: %s", udp_rcvbuf, strerror(errno)); - } - if(udp_sndbuf && setsockopt(nfd, SOL_SOCKET, SO_SNDBUF, (void *)&udp_sndbuf, sizeof(udp_sndbuf))) { + if(udp_sndbuf && setsockopt(nfd, SOL_SOCKET, SO_SNDBUF, (void *)&udp_sndbuf, sizeof(udp_sndbuf))) logger(LOG_WARNING, "Can't set UDP SO_SNDBUF to %i: %s", udp_sndbuf, strerror(errno)); - } - -#if defined(IPV6_V6ONLY) - - if(sa->sa.sa_family == AF_INET6) { - setsockopt(nfd, IPPROTO_IPV6, IPV6_V6ONLY, (void *)&option, sizeof(option)); - } +#if defined(IPPROTO_IPV6) && defined(IPV6_V6ONLY) + if(sa->sa.sa_family == AF_INET6) + setsockopt(nfd, IPPROTO_IPV6, IPV6_V6ONLY, (void *)&option, sizeof option); #endif #if defined(IP_DONTFRAG) && !defined(IP_DONTFRAGMENT) #define IP_DONTFRAGMENT IP_DONTFRAG #endif -#if defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DO) - +#if defined(SOL_IP) && defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DO) if(myself->options & OPTION_PMTU_DISCOVERY) { option = IP_PMTUDISC_DO; - setsockopt(nfd, IPPROTO_IP, IP_MTU_DISCOVER, (void *)&option, sizeof(option)); + setsockopt(nfd, SOL_IP, IP_MTU_DISCOVER, (void *)&option, sizeof(option)); } - -#elif defined(IP_DONTFRAGMENT) - +#elif defined(IPPROTO_IP) && defined(IP_DONTFRAGMENT) if(myself->options & OPTION_PMTU_DISCOVERY) { option = 1; setsockopt(nfd, IPPROTO_IP, IP_DONTFRAGMENT, (void *)&option, sizeof(option)); } - +#else +#warning No way to disable IPv4 fragmentation #endif -#if defined(IPV6_MTU_DISCOVER) && defined(IPV6_PMTUDISC_DO) - +#if defined(SOL_IPV6) && defined(IPV6_MTU_DISCOVER) && defined(IPV6_PMTUDISC_DO) if(myself->options & OPTION_PMTU_DISCOVERY) { option = IPV6_PMTUDISC_DO; - setsockopt(nfd, IPPROTO_IPV6, IPV6_MTU_DISCOVER, (void *)&option, sizeof(option)); + setsockopt(nfd, SOL_IPV6, IPV6_MTU_DISCOVER, (void *)&option, sizeof(option)); } - -#elif defined(IPV6_DONTFRAG) - +#elif defined(IPPROTO_IPV6) && defined(IPV6_DONTFRAG) if(myself->options & OPTION_PMTU_DISCOVERY) { option = 1; setsockopt(nfd, IPPROTO_IPV6, IPV6_DONTFRAG, (void *)&option, sizeof(option)); } - +#else +#warning No way to disable IPv6 fragmentation #endif - if(!bind_to_interface(nfd)) { + if (!bind_to_interface(nfd)) { closesocket(nfd); return -1; } @@ -300,109 +321,37 @@ int setup_vpn_in_socket(const sockaddr_t *sa) { return nfd; } /* int setup_vpn_in_socket */ +static void retry_outgoing_handler(int fd, short events, void *data) { + setup_outgoing_connection(data); +} + void retry_outgoing(outgoing_t *outgoing) { outgoing->timeout += 5; - if(outgoing->timeout < mintimeout) { - outgoing->timeout = mintimeout; - } - - if(outgoing->timeout > maxtimeout) { + if(outgoing->timeout > maxtimeout) outgoing->timeout = maxtimeout; - } - if(outgoing->event) { - event_del(outgoing->event); - } - - outgoing->event = new_event(); - outgoing->event->handler = (event_handler_t) setup_outgoing_connection; - outgoing->event->time = now + outgoing->timeout; - outgoing->event->data = outgoing; - event_add(outgoing->event); + timeout_set(&outgoing->ev, retry_outgoing_handler, outgoing); + event_add(&outgoing->ev, &(struct timeval){outgoing->timeout, 0}); ifdebug(CONNECTIONS) logger(LOG_NOTICE, - "Trying to re-establish outgoing connection in %d seconds", - outgoing->timeout); + "Trying to re-establish outgoing connection in %d seconds", + outgoing->timeout); } void finish_connecting(connection_t *c) { ifdebug(CONNECTIONS) logger(LOG_INFO, "Connected to %s (%s)", c->name, c->hostname); - c->last_ping_time = now; + configure_tcp(c); + + c->last_ping_time = time(NULL); + c->status.connecting = false; send_id(c); } -static void do_outgoing_pipe(connection_t *c, char *command) { -#ifndef HAVE_MINGW - int fd[2]; - - if(socketpair(AF_UNIX, SOCK_STREAM, 0, fd)) { - logger(LOG_ERR, "Could not create socketpair: %s\n", strerror(errno)); - return; - } - - if(fork()) { - c->socket = fd[0]; - close(fd[1]); - ifdebug(CONNECTIONS) logger(LOG_DEBUG, "Using proxy %s", command); - return; - } - - close(0); - close(1); - close(fd[0]); - dup2(fd[1], 0); - dup2(fd[1], 1); - close(fd[1]); - - // Other filedescriptors should be closed automatically by CLOEXEC - - char *host = NULL; - char *port = NULL; - - sockaddr2str(&c->address, &host, &port); - setenv("REMOTEADDRESS", host, true); - setenv("REMOTEPORT", port, true); - setenv("NODE", c->name, true); - setenv("NAME", myself->name, true); - - if(netname) { - setenv("NETNAME", netname, true); - } - - int result = system(command); - - if(result < 0) { - logger(LOG_ERR, "Could not execute %s: %s\n", command, strerror(errno)); - } else if(result) { - logger(LOG_ERR, "%s exited with non-zero status %d", command, result); - } - - exit(result); -#else - logger(LOG_ERR, "Proxy type exec not supported on this platform!"); - return; -#endif -} - -static bool is_valid_host_port(const char *host, const char *port) { - for(const char *p = host; *p; p++) - if(!isalnum(*p) && *p != '-' && *p != '.') { - return false; - } - - for(const char *p = port; *p; p++) - if(!isalnum(*p)) { - return false; - } - - return true; -} - -void do_outgoing_connection(connection_t *c) { - struct addrinfo *proxyai = NULL; +bool do_outgoing_connection(connection_t *c) { + char *address, *port, *space; int result; if(!c->outgoing) { @@ -411,58 +360,38 @@ void do_outgoing_connection(connection_t *c) { } begin: - if(!c->outgoing->ai) { if(!c->outgoing->cfg) { ifdebug(CONNECTIONS) logger(LOG_ERR, "Could not set up a meta connection to %s", - c->name); - c->status.remove = true; + c->name); retry_outgoing(c->outgoing); c->outgoing = NULL; - return; + connection_del(c); + return false; } - char *address, *port, *space; - get_config_string(c->outgoing->cfg, &address); space = strchr(address, ' '); - if(space) { port = xstrdup(space + 1); *space = 0; } else { - if(!get_config_string(lookup_config(c->config_tree, "Port"), &port)) { + if(!get_config_string(lookup_config(c->config_tree, "Port"), &port)) port = xstrdup("655"); - } } c->outgoing->ai = str2addrinfo(address, port, SOCK_STREAM); - - // If we cannot resolve the address, maybe we are using a proxy that can? - if(!c->outgoing->ai && proxytype != PROXY_NONE && is_valid_host_port(address, port)) { - memset(&c->address, 0, sizeof(c->address)); - c->address.sa.sa_family = AF_UNKNOWN; - c->address.unknown.address = address; - c->address.unknown.port = port; - } else { - free(address); - free(port); - } + free(address); + free(port); c->outgoing->aip = c->outgoing->ai; c->outgoing->cfg = lookup_config_next(c->config_tree, c->outgoing->cfg); - - if(!c->outgoing->ai && proxytype != PROXY_NONE) { - goto connect; - } } if(!c->outgoing->aip) { - if(c->outgoing->ai) { + if(c->outgoing->ai) freeaddrinfo(c->outgoing->ai); - } - c->outgoing->ai = NULL; goto begin; } @@ -470,106 +399,42 @@ begin: memcpy(&c->address, c->outgoing->aip->ai_addr, c->outgoing->aip->ai_addrlen); c->outgoing->aip = c->outgoing->aip->ai_next; -connect: - - if(c->hostname) { + if(c->hostname) free(c->hostname); - } c->hostname = sockaddr2hostname(&c->address); ifdebug(CONNECTIONS) logger(LOG_INFO, "Trying to connect to %s (%s)", c->name, - c->hostname); + c->hostname); - if(!proxytype) { - c->socket = socket(c->address.sa.sa_family, SOCK_STREAM, IPPROTO_TCP); - } else if(proxytype == PROXY_EXEC) { - c->status.proxy_passed = true; - do_outgoing_pipe(c, proxyhost); - } else { - proxyai = str2addrinfo(proxyhost, proxyport, SOCK_STREAM); - - if(!proxyai) { - goto begin; - } - - ifdebug(CONNECTIONS) logger(LOG_INFO, "Using proxy at %s port %s", proxyhost, proxyport); - c->socket = socket(proxyai->ai_family, SOCK_STREAM, IPPROTO_TCP); - } + c->socket = socket(c->address.sa.sa_family, SOCK_STREAM, IPPROTO_TCP); if(c->socket == -1) { ifdebug(CONNECTIONS) logger(LOG_ERR, "Creating socket for %s failed: %s", c->hostname, sockstrerror(sockerrno)); goto begin; } - if(proxytype != PROXY_EXEC) { - configure_tcp(c); - } - -#ifdef FD_CLOEXEC - fcntl(c->socket, F_SETFD, FD_CLOEXEC); +#if defined(SOL_IPV6) && defined(IPV6_V6ONLY) + int option = 1; + if(c->address.sa.sa_family == AF_INET6) + setsockopt(c->socket, SOL_IPV6, IPV6_V6ONLY, (void *)&option, sizeof option); #endif - if(proxytype != PROXY_EXEC) { -#if defined(IPV6_V6ONLY) - int option = 1; + bind_to_interface(c->socket); + bind_to_address(c); - if(c->address.sa.sa_family == AF_INET6) { - setsockopt(c->socket, IPPROTO_IPV6, IPV6_V6ONLY, (void *)&option, sizeof(option)); - } + /* Optimize TCP settings */ -#endif - - bind_to_interface(c->socket); - - int b = -1; - - for(int i = 0; i < listen_sockets; i++) { - if(listen_socket[i].sa.sa.sa_family == c->address.sa.sa_family) { - if(b == -1) { - b = i; - } else { - b = -1; - break; - } - } - } - - if(b != -1) { - sockaddr_t sa = listen_socket[b].sa; - - if(sa.sa.sa_family == AF_INET) { - sa.in.sin_port = 0; - } else if(sa.sa.sa_family == AF_INET6) { - sa.in6.sin6_port = 0; - } - - if(bind(c->socket, &sa.sa, SALEN(sa.sa))) { - char *addrstr = sockaddr2hostname(&sa); - logger(LOG_ERR, "Can't bind to %s/tcp: %s", addrstr, sockstrerror(sockerrno)); - free(addrstr); - } - } - } + configure_tcp(c); /* Connect */ - if(!proxytype) { - result = connect(c->socket, &c->address.sa, SALEN(c->address.sa)); - } else if(proxytype == PROXY_EXEC) { - result = 0; - } else { - result = connect(c->socket, proxyai->ai_addr, proxyai->ai_addrlen); - freeaddrinfo(proxyai); - } - - now = time(NULL); + result = connect(c->socket, &c->address.sa, SALEN(c->address.sa)); if(result == -1) { if(sockinprogress(sockerrno)) { - c->last_ping_time = now; c->status.connecting = true; - return; + return true; } closesocket(c->socket); @@ -581,14 +446,32 @@ connect: finish_connecting(c); - return; + return true; +} + +static void handle_meta_write(int sock, short events, void *data) { + ifdebug(META) logger(LOG_DEBUG, "handle_meta_write() called"); + + connection_t *c = data; + + ssize_t outlen = send(c->socket, c->outbuf.data + c->outbuf.offset, c->outbuf.len - c->outbuf.offset, 0); + if(outlen <= 0) { + logger(LOG_ERR, "Onoes, outlen = %d (%s)", (int)outlen, strerror(errno)); + terminate_connection(c, c->status.active); + return; + } + + buffer_read(&c->outbuf, outlen); + if(!c->outbuf.len && event_initialized(&c->outevent)) + event_del(&c->outevent); } void setup_outgoing_connection(outgoing_t *outgoing) { connection_t *c; node_t *n; - outgoing->event = NULL; + if(event_initialized(&outgoing->ev)) + event_del(&outgoing->ev); n = lookup_node(outgoing->name); @@ -608,66 +491,43 @@ void setup_outgoing_connection(outgoing_t *outgoing) { c->outcompression = myself->connection->outcompression; init_configuration(&c->config_tree); - - if(!read_connection_config(c)) { - free_connection(c); - outgoing->timeout = maxtimeout; - retry_outgoing(outgoing); - return; - } + read_connection_config(c); outgoing->cfg = lookup_config(c->config_tree, "Address"); if(!outgoing->cfg) { logger(LOG_ERR, "No address specified for %s", c->name); free_connection(c); - outgoing->timeout = maxtimeout; - retry_outgoing(outgoing); return; } c->outgoing = outgoing; - c->last_ping_time = now; + c->last_ping_time = time(NULL); connection_add(c); - do_outgoing_connection(c); + if (do_outgoing_connection(c)) { + event_set(&c->inevent, c->socket, EV_READ | EV_PERSIST, handle_meta_connection_data, c); + event_set(&c->outevent, c->socket, EV_WRITE | EV_PERSIST, handle_meta_write, c); + event_add(&c->inevent, NULL); + } } /* accept a new tcp connect and create a new connection */ -bool handle_new_meta_connection(int sock) { - static const int max_accept_burst = 10; - static int last_accept_burst; - static int last_accept_time; +void handle_new_meta_connection(int sock, short events, void *data) { connection_t *c; sockaddr_t sa; int fd; - socklen_t len = sizeof(sa); + socklen_t len = sizeof sa; fd = accept(sock, &sa.sa, &len); if(fd < 0) { logger(LOG_ERR, "Accepting a new connection failed: %s", sockstrerror(sockerrno)); - return false; - } - - if(last_accept_time == now) { - last_accept_burst++; - - if(last_accept_burst >= max_accept_burst) { - if(last_accept_burst == max_accept_burst) { - ifdebug(CONNECTIONS) logger(LOG_WARNING, "Throttling incoming connections"); - } - - tarpit(fd); - return false; - } - } else { - last_accept_burst = 0; - last_accept_time = now; + return; } sockaddrunmap(&sa); @@ -682,27 +542,28 @@ bool handle_new_meta_connection(int sock) { c->address = sa; c->hostname = sockaddr2hostname(&sa); c->socket = fd; - c->last_ping_time = now; + c->last_ping_time = time(NULL); ifdebug(CONNECTIONS) logger(LOG_NOTICE, "Connection from %s", c->hostname); + event_set(&c->inevent, c->socket, EV_READ | EV_PERSIST, handle_meta_connection_data, c); + event_set(&c->outevent, c->socket, EV_WRITE | EV_PERSIST, handle_meta_write, c); + event_add(&c->inevent, NULL); + configure_tcp(c); connection_add(c); c->allow_request = ID; - - return true; + send_id(c); } static void free_outgoing(outgoing_t *outgoing) { - if(outgoing->ai) { + if(outgoing->ai) freeaddrinfo(outgoing->ai); - } - if(outgoing->name) { + if(outgoing->name) free(outgoing->name); - } free(outgoing); } @@ -711,21 +572,21 @@ void try_outgoing_connections(void) { static config_t *cfg = NULL; char *name; outgoing_t *outgoing; - + outgoing_list = list_alloc((list_action_t)free_outgoing); - + for(cfg = lookup_config(config_tree, "ConnectTo"); cfg; cfg = lookup_config_next(config_tree, cfg)) { get_config_string(cfg, &name); if(!check_id(name)) { logger(LOG_ERR, - "Invalid name for outgoing connection in %s line %d", - cfg->file, cfg->line); + "Invalid name for outgoing connection in %s line %d", + cfg->file, cfg->line); free(name); continue; } - outgoing = xmalloc_and_zero(sizeof(*outgoing)); + outgoing = xmalloc_and_zero(sizeof *outgoing); outgoing->name = name; list_insert_tail(outgoing_list, outgoing); setup_outgoing_connection(outgoing); diff --git a/src/netutl.c b/src/netutl.c index abe3d87..8db252d 100644 --- a/src/netutl.c +++ b/src/netutl.c @@ -1,7 +1,7 @@ /* netutl.c -- some supporting network utility code Copyright (C) 1998-2005 Ivo Timmermans - 2000-2016 Guus Sliepen + 2000-2011 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 @@ -33,21 +33,17 @@ bool hostnames = false; Return NULL on failure. */ struct addrinfo *str2addrinfo(const char *address, const char *service, int socktype) { - struct addrinfo *ai = NULL, hint = {0}; + struct addrinfo *ai, hint = {0}; int err; hint.ai_family = addressfamily; hint.ai_socktype = socktype; -#if HAVE_DECL_RES_INIT - // ensure glibc reloads /etc/resolv.conf. - res_init(); -#endif err = getaddrinfo(address, service, &hint, &ai); if(err) { logger(LOG_WARNING, "Error looking up %s port %s: %s", address, - service, gai_strerror(err)); + service, gai_strerror(err)); return NULL; } @@ -55,7 +51,7 @@ struct addrinfo *str2addrinfo(const char *address, const char *service, int sock } sockaddr_t str2sockaddr(const char *address, const char *port) { - struct addrinfo *ai = NULL, hint = {0}; + struct addrinfo *ai, hint = {0}; sockaddr_t result; int err; @@ -67,7 +63,7 @@ sockaddr_t str2sockaddr(const char *address, const char *port) { if(err || !ai) { ifdebug(SCARY_THINGS) - logger(LOG_DEBUG, "Unknown type address %s port %s", address, port); + logger(LOG_DEBUG, "Unknown type address %s port %s", address, port); result.sa.sa_family = AF_UNKNOWN; result.unknown.address = xstrdup(address); result.unknown.port = xstrdup(port); @@ -87,38 +83,28 @@ void sockaddr2str(const sockaddr_t *sa, char **addrstr, char **portstr) { int err; if(sa->sa.sa_family == AF_UNKNOWN) { - if(addrstr) { - *addrstr = xstrdup(sa->unknown.address); - } - - if(portstr) { - *portstr = xstrdup(sa->unknown.port); - } - + *addrstr = xstrdup(sa->unknown.address); + *portstr = xstrdup(sa->unknown.port); return; } - err = getnameinfo(&sa->sa, SALEN(sa->sa), address, sizeof(address), port, sizeof(port), NI_NUMERICHOST | NI_NUMERICSERV); + err = getnameinfo(&sa->sa, SALEN(sa->sa), address, sizeof address, port, sizeof port, NI_NUMERICHOST | NI_NUMERICSERV); if(err) { logger(LOG_ERR, "Error while translating addresses: %s", - gai_strerror(err)); + gai_strerror(err)); abort(); } scopeid = strchr(address, '%'); - if(scopeid) { - *scopeid = '\0'; /* Descope. */ - } + if(scopeid) + *scopeid = '\0'; /* Descope. */ - if(addrstr) { + if(addrstr) *addrstr = xstrdup(address); - } - - if(portstr) { + if(portstr) *portstr = xstrdup(port); - } } char *sockaddr2hostname(const sockaddr_t *sa) { @@ -132,12 +118,11 @@ char *sockaddr2hostname(const sockaddr_t *sa) { return str; } - err = getnameinfo(&sa->sa, SALEN(sa->sa), address, sizeof(address), port, sizeof(port), - hostnames ? 0 : (NI_NUMERICHOST | NI_NUMERICSERV)); - + err = getnameinfo(&sa->sa, SALEN(sa->sa), address, sizeof address, port, sizeof port, + hostnames ? 0 : (NI_NUMERICHOST | NI_NUMERICSERV)); if(err) { logger(LOG_ERR, "Error while looking up hostname: %s", - gai_strerror(err)); + gai_strerror(err)); } xasprintf(&str, "%s port %s", address, port); @@ -150,27 +135,26 @@ int sockaddrcmp_noport(const sockaddr_t *a, const sockaddr_t *b) { result = a->sa.sa_family - b->sa.sa_family; - if(result) { + if(result) return result; - } - switch(a->sa.sa_family) { - case AF_UNSPEC: - return 0; + switch (a->sa.sa_family) { + case AF_UNSPEC: + return 0; - case AF_UNKNOWN: - return strcmp(a->unknown.address, b->unknown.address); + case AF_UNKNOWN: + return strcmp(a->unknown.address, b->unknown.address); - case AF_INET: - return memcmp(&a->in.sin_addr, &b->in.sin_addr, sizeof(a->in.sin_addr)); + case AF_INET: + return memcmp(&a->in.sin_addr, &b->in.sin_addr, sizeof(a->in.sin_addr)); - case AF_INET6: - return memcmp(&a->in6.sin6_addr, &b->in6.sin6_addr, sizeof(a->in6.sin6_addr)); + case AF_INET6: + return memcmp(&a->in6.sin6_addr, &b->in6.sin6_addr, sizeof(a->in6.sin6_addr)); - default: - logger(LOG_ERR, "sockaddrcmp() was called with unknown address family %d, exitting!", - a->sa.sa_family); - abort(); + default: + logger(LOG_ERR, "sockaddrcmp() was called with unknown address family %d, exitting!", + a->sa.sa_family); + abort(); } } @@ -179,45 +163,41 @@ int sockaddrcmp(const sockaddr_t *a, const sockaddr_t *b) { result = a->sa.sa_family - b->sa.sa_family; - if(result) { + if(result) return result; - } - switch(a->sa.sa_family) { - case AF_UNSPEC: - return 0; + switch (a->sa.sa_family) { + case AF_UNSPEC: + return 0; - case AF_UNKNOWN: - result = strcmp(a->unknown.address, b->unknown.address); + case AF_UNKNOWN: + result = strcmp(a->unknown.address, b->unknown.address); - if(result) { - return result; - } + if(result) + return result; - return strcmp(a->unknown.port, b->unknown.port); + return strcmp(a->unknown.port, b->unknown.port); - case AF_INET: - result = memcmp(&a->in.sin_addr, &b->in.sin_addr, sizeof(a->in.sin_addr)); + case AF_INET: + result = memcmp(&a->in.sin_addr, &b->in.sin_addr, sizeof a->in.sin_addr); - if(result) { - return result; - } + if(result) + return result; - return memcmp(&a->in.sin_port, &b->in.sin_port, sizeof(a->in.sin_port)); + return memcmp(&a->in.sin_port, &b->in.sin_port, sizeof a->in.sin_port); - case AF_INET6: - result = memcmp(&a->in6.sin6_addr, &b->in6.sin6_addr, sizeof(a->in6.sin6_addr)); + case AF_INET6: + result = memcmp(&a->in6.sin6_addr, &b->in6.sin6_addr, sizeof a->in6.sin6_addr); - if(result) { - return result; - } + if(result) + return result; - return memcmp(&a->in6.sin6_port, &b->in6.sin6_port, sizeof(a->in6.sin6_port)); + return memcmp(&a->in6.sin6_port, &b->in6.sin6_port, sizeof a->in6.sin6_port); - default: - logger(LOG_ERR, "sockaddrcmp() was called with unknown address family %d, exitting!", - a->sa.sa_family); - abort(); + default: + logger(LOG_ERR, "sockaddrcmp() was called with unknown address family %d, exitting!", + a->sa.sa_family); + abort(); } } @@ -237,7 +217,7 @@ void sockaddrfree(sockaddr_t *a) { free(a->unknown.port); } } - + void sockaddrunmap(sockaddr_t *sa) { if(sa->sa.sa_family == AF_INET6 && IN6_IS_ADDR_V4MAPPED(&sa->in6.sin6_addr)) { sa->in.sin_addr.s_addr = ((uint32_t *) & sa->in6.sin6_addr)[3]; @@ -245,31 +225,6 @@ void sockaddrunmap(sockaddr_t *sa) { } } -void sockaddr_setport(sockaddr_t *sa, const char *port) { - uint16_t portnum = htons(atoi(port)); - - if(!portnum) { - return; - } - - switch(sa->sa.sa_family) { - case AF_INET: - sa->in.sin_port = portnum; - break; - - case AF_INET6: - sa->in6.sin6_port = portnum; - break; - - case AF_UNKNOWN: - free(sa->unknown.port); - sa->unknown.port = xstrdup(port); - - default: - return; - } -} - /* Subnet mask handling */ int maskcmp(const void *va, const void *vb, int masklen) { @@ -279,15 +234,13 @@ int maskcmp(const void *va, const void *vb, int masklen) { for(m = masklen, i = 0; m >= 8; m -= 8, i++) { result = a[i] - b[i]; - - if(result) { + if(result) return result; - } } if(m) return (a[i] & (0x100 - (1 << (8 - m)))) - - (b[i] & (0x100 - (1 << (8 - m)))); + (b[i] & (0x100 - (1 << (8 - m)))); return 0; } @@ -299,13 +252,11 @@ void mask(void *va, int masklen, int len) { i = masklen / 8; masklen %= 8; - if(masklen) { + if(masklen) a[i++] &= (0x100 - (1 << (8 - masklen))); - } - for(; i < len; i++) { + for(; i < len; i++) a[i] = 0; - } } void maskcpy(void *va, const void *vb, int masklen, int len) { @@ -313,18 +264,16 @@ void maskcpy(void *va, const void *vb, int masklen, int len) { char *a = va; const char *b = vb; - for(m = masklen, i = 0; m >= 8; m -= 8, i++) { + for(m = masklen, i = 0; m >= 8; m -= 8, i++) a[i] = b[i]; - } if(m) { a[i] = b[i] & (0x100 - (1 << (8 - m))); i++; } - for(; i < len; i++) { + for(; i < len; i++) a[i] = 0; - } } bool maskcheck(const void *va, int masklen, int len) { @@ -334,14 +283,12 @@ bool maskcheck(const void *va, int masklen, int len) { i = masklen / 8; masklen %= 8; - if(masklen && a[i++] & (0xff >> masklen)) { + if(masklen && a[i++] & (0xff >> masklen)) return false; - } for(; i < len; i++) - if(a[i] != 0) { + if(a[i] != 0) return false; - } return true; } diff --git a/src/netutl.h b/src/netutl.h index cc3ccab..7fc41e8 100644 --- a/src/netutl.h +++ b/src/netutl.h @@ -1,10 +1,7 @@ -#ifndef TINC_NETUTL_H -#define TINC_NETUTL_H - /* netutl.h -- header file for netutl.c Copyright (C) 1998-2005 Ivo Timmermans - 2000-2016 Guus Sliepen + 2000-2009 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 @@ -21,23 +18,25 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +#ifndef __TINC_NETUTL_H__ +#define __TINC_NETUTL_H__ + #include "net.h" extern bool hostnames; -extern struct addrinfo *str2addrinfo(const char *address, const char *service, int socktype); -extern sockaddr_t str2sockaddr(const char *address, const char *port); -extern void sockaddr2str(const sockaddr_t *sa, char **addrstr, char **portstr); -extern char *sockaddr2hostname(const sockaddr_t *sa); -extern int sockaddrcmp(const sockaddr_t *a, const sockaddr_t *b); -extern int sockaddrcmp_noport(const sockaddr_t *a, const sockaddr_t *b); -extern void sockaddrunmap(sockaddr_t *sa); -extern void sockaddrfree(sockaddr_t *sa); -extern void sockaddrcpy(sockaddr_t *dest, const sockaddr_t *src); -extern void sockaddr_setport(sockaddr_t *sa, const char *port); -extern int maskcmp(const void *a, const void *b, int masklen); -extern void maskcpy(void *dest, const void *src, int masklen, int len); -extern void mask(void *mask, int masklen, int len); -extern bool maskcheck(const void *mask, int masklen, int len); +extern struct addrinfo *str2addrinfo(const char *, const char *, int); +extern sockaddr_t str2sockaddr(const char *, const char *); +extern void sockaddr2str(const sockaddr_t *, char **, char **); +extern char *sockaddr2hostname(const sockaddr_t *); +extern int sockaddrcmp(const sockaddr_t *, const sockaddr_t *); +extern int sockaddrcmp_noport(const sockaddr_t *, const sockaddr_t *); +extern void sockaddrunmap(sockaddr_t *); +extern void sockaddrfree(sockaddr_t *); +extern void sockaddrcpy(sockaddr_t *, const sockaddr_t *); +extern int maskcmp(const void *, const void *, int); +extern void maskcpy(void *, const void *, int, int); +extern void mask(void *, int, int); +extern bool maskcheck(const void *, int, int); -#endif +#endif /* __TINC_NETUTL_H__ */ diff --git a/src/node.c b/src/node.c index 03be21c..38123e2 100644 --- a/src/node.c +++ b/src/node.c @@ -1,6 +1,6 @@ /* node.c -- node tree management - Copyright (C) 2001-2016 Guus Sliepen , + Copyright (C) 2001-2011 Guus Sliepen , 2001-2005 Ivo Timmermans This program is free software; you can redistribute it and/or modify @@ -20,7 +20,8 @@ #include "system.h" -#include "avl_tree.h" +#include "control_common.h" +#include "splay_tree.h" #include "logger.h" #include "net.h" #include "netutl.h" @@ -28,8 +29,8 @@ #include "utils.h" #include "xalloc.h" -avl_tree_t *node_tree; /* Known nodes, sorted by name */ -avl_tree_t *node_udp_tree; /* Known nodes, sorted by address and port */ +splay_tree_t *node_tree; /* Known nodes, sorted by name */ +splay_tree_t *node_udp_tree; /* Known nodes, sorted by address and port */ node_t *myself; @@ -38,35 +39,32 @@ static int node_compare(const node_t *a, const node_t *b) { } static int node_udp_compare(const node_t *a, const node_t *b) { - return sockaddrcmp(&a->address, &b->address); + int result; + + result = sockaddrcmp(&a->address, &b->address); + + if(result) + return result; + + return (a->name && b->name) ? strcmp(a->name, b->name) : 0; } void init_nodes(void) { - node_tree = avl_alloc_tree((avl_compare_t) node_compare, (avl_action_t) free_node); - node_udp_tree = avl_alloc_tree((avl_compare_t) node_udp_compare, NULL); + node_tree = splay_alloc_tree((splay_compare_t) node_compare, (splay_action_t) free_node); + node_udp_tree = splay_alloc_tree((splay_compare_t) node_udp_compare, NULL); } void exit_nodes(void) { - avl_delete_tree(node_udp_tree); - avl_delete_tree(node_tree); + splay_delete_tree(node_udp_tree); + splay_delete_tree(node_tree); } node_t *new_node(void) { - node_t *n = xmalloc_and_zero(sizeof(*n)); - - if(replaywin) { - n->late = xmalloc_and_zero(replaywin); - } + node_t *n = xmalloc_and_zero(sizeof *n); + if(replaywin) n->late = xmalloc_and_zero(replaywin); n->subnet_tree = new_subnet_tree(); n->edge_tree = new_edge_tree(); - n->inctx = EVP_CIPHER_CTX_new(); - n->outctx = EVP_CIPHER_CTX_new(); - - if(!n->inctx || !n->outctx) { - abort(); - } - n->mtu = MTU; n->maxmtu = MTU; @@ -74,52 +72,43 @@ node_t *new_node(void) { } void free_node(node_t *n) { - if(n->inkey) { - free(n->inkey); - } - - if(n->outkey) { - free(n->outkey); - } - - if(n->subnet_tree) { + if(n->subnet_tree) free_subnet_tree(n->subnet_tree); - } - if(n->edge_tree) { + if(n->edge_tree) free_edge_tree(n->edge_tree); - } sockaddrfree(&n->address); - EVP_CIPHER_CTX_free(n->outctx); - EVP_CIPHER_CTX_free(n->inctx); + cipher_close(&n->incipher); + digest_close(&n->indigest); + cipher_close(&n->outcipher); + digest_close(&n->outdigest); - if(n->mtuevent) { - event_del(n->mtuevent); - } + ecdh_free(&n->ecdh); + ecdsa_free(&n->ecdsa); - if(n->hostname) { + if(timeout_initialized(&n->mtuevent)) + event_del(&n->mtuevent); + + if(n->hostname) free(n->hostname); - } - if(n->name) { + if(n->name) free(n->name); - } - if(n->late) { + if(n->late) free(n->late); - } free(n); } void node_add(node_t *n) { - avl_insert(node_tree, n); + splay_insert(node_tree, n); } void node_del(node_t *n) { - avl_node_t *node, *next; + splay_node_t *node, *next; edge_t *e; subnet_t *s; @@ -135,25 +124,25 @@ void node_del(node_t *n) { edge_del(e); } - avl_delete(node_udp_tree, n); - avl_delete(node_tree, n); + splay_delete(node_udp_tree, n); + splay_delete(node_tree, n); } node_t *lookup_node(char *name) { - node_t n = {0}; + node_t n = {NULL}; n.name = name; - return avl_search(node_tree, &n); + return splay_search(node_tree, &n); } node_t *lookup_node_udp(const sockaddr_t *sa) { - node_t n = {0}; + node_t n = {NULL}; n.address = *sa; n.name = NULL; - return avl_search(node_udp_tree, &n); + return splay_search(node_udp_tree, &n); } void update_node_udp(node_t *n, const sockaddr_t *sa) { @@ -162,38 +151,48 @@ void update_node_udp(node_t *n, const sockaddr_t *sa) { return; } - avl_delete(node_udp_tree, n); + splay_delete(node_udp_tree, n); - if(n->hostname) { + if(n->hostname) free(n->hostname); - } if(sa) { n->address = *sa; n->hostname = sockaddr2hostname(&n->address); - avl_insert(node_udp_tree, n); + splay_insert(node_udp_tree, n); ifdebug(PROTOCOL) logger(LOG_DEBUG, "UDP address of %s set to %s", n->name, n->hostname); } else { - memset(&n->address, 0, sizeof(n->address)); + memset(&n->address, 0, sizeof n->address); n->hostname = NULL; ifdebug(PROTOCOL) logger(LOG_DEBUG, "UDP address of %s cleared", n->name); } } -void dump_nodes(void) { - avl_node_t *node; +bool dump_nodes(connection_t *c) { + splay_node_t *node; node_t *n; - logger(LOG_DEBUG, "Nodes:"); - for(node = node_tree->head; node; node = node->next) { n = node->data; - logger(LOG_DEBUG, " %s at %s cipher %d digest %d maclength %d compression %d options %x status %04x nexthop %s via %s pmtu %d (min %d max %d)", - n->name, n->hostname, n->outcipher ? EVP_CIPHER_nid(n->outcipher) : 0, - n->outdigest ? EVP_MD_type(n->outdigest) : 0, n->outmaclength, n->outcompression, - n->options, bitfield_to_int(&n->status, sizeof(n->status)), n->nexthop ? n->nexthop->name : "-", - n->via ? n->via->name : "-", n->mtu, n->minmtu, n->maxmtu); + send_request(c, "%d %d %s at %s cipher %d digest %d maclength %d compression %d options %x status %04x nexthop %s via %s distance %d pmtu %hd (min %hd max %hd)", CONTROL, REQ_DUMP_NODES, + n->name, n->hostname, cipher_get_nid(&n->outcipher), + digest_get_nid(&n->outdigest), (int)digest_length(&n->outdigest), n->outcompression, + n->options, bitfield_to_int(&n->status, sizeof n->status), n->nexthop ? n->nexthop->name : "-", + n->via ? n->via->name ?: "-" : "-", n->distance, n->mtu, n->minmtu, n->maxmtu); } - logger(LOG_DEBUG, "End of nodes."); + return send_request(c, "%d %d", CONTROL, REQ_DUMP_NODES); +} + +bool dump_traffic(connection_t *c) { + splay_node_t *node; + node_t *n; + + for(node = node_tree->head; node; node = node->next) { + n = node->data; + send_request(c, "%d %d %s %"PRIu64" %"PRIu64" %"PRIu64" %"PRIu64, CONTROL, REQ_DUMP_TRAFFIC, + n->name, n->in_packets, n->in_bytes, n->out_packets, n->out_bytes); + } + + return send_request(c, "%d %d", CONTROL, REQ_DUMP_TRAFFIC); } diff --git a/src/node.h b/src/node.h index b360fe5..0ce7542 100644 --- a/src/node.h +++ b/src/node.h @@ -1,9 +1,6 @@ -#ifndef TINC_NODE_H -#define TINC_NODE_H - /* node.h -- header for node.c - Copyright (C) 2001-2016 Guus Sliepen , + Copyright (C) 2001-2010 Guus Sliepen , 2001-2005 Ivo Timmermans This program is free software; you can redistribute it and/or modify @@ -21,86 +18,90 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#include "avl_tree.h" +#ifndef __TINC_NODE_H__ +#define __TINC_NODE_H__ + +#include "splay_tree.h" +#include "cipher.h" #include "connection.h" -#include "event.h" +#include "digest.h" +#include "ecdh.h" #include "subnet.h" typedef struct node_status_t { - unsigned int unused_active: 1; /* 1 if active (not used for nodes) */ - unsigned int validkey: 1; /* 1 if we currently have a valid key for him */ - unsigned int unused_waitingforkey: 1; /* 1 if we already sent out a request */ - unsigned int visited: 1; /* 1 if this node has been visited by one of the graph algorithms */ - unsigned int reachable: 1; /* 1 if this node is reachable in the graph */ - unsigned int indirect: 1; /* 1 if this node is not directly reachable by us */ - unsigned int unused: 26; + unsigned int unused_active:1; /* 1 if active (not used for nodes) */ + unsigned int validkey:1; /* 1 if we currently have a valid key for him */ + unsigned int unused_waitingforkey:1; /* 1 if we already sent out a request */ + unsigned int visited:1; /* 1 if this node has been visited by one of the graph algorithms */ + unsigned int reachable:1; /* 1 if this node is reachable in the graph */ + unsigned int indirect:1; /* 1 if this node is not directly reachable by us */ + unsigned int ecdh:1; /* 1 if this node supports ECDH key exchange */ + unsigned int unused:25; } node_status_t; typedef struct node_t { - char *name; /* name of this node */ - uint32_t options; /* options turned on for this node */ + char *name; /* name of this node */ + uint32_t options; /* options turned on for this node */ - int sock; /* Socket to use for outgoing UDP packets */ - sockaddr_t address; /* his real (internet) ip to send UDP packets to */ - char *hostname; /* the hostname of its real ip */ + sockaddr_t address; /* his real (internet) ip to send UDP packets to */ + 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 */ - int inkeylength; /* Cipher key and iv length */ - EVP_CIPHER_CTX *inctx; /* Cipher context */ + ecdsa_t ecdsa; /* His public ECDSA key */ + ecdh_t ecdh; /* State for ECDH key exchange */ - const EVP_CIPHER *outcipher; /* Cipher type for UDP packets sent to him*/ - char *outkey; /* Cipher key and iv */ - int outkeylength; /* Cipher key and iv length */ - EVP_CIPHER_CTX *outctx; /* Cipher context */ + cipher_t incipher; /* Cipher for UDP packets */ + digest_t indigest; /* Digest for UDP packets */ - const EVP_MD *indigest; /* Digest type for MAC of packets received from him */ - int inmaclength; /* Length of MAC */ + cipher_t outcipher; /* Cipher for UDP packets */ + digest_t outdigest; /* Digest for UDP packets */ - const EVP_MD *outdigest; /* Digest type for MAC of packets sent to him*/ - int outmaclength; /* Length of MAC */ + int incompression; /* Compressionlevel, 0 = no compression */ + int outcompression; /* Compressionlevel, 0 = no compression */ - int incompression; /* Compressionlevel, 0 = no compression */ - int outcompression; /* Compressionlevel, 0 = no compression */ + int distance; + struct node_t *nexthop; /* nearest node from us to him */ + struct node_t *via; /* next hop for UDP packets */ - struct node_t *nexthop; /* nearest node from us to him */ - struct edge_t *prevedge; /* nearest node from him to us */ - struct node_t *via; /* next hop for UDP packets */ + splay_tree_t *subnet_tree; /* Pointer to a tree of subnets belonging to this node */ - avl_tree_t *subnet_tree; /* Pointer to a tree of subnets belonging to this node */ + splay_tree_t *edge_tree; /* Edges with this node as one of the endpoints */ - avl_tree_t *edge_tree; /* Edges with this node as one of the endpoints */ + struct connection_t *connection; /* Connection associated with this node (if a direct connection exists) */ - struct connection_t *connection; /* Connection associated with this node (if a direct connection exists) */ + uint32_t sent_seqno; /* Sequence number last sent to this node */ + uint32_t received_seqno; /* Sequence number last received from this node */ + uint32_t farfuture; /* Packets in a row that have arrived from the far future */ + unsigned char* late; /* Bitfield marking late packets */ - uint32_t sent_seqno; /* Sequence number last sent to this node */ - uint32_t received_seqno; /* Sequence number last received from this node */ - uint32_t farfuture; /* Packets in a row that have arrived from the far future */ - unsigned char *late; /* Bitfield marking late packets */ + length_t mtu; /* Maximum size of packets to send to this node */ + length_t minmtu; /* Probed minimum MTU */ + length_t maxmtu; /* Probed maximum MTU */ + int mtuprobes; /* Number of probes */ + struct event mtuevent; /* Probe event */ - length_t mtu; /* Maximum size of packets to send to this node */ - length_t minmtu; /* Probed minimum MTU */ - length_t maxmtu; /* Probed maximum MTU */ - int mtuprobes; /* Number of probes */ - event_t *mtuevent; /* Probe event */ + uint64_t in_packets; + uint64_t in_bytes; + uint64_t out_packets; + uint64_t out_bytes; } node_t; extern struct node_t *myself; -extern avl_tree_t *node_tree; -extern avl_tree_t *node_udp_tree; +extern splay_tree_t *node_tree; +extern splay_tree_t *node_udp_tree; extern void init_nodes(void); extern void exit_nodes(void); -extern node_t *new_node(void) __attribute__((__malloc__)); -extern void free_node(node_t *n); -extern void node_add(node_t *n); -extern void node_del(node_t *n); -extern node_t *lookup_node(char *name); -extern node_t *lookup_node_udp(const sockaddr_t *sa); -extern void update_node_udp(node_t *n, const sockaddr_t *sa); -extern void dump_nodes(void); +extern node_t *new_node(void) __attribute__ ((__malloc__)); +extern void free_node(node_t *); +extern void node_add(node_t *); +extern void node_del(node_t *); +extern node_t *lookup_node(char *); +extern node_t *lookup_node_udp(const sockaddr_t *); +extern bool dump_nodes(struct connection_t *); +extern bool dump_traffic(struct connection_t *); +extern void update_node_udp(node_t *, const sockaddr_t *); -#endif +#endif /* __TINC_NODE_H__ */ diff --git a/src/openssl/cipher.c b/src/openssl/cipher.c new file mode 100644 index 0000000..86a1aca --- /dev/null +++ b/src/openssl/cipher.c @@ -0,0 +1,146 @@ +/* + cipher.c -- Symmetric block cipher handling + Copyright (C) 2007 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "system.h" + +#include +#include + +#include "cipher.h" +#include "logger.h" +#include "xalloc.h" + +static bool cipher_open(cipher_t *cipher) { + EVP_CIPHER_CTX_init(&cipher->ctx); + + return true; +} + +bool cipher_open_by_name(cipher_t *cipher, const char *name) { + cipher->cipher = EVP_get_cipherbyname(name); + + if(cipher->cipher) + return cipher_open(cipher); + + logger(LOG_ERR, "Unknown cipher name '%s'!", name); + return false; +} + +bool cipher_open_by_nid(cipher_t *cipher, int nid) { + cipher->cipher = EVP_get_cipherbynid(nid); + + if(cipher->cipher) + return cipher_open(cipher); + + logger(LOG_ERR, "Unknown cipher nid %d!", nid); + return false; +} + +bool cipher_open_blowfish_ofb(cipher_t *cipher) { + cipher->cipher = EVP_bf_ofb(); + return cipher_open(cipher); +} + +void cipher_close(cipher_t *cipher) { + EVP_CIPHER_CTX_cleanup(&cipher->ctx); +} + +size_t cipher_keylength(const cipher_t *cipher) { + return cipher->cipher->key_len + cipher->cipher->iv_len; +} + +bool cipher_set_key(cipher_t *cipher, void *key, bool encrypt) { + bool result; + + if(encrypt) + result = EVP_EncryptInit_ex(&cipher->ctx, cipher->cipher, NULL, (unsigned char *)key, (unsigned char *)key + cipher->cipher->key_len); + else + result = EVP_DecryptInit_ex(&cipher->ctx, cipher->cipher, NULL, (unsigned char *)key, (unsigned char *)key + cipher->cipher->key_len); + + if(result) + return true; + + logger(LOG_ERR, "Error while setting key: %s", ERR_error_string(ERR_get_error(), NULL)); + return false; +} + +bool cipher_set_key_from_rsa(cipher_t *cipher, void *key, size_t len, bool encrypt) { + bool result; + + if(encrypt) + result = EVP_EncryptInit_ex(&cipher->ctx, cipher->cipher, NULL, (unsigned char *)key + len - cipher->cipher->key_len, (unsigned char *)key + len - cipher->cipher->iv_len - cipher->cipher->key_len); + else + result = EVP_DecryptInit_ex(&cipher->ctx, cipher->cipher, NULL, (unsigned char *)key + len - cipher->cipher->key_len, (unsigned char *)key + len - cipher->cipher->iv_len - cipher->cipher->key_len); + + if(result) + return true; + + logger(LOG_ERR, "Error while setting key: %s", ERR_error_string(ERR_get_error(), NULL)); + return false; +} + +bool cipher_encrypt(cipher_t *cipher, const void *indata, size_t inlen, void *outdata, size_t *outlen, bool oneshot) { + if(oneshot) { + int len, pad; + if(EVP_EncryptInit_ex(&cipher->ctx, NULL, NULL, NULL, NULL) + && EVP_EncryptUpdate(&cipher->ctx, (unsigned char *)outdata, &len, indata, inlen) + && EVP_EncryptFinal(&cipher->ctx, (unsigned char *)outdata + len, &pad)) { + *outlen = len + pad; + return true; + } + } else { + int len; + if(EVP_EncryptUpdate(&cipher->ctx, outdata, &len, indata, inlen)) { + *outlen = len; + return true; + } + } + + logger(LOG_ERR, "Error while encrypting: %s", ERR_error_string(ERR_get_error(), NULL)); + return false; +} + +bool cipher_decrypt(cipher_t *cipher, const void *indata, size_t inlen, void *outdata, size_t *outlen, bool oneshot) { + if(oneshot) { + int len, pad; + if(EVP_DecryptInit_ex(&cipher->ctx, NULL, NULL, NULL, NULL) + && EVP_DecryptUpdate(&cipher->ctx, (unsigned char *)outdata, &len, indata, inlen) + && EVP_DecryptFinal(&cipher->ctx, (unsigned char *)outdata + len, &pad)) { + *outlen = len + pad; + return true; + } + } else { + int len; + if(EVP_EncryptUpdate(&cipher->ctx, outdata, &len, indata, inlen)) { + *outlen = len; + return true; + } + } + + logger(LOG_ERR, "Error while decrypting: %s", ERR_error_string(ERR_get_error(), NULL)); + return false; +} + +int cipher_get_nid(const cipher_t *cipher) { + return cipher->cipher ? cipher->cipher->nid : 0; +} + +bool cipher_active(const cipher_t *cipher) { + return cipher->cipher && cipher->cipher->nid != 0; +} diff --git a/src/openssl/cipher.h b/src/openssl/cipher.h new file mode 100644 index 0000000..380384a --- /dev/null +++ b/src/openssl/cipher.h @@ -0,0 +1,46 @@ +/* + cipher.h -- header file cipher.c + Copyright (C) 2007 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#ifndef __TINC_CIPHER_H__ +#define __TINC_CIPHER_H__ + +#include + +#define CIPHER_MAX_BLOCK_SIZE EVP_MAX_BLOCK_LENGTH +#define CIPHER_MAX_KEY_SIZE EVP_MAX_KEY_LENGTH +#define CIPHER_MAX_IV_SIZE EVP_MAX_IV_LENGTH + +typedef struct cipher { + EVP_CIPHER_CTX ctx; + const EVP_CIPHER *cipher; +} cipher_t; + +extern bool cipher_open_by_name(cipher_t *, const char *); +extern bool cipher_open_by_nid(cipher_t *, int); +extern bool cipher_open_blowfish_ofb(cipher_t *); +extern void cipher_close(cipher_t *); +extern size_t cipher_keylength(const cipher_t *); +extern bool cipher_set_key(cipher_t *, void *, bool); +extern bool cipher_set_key_from_rsa(cipher_t *, void *, size_t, bool); +extern bool cipher_encrypt(cipher_t *, const void *indata, size_t inlen, void *outdata, size_t *outlen, bool); +extern bool cipher_decrypt(cipher_t *, const void *indata, size_t inlen, void *outdata, size_t *outlen, bool); +extern int cipher_get_nid(const cipher_t *); +extern bool cipher_active(const cipher_t *); + +#endif diff --git a/src/openssl/crypto.c b/src/openssl/crypto.c new file mode 100644 index 0000000..db921d6 --- /dev/null +++ b/src/openssl/crypto.c @@ -0,0 +1,43 @@ +/* + crypto.c -- Cryptographic miscellaneous functions and initialisation + Copyright (C) 2007 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "system.h" + +#include +#include +#include + +#include "crypto.h" + +void crypto_init(void) { + RAND_load_file("/dev/urandom", 1024); + + ENGINE_load_builtin_engines(); + ENGINE_register_all_complete(); + + OpenSSL_add_all_algorithms(); +} + +void crypto_exit(void) { + EVP_cleanup(); +} + +void randomize(void *out, size_t outlen) { + RAND_pseudo_bytes(out, outlen); +} diff --git a/src/openssl/crypto.h b/src/openssl/crypto.h new file mode 100644 index 0000000..8047bfb --- /dev/null +++ b/src/openssl/crypto.h @@ -0,0 +1,27 @@ +/* + crypto.h -- header for crypto.c + Copyright (C) 2007 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#ifndef __TINC_CRYPTO_H__ +#define __TINC_CRYPTO_H__ + +extern void crypto_init(); +extern void crypto_exit(); +extern void randomize(void *, size_t); + +#endif diff --git a/src/openssl/digest.c b/src/openssl/digest.c new file mode 100644 index 0000000..09ed666 --- /dev/null +++ b/src/openssl/digest.c @@ -0,0 +1,124 @@ +/* + digest.c -- Digest handling + Copyright (C) 2007 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "system.h" +#include "utils.h" +#include "xalloc.h" + +#include +#include + +#include "digest.h" +#include "logger.h" + +static void set_maclength(digest_t *digest, int maclength) { + int digestlen = EVP_MD_size(digest->digest); + + if(maclength > digestlen || maclength < 0) + digest->maclength = digestlen; + else + digest->maclength = maclength; +} + +bool digest_open_by_name(digest_t *digest, const char *name, int maclength) { + digest->digest = EVP_get_digestbyname(name); + digest->key = NULL; + + if(!digest->digest) { + logger(LOG_DEBUG, "Unknown digest name '%s'!", name); + return false; + } + + set_maclength(digest, maclength); + return true; +} + +bool digest_open_by_nid(digest_t *digest, int nid, int maclength) { + digest->digest = EVP_get_digestbynid(nid); + digest->key = NULL; + + if(!digest->digest) { + logger(LOG_DEBUG, "Unknown digest nid %d!", nid); + return false; + } + + set_maclength(digest, maclength); + return true; +} + +bool digest_open_sha1(digest_t *digest, int maclength) { + digest->digest = EVP_sha1(); + digest->key = NULL; + + set_maclength(digest, maclength); + return true; +} + +bool digest_set_key(digest_t *digest, const void *key, size_t len) { + digest->key = xrealloc(digest->key, len); + memcpy(digest->key, key, len); + digest->keylength = len; + return true; +} + +void digest_close(digest_t *digest) { + if(digest->key) + free(digest->key); + digest->key = NULL; +} + +bool digest_create(digest_t *digest, const void *indata, size_t inlen, void *outdata) { + size_t len = EVP_MD_size(digest->digest); + unsigned char tmpdata[len]; + + if(digest->key) { + HMAC(digest->digest, digest->key, digest->keylength, indata, inlen, tmpdata, NULL); + } else { + EVP_MD_CTX ctx; + + if(!EVP_DigestInit(&ctx, digest->digest) + || !EVP_DigestUpdate(&ctx, indata, inlen) + || !EVP_DigestFinal(&ctx, tmpdata, NULL)) { + logger(LOG_DEBUG, "Error creating digest: %s", ERR_error_string(ERR_get_error(), NULL)); + return false; + } + } + + memcpy(outdata, tmpdata, digest->maclength); + return true; +} + +bool digest_verify(digest_t *digest, const void *indata, size_t inlen, const void *cmpdata) { + size_t len = digest->maclength; + unsigned char outdata[len]; + + return digest_create(digest, indata, inlen, outdata) && !memcmp(cmpdata, outdata, digest->maclength); +} + +int digest_get_nid(const digest_t *digest) { + return digest->digest ? digest->digest->type : 0; +} + +size_t digest_length(const digest_t *digest) { + return digest->maclength; +} + +bool digest_active(const digest_t *digest) { + return digest->digest && digest->digest->type != 0; +} diff --git a/src/openssl/digest.h b/src/openssl/digest.h new file mode 100644 index 0000000..f3855c9 --- /dev/null +++ b/src/openssl/digest.h @@ -0,0 +1,45 @@ +/* + digest.h -- header file digest.c + Copyright (C) 2007 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#ifndef __TINC_DIGEST_H__ +#define __TINC_DIGEST_H__ + +#include + +#define DIGEST_MAX_SIZE EVP_MAX_MD_SIZE + +typedef struct digest { + const EVP_MD *digest; + int maclength; + int keylength; + char *key; +} digest_t; + +extern bool digest_open_by_name(struct digest *, const char *name, int maclength); +extern bool digest_open_by_nid(struct digest *, int nid, int maclength); +extern bool digest_open_sha1(struct digest *, int maclength); +extern void digest_close(struct digest *); +extern bool digest_create(struct digest *, const void *indata, size_t inlen, void *outdata); +extern bool digest_verify(struct digest *, const void *indata, size_t inlen, const void *digestdata); +extern bool digest_set_key(struct digest *, const void *key, size_t len); +extern int digest_get_nid(const struct digest *); +extern size_t digest_length(const struct digest *); +extern bool digest_active(const struct digest *); + +#endif diff --git a/src/openssl/ecdh.c b/src/openssl/ecdh.c new file mode 100644 index 0000000..4dd399f --- /dev/null +++ b/src/openssl/ecdh.c @@ -0,0 +1,84 @@ +/* + ecdh.c -- Diffie-Hellman key exchange handling + Copyright (C) 2011 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "system.h" +#include "utils.h" +#include "xalloc.h" + +#include +#include +#include + +#include "ecdh.h" +#include "logger.h" + +bool ecdh_generate_public(ecdh_t *ecdh, void *pubkey) { + *ecdh = EC_KEY_new_by_curve_name(NID_secp521r1); + if(!EC_KEY_generate_key(*ecdh)) { + logger(LOG_ERR, "Generating EC key failed: %s", ERR_error_string(ERR_get_error(), NULL)); + abort(); + } + + const EC_POINT *point = EC_KEY_get0_public_key(*ecdh); + if(!point) { + logger(LOG_ERR, "Getting public key failed: %s", ERR_error_string(ERR_get_error(), NULL)); + abort(); + } + + size_t result = EC_POINT_point2oct(EC_KEY_get0_group(*ecdh), point, POINT_CONVERSION_COMPRESSED, pubkey, ECDH_SIZE, NULL); + if(!result) { + logger(LOG_ERR, "Converting EC_POINT to binary failed: %s", ERR_error_string(ERR_get_error(), NULL)); + abort(); + } + + return true; +} + +bool ecdh_compute_shared(ecdh_t *ecdh, const void *pubkey, void *shared) { + EC_POINT *point = EC_POINT_new(EC_KEY_get0_group(*ecdh)); + if(!point) { + logger(LOG_ERR, "EC_POINT_new() failed: %s", ERR_error_string(ERR_get_error(), NULL)); + abort(); + } + + int result = EC_POINT_oct2point(EC_KEY_get0_group(*ecdh), point, pubkey, ECDH_SIZE, NULL); + if(!result) { + logger(LOG_ERR, "Converting binary to EC_POINT failed: %s", ERR_error_string(ERR_get_error(), NULL)); + abort(); + } + + result = ECDH_compute_key(shared, ECDH_SIZE, point, *ecdh, NULL); + EC_POINT_free(point); + EC_KEY_free(*ecdh); + *ecdh = NULL; + + if(!result) { + logger(LOG_ERR, "Computing Elliptic Curve Diffie-Hellman shared key failed: %s", ERR_error_string(ERR_get_error(), NULL)); + return false; + } + + return true; +} + +void ecdh_free(ecdh_t *ecdh) { + if(*ecdh) { + EC_KEY_free(*ecdh); + *ecdh = NULL; + } +} diff --git a/src/proxy.h b/src/openssl/ecdh.h similarity index 58% rename from src/proxy.h rename to src/openssl/ecdh.h index a96fc3d..ef7de6e 100644 --- a/src/proxy.h +++ b/src/openssl/ecdh.h @@ -1,9 +1,6 @@ -#ifndef TINC_PROXY_H -#define TINC_PROXY_H - /* - proxy.h -- header for proxy.c - Copyright (C) 2015 Guus Sliepen + ecdh.h -- header file for ecdh.c + Copyright (C) 2011 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 @@ -20,24 +17,18 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#include "connection.h" +#ifndef __TINC_ECDH_H__ +#define __TINC_ECDH_H__ -typedef enum proxytype_t { - PROXY_NONE = 0, - PROXY_SOCKS4, - PROXY_SOCKS4A, - PROXY_SOCKS5, - PROXY_HTTP, - PROXY_EXEC, -} proxytype_t; +#include -extern proxytype_t proxytype; -extern char *proxyhost; -extern char *proxyport; -extern char *proxyuser; -extern char *proxypass; +#define ECDH_SIZE 67 +#define ECDH_SHARED_SIZE 66 -extern bool send_proxyrequest(struct connection_t *c); -extern int receive_proxy_meta(struct connection_t *c); +typedef EC_KEY *ecdh_t; + +extern bool ecdh_generate_public(ecdh_t *ecdh, void *pubkey); +extern bool ecdh_compute_shared(ecdh_t *ecdh, const void *pubkey, void *shared); +extern void ecdh_free(ecdh_t *ecdh); #endif diff --git a/src/openssl/ecdsa.c b/src/openssl/ecdsa.c new file mode 100644 index 0000000..43464d8 --- /dev/null +++ b/src/openssl/ecdsa.c @@ -0,0 +1,130 @@ +/* + ecdsa.c -- ECDSA key handling + Copyright (C) 2011 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "system.h" + +#include +#include + +#include "logger.h" +#include "ecdsa.h" +#include "utils.h" + +// Get and set ECDSA keys +// +bool ecdsa_set_base64_public_key(ecdsa_t *ecdsa, const char *p) { + *ecdsa = EC_KEY_new_by_curve_name(NID_secp521r1); + + int len = strlen(p); + unsigned char pubkey[len / 4 * 3 + 3]; + const unsigned char *ppubkey = pubkey; + len = b64decode(p, pubkey, len); + + if(!o2i_ECPublicKey(ecdsa, &ppubkey, len)) { + logger(LOG_DEBUG, "o2i_ECPublicKey failed: %s", ERR_error_string(ERR_get_error(), NULL)); + abort(); + } + + return true; +} + +char *ecdsa_get_base64_public_key(ecdsa_t *ecdsa) { + unsigned char *pubkey = NULL; + int len = i2o_ECPublicKey(*ecdsa, &pubkey); + + char *base64 = malloc(len * 4 / 3 + 5); + b64encode(pubkey, base64, len); + + free(pubkey); + + return base64; +} + +// Read PEM ECDSA keys + +bool ecdsa_read_pem_public_key(ecdsa_t *ecdsa, FILE *fp) { + *ecdsa = PEM_read_EC_PUBKEY(fp, ecdsa, NULL, NULL); + + if(*ecdsa) + return true; + + logger(LOG_ERR, "Unable to read ECDSA public key: %s", ERR_error_string(ERR_get_error(), NULL)); + return false; +} + +bool ecdsa_read_pem_private_key(ecdsa_t *ecdsa, FILE *fp) { + *ecdsa = PEM_read_ECPrivateKey(fp, NULL, NULL, NULL); + + if(*ecdsa) + return true; + + logger(LOG_ERR, "Unable to read ECDSA private key: %s", ERR_error_string(ERR_get_error(), NULL)); + return false; +} + +size_t ecdsa_size(ecdsa_t *ecdsa) { + return ECDSA_size(*ecdsa); +} + +// TODO: standardise output format? + +bool ecdsa_sign(ecdsa_t *ecdsa, const void *in, size_t len, void *sig) { + unsigned int siglen = ECDSA_size(*ecdsa); + + char hash[SHA512_DIGEST_LENGTH]; + SHA512(in, len, hash); + + memset(sig, 0, siglen); + + if(!ECDSA_sign(0, hash, sizeof hash, sig, &siglen, *ecdsa)) { + logger(LOG_DEBUG, "ECDSA_sign() failed: %s", ERR_error_string(ERR_get_error(), NULL)); + return false; + } + + if(siglen != ECDSA_size(*ecdsa)) { + logger(LOG_ERR, "Signature length %d != %d", siglen, ECDSA_size(*ecdsa)); + } + + return true; +} + +bool ecdsa_verify(ecdsa_t *ecdsa, const void *in, size_t len, const void *sig) { + unsigned int siglen = ECDSA_size(*ecdsa); + + char hash[SHA512_DIGEST_LENGTH]; + SHA512(in, len, hash); + + if(!ECDSA_verify(0, hash, sizeof hash, sig, siglen, *ecdsa)) { + logger(LOG_DEBUG, "ECDSA_verify() failed: %s", ERR_error_string(ERR_get_error(), NULL)); + return false; + } + + return true; +} + +bool ecdsa_active(ecdsa_t *ecdsa) { + return *ecdsa; +} + +void ecdsa_free(ecdsa_t *ecdsa) { + if(*ecdsa) { + EC_KEY_free(*ecdsa); + *ecdsa = NULL; + } +} diff --git a/src/openssl/ecdsa.h b/src/openssl/ecdsa.h new file mode 100644 index 0000000..04f9eb9 --- /dev/null +++ b/src/openssl/ecdsa.h @@ -0,0 +1,37 @@ +/* + ecdsa.h -- ECDSA key handling + Copyright (C) 2011 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#ifndef __TINC_ECDSA_H__ +#define __TINC_ECDSA_H__ + +#include + +typedef EC_KEY *ecdsa_t; + +extern bool ecdsa_set_base64_public_key(ecdsa_t *ecdsa, const char *p); +extern char *ecdsa_get_base64_public_key(ecdsa_t *ecdsa); +extern bool ecdsa_read_pem_public_key(ecdsa_t *ecdsa, FILE *fp); +extern bool ecdsa_read_pem_private_key(ecdsa_t *ecdsa, FILE *fp); +extern size_t ecdsa_size(ecdsa_t *ecdsa); +extern bool ecdsa_sign(ecdsa_t *ecdsa, const void *in, size_t inlen, void *out); +extern bool ecdsa_verify(ecdsa_t *ecdsa, const void *in, size_t inlen, const void *out); +extern bool ecdsa_active(ecdsa_t *ecdsa); +extern void ecdsa_free(ecdsa_t *ecdsa); + +#endif diff --git a/src/openssl/ecdsagen.c b/src/openssl/ecdsagen.c new file mode 100644 index 0000000..86b79a2 --- /dev/null +++ b/src/openssl/ecdsagen.c @@ -0,0 +1,75 @@ +/* + ecdsagen.c -- ECDSA key generation and export + Copyright (C) 2011 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "system.h" + +#include +#include +#include + +#include "ecdsagen.h" +#include "utils.h" + +// Generate ECDSA key + +bool ecdsa_generate(ecdsa_t *ecdsa) { + *ecdsa = EC_KEY_new_by_curve_name(NID_secp521r1); + + if(!EC_KEY_generate_key(*ecdsa)) { + fprintf(stderr, "Generating EC key failed: %s", ERR_error_string(ERR_get_error(), NULL)); + return false; + } + + EC_KEY_set_asn1_flag(*ecdsa, OPENSSL_EC_NAMED_CURVE); + EC_KEY_set_conv_form(*ecdsa, POINT_CONVERSION_COMPRESSED); + + return true; +} + +// Write PEM ECDSA keys + +bool ecdsa_write_pem_public_key(ecdsa_t *ecdsa, FILE *fp) { + BIO *out = BIO_new(BIO_s_file()); + BIO_set_fp(out,fp,BIO_NOCLOSE); + PEM_write_bio_EC_PUBKEY(out, *ecdsa); + BIO_free(out); + return true; +} + +bool ecdsa_write_pem_private_key(ecdsa_t *ecdsa, FILE *fp) { + BIO *out = BIO_new(BIO_s_file()); + BIO_set_fp(out,fp,BIO_NOCLOSE); + PEM_write_bio_ECPrivateKey(out, *ecdsa, NULL, NULL, 0, NULL, NULL); + BIO_free(out); + return true; +} + +// Convert ECDSA public key to base64 format + +char *ecdsa_get_base64_public_key(ecdsa_t *ecdsa) { + unsigned char *pubkey = NULL; + int len = i2o_ECPublicKey(*ecdsa, &pubkey); + + char *base64 = malloc(len * 4 / 3 + 5); + b64encode(pubkey, base64, len); + + free(pubkey); + + return base64; +} diff --git a/src/openssl/ecdsagen.h b/src/openssl/ecdsagen.h new file mode 100644 index 0000000..8a40e45 --- /dev/null +++ b/src/openssl/ecdsagen.h @@ -0,0 +1,30 @@ +/* + ecdsagen.h -- ECDSA key generation and export + Copyright (C) 2011 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#ifndef __TINC_ECDSAGEN_H__ +#define __TINC_ECDSAGEN_H__ + +#include "ecdsa.h" + +extern bool ecdsa_generate(ecdsa_t *ecdsa); +extern bool ecdsa_write_pem_public_key(ecdsa_t *ecdsa, FILE *fp); +extern bool ecdsa_write_pem_private_key(ecdsa_t *ecdsa, FILE *fp); +extern char *ecdsa_get_base64_public_key(ecdsa_t *ecdsa); + +#endif diff --git a/src/openssl/prf.c b/src/openssl/prf.c new file mode 100644 index 0000000..df7f445 --- /dev/null +++ b/src/openssl/prf.c @@ -0,0 +1,76 @@ +/* + prf.c -- Pseudo-Random Function for key material generation + Copyright (C) 2011 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "system.h" + +#include "digest.h" +#include "prf.h" + +/* Generate key material from a master secret and a seed, based on RFC 4346 section 5. + We use SHA512 and Whirlpool instead of MD5 and SHA1. + */ + +static bool prf_xor(int nid, char *secret, size_t secretlen, char *seed, size_t seedlen, char *out, ssize_t outlen) { + digest_t digest; + + if(!digest_open_by_nid(&digest, nid, -1)) + return false; + + if(!digest_set_key(&digest, secret, secretlen)) + return false; + + size_t len = digest_length(&digest); + + /* Data is what the "inner" HMAC function processes. + It consists of the previous HMAC result plus the seed. + */ + + char data[len + seedlen]; + memset(data, 0, len); + memcpy(data + len, seed, seedlen); + + char hash[len]; + + while(outlen > 0) { + /* Inner HMAC */ + digest_create(&digest, data, len + seedlen, data); + + /* Outer HMAC */ + digest_create(&digest, data, len + seedlen, hash); + + /* XOR the results of the outer HMAC into the out buffer */ + for(int i = 0; i < len && i < outlen; i++) + *out++ ^= hash[i]; + + outlen -= len; + } + + digest_close(&digest); + return true; +} + +bool prf(char *secret, size_t secretlen, char *seed, size_t seedlen, char *out, size_t outlen) { + /* Split secret in half, generate outlen bits with two different hash algorithms, + and XOR the results. */ + + memset(out, 0, outlen); + + return prf_xor(NID_sha512, secret, (secretlen + 1) / 2, seed, seedlen, out, outlen) + && prf_xor(NID_whirlpool, secret + secretlen / 2, (secretlen + 1) / 2, seed, seedlen, out, outlen); +} diff --git a/src/openssl/prf.h b/src/openssl/prf.h new file mode 100644 index 0000000..264d198 --- /dev/null +++ b/src/openssl/prf.h @@ -0,0 +1,25 @@ +/* + prf.h -- header file for prf.c + Copyright (C) 2011 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#ifndef __TINC_PRF_H__ +#define __TINC_PRF_H__ + +extern bool prf(char *secret, size_t secretlen, char *seed, size_t seedlen, char *out, size_t outlen); + +#endif diff --git a/src/openssl/rsa.c b/src/openssl/rsa.c new file mode 100644 index 0000000..c3ea692 --- /dev/null +++ b/src/openssl/rsa.c @@ -0,0 +1,101 @@ +/* + rsa.c -- RSA key handling + Copyright (C) 2007 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "system.h" + +#include +#include + +#include "logger.h" +#include "rsa.h" + +// Set RSA keys + +bool rsa_set_hex_public_key(rsa_t *rsa, char *n, char *e) { + *rsa = RSA_new(); + BN_hex2bn(&(*rsa)->n, n); + BN_hex2bn(&(*rsa)->e, e); + return true; +} + +bool rsa_set_hex_private_key(rsa_t *rsa, char *n, char *e, char *d) { + *rsa = RSA_new(); + BN_hex2bn(&(*rsa)->n, n); + BN_hex2bn(&(*rsa)->e, e); + BN_hex2bn(&(*rsa)->d, d); + return true; +} + +// Read PEM RSA keys + +bool rsa_read_pem_public_key(rsa_t *rsa, FILE *fp) { + *rsa = PEM_read_RSAPublicKey(fp, rsa, NULL, NULL); + + if(*rsa) + return true; + + *rsa = PEM_read_RSA_PUBKEY(fp, rsa, NULL, NULL); + + if(*rsa) + return true; + + logger(LOG_ERR, "Unable to read RSA public key: %s", ERR_error_string(ERR_get_error(), NULL)); + return false; +} + +bool rsa_read_pem_private_key(rsa_t *rsa, FILE *fp) { + *rsa = PEM_read_RSAPrivateKey(fp, NULL, NULL, NULL); + + if(*rsa) + return true; + + logger(LOG_ERR, "Unable to read RSA private key: %s", ERR_error_string(ERR_get_error(), NULL)); + return false; +} + +size_t rsa_size(rsa_t *rsa) { + return RSA_size(*rsa); +} + +bool rsa_public_encrypt(rsa_t *rsa, void *in, size_t len, void *out) { + if(RSA_public_encrypt(len, in, out, *rsa, RSA_NO_PADDING) == len) + return true; + + logger(LOG_ERR, "Unable to perform RSA encryption: %s", ERR_error_string(ERR_get_error(), NULL)); + return false; +} + +bool rsa_private_decrypt(rsa_t *rsa, void *in, size_t len, void *out) { + if(RSA_private_decrypt(len, in, out, *rsa, RSA_NO_PADDING) == len) + return true; + + logger(LOG_ERR, "Unable to perform RSA decryption: %s", ERR_error_string(ERR_get_error(), NULL)); + return false; +} + +bool rsa_active(rsa_t *rsa) { + return *rsa; +} + +void rsa_free(rsa_t *rsa) { + if(*rsa) { + RSA_free(*rsa); + *rsa = NULL; + } +} diff --git a/src/event.h b/src/openssl/rsa.h similarity index 50% rename from src/event.h rename to src/openssl/rsa.h index 6d521bb..10fe346 100644 --- a/src/event.h +++ b/src/openssl/rsa.h @@ -1,10 +1,6 @@ -#ifndef TINC_EVENT_H -#define TINC_EVENT_H - /* - event.h -- header for event.c - Copyright (C) 2002-2009 Guus Sliepen , - 2002-2005 Ivo Timmermans + rsa.h -- RSA key handling + Copyright (C) 2007 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 @@ -21,27 +17,22 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#include "avl_tree.h" +#ifndef __TINC_RSA_H__ +#define __TINC_RSA_H__ -extern avl_tree_t *event_tree; +#include -typedef void (*event_handler_t)(void *); +typedef RSA *rsa_t; -typedef struct event { - time_t time; - int id; - event_handler_t handler; - void *data; -} event_t; +extern bool rsa_set_hex_public_key(rsa_t *rsa, char *n, char *e); +extern bool rsa_set_hex_private_key(rsa_t *rsa, char *n, char *e, char *d); +extern bool rsa_read_pem_public_key(rsa_t *rsa, FILE *fp); +extern bool rsa_read_pem_private_key(rsa_t *rsa, FILE *fp); +extern size_t rsa_size(rsa_t *rsa); +extern bool rsa_public_encrypt(rsa_t *rsa, void *in, size_t inlen, void *out); +extern bool rsa_private_decrypt(rsa_t *rsa, void *in, size_t inlen, void *out); +extern bool rsa_active(rsa_t *rsa); +extern void rsa_free(rsa_t *rsa); -extern void init_events(void); -extern void exit_events(void); -extern void expire_events(void); -extern event_t *new_event(void) __attribute__((__malloc__)); -extern void free_event(event_t *event); -extern void event_add(event_t *event); -extern void event_del(event_t *event); -extern event_t *get_expired_event(void); -extern event_t *peek_next_event(void); #endif diff --git a/src/openssl/rsagen.c b/src/openssl/rsagen.c new file mode 100644 index 0000000..0f4a4fa --- /dev/null +++ b/src/openssl/rsagen.c @@ -0,0 +1,83 @@ +/* + rsagen.c -- RSA key generation and export + Copyright (C) 2008 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "system.h" + +#include +#include + +#include "logger.h" +#include "rsagen.h" + +/* This function prettyprints the key generation process */ + +static void indicator(int a, int b, void *p) { + switch (a) { + case 0: + fprintf(stderr, "."); + break; + + case 1: + fprintf(stderr, "+"); + break; + + case 2: + fprintf(stderr, "-"); + break; + + case 3: + switch (b) { + case 0: + fprintf(stderr, " p\n"); + break; + + case 1: + fprintf(stderr, " q\n"); + break; + + default: + fprintf(stderr, "?"); + } + break; + + default: + fprintf(stderr, "?"); + } +} + +// Generate RSA key + +bool rsa_generate(rsa_t *rsa, size_t bits, unsigned long exponent) { + *rsa = RSA_generate_key(bits, exponent, indicator, NULL); + + return *rsa; +} + +// Write PEM RSA keys + +bool rsa_write_pem_public_key(rsa_t *rsa, FILE *fp) { + PEM_write_RSAPublicKey(fp, *rsa); + + return true; +} + +bool rsa_write_pem_private_key(rsa_t *rsa, FILE *fp) { + PEM_write_RSAPrivateKey(fp, *rsa, NULL, NULL, 0, NULL, NULL); + return true; +} diff --git a/src/openssl/rsagen.h b/src/openssl/rsagen.h new file mode 100644 index 0000000..422d156 --- /dev/null +++ b/src/openssl/rsagen.h @@ -0,0 +1,29 @@ +/* + rsagen.h -- RSA key generation and export + Copyright (C) 2008 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#ifndef __TINC_RSAGEN_H__ +#define __TINC_RSAGEN_H__ + +#include "rsa.h" + +extern bool rsa_generate(rsa_t *rsa, size_t bits, unsigned long exponent); +extern bool rsa_write_pem_public_key(rsa_t *rsa, FILE *fp); +extern bool rsa_write_pem_private_key(rsa_t *rsa, FILE *fp); + +#endif diff --git a/src/pidfile.c b/src/pidfile.c deleted file mode 100644 index dd17267..0000000 --- a/src/pidfile.c +++ /dev/null @@ -1,142 +0,0 @@ -/* - pidfile.c - interact with pidfiles - Copyright (c) 1995 Martin Schulze - - This file is part of the sysklogd package, a kernel and system log daemon. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -/* left unaltered for tinc -- Ivo Timmermans */ -/* - * Sat Aug 19 13:24:33 MET DST 1995: Martin Schulze - * First version (v0.2) released - */ - -#include "system.h" - -#include "pidfile.h" - -#ifndef HAVE_MINGW -/* read_pid - * - * Reads the specified pidfile and returns the read pid. - * 0 is returned if either there's no pidfile, it's empty - * or no pid can be read. - */ -pid_t read_pid(const char *pidfile) { - FILE *f; - long pid; - - if(!(f = fopen(pidfile, "r"))) { - return 0; - } - - if(fscanf(f, "%20ld", &pid) != 1) { - pid = 0; - } - - fclose(f); - return (pid_t)pid; -} - -/* check_pid - * - * Reads the pid using read_pid and looks up the pid in the process - * table (using /proc) to determine if the process already exists. If - * so the pid is returned, otherwise 0. - */ -pid_t check_pid(const char *pidfile) { - pid_t pid = read_pid(pidfile); - - /* Amazing ! _I_ am already holding the pid file... */ - if((!pid) || (pid == getpid())) { - return 0; - } - - /* - * The 'standard' method of doing this is to try and do a 'fake' kill - * of the process. If an ESRCH error is returned the process cannot - * be found -- GW - */ - /* But... errno is usually changed only on error.. */ - errno = 0; - - if(kill(pid, 0) && errno == ESRCH) { - return 0; - } - - return pid; -} - -/* write_pid - * - * Writes the pid to the specified file. If that fails 0 is - * returned, otherwise the pid. - */ -pid_t write_pid(const char *pidfile) { - FILE *f; - int fd; - pid_t pid; - - if((fd = open(pidfile, O_RDWR | O_CREAT, 0644)) == -1) { - return 0; - } - - if((f = fdopen(fd, "r+")) == NULL) { - close(fd); - return 0; - } - -#ifdef HAVE_FLOCK - - if(flock(fd, LOCK_EX | LOCK_NB) == -1) { - fclose(f); - return 0; - } - -#endif - - pid = getpid(); - - if(!fprintf(f, "%ld\n", (long)pid)) { - fclose(f); - return 0; - } - - fflush(f); - -#ifdef HAVE_FLOCK - - if(flock(fd, LOCK_UN) == -1) { - fclose(f); - return 0; - } - -#endif - fclose(f); - - return pid; -} - -/* remove_pid - * - * Remove the the specified file. The result from unlink(2) - * is returned - */ -int remove_pid(const char *pidfile) { - return unlink(pidfile); -} -#endif diff --git a/src/pidfile.h b/src/pidfile.h deleted file mode 100644 index 7d71cc2..0000000 --- a/src/pidfile.h +++ /dev/null @@ -1,57 +0,0 @@ -#ifndef TINC_PIDFILE_H -#define TINC_PIDFILE_H - -/* - pidfile.h - interact with pidfiles - Copyright (c) 1995 Martin Schulze - - This file is part of the sysklogd package, a kernel and system log daemon. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#ifndef HAVE_MINGW -/* read_pid - * - * Reads the specified pidfile and returns the read pid. - * 0 is returned if either there's no pidfile, it's empty - * or no pid can be read. - */ -extern pid_t read_pid(const char *pidfile); - -/* check_pid - * - * Reads the pid using read_pid and looks up the pid in the process - * table (using /proc) to determine if the process already exists. If - * so 1 is returned, otherwise 0. - */ -extern pid_t check_pid(const char *pidfile); - -/* write_pid - * - * Writes the pid to the specified file. If that fails 0 is - * returned, otherwise the pid. - */ -extern pid_t write_pid(const char *pidfile); - -/* remove_pid - * - * Remove the the specified file. The result from unlink(2) - * is returned - */ -extern int remove_pid(const char *pidfile); -#endif - -#endif diff --git a/src/process.c b/src/process.c index 13d1007..a7d0f26 100644 --- a/src/process.c +++ b/src/process.c @@ -1,7 +1,7 @@ /* process.c -- process management functions Copyright (C) 1999-2005 Ivo Timmermans, - 2000-2015 Guus Sliepen + 2000-2011 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 @@ -22,12 +22,12 @@ #include "conf.h" #include "connection.h" +#include "control.h" #include "device.h" #include "edge.h" #include "logger.h" #include "net.h" #include "node.h" -#include "pidfile.h" #include "process.h" #include "subnet.h" #include "utils.h" @@ -35,18 +35,12 @@ /* If zero, don't detach from the terminal. */ bool do_detach = true; -bool sighup = false; bool sigalrm = false; extern char *identname; -extern char *pidfilename; extern char **g_argv; extern bool use_logfile; -#ifndef HAVE_MINGW -static sigset_t emptysigset; -#endif - /* Some functions the less gifted operating systems might lack... */ #ifdef HAVE_MINGW @@ -59,54 +53,49 @@ static SC_HANDLE service = NULL; static SERVICE_STATUS status = {0}; static SERVICE_STATUS_HANDLE statushandle = 0; -bool install_service(void) { +static bool install_service(void) { char command[4096] = "\""; char **argp; bool space; SERVICE_DESCRIPTION description = {"Virtual Private Network daemon"}; manager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); - if(!manager) { logger(LOG_ERR, "Could not open service manager: %s", winerror(GetLastError())); return false; } if(!strchr(program_name, '\\')) { - GetCurrentDirectory(sizeof(command) - 1, command + 1); - strncat(command, "\\", sizeof(command) - strlen(command)); + GetCurrentDirectory(sizeof command - 1, command + 1); + strncat(command, "\\", sizeof command - strlen(command)); } - strncat(command, program_name, sizeof(command) - strlen(command)); + strncat(command, program_name, sizeof command - strlen(command)); - strncat(command, "\"", sizeof(command) - strlen(command)); + strncat(command, "\"", sizeof command - strlen(command)); for(argp = g_argv + 1; *argp; argp++) { space = strchr(*argp, ' '); - strncat(command, " ", sizeof(command) - strlen(command)); + strncat(command, " ", sizeof command - strlen(command)); + + if(space) + strncat(command, "\"", sizeof command - strlen(command)); + + strncat(command, *argp, sizeof command - strlen(command)); - if(space) { - strncat(command, "\"", sizeof(command) - strlen(command)); - } - - strncat(command, *argp, sizeof(command) - strlen(command)); - - if(space) { - strncat(command, "\"", sizeof(command) - strlen(command)); - } + if(space) + strncat(command, "\"", sizeof command - strlen(command)); } service = CreateService(manager, identname, identname, - SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START, SERVICE_ERROR_NORMAL, - command, NULL, NULL, NULL, NULL, NULL); - + SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START, SERVICE_ERROR_NORMAL, + command, NULL, NULL, NULL, NULL, NULL); + if(!service) { DWORD lasterror = GetLastError(); logger(LOG_ERR, "Could not create %s service: %s", identname, winerror(lasterror)); - - if(lasterror != ERROR_SERVICE_EXISTS) { + if(lasterror != ERROR_SERVICE_EXISTS) return false; - } } if(service) { @@ -116,106 +105,67 @@ bool install_service(void) { service = OpenService(manager, identname, SERVICE_ALL_ACCESS); } - if(!StartService(service, 0, NULL)) { + if(!StartService(service, 0, NULL)) logger(LOG_WARNING, "Could not start %s service: %s", identname, winerror(GetLastError())); - } else { + else logger(LOG_INFO, "%s service started", identname); - } - - return true; -} - -bool remove_service(void) { - manager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); - - if(!manager) { - logger(LOG_ERR, "Could not open service manager: %s", winerror(GetLastError())); - return false; - } - - service = OpenService(manager, identname, SERVICE_ALL_ACCESS); - - if(!service) { - logger(LOG_ERR, "Could not open %s service: %s", identname, winerror(GetLastError())); - return false; - } - - if(!ControlService(service, SERVICE_CONTROL_STOP, &status)) { - logger(LOG_ERR, "Could not stop %s service: %s", identname, winerror(GetLastError())); - } else { - logger(LOG_INFO, "%s service stopped", identname); - } - - if(!DeleteService(service)) { - logger(LOG_ERR, "Could not remove %s service: %s", identname, winerror(GetLastError())); - return false; - } - - logger(LOG_INFO, "%s service removed", identname); return true; } DWORD WINAPI controlhandler(DWORD request, DWORD type, LPVOID boe, LPVOID bah) { switch(request) { - case SERVICE_CONTROL_INTERROGATE: - SetServiceStatus(statushandle, &status); - return NO_ERROR; - - case SERVICE_CONTROL_STOP: - logger(LOG_NOTICE, "Got %s request", "SERVICE_CONTROL_STOP"); - break; - - case SERVICE_CONTROL_SHUTDOWN: - logger(LOG_NOTICE, "Got %s request", "SERVICE_CONTROL_SHUTDOWN"); - break; - - default: - logger(LOG_WARNING, "Got unexpected request %d", (int)request); - return ERROR_CALL_NOT_IMPLEMENTED; - } - - if(running) { - running = false; - status.dwWaitHint = 30000; - status.dwCurrentState = SERVICE_STOP_PENDING; - SetServiceStatus(statushandle, &status); - return NO_ERROR; - } else { - status.dwWaitHint = 0; - status.dwCurrentState = SERVICE_STOPPED; - SetServiceStatus(statushandle, &status); - exit(1); + case SERVICE_CONTROL_INTERROGATE: + SetServiceStatus(statushandle, &status); + return NO_ERROR; + case SERVICE_CONTROL_STOP: + logger(LOG_NOTICE, "Got %s request", "SERVICE_CONTROL_STOP"); + break; + case SERVICE_CONTROL_SHUTDOWN: + logger(LOG_NOTICE, "Got %s request", "SERVICE_CONTROL_SHUTDOWN"); + break; + default: + logger(LOG_WARNING, "Got unexpected request %d", request); + return ERROR_CALL_NOT_IMPLEMENTED; } + event_loopexit(NULL); + status.dwWaitHint = 30000; + status.dwCurrentState = SERVICE_STOP_PENDING; + SetServiceStatus(statushandle, &status); + return NO_ERROR; } -VOID WINAPI run_service(DWORD argc, LPTSTR *argv) { +VOID WINAPI run_service(DWORD argc, LPTSTR* argv) { + int err = 1; extern int main2(int argc, char **argv); - status.dwServiceType = SERVICE_WIN32; + + status.dwServiceType = SERVICE_WIN32; status.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN; - status.dwWin32ExitCode = 0; - status.dwServiceSpecificExitCode = 0; - status.dwCheckPoint = 0; + status.dwWin32ExitCode = 0; + status.dwServiceSpecificExitCode = 0; + status.dwCheckPoint = 0; - statushandle = RegisterServiceCtrlHandlerEx(identname, controlhandler, NULL); + statushandle = RegisterServiceCtrlHandlerEx(identname, controlhandler, NULL); - if(!statushandle) { + if (!statushandle) { logger(LOG_ERR, "System call `%s' failed: %s", "RegisterServiceCtrlHandlerEx", winerror(GetLastError())); + err = 1; } else { - status.dwWaitHint = 30000; - status.dwCurrentState = SERVICE_START_PENDING; + status.dwWaitHint = 30000; + status.dwCurrentState = SERVICE_START_PENDING; SetServiceStatus(statushandle, &status); - status.dwWaitHint = 0; + status.dwWaitHint = 0; status.dwCurrentState = SERVICE_RUNNING; SetServiceStatus(statushandle, &status); - main2(argc, argv); + err = main2(argc, argv); status.dwWaitHint = 0; - status.dwCurrentState = SERVICE_STOPPED; + status.dwCurrentState = SERVICE_STOPPED; + //status.dwWin32ExitCode = err; SetServiceStatus(statushandle, &status); } @@ -231,39 +181,9 @@ bool init_service(void) { if(!StartServiceCtrlDispatcher(services)) { if(GetLastError() == ERROR_FAILED_SERVICE_CONTROLLER_CONNECT) { return false; - } else { + } + else logger(LOG_ERR, "System call `%s' failed: %s", "StartServiceCtrlDispatcher", winerror(GetLastError())); - } - } - - return true; -} -#endif - -#ifndef HAVE_MINGW -/* - check for an existing tinc for this net, and write pid to pidfile -*/ -static bool write_pidfile(void) { - pid_t pid; - - pid = check_pid(pidfilename); - - if(pid) { - if(netname) - fprintf(stderr, "A tincd is already running for net `%s' with pid %ld.\n", - netname, (long)pid); - else { - fprintf(stderr, "A tincd is already running with pid %ld.\n", (long)pid); - } - - return false; - } - - /* if it's locked, write-protected, or whatever */ - if(!write_pid(pidfilename)) { - fprintf(stderr, "Couldn't write pid file %s: %s\n", pidfilename, strerror(errno)); - return false; } return true; @@ -271,193 +191,72 @@ static bool write_pidfile(void) { #endif /* - kill older tincd for this net -*/ -bool kill_other(int signal) { -#ifndef HAVE_MINGW - pid_t pid; - - pid = read_pid(pidfilename); - - if(!pid) { - if(netname) - fprintf(stderr, "No other tincd is running for net `%s'.\n", - netname); - else { - fprintf(stderr, "No other tincd is running.\n"); - } - - return false; - } - - errno = 0; /* No error, sometimes errno is only changed on error */ - - /* ESRCH is returned when no process with that pid is found */ - if(kill(pid, signal) && errno == ESRCH) { - if(netname) - fprintf(stderr, "The tincd for net `%s' is no longer running. ", - netname); - else { - fprintf(stderr, "The tincd is no longer running. "); - } - - fprintf(stderr, "Removing stale lock file.\n"); - remove_pid(pidfilename); - } - - return true; -#else - return remove_service(); -#endif -} - -/* - Detach from current terminal, write pidfile, kill parent + Detach from current terminal */ bool detach(void) { - setup_signals(); - - /* First check if we can open a fresh new pidfile */ - #ifndef HAVE_MINGW - - if(!write_pidfile()) { - return false; - } - - /* If we succeeded in doing that, detach */ + signal(SIGPIPE, SIG_IGN); + signal(SIGUSR1, SIG_IGN); + signal(SIGUSR2, SIG_IGN); + signal(SIGWINCH, SIG_IGN); closelogger(); #endif if(do_detach) { #ifndef HAVE_MINGW - if(daemon(0, 0)) { fprintf(stderr, "Couldn't detach from terminal: %s", - strerror(errno)); + strerror(errno)); return false; } - - /* Now UPDATE the pid in the pidfile, because we changed it... */ - - if(!write_pid(pidfilename)) { - fprintf(stderr, "Could not write pid file %s: %s\n", pidfilename, strerror(errno)); - return false; - } - #else - - if(!statushandle) { + if(!statushandle) exit(install_service()); - } - #endif } - openlogger(identname, use_logfile ? LOGMODE_FILE : (do_detach ? LOGMODE_SYSLOG : LOGMODE_STDERR)); + openlogger(identname, use_logfile?LOGMODE_FILE:(do_detach?LOGMODE_SYSLOG:LOGMODE_STDERR)); - logger(LOG_NOTICE, "tincd %s starting, debug level %d", - VERSION, debug_level); + logger(LOG_NOTICE, "tincd %s (%s %s) starting, debug level %d", + VERSION, __DATE__, __TIME__, debug_level); return true; } -#ifdef HAVE_PUTENV -void unputenv(char *p) { - char *e = strchr(p, '='); - - if(!e) { - return; - } - - int len = e - p; -#ifndef HAVE_UNSETENV -#ifdef HAVE_MINGW - // Windows requires putenv("FOO=") to unset %FOO% - len++; -#endif -#endif - char var[len + 1]; - memcpy(var, p, len); - var[len] = 0; -#ifdef HAVE_UNSETENV - unsetenv(var); -#else - // We must keep what we putenv() around in memory. - // To do this without memory leaks, keep things in a list and reuse if possible. - static list_t list = {}; - - for(list_node_t *node = list.head; node; node = node->next) { - char *data = node->data; - - if(!strcmp(data, var)) { - putenv(data); - return; - } - } - - char *data = xstrdup(var); - list_insert_tail(&list, data); - putenv(data); -#endif -} -#else -void putenv(const char *p) {} -void unputenv(const char *p) {} -#endif - bool execute_script(const char *name, char **envp) { #ifdef HAVE_SYSTEM + int status, len; char *scriptname; - char *interpreter = NULL; - config_t *cfg_interpreter; - int status, len, i; + int i; - cfg_interpreter = lookup_config(config_tree, "ScriptsInterpreter"); #ifndef HAVE_MINGW len = xasprintf(&scriptname, "\"%s/%s\"", confbase, name); #else - - if(cfg_interpreter) { - len = xasprintf(&scriptname, "\"%s/%s\"", confbase, name); - } else { - len = xasprintf(&scriptname, "\"%s/%s.bat\"", confbase, name); - } - + len = xasprintf(&scriptname, "\"%s/%s.bat\"", confbase, name); #endif - - if(len < 0) { + if(len < 0) return false; - } scriptname[len - 1] = '\0'; +#ifndef HAVE_TUNEMU /* First check if there is a script */ + if(access(scriptname + 1, F_OK)) { free(scriptname); return true; } - - // Custom scripts interpreter - if(get_config_string(cfg_interpreter, &interpreter)) { - // Force custom scripts interpreter allowing execution of scripts on android without execution flag (such as on /sdcard) - free(scriptname); - len = xasprintf(&scriptname, "%s \"%s/%s\"", interpreter, confbase, name); - free(interpreter); - - if(len < 0) { - return false; - } - } +#endif ifdebug(STATUS) logger(LOG_INFO, "Executing script %s", name); +#ifdef HAVE_PUTENV /* Set environment */ - - for(i = 0; envp[i]; i++) { + + for(i = 0; envp[i]; i++) putenv(envp[i]); - } +#endif scriptname[len - 1] = '\"'; status = system(scriptname); @@ -467,212 +266,36 @@ bool execute_script(const char *name, char **envp) { /* Unset environment */ for(i = 0; envp[i]; i++) { - unputenv(envp[i]); + char *e = strchr(envp[i], '='); + if(e) { + char p[e - envp[i] + 1]; + strncpy(p, envp[i], e - envp[i]); + p[e - envp[i]] = '\0'; + putenv(p); + } } - if(status != -1) { #ifdef WEXITSTATUS - - if(WIFEXITED(status)) { /* Child exited by itself */ + if(status != -1) { + if(WIFEXITED(status)) { /* Child exited by itself */ if(WEXITSTATUS(status)) { logger(LOG_ERR, "Script %s exited with non-zero status %d", - name, WEXITSTATUS(status)); + name, WEXITSTATUS(status)); return false; } - } else if(WIFSIGNALED(status)) { /* Child was killed by a signal */ + } else if(WIFSIGNALED(status)) { /* Child was killed by a signal */ logger(LOG_ERR, "Script %s was killed by signal %d (%s)", - name, WTERMSIG(status), strsignal(WTERMSIG(status))); + name, WTERMSIG(status), strsignal(WTERMSIG(status))); return false; - } else { /* Something strange happened */ + } else { /* Something strange happened */ logger(LOG_ERR, "Script %s terminated abnormally", name); return false; } - -#endif } else { logger(LOG_ERR, "System call `%s' failed: %s", "system", strerror(errno)); return false; } - +#endif #endif return true; } - - -/* - Signal handlers. -*/ - -#ifndef HAVE_MINGW -static RETSIGTYPE sigterm_handler(int a) { - (void)a; - logger(LOG_NOTICE, "Got %s signal", "TERM"); - - if(running) { - running = false; - } else { - exit(1); - } -} - -static RETSIGTYPE sigquit_handler(int a) { - (void)a; - logger(LOG_NOTICE, "Got %s signal", "QUIT"); - - if(running) { - running = false; - } else { - exit(1); - } -} - -static RETSIGTYPE fatal_signal_square(int a) { - logger(LOG_ERR, "Got another fatal signal %d (%s): not restarting.", a, - strsignal(a)); - exit(1); -} - -static RETSIGTYPE fatal_signal_handler(int a) { - struct sigaction act; - logger(LOG_ERR, "Got fatal signal %d (%s)", a, strsignal(a)); - - if(do_detach) { - logger(LOG_NOTICE, "Trying to re-execute in 5 seconds..."); - - act.sa_handler = fatal_signal_square; - act.sa_mask = emptysigset; - act.sa_flags = 0; - sigaction(SIGSEGV, &act, NULL); - - close_network_connections(); - sleep(5); - remove_pid(pidfilename); - execvp(g_argv[0], g_argv); - } else { - logger(LOG_NOTICE, "Not restarting."); - exit(1); - } -} - -static RETSIGTYPE sighup_handler(int a) { - (void)a; - logger(LOG_NOTICE, "Got %s signal", "HUP"); - sighup = true; -} - -static RETSIGTYPE sigint_handler(int a) { - (void)a; - static int saved_debug_level = -1; - - logger(LOG_NOTICE, "Got %s signal", "INT"); - - if(saved_debug_level != -1) { - logger(LOG_NOTICE, "Reverting to old debug level (%d)", - saved_debug_level); - debug_level = saved_debug_level; - saved_debug_level = -1; - } else { - logger(LOG_NOTICE, - "Temporarily setting debug level to 5. Kill me with SIGINT again to go back to level %d.", - debug_level); - saved_debug_level = debug_level; - debug_level = 5; - } -} - -static RETSIGTYPE sigalrm_handler(int a) { - (void)a; - logger(LOG_NOTICE, "Got %s signal", "ALRM"); - sigalrm = true; -} - -static RETSIGTYPE sigusr1_handler(int a) { - (void)a; - dump_connections(); -} - -static RETSIGTYPE sigusr2_handler(int a) { - (void)a; - devops.dump_stats(); - dump_nodes(); - dump_edges(); - dump_subnets(); -} - -static RETSIGTYPE sigwinch_handler(int a) { - (void)a; - do_purge = true; -} - -static RETSIGTYPE unexpected_signal_handler(int a) { - (void)a; - logger(LOG_WARNING, "Got unexpected signal %d (%s)", a, strsignal(a)); -} - -static RETSIGTYPE ignore_signal_handler(int a) { - (void)a; - ifdebug(SCARY_THINGS) logger(LOG_DEBUG, "Ignored signal %d (%s)", a, strsignal(a)); -} - -static struct { - int signal; - void (*handler)(int); -} sighandlers[] = { - {SIGHUP, sighup_handler}, - {SIGTERM, sigterm_handler}, - {SIGQUIT, sigquit_handler}, - {SIGSEGV, fatal_signal_handler}, - {SIGBUS, fatal_signal_handler}, - {SIGILL, fatal_signal_handler}, - {SIGPIPE, ignore_signal_handler}, - {SIGINT, sigint_handler}, - {SIGUSR1, sigusr1_handler}, - {SIGUSR2, sigusr2_handler}, - {SIGCHLD, ignore_signal_handler}, - {SIGALRM, sigalrm_handler}, - {SIGWINCH, sigwinch_handler}, - {SIGABRT, SIG_DFL}, - {0, NULL} -}; -#endif - -void setup_signals(void) { -#ifndef HAVE_MINGW - int i; - struct sigaction act; - - sigemptyset(&emptysigset); - act.sa_handler = NULL; - act.sa_mask = emptysigset; - act.sa_flags = 0; - - /* Set a default signal handler for every signal, errors will be - ignored. */ - for(i = 1; i < NSIG; i++) { - if(!do_detach) { - act.sa_handler = SIG_DFL; - } else { - act.sa_handler = unexpected_signal_handler; - } - - sigaction(i, &act, NULL); - } - - /* If we didn't detach, allow coredumps */ - if(!do_detach) { - sighandlers[3].handler = SIG_DFL; - } - - /* Then, for each known signal that we want to catch, assign a - handler to the signal, with error checking this time. */ - for(i = 0; sighandlers[i].signal; i++) { - act.sa_handler = sighandlers[i].handler; - - if(sigaction(sighandlers[i].signal, &act, NULL) < 0) - fprintf(stderr, "Installing signal handler for signal %d (%s) failed: %s\n", - sighandlers[i].signal, strsignal(sighandlers[i].signal), - strerror(errno)); - } - -#endif -} diff --git a/src/process.h b/src/process.h index e775ac3..ea7815e 100644 --- a/src/process.h +++ b/src/process.h @@ -1,6 +1,3 @@ -#ifndef TINC_PROCESS_H -#define TINC_PROCESS_H - /* process.h -- header file for process.c Copyright (C) 1999-2005 Ivo Timmermans, @@ -21,17 +18,19 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +#ifndef __TINC_PROCESS_H__ +#define __TINC_PROCESS_H__ + extern bool do_detach; -extern bool sighup; extern bool sigalrm; extern void setup_signals(void); -extern bool execute_script(const char *name, char **envp); +extern bool execute_script(const char *, char **); extern bool detach(void); -extern bool kill_other(int signal); +extern bool kill_other(int); #ifdef HAVE_MINGW extern bool init_service(void); #endif -#endif +#endif /* __TINC_PROCESS_H__ */ diff --git a/src/protocol.c b/src/protocol.c index 4f74d3b..63163a0 100644 --- a/src/protocol.c +++ b/src/protocol.c @@ -1,7 +1,7 @@ /* protocol.c -- handle the meta-protocol, basic functions Copyright (C) 1999-2005 Ivo Timmermans, - 2000-2016 Guus Sliepen + 2000-2009 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 @@ -30,35 +30,35 @@ bool tunnelserver = false; bool strictsubnets = false; +bool experimental = false; /* Jumptable for the request handlers */ -static bool (*request_handlers[])(connection_t *) = { - id_h, metakey_h, challenge_h, chal_reply_h, ack_h, - NULL, NULL, NULL, - ping_h, pong_h, - add_subnet_h, del_subnet_h, - add_edge_h, del_edge_h, - key_changed_h, req_key_h, ans_key_h, tcppacket_h, +static bool (*request_handlers[])(connection_t *, char *) = { + id_h, metakey_h, challenge_h, chal_reply_h, ack_h, + status_h, error_h, termreq_h, + ping_h, pong_h, + add_subnet_h, del_subnet_h, + add_edge_h, del_edge_h, + key_changed_h, req_key_h, ans_key_h, tcppacket_h, control_h, }; /* Request names */ static char (*request_name[]) = { - "ID", "METAKEY", "CHALLENGE", "CHAL_REPLY", "ACK", - "STATUS", "ERROR", "TERMREQ", - "PING", "PONG", - "ADD_SUBNET", "DEL_SUBNET", - "ADD_EDGE", "DEL_EDGE", "KEY_CHANGED", "REQ_KEY", "ANS_KEY", "PACKET", + "ID", "METAKEY", "CHALLENGE", "CHAL_REPLY", "ACK", + "STATUS", "ERROR", "TERMREQ", + "PING", "PONG", + "ADD_SUBNET", "DEL_SUBNET", + "ADD_EDGE", "DEL_EDGE", "KEY_CHANGED", "REQ_KEY", "ANS_KEY", "PACKET", "CONTROL", }; -static avl_tree_t *past_request_tree; +static splay_tree_t *past_request_tree; bool check_id(const char *id) { for(; *id; id++) - if(!isalnum(*id) && *id != '_') { + if(!isalnum(*id) && *id != '_') return false; - } return true; } @@ -68,104 +68,97 @@ bool check_id(const char *id) { bool send_request(connection_t *c, const char *format, ...) { va_list args; - char buffer[MAXBUFSIZE]; - int len, request = 0; + char request[MAXBUFSIZE]; + int len; /* Use vsnprintf instead of vxasprintf: faster, no memory fragmentation, cleanup is automatic, and there is a limit on the input buffer anyway */ va_start(args, format); - len = vsnprintf(buffer, sizeof(buffer), format, args); - buffer[sizeof(buffer) - 1] = 0; + len = vsnprintf(request, MAXBUFSIZE, format, args); va_end(args); - if(len < 0 || (size_t)len > sizeof(buffer) - 1) { + if(len < 0 || len > MAXBUFSIZE - 1) { logger(LOG_ERR, "Output buffer overflow while sending request to %s (%s)", - c->name, c->hostname); + c->name, c->hostname); return false; } ifdebug(PROTOCOL) { - sscanf(buffer, "%d", &request); ifdebug(META) - logger(LOG_DEBUG, "Sending %s to %s (%s): %s", - request_name[request], c->name, c->hostname, buffer); + logger(LOG_DEBUG, "Sending %s to %s (%s): %s", + request_name[atoi(request)], c->name, c->hostname, request); else - logger(LOG_DEBUG, "Sending %s to %s (%s)", request_name[request], - c->name, c->hostname); + logger(LOG_DEBUG, "Sending %s to %s (%s)", request_name[atoi(request)], + c->name, c->hostname); } - buffer[len++] = '\n'; + request[len++] = '\n'; - if(c == everyone) { - broadcast_meta(NULL, buffer, len); + if(c == broadcast) { + broadcast_meta(NULL, request, len); return true; - } else { - return send_meta(c, buffer, len); - } + } else + return send_meta(c, request, len); } -void forward_request(connection_t *from) { - int request; - +void forward_request(connection_t *from, char *request) { + /* Note: request is not zero terminated anymore after a call to this function! */ ifdebug(PROTOCOL) { - sscanf(from->buffer, "%d", &request); ifdebug(META) - logger(LOG_DEBUG, "Forwarding %s from %s (%s): %s", - request_name[request], from->name, from->hostname, - from->buffer); + logger(LOG_DEBUG, "Forwarding %s from %s (%s): %s", + request_name[atoi(request)], from->name, from->hostname, request); else logger(LOG_DEBUG, "Forwarding %s from %s (%s)", - request_name[request], from->name, from->hostname); + request_name[atoi(request)], from->name, from->hostname); } - from->buffer[from->reqlen - 1] = '\n'; - - broadcast_meta(from, from->buffer, from->reqlen); + int len = strlen(request); + request[len++] = '\n'; + broadcast_meta(from, request, len); } -bool receive_request(connection_t *c) { - int request; +bool receive_request(connection_t *c, char *request) { + int reqno = atoi(request); - if(sscanf(c->buffer, "%d", &request) == 1) { - if((request < 0) || (request >= LAST) || !request_handlers[request]) { + if(reqno || *request == '0') { + if((reqno < 0) || (reqno >= LAST) || !request_handlers[reqno]) { ifdebug(META) - logger(LOG_DEBUG, "Unknown request from %s (%s): %s", - c->name, c->hostname, c->buffer); + logger(LOG_DEBUG, "Unknown request from %s (%s): %s", + c->name, c->hostname, request); else logger(LOG_ERR, "Unknown request from %s (%s)", - c->name, c->hostname); + c->name, c->hostname); return false; } else { ifdebug(PROTOCOL) { ifdebug(META) - logger(LOG_DEBUG, "Got %s from %s (%s): %s", - request_name[request], c->name, c->hostname, - c->buffer); + logger(LOG_DEBUG, "Got %s from %s (%s): %s", + request_name[reqno], c->name, c->hostname, request); else logger(LOG_DEBUG, "Got %s from %s (%s)", - request_name[request], c->name, c->hostname); + request_name[reqno], c->name, c->hostname); } } - if((c->allow_request != ALL) && (c->allow_request != request)) { + if((c->allow_request != ALL) && (c->allow_request != reqno)) { logger(LOG_ERR, "Unauthorized request from %s (%s)", c->name, - c->hostname); + c->hostname); return false; } - if(!request_handlers[request](c)) { + if(!request_handlers[reqno](c, request)) { /* Something went wrong. Probably scriptkiddies. Terminate. */ logger(LOG_ERR, "Error while processing %s from %s (%s)", - request_name[request], c->name, c->hostname); + request_name[reqno], c->name, c->hostname); return false; } } else { logger(LOG_ERR, "Bogus data received from %s (%s)", - c->name, c->hostname); + c->name, c->hostname); return false; } @@ -177,55 +170,65 @@ static int past_request_compare(const past_request_t *a, const past_request_t *b } static void free_past_request(past_request_t *r) { - if(r->request) { + if(r->request) free(r->request); - } free(r); } -void init_requests(void) { - past_request_tree = avl_alloc_tree((avl_compare_t) past_request_compare, (avl_action_t) free_past_request); -} - -void exit_requests(void) { - avl_delete_tree(past_request_tree); -} +static struct event past_request_event; bool seen_request(char *request) { - past_request_t *new, p = {0}; + past_request_t *new, p = {NULL}; p.request = request; - if(avl_search(past_request_tree, &p)) { + if(splay_search(past_request_tree, &p)) { ifdebug(SCARY_THINGS) logger(LOG_DEBUG, "Already seen request"); return true; } else { - new = xmalloc(sizeof(*new)); + new = xmalloc(sizeof *new); new->request = xstrdup(request); - new->firstseen = now; - avl_insert(past_request_tree, new); + new->firstseen = time(NULL); + splay_insert(past_request_tree, new); + event_add(&past_request_event, &(struct timeval){10, 0}); return false; } } -void age_past_requests(void) { - avl_node_t *node, *next; +static void age_past_requests(int fd, short events, void *data) { + splay_node_t *node, *next; past_request_t *p; int left = 0, deleted = 0; + time_t now = time(NULL); for(node = past_request_tree->head; node; node = next) { next = node->next; p = node->data; - if(p->firstseen + pinginterval <= now) { - avl_delete_node(past_request_tree, node), deleted++; - } else { + if(p->firstseen + pinginterval <= now) + splay_delete_node(past_request_tree, node), deleted++; + else left++; - } } if(left || deleted) ifdebug(SCARY_THINGS) logger(LOG_DEBUG, "Aging past requests: deleted %d, left %d", - deleted, left); + deleted, left); + + if(left) + event_add(&past_request_event, &(struct timeval){10, 0}); +} + +void init_requests(void) { + past_request_tree = splay_alloc_tree((splay_compare_t) past_request_compare, (splay_action_t) free_past_request); + + timeout_set(&past_request_event, age_past_requests, NULL); +} + +void exit_requests(void) { + splay_delete_tree(past_request_tree); + + if(timeout_initialized(&past_request_event)) + event_del(&past_request_event); } diff --git a/src/protocol.h b/src/protocol.h index a055f28..2c97641 100644 --- a/src/protocol.h +++ b/src/protocol.h @@ -1,10 +1,7 @@ -#ifndef TINC_PROTOCOL_H -#define TINC_PROTOCOL_H - /* protocol.h -- header for protocol.c Copyright (C) 1999-2005 Ivo Timmermans, - 2000-2015 Guus Sliepen + 2000-2009 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 @@ -21,11 +18,13 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -/* Protocol version. Different versions are incompatible, - incompatible version have different protocols. - */ +#ifndef __TINC_PROTOCOL_H__ +#define __TINC_PROTOCOL_H__ -#define PROT_CURRENT 17 +/* Protocol version. Different major versions are incompatible. */ + +#define PROT_MAJOR 17 +#define PROT_MINOR 2 /* Silly Windows */ @@ -36,8 +35,7 @@ /* Request numbers */ typedef enum request_t { - PROXY = -2, - ALL = -1, /* Guardian for allow_request */ + ALL = -1, /* Guardian for allow_request */ ID = 0, METAKEY, CHALLENGE, CHAL_REPLY, ACK, STATUS, ERROR, TERMREQ, PING, PONG, @@ -45,7 +43,8 @@ typedef enum request_t { ADD_EDGE, DEL_EDGE, KEY_CHANGED, REQ_KEY, ANS_KEY, PACKET, - LAST /* Guardian for the highest request number */ + CONTROL, + LAST /* Guardian for the highest request number */ } request_t; typedef struct past_request_t { @@ -55,6 +54,7 @@ typedef struct past_request_t { extern bool tunnelserver; extern bool strictsubnets; +extern bool experimental; /* Maximum size of strings in a request. * scanf terminates %2048s with a NUL character, @@ -71,50 +71,57 @@ extern bool strictsubnets; /* Basic functions */ -extern bool send_request(struct connection_t *c, const char *format, ...) __attribute__((__format__(printf, 2, 3))); -extern void forward_request(struct connection_t *c); -extern bool receive_request(struct connection_t *c); -extern bool check_id(const char *name); +extern bool send_request(struct connection_t *, const char *, ...) __attribute__ ((__format__(printf, 2, 3))); +extern void forward_request(struct connection_t *, char *); +extern bool receive_request(struct connection_t *, char *); +extern bool check_id(const char *); extern void init_requests(void); extern void exit_requests(void); -extern bool seen_request(char *request); -extern void age_past_requests(void); +extern bool seen_request(char *); /* Requests */ -extern bool send_id(struct connection_t *c); -extern bool send_metakey(struct connection_t *c); -extern bool send_challenge(struct connection_t *c); -extern bool send_chal_reply(struct connection_t *c); -extern bool send_ack(struct connection_t *c); -extern bool send_ping(struct connection_t *c); -extern bool send_pong(struct connection_t *c); -extern bool send_add_subnet(struct connection_t *c, const struct subnet_t *subnet); -extern bool send_del_subnet(struct connection_t *c, const struct subnet_t *subnet); -extern bool send_add_edge(struct connection_t *c, const struct edge_t *e); -extern bool send_del_edge(struct connection_t *c, const struct edge_t *e); +extern bool send_id(struct connection_t *); +extern bool send_metakey(struct connection_t *); +extern bool send_metakey_ec(struct connection_t *); +extern bool send_challenge(struct connection_t *); +extern bool send_chal_reply(struct connection_t *); +extern bool send_ack(struct connection_t *); +extern bool send_status(struct connection_t *, int, const char *); +extern bool send_error(struct connection_t *, int,const char *); +extern bool send_termreq(struct connection_t *); +extern bool send_ping(struct connection_t *); +extern bool send_pong(struct connection_t *); +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 void send_key_changed(void); -extern bool send_req_key(struct node_t *n); -extern bool send_ans_key(struct node_t *n); -extern bool send_tcppacket(struct connection_t *c, const struct vpn_packet_t *packet); +extern bool send_req_key(struct node_t *); +extern bool send_ans_key(struct node_t *); +extern bool send_tcppacket(struct connection_t *, const struct vpn_packet_t *); /* Request handlers */ -extern bool id_h(struct connection_t *c); -extern bool metakey_h(struct connection_t *c); -extern bool challenge_h(struct connection_t *c); -extern bool chal_reply_h(struct connection_t *c); -extern bool ack_h(struct connection_t *c); -extern bool ping_h(struct connection_t *c); -extern bool pong_h(struct connection_t *c); -extern bool add_subnet_h(struct connection_t *c); -extern bool del_subnet_h(struct connection_t *c); -extern bool add_edge_h(struct connection_t *c); -extern bool del_edge_h(struct connection_t *c); -extern bool key_changed_h(struct connection_t *c); -extern bool req_key_h(struct connection_t *c); -extern bool ans_key_h(struct connection_t *c); -extern bool tcppacket_h(struct connection_t *c); +extern bool id_h(struct connection_t *, char *); +extern bool metakey_h(struct connection_t *, char *); +extern bool challenge_h(struct connection_t *, char *); +extern bool chal_reply_h(struct connection_t *, char *); +extern bool ack_h(struct connection_t *, char *); +extern bool status_h(struct connection_t *, char *); +extern bool error_h(struct connection_t *, char *); +extern bool termreq_h(struct connection_t *, char *); +extern bool ping_h(struct connection_t *, char *); +extern bool pong_h(struct connection_t *, char *); +extern bool add_subnet_h(struct connection_t *, char *); +extern bool del_subnet_h(struct connection_t *, char *); +extern bool add_edge_h(struct connection_t *, char *); +extern bool del_edge_h(struct connection_t *, char *); +extern bool key_changed_h(struct connection_t *, char *); +extern bool req_key_h(struct connection_t *, char *); +extern bool ans_key_h(struct connection_t *, char *); +extern bool tcppacket_h(struct connection_t *, char *); +extern bool control_h(struct connection_t *, char *); -#endif +#endif /* __TINC_PROTOCOL_H__ */ diff --git a/src/protocol_auth.c b/src/protocol_auth.c index 15807c3..4331e94 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-2016 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 @@ -20,49 +20,64 @@ #include "system.h" -#include -#include -#include -#include - -#include "avl_tree.h" +#include "splay_tree.h" #include "conf.h" #include "connection.h" +#include "control.h" +#include "control_common.h" +#include "cipher.h" +#include "crypto.h" +#include "digest.h" #include "edge.h" #include "graph.h" #include "logger.h" -#include "meta.h" #include "net.h" #include "netutl.h" #include "node.h" +#include "prf.h" #include "protocol.h" -#include "proxy.h" +#include "rsa.h" #include "utils.h" #include "xalloc.h" bool send_id(connection_t *c) { - if(proxytype && c->outgoing && !c->status.proxy_passed) { - return send_proxyrequest(c); + gettimeofday(&c->start, NULL); + + int minor = 0; + + if(experimental) { + if(c->config_tree && !read_ecdsa_public_key(c)) + minor = 1; + else + minor = myself->connection->protocol_minor; } - return send_request(c, "%d %s %d", ID, myself->connection->name, - myself->connection->protocol_version); + return send_request(c, "%d %s %d.%d", ID, myself->connection->name, myself->connection->protocol_major, minor); } -bool id_h(connection_t *c) { +bool id_h(connection_t *c, char *request) { char name[MAX_STRING_SIZE]; - if(sscanf(c->buffer, "%*d " MAX_STRING " %d", name, &c->protocol_version) != 2) { + if(sscanf(request, "%*d " MAX_STRING " %d.%d", name, &c->protocol_major, &c->protocol_minor) < 2) { logger(LOG_ERR, "Got bad %s from %s (%s)", "ID", c->name, - c->hostname); + c->hostname); return false; } + /* Check if this is a control connection */ + + if(name[0] == '^' && !strcmp(name + 1, controlcookie)) { + c->status.control = true; + c->allow_request = CONTROL; + c->last_ping_time = time(NULL) + 3600; + return send_request(c, "%d %d %d", ACK, TINC_CTL_VERSION_CURRENT, getpid()); + } + /* Check if identity is a valid name */ - if(!check_id(name) || !strcmp(name, myself->name)) { + if(!check_id(name)) { logger(LOG_ERR, "Got bad %s from %s (%s): %s", "ID", c->name, - c->hostname, "invalid name"); + c->hostname, "invalid name"); return false; } @@ -71,36 +86,27 @@ bool id_h(connection_t *c) { if(c->outgoing) { if(strcmp(c->name, name)) { logger(LOG_ERR, "Peer %s is %s instead of %s", c->hostname, name, - c->name); + c->name); return false; } } else { - if(c->name) { + if(c->name) free(c->name); - } - c->name = xstrdup(name); } /* Check if version matches */ - if(c->protocol_version != myself->connection->protocol_version) { - logger(LOG_ERR, "Peer %s (%s) uses incompatible version %d", - c->name, c->hostname, c->protocol_version); + if(c->protocol_major != myself->connection->protocol_major) { + logger(LOG_ERR, "Peer %s (%s) uses incompatible version %d.%d", + c->name, c->hostname, c->protocol_major, c->protocol_minor); return false; } if(bypass_security) { - if(!c->config_tree) { + if(!c->config_tree) init_configuration(&c->config_tree); - } - c->allow_request = ACK; - - if(!c->outgoing) { - send_id(c); - } - return send_ack(c); } @@ -109,66 +115,67 @@ bool id_h(connection_t *c) { if(!read_connection_config(c)) { logger(LOG_ERR, "Peer %s had unknown identity (%s)", c->hostname, - c->name); + c->name); return false; } + + if(experimental && c->protocol_minor >= 2) + if(!read_ecdsa_public_key(c)) + return false; + } else { + if(!ecdsa_active(&c->ecdsa)) + c->protocol_minor = 1; } - if(!read_rsa_public_key(c)) { - return false; - } + if(!experimental) + c->protocol_minor = 0; c->allow_request = METAKEY; - if(!c->outgoing) { - send_id(c); - } - - return send_metakey(c); + if(c->protocol_minor >= 2) + return send_metakey_ec(c); + else + return send_metakey(c); } -static uint64_t byte_budget(const EVP_CIPHER *cipher) { - /* Hopefully some failsafe way to calculate the maximum amount of bytes to - send/receive with a given cipher before we might run into birthday paradox - attacks. Because we might use different modes, the block size of the mode - might be 1 byte. In that case, use the IV length. Ensure the whole thing - is limited to what can be represented with a 64 bits integer. - */ +bool send_metakey_ec(connection_t *c) { + logger(LOG_DEBUG, "Sending ECDH metakey to %s", c->name); - int ivlen = EVP_CIPHER_iv_length(cipher); - int blklen = EVP_CIPHER_block_size(cipher); - int len = blklen > 1 ? blklen : ivlen > 1 ? ivlen : 8; - int bits = len * 4 - 1; - return bits < 64 ? UINT64_C(1) << bits : UINT64_MAX; + size_t siglen = ecdsa_size(&myself->connection->ecdsa); + + char key[(ECDH_SIZE + siglen) * 2 + 1]; + + // TODO: include nonce? Use relevant parts of SSH or TLS protocol + + if(!ecdh_generate_public(&c->ecdh, key)) + return false; + + if(!ecdsa_sign(&myself->connection->ecdsa, key, ECDH_SIZE, key + ECDH_SIZE)) + return false; + + b64encode(key, key, ECDH_SIZE + siglen); + + return send_request(c, "%d %s", METAKEY, key); } bool send_metakey(connection_t *c) { - bool x; - - int len = RSA_size(c->rsa_key); - - /* Allocate buffers for the meta key */ - - char buffer[2 * len + 1]; - - c->outkey = xrealloc(c->outkey, len); - - if(!c->outctx) { - c->outctx = EVP_CIPHER_CTX_new(); - - if(!c->outctx) { - abort(); - } - } - - /* Copy random data to the buffer */ - - if(1 != RAND_bytes((unsigned char *)c->outkey, len)) { - int err = ERR_get_error(); - logger(LOG_ERR, "Failed to generate meta key (%s)", ERR_error_string(err, NULL)); + if(!read_rsa_public_key(c)) return false; - } + if(!cipher_open_blowfish_ofb(&c->outcipher)) + return false; + + if(!digest_open_sha1(&c->outdigest, -1)) + return false; + + size_t len = rsa_size(&c->rsa); + char key[len]; + char enckey[len]; + char hexkey[2 * len + 1]; + + /* Create a random key */ + + randomize(key, len); /* The message we send must be smaller than the modulus of the RSA key. By definition, for a key of k bits, the following formula holds: @@ -180,13 +187,13 @@ bool send_metakey(connection_t *c) { This can be done by setting the most significant bit to zero. */ - c->outkey[0] &= 0x7F; + key[0] &= 0x7F; + + cipher_set_key_from_rsa(&c->outcipher, key, len, true); ifdebug(SCARY_THINGS) { - bin2hex(c->outkey, buffer, len); - buffer[len * 2] = '\0'; - logger(LOG_DEBUG, "Generated random meta key (unencrypted): %s", - buffer); + bin2hex(key, hexkey, len); + logger(LOG_DEBUG, "Generated random meta key (unencrypted): %s", hexkey); } /* Encrypt the random data @@ -196,144 +203,152 @@ bool send_metakey(connection_t *c) { with a length equal to that of the modulus of the RSA key. */ - if(RSA_public_encrypt(len, (unsigned char *)c->outkey, (unsigned char *)buffer, c->rsa_key, RSA_NO_PADDING) != len) { - logger(LOG_ERR, "Error during encryption of meta key for %s (%s): %s", - c->name, c->hostname, ERR_error_string(ERR_get_error(), NULL)); + if(!rsa_public_encrypt(&c->rsa, key, len, enckey)) { + logger(LOG_ERR, "Error during encryption of meta key for %s (%s)", c->name, c->hostname); return false; } /* Convert the encrypted random data to a hexadecimal formatted string */ - bin2hex(buffer, buffer, len); - buffer[len * 2] = '\0'; + bin2hex(enckey, hexkey, len); /* Send the meta key */ - x = send_request(c, "%d %d %d %d %d %s", METAKEY, - c->outcipher ? EVP_CIPHER_nid(c->outcipher) : 0, - c->outdigest ? EVP_MD_type(c->outdigest) : 0, c->outmaclength, - c->outcompression, buffer); - - /* Further outgoing requests are encrypted with the key we just generated */ - - if(c->outcipher) { - if(!EVP_EncryptInit(c->outctx, c->outcipher, - (unsigned char *)c->outkey + len - EVP_CIPHER_key_length(c->outcipher), - (unsigned char *)c->outkey + len - EVP_CIPHER_key_length(c->outcipher) - - EVP_CIPHER_iv_length(c->outcipher))) { - logger(LOG_ERR, "Error during initialisation of cipher for %s (%s): %s", - c->name, c->hostname, ERR_error_string(ERR_get_error(), NULL)); - return false; - } - - c->outbudget = byte_budget(c->outcipher); - c->status.encryptout = true; - } - - return x; + bool result = send_request(c, "%d %d %d %d %d %s", METAKEY, + cipher_get_nid(&c->outcipher), + digest_get_nid(&c->outdigest), c->outmaclength, + c->outcompression, hexkey); + + c->status.encryptout = true; + return result; } -bool metakey_h(connection_t *c) { - char buffer[MAX_STRING_SIZE]; - int cipher, digest, maclength, compression; - int len; +static bool metakey_ec_h(connection_t *c, const char *request) { + size_t siglen = ecdsa_size(&c->ecdsa); + char key[MAX_STRING_SIZE]; + char sig[siglen]; - if(sscanf(c->buffer, "%*d %d %d %d %d " MAX_STRING, &cipher, &digest, &maclength, &compression, buffer) != 5) { - logger(LOG_ERR, "Got bad %s from %s (%s)", "METAKEY", c->name, - c->hostname); + logger(LOG_DEBUG, "Got ECDH metakey from %s", c->name); + + if(sscanf(request, "%*d " MAX_STRING, key) != 1) { + logger(LOG_ERR, "Got bad %s from %s (%s)", "METAKEY", c->name, c->hostname); return false; } - len = RSA_size(myself->connection->rsa_key); + int inlen = b64decode(key, key, sizeof key); - /* Check if the length of the meta key is all right */ - - if(strlen(buffer) != (size_t)len * 2) { + if(inlen != (ECDH_SIZE + siglen)) { logger(LOG_ERR, "Possible intruder %s (%s): %s", c->name, c->hostname, "wrong keylength"); return false; } - /* Allocate buffers for the meta key */ + if(!ecdsa_verify(&c->ecdsa, key, ECDH_SIZE, key + ECDH_SIZE)) { + logger(LOG_ERR, "Possible intruder %s (%s): %s", c->name, c->hostname, "invalid ECDSA signature"); + return false; + } - c->inkey = xrealloc(c->inkey, len); + char shared[ECDH_SHARED_SIZE]; - if(!c->inctx) { - c->inctx = EVP_CIPHER_CTX_new(); + if(!ecdh_compute_shared(&c->ecdh, key, shared)) + return false; - if(!c->inctx) { - abort(); - } + /* Update our crypto end */ + + if(!cipher_open_by_name(&c->incipher, "aes-256-ofb")) + return false; + if(!digest_open_by_name(&c->indigest, "sha512", -1)) + return false; + if(!cipher_open_by_name(&c->outcipher, "aes-256-ofb")) + return false; + if(!digest_open_by_name(&c->outdigest, "sha512", -1)) + return false; + + size_t mykeylen = cipher_keylength(&c->incipher); + size_t hiskeylen = cipher_keylength(&c->outcipher); + + char *mykey; + char *hiskey; + char *seed; + + if(strcmp(myself->name, c->name) < 0) { + mykey = key; + hiskey = key + mykeylen * 2; + xasprintf(&seed, "tinc TCP key expansion %s %s", myself->name, c->name); + } else { + mykey = key + hiskeylen * 2; + hiskey = key; + xasprintf(&seed, "tinc TCP key expansion %s %s", c->name, myself->name); + } + + if(!prf(shared, ECDH_SHARED_SIZE, seed, strlen(seed), key, hiskeylen * 2 + mykeylen * 2)) + return false; + + free(seed); + + cipher_set_key(&c->incipher, mykey, false); + digest_set_key(&c->indigest, mykey + mykeylen, mykeylen); + + cipher_set_key(&c->outcipher, hiskey, true); + digest_set_key(&c->outdigest, hiskey + hiskeylen, hiskeylen); + + c->status.decryptin = true; + c->status.encryptout = true; + c->allow_request = CHALLENGE; + + return send_challenge(c); +} + +bool metakey_h(connection_t *c, char *request) { + if(c->protocol_minor >= 2) + return metakey_ec_h(c, request); + + char hexkey[MAX_STRING_SIZE]; + int cipher, digest, maclength, compression; + size_t len = rsa_size(&myself->connection->rsa); + char enckey[len]; + char key[len]; + + if(sscanf(request, "%*d %d %d %d %d " MAX_STRING, &cipher, &digest, &maclength, &compression, hexkey) != 5) { + logger(LOG_ERR, "Got bad %s from %s (%s)", "METAKEY", c->name, c->hostname); + return false; } /* Convert the challenge from hexadecimal back to binary */ - if(!hex2bin(buffer, buffer, len)) { - logger(LOG_ERR, "Got bad %s from %s(%s): %s", "METAKEY", c->name, c->hostname, "invalid key"); + int inlen = hex2bin(hexkey, enckey, sizeof enckey); + + /* Check if the length of the meta key is all right */ + + if(inlen != len) { + logger(LOG_ERR, "Possible intruder %s (%s): %s", c->name, c->hostname, "wrong keylength"); return false; } /* Decrypt the meta key */ - if(RSA_private_decrypt(len, (unsigned char *)buffer, (unsigned char *)c->inkey, myself->connection->rsa_key, RSA_NO_PADDING) != len) { /* See challenge() */ - logger(LOG_ERR, "Error during decryption of meta key for %s (%s): %s", - c->name, c->hostname, ERR_error_string(ERR_get_error(), NULL)); + if(!rsa_private_decrypt(&myself->connection->rsa, enckey, len, key)) { + logger(LOG_ERR, "Error during decryption of meta key for %s (%s)", c->name, c->hostname); return false; } ifdebug(SCARY_THINGS) { - bin2hex(c->inkey, buffer, len); - buffer[len * 2] = '\0'; - logger(LOG_DEBUG, "Received random meta key (unencrypted): %s", buffer); + bin2hex(key, hexkey, len); + logger(LOG_DEBUG, "Received random meta key (unencrypted): %s", hexkey); } - /* All incoming requests will now be encrypted. */ - /* Check and lookup cipher and digest algorithms */ - if(cipher) { - c->incipher = EVP_get_cipherbynid(cipher); - - if(!c->incipher) { - logger(LOG_ERR, "%s (%s) uses unknown cipher!", c->name, c->hostname); - return false; - } - - if(!EVP_DecryptInit(c->inctx, c->incipher, - (unsigned char *)c->inkey + len - EVP_CIPHER_key_length(c->incipher), - (unsigned char *)c->inkey + len - EVP_CIPHER_key_length(c->incipher) - - EVP_CIPHER_iv_length(c->incipher))) { - logger(LOG_ERR, "Error during initialisation of cipher from %s (%s): %s", - c->name, c->hostname, ERR_error_string(ERR_get_error(), NULL)); - return false; - } - - c->inbudget = byte_budget(c->incipher); - c->status.decryptin = true; - } else { - logger(LOG_ERR, "%s (%s) uses null cipher!", c->name, c->hostname); + if(!cipher_open_by_nid(&c->incipher, cipher) || !cipher_set_key_from_rsa(&c->incipher, key, len, false)) { + logger(LOG_ERR, "Error during initialisation of cipher from %s (%s)", c->name, c->hostname); return false; } - c->inmaclength = maclength; - - if(digest) { - c->indigest = EVP_get_digestbynid(digest); - - if(!c->indigest) { - logger(LOG_ERR, "Node %s (%s) uses unknown digest!", c->name, c->hostname); - return false; - } - - if(c->inmaclength > EVP_MD_size(c->indigest) || c->inmaclength < 0) { - logger(LOG_ERR, "%s (%s) uses bogus MAC length!", c->name, c->hostname); - return false; - } - } else { - logger(LOG_ERR, "%s (%s) uses null digest!", c->name, c->hostname); + if(!digest_open_by_nid(&c->indigest, digest, -1)) { + logger(LOG_ERR, "Error during initialisation of digest from %s (%s)", c->name, c->hostname); return false; } - c->incompression = compression; + c->status.decryptin = true; c->allow_request = CHALLENGE; @@ -341,166 +356,87 @@ bool metakey_h(connection_t *c) { } bool send_challenge(connection_t *c) { - /* CHECKME: what is most reasonable value for len? */ + size_t len = c->protocol_minor >= 2 ? ECDH_SIZE : rsa_size(&c->rsa); + char buffer[len * 2 + 1]; - int len = RSA_size(c->rsa_key); - - /* Allocate buffers for the challenge */ - - char buffer[2 * len + 1]; - - c->hischallenge = xrealloc(c->hischallenge, len); + if(!c->hischallenge) + c->hischallenge = xrealloc(c->hischallenge, len); /* Copy random data to the buffer */ - if(1 != RAND_bytes((unsigned char *)c->hischallenge, len)) { - int err = ERR_get_error(); - logger(LOG_ERR, "Failed to generate challenge (%s)", ERR_error_string(err, NULL)); - return false; // Do not send predictable challenges, let connection attempt fail. - } + randomize(c->hischallenge, len); /* Convert to hex */ bin2hex(c->hischallenge, buffer, len); - buffer[len * 2] = '\0'; /* Send the challenge */ return send_request(c, "%d %s", CHALLENGE, buffer); } -bool challenge_h(connection_t *c) { +bool challenge_h(connection_t *c, char *request) { char buffer[MAX_STRING_SIZE]; - int len; + size_t len = c->protocol_minor >= 2 ? ECDH_SIZE : rsa_size(&myself->connection->rsa); + size_t digestlen = digest_length(&c->indigest); + char digest[digestlen]; - if(sscanf(c->buffer, "%*d " MAX_STRING, buffer) != 1) { - logger(LOG_ERR, "Got bad %s from %s (%s)", "CHALLENGE", c->name, - c->hostname); + if(sscanf(request, "%*d " MAX_STRING, buffer) != 1) { + logger(LOG_ERR, "Got bad %s from %s (%s)", "CHALLENGE", c->name, c->hostname); return false; } - len = RSA_size(myself->connection->rsa_key); - - /* Check if the length of the challenge is all right */ - - if(strlen(buffer) != (size_t)len * 2) { - logger(LOG_ERR, "Possible intruder %s (%s): %s", c->name, - c->hostname, "wrong challenge length"); - return false; - } - - /* Allocate buffers for the challenge */ - - c->mychallenge = xrealloc(c->mychallenge, len); - /* Convert the challenge from hexadecimal back to binary */ - if(!hex2bin(buffer, c->mychallenge, len)) { - logger(LOG_ERR, "Got bad %s from %s(%s): %s", "CHALLENGE", c->name, c->hostname, "invalid challenge"); + int inlen = hex2bin(buffer, buffer, sizeof buffer); + + /* Check if the length of the challenge is all right */ + + if(inlen != len) { + logger(LOG_ERR, "Possible intruder %s (%s): %s", c->name, c->hostname, "wrong challenge length"); return false; } c->allow_request = CHAL_REPLY; - /* Rest is done by send_chal_reply() */ - - if(c->outgoing) { - return send_chal_reply(c); - } else { - return true; - } -} - -bool send_chal_reply(connection_t *c) { - char hash[EVP_MAX_MD_SIZE * 2 + 1]; - EVP_MD_CTX *ctx; - /* Calculate the hash from the challenge we received */ - ctx = EVP_MD_CTX_create(); - - if(!ctx) { - abort(); - } - - if(!EVP_DigestInit(ctx, c->indigest) - || !EVP_DigestUpdate(ctx, c->mychallenge, RSA_size(myself->connection->rsa_key)) - || !EVP_DigestFinal(ctx, (unsigned char *)hash, NULL)) { - EVP_MD_CTX_destroy(ctx); - logger(LOG_ERR, "Error during calculation of response for %s (%s): %s", - c->name, c->hostname, ERR_error_string(ERR_get_error(), NULL)); - return false; - } - - EVP_MD_CTX_destroy(ctx); + digest_create(&c->indigest, buffer, len, digest); /* Convert the hash to a hexadecimal formatted string */ - bin2hex(hash, hash, EVP_MD_size(c->indigest)); - hash[EVP_MD_size(c->indigest) * 2] = '\0'; + bin2hex(digest, buffer, digestlen); /* Send the reply */ - return send_request(c, "%d %s", CHAL_REPLY, hash); + return send_request(c, "%d %s", CHAL_REPLY, buffer); } -bool chal_reply_h(connection_t *c) { +bool chal_reply_h(connection_t *c, char *request) { char hishash[MAX_STRING_SIZE]; - char myhash[EVP_MAX_MD_SIZE]; - EVP_MD_CTX *ctx; - if(sscanf(c->buffer, "%*d " MAX_STRING, hishash) != 1) { + if(sscanf(request, "%*d " MAX_STRING, hishash) != 1) { logger(LOG_ERR, "Got bad %s from %s (%s)", "CHAL_REPLY", c->name, - c->hostname); - return false; - } - - /* Check if the length of the hash is all right */ - - if(strlen(hishash) != (size_t)EVP_MD_size(c->outdigest) * 2) { - logger(LOG_ERR, "Possible intruder %s (%s): %s", c->name, - c->hostname, "wrong challenge reply length"); + c->hostname); return false; } /* Convert the hash to binary format */ - if(!hex2bin(hishash, hishash, EVP_MD_size(c->outdigest))) { - logger(LOG_ERR, "Got bad %s from %s(%s): %s", "CHAL_REPLY", c->name, c->hostname, "invalid hash"); + int inlen = hex2bin(hishash, hishash, sizeof hishash); + + /* Check if the length of the hash is all right */ + + if(inlen != digest_length(&c->outdigest)) { + logger(LOG_ERR, "Possible intruder %s (%s): %s", c->name, c->hostname, "wrong challenge reply length"); return false; } - /* Calculate the hash from the challenge we sent */ - ctx = EVP_MD_CTX_create(); - - if(!ctx) { - abort(); - } - - if(!EVP_DigestInit(ctx, c->outdigest) - || !EVP_DigestUpdate(ctx, c->hischallenge, RSA_size(c->rsa_key)) - || !EVP_DigestFinal(ctx, (unsigned char *)myhash, NULL)) { - EVP_MD_CTX_destroy(ctx); - logger(LOG_ERR, "Error during calculation of response from %s (%s): %s", - c->name, c->hostname, ERR_error_string(ERR_get_error(), NULL)); - return false; - } - - EVP_MD_CTX_destroy(ctx); - - /* Verify the incoming hash with the calculated hash */ - - if(memcmp(hishash, myhash, EVP_MD_size(c->outdigest))) { - logger(LOG_ERR, "Possible intruder %s (%s): %s", c->name, - c->hostname, "wrong challenge reply"); - - ifdebug(SCARY_THINGS) { - bin2hex(myhash, hishash, SHA_DIGEST_LENGTH); - hishash[SHA_DIGEST_LENGTH * 2] = '\0'; - logger(LOG_DEBUG, "Expected challenge reply: %s", hishash); - } + /* Verify the hash */ + if(!digest_verify(&c->outdigest, c->hischallenge, c->protocol_minor >= 2 ? ECDH_SIZE : rsa_size(&c->rsa), hishash)) { + logger(LOG_ERR, "Possible intruder %s (%s): %s", c->name, c->hostname, "wrong challenge reply"); return false; } @@ -508,16 +444,31 @@ bool chal_reply_h(connection_t *c) { Send an acknowledgement with the rest of the information needed. */ + free(c->hischallenge); + c->hischallenge = NULL; c->allow_request = ACK; - if(!c->outgoing) { - send_chal_reply(c); - } - return send_ack(c); } +static bool send_upgrade(connection_t *c) { + /* Special case when protocol_minor is 1: the other end is ECDSA capable, + * but doesn't know our key yet. So send it now. */ + + char *pubkey = ecdsa_get_base64_public_key(&myself->connection->ecdsa); + + if(!pubkey) + return false; + + bool result = send_request(c, "%d %s", ACK, pubkey); + free(pubkey); + return result; +} + bool send_ack(connection_t *c) { + if(c->protocol_minor == 1) + return send_upgrade(c); + /* ACK message contains rest of the information the other end needs to create node_t and edge_t structures. */ @@ -531,24 +482,19 @@ bool send_ack(connection_t *c) { /* Check some options */ - if((get_config_bool(lookup_config(c->config_tree, "IndirectData"), &choice) && choice) || myself->options & OPTION_INDIRECT) { + if((get_config_bool(lookup_config(c->config_tree, "IndirectData"), &choice) && choice) || myself->options & OPTION_INDIRECT) c->options |= OPTION_INDIRECT; - } - if((get_config_bool(lookup_config(c->config_tree, "TCPOnly"), &choice) && choice) || myself->options & OPTION_TCPONLY) { + if((get_config_bool(lookup_config(c->config_tree, "TCPOnly"), &choice) && choice) || myself->options & OPTION_TCPONLY) c->options |= OPTION_TCPONLY | OPTION_INDIRECT; - } - if(myself->options & OPTION_PMTU_DISCOVERY && !(c->options & OPTION_TCPONLY)) { + 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) { + if(choice) c->options |= OPTION_CLAMP_MSS; - } get_config_int(lookup_config(c->config_tree, "Weight"), &c->estimated_weight); @@ -556,7 +502,7 @@ bool send_ack(connection_t *c) { } static void send_everything(connection_t *c) { - avl_node_t *node, *node2; + splay_node_t *node, *node2; node_t *n; subnet_t *s; edge_t *e; @@ -587,16 +533,39 @@ static void send_everything(connection_t *c) { } } -bool ack_h(connection_t *c) { +static bool upgrade_h(connection_t *c, char *request) { + char pubkey[MAX_STRING_SIZE]; + + if(sscanf(request, "%*d " MAX_STRING, pubkey) != 1) { + logger(LOG_ERR, "Got bad %s from %s (%s)", "ACK", c->name, c->hostname); + return false; + } + + if(ecdsa_active(&c->ecdsa) || read_ecdsa_public_key(c)) { + logger(LOG_INFO, "Already have ECDSA public key from %s (%s), not upgrading.", c->name, c->hostname); + return false; + } + + logger(LOG_INFO, "Got ECDSA public key from %s (%s), upgrading!", c->name, c->hostname); + append_config_file(c->name, "ECDSAPublicKey", pubkey); + c->allow_request = TERMREQ; + return send_termreq(c); +} + +bool ack_h(connection_t *c, char *request) { + if(c->protocol_minor == 1) + return upgrade_h(c, request); + char hisport[MAX_STRING_SIZE]; + char *hisaddress; int weight, mtu; uint32_t options; node_t *n; bool choice; - if(sscanf(c->buffer, "%*d " MAX_STRING " %d %x", hisport, &weight, &options) != 3) { + if(sscanf(request, "%*d " MAX_STRING " %d %x", hisport, &weight, &options) != 3) { logger(LOG_ERR, "Got bad %s from %s (%s)", "ACK", c->name, - c->hostname); + c->hostname); return false; } @@ -611,8 +580,17 @@ bool ack_h(connection_t *c) { } else { if(n->connection) { /* Oh dear, we already have a connection to this node. */ - ifdebug(CONNECTIONS) logger(LOG_DEBUG, "Established a second connection with %s (%s), closing old connection", - n->name, n->hostname); + ifdebug(CONNECTIONS) logger(LOG_DEBUG, "Established a second connection with %s (%s), closing old connection", n->connection->name, n->connection->hostname); + + if(n->connection->outgoing) { + if(c->outgoing) + logger(LOG_WARNING, "Two outgoing connections to the same node!"); + else + c->outgoing = n->connection->outgoing; + + n->connection->outgoing = NULL; + } + terminate_connection(n->connection, false); /* Run graph algorithm to purge key and make sure up/down scripts are rerun with new IP addresses and stuff */ graph(); @@ -621,37 +599,35 @@ bool ack_h(connection_t *c) { n->connection = c; c->node = n; - if(!(c->options & options & OPTION_PMTU_DISCOVERY)) { c->options &= ~OPTION_PMTU_DISCOVERY; options &= ~OPTION_PMTU_DISCOVERY; } - c->options |= options; - if(get_config_int(lookup_config(c->config_tree, "PMTU"), &mtu) && mtu < n->mtu) { + if(get_config_int(lookup_config(c->config_tree, "PMTU"), &mtu) && mtu < n->mtu) n->mtu = mtu; - } - if(get_config_int(lookup_config(config_tree, "PMTU"), &mtu) && mtu < n->mtu) { + if(get_config_int(lookup_config(config_tree, "PMTU"), &mtu) && mtu < n->mtu) n->mtu = mtu; - } if(get_config_bool(lookup_config(c->config_tree, "ClampMSS"), &choice)) { - if(choice) { + if(choice) c->options |= OPTION_CLAMP_MSS; - } else { + else c->options &= ~OPTION_CLAMP_MSS; - } } + if(c->protocol_minor > 0) + c->node->status.ecdh = true; + /* Activate this connection */ c->allow_request = ALL; c->status.active = true; ifdebug(CONNECTIONS) logger(LOG_NOTICE, "Connection with %s (%s) activated", c->name, - c->hostname); + c->hostname); /* Send him everything we know */ @@ -662,8 +638,9 @@ bool ack_h(connection_t *c) { c->edge = new_edge(); c->edge->from = myself; c->edge->to = n; - sockaddrcpy(&c->edge->address, &c->address); - sockaddr_setport(&c->edge->address, hisport); + sockaddr2str(&c->address, &hisaddress, NULL); + c->edge->address = str2sockaddr(hisaddress, hisport); + free(hisaddress); c->edge->weight = (weight + c->estimated_weight) / 2; c->edge->connection = c; c->edge->options = c->options; @@ -672,11 +649,10 @@ bool ack_h(connection_t *c) { /* Notify everyone of the new edge */ - if(tunnelserver) { + if(tunnelserver) send_add_edge(c, c->edge); - } else { - send_add_edge(everyone, c->edge); - } + else + send_add_edge(broadcast, c->edge); /* Run MST and SSSP algorithms */ diff --git a/src/protocol_edge.c b/src/protocol_edge.c index a1cf640..1dd68d5 100644 --- a/src/protocol_edge.c +++ b/src/protocol_edge.c @@ -1,7 +1,7 @@ /* protocol_edge.c -- handle the meta-protocol, edges Copyright (C) 1999-2005 Ivo Timmermans, - 2000-2016 Guus Sliepen + 2000-2009 Guus Sliepen 2009 Michael Tokarev This program is free software; you can redistribute it and/or modify @@ -21,7 +21,7 @@ #include "system.h" -#include "avl_tree.h" +#include "splay_tree.h" #include "conf.h" #include "connection.h" #include "edge.h" @@ -42,15 +42,15 @@ bool send_add_edge(connection_t *c, const edge_t *e) { sockaddr2str(&e->address, &address, &port); x = send_request(c, "%d %x %s %s %s %s %x %d", ADD_EDGE, rand(), - e->from->name, e->to->name, address, port, - e->options, e->weight); + e->from->name, e->to->name, address, port, + e->options, e->weight); free(address); free(port); return x; } -bool add_edge_h(connection_t *c) { +bool add_edge_h(connection_t *c, char *request) { edge_t *e; node_t *from, *to; char from_name[MAX_STRING_SIZE]; @@ -61,24 +61,23 @@ bool add_edge_h(connection_t *c) { uint32_t options; int weight; - if(sscanf(c->buffer, "%*d %*x "MAX_STRING" "MAX_STRING" "MAX_STRING" "MAX_STRING" %x %d", - from_name, to_name, to_address, to_port, &options, &weight) != 6) { + if(sscanf(request, "%*d %*x "MAX_STRING" "MAX_STRING" "MAX_STRING" "MAX_STRING" %x %d", + from_name, to_name, to_address, to_port, &options, &weight) != 6) { logger(LOG_ERR, "Got bad %s from %s (%s)", "ADD_EDGE", c->name, - c->hostname); + c->hostname); return false; } /* Check if names are valid */ - if(!check_id(from_name) || !check_id(to_name) || !strcmp(from_name, to_name)) { + if(!check_id(from_name) || !check_id(to_name)) { logger(LOG_ERR, "Got bad %s from %s (%s): %s", "ADD_EDGE", c->name, - c->hostname, "invalid name"); + c->hostname, "invalid name"); return false; } - if(seen_request(c->buffer)) { + if(seen_request(request)) return true; - } /* Lookup nodes */ @@ -86,12 +85,12 @@ bool add_edge_h(connection_t *c) { to = lookup_node(to_name); if(tunnelserver && - from != myself && from != c->node && - to != myself && to != c->node) { + from != myself && from != c->node && + to != myself && to != c->node) { /* ignore indirect edge registrations for tunnelserver */ ifdebug(PROTOCOL) logger(LOG_WARNING, - "Ignoring indirect %s from %s (%s)", - "ADD_EDGE", c->name, c->hostname); + "Ignoring indirect %s from %s (%s)", + "ADD_EDGE", c->name, c->hostname); return true; } @@ -120,33 +119,20 @@ bool add_edge_h(connection_t *c) { if(e->weight != weight || e->options != options || sockaddrcmp(&e->address, &address)) { if(from == myself) { ifdebug(PROTOCOL) logger(LOG_WARNING, "Got %s from %s (%s) for ourself which does not match existing entry", - "ADD_EDGE", c->name, c->hostname); + "ADD_EDGE", c->name, c->hostname); send_add_edge(c, e); return true; } else { ifdebug(PROTOCOL) logger(LOG_WARNING, "Got %s from %s (%s) which does not match existing entry", - "ADD_EDGE", c->name, c->hostname); - e->options = options; - - if(sockaddrcmp(&e->address, &address)) { - sockaddrfree(&e->address); - e->address = address; - } - - if(e->weight != weight) { - avl_node_t *node = avl_unlink(edge_weight_tree, e); - e->weight = weight; - avl_insert_node(edge_weight_tree, node); - } - - goto done; + "ADD_EDGE", c->name, c->hostname); + edge_del(e); + graph(); } - } else { + } else return true; - } } else if(from == myself) { ifdebug(PROTOCOL) logger(LOG_WARNING, "Got %s from %s (%s) for ourself which does not exist", - "ADD_EDGE", c->name, c->hostname); + "ADD_EDGE", c->name, c->hostname); contradicting_add_edge++; e = new_edge(); e->from = from; @@ -164,12 +150,10 @@ bool add_edge_h(connection_t *c) { e->weight = weight; edge_add(e); -done: /* Tell the rest about the new edge */ - if(!tunnelserver) { - forward_request(c); - } + if(!tunnelserver) + forward_request(c, request); /* Run MST before or after we tell the rest? */ @@ -180,32 +164,31 @@ done: bool send_del_edge(connection_t *c, const edge_t *e) { return send_request(c, "%d %x %s %s", DEL_EDGE, rand(), - e->from->name, e->to->name); + e->from->name, e->to->name); } -bool del_edge_h(connection_t *c) { +bool del_edge_h(connection_t *c, char *request) { edge_t *e; char from_name[MAX_STRING_SIZE]; char to_name[MAX_STRING_SIZE]; node_t *from, *to; - if(sscanf(c->buffer, "%*d %*x "MAX_STRING" "MAX_STRING, from_name, to_name) != 2) { + if(sscanf(request, "%*d %*x "MAX_STRING" "MAX_STRING, from_name, to_name) != 2) { logger(LOG_ERR, "Got bad %s from %s (%s)", "DEL_EDGE", c->name, - c->hostname); + c->hostname); return false; } /* Check if names are valid */ - if(!check_id(from_name) || !check_id(to_name) || !strcmp(from_name, to_name)) { + if(!check_id(from_name) || !check_id(to_name)) { logger(LOG_ERR, "Got bad %s from %s (%s): %s", "DEL_EDGE", c->name, - c->hostname, "invalid name"); + c->hostname, "invalid name"); return false; } - if(seen_request(c->buffer)) { + if(seen_request(request)) return true; - } /* Lookup nodes */ @@ -213,24 +196,24 @@ bool del_edge_h(connection_t *c) { to = lookup_node(to_name); if(tunnelserver && - from != myself && from != c->node && - to != myself && to != c->node) { + from != myself && from != c->node && + to != myself && to != c->node) { /* ignore indirect edge registrations for tunnelserver */ ifdebug(PROTOCOL) logger(LOG_WARNING, - "Ignoring indirect %s from %s (%s)", - "DEL_EDGE", c->name, c->hostname); + "Ignoring indirect %s from %s (%s)", + "DEL_EDGE", c->name, c->hostname); return true; } if(!from) { ifdebug(PROTOCOL) logger(LOG_ERR, "Got %s from %s (%s) which does not appear in the edge tree", - "DEL_EDGE", c->name, c->hostname); + "DEL_EDGE", c->name, c->hostname); return true; } if(!to) { ifdebug(PROTOCOL) logger(LOG_ERR, "Got %s from %s (%s) which does not appear in the edge tree", - "DEL_EDGE", c->name, c->hostname); + "DEL_EDGE", c->name, c->hostname); return true; } @@ -240,23 +223,22 @@ bool del_edge_h(connection_t *c) { if(!e) { ifdebug(PROTOCOL) logger(LOG_WARNING, "Got %s from %s (%s) which does not appear in the edge tree", - "DEL_EDGE", c->name, c->hostname); + "DEL_EDGE", c->name, c->hostname); return true; } if(e->from == myself) { ifdebug(PROTOCOL) logger(LOG_WARNING, "Got %s from %s (%s) for ourself", - "DEL_EDGE", c->name, c->hostname); + "DEL_EDGE", c->name, c->hostname); contradicting_del_edge++; - send_add_edge(c, e); /* Send back a correction */ + send_add_edge(c, e); /* Send back a correction */ return true; } /* Tell the rest about the deleted edge */ - if(!tunnelserver) { - forward_request(c); - } + if(!tunnelserver) + forward_request(c, request); /* Delete the edge */ @@ -270,12 +252,9 @@ bool del_edge_h(connection_t *c) { if(!to->status.reachable) { e = lookup_edge(to, myself); - if(e) { - if(!tunnelserver) { - send_del_edge(everyone, e); - } - + if(!tunnelserver) + send_del_edge(broadcast, e); edge_del(e); } } diff --git a/src/protocol_key.c b/src/protocol_key.c index 6140a53..5246e7d 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-2016 Guus Sliepen + 2000-2011 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 @@ -20,16 +20,16 @@ #include "system.h" -#include -#include -#include - -#include "avl_tree.h" +#include "splay_tree.h" +#include "cipher.h" #include "connection.h" +#include "crypto.h" +#include "ecdh.h" #include "logger.h" #include "net.h" #include "netutl.h" #include "node.h" +#include "prf.h" #include "protocol.h" #include "utils.h" #include "xalloc.h" @@ -37,46 +37,38 @@ static bool mykeyused = false; void send_key_changed(void) { - avl_node_t *node; + splay_node_t *node; connection_t *c; - send_request(everyone, "%d %x %s", KEY_CHANGED, rand(), myself->name); + 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) { + if(c->status.active && c->node && c->node->status.reachable) send_ans_key(c->node); - } } } -bool key_changed_h(connection_t *c) { +bool key_changed_h(connection_t *c, char *request) { char name[MAX_STRING_SIZE]; node_t *n; - if(sscanf(c->buffer, "%*d %*x " MAX_STRING, name) != 1) { + if(sscanf(request, "%*d %*x " MAX_STRING, name) != 1) { logger(LOG_ERR, "Got bad %s from %s (%s)", "KEY_CHANGED", - c->name, c->hostname); + c->name, c->hostname); 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)) { + if(seen_request(request)) return true; - } n = lookup_node(name); if(!n) { logger(LOG_ERR, "Got %s from %s (%s) origin %s which does not exist", - "KEY_CHANGED", c->name, c->hostname, name); + "KEY_CHANGED", c->name, c->hostname, name); return true; } @@ -85,25 +77,25 @@ bool key_changed_h(connection_t *c) { /* Tell the others */ - if(!tunnelserver) { - forward_request(c); - } + if(!tunnelserver) + forward_request(c, request); return true; } bool send_req_key(node_t *to) { - return send_request(to->nexthop->connection, "%d %s %s", REQ_KEY, myself->name, to->name); + return send_request(to->nexthop->connection, "%d %s %s %d", REQ_KEY, myself->name, to->name, experimental ? 1 : 0); } -bool req_key_h(connection_t *c) { +bool req_key_h(connection_t *c, char *request) { char from_name[MAX_STRING_SIZE]; char to_name[MAX_STRING_SIZE]; node_t *from, *to; + int kx_version = 0; - if(sscanf(c->buffer, "%*d " MAX_STRING " " MAX_STRING, from_name, to_name) != 2) { + if(sscanf(request, "%*d " MAX_STRING " " MAX_STRING " %d", from_name, to_name, &kx_version) < 2) { logger(LOG_ERR, "Got bad %s from %s (%s)", "REQ_KEY", c->name, - c->hostname); + c->hostname); return false; } @@ -116,7 +108,7 @@ bool req_key_h(connection_t *c) { 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); + "REQ_KEY", c->name, c->hostname, from_name); return true; } @@ -124,89 +116,106 @@ 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); + "REQ_KEY", c->name, c->hostname, to_name); return true; } /* Check if this key request is for us */ - if(to == myself) { /* Yes, send our own key back */ - if(!send_ans_key(from)) { - return false; + if(to == myself) { /* Yes, send our own key back */ + if(experimental && kx_version >= 1) { + logger(LOG_DEBUG, "Got ECDH key request from %s", from->name); + from->status.ecdh = true; } + send_ans_key(from); } else { - if(tunnelserver) { + if(tunnelserver) return true; - } if(!to->status.reachable) { logger(LOG_WARNING, "Got %s from %s (%s) destination %s which is not reachable", - "REQ_KEY", c->name, c->hostname, to_name); + "REQ_KEY", c->name, c->hostname, to_name); return true; } - send_request(to->nexthop->connection, "%s", c->buffer); + send_request(to->nexthop->connection, "%s", request); } return true; } +bool send_ans_key_ecdh(node_t *to) { + int siglen = ecdsa_size(&myself->connection->ecdsa); + char key[(ECDH_SIZE + siglen) * 2 + 1]; + + if(!ecdh_generate_public(&to->ecdh, key)) + return false; + + if(!ecdsa_sign(&myself->connection->ecdsa, key, ECDH_SIZE, key + ECDH_SIZE)) + return false; + + b64encode(key, key, ECDH_SIZE + siglen); + + char *pubkey = ecdsa_get_base64_public_key(&myself->connection->ecdsa); + + if(!pubkey) + return false; + + int result = send_request(to->nexthop->connection, "%d %s %s ECDH:%s:%s %d %d %zu %d", ANS_KEY, + myself->name, to->name, key, pubkey, + cipher_get_nid(&myself->incipher), + digest_get_nid(&myself->indigest), + digest_length(&myself->indigest), + myself->incompression); + + free(pubkey); + return result; +} + bool send_ans_key(node_t *to) { - // Set key parameters - to->incipher = myself->incipher; - to->inkeylength = myself->inkeylength; - to->indigest = myself->indigest; - to->inmaclength = myself->inmaclength; + if(experimental && to->status.ecdh) + return send_ans_key_ecdh(to); + + size_t keylen = cipher_keylength(&myself->incipher); + char key[keylen * 2 + 1]; + + cipher_open_by_nid(&to->incipher, cipher_get_nid(&myself->incipher)); + digest_open_by_nid(&to->indigest, digest_get_nid(&myself->indigest), digest_length(&myself->indigest)); to->incompression = myself->incompression; - // Allocate memory for key - to->inkey = xrealloc(to->inkey, to->inkeylength); + randomize(key, keylen); + cipher_set_key(&to->incipher, key, false); + digest_set_key(&to->indigest, key, keylen); - // Create a new key - if(1 != RAND_bytes((unsigned char *)to->inkey, to->inkeylength)) { - int err = ERR_get_error(); - logger(LOG_ERR, "Failed to generate random for key (%s)", ERR_error_string(err, NULL)); - return false; // Do not send insecure keys, let connection attempt fail. - } - - if(to->incipher) { - EVP_DecryptInit_ex(to->inctx, to->incipher, NULL, (unsigned char *)to->inkey, (unsigned char *)to->inkey + EVP_CIPHER_key_length(to->incipher)); - } + bin2hex(key, key, keylen); // Reset sequence number and late packet window mykeyused = true; to->received_seqno = 0; + if(replaywin) memset(to->late, 0, replaywin); - if(replaywin) { - memset(to->late, 0, replaywin); - } - - // Convert to hexadecimal and send - char key[2 * to->inkeylength + 1]; - bin2hex(to->inkey, key, to->inkeylength); - key[to->inkeylength * 2] = '\0'; - - return send_request(to->nexthop->connection, "%d %s %s %s %d %d %d %d", ANS_KEY, - myself->name, to->name, key, - to->incipher ? EVP_CIPHER_nid(to->incipher) : 0, - to->indigest ? EVP_MD_type(to->indigest) : 0, to->inmaclength, - to->incompression); + return send_request(to->nexthop->connection, "%d %s %s %s %d %d %zu %d", ANS_KEY, + myself->name, to->name, key, + cipher_get_nid(&to->incipher), + digest_get_nid(&to->indigest), + digest_length(&to->indigest), + to->incompression); } -bool ans_key_h(connection_t *c) { +bool ans_key_h(connection_t *c, char *request) { 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; + char address[MAX_STRING_SIZE] = ""; + char port[MAX_STRING_SIZE] = ""; + int cipher, digest, maclength, compression, keylen; node_t *from, *to; - 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, address, port) < 7) { + if(sscanf(request, "%*d "MAX_STRING" "MAX_STRING" "MAX_STRING" %d %d %d %d "MAX_STRING" "MAX_STRING, + from_name, to_name, key, &cipher, &digest, &maclength, + &compression, address, port) < 7) { logger(LOG_ERR, "Got bad %s from %s (%s)", "ANS_KEY", c->name, - c->hostname); + c->hostname); return false; } @@ -219,7 +228,7 @@ bool ans_key_h(connection_t *c) { 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); + "ANS_KEY", c->name, c->hostname, from_name); return true; } @@ -227,91 +236,50 @@ 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); + "ANS_KEY", c->name, c->hostname, to_name); return true; } /* Forward it if necessary */ if(to != myself) { - if(tunnelserver) { + if(tunnelserver) return true; - } if(!to->status.reachable) { logger(LOG_WARNING, "Got %s from %s (%s) destination %s which is not reachable", - "ANS_KEY", c->name, c->hostname, to_name); + "ANS_KEY", c->name, c->hostname, to_name); return true; } - if(!*address && from->address.sa.sa_family != AF_UNSPEC && to->minmtu) { + if(!*address && from->address.sa.sa_family != AF_UNSPEC) { 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); + send_request(to->nexthop->connection, "%s %s %s", request, address, port); free(address); free(port); return true; } - return send_request(to->nexthop->connection, "%s", c->buffer); - } - - /* Don't use key material until every check has passed. */ - from->status.validkey = false; - - /* Update our copy of the origin's packet key */ - from->outkey = xrealloc(from->outkey, strlen(key) / 2); - from->outkeylength = strlen(key) / 2; - - if(!hex2bin(key, from->outkey, from->outkeylength)) { - logger(LOG_ERR, "Got bad %s from %s(%s): %s", "ANS_KEY", from->name, from->hostname, "invalid key"); - return true; + return send_request(to->nexthop->connection, "%s", request); } /* Check and lookup cipher and digest algorithms */ - if(cipher) { - from->outcipher = EVP_get_cipherbynid(cipher); - - if(!from->outcipher) { - logger(LOG_ERR, "Node %s (%s) uses unknown cipher!", from->name, - from->hostname); - return true; - } - - if(from->outkeylength != EVP_CIPHER_key_length(from->outcipher) + EVP_CIPHER_iv_length(from->outcipher)) { - logger(LOG_ERR, "Node %s (%s) uses wrong keylength!", from->name, - from->hostname); - return true; - } - } else { - if(from->outkeylength != 1) { - logger(LOG_ERR, "Node %s (%s) uses wrong keylength!", from->name, from->hostname); - return true; - } - - from->outcipher = NULL; + if(!cipher_open_by_nid(&from->outcipher, cipher)) { + logger(LOG_ERR, "Node %s (%s) uses unknown cipher!", from->name, from->hostname); + return false; } - from->outmaclength = maclength; + if(!digest_open_by_nid(&from->outdigest, digest, maclength)) { + logger(LOG_ERR, "Node %s (%s) uses unknown digest!", from->name, from->hostname); + return false; + } - if(digest) { - from->outdigest = EVP_get_digestbynid(digest); - - if(!from->outdigest) { - logger(LOG_ERR, "Node %s (%s) uses unknown digest!", from->name, - from->hostname); - return true; - } - - if(from->outmaclength > EVP_MD_size(from->outdigest) || from->outmaclength < 0) { - logger(LOG_ERR, "Node %s (%s) uses bogus MAC length!", - from->name, from->hostname); - return true; - } - } else { - from->outdigest = NULL; + if(maclength != digest_length(&from->outdigest)) { + logger(LOG_ERR, "Node %s (%s) uses bogus MAC length!", from->name, from->hostname); + return false; } if(compression < 0 || compression > 11) { @@ -321,13 +289,113 @@ bool ans_key_h(connection_t *c) { from->outcompression = compression; - if(from->outcipher) - if(!EVP_EncryptInit_ex(from->outctx, from->outcipher, NULL, (unsigned char *)from->outkey, (unsigned char *)from->outkey + EVP_CIPHER_key_length(from->outcipher))) { - logger(LOG_ERR, "Error during initialisation of key from %s (%s): %s", - from->name, from->hostname, ERR_error_string(ERR_get_error(), NULL)); + /* ECDH or old-style key exchange? */ + + if(experimental && !strncmp(key, "ECDH:", 5)) { + char *pubkey = strchr(key + 5, ':'); + if(pubkey) + *pubkey++ = 0; + + /* Check if we already have an ECDSA public key for this node. + * If not, use the one from the key exchange, and store it. */ + + if(!node_read_ecdsa_public_key(from)) { + if(!pubkey) { + logger(LOG_ERR, "No ECDSA public key known for %s (%s), cannot verify ECDH key exchange!", from->name, from->hostname); + return true; + } + + if(!ecdsa_set_base64_public_key(&from->ecdsa, pubkey)) + return true; + + append_config_file(from->name, "ECDSAPublicKey", pubkey); + } + + int siglen = ecdsa_size(&from->ecdsa); + int keylen = b64decode(key + 5, key + 5, sizeof key - 5); + + if(keylen != ECDH_SIZE + siglen) { + logger(LOG_ERR, "Node %s (%s) uses wrong keylength! %d != %d", from->name, from->hostname, keylen, ECDH_SIZE + siglen); return true; } + if(ECDH_SHARED_SIZE < cipher_keylength(&from->outcipher)) { + logger(LOG_ERR, "ECDH key too short for cipher of %s!", from->name); + return true; + } + + if(!ecdsa_verify(&from->ecdsa, key + 5, ECDH_SIZE, key + 5 + ECDH_SIZE)) { + logger(LOG_ERR, "Possible intruder %s (%s): %s", from->name, from->hostname, "invalid ECDSA signature"); + return true; + } + + if(!from->ecdh) { + from->status.ecdh = true; + if(!send_ans_key(from)) + return true; + } + + char shared[ECDH_SHARED_SIZE * 2 + 1]; + + if(!ecdh_compute_shared(&from->ecdh, key + 5, shared)) + return true; + + /* Update our crypto end */ + + size_t mykeylen = cipher_keylength(&myself->incipher); + size_t hiskeylen = cipher_keylength(&from->outcipher); + + char *mykey; + char *hiskey; + char *seed; + + if(strcmp(myself->name, from->name) < 0) { + mykey = key; + hiskey = key + mykeylen * 2; + xasprintf(&seed, "tinc UDP key expansion %s %s", myself->name, from->name); + } else { + mykey = key + hiskeylen * 2; + hiskey = key; + xasprintf(&seed, "tinc UDP key expansion %s %s", from->name, myself->name); + } + + if(!prf(shared, ECDH_SHARED_SIZE, seed, strlen(seed), key, hiskeylen * 2 + mykeylen * 2)) + return true; + + free(seed); + + cipher_open_by_nid(&from->incipher, cipher_get_nid(&myself->incipher)); + digest_open_by_nid(&from->indigest, digest_get_nid(&myself->indigest), digest_length(&myself->indigest)); + from->incompression = myself->incompression; + + cipher_set_key(&from->incipher, mykey, false); + digest_set_key(&from->indigest, mykey + mykeylen, mykeylen); + + cipher_set_key(&from->outcipher, hiskey, true); + digest_set_key(&from->outdigest, hiskey + hiskeylen, hiskeylen); + + // Reset sequence number and late packet window + mykeyused = true; + from->received_seqno = 0; + if(replaywin) + memset(from->late, 0, replaywin); + + if(strcmp(myself->name, from->name) < 0) + memmove(key, key + mykeylen * 2, hiskeylen * 2); + } else { + keylen = hex2bin(key, key, sizeof key); + + if(keylen != cipher_keylength(&from->outcipher)) { + logger(LOG_ERR, "Node %s (%s) uses wrong keylength!", from->name, from->hostname); + return true; + } + + /* Update our copy of the origin's packet key */ + + cipher_set_key(&from->outcipher, key, true); + digest_set_key(&from->outdigest, key, keylen); + } + from->status.validkey = true; from->sent_seqno = 0; @@ -337,9 +405,8 @@ bool ans_key_h(connection_t *c) { update_node_udp(from, &sa); } - if(from->options & OPTION_PMTU_DISCOVERY && !from->mtuevent) { + if(from->options & OPTION_PMTU_DISCOVERY) send_mtu_probe(from); - } return true; } diff --git a/src/protocol_misc.c b/src/protocol_misc.c index 904ac3f..225d7b4 100644 --- a/src/protocol_misc.c +++ b/src/protocol_misc.c @@ -1,7 +1,7 @@ /* protocol_misc.c -- handle the meta-protocol, miscellaneous functions Copyright (C) 1999-2005 Ivo Timmermans, - 2000-2012 Guus Sliepen + 2000-2009 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 @@ -31,14 +31,70 @@ int maxoutbufsize = 0; +/* Status and error notification routines */ + +bool send_status(connection_t *c, int statusno, const char *statusstring) { + if(!statusstring) + statusstring = "Status"; + + return send_request(c, "%d %d %s", STATUS, statusno, statusstring); +} + +bool status_h(connection_t *c, char *request) { + int statusno; + char statusstring[MAX_STRING_SIZE]; + + if(sscanf(request, "%*d %d " MAX_STRING, &statusno, statusstring) != 2) { + logger(LOG_ERR, "Got bad %s from %s (%s)", "STATUS", + c->name, c->hostname); + return false; + } + + ifdebug(STATUS) logger(LOG_NOTICE, "Status message from %s (%s): %d: %s", + c->name, c->hostname, statusno, statusstring); + + return true; +} + +bool send_error(connection_t *c, int err, const char *errstring) { + if(!errstring) + errstring = "Error"; + + return send_request(c, "%d %d %s", ERROR, err, errstring); +} + +bool error_h(connection_t *c, char *request) { + int err; + char errorstring[MAX_STRING_SIZE]; + + if(sscanf(request, "%*d %d " MAX_STRING, &err, errorstring) != 2) { + logger(LOG_ERR, "Got bad %s from %s (%s)", "ERROR", + c->name, c->hostname); + return false; + } + + ifdebug(ERROR) logger(LOG_NOTICE, "Error message from %s (%s): %d: %s", + c->name, c->hostname, err, errorstring); + + return false; +} + +bool send_termreq(connection_t *c) { + return send_request(c, "%d", TERMREQ); +} + +bool termreq_h(connection_t *c, char *request) { + return false; +} + bool send_ping(connection_t *c) { c->status.pinged = true; - c->last_ping_time = now; + c->last_ping_time = time(NULL); return send_request(c, "%d", PING); } -bool ping_h(connection_t *c) { +bool ping_h(connection_t *c, char *request) { return send_pong(c); } @@ -46,22 +102,13 @@ bool send_pong(connection_t *c) { return send_request(c, "%d", PONG); } -bool pong_h(connection_t *c) { +bool pong_h(connection_t *c, char *request) { c->status.pinged = false; - /* Successful connection, reset timeout if this is an outgoing connection. */ + /* Succesful connection, reset timeout if this is an outgoing connection. */ - if(c->outgoing) { + if(c->outgoing) c->outgoing->timeout = 0; - c->outgoing->cfg = NULL; - - if(c->outgoing->ai) { - freeaddrinfo(c->outgoing->ai); - } - - c->outgoing->ai = NULL; - c->outgoing->aip = NULL; - } return true; } @@ -70,25 +117,23 @@ bool pong_h(connection_t *c) { bool send_tcppacket(connection_t *c, const vpn_packet_t *packet) { /* If there already is a lot of data in the outbuf buffer, discard this packet. - We use a very simple Random Early Drop algorithm. */ + We use a very simple Random Early Drop algorithm. */ - if(2.0 * c->outbuflen / (float)maxoutbufsize - 1 > (float)rand() / (float)RAND_MAX) { + if(2.0 * c->outbuf.len / (float)maxoutbufsize - 1 > (float)rand()/(float)RAND_MAX) return true; - } - if(!send_request(c, "%d %hd", PACKET, packet->len)) { + if(!send_request(c, "%d %hd", PACKET, packet->len)) return false; - } - return send_meta(c, (char *)packet->data, packet->len) && flush_meta(c); + return send_meta(c, (char *)packet->data, packet->len); } -bool tcppacket_h(connection_t *c) { - length_t len; +bool tcppacket_h(connection_t *c, char *request) { + short int len; - if(sscanf(c->buffer, "%*d %hu", &len) != 1) { + if(sscanf(request, "%*d %hd", &len) != 1) { logger(LOG_ERR, "Got bad %s from %s (%s)", "PACKET", c->name, - c->hostname); + c->hostname); return false; } diff --git a/src/protocol_subnet.c b/src/protocol_subnet.c index 2c4d08f..6f9e626 100644 --- a/src/protocol_subnet.c +++ b/src/protocol_subnet.c @@ -35,22 +35,21 @@ bool send_add_subnet(connection_t *c, const subnet_t *subnet) { char netstr[MAXNETSTR]; - if(!net2str(netstr, sizeof(netstr), subnet)) { + if(!net2str(netstr, sizeof netstr, subnet)) return false; - } return send_request(c, "%d %x %s %s", ADD_SUBNET, rand(), subnet->owner->name, netstr); } -bool add_subnet_h(connection_t *c) { +bool add_subnet_h(connection_t *c, char *request) { char subnetstr[MAX_STRING_SIZE]; char name[MAX_STRING_SIZE]; node_t *owner; - subnet_t s = {0}, *new, *old; + subnet_t s = {NULL}, *new, *old; - if(sscanf(c->buffer, "%*d %*x " MAX_STRING " " MAX_STRING, name, subnetstr) != 2) { + if(sscanf(request, "%*d %*x " MAX_STRING " " MAX_STRING, name, subnetstr) != 2) { logger(LOG_ERR, "Got bad %s from %s (%s)", "ADD_SUBNET", c->name, - c->hostname); + c->hostname); return false; } @@ -58,7 +57,7 @@ bool add_subnet_h(connection_t *c) { if(!check_id(name)) { logger(LOG_ERR, "Got bad %s from %s (%s): %s", "ADD_SUBNET", c->name, - c->hostname, "invalid name"); + c->hostname, "invalid name"); return false; } @@ -66,13 +65,12 @@ bool add_subnet_h(connection_t *c) { if(!str2net(&s, subnetstr)) { logger(LOG_ERR, "Got bad %s from %s (%s): %s", "ADD_SUBNET", c->name, - c->hostname, "invalid subnet string"); + c->hostname, "invalid subnet string"); return false; } - if(seen_request(c->buffer)) { + if(seen_request(request)) return true; - } /* Check if the owner of the new subnet is in the connection list */ @@ -81,7 +79,7 @@ bool add_subnet_h(connection_t *c) { if(tunnelserver && owner != myself && owner != c->node) { /* in case of tunnelserver, ignore indirect subnet registrations */ ifdebug(PROTOCOL) logger(LOG_WARNING, "Ignoring indirect %s from %s (%s) for %s", - "ADD_SUBNET", c->name, c->hostname, subnetstr); + "ADD_SUBNET", c->name, c->hostname, subnetstr); return true; } @@ -93,15 +91,14 @@ bool add_subnet_h(connection_t *c) { /* Check if we already know this subnet */ - if(lookup_subnet(owner, &s)) { + if(lookup_subnet(owner, &s)) return true; - } /* If we don't know this subnet, but we are the owner, retaliate with a DEL_SUBNET */ if(owner == myself) { ifdebug(PROTOCOL) logger(LOG_WARNING, "Got %s from %s (%s) for ourself", - "ADD_SUBNET", c->name, c->hostname); + "ADD_SUBNET", c->name, c->hostname); s.owner = myself; send_del_subnet(c, &s); return true; @@ -111,7 +108,7 @@ bool add_subnet_h(connection_t *c) { if(tunnelserver) { logger(LOG_WARNING, "Ignoring unauthorized %s from %s (%s): %s", - "ADD_SUBNET", c->name, c->hostname, subnetstr); + "ADD_SUBNET", c->name, c->hostname, subnetstr); return true; } @@ -119,8 +116,8 @@ bool add_subnet_h(connection_t *c) { if(strictsubnets) { logger(LOG_WARNING, "Ignoring unauthorized %s from %s (%s): %s", - "ADD_SUBNET", c->name, c->hostname, subnetstr); - forward_request(c); + "ADD_SUBNET", c->name, c->hostname, subnetstr); + forward_request(c, request); return true; } @@ -129,19 +126,18 @@ bool add_subnet_h(connection_t *c) { *(new = new_subnet()) = s; subnet_add(owner, new); - if(owner->status.reachable) { + if(owner->status.reachable) subnet_update(owner, new, true); - } /* Tell the rest */ - forward_request(c); + if(!tunnelserver) + forward_request(c, request); /* Fast handoff of roaming MAC addresses */ - if(s.type == SUBNET_MAC && owner != myself && (old = lookup_subnet(myself, &s)) && old->expires) { - old->expires = now; - } + if(s.type == SUBNET_MAC && owner != myself && (old = lookup_subnet(myself, &s)) && old->expires) + old->expires = 1; return true; } @@ -149,22 +145,21 @@ bool add_subnet_h(connection_t *c) { bool send_del_subnet(connection_t *c, const subnet_t *s) { char netstr[MAXNETSTR]; - if(!net2str(netstr, sizeof(netstr), s)) { + if(!net2str(netstr, sizeof netstr, s)) return false; - } return send_request(c, "%d %x %s %s", DEL_SUBNET, rand(), s->owner->name, netstr); } -bool del_subnet_h(connection_t *c) { +bool del_subnet_h(connection_t *c, char *request) { char subnetstr[MAX_STRING_SIZE]; char name[MAX_STRING_SIZE]; node_t *owner; - subnet_t s = {0}, *find; + subnet_t s = {NULL}, *find; - if(sscanf(c->buffer, "%*d %*x " MAX_STRING " " MAX_STRING, name, subnetstr) != 2) { + if(sscanf(request, "%*d %*x " MAX_STRING " " MAX_STRING, name, subnetstr) != 2) { logger(LOG_ERR, "Got bad %s from %s (%s)", "DEL_SUBNET", c->name, - c->hostname); + c->hostname); return false; } @@ -172,7 +167,7 @@ bool del_subnet_h(connection_t *c) { if(!check_id(name)) { logger(LOG_ERR, "Got bad %s from %s (%s): %s", "DEL_SUBNET", c->name, - c->hostname, "invalid name"); + c->hostname, "invalid name"); return false; } @@ -180,13 +175,12 @@ bool del_subnet_h(connection_t *c) { if(!str2net(&s, subnetstr)) { logger(LOG_ERR, "Got bad %s from %s (%s): %s", "DEL_SUBNET", c->name, - c->hostname, "invalid subnet string"); + c->hostname, "invalid subnet string"); return false; } - if(seen_request(c->buffer)) { + if(seen_request(request)) return true; - } /* Check if the owner of the subnet being deleted is in the connection list */ @@ -195,13 +189,13 @@ bool del_subnet_h(connection_t *c) { if(tunnelserver && owner != myself && owner != c->node) { /* in case of tunnelserver, ignore indirect subnet deletion */ ifdebug(PROTOCOL) logger(LOG_WARNING, "Ignoring indirect %s from %s (%s) for %s", - "DEL_SUBNET", c->name, c->hostname, subnetstr); + "DEL_SUBNET", c->name, c->hostname, subnetstr); return true; } if(!owner) { ifdebug(PROTOCOL) logger(LOG_WARNING, "Got %s from %s (%s) for %s which is not in our node tree", - "DEL_SUBNET", c->name, c->hostname, name); + "DEL_SUBNET", c->name, c->hostname, name); return true; } @@ -213,12 +207,9 @@ 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); - } - + "DEL_SUBNET", c->name, c->hostname, name); + if(strictsubnets) + forward_request(c, request); return true; } @@ -226,28 +217,25 @@ bool del_subnet_h(connection_t *c) { if(owner == myself) { ifdebug(PROTOCOL) logger(LOG_WARNING, "Got %s from %s (%s) for ourself", - "DEL_SUBNET", c->name, c->hostname); + "DEL_SUBNET", c->name, c->hostname); send_add_subnet(c, find); return true; } - if(tunnelserver) { + if(tunnelserver) return true; - } /* Tell the rest */ - forward_request(c); - - if(strictsubnets) { + if(!tunnelserver) + forward_request(c, request); + if(strictsubnets) return true; - } /* Finally, delete it. */ - if(owner->status.reachable) { + if(owner->status.reachable) subnet_update(owner, find, false); - } subnet_del(owner, find); diff --git a/src/proxy.c b/src/proxy.c deleted file mode 100644 index 979626c..0000000 --- a/src/proxy.c +++ /dev/null @@ -1,366 +0,0 @@ -/* - proxy.c -- Proxy handling functions. - Copyright (C) 2015-2017 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 - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include "system.h" - -#include "connection.h" -#include "logger.h" -#include "meta.h" -#include "netutl.h" -#include "protocol.h" -#include "proxy.h" -#include "utils.h" // - -proxytype_t proxytype; -char *proxyhost; -char *proxyport; -char *proxyuser; -char *proxypass; - -static void update_address_ipv4(connection_t *c, void *address, void *port) { - sockaddrfree(&c->address); - memset(&c->address, 0, sizeof(c->address)); - c->address.sa.sa_family = AF_INET; - - if(address) { - memcpy(&c->address.in.sin_addr, address, sizeof(ipv4_t)); - } - - if(port) { - memcpy(&c->address.in.sin_port, port, sizeof(uint16_t)); - } - - // OpenSSH -D returns all zero address, set it to 0.0.0.1 to prevent spamming ourselves. - if(!memcmp(&c->address.in.sin_addr, "\0\0\0\0", 4)) { - memcpy(&c->address.in.sin_addr, "\0\0\0\01", 4); - } -} - -static void update_address_ipv6(connection_t *c, void *address, void *port) { - sockaddrfree(&c->address); - memset(&c->address, 0, sizeof(c->address)); - c->address.sa.sa_family = AF_INET6; - - if(address) { - memcpy(&c->address.in6.sin6_addr, address, sizeof(ipv6_t)); - } - - if(port) { - memcpy(&c->address.in6.sin6_port, port, sizeof(uint16_t)); - } - - // OpenSSH -D returns all zero address, set it to 0100:: to prevent spamming ourselves. - if(!memcmp(&c->address.in6.sin6_addr, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 16)) { - memcpy(&c->address.in6.sin6_addr, "\01\0\0\0\0\0\0\0", 8); - } -} - -bool send_proxyrequest(connection_t *c) { - switch(proxytype) { - case PROXY_SOCKS4: - if(c->address.sa.sa_family != AF_INET) { - logger(LOG_ERR, "Can only connect to numeric IPv4 addresses through a SOCKS 4 proxy!"); - return false; - } - - // fallthrough - case PROXY_SOCKS4A: { - if(c->address.sa.sa_family != AF_INET && c->address.sa.sa_family != AF_UNKNOWN) { - logger(LOG_ERR, "Can only connect to IPv4 addresses or hostnames through a SOCKS 4a proxy!"); - return false; - } - - int len = 9; - - if(proxyuser) { - len += strlen(proxyuser); - } - - if(c->address.sa.sa_family == AF_UNKNOWN) { - len += 1 + strlen(c->address.unknown.address); - } - - char s4req[len]; - s4req[0] = 4; - s4req[1] = 1; - - if(c->address.sa.sa_family == AF_INET) { - memcpy(s4req + 2, &c->address.in.sin_port, 2); - memcpy(s4req + 4, &c->address.in.sin_addr, 4); - } else { - uint16_t port = htons(atoi(c->address.unknown.port)); - memcpy(s4req + 2, &port, 2); - memcpy(s4req + 4, "\0\0\0\1", 4); - strcpy(s4req + (9 + (proxyuser ? strlen(proxyuser) : 0)), c->address.unknown.address); - } - - if(proxyuser) { - strcpy(s4req + 8, proxyuser); - } else { - s4req[8] = 0; - } - - s4req[sizeof(s4req) - 1] = 0; - c->allow_request = PROXY; - return send_meta(c, s4req, sizeof(s4req)); - } - - case PROXY_SOCKS5: { - int len = 3 + 6; - - if(c->address.sa.sa_family == AF_INET) { - len += 4; - } else if(c->address.sa.sa_family == AF_INET6) { - len += 16; - } else if(c->address.sa.sa_family == AF_UNKNOWN) { - len += 1 + strlen(c->address.unknown.address); - } else { - logger(LOG_ERR, "Address family %x not supported for SOCKS 5 proxies!", c->address.sa.sa_family); - return false; - } - - if(proxypass) { - len += 3 + strlen(proxyuser) + strlen(proxypass); - } - - char s5req[len]; - int i = 0; - s5req[i++] = 5; - s5req[i++] = 1; - - if(proxypass) { - s5req[i++] = 2; - s5req[i++] = 1; - s5req[i++] = strlen(proxyuser); - strcpy(s5req + i, proxyuser); - i += strlen(proxyuser); - s5req[i++] = strlen(proxypass); - strcpy(s5req + i, proxypass); - i += strlen(proxypass); - } else { - s5req[i++] = 0; - } - - s5req[i++] = 5; - s5req[i++] = 1; - s5req[i++] = 0; - - if(c->address.sa.sa_family == AF_INET) { - s5req[i++] = 1; - memcpy(s5req + i, &c->address.in.sin_addr, 4); - i += 4; - memcpy(s5req + i, &c->address.in.sin_port, 2); - i += 2; - } else if(c->address.sa.sa_family == AF_INET6) { - s5req[i++] = 4; - memcpy(s5req + i, &c->address.in6.sin6_addr, 16); - i += 16; - memcpy(s5req + i, &c->address.in6.sin6_port, 2); - i += 2; - } else if(c->address.sa.sa_family == AF_UNKNOWN) { - s5req[i++] = 3; - int len = strlen(c->address.unknown.address); - s5req[i++] = len; - memcpy(s5req + i, c->address.unknown.address, len); - i += len; - uint16_t port = htons(atoi(c->address.unknown.port)); - memcpy(s5req + i, &port, 2); - i += 2; - } else { - logger(LOG_ERR, "Unknown address family while trying to connect to SOCKS5 proxy"); - return false; - } - - if(i > len) { - abort(); - } - - c->allow_request = PROXY; - return send_meta(c, s5req, sizeof(s5req)); - } - - case PROXY_HTTP: { - char *host; - char *port; - - sockaddr2str(&c->address, &host, &port); - send_request(c, "CONNECT %s:%s HTTP/1.1\r\n\r", host, port); - free(host); - free(port); - c->allow_request = PROXY; - return true; - } - - case PROXY_EXEC: - abort(); - - default: - logger(LOG_ERR, "Unknown proxy type"); - return false; - } -} - -int receive_proxy_meta(connection_t *c) { - switch(proxytype) { - case PROXY_SOCKS4: - case PROXY_SOCKS4A: - if(c->buflen < 8) { - return 0; - } - - if(c->buffer[0] == 0 && c->buffer[1] == 0x5a) { - if(c->address.sa.sa_family == AF_UNKNOWN) { - update_address_ipv4(c, c->buffer + 4, c->buffer + 2); - } - - ifdebug(CONNECTIONS) logger(LOG_DEBUG, "Proxy request granted"); - c->allow_request = ID; - c->status.proxy_passed = true; - send_id(c); - return 8; - } else { - logger(LOG_ERR, "Proxy request rejected"); - return -1; - } - - case PROXY_SOCKS5: - if(c->buflen < 2) { - return 0; - } - - if(c->buffer[0] != 0x05 || c->buffer[1] == (char)0xff) { - logger(LOG_ERR, "Proxy authentication method rejected"); - return -1; - } - - int offset = 2; - - if(c->buffer[1] == 0x02) { - if(c->buflen < 4) { - return 0; - } - - if(c->buffer[2] != 0x05 || c->buffer[3] != 0x00) { - logger(LOG_ERR, "Proxy username/password rejected"); - return -1; - } - - offset += 2; - } - - if(c->buflen - offset < 7) { - return 0; - } - - if(c->buffer[offset] != 0x05 || c->buffer[offset + 1] != 0x00) { - logger(LOG_ERR, "Proxy request rejected"); - return -1; - } - - int replen = offset + 6; - - switch(c->buffer[offset + 3]) { - case 0x01: // IPv4 - if(c->address.sa.sa_family == AF_UNKNOWN) { - update_address_ipv4(c, c->buffer + offset + 4, c->buffer + offset + 8); - } - - replen += 4; - break; - - case 0x03: // Hostname - if(c->address.sa.sa_family == AF_UNKNOWN) { - update_address_ipv4(c, "\0\0\0\1", "\0\0"); - } - - replen += ((uint8_t *)c->buffer)[offset + 4]; - break; - - case 0x04: // IPv6 - if(c->address.sa.sa_family == AF_UNKNOWN) { - update_address_ipv6(c, c->buffer + offset + 4, c->buffer + offset + 20); - } - - replen += 16; - break; - - default: - logger(LOG_ERR, "Proxy reply malformed"); - return -1; - } - - if(c->buflen < replen) { - return 0; - } else { - ifdebug(CONNECTIONS) logger(LOG_DEBUG, "Proxy request granted"); - c->allow_request = ID; - c->status.proxy_passed = true; - send_id(c); - return replen; - } - - case PROXY_HTTP: { - char *p = memchr(c->buffer, '\n', c->buflen); - - if(!p || p - c->buffer >= c->buflen) { - return 0; - } - - while((p = memchr(p + 1, '\n', c->buflen - (p + 1 - c->buffer)))) { - if(p > c->buffer + 3 && !memcmp(p - 3, "\r\n\r\n", 4)) { - break; - } - } - - if(!p) { - return 0; - } - - if(c->buflen < 9) { - return 0; - } - - if(!strncasecmp(c->buffer, "HTTP/1.1 ", 9)) { - if(!strncmp(c->buffer + 9, "200", 3)) { - if(c->address.sa.sa_family == AF_UNKNOWN) { - update_address_ipv4(c, "\0\0\0\1", "\0\0"); - } - - logger(LOG_DEBUG, "Proxy request granted"); - replen = p + 1 - c->buffer; - c->allow_request = ID; - c->status.proxy_passed = true; - send_id(c); - return replen; - } else { - p = memchr(c->buffer, '\n', c->buflen); - p[-1] = 0; - logger(LOG_ERR, "Proxy request rejected: %s", c->buffer + 9); - return false; - } - } else { - logger(LOG_ERR, "Proxy reply malformed"); - return -1; - } - } - - default: - abort(); - } -} diff --git a/src/raw_socket_device.c b/src/raw_socket/device.c similarity index 61% rename from src/raw_socket_device.c rename to src/raw_socket/device.c index f4ed694..410e46e 100644 --- a/src/raw_socket_device.c +++ b/src/raw_socket/device.c @@ -1,7 +1,7 @@ /* device.c -- raw socket Copyright (C) 2002-2005 Ivo Timmermans, - 2002-2014 Guus Sliepen + 2002-2009 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 @@ -20,9 +20,7 @@ #include "system.h" -#ifdef HAVE_NETPACKET_PACKET_H #include -#endif #include "conf.h" #include "device.h" @@ -32,51 +30,49 @@ #include "route.h" #include "xalloc.h" -#if defined(PF_PACKET) && defined(ETH_P_ALL) && defined(AF_PACKET) && defined(SIOCGIFINDEX) -static const char *device_info = "raw_socket"; +int device_fd = -1; +char *device = NULL; +char *iface = NULL; +static char ifrname[IFNAMSIZ]; +static char *device_info; static uint64_t device_total_in = 0; static uint64_t device_total_out = 0; -static bool setup_device(void) { +bool setup_device(void) { struct ifreq ifr; struct sockaddr_ll sa; - if(!get_config_string(lookup_config(config_tree, "Interface"), &iface)) { + if(!get_config_string(lookup_config(config_tree, "Interface"), &iface)) iface = xstrdup("eth0"); - } - if(!get_config_string(lookup_config(config_tree, "Device"), &device)) { + if(!get_config_string(lookup_config(config_tree, "Device"), &device)) device = xstrdup(iface); - } + + device_info = "raw socket"; if((device_fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL))) < 0) { logger(LOG_ERR, "Could not open %s: %s", device_info, - strerror(errno)); + strerror(errno)); return false; } -#ifdef FD_CLOEXEC - fcntl(device_fd, F_SETFD, FD_CLOEXEC); -#endif - - memset(&ifr, 0, sizeof(ifr)); + memset(&ifr, 0, sizeof ifr); strncpy(ifr.ifr_ifrn.ifrn_name, iface, IFNAMSIZ); - ifr.ifr_ifrn.ifrn_name[IFNAMSIZ - 1] = 0; - if(ioctl(device_fd, SIOCGIFINDEX, &ifr)) { close(device_fd); - logger(LOG_ERR, "Can't find interface %s: %s", ifr.ifr_ifrn.ifrn_name, strerror(errno)); + logger(LOG_ERR, "Can't find interface %s: %s", iface, + strerror(errno)); return false; } - memset(&sa, 0, sizeof(sa)); + memset(&sa, '0', sizeof sa); sa.sll_family = AF_PACKET; sa.sll_protocol = htons(ETH_P_ALL); sa.sll_ifindex = ifr.ifr_ifindex; - if(bind(device_fd, (struct sockaddr *) &sa, (socklen_t) sizeof(sa))) { - logger(LOG_ERR, "Could not bind %s to %s: %s", device, ifr.ifr_ifrn.ifrn_name, strerror(errno)); + if(bind(device_fd, (struct sockaddr *) &sa, (socklen_t) sizeof sa)) { + logger(LOG_ERR, "Could not bind %s to %s: %s", device, iface, strerror(errno)); return false; } @@ -85,39 +81,39 @@ static bool setup_device(void) { return true; } -static void close_device(void) { +void close_device(void) { close(device_fd); free(device); free(iface); } -static bool read_packet(vpn_packet_t *packet) { - int lenin; +bool read_packet(vpn_packet_t *packet) { + int inlen; - if((lenin = read(device_fd, packet->data, MTU)) <= 0) { + if((inlen = read(device_fd, packet->data, MTU)) <= 0) { logger(LOG_ERR, "Error while reading from %s %s: %s", device_info, - device, strerror(errno)); + device, strerror(errno)); return false; } - packet->len = lenin; + packet->len = inlen; device_total_in += packet->len; ifdebug(TRAFFIC) logger(LOG_DEBUG, "Read packet of %d bytes from %s", packet->len, - device_info); + device_info); return true; } -static bool write_packet(vpn_packet_t *packet) { +bool write_packet(vpn_packet_t *packet) { ifdebug(TRAFFIC) logger(LOG_DEBUG, "Writing packet of %d bytes to %s", - packet->len, device_info); + packet->len, device_info); if(write(device_fd, packet->data, packet->len) < 0) { logger(LOG_ERR, "Can't write to %s %s: %s", device_info, device, - strerror(errno)); + strerror(errno)); return false; } @@ -126,32 +122,8 @@ static bool write_packet(vpn_packet_t *packet) { return true; } -static void dump_device_stats(void) { +void dump_device_stats(void) { logger(LOG_DEBUG, "Statistics for %s %s:", device_info, device); logger(LOG_DEBUG, " total bytes in: %10"PRIu64, device_total_in); logger(LOG_DEBUG, " total bytes out: %10"PRIu64, device_total_out); } - -const devops_t raw_socket_devops = { - .setup = setup_device, - .close = close_device, - .read = read_packet, - .write = write_packet, - .dump_stats = dump_device_stats, -}; - -#else - -static bool not_supported(void) { - logger(LOG_ERR, "Raw socket device not supported on this platform"); - return false; -} - -const devops_t raw_socket_devops = { - .setup = not_supported, - .close = NULL, - .read = NULL, - .write = NULL, - .dump_stats = NULL, -}; -#endif diff --git a/src/route.c b/src/route.c index 850a146..0b2d22e 100644 --- a/src/route.c +++ b/src/route.c @@ -1,8 +1,7 @@ /* route.c -- routing Copyright (C) 2000-2005 Ivo Timmermans, - 2000-2017 Guus Sliepen - 2015-2016 Vittorio Gambaletta + 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 @@ -21,12 +20,14 @@ #include "system.h" -#include "avl_tree.h" +#include "splay_tree.h" #include "connection.h" +#include "control_common.h" #include "ethernet.h" #include "ipv4.h" #include "ipv6.h" #include "logger.h" +#include "meta.h" #include "net.h" #include "protocol.h" #include "route.h" @@ -35,13 +36,12 @@ rmode_t routing_mode = RMODE_ROUTER; fmode_t forwarding_mode = FMODE_INTERNAL; -bmode_t broadcast_mode = BMODE_MST; -bool decrement_ttl = false; bool directonly = false; bool priorityinheritance = false; int macexpire = 600; bool overwrite_mac = false; mac_t mymac = {{0xFE, 0xFD, 0, 0, 0, 0}}; +bool pcap = false; /* Sizes of various headers */ @@ -58,6 +58,8 @@ static const size_t opt_size = sizeof(struct nd_opt_hdr); #define MAX(a, b) ((a) > (b) ? (a) : (b)) #endif +static struct event age_subnets_event; + /* RFC 1071 */ static uint16_t inet_checksum(void *data, int len, uint16_t prevsum) { @@ -68,14 +70,12 @@ static uint16_t inet_checksum(void *data, int len, uint16_t prevsum) { checksum += *p++; len -= 2; } - - if(len) { + + if(len) checksum += *(uint8_t *)p; - } - while(checksum >> 16) { + while(checksum >> 16) checksum = (checksum & 0xFFFF) + (checksum >> 16); - } return ~checksum; } @@ -83,17 +83,16 @@ static uint16_t inet_checksum(void *data, int len, uint16_t prevsum) { static bool ratelimit(int frequency) { static time_t lasttime = 0; static int count = 0; - + time_t now = time(NULL); + if(lasttime == now) { - if(count >= frequency) { + if(++count > frequency) return true; - } } else { lasttime = now; count = 0; } - count++; return false; } @@ -101,32 +100,175 @@ static bool checklength(node_t *source, vpn_packet_t *packet, length_t length) { if(packet->len < length) { ifdebug(TRAFFIC) logger(LOG_WARNING, "Got too short packet from %s (%s)", source->name, source->hostname); return false; - } else { + } else return true; +} + +static void clamp_mss(const node_t *source, const node_t *via, vpn_packet_t *packet) { + 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]; + + 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 = 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)); - memcpy(&packet->data[0], &packet->data[6], sizeof(tmp)); - memcpy(&packet->data[6], &tmp, sizeof(tmp)); + memcpy(&tmp, &packet->data[0], sizeof tmp); + memcpy(&packet->data[0], &packet->data[6], sizeof tmp); + memcpy(&packet->data[6], &tmp, sizeof tmp); +} + +static void age_subnets(int fd, short events, void *data) { + subnet_t *s; + connection_t *c; + splay_node_t *node, *next, *node2; + bool left = false; + time_t now = time(NULL); + + for(node = myself->subnet_tree->head; node; node = next) { + next = node->next; + s = node->data; + if(s->expires && s->expires < now) { + ifdebug(TRAFFIC) { + char netstr[MAXNETSTR]; + if(net2str(netstr, sizeof netstr, s)) + logger(LOG_INFO, "Subnet %s expired", netstr); + } + + for(node2 = connection_tree->head; node2; node2 = node2->next) { + c = node2->data; + if(c->status.active) + send_del_subnet(c, s); + } + + subnet_del(myself, s); + } else { + if(s->expires) + left = true; + } + } + + if(left) + event_add(&age_subnets_event, &(struct timeval){10, 0}); +} + +static void learn_mac(mac_t *address) { + subnet_t *subnet; + splay_node_t *node; + connection_t *c; + + subnet = lookup_subnet_mac(myself, address); + + /* If we don't know this MAC address yet, store it */ + + if(!subnet) { + ifdebug(TRAFFIC) logger(LOG_INFO, "Learned new MAC address %hx:%hx:%hx:%hx:%hx:%hx", + address->x[0], address->x[1], address->x[2], address->x[3], + address->x[4], address->x[5]); + + subnet = new_subnet(); + subnet->type = SUBNET_MAC; + subnet->expires = time(NULL) + macexpire; + 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 */ + + for(node = connection_tree->head; node; node = node->next) { + c = node->data; + if(c->status.active) + send_add_subnet(c, subnet); + } + + if(!timeout_initialized(&age_subnets_event)) + timeout_set(&age_subnets_event, age_subnets, NULL); + event_add(&age_subnets_event, &(struct timeval){10, 0}); + } else { + if(subnet->expires) + subnet->expires = time(NULL) + macexpire; + } } /* RFC 792 */ -static void route_ipv4_unreachable(node_t *source, vpn_packet_t *packet, length_t ether_size, uint8_t type, uint8_t code) { +static void route_ipv4_unreachable(node_t *source, vpn_packet_t *packet, uint8_t type, uint8_t code) { struct ip ip = {0}; struct icmp icmp = {0}; - + struct in_addr ip_src; struct in_addr ip_dst; uint32_t oldlen; - if(ratelimit(3)) { + if(ratelimit(3)) return; - } - + /* Swap Ethernet source and destination addresses */ swap_mac_addresses(packet); @@ -136,51 +278,24 @@ static void route_ipv4_unreachable(node_t *source, vpn_packet_t *packet, length_ memcpy(&ip, packet->data + ether_size, ip_size); /* Remember original source and destination */ - + ip_src = ip.ip_src; ip_dst = ip.ip_dst; - /* Try to reply with an IP address assigned to the local machine */ - - if(type == ICMP_TIME_EXCEEDED && code == ICMP_EXC_TTL) { - int sockfd = socket(AF_INET, SOCK_DGRAM, 0); - - if(sockfd != -1) { - struct sockaddr_in addr; - memset(&addr, 0, sizeof(addr)); - addr.sin_family = AF_INET; - addr.sin_addr = ip.ip_src; - - if(!connect(sockfd, (const struct sockaddr *) &addr, sizeof(addr))) { - memset(&addr, 0, sizeof(addr)); - addr.sin_family = AF_INET; - socklen_t addrlen = sizeof(addr); - - if(!getsockname(sockfd, (struct sockaddr *) &addr, &addrlen) && addrlen <= sizeof(addr)) { - ip_dst = addr.sin_addr; - } - } - - close(sockfd); - } - } - oldlen = packet->len - ether_size; - if(type == ICMP_DEST_UNREACH && code == ICMP_FRAG_NEEDED) { + if(type == ICMP_DEST_UNREACH && code == ICMP_FRAG_NEEDED) icmp.icmp_nextmtu = htons(packet->len - ether_size); - } - if(oldlen >= IP_MSS - ip_size - icmp_size) { + if(oldlen >= IP_MSS - ip_size - icmp_size) oldlen = IP_MSS - ip_size - icmp_size; - } - + /* Copy first part of original contents to ICMP message */ - + memmove(packet->data + ether_size + ip_size + icmp_size, packet->data + ether_size, oldlen); /* Fill in IPv4 header */ - + ip.ip_v = 4; ip.ip_hl = ip_size / 4; ip.ip_tos = 0; @@ -194,13 +309,13 @@ static void route_ipv4_unreachable(node_t *source, vpn_packet_t *packet, length_ ip.ip_dst = ip_src; ip.ip_sum = inet_checksum(&ip, ip_size, ~0); - + /* Fill in ICMP header */ - + icmp.icmp_type = type; icmp.icmp_code = code; icmp.icmp_cksum = 0; - + icmp.icmp_cksum = inet_checksum(&icmp, icmp_size, ~0); icmp.icmp_cksum = inet_checksum(packet->data + ether_size + ip_size + icmp_size, oldlen, icmp.icmp_cksum); @@ -208,369 +323,27 @@ static void route_ipv4_unreachable(node_t *source, vpn_packet_t *packet, length_ memcpy(packet->data + ether_size, &ip, ip_size); memcpy(packet->data + ether_size + ip_size, &icmp, icmp_size); - + packet->len = ether_size + ip_size + icmp_size + oldlen; send_packet(source, packet); } -/* RFC 2463 */ - -static void route_ipv6_unreachable(node_t *source, vpn_packet_t *packet, length_t ether_size, uint8_t type, uint8_t code) { - struct ip6_hdr ip6; - struct icmp6_hdr icmp6 = {0}; - uint16_t checksum; - - struct { - struct in6_addr ip6_src; /* source address */ - struct in6_addr ip6_dst; /* destination address */ - uint32_t length; - uint32_t next; - } pseudo; - - if(ratelimit(3)) { - return; - } - - /* Swap Ethernet source and destination addresses */ - - swap_mac_addresses(packet); - - /* Copy headers from packet to structs on the stack */ - - memcpy(&ip6, packet->data + ether_size, ip6_size); - - /* Remember original source and destination */ - - pseudo.ip6_src = ip6.ip6_dst; - pseudo.ip6_dst = ip6.ip6_src; - - /* Try to reply with an IP address assigned to the local machine */ - - if(type == ICMP6_TIME_EXCEEDED && code == ICMP6_TIME_EXCEED_TRANSIT) { - int sockfd = socket(AF_INET6, SOCK_DGRAM, 0); - - if(sockfd != -1) { - struct sockaddr_in6 addr; - memset(&addr, 0, sizeof(addr)); - addr.sin6_family = AF_INET6; - addr.sin6_addr = ip6.ip6_src; - - if(!connect(sockfd, (const struct sockaddr *) &addr, sizeof(addr))) { - memset(&addr, 0, sizeof(addr)); - addr.sin6_family = AF_INET6; - socklen_t addrlen = sizeof(addr); - - if(!getsockname(sockfd, (struct sockaddr *) &addr, &addrlen) && addrlen <= sizeof(addr)) { - pseudo.ip6_src = addr.sin6_addr; - } - } - - close(sockfd); - } - } - - pseudo.length = packet->len - ether_size; - - if(type == ICMP6_PACKET_TOO_BIG) { - icmp6.icmp6_mtu = htonl(pseudo.length); - } - - if(pseudo.length >= IP_MSS - ip6_size - icmp6_size) { - pseudo.length = IP_MSS - ip6_size - icmp6_size; - } - - /* Copy first part of original contents to ICMP message */ - - memmove(packet->data + ether_size + ip6_size + icmp6_size, packet->data + ether_size, pseudo.length); - - /* Fill in IPv6 header */ - - ip6.ip6_flow = htonl(0x60000000UL); - ip6.ip6_plen = htons(icmp6_size + pseudo.length); - ip6.ip6_nxt = IPPROTO_ICMPV6; - ip6.ip6_hlim = 255; - ip6.ip6_src = pseudo.ip6_src; - ip6.ip6_dst = pseudo.ip6_dst; - - /* Fill in ICMP header */ - - icmp6.icmp6_type = type; - icmp6.icmp6_code = code; - icmp6.icmp6_cksum = 0; - - /* Create pseudo header */ - - pseudo.length = htonl(icmp6_size + pseudo.length); - pseudo.next = htonl(IPPROTO_ICMPV6); - - /* Generate checksum */ - - checksum = inet_checksum(&pseudo, sizeof(pseudo), ~0); - checksum = inet_checksum(&icmp6, icmp6_size, checksum); - checksum = inet_checksum(packet->data + ether_size + ip6_size + icmp6_size, ntohl(pseudo.length) - icmp6_size, checksum); - - icmp6.icmp6_cksum = checksum; - - /* Copy structs on stack back to packet */ - - memcpy(packet->data + ether_size, &ip6, ip6_size); - memcpy(packet->data + ether_size + ip6_size, &icmp6, icmp6_size); - - packet->len = ether_size + ip6_size + ntohl(pseudo.length); - - send_packet(source, packet); -} - -static bool do_decrement_ttl(node_t *source, vpn_packet_t *packet) { - uint16_t type = packet->data[12] << 8 | packet->data[13]; - length_t ethlen = ether_size; - - if(type == ETH_P_8021Q) { - type = packet->data[16] << 8 | packet->data[17]; - ethlen += 4; - } - - switch(type) { - case ETH_P_IP: - if(!checklength(source, packet, ethlen + ip_size)) { - return false; - } - - if(packet->data[ethlen + 8] <= 1) { - if(packet->data[ethlen + 11] != IPPROTO_ICMP || packet->data[ethlen + 32] != ICMP_TIME_EXCEEDED) { - route_ipv4_unreachable(source, packet, ethlen, ICMP_TIME_EXCEEDED, ICMP_EXC_TTL); - } - - return false; - } - - uint16_t old = packet->data[ethlen + 8] << 8 | packet->data[ethlen + 9]; - packet->data[ethlen + 8]--; - uint16_t new = packet->data[ethlen + 8] << 8 | packet->data[ethlen + 9]; - - uint32_t checksum = packet->data[ethlen + 10] << 8 | packet->data[ethlen + 11]; - checksum += old + (~new & 0xFFFF); - - while(checksum >> 16) { - checksum = (checksum & 0xFFFF) + (checksum >> 16); - } - - packet->data[ethlen + 10] = checksum >> 8; - packet->data[ethlen + 11] = checksum & 0xff; - - return true; - - case ETH_P_IPV6: - if(!checklength(source, packet, ethlen + ip6_size)) { - return false; - } - - if(packet->data[ethlen + 7] <= 1) { - if(packet->data[ethlen + 6] != IPPROTO_ICMPV6 || packet->data[ethlen + 40] != ICMP6_TIME_EXCEEDED) { - route_ipv6_unreachable(source, packet, ethlen, ICMP6_TIME_EXCEEDED, ICMP6_TIME_EXCEED_TRANSIT); - } - - return false; - } - - packet->data[ethlen + 7]--; - - return true; - - default: - return true; - } -} - -static void clamp_mss(const node_t *source, const node_t *via, vpn_packet_t *packet) { - 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 = ether_size; - uint16_t type = packet->data[12] << 8 | packet->data[13]; - - if(type == ETH_P_8021Q) { - start += 4; - type = packet->data[16] << 8 | packet->data[17]; - } - - if(type == ETH_P_IP && packet->data[start + 9] == 6) { - start += (packet->data[start] & 0xf) * 4; - } else if(type == ETH_P_IPV6 && packet->data[start + 6] == 6) { - start += 40; - } else { - return; - } - - if(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 = mtu - start - 20; - uint32_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 ^ 0xffff; - csum += newmss; - csum = (csum & 0xffff) + (csum >> 16); - csum += csum >> 16; - csum ^= 0xffff; - packet->data[start + 16] = csum >> 8; - packet->data[start + 17] = csum; - break; - } -} - -static void learn_mac(mac_t *address) { - subnet_t *subnet; - avl_node_t *node; - connection_t *c; - - subnet = lookup_subnet_mac(myself, address); - - /* If we don't know this MAC address yet, store it */ - - if(!subnet) { - ifdebug(TRAFFIC) logger(LOG_INFO, "Learned new MAC address %x:%x:%x:%x:%x:%x", - address->x[0], address->x[1], address->x[2], address->x[3], - address->x[4], address->x[5]); - - subnet = new_subnet(); - subnet->type = SUBNET_MAC; - subnet->expires = now + macexpire; - 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 */ - - for(node = connection_tree->head; node; node = node->next) { - c = node->data; - - if(c->status.active) { - send_add_subnet(c, subnet); - } - } - } - - if(subnet->expires) { - subnet->expires = now + macexpire; - } -} - -void age_subnets(void) { - subnet_t *s; - connection_t *c; - avl_node_t *node, *next, *node2; - - for(node = myself->subnet_tree->head; node; node = next) { - next = node->next; - s = node->data; - - if(s->expires && s->expires <= now) { - ifdebug(TRAFFIC) { - char netstr[MAXNETSTR]; - - if(net2str(netstr, sizeof(netstr), s)) { - logger(LOG_INFO, "Subnet %s expired", netstr); - } - } - - for(node2 = connection_tree->head; node2; node2 = node2->next) { - c = node2->data; - - if(c->status.active) { - send_del_subnet(c, s); - } - } - - subnet_update(myself, s, false); - subnet_del(myself, s); - } - } -} - -static void route_broadcast(node_t *source, vpn_packet_t *packet) { - if(decrement_ttl && source != myself) - if(!do_decrement_ttl(source, packet)) { - return; - } - - broadcast_packet(source, packet); -} - /* RFC 791 */ -static void fragment_ipv4_packet(node_t *dest, vpn_packet_t *packet, length_t ether_size) { +static void fragment_ipv4_packet(node_t *dest, vpn_packet_t *packet) { struct ip ip; vpn_packet_t fragment; int len, maxlen, todo; uint8_t *offset; uint16_t ip_off, origf; - + memcpy(&ip, packet->data + ether_size, ip_size); fragment.priority = packet->priority; - if(ip.ip_hl != ip_size / 4) { + if(ip.ip_hl != ip_size / 4) return; - } - + todo = ntohs(ip.ip_len) - ip_size; if(ether_size + ip_size + todo != packet->len) { @@ -585,7 +358,7 @@ static void fragment_ipv4_packet(node_t *dest, vpn_packet_t *packet, length_t et ip_off = ntohs(ip.ip_off); origf = ip_off & ~IP_OFFMASK; ip_off &= IP_OFFMASK; - + while(todo) { len = todo > maxlen ? maxlen : todo; memcpy(fragment.data + ether_size + ip_size, offset, len); @@ -603,7 +376,7 @@ static void fragment_ipv4_packet(node_t *dest, vpn_packet_t *packet, length_t et send_packet(dest, &fragment); ip_off += len / 8; - } + } } static void route_ipv4_unicast(node_t *source, vpn_packet_t *packet) { @@ -611,89 +384,149 @@ static void route_ipv4_unicast(node_t *source, vpn_packet_t *packet) { node_t *via; ipv4_t dest; - memcpy(&dest, &packet->data[30], sizeof(dest)); + memcpy(&dest, &packet->data[30], sizeof dest); subnet = lookup_subnet_ipv4(&dest); if(!subnet) { ifdebug(TRAFFIC) logger(LOG_WARNING, "Cannot route packet from %s (%s): unknown IPv4 destination address %d.%d.%d.%d", - source->name, source->hostname, - dest.x[0], - dest.x[1], - dest.x[2], - dest.x[3]); + source->name, source->hostname, + dest.x[0], + dest.x[1], + dest.x[2], + dest.x[3]); - route_ipv4_unreachable(source, packet, ether_size, ICMP_DEST_UNREACH, ICMP_NET_UNKNOWN); + route_ipv4_unreachable(source, packet, ICMP_DEST_UNREACH, ICMP_NET_UNKNOWN); return; } - + if(subnet->owner == source) { ifdebug(TRAFFIC) logger(LOG_WARNING, "Packet looping back to %s (%s)!", source->name, source->hostname); return; } - if(!subnet->owner->status.reachable) { - route_ipv4_unreachable(source, packet, ether_size, ICMP_DEST_UNREACH, ICMP_NET_UNREACH); - return; - } + if(!subnet->owner->status.reachable) + return route_ipv4_unreachable(source, packet, ICMP_DEST_UNREACH, ICMP_NET_UNREACH); - if(forwarding_mode == FMODE_OFF && source != myself && subnet->owner != myself) { - route_ipv4_unreachable(source, packet, ether_size, ICMP_DEST_UNREACH, ICMP_NET_ANO); - return; - } + if(forwarding_mode == FMODE_OFF && source != myself && subnet->owner != myself) + return route_ipv4_unreachable(source, packet, ICMP_DEST_UNREACH, ICMP_NET_ANO); - if(decrement_ttl && source != myself && subnet->owner != myself) - if(!do_decrement_ttl(source, packet)) { - return; - } - - if(priorityinheritance) { + if(priorityinheritance) packet->priority = packet->data[15]; - } via = (subnet->owner->via == myself) ? subnet->owner->nexthop : subnet->owner->via; - - if(via == source) { - ifdebug(TRAFFIC) logger(LOG_ERR, "Routing loop for packet from %s (%s)!", source->name, source->hostname); - return; - } - - if(directonly && subnet->owner != via) { - route_ipv4_unreachable(source, packet, ether_size, ICMP_DEST_UNREACH, ICMP_NET_ANO); - return; - } + + 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); - route_ipv4_unreachable(source, packet, ether_size, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED); + route_ipv4_unreachable(source, packet, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED); } else { - fragment_ipv4_packet(via, packet, ether_size); + fragment_ipv4_packet(via, packet); } return; } clamp_mss(source, via, packet); - + send_packet(subnet->owner, packet); } static void route_ipv4(node_t *source, vpn_packet_t *packet) { - if(!checklength(source, packet, ether_size + ip_size)) { + if(!checklength(source, packet, ether_size + ip_size)) return; - } - if(broadcast_mode && (((packet->data[30] & 0xf0) == 0xe0) || ( - packet->data[30] == 255 && - packet->data[31] == 255 && - packet->data[32] == 255 && - packet->data[33] == 255))) { - route_broadcast(source, packet); - } else { + if(((packet->data[30] & 0xf0) == 0xe0) || ( + packet->data[30] == 255 && + packet->data[31] == 255 && + packet->data[32] == 255 && + packet->data[33] == 255)) + broadcast_packet(source, packet); + else route_ipv4_unicast(source, packet); - } +} + +/* RFC 2463 */ + +static void route_ipv6_unreachable(node_t *source, vpn_packet_t *packet, uint8_t type, uint8_t code) { + struct ip6_hdr ip6; + struct icmp6_hdr icmp6 = {0}; + uint16_t checksum; + + struct { + struct in6_addr ip6_src; /* source address */ + struct in6_addr ip6_dst; /* destination address */ + uint32_t length; + uint32_t next; + } pseudo; + + if(ratelimit(3)) + return; + + /* Swap Ethernet source and destination addresses */ + + swap_mac_addresses(packet); + + /* Copy headers from packet to structs on the stack */ + + memcpy(&ip6, packet->data + ether_size, ip6_size); + + /* Remember original source and destination */ + + pseudo.ip6_src = ip6.ip6_dst; + pseudo.ip6_dst = ip6.ip6_src; + + pseudo.length = packet->len - ether_size; + + if(type == ICMP6_PACKET_TOO_BIG) + icmp6.icmp6_mtu = htonl(pseudo.length); + + if(pseudo.length >= IP_MSS - ip6_size - icmp6_size) + pseudo.length = IP_MSS - ip6_size - icmp6_size; + + /* Copy first part of original contents to ICMP message */ + + memmove(packet->data + ether_size + ip6_size + icmp6_size, packet->data + ether_size, pseudo.length); + + /* Fill in IPv6 header */ + + ip6.ip6_flow = htonl(0x60000000UL); + ip6.ip6_plen = htons(icmp6_size + pseudo.length); + ip6.ip6_nxt = IPPROTO_ICMPV6; + ip6.ip6_hlim = 255; + ip6.ip6_src = pseudo.ip6_src; + ip6.ip6_dst = pseudo.ip6_dst; + + /* Fill in ICMP header */ + + icmp6.icmp6_type = type; + icmp6.icmp6_code = code; + icmp6.icmp6_cksum = 0; + + /* Create pseudo header */ + + pseudo.length = htonl(icmp6_size + pseudo.length); + pseudo.next = htonl(IPPROTO_ICMPV6); + + /* Generate checksum */ + + checksum = inet_checksum(&pseudo, sizeof pseudo, ~0); + checksum = inet_checksum(&icmp6, icmp6_size, checksum); + checksum = inet_checksum(packet->data + ether_size + ip6_size + icmp6_size, ntohl(pseudo.length) - icmp6_size, checksum); + + icmp6.icmp6_cksum = checksum; + + /* Copy structs on stack back to packet */ + + memcpy(packet->data + ether_size, &ip6, ip6_size); + memcpy(packet->data + ether_size + ip6_size, &icmp6, icmp6_size); + + packet->len = ether_size + ip6_size + ntohl(pseudo.length); + + send_packet(source, packet); } static void route_ipv6_unicast(node_t *source, vpn_packet_t *packet) { @@ -701,22 +534,22 @@ static void route_ipv6_unicast(node_t *source, vpn_packet_t *packet) { node_t *via; ipv6_t dest; - memcpy(&dest, &packet->data[38], sizeof(dest)); + memcpy(&dest, &packet->data[38], sizeof dest); subnet = lookup_subnet_ipv6(&dest); if(!subnet) { ifdebug(TRAFFIC) logger(LOG_WARNING, "Cannot route packet from %s (%s): unknown IPv6 destination address %hx:%hx:%hx:%hx:%hx:%hx:%hx:%hx", - source->name, source->hostname, - ntohs(dest.x[0]), - ntohs(dest.x[1]), - ntohs(dest.x[2]), - ntohs(dest.x[3]), - ntohs(dest.x[4]), - ntohs(dest.x[5]), - ntohs(dest.x[6]), - ntohs(dest.x[7])); + source->name, source->hostname, + ntohs(dest.x[0]), + ntohs(dest.x[1]), + ntohs(dest.x[2]), + ntohs(dest.x[3]), + ntohs(dest.x[4]), + ntohs(dest.x[5]), + ntohs(dest.x[6]), + ntohs(dest.x[7])); - route_ipv6_unreachable(source, packet, ether_size, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_ADDR); + route_ipv6_unreachable(source, packet, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_ADDR); return; } @@ -725,47 +558,26 @@ static void route_ipv6_unicast(node_t *source, vpn_packet_t *packet) { return; } - if(!subnet->owner->status.reachable) { - route_ipv6_unreachable(source, packet, ether_size, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_NOROUTE); - return; - } + if(!subnet->owner->status.reachable) + return route_ipv6_unreachable(source, packet, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_NOROUTE); - if(forwarding_mode == FMODE_OFF && source != myself && subnet->owner != myself) { - route_ipv6_unreachable(source, packet, ether_size, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_ADMIN); - return; - } - - if(decrement_ttl && source != myself && subnet->owner != myself) { - if(!do_decrement_ttl(source, packet)) { - return; - } - } - - if(priorityinheritance) { - packet->priority = ((packet->data[14] & 0x0f) << 4) | (packet->data[15] >> 4); - } + 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 == source) { - ifdebug(TRAFFIC) logger(LOG_ERR, "Routing loop for packet from %s (%s)!", source->name, source->hostname); - return; - } - - if(directonly && subnet->owner != via) { - route_ipv6_unreachable(source, packet, ether_size, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_ADMIN); - return; - } + + 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); - route_ipv6_unreachable(source, packet, ether_size, ICMP6_PACKET_TOO_BIG, 0); + route_ipv6_unreachable(source, packet, ICMP6_PACKET_TOO_BIG, 0); return; } clamp_mss(source, via, packet); - + send_packet(subnet->owner, packet); } @@ -780,18 +592,17 @@ static void route_neighborsol(node_t *source, vpn_packet_t *packet) { bool has_opt; struct { - struct in6_addr ip6_src; /* source address */ - struct in6_addr ip6_dst; /* destination address */ + struct in6_addr ip6_src; /* source address */ + struct in6_addr ip6_dst; /* destination address */ uint32_t length; uint32_t next; } pseudo; - if(!checklength(source, packet, ether_size + ip6_size + ns_size)) { + if(!checklength(source, packet, ether_size + ip6_size + ns_size)) return; - } - + has_opt = packet->len >= ether_size + ip6_size + ns_size + opt_size + ETH_ALEN; - + if(source != myself) { ifdebug(TRAFFIC) logger(LOG_WARNING, "Got neighbor solicitation request from %s (%s) while in router mode!", source->name, source->hostname); return; @@ -801,21 +612,18 @@ static void route_neighborsol(node_t *source, vpn_packet_t *packet) { memcpy(&ip6, packet->data + ether_size, ip6_size); memcpy(&ns, packet->data + ether_size + ip6_size, ns_size); - - if(has_opt) { + if(has_opt) memcpy(&opt, packet->data + ether_size + ip6_size + ns_size, opt_size); - } /* First, snatch the source address from the neighbor solicitation packet */ - if(overwrite_mac) { + if(overwrite_mac) memcpy(mymac.x, packet->data + ETH_ALEN, ETH_ALEN); - } /* Check if this is a valid neighbor solicitation request */ if(ns.nd_ns_hdr.icmp6_type != ND_NEIGHBOR_SOLICIT || - (has_opt && opt.nd_opt_type != ND_OPT_SOURCE_LINKADDR)) { + (has_opt && opt.nd_opt_type != ND_OPT_SOURCE_LINKADDR)) { ifdebug(TRAFFIC) logger(LOG_WARNING, "Cannot route packet: received unknown type neighbor solicitation request"); return; } @@ -824,20 +632,16 @@ static void route_neighborsol(node_t *source, vpn_packet_t *packet) { pseudo.ip6_src = ip6.ip6_src; pseudo.ip6_dst = ip6.ip6_dst; - - if(has_opt) { + if(has_opt) pseudo.length = htonl(ns_size + opt_size + ETH_ALEN); - } else { + else pseudo.length = htonl(ns_size); - } - pseudo.next = htonl(IPPROTO_ICMPV6); /* Generate checksum */ - checksum = inet_checksum(&pseudo, sizeof(pseudo), ~0); + checksum = inet_checksum(&pseudo, sizeof pseudo, ~0); checksum = inet_checksum(&ns, ns_size, checksum); - if(has_opt) { checksum = inet_checksum(&opt, opt_size, checksum); checksum = inet_checksum(packet->data + ether_size + ip6_size + ns_size + opt_size, ETH_ALEN, checksum); @@ -854,64 +658,53 @@ static void route_neighborsol(node_t *source, vpn_packet_t *packet) { if(!subnet) { ifdebug(TRAFFIC) logger(LOG_WARNING, "Cannot route packet: neighbor solicitation request for unknown address %hx:%hx:%hx:%hx:%hx:%hx:%hx:%hx", - ntohs(((uint16_t *) &ns.nd_ns_target)[0]), - ntohs(((uint16_t *) &ns.nd_ns_target)[1]), - ntohs(((uint16_t *) &ns.nd_ns_target)[2]), - ntohs(((uint16_t *) &ns.nd_ns_target)[3]), - ntohs(((uint16_t *) &ns.nd_ns_target)[4]), - ntohs(((uint16_t *) &ns.nd_ns_target)[5]), - ntohs(((uint16_t *) &ns.nd_ns_target)[6]), - ntohs(((uint16_t *) &ns.nd_ns_target)[7])); + ntohs(((uint16_t *) &ns.nd_ns_target)[0]), + ntohs(((uint16_t *) &ns.nd_ns_target)[1]), + ntohs(((uint16_t *) &ns.nd_ns_target)[2]), + ntohs(((uint16_t *) &ns.nd_ns_target)[3]), + ntohs(((uint16_t *) &ns.nd_ns_target)[4]), + ntohs(((uint16_t *) &ns.nd_ns_target)[5]), + ntohs(((uint16_t *) &ns.nd_ns_target)[6]), + ntohs(((uint16_t *) &ns.nd_ns_target)[7])); return; } /* Check if it is for our own subnet */ - if(subnet->owner == myself) { - return; /* silently ignore */ - } - - if(decrement_ttl) - if(!do_decrement_ttl(source, packet)) { - return; - } + if(subnet->owner == myself) + return; /* silently ignore */ /* Create neighbor advertation reply */ - memcpy(packet->data, packet->data + ETH_ALEN, ETH_ALEN); /* copy destination address */ - packet->data[ETH_ALEN * 2 - 1] ^= 0xFF; /* mangle source address so it looks like it's not from us */ + memcpy(packet->data, packet->data + ETH_ALEN, ETH_ALEN); /* copy destination address */ + packet->data[ETH_ALEN * 2 - 1] ^= 0xFF; /* mangle source address so it looks like it's not from us */ - ip6.ip6_dst = ip6.ip6_src; /* swap destination and source protocol address */ + ip6.ip6_dst = ip6.ip6_src; /* swap destination and source protocoll address */ ip6.ip6_src = ns.nd_ns_target; - if(has_opt) { - memcpy(packet->data + ether_size + ip6_size + ns_size + opt_size, packet->data + ETH_ALEN, ETH_ALEN); /* add fake source hard addr */ - } + if(has_opt) + memcpy(packet->data + ether_size + ip6_size + ns_size + opt_size, packet->data + ETH_ALEN, ETH_ALEN); /* add fake source hard addr */ ns.nd_ns_cksum = 0; ns.nd_ns_type = ND_NEIGHBOR_ADVERT; - ns.nd_ns_reserved = htonl(0x40000000UL); /* Set solicited flag */ + ns.nd_ns_reserved = htonl(0x40000000UL); /* Set solicited flag */ opt.nd_opt_type = ND_OPT_TARGET_LINKADDR; /* Create pseudo header */ pseudo.ip6_src = ip6.ip6_src; pseudo.ip6_dst = ip6.ip6_dst; - - if(has_opt) { + if(has_opt) pseudo.length = htonl(ns_size + opt_size + ETH_ALEN); - } else { + else pseudo.length = htonl(ns_size); - } - pseudo.next = htonl(IPPROTO_ICMPV6); /* Generate checksum */ - checksum = inet_checksum(&pseudo, sizeof(pseudo), ~0); + checksum = inet_checksum(&pseudo, sizeof pseudo, ~0); checksum = inet_checksum(&ns, ns_size, checksum); - if(has_opt) { checksum = inet_checksum(&opt, opt_size, checksum); checksum = inet_checksum(packet->data + ether_size + ip6_size + ns_size + opt_size, ETH_ALEN, checksum); @@ -923,29 +716,25 @@ static void route_neighborsol(node_t *source, vpn_packet_t *packet) { memcpy(packet->data + ether_size, &ip6, ip6_size); memcpy(packet->data + ether_size + ip6_size, &ns, ns_size); - - if(has_opt) { + if(has_opt) memcpy(packet->data + ether_size + ip6_size + ns_size, &opt, opt_size); - } send_packet(source, packet); } static void route_ipv6(node_t *source, vpn_packet_t *packet) { - if(!checklength(source, packet, ether_size + ip6_size)) { + if(!checklength(source, packet, ether_size + ip6_size)) return; - } if(packet->data[20] == IPPROTO_ICMPV6 && checklength(source, packet, ether_size + ip6_size + icmp6_size) && packet->data[54] == ND_NEIGHBOR_SOLICIT) { route_neighborsol(source, packet); return; } - if(broadcast_mode && packet->data[38] == 255) { - route_broadcast(source, packet); - } else { + if(packet->data[38] == 255) + broadcast_packet(source, packet); + else route_ipv6_unicast(source, packet); - } } /* RFC 826 */ @@ -955,9 +744,8 @@ static void route_arp(node_t *source, vpn_packet_t *packet) { subnet_t *subnet; struct in_addr addr; - if(!checklength(source, packet, ether_size + arp_size)) { + if(!checklength(source, packet, ether_size + arp_size)) return; - } if(source != myself) { ifdebug(TRAFFIC) logger(LOG_WARNING, "Got ARP request from %s (%s) while in router mode!", source->name, source->hostname); @@ -966,9 +754,8 @@ static void route_arp(node_t *source, vpn_packet_t *packet) { /* First, snatch the source address from the ARP packet */ - if(overwrite_mac) { + if(overwrite_mac) memcpy(mymac.x, packet->data + ETH_ALEN, ETH_ALEN); - } /* Copy headers from packet to structs on the stack */ @@ -977,7 +764,7 @@ static void route_arp(node_t *source, vpn_packet_t *packet) { /* Check if this is a valid ARP request */ if(ntohs(arp.arp_hrd) != ARPHRD_ETHER || ntohs(arp.arp_pro) != ETH_P_IP || - arp.arp_hln != ETH_ALEN || arp.arp_pln != sizeof(addr) || ntohs(arp.arp_op) != ARPOP_REQUEST) { + arp.arp_hln != ETH_ALEN || arp.arp_pln != sizeof addr || ntohs(arp.arp_op) != ARPOP_REQUEST) { ifdebug(TRAFFIC) logger(LOG_WARNING, "Cannot route packet: received unknown type ARP request"); return; } @@ -988,31 +775,25 @@ static void route_arp(node_t *source, vpn_packet_t *packet) { if(!subnet) { ifdebug(TRAFFIC) logger(LOG_WARNING, "Cannot route packet: ARP request for unknown address %d.%d.%d.%d", - arp.arp_tpa[0], arp.arp_tpa[1], arp.arp_tpa[2], - arp.arp_tpa[3]); + arp.arp_tpa[0], arp.arp_tpa[1], arp.arp_tpa[2], + arp.arp_tpa[3]); return; } /* Check if it is for our own subnet */ - if(subnet->owner == myself) { - return; /* silently ignore */ - } + if(subnet->owner == myself) + return; /* silently ignore */ - if(decrement_ttl) - if(!do_decrement_ttl(source, packet)) { - return; - } + memcpy(packet->data, packet->data + ETH_ALEN, ETH_ALEN); /* copy destination address */ + packet->data[ETH_ALEN * 2 - 1] ^= 0xFF; /* mangle source address so it looks like it's not from us */ - memcpy(packet->data, packet->data + ETH_ALEN, ETH_ALEN); /* copy destination address */ - packet->data[ETH_ALEN * 2 - 1] ^= 0xFF; /* mangle source address so it looks like it's not from us */ + memcpy(&addr, arp.arp_tpa, sizeof addr); /* save protocol addr */ + memcpy(arp.arp_tpa, arp.arp_spa, sizeof addr); /* swap destination and source protocol address */ + memcpy(arp.arp_spa, &addr, sizeof addr); /* ... */ - memcpy(&addr, arp.arp_tpa, sizeof(addr)); /* save protocol addr */ - memcpy(arp.arp_tpa, arp.arp_spa, sizeof(addr)); /* swap destination and source protocol address */ - memcpy(arp.arp_spa, &addr, sizeof(addr)); /* ... */ - - memcpy(arp.arp_tha, arp.arp_sha, ETH_ALEN); /* set target hard/proto addr */ - memcpy(arp.arp_sha, packet->data + ETH_ALEN, ETH_ALEN); /* add fake source hard addr */ + memcpy(arp.arp_tha, arp.arp_sha, ETH_ALEN); /* set target hard/proto addr */ + memcpy(arp.arp_sha, packet->data + ETH_ALEN, ETH_ALEN); /* add fake source hard addr */ arp.arp_op = htons(ARPOP_REPLY); /* Copy structs on stack back to packet */ @@ -1030,17 +811,17 @@ static void route_mac(node_t *source, vpn_packet_t *packet) { if(source == myself) { mac_t src; - memcpy(&src, &packet->data[6], sizeof(src)); + memcpy(&src, &packet->data[6], sizeof src); learn_mac(&src); } /* Lookup destination address */ - memcpy(&dest, &packet->data[0], sizeof(dest)); + memcpy(&dest, &packet->data[0], sizeof dest); subnet = lookup_subnet_mac(NULL, &dest); if(!subnet) { - route_broadcast(source, packet); + broadcast_packet(source, packet); return; } @@ -1049,103 +830,95 @@ static void route_mac(node_t *source, vpn_packet_t *packet) { return; } - if(forwarding_mode == FMODE_OFF && source != myself && subnet->owner != myself) { + if(forwarding_mode == FMODE_OFF && source != myself && subnet->owner != myself) return; - } - - if(decrement_ttl && source != myself && subnet->owner != myself) - if(!do_decrement_ttl(source, packet)) { - return; - } - - uint16_t type = packet->data[12] << 8 | packet->data[13]; - - if(priorityinheritance) { - if(type == ETH_P_IP && packet->len >= ether_size + ip_size) { - packet->priority = packet->data[15]; - } else if(type == ETH_P_IPV6 && packet->len >= ether_size + ip6_size) { - packet->priority = ((packet->data[14] & 0x0f) << 4) | (packet->data[15] >> 4); - } - } // Handle packets larger than PMTU node_t *via = (subnet->owner->via == myself) ? subnet->owner->nexthop : subnet->owner->via; - if(directonly && 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); - length_t ethlen = 14; - - if(type == ETH_P_8021Q) { - type = packet->data[16] << 8 | packet->data[17]; - ethlen += 4; - } - - if(type == ETH_P_IP && packet->len > 576 + ethlen) { - if(packet->data[6 + ethlen] & 0x40) { + uint16_t type = packet->data[12] << 8 | packet->data[13]; + if(type == ETH_P_IP && packet->len > 590) { + if(packet->data[20] & 0x40) { packet->len = via->mtu; - route_ipv4_unreachable(source, packet, ethlen, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED); + route_ipv4_unreachable(source, packet, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED); } else { - fragment_ipv4_packet(via, packet, ethlen); + fragment_ipv4_packet(via, packet); } - return; - } else if(type == ETH_P_IPV6 && packet->len > 1280 + ethlen) { + } else if(type == ETH_P_IPV6 && packet->len > 1294) { packet->len = via->mtu; - route_ipv6_unreachable(source, packet, ethlen, ICMP6_PACKET_TOO_BIG, 0); + route_ipv6_unreachable(source, packet, ICMP6_PACKET_TOO_BIG, 0); return; } } clamp_mss(source, via, packet); - + send_packet(subnet->owner, packet); } +static void send_pcap(vpn_packet_t *packet) { + pcap = false; + for(splay_node_t *node = connection_tree->head; node; node = node->next) { + connection_t *c = node->data; + if(!c->status.pcap) + continue; + else + pcap = true; + if(send_request(c, "%d %d %d", CONTROL, REQ_PCAP, packet->len)) + send_meta(c, (char *)packet->data, packet->len); + } +} + void route(node_t *source, vpn_packet_t *packet) { + if(pcap) + send_pcap(packet); + if(forwarding_mode == FMODE_KERNEL && source != myself) { send_packet(myself, packet); return; } - if(!checklength(source, packet, ether_size)) { + if(!checklength(source, packet, ether_size)) return; - } - switch(routing_mode) { - case RMODE_ROUTER: { - uint16_t type = packet->data[12] << 8 | packet->data[13]; + switch (routing_mode) { + case RMODE_ROUTER: + { + uint16_t type = packet->data[12] << 8 | packet->data[13]; - switch(type) { - case ETH_P_ARP: - route_arp(source, packet); + switch (type) { + case ETH_P_ARP: + route_arp(source, packet); + break; + + case ETH_P_IP: + route_ipv4(source, packet); + break; + + case ETH_P_IPV6: + route_ipv6(source, packet); + break; + + default: + ifdebug(TRAFFIC) logger(LOG_WARNING, "Cannot route packet from %s (%s): unknown type %hx", source->name, source->hostname, type); + break; + } + } break; - case ETH_P_IP: - route_ipv4(source, packet); + case RMODE_SWITCH: + route_mac(source, packet); break; - case ETH_P_IPV6: - route_ipv6(source, packet); + case RMODE_HUB: + broadcast_packet(source, packet); break; - - default: - ifdebug(TRAFFIC) logger(LOG_WARNING, "Cannot route packet from %s (%s): unknown type %hx", source->name, source->hostname, type); - break; - } - } - break; - - case RMODE_SWITCH: - route_mac(source, packet); - break; - - case RMODE_HUB: - route_broadcast(source, packet); - break; } } diff --git a/src/route.h b/src/route.h index 5b9e808..5af2a09 100644 --- a/src/route.h +++ b/src/route.h @@ -1,10 +1,7 @@ -#ifndef TINC_ROUTE_H -#define TINC_ROUTE_H - /* route.h -- header file for route.c Copyright (C) 2000-2005 Ivo Timmermans - 2000-2012 Guus Sliepen + 2000-2006 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 @@ -21,6 +18,9 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +#ifndef __TINC_ROUTE_H__ +#define __TINC_ROUTE_H__ + #include "net.h" #include "node.h" @@ -36,24 +36,16 @@ typedef enum fmode_t { FMODE_KERNEL, } fmode_t; -typedef enum bmode_t { - BMODE_NONE = 0, - BMODE_MST, - BMODE_DIRECT, -} bmode_t; - extern rmode_t routing_mode; extern fmode_t forwarding_mode; -extern bmode_t broadcast_mode; -extern bool decrement_ttl; extern bool directonly; extern bool overwrite_mac; extern bool priorityinheritance; extern int macexpire; +extern bool pcap; extern mac_t mymac; -extern void age_subnets(void); -extern void route(struct node_t *source, struct vpn_packet_t *packet); +extern void route(struct node_t *, struct vpn_packet_t *); -#endif +#endif /* __TINC_ROUTE_H__ */ diff --git a/src/solaris/device.c b/src/solaris/device.c index fa2e6e6..eac267a 100644 --- a/src/solaris/device.c +++ b/src/solaris/device.c @@ -1,8 +1,7 @@ /* device.c -- Interaction with Solaris tun device Copyright (C) 2001-2005 Ivo Timmermans, - 2002-2010 OpenVPN Technologies, Inc. - 2001-2017 Guus Sliepen + 2001-2011 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 @@ -20,299 +19,94 @@ */ -#include "../system.h" +#include "system.h" #include #include -#include +#include -#include "../conf.h" -#include "../device.h" -#include "../logger.h" -#include "../net.h" -#include "../route.h" -#include "../utils.h" -#include "../xalloc.h" +#include "conf.h" +#include "device.h" +#include "logger.h" +#include "net.h" +#include "utils.h" +#include "xalloc.h" -#ifndef TUNNEWPPA -#warning Missing net/if_tun.h, using hardcoded value for TUNNEWPPA -#define TUNNEWPPA (('T'<<16) | 0x0001) -#endif - -#define DEFAULT_TUN_DEVICE "/dev/tun" -#define DEFAULT_TAP_DEVICE "/dev/tap" -#define IP_DEVICE "/dev/udp" - -static enum { - DEVICE_TYPE_TUN, - DEVICE_TYPE_TAP, -} device_type = DEVICE_TYPE_TUN; +#define DEFAULT_DEVICE "/dev/tun" int device_fd = -1; -static int if_fd = -1; -static int ip_fd = -1; +int ip_fd = -1, if_fd = -1; char *device = NULL; char *iface = NULL; -static const char *device_info = NULL; +static char *device_info = NULL; -uint64_t device_total_in = 0; -uint64_t device_total_out = 0; +static uint64_t device_total_in = 0; +static uint64_t device_total_out = 0; -static bool setup_device(void) { - char *type; +bool setup_device(void) { + int ppa; + char *ptr; - if(!get_config_string(lookup_config(config_tree, "Device"), &device)) { - if(routing_mode == RMODE_ROUTER) { - device = xstrdup(DEFAULT_TUN_DEVICE); - } else { - device = xstrdup(DEFAULT_TAP_DEVICE); - } - } + if(!get_config_string(lookup_config(config_tree, "Device"), &device)) + device = xstrdup(DEFAULT_DEVICE); - if(get_config_string(lookup_config(config_tree, "DeviceType"), &type)) { - if(!strcasecmp(type, "tun")) - /* use default */; - else if(!strcasecmp(type, "tap")) { - device_type = DEVICE_TYPE_TAP; - } else { - logger(LOG_ERR, "Unknown device type %s!", type); - return false; - } - } else { - if(strstr(device, "tap") || routing_mode != RMODE_ROUTER) { - device_type = DEVICE_TYPE_TAP; - } - } - - if(device_type == DEVICE_TYPE_TUN) { - device_info = "Solaris tun device"; - } else { - device_info = "Solaris tap device"; - } - - if(device_type == DEVICE_TYPE_TAP && routing_mode == RMODE_ROUTER) { - overwrite_mac = true; - } - - /* The following is black magic copied from OpenVPN. */ - - if((ip_fd = open(IP_DEVICE, O_RDWR, 0)) < 0) { - logger(LOG_ERR, "Could not open %s: %s\n", IP_DEVICE, strerror(errno)); + if((device_fd = open(device, O_RDWR | O_NONBLOCK)) < 0) { + logger(LOG_ERR, "Could not open %s: %s", device, strerror(errno)); return false; } - if((device_fd = open(device, O_RDWR, 0)) < 0) { - logger(LOG_ERR, "Could not open %s: %s\n", device, strerror(errno)); - return false; - } + ppa = 0; - /* Get unit number. */ - - char *ptr = device; - get_config_string(lookup_config(config_tree, "Interface"), &ptr); - - while(*ptr && !isdigit(*ptr)) { + ptr = device; + while(*ptr && !isdigit((int) *ptr)) ptr++; - } + ppa = atoi(ptr); - int ppa = atoi(ptr); + if((ip_fd = open("/dev/ip", O_RDWR, 0)) < 0) { + logger(LOG_ERR, "Could not open /dev/ip: %s", strerror(errno)); + return false; + } /* Assign a new PPA and get its unit number. */ - - struct strioctl strioc_ppa = { - .ic_cmd = TUNNEWPPA, - .ic_len = sizeof(ppa), - .ic_dp = (char *) &ppa, - }; - - if(!*ptr) { /* no number given, try dynamic */ - bool found = false; - - while(!found && ppa < 64) { - int new_ppa = ioctl(device_fd, I_STR, &strioc_ppa); - - if(new_ppa >= 0) { - ppa = new_ppa; - found = true; - break; - } - - ppa++; - } - - if(!found) { - logger(LOG_ERR, "Could not find free PPA for %s %s!", device_info, device); - return false; - } - } else { /* try this particular one */ - if((ppa = ioctl(device_fd, I_STR, &strioc_ppa)) < 0) { - logger(LOG_ERR, "Could not assign PPA %d for %s %s!", ppa, device_info, device); - return false; - } + if((ppa = ioctl(device_fd, TUNNEWPPA, ppa)) < 0) { + logger(LOG_ERR, "Can't assign new interface: %s", strerror(errno)); + return false; } if((if_fd = open(device, O_RDWR, 0)) < 0) { - logger(LOG_ERR, "Could not open %s: %s\n", device, strerror(errno)); + logger(LOG_ERR, "Could not open %s twice: %s", device, + strerror(errno)); return false; } if(ioctl(if_fd, I_PUSH, "ip") < 0) { - logger(LOG_ERR, "Could not push IP module onto %s %s!", device_info, device); + logger(LOG_ERR, "Can't push IP module: %s", strerror(errno)); return false; } - xasprintf(&iface, "%s%d", device_type == DEVICE_TYPE_TUN ? "tun" : "tap", ppa); - - { - /* Remove muxes just in case they are left over from a crashed tincd */ - struct lifreq ifr = {}; - strncpy(ifr.lifr_name, iface, sizeof(ifr.lifr_name)); - - if(ioctl(ip_fd, SIOCGLIFMUXID, &ifr) >= 0) { - int muxid = ifr.lifr_arp_muxid; - ioctl(ip_fd, I_PUNLINK, muxid); - muxid = ifr.lifr_ip_muxid; - ioctl(ip_fd, I_PUNLINK, muxid); - } - } - - if(device_type == DEVICE_TYPE_TUN) { - /* Assign ppa according to the unit number returned by tun device */ - if(ioctl(if_fd, IF_UNITSEL, (char *)&ppa) < 0) { - logger(LOG_ERR, "Could not set PPA %d on %s %s!", ppa, device_info, device); - return false; - } - } - - int arp_fd = -1; - - if(device_type == DEVICE_TYPE_TAP) { - struct lifreq ifr = {}; - - if(ioctl(if_fd, SIOCGLIFFLAGS, &ifr) < 0) { - logger(LOG_ERR, "Could not set flags on %s %s!", device_info, device); - return false; - } - - strncpy(ifr.lifr_name, iface, sizeof(ifr.lifr_name)); - ifr.lifr_ppa = ppa; - - /* Assign ppa according to the unit number returned by tun device */ - if(ioctl(if_fd, SIOCSLIFNAME, &ifr) < 0) { - logger(LOG_ERR, "Could not set PPA %d on %s %s!", ppa, device_info, device); - return false; - } - - if(ioctl(if_fd, SIOCGLIFFLAGS, &ifr) < 0) { - logger(LOG_ERR, "Could not set flags on %s %s!", device_info, device); - return false; - } - - /* Push arp module to if_fd */ - if(ioctl(if_fd, I_PUSH, "arp") < 0) { - logger(LOG_ERR, "Could not push ARP module onto %s %s!", device_info, device); - return false; - } - - /* Pop any modules on the stream */ - while(true) { - if(ioctl(ip_fd, I_POP, NULL) < 0) { - break; - } - } - - /* Push arp module to ip_fd */ - if(ioctl(ip_fd, I_PUSH, "arp") < 0) { - logger(LOG_ERR, "Could not push ARP module onto %s!", IP_DEVICE); - return false; - } - - /* Open arp_fd */ - if((arp_fd = open(device, O_RDWR, 0)) < 0) { - logger(LOG_ERR, "Could not open %s: %s\n", device, strerror(errno)); - return false; - } - - /* Push arp module to arp_fd */ - if(ioctl(arp_fd, I_PUSH, "arp") < 0) { - logger(LOG_ERR, "Could not push ARP module onto %s %s!", device_info, device); - return false; - } - - /* Set ifname to arp */ - struct strioctl strioc_if = { - .ic_cmd = SIOCSLIFNAME, - .ic_len = sizeof(ifr), - .ic_dp = (char *) &ifr, - }; - - if(ioctl(arp_fd, I_STR, &strioc_if) < 0) { - logger(LOG_ERR, "Could not set ifname to %s %s", device_info, device); - return false; - } - } - - int ip_muxid, arp_muxid; - - if((ip_muxid = ioctl(ip_fd, I_PLINK, if_fd)) < 0) { - logger(LOG_ERR, "Could not link %s %s to IP", device_info, device); + /* Assign ppa according to the unit number returned by tun device */ + if(ioctl(if_fd, IF_UNITSEL, (char *) &ppa) < 0) { + logger(LOG_ERR, "Can't set PPA %d: %s", ppa, strerror(errno)); return false; } - if(device_type == DEVICE_TYPE_TAP) { - if((arp_muxid = ioctl(ip_fd, I_PLINK, arp_fd)) < 0) { - logger(LOG_ERR, "Could not link %s %s to ARP", device_info, device); - return false; - } - - close(arp_fd); - } - - struct lifreq ifr = {}; - - strncpy(ifr.lifr_name, iface, sizeof(ifr.lifr_name)); - - ifr.lifr_ip_muxid = ip_muxid; - - if(device_type == DEVICE_TYPE_TAP) { - ifr.lifr_arp_muxid = arp_muxid; - } - - if(ioctl(ip_fd, SIOCSLIFMUXID, &ifr) < 0) { - if(device_type == DEVICE_TYPE_TAP) { - ioctl(ip_fd, I_PUNLINK, arp_muxid); - } - - ioctl(ip_fd, I_PUNLINK, ip_muxid); - logger(LOG_ERR, "Could not set multiplexor id for %s %s", device_info, device); + if(ioctl(ip_fd, I_LINK, if_fd) < 0) { + logger(LOG_ERR, "Can't link TUN device to IP: %s", strerror(errno)); return false; } - close(if_fd); + if(!get_config_string(lookup_config(config_tree, "Interface"), &iface)) + xasprintf(&iface, "tun%d", ppa); -#ifdef FD_CLOEXEC - fcntl(device_fd, F_SETFD, FD_CLOEXEC); - fcntl(ip_fd, F_SETFD, FD_CLOEXEC); -#endif + device_info = "Solaris tun device"; logger(LOG_INFO, "%s is a %s", device, device_info); return true; } -static void close_device(void) { - if(iface) { - struct lifreq ifr = {}; - strncpy(ifr.lifr_name, iface, sizeof(ifr.lifr_name)); - - if(ioctl(ip_fd, SIOCGLIFMUXID, &ifr) >= 0) { - int muxid = ifr.lifr_arp_muxid; - ioctl(ip_fd, I_PUNLINK, muxid); - muxid = ifr.lifr_ip_muxid; - ioctl(ip_fd, I_PUNLINK, muxid); - } - } - +void close_device(void) { + close(if_fd); close(ip_fd); close(device_fd); @@ -320,94 +114,49 @@ static void close_device(void) { free(iface); } -static bool read_packet(vpn_packet_t *packet) { - int result; - struct strbuf sbuf; - int f = 0; +bool read_packet(vpn_packet_t *packet) { + int inlen; - switch(device_type) { - case DEVICE_TYPE_TUN: - sbuf.maxlen = MTU - 14; - sbuf.buf = (char *)packet->data + 14; + if((inlen = read(device_fd, packet->data + 14, MTU - 14)) <= 0) { + logger(LOG_ERR, "Error while reading from %s %s: %s", device_info, + device, strerror(errno)); + return false; + } - if((result = getmsg(device_fd, NULL, &sbuf, &f)) < 0) { - logger(LOG_ERR, "Error while reading from %s %s: %s", device_info, device, strerror(errno)); - return false; - } - - switch(packet->data[14] >> 4) { + switch(packet->data[14] >> 4) { case 4: packet->data[12] = 0x08; packet->data[13] = 0x00; break; - case 6: packet->data[12] = 0x86; packet->data[13] = 0xDD; break; - default: - ifdebug(TRAFFIC) logger(LOG_ERR, "Unknown IP version %d while reading packet from %s %s", packet->data[14] >> 4, device_info, device); + ifdebug(TRAFFIC) logger(LOG_ERR, + "Unknown IP version %d while reading packet from %s %s", + packet->data[14] >> 4, device_info, device); return false; - } - - memset(packet->data, 0, 12); - packet->len = sbuf.len + 14; - break; - - case DEVICE_TYPE_TAP: - sbuf.maxlen = MTU; - sbuf.buf = (char *)packet->data; - - if((result = getmsg(device_fd, NULL, &sbuf, &f)) < 0) { - logger(LOG_ERR, "Error while reading from %s %s: %s", device_info, device, strerror(errno)); - return false; - } - - packet->len = sbuf.len; - break; - - default: - abort(); } + packet->len = inlen + 14; + device_total_in += packet->len; - ifdebug(TRAFFIC) logger(LOG_DEBUG, "Read packet of %d bytes from %s", packet->len, device_info); + ifdebug(TRAFFIC) logger(LOG_DEBUG, "Read packet of %d bytes from %s", packet->len, + device_info); return true; } -static bool write_packet(vpn_packet_t *packet) { - ifdebug(TRAFFIC) logger(LOG_DEBUG, "Writing packet of %d bytes to %s", packet->len, device_info); +bool write_packet(vpn_packet_t *packet) { + ifdebug(TRAFFIC) logger(LOG_DEBUG, "Writing packet of %d bytes to %s", + packet->len, device_info); - struct strbuf sbuf; - - switch(device_type) { - case DEVICE_TYPE_TUN: - sbuf.len = packet->len - 14; - sbuf.buf = (char *)packet->data + 14; - - if(putmsg(device_fd, NULL, &sbuf, 0) < 0) { - logger(LOG_ERR, "Can't write to %s %s: %s", device_info, device, strerror(errno)); - return false; - } - - break; - - case DEVICE_TYPE_TAP: - sbuf.len = packet->len; - sbuf.buf = (char *)packet->data; - - if(putmsg(device_fd, NULL, &sbuf, 0) < 0) { - logger(LOG_ERR, "Can't write to %s %s: %s", device_info, device, strerror(errno)); - return false; - } - - break; - - default: - abort(); + if(write(device_fd, packet->data + 14, packet->len - 14) < 0) { + logger(LOG_ERR, "Can't write to %s %s: %s", device_info, + device, strerror(errno)); + return false; } device_total_out += packet->len; @@ -415,16 +164,8 @@ static bool write_packet(vpn_packet_t *packet) { return true; } -static void dump_device_stats(void) { +void dump_device_stats(void) { logger(LOG_DEBUG, "Statistics for %s %s:", device_info, device); logger(LOG_DEBUG, " total bytes in: %10"PRIu64, device_total_in); logger(LOG_DEBUG, " total bytes out: %10"PRIu64, device_total_out); } - -const devops_t os_devops = { - .setup = setup_device, - .close = close_device, - .read = read_packet, - .write = write_packet, - .dump_stats = dump_device_stats, -}; diff --git a/src/splay_tree.c b/src/splay_tree.c new file mode 100644 index 0000000..135ba06 --- /dev/null +++ b/src/splay_tree.c @@ -0,0 +1,561 @@ +/* + splay_tree.c -- splay tree and linked list convenience + Copyright (C) 2004-2006 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "system.h" + +#include "splay_tree.h" +#include "xalloc.h" + +/* Splay operation */ + +static splay_node_t *splay_top_down(splay_tree_t *tree, const void *data, int *result) { + splay_node_t left = {NULL}, right = {NULL}; + splay_node_t *leftbottom = &left, *rightbottom = &right, *child, *grandchild; + splay_node_t *root = tree->root; + int c; + + if(!root) { + if(result) + *result = 0; + return NULL; + } + + while((c = tree->compare(data, root->data))) { + if(c < 0 && (child = root->left)) { + c = tree->compare(data, child->data); + + if(c < 0 && (grandchild = child->left)) { + rightbottom->left = child; + child->parent = rightbottom; + rightbottom = child; + + if((root->left = child->right)) + child->right->parent = root; + + child->right = root; + root->parent = child; + + child->left = NULL; + grandchild->parent = NULL; + + root = grandchild; + } else if (c > 0 && (grandchild = child->right)) { + leftbottom->right = child; + child->parent = leftbottom; + leftbottom = child; + + child->right = NULL; + grandchild->parent = NULL; + + rightbottom->left = root; + root->parent = rightbottom; + rightbottom = root; + + root->left = NULL; + + root = grandchild; + } else { + rightbottom->left = root; + root->parent = rightbottom; + rightbottom = root; + + root->left = NULL; + child->parent = NULL; + + root = child; + break; + } + } else if(c > 0 && (child = root->right)) { + c = tree->compare(data, child->data); + + if(c > 0 && (grandchild = child->right)) { + leftbottom->right = child; + child->parent = leftbottom; + leftbottom = child; + + if((root->right = child->left)) + child->left->parent = root; + + child->left = root; + root->parent = child; + + child->right = NULL; + grandchild->parent = NULL; + + root = grandchild; + } else if (c < 0 && (grandchild = child->left)) { + rightbottom->left = child; + child->parent = rightbottom; + rightbottom = child; + + child->left = NULL; + grandchild->parent = NULL; + + leftbottom->right = root; + root->parent = leftbottom; + leftbottom = root; + + root->right = NULL; + + root = grandchild; + } else { + leftbottom->right = root; + root->parent = leftbottom; + leftbottom = root; + + root->right = NULL; + child->parent = NULL; + + root = child; + break; + } + } else { + break; + } + } + + /* Merge trees */ + + if(left.right) { + if(root->left) { + leftbottom->right = root->left; + root->left->parent = leftbottom; + } + root->left = left.right; + left.right->parent = root; + } + + if(right.left) { + if(root->right) { + rightbottom->left = root->right; + root->right->parent = rightbottom; + } + root->right = right.left; + right.left->parent = root; + } + + /* Return result */ + + tree->root = root; + if(result) + *result = c; + + return tree->root; +} + +static void splay_bottom_up(splay_tree_t *tree, splay_node_t *node) { + splay_node_t *parent, *grandparent, *greatgrandparent; + + while((parent = node->parent)) { + if(!(grandparent = parent->parent)) { /* zig */ + if(node == parent->left) { + if((parent->left = node->right)) + parent->left->parent = parent; + node->right = parent; + } else { + if((parent->right = node->left)) + parent->right->parent = parent; + node->left = parent; + } + + parent->parent = node; + node->parent = NULL; + } else { + greatgrandparent = grandparent->parent; + + if(node == parent->left && parent == grandparent->left) { /* left zig-zig */ + if((grandparent->left = parent->right)) + grandparent->left->parent = grandparent; + parent->right = grandparent; + grandparent->parent = parent; + + if((parent->left = node->right)) + parent->left->parent = parent; + node->right = parent; + parent->parent = node; + } else if(node == parent->right && parent == grandparent->right) { /* right zig-zig */ + if((grandparent->right = parent->left)) + grandparent->right->parent = grandparent; + parent->left = grandparent; + grandparent->parent = parent; + + if((parent->right = node->left)) + parent->right->parent = parent; + node->left = parent; + parent->parent = node; + } else if(node == parent->right && parent == grandparent->left) { /* left-right zig-zag */ + if((parent->right = node->left)) + parent->right->parent = parent; + node->left = parent; + parent->parent = node; + + if((grandparent->left = node->right)) + grandparent->left->parent = grandparent; + node->right = grandparent; + grandparent->parent = node; + } else { /* right-left zig-zag */ + if((parent->left = node->right)) + parent->left->parent = parent; + node->right = parent; + parent->parent = node; + + if((grandparent->right = node->left)) + grandparent->right->parent = grandparent; + node->left = grandparent; + grandparent->parent = node; + } + + if((node->parent = greatgrandparent)) { + if(grandparent == greatgrandparent->left) + greatgrandparent->left = node; + else + greatgrandparent->right = node; + } + } + } + + tree->root = node; +} + +/* (De)constructors */ + +splay_tree_t *splay_alloc_tree(splay_compare_t compare, splay_action_t delete) { + splay_tree_t *tree; + + tree = xmalloc_and_zero(sizeof(splay_tree_t)); + tree->compare = compare; + tree->delete = delete; + + return tree; +} + +void splay_free_tree(splay_tree_t *tree) { + free(tree); +} + +splay_node_t *splay_alloc_node(void) { + return xmalloc_and_zero(sizeof(splay_node_t)); +} + +void splay_free_node(splay_tree_t *tree, splay_node_t *node) { + if(node->data && tree->delete) + tree->delete(node->data); + + free(node); +} + +/* Searching */ + +void *splay_search(splay_tree_t *tree, const void *data) { + splay_node_t *node; + + node = splay_search_node(tree, data); + + return node ? node->data : NULL; +} + +void *splay_search_closest(splay_tree_t *tree, const void *data, int *result) { + splay_node_t *node; + + node = splay_search_closest_node(tree, data, result); + + return node ? node->data : NULL; +} + +void *splay_search_closest_smaller(splay_tree_t *tree, const void *data) { + splay_node_t *node; + + node = splay_search_closest_smaller_node(tree, data); + + return node ? node->data : NULL; +} + +void *splay_search_closest_greater(splay_tree_t *tree, const void *data) { + splay_node_t *node; + + node = splay_search_closest_greater_node(tree, data); + + return node ? node->data : NULL; +} + +splay_node_t *splay_search_node(splay_tree_t *tree, const void *data) { + splay_node_t *node; + int result; + + node = splay_search_closest_node(tree, data, &result); + + return result ? NULL : node; +} + +splay_node_t *splay_search_closest_node_nosplay(const splay_tree_t *tree, const void *data, int *result) { + splay_node_t *node; + int c; + + node = tree->root; + + if(!node) { + if(result) + *result = 0; + return NULL; + } + + for(;;) { + c = tree->compare(data, node->data); + + if(c < 0) { + if(node->left) + node = node->left; + else + break; + } else if(c > 0) { + if(node->right) + node = node->right; + else + break; + } else { + break; + } + } + + if(result) + *result = c; + return node; +} + +splay_node_t *splay_search_closest_node(splay_tree_t *tree, const void *data, int *result) { + return splay_top_down(tree, data, result); +} + +splay_node_t *splay_search_closest_smaller_node(splay_tree_t *tree, const void *data) { + splay_node_t *node; + int result; + + node = splay_search_closest_node(tree, data, &result); + + if(result < 0) + node = node->prev; + + return node; +} + +splay_node_t *splay_search_closest_greater_node(splay_tree_t *tree, const void *data) { + splay_node_t *node; + int result; + + node = splay_search_closest_node(tree, data, &result); + + if(result > 0) + node = node->next; + + return node; +} + +/* Insertion and deletion */ + +splay_node_t *splay_insert(splay_tree_t *tree, void *data) { + splay_node_t *closest, *new; + int result; + + if(!tree->root) { + new = splay_alloc_node(); + new->data = data; + splay_insert_top(tree, new); + } else { + closest = splay_search_closest_node(tree, data, &result); + + if(!result) + return NULL; + + new = splay_alloc_node(); + new->data = data; + + if(result < 0) + splay_insert_before(tree, closest, new); + else + splay_insert_after(tree, closest, new); + } + + return new; +} + +splay_node_t *splay_insert_node(splay_tree_t *tree, splay_node_t *node) { + splay_node_t *closest; + int result; + + if(!tree->root) + splay_insert_top(tree, node); + else { + closest = splay_search_closest_node(tree, node->data, &result); + + if(!result) + return NULL; + + if(result < 0) + splay_insert_before(tree, closest, node); + else + splay_insert_after(tree, closest, node); + } + + return node; +} + +void splay_insert_top(splay_tree_t *tree, splay_node_t *node) { + node->prev = node->next = node->left = node->right = node->parent = NULL; + tree->head = tree->tail = tree->root = node; +} + +void splay_insert_before(splay_tree_t *tree, splay_node_t *before, splay_node_t *node) { + if(!before) { + if(tree->tail) + splay_insert_after(tree, tree->tail, node); + else + splay_insert_top(tree, node); + return; + } + + node->next = before; + if((node->prev = before->prev)) + before->prev->next = node; + else + tree->head = node; + before->prev = node; + + splay_bottom_up(tree, before); + + node->right = before; + before->parent = node; + if((node->left = before->left)) + before->left->parent = node; + before->left = NULL; + + node->parent = NULL; + tree->root = node; +} + +void splay_insert_after(splay_tree_t *tree, splay_node_t *after, splay_node_t *node) { + if(!after) { + if(tree->head) + splay_insert_before(tree, tree->head, node); + else + splay_insert_top(tree, node); + return; + } + + node->prev = after; + if((node->next = after->next)) + after->next->prev = node; + else + tree->tail = node; + after->next = node; + + splay_bottom_up(tree, after); + + node->left = after; + after->parent = node; + if((node->right = after->right)) + after->right->parent = node; + after->right = NULL; + + node->parent = NULL; + tree->root = node; +} + +splay_node_t *splay_unlink(splay_tree_t *tree, void *data) { + splay_node_t *node; + + node = splay_search_node(tree, data); + + if(node) + splay_unlink_node(tree, node); + + return node; +} + +void splay_unlink_node(splay_tree_t *tree, splay_node_t *node) { + if(node->prev) + node->prev->next = node->next; + else + tree->head = node->next; + + if(node->next) + node->next->prev = node->prev; + else + tree->tail = node->prev; + + splay_bottom_up(tree, node); + + if(node->prev) { + node->left->parent = NULL; + tree->root = node->left; + if((node->prev->right = node->right)) + node->right->parent = node->prev; + } else if(node->next) { + tree->root = node->right; + node->right->parent = NULL; + } else { + tree->root = NULL; + } +} + +void splay_delete_node(splay_tree_t *tree, splay_node_t *node) { + splay_unlink_node(tree, node); + splay_free_node(tree, node); +} + +void splay_delete(splay_tree_t *tree, void *data) { + splay_node_t *node; + + node = splay_search_node(tree, data); + + if(node) + splay_delete_node(tree, node); +} + +/* Fast tree cleanup */ + +void splay_delete_tree(splay_tree_t *tree) { + splay_node_t *node, *next; + + for(node = tree->head; node; node = next) { + next = node->next; + splay_free_node(tree, node); + } + + splay_free_tree(tree); +} + +/* Tree walking */ + +void splay_foreach(const splay_tree_t *tree, splay_action_t action) { + splay_node_t *node, *next; + + for(node = tree->head; node; node = next) { + next = node->next; + action(node->data); + } +} + +void splay_foreach_node(const splay_tree_t *tree, splay_action_t action) { + splay_node_t *node, *next; + + for(node = tree->head; node; node = next) { + next = node->next; + action(node); + } +} diff --git a/src/splay_tree.h b/src/splay_tree.h new file mode 100644 index 0000000..e4af0c4 --- /dev/null +++ b/src/splay_tree.h @@ -0,0 +1,107 @@ +/* + splay_tree.h -- header file for splay_tree.c + Copyright (C) 2004-2006 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + + +#ifndef __SPLAY_TREE_H__ +#define __SPLAY_TREE_H__ + +typedef struct splay_node_t { + + /* Linked list part */ + + struct splay_node_t *next; + struct splay_node_t *prev; + + /* Tree part */ + + struct splay_node_t *parent; + struct splay_node_t *left; + struct splay_node_t *right; + + /* Payload */ + + void *data; + +} splay_node_t; + +typedef int (*splay_compare_t)(const void *, const void *); +typedef void (*splay_action_t)(const void *); +typedef void (*splay_action_node_t)(const splay_node_t *); + +typedef struct splay_tree_t { + + /* Linked list part */ + + splay_node_t *head; + splay_node_t *tail; + + /* Tree part */ + + splay_node_t *root; + + splay_compare_t compare; + splay_action_t delete; + +} splay_tree_t; + +/* (De)constructors */ + +extern splay_tree_t *splay_alloc_tree(splay_compare_t, splay_action_t); +extern void splay_free_tree(splay_tree_t *); + +extern splay_node_t *splay_alloc_node(void); +extern void splay_free_node(splay_tree_t *tree, splay_node_t *); + +/* Insertion and deletion */ + +extern splay_node_t *splay_insert(splay_tree_t *, void *); +extern splay_node_t *splay_insert_node(splay_tree_t *, splay_node_t *); + +extern void splay_insert_top(splay_tree_t *, splay_node_t *); +extern void splay_insert_before(splay_tree_t *, splay_node_t *, splay_node_t *); +extern void splay_insert_after(splay_tree_t *, splay_node_t *, splay_node_t *); + +extern splay_node_t *splay_unlink(splay_tree_t *, void *); +extern void splay_unlink_node(splay_tree_t *tree, splay_node_t *); +extern void splay_delete(splay_tree_t *, void *); +extern void splay_delete_node(splay_tree_t *, splay_node_t *); + +/* Fast tree cleanup */ + +extern void splay_delete_tree(splay_tree_t *); + +/* Searching */ + +extern void *splay_search(splay_tree_t *, const void *); +extern void *splay_search_closest(splay_tree_t *, const void *, int *); +extern void *splay_search_closest_smaller(splay_tree_t *, const void *); +extern void *splay_search_closest_greater(splay_tree_t *, const void *); + +extern splay_node_t *splay_search_node(splay_tree_t *, const void *); +extern splay_node_t *splay_search_closest_node(splay_tree_t *, const void *, int *); +extern splay_node_t *splay_search_closest_node_nosplay(const splay_tree_t *, const void *, int *); +extern splay_node_t *splay_search_closest_smaller_node(splay_tree_t *, const void *); +extern splay_node_t *splay_search_closest_greater_node(splay_tree_t *, const void *); + +/* Tree walking */ + +extern void splay_foreach(const splay_tree_t *, splay_action_t); +extern void splay_foreach_node(const splay_tree_t *, splay_action_t); + +#endif diff --git a/src/subnet.c b/src/subnet.c index dc30b01..bf1bda2 100644 --- a/src/subnet.c +++ b/src/subnet.c @@ -1,6 +1,6 @@ /* subnet.c -- handle subnet lookups and lists - Copyright (C) 2000-2014 Guus Sliepen , + Copyright (C) 2000-2010 Guus Sliepen , 2000-2005 Ivo Timmermans This program is free software; you can redistribute it and/or modify @@ -20,7 +20,8 @@ #include "system.h" -#include "avl_tree.h" +#include "splay_tree.h" +#include "control_common.h" #include "device.h" #include "logger.h" #include "net.h" @@ -33,7 +34,7 @@ /* lists type of subnet */ -avl_tree_t *subnet_tree; +splay_tree_t *subnet_tree; /* Subnet lookup cache */ @@ -63,17 +64,15 @@ void subnet_cache_flush(void) { static int subnet_compare_mac(const subnet_t *a, const subnet_t *b) { int result; - result = memcmp(&a->net.mac.address, &b->net.mac.address, sizeof(mac_t)); + result = memcmp(&a->net.mac.address, &b->net.mac.address, sizeof a->net.mac.address); - if(result) { + if(result) return result; - } - + result = a->weight - b->weight; - if(result || !a->owner || !b->owner) { + if(result || !a->owner || !b->owner) return result; - } return strcmp(a->owner->name, b->owner->name); } @@ -83,21 +82,18 @@ static int subnet_compare_ipv4(const subnet_t *a, const subnet_t *b) { result = b->net.ipv4.prefixlength - a->net.ipv4.prefixlength; - if(result) { + if(result) return result; - } result = memcmp(&a->net.ipv4.address, &b->net.ipv4.address, sizeof(ipv4_t)); - if(result) { + if(result) return result; - } - + result = a->weight - b->weight; - if(result || !a->owner || !b->owner) { + if(result || !a->owner || !b->owner) return result; - } return strcmp(a->owner->name, b->owner->name); } @@ -107,21 +103,18 @@ static int subnet_compare_ipv6(const subnet_t *a, const subnet_t *b) { result = b->net.ipv6.prefixlength - a->net.ipv6.prefixlength; - if(result) { + if(result) return result; - } - + result = memcmp(&a->net.ipv6.address, &b->net.ipv6.address, sizeof(ipv6_t)); - if(result) { + if(result) return result; - } - + result = a->weight - b->weight; - if(result || !a->owner || !b->owner) { + if(result || !a->owner || !b->owner) return result; - } return strcmp(a->owner->name, b->owner->name); } @@ -131,23 +124,19 @@ int subnet_compare(const subnet_t *a, const subnet_t *b) { result = a->type - b->type; - if(result) { + if(result) return result; - } - switch(a->type) { + switch (a->type) { case SUBNET_MAC: return subnet_compare_mac(a, b); - case SUBNET_IPV4: return subnet_compare_ipv4(a, b); - case SUBNET_IPV6: return subnet_compare_ipv6(a, b); - default: logger(LOG_ERR, "subnet_compare() was called with unknown subnet type %d, exitting!", - a->type); + a->type); exit(0); } @@ -157,21 +146,21 @@ int subnet_compare(const subnet_t *a, const subnet_t *b) { /* Initialising trees */ void init_subnets(void) { - subnet_tree = avl_alloc_tree((avl_compare_t) subnet_compare, (avl_action_t) free_subnet); + subnet_tree = splay_alloc_tree((splay_compare_t) subnet_compare, (splay_action_t) free_subnet); subnet_cache_flush(); } void exit_subnets(void) { - avl_delete_tree(subnet_tree); + splay_delete_tree(subnet_tree); } -avl_tree_t *new_subnet_tree(void) { - return avl_alloc_tree((avl_compare_t) subnet_compare, NULL); +splay_tree_t *new_subnet_tree(void) { + return splay_alloc_tree((splay_compare_t) subnet_compare, NULL); } -void free_subnet_tree(avl_tree_t *subnet_tree) { - avl_delete_tree(subnet_tree); +void free_subnet_tree(splay_tree_t *subnet_tree) { + splay_delete_tree(subnet_tree); } /* Allocating and freeing space for subnets */ @@ -189,15 +178,15 @@ void free_subnet(subnet_t *subnet) { void subnet_add(node_t *n, subnet_t *subnet) { subnet->owner = n; - avl_insert(subnet_tree, subnet); - avl_insert(n->subnet_tree, subnet); + splay_insert(subnet_tree, subnet); + splay_insert(n->subnet_tree, subnet); subnet_cache_flush(); } void subnet_del(node_t *n, subnet_t *subnet) { - avl_delete(n->subnet_tree, subnet); - avl_delete(subnet_tree, subnet); + splay_delete(n->subnet_tree, subnet); + splay_delete(subnet_tree, subnet); subnet_cache_flush(); } @@ -210,20 +199,17 @@ bool str2net(subnet_t *subnet, const char *subnetstr) { int weight = 10; if(sscanf(subnetstr, "%hu.%hu.%hu.%hu/%d#%d", - &x[0], &x[1], &x[2], &x[3], &l, &weight) >= 5) { - if(l < 0 || l > 32) { + &x[0], &x[1], &x[2], &x[3], &l, &weight) >= 5) { + if(l < 0 || l > 32) return false; - } subnet->type = SUBNET_IPV4; subnet->net.ipv4.prefixlength = l; subnet->weight = weight; for(i = 0; i < 4; i++) { - if(x[i] > 255) { + if(x[i] > 255) return false; - } - subnet->net.ipv4.address.x[i] = x[i]; } @@ -231,19 +217,17 @@ bool str2net(subnet_t *subnet, const char *subnetstr) { } if(sscanf(subnetstr, "%hx:%hx:%hx:%hx:%hx:%hx:%hx:%hx/%d#%d", - &x[0], &x[1], &x[2], &x[3], &x[4], &x[5], &x[6], &x[7], - &l, &weight) >= 9) { - if(l < 0 || l > 128) { + &x[0], &x[1], &x[2], &x[3], &x[4], &x[5], &x[6], &x[7], + &l, &weight) >= 9) { + if(l < 0 || l > 128) return false; - } subnet->type = SUBNET_IPV6; subnet->net.ipv6.prefixlength = l; subnet->weight = weight; - for(i = 0; i < 8; i++) { + for(i = 0; i < 8; i++) subnet->net.ipv6.address.x[i] = htons(x[i]); - } return true; } @@ -254,10 +238,8 @@ bool str2net(subnet_t *subnet, const char *subnetstr) { subnet->weight = weight; for(i = 0; i < 4; i++) { - if(x[i] > 255) { + if(x[i] > 255) return false; - } - subnet->net.ipv4.address.x[i] = x[i]; } @@ -265,119 +247,24 @@ bool str2net(subnet_t *subnet, const char *subnetstr) { } if(sscanf(subnetstr, "%hx:%hx:%hx:%hx:%hx:%hx:%hx:%hx#%d", - &x[0], &x[1], &x[2], &x[3], &x[4], &x[5], &x[6], &x[7], &weight) >= 8) { + &x[0], &x[1], &x[2], &x[3], &x[4], &x[5], &x[6], &x[7], &weight) >= 8) { subnet->type = SUBNET_IPV6; subnet->net.ipv6.prefixlength = 128; subnet->weight = weight; - for(i = 0; i < 8; i++) { + for(i = 0; i < 8; i++) subnet->net.ipv6.address.x[i] = htons(x[i]); - } return true; } if(sscanf(subnetstr, "%hx:%hx:%hx:%hx:%hx:%hx#%d", - &x[0], &x[1], &x[2], &x[3], &x[4], &x[5], &weight) >= 6) { + &x[0], &x[1], &x[2], &x[3], &x[4], &x[5], &weight) >= 6) { subnet->type = SUBNET_MAC; subnet->weight = weight; - for(i = 0; i < 6; i++) { + for(i = 0; i < 6; i++) subnet->net.mac.address.x[i] = x[i]; - } - - return true; - } - - // IPv6 short form - if(strstr(subnetstr, "::")) { - const char *p; - char *q; - int colons = 0; - - // Count number of colons - for(p = subnetstr; *p; p++) - if(*p == ':') { - colons++; - } - - if(colons > 7) { - return false; - } - - // Scan numbers before the double colon - p = subnetstr; - - for(i = 0; i < colons; i++) { - if(*p == ':') { - break; - } - - x[i] = strtoul(p, &q, 0x10); - - if(!q || p == q || *q != ':') { - return false; - } - - p = ++q; - } - - p++; - colons -= i; - - if(!i) { - p++; - colons--; - } - - if(!*p || *p == '/' || *p == '#') { - colons--; - } - - // Fill in the blanks - for(; i < 8 - colons; i++) { - x[i] = 0; - } - - // Scan the remaining numbers - for(; i < 8; i++) { - x[i] = strtoul(p, &q, 0x10); - - if(!q || p == q) { - return false; - } - - if(i == 7) { - p = q; - break; - } - - if(*q != ':') { - return false; - } - - p = ++q; - } - - l = 128; - - if(*p == '/') { - sscanf(p, "/%d#%d", &l, &weight); - } else if(*p == '#') { - sscanf(p, "#%d", &weight); - } - - if(l < 0 || l > 128) { - return false; - } - - subnet->type = SUBNET_IPV6; - subnet->net.ipv6.prefixlength = l; - subnet->weight = weight; - - for(i = 0; i < 8; i++) { - subnet->net.ipv6.address.x[i] = htons(x[i]); - } return true; } @@ -387,51 +274,51 @@ bool str2net(subnet_t *subnet, const char *subnetstr) { bool net2str(char *netstr, int len, const subnet_t *subnet) { if(!netstr || !subnet) { - logger(LOG_ERR, "net2str() was called with netstr=%p, subnet=%p!", (void *)netstr, (void *)subnet); + logger(LOG_ERR, "net2str() was called with netstr=%p, subnet=%p!", netstr, subnet); return false; } - switch(subnet->type) { - case SUBNET_MAC: - snprintf(netstr, len, "%x:%x:%x:%x:%x:%x#%d", - subnet->net.mac.address.x[0], - subnet->net.mac.address.x[1], - subnet->net.mac.address.x[2], - subnet->net.mac.address.x[3], - subnet->net.mac.address.x[4], - subnet->net.mac.address.x[5], - subnet->weight); - break; + switch (subnet->type) { + case SUBNET_MAC: + snprintf(netstr, len, "%hx:%hx:%hx:%hx:%hx:%hx#%d", + subnet->net.mac.address.x[0], + subnet->net.mac.address.x[1], + subnet->net.mac.address.x[2], + subnet->net.mac.address.x[3], + subnet->net.mac.address.x[4], + subnet->net.mac.address.x[5], + subnet->weight); + break; - case SUBNET_IPV4: - snprintf(netstr, len, "%u.%u.%u.%u/%d#%d", - subnet->net.ipv4.address.x[0], - subnet->net.ipv4.address.x[1], - subnet->net.ipv4.address.x[2], - subnet->net.ipv4.address.x[3], - subnet->net.ipv4.prefixlength, - subnet->weight); - break; + case SUBNET_IPV4: + snprintf(netstr, len, "%hu.%hu.%hu.%hu/%d#%d", + subnet->net.ipv4.address.x[0], + subnet->net.ipv4.address.x[1], + subnet->net.ipv4.address.x[2], + subnet->net.ipv4.address.x[3], + subnet->net.ipv4.prefixlength, + subnet->weight); + break; - case SUBNET_IPV6: - snprintf(netstr, len, "%x:%x:%x:%x:%x:%x:%x:%x/%d#%d", - ntohs(subnet->net.ipv6.address.x[0]), - ntohs(subnet->net.ipv6.address.x[1]), - ntohs(subnet->net.ipv6.address.x[2]), - ntohs(subnet->net.ipv6.address.x[3]), - ntohs(subnet->net.ipv6.address.x[4]), - ntohs(subnet->net.ipv6.address.x[5]), - ntohs(subnet->net.ipv6.address.x[6]), - ntohs(subnet->net.ipv6.address.x[7]), - subnet->net.ipv6.prefixlength, - subnet->weight); - break; + case SUBNET_IPV6: + snprintf(netstr, len, "%hx:%hx:%hx:%hx:%hx:%hx:%hx:%hx/%d#%d", + ntohs(subnet->net.ipv6.address.x[0]), + ntohs(subnet->net.ipv6.address.x[1]), + ntohs(subnet->net.ipv6.address.x[2]), + ntohs(subnet->net.ipv6.address.x[3]), + ntohs(subnet->net.ipv6.address.x[4]), + ntohs(subnet->net.ipv6.address.x[5]), + ntohs(subnet->net.ipv6.address.x[6]), + ntohs(subnet->net.ipv6.address.x[7]), + subnet->net.ipv6.prefixlength, + subnet->weight); + break; - default: - logger(LOG_ERR, - "net2str() was called with unknown subnet type %d, exiting!", - subnet->type); - exit(0); + default: + logger(LOG_ERR, + "net2str() was called with unknown subnet type %d, exiting!", + subnet->type); + exit(0); } return true; @@ -440,52 +327,44 @@ bool net2str(char *netstr, int len, const subnet_t *subnet) { /* Subnet lookup routines */ subnet_t *lookup_subnet(const node_t *owner, const subnet_t *subnet) { - return avl_search(owner->subnet_tree, subnet); + return splay_search(owner->subnet_tree, subnet); } subnet_t *lookup_subnet_mac(const node_t *owner, const mac_t *address) { subnet_t *p, *r = NULL; - avl_node_t *n; + splay_node_t *n; int i; // Check if this address is cached for(i = 0; i < 2; i++) { - if(!cache_mac_valid[i]) { + if(!cache_mac_valid[i]) continue; - } - - if(owner && cache_mac_subnet[i] && cache_mac_subnet[i]->owner != owner) { + if(owner && cache_mac_subnet[i] && cache_mac_subnet[i]->owner != owner) continue; - } - - if(!memcmp(address, &cache_mac_address[i], sizeof(*address))) { + if(!memcmp(address, &cache_mac_address[i], sizeof *address)) return cache_mac_subnet[i]; - } } // Search all subnets for a matching one for(n = owner ? owner->subnet_tree->head : subnet_tree->head; n; n = n->next) { p = n->data; - - if(!p || p->type != SUBNET_MAC) { + + if(!p || p->type != SUBNET_MAC) continue; - } - if(!memcmp(address, &p->net.mac.address, sizeof(*address))) { + if(!memcmp(address, &p->net.mac.address, sizeof *address)) { r = p; - - if(p->owner->status.reachable) { + if(p->owner->status.reachable) break; - } } } // Cache the result cache_mac_slot = !cache_mac_slot; - memcpy(&cache_mac_address[cache_mac_slot], address, sizeof(*address)); + memcpy(&cache_mac_address[cache_mac_slot], address, sizeof *address); cache_mac_subnet[cache_mac_slot] = r; cache_mac_valid[cache_mac_slot] = true; @@ -494,43 +373,37 @@ subnet_t *lookup_subnet_mac(const node_t *owner, const mac_t *address) { subnet_t *lookup_subnet_ipv4(const ipv4_t *address) { subnet_t *p, *r = NULL; - avl_node_t *n; + splay_node_t *n; int i; // Check if this address is cached for(i = 0; i < 2; i++) { - if(!cache_ipv4_valid[i]) { + if(!cache_ipv4_valid[i]) continue; - } - - if(!memcmp(address, &cache_ipv4_address[i], sizeof(*address))) { + if(!memcmp(address, &cache_ipv4_address[i], sizeof *address)) return cache_ipv4_subnet[i]; - } } // Search all subnets for a matching one for(n = subnet_tree->head; n; n = n->next) { p = n->data; - - if(!p || p->type != SUBNET_IPV4) { + + if(!p || p->type != SUBNET_IPV4) continue; - } if(!maskcmp(address, &p->net.ipv4.address, p->net.ipv4.prefixlength)) { r = p; - - if(p->owner->status.reachable) { + if(p->owner->status.reachable) break; - } } } // Cache the result cache_ipv4_slot = !cache_ipv4_slot; - memcpy(&cache_ipv4_address[cache_ipv4_slot], address, sizeof(*address)); + memcpy(&cache_ipv4_address[cache_ipv4_slot], address, sizeof *address); cache_ipv4_subnet[cache_ipv4_slot] = r; cache_ipv4_valid[cache_ipv4_slot] = true; @@ -539,43 +412,37 @@ subnet_t *lookup_subnet_ipv4(const ipv4_t *address) { subnet_t *lookup_subnet_ipv6(const ipv6_t *address) { subnet_t *p, *r = NULL; - avl_node_t *n; + splay_node_t *n; int i; // Check if this address is cached for(i = 0; i < 2; i++) { - if(!cache_ipv6_valid[i]) { + if(!cache_ipv6_valid[i]) continue; - } - - if(!memcmp(address, &cache_ipv6_address[i], sizeof(*address))) { + if(!memcmp(address, &cache_ipv6_address[i], sizeof *address)) return cache_ipv6_subnet[i]; - } } // Search all subnets for a matching one for(n = subnet_tree->head; n; n = n->next) { p = n->data; - - if(!p || p->type != SUBNET_IPV6) { + + if(!p || p->type != SUBNET_IPV6) continue; - } if(!maskcmp(address, &p->net.ipv6.address, p->net.ipv6.prefixlength)) { r = p; - - if(p->owner->status.reachable) { + if(p->owner->status.reachable) break; - } } } // Cache the result cache_ipv6_slot = !cache_ipv6_slot; - memcpy(&cache_ipv6_address[cache_ipv6_slot], address, sizeof(*address)); + memcpy(&cache_ipv6_address[cache_ipv6_slot], address, sizeof *address); cache_ipv6_subnet[cache_ipv6_slot] = r; cache_ipv6_valid[cache_ipv6_slot] = true; @@ -583,28 +450,25 @@ subnet_t *lookup_subnet_ipv6(const ipv6_t *address) { } void subnet_update(node_t *owner, subnet_t *subnet, bool up) { - avl_node_t *node; + splay_node_t *node; int i; - char *envp[10] = {NULL}; + char *envp[9] = {NULL}; char netstr[MAXNETSTR]; char *name, *address, *port; char empty[] = ""; // Prepare environment variables to be passed to the script - xasprintf(&envp[0], "NETNAME=%s", netname ? netname : ""); - xasprintf(&envp[1], "DEVICE=%s", device ? device : ""); - xasprintf(&envp[2], "INTERFACE=%s", iface ? iface : ""); + xasprintf(&envp[0], "NETNAME=%s", netname ? : ""); + xasprintf(&envp[1], "DEVICE=%s", device ? : ""); + xasprintf(&envp[2], "INTERFACE=%s", iface ? : ""); xasprintf(&envp[3], "NODE=%s", owner->name); - xasprintf(&envp[4], "NAME=%s", myself->name); if(owner != myself) { sockaddr2str(&owner->address, &address, &port); - // 5 and 6 are reserved for SUBNET and WEIGHT - xasprintf(&envp[7], "REMOTEADDRESS=%s", address); - xasprintf(&envp[8], "REMOTEPORT=%s", port); - free(port); - free(address); + // 4 and 5 are reserved for SUBNET and WEIGHT + xasprintf(&envp[6], "REMOTEADDRESS=%s", address); + xasprintf(&envp[7], "REMOTEPORT=%s", port); } name = up ? "subnet-up" : "subnet-down"; @@ -612,69 +476,59 @@ void subnet_update(node_t *owner, subnet_t *subnet, bool up) { if(!subnet) { for(node = owner->subnet_tree->head; node; node = node->next) { subnet = node->data; - - if(!net2str(netstr, sizeof(netstr), subnet)) { + 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, '#'); - - if(weight) { + if(weight) *weight++ = 0; - } else { + else weight = empty; - } // Prepare the SUBNET and WEIGHT variables - free(envp[5]); - free(envp[6]); - - xasprintf(&envp[5], "SUBNET=%s", netstr); - xasprintf(&envp[6], "WEIGHT=%s", weight); + if(envp[4]) + free(envp[4]); + if(envp[5]) + free(envp[5]); + xasprintf(&envp[4], "SUBNET=%s", netstr); + xasprintf(&envp[5], "WEIGHT=%s", weight); execute_script(name, envp); } } else { - if(net2str(netstr, sizeof(netstr), 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, '#'); - - if(weight) { + if(weight) *weight++ = 0; - } else { + else weight = empty; - } // Prepare the SUBNET and WEIGHT variables - xasprintf(&envp[5], "SUBNET=%s", netstr); - xasprintf(&envp[6], "WEIGHT=%s", weight); + xasprintf(&envp[4], "SUBNET=%s", netstr); + xasprintf(&envp[5], "WEIGHT=%s", weight); execute_script(name, envp); } } - for(i = 0; i < 9; i++) { + for(i = 0; envp[i] && i < 8; i++) free(envp[i]); - } } -void dump_subnets(void) { +bool dump_subnets(connection_t *c) { char netstr[MAXNETSTR]; subnet_t *subnet; - avl_node_t *node; - - logger(LOG_DEBUG, "Subnet list:"); + splay_node_t *node; for(node = subnet_tree->head; node; node = node->next) { subnet = node->data; - - if(!net2str(netstr, sizeof(netstr), subnet)) { + if(!net2str(netstr, sizeof netstr, subnet)) continue; - } - - logger(LOG_DEBUG, " %s owner %s", netstr, subnet->owner->name); + send_request(c, "%d %d %s owner %s", + CONTROL, REQ_DUMP_SUBNETS, + netstr, subnet->owner->name); } - logger(LOG_DEBUG, "End of subnet list."); + return send_request(c, "%d %d", CONTROL, REQ_DUMP_SUBNETS); } diff --git a/src/subnet.h b/src/subnet.h index 6fecca3..f22e6d5 100644 --- a/src/subnet.h +++ b/src/subnet.h @@ -1,6 +1,3 @@ -#ifndef TINC_SUBNET_H -#define TINC_SUBNET_H - /* subnet.h -- header for subnet.c Copyright (C) 2000-2009 Guus Sliepen , @@ -21,13 +18,16 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +#ifndef __TINC_SUBNET_H__ +#define __TINC_SUBNET_H__ + #include "net.h" typedef enum subnet_type_t { SUBNET_MAC = 0, SUBNET_IPV4, SUBNET_IPV6, - SUBNET_TYPES, /* Guardian */ + SUBNET_TYPES /* Guardian */ } subnet_type_t; typedef struct subnet_mac_t { @@ -47,11 +47,11 @@ typedef struct subnet_ipv6_t { #include "node.h" typedef struct subnet_t { - struct node_t *owner; /* the owner of this subnet */ + struct node_t *owner; /* the owner of this subnet */ - subnet_type_t type; /* subnet type (IPv4? IPv6? MAC? something even weirder?) */ - time_t expires; /* expiry time */ - int weight; /* weight (higher value is higher priority) */ + subnet_type_t type; /* subnet type (IPv4? IPv6? MAC? something even weirder?) */ + time_t expires; /* expiry time */ + int weight; /* weight (higher value is higher priority) */ /* And now for the actual subnet: */ @@ -64,24 +64,25 @@ typedef struct subnet_t { #define MAXNETSTR 64 -extern avl_tree_t *subnet_tree; +extern splay_tree_t *subnet_tree; -extern subnet_t *new_subnet(void) __attribute__((__malloc__)); -extern void free_subnet(subnet_t *subnet); +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 *); extern void init_subnets(void); extern void exit_subnets(void); -extern avl_tree_t *new_subnet_tree(void) __attribute__((__malloc__)); -extern void free_subnet_tree(avl_tree_t *subnet_tree); -extern void subnet_add(struct node_t *owner, subnet_t *subnet); -extern void subnet_del(struct node_t *owner, subnet_t *subnet); -extern void subnet_update(struct node_t *owner, subnet_t *subnet, bool up); -extern bool net2str(char *netstr, int len, const subnet_t *subnet); -extern bool str2net(subnet_t *subnet, const char *netstr); -extern subnet_t *lookup_subnet(const struct node_t *owner, const subnet_t *subnet); -extern subnet_t *lookup_subnet_mac(const struct node_t *owner, const mac_t *address); -extern subnet_t *lookup_subnet_ipv4(const ipv4_t *address); -extern subnet_t *lookup_subnet_ipv6(const ipv6_t *address); -extern void dump_subnets(void); +extern splay_tree_t *new_subnet_tree(void) __attribute__ ((__malloc__)); +extern void free_subnet_tree(splay_tree_t *); +extern void subnet_add(struct node_t *, subnet_t *); +extern void subnet_del(struct node_t *, subnet_t *); +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 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 bool dump_subnets(struct connection_t *); extern void subnet_cache_flush(void); -#endif +#endif /* __TINC_SUBNET_H__ */ diff --git a/src/tincctl.c b/src/tincctl.c new file mode 100644 index 0000000..c055db5 --- /dev/null +++ b/src/tincctl.c @@ -0,0 +1,833 @@ +/* + tincctl.c -- Controlling a running tincd + Copyright (C) 2007-2011 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "system.h" + +#include + +#include "xalloc.h" +#include "protocol.h" +#include "control_common.h" +#include "ecdsagen.h" +#include "rsagen.h" +#include "utils.h" +#include "tincctl.h" +#include "top.h" + +/* The name this program was run with. */ +static char *program_name = NULL; + +/* If nonzero, display usage information and exit. */ +static bool show_help = false; + +/* If nonzero, print the version on standard output and exit. */ +static bool show_version = false; + +static char *name = NULL; +static char *identname = NULL; /* program name for syslog */ +static char *pidfilename = NULL; /* pid file location */ +static char controlcookie[1024]; +char *netname = NULL; +char *confbase = NULL; + +#ifdef HAVE_MINGW +static struct WSAData wsa_state; +#endif + +static struct option const long_options[] = { + {"config", required_argument, NULL, 'c'}, + {"net", required_argument, NULL, 'n'}, + {"help", no_argument, NULL, 1}, + {"version", no_argument, NULL, 2}, + {"pidfile", required_argument, NULL, 5}, + {NULL, 0, NULL, 0} +}; + +static void usage(bool status) { + if(status) + fprintf(stderr, "Try `%s --help\' for more information.\n", + program_name); + else { + printf("Usage: %s [options] command\n\n", program_name); + printf("Valid options are:\n" + " -c, --config=DIR Read configuration options from DIR.\n" + " -n, --net=NETNAME Connect to net NETNAME.\n" + " --pidfile=FILENAME Read control cookie from FILENAME.\n" + " --help Display this help and exit.\n" + " --version Output version information and exit.\n" + "\n" + "Valid commands are:\n" + " start Start tincd.\n" + " stop Stop tincd.\n" + " restart Restart tincd.\n" + " reload Reload configuration of running tincd.\n" + " pid Show PID of currently running tincd.\n" + " generate-keys [bits] Generate new RSA and ECDSA public/private keypairs.\n" + " generate-rsa-keys [bits] Generate a new RSA public/private keypair.\n" + " generate-ecdsa-keys Generate a new ECDSA public/private keypair.\n" + " dump Dump a list of one of the following things:\n" + " nodes - all known nodes in the VPN\n" + " edges - all known connections in the VPN\n" + " subnets - all known subnets in the VPN\n" + " connections - all meta connections with ourself\n" + " graph - graph of the VPN in dotty format\n" + " purge Purge unreachable nodes\n" + " debug N Set debug level\n" + " retry Retry all outgoing connections\n" + " reload Partial reload of configuration\n" + " disconnect NODE Close meta connection with NODE\n" +#ifdef HAVE_CURSES + " top Show real-time statistics\n" +#endif + " pcap Dump traffic in pcap format\n" + "\n"); + printf("Report bugs to tinc@tinc-vpn.org.\n"); + } +} + +static bool parse_options(int argc, char **argv) { + int r; + int option_index = 0; + + while((r = getopt_long(argc, argv, "c:n:", long_options, &option_index)) != EOF) { + switch (r) { + case 0: /* long option */ + break; + + case 'c': /* config file */ + confbase = xstrdup(optarg); + break; + + case 'n': /* net name given */ + netname = xstrdup(optarg); + break; + + case 1: /* show help */ + show_help = true; + break; + + case 2: /* show version */ + show_version = true; + break; + + case 5: /* open control socket here */ + pidfilename = xstrdup(optarg); + break; + + case '?': + usage(true); + return false; + + default: + break; + } + } + + return true; +} + +FILE *ask_and_open(const char *filename, const char *what, const char *mode) { + FILE *r; + char *directory; + char buf[PATH_MAX]; + char buf2[PATH_MAX]; + + /* Check stdin and stdout */ + if(isatty(0) && isatty(1)) { + /* Ask for a file and/or directory name. */ + fprintf(stdout, "Please enter a file to save %s to [%s]: ", + what, filename); + fflush(stdout); + + if(fgets(buf, sizeof buf, stdin) == NULL) { + fprintf(stderr, "Error while reading stdin: %s\n", + strerror(errno)); + return NULL; + } + + size_t len = strlen(buf); + if(len) + buf[--len] = 0; + + if(len) + filename = buf; + } + +#ifdef HAVE_MINGW + if(filename[0] != '\\' && filename[0] != '/' && !strchr(filename, ':')) { +#else + if(filename[0] != '/') { +#endif + /* The directory is a relative path or a filename. */ + directory = get_current_dir_name(); + snprintf(buf2, sizeof buf2, "%s/%s", directory, filename); + filename = buf2; + } + + umask(0077); /* Disallow everything for group and other */ + + /* Open it first to keep the inode busy */ + + r = fopen(filename, mode); + + if(!r) { + fprintf(stderr, "Error opening file `%s': %s\n", filename, strerror(errno)); + return NULL; + } + + return r; +} + +/* + Generate a public/private ECDSA keypair, and ask for a file to store + them in. +*/ +static bool ecdsa_keygen() { + ecdsa_t key; + FILE *f; + char *filename; + + fprintf(stderr, "Generating ECDSA keypair:\n"); + + if(!ecdsa_generate(&key)) { + fprintf(stderr, "Error during key generation!\n"); + return false; + } else + fprintf(stderr, "Done.\n"); + + xasprintf(&filename, "%s/ecdsa_key.priv", confbase); + f = ask_and_open(filename, "private ECDSA key", "a"); + + if(!f) + return false; + +#ifdef HAVE_FCHMOD + /* Make it unreadable for others. */ + fchmod(fileno(f), 0600); +#endif + + if(ftell(f)) + fprintf(stderr, "Appending key to existing contents.\nMake sure only one key is stored in the file.\n"); + + ecdsa_write_pem_private_key(&key, f); + + fclose(f); + free(filename); + + if(name) + xasprintf(&filename, "%s/hosts/%s", confbase, name); + else + xasprintf(&filename, "%s/ecdsa_key.pub", confbase); + + f = ask_and_open(filename, "public ECDSA key", "a"); + + if(!f) + return false; + + if(ftell(f)) + fprintf(stderr, "Appending key to existing contents.\nMake sure only one key is stored in the file.\n"); + + char *pubkey = ecdsa_get_base64_public_key(&key); + fprintf(f, "ECDSAPublicKey = %s\n", pubkey); + free(pubkey); + + fclose(f); + free(filename); + + return true; +} + +/* + Generate a public/private RSA keypair, and ask for a file to store + them in. +*/ +static bool rsa_keygen(int bits) { + rsa_t key; + FILE *f; + char *filename; + + fprintf(stderr, "Generating %d bits keys:\n", bits); + + if(!rsa_generate(&key, bits, 0x10001)) { + fprintf(stderr, "Error during key generation!\n"); + return false; + } else + fprintf(stderr, "Done.\n"); + + xasprintf(&filename, "%s/rsa_key.priv", confbase); + f = ask_and_open(filename, "private RSA key", "a"); + + if(!f) + return false; + +#ifdef HAVE_FCHMOD + /* Make it unreadable for others. */ + fchmod(fileno(f), 0600); +#endif + + if(ftell(f)) + fprintf(stderr, "Appending key to existing contents.\nMake sure only one key is stored in the file.\n"); + + rsa_write_pem_private_key(&key, f); + + fclose(f); + free(filename); + + if(name) + xasprintf(&filename, "%s/hosts/%s", confbase, name); + else + xasprintf(&filename, "%s/rsa_key.pub", confbase); + + f = ask_and_open(filename, "public RSA key", "a"); + + if(!f) + return false; + + if(ftell(f)) + fprintf(stderr, "Appending key to existing contents.\nMake sure only one key is stored in the file.\n"); + + rsa_write_pem_public_key(&key, f); + + fclose(f); + free(filename); + + return true; +} + +/* + Set all files and paths according to netname +*/ +static void make_names(void) { +#ifdef HAVE_MINGW + HKEY key; + char installdir[1024] = ""; + long len = sizeof installdir; +#endif + + if(netname) + xasprintf(&identname, "tinc.%s", netname); + else + identname = xstrdup("tinc"); + +#ifdef HAVE_MINGW + if(!RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\tinc", 0, KEY_READ, &key)) { + if(!RegQueryValueEx(key, NULL, 0, 0, installdir, &len)) { + if(!confbase) { + if(netname) + xasprintf(&confbase, "%s/%s", installdir, netname); + else + xasprintf(&confbase, "%s", installdir); + } + } + if(!pidfilename) + xasprintf(&pidfilename, "%s/pid", confbase); + RegCloseKey(key); + if(*installdir) + return; + } +#endif + + if(!pidfilename) + xasprintf(&pidfilename, "%s/run/%s.pid", LOCALSTATEDIR, identname); + + if(netname) { + if(!confbase) + xasprintf(&confbase, CONFDIR "/tinc/%s", netname); + else + fprintf(stderr, "Both netname and configuration directory given, using the latter...\n"); + } else { + if(!confbase) + xasprintf(&confbase, CONFDIR "/tinc"); + } +} + +static char buffer[4096]; +static size_t blen = 0; + +bool recvline(int fd, char *line, size_t len) { + char *newline = NULL; + + while(!(newline = memchr(buffer, '\n', blen))) { + int result = recv(fd, buffer + blen, sizeof buffer - blen, 0); + if(result == -1 && errno == EINTR) + continue; + else if(result <= 0) + return false; + blen += result; + } + + if(newline - buffer >= len) + return false; + + len = newline - buffer; + + memcpy(line, buffer, len); + line[len] = 0; + memmove(buffer, newline + 1, blen - len - 1); + blen -= len + 1; + + return true; +} + +bool recvdata(int fd, char *data, size_t len) { + while(blen < len) { + int result = recv(fd, buffer + blen, sizeof buffer - blen, 0); + if(result == -1 && errno == EINTR) + continue; + else if(result <= 0) + return false; + blen += result; + } + + memcpy(data, buffer, len); + memmove(buffer, buffer + len, blen - len); + blen -= len; + + return true; +} + +bool sendline(int fd, char *format, ...) { + static char buffer[4096]; + char *p = buffer; + int blen = 0; + va_list ap; + + va_start(ap, format); + blen = vsnprintf(buffer, sizeof buffer, format, ap); + va_end(ap); + + if(blen < 1 || blen >= sizeof buffer) + return false; + + buffer[blen] = '\n'; + blen++; + + while(blen) { + int result = send(fd, p, blen, 0); + if(result == -1 && errno == EINTR) + continue; + else if(result <= 0) + return false; + p += result; + blen -= result; + } + + return true; +} + +void pcap(int fd, FILE *out) { + sendline(fd, "%d %d", CONTROL, REQ_PCAP); + char data[9018]; + + struct { + uint32_t magic; + uint16_t major; + uint16_t minor; + uint32_t tz_offset; + uint32_t tz_accuracy; + uint32_t snaplen; + uint32_t ll_type; + } header = { + 0xa1b2c3d4, + 2, 4, + 0, 0, + sizeof data, + 1, + }; + + struct { + uint32_t tv_sec; + uint32_t tv_usec; + uint32_t len; + uint32_t origlen; + } packet; + + struct timeval tv; + + fwrite(&header, sizeof header, 1, out); + fflush(out); + + char line[32]; + while(recvline(fd, line, sizeof line)) { + int code, req, len; + int n = sscanf(line, "%d %d %d", &code, &req, &len); + gettimeofday(&tv, NULL); + if(n != 3 || code != CONTROL || req != REQ_PCAP || len < 0 || len > sizeof data) + break; + if(!recvdata(fd, data, len)) + break; + packet.tv_sec = tv.tv_sec; + packet.tv_usec = tv.tv_usec; + packet.len = len; + packet.origlen = len; + fwrite(&packet, sizeof packet, 1, out); + fwrite(data, len, 1, out); + fflush(out); + } +} + +#ifdef HAVE_MINGW +static bool remove_service(void) { + SC_HANDLE manager = NULL; + SC_HANDLE service = NULL; + SERVICE_STATUS status = {0}; + + manager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); + if(!manager) { + fprintf(stderr, "Could not open service manager: %s\n", winerror(GetLastError())); + return false; + } + + service = OpenService(manager, identname, SERVICE_ALL_ACCESS); + + if(!service) { + fprintf(stderr, "Could not open %s service: %s\n", identname, winerror(GetLastError())); + return false; + } + + if(!ControlService(service, SERVICE_CONTROL_STOP, &status)) + fprintf(stderr, "Could not stop %s service: %s\n", identname, winerror(GetLastError())); + else + fprintf(stderr, "%s service stopped\n", identname); + + if(!DeleteService(service)) { + fprintf(stderr, "Could not remove %s service: %s\n", identname, winerror(GetLastError())); + return false; + } + + fprintf(stderr, "%s service removed\n", identname); + + return true; +} +#endif + +int main(int argc, char *argv[], char *envp[]) { + int fd; + int result; + char host[128]; + char port[128]; + int pid; + + program_name = argv[0]; + + if(!parse_options(argc, argv)) + return 1; + + make_names(); + + if(show_version) { + printf("%s version %s (built %s %s, protocol %d.%d)\n", PACKAGE, + VERSION, __DATE__, __TIME__, PROT_MAJOR, PROT_MINOR); + printf("Copyright (C) 1998-2009 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" + "see the file COPYING for details.\n"); + + return 0; + } + + if(show_help) { + usage(false); + return 0; + } + + if(optind >= argc) { + fprintf(stderr, "Not enough arguments.\n"); + usage(true); + return 1; + } + + // First handle commands that don't involve connecting to a running tinc daemon. + + if(!strcasecmp(argv[optind], "generate-rsa-keys")) { + return !rsa_keygen(optind > argc ? atoi(argv[optind + 1]) : 2048); + } + + if(!strcasecmp(argv[optind], "generate-ecdsa-keys")) { + return !ecdsa_keygen(); + } + + if(!strcasecmp(argv[optind], "generate-keys")) { + return !(rsa_keygen(optind > argc ? atoi(argv[optind + 1]) : 2048) && ecdsa_keygen()); + } + + if(!strcasecmp(argv[optind], "start")) { + argv[optind] = NULL; + execve(SBINDIR "/tincd", argv, envp); + fprintf(stderr, "Could not start tincd: %s", strerror(errno)); + return 1; + } + + /* + * Now handle commands that do involve connecting to a running tinc daemon. + * Authenticate the server by ensuring the parent directory can be + * traversed only by root. Note this is not totally race-free unless all + * ancestors are writable only by trusted users, which we don't verify. + */ + + FILE *f = fopen(pidfilename, "r"); + if(!f) { + fprintf(stderr, "Could not open pid file %s: %s\n", pidfilename, strerror(errno)); + return 1; + } + if(fscanf(f, "%20d %1024s %128s port %128s", &pid, controlcookie, host, port) != 4) { + fprintf(stderr, "Could not parse pid file %s\n", pidfilename); + return 1; + } + +#ifdef HAVE_MINGW + if(WSAStartup(MAKEWORD(2, 2), &wsa_state)) { + fprintf(stderr, "System call `%s' failed: %s", "WSAStartup", winerror(GetLastError())); + return 1; + } +#endif + + struct addrinfo hints = { + .ai_family = AF_UNSPEC, + .ai_socktype = SOCK_STREAM, + .ai_protocol = IPPROTO_TCP, + .ai_flags = 0, + }; + + struct addrinfo *res = NULL; + + if(getaddrinfo(host, port, &hints, &res) || !res) { + fprintf(stderr, "Cannot resolve %s port %s: %s", host, port, strerror(errno)); + return 1; + } + + fd = socket(res->ai_family, SOCK_STREAM, IPPROTO_TCP); + if(fd < 0) { + fprintf(stderr, "Cannot create TCP socket: %s\n", sockstrerror(sockerrno)); + return 1; + } + +#ifdef HAVE_MINGW + unsigned long arg = 0; + + if(ioctlsocket(fd, FIONBIO, &arg) != 0) { + fprintf(stderr, "ioctlsocket failed: %s", sockstrerror(sockerrno)); + } +#endif + + if(connect(fd, res->ai_addr, res->ai_addrlen) < 0) { + fprintf(stderr, "Cannot connect to %s port %s: %s\n", host, port, sockstrerror(sockerrno)); + return 1; + } + + freeaddrinfo(res); + + char line[4096]; + char data[4096]; + int code, version, req; + + if(!recvline(fd, line, sizeof line) || sscanf(line, "%d %s %d", &code, data, &version) != 3 || code != 0) { + fprintf(stderr, "Cannot read greeting from control socket: %s\n", + sockstrerror(sockerrno)); + return 1; + } + + sendline(fd, "%d ^%s %d", ID, controlcookie, TINC_CTL_VERSION_CURRENT); + + if(!recvline(fd, line, sizeof line) || sscanf(line, "%d %d %d", &code, &version, &pid) != 3 || code != 4 || version != TINC_CTL_VERSION_CURRENT) { + fprintf(stderr, "Could not fully establish control socket connection\n"); + return 1; + } + + if(!strcasecmp(argv[optind], "pid")) { + printf("%d\n", pid); + return 0; + } + + if(!strcasecmp(argv[optind], "stop")) { +#ifndef HAVE_MINGW + sendline(fd, "%d %d", CONTROL, REQ_STOP); + if(!recvline(fd, line, sizeof line) || sscanf(line, "%d %d %d", &code, &req, &result) != 3 || code != CONTROL || req != REQ_STOP || result) { + fprintf(stderr, "Could not stop tinc daemon\n"); + return 1; + } +#else + if(!remove_service()) + return 1; +#endif + return 0; + } + + if(!strcasecmp(argv[optind], "reload")) { + sendline(fd, "%d %d", CONTROL, REQ_RELOAD); + if(!recvline(fd, line, sizeof line) || sscanf(line, "%d %d %d", &code, &req, &result) != 3 || code != CONTROL || req != REQ_RELOAD || result) { + fprintf(stderr, "Could not reload tinc daemon\n"); + return 1; + } + return 0; + } + + if(!strcasecmp(argv[optind], "restart")) { + sendline(fd, "%d %d", CONTROL, REQ_RESTART); + if(!recvline(fd, line, sizeof line) || sscanf(line, "%d %d %d", &code, &req, &result) != 3 || code != CONTROL || req != REQ_RESTART || result) { + fprintf(stderr, "Could not restart tinc daemon\n"); + return 1; + } + return 0; + } + + if(!strcasecmp(argv[optind], "retry")) { + sendline(fd, "%d %d", CONTROL, REQ_RETRY); + if(!recvline(fd, line, sizeof line) || sscanf(line, "%d %d %d", &code, &req, &result) != 3 || code != CONTROL || req != REQ_RETRY || result) { + fprintf(stderr, "Could not retry outgoing connections\n"); + return 1; + } + return 0; + } + + if(!strcasecmp(argv[optind], "dump")) { + if(argc < optind + 2) { + fprintf(stderr, "Not enough arguments.\n"); + usage(true); + return 1; + } + + bool do_graph = false; + + if(!strcasecmp(argv[optind+1], "nodes")) + sendline(fd, "%d %d", CONTROL, REQ_DUMP_NODES); + else if(!strcasecmp(argv[optind+1], "edges")) + sendline(fd, "%d %d", CONTROL, REQ_DUMP_EDGES); + else if(!strcasecmp(argv[optind+1], "subnets")) + sendline(fd, "%d %d", CONTROL, REQ_DUMP_SUBNETS); + else if(!strcasecmp(argv[optind+1], "connections")) + sendline(fd, "%d %d", CONTROL, REQ_DUMP_CONNECTIONS); + else if(!strcasecmp(argv[optind+1], "graph")) { + sendline(fd, "%d %d", CONTROL, REQ_DUMP_NODES); + sendline(fd, "%d %d", CONTROL, REQ_DUMP_EDGES); + do_graph = true; + printf("digraph {\n"); + } else { + fprintf(stderr, "Unknown dump type '%s'.\n", argv[optind+1]); + usage(true); + return 1; + } + + while(recvline(fd, line, sizeof line)) { + char node1[4096], node2[4096]; + int n = sscanf(line, "%d %d %s to %s", &code, &req, node1, node2); + if(n == 2) { + if(do_graph && req == REQ_DUMP_NODES) + continue; + else { + if(do_graph) + printf("}\n"); + return 0; + } + } + if(n < 2) + break; + + if(!do_graph) + printf("%s\n", line + 5); + else { + if(req == REQ_DUMP_NODES) + printf(" %s [label = \"%s\"];\n", node1, node1); + else + printf(" %s -> %s;\n", node1, node2); + } + } + + fprintf(stderr, "Error receiving dump\n"); + return 1; + } + + if(!strcasecmp(argv[optind], "purge")) { + sendline(fd, "%d %d", CONTROL, REQ_PURGE); + if(!recvline(fd, line, sizeof line) || sscanf(line, "%d %d %d", &code, &req, &result) != 3 || code != CONTROL || req != REQ_PURGE || result) { + fprintf(stderr, "Could not purge tinc daemon\n"); + return 1; + } + return 0; + } + + if(!strcasecmp(argv[optind], "debug")) { + int debuglevel, origlevel; + + if(argc != optind + 2) { + fprintf(stderr, "Invalid arguments.\n"); + return 1; + } + debuglevel = atoi(argv[optind+1]); + + sendline(fd, "%d %d %d", CONTROL, REQ_SET_DEBUG, debuglevel); + if(!recvline(fd, line, sizeof line) || sscanf(line, "%d %d %d", &code, &req, &origlevel) != 3 || code != CONTROL || req != REQ_SET_DEBUG) { + fprintf(stderr, "Could not purge tinc daemon\n"); + return 1; + } + + fprintf(stderr, "Old level %d, new level %d\n", origlevel, debuglevel); + return 0; + } + + if(!strcasecmp(argv[optind], "connect")) { + if(argc != optind + 2) { + fprintf(stderr, "Invalid arguments.\n"); + return 1; + } + char *name = argv[optind + 1]; + + sendline(fd, "%d %d %s", CONTROL, REQ_CONNECT, name); + if(!recvline(fd, line, sizeof line) || sscanf(line, "%d %d %d", &code, &req, &result) != 3 || code != CONTROL || req != REQ_CONNECT || result) { + fprintf(stderr, "Could not connect to %s\n", name); + return 1; + } + return 0; + } + + if(!strcasecmp(argv[optind], "disconnect")) { + if(argc != optind + 2) { + fprintf(stderr, "Invalid arguments.\n"); + return 1; + } + char *name = argv[optind + 1]; + + sendline(fd, "%d %d %s", CONTROL, REQ_DISCONNECT, name); + if(!recvline(fd, line, sizeof line) || sscanf(line, "%d %d %d", &code, &req, &result) != 3 || code != CONTROL || req != REQ_DISCONNECT || result) { + fprintf(stderr, "Could not disconnect %s\n", name); + return 1; + } + return 0; + } + +#ifdef HAVE_CURSES + if(!strcasecmp(argv[optind], "top")) { + top(fd); + return 0; + } +#endif + + if(!strcasecmp(argv[optind], "pcap")) { + pcap(fd, stdout); + return 0; + } + + fprintf(stderr, "Unknown command `%s'.\n", argv[optind]); + usage(true); + + close(fd); + + return 0; +} diff --git a/src/tincctl.h b/src/tincctl.h new file mode 100644 index 0000000..114b931 --- /dev/null +++ b/src/tincctl.h @@ -0,0 +1,27 @@ +/* + tincctl.h -- header for tincctl.c. + Copyright (C) 2011 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#ifndef __TINC_TINCCTL_H__ +#define __TINC_TINCCTL_H__ + +extern bool sendline(int fd, char *format, ...); +extern bool recvline(int fd, char *line, size_t len); + +#endif + diff --git a/src/tincd.c b/src/tincd.c index b4704c4..8401b20 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-2018 Guus Sliepen + 2000-2011 Guus Sliepen 2008 Max Rijevski 2009 Michael Tokarev 2010 Julien Muchembled @@ -49,15 +49,11 @@ #include #endif -#ifdef HAVE_GETOPT_LONG #include -#else -#include "getopt.h" -#endif - -#include "pidfile.h" #include "conf.h" +#include "control.h" +#include "crypto.h" #include "device.h" #include "logger.h" #include "net.h" @@ -71,22 +67,16 @@ char *program_name = NULL; /* If nonzero, display usage information and exit. */ -bool show_help = false; +static bool show_help = false; /* If nonzero, print the version on standard output and exit. */ -bool show_version = false; - -/* If nonzero, it will attempt to kill a running tincd and exit. */ -int kill_tincd = 0; - -/* If nonzero, generate public/private keypair for this host/net. */ -int generate_keys = 0; +static bool show_version = false; /* If nonzero, use null ciphers and skip all key exchanges. */ bool bypass_security = false; /* If nonzero, disable swapping for this process. */ -bool do_mlock = false; +static bool do_mlock = false; /* If nonzero, chroot to netdir after startup. */ static bool do_chroot = false; @@ -97,21 +87,19 @@ static const char *switchuser = NULL; /* If nonzero, write log entries to a separate file. */ bool use_logfile = false; -char *identname = NULL; /* program name for syslog */ -char *pidfilename = NULL; /* pid file location */ -char *logfilename = NULL; /* log file location */ -char **g_argv; /* a copy of the cmdline arguments */ +char *identname = NULL; /* program name for syslog */ +char *logfilename = NULL; /* log file location */ +char *pidfilename = NULL; +char **g_argv; /* a copy of the cmdline arguments */ static int status = 1; static struct option const long_options[] = { {"config", required_argument, NULL, 'c'}, - {"kill", optional_argument, NULL, 'k'}, {"net", required_argument, NULL, 'n'}, {"help", no_argument, NULL, 1}, {"version", no_argument, NULL, 2}, {"no-detach", no_argument, NULL, 'D'}, - {"generate-keys", optional_argument, NULL, 'K'}, {"debug", optional_argument, NULL, 'd'}, {"bypass-security", no_argument, NULL, 3}, {"mlock", no_argument, NULL, 'L'}, @@ -119,7 +107,6 @@ static struct option const long_options[] = { {"user", required_argument, NULL, 'U'}, {"logfile", optional_argument, NULL, 4}, {"pidfile", required_argument, NULL, 5}, - {"option", required_argument, NULL, 'o'}, {NULL, 0, NULL, 0} }; @@ -132,23 +119,21 @@ int main2(int argc, char **argv); static void usage(bool status) { if(status) fprintf(stderr, "Try `%s --help\' for more information.\n", - program_name); + program_name); else { printf("Usage: %s [option]...\n\n", program_name); - printf(" -c, --config=DIR Read configuration options from DIR.\n" - " -D, --no-detach Don't fork and detach.\n" - " -d, --debug[=LEVEL] Increase debug level or set it to LEVEL.\n" - " -k, --kill[=SIGNAL] Attempt to kill a running tincd and exit.\n" - " -n, --net=NETNAME Connect to net NETNAME.\n" - " -K, --generate-keys[=BITS] Generate public/private RSA keypair.\n" - " -L, --mlock Lock tinc into main memory.\n" - " --logfile[=FILENAME] Write log entries to a logfile.\n" - " --pidfile=FILENAME Write PID to FILENAME.\n" - " -o, --option=[HOST.]KEY=VALUE Set global/host configuration value.\n" - " -R, --chroot chroot to NET dir at startup.\n" - " -U, --user=USER setuid to given USER at startup.\n" - " --help Display this help and exit.\n" - " --version Output version information and exit.\n\n"); + printf( " -c, --config=DIR Read configuration options from DIR.\n" + " -D, --no-detach Don't fork and detach.\n" + " -d, --debug[=LEVEL] Increase debug level or set it to LEVEL.\n" + " -n, --net=NETNAME Connect to net NETNAME.\n" + " -L, --mlock Lock tinc into main memory.\n" + " --logfile[=FILENAME] Write log entries to a logfile.\n" + " --pidfile=FILENAME Write PID and control socket cookie to FILENAME.\n" + " --bypass-security Disables meta protocol security, for debugging.\n" + " -o [HOST.]KEY=VALUE Set global/host configuration value.\n" + " -R, --chroot chroot to NET dir at startup.\n" + " -U, --user=USER setuid to given USER at startup.\n" " --help Display this help and exit.\n" + " --version Output version information and exit.\n\n"); printf("Report bugs to tinc@tinc-vpn.org.\n"); } } @@ -161,340 +146,87 @@ static bool parse_options(int argc, char **argv) { cmdline_conf = list_alloc((list_action_t)free_config); - while((r = getopt_long(argc, argv, "c:DLd::k::n:o:K::RU:", long_options, &option_index)) != EOF) { - switch(r) { - case 0: /* long option */ - break; + while((r = getopt_long(argc, argv, "c:DLd::n:o:RU:", long_options, &option_index)) != EOF) { + switch (r) { + case 0: /* long option */ + break; - case 'c': /* config file */ - if(confbase) { - fprintf(stderr, "Only one configuration directory can be given.\n"); - usage(true); - return false; - } + case 'c': /* config file */ + confbase = xstrdup(optarg); + break; - confbase = xstrdup(optarg); - break; + case 'D': /* no detach */ + do_detach = false; + break; - case 'D': /* no detach */ - do_detach = false; - break; - - case 'L': /* no detach */ + case 'L': /* no detach */ #ifndef HAVE_MLOCKALL - logger(LOG_ERR, "%s not supported on this platform", "mlockall()"); - return false; + logger(LOG_ERR, "%s not supported on this platform", "mlockall()"); + return false; #else - do_mlock = true; - break; + do_mlock = true; + break; #endif - case 'd': /* increase debug level */ - if(!optarg && optind < argc && *argv[optind] != '-') { - optarg = argv[optind++]; - } + case 'd': /* inc debug level */ + if(optarg) + debug_level = atoi(optarg); + else + debug_level++; + break; - if(optarg) { - debug_level = atoi(optarg); - } else { - debug_level++; - } + case 'n': /* net name given */ + /* netname "." is special: a "top-level name" */ + netname = strcmp(optarg, ".") != 0 ? + xstrdup(optarg) : NULL; + break; - break; + case 'o': /* option */ + cfg = parse_config_line(optarg, NULL, ++lineno); + if (!cfg) + return false; + list_insert_tail(cmdline_conf, cfg); + break; - case 'k': /* kill old tincds */ -#ifndef HAVE_MINGW - if(!optarg && optind < argc && *argv[optind] != '-') { - optarg = argv[optind++]; - } + case 'R': /* chroot to NETNAME dir */ + do_chroot = true; + break; - if(optarg) { - if(!strcasecmp(optarg, "HUP")) { - kill_tincd = SIGHUP; - } else if(!strcasecmp(optarg, "TERM")) { - kill_tincd = SIGTERM; - } else if(!strcasecmp(optarg, "KILL")) { - kill_tincd = SIGKILL; - } else if(!strcasecmp(optarg, "USR1")) { - kill_tincd = SIGUSR1; - } else if(!strcasecmp(optarg, "USR2")) { - kill_tincd = SIGUSR2; - } else if(!strcasecmp(optarg, "WINCH")) { - kill_tincd = SIGWINCH; - } else if(!strcasecmp(optarg, "INT")) { - kill_tincd = SIGINT; - } else if(!strcasecmp(optarg, "ALRM")) { - kill_tincd = SIGALRM; - } else if(!strcasecmp(optarg, "ABRT")) { - kill_tincd = SIGABRT; - } else { - kill_tincd = atoi(optarg); + case 'U': /* setuid to USER */ + switchuser = optarg; + break; - if(!kill_tincd) { - fprintf(stderr, "Invalid argument `%s'; SIGNAL must be a number or one of HUP, TERM, KILL, USR1, USR2, WINCH, INT or ALRM.\n", - optarg); - usage(true); - return false; - } - } - } else { - kill_tincd = SIGTERM; - } + case 1: /* show help */ + show_help = true; + break; -#else - kill_tincd = 1; -#endif - break; + case 2: /* show version */ + show_version = true; + break; - case 'n': /* net name given */ + case 3: /* bypass security */ + bypass_security = true; + break; - /* netname "." is special: a "top-level name" */ - if(netname) { - fprintf(stderr, "Only one netname can be given.\n"); + case 4: /* write log entries to a file */ + use_logfile = true; + if(optarg) + logfilename = xstrdup(optarg); + break; + + case 5: /* open control socket here */ + pidfilename = xstrdup(optarg); + break; + + case '?': usage(true); return false; - } - if(optarg && strcmp(optarg, ".")) { - netname = xstrdup(optarg); - } - - break; - - case 'o': /* option */ - cfg = parse_config_line(optarg, NULL, ++lineno); - - if(!cfg) { - return false; - } - - list_insert_tail(cmdline_conf, cfg); - break; - - case 'K': /* generate public/private keypair */ - if(!optarg && optind < argc && *argv[optind] != '-') { - optarg = argv[optind++]; - } - - if(optarg) { - generate_keys = atoi(optarg); - - if(generate_keys < 512) { - fprintf(stderr, "Invalid argument `%s'; BITS must be a number equal to or greater than 512.\n", - optarg); - usage(true); - return false; - } - - generate_keys &= ~7; /* Round it to bytes */ - } else { - generate_keys = 2048; - } - - break; - - case 'R': /* chroot to NETNAME dir */ - do_chroot = true; - break; - - case 'U': /* setuid to USER */ - switchuser = optarg; - break; - - case 1: /* show help */ - show_help = true; - break; - - case 2: /* show version */ - show_version = true; - break; - - case 3: /* bypass security */ - bypass_security = true; - break; - - case 4: /* write log entries to a file */ - use_logfile = true; - - if(!optarg && optind < argc && *argv[optind] != '-') { - optarg = argv[optind++]; - } - - if(optarg) { - if(logfilename) { - fprintf(stderr, "Only one logfile can be given.\n"); - usage(true); - return false; - } - - logfilename = xstrdup(optarg); - } - - break; - - case 5: /* write PID to a file */ - if(pidfilename) { - fprintf(stderr, "Only one pidfile can be given.\n"); - usage(true); - return false; - } - - pidfilename = xstrdup(optarg); - break; - - case '?': - usage(true); - return false; - - default: - break; + default: + break; } } - if(optind < argc) { - fprintf(stderr, "%s: unrecognized argument '%s'\n", argv[0], argv[optind]); - usage(true); - return false; - } - - return true; -} - -/* This function prettyprints the key generation process */ - -static int indicator(int a, int b, BN_GENCB *cb) { - (void)cb; - - switch(a) { - case 0: - fprintf(stderr, "."); - break; - - case 1: - fprintf(stderr, "+"); - break; - - case 2: - fprintf(stderr, "-"); - break; - - case 3: - switch(b) { - case 0: - fprintf(stderr, " p\n"); - break; - - case 1: - fprintf(stderr, " q\n"); - break; - - default: - fprintf(stderr, "?"); - } - - break; - - default: - fprintf(stderr, "?"); - } - - return 1; -} - -#ifndef HAVE_BN_GENCB_NEW -BN_GENCB *BN_GENCB_new(void) { - return xmalloc_and_zero(sizeof(BN_GENCB)); -} - -void BN_GENCB_free(BN_GENCB *cb) { - free(cb); -} -#endif - -/* - Generate a public/private RSA keypair, and ask for a file to store - them in. -*/ -static bool keygen(int bits) { - BIGNUM *e = NULL; - RSA *rsa_key; - FILE *f; - char filename[PATH_MAX]; - BN_GENCB *cb; - int result; - - fprintf(stderr, "Generating %d bits keys:\n", bits); - - cb = BN_GENCB_new(); - - if(!cb) { - abort(); - } - - BN_GENCB_set(cb, indicator, NULL); - - rsa_key = RSA_new(); - - if(BN_hex2bn(&e, "10001") == 0) { - abort(); - } - - if(!rsa_key || !e) { - abort(); - } - - result = RSA_generate_key_ex(rsa_key, bits, e, cb); - - BN_free(e); - BN_GENCB_free(cb); - - if(!result) { - fprintf(stderr, "Error during key generation!\n"); - RSA_free(rsa_key); - return false; - } else { - fprintf(stderr, "Done.\n"); - } - - snprintf(filename, sizeof(filename), "%s/rsa_key.priv", confbase); - f = ask_and_open(filename, "private RSA key"); - - if(!f) { - RSA_free(rsa_key); - return false; - } - -#ifdef HAVE_FCHMOD - /* Make it unreadable for others. */ - fchmod(fileno(f), 0600); -#endif - - fputc('\n', f); - PEM_write_RSAPrivateKey(f, rsa_key, NULL, NULL, 0, NULL, NULL); - fclose(f); - - char *name = get_name(); - - if(name) { - snprintf(filename, sizeof(filename), "%s/hosts/%s", confbase, name); - free(name); - } else { - snprintf(filename, sizeof(filename), "%s/rsa_key.pub", confbase); - } - - f = ask_and_open(filename, "public RSA key"); - - if(!f) { - RSA_free(rsa_key); - return false; - } - - fputc('\n', f); - PEM_write_RSAPublicKey(f, rsa_key); - fclose(f); - - RSA_free(rsa_key); - return true; } @@ -505,130 +237,103 @@ static void make_names(void) { #ifdef HAVE_MINGW HKEY key; char installdir[1024] = ""; - DWORD len = sizeof(installdir); + long len = sizeof installdir; #endif - if(netname) { + if(netname) xasprintf(&identname, "tinc.%s", netname); - } else { + else identname = xstrdup("tinc"); - } #ifdef HAVE_MINGW - if(!RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\tinc", 0, KEY_READ, &key)) { - if(!RegQueryValueEx(key, NULL, 0, 0, (LPBYTE)installdir, &len)) { + if(!RegQueryValueEx(key, NULL, 0, 0, installdir, &len)) { + if(!logfilename) + xasprintf(&logfilename, "%s/log/%s.log", identname); if(!confbase) { - if(netname) { + if(netname) xasprintf(&confbase, "%s/%s", installdir, netname); - } else { + else xasprintf(&confbase, "%s", installdir); - } - } - - if(!logfilename) { - xasprintf(&logfilename, "%s/tinc.log", confbase); } + if(!pidfilename) + xasprintf(&pidfilename, "%s/pid", confbase); } - RegCloseKey(key); - - if(*installdir) { + if(*installdir) return; - } } - #endif - if(!pidfilename) { - xasprintf(&pidfilename, RUNSTATEDIR "/%s.pid", identname); - } - - if(!logfilename) { + if(!logfilename) xasprintf(&logfilename, LOCALSTATEDIR "/log/%s.log", identname); - } + + if(!pidfilename) + xasprintf(&pidfilename, LOCALSTATEDIR "/run/%s.pid", identname); if(netname) { - if(!confbase) { + if(!confbase) xasprintf(&confbase, CONFDIR "/tinc/%s", netname); - } else { + else logger(LOG_INFO, "Both netname and configuration directory given, using the latter..."); - } } else { - if(!confbase) { + if(!confbase) xasprintf(&confbase, CONFDIR "/tinc"); - } } } -static void free_names() { - free(identname); - free(netname); - free(pidfilename); - free(logfilename); - free(confbase); +static void free_names(void) { + if (identname) free(identname); + if (netname) free(netname); + if (pidfilename) free(pidfilename); + if (logfilename) free(logfilename); + if (confbase) free(confbase); } -static bool drop_privs() { +static bool drop_privs(void) { #ifdef HAVE_MINGW - - if(switchuser) { + if (switchuser) { logger(LOG_ERR, "%s not supported on this platform", "-U"); return false; } - - if(do_chroot) { + if (do_chroot) { logger(LOG_ERR, "%s not supported on this platform", "-R"); return false; } - #else uid_t uid = 0; - - if(switchuser) { + if (switchuser) { struct passwd *pw = getpwnam(switchuser); - - if(!pw) { + if (!pw) { logger(LOG_ERR, "unknown user `%s'", switchuser); return false; } - uid = pw->pw_uid; - - if(initgroups(switchuser, pw->pw_gid) != 0 || - setgid(pw->pw_gid) != 0) { + if (initgroups(switchuser, pw->pw_gid) != 0 || + setgid(pw->pw_gid) != 0) { logger(LOG_ERR, "System call `%s' failed: %s", "initgroups", strerror(errno)); return false; } - -#ifndef ANDROID -// Not supported in android NDK endgrent(); endpwent(); -#endif } - - if(do_chroot) { - tzset(); /* for proper timestamps in logs */ - - if(chroot(confbase) != 0 || chdir("/") != 0) { + if (do_chroot) { + tzset(); /* for proper timestamps in logs */ + if (chroot(confbase) != 0 || chdir("/") != 0) { logger(LOG_ERR, "System call `%s' failed: %s", "chroot", strerror(errno)); return false; } - free(confbase); confbase = xstrdup(""); } - - if(switchuser) - if(setuid(uid) != 0) { + if (switchuser) + if (setuid(uid) != 0) { logger(LOG_ERR, "System call `%s' failed: %s", "setuid", strerror(errno)); return false; } - #endif return true; } @@ -645,17 +350,19 @@ static bool drop_privs() { int main(int argc, char **argv) { program_name = argv[0]; - if(!parse_options(argc, argv)) { + if(!parse_options(argc, argv)) return 1; - } + + make_names(); if(show_version) { - printf("%s version %s\n", PACKAGE, VERSION); - printf("Copyright (C) 1998-2018 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" - "see the file COPYING for details.\n"); + printf("%s version %s (built %s %s, protocol %d.%d)\n", PACKAGE, + VERSION, __DATE__, __TIME__, PROT_MAJOR, PROT_MINOR); + printf("Copyright (C) 1998-2011 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" + "see the file COPYING for details.\n"); return 0; } @@ -665,98 +372,72 @@ int main(int argc, char **argv) { return 0; } - make_names(); - - if(kill_tincd) { - return !kill_other(kill_tincd); +#ifdef HAVE_MINGW + if(WSAStartup(MAKEWORD(2, 2), &wsa_state)) { + logger(LOG_ERR, "System call `%s' failed: %s", "WSAStartup", winerror(GetLastError())); + return 1; } +#endif - openlogger("tinc", use_logfile ? LOGMODE_FILE : LOGMODE_STDERR); + openlogger("tinc", use_logfile?LOGMODE_FILE:LOGMODE_STDERR); + + if(!event_init()) { + logger(LOG_ERR, "Error initializing libevent!"); + return 1; + } g_argv = argv; - if(getenv("LISTEN_PID") && atoi(getenv("LISTEN_PID")) == getpid()) { - do_detach = false; - } - -#ifdef HAVE_UNSETENV - unsetenv("LISTEN_PID"); -#endif - init_configuration(&config_tree); /* Slllluuuuuuurrrrp! */ - if(RAND_load_file("/dev/urandom", 1024) != 1024) { - logger(LOG_ERR, "Error initializing RNG!"); + srand(time(NULL)); + crypto_init(); + + if(!read_server_config()) return 1; - } - - ENGINE_load_builtin_engines(); - ENGINE_register_all_complete(); - - OpenSSL_add_all_algorithms(); - - if(generate_keys) { - read_server_config(); - return !keygen(generate_keys); - } - - 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)) { - logger(LOG_ERR, "System call `%s' failed: %s", "WSAStartup", winerror(GetLastError())); - return 1; - } - - if(!do_detach || !init_service()) { + if(!do_detach || !init_service()) return main2(argc, argv); - } else { + else return 1; - } } int main2(int argc, char **argv) { InitializeCriticalSection(&mutex); EnterCriticalSection(&mutex); #endif - char *priority = NULL; - if(!detach()) { + if(!detach()) return 1; - } #ifdef HAVE_MLOCKALL - /* Lock all pages into memory if requested. * This has to be done after daemon()/fork() so it works for child. * No need to do that in parent as it's very short-lived. */ if(do_mlock && mlockall(MCL_CURRENT | MCL_FUTURE) != 0) { logger(LOG_ERR, "System call `%s' failed: %s", "mlockall", - strerror(errno)); + strerror(errno)); return 1; } - #endif /* Setup sockets and open device. */ - if(!setup_network()) { - goto end; - } + if(!setup_network()) + goto end_nonet; + + if(!init_control()) + goto end_nonet; /* Initiate all outgoing connections. */ @@ -764,35 +445,36 @@ int main2(int argc, char **argv) { /* Change process priority */ - if(get_config_string(lookup_config(config_tree, "ProcessPriority"), &priority)) { - if(!strcasecmp(priority, "Normal")) { - if(setpriority(NORMAL_PRIORITY_CLASS) != 0) { - logger(LOG_ERR, "System call `%s' failed: %s", - "setpriority", strerror(errno)); - goto end; - } - } else if(!strcasecmp(priority, "Low")) { - if(setpriority(BELOW_NORMAL_PRIORITY_CLASS) != 0) { - logger(LOG_ERR, "System call `%s' failed: %s", - "setpriority", strerror(errno)); - goto end; - } - } else if(!strcasecmp(priority, "High")) { - if(setpriority(HIGH_PRIORITY_CLASS) != 0) { - logger(LOG_ERR, "System call `%s' failed: %s", - "setpriority", strerror(errno)); - goto end; - } - } else { - logger(LOG_ERR, "Invalid priority `%s`!", priority); - goto end; - } - } + char *priority = NULL; + + if(get_config_string(lookup_config(config_tree, "ProcessPriority"), &priority)) { + if(!strcasecmp(priority, "Normal")) { + if (setpriority(NORMAL_PRIORITY_CLASS) != 0) { + logger(LOG_ERR, "System call `%s' failed: %s", + "setpriority", strerror(errno)); + goto end; + } + } else if(!strcasecmp(priority, "Low")) { + if (setpriority(BELOW_NORMAL_PRIORITY_CLASS) != 0) { + logger(LOG_ERR, "System call `%s' failed: %s", + "setpriority", strerror(errno)); + goto end; + } + } else if(!strcasecmp(priority, "High")) { + if (setpriority(HIGH_PRIORITY_CLASS) != 0) { + logger(LOG_ERR, "System call `%s' failed: %s", + "setpriority", strerror(errno)); + goto end; + } + } else { + logger(LOG_ERR, "Invalid priority `%s`!", priority); + goto end; + } + } /* drop privileges */ - if(!drop_privs()) { + if (!drop_privs()) goto end; - } /* Start main loop. It only exits when tinc is killed. */ @@ -801,25 +483,19 @@ int main2(int argc, char **argv) { /* Shutdown properly. */ ifdebug(CONNECTIONS) - devops.dump_stats(); + dump_device_stats(); close_network_connections(); end: + exit_control(); + +end_nonet: logger(LOG_NOTICE, "Terminating"); -#ifndef HAVE_MINGW - remove_pid(pidfilename); -#endif - - free(priority); - - EVP_cleanup(); - ERR_free_strings(); - ENGINE_cleanup(); + crypto_exit(); exit_configuration(&config_tree); - list_delete_list(cmdline_conf); free_names(); return status; diff --git a/src/top.c b/src/top.c new file mode 100644 index 0000000..f14395e --- /dev/null +++ b/src/top.c @@ -0,0 +1,319 @@ +/* + top.c -- Show real-time statistics from a running tincd + Copyright (C) 2011 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "system.h" + +#ifdef HAVE_CURSES + +#include + +#include "control_common.h" +#include "list.h" +#include "tincctl.h" +#include "top.h" +#include "xalloc.h" + +typedef struct nodestats_t { + char *name; + int i; + uint64_t in_packets; + uint64_t in_bytes; + uint64_t out_packets; + uint64_t out_bytes; + float in_packets_rate; + float in_bytes_rate; + float out_packets_rate; + float out_bytes_rate; + bool known; +} nodestats_t; + +static const char *const sortname[] = { + "name", + "in pkts", + "in bytes", + "out pkts", + "out bytes", + "tot pkts", + "tot bytes", +}; + +static int sortmode = 0; +static bool cumulative = false; + +static list_t node_list; +static struct timeval now, prev, diff; +static int delay = 1000; +static bool running = true; +static bool changed = true; +static const char *unit = "bytes"; +static float scale = 1; + +#ifndef timersub +#define timersub(a, b, c) do {(c)->tv_sec = (a)->tv_sec - (b)->tv_sec; (c)->tv_usec = (a)->tv_usec = (b)->tv_usec;} while(0) +#endif + +static void update(int fd) { + sendline(fd, "%d %d", CONTROL, REQ_DUMP_TRAFFIC); + gettimeofday(&now, NULL); + + timersub(&now, &prev, &diff); + prev = now; + float interval = diff.tv_sec + diff.tv_usec * 1e-6; + + char line[4096]; + char name[4096]; + int code; + int req; + uint64_t in_packets; + uint64_t in_bytes; + uint64_t out_packets; + uint64_t out_bytes; + + for(list_node_t *i = node_list.head; i; i = i->next) { + nodestats_t *node = i->data; + node->known = false; + } + + while(recvline(fd, line, sizeof line)) { + int n = sscanf(line, "%d %d %s %"PRIu64" %"PRIu64" %"PRIu64" %"PRIu64, &code, &req, name, &in_packets, &in_bytes, &out_packets, &out_bytes); + + if(n == 2) + break; + + if(n != 7) { + endwin(); + fprintf(stderr, "Error receiving traffic information\n"); + exit(1); + } + + nodestats_t *found = NULL; + + for(list_node_t *i = node_list.head; i; i = i->next) { + nodestats_t *node = i->data; + int result = strcmp(name, node->name); + if(result > 0) { + continue; + } if(result == 0) { + found = node; + break; + } else { + found = xmalloc_and_zero(sizeof *found); + found->name = xstrdup(name); + list_insert_before(&node_list, i, found); + changed = true; + break; + } + } + + if(!found) { + found = xmalloc_and_zero(sizeof *found); + found->name = xstrdup(name); + list_insert_tail(&node_list, found); + changed = true; + } + + found->known = true; + found->in_packets_rate = (in_packets - found->in_packets) / interval; + found->in_bytes_rate = (in_bytes - found->in_bytes) / interval; + found->out_packets_rate = (out_packets - found->out_packets) / interval; + found->out_bytes_rate = (out_bytes - found->out_bytes) / interval; + found->in_packets = in_packets; + found->in_bytes = in_bytes; + found->out_packets = out_packets; + found->out_bytes = out_bytes; + } +} + +static void redraw(void) { + erase(); + + mvprintw(0, 0, "Tinc %-16s Nodes: %4d Sort: %-10s %s", netname ?: "", node_list.count, sortname[sortmode], cumulative ? "Cumulative" : "Current"); + attrset(A_REVERSE); + mvprintw(2, 0, "Node IN pkts IN %s OUT pkts OUT %s", unit, unit); + chgat(-1, A_REVERSE, 0, NULL); + + static nodestats_t **sorted = 0; + static int n = 0; + if(changed) { + n = 0; + sorted = xrealloc(sorted, node_list.count * sizeof *sorted); + for(list_node_t *i = node_list.head; i; i = i->next) + sorted[n++] = i->data; + changed = false; + } + + for(int i = 0; i < n; i++) + sorted[i]->i = i; + + int cmpfloat(float a, float b) { + if(a < b) + return -1; + else if(a > b) + return 1; + else + return 0; + } + + int cmpu64(uint64_t a, uint64_t b) { + if(a < b) + return -1; + else if(a > b) + return 1; + else + return 0; + } + + int sortfunc(const void *a, const void *b) { + const nodestats_t *na = *(const nodestats_t **)a; + const nodestats_t *nb = *(const nodestats_t **)b; + switch(sortmode) { + case 1: + if(cumulative) + return -cmpu64(na->in_packets, nb->in_packets) ?: na->i - nb->i; + else + return -cmpfloat(na->in_packets_rate, nb->in_packets_rate) ?: na->i - nb->i; + case 2: + if(cumulative) + return -cmpu64(na->in_bytes, nb->in_bytes) ?: na->i - nb->i; + else + return -cmpfloat(na->in_bytes_rate, nb->in_bytes_rate) ?: na->i - nb->i; + case 3: + if(cumulative) + return -cmpu64(na->out_packets, nb->out_packets) ?: na->i - nb->i; + else + return -cmpfloat(na->out_packets_rate, nb->out_packets_rate) ?: na->i - nb->i; + case 4: + if(cumulative) + return -cmpu64(na->out_bytes, nb->out_bytes) ?: na->i - nb->i; + else + return -cmpfloat(na->out_bytes_rate, nb->out_bytes_rate) ?: na->i - nb->i; + case 5: + if(cumulative) + return -cmpu64(na->in_packets + na->out_packets, nb->in_packets + nb->out_packets) ?: na->i - nb->i; + else + return -cmpfloat(na->in_packets_rate + na->out_packets_rate, nb->in_packets_rate + nb->out_packets_rate) ?: na->i - nb->i; + case 6: + if(cumulative) + return -cmpu64(na->in_bytes + na->out_bytes, nb->in_bytes + nb->out_bytes) ?: na->i - nb->i; + else + return -cmpfloat(na->in_bytes_rate + na->out_bytes_rate, nb->in_bytes_rate + nb->out_bytes_rate) ?: na->i - nb->i; + default: + return strcmp(na->name, nb->name) ?: na->i - nb->i; + } + } + + qsort(sorted, n, sizeof *sorted, sortfunc); + + for(int i = 0, row = 3; i < n; i++, row++) { + nodestats_t *node = sorted[i]; + if(node->known) + if(node->in_packets_rate || node->out_packets_rate) + attrset(A_BOLD); + else + attrset(A_NORMAL); + else + attrset(A_DIM); + + if(cumulative) + mvprintw(row, 0, "%-16s %10"PRIu64" %10.0f %10"PRIu64" %10.0f", + node->name, node->in_packets, node->in_bytes * scale, node->out_packets, node->out_bytes * scale); + else + mvprintw(row, 0, "%-16s %10.0f %10.0f %10.0f %10.0f", + node->name, node->in_packets_rate, node->in_bytes_rate * scale, node->out_packets_rate, node->out_bytes_rate * scale); + } + + attrset(A_NORMAL); + move(1, 0); + + refresh(); +} + +void top(int fd) { + initscr(); + timeout(delay); + + while(running) { + update(fd); + redraw(); + + switch(getch()) { + case 's': { + timeout(-1); + float input = delay * 1e-3; + mvprintw(1, 0, "Change delay from %.1fs to: ", input); + scanw("%f", &input); + if(input < 0.1) + input = 0.1; + delay = input * 1e3; + timeout(delay); + break; + } + case 'c': + cumulative = !cumulative; + break; + case 'n': + sortmode = 0; + break; + case 'i': + sortmode = 2; + break; + case 'I': + sortmode = 1; + break; + case 'o': + sortmode = 4; + break; + case 'O': + sortmode = 3; + break; + case 't': + sortmode = 6; + break; + case 'T': + sortmode = 5; + break; + case 'b': + unit = "bytes"; + scale = 1; + break; + case 'k': + unit = "kbyte"; + scale = 1e-3; + break; + case 'M': + unit = "Mbyte"; + scale = 1e-6; + break; + case 'G': + unit = "Gbyte"; + scale = 1e-9; + break; + case 'q': + case KEY_BREAK: + running = false; + break; + default: + break; + } + } + + endwin(); +} + +#endif diff --git a/src/top.h b/src/top.h new file mode 100644 index 0000000..b3a264d --- /dev/null +++ b/src/top.h @@ -0,0 +1,26 @@ +/* + top.h -- header for top.c. + Copyright (C) 2011 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#ifndef __TINC_TOP_H__ +#define __TINC_TOP_H__ + +extern void top(int fd); + +#endif + diff --git a/src/uml_device.c b/src/uml_socket/device.c similarity index 53% rename from src/uml_device.c rename to src/uml_socket/device.c index 66de431..d8f13a5 100644 --- a/src/uml_device.c +++ b/src/uml_socket/device.c @@ -1,7 +1,7 @@ /* device.c -- UML network socket Copyright (C) 2002-2005 Ivo Timmermans, - 2002-2012 Guus Sliepen + 2002-2009 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 @@ -28,17 +28,19 @@ #include "logger.h" #include "utils.h" #include "route.h" -#include "xalloc.h" +int device_fd = -1; static int listen_fd = -1; static int request_fd = -1; static int data_fd = -1; static int write_fd = -1; static int state = 0; -static const char *device_info = "UML network socket"; +char *device = NULL; +char *iface = NULL; +static char *device_info; extern char *identname; -extern volatile bool running; +extern bool running; static uint64_t device_total_in = 0; static uint64_t device_total_out = 0; @@ -46,15 +48,15 @@ static uint64_t device_total_out = 0; enum request_type { REQ_NEW_CONTROL }; static struct request { - uint32_t magic; - uint32_t version; - enum request_type type; - struct sockaddr_un sock; + uint32_t magic; + uint32_t version; + enum request_type type; + struct sockaddr_un sock; } request; static struct sockaddr_un data_sun; -static bool setup_device(void) { +bool setup_device(void) { struct sockaddr_un listen_sun; static const int one = 1; struct { @@ -64,23 +66,20 @@ static bool setup_device(void) { } name; struct timeval tv; - if(!get_config_string(lookup_config(config_tree, "Device"), &device)) { - xasprintf(&device, RUNSTATEDIR "/%s.umlsocket", identname); - } + if(!get_config_string(lookup_config(config_tree, "Device"), &device)) + xasprintf(&device, LOCALSTATEDIR "/run/%s.umlsocket", identname); get_config_string(lookup_config(config_tree, "Interface"), &iface); + device_info = "UML network socket"; + if((write_fd = socket(PF_UNIX, SOCK_DGRAM, 0)) < 0) { logger(LOG_ERR, "Could not open write %s: %s", device_info, strerror(errno)); running = false; return false; } -#ifdef FD_CLOEXEC - fcntl(write_fd, F_SETFD, FD_CLOEXEC); -#endif - - setsockopt(write_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)); + setsockopt(write_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof one); if(fcntl(write_fd, F_SETFL, O_NONBLOCK) < 0) { logger(LOG_ERR, "System call `%s' failed: %s", "fcntl", strerror(errno)); @@ -94,11 +93,7 @@ static bool setup_device(void) { return false; } -#ifdef FD_CLOEXEC - fcntl(data_fd, F_SETFD, FD_CLOEXEC); -#endif - - setsockopt(data_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)); + setsockopt(data_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof one); if(fcntl(data_fd, F_SETFL, O_NONBLOCK) < 0) { logger(LOG_ERR, "System call `%s' failed: %s", "fcntl", strerror(errno)); @@ -111,9 +106,9 @@ static bool setup_device(void) { gettimeofday(&tv, NULL); name.usecs = tv.tv_usec; data_sun.sun_family = AF_UNIX; - memcpy(&data_sun.sun_path, &name, sizeof(name)); - - if(bind(data_fd, (struct sockaddr *)&data_sun, sizeof(data_sun)) < 0) { + memcpy(&data_sun.sun_path, &name, sizeof name); + + if(bind(data_fd, (struct sockaddr *)&data_sun, sizeof data_sun) < 0) { logger(LOG_ERR, "Could not bind data %s: %s", device_info, strerror(errno)); running = false; return false; @@ -121,15 +116,11 @@ static bool setup_device(void) { if((listen_fd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) { logger(LOG_ERR, "Could not open %s: %s", device_info, - strerror(errno)); + strerror(errno)); return false; } -#ifdef FD_CLOEXEC - fcntl(device_fd, F_SETFD, FD_CLOEXEC); -#endif - - setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)); + setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof one); if(fcntl(listen_fd, F_SETFL, O_NONBLOCK) < 0) { logger(LOG_ERR, "System call `%s' failed: %s", "fcntl", strerror(errno)); @@ -137,9 +128,8 @@ static bool setup_device(void) { } listen_sun.sun_family = AF_UNIX; - strncpy(listen_sun.sun_path, device, sizeof(listen_sun.sun_path)); - - if(bind(listen_fd, (struct sockaddr *)&listen_sun, sizeof(listen_sun)) < 0) { + strncpy(listen_sun.sun_path, device, sizeof listen_sun.sun_path); + if(bind(listen_fd, (struct sockaddr *)&listen_sun, sizeof listen_sun) < 0) { logger(LOG_ERR, "Could not bind %s to %s: %s", device_info, device, strerror(errno)); return false; } @@ -154,132 +144,118 @@ static bool setup_device(void) { logger(LOG_INFO, "%s is a %s", device, device_info); - if(routing_mode == RMODE_ROUTER) { + if(routing_mode == RMODE_ROUTER) overwrite_mac = true; - } return true; } void close_device(void) { - if(listen_fd >= 0) { + if(listen_fd >= 0) close(listen_fd); - } - if(request_fd >= 0) { + if(request_fd >= 0) close(request_fd); - } - if(data_fd >= 0) { + if(data_fd >= 0) close(data_fd); - } - if(write_fd >= 0) { + if(write_fd >= 0) close(write_fd); - } unlink(device); free(device); - free(iface); + if(iface) free(iface); } -static bool read_packet(vpn_packet_t *packet) { - int lenin; +bool read_packet(vpn_packet_t *packet) { + int inlen; switch(state) { - case 0: { - struct sockaddr sa; - socklen_t salen = sizeof(sa); + case 0: { + struct sockaddr sa; + int salen = sizeof sa; - request_fd = accept(listen_fd, &sa, &salen); + request_fd = accept(listen_fd, &sa, &salen); + if(request_fd < 0) { + logger(LOG_ERR, "Could not accept connection to %s %s: %s", device_info, device, strerror(errno)); + return false; + } + + if(fcntl(listen_fd, F_SETFL, O_NONBLOCK) < 0) { + logger(LOG_ERR, "System call `%s' failed: %s", "fcntl", strerror(errno)); + running = false; + return false; + } + + close(listen_fd); + listen_fd = -1; + device_fd = request_fd; + state = 1; - if(request_fd < 0) { - logger(LOG_ERR, "Could not accept connection to %s %s: %s", device_info, device, strerror(errno)); return false; } -#ifdef FD_CLOEXEC - fcntl(request_fd, F_SETFD, FD_CLOEXEC); -#endif + case 1: { + if((inlen = read(request_fd, &request, sizeof request)) != sizeof request) { + logger(LOG_ERR, "Error while reading request from %s %s: %s", device_info, + device, strerror(errno)); + running = false; + return false; + } - if(fcntl(listen_fd, F_SETFL, O_NONBLOCK) < 0) { - logger(LOG_ERR, "System call `%s' failed: %s", "fcntl", strerror(errno)); - running = false; + if(request.magic != 0xfeedface || request.version != 3 || request.type != REQ_NEW_CONTROL) { + logger(LOG_ERR, "Unknown magic %x, version %d, request type %d from %s %s", + request.magic, request.version, request.type, device_info, device); + running = false; + return false; + } + + if(connect(write_fd, &request.sock, sizeof request.sock) < 0) { + logger(LOG_ERR, "Could not bind write %s: %s", device_info, strerror(errno)); + running = false; + return false; + } + + write(request_fd, &data_sun, sizeof data_sun); + device_fd = data_fd; + + logger(LOG_INFO, "Connection with UML established"); + + state = 2; return false; } - close(listen_fd); - listen_fd = -1; - device_fd = request_fd; - state = 1; + case 2: { + if((inlen = read(data_fd, packet->data, MTU)) <= 0) { + logger(LOG_ERR, "Error while reading from %s %s: %s", device_info, + device, strerror(errno)); + running = false; + return false; + } - return false; - } + packet->len = inlen; - case 1: { - if((lenin = read(request_fd, &request, sizeof(request))) != sizeof request) { - logger(LOG_ERR, "Error while reading request from %s %s: %s", device_info, - device, strerror(errno)); - running = false; - return false; + device_total_in += packet->len; + + ifdebug(TRAFFIC) logger(LOG_DEBUG, "Read packet of %d bytes from %s", packet->len, + device_info); + + return true; } - - if(request.magic != 0xfeedface || request.version != 3 || request.type != REQ_NEW_CONTROL) { - logger(LOG_ERR, "Unknown magic %x, version %d, request type %d from %s %s", - request.magic, request.version, request.type, device_info, device); - running = false; - return false; - } - - if(connect(write_fd, (struct sockaddr *)&request.sock, sizeof(request.sock)) < 0) { - logger(LOG_ERR, "Could not bind write %s: %s", device_info, strerror(errno)); - running = false; - return false; - } - - write(request_fd, &data_sun, sizeof(data_sun)); - device_fd = data_fd; - - logger(LOG_INFO, "Connection with UML established"); - - state = 2; - return false; - } - - case 2: { - if((lenin = read(data_fd, packet->data, MTU)) <= 0) { - logger(LOG_ERR, "Error while reading from %s %s: %s", device_info, - device, strerror(errno)); - running = false; - return false; - } - - packet->len = lenin; - - device_total_in += packet->len; - - ifdebug(TRAFFIC) logger(LOG_DEBUG, "Read packet of %d bytes from %s", packet->len, - device_info); - - return true; - } - - default: - logger(LOG_ERR, "Invalid value for state variable in " __FILE__); - abort(); } } -static bool write_packet(vpn_packet_t *packet) { +bool write_packet(vpn_packet_t *packet) { if(state != 2) { ifdebug(TRAFFIC) logger(LOG_DEBUG, "Dropping packet of %d bytes to %s: not connected to UML yet", - packet->len, device_info); + packet->len, device_info); return false; } ifdebug(TRAFFIC) logger(LOG_DEBUG, "Writing packet of %d bytes to %s", - packet->len, device_info); + packet->len, device_info); if(write(write_fd, packet->data, packet->len) < 0) { if(errno != EINTR && errno != EAGAIN) { @@ -295,16 +271,8 @@ static bool write_packet(vpn_packet_t *packet) { return true; } -static void dump_device_stats(void) { +void dump_device_stats(void) { logger(LOG_DEBUG, "Statistics for %s %s:", device_info, device); logger(LOG_DEBUG, " total bytes in: %10"PRIu64, device_total_in); logger(LOG_DEBUG, " total bytes out: %10"PRIu64, device_total_out); } - -const devops_t uml_devops = { - .setup = setup_device, - .close = close_device, - .read = read_packet, - .write = write_packet, - .dump_stats = dump_device_stats, -}; diff --git a/src/utils.c b/src/utils.c index 70a5c99..022ac25 100644 --- a/src/utils.c +++ b/src/utils.c @@ -1,7 +1,7 @@ /* utils.c -- gathering of some stupid small functions Copyright (C) 1999-2005 Ivo Timmermans - 2000-2014 Guus Sliepen + 2000-2009 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 @@ -24,34 +24,111 @@ #include "utils.h" static const char hexadecimals[] = "0123456789ABCDEF"; +static const char base64imals[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; static int charhex2bin(char c) { - if(isdigit(c)) { + if(isdigit(c)) return c - '0'; - } else { + else return toupper(c) - 'A' + 10; - } } -bool hex2bin(char *src, char *dst, int length) { - for(int i = 0; i < length; i++) { - if(!isxdigit(src[i * 2]) || !isxdigit(src[i * 2 + 1])) { - return false; - } - - dst[i] = charhex2bin(src[i * 2]) * 16 + charhex2bin(src[i * 2 + 1]); - } - - return true; +static int charb64decode(char c) { + if(c >= 'a') + return c - 'a' + 26; + else if(c >= 'A') + return c - 'A'; + else if(c >= '0') + return c - '0' + 52; + else if(c == '+') + return 62; + else + return 63; } -void bin2hex(char *src, char *dst, int length) { +int hex2bin(const char *src, char *dst, int length) { int i; + for(i = 0; i < length && src[i * 2] && src[i * 2 + 1]; i++) + dst[i] = charhex2bin(src[i * 2]) * 16 + charhex2bin(src[i * 2 + 1]); + return i; +} +int bin2hex(const char *src, char *dst, int length) { + int i; for(i = length - 1; i >= 0; i--) { dst[i * 2 + 1] = hexadecimals[(unsigned char) src[i] & 15]; dst[i * 2] = hexadecimals[(unsigned char) src[i] >> 4]; } + dst[length * 2] = 0; + return length * 2; +} + +int b64decode(const char *src, char *dst, int length) { + int i; + uint32_t triplet = 0; + unsigned char *udst = dst; + + for(i = 0; i < length / 3 * 4 && src[i]; i++) { + triplet |= charb64decode(src[i]) << (6 * (i & 3)); + if((i & 3) == 3) { + udst[0] = triplet & 0xff; triplet >>= 8; + udst[1] = triplet & 0xff; triplet >>= 8; + udst[2] = triplet; + triplet = 0; + udst += 3; + } + } + if((i & 3) == 3) { + udst[0] = triplet & 0xff; triplet >>= 8; + udst[1] = triplet & 0xff; + return i / 4 * 3 + 2; + } else if((i & 3) == 2) { + udst[0] = triplet & 0xff; + return i / 4 * 3 + 1; + } else { + return i / 4 * 3; + } +} + +int b64encode(const char *src, char *dst, int length) { + uint32_t triplet; + const unsigned char *usrc = src; + int si = length / 3 * 3; + int di = length / 3 * 4; + + switch(length % 3) { + case 2: + triplet = usrc[si] | usrc[si + 1] << 8; + dst[di] = base64imals[triplet & 63]; triplet >>= 6; + dst[di + 1] = base64imals[triplet & 63]; triplet >>= 6; + dst[di + 2] = base64imals[triplet]; + dst[di + 3] = 0; + length = di + 2; + break; + case 1: + triplet = usrc[si]; + dst[di] = base64imals[triplet & 63]; triplet >>= 6; + dst[di + 1] = base64imals[triplet]; + dst[di + 2] = 0; + length = di + 1; + break; + default: + dst[di] = 0; + length = di; + break; + } + + while(si > 0) { + di -= 4; + si -= 3; + triplet = usrc[si] | usrc[si + 1] << 8 | usrc[si + 2] << 16; + dst[di] = base64imals[triplet & 63]; triplet >>= 6; + dst[di + 1] = base64imals[triplet & 63]; triplet >>= 6; + dst[di + 2] = base64imals[triplet & 63]; triplet >>= 6; + dst[di + 3] = base64imals[triplet]; + } + + return length; } #if defined(HAVE_MINGW) || defined(HAVE_CYGWIN) @@ -60,18 +137,15 @@ void bin2hex(char *src, char *dst, int length) { #endif const char *winerror(int err) { - static char buf[1024], *ptr; + static char buf[1024], *newline; - ptr = buf + sprintf(buf, "(%d) ", err); - - if(!FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), ptr, sizeof(buf) - (ptr - buf), NULL)) { - strcpy(ptr, "(unable to format errormessage)"); + if (!FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), buf, sizeof(buf), NULL)) { + strncpy(buf, "(unable to format errormessage)", sizeof(buf)); }; - if((ptr = strchr(buf, '\r'))) { - *ptr = '\0'; - } + if((newline = strchr(buf, '\r'))) + *newline = '\0'; return buf; } @@ -79,27 +153,8 @@ const char *winerror(int err) { unsigned int bitfield_to_int(const void *bitfield, size_t size) { unsigned int value = 0; - - if(size > sizeof(value)) { - size = sizeof(value); - } - + if(size > sizeof value) + size = sizeof value; memcpy(&value, bitfield, size); return value; } - -/** - * As memcmp(), but constant-time. - * Returns 0 when data is equal, non-zero otherwise. - */ -int memcmp_constant_time(const void *a, const void *b, size_t size) { - const uint8_t *a1 = a, *b1 = b; - int ret = 0; - size_t i; - - for(i = 0; i < size; i++) { - ret |= *a1++ ^ *b1++; - } - - return ret; -} diff --git a/src/utils.h b/src/utils.h index 7952025..67c94f3 100644 --- a/src/utils.h +++ b/src/utils.h @@ -1,10 +1,7 @@ -#ifndef TINC_UTILS_H -#define TINC_UTILS_H - /* utils.h -- header file for utils.c Copyright (C) 1999-2005 Ivo Timmermans - 2000-2014 Guus Sliepen + 2000-2009 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 @@ -21,30 +18,33 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -extern bool hex2bin(char *src, char *dst, int length); -extern void bin2hex(char *src, char *dst, int length); +#ifndef __TINC_UTILS_H__ +#define __TINC_UTILS_H__ -#if defined(HAVE_MINGW) || defined(HAVE_CYGWIN) -extern const char *winerror(int); -#endif +extern int hex2bin(const char *src, char *dst, int length); +extern int bin2hex(const char *src, char *dst, int length); + +extern int b64encode(const char *src, char *dst, int length); +extern int b64decode(const char *src, char *dst, int length); #ifdef HAVE_MINGW +extern const char *winerror(int); #define strerror(x) ((x)>0?strerror(x):winerror(GetLastError())) #define sockerrno WSAGetLastError() #define sockstrerror(x) winerror(x) #define sockwouldblock(x) ((x) == WSAEWOULDBLOCK || (x) == WSAEINTR) #define sockmsgsize(x) ((x) == WSAEMSGSIZE) #define sockinprogress(x) ((x) == WSAEINPROGRESS || (x) == WSAEWOULDBLOCK) +#define sockinuse(x) ((x) == WSAEADDRINUSE) #else #define sockerrno errno #define sockstrerror(x) strerror(x) #define sockwouldblock(x) ((x) == EWOULDBLOCK || (x) == EINTR) #define sockmsgsize(x) ((x) == EMSGSIZE) #define sockinprogress(x) ((x) == EINPROGRESS) +#define sockinuse(x) ((x) == EADDRINUSE) #endif extern unsigned int bitfield_to_int(const void *bitfield, size_t size); -int memcmp_constant_time(const void *a, const void *b, size_t size); - -#endif +#endif /* __TINC_UTILS_H__ */ diff --git a/src/vde_device.c b/src/vde_device.c deleted file mode 100644 index 6d854a6..0000000 --- a/src/vde_device.c +++ /dev/null @@ -1,147 +0,0 @@ -/* - device.c -- VDE plug - Copyright (C) 2012 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 - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include "system.h" - -#include - -#include "conf.h" -#include "device.h" -#include "net.h" -#include "logger.h" -#include "utils.h" -#include "route.h" -#include "xalloc.h" - -static struct vdepluglib plug; -static struct vdeconn *conn = NULL; -static int port = 0; -static char *group = NULL; -static const char *device_info = "VDE socket"; - -extern char *identname; -extern volatile bool running; - -static uint64_t device_total_in = 0; -static uint64_t device_total_out = 0; - -static bool setup_device(void) { - libvdeplug_dynopen(plug); - - if(!plug.dl_handle) { - logger(LOG_ERR, "Could not open libvdeplug library!"); - return false; - } - - if(!get_config_string(lookup_config(config_tree, "Device"), &device)) { - xasprintf(&device, RUNSTATEDIR "/vde.ctl"); - } - - get_config_string(lookup_config(config_tree, "Interface"), &iface); - - get_config_int(lookup_config(config_tree, "VDEPort"), &port); - - get_config_string(lookup_config(config_tree, "VDEGroup"), &group); - - struct vde_open_args args = { - .port = port, - .group = group, - .mode = 0700, - }; - - conn = plug.vde_open(device, identname, &args); - - if(!conn) { - logger(LOG_ERR, "Could not open VDE socket %s", device); - return false; - } - - device_fd = plug.vde_datafd(conn); - -#ifdef FD_CLOEXEC - fcntl(device_fd, F_SETFD, FD_CLOEXEC); -#endif - - logger(LOG_INFO, "%s is a %s", device, device_info); - - if(routing_mode == RMODE_ROUTER) { - overwrite_mac = true; - } - - return true; -} - -static void close_device(void) { - if(conn) { - plug.vde_close(conn); - } - - if(plug.dl_handle) { - libvdeplug_dynclose(plug); - } - - free(device); - - free(iface); -} - -static bool read_packet(vpn_packet_t *packet) { - int lenin = (ssize_t)plug.vde_recv(conn, packet->data, MTU, 0); - - if(lenin <= 0) { - logger(LOG_ERR, "Error while reading from %s %s: %s", device_info, device, strerror(errno)); - running = false; - return false; - } - - packet->len = lenin; - device_total_in += packet->len; - ifdebug(TRAFFIC) logger(LOG_DEBUG, "Read packet of %d bytes from %s", packet->len, device_info); - - return true; -} - -static bool write_packet(vpn_packet_t *packet) { - if((ssize_t)plug.vde_send(conn, packet->data, packet->len, 0) < 0) { - if(errno != EINTR && errno != EAGAIN) { - logger(LOG_ERR, "Can't write to %s %s: %s", device_info, device, strerror(errno)); - running = false; - } - - return false; - } - - device_total_out += packet->len; - - return true; -} - -static void dump_device_stats(void) { - logger(LOG_DEBUG, "Statistics for %s %s:", device_info, device); - logger(LOG_DEBUG, " total bytes in: %10"PRIu64, device_total_in); - logger(LOG_DEBUG, " total bytes out: %10"PRIu64, device_total_out); -} - -const devops_t vde_devops = { - .setup = setup_device, - .close = close_device, - .read = read_packet, - .write = write_packet, - .dump_stats = dump_device_stats, -}; diff --git a/src/xalloc.h b/src/xalloc.h index cda0871..42d0d95 100644 --- a/src/xalloc.h +++ b/src/xalloc.h @@ -1,10 +1,7 @@ -#ifndef TINC_XALLOC_H -#define TINC_XALLOC_H - /* - xalloc.h -- malloc and related functions with out of memory checking + xalloc.h -- malloc and related fuctions with out of memory checking Copyright (C) 1990, 91, 92, 93, 94, 95, 96, 97 Free Software Foundation, Inc. - Copyright (C) 2011-2017 Guus Sliepen + Copyright (C) 2011 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 @@ -18,74 +15,46 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., Foundation, - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ + +#ifndef __TINC_XALLOC_H__ +#define __TINC_XALLOC_H__ -static inline void *xmalloc(size_t n) __attribute__((__malloc__)); static inline void *xmalloc(size_t n) { void *p = malloc(n); - - if(!p) { + if(!p) abort(); - } - return p; } -static inline void *xmalloc_and_zero(size_t n) __attribute__((__malloc__)); static inline void *xmalloc_and_zero(size_t n) { void *p = calloc(1, n); - - if(!p) { + if(!p) abort(); - } - return p; } static inline void *xrealloc(void *p, size_t n) { p = realloc(p, n); - - if(!p) { + if(!p) abort(); - } - return p; } -static inline char *xstrdup(const char *s) __attribute__((__malloc__)); static inline char *xstrdup(const char *s) { char *p = strdup(s); - - if(!p) { + if(!p) abort(); - } - return p; } static inline int xvasprintf(char **strp, const char *fmt, va_list ap) { -#ifdef HAVE_MINGW - char buf[1024]; - int result = vsnprintf(buf, sizeof(buf), fmt, ap); - - if(result < 0) { - abort(); - } - - *strp = xstrdup(buf); -#else int result = vasprintf(strp, fmt, ap); - - if(result < 0) { + if(result < 0) abort(); - } - -#endif return result; } -static inline int xasprintf(char **strp, const char *fmt, ...) __attribute__((__format__(printf, 2, 3))); static inline int xasprintf(char **strp, const char *fmt, ...) { va_list ap; va_start(ap, fmt); diff --git a/src/system.h b/system.h similarity index 85% rename from src/system.h rename to system.h index 14db7f5..5dc1daf 100644 --- a/src/system.h +++ b/system.h @@ -1,6 +1,3 @@ -#ifndef TINC_SYSTEM_H -#define TINC_SYSTEM_H - /* system.h -- system headers Copyright (C) 1998-2005 Ivo Timmermans @@ -21,20 +18,29 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +#ifndef __TINC_SYSTEM_H__ +#define __TINC_SYSTEM_H__ + #include "config.h" #include "have.h" +#ifndef HAVE_STDBOOL_H +typedef int bool; +#define true 1 +#define false 0 +#endif + #ifndef HAVE_STRSIGNAL # define strsignal(p) "" #endif /* Other functions */ -#include "dropin.h" +#include "src/dropin.h" #ifndef HAVE_SOCKLEN_T typedef int socklen_t; #endif -#endif +#endif /* __TINC_SYSTEM_H__ */ diff --git a/systemd/Makefile.am b/systemd/Makefile.am deleted file mode 100644 index dac2b73..0000000 --- a/systemd/Makefile.am +++ /dev/null @@ -1,18 +0,0 @@ -EXTRA_DIST = tinc.service.in tinc@.service.in - -CLEANFILES = tinc.service tinc@.service - -if WITH_SYSTEMD -systemddir = @systemd_path@ -nodist_systemd_DATA = tinc.service tinc@.service -endif - -substitute = sed \ - -e s,'@sbindir\@',"$(sbindir)",g \ - -e s,'@sysconfdir\@',"$(sysconfdir)",g - -tinc.service: $(srcdir)/tinc.service.in - $(AM_V_GEN)$(substitute) $(srcdir)/tinc.service.in > $@ - -tinc@.service: $(srcdir)/tinc@.service.in - $(AM_V_GEN)$(substitute) $(srcdir)/tinc@.service.in > $@ diff --git a/systemd/tinc.service.in b/systemd/tinc.service.in deleted file mode 100644 index b671042..0000000 --- a/systemd/tinc.service.in +++ /dev/null @@ -1,20 +0,0 @@ -# This is a mostly empty service, but allows commands like stop, start, reload -# to propagate to all tinc@ service instances. - -[Unit] -Description=Tinc VPN -Documentation=info:tinc -Documentation=man:tinc(8) man:tinc.conf(5) -Documentation=http://tinc-vpn.org/docs/ -After=network.target -Wants=network.target - -[Service] -Type=oneshot -RemainAfterExit=yes -ExecStart=/bin/true -ExecReload=/bin/true -WorkingDirectory=@sysconfdir@/tinc - -[Install] -WantedBy=multi-user.target diff --git a/systemd/tinc@.service.in b/systemd/tinc@.service.in deleted file mode 100644 index 8fbf551..0000000 --- a/systemd/tinc@.service.in +++ /dev/null @@ -1,20 +0,0 @@ -[Unit] -Description=Tinc net %i -Documentation=info:tinc -Documentation=man:tinc(8) man:tinc.conf(5) -Documentation=http://tinc-vpn.org/docs/ -PartOf=tinc.service -ReloadPropagatedFrom=tinc.service - -[Service] -Type=simple -WorkingDirectory=@sysconfdir@/tinc/%i -ExecStart=@sbindir@/tincd -n %i -D -ExecReload=@sbindir@/tincd -n %i -kHUP -KillMode=mixed -Restart=on-failure -RestartSec=5 -TimeoutStopSec=5 - -[Install] -WantedBy=tinc.service From 34d5939212de8fba502a3399d561a8e0533b1349 Mon Sep 17 00:00:00 2001 From: Guus Sliepen Date: Mon, 26 Aug 2019 13:44:49 +0200 Subject: [PATCH 02/13] Import Upstream version 1.1~pre3 --- COPYING | 2 +- ChangeLog | 1976 ++++++++++++++++ INSTALL | 9 +- Makefile.in | 122 +- NEWS | 70 +- README | 88 +- THANKS | 7 + aclocal.m4 | 79 +- config.guess | 49 +- config.h.in | 33 + config.sub | 74 +- configure | 475 +++- configure.in | 54 +- depcomp | 190 +- doc/Makefile.am | 18 +- doc/Makefile.in | 152 +- doc/sample-config.tar.gz | Bin 1246 -> 1237 bytes doc/texinfo.tex | 2056 +++++++++++------ doc/tinc.conf.5.in | 279 ++- doc/tinc.info | 815 +++++-- doc/tinc.texi | 500 +++- doc/tincctl.8.in | 76 +- doc/tincd.8.in | 21 +- gui/Makefile.in | 60 +- gui/tinc-gui | 183 +- have.h | 9 +- install-sh | 29 +- m4/Makefile.in | 45 +- m4/openssl.m4 | 4 +- m4/readline.m4 | 42 + missing | 53 +- src/Makefile.am | 29 +- src/Makefile.in | 150 +- src/bsd/device.c | 97 +- src/bsd/tunemu.c | 26 +- src/bsd/tunemu.h | 8 +- src/buffer.c | 2 +- src/cipher.c | 218 ++ src/conf.c | 132 +- src/conf.h | 9 +- src/connection.c | 58 +- src/connection.h | 96 +- src/control.c | 28 +- src/control_common.h | 4 +- src/crypto.c | 43 + src/cygwin/device.c | 66 +- src/device.h | 26 +- src/digest.c | 127 + src/dropin.c | 6 +- src/dropin.h | 2 +- src/dummy_device.c | 62 + src/ecdh.c | 96 + src/ecdsa.c | 130 ++ src/edge.c | 21 +- src/edge.h | 14 +- src/ethernet.h | 18 +- src/fake-gai-errnos.h | 6 +- src/fake-getaddrinfo.c | 10 +- src/fake-getaddrinfo.h | 21 +- src/fake-getnameinfo.c | 4 +- src/fake-getnameinfo.h | 3 +- src/gcrypt/cipher.c | 24 +- src/gcrypt/cipher.h | 2 +- src/gcrypt/crypto.h | 2 +- src/gcrypt/digest.c | 10 +- src/gcrypt/digest.h | 2 +- src/gcrypt/rsa.c | 20 +- src/gcrypt/rsagen.c | 10 +- src/graph.c | 223 +- src/graph.h | 2 +- src/hash.c | 105 + src/hash.h | 41 + src/info.c | 266 +++ src/info.h | 27 + src/ipv4.h | 12 +- src/ipv6.h | 10 +- src/linux/device.c | 74 +- src/list.c | 42 +- src/list.h | 8 +- src/logger.c | 147 +- src/logger.h | 43 +- src/meta.c | 94 +- src/meta.h | 6 +- src/mingw/device.c | 50 +- src/multicast_device.c | 235 ++ src/net.c | 231 +- src/net.h | 62 +- src/net_packet.c | 444 +++- src/net_setup.c | 716 ++++-- src/net_socket.c | 476 ++-- src/netutl.c | 93 +- src/netutl.h | 8 +- src/node.c | 86 +- src/node.h | 78 +- src/openssl/cipher.c | 96 +- src/openssl/cipher.h | 6 +- src/openssl/crypto.c | 8 +- src/openssl/digest.c | 15 +- src/openssl/digest.h | 3 +- src/openssl/ecdh.c | 40 +- src/openssl/ecdsa.c | 32 +- src/openssl/ecdsagen.c | 2 +- src/openssl/prf.c | 19 +- src/openssl/prf.h | 2 +- src/openssl/rsa.c | 33 +- src/openssl/rsa.h | 2 +- src/prf.c | 75 + src/process.c | 117 +- src/process.h | 4 +- src/protocol.c | 96 +- src/protocol.h | 61 +- src/protocol_auth.c | 348 ++- src/protocol_edge.c | 37 +- src/protocol_key.c | 399 ++-- src/protocol_misc.c | 34 +- src/protocol_subnet.c | 36 +- .../device.c => raw_socket_device.c} | 70 +- src/route.c | 301 ++- src/route.h | 12 +- src/solaris/device.c | 67 +- src/splay_tree.c | 36 +- src/splay_tree.h | 4 +- src/sptps.c | 662 ++++++ src/sptps.h | 94 + src/sptps_test.c | 194 ++ src/subnet.c | 341 +-- src/subnet.h | 18 +- src/subnet_parse.c | 382 +++ src/tincctl.c | 1938 +++++++++++++--- src/tincd.c | 200 +- src/top.c | 25 +- src/{uml_socket/device.c => uml_device.c} | 96 +- src/utils.c | 25 +- src/utils.h | 4 +- src/vde_device.c | 143 ++ system.h | 2 +- 136 files changed, 13943 insertions(+), 4867 deletions(-) create mode 100644 m4/readline.m4 create mode 100644 src/cipher.c create mode 100644 src/crypto.c create mode 100644 src/digest.c create mode 100644 src/dummy_device.c create mode 100644 src/ecdh.c create mode 100644 src/ecdsa.c create mode 100644 src/hash.c create mode 100644 src/hash.h create mode 100644 src/info.c create mode 100644 src/info.h create mode 100644 src/multicast_device.c create mode 100644 src/prf.c rename src/{raw_socket/device.c => raw_socket_device.c} (57%) create mode 100644 src/sptps.c create mode 100644 src/sptps.h create mode 100644 src/sptps_test.c create mode 100644 src/subnet_parse.c rename src/{uml_socket/device.c => uml_device.c} (62%) create mode 100644 src/vde_device.c diff --git a/COPYING b/COPYING index 74fe22a..85c729f 100644 --- a/COPYING +++ b/COPYING @@ -1,4 +1,4 @@ -Copyright (C) 1998-2010 Ivo Timmermans, Guus Sliepen and others. +Copyright (C) 1998-2012 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/ChangeLog b/ChangeLog index 859f691..831cb4e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,1953 @@ +commit 0db9e471ea53b48687ea247c855cd95ec453530c +Author: Guus Sliepen +Date: Sun Oct 14 19:22:30 2012 +0200 + + Releasing 1.1pre3. + +commit 3254e75afe0ff28fed68d8682f61c184f442161d +Author: Guus Sliepen +Date: Sun Oct 14 19:21:13 2012 +0200 + + Fix a few compiler errors/warnings. + +commit 70a1a5594af5d4e6a364186b42ba4e34c676009b +Author: Guus Sliepen +Date: Sun Oct 14 17:42:49 2012 +0200 + + Update copyright notices. + +commit 4200a378c4fedf64e89b9f8481d7cd09dac14965 +Author: Guus Sliepen +Date: Sun Oct 14 16:39:16 2012 +0200 + + Fix compile error on Windows. + +commit 368727c3dac4a1f8343e2e0eccf5bc62d9b197e2 +Author: Guus Sliepen +Date: Sun Oct 14 16:07:35 2012 +0200 + + tincctl: add node colors and edge weight to graph dump. + +commit 40ed0c07dd3d4667054b0f5952b89ee39686493b +Author: Guus Sliepen +Date: Sun Oct 14 15:37:24 2012 +0200 + + Log more messages using logger(). + +commit b234304b6628aeddce63d7f751da97c3344bbb78 +Author: Guus Sliepen +Date: Sun Oct 14 14:48:35 2012 +0200 + + Make sure the ReplayWindow option works for SPTPS as well. + +commit ee1d655f2f1ede6da66b6268974d6f9585c616b3 +Author: Guus Sliepen +Date: Sun Oct 14 14:45:27 2012 +0200 + + Only log success of initial datagram SPTPS handshake. + +commit 44a24f63acc70d19904e5540986b8301b3c9b882 +Author: Guus Sliepen +Date: Sun Oct 14 14:33:54 2012 +0200 + + Fix handling of initial datagram SPTPS packet. + + Only the very first packet of an SPTPS session should be send with REQ_KEY, + this signals the peer to abort any previous session and start a new one as + well. + +commit ec1f7e525d046bcaeb8e7040b8cec9a34a568371 +Author: Sven-Haegar Koch +Date: Fri Oct 12 17:08:01 2012 +0200 + + sptps.c: Add missing newline to log message. + +commit 94ec8d34db0ddef14b5446975663e5ff37e27b45 +Author: Guus Sliepen +Date: Thu Oct 11 22:47:13 2012 +0200 + + Strip newline from incoming SPTPS requests. + + Most of the code doesn't care whether requests are terminated with a newline or + not, except that when requests are forwarded, it is assumed they do not have + one and a newline is added. When a node using SPTPS receives a request from + another SPTPS-using node, and forwards it to a non-SPTPS-using node, this will + result in two consecutive newlines, which the latter node will see as an empty, + and thus invalid, request. + +commit 45944e4514a7765f858fa33cc1d9719a603099e0 +Author: Guus Sliepen +Date: Thu Oct 11 22:21:30 2012 +0200 + + Clear status and options fields of unreachable nodes. + +commit d917c8cb6b69475d568ccbe82389b9f2b3eb5e80 +Author: Guus Sliepen +Date: Wed Oct 10 17:17:49 2012 +0200 + + Fix whitespace. + +commit 58f4b845b9a7d83739af77337f2ce263d8df7838 +Author: Guus Sliepen +Date: Wed Oct 10 14:46:22 2012 +0200 + + Try all known addresses of node during the PMTU discovery phase. + + This helps in situations where some nodes have IPv6 and others have not. + +commit 0ed0cc6f9c30537bd74222fd99a41726d488dd37 +Author: Guus Sliepen +Date: Tue Oct 9 17:49:09 2012 +0200 + + Fix hash functions for keys whose size is not divisible by 4. + +commit d1ec010660905ae0b99d783737350ccc08b37b16 +Author: Guus Sliepen +Date: Tue Oct 9 16:27:28 2012 +0200 + + Fix memory leaks found by valgrind. + +commit 72642b40b3ad476101622da202b6f977a32b472f +Author: Guus Sliepen +Date: Tue Oct 9 15:52:58 2012 +0200 + + Clear Ethernet header when reading packets from a tun device. + + This fixes a warning from valgrind about uninitialized bytes, which were being + sent to other nodes. + +commit b346338f9c2de6f71d87cb4ad8e61b0af0052688 +Author: Guus Sliepen +Date: Tue Oct 9 13:28:09 2012 +0200 + + Remove unused variables, fix some #includes. + +commit f62b4a91344bd0de09e7fb4e4c8c1993ffc027c3 +Author: Guus Sliepen +Date: Tue Oct 9 13:23:12 2012 +0200 + + Fix deleting connections from the connection list. + +commit 0b8b23e0dd7219344543f135ca0aeba8a4a42d48 +Author: Guus Sliepen +Date: Mon Oct 8 00:35:38 2012 +0200 + + C99 extravaganza. + +commit ff306f0cdaedb50de1472e7c1fb55de922a6ca60 +Author: Guus Sliepen +Date: Sun Oct 7 21:59:53 2012 +0200 + + Replace the connection_tree with a connection_list. + + The tree functions were never used on the connection_tree, a list is more appropriate. + Also be more paranoid about connections disappearing while traversing the list. + +commit ce059e36fdb3d3049c278e8b2f36b03c93778996 +Author: Guus Sliepen +Date: Sun Oct 7 21:02:40 2012 +0200 + + Refactor outgoing connection handling. + + Struct outgoing_ts and connection_ts were depending too much on each other, + causing lots of problems, especially the reuse of a connection_t. Now, whenever + a connection is closed it is immediately removed from the list of connections + and destroyed. + +commit d93a37928b75b17ac5e1eae5c2d62fd0760a6608 +Author: Guus Sliepen +Date: Sun Oct 7 17:53:23 2012 +0200 + + Fix warnings from cppcheck. + +commit 5d0812d49275ec8bda2b5b0ac813239045463777 +Author: Guus Sliepen +Date: Sun Oct 7 14:06:47 2012 +0200 + + Remove a debug message. + +commit c2a9ed9e98e3dc4218c74fff774ddfe654adfd72 +Author: Guus Sliepen +Date: Sun Oct 7 14:03:50 2012 +0200 + + Handle packets encrypted via SPTPS that need to be forwarded via TCP. + +commit bb6b97ce3493d49b79f1bd57fdac420c312ef8d6 +Author: Guus Sliepen +Date: Sun Oct 7 13:31:19 2012 +0200 + + Make datagram SPTPS key exchange more robust. + + Similar to old style key exchange requests, keep track of whether a key + exchange is already in progress and how long it took. If no key is known yet + or if key exchange takes too long, (re)start a new key exchange. + +commit b99af2f813b897e1fd49c87a7cf44241cad3a017 +Author: Guus Sliepen +Date: Sun Oct 7 11:45:54 2012 +0200 + + Useful error messages when writing to a meta connection fails. + +commit e05371346548dee977d4ee45e12e3058e749afb6 +Author: Guus Sliepen +Date: Sat Oct 6 21:16:17 2012 +0200 + + When terminating, keep control connections open until the end. + + This ensures all device files and listening sockets have been closed before + tincctl gets notified of tincd's termination. + +commit 86116bb022f0b885638ff9ba21b359fc9f55286a +Author: Guus Sliepen +Date: Sat Oct 6 21:15:19 2012 +0200 + + Clear connection options and status fields in free_connection_partially(). + + Most fields should be zero when reusing a connection. In particular, when an + outgoing connection to a node which is reachable on more than one address is + made, the second connection to that node will have status.encryptout set but + outctx will be NULL, causing a NULL pointer dereference when + EVP_EncryptUpdate() is called in send_meta() when it shouldn't. + +commit ef9358c0d616c5ff3391c8ec3da5d357286a4457 +Author: Guus Sliepen +Date: Sat Oct 6 17:45:03 2012 +0200 + + Improve starting/stopping tincd using tincctl. + + When starting tincd, tincctl now strips non-options from the command line, and + sets argv[0] to the name of the tincd command instead of copying its own + command name. + + When stopping a running tincd, tincctl now waits for it to terminate. + +commit 47f33e07ff90b557cfa96999e921d35ea537ca80 +Author: Guus Sliepen +Date: Sat Oct 6 16:53:43 2012 +0200 + + Fix off-by-one error. + + Apart from writing 1 byte beyond an array allocated on the stack, this slipped + an unitialized byte in the seed used for key generation. + +commit 20b441a6de743b2149df59cfb94a7663e1924fa3 +Author: Guus Sliepen +Date: Mon Oct 1 10:42:13 2012 +0200 + + Libreadline might depend on libcurses. + +commit 3887e6dcb54494ee11798e721e274e06b0a5621a +Author: Guus Sliepen +Date: Mon Oct 1 10:39:15 2012 +0200 + + Remove abort() call that accidentily sneaked into commit dd1b69e. + +commit 0b0949e5bb63f9545feb4714812e2aa2112fb092 +Author: Guus Sliepen +Date: Mon Oct 1 10:36:23 2012 +0200 + + Make sure sptps_test compiles without -flto. + +commit b381acd60dbadbb4bc679d35a7d86bf425f21f86 +Author: Guus Sliepen +Date: Sun Sep 30 23:12:43 2012 +0200 + + Remove unused function declaration. + +commit dd1b69e31f83e2cc200ecc10e6d927373823332b +Author: Guus Sliepen +Date: Sun Sep 30 22:43:48 2012 +0200 + + Fix not reading Port statement from host config file. + +commit 6dfdb323612184529b4b83c1be914dda8262de47 +Merge: 9e76c46 c4940a5 +Author: Guus Sliepen +Date: Sun Sep 30 15:00:47 2012 +0200 + + Merge branch 'master' into 1.1 + + Conflicts: + lib/utils.c + src/net_setup.c + src/process.c + src/protocol_auth.c + src/protocol_key.c + src/utils.h + +commit c4940a5c888d85b4c477b6face5e9a618e64718d +Author: Guus Sliepen +Date: Sun Sep 30 13:45:47 2012 +0200 + + Add strict checks to hex to binary conversions. + + The main goal is to catch misuse of the obsolete PrivateKey and PublicKey + statements. + +commit 3bd810ea79d6933839ddac4a2cf1445c51947d38 +Author: Guus Sliepen +Date: Sun Sep 30 13:45:39 2012 +0200 + + Attribution for Martin Schürrer. + +commit 5a161e86cf35351f5274d7a8e17fef4630b40686 +Author: Martin Schürrer +Date: Sun Sep 30 02:04:55 2012 +0200 + + Output details of encryption errors + +commit 9e76c464b26b066e1eb3aa5232e573792e28020d +Author: Guus Sliepen +Date: Fri Sep 28 17:51:48 2012 +0200 + + Remove some debugging messages. + +commit e971130b601064090815c31c90b876e3d0d1d5b1 +Author: Guus Sliepen +Date: Fri Sep 28 17:36:25 2012 +0200 + + Make tincctl robust against dropped control connections. + +commit c5325ffdd1c6749beaf842c272eb28ecd5a070b6 +Author: Guus Sliepen +Date: Fri Sep 28 17:05:01 2012 +0200 + + Correctly add/remove outgoing connections when reloading configuration. + +commit f417271ea1447589ea05901f54fbb0377e7afaf9 +Author: Guus Sliepen +Date: Fri Sep 28 17:03:14 2012 +0200 + + Fix column sorting, make all lists sortable. + +commit aee86011ff2d389832fc9a23081ea23ab8484607 +Author: Guus Sliepen +Date: Thu Sep 27 22:12:15 2012 +0200 + + Let the GUI handle the new dump format. + +commit fac5593f44e47f3bd4f4b425ada38ab49fbe3b42 +Author: Guus Sliepen +Date: Thu Sep 27 17:19:02 2012 +0200 + + Fix links in documenation. + +commit 2e09986a1fd6dc5b6313f10e5d86aaaf4a531235 +Author: Guus Sliepen +Date: Thu Sep 27 17:18:49 2012 +0200 + + Fix links in documentation. + +commit f70cbc9d3ee3a88cf956592007e57f7a1dde2c17 +Author: Guus Sliepen +Date: Thu Sep 27 15:45:02 2012 +0200 + + Comment out old public/private keys when generating new ones. + +commit 38dbc63f118dbfdb955b56740b8c20a9379fb3ba +Author: Guus Sliepen +Date: Wed Sep 26 23:56:21 2012 +0200 + + Update documentation of the "dump graph" command. + +commit 1f312137d5ab12a2d996d5f7972f169aeb852040 +Author: Guus Sliepen +Date: Wed Sep 26 23:52:36 2012 +0200 + + Allow dumping either directed or undirected graphs. + + Internally, tinc maintains a directed graph of the meta connections between + nodes. However, this causes graphviz to draw two lines between nodes, which is + not always desirable. The "dump graph" command now defaults to dumping an + undirected graph, the "dump digraph" command will dump a directed graph. + +commit d6388d782ede1bbe49a5c2643362e2e0f383fa89 +Author: Guus Sliepen +Date: Wed Sep 26 23:18:32 2012 +0200 + + Let tincctl parse and format dumps. + + At the moment it just reproduces the old format. + +commit 9ade39b7d5564fb6f5a41946c9a23cfa7851a19f +Author: Guus Sliepen +Date: Wed Sep 26 22:20:43 2012 +0200 + + Keep last known address and time since reachability changed. + + This allows tincctl info to show since when a node is online or offline. + +commit 1e5deec973cd366b9d9cec6c1314a97e7051ce0f +Author: Guus Sliepen +Date: Tue Sep 25 22:28:08 2012 +0200 + + Remove remnants of Ethertap and old TUNSETIFF ioctl(). + +commit 125dd0dbcf4f46033ead3486044eb00b413fe537 +Author: Guus Sliepen +Date: Tue Sep 25 22:12:36 2012 +0200 + + Fix typo in manpage. + +commit 72f08932cf6f1ac0cfb837d377b423207e8c671a +Author: Guus Sliepen +Date: Mon Sep 24 14:56:00 2012 +0200 + + Don't ignore Makefile.am. + +commit 66e702d90d83977dc089736d7e4146330bc5df28 +Author: Guus Sliepen +Date: Mon Sep 24 14:02:07 2012 +0200 + + Attribution for Vil Brekin and some code style cleanups. + +commit f421a640777bd9484c59fa6feacadcf3e05d4b44 +Author: Vilbrekin +Date: Sat Aug 25 20:32:38 2012 +0200 + + Android cross-compilation instructions. + +commit afe4bf62eccab76c75e5a661fb2c16f1391a8417 +Author: Vilbrekin +Date: Sat Aug 25 20:01:11 2012 +0200 + + Use __ANDROID__ define rather than dirty hard-code to allow android NDK cross-compilation. + +commit c6720f1a608d19c722d8601fab1048773dbad59b +Author: Vilbrekin +Date: Sat Aug 25 19:59:26 2012 +0200 + + Add basic .gitignore file, cleaning (most) files generated by autotools. + +commit f2570c1b7f5813e087c867cf002f36f0c09b5cfa +Author: Vilbrekin +Date: Sat Aug 25 19:14:00 2012 +0200 + + Replace hard-code with new ScriptsInterpreter configuration property. + + This new setting allows choosing a custom script interpreter used for the various tinc callbacks. + If none is specified, the script itself is called as executable (as before). + This is particularly useful when storing tinc configuration and script on a mount point with no-exec attribute. + +commit 8a6f278fd2606c0a8f133f05df83b2649eacf6c3 +Author: Vilbrekin +Date: Wed Aug 22 10:46:24 2012 +0200 + + Basic patch for android cross-compilation. + + Commented non-existing functions in android NDK. + Prefix scripts execution with shell binary to allow execution on no-exec mount points. + Everyything is currently hard coded, while it should use pre-compiler variables... + +commit 2dc8deb1047a076d1c040f47bedf36ad4b41b17c +Author: Guus Sliepen +Date: Thu Sep 13 21:35:29 2012 +0200 + + Ensure sptps_test compiles with -flto. + +commit 90f1cba1fd9e748ec4b8274511d5a36ec1a24d9d +Author: Guus Sliepen +Date: Wed Sep 5 13:05:48 2012 +0200 + + Replace node_udp_tree with a hash table. + +commit 4c05afd19acada4781e1b8865cf702b197882e5d +Author: Guus Sliepen +Date: Wed Sep 5 12:45:36 2012 +0200 + + Use hash tables to lookup owners of addresses. + +commit 6b6a025488f289f749498a7e6cc1994be19f53e8 +Author: Guus Sliepen +Date: Wed Sep 5 12:44:41 2012 +0200 + + Add a simple hash table implementation. + +commit e9de08be0dab58a48f9a8ce3d250516cf05d6b8e +Author: Guus Sliepen +Date: Tue Sep 4 14:21:50 2012 +0200 + + Remove newlines at end of log messages. + +commit 05dac63dbc03dc5a64a7f4b50e24eb3766135916 +Author: Guus Sliepen +Date: Tue Sep 4 14:16:05 2012 +0200 + + Remove some debug messages. + +commit 742f7bb04e72d93f2c4a858534144a599b3fc14d +Author: Guus Sliepen +Date: Thu Aug 30 14:21:23 2012 +0200 + + Properly handle SPTPS packets with stripped Ethernet headers. + +commit d74b81b61e87c66d364a8590a48d87773ad2652c +Author: Guus Sliepen +Date: Thu Aug 30 14:00:34 2012 +0200 + + Fix node name check for "connect" and "disconnect" commands. + +commit 5567c0d4107e6ff6f4639d8664651841bd59ddad +Author: Guus Sliepen +Date: Sun Aug 5 17:25:31 2012 +0200 + + Quit when "exit" or "quit" commands are used in tincctl's shell. + +commit d18519ae21345fea68dd7f0f5525adba3a7639a9 +Author: Guus Sliepen +Date: Sun Aug 5 17:03:57 2012 +0200 + + Fix segfault when using tincctl's shell without readline. + +commit b332bd964663b7109a5fc4be596d36fbf1dbaa47 +Author: Guus Sliepen +Date: Sun Aug 5 13:50:51 2012 +0200 + + Add bash completion script. + +commit e29e0fee8812851473bcf24324a15cbf3cc854a0 +Author: Guus Sliepen +Date: Fri Aug 3 14:17:02 2012 +0200 + + Make sure the top command can be used more than once in tincctl's shell. + +commit a57db1dfe0736fd902a45ed5f695630faf3f0e1e +Author: Guus Sliepen +Date: Fri Aug 3 14:15:50 2012 +0200 + + Fork when using the "start" command in tincctl. + + This allows the command to be given in its shell without immediatly exiting tincctl. + +commit 36c6afede36b6956bd86df824f5616c1afee35ed +Author: Guus Sliepen +Date: Fri Aug 3 13:23:07 2012 +0200 + + Add readline completion for tincctl config and tincctl info. + +commit 8af2f3f5a4061a8dbfd4f7d259e0038df06a373e +Author: Guus Sliepen +Date: Thu Aug 2 17:44:59 2012 +0200 + + Optionally compress and/or strip Ethernet header from SPTPS packets. + +commit 73348be58ecb9c40cf435122a00e72ac4d1a4c9b +Author: Guus Sliepen +Date: Thu Aug 2 17:24:42 2012 +0200 + + Have tincctl act as a shell when no command is given. + + By default it uses readline to read commands. If the input and output are not a + tty, no prompt is shown. + +commit 91937812bdfe74699e4f7cdf86265d07423acbba +Author: Guus Sliepen +Date: Thu Aug 2 17:23:51 2012 +0200 + + Clear struct sptps before reusing it. + +commit 6bcd03c2027636f82ab7228566717d112df7bc6d +Author: Guus Sliepen +Date: Wed Aug 1 22:22:52 2012 +0200 + + Update the documentation to encourage using "tincctl init" and "tincctl config". + +commit 6396f42d74f22ab5f8e736dc5cb04c57917f9319 +Author: Guus Sliepen +Date: Wed Aug 1 16:51:59 2012 +0200 + + Stricter checks for netname and node names. + + - Node names should not be empty. + - Net names should not contain slashes or start with a dot, because they are + used in pathnames. + +commit 61006ced88e1bf62e8883216cabc636f2d4cb12a +Author: Guus Sliepen +Date: Wed Aug 1 16:13:23 2012 +0200 + + Add missing configuration variables. + +commit b0f3a76e9bf8ceeab75c1e6f4dce6763aecddc5e +Author: Guus Sliepen +Date: Wed Aug 1 15:50:45 2012 +0200 + + Add the ability to query configuration variables to tincctl. + +commit a9caa2a6ea3aa553c9d2140ad4f5b34b7ab7297b +Author: Guus Sliepen +Date: Wed Aug 1 15:15:37 2012 +0200 + + tincctl restart should work even if no tincd is running. + +commit 07980b056c5371f8b6fdd50172f501be07155bdf +Author: Guus Sliepen +Date: Wed Aug 1 15:14:48 2012 +0200 + + Try sending SIGTERM if we cannot connect to a tincd but we know its PID. + +commit 7a71d48009e03ff1143a6e1084803f456a27c849 +Author: Guus Sliepen +Date: Tue Jul 31 21:43:49 2012 +0200 + + Use a status bit to track which nodes use SPTPS. + +commit 6bc8df3e010509f69af95d2cc14ec893def6f644 +Author: Guus Sliepen +Date: Tue Jul 31 20:39:15 2012 +0200 + + Add Brandon Black's replay window code to SPTPS. + +commit 5ede437307cc3bbb20431f4b82f4a2ef79c9b746 +Author: Guus Sliepen +Date: Tue Jul 31 20:36:35 2012 +0200 + + Handle SPTPS datagrams in try_mac(). + +commit aaff0ed08916f936b0a7b8a3d0607b8111b7a185 +Author: Guus Sliepen +Date: Tue Jul 31 20:29:13 2012 +0200 + + Remove unused #include. + +commit 153abaa4d940bf2bc9bd7275d5efe5c01c354190 +Author: Guus Sliepen +Date: Mon Jul 30 18:36:59 2012 +0200 + + Use datagram SPTPS for packet exchange between nodes. + + When two nodes which support SPTPS want to send packets to each other, they now + always use SPTPS. The node initiating the SPTPS session send the first SPTPS + packet via an extended REQ_KEY messages. All other handshake messages are sent + using ANS_KEY messages. This ensures that intermediate nodes using an older + version of tinc can still help with NAT traversal. After the authentication + phase is over, SPTPS packets are sent via UDP, or are encapsulated in extended + REQ_KEY messages instead of PACKET messages. + +commit 248d300f1be0d5f2aae39202041699ab2b46c56b +Merge: e1355e2 3391018 +Author: Guus Sliepen +Date: Fri Jul 27 22:48:24 2012 +0200 + + Merge branch 'master' into 1.1 + +commit 3391018efbd41858d42ccae6ae919749ba94c8db +Author: Guus Sliepen +Date: Fri Jul 27 22:43:01 2012 +0200 + + Also clarify hostnames=[yes|no] in tinc.conf(5). + +commit e895b358db8863d19dfa3d77c861ae19b76bc750 +Author: Mesar Hameed +Date: Tue Jul 24 07:18:50 2012 +0100 + + Minor clarification, tinc.conf hostnames=[yes|no] variable only resolves names for logging purposes. + +commit e1355e24eb7fe36bdb5dd7c818815fa266046a51 +Author: Guus Sliepen +Date: Sun Jul 22 13:05:56 2012 +0200 + + Remove unused po/ directory. + +commit 6c9b33c8b67374d38525b88f292840034c559a45 +Author: Guus Sliepen +Date: Sun Jul 22 12:55:04 2012 +0200 + + Have tinc-gui use same way of locating pidfile as tincd and tincctl. + +commit 2b97a7d7cf6ca7f4d84d3df754062a55bdf55305 +Author: Guus Sliepen +Date: Sun Jul 22 12:52:31 2012 +0200 + + tincctl init now also creates a template tinc-up script. + +commit eb430005c74b6b5f717e7e264afa3bd35284740d +Author: Guus Sliepen +Date: Sat Jul 21 17:10:10 2012 +0200 + + Fix exit code when installing tincd as a service on Windows. + +commit e5e96882c3825cee81ff163490b2f39fad3192b8 +Author: Guus Sliepen +Date: Sat Jul 21 16:33:09 2012 +0200 + + Windows doesn't like quotes around "edit" when calling it through system(). + + Even though that works fine on the command line. + +commit 18237e1f2d9dd5eef4a4e0d746d016bf94a42ad4 +Author: Guus Sliepen +Date: Sat Jul 21 16:26:55 2012 +0200 + + Use backslashes on Windows. + + Although Windows itself supports the forward slash, some programs may not. + +commit 09a8ff649cc7aa51d291c89e1556526a6265cc81 +Author: Guus Sliepen +Date: Sat Jul 21 15:58:16 2012 +0200 + + Don't try to mkdir(CONFDIR) on Windows when there is a registry key for tinc. + +commit ed8ce60845dc0568840c64c692838136f342fa54 +Author: Guus Sliepen +Date: Sat Jul 21 15:51:15 2012 +0200 + + Fix crash when no netname is specified. + +commit 7303b512b0e4f0d9cbc3236e846b2618f527b830 +Author: Guus Sliepen +Date: Sat Jul 21 15:50:50 2012 +0200 + + Fix some compiler warnings. + +commit 33521eabd4501b4add35468618453ac4f76311f3 +Author: Guus Sliepen +Date: Sat Jul 21 15:15:04 2012 +0200 + + Have tincd and tincctl use the same method of determining netname. + +commit 1d322d2eda8223f21b0c00381af34b94054f251a +Author: Guus Sliepen +Date: Sat Jul 21 15:02:44 2012 +0200 + + Add a newline to a configuration file if it is missing. + +commit dea722c4aca9a8cfa463807d279aa10cc6a0fc64 +Author: Guus Sliepen +Date: Sat Jul 21 15:02:17 2012 +0200 + + Add some checks when changing configuration. + +commit cc0c35267f8fac4f82622ff73474ed1e2d3a1e36 +Author: Guus Sliepen +Date: Sat Jul 21 14:19:23 2012 +0200 + + Call event_init() after detaching. + + Otherwise, the call to daemon() could close filedescriptors in use by libevent + itself; for example if it uses kqueue or epoll instead of a select() or poll() + backend. + +commit 4e0fc52197546bbf8a0be7af946f4b569e13048c +Author: Guus Sliepen +Date: Sat Jul 21 13:53:22 2012 +0200 + + Fix various compiler warnings. + +commit b161088b35fad1d284855f6434a895a20e34a250 +Author: Guus Sliepen +Date: Sat Jul 21 13:38:14 2012 +0200 + + BSD make doesn't like $<. + +commit 98a72d686983178f71cd2bf336c1f3d5c647f1e7 +Author: Guus Sliepen +Date: Sat Jul 21 13:02:35 2012 +0200 + + Make sure sptps.h and info.h are in the tarball. + +commit 5eeed38b8eb15f4c0464675b7d8c7722bc8be168 +Author: Guus Sliepen +Date: Sat Jul 21 12:51:53 2012 +0200 + + Make sure tinc compiles on Windows. + +commit 1d4590ca5cae09ea3b7a7e80355639e20861d349 +Author: Guus Sliepen +Date: Fri Jul 20 20:35:07 2012 +0200 + + Prefer routes with lower weight as long as they do not increase the number of hops. + + This should improve traffic to nodes that are not directly reachable somewhat. + +commit 4c8ead98743254be97c830e942f0cc53539d780c +Author: Guus Sliepen +Date: Fri Jul 20 20:01:29 2012 +0200 + + Allow more configuration variables to be changed when reloading configuration. + + In particular, Subnets may be added or removed from the local node on the fly. + +commit c678e7c4fb52d93350eafaed0f666018ed469e10 +Author: Guus Sliepen +Date: Fri Jul 20 19:59:47 2012 +0200 + + Split setup_myself() into two functions, one for reloading configuration. + +commit 4591e96c76914795aaae317c067f16abc22fb2e0 +Author: Guus Sliepen +Date: Fri Jul 20 17:29:16 2012 +0200 + + Never remove items from cmdline_conf. + + We should treat cmdline_conf as const, so we can call read_config_options() + more than once with prefix = NULL. + +commit 68a20876d0c4a6c370064d78786dd9f2aa6273cb +Author: Guus Sliepen +Date: Fri Jul 20 01:02:51 2012 +0200 + + Use minor protocol version to determine whether to use ECDH key exchange between nodes. + +commit 76a3ada4eb4032172c3d780915a07680f9954d42 +Author: Guus Sliepen +Date: Tue Jul 17 18:05:55 2012 +0200 + + Put minor protocol version in connection options so other nodes can see it. + + This allows two nodes that do not have a meta-connection with each other see + which version they are. + +commit 68de7b481e54d6a7c573d9a2d61f76d4d3a6b2f9 +Author: Guus Sliepen +Date: Mon Jul 16 18:49:39 2012 +0200 + + When exporting configuration files, don't copy Name variables. + + These interfere with tincctl import. Besides, host configuration files should + not contain Name at all. + +commit c52c46f8717aac6904f32766d774fa3fdf9611d8 +Author: Guus Sliepen +Date: Mon Jul 16 16:48:24 2012 +0200 + + Add an easy way to export and import host configuration files. + +commit 6319dc9dde3b328ba800f25a6bb4cf303d27f664 +Author: Guus Sliepen +Date: Mon Jul 16 01:14:08 2012 +0200 + + Strip default subnet weight from output. + +commit 74646a4afa6557a0363cc85e0a95d578d4ab0ac2 +Author: Guus Sliepen +Date: Mon Jul 16 01:09:47 2012 +0200 + + Give an error message when tincctl info cannot parse the given subnet or address. + +commit 53735a9d964579829d089f4b7572aef50c4e1468 +Author: Guus Sliepen +Date: Mon Jul 16 01:05:25 2012 +0200 + + "tincctl info" gives more human readable information about nodes or subnets. + +commit 3c7003893fe2f82023d0d4f54b488bb7a16d0007 +Author: Guus Sliepen +Date: Mon Jul 16 00:52:50 2012 +0200 + + Move all functions related to subnet parsing to subnet_parse.c. + +commit e72e6febfeddbd4354560388c8e0e125a8017909 +Author: Guus Sliepen +Date: Sun Jul 15 22:53:03 2012 +0200 + + Fix tincctl dump. + +commit 9be8980a2bb6245da017270f85bd6da186fb433b +Author: Guus Sliepen +Date: Sun Jul 15 21:17:10 2012 +0200 + + Let tincctl ignore tincd options, so they will be passed on. + +commit 36dee4c539521578005eed5e58b4803b73f0c889 +Author: Guus Sliepen +Date: Sun Jul 15 21:15:35 2012 +0200 + + Fix tincctl start. + +commit 439069bda62b25baaabeb765ac0557efa57b6cfb +Author: Guus Sliepen +Date: Sun Jul 15 20:59:17 2012 +0200 + + Have tincctl notify a running tincd of configuration file changes. + +commit eb01fd96258e5f99be0e4930eac04e5487a108a0 +Author: Guus Sliepen +Date: Sun Jul 15 20:37:38 2012 +0200 + + Add an easy way to edit a configuration file. + +commit cedfeccb247abb00063316068d7d2ade880f9d09 +Author: Guus Sliepen +Date: Sun Jul 15 20:22:21 2012 +0200 + + Stricter checks for node names. + +commit 03f72c6173f27198e2e68227cb41e00f8ec4ddc9 +Author: Guus Sliepen +Date: Sun Jul 15 18:16:35 2012 +0200 + + Allow configuration variables to be added/removed using tincctl. + +commit dd102efd24d847c41890adfcc7ce6d9d2592dcdb +Author: Guus Sliepen +Date: Sun Jul 15 15:46:16 2012 +0200 + + Put every command in its own function. + +commit a444ec396456a25546a4ab3d185c7fb5e4bb7ae3 +Author: Guus Sliepen +Date: Sun Jul 15 14:49:36 2012 +0200 + + "tincctl init" creates initial directory structure, tinc.conf and keypairs. + +commit 268c8545aaf83b7433f43402f5c77e39e20006ef +Merge: bce1777 f13fd8c +Author: Guus Sliepen +Date: Sat Jul 14 15:13:21 2012 +0200 + + Merge branch 'master' into 1.1 + +commit f13fd8c35068cd1f776e33362dcac40be9499035 +Author: Guus Sliepen +Date: Thu Jul 12 11:32:08 2012 +0200 + + Update THANKS file. + +commit 2eb0043e1352944b1113c1f7e40f37dffac0021d +Author: Guus Sliepen +Date: Thu Jul 12 11:30:56 2012 +0200 + + Document how to load the tap driver on FreeBSD. + +commit ae8c0b65d8f97942d7eff5f96344f781b8dec35d +Author: Guus Sliepen +Date: Thu Jul 12 11:25:11 2012 +0200 + + Use /dev/tap0 by default on FreeBSD and NetBSD when using Mode = switch. + +commit bce177767d521b47efd458c5cd570959a98d940d +Author: Guus Sliepen +Date: Tue Jun 26 14:22:57 2012 +0200 + + Fix crash when handling the ALRM signal. + + In retry() the function do_outgoing_connection() is called, which can delete + items from the connection_tree, so when walking the tree we must first save the + pointer to the next item. + +commit 19be9cf7150858311f7898fa3fb525d692d02f64 +Merge: 62b61a1 00e71ec +Author: Guus Sliepen +Date: Tue Jun 26 13:24:20 2012 +0200 + + Merge branch 'master' of git://tinc-vpn.org/tinc into 1.1 + + Conflicts: + NEWS + README + configure.in + lib/utils.c + src/linux/device.c + src/meta.c + src/net.h + src/net_setup.c + src/net_socket.c + src/protocol.c + src/protocol_auth.c + src/tincd.c + +commit 00e71ece25070dc919f9bc0696e4ff3a387360d0 +Author: Guus Sliepen +Date: Mon Jun 25 19:45:51 2012 +0200 + + Releasing 1.0.19. + +commit 236b0ba4ebba01e22e382e79897100338a039bbb +Author: Guus Sliepen +Date: Mon Jun 25 19:03:54 2012 +0200 + + Fix crash when using Broadcast = direct. + +commit 0a84f9cb8f52f2d2b4f03a5ad5ef9dfcd3509033 +Author: Guus Sliepen +Date: Mon Jun 25 19:01:51 2012 +0200 + + Fix compiler warnings. + +commit 62ee9b776d45af41c8b040ad86e50ba8f6f8e6c4 +Author: Guus Sliepen +Date: Mon Jun 25 15:01:42 2012 +0200 + + #include on Windows. + + MinGW complained about it not being included. + +commit c0af4c37d2046ffb3e07dd62f266a4fb99ea5614 +Author: Guus Sliepen +Date: Mon Jun 25 15:00:24 2012 +0200 + + Small fixes in proxy code. + +commit 62b61a1b7c2382b1bade142b3a41a9b27c1fd40d +Author: Guus Sliepen +Date: Sun May 13 22:16:42 2012 +0200 + + Don't forget to send a newline when forwarding requests. + +commit 42a8158b1dca6ee4ec1707176199cc36c26da7af +Author: Michael Tokarev +Date: Fri May 4 16:41:47 2012 +0400 + + add (errnum) in front of windows error messages + + On localized, non-English versions of windows, it is + common to have two active charsets -- for console applications + and for GUI applications, together with localized error messages + returned by windows. But two charsets are rarely compatible, + so sending the same byte sequence to console and to windows + event log makes one or another to be unreadable. So at least + include the error number, this way it will be possible to + lookup the actual error test using external ways. + + Signed-off-by: Michael Tokarev + +commit 58007d7efa3940c863c5a398f8b257a686ce37ba +Author: Guus Sliepen +Date: Tue May 8 16:44:15 2012 +0200 + + Always pass request strings to other functions as const char *. + +commit 291a59b5b732de084e392daea1433b1fdb9fbfd5 +Author: Sven-Haegar Koch +Date: Sun Apr 22 03:44:28 2012 +0200 + + free_connection_partially(): also reset remote protocol version infos + + The used remote protocol can change between two reconnects, aka if + the remote side has enabled/disabled for example their ExperimentalProtocols + setting. + +commit 32e5c5bb7c2c9127274247cb74cffa7345b04fad +Author: Sven-Haegar Koch +Date: Sun Apr 22 03:05:29 2012 +0200 + + Silence SPTPS log messages, reduce them from DEBUG_ALWAYS to DEBUG_META. + +commit c78bb143030162f0c820f08c87808e157c014a07 +Author: Sven-Haegar Koch +Date: Sun Apr 22 02:55:06 2012 +0200 + + terminate_connection(): delete non-outgoing (aka incoming) connections. + +commit 8b9e5af0d93069a81ce2ebed9899eedf3b7b184b +Author: Sven-Haegar Koch +Date: Sat Apr 21 03:44:24 2012 +0200 + + Label control connections for log output as "", not "". + +commit d3f4cf59ca917386e7c6358a98adbe3b8e9ce87a +Author: Sven-Haegar Koch +Date: Sat Apr 21 01:59:01 2012 +0200 + + free_connection_partially(): Avoid possible use-after-free for c->hischallenge + +commit 7a6ca7a993e5907497d97fef09e375698dde182f +Author: Sven-Haegar Koch +Date: Sat Apr 21 01:51:36 2012 +0200 + + terminate_connection(): only kill c->node->connection if it is pointing + to the same connection + +commit a96c4f016c9fff2392d85f762e16f5430c0b6463 +Author: Sven-Haegar Koch +Date: Fri Apr 20 00:24:38 2012 +0200 + + terminate_connection(): Avoid use-after-free and double-free for + already freed edge structure. + +commit 5c0dd104f94519c3cb50e9ca44227656c5adc7ae +Author: Guus Sliepen +Date: Thu Apr 19 15:56:08 2012 +0200 + + Document new proxy types. + +commit 5ae19cb0bb8dd6be1e9bcd560bb051f496a373ec +Author: Guus Sliepen +Date: Thu Apr 19 15:18:31 2012 +0200 + + Add support for proxying through an external command. + + Proxy type "exec" can be used to have an external script or binary set + up an outgoing connection. Standard input and output will be used to + exchange data with the external command. The variables REMOTEADDRESS and + REMOTEPORT are set to the intended destination address and port. + +commit fb5588856fa4dd6f140c72f7360302fe85b20c75 +Author: Guus Sliepen +Date: Thu Apr 19 14:10:54 2012 +0200 + + Add support for SOCKS 5 proxies. + + This only covers outgoing TCP connections, and supports only + username/password authentication or no authentication. + +commit b58d95eb29662bce4388f95dbc5762b9e2999806 +Author: Guus Sliepen +Date: Wed Apr 18 23:19:40 2012 +0200 + + Add basic support for SOCKS 4 and HTTP CONNECT proxies. + + When the Proxy option is used, outgoing connections will be made via the + specified proxy. There is no support for authentication methods or for having + the proxy forward incoming connections, and there is no attempt to proxy UDP. + +commit 84531fb6e621959e06519fdbb7f2a8f7578f66bd +Author: Guus Sliepen +Date: Mon Apr 16 01:57:25 2012 +0200 + + Allow broadcast packets to be sent directly instead of via the MST. + + When the "Broadcast = direct" option is used, broadcast packets are not sent + and forwarded via the Minimum Spanning Tree to all nodes, but are sent directly + to all nodes that can be reached in one hop. + + One use for this is to allow running ad-hoc routing protocols, such as OLSR, on + top of tinc. + +commit 9ebb34f907e8a15cb71dd20b111270d80bad1e96 +Author: Guus Sliepen +Date: Mon Apr 16 01:16:59 2012 +0200 + + Update README to reflect that only OpenSSL is currently supported. + +commit a851d8a9f6e3b69ab75695d84471ff4d525341b7 +Author: Guus Sliepen +Date: Mon Apr 16 01:14:59 2012 +0200 + + Add autoconf checks for OpenSSL's elliptic curve functions. + +commit f8e15dfe8d155b5bdb1e39bf6b9af486606145e8 +Author: Sven-Haegar Koch +Date: Sat Apr 14 02:28:43 2012 +0200 + + ecdh & ecdsa: avoid some possible memory leaks in error conditions. + +commit 8792b9a9f343e751dc3cfd789db9528da609ba9f +Author: Sven-Haegar Koch +Date: Sat Apr 14 02:02:11 2012 +0200 + + Remove confusing error message for failed reading in ECDSA keys. + + Most likeley the error is that there just is no valid key inside the used + host file, and in this case errno just contains a random value from the + last previously failed call. + +commit a5bb6d40fb517aa175510ec179091e4f9ffaf6f6 +Author: Sven-Haegar Koch +Date: Sat Apr 14 02:29:32 2012 +0200 + + sptps_stop(): clear pointers after free to avoid double free. + + sptps_stop() may get called twice on some failed connection setups. + +commit 535a55100bb77f107c85361e9f72a194e92bc8bc +Author: Guus Sliepen +Date: Thu Mar 29 16:45:25 2012 +0100 + + Allow environment variables to be used for Name. + + When the Name starts with a $, the rest will be interpreted as the name of an + environment variable containing the real Name. When Name is $HOST, but this + environment variable does not exist, gethostname() will be used to set the + Name. In both cases, illegal characters will be converted to underscores. + +commit 1d9dacb1f26971e19463b5501c2410c57f780ecb +Merge: 86c2990 89f4574 +Author: Guus Sliepen +Date: Mon Mar 26 19:06:39 2012 +0100 + + Merge branch 'master' of git://tinc-vpn.org/tinc into 1.1 + + Conflicts: + src/logger.c + src/net_setup.c + +commit 89f4574e0b1553c8e5dcbfc275e829a759b697f6 +Author: Guus Sliepen +Date: Mon Mar 26 14:46:09 2012 +0100 + + Add support for systemd style socket activation. + + If the LISTEN_FDS environment variable is set and tinc is run in the + foreground, tinc will use filedescriptors 3 to 3 + LISTEN_FDS for its listening + TCP sockets. For now, tinc will create matching listening UDP sockets itself. + + There is no dependency on systemd or on libsystemd-daemon. + +commit cc6aee784659bfbd21eb8d414e00a8f1a801cac4 +Author: Guus Sliepen +Date: Mon Mar 26 14:45:20 2012 +0100 + + Remove newline from log message. + +commit 16e6769feef21a5bf58f6022d990452987bb5efb +Author: Anthony G. Basile +Date: Mon Mar 26 06:29:40 2012 -0400 + + configure.in: fix AC_ARG_ENABLE and AC_ARG_WITH + + The current configure.in file does not correctly make use of these + macros. The resulting configure file will therefore enable an item + even if --disable-FEATURE is given. This patch restores the intended + behavior. + +commit 86c2990327fdf7ec1197aa73cb2b9a926a734db4 +Merge: d7bf63c b23681d +Author: Guus Sliepen +Date: Sun Mar 25 23:35:31 2012 +0100 + + Merge branch 'master' of git://tinc-vpn.org/tinc into 1.1 + + Conflicts: + NEWS + README + configure.in + src/Makefile.am + src/conf.c + src/conf.h + src/connection.c + src/net.c + src/tincd.c + +commit b23681dddb8987571f04d46fc14f0ba012a7929c +Author: Guus Sliepen +Date: Sun Mar 25 22:54:36 2012 +0100 + + Support :: in IPv6 Subnets. + +commit 482c6119a7ae80f320e5b519ef2e785e04a77b8e +Author: Guus Sliepen +Date: Sun Mar 25 15:32:26 2012 +0100 + + Releasing 1.0.18. + +commit 64c657b32d1eb34eb669c6d5b0ec26c1a643b194 +Author: Guus Sliepen +Date: Sun Mar 25 15:30:58 2012 +0100 + + Mark DecrementTTL option experimental. + +commit f71ce341800739c7cdee01d7cf025e7492da22ac +Author: Guus Sliepen +Date: Sun Mar 25 15:17:50 2012 +0100 + + Fix return type of vde_recv() as well. + + In this case it is not really necessary as the conversion to int will already + take care of ensuring the return value is treated as signed. + +commit 6225b1884a25af4debc2d0821a4c377ddbaec696 +Author: Guus Sliepen +Date: Sun Mar 25 14:55:56 2012 +0100 + + Document OpenBSD "ifconfig link0" and Linux "ip tuntap" commands. + +commit 399835385380d485416d6d59a8f27ce71f1db644 +Author: Guus Sliepen +Date: Sun Mar 25 14:46:50 2012 +0100 + + Fix some more compiler warnings. + +commit cfe6558d4ba4f572311aeafd62737f6f2692ad86 +Author: Guus Sliepen +Date: Sun Mar 25 14:00:21 2012 +0100 + + Fix return value type of vde_send(). + + The libvdeplug_dyn.h header file incorrectly declares the return type of + vde_send() to size_t, while in reality it is ssize_t. + +commit 95968c67f9df9102ddbce5b7c8d34107989ad51a +Author: Guus Sliepen +Date: Sun Mar 25 13:58:14 2012 +0100 + + Fix compiler warnings. + +commit e2d1b0b899ef66cd7ff227549e58b96c292f784e +Author: Guus Sliepen +Date: Sun Mar 25 13:42:10 2012 +0100 + + Allow scoped addresses to be used for IPv6 multicast socket. + +commit 251204063255d95910f9a079015e2f9b428fd983 +Author: Guus Sliepen +Date: Sun Mar 25 13:40:55 2012 +0100 + + Add #ifdefs in case not all platforms support IPv4 and IPv6 multicast. + +commit b5e3bf1a85462f0c41638c11305d28f87af24395 +Author: Guus Sliepen +Date: Fri Mar 23 13:18:36 2012 +0100 + + Set default value of DecrementTTL to "no". + + Decrementing the TTL causes IPv6 to fail when Mode = switch, and there may be + other unforeseen side-effects. + +commit c373de2e9812700c0568640727ad917b6fc7d758 +Author: Guus Sliepen +Date: Wed Mar 21 17:00:53 2012 +0100 + + Add support for multicast communication with UML/QEMU/KVM. + + DeviceType = multicast allows one to specify a multicast address and port with + a Device statement. Tinc will then read/send packets to that multicast group + instead of to a tun/tap device. This allows interaction with UML, QEMU and KVM + instances that are listening on the same group. + +commit a7dbb50c23f447a23b543c92ec096ff178bc2de3 +Author: Guus Sliepen +Date: Wed Mar 21 13:20:15 2012 +0100 + + Allow a port to be specified in BindToAddress statements. + + This can be used to let tinc listen on multiple ports for incoming connections. + +commit 80e15d8b96e5313b33c91003b1f75d7f6db9924e +Author: Guus Sliepen +Date: Tue Mar 20 23:49:16 2012 +0100 + + Always try next Address when an outgoing connection fails to authenticate. + + When making outgoing connections, tinc goes through the list of Addresses and + tries all of them until one succeeds. However, before it would consider + establishing a TCP connection a success, even when the authentication failed. + This would be a problem if the first Address would point to a hostname and port + combination that belongs to the wrong tinc node, or perhaps even to a non-tinc + service, causing tinc to endlessly try this Address instead of moving to the + next one. + + Problem found by Delf Eldkraft. + +commit d7bf63c63ab397cf3e5ca4a065922364925788e7 +Author: Guus Sliepen +Date: Sun Mar 18 21:24:46 2012 +0100 + + Make sure the signature also covers the session label. + +commit 42a0b61076d5d0f6391f0dd5c2c400b8fb89c5c5 +Author: Guus Sliepen +Date: Sun Mar 18 20:38:48 2012 +0100 + + Start documenting the SPTPS protocol. + +commit d756bb92ed52d5b1ecdd42af32f11f733db64d91 +Author: Guus Sliepen +Date: Sun Mar 18 17:46:30 2012 +0100 + + Don't send an ACK message after the first key exchange in the SPTPS protocol. + +commit c970ecdd75d4e7b3203a788f28b6e40cd532759b +Author: Guus Sliepen +Date: Sun Mar 18 17:42:43 2012 +0100 + + Test SPTPS messages sent while key renegotation is in progress. + +commit 3a4fe104a06b73fd19c550546e7c65a59ff2afe3 +Author: Guus Sliepen +Date: Sun Mar 18 16:42:02 2012 +0100 + + Add datagram mode to the SPTPS protocol. + + * Everything is identical except the headers of the records. + * Instead of sending explicit message length and having an implicit sequence + number, datagram mode has an implicit message length and an explicit sequence + number. + * The sequence number is used to set the most significant bytes of the counter. + +commit 03e06fd43aff73b4a5c9d367968a1279371ae252 +Author: Guus Sliepen +Date: Sun Mar 18 16:41:13 2012 +0100 + + Allow CTR mode counter to be set to a specific value. + +commit 28a1501b9a8b4c730f7f965d6b2e8fc50feba261 +Author: Guus Sliepen +Date: Sat Mar 10 13:31:36 2012 +0100 + + Releasing 1.0.17. + +commit 4712d8f92e63e86e835ffb624d6399343ee568ea +Author: Guus Sliepen +Date: Sat Mar 10 13:23:08 2012 +0100 + + Update copyright notices. + +commit 5b0f5ad958d6db4e73aebc5ee6c608cdae81b7b5 +Author: Guus Sliepen +Date: Thu Mar 8 23:23:39 2012 +0100 + + Make sure disabling old RSA keys works on Windows. + + Seeking in files and rewriting parts of them does not seem to work properly on + Windows. Instead, when old RSA keys are found when generating new ones, the + file containing the old keys is copied to a temporary file where the changes + are made, and that file is renamed back to the original filename. On Windows, + we cannot atomically replace files with a rename(), so we need to move the + original file out of the way first. If anything fails, the new code will warn + that the user has to solve the problem by hand. + +commit 2f1c337c541fcb7e2c62aeeab245ff7a43eb51a5 +Author: Guus Sliepen +Date: Thu Mar 8 22:19:20 2012 +0100 + + Add missing ICMP6 message type definitions. + +commit 40c28589328a2aa96c2ce1419c5d90616c758b3d +Merge: 8ac096b 9dea33f +Author: Guus Sliepen +Date: Thu Mar 8 21:15:08 2012 +0100 + + Merge branch 'master' of git://tinc-vpn.org/tinc into 1.1 + + Conflicts: + src/net_packet.c + +commit 9dea33f5301119dd4423eb962956cf2d246af3f3 +Author: Guus Sliepen +Date: Wed Mar 7 10:40:06 2012 +0100 + + Accept Subnets passed with the -o option when StrictSubnets = yes. + +commit 63f8303a5dc1758876451a580a8317dbc3d295d6 +Author: Guus Sliepen +Date: Fri Mar 2 16:09:58 2012 +0100 + + Only log errors sending UDP packets when debug level >= 5. + + Since tinc will fall back to TCP or route via another node, it is not necessary + to log such errors unconditionally. + +commit 8ac096b5bf9da1b3961a3ac4a03d083629222a63 +Author: Guus Sliepen +Date: Sun Feb 26 18:37:36 2012 +0100 + + Allow log messages to be captured by tincctl. + + This allows tincctl to receive log messages from a running tincd, + independent of what is logged to syslog or to file. Tincctl can receive + debug messages with an arbitrary level. + +commit a1bd3a291379492c8ffecd53792065dc20a28c79 +Author: Guus Sliepen +Date: Sun Feb 26 16:56:53 2012 +0100 + + Don't close control connections when handling a reload command. + + Because this would terminate the connection while the control message + handler was still running, it would lead to a segmentation fault later + on. + +commit 483c5dcfb43719e5fd50902641252e28a04fd74e +Merge: 344d6b9 ae52496 +Author: Guus Sliepen +Date: Sun Feb 26 16:27:13 2012 +0100 + + Merge branch 'master' of git://tinc-vpn.org/tinc into 1.1 + +commit ae5249610954af17c68c547bb1b45ad286ad647e +Author: Guus Sliepen +Date: Sun Feb 26 16:23:02 2012 +0100 + + Only use broadcast at the start of the PMTU discovery phase. + + For local peer discovery, only a handful of packets are necessary for + peers to detect each other. + +commit 344d6b9ac3c795f2942e457c1ab38b1dac5f7242 +Author: Guus Sliepen +Date: Sun Feb 26 12:39:46 2012 +0100 + + Let tincctl use the NETNAME environment variable if no -n option is given. + + This allows administrators who frequently want to work with one tinc + network to omit the -n option. Since the NETNAME variable is set by + tincd when executing scripts, this makes it slightly easier to use + tincctl from within scripts. + +commit 84570275acd84628586a6ca591a283d074ca10f0 +Author: Guus Sliepen +Date: Sun Feb 26 12:33:16 2012 +0100 + + Ensure all SPTPS functions are prefixed with sptps_. + +commit 8b1ad6f76f821648079818f6ff018bbc33b9d9e9 +Author: Guus Sliepen +Date: Sat Feb 25 23:03:09 2012 +0100 + + Go back to breadth first search for path finding. + + If 1.1.x nodes using Dijkstra's algorithm are mixed with 1.0.x nodes using BFS, + then routing loops can occur. + +commit 36623e15a1c8685e5d8730345c1a7f9c93710fef +Merge: 65d6f02 5140656 +Author: Guus Sliepen +Date: Sat Feb 25 22:52:57 2012 +0100 + + Merge branch 'master' of git://tinc-vpn.org/tinc into 1.1 + +commit 5140656de6bcfda72951a7827b05414ce306e3ca +Author: Guus Sliepen +Date: Sat Feb 25 22:11:30 2012 +0100 + + Stricter checks against routing loops. + + If a packet that had to be sent via an intermediate hop, and that intermediate + hop was the one that sent the packet, we drop it. + +commit f1d5eae643cdf537ef357f10f2da8ff83bdf32b4 +Author: Guus Sliepen +Date: Sat Feb 25 21:46:18 2012 +0100 + + Don't send ICMP Time Exceeded messages for other Time Exceeded messages. + + That would be silly. + +commit 65d6f023c46ac3a087f59b60762f87c869783f21 +Author: Guus Sliepen +Date: Sat Feb 25 18:25:21 2012 +0100 + + Use SPTPS when ExperimentalProtocol is enabled. + +commit efd21e232dced3225f119aeb7a585ebf55b7cf77 +Author: Guus Sliepen +Date: Sat Feb 25 15:18:15 2012 +0100 + + Apply HMAC after encryption. + +commit f5dc136cfd7a3a195b75f7174722734e25f30fd9 +Merge: 3fba801 5a28aa7 +Author: Guus Sliepen +Date: Thu Feb 23 13:26:01 2012 +0100 + + Merge branch 'master' of git://tinc-vpn.org/tinc into 1.1 + + Conflicts: + src/net.c + src/net_packet.c + src/net_socket.c + +commit 5a28aa7b8b0ab6237c2eab5f8b11253ea3ec5a05 +Author: Guus Sliepen +Date: Wed Feb 22 23:17:43 2012 +0100 + + Add LocalDiscovery option which tries to detect peers on the local network. + + Currently, this is implemented by sending IPv4 broadcast packets to the + LAN during path MTU discovery. + +commit 8e717ddb602f01f656369106ec0398efbe9ca4a4 +Author: Guus Sliepen +Date: Wed Feb 22 14:37:56 2012 +0100 + + Pass index into listen_socket[] to handle_incoming_vpn_data(). + +commit 3fba80174dbe29bcfe0d121a2a1d2e61be5ee57b +Merge: fba1c85 65e8e06 +Author: Guus Sliepen +Date: Wed Feb 22 14:23:59 2012 +0100 + + Merge branch 'master' of git://tinc-vpn.org/tinc into 1.1 + + Conflicts: + NEWS + README + configure.in + doc/tincd.8.in + src/Makefile.am + src/bsd/device.c + src/connection.c + src/connection.h + src/cygwin/device.c + src/device.h + src/dropin.h + src/linux/device.c + src/mingw/device.c + src/net.c + src/net_packet.c + src/net_setup.c + src/net_socket.c + src/process.c + src/protocol.c + src/protocol_key.c + src/raw_socket_device.c + src/route.c + src/solaris/device.c + src/tincd.c + src/uml_device.c + +commit fba1c85f44edfc56c19d35332b1eb825179a8bb6 +Author: Guus Sliepen +Date: Tue Feb 21 23:19:51 2012 +0100 + + Remove useless warning about signature length being shorter than expected. + +commit cb6cbf452f6183a00746afc5bff8f63f3f55235f +Author: Guus Sliepen +Date: Tue Feb 21 23:17:12 2012 +0100 + + Use only one hash algorithm (SHA512) in the PRF. + + On some platforms, OpenSSL by default does not support the Whirlpool algorithm. + +commit 65e8e06c6dc7349b11c3c1e8f4071b51e2994c65 +Author: Nick Hibma +Date: Tue Feb 21 15:26:58 2012 +0100 + + Add missing ICMP message type definitions. + +commit ac48c4ee8c09c8144f830cb66386b9dbe7298440 +Author: Guus Sliepen +Date: Tue Feb 21 14:06:55 2012 +0100 + + Fix check for raw socket support. + + Also, move some variables so there are no compiler warnings about unused + variables when there is no support for raw sockets. + +commit d9ad3d313d96d30ef45cd53367dff9a855a396d4 +Author: Guus Sliepen +Date: Tue Feb 21 13:31:21 2012 +0100 + + Fix a bug that caused tinc to ignore all but the last listening socket. + +commit 46506b7aaf6c6a8a85561c38fdb9c95eae21aa75 +Author: Guus Sliepen +Date: Tue Feb 21 13:13:40 2012 +0100 + + Document the command line flag -o and provide --option as well. + +commit 7d76e287598c8c18cadfb5818046d9dd1b0ad881 +Author: Guus Sliepen +Date: Tue Feb 21 11:39:21 2012 +0100 + + Move initialization of char *priority up to prevent freeing an uninitialized pointer. + +commit 8420a0c8bde1781db04dd2436eb9d5dca5a1732a +Author: Guus Sliepen +Date: Mon Feb 20 17:19:00 2012 +0100 + + Allow disabling of broadcast packets. + + The Broadcast option can be used to cause tinc to drop all broadcast and + multicast packets. This option might be expanded in the future to selectively + allow only some broadcast packet types. + +commit ea415ccc1690d6e5864a7500977b181e5c8faafe +Author: Guus Sliepen +Date: Mon Feb 20 17:12:48 2012 +0100 + + Rename connection_t *broadcast to everyone. + +commit cff5a844a3e6b494f4a4f6eb5b48a84780f2d0e5 +Author: Guus Sliepen +Date: Mon Feb 20 16:52:53 2012 +0100 + + Don't bind outgoing TCP sockets anymore. + + The code introduced in commit 41a05f59ba2c3eb5caab555f096ed1b9fbe69ee3 is not + needed anymore, since tinc has been able to handle UDP packets from a different + source address than those of the TCP packets since 1.0.10. When using multiple + BindToAddress statements, this code does not make sense anymore, we do want the + kernel to choose the source address on its own. + +commit 0233b1d710222cb09be0cbd08c1297e3ece38a9f +Author: Guus Sliepen +Date: Mon Feb 20 16:34:02 2012 +0100 + + Decrement TTL of incoming packets. + + Tinc will now, by default, decrement the TTL field of incoming IPv4 and IPv6 + packets, before forwarding them to the virtual network device or to another + node. Packets with a TTL value of zero will be dropped, and an ICMP Time + Exceeded message will be sent back. + + This behaviour can be disabled using the DecrementTTL option. + +commit 6289859ab365dc1c0d420323174418b316b14502 +Author: Guus Sliepen +Date: Mon Feb 20 15:44:52 2012 +0100 + + Only compile raw socket code when it is supported on that platform. + +commit d1dcdf8eb6f800704be426b1ce6f6c1a8e65ba0d +Merge: 1b2846d 3b1fad0 +Author: Guus Sliepen +Date: Sat Feb 18 14:31:08 2012 +0100 + + Merge branch 'master' of black:tinc + +commit 3b1fad04de6bed2f284fdf3d5b27d4162aeebc8c +Author: Guus Sliepen +Date: Sat Feb 18 14:37:52 2012 +0100 + + Allow setting DeviceType to tun or tap on Linux. + +commit 6455654d26d204cea4bbc102e5bd6550b7fff7a7 +Author: Guus Sliepen +Date: Sat Feb 18 11:48:21 2012 +0100 + + Send packets back using the same socket as they were received on. + +commit 1b2846d907adfc8472fc9da0c951c3243c7ee143 +Merge: 9f6a96a 6455654 +Author: Guus Sliepen +Date: Sat Feb 18 11:43:00 2012 +0100 + + Merge branch 'master' of black:tinc + +commit 9f6a96af3939bd2de410ce346a8c8fbcf93e7c9b +Author: Guus Sliepen +Date: Fri Feb 17 16:25:00 2012 +0100 + + Allow multiple BindToAddress statements. + +commit 708314df2f61675d0f54e541c9fff62ac1f433b5 +Author: Guus Sliepen +Date: Fri Feb 17 16:13:38 2012 +0100 + + Set FD_CLOEXEC flag on all sockets. + + Scripts called by tinc would inherit its open filedescriptors. This could + be a problem if other long-running daemons are started from those scripts, + if those daemons would not close all filedescriptors before going into the + background. + + Problem found and solution suggested by Nick Hibma. + +commit 1f00111e94b2f9a4beb9608b1e03a5e73c9c5d21 +Author: Guus Sliepen +Date: Mon Dec 26 23:11:27 2011 +0100 + + Fix a few small memory leaks. + +commit b50d6a7f2ad98239018bc5ce7a5739e3bf4f50f7 +Author: Guus Sliepen +Date: Mon Dec 26 23:04:40 2011 +0100 + + Fix compiler warnings. + +commit 178e52f76ef4ba40748c13ea7e518837394d6dbc +Author: Guus Sliepen +Date: Sun Dec 4 01:20:59 2011 +0100 + + Allow linking with multiple device drivers. + + Apart from the platform specific tun/tap driver, link with the dummy and + raw_socket devices, and optionally with support for UML and VDE devices. + At runtime, the DeviceType option can be used to select which driver to + use. + +commit 5672863e59e6a114ac6b66de98254b14266c0e61 +Author: Guus Sliepen +Date: Sat Dec 3 21:59:47 2011 +0100 + + Fix a few small memory leaks. + +commit 52ded09d1713b83222b56db7d29ff061aefb95e3 +Author: Guus Sliepen +Date: Sun Nov 27 12:13:16 2011 +0100 + + Add vde/device.c to the tarball. + +commit 2c7c87ec75c94d0b3cca9f7a5aeba34384f77cc1 +Author: Guus Sliepen +Date: Sun Nov 27 12:12:34 2011 +0100 + + Fix compilation of VDE and UML interfaces. + +commit 2a9060bba62d78f73da9b09ca791fe80993520fc +Author: Guus Sliepen +Date: Thu Oct 6 15:32:12 2011 +0200 + + Exchange ACK records to indicate switch to new keys. + + This allow application records to be sent while key renegotiation is still + happening. + +commit 3b5898078af1ab86797b3e24f2381131e6e702f7 +Author: Guus Sliepen +Date: Thu Oct 6 09:34:34 2011 +0200 + + Use counter mode encryption. + +commit a0f795ff5bd671ca10a7203e4234b37a12d8d1cd +Author: Guus Sliepen +Date: Thu Oct 6 09:33:09 2011 +0200 + + Add counter mode encryption. + +commit 67ff81ec16b8ab5f15d16efbedfecfaf0be17c13 +Author: Guus Sliepen +Date: Wed Oct 5 22:05:13 2011 +0200 + + Test corner cases in the SPTPS protocol. + + * Test zero-byte messages. + * Test maximum size (65535 byte) messages. + * Test different message types. + * Test key renegotiation. + +commit 30013511504e925729ebc67772205a74c4b8aeea +Author: Guus Sliepen +Date: Wed Oct 5 22:00:51 2011 +0200 + + Update SPTPS protocol. + + * Exchange nonce and ECDH public key first, calculate the ECDSA signature + over the complete key exchange. + * Make an explicit distinction between client and server in the signatures. + * Add more comments and replace some magic numbers by #defines. + + Thanks to Erik Tews for very helpful hints and comments! + +commit 810847248ae90140ee6f3e568add80aef88c3def +Author: Guus Sliepen +Date: Wed Oct 5 21:59:33 2011 +0200 + + Fix compiler warning. + +commit ddea7a23a66b8fee4942f2ce237dcabe02e17270 +Author: Guus Sliepen +Date: Tue Aug 30 20:49:48 2011 +0200 + + Return false instead of void when there is an error. + +commit e838289683c0039fac0ae6172d40b4177c17911b +Author: Guus Sliepen +Date: Tue Aug 30 19:56:56 2011 +0200 + + Prevent read_rsa_public_key() from returning an uninitialized RSA structure. + + In case the config file could not be opened a new but unitialized RSA structure + would be returned, causing a segmentation fault later on. This would only + happen in the case that the config file could be opened before, but not when + read_rsa_public_key() was called. This situation could occur when the --user + option was used, and the config files were not readable by the specified user. + +commit 5d4336e5429b88dcc53e80c00412e76a5269b384 +Author: Guus Sliepen +Date: Wed Aug 10 17:04:17 2011 +0200 + + Handle UDP packets with unknown source addresses properly. + + Probably due to a merge, the try_harder() function had duplicated the + rate-limiting code for detecting the sender node based on the HMAC of the + packet. This prevented this detection from running at all. The function is now + identical again to that in the 1.0 branch. + +commit bbc0ba9e87f76111529d6dc9cb00c0b9435b5858 +Author: Michael Tokarev +Date: Sun Aug 7 12:18:20 2011 +0400 + + use execvp() not execve() in tincctl start + + sometimes argv[0] will have directory-less name (when the + command is started by shell searching in $PATH for example). + For tincctl start we want the same rules to run tincd as for + tincctl itself (having full path is better but if shell does + not provide one we've no other choice). Previous code tried + to run ./tincd in this case, which is obviously wrong. + + This is a fix for the previous commit. + + Signed-off-by: Michael Tokarev + +commit a7556a9d2c943a6317d2dab66d9f742997f0d47a +Author: Michael Tokarev +Date: Sun Aug 7 12:05:07 2011 +0400 + + run tincd from the same directory as tincctl and pass all options to it + + For tincctl start, run tincd from dirname($0) not SBINDIR - + this allows painless alternative directory installation and + running from build directory too. + + Also while at it, pass the rest of command line to tincd, not + only options before "start" argument. This way it's possible + to pass options to tincd like this: + tincctl -n net start -- -d 1 -R -U tincuser ... + + And also add missing newline at the end of error message there. + + Signed-Off-By: Michael Tokarev + +commit 2696ad2cca73aee13e38f740d5530dc33e4a92e6 +Author: Michael Tokarev +Date: Sun Aug 7 11:25:03 2011 +0400 + + don't mention reload twice in tincctl help + + Signed-Off-By: Michael Tokarev + +commit 3d75dbc0880484ff6d2f689a9b981def3cd75b5e +Author: Guus Sliepen +Date: Sun Jul 24 15:44:51 2011 +0200 + + Start of "Simple Peer-To-Peer Security" protocol. + + Encryption and authentication of the meta connection is spread out over + meta.c and protocol_auth.c. The new protocol was added there as well, + leading to spaghetti code. To improve things, the new protocol will now + be implemented in sptps.[ch]. + + The goal is to have a very simplified version of TLS. There is a record + layer, and there are only two record types: application data and + handshake messages. The handshake message contains a random nonce, an + ephemeral ECDH public key, and an ECDSA signature over the former. After + the ECDH public keys are exchanged, a shared secret is calculated, and a + TLS style PRF is used to generate the key material for the cipher and + HMAC algorithm, and further communication is encrypted and authenticated. + + A lot of the simplicity comes from the fact that both sides must have + each other's public keys in advance, and there are no options to choose. + There will be one fixed cipher suite, and both peers always authenticate + each other. (Inspiration taken from Ian Grigg's hypotheses[0].) + There might be some compromise in the future, to enable or disable + encryption, authentication and compression, but there will be no choice + of algorithms. This will allow SPTPS to be built with a few embedded + crypto algorithms instead of linking with huge crypto libraries. + + The API is also kept simple. There is a start and a stop function. All + data necessary to make the connection work is passed in the start + function. Instead having both send- and receive-record functions, there + is a send-record function and a receive-data function. The latter will + pass protocol data received from the peer to the SPTPS implementation, + which will in turn call a receive-record callback function when + necessary. This hides all the handshaking from the application, and is + completely independent from any event loop or socket characteristics. + + [0] http://iang.org/ssl/hn_hypotheses_in_secure_protocol_design.html + +commit 0f2aa4bd8b698608876bec141c5aef1aa619730b +Author: Guus Sliepen +Date: Sat Jul 23 14:12:23 2011 +0200 + + Releasing 1.0.16. + +commit e16ead8dd9d4600664058069f0695832dfe068b2 +Author: Guus Sliepen +Date: Sat Jul 23 14:11:44 2011 +0200 + + Use usleep() instead of sleep(), MinGW complained. + +commit ff751903aa82bd6dd66a099f9c05dcdae9fc57f2 +Author: Guus Sliepen +Date: Wed Jul 20 08:19:18 2011 +0200 + + Don't abort() on low-level crypto errors, just return false. + + The abort() calls were accidentily left in for debugging. + +commit 2f4ccfe2473948372f7c9f14d9ffce1d77f5fd8c +Author: Guus Sliepen +Date: Tue Jul 19 21:11:11 2011 +0200 + + Fix tinc 1.0.x daemons connecting when ExperimentalProtocol = yes. + commit f8d94f34fc5d7fe9ed4a076a2fd77eacbd83adca Author: Guus Sliepen Date: Sun Jul 17 20:09:08 2011 +0200 @@ -16,6 +1966,18 @@ Date: Sun Jul 17 20:01:24 2011 +0200 Write loopback address instead of "any" address in pidfile. +commit 50fcfea127c9d2fdf8894498a9fdcc6fb3bbb2ce +Author: Guus Sliepen +Date: Sun Jul 17 19:34:01 2011 +0200 + + Flush output buffer in send_tcppacket(). + + This is mainly important for Windows, where the select() call in the + main thread is not being woken up when the tapreader thread calls + route(), causing a delay of up to 1 second before the output buffer is + flushed. This would cause bad performance when UDP communication is not + possible. + commit 25091454da21941dd92375ddbee7dd6151343058 Author: Guus Sliepen Date: Sun Jul 17 19:23:52 2011 +0200 @@ -76,6 +2038,20 @@ Date: Sat Jul 16 15:15:29 2011 +0200 The flag was set incorrectly, but for most ciphers this does not have any effect. AES in any of the block modes is picky about it though. +commit be2fc8b0458b1e2ced3b5de410356d8d8639acff +Author: Guus Sliepen +Date: Sat Jul 16 10:47:35 2011 +0200 + + Make code to detect two nodes with the same Name less triggerhappy. + + First of all, if there really are two nodes with the same name, much + more than 10 contradicting ADD_EDGE and DEL_EDGE messages will be sent. + Also, we forgot to reset the counters when nothing happened. + + In case there is a ADD_EDGE/DEL_EDGE storm, we do not shut down, but + sleep an increasing amount of time, allowing tinc to recover gracefully + from temporary failures. + commit 303dd1e70219a7542921f6e63d9391ab326d434f Author: Guus Sliepen Date: Wed Jul 13 22:52:52 2011 +0200 diff --git a/INSTALL b/INSTALL index 7d1c323..a1e89e1 100644 --- a/INSTALL +++ b/INSTALL @@ -1,8 +1,8 @@ Installation Instructions ************************* -Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005, -2006, 2007, 2008, 2009 Free Software Foundation, Inc. +Copyright (C) 1994-1996, 1999-2002, 2004-2011 Free Software Foundation, +Inc. Copying and distribution of this file, with or without modification, are permitted in any medium without royalty provided the copyright @@ -226,6 +226,11 @@ order to use an ANSI C compiler: and if that doesn't work, install pre-built binaries of GCC for HP-UX. + HP-UX `make' updates targets which have the same time stamps as +their prerequisites, which makes it generally unusable when shipped +generated files such as `configure' are involved. Use GNU `make' +instead. + On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot parse its `' header file. The option `-nodtk' can be used as a workaround. If GNU CC is not installed, it is therefore recommended diff --git a/Makefile.in b/Makefile.in index baa5005..3fe02c7 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1,9 +1,9 @@ -# Makefile.in generated by automake 1.11.1 from Makefile.am. +# Makefile.in generated by automake 1.11.6 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, -# Inc. +# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software +# Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -15,6 +15,23 @@ @SET_MAKE@ VPATH = @srcdir@ +am__make_dryrun = \ + { \ + am__dry=no; \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ + | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ + *) \ + for am__flg in $$MAKEFLAGS; do \ + case $$am__flg in \ + *=*|--*) ;; \ + *n*) am__dry=yes; break;; \ + esac; \ + done;; \ + esac; \ + test $$am__dry = yes; \ + } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ @@ -42,7 +59,8 @@ ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \ $(top_srcdir)/m4/curses.m4 $(top_srcdir)/m4/libevent.m4 \ $(top_srcdir)/m4/lzo.m4 $(top_srcdir)/m4/openssl.m4 \ - $(top_srcdir)/m4/zlib.m4 $(top_srcdir)/configure.in + $(top_srcdir)/m4/readline.m4 $(top_srcdir)/m4/zlib.m4 \ + $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ @@ -60,6 +78,11 @@ RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ install-pdf-recursive install-ps-recursive install-recursive \ installcheck-recursive installdirs-recursive pdf-recursive \ ps-recursive uninstall-recursive +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ @@ -72,9 +95,11 @@ DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) top_distdir = $(distdir) am__remove_distdir = \ - { test ! -d "$(distdir)" \ - || { find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ - && rm -fr "$(distdir)"; }; } + if test -d "$(distdir)"; then \ + find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ + && rm -rf "$(distdir)" \ + || { sleep 5 && rm -rf "$(distdir)"; }; \ + else :; fi am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ @@ -103,6 +128,8 @@ am__relativize = \ DIST_ARCHIVES = $(distdir).tar.gz GZIP_ENV = --best distuninstallcheck_listfiles = find . -type f -print +am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ + | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' distcleancheck_listfiles = find . -type f -print ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ @@ -152,6 +179,7 @@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ +READLINE_LIBS = @READLINE_LIBS@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ @@ -214,7 +242,7 @@ all: config.h $(MAKE) $(AM_MAKEFLAGS) all-recursive .SUFFIXES: -am--refresh: +am--refresh: Makefile @: $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ @@ -250,10 +278,8 @@ $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) $(am__aclocal_m4_deps): config.h: stamp-h1 - @if test ! -f $@; then \ - rm -f stamp-h1; \ - $(MAKE) $(AM_MAKEFLAGS) stamp-h1; \ - else :; fi + @if test ! -f $@; then rm -f stamp-h1; else :; fi + @if test ! -f $@; then $(MAKE) $(AM_MAKEFLAGS) stamp-h1; else :; fi stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status @rm -f stamp-h1 @@ -435,13 +461,10 @@ distdir: $(DISTFILES) done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ - test -d "$(distdir)/$$subdir" \ - || $(MKDIR_P) "$(distdir)/$$subdir" \ - || exit 1; \ - fi; \ - done - @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ - if test "$$subdir" = .; then :; else \ + $(am__make_dryrun) \ + || test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ @@ -473,7 +496,11 @@ dist-gzip: distdir $(am__remove_distdir) dist-bzip2: distdir - tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2 + tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2 + $(am__remove_distdir) + +dist-lzip: distdir + tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz $(am__remove_distdir) dist-lzma: distdir @@ -481,7 +508,7 @@ dist-lzma: distdir $(am__remove_distdir) dist-xz: distdir - tardir=$(distdir) && $(am__tar) | xz -c >$(distdir).tar.xz + tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz $(am__remove_distdir) dist-tarZ: distdir @@ -512,6 +539,8 @@ distcheck: dist bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ *.tar.lzma*) \ lzma -dc $(distdir).tar.lzma | $(am__untar) ;;\ + *.tar.lz*) \ + lzip -dc $(distdir).tar.lz | $(am__untar) ;;\ *.tar.xz*) \ xz -dc $(distdir).tar.xz | $(am__untar) ;;\ *.tar.Z*) \ @@ -521,7 +550,7 @@ distcheck: dist *.zip*) \ unzip $(distdir).zip ;;\ esac - chmod -R a-w $(distdir); chmod a+w $(distdir) + chmod -R a-w $(distdir); chmod u+w $(distdir) mkdir $(distdir)/_build mkdir $(distdir)/_inst chmod a-w $(distdir) @@ -531,6 +560,7 @@ distcheck: dist && am__cwd=`pwd` \ && $(am__cd) $(distdir)/_build \ && ../configure --srcdir=.. --prefix="$$dc_install_base" \ + $(AM_DISTCHECK_CONFIGURE_FLAGS) \ $(DISTCHECK_CONFIGURE_FLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) dvi \ @@ -559,8 +589,16 @@ distcheck: dist list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' distuninstallcheck: - @$(am__cd) '$(distuninstallcheck_dir)' \ - && test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \ + @test -n '$(distuninstallcheck_dir)' || { \ + echo 'ERROR: trying to run $@ with an empty' \ + '$$(distuninstallcheck_dir)' >&2; \ + exit 1; \ + }; \ + $(am__cd) '$(distuninstallcheck_dir)' || { \ + echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \ + exit 1; \ + }; \ + test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \ || { echo "ERROR: files left after uninstall:" ; \ if test -n "$(DESTDIR)"; then \ echo " (check DESTDIR support)"; \ @@ -591,10 +629,15 @@ install-am: all-am installcheck: installcheck-recursive install-strip: - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - `test -z '$(STRIP)' || \ - echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi mostlyclean-generic: clean-generic: @@ -681,17 +724,18 @@ uninstall-am: .PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ all all-am am--refresh check check-am clean clean-generic \ ctags ctags-recursive dist dist-all dist-bzip2 dist-gzip \ - dist-lzma dist-shar dist-tarZ dist-xz dist-zip distcheck \ - distclean distclean-generic distclean-hdr distclean-tags \ - distcleancheck distdir distuninstallcheck dvi dvi-am html \ - html-am info info-am install install-am install-data \ - install-data-am install-dvi install-dvi-am install-exec \ - install-exec-am install-html install-html-am install-info \ - install-info-am install-man install-pdf install-pdf-am \ - install-ps install-ps-am install-strip installcheck \ - installcheck-am installdirs installdirs-am maintainer-clean \ - maintainer-clean-generic mostlyclean mostlyclean-generic pdf \ - pdf-am ps ps-am tags tags-recursive uninstall uninstall-am + dist-lzip dist-lzma dist-shar dist-tarZ dist-xz dist-zip \ + distcheck distclean distclean-generic distclean-hdr \ + distclean-tags distcleancheck distdir distuninstallcheck dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-ps install-ps-am install-strip \ + installcheck installcheck-am installdirs installdirs-am \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-generic pdf pdf-am ps ps-am tags tags-recursive \ + uninstall uninstall-am ChangeLog: diff --git a/NEWS b/NEWS index 679040b..806f2b7 100644 --- a/NEWS +++ b/NEWS @@ -1,4 +1,28 @@ -Version 1.1pre2 Juli 17 2011 +Version 1.1pre3 October 14 2012 + + * New experimental protocol: + * Uses 521 bit ECDSA keys for authentication. + * Uses AES-256-CTR and HMAC-SHA256. + * Always provides perfect forward secrecy. + * Used for both meta-connections and VPN packets. + * VPN packets are encrypted end-to-end. + + * Many improvements to tincctl: + * "config" command shows/adds/changes configuration variables. + * "export" and "import" commands help exchange configuration files. + * "init" command sets up initial configuration files. + * "info" command shows details about a node, subnet or address. + * "log" command shows live log messages. + * Without a command it acts as a shell, with history and TAB completion. + * Improved starting/stopping tincd. + * Improved graph output. + + * When trying to directly send UDP packets to a node for which multiple + addresses are known, all of them are tried. + + * Many small fixes, code cleanups and documentation updates. + +Version 1.1pre2 July 17 2011 * .cookie files are renamed to .pid files, which are compatible with 1.0.x. @@ -28,6 +52,50 @@ Version 1.1pre1 June 25 2011 Thanks to Scott Lamb and Sven-Haegar Koch for their contributions to this version of tinc. +Version 1.0.19 June 25 2012 + + * Allow :: notation in IPv6 Subnets. + + * Add support for systemd style socket activation. + + * Allow environment variables to be used for the Name option. + + * Add basic support for SOCKS proxies, HTTP proxies, and proxying through an + external command. + +Version 1.0.18 March 25 2012 + + * Fixed IPv6 in switch mode by turning off DecrementTTL by default. + + * Allow a port number to be specified in BindToAddress, which also allows tinc + to listen on multiple ports. + + * Add support for multicast communication with UML/QEMU/KVM. + +Version 1.0.17 March 10 2012 + + * The DeviceType option can now be used to select dummy, raw socket, UML and + VDE devices without needing to recompile tinc. + + * Allow multiple BindToAddress statements. + + * Decrement TTL value of IPv4 and IPv6 packets. + + * Add LocalDiscovery option allowing tinc to detect peers that are behind the + same NAT. + + * Accept Subnets passed with the -o option when StrictSubnets = yes. + + * Disabling old RSA keys when generating new ones now also works properly on + Windows. + +Version 1.0.16 July 23 2011 + + * Fixed a performance issue with TCP communication under Windows. + + * Fixed code that, during network outages, would cause tinc to exit when it + thought two nodes with identical Names were on the VPN. + Version 1.0.15 June 24 2011 * Improved logging to file. diff --git a/README b/README index 09f6e6e..10cb0b5 100644 --- a/README +++ b/README @@ -1,7 +1,7 @@ -This is the README file for tinc version 1.1pre2. Installation +This is the README file for tinc version 1.1pre3. Installation instructions may be found in the INSTALL file. -tinc is Copyright (C) 1998-2011 by: +tinc is Copyright (C) 1998-2012 by: Ivo Timmermans, Guus Sliepen , @@ -29,82 +29,66 @@ protocol is not fixed yet. Security statement ------------------ -This version uses an experimental and unfinished cryptographic protocol. Use -it at your own risk. +This version uses an experimental and unfinished cryptographic protocol. Use it +at your own risk. Compatibility ------------- -Version 1.1pre2 is compatible with 1.0pre8, 1.0 and later, but not with older +Version 1.1pre3 is compatible with 1.0pre8, 1.0 and later, but not with older versions of tinc. When the ExperimentalProtocol option is used, tinc is still compatible with -1.0.X and 1.1pre2 itself, but not with any other 1.1preX version. +1.0.X and 1.1pre3 itself, but not with any other 1.1preX version. Requirements ------------ -Either OpenSSL (http://www.openssl.org/) or libgcrypt -(http://www.gnupg.org/download/#libgcrypt). - -The zlib library is used for optional compression. You can find it at -http://www.gzip.org/zlib/. - -The lzo library is also used for optional compression. You can find it at -http://www.oberhumer.com/opensource/lzo/. - -Since 1.1, the libevent library is used for the main event loop. You can find -it at http://monkey.org/~provos/libevent/. - In order to compile tinc, you will need a GNU C compiler environment. Please -ensure you have the latest stable versions of all the required libraries. +ensure you have the latest stable versions of all the required libraries: + +- OpenSSL (http://www.openssl.org/) version 1.0.0 or later. +- Libevent (http://monkey.org/~provos/libevent/) + +The following libraries are used by default, but can be disabled if necessary: + +- zlib (http://www.gzip.org/zlib/) +- lzo (http://www.oberhumer.com/opensource/lzo/) +- ncurses (http://invisible-island.net/ncurses/) +- readline (ftp://ftp.gnu.org/pub/gnu/readline/) Features -------- -This version of tinc supports multiple virtual networks at once. To -use this feature, you may supply a netname via the -n or --net -options. The standard locations for the config files will then be -/etc/tinc//. +Tinc is a peer-to-peer VPN daemon that supports VPNs with an arbitrary number +of nodes. Instead of configuring tunnels, you give tinc the location and +public key of a few nodes in the VPN. After making the initial connections to +those nodes, tinc will learn about all other nodes on the VPN, and will make +connections automatically. When direct connections are not possible, data will +be forwarded by intermediate nodes. -tincd regenerates its encryption key pairs. It does this on the first -activity after the keys have expired. This period is adjustable in the -configuration file, and the default time is 3600 seconds (one hour). +By default, nodes authenticate each other using 2048 bit RSA (or 521 bit +ECDSA*) keys. Traffic is encrypted using Blowfish in CBC mode (or AES-256 in +CTR mode*), authenticated using HMAC-SHA1 (or HMAC-SHA-256*), and is protected +against replay attacks. -This version supports multiple subnets at once. They are also sorted -on subnet mask size. This means that it is possible to have -overlapping subnets on the VPN, as long as their subnet mask sizes -differ. +*) When using the ExperimentalProtocol option. -Since pre5, tinc can operate in several routing modes. The default mode, -"router", works exactly like the older version, and uses Subnet lines to -determine the destination of packets. The other two modes, "switch" and "hub", -allow the tinc daemons to work together like a single network switch or hub. -This is useful for bridging networks. The latter modes only work properly on -Linux, FreeBSD and Windows. +Tinc fully supports IPv6. -The algorithms used for encryption and generating message authentication codes -can now be changed in the configuration files. All cipher and digest algorithms -supported by OpenSSL can be used. Useful ciphers are "blowfish" (default), -"bf-ofb", "des", "des3", etcetera. Useful digests are "sha1" (default), "md5", -etcetera. - -Support for routing IPv6 packets has been added. Just add Subnet lines with -IPv6 addresses (without using :: abbreviations) and use ifconfig or ip (from -the iproute package) to give the virtual network interface corresponding IPv6 -addresses. tinc does not provide autoconfiguration for IPv6 hosts, if you need -it use radvd or zebra. - -It is also possible to make tunnels to other tinc daemons over IPv6 networks, -if the operating system supports IPv6. tinc will automatically use both IPv6 -and IPv4 when available, but this can be changed by adding the option -"AddressFamily = ipv4" or "AddressFamily = ipv6" to the tinc.conf file. +Tinc can operate in several routing modes. In the default mode, "router", every +node is associated with one or more IPv4 and/or IPv6 Subnets. The other two +modes, "switch" and "hub", let the tinc daemons work together to form a virtual +Ethernet network switch or hub. Normally, when started tinc will detach and run in the background. In a native Windows environment this means tinc will intall itself as a service, which will restart after reboots. To prevent tinc from detaching or running as a service, use the -D option. +The status of the VPN can be queried using the "tincctl" tool, which connects +to a running tinc daemon via a control connection. The same tool also makes it +easy to start and stop tinc, and to change its configuration. diff --git a/THANKS b/THANKS index 4a6eae2..7d91271 100644 --- a/THANKS +++ b/THANKS @@ -3,12 +3,14 @@ We would like to thank the following people for their contributions to tinc: * Alexander Reil and Gemeinde Berg * Allesandro Gatti * Andreas van Cranenburgh +* Anthony G. Basile * Armijn Hemel * Brandon Black * Cris van Pelt * Delf Eldkraft * dnk * Enrique Zanardi +* Erik Tews * Flynn Marquardt * Grzegorz Dymarek * Hans Bayle @@ -26,13 +28,17 @@ We would like to thank the following people for their contributions to tinc: * Mark Glines * Markus Goetz * Martin Kihlgren +* Martin Schürrer * Matias Carrasco * Max Rijevski * Menno Smits +* Mesar Hameed * Michael Tokarev * Miles Nordin +* Nick Hibma * Nick Patavalis * Paul Littlefield +* Philipp Babel * Robert van der Meulen * Rumko * Scott Lamb @@ -40,6 +46,7 @@ We would like to thank the following people for their contributions to tinc: * Teemu Kiviniemi * Timothy Redaelli * Tonnerre Lombard +* Vil Brekin * Wessel Dankers * Wouter van Heyst diff --git a/aclocal.m4 b/aclocal.m4 index 3e5708a..4171fdd 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -1,7 +1,8 @@ -# generated automatically by aclocal 1.11.1 -*- Autoconf -*- +# generated automatically by aclocal 1.11.6 -*- Autoconf -*- # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, -# 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. +# 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, +# Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -13,8 +14,8 @@ m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl -m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.68],, -[m4_warning([this file was generated for autoconf 2.68. +m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],, +[m4_warning([this file was generated for autoconf 2.69. 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'.])]) @@ -143,12 +144,15 @@ AC_DEFUN([AM_PATH_LIBGCRYPT], AC_SUBST(LIBGCRYPT_LIBS) ]) -# Copyright (C) 2002, 2003, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. +# Copyright (C) 2002, 2003, 2005, 2006, 2007, 2008, 2011 Free Software +# Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. +# serial 1 + # AM_AUTOMAKE_VERSION(VERSION) # ---------------------------- # Automake X.Y traces this macro to ensure aclocal.m4 has been @@ -158,7 +162,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.1], [], +m4_if([$1], [1.11.6], [], [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl ]) @@ -174,19 +178,21 @@ 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.1])dnl +[AM_AUTOMAKE_VERSION([1.11.6])dnl m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) # AM_AUX_DIR_EXPAND -*- Autoconf -*- -# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. +# Copyright (C) 2001, 2003, 2005, 2011 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. +# serial 1 + # For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets # $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to # `$srcdir', `$srcdir/..', or `$srcdir/../..'. @@ -268,14 +274,14 @@ AC_CONFIG_COMMANDS_PRE( Usually this means the macro was only invoked conditionally.]]) fi])]) -# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2009 -# Free Software Foundation, Inc. +# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2009, +# 2010, 2011 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 10 +# serial 12 # There are a few dirty hacks below to avoid letting `AC_PROG_CC' be # written in clear, in which case automake, when reading aclocal.m4, @@ -315,6 +321,7 @@ AC_CACHE_CHECK([dependency style of $depcc], # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named `D' -- because `-MD' means `put the output # in D'. + rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. @@ -379,7 +386,7 @@ AC_CACHE_CHECK([dependency style of $depcc], break fi ;; - msvisualcpp | msvcmsys) + msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok `-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. @@ -444,10 +451,13 @@ AC_DEFUN([AM_DEP_TRACK], if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' + am__nodep='_no' fi AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) AC_SUBST([AMDEPBACKSLASH])dnl _AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl +AC_SUBST([am__nodep])dnl +_AM_SUBST_NOTMAKE([am__nodep])dnl ]) # Generate code to set up dependency tracking. -*- Autoconf -*- @@ -669,12 +679,15 @@ for _am_header in $config_headers :; do done echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) -# Copyright (C) 2001, 2003, 2005, 2008 Free Software Foundation, Inc. +# Copyright (C) 2001, 2003, 2005, 2008, 2011 Free Software Foundation, +# Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. +# serial 1 + # AM_PROG_INSTALL_SH # ------------------ # Define $install_sh. @@ -714,8 +727,8 @@ AC_SUBST([am__leading_dot])]) # Add --enable-maintainer-mode option to configure. -*- Autoconf -*- # From Jim Meyering -# Copyright (C) 1996, 1998, 2000, 2001, 2002, 2003, 2004, 2005, 2008 -# Free Software Foundation, Inc. +# Copyright (C) 1996, 1998, 2000, 2001, 2002, 2003, 2004, 2005, 2008, +# 2011 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -735,7 +748,7 @@ AC_DEFUN([AM_MAINTAINER_MODE], [disable], [m4_define([am_maintainer_other], [enable])], [m4_define([am_maintainer_other], [enable]) m4_warn([syntax], [unexpected argument to AM@&t@_MAINTAINER_MODE: $1])]) -AC_MSG_CHECKING([whether to am_maintainer_other maintainer-specific portions of Makefiles]) +AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles]) dnl maintainer-mode's default is 'disable' unless 'enable' is passed AC_ARG_ENABLE([maintainer-mode], [ --][am_maintainer_other][-maintainer-mode am_maintainer_other make rules and dependencies not useful @@ -846,12 +859,15 @@ else fi ]) -# Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +# Copyright (C) 2003, 2004, 2005, 2006, 2011 Free Software Foundation, +# Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. +# serial 1 + # AM_PROG_MKDIR_P # --------------- # Check for `mkdir -p'. @@ -874,13 +890,14 @@ esac # Helper functions for option handling. -*- Autoconf -*- -# Copyright (C) 2001, 2002, 2003, 2005, 2008 Free Software Foundation, Inc. +# Copyright (C) 2001, 2002, 2003, 2005, 2008, 2010 Free Software +# Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 4 +# serial 5 # _AM_MANGLE_OPTION(NAME) # ----------------------- @@ -888,13 +905,13 @@ AC_DEFUN([_AM_MANGLE_OPTION], [[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) # _AM_SET_OPTION(NAME) -# ------------------------------ +# -------------------- # Set option NAME. Presently that only means defining a flag for this option. AC_DEFUN([_AM_SET_OPTION], [m4_define(_AM_MANGLE_OPTION([$1]), 1)]) # _AM_SET_OPTIONS(OPTIONS) -# ---------------------------------- +# ------------------------ # OPTIONS is a space-separated list of Automake options. AC_DEFUN([_AM_SET_OPTIONS], [m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) @@ -970,12 +987,14 @@ Check your system clock]) fi AC_MSG_RESULT(yes)]) -# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. +# Copyright (C) 2001, 2003, 2005, 2011 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. +# serial 1 + # AM_PROG_INSTALL_STRIP # --------------------- # One issue with vendor `install' (even GNU) is that you can't @@ -998,13 +1017,13 @@ fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" AC_SUBST([INSTALL_STRIP_PROGRAM])]) -# Copyright (C) 2006, 2008 Free Software Foundation, Inc. +# Copyright (C) 2006, 2008, 2010 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 2 +# serial 3 # _AM_SUBST_NOTMAKE(VARIABLE) # --------------------------- @@ -1013,13 +1032,13 @@ AC_SUBST([INSTALL_STRIP_PROGRAM])]) AC_DEFUN([_AM_SUBST_NOTMAKE]) # AM_SUBST_NOTMAKE(VARIABLE) -# --------------------------- +# -------------------------- # Public sister of _AM_SUBST_NOTMAKE. AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) # Check how to create a tarball. -*- Autoconf -*- -# Copyright (C) 2004, 2005 Free Software Foundation, Inc. +# Copyright (C) 2004, 2005, 2012 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -1041,10 +1060,11 @@ AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) # a tarball read from stdin. # $(am__untar) < result.tar AC_DEFUN([_AM_PROG_TAR], -[# Always define AMTAR for backward compatibility. -AM_MISSING_PROG([AMTAR], [tar]) +[# Always define AMTAR for backward compatibility. Yes, it's still used +# in the wild :-( We should find a proper way to deprecate it ... +AC_SUBST([AMTAR], ['$${TAR-tar}']) m4_if([$1], [v7], - [am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'], + [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'], [m4_case([$1], [ustar],, [pax],, [m4_fatal([Unknown tar format])]) AC_MSG_CHECKING([how to create a $1 tar archive]) @@ -1118,4 +1138,5 @@ m4_include([m4/curses.m4]) m4_include([m4/libevent.m4]) m4_include([m4/lzo.m4]) m4_include([m4/openssl.m4]) +m4_include([m4/readline.m4]) m4_include([m4/zlib.m4]) diff --git a/config.guess b/config.guess index 40eaed4..d622a44 100755 --- a/config.guess +++ b/config.guess @@ -2,9 +2,9 @@ # 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, 2010, -# 2011 Free Software Foundation, Inc. +# 2011, 2012 Free Software Foundation, Inc. -timestamp='2011-05-11' +timestamp='2012-02-10' # 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 @@ -17,9 +17,7 @@ timestamp='2011-05-11' # General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA -# 02110-1301, USA. +# along with this program; if not, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a @@ -57,8 +55,8 @@ 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, 2009, 2010, 2011 Free -Software Foundation, Inc. +2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 +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." @@ -145,7 +143,7 @@ UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in *:NetBSD:*:*) # NetBSD (nbsd) targets should (where applicable) match one or - # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, + # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently # switched to ELF, *-*-netbsd* would select the old # object file format. This provides both forward @@ -792,13 +790,12 @@ EOF echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} exit ;; *:FreeBSD:*:*) - case ${UNAME_MACHINE} in - pc98) - echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + UNAME_PROCESSOR=`/usr/bin/uname -p` + case ${UNAME_PROCESSOR} in amd64) echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; *) - echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; esac exit ;; i*:CYGWIN*:*) @@ -807,6 +804,9 @@ EOF *:MINGW*:*) echo ${UNAME_MACHINE}-pc-mingw32 exit ;; + i*:MSYS*:*) + echo ${UNAME_MACHINE}-pc-msys + exit ;; i*:windows32*:*) # uname -m includes "-pc" on this system. echo ${UNAME_MACHINE}-mingw32 @@ -861,6 +861,13 @@ EOF i*86:Minix:*:*) echo ${UNAME_MACHINE}-pc-minix exit ;; + aarch64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + aarch64_be:Linux:*:*) + UNAME_MACHINE=aarch64_be + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; alpha:Linux:*:*) case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in EV5) UNAME_MACHINE=alphaev5 ;; @@ -895,13 +902,16 @@ EOF echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; cris:Linux:*:*) - echo cris-axis-linux-gnu + echo ${UNAME_MACHINE}-axis-linux-gnu exit ;; crisv32:Linux:*:*) - echo crisv32-axis-linux-gnu + echo ${UNAME_MACHINE}-axis-linux-gnu exit ;; frv:Linux:*:*) - echo frv-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + hexagon:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; i*86:Linux:*:*) LIBC=gnu @@ -943,7 +953,7 @@ EOF test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } ;; or32:Linux:*:*) - echo or32-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; padre:Linux:*:*) echo sparc-unknown-linux-gnu @@ -978,13 +988,13 @@ EOF echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; tile*:Linux:*:*) - echo ${UNAME_MACHINE}-tilera-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; vax:Linux:*:*) echo ${UNAME_MACHINE}-dec-linux-gnu exit ;; x86_64:Linux:*:*) - echo x86_64-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; xtensa*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu @@ -1315,6 +1325,9 @@ EOF i*86:AROS:*:*) echo ${UNAME_MACHINE}-pc-aros exit ;; + x86_64:VMkernel:*:*) + echo ${UNAME_MACHINE}-unknown-esx + exit ;; esac #echo '(No uname command or uname output not recognized.)' 1>&2 diff --git a/config.h.in b/config.h.in index 3d4493a..ce11d29 100644 --- a/config.h.in +++ b/config.h.in @@ -6,6 +6,12 @@ /* Support for tunemu */ #undef ENABLE_TUNEMU +/* Support for UML */ +#undef ENABLE_UML + +/* Support for VDE */ +#undef ENABLE_VDE + /* Define to 1 if you have the header file. */ #undef HAVE_ARPA_INET_H @@ -52,6 +58,12 @@ /* DragonFly */ #undef HAVE_DRAGONFLY +/* Define to 1 if you have the `ECDH_compute_key' function. */ +#undef HAVE_ECDH_COMPUTE_KEY + +/* Define to 1 if you have the `ECDSA_verify' function. */ +#undef HAVE_ECDSA_VERIFY + /* Define to 1 if you have the header file. */ #undef HAVE_EVENT_H @@ -88,6 +100,9 @@ /* Define to 1 if you have the `socket' library (-lsocket). */ #undef HAVE_LIBSOCKET +/* Define to 1 if you have the header file. */ +#undef HAVE_LIBVDEPLUG_DYN_H + /* Linux */ #undef HAVE_LINUX @@ -148,6 +163,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_NETINET_TCP_H +/* Define to 1 if you have the header file. */ +#undef HAVE_NETPACKET_PACKET_H + /* Define to 1 if you have the header file. */ #undef HAVE_NET_ETHERNET_H @@ -175,6 +193,12 @@ /* OpenBSD */ #undef HAVE_OPENBSD +/* Define to 1 if you have the header file. */ +#undef HAVE_OPENSSL_ECDH_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_OPENSSL_EC_H + /* Define to 1 if you have the header file. */ #undef HAVE_OPENSSL_ENGINE_H @@ -205,6 +229,15 @@ /* Define to 1 if you have the `RAND_pseudo_bytes' function. */ #undef HAVE_RAND_PSEUDO_BYTES +/* have readline support */ +#undef HAVE_READLINE + +/* Define to 1 if you have the header file. */ +#undef HAVE_READLINE_HISTORY_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_READLINE_READLINE_H + /* Define to 1 if you have the `select' function. */ #undef HAVE_SELECT diff --git a/config.sub b/config.sub index 30fdca8..6205f84 100755 --- a/config.sub +++ b/config.sub @@ -2,9 +2,9 @@ # Configuration validation subroutine script. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, # 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, -# 2011 Free Software Foundation, Inc. +# 2011, 2012 Free Software Foundation, Inc. -timestamp='2011-03-23' +timestamp='2012-04-18' # This file is (in principle) common to ALL GNU software. # The presence of a machine in this file suggests that SOME GNU software @@ -21,9 +21,7 @@ timestamp='2011-03-23' # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA -# 02110-1301, USA. +# along with this program; if not, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a @@ -76,8 +74,8 @@ version="\ GNU config.sub ($timestamp) Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, -2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free -Software Foundation, Inc. +2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 +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." @@ -132,6 +130,10 @@ case $maybe_os in os=-$maybe_os basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` ;; + android-linux) + os=-linux-android + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown + ;; *) basic_machine=`echo $1 | sed 's/-[^-]*$//'` if [ $basic_machine != $1 ] @@ -223,6 +225,12 @@ case $os in -isc*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; + -lynx*178) + os=-lynxos178 + ;; + -lynx*5) + os=-lynxos5 + ;; -lynx*) os=-lynxos ;; @@ -247,17 +255,22 @@ case $basic_machine in # Some are omitted here because they have special meanings below. 1750a | 580 \ | a29k \ + | aarch64 | aarch64_be \ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ | am33_2.0 \ | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \ + | be32 | be64 \ | bfin \ | c4x | clipper \ | d10v | d30v | dlx | dsp16xx \ + | epiphany \ | fido | fr30 | frv \ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | hexagon \ | i370 | i860 | i960 | ia64 \ | ip2k | iq2000 \ + | le32 | le64 \ | lm32 \ | m32c | m32r | m32rle | m68000 | m68k | m88k \ | maxq | mb | microblaze | mcore | mep | metag \ @@ -291,7 +304,7 @@ case $basic_machine in | pdp10 | pdp11 | pj | pjl \ | powerpc | powerpc64 | powerpc64le | powerpcle \ | pyramid \ - | rx \ + | rl78 | 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 \ @@ -300,7 +313,7 @@ case $basic_machine in | spu \ | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ | ubicom32 \ - | v850 | v850e \ + | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ | we32k \ | x86 | xc16x | xstormy16 | xtensa \ | z8k | z80) @@ -315,8 +328,7 @@ case $basic_machine in c6x) basic_machine=tic6x-unknown ;; - m6811 | m68hc11 | m6812 | m68hc12 | picochip) - # Motorola 68HC11/12. + m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | picochip) basic_machine=$basic_machine-unknown os=-none ;; @@ -329,7 +341,10 @@ case $basic_machine in strongarm | thumb | xscale) basic_machine=arm-unknown ;; - + xgate) + basic_machine=$basic_machine-unknown + os=-none + ;; xscaleeb) basic_machine=armeb-unknown ;; @@ -352,11 +367,13 @@ case $basic_machine in # Recognize the basic CPU types with company name. 580-* \ | a29k-* \ + | aarch64-* | aarch64_be-* \ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ | avr-* | avr32-* \ + | be32-* | be64-* \ | bfin-* | bs2000-* \ | c[123]* | c30-* | [cjt]90-* | c4x-* \ | clipper-* | craynv-* | cydra-* \ @@ -365,8 +382,10 @@ case $basic_machine in | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ | h8300-* | h8500-* \ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ + | hexagon-* \ | i*86-* | i860-* | i960-* | ia64-* \ | ip2k-* | iq2000-* \ + | le32-* | le64-* \ | lm32-* \ | m32c-* | m32r-* | m32rle-* \ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ @@ -400,7 +419,7 @@ case $basic_machine in | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ | pyramid-* \ - | romp-* | rs6000-* | rx-* \ + | rl78-* | 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-* \ @@ -408,10 +427,11 @@ case $basic_machine in | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \ | tahoe-* \ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ - | tile-* | tilegx-* \ + | tile*-* \ | tron-* \ | ubicom32-* \ - | v850-* | v850e-* | vax-* \ + | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ + | vax-* \ | we32k-* \ | x86-* | x86_64-* | xc16x-* | xps100-* \ | xstormy16-* | xtensa*-* \ @@ -711,7 +731,6 @@ case $basic_machine in i370-ibm* | ibm*) basic_machine=i370-ibm ;; -# I'm not sure what "Sysv32" means. Should this be sysv3.2? i*86v32) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv32 @@ -808,10 +827,18 @@ case $basic_machine in ms1-*) basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` ;; + msys) + basic_machine=i386-pc + os=-msys + ;; mvs) basic_machine=i370-ibm os=-mvs ;; + nacl) + basic_machine=le32-unknown + os=-nacl + ;; ncr3000) basic_machine=i486-ncr os=-sysv4 @@ -1120,13 +1147,8 @@ case $basic_machine in basic_machine=t90-cray os=-unicos ;; - # This must be matched before tile*. - tilegx*) - basic_machine=tilegx-unknown - os=-linux-gnu - ;; tile*) - basic_machine=tile-unknown + basic_machine=$basic_machine-unknown os=-linux-gnu ;; tx39) @@ -1336,7 +1358,7 @@ case $os in | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ | -chorusos* | -chorusrdb* | -cegcc* \ - | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ | -mingw32* | -linux-gnu* | -linux-android* \ | -linux-newlib* | -linux-uclibc* \ | -uxpv* | -beos* | -mpeix* | -udk* \ @@ -1521,6 +1543,9 @@ case $basic_machine in c4x-* | tic4x-*) os=-coff ;; + hexagon-*) + os=-elf + ;; tic54x-*) os=-coff ;; @@ -1548,9 +1573,6 @@ case $basic_machine in ;; m68000-sun) os=-sunos3 - # This also exists in the configure program, but was not the - # default. - # os=-sunos4 ;; m68*-cisco) os=-aout diff --git a/configure b/configure index a87b0e9..ecbfc43 100755 --- a/configure +++ b/configure @@ -1,11 +1,9 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68. +# Generated by GNU Autoconf 2.69. # # -# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, -# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software -# Foundation, Inc. +# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. # # # This configure script is free software; the Free Software Foundation @@ -134,6 +132,31 @@ export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH +# Use a proper internal environment variable to ensure we don't fall + # into an infinite loop, continuously re-executing ourselves. + if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then + _as_can_reexec=no; export _as_can_reexec; + # We cannot yet assume a decent shell, so we have to provide a +# neutralization value for shells without unset; and this also +# works around shells that cannot unset nonexistent variables. +# Preserve -v and -x to the replacement shell. +BASH_ENV=/dev/null +ENV=/dev/null +(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; +esac +exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +# Admittedly, this is quite paranoid, since all the known shells bail +# out after a failed `exec'. +$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 +as_fn_exit 255 + fi + # We don't want this to propagate to other subprocesses. + { _as_can_reexec=; unset _as_can_reexec;} if test "x$CONFIG_SHELL" = x; then as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : emulate sh @@ -167,7 +190,8 @@ if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : else exitcode=1; echo positional parameters were not saved. fi -test x\$exitcode = x0 || exit 1" +test x\$exitcode = x0 || exit 1 +test -x / || exit 1" as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && @@ -212,21 +236,25 @@ IFS=$as_save_IFS if test "x$CONFIG_SHELL" != x; then : - # We cannot yet assume a decent shell, so we have to provide a - # neutralization value for shells without unset; and this also - # works around shells that cannot unset nonexistent variables. - # Preserve -v and -x to the replacement shell. - BASH_ENV=/dev/null - ENV=/dev/null - (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV - export CONFIG_SHELL - case $- in # (((( - *v*x* | *x*v* ) as_opts=-vx ;; - *v* ) as_opts=-v ;; - *x* ) as_opts=-x ;; - * ) as_opts= ;; - esac - exec "$CONFIG_SHELL" $as_opts "$as_myself" ${1+"$@"} + export CONFIG_SHELL + # We cannot yet assume a decent shell, so we have to provide a +# neutralization value for shells without unset; and this also +# works around shells that cannot unset nonexistent variables. +# Preserve -v and -x to the replacement shell. +BASH_ENV=/dev/null +ENV=/dev/null +(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; +esac +exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +# Admittedly, this is quite paranoid, since all the known shells bail +# out after a failed `exec'. +$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 +exit 255 fi if test x$as_have_required = xno; then : @@ -328,6 +356,14 @@ $as_echo X"$as_dir" | } # as_fn_mkdir_p + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take @@ -449,6 +485,10 @@ as_cr_alnum=$as_cr_Letters$as_cr_digits chmod +x "$as_me.lineno" || { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } + # If we had to re-execute with $CONFIG_SHELL, we're ensured to have + # already done that, so ensure we don't try to do so again and fall + # in an infinite loop. This has already happened in practice. + _as_can_reexec=no; export _as_can_reexec # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). @@ -483,16 +523,16 @@ if (echo >conf$$.file) 2>/dev/null; then # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. - # In both cases, we have to default to `cp -p'. + # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || - as_ln_s='cp -p' + as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else - as_ln_s='cp -p' + as_ln_s='cp -pR' fi else - as_ln_s='cp -p' + as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null @@ -504,28 +544,8 @@ else as_mkdir_p=false fi -if test -x / >/dev/null 2>&1; then - as_test_x='test -x' -else - if ls -dL / >/dev/null 2>&1; then - as_ls_L_option=L - else - as_ls_L_option= - fi - as_test_x=' - eval sh -c '\'' - if test -d "$1"; then - test -d "$1/."; - else - case $1 in #( - -*)set "./$1";; - esac; - case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( - ???[sx]*):;;*)false;;esac;fi - '\'' sh - ' -fi -as_executable_p=$as_test_x +as_test_x='test -x' +as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" @@ -607,9 +627,14 @@ INCLUDES LIBGCRYPT_LIBS LIBGCRYPT_CFLAGS LIBGCRYPT_CONFIG +READLINE_LIBS CURSES_LIBS TUNEMU_FALSE TUNEMU_TRUE +VDE_FALSE +VDE_TRUE +UML_FALSE +UML_TRUE host_os host_vendor host_cpu @@ -626,6 +651,7 @@ MAINTAINER_MODE_TRUE am__fastdepCC_FALSE am__fastdepCC_TRUE CCDEPMODE +am__nodep AMDEPBACKSLASH AMDEP_FALSE AMDEP_TRUE @@ -708,6 +734,8 @@ ac_user_opts=' enable_option_checking enable_dependency_tracking enable_maintainer_mode +enable_uml +enable_vde enable_tunemu with_windows2000 with_libgcrypt @@ -715,6 +743,10 @@ enable_curses with_curses with_curses_include with_curses_lib +enable_readline +with_readline +with_readline_include +with_readline_lib with_libevent with_libevent_include with_libevent_lib @@ -1196,8 +1228,6 @@ target=$target_alias if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe - $as_echo "$as_me: WARNING: if you wanted to set the --build type, don't use --host. - If a cross compiler is detected then cross compile mode will be used" >&2 elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi @@ -1363,23 +1393,30 @@ Optional Features: --enable-dependency-tracking do not reject slow dependency extractors --enable-maintainer-mode enable make rules and dependencies not useful (and sometimes confusing) to the casual installer - --enable-tunemu enable support for the tunemu driver + --disable-uml enable support for User Mode Linux + --disable-vde enable support for Virtual Distributed Ethernet + --disable-tunemu enable support for the tunemu driver --disable-curses disable curses support + --disable-readline disable readline support --disable-zlib disable zlib compression support --disable-lzo disable lzo compression support - --enable-jumbograms enable support for jumbograms (packets up to 9000 + --disable-jumbograms enable support for jumbograms (packets up to 9000 bytes) Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) - --with-windows2000 compile with support for Windows 2000. This disables + --without-windows2000 compile with support for Windows 2000. This disables support for tunneling over existing IPv6 networks. --with-libgcrypt enable use of libgcrypt instead of OpenSSL] --with-curses=DIR curses base directory, or: --with-curses-include=DIR curses headers directory --with-curses-lib=DIR curses library directory + --with-readline=DIR readline base directory, or: + --with-readline-include=DIR + readline headers directory + --with-readline-lib=DIR readline library directory --with-libevent=DIR libevent base directory, or: --with-libevent-include=DIR libevent headers directory @@ -1475,9 +1512,9 @@ test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF configure -generated by GNU Autoconf 2.68 +generated by GNU Autoconf 2.69 -Copyright (C) 2010 Free Software Foundation, Inc. +Copyright (C) 2012 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF @@ -1804,7 +1841,7 @@ $as_echo "$ac_try_echo"; } >&5 test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || - $as_test_x conftest$ac_exeext + test -x conftest$ac_exeext }; then : ac_retval=0 else @@ -1940,7 +1977,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.68. Invocation command line was +generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -2310,7 +2347,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -2350,7 +2387,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -2403,7 +2440,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -2444,7 +2481,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue @@ -2502,7 +2539,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -2546,7 +2583,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -2992,8 +3029,7 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include -#include -#include +struct stat; /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); @@ -3233,7 +3269,7 @@ do for ac_prog in grep ggrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" - { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue + as_fn_executable_p "$ac_path_GREP" || continue # Check for GNU ac_path_GREP and select it if it is found. # Check for GNU $ac_path_GREP case `"$ac_path_GREP" --version 2>&1` in @@ -3299,7 +3335,7 @@ do for ac_prog in egrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" - { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue + as_fn_executable_p "$ac_path_EGREP" || continue # Check for GNU ac_path_EGREP and select it if it is found. # Check for GNU $ac_path_EGREP case `"$ac_path_EGREP" --version 2>&1` in @@ -3506,8 +3542,8 @@ else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -# define __EXTENSIONS__ 1 - $ac_includes_default +# define __EXTENSIONS__ 1 + $ac_includes_default int main () { @@ -3606,7 +3642,7 @@ case $as_dir/ in #(( # by default. for ac_prog in ginstall scoinst install; do for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then if test $ac_prog = install && grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. @@ -3775,7 +3811,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -3815,7 +3851,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_STRIP="strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -3866,7 +3902,7 @@ do test -z "$as_dir" && as_dir=. for ac_prog in mkdir gmkdir; do for ac_exec_ext in '' $ac_executable_extensions; do - { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; } || continue + as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext" || continue case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( 'mkdir (GNU coreutils) '* | \ 'mkdir (coreutils) '* | \ @@ -3919,7 +3955,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_AWK="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -4035,6 +4071,7 @@ fi if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' + am__nodep='_no' fi if test "x$enable_dependency_tracking" != xno; then AMDEP_TRUE= @@ -4067,7 +4104,7 @@ fi # Define the identity of the package. PACKAGE=tinc - VERSION=1.1pre2 + VERSION=1.1pre3 cat >>confdefs.h <<_ACEOF @@ -4097,11 +4134,11 @@ MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} # We need awk for the "check" target. The system "awk" is bad on # some platforms. -# Always define AMTAR for backward compatibility. +# Always define AMTAR for backward compatibility. Yes, it's still used +# in the wild :-( We should find a proper way to deprecate it ... +AMTAR='$${TAR-tar}' -AMTAR=${AMTAR-"${am_missing_run}tar"} - -am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -' +am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -' @@ -4119,6 +4156,7 @@ else # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named `D' -- because `-MD' means `put the output # in D'. + rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. @@ -4178,7 +4216,7 @@ else break fi ;; - msvisualcpp | msvcmsys) + msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok `-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. @@ -4414,7 +4452,7 @@ main () return 0; } _ACEOF -for ac_arg in '' -std=gnu99 -std=c99 -c99 -AC99 -xc99=all -qlanglvl=extc99 +for ac_arg in '' -std=gnu99 -std=c99 -c99 -AC99 -D_STDC_C99= -qlanglvl=extc99 do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO"; then : @@ -4611,7 +4649,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -4651,7 +4689,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_RANLIB="ranlib" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -4829,13 +4867,70 @@ $as_echo "#define HAVE_MINGW 1" >>confdefs.h ;; esac +# Check whether --enable-uml was given. +if test "${enable_uml+set}" = set; then : + enableval=$enable_uml; if test "x$enable_uml" = "xyes"; then : + +$as_echo "#define ENABLE_UML 1" >>confdefs.h + + uml=true + +else + uml=false +fi + +else + uml=false + +fi + + +# Check whether --enable-vde was given. +if test "${enable_vde+set}" = set; then : + enableval=$enable_vde; if test "x$enable_vde" = "xyes"; then : + for ac_header in libvdeplug_dyn.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "libvdeplug_dyn.h" "ac_cv_header_libvdeplug_dyn_h" "$ac_includes_default" +if test "x$ac_cv_header_libvdeplug_dyn_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBVDEPLUG_DYN_H 1 +_ACEOF + +else + as_fn_error $? "VDE plug header files not found." "$LINENO" 5; break +fi + +done + + +$as_echo "#define ENABLE_VDE 1" >>confdefs.h + + vde=true + +else + vde=false +fi + +else + vde=false + +fi + + # Check whether --enable-tunemu was given. if test "${enable_tunemu+set}" = set; then : - enableval=$enable_tunemu; + enableval=$enable_tunemu; if test "x$enable_tunemu" = "xyes"; then : + $as_echo "#define ENABLE_TUNEMU 1" >>confdefs.h - tunemu=true + tunemu=true +else + tunemu=false +fi + +else + tunemu=false fi @@ -4843,13 +4938,32 @@ fi # Check whether --with-windows2000 was given. if test "${with_windows2000+set}" = set; then : - withval=$with_windows2000; + withval=$with_windows2000; if test "x$with_windows2000" = "xyes"; then : + $as_echo "#define WITH_WINDOWS2000 1" >>confdefs.h +fi + fi + if test "$uml" = true; then + UML_TRUE= + UML_FALSE='#' +else + UML_TRUE='#' + UML_FALSE= +fi + + if test "$vde" = true; then + VDE_TRUE= + VDE_FALSE='#' +else + VDE_TRUE='#' + VDE_FALSE= +fi + if test "$tunemu" = true; then TUNEMU_TRUE= TUNEMU_FALSE='#' @@ -5078,7 +5192,7 @@ fi done -for ac_header in net/if.h net/if_types.h linux/if_tun.h net/if_tun.h net/tun/if_tun.h net/if_tap.h net/tap/if_tap.h net/ethernet.h net/if_arp.h netinet/in_systm.h netinet/in.h netinet/in6.h time.h +for ac_header in net/if.h net/if_types.h linux/if_tun.h net/if_tun.h net/tun/if_tun.h net/if_tap.h net/tap/if_tap.h net/ethernet.h net/if_arp.h netinet/in_systm.h netinet/in.h netinet/in6.h time.h netpacket/packet.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "#include \"have.h\" @@ -5135,11 +5249,11 @@ else int main () { -/* FIXME: Include the comments suggested by Paul. */ + #ifndef __cplusplus - /* Ultrix mips cc rejects this. */ + /* Ultrix mips cc rejects this sort of thing. */ typedef int charset[2]; - const charset cs; + const charset cs = { 0, 0 }; /* SunOS 4.1.1 cc rejects this. */ char const *const *pcpcc; char **ppc; @@ -5156,8 +5270,9 @@ main () ++pcpcc; ppc = (char**) pcpcc; pcpcc = (char const *const *) ppc; - { /* SCO 3.2v4 cc rejects this. */ - char *t; + { /* SCO 3.2v4 cc rejects this sort of thing. */ + char tx; + char *t = &tx; char const *s = 0 ? (char *) 0 : (char const *) 0; *t++ = 0; @@ -5173,10 +5288,10 @@ main () iptr p = 0; ++p; } - { /* AIX XL C 1.02.0.0 rejects this saying + { /* AIX XL C 1.02.0.0 rejects this sort of thing, saying "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ - struct s { int j; const int *ap[3]; }; - struct s *b; b->j = 5; + struct s { int j; const int *ap[3]; } bx; + struct s *b = &bx; b->j = 5; } { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ const int foo = 10; @@ -5925,6 +6040,111 @@ fi + # Check whether --enable-readline was given. +if test "${enable_readline+set}" = set; then : + enableval=$enable_readline; +fi + + if test "x$enable_readline" != "xno"; then : + + +$as_echo "#define HAVE_READLINE 1" >>confdefs.h + + readline=true + +# Check whether --with-readline was given. +if test "${with_readline+set}" = set; then : + withval=$with_readline; readline="$withval" + CPPFLAGS="$CPPFLAGS -I$withval/include" + LDFLAGS="$LDFLAGS -L$withval/lib" + +fi + + + +# Check whether --with-readline-include was given. +if test "${with_readline_include+set}" = set; then : + withval=$with_readline_include; readline_include="$withval" + CPPFLAGS="$CPPFLAGS -I$withval" + +fi + + + +# Check whether --with-readline-lib was given. +if test "${with_readline_lib+set}" = set; then : + withval=$with_readline_lib; readline_lib="$withval" + LDFLAGS="$LDFLAGS -L$withval" + +fi + + + for ac_header in readline/readline.h readline/history.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" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +else + as_fn_error $? "\"readline header files not found.\"" "$LINENO" 5; break + +fi + +done + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for readline in -lreadline" >&5 +$as_echo_n "checking for readline in -lreadline... " >&6; } +if ${ac_cv_lib_readline_readline+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lreadline $CURSES_LIBS + $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char readline (); +int +main () +{ +return readline (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_readline_readline=yes +else + ac_cv_lib_readline_readline=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_readline_readline" >&5 +$as_echo "$ac_cv_lib_readline_readline" >&6; } +if test "x$ac_cv_lib_readline_readline" = xyes; then : + READLINE_LIBS="-lreadline" +else + as_fn_error $? "\"readline library not found.\"" "$LINENO" 5 +fi + + +fi + + + + # Check whether --with-libevent was given. if test "${with_libevent+set}" = set; then : @@ -6326,7 +6546,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_LIBGCRYPT_CONFIG="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -6369,7 +6589,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_ac_pt_LIBGCRYPT_CONFIG="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -6596,7 +6816,7 @@ if test "${with_openssl_lib+set}" = set; then : fi - for ac_header in openssl/evp.h openssl/rsa.h openssl/rand.h openssl/err.h openssl/sha.h openssl/pem.h openssl/engine.h + for ac_header in openssl/evp.h openssl/rsa.h openssl/rand.h openssl/err.h openssl/sha.h openssl/pem.h openssl/engine.h openssl/ecdh.h openssl/ec.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" @@ -6657,7 +6877,7 @@ else fi - for ac_func in RAND_pseudo_bytes EVP_EncryptInit_ex + for ac_func in RAND_pseudo_bytes EVP_EncryptInit_ex ECDH_compute_key ECDSA_verify do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" @@ -6688,9 +6908,12 @@ fi # Check whether --enable-jumbograms was given. if test "${enable_jumbograms+set}" = set; then : - enableval=$enable_jumbograms; + enableval=$enable_jumbograms; if test "x$enable_jumbograms" = "xyes"; then : + $as_echo "#define ENABLE_JUMBOGRAMS 1" >>confdefs.h +fi + fi @@ -6829,6 +7052,14 @@ if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then as_fn_error $? "conditional \"MAINTAINER_MODE\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi +if test -z "${UML_TRUE}" && test -z "${UML_FALSE}"; then + as_fn_error $? "conditional \"UML\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${VDE_TRUE}" && test -z "${VDE_FALSE}"; then + as_fn_error $? "conditional \"VDE\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi if test -z "${TUNEMU_TRUE}" && test -z "${TUNEMU_FALSE}"; then as_fn_error $? "conditional \"TUNEMU\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 @@ -7131,16 +7362,16 @@ if (echo >conf$$.file) 2>/dev/null; then # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. - # In both cases, we have to default to `cp -p'. + # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || - as_ln_s='cp -p' + as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else - as_ln_s='cp -p' + as_ln_s='cp -pR' fi else - as_ln_s='cp -p' + as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null @@ -7200,28 +7431,16 @@ else as_mkdir_p=false fi -if test -x / >/dev/null 2>&1; then - as_test_x='test -x' -else - if ls -dL / >/dev/null 2>&1; then - as_ls_L_option=L - else - as_ls_L_option= - fi - as_test_x=' - eval sh -c '\'' - if test -d "$1"; then - test -d "$1/."; - else - case $1 in #( - -*)set "./$1";; - esac; - case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( - ???[sx]*):;;*)false;;esac;fi - '\'' sh - ' -fi -as_executable_p=$as_test_x + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p +as_test_x='test -x' +as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" @@ -7243,7 +7462,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.68. Invocation command line was +generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS @@ -7309,10 +7528,10 @@ 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.68, +configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" -Copyright (C) 2010 Free Software Foundation, Inc. +Copyright (C) 2012 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." @@ -7403,7 +7622,7 @@ fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 if \$ac_cs_recheck; then - set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion + set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion shift \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 CONFIG_SHELL='$SHELL' diff --git a/configure.in b/configure.in index 2e519b0..5781537 100644 --- a/configure.in +++ b/configure.in @@ -4,7 +4,7 @@ AC_PREREQ(2.61) AC_INIT AC_CONFIG_SRCDIR([src/tincd.c]) AC_GNU_SOURCE -AM_INIT_AUTOMAKE(tinc, 1.1pre2) +AM_INIT_AUTOMAKE(tinc, 1.1pre3) AC_CONFIG_HEADERS([config.h]) AM_MAINTAINER_MODE @@ -73,18 +73,49 @@ case $host_os in ;; esac +AC_ARG_ENABLE(uml, + AS_HELP_STRING([--disable-uml], [enable support for User Mode Linux]), + [ AS_IF([test "x$enable_uml" = "xyes"], + [ AC_DEFINE(ENABLE_UML, 1, [Support for UML]) + uml=true + ], + [uml=false]) + ], + [uml=false] +) + +AC_ARG_ENABLE(vde, + AS_HELP_STRING([--disable-vde], [enable support for Virtual Distributed Ethernet]), + [ AS_IF([test "x$enable_vde" = "xyes"], + [ AC_CHECK_HEADERS(libvdeplug_dyn.h, [], [AC_MSG_ERROR([VDE plug header files not found.]); break]) + AC_DEFINE(ENABLE_VDE, 1, [Support for VDE]) + vde=true + ], + [vde=false]) + ], + [vde=false] +) + AC_ARG_ENABLE(tunemu, - AS_HELP_STRING([--enable-tunemu], [enable support for the tunemu driver]), - [ AC_DEFINE(ENABLE_TUNEMU, 1, [Support for tunemu]) - tunemu=true - ] + AS_HELP_STRING([--disable-tunemu], [enable support for the tunemu driver]), + [ AS_IF([test "x$enable_tunemu" = "xyes"], + [ AC_DEFINE(ENABLE_TUNEMU, 1, [Support for tunemu]) + tunemu=true + ], + [tunemu=false]) + ], + [tunemu=false] ) AC_ARG_WITH(windows2000, - AS_HELP_STRING([--with-windows2000], [compile with support for Windows 2000. This disables support for tunneling over existing IPv6 networks.]), - [AC_DEFINE(WITH_WINDOWS2000, 1, [Compile with support for Windows 2000])] + AS_HELP_STRING([--without-windows2000], [compile with support for Windows 2000. This disables support for tunneling over existing IPv6 networks.]), + [ AS_IF([test "x$with_windows2000" = "xyes"], + [AC_DEFINE(WITH_WINDOWS2000, 1, [Compile with support for Windows 2000])]) + ] ) +AM_CONDITIONAL(UML, test "$uml" = true) +AM_CONDITIONAL(VDE, test "$vde" = true) AM_CONDITIONAL(TUNEMU, test "$tunemu" = true) AC_CACHE_SAVE @@ -101,7 +132,7 @@ dnl We do this in multiple stages, because unlike Linux all the other operating AC_HEADER_STDC AC_CHECK_HEADERS([stdbool.h syslog.h sys/file.h sys/ioctl.h sys/mman.h sys/param.h sys/resource.h sys/socket.h sys/time.h sys/uio.h sys/un.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/tun/if_tun.h net/if_tap.h net/tap/if_tap.h net/ethernet.h net/if_arp.h netinet/in_systm.h netinet/in.h netinet/in6.h time.h], +AC_CHECK_HEADERS([net/if.h net/if_types.h linux/if_tun.h net/if_tun.h net/tun/if_tun.h net/if_tap.h net/tap/if_tap.h net/ethernet.h net/if_arp.h netinet/in_systm.h netinet/in.h netinet/in6.h time.h netpacket/packet.h], [], [], [#include "have.h"] ) AC_CHECK_HEADERS([netinet/if_ether.h netinet/ip.h netinet/ip6.h], @@ -151,6 +182,7 @@ dnl These are defined in files in m4/ AC_ARG_WITH(libgcrypt, AC_HELP_STRING([--with-libgcrypt], [enable use of libgcrypt instead of OpenSSL])], []) tinc_CURSES +tinc_READLINE tinc_LIBEVENT tinc_ZLIB tinc_LZO @@ -166,8 +198,10 @@ fi dnl Check if support for jumbograms is requested AC_ARG_ENABLE(jumbograms, - AS_HELP_STRING([--enable-jumbograms], [enable support for jumbograms (packets up to 9000 bytes)]), - [ AC_DEFINE(ENABLE_JUMBOGRAMS, 1, [Support for jumbograms (packets up to 9000 bytes)]) ] + AS_HELP_STRING([--disable-jumbograms], [enable support for jumbograms (packets up to 9000 bytes)]), + [ AS_IF([test "x$enable_jumbograms" = "xyes"], + [ AC_DEFINE(ENABLE_JUMBOGRAMS, 1, [Support for jumbograms (packets up to 9000 bytes)]) ]) + ] ) AC_SUBST(INCLUDES) diff --git a/depcomp b/depcomp index df8eea7..25a39e6 100755 --- a/depcomp +++ b/depcomp @@ -1,10 +1,10 @@ #! /bin/sh # depcomp - compile a program generating dependencies as side-effects -scriptversion=2009-04-28.21; # UTC +scriptversion=2012-03-27.16; # UTC -# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006, 2007, 2009 Free -# Software Foundation, Inc. +# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006, 2007, 2009, 2010, +# 2011, 2012 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -28,7 +28,7 @@ scriptversion=2009-04-28.21; # UTC case $1 in '') - echo "$0: No command. Try \`$0 --help' for more information." 1>&2 + echo "$0: No command. Try '$0 --help' for more information." 1>&2 exit 1; ;; -h | --h*) @@ -40,11 +40,11 @@ as side-effects. Environment variables: depmode Dependency tracking mode. - source Source file read by `PROGRAMS ARGS'. - object Object file output by `PROGRAMS ARGS'. + source Source file read by 'PROGRAMS ARGS'. + object Object file output by 'PROGRAMS ARGS'. DEPDIR directory where to store dependencies. depfile Dependency file to output. - tmpdepfile Temporary file to use when outputing dependencies. + tmpdepfile Temporary file to use when outputting dependencies. libtool Whether libtool is used (yes/no). Report bugs to . @@ -57,6 +57,12 @@ EOF ;; esac +# A tabulation character. +tab=' ' +# A newline character. +nl=' +' + if test -z "$depmode" || test -z "$source" || test -z "$object"; then echo "depcomp: Variables source, object and depmode must be set" 1>&2 exit 1 @@ -90,10 +96,24 @@ if test "$depmode" = msvcmsys; then # This is just like msvisualcpp but w/o cygpath translation. # Just convert the backslash-escaped backslashes to single forward # slashes to satisfy depend.m4 - cygpath_u="sed s,\\\\\\\\,/,g" + cygpath_u='sed s,\\\\,/,g' depmode=msvisualcpp fi +if test "$depmode" = msvc7msys; then + # This is just like msvc7 but w/o cygpath translation. + # Just convert the backslash-escaped backslashes to single forward + # slashes to satisfy depend.m4 + cygpath_u='sed s,\\\\,/,g' + depmode=msvc7 +fi + +if test "$depmode" = xlc; then + # IBM C/C++ Compilers xlc/xlC can output gcc-like dependency informations. + gccflag=-qmakedep=gcc,-MF + depmode=gcc +fi + case "$depmode" in gcc3) ## gcc 3 implements dependency tracking that does exactly what @@ -148,20 +168,21 @@ gcc) ## The second -e expression handles DOS-style file names with drive letters. sed -e 's/^[^:]*: / /' \ -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" -## This next piece of magic avoids the `deleted header file' problem. +## This next piece of magic avoids the "deleted header file" problem. ## The problem is that when a header file which appears in a .P file ## is deleted, the dependency causes make to die (because there is ## typically no way to rebuild the header). We avoid this by adding ## dummy dependencies for each header file. Too bad gcc doesn't do ## this for us directly. - tr ' ' ' -' < "$tmpdepfile" | -## Some versions of gcc put a space before the `:'. On the theory + tr ' ' "$nl" < "$tmpdepfile" | +## Some versions of gcc put a space before the ':'. On the theory ## that the space means something, we add a space to the output as -## well. +## well. hp depmode also adds that space, but also prefixes the VPATH +## to the object. Take care to not repeat it in the output. ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. - sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \ + | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; @@ -193,18 +214,15 @@ sgi) # clever and replace this with sed code, as IRIX sed won't handle # lines with more than a fixed number of characters (4096 in # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; - # the IRIX cc adds comments like `#:fec' to the end of the + # the IRIX cc adds comments like '#:fec' to the end of the # dependency line. - tr ' ' ' -' < "$tmpdepfile" \ + tr ' ' "$nl" < "$tmpdepfile" \ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \ - tr ' -' ' ' >> "$depfile" + tr "$nl" ' ' >> "$depfile" echo >> "$depfile" # The second pass generates a dummy entry for each header file. - tr ' ' ' -' < "$tmpdepfile" \ + tr ' ' "$nl" < "$tmpdepfile" \ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ >> "$depfile" else @@ -216,10 +234,17 @@ sgi) rm -f "$tmpdepfile" ;; +xlc) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + aix) # The C for AIX Compiler uses -M and outputs the dependencies # in a .u file. In older versions, this file always lives in the - # current directory. Also, the AIX compiler puts `$object:' at the + # current directory. Also, the AIX compiler puts '$object:' at the # start of each line; $object doesn't have directory information. # Version 6 uses the directory in both cases. dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` @@ -249,12 +274,11 @@ aix) test -f "$tmpdepfile" && break done if test -f "$tmpdepfile"; then - # Each line is of the form `foo.o: dependent.h'. + # Each line is of the form 'foo.o: dependent.h'. # Do two passes, one to just change these to - # `$object: dependent.h' and one to simply `dependent.h:'. + # '$object: dependent.h' and one to simply 'dependent.h:'. sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" - # That's a tab and a space in the []. - sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" + sed -e 's,^.*\.[a-z]*:['"$tab"' ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" else # The sourcefile does not contain any dependencies, so just # store a dummy comment line, to avoid errors with the Makefile @@ -265,23 +289,26 @@ aix) ;; icc) - # Intel's C compiler understands `-MD -MF file'. However on - # icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c + # Intel's C compiler anf tcc (Tiny C Compiler) understand '-MD -MF file'. + # However on + # $CC -MD -MF foo.d -c -o sub/foo.o sub/foo.c # ICC 7.0 will fill foo.d with something like # foo.o: sub/foo.c # foo.o: sub/foo.h - # which is wrong. We want: + # which is wrong. We want # sub/foo.o: sub/foo.c # sub/foo.o: sub/foo.h # sub/foo.c: # sub/foo.h: # ICC 7.1 will output # foo.o: sub/foo.c sub/foo.h - # and will wrap long lines using \ : + # and will wrap long lines using '\': # foo.o: sub/foo.c ... \ # sub/foo.h ... \ # ... - + # tcc 0.9.26 (FIXME still under development at the moment of writing) + # will emit a similar output, but also prepend the continuation lines + # with horizontal tabulation characters. "$@" -MD -MF "$tmpdepfile" stat=$? if test $stat -eq 0; then : @@ -290,15 +317,21 @@ icc) exit $stat fi rm -f "$depfile" - # Each line is of the form `foo.o: dependent.h', - # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. + # Each line is of the form 'foo.o: dependent.h', + # or 'foo.o: dep1.h dep2.h \', or ' dep3.h dep4.h \'. # Do two passes, one to just change these to - # `$object: dependent.h' and one to simply `dependent.h:'. - sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" - # Some versions of the HPUX 10.20 sed can't process this invocation - # correctly. Breaking it into two sed invocations is a workaround. - sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" | - sed -e 's/$/ :/' >> "$depfile" + # '$object: dependent.h' and one to simply 'dependent.h:'. + sed -e "s/^[ $tab][ $tab]*/ /" -e "s,^[^:]*:,$object :," \ + < "$tmpdepfile" > "$depfile" + sed ' + s/[ '"$tab"'][ '"$tab"']*/ /g + s/^ *// + s/ *\\*$// + s/^[^:]*: *// + /^$/d + /:$/d + s/$/ :/ + ' < "$tmpdepfile" >> "$depfile" rm -f "$tmpdepfile" ;; @@ -334,7 +367,7 @@ hp2) done if test -f "$tmpdepfile"; then sed -e "s,^.*\.[a-z]*:,$object:," "$tmpdepfile" > "$depfile" - # Add `dependent.h:' lines. + # Add 'dependent.h:' lines. sed -ne '2,${ s/^ *// s/ \\*$// @@ -349,9 +382,9 @@ hp2) tru64) # The Tru64 compiler uses -MD to generate dependencies as a side - # effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'. + # effect. 'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'. # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put - # dependencies in `foo.d' instead, so we check for that too. + # dependencies in 'foo.d' instead, so we check for that too. # Subdirectories are respected. dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` test "x$dir" = "x$object" && dir= @@ -397,14 +430,59 @@ tru64) done if test -f "$tmpdepfile"; then sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" - # That's a tab and a space in the []. - sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" + sed -e 's,^.*\.[a-z]*:['"$tab"' ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" else echo "#dummy" > "$depfile" fi rm -f "$tmpdepfile" ;; +msvc7) + if test "$libtool" = yes; then + showIncludes=-Wc,-showIncludes + else + showIncludes=-showIncludes + fi + "$@" $showIncludes > "$tmpdepfile" + stat=$? + grep -v '^Note: including file: ' "$tmpdepfile" + if test "$stat" = 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + echo "$object : \\" > "$depfile" + # The first sed program below extracts the file names and escapes + # backslashes for cygpath. The second sed program outputs the file + # name when reading, but also accumulates all include files in the + # hold buffer in order to output them again at the end. This only + # works with sed implementations that can handle large buffers. + sed < "$tmpdepfile" -n ' +/^Note: including file: *\(.*\)/ { + s//\1/ + s/\\/\\\\/g + p +}' | $cygpath_u | sort -u | sed -n ' +s/ /\\ /g +s/\(.*\)/'"$tab"'\1 \\/p +s/.\(.*\) \\/\1:/ +H +$ { + s/.*/'"$tab"'/ + G + p +}' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvc7msys) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + #nosideeffect) # This comment above is used by automake to tell side-effect # dependency tracking mechanisms from slower ones. @@ -422,7 +500,7 @@ dashmstdout) shift fi - # Remove `-o $object'. + # Remove '-o $object'. IFS=" " for arg do @@ -442,15 +520,14 @@ dashmstdout) done test -z "$dashmflag" && dashmflag=-M - # Require at least two characters before searching for `:' + # Require at least two characters before searching for ':' # in the target name. This is to cope with DOS-style filenames: - # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise. + # a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise. "$@" $dashmflag | - sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile" + sed 's:^['"$tab"' ]*[^:'"$tab"' ][^:][^:]*\:['"$tab"' ]*:'"$object"'\: :' > "$tmpdepfile" rm -f "$depfile" cat < "$tmpdepfile" > "$depfile" - tr ' ' ' -' < "$tmpdepfile" | \ + tr ' ' "$nl" < "$tmpdepfile" | \ ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" @@ -503,9 +580,10 @@ makedepend) touch "$tmpdepfile" ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" rm -f "$depfile" - cat < "$tmpdepfile" > "$depfile" - sed '1,2d' "$tmpdepfile" | tr ' ' ' -' | \ + # makedepend may prepend the VPATH from the source file name to the object. + # No need to regex-escape $object, excess matching of '.' is harmless. + sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile" + sed '1,2d' "$tmpdepfile" | tr ' ' "$nl" | \ ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" @@ -525,7 +603,7 @@ cpp) shift fi - # Remove `-o $object'. + # Remove '-o $object'. IFS=" " for arg do @@ -594,8 +672,8 @@ msvisualcpp) sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" - sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile" - echo " " >> "$depfile" + sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile" + echo "$tab" >> "$depfile" sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile" rm -f "$tmpdepfile" ;; diff --git a/doc/Makefile.am b/doc/Makefile.am index 8f0305e..2ada5d7 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -23,16 +23,16 @@ texi2html: tinc.texi texi2html -split=chapter tinc.texi tincd.8.html: tincd.8 - w3mman2html $< > $@ + w3mman2html $? > $@ tincctl.8.html: tincctl.8 - w3mman2html $< > $@ + w3mman2html $? > $@ tinc-gui.8.html: tinc-gui.8 - w3mman2html $< > $@ + w3mman2html $? > $@ tinc.conf.5.html: tinc.conf.5 - w3mman2html $< > $@ + w3mman2html $? > $@ substitute = sed \ -e s,'@PACKAGE\@',"$(PACKAGE)",g \ @@ -41,18 +41,18 @@ substitute = sed \ -e s,'@localstatedir\@',"$(localstatedir)",g tincd.8: tincd.8.in - $(substitute) $< > $@ + $(substitute) $? > $@ tincctl.8: tincctl.8.in - $(substitute) $< > $@ + $(substitute) $? > $@ tinc-gui.8: tinc-gui.8.in - $(substitute) $< > $@ + $(substitute) $? > $@ tinc.conf.5: tinc.conf.5.in - $(substitute) $< > $@ + $(substitute) $? > $@ tincinclude.texi: tincinclude.texi.in - $(substitute) $< > $@ + $(substitute) $? > $@ tinc.texi: tincinclude.texi diff --git a/doc/Makefile.in b/doc/Makefile.in index b80f326..4610da9 100644 --- a/doc/Makefile.in +++ b/doc/Makefile.in @@ -1,9 +1,9 @@ -# Makefile.in generated by automake 1.11.1 from Makefile.am. +# Makefile.in generated by automake 1.11.6 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, -# Inc. +# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software +# Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -15,6 +15,23 @@ @SET_MAKE@ VPATH = @srcdir@ +am__make_dryrun = \ + { \ + am__dry=no; \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ + | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ + *) \ + for am__flg in $$MAKEFLAGS; do \ + case $$am__flg in \ + *=*|--*) ;; \ + *n*) am__dry=yes; break;; \ + esac; \ + done;; \ + esac; \ + test $$am__dry = yes; \ + } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ @@ -38,7 +55,8 @@ ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \ $(top_srcdir)/m4/curses.m4 $(top_srcdir)/m4/libevent.m4 \ $(top_srcdir)/m4/lzo.m4 $(top_srcdir)/m4/openssl.m4 \ - $(top_srcdir)/m4/zlib.m4 $(top_srcdir)/configure.in + $(top_srcdir)/m4/readline.m4 $(top_srcdir)/m4/zlib.m4 \ + $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d @@ -59,6 +77,11 @@ TEXI2PDF = $(TEXI2DVI) --pdf --batch MAKEINFOHTML = $(MAKEINFO) --html AM_MAKEINFOHTMLFLAGS = $(AM_MAKEINFOFLAGS) DVIPS = dvips +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac am__installdirs = "$(DESTDIR)$(infodir)" "$(DESTDIR)$(man5dir)" \ "$(DESTDIR)$(man8dir)" am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; @@ -82,6 +105,12 @@ am__nobase_list = $(am__nobase_strip_setup); \ am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } man5dir = $(mandir)/man5 man8dir = $(mandir)/man8 NROFF = nroff @@ -140,6 +169,7 @@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ +READLINE_LIBS = @READLINE_LIBS@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ @@ -304,9 +334,7 @@ uninstall-html-am: uninstall-info-am: @$(PRE_UNINSTALL) - @if test -d '$(DESTDIR)$(infodir)' && \ - (install-info --version && \ - install-info --version 2>&1 | sed 1q | grep -i -v debian) >/dev/null 2>&1; then \ + @if test -d '$(DESTDIR)$(infodir)' && $(am__can_run_installinfo); then \ list='$(INFO_DEPS)'; \ for file in $$list; do \ relfile=`echo "$$file" | sed 's|^.*/||'`; \ @@ -379,11 +407,18 @@ maintainer-clean-aminfo: done install-man5: $(man_MANS) @$(NORMAL_INSTALL) - test -z "$(man5dir)" || $(MKDIR_P) "$(DESTDIR)$(man5dir)" - @list=''; test -n "$(man5dir)" || exit 0; \ - { for i in $$list; do echo "$$i"; done; \ - l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ - sed -n '/\.5[a-z]*$$/p'; \ + @list1=''; \ + list2='$(man_MANS)'; \ + test -n "$(man5dir)" \ + && test -n "`echo $$list1$$list2`" \ + || exit 0; \ + echo " $(MKDIR_P) '$(DESTDIR)$(man5dir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(man5dir)" || exit 1; \ + { for i in $$list1; do echo "$$i"; done; \ + if test -n "$$list2"; then \ + for i in $$list2; do echo "$$i"; done \ + | sed -n '/\.5[a-z]*$$/p'; \ + fi; \ } | while read p; do \ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; echo "$$p"; \ @@ -412,16 +447,21 @@ uninstall-man5: sed -n '/\.5[a-z]*$$/p'; \ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^5][0-9a-z]*$$,5,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ - test -z "$$files" || { \ - echo " ( cd '$(DESTDIR)$(man5dir)' && rm -f" $$files ")"; \ - cd "$(DESTDIR)$(man5dir)" && rm -f $$files; } + dir='$(DESTDIR)$(man5dir)'; $(am__uninstall_files_from_dir) install-man8: $(man_MANS) @$(NORMAL_INSTALL) - test -z "$(man8dir)" || $(MKDIR_P) "$(DESTDIR)$(man8dir)" - @list=''; test -n "$(man8dir)" || exit 0; \ - { for i in $$list; do echo "$$i"; done; \ - l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ - sed -n '/\.8[a-z]*$$/p'; \ + @list1=''; \ + list2='$(man_MANS)'; \ + test -n "$(man8dir)" \ + && test -n "`echo $$list1$$list2`" \ + || exit 0; \ + echo " $(MKDIR_P) '$(DESTDIR)$(man8dir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(man8dir)" || exit 1; \ + { for i in $$list1; do echo "$$i"; done; \ + if test -n "$$list2"; then \ + for i in $$list2; do echo "$$i"; done \ + | sed -n '/\.8[a-z]*$$/p'; \ + fi; \ } | while read p; do \ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; echo "$$p"; \ @@ -450,9 +490,7 @@ uninstall-man8: sed -n '/\.8[a-z]*$$/p'; \ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ - test -z "$$files" || { \ - echo " ( cd '$(DESTDIR)$(man8dir)' && rm -f" $$files ")"; \ - cd "$(DESTDIR)$(man8dir)" && rm -f $$files; } + dir='$(DESTDIR)$(man8dir)'; $(am__uninstall_files_from_dir) tags: TAGS TAGS: @@ -523,10 +561,15 @@ install-am: all-am installcheck: installcheck-am install-strip: - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - `test -z '$(STRIP)' || \ - echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi mostlyclean-generic: clean-generic: @@ -565,8 +608,11 @@ install-dvi: install-dvi-am install-dvi-am: $(DVIS) @$(NORMAL_INSTALL) - test -z "$(dvidir)" || $(MKDIR_P) "$(DESTDIR)$(dvidir)" @list='$(DVIS)'; test -n "$(dvidir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(dvidir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(dvidir)" || exit 1; \ + fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ @@ -581,18 +627,22 @@ install-html: install-html-am install-html-am: $(HTMLS) @$(NORMAL_INSTALL) - test -z "$(htmldir)" || $(MKDIR_P) "$(DESTDIR)$(htmldir)" @list='$(HTMLS)'; list2=; test -n "$(htmldir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(htmldir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(htmldir)" || exit 1; \ + fi; \ for p in $$list; do \ if test -f "$$p" || test -d "$$p"; then d=; else d="$(srcdir)/"; fi; \ $(am__strip_dir) \ - if test -d "$$d$$p"; then \ + d2=$$d$$p; \ + if test -d "$$d2"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(htmldir)/$$f'"; \ $(MKDIR_P) "$(DESTDIR)$(htmldir)/$$f" || exit 1; \ - echo " $(INSTALL_DATA) '$$d$$p'/* '$(DESTDIR)$(htmldir)/$$f'"; \ - $(INSTALL_DATA) "$$d$$p"/* "$(DESTDIR)$(htmldir)/$$f" || exit $$?; \ + echo " $(INSTALL_DATA) '$$d2'/* '$(DESTDIR)$(htmldir)/$$f'"; \ + $(INSTALL_DATA) "$$d2"/* "$(DESTDIR)$(htmldir)/$$f" || exit $$?; \ else \ - list2="$$list2 $$d$$p"; \ + list2="$$list2 $$d2"; \ fi; \ done; \ test -z "$$list2" || { echo "$$list2" | $(am__base_list) | \ @@ -604,9 +654,12 @@ install-info: install-info-am install-info-am: $(INFO_DEPS) @$(NORMAL_INSTALL) - test -z "$(infodir)" || $(MKDIR_P) "$(DESTDIR)$(infodir)" @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ list='$(INFO_DEPS)'; test -n "$(infodir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(infodir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(infodir)" || exit 1; \ + fi; \ for file in $$list; do \ case $$file in \ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ @@ -624,8 +677,7 @@ install-info-am: $(INFO_DEPS) echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(infodir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(infodir)" || exit $$?; done @$(POST_INSTALL) - @if (install-info --version && \ - install-info --version 2>&1 | sed 1q | grep -i -v debian) >/dev/null 2>&1; then \ + @if $(am__can_run_installinfo); then \ list='$(INFO_DEPS)'; test -n "$(infodir)" || list=; \ for file in $$list; do \ relfile=`echo "$$file" | sed 's|^.*/||'`; \ @@ -639,8 +691,11 @@ install-pdf: install-pdf-am install-pdf-am: $(PDFS) @$(NORMAL_INSTALL) - test -z "$(pdfdir)" || $(MKDIR_P) "$(DESTDIR)$(pdfdir)" @list='$(PDFS)'; test -n "$(pdfdir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(pdfdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(pdfdir)" || exit 1; \ + fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ @@ -652,8 +707,11 @@ install-ps: install-ps-am install-ps-am: $(PSS) @$(NORMAL_INSTALL) - test -z "$(psdir)" || $(MKDIR_P) "$(DESTDIR)$(psdir)" @list='$(PSS)'; test -n "$(psdir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(psdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(psdir)" || exit 1; \ + fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ @@ -713,31 +771,31 @@ texi2html: tinc.texi texi2html -split=chapter tinc.texi tincd.8.html: tincd.8 - w3mman2html $< > $@ + w3mman2html $? > $@ tincctl.8.html: tincctl.8 - w3mman2html $< > $@ + w3mman2html $? > $@ tinc-gui.8.html: tinc-gui.8 - w3mman2html $< > $@ + w3mman2html $? > $@ tinc.conf.5.html: tinc.conf.5 - w3mman2html $< > $@ + w3mman2html $? > $@ tincd.8: tincd.8.in - $(substitute) $< > $@ + $(substitute) $? > $@ tincctl.8: tincctl.8.in - $(substitute) $< > $@ + $(substitute) $? > $@ tinc-gui.8: tinc-gui.8.in - $(substitute) $< > $@ + $(substitute) $? > $@ tinc.conf.5: tinc.conf.5.in - $(substitute) $< > $@ + $(substitute) $? > $@ tincinclude.texi: tincinclude.texi.in - $(substitute) $< > $@ + $(substitute) $? > $@ tinc.texi: tincinclude.texi diff --git a/doc/sample-config.tar.gz b/doc/sample-config.tar.gz index 3ad2d9a525b44c970be6c10d0ba1759bbd78531e..d7edc13ec53c0242d6f8827c97a86c3e59c1e427 100644 GIT binary patch literal 1237 zcmV;`1SH14RmPf~SAk#W|7Z|5{C^PHwErwG zr)-CFY~%kvez(T|{eIN&{~_cUM(zXvZ9Vv7P-$j`lCBiATwUOxIm_Yt7Fd>PZVad~ z76vRA)G;{Q0ESFL!l5!egJb~;3x|FjH$m&XwmkzZ@Iidq4NiMOe?U{*Ds5#|Bxo^K z8qi1;LQW_k$y18P1aQg6tjaCmwEbQ$Xps>*!*_BqsuIa9C||K=LfZ;MF1463%K?Yx zN;nqM^KD+xJ!?lHpnBm=Up(-~#)|_Xm z0ITp42uv;zCJ0Cxo-=7-F6 z1S4Cya}sV4gg7zTYcZL6muQaIE{K}SoLQWpFei{y2?&q7$cMYF;76qaYqLf}(Of2|3dfBD*P* zo?yH(@>nKjA|oF1)MC&c$u{F-A(0q_=c=D@^s9|m^2Z(~T1E^p(jonaL0I#|bNmPN zzSA?d1^-bzc>eoOga5k#FpCy;I z5`A=vxQL|ebUz7MeFOZ|S*<&lKCZJT`pxf+JCLXRuMPVfyVii3;oZ%#t^dQpHU2*h zyK%$+hY)OY>KlruKY!1oo^8`*)A%dBO4>QjHtW04M+eSUps^ literal 1246 zcmV<41R?t$iwFQZ1S3uW1MQe!Z`(Kw!26s}!J!8X2Q-fD#K|_G5B;|x*sfPJ-2r>L z$+nURwI!bcP-|v|k}wtpZ?z8LW-1KeAH(Nm$)yeO z%TdKLj^D`~EKBi1bKr$2g=CiJfivT93`R^O8q2p9jMXBu#R4QpQ^WKE%@{Qj0DJ)bCC0oFpNsC^rf`YRd2Vp@-V8&gPl~ywxUUQbSR20H4;KT2z{uk4Nr8pnS zO75ewsDvRw#teFqhD#%?nDL;s43bnqjWGb6q|3up85_Vg|ECt3CUZ#|$H0ne%2rlF zTCOFxPMN~Qe2ce zrJ+X8H5%KsD4A4vtJeZW?LRPKDJR_=tqLprl2QuBN@JSxTINhq;FU&yJ-y1aj|2gFFO(zwyW2UPe&^OR;Pr64kRgvHK1}JhkS+{G$C}GGU}^rrHm|@iD2P@OL!2Z5{f9xg?ADw0uMPYA zmM?-zi`nk>*i-e7zxE&0e>dz$P5nQI;5O%y<7VRi=Z`CYSF_*gWspN#0{`KEBDOz& zZ{G2*Og8JE8jRWbDd4Z4|3!mdbN=@%vTgn8RA855Jjs9YBmPU`r0M_9A$RA0KVgdv zESw{fOqQ>U9MXk1qU~~bmZmu}%1qPQFM zlAu2bqId6Uh%2S7tckfCIHHj%2{-SL&P=d=TGdC`X^{~+>nCAIK1NGU^Gt<|X^FcC zdFU;Ok31L>o}q_AW%$%nD&G17x222YJIIQIuoL%INvP_y5E&pzZKiA6EA_48SgSOu zU?O;{O>%niX?O|OqZ7FLdirH}2A?m!xd*Kv2)xS0<@r{HUt9le_3w^3ceux%s{eix zJ*@u$RuJqkg#F8Ft^d8%b=>U*U8?Q>Uf0RK$~t10000 \vskip\parskip \fi + \ifnum\centerpenalty>9999 \penalty\centerpenalty \fi + \line{\kern\leftskip #1\kern\rightskip}% } -\def\centerV#1{\line{\kern\leftskip #1\kern\rightskip}} % @sp n outputs n lines of vertical space - +% \parseargdef\sp{\vskip #1\baselineskip} % @comment ...line which is ignored... % @c is the same as @comment % @ignore ... @end ignore is another way to write a comment - +% \def\comment{\begingroup \catcode`\^^M=\other% \catcode`\@=\other \catcode`\{=\other \catcode`\}=\other% \commentxxx} {\catcode`\^^M=\other \gdef\commentxxx#1^^M{\endgroup}} - +% \let\c=\comment % @paragraphindent NCHARS @@ -1095,109 +1027,6 @@ where each line of input produces a line of output.} } -% @asis just yields its argument. Used with @table, for example. -% -\def\asis#1{#1} - -% @math outputs its argument in math mode. -% -% One complication: _ usually means subscripts, but it could also mean -% an actual _ character, as in @math{@var{some_variable} + 1}. So make -% _ active, and distinguish by seeing if the current family is \slfam, -% which is what @var uses. -{ - \catcode`\_ = \active - \gdef\mathunderscore{% - \catcode`\_=\active - \def_{\ifnum\fam=\slfam \_\else\sb\fi}% - } -} -% Another complication: we want \\ (and @\) to output a \ character. -% FYI, plain.tex uses \\ as a temporary control sequence (why?), but -% this is not advertised and we don't care. Texinfo does not -% otherwise define @\. -% -% The \mathchar is class=0=ordinary, family=7=ttfam, position=5C=\. -\def\mathbackslash{\ifnum\fam=\ttfam \mathchar"075C \else\backslash \fi} -% -\def\math{% - \tex - \mathunderscore - \let\\ = \mathbackslash - \mathactive - % make the texinfo accent commands work in math mode - \let\"=\ddot - \let\'=\acute - \let\==\bar - \let\^=\hat - \let\`=\grave - \let\u=\breve - \let\v=\check - \let\~=\tilde - \let\dotaccent=\dot - $\finishmath -} -\def\finishmath#1{#1$\endgroup} % Close the group opened by \tex. - -% Some active characters (such as <) are spaced differently in math. -% We have to reset their definitions in case the @math was an argument -% to a command which sets the catcodes (such as @item or @section). -% -{ - \catcode`^ = \active - \catcode`< = \active - \catcode`> = \active - \catcode`+ = \active - \catcode`' = \active - \gdef\mathactive{% - \let^ = \ptexhat - \let< = \ptexless - \let> = \ptexgtr - \let+ = \ptexplus - \let' = \ptexquoteright - } -} - -% Some math mode symbols. -\def\bullet{$\ptexbullet$} -\def\geq{\ifmmode \ge\else $\ge$\fi} -\def\leq{\ifmmode \le\else $\le$\fi} -\def\minus{\ifmmode -\else $-$\fi} - -% @dots{} outputs an ellipsis using the current font. -% We do .5em per period so that it has the same spacing in the cm -% typewriter fonts as three actual period characters; on the other hand, -% in other typewriter fonts three periods are wider than 1.5em. So do -% whichever is larger. -% -\def\dots{% - \leavevmode - \setbox0=\hbox{...}% get width of three periods - \ifdim\wd0 > 1.5em - \dimen0 = \wd0 - \else - \dimen0 = 1.5em - \fi - \hbox to \dimen0{% - \hskip 0pt plus.25fil - .\hskip 0pt plus1fil - .\hskip 0pt plus1fil - .\hskip 0pt plus.5fil - }% -} - -% @enddots{} is an end-of-sentence ellipsis. -% -\def\enddots{% - \dots - \spacefactor=\endofsentencespacefactor -} - -% @comma{} is so commas can be inserted into text without messing up -% Texinfo's parsing. -% -\let\comma = , - % @refill is a no-op. \let\refill=\relax @@ -1262,9 +1091,8 @@ where each line of input produces a line of output.} \newif\ifpdfmakepagedest % when pdftex is run in dvi mode, \pdfoutput is defined (so \pdfoutput=1 -% can be set). So we test for \relax and 0 as well as \undefined, -% borrowed from ifpdf.sty. -\ifx\pdfoutput\undefined +% can be set). So we test for \relax and 0 as well as being undefined. +\ifx\pdfoutput\thisisundefined \else \ifx\pdfoutput\relax \else @@ -1279,50 +1107,24 @@ where each line of input produces a line of output.} % for display in the outlines, and in other places. Thus, we have to % double any backslashes. Otherwise, a name like "\node" will be % interpreted as a newline (\n), followed by o, d, e. Not good. -% http://www.ntg.nl/pipermail/ntg-pdftex/2004-July/000654.html -% (and related messages, the final outcome is that it is up to the TeX -% user to double the backslashes and otherwise make the string valid, so -% that's what we do). +% +% See http://www.ntg.nl/pipermail/ntg-pdftex/2004-July/000654.html and +% related messages. The final outcome is that it is up to the TeX user +% to double the backslashes and otherwise make the string valid, so +% that's what we do. pdftex 1.30.0 (ca.2005) introduced a primitive to +% do this reliably, so we use it. -% double active backslashes. -% -{\catcode`\@=0 \catcode`\\=\active - @gdef@activebackslashdouble{% - @catcode`@\=@active - @let\=@doublebackslash} -} - -% To handle parens, we must adopt a different approach, since parens are -% not active characters. hyperref.dtx (which has the same problem as -% us) handles it with this amazing macro to replace tokens, with minor -% changes for Texinfo. It is included here under the GPL by permission -% from the author, Heiko Oberdiek. -% -% #1 is the tokens to replace. -% #2 is the replacement. -% #3 is the control sequence with the string. -% -\def\HyPsdSubst#1#2#3{% - \def\HyPsdReplace##1#1##2\END{% - ##1% - \ifx\\##2\\% - \else - #2% - \HyReturnAfterFi{% - \HyPsdReplace##2\END - }% - \fi - }% - \xdef#3{\expandafter\HyPsdReplace#3#1\END}% -} -\long\def\HyReturnAfterFi#1\fi{\fi#1} - -% #1 is a control sequence in which to do the replacements. -\def\backslashparens#1{% - \xdef#1{#1}% redefine it as its expansion; the definition is simply - % \lastnode when called from \setref -> \pdfmkdest. - \HyPsdSubst{(}{\realbackslash(}{#1}% - \HyPsdSubst{)}{\realbackslash)}{#1}% +% #1 is a control sequence in which to do the replacements, +% which we \xdef. +\def\txiescapepdf#1{% + \ifx\pdfescapestring\relax + % No primitive available; should we give a warning or log? + % Many times it won't matter. + \else + % The expandable \pdfescapestring primitive escapes parentheses, + % backslashes, and other special chars. + \xdef#1{\pdfescapestring{#1}}% + \fi } \newhelp\nopdfimagehelp{Texinfo supports .png, .jpg, .jpeg, and .pdf images @@ -1381,32 +1183,34 @@ output) for that.)} % % #1 is image name, #2 width (might be empty/whitespace), #3 height (ditto). \def\dopdfimage#1#2#3{% - \def\imagewidth{#2}\setbox0 = \hbox{\ignorespaces #2}% - \def\imageheight{#3}\setbox2 = \hbox{\ignorespaces #3}% + \def\pdfimagewidth{#2}\setbox0 = \hbox{\ignorespaces #2}% + \def\pdfimageheight{#3}\setbox2 = \hbox{\ignorespaces #3}% % - % pdftex (and the PDF format) support .png, .jpg, .pdf (among - % others). Let's try in that order. + % pdftex (and the PDF format) support .pdf, .png, .jpg (among + % others). Let's try in that order, PDF first since if + % someone has a scalable image, presumably better to use that than a + % bitmap. \let\pdfimgext=\empty \begingroup - \openin 1 #1.png \ifeof 1 - \openin 1 #1.jpg \ifeof 1 - \openin 1 #1.jpeg \ifeof 1 - \openin 1 #1.JPG \ifeof 1 - \openin 1 #1.pdf \ifeof 1 - \openin 1 #1.PDF \ifeof 1 + \openin 1 #1.pdf \ifeof 1 + \openin 1 #1.PDF \ifeof 1 + \openin 1 #1.png \ifeof 1 + \openin 1 #1.jpg \ifeof 1 + \openin 1 #1.jpeg \ifeof 1 + \openin 1 #1.JPG \ifeof 1 \errhelp = \nopdfimagehelp \errmessage{Could not find image file #1 for pdf}% - \else \gdef\pdfimgext{PDF}% + \else \gdef\pdfimgext{JPG}% \fi - \else \gdef\pdfimgext{pdf}% + \else \gdef\pdfimgext{jpeg}% \fi - \else \gdef\pdfimgext{JPG}% + \else \gdef\pdfimgext{jpg}% \fi - \else \gdef\pdfimgext{jpeg}% + \else \gdef\pdfimgext{png}% \fi - \else \gdef\pdfimgext{jpg}% + \else \gdef\pdfimgext{PDF}% \fi - \else \gdef\pdfimgext{png}% + \else \gdef\pdfimgext{pdf}% \fi \closein 1 \endgroup @@ -1418,8 +1222,8 @@ output) for that.)} \else \immediate\pdfximage \fi - \ifdim \wd0 >0pt width \imagewidth \fi - \ifdim \wd2 >0pt height \imageheight \fi + \ifdim \wd0 >0pt width \pdfimagewidth \fi + \ifdim \wd2 >0pt height \pdfimageheight \fi \ifnum\pdftexversion<13 #1.\pdfimgext \else @@ -1434,10 +1238,9 @@ output) for that.)} % such as \, aren't expanded when present in a section title. \indexnofonts \turnoffactive - \activebackslashdouble \makevalueexpandable \def\pdfdestname{#1}% - \backslashparens\pdfdestname + \txiescapepdf\pdfdestname \safewhatsit{\pdfdest name{\pdfdestname} xyz}% }} % @@ -1469,29 +1272,24 @@ output) for that.)} % page number. We could generate a destination for the section % text in the case where a section has no node, but it doesn't % seem worth the trouble, since most documents are normally structured. - \def\pdfoutlinedest{#3}% + \edef\pdfoutlinedest{#3}% \ifx\pdfoutlinedest\empty \def\pdfoutlinedest{#4}% \else - % Doubled backslashes in the name. - {\activebackslashdouble \xdef\pdfoutlinedest{#3}% - \backslashparens\pdfoutlinedest}% + \txiescapepdf\pdfoutlinedest \fi % - % Also double the backslashes in the display string. - {\activebackslashdouble \xdef\pdfoutlinetext{#1}% - \backslashparens\pdfoutlinetext}% + % Also escape PDF chars in the display string. + \edef\pdfoutlinetext{#1}% + \txiescapepdf\pdfoutlinetext % \pdfoutline goto name{\pdfmkpgn{\pdfoutlinedest}}#2{\pdfoutlinetext}% } % \def\pdfmakeoutlines{% \begingroup - % Thanh's hack / proper braces in bookmarks - \edef\mylbrace{\iftrue \string{\else}\fi}\let\{=\mylbrace - \edef\myrbrace{\iffalse{\else\string}\fi}\let\}=\myrbrace - % % Read toc silently, to get counts of subentries for \pdfoutline. + \def\partentry##1##2##3##4{}% ignore parts in the outlines \def\numchapentry##1##2##3##4{% \def\thischapnum{##2}% \def\thissecnum{0}% @@ -1545,15 +1343,26 @@ output) for that.)} % Latin 2 (0xea) gets translated to a | character. Info from % Staszek Wawrykiewicz, 19 Jan 2004 04:09:24 +0100. % - % xx to do this right, we have to translate 8-bit characters to - % their "best" equivalent, based on the @documentencoding. Right - % now, I guess we'll just let the pdf reader have its way. + % TODO this right, we have to translate 8-bit characters to + % their "best" equivalent, based on the @documentencoding. Too + % much work for too little return. Just use the ASCII equivalents + % we use for the index sort strings. + % \indexnofonts \setupdatafile + % We can have normal brace characters in the PDF outlines, unlike + % Texinfo index files. So set that up. + \def\{{\lbracecharliteral}% + \def\}{\rbracecharliteral}% \catcode`\\=\active \otherbackslash \input \tocreadfilename \endgroup } + {\catcode`[=1 \catcode`]=2 + \catcode`{=\other \catcode`}=\other + \gdef\lbracecharliteral[{]% + \gdef\rbracecharliteral[}]% + ] % \def\skipspaces#1{\def\PP{#1}\def\D{|}% \ifx\PP\D\let\nextsp\relax @@ -1563,7 +1372,13 @@ output) for that.)} \fi \fi \nextsp} - \def\getfilename#1{\filenamelength=0\expandafter\skipspaces#1|\relax} + \def\getfilename#1{% + \filenamelength=0 + % If we don't expand the argument now, \skipspaces will get + % snagged on things like "@value{foo}". + \edef\temp{#1}% + \expandafter\skipspaces\temp|\relax + } \ifnum\pdftexversion < 14 \let \startlink \pdfannotlink \else @@ -1695,7 +1510,7 @@ output) for that.)} % if we are producing pdf, and we have \pdffontattr, then define cmaps. % (\pdffontattr was introduced many years ago, but people still run % older pdftex's; it's easy to conditionalize, so we do.) -\ifpdf \ifx\pdffontattr\undefined \else +\ifpdf \ifx\pdffontattr\thisisundefined \else \begingroup \catcode`\^^M=\active \def^^M{^^J}% Output line endings as the ^^J char. \catcode`\%=12 \immediate\pdfobj stream {%!PS-Adobe-3.0 Resource-CMap @@ -1962,7 +1777,7 @@ end % Use cm as the default font prefix. % To specify the font prefix, you must define \fontprefix % before you read in texinfo.tex. -\ifx\fontprefix\undefined +\ifx\fontprefix\thisisundefined \def\fontprefix{cm} \fi % Support font families that don't use the same naming scheme as CM. @@ -2105,8 +1920,8 @@ end \font\reducedsy=cmsy10 \def\reducedecsize{1000} -% reset the current fonts -\textfonts +\textleading = 13.2pt % line spacing for 11pt CM +\textfonts % reset the current fonts \rm } % end of 11pt text font size definitions @@ -2236,11 +2051,9 @@ end \font\reducedsy=cmsy9 \def\reducedecsize{0900} -% reduce space between paragraphs -\divide\parskip by 2 - -% reset the current fonts -\textfonts +\divide\parskip by 2 % reduce space between paragraphs +\textleading = 12pt % line spacing for 10pt CM +\textfonts % reset the current fonts \rm } % end of 10pt text font size definitions @@ -2249,12 +2062,13 @@ end % @fonttextsize 10 % (or 11) to redefine the text font size. pt is assumed. % -\def\xword{10} \def\xiword{11} +\def\xword{10} +\def\xwordpt{10pt} % \parseargdef\fonttextsize{% \def\textsizearg{#1}% - \wlog{doing @fonttextsize \textsizearg}% + %\wlog{doing @fonttextsize \textsizearg}% % % Set \globaldefs so that documents can use this inside @tex, since % makeinfo 4.8 does not support it, but we need it nonetheless. @@ -2308,7 +2122,7 @@ end \let\tenttsl=\titlettsl \def\curfontsize{title}% \def\lsize{chap}\def\lllsize{subsec}% - \resetmathfonts \setleading{25pt}} + \resetmathfonts \setleading{27pt}} \def\titlefont#1{{\titlefonts\rmisbold #1}} \def\chapfonts{% \let\tenrm=\chaprm \let\tenit=\chapit \let\tensl=\chapsl @@ -2436,12 +2250,14 @@ end % Markup style setup for left and right quotes. \defmarkupstylesetup\markupsetuplq{% - \expandafter\let\expandafter \temp \csname markupsetuplq\currentmarkupstyle\endcsname + \expandafter\let\expandafter \temp + \csname markupsetuplq\currentmarkupstyle\endcsname \ifx\temp\relax \markupsetuplqdefault \else \temp \fi } \defmarkupstylesetup\markupsetuprq{% - \expandafter\let\expandafter \temp \csname markupsetuprq\currentmarkupstyle\endcsname + \expandafter\let\expandafter \temp + \csname markupsetuprq\currentmarkupstyle\endcsname \ifx\temp\relax \markupsetuprqdefault \else \temp \fi } @@ -2460,22 +2276,26 @@ end \let\markupsetuplqcode \markupsetcodequoteleft \let\markupsetuprqcode \markupsetcodequoteright +% \let\markupsetuplqexample \markupsetcodequoteleft \let\markupsetuprqexample \markupsetcodequoteright +% +\let\markupsetuplqsamp \markupsetcodequoteleft +\let\markupsetuprqsamp \markupsetcodequoteright +% \let\markupsetuplqverb \markupsetcodequoteleft \let\markupsetuprqverb \markupsetcodequoteright +% \let\markupsetuplqverbatim \markupsetcodequoteleft \let\markupsetuprqverbatim \markupsetcodequoteright -\let\markupsetuplqsamp \markupsetnoligaturesquoteleft \let\markupsetuplqkbd \markupsetnoligaturesquoteleft -% Allow an option to not replace quotes with a regular directed right -% quote/apostrophe (char 0x27), but instead use the undirected quote -% from cmtt (char 0x0d). The undirected quote is ugly, so don't make it -% the default, but it works for pasting with more pdf viewers (at least -% evince), the lilypond developers report. xpdf does work with the -% regular 0x27. +% Allow an option to not use regular directed right quote/apostrophe +% (char 0x27), but instead the undirected quote from cmtt (char 0x0d). +% The undirected quote is ugly, so don't make it the default, but it +% works for pasting with more pdf viewers (at least evince), the +% lilypond developers report. xpdf does work with the regular 0x27. % \def\codequoteright{% \expandafter\ifx\csname SETtxicodequoteundirected\endcsname\relax @@ -2499,33 +2319,84 @@ end \else \char'22 \fi } +% Commands to set the quote options. +% +\parseargdef\codequoteundirected{% + \def\temp{#1}% + \ifx\temp\onword + \expandafter\let\csname SETtxicodequoteundirected\endcsname + = t% + \else\ifx\temp\offword + \expandafter\let\csname SETtxicodequoteundirected\endcsname + = \relax + \else + \errhelp = \EMsimple + \errmessage{Unknown @codequoteundirected value `\temp', must be on|off}% + \fi\fi +} +% +\parseargdef\codequotebacktick{% + \def\temp{#1}% + \ifx\temp\onword + \expandafter\let\csname SETtxicodequotebacktick\endcsname + = t% + \else\ifx\temp\offword + \expandafter\let\csname SETtxicodequotebacktick\endcsname + = \relax + \else + \errhelp = \EMsimple + \errmessage{Unknown @codequotebacktick value `\temp', must be on|off}% + \fi\fi +} + % [Knuth] pp. 380,381,391, disable Spanish ligatures ?` and !` of \tt font. \def\noligaturesquoteleft{\relax\lq} % Count depth in font-changes, for error checks \newcount\fontdepth \fontdepth=0 -%% Add scribe-like font environments, plus @l for inline lisp (usually sans -%% serif) and @ii for TeX italic +% Font commands. -% \smartitalic{ARG} outputs arg in italics, followed by an italic correction -% unless the following character is such as not to need one. -\def\smartitalicx{\ifx\next,\else\ifx\next-\else\ifx\next.\else - \ptexslash\fi\fi\fi} -\def\smartslanted#1{{\ifusingtt\ttsl\sl #1}\futurelet\next\smartitalicx} -\def\smartitalic#1{{\ifusingtt\ttsl\it #1}\futurelet\next\smartitalicx} +% #1 is the font command (\sl or \it), #2 is the text to slant. +% If we are in a monospaced environment, however, 1) always use \ttsl, +% and 2) do not add an italic correction. +\def\dosmartslant#1#2{% + \ifusingtt + {{\ttsl #2}\let\next=\relax}% + {\def\next{{#1#2}\futurelet\next\smartitaliccorrection}}% + \next +} +\def\smartslanted{\dosmartslant\sl} +\def\smartitalic{\dosmartslant\it} -% like \smartslanted except unconditionally uses \ttsl. +% Output an italic correction unless \next (presumed to be the following +% character) is such as not to need one. +\def\smartitaliccorrection{% + \ifx\next,% + \else\ifx\next-% + \else\ifx\next.% + \else\ptexslash + \fi\fi\fi + \aftersmartic +} + +% like \smartslanted except unconditionally uses \ttsl, and no ic. % @var is set to this for defun arguments. -\def\ttslanted#1{{\ttsl #1}\futurelet\next\smartitalicx} +\def\ttslanted#1{{\ttsl #1}} % @cite is like \smartslanted except unconditionally use \sl. We never want % ttsl for book titles, do we? -\def\cite#1{{\sl #1}\futurelet\next\smartitalicx} +\def\cite#1{{\sl #1}\futurelet\next\smartitaliccorrection} + +\def\aftersmartic{} +\def\var#1{% + \let\saveaftersmartic = \aftersmartic + \def\aftersmartic{\null\let\aftersmartic=\saveaftersmartic}% + \smartslanted{#1}% +} \let\i=\smartitalic \let\slanted=\smartslanted -\def\var#1{{\setupmarkupstyle{var}\smartslanted{#1}}} \let\dfn=\smartslanted \let\emph=\smartitalic @@ -2621,7 +2492,7 @@ end \plainfrenchspacing #1% }% - \null + \null % reset spacefactor to 1000 } % We *must* turn on hyphenation at `-' and `_' in @code. @@ -2653,6 +2524,8 @@ end } } +\def\codex #1{\tclose{#1}\endgroup} + \def\realdash{-} \def\codedash{-\discretionary{}{}{}} \def\codeunder{% @@ -2666,7 +2539,6 @@ end \discretionary{}{}{}}% {\_}% } -\def\codex #1{\tclose{#1}\endgroup} % An additional complication: the above will allow breaks after, e.g., % each of the four underscores in __typeof__. This is undesirable in @@ -2686,10 +2558,156 @@ end \allowcodebreaksfalse \else \errhelp = \EMsimple - \errmessage{Unknown @allowcodebreaks option `\txiarg'}% + \errmessage{Unknown @allowcodebreaks option `\txiarg', must be true|false}% \fi\fi } +% @uref (abbreviation for `urlref') takes an optional (comma-separated) +% second argument specifying the text to display and an optional third +% arg as text to display instead of (rather than in addition to) the url +% itself. First (mandatory) arg is the url. +% (This \urefnobreak definition isn't used now, leaving it for a while +% for comparison.) +\def\urefnobreak#1{\dourefnobreak #1,,,\finish} +\def\dourefnobreak#1,#2,#3,#4\finish{\begingroup + \unsepspaces + \pdfurl{#1}% + \setbox0 = \hbox{\ignorespaces #3}% + \ifdim\wd0 > 0pt + \unhbox0 % third arg given, show only that + \else + \setbox0 = \hbox{\ignorespaces #2}% + \ifdim\wd0 > 0pt + \ifpdf + \unhbox0 % PDF: 2nd arg given, show only it + \else + \unhbox0\ (\code{#1})% DVI: 2nd arg given, show both it and url + \fi + \else + \code{#1}% only url given, so show it + \fi + \fi + \endlink +\endgroup} + +% This \urefbreak definition is the active one. +\def\urefbreak{\begingroup \urefcatcodes \dourefbreak} +\let\uref=\urefbreak +\def\dourefbreak#1{\urefbreakfinish #1,,,\finish} +\def\urefbreakfinish#1,#2,#3,#4\finish{% doesn't work in @example + \unsepspaces + \pdfurl{#1}% + \setbox0 = \hbox{\ignorespaces #3}% + \ifdim\wd0 > 0pt + \unhbox0 % third arg given, show only that + \else + \setbox0 = \hbox{\ignorespaces #2}% + \ifdim\wd0 > 0pt + \ifpdf + \unhbox0 % PDF: 2nd arg given, show only it + \else + \unhbox0\ (\urefcode{#1})% DVI: 2nd arg given, show both it and url + \fi + \else + \urefcode{#1}% only url given, so show it + \fi + \fi + \endlink +\endgroup} + +% Allow line breaks around only a few characters (only). +\def\urefcatcodes{% + \catcode\ampChar=\active \catcode\dotChar=\active + \catcode\hashChar=\active \catcode\questChar=\active + \catcode\slashChar=\active +} +{ + \urefcatcodes + % + \global\def\urefcode{\begingroup + \setupmarkupstyle{code}% + \urefcatcodes + \let&\urefcodeamp + \let.\urefcodedot + \let#\urefcodehash + \let?\urefcodequest + \let/\urefcodeslash + \codex + } + % + % By default, they are just regular characters. + \global\def&{\normalamp} + \global\def.{\normaldot} + \global\def#{\normalhash} + \global\def?{\normalquest} + \global\def/{\normalslash} +} + +% we put a little stretch before and after the breakable chars, to help +% line breaking of long url's. The unequal skips make look better in +% cmtt at least, especially for dots. +\def\urefprestretch{\urefprebreak \hskip0pt plus.13em } +\def\urefpoststretch{\urefpostbreak \hskip0pt plus.1em } +% +\def\urefcodeamp{\urefprestretch \&\urefpoststretch} +\def\urefcodedot{\urefprestretch .\urefpoststretch} +\def\urefcodehash{\urefprestretch \#\urefpoststretch} +\def\urefcodequest{\urefprestretch ?\urefpoststretch} +\def\urefcodeslash{\futurelet\next\urefcodeslashfinish} +{ + \catcode`\/=\active + \global\def\urefcodeslashfinish{% + \urefprestretch \slashChar + % Allow line break only after the final / in a sequence of + % slashes, to avoid line break between the slashes in http://. + \ifx\next/\else \urefpoststretch \fi + } +} + +% One more complication: by default we'll break after the special +% characters, but some people like to break before the special chars, so +% allow that. Also allow no breaking at all, for manual control. +% +\parseargdef\urefbreakstyle{% + \def\txiarg{#1}% + \ifx\txiarg\wordnone + \def\urefprebreak{\nobreak}\def\urefpostbreak{\nobreak} + \else\ifx\txiarg\wordbefore + \def\urefprebreak{\allowbreak}\def\urefpostbreak{\nobreak} + \else\ifx\txiarg\wordafter + \def\urefprebreak{\nobreak}\def\urefpostbreak{\allowbreak} + \else + \errhelp = \EMsimple + \errmessage{Unknown @urefbreakstyle setting `\txiarg'}% + \fi\fi\fi +} +\def\wordafter{after} +\def\wordbefore{before} +\def\wordnone{none} + +\urefbreakstyle after + +% @url synonym for @uref, since that's how everyone uses it. +% +\let\url=\uref + +% rms does not like angle brackets --karl, 17may97. +% So now @email is just like @uref, unless we are pdf. +% +%\def\email#1{\angleleft{\tt #1}\angleright} +\ifpdf + \def\email#1{\doemail#1,,\finish} + \def\doemail#1,#2,#3\finish{\begingroup + \unsepspaces + \pdfurl{mailto:#1}% + \setbox0 = \hbox{\ignorespaces #2}% + \ifdim\wd0>0pt\unhbox0\else\code{#1}\fi + \endlink + \endgroup} +\else + \let\email=\uref +\fi + % @kbd is like @code, except that if the argument is just one @key command, % then @kbd has no effect. \def\kbd#1{{\setupmarkupstyle{kbd}\def\look{#1}\expandafter\kbdfoo\look??\par}} @@ -2707,7 +2725,7 @@ end \gdef\kbdexamplefont{\tt}\gdef\kbdfont{\tt}% \else \errhelp = \EMsimple - \errmessage{Unknown @kbdinputstyle option `\txiarg'}% + \errmessage{Unknown @kbdinputstyle setting `\txiarg'}% \fi\fi\fi } \def\worddistinct{distinct} @@ -2735,55 +2753,6 @@ end \parseargdef\clickstyle{\def\click{#1}} \def\click{\arrow} -% @uref (abbreviation for `urlref') takes an optional (comma-separated) -% second argument specifying the text to display and an optional third -% arg as text to display instead of (rather than in addition to) the url -% itself. First (mandatory) arg is the url. Perhaps eventually put in -% a hypertex \special here. -% -\def\uref#1{\douref #1,,,\finish} -\def\douref#1,#2,#3,#4\finish{\begingroup - \unsepspaces - \pdfurl{#1}% - \setbox0 = \hbox{\ignorespaces #3}% - \ifdim\wd0 > 0pt - \unhbox0 % third arg given, show only that - \else - \setbox0 = \hbox{\ignorespaces #2}% - \ifdim\wd0 > 0pt - \ifpdf - \unhbox0 % PDF: 2nd arg given, show only it - \else - \unhbox0\ (\code{#1})% DVI: 2nd arg given, show both it and url - \fi - \else - \code{#1}% only url given, so show it - \fi - \fi - \endlink -\endgroup} - -% @url synonym for @uref, since that's how everyone uses it. -% -\let\url=\uref - -% rms does not like angle brackets --karl, 17may97. -% So now @email is just like @uref, unless we are pdf. -% -%\def\email#1{\angleleft{\tt #1}\angleright} -\ifpdf - \def\email#1{\doemail#1,,\finish} - \def\doemail#1,#2,#3\finish{\begingroup - \unsepspaces - \pdfurl{mailto:#1}% - \setbox0 = \hbox{\ignorespaces #2}% - \ifdim\wd0>0pt\unhbox0\else\code{#1}\fi - \endlink - \endgroup} -\else - \let\email=\uref -\fi - % Typeset a dimension, e.g., `in' or `pt'. The only reason for the % argument is to make the input look right: @dmn{pt} instead of @dmn{}pt. % @@ -2805,6 +2774,7 @@ end \ifx\temp\empty \else \space ({\unsepspaces \ignorespaces \temp \unskip})% \fi + \null % reset \spacefactor=1000 } % @abbr for "Comput. J." and the like. @@ -2817,10 +2787,219 @@ end \ifx\temp\empty \else \space ({\unsepspaces \ignorespaces \temp \unskip})% \fi + \null % reset \spacefactor=1000 +} + +% @asis just yields its argument. Used with @table, for example. +% +\def\asis#1{#1} + +% @math outputs its argument in math mode. +% +% One complication: _ usually means subscripts, but it could also mean +% an actual _ character, as in @math{@var{some_variable} + 1}. So make +% _ active, and distinguish by seeing if the current family is \slfam, +% which is what @var uses. +{ + \catcode`\_ = \active + \gdef\mathunderscore{% + \catcode`\_=\active + \def_{\ifnum\fam=\slfam \_\else\sb\fi}% + } +} +% Another complication: we want \\ (and @\) to output a math (or tt) \. +% FYI, plain.tex uses \\ as a temporary control sequence (for no +% particular reason), but this is not advertised and we don't care. +% +% The \mathchar is class=0=ordinary, family=7=ttfam, position=5C=\. +\def\mathbackslash{\ifnum\fam=\ttfam \mathchar"075C \else\backslash \fi} +% +\def\math{% + \tex + \mathunderscore + \let\\ = \mathbackslash + \mathactive + % make the texinfo accent commands work in math mode + \let\"=\ddot + \let\'=\acute + \let\==\bar + \let\^=\hat + \let\`=\grave + \let\u=\breve + \let\v=\check + \let\~=\tilde + \let\dotaccent=\dot + $\finishmath +} +\def\finishmath#1{#1$\endgroup} % Close the group opened by \tex. + +% Some active characters (such as <) are spaced differently in math. +% We have to reset their definitions in case the @math was an argument +% to a command which sets the catcodes (such as @item or @section). +% +{ + \catcode`^ = \active + \catcode`< = \active + \catcode`> = \active + \catcode`+ = \active + \catcode`' = \active + \gdef\mathactive{% + \let^ = \ptexhat + \let< = \ptexless + \let> = \ptexgtr + \let+ = \ptexplus + \let' = \ptexquoteright + } +} + +% @inlinefmt{FMTNAME,PROCESSED-TEXT} and @inlineraw{FMTNAME,RAW-TEXT}. +% Ignore unless FMTNAME == tex; then it is like @iftex and @tex, +% except specified as a normal braced arg, so no newlines to worry about. +% +\def\outfmtnametex{tex} +% +\long\def\inlinefmt#1{\doinlinefmt #1,\finish} +\long\def\doinlinefmt#1,#2,\finish{% + \def\inlinefmtname{#1}% + \ifx\inlinefmtname\outfmtnametex \ignorespaces #2\fi +} +% For raw, must switch into @tex before parsing the argument, to avoid +% setting catcodes prematurely. Doing it this way means that, for +% example, @inlineraw{html, foo{bar} gets a parse error instead of being +% ignored. But this isn't important because if people want a literal +% *right* brace they would have to use a command anyway, so they may as +% well use a command to get a left brace too. We could re-use the +% delimiter character idea from \verb, but it seems like overkill. +% +\long\def\inlineraw{\tex \doinlineraw} +\long\def\doinlineraw#1{\doinlinerawtwo #1,\finish} +\def\doinlinerawtwo#1,#2,\finish{% + \def\inlinerawname{#1}% + \ifx\inlinerawname\outfmtnametex \ignorespaces #2\fi + \endgroup % close group opened by \tex. } \message{glyphs,} +% and logos. + +% @@ prints an @, as does @atchar{}. +\def\@{\char64 } +\let\atchar=\@ + +% @{ @} @lbracechar{} @rbracechar{} all generate brace characters. +% Unless we're in typewriter, use \ecfont because the CM text fonts do +% not have braces, and we don't want to switch into math. +\def\mylbrace{{\ifmonospace\else\ecfont\fi \char123}} +\def\myrbrace{{\ifmonospace\else\ecfont\fi \char125}} +\let\{=\mylbrace \let\lbracechar=\{ +\let\}=\myrbrace \let\rbracechar=\} +\begingroup + % Definitions to produce \{ and \} commands for indices, + % and @{ and @} for the aux/toc files. + \catcode`\{ = \other \catcode`\} = \other + \catcode`\[ = 1 \catcode`\] = 2 + \catcode`\! = 0 \catcode`\\ = \other + !gdef!lbracecmd[\{]% + !gdef!rbracecmd[\}]% + !gdef!lbraceatcmd[@{]% + !gdef!rbraceatcmd[@}]% +!endgroup + +% @comma{} to avoid , parsing problems. +\let\comma = , + +% Accents: @, @dotaccent @ringaccent @ubaraccent @udotaccent +% Others are defined by plain TeX: @` @' @" @^ @~ @= @u @v @H. +\let\, = \ptexc +\let\dotaccent = \ptexdot +\def\ringaccent#1{{\accent23 #1}} +\let\tieaccent = \ptext +\let\ubaraccent = \ptexb +\let\udotaccent = \d + +% Other special characters: @questiondown @exclamdown @ordf @ordm +% Plain TeX defines: @AA @AE @O @OE @L (plus lowercase versions) @ss. +\def\questiondown{?`} +\def\exclamdown{!`} +\def\ordf{\leavevmode\raise1ex\hbox{\selectfonts\lllsize \underbar{a}}} +\def\ordm{\leavevmode\raise1ex\hbox{\selectfonts\lllsize \underbar{o}}} + +% Dotless i and dotless j, used for accents. +\def\imacro{i} +\def\jmacro{j} +\def\dotless#1{% + \def\temp{#1}% + \ifx\temp\imacro \ifmmode\imath \else\ptexi \fi + \else\ifx\temp\jmacro \ifmmode\jmath \else\j \fi + \else \errmessage{@dotless can be used only with i or j}% + \fi\fi +} + +% The \TeX{} logo, as in plain, but resetting the spacing so that a +% period following counts as ending a sentence. (Idea found in latex.) +% +\edef\TeX{\TeX \spacefactor=1000 } + +% @LaTeX{} logo. Not quite the same results as the definition in +% latex.ltx, since we use a different font for the raised A; it's most +% convenient for us to use an explicitly smaller font, rather than using +% the \scriptstyle font (since we don't reset \scriptstyle and +% \scriptscriptstyle). +% +\def\LaTeX{% + L\kern-.36em + {\setbox0=\hbox{T}% + \vbox to \ht0{\hbox{% + \ifx\textnominalsize\xwordpt + % for 10pt running text, \lllsize (8pt) is too small for the A in LaTeX. + % Revert to plain's \scriptsize, which is 7pt. + \count255=\the\fam $\fam\count255 \scriptstyle A$% + \else + % For 11pt, we can use our lllsize. + \selectfonts\lllsize A% + \fi + }% + \vss + }}% + \kern-.15em + \TeX +} + +% Some math mode symbols. +\def\bullet{$\ptexbullet$} +\def\geq{\ifmmode \ge\else $\ge$\fi} +\def\leq{\ifmmode \le\else $\le$\fi} +\def\minus{\ifmmode -\else $-$\fi} + +% @dots{} outputs an ellipsis using the current font. +% We do .5em per period so that it has the same spacing in the cm +% typewriter fonts as three actual period characters; on the other hand, +% in other typewriter fonts three periods are wider than 1.5em. So do +% whichever is larger. +% +\def\dots{% + \leavevmode + \setbox0=\hbox{...}% get width of three periods + \ifdim\wd0 > 1.5em + \dimen0 = \wd0 + \else + \dimen0 = 1.5em + \fi + \hbox to \dimen0{% + \hskip 0pt plus.25fil + .\hskip 0pt plus1fil + .\hskip 0pt plus1fil + .\hskip 0pt plus.5fil + }% +} + +% @enddots{} is an end-of-sentence ellipsis. +% +\def\enddots{% + \dots + \spacefactor=\endofsentencespacefactor +} % @point{}, @result{}, @expansion{}, @print{}, @equiv{}. % @@ -2842,7 +3021,7 @@ end {\tentt \global\dimen0 = 3em}% Width of the box. \dimen2 = .55pt % Thickness of rules % The text. (`r' is open on the right, `e' somewhat less so on the left.) -\setbox0 = \hbox{\kern-.75pt \reducedsf error\kern-1.5pt} +\setbox0 = \hbox{\kern-.75pt \reducedsf \putworderror\kern-1.5pt} % \setbox\errorbox=\hbox to \dimen0{\hfil \hsize = \dimen0 \advance\hsize by -5.8pt % Space to left+right. @@ -2991,7 +3170,7 @@ end % Textures 1.7.7 (preloaded format=plain 93.10.14) (68K) 16 APR 2004 02:38 % so we'll define it if necessary. % -\ifx\Orb\undefined +\ifx\Orb\thisisundefined \def\Orb{\mathhexbox20D} \fi @@ -3019,8 +3198,9 @@ end \newif\ifsetshortcontentsaftertitlepage \let\setshortcontentsaftertitlepage = \setshortcontentsaftertitlepagetrue -\parseargdef\shorttitlepage{\begingroup\hbox{}\vskip 1.5in \chaprm \centerline{#1}% - \endgroup\page\hbox{}\page} +\parseargdef\shorttitlepage{% + \begingroup \hbox{}\vskip 1.5in \chaprm \centerline{#1}% + \endgroup\page\hbox{}\page} \envdef\titlepage{% % Open one extra group, as we want to close it in the middle of \Etitlepage. @@ -3080,7 +3260,7 @@ end \finishedtitlepagetrue } -%%% Macros to be used within @titlepage: +% Macros to be used within @titlepage: \let\subtitlerm=\tenrm \def\subtitlefont{\subtitlerm \normalbaselineskip = 13pt \normalbaselines} @@ -3113,7 +3293,7 @@ end } -%%% Set up page headings and footings. +% Set up page headings and footings. \let\thispage=\folio @@ -3207,10 +3387,14 @@ end \def\headings #1 {\csname HEADINGS#1\endcsname} -\def\HEADINGSoff{% -\global\evenheadline={\hfil} \global\evenfootline={\hfil} -\global\oddheadline={\hfil} \global\oddfootline={\hfil}} -\HEADINGSoff +\def\headingsoff{% non-global headings elimination + \evenheadline={\hfil}\evenfootline={\hfil}% + \oddheadline={\hfil}\oddfootline={\hfil}% +} + +\def\HEADINGSoff{{\globaldefs=1 \headingsoff}} % global setting +\HEADINGSoff % it's the default + % When we turn headings on, set the page number to 1. % For double-sided printing, put current file name in lower left corner, % chapter name on inside top of right hand pages, document @@ -3261,7 +3445,7 @@ end % This produces Day Month Year style of output. % Only define if not already defined, in case a txi-??.tex file has set % up a different format (e.g., txi-cs.tex does this). -\ifx\today\undefined +\ifx\today\thisisundefined \def\today{% \number\day\space \ifcase\month @@ -3322,7 +3506,7 @@ end \begingroup \advance\leftskip by-\tableindent \advance\hsize by\tableindent - \advance\rightskip by0pt plus1fil + \advance\rightskip by0pt plus1fil\relax \leavevmode\unhbox0\par \endgroup % @@ -3808,18 +3992,18 @@ end \setbox0=\vbox{X}\global\multitablelinespace=\the\baselineskip \global\advance\multitablelinespace by-\ht0 \fi -%% Test to see if parskip is larger than space between lines of -%% table. If not, do nothing. -%% If so, set to same dimension as multitablelinespace. +% Test to see if parskip is larger than space between lines of +% table. If not, do nothing. +% If so, set to same dimension as multitablelinespace. \ifdim\multitableparskip>\multitablelinespace \global\multitableparskip=\multitablelinespace -\global\advance\multitableparskip-7pt %% to keep parskip somewhat smaller - %% than skip between lines in the table. +\global\advance\multitableparskip-7pt % to keep parskip somewhat smaller + % than skip between lines in the table. \fi% \ifdim\multitableparskip=0pt \global\multitableparskip=\multitablelinespace -\global\advance\multitableparskip-7pt %% to keep parskip somewhat smaller - %% than skip between lines in the table. +\global\advance\multitableparskip-7pt % to keep parskip somewhat smaller + % than skip between lines in the table. \fi} @@ -4134,11 +4318,14 @@ end \def\@{@}% change to @@ when we switch to @ as escape char in index files. \def\ {\realbackslash\space }% % - % Need these in case \tex is in effect and \{ is a \delimiter again. - % But can't use \lbracecmd and \rbracecmd because texindex assumes - % braces and backslashes are used only as delimiters. - \let\{ = \mylbrace - \let\} = \myrbrace + % Need these unexpandable (because we define \tt as a dummy) + % definitions when @{ or @} appear in index entry text. Also, more + % complicated, when \tex is in effect and \{ is a \delimiter again. + % We can't use \lbracecmd and \rbracecmd because texindex assumes + % braces and backslashes are used only as delimiters. Perhaps we + % should define @lbrace and @rbrace commands a la @comma. + \def\{{{\tt\char123}}% + \def\}{{\tt\char125}}% % % I don't entirely understand this, but when an index entry is % generated from a macro call, the \endinput which \scanmacro inserts @@ -4191,7 +4378,7 @@ end \def\commondummies{% % % \definedummyword defines \#1 as \string\#1\space, thus effectively - % preventing its expansion. This is used only for control% words, + % preventing its expansion. This is used only for control words, % not control letters, because the \space would be incorrect for % control characters, but is needed to separate the control word % from whatever follows. @@ -4210,6 +4397,7 @@ end \commondummiesnofonts % \definedummyletter\_% + \definedummyletter\-% % % Non-English letters. \definedummyword\AA @@ -4246,20 +4434,24 @@ end \definedummyword\TeX % % Assorted special characters. + \definedummyword\arrow \definedummyword\bullet \definedummyword\comma \definedummyword\copyright \definedummyword\registeredsymbol \definedummyword\dots \definedummyword\enddots + \definedummyword\entrybreak \definedummyword\equiv \definedummyword\error \definedummyword\euro + \definedummyword\expansion + \definedummyword\geq \definedummyword\guillemetleft \definedummyword\guillemetright \definedummyword\guilsinglleft \definedummyword\guilsinglright - \definedummyword\expansion + \definedummyword\leq \definedummyword\minus \definedummyword\ogonek \definedummyword\pounds @@ -4316,19 +4508,24 @@ end \definedummyword\b \definedummyword\i \definedummyword\r + \definedummyword\sansserif \definedummyword\sc + \definedummyword\slanted \definedummyword\t % % Commands that take arguments. \definedummyword\acronym + \definedummyword\anchor \definedummyword\cite \definedummyword\code \definedummyword\command \definedummyword\dfn + \definedummyword\dmn \definedummyword\email \definedummyword\emph \definedummyword\env \definedummyword\file + \definedummyword\indicateurl \definedummyword\kbd \definedummyword\key \definedummyword\math @@ -4356,7 +4553,7 @@ end \def\definedummyaccent##1{\let##1\asis}% % We can just ignore other control letters. \def\definedummyletter##1{\let##1\empty}% - % Hopefully, all control words can become @asis. + % All control words become @asis by default; overrides below. \let\definedummyword\definedummyaccent % \commondummiesnofonts @@ -4368,8 +4565,14 @@ end % \def\ { }% \def\@{@}% - % how to handle braces? \def\_{\normalunderscore}% + \def\-{}% @- shouldn't affect sorting + % + % Unfortunately, texindex is not prepared to handle braces in the + % content at all. So for index sorting, we map @{ and @} to strings + % starting with |, since that ASCII character is between ASCII { and }. + \def\{{|a}% + \def\}{|b}% % % Non-English letters. \def\AA{AA}% @@ -4397,6 +4600,7 @@ end % % Assorted special characters. % (The following {} will end up in the sort string, but that's ok.) + \def\arrow{->}% \def\bullet{bullet}% \def\comma{,}% \def\copyright{copyright}% @@ -4406,10 +4610,12 @@ end \def\error{error}% \def\euro{euro}% \def\expansion{==>}% + \def\geq{>=}% \def\guillemetleft{<<}% \def\guillemetright{>>}% \def\guilsinglleft{<}% \def\guilsinglright{>}% + \def\leq{<=}% \def\minus{-}% \def\point{.}% \def\pounds{pounds}% @@ -4424,6 +4630,9 @@ end \def\result{=>}% \def\textdegree{o}% % + \expandafter\ifx\csname SETtxiindexlquoteignore\endcsname\relax + \else \indexlquoteignore \fi + % % We need to get rid of all macros, leaving only the arguments (if present). % Of course this is not nearly correct, but it is the best we can do for now. % makeinfo does not expand macros in the argument to @deffn, which ends up @@ -4437,6 +4646,11 @@ end \macrolist } +% Undocumented (for FSFS 2nd ed.): @set txiindexlquoteignore makes us +% ignore left quotes in the sort term. +{\catcode`\`=\active + \gdef\indexlquoteignore{\let`=\empty}} + \let\indexbackslash=0 %overridden during \printindex. \let\SETmarginindex=\relax % put index entries in margin (undocumented)? @@ -4534,10 +4748,9 @@ end % % ..., ready, GO: % -\def\safewhatsit#1{% -\ifhmode +\def\safewhatsit#1{\ifhmode #1% -\else + \else % \lastskip and \lastpenalty cannot both be nonzero simultaneously. \whatsitskip = \lastskip \edef\lastskipmacro{\the\lastskip}% @@ -4561,7 +4774,6 @@ end % to re-insert the same penalty (values >10000 are used for various % signals); since we just inserted a non-discardable item, any % following glue (such as a \parskip) would be a breakpoint. For example: - % % @deffn deffn-whatever % @vindex index-whatever % Description. @@ -4574,8 +4786,7 @@ end % (the whatsit from the \write), so we must insert a \nobreak. \nobreak\vskip\whatsitskip \fi -\fi -} +\fi} % The index entry written in the file actually looks like % \entry {sortstring}{page}{topic} @@ -4694,7 +4905,6 @@ end % But this freezes the catcodes in the argument, and can cause problems to % @code, which sets - active. This problem was fixed by a kludge--- % ``-'' was active throughout whole index, but this isn't really right. -% % The right solution is to prevent \entry from swallowing the whole text. % --kasal, 21nov03 \def\entry{% @@ -4731,10 +4941,17 @@ end % columns. \vskip 0pt plus1pt % + % When reading the text of entry, convert explicit line breaks + % from @* into spaces. The user might give these in long section + % titles, for instance. + \def\*{\unskip\space\ignorespaces}% + \def\entrybreak{\hfil\break}% + % % Swallow the left brace of the text (first parameter): \afterassignment\doentry \let\temp = } +\def\entrybreak{\unskip\space\ignorespaces}% \def\doentry{% \bgroup % Instead of the swallowed brace. \noindent @@ -4967,7 +5184,22 @@ end \message{sectioning,} % Chapters, sections, etc. -% \unnumberedno is an oxymoron, of course. But we count the unnumbered +% Let's start with @part. +\outer\parseargdef\part{\partzzz{#1}} +\def\partzzz#1{% + \chapoddpage + \null + \vskip.3\vsize % move it down on the page a bit + \begingroup + \noindent \titlefonts\rmisbold #1\par % the text + \let\lastnode=\empty % no node to associate with + \writetocentry{part}{#1}{}% but put it in the toc + \headingsoff % no headline or footline on the part page + \chapoddpage + \endgroup +} + +% \unnumberedno is an oxymoron. But we count the unnumbered % sections so that we can refer to them unambiguously in the pdf % outlines by their "section number". We avoid collisions with chapter % numbers by starting them at 10000. (If a document ever has 10000 @@ -5046,8 +5278,8 @@ end \chardef\maxseclevel = 3 % % A numbered section within an unnumbered changes to unnumbered too. -% To achive this, remember the "biggest" unnum. sec. we are currently in: -\chardef\unmlevel = \maxseclevel +% To achieve this, remember the "biggest" unnum. sec. we are currently in: +\chardef\unnlevel = \maxseclevel % % Trace whether the current chapter is an appendix or not: % \chapheadtype is "N" or "A", unnumbered chapters are ignored. @@ -5072,8 +5304,8 @@ end % The heading type: \def\headtype{#1}% \if \headtype U% - \ifnum \absseclevel < \unmlevel - \chardef\unmlevel = \absseclevel + \ifnum \absseclevel < \unnlevel + \chardef\unnlevel = \absseclevel \fi \else % Check for appendix sections: @@ -5085,10 +5317,10 @@ end \fi\fi \fi % Check for numbered within unnumbered: - \ifnum \absseclevel > \unmlevel + \ifnum \absseclevel > \unnlevel \def\headtype{U}% \else - \chardef\unmlevel = 3 + \chardef\unnlevel = 3 \fi \fi % Now print the heading: @@ -5174,7 +5406,8 @@ end \global\let\subsubsection = \appendixsubsubsec } -\outer\parseargdef\unnumbered{\unnmhead0{#1}} % normally unnmhead0 calls unnumberedzzz +% normally unnmhead0 calls unnumberedzzz: +\outer\parseargdef\unnumbered{\unnmhead0{#1}} \def\unnumberedzzz#1{% \global\secno=0 \global\subsecno=0 \global\subsubsecno=0 \global\advance\unnumberedno by 1 @@ -5218,40 +5451,47 @@ end \let\top\unnumbered % Sections. +% \outer\parseargdef\numberedsec{\numhead1{#1}} % normally calls seczzz \def\seczzz#1{% \global\subsecno=0 \global\subsubsecno=0 \global\advance\secno by 1 \sectionheading{#1}{sec}{Ynumbered}{\the\chapno.\the\secno}% } -\outer\parseargdef\appendixsection{\apphead1{#1}} % normally calls appendixsectionzzz +% normally calls appendixsectionzzz: +\outer\parseargdef\appendixsection{\apphead1{#1}} \def\appendixsectionzzz#1{% \global\subsecno=0 \global\subsubsecno=0 \global\advance\secno by 1 \sectionheading{#1}{sec}{Yappendix}{\appendixletter.\the\secno}% } \let\appendixsec\appendixsection -\outer\parseargdef\unnumberedsec{\unnmhead1{#1}} % normally calls unnumberedseczzz +% normally calls unnumberedseczzz: +\outer\parseargdef\unnumberedsec{\unnmhead1{#1}} \def\unnumberedseczzz#1{% \global\subsecno=0 \global\subsubsecno=0 \global\advance\secno by 1 \sectionheading{#1}{sec}{Ynothing}{\the\unnumberedno.\the\secno}% } % Subsections. -\outer\parseargdef\numberedsubsec{\numhead2{#1}} % normally calls numberedsubseczzz +% +% normally calls numberedsubseczzz: +\outer\parseargdef\numberedsubsec{\numhead2{#1}} \def\numberedsubseczzz#1{% \global\subsubsecno=0 \global\advance\subsecno by 1 \sectionheading{#1}{subsec}{Ynumbered}{\the\chapno.\the\secno.\the\subsecno}% } -\outer\parseargdef\appendixsubsec{\apphead2{#1}} % normally calls appendixsubseczzz +% normally calls appendixsubseczzz: +\outer\parseargdef\appendixsubsec{\apphead2{#1}} \def\appendixsubseczzz#1{% \global\subsubsecno=0 \global\advance\subsecno by 1 \sectionheading{#1}{subsec}{Yappendix}% {\appendixletter.\the\secno.\the\subsecno}% } -\outer\parseargdef\unnumberedsubsec{\unnmhead2{#1}} %normally calls unnumberedsubseczzz +% normally calls unnumberedsubseczzz: +\outer\parseargdef\unnumberedsubsec{\unnmhead2{#1}} \def\unnumberedsubseczzz#1{% \global\subsubsecno=0 \global\advance\subsecno by 1 \sectionheading{#1}{subsec}{Ynothing}% @@ -5259,21 +5499,25 @@ end } % Subsubsections. -\outer\parseargdef\numberedsubsubsec{\numhead3{#1}} % normally numberedsubsubseczzz +% +% normally numberedsubsubseczzz: +\outer\parseargdef\numberedsubsubsec{\numhead3{#1}} \def\numberedsubsubseczzz#1{% \global\advance\subsubsecno by 1 \sectionheading{#1}{subsubsec}{Ynumbered}% {\the\chapno.\the\secno.\the\subsecno.\the\subsubsecno}% } -\outer\parseargdef\appendixsubsubsec{\apphead3{#1}} % normally appendixsubsubseczzz +% normally appendixsubsubseczzz: +\outer\parseargdef\appendixsubsubsec{\apphead3{#1}} \def\appendixsubsubseczzz#1{% \global\advance\subsubsecno by 1 \sectionheading{#1}{subsubsec}{Yappendix}% {\appendixletter.\the\secno.\the\subsecno.\the\subsubsecno}% } -\outer\parseargdef\unnumberedsubsubsec{\unnmhead3{#1}} %normally unnumberedsubsubseczzz +% normally unnumberedsubsubseczzz: +\outer\parseargdef\unnumberedsubsubsec{\unnmhead3{#1}} \def\unnumberedsubsubseczzz#1{% \global\advance\subsubsecno by 1 \sectionheading{#1}{subsubsec}{Ynothing}% @@ -5323,14 +5567,13 @@ end % (including whitespace, linebreaking, etc. around it), % given all the information in convenient, parsed form. -%%% Args are the skip and penalty (usually negative) +% Args are the skip and penalty (usually negative) \def\dobreak#1#2{\par\ifdim\lastskip<#1\removelastskip\penalty#2\vskip#1\fi} -%%% Define plain chapter starts, and page on/off switching for it % Parameter controlling skip before chapter headings (if needed) - \newskip\chapheadingskip +% Define plain chapter starts, and page on/off switching for it. \def\chapbreak{\dobreak \chapheadingskip {-4000}} \def\chappager{\par\vfill\supereject} % Because \domark is called before \chapoddpage, the filler page will @@ -5340,9 +5583,8 @@ end \chappager \ifodd\pageno \else \begingroup - \evenheadline={\hfil}\evenfootline={\hfil}% - \oddheadline={\hfil}\oddfootline={\hfil}% - \hbox to 0pt{}% + \headingsoff + \null \chappager \endgroup \fi @@ -5534,6 +5776,8 @@ end % \def\sectionheading#1#2#3#4{% {% + \checkenv{}% should not be in an environment. + % % Switch to the right set of fonts. \csname #2fonts\endcsname \rmisbold % @@ -5645,15 +5889,15 @@ end % % We'll almost certainly start a paragraph next, so don't let that % glue accumulate. (Not a breakpoint because it's preceded by a - % discardable item.) + % discardable item.) However, when a paragraph is not started next + % (\startdefun, \cartouche, \center, etc.), this needs to be wiped out + % or the negative glue will cause weirdly wrong output, typically + % obscuring the section heading with something else. \vskip-\parskip % - % This is purely so the last item on the list is a known \penalty > - % 10000. This is so \startdefun can avoid allowing breakpoints after - % section headings. Otherwise, it would insert a valid breakpoint between: - % - % @section sec-whatever - % @deffn def-whatever + % This is so the last item on the main vertical list is a known + % \penalty > 10000, so \startdefun, etc., can recognize the situation + % and do the needful. \penalty 10001 } @@ -5785,6 +6029,7 @@ end \def\summarycontents{% \startcontents{\putwordShortTOC}% % + \let\partentry = \shortpartentry \let\numchapentry = \shortchapentry \let\appentry = \shortchapentry \let\unnchapentry = \shortunnchapentry @@ -5840,6 +6085,19 @@ end % The last argument is the page number. % The arguments in between are the chapter number, section number, ... +% Parts, in the main contents. Replace the part number, which doesn't +% exist, with an empty box. Let's hope all the numbers have the same width. +% Also ignore the page number, which is conventionally not printed. +\def\numeralbox{\setbox0=\hbox{8}\hbox to \wd0{\hfil}} +\def\partentry#1#2#3#4{\dochapentry{\numeralbox\labelspace#1}{}} +% +% Parts, in the short toc. +\def\shortpartentry#1#2#3#4{% + \penalty-300 + \vskip.5\baselineskip plus.15\baselineskip minus.1\baselineskip + \shortchapentry{{\bf #1}}{\numeralbox}{}{}% +} + % Chapters, in the main contents. \def\numchapentry#1#2#3#4{\dochapentry{#2\labelspace#1}{#4}} % @@ -5929,9 +6187,9 @@ end \message{environments,} % @foo ... @end foo. -% @tex ... @end tex escapes into raw Tex temporarily. +% @tex ... @end tex escapes into raw TeX temporarily. % One exception: @ is still an escape character, so that @end tex works. -% But \@ or @@ will get a plain tex @ character. +% But \@ or @@ will get a plain @ character. \envdef\tex{% \setupmarkupstyle{tex}% @@ -5948,6 +6206,10 @@ end \catcode`\'=\other \escapechar=`\\ % + % ' is active in math mode (mathcode"8000). So reset it, and all our + % other math active characters (just in case), to plain's definitions. + \mathactive + % \let\b=\ptexb \let\bullet=\ptexbullet \let\c=\ptexc @@ -6051,6 +6313,12 @@ end \normbskip=\baselineskip \normpskip=\parskip \normlskip=\lineskip % Flag to tell @lisp, etc., not to narrow margin. \let\nonarrowing = t% + % + % If this cartouche directly follows a sectioning command, we need the + % \parskip glue (backspaced over by default) or the cartouche can + % collide with the section heading. + \ifnum\lastpenalty>10000 \vskip\parskip \penalty\lastpenalty \fi + % \vbox\bgroup \baselineskip=0pt\parskip=0pt\lineskip=0pt \carttop @@ -6064,7 +6332,7 @@ end \lineskip=\normlskip \parskip=\normpskip \vskip -\parskip - \comment % For explanation, see the end of \def\group. + \comment % For explanation, see the end of def\group. } \def\Ecartouche{% \ifhmode\par\fi @@ -6150,41 +6418,42 @@ end } % We often define two environments, @foo and @smallfoo. -% Let's do it by one command: -\def\makedispenv #1#2{ - \expandafter\envdef\csname#1\endcsname {\setnormaldispenv #2} - \expandafter\envdef\csname small#1\endcsname {\setsmalldispenv #2} +% Let's do it in one command. #1 is the env name, #2 the definition. +\def\makedispenvdef#1#2{% + \expandafter\envdef\csname#1\endcsname {\setnormaldispenv #2}% + \expandafter\envdef\csname small#1\endcsname {\setsmalldispenv #2}% \expandafter\let\csname E#1\endcsname \afterenvbreak \expandafter\let\csname Esmall#1\endcsname \afterenvbreak } -% Define two synonyms: -\def\maketwodispenvs #1#2#3{ - \makedispenv{#1}{#3} - \makedispenv{#2}{#3} +% Define two environment synonyms (#1 and #2) for an environment. +\def\maketwodispenvdef#1#2#3{% + \makedispenvdef{#1}{#3}% + \makedispenvdef{#2}{#3}% } - -% @lisp: indented, narrowed, typewriter font; @example: same as @lisp. +% +% @lisp: indented, narrowed, typewriter font; +% @example: same as @lisp. % % @smallexample and @smalllisp: use smaller fonts. % Originally contributed by Pavel@xerox. % -\maketwodispenvs {lisp}{example}{% +\maketwodispenvdef{lisp}{example}{% \nonfillstart \tt\setupmarkupstyle{example}% \let\kbdfont = \kbdexamplefont % Allow @kbd to do something special. - \gobble % eat return + \gobble % eat return } % @display/@smalldisplay: same as @lisp except keep current font. % -\makedispenv {display}{% +\makedispenvdef{display}{% \nonfillstart \gobble } % @format/@smallformat: same as @display except don't narrow margins. % -\makedispenv{format}{% +\makedispenvdef{format}{% \let\nonarrowing = t% \nonfillstart \gobble @@ -6203,7 +6472,7 @@ end \envdef\flushright{% \let\nonarrowing = t% \nonfillstart - \advance\leftskip by 0pt plus 1fill + \advance\leftskip by 0pt plus 1fill\relax \gobble } \let\Eflushright = \afterenvbreak @@ -6238,6 +6507,8 @@ end % we're doing normal filling. So, when using \aboveenvbreak and % \afterenvbreak, temporarily make \parskip 0. % +\makedispenvdef{quotation}{\quotationstart} +% \def\quotationstart{% {\parskip=0pt \aboveenvbreak}% because \aboveenvbreak inserts \parskip \parindent=0pt @@ -6253,28 +6524,18 @@ end \parsearg\quotationlabel } -\envdef\quotation{% - \setnormaldispenv - \quotationstart -} - -\envdef\smallquotation{% - \setsmalldispenv - \quotationstart -} -\let\Esmallquotation = \Equotation - % We have retained a nonzero parskip for the environment, since we're % doing normal filling. % \def\Equotation{% \par - \ifx\quotationauthor\undefined\else + \ifx\quotationauthor\thisisundefined\else % indent a bit. \leftline{\kern 2\leftskip \sl ---\quotationauthor}% \fi {\parskip=0pt \afterenvbreak}% } +\def\Esmallquotation{\Equotation} % If we're given an argument, typeset it in bold with a colon after. \def\quotationlabel#1{% @@ -6331,21 +6592,28 @@ end % Setup for the @verbatim environment % -% Real tab expansion +% Real tab expansion. \newdimen\tabw \setbox0=\hbox{\tt\space} \tabw=8\wd0 % tab amount % -\def\starttabbox{\setbox0=\hbox\bgroup} +% We typeset each line of the verbatim in an \hbox, so we can handle +% tabs. The \global is in case the verbatim line starts with an accent, +% or some other command that starts with a begin-group. Otherwise, the +% entire \verbbox would disappear at the corresponding end-group, before +% it is typeset. Meanwhile, we can't have nested verbatim commands +% (can we?), so the \global won't be overwriting itself. +\newbox\verbbox +\def\starttabbox{\global\setbox\verbbox=\hbox\bgroup} % \begingroup \catcode`\^^I=\active \gdef\tabexpand{% \catcode`\^^I=\active \def^^I{\leavevmode\egroup - \dimen0=\wd0 % the width so far, or since the previous tab - \divide\dimen0 by\tabw - \multiply\dimen0 by\tabw % compute previous multiple of \tabw - \advance\dimen0 by\tabw % advance to next multiple of \tabw - \wd0=\dimen0 \box0 \starttabbox + \dimen\verbbox=\wd\verbbox % the width so far, or since the previous tab + \divide\dimen\verbbox by\tabw + \multiply\dimen\verbbox by\tabw % compute previous multiple of \tabw + \advance\dimen\verbbox by\tabw % advance to next multiple of \tabw + \wd\verbbox=\dimen\verbbox \box\verbbox \starttabbox }% } \endgroup @@ -6354,15 +6622,16 @@ end \def\setupverbatim{% \let\nonarrowing = t% \nonfillstart - % Easiest (and conventionally used) font for verbatim - \tt - \def\par{\leavevmode\egroup\box0\endgraf}% + \tt % easiest (and conventionally used) font for verbatim + % The \leavevmode here is for blank lines. Otherwise, we would + % never \starttabox and the \egroup would end verbatim mode. + \def\par{\leavevmode\egroup\box\verbbox\endgraf}% \tabexpand \setupmarkupstyle{verbatim}% % Respect line breaks, % print special symbols as themselves, and - % make each space count - % must do in this order: + % make each space count. + % Must do in this order: \obeylines \uncatcodespecials \sepspaces \everypar{\starttabbox}% } @@ -6419,6 +6688,7 @@ end \makevalueexpandable \setupverbatim \indexnofonts % Allow `@@' and other weird things in file names. + \wlog{texinfo.tex: doing @verbatiminclude of #1^^J}% \input #1 \afterenvbreak }% @@ -6468,7 +6738,7 @@ end % commands also insert a nobreak penalty, and we don't want to allow % a break between a section heading and a defun. % - % As a minor refinement, we avoid "club" headers by signalling + % As a further refinement, we avoid "club" headers by signalling % with penalty of 10003 after the very first @deffn in the % sequence (see above), and penalty of 10002 after any following % @def command. @@ -6505,7 +6775,7 @@ end #1#2 \endheader % common ending: \interlinepenalty = 10000 - \advance\rightskip by 0pt plus 1fil + \advance\rightskip by 0pt plus 1fil\relax \endgraf \nobreak\vskip -\parskip \penalty\defunpenalty % signal to \startdefun and \dodefunx @@ -6535,13 +6805,36 @@ end \def\domakedefun#1#2#3{% \envdef#1{% \startdefun + \doingtypefnfalse % distinguish typed functions from all else \parseargusing\activeparens{\printdefunline#3}% }% \def#2{\dodefunx#1}% \def#3% } -%%% Untyped functions: +\newif\ifdoingtypefn % doing typed function? +\newif\ifrettypeownline % typeset return type on its own line? + +% @deftypefnnewline on|off says whether the return type of typed functions +% are printed on their own line. This affects @deftypefn, @deftypefun, +% @deftypeop, and @deftypemethod. +% +\parseargdef\deftypefnnewline{% + \def\temp{#1}% + \ifx\temp\onword + \expandafter\let\csname SETtxideftypefnnl\endcsname + = \empty + \else\ifx\temp\offword + \expandafter\let\csname SETtxideftypefnnl\endcsname + = \relax + \else + \errhelp = \EMsimple + \errmessage{Unknown @txideftypefnnl value `\temp', + must be on|off}% + \fi\fi +} + +% Untyped functions: % @deffn category name args \makedefun{deffn}{\deffngeneral{}} @@ -6560,7 +6853,7 @@ end \defname{#2}{}{#3}\magicamp\defunargs{#4\unskip}% } -%%% Typed functions: +% Typed functions: % @deftypefn category type name args \makedefun{deftypefn}{\deftypefngeneral{}} @@ -6575,10 +6868,11 @@ end % \def\deftypefngeneral#1#2 #3 #4 #5\endheader{% \dosubind{fn}{\code{#4}}{#1}% + \doingtypefntrue \defname{#2}{#3}{#4}\defunargs{#5\unskip}% } -%%% Typed variables: +% Typed variables: % @deftypevr category type var args \makedefun{deftypevr}{\deftypecvgeneral{}} @@ -6596,7 +6890,7 @@ end \defname{#2}{#3}{#4}\defunargs{#5\unskip}% } -%%% Untyped variables: +% Untyped variables: % @defvr category var args \makedefun{defvr}#1 {\deftypevrheader{#1} {} } @@ -6607,7 +6901,8 @@ end % \defcvof {category of}class var args \def\defcvof#1#2 {\deftypecvof{#1}#2 {} } -%%% Type: +% Types: + % @deftp category name args \makedefun{deftp}#1 #2 #3\endheader{% \doind{tp}{\code{#2}}% @@ -6635,25 +6930,49 @@ end % We are followed by (but not passed) the arguments, if any. % \def\defname#1#2#3{% + \par % Get the values of \leftskip and \rightskip as they were outside the @def... \advance\leftskip by -\defbodyindent % - % How we'll format the type name. Putting it in brackets helps + % Determine if we are typesetting the return type of a typed function + % on a line by itself. + \rettypeownlinefalse + \ifdoingtypefn % doing a typed function specifically? + % then check user option for putting return type on its own line: + \expandafter\ifx\csname SETtxideftypefnnl\endcsname\relax \else + \rettypeownlinetrue + \fi + \fi + % + % How we'll format the category name. Putting it in brackets helps % distinguish it from the body text that may end up on the next line % just below it. \def\temp{#1}% \setbox0=\hbox{\kern\deflastargmargin \ifx\temp\empty\else [\rm\temp]\fi} % - % Figure out line sizes for the paragraph shape. + % Figure out line sizes for the paragraph shape. We'll always have at + % least two. + \tempnum = 2 + % % The first line needs space for \box0; but if \rightskip is nonzero, % we need only space for the part of \box0 which exceeds it: \dimen0=\hsize \advance\dimen0 by -\wd0 \advance\dimen0 by \rightskip + % + % If doing a return type on its own line, we'll have another line. + \ifrettypeownline + \advance\tempnum by 1 + \def\maybeshapeline{0in \hsize}% + \else + \def\maybeshapeline{}% + \fi + % % The continuations: \dimen2=\hsize \advance\dimen2 by -\defargsindent - % (plain.tex says that \dimen1 should be used only as global.) - \parshape 2 0in \dimen0 \defargsindent \dimen2 % - % Put the type name to the right margin. + % The final paragraph shape: + \parshape \tempnum 0in \dimen0 \maybeshapeline \defargsindent \dimen2 + % + % Put the category name at the right margin. \noindent \hbox to 0pt{% \hfil\box0 \kern-\hsize @@ -6675,8 +6994,16 @@ end % . this still does not fix the ?` and !` ligatures, but so far no % one has made identifiers using them :). \df \tt - \def\temp{#2}% return value type - \ifx\temp\empty\else \tclose{\temp} \fi + \def\temp{#2}% text of the return type + \ifx\temp\empty\else + \tclose{\temp}% typeset the return type + \ifrettypeownline + % put return type on its own line; prohibit line break following: + \hfil\vadjust{\nobreak}\break + \else + \space % type on same line, so just followed by a space + \fi + \fi % no return type #3% output function name }% {\rm\enskip}% hskip 0.5 em of \tenrm @@ -6794,7 +7121,7 @@ end % To do this right we need a feature of e-TeX, \scantokens, % which we arrange to emulate with a temporary file in ordinary TeX. -\ifx\eTeXversion\undefined +\ifx\eTeXversion\thisisundefined \newwrite\macscribble \def\scantokens#1{% \toks0={#1}% @@ -6805,25 +7132,30 @@ end } \fi -\def\scanmacro#1{% - \begingroup - \newlinechar`\^^M - \let\xeatspaces\eatspaces - % Undo catcode changes of \startcontents and \doprintindex - % When called from @insertcopying or (short)caption, we need active - % backslash to get it printed correctly. Previously, we had - % \catcode`\\=\other instead. We'll see whether a problem appears - % with macro expansion. --kasal, 19aug04 - \catcode`\@=0 \catcode`\\=\active \escapechar=`\@ - % ... and \example - \spaceisspace - % - % Append \endinput to make sure that TeX does not see the ending newline. - % I've verified that it is necessary both for e-TeX and for ordinary TeX - % --kasal, 29nov03 - \scantokens{#1\endinput}% - \endgroup -} +\def\scanmacro#1{\begingroup + \newlinechar`\^^M + \let\xeatspaces\eatspaces + % + % Undo catcode changes of \startcontents and \doprintindex + % When called from @insertcopying or (short)caption, we need active + % backslash to get it printed correctly. Previously, we had + % \catcode`\\=\other instead. We'll see whether a problem appears + % with macro expansion. --kasal, 19aug04 + \catcode`\@=0 \catcode`\\=\active \escapechar=`\@ + % + % ... and for \example: + \spaceisspace + % + % The \empty here causes a following catcode 5 newline to be eaten as + % part of reading whitespace after a control sequence. It does not + % eat a catcode 13 newline. There's no good way to handle the two + % cases (untried: maybe e-TeX's \everyeof could help, though plain TeX + % would then have different behavior). See the Macro Details node in + % the manual for the workaround we recommend for macros and + % line-oriented commands. + % + \scantokens{#1\empty}% +\endgroup} \def\scanexp#1{% \edef\temp{\noexpand\scanmacro{#1}}% @@ -6877,17 +7209,18 @@ end % Macro bodies are absorbed as an argument in a context where % all characters are catcode 10, 11 or 12, except \ which is active -% (as in normal texinfo). It is necessary to change the definition of \. - +% (as in normal texinfo). It is necessary to change the definition of \ +% to recognize macro arguments; this is the job of \mbodybackslash. +% % Non-ASCII encodings make 8-bit characters active, so un-activate % them to avoid their expansion. Must do this non-globally, to % confine the change to the current group. - +% % It's necessary to have hard CRs when the macro is executed. This is -% done by making ^^M (\endlinechar) catcode 12 when reading the macro +% done by making ^^M (\endlinechar) catcode 12 when reading the macro % body, and then making it the \newlinechar in \scanmacro. - -\def\scanctxt{% +% +\def\scanctxt{% used as subroutine \catcode`\"=\other \catcode`\+=\other \catcode`\<=\other @@ -6900,13 +7233,13 @@ end \ifx\declaredencoding\ascii \else \setnonasciicharscatcodenonglobal\other \fi } -\def\scanargctxt{% +\def\scanargctxt{% used for copying and captions, not macros. \scanctxt \catcode`\\=\other \catcode`\^^M=\other } -\def\macrobodyctxt{% +\def\macrobodyctxt{% used for @macro definitions \scanctxt \catcode`\{=\other \catcode`\}=\other @@ -6914,32 +7247,56 @@ end \usembodybackslash } -\def\macroargctxt{% +\def\macroargctxt{% used when scanning invocations \scanctxt - \catcode`\\=\other + \catcode`\\=0 } +% why catcode 0 for \ in the above? To recognize \\ \{ \} as "escapes" +% for the single characters \ { }. Thus, we end up with the "commands" +% that would be written @\ @{ @} in a Texinfo document. +% +% We already have @{ and @}. For @\, we define it here, and only for +% this purpose, to produce a typewriter backslash (so, the @\ that we +% define for @math can't be used with @macro calls): +% +\def\\{\normalbackslash}% +% +% We would like to do this for \, too, since that is what makeinfo does. +% But it is not possible, because Texinfo already has a command @, for a +% cedilla accent. Documents must use @comma{} instead. +% +% \anythingelse will almost certainly be an error of some kind. + % \mbodybackslash is the definition of \ in @macro bodies. % It maps \foo\ => \csname macarg.foo\endcsname => #N % where N is the macro parameter number. % We define \csname macarg.\endcsname to be \realbackslash, so % \\ in macro replacement text gets you a backslash. - +% {\catcode`@=0 @catcode`@\=@active @gdef@usembodybackslash{@let\=@mbodybackslash} @gdef@mbodybackslash#1\{@csname macarg.#1@endcsname} } \expandafter\def\csname macarg.\endcsname{\realbackslash} +\def\margbackslash#1{\char`\#1 } + \def\macro{\recursivefalse\parsearg\macroxxx} \def\rmacro{\recursivetrue\parsearg\macroxxx} \def\macroxxx#1{% - \getargs{#1}% now \macname is the macname and \argl the arglist + \getargs{#1}% now \macname is the macname and \argl the arglist \ifx\argl\empty % no arguments - \paramno=0% + \paramno=0\relax \else \expandafter\parsemargdef \argl;% + \if\paramno>256\relax + \ifx\eTeXversion\thisisundefined + \errhelp = \EMsimple + \errmessage{You need eTeX to compile a file with macros with more than 256 arguments} + \fi + \fi \fi \if1\csname ismacro.\the\macname\endcsname \message{Warning: redefining \the\macname}% @@ -6986,46 +7343,269 @@ end % an opening brace, and that opening brace is not consumed. \def\getargs#1{\getargsxxx#1{}} \def\getargsxxx#1#{\getmacname #1 \relax\getmacargs} -\def\getmacname #1 #2\relax{\macname={#1}} +\def\getmacname#1 #2\relax{\macname={#1}} \def\getmacargs#1{\def\argl{#1}} -% Parse the optional {params} list. Set up \paramno and \paramlist -% so \defmacro knows what to do. Define \macarg.blah for each blah -% in the params list, to be ##N where N is the position in that list. -% That gets used by \mbodybackslash (above). +% For macro processing make @ a letter so that we can make Texinfo private macro names. +\edef\texiatcatcode{\the\catcode`\@} +\catcode `@=11\relax +% Parse the optional {params} list. Set up \paramno and \paramlist +% so \defmacro knows what to do. Define \macarg.BLAH for each BLAH +% in the params list to some hook where the argument si to be expanded. If +% there are less than 10 arguments that hook is to be replaced by ##N where N +% is the position in that list, that is to say the macro arguments are to be +% defined `a la TeX in the macro body. +% +% That gets used by \mbodybackslash (above). +% % We need to get `macro parameter char #' into several definitions. -% The technique used is stolen from LaTeX: let \hash be something +% The technique used is stolen from LaTeX: let \hash be something % unexpandable, insert that wherever you need a #, and then redefine % it to # just before using the token list produced. % % The same technique is used to protect \eatspaces till just before % the macro is used. - -\def\parsemargdef#1;{\paramno=0\def\paramlist{}% - \let\hash\relax\let\xeatspaces\relax\parsemargdefxxx#1,;,} +% +% If there are 10 or more arguments, a different technique is used, where the +% hook remains in the body, and when macro is to be expanded the body is +% processed again to replace the arguments. +% +% In that case, the hook is \the\toks N-1, and we simply set \toks N-1 to the +% argument N value and then \edef the body (nothing else will expand because of +% the catcode regime underwhich the body was input). +% +% If you compile with TeX (not eTeX), and you have macros with 10 or more +% arguments, you need that no macro has more than 256 arguments, otherwise an +% error is produced. +\def\parsemargdef#1;{% + \paramno=0\def\paramlist{}% + \let\hash\relax + \let\xeatspaces\relax + \parsemargdefxxx#1,;,% + % In case that there are 10 or more arguments we parse again the arguments + % list to set new definitions for the \macarg.BLAH macros corresponding to + % each BLAH argument. It was anyhow needed to parse already once this list + % in order to count the arguments, and as macros with at most 9 arguments + % are by far more frequent than macro with 10 or more arguments, defining + % twice the \macarg.BLAH macros does not cost too much processing power. + \ifnum\paramno<10\relax\else + \paramno0\relax + \parsemmanyargdef@@#1,;,% 10 or more arguments + \fi +} \def\parsemargdefxxx#1,{% \if#1;\let\next=\relax \else \let\next=\parsemargdefxxx - \advance\paramno by 1% + \advance\paramno by 1 \expandafter\edef\csname macarg.\eatspaces{#1}\endcsname {\xeatspaces{\hash\the\paramno}}% \edef\paramlist{\paramlist\hash\the\paramno,}% \fi\next} +\def\parsemmanyargdef@@#1,{% + \if#1;\let\next=\relax + \else + \let\next=\parsemmanyargdef@@ + \edef\tempb{\eatspaces{#1}}% + \expandafter\def\expandafter\tempa + \expandafter{\csname macarg.\tempb\endcsname}% + % Note that we need some extra \noexpand\noexpand, this is because we + % don't want \the to be expanded in the \parsermacbody as it uses an + % \xdef . + \expandafter\edef\tempa + {\noexpand\noexpand\noexpand\the\toks\the\paramno}% + \advance\paramno by 1\relax + \fi\next} + % These two commands read recursive and nonrecursive macro bodies. % (They're different since rec and nonrec macros end differently.) +% +\catcode `\@\texiatcatcode \long\def\parsemacbody#1@end macro% {\xdef\temp{\eatcr{#1}}\endgroup\defmacro}% \long\def\parsermacbody#1@end rmacro% {\xdef\temp{\eatcr{#1}}\endgroup\defmacro}% +\catcode `\@=11\relax -% This defines the macro itself. There are six cases: recursive and -% nonrecursive macros of zero, one, and many arguments. +\let\endargs@\relax +\let\nil@\relax +\def\nilm@{\nil@}% +\long\def\nillm@{\nil@}% + +% This macro is expanded during the Texinfo macro expansion, not during its +% definition. It gets all the arguments values and assigns them to macros +% macarg.ARGNAME +% +% #1 is the macro name +% #2 is the list of argument names +% #3 is the list of argument values +\def\getargvals@#1#2#3{% + \def\macargdeflist@{}% + \def\saveparamlist@{#2}% Need to keep a copy for parameter expansion. + \def\paramlist{#2,\nil@}% + \def\macroname{#1}% + \begingroup + \macroargctxt + \def\argvaluelist{#3,\nil@}% + \def\@tempa{#3}% + \ifx\@tempa\empty + \setemptyargvalues@ + \else + \getargvals@@ + \fi +} + +% +\def\getargvals@@{% + \ifx\paramlist\nilm@ + % Some sanity check needed here that \argvaluelist is also empty. + \ifx\argvaluelist\nillm@ + \else + \errhelp = \EMsimple + \errmessage{Too many arguments in macro `\macroname'!}% + \fi + \let\next\macargexpandinbody@ + \else + \ifx\argvaluelist\nillm@ + % No more arguments values passed to macro. Set remaining named-arg + % macros to empty. + \let\next\setemptyargvalues@ + \else + % pop current arg name into \@tempb + \def\@tempa##1{\pop@{\@tempb}{\paramlist}##1\endargs@}% + \expandafter\@tempa\expandafter{\paramlist}% + % pop current argument value into \@tempc + \def\@tempa##1{\longpop@{\@tempc}{\argvaluelist}##1\endargs@}% + \expandafter\@tempa\expandafter{\argvaluelist}% + % Here \@tempb is the current arg name and \@tempc is the current arg value. + % First place the new argument macro definition into \@tempd + \expandafter\macname\expandafter{\@tempc}% + \expandafter\let\csname macarg.\@tempb\endcsname\relax + \expandafter\def\expandafter\@tempe\expandafter{% + \csname macarg.\@tempb\endcsname}% + \edef\@tempd{\long\def\@tempe{\the\macname}}% + \push@\@tempd\macargdeflist@ + \let\next\getargvals@@ + \fi + \fi + \next +} + +\def\push@#1#2{% + \expandafter\expandafter\expandafter\def + \expandafter\expandafter\expandafter#2% + \expandafter\expandafter\expandafter{% + \expandafter#1#2}% +} + +% Replace arguments by their values in the macro body, and place the result +% in macro \@tempa +\def\macvalstoargs@{% + % To do this we use the property that token registers that are \the'ed + % within an \edef expand only once. So we are going to place all argument + % values into respective token registers. + % + % First we save the token context, and initialize argument numbering. + \begingroup + \paramno0\relax + % Then, for each argument number #N, we place the corresponding argument + % value into a new token list register \toks#N + \expandafter\putargsintokens@\saveparamlist@,;,% + % Then, we expand the body so that argument are replaced by their + % values. The trick for values not to be expanded themselves is that they + % are within tokens and that tokens expand only once in an \edef . + \edef\@tempc{\csname mac.\macroname .body\endcsname}% + % Now we restore the token stack pointer to free the token list registers + % which we have used, but we make sure that expanded body is saved after + % group. + \expandafter + \endgroup + \expandafter\def\expandafter\@tempa\expandafter{\@tempc}% + } + +\def\macargexpandinbody@{% + %% Define the named-macro outside of this group and then close this group. + \expandafter + \endgroup + \macargdeflist@ + % First the replace in body the macro arguments by their values, the result + % is in \@tempa . + \macvalstoargs@ + % Then we point at the \norecurse or \gobble (for recursive) macro value + % with \@tempb . + \expandafter\let\expandafter\@tempb\csname mac.\macroname .recurse\endcsname + % Depending on whether it is recursive or not, we need some tailing + % \egroup . + \ifx\@tempb\gobble + \let\@tempc\relax + \else + \let\@tempc\egroup + \fi + % And now we do the real job: + \edef\@tempd{\noexpand\@tempb{\macroname}\noexpand\scanmacro{\@tempa}\@tempc}% + \@tempd +} + +\def\putargsintokens@#1,{% + \if#1;\let\next\relax + \else + \let\next\putargsintokens@ + % First we allocate the new token list register, and give it a temporary + % alias \@tempb . + \toksdef\@tempb\the\paramno + % Then we place the argument value into that token list register. + \expandafter\let\expandafter\@tempa\csname macarg.#1\endcsname + \expandafter\@tempb\expandafter{\@tempa}% + \advance\paramno by 1\relax + \fi + \next +} + +% Save the token stack pointer into macro #1 +\def\texisavetoksstackpoint#1{\edef#1{\the\@cclvi}} +% Restore the token stack pointer from number in macro #1 +\def\texirestoretoksstackpoint#1{\expandafter\mathchardef\expandafter\@cclvi#1\relax} +% newtoks that can be used non \outer . +\def\texinonouternewtoks{\alloc@ 5\toks \toksdef \@cclvi} + +% Tailing missing arguments are set to empty +\def\setemptyargvalues@{% + \ifx\paramlist\nilm@ + \let\next\macargexpandinbody@ + \else + \expandafter\setemptyargvaluesparser@\paramlist\endargs@ + \let\next\setemptyargvalues@ + \fi + \next +} + +\def\setemptyargvaluesparser@#1,#2\endargs@{% + \expandafter\def\expandafter\@tempa\expandafter{% + \expandafter\def\csname macarg.#1\endcsname{}}% + \push@\@tempa\macargdeflist@ + \def\paramlist{#2}% +} + +% #1 is the element target macro +% #2 is the list macro +% #3,#4\endargs@ is the list value +\def\pop@#1#2#3,#4\endargs@{% + \def#1{#3}% + \def#2{#4}% +} +\long\def\longpop@#1#2#3,#4\endargs@{% + \long\def#1{#3}% + \long\def#2{#4}% +} + +% This defines a Texinfo @macro. There are eight cases: recursive and +% nonrecursive macros of zero, one, up to nine, and many arguments. % Much magic with \expandafter here. % \xdef is used so that macro definitions will survive the file % they're defined in; @include reads the file inside a group. +% \def\defmacro{% \let\hash=##% convert placeholders to macro parameter chars \ifrecursive @@ -7040,17 +7620,25 @@ end \expandafter\noexpand\csname\the\macname xxx\endcsname}% \expandafter\xdef\csname\the\macname xxx\endcsname##1{% \egroup\noexpand\scanmacro{\temp}}% - \else % many - \expandafter\xdef\csname\the\macname\endcsname{% - \bgroup\noexpand\macroargctxt - \noexpand\csname\the\macname xx\endcsname}% - \expandafter\xdef\csname\the\macname xx\endcsname##1{% - \expandafter\noexpand\csname\the\macname xxx\endcsname ##1,}% - \expandafter\expandafter - \expandafter\xdef - \expandafter\expandafter - \csname\the\macname xxx\endcsname - \paramlist{\egroup\noexpand\scanmacro{\temp}}% + \else + \ifnum\paramno<10\relax % at most 9 + \expandafter\xdef\csname\the\macname\endcsname{% + \bgroup\noexpand\macroargctxt + \noexpand\csname\the\macname xx\endcsname}% + \expandafter\xdef\csname\the\macname xx\endcsname##1{% + \expandafter\noexpand\csname\the\macname xxx\endcsname ##1,}% + \expandafter\expandafter + \expandafter\xdef + \expandafter\expandafter + \csname\the\macname xxx\endcsname + \paramlist{\egroup\noexpand\scanmacro{\temp}}% + \else % 10 or more + \expandafter\xdef\csname\the\macname\endcsname{% + \noexpand\getargvals@{\the\macname}{\argl}% + }% + \global\expandafter\let\csname mac.\the\macname .body\endcsname\temp + \global\expandafter\let\csname mac.\the\macname .recurse\endcsname\gobble + \fi \fi \else \ifcase\paramno @@ -7067,29 +7655,40 @@ end \egroup \noexpand\norecurse{\the\macname}% \noexpand\scanmacro{\temp}\egroup}% - \else % many - \expandafter\xdef\csname\the\macname\endcsname{% - \bgroup\noexpand\macroargctxt - \expandafter\noexpand\csname\the\macname xx\endcsname}% - \expandafter\xdef\csname\the\macname xx\endcsname##1{% - \expandafter\noexpand\csname\the\macname xxx\endcsname ##1,}% - \expandafter\expandafter - \expandafter\xdef - \expandafter\expandafter - \csname\the\macname xxx\endcsname - \paramlist{% - \egroup - \noexpand\norecurse{\the\macname}% - \noexpand\scanmacro{\temp}\egroup}% + \else % at most 9 + \ifnum\paramno<10\relax + \expandafter\xdef\csname\the\macname\endcsname{% + \bgroup\noexpand\macroargctxt + \expandafter\noexpand\csname\the\macname xx\endcsname}% + \expandafter\xdef\csname\the\macname xx\endcsname##1{% + \expandafter\noexpand\csname\the\macname xxx\endcsname ##1,}% + \expandafter\expandafter + \expandafter\xdef + \expandafter\expandafter + \csname\the\macname xxx\endcsname + \paramlist{% + \egroup + \noexpand\norecurse{\the\macname}% + \noexpand\scanmacro{\temp}\egroup}% + \else % 10 or more: + \expandafter\xdef\csname\the\macname\endcsname{% + \noexpand\getargvals@{\the\macname}{\argl}% + }% + \global\expandafter\let\csname mac.\the\macname .body\endcsname\temp + \global\expandafter\let\csname mac.\the\macname .recurse\endcsname\norecurse + \fi \fi \fi} +\catcode `\@\texiatcatcode\relax + \def\norecurse#1{\bgroup\cslet{#1}{macsave.#1}} % \braceorline decides whether the next nonwhitespace character is a % {. If so it reads up to the closing }, if not, it reads the whole % line. Whatever was read is then fed to the next control sequence -% as an argument (by \parsebrace or \parsearg) +% as an argument (by \parsebrace or \parsearg). +% \def\braceorline#1{\let\macnamexxx=#1\futurelet\nchar\braceorlinexxx} \def\braceorlinexxx{% \ifx\nchar\bgroup\else @@ -7099,7 +7698,8 @@ end % @alias. % We need some trickery to remove the optional spaces around the equal -% sign. Just make them active and then expand them all to nothing. +% sign. Make them active and then expand them all to nothing. +% \def\alias{\parseargusing\obeyspaces\aliasxxx} \def\aliasxxx #1{\aliasyyy#1\relax} \def\aliasyyy #1=#2\relax{% @@ -7120,7 +7720,8 @@ end % @inforef is relatively simple. \def\inforef #1{\inforefzzz #1,,,,**} -\def\inforefzzz #1,#2,#3,#4**{\putwordSee{} \putwordInfo{} \putwordfile{} \file{\ignorespaces #3{}}, +\def\inforefzzz #1,#2,#3,#4**{% + \putwordSee{} \putwordInfo{} \putwordfile{} \file{\ignorespaces #3{}}, node \samp{\ignorespaces#1{}}} % @node's only job in TeX is to define \lastnode, which is used in @@ -7181,11 +7782,32 @@ end \toks0 = \expandafter{\lastsection}% \immediate \writexrdef{title}{\the\toks0 }% \immediate \writexrdef{snt}{\csname #2\endcsname}% \Ynumbered etc. - \safewhatsit{\writexrdef{pg}{\folio}}% will be written later, during \shipout + \safewhatsit{\writexrdef{pg}{\folio}}% will be written later, at \shipout }% \fi } +% @xrefautosectiontitle on|off says whether @section(ing) names are used +% automatically in xrefs, if the third arg is not explicitly specified. +% This was provided as a "secret" @set xref-automatic-section-title +% variable, now it's official. +% +\parseargdef\xrefautomaticsectiontitle{% + \def\temp{#1}% + \ifx\temp\onword + \expandafter\let\csname SETxref-automatic-section-title\endcsname + = \empty + \else\ifx\temp\offword + \expandafter\let\csname SETxref-automatic-section-title\endcsname + = \relax + \else + \errhelp = \EMsimple + \errmessage{Unknown @xrefautomaticsectiontitle value `\temp', + must be on|off}% + \fi\fi +} + + % @xref, @pxref, and @ref generate cross-references. For \xrefX, #1 is % the node name, #2 the name of the Info cross-reference, #3 the printed % node name, #4 the name of the Info file, #5 the name of the printed @@ -7194,26 +7816,36 @@ end \def\pxref#1{\putwordsee{} \xrefX[#1,,,,,,,]} \def\xref#1{\putwordSee{} \xrefX[#1,,,,,,,]} \def\ref#1{\xrefX[#1,,,,,,,]} +% +\newbox\topbox +\newbox\printedrefnamebox +\newbox\printedmanualbox +% \def\xrefX[#1,#2,#3,#4,#5,#6]{\begingroup \unsepspaces - \def\printedmanual{\ignorespaces #5}% + % \def\printedrefname{\ignorespaces #3}% - \setbox1=\hbox{\printedmanual\unskip}% - \setbox0=\hbox{\printedrefname\unskip}% - \ifdim \wd0 = 0pt + \setbox\printedrefnamebox = \hbox{\printedrefname\unskip}% + % + \def\printedmanual{\ignorespaces #5}% + \setbox\printedmanualbox = \hbox{\printedmanual\unskip}% + % + % If the printed reference name (arg #3) was not explicitly given in + % the @xref, figure out what we want to use. + \ifdim \wd\printedrefnamebox = 0pt % No printed node name was explicitly given. - \expandafter\ifx\csname SETxref-automatic-section-title\endcsname\relax - % Use the node name inside the square brackets. + \expandafter\ifx\csname SETxref-automatic-section-title\endcsname \relax + % Not auto section-title: use node name inside the square brackets. \def\printedrefname{\ignorespaces #1}% \else - % Use the actual chapter/section title appear inside - % the square brackets. Use the real section title if we have it. - \ifdim \wd1 > 0pt - % It is in another manual, so we don't have it. + % Auto section-title: use chapter/section title inside + % the square brackets if we have it. + \ifdim \wd\printedmanualbox > 0pt + % It is in another manual, so we don't have it; use node name. \def\printedrefname{\ignorespaces #1}% \else \ifhavexrefs - % We know the real title if we have the xref values. + % We (should) know the real title if we have the xref values. \def\printedrefname{\refx{#1-title}{}}% \else % Otherwise just copy the Info node name. @@ -7227,13 +7859,13 @@ end \ifpdf {\indexnofonts \turnoffactive + \makevalueexpandable % This expands tokens, so do it after making catcode changes, so _ % etc. don't get their TeX definitions. \getfilename{#4}% % - % See comments at \activebackslashdouble. - {\activebackslashdouble \xdef\pdfxrefdest{#1}% - \backslashparens\pdfxrefdest}% + \edef\pdfxrefdest{#1}% + \txiescapepdf\pdfxrefdest % \leavevmode \startlink attr{/Border [0 0 0]}% @@ -7260,7 +7892,7 @@ end \iffloat\Xthisreftitle % If the user specified the print name (third arg) to the ref, % print it instead of our usual "Figure 1.2". - \ifdim\wd0 = 0pt + \ifdim\wd\printedrefnamebox = 0pt \refx{#1-snt}{}% \else \printedrefname @@ -7268,21 +7900,46 @@ end % % if the user also gave the printed manual name (fifth arg), append % "in MANUALNAME". - \ifdim \wd1 > 0pt + \ifdim \wd\printedmanualbox > 0pt \space \putwordin{} \cite{\printedmanual}% \fi \else % node/anchor (non-float) references. - % - % If we use \unhbox0 and \unhbox1 to print the node names, TeX does not - % insert empty discretionaries after hyphens, which means that it will - % not find a line break at a hyphen in a node names. Since some manuals - % are best written with fairly long node names, containing hyphens, this - % is a loss. Therefore, we give the text of the node name again, so it - % is as if TeX is seeing it for the first time. - \ifdim \wd1 > 0pt - \putwordSection{} ``\printedrefname'' \putwordin{} \cite{\printedmanual}% + % + % If we use \unhbox to print the node names, TeX does not insert + % empty discretionaries after hyphens, which means that it will not + % find a line break at a hyphen in a node names. Since some manuals + % are best written with fairly long node names, containing hyphens, + % this is a loss. Therefore, we give the text of the node name + % again, so it is as if TeX is seeing it for the first time. + % + % Cross-manual reference. Only include the "Section ``foo'' in" if + % the foo is neither missing or Top. Thus, @xref{,,,foo,The Foo Manual} + % outputs simply "see The Foo Manual". + \ifdim \wd\printedmanualbox > 0pt + % What is the 7sp about? The idea is that we also want to omit + % the Section part if we would be printing "Top", since they are + % clearly trying to refer to the whole manual. But, this being + % TeX, we can't easily compare strings while ignoring the possible + % spaces before and after in the input. By adding the arbitrary + % 7sp, we make it much less likely that a real node name would + % happen to have the same width as "Top" (e.g., in a monospaced font). + % I hope it will never happen in practice. + % + % For the same basic reason, we retypeset the "Top" at every + % reference, since the current font is indeterminate. + % + \setbox\topbox = \hbox{Top\kern7sp}% + \setbox2 = \hbox{\ignorespaces \printedrefname \unskip \kern7sp}% + \ifdim \wd2 > 7sp + \ifdim \wd2 = \wd\topbox \else + \putwordSection{} ``\printedrefname'' \putwordin{}\space + \fi + \fi + \cite{\printedmanual}% \else + % Reference in this manual. + % % _ (for example) has to be the character _ for the purposes of the % control sequence corresponding to the node, but it has to expand % into the usual \leavevmode...\vrule stuff for purposes of @@ -7294,7 +7951,7 @@ end \setbox2 = \hbox{\ignorespaces \refx{#1-snt}{}}% \ifdim \wd2 > 0pt \refx{#1-snt}\space\fi }% - % output the `[mynode]' via a macro so it can be overridden. + % output the `[mynode]' via the macro below so it can be overridden. \xrefprintnodename\printedrefname % % But we always want a comma and a space: @@ -7357,7 +8014,8 @@ end \angleleft un\-de\-fined\angleright \iflinks \ifhavexrefs - \message{\linenumber Undefined cross reference `#1'.}% + {\toks0 = {#1}% avoid expansion of possibly-complex value + \message{\linenumber Undefined cross reference `\the\toks0'.}}% \else \ifwarnedxrefs\else \global\warnedxrefstrue @@ -7521,7 +8179,7 @@ end % space to prevent strange expansion errors.) \def\supereject{\par\penalty -20000\footnoteno =0 } -% @footnotestyle is meaningful for info output only. +% @footnotestyle is meaningful for Info output only. \let\footnotestyle=\comment {\catcode `\@=11 @@ -7584,6 +8242,8 @@ end % expands into a box, it must come within the paragraph, lest it % provide a place where TeX can split the footnote. \footstrut + % + % Invoke rest of plain TeX footnote routine. \futurelet\next\fo@t } }%end \catcode `\@=11 @@ -7671,7 +8331,7 @@ end it from ftp://tug.org/tex/epsf.tex.} % \def\image#1{% - \ifx\epsfbox\undefined + \ifx\epsfbox\thisisundefined \ifwarnednoepsf \else \errhelp = \noepsfhelp \errmessage{epsf.tex not found, images will be ignored}% @@ -7687,7 +8347,7 @@ end % #2 is (optional) width, #3 is (optional) height. % #4 is (ignored optional) html alt text. % #5 is (ignored optional) extension. -% #6 is just the usual extra ignored arg for parsing this stuff. +% #6 is just the usual extra ignored arg for parsing stuff. \newif\ifimagevmode \def\imagexxx#1,#2,#3,#4,#5,#6\finish{\begingroup \catcode`\^^M = 5 % in case we're inside an example @@ -7695,6 +8355,13 @@ end % If the image is by itself, center it. \ifvmode \imagevmodetrue + \else \ifx\centersub\centerV + % for @center @image, we need a vbox so we can have our vertical space + \imagevmodetrue + \vbox\bgroup % vbox has better behavior than vtop herev + \fi\fi + % + \ifimagevmode \nobreak\medskip % Usually we'll have text after the image which will insert % \parskip glue, so insert it here too to equalize the space @@ -7704,9 +8371,13 @@ end \fi % % Leave vertical mode so that indentation from an enclosing - % environment such as @quotation is respected. On the other hand, if - % it's at the top level, we don't want the normal paragraph indentation. - \noindent + % environment such as @quotation is respected. + % However, if we're at the top level, we don't want the + % normal paragraph indentation. + % On the other hand, if we are in the case of @center @image, we don't + % want to start a paragraph, which will create a hsize-width box and + % eradicate the centering. + \ifx\centersub\centerV\else \noindent \fi % % Output the image. \ifpdf @@ -7718,7 +8389,10 @@ end \epsfbox{#1.eps}% \fi % - \ifimagevmode \medskip \fi % space after the standalone image + \ifimagevmode + \medskip % space after a standalone image + \fi + \ifx\centersub\centerV \egroup \fi \endgroup} @@ -8136,7 +8810,7 @@ directory should work if nowhere else does.} % % Latin1 (ISO-8859-1) character definitions. \def\latonechardefs{% - \gdef^^a0{~} + \gdef^^a0{\tie} \gdef^^a1{\exclamdown} \gdef^^a2{\missingcharmsg{CENT SIGN}} \gdef^^a3{{\pounds}} @@ -8166,7 +8840,7 @@ directory should work if nowhere else does.} \gdef^^b9{$^1$} \gdef^^ba{\ordm} % - \gdef^^bb{\guilletright} + \gdef^^bb{\guillemetright} \gdef^^bc{$1\over4$} \gdef^^bd{$1\over2$} \gdef^^be{$3\over4$} @@ -8258,7 +8932,7 @@ directory should work if nowhere else does.} % Latin2 (ISO-8859-2) character definitions. \def\lattwochardefs{% - \gdef^^a0{~} + \gdef^^a0{\tie} \gdef^^a1{\ogonek{A}} \gdef^^a2{\u{}} \gdef^^a3{\L} @@ -8339,8 +9013,8 @@ directory should work if nowhere else does.} \gdef^^ea{\ogonek{e}} \gdef^^eb{\"e} \gdef^^ec{\v e} - \gdef^^ed{\'\i} - \gdef^^ee{\^\i} + \gdef^^ed{\'{\dotless{i}}} + \gdef^^ee{\^{\dotless{i}}} \gdef^^ef{\v d} % \gdef^^f0{\dh} @@ -8431,7 +9105,7 @@ directory should work if nowhere else does.} \gdef\DeclareUnicodeCharacter#1#2{% \countUTFz = "#1\relax - \wlog{\space\space defining Unicode char U+#1 (decimal \the\countUTFz)}% + %\wlog{\space\space defining Unicode char U+#1 (decimal \the\countUTFz)}% \begingroup \parseXMLCharref \def\UTFviiiTwoOctets##1##2{% @@ -8899,8 +9573,8 @@ directory should work if nowhere else does.} % Prevent underfull vbox error messages. \vbadness = 10000 -% Don't be so finicky about underfull hboxes, either. -\hbadness = 2000 +% Don't be very finicky about underfull hboxes, either. +\hbadness = 6666 % Following George Bush, get rid of widows and orphans. \widowpenalty=10000 @@ -9107,28 +9781,21 @@ directory should work if nowhere else does.} \message{and turning on texinfo input format.} +\def^^L{\par} % remove \outer, so ^L can appear in an @comment + % DEL is a comment character, in case @c does not suffice. \catcode`\^^? = 14 % Define macros to output various characters with catcode for normal text. -\catcode`\"=\other -\catcode`\~=\other -\catcode`\^=\other -\catcode`\_=\other -\catcode`\|=\other -\catcode`\<=\other -\catcode`\>=\other -\catcode`\+=\other -\catcode`\$=\other -\def\normaldoublequote{"} -\def\normaltilde{~} -\def\normalcaret{^} -\def\normalunderscore{_} -\def\normalverticalbar{|} -\def\normalless{<} -\def\normalgreater{>} -\def\normalplus{+} -\def\normaldollar{$}%$ font-lock fix +\catcode`\"=\other \def\normaldoublequote{"} +\catcode`\$=\other \def\normaldollar{$}%$ font-lock fix +\catcode`\+=\other \def\normalplus{+} +\catcode`\<=\other \def\normalless{<} +\catcode`\>=\other \def\normalgreater{>} +\catcode`\^=\other \def\normalcaret{^} +\catcode`\_=\other \def\normalunderscore{_} +\catcode`\|=\other \def\normalverticalbar{|} +\catcode`\~=\other \def\normaltilde{~} % This macro is used to make a character print one way in \tt % (where it can probably be output as-is), and another way in other fonts, @@ -9206,14 +9873,24 @@ directory should work if nowhere else does.} % In texinfo, backslash is an active character; it prints the backslash % in fixed width font. -\catcode`\\=\active -@def@normalbackslash{{@tt@backslashcurfont}} +\catcode`\\=\active % @ for escape char from now on. + +% The story here is that in math mode, the \char of \backslashcurfont +% ends up printing the roman \ from the math symbol font (because \char +% in math mode uses the \mathcode, and plain.tex sets +% \mathcode`\\="026E). It seems better for @backslashchar{} to always +% print a typewriter backslash, hence we use an explicit \mathchar, +% which is the decimal equivalent of "715c (class 7, e.g., use \fam; +% ignored family value; char position "5C). We can't use " for the +% usual hex value because it has already been made active. +@def@normalbackslash{{@tt @ifmmode @mathchar29020 @else @backslashcurfont @fi}} +@let@backslashchar = @normalbackslash % @backslashchar{} is for user documents. + % On startup, @fixbackslash assigns: % @let \ = @normalbackslash - % \rawbackslash defines an active \ to do \backslashcurfont. % \otherbackslash defines an active \ to be a literal `\' character with -% catcode other. +% catcode other. We switch back and forth between these. @gdef@rawbackslash{@let\=@backslashcurfont} @gdef@otherbackslash{@let\=@realbackslash} @@ -9221,16 +9898,16 @@ directory should work if nowhere else does.} % the literal character `\'. % @def@normalturnoffactive{% - @let\=@normalbackslash @let"=@normaldoublequote - @let~=@normaltilde + @let$=@normaldollar %$ font-lock fix + @let+=@normalplus + @let<=@normalless + @let>=@normalgreater + @let\=@normalbackslash @let^=@normalcaret @let_=@normalunderscore @let|=@normalverticalbar - @let<=@normalless - @let>=@normalgreater - @let+=@normalplus - @let$=@normaldollar %$ font-lock fix + @let~=@normaltilde @markupsetuplqdefault @markupsetuprqdefault @unsepspaces @@ -9262,10 +9939,19 @@ directory should work if nowhere else does.} % Say @foo, not \foo, in error messages. @escapechar = `@@ +% These (along with & and #) are made active for url-breaking, so need +% active definitions as the normal characters. +@def@normaldot{.} +@def@normalquest{?} +@def@normalslash{/} + % These look ok in all fonts, so just make them not special. -@catcode`@& = @other -@catcode`@# = @other -@catcode`@% = @other +% @hashchar{} gets its own user-level command, because of #line. +@catcode`@& = @other @def@normalamp{&} +@catcode`@# = @other @def@normalhash{#} +@catcode`@% = @other @def@normalpercent{%} + +@let @hashchar = @normalhash @c Finally, make ` and ' active, so that txicodequoteundirected and @c txicodequotebacktick work right in, e.g., @w{@code{`foo'}}. If we diff --git a/doc/tinc.conf.5.in b/doc/tinc.conf.5.in index a44f27c..f868c15 100644 --- a/doc/tinc.conf.5.in +++ b/doc/tinc.conf.5.in @@ -1,4 +1,4 @@ -.Dd 2010-01-16 +.Dd 2012-09-27 .Dt TINC.CONF 5 .\" Manual page created by: .\" Ivo Timmermans @@ -14,22 +14,12 @@ The files in the directory contain runtime and security information for the tinc daemon. .Sh NETWORKS -It is perfectly ok for you to run more than one tinc daemon. -However, in its default form, -you will soon notice that you can't use two different configuration files without the -.Fl c -option. - -.Pp -We have thought of another way of dealing with this: network names. -This means that you call -.Nm -with the +To distinguish multiple instances of tinc running on one computer, +you can use the .Fl n -option, which will assign a name to this daemon. - +option to assign a network name to each tinc daemon. .Pp -The effect of this is that the daemon will set its configuration root to +The effect of this option is that the daemon will set its configuration root to .Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa / , where .Ar NETNAME @@ -37,14 +27,14 @@ is your argument to the .Fl n option. You'll notice that messages appear in syslog as coming from -.Nm tincd. Ns Ar NETNAME . - +.Nm tincd. Ns Ar NETNAME , +and on Linux, unless specified otherwise, the name of the virtual network interface will be the same as the network name. .Pp -However, it is not strictly necessary that you call tinc with the +It is recommended that you use network names even if you run only one instance of tinc. +However, you can choose not to use the .Fl n option. -In this case, the network name would just be empty, -and it will be used as such. +In this case, the network name would just be empty, and .Nm tinc now looks for files in .Pa @sysconfdir@/tinc/ , @@ -55,12 +45,6 @@ the configuration file should be and the host configuration files are now expected to be in .Pa @sysconfdir@/tinc/hosts/ . -.Pp -But it is highly recommended that you use this feature of -.Nm tinc , -because it will be so much clearer whom your daemon talks to. -Hence, we will assume that you use it. - .Sh NAMES Each tinc daemon should have a name that is unique in the network which it will be part of. The name will be used by other tinc daemons for identification. @@ -72,25 +56,38 @@ file. To make things easy, choose something that will give unique and easy to remember names to your tinc daemon(s). You could try things like hostnames, owner surnames or location names. +However, you are only allowed to use alphanumerical characters (a-z, A-Z, and 0-9) and underscores (_) in the name. + +.Sh INITIAL CONFIGURATION +If you have not configured tinc yet, you can easily create a basic configuration using the following command: +.Bd -literal -offset indent +.Nm tincctl Fl n Ar NETNAME Li init Ar NAME +.Ed + +.Pp +You can further change the configuration as needed either by manually editing the configuration files, +or by using +.Xr tincctl 8 . .Sh PUBLIC/PRIVATE KEYS -You should use -.Ic tincd -K -to generate public/private keypairs. -It will generate two keys. -The private key should be stored in a separate file -.Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /rsa_key.priv -\-\- where -.Ar NETNAME -stands for the network (see -.Sx NETWORKS ) -above. -The public key should be stored in the host configuration file -.Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /hosts/ Ns Va NAME -\-\- where -.Va NAME -stands for the name of the local tinc daemon (see -.Sx NAMES ) . +The +.Nm tincctl Li init +command will have generated both RSA and ECDSA public/private keypairs. +The private keys should be stored in files named +.Pa rsa_key.priv +and +.Pa ecdsa_key.priv +in the directory +.Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa / +The public keys should be stored in the host configuration file +.Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /hosts/ Ns Va NAME . + +The RSA keys are used for backwards compatibility with tinc version 1.0. +If you are upgrading from version 1.0 to 1.1, you can keep the old configuration files, +but you will need to create ECDSA keys using the following command: +.Bd -literal -offset indent +.Nm tincctl Fl n Ar NETNAME Li generate-ecdsa-keys +.Ed .Sh SERVER CONFIGURATION The server configuration of the daemon is done in the file @@ -117,6 +114,11 @@ Although all configuration options for the local host listed in this document ca it is recommended to put host specific configuration options in the host configuration file, as this makes it easy to exchange with other nodes. +.Pp +You can edit the config file manually, but it is recommended that you use +.Xr tincctl 8 +to change configuration variables for you. + .Pp Here are all valid variables, listed in alphabetical order. The default value is given between parentheses. @@ -129,14 +131,24 @@ If is selected, then depending on the operating system both IPv4 and IPv6 or just IPv6 listening sockets will be created. -.It Va BindToAddress Li = Ar address Bq experimental +.It Va BindToAddress Li = Ar address Op Ar port If your computer has more than one IPv4 or IPv6 address, .Nm tinc will by default listen on all of them for incoming connections. -It is possible to bind only to a single address with this variable. - +Multiple +.Va BindToAddress +variables may be specified, +in which case listening sockets for each specified address are made. .Pp -This option may not work on all platforms. +If no +.Ar port +is specified, the socket will be bound to the port specified by the +.Va Port +option, or to port 655 if neither is given. +To only bind to a specific port but not to a specific address, use +.Li * +for the +.Ar address . .It Va BindToInterface Li = Ar interface Bq experimental If your computer has more than one network interface, @@ -146,6 +158,28 @@ It is possible to bind only to a single interface with this variable. .Pp This option may not work on all platforms. +Also, on some platforms it will not actually bind to an interface, +but rather to the address that the interface has at the moment a socket is created. + +.It Va Broadcast Li = no | mst | direct Po mst Pc Bq experimental +This option selects the way broadcast packets are sent to other daemons. +NOTE: all nodes in a VPN must use the same +.Va Broadcast +mode, otherwise routing loops can form. + +.Bl -tag -width indent +.It no +Broadcast packets are never sent to other nodes. + +.It mst +Broadcast packets are sent and forwarded via the VPN's Minimum Spanning Tree. +This ensures broadcast packets reach all nodes. + +.It direct +Broadcast packets are sent directly to all nodes that can be reached directly. +Broadcast packets received from other nodes are never forwarded. +If the IndirectData option is also set, broadcast packets will only be sent to nodes which we have a meta connection to. +.El .It Va ConnectTo Li = Ar name Specifies which other tinc daemon to connect to on startup. @@ -165,6 +199,16 @@ If you don't specify a host with won't try to connect to other daemons at all, and will instead just listen for incoming connections. +.It Va DecrementTTL Li = yes | no Po no Pc Bq experimental +When enabled, +.Nm tinc +will decrement the Time To Live field in IPv4 packets, or the Hop Limit field in IPv6 packets, +before forwarding a received packet to the virtual network device or to another node, +and will drop packets that have a TTL value of zero, +in which case it will send an ICMP Time Exceeded packet back. +.Pp +Do not use this option if you use switch mode and want to use IPv6. + .It Va Device Li = Ar device Po Pa /dev/tap0 , Pa /dev/net/tun No or other depending on platform Pc The virtual network device to use. .Nm tinc @@ -177,30 +221,75 @@ instead of The info pages of the tinc package contain more information about configuring the virtual network device. -.It Va DeviceType Li = tun | tunnohead | tunifhead | tap Po only supported on BSD platforms Pc +.It Va DeviceType Li = Ar type Pq platform dependent The type of the virtual network device. -Tinc will normally automatically select the right type, and this option should not be used. -However, in case tinc does not seem to correctly interpret packets received from the virtual network device, -using this option might help. +Tinc will normally automatically select the right type of tun/tap interface, and this option should not be used. +However, this option can be used to select one of the special interface types, if support for them is compiled in. .Bl -tag -width indent -.It tun +.It dummy +Use a dummy interface. +No packets are ever read or written to a virtual network device. +Useful for testing, or when setting up a node that only forwards packets for other nodes. + +.It raw_socket +Open a raw socket, and bind it to a pre-existing +.Va Interface +(eth0 by default). +All packets are read from this interface. +Packets received for the local node are written to the raw socket. +However, at least on Linux, the operating system does not process IP packets destined for the local host. + +.It multicast +Open a multicast UDP socket and bind it to the address and port (separated by spaces) and optionally a TTL value specified using +.Va Device . +Packets are read from and written to this multicast socket. +This can be used to connect to UML, QEMU or KVM instances listening on the same multicast address. +Do NOT connect multiple +.Nm tinc +daemons to the same multicast address, this will very likely cause routing loops. +Also note that this can cause decrypted VPN packets to be sent out on a real network if misconfigured. + +.It uml Pq not compiled in by default +Create a UNIX socket with the filename specified by +.Va Device , +or +.Pa @localstatedir@/run/ Ns Ar NETNAME Ns Pa .umlsocket +if not specified. +.Nm tinc +will wait for a User Mode Linux instance to connect to this socket. + +.It vde Pq not compiled in by default +Uses the libvdeplug library to connect to a Virtual Distributed Ethernet switch, +using the UNIX socket specified by +.Va Device , +or +.Pa @localstatedir@/run/vde.ctl +if not specified. +.El + +Also, in case tinc does not seem to correctly interpret packets received from the virtual network device, +it can be used to change the way packets are interpreted: + +.Bl -tag -width indent + +.It tun Pq BSD and Linux Set type to tun. Depending on the platform, this can either be with or without an address family header (see below). -.It tunnohead +.It tunnohead Pq BSD Set type to tun without an address family header. Tinc will expect packets read from the virtual network device to start with an IP header. On some platforms IPv6 packets cannot be read from or written to the device in this mode. -.It tunifhead +.It tunifhead Pq BSD Set type to tun with an address family header. Tinc will expect packets read from the virtual network device to start with a four byte header containing the address family, followed by an IP header. This mode should support both IPv4 and IPv6 packets. -.It tap +.It tap Pq BSD and Linux Set type to tap. Tinc will expect packets read from the virtual network device to start with an Ethernet header. @@ -247,7 +336,7 @@ This is less efficient, but allows the kernel to apply its routing and firewall and can also help debugging. .El -.It Va GraphDumpFile Li = Ar filename Bq experimental +.It Va GraphDumpFile Li = Ar filename If this option is present, .Nm tinc will dump the current network graph to the file @@ -268,7 +357,7 @@ a lookup if your DNS server is not responding. .Pp This does not affect resolving hostnames to IP addresses from the -host configuration files. +host configuration files, but whether hostnames should be resolved while logging. .It Va IffOneQueue Li = yes | no Po no Pc Bq experimental (Linux only) Set IFF_ONE_QUEUE flag on TUN/TAP devices. @@ -286,6 +375,18 @@ This option controls the period the encryption keys used to encrypt the data are It is common practice to change keys at regular intervals to make it even harder for crackers, even though it is thought to be nearly impossible to crack a single key. +.It Va LocalDiscovery Li = yes | no Pq no +When enabled, +.Nm tinc +will try to detect peers that are on the same local network. +This will allow direct communication using LAN addresses, even if both peers are behind a NAT +and they only ConnectTo a third node outside the NAT, +which normally would prevent the peers from learning each other's LAN address. + +.Pp +Currently, local discovery is implemented by sending broadcast packets to the LAN during path MTU discovery. +This feature may not work in all possible situations. + .It Va MACExpire Li = Ar seconds Pq 600 This option controls the amount of time MAC addresses are kept before they are removed. This only has effect when @@ -327,6 +428,19 @@ while no routing table is managed. .It Va Name Li = Ar name Bq required This is the name which identifies this tinc daemon. It must be unique for the virtual private network this daemon will connect to. +The Name may only consist of alphanumeric and underscore characters. + +If +.Va Name +starts with a +.Li $ , +then the contents of the environment variable that follows will be used. +In that case, invalid characters will be converted to underscores. +If +.Va Name +is +.Li $HOST , +but no such environment variable exist, the hostname will be read using the gethostnname() system call. .It Va PingInterval Li = Ar seconds Pq 60 The number of seconds of inactivity that @@ -356,11 +470,46 @@ or specified in the configuration file. .It Va ProcessPriority Li = low | normal | high -When this option is used the priority of the tincd process will be adjusted. +When this option is used the priority of the +.Nm tincd +process will be adjusted. Increasing the priority may help to reduce latency and packet loss on the VPN. +.It Va Proxy Li = socks4 | socks5 | http | exec Ar ... Bq experimental +Use a proxy when making outgoing connections. +The following proxy types are currently supported: +.Bl -tag -width indent +.It socks4 Ar address Ar port Op Ar username +Connects to the proxy using the SOCKS version 4 protocol. +Optionally, a +.Ar username +can be supplied which will be passed on to the proxy server. +Only IPv4 connections can be proxied using SOCKS 4. +.It socks5 Ar address Ar port Op Ar username Ar password +Connect to the proxy using the SOCKS version 5 protocol. +If a +.Ar username +and +.Ar password +are given, basic username/password authentication will be used, +otherwise no authentication will be used. +.It http Ar address Ar port +Connects to the proxy and sends a HTTP CONNECT request. +.It exec Ar command +Executes the given +.Ar command +which should set up the outgoing connection. +The environment variables +.Ev NAME , +.Ev NODE , +.Ev REMOTEADDRES +and +.Ev REMOTEPORT +are available. +.El + .It Va ReplayWindow Li = Ar bytes Pq 16 -This is the size of the replay tracking window for each remote node, in bytes. +vhis is the size of the replay tracking window for each remote node, in bytes. The window is a bitfield which tracks 1 packet per bit, so for example the default setting of 16 will track up to 128 packets in the window. In high bandwidth scenarios, setting this to a higher value can reduce packet loss from @@ -406,7 +555,7 @@ 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 Oo port Oc Bq recommended +.It Va Address Li = Ar address Oo Ar 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. @@ -497,12 +646,11 @@ variables can be specified. Subnets can either be single MAC, IPv4 or IPv6 addresses, in which case a subnet consisting of only that single address is assumed, or they can be a IPv4 or IPv6 network address with a prefixlength. -Shorthand notations are not supported. For example, IPv4 subnets must be in a form like 192.168.1.0/24, where 192.168.1.0 is the network address and 24 is the number of bits set in the netmask. Note that subnets like 192.168.1.1/24 are invalid! Read a networking HOWTO/FAQ/guide if you don't understand this. -IPv6 subnets are notated like fec0:0:0:1:0:0:0:0/64. +IPv6 subnets are notated like fec0:0:0:1::/64. MAC addresses are notated like 0:1a:2b:3c:4d:5e. .Pp @@ -609,6 +757,10 @@ When a subnet becomes (un)reachable, this is set to the subnet. When a subnet becomes (un)reachable, this is set to the subnet weight. .El +.Pp +Do not forget that under UNIX operating systems, you have to make the scripts executable, using the command +.Nm chmod Li a+x Pa script . + .Sh FILES The most important files are: .Bl -tag -width indent @@ -636,8 +788,9 @@ its connection to the virtual network device. .Sh SEE ALSO .Xr tincd 8 , +.Xr tincctl 8 , .Pa http://www.tinc-vpn.org/ , -.Pa http://www.linuxdoc.org/LDP/nag2/ . +.Pa http://www.tldp.org/LDP/nag2/ . .Pp The full documentation for diff --git a/doc/tinc.info b/doc/tinc.info index f6c0548..8a95302 100644 --- a/doc/tinc.info +++ b/doc/tinc.info @@ -8,7 +8,7 @@ END-INFO-DIR-ENTRY This is the info manual for tinc version 1.1pre2, a Virtual Private Network daemon. - Copyright (C) 1998-2011 Ivo Timmermans, Guus Sliepen + Copyright (C) 1998-2012 Ivo Timmermans, Guus Sliepen and Wessel Dankers . Permission is granted to make and distribute verbatim copies of this @@ -148,7 +148,7 @@ will most likely compile and run, but it will not be able to send or receive data packets. For an up to date list of supported platforms, please check the list -on our website: `http://www.tinc-vpn.org/platforms'. +on our website: `http://www.tinc-vpn.org/platforms/'.  File: tinc.info, Node: Preparations, Next: Installation, Prev: Introduction, Up: Top @@ -210,7 +210,9 @@ File: tinc.info, Node: Configuration of FreeBSD kernels, Next: Configuration o -------------------------------------- For FreeBSD version 4.1 and higher, tun and tap drivers are included in -the default kernel configuration. Using tap devices is recommended. +the default kernel configuration. The tap driver can be loaded with +`kldload if_tap', or by adding `if_tap_load="YES"' to +`/boot/loader.conf'.  File: tinc.info, Node: Configuration of OpenBSD kernels, Next: Configuration of NetBSD kernels, Prev: Configuration of FreeBSD kernels, Up: Configuring the kernel @@ -413,10 +415,9 @@ if available. Make sure you install the development AND runtime versions of this package. If you have to install libevent manually, you can get the source code -from `http://monkey.org/~provos/libevent/'. Instructions on how to -configure, build and install this package are included within the -package. Please make sure you build development and runtime libraries -(which is the default). +from `http://libevent.org/'. Instructions on how to configure, build +and install this package are included within the package. Please make +sure you build development and runtime libraries (which is the default).  File: tinc.info, Node: Installation, Next: Configuration, Prev: Preparations, Up: Top @@ -431,9 +432,9 @@ startup scripts and sample configurations. If you cannot use one of the precompiled packages, or you want to compile tinc for yourself, you can use the source. The source is distributed under the GNU General Public License (GPL). Download the -source from the download page (http://www.tinc-vpn.org/download), which -has the checksums of these files listed; you may wish to check these -with md5sum before continuing. +source from the download page (http://www.tinc-vpn.org/download/), +which has the checksums of these files listed; you may wish to check +these with md5sum before continuing. Tinc comes in a convenient autoconf/automake package, which you can just treat the same as any other package. Which is just untar it, type @@ -474,7 +475,7 @@ File: tinc.info, Node: Darwin (MacOS/X) build environment, Next: Cygwin (Windo In order to build tinc on Darwin, you need to install the MacOS/X Developer Tools from `http://developer.apple.com/tools/macosxtools.html' and a recent -version of Fink from `http://fink.sourceforge.net/'. +version of Fink from `http://www.finkproject.org/'. After installation use fink to download and install the following packages: autoconf25, automake, dlcompat, m4, openssl, zlib and lzo. @@ -573,7 +574,6 @@ File: tinc.info, Node: Configuration, Next: Running tinc, Prev: Installation, * Multiple networks:: * How connections work:: * Configuration files:: -* Generating keypairs:: * Network interfaces:: * Example configuration:: @@ -593,13 +593,19 @@ Do you want to run tinc in router mode or switch mode? These questions can only be answered by yourself, you will not find the answers in this documentation. Make sure you have an adequate understanding of networks in general. A good resource on networking is the Linux -Network Administrators Guide (http://www.linuxdoc.org/LDP/nag2/). +Network Administrators Guide (http://www.tldp.org/LDP/nag2/). If you have everything clearly pictured in your mind, proceed in the -following order: First, generate the configuration files (`tinc.conf', -your host configuration file, `tinc-up' and perhaps `tinc-down'). Then -generate the keypairs. Finally, distribute the host configuration -files. These steps are described in the subsections below. +following order: First, create the initial configuration files and +public/private keypairs using the following command: + tincctl -n NETNAME init NAME + Second, use `tincctl -n NETNAME config ...' to further configure +tinc. Finally, export your host configuration file using `tincctl -n +NETNAME export' and send it to those people or computers you want tinc +to connect to. They should send you their host configuration file +back, which you can import using `tincctl -n NETNAME import'. + + These steps are described in the subsections below.  File: tinc.info, Node: Multiple networks, Next: How connections work, Prev: Configuration introduction, Up: Configuration @@ -610,27 +616,26 @@ File: tinc.info, Node: Multiple networks, Next: How connections work, Prev: C In order to allow you to run more than one tinc daemon on one computer, for instance if your computer is part of more than one VPN, you can assign a NETNAME to your VPN. It is not required if you only run one -tinc daemon, it doesn't even have to be the same on all the sites of +tinc daemon, it doesn't even have to be the same on all the nodes of your VPN, but it is recommended that you choose one anyway. We will asume you use a netname throughout this document. This -means that you call tincd with the -n argument, which will assign a -netname to this daemon. +means that you call tincctl with the -n argument, which will specify +the netname. - The effect of this is that the daemon will set its configuration + The effect of this option is that tinc will set its configuration root to `/etc/tinc/NETNAME/', where NETNAME is your argument to the -n -option. You'll notice that it appears in syslog as `tinc.NETNAME'. +option. You will also notice that log messages it appears in syslog as +coming from `tinc.NETNAME', and on Linux, unless specified otherwise, +the name of the virtual network interface will be the same as the +network name. However, it is not strictly necessary that you call tinc with the -n -option. In this case, the network name would just be empty, and it will -be used as such. tinc now looks for files in `/etc/tinc/', instead of -`/etc/tinc/NETNAME/'; the configuration file should be -`/etc/tinc/tinc.conf', and the host configuration files are now -expected to be in `/etc/tinc/hosts/'. - - But it is highly recommended that you use this feature of tinc, -because it will be so much clearer whom your daemon talks to. Hence, -we will assume that you use it. +option. If you don not use it, the network name will just be empty, and +tinc will look for files in `/etc/tinc/' instead of +`/etc/tinc/NETNAME/'; the configuration file will then be +`/etc/tinc/tinc.conf', and the host configuration files are expected to +be in `/etc/tinc/hosts/'.  File: tinc.info, Node: How connections work, Next: Configuration files, Prev: Multiple networks, Up: Configuration @@ -656,8 +661,31 @@ a server, and one which does specify such a value as a client. It does not matter if two tinc daemons have a `ConnectTo' value pointing to each other however. + Connections specified using `ConnectTo' are so-called +meta-connections. Tinc daemons exchange information about all other +daemon they know about via these meta-connections. After learning +about all the daemons in the VPN, tinc will create other connections as +necessary in order to communicate with them. For example, if there are +three daemons named A, B and C, and A has `ConnectTo = B' in its +tinc.conf file, and C has `ConnectTo = B' in its tinc.conf file, then A +will learn about C from B, and will be able to exchange VPN packets +with C without the need to have `ConnectTo = C' in its tinc.conf file. + + It could be that some daemons are located behind a Network Address +Translation (NAT) device, or behind a firewall. In the above scenario +with three daemons, if A and C are behind a NAT, B will automatically +help A and C punch holes through their NAT, in a way similar to the +STUN protocol, so that A and C can still communicate with each other +directly. It is not always possible to do this however, and firewalls +might also prevent direct communication. In that case, VPN packets +between A and C will be forwarded by B. + + In effect, all nodes in the VPN will be able to talk to each other, +as long as their is a path of meta-connections between them, and +whenever possible, two nodes will communicate with each other directly. +  -File: tinc.info, Node: Configuration files, Next: Generating keypairs, Prev: How connections work, Up: Configuration +File: tinc.info, Node: Configuration files, Next: Network interfaces, Prev: How connections work, Up: Configuration 4.4 Configuration files ======================= @@ -684,9 +712,12 @@ options for the local node listed in this document can also be put in configuration options in the host configuration file, as this makes it easy to exchange with other nodes. - In this section all valid variables are listed in alphabetical order. -The default value is given between parentheses, other comments are -between square brackets. + You can edit the config file manually, but it is recommended that +you use tincctl to change configuration variables for you. + + In the following two subsections all valid variables are listed in +alphabetical order. The default value is given between parentheses, +other comments are between square brackets. * Menu: @@ -707,12 +738,16 @@ AddressFamily = (any) system both IPv4 and IPv6 or just IPv6 listening sockets will be created. -BindToAddress =
[experimental] +BindToAddress =
[] If your computer has more than one IPv4 or IPv6 address, tinc will - by default listen on all of them for incoming connections. It is - possible to bind only to a single address with this variable. + by default listen on all of them for incoming connections. + Multiple BindToAddress variables may be specified, in which case + listening sockets for each specified address are made. - This option may not work on all platforms. + If no PORT is specified, the socket will be bound to the port + specified by the Port option, or to port 655 if neither is given. + To only bind to a specific port but not to a specific address, use + "*" for the ADDRESS. BindToInterface = [experimental] If you have more than one network interface in your computer, tinc @@ -720,7 +755,30 @@ BindToInterface = [experimental] It is possible to bind tinc to a single interface like eth0 or ppp0 with this variable. - This option may not work on all platforms. + This option may not work on all platforms. Also, on some + platforms it will not actually bind to an interface, but rather to + the address that the interface has at the moment a socket is + created. + +Broadcast = (mst) [experimental] + This option selects the way broadcast packets are sent to other + daemons. _NOTE: all nodes in a VPN must use the same Broadcast + mode, otherwise routing loops can form._ + + no + Broadcast packets are never sent to other nodes. + + mst + Broadcast packets are sent and forwarded via the VPN's + Minimum Spanning Tree. This ensures broadcast packets reach + all nodes. + + direct + Broadcast packets are sent directly to all nodes that can be + reached directly. Broadcast packets received from other + nodes are never forwarded. If the IndirectData option is + also set, broadcast packets will only be sent to nodes which + we have a meta connection to. ConnectTo = Specifies which other tinc daemon to connect to on startup. @@ -733,6 +791,15 @@ ConnectTo = connect to other daemons at all, and will instead just listen for incoming connections. +DecrementTTL = (no) [experimental] + When enabled, tinc will decrement the Time To Live field in IPv4 + packets, or the Hop Limit field in IPv6 packets, before forwarding + a received packet to the virtual network device or to another node, + and will drop packets that have a TTL value of zero, in which case + it will send an ICMP Time Exceeded packet back. + + Do not use this option if you use switch mode and want to use IPv6. + Device = (`/dev/tap0', `/dev/net/tun' or other depending on platform) The virtual network device to use. Tinc will automatically detect what kind of device it is. Note that you can only use one device @@ -740,31 +807,68 @@ Device = (`/dev/tap0', `/dev/net/tun' or other depending on platform) that you can only use one device per daemon. See also *note Device files::. -DeviceType = (only supported on BSD platforms) +DeviceType = (platform dependent) The type of the virtual network device. Tinc will normally - automatically select the right type, and this option should not be - used. However, in case tinc does not seem to correctly interpret - packets received from the virtual network device, using this - option might help. + automatically select the right type of tun/tap interface, and this + option should not be used. However, this option can be used to + select one of the special interface types, if support for them is + compiled in. - tun + dummy + Use a dummy interface. No packets are ever read or written + to a virtual network device. Useful for testing, or when + setting up a node that only forwards packets for other nodes. + + raw_socket + Open a raw socket, and bind it to a pre-existing INTERFACE + (eth0 by default). All packets are read from this interface. + Packets received for the local node are written to the raw + socket. However, at least on Linux, the operating system + does not process IP packets destined for the local host. + + multicast + Open a multicast UDP socket and bind it to the address and + port (separated by spaces) and optionally a TTL value + specified using DEVICE. Packets are read from and written to + this multicast socket. This can be used to connect to UML, + QEMU or KVM instances listening on the same multicast address. + Do NOT connect multiple tinc daemons to the same multicast + address, this will very likely cause routing loops. Also + note that this can cause decrypted VPN packets to be sent out + on a real network if misconfigured. + + uml (not compiled in by default) + Create a UNIX socket with the filename specified by DEVICE, + or `/var/run/NETNAME.umlsocket' if not specified. Tinc will + wait for a User Mode Linux instance to connect to this socket. + + vde (not compiled in by default) + Uses the libvdeplug library to connect to a Virtual + Distributed Ethernet switch, using the UNIX socket specified + by DEVICE, or `/var/run/vde.ctl' if not specified. + + Also, in case tinc does not seem to correctly interpret packets + received from the virtual network device, it can be used to change + the way packets are interpreted: + + tun (BSD and Linux) Set type to tun. Depending on the platform, this can either be with or without an address family header (see below). - tunnohead + tunnohead (BSD) Set type to tun without an address family header. Tinc will expect packets read from the virtual network device to start with an IP header. On some platforms IPv6 packets cannot be read from or written to the device in this mode. - tunifhead + tunifhead (BSD) Set type to tun with an address family header. Tinc will expect packets read from the virtual network device to start with a four byte header containing the address family, followed by an IP header. This mode should support both IPv4 and IPv6 packets. - tap + tap (BSD and Linux) Set type to tap. Tinc will expect packets read from the virtual network device to start with an Ethernet header. @@ -808,7 +912,7 @@ Forwarding = (internal) [experimental] efficient, but allows the kernel to apply its routing and firewall rules on them, and can also help debugging. -GraphDumpFile = [experimental] +GraphDumpFile = If this option is present, tinc will dump the current network graph to the file FILENAME every minute, unless there were no changes to the graph. The file is in a format that can be read by @@ -824,7 +928,8 @@ Hostnames = (no) responding. This does not affect resolving hostnames to IP addresses from the - configuration file. + configuration file, but whether hostnames should be resolved while + logging. Interface = Defines the name of the interface corresponding to the virtual @@ -834,6 +939,17 @@ Interface = interface will be used. If you specified a Device, this variable is almost always already correctly set. +LocalDiscovery = (no) + When enabled, tinc will try to detect peers that are on the same + local network. This will allow direct communication using LAN + addresses, even if both peers are behind a NAT and they only + ConnectTo a third node outside the NAT, which normally would + prevent the peers from learning each other's LAN address. + + Currently, local discovery is implemented by sending broadcast + packets to the LAN during path MTU discovery. This feature may + not work in all possible situations. + Mode = (router) This option selects the way packets are routed to other daemons. @@ -878,6 +994,12 @@ Name = [required] consist only of alfanumeric and underscore characters (a-z, A-Z, 0-9 and _). + If Name starts with a $, then the contents of the environment + variable that follows will be used. In that case, invalid + characters will be converted to underscores. If Name is $HOST, + but no such environment variable exist, the hostname will be read + using the gethostnname() system call. + PingInterval = (60) The number of seconds of inactivity that tinc will wait before sending a probe to the other end. @@ -912,6 +1034,29 @@ ProcessPriority = adjusted. Increasing the priority may help to reduce latency and packet loss on the VPN. +Proxy = socks4 | socks4 | http | exec ... [experimental] + Use a proxy when making outgoing connections. The following proxy + types are currently supported: + + socks4
[] + Connects to the proxy using the SOCKS version 4 protocol. + Optionally, a USERNAME can be supplied which will be passed + on to the proxy server. + + socks4
[ ] + Connect to the proxy using the SOCKS version 5 protocol. If + a USERNAME and PASSWORD are given, basic username/password + authentication will be used, otherwise no authentication will + be used. + + http
+ Connects to the proxy and sends a HTTP CONNECT request. + + exec + Executes the given command which should set up the outgoing + connection. The environment variables `NAME', `NODE', + `REMOTEADDRES' and `REMOTEPORT' are available. + ReplayWindow = (16) This is the size of the replay tracking window for each remote node, in bytes. The window is a bitfield which tracks 1 packet @@ -1030,18 +1175,17 @@ Subnet = Subnets can either be single MAC, IPv4 or IPv6 addresses, in which case a subnet consisting of only that single address is assumed, or they can be a IPv4 or IPv6 network address with a prefixlength. - Shorthand notations are not supported. For example, IPv4 subnets - must be in a form like 192.168.1.0/24, where 192.168.1.0 is the - network address and 24 is the number of bits set in the netmask. - Note that subnets like 192.168.1.1/24 are invalid! Read a - networking HOWTO/FAQ/guide if you don't understand this. IPv6 - subnets are notated like fec0:0:0:1:0:0:0:0/64. MAC addresses are - notated like 0:1a:2b:3c:4d:5e. + For example, IPv4 subnets must be in a form like 192.168.1.0/24, + where 192.168.1.0 is the network address and 24 is the number of + bits set in the netmask. Note that subnets like 192.168.1.1/24 + are invalid! Read a networking HOWTO/FAQ/guide if you don't + understand this. IPv6 subnets are notated like fec0:0:0:1::/64. + MAC addresses are notated like 0:1a:2b:3c:4d:5e. Prefixlength is the number of bits set to 1 in the netmask part; for example: netmask 255.255.255.0 would become /24, 255.255.252.0 becomes /22. This conforms to standard CIDR notation as described - in RFC1519 (ftp://ftp.isi.edu/in-notes/rfc1519.txt) + in RFC1519 (http://www.ietf.org/rfc/rfc1519.txt) A Subnet can be given a weight to indicate its priority over identical Subnets owned by different nodes. The default weight is @@ -1142,55 +1286,117 @@ File: tinc.info, Node: How to configure, Prev: Scripts, Up: Configuration fil 4.4.4 How to configure ---------------------- -Step 1. Creating the main configuration file -............................................. - -The main configuration file will be called -`/etc/tinc/NETNAME/tinc.conf'. Adapt the following example to create a -basic configuration file: - - Name = YOURNAME - Device = `/dev/tap0' - - Then, if you know to which other tinc daemon(s) yours is going to -connect, add `ConnectTo' values. - -Step 2. Creating your host configuration file +Step 1. Creating initial configuration files. .............................................. -If you added a line containing `Name = yourname' in the main -configuarion file, you will need to create a host configuration file -`/etc/tinc/NETNAME/hosts/yourname'. Adapt the following example to -create a host configuration file: +The initial directory structure, configuration files and public/private +keypairs are created using the following command: - Address = your.real.hostname.org - Subnet = 192.168.1.0/24 + tincctl -n NETNAME init NAME - You can also use an IP address instead of a hostname. The `Subnet' -specifies the address range that is local for _your part of the VPN -only_. If you have multiple address ranges you can specify more than -one `Subnet'. You might also need to add a `Port' if you want your -tinc daemon to run on a different port number than the default (655). + (You will need to run this as root, or use "sudo".) This will +create the configuration directory `/etc/tinc/NETNAME.', and inside it +will create another directory named `hosts/'. In the configuration +directory, it will create the file `tinc.conf' with the following +contents: + + Name = NAME + + It will also create private RSA and ECDSA keys, which will be stored +in the files `rsa_key.priv' and `ecdsa_key.priv'. It will also create +a host configuration file `hosts/NAME', which will contain the +corresponding public RSA and ECDSA keys. + + Finally, on UNIX operating systems, it will create an executable +script `tinc-up', which will initially not do anything except warning +that you should edit it. + +Step 2. Modifying the initial configuration. +............................................. + +Unless you want to use tinc in switch mode, you should now configure +which range of addresses you will use on the VPN. Let's assume you +will be part of a VPN which uses the address range 192.168.0.0/16, and +you yourself have a smaller portion of that range: 192.168.2.0/24. +Then you should run the following command: + + tincctl -n NETNAME config add subnet 192.168.2.0/24 + + This will add a Subnet statement to your host configuration file. +Try opening the file `/etc/tinc/NETNAME/hosts/NAME' in an editor. You +should now see a file containing the public RSA and ECDSA keys (which +looks like a bunch of random characters), and the following line at the +bottom: + + Subnet = 192.168.2.0/24 + + If you will use more than one address range, you can add more +Subnets. For example, if you also use the IPv6 subnet fec0:0:0:2::/64, +you can add it as well: + + tincctl -n NETNAME config add subnet fec0:0:0:2::/24 + + This will add another line to the file `hosts/NAME'. If you make a +mistake, you can undo it by simply using `config del' instead of +`config add'. + + If you want other tinc daemons to create meta-connections to your +daemon, you should add your public IP address or hostname to your host +configuration file. For example, if your hostname is foo.example.org, +run: + + tincctl -n NETNAME config add address foo.example.org + + If you already know to which daemons your daemon should make +meta-connections, you should configure that now as well. Suppose you +want to connect to a daemon named "bar", run: + + tincctl -n NETNAME config add connectto bar + + Note that you specify the Name of the other daemon here, not an IP +address or hostname! When you start tinc, and it tries to make a +connection to "bar", it will look for a host configuration file named +`hosts/bar', and will read Address statements and public keys from that +file. + +Step 2. Exchanging configuration files. +........................................ + +If your daemon has a ConnectTo = bar statement in its `tinc.conf' file, +or if bar has a ConnectTo your daemon, then you both need each other's +host configuration files. You should send `hosts/NAME' to bar, and bar +should send you his file which you should move to `hosts/bar'. If you +are on a UNIX platform, you can easily send an email containing the +necessary information using the following command (assuming the owner +of bar has the email address bar@example.org): + + tincctl -n NETNAME export | mail -s "My config file" bar@example.org + + If the owner of bar does the same to send his host configuration +file to you, you can probably pipe his email through the following +command, or you can just start this command in a terminal and +copy&paste the email: + + tincctl -n NETNAME import + + If you are the owner of bar yourself, and you have SSH access to +that computer, you can also swap the host configuration files using the +following commands: + + tincctl -n NETNAME export | ssh bar.example.org tincctl -n NETNAME import + ssh bar.example.org tincctl -n NETNAME export | tincctl -n NETNAME import + + You should repeat this for all nodes you ConnectTo, or which +ConnectTo you. However, remember that you do not need to ConnectTo all +nodes in the VPN; it is only necessary to create one or a few +meta-connections, after the connections are made tinc will learn about +all the other nodes in the VPN, and will automatically make other +connections as necessary.  -File: tinc.info, Node: Generating keypairs, Next: Network interfaces, Prev: Configuration files, Up: Configuration +File: tinc.info, Node: Network interfaces, Next: Example configuration, Prev: Configuration files, Up: Configuration -4.5 Generating keypairs -======================= - -Now that you have already created the main configuration file and your -host configuration file, you can easily create a public/private keypair -by entering the following command: - - tincctl -n NETNAME generate-keys - - Tinc will generate a public and a private key and ask you where to -put them. Just press enter to accept the defaults. - - -File: tinc.info, Node: Network interfaces, Next: Example configuration, Prev: Generating keypairs, Up: Configuration - -4.6 Network interfaces +4.5 Network interfaces ====================== Before tinc can start transmitting data over the tunnel, it must set up @@ -1211,19 +1417,28 @@ ifconfig, route, and other commands to a script named `/etc/tinc/NETNAME/tinc-up'. When tinc starts, this script will be executed. When tinc exits, it will execute the script named `/etc/tinc/NETNAME/tinc-down', but normally you don't need to create -that script. +that script. You can manually open the script in an editor, or use the +following command: - An example `tinc-up' script: + tincctl -n NETNAME edit tinc-up + + An example `tinc-up' script, that would be appropriate for the +scenario in the previous section, is: #!/bin/sh - ifconfig $INTERFACE 192.168.1.1 netmask 255.255.0.0 + ifconfig $INTERFACE 192.168.2.1 netmask 255.255.0.0 + ip addr add fec0:0:0:2::/48 dev $INTERFACE - This script gives the interface an IP address and a netmask. The -kernel will also automatically add a route to this interface, so -normally you don't need to add route commands to the `tinc-up' script. -The kernel will also bring the interface up after this command. The + The first command gives the interface an IPv4 address and a netmask. +The kernel will also automatically add an IPv4 route to this interface, +so normally you don't need to add route commands to the `tinc-up' +script. The kernel will also bring the interface up after this command. The netmask is the mask of the _entire_ VPN network, not just your own -subnet. +subnet. The second command gives the interface an IPv6 address and +netmask, which will also automatically add an IPv6 route. If you only +want to use "ip addr" commands on Linux, don't forget that it doesn't +bring the interface up, unlike ifconfig, so you need to add `ip link +set $INTERFACE up' in that case. The exact syntax of the ifconfig and route commands differs from platform to platform. You can look up the commands for setting @@ -1234,7 +1449,7 @@ platform.  File: tinc.info, Node: Example configuration, Prev: Network interfaces, Up: Configuration -4.7 Example configuration +4.6 Example configuration ========================= Imagine the following situation. Branch A of our example `company' @@ -1262,6 +1477,9 @@ configuration of the real interface is also shown as a comment, to give you an idea of how these example host is set up. All branches use the netname `company' for this particular VPN. + Each branch is set up using the `tincctl init' and `tincctl config' +commands, here we just show the end results: + For Branch A ............ @@ -1269,6 +1487,8 @@ _BranchA_ would be configured like this: In `/etc/tinc/company/tinc-up': + #!/bin/sh + # Real interface of internal network: # ifconfig eth0 10.1.54.1 netmask 255.255.0.0 @@ -1277,7 +1497,6 @@ _BranchA_ would be configured like this: and in `/etc/tinc/company/tinc.conf': Name = BranchA - Device = /dev/tap0 On all hosts, `/etc/tinc/company/hosts/BranchA' contains: @@ -1288,17 +1507,19 @@ _BranchA_ would be configured like this: ... -----END RSA PUBLIC KEY----- - 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 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. + Note that the IP addresses of eth0 and the VPN interface 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 both +real internal network interfaces and VPN interfaces the same IP address, +since that will make things a lot easier to remember and set up. For Branch B ............ In `/etc/tinc/company/tinc-up': + #!/bin/sh + # Real interface of internal network: # ifconfig eth0 10.2.43.8 netmask 255.255.0.0 @@ -1310,8 +1531,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 this node -will always try to connect to BranchA. +same as on the VPN interface. Also, ConnectTo is given so that this +node will always try to connect to BranchA. On all hosts, in `/etc/tinc/company/hosts/BranchB': @@ -1327,6 +1548,8 @@ For Branch C In `/etc/tinc/company/tinc-up': + #!/bin/sh + # Real interface of internal network: # ifconfig eth0 10.3.69.254 netmask 255.255.0.0 @@ -1336,7 +1559,6 @@ In `/etc/tinc/company/tinc-up': Name = BranchC ConnectTo = BranchA - Device = /dev/tap1 C already has another daemon that runs on port 655, so they have to reserve another port for tinc. It knows the portnumber it has to listen @@ -1357,6 +1579,8 @@ For Branch D In `/etc/tinc/company/tinc-up': + #!/bin/sh + # Real interface of internal network: # ifconfig eth0 10.4.3.32 netmask 255.255.0.0 @@ -1366,13 +1590,10 @@ In `/etc/tinc/company/tinc-up': Name = BranchD ConnectTo = BranchC - Device = /dev/net/tun D will be connecting to C, which has a tincd running for this network on port 2000. It knows the port number from the host -configuration file. Also note that since D uses the tun/tap driver, -the network interface will not be called `tun' or `tap0' or something -like that, but will have the same name as netname. +configuration file. On all hosts, in `/etc/tinc/company/hosts/BranchD': @@ -1386,16 +1607,12 @@ like that, but will have the same name as netname. Key files ......... -A, B, C and D all have generated a public/private keypair with the -following command: +A, B, C and D all have their own public/private keypairs: - tincctl -n company generate-keys - - The private key is stored in `/etc/tinc/company/rsa_key.priv', the -public key is put into the host configuration file in the -`/etc/tinc/company/hosts/' directory. During key generation, tinc -automatically guesses the right filenames based on the -n option and -the Name directive in the `tinc.conf' file (if it is available). + The private RSA key is stored in `/etc/tinc/company/rsa_key.priv', +the private ECDSA key is stored in `/etc/tinc/company/ecdsa_key.priv', +and the public RSA and ECDSA keys are put into the host configuration +file in the `/etc/tinc/company/hosts/' directory. Starting ........ @@ -1415,7 +1632,7 @@ File: tinc.info, Node: Running tinc, Next: Controlling tinc, Prev: Configurat If everything else is done, you can start tinc by typing the following command: - tincd -n NETNAME + tincctl -n NETNAME start Tinc will detach from the terminal and continue to run in the background like a good daemon. If there are any problems however you @@ -1462,6 +1679,13 @@ command line options. Store a cookie in FILENAME which allows tincctl to authenticate. If unspecified, the default is `/var/run/tinc.NETNAME.pid'. +`-o, --option=[HOST.]KEY=VALUE' + Without specifying a HOST, this will set server configuration + variable KEY to VALUE. If specified as HOST.KEY=VALUE, this will + set the host configuration variable KEY of the host named HOST to + VALUE. This option can be used more than once to specify multiple + configuration variables. + `-L, --mlock' Lock tinc into main memory. This will prevent sensitive data like shared private keys to be written to the system swap @@ -1738,12 +1962,13 @@ command. A quick example: * Menu: * tincctl runtime options:: +* tincctl environment variables:: * tincctl commands:: * tincctl examples:: * tincctl top::  -File: tinc.info, Node: tincctl runtime options, Next: tincctl commands, Up: Controlling tinc +File: tinc.info, Node: tincctl runtime options, Next: tincctl environment variables, Up: Controlling tinc 6.1 tincctl runtime options =========================== @@ -1769,13 +1994,64 @@ File: tinc.info, Node: tincctl runtime options, Next: tincctl commands, Up: C  -File: tinc.info, Node: tincctl commands, Next: tincctl examples, Prev: tincctl runtime options, Up: Controlling tinc +File: tinc.info, Node: tincctl environment variables, Next: tincctl commands, Prev: tincctl runtime options, Up: Controlling tinc -6.2 tincctl commands +6.2 tincctl environment variables +================================= + +`NETNAME' + If no netname is specified on the command line with the `-n' + option, the value of this environment variable is used. + + +File: tinc.info, Node: tincctl commands, Next: tincctl examples, Prev: tincctl environment variables, Up: Controlling tinc + +6.3 tincctl commands ==================== -`start' - Start `tincd'. +`init [NAME]' + Create initial configuration files and RSA and ECDSA keypairs with + default length. If no NAME for this node is given, it will be + asked for. + +`config [get] VARIABLE' + Print the current value of configuration variable VARIABLE. If + more than one variable with the same name exists, the value of + each of them will be printed on a separate line. + +`config [set] VARIABLE VALUE' + Set configuration variable VARIABLE to the given VALUE. All + previously existing configuration variables with the same name are + removed. To set a variable for a specific host, use the notation + HOST.VARIABLE. + +`config add VARIABLE VALUE' + As above, but without removing any previously existing + configuration variables. + +`config del VARIABLE [VALUE]' + Remove configuration variables with the same name and VALUE. If + no VALUE is given, all configuration variables with the same name + will be removed. + +`edit FILENAME' + Start an editor for the given configuration file. You do not need + to specify the full path to the file. + +`export' + Export the host configuration file of the local node to standard + output. + +`export-all' + Export all host configuration files to standard output. + +`import [--force]' + Import host configuration file(s) from standard input. Already + existing host configuration files are not overwritten unless the + option -force is used. + +`start [tincd options]' + Start `tincd', optionally with the given extra options. `stop' Stop `tincd'. @@ -1809,8 +2085,16 @@ File: tinc.info, Node: tincctl commands, Next: tincctl examples, Prev: tincct `dump connections' Dump a list of all meta connections with ourself. -`dump graph' - Dump a graph of the VPN in dotty format. +`dump graph | digraph' + Dump a graph of the VPN in dotty format. Nodes are colored + according to their reachability: red nodes are unreachable, orange + nodes are indirectly reachable, green nodes are directly reachable. + Black nodes are either directly or indirectly reachable, but + direct reachability has not been tried yet. + +`info NODE | SUBNET | ADDRESS' + Show information about a particular NODE, SUBNET or ADDRESS. If + an ADDRESS is given, any matching subnet will be shown. `purge' Purges all information remembered about unreachable nodes. @@ -1818,6 +2102,11 @@ File: tinc.info, Node: tincctl commands, Next: tincctl examples, Prev: tincct `debug LEVEL' Sets debug level to LEVEL. +`log [LEVEL]' + Capture log messages from a running tinc daemon. An optional + debug level can be given that will be applied only for log + messages sent to tincctl. + `retry' Forces tinc to try to connect to all uplinks immediately. Usually tinc attempts to do this itself, but increases the time it waits @@ -1843,7 +2132,7 @@ File: tinc.info, Node: tincctl commands, Next: tincctl examples, Prev: tincct  File: tinc.info, Node: tincctl examples, Next: tincctl top, Prev: tincctl commands, Up: Controlling tinc -6.3 tincctl examples +6.4 tincctl examples ==================== Examples of some commands: @@ -1852,10 +2141,18 @@ Examples of some commands: tincctl -n vpn pcap | tcpdump -r - tincctl -n vpn top + Example of configuring tinc using tincctl: + + tincctl -n vpn init foo + tincctl -n vpn config Subnet 192.168.1.0/24 + tincctl -n vpn config bar.Address bar.example.com + tincctl -n vpn config ConnectTo bar + tincctl -n vpn export | gpg --clearsign | mail -s "My config" vpnmaster@example.com +  File: tinc.info, Node: tincctl top, Prev: tincctl examples, Up: Controlling tinc -6.4 tincctl top +6.5 tincctl top =============== The top command connects to a running tinc daemon and repeatedly @@ -2387,6 +2684,19 @@ Solaris `ifconfig' INTERFACE `inet6 plumb up' Darwin (MacOS/X) `ifconfig' INTERFACE `inet6' ADDRESS `prefixlen' PREFIXLENGTH Windows `netsh interface ipv6 add address' INTERFACE `static' ADDRESS/PREFIXLENGTH + On some platforms, when running tinc in switch mode, the VPN +interface must be set to tap mode with an ifconfig command: + +OpenBSD `ifconfig' INTERFACE `link0' + + On Linux, it is possible to create a persistent tun/tap interface +which will continue to exist even if tinc quit, although this is +normally not required. It can be useful to set up a tun/tap interface +owned by a non-root user, so tinc can be started without needing any +root privileges at all. + +Linux `ip tuntap add dev' INTERFACE `mode' TUN|TAP `user' USERNAME +  File: tinc.info, Node: Routes, Prev: Interface configuration, Up: Platform specific information @@ -2487,14 +2797,16 @@ Concept Index * BindToAddress: Main configuration variables. (line 12) * BindToInterface: Main configuration variables. - (line 19) + (line 23) +* Broadcast: Main configuration variables. + (line 34) * Cabal: Security. (line 6) * CHAL_REPLY: Authentication protocol. (line 10) * CHALLENGE: Authentication protocol. (line 10) * CIDR notation: Host configuration variables. - (line 92) + (line 91) * Cipher: Host configuration variables. (line 12) * ClampMSS: Host configuration variables. @@ -2506,72 +2818,85 @@ Concept Index (line 24) * connection: The connection. (line 6) * ConnectTo: Main configuration variables. - (line 27) + (line 54) * daemon: Running tinc. (line 11) * data-protocol: The meta-connection. (line 18) * debug level: Runtime options. (line 17) * debug levels: Debug levels. (line 6) +* DecrementTTL: Main configuration variables. + (line 65) * DEL_EDGE: The meta-protocol. (line 47) * DEL_SUBNET: The meta-protocol. (line 47) * DEVICE: Scripts. (line 55) * Device: Main configuration variables. - (line 38) + (line 74) * device files: Device files. (line 6) * DeviceType: Main configuration variables. - (line 45) + (line 81) * Digest: Host configuration variables. (line 29) * DirectOnly: Main configuration variables. - (line 73) + (line 146) +* dummy: Main configuration variables. + (line 88) * ECDSAPrivateKeyFile: Main configuration variables. - (line 80) + (line 153) * encapsulating: The UDP tunnel. (line 30) * encryption: Encryption of network packets. (line 6) * environment variables: Scripts. (line 43) * example: Example configuration. (line 6) +* exec: Main configuration variables. + (line 326) * ExperimentalProtocol: Main configuration variables. - (line 84) + (line 157) * Forwarding: Main configuration variables. - (line 93) + (line 166) * frame type: The UDP tunnel. (line 6) * GraphDumpFile: Main configuration variables. - (line 113) + (line 186) * Hostnames: Main configuration variables. - (line 121) + (line 194) +* http: Main configuration variables. + (line 323) * hub: Main configuration variables. - (line 162) + (line 247) * ID: Authentication protocol. (line 10) * IndirectData: Host configuration variables. (line 34) * INTERFACE: Scripts. (line 58) * Interface: Main configuration variables. - (line 131) + (line 205) * IRC: Contact information. (line 9) -* key generation: Generating keypairs. (line 6) * KEY_CHANGED: The meta-protocol. (line 64) * KeyExpire: Main configuration variables. - (line 167) + (line 252) * libevent: libevent. (line 6) * libraries: Libraries. (line 6) * license: OpenSSL. (line 36) +* LocalDiscovery: Main configuration variables. + (line 213) * lzo: lzo. (line 6) * MACExpire: Main configuration variables. - (line 173) + (line 258) * MACLength: Host configuration variables. (line 42) * meta-protocol: The meta-connection. (line 18) * META_KEY: Authentication protocol. (line 10) * Mode: Main configuration variables. - (line 139) + (line 224) +* multicast: Main configuration variables. + (line 100) * multiple networks: Multiple networks. (line 6) * NAME: Scripts. (line 52) * Name: Main configuration variables. - (line 178) -* netmask: Network interfaces. (line 34) + (line 263) +* netmask: Network interfaces. (line 39) +* NETNAME <1>: tincctl environment variables. + (line 6) * NETNAME: Scripts. (line 49) * netname: Multiple networks. (line 6) * Network Administrators Guide: Configuration introduction. @@ -2583,9 +2908,9 @@ Concept Index (line 67) * PING: The meta-protocol. (line 89) * PingInterval: Main configuration variables. - (line 183) + (line 274) * PingTimeout: Main configuration variables. - (line 187) + (line 278) * platforms: Supported platforms. (line 6) * PMTU: Host configuration variables. (line 47) @@ -2596,45 +2921,53 @@ Concept Index (line 55) * port numbers: Other files. (line 17) * PriorityInheritance: Main configuration variables. - (line 193) + (line 284) * private: Virtual Private Networks. (line 10) * PrivateKey: Main configuration variables. - (line 198) + (line 289) * PrivateKeyFile: Main configuration variables. - (line 204) + (line 295) * ProcessPriority: Main configuration variables. - (line 212) + (line 303) +* Proxy: Main configuration variables. + (line 308) * PublicKey: Host configuration variables. (line 59) * PublicKeyFile: Host configuration variables. (line 62) +* raw_socket: Main configuration variables. + (line 93) * release: Supported platforms. (line 14) * REMOTEADDRESS: Scripts. (line 67) * REMOTEPORT: Scripts. (line 70) * ReplayWindow: Main configuration variables. - (line 217) + (line 331) * REQ_KEY: The meta-protocol. (line 64) * requirements: Libraries. (line 6) * router: Main configuration variables. - (line 142) + (line 227) * runtime options: Runtime options. (line 9) * scalability: tinc. (line 19) * scripts: Scripts. (line 6) * server: How connections work. (line 18) * signals: Signals. (line 6) +* socks4: Main configuration variables. + (line 312) +* socks5: Main configuration variables. + (line 317) * StrictSubnets: Main configuration variables. - (line 228) + (line 342) * SUBNET: Scripts. (line 74) * Subnet: Host configuration variables. (line 74) * SVPN: Security. (line 11) * switch: Main configuration variables. - (line 151) + (line 236) * TCP: The meta-connection. (line 10) * TCPonly: Host configuration variables. - (line 104) + (line 103) * TINC: Security. (line 6) * tinc: Introduction. (line 6) * tinc-down: Scripts. (line 18) @@ -2643,20 +2976,24 @@ Concept Index * tincd: tinc. (line 14) * traditional VPNs: tinc. (line 19) * tunifhead: Main configuration variables. - (line 62) + (line 135) * TunnelServer: Main configuration variables. - (line 233) + (line 347) * tunnohead: Main configuration variables. - (line 56) + (line 129) * UDP <1>: Encryption of network packets. (line 12) * UDP: The UDP tunnel. (line 30) * UDPRcvBuf: Main configuration variables. - (line 240) + (line 354) * UDPSndBuf: Main configuration variables. - (line 245) + (line 359) +* UML: Main configuration variables. + (line 111) * Universal tun/tap: Configuration of Linux kernels. (line 6) +* VDE: Main configuration variables. + (line 116) * virtual: Virtual Private Networks. (line 18) * virtual network device: The UDP tunnel. (line 6) @@ -2674,67 +3011,67 @@ Node: Introduction1131 Node: Virtual Private Networks1941 Node: tinc3667 Node: Supported platforms5194 -Node: Preparations5892 -Node: Configuring the kernel6148 -Node: Configuration of Linux kernels6557 -Node: Configuration of FreeBSD kernels7412 -Node: Configuration of OpenBSD kernels7802 -Node: Configuration of NetBSD kernels8410 -Node: Configuration of Solaris kernels8815 -Node: Configuration of Darwin (MacOS/X) kernels9476 -Node: Configuration of Windows10165 -Node: Libraries10679 -Node: OpenSSL11080 -Node: zlib13356 -Node: lzo14185 -Node: libevent14989 -Node: Installation15700 -Node: Building and installing tinc16715 -Node: Darwin (MacOS/X) build environment17374 -Node: Cygwin (Windows) build environment17942 -Node: MinGW (Windows) build environment18530 -Node: System files19054 -Node: Device files19319 -Node: Other files19735 -Node: Configuration20348 -Node: Configuration introduction20659 -Node: Multiple networks21932 -Node: How connections work23358 -Node: Configuration files24580 -Node: Main configuration variables25967 -Node: Host configuration variables37161 -Node: Scripts42445 -Node: How to configure45124 -Node: Generating keypairs46387 -Node: Network interfaces46899 -Node: Example configuration48747 -Node: Running tinc54083 -Node: Runtime options54668 -Node: Signals57028 -Node: Debug levels57878 -Node: Solving problems58814 -Node: Error messages60244 -Node: Sending bug reports64566 -Node: Controlling tinc65518 -Node: tincctl runtime options65881 -Node: tincctl commands66567 -Node: tincctl examples68653 -Node: tincctl top68947 -Node: Technical information70545 -Node: The connection70780 -Node: The UDP tunnel71092 -Node: The meta-connection74153 -Node: The meta-protocol75622 -Node: Security80631 -Node: Authentication protocol81761 -Node: Encryption of network packets86765 -Node: Security issues88138 -Node: Platform specific information89755 -Node: Interface configuration89983 -Node: Routes91882 -Node: About us93798 -Node: Contact information93973 -Node: Authors94377 -Node: Concept Index94782 +Node: Preparations5893 +Node: Configuring the kernel6149 +Node: Configuration of Linux kernels6558 +Node: Configuration of FreeBSD kernels7413 +Node: Configuration of OpenBSD kernels7878 +Node: Configuration of NetBSD kernels8486 +Node: Configuration of Solaris kernels8891 +Node: Configuration of Darwin (MacOS/X) kernels9552 +Node: Configuration of Windows10241 +Node: Libraries10755 +Node: OpenSSL11156 +Node: zlib13432 +Node: lzo14261 +Node: libevent15065 +Node: Installation15760 +Node: Building and installing tinc16776 +Node: Darwin (MacOS/X) build environment17435 +Node: Cygwin (Windows) build environment18002 +Node: MinGW (Windows) build environment18590 +Node: System files19114 +Node: Device files19379 +Node: Other files19795 +Node: Configuration20408 +Node: Configuration introduction20695 +Node: Multiple networks22242 +Node: How connections work23622 +Node: Configuration files26195 +Node: Main configuration variables27728 +Node: Host configuration variables44334 +Node: Scripts49564 +Node: How to configure52243 +Node: Network interfaces56861 +Node: Example configuration59262 +Node: Running tinc64414 +Node: Runtime options65007 +Node: Signals67711 +Node: Debug levels68561 +Node: Solving problems69497 +Node: Error messages70927 +Node: Sending bug reports75249 +Node: Controlling tinc76201 +Node: tincctl runtime options76598 +Node: tincctl environment variables77297 +Node: tincctl commands77641 +Node: tincctl examples81866 +Node: tincctl top82471 +Node: Technical information84069 +Node: The connection84304 +Node: The UDP tunnel84616 +Node: The meta-connection87677 +Node: The meta-protocol89146 +Node: Security94155 +Node: Authentication protocol95285 +Node: Encryption of network packets100289 +Node: Security issues101662 +Node: Platform specific information103279 +Node: Interface configuration103507 +Node: Routes105960 +Node: About us107876 +Node: Contact information108051 +Node: Authors108455 +Node: Concept Index108860  End Tag Table diff --git a/doc/tinc.texi b/doc/tinc.texi index 69e5a2b..ac3a630 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-2011 Ivo Timmermans, +Copyright @copyright{} 1998-2012 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-2011 Ivo Timmermans, +Copyright @copyright{} 1998-2012 Ivo Timmermans, Guus Sliepen and Wessel Dankers . @@ -187,7 +187,7 @@ packets. @cindex release For an up to date list of supported platforms, please check the list on our website: -@uref{http://www.tinc-vpn.org/platforms}. +@uref{http://www.tinc-vpn.org/platforms/}. @c @c @@ -262,7 +262,7 @@ alias char-major-10-200 tun @subsection Configuration of FreeBSD kernels For FreeBSD version 4.1 and higher, tun and tap drivers are included in the default kernel configuration. -Using tap devices is recommended. +The tap driver can be loaded with @code{kldload if_tap}, or by adding @code{if_tap_load="YES"} to @file{/boot/loader.conf}. @c ================================================================== @@ -276,6 +276,7 @@ which adds a tap device to OpenBSD which should work with tinc, but with recent versions of OpenBSD, a tun device can act as a tap device by setting the link0 option with ifconfig. + @c ================================================================== @node Configuration of NetBSD kernels @subsection Configuration of NetBSD kernels @@ -466,7 +467,7 @@ available. Make sure you install the development AND runtime versions of this package. If you have to install libevent manually, you can get the source code -from @url{http://monkey.org/~provos/libevent/}. Instructions on how to configure, +from @url{http://libevent.org/}. Instructions on how to configure, build and install this package are included within the package. Please make sure you build development and runtime libraries (which is the default). @@ -492,7 +493,7 @@ system startup scripts and sample configurations. If you cannot use one of the precompiled packages, or you want to compile tinc for yourself, you can use the source. The source is distributed under the GNU General Public License (GPL). Download the source from the -@uref{http://www.tinc-vpn.org/download, download page}, which has +@uref{http://www.tinc-vpn.org/download/, download page}, which has the checksums of these files listed; you may wish to check these with md5sum before continuing. @@ -533,7 +534,7 @@ The documentation that comes along with your distribution will tell you how to d In order to build tinc on Darwin, you need to install the MacOS/X Developer Tools from @uref{http://developer.apple.com/tools/macosxtools.html} and -a recent version of Fink from @uref{http://fink.sourceforge.net/}. +a recent version of Fink from @uref{http://www.finkproject.org/}. After installation use fink to download and install the following packages: autoconf25, automake, dlcompat, m4, openssl, zlib and lzo. @@ -638,7 +639,6 @@ tinc 655/udp TINC * Multiple networks:: * How connections work:: * Configuration files:: -* Generating keypairs:: * Network interfaces:: * Example configuration:: @end menu @@ -661,13 +661,19 @@ you will not find the answers in this documentation. Make sure you have an adequate understanding of networks in general. @cindex Network Administrators Guide A good resource on networking is the -@uref{http://www.linuxdoc.org/LDP/nag2/, Linux Network Administrators Guide}. +@uref{http://www.tldp.org/LDP/nag2/, Linux Network Administrators Guide}. If you have everything clearly pictured in your mind, proceed in the following order: -First, generate the configuration files (@file{tinc.conf}, your host configuration file, @file{tinc-up} and perhaps @file{tinc-down}). -Then generate the keypairs. -Finally, distribute the host configuration files. +First, create the initial configuration files and public/private keypairs using the following command: +@example +tincctl -n @var{NETNAME} init @var{NAME} +@end example +Second, use @samp{tincctl -n @var{NETNAME} config ...} to further configure tinc. +Finally, export your host configuration file using @samp{tincctl -n @var{NETNAME} export} and send it to those +people or computers you want tinc to connect to. +They should send you their host configuration file back, which you can import using @samp{tincctl -n @var{NETNAME} import}. + These steps are described in the subsections below. @@ -677,30 +683,29 @@ These steps are described in the subsections below. @cindex multiple networks @cindex netname + In order to allow you to run more than one tinc daemon on one computer, for instance if your computer is part of more than one VPN, you can assign a @var{netname} to your VPN. It is not required if you only run one tinc daemon, -it doesn't even have to be the same on all the sites of your VPN, +it doesn't even have to be the same on all the nodes of your VPN, but it is recommended that you choose one anyway. We will asume you use a netname throughout this document. -This means that you call tincd with the -n argument, -which will assign a netname to this daemon. +This means that you call tincctl with the -n argument, +which will specify the netname. -The effect of this is that the daemon will set its configuration -root to @file{@value{sysconfdir}/tinc/@var{netname}/}, where @var{netname} is your argument to the -n -option. You'll notice that it appears in syslog as @file{tinc.@var{netname}}. +The effect of this option is that tinc will set its configuration +root to @file{@value{sysconfdir}/tinc/@var{netname}/}, where @var{netname} is your argument to the -n option. +You will also notice that log messages it appears in syslog as coming from @file{tinc.@var{netname}}, +and on Linux, unless specified otherwise, the name of the virtual network interface will be the same as the network name. However, it is not strictly necessary that you call tinc with the -n -option. In this case, the network name would just be empty, and it will -be used as such. tinc now looks for files in @file{@value{sysconfdir}/tinc/}, instead of -@file{@value{sysconfdir}/tinc/@var{netname}/}; the configuration file should be @file{@value{sysconfdir}/tinc/tinc.conf}, -and the host configuration files are now expected to be in @file{@value{sysconfdir}/tinc/hosts/}. - -But it is highly recommended that you use this feature of tinc, because -it will be so much clearer whom your daemon talks to. Hence, we will -assume that you use it. +option. If you don not use it, the network name will just be empty, and +tinc will look for files in @file{@value{sysconfdir}/tinc/} instead of +@file{@value{sysconfdir}/tinc/@var{netname}/}; +the configuration file will then be @file{@value{sysconfdir}/tinc/tinc.conf}, +and the host configuration files are expected to be in @file{@value{sysconfdir}/tinc/hosts/}. @c ================================================================== @@ -727,6 +732,25 @@ If you wish, you can view a tinc daemon without a `ConnectTo' value as a server, and one which does specify such a value as a client. It does not matter if two tinc daemons have a `ConnectTo' value pointing to each other however. +Connections specified using `ConnectTo' are so-called meta-connections. +Tinc daemons exchange information about all other daemon they know about via these meta-connections. +After learning about all the daemons in the VPN, +tinc will create other connections as necessary in order to communicate with them. +For example, if there are three daemons named A, B and C, and A has @samp{ConnectTo = B} in its tinc.conf file, +and C has @samp{ConnectTo = B} in its tinc.conf file, then A will learn about C from B, +and will be able to exchange VPN packets with C without the need to have @samp{ConnectTo = C} in its tinc.conf file. + +It could be that some daemons are located behind a Network Address Translation (NAT) device, or behind a firewall. +In the above scenario with three daemons, if A and C are behind a NAT, +B will automatically help A and C punch holes through their NAT, +in a way similar to the STUN protocol, so that A and C can still communicate with each other directly. +It is not always possible to do this however, and firewalls might also prevent direct communication. +In that case, VPN packets between A and C will be forwarded by B. + +In effect, all nodes in the VPN will be able to talk to each other, as long as +their is a path of meta-connections between them, and whenever possible, two +nodes will communicate with each other directly. + @c ================================================================== @node Configuration files @@ -755,7 +779,10 @@ listed in this document can also be put in put host specific configuration options in the host configuration file, as this makes it easy to exchange with other nodes. -In this section all valid variables are listed in alphabetical order. +You can edit the config file manually, but it is recommended that you use +tincctl to change configuration variables for you. + +In the following two subsections all valid variables are listed in alphabetical order. The default value is given between parentheses, other comments are between square brackets. @@ -779,12 +806,15 @@ If any is selected, then depending on the operating system both IPv4 and IPv6 or just IPv6 listening sockets will be created. @cindex BindToAddress -@item BindToAddress = <@var{address}> [experimental] +@item BindToAddress = <@var{address}> [<@var{port}>] If your computer has more than one IPv4 or IPv6 address, tinc will by default listen on all of them for incoming connections. -It is possible to bind only to a single address with this variable. +Multiple BindToAddress variables may be specified, +in which case listening sockets for each specified address are made. -This option may not work on all platforms. +If no @var{port} is specified, the socket will be bound to the port specified by the Port option, +or to port 655 if neither is given. +To only bind to a specific port but not to a specific address, use "*" for the @var{address}. @cindex BindToInterface @item BindToInterface = <@var{interface}> [experimental] @@ -794,6 +824,27 @@ possible to bind tinc to a single interface like eth0 or ppp0 with this variable. This option may not work on all platforms. +Also, on some platforms it will not actually bind to an interface, +but rather to the address that the interface has at the moment a socket is created. + +@cindex Broadcast +@item Broadcast = (mst) [experimental] +This option selects the way broadcast packets are sent to other daemons. +@emph{NOTE: all nodes in a VPN must use the same Broadcast mode, otherwise routing loops can form.} + +@table @asis +@item no +Broadcast packets are never sent to other nodes. + +@item mst +Broadcast packets are sent and forwarded via the VPN's Minimum Spanning Tree. +This ensures broadcast packets reach all nodes. + +@item direct +Broadcast packets are sent directly to all nodes that can be reached directly. +Broadcast packets received from other nodes are never forwarded. +If the IndirectData option is also set, broadcast packets will only be sent to nodes which we have a meta connection to. +@end table @cindex ConnectTo @item ConnectTo = <@var{name}> @@ -807,6 +858,15 @@ If you don't specify a host with ConnectTo, tinc won't try to connect to other daemons at all, and will instead just listen for incoming connections. +@cindex DecrementTTL +@item DecrementTTL = (no) [experimental] +When enabled, tinc will decrement the Time To Live field in IPv4 packets, or the Hop Limit field in IPv6 packets, +before forwarding a received packet to the virtual network device or to another node, +and will drop packets that have a TTL value of zero, +in which case it will send an ICMP Time Exceeded packet back. + +Do not use this option if you use switch mode and want to use IPv6. + @cindex Device @item Device = <@var{device}> (@file{/dev/tap0}, @file{/dev/net/tun} or other depending on platform) The virtual network device to use. @@ -817,32 +877,72 @@ Note that you can only use one device per daemon. See also @ref{Device files}. @cindex DeviceType -@item DeviceType = (only supported on BSD platforms) +@item DeviceType = <@var{type}> (platform dependent) The type of the virtual network device. -Tinc will normally automatically select the right type, and this option should not be used. -However, in case tinc does not seem to correctly interpret packets received from the virtual network device, -using this option might help. +Tinc will normally automatically select the right type of tun/tap interface, and this option should not be used. +However, this option can be used to select one of the special interface types, if support for them is compiled in. @table @asis -@item tun +@cindex dummy +@item dummy +Use a dummy interface. +No packets are ever read or written to a virtual network device. +Useful for testing, or when setting up a node that only forwards packets for other nodes. + +@cindex raw_socket +@item raw_socket +Open a raw socket, and bind it to a pre-existing +@var{Interface} (eth0 by default). +All packets are read from this interface. +Packets received for the local node are written to the raw socket. +However, at least on Linux, the operating system does not process IP packets destined for the local host. + +@cindex multicast +@item multicast +Open a multicast UDP socket and bind it to the address and port (separated by spaces) and optionally a TTL value specified using @var{Device}. +Packets are read from and written to this multicast socket. +This can be used to connect to UML, QEMU or KVM instances listening on the same multicast address. +Do NOT connect multiple tinc daemons to the same multicast address, this will very likely cause routing loops. +Also note that this can cause decrypted VPN packets to be sent out on a real network if misconfigured. + +@cindex UML +@item uml (not compiled in by default) +Create a UNIX socket with the filename specified by +@var{Device}, or @file{@value{localstatedir}/run/@var{netname}.umlsocket} +if not specified. +Tinc will wait for a User Mode Linux instance to connect to this socket. + +@cindex VDE +@item vde (not compiled in by default) +Uses the libvdeplug library to connect to a Virtual Distributed Ethernet switch, +using the UNIX socket specified by +@var{Device}, or @file{@value{localstatedir}/run/vde.ctl} +if not specified. +@end table + +Also, in case tinc does not seem to correctly interpret packets received from the virtual network device, +it can be used to change the way packets are interpreted: + +@table @asis +@item tun (BSD and Linux) Set type to tun. Depending on the platform, this can either be with or without an address family header (see below). @cindex tunnohead -@item tunnohead +@item tunnohead (BSD) Set type to tun without an address family header. Tinc will expect packets read from the virtual network device to start with an IP header. On some platforms IPv6 packets cannot be read from or written to the device in this mode. @cindex tunifhead -@item tunifhead +@item tunifhead (BSD) Set type to tun with an address family header. Tinc will expect packets read from the virtual network device to start with a four byte header containing the address family, followed by an IP header. This mode should support both IPv4 and IPv6 packets. -@item tap +@item tap (BSD and Linux) Set type to tap. Tinc will expect packets read from the virtual network device to start with an Ethernet header. @@ -891,7 +991,7 @@ and can also help debugging. @end table @cindex GraphDumpFile -@item GraphDumpFile = <@var{filename}> [experimental] +@item GraphDumpFile = <@var{filename}> If this option is present, tinc will dump the current network graph to the file @var{filename} every minute, unless there were no changes to the graph. @@ -908,7 +1008,7 @@ tinc's efficiency, even stopping the daemon for a few seconds everytime it does a lookup if your DNS server is not responding. This does not affect resolving hostnames to IP addresses from the -configuration file. +configuration file, but whether hostnames should be resolved while logging. @cindex Interface @item Interface = <@var{interface}> @@ -917,6 +1017,16 @@ Depending on the operating system and the type of device this may or may not act Under Windows, this variable is used to select which network interface will be used. If you specified a Device, this variable is almost always already correctly set. +@cindex LocalDiscovery +@item LocalDiscovery = (no) +When enabled, tinc will try to detect peers that are on the same local network. +This will allow direct communication using LAN addresses, even if both peers are behind a NAT +and they only ConnectTo a third node outside the NAT, +which normally would prevent the peers from learning each other's LAN address. + +Currently, local discovery is implemented by sending broadcast packets to the LAN during path MTU discovery. +This feature may not work in all possible situations. + @cindex Mode @item Mode = (router) This option selects the way packets are routed to other daemons. @@ -963,6 +1073,11 @@ This only has effect when Mode is set to "switch". This is a symbolic name for this connection. The name should consist only of alfanumeric and underscore characters (a-z, A-Z, 0-9 and _). +If Name starts with a $, then the contents of the environment variable that follows will be used. +In that case, invalid characters will be converted to underscores. +If Name is $HOST, but no such environment variable exist, +the hostname will be read using the gethostnname() system call. + @cindex PingInterval @item PingInterval = <@var{seconds}> (60) The number of seconds of inactivity that tinc will wait before sending a @@ -1000,6 +1115,33 @@ 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 Proxy +@item Proxy = socks4 | socks4 | http | exec @var{...} [experimental] +Use a proxy when making outgoing connections. +The following proxy types are currently supported: + +@table @asis +@cindex socks4 +@item socks4 <@var{address}> <@var{port}> [<@var{username}>] +Connects to the proxy using the SOCKS version 4 protocol. +Optionally, a @var{username} can be supplied which will be passed on to the proxy server. + +@cindex socks5 +@item socks4 <@var{address}> <@var{port}> [<@var{username}> <@var{password}>] +Connect to the proxy using the SOCKS version 5 protocol. +If a @var{username} and @var{password} are given, basic username/password authentication will be used, +otherwise no authentication will be used. + +@cindex http +@item http <@var{address}> <@var{port}> +Connects to the proxy and sends a HTTP CONNECT request. + +@cindex exec +@item exec <@var{command}> +Executes the given command which should set up the outgoing connection. +The environment variables @env{NAME}, @env{NODE}, @env{REMOTEADDRES} and @env{REMOTEPORT} are available. +@end table + @cindex ReplayWindow @item ReplayWindow = (16) This is the size of the replay tracking window for each remote node, in bytes. @@ -1132,19 +1274,18 @@ Multiple subnet lines can be specified for each daemon. Subnets can either be single MAC, IPv4 or IPv6 addresses, in which case a subnet consisting of only that single address is assumed, or they can be a IPv4 or IPv6 network address with a prefixlength. -Shorthand notations are not supported. For example, IPv4 subnets must be in a form like 192.168.1.0/24, where 192.168.1.0 is the network address and 24 is the number of bits set in the netmask. Note that subnets like 192.168.1.1/24 are invalid! Read a networking HOWTO/FAQ/guide if you don't understand this. -IPv6 subnets are notated like fec0:0:0:1:0:0:0:0/64. +IPv6 subnets are notated like fec0:0:0:1::/64. MAC addresses are notated like 0:1a:2b:3c:4d:5e. @cindex CIDR notation Prefixlength is the number of bits set to 1 in the netmask part; for example: netmask 255.255.255.0 would become /24, 255.255.252.0 becomes /22. This conforms to standard CIDR notation as described in -@uref{ftp://ftp.isi.edu/in-notes/rfc1519.txt, RFC1519} +@uref{http://www.ietf.org/rfc/rfc1519.txt, RFC1519} A Subnet can be given a weight to indicate its priority over identical Subnets owned by different nodes. The default weight is 10. Lower values indicate @@ -1254,50 +1395,115 @@ When a subnet becomes (un)reachable, this is set to the subnet. @node How to configure @subsection How to configure -@subsubheading Step 1. Creating the main configuration file +@subsubheading Step 1. Creating initial configuration files. -The main configuration file will be called @file{@value{sysconfdir}/tinc/@var{netname}/tinc.conf}. -Adapt the following example to create a basic configuration file: +The initial directory structure, configuration files and public/private keypairs are created using the following command: @example -Name = @var{yourname} -Device = @file{/dev/tap0} +tincctl -n @var{netname} init @var{name} @end example -Then, if you know to which other tinc daemon(s) yours is going to connect, -add `ConnectTo' values. - -@subsubheading Step 2. Creating your host configuration file - -If you added a line containing `Name = yourname' in the main configuarion file, -you will need to create a host configuration file @file{@value{sysconfdir}/tinc/@var{netname}/hosts/yourname}. -Adapt the following example to create a host configuration file: +(You will need to run this as root, or use "sudo".) +This will create the configuration directory @file{@value{sysconfdir}/tinc/@var{netname}.}, +and inside it will create another directory named @file{hosts/}. +In the configuration directory, it will create the file @file{tinc.conf} with the following contents: @example -Address = your.real.hostname.org -Subnet = 192.168.1.0/24 +Name = @var{name} @end example -You can also use an IP address instead of a hostname. -The `Subnet' specifies the address range that is local for @emph{your part of the VPN only}. -If you have multiple address ranges you can specify more than one `Subnet'. -You might also need to add a `Port' if you want your tinc daemon to run on a different port number than the default (655). +It will also create private RSA and ECDSA keys, which will be stored in the files @file{rsa_key.priv} and @file{ecdsa_key.priv}. +It will also create a host configuration file @file{hosts/@var{name}}, +which will contain the corresponding public RSA and ECDSA keys. +Finally, on UNIX operating systems, it will create an executable script @file{tinc-up}, +which will initially not do anything except warning that you should edit it. -@c ================================================================== -@node Generating keypairs -@section Generating keypairs +@subsubheading Step 2. Modifying the initial configuration. -@cindex key generation -Now that you have already created the main configuration file and your host configuration file, -you can easily create a public/private keypair by entering the following command: +Unless you want to use tinc in switch mode, +you should now configure which range of addresses you will use on the VPN. +Let's assume you will be part of a VPN which uses the address range 192.168.0.0/16, +and you yourself have a smaller portion of that range: 192.168.2.0/24. +Then you should run the following command: @example -tincctl -n @var{netname} generate-keys +tincctl -n @var{netname} config add subnet 192.168.2.0/24 @end example -Tinc will generate a public and a private key and ask you where to put them. -Just press enter to accept the defaults. +This will add a Subnet statement to your host configuration file. +Try opening the file @file{@value{sysconfdir}/tinc/@var{netname}/hosts/@var{name}} in an editor. +You should now see a file containing the public RSA and ECDSA keys (which looks like a bunch of random characters), +and the following line at the bottom: + +@example +Subnet = 192.168.2.0/24 +@end example + +If you will use more than one address range, you can add more Subnets. +For example, if you also use the IPv6 subnet fec0:0:0:2::/64, you can add it as well: + +@example +tincctl -n @var{netname} config add subnet fec0:0:0:2::/24 +@end example + +This will add another line to the file @file{hosts/@var{name}}. +If you make a mistake, you can undo it by simply using @samp{config del} instead of @samp{config add}. + +If you want other tinc daemons to create meta-connections to your daemon, +you should add your public IP address or hostname to your host configuration file. +For example, if your hostname is foo.example.org, run: + +@example +tincctl -n @var{netname} config add address foo.example.org +@end example + +If you already know to which daemons your daemon should make meta-connections, +you should configure that now as well. +Suppose you want to connect to a daemon named "bar", run: + +@example +tincctl -n @var{netname} config add connectto bar +@end example + +Note that you specify the Name of the other daemon here, not an IP address or hostname! +When you start tinc, and it tries to make a connection to "bar", +it will look for a host configuration file named @file{hosts/bar}, +and will read Address statements and public keys from that file. + +@subsubheading Step 2. Exchanging configuration files. + +If your daemon has a ConnectTo = bar statement in its @file{tinc.conf} file, +or if bar has a ConnectTo your daemon, then you both need each other's host configuration files. +You should send @file{hosts/@var{name}} to bar, and bar should send you his file which you should move to @file{hosts/bar}. +If you are on a UNIX platform, you can easily send an email containing the necessary information using the following command +(assuming the owner of bar has the email address bar@@example.org): + +@example +tincctl -n @var{netname} export | mail -s "My config file" bar@@example.org +@end example + +If the owner of bar does the same to send his host configuration file to you, +you can probably pipe his email through the following command, +or you can just start this command in a terminal and copy&paste the email: + +@example +tincctl -n @var{netname} import +@end example + +If you are the owner of bar yourself, and you have SSH access to that computer, +you can also swap the host configuration files using the following commands: + +@example +tincctl -n @var{netname} export | ssh bar.example.org tincctl -n @var{netname} import +ssh bar.example.org tincctl -n @var{netname} export | tincctl -n @var{netname} import +@end example + +You should repeat this for all nodes you ConnectTo, or which ConnectTo you. +However, remember that you do not need to ConnectTo all nodes in the VPN; +it is only necessary to create one or a few meta-connections, +after the connections are made tinc will learn about all the other nodes in the VPN, +and will automatically make other connections as necessary. @c ================================================================== @@ -1320,21 +1526,31 @@ You can configure the network interface by putting ordinary ifconfig, route, and to a script named @file{@value{sysconfdir}/tinc/@var{netname}/tinc-up}. When tinc starts, this script will be executed. When tinc exits, it will execute the script named @file{@value{sysconfdir}/tinc/@var{netname}/tinc-down}, but normally you don't need to create that script. +You can manually open the script in an editor, or use the following command: -An example @file{tinc-up} script: +@example +tincctl -n @var{netname} edit tinc-up +@end example + +An example @file{tinc-up} script, that would be appropriate for the scenario in the previous section, is: @example #!/bin/sh -ifconfig $INTERFACE 192.168.1.1 netmask 255.255.0.0 +ifconfig $INTERFACE 192.168.2.1 netmask 255.255.0.0 +ip addr add fec0:0:0:2::/48 dev $INTERFACE @end example -This script gives the interface an IP address and a netmask. -The kernel will also automatically add a route to this interface, so normally you don't need +The first command gives the interface an IPv4 address and a netmask. +The kernel will also automatically add an IPv4 route to this interface, so normally you don't need to add route commands to the @file{tinc-up} script. The kernel will also bring the interface up after this command. @cindex netmask The netmask is the mask of the @emph{entire} VPN network, not just your own subnet. +The second command gives the interface an IPv6 address and netmask, +which will also automatically add an IPv6 route. +If you only want to use "ip addr" commands on Linux, don't forget that it doesn't bring the interface up, unlike ifconfig, +so you need to add @samp{ip link set $INTERFACE up} in that case. The exact syntax of the ifconfig and route commands differs from platform to platform. You can look up the commands for setting addresses and adding routes in @ref{Platform specific information}, @@ -1374,6 +1590,9 @@ the real interface is also shown as a comment, to give you an idea of how these example host is set up. All branches use the netname `company' for this particular VPN. +Each branch is set up using the @samp{tincctl init} and @samp{tincctl config} commands, +here we just show the end results: + @subsubheading For Branch A @emph{BranchA} would be configured like this: @@ -1381,6 +1600,8 @@ for this particular VPN. In @file{@value{sysconfdir}/tinc/company/tinc-up}: @example +#!/bin/sh + # Real interface of internal network: # ifconfig eth0 10.1.54.1 netmask 255.255.0.0 @@ -1391,7 +1612,6 @@ and in @file{@value{sysconfdir}/tinc/company/tinc.conf}: @example Name = BranchA -Device = /dev/tap0 @end example On all hosts, @file{@value{sysconfdir}/tinc/company/hosts/BranchA} contains: @@ -1405,9 +1625,9 @@ Address = 1.2.3.4 -----END RSA PUBLIC KEY----- @end example -Note that the IP addresses of eth0 and tap0 are the same. +Note that the IP addresses of eth0 and the VPN interface 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 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 VPN interfaces the same IP address, since that will make things a lot easier to remember and set up. @@ -1416,6 +1636,8 @@ since that will make things a lot easier to remember and set up. In @file{@value{sysconfdir}/tinc/company/tinc-up}: @example +#!/bin/sh + # Real interface of internal network: # ifconfig eth0 10.2.43.8 netmask 255.255.0.0 @@ -1430,7 +1652,7 @@ 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 this node will +same as on the VPN interface. 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}: @@ -1450,6 +1672,8 @@ Address = 2.3.4.5 In @file{@value{sysconfdir}/tinc/company/tinc-up}: @example +#!/bin/sh + # Real interface of internal network: # ifconfig eth0 10.3.69.254 netmask 255.255.0.0 @@ -1461,7 +1685,6 @@ and in @file{@value{sysconfdir}/tinc/company/tinc.conf}: @example Name = BranchC ConnectTo = BranchA -Device = /dev/tap1 @end example C already has another daemon that runs on port 655, so they have to @@ -1486,6 +1709,8 @@ Port = 2000 In @file{@value{sysconfdir}/tinc/company/tinc-up}: @example +#!/bin/sh + # Real interface of internal network: # ifconfig eth0 10.4.3.32 netmask 255.255.0.0 @@ -1497,14 +1722,10 @@ and in @file{@value{sysconfdir}/tinc/company/tinc.conf}: @example Name = BranchD ConnectTo = BranchC -Device = /dev/net/tun @end example D will be connecting to C, which has a tincd running for this network on port 2000. It knows the port number from the host configuration file. -Also note that since D uses the tun/tap driver, the network interface -will not be called `tun' or `tap0' or something like that, but will -have the same name as netname. On all hosts, in @file{@value{sysconfdir}/tinc/company/hosts/BranchD}: @@ -1519,16 +1740,11 @@ Address = 4.5.6.7 @subsubheading Key files -A, B, C and D all have generated a public/private keypair with the following command: +A, B, C and D all have their own public/private keypairs: -@example -tincctl -n company generate-keys -@end example - -The private key is stored in @file{@value{sysconfdir}/tinc/company/rsa_key.priv}, -the public key is put into the host configuration file in the @file{@value{sysconfdir}/tinc/company/hosts/} directory. -During key generation, tinc automatically guesses the right filenames based on the -n option and -the Name directive in the @file{tinc.conf} file (if it is available). +The private RSA key is stored in @file{@value{sysconfdir}/tinc/company/rsa_key.priv}, +the private ECDSA key is stored in @file{@value{sysconfdir}/tinc/company/ecdsa_key.priv}, +and the public RSA and ECDSA keys are put into the host configuration file in the @file{@value{sysconfdir}/tinc/company/hosts/} directory. @subsubheading Starting @@ -1545,7 +1761,7 @@ their daemons, tinc will try connecting until they are available. If everything else is done, you can start tinc by typing the following command: @example -tincd -n @var{netname} +tincctl -n @var{netname} start @end example @cindex daemon @@ -1600,6 +1816,12 @@ Store a cookie in @var{filename} which allows tincctl to authenticate. If unspecified, the default is @file{@value{localstatedir}/run/tinc.@var{netname}.pid}. +@item -o, --option=[@var{HOST}.]@var{KEY}=@var{VALUE} +Without specifying a @var{HOST}, this will set server configuration variable @var{KEY} to @var{VALUE}. +If specified as @var{HOST}.@var{KEY}=@var{VALUE}, +this will set the host configuration variable @var{KEY} of the host named @var{HOST} to @var{VALUE}. +This option can be used more than once to specify multiple configuration variables. + @item -L, --mlock Lock tinc into main memory. This will prevent sensitive data like shared private keys to be written to the system swap files/partitions. @@ -1868,6 +2090,7 @@ tincctl -n @var{netname} reload @menu * tincctl runtime options:: +* tincctl environment variables:: * tincctl commands:: * tincctl examples:: * tincctl top:: @@ -1900,6 +2123,16 @@ Output version information and exit. @end table +@c ================================================================== +@node tincctl environment variables +@section tincctl environment variables + +@table @env +@cindex NETNAME +@item NETNAME +If no netname is specified on the command line with the @option{-n} option, +the value of this environment variable is used. +@end table @c ================================================================== @node tincctl commands @@ -1908,8 +2141,43 @@ Output version information and exit. @c from the manpage @table @code -@item start -Start @samp{tincd}. +@item init [@var{name}] +Create initial configuration files and RSA and ECDSA keypairs with default length. +If no @var{name} for this node is given, it will be asked for. + +@item config [get] @var{variable} +Print the current value of configuration variable @var{variable}. +If more than one variable with the same name exists, +the value of each of them will be printed on a separate line. + +@item config [set] @var{variable} @var{value} +Set configuration variable @var{variable} to the given @var{value}. +All previously existing configuration variables with the same name are removed. +To set a variable for a specific host, use the notation @var{host}.@var{variable}. + +@item config add @var{variable} @var{value} +As above, but without removing any previously existing configuration variables. + +@item config del @var{variable} [@var{value}] +Remove configuration variables with the same name and @var{value}. +If no @var{value} is given, all configuration variables with the same name will be removed. + +@item edit @var{filename} +Start an editor for the given configuration file. +You do not need to specify the full path to the file. + +@item export +Export the host configuration file of the local node to standard output. + +@item export-all +Export all host configuration files to standard output. + +@item import [--force] +Import host configuration file(s) from standard input. +Already existing host configuration files are not overwritten unless the option --force is used. + +@item start [tincd options] +Start @samp{tincd}, optionally with the given extra options. @item stop Stop @samp{tincd}. @@ -1943,8 +2211,15 @@ Dump a list of all known subnets in the VPN. @item dump connections Dump a list of all meta connections with ourself. -@item dump graph +@item dump graph | digraph Dump a graph of the VPN in dotty format. +Nodes are colored according to their reachability: +red nodes are unreachable, orange nodes are indirectly reachable, green nodes are directly reachable. +Black nodes are either directly or indirectly reachable, but direct reachability has not been tried yet. + +@item info @var{node} | @var{subnet} | @var{address} +Show information about a particular @var{node}, @var{subnet} or @var{address}. +If an @var{address} is given, any matching subnet will be shown. @item purge Purges all information remembered about unreachable nodes. @@ -1952,6 +2227,10 @@ Purges all information remembered about unreachable nodes. @item debug @var{level} Sets debug level to @var{level}. +@item log [@var{level}] +Capture log messages from a running tinc daemon. +An optional debug level can be given that will be applied only for log messages sent to tincctl. + @item retry Forces tinc to try to connect to all uplinks immediately. Usually tinc attempts to do this itself, @@ -1986,6 +2265,16 @@ tincctl -n vpn pcap | tcpdump -r - tincctl -n vpn top @end example +Example of configuring tinc using tincctl: + +@example +tincctl -n vpn init foo +tincctl -n vpn config Subnet 192.168.1.0/24 +tincctl -n vpn config bar.Address bar.example.com +tincctl -n vpn config ConnectTo bar +tincctl -n vpn export | gpg --clearsign | mail -s "My config" vpnmaster@@example.com +@end example + @c ================================================================== @node tincctl top @section tincctl top @@ -2531,7 +2820,6 @@ For IPv4 addresses: @tab @code{netsh interface ip set address} @var{interface} @code{static} @var{address} @var{netmask} @end multitable - For IPv6 addresses: @multitable {Darwin (MacOS/X)} {ifconfig route add -bla network address netmask netmask prefixlength interface} @@ -2553,6 +2841,22 @@ For IPv6 addresses: @tab @code{netsh interface ipv6 add address} @var{interface} @code{static} @var{address}/@var{prefixlength} @end multitable +On some platforms, when running tinc in switch mode, the VPN interface must be set to tap mode with an ifconfig command: + +@multitable {Darwin (MacOS/X)} {ifconfig route add -bla network address netmask netmask prefixlength interface} +@item OpenBSD +@tab @code{ifconfig} @var{interface} @code{link0} +@end multitable + +On Linux, it is possible to create a persistent tun/tap interface which will +continue to exist even if tinc quit, although this is normally not required. +It can be useful to set up a tun/tap interface owned by a non-root user, so +tinc can be started without needing any root privileges at all. + +@multitable {Darwin (MacOS/X)} {ifconfig route add -bla network address netmask netmask prefixlength interface} +@item Linux +@tab @code{ip tuntap add dev} @var{interface} @code{mode} @var{tun|tap} @code{user} @var{username} +@end multitable @c ================================================================== @node Routes diff --git a/doc/tincctl.8.in b/doc/tincctl.8.in index bbc8dba..3834323 100644 --- a/doc/tincctl.8.in +++ b/doc/tincctl.8.in @@ -1,4 +1,4 @@ -.Dd 2011-06-25 +.Dd 2012-10-14 .Dt TINCCTL 8 .\" Manual page created by: .\" Scott Lamb @@ -37,12 +37,58 @@ Display short list of options. .It Fl -version Output version information and exit. .El +.Sh ENVIRONMENT VARIABLES +.Bl -tag -width indent +.It Ev NETNAME +If no netname is specified on the command line with the +.Fl n +option, the value of this environment variable is used. +.El .Sh COMMANDS .zZ .Bl -tag -width indent -.It start +.It init Op Ar name +Create initial configuration files and RSA and ECDSA keypairs with default length. +If no +.Ar name +for this node is given, it will be asked for. +.It config Oo get Oc Ar variable +Print the current value of configuration variable +.Ar variable . +If more than one variable with the same name exists, +the value of each of them will be printed on a separate line. +.It config Oo set Oc Ar variable Ar value +Set configuration variable +.Ar variable +to the given +.Ar value . +All previously existing configuration variables with the same name are removed. +To set a variable for a specific host, use the notation +.Ar host Ns Li . Ns Ar variable . +.It config add Ar variable Ar value +As above, but without removing any previously existing configuration variables. +.It config del Ar variable Op Ar value +Remove configuration variables with the same name and +.Ar value . +If no +.Ar value +is given, all configuration variables with the same name will be removed. +.It edit Ar filename +Start an editor for the given configuration file. +You do not need to specify the full path to the file. +.It export +Export the host configuration file of the local node to standard output. +.It export-all +Export all host configuration files to standard output. +.It import Op Fl -force +Import host configuration file(s) from standard input. +Already existing host configuration files are not overwritten unless the option +.Fl -force +is used. +.It start Op tincd options Start -.Xr tincd 8 . +.Xr tincd 8 , +optionally with the given extra options. .It stop Stop .Xr tincd 8 . @@ -69,6 +115,7 @@ If is omitted, the default length will be 2048 bits. When saving keys to existing files, tinc will not delete the old keys; you have to remove them manually. + .It dump nodes Dump a list of all known nodes in the VPN. .It dump edges @@ -77,15 +124,25 @@ Dump a list of all known connections in the VPN. Dump a list of all known subnets in the VPN. .It dump connections Dump a list of all meta connections with ourself. -.It dump graph +.It dump graph | digraph Dump a graph of the VPN in .Xr dotty 1 format. +Nodes are colored according to their reachability: +red nodes are unreachable, orange nodes are indirectly reachable, green nodes are directly reachable. +Black nodes are either directly or indirectly reachable, but direct reachability has not been tried yet. +.It info Ar node | subnet | address +Show information about a particular node, subnet or address. +If an address is given, any matching subnet will be shown. .It purge Purges all information remembered about unreachable nodes. .It debug Ar N Sets debug level to .Ar N . +.It log Op Ar N +Capture log messages from a running tinc daemon. +An optional debug level can be given that will be applied only for log messages sent to +.Nm tincctl . .It retry Forces .Xr tincd 8 @@ -123,7 +180,16 @@ Examples of some commands: tincctl -n vpn dump graph | circo -Txlib tincctl -n vpn pcap | tcpdump -r - tincctl -n vpn top +.Pp .Ed +Example of configuring tinc using +.Nm : +.Bd -literal -offset indent +tincctl -n vpn init foo +tincctl -n vpn config Subnet 192.168.1.0/24 +tincctl -n vpn config bar.Address bar.example.com +tincctl -n vpn config ConnectTo bar +tincctl -n vpn export | gpg --clearsign | mail -s "My config" vpnmaster@example.com .Sh TOP The top command connects to a running tinc daemon and repeatedly queries its per-node traffic counters. It displays a list of all the known nodes in the left-most column, @@ -172,7 +238,7 @@ If you find any bugs, report them to tinc@tinc-vpn.org. .Xr tincd 8 , .Xr tinc.conf 5 , .Xr dotty 1 , -.Xr pcap-savefile 7 , +.Xr pcap-savefile 5 , .Xr tcpdump 8 , .Xr top 1 , .Pa http://www.tinc-vpn.org/ , diff --git a/doc/tincd.8.in b/doc/tincd.8.in index bb4aa48..9468120 100644 --- a/doc/tincd.8.in +++ b/doc/tincd.8.in @@ -1,4 +1,4 @@ -.Dd 2011-06-25 +.Dd 2012-02-22 .Dt TINCD 8 .\" Manual page created by: .\" Ivo Timmermans @@ -8,11 +8,12 @@ .Nd tinc VPN daemon .Sh SYNOPSIS .Nm -.Op Fl cdDKnLRU +.Op Fl cdDKnoLRU .Op Fl -config Ns = Ns Ar DIR .Op Fl -no-detach .Op Fl -debug Ns Op = Ns Ar LEVEL .Op Fl -net Ns = Ns Ar NETNAME +.Op Fl -option Ns = Ns Ar [HOST.]KEY=VALUE .Op Fl -mlock .Op Fl -logfile Ns Op = Ns Ar FILE .Op Fl -bypass-security @@ -61,6 +62,22 @@ for .Ar NETNAME is the same as not specifying any .Ar NETNAME . +.It Fl o, -option Ns = Ns Ar [HOST.]KEY=VALUE +Without specifying a +.Ar HOST , +this will set server configuration variable +.Ar KEY +to +.Ar VALUE . +If specified as +.Ar HOST.KEY=VALUE , +this will set the host configuration variable +.Ar KEY +of the host named +.Ar HOST +to +.Ar VALUE . +This option can be used more than once to specify multiple configuration variables. .It Fl L, -mlock Lock tinc into main memory. This will prevent sensitive data like shared private keys to be written to the system swap files/partitions. diff --git a/gui/Makefile.in b/gui/Makefile.in index 632fd78..2d08ef7 100644 --- a/gui/Makefile.in +++ b/gui/Makefile.in @@ -1,9 +1,9 @@ -# Makefile.in generated by automake 1.11.1 from Makefile.am. +# Makefile.in generated by automake 1.11.6 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, -# Inc. +# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software +# Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -16,6 +16,23 @@ @SET_MAKE@ VPATH = @srcdir@ +am__make_dryrun = \ + { \ + am__dry=no; \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ + | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ + *) \ + for am__flg in $$MAKEFLAGS; do \ + case $$am__flg in \ + *=*|--*) ;; \ + *n*) am__dry=yes; break;; \ + esac; \ + done;; \ + esac; \ + test $$am__dry = yes; \ + } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ @@ -41,7 +58,8 @@ ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \ $(top_srcdir)/m4/curses.m4 $(top_srcdir)/m4/libevent.m4 \ $(top_srcdir)/m4/lzo.m4 $(top_srcdir)/m4/openssl.m4 \ - $(top_srcdir)/m4/zlib.m4 $(top_srcdir)/configure.in + $(top_srcdir)/m4/readline.m4 $(top_srcdir)/m4/zlib.m4 \ + $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d @@ -69,10 +87,21 @@ am__nobase_list = $(am__nobase_strip_setup); \ am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } am__installdirs = "$(DESTDIR)$(bindir)" SCRIPTS = $(dist_bin_SCRIPTS) SOURCES = DIST_SOURCES = +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ @@ -122,6 +151,7 @@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ +READLINE_LIBS = @READLINE_LIBS@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ @@ -213,8 +243,11 @@ $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) $(am__aclocal_m4_deps): install-dist_binSCRIPTS: $(dist_bin_SCRIPTS) @$(NORMAL_INSTALL) - test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)" @list='$(dist_bin_SCRIPTS)'; test -n "$(bindir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ + fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ if test -f "$$d$$p"; then echo "$$d$$p"; echo "$$p"; else :; fi; \ @@ -242,9 +275,7 @@ uninstall-dist_binSCRIPTS: @list='$(dist_bin_SCRIPTS)'; test -n "$(bindir)" || exit 0; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 's,.*/,,;$(transform)'`; \ - test -n "$$list" || exit 0; \ - echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ - cd "$(DESTDIR)$(bindir)" && rm -f $$files + dir='$(DESTDIR)$(bindir)'; $(am__uninstall_files_from_dir) tags: TAGS TAGS: @@ -299,10 +330,15 @@ install-am: all-am installcheck: installcheck-am install-strip: - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - `test -z '$(STRIP)' || \ - echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi mostlyclean-generic: clean-generic: diff --git a/gui/tinc-gui b/gui/tinc-gui index c0f1cb1..9c6485f 100755 --- a/gui/tinc-gui +++ b/gui/tinc-gui @@ -1,12 +1,35 @@ #!/usr/bin/python +# tinc-gui -- GUI for controlling a running tincd +# Copyright (C) 2009-2012 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 +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + import string import socket import wx import sys +import os +import platform +import time from wx.lib.mixins.listctrl import ColumnSorterMixin from wx.lib.mixins.listctrl import ListCtrlAutoWidthMixin +if platform.system == 'Windows': + import _winreg + # Classes to interface with a running tinc daemon REQ_STOP = 0 @@ -30,34 +53,32 @@ CONTROL = 18 class Node: def parse(self, args): self.name = args[0] - self.address = args[2] - if args[3] != 'port': - args.insert(3, 'port') - args.insert(4, '') - self.port = args[4] - self.cipher = int(args[6]) - self.digest = int(args[8]) - self.maclength = int(args[10]) - self.compression = int(args[12]) - self.options = int(args[14], 0x10) - self.status = int(args[16], 0x10) - self.nexthop = args[18] - self.via = args[20] - self.distance = int(args[22]) - self.pmtu = int(args[24]) - self.minmtu = int(args[26]) - self.maxmtu = int(args[28][:-1]) + self.address = args[1] + self.port = args[3] + self.cipher = int(args[4]) + self.digest = int(args[5]) + self.maclength = int(args[6]) + self.compression = int(args[7]) + self.options = int(args[8], 0x10) + self.status = int(args[9], 0x10) + self.nexthop = args[10] + self.via = args[11] + self.distance = int(args[12]) + self.pmtu = int(args[13]) + self.minmtu = int(args[14]) + self.maxmtu = int(args[15]) + self.last_state_change = float(args[16]) self.subnets = {} class Edge: def parse(self, args): self.fr = args[0] - self.to = args[2] - self.address = args[4] - self.port = args[6] - self.options = int(args[8], 16) - self.weight = int(args[10]) + self.to = args[1] + self.address = args[2] + self.port = args[4] + self.options = int(args[5], 16) + self.weight = int(args[6]) class Subnet: def parse(self, args): @@ -73,19 +94,16 @@ class Subnet: self.address = address self.prefixlen = '48' - self.owner = args[2] + self.owner = args[1] class Connection: def parse(self, args): self.name = args[0] - self.address = args[2] - if args[3] != 'port': - args.insert(3, 'port') - args.insert(4, '') - self.port = args[4] - self.options = int(args[6], 0x10) - self.socket = int(args[8]) - self.status = int(args[10], 0x10) + self.address = args[1] + self.port = args[3] + self.options = int(args[4], 0x10) + self.socket = int(args[5]) + self.status = int(args[6], 0x10) self.weight = 123 class VPN: @@ -132,34 +150,34 @@ class VPN: if resp[0] != '18': break if resp[1] == '3': - if len(resp) < 3: + if len(resp) < 19: continue node = self.nodes.get(resp[2]) or Node() node.parse(resp[2:]) node.visited = True self.nodes[resp[2]] = node elif resp[1] == '4': - if len(resp) < 5: + if len(resp) < 9: continue - edge = self.nodes.get((resp[2], resp[4])) or Edge() + edge = self.nodes.get((resp[2], resp[3])) or Edge() edge.parse(resp[2:]) edge.visited = True - self.edges[(resp[2], resp[4])] = edge + self.edges[(resp[2], resp[3])] = edge elif resp[1] == '5': - if len(resp) < 5: + if len(resp) < 4: continue - subnet = self.subnets.get((resp[2], resp[4])) or Subnet() + subnet = self.subnets.get((resp[2], resp[3])) or Subnet() subnet.parse(resp[2:]) subnet.visited = True - self.subnets[(resp[2], resp[4])] = subnet + self.subnets[(resp[2], resp[3])] = subnet self.nodes[subnet.owner].subnets[resp[2]] = subnet elif resp[1] == '6': - if len(resp) < 5: + if len(resp) < 9: break - connection = self.connections.get((resp[2], resp[4])) or Connection() + connection = self.connections.get((resp[2], resp[3], resp[5])) or Connection() connection.parse(resp[2:]) connection.visited = True - self.connections[(resp[2], resp[4])] = connection + self.connections[(resp[2], resp[3], resp[5])] = connection else: break @@ -198,27 +216,38 @@ class VPN: return int(resp[2]) def __init__(self, netname = None, pidfile = None): - self.tincconf = VPN.confdir + '/' + if platform.system == 'Windows': + try: + reg = _winreg.ConnectRegistry(None, HKEY_LOCAL_MACHINE) + key = _winreg.OpenKey(reg, "SOFTWARE\\tinc") + VPN.confdir = _winreg.QueryValue(key, None) + except WindowsError: + pass if netname: self.netname = netname - self.tincconf += netname + '/' + self.confbase = os.path.join(VPN.confdir, netname) + else: + self.confbase = VPN.confdir - self.tincconf += 'tinc.conf' + self.tincconf = os.path.join(self.confbase, 'tinc.conf') - if pidfile is not None: + if pidfile != None: self.pidfile = pidfile else: - self.pidfile = VPN.piddir + 'tinc.' - if netname: - self.pidfile += netname + '.' - self.pidfile += 'pid' + if platform.system == 'Windows': + self.pidfile = os.path.join(self.confbase, 'pid') + else: + if netname: + self.pidfile = os.path.join(VPN.piddir, 'tinc.' + netname + '.pid') + else: + self.pidfile = os.path.join(VPN.piddir, 'tinc.pid') # GUI starts here argv0 = sys.argv[0] del sys.argv[0] -net = None +netname = None pidfile = None def usage(exitcode = 0): @@ -230,10 +259,10 @@ def usage(exitcode = 0): print('\nReport bugs to tinc@tinc-vpn.org.') sys.exit(exitcode) -while len(sys.argv): +while sys.argv: if sys.argv[0] in ('-n', '--net'): del sys.argv[0] - net = sys.argv[0] + netname = sys.argv[0] elif sys.argv[0] in ('--pidfile'): del sys.argv[0] pidfile = sys.argv[0] @@ -245,14 +274,20 @@ while len(sys.argv): del sys.argv[0] -vpn = VPN(net, pidfile) +if netname == None: + netname = os.getenv("NETNAME") + +if netname == ".": + netname = None + +vpn = VPN(netname, pidfile) vpn.connect() class SuperListCtrl(wx.ListCtrl, ColumnSorterMixin, ListCtrlAutoWidthMixin): def __init__(self, parent, style): wx.ListCtrl.__init__(self, parent, -1, style=wx.LC_REPORT | wx.LC_HRULES | wx.LC_VRULES) ListCtrlAutoWidthMixin.__init__(self) - ColumnSorterMixin.__init__(self, 14) + ColumnSorterMixin.__init__(self, 16) def GetListCtrl(self): return self @@ -265,12 +300,12 @@ class SettingsPage(wx.Panel): def __init__(self, parent, id): wx.Panel.__init__(self, parent, id) grid = wx.FlexGridSizer(cols = 2) - grid.AddGrowableCol(0, 1) + grid.AddGrowableCol(1, 1) namelabel = wx.StaticText(self, -1, 'Name:') self.name = wx.TextCtrl(self, -1, vpn.name) grid.Add(namelabel) - grid.Add(self.name) + grid.Add(self.name, 1, wx.EXPAND) portlabel = wx.StaticText(self, -1, 'Port:') self.port = wx.TextCtrl(self, -1, vpn.port) @@ -293,7 +328,7 @@ class SettingsPage(wx.Panel): class ConnectionsPage(wx.Panel): def __init__(self, parent, id): wx.Panel.__init__(self, parent, id) - self.list = wx.ListCtrl(self, id, style=wx.LC_REPORT | wx.LC_HRULES | wx.LC_VRULES) + self.list = SuperListCtrl(self, id) self.list.InsertColumn(0, 'Name') self.list.InsertColumn(1, 'Address') self.list.InsertColumn(2, 'Port') @@ -323,6 +358,7 @@ class ConnectionsPage(wx.Panel): self.PopupMenu(self.ContextMenu(self.list.itemDataMap[event.GetIndex()]), event.GetPosition()) def refresh(self): + sortstate = self.list.GetSortState() self.list.itemDataMap = {} i = 0 @@ -337,11 +373,13 @@ class ConnectionsPage(wx.Panel): self.list.SetStringItem(i, 4, str(connection.weight)) self.list.itemDataMap[i] = (connection.name, connection.address, connection.port, connection.options, connection.weight) self.list.Bind(wx.EVT_LIST_ITEM_RIGHT_CLICK, self.OnContext) + self.list.SetItemData(i, i) i += 1 while self.list.GetItemCount() > i: self.list.DeleteItem(self.list.GetItemCount() - 1) + self.list.SortListItems(sortstate[0], sortstate[1]) class NodesPage(wx.Panel): def __init__(self, parent, id): @@ -362,6 +400,7 @@ class NodesPage(wx.Panel): self.list.InsertColumn(12, 'PMTU') self.list.InsertColumn(13, 'Min MTU') self.list.InsertColumn(14, 'Max MTU') + self.list.InsertColumn(15, 'Since') hbox = wx.BoxSizer(wx.HORIZONTAL) hbox.Add(self.list, 1, wx.EXPAND) @@ -369,6 +408,7 @@ class NodesPage(wx.Panel): self.refresh() def refresh(self): + sortstate = self.list.GetSortState() self.list.itemDataMap = {} i = 0 @@ -383,25 +423,32 @@ class NodesPage(wx.Panel): self.list.SetStringItem(i, 4, str(node.digest)) self.list.SetStringItem(i, 5, str(node.maclength)) self.list.SetStringItem(i, 6, str(node.compression)) - self.list.SetStringItem(i, 7, str(node.options)) - self.list.SetStringItem(i, 8, str(node.status)) + self.list.SetStringItem(i, 7, format(node.options, "x")) + self.list.SetStringItem(i, 8, format(node.status, "04x")) self.list.SetStringItem(i, 9, node.nexthop) self.list.SetStringItem(i, 10, node.via) self.list.SetStringItem(i, 11, str(node.distance)) self.list.SetStringItem(i, 12, str(node.pmtu)) self.list.SetStringItem(i, 13, str(node.minmtu)) self.list.SetStringItem(i, 14, str(node.maxmtu)) - self.list.itemDataMap[i] = (node.name, node.address, node.port, node.cipher, node.digest, node.maclength, node.compression, node.options, node.status, node.nexthop, node.via, node.distance, node.pmtu, node.minmtu, node.maxmtu) + if node.last_state_change: + since = time.strftime("%Y-%m-%d %H:%M", time.localtime(node.last_state_change)) + else: + since = "never" + self.list.SetStringItem(i, 15, since) + self.list.itemDataMap[i] = (node.name, node.address, node.port, node.cipher, node.digest, node.maclength, node.compression, node.options, node.status, node.nexthop, node.via, node.distance, node.pmtu, node.minmtu, node.maxmtu, since) self.list.SetItemData(i, i) i += 1 while self.list.GetItemCount() > i: self.list.DeleteItem(self.list.GetItemCount() - 1) + self.list.SortListItems(sortstate[0], sortstate[1]) + class EdgesPage(wx.Panel): def __init__(self, parent, id): wx.Panel.__init__(self, parent, id) - self.list = wx.ListCtrl(self, id, style=wx.LC_REPORT | wx.LC_HRULES | wx.LC_VRULES) + self.list = SuperListCtrl(self, id) self.list.InsertColumn(0, 'From') self.list.InsertColumn(1, 'To') self.list.InsertColumn(2, 'Address') @@ -415,6 +462,7 @@ class EdgesPage(wx.Panel): self.refresh() def refresh(self): + sortstate = self.list.GetSortState() self.list.itemDataMap = {} i = 0 @@ -426,14 +474,17 @@ class EdgesPage(wx.Panel): self.list.SetStringItem(i, 1, edge.to) self.list.SetStringItem(i, 2, edge.address) self.list.SetStringItem(i, 3, edge.port) - self.list.SetStringItem(i, 4, str(edge.options)) + self.list.SetStringItem(i, 4, format(edge.options, "x")) self.list.SetStringItem(i, 5, str(edge.weight)) self.list.itemDataMap[i] = (edge.fr, edge.to, edge.address, edge.port, edge.options, edge.weight) + self.list.SetItemData(i, i) i += 1 while self.list.GetItemCount() > i: self.list.DeleteItem(self.list.GetItemCount() - 1) + self.list.SortListItems(sortstate[0], sortstate[1]) + class SubnetsPage(wx.Panel): def __init__(self, parent, id): wx.Panel.__init__(self, parent, id) @@ -447,6 +498,7 @@ class SubnetsPage(wx.Panel): self.refresh() def refresh(self): + sortstate = self.list.GetSortState() self.list.itemDataMap = {} i = 0 @@ -458,11 +510,14 @@ class SubnetsPage(wx.Panel): self.list.SetStringItem(i, 1, subnet.weight) self.list.SetStringItem(i, 2, subnet.owner) self.list.itemDataMap[i] = (subnet.address + '/' + subnet.prefixlen, subnet.weight, subnet.owner) - i = i + 1 + self.list.SetItemData(i, i) + i += 1 while self.list.GetItemCount() > i: self.list.DeleteItem(self.list.GetItemCount() - 1) + self.list.SortListItems(sortstate[0], sortstate[1]) + class StatusPage(wx.Panel): def __init__(self, parent, id): wx.Panel.__init__(self, parent, id) @@ -493,7 +548,7 @@ class NetPage(wx.Notebook): class MainWindow(wx.Frame): def OnQuit(self, event): - self.Close(True) + app.ExitMainLoop() def OnTimer(self, event): vpn.refresh() diff --git a/have.h b/have.h index 0ab8134..d040717 100644 --- a/have.h +++ b/have.h @@ -1,7 +1,7 @@ /* have.h -- include headers which are known to exist Copyright (C) 1998-2005 Ivo Timmermans - 2003-2011 Guus Sliepen + 2003-2012 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 @@ -42,6 +42,7 @@ #ifdef HAVE_MINGW #include +#include #include #include #endif @@ -199,4 +200,10 @@ #include #endif +#ifdef HAVE_MINGW +#define SLASH "\\" +#else +#define SLASH "/" +#endif + #endif /* __TINC_SYSTEM_H__ */ diff --git a/install-sh b/install-sh index 6781b98..a9244eb 100755 --- a/install-sh +++ b/install-sh @@ -1,7 +1,7 @@ #!/bin/sh # install - install a program, script, or datafile -scriptversion=2009-04-28.21; # UTC +scriptversion=2011-01-19.21; # UTC # This originates from X11R5 (mit/util/scripts/install.sh), which was # later released in X11R6 (xc/config/util/install.sh) with the @@ -156,6 +156,10 @@ while test $# -ne 0; do -s) stripcmd=$stripprog;; -t) dst_arg=$2 + # Protect names problematic for `test' and other utilities. + case $dst_arg in + -* | [=\(\)!]) dst_arg=./$dst_arg;; + esac shift;; -T) no_target_directory=true;; @@ -186,6 +190,10 @@ if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then fi shift # arg dst_arg=$arg + # Protect names problematic for `test' and other utilities. + case $dst_arg in + -* | [=\(\)!]) dst_arg=./$dst_arg;; + esac done fi @@ -200,7 +208,11 @@ if test $# -eq 0; then fi if test -z "$dir_arg"; then - trap '(exit $?); exit' 1 2 13 15 + do_exit='(exit $ret); exit $ret' + trap "ret=129; $do_exit" 1 + trap "ret=130; $do_exit" 2 + trap "ret=141; $do_exit" 13 + trap "ret=143; $do_exit" 15 # Set umask so as not to create temps with too-generous modes. # However, 'strip' requires both read and write access to temps. @@ -228,9 +240,9 @@ fi for src do - # Protect names starting with `-'. + # Protect names problematic for `test' and other utilities. case $src in - -*) src=./$src;; + -* | [=\(\)!]) src=./$src;; esac if test -n "$dir_arg"; then @@ -252,12 +264,7 @@ do echo "$0: no destination specified." >&2 exit 1 fi - dst=$dst_arg - # Protect names starting with `-'. - case $dst in - -*) dst=./$dst;; - esac # If destination is a directory, append the input filename; won't work # if double slashes aren't ignored. @@ -385,7 +392,7 @@ do case $dstdir in /*) prefix='/';; - -*) prefix='./';; + [-=\(\)!]*) prefix='./';; *) prefix='';; esac @@ -403,7 +410,7 @@ do for d do - test -z "$d" && continue + test X"$d" = X && continue prefix=$prefix$d if test -d "$prefix"; then diff --git a/m4/Makefile.in b/m4/Makefile.in index 17af65a..8f1372a 100644 --- a/m4/Makefile.in +++ b/m4/Makefile.in @@ -1,9 +1,9 @@ -# Makefile.in generated by automake 1.11.1 from Makefile.am. +# Makefile.in generated by automake 1.11.6 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, -# Inc. +# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software +# Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -15,6 +15,23 @@ @SET_MAKE@ VPATH = @srcdir@ +am__make_dryrun = \ + { \ + am__dry=no; \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ + | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ + *) \ + for am__flg in $$MAKEFLAGS; do \ + case $$am__flg in \ + *=*|--*) ;; \ + *n*) am__dry=yes; break;; \ + esac; \ + done;; \ + esac; \ + test $$am__dry = yes; \ + } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ @@ -39,7 +56,8 @@ ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \ $(top_srcdir)/m4/curses.m4 $(top_srcdir)/m4/libevent.m4 \ $(top_srcdir)/m4/lzo.m4 $(top_srcdir)/m4/openssl.m4 \ - $(top_srcdir)/m4/zlib.m4 $(top_srcdir)/configure.in + $(top_srcdir)/m4/readline.m4 $(top_srcdir)/m4/zlib.m4 \ + $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d @@ -48,6 +66,11 @@ CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = SOURCES = DIST_SOURCES = +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ @@ -97,6 +120,7 @@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ +READLINE_LIBS = @READLINE_LIBS@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ @@ -236,10 +260,15 @@ install-am: all-am installcheck: installcheck-am install-strip: - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - `test -z '$(STRIP)' || \ - echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi mostlyclean-generic: clean-generic: diff --git a/m4/openssl.m4 b/m4/openssl.m4 index 254ea4f..922e468 100644 --- a/m4/openssl.m4 +++ b/m4/openssl.m4 @@ -35,7 +35,7 @@ AC_DEFUN([tinc_OPENSSL], LDFLAGS="$LDFLAGS -L$withval"] ) - AC_CHECK_HEADERS(openssl/evp.h openssl/rsa.h openssl/rand.h openssl/err.h openssl/sha.h openssl/pem.h openssl/engine.h, + AC_CHECK_HEADERS([openssl/evp.h openssl/rsa.h openssl/rand.h openssl/err.h openssl/sha.h openssl/pem.h openssl/engine.h openssl/ecdh.h openssl/ec.h], [], [AC_MSG_ERROR([OpenSSL header files not found.]); break] ) @@ -45,7 +45,7 @@ AC_DEFUN([tinc_OPENSSL], [AC_MSG_ERROR([OpenSSL libraries not found.])] ) - AC_CHECK_FUNCS([RAND_pseudo_bytes EVP_EncryptInit_ex], , + AC_CHECK_FUNCS([RAND_pseudo_bytes EVP_EncryptInit_ex ECDH_compute_key ECDSA_verify], , [AC_MSG_ERROR([Missing OpenSSL functionality, make sure you have installed the latest version.]); break], ) diff --git a/m4/readline.m4 b/m4/readline.m4 new file mode 100644 index 0000000..f29e692 --- /dev/null +++ b/m4/readline.m4 @@ -0,0 +1,42 @@ +dnl Check to find the readline headers/libraries + +AC_DEFUN([tinc_READLINE], +[ + AC_ARG_ENABLE([readline], + AS_HELP_STRING([--disable-readline], [disable readline support])) + AS_IF([test "x$enable_readline" != "xno"], [ + AC_DEFINE(HAVE_READLINE, 1, [have readline support]) + readline=true + AC_ARG_WITH(readline, + AS_HELP_STRING([--with-readline=DIR], [readline base directory, or:]), + [readline="$withval" + CPPFLAGS="$CPPFLAGS -I$withval/include" + LDFLAGS="$LDFLAGS -L$withval/lib"] + ) + + AC_ARG_WITH(readline-include, + AS_HELP_STRING([--with-readline-include=DIR], [readline headers directory]), + [readline_include="$withval" + CPPFLAGS="$CPPFLAGS -I$withval"] + ) + + AC_ARG_WITH(readline-lib, + AS_HELP_STRING([--with-readline-lib=DIR], [readline library directory]), + [readline_lib="$withval" + LDFLAGS="$LDFLAGS -L$withval"] + ) + + AC_CHECK_HEADERS([readline/readline.h readline/history.h], + [], + [AC_MSG_ERROR("readline header files not found."); break] + ) + + AC_CHECK_LIB(readline, readline, + [READLINE_LIBS="-lreadline"], + [AC_MSG_ERROR("readline library not found.")], + [$CURSES_LIBS] + ) + ]) + + AC_SUBST(READLINE_LIBS) +]) diff --git a/missing b/missing index 28055d2..86a8fc3 100755 --- a/missing +++ b/missing @@ -1,10 +1,10 @@ #! /bin/sh # Common stub for a few missing GNU programs while installing. -scriptversion=2009-04-28.21; # UTC +scriptversion=2012-01-06.13; # UTC # Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006, -# 2008, 2009 Free Software Foundation, Inc. +# 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc. # Originally by Fran,cois Pinard , 1996. # This program is free software; you can redistribute it and/or modify @@ -84,7 +84,6 @@ Supported PROGRAM values: help2man touch the output file lex create \`lex.yy.c', if possible, from existing .c makeinfo touch the output file - tar try tar, gnutar, gtar, then tar without non-portable flags yacc create \`y.tab.[ch]', if possible, from existing .[ch] Version suffixes to PROGRAM as well as the prefixes \`gnu-', \`gnu', and @@ -122,15 +121,6 @@ case $1 in # Not GNU programs, they don't have --version. ;; - tar*) - if test -n "$run"; then - echo 1>&2 "ERROR: \`tar' requires --run" - exit 1 - elif test "x$2" = "x--version" || test "x$2" = "x--help"; then - exit 1 - fi - ;; - *) if test -z "$run" && ($1 --version) > /dev/null 2>&1; then # We have it, but it failed. @@ -226,7 +216,7 @@ WARNING: \`$1' $msg. You should only need it if \`Bison' from any GNU archive site." rm -f y.tab.c y.tab.h if test $# -ne 1; then - eval LASTARG="\${$#}" + eval LASTARG=\${$#} case $LASTARG in *.y) SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` @@ -256,7 +246,7 @@ WARNING: \`$1' is $msg. You should only need it if \`Flex' from any GNU archive site." rm -f lex.yy.c if test $# -ne 1; then - eval LASTARG="\${$#}" + eval LASTARG=\${$#} case $LASTARG in *.l) SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` @@ -318,41 +308,6 @@ WARNING: \`$1' is $msg. You should only need it if touch $file ;; - tar*) - shift - - # We have already tried tar in the generic part. - # Look for gnutar/gtar before invocation to avoid ugly error - # messages. - if (gnutar --version > /dev/null 2>&1); then - gnutar "$@" && exit 0 - fi - if (gtar --version > /dev/null 2>&1); then - gtar "$@" && exit 0 - fi - firstarg="$1" - if shift; then - case $firstarg in - *o*) - firstarg=`echo "$firstarg" | sed s/o//` - tar "$firstarg" "$@" && exit 0 - ;; - esac - case $firstarg in - *h*) - firstarg=`echo "$firstarg" | sed s/h//` - tar "$firstarg" "$@" && exit 0 - ;; - esac - fi - - echo 1>&2 "\ -WARNING: I can't seem to be able to run \`tar' with the given arguments. - You may want to install GNU tar or Free paxutils, or check the - command line arguments." - exit 1 - ;; - *) echo 1>&2 "\ WARNING: \`$1' is needed, and is $msg. diff --git a/src/Makefile.am b/src/Makefile.am index 186c042..3bd8646 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,30 +1,43 @@ ## Produce this file with automake to get Makefile.in -sbin_PROGRAMS = tincd tincctl +sbin_PROGRAMS = tincd tincctl sptps_test -EXTRA_DIST = linux bsd solaris cygwin mingw raw_socket uml_socket openssl gcrypt +EXTRA_DIST = linux bsd solaris cygwin mingw openssl gcrypt tincd_SOURCES = \ - utils.c getopt.c getopt1.c list.c splay_tree.c dropin.c fake-getaddrinfo.c fake-getnameinfo.c \ + utils.c getopt.c getopt1.c list.c splay_tree.c dropin.c fake-getaddrinfo.c fake-getnameinfo.c hash.c \ buffer.c conf.c connection.c control.c edge.c graph.c logger.c meta.c net.c net_packet.c net_setup.c \ net_socket.c netutl.c node.c process.c protocol.c protocol_auth.c protocol_edge.c protocol_misc.c \ - protocol_key.c protocol_subnet.c route.c subnet.c tincd.c + protocol_key.c protocol_subnet.c route.c sptps.c subnet.c subnet_parse.c tincd.c \ + dummy_device.c raw_socket_device.c multicast_device.c + +if UML +tincd_SOURCES += uml_device.c +endif + +if VDE +tincd_SOURCES += vde_device.c +endif nodist_tincd_SOURCES = \ device.c cipher.c crypto.c ecdh.c ecdsa.c digest.c prf.c rsa.c tincctl_SOURCES = \ utils.c getopt.c getopt1.c dropin.c \ - list.c tincctl.c top.c + info.c list.c subnet_parse.c tincctl.c top.c nodist_tincctl_SOURCES = \ ecdsagen.c rsagen.c +sptps_test_SOURCES = \ + logger.c cipher.c crypto.c ecdh.c ecdsa.c digest.c prf.c \ + sptps.c sptps_test.c utils.c + if TUNEMU tincd_SOURCES += bsd/tunemu.c endif -tincctl_LDADD = $(CURSES_LIBS) +tincctl_LDADD = $(READLINE_LIBS) $(CURSES_LIBS) DEFAULT_INCLUDES = @@ -32,8 +45,8 @@ INCLUDES = @INCLUDES@ -I$(top_builddir) noinst_HEADERS = \ xalloc.h utils.h getopt.h list.h splay_tree.h dropin.h fake-getaddrinfo.h fake-getnameinfo.h fake-gai-errnos.h ipv6.h ipv4.h ethernet.h \ - buffer.h conf.h connection.h control.h control_common.h device.h edge.h graph.h logger.h meta.h net.h netutl.h node.h process.h \ - protocol.h route.h subnet.h tincctl.h top.h bsd/tunemu.h + buffer.h conf.h connection.h control.h control_common.h device.h edge.h graph.h info.h logger.h meta.h net.h netutl.h node.h process.h \ + protocol.h route.h subnet.h sptps.h tincctl.h top.h bsd/tunemu.h hash.h nodist_noinst_HEADERS = \ cipher.h crypto.h ecdh.h ecdsa.h digest.h prf.h rsa.h ecdsagen.h rsagen.h diff --git a/src/Makefile.in b/src/Makefile.in index d7e2afd..d2a972b 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -1,9 +1,9 @@ -# Makefile.in generated by automake 1.11.1 from Makefile.am. +# Makefile.in generated by automake 1.11.6 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, -# Inc. +# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software +# Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -17,6 +17,23 @@ VPATH = @srcdir@ +am__make_dryrun = \ + { \ + am__dry=no; \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ + | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ + *) \ + for am__flg in $$MAKEFLAGS; do \ + case $$am__flg in \ + *=*|--*) ;; \ + *n*) am__dry=yes; break;; \ + esac; \ + done;; \ + esac; \ + test $$am__dry = yes; \ + } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ @@ -35,9 +52,11 @@ PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ -sbin_PROGRAMS = tincd$(EXEEXT) tincctl$(EXEEXT) -@TUNEMU_TRUE@am__append_1 = bsd/tunemu.c -@TUNEMU_TRUE@am__append_2 = -lpcap +sbin_PROGRAMS = tincd$(EXEEXT) tincctl$(EXEEXT) sptps_test$(EXEEXT) +@UML_TRUE@am__append_1 = uml_device.c +@VDE_TRUE@am__append_2 = vde_device.c +@TUNEMU_TRUE@am__append_3 = bsd/tunemu.c +@TUNEMU_TRUE@am__append_4 = -lpcap subdir = src DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \ $(srcdir)/Makefile.in @@ -45,7 +64,8 @@ ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \ $(top_srcdir)/m4/curses.m4 $(top_srcdir)/m4/libevent.m4 \ $(top_srcdir)/m4/lzo.m4 $(top_srcdir)/m4/openssl.m4 \ - $(top_srcdir)/m4/zlib.m4 $(top_srcdir)/configure.in + $(top_srcdir)/m4/readline.m4 $(top_srcdir)/m4/zlib.m4 \ + $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d @@ -54,34 +74,47 @@ CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__installdirs = "$(DESTDIR)$(sbindir)" PROGRAMS = $(sbin_PROGRAMS) +am_sptps_test_OBJECTS = logger.$(OBJEXT) cipher.$(OBJEXT) \ + crypto.$(OBJEXT) ecdh.$(OBJEXT) ecdsa.$(OBJEXT) \ + digest.$(OBJEXT) prf.$(OBJEXT) sptps.$(OBJEXT) \ + sptps_test.$(OBJEXT) utils.$(OBJEXT) +sptps_test_OBJECTS = $(am_sptps_test_OBJECTS) +sptps_test_LDADD = $(LDADD) am_tincctl_OBJECTS = utils.$(OBJEXT) getopt.$(OBJEXT) \ - getopt1.$(OBJEXT) dropin.$(OBJEXT) list.$(OBJEXT) \ - tincctl.$(OBJEXT) top.$(OBJEXT) + getopt1.$(OBJEXT) dropin.$(OBJEXT) info.$(OBJEXT) \ + list.$(OBJEXT) subnet_parse.$(OBJEXT) tincctl.$(OBJEXT) \ + top.$(OBJEXT) nodist_tincctl_OBJECTS = ecdsagen.$(OBJEXT) rsagen.$(OBJEXT) tincctl_OBJECTS = $(am_tincctl_OBJECTS) $(nodist_tincctl_OBJECTS) am__DEPENDENCIES_1 = -tincctl_DEPENDENCIES = $(am__DEPENDENCIES_1) +tincctl_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) am__tincd_SOURCES_DIST = utils.c getopt.c getopt1.c list.c \ splay_tree.c dropin.c fake-getaddrinfo.c fake-getnameinfo.c \ - buffer.c conf.c connection.c control.c edge.c graph.c logger.c \ - meta.c net.c net_packet.c net_setup.c net_socket.c netutl.c \ - node.c process.c protocol.c protocol_auth.c protocol_edge.c \ - protocol_misc.c protocol_key.c protocol_subnet.c route.c \ - subnet.c tincd.c bsd/tunemu.c -@TUNEMU_TRUE@am__objects_1 = tunemu.$(OBJEXT) + hash.c buffer.c conf.c connection.c control.c edge.c graph.c \ + logger.c meta.c net.c net_packet.c net_setup.c net_socket.c \ + netutl.c node.c process.c protocol.c protocol_auth.c \ + protocol_edge.c protocol_misc.c protocol_key.c \ + protocol_subnet.c route.c sptps.c subnet.c subnet_parse.c \ + tincd.c dummy_device.c raw_socket_device.c multicast_device.c \ + uml_device.c vde_device.c bsd/tunemu.c +@UML_TRUE@am__objects_1 = uml_device.$(OBJEXT) +@VDE_TRUE@am__objects_2 = vde_device.$(OBJEXT) +@TUNEMU_TRUE@am__objects_3 = tunemu.$(OBJEXT) am_tincd_OBJECTS = utils.$(OBJEXT) getopt.$(OBJEXT) getopt1.$(OBJEXT) \ list.$(OBJEXT) splay_tree.$(OBJEXT) dropin.$(OBJEXT) \ fake-getaddrinfo.$(OBJEXT) fake-getnameinfo.$(OBJEXT) \ - buffer.$(OBJEXT) conf.$(OBJEXT) connection.$(OBJEXT) \ - control.$(OBJEXT) edge.$(OBJEXT) graph.$(OBJEXT) \ - logger.$(OBJEXT) meta.$(OBJEXT) net.$(OBJEXT) \ + hash.$(OBJEXT) buffer.$(OBJEXT) conf.$(OBJEXT) \ + connection.$(OBJEXT) control.$(OBJEXT) edge.$(OBJEXT) \ + graph.$(OBJEXT) logger.$(OBJEXT) meta.$(OBJEXT) net.$(OBJEXT) \ net_packet.$(OBJEXT) net_setup.$(OBJEXT) net_socket.$(OBJEXT) \ netutl.$(OBJEXT) node.$(OBJEXT) process.$(OBJEXT) \ protocol.$(OBJEXT) protocol_auth.$(OBJEXT) \ protocol_edge.$(OBJEXT) protocol_misc.$(OBJEXT) \ protocol_key.$(OBJEXT) protocol_subnet.$(OBJEXT) \ - route.$(OBJEXT) subnet.$(OBJEXT) tincd.$(OBJEXT) \ - $(am__objects_1) + route.$(OBJEXT) sptps.$(OBJEXT) subnet.$(OBJEXT) \ + subnet_parse.$(OBJEXT) tincd.$(OBJEXT) dummy_device.$(OBJEXT) \ + raw_socket_device.$(OBJEXT) multicast_device.$(OBJEXT) \ + $(am__objects_1) $(am__objects_2) $(am__objects_3) nodist_tincd_OBJECTS = device.$(OBJEXT) cipher.$(OBJEXT) \ crypto.$(OBJEXT) ecdh.$(OBJEXT) ecdsa.$(OBJEXT) \ digest.$(OBJEXT) prf.$(OBJEXT) rsa.$(OBJEXT) @@ -94,9 +127,16 @@ COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ -SOURCES = $(tincctl_SOURCES) $(nodist_tincctl_SOURCES) \ - $(tincd_SOURCES) $(nodist_tincd_SOURCES) -DIST_SOURCES = $(tincctl_SOURCES) $(am__tincd_SOURCES_DIST) +SOURCES = $(sptps_test_SOURCES) $(tincctl_SOURCES) \ + $(nodist_tincctl_SOURCES) $(tincd_SOURCES) \ + $(nodist_tincd_SOURCES) +DIST_SOURCES = $(sptps_test_SOURCES) $(tincctl_SOURCES) \ + $(am__tincd_SOURCES_DIST) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac HEADERS = $(nodist_noinst_HEADERS) $(noinst_HEADERS) ETAGS = etags CTAGS = ctags @@ -133,7 +173,7 @@ LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ LIBOBJS = @LIBOBJS@ -LIBS = @LIBS@ @LIBGCRYPT_LIBS@ $(am__append_2) +LIBS = @LIBS@ @LIBGCRYPT_LIBS@ $(am__append_4) LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAINT = @MAINT@ @@ -149,6 +189,7 @@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ +READLINE_LIBS = @READLINE_LIBS@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ @@ -203,30 +244,36 @@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ -EXTRA_DIST = linux bsd solaris cygwin mingw raw_socket uml_socket openssl gcrypt +EXTRA_DIST = linux bsd solaris cygwin mingw openssl gcrypt tincd_SOURCES = utils.c getopt.c getopt1.c list.c splay_tree.c \ - dropin.c fake-getaddrinfo.c fake-getnameinfo.c buffer.c conf.c \ - connection.c control.c edge.c graph.c logger.c meta.c net.c \ - net_packet.c net_setup.c net_socket.c netutl.c node.c \ + dropin.c fake-getaddrinfo.c fake-getnameinfo.c hash.c buffer.c \ + conf.c connection.c control.c edge.c graph.c logger.c meta.c \ + net.c net_packet.c net_setup.c net_socket.c netutl.c node.c \ process.c protocol.c protocol_auth.c protocol_edge.c \ protocol_misc.c protocol_key.c protocol_subnet.c route.c \ - subnet.c tincd.c $(am__append_1) + sptps.c subnet.c subnet_parse.c tincd.c dummy_device.c \ + raw_socket_device.c multicast_device.c $(am__append_1) \ + $(am__append_2) $(am__append_3) nodist_tincd_SOURCES = \ device.c cipher.c crypto.c ecdh.c ecdsa.c digest.c prf.c rsa.c tincctl_SOURCES = \ utils.c getopt.c getopt1.c dropin.c \ - list.c tincctl.c top.c + info.c list.c subnet_parse.c tincctl.c top.c nodist_tincctl_SOURCES = \ ecdsagen.c rsagen.c -tincctl_LDADD = $(CURSES_LIBS) +sptps_test_SOURCES = \ + logger.c cipher.c crypto.c ecdh.c ecdsa.c digest.c prf.c \ + sptps.c sptps_test.c utils.c + +tincctl_LDADD = $(READLINE_LIBS) $(CURSES_LIBS) DEFAULT_INCLUDES = noinst_HEADERS = \ xalloc.h utils.h getopt.h list.h splay_tree.h dropin.h fake-getaddrinfo.h fake-getnameinfo.h fake-gai-errnos.h ipv6.h ipv4.h ethernet.h \ - buffer.h conf.h connection.h control.h control_common.h device.h edge.h graph.h logger.h meta.h net.h netutl.h node.h process.h \ - protocol.h route.h subnet.h tincctl.h top.h bsd/tunemu.h + buffer.h conf.h connection.h control.h control_common.h device.h edge.h graph.h info.h logger.h meta.h net.h netutl.h node.h process.h \ + protocol.h route.h subnet.h sptps.h tincctl.h top.h bsd/tunemu.h hash.h nodist_noinst_HEADERS = \ cipher.h crypto.h ecdh.h ecdsa.h digest.h prf.h rsa.h ecdsagen.h rsagen.h @@ -268,8 +315,11 @@ $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) $(am__aclocal_m4_deps): install-sbinPROGRAMS: $(sbin_PROGRAMS) @$(NORMAL_INSTALL) - test -z "$(sbindir)" || $(MKDIR_P) "$(DESTDIR)$(sbindir)" @list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(sbindir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(sbindir)" || exit 1; \ + fi; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p; \ @@ -303,10 +353,13 @@ uninstall-sbinPROGRAMS: clean-sbinPROGRAMS: -test -z "$(sbin_PROGRAMS)" || rm -f $(sbin_PROGRAMS) -tincctl$(EXEEXT): $(tincctl_OBJECTS) $(tincctl_DEPENDENCIES) +sptps_test$(EXEEXT): $(sptps_test_OBJECTS) $(sptps_test_DEPENDENCIES) $(EXTRA_sptps_test_DEPENDENCIES) + @rm -f sptps_test$(EXEEXT) + $(LINK) $(sptps_test_OBJECTS) $(sptps_test_LDADD) $(LIBS) +tincctl$(EXEEXT): $(tincctl_OBJECTS) $(tincctl_DEPENDENCIES) $(EXTRA_tincctl_DEPENDENCIES) @rm -f tincctl$(EXEEXT) $(LINK) $(tincctl_OBJECTS) $(tincctl_LDADD) $(LIBS) -tincd$(EXEEXT): $(tincd_OBJECTS) $(tincd_DEPENDENCIES) +tincd$(EXEEXT): $(tincd_OBJECTS) $(tincd_DEPENDENCIES) $(EXTRA_tincd_DEPENDENCIES) @rm -f tincd$(EXEEXT) $(LINK) $(tincd_OBJECTS) $(tincd_LDADD) $(LIBS) @@ -325,6 +378,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/device.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/digest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dropin.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dummy_device.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ecdh.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ecdsa.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ecdsagen.Po@am__quote@ @@ -334,9 +388,12 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getopt.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getopt1.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/graph.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hash.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/info.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/list.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/logger.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/meta.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/multicast_device.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/net.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/net_packet.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/net_setup.Po@am__quote@ @@ -351,16 +408,22 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protocol_key.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protocol_misc.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protocol_subnet.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/raw_socket_device.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/route.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rsa.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rsagen.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/splay_tree.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sptps.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sptps_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/subnet.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/subnet_parse.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tincctl.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tincd.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/top.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tunemu.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uml_device.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/utils.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vde_device.Po@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @@ -492,10 +555,15 @@ install-am: all-am installcheck: installcheck-am install-strip: - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - `test -z '$(STRIP)' || \ - echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi mostlyclean-generic: clean-generic: diff --git a/src/bsd/device.c b/src/bsd/device.c index 9c3009d..3e64ba9 100644 --- a/src/bsd/device.c +++ b/src/bsd/device.c @@ -1,7 +1,7 @@ /* device.c -- Interaction BSD tun/tap device Copyright (C) 2001-2005 Ivo Timmermans, - 2001-2011 Guus Sliepen + 2001-2012 Guus Sliepen 2009 Grzegorz Dymarek This program is free software; you can redistribute it and/or modify @@ -33,7 +33,12 @@ #include "bsd/tunemu.h" #endif -#define DEFAULT_DEVICE "/dev/tun0" +#define DEFAULT_TUN_DEVICE "/dev/tun0" +#if defined(HAVE_FREEBSD) || defined(HAVE_NETBSD) +#define DEFAULT_TAP_DEVICE "/dev/tap0" +#else +#define DEFAULT_TAP_DEVICE "/dev/tun0" +#endif typedef enum device_type { DEVICE_TYPE_TUN, @@ -58,18 +63,22 @@ static device_type_t device_type = DEVICE_TYPE_TUNIFHEAD; static device_type_t device_type = DEVICE_TYPE_TUN; #endif -bool setup_device(void) { +static bool setup_device(void) { char *type; - if(!get_config_string(lookup_config(config_tree, "Device"), &device)) - device = xstrdup(DEFAULT_DEVICE); + if(!get_config_string(lookup_config(config_tree, "Device"), &device)) { + if(routing_mode == RMODE_ROUTER) + device = xstrdup(DEFAULT_TUN_DEVICE); + else + device = xstrdup(DEFAULT_TAP_DEVICE); + } if(!get_config_string(lookup_config(config_tree, "Interface"), &iface)) iface = xstrdup(strrchr(device, '/') ? strrchr(device, '/') + 1 : device); if(get_config_string(lookup_config(config_tree, "DeviceType"), &type)) { if(!strcasecmp(type, "tun")) - /* use default */; + /* use default */; #ifdef HAVE_TUNEMU else if(!strcasecmp(type, "tunemu")) device_type = DEVICE_TYPE_TUNEMU; @@ -81,7 +90,7 @@ bool setup_device(void) { else if(!strcasecmp(type, "tap")) device_type = DEVICE_TYPE_TAP; else { - logger(LOG_ERR, "Unknown device type %s!", type); + logger(DEBUG_ALWAYS, LOG_ERR, "Unknown device type %s!", type); return false; } } else { @@ -93,7 +102,7 @@ bool setup_device(void) { #ifdef HAVE_TUNEMU case DEVICE_TYPE_TUNEMU: { char dynamic_name[256] = ""; - device_fd = tunemu_open(dynamic_name); + device_fd = tunemu_open(dynamic_name); } break; #endif @@ -102,19 +111,23 @@ bool setup_device(void) { } if(device_fd < 0) { - logger(LOG_ERR, "Could not open %s: %s", device, strerror(errno)); + logger(DEBUG_ALWAYS, LOG_ERR, "Could not open %s: %s", device, strerror(errno)); return false; } +#ifdef FD_CLOEXEC + fcntl(device_fd, F_SETFD, FD_CLOEXEC); +#endif + switch(device_type) { default: device_type = DEVICE_TYPE_TUN; case DEVICE_TYPE_TUN: #ifdef TUNSIFHEAD - { + { const int zero = 0; if(ioctl(device_fd, TUNSIFHEAD, &zero, sizeof zero) == -1) { - logger(LOG_ERR, "System call `%s' failed: %s", "ioctl", strerror(errno)); + logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "ioctl", strerror(errno)); return false; } } @@ -133,7 +146,7 @@ bool setup_device(void) { { const int one = 1; if(ioctl(device_fd, TUNSIFHEAD, &one, sizeof one) == -1) { - logger(LOG_ERR, "System call `%s' failed: %s", "ioctl", strerror(errno)); + logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "ioctl", strerror(errno)); return false; } } @@ -160,22 +173,22 @@ bool setup_device(void) { iface = xstrdup(ifr.ifr_name); } } - + #endif break; #ifdef HAVE_TUNEMU case DEVICE_TYPE_TUNEMU: - device_info = "BSD tunemu device"; + device_info = "BSD tunemu device"; break; #endif } - logger(LOG_INFO, "%s is a %s", device, device_info); + logger(DEBUG_ALWAYS, LOG_INFO, "%s is a %s", device, device_info); return true; } -void close_device(void) { +static void close_device(void) { switch(device_type) { #ifdef HAVE_TUNEMU case DEVICE_TYPE_TUNEMU: @@ -190,7 +203,7 @@ void close_device(void) { free(iface); } -bool read_packet(vpn_packet_t *packet) { +static bool read_packet(vpn_packet_t *packet) { int inlen; switch(device_type) { @@ -204,7 +217,7 @@ bool read_packet(vpn_packet_t *packet) { inlen = read(device_fd, packet->data + 14, MTU - 14); if(inlen <= 0) { - logger(LOG_ERR, "Error while reading from %s %s: %s", device_info, + logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info, device, strerror(errno)); return false; } @@ -219,12 +232,13 @@ bool read_packet(vpn_packet_t *packet) { packet->data[13] = 0xDD; break; default: - ifdebug(TRAFFIC) logger(LOG_ERR, + logger(DEBUG_TRAFFIC, LOG_ERR, "Unknown IP version %d while reading packet from %s %s", packet->data[14] >> 4, device_info, device); return false; } + memset(packet->data, 0, 12); packet->len = inlen + 14; break; @@ -233,7 +247,7 @@ bool read_packet(vpn_packet_t *packet) { struct iovec vector[2] = {{&type, sizeof type}, {packet->data + 14, MTU - 14}}; if((inlen = readv(device_fd, vector, 2)) <= 0) { - logger(LOG_ERR, "Error while reading from %s %s: %s", device_info, + logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info, device, strerror(errno)); return false; } @@ -250,19 +264,20 @@ bool read_packet(vpn_packet_t *packet) { break; default: - ifdebug(TRAFFIC) logger(LOG_ERR, + logger(DEBUG_TRAFFIC, LOG_ERR, "Unknown address family %x while reading packet from %s %s", ntohl(type), device_info, device); return false; } + memset(packet->data, 0, 12); packet->len = inlen + 10; break; } case DEVICE_TYPE_TAP: if((inlen = read(device_fd, packet->data, MTU)) <= 0) { - logger(LOG_ERR, "Error while reading from %s %s: %s", device_info, + logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info, device, strerror(errno)); return false; } @@ -273,23 +288,23 @@ bool read_packet(vpn_packet_t *packet) { default: return false; } - + device_total_in += packet->len; - ifdebug(TRAFFIC) logger(LOG_DEBUG, "Read packet of %d bytes from %s", + logger(DEBUG_TRAFFIC, LOG_DEBUG, "Read packet of %d bytes from %s", packet->len, device_info); return true; } -bool write_packet(vpn_packet_t *packet) { - ifdebug(TRAFFIC) logger(LOG_DEBUG, "Writing packet of %d bytes to %s", +static bool write_packet(vpn_packet_t *packet) { + logger(DEBUG_TRAFFIC, LOG_DEBUG, "Writing packet of %d bytes to %s", packet->len, device_info); switch(device_type) { case DEVICE_TYPE_TUN: if(write(device_fd, packet->data + 14, packet->len - 14) < 0) { - logger(LOG_ERR, "Error while writing to %s %s: %s", device_info, + logger(DEBUG_ALWAYS, LOG_ERR, "Error while writing to %s %s: %s", device_info, device, strerror(errno)); return false; } @@ -299,7 +314,7 @@ bool write_packet(vpn_packet_t *packet) { u_int32_t type; struct iovec vector[2] = {{&type, sizeof type}, {packet->data + 14, packet->len - 14}}; int af; - + af = (packet->data[12] << 8) + packet->data[13]; switch (af) { @@ -310,23 +325,23 @@ bool write_packet(vpn_packet_t *packet) { type = htonl(AF_INET6); break; default: - ifdebug(TRAFFIC) logger(LOG_ERR, + logger(DEBUG_TRAFFIC, LOG_ERR, "Unknown address family %x while writing packet to %s %s", af, device_info, device); return false; } if(writev(device_fd, vector, 2) < 0) { - logger(LOG_ERR, "Can't write to %s %s: %s", device_info, device, + logger(DEBUG_ALWAYS, LOG_ERR, "Can't write to %s %s: %s", device_info, device, strerror(errno)); return false; } break; } - + case DEVICE_TYPE_TAP: if(write(device_fd, packet->data, packet->len) < 0) { - logger(LOG_ERR, "Error while writing to %s %s: %s", device_info, + logger(DEBUG_ALWAYS, LOG_ERR, "Error while writing to %s %s: %s", device_info, device, strerror(errno)); return false; } @@ -335,7 +350,7 @@ bool write_packet(vpn_packet_t *packet) { #ifdef HAVE_TUNEMU case DEVICE_TYPE_TUNEMU: if(tunemu_write(device_fd, packet->data + 14, packet->len - 14) < 0) { - logger(LOG_ERR, "Error while writing to %s %s: %s", device_info, + logger(DEBUG_ALWAYS, LOG_ERR, "Error while writing to %s %s: %s", device_info, device, strerror(errno)); return false; } @@ -351,8 +366,16 @@ bool write_packet(vpn_packet_t *packet) { return true; } -void dump_device_stats(void) { - logger(LOG_DEBUG, "Statistics for %s %s:", device_info, device); - logger(LOG_DEBUG, " total bytes in: %10"PRIu64, device_total_in); - logger(LOG_DEBUG, " total bytes out: %10"PRIu64, device_total_out); +static void dump_device_stats(void) { + logger(DEBUG_ALWAYS, LOG_DEBUG, "Statistics for %s %s:", device_info, device); + logger(DEBUG_ALWAYS, LOG_DEBUG, " total bytes in: %10"PRIu64, device_total_in); + logger(DEBUG_ALWAYS, LOG_DEBUG, " total bytes out: %10"PRIu64, device_total_out); } + +const devops_t os_devops = { + .setup = setup_device, + .close = close_device, + .read = read_packet, + .write = write_packet, + .dump_stats = dump_device_stats, +}; diff --git a/src/bsd/tunemu.c b/src/bsd/tunemu.c index f532b04..1ce9007 100644 --- a/src/bsd/tunemu.c +++ b/src/bsd/tunemu.c @@ -1,20 +1,20 @@ /* * tunemu - Tun device emulation for Darwin * Copyright (C) 2009 Friedrich Schöller - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program. If not, see . - * + * */ #include "tunemu.h" @@ -36,18 +36,18 @@ #define PPPPROTO_CTL 1 -#define PPP_IP 0x21 -#define PPP_IPV6 0x57 +#define PPP_IP 0x21 +#define PPP_IPV6 0x57 #define SC_LOOP_TRAFFIC 0x00000200 -#define PPPIOCNEWUNIT _IOWR('t', 62, int) -#define PPPIOCSFLAGS _IOW('t', 89, int) -#define PPPIOCSNPMODE _IOW('t', 75, struct npioctl) -#define PPPIOCATTCHAN _IOW('t', 56, int) -#define PPPIOCGCHAN _IOR('t', 55, int) -#define PPPIOCCONNECT _IOW('t', 58, int) -#define PPPIOCGUNIT _IOR('t', 86, int) +#define PPPIOCNEWUNIT _IOWR('t', 62, int) +#define PPPIOCSFLAGS _IOW('t', 89, int) +#define PPPIOCSNPMODE _IOW('t', 75, struct npioctl) +#define PPPIOCATTCHAN _IOW('t', 56, int) +#define PPPIOCGCHAN _IOR('t', 55, int) +#define PPPIOCCONNECT _IOW('t', 58, int) +#define PPPIOCGUNIT _IOR('t', 86, int) struct sockaddr_ppp { diff --git a/src/bsd/tunemu.h b/src/bsd/tunemu.h index 42b1785..e0452a8 100644 --- a/src/bsd/tunemu.h +++ b/src/bsd/tunemu.h @@ -1,20 +1,20 @@ /* * tunemu - Tun device emulation for Darwin * Copyright (C) 2009 Friedrich Schöller - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program. If not, see . - * + * */ #ifndef TUNEMU_H diff --git a/src/buffer.c b/src/buffer.c index 3d4c329..ac57d1c 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -57,7 +57,7 @@ char *buffer_prepare(buffer_t *buffer, int size) { } // Copy data into the buffer. - + void buffer_add(buffer_t *buffer, const char *data, int size) { memcpy(buffer_prepare(buffer, size), data, size); } diff --git a/src/cipher.c b/src/cipher.c new file mode 100644 index 0000000..553b4ad --- /dev/null +++ b/src/cipher.c @@ -0,0 +1,218 @@ +/* + cipher.c -- Symmetric block cipher handling + Copyright (C) 2007-2012 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "system.h" + +#include +#include + +#include "cipher.h" +#include "logger.h" +#include "xalloc.h" + +typedef struct cipher_counter { + unsigned char counter[EVP_MAX_IV_LENGTH]; + unsigned char block[EVP_MAX_IV_LENGTH]; + int n; +} cipher_counter_t; + +static bool cipher_open(cipher_t *cipher) { + EVP_CIPHER_CTX_init(&cipher->ctx); + + return true; +} + +bool cipher_open_by_name(cipher_t *cipher, const char *name) { + cipher->cipher = EVP_get_cipherbyname(name); + + if(cipher->cipher) + return cipher_open(cipher); + + logger(DEBUG_ALWAYS, LOG_ERR, "Unknown cipher name '%s'!", name); + return false; +} + +bool cipher_open_by_nid(cipher_t *cipher, int nid) { + cipher->cipher = EVP_get_cipherbynid(nid); + + if(cipher->cipher) + return cipher_open(cipher); + + logger(DEBUG_ALWAYS, LOG_ERR, "Unknown cipher nid %d!", nid); + return false; +} + +bool cipher_open_blowfish_ofb(cipher_t *cipher) { + cipher->cipher = EVP_bf_ofb(); + return cipher_open(cipher); +} + +void cipher_close(cipher_t *cipher) { + EVP_CIPHER_CTX_cleanup(&cipher->ctx); + free(cipher->counter); + cipher->counter = NULL; +} + +size_t cipher_keylength(const cipher_t *cipher) { + return cipher->cipher->key_len + cipher->cipher->block_size; +} + +bool cipher_set_key(cipher_t *cipher, void *key, bool encrypt) { + bool result; + + if(encrypt) + result = EVP_EncryptInit_ex(&cipher->ctx, cipher->cipher, NULL, (unsigned char *)key, (unsigned char *)key + cipher->cipher->key_len); + else + result = EVP_DecryptInit_ex(&cipher->ctx, cipher->cipher, NULL, (unsigned char *)key, (unsigned char *)key + cipher->cipher->key_len); + + if(result) + return true; + + logger(DEBUG_ALWAYS, LOG_ERR, "Error while setting key: %s", ERR_error_string(ERR_get_error(), NULL)); + return false; +} + +bool cipher_set_key_from_rsa(cipher_t *cipher, void *key, size_t len, bool encrypt) { + bool result; + + if(encrypt) + result = EVP_EncryptInit_ex(&cipher->ctx, cipher->cipher, NULL, (unsigned char *)key + len - cipher->cipher->key_len, (unsigned char *)key + len - cipher->cipher->iv_len - cipher->cipher->key_len); + else + result = EVP_DecryptInit_ex(&cipher->ctx, cipher->cipher, NULL, (unsigned char *)key + len - cipher->cipher->key_len, (unsigned char *)key + len - cipher->cipher->iv_len - cipher->cipher->key_len); + + if(result) + return true; + + logger(DEBUG_ALWAYS, LOG_ERR, "Error while setting key: %s", ERR_error_string(ERR_get_error(), NULL)); + return false; +} + +bool cipher_set_counter(cipher_t *cipher, const void *counter, size_t len) { + if(len > cipher->cipher->block_size - 4) { + logger(DEBUG_ALWAYS, LOG_ERR, "Counter too long"); + abort(); + } + + memcpy(cipher->counter->counter + cipher->cipher->block_size - len, counter, len); + memset(cipher->counter->counter, 0, 4); + cipher->counter->n = 0; + + return true; +} + +bool cipher_set_counter_key(cipher_t *cipher, void *key) { + int result = EVP_EncryptInit_ex(&cipher->ctx, cipher->cipher, NULL, (unsigned char *)key, NULL); + if(!result) { + logger(DEBUG_ALWAYS, LOG_ERR, "Error while setting key: %s", ERR_error_string(ERR_get_error(), NULL)); + return false; + } + + if(!cipher->counter) + cipher->counter = xmalloc_and_zero(sizeof *cipher->counter); + else + cipher->counter->n = 0; + + memcpy(cipher->counter->counter, (unsigned char *)key + cipher->cipher->key_len, cipher->cipher->block_size); + + return true; +} + +bool cipher_counter_xor(cipher_t *cipher, const void *indata, size_t inlen, void *outdata) { + if(!cipher->counter) { + logger(DEBUG_ALWAYS, LOG_ERR, "Counter not initialized"); + return false; + } + + const unsigned char *in = indata; + unsigned char *out = outdata; + + while(inlen--) { + // Encrypt the new counter value if we need it + if(!cipher->counter->n) { + int len; + if(!EVP_EncryptUpdate(&cipher->ctx, cipher->counter->block, &len, cipher->counter->counter, cipher->cipher->block_size)) { + logger(DEBUG_ALWAYS, LOG_ERR, "Error while encrypting: %s", ERR_error_string(ERR_get_error(), NULL)); + return false; + } + + // Increase the counter value + for(int i = 0; i < cipher->cipher->block_size; i++) + if(++cipher->counter->counter[i]) + break; + } + + *out++ = *in++ ^ cipher->counter->counter[cipher->counter->n++]; + + if(cipher->counter->n >= cipher->cipher->block_size) + cipher->counter->n = 0; + } + + return true; +} + + +bool cipher_encrypt(cipher_t *cipher, const void *indata, size_t inlen, void *outdata, size_t *outlen, bool oneshot) { + if(oneshot) { + int len, pad; + if(EVP_EncryptInit_ex(&cipher->ctx, NULL, NULL, NULL, NULL) + && EVP_EncryptUpdate(&cipher->ctx, (unsigned char *)outdata, &len, indata, inlen) + && EVP_EncryptFinal(&cipher->ctx, (unsigned char *)outdata + len, &pad)) { + if(outlen) *outlen = len + pad; + return true; + } + } else { + int len; + if(EVP_EncryptUpdate(&cipher->ctx, outdata, &len, indata, inlen)) { + if(outlen) *outlen = len; + return true; + } + } + + logger(DEBUG_ALWAYS, LOG_ERR, "Error while encrypting: %s", ERR_error_string(ERR_get_error(), NULL)); + return false; +} + +bool cipher_decrypt(cipher_t *cipher, const void *indata, size_t inlen, void *outdata, size_t *outlen, bool oneshot) { + if(oneshot) { + int len, pad; + if(EVP_DecryptInit_ex(&cipher->ctx, NULL, NULL, NULL, NULL) + && EVP_DecryptUpdate(&cipher->ctx, (unsigned char *)outdata, &len, indata, inlen) + && EVP_DecryptFinal(&cipher->ctx, (unsigned char *)outdata + len, &pad)) { + if(outlen) *outlen = len + pad; + return true; + } + } else { + int len; + if(EVP_EncryptUpdate(&cipher->ctx, outdata, &len, indata, inlen)) { + if(outlen) *outlen = len; + return true; + } + } + + logger(DEBUG_ALWAYS, LOG_ERR, "Error while decrypting: %s", ERR_error_string(ERR_get_error(), NULL)); + return false; +} + +int cipher_get_nid(const cipher_t *cipher) { + return cipher->cipher ? cipher->cipher->nid : 0; +} + +bool cipher_active(const cipher_t *cipher) { + return cipher->cipher && cipher->cipher->nid != 0; +} diff --git a/src/conf.c b/src/conf.c index f47faef..b9bfbf6 100644 --- a/src/conf.c +++ b/src/conf.c @@ -2,9 +2,9 @@ conf.c -- configuration code Copyright (C) 1998 Robert van der Meulen 1998-2005 Ivo Timmermans - 2000-2010 Guus Sliepen + 2000-2012 Guus Sliepen 2010-2011 Julien Muchembled - 2000 Cris van Pelt + 2000 Cris van Pelt This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -28,18 +28,18 @@ #include "conf.h" #include "list.h" #include "logger.h" -#include "netutl.h" /* for str2address */ +#include "netutl.h" /* for str2address */ #include "protocol.h" -#include "utils.h" /* for cp */ +#include "utils.h" /* for cp */ #include "xalloc.h" splay_tree_t *config_tree; -int pinginterval = 0; /* seconds between pings */ -int pingtimeout = 0; /* seconds to wait for response */ -char *confbase = NULL; /* directory in which all config files are */ -char *netname = NULL; /* name of the vpn network */ -list_t *cmdline_conf = NULL; /* global/host configuration values given at the command line */ +int pinginterval = 0; /* seconds between pings */ +int pingtimeout = 0; /* seconds to wait for response */ +char *confbase = NULL; /* directory in which all config files are */ +char *netname = NULL; /* name of the vpn network */ +list_t *cmdline_conf = NULL; /* global/host configuration values given at the command line */ static int config_compare(const config_t *a, const config_t *b) { @@ -141,7 +141,7 @@ bool get_config_bool(const config_t *cfg, bool *result) { return true; } - logger(LOG_ERR, "\"yes\" or \"no\" expected for configuration variable %s in %s line %d", + logger(DEBUG_ALWAYS, LOG_ERR, "\"yes\" or \"no\" expected for configuration variable %s in %s line %d", cfg->variable, cfg->file, cfg->line); return false; @@ -154,7 +154,7 @@ bool get_config_int(const config_t *cfg, int *result) { if(sscanf(cfg->value, "%d", result) == 1) return true; - logger(LOG_ERR, "Integer expected for configuration variable %s in %s line %d", + logger(DEBUG_ALWAYS, LOG_ERR, "Integer expected for configuration variable %s in %s line %d", cfg->variable, cfg->file, cfg->line); return false; @@ -182,7 +182,7 @@ bool get_config_address(const config_t *cfg, struct addrinfo **result) { return true; } - logger(LOG_ERR, "Hostname or IP address expected for configuration variable %s in %s line %d", + logger(DEBUG_ALWAYS, LOG_ERR, "Hostname or IP address expected for configuration variable %s in %s line %d", cfg->variable, cfg->file, cfg->line); return false; @@ -195,7 +195,7 @@ bool get_config_subnet(const config_t *cfg, subnet_t ** result) { return false; if(!str2net(&subnet, cfg->value)) { - logger(LOG_ERR, "Subnet expected for configuration variable %s in %s line %d", + logger(DEBUG_ALWAYS, LOG_ERR, "Subnet expected for configuration variable %s in %s line %d", cfg->variable, cfg->file, cfg->line); return false; } @@ -206,7 +206,7 @@ bool get_config_subnet(const config_t *cfg, subnet_t ** result) { && !maskcheck(&subnet.net.ipv4.address, subnet.net.ipv4.prefixlength, sizeof subnet.net.ipv4.address)) || ((subnet.type == SUBNET_IPV6) && !maskcheck(&subnet.net.ipv6.address, subnet.net.ipv6.prefixlength, sizeof subnet.net.ipv6.address))) { - logger(LOG_ERR, "Network address and prefix length do not match for configuration variable %s in %s line %d", + logger(DEBUG_ALWAYS, LOG_ERR, "Network address and prefix length do not match for configuration variable %s in %s line %d", cfg->variable, cfg->file, cfg->line); return false; } @@ -236,8 +236,9 @@ static char *readline(FILE * fp, char *buf, size_t buflen) { if(!newline) return buf; - *newline = '\0'; /* kill newline */ - if(newline > p && newline[-1] == '\r') /* and carriage return if necessary */ + /* kill newline and carriage return if necessary */ + *newline = '\0'; + if(newline > p && newline[-1] == '\r') newline[-1] = '\0'; return buf; @@ -265,10 +266,10 @@ config_t *parse_config_line(char *line, const char *fname, int lineno) { if(!*value) { const char err[] = "No value for variable"; if (fname) - logger(LOG_ERR, "%s `%s' on line %d while reading config file %s", + logger(DEBUG_ALWAYS, LOG_ERR, "%s `%s' on line %d while reading config file %s", err, variable, lineno, fname); else - logger(LOG_ERR, "%s `%s' in command line option %d", + logger(DEBUG_ALWAYS, LOG_ERR, "%s `%s' in command line option %d", err, variable, lineno); return NULL; } @@ -298,7 +299,7 @@ bool read_config_file(splay_tree_t *config_tree, const char *fname) { fp = fopen(fname, "r"); if(!fp) { - logger(LOG_ERR, "Cannot open config file %s: %s", fname, strerror(errno)); + logger(DEBUG_ALWAYS, LOG_ERR, "Cannot open config file %s: %s", fname, strerror(errno)); return false; } @@ -321,7 +322,7 @@ bool read_config_file(splay_tree_t *config_tree, const char *fname) { ignore = false; continue; } - + if(!strncmp(line, "-----BEGIN", 10)) { ignore = true; continue; @@ -339,33 +340,31 @@ bool read_config_file(splay_tree_t *config_tree, const char *fname) { } void read_config_options(splay_tree_t *config_tree, const char *prefix) { - list_node_t *node, *next; size_t prefix_len = prefix ? strlen(prefix) : 0; - for(node = cmdline_conf->tail; node; node = next) { - config_t *orig_cfg, *cfg = (config_t *)node->data; - next = node->prev; + for(const list_node_t *node = cmdline_conf->tail; node; node = node->prev) { + const config_t *cfg = node->data; + config_t *new; if(!prefix) { if(strchr(cfg->variable, '.')) continue; - node->data = NULL; - list_unlink_node(cmdline_conf, node); } else { if(strncmp(prefix, cfg->variable, prefix_len) || cfg->variable[prefix_len] != '.') continue; - /* Because host configuration is parsed again when - reconnecting, nodes must not be freed when a prefix - is given. */ - orig_cfg = cfg; - cfg = new_config(); - cfg->variable = xstrdup(orig_cfg->variable + prefix_len + 1); - cfg->value = xstrdup(orig_cfg->value); - cfg->file = NULL; - cfg->line = orig_cfg->line; } - config_add(config_tree, cfg); + + new = new_config(); + if(prefix) + new->variable = xstrdup(cfg->variable + prefix_len + 1); + else + new->variable = xstrdup(cfg->variable); + new->value = xstrdup(cfg->value); + new->file = NULL; + new->line = cfg->line; + + config_add(config_tree, new); } } @@ -375,26 +374,25 @@ bool read_server_config(void) { read_config_options(config_tree, NULL); - xasprintf(&fname, "%s/tinc.conf", confbase); + xasprintf(&fname, "%s" SLASH "tinc.conf", confbase); x = read_config_file(config_tree, fname); - if(!x) { /* System error: complain */ - logger(LOG_ERR, "Failed to read `%s': %s", fname, strerror(errno)); - } + if(!x) + logger(DEBUG_ALWAYS, LOG_ERR, "Failed to read `%s': %s", fname, strerror(errno)); free(fname); return x; } -bool read_connection_config(connection_t *c) { +bool read_host_config(splay_tree_t *config_tree, const char *name) { char *fname; bool x; - read_config_options(c->config_tree, c->name); + read_config_options(config_tree, name); - xasprintf(&fname, "%s/hosts/%s", confbase, c->name); - x = read_config_file(c->config_tree, fname); + xasprintf(&fname, "%s" SLASH "hosts" SLASH "%s", confbase, name); + x = read_config_file(config_tree, fname); free(fname); return x; @@ -402,12 +400,12 @@ bool read_connection_config(connection_t *c) { bool append_config_file(const char *name, const char *key, const char *value) { char *fname; - xasprintf(&fname, "%s/hosts/%s", confbase, name); + xasprintf(&fname, "%s" SLASH "hosts" SLASH "%s", confbase, name); FILE *fp = fopen(fname, "a"); if(!fp) { - logger(LOG_ERR, "Cannot open config file %s: %s", fname, strerror(errno)); + logger(DEBUG_ALWAYS, LOG_ERR, "Cannot open config file %s: %s", fname, strerror(errno)); } else { fprintf(fp, "\n# The following line was automatically added by tinc\n%s = %s\n", key, value); fclose(fp); @@ -415,45 +413,5 @@ bool append_config_file(const char *name, const char *key, const char *value) { free(fname); - return fp; -} - -bool disable_old_keys(FILE *f) { - char buf[100]; - long pos; - bool disabled = false; - - rewind(f); - pos = ftell(f); - - if(pos < 0) - return false; - - while(fgets(buf, sizeof buf, f)) { - if(!strncmp(buf, "-----BEGIN RSA", 14)) { - buf[11] = 'O'; - buf[12] = 'L'; - buf[13] = 'D'; - if(fseek(f, pos, SEEK_SET)) - break; - if(fputs(buf, f) <= 0) - break; - disabled = true; - } - else if(!strncmp(buf, "-----END RSA", 12)) { - buf[ 9] = 'O'; - buf[10] = 'L'; - buf[11] = 'D'; - if(fseek(f, pos, SEEK_SET)) - break; - if(fputs(buf, f) <= 0) - break; - disabled = true; - } - pos = ftell(f); - if(pos < 0) - break; - } - - return disabled; + return fp != NULL; } diff --git a/src/conf.h b/src/conf.h index bd3850b..20a78a9 100644 --- a/src/conf.h +++ b/src/conf.h @@ -1,7 +1,7 @@ /* conf.h -- header for conf.c Copyright (C) 1998-2005 Ivo Timmermans - 2000-2009 Guus Sliepen + 2000-2012 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 @@ -60,10 +60,7 @@ extern config_t *parse_config_line(char *, const char *, int); extern bool read_config_file(splay_tree_t *, const char *); extern void read_config_options(splay_tree_t *, const char *); extern bool read_server_config(void); -extern bool read_connection_config(struct connection_t *); +extern bool read_host_config(splay_tree_t *, const char *); extern bool append_config_file(const char *, const char *, const char *); -extern FILE *ask_and_open(const char *, const char *, const char *); -extern bool is_safe_path(const char *); -extern bool disable_old_keys(FILE *); -#endif /* __TINC_CONF_H__ */ +#endif /* __TINC_CONF_H__ */ diff --git a/src/connection.c b/src/connection.c index bae86b9..d39f43f 100644 --- a/src/connection.c +++ b/src/connection.c @@ -1,6 +1,6 @@ /* connection.c -- connection list management - Copyright (C) 2000-2009 Guus Sliepen , + Copyright (C) 2000-2012 Guus Sliepen , 2000-2005 Ivo Timmermans 2008 Max Rijevski @@ -21,7 +21,7 @@ #include "system.h" -#include "splay_tree.h" +#include "list.h" #include "cipher.h" #include "conf.h" #include "control_common.h" @@ -31,23 +31,19 @@ #include "utils.h" #include "xalloc.h" -splay_tree_t *connection_tree; /* Meta connections */ -connection_t *broadcast; - -static int connection_compare(const connection_t *a, const connection_t *b) { - return a < b ? -1 : a == b ? 0 : 1; -} +list_t *connection_list; +connection_t *everyone; void init_connections(void) { - connection_tree = splay_alloc_tree((splay_compare_t) connection_compare, (splay_action_t) free_connection); - broadcast = new_connection(); - broadcast->name = xstrdup("everyone"); - broadcast->hostname = xstrdup("BROADCAST"); + connection_list = list_alloc((list_action_t) free_connection); + everyone = new_connection(); + everyone->name = xstrdup("everyone"); + everyone->hostname = xstrdup("BROADCAST"); } void exit_connections(void) { - splay_delete_tree(connection_tree); - free_connection(broadcast); + list_delete_list(connection_list); + free_connection(everyone); } connection_t *new_connection(void) { @@ -58,30 +54,20 @@ void free_connection(connection_t *c) { if(!c) return; - if(c->name) - free(c->name); - - if(c->hostname) - free(c->hostname); - cipher_close(&c->incipher); digest_close(&c->indigest); cipher_close(&c->outcipher); digest_close(&c->outdigest); - ecdh_free(&c->ecdh); + sptps_stop(&c->sptps); ecdsa_free(&c->ecdsa); rsa_free(&c->rsa); - if(c->hischallenge) - free(c->hischallenge); - - if(c->config_tree) - exit_configuration(&c->config_tree); + free(c->hischallenge); buffer_clear(&c->inbuf); buffer_clear(&c->outbuf); - + if(event_initialized(&c->inevent)) event_del(&c->inevent); @@ -91,24 +77,26 @@ void free_connection(connection_t *c) { if(c->socket > 0) closesocket(c->socket); + free(c->name); + free(c->hostname); + + if(c->config_tree) + exit_configuration(&c->config_tree); + free(c); } void connection_add(connection_t *c) { - splay_insert(connection_tree, c); + list_insert_tail(connection_list, c); } void connection_del(connection_t *c) { - splay_delete(connection_tree, c); + list_delete(connection_list, c); } bool dump_connections(connection_t *cdump) { - splay_node_t *node; - connection_t *c; - - for(node = connection_tree->head; node; node = node->next) { - c = node->data; - send_request(cdump, "%d %d %s at %s options %x socket %d status %04x", + for list_each(connection_t, c, connection_list) { + send_request(cdump, "%d %d %s %s %x %d %x", CONTROL, REQ_DUMP_CONNECTIONS, c->name, c->hostname, c->options, c->socket, bitfield_to_int(&c->status, sizeof c->status)); diff --git a/src/connection.h b/src/connection.h index 26aa3f0..01c2bf4 100644 --- a/src/connection.h +++ b/src/connection.h @@ -1,6 +1,6 @@ /* connection.h -- header for connection.c - Copyright (C) 2000-2010 Guus Sliepen , + Copyright (C) 2000-2012 Guus Sliepen , 2000-2005 Ivo Timmermans This program is free software; you can redistribute it and/or modify @@ -25,81 +25,83 @@ #include "cipher.h" #include "digest.h" #include "rsa.h" -#include "splay_tree.h" +#include "list.h" +#include "sptps.h" -#define OPTION_INDIRECT 0x0001 -#define OPTION_TCPONLY 0x0002 -#define OPTION_PMTU_DISCOVERY 0x0004 -#define OPTION_CLAMP_MSS 0x0008 +#define OPTION_INDIRECT 0x0001 +#define OPTION_TCPONLY 0x0002 +#define OPTION_PMTU_DISCOVERY 0x0004 +#define OPTION_CLAMP_MSS 0x0008 +#define OPTION_VERSION(x) ((x) >> 24) /* Top 8 bits are for protocol minor version */ typedef struct connection_status_t { - unsigned int pinged:1; /* sent ping */ - unsigned int active:1; /* 1 if active.. */ - unsigned int connecting:1; /* 1 if we are waiting for a non-blocking connect() to finish */ - unsigned int termreq:1; /* the termination of this connection was requested */ - unsigned int remove_unused:1; /* Set to 1 if you want this connection removed */ - unsigned int timeout_unused:1; /* 1 if gotten timeout */ - unsigned int encryptout:1; /* 1 if we can encrypt outgoing traffic */ - unsigned int decryptin:1; /* 1 if we have to decrypt incoming traffic */ - unsigned int mst:1; /* 1 if this connection is part of a minimum spanning tree */ - unsigned int control:1; - unsigned int pcap:1; - unsigned int unused:21; + unsigned int pinged:1; /* sent ping */ + unsigned int active:1; /* 1 if active.. */ + unsigned int connecting:1; /* 1 if we are waiting for a non-blocking connect() to finish */ + unsigned int unused_termreq:1; /* the termination of this connection was requested */ + unsigned int remove_unused:1; /* Set to 1 if you want this connection removed */ + unsigned int timeout_unused:1; /* 1 if gotten timeout */ + unsigned int encryptout:1; /* 1 if we can encrypt outgoing traffic */ + unsigned int decryptin:1; /* 1 if we have to decrypt incoming traffic */ + unsigned int mst:1; /* 1 if this connection is part of a minimum spanning tree */ + unsigned int control:1; /* 1 if this is a control connection */ + unsigned int pcap:1; /* 1 if this is a control connection requesting packet capture */ + unsigned int log:1; /* 1 if this is a control connection requesting log dump */ + unsigned int unused:20; } connection_status_t; -#include "ecdh.h" #include "ecdsa.h" #include "edge.h" #include "net.h" #include "node.h" typedef struct connection_t { - char *name; /* name he claims to have */ + char *name; /* name he claims to have */ - union sockaddr_t address; /* his real (internet) ip */ - char *hostname; /* the hostname of its real ip */ - int protocol_major; /* used protocol */ - int protocol_minor; /* used protocol */ + union sockaddr_t address; /* his real (internet) ip */ + char *hostname; /* the hostname of its real ip */ + int protocol_major; /* used protocol */ + int protocol_minor; /* used protocol */ - int socket; /* socket used for this connection */ - uint32_t options; /* options for this connection */ - connection_status_t status; /* status info */ - int estimated_weight; /* estimation for the weight of the edge for this connection */ - struct timeval start; /* time this connection was started, used for above estimation */ - struct outgoing_t *outgoing; /* used to keep track of outgoing connections */ + int socket; /* socket used for this connection */ + uint32_t options; /* options for this connection */ + connection_status_t status; /* status info */ + int estimated_weight; /* estimation for the weight of the edge for this connection */ + struct timeval start; /* time this connection was started, used for above estimation */ + struct outgoing_t *outgoing; /* used to keep track of outgoing connections */ - struct node_t *node; /* node associated with the other end */ - struct edge_t *edge; /* edge associated with this connection */ + struct node_t *node; /* node associated with the other end */ + struct edge_t *edge; /* edge associated with this connection */ - rsa_t rsa; /* his public RSA key */ - ecdsa_t ecdsa; /* his public ECDSA key */ - ecdsa_t ecdh; /* state for ECDH key exchange */ - cipher_t incipher; /* Cipher he will use to send data to us */ - cipher_t outcipher; /* Cipher we will use to send data to him */ + rsa_t rsa; /* his public RSA key */ + ecdsa_t ecdsa; /* his public ECDSA key */ + cipher_t incipher; /* Cipher he will use to send data to us */ + cipher_t outcipher; /* Cipher we will use to send data to him */ digest_t indigest; digest_t outdigest; + sptps_t sptps; int inmaclength; int outmaclength; int incompression; int outcompression; - char *hischallenge; /* The challenge we sent to him */ + char *hischallenge; /* The challenge we sent to him */ struct buffer_t inbuf; struct buffer_t outbuf; - struct event inevent; /* input event on this metadata connection */ - struct event outevent; /* output event on this metadata connection */ - int tcplen; /* length of incoming TCPpacket */ - int allow_request; /* defined if there's only one request possible */ + struct event inevent; /* input event on this metadata connection */ + struct event outevent; /* output event on this metadata connection */ + int tcplen; /* length of incoming TCPpacket */ + int allow_request; /* defined if there's only one request possible */ - time_t last_ping_time; /* last time we saw some activity from the other end or pinged them */ + time_t last_ping_time; /* last time we saw some activity from the other end or pinged them */ - splay_tree_t *config_tree; /* Pointer to configuration tree belonging to him */ + splay_tree_t *config_tree; /* Pointer to configuration tree belonging to him */ } connection_t; -extern splay_tree_t *connection_tree; -extern connection_t *broadcast; +extern list_t *connection_list; +extern connection_t *everyone; extern void init_connections(void); extern void exit_connections(void); @@ -109,4 +111,4 @@ extern void connection_add(connection_t *); extern void connection_del(connection_t *); extern bool dump_connections(struct connection_t *); -#endif /* __TINC_CONNECTION_H__ */ +#endif /* __TINC_CONNECTION_H__ */ diff --git a/src/control.c b/src/control.c index 86224c2..c166943 100644 --- a/src/control.c +++ b/src/control.c @@ -1,6 +1,6 @@ /* control.c -- Control socket handling. - Copyright (C) 2007 Guus Sliepen + Copyright (C) 2012 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 @@ -29,7 +29,6 @@ #include "netutl.h" #include "protocol.h" #include "route.h" -#include "splay_tree.h" #include "utils.h" #include "xalloc.h" @@ -44,16 +43,16 @@ static bool control_ok(connection_t *c, int type) { return control_return(c, type, 0); } -bool control_h(connection_t *c, char *request) { +bool control_h(connection_t *c, const char *request) { int type; if(!c->status.control || c->allow_request != CONTROL) { - logger(LOG_ERR, "Unauthorized control request from %s (%s)", c->name, c->hostname); + logger(DEBUG_ALWAYS, LOG_ERR, "Unauthorized control request from %s (%s)", c->name, c->hostname); return false; } if(sscanf(request, "%*d %d", &type) != 1) { - logger(LOG_ERR, "Got bad %s from %s (%s)", "CONTROL", c->name, c->hostname); + logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "CONTROL", c->name, c->hostname); return false; } @@ -64,7 +63,7 @@ bool control_h(connection_t *c, char *request) { case REQ_DUMP_NODES: return dump_nodes(c); - + case REQ_DUMP_EDGES: return dump_edges(c); @@ -93,22 +92,18 @@ bool control_h(connection_t *c, char *request) { return control_ok(c, REQ_RETRY); case REQ_RELOAD: - logger(LOG_NOTICE, "Got '%s' command", "reload"); + logger(DEBUG_ALWAYS, LOG_NOTICE, "Got '%s' command", "reload"); int result = reload_configuration(); return control_return(c, REQ_RELOAD, result); case REQ_DISCONNECT: { char name[MAX_STRING_SIZE]; - connection_t *other; - splay_node_t *node, *next; bool found = false; if(sscanf(request, "%*d %*d " MAX_STRING, name) != 1) return control_return(c, REQ_DISCONNECT, -1); - for(node = connection_tree->head; node; node = next) { - next = node->next; - other = node->data; + for list_each(connection_t, other, connection_list) { if(strcmp(other->name, name)) continue; terminate_connection(other, other->status.active); @@ -122,10 +117,17 @@ bool control_h(connection_t *c, char *request) { return dump_traffic(c); case REQ_PCAP: + sscanf(request, "%*d %*d %d", &c->outmaclength); c->status.pcap = true; pcap = true; return true; + case REQ_LOG: + sscanf(request, "%*d %*d %d", &c->outcompression); + c->status.log = true; + logcontrol = true; + return true; + default: return send_request(c, "%d %d", CONTROL, REQ_INVALID); } @@ -137,7 +139,7 @@ bool init_control(void) { FILE *f = fopen(pidfilename, "w"); if(!f) { - logger(LOG_ERR, "Cannot write control socket cookie file %s: %s", pidfilename, strerror(errno)); + logger(DEBUG_ALWAYS, LOG_ERR, "Cannot write control socket cookie file %s: %s", pidfilename, strerror(errno)); return false; } diff --git a/src/control_common.h b/src/control_common.h index 615e10a..cd54889 100644 --- a/src/control_common.h +++ b/src/control_common.h @@ -1,6 +1,7 @@ /* control_protocol.h -- control socket protocol. - Copyright (C) 2007 Scott Lamb + Copyright (C) 2007 Scott Lamb + 2009-2012 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 @@ -39,6 +40,7 @@ enum request_type { REQ_DISCONNECT, REQ_DUMP_TRAFFIC, REQ_PCAP, + REQ_LOG, }; #define TINC_CTL_VERSION_CURRENT 0 diff --git a/src/crypto.c b/src/crypto.c new file mode 100644 index 0000000..c695be8 --- /dev/null +++ b/src/crypto.c @@ -0,0 +1,43 @@ +/* + crypto.c -- Cryptographic miscellaneous functions and initialisation + Copyright (C) 2007 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "system.h" + +#include +#include +#include + +#include "crypto.h" + +void crypto_init(void) { + RAND_load_file("/dev/urandom", 1024); + + ENGINE_load_builtin_engines(); + ENGINE_register_all_complete(); + + OpenSSL_add_all_algorithms(); +} + +void crypto_exit(void) { + EVP_cleanup(); +} + +void randomize(void *out, size_t outlen) { + RAND_pseudo_bytes(out, outlen); +} diff --git a/src/cygwin/device.c b/src/cygwin/device.c index a4ab938..6266e87 100644 --- a/src/cygwin/device.c +++ b/src/cygwin/device.c @@ -1,7 +1,7 @@ /* device.c -- Interaction with Windows tap driver in a Cygwin environment Copyright (C) 2002-2005 Ivo Timmermans, - 2002-2009 Guus Sliepen + 2002-2012 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 @@ -45,7 +45,7 @@ static uint64_t device_total_out = 0; static pid_t reader_pid; static int sp[2]; -bool setup_device(void) { +static bool setup_device(void) { HKEY key, key2; int i, err; @@ -64,7 +64,7 @@ bool setup_device(void) { /* Open registry and look for network adapters */ if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, NETWORK_CONNECTIONS_KEY, 0, KEY_READ, &key)) { - logger(LOG_ERR, "Unable to read registry: %s", winerror(GetLastError())); + logger(DEBUG_ALWAYS, LOG_ERR, "Unable to read registry: %s", winerror(GetLastError())); return false; } @@ -77,7 +77,7 @@ bool setup_device(void) { snprintf(regpath, sizeof regpath, "%s\\%s\\Connection", NETWORK_CONNECTIONS_KEY, adapterid); - if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, regpath, 0, KEY_READ, &key2)) + if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, regpath, 0, KEY_READ, &key2)) continue; len = sizeof adaptername; @@ -116,7 +116,7 @@ bool setup_device(void) { RegCloseKey(key); if(!found) { - logger(LOG_ERR, "No Windows tap device found!"); + logger(DEBUG_ALWAYS, LOG_ERR, "No Windows tap device found!"); return false; } @@ -127,22 +127,22 @@ bool setup_device(void) { iface = xstrdup(adaptername); snprintf(tapname, sizeof tapname, USERMODEDEVICEDIR "%s" TAPSUFFIX, device); - + /* Now we are going to open this device twice: once for reading and once for writing. We do this because apparently it isn't possible to check for activity in the select() loop. Furthermore I don't really know how to do it the "Windows" way. */ if(socketpair(AF_UNIX, SOCK_DGRAM, PF_UNIX, sp)) { - logger(LOG_DEBUG, "System call `%s' failed: %s", "socketpair", strerror(errno)); + logger(DEBUG_ALWAYS, LOG_DEBUG, "System call `%s' failed: %s", "socketpair", strerror(errno)); return false; } /* The parent opens the tap device for writing. */ - + device_handle = CreateFile(tapname, GENERIC_WRITE, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM , 0); - + if(device_handle == INVALID_HANDLE_VALUE) { - logger(LOG_ERR, "Could not open Windows tap device %s (%s) for writing: %s", device, iface, winerror(GetLastError())); + logger(DEBUG_ALWAYS, LOG_ERR, "Could not open Windows tap device %s (%s) for writing: %s", device, iface, winerror(GetLastError())); return false; } @@ -151,7 +151,7 @@ bool setup_device(void) { /* Get MAC address from tap device */ if(!DeviceIoControl(device_handle, TAP_IOCTL_GET_MAC, mymac.x, sizeof mymac.x, mymac.x, sizeof mymac.x, &len, 0)) { - logger(LOG_ERR, "Could not get MAC address from Windows tap device %s (%s): %s", device, iface, winerror(GetLastError())); + logger(DEBUG_ALWAYS, LOG_ERR, "Could not get MAC address from Windows tap device %s (%s): %s", device, iface, winerror(GetLastError())); return false; } @@ -164,14 +164,14 @@ bool setup_device(void) { reader_pid = fork(); if(reader_pid == -1) { - logger(LOG_DEBUG, "System call `%s' failed: %s", "fork", strerror(errno)); + logger(DEBUG_ALWAYS, LOG_DEBUG, "System call `%s' failed: %s", "fork", strerror(errno)); return false; } if(!reader_pid) { /* The child opens the tap device for reading, blocking. It passes everything it reads to the socket. */ - + char buf[MTU]; long inlen; @@ -180,13 +180,13 @@ bool setup_device(void) { device_handle = CreateFile(tapname, GENERIC_READ, FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM, 0); if(device_handle == INVALID_HANDLE_VALUE) { - logger(LOG_ERR, "Could not open Windows tap device %s (%s) for reading: %s", device, iface, winerror(GetLastError())); + logger(DEBUG_ALWAYS, LOG_ERR, "Could not open Windows tap device %s (%s) for reading: %s", device, iface, winerror(GetLastError())); buf[0] = 0; write(sp[1], buf, 1); exit(1); } - logger(LOG_DEBUG, "Tap reader forked and running."); + logger(DEBUG_ALWAYS, LOG_DEBUG, "Tap reader forked and running."); /* Notify success */ @@ -203,18 +203,18 @@ bool setup_device(void) { read(device_fd, &gelukt, 1); if(gelukt != 1) { - logger(LOG_DEBUG, "Tap reader failed!"); + logger(DEBUG_ALWAYS, LOG_DEBUG, "Tap reader failed!"); return false; } device_info = "Windows tap device"; - logger(LOG_INFO, "%s (%s) is a %s", device, iface, device_info); + logger(DEBUG_ALWAYS, LOG_INFO, "%s (%s) is a %s", device, iface, device_info); return true; } -void close_device(void) { +static void close_device(void) { close(sp[0]); close(sp[1]); CloseHandle(device_handle); @@ -225,33 +225,33 @@ void close_device(void) { free(iface); } -bool read_packet(vpn_packet_t *packet) { +static bool read_packet(vpn_packet_t *packet) { int inlen; if((inlen = read(sp[0], packet->data, MTU)) <= 0) { - logger(LOG_ERR, "Error while reading from %s %s: %s", device_info, + logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info, device, strerror(errno)); return false; } - + packet->len = inlen; device_total_in += packet->len; - ifdebug(TRAFFIC) logger(LOG_DEBUG, "Read packet of %d bytes from %s", packet->len, + logger(DEBUG_TRAFFIC, LOG_DEBUG, "Read packet of %d bytes from %s", packet->len, device_info); return true; } -bool write_packet(vpn_packet_t *packet) { +static bool write_packet(vpn_packet_t *packet) { long outlen; - ifdebug(TRAFFIC) logger(LOG_DEBUG, "Writing packet of %d bytes to %s", + logger(DEBUG_TRAFFIC, LOG_DEBUG, "Writing packet of %d bytes to %s", packet->len, device_info); if(!WriteFile (device_handle, packet->data, packet->len, &outlen, NULL)) { - logger(LOG_ERR, "Error while writing to %s %s: %s", device_info, device, winerror(GetLastError())); + logger(DEBUG_ALWAYS, LOG_ERR, "Error while writing to %s %s: %s", device_info, device, winerror(GetLastError())); return false; } @@ -260,8 +260,16 @@ bool write_packet(vpn_packet_t *packet) { return true; } -void dump_device_stats(void) { - logger(LOG_DEBUG, "Statistics for %s %s:", device_info, device); - logger(LOG_DEBUG, " total bytes in: %10"PRIu64, device_total_in); - logger(LOG_DEBUG, " total bytes out: %10"PRIu64, device_total_out); +static void dump_device_stats(void) { + logger(DEBUG_ALWAYS, LOG_DEBUG, "Statistics for %s %s:", device_info, device); + logger(DEBUG_ALWAYS, LOG_DEBUG, " total bytes in: %10"PRIu64, device_total_in); + logger(DEBUG_ALWAYS, LOG_DEBUG, " total bytes out: %10"PRIu64, device_total_out); } + +const devops_t os_devops = { + .setup = setup_device, + .close = close_device, + .read = read_packet, + .write = write_packet, + .dump_stats = dump_device_stats, +}; diff --git a/src/device.h b/src/device.h index 16a2486..c91f035 100644 --- a/src/device.h +++ b/src/device.h @@ -1,7 +1,7 @@ /* - net.h -- generic header for device.c + device.h -- generic header for device.c Copyright (C) 2001-2005 Ivo Timmermans - 2001-2006 Guus Sliepen + 2001-2012 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 @@ -32,10 +32,20 @@ extern uint64_t device_in_bytes; extern uint64_t device_out_packets; extern uint64_t device_out_bytes; -extern bool setup_device(void); -extern void close_device(void); -extern bool read_packet(struct vpn_packet_t *); -extern bool write_packet(struct vpn_packet_t *); -extern void dump_device_stats(void); +typedef struct devops_t { + bool (*setup)(void); + void (*close)(void); + bool (*read)(struct vpn_packet_t *); + bool (*write)(struct vpn_packet_t *); + void (*dump_stats)(void); +} devops_t; -#endif /* __TINC_DEVICE_H__ */ +extern const devops_t os_devops; +extern const devops_t dummy_devops; +extern const devops_t raw_socket_devops; +extern const devops_t multicast_devops; +extern const devops_t uml_devops; +extern const devops_t vde_devops; +extern devops_t devops; + +#endif /* __TINC_DEVICE_H__ */ diff --git a/src/digest.c b/src/digest.c new file mode 100644 index 0000000..79db491 --- /dev/null +++ b/src/digest.c @@ -0,0 +1,127 @@ +/* + digest.c -- Digest handling + Copyright (C) 2007-2012 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "system.h" +#include "utils.h" +#include "xalloc.h" + +#include +#include + +#include "digest.h" +#include "logger.h" + +static void set_maclength(digest_t *digest, int maclength) { + int digestlen = EVP_MD_size(digest->digest); + + if(maclength > digestlen || maclength < 0) + digest->maclength = digestlen; + else + digest->maclength = maclength; +} + +bool digest_open_by_name(digest_t *digest, const char *name, int maclength) { + digest->digest = EVP_get_digestbyname(name); + digest->key = NULL; + + if(!digest->digest) { + logger(DEBUG_ALWAYS, LOG_DEBUG, "Unknown digest name '%s'!", name); + return false; + } + + set_maclength(digest, maclength); + return true; +} + +bool digest_open_by_nid(digest_t *digest, int nid, int maclength) { + digest->digest = EVP_get_digestbynid(nid); + digest->key = NULL; + + if(!digest->digest) { + logger(DEBUG_ALWAYS, LOG_DEBUG, "Unknown digest nid %d!", nid); + return false; + } + + set_maclength(digest, maclength); + return true; +} + +bool digest_open_sha1(digest_t *digest, int maclength) { + digest->digest = EVP_sha1(); + digest->key = NULL; + + set_maclength(digest, maclength); + return true; +} + +bool digest_set_key(digest_t *digest, const void *key, size_t len) { + digest->key = xrealloc(digest->key, len); + memcpy(digest->key, key, len); + digest->keylength = len; + return true; +} + +void digest_close(digest_t *digest) { + free(digest->key); + digest->key = NULL; +} + +bool digest_create(digest_t *digest, const void *indata, size_t inlen, void *outdata) { + size_t len = EVP_MD_size(digest->digest); + unsigned char tmpdata[len]; + + if(digest->key) { + HMAC(digest->digest, digest->key, digest->keylength, indata, inlen, tmpdata, NULL); + } else { + EVP_MD_CTX ctx; + + if(!EVP_DigestInit(&ctx, digest->digest) + || !EVP_DigestUpdate(&ctx, indata, inlen) + || !EVP_DigestFinal(&ctx, tmpdata, NULL)) { + logger(DEBUG_ALWAYS, LOG_DEBUG, "Error creating digest: %s", ERR_error_string(ERR_get_error(), NULL)); + return false; + } + } + + memcpy(outdata, tmpdata, digest->maclength); + return true; +} + +bool digest_verify(digest_t *digest, const void *indata, size_t inlen, const void *cmpdata) { + size_t len = digest->maclength; + unsigned char outdata[len]; + + return digest_create(digest, indata, inlen, outdata) && !memcmp(cmpdata, outdata, digest->maclength); +} + +int digest_get_nid(const digest_t *digest) { + return digest->digest ? digest->digest->type : 0; +} + +size_t digest_keylength(const digest_t *digest) { + return digest->digest->md_size; +} + +size_t digest_length(const digest_t *digest) { + return digest->maclength; +} + +bool digest_active(const digest_t *digest) { + return digest->digest && digest->digest->type != 0; +} diff --git a/src/dropin.c b/src/dropin.c index eb17aca..f1a51ac 100644 --- a/src/dropin.c +++ b/src/dropin.c @@ -25,7 +25,7 @@ #ifndef HAVE_DAEMON /* Replacement for the daemon() function. - + The daemon() function is for programs wishing to detach themselves from the controlling terminal and run in the background as system daemons. @@ -104,14 +104,14 @@ char *get_current_dir_name(void) { size = 100; buf = xmalloc(size); - errno = 0; /* Success */ + errno = 0; /* Success */ r = getcwd(buf, size); /* getcwd returns NULL and sets errno to ERANGE if the bufferspace is insufficient to contain the entire working directory. */ while(r == NULL && errno == ERANGE) { free(buf); - size <<= 1; /* double the size */ + size <<= 1; /* double the size */ buf = xmalloc(size); r = getcwd(buf, size); } diff --git a/src/dropin.h b/src/dropin.h index 3617b70..c6cabba 100644 --- a/src/dropin.h +++ b/src/dropin.h @@ -45,4 +45,4 @@ extern int gettimeofday(struct timeval *, void *); extern int usleep(long long usec); #endif -#endif /* __DROPIN_H__ */ +#endif /* __DROPIN_H__ */ diff --git a/src/dummy_device.c b/src/dummy_device.c new file mode 100644 index 0000000..d508180 --- /dev/null +++ b/src/dummy_device.c @@ -0,0 +1,62 @@ +/* + device.c -- Dummy device + Copyright (C) 2011-2012 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "system.h" + +#include "device.h" +#include "logger.h" +#include "net.h" + +static char *device_info = "dummy device"; + +static uint64_t device_total_in = 0; +static uint64_t device_total_out = 0; + +static bool setup_device(void) { + device = "dummy"; + iface = "dummy"; + logger(DEBUG_ALWAYS, LOG_INFO, "%s (%s) is a %s", device, iface, device_info); + return true; +} + +static void close_device(void) { +} + +static bool read_packet(vpn_packet_t *packet) { + return false; +} + +static bool write_packet(vpn_packet_t *packet) { + device_total_out += packet->len; + return true; +} + +static void dump_device_stats(void) { + logger(DEBUG_ALWAYS, LOG_DEBUG, "Statistics for %s %s:", device_info, device); + logger(DEBUG_ALWAYS, LOG_DEBUG, " total bytes in: %10"PRIu64, device_total_in); + logger(DEBUG_ALWAYS, LOG_DEBUG, " total bytes out: %10"PRIu64, device_total_out); +} + +const devops_t dummy_devops = { + .setup = setup_device, + .close = close_device, + .read = read_packet, + .write = write_packet, + .dump_stats = dump_device_stats, +}; diff --git a/src/ecdh.c b/src/ecdh.c new file mode 100644 index 0000000..f94555d --- /dev/null +++ b/src/ecdh.c @@ -0,0 +1,96 @@ +/* + ecdh.c -- Diffie-Hellman key exchange handling + Copyright (C) 2011-2012 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "system.h" +#include "utils.h" +#include "xalloc.h" + +#include +#include +#include + +#include "ecdh.h" +#include "logger.h" + +bool ecdh_generate_public(ecdh_t *ecdh, void *pubkey) { + *ecdh = EC_KEY_new_by_curve_name(NID_secp521r1); + if(!*ecdh) { + logger(DEBUG_ALWAYS, LOG_ERR, "Generating EC key_by_curve_name failed: %s", ERR_error_string(ERR_get_error(), NULL)); + return false; + } + + if(!EC_KEY_generate_key(*ecdh)) { + EC_KEY_free(*ecdh); + *ecdh = NULL; + logger(DEBUG_ALWAYS, LOG_ERR, "Generating EC key failed: %s", ERR_error_string(ERR_get_error(), NULL)); + return false; + } + + const EC_POINT *point = EC_KEY_get0_public_key(*ecdh); + if(!point) { + EC_KEY_free(*ecdh); + *ecdh = NULL; + logger(DEBUG_ALWAYS, LOG_ERR, "Getting public key failed: %s", ERR_error_string(ERR_get_error(), NULL)); + return false; + } + + size_t result = EC_POINT_point2oct(EC_KEY_get0_group(*ecdh), point, POINT_CONVERSION_COMPRESSED, pubkey, ECDH_SIZE, NULL); + if(!result) { + EC_KEY_free(*ecdh); + *ecdh = NULL; + logger(DEBUG_ALWAYS, LOG_ERR, "Converting EC_POINT to binary failed: %s", ERR_error_string(ERR_get_error(), NULL)); + return false; + } + + return true; +} + +bool ecdh_compute_shared(ecdh_t *ecdh, const void *pubkey, void *shared) { + EC_POINT *point = EC_POINT_new(EC_KEY_get0_group(*ecdh)); + if(!point) { + logger(DEBUG_ALWAYS, LOG_ERR, "EC_POINT_new() failed: %s", ERR_error_string(ERR_get_error(), NULL)); + return false; + } + + int result = EC_POINT_oct2point(EC_KEY_get0_group(*ecdh), point, pubkey, ECDH_SIZE, NULL); + if(!result) { + EC_POINT_free(point); + logger(DEBUG_ALWAYS, LOG_ERR, "Converting binary to EC_POINT failed: %s", ERR_error_string(ERR_get_error(), NULL)); + return false; + } + + result = ECDH_compute_key(shared, ECDH_SIZE, point, *ecdh, NULL); + EC_POINT_free(point); + EC_KEY_free(*ecdh); + *ecdh = NULL; + + if(!result) { + logger(DEBUG_ALWAYS, LOG_ERR, "Computing Elliptic Curve Diffie-Hellman shared key failed: %s", ERR_error_string(ERR_get_error(), NULL)); + return false; + } + + return true; +} + +void ecdh_free(ecdh_t *ecdh) { + if(*ecdh) { + EC_KEY_free(*ecdh); + *ecdh = NULL; + } +} diff --git a/src/ecdsa.c b/src/ecdsa.c new file mode 100644 index 0000000..e2af6f9 --- /dev/null +++ b/src/ecdsa.c @@ -0,0 +1,130 @@ +/* + ecdsa.c -- ECDSA key handling + Copyright (C) 2011-2012 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "system.h" + +#include +#include + +#include "logger.h" +#include "ecdsa.h" +#include "utils.h" + +// Get and set ECDSA keys +// +bool ecdsa_set_base64_public_key(ecdsa_t *ecdsa, const char *p) { + *ecdsa = EC_KEY_new_by_curve_name(NID_secp521r1); + if(!*ecdsa) { + logger(DEBUG_ALWAYS, LOG_DEBUG, "EC_KEY_new_by_curve_name failed: %s", ERR_error_string(ERR_get_error(), NULL)); + return false; + } + + int len = strlen(p); + unsigned char pubkey[len / 4 * 3 + 3]; + const unsigned char *ppubkey = pubkey; + len = b64decode(p, (char *)pubkey, len); + + if(!o2i_ECPublicKey(ecdsa, &ppubkey, len)) { + logger(DEBUG_ALWAYS, LOG_DEBUG, "o2i_ECPublicKey failed: %s", ERR_error_string(ERR_get_error(), NULL)); + return false; + } + + return true; +} + +char *ecdsa_get_base64_public_key(ecdsa_t *ecdsa) { + unsigned char *pubkey = NULL; + int len = i2o_ECPublicKey(*ecdsa, &pubkey); + + char *base64 = malloc(len * 4 / 3 + 5); + b64encode((char *)pubkey, base64, len); + + free(pubkey); + + return base64; +} + +// Read PEM ECDSA keys + +bool ecdsa_read_pem_public_key(ecdsa_t *ecdsa, FILE *fp) { + *ecdsa = PEM_read_EC_PUBKEY(fp, ecdsa, NULL, NULL); + + if(*ecdsa) + return true; + + logger(DEBUG_ALWAYS, LOG_ERR, "Unable to read ECDSA public key: %s", ERR_error_string(ERR_get_error(), NULL)); + return false; +} + +bool ecdsa_read_pem_private_key(ecdsa_t *ecdsa, FILE *fp) { + *ecdsa = PEM_read_ECPrivateKey(fp, NULL, NULL, NULL); + + if(*ecdsa) + return true; + + logger(DEBUG_ALWAYS, LOG_ERR, "Unable to read ECDSA private key: %s", ERR_error_string(ERR_get_error(), NULL)); + return false; +} + +size_t ecdsa_size(ecdsa_t *ecdsa) { + return ECDSA_size(*ecdsa); +} + +// TODO: standardise output format? + +bool ecdsa_sign(ecdsa_t *ecdsa, const void *in, size_t len, void *sig) { + unsigned int siglen = ECDSA_size(*ecdsa); + + unsigned char hash[SHA512_DIGEST_LENGTH]; + SHA512(in, len, hash); + + memset(sig, 0, siglen); + + if(!ECDSA_sign(0, hash, sizeof hash, sig, &siglen, *ecdsa)) { + logger(DEBUG_ALWAYS, LOG_DEBUG, "ECDSA_sign() failed: %s", ERR_error_string(ERR_get_error(), NULL)); + return false; + } + + return true; +} + +bool ecdsa_verify(ecdsa_t *ecdsa, const void *in, size_t len, const void *sig) { + unsigned int siglen = ECDSA_size(*ecdsa); + + unsigned char hash[SHA512_DIGEST_LENGTH]; + SHA512(in, len, hash); + + if(!ECDSA_verify(0, hash, sizeof hash, sig, siglen, *ecdsa)) { + logger(DEBUG_ALWAYS, LOG_DEBUG, "ECDSA_verify() failed: %s", ERR_error_string(ERR_get_error(), NULL)); + return false; + } + + return true; +} + +bool ecdsa_active(ecdsa_t *ecdsa) { + return *ecdsa; +} + +void ecdsa_free(ecdsa_t *ecdsa) { + if(*ecdsa) { + EC_KEY_free(*ecdsa); + *ecdsa = NULL; + } +} diff --git a/src/edge.c b/src/edge.c index f5aa099..fd03327 100644 --- a/src/edge.c +++ b/src/edge.c @@ -1,6 +1,6 @@ /* edge.c -- edge tree management - Copyright (C) 2000-2006 Guus Sliepen , + Copyright (C) 2000-2012 Guus Sliepen , 2000-2005 Ivo Timmermans This program is free software; you can redistribute it and/or modify @@ -29,7 +29,7 @@ #include "utils.h" #include "xalloc.h" -splay_tree_t *edge_weight_tree; /* Tree with all edges, sorted on weight */ +splay_tree_t *edge_weight_tree; static int edge_compare(const edge_t *a, const edge_t *b) { return strcmp(a->to->name, b->to->name); @@ -99,7 +99,7 @@ void edge_del(edge_t *e) { edge_t *lookup_edge(node_t *from, node_t *to) { edge_t v; - + v.from = from; v.to = to; @@ -107,17 +107,10 @@ edge_t *lookup_edge(node_t *from, node_t *to) { } bool dump_edges(connection_t *c) { - splay_node_t *node, *node2; - node_t *n; - edge_t *e; - char *address; - - for(node = node_tree->head; node; node = node->next) { - n = node->data; - for(node2 = n->edge_tree->head; node2; node2 = node2->next) { - e = node2->data; - address = sockaddr2hostname(&e->address); - send_request(c, "%d %d %s to %s at %s options %x weight %d", + for splay_each(node_t, n, node_tree) { + for splay_each(edge_t, e, n->edge_tree) { + char *address = sockaddr2hostname(&e->address); + send_request(c, "%d %d %s %s %s %x %d", CONTROL, REQ_DUMP_EDGES, e->from->name, e->to->name, address, e->options, e->weight); diff --git a/src/edge.h b/src/edge.h index ea45f49..cbd9e5a 100644 --- a/src/edge.h +++ b/src/edge.h @@ -1,6 +1,6 @@ /* edge.h -- header for edge.c - Copyright (C) 2001-2006 Guus Sliepen , + Copyright (C) 2001-2012 Guus Sliepen , 2001-2005 Ivo Timmermans This program is free software; you can redistribute it and/or modify @@ -31,14 +31,14 @@ typedef struct edge_t { struct node_t *to; sockaddr_t address; - uint32_t options; /* options turned on for this edge */ - int weight; /* weight of this edge */ + uint32_t options; /* options turned on for this edge */ + int weight; /* weight of this edge */ - struct connection_t *connection; /* connection associated with this edge, if available */ - struct edge_t *reverse; /* edge in the opposite direction, if available */ + struct connection_t *connection; /* connection associated with this edge, if available */ + struct edge_t *reverse; /* edge in the opposite direction, if available */ } edge_t; -extern splay_tree_t *edge_weight_tree; /* Tree with all known edges sorted on weight */ +extern splay_tree_t *edge_weight_tree; /* Tree with all known edges sorted on weight */ extern void init_edges(void); extern void exit_edges(void); @@ -51,4 +51,4 @@ extern void edge_del(edge_t *); extern edge_t *lookup_edge(struct node_t *, struct node_t *); extern bool dump_edges(struct connection_t *); -#endif /* __TINC_EDGE_H__ */ +#endif /* __TINC_EDGE_H__ */ diff --git a/src/ethernet.h b/src/ethernet.h index eef5f42..b759ab3 100644 --- a/src/ethernet.h +++ b/src/ethernet.h @@ -54,17 +54,17 @@ struct arphdr { uint16_t ar_hrd; uint16_t ar_pro; uint8_t ar_hln; - uint8_t ar_pln; - uint16_t ar_op; + uint8_t ar_pln; + uint16_t ar_op; } __attribute__ ((__packed__)); -#define ARPOP_REQUEST 1 -#define ARPOP_REPLY 2 -#define ARPOP_RREQUEST 3 -#define ARPOP_RREPLY 4 -#define ARPOP_InREQUEST 8 -#define ARPOP_InREPLY 9 -#define ARPOP_NAK 10 +#define ARPOP_REQUEST 1 +#define ARPOP_REPLY 2 +#define ARPOP_RREQUEST 3 +#define ARPOP_RREPLY 4 +#define ARPOP_InREQUEST 8 +#define ARPOP_InREPLY 9 +#define ARPOP_NAK 10 #endif #ifndef HAVE_STRUCT_ETHER_ARP diff --git a/src/fake-gai-errnos.h b/src/fake-gai-errnos.h index 4ffabb6..33913eb 100644 --- a/src/fake-gai-errnos.h +++ b/src/fake-gai-errnos.h @@ -7,13 +7,13 @@ /* for old netdb.h */ #ifndef EAI_NODATA -#define EAI_NODATA 1 +#define EAI_NODATA 1 #endif #ifndef EAI_MEMORY -#define EAI_MEMORY 2 +#define EAI_MEMORY 2 #endif #ifndef EAI_FAMILY -#define EAI_FAMILY 3 +#define EAI_FAMILY 3 #endif diff --git a/src/fake-getaddrinfo.c b/src/fake-getaddrinfo.c index df3d347..db50f73 100644 --- a/src/fake-getaddrinfo.c +++ b/src/fake-getaddrinfo.c @@ -29,7 +29,7 @@ char *gai_strerror(int ecode) { default: return "Unknown error"; } -} +} #endif /* !HAVE_GAI_STRERROR */ #if !HAVE_DECL_FREEADDRINFO @@ -49,14 +49,14 @@ static struct addrinfo *malloc_ai(uint16_t port, uint32_t addr) { struct addrinfo *ai; ai = xmalloc_and_zero(sizeof(struct addrinfo) + sizeof(struct sockaddr_in)); - + ai->ai_addr = (struct sockaddr *)(ai + 1); ai->ai_addrlen = sizeof(struct sockaddr_in); ai->ai_addr->sa_family = ai->ai_family = AF_INET; ((struct sockaddr_in *)(ai)->ai_addr)->sin_port = port; ((struct sockaddr_in *)(ai)->ai_addr)->sin_addr.s_addr = addr; - + return ai; } @@ -77,12 +77,12 @@ int getaddrinfo(const char *hostname, const char *servname, const struct addrinf *res = malloc_ai(port, htonl(0x00000000)); return 0; } - + if (!hostname) { *res = malloc_ai(port, htonl(0x7f000001)); return 0; } - + hp = gethostbyname(hostname); if(!hp || !hp->h_addr_list || !hp->h_addr_list[0]) diff --git a/src/fake-getaddrinfo.h b/src/fake-getaddrinfo.h index 5af7491..5809985 100644 --- a/src/fake-getaddrinfo.h +++ b/src/fake-getaddrinfo.h @@ -15,25 +15,24 @@ #endif #ifndef AI_NUMERICHOST -#define AI_NUMERICHOST 4 +#define AI_NUMERICHOST 4 #endif #ifndef HAVE_STRUCT_ADDRINFO struct addrinfo { - int ai_flags; /* AI_PASSIVE, AI_CANONNAME */ - int ai_family; /* PF_xxx */ - int ai_socktype; /* SOCK_xxx */ - int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */ - size_t ai_addrlen; /* length of ai_addr */ - char *ai_canonname; /* canonical name for hostname */ - struct sockaddr *ai_addr; /* binary address */ - struct addrinfo *ai_next; /* next structure in linked list */ + int ai_flags; /* AI_PASSIVE, AI_CANONNAME */ + int ai_family; /* PF_xxx */ + int ai_socktype; /* SOCK_xxx */ + int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */ + size_t ai_addrlen; /* length of ai_addr */ + char *ai_canonname; /* canonical name for hostname */ + struct sockaddr *ai_addr; /* binary address */ + struct addrinfo *ai_next; /* next structure in linked list */ }; #endif /* !HAVE_STRUCT_ADDRINFO */ #if !HAVE_DECL_GETADDRINFO -int getaddrinfo(const char *hostname, const char *servname, - const struct addrinfo *hints, struct addrinfo **res); +int getaddrinfo(const char *hostname, const char *servname, const struct addrinfo *hints, struct addrinfo **res); #endif /* !HAVE_GETADDRINFO */ #if !HAVE_DECL_GAI_STRERROR diff --git a/src/fake-getnameinfo.c b/src/fake-getnameinfo.c index 1eba492..4a4d132 100644 --- a/src/fake-getnameinfo.c +++ b/src/fake-getnameinfo.c @@ -41,10 +41,10 @@ int getnameinfo(const struct sockaddr *sa, size_t salen, char *host, size_t host } hp = gethostbyaddr((char *)&sin->sin_addr, sizeof(struct in_addr), AF_INET); - + if(!hp || !hp->h_name || !hp->h_name[0]) return EAI_NODATA; - + len = snprintf(host, hostlen, "%s", hp->h_name); if(len < 0 || len >= hostlen) return EAI_MEMORY; diff --git a/src/fake-getnameinfo.h b/src/fake-getnameinfo.h index 4389a8f..043ed97 100644 --- a/src/fake-getnameinfo.h +++ b/src/fake-getnameinfo.h @@ -2,8 +2,7 @@ #define _FAKE_GETNAMEINFO_H #if !HAVE_DECL_GETNAMEINFO -int getnameinfo(const struct sockaddr *sa, size_t salen, char *host, - size_t hostlen, char *serv, size_t servlen, int flags); +int getnameinfo(const struct sockaddr *sa, size_t salen, char *host, size_t hostlen, char *serv, size_t servlen, int flags); #endif /* !HAVE_GETNAMEINFO */ #ifndef NI_MAXSERV diff --git a/src/gcrypt/cipher.c b/src/gcrypt/cipher.c index 6a2cc5a..e9b32cf 100644 --- a/src/gcrypt/cipher.c +++ b/src/gcrypt/cipher.c @@ -1,6 +1,6 @@ /* cipher.c -- Symmetric block cipher handling - Copyright (C) 2007 Guus Sliepen + Copyright (C) 2007-2012 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 @@ -97,12 +97,12 @@ static bool cipher_open(cipher_t *cipher, int algo, int mode) { gcry_error_t err; if(!ciphertonid(algo, mode, &cipher->nid)) { - logger(LOG_DEBUG, "Cipher %d mode %d has no corresponding nid!", algo, mode); + logger(DEBUG_ALWAYS, LOG_DEBUG, "Cipher %d mode %d has no corresponding nid!", algo, mode); return false; } if((err = gcry_cipher_open(&cipher->handle, algo, mode, 0))) { - logger(LOG_DEBUG, "Unable to intialise cipher %d mode %d: %s", algo, mode, gcry_strerror(err)); + logger(DEBUG_ALWAYS, LOG_DEBUG, "Unable to intialise cipher %d mode %d: %s", algo, mode, gcry_strerror(err)); return false; } @@ -118,7 +118,7 @@ bool cipher_open_by_name(cipher_t *cipher, const char *name) { int algo, mode; if(!nametocipher(name, &algo, &mode)) { - logger(LOG_DEBUG, "Unknown cipher name '%s'!", name); + logger(DEBUG_ALWAYS, LOG_DEBUG, "Unknown cipher name '%s'!", name); return false; } @@ -129,7 +129,7 @@ bool cipher_open_by_nid(cipher_t *cipher, int nid) { int algo, mode; if(!nidtocipher(nid, &algo, &mode)) { - logger(LOG_DEBUG, "Unknown cipher ID %d!", nid); + logger(DEBUG_ALWAYS, LOG_DEBUG, "Unknown cipher ID %d!", nid); return false; } @@ -199,7 +199,7 @@ bool cipher_encrypt(cipher_t *cipher, const void *indata, size_t inlen, void *ou size_t reqlen = ((inlen + cipher->blklen) / cipher->blklen) * cipher->blklen; if(*outlen < reqlen) { - logger(LOG_ERR, "Error while encrypting: not enough room for padding"); + logger(DEBUG_ALWAYS, LOG_ERR, "Error while encrypting: not enough room for padding"); return false; } @@ -212,18 +212,18 @@ bool cipher_encrypt(cipher_t *cipher, const void *indata, size_t inlen, void *ou else pad[i] = padbyte; } - + if(oneshot) gcry_cipher_setiv(cipher->handle, cipher->key + cipher->keylen, cipher->blklen); if((err = gcry_cipher_encrypt(cipher->handle, outdata, *outlen, indata, inlen))) { - logger(LOG_ERR, "Error while encrypting: %s", gcry_strerror(err)); + logger(DEBUG_ALWAYS, LOG_ERR, "Error while encrypting: %s", gcry_strerror(err)); return false; } if(cipher->padding) { if((err = gcry_cipher_encrypt(cipher->handle, outdata + inlen, cipher->blklen, pad, cipher->blklen))) { - logger(LOG_ERR, "Error while encrypting: %s", gcry_strerror(err)); + logger(DEBUG_ALWAYS, LOG_ERR, "Error while encrypting: %s", gcry_strerror(err)); return false; } @@ -241,7 +241,7 @@ bool cipher_decrypt(cipher_t *cipher, const void *indata, size_t inlen, void *ou gcry_cipher_setiv(cipher->handle, cipher->key + cipher->keylen, cipher->blklen); if((err = gcry_cipher_decrypt(cipher->handle, outdata, *outlen, indata, inlen))) { - logger(LOG_ERR, "Error while decrypting: %s", gcry_strerror(err)); + logger(DEBUG_ALWAYS, LOG_ERR, "Error while decrypting: %s", gcry_strerror(err)); return false; } @@ -252,7 +252,7 @@ bool cipher_decrypt(cipher_t *cipher, const void *indata, size_t inlen, void *ou uint8_t padbyte = ((uint8_t *)outdata)[inlen - 1]; if(padbyte == 0 || padbyte > cipher->blklen || padbyte > inlen) { - logger(LOG_ERR, "Error while decrypting: invalid padding"); + logger(DEBUG_ALWAYS, LOG_ERR, "Error while decrypting: invalid padding"); return false; } @@ -260,7 +260,7 @@ bool cipher_decrypt(cipher_t *cipher, const void *indata, size_t inlen, void *ou for(int i = inlen - 1; i >= origlen; i--) if(((uint8_t *)outdata)[i] != padbyte) { - logger(LOG_ERR, "Error while decrypting: invalid padding"); + logger(DEBUG_ALWAYS, LOG_ERR, "Error while decrypting: invalid padding"); return false; } diff --git a/src/gcrypt/cipher.h b/src/gcrypt/cipher.h index 8e4a2eb..389bb11 100644 --- a/src/gcrypt/cipher.h +++ b/src/gcrypt/cipher.h @@ -1,6 +1,6 @@ /* cipher.h -- header file cipher.c - Copyright (C) 2007 Guus Sliepen + Copyright (C) 2007-2009 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 diff --git a/src/gcrypt/crypto.h b/src/gcrypt/crypto.h index 8047bfb..71df50c 100644 --- a/src/gcrypt/crypto.h +++ b/src/gcrypt/crypto.h @@ -1,6 +1,6 @@ /* crypto.h -- header for crypto.c - Copyright (C) 2007 Guus Sliepen + Copyright (C) 2007-2009 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 diff --git a/src/gcrypt/digest.c b/src/gcrypt/digest.c index 066600f..4229b0c 100644 --- a/src/gcrypt/digest.c +++ b/src/gcrypt/digest.c @@ -1,6 +1,6 @@ /* digest.c -- Digest handling - Copyright (C) 2007 Guus Sliepen + Copyright (C) 2007-2012 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 @@ -75,7 +75,7 @@ static bool digesttonid(int algo, int *nid) { static bool digest_open(digest_t *digest, int algo, int maclength) { if(!digesttonid(algo, &digest->nid)) { - logger(LOG_DEBUG, "Digest %d has no corresponding nid!", algo); + logger(DEBUG_ALWAYS, LOG_DEBUG, "Digest %d has no corresponding nid!", algo); return false; } @@ -85,7 +85,7 @@ static bool digest_open(digest_t *digest, int algo, int maclength) { digest->maclength = len; else digest->maclength = maclength; - + digest->algo = algo; digest->hmac = NULL; @@ -96,7 +96,7 @@ bool digest_open_by_name(digest_t *digest, const char *name, int maclength) { int algo; if(!nametodigest(name, &algo)) { - logger(LOG_DEBUG, "Unknown digest name '%s'!", name); + logger(DEBUG_ALWAYS, LOG_DEBUG, "Unknown digest name '%s'!", name); return false; } @@ -107,7 +107,7 @@ bool digest_open_by_nid(digest_t *digest, int nid, int maclength) { int algo; if(!nidtodigest(nid, &algo)) { - logger(LOG_DEBUG, "Unknown digest ID %d!", nid); + logger(DEBUG_ALWAYS, LOG_DEBUG, "Unknown digest ID %d!", nid); return false; } diff --git a/src/gcrypt/digest.h b/src/gcrypt/digest.h index 1188496..9f0d7d8 100644 --- a/src/gcrypt/digest.h +++ b/src/gcrypt/digest.h @@ -1,6 +1,6 @@ /* digest.h -- header file digest.c - Copyright (C) 2007 Guus Sliepen + Copyright (C) 2007-2009 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 diff --git a/src/gcrypt/rsa.c b/src/gcrypt/rsa.c index ceb1638..751f7b6 100644 --- a/src/gcrypt/rsa.c +++ b/src/gcrypt/rsa.c @@ -1,6 +1,6 @@ /* rsa.c -- RSA key handling - Copyright (C) 2007 Guus Sliepen + Copyright (C) 2007-2012 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 @@ -148,7 +148,7 @@ static size_t ber_read_len(unsigned char **p, size_t *buflen) { return *(*p)++; } } - + static bool ber_read_sequence(unsigned char **p, size_t *buflen, size_t *result) { int tag = ber_read_id(p, buflen); @@ -173,7 +173,7 @@ static bool ber_read_mpi(unsigned char **p, size_t *buflen, gcry_mpi_t *mpi) { if(mpi) err = gcry_mpi_scan(mpi, GCRYMPI_FMT_USG, *p, len, NULL); - + *p += len; *buflen -= len; @@ -187,7 +187,7 @@ bool rsa_set_hex_public_key(rsa_t *rsa, char *n, char *e) { ?: gcry_mpi_scan(&rsa->e, GCRYMPI_FMT_HEX, e, 0, NULL); if(err) { - logger(LOG_ERR, "Error while reading RSA public key: %s", gcry_strerror(errno)); + logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading RSA public key: %s", gcry_strerror(errno)); return false; } @@ -202,7 +202,7 @@ bool rsa_set_hex_private_key(rsa_t *rsa, char *n, char *e, char *d) { ?: gcry_mpi_scan(&rsa->d, GCRYMPI_FMT_HEX, d, 0, NULL); if(err) { - logger(LOG_ERR, "Error while reading RSA public key: %s", gcry_strerror(errno)); + logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading RSA public key: %s", gcry_strerror(errno)); return false; } @@ -216,7 +216,7 @@ bool rsa_read_pem_public_key(rsa_t *rsa, FILE *fp) { size_t derlen; if(!pem_decode(fp, "RSA PUBLIC KEY", derbuf, sizeof derbuf, &derlen)) { - logger(LOG_ERR, "Unable to read RSA public key: %s", strerror(errno)); + logger(DEBUG_ALWAYS, LOG_ERR, "Unable to read RSA public key: %s", strerror(errno)); return NULL; } @@ -224,7 +224,7 @@ bool rsa_read_pem_public_key(rsa_t *rsa, FILE *fp) { || !ber_read_mpi(&derp, &derlen, &rsa->n) || !ber_read_mpi(&derp, &derlen, &rsa->e) || derlen) { - logger(LOG_ERR, "Error while decoding RSA public key"); + logger(DEBUG_ALWAYS, LOG_ERR, "Error while decoding RSA public key"); return NULL; } @@ -236,7 +236,7 @@ bool rsa_read_pem_private_key(rsa_t *rsa, FILE *fp) { size_t derlen; if(!pem_decode(fp, "RSA PRIVATE KEY", derbuf, sizeof derbuf, &derlen)) { - logger(LOG_ERR, "Unable to read RSA private key: %s", strerror(errno)); + logger(DEBUG_ALWAYS, LOG_ERR, "Unable to read RSA private key: %s", strerror(errno)); return NULL; } @@ -251,7 +251,7 @@ bool rsa_read_pem_private_key(rsa_t *rsa, FILE *fp) { || !ber_read_mpi(&derp, &derlen, NULL) || !ber_read_mpi(&derp, &derlen, NULL) // u || derlen) { - logger(LOG_ERR, "Error while decoding RSA private key"); + logger(DEBUG_ALWAYS, LOG_ERR, "Error while decoding RSA private key"); return NULL; } @@ -267,7 +267,7 @@ size_t rsa_size(rsa_t *rsa) { */ // TODO: get rid of this macro, properly clean up gcry_ structures after use -#define check(foo) { gcry_error_t err = (foo); if(err) {logger(LOG_ERR, "gcrypt error %s/%s at %s:%d", gcry_strsource(err), gcry_strerror(err), __FILE__, __LINE__); return false; }} +#define check(foo) { gcry_error_t err = (foo); if(err) {logger(DEBUG_ALWAYS, LOG_ERR, "gcrypt error %s/%s at %s:%d", gcry_strsource(err), gcry_strerror(err), __FILE__, __LINE__); return false; }} bool rsa_public_encrypt(rsa_t *rsa, void *in, size_t len, void *out) { gcry_mpi_t inmpi; diff --git a/src/gcrypt/rsagen.c b/src/gcrypt/rsagen.c index 7d37d19..36fb104 100644 --- a/src/gcrypt/rsagen.c +++ b/src/gcrypt/rsagen.c @@ -1,6 +1,6 @@ /* rsagen.c -- RSA key generation and export - Copyright (C) 2008 Guus Sliepen + Copyright (C) 2008-2012 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 @@ -164,12 +164,12 @@ bool rsa_write_pem_public_key(rsa_t *rsa, FILE *fp) { if(!ber_write_mpi(&derp1, &derlen1, &rsa->n) || !ber_write_mpi(&derp1, &derlen1, &rsa->e) || !ber_write_sequence(&derp2, &derlen2, derbuf1, derlen1)) { - logger(LOG_ERR, "Error while encoding RSA public key"); + logger(DEBUG_ALWAYS, LOG_ERR, "Error while encoding RSA public key"); return false; } if(!pem_encode(fp, "RSA PUBLIC KEY", derbuf2, derlen2)) { - logger(LOG_ERR, "Unable to write RSA public key: %s", strerror(errno)); + logger(DEBUG_ALWAYS, LOG_ERR, "Unable to write RSA public key: %s", strerror(errno)); return false; } @@ -193,12 +193,12 @@ bool rsa_write_pem_private_key(rsa_t *rsa, FILE *fp) { || ber_write_mpi(&derp1, &derlen1, &exp1) || ber_write_mpi(&derp1, &derlen1, &exp2) || ber_write_mpi(&derp1, &derlen1, &coeff)) - logger(LOG_ERR, "Error while encoding RSA private key"); + logger(DEBUG_ALWAYS, LOG_ERR, "Error while encoding RSA private key"); return false; } if(!pem_encode(fp, "RSA PRIVATE KEY", derbuf2, derlen2)) { - logger(LOG_ERR, "Unable to write RSA private key: %s", strerror(errno)); + logger(DEBUG_ALWAYS, LOG_ERR, "Unable to write RSA private key: %s", strerror(errno)); return false; } diff --git a/src/graph.c b/src/graph.c index bb55dfd..9036c52 100644 --- a/src/graph.c +++ b/src/graph.c @@ -1,6 +1,6 @@ /* graph.c -- graph algorithms - Copyright (C) 2001-2011 Guus Sliepen , + Copyright (C) 2001-2012 Guus Sliepen , 2001-2005 Ivo Timmermans This program is free software; you can redistribute it and/or modify @@ -44,12 +44,12 @@ #include "system.h" -#include "splay_tree.h" #include "config.h" #include "connection.h" #include "device.h" #include "edge.h" #include "graph.h" +#include "list.h" #include "logger.h" #include "netutl.h" #include "node.h" @@ -65,34 +65,22 @@ Please note that sorting on weight is already done by add_edge(). */ -void mst_kruskal(void) { - splay_node_t *node, *next; - edge_t *e; - node_t *n; - connection_t *c; - +static void mst_kruskal(void) { /* Clear MST status on connections */ - for(node = connection_tree->head; node; node = node->next) { - c = node->data; + for list_each(connection_t, c, connection_list) c->status.mst = false; - } - ifdebug(SCARY_THINGS) logger(LOG_DEBUG, "Running Kruskal's algorithm:"); + logger(DEBUG_SCARY_THINGS, LOG_DEBUG, "Running Kruskal's algorithm:"); /* Clear visited status on nodes */ - for(node = node_tree->head; node; node = node->next) { - n = node->data; + for splay_each(node_t, n, node_tree) n->status.visited = false; - } /* Add safe edges */ - for(node = edge_weight_tree->head; node; node = next) { - next = node->next; - e = node->data; - + for splay_each(edge_t, e, edge_weight_tree) { if(!e->reverse || (e->from->status.visited && e->to->status.visited)) continue; @@ -105,31 +93,21 @@ void mst_kruskal(void) { if(e->reverse->connection) e->reverse->connection->status.mst = true; - ifdebug(SCARY_THINGS) logger(LOG_DEBUG, " Adding edge %s - %s weight %d", e->from->name, + logger(DEBUG_SCARY_THINGS, LOG_DEBUG, " Adding edge %s - %s weight %d", e->from->name, e->to->name, e->weight); } } -/* Implementation of Dijkstra's algorithm. - Running time: O(N^2) +/* Implementation of a simple breadth-first search algorithm. + Running time: O(E) */ -static void sssp_dijkstra(void) { - splay_node_t *node, *to; - edge_t *e; - node_t *n, *m; - list_t *todo_list; - list_node_t *lnode, *nnode; - bool indirect; - - todo_list = list_alloc(NULL); - - ifdebug(SCARY_THINGS) logger(LOG_DEBUG, "Running Dijkstra's algorithm:"); +static void sssp_bfs(void) { + list_t *todo_list = list_alloc(NULL); /* Clear visited status on nodes */ - for(node = node_tree->head; node; node = node->next) { - n = node->data; + for splay_each(node_t, n, node_tree) { n->status.visited = false; n->status.indirect = true; n->distance = -1; @@ -137,119 +115,23 @@ static void sssp_dijkstra(void) { /* Begin with myself */ + myself->status.visited = true; myself->status.indirect = false; myself->nexthop = myself; + myself->prevedge = NULL; myself->via = myself; myself->distance = 0; list_insert_head(todo_list, myself); /* Loop while todo_list is filled */ - while(todo_list->head) { - n = NULL; - nnode = NULL; + for list_each(node_t, n, todo_list) { /* "n" is the node from which we start */ + logger(DEBUG_SCARY_THINGS, LOG_DEBUG, " Examining edges from %s", n->name); - /* Select node from todo_list with smallest distance */ - - for(lnode = todo_list->head; lnode; lnode = lnode->next) { - m = lnode->data; - if(!n || m->status.indirect < n->status.indirect || m->distance < n->distance) { - n = m; - nnode = lnode; - } - } - - /* Mark this node as visited and remove it from the todo_list */ - - n->status.visited = true; - list_unlink_node(todo_list, nnode); - - /* Update distance of neighbours and add them to the todo_list */ - - for(to = n->edge_tree->head; to; to = to->next) { /* "to" is the edge connected to "from" */ - e = to->data; - - if(e->to->status.visited || !e->reverse) - continue; - - /* Situation: - - / - / - ----->(n)---e-->(e->to) - \ - \ - - Where e is an edge, (n) and (e->to) are nodes. - n->address is set to the e->address of the edge left of n to n. - We are currently examining the edge e right of n from n: - - - If edge e provides for better reachability of e->to, update e->to. - */ - - if(e->to->distance < 0) - list_insert_tail(todo_list, e->to); - - indirect = n->status.indirect || e->options & OPTION_INDIRECT || ((n != myself) && sockaddrcmp(&n->address, &e->reverse->address)); - - if(e->to->distance >= 0 && (!e->to->status.indirect || indirect) && e->to->distance <= n->distance + e->weight) - continue; - - e->to->distance = n->distance + e->weight; - e->to->status.indirect = indirect; - e->to->nexthop = (n->nexthop == myself) ? e->to : n->nexthop; - e->to->via = indirect ? n->via : e->to; - e->to->options = e->options; - - if(e->to->address.sa.sa_family == AF_UNSPEC && e->address.sa.sa_family != AF_UNKNOWN) - update_node_udp(e->to, &e->address); - - ifdebug(SCARY_THINGS) logger(LOG_DEBUG, " Updating edge %s - %s weight %d distance %d", e->from->name, - e->to->name, e->weight, e->to->distance); - } - } - - list_free(todo_list); -} - -/* Implementation of a simple breadth-first search algorithm. - Running time: O(E) -*/ - -void sssp_bfs(void) { - splay_node_t *node, *to; - edge_t *e; - node_t *n; - list_t *todo_list; - list_node_t *from, *todonext; - bool indirect; - - todo_list = list_alloc(NULL); - - /* Clear visited status on nodes */ - - for(node = node_tree->head; node; node = node->next) { - n = node->data; - n->status.visited = false; - n->status.indirect = true; - } - - /* Begin with myself */ - - myself->status.visited = true; - myself->status.indirect = false; - myself->nexthop = myself; - myself->via = myself; - list_insert_head(todo_list, myself); - - /* Loop while todo_list is filled */ - - for(from = todo_list->head; from; from = todonext) { /* "from" is the node from which we start */ - n = from->data; - - for(to = n->edge_tree->head; to; to = to->next) { /* "to" is the edge connected to "from" */ - e = to->data; + if(n->distance < 0) + abort(); + for splay_each(edge_t, e, n->edge_tree) { /* "e" is the edge connected to "from" */ if(!e->reverse) continue; @@ -270,61 +152,63 @@ void sssp_bfs(void) { of nodes behind it. */ - indirect = n->status.indirect || e->options & OPTION_INDIRECT; + bool indirect = n->status.indirect || e->options & OPTION_INDIRECT; if(e->to->status.visited - && (!e->to->status.indirect || indirect)) + && (!e->to->status.indirect || indirect) + && (e->to->distance != n->distance + 1 || e->weight >= e->to->prevedge->weight)) continue; e->to->status.visited = true; e->to->status.indirect = indirect; e->to->nexthop = (n->nexthop == myself) ? e->to : n->nexthop; + e->to->prevedge = e; e->to->via = indirect ? n->via : e->to; e->to->options = e->options; + e->to->distance = n->distance + 1; - if(e->to->address.sa.sa_family == AF_UNSPEC && e->address.sa.sa_family != AF_UNKNOWN) + if(!e->to->status.reachable || (e->to->address.sa.sa_family == AF_UNSPEC && e->address.sa.sa_family != AF_UNKNOWN)) update_node_udp(e->to, &e->address); list_insert_tail(todo_list, e->to); } - todonext = from->next; - list_delete_node(todo_list, from); + next = node->next; /* Because the list_insert_tail() above could have added something extra for us! */ + list_delete_node(todo_list, node); } list_free(todo_list); } static void check_reachability(void) { - splay_node_t *node, *next; - node_t *n; - char *name; - char *address, *port; - char *envp[7]; - int i; - /* Check reachability status. */ - for(node = node_tree->head; node; node = next) { - next = node->next; - n = node->data; - + for splay_each(node_t, n, node_tree) { if(n->status.visited != n->status.reachable) { n->status.reachable = !n->status.reachable; + n->last_state_change = time(NULL); if(n->status.reachable) { - ifdebug(TRAFFIC) logger(LOG_DEBUG, "Node %s (%s) became reachable", + logger(DEBUG_TRAFFIC, LOG_DEBUG, "Node %s (%s) became reachable", n->name, n->hostname); } else { - ifdebug(TRAFFIC) logger(LOG_DEBUG, "Node %s (%s) became unreachable", + logger(DEBUG_TRAFFIC, LOG_DEBUG, "Node %s (%s) became unreachable", n->name, n->hostname); } + if(experimental && OPTION_VERSION(n->options) >= 2) + n->status.sptps = true; + /* TODO: only clear status.validkey if node is unreachable? */ n->status.validkey = false; + if(n->status.sptps) { + sptps_stop(&n->sptps); + n->status.waitingforkey = false; + } n->last_req_key = 0; + n->status.udp_confirmed = false; n->maxmtu = MTU; n->minmtu = 0; n->mtuprobes = 0; @@ -332,6 +216,11 @@ static void check_reachability(void) { if(timeout_initialized(&n->mtuevent)) event_del(&n->mtuevent); + char *name; + char *address; + char *port; + char *envp[7]; + xasprintf(&envp[0], "NETNAME=%s", netname ? : ""); xasprintf(&envp[1], "DEVICE=%s", device ? : ""); xasprintf(&envp[2], "INTERFACE=%s", iface ? : ""); @@ -343,31 +232,37 @@ static void check_reachability(void) { execute_script(n->status.reachable ? "host-up" : "host-down", envp); - xasprintf(&name, - n->status.reachable ? "hosts/%s-up" : "hosts/%s-down", - n->name); + xasprintf(&name, n->status.reachable ? "hosts/%s-up" : "hosts/%s-down", n->name); execute_script(name, envp); free(name); free(address); free(port); - for(i = 0; i < 6; i++) + for(int i = 0; i < 6; i++) free(envp[i]); subnet_update(n, NULL, n->status.reachable); - if(!n->status.reachable) + if(!n->status.reachable) { update_node_udp(n, NULL); - else if(n->connection) - send_ans_key(n); + memset(&n->status, 0, sizeof n->status); + n->options = 0; + } else if(n->connection) { + if(n->status.sptps) { + if(n->connection->outgoing) + send_req_key(n); + } else { + send_ans_key(n); + } + } } } } void graph(void) { subnet_cache_flush(); - sssp_dijkstra(); + sssp_bfs(); check_reachability(); mst_kruskal(); } diff --git a/src/graph.h b/src/graph.h index fb41096..fa521f5 100644 --- a/src/graph.h +++ b/src/graph.h @@ -1,6 +1,6 @@ /* graph.h -- header for graph.c - Copyright (C) 2001-2006 Guus Sliepen , + Copyright (C) 2001-2012 Guus Sliepen , 2001-2005 Ivo Timmermans This program is free software; you can redistribute it and/or modify diff --git a/src/hash.c b/src/hash.c new file mode 100644 index 0000000..cf5ba90 --- /dev/null +++ b/src/hash.c @@ -0,0 +1,105 @@ +/* + hash.c -- hash table management + Copyright (C) 2012 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "system.h" + +#include "hash.h" +#include "xalloc.h" + +/* Generic hash function */ + +static uint32_t hash_function(const void *p, size_t len) { + const uint8_t *q = p; + uint32_t hash = 0; + while(true) { + for(int i = len > 4 ? 4 : len; --i;) + hash += q[i] << (8 * i); + hash *= 0x9e370001UL; // Golden ratio prime. + if(len <= 4) + break; + len -= 4; + } + return hash; +} + +/* Map 32 bits int onto 0..n-1, without throwing away too many bits if n is 2^8 or 2^16 */ + +static uint32_t modulo(uint32_t hash, size_t n) { + if(n == 0x100) + return (hash >> 24) ^ ((hash >> 16) & 0xff) ^ ((hash >> 8) & 0xff) ^ (hash & 0xff); + else if(n == 0x10000) + return (hash >> 16) ^ (hash & 0xffff); + else + return hash % n; +} + +/* (De)allocation */ + +hash_t *hash_alloc(size_t n, size_t size) { + hash_t *hash = xmalloc_and_zero(sizeof *hash); + hash->n = n; + hash->size = size; + hash->keys = xmalloc(hash->n * hash->size); + hash->values = xmalloc_and_zero(hash->n * sizeof *hash->values); + return hash; +} + +void hash_free(hash_t *hash) { + free(hash->keys); + free(hash->values); + free(hash); +} + +/* Searching and inserting */ + +void hash_insert(hash_t *hash, const void *key, const void *value) { + uint32_t i = modulo(hash_function(key, hash->size), hash->n); + memcpy(hash->keys + i * hash->size, key, hash->size); + hash->values[i] = value; +} + +void *hash_search(const hash_t *hash, const void *key) { + uint32_t i = modulo(hash_function(key, hash->size), hash->n); + if(hash->values[i] && !memcmp(key, hash->keys + i * hash->size, hash->size)) { + return (void *)hash->values[i]; + } + return NULL; +} + +void *hash_search_or_insert(hash_t *hash, const void *key, const void *value) { + uint32_t i = modulo(hash_function(key, hash->size), hash->n); + if(hash->values[i] && !memcmp(key, hash->keys + i * hash->size, hash->size)) + return (void *)hash->values[i]; + memcpy(hash->keys + i * hash->size, key, hash->size); + hash->values[i] = value; + return NULL; +} + +/* Utility functions */ + +void hash_clear(hash_t *hash) { + memset(hash->values, 0, hash->n * sizeof *hash->values); +} + +void hash_resize(hash_t *hash, size_t n) { + hash->keys = xrealloc(hash->keys, n * hash->size); + hash->values = xrealloc(hash->values, n * sizeof *hash->values); + if(n > hash->n) + memset(hash->values + hash->n, 0, (n - hash->n) * sizeof *hash->values); +} diff --git a/src/hash.h b/src/hash.h new file mode 100644 index 0000000..83ed6af --- /dev/null +++ b/src/hash.h @@ -0,0 +1,41 @@ +/* + hash.h -- header file for hash.c + Copyright (C) 2012 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#ifndef __TINC_HASH_H__ +#define __TINC_HASH_H__ + +typedef struct hash_t { + size_t n; + size_t size; + char *keys; + const void **values; +} hash_t; + +extern hash_t *hash_alloc(size_t n, size_t size) __attribute__ ((__malloc__)); +extern void hash_free(hash_t *); + +extern void hash_insert(hash_t *, const void *key, const void *value); + +extern void *hash_search(const hash_t *, const void *key); +extern void *hash_search_or_insert(hash_t *, const void *key, const void *value); + +extern void hash_clear(hash_t *); +extern void hash_resize(hash_t *, size_t n); + +#endif /* __TINC_HASH_H__ */ diff --git a/src/info.c b/src/info.c new file mode 100644 index 0000000..25d51bf --- /dev/null +++ b/src/info.c @@ -0,0 +1,266 @@ +/* + info.c -- Show information about a node, subnet or address + Copyright (C) 2012 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "system.h" + +#include "control_common.h" +#include "list.h" +#include "subnet.h" +#include "tincctl.h" +#include "info.h" +#include "xalloc.h" + +void logger(int level, int priority, const char *format, ...) { + va_list ap; + va_start(ap, format); + vfprintf(stderr, format, ap); + va_end(ap); +} + +char *strip_weight(char *netstr) { + int len = strlen(netstr); + if(len >= 3 && !strcmp(netstr + len - 3, "#10")) + netstr[len - 3] = 0; + return netstr; +} + +static int info_node(int fd, const char *item) { + // Check the list of nodes + sendline(fd, "%d %d %s", CONTROL, REQ_DUMP_NODES, item); + + bool found = false; + char line[4096]; + + char node[4096]; + char from[4096]; + char to[4096]; + char subnet[4096]; + char host[4096]; + char port[4096]; + char via[4096]; + char nexthop[4096]; + int code, req, cipher, digest, maclength, compression, distance; + short int pmtu, minmtu, maxmtu; + unsigned int options; + node_status_t status; + long int last_state_change; + + while(recvline(fd, line, sizeof line)) { + int n = sscanf(line, "%d %d %s %s port %s %d %d %d %d %x %x %s %s %d %hd %hd %hd %ld", &code, &req, node, host, port, &cipher, &digest, &maclength, &compression, &options, (unsigned *)&status, nexthop, via, &distance, &pmtu, &minmtu, &maxmtu, &last_state_change); + + if(n == 2) + break; + + if(n != 18) { + fprintf(stderr, "Unable to parse node dump from tincd.\n"); + return 1; + } + + if(!strcmp(node, item)) { + found = true; + break; + } + } + + if(!found) { + fprintf(stderr, "Unknown node %s.\n", item); + return 1; + } + + while(recvline(fd, line, sizeof line)) { + if(sscanf(line, "%d %d %s", &code, &req, node) == 2) + break; + } + + printf("Node: %s\n", item); + printf("Address: %s port %s\n", host, port); + + char timestr[32] = "never"; + if(last_state_change) + strftime(timestr, sizeof timestr, "%Y-%m-%d %H:%M:%S", localtime(&last_state_change)); + + if(status.reachable) + printf("Online since: %s\n", timestr); + else + printf("Last seen: %s\n", timestr); + + printf("Status: "); + if(status.validkey) + printf(" validkey"); + if(status.visited) + printf(" visited"); + if(status.reachable) + printf(" reachable"); + if(status.indirect) + printf(" indirect"); + if(status.sptps) + printf(" sptps"); + if(status.udp_confirmed) + printf(" udp_confirmed"); + printf("\n"); + + printf("Options: "); + if(options & OPTION_INDIRECT) + printf(" indirect"); + if(options & OPTION_TCPONLY) + printf(" tcponly"); + if(options & OPTION_PMTU_DISCOVERY) + printf(" pmtu_discovery"); + if(options & OPTION_CLAMP_MSS) + printf(" clamp_mss"); + printf("\n"); + printf("Protocol: %d.%d\n", PROT_MAJOR, OPTION_VERSION(options)); + printf("Reachability: "); + if(!strcmp(host, "MYSELF")) + printf("can reach itself\n"); + else if(!status.reachable) + printf("unreachable\n"); + else if(strcmp(via, item)) + printf("indirectly via %s\n", via); + else if(!status.validkey) + printf("unknown\n"); + else if(minmtu > 0) + printf("directly with UDP\nPMTU: %d\n", pmtu); + else if(!strcmp(nexthop, item)) + printf("directly with TCP\n"); + else + printf("none, forwarded via %s\n", nexthop); + + // List edges + printf("Edges: "); + sendline(fd, "%d %d %s", CONTROL, REQ_DUMP_EDGES, item); + while(recvline(fd, line, sizeof line)) { + int n = sscanf(line, "%d %d %s %s", &code, &req, from, to); + if(n == 2) + break; + if(n != 4) { + fprintf(stderr, "Unable to parse edge dump from tincd.\n%s\n", line); + return 1; + } + if(!strcmp(from, item)) + printf(" %s", to); + } + printf("\n"); + + // List subnets + printf("Subnets: "); + sendline(fd, "%d %d %s", CONTROL, REQ_DUMP_SUBNETS, item); + while(recvline(fd, line, sizeof line)) { + int n = sscanf(line, "%d %d %s %s", &code, &req, subnet, from); + if(n == 2) + break; + if(n != 4) { + fprintf(stderr, "Unable to parse subnet dump from tincd.\n"); + return 1; + } + if(!strcmp(from, item)) + printf(" %s", strip_weight(subnet)); + } + printf("\n"); + + return 0; +} + +static int info_subnet(int fd, const char *item) { + subnet_t subnet, find; + + if(!str2net(&find, item)) { + fprintf(stderr, "Could not parse subnet or address '%s'.\n", item); + return 1; + } + + bool address = !strchr(item, '/'); + bool weight = strchr(item, '#'); + bool found = false; + + char line[4096]; + char netstr[4096]; + char owner[4096]; + + int code, req; + + sendline(fd, "%d %d %s", CONTROL, REQ_DUMP_SUBNETS, item); + while(recvline(fd, line, sizeof line)) { + int n = sscanf(line, "%d %d %s %s", &code, &req, netstr, owner); + if(n == 2) + break; + + if(n != 4 || !str2net(&subnet, netstr)) { + fprintf(stderr, "Unable to parse subnet dump from tincd.\n"); + return 1; + } + + if(find.type != subnet.type) + continue; + + if(weight) { + if(find.weight != subnet.weight) + continue; + } + + if(find.type == SUBNET_IPV4) { + if(address) { + if(maskcmp(&find.net.ipv4.address, &subnet.net.ipv4.address, subnet.net.ipv4.prefixlength)) + continue; + } else { + if(find.net.ipv4.prefixlength != subnet.net.ipv4.prefixlength) + continue; + if(memcmp(&find.net.ipv4.address, &subnet.net.ipv4.address, sizeof subnet.net.ipv4)) + continue; + } + } else if(find.type == SUBNET_IPV6) { + if(address) { + if(maskcmp(&find.net.ipv6.address, &subnet.net.ipv6.address, subnet.net.ipv6.prefixlength)) + continue; + } else { + if(find.net.ipv6.prefixlength != subnet.net.ipv6.prefixlength) + continue; + if(memcmp(&find.net.ipv6.address, &subnet.net.ipv6.address, sizeof subnet.net.ipv6)) + continue; + } + } if(find.type == SUBNET_MAC) { + if(memcmp(&find.net.mac.address, &subnet.net.mac.address, sizeof subnet.net.mac)) + continue; + } + + found = true; + printf("Subnet: %s\n", strip_weight(netstr)); + printf("Owner: %s\n", owner); + } + + if(!found) { + if(address) + fprintf(stderr, "Unknown address %s.\n", item); + else + fprintf(stderr, "Unknown subnet %s.\n", item); + return 1; + } + + return 0; +} + +int info(int fd, const char *item) { + if(check_id(item)) + return info_node(fd, item); + if(strchr(item, '.') || strchr(item, ':')) + return info_subnet(fd, item); + + fprintf(stderr, "Argument is not a node name, subnet or address.\n"); + return 1; +} diff --git a/src/info.h b/src/info.h new file mode 100644 index 0000000..a3f387f --- /dev/null +++ b/src/info.h @@ -0,0 +1,27 @@ +/* + info.h -- header for info.c. + Copyright (C) 2012 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#ifndef __TINC_INFO_H__ +#define __TINC_INFO_H__ + +extern int info(int fd, const char *item); +extern char *strip_weight(char *); + +#endif + diff --git a/src/ipv4.h b/src/ipv4.h index 940c239..6cb969b 100644 --- a/src/ipv4.h +++ b/src/ipv4.h @@ -1,7 +1,7 @@ /* ipv4.h -- missing IPv4 related definitions Copyright (C) 2005 Ivo Timmermans - 2006 Guus Sliepen + 2006-2012 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 @@ -41,6 +41,14 @@ #define ICMP_NET_UNKNOWN 6 #endif +#ifndef ICMP_TIME_EXCEEDED +#define ICMP_TIME_EXCEEDED 11 +#endif + +#ifndef ICMP_EXC_TTL +#define ICMP_EXC_TTL 0 +#endif + #ifndef ICMP_NET_UNREACH #define ICMP_NET_UNREACH 0 #endif @@ -64,7 +72,7 @@ struct ip { #endif uint8_t ip_tos; uint16_t ip_len; - uint16_t ip_id; + uint16_t ip_id; uint16_t ip_off; #define IP_RF 0x8000 #define IP_DF 0x4000 diff --git a/src/ipv6.h b/src/ipv6.h index d98001d..37d999a 100644 --- a/src/ipv6.h +++ b/src/ipv6.h @@ -1,7 +1,7 @@ /* ipv6.h -- missing IPv6 related definitions Copyright (C) 2005 Ivo Timmermans - 2006 Guus Sliepen + 2006-2012 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 @@ -54,9 +54,9 @@ struct sockaddr_in6 { #ifndef IN6_IS_ADDR_V4MAPPED #define IN6_IS_ADDR_V4MAPPED(a) \ - ((((__const uint32_t *) (a))[0] == 0) \ - && (((__const uint32_t *) (a))[1] == 0) \ - && (((__const uint32_t *) (a))[2] == htonl (0xffff))) + ((((__const uint32_t *) (a))[0] == 0) \ + && (((__const uint32_t *) (a))[1] == 0) \ + && (((__const uint32_t *) (a))[2] == htonl (0xffff))) #endif #ifndef HAVE_STRUCT_IP6_HDR @@ -95,8 +95,10 @@ struct icmp6_hdr { #define ICMP6_DST_UNREACH_NOROUTE 0 #define ICMP6_DST_UNREACH 1 #define ICMP6_PACKET_TOO_BIG 2 +#define ICMP6_TIME_EXCEEDED 3 #define ICMP6_DST_UNREACH_ADMIN 1 #define ICMP6_DST_UNREACH_ADDR 3 +#define ICMP6_TIME_EXCEED_TRANSIT 0 #define ND_NEIGHBOR_SOLICIT 135 #define ND_NEIGHBOR_ADVERT 136 #define icmp6_data32 icmp6_dataun.icmp6_un_data32 diff --git a/src/linux/device.c b/src/linux/device.c index d36f3f6..18f1b6e 100644 --- a/src/linux/device.c +++ b/src/linux/device.c @@ -1,7 +1,7 @@ /* device.c -- Interaction with Linux ethertap and tun/tap device Copyright (C) 2001-2005 Ivo Timmermans, - 2001-2009 Guus Sliepen + 2001-2012 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 @@ -41,6 +41,7 @@ int device_fd = -1; static device_type_t device_type; char *device = NULL; char *iface = NULL; +static char *type = NULL; static char ifrname[IFNAMSIZ]; static char *device_info; @@ -49,27 +50,35 @@ uint64_t device_in_bytes = 0; uint64_t device_out_packets = 0; uint64_t device_out_bytes = 0; -bool setup_device(void) { +static bool setup_device(void) { if(!get_config_string(lookup_config(config_tree, "Device"), &device)) device = xstrdup(DEFAULT_DEVICE); if(!get_config_string(lookup_config(config_tree, "Interface"), &iface)) -#ifdef HAVE_LINUX_IF_TUN_H - if (netname != NULL) + if(netname) iface = xstrdup(netname); -#else - iface = xstrdup(strrchr(device, '/') ? strrchr(device, '/') + 1 : device); -#endif + device_fd = open(device, O_RDWR | O_NONBLOCK); if(device_fd < 0) { - logger(LOG_ERR, "Could not open %s: %s", device, strerror(errno)); + logger(DEBUG_ALWAYS, LOG_ERR, "Could not open %s: %s", device, strerror(errno)); return false; } +#ifdef FD_CLOEXEC + fcntl(device_fd, F_SETFD, FD_CLOEXEC); +#endif + struct ifreq ifr = {{{0}}}; - if(routing_mode == RMODE_ROUTER) { + get_config_string(lookup_config(config_tree, "DeviceType"), &type); + + if(type && strcasecmp(type, "tun") && strcasecmp(type, "tap")) { + logger(DEBUG_ALWAYS, LOG_ERR, "Unknown device type %s!", type); + return false; + } + + if((type && !strcasecmp(type, "tun")) || (!type && routing_mode == RMODE_ROUTER)) { ifr.ifr_flags = IFF_TUN; device_type = DEVICE_TYPE_TUN; device_info = "Linux tun/tap device (tun mode)"; @@ -92,47 +101,44 @@ bool setup_device(void) { if(!ioctl(device_fd, TUNSETIFF, &ifr)) { strncpy(ifrname, ifr.ifr_name, IFNAMSIZ); - if(iface) free(iface); - iface = xstrdup(ifrname); - } else if(!ioctl(device_fd, (('T' << 8) | 202), &ifr)) { - logger(LOG_WARNING, "Old ioctl() request was needed for %s", device); - strncpy(ifrname, ifr.ifr_name, IFNAMSIZ); - if(iface) free(iface); + free(iface); iface = xstrdup(ifrname); } - logger(LOG_INFO, "%s is a %s", device, device_info); + logger(DEBUG_ALWAYS, LOG_INFO, "%s is a %s", device, device_info); return true; } -void close_device(void) { +static void close_device(void) { close(device_fd); + free(type); free(device); free(iface); } -bool read_packet(vpn_packet_t *packet) { +static bool read_packet(vpn_packet_t *packet) { int inlen; - + switch(device_type) { case DEVICE_TYPE_TUN: inlen = read(device_fd, packet->data + 10, MTU - 10); if(inlen <= 0) { - logger(LOG_ERR, "Error while reading from %s %s: %s", + logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info, device, strerror(errno)); return false; } + memset(packet->data, 0, 12); packet->len = inlen + 10; break; case DEVICE_TYPE_TAP: inlen = read(device_fd, packet->data, MTU); if(inlen <= 0) { - logger(LOG_ERR, "Error while reading from %s %s: %s", + logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info, device, strerror(errno)); return false; } @@ -146,28 +152,28 @@ bool read_packet(vpn_packet_t *packet) { device_in_packets++; device_in_bytes += packet->len; - ifdebug(TRAFFIC) logger(LOG_DEBUG, "Read packet of %d bytes from %s", packet->len, + logger(DEBUG_TRAFFIC, LOG_DEBUG, "Read packet of %d bytes from %s", packet->len, device_info); return true; } -bool write_packet(vpn_packet_t *packet) { - ifdebug(TRAFFIC) logger(LOG_DEBUG, "Writing packet of %d bytes to %s", +static bool write_packet(vpn_packet_t *packet) { + logger(DEBUG_TRAFFIC, LOG_DEBUG, "Writing packet of %d bytes to %s", packet->len, device_info); switch(device_type) { case DEVICE_TYPE_TUN: packet->data[10] = packet->data[11] = 0; if(write(device_fd, packet->data + 10, packet->len - 10) < 0) { - logger(LOG_ERR, "Can't write to %s %s: %s", device_info, device, + logger(DEBUG_ALWAYS, LOG_ERR, "Can't write to %s %s: %s", device_info, device, strerror(errno)); return false; } break; case DEVICE_TYPE_TAP: if(write(device_fd, packet->data, packet->len) < 0) { - logger(LOG_ERR, "Can't write to %s %s: %s", device_info, device, + logger(DEBUG_ALWAYS, LOG_ERR, "Can't write to %s %s: %s", device_info, device, strerror(errno)); return false; } @@ -182,8 +188,16 @@ bool write_packet(vpn_packet_t *packet) { return true; } -void dump_device_stats(void) { - logger(LOG_DEBUG, "Statistics for %s %s:", device_info, device); - logger(LOG_DEBUG, " total bytes in: %10"PRIu64, device_in_bytes); - logger(LOG_DEBUG, " total bytes out: %10"PRIu64, device_out_bytes); +static void dump_device_stats(void) { + logger(DEBUG_ALWAYS, LOG_DEBUG, "Statistics for %s %s:", device_info, device); + logger(DEBUG_ALWAYS, LOG_DEBUG, " total bytes in: %10"PRIu64, device_in_bytes); + logger(DEBUG_ALWAYS, LOG_DEBUG, " total bytes out: %10"PRIu64, device_out_bytes); } + +const devops_t os_devops = { + .setup = setup_device, + .close = close_device, + .read = read_packet, + .write = write_packet, + .dump_stats = dump_device_stats, +}; diff --git a/src/list.c b/src/list.c index 9b67791..2dd414a 100644 --- a/src/list.c +++ b/src/list.c @@ -1,7 +1,7 @@ /* list.c -- functions to deal with double linked lists Copyright (C) 2000-2005 Ivo Timmermans - 2000-2006 Guus Sliepen + 2000-2012 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 @@ -26,9 +26,7 @@ /* (De)constructors */ list_t *list_alloc(list_action_t delete) { - list_t *list; - - list = xmalloc_and_zero(sizeof(list_t)); + list_t *list = xmalloc_and_zero(sizeof(list_t)); list->delete = delete; return list; @@ -52,9 +50,7 @@ void list_free_node(list_t *list, list_node_t *node) { /* Insertion and deletion */ list_node_t *list_insert_head(list_t *list, void *data) { - list_node_t *node; - - node = list_alloc_node(); + list_node_t *node = list_alloc_node(); node->data = data; node->prev = NULL; @@ -72,9 +68,7 @@ list_node_t *list_insert_head(list_t *list, void *data) { } list_node_t *list_insert_tail(list_t *list, void *data) { - list_node_t *node; - - node = list_alloc_node(); + list_node_t *node = list_alloc_node(); node->data = data; node->next = NULL; @@ -92,9 +86,7 @@ list_node_t *list_insert_tail(list_t *list, void *data) { } list_node_t *list_insert_after(list_t *list, list_node_t *after, void *data) { - list_node_t *node; - - node = list_alloc_node(); + list_node_t *node = list_alloc_node(); node->data = data; node->next = after->next; @@ -158,6 +150,12 @@ void list_delete_tail(list_t *list) { list_delete_node(list, list->tail); } +void list_delete(list_t *list, const void *data) { + for(list_node_t *node = list->head, *next; next = node ? node->next : NULL, node; node = next) + if(node->data == data) + list_delete_node(list, node); +} + /* Head/tail lookup */ void *list_get_head(list_t *list) { @@ -177,12 +175,8 @@ void *list_get_tail(list_t *list) { /* Fast list deletion */ void list_delete_list(list_t *list) { - list_node_t *node, *next; - - for(node = list->head; node; node = next) { - next = node->next; + for(list_node_t *node = list->head, *next; next = node ? node->next : NULL, node; node = next) list_free_node(list, node); - } list_free(list); } @@ -190,20 +184,12 @@ void list_delete_list(list_t *list) { /* Traversing */ void list_foreach_node(list_t *list, list_action_node_t action) { - list_node_t *node, *next; - - for(node = list->head; node; node = next) { - next = node->next; + for(list_node_t *node = list->head, *next; next = node ? node->next : NULL, node; node = next) action(node); - } } void list_foreach(list_t *list, list_action_t action) { - list_node_t *node, *next; - - for(node = list->head; node; node = next) { - next = node->next; + for(list_node_t *node = list->head, *next; next = node ? node->next : NULL, node; node = next) if(node->data) action(node->data); - } } diff --git a/src/list.h b/src/list.h index 4fe48db..0437bd9 100644 --- a/src/list.h +++ b/src/list.h @@ -1,7 +1,7 @@ /* list.h -- header file for list.c Copyright (C) 2000-2005 Ivo Timmermans - 2000-2006 Guus Sliepen + 2000-2012 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 @@ -57,6 +57,8 @@ extern list_node_t *list_insert_tail(list_t *, void *); extern list_node_t *list_insert_after(list_t *, list_node_t *, void *); extern list_node_t *list_insert_before(list_t *, list_node_t *, void *); +extern void list_delete(list_t *, const void *); + extern void list_unlink_node(list_t *, list_node_t *); extern void list_delete_node(list_t *, list_node_t *); @@ -77,4 +79,6 @@ extern void list_delete_list(list_t *); extern void list_foreach(list_t *, list_action_t); extern void list_foreach_node(list_t *, list_action_node_t); -#endif /* __TINC_LIST_H__ */ +#define list_each(type, item, list) (type *item = (type *)1; item; item = NULL) for(list_node_t *node = (list)->head, *next; item = node ? node->data : NULL, next = node ? node->next : NULL, node; node = next) + +#endif /* __TINC_LIST_H__ */ diff --git a/src/logger.c b/src/logger.c index 08f9795..4527a37 100644 --- a/src/logger.c +++ b/src/logger.c @@ -1,6 +1,6 @@ /* logger.c -- logging code - Copyright (C) 2004-2006 Guus Sliepen + Copyright (C) 2004-2012 Guus Sliepen 2004-2005 Ivo Timmermans This program is free software; you can redistribute it and/or modify @@ -21,7 +21,11 @@ #include "system.h" #include "conf.h" +#include "meta.h" #include "logger.h" +#include "connection.h" +#include "control_common.h" +#include "sptps.h" debug_t debug_level = DEBUG_NOTHING; static logmode_t logmode = LOGMODE_STDERR; @@ -32,11 +36,94 @@ static FILE *logfile = NULL; static HANDLE loghandle = NULL; #endif static const char *logident = NULL; +bool logcontrol = false; + + +static void real_logger(int level, int priority, const char *message) { + char timestr[32] = ""; + time_t now; + static bool suppress = false; + + // Bail out early if there is nothing to do. + if(suppress) + return; + + if(!logcontrol && (level > debug_level || logmode == LOGMODE_NULL)) + return; + + if(level <= debug_level) { + switch(logmode) { + case LOGMODE_STDERR: + fprintf(stderr, "%s\n", message); + fflush(stderr); + break; + case LOGMODE_FILE: + now = time(NULL); + strftime(timestr, sizeof timestr, "%Y-%m-%d %H:%M:%S", localtime(&now)); + fprintf(logfile, "%s %s[%ld]: %s\n", timestr, logident, (long)logpid, message); + fflush(logfile); + break; + case LOGMODE_SYSLOG: +#ifdef HAVE_MINGW + { + const char *messages[] = {message}; + ReportEvent(loghandle, priority, 0, 0, NULL, 1, 0, messages, NULL); + } +#else +#ifdef HAVE_SYSLOG_H + syslog(priority, "%s", message); +#endif +#endif + break; + case LOGMODE_NULL: + break; + } + } + + if(logcontrol) { + suppress = true; + logcontrol = false; + for list_each(connection_t, c, connection_list) { + if(!c->status.log) + continue; + logcontrol = true; + if(level > (c->outcompression >= 0 ? c->outcompression : debug_level)) + continue; + int len = strlen(message); + if(send_request(c, "%d %d %d", CONTROL, REQ_LOG, len)) + send_meta(c, message, len); + } + suppress = false; + } +} + +void logger(int level, int priority, const char *format, ...) { + va_list ap; + char message[1024] = ""; + + va_start(ap, format); + int len = vsnprintf(message, sizeof message, format, ap); + va_end(ap); + + if(len > 0 && len < sizeof message && message[len - 1] == '\n') + message[len - 1] = 0; + + real_logger(level, priority, message); +} + +static void sptps_logger(sptps_t *s, int s_errno, const char *format, va_list ap) { + char message[1024] = ""; + int len = vsnprintf(message, sizeof message, format, ap); + if(len > 0 && len < sizeof message && message[len - 1] == '\n') + message[len - 1] = 0; + + real_logger(DEBUG_ALWAYS, LOG_ERR, message); +} void openlogger(const char *ident, logmode_t mode) { logident = ident; logmode = mode; - + switch(mode) { case LOGMODE_STDERR: logpid = getpid(); @@ -66,6 +153,11 @@ void openlogger(const char *ident, logmode_t mode) { case LOGMODE_NULL: break; } + + if(logmode != LOGMODE_NULL) + sptps_log = sptps_logger; + else + sptps_log = sptps_log_quiet; } void reopenlogger() { @@ -75,62 +167,13 @@ void reopenlogger() { fflush(logfile); FILE *newfile = fopen(logfilename, "a"); if(!newfile) { - logger(LOG_ERR, "Unable to reopen log file %s: %s\n", logfilename, strerror(errno)); + logger(DEBUG_ALWAYS, LOG_ERR, "Unable to reopen log file %s: %s", logfilename, strerror(errno)); return; } fclose(logfile); logfile = newfile; } -void logger(int priority, const char *format, ...) { - va_list ap; - char timestr[32] = ""; - time_t now; - - va_start(ap, format); - - switch(logmode) { - case LOGMODE_STDERR: - vfprintf(stderr, format, ap); - fprintf(stderr, "\n"); - fflush(stderr); - break; - case LOGMODE_FILE: - now = time(NULL); - strftime(timestr, sizeof timestr, "%Y-%m-%d %H:%M:%S", localtime(&now)); - fprintf(logfile, "%s %s[%ld]: ", timestr, logident, (long)logpid); - vfprintf(logfile, format, ap); - fprintf(logfile, "\n"); - fflush(logfile); - break; - case LOGMODE_SYSLOG: -#ifdef HAVE_MINGW - { - char message[4096]; - const char *messages[] = {message}; - vsnprintf(message, sizeof message, format, ap); - ReportEvent(loghandle, priority, 0, 0, NULL, 1, 0, messages, NULL); - } -#else -#ifdef HAVE_SYSLOG_H -#ifdef HAVE_VSYSLOG - vsyslog(priority, format, ap); -#else - { - char message[4096]; - vsnprintf(message, sizeof message, format, ap); - syslog(priority, "%s", message); - } -#endif - break; -#endif -#endif - case LOGMODE_NULL: - break; - } - - va_end(ap); -} void closelogger(void) { switch(logmode) { diff --git a/src/logger.h b/src/logger.h index ff2cb34..637eef8 100644 --- a/src/logger.h +++ b/src/logger.h @@ -1,17 +1,37 @@ +/* + logger.h -- header file for logger.c + Copyright (C) 1998-2005 Ivo Timmermans + 2000-2012 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + #ifndef __TINC_LOGGER_H__ #define __TINC_LOGGER_H__ typedef enum debug_t { - DEBUG_NOTHING = 0, /* Quiet mode, only show starting/stopping of the daemon */ + DEBUG_NOTHING = 0, /* Quiet mode, only show starting/stopping of the daemon */ DEBUG_ALWAYS = 0, - DEBUG_CONNECTIONS = 1, /* Show (dis)connects of other tinc daemons via TCP */ - DEBUG_ERROR = 2, /* Show error messages received from other hosts */ - DEBUG_STATUS = 2, /* Show status messages received from other hosts */ - DEBUG_PROTOCOL = 3, /* Show the requests that are sent/received */ - DEBUG_META = 4, /* Show contents of every request that is sent/received */ - DEBUG_TRAFFIC = 5, /* Show network traffic information */ - DEBUG_PACKET = 6, /* Show contents of each packet that is being sent/received */ - DEBUG_SCARY_THINGS = 10 /* You have been warned */ + DEBUG_CONNECTIONS = 1, /* Show (dis)connects of other tinc daemons via TCP */ + DEBUG_ERROR = 2, /* Show error messages received from other hosts */ + DEBUG_STATUS = 2, /* Show status messages received from other hosts */ + DEBUG_PROTOCOL = 3, /* Show the requests that are sent/received */ + DEBUG_META = 4, /* Show contents of every request that is sent/received */ + DEBUG_TRAFFIC = 5, /* Show network traffic information */ + DEBUG_PACKET = 6, /* Show contents of each packet that is being sent/received */ + DEBUG_SCARY_THINGS = 10 /* You have been warned */ } debug_t; typedef enum logmode_t { @@ -46,11 +66,10 @@ enum { #endif extern debug_t debug_level; +extern bool logcontrol; extern void openlogger(const char *, logmode_t); extern void reopenlogger(void); -extern void logger(int, const char *, ...) __attribute__ ((__format__(printf, 2, 3))); +extern void logger(int, int, const char *, ...) __attribute__ ((__format__(printf, 3, 4))); extern void closelogger(void); -#define ifdebug(l) if(debug_level >= DEBUG_##l) - #endif /* __TINC_LOGGER_H__ */ diff --git a/src/meta.c b/src/meta.c index 29dd824..84fb196 100644 --- a/src/meta.c +++ b/src/meta.c @@ -1,6 +1,6 @@ /* meta.c -- handle the meta communication - Copyright (C) 2000-2009 Guus Sliepen , + Copyright (C) 2000-2012 Guus Sliepen , 2000-2005 Ivo Timmermans 2006 Scott Lamb @@ -21,7 +21,6 @@ #include "system.h" -#include "splay_tree.h" #include "cipher.h" #include "connection.h" #include "logger.h" @@ -31,21 +30,38 @@ #include "utils.h" #include "xalloc.h" -bool send_meta(connection_t *c, const char *buffer, int length) { +bool send_meta_sptps(void *handle, uint8_t type, const char *buffer, size_t length) { + connection_t *c = handle; + if(!c) { - logger(LOG_ERR, "send_meta() called with NULL pointer!"); + logger(DEBUG_ALWAYS, LOG_ERR, "send_meta_sptps() called with NULL pointer!"); abort(); } - ifdebug(META) logger(LOG_DEBUG, "Sending %d bytes of metadata to %s (%s)", length, + buffer_add(&c->outbuf, buffer, length); + event_add(&c->outevent, NULL); + + return true; +} + +bool send_meta(connection_t *c, const char *buffer, int length) { + if(!c) { + logger(DEBUG_ALWAYS, LOG_ERR, "send_meta() called with NULL pointer!"); + abort(); + } + + logger(DEBUG_META, LOG_DEBUG, "Sending %d bytes of metadata to %s (%s)", length, c->name, c->hostname); + if(c->protocol_minor >= 2) + return sptps_send_record(&c->sptps, 0, buffer, length); + /* Add our data to buffer */ if(c->status.encryptout) { size_t outlen = length; if(!cipher_encrypt(&c->outcipher, buffer, length, buffer_prepare(&c->outbuf, length), &outlen, false) || outlen != length) { - logger(LOG_ERR, "Error while encrypting metadata to %s (%s)", + logger(DEBUG_ALWAYS, LOG_ERR, "Error while encrypting metadata to %s (%s)", c->name, c->hostname); return false; } @@ -60,15 +76,47 @@ bool send_meta(connection_t *c, const char *buffer, int length) { } void broadcast_meta(connection_t *from, const char *buffer, int length) { - splay_node_t *node; - connection_t *c; - - for(node = connection_tree->head; node; node = node->next) { - c = node->data; - + for list_each(connection_t, c, connection_list) if(c != from && c->status.active) send_meta(c, buffer, length); +} + +bool receive_meta_sptps(void *handle, uint8_t type, const char *data, uint16_t length) { + connection_t *c = handle; + + if(!c) { + logger(DEBUG_ALWAYS, LOG_ERR, "receive_meta_sptps() called with NULL pointer!"); + abort(); } + + if(type == SPTPS_HANDSHAKE) { + if(c->allow_request == ACK) + return send_ack(c); + else + return true; + } + + if(!data) + return true; + + /* Are we receiving a TCPpacket? */ + + if(c->tcplen) { + if(length != c->tcplen) + return false; + receive_tcppacket(c, data, length); + c->tcplen = 0; + return true; + } + + /* Change newline to null byte, just like non-SPTPS requests */ + + if(data[length - 1] == '\n') + ((char *)data)[length - 1] = 0; + + /* Otherwise we are waiting for a request */ + + return receive_request(c, data); } bool receive_meta(connection_t *c) { @@ -88,7 +136,7 @@ bool receive_meta(connection_t *c) { buffer_compact(&c->inbuf, MAXBUFSIZE); if(sizeof inbuf <= c->inbuf.len) { - logger(LOG_ERR, "Input buffer full for %s (%s)", c->name, c->hostname); + logger(DEBUG_ALWAYS, LOG_ERR, "Input buffer full for %s (%s)", c->name, c->hostname); return false; } @@ -96,17 +144,20 @@ bool receive_meta(connection_t *c) { if(inlen <= 0) { if(!inlen || !errno) { - ifdebug(CONNECTIONS) logger(LOG_NOTICE, "Connection closed by %s (%s)", + logger(DEBUG_CONNECTIONS, LOG_NOTICE, "Connection closed by %s (%s)", c->name, c->hostname); } else if(sockwouldblock(sockerrno)) return true; else - logger(LOG_ERR, "Metadata socket read error for %s (%s): %s", + logger(DEBUG_ALWAYS, LOG_ERR, "Metadata socket read error for %s (%s): %s", c->name, c->hostname, sockstrerror(sockerrno)); return false; } do { + if(c->protocol_minor >= 2) + return sptps_receive_data(&c->sptps, bufp, inlen); + if(!c->status.decryptin) { endp = memchr(bufp, '\n', inlen); if(endp) @@ -120,10 +171,9 @@ bool receive_meta(connection_t *c) { bufp = endp; } else { size_t outlen = inlen; - ifdebug(META) logger(LOG_DEBUG, "Received encrypted %d bytes", inlen); if(!cipher_decrypt(&c->incipher, bufp, inlen, buffer_prepare(&c->inbuf, inlen), &outlen, false) || inlen != outlen) { - logger(LOG_ERR, "Error while decrypting metadata from %s (%s)", + logger(DEBUG_ALWAYS, LOG_ERR, "Error while decrypting metadata from %s (%s)", c->name, c->hostname); return false; } @@ -137,7 +187,15 @@ bool receive_meta(connection_t *c) { if(c->tcplen) { char *tcpbuffer = buffer_read(&c->inbuf, c->tcplen); if(tcpbuffer) { - receive_tcppacket(c, tcpbuffer, c->tcplen); + if(proxytype == PROXY_SOCKS4 && c->allow_request == ID) { + if(tcpbuffer[0] == 0 && tcpbuffer[1] == 0x5a) { + logger(DEBUG_CONNECTIONS, LOG_DEBUG, "Proxy request granted"); + } else { + logger(DEBUG_CONNECTIONS, LOG_ERR, "Proxy request rejected"); + return false; + } + } else + receive_tcppacket(c, tcpbuffer, c->tcplen); c->tcplen = 0; continue; } else { diff --git a/src/meta.h b/src/meta.h index bc81a6a..2a71228 100644 --- a/src/meta.h +++ b/src/meta.h @@ -1,6 +1,6 @@ /* meta.h -- header for meta.c - Copyright (C) 2000-2006 Guus Sliepen , + Copyright (C) 2000-2012 Guus Sliepen , 2000-2005 Ivo Timmermans This program is free software; you can redistribute it and/or modify @@ -24,7 +24,9 @@ #include "connection.h" extern bool send_meta(struct connection_t *, const char *, int); +extern bool send_meta_sptps(void *, uint8_t, const char *, size_t); +extern bool receive_meta_sptps(void *, uint8_t, const char *, uint16_t); extern void broadcast_meta(struct connection_t *, const char *, int); extern bool receive_meta(struct connection_t *); -#endif /* __TINC_META_H__ */ +#endif /* __TINC_META_H__ */ diff --git a/src/mingw/device.c b/src/mingw/device.c index bdca842..3b1458c 100644 --- a/src/mingw/device.c +++ b/src/mingw/device.c @@ -1,7 +1,7 @@ /* device.c -- Interaction with Windows tap driver in a MinGW environment Copyright (C) 2002-2005 Ivo Timmermans, - 2002-2011 Guus Sliepen + 2002-2012 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 @@ -50,7 +50,7 @@ static DWORD WINAPI tapreader(void *bla) { OVERLAPPED overlapped; vpn_packet_t packet; - logger(LOG_DEBUG, "Tap reader running"); + logger(DEBUG_ALWAYS, LOG_DEBUG, "Tap reader running"); /* Read from tap device and send to parent */ @@ -69,7 +69,7 @@ static DWORD WINAPI tapreader(void *bla) { if(!GetOverlappedResult(device_handle, &overlapped, &len, FALSE)) continue; } else { - logger(LOG_ERR, "Error while reading from %s %s: %s", device_info, + logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info, device, strerror(errno)); return -1; } @@ -83,7 +83,7 @@ static DWORD WINAPI tapreader(void *bla) { } } -bool setup_device(void) { +static bool setup_device(void) { HKEY key, key2; int i; @@ -105,7 +105,7 @@ bool setup_device(void) { /* Open registry and look for network adapters */ if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, NETWORK_CONNECTIONS_KEY, 0, KEY_READ, &key)) { - logger(LOG_ERR, "Unable to read registry: %s", winerror(GetLastError())); + logger(DEBUG_ALWAYS, LOG_ERR, "Unable to read registry: %s", winerror(GetLastError())); return false; } @@ -118,7 +118,7 @@ bool setup_device(void) { snprintf(regpath, sizeof regpath, "%s\\%s\\Connection", NETWORK_CONNECTIONS_KEY, adapterid); - if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, regpath, 0, KEY_READ, &key2)) + if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, regpath, 0, KEY_READ, &key2)) continue; len = sizeof adaptername; @@ -156,7 +156,7 @@ bool setup_device(void) { RegCloseKey(key); if(!found) { - logger(LOG_ERR, "No Windows tap device found!"); + logger(DEBUG_ALWAYS, LOG_ERR, "No Windows tap device found!"); return false; } @@ -172,16 +172,16 @@ bool setup_device(void) { snprintf(tapname, sizeof tapname, USERMODEDEVICEDIR "%s" TAPSUFFIX, device); device_handle = CreateFile(tapname, GENERIC_WRITE | GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED, 0); } - + if(device_handle == INVALID_HANDLE_VALUE) { - logger(LOG_ERR, "%s (%s) is not a usable Windows tap device: %s", device, iface, winerror(GetLastError())); + logger(DEBUG_ALWAYS, LOG_ERR, "%s (%s) is not a usable Windows tap device: %s", device, iface, winerror(GetLastError())); return false; } /* Get MAC address from tap device */ if(!DeviceIoControl(device_handle, TAP_IOCTL_GET_MAC, mymac.x, sizeof mymac.x, mymac.x, sizeof mymac.x, &len, 0)) { - logger(LOG_ERR, "Could not get MAC address from Windows tap device %s (%s): %s", device, iface, winerror(GetLastError())); + logger(DEBUG_ALWAYS, LOG_ERR, "Could not get MAC address from Windows tap device %s (%s): %s", device, iface, winerror(GetLastError())); return false; } @@ -194,7 +194,7 @@ bool setup_device(void) { thread = CreateThread(NULL, 0, tapreader, NULL, 0, NULL); if(!thread) { - logger(LOG_ERR, "System call `%s' failed: %s", "CreateThread", winerror(GetLastError())); + logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "CreateThread", winerror(GetLastError())); return false; } @@ -205,31 +205,31 @@ bool setup_device(void) { device_info = "Windows tap device"; - logger(LOG_INFO, "%s (%s) is a %s", device, iface, device_info); + logger(DEBUG_ALWAYS, LOG_INFO, "%s (%s) is a %s", device, iface, device_info); return true; } -void close_device(void) { +static void close_device(void) { CloseHandle(device_handle); free(device); free(iface); } -bool read_packet(vpn_packet_t *packet) { +static bool read_packet(vpn_packet_t *packet) { return false; } -bool write_packet(vpn_packet_t *packet) { +static bool write_packet(vpn_packet_t *packet) { long outlen; OVERLAPPED overlapped = {0}; - ifdebug(TRAFFIC) logger(LOG_DEBUG, "Writing packet of %d bytes to %s", + logger(DEBUG_TRAFFIC, LOG_DEBUG, "Writing packet of %d bytes to %s", packet->len, device_info); if(!WriteFile(device_handle, packet->data, packet->len, &outlen, &overlapped)) { - logger(LOG_ERR, "Error while writing to %s %s: %s", device_info, device, winerror(GetLastError())); + logger(DEBUG_ALWAYS, LOG_ERR, "Error while writing to %s %s: %s", device_info, device, winerror(GetLastError())); return false; } @@ -238,8 +238,16 @@ bool write_packet(vpn_packet_t *packet) { return true; } -void dump_device_stats(void) { - logger(LOG_DEBUG, "Statistics for %s %s:", device_info, device); - logger(LOG_DEBUG, " total bytes in: %10"PRIu64, device_total_in); - logger(LOG_DEBUG, " total bytes out: %10"PRIu64, device_total_out); +static void dump_device_stats(void) { + logger(DEBUG_ALWAYS, LOG_DEBUG, "Statistics for %s %s:", device_info, device); + logger(DEBUG_ALWAYS, LOG_DEBUG, " total bytes in: %10"PRIu64, device_total_in); + logger(DEBUG_ALWAYS, LOG_DEBUG, " total bytes out: %10"PRIu64, device_total_out); } + +const devops_t os_devops = { + .setup = setup_device, + .close = close_device, + .read = read_packet, + .write = write_packet, + .dump_stats = dump_device_stats, +}; diff --git a/src/multicast_device.c b/src/multicast_device.c new file mode 100644 index 0000000..bd9ef1d --- /dev/null +++ b/src/multicast_device.c @@ -0,0 +1,235 @@ +/* + device.c -- multicast socket + Copyright (C) 2002-2005 Ivo Timmermans, + 2002-2012 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "system.h" + +#include "conf.h" +#include "device.h" +#include "net.h" +#include "logger.h" +#include "netutl.h" +#include "utils.h" +#include "route.h" +#include "xalloc.h" + +static char *device_info; + +static uint64_t device_total_in = 0; +static uint64_t device_total_out = 0; + +static struct addrinfo *ai = NULL; +static mac_t ignore_src = {{0}}; + +static bool setup_device(void) { + char *host = NULL; + char *port; + char *space; + int ttl = 1; + + device_info = "multicast socket"; + + get_config_string(lookup_config(config_tree, "Interface"), &iface); + + if(!get_config_string(lookup_config(config_tree, "Device"), &device)) { + logger(DEBUG_ALWAYS, LOG_ERR, "Device variable required for %s", device_info); + goto error; + } + + host = xstrdup(device); + space = strchr(host, ' '); + if(!space) { + logger(DEBUG_ALWAYS, LOG_ERR, "Port number required for %s", device_info); + goto error; + } + + *space++ = 0; + port = space; + space = strchr(port, ' '); + + if(space) { + *space++ = 0; + ttl = atoi(space); + } + + ai = str2addrinfo(host, port, SOCK_DGRAM); + if(!ai) + goto error; + + device_fd = socket(ai->ai_family, SOCK_DGRAM, IPPROTO_UDP); + if(device_fd < 0) { + logger(DEBUG_ALWAYS, LOG_ERR, "Creating socket failed: %s", sockstrerror(sockerrno)); + goto error; + } + +#ifdef FD_CLOEXEC + fcntl(device_fd, F_SETFD, FD_CLOEXEC); +#endif + + static const int one = 1; + setsockopt(device_fd, SOL_SOCKET, SO_REUSEADDR, (void *)&one, sizeof one); + + if(bind(device_fd, ai->ai_addr, ai->ai_addrlen)) { + logger(DEBUG_ALWAYS, LOG_ERR, "Can't bind to %s %s: %s", host, port, sockstrerror(sockerrno)); + goto error; + } + + switch(ai->ai_family) { +#ifdef IP_ADD_MEMBERSHIP + case AF_INET: { + struct ip_mreq mreq; + struct sockaddr_in in; + memcpy(&in, ai->ai_addr, sizeof in); + mreq.imr_multiaddr.s_addr = in.sin_addr.s_addr; + mreq.imr_interface.s_addr = htonl(INADDR_ANY); + if(setsockopt(device_fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (void *)&mreq, sizeof mreq)) { + logger(DEBUG_ALWAYS, LOG_ERR, "Cannot join multicast group %s %s: %s", host, port, sockstrerror(sockerrno)); + goto error; + } +#ifdef IP_MULTICAST_LOOP + setsockopt(device_fd, IPPROTO_IP, IP_MULTICAST_LOOP, (const void *)&one, sizeof one); +#endif +#ifdef IP_MULTICAST_TTL + setsockopt(device_fd, IPPROTO_IP, IP_MULTICAST_TTL, (void *)&ttl, sizeof ttl); +#endif + } break; +#endif + +#ifdef IPV6_JOIN_GROUP + case AF_INET6: { + struct ipv6_mreq mreq; + struct sockaddr_in6 in6; + memcpy(&in6, ai->ai_addr, sizeof in6); + memcpy(&mreq.ipv6mr_multiaddr, &in6.sin6_addr, sizeof mreq.ipv6mr_multiaddr); + mreq.ipv6mr_interface = in6.sin6_scope_id; + if(setsockopt(device_fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, (void *)&mreq, sizeof mreq)) { + logger(DEBUG_ALWAYS, LOG_ERR, "Cannot join multicast group %s %s: %s", host, port, sockstrerror(sockerrno)); + goto error; + } +#ifdef IPV6_MULTICAST_LOOP + setsockopt(device_fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, (const void *)&one, sizeof one); +#endif +#ifdef IPV6_MULTICAST_HOPS + setsockopt(device_fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, (void *)&ttl, sizeof ttl); +#endif + } break; +#endif + + default: + logger(DEBUG_ALWAYS, LOG_ERR, "Multicast for address family %hx unsupported", ai->ai_family); + goto error; + } + + freeaddrinfo(ai); + + logger(DEBUG_ALWAYS, LOG_INFO, "%s is a %s", device, device_info); + + return true; + +error: + if(device_fd >= 0) + closesocket(device_fd); + if(ai) + freeaddrinfo(ai); + free(host); + + return false; +} + +static void close_device(void) { + close(device_fd); + + free(device); + free(iface); + + if(ai) + freeaddrinfo(ai); +} + +static bool read_packet(vpn_packet_t *packet) { + int lenin; + + if((lenin = recv(device_fd, packet->data, MTU, 0)) <= 0) { + logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info, + device, strerror(errno)); + return false; + } + + if(!memcmp(&ignore_src, packet->data + 6, sizeof ignore_src)) { + logger(DEBUG_SCARY_THINGS, LOG_DEBUG, "Ignoring loopback packet of %d bytes from %s", lenin, device_info); + packet->len = 0; + return true; + } + + packet->len = lenin; + + device_total_in += packet->len; + + logger(DEBUG_TRAFFIC, LOG_DEBUG, "Read packet of %d bytes from %s", packet->len, + device_info); + + return true; +} + +static bool write_packet(vpn_packet_t *packet) { + logger(DEBUG_TRAFFIC, LOG_DEBUG, "Writing packet of %d bytes to %s", + packet->len, device_info); + + if(sendto(device_fd, packet->data, packet->len, 0, ai->ai_addr, ai->ai_addrlen) < 0) { + logger(DEBUG_ALWAYS, LOG_ERR, "Can't write to %s %s: %s", device_info, device, + strerror(errno)); + return false; + } + + device_total_out += packet->len; + + memcpy(&ignore_src, packet->data + 6, sizeof ignore_src); + + return true; +} + +static void dump_device_stats(void) { + logger(DEBUG_ALWAYS, LOG_DEBUG, "Statistics for %s %s:", device_info, device); + logger(DEBUG_ALWAYS, LOG_DEBUG, " total bytes in: %10"PRIu64, device_total_in); + logger(DEBUG_ALWAYS, LOG_DEBUG, " total bytes out: %10"PRIu64, device_total_out); +} + +const devops_t multicast_devops = { + .setup = setup_device, + .close = close_device, + .read = read_packet, + .write = write_packet, + .dump_stats = dump_device_stats, +}; + +#if 0 + +static bool not_supported(void) { + logger(DEBUG_ALWAYS, LOG_ERR, "Raw socket device not supported on this platform"); + return false; +} + +const devops_t multicast_devops = { + .setup = not_supported, + .close = NULL, + .read = NULL, + .write = NULL, + .dump_stats = NULL, +}; +#endif diff --git a/src/net.c b/src/net.c index f9020b3..f8ffbe3 100644 --- a/src/net.c +++ b/src/net.c @@ -1,9 +1,9 @@ /* net.c -- most of the network code Copyright (C) 1998-2005 Ivo Timmermans, - 2000-2011 Guus Sliepen + 2000-2012 Guus Sliepen 2006 Scott Lamb - 2011 Loïc Grenié + 2011 Loïc Grenié 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 @@ -23,7 +23,6 @@ #include "system.h" #include "utils.h" -#include "splay_tree.h" #include "conf.h" #include "connection.h" #include "device.h" @@ -40,40 +39,28 @@ int contradicting_add_edge = 0; int contradicting_del_edge = 0; static int sleeptime = 10; +time_t last_config_check = 0; /* Purge edges and subnets of unreachable nodes. Use carefully. */ void purge(void) { - splay_node_t *nnode, *nnext, *enode, *enext, *snode, *snext; - node_t *n; - edge_t *e; - subnet_t *s; - - ifdebug(PROTOCOL) logger(LOG_DEBUG, "Purging unreachable nodes"); + logger(DEBUG_PROTOCOL, LOG_DEBUG, "Purging unreachable nodes"); /* Remove all edges and subnets owned by unreachable nodes. */ - for(nnode = node_tree->head; nnode; nnode = nnext) { - nnext = nnode->next; - n = nnode->data; - + for splay_each(node_t, n, node_tree) { if(!n->status.reachable) { - ifdebug(SCARY_THINGS) logger(LOG_DEBUG, "Purging node %s (%s)", n->name, - n->hostname); + logger(DEBUG_SCARY_THINGS, LOG_DEBUG, "Purging node %s (%s)", n->name, n->hostname); - for(snode = n->subnet_tree->head; snode; snode = snext) { - snext = snode->next; - s = snode->data; - send_del_subnet(broadcast, s); + for splay_each(subnet_t, s, n->subnet_tree) { + send_del_subnet(everyone, s); if(!strictsubnets) subnet_del(n, s); } - for(enode = n->edge_tree->head; enode; enode = enext) { - enext = enode->next; - e = enode->data; + for splay_each(edge_t, e, n->edge_tree) { if(!tunnelserver) - send_del_edge(broadcast, e); + send_del_edge(everyone, e); edge_del(e); } } @@ -81,20 +68,13 @@ void purge(void) { /* Check if anyone else claims to have an edge to an unreachable node. If not, delete node. */ - for(nnode = node_tree->head; nnode; nnode = nnext) { - nnext = nnode->next; - n = nnode->data; - + for splay_each(node_t, n, node_tree) { if(!n->status.reachable) { - for(enode = edge_weight_tree->head; enode; enode = enext) { - enext = enode->next; - e = enode->data; - + for splay_each(edge_t, e, edge_weight_tree) if(e->to == n) - break; - } + return; - if(!enode && (!strictsubnets || !n->subnet_tree->head)) + if(!strictsubnets || !n->subnet_tree->head) /* in strictsubnets mode do not delete nodes with subnets */ node_del(n); } @@ -103,25 +83,25 @@ void purge(void) { /* Terminate a connection: - - Close the socket - - Remove associated edge and tell other connections about it if report = true + - Mark it as inactive + - Remove the edge representing this connection + - Kill it with fire - Check if we need to retry making an outgoing connection - - Deactivate the host */ void terminate_connection(connection_t *c, bool report) { - ifdebug(CONNECTIONS) logger(LOG_NOTICE, "Closing connection with %s (%s)", - c->name, c->hostname); + logger(DEBUG_CONNECTIONS, LOG_NOTICE, "Closing connection with %s (%s)", c->name, c->hostname); c->status.active = false; - if(c->node) + if(c->node && c->node->connection == c) c->node->connection = NULL; if(c->edge) { if(report && !tunnelserver) - send_del_edge(broadcast, c->edge); + send_del_edge(everyone, c->edge); edge_del(c->edge); + c->edge = NULL; /* Run MST and SSSP algorithms */ @@ -134,18 +114,19 @@ void terminate_connection(connection_t *c, bool report) { e = lookup_edge(c->node, myself); if(e) { if(!tunnelserver) - send_del_edge(broadcast, e); + send_del_edge(everyone, e); edge_del(e); } } } + outgoing_t *outgoing = c->outgoing; + connection_del(c); + /* Check if this was our outgoing connection */ - if(c->outgoing) - retry_outgoing(c->outgoing); - - connection_del(c); + if(outgoing) + do_outgoing_connection(outgoing); } /* @@ -157,42 +138,34 @@ void terminate_connection(connection_t *c, bool report) { and close the connection. */ static void timeout_handler(int fd, short events, void *event) { - splay_node_t *node, *next; - connection_t *c; time_t now = time(NULL); - for(node = connection_tree->head; node; node = next) { - next = node->next; - c = node->data; + for list_each(connection_t, c, connection_list) { + if(c->status.control) + continue; if(c->last_ping_time + pingtimeout <= now) { if(c->status.active) { if(c->status.pinged) { - ifdebug(CONNECTIONS) logger(LOG_INFO, "%s (%s) didn't respond to PING in %ld seconds", - c->name, c->hostname, now - c->last_ping_time); - terminate_connection(c, true); - continue; + logger(DEBUG_CONNECTIONS, LOG_INFO, "%s (%s) didn't respond to PING in %ld seconds", c->name, c->hostname, (long)now - c->last_ping_time); } else if(c->last_ping_time + pinginterval <= now) { send_ping(c); - } - } else { - if(c->status.connecting) { - ifdebug(CONNECTIONS) - logger(LOG_WARNING, "Timeout while connecting to %s (%s)", c->name, c->hostname); - c->status.connecting = false; - closesocket(c->socket); - do_outgoing_connection(c); + continue; } else { - ifdebug(CONNECTIONS) logger(LOG_WARNING, "Timeout from %s (%s) during authentication", c->name, c->hostname); - terminate_connection(c, false); continue; } + } else { + if(c->status.connecting) + logger(DEBUG_CONNECTIONS, LOG_WARNING, "Timeout while connecting to %s (%s)", c->name, c->hostname); + else + logger(DEBUG_CONNECTIONS, LOG_WARNING, "Timeout from %s (%s) during authentication", c->name, c->hostname); } + terminate_connection(c, c->status.active); } } if(contradicting_del_edge > 100 && contradicting_add_edge > 100) { - logger(LOG_WARNING, "Possible node with same Name as us! Sleeping %d seconds.", sleeptime); + logger(DEBUG_ALWAYS, LOG_WARNING, "Possible node with same Name as us! Sleeping %d seconds.", sleeptime); usleep(sleeptime * 1000000LL); sleeptime *= 2; if(sleeptime < 0) @@ -222,11 +195,8 @@ void handle_meta_connection_data(int fd, short events, void *data) { if(!result) finish_connecting(c); else { - ifdebug(CONNECTIONS) logger(LOG_DEBUG, - "Error while connecting to %s (%s): %s", - c->name, c->hostname, sockstrerror(result)); - closesocket(c->socket); - do_outgoing_connection(c); + logger(DEBUG_CONNECTIONS, LOG_DEBUG, "Error while connecting to %s (%s): %s", c->name, c->hostname, sockstrerror(result)); + terminate_connection(c, false); return; } } @@ -238,27 +208,23 @@ void handle_meta_connection_data(int fd, short events, void *data) { } static void sigterm_handler(int signal, short events, void *data) { - logger(LOG_NOTICE, "Got %s signal", strsignal(signal)); + logger(DEBUG_ALWAYS, LOG_NOTICE, "Got %s signal", strsignal(signal)); event_loopexit(NULL); } static void sighup_handler(int signal, short events, void *data) { - logger(LOG_NOTICE, "Got %s signal", strsignal(signal)); + logger(DEBUG_ALWAYS, LOG_NOTICE, "Got %s signal", strsignal(signal)); reopenlogger(); reload_configuration(); } static void sigalrm_handler(int signal, short events, void *data) { - logger(LOG_NOTICE, "Got %s signal", strsignal(signal)); + logger(DEBUG_ALWAYS, LOG_NOTICE, "Got %s signal", strsignal(signal)); retry(); } int reload_configuration(void) { - connection_t *c; - splay_node_t *node, *next; char *fname; - struct stat s; - static time_t last_config_check = 0; /* Reread our own configuration file */ @@ -266,85 +232,112 @@ int reload_configuration(void) { init_configuration(&config_tree); if(!read_server_config()) { - logger(LOG_ERR, "Unable to reread configuration file, exitting."); + logger(DEBUG_ALWAYS, LOG_ERR, "Unable to reread configuration file, exitting."); event_loopexit(NULL); return EINVAL; } - /* Close connections to hosts that have a changed or deleted host config file */ - - for(node = connection_tree->head; node; node = next) { - c = node->data; - next = node->next; - - if(c->outgoing) { - free(c->outgoing->name); - if(c->outgoing->ai) - freeaddrinfo(c->outgoing->ai); - free(c->outgoing); - c->outgoing = NULL; - } - - xasprintf(&fname, "%s/hosts/%s", confbase, c->name); - if(stat(fname, &s) || s.st_mtime > last_config_check) - terminate_connection(c, c->status.active); - free(fname); - } + read_config_options(config_tree, NULL); - last_config_check = time(NULL); + xasprintf(&fname, "%s" SLASH "hosts" SLASH "%s", confbase, myself->name); + read_config_file(config_tree, fname); + free(fname); + + /* Parse some options that are allowed to be changed while tinc is running */ + + setup_myself_reloadable(); /* 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; + for splay_each(subnet_t, subnet, subnet_tree) subnet->expires = 1; - } load_all_subnets(); - for(node = subnet_tree->head; node; node = next) { - next = node->next; - subnet = node->data; + for splay_each(subnet_t, subnet, subnet_tree) { if(subnet->expires == 1) { - send_del_subnet(broadcast, subnet); + send_del_subnet(everyone, 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); + send_add_subnet(everyone, subnet); if(subnet->owner->status.reachable) subnet_update(subnet->owner, subnet, true); } } + } else { /* Only read our own subnets back in */ + for splay_each(subnet_t, subnet, myself->subnet_tree) + if(!subnet->expires) + subnet->expires = 1; + + config_t *cfg = lookup_config(config_tree, "Subnet"); + + while(cfg) { + subnet_t *subnet, *s2; + + if(!get_config_subnet(cfg, &subnet)) + continue; + + if((s2 = lookup_subnet(myself, subnet))) { + if(s2->expires == 1) + s2->expires = 0; + + free_subnet(subnet); + } else { + subnet_add(myself, subnet); + send_add_subnet(everyone, subnet); + subnet_update(myself, subnet, true); + } + + cfg = lookup_config_next(config_tree, cfg); + } + + for splay_each(subnet_t, subnet, myself->subnet_tree) { + if(subnet->expires == 1) { + send_del_subnet(everyone, subnet); + subnet_update(myself, subnet, false); + subnet_del(myself, subnet); + } + } } /* Try to make outgoing connections */ - + try_outgoing_connections(); + /* Close connections to hosts that have a changed or deleted host config file */ + + for list_each(connection_t, c, connection_list) { + if(c->status.control) + continue; + + xasprintf(&fname, "%s" SLASH "hosts" SLASH "%s", confbase, c->name); + struct stat s; + if(stat(fname, &s) || s.st_mtime > last_config_check) { + logger(DEBUG_CONNECTIONS, LOG_INFO, "Host config file of %s has been changed", c->name); + terminate_connection(c, c->status.active); + } + free(fname); + } + + last_config_check = time(NULL); + return 0; } void retry(void) { - connection_t *c; - splay_node_t *node; - - for(node = connection_tree->head; node; node = node->next) { - c = node->data; - + for list_each(connection_t, c, connection_list) { if(c->outgoing && !c->node) { if(timeout_initialized(&c->outgoing->ev)) event_del(&c->outgoing->ev); if(c->status.connecting) close(c->socket); c->outgoing->timeout = 0; - do_outgoing_connection(c); + terminate_connection(c, c->status.active); } } } @@ -375,7 +368,7 @@ int main_loop(void) { #endif if(event_loop(0) < 0) { - logger(LOG_ERR, "Error while waiting for input: %s", strerror(errno)); + logger(DEBUG_ALWAYS, LOG_ERR, "Error while waiting for input: %s", strerror(errno)); return 1; } diff --git a/src/net.h b/src/net.h index c511a5f..23b8cae 100644 --- a/src/net.h +++ b/src/net.h @@ -1,7 +1,7 @@ /* net.h -- header for net.c Copyright (C) 1998-2005 Ivo Timmermans - 2000-2009 Guus Sliepen + 2000-2012 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 @@ -26,15 +26,18 @@ #include "digest.h" #ifdef ENABLE_JUMBOGRAMS -#define MTU 9018 /* 9000 bytes payload + 14 bytes ethernet header + 4 bytes VLAN tag */ +#define MTU 9018 /* 9000 bytes payload + 14 bytes ethernet header + 4 bytes VLAN tag */ #else -#define MTU 1518 /* 1500 bytes payload + 14 bytes ethernet header + 4 bytes VLAN tag */ +#define MTU 1518 /* 1500 bytes payload + 14 bytes ethernet header + 4 bytes VLAN tag */ #endif -#define MAXSIZE (MTU + 4 + CIPHER_MAX_BLOCK_SIZE + DIGEST_MAX_SIZE + MTU/64 + 20) /* MTU + seqno + padding + HMAC + compressor overhead */ -#define MAXBUFSIZE ((MAXSIZE > 2048 ? MAXSIZE : 2048) + 128) /* Enough room for a request with a MAXSIZEd packet or a 8192 bits RSA key */ +/* MAXSIZE is the maximum size of an encapsulated packet: MTU + seqno + padding + HMAC + compressor overhead */ +#define MAXSIZE (MTU + 4 + CIPHER_MAX_BLOCK_SIZE + DIGEST_MAX_SIZE + MTU/64 + 20) -#define MAXSOCKETS 8 /* Probably overkill... */ +/* MAXBUFSIZE is the maximum size of a request: enough for a MAXSIZEd packet or a 8192 bits RSA key */ +#define MAXBUFSIZE ((MAXSIZE > 2048 ? MAXSIZE : 2048) + 128) + +#define MAXSOCKETS 8 /* Probably overkill... */ typedef struct mac_t { uint8_t x[6]; @@ -77,12 +80,24 @@ typedef union sockaddr_t { #endif typedef struct vpn_packet_t { - length_t len; /* the actual number of bytes in the `data' field */ - int priority; /* priority or TOS */ - uint32_t seqno; /* 32 bits sequence number (network byte order of course) */ + length_t len; /* the actual number of bytes in the `data' field */ + int priority; /* priority or TOS */ + uint32_t seqno; /* 32 bits sequence number (network byte order of course) */ uint8_t data[MAXSIZE]; } vpn_packet_t; +/* Packet types when using SPTPS */ + +#define PKT_COMPRESSED 1 +#define PKT_MAC 2 +#define PKT_PROBE 4 + +typedef enum packet_type_t { + PACKET_NORMAL, + PACKET_COMPRESSED, + PACKET_PROBE +} packet_type_t; + typedef struct listen_socket_t { struct event ev_tcp; struct event ev_udp; @@ -97,6 +112,7 @@ typedef struct listen_socket_t { typedef struct outgoing_t { char *name; int timeout; + splay_tree_t *config_tree; struct config_t *cfg; struct addrinfo *ai; struct addrinfo *aip; @@ -109,6 +125,7 @@ extern int maxoutbufsize; extern int seconds_till_retry; extern int addressfamily; extern unsigned replaywin; +extern bool localdiscovery; extern listen_socket_t listen_socket[MAXSOCKETS]; extern int listen_sockets; @@ -119,6 +136,24 @@ extern bool do_prune; extern char *myport; extern int contradicting_add_edge; extern int contradicting_del_edge; +extern time_t last_config_check; + +extern char *proxyhost; +extern char *proxyport; +extern char *proxyuser; +extern char *proxypass; +typedef enum proxytype_t { + PROXY_NONE = 0, + PROXY_SOCKS4, + PROXY_SOCKS4A, + PROXY_SOCKS5, + PROXY_HTTP, + PROXY_EXEC, +} proxytype_t; +extern proxytype_t proxytype; + +extern char *scriptinterpreter; +extern char *scriptextension; /* Yes, very strange placement indeed, but otherwise the typedefs get all tangled up */ #include "connection.h" @@ -127,20 +162,23 @@ extern int contradicting_del_edge; extern void retry_outgoing(outgoing_t *); extern void handle_incoming_vpn_data(int, short, void *); extern void finish_connecting(struct connection_t *); -extern bool do_outgoing_connection(struct connection_t *); +extern bool do_outgoing_connection(struct outgoing_t *); extern void handle_new_meta_connection(int, short, void *); extern int setup_listen_socket(const sockaddr_t *); extern int setup_vpn_in_socket(const sockaddr_t *); +extern bool send_sptps_data(void *handle, uint8_t type, const char *data, size_t len); +extern bool receive_sptps_record(void *handle, uint8_t type, const char *data, uint16_t len); extern void send_packet(struct node_t *, vpn_packet_t *); extern void receive_tcppacket(struct connection_t *, const char *, int); extern void broadcast_packet(const struct node_t *, vpn_packet_t *); +extern char *get_name(void); +extern bool setup_myself_reloadable(void); extern bool setup_network(void); extern void setup_outgoing_connection(struct outgoing_t *); extern void try_outgoing_connections(void); extern void close_network_connections(void); extern int main_loop(void); extern void terminate_connection(struct connection_t *, bool); -extern void flush_queue(struct node_t *); extern bool node_read_ecdsa_public_key(struct node_t *); extern bool read_ecdsa_public_key(struct connection_t *); extern bool read_rsa_public_key(struct connection_t *); @@ -159,4 +197,4 @@ extern void load_all_subnets(void); extern CRITICAL_SECTION mutex; #endif -#endif /* __TINC_NET_H__ */ +#endif /* __TINC_NET_H__ */ diff --git a/src/net_packet.c b/src/net_packet.c index 3627f31..67ebc22 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-2011 Guus Sliepen + 2000-2012 Guus Sliepen 2010 Timothy Redaelli 2010 Brandon Black @@ -36,7 +36,6 @@ #include LZO1X_H #endif -#include "splay_tree.h" #include "cipher.h" #include "conf.h" #include "connection.h" @@ -62,24 +61,30 @@ static char lzo_wrkmem[LZO1X_999_MEM_COMPRESS > LZO1X_1_MEM_COMPRESS ? LZO1X_999 static void send_udppacket(node_t *, vpn_packet_t *); unsigned replaywin = 16; +bool localdiscovery = false; #define MAX_SEQNO 1073741824 -// mtuprobes == 1..30: initial discovery, send bursts with 1 second interval -// mtuprobes == 31: sleep pinginterval seconds -// mtuprobes == 32: send 1 burst, sleep pingtimeout second -// mtuprobes == 33: no response from other side, restart PMTU discovery process +/* mtuprobes == 1..30: initial discovery, send bursts with 1 second interval + mtuprobes == 31: sleep pinginterval seconds + mtuprobes == 32: send 1 burst, sleep pingtimeout second + mtuprobes == 33: no response from other side, restart PMTU discovery process + + Probes are sent in batches of three, with random sizes between the lower and + upper boundaries for the MTU thus far discovered. + + In case local discovery is enabled, a fourth packet is added to each batch, + which will be broadcast to the local network. +*/ static void send_mtu_probe_handler(int fd, short events, void *data) { node_t *n = data; - vpn_packet_t packet; - int len, i; int timeout = 1; - + n->mtuprobes++; if(!n->status.reachable || !n->status.validkey) { - ifdebug(TRAFFIC) logger(LOG_INFO, "Trying to send MTU probe to unreachable or rekeying node %s (%s)", n->name, n->hostname); + logger(DEBUG_TRAFFIC, LOG_INFO, "Trying to send MTU probe to unreachable or rekeying node %s (%s)", n->name, n->hostname); n->mtuprobes = 0; return; } @@ -91,14 +96,15 @@ static void send_mtu_probe_handler(int fd, short events, void *data) { goto end; } - ifdebug(TRAFFIC) logger(LOG_INFO, "%s (%s) did not respond to UDP ping, restarting PMTU discovery", n->name, n->hostname); + logger(DEBUG_TRAFFIC, LOG_INFO, "%s (%s) did not respond to UDP ping, restarting PMTU discovery", n->name, n->hostname); + n->status.udp_confirmed = false; n->mtuprobes = 1; n->minmtu = 0; n->maxmtu = MTU; } if(n->mtuprobes >= 10 && n->mtuprobes < 32 && !n->minmtu) { - ifdebug(TRAFFIC) logger(LOG_INFO, "No response to MTU probes from %s (%s)", n->name, n->hostname); + logger(DEBUG_TRAFFIC, LOG_INFO, "No response to MTU probes from %s (%s)", n->name, n->hostname); n->mtuprobes = 31; } @@ -108,7 +114,7 @@ static void send_mtu_probe_handler(int fd, short events, void *data) { else n->maxmtu = n->minmtu; n->mtu = n->minmtu; - ifdebug(TRAFFIC) logger(LOG_INFO, "Fixing MTU of %s (%s) to %d after %d probes", n->name, n->hostname, n->mtu, n->mtuprobes); + logger(DEBUG_TRAFFIC, LOG_INFO, "Fixing MTU of %s (%s) to %d after %d probes", n->name, n->hostname, n->mtu, n->mtuprobes); n->mtuprobes = 31; } @@ -119,7 +125,9 @@ static void send_mtu_probe_handler(int fd, short events, void *data) { timeout = pingtimeout; } - for(i = 0; i < 3; i++) { + for(int i = 0; i < 3 + localdiscovery; i++) { + int len; + if(n->maxmtu <= n->minmtu) len = n->maxmtu; else @@ -127,13 +135,17 @@ static void send_mtu_probe_handler(int fd, short events, void *data) { if(len < 64) len = 64; - + + vpn_packet_t packet; memset(packet.data, 0, 14); randomize(packet.data + 14, len - 14); packet.len = len; - packet.priority = 0; + if(i >= 3 && n->mtuprobes <= 10) + packet.priority = -1; + else + packet.priority = 0; - ifdebug(TRAFFIC) logger(LOG_INFO, "Sending MTU probe length %d to %s (%s)", len, n->name, n->hostname); + logger(DEBUG_TRAFFIC, LOG_INFO, "Sending MTU probe length %d to %s (%s)", len, n->name, n->hostname); send_udppacket(n, &packet); } @@ -149,12 +161,14 @@ void send_mtu_probe(node_t *n) { } static void mtu_probe_h(node_t *n, vpn_packet_t *packet, length_t len) { - ifdebug(TRAFFIC) logger(LOG_INFO, "Got MTU probe length %d from %s (%s)", packet->len, n->name, n->hostname); + logger(DEBUG_TRAFFIC, LOG_INFO, "Got MTU probe length %d from %s (%s)", packet->len, n->name, n->hostname); if(!packet->data[0]) { packet->data[0] = 1; send_udppacket(n, packet); } else { + n->status.udp_confirmed = true; + if(n->mtuprobes > 30) { if(n->minmtu) n->mtuprobes = 30; @@ -198,7 +212,7 @@ static length_t compress_packet(uint8_t *dest, const uint8_t *source, length_t l return -1; #endif } - + return -1; } @@ -231,7 +245,7 @@ static length_t uncompress_packet(uint8_t *dest, const uint8_t *source, length_t /* VPN packet I/O */ static void receive_packet(node_t *n, vpn_packet_t *packet) { - ifdebug(TRAFFIC) logger(LOG_DEBUG, "Received packet of %d bytes from %s (%s)", + logger(DEBUG_TRAFFIC, LOG_DEBUG, "Received packet of %d bytes from %s (%s)", packet->len, n->name, n->hostname); n->in_packets++; @@ -241,6 +255,9 @@ static void receive_packet(node_t *n, vpn_packet_t *packet) { } static bool try_mac(node_t *n, const vpn_packet_t *inpkt) { + if(n->status.sptps) + return sptps_verify_datagram(&n->sptps, (char *)&inpkt->seqno, inpkt->len); + if(!digest_active(&n->indigest) || inpkt->len < sizeof inpkt->seqno + digest_length(&n->indigest)) return false; @@ -254,8 +271,13 @@ static void receive_udppacket(node_t *n, vpn_packet_t *inpkt) { vpn_packet_t *outpkt = pkt[0]; size_t outlen; + if(n->status.sptps) { + sptps_receive_data(&n->sptps, (char *)&inpkt->seqno, inpkt->len); + return; + } + if(!cipher_active(&n->incipher)) { - ifdebug(TRAFFIC) logger(LOG_DEBUG, "Got packet from %s (%s) but he hasn't got our key yet", + logger(DEBUG_TRAFFIC, LOG_DEBUG, "Got packet from %s (%s) but he hasn't got our key yet", n->name, n->hostname); return; } @@ -263,7 +285,7 @@ static void receive_udppacket(node_t *n, vpn_packet_t *inpkt) { /* Check packet length */ if(inpkt->len < sizeof inpkt->seqno + digest_length(&n->indigest)) { - ifdebug(TRAFFIC) logger(LOG_DEBUG, "Got too short packet from %s (%s)", + logger(DEBUG_TRAFFIC, LOG_DEBUG, "Got too short packet from %s (%s)", n->name, n->hostname); return; } @@ -272,8 +294,8 @@ static void receive_udppacket(node_t *n, vpn_packet_t *inpkt) { if(digest_active(&n->indigest)) { inpkt->len -= n->indigest.maclength; - if(!digest_verify(&n->indigest, &inpkt->seqno, inpkt->len, (const char *)&inpkt->seqno + inpkt->len)) { - ifdebug(TRAFFIC) logger(LOG_DEBUG, "Got unauthenticated packet from %s (%s)", n->name, n->hostname); + if(!digest_verify(&n->indigest, &inpkt->seqno, inpkt->len, (const char *)&inpkt->seqno + inpkt->len)) { + logger(DEBUG_TRAFFIC, LOG_DEBUG, "Got unauthenticated packet from %s (%s)", n->name, n->hostname); return; } } @@ -284,10 +306,10 @@ static void receive_udppacket(node_t *n, vpn_packet_t *inpkt) { outlen = MAXSIZE; if(!cipher_decrypt(&n->incipher, &inpkt->seqno, inpkt->len, &outpkt->seqno, &outlen, true)) { - ifdebug(TRAFFIC) logger(LOG_DEBUG, "Error decrypting packet from %s (%s)", n->name, n->hostname); + logger(DEBUG_TRAFFIC, LOG_DEBUG, "Error decrypting packet from %s (%s)", n->name, n->hostname); return; } - + outpkt->len = outlen; inpkt = outpkt; } @@ -301,17 +323,17 @@ static void receive_udppacket(node_t *n, vpn_packet_t *inpkt) { if(inpkt->seqno != n->received_seqno + 1) { if(inpkt->seqno >= n->received_seqno + replaywin * 8) { if(n->farfuture++ < replaywin >> 2) { - logger(LOG_WARNING, "Packet from %s (%s) is %d seqs in the future, dropped (%u)", + logger(DEBUG_ALWAYS, LOG_WARNING, "Packet from %s (%s) is %d seqs in the future, dropped (%u)", n->name, n->hostname, inpkt->seqno - n->received_seqno - 1, n->farfuture); return; } - logger(LOG_WARNING, "Lost %d packets from %s (%s)", - inpkt->seqno - n->received_seqno - 1, n->name, n->hostname); + logger(DEBUG_ALWAYS, LOG_WARNING, "Lost %d packets from %s (%s)", + inpkt->seqno - n->received_seqno - 1, n->name, n->hostname); memset(n->late, 0, replaywin); } else if (inpkt->seqno <= n->received_seqno) { if((n->received_seqno >= replaywin * 8 && inpkt->seqno <= n->received_seqno - replaywin * 8) || !(n->late[(inpkt->seqno / 8) % replaywin] & (1 << inpkt->seqno % 8))) { - logger(LOG_WARNING, "Got late or replayed packet from %s (%s), seqno %d, last received %d", - n->name, n->hostname, inpkt->seqno, n->received_seqno); + logger(DEBUG_ALWAYS, LOG_WARNING, "Got late or replayed packet from %s (%s), seqno %d, last received %d", + n->name, n->hostname, inpkt->seqno, n->received_seqno); return; } } else { @@ -326,7 +348,7 @@ static void receive_udppacket(node_t *n, vpn_packet_t *inpkt) { if(inpkt->seqno > n->received_seqno) n->received_seqno = inpkt->seqno; - + if(n->received_seqno > MAX_SEQNO) regenerate_key(); @@ -338,8 +360,8 @@ static void receive_udppacket(node_t *n, vpn_packet_t *inpkt) { outpkt = pkt[nextpkt++]; if((outpkt->len = uncompress_packet(outpkt->data, inpkt->data, inpkt->len, n->incompression)) < 0) { - ifdebug(TRAFFIC) logger(LOG_ERR, "Error while uncompressing packet from %s (%s)", - n->name, n->hostname); + logger(DEBUG_TRAFFIC, LOG_ERR, "Error while uncompressing packet from %s (%s)", + n->name, n->hostname); return; } @@ -369,6 +391,53 @@ void receive_tcppacket(connection_t *c, const char *buffer, int len) { receive_packet(c->node, &outpkt); } +static void send_sptps_packet(node_t *n, vpn_packet_t *origpkt) { + if(!n->status.validkey) { + logger(DEBUG_TRAFFIC, LOG_INFO, "No valid key known yet for %s (%s)", n->name, n->hostname); + if(!n->status.waitingforkey) + send_req_key(n); + else if(n->last_req_key + 10 < time(NULL)) { + logger(DEBUG_ALWAYS, LOG_DEBUG, "No key from %s after 10 seconds, restarting SPTPS", n->name); + sptps_stop(&n->sptps); + n->status.waitingforkey = false; + send_req_key(n); + } + return; + } + + uint8_t type = 0; + int offset = 0; + + if(!(origpkt->data[12] | origpkt->data[13])) { + sptps_send_record(&n->sptps, PKT_PROBE, (char *)origpkt->data, origpkt->len); + return; + } + + if(routing_mode == RMODE_ROUTER) + offset = 14; + else + type = PKT_MAC; + + if(origpkt->len < offset) + return; + + vpn_packet_t outpkt; + + if(n->outcompression) { + int len = compress_packet(outpkt.data + offset, origpkt->data + offset, origpkt->len - offset, n->outcompression); + if(len < 0) { + logger(DEBUG_TRAFFIC, LOG_ERR, "Error while compressing packet to %s (%s)", n->name, n->hostname); + } else if(len < origpkt->len - offset) { + outpkt.len = len + offset; + origpkt = &outpkt; + type |= PKT_COMPRESSED; + } + } + + sptps_send_record(&n->sptps, type, (char *)origpkt->data + offset, origpkt->len - offset); + return; +} + static void send_udppacket(node_t *n, vpn_packet_t *origpkt) { vpn_packet_t pkt1, pkt2; vpn_packet_t *pkt[] = { &pkt1, &pkt2, &pkt1, &pkt2 }; @@ -379,21 +448,23 @@ static void send_udppacket(node_t *n, vpn_packet_t *origpkt) { size_t outlen; #if defined(SOL_IP) && defined(IP_TOS) static int priority = 0; - int origpriority = origpkt->priority; #endif - int sock; + int origpriority = origpkt->priority; if(!n->status.reachable) { - ifdebug(TRAFFIC) logger(LOG_INFO, "Trying to send UDP packet to unreachable node %s (%s)", n->name, n->hostname); + logger(DEBUG_TRAFFIC, LOG_INFO, "Trying to send UDP packet to unreachable node %s (%s)", n->name, n->hostname); return; } + if(n->status.sptps) + return send_sptps_packet(n, origpkt); + /* Make sure we have a valid key */ if(!n->status.validkey) { time_t now = time(NULL); - ifdebug(TRAFFIC) logger(LOG_INFO, + logger(DEBUG_TRAFFIC, LOG_INFO, "No valid key known yet for %s (%s), forwarding via TCP", n->name, n->hostname); @@ -408,7 +479,7 @@ static void send_udppacket(node_t *n, vpn_packet_t *origpkt) { } if(n->options & OPTION_PMTU_DISCOVERY && inpkt->len > n->minmtu && (inpkt->data[12] | inpkt->data[13])) { - ifdebug(TRAFFIC) logger(LOG_INFO, + logger(DEBUG_TRAFFIC, LOG_INFO, "Packet for %s (%s) larger than minimum MTU, forwarding via %s", n->name, n->hostname, n != n->nexthop ? n->nexthop->name : "TCP"); @@ -426,7 +497,7 @@ static void send_udppacket(node_t *n, vpn_packet_t *origpkt) { outpkt = pkt[nextpkt++]; if((outpkt->len = compress_packet(outpkt->data, inpkt->data, inpkt->len, n->outcompression)) < 0) { - ifdebug(TRAFFIC) logger(LOG_ERR, "Error while compressing packet to %s (%s)", + logger(DEBUG_TRAFFIC, LOG_ERR, "Error while compressing packet to %s (%s)", n->name, n->hostname); return; } @@ -446,7 +517,7 @@ static void send_udppacket(node_t *n, vpn_packet_t *origpkt) { outlen = MAXSIZE; if(!cipher_encrypt(&n->outcipher, &inpkt->seqno, inpkt->len, &outpkt->seqno, &outlen, true)) { - ifdebug(TRAFFIC) logger(LOG_ERR, "Error while encrypting packet to %s (%s)", n->name, n->hostname); + logger(DEBUG_TRAFFIC, LOG_ERR, "Error while encrypting packet to %s (%s)", n->name, n->hostname); goto end; } @@ -461,41 +532,221 @@ static void send_udppacket(node_t *n, vpn_packet_t *origpkt) { inpkt->len += digest_length(&n->outdigest); } + /* Send the packet */ + + sockaddr_t *sa; + int sock; + + /* Overloaded use of priority field: -1 means local broadcast */ + + if(origpriority == -1 && n->prevedge) { + sockaddr_t broadcast; + broadcast.in.sin_family = AF_INET; + broadcast.in.sin_addr.s_addr = -1; + broadcast.in.sin_port = n->prevedge->address.in.sin_port; + sa = &broadcast; + sock = 0; + } else { + if(origpriority == -1) + origpriority = 0; + + if(n->status.udp_confirmed) { + /* Address of this node is confirmed, so use it. */ + sa = &n->address; + sock = n->sock; + } else { + /* Otherwise, go through the list of known addresses of + this node. The first address we try is always the + one in n->address; that could be set to the node's + reflexive UDP address discovered during key + exchange. The other known addresses are those found + in edges to this node. */ + + static unsigned int i; + int j = 0; + edge_t *candidate = NULL; + + if(i) { + for splay_each(edge_t, e, edge_weight_tree) { + if(e->to != n) + continue; + j++; + if(!candidate || j == i) + candidate = e; + } + } + + if(!candidate) { + sa = &n->address; + sock = n->sock; + } else { + sa = &candidate->address; + sock = rand() % listen_sockets; + } + + if(i++) + if(i > j) + i = 0; + } + } + /* Determine which socket we have to use */ - for(sock = 0; sock < listen_sockets; sock++) - if(n->address.sa.sa_family == listen_socket[sock].sa.sa.sa_family) - break; + if(sa->sa.sa_family != listen_socket[sock].sa.sa.sa_family) + for(sock = 0; sock < listen_sockets; sock++) + if(sa->sa.sa_family == listen_socket[sock].sa.sa.sa_family) + break; if(sock >= listen_sockets) - sock = 0; /* If none is available, just use the first and hope for the best. */ + sock = 0; - /* Send the packet */ + if(!n->status.udp_confirmed) + n->sock = sock; #if defined(SOL_IP) && defined(IP_TOS) if(priorityinheritance && origpriority != priority - && listen_socket[sock].sa.sa.sa_family == AF_INET) { + && listen_socket[n->sock].sa.sa.sa_family == AF_INET) { priority = origpriority; - ifdebug(TRAFFIC) logger(LOG_DEBUG, "Setting outgoing packet priority to %d", priority); - if(setsockopt(listen_socket[sock].udp, SOL_IP, IP_TOS, &priority, sizeof priority)) /* SO_PRIORITY doesn't seem to work */ - logger(LOG_ERR, "System call `%s' failed: %s", "setsockopt", strerror(errno)); + logger(DEBUG_TRAFFIC, LOG_DEBUG, "Setting outgoing packet priority to %d", priority); + if(setsockopt(listen_socket[n->sock].udp, SOL_IP, IP_TOS, &priority, sizeof(priority))) /* SO_PRIORITY doesn't seem to work */ + logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "setsockopt", strerror(errno)); } #endif - if(sendto(listen_socket[sock].udp, (char *) &inpkt->seqno, inpkt->len, 0, &(n->address.sa), SALEN(n->address.sa)) < 0 && !sockwouldblock(sockerrno)) { + socklen_t sl = SALEN(n->address.sa); + + if(sendto(listen_socket[sock].udp, (char *) &inpkt->seqno, inpkt->len, 0, &sa->sa, sl) < 0 && !sockwouldblock(sockerrno)) { if(sockmsgsize(sockerrno)) { if(n->maxmtu >= origlen) n->maxmtu = origlen - 1; if(n->mtu >= origlen) n->mtu = origlen - 1; } else - logger(LOG_ERR, "Error sending packet to %s (%s): %s", n->name, n->hostname, sockstrerror(sockerrno)); + logger(DEBUG_TRAFFIC, LOG_WARNING, "Error sending packet to %s (%s): %s", n->name, n->hostname, sockstrerror(sockerrno)); } end: origpkt->len = origlen; } +bool send_sptps_data(void *handle, uint8_t type, const char *data, size_t len) { + node_t *to = handle; + + /* Send it via TCP if it is a handshake packet, TCPOnly is in use, or this packet is larger than the MTU. */ + + if(type >= SPTPS_HANDSHAKE || ((myself->options | to->options) & OPTION_TCPONLY) || (type != PKT_PROBE && len > to->minmtu)) { + char buf[len * 4 / 3 + 5]; + b64encode(data, buf, len); + /* If no valid key is known yet, send the packets using ANS_KEY requests, + to ensure we get to learn the reflexive UDP address. */ + if(!to->status.validkey) + return send_request(to->nexthop->connection, "%d %s %s %s -1 -1 -1 %d", ANS_KEY, myself->name, to->name, buf, myself->incompression); + else + return send_request(to->nexthop->connection, "%d %s %s %d %s", REQ_KEY, myself->name, to->name, REQ_SPTPS, buf); + } + + /* Otherwise, send the packet via UDP */ + + struct sockaddr *sa; + socklen_t sl; + int sock; + + sa = &(to->address.sa); + sl = SALEN(to->address.sa); + sock = to->sock; + + if(sendto(listen_socket[sock].udp, data, len, 0, sa, sl) < 0 && !sockwouldblock(sockerrno)) { + if(sockmsgsize(sockerrno)) { + if(to->maxmtu >= len) + to->maxmtu = len - 1; + if(to->mtu >= len) + to->mtu = len - 1; + } else { + logger(DEBUG_TRAFFIC, LOG_WARNING, "Error sending UDP SPTPS packet to %s (%s): %s", to->name, to->hostname, sockstrerror(sockerrno)); + return false; + } + } + + return true; +} + +bool receive_sptps_record(void *handle, uint8_t type, const char *data, uint16_t len) { + node_t *from = handle; + + if(type == SPTPS_HANDSHAKE) { + if(!from->status.validkey) { + from->status.validkey = true; + from->status.waitingforkey = false; + logger(DEBUG_META, LOG_INFO, "SPTPS key exchange with %s (%s) succesful", from->name, from->hostname); + } + return true; + } + + if(len > MTU) { + logger(DEBUG_ALWAYS, LOG_ERR, "Packet from %s (%s) larger than maximum supported size (%d > %d)", from->name, from->hostname, len, MTU); + return false; + } + + vpn_packet_t inpkt; + + if(type == PKT_PROBE) { + inpkt.len = len; + memcpy(inpkt.data, data, len); + mtu_probe_h(from, &inpkt, len); + return true; + } + + if(type & ~(PKT_COMPRESSED | PKT_MAC)) { + logger(DEBUG_ALWAYS, LOG_ERR, "Unexpected SPTPS record type %d len %d from %s (%s)", type, len, from->name, from->hostname); + return false; + } + + /* Check if we have the headers we need */ + if(routing_mode != RMODE_ROUTER && !(type & PKT_MAC)) { + logger(DEBUG_TRAFFIC, LOG_ERR, "Received packet from %s (%s) without MAC header (maybe Mode is not set correctly)", from->name, from->hostname); + return false; + } else if(routing_mode == RMODE_ROUTER && (type & PKT_MAC)) { + logger(DEBUG_TRAFFIC, LOG_WARNING, "Received packet from %s (%s) with MAC header (maybe Mode is not set correctly)", from->name, from->hostname); + } + + int offset = (type & PKT_MAC) ? 0 : 14; + if(type & PKT_COMPRESSED) { + len = uncompress_packet(inpkt.data + offset, (const uint8_t *)data, len, from->incompression); + if(len < 0) { + return false; + } else { + inpkt.len = len + offset; + } + if(inpkt.len > MAXSIZE) + abort(); + } else { + memcpy(inpkt.data + offset, data, len); + inpkt.len = len + offset; + } + + /* Generate the Ethernet packet type if necessary */ + if(offset) { + switch(inpkt.data[14] >> 4) { + case 4: + inpkt.data[12] = 0x08; + inpkt.data[13] = 0x00; + break; + case 6: + inpkt.data[12] = 0x86; + inpkt.data[13] = 0xDD; + break; + default: + logger(DEBUG_TRAFFIC, LOG_ERR, + "Unknown IP version %d while reading packet from %s (%s)", + inpkt.data[14] >> 4, from->name, from->hostname); + return false; + } + } + + receive_packet(from, &inpkt); + return true; +} + /* send a packet to the given vpn ip. */ @@ -507,15 +758,15 @@ void send_packet(node_t *n, vpn_packet_t *packet) { memcpy(packet->data, mymac.x, ETH_ALEN); n->out_packets++; n->out_bytes += packet->len; - write_packet(packet); + devops.write(packet); return; } - ifdebug(TRAFFIC) logger(LOG_ERR, "Sending packet of %d bytes to %s (%s)", + logger(DEBUG_TRAFFIC, LOG_ERR, "Sending packet of %d bytes to %s (%s)", packet->len, n->name, n->hostname); if(!n->status.reachable) { - ifdebug(TRAFFIC) logger(LOG_INFO, "Node %s (%s) is not reachable", + logger(DEBUG_TRAFFIC, LOG_INFO, "Node %s (%s) is not reachable", n->name, n->hostname); return; } @@ -523,10 +774,15 @@ void send_packet(node_t *n, vpn_packet_t *packet) { n->out_packets++; n->out_bytes += packet->len; + if(n->status.sptps) { + send_sptps_packet(n, packet); + return; + } + via = (packet->priority == -1 || n->via == myself) ? n->nexthop : n->via; if(via != n) - ifdebug(TRAFFIC) logger(LOG_INFO, "Sending packet to %s via %s (%s)", + logger(DEBUG_TRAFFIC, LOG_INFO, "Sending packet to %s via %s (%s)", n->name, via->name, n->via->hostname); if(packet->priority == -1 || ((myself->options | via->options) & OPTION_TCPONLY)) { @@ -539,46 +795,53 @@ void send_packet(node_t *n, vpn_packet_t *packet) { /* Broadcast a packet using the minimum spanning tree */ void broadcast_packet(const node_t *from, vpn_packet_t *packet) { - splay_node_t *node; - connection_t *c; - - ifdebug(TRAFFIC) logger(LOG_INFO, "Broadcasting packet of %d bytes from %s (%s)", - packet->len, from->name, from->hostname); - - if(from != myself) { + // Always give ourself a copy of the packet. + if(from != myself) send_packet(myself, packet); - // In TunnelServer mode, do not forward broadcast packets. - // The MST might not be valid and create loops. - if(tunnelserver) - return; - } + // In TunnelServer mode, do not forward broadcast packets. + // The MST might not be valid and create loops. + if(tunnelserver || broadcast_mode == BMODE_NONE) + return; - for(node = connection_tree->head; node; node = node->next) { - c = node->data; + logger(DEBUG_TRAFFIC, LOG_INFO, "Broadcasting packet of %d bytes from %s (%s)", + packet->len, from->name, from->hostname); - if(c->status.active && c->status.mst && c != from->nexthop->connection) - send_packet(c->node, packet); + switch(broadcast_mode) { + // In MST mode, broadcast packets travel via the Minimum Spanning Tree. + // This guarantees all nodes receive the broadcast packet, and + // usually distributes the sending of broadcast packets over all nodes. + case BMODE_MST: + for list_each(connection_t, c, connection_list) + if(c->status.active && c->status.mst && c != from->nexthop->connection) + send_packet(c->node, packet); + break; + + // In direct mode, we send copies to each node we know of. + // However, this only reaches nodes that can be reached in a single hop. + // We don't have enough information to forward broadcast packets in this case. + case BMODE_DIRECT: + if(from != myself) + break; + + for splay_each(node_t, n, node_tree) + if(n->status.reachable && ((n->via == myself && n->nexthop == n) || n->via == n)) + send_packet(n, packet); + break; + + default: + break; } } static node_t *try_harder(const sockaddr_t *from, const vpn_packet_t *pkt) { - splay_node_t *node; - edge_t *e; node_t *n = NULL; bool hard = false; static time_t last_hard_try = 0; time_t now = time(NULL); - if(last_hard_try == now) - return NULL; - else - last_hard_try = now; - - for(node = edge_weight_tree->head; node; node = node->next) { - e = node->data; - - if(e->to == myself) + for splay_each(edge_t, e, edge_weight_tree) { + if(!e->to->status.reachable || e->to == myself) continue; if(sockaddrcmp_noport(from, &e->address)) { @@ -597,13 +860,14 @@ static node_t *try_harder(const sockaddr_t *from, const vpn_packet_t *pkt) { if(hard) last_hard_try = now; + last_hard_try = now; return n; } void handle_incoming_vpn_data(int sock, short events, void *data) { vpn_packet_t pkt; char *hostname; - sockaddr_t from; + sockaddr_t from = {{0}}; socklen_t fromlen = sizeof from; node_t *n; int len; @@ -612,13 +876,13 @@ void handle_incoming_vpn_data(int sock, short events, void *data) { if(len <= 0 || len > MAXSIZE) { if(!sockwouldblock(sockerrno)) - logger(LOG_ERR, "Receiving packet failed: %s", sockstrerror(sockerrno)); + logger(DEBUG_ALWAYS, LOG_ERR, "Receiving packet failed: %s", sockstrerror(sockerrno)); return; } pkt.len = len; - sockaddrunmap(&from); /* Some braindead IPv6 implementations do stupid things. */ + sockaddrunmap(&from); /* Some braindead IPv6 implementations do stupid things. */ n = lookup_node_udp(&from); @@ -626,9 +890,9 @@ void handle_incoming_vpn_data(int sock, short events, void *data) { n = try_harder(&from, &pkt); if(n) update_node_udp(n, &from); - else ifdebug(PROTOCOL) { + else if(debug_level >= DEBUG_PROTOCOL) { hostname = sockaddr2hostname(&from); - logger(LOG_WARNING, "Received UDP packet from unknown source %s", hostname); + logger(DEBUG_PROTOCOL, LOG_WARNING, "Received UDP packet from unknown source %s", hostname); free(hostname); return; } @@ -636,6 +900,8 @@ void handle_incoming_vpn_data(int sock, short events, void *data) { return; } + n->sock = (intptr_t)data; + receive_udppacket(n, &pkt); } @@ -644,7 +910,7 @@ void handle_device_data(int sock, short events, void *data) { packet.priority = 0; - if(read_packet(&packet)) { + if(devops.read(&packet)) { myself->in_packets++; myself->in_bytes += packet.len; route(myself, &packet); diff --git a/src/net_setup.c b/src/net_setup.c index 91f7609..95ff5c3 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-2010 Guus Sliepen + 2000-2012 Guus Sliepen 2006 Scott Lamb 2010 Brandon Black @@ -22,7 +22,6 @@ #include "system.h" -#include "splay_tree.h" #include "cipher.h" #include "conf.h" #include "connection.h" @@ -44,6 +43,16 @@ char *myport; static struct event device_ev; +devops_t devops; + +char *proxyhost; +char *proxyport; +char *proxyuser; +char *proxypass; +proxytype_t proxytype; + +char *scriptinterpreter; +char *scriptextension; bool node_read_ecdsa_public_key(node_t *n) { if(ecdsa_active(&n->ecdsa)) @@ -51,14 +60,14 @@ bool node_read_ecdsa_public_key(node_t *n) { splay_tree_t *config_tree; FILE *fp; - char *fname; + char *pubname = NULL, *hcfname = NULL; char *p; bool result = false; - xasprintf(&fname, "%s/hosts/%s", confbase, n->name); + xasprintf(&hcfname, "%s" SLASH "hosts" SLASH "%s", confbase, n->name); init_configuration(&config_tree); - if(!read_config_file(config_tree, fname)) + if(!read_config_file(config_tree, hcfname)) goto exit; /* First, check for simple ECDSAPublicKey statement */ @@ -71,15 +80,13 @@ bool node_read_ecdsa_public_key(node_t *n) { /* Else, check for ECDSAPublicKeyFile statement and read it */ - free(fname); + if(!get_config_string(lookup_config(config_tree, "ECDSAPublicKeyFile"), &pubname)) + xasprintf(&pubname, "%s" SLASH "hosts" SLASH "%s", confbase, n->name); - if(!get_config_string(lookup_config(config_tree, "ECDSAPublicKeyFile"), &fname)) - xasprintf(&fname, "%s/hosts/%s", confbase, n->name); - - fp = fopen(fname, "r"); + fp = fopen(pubname, "r"); if(!fp) { - logger(LOG_ERR, "Error reading ECDSA public key file `%s': %s", fname, strerror(errno)); + logger(DEBUG_ALWAYS, LOG_ERR, "Error reading ECDSA public key file `%s': %s", pubname, strerror(errno)); goto exit; } @@ -88,7 +95,8 @@ bool node_read_ecdsa_public_key(node_t *n) { exit: exit_configuration(&config_tree); - free(fname); + free(hcfname); + free(pubname); return result; } @@ -109,12 +117,12 @@ bool read_ecdsa_public_key(connection_t *c) { /* Else, check for ECDSAPublicKeyFile statement and read it */ if(!get_config_string(lookup_config(c->config_tree, "ECDSAPublicKeyFile"), &fname)) - xasprintf(&fname, "%s/hosts/%s", confbase, c->name); + xasprintf(&fname, "%s" SLASH "hosts" SLASH "%s", confbase, c->name); fp = fopen(fname, "r"); if(!fp) { - logger(LOG_ERR, "Error reading ECDSA public key file `%s': %s", + logger(DEBUG_ALWAYS, LOG_ERR, "Error reading ECDSA public key file `%s': %s", fname, strerror(errno)); free(fname); return false; @@ -123,8 +131,8 @@ bool read_ecdsa_public_key(connection_t *c) { result = ecdsa_read_pem_public_key(&c->ecdsa, fp); fclose(fp); - if(!result) - logger(LOG_ERR, "Reading ECDSA public key file `%s' failed: %s", fname, strerror(errno)); + if(!result) + logger(DEBUG_ALWAYS, LOG_ERR, "Parsing ECDSA public key file `%s' failed.", fname); free(fname); return result; } @@ -146,13 +154,12 @@ bool read_rsa_public_key(connection_t *c) { /* Else, check for PublicKeyFile statement and read it */ if(!get_config_string(lookup_config(c->config_tree, "PublicKeyFile"), &fname)) - xasprintf(&fname, "%s/hosts/%s", confbase, c->name); + xasprintf(&fname, "%s" SLASH "hosts" SLASH "%s", confbase, c->name); fp = fopen(fname, "r"); if(!fp) { - logger(LOG_ERR, "Error reading RSA public key file `%s': %s", - fname, strerror(errno)); + logger(DEBUG_ALWAYS, LOG_ERR, "Error reading RSA public key file `%s': %s", fname, strerror(errno)); free(fname); return false; } @@ -160,8 +167,8 @@ bool read_rsa_public_key(connection_t *c) { result = rsa_read_pem_public_key(&c->rsa, fp); fclose(fp); - if(!result) - logger(LOG_ERR, "Reading RSA public key file `%s' failed: %s", fname, strerror(errno)); + if(!result) + logger(DEBUG_ALWAYS, LOG_ERR, "Reading RSA public key file `%s' failed: %s", fname, strerror(errno)); free(fname); return result; } @@ -174,13 +181,12 @@ static bool read_ecdsa_private_key(void) { /* Check for PrivateKeyFile statement and read it */ if(!get_config_string(lookup_config(config_tree, "ECDSAPrivateKeyFile"), &fname)) - xasprintf(&fname, "%s/ecdsa_key.priv", confbase); + xasprintf(&fname, "%s" SLASH "ecdsa_key.priv", confbase); fp = fopen(fname, "r"); if(!fp) { - logger(LOG_ERR, "Error reading ECDSA private key file `%s': %s", - fname, strerror(errno)); + logger(DEBUG_ALWAYS, LOG_ERR, "Error reading ECDSA private key file `%s': %s", fname, strerror(errno)); free(fname); return false; } @@ -189,20 +195,20 @@ static bool read_ecdsa_private_key(void) { struct stat s; if(fstat(fileno(fp), &s)) { - logger(LOG_ERR, "Could not stat ECDSA private key file `%s': %s'", fname, strerror(errno)); + logger(DEBUG_ALWAYS, LOG_ERR, "Could not stat ECDSA private key file `%s': %s'", fname, strerror(errno)); free(fname); return false; } if(s.st_mode & ~0100700) - logger(LOG_WARNING, "Warning: insecure file permissions for ECDSA private key file `%s'!", fname); + logger(DEBUG_ALWAYS, LOG_WARNING, "Warning: insecure file permissions for ECDSA private key file `%s'!", fname); #endif result = ecdsa_read_pem_private_key(&myself->connection->ecdsa, fp); fclose(fp); - if(!result) - logger(LOG_ERR, "Reading ECDSA private key file `%s' failed: %s", fname, strerror(errno)); + if(!result) + logger(DEBUG_ALWAYS, LOG_ERR, "Reading ECDSA private key file `%s' failed: %s", fname, strerror(errno)); free(fname); return result; } @@ -217,25 +223,25 @@ static bool read_rsa_private_key(void) { if(get_config_string(lookup_config(config_tree, "PrivateKey"), &d)) { if(!get_config_string(lookup_config(config_tree, "PublicKey"), &n)) { - logger(LOG_ERR, "PrivateKey used but no PublicKey found!"); + logger(DEBUG_ALWAYS, LOG_ERR, "PrivateKey used but no PublicKey found!"); free(d); return false; } result = rsa_set_hex_private_key(&myself->connection->rsa, n, "FFFF", d); free(n); free(d); - return true; + return result; } /* Else, check for PrivateKeyFile statement and read it */ if(!get_config_string(lookup_config(config_tree, "PrivateKeyFile"), &fname)) - xasprintf(&fname, "%s/rsa_key.priv", confbase); + xasprintf(&fname, "%s" SLASH "rsa_key.priv", confbase); fp = fopen(fname, "r"); if(!fp) { - logger(LOG_ERR, "Error reading RSA private key file `%s': %s", + logger(DEBUG_ALWAYS, LOG_ERR, "Error reading RSA private key file `%s': %s", fname, strerror(errno)); free(fname); return false; @@ -245,20 +251,20 @@ static bool read_rsa_private_key(void) { struct stat s; if(fstat(fileno(fp), &s)) { - logger(LOG_ERR, "Could not stat RSA private key file `%s': %s'", fname, strerror(errno)); + logger(DEBUG_ALWAYS, LOG_ERR, "Could not stat RSA private key file `%s': %s'", fname, strerror(errno)); free(fname); return false; } if(s.st_mode & ~0100700) - logger(LOG_WARNING, "Warning: insecure file permissions for RSA private key file `%s'!", fname); + logger(DEBUG_ALWAYS, LOG_WARNING, "Warning: insecure file permissions for RSA private key file `%s'!", fname); #endif result = rsa_read_pem_private_key(&myself->connection->rsa, fp); fclose(fp); - if(!result) - logger(LOG_ERR, "Reading RSA private key file `%s' failed: %s", fname, strerror(errno)); + if(!result) + logger(DEBUG_ALWAYS, LOG_ERR, "Reading RSA private key file `%s' failed: %s", fname, strerror(errno)); free(fname); return result; } @@ -271,7 +277,7 @@ static void keyexpire_handler(int fd, short events, void *data) { void regenerate_key(void) { if(timeout_initialized(&keyexpire_event)) { - ifdebug(STATUS) logger(LOG_INFO, "Expiring symmetric keys"); + logger(DEBUG_STATUS, LOG_INFO, "Expiring symmetric keys"); event_del(&keyexpire_event); send_key_changed(); } else { @@ -288,17 +294,11 @@ void load_all_subnets(void) { DIR *dir; struct dirent *ent; char *dname; - char *fname; - splay_tree_t *config_tree; - config_t *cfg; - subnet_t *s, *s2; - node_t *n; - bool result; - xasprintf(&dname, "%s/hosts", confbase); + xasprintf(&dname, "%s" SLASH "hosts", confbase); dir = opendir(dname); if(!dir) { - logger(LOG_ERR, "Could not open %s: %s", dname, strerror(errno)); + logger(DEBUG_ALWAYS, LOG_ERR, "Could not open %s: %s", dname, strerror(errno)); free(dname); return; } @@ -307,18 +307,20 @@ void load_all_subnets(void) { if(!check_id(ent->d_name)) continue; - n = lookup_node(ent->d_name); + node_t *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); + char *fname; + xasprintf(&fname, "%s" SLASH "hosts" SLASH "%s", confbase, ent->d_name); + + splay_tree_t *config_tree; init_configuration(&config_tree); - result = read_config_file(config_tree, fname); + read_config_options(config_tree, ent->d_name); + read_config_file(config_tree, fname); free(fname); - if(!result) - continue; if(!n) { n = new_node(); @@ -326,7 +328,9 @@ void load_all_subnets(void) { node_add(n); } - for(cfg = lookup_config(config_tree, "Subnet"); cfg; cfg = lookup_config_next(config_tree, cfg)) { + for(config_t *cfg = lookup_config(config_tree, "Subnet"); cfg; cfg = lookup_config_next(config_tree, cfg)) { + subnet_t *s, *s2; + if(!get_config_subnet(cfg, &s)) continue; @@ -343,85 +347,128 @@ void load_all_subnets(void) { closedir(dir); } -/* - Configure node_t myself and set up the local sockets (listen only) -*/ -static bool setup_myself(void) { - config_t *cfg; - subnet_t *subnet; - char *name, *hostname, *mode, *afname, *cipher, *digest; - char *fname = NULL; - char *address = NULL; - char *envp[5]; - struct addrinfo *ai, *aip, hint = {0}; - bool choice; - int i, err; - int replaywin_int; +char *get_name(void) { + char *name = NULL; - myself = new_node(); - myself->connection = new_connection(); + get_config_string(lookup_config(config_tree, "Name"), &name); - myself->hostname = xstrdup("MYSELF"); - myself->connection->hostname = xstrdup("MYSELF"); + if(!name) + return NULL; - myself->connection->options = 0; - myself->connection->protocol_major = PROT_MAJOR; - myself->connection->protocol_minor = PROT_MINOR; - - if(!get_config_string(lookup_config(config_tree, "Name"), &name)) { /* Not acceptable */ - logger(LOG_ERR, "Name for tinc daemon required!"); - return false; + if(*name == '$') { + char *envname = getenv(name + 1); + if(!envname) { + if(strcmp(name + 1, "HOST")) { + logger(DEBUG_ALWAYS, LOG_ERR, "Invalid Name: environment variable %s does not exist\n", name + 1); + return false; + } + envname = alloca(32); + if(gethostname(envname, 32)) { + logger(DEBUG_ALWAYS, LOG_ERR, "Could not get hostname: %s\n", strerror(errno)); + return false; + } + envname[31] = 0; + } + free(name); + name = xstrdup(envname); + for(char *c = name; *c; c++) + if(!isalnum(*c)) + *c = '_'; } if(!check_id(name)) { - logger(LOG_ERR, "Invalid name for myself!"); + logger(DEBUG_ALWAYS, LOG_ERR, "Invalid name for myself!"); free(name); return false; } - myself->name = name; - myself->connection->name = xstrdup(name); - xasprintf(&fname, "%s/hosts/%s", confbase, name); - read_config_options(config_tree, name); - read_config_file(config_tree, fname); - free(fname); + return name; +} - get_config_bool(lookup_config(config_tree, "ExperimentalProtocol"), &experimental); +bool setup_myself_reloadable(void) { + char *proxy = NULL; + char *rmode = NULL; + char *fmode = NULL; + char *bmode = NULL; + char *afname = NULL; + char *space; + bool choice; - if(experimental && !read_ecdsa_private_key()) - return false; + free(scriptinterpreter); + scriptinterpreter = NULL; + get_config_string(lookup_config(config_tree, "ScriptsInterpreter"), &scriptinterpreter); - if(!read_rsa_private_key()) - return false; - if(!get_config_string(lookup_config(config_tree, "Port"), &myport)) - myport = xstrdup("655"); + free(scriptextension); + if(!get_config_string(lookup_config(config_tree, "ScriptsExtension"), &scriptextension)) +#ifdef HAVE_MINGW + scriptextension = xstrdup(".bat"); +#else + scriptextension = xstrdup(""); +#endif - if(!atoi(myport)) { - struct addrinfo *ai = str2addrinfo("localhost", myport, SOCK_DGRAM); - sockaddr_t sa; - if(!ai || !ai->ai_addr) + get_config_string(lookup_config(config_tree, "Proxy"), &proxy); + if(proxy) { + if((space = strchr(proxy, ' '))) + *space++ = 0; + + if(!strcasecmp(proxy, "none")) { + proxytype = PROXY_NONE; + } else if(!strcasecmp(proxy, "socks4")) { + proxytype = PROXY_SOCKS4; + } else if(!strcasecmp(proxy, "socks4a")) { + proxytype = PROXY_SOCKS4A; + } else if(!strcasecmp(proxy, "socks5")) { + proxytype = PROXY_SOCKS5; + } else if(!strcasecmp(proxy, "http")) { + proxytype = PROXY_HTTP; + } else if(!strcasecmp(proxy, "exec")) { + proxytype = PROXY_EXEC; + } else { + logger(DEBUG_ALWAYS, LOG_ERR, "Unknown proxy type %s!", proxy); return false; - free(myport); - memcpy(&sa, ai->ai_addr, ai->ai_addrlen); - sockaddr2str(&sa, NULL, &myport); + } + + switch(proxytype) { + case PROXY_NONE: + default: + break; + + case PROXY_EXEC: + if(!space || !*space) { + logger(DEBUG_ALWAYS, LOG_ERR, "Argument expected for proxy type exec!"); + return false; + } + proxyhost = xstrdup(space); + break; + + case PROXY_SOCKS4: + case PROXY_SOCKS4A: + case PROXY_SOCKS5: + case PROXY_HTTP: + proxyhost = space; + if(space && (space = strchr(space, ' '))) + *space++ = 0, proxyport = space; + if(space && (space = strchr(space, ' '))) + *space++ = 0, proxyuser = space; + if(space && (space = strchr(space, ' '))) + *space++ = 0, proxypass = space; + if(!proxyhost || !*proxyhost || !proxyport || !*proxyport) { + logger(DEBUG_ALWAYS, LOG_ERR, "Host and port argument expected for proxy!"); + return false; + } + proxyhost = xstrdup(proxyhost); + proxyport = xstrdup(proxyport); + if(proxyuser && *proxyuser) + proxyuser = xstrdup(proxyuser); + if(proxypass && *proxypass) + proxypass = xstrdup(proxypass); + break; + } + + free(proxy); } - /* Read in all the subnets specified in the host configuration file */ - - cfg = lookup_config(config_tree, "Subnet"); - - while(cfg) { - if(!get_config_subnet(cfg, &subnet)) - return false; - - subnet_add(myself, subnet); - - cfg = lookup_config_next(config_tree, cfg); - } - - /* Check some options */ - if(get_config_bool(lookup_config(config_tree, "IndirectData"), &choice) && choice) myself->options |= OPTION_INDIRECT; @@ -432,36 +479,34 @@ static bool setup_myself(void) { 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; + get_config_bool(lookup_config(config_tree, "LocalDiscovery"), &localdiscovery); - if(get_config_string(lookup_config(config_tree, "Mode"), &mode)) { - if(!strcasecmp(mode, "router")) + if(get_config_string(lookup_config(config_tree, "Mode"), &rmode)) { + if(!strcasecmp(rmode, "router")) routing_mode = RMODE_ROUTER; - else if(!strcasecmp(mode, "switch")) + else if(!strcasecmp(rmode, "switch")) routing_mode = RMODE_SWITCH; - else if(!strcasecmp(mode, "hub")) + else if(!strcasecmp(rmode, "hub")) routing_mode = RMODE_HUB; else { - logger(LOG_ERR, "Invalid routing mode!"); + logger(DEBUG_ALWAYS, LOG_ERR, "Invalid routing mode!"); return false; } - free(mode); + free(rmode); } - if(get_config_string(lookup_config(config_tree, "Forwarding"), &mode)) { - if(!strcasecmp(mode, "off")) + if(get_config_string(lookup_config(config_tree, "Forwarding"), &fmode)) { + if(!strcasecmp(fmode, "off")) forwarding_mode = FMODE_OFF; - else if(!strcasecmp(mode, "internal")) + else if(!strcasecmp(fmode, "internal")) forwarding_mode = FMODE_INTERNAL; - else if(!strcasecmp(mode, "kernel")) + else if(!strcasecmp(fmode, "kernel")) forwarding_mode = FMODE_KERNEL; else { - logger(LOG_ERR, "Invalid forwarding mode!"); + logger(DEBUG_ALWAYS, LOG_ERR, "Invalid forwarding mode!"); return false; } - free(mode); + free(fmode); } choice = true; @@ -475,10 +520,24 @@ static bool setup_myself(void) { myself->options |= OPTION_CLAMP_MSS; get_config_bool(lookup_config(config_tree, "PriorityInheritance"), &priorityinheritance); + get_config_bool(lookup_config(config_tree, "DecrementTTL"), &decrement_ttl); + if(get_config_string(lookup_config(config_tree, "Broadcast"), &bmode)) { + if(!strcasecmp(bmode, "no")) + broadcast_mode = BMODE_NONE; + else if(!strcasecmp(bmode, "yes") || !strcasecmp(bmode, "mst")) + broadcast_mode = BMODE_MST; + else if(!strcasecmp(bmode, "direct")) + broadcast_mode = BMODE_DIRECT; + else { + logger(DEBUG_ALWAYS, LOG_ERR, "Invalid broadcast mode!"); + return false; + } + free(bmode); + } #if !defined(SOL_IP) || !defined(IP_TOS) if(priorityinheritance) - logger(LOG_WARNING, "%s not supported on this platform", "PriorityInheritance"); + logger(DEBUG_ALWAYS, LOG_WARNING, "%s not supported on this platform", "PriorityInheritance"); #endif if(!get_config_int(lookup_config(config_tree, "MACExpire"), &macexpire)) @@ -486,34 +545,12 @@ static bool setup_myself(void) { if(get_config_int(lookup_config(config_tree, "MaxTimeout"), &maxtimeout)) { if(maxtimeout <= 0) { - logger(LOG_ERR, "Bogus maximum timeout!"); + logger(DEBUG_ALWAYS, LOG_ERR, "Bogus maximum timeout!"); return false; } } else maxtimeout = 900; - if(get_config_int(lookup_config(config_tree, "UDPRcvBuf"), &udp_rcvbuf)) { - if(udp_rcvbuf <= 0) { - logger(LOG_ERR, "UDPRcvBuf cannot be negative!"); - return false; - } - } - - if(get_config_int(lookup_config(config_tree, "UDPSndBuf"), &udp_sndbuf)) { - if(udp_sndbuf <= 0) { - logger(LOG_ERR, "UDPSndBuf cannot be negative!"); - return false; - } - } - - if(get_config_int(lookup_config(config_tree, "ReplayWindow"), &replaywin_int)) { - if(replaywin_int < 0) { - logger(LOG_ERR, "ReplayWindow cannot be negative!"); - return false; - } - replaywin = (unsigned)replaywin_int; - } - if(get_config_string(lookup_config(config_tree, "AddressFamily"), &afname)) { if(!strcasecmp(afname, "IPv4")) addressfamily = AF_INET; @@ -522,7 +559,7 @@ static bool setup_myself(void) { else if(!strcasecmp(afname, "any")) addressfamily = AF_UNSPEC; else { - logger(LOG_ERR, "Invalid address family!"); + logger(DEBUG_ALWAYS, LOG_ERR, "Invalid address family!"); return false; } free(afname); @@ -530,44 +567,149 @@ static bool setup_myself(void) { get_config_bool(lookup_config(config_tree, "Hostnames"), &hostnames); + if(!get_config_int(lookup_config(config_tree, "KeyExpire"), &keylifetime)) + keylifetime = 3600; + + return true; +} + +/* + Configure node_t myself and set up the local sockets (listen only) +*/ +static bool setup_myself(void) { + char *name, *hostname, *cipher, *digest, *type; + char *fname = NULL; + char *address = NULL; + + if(!(name = get_name())) { + logger(DEBUG_ALWAYS, LOG_ERR, "Name for tinc daemon required!"); + return false; + } + + myself = new_node(); + myself->connection = new_connection(); + myself->name = name; + myself->connection->name = xstrdup(name); + xasprintf(&fname, "%s" SLASH "hosts" SLASH "%s", confbase, name); + read_config_options(config_tree, name); + read_config_file(config_tree, fname); + free(fname); + + if(!get_config_string(lookup_config(config_tree, "Port"), &myport)) + myport = xstrdup("655"); + + xasprintf(&myself->hostname, "MYSELF port %s", myport); + myself->connection->hostname = xstrdup(myself->hostname); + + myself->connection->options = 0; + myself->connection->protocol_major = PROT_MAJOR; + myself->connection->protocol_minor = PROT_MINOR; + + myself->options |= PROT_MINOR << 24; + + get_config_bool(lookup_config(config_tree, "ExperimentalProtocol"), &experimental); + + if(experimental && !read_ecdsa_private_key()) + return false; + + if(!read_rsa_private_key()) + return false; + + 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 */ + + for(config_t *cfg = lookup_config(config_tree, "Subnet"); cfg; cfg = lookup_config_next(config_tree, cfg)) { + subnet_t *subnet; + + if(!get_config_subnet(cfg, &subnet)) + return false; + + subnet_add(myself, subnet); + } + + /* Check some options */ + + if(!setup_myself_reloadable()) + return false; + + get_config_bool(lookup_config(config_tree, "StrictSubnets"), &strictsubnets); + get_config_bool(lookup_config(config_tree, "TunnelServer"), &tunnelserver); + strictsubnets |= tunnelserver; + + + + if(get_config_int(lookup_config(config_tree, "UDPRcvBuf"), &udp_rcvbuf)) { + if(udp_rcvbuf <= 0) { + logger(DEBUG_ALWAYS, LOG_ERR, "UDPRcvBuf cannot be negative!"); + return false; + } + } + + if(get_config_int(lookup_config(config_tree, "UDPSndBuf"), &udp_sndbuf)) { + if(udp_sndbuf <= 0) { + logger(DEBUG_ALWAYS, LOG_ERR, "UDPSndBuf cannot be negative!"); + return false; + } + } + + int replaywin_int; + if(get_config_int(lookup_config(config_tree, "ReplayWindow"), &replaywin_int)) { + if(replaywin_int < 0) { + logger(DEBUG_ALWAYS, LOG_ERR, "ReplayWindow cannot be negative!"); + return false; + } + replaywin = (unsigned)replaywin_int; + sptps_replaywin = replaywin; + } + /* Generate packet encryption key */ if(!get_config_string(lookup_config(config_tree, "Cipher"), &cipher)) cipher = xstrdup("blowfish"); if(!cipher_open_by_name(&myself->incipher, cipher)) { - logger(LOG_ERR, "Unrecognized cipher type!"); + logger(DEBUG_ALWAYS, LOG_ERR, "Unrecognized cipher type!"); return false; } - if(!get_config_int(lookup_config(config_tree, "KeyExpire"), &keylifetime)) - keylifetime = 3600; + free(cipher); regenerate_key(); /* Check if we want to use message authentication codes... */ - if(!get_config_string(lookup_config(config_tree, "Digest"), &digest)) - digest = xstrdup("sha1"); - int maclength = 4; get_config_int(lookup_config(config_tree, "MACLength"), &maclength); if(maclength < 0) { - logger(LOG_ERR, "Bogus MAC length!"); + logger(DEBUG_ALWAYS, LOG_ERR, "Bogus MAC length!"); return false; } + if(!get_config_string(lookup_config(config_tree, "Digest"), &digest)) + digest = xstrdup("sha1"); + if(!digest_open_by_name(&myself->indigest, digest, maclength)) { - logger(LOG_ERR, "Unrecognized digest type!"); + logger(DEBUG_ALWAYS, LOG_ERR, "Unrecognized digest type!"); return false; } + free(digest); + /* Compression */ if(get_config_int(lookup_config(config_tree, "Compression"), &myself->incompression)) { if(myself->incompression < 0 || myself->incompression > 11) { - logger(LOG_ERR, "Bogus compression level!"); + logger(DEBUG_ALWAYS, LOG_ERR, "Bogus compression level!"); return false; } } else @@ -580,6 +722,8 @@ static bool setup_myself(void) { myself->nexthop = myself; myself->via = myself; myself->status.reachable = true; + myself->last_state_change = time(NULL); + myself->status.sptps = experimental; node_add(myself); graph(); @@ -589,20 +733,40 @@ static bool setup_myself(void) { /* Open device */ - if(!setup_device()) + devops = os_devops; + + if(get_config_string(lookup_config(config_tree, "DeviceType"), &type)) { + if(!strcasecmp(type, "dummy")) + devops = dummy_devops; + else if(!strcasecmp(type, "raw_socket")) + devops = raw_socket_devops; + else if(!strcasecmp(type, "multicast")) + devops = multicast_devops; +#ifdef ENABLE_UML + else if(!strcasecmp(type, "uml")) + devops = uml_devops; +#endif +#ifdef ENABLE_VDE + else if(!strcasecmp(type, "vde")) + devops = vde_devops; +#endif + } + + if(!devops.setup()) return false; if(device_fd >= 0) { event_set(&device_ev, device_fd, EV_READ|EV_PERSIST, handle_device_data, NULL); if (event_add(&device_ev, NULL) < 0) { - logger(LOG_ERR, "event_add failed: %s", strerror(errno)); - close_device(); + logger(DEBUG_ALWAYS, LOG_ERR, "event_add failed: %s", strerror(errno)); + devops.close(); return false; } } /* Run tinc-up script to further initialize the tap interface */ + char *envp[5]; xasprintf(&envp[0], "NETNAME=%s", netname ? : ""); xasprintf(&envp[1], "DEVICE=%s", device ? : ""); xasprintf(&envp[2], "INTERFACE=%s", iface ? : ""); @@ -611,7 +775,7 @@ static bool setup_myself(void) { execute_script("tinc-up", envp); - for(i = 0; i < 4; i++) + for(int i = 0; i < 4; i++) free(envp[i]); /* Run subnet-up scripts for our own subnets */ @@ -620,80 +784,155 @@ static bool setup_myself(void) { /* Open sockets */ - get_config_string(lookup_config(config_tree, "BindToAddress"), &address); + if(!do_detach && getenv("LISTEN_FDS")) { + sockaddr_t sa; + socklen_t salen; - hint.ai_family = addressfamily; - hint.ai_socktype = SOCK_STREAM; - hint.ai_protocol = IPPROTO_TCP; - hint.ai_flags = AI_PASSIVE; + listen_sockets = atoi(getenv("LISTEN_FDS")); +#ifdef HAVE_UNSETENV + unsetenv("LISTEN_FDS"); +#endif - err = getaddrinfo(address, myport, &hint, &ai); + if(listen_sockets > MAXSOCKETS) { + logger(DEBUG_ALWAYS, LOG_ERR, "Too many listening sockets"); + return false; + } - if(err || !ai) { - logger(LOG_ERR, "System call `%s' failed: %s", "getaddrinfo", - gai_strerror(err)); - return false; + for(int i = 0; i < listen_sockets; i++) { + salen = sizeof sa; + if(getsockname(i + 3, &sa.sa, &salen) < 0) { + logger(DEBUG_ALWAYS, LOG_ERR, "Could not get address of listen fd %d: %s", i + 3, sockstrerror(errno)); + return false; + } + + listen_socket[i].tcp = i + 3; + +#ifdef FD_CLOEXEC + fcntl(i + 3, F_SETFD, FD_CLOEXEC); +#endif + + listen_socket[i].udp = setup_vpn_in_socket(&sa); + if(listen_socket[i].udp < 0) + return false; + + event_set(&listen_socket[i].ev_tcp, listen_socket[i].tcp, EV_READ|EV_PERSIST, handle_new_meta_connection, NULL); + if(event_add(&listen_socket[i].ev_tcp, NULL) < 0) { + logger(DEBUG_ALWAYS, LOG_ERR, "event_add failed: %s", strerror(errno)); + abort(); + } + + event_set(&listen_socket[i].ev_udp, listen_socket[i].udp, EV_READ|EV_PERSIST, handle_incoming_vpn_data, (void *)(intptr_t)listen_sockets); + if(event_add(&listen_socket[listen_sockets].ev_udp, NULL) < 0) { + logger(DEBUG_ALWAYS, LOG_ERR, "event_add failed: %s", strerror(errno)); + abort(); + } + + if(debug_level >= DEBUG_CONNECTIONS) { + hostname = sockaddr2hostname(&sa); + logger(DEBUG_CONNECTIONS, LOG_NOTICE, "Listening on %s", hostname); + free(hostname); + } + + memcpy(&listen_socket[i].sa, &sa, salen); + } + } else { + listen_sockets = 0; + config_t *cfg = lookup_config(config_tree, "BindToAddress"); + + do { + get_config_string(cfg, &address); + if(cfg) + cfg = lookup_config_next(config_tree, cfg); + + char *port = myport; + + if(address) { + char *space = strchr(address, ' '); + if(space) { + *space++ = 0; + port = space; + } + + if(!strcmp(address, "*")) + *address = 0; + } + + struct addrinfo *ai, hint = {0}; + hint.ai_family = addressfamily; + hint.ai_socktype = SOCK_STREAM; + hint.ai_protocol = IPPROTO_TCP; + hint.ai_flags = AI_PASSIVE; + + int err = getaddrinfo(address && *address ? address : NULL, port, &hint, &ai); + free(address); + + if(err || !ai) { + logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "getaddrinfo", + gai_strerror(err)); + return false; + } + + for(struct addrinfo *aip = ai; aip; aip = aip->ai_next) { + if(listen_sockets >= MAXSOCKETS) { + logger(DEBUG_ALWAYS, LOG_ERR, "Too many listening sockets"); + return false; + } + + listen_socket[listen_sockets].tcp = + setup_listen_socket((sockaddr_t *) aip->ai_addr); + + if(listen_socket[listen_sockets].tcp < 0) + continue; + + listen_socket[listen_sockets].udp = + setup_vpn_in_socket((sockaddr_t *) aip->ai_addr); + + if(listen_socket[listen_sockets].udp < 0) { + close(listen_socket[listen_sockets].tcp); + continue; + } + + event_set(&listen_socket[listen_sockets].ev_tcp, + listen_socket[listen_sockets].tcp, + EV_READ|EV_PERSIST, + handle_new_meta_connection, NULL); + if(event_add(&listen_socket[listen_sockets].ev_tcp, NULL) < 0) { + logger(DEBUG_ALWAYS, LOG_ERR, "event_add failed: %s", strerror(errno)); + abort(); + } + + event_set(&listen_socket[listen_sockets].ev_udp, + listen_socket[listen_sockets].udp, + EV_READ|EV_PERSIST, + handle_incoming_vpn_data, (void *)(intptr_t)listen_sockets); + if(event_add(&listen_socket[listen_sockets].ev_udp, NULL) < 0) { + logger(DEBUG_ALWAYS, LOG_ERR, "event_add failed: %s", strerror(errno)); + abort(); + } + + if(debug_level >= DEBUG_CONNECTIONS) { + hostname = sockaddr2hostname((sockaddr_t *) aip->ai_addr); + logger(DEBUG_CONNECTIONS, LOG_NOTICE, "Listening on %s", hostname); + free(hostname); + } + + memcpy(&listen_socket[listen_sockets].sa, aip->ai_addr, aip->ai_addrlen); + listen_sockets++; + } + + freeaddrinfo(ai); + } while(cfg); } - listen_sockets = 0; - - for(aip = ai; aip; aip = aip->ai_next) { - listen_socket[listen_sockets].tcp = - setup_listen_socket((sockaddr_t *) aip->ai_addr); - - if(listen_socket[listen_sockets].tcp < 0) - continue; - - listen_socket[listen_sockets].udp = - setup_vpn_in_socket((sockaddr_t *) aip->ai_addr); - - if(listen_socket[listen_sockets].udp < 0) { - close(listen_socket[listen_sockets].tcp); - continue; - } - - event_set(&listen_socket[listen_sockets].ev_tcp, - listen_socket[listen_sockets].tcp, - EV_READ|EV_PERSIST, - handle_new_meta_connection, NULL); - if(event_add(&listen_socket[listen_sockets].ev_tcp, NULL) < 0) { - logger(LOG_ERR, "event_add failed: %s", strerror(errno)); - abort(); - } - - event_set(&listen_socket[listen_sockets].ev_udp, - listen_socket[listen_sockets].udp, - EV_READ|EV_PERSIST, - handle_incoming_vpn_data, NULL); - if(event_add(&listen_socket[listen_sockets].ev_udp, NULL) < 0) { - logger(LOG_ERR, "event_add failed: %s", strerror(errno)); - abort(); - } - - ifdebug(CONNECTIONS) { - hostname = sockaddr2hostname((sockaddr_t *) aip->ai_addr); - logger(LOG_NOTICE, "Listening on %s", hostname); - free(hostname); - } - - memcpy(&listen_socket[listen_sockets].sa, aip->ai_addr, aip->ai_addrlen); - listen_sockets++; - - if(listen_sockets >= MAXSOCKETS) { - logger(LOG_WARNING, "Maximum of %d listening sockets reached", MAXSOCKETS); - break; - } - } - - freeaddrinfo(ai); - if(listen_sockets) - logger(LOG_NOTICE, "Ready"); + logger(DEBUG_ALWAYS, LOG_NOTICE, "Ready"); else { - logger(LOG_ERR, "Unable to create any listening socket!"); + logger(DEBUG_ALWAYS, LOG_ERR, "Unable to create any listening socket!"); return false; } + last_config_check = time(NULL); + return true; } @@ -732,14 +971,12 @@ bool setup_network(void) { close all open network connections */ void close_network_connections(void) { - splay_node_t *node, *next; - connection_t *c; - char *envp[5]; - int i; - - for(node = connection_tree->head; node; node = next) { + for(list_node_t *node = connection_list->head, *next; node; node = next) { next = node->next; - c = node->data; + connection_t *c = node->data; + /* Keep control connections open until the end, so they know when we really terminated */ + if(c->status.control) + c->socket = -1; c->outgoing = NULL; terminate_connection(c, false); } @@ -752,13 +989,14 @@ void close_network_connections(void) { free_connection(myself->connection); } - for(i = 0; i < listen_sockets; i++) { + for(int i = 0; i < listen_sockets; i++) { event_del(&listen_socket[i].ev_tcp); event_del(&listen_socket[i].ev_udp); close(listen_socket[i].tcp); close(listen_socket[i].udp); } + char *envp[5]; xasprintf(&envp[0], "NETNAME=%s", netname ? : ""); xasprintf(&envp[1], "DEVICE=%s", device ? : ""); xasprintf(&envp[2], "INTERFACE=%s", iface ? : ""); @@ -775,10 +1013,10 @@ void close_network_connections(void) { if(myport) free(myport); - for(i = 0; i < 4; i++) + for(int i = 0; i < 4; i++) free(envp[i]); - close_device(); + devops.close(); return; } diff --git a/src/net_socket.c b/src/net_socket.c index a1dfcd3..09c5207 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-2010 Guus Sliepen + 2000-2012 Guus Sliepen 2006 Scott Lamb 2009 Florian Forster @@ -22,9 +22,9 @@ #include "system.h" -#include "splay_tree.h" #include "conf.h" #include "connection.h" +#include "list.h" #include "logger.h" #include "meta.h" #include "net.h" @@ -33,8 +33,6 @@ #include "utils.h" #include "xalloc.h" -#include - /* Needed on Mac OS/X */ #ifndef SOL_TCP #define SOL_TCP IPPROTO_TCP @@ -59,13 +57,13 @@ static void configure_tcp(connection_t *c) { int flags = fcntl(c->socket, F_GETFL); if(fcntl(c->socket, F_SETFL, flags | O_NONBLOCK) < 0) { - logger(LOG_ERR, "fcntl for %s: %s", c->hostname, strerror(errno)); + logger(DEBUG_ALWAYS, LOG_ERR, "fcntl for %s: %s", c->hostname, strerror(errno)); } #elif defined(WIN32) unsigned long arg = 1; if(ioctlsocket(c->socket, FIONBIO, &arg) != 0) { - logger(LOG_ERR, "ioctlsocket for %s: %d", c->hostname, sockstrerror(sockerrno)); + logger(DEBUG_ALWAYS, LOG_ERR, "ioctlsocket for %s: %s", c->hostname, sockstrerror(sockerrno)); } #endif @@ -98,74 +96,17 @@ static bool bind_to_interface(int sd) { status = setsockopt(sd, SOL_SOCKET, SO_BINDTODEVICE, (void *)&ifr, sizeof(ifr)); if(status) { - logger(LOG_ERR, "Can't bind to interface %s: %s", iface, + logger(DEBUG_ALWAYS, LOG_ERR, "Can't bind to interface %s: %s", iface, strerror(errno)); return false; } #else /* if !defined(SOL_SOCKET) || !defined(SO_BINDTODEVICE) */ - logger(LOG_WARNING, "%s not supported on this platform", "BindToInterface"); + logger(DEBUG_ALWAYS, LOG_WARNING, "%s not supported on this platform", "BindToInterface"); #endif return true; } -static bool bind_to_address(connection_t *c) { - char *node; - struct addrinfo *ai_list; - struct addrinfo *ai_ptr; - struct addrinfo ai_hints; - int status; - - assert(c != NULL); - assert(c->socket >= 0); - - node = NULL; - if(!get_config_string(lookup_config(config_tree, "BindToAddress"), - &node)) - return true; - - assert(node != NULL); - - memset(&ai_hints, 0, sizeof(ai_hints)); - ai_hints.ai_family = c->address.sa.sa_family; - /* We're called from `do_outgoing_connection' only. */ - ai_hints.ai_socktype = SOCK_STREAM; - ai_hints.ai_protocol = IPPROTO_TCP; - - ai_list = NULL; - - status = getaddrinfo(node, /* service = */ NULL, - &ai_hints, &ai_list); - if(status) { - logger(LOG_WARNING, "Error looking up %s port %s: %s", - node, "any", gai_strerror(status)); - free(node); - return false; - } - assert(ai_list != NULL); - - status = -1; - for(ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next) { - status = bind(c->socket, - ai_list->ai_addr, ai_list->ai_addrlen); - if(!status) - break; - } - - - if(status) { - logger(LOG_ERR, "Can't bind to %s/tcp: %s", node, sockstrerror(sockerrno)); - } else ifdebug(CONNECTIONS) { - logger(LOG_DEBUG, "Successfully bound outgoing " - "TCP socket to %s", node); - } - - free(node); - freeaddrinfo(ai_list); - - return status ? false : true; -} - int setup_listen_socket(const sockaddr_t *sa) { int nfd; char *addrstr; @@ -175,10 +116,14 @@ int setup_listen_socket(const sockaddr_t *sa) { nfd = socket(sa->sa.sa_family, SOCK_STREAM, IPPROTO_TCP); if(nfd < 0) { - ifdebug(STATUS) logger(LOG_ERR, "Creating metasocket failed: %s", sockstrerror(sockerrno)); + logger(DEBUG_STATUS, LOG_ERR, "Creating metasocket failed: %s", sockstrerror(sockerrno)); return -1; } +#ifdef FD_CLOEXEC + fcntl(nfd, F_SETFD, FD_CLOEXEC); +#endif + /* Optimize TCP settings */ option = 1; @@ -199,26 +144,26 @@ int setup_listen_socket(const sockaddr_t *sa) { if(setsockopt(nfd, SOL_SOCKET, SO_BINDTODEVICE, (void *)&ifr, sizeof ifr)) { closesocket(nfd); - logger(LOG_ERR, "Can't bind to interface %s: %s", iface, + logger(DEBUG_ALWAYS, LOG_ERR, "Can't bind to interface %s: %s", iface, strerror(sockerrno)); return -1; } #else - logger(LOG_WARNING, "%s not supported on this platform", "BindToInterface"); + logger(DEBUG_ALWAYS, LOG_WARNING, "%s not supported on this platform", "BindToInterface"); #endif } if(bind(nfd, &sa->sa, SALEN(sa->sa))) { closesocket(nfd); addrstr = sockaddr2hostname(sa); - logger(LOG_ERR, "Can't bind to %s/tcp: %s", addrstr, sockstrerror(sockerrno)); + logger(DEBUG_ALWAYS, LOG_ERR, "Can't bind to %s/tcp: %s", addrstr, sockstrerror(sockerrno)); free(addrstr); return -1; } if(listen(nfd, 3)) { closesocket(nfd); - logger(LOG_ERR, "System call `%s' failed: %s", "listen", sockstrerror(sockerrno)); + logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "listen", sockstrerror(sockerrno)); return -1; } @@ -233,17 +178,21 @@ int setup_vpn_in_socket(const sockaddr_t *sa) { nfd = socket(sa->sa.sa_family, SOCK_DGRAM, IPPROTO_UDP); if(nfd < 0) { - logger(LOG_ERR, "Creating UDP socket failed: %s", sockstrerror(sockerrno)); + logger(DEBUG_ALWAYS, LOG_ERR, "Creating UDP socket failed: %s", sockstrerror(sockerrno)); return -1; } +#ifdef FD_CLOEXEC + fcntl(nfd, F_SETFD, FD_CLOEXEC); +#endif + #ifdef O_NONBLOCK { int flags = fcntl(nfd, F_GETFL); if(fcntl(nfd, F_SETFL, flags | O_NONBLOCK) < 0) { closesocket(nfd); - logger(LOG_ERR, "System call `%s' failed: %s", "fcntl", + logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "fcntl", strerror(errno)); return -1; } @@ -253,7 +202,7 @@ int setup_vpn_in_socket(const sockaddr_t *sa) { unsigned long arg = 1; if(ioctlsocket(nfd, FIONBIO, &arg) != 0) { closesocket(nfd); - logger(LOG_ERR, "Call to `%s' failed: %s", "ioctlsocket", sockstrerror(sockerrno)); + logger(DEBUG_ALWAYS, LOG_ERR, "Call to `%s' failed: %s", "ioctlsocket", sockstrerror(sockerrno)); return -1; } } @@ -261,12 +210,13 @@ int setup_vpn_in_socket(const sockaddr_t *sa) { option = 1; setsockopt(nfd, SOL_SOCKET, SO_REUSEADDR, (void *)&option, sizeof option); + setsockopt(nfd, SOL_SOCKET, SO_BROADCAST, (void *)&option, sizeof option); if(udp_rcvbuf && setsockopt(nfd, SOL_SOCKET, SO_RCVBUF, (void *)&udp_rcvbuf, sizeof(udp_rcvbuf))) - logger(LOG_WARNING, "Can't set UDP SO_RCVBUF to %i: %s", udp_rcvbuf, strerror(errno)); + logger(DEBUG_ALWAYS, LOG_WARNING, "Can't set UDP SO_RCVBUF to %i: %s", udp_rcvbuf, strerror(errno)); if(udp_sndbuf && setsockopt(nfd, SOL_SOCKET, SO_SNDBUF, (void *)&udp_sndbuf, sizeof(udp_sndbuf))) - logger(LOG_WARNING, "Can't set UDP SO_SNDBUF to %i: %s", udp_sndbuf, strerror(errno)); + logger(DEBUG_ALWAYS, LOG_WARNING, "Can't set UDP SO_SNDBUF to %i: %s", udp_sndbuf, strerror(errno)); #if defined(IPPROTO_IPV6) && defined(IPV6_V6ONLY) if(sa->sa.sa_family == AF_INET6) @@ -313,7 +263,7 @@ int setup_vpn_in_socket(const sockaddr_t *sa) { if(bind(nfd, &sa->sa, SALEN(sa->sa))) { closesocket(nfd); addrstr = sockaddr2hostname(sa); - logger(LOG_ERR, "Can't bind to %s/udp: %s", addrstr, sockstrerror(sockerrno)); + logger(DEBUG_ALWAYS, LOG_ERR, "Can't bind to %s/udp: %s", addrstr, sockstrerror(sockerrno)); free(addrstr); return -1; } @@ -334,15 +284,16 @@ void retry_outgoing(outgoing_t *outgoing) { timeout_set(&outgoing->ev, retry_outgoing_handler, outgoing); event_add(&outgoing->ev, &(struct timeval){outgoing->timeout, 0}); - ifdebug(CONNECTIONS) logger(LOG_NOTICE, + logger(DEBUG_CONNECTIONS, LOG_NOTICE, "Trying to re-establish outgoing connection in %d seconds", outgoing->timeout); } void finish_connecting(connection_t *c) { - ifdebug(CONNECTIONS) logger(LOG_INFO, "Connected to %s (%s)", c->name, c->hostname); + logger(DEBUG_CONNECTIONS, LOG_INFO, "Connected to %s (%s)", c->name, c->hostname); - configure_tcp(c); + if(proxytype != PROXY_EXEC) + configure_tcp(c); c->last_ping_time = time(NULL); c->status.connecting = false; @@ -350,113 +301,68 @@ void finish_connecting(connection_t *c) { send_id(c); } -bool do_outgoing_connection(connection_t *c) { - char *address, *port, *space; - int result; +static void do_outgoing_pipe(connection_t *c, char *command) { +#ifndef HAVE_MINGW + int fd[2]; - if(!c->outgoing) { - logger(LOG_ERR, "do_outgoing_connection() for %s called without c->outgoing", c->name); - abort(); + if(socketpair(AF_UNIX, SOCK_STREAM, 0, fd)) { + logger(DEBUG_ALWAYS, LOG_ERR, "Could not create socketpair: %s", strerror(errno)); + return; } -begin: - if(!c->outgoing->ai) { - if(!c->outgoing->cfg) { - ifdebug(CONNECTIONS) logger(LOG_ERR, "Could not set up a meta connection to %s", - c->name); - retry_outgoing(c->outgoing); - c->outgoing = NULL; - connection_del(c); - return false; - } - - get_config_string(c->outgoing->cfg, &address); - - 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); - free(port); - - c->outgoing->aip = c->outgoing->ai; - c->outgoing->cfg = lookup_config_next(c->config_tree, c->outgoing->cfg); + if(fork()) { + c->socket = fd[0]; + close(fd[1]); + logger(DEBUG_CONNECTIONS, LOG_DEBUG, "Using proxy %s", command); + return; } - if(!c->outgoing->aip) { - if(c->outgoing->ai) - freeaddrinfo(c->outgoing->ai); - c->outgoing->ai = NULL; - goto begin; - } + close(0); + close(1); + close(fd[0]); + dup2(fd[1], 0); + dup2(fd[1], 1); + close(fd[1]); - memcpy(&c->address, c->outgoing->aip->ai_addr, c->outgoing->aip->ai_addrlen); - c->outgoing->aip = c->outgoing->aip->ai_next; + // Other filedescriptors should be closed automatically by CLOEXEC - if(c->hostname) - free(c->hostname); + char *host = NULL; + char *port = NULL; - c->hostname = sockaddr2hostname(&c->address); + sockaddr2str(&c->address, &host, &port); + setenv("REMOTEADDRESS", host, true); + setenv("REMOTEPORT", port, true); + setenv("NODE", c->name, true); + setenv("NAME", myself->name, true); + if(netname) + setenv("NETNAME", netname, true); - ifdebug(CONNECTIONS) logger(LOG_INFO, "Trying to connect to %s (%s)", c->name, - c->hostname); - - c->socket = socket(c->address.sa.sa_family, SOCK_STREAM, IPPROTO_TCP); - - if(c->socket == -1) { - ifdebug(CONNECTIONS) logger(LOG_ERR, "Creating socket for %s failed: %s", c->hostname, sockstrerror(sockerrno)); - goto begin; - } - -#if defined(SOL_IPV6) && defined(IPV6_V6ONLY) - int option = 1; - if(c->address.sa.sa_family == AF_INET6) - setsockopt(c->socket, SOL_IPV6, IPV6_V6ONLY, (void *)&option, sizeof option); + int result = system(command); + if(result < 0) + logger(DEBUG_ALWAYS, LOG_ERR, "Could not execute %s: %s", command, strerror(errno)); + else if(result) + logger(DEBUG_ALWAYS, LOG_ERR, "%s exited with non-zero status %d", command, result); + exit(result); +#else + logger(DEBUG_ALWAYS, LOG_ERR, "Proxy type exec not supported on this platform!"); + return; #endif - - bind_to_interface(c->socket); - bind_to_address(c); - - /* Optimize TCP settings */ - - configure_tcp(c); - - /* Connect */ - - result = connect(c->socket, &c->address.sa, SALEN(c->address.sa)); - - if(result == -1) { - if(sockinprogress(sockerrno)) { - c->status.connecting = true; - return true; - } - - closesocket(c->socket); - - ifdebug(CONNECTIONS) logger(LOG_ERR, "%s: %s", c->hostname, sockstrerror(sockerrno)); - - goto begin; - } - - finish_connecting(c); - - return true; } static void handle_meta_write(int sock, short events, void *data) { - ifdebug(META) logger(LOG_DEBUG, "handle_meta_write() called"); - connection_t *c = data; ssize_t outlen = send(c->socket, c->outbuf.data + c->outbuf.offset, c->outbuf.len - c->outbuf.offset, 0); if(outlen <= 0) { - logger(LOG_ERR, "Onoes, outlen = %d (%s)", (int)outlen, strerror(errno)); + if(!errno || errno == EPIPE) { + logger(DEBUG_CONNECTIONS, LOG_NOTICE, "Connection closed by %s (%s)", c->name, c->hostname); + } else if(sockwouldblock(sockerrno)) { + logger(DEBUG_CONNECTIONS, LOG_DEBUG, "Sending %d bytes to %s (%s) would block", c->outbuf.len - c->outbuf.offset, c->name, c->hostname); + return; + } else { + logger(DEBUG_CONNECTIONS, LOG_ERR, "Could not send %d bytes of data to %s (%s): %s", c->outbuf.len - c->outbuf.offset, c->name, c->hostname, strerror(errno)); + } + terminate_connection(c, c->status.active); return; } @@ -466,51 +372,151 @@ static void handle_meta_write(int sock, short events, void *data) { event_del(&c->outevent); } -void setup_outgoing_connection(outgoing_t *outgoing) { - connection_t *c; - node_t *n; - if(event_initialized(&outgoing->ev)) - event_del(&outgoing->ev); +bool do_outgoing_connection(outgoing_t *outgoing) { + char *address, *port, *space; + struct addrinfo *proxyai = NULL; + int result; - n = lookup_node(outgoing->name); - - if(n) - if(n->connection) { - ifdebug(CONNECTIONS) logger(LOG_INFO, "Already connected to %s", outgoing->name); - - n->connection->outgoing = outgoing; - return; +begin: + if(!outgoing->ai) { + if(!outgoing->cfg) { + logger(DEBUG_CONNECTIONS, LOG_ERR, "Could not set up a meta connection to %s", outgoing->name); + retry_outgoing(outgoing); + return false; } - c = new_connection(); + get_config_string(outgoing->cfg, &address); + + space = strchr(address, ' '); + if(space) { + port = xstrdup(space + 1); + *space = 0; + } else { + if(!get_config_string(lookup_config(outgoing->config_tree, "Port"), &port)) + port = xstrdup("655"); + } + + outgoing->ai = str2addrinfo(address, port, SOCK_STREAM); + free(address); + free(port); + + outgoing->aip = outgoing->ai; + outgoing->cfg = lookup_config_next(outgoing->config_tree, outgoing->cfg); + } + + if(!outgoing->aip) { + if(outgoing->ai) + freeaddrinfo(outgoing->ai); + outgoing->ai = NULL; + goto begin; + } + + connection_t *c = new_connection(); + c->outgoing = outgoing; + + memcpy(&c->address, outgoing->aip->ai_addr, outgoing->aip->ai_addrlen); + outgoing->aip = outgoing->aip->ai_next; + + c->hostname = sockaddr2hostname(&c->address); + + logger(DEBUG_CONNECTIONS, LOG_INFO, "Trying to connect to %s (%s)", outgoing->name, c->hostname); + + if(!proxytype) { + c->socket = socket(c->address.sa.sa_family, SOCK_STREAM, IPPROTO_TCP); + configure_tcp(c); + } else if(proxytype == PROXY_EXEC) { + do_outgoing_pipe(c, proxyhost); + } else { + proxyai = str2addrinfo(proxyhost, proxyport, SOCK_STREAM); + if(!proxyai) { + free_connection(c); + goto begin; + } + logger(DEBUG_CONNECTIONS, LOG_INFO, "Using proxy at %s port %s", proxyhost, proxyport); + c->socket = socket(proxyai->ai_family, SOCK_STREAM, IPPROTO_TCP); + } + + if(c->socket == -1) { + logger(DEBUG_CONNECTIONS, LOG_ERR, "Creating socket for %s failed: %s", c->hostname, sockstrerror(sockerrno)); + free_connection(c); + goto begin; + } + +#ifdef FD_CLOEXEC + fcntl(c->socket, F_SETFD, FD_CLOEXEC); +#endif + + if(proxytype != PROXY_EXEC) { +#if defined(SOL_IPV6) && defined(IPV6_V6ONLY) + int option = 1; + if(c->address.sa.sa_family == AF_INET6) + setsockopt(c->socket, SOL_IPV6, IPV6_V6ONLY, (void *)&option, sizeof option); +#endif + + bind_to_interface(c->socket); + } + + /* Connect */ + + if(!proxytype) { + result = connect(c->socket, &c->address.sa, SALEN(c->address.sa)); + } else if(proxytype == PROXY_EXEC) { + result = 0; + } else { + result = connect(c->socket, proxyai->ai_addr, proxyai->ai_addrlen); + freeaddrinfo(proxyai); + } + + if(result == -1 && !sockinprogress(sockerrno)) { + logger(DEBUG_CONNECTIONS, LOG_ERR, "Could not connect to %s (%s): %s", outgoing->name, c->hostname, sockstrerror(sockerrno)); + free_connection(c); + + goto begin; + } + + /* Now that there is a working socket, fill in the rest and register this connection. */ + + c->status.connecting = true; c->name = xstrdup(outgoing->name); c->outcipher = myself->connection->outcipher; c->outdigest = myself->connection->outdigest; c->outmaclength = myself->connection->outmaclength; c->outcompression = myself->connection->outcompression; - - init_configuration(&c->config_tree); - read_connection_config(c); - - outgoing->cfg = lookup_config(c->config_tree, "Address"); - - if(!outgoing->cfg) { - logger(LOG_ERR, "No address specified for %s", c->name); - free_connection(c); - return; - } - - c->outgoing = outgoing; c->last_ping_time = time(NULL); connection_add(c); - if (do_outgoing_connection(c)) { - event_set(&c->inevent, c->socket, EV_READ | EV_PERSIST, handle_meta_connection_data, c); - event_set(&c->outevent, c->socket, EV_WRITE | EV_PERSIST, handle_meta_write, c); - event_add(&c->inevent, NULL); + event_set(&c->inevent, c->socket, EV_READ | EV_PERSIST, handle_meta_connection_data, c); + event_set(&c->outevent, c->socket, EV_WRITE | EV_PERSIST, handle_meta_write, c); + event_add(&c->inevent, NULL); + + return true; +} + +void setup_outgoing_connection(outgoing_t *outgoing) { + if(event_initialized(&outgoing->ev)) + event_del(&outgoing->ev); + + node_t *n = lookup_node(outgoing->name); + + if(n && n->connection) { + logger(DEBUG_CONNECTIONS, LOG_INFO, "Already connected to %s", outgoing->name); + + n->connection->outgoing = outgoing; + return; } + + init_configuration(&outgoing->config_tree); + read_host_config(outgoing->config_tree, outgoing->name); + outgoing->cfg = lookup_config(outgoing->config_tree, "Address"); + + if(!outgoing->cfg) { + logger(DEBUG_ALWAYS, LOG_ERR, "No address specified for %s", outgoing->name); + return; + } + + do_outgoing_connection(outgoing); } /* @@ -526,7 +532,7 @@ void handle_new_meta_connection(int sock, short events, void *data) { fd = accept(sock, &sa.sa, &len); if(fd < 0) { - logger(LOG_ERR, "Accepting a new connection failed: %s", sockstrerror(sockerrno)); + logger(DEBUG_ALWAYS, LOG_ERR, "Accepting a new connection failed: %s", sockstrerror(sockerrno)); return; } @@ -544,12 +550,12 @@ void handle_new_meta_connection(int sock, short events, void *data) { c->socket = fd; c->last_ping_time = time(NULL); - ifdebug(CONNECTIONS) logger(LOG_NOTICE, "Connection from %s", c->hostname); + logger(DEBUG_CONNECTIONS, LOG_NOTICE, "Connection from %s", c->hostname); event_set(&c->inevent, c->socket, EV_READ | EV_PERSIST, handle_meta_connection_data, c); event_set(&c->outevent, c->socket, EV_WRITE | EV_PERSIST, handle_meta_write, c); event_add(&c->inevent, NULL); - + configure_tcp(c); connection_add(c); @@ -559,9 +565,15 @@ void handle_new_meta_connection(int sock, short events, void *data) { } static void free_outgoing(outgoing_t *outgoing) { + if(event_initialized(&outgoing->ev)) + event_del(&outgoing->ev); + if(outgoing->ai) freeaddrinfo(outgoing->ai); + if(outgoing->config_tree) + exit_configuration(&outgoing->config_tree); + if(outgoing->name) free(outgoing->name); @@ -569,26 +581,60 @@ static void free_outgoing(outgoing_t *outgoing) { } void try_outgoing_connections(void) { - static config_t *cfg = NULL; - char *name; - outgoing_t *outgoing; - - outgoing_list = list_alloc((list_action_t)free_outgoing); - - for(cfg = lookup_config(config_tree, "ConnectTo"); cfg; cfg = lookup_config_next(config_tree, cfg)) { + /* If there is no outgoing list yet, create one. Otherwise, mark all outgoings as deleted. */ + + if(!outgoing_list) { + outgoing_list = list_alloc((list_action_t)free_outgoing); + } else { + for list_each(outgoing_t, outgoing, outgoing_list) + outgoing->timeout = -1; + } + + /* Make sure there is one outgoing_t in the list for each ConnectTo. */ + + for(config_t *cfg = lookup_config(config_tree, "ConnectTo"); cfg; cfg = lookup_config_next(config_tree, cfg)) { + char *name; get_config_string(cfg, &name); if(!check_id(name)) { - logger(LOG_ERR, + logger(DEBUG_ALWAYS, LOG_ERR, "Invalid name for outgoing connection in %s line %d", cfg->file, cfg->line); free(name); continue; } - outgoing = xmalloc_and_zero(sizeof *outgoing); - outgoing->name = name; - list_insert_tail(outgoing_list, outgoing); - setup_outgoing_connection(outgoing); + bool found = false; + + for list_each(outgoing_t, outgoing, outgoing_list) { + if(!strcmp(outgoing->name, name)) { + found = true; + outgoing->timeout = 0; + break; + } + } + + if(!found) { + outgoing_t *outgoing = xmalloc_and_zero(sizeof *outgoing); + outgoing->name = name; + list_insert_tail(outgoing_list, outgoing); + setup_outgoing_connection(outgoing); + } } + + /* Terminate any connections whose outgoing_t is to be deleted. */ + + for list_each(connection_t, c, connection_list) { + if(c->outgoing && c->outgoing->timeout == -1) { + c->outgoing = NULL; + logger(DEBUG_CONNECTIONS, LOG_INFO, "No more outgoing connection to %s", c->name); + terminate_connection(c, c->status.active); + } + } + + /* Delete outgoing_ts for which there is no ConnectTo. */ + + for list_each(outgoing_t, outgoing, outgoing_list) + if(outgoing->timeout == -1) + list_delete_node(outgoing_list, node); } diff --git a/src/netutl.c b/src/netutl.c index 8db252d..a71b370 100644 --- a/src/netutl.c +++ b/src/netutl.c @@ -1,7 +1,7 @@ /* netutl.c -- some supporting network utility code Copyright (C) 1998-2005 Ivo Timmermans - 2000-2011 Guus Sliepen + 2000-2012 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 @@ -42,7 +42,7 @@ struct addrinfo *str2addrinfo(const char *address, const char *service, int sock err = getaddrinfo(address, service, &hint, &ai); if(err) { - logger(LOG_WARNING, "Error looking up %s port %s: %s", address, + logger(DEBUG_ALWAYS, LOG_WARNING, "Error looking up %s port %s: %s", address, service, gai_strerror(err)); return NULL; } @@ -62,8 +62,7 @@ sockaddr_t str2sockaddr(const char *address, const char *port) { err = getaddrinfo(address, port, &hint, &ai); if(err || !ai) { - ifdebug(SCARY_THINGS) - logger(LOG_DEBUG, "Unknown type address %s port %s", address, port); + logger(DEBUG_SCARY_THINGS, LOG_DEBUG, "Unknown type address %s port %s", address, port); result.sa.sa_family = AF_UNKNOWN; result.unknown.address = xstrdup(address); result.unknown.port = xstrdup(port); @@ -83,15 +82,17 @@ void sockaddr2str(const sockaddr_t *sa, char **addrstr, char **portstr) { int err; if(sa->sa.sa_family == AF_UNKNOWN) { - *addrstr = xstrdup(sa->unknown.address); - *portstr = xstrdup(sa->unknown.port); + if(addrstr) + *addrstr = xstrdup(sa->unknown.address); + if(portstr) + *portstr = xstrdup(sa->unknown.port); return; } err = getnameinfo(&sa->sa, SALEN(sa->sa), address, sizeof address, port, sizeof port, NI_NUMERICHOST | NI_NUMERICSERV); if(err) { - logger(LOG_ERR, "Error while translating addresses: %s", + logger(DEBUG_ALWAYS, LOG_ERR, "Error while translating addresses: %s", gai_strerror(err)); abort(); } @@ -99,7 +100,7 @@ void sockaddr2str(const sockaddr_t *sa, char **addrstr, char **portstr) { scopeid = strchr(address, '%'); if(scopeid) - *scopeid = '\0'; /* Descope. */ + *scopeid = '\0'; /* Descope. */ if(addrstr) *addrstr = xstrdup(address); @@ -121,7 +122,7 @@ char *sockaddr2hostname(const sockaddr_t *sa) { err = getnameinfo(&sa->sa, SALEN(sa->sa), address, sizeof address, port, sizeof port, hostnames ? 0 : (NI_NUMERICHOST | NI_NUMERICSERV)); if(err) { - logger(LOG_ERR, "Error while looking up hostname: %s", + logger(DEBUG_ALWAYS, LOG_ERR, "Error while looking up hostname: %s", gai_strerror(err)); } @@ -152,7 +153,7 @@ int sockaddrcmp_noport(const sockaddr_t *a, const sockaddr_t *b) { return memcmp(&a->in6.sin6_addr, &b->in6.sin6_addr, sizeof(a->in6.sin6_addr)); default: - logger(LOG_ERR, "sockaddrcmp() was called with unknown address family %d, exitting!", + logger(DEBUG_ALWAYS, LOG_ERR, "sockaddrcmp() was called with unknown address family %d, exitting!", a->sa.sa_family); abort(); } @@ -195,7 +196,7 @@ int sockaddrcmp(const sockaddr_t *a, const sockaddr_t *b) { return memcmp(&a->in6.sin6_port, &b->in6.sin6_port, sizeof a->in6.sin6_port); default: - logger(LOG_ERR, "sockaddrcmp() was called with unknown address family %d, exitting!", + logger(DEBUG_ALWAYS, LOG_ERR, "sockaddrcmp() was called with unknown address family %d, exitting!", a->sa.sa_family); abort(); } @@ -217,78 +218,10 @@ void sockaddrfree(sockaddr_t *a) { free(a->unknown.port); } } - + void sockaddrunmap(sockaddr_t *sa) { if(sa->sa.sa_family == AF_INET6 && IN6_IS_ADDR_V4MAPPED(&sa->in6.sin6_addr)) { sa->in.sin_addr.s_addr = ((uint32_t *) & sa->in6.sin6_addr)[3]; sa->in.sin_family = AF_INET; } } - -/* Subnet mask handling */ - -int maskcmp(const void *va, const void *vb, int masklen) { - int i, m, result; - const char *a = va; - const char *b = vb; - - for(m = masklen, i = 0; m >= 8; m -= 8, i++) { - result = a[i] - b[i]; - if(result) - return result; - } - - if(m) - return (a[i] & (0x100 - (1 << (8 - m)))) - - (b[i] & (0x100 - (1 << (8 - m)))); - - return 0; -} - -void mask(void *va, int masklen, int len) { - int i; - char *a = va; - - i = masklen / 8; - masklen %= 8; - - if(masklen) - a[i++] &= (0x100 - (1 << (8 - masklen))); - - for(; i < len; i++) - a[i] = 0; -} - -void maskcpy(void *va, const void *vb, int masklen, int len) { - int i, m; - char *a = va; - const char *b = vb; - - for(m = masklen, i = 0; m >= 8; m -= 8, i++) - a[i] = b[i]; - - if(m) { - a[i] = b[i] & (0x100 - (1 << (8 - m))); - i++; - } - - for(; i < len; i++) - a[i] = 0; -} - -bool maskcheck(const void *va, int masklen, int len) { - int i; - const char *a = va; - - i = masklen / 8; - masklen %= 8; - - if(masklen && a[i++] & (0xff >> masklen)) - return false; - - for(; i < len; i++) - if(a[i] != 0) - return false; - - return true; -} diff --git a/src/netutl.h b/src/netutl.h index 7fc41e8..0fef2d6 100644 --- a/src/netutl.h +++ b/src/netutl.h @@ -1,7 +1,7 @@ /* netutl.h -- header file for netutl.c Copyright (C) 1998-2005 Ivo Timmermans - 2000-2009 Guus Sliepen + 2000-2012 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 @@ -34,9 +34,5 @@ extern int sockaddrcmp_noport(const sockaddr_t *, const sockaddr_t *); extern void sockaddrunmap(sockaddr_t *); extern void sockaddrfree(sockaddr_t *); extern void sockaddrcpy(sockaddr_t *, const sockaddr_t *); -extern int maskcmp(const void *, const void *, int); -extern void maskcpy(void *, const void *, int, int); -extern void mask(void *, int, int); -extern bool maskcheck(const void *, int, int); -#endif /* __TINC_NETUTL_H__ */ +#endif /* __TINC_NETUTL_H__ */ diff --git a/src/node.c b/src/node.c index 38123e2..e67b9b9 100644 --- a/src/node.c +++ b/src/node.c @@ -1,6 +1,6 @@ /* node.c -- node tree management - Copyright (C) 2001-2011 Guus Sliepen , + Copyright (C) 2001-2012 Guus Sliepen , 2001-2005 Ivo Timmermans This program is free software; you can redistribute it and/or modify @@ -21,16 +21,17 @@ #include "system.h" #include "control_common.h" -#include "splay_tree.h" +#include "hash.h" #include "logger.h" #include "net.h" #include "netutl.h" #include "node.h" +#include "splay_tree.h" #include "utils.h" #include "xalloc.h" -splay_tree_t *node_tree; /* Known nodes, sorted by name */ -splay_tree_t *node_udp_tree; /* Known nodes, sorted by address and port */ +splay_tree_t *node_tree; +static hash_t *node_udp_cache; node_t *myself; @@ -38,24 +39,13 @@ static int node_compare(const node_t *a, const node_t *b) { return strcmp(a->name, b->name); } -static int node_udp_compare(const node_t *a, const node_t *b) { - int result; - - result = sockaddrcmp(&a->address, &b->address); - - if(result) - return result; - - return (a->name && b->name) ? strcmp(a->name, b->name) : 0; -} - void init_nodes(void) { node_tree = splay_alloc_tree((splay_compare_t) node_compare, (splay_action_t) free_node); - node_udp_tree = splay_alloc_tree((splay_compare_t) node_udp_compare, NULL); + node_udp_cache = hash_alloc(0x100, sizeof(sockaddr_t)); } void exit_nodes(void) { - splay_delete_tree(node_udp_tree); + hash_free(node_udp_cache); splay_delete_tree(node_tree); } @@ -85,12 +75,12 @@ void free_node(node_t *n) { cipher_close(&n->outcipher); digest_close(&n->outdigest); - ecdh_free(&n->ecdh); ecdsa_free(&n->ecdsa); + sptps_stop(&n->sptps); if(timeout_initialized(&n->mtuevent)) event_del(&n->mtuevent); - + if(n->hostname) free(n->hostname); @@ -108,23 +98,12 @@ void node_add(node_t *n) { } void node_del(node_t *n) { - splay_node_t *node, *next; - edge_t *e; - subnet_t *s; - - for(node = n->subnet_tree->head; node; node = next) { - next = node->next; - s = node->data; + for splay_each(subnet_t, s, n->subnet_tree) subnet_del(n, s); - } - for(node = n->edge_tree->head; node; node = next) { - next = node->next; - e = node->data; + for splay_each(edge_t, e, n->edge_tree) edge_del(e); - } - splay_delete(node_udp_tree, n); splay_delete(node_tree, n); } @@ -137,62 +116,41 @@ node_t *lookup_node(char *name) { } node_t *lookup_node_udp(const sockaddr_t *sa) { - node_t n = {NULL}; - - n.address = *sa; - n.name = NULL; - - return splay_search(node_udp_tree, &n); + return hash_search(node_udp_cache, sa); } void update_node_udp(node_t *n, const sockaddr_t *sa) { if(n == myself) { - logger(LOG_WARNING, "Trying to update UDP address of myself!"); + logger(DEBUG_ALWAYS, LOG_WARNING, "Trying to update UDP address of myself!"); return; } - splay_delete(node_udp_tree, n); - - if(n->hostname) - free(n->hostname); + hash_insert(node_udp_cache, &n->address, NULL); if(sa) { n->address = *sa; + hash_insert(node_udp_cache, sa, n); + free(n->hostname); n->hostname = sockaddr2hostname(&n->address); - splay_insert(node_udp_tree, n); - ifdebug(PROTOCOL) logger(LOG_DEBUG, "UDP address of %s set to %s", n->name, n->hostname); - } else { - memset(&n->address, 0, sizeof n->address); - n->hostname = NULL; - ifdebug(PROTOCOL) logger(LOG_DEBUG, "UDP address of %s cleared", n->name); + logger(DEBUG_PROTOCOL, LOG_DEBUG, "UDP address of %s set to %s", n->name, n->hostname); } } bool dump_nodes(connection_t *c) { - splay_node_t *node; - node_t *n; - - for(node = node_tree->head; node; node = node->next) { - n = node->data; - send_request(c, "%d %d %s at %s cipher %d digest %d maclength %d compression %d options %x status %04x nexthop %s via %s distance %d pmtu %hd (min %hd max %hd)", CONTROL, REQ_DUMP_NODES, - n->name, n->hostname, cipher_get_nid(&n->outcipher), + for splay_each(node_t, n, node_tree) + send_request(c, "%d %d %s %s %d %d %d %d %x %x %s %s %d %hd %hd %hd %ld", CONTROL, REQ_DUMP_NODES, + n->name, n->hostname ?: "unknown port unknown", cipher_get_nid(&n->outcipher), digest_get_nid(&n->outdigest), (int)digest_length(&n->outdigest), n->outcompression, n->options, bitfield_to_int(&n->status, sizeof n->status), n->nexthop ? n->nexthop->name : "-", - n->via ? n->via->name ?: "-" : "-", n->distance, n->mtu, n->minmtu, n->maxmtu); - } + n->via ? n->via->name ?: "-" : "-", n->distance, n->mtu, n->minmtu, n->maxmtu, (long)n->last_state_change); return send_request(c, "%d %d", CONTROL, REQ_DUMP_NODES); } bool dump_traffic(connection_t *c) { - splay_node_t *node; - node_t *n; - - for(node = node_tree->head; node; node = node->next) { - n = node->data; + for splay_each(node_t, n, node_tree) send_request(c, "%d %d %s %"PRIu64" %"PRIu64" %"PRIu64" %"PRIu64, CONTROL, REQ_DUMP_TRAFFIC, n->name, n->in_packets, n->in_bytes, n->out_packets, n->out_bytes); - } return send_request(c, "%d %d", CONTROL, REQ_DUMP_TRAFFIC); } diff --git a/src/node.h b/src/node.h index 0ce7542..3327fca 100644 --- a/src/node.h +++ b/src/node.h @@ -1,6 +1,6 @@ /* node.h -- header for node.c - Copyright (C) 2001-2010 Guus Sliepen , + Copyright (C) 2001-2012 Guus Sliepen , 2001-2005 Ivo Timmermans This program is free software; you can redistribute it and/or modify @@ -25,62 +25,65 @@ #include "cipher.h" #include "connection.h" #include "digest.h" -#include "ecdh.h" #include "subnet.h" typedef struct node_status_t { - unsigned int unused_active:1; /* 1 if active (not used for nodes) */ - unsigned int validkey:1; /* 1 if we currently have a valid key for him */ - unsigned int unused_waitingforkey:1; /* 1 if we already sent out a request */ - unsigned int visited:1; /* 1 if this node has been visited by one of the graph algorithms */ - unsigned int reachable:1; /* 1 if this node is reachable in the graph */ - unsigned int indirect:1; /* 1 if this node is not directly reachable by us */ - unsigned int ecdh:1; /* 1 if this node supports ECDH key exchange */ - unsigned int unused:25; + unsigned int unused_active:1; /* 1 if active (not used for nodes) */ + unsigned int validkey:1; /* 1 if we currently have a valid key for him */ + unsigned int waitingforkey:1; /* 1 if we already sent out a request */ + unsigned int visited:1; /* 1 if this node has been visited by one of the graph algorithms */ + unsigned int reachable:1; /* 1 if this node is reachable in the graph */ + unsigned int indirect:1; /* 1 if this node is not directly reachable by us */ + unsigned int sptps:1; /* 1 if this node supports SPTPS */ + unsigned int udp_confirmed:1; /* 1 if the address is one that we received UDP traffic on */ + unsigned int unused:24; } node_status_t; typedef struct node_t { - char *name; /* name of this node */ - uint32_t options; /* options turned on for this node */ + char *name; /* name of this node */ + uint32_t options; /* options turned on for this node */ - sockaddr_t address; /* his real (internet) ip to send UDP packets to */ - char *hostname; /* the hostname of its real ip */ + int sock; /* Socket to use for outgoing UDP packets */ + sockaddr_t address; /* his real (internet) ip to send UDP packets to */ + char *hostname; /* the hostname of its real ip */ node_status_t status; + time_t last_state_change; time_t last_req_key; - ecdsa_t ecdsa; /* His public ECDSA key */ - ecdh_t ecdh; /* State for ECDH key exchange */ + ecdsa_t ecdsa; /* His public ECDSA key */ + sptps_t sptps; - cipher_t incipher; /* Cipher for UDP packets */ - digest_t indigest; /* Digest for UDP packets */ + cipher_t incipher; /* Cipher for UDP packets */ + digest_t indigest; /* Digest for UDP packets */ - cipher_t outcipher; /* Cipher for UDP packets */ - digest_t outdigest; /* Digest for UDP packets */ + cipher_t outcipher; /* Cipher for UDP packets */ + digest_t outdigest; /* Digest for UDP packets */ - int incompression; /* Compressionlevel, 0 = no compression */ - int outcompression; /* Compressionlevel, 0 = no compression */ + int incompression; /* Compressionlevel, 0 = no compression */ + int outcompression; /* Compressionlevel, 0 = no compression */ int distance; - struct node_t *nexthop; /* nearest node from us to him */ - struct node_t *via; /* next hop for UDP packets */ + struct node_t *nexthop; /* nearest node from us to him */ + struct edge_t *prevedge; /* nearest node from him to us */ + struct node_t *via; /* next hop for UDP packets */ - splay_tree_t *subnet_tree; /* Pointer to a tree of subnets belonging to this node */ + splay_tree_t *subnet_tree; /* Pointer to a tree of subnets belonging to this node */ - splay_tree_t *edge_tree; /* Edges with this node as one of the endpoints */ + splay_tree_t *edge_tree; /* Edges with this node as one of the endpoints */ - struct connection_t *connection; /* Connection associated with this node (if a direct connection exists) */ + struct connection_t *connection; /* Connection associated with this node (if a direct connection exists) */ - uint32_t sent_seqno; /* Sequence number last sent to this node */ - uint32_t received_seqno; /* Sequence number last received from this node */ - uint32_t farfuture; /* Packets in a row that have arrived from the far future */ - unsigned char* late; /* Bitfield marking late packets */ + uint32_t sent_seqno; /* Sequence number last sent to this node */ + uint32_t received_seqno; /* Sequence number last received from this node */ + uint32_t farfuture; /* Packets in a row that have arrived from the far future */ + unsigned char* late; /* Bitfield marking late packets */ - length_t mtu; /* Maximum size of packets to send to this node */ - length_t minmtu; /* Probed minimum MTU */ - length_t maxmtu; /* Probed maximum MTU */ - int mtuprobes; /* Number of probes */ - struct event mtuevent; /* Probe event */ + length_t mtu; /* Maximum size of packets to send to this node */ + length_t minmtu; /* Probed minimum MTU */ + length_t maxmtu; /* Probed maximum MTU */ + int mtuprobes; /* Number of probes */ + struct event mtuevent; /* Probe event */ uint64_t in_packets; uint64_t in_bytes; @@ -90,7 +93,6 @@ typedef struct node_t { extern struct node_t *myself; extern splay_tree_t *node_tree; -extern splay_tree_t *node_udp_tree; extern void init_nodes(void); extern void exit_nodes(void); @@ -104,4 +106,4 @@ extern bool dump_nodes(struct connection_t *); extern bool dump_traffic(struct connection_t *); extern void update_node_udp(node_t *, const sockaddr_t *); -#endif /* __TINC_NODE_H__ */ +#endif /* __TINC_NODE_H__ */ diff --git a/src/openssl/cipher.c b/src/openssl/cipher.c index 86a1aca..553b4ad 100644 --- a/src/openssl/cipher.c +++ b/src/openssl/cipher.c @@ -1,6 +1,6 @@ /* cipher.c -- Symmetric block cipher handling - Copyright (C) 2007 Guus Sliepen + Copyright (C) 2007-2012 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 @@ -26,6 +26,12 @@ #include "logger.h" #include "xalloc.h" +typedef struct cipher_counter { + unsigned char counter[EVP_MAX_IV_LENGTH]; + unsigned char block[EVP_MAX_IV_LENGTH]; + int n; +} cipher_counter_t; + static bool cipher_open(cipher_t *cipher) { EVP_CIPHER_CTX_init(&cipher->ctx); @@ -38,7 +44,7 @@ bool cipher_open_by_name(cipher_t *cipher, const char *name) { if(cipher->cipher) return cipher_open(cipher); - logger(LOG_ERR, "Unknown cipher name '%s'!", name); + logger(DEBUG_ALWAYS, LOG_ERR, "Unknown cipher name '%s'!", name); return false; } @@ -48,7 +54,7 @@ bool cipher_open_by_nid(cipher_t *cipher, int nid) { if(cipher->cipher) return cipher_open(cipher); - logger(LOG_ERR, "Unknown cipher nid %d!", nid); + logger(DEBUG_ALWAYS, LOG_ERR, "Unknown cipher nid %d!", nid); return false; } @@ -59,10 +65,12 @@ bool cipher_open_blowfish_ofb(cipher_t *cipher) { void cipher_close(cipher_t *cipher) { EVP_CIPHER_CTX_cleanup(&cipher->ctx); + free(cipher->counter); + cipher->counter = NULL; } size_t cipher_keylength(const cipher_t *cipher) { - return cipher->cipher->key_len + cipher->cipher->iv_len; + return cipher->cipher->key_len + cipher->cipher->block_size; } bool cipher_set_key(cipher_t *cipher, void *key, bool encrypt) { @@ -76,7 +84,7 @@ bool cipher_set_key(cipher_t *cipher, void *key, bool encrypt) { if(result) return true; - logger(LOG_ERR, "Error while setting key: %s", ERR_error_string(ERR_get_error(), NULL)); + logger(DEBUG_ALWAYS, LOG_ERR, "Error while setting key: %s", ERR_error_string(ERR_get_error(), NULL)); return false; } @@ -91,28 +99,92 @@ bool cipher_set_key_from_rsa(cipher_t *cipher, void *key, size_t len, bool encry if(result) return true; - logger(LOG_ERR, "Error while setting key: %s", ERR_error_string(ERR_get_error(), NULL)); + logger(DEBUG_ALWAYS, LOG_ERR, "Error while setting key: %s", ERR_error_string(ERR_get_error(), NULL)); return false; } +bool cipher_set_counter(cipher_t *cipher, const void *counter, size_t len) { + if(len > cipher->cipher->block_size - 4) { + logger(DEBUG_ALWAYS, LOG_ERR, "Counter too long"); + abort(); + } + + memcpy(cipher->counter->counter + cipher->cipher->block_size - len, counter, len); + memset(cipher->counter->counter, 0, 4); + cipher->counter->n = 0; + + return true; +} + +bool cipher_set_counter_key(cipher_t *cipher, void *key) { + int result = EVP_EncryptInit_ex(&cipher->ctx, cipher->cipher, NULL, (unsigned char *)key, NULL); + if(!result) { + logger(DEBUG_ALWAYS, LOG_ERR, "Error while setting key: %s", ERR_error_string(ERR_get_error(), NULL)); + return false; + } + + if(!cipher->counter) + cipher->counter = xmalloc_and_zero(sizeof *cipher->counter); + else + cipher->counter->n = 0; + + memcpy(cipher->counter->counter, (unsigned char *)key + cipher->cipher->key_len, cipher->cipher->block_size); + + return true; +} + +bool cipher_counter_xor(cipher_t *cipher, const void *indata, size_t inlen, void *outdata) { + if(!cipher->counter) { + logger(DEBUG_ALWAYS, LOG_ERR, "Counter not initialized"); + return false; + } + + const unsigned char *in = indata; + unsigned char *out = outdata; + + while(inlen--) { + // Encrypt the new counter value if we need it + if(!cipher->counter->n) { + int len; + if(!EVP_EncryptUpdate(&cipher->ctx, cipher->counter->block, &len, cipher->counter->counter, cipher->cipher->block_size)) { + logger(DEBUG_ALWAYS, LOG_ERR, "Error while encrypting: %s", ERR_error_string(ERR_get_error(), NULL)); + return false; + } + + // Increase the counter value + for(int i = 0; i < cipher->cipher->block_size; i++) + if(++cipher->counter->counter[i]) + break; + } + + *out++ = *in++ ^ cipher->counter->counter[cipher->counter->n++]; + + if(cipher->counter->n >= cipher->cipher->block_size) + cipher->counter->n = 0; + } + + return true; +} + + bool cipher_encrypt(cipher_t *cipher, const void *indata, size_t inlen, void *outdata, size_t *outlen, bool oneshot) { if(oneshot) { int len, pad; if(EVP_EncryptInit_ex(&cipher->ctx, NULL, NULL, NULL, NULL) && EVP_EncryptUpdate(&cipher->ctx, (unsigned char *)outdata, &len, indata, inlen) && EVP_EncryptFinal(&cipher->ctx, (unsigned char *)outdata + len, &pad)) { - *outlen = len + pad; + if(outlen) *outlen = len + pad; return true; } } else { int len; if(EVP_EncryptUpdate(&cipher->ctx, outdata, &len, indata, inlen)) { - *outlen = len; + if(outlen) *outlen = len; return true; } } - logger(LOG_ERR, "Error while encrypting: %s", ERR_error_string(ERR_get_error(), NULL)); + logger(DEBUG_ALWAYS, LOG_ERR, "Error while encrypting: %s", ERR_error_string(ERR_get_error(), NULL)); return false; } @@ -122,18 +194,18 @@ bool cipher_decrypt(cipher_t *cipher, const void *indata, size_t inlen, void *ou if(EVP_DecryptInit_ex(&cipher->ctx, NULL, NULL, NULL, NULL) && EVP_DecryptUpdate(&cipher->ctx, (unsigned char *)outdata, &len, indata, inlen) && EVP_DecryptFinal(&cipher->ctx, (unsigned char *)outdata + len, &pad)) { - *outlen = len + pad; + if(outlen) *outlen = len + pad; return true; } } else { int len; if(EVP_EncryptUpdate(&cipher->ctx, outdata, &len, indata, inlen)) { - *outlen = len; + if(outlen) *outlen = len; return true; } } - logger(LOG_ERR, "Error while decrypting: %s", ERR_error_string(ERR_get_error(), NULL)); + logger(DEBUG_ALWAYS, LOG_ERR, "Error while decrypting: %s", ERR_error_string(ERR_get_error(), NULL)); return false; } diff --git a/src/openssl/cipher.h b/src/openssl/cipher.h index 380384a..c9f89eb 100644 --- a/src/openssl/cipher.h +++ b/src/openssl/cipher.h @@ -1,6 +1,6 @@ /* cipher.h -- header file cipher.c - Copyright (C) 2007 Guus Sliepen + Copyright (C) 2007-2012 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 @@ -29,6 +29,7 @@ typedef struct cipher { EVP_CIPHER_CTX ctx; const EVP_CIPHER *cipher; + struct cipher_counter *counter; } cipher_t; extern bool cipher_open_by_name(cipher_t *, const char *); @@ -38,8 +39,11 @@ extern void cipher_close(cipher_t *); extern size_t cipher_keylength(const cipher_t *); extern bool cipher_set_key(cipher_t *, void *, bool); extern bool cipher_set_key_from_rsa(cipher_t *, void *, size_t, bool); +extern bool cipher_set_counter(cipher_t *, const void *, size_t); +extern bool cipher_set_counter_key(cipher_t *, void *); extern bool cipher_encrypt(cipher_t *, const void *indata, size_t inlen, void *outdata, size_t *outlen, bool); extern bool cipher_decrypt(cipher_t *, const void *indata, size_t inlen, void *outdata, size_t *outlen, bool); +extern bool cipher_counter_xor(cipher_t *, const void *indata, size_t inlen, void *outdata); extern int cipher_get_nid(const cipher_t *); extern bool cipher_active(const cipher_t *); diff --git a/src/openssl/crypto.c b/src/openssl/crypto.c index db921d6..c695be8 100644 --- a/src/openssl/crypto.c +++ b/src/openssl/crypto.c @@ -26,12 +26,12 @@ #include "crypto.h" void crypto_init(void) { - RAND_load_file("/dev/urandom", 1024); + RAND_load_file("/dev/urandom", 1024); - ENGINE_load_builtin_engines(); - ENGINE_register_all_complete(); + ENGINE_load_builtin_engines(); + ENGINE_register_all_complete(); - OpenSSL_add_all_algorithms(); + OpenSSL_add_all_algorithms(); } void crypto_exit(void) { diff --git a/src/openssl/digest.c b/src/openssl/digest.c index 09ed666..79db491 100644 --- a/src/openssl/digest.c +++ b/src/openssl/digest.c @@ -1,6 +1,6 @@ /* digest.c -- Digest handling - Copyright (C) 2007 Guus Sliepen + Copyright (C) 2007-2012 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 @@ -41,7 +41,7 @@ bool digest_open_by_name(digest_t *digest, const char *name, int maclength) { digest->key = NULL; if(!digest->digest) { - logger(LOG_DEBUG, "Unknown digest name '%s'!", name); + logger(DEBUG_ALWAYS, LOG_DEBUG, "Unknown digest name '%s'!", name); return false; } @@ -54,7 +54,7 @@ bool digest_open_by_nid(digest_t *digest, int nid, int maclength) { digest->key = NULL; if(!digest->digest) { - logger(LOG_DEBUG, "Unknown digest nid %d!", nid); + logger(DEBUG_ALWAYS, LOG_DEBUG, "Unknown digest nid %d!", nid); return false; } @@ -78,8 +78,7 @@ bool digest_set_key(digest_t *digest, const void *key, size_t len) { } void digest_close(digest_t *digest) { - if(digest->key) - free(digest->key); + free(digest->key); digest->key = NULL; } @@ -95,7 +94,7 @@ bool digest_create(digest_t *digest, const void *indata, size_t inlen, void *out if(!EVP_DigestInit(&ctx, digest->digest) || !EVP_DigestUpdate(&ctx, indata, inlen) || !EVP_DigestFinal(&ctx, tmpdata, NULL)) { - logger(LOG_DEBUG, "Error creating digest: %s", ERR_error_string(ERR_get_error(), NULL)); + logger(DEBUG_ALWAYS, LOG_DEBUG, "Error creating digest: %s", ERR_error_string(ERR_get_error(), NULL)); return false; } } @@ -115,6 +114,10 @@ int digest_get_nid(const digest_t *digest) { return digest->digest ? digest->digest->type : 0; } +size_t digest_keylength(const digest_t *digest) { + return digest->digest->md_size; +} + size_t digest_length(const digest_t *digest) { return digest->maclength; } diff --git a/src/openssl/digest.h b/src/openssl/digest.h index f3855c9..c192249 100644 --- a/src/openssl/digest.h +++ b/src/openssl/digest.h @@ -1,6 +1,6 @@ /* digest.h -- header file digest.c - Copyright (C) 2007 Guus Sliepen + Copyright (C) 2007-2011 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 @@ -39,6 +39,7 @@ extern bool digest_create(struct digest *, const void *indata, size_t inlen, voi extern bool digest_verify(struct digest *, const void *indata, size_t inlen, const void *digestdata); extern bool digest_set_key(struct digest *, const void *key, size_t len); extern int digest_get_nid(const struct digest *); +extern size_t digest_keylength(const struct digest *); extern size_t digest_length(const struct digest *); extern bool digest_active(const struct digest *); diff --git a/src/openssl/ecdh.c b/src/openssl/ecdh.c index 4dd399f..f94555d 100644 --- a/src/openssl/ecdh.c +++ b/src/openssl/ecdh.c @@ -1,6 +1,6 @@ /* ecdh.c -- Diffie-Hellman key exchange handling - Copyright (C) 2011 Guus Sliepen + Copyright (C) 2011-2012 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 @@ -30,21 +30,32 @@ bool ecdh_generate_public(ecdh_t *ecdh, void *pubkey) { *ecdh = EC_KEY_new_by_curve_name(NID_secp521r1); - if(!EC_KEY_generate_key(*ecdh)) { - logger(LOG_ERR, "Generating EC key failed: %s", ERR_error_string(ERR_get_error(), NULL)); - abort(); + if(!*ecdh) { + logger(DEBUG_ALWAYS, LOG_ERR, "Generating EC key_by_curve_name failed: %s", ERR_error_string(ERR_get_error(), NULL)); + return false; } - + + if(!EC_KEY_generate_key(*ecdh)) { + EC_KEY_free(*ecdh); + *ecdh = NULL; + logger(DEBUG_ALWAYS, LOG_ERR, "Generating EC key failed: %s", ERR_error_string(ERR_get_error(), NULL)); + return false; + } + const EC_POINT *point = EC_KEY_get0_public_key(*ecdh); if(!point) { - logger(LOG_ERR, "Getting public key failed: %s", ERR_error_string(ERR_get_error(), NULL)); - abort(); + EC_KEY_free(*ecdh); + *ecdh = NULL; + logger(DEBUG_ALWAYS, LOG_ERR, "Getting public key failed: %s", ERR_error_string(ERR_get_error(), NULL)); + return false; } size_t result = EC_POINT_point2oct(EC_KEY_get0_group(*ecdh), point, POINT_CONVERSION_COMPRESSED, pubkey, ECDH_SIZE, NULL); if(!result) { - logger(LOG_ERR, "Converting EC_POINT to binary failed: %s", ERR_error_string(ERR_get_error(), NULL)); - abort(); + EC_KEY_free(*ecdh); + *ecdh = NULL; + logger(DEBUG_ALWAYS, LOG_ERR, "Converting EC_POINT to binary failed: %s", ERR_error_string(ERR_get_error(), NULL)); + return false; } return true; @@ -53,14 +64,15 @@ bool ecdh_generate_public(ecdh_t *ecdh, void *pubkey) { bool ecdh_compute_shared(ecdh_t *ecdh, const void *pubkey, void *shared) { EC_POINT *point = EC_POINT_new(EC_KEY_get0_group(*ecdh)); if(!point) { - logger(LOG_ERR, "EC_POINT_new() failed: %s", ERR_error_string(ERR_get_error(), NULL)); - abort(); + logger(DEBUG_ALWAYS, LOG_ERR, "EC_POINT_new() failed: %s", ERR_error_string(ERR_get_error(), NULL)); + return false; } int result = EC_POINT_oct2point(EC_KEY_get0_group(*ecdh), point, pubkey, ECDH_SIZE, NULL); if(!result) { - logger(LOG_ERR, "Converting binary to EC_POINT failed: %s", ERR_error_string(ERR_get_error(), NULL)); - abort(); + EC_POINT_free(point); + logger(DEBUG_ALWAYS, LOG_ERR, "Converting binary to EC_POINT failed: %s", ERR_error_string(ERR_get_error(), NULL)); + return false; } result = ECDH_compute_key(shared, ECDH_SIZE, point, *ecdh, NULL); @@ -69,7 +81,7 @@ bool ecdh_compute_shared(ecdh_t *ecdh, const void *pubkey, void *shared) { *ecdh = NULL; if(!result) { - logger(LOG_ERR, "Computing Elliptic Curve Diffie-Hellman shared key failed: %s", ERR_error_string(ERR_get_error(), NULL)); + logger(DEBUG_ALWAYS, LOG_ERR, "Computing Elliptic Curve Diffie-Hellman shared key failed: %s", ERR_error_string(ERR_get_error(), NULL)); return false; } diff --git a/src/openssl/ecdsa.c b/src/openssl/ecdsa.c index 43464d8..e2af6f9 100644 --- a/src/openssl/ecdsa.c +++ b/src/openssl/ecdsa.c @@ -1,6 +1,6 @@ /* ecdsa.c -- ECDSA key handling - Copyright (C) 2011 Guus Sliepen + Copyright (C) 2011-2012 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 @@ -30,15 +30,19 @@ // bool ecdsa_set_base64_public_key(ecdsa_t *ecdsa, const char *p) { *ecdsa = EC_KEY_new_by_curve_name(NID_secp521r1); + if(!*ecdsa) { + logger(DEBUG_ALWAYS, LOG_DEBUG, "EC_KEY_new_by_curve_name failed: %s", ERR_error_string(ERR_get_error(), NULL)); + return false; + } int len = strlen(p); unsigned char pubkey[len / 4 * 3 + 3]; const unsigned char *ppubkey = pubkey; - len = b64decode(p, pubkey, len); + len = b64decode(p, (char *)pubkey, len); if(!o2i_ECPublicKey(ecdsa, &ppubkey, len)) { - logger(LOG_DEBUG, "o2i_ECPublicKey failed: %s", ERR_error_string(ERR_get_error(), NULL)); - abort(); + logger(DEBUG_ALWAYS, LOG_DEBUG, "o2i_ECPublicKey failed: %s", ERR_error_string(ERR_get_error(), NULL)); + return false; } return true; @@ -49,7 +53,7 @@ char *ecdsa_get_base64_public_key(ecdsa_t *ecdsa) { int len = i2o_ECPublicKey(*ecdsa, &pubkey); char *base64 = malloc(len * 4 / 3 + 5); - b64encode(pubkey, base64, len); + b64encode((char *)pubkey, base64, len); free(pubkey); @@ -64,7 +68,7 @@ bool ecdsa_read_pem_public_key(ecdsa_t *ecdsa, FILE *fp) { if(*ecdsa) return true; - logger(LOG_ERR, "Unable to read ECDSA public key: %s", ERR_error_string(ERR_get_error(), NULL)); + logger(DEBUG_ALWAYS, LOG_ERR, "Unable to read ECDSA public key: %s", ERR_error_string(ERR_get_error(), NULL)); return false; } @@ -73,8 +77,8 @@ bool ecdsa_read_pem_private_key(ecdsa_t *ecdsa, FILE *fp) { if(*ecdsa) return true; - - logger(LOG_ERR, "Unable to read ECDSA private key: %s", ERR_error_string(ERR_get_error(), NULL)); + + logger(DEBUG_ALWAYS, LOG_ERR, "Unable to read ECDSA private key: %s", ERR_error_string(ERR_get_error(), NULL)); return false; } @@ -87,31 +91,27 @@ size_t ecdsa_size(ecdsa_t *ecdsa) { bool ecdsa_sign(ecdsa_t *ecdsa, const void *in, size_t len, void *sig) { unsigned int siglen = ECDSA_size(*ecdsa); - char hash[SHA512_DIGEST_LENGTH]; + unsigned char hash[SHA512_DIGEST_LENGTH]; SHA512(in, len, hash); memset(sig, 0, siglen); if(!ECDSA_sign(0, hash, sizeof hash, sig, &siglen, *ecdsa)) { - logger(LOG_DEBUG, "ECDSA_sign() failed: %s", ERR_error_string(ERR_get_error(), NULL)); + logger(DEBUG_ALWAYS, LOG_DEBUG, "ECDSA_sign() failed: %s", ERR_error_string(ERR_get_error(), NULL)); return false; } - if(siglen != ECDSA_size(*ecdsa)) { - logger(LOG_ERR, "Signature length %d != %d", siglen, ECDSA_size(*ecdsa)); - } - return true; } bool ecdsa_verify(ecdsa_t *ecdsa, const void *in, size_t len, const void *sig) { unsigned int siglen = ECDSA_size(*ecdsa); - char hash[SHA512_DIGEST_LENGTH]; + unsigned char hash[SHA512_DIGEST_LENGTH]; SHA512(in, len, hash); if(!ECDSA_verify(0, hash, sizeof hash, sig, siglen, *ecdsa)) { - logger(LOG_DEBUG, "ECDSA_verify() failed: %s", ERR_error_string(ERR_get_error(), NULL)); + logger(DEBUG_ALWAYS, LOG_DEBUG, "ECDSA_verify() failed: %s", ERR_error_string(ERR_get_error(), NULL)); return false; } diff --git a/src/openssl/ecdsagen.c b/src/openssl/ecdsagen.c index 86b79a2..883c77e 100644 --- a/src/openssl/ecdsagen.c +++ b/src/openssl/ecdsagen.c @@ -67,7 +67,7 @@ char *ecdsa_get_base64_public_key(ecdsa_t *ecdsa) { int len = i2o_ECPublicKey(*ecdsa, &pubkey); char *base64 = malloc(len * 4 / 3 + 5); - b64encode(pubkey, base64, len); + b64encode((char *)pubkey, base64, len); free(pubkey); diff --git a/src/openssl/prf.c b/src/openssl/prf.c index df7f445..b37efdf 100644 --- a/src/openssl/prf.c +++ b/src/openssl/prf.c @@ -1,6 +1,6 @@ /* prf.c -- Pseudo-Random Function for key material generation - Copyright (C) 2011 Guus Sliepen + Copyright (C) 2011-2012 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 @@ -19,16 +19,18 @@ #include "system.h" +#include + #include "digest.h" #include "prf.h" /* Generate key material from a master secret and a seed, based on RFC 4346 section 5. - We use SHA512 and Whirlpool instead of MD5 and SHA1. + We use SHA512 instead of MD5 and SHA1. */ -static bool prf_xor(int nid, char *secret, size_t secretlen, char *seed, size_t seedlen, char *out, ssize_t outlen) { +static bool prf_xor(int nid, const char *secret, size_t secretlen, char *seed, size_t seedlen, char *out, ssize_t outlen) { digest_t digest; - + if(!digest_open_by_nid(&digest, nid, -1)) return false; @@ -65,12 +67,9 @@ static bool prf_xor(int nid, char *secret, size_t secretlen, char *seed, size_t return true; } -bool prf(char *secret, size_t secretlen, char *seed, size_t seedlen, char *out, size_t outlen) { - /* Split secret in half, generate outlen bits with two different hash algorithms, - and XOR the results. */ - +bool prf(const char *secret, size_t secretlen, char *seed, size_t seedlen, char *out, size_t outlen) { + /* This construction allows us to easily switch back to a scheme where the PRF is calculated using two different digest algorithms. */ memset(out, 0, outlen); - return prf_xor(NID_sha512, secret, (secretlen + 1) / 2, seed, seedlen, out, outlen) - && prf_xor(NID_whirlpool, secret + secretlen / 2, (secretlen + 1) / 2, seed, seedlen, out, outlen); + return prf_xor(NID_sha512, secret, secretlen, seed, seedlen, out, outlen); } diff --git a/src/openssl/prf.h b/src/openssl/prf.h index 264d198..6525505 100644 --- a/src/openssl/prf.h +++ b/src/openssl/prf.h @@ -20,6 +20,6 @@ #ifndef __TINC_PRF_H__ #define __TINC_PRF_H__ -extern bool prf(char *secret, size_t secretlen, char *seed, size_t seedlen, char *out, size_t outlen); +extern bool prf(const char *secret, size_t secretlen, char *seed, size_t seedlen, char *out, size_t outlen); #endif diff --git a/src/openssl/rsa.c b/src/openssl/rsa.c index c3ea692..1b5ce56 100644 --- a/src/openssl/rsa.c +++ b/src/openssl/rsa.c @@ -1,6 +1,6 @@ /* rsa.c -- RSA key handling - Copyright (C) 2007 Guus Sliepen + Copyright (C) 2007-2012 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 @@ -29,16 +29,21 @@ bool rsa_set_hex_public_key(rsa_t *rsa, char *n, char *e) { *rsa = RSA_new(); - BN_hex2bn(&(*rsa)->n, n); - BN_hex2bn(&(*rsa)->e, e); + if(BN_hex2bn(&(*rsa)->n, n) != strlen(n)) + return false; + if(BN_hex2bn(&(*rsa)->e, e) != strlen(e)) + return false; return true; } bool rsa_set_hex_private_key(rsa_t *rsa, char *n, char *e, char *d) { *rsa = RSA_new(); - BN_hex2bn(&(*rsa)->n, n); - BN_hex2bn(&(*rsa)->e, e); - BN_hex2bn(&(*rsa)->d, d); + if(BN_hex2bn(&(*rsa)->n, n) != strlen(n)) + return false; + if(BN_hex2bn(&(*rsa)->e, e) != strlen(e)) + return false; + if(BN_hex2bn(&(*rsa)->d, d) != strlen(d)) + return false; return true; } @@ -49,13 +54,13 @@ bool rsa_read_pem_public_key(rsa_t *rsa, FILE *fp) { if(*rsa) return true; - + *rsa = PEM_read_RSA_PUBKEY(fp, rsa, NULL, NULL); if(*rsa) return true; - logger(LOG_ERR, "Unable to read RSA public key: %s", ERR_error_string(ERR_get_error(), NULL)); + logger(DEBUG_ALWAYS, LOG_ERR, "Unable to read RSA public key: %s", ERR_error_string(ERR_get_error(), NULL)); return false; } @@ -64,8 +69,8 @@ bool rsa_read_pem_private_key(rsa_t *rsa, FILE *fp) { if(*rsa) return true; - - logger(LOG_ERR, "Unable to read RSA private key: %s", ERR_error_string(ERR_get_error(), NULL)); + + logger(DEBUG_ALWAYS, LOG_ERR, "Unable to read RSA private key: %s", ERR_error_string(ERR_get_error(), NULL)); return false; } @@ -77,16 +82,16 @@ bool rsa_public_encrypt(rsa_t *rsa, void *in, size_t len, void *out) { if(RSA_public_encrypt(len, in, out, *rsa, RSA_NO_PADDING) == len) return true; - logger(LOG_ERR, "Unable to perform RSA encryption: %s", ERR_error_string(ERR_get_error(), NULL)); - return false; + logger(DEBUG_ALWAYS, LOG_ERR, "Unable to perform RSA encryption: %s", ERR_error_string(ERR_get_error(), NULL)); + return false; } bool rsa_private_decrypt(rsa_t *rsa, void *in, size_t len, void *out) { if(RSA_private_decrypt(len, in, out, *rsa, RSA_NO_PADDING) == len) return true; - logger(LOG_ERR, "Unable to perform RSA decryption: %s", ERR_error_string(ERR_get_error(), NULL)); - return false; + logger(DEBUG_ALWAYS, LOG_ERR, "Unable to perform RSA decryption: %s", ERR_error_string(ERR_get_error(), NULL)); + return false; } bool rsa_active(rsa_t *rsa) { diff --git a/src/openssl/rsa.h b/src/openssl/rsa.h index 10fe346..9a826cb 100644 --- a/src/openssl/rsa.h +++ b/src/openssl/rsa.h @@ -1,6 +1,6 @@ /* rsa.h -- RSA key handling - Copyright (C) 2007 Guus Sliepen + Copyright (C) 2007-2011 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 diff --git a/src/prf.c b/src/prf.c new file mode 100644 index 0000000..b37efdf --- /dev/null +++ b/src/prf.c @@ -0,0 +1,75 @@ +/* + prf.c -- Pseudo-Random Function for key material generation + Copyright (C) 2011-2012 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "system.h" + +#include + +#include "digest.h" +#include "prf.h" + +/* Generate key material from a master secret and a seed, based on RFC 4346 section 5. + We use SHA512 instead of MD5 and SHA1. + */ + +static bool prf_xor(int nid, const char *secret, size_t secretlen, char *seed, size_t seedlen, char *out, ssize_t outlen) { + digest_t digest; + + if(!digest_open_by_nid(&digest, nid, -1)) + return false; + + if(!digest_set_key(&digest, secret, secretlen)) + return false; + + size_t len = digest_length(&digest); + + /* Data is what the "inner" HMAC function processes. + It consists of the previous HMAC result plus the seed. + */ + + char data[len + seedlen]; + memset(data, 0, len); + memcpy(data + len, seed, seedlen); + + char hash[len]; + + while(outlen > 0) { + /* Inner HMAC */ + digest_create(&digest, data, len + seedlen, data); + + /* Outer HMAC */ + digest_create(&digest, data, len + seedlen, hash); + + /* XOR the results of the outer HMAC into the out buffer */ + for(int i = 0; i < len && i < outlen; i++) + *out++ ^= hash[i]; + + outlen -= len; + } + + digest_close(&digest); + return true; +} + +bool prf(const char *secret, size_t secretlen, char *seed, size_t seedlen, char *out, size_t outlen) { + /* This construction allows us to easily switch back to a scheme where the PRF is calculated using two different digest algorithms. */ + memset(out, 0, outlen); + + return prf_xor(NID_sha512, secret, secretlen, seed, seedlen, out, outlen); +} diff --git a/src/process.c b/src/process.c index a7d0f26..37ba84b 100644 --- a/src/process.c +++ b/src/process.c @@ -1,7 +1,7 @@ /* process.c -- process management functions Copyright (C) 1999-2005 Ivo Timmermans, - 2000-2011 Guus Sliepen + 2000-2012 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 @@ -55,13 +55,11 @@ static SERVICE_STATUS_HANDLE statushandle = 0; static bool install_service(void) { char command[4096] = "\""; - char **argp; - bool space; SERVICE_DESCRIPTION description = {"Virtual Private Network daemon"}; manager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); if(!manager) { - logger(LOG_ERR, "Could not open service manager: %s", winerror(GetLastError())); + logger(DEBUG_ALWAYS, LOG_ERR, "Could not open service manager: %s", winerror(GetLastError())); return false; } @@ -74,13 +72,13 @@ static bool install_service(void) { strncat(command, "\"", sizeof command - strlen(command)); - for(argp = g_argv + 1; *argp; argp++) { - space = strchr(*argp, ' '); + for(char **argp = g_argv + 1; *argp; argp++) { + char *space = strchr(*argp, ' '); strncat(command, " ", sizeof command - strlen(command)); - + if(space) strncat(command, "\"", sizeof command - strlen(command)); - + strncat(command, *argp, sizeof command - strlen(command)); if(space) @@ -90,25 +88,25 @@ static bool install_service(void) { service = CreateService(manager, identname, identname, SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START, SERVICE_ERROR_NORMAL, command, NULL, NULL, NULL, NULL, NULL); - + if(!service) { DWORD lasterror = GetLastError(); - logger(LOG_ERR, "Could not create %s service: %s", identname, winerror(lasterror)); + logger(DEBUG_ALWAYS, LOG_ERR, "Could not create %s service: %s", identname, winerror(lasterror)); if(lasterror != ERROR_SERVICE_EXISTS) return false; } if(service) { ChangeServiceConfig2(service, SERVICE_CONFIG_DESCRIPTION, &description); - logger(LOG_INFO, "%s service installed", identname); + logger(DEBUG_ALWAYS, LOG_INFO, "%s service installed", identname); } else { service = OpenService(manager, identname, SERVICE_ALL_ACCESS); } if(!StartService(service, 0, NULL)) - logger(LOG_WARNING, "Could not start %s service: %s", identname, winerror(GetLastError())); + logger(DEBUG_ALWAYS, LOG_WARNING, "Could not start %s service: %s", identname, winerror(GetLastError())); else - logger(LOG_INFO, "%s service started", identname); + logger(DEBUG_ALWAYS, LOG_INFO, "%s service started", identname); return true; } @@ -119,53 +117,49 @@ DWORD WINAPI controlhandler(DWORD request, DWORD type, LPVOID boe, LPVOID bah) { SetServiceStatus(statushandle, &status); return NO_ERROR; case SERVICE_CONTROL_STOP: - logger(LOG_NOTICE, "Got %s request", "SERVICE_CONTROL_STOP"); + logger(DEBUG_ALWAYS, LOG_NOTICE, "Got %s request", "SERVICE_CONTROL_STOP"); break; case SERVICE_CONTROL_SHUTDOWN: - logger(LOG_NOTICE, "Got %s request", "SERVICE_CONTROL_SHUTDOWN"); + logger(DEBUG_ALWAYS, LOG_NOTICE, "Got %s request", "SERVICE_CONTROL_SHUTDOWN"); break; default: - logger(LOG_WARNING, "Got unexpected request %d", request); + logger(DEBUG_ALWAYS, LOG_WARNING, "Got unexpected request %d", (int)request); return ERROR_CALL_NOT_IMPLEMENTED; } event_loopexit(NULL); - status.dwWaitHint = 30000; - status.dwCurrentState = SERVICE_STOP_PENDING; + status.dwWaitHint = 30000; + status.dwCurrentState = SERVICE_STOP_PENDING; SetServiceStatus(statushandle, &status); return NO_ERROR; } VOID WINAPI run_service(DWORD argc, LPTSTR* argv) { - int err = 1; extern int main2(int argc, char **argv); - - status.dwServiceType = SERVICE_WIN32; + status.dwServiceType = SERVICE_WIN32; status.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN; - status.dwWin32ExitCode = 0; - status.dwServiceSpecificExitCode = 0; - status.dwCheckPoint = 0; + status.dwWin32ExitCode = 0; + status.dwServiceSpecificExitCode = 0; + status.dwCheckPoint = 0; - statushandle = RegisterServiceCtrlHandlerEx(identname, controlhandler, NULL); + statushandle = RegisterServiceCtrlHandlerEx(identname, controlhandler, NULL); if (!statushandle) { - logger(LOG_ERR, "System call `%s' failed: %s", "RegisterServiceCtrlHandlerEx", winerror(GetLastError())); - err = 1; + logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "RegisterServiceCtrlHandlerEx", winerror(GetLastError())); } else { - status.dwWaitHint = 30000; - status.dwCurrentState = SERVICE_START_PENDING; + status.dwWaitHint = 30000; + status.dwCurrentState = SERVICE_START_PENDING; SetServiceStatus(statushandle, &status); - status.dwWaitHint = 0; + status.dwWaitHint = 0; status.dwCurrentState = SERVICE_RUNNING; SetServiceStatus(statushandle, &status); - err = main2(argc, argv); + main2(argc, argv); status.dwWaitHint = 0; - status.dwCurrentState = SERVICE_STOPPED; - //status.dwWin32ExitCode = err; + status.dwCurrentState = SERVICE_STOPPED; SetServiceStatus(statushandle, &status); } @@ -183,7 +177,7 @@ bool init_service(void) { return false; } else - logger(LOG_ERR, "System call `%s' failed: %s", "StartServiceCtrlDispatcher", winerror(GetLastError())); + logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "StartServiceCtrlDispatcher", winerror(GetLastError())); } return true; @@ -206,19 +200,18 @@ bool detach(void) { if(do_detach) { #ifndef HAVE_MINGW if(daemon(0, 0)) { - fprintf(stderr, "Couldn't detach from terminal: %s", - strerror(errno)); + logger(DEBUG_ALWAYS, LOG_ERR, "Couldn't detach from terminal: %s", strerror(errno)); return false; } #else if(!statushandle) - exit(install_service()); + exit(!install_service()); #endif } openlogger(identname, use_logfile?LOGMODE_FILE:(do_detach?LOGMODE_SYSLOG:LOGMODE_STDERR)); - logger(LOG_NOTICE, "tincd %s (%s %s) starting, debug level %d", + logger(DEBUG_ALWAYS, LOG_NOTICE, "tincd %s (%s %s) starting, debug level %d", VERSION, __DATE__, __TIME__, debug_level); return true; @@ -226,46 +219,40 @@ bool detach(void) { bool execute_script(const char *name, char **envp) { #ifdef HAVE_SYSTEM - int status, len; char *scriptname; - int i; + char *command; -#ifndef HAVE_MINGW - len = xasprintf(&scriptname, "\"%s/%s\"", confbase, name); -#else - len = xasprintf(&scriptname, "\"%s/%s.bat\"", confbase, name); -#endif - if(len < 0) - return false; + xasprintf(&scriptname, "%s" SLASH "%s%s", confbase, name, scriptextension); - scriptname[len - 1] = '\0'; - -#ifndef HAVE_TUNEMU /* First check if there is a script */ - if(access(scriptname + 1, F_OK)) { + if(access(scriptname, F_OK)) { free(scriptname); return true; } -#endif - ifdebug(STATUS) logger(LOG_INFO, "Executing script %s", name); + logger(DEBUG_STATUS, LOG_INFO, "Executing script %s", name); #ifdef HAVE_PUTENV /* Set environment */ - - for(i = 0; envp[i]; i++) + + for(int i = 0; envp[i]; i++) putenv(envp[i]); #endif - scriptname[len - 1] = '\"'; - status = system(scriptname); + if(scriptinterpreter) + xasprintf(&command, "%s \"%s\"", scriptinterpreter, scriptname); + else + xasprintf(&command, "\"%s\"", scriptname); + int status = system(command); + + free(command); free(scriptname); /* Unset environment */ - for(i = 0; envp[i]; i++) { + for(int i = 0; envp[i]; i++) { char *e = strchr(envp[i], '='); if(e) { char p[e - envp[i] + 1]; @@ -277,22 +264,22 @@ bool execute_script(const char *name, char **envp) { #ifdef WEXITSTATUS if(status != -1) { - if(WIFEXITED(status)) { /* Child exited by itself */ + if(WIFEXITED(status)) { /* Child exited by itself */ if(WEXITSTATUS(status)) { - logger(LOG_ERR, "Script %s exited with non-zero status %d", + logger(DEBUG_ALWAYS, LOG_ERR, "Script %s exited with non-zero status %d", name, WEXITSTATUS(status)); return false; } - } else if(WIFSIGNALED(status)) { /* Child was killed by a signal */ - logger(LOG_ERR, "Script %s was killed by signal %d (%s)", + } else if(WIFSIGNALED(status)) { /* Child was killed by a signal */ + logger(DEBUG_ALWAYS, LOG_ERR, "Script %s was killed by signal %d (%s)", name, WTERMSIG(status), strsignal(WTERMSIG(status))); return false; - } else { /* Something strange happened */ - logger(LOG_ERR, "Script %s terminated abnormally", name); + } else { /* Something strange happened */ + logger(DEBUG_ALWAYS, LOG_ERR, "Script %s terminated abnormally", name); return false; } } else { - logger(LOG_ERR, "System call `%s' failed: %s", "system", strerror(errno)); + logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "system", strerror(errno)); return false; } #endif diff --git a/src/process.h b/src/process.h index ea7815e..0b296db 100644 --- a/src/process.h +++ b/src/process.h @@ -1,7 +1,7 @@ /* process.h -- header file for process.c Copyright (C) 1999-2005 Ivo Timmermans, - 2000-2006 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 @@ -33,4 +33,4 @@ extern bool kill_other(int); extern bool init_service(void); #endif -#endif /* __TINC_PROCESS_H__ */ +#endif /* __TINC_PROCESS_H__ */ diff --git a/src/protocol.c b/src/protocol.c index 63163a0..3c08d72 100644 --- a/src/protocol.c +++ b/src/protocol.c @@ -1,7 +1,7 @@ /* protocol.c -- handle the meta-protocol, basic functions Copyright (C) 1999-2005 Ivo Timmermans, - 2000-2009 Guus Sliepen + 2000-2012 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 @@ -34,7 +34,7 @@ bool experimental = false; /* Jumptable for the request handlers */ -static bool (*request_handlers[])(connection_t *, char *) = { +static bool (*request_handlers[])(connection_t *, const char *) = { id_h, metakey_h, challenge_h, chal_reply_h, ack_h, status_h, error_h, termreq_h, ping_h, pong_h, @@ -56,6 +56,9 @@ static char (*request_name[]) = { static splay_tree_t *past_request_tree; bool check_id(const char *id) { + if(!id || !*id) + return false; + for(; *id; id++) if(!isalnum(*id) && *id != '_') return false; @@ -80,85 +83,71 @@ bool send_request(connection_t *c, const char *format, ...) { va_end(args); if(len < 0 || len > MAXBUFSIZE - 1) { - logger(LOG_ERR, "Output buffer overflow while sending request to %s (%s)", + logger(DEBUG_ALWAYS, LOG_ERR, "Output buffer overflow while sending request to %s (%s)", c->name, c->hostname); return false; } - ifdebug(PROTOCOL) { - ifdebug(META) - logger(LOG_DEBUG, "Sending %s to %s (%s): %s", - request_name[atoi(request)], c->name, c->hostname, request); - else - logger(LOG_DEBUG, "Sending %s to %s (%s)", request_name[atoi(request)], - c->name, c->hostname); - } + logger(DEBUG_META, LOG_DEBUG, "Sending %s to %s (%s): %s", request_name[atoi(request)], c->name, c->hostname, request); request[len++] = '\n'; - if(c == broadcast) { + if(c == everyone) { broadcast_meta(NULL, request, len); return true; } else return send_meta(c, request, len); } -void forward_request(connection_t *from, char *request) { - /* Note: request is not zero terminated anymore after a call to this function! */ - ifdebug(PROTOCOL) { - ifdebug(META) - logger(LOG_DEBUG, "Forwarding %s from %s (%s): %s", - request_name[atoi(request)], from->name, from->hostname, request); - else - logger(LOG_DEBUG, "Forwarding %s from %s (%s)", - request_name[atoi(request)], from->name, from->hostname); - } +void forward_request(connection_t *from, const char *request) { + logger(DEBUG_META, LOG_DEBUG, "Forwarding %s from %s (%s): %s", request_name[atoi(request)], from->name, from->hostname, request); + // Create a temporary newline-terminated copy of the request int len = strlen(request); - request[len++] = '\n'; - broadcast_meta(from, request, len); + char tmp[len + 1]; + memcpy(tmp, request, len); + tmp[len] = '\n'; + broadcast_meta(from, tmp, sizeof tmp); } -bool receive_request(connection_t *c, char *request) { +bool receive_request(connection_t *c, const char *request) { + if(proxytype == PROXY_HTTP && c->allow_request == ID) { + if(!request[0] || request[0] == '\r') + return true; + if(!strncasecmp(request, "HTTP/1.1 ", 9)) { + if(!strncmp(request + 9, "200", 3)) { + logger(DEBUG_CONNECTIONS, LOG_DEBUG, "Proxy request granted"); + return true; + } else { + logger(DEBUG_ALWAYS, LOG_DEBUG, "Proxy request rejected: %s", request + 9); + return false; + } + } + } + int reqno = atoi(request); if(reqno || *request == '0') { if((reqno < 0) || (reqno >= LAST) || !request_handlers[reqno]) { - ifdebug(META) - logger(LOG_DEBUG, "Unknown request from %s (%s): %s", - c->name, c->hostname, request); - else - logger(LOG_ERR, "Unknown request from %s (%s)", - c->name, c->hostname); - + logger(DEBUG_META, LOG_DEBUG, "Unknown request from %s (%s): %s", c->name, c->hostname, request); return false; } else { - ifdebug(PROTOCOL) { - ifdebug(META) - logger(LOG_DEBUG, "Got %s from %s (%s): %s", - request_name[reqno], c->name, c->hostname, request); - else - logger(LOG_DEBUG, "Got %s from %s (%s)", - request_name[reqno], c->name, c->hostname); - } + logger(DEBUG_META, LOG_DEBUG, "Got %s from %s (%s): %s", request_name[reqno], c->name, c->hostname, request); } if((c->allow_request != ALL) && (c->allow_request != reqno)) { - logger(LOG_ERR, "Unauthorized request from %s (%s)", c->name, - c->hostname); + logger(DEBUG_ALWAYS, LOG_ERR, "Unauthorized request from %s (%s)", c->name, c->hostname); return false; } if(!request_handlers[reqno](c, request)) { /* Something went wrong. Probably scriptkiddies. Terminate. */ - logger(LOG_ERR, "Error while processing %s from %s (%s)", - request_name[reqno], c->name, c->hostname); + logger(DEBUG_ALWAYS, LOG_ERR, "Error while processing %s from %s (%s)", request_name[reqno], c->name, c->hostname); return false; } } else { - logger(LOG_ERR, "Bogus data received from %s (%s)", - c->name, c->hostname); + logger(DEBUG_ALWAYS, LOG_ERR, "Bogus data received from %s (%s)", c->name, c->hostname); return false; } @@ -171,20 +160,20 @@ static int past_request_compare(const past_request_t *a, const past_request_t *b static void free_past_request(past_request_t *r) { if(r->request) - free(r->request); + free((char *)r->request); free(r); } static struct event past_request_event; -bool seen_request(char *request) { +bool seen_request(const char *request) { past_request_t *new, p = {NULL}; p.request = request; if(splay_search(past_request_tree, &p)) { - ifdebug(SCARY_THINGS) logger(LOG_DEBUG, "Already seen request"); + logger(DEBUG_SCARY_THINGS, LOG_DEBUG, "Already seen request"); return true; } else { new = xmalloc(sizeof *new); @@ -197,15 +186,10 @@ bool seen_request(char *request) { } static void age_past_requests(int fd, short events, void *data) { - splay_node_t *node, *next; - past_request_t *p; int left = 0, deleted = 0; time_t now = time(NULL); - for(node = past_request_tree->head; node; node = next) { - next = node->next; - p = node->data; - + for splay_each(past_request_t, p, past_request_tree) { if(p->firstseen + pinginterval <= now) splay_delete_node(past_request_tree, node), deleted++; else @@ -213,7 +197,7 @@ static void age_past_requests(int fd, short events, void *data) { } if(left || deleted) - ifdebug(SCARY_THINGS) logger(LOG_DEBUG, "Aging past requests: deleted %d, left %d", + logger(DEBUG_SCARY_THINGS, LOG_DEBUG, "Aging past requests: deleted %d, left %d", deleted, left); if(left) diff --git a/src/protocol.h b/src/protocol.h index 2c97641..1df54fc 100644 --- a/src/protocol.h +++ b/src/protocol.h @@ -1,7 +1,7 @@ /* protocol.h -- header for protocol.c Copyright (C) 1999-2005 Ivo Timmermans, - 2000-2009 Guus Sliepen + 2000-2012 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 @@ -24,7 +24,7 @@ /* Protocol version. Different major versions are incompatible. */ #define PROT_MAJOR 17 -#define PROT_MINOR 2 +#define PROT_MINOR 2 /* Should not exceed 255! */ /* Silly Windows */ @@ -35,7 +35,7 @@ /* Request numbers */ typedef enum request_t { - ALL = -1, /* Guardian for allow_request */ + ALL = -1, /* Guardian for allow_request */ ID = 0, METAKEY, CHALLENGE, CHAL_REPLY, ACK, STATUS, ERROR, TERMREQ, PING, PONG, @@ -43,12 +43,15 @@ typedef enum request_t { ADD_EDGE, DEL_EDGE, KEY_CHANGED, REQ_KEY, ANS_KEY, PACKET, + /* Tinc 1.1 requests */ CONTROL, - LAST /* Guardian for the highest request number */ + REQ_PUBKEY, ANS_PUBKEY, + REQ_SPTPS, + LAST /* Guardian for the highest request number */ } request_t; typedef struct past_request_t { - char *request; + const char *request; time_t firstseen; } past_request_t; @@ -72,13 +75,13 @@ extern bool experimental; /* Basic functions */ extern bool send_request(struct connection_t *, const char *, ...) __attribute__ ((__format__(printf, 2, 3))); -extern void forward_request(struct connection_t *, char *); -extern bool receive_request(struct connection_t *, char *); +extern void forward_request(struct connection_t *, const char *); +extern bool receive_request(struct connection_t *, const char *); extern bool check_id(const char *); extern void init_requests(void); extern void exit_requests(void); -extern bool seen_request(char *); +extern bool seen_request(const char *); /* Requests */ @@ -89,7 +92,7 @@ extern bool send_challenge(struct connection_t *); extern bool send_chal_reply(struct connection_t *); extern bool send_ack(struct connection_t *); extern bool send_status(struct connection_t *, int, const char *); -extern bool send_error(struct connection_t *, int,const char *); +extern bool send_error(struct connection_t *, int, const char *); extern bool send_termreq(struct connection_t *); extern bool send_ping(struct connection_t *); extern bool send_pong(struct connection_t *); @@ -104,24 +107,24 @@ extern bool send_tcppacket(struct connection_t *, const struct vpn_packet_t *); /* Request handlers */ -extern bool id_h(struct connection_t *, char *); -extern bool metakey_h(struct connection_t *, char *); -extern bool challenge_h(struct connection_t *, char *); -extern bool chal_reply_h(struct connection_t *, char *); -extern bool ack_h(struct connection_t *, char *); -extern bool status_h(struct connection_t *, char *); -extern bool error_h(struct connection_t *, char *); -extern bool termreq_h(struct connection_t *, char *); -extern bool ping_h(struct connection_t *, char *); -extern bool pong_h(struct connection_t *, char *); -extern bool add_subnet_h(struct connection_t *, char *); -extern bool del_subnet_h(struct connection_t *, char *); -extern bool add_edge_h(struct connection_t *, char *); -extern bool del_edge_h(struct connection_t *, char *); -extern bool key_changed_h(struct connection_t *, char *); -extern bool req_key_h(struct connection_t *, char *); -extern bool ans_key_h(struct connection_t *, char *); -extern bool tcppacket_h(struct connection_t *, char *); -extern bool control_h(struct connection_t *, char *); +extern bool id_h(struct connection_t *, const char *); +extern bool metakey_h(struct connection_t *, const char *); +extern bool challenge_h(struct connection_t *, const char *); +extern bool chal_reply_h(struct connection_t *, const char *); +extern bool ack_h(struct connection_t *, const char *); +extern bool status_h(struct connection_t *, const char *); +extern bool error_h(struct connection_t *, const char *); +extern bool termreq_h(struct connection_t *, const char *); +extern bool ping_h(struct connection_t *, const char *); +extern bool pong_h(struct connection_t *, const char *); +extern bool add_subnet_h(struct connection_t *, const char *); +extern bool del_subnet_h(struct connection_t *, const char *); +extern bool add_edge_h(struct connection_t *, const char *); +extern bool del_edge_h(struct connection_t *, const char *); +extern bool key_changed_h(struct connection_t *, const char *); +extern bool req_key_h(struct connection_t *, const char *); +extern bool ans_key_h(struct connection_t *, const char *); +extern bool tcppacket_h(struct connection_t *, const char *); +extern bool control_h(struct connection_t *, const char *); -#endif /* __TINC_PROTOCOL_H__ */ +#endif /* __TINC_PROTOCOL_H__ */ diff --git a/src/protocol_auth.c b/src/protocol_auth.c index 4331e94..1b061b3 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-2010 Guus Sliepen + 2000-2012 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 @@ -20,7 +20,6 @@ #include "system.h" -#include "splay_tree.h" #include "conf.h" #include "connection.h" #include "control.h" @@ -31,15 +30,103 @@ #include "edge.h" #include "graph.h" #include "logger.h" +#include "meta.h" #include "net.h" #include "netutl.h" #include "node.h" #include "prf.h" #include "protocol.h" #include "rsa.h" +#include "sptps.h" #include "utils.h" #include "xalloc.h" +static bool send_proxyrequest(connection_t *c) { + switch(proxytype) { + case PROXY_HTTP: { + char *host; + char *port; + + sockaddr2str(&c->address, &host, &port); + send_request(c, "CONNECT %s:%s HTTP/1.1\r\n\r", host, port); + free(host); + free(port); + return true; + } + case PROXY_SOCKS4: { + if(c->address.sa.sa_family != AF_INET) { + logger(DEBUG_ALWAYS, LOG_ERR, "Cannot connect to an IPv6 host through a SOCKS 4 proxy!"); + return false; + } + char s4req[9 + (proxyuser ? strlen(proxyuser) : 0)]; + s4req[0] = 4; + s4req[1] = 1; + memcpy(s4req + 2, &c->address.in.sin_port, 2); + memcpy(s4req + 4, &c->address.in.sin_addr, 4); + if(proxyuser) + memcpy(s4req + 8, proxyuser, strlen(proxyuser)); + s4req[sizeof s4req - 1] = 0; + c->tcplen = 8; + return send_meta(c, s4req, sizeof s4req); + } + case PROXY_SOCKS5: { + int len = 3 + 6 + (c->address.sa.sa_family == AF_INET ? 4 : 16); + c->tcplen = 2; + if(proxypass) + len += 3 + strlen(proxyuser) + strlen(proxypass); + char s5req[len]; + int i = 0; + s5req[i++] = 5; + s5req[i++] = 1; + if(proxypass) { + s5req[i++] = 2; + s5req[i++] = 1; + s5req[i++] = strlen(proxyuser); + memcpy(s5req + i, proxyuser, strlen(proxyuser)); + i += strlen(proxyuser); + s5req[i++] = strlen(proxypass); + memcpy(s5req + i, proxypass, strlen(proxypass)); + i += strlen(proxypass); + c->tcplen += 2; + } else { + s5req[i++] = 0; + } + s5req[i++] = 5; + s5req[i++] = 1; + s5req[i++] = 0; + if(c->address.sa.sa_family == AF_INET) { + s5req[i++] = 1; + memcpy(s5req + i, &c->address.in.sin_addr, 4); + i += 4; + memcpy(s5req + i, &c->address.in.sin_port, 2); + i += 2; + c->tcplen += 10; + } else if(c->address.sa.sa_family == AF_INET6) { + s5req[i++] = 3; + memcpy(s5req + i, &c->address.in6.sin6_addr, 16); + i += 16; + memcpy(s5req + i, &c->address.in6.sin6_port, 2); + i += 2; + c->tcplen += 22; + } else { + logger(DEBUG_ALWAYS, LOG_ERR, "Address family %hx not supported for SOCKS 5 proxies!", c->address.sa.sa_family); + return false; + } + if(i > len) + abort(); + return send_meta(c, s5req, sizeof s5req); + } + case PROXY_SOCKS4A: + logger(DEBUG_ALWAYS, LOG_ERR, "Proxy type not implemented yet"); + return false; + case PROXY_EXEC: + return true; + default: + logger(DEBUG_ALWAYS, LOG_ERR, "Unknown proxy type"); + return false; + } +} + bool send_id(connection_t *c) { gettimeofday(&c->start, NULL); @@ -52,14 +139,18 @@ bool send_id(connection_t *c) { minor = myself->connection->protocol_minor; } + if(proxytype) + if(!send_proxyrequest(c)) + return false; + return send_request(c, "%d %s %d.%d", ID, myself->connection->name, myself->connection->protocol_major, minor); } -bool id_h(connection_t *c, char *request) { +bool id_h(connection_t *c, const char *request) { char name[MAX_STRING_SIZE]; if(sscanf(request, "%*d " MAX_STRING " %d.%d", name, &c->protocol_major, &c->protocol_minor) < 2) { - logger(LOG_ERR, "Got bad %s from %s (%s)", "ID", c->name, + logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "ID", c->name, c->hostname); return false; } @@ -70,13 +161,17 @@ bool id_h(connection_t *c, char *request) { c->status.control = true; c->allow_request = CONTROL; c->last_ping_time = time(NULL) + 3600; + + free(c->name); + c->name = xstrdup(""); + return send_request(c, "%d %d %d", ACK, TINC_CTL_VERSION_CURRENT, getpid()); } /* Check if identity is a valid name */ if(!check_id(name)) { - logger(LOG_ERR, "Got bad %s from %s (%s): %s", "ID", c->name, + logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s): %s", "ID", c->name, c->hostname, "invalid name"); return false; } @@ -85,7 +180,7 @@ bool id_h(connection_t *c, char *request) { if(c->outgoing) { if(strcmp(c->name, name)) { - logger(LOG_ERR, "Peer %s is %s instead of %s", c->hostname, name, + logger(DEBUG_ALWAYS, LOG_ERR, "Peer %s is %s instead of %s", c->hostname, name, c->name); return false; } @@ -98,7 +193,7 @@ bool id_h(connection_t *c, char *request) { /* Check if version matches */ if(c->protocol_major != myself->connection->protocol_major) { - logger(LOG_ERR, "Peer %s (%s) uses incompatible version %d.%d", + logger(DEBUG_ALWAYS, LOG_ERR, "Peer %s (%s) uses incompatible version %d.%d", c->name, c->hostname, c->protocol_major, c->protocol_minor); return false; } @@ -110,52 +205,41 @@ bool id_h(connection_t *c, char *request) { return send_ack(c); } - if(!c->config_tree) { - init_configuration(&c->config_tree); - - if(!read_connection_config(c)) { - logger(LOG_ERR, "Peer %s had unknown identity (%s)", c->hostname, - c->name); - return false; - } - - if(experimental && c->protocol_minor >= 2) - if(!read_ecdsa_public_key(c)) - return false; - } else { - if(!ecdsa_active(&c->ecdsa)) - c->protocol_minor = 1; - } - if(!experimental) c->protocol_minor = 0; + if(!c->config_tree) { + init_configuration(&c->config_tree); + + if(!read_host_config(c->config_tree, c->name)) { + logger(DEBUG_ALWAYS, LOG_ERR, "Peer %s had unknown identity (%s)", c->hostname, c->name); + return false; + } + + if(experimental && c->protocol_minor >= 2) { + if(!read_ecdsa_public_key(c)) + return false; + } + } else { + if(c->protocol_minor && !ecdsa_active(&c->ecdsa)) + c->protocol_minor = 1; + } + c->allow_request = METAKEY; - if(c->protocol_minor >= 2) - return send_metakey_ec(c); - else + if(c->protocol_minor >= 2) { + c->allow_request = ACK; + char label[25 + strlen(myself->name) + strlen(c->name)]; + + if(c->outgoing) + snprintf(label, sizeof label, "tinc TCP key expansion %s %s", myself->name, c->name); + else + snprintf(label, sizeof label, "tinc TCP key expansion %s %s", c->name, myself->name); + + return sptps_start(&c->sptps, c, c->outgoing, false, myself->connection->ecdsa, c->ecdsa, label, sizeof label, send_meta_sptps, receive_meta_sptps); + } else { return send_metakey(c); -} - -bool send_metakey_ec(connection_t *c) { - logger(LOG_DEBUG, "Sending ECDH metakey to %s", c->name); - - size_t siglen = ecdsa_size(&myself->connection->ecdsa); - - char key[(ECDH_SIZE + siglen) * 2 + 1]; - - // TODO: include nonce? Use relevant parts of SSH or TLS protocol - - if(!ecdh_generate_public(&c->ecdh, key)) - return false; - - if(!ecdsa_sign(&myself->connection->ecdsa, key, ECDH_SIZE, key + ECDH_SIZE)) - return false; - - b64encode(key, key, ECDH_SIZE + siglen); - - return send_request(c, "%d %s", METAKEY, key); + } } bool send_metakey(connection_t *c) { @@ -164,7 +248,7 @@ bool send_metakey(connection_t *c) { if(!cipher_open_blowfish_ofb(&c->outcipher)) return false; - + if(!digest_open_sha1(&c->outdigest, -1)) return false; @@ -191,9 +275,9 @@ bool send_metakey(connection_t *c) { cipher_set_key_from_rsa(&c->outcipher, key, len, true); - ifdebug(SCARY_THINGS) { + if(debug_level >= DEBUG_SCARY_THINGS) { bin2hex(key, hexkey, len); - logger(LOG_DEBUG, "Generated random meta key (unencrypted): %s", hexkey); + logger(DEBUG_SCARY_THINGS, LOG_DEBUG, "Generated random meta key (unencrypted): %s", hexkey); } /* Encrypt the random data @@ -204,7 +288,7 @@ bool send_metakey(connection_t *c) { */ if(!rsa_public_encrypt(&c->rsa, key, len, enckey)) { - logger(LOG_ERR, "Error during encryption of meta key for %s (%s)", c->name, c->hostname); + logger(DEBUG_ALWAYS, LOG_ERR, "Error during encryption of meta key for %s (%s)", c->name, c->hostname); return false; } @@ -218,90 +302,12 @@ bool send_metakey(connection_t *c) { cipher_get_nid(&c->outcipher), digest_get_nid(&c->outdigest), c->outmaclength, c->outcompression, hexkey); - + c->status.encryptout = true; return result; } -static bool metakey_ec_h(connection_t *c, const char *request) { - size_t siglen = ecdsa_size(&c->ecdsa); - char key[MAX_STRING_SIZE]; - char sig[siglen]; - - logger(LOG_DEBUG, "Got ECDH metakey from %s", c->name); - - if(sscanf(request, "%*d " MAX_STRING, key) != 1) { - logger(LOG_ERR, "Got bad %s from %s (%s)", "METAKEY", c->name, c->hostname); - return false; - } - - int inlen = b64decode(key, key, sizeof key); - - if(inlen != (ECDH_SIZE + siglen)) { - logger(LOG_ERR, "Possible intruder %s (%s): %s", c->name, c->hostname, "wrong keylength"); - return false; - } - - if(!ecdsa_verify(&c->ecdsa, key, ECDH_SIZE, key + ECDH_SIZE)) { - logger(LOG_ERR, "Possible intruder %s (%s): %s", c->name, c->hostname, "invalid ECDSA signature"); - return false; - } - - char shared[ECDH_SHARED_SIZE]; - - if(!ecdh_compute_shared(&c->ecdh, key, shared)) - return false; - - /* Update our crypto end */ - - if(!cipher_open_by_name(&c->incipher, "aes-256-ofb")) - return false; - if(!digest_open_by_name(&c->indigest, "sha512", -1)) - return false; - if(!cipher_open_by_name(&c->outcipher, "aes-256-ofb")) - return false; - if(!digest_open_by_name(&c->outdigest, "sha512", -1)) - return false; - - size_t mykeylen = cipher_keylength(&c->incipher); - size_t hiskeylen = cipher_keylength(&c->outcipher); - - char *mykey; - char *hiskey; - char *seed; - - if(strcmp(myself->name, c->name) < 0) { - mykey = key; - hiskey = key + mykeylen * 2; - xasprintf(&seed, "tinc TCP key expansion %s %s", myself->name, c->name); - } else { - mykey = key + hiskeylen * 2; - hiskey = key; - xasprintf(&seed, "tinc TCP key expansion %s %s", c->name, myself->name); - } - - if(!prf(shared, ECDH_SHARED_SIZE, seed, strlen(seed), key, hiskeylen * 2 + mykeylen * 2)) - return false; - - free(seed); - - cipher_set_key(&c->incipher, mykey, false); - digest_set_key(&c->indigest, mykey + mykeylen, mykeylen); - - cipher_set_key(&c->outcipher, hiskey, true); - digest_set_key(&c->outdigest, hiskey + hiskeylen, hiskeylen); - - c->status.decryptin = true; - c->status.encryptout = true; - c->allow_request = CHALLENGE; - - return send_challenge(c); -} - -bool metakey_h(connection_t *c, char *request) { - if(c->protocol_minor >= 2) - return metakey_ec_h(c, request); - +bool metakey_h(connection_t *c, const char *request) { char hexkey[MAX_STRING_SIZE]; int cipher, digest, maclength, compression; size_t len = rsa_size(&myself->connection->rsa); @@ -309,7 +315,7 @@ bool metakey_h(connection_t *c, char *request) { char key[len]; if(sscanf(request, "%*d %d %d %d %d " MAX_STRING, &cipher, &digest, &maclength, &compression, hexkey) != 5) { - logger(LOG_ERR, "Got bad %s from %s (%s)", "METAKEY", c->name, c->hostname); + logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "METAKEY", c->name, c->hostname); return false; } @@ -320,31 +326,31 @@ bool metakey_h(connection_t *c, char *request) { /* Check if the length of the meta key is all right */ if(inlen != len) { - logger(LOG_ERR, "Possible intruder %s (%s): %s", c->name, c->hostname, "wrong keylength"); + logger(DEBUG_ALWAYS, LOG_ERR, "Possible intruder %s (%s): %s", c->name, c->hostname, "wrong keylength"); return false; } /* Decrypt the meta key */ if(!rsa_private_decrypt(&myself->connection->rsa, enckey, len, key)) { - logger(LOG_ERR, "Error during decryption of meta key for %s (%s)", c->name, c->hostname); + logger(DEBUG_ALWAYS, LOG_ERR, "Error during decryption of meta key for %s (%s)", c->name, c->hostname); return false; } - ifdebug(SCARY_THINGS) { + if(debug_level >= DEBUG_SCARY_THINGS) { bin2hex(key, hexkey, len); - logger(LOG_DEBUG, "Received random meta key (unencrypted): %s", hexkey); + logger(DEBUG_SCARY_THINGS, LOG_DEBUG, "Received random meta key (unencrypted): %s", hexkey); } /* Check and lookup cipher and digest algorithms */ if(!cipher_open_by_nid(&c->incipher, cipher) || !cipher_set_key_from_rsa(&c->incipher, key, len, false)) { - logger(LOG_ERR, "Error during initialisation of cipher from %s (%s)", c->name, c->hostname); + logger(DEBUG_ALWAYS, LOG_ERR, "Error during initialisation of cipher from %s (%s)", c->name, c->hostname); return false; } if(!digest_open_by_nid(&c->indigest, digest, -1)) { - logger(LOG_ERR, "Error during initialisation of digest from %s (%s)", c->name, c->hostname); + logger(DEBUG_ALWAYS, LOG_ERR, "Error during initialisation of digest from %s (%s)", c->name, c->hostname); return false; } @@ -356,7 +362,7 @@ bool metakey_h(connection_t *c, char *request) { } bool send_challenge(connection_t *c) { - size_t len = c->protocol_minor >= 2 ? ECDH_SIZE : rsa_size(&c->rsa); + size_t len = rsa_size(&c->rsa); char buffer[len * 2 + 1]; if(!c->hischallenge) @@ -375,14 +381,14 @@ bool send_challenge(connection_t *c) { return send_request(c, "%d %s", CHALLENGE, buffer); } -bool challenge_h(connection_t *c, char *request) { +bool challenge_h(connection_t *c, const char *request) { char buffer[MAX_STRING_SIZE]; - size_t len = c->protocol_minor >= 2 ? ECDH_SIZE : rsa_size(&myself->connection->rsa); + size_t len = rsa_size(&myself->connection->rsa); size_t digestlen = digest_length(&c->indigest); char digest[digestlen]; if(sscanf(request, "%*d " MAX_STRING, buffer) != 1) { - logger(LOG_ERR, "Got bad %s from %s (%s)", "CHALLENGE", c->name, c->hostname); + logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "CHALLENGE", c->name, c->hostname); return false; } @@ -393,7 +399,7 @@ bool challenge_h(connection_t *c, char *request) { /* Check if the length of the challenge is all right */ if(inlen != len) { - logger(LOG_ERR, "Possible intruder %s (%s): %s", c->name, c->hostname, "wrong challenge length"); + logger(DEBUG_ALWAYS, LOG_ERR, "Possible intruder %s (%s): %s", c->name, c->hostname, "wrong challenge length"); return false; } @@ -412,11 +418,11 @@ bool challenge_h(connection_t *c, char *request) { return send_request(c, "%d %s", CHAL_REPLY, buffer); } -bool chal_reply_h(connection_t *c, char *request) { +bool chal_reply_h(connection_t *c, const char *request) { char hishash[MAX_STRING_SIZE]; if(sscanf(request, "%*d " MAX_STRING, hishash) != 1) { - logger(LOG_ERR, "Got bad %s from %s (%s)", "CHAL_REPLY", c->name, + logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "CHAL_REPLY", c->name, c->hostname); return false; } @@ -428,15 +434,15 @@ bool chal_reply_h(connection_t *c, char *request) { /* Check if the length of the hash is all right */ if(inlen != digest_length(&c->outdigest)) { - logger(LOG_ERR, "Possible intruder %s (%s): %s", c->name, c->hostname, "wrong challenge reply length"); + logger(DEBUG_ALWAYS, LOG_ERR, "Possible intruder %s (%s): %s", c->name, c->hostname, "wrong challenge reply length"); return false; } /* Verify the hash */ - if(!digest_verify(&c->outdigest, c->hischallenge, c->protocol_minor >= 2 ? ECDH_SIZE : rsa_size(&c->rsa), hishash)) { - logger(LOG_ERR, "Possible intruder %s (%s): %s", c->name, c->hostname, "wrong challenge reply"); + if(!digest_verify(&c->outdigest, c->hischallenge, rsa_size(&c->rsa), hishash)) { + logger(DEBUG_ALWAYS, LOG_ERR, "Possible intruder %s (%s): %s", c->name, c->hostname, "wrong challenge reply"); return false; } @@ -498,61 +504,48 @@ bool send_ack(connection_t *c) { 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); + return send_request(c, "%d %s %d %x", ACK, myport, c->estimated_weight, (c->options & 0xffffff) | (experimental ? (PROT_MINOR << 24) : 0)); } static void send_everything(connection_t *c) { - splay_node_t *node, *node2; - node_t *n; - subnet_t *s; - edge_t *e; - /* Send all known subnets and edges */ if(tunnelserver) { - for(node = myself->subnet_tree->head; node; node = node->next) { - s = node->data; + for splay_each(subnet_t, s, myself->subnet_tree) send_add_subnet(c, s); - } return; } - for(node = node_tree->head; node; node = node->next) { - n = node->data; - - for(node2 = n->subnet_tree->head; node2; node2 = node2->next) { - s = node2->data; + for splay_each(node_t, n, node_tree) { + for splay_each(subnet_t, s, n->subnet_tree) send_add_subnet(c, s); - } - for(node2 = n->edge_tree->head; node2; node2 = node2->next) { - e = node2->data; + for splay_each(edge_t, e, n->edge_tree) send_add_edge(c, e); - } } } -static bool upgrade_h(connection_t *c, char *request) { +static bool upgrade_h(connection_t *c, const char *request) { char pubkey[MAX_STRING_SIZE]; if(sscanf(request, "%*d " MAX_STRING, pubkey) != 1) { - logger(LOG_ERR, "Got bad %s from %s (%s)", "ACK", c->name, c->hostname); + logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "ACK", c->name, c->hostname); return false; } if(ecdsa_active(&c->ecdsa) || read_ecdsa_public_key(c)) { - logger(LOG_INFO, "Already have ECDSA public key from %s (%s), not upgrading.", c->name, c->hostname); + logger(DEBUG_ALWAYS, LOG_INFO, "Already have ECDSA public key from %s (%s), not upgrading.", c->name, c->hostname); return false; } - logger(LOG_INFO, "Got ECDSA public key from %s (%s), upgrading!", c->name, c->hostname); + logger(DEBUG_ALWAYS, LOG_INFO, "Got ECDSA public key from %s (%s), upgrading!", c->name, c->hostname); append_config_file(c->name, "ECDSAPublicKey", pubkey); c->allow_request = TERMREQ; return send_termreq(c); } -bool ack_h(connection_t *c, char *request) { +bool ack_h(connection_t *c, const char *request) { if(c->protocol_minor == 1) return upgrade_h(c, request); @@ -564,7 +557,7 @@ bool ack_h(connection_t *c, char *request) { bool choice; if(sscanf(request, "%*d " MAX_STRING " %d %x", hisport, &weight, &options) != 3) { - logger(LOG_ERR, "Got bad %s from %s (%s)", "ACK", c->name, + logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "ACK", c->name, c->hostname); return false; } @@ -580,11 +573,11 @@ bool ack_h(connection_t *c, char *request) { } else { if(n->connection) { /* Oh dear, we already have a connection to this node. */ - ifdebug(CONNECTIONS) logger(LOG_DEBUG, "Established a second connection with %s (%s), closing old connection", n->connection->name, n->connection->hostname); + logger(DEBUG_CONNECTIONS, LOG_DEBUG, "Established a second connection with %s (%s), closing old connection", n->connection->name, n->connection->hostname); if(n->connection->outgoing) { if(c->outgoing) - logger(LOG_WARNING, "Two outgoing connections to the same node!"); + logger(DEBUG_ALWAYS, LOG_WARNING, "Two outgoing connections to the same node!"); else c->outgoing = n->connection->outgoing; @@ -618,15 +611,12 @@ bool ack_h(connection_t *c, char *request) { c->options &= ~OPTION_CLAMP_MSS; } - if(c->protocol_minor > 0) - c->node->status.ecdh = true; - /* Activate this connection */ c->allow_request = ALL; c->status.active = true; - ifdebug(CONNECTIONS) logger(LOG_NOTICE, "Connection with %s (%s) activated", c->name, + logger(DEBUG_CONNECTIONS, LOG_NOTICE, "Connection with %s (%s) activated", c->name, c->hostname); /* Send him everything we know */ @@ -652,7 +642,7 @@ bool ack_h(connection_t *c, char *request) { if(tunnelserver) send_add_edge(c, c->edge); else - send_add_edge(broadcast, c->edge); + send_add_edge(everyone, c->edge); /* Run MST and SSSP algorithms */ diff --git a/src/protocol_edge.c b/src/protocol_edge.c index 1dd68d5..e285a6d 100644 --- a/src/protocol_edge.c +++ b/src/protocol_edge.c @@ -1,7 +1,7 @@ /* protocol_edge.c -- handle the meta-protocol, edges Copyright (C) 1999-2005 Ivo Timmermans, - 2000-2009 Guus Sliepen + 2000-2012 Guus Sliepen 2009 Michael Tokarev This program is free software; you can redistribute it and/or modify @@ -21,7 +21,6 @@ #include "system.h" -#include "splay_tree.h" #include "conf.h" #include "connection.h" #include "edge.h" @@ -50,7 +49,7 @@ bool send_add_edge(connection_t *c, const edge_t *e) { return x; } -bool add_edge_h(connection_t *c, char *request) { +bool add_edge_h(connection_t *c, const char *request) { edge_t *e; node_t *from, *to; char from_name[MAX_STRING_SIZE]; @@ -63,7 +62,7 @@ bool add_edge_h(connection_t *c, char *request) { if(sscanf(request, "%*d %*x "MAX_STRING" "MAX_STRING" "MAX_STRING" "MAX_STRING" %x %d", from_name, to_name, to_address, to_port, &options, &weight) != 6) { - logger(LOG_ERR, "Got bad %s from %s (%s)", "ADD_EDGE", c->name, + logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "ADD_EDGE", c->name, c->hostname); return false; } @@ -71,7 +70,7 @@ bool add_edge_h(connection_t *c, char *request) { /* Check if names are valid */ if(!check_id(from_name) || !check_id(to_name)) { - logger(LOG_ERR, "Got bad %s from %s (%s): %s", "ADD_EDGE", c->name, + logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s): %s", "ADD_EDGE", c->name, c->hostname, "invalid name"); return false; } @@ -88,7 +87,7 @@ bool add_edge_h(connection_t *c, char *request) { from != myself && from != c->node && to != myself && to != c->node) { /* ignore indirect edge registrations for tunnelserver */ - ifdebug(PROTOCOL) logger(LOG_WARNING, + logger(DEBUG_PROTOCOL, LOG_WARNING, "Ignoring indirect %s from %s (%s)", "ADD_EDGE", c->name, c->hostname); return true; @@ -118,12 +117,12 @@ bool add_edge_h(connection_t *c, char *request) { if(e) { if(e->weight != weight || e->options != options || sockaddrcmp(&e->address, &address)) { if(from == myself) { - ifdebug(PROTOCOL) logger(LOG_WARNING, "Got %s from %s (%s) for ourself which does not match existing entry", + logger(DEBUG_PROTOCOL, LOG_WARNING, "Got %s from %s (%s) for ourself which does not match existing entry", "ADD_EDGE", c->name, c->hostname); send_add_edge(c, e); return true; } else { - ifdebug(PROTOCOL) logger(LOG_WARNING, "Got %s from %s (%s) which does not match existing entry", + logger(DEBUG_PROTOCOL, LOG_WARNING, "Got %s from %s (%s) which does not match existing entry", "ADD_EDGE", c->name, c->hostname); edge_del(e); graph(); @@ -131,7 +130,7 @@ bool add_edge_h(connection_t *c, char *request) { } else return true; } else if(from == myself) { - ifdebug(PROTOCOL) logger(LOG_WARNING, "Got %s from %s (%s) for ourself which does not exist", + logger(DEBUG_PROTOCOL, LOG_WARNING, "Got %s from %s (%s) for ourself which does not exist", "ADD_EDGE", c->name, c->hostname); contradicting_add_edge++; e = new_edge(); @@ -167,14 +166,14 @@ bool send_del_edge(connection_t *c, const edge_t *e) { e->from->name, e->to->name); } -bool del_edge_h(connection_t *c, char *request) { +bool del_edge_h(connection_t *c, const char *request) { edge_t *e; char from_name[MAX_STRING_SIZE]; char to_name[MAX_STRING_SIZE]; node_t *from, *to; if(sscanf(request, "%*d %*x "MAX_STRING" "MAX_STRING, from_name, to_name) != 2) { - logger(LOG_ERR, "Got bad %s from %s (%s)", "DEL_EDGE", c->name, + logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "DEL_EDGE", c->name, c->hostname); return false; } @@ -182,7 +181,7 @@ bool del_edge_h(connection_t *c, char *request) { /* Check if names are valid */ if(!check_id(from_name) || !check_id(to_name)) { - logger(LOG_ERR, "Got bad %s from %s (%s): %s", "DEL_EDGE", c->name, + logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s): %s", "DEL_EDGE", c->name, c->hostname, "invalid name"); return false; } @@ -199,20 +198,20 @@ bool del_edge_h(connection_t *c, char *request) { from != myself && from != c->node && to != myself && to != c->node) { /* ignore indirect edge registrations for tunnelserver */ - ifdebug(PROTOCOL) logger(LOG_WARNING, + logger(DEBUG_PROTOCOL, LOG_WARNING, "Ignoring indirect %s from %s (%s)", "DEL_EDGE", c->name, c->hostname); return true; } if(!from) { - ifdebug(PROTOCOL) logger(LOG_ERR, "Got %s from %s (%s) which does not appear in the edge tree", + logger(DEBUG_PROTOCOL, LOG_ERR, "Got %s from %s (%s) which does not appear in the edge tree", "DEL_EDGE", c->name, c->hostname); return true; } if(!to) { - ifdebug(PROTOCOL) logger(LOG_ERR, "Got %s from %s (%s) which does not appear in the edge tree", + logger(DEBUG_PROTOCOL, LOG_ERR, "Got %s from %s (%s) which does not appear in the edge tree", "DEL_EDGE", c->name, c->hostname); return true; } @@ -222,16 +221,16 @@ bool del_edge_h(connection_t *c, char *request) { e = lookup_edge(from, to); if(!e) { - ifdebug(PROTOCOL) logger(LOG_WARNING, "Got %s from %s (%s) which does not appear in the edge tree", + logger(DEBUG_PROTOCOL, LOG_WARNING, "Got %s from %s (%s) which does not appear in the edge tree", "DEL_EDGE", c->name, c->hostname); return true; } if(e->from == myself) { - ifdebug(PROTOCOL) logger(LOG_WARNING, "Got %s from %s (%s) for ourself", + logger(DEBUG_PROTOCOL, LOG_WARNING, "Got %s from %s (%s) for ourself", "DEL_EDGE", c->name, c->hostname); contradicting_del_edge++; - send_add_edge(c, e); /* Send back a correction */ + send_add_edge(c, e); /* Send back a correction */ return true; } @@ -254,7 +253,7 @@ bool del_edge_h(connection_t *c, char *request) { e = lookup_edge(to, myself); if(e) { if(!tunnelserver) - send_del_edge(broadcast, e); + send_del_edge(everyone, e); edge_del(e); } } diff --git a/src/protocol_key.c b/src/protocol_key.c index 5246e7d..b54df3c 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-2011 Guus Sliepen + 2000-2012 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 @@ -20,43 +20,45 @@ #include "system.h" -#include "splay_tree.h" #include "cipher.h" #include "connection.h" #include "crypto.h" -#include "ecdh.h" #include "logger.h" #include "net.h" #include "netutl.h" #include "node.h" #include "prf.h" #include "protocol.h" +#include "sptps.h" #include "utils.h" #include "xalloc.h" static bool mykeyused = false; void send_key_changed(void) { - splay_node_t *node; - connection_t *c; - - send_request(broadcast, "%d %x %s", KEY_CHANGED, rand(), myself->name); + send_request(everyone, "%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) + for list_each(connection_t, c, connection_list) + if(c->status.active && c->node && c->node->status.reachable && !c->node->status.sptps) send_ans_key(c->node); + + /* Force key exchange for connections using SPTPS */ + + if(experimental) { + for splay_each(node_t, n, node_tree) + if(n->status.reachable && n->status.validkey && n->status.sptps) + sptps_force_kex(&n->sptps); } } -bool key_changed_h(connection_t *c, char *request) { +bool key_changed_h(connection_t *c, const char *request) { char name[MAX_STRING_SIZE]; node_t *n; if(sscanf(request, "%*d %*x " MAX_STRING, name) != 1) { - logger(LOG_ERR, "Got bad %s from %s (%s)", "KEY_CHANGED", + logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "KEY_CHANGED", c->name, c->hostname); return false; } @@ -67,13 +69,15 @@ bool key_changed_h(connection_t *c, char *request) { n = lookup_node(name); if(!n) { - logger(LOG_ERR, "Got %s from %s (%s) origin %s which does not exist", + logger(DEBUG_ALWAYS, LOG_ERR, "Got %s from %s (%s) origin %s which does not exist", "KEY_CHANGED", c->name, c->hostname, name); return true; } - n->status.validkey = false; - n->last_req_key = 0; + if(!n->status.sptps) { + n->status.validkey = false; + n->last_req_key = 0; + } /* Tell the others */ @@ -83,31 +87,137 @@ bool key_changed_h(connection_t *c, char *request) { return true; } -bool send_req_key(node_t *to) { - return send_request(to->nexthop->connection, "%d %s %s %d", REQ_KEY, myself->name, to->name, experimental ? 1 : 0); +static bool send_initial_sptps_data(void *handle, uint8_t type, const char *data, size_t len) { + node_t *to = handle; + to->sptps.send_data = send_sptps_data; + char buf[len * 4 / 3 + 5]; + b64encode(data, buf, len); + return send_request(to->nexthop->connection, "%d %s %s %d %s", REQ_KEY, myself->name, to->name, REQ_KEY, buf); } -bool req_key_h(connection_t *c, char *request) { +bool send_req_key(node_t *to) { + if(to->status.sptps) { + if(!node_read_ecdsa_public_key(to)) { + logger(DEBUG_PROTOCOL, LOG_DEBUG, "No ECDSA key known for %s (%s)", to->name, to->hostname); + send_request(to->nexthop->connection, "%d %s %s %d", REQ_KEY, myself->name, to->name, REQ_PUBKEY); + return true; + } + + if(to->sptps.label) + logger(DEBUG_ALWAYS, LOG_DEBUG, "send_req_key(%s) called while sptps->label != NULL!", to->name); + + char label[25 + strlen(myself->name) + strlen(to->name)]; + snprintf(label, sizeof label, "tinc UDP key expansion %s %s", myself->name, to->name); + sptps_stop(&to->sptps); + to->status.validkey = false; + to->status.waitingforkey = true; + to->last_req_key = time(NULL); + to->incompression = myself->incompression; + return sptps_start(&to->sptps, to, true, true, myself->connection->ecdsa, to->ecdsa, label, sizeof label, send_initial_sptps_data, receive_sptps_record); + } + + return send_request(to->nexthop->connection, "%d %s %s", REQ_KEY, myself->name, to->name); +} + +/* REQ_KEY is overloaded to allow arbitrary requests to be routed between two nodes. */ + +static bool req_key_ext_h(connection_t *c, const char *request, node_t *from, int reqno) { + switch(reqno) { + case REQ_PUBKEY: { + char *pubkey = ecdsa_get_base64_public_key(&myself->connection->ecdsa); + send_request(from->nexthop->connection, "%d %s %s %d %s", REQ_KEY, myself->name, from->name, ANS_PUBKEY, pubkey); + free(pubkey); + return true; + } + + case ANS_PUBKEY: { + if(node_read_ecdsa_public_key(from)) { + logger(DEBUG_PROTOCOL, LOG_WARNING, "Got ANS_PUBKEY from %s (%s) even though we already have his pubkey", from->name, from->hostname); + return true; + } + + char pubkey[MAX_STRING_SIZE]; + if(sscanf(request, "%*d %*s %*s %*d " MAX_STRING, pubkey) != 1 || !ecdsa_set_base64_public_key(&from->ecdsa, pubkey)) { + logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s): %s", "ANS_PUBKEY", from->name, from->hostname, "invalid pubkey"); + return true; + } + + logger(DEBUG_PROTOCOL, LOG_INFO, "Learned ECDSA public key from %s (%s)", from->name, from->hostname); + append_config_file(from->name, "ECDSAPublicKey", pubkey); + return true; + } + + case REQ_KEY: { + if(!node_read_ecdsa_public_key(from)) { + logger(DEBUG_PROTOCOL, LOG_DEBUG, "No ECDSA key known for %s (%s)", from->name, from->hostname); + send_request(from->nexthop->connection, "%d %s %s %d", REQ_KEY, myself->name, from->name, REQ_PUBKEY); + return true; + } + + if(from->sptps.label) + logger(DEBUG_ALWAYS, LOG_DEBUG, "Got REQ_KEY from %s while we already started a SPTPS session!", from->name); + + char buf[MAX_STRING_SIZE]; + if(sscanf(request, "%*d %*s %*s %*d " MAX_STRING, buf) != 1) { + logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s): %s", "REQ_SPTPS_START", from->name, from->hostname, "invalid SPTPS data"); + return true; + } + int len = b64decode(buf, buf, strlen(buf)); + + char label[25 + strlen(from->name) + strlen(myself->name)]; + snprintf(label, sizeof label, "tinc UDP key expansion %s %s", from->name, myself->name); + sptps_stop(&from->sptps); + from->status.validkey = false; + from->status.waitingforkey = true; + from->last_req_key = time(NULL); + sptps_start(&from->sptps, from, false, true, myself->connection->ecdsa, from->ecdsa, label, sizeof label, send_sptps_data, receive_sptps_record); + sptps_receive_data(&from->sptps, buf, len); + return true; + } + + case REQ_SPTPS: { + if(!from->status.validkey) { + logger(DEBUG_PROTOCOL, LOG_ERR, "Got REQ_SPTPS from %s (%s) but we don't have a valid key yet", from->name, from->hostname); + return true; + } + + char buf[MAX_STRING_SIZE]; + if(sscanf(request, "%*d %*s %*s %*d " MAX_STRING, buf) != 1) { + logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s): %s", "REQ_SPTPS", from->name, from->hostname, "invalid SPTPS data"); + return true; + } + int len = b64decode(buf, buf, strlen(buf)); + sptps_receive_data(&from->sptps, buf, len); + return true; + } + + default: + logger(DEBUG_ALWAYS, LOG_ERR, "Unknown extended REQ_KEY request from %s (%s): %s", from->name, from->hostname, request); + return true; + } +} + +bool req_key_h(connection_t *c, const char *request) { char from_name[MAX_STRING_SIZE]; char to_name[MAX_STRING_SIZE]; node_t *from, *to; - int kx_version = 0; + int reqno = 0; - if(sscanf(request, "%*d " MAX_STRING " " MAX_STRING " %d", from_name, to_name, &kx_version) < 2) { - logger(LOG_ERR, "Got bad %s from %s (%s)", "REQ_KEY", c->name, + if(sscanf(request, "%*d " MAX_STRING " " MAX_STRING " %d", from_name, to_name, &reqno) < 2) { + logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "REQ_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", "REQ_KEY", c->name, c->hostname, "invalid name"); + logger(DEBUG_ALWAYS, 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", + logger(DEBUG_ALWAYS, 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 true; } @@ -115,25 +225,26 @@ bool req_key_h(connection_t *c, char *request) { to = lookup_node(to_name); if(!to) { - logger(LOG_ERR, "Got %s from %s (%s) destination %s which does not exist in our connection list", + logger(DEBUG_ALWAYS, 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 true; } /* Check if this key request is for us */ - if(to == myself) { /* Yes, send our own key back */ - if(experimental && kx_version >= 1) { - logger(LOG_DEBUG, "Got ECDH key request from %s", from->name); - from->status.ecdh = true; - } + if(to == myself) { /* Yes */ + /* Is this an extended REQ_KEY message? */ + if(experimental && reqno) + return req_key_ext_h(c, request, from, reqno); + + /* No, just send our key back */ send_ans_key(from); } else { if(tunnelserver) return true; if(!to->status.reachable) { - logger(LOG_WARNING, "Got %s from %s (%s) destination %s which is not reachable", + logger(DEBUG_PROTOCOL, LOG_WARNING, "Got %s from %s (%s) destination %s which is not reachable", "REQ_KEY", c->name, c->hostname, to_name); return true; } @@ -144,41 +255,16 @@ bool req_key_h(connection_t *c, char *request) { return true; } -bool send_ans_key_ecdh(node_t *to) { - int siglen = ecdsa_size(&myself->connection->ecdsa); - char key[(ECDH_SIZE + siglen) * 2 + 1]; - - if(!ecdh_generate_public(&to->ecdh, key)) - return false; - - if(!ecdsa_sign(&myself->connection->ecdsa, key, ECDH_SIZE, key + ECDH_SIZE)) - return false; - - b64encode(key, key, ECDH_SIZE + siglen); - - char *pubkey = ecdsa_get_base64_public_key(&myself->connection->ecdsa); - - if(!pubkey) - return false; - - int result = send_request(to->nexthop->connection, "%d %s %s ECDH:%s:%s %d %d %zu %d", ANS_KEY, - myself->name, to->name, key, pubkey, - cipher_get_nid(&myself->incipher), - digest_get_nid(&myself->indigest), - digest_length(&myself->indigest), - myself->incompression); - - free(pubkey); - return result; -} - bool send_ans_key(node_t *to) { - if(experimental && to->status.ecdh) - return send_ans_key_ecdh(to); + if(to->status.sptps) + abort(); size_t keylen = cipher_keylength(&myself->incipher); char key[keylen * 2 + 1]; + cipher_close(&to->incipher); + digest_close(&to->indigest); + cipher_open_by_nid(&to->incipher, cipher_get_nid(&myself->incipher)); digest_open_by_nid(&to->indigest, digest_get_nid(&myself->indigest), digest_length(&myself->indigest)); to->incompression = myself->incompression; @@ -194,40 +280,40 @@ bool send_ans_key(node_t *to) { to->received_seqno = 0; if(replaywin) memset(to->late, 0, replaywin); - return send_request(to->nexthop->connection, "%d %s %s %s %d %d %zu %d", ANS_KEY, + return send_request(to->nexthop->connection, "%d %s %s %s %d %d %d %d", ANS_KEY, myself->name, to->name, key, cipher_get_nid(&to->incipher), digest_get_nid(&to->indigest), - digest_length(&to->indigest), + (int)digest_length(&to->indigest), to->incompression); } -bool ans_key_h(connection_t *c, char *request) { +bool ans_key_h(connection_t *c, const char *request) { 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] = ""; + char address[MAX_STRING_SIZE] = ""; + char port[MAX_STRING_SIZE] = ""; int cipher, digest, maclength, compression, keylen; node_t *from, *to; if(sscanf(request, "%*d "MAX_STRING" "MAX_STRING" "MAX_STRING" %d %d %d %d "MAX_STRING" "MAX_STRING, from_name, to_name, key, &cipher, &digest, &maclength, &compression, address, port) < 7) { - logger(LOG_ERR, "Got bad %s from %s (%s)", "ANS_KEY", c->name, + logger(DEBUG_ALWAYS, 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"); + logger(DEBUG_ALWAYS, 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", + logger(DEBUG_ALWAYS, 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 true; } @@ -235,7 +321,7 @@ bool ans_key_h(connection_t *c, char *request) { to = lookup_node(to_name); if(!to) { - logger(LOG_ERR, "Got %s from %s (%s) destination %s which does not exist in our connection list", + logger(DEBUG_ALWAYS, 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 true; } @@ -247,14 +333,14 @@ bool ans_key_h(connection_t *c, char *request) { return true; if(!to->status.reachable) { - logger(LOG_WARNING, "Got %s from %s (%s) destination %s which is not reachable", + logger(DEBUG_ALWAYS, LOG_WARNING, "Got %s from %s (%s) destination %s which is not reachable", "ANS_KEY", c->name, c->hostname, to_name); return true; } if(!*address && from->address.sa.sa_family != AF_UNSPEC) { char *address, *port; - ifdebug(PROTOCOL) logger(LOG_DEBUG, "Appending reflexive UDP address to ANS_KEY from %s to %s", from->name, to->name); + logger(DEBUG_PROTOCOL, 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", request, address, port); free(address); @@ -265,142 +351,77 @@ bool ans_key_h(connection_t *c, char *request) { return send_request(to->nexthop->connection, "%s", request); } - /* Check and lookup cipher and digest algorithms */ - - if(!cipher_open_by_nid(&from->outcipher, cipher)) { - logger(LOG_ERR, "Node %s (%s) uses unknown cipher!", from->name, from->hostname); - return false; - } - - if(!digest_open_by_nid(&from->outdigest, digest, maclength)) { - logger(LOG_ERR, "Node %s (%s) uses unknown digest!", from->name, from->hostname); - return false; - } - - if(maclength != digest_length(&from->outdigest)) { - logger(LOG_ERR, "Node %s (%s) uses bogus MAC length!", from->name, from->hostname); - return false; - } + /* Don't use key material until every check has passed. */ + cipher_close(&from->outcipher); + digest_close(&from->outdigest); + from->status.validkey = false; if(compression < 0 || compression > 11) { - logger(LOG_ERR, "Node %s (%s) uses bogus compression level!", from->name, from->hostname); + logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses bogus compression level!", from->name, from->hostname); return true; } from->outcompression = compression; - /* ECDH or old-style key exchange? */ - - if(experimental && !strncmp(key, "ECDH:", 5)) { - char *pubkey = strchr(key + 5, ':'); - if(pubkey) - *pubkey++ = 0; - - /* Check if we already have an ECDSA public key for this node. - * If not, use the one from the key exchange, and store it. */ + /* SPTPS or old-style key exchange? */ - if(!node_read_ecdsa_public_key(from)) { - if(!pubkey) { - logger(LOG_ERR, "No ECDSA public key known for %s (%s), cannot verify ECDH key exchange!", from->name, from->hostname); - return true; + if(from->status.sptps) { + char buf[strlen(key)]; + int len = b64decode(key, buf, strlen(key)); + + if(!sptps_receive_data(&from->sptps, buf, len)) + logger(DEBUG_ALWAYS, LOG_ERR, "Error processing SPTPS data from %s (%s)", from->name, from->hostname); + + if(from->status.validkey) { + if(*address && *port) { + logger(DEBUG_PROTOCOL, 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(!ecdsa_set_base64_public_key(&from->ecdsa, pubkey)) - return true; - - append_config_file(from->name, "ECDSAPublicKey", pubkey); + if(from->options & OPTION_PMTU_DISCOVERY) + send_mtu_probe(from); } - int siglen = ecdsa_size(&from->ecdsa); - int keylen = b64decode(key + 5, key + 5, sizeof key - 5); - - if(keylen != ECDH_SIZE + siglen) { - logger(LOG_ERR, "Node %s (%s) uses wrong keylength! %d != %d", from->name, from->hostname, keylen, ECDH_SIZE + siglen); - return true; - } - - if(ECDH_SHARED_SIZE < cipher_keylength(&from->outcipher)) { - logger(LOG_ERR, "ECDH key too short for cipher of %s!", from->name); - return true; - } - - if(!ecdsa_verify(&from->ecdsa, key + 5, ECDH_SIZE, key + 5 + ECDH_SIZE)) { - logger(LOG_ERR, "Possible intruder %s (%s): %s", from->name, from->hostname, "invalid ECDSA signature"); - return true; - } - - if(!from->ecdh) { - from->status.ecdh = true; - if(!send_ans_key(from)) - return true; - } - - char shared[ECDH_SHARED_SIZE * 2 + 1]; - - if(!ecdh_compute_shared(&from->ecdh, key + 5, shared)) - return true; - - /* Update our crypto end */ - - size_t mykeylen = cipher_keylength(&myself->incipher); - size_t hiskeylen = cipher_keylength(&from->outcipher); - - char *mykey; - char *hiskey; - char *seed; - - if(strcmp(myself->name, from->name) < 0) { - mykey = key; - hiskey = key + mykeylen * 2; - xasprintf(&seed, "tinc UDP key expansion %s %s", myself->name, from->name); - } else { - mykey = key + hiskeylen * 2; - hiskey = key; - xasprintf(&seed, "tinc UDP key expansion %s %s", from->name, myself->name); - } - - if(!prf(shared, ECDH_SHARED_SIZE, seed, strlen(seed), key, hiskeylen * 2 + mykeylen * 2)) - return true; - - free(seed); - - cipher_open_by_nid(&from->incipher, cipher_get_nid(&myself->incipher)); - digest_open_by_nid(&from->indigest, digest_get_nid(&myself->indigest), digest_length(&myself->indigest)); - from->incompression = myself->incompression; - - cipher_set_key(&from->incipher, mykey, false); - digest_set_key(&from->indigest, mykey + mykeylen, mykeylen); - - cipher_set_key(&from->outcipher, hiskey, true); - digest_set_key(&from->outdigest, hiskey + hiskeylen, hiskeylen); - - // Reset sequence number and late packet window - mykeyused = true; - from->received_seqno = 0; - if(replaywin) - memset(from->late, 0, replaywin); - - if(strcmp(myself->name, from->name) < 0) - memmove(key, key + mykeylen * 2, hiskeylen * 2); - } else { - keylen = hex2bin(key, key, sizeof key); - - if(keylen != cipher_keylength(&from->outcipher)) { - logger(LOG_ERR, "Node %s (%s) uses wrong keylength!", from->name, from->hostname); - return true; - } - - /* Update our copy of the origin's packet key */ - - cipher_set_key(&from->outcipher, key, true); - digest_set_key(&from->outdigest, key, keylen); + return true; } + /* Check and lookup cipher and digest algorithms */ + + if(!cipher_open_by_nid(&from->outcipher, cipher)) { + logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses unknown cipher!", from->name, from->hostname); + return false; + } + + if(!digest_open_by_nid(&from->outdigest, digest, maclength)) { + logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses unknown digest!", from->name, from->hostname); + return false; + } + + if(maclength != digest_length(&from->outdigest)) { + logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses bogus MAC length!", from->name, from->hostname); + return false; + } + + /* Process key */ + + keylen = hex2bin(key, key, sizeof key); + + if(keylen != cipher_keylength(&from->outcipher)) { + logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses wrong keylength!", from->name, from->hostname); + return true; + } + + /* Update our copy of the origin's packet key */ + + cipher_set_key(&from->outcipher, key, true); + digest_set_key(&from->outdigest, key, keylen); + 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); + logger(DEBUG_PROTOCOL, 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); } diff --git a/src/protocol_misc.c b/src/protocol_misc.c index 225d7b4..7617091 100644 --- a/src/protocol_misc.c +++ b/src/protocol_misc.c @@ -1,7 +1,7 @@ /* protocol_misc.c -- handle the meta-protocol, miscellaneous functions Copyright (C) 1999-2005 Ivo Timmermans, - 2000-2009 Guus Sliepen + 2000-2012 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 @@ -40,17 +40,17 @@ bool send_status(connection_t *c, int statusno, const char *statusstring) { return send_request(c, "%d %d %s", STATUS, statusno, statusstring); } -bool status_h(connection_t *c, char *request) { +bool status_h(connection_t *c, const char *request) { int statusno; char statusstring[MAX_STRING_SIZE]; if(sscanf(request, "%*d %d " MAX_STRING, &statusno, statusstring) != 2) { - logger(LOG_ERR, "Got bad %s from %s (%s)", "STATUS", + logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "STATUS", c->name, c->hostname); return false; } - ifdebug(STATUS) logger(LOG_NOTICE, "Status message from %s (%s): %d: %s", + logger(DEBUG_STATUS, LOG_NOTICE, "Status message from %s (%s): %d: %s", c->name, c->hostname, statusno, statusstring); return true; @@ -63,17 +63,17 @@ bool send_error(connection_t *c, int err, const char *errstring) { return send_request(c, "%d %d %s", ERROR, err, errstring); } -bool error_h(connection_t *c, char *request) { +bool error_h(connection_t *c, const char *request) { int err; char errorstring[MAX_STRING_SIZE]; if(sscanf(request, "%*d %d " MAX_STRING, &err, errorstring) != 2) { - logger(LOG_ERR, "Got bad %s from %s (%s)", "ERROR", + logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "ERROR", c->name, c->hostname); return false; } - ifdebug(ERROR) logger(LOG_NOTICE, "Error message from %s (%s): %d: %s", + logger(DEBUG_ERROR, LOG_NOTICE, "Error message from %s (%s): %d: %s", c->name, c->hostname, err, errorstring); return false; @@ -83,7 +83,7 @@ bool send_termreq(connection_t *c) { return send_request(c, "%d", TERMREQ); } -bool termreq_h(connection_t *c, char *request) { +bool termreq_h(connection_t *c, const char *request) { return false; } @@ -94,7 +94,7 @@ bool send_ping(connection_t *c) { return send_request(c, "%d", PING); } -bool ping_h(connection_t *c, char *request) { +bool ping_h(connection_t *c, const char *request) { return send_pong(c); } @@ -102,13 +102,19 @@ bool send_pong(connection_t *c) { return send_request(c, "%d", PONG); } -bool pong_h(connection_t *c, char *request) { +bool pong_h(connection_t *c, const char *request) { c->status.pinged = false; /* Succesful connection, reset timeout if this is an outgoing connection. */ - if(c->outgoing) + if(c->outgoing) { c->outgoing->timeout = 0; + c->outgoing->cfg = NULL; + if(c->outgoing->ai) + freeaddrinfo(c->outgoing->ai); + c->outgoing->ai = NULL; + c->outgoing->aip = NULL; + } return true; } @@ -117,7 +123,7 @@ bool pong_h(connection_t *c, char *request) { bool send_tcppacket(connection_t *c, const vpn_packet_t *packet) { /* If there already is a lot of data in the outbuf buffer, discard this packet. - We use a very simple Random Early Drop algorithm. */ + We use a very simple Random Early Drop algorithm. */ if(2.0 * c->outbuf.len / (float)maxoutbufsize - 1 > (float)rand()/(float)RAND_MAX) return true; @@ -128,11 +134,11 @@ bool send_tcppacket(connection_t *c, const vpn_packet_t *packet) { return send_meta(c, (char *)packet->data, packet->len); } -bool tcppacket_h(connection_t *c, char *request) { +bool tcppacket_h(connection_t *c, const char *request) { short int len; if(sscanf(request, "%*d %hd", &len) != 1) { - logger(LOG_ERR, "Got bad %s from %s (%s)", "PACKET", c->name, + logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "PACKET", c->name, c->hostname); return false; } diff --git a/src/protocol_subnet.c b/src/protocol_subnet.c index 6f9e626..06dafbc 100644 --- a/src/protocol_subnet.c +++ b/src/protocol_subnet.c @@ -1,7 +1,7 @@ /* protocol_subnet.c -- handle the meta-protocol, subnets Copyright (C) 1999-2005 Ivo Timmermans, - 2000-2009 Guus Sliepen + 2000-2012 Guus Sliepen 2009 Michael Tokarev This program is free software; you can redistribute it and/or modify @@ -41,14 +41,14 @@ bool send_add_subnet(connection_t *c, const subnet_t *subnet) { return send_request(c, "%d %x %s %s", ADD_SUBNET, rand(), subnet->owner->name, netstr); } -bool add_subnet_h(connection_t *c, char *request) { +bool add_subnet_h(connection_t *c, const char *request) { char subnetstr[MAX_STRING_SIZE]; char name[MAX_STRING_SIZE]; node_t *owner; subnet_t s = {NULL}, *new, *old; if(sscanf(request, "%*d %*x " MAX_STRING " " MAX_STRING, name, subnetstr) != 2) { - logger(LOG_ERR, "Got bad %s from %s (%s)", "ADD_SUBNET", c->name, + logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "ADD_SUBNET", c->name, c->hostname); return false; } @@ -56,7 +56,7 @@ bool add_subnet_h(connection_t *c, char *request) { /* Check if owner name is valid */ if(!check_id(name)) { - logger(LOG_ERR, "Got bad %s from %s (%s): %s", "ADD_SUBNET", c->name, + logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s): %s", "ADD_SUBNET", c->name, c->hostname, "invalid name"); return false; } @@ -64,7 +64,7 @@ bool add_subnet_h(connection_t *c, char *request) { /* Check if subnet string is valid */ if(!str2net(&s, subnetstr)) { - logger(LOG_ERR, "Got bad %s from %s (%s): %s", "ADD_SUBNET", c->name, + logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s): %s", "ADD_SUBNET", c->name, c->hostname, "invalid subnet string"); return false; } @@ -78,7 +78,7 @@ bool add_subnet_h(connection_t *c, char *request) { if(tunnelserver && owner != myself && owner != c->node) { /* in case of tunnelserver, ignore indirect subnet registrations */ - ifdebug(PROTOCOL) logger(LOG_WARNING, "Ignoring indirect %s from %s (%s) for %s", + logger(DEBUG_PROTOCOL, LOG_WARNING, "Ignoring indirect %s from %s (%s) for %s", "ADD_SUBNET", c->name, c->hostname, subnetstr); return true; } @@ -97,7 +97,7 @@ bool add_subnet_h(connection_t *c, char *request) { /* If we don't know this subnet, but we are the owner, retaliate with a DEL_SUBNET */ if(owner == myself) { - ifdebug(PROTOCOL) logger(LOG_WARNING, "Got %s from %s (%s) for ourself", + logger(DEBUG_PROTOCOL, LOG_WARNING, "Got %s from %s (%s) for ourself", "ADD_SUBNET", c->name, c->hostname); s.owner = myself; send_del_subnet(c, &s); @@ -107,7 +107,7 @@ bool add_subnet_h(connection_t *c, char *request) { /* In tunnel server mode, we should already know all allowed subnets */ if(tunnelserver) { - logger(LOG_WARNING, "Ignoring unauthorized %s from %s (%s): %s", + logger(DEBUG_ALWAYS, LOG_WARNING, "Ignoring unauthorized %s from %s (%s): %s", "ADD_SUBNET", c->name, c->hostname, subnetstr); return true; } @@ -115,7 +115,7 @@ bool add_subnet_h(connection_t *c, char *request) { /* Ignore if strictsubnets is true, but forward it to others */ if(strictsubnets) { - logger(LOG_WARNING, "Ignoring unauthorized %s from %s (%s): %s", + logger(DEBUG_ALWAYS, LOG_WARNING, "Ignoring unauthorized %s from %s (%s): %s", "ADD_SUBNET", c->name, c->hostname, subnetstr); forward_request(c, request); return true; @@ -151,14 +151,14 @@ bool send_del_subnet(connection_t *c, const subnet_t *s) { return send_request(c, "%d %x %s %s", DEL_SUBNET, rand(), s->owner->name, netstr); } -bool del_subnet_h(connection_t *c, char *request) { +bool del_subnet_h(connection_t *c, const char *request) { char subnetstr[MAX_STRING_SIZE]; char name[MAX_STRING_SIZE]; node_t *owner; subnet_t s = {NULL}, *find; if(sscanf(request, "%*d %*x " MAX_STRING " " MAX_STRING, name, subnetstr) != 2) { - logger(LOG_ERR, "Got bad %s from %s (%s)", "DEL_SUBNET", c->name, + logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "DEL_SUBNET", c->name, c->hostname); return false; } @@ -166,7 +166,7 @@ bool del_subnet_h(connection_t *c, char *request) { /* Check if owner name is valid */ if(!check_id(name)) { - logger(LOG_ERR, "Got bad %s from %s (%s): %s", "DEL_SUBNET", c->name, + logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s): %s", "DEL_SUBNET", c->name, c->hostname, "invalid name"); return false; } @@ -174,7 +174,7 @@ bool del_subnet_h(connection_t *c, char *request) { /* Check if subnet string is valid */ if(!str2net(&s, subnetstr)) { - logger(LOG_ERR, "Got bad %s from %s (%s): %s", "DEL_SUBNET", c->name, + logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s): %s", "DEL_SUBNET", c->name, c->hostname, "invalid subnet string"); return false; } @@ -188,13 +188,13 @@ bool del_subnet_h(connection_t *c, char *request) { if(tunnelserver && owner != myself && owner != c->node) { /* in case of tunnelserver, ignore indirect subnet deletion */ - ifdebug(PROTOCOL) logger(LOG_WARNING, "Ignoring indirect %s from %s (%s) for %s", - "DEL_SUBNET", c->name, c->hostname, subnetstr); + logger(DEBUG_PROTOCOL, LOG_WARNING, "Ignoring indirect %s from %s (%s) for %s", + "DEL_SUBNET", c->name, c->hostname, subnetstr); return true; } if(!owner) { - ifdebug(PROTOCOL) logger(LOG_WARNING, "Got %s from %s (%s) for %s which is not in our node tree", + logger(DEBUG_PROTOCOL, LOG_WARNING, "Got %s from %s (%s) for %s which is not in our node tree", "DEL_SUBNET", c->name, c->hostname, name); return true; } @@ -206,7 +206,7 @@ bool del_subnet_h(connection_t *c, char *request) { find = lookup_subnet(owner, &s); if(!find) { - ifdebug(PROTOCOL) logger(LOG_WARNING, "Got %s from %s (%s) for %s which does not appear in his subnet tree", + logger(DEBUG_PROTOCOL, 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, request); @@ -216,7 +216,7 @@ bool del_subnet_h(connection_t *c, char *request) { /* If we are the owner of this subnet, retaliate with an ADD_SUBNET */ if(owner == myself) { - ifdebug(PROTOCOL) logger(LOG_WARNING, "Got %s from %s (%s) for ourself", + logger(DEBUG_PROTOCOL, LOG_WARNING, "Got %s from %s (%s) for ourself", "DEL_SUBNET", c->name, c->hostname); send_add_subnet(c, find); return true; diff --git a/src/raw_socket/device.c b/src/raw_socket_device.c similarity index 57% rename from src/raw_socket/device.c rename to src/raw_socket_device.c index 410e46e..48954d5 100644 --- a/src/raw_socket/device.c +++ b/src/raw_socket_device.c @@ -1,7 +1,7 @@ /* device.c -- raw socket Copyright (C) 2002-2005 Ivo Timmermans, - 2002-2009 Guus Sliepen + 2002-2012 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 @@ -20,7 +20,9 @@ #include "system.h" +#ifdef HAVE_NETPACKET_PACKET_H #include +#endif #include "conf.h" #include "device.h" @@ -30,16 +32,13 @@ #include "route.h" #include "xalloc.h" -int device_fd = -1; -char *device = NULL; -char *iface = NULL; -static char ifrname[IFNAMSIZ]; +#if defined(PF_PACKET) && defined(ETH_P_ALL) && defined(AF_PACKET) static char *device_info; static uint64_t device_total_in = 0; static uint64_t device_total_out = 0; -bool setup_device(void) { +static bool setup_device(void) { struct ifreq ifr; struct sockaddr_ll sa; @@ -52,16 +51,21 @@ bool setup_device(void) { device_info = "raw socket"; if((device_fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL))) < 0) { - logger(LOG_ERR, "Could not open %s: %s", device_info, + logger(DEBUG_ALWAYS, LOG_ERR, "Could not open %s: %s", device_info, strerror(errno)); return false; } memset(&ifr, 0, sizeof ifr); + +#ifdef FD_CLOEXEC + fcntl(device_fd, F_SETFD, FD_CLOEXEC); +#endif + strncpy(ifr.ifr_ifrn.ifrn_name, iface, IFNAMSIZ); if(ioctl(device_fd, SIOCGIFINDEX, &ifr)) { close(device_fd); - logger(LOG_ERR, "Can't find interface %s: %s", iface, + logger(DEBUG_ALWAYS, LOG_ERR, "Can't find interface %s: %s", iface, strerror(errno)); return false; } @@ -72,27 +76,27 @@ bool setup_device(void) { sa.sll_ifindex = ifr.ifr_ifindex; if(bind(device_fd, (struct sockaddr *) &sa, (socklen_t) sizeof sa)) { - logger(LOG_ERR, "Could not bind %s to %s: %s", device, iface, strerror(errno)); + logger(DEBUG_ALWAYS, LOG_ERR, "Could not bind %s to %s: %s", device, iface, strerror(errno)); return false; } - logger(LOG_INFO, "%s is a %s", device, device_info); + logger(DEBUG_ALWAYS, LOG_INFO, "%s is a %s", device, device_info); return true; } -void close_device(void) { +static void close_device(void) { close(device_fd); free(device); free(iface); } -bool read_packet(vpn_packet_t *packet) { +static bool read_packet(vpn_packet_t *packet) { int inlen; if((inlen = read(device_fd, packet->data, MTU)) <= 0) { - logger(LOG_ERR, "Error while reading from %s %s: %s", device_info, + logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info, device, strerror(errno)); return false; } @@ -101,18 +105,18 @@ bool read_packet(vpn_packet_t *packet) { device_total_in += packet->len; - ifdebug(TRAFFIC) logger(LOG_DEBUG, "Read packet of %d bytes from %s", packet->len, + logger(DEBUG_TRAFFIC, LOG_DEBUG, "Read packet of %d bytes from %s", packet->len, device_info); return true; } -bool write_packet(vpn_packet_t *packet) { - ifdebug(TRAFFIC) logger(LOG_DEBUG, "Writing packet of %d bytes to %s", +static bool write_packet(vpn_packet_t *packet) { + logger(DEBUG_TRAFFIC, LOG_DEBUG, "Writing packet of %d bytes to %s", packet->len, device_info); if(write(device_fd, packet->data, packet->len) < 0) { - logger(LOG_ERR, "Can't write to %s %s: %s", device_info, device, + logger(DEBUG_ALWAYS, LOG_ERR, "Can't write to %s %s: %s", device_info, device, strerror(errno)); return false; } @@ -122,8 +126,32 @@ bool write_packet(vpn_packet_t *packet) { return true; } -void dump_device_stats(void) { - logger(LOG_DEBUG, "Statistics for %s %s:", device_info, device); - logger(LOG_DEBUG, " total bytes in: %10"PRIu64, device_total_in); - logger(LOG_DEBUG, " total bytes out: %10"PRIu64, device_total_out); +static void dump_device_stats(void) { + logger(DEBUG_ALWAYS, LOG_DEBUG, "Statistics for %s %s:", device_info, device); + logger(DEBUG_ALWAYS, LOG_DEBUG, " total bytes in: %10"PRIu64, device_total_in); + logger(DEBUG_ALWAYS, LOG_DEBUG, " total bytes out: %10"PRIu64, device_total_out); } + +const devops_t raw_socket_devops = { + .setup = setup_device, + .close = close_device, + .read = read_packet, + .write = write_packet, + .dump_stats = dump_device_stats, +}; + +#else + +static bool not_supported(void) { + logger(DEBUG_ALWAYS, LOG_ERR, "Raw socket device not supported on this platform"); + return false; +} + +const devops_t raw_socket_devops = { + .setup = not_supported, + .close = NULL, + .read = NULL, + .write = NULL, + .dump_stats = NULL, +}; +#endif diff --git a/src/route.c b/src/route.c index 0b2d22e..e874d89 100644 --- a/src/route.c +++ b/src/route.c @@ -1,7 +1,7 @@ /* route.c -- routing Copyright (C) 2000-2005 Ivo Timmermans, - 2000-2010 Guus Sliepen + 2000-2012 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 @@ -20,7 +20,6 @@ #include "system.h" -#include "splay_tree.h" #include "connection.h" #include "control_common.h" #include "ethernet.h" @@ -36,6 +35,8 @@ rmode_t routing_mode = RMODE_ROUTER; fmode_t forwarding_mode = FMODE_INTERNAL; +bmode_t broadcast_mode = BMODE_MST; +bool decrement_ttl = false; bool directonly = false; bool priorityinheritance = false; int macexpire = 600; @@ -70,7 +71,7 @@ static uint16_t inet_checksum(void *data, int len, uint16_t prevsum) { checksum += *p++; len -= 2; } - + if(len) checksum += *(uint8_t *)p; @@ -84,21 +85,22 @@ static bool ratelimit(int frequency) { static time_t lasttime = 0; static int count = 0; time_t now = time(NULL); - + if(lasttime == now) { - if(++count > frequency) + if(count >= frequency) return true; } else { lasttime = now; count = 0; } + count++; return false; } static bool checklength(node_t *source, vpn_packet_t *packet, length_t length) { if(packet->len < length) { - ifdebug(TRAFFIC) logger(LOG_WARNING, "Got too short packet from %s (%s)", source->name, source->hostname); + logger(DEBUG_TRAFFIC, LOG_WARNING, "Got too short packet from %s (%s)", source->name, source->hostname); return false; } else return true; @@ -160,8 +162,8 @@ static void clamp_mss(const node_t *source, const node_t *via, vpn_packet_t *pac if(oldmss <= newmss) break; - - ifdebug(TRAFFIC) logger(LOG_INFO, "Clamping MSS of packet from %s to %s to %d", source->name, via->name, newmss); + + logger(DEBUG_TRAFFIC, 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; @@ -182,29 +184,22 @@ static void swap_mac_addresses(vpn_packet_t *packet) { memcpy(&packet->data[0], &packet->data[6], sizeof tmp); memcpy(&packet->data[6], &tmp, sizeof tmp); } - + static void age_subnets(int fd, short events, void *data) { - subnet_t *s; - connection_t *c; - splay_node_t *node, *next, *node2; bool left = false; time_t now = time(NULL); - for(node = myself->subnet_tree->head; node; node = next) { - next = node->next; - s = node->data; + for splay_each(subnet_t, s, myself->subnet_tree) { if(s->expires && s->expires < now) { - ifdebug(TRAFFIC) { + if(debug_level >= DEBUG_TRAFFIC) { char netstr[MAXNETSTR]; if(net2str(netstr, sizeof netstr, s)) - logger(LOG_INFO, "Subnet %s expired", netstr); + logger(DEBUG_TRAFFIC, LOG_INFO, "Subnet %s expired", netstr); } - for(node2 = connection_tree->head; node2; node2 = node2->next) { - c = node2->data; + for list_each(connection_t, c, connection_list) if(c->status.active) send_del_subnet(c, s); - } subnet_del(myself, s); } else { @@ -218,16 +213,12 @@ static void age_subnets(int fd, short events, void *data) { } static void learn_mac(mac_t *address) { - subnet_t *subnet; - splay_node_t *node; - connection_t *c; - - subnet = lookup_subnet_mac(myself, address); + subnet_t *subnet = lookup_subnet_mac(myself, address); /* If we don't know this MAC address yet, store it */ if(!subnet) { - ifdebug(TRAFFIC) logger(LOG_INFO, "Learned new MAC address %hx:%hx:%hx:%hx:%hx:%hx", + logger(DEBUG_TRAFFIC, LOG_INFO, "Learned new MAC address %hx:%hx:%hx:%hx:%hx:%hx", address->x[0], address->x[1], address->x[2], address->x[3], address->x[4], address->x[5]); @@ -241,11 +232,9 @@ static void learn_mac(mac_t *address) { /* And tell all other tinc daemons it's our MAC */ - for(node = connection_tree->head; node; node = node->next) { - c = node->data; + for list_each(connection_t, c, connection_list) if(c->status.active) send_add_subnet(c, subnet); - } if(!timeout_initialized(&age_subnets_event)) timeout_set(&age_subnets_event, age_subnets, NULL); @@ -261,14 +250,14 @@ static void learn_mac(mac_t *address) { static void route_ipv4_unreachable(node_t *source, vpn_packet_t *packet, uint8_t type, uint8_t code) { struct ip ip = {0}; struct icmp icmp = {0}; - + struct in_addr ip_src; struct in_addr ip_dst; uint32_t oldlen; if(ratelimit(3)) return; - + /* Swap Ethernet source and destination addresses */ swap_mac_addresses(packet); @@ -278,7 +267,7 @@ static void route_ipv4_unreachable(node_t *source, vpn_packet_t *packet, uint8_t memcpy(&ip, packet->data + ether_size, ip_size); /* Remember original source and destination */ - + ip_src = ip.ip_src; ip_dst = ip.ip_dst; @@ -289,13 +278,13 @@ static void route_ipv4_unreachable(node_t *source, vpn_packet_t *packet, uint8_t if(oldlen >= IP_MSS - ip_size - icmp_size) oldlen = IP_MSS - ip_size - icmp_size; - + /* Copy first part of original contents to ICMP message */ - + memmove(packet->data + ether_size + ip_size + icmp_size, packet->data + ether_size, oldlen); /* Fill in IPv4 header */ - + ip.ip_v = 4; ip.ip_hl = ip_size / 4; ip.ip_tos = 0; @@ -309,13 +298,13 @@ static void route_ipv4_unreachable(node_t *source, vpn_packet_t *packet, uint8_t ip.ip_dst = ip_src; ip.ip_sum = inet_checksum(&ip, ip_size, ~0); - + /* Fill in ICMP header */ - + icmp.icmp_type = type; icmp.icmp_code = code; icmp.icmp_cksum = 0; - + icmp.icmp_cksum = inet_checksum(&icmp, icmp_size, ~0); icmp.icmp_cksum = inet_checksum(packet->data + ether_size + ip_size + icmp_size, oldlen, icmp.icmp_cksum); @@ -323,7 +312,7 @@ static void route_ipv4_unreachable(node_t *source, vpn_packet_t *packet, uint8_t memcpy(packet->data + ether_size, &ip, ip_size); memcpy(packet->data + ether_size + ip_size, &icmp, icmp_size); - + packet->len = ether_size + ip_size + icmp_size + oldlen; send_packet(source, packet); @@ -337,28 +326,28 @@ static void fragment_ipv4_packet(node_t *dest, vpn_packet_t *packet) { int len, maxlen, todo; uint8_t *offset; uint16_t ip_off, origf; - + memcpy(&ip, packet->data + ether_size, ip_size); fragment.priority = packet->priority; if(ip.ip_hl != ip_size / 4) return; - + todo = ntohs(ip.ip_len) - ip_size; if(ether_size + ip_size + todo != packet->len) { - ifdebug(TRAFFIC) logger(LOG_WARNING, "Length of packet (%d) doesn't match length in IPv4 header (%d)", packet->len, (int)(ether_size + ip_size + todo)); + logger(DEBUG_TRAFFIC, LOG_WARNING, "Length of packet (%d) doesn't match length in IPv4 header (%d)", packet->len, (int)(ether_size + ip_size + todo)); return; } - ifdebug(TRAFFIC) logger(LOG_INFO, "Fragmenting packet of %d bytes to %s (%s)", packet->len, dest->name, dest->hostname); + logger(DEBUG_TRAFFIC, LOG_INFO, "Fragmenting packet of %d bytes to %s (%s)", packet->len, dest->name, dest->hostname); offset = packet->data + ether_size + ip_size; maxlen = (dest->mtu - ether_size - ip_size) & ~0x7; ip_off = ntohs(ip.ip_off); origf = ip_off & ~IP_OFFMASK; ip_off &= IP_OFFMASK; - + while(todo) { len = todo > maxlen ? maxlen : todo; memcpy(fragment.data + ether_size + ip_size, offset, len); @@ -376,7 +365,7 @@ static void fragment_ipv4_packet(node_t *dest, vpn_packet_t *packet) { send_packet(dest, &fragment); ip_off += len / 8; - } + } } static void route_ipv4_unicast(node_t *source, vpn_packet_t *packet) { @@ -388,7 +377,7 @@ static void route_ipv4_unicast(node_t *source, vpn_packet_t *packet) { subnet = lookup_subnet_ipv4(&dest); if(!subnet) { - ifdebug(TRAFFIC) logger(LOG_WARNING, "Cannot route packet from %s (%s): unknown IPv4 destination address %d.%d.%d.%d", + logger(DEBUG_TRAFFIC, LOG_WARNING, "Cannot route packet from %s (%s): unknown IPv4 destination address %d.%d.%d.%d", source->name, source->hostname, dest.x[0], dest.x[1], @@ -398,9 +387,9 @@ static void route_ipv4_unicast(node_t *source, vpn_packet_t *packet) { route_ipv4_unreachable(source, packet, ICMP_DEST_UNREACH, ICMP_NET_UNKNOWN); return; } - + if(subnet->owner == source) { - ifdebug(TRAFFIC) logger(LOG_WARNING, "Packet looping back to %s (%s)!", source->name, source->hostname); + logger(DEBUG_TRAFFIC, LOG_WARNING, "Packet looping back to %s (%s)!", source->name, source->hostname); return; } @@ -414,12 +403,17 @@ static void route_ipv4_unicast(node_t *source, vpn_packet_t *packet) { packet->priority = packet->data[15]; via = (subnet->owner->via == myself) ? subnet->owner->nexthop : subnet->owner->via; - + + if(via == source) { + logger(DEBUG_TRAFFIC, LOG_ERR, "Routing loop for packet from %s (%s)!", source->name, source->hostname); + return; + } + 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); + logger(DEBUG_TRAFFIC, 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); route_ipv4_unreachable(source, packet, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED); @@ -431,7 +425,7 @@ static void route_ipv4_unicast(node_t *source, vpn_packet_t *packet) { } clamp_mss(source, via, packet); - + send_packet(subnet->owner, packet); } @@ -439,11 +433,11 @@ static void route_ipv4(node_t *source, vpn_packet_t *packet) { if(!checklength(source, packet, ether_size + ip_size)) return; - if(((packet->data[30] & 0xf0) == 0xe0) || ( + if(broadcast_mode && (((packet->data[30] & 0xf0) == 0xe0) || ( packet->data[30] == 255 && packet->data[31] == 255 && packet->data[32] == 255 && - packet->data[33] == 255)) + packet->data[33] == 255))) broadcast_packet(source, packet); else route_ipv4_unicast(source, packet); @@ -454,18 +448,18 @@ static void route_ipv4(node_t *source, vpn_packet_t *packet) { static void route_ipv6_unreachable(node_t *source, vpn_packet_t *packet, uint8_t type, uint8_t code) { struct ip6_hdr ip6; struct icmp6_hdr icmp6 = {0}; - uint16_t checksum; + uint16_t checksum; struct { - struct in6_addr ip6_src; /* source address */ - struct in6_addr ip6_dst; /* destination address */ + struct in6_addr ip6_src; /* source address */ + struct in6_addr ip6_dst; /* destination address */ uint32_t length; uint32_t next; } pseudo; if(ratelimit(3)) return; - + /* Swap Ethernet source and destination addresses */ swap_mac_addresses(packet); @@ -475,7 +469,7 @@ static void route_ipv6_unreachable(node_t *source, vpn_packet_t *packet, uint8_t memcpy(&ip6, packet->data + ether_size, ip6_size); /* Remember original source and destination */ - + pseudo.ip6_src = ip6.ip6_dst; pseudo.ip6_dst = ip6.ip6_src; @@ -483,16 +477,16 @@ static void route_ipv6_unreachable(node_t *source, vpn_packet_t *packet, uint8_t if(type == ICMP6_PACKET_TOO_BIG) icmp6.icmp6_mtu = htonl(pseudo.length); - + if(pseudo.length >= IP_MSS - ip6_size - icmp6_size) pseudo.length = IP_MSS - ip6_size - icmp6_size; - + /* Copy first part of original contents to ICMP message */ - + memmove(packet->data + ether_size + ip6_size + icmp6_size, packet->data + ether_size, pseudo.length); /* Fill in IPv6 header */ - + ip6.ip6_flow = htonl(0x60000000UL); ip6.ip6_plen = htons(icmp6_size + pseudo.length); ip6.ip6_nxt = IPPROTO_ICMPV6; @@ -501,18 +495,18 @@ static void route_ipv6_unreachable(node_t *source, vpn_packet_t *packet, uint8_t ip6.ip6_dst = pseudo.ip6_dst; /* Fill in ICMP header */ - + icmp6.icmp6_type = type; icmp6.icmp6_code = code; icmp6.icmp6_cksum = 0; /* Create pseudo header */ - + pseudo.length = htonl(icmp6_size + pseudo.length); pseudo.next = htonl(IPPROTO_ICMPV6); /* Generate checksum */ - + checksum = inet_checksum(&pseudo, sizeof pseudo, ~0); checksum = inet_checksum(&icmp6, icmp6_size, checksum); checksum = inet_checksum(packet->data + ether_size + ip6_size + icmp6_size, ntohl(pseudo.length) - icmp6_size, checksum); @@ -523,9 +517,9 @@ static void route_ipv6_unreachable(node_t *source, vpn_packet_t *packet, uint8_t memcpy(packet->data + ether_size, &ip6, ip6_size); memcpy(packet->data + ether_size + ip6_size, &icmp6, icmp6_size); - + packet->len = ether_size + ip6_size + ntohl(pseudo.length); - + send_packet(source, packet); } @@ -538,7 +532,7 @@ static void route_ipv6_unicast(node_t *source, vpn_packet_t *packet) { subnet = lookup_subnet_ipv6(&dest); if(!subnet) { - ifdebug(TRAFFIC) logger(LOG_WARNING, "Cannot route packet from %s (%s): unknown IPv6 destination address %hx:%hx:%hx:%hx:%hx:%hx:%hx:%hx", + logger(DEBUG_TRAFFIC, LOG_WARNING, "Cannot route packet from %s (%s): unknown IPv6 destination address %hx:%hx:%hx:%hx:%hx:%hx:%hx:%hx", source->name, source->hostname, ntohs(dest.x[0]), ntohs(dest.x[1]), @@ -554,7 +548,7 @@ static void route_ipv6_unicast(node_t *source, vpn_packet_t *packet) { } if(subnet->owner == source) { - ifdebug(TRAFFIC) logger(LOG_WARNING, "Packet looping back to %s (%s)!", source->name, source->hostname); + logger(DEBUG_TRAFFIC, LOG_WARNING, "Packet looping back to %s (%s)!", source->name, source->hostname); return; } @@ -565,19 +559,24 @@ static void route_ipv6_unicast(node_t *source, vpn_packet_t *packet) { 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 == source) { + logger(DEBUG_TRAFFIC, LOG_ERR, "Routing loop for packet from %s (%s)!", source->name, source->hostname); + return; + } + 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); + logger(DEBUG_TRAFFIC, 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); route_ipv6_unreachable(source, packet, ICMP6_PACKET_TOO_BIG, 0); return; } clamp_mss(source, via, packet); - + send_packet(subnet->owner, packet); } @@ -592,19 +591,19 @@ static void route_neighborsol(node_t *source, vpn_packet_t *packet) { bool has_opt; struct { - struct in6_addr ip6_src; /* source address */ - struct in6_addr ip6_dst; /* destination address */ + struct in6_addr ip6_src; + struct in6_addr ip6_dst; uint32_t length; uint32_t next; } pseudo; if(!checklength(source, packet, ether_size + ip6_size + ns_size)) return; - + has_opt = packet->len >= ether_size + ip6_size + ns_size + opt_size + ETH_ALEN; - + if(source != myself) { - ifdebug(TRAFFIC) logger(LOG_WARNING, "Got neighbor solicitation request from %s (%s) while in router mode!", source->name, source->hostname); + logger(DEBUG_TRAFFIC, LOG_WARNING, "Got neighbor solicitation request from %s (%s) while in router mode!", source->name, source->hostname); return; } @@ -624,7 +623,7 @@ static void route_neighborsol(node_t *source, vpn_packet_t *packet) { if(ns.nd_ns_hdr.icmp6_type != ND_NEIGHBOR_SOLICIT || (has_opt && opt.nd_opt_type != ND_OPT_SOURCE_LINKADDR)) { - ifdebug(TRAFFIC) logger(LOG_WARNING, "Cannot route packet: received unknown type neighbor solicitation request"); + logger(DEBUG_TRAFFIC, LOG_WARNING, "Cannot route packet: received unknown type neighbor solicitation request"); return; } @@ -648,7 +647,7 @@ static void route_neighborsol(node_t *source, vpn_packet_t *packet) { } if(checksum) { - ifdebug(TRAFFIC) logger(LOG_WARNING, "Cannot route packet: checksum error for neighbor solicitation request"); + logger(DEBUG_TRAFFIC, LOG_WARNING, "Cannot route packet: checksum error for neighbor solicitation request"); return; } @@ -657,7 +656,7 @@ static void route_neighborsol(node_t *source, vpn_packet_t *packet) { subnet = lookup_subnet_ipv6((ipv6_t *) &ns.nd_ns_target); if(!subnet) { - ifdebug(TRAFFIC) logger(LOG_WARNING, "Cannot route packet: neighbor solicitation request for unknown address %hx:%hx:%hx:%hx:%hx:%hx:%hx:%hx", + logger(DEBUG_TRAFFIC, LOG_WARNING, "Cannot route packet: neighbor solicitation request for unknown address %hx:%hx:%hx:%hx:%hx:%hx:%hx:%hx", ntohs(((uint16_t *) &ns.nd_ns_target)[0]), ntohs(((uint16_t *) &ns.nd_ns_target)[1]), ntohs(((uint16_t *) &ns.nd_ns_target)[2]), @@ -673,22 +672,22 @@ static void route_neighborsol(node_t *source, vpn_packet_t *packet) { /* Check if it is for our own subnet */ if(subnet->owner == myself) - return; /* silently ignore */ + return; /* silently ignore */ /* Create neighbor advertation reply */ - memcpy(packet->data, packet->data + ETH_ALEN, ETH_ALEN); /* copy destination address */ - packet->data[ETH_ALEN * 2 - 1] ^= 0xFF; /* mangle source address so it looks like it's not from us */ + memcpy(packet->data, packet->data + ETH_ALEN, ETH_ALEN); /* copy destination address */ + packet->data[ETH_ALEN * 2 - 1] ^= 0xFF; /* mangle source address so it looks like it's not from us */ - ip6.ip6_dst = ip6.ip6_src; /* swap destination and source protocoll address */ + ip6.ip6_dst = ip6.ip6_src; /* swap destination and source protocoll address */ ip6.ip6_src = ns.nd_ns_target; if(has_opt) - memcpy(packet->data + ether_size + ip6_size + ns_size + opt_size, packet->data + ETH_ALEN, ETH_ALEN); /* add fake source hard addr */ + memcpy(packet->data + ether_size + ip6_size + ns_size + opt_size, packet->data + ETH_ALEN, ETH_ALEN); /* add fake source hard addr */ ns.nd_ns_cksum = 0; ns.nd_ns_type = ND_NEIGHBOR_ADVERT; - ns.nd_ns_reserved = htonl(0x40000000UL); /* Set solicited flag */ + ns.nd_ns_reserved = htonl(0x40000000UL); /* Set solicited flag */ opt.nd_opt_type = ND_OPT_TARGET_LINKADDR; /* Create pseudo header */ @@ -731,7 +730,7 @@ static void route_ipv6(node_t *source, vpn_packet_t *packet) { return; } - if(packet->data[38] == 255) + if(broadcast_mode && packet->data[38] == 255) broadcast_packet(source, packet); else route_ipv6_unicast(source, packet); @@ -748,7 +747,7 @@ static void route_arp(node_t *source, vpn_packet_t *packet) { return; if(source != myself) { - ifdebug(TRAFFIC) logger(LOG_WARNING, "Got ARP request from %s (%s) while in router mode!", source->name, source->hostname); + logger(DEBUG_TRAFFIC, LOG_WARNING, "Got ARP request from %s (%s) while in router mode!", source->name, source->hostname); return; } @@ -765,7 +764,7 @@ static void route_arp(node_t *source, vpn_packet_t *packet) { if(ntohs(arp.arp_hrd) != ARPHRD_ETHER || ntohs(arp.arp_pro) != ETH_P_IP || arp.arp_hln != ETH_ALEN || arp.arp_pln != sizeof addr || ntohs(arp.arp_op) != ARPOP_REQUEST) { - ifdebug(TRAFFIC) logger(LOG_WARNING, "Cannot route packet: received unknown type ARP request"); + logger(DEBUG_TRAFFIC, LOG_WARNING, "Cannot route packet: received unknown type ARP request"); return; } @@ -774,7 +773,7 @@ static void route_arp(node_t *source, vpn_packet_t *packet) { subnet = lookup_subnet_ipv4((ipv4_t *) &arp.arp_tpa); if(!subnet) { - ifdebug(TRAFFIC) logger(LOG_WARNING, "Cannot route packet: ARP request for unknown address %d.%d.%d.%d", + logger(DEBUG_TRAFFIC, LOG_WARNING, "Cannot route packet: ARP request for unknown address %d.%d.%d.%d", arp.arp_tpa[0], arp.arp_tpa[1], arp.arp_tpa[2], arp.arp_tpa[3]); return; @@ -783,17 +782,17 @@ static void route_arp(node_t *source, vpn_packet_t *packet) { /* Check if it is for our own subnet */ if(subnet->owner == myself) - return; /* silently ignore */ + return; /* silently ignore */ - memcpy(packet->data, packet->data + ETH_ALEN, ETH_ALEN); /* copy destination address */ - packet->data[ETH_ALEN * 2 - 1] ^= 0xFF; /* mangle source address so it looks like it's not from us */ + memcpy(packet->data, packet->data + ETH_ALEN, ETH_ALEN); /* copy destination address */ + packet->data[ETH_ALEN * 2 - 1] ^= 0xFF; /* mangle source address so it looks like it's not from us */ - memcpy(&addr, arp.arp_tpa, sizeof addr); /* save protocol addr */ - memcpy(arp.arp_tpa, arp.arp_spa, sizeof addr); /* swap destination and source protocol address */ - memcpy(arp.arp_spa, &addr, sizeof addr); /* ... */ + memcpy(&addr, arp.arp_tpa, sizeof addr); /* save protocol addr */ + memcpy(arp.arp_tpa, arp.arp_spa, sizeof addr); /* swap destination and source protocol address */ + memcpy(arp.arp_spa, &addr, sizeof addr); /* ... */ - memcpy(arp.arp_tha, arp.arp_sha, ETH_ALEN); /* set target hard/proto addr */ - memcpy(arp.arp_sha, packet->data + ETH_ALEN, ETH_ALEN); /* add fake source hard addr */ + memcpy(arp.arp_tha, arp.arp_sha, ETH_ALEN); /* set target hard/proto addr */ + memcpy(arp.arp_sha, packet->data + ETH_ALEN, ETH_ALEN); /* add fake source hard addr */ arp.arp_op = htons(ARPOP_REPLY); /* Copy structs on stack back to packet */ @@ -826,7 +825,7 @@ static void route_mac(node_t *source, vpn_packet_t *packet) { } if(subnet->owner == source) { - ifdebug(TRAFFIC) logger(LOG_WARNING, "Packet looping back to %s (%s)!", source->name, source->hostname); + logger(DEBUG_TRAFFIC, LOG_WARNING, "Packet looping back to %s (%s)!", source->name, source->hostname); return; } @@ -839,9 +838,9 @@ static void route_mac(node_t *source, vpn_packet_t *packet) { 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); + logger(DEBUG_TRAFFIC, 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 && packet->len > 590) { if(packet->data[20] & 0x40) { @@ -859,20 +858,70 @@ static void route_mac(node_t *source, vpn_packet_t *packet) { } clamp_mss(source, via, packet); - + send_packet(subnet->owner, packet); } static void send_pcap(vpn_packet_t *packet) { pcap = false; - for(splay_node_t *node = connection_tree->head; node; node = node->next) { - connection_t *c = node->data; + + for list_each(connection_t, c, connection_list) { if(!c->status.pcap) continue; - else - pcap = true; - if(send_request(c, "%d %d %d", CONTROL, REQ_PCAP, packet->len)) - send_meta(c, (char *)packet->data, packet->len); + + pcap = true; + int len = packet->len; + if(c->outmaclength && c->outmaclength < len) + len = c->outmaclength; + + if(send_request(c, "%d %d %d", CONTROL, REQ_PCAP, len)) + send_meta(c, (char *)packet->data, len); + } +} + +static bool do_decrement_ttl(node_t *source, vpn_packet_t *packet) { + uint16_t type = packet->data[12] << 8 | packet->data[13]; + + switch (type) { + case ETH_P_IP: + if(!checklength(source, packet, 14 + 32)) + return false; + + if(packet->data[22] < 1) { + if(packet->data[25] != IPPROTO_ICMP || packet->data[46] != ICMP_TIME_EXCEEDED) + route_ipv4_unreachable(source, packet, ICMP_TIME_EXCEEDED, ICMP_EXC_TTL); + return false; + } + + uint16_t old = packet->data[22] << 8 | packet->data[23]; + packet->data[22]--; + uint16_t new = packet->data[22] << 8 | packet->data[23]; + + uint32_t checksum = packet->data[24] << 8 | packet->data[25]; + checksum += old + (~new & 0xFFFF); + while(checksum >> 16) + checksum = (checksum & 0xFFFF) + (checksum >> 16); + packet->data[24] = checksum >> 8; + packet->data[25] = checksum & 0xff; + + return true; + + case ETH_P_IPV6: + if(!checklength(source, packet, 14 + 40)) + return false; + + if(packet->data[21] < 1) { + if(packet->data[20] != IPPROTO_ICMPV6 || packet->data[54] != ICMP6_TIME_EXCEEDED) + route_ipv6_unreachable(source, packet, ICMP6_TIME_EXCEEDED, ICMP6_TIME_EXCEED_TRANSIT); + return false; + } + + packet->data[21]--; + + return true; + + default: + return true; } } @@ -888,28 +937,30 @@ void route(node_t *source, vpn_packet_t *packet) { if(!checklength(source, packet, ether_size)) return; + if(decrement_ttl && source != myself) + if(!do_decrement_ttl(source, packet)) + return; + + uint16_t type = packet->data[12] << 8 | packet->data[13]; + switch (routing_mode) { case RMODE_ROUTER: - { - uint16_t type = packet->data[12] << 8 | packet->data[13]; + switch (type) { + case ETH_P_ARP: + route_arp(source, packet); + break; - switch (type) { - case ETH_P_ARP: - route_arp(source, packet); - break; + case ETH_P_IP: + route_ipv4(source, packet); + break; - case ETH_P_IP: - route_ipv4(source, packet); - break; + case ETH_P_IPV6: + route_ipv6(source, packet); + break; - case ETH_P_IPV6: - route_ipv6(source, packet); - break; - - default: - ifdebug(TRAFFIC) logger(LOG_WARNING, "Cannot route packet from %s (%s): unknown type %hx", source->name, source->hostname, type); - break; - } + default: + logger(DEBUG_TRAFFIC, LOG_WARNING, "Cannot route packet from %s (%s): unknown type %hx", source->name, source->hostname, type); + break; } break; diff --git a/src/route.h b/src/route.h index 5af2a09..a0121d7 100644 --- a/src/route.h +++ b/src/route.h @@ -1,7 +1,7 @@ /* route.h -- header file for route.c Copyright (C) 2000-2005 Ivo Timmermans - 2000-2006 Guus Sliepen + 2000-2012 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,8 +36,16 @@ typedef enum fmode_t { FMODE_KERNEL, } fmode_t; +typedef enum bmode_t { + BMODE_NONE = 0, + BMODE_MST, + BMODE_DIRECT, +} bmode_t; + extern rmode_t routing_mode; extern fmode_t forwarding_mode; +extern bmode_t broadcast_mode; +extern bool decrement_ttl; extern bool directonly; extern bool overwrite_mac; extern bool priorityinheritance; @@ -48,4 +56,4 @@ extern mac_t mymac; extern void route(struct node_t *, struct vpn_packet_t *); -#endif /* __TINC_ROUTE_H__ */ +#endif /* __TINC_ROUTE_H__ */ diff --git a/src/solaris/device.c b/src/solaris/device.c index eac267a..cb2ece7 100644 --- a/src/solaris/device.c +++ b/src/solaris/device.c @@ -1,7 +1,7 @@ /* device.c -- Interaction with Solaris tun device Copyright (C) 2001-2005 Ivo Timmermans, - 2001-2011 Guus Sliepen + 2001-2012 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 @@ -35,7 +35,7 @@ #define DEFAULT_DEVICE "/dev/tun" int device_fd = -1; -int ip_fd = -1, if_fd = -1; +static int ip_fd = -1, if_fd = -1; char *device = NULL; char *iface = NULL; static char *device_info = NULL; @@ -43,7 +43,7 @@ static char *device_info = NULL; static uint64_t device_total_in = 0; static uint64_t device_total_out = 0; -bool setup_device(void) { +static bool setup_device(void) { int ppa; char *ptr; @@ -51,10 +51,14 @@ bool setup_device(void) { device = xstrdup(DEFAULT_DEVICE); if((device_fd = open(device, O_RDWR | O_NONBLOCK)) < 0) { - logger(LOG_ERR, "Could not open %s: %s", device, strerror(errno)); + logger(DEBUG_ALWAYS, LOG_ERR, "Could not open %s: %s", device, strerror(errno)); return false; } +#ifdef FD_CLOEXEC + fcntl(device_fd, F_SETFD, FD_CLOEXEC); +#endif + ppa = 0; ptr = device; @@ -63,35 +67,43 @@ bool setup_device(void) { ppa = atoi(ptr); if((ip_fd = open("/dev/ip", O_RDWR, 0)) < 0) { - logger(LOG_ERR, "Could not open /dev/ip: %s", strerror(errno)); + logger(DEBUG_ALWAYS, LOG_ERR, "Could not open /dev/ip: %s", strerror(errno)); return false; } +#ifdef FD_CLOEXEC + fcntl(ip_fd, F_SETFD, FD_CLOEXEC); +#endif + /* Assign a new PPA and get its unit number. */ if((ppa = ioctl(device_fd, TUNNEWPPA, ppa)) < 0) { - logger(LOG_ERR, "Can't assign new interface: %s", strerror(errno)); + logger(DEBUG_ALWAYS, LOG_ERR, "Can't assign new interface: %s", strerror(errno)); return false; } if((if_fd = open(device, O_RDWR, 0)) < 0) { - logger(LOG_ERR, "Could not open %s twice: %s", device, + logger(DEBUG_ALWAYS, LOG_ERR, "Could not open %s twice: %s", device, strerror(errno)); return false; } +#ifdef FD_CLOEXEC + fcntl(if_fd, F_SETFD, FD_CLOEXEC); +#endif + if(ioctl(if_fd, I_PUSH, "ip") < 0) { - logger(LOG_ERR, "Can't push IP module: %s", strerror(errno)); + logger(DEBUG_ALWAYS, LOG_ERR, "Can't push IP module: %s", strerror(errno)); return false; } /* Assign ppa according to the unit number returned by tun device */ if(ioctl(if_fd, IF_UNITSEL, (char *) &ppa) < 0) { - logger(LOG_ERR, "Can't set PPA %d: %s", ppa, strerror(errno)); + logger(DEBUG_ALWAYS, LOG_ERR, "Can't set PPA %d: %s", ppa, strerror(errno)); return false; } if(ioctl(ip_fd, I_LINK, if_fd) < 0) { - logger(LOG_ERR, "Can't link TUN device to IP: %s", strerror(errno)); + logger(DEBUG_ALWAYS, LOG_ERR, "Can't link TUN device to IP: %s", strerror(errno)); return false; } @@ -100,12 +112,12 @@ bool setup_device(void) { device_info = "Solaris tun device"; - logger(LOG_INFO, "%s is a %s", device, device_info); + logger(DEBUG_ALWAYS, LOG_INFO, "%s is a %s", device, device_info); return true; } -void close_device(void) { +static void close_device(void) { close(if_fd); close(ip_fd); close(device_fd); @@ -114,11 +126,11 @@ void close_device(void) { free(iface); } -bool read_packet(vpn_packet_t *packet) { +static bool read_packet(vpn_packet_t *packet) { int inlen; if((inlen = read(device_fd, packet->data + 14, MTU - 14)) <= 0) { - logger(LOG_ERR, "Error while reading from %s %s: %s", device_info, + logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info, device, strerror(errno)); return false; } @@ -133,28 +145,29 @@ bool read_packet(vpn_packet_t *packet) { packet->data[13] = 0xDD; break; default: - ifdebug(TRAFFIC) logger(LOG_ERR, + logger(DEBUG_TRAFFIC, LOG_ERR, "Unknown IP version %d while reading packet from %s %s", packet->data[14] >> 4, device_info, device); return false; } + memset(packet->data, 0, 12); packet->len = inlen + 14; device_total_in += packet->len; - ifdebug(TRAFFIC) logger(LOG_DEBUG, "Read packet of %d bytes from %s", packet->len, + logger(DEBUG_TRAFFIC, LOG_DEBUG, "Read packet of %d bytes from %s", packet->len, device_info); return true; } -bool write_packet(vpn_packet_t *packet) { - ifdebug(TRAFFIC) logger(LOG_DEBUG, "Writing packet of %d bytes to %s", +static bool write_packet(vpn_packet_t *packet) { + logger(DEBUG_TRAFFIC, LOG_DEBUG, "Writing packet of %d bytes to %s", packet->len, device_info); if(write(device_fd, packet->data + 14, packet->len - 14) < 0) { - logger(LOG_ERR, "Can't write to %s %s: %s", device_info, + logger(DEBUG_ALWAYS, LOG_ERR, "Can't write to %s %s: %s", device_info, device, strerror(errno)); return false; } @@ -164,8 +177,16 @@ bool write_packet(vpn_packet_t *packet) { return true; } -void dump_device_stats(void) { - logger(LOG_DEBUG, "Statistics for %s %s:", device_info, device); - logger(LOG_DEBUG, " total bytes in: %10"PRIu64, device_total_in); - logger(LOG_DEBUG, " total bytes out: %10"PRIu64, device_total_out); +static void dump_device_stats(void) { + logger(DEBUG_ALWAYS, LOG_DEBUG, "Statistics for %s %s:", device_info, device); + logger(DEBUG_ALWAYS, LOG_DEBUG, " total bytes in: %10"PRIu64, device_total_in); + logger(DEBUG_ALWAYS, LOG_DEBUG, " total bytes out: %10"PRIu64, device_total_out); } + +const devops_t os_devops = { + .setup = setup_device, + .close = close_device, + .read = read_packet, + .write = write_packet, + .dump_stats = dump_device_stats, +}; diff --git a/src/splay_tree.c b/src/splay_tree.c index 135ba06..e7d6dbb 100644 --- a/src/splay_tree.c +++ b/src/splay_tree.c @@ -1,6 +1,6 @@ /* splay_tree.c -- splay tree and linked list convenience - Copyright (C) 2004-2006 Guus Sliepen + Copyright (C) 2004-2012 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 @@ -44,10 +44,10 @@ static splay_node_t *splay_top_down(splay_tree_t *tree, const void *data, int *r rightbottom->left = child; child->parent = rightbottom; rightbottom = child; - + if((root->left = child->right)) child->right->parent = root; - + child->right = root; root->parent = child; @@ -74,7 +74,7 @@ static splay_node_t *splay_top_down(splay_tree_t *tree, const void *data, int *r rightbottom->left = root; root->parent = rightbottom; rightbottom = root; - + root->left = NULL; child->parent = NULL; @@ -88,10 +88,10 @@ static splay_node_t *splay_top_down(splay_tree_t *tree, const void *data, int *r leftbottom->right = child; child->parent = leftbottom; leftbottom = child; - + if((root->right = child->left)) child->left->parent = root; - + child->left = root; root->parent = child; @@ -158,14 +158,14 @@ static splay_node_t *splay_top_down(splay_tree_t *tree, const void *data, int *r return tree->root; } - + static void splay_bottom_up(splay_tree_t *tree, splay_node_t *node) { splay_node_t *parent, *grandparent, *greatgrandparent; while((parent = node->parent)) { if(!(grandparent = parent->parent)) { /* zig */ if(node == parent->left) { - if((parent->left = node->right)) + if((parent->left = node->right)) parent->left->parent = parent; node->right = parent; } else { @@ -326,7 +326,7 @@ splay_node_t *splay_search_closest_node_nosplay(const splay_tree_t *tree, const } else if(c > 0) { if(node->right) node = node->right; - else + else break; } else { break; @@ -384,12 +384,12 @@ splay_node_t *splay_insert(splay_tree_t *tree, void *data) { new = splay_alloc_node(); new->data = data; - + if(result < 0) splay_insert_before(tree, closest, new); else splay_insert_after(tree, closest, new); - } + } return new; } @@ -402,7 +402,7 @@ splay_node_t *splay_insert_node(splay_tree_t *tree, splay_node_t *node) { splay_insert_top(tree, node); else { closest = splay_search_closest_node(tree, node->data, &result); - + if(!result) return NULL; @@ -530,9 +530,7 @@ void splay_delete(splay_tree_t *tree, void *data) { /* Fast tree cleanup */ void splay_delete_tree(splay_tree_t *tree) { - splay_node_t *node, *next; - - for(node = tree->head; node; node = next) { + for(splay_node_t *node = tree->head, *next; node; node = next) { next = node->next; splay_free_node(tree, node); } @@ -543,18 +541,14 @@ void splay_delete_tree(splay_tree_t *tree) { /* Tree walking */ void splay_foreach(const splay_tree_t *tree, splay_action_t action) { - splay_node_t *node, *next; - - for(node = tree->head; node; node = next) { + for(splay_node_t *node = tree->head, *next; node; node = next) { next = node->next; action(node->data); } } void splay_foreach_node(const splay_tree_t *tree, splay_action_t action) { - splay_node_t *node, *next; - - for(node = tree->head; node; node = next) { + for(splay_node_t *node = tree->head, *next; node; node = next) { next = node->next; action(node); } diff --git a/src/splay_tree.h b/src/splay_tree.h index e4af0c4..88d7516 100644 --- a/src/splay_tree.h +++ b/src/splay_tree.h @@ -1,6 +1,6 @@ /* splay_tree.h -- header file for splay_tree.c - Copyright (C) 2004-2006 Guus Sliepen + Copyright (C) 2004-2012 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 @@ -104,4 +104,6 @@ extern splay_node_t *splay_search_closest_greater_node(splay_tree_t *, const voi extern void splay_foreach(const splay_tree_t *, splay_action_t); extern void splay_foreach_node(const splay_tree_t *, splay_action_t); +#define splay_each(type, item, tree) (type *item = (type *)1; item; item = NULL) for(splay_node_t *node = (tree)->head, *next; item = node ? node->data : NULL, next = node ? node->next : NULL, node; node = next) + #endif diff --git a/src/sptps.c b/src/sptps.c new file mode 100644 index 0000000..5a99055 --- /dev/null +++ b/src/sptps.c @@ -0,0 +1,662 @@ +/* + sptps.c -- Simple Peer-to-Peer Security + Copyright (C) 2011-2012 Guus Sliepen , + 2010 Brandon L. Black + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "system.h" + +#include "cipher.h" +#include "crypto.h" +#include "digest.h" +#include "ecdh.h" +#include "ecdsa.h" +#include "logger.h" +#include "prf.h" +#include "sptps.h" + +unsigned int sptps_replaywin = 16; + +/* + Nonce MUST be exchanged first (done) + Signatures MUST be done over both nonces, to guarantee the signature is fresh + Otherwise: if ECDHE key of one side is compromised, it can be reused! + + Add explicit tag to beginning of structure to distinguish the client and server when signing. (done) + + Sign all handshake messages up to ECDHE kex with long-term public keys. (done) + + HMACed KEX finished message to prevent downgrade attacks and prove you have the right key material (done by virtue of ECDSA over the whole ECDHE exchange?) + + Explicit close message needs to be added. + + Maybe do add some alert messages to give helpful error messages? Not more than TLS sends. + + Use counter mode instead of OFB. (done) + + Make sure ECC operations are fixed time (aka prevent side-channel attacks). +*/ + +void sptps_log_quiet(sptps_t *s, int s_errno, const char *format, va_list ap) { +} + +void sptps_log_stderr(sptps_t *s, int s_errno, const char *format, va_list ap) { + vfprintf(stderr, format, ap); + fputc('\n', stderr); +} + +void (*sptps_log)(sptps_t *s, int s_errno, const char *format, va_list ap) = sptps_log_stderr; + +// Log an error message. +static bool error(sptps_t *s, int s_errno, const char *format, ...) { + if(format) { + va_list ap; + va_start(ap, format); + sptps_log(s, s_errno, format, ap); + va_end(ap); + } + + errno = s_errno; + return false; +} + +static void warning(sptps_t *s, const char *format, ...) { + va_list ap; + va_start(ap, format); + sptps_log(s, 0, format, ap); + va_end(ap); +} + +// Send a record (datagram version, accepts all record types, handles encryption and authentication). +static bool send_record_priv_datagram(sptps_t *s, uint8_t type, const char *data, uint16_t len) { + char buffer[len + 23UL]; + + // Create header with sequence number, length and record type + uint32_t seqno = htonl(s->outseqno++); + uint16_t netlen = htons(len); + + memcpy(buffer, &netlen, 2); + memcpy(buffer + 2, &seqno, 4); + buffer[6] = type; + + // Add plaintext (TODO: avoid unnecessary copy) + memcpy(buffer + 7, data, len); + + if(s->outstate) { + // If first handshake has finished, encrypt and HMAC + cipher_set_counter(&s->outcipher, &seqno, sizeof seqno); + if(!cipher_counter_xor(&s->outcipher, buffer + 6, len + 1UL, buffer + 6)) + return false; + + if(!digest_create(&s->outdigest, buffer, len + 7UL, buffer + 7UL + len)) + return false; + + return s->send_data(s->handle, type, buffer + 2, len + 21UL); + } else { + // Otherwise send as plaintext + return s->send_data(s->handle, type, buffer + 2, len + 5UL); + } +} +// Send a record (private version, accepts all record types, handles encryption and authentication). +static bool send_record_priv(sptps_t *s, uint8_t type, const char *data, uint16_t len) { + if(s->datagram) + return send_record_priv_datagram(s, type, data, len); + + char buffer[len + 23UL]; + + // Create header with sequence number, length and record type + uint32_t seqno = htonl(s->outseqno++); + uint16_t netlen = htons(len); + + memcpy(buffer, &seqno, 4); + memcpy(buffer + 4, &netlen, 2); + buffer[6] = type; + + // Add plaintext (TODO: avoid unnecessary copy) + memcpy(buffer + 7, data, len); + + if(s->outstate) { + // If first handshake has finished, encrypt and HMAC + if(!cipher_counter_xor(&s->outcipher, buffer + 4, len + 3UL, buffer + 4)) + return false; + + if(!digest_create(&s->outdigest, buffer, len + 7UL, buffer + 7UL + len)) + return false; + + return s->send_data(s->handle, type, buffer + 4, len + 19UL); + } else { + // Otherwise send as plaintext + return s->send_data(s->handle, type, buffer + 4, len + 3UL); + } +} + +// Send an application record. +bool sptps_send_record(sptps_t *s, uint8_t type, const char *data, uint16_t len) { + // Sanity checks: application cannot send data before handshake is finished, + // and only record types 0..127 are allowed. + if(!s->outstate) + return error(s, EINVAL, "Handshake phase not finished yet"); + + if(type >= SPTPS_HANDSHAKE) + return error(s, EINVAL, "Invalid application record type"); + + return send_record_priv(s, type, data, len); +} + +// Send a Key EXchange record, containing a random nonce and an ECDHE public key. +static bool send_kex(sptps_t *s) { + size_t keylen = ECDH_SIZE; + + // Make room for our KEX message, which we will keep around since send_sig() needs it. + if(s->mykex) + abort(); + s->mykex = realloc(s->mykex, 1 + 32 + keylen); + if(!s->mykex) + return error(s, errno, strerror(errno)); + + // Set version byte to zero. + s->mykex[0] = SPTPS_VERSION; + + // Create a random nonce. + randomize(s->mykex + 1, 32); + + // Create a new ECDH public key. + if(!ecdh_generate_public(&s->ecdh, s->mykex + 1 + 32)) + return false; + + return send_record_priv(s, SPTPS_HANDSHAKE, s->mykex, 1 + 32 + keylen); +} + +// Send a SIGnature record, containing an ECDSA signature over both KEX records. +static bool send_sig(sptps_t *s) { + size_t keylen = ECDH_SIZE; + size_t siglen = ecdsa_size(&s->mykey); + + // Concatenate both KEX messages, plus tag indicating if it is from the connection originator, plus label + char msg[(1 + 32 + keylen) * 2 + 1 + s->labellen]; + char sig[siglen]; + + msg[0] = s->initiator; + memcpy(msg + 1, s->mykex, 1 + 32 + keylen); + memcpy(msg + 1 + 33 + keylen, s->hiskex, 1 + 32 + keylen); + memcpy(msg + 1 + 2 * (33 + keylen), s->label, s->labellen); + + // Sign the result. + if(!ecdsa_sign(&s->mykey, msg, sizeof msg, sig)) + return false; + + // Send the SIG exchange record. + return send_record_priv(s, SPTPS_HANDSHAKE, sig, sizeof sig); +} + +// Generate key material from the shared secret created from the ECDHE key exchange. +static bool generate_key_material(sptps_t *s, const char *shared, size_t len) { + // Initialise cipher and digest structures if necessary + if(!s->outstate) { + bool result + = cipher_open_by_name(&s->incipher, "aes-256-ecb") + && cipher_open_by_name(&s->outcipher, "aes-256-ecb") + && digest_open_by_name(&s->indigest, "sha256", 16) + && digest_open_by_name(&s->outdigest, "sha256", 16); + if(!result) + return false; + } + + // Allocate memory for key material + size_t keylen = digest_keylength(&s->indigest) + digest_keylength(&s->outdigest) + cipher_keylength(&s->incipher) + cipher_keylength(&s->outcipher); + + s->key = realloc(s->key, keylen); + if(!s->key) + return error(s, errno, strerror(errno)); + + // Create the HMAC seed, which is "key expansion" + session label + server nonce + client nonce + char seed[s->labellen + 64 + 13]; + strcpy(seed, "key expansion"); + if(s->initiator) { + memcpy(seed + 13, s->mykex + 1, 32); + memcpy(seed + 45, s->hiskex + 1, 32); + } else { + memcpy(seed + 13, s->hiskex + 1, 32); + memcpy(seed + 45, s->mykex + 1, 32); + } + memcpy(seed + 77, s->label, s->labellen); + + // Use PRF to generate the key material + if(!prf(shared, len, seed, s->labellen + 64 + 13, s->key, keylen)) + return false; + + return true; +} + +// Send an ACKnowledgement record. +static bool send_ack(sptps_t *s) { + return send_record_priv(s, SPTPS_HANDSHAKE, "", 0); +} + +// Receive an ACKnowledgement record. +static bool receive_ack(sptps_t *s, const char *data, uint16_t len) { + if(len) + return error(s, EIO, "Invalid ACK record length"); + + if(s->initiator) { + bool result + = cipher_set_counter_key(&s->incipher, s->key) + && digest_set_key(&s->indigest, s->key + cipher_keylength(&s->incipher), digest_keylength(&s->indigest)); + if(!result) + return false; + } else { + bool result + = cipher_set_counter_key(&s->incipher, s->key + cipher_keylength(&s->outcipher) + digest_keylength(&s->outdigest)) + && digest_set_key(&s->indigest, s->key + cipher_keylength(&s->outcipher) + digest_keylength(&s->outdigest) + cipher_keylength(&s->incipher), digest_keylength(&s->indigest)); + if(!result) + return false; + } + + free(s->key); + s->key = NULL; + s->instate = true; + + return true; +} + +// Receive a Key EXchange record, respond by sending a SIG record. +static bool receive_kex(sptps_t *s, const char *data, uint16_t len) { + // Verify length of the HELLO record + if(len != 1 + 32 + ECDH_SIZE) + return error(s, EIO, "Invalid KEX record length"); + + // Ignore version number for now. + + // Make a copy of the KEX message, send_sig() and receive_sig() need it + if(s->hiskex) + abort(); + s->hiskex = realloc(s->hiskex, len); + if(!s->hiskex) + return error(s, errno, strerror(errno)); + + memcpy(s->hiskex, data, len); + + return send_sig(s); +} + +// Receive a SIGnature record, verify it, if it passed, compute the shared secret and calculate the session keys. +static bool receive_sig(sptps_t *s, const char *data, uint16_t len) { + size_t keylen = ECDH_SIZE; + size_t siglen = ecdsa_size(&s->hiskey); + + // Verify length of KEX record. + if(len != siglen) + return error(s, EIO, "Invalid KEX record length"); + + // Concatenate both KEX messages, plus tag indicating if it is from the connection originator + char msg[(1 + 32 + keylen) * 2 + 1 + s->labellen]; + + msg[0] = !s->initiator; + memcpy(msg + 1, s->hiskex, 1 + 32 + keylen); + memcpy(msg + 1 + 33 + keylen, s->mykex, 1 + 32 + keylen); + memcpy(msg + 1 + 2 * (33 + keylen), s->label, s->labellen); + + // Verify signature. + if(!ecdsa_verify(&s->hiskey, msg, sizeof msg, data)) + return false; + + // Compute shared secret. + char shared[ECDH_SHARED_SIZE]; + if(!ecdh_compute_shared(&s->ecdh, s->hiskex + 1 + 32, shared)) + return false; + + // Generate key material from shared secret. + if(!generate_key_material(s, shared, sizeof shared)) + return false; + + free(s->mykex); + free(s->hiskex); + + s->mykex = NULL; + s->hiskex = NULL; + + // Send cipher change record + if(s->outstate && !send_ack(s)) + return false; + + // TODO: only set new keys after ACK has been set/received + if(s->initiator) { + bool result + = cipher_set_counter_key(&s->outcipher, s->key + cipher_keylength(&s->incipher) + digest_keylength(&s->indigest)) + && digest_set_key(&s->outdigest, s->key + cipher_keylength(&s->incipher) + digest_keylength(&s->indigest) + cipher_keylength(&s->outcipher), digest_keylength(&s->outdigest)); + if(!result) + return false; + } else { + bool result + = cipher_set_counter_key(&s->outcipher, s->key) + && digest_set_key(&s->outdigest, s->key + cipher_keylength(&s->outcipher), digest_keylength(&s->outdigest)); + if(!result) + return false; + } + + return true; +} + +// Force another Key EXchange (for testing purposes). +bool sptps_force_kex(sptps_t *s) { + if(!s->outstate || s->state != SPTPS_SECONDARY_KEX) + return error(s, EINVAL, "Cannot force KEX in current state"); + + s->state = SPTPS_KEX; + return send_kex(s); +} + +// Receive a handshake record. +static bool receive_handshake(sptps_t *s, const char *data, uint16_t len) { + // Only a few states to deal with handshaking. + switch(s->state) { + case SPTPS_SECONDARY_KEX: + // We receive a secondary KEX request, first respond by sending our own. + if(!send_kex(s)) + return false; + case SPTPS_KEX: + // We have sent our KEX request, we expect our peer to sent one as well. + if(!receive_kex(s, data, len)) + return false; + s->state = SPTPS_SIG; + return true; + case SPTPS_SIG: + // If we already sent our secondary public ECDH key, we expect the peer to send his. + if(!receive_sig(s, data, len)) + return false; + if(s->outstate) + s->state = SPTPS_ACK; + else { + s->outstate = true; + if(!receive_ack(s, NULL, 0)) + return false; + s->receive_record(s->handle, SPTPS_HANDSHAKE, NULL, 0); + s->state = SPTPS_SECONDARY_KEX; + } + + return true; + case SPTPS_ACK: + // We expect a handshake message to indicate transition to the new keys. + if(!receive_ack(s, data, len)) + return false; + s->receive_record(s->handle, SPTPS_HANDSHAKE, NULL, 0); + s->state = SPTPS_SECONDARY_KEX; + return true; + // TODO: split ACK into a VERify and ACK? + default: + return error(s, EIO, "Invalid session state"); + } +} + +// Check datagram for valid HMAC +bool sptps_verify_datagram(sptps_t *s, const char *data, size_t len) { + if(!s->instate || len < 21) + return false; + + char buffer[len + 23]; + uint16_t netlen = htons(len - 21); + + memcpy(buffer, &netlen, 2); + memcpy(buffer + 2, data, len); + + return digest_verify(&s->indigest, buffer, len - 14, buffer + len - 14); +} + +// Receive incoming data, datagram version. +static bool sptps_receive_data_datagram(sptps_t *s, const char *data, size_t len) { + if(len < (s->instate ? 21 : 5)) + return error(s, EIO, "Received short packet"); + + uint32_t seqno; + memcpy(&seqno, data, 4); + seqno = ntohl(seqno); + + if(!s->instate) { + if(seqno != s->inseqno) + return error(s, EIO, "Invalid packet seqno: %d != %d", seqno, s->inseqno); + + s->inseqno = seqno + 1; + + uint8_t type = data[4]; + + if(type != SPTPS_HANDSHAKE) + return error(s, EIO, "Application record received before handshake finished"); + + return receive_handshake(s, data + 5, len - 5); + } + + // Replay protection using a sliding window of configurable size. + // s->inseqno is expected sequence number + // seqno is received sequence number + // s->late[] is a circular buffer, a 1 bit means a packet has not been received yet + // The circular buffer contains bits for sequence numbers from s->inseqno - s->replaywin * 8 to (but excluding) s->inseqno. + if(s->replaywin) { + if(seqno != s->inseqno) { + if(seqno >= s->inseqno + s->replaywin * 8) { + // Prevent packets that jump far ahead of the queue from causing many others to be dropped. + if(s->farfuture++ < s->replaywin >> 2) + return error(s, EIO, "Packet is %d seqs in the future, dropped (%u)\n", seqno - s->inseqno, s->farfuture); + + // Unless we have seen lots of them, in which case we consider the others lost. + warning(s, "Lost %d packets\n", seqno - s->inseqno); + memset(s->late, 0, s->replaywin); + } else if (seqno < s->inseqno) { + // If the sequence number is farther in the past than the bitmap goes, or if the packet was already received, drop it. + if((s->inseqno >= s->replaywin * 8 && seqno < s->inseqno - s->replaywin * 8) || !(s->late[(seqno / 8) % s->replaywin] & (1 << seqno % 8))) + return error(s, EIO, "Received late or replayed packet, seqno %d, last received %d\n", seqno, s->inseqno); + } else { + // We missed some packets. Mark them in the bitmap as being late. + for(int i = s->inseqno; i < seqno; i++) + s->late[(i / 8) % s->replaywin] |= 1 << i % 8; + } + } + + // Mark the current packet as not being late. + s->late[(seqno / 8) % s->replaywin] &= ~(1 << seqno % 8); + s->farfuture = 0; + } + + if(seqno > s->inseqno) + s->inseqno = seqno + 1; + + uint16_t netlen = htons(len - 21); + + char buffer[len + 23]; + + memcpy(buffer, &netlen, 2); + memcpy(buffer + 2, data, len); + + memcpy(&seqno, buffer + 2, 4); + + // Check HMAC and decrypt. + if(!digest_verify(&s->indigest, buffer, len - 14, buffer + len - 14)) + return error(s, EIO, "Invalid HMAC"); + + cipher_set_counter(&s->incipher, &seqno, sizeof seqno); + if(!cipher_counter_xor(&s->incipher, buffer + 6, len - 4, buffer + 6)) + return false; + + // Append a NULL byte for safety. + buffer[len - 14] = 0; + + uint8_t type = buffer[6]; + + if(type < SPTPS_HANDSHAKE) { + if(!s->instate) + return error(s, EIO, "Application record received before handshake finished"); + if(!s->receive_record(s->handle, type, buffer + 7, len - 21)) + return false; + } else if(type == SPTPS_HANDSHAKE) { + if(!receive_handshake(s, buffer + 7, len - 21)) + return false; + } else { + return error(s, EIO, "Invalid record type"); + } + + return true; +} + +// Receive incoming data. Check if it contains a complete record, if so, handle it. +bool sptps_receive_data(sptps_t *s, const char *data, size_t len) { + if(s->datagram) + return sptps_receive_data_datagram(s, data, len); + + while(len) { + // First read the 2 length bytes. + if(s->buflen < 6) { + size_t toread = 6 - s->buflen; + if(toread > len) + toread = len; + + memcpy(s->inbuf + s->buflen, data, toread); + + s->buflen += toread; + len -= toread; + data += toread; + + // Exit early if we don't have the full length. + if(s->buflen < 6) + return true; + + // Decrypt the length bytes + + if(s->instate) { + if(!cipher_counter_xor(&s->incipher, s->inbuf + 4, 2, &s->reclen)) + return false; + } else { + memcpy(&s->reclen, s->inbuf + 4, 2); + } + + s->reclen = ntohs(s->reclen); + + // If we have the length bytes, ensure our buffer can hold the whole request. + s->inbuf = realloc(s->inbuf, s->reclen + 23UL); + if(!s->inbuf) + return error(s, errno, strerror(errno)); + + // Add sequence number. + uint32_t seqno = htonl(s->inseqno++); + memcpy(s->inbuf, &seqno, 4); + + // Exit early if we have no more data to process. + if(!len) + return true; + } + + // Read up to the end of the record. + size_t toread = s->reclen + (s->instate ? 23UL : 7UL) - s->buflen; + if(toread > len) + toread = len; + + memcpy(s->inbuf + s->buflen, data, toread); + s->buflen += toread; + len -= toread; + data += toread; + + // If we don't have a whole record, exit. + if(s->buflen < s->reclen + (s->instate ? 23UL : 7UL)) + return true; + + // Check HMAC and decrypt. + if(s->instate) { + if(!digest_verify(&s->indigest, s->inbuf, s->reclen + 7UL, s->inbuf + s->reclen + 7UL)) + return error(s, EIO, "Invalid HMAC"); + + if(!cipher_counter_xor(&s->incipher, s->inbuf + 6UL, s->reclen + 1UL, s->inbuf + 6UL)) + return false; + } + + // Append a NULL byte for safety. + s->inbuf[s->reclen + 7UL] = 0; + + uint8_t type = s->inbuf[6]; + + if(type < SPTPS_HANDSHAKE) { + if(!s->instate) + return error(s, EIO, "Application record received before handshake finished"); + if(!s->receive_record(s->handle, type, s->inbuf + 7, s->reclen)) + return false; + } else if(type == SPTPS_HANDSHAKE) { + if(!receive_handshake(s, s->inbuf + 7, s->reclen)) + return false; + } else { + return error(s, EIO, "Invalid record type"); + } + + s->buflen = 4; + } + + return true; +} + +// Start a SPTPS session. +bool sptps_start(sptps_t *s, void *handle, bool initiator, bool datagram, ecdsa_t mykey, ecdsa_t hiskey, const char *label, size_t labellen, send_data_t send_data, receive_record_t receive_record) { + // Initialise struct sptps + memset(s, 0, sizeof *s); + + s->handle = handle; + s->initiator = initiator; + s->datagram = datagram; + s->mykey = mykey; + s->hiskey = hiskey; + s->replaywin = sptps_replaywin; + if(s->replaywin) { + s->late = malloc(s->replaywin); + if(!s->late) + return error(s, errno, strerror(errno)); + } + + s->label = malloc(labellen); + if(!s->label) + return error(s, errno, strerror(errno)); + + if(!datagram) { + s->inbuf = malloc(7); + if(!s->inbuf) + return error(s, errno, strerror(errno)); + s->buflen = 4; + memset(s->inbuf, 0, 4); + } + + memcpy(s->label, label, labellen); + s->labellen = labellen; + + s->send_data = send_data; + s->receive_record = receive_record; + + // Do first KEX immediately + s->state = SPTPS_KEX; + return send_kex(s); +} + +// Stop a SPTPS session. +bool sptps_stop(sptps_t *s) { + // Clean up any resources. + cipher_close(&s->incipher); + cipher_close(&s->outcipher); + digest_close(&s->indigest); + digest_close(&s->outdigest); + ecdh_free(&s->ecdh); + free(s->inbuf); + free(s->mykex); + free(s->hiskex); + free(s->key); + free(s->label); + free(s->late); + memset(s, 0, sizeof *s); + return true; +} diff --git a/src/sptps.h b/src/sptps.h new file mode 100644 index 0000000..a19be97 --- /dev/null +++ b/src/sptps.h @@ -0,0 +1,94 @@ +/* + sptps.h -- Simple Peer-to-Peer Security + Copyright (C) 2011-2012 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#ifndef __SPTPS_H__ +#define __SPTPS_H__ + +#include "system.h" + +#include "cipher.h" +#include "digest.h" +#include "ecdh.h" +#include "ecdsa.h" + +#define SPTPS_VERSION 0 + +// Record types +#define SPTPS_HANDSHAKE 128 // Key exchange and authentication +#define SPTPS_ALERT 129 // Warning or error messages +#define SPTPS_CLOSE 130 // Application closed the connection + +// Key exchange states +#define SPTPS_KEX 0 // Waiting for the first Key EXchange record +#define SPTPS_SECONDARY_KEX 1 // Ready to receive a secondary Key EXchange record +#define SPTPS_SIG 2 // Waiting for a SIGnature record +#define SPTPS_ACK 3 // Waiting for an ACKnowledgement record + +typedef bool (*send_data_t)(void *handle, uint8_t type, const char *data, size_t len); +typedef bool (*receive_record_t)(void *handle, uint8_t type, const char *data, uint16_t len); + +typedef struct sptps { + bool initiator; + bool datagram; + int state; + + char *inbuf; + size_t buflen; + uint16_t reclen; + + bool instate; + cipher_t incipher; + digest_t indigest; + uint32_t inseqno; + unsigned int replaywin; + unsigned int farfuture; + char *late; + + bool outstate; + cipher_t outcipher; + digest_t outdigest; + uint32_t outseqno; + + ecdsa_t mykey; + ecdsa_t hiskey; + ecdh_t ecdh; + + char *mykex; + char *hiskex; + char *key; + char *label; + size_t labellen; + + void *handle; + send_data_t send_data; + receive_record_t receive_record; +} sptps_t; + +extern unsigned int sptps_replaywin; +extern void sptps_log_quiet(sptps_t *s, int s_errno, const char *format, va_list ap); +extern void sptps_log_stderr(sptps_t *s, int s_errno, const char *format, va_list ap); +extern void (*sptps_log)(sptps_t *s, int s_errno, const char *format, va_list ap); +extern bool sptps_start(sptps_t *s, void *handle, bool initiator, bool datagram, ecdsa_t mykey, ecdsa_t hiskey, const char *label, size_t labellen, send_data_t send_data, receive_record_t receive_record); +extern bool sptps_stop(sptps_t *s); +extern bool sptps_send_record(sptps_t *s, uint8_t type, const char *data, uint16_t len); +extern bool sptps_receive_data(sptps_t *s, const char *data, size_t len); +extern bool sptps_force_kex(sptps_t *s); +extern bool sptps_verify_datagram(sptps_t *s, const char *data, size_t len); + +#endif diff --git a/src/sptps_test.c b/src/sptps_test.c new file mode 100644 index 0000000..7aafbbe --- /dev/null +++ b/src/sptps_test.c @@ -0,0 +1,194 @@ +/* + sptps_test.c -- Simple Peer-to-Peer Security test program + Copyright (C) 2011-2012 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "system.h" + +#include "crypto.h" +#include "ecdsa.h" +#include "sptps.h" +#include "utils.h" + +// Symbols necessary to link with logger.o +bool send_request(void *c, const char *msg, ...) { return false; } +struct list_t *connection_list = NULL; +bool send_meta(void *c, const char *msg , int len) { return false; } +char *logfilename = NULL; + +ecdsa_t mykey, hiskey; + +static bool send_data(void *handle, uint8_t type, const char *data, size_t len) { + char hex[len * 2 + 1]; + bin2hex(data, hex, len); + fprintf(stderr, "Sending %d bytes of data:\n%s\n", (int)len, hex); + const int *sock = handle; + if(send(*sock, data, len, 0) != len) + return false; + return true; +} + +static bool receive_record(void *handle, uint8_t type, const char *data, uint16_t len) { + fprintf(stderr, "Received type %d record of %hu bytes:\n", type, len); + fwrite(data, len, 1, stdout); + return true; +} + +int main(int argc, char *argv[]) { + bool initiator = false; + bool datagram = false; + + if(argc > 1 && !strcmp(argv[1], "-d")) { + datagram = true; + argc--; + argv++; + } + + if(argc < 4) { + fprintf(stderr, "Usage: %s [-d] my_ecdsa_key_file his_ecdsa_key_file [host] port\n", argv[0]); + return 1; + } + + if(argc > 4) + initiator = true; + +#ifdef HAVE_MINGW + static struct WSAData wsa_state; + if(WSAStartup(MAKEWORD(2, 2), &wsa_state)) + return 1; +#endif + + struct addrinfo *ai, hint; + memset(&hint, 0, sizeof hint); + + hint.ai_family = AF_UNSPEC; + hint.ai_socktype = SOCK_STREAM; + hint.ai_protocol = IPPROTO_TCP; + hint.ai_flags = initiator ? 0 : AI_PASSIVE; + + if(getaddrinfo(initiator ? argv[3] : NULL, initiator ? argv[4] : argv[3], &hint, &ai) || !ai) { + fprintf(stderr, "getaddrinfo() failed: %s\n", strerror(errno)); + return 1; + } + + int sock = socket(ai->ai_family, SOCK_STREAM, IPPROTO_TCP); + if(sock < 0) { + fprintf(stderr, "Could not create socket: %s\n", strerror(errno)); + return 1; + } + + int one = 1; + setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void *)&one, sizeof one); + + if(initiator) { + if(connect(sock, ai->ai_addr, ai->ai_addrlen)) { + fprintf(stderr, "Could not connect to peer: %s\n", strerror(errno)); + return 1; + } + fprintf(stderr, "Connected\n"); + } else { + if(bind(sock, ai->ai_addr, ai->ai_addrlen)) { + fprintf(stderr, "Could not bind socket: %s\n", strerror(errno)); + return 1; + } + if(listen(sock, 1)) { + fprintf(stderr, "Could not listen on socket: %s\n", strerror(errno)); + return 1; + } + fprintf(stderr, "Listening...\n"); + + sock = accept(sock, NULL, NULL); + if(sock < 0) { + fprintf(stderr, "Could not accept connection: %s\n", strerror(errno)); + return 1; + } + + fprintf(stderr, "Connected\n"); + } + + crypto_init(); + + FILE *fp = fopen(argv[1], "r"); + if(!ecdsa_read_pem_private_key(&mykey, fp)) + return 1; + fclose(fp); + + fp = fopen(argv[2], "r"); + if(!ecdsa_read_pem_public_key(&hiskey, fp)) + return 1; + fclose(fp); + + fprintf(stderr, "Keys loaded\n"); + + sptps_t s; + if(!sptps_start(&s, &sock, initiator, datagram, mykey, hiskey, "sptps_test", 10, send_data, receive_record)) + return 1; + + while(true) { + char buf[65535] = ""; + + fd_set fds; + FD_ZERO(&fds); +#ifndef HAVE_MINGW + FD_SET(0, &fds); +#endif + FD_SET(sock, &fds); + if(select(sock + 1, &fds, NULL, NULL, NULL) <= 0) + return 1; + + if(FD_ISSET(0, &fds)) { + ssize_t len = read(0, buf, sizeof buf); + if(len < 0) { + fprintf(stderr, "Could not read from stdin: %s\n", strerror(errno)); + return 1; + } + if(len == 0) + break; + if(buf[0] == '^') + sptps_send_record(&s, SPTPS_HANDSHAKE, NULL, 0); + else if(buf[0] == '$') { + sptps_force_kex(&s); + if(len > 1) + sptps_send_record(&s, 0, buf, len); + } else + if(!sptps_send_record(&s, buf[0] == '!' ? 1 : 0, buf, buf[0] == '\n' ? 0 : buf[0] == '*' ? sizeof buf : len)) + return 1; + } + + if(FD_ISSET(sock, &fds)) { + ssize_t len = recv(sock, buf, sizeof buf, 0); + if(len < 0) { + fprintf(stderr, "Could not read from socket: %s\n", strerror(errno)); + return 1; + } + if(len == 0) { + fprintf(stderr, "Connection terminated by peer.\n"); + break; + } + char hex[len * 2 + 1]; + bin2hex(buf, hex, len); + fprintf(stderr, "Received %d bytes of data:\n%s\n", (int)len, hex); + if(!sptps_receive_data(&s, buf, len)) + return 1; + } + } + + if(!sptps_stop(&s)) + return 1; + + return 0; +} diff --git a/src/subnet.c b/src/subnet.c index bf1bda2..4b6c068 100644 --- a/src/subnet.c +++ b/src/subnet.c @@ -1,6 +1,6 @@ /* subnet.c -- handle subnet lookups and lists - Copyright (C) 2000-2010 Guus Sliepen , + Copyright (C) 2000-2012 Guus Sliepen , 2000-2005 Ivo Timmermans This program is free software; you can redistribute it and/or modify @@ -23,6 +23,7 @@ #include "splay_tree.h" #include "control_common.h" #include "device.h" +#include "hash.h" #include "logger.h" #include "net.h" #include "netutl.h" @@ -38,109 +39,14 @@ splay_tree_t *subnet_tree; /* Subnet lookup cache */ -static ipv4_t cache_ipv4_address[2]; -static subnet_t *cache_ipv4_subnet[2]; -static bool cache_ipv4_valid[2]; -static int cache_ipv4_slot; - -static ipv6_t cache_ipv6_address[2]; -static subnet_t *cache_ipv6_subnet[2]; -static bool cache_ipv6_valid[2]; -static int cache_ipv6_slot; - -static mac_t cache_mac_address[2]; -static subnet_t *cache_mac_subnet[2]; -static bool cache_mac_valid[2]; -static int cache_mac_slot; +hash_t *ipv4_cache; +hash_t *ipv6_cache; +hash_t *mac_cache; void subnet_cache_flush(void) { - cache_ipv4_valid[0] = cache_ipv4_valid[1] = false; - cache_ipv6_valid[0] = cache_ipv6_valid[1] = false; - cache_mac_valid[0] = cache_mac_valid[1] = false; -} - -/* Subnet comparison */ - -static int subnet_compare_mac(const subnet_t *a, const subnet_t *b) { - int result; - - result = memcmp(&a->net.mac.address, &b->net.mac.address, sizeof a->net.mac.address); - - if(result) - return result; - - result = a->weight - b->weight; - - if(result || !a->owner || !b->owner) - return result; - - return strcmp(a->owner->name, b->owner->name); -} - -static int subnet_compare_ipv4(const subnet_t *a, const subnet_t *b) { - int result; - - result = b->net.ipv4.prefixlength - a->net.ipv4.prefixlength; - - if(result) - return result; - - result = memcmp(&a->net.ipv4.address, &b->net.ipv4.address, sizeof(ipv4_t)); - - if(result) - return result; - - result = a->weight - b->weight; - - if(result || !a->owner || !b->owner) - return result; - - return strcmp(a->owner->name, b->owner->name); -} - -static int subnet_compare_ipv6(const subnet_t *a, const subnet_t *b) { - int result; - - result = b->net.ipv6.prefixlength - a->net.ipv6.prefixlength; - - if(result) - return result; - - result = memcmp(&a->net.ipv6.address, &b->net.ipv6.address, sizeof(ipv6_t)); - - if(result) - return result; - - result = a->weight - b->weight; - - if(result || !a->owner || !b->owner) - return result; - - return strcmp(a->owner->name, b->owner->name); -} - -int subnet_compare(const subnet_t *a, const subnet_t *b) { - int result; - - result = a->type - b->type; - - if(result) - return result; - - switch (a->type) { - case SUBNET_MAC: - return subnet_compare_mac(a, b); - case SUBNET_IPV4: - return subnet_compare_ipv4(a, b); - case SUBNET_IPV6: - return subnet_compare_ipv6(a, b); - default: - logger(LOG_ERR, "subnet_compare() was called with unknown subnet type %d, exitting!", - a->type); - exit(0); - } - - return 0; + hash_clear(ipv4_cache); + hash_clear(ipv6_cache); + hash_clear(mac_cache); } /* Initialising trees */ @@ -148,11 +54,17 @@ int subnet_compare(const subnet_t *a, const subnet_t *b) { void init_subnets(void) { subnet_tree = splay_alloc_tree((splay_compare_t) subnet_compare, (splay_action_t) free_subnet); - subnet_cache_flush(); + ipv4_cache = hash_alloc(0x100, sizeof(ipv4_t)); + ipv6_cache = hash_alloc(0x100, sizeof(ipv6_t)); + mac_cache = hash_alloc(0x100, sizeof(mac_t)); } void exit_subnets(void) { splay_delete_tree(subnet_tree); + + hash_free(ipv4_cache); + hash_free(ipv6_cache); + hash_free(mac_cache); } splay_tree_t *new_subnet_tree(void) { @@ -191,139 +103,6 @@ void subnet_del(node_t *n, subnet_t *subnet) { subnet_cache_flush(); } -/* Ascii representation of subnets */ - -bool str2net(subnet_t *subnet, const char *subnetstr) { - int i, l; - uint16_t x[8]; - int weight = 10; - - if(sscanf(subnetstr, "%hu.%hu.%hu.%hu/%d#%d", - &x[0], &x[1], &x[2], &x[3], &l, &weight) >= 5) { - if(l < 0 || l > 32) - return false; - - subnet->type = SUBNET_IPV4; - subnet->net.ipv4.prefixlength = l; - subnet->weight = weight; - - for(i = 0; i < 4; i++) { - if(x[i] > 255) - return false; - subnet->net.ipv4.address.x[i] = x[i]; - } - - return true; - } - - if(sscanf(subnetstr, "%hx:%hx:%hx:%hx:%hx:%hx:%hx:%hx/%d#%d", - &x[0], &x[1], &x[2], &x[3], &x[4], &x[5], &x[6], &x[7], - &l, &weight) >= 9) { - if(l < 0 || l > 128) - return false; - - subnet->type = SUBNET_IPV6; - subnet->net.ipv6.prefixlength = l; - subnet->weight = weight; - - for(i = 0; i < 8; i++) - subnet->net.ipv6.address.x[i] = htons(x[i]); - - return true; - } - - if(sscanf(subnetstr, "%hu.%hu.%hu.%hu#%d", &x[0], &x[1], &x[2], &x[3], &weight) >= 4) { - subnet->type = SUBNET_IPV4; - subnet->net.ipv4.prefixlength = 32; - subnet->weight = weight; - - for(i = 0; i < 4; i++) { - if(x[i] > 255) - return false; - subnet->net.ipv4.address.x[i] = x[i]; - } - - return true; - } - - if(sscanf(subnetstr, "%hx:%hx:%hx:%hx:%hx:%hx:%hx:%hx#%d", - &x[0], &x[1], &x[2], &x[3], &x[4], &x[5], &x[6], &x[7], &weight) >= 8) { - subnet->type = SUBNET_IPV6; - subnet->net.ipv6.prefixlength = 128; - subnet->weight = weight; - - for(i = 0; i < 8; i++) - subnet->net.ipv6.address.x[i] = htons(x[i]); - - return true; - } - - if(sscanf(subnetstr, "%hx:%hx:%hx:%hx:%hx:%hx#%d", - &x[0], &x[1], &x[2], &x[3], &x[4], &x[5], &weight) >= 6) { - subnet->type = SUBNET_MAC; - subnet->weight = weight; - - for(i = 0; i < 6; i++) - subnet->net.mac.address.x[i] = x[i]; - - return true; - } - - return false; -} - -bool net2str(char *netstr, int len, const subnet_t *subnet) { - if(!netstr || !subnet) { - logger(LOG_ERR, "net2str() was called with netstr=%p, subnet=%p!", netstr, subnet); - return false; - } - - switch (subnet->type) { - case SUBNET_MAC: - snprintf(netstr, len, "%hx:%hx:%hx:%hx:%hx:%hx#%d", - subnet->net.mac.address.x[0], - subnet->net.mac.address.x[1], - subnet->net.mac.address.x[2], - subnet->net.mac.address.x[3], - subnet->net.mac.address.x[4], - subnet->net.mac.address.x[5], - subnet->weight); - break; - - case SUBNET_IPV4: - snprintf(netstr, len, "%hu.%hu.%hu.%hu/%d#%d", - subnet->net.ipv4.address.x[0], - subnet->net.ipv4.address.x[1], - subnet->net.ipv4.address.x[2], - subnet->net.ipv4.address.x[3], - subnet->net.ipv4.prefixlength, - subnet->weight); - break; - - case SUBNET_IPV6: - snprintf(netstr, len, "%hx:%hx:%hx:%hx:%hx:%hx:%hx:%hx/%d#%d", - ntohs(subnet->net.ipv6.address.x[0]), - ntohs(subnet->net.ipv6.address.x[1]), - ntohs(subnet->net.ipv6.address.x[2]), - ntohs(subnet->net.ipv6.address.x[3]), - ntohs(subnet->net.ipv6.address.x[4]), - ntohs(subnet->net.ipv6.address.x[5]), - ntohs(subnet->net.ipv6.address.x[6]), - ntohs(subnet->net.ipv6.address.x[7]), - subnet->net.ipv6.prefixlength, - subnet->weight); - break; - - default: - logger(LOG_ERR, - "net2str() was called with unknown subnet type %d, exiting!", - subnet->type); - exit(0); - } - - return true; -} - /* Subnet lookup routines */ subnet_t *lookup_subnet(const node_t *owner, const subnet_t *subnet) { @@ -331,26 +110,16 @@ subnet_t *lookup_subnet(const node_t *owner, const subnet_t *subnet) { } subnet_t *lookup_subnet_mac(const node_t *owner, const mac_t *address) { - subnet_t *p, *r = NULL; - splay_node_t *n; - int i; + subnet_t *r = NULL; // Check if this address is cached - 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]; - } + if((r = hash_search(mac_cache, address))) + return r; // Search all subnets for a matching one - for(n = owner ? owner->subnet_tree->head : subnet_tree->head; n; n = n->next) { - p = n->data; - + for splay_each(subnet_t, p, owner ? owner->subnet_tree : subnet_tree) { if(!p || p->type != SUBNET_MAC) continue; @@ -363,33 +132,23 @@ subnet_t *lookup_subnet_mac(const node_t *owner, const mac_t *address) { // Cache the result - cache_mac_slot = !cache_mac_slot; - memcpy(&cache_mac_address[cache_mac_slot], address, sizeof *address); - cache_mac_subnet[cache_mac_slot] = r; - cache_mac_valid[cache_mac_slot] = true; + if(r) + hash_insert(mac_cache, address, r); return r; } subnet_t *lookup_subnet_ipv4(const ipv4_t *address) { - subnet_t *p, *r = NULL; - splay_node_t *n; - int i; + subnet_t *r = NULL; // Check if this address is cached - for(i = 0; i < 2; i++) { - if(!cache_ipv4_valid[i]) - continue; - if(!memcmp(address, &cache_ipv4_address[i], sizeof *address)) - return cache_ipv4_subnet[i]; - } + if((r = hash_search(ipv4_cache, address))) + return r; // Search all subnets for a matching one - for(n = subnet_tree->head; n; n = n->next) { - p = n->data; - + for splay_each(subnet_t, p, subnet_tree) { if(!p || p->type != SUBNET_IPV4) continue; @@ -402,33 +161,23 @@ subnet_t *lookup_subnet_ipv4(const ipv4_t *address) { // Cache the result - cache_ipv4_slot = !cache_ipv4_slot; - memcpy(&cache_ipv4_address[cache_ipv4_slot], address, sizeof *address); - cache_ipv4_subnet[cache_ipv4_slot] = r; - cache_ipv4_valid[cache_ipv4_slot] = true; + if(r) + hash_insert(ipv4_cache, address, r); return r; } subnet_t *lookup_subnet_ipv6(const ipv6_t *address) { - subnet_t *p, *r = NULL; - splay_node_t *n; - int i; + subnet_t *r = NULL; // Check if this address is cached - for(i = 0; i < 2; i++) { - if(!cache_ipv6_valid[i]) - continue; - if(!memcmp(address, &cache_ipv6_address[i], sizeof *address)) - return cache_ipv6_subnet[i]; - } + if((r = hash_search(ipv6_cache, address))) + return r; // Search all subnets for a matching one - for(n = subnet_tree->head; n; n = n->next) { - p = n->data; - + for splay_each(subnet_t, p, subnet_tree) { if(!p || p->type != SUBNET_IPV6) continue; @@ -441,24 +190,20 @@ subnet_t *lookup_subnet_ipv6(const ipv6_t *address) { // Cache the result - cache_ipv6_slot = !cache_ipv6_slot; - memcpy(&cache_ipv6_address[cache_ipv6_slot], address, sizeof *address); - cache_ipv6_subnet[cache_ipv6_slot] = r; - cache_ipv6_valid[cache_ipv6_slot] = true; + if(r) + hash_insert(ipv6_cache, address, r); return r; } void subnet_update(node_t *owner, subnet_t *subnet, bool up) { - splay_node_t *node; - int i; - char *envp[9] = {NULL}; char netstr[MAXNETSTR]; char *name, *address, *port; char empty[] = ""; // Prepare environment variables to be passed to the script + char *envp[9] = {NULL}; xasprintf(&envp[0], "NETNAME=%s", netname ? : ""); xasprintf(&envp[1], "DEVICE=%s", device ? : ""); xasprintf(&envp[2], "INTERFACE=%s", iface ? : ""); @@ -469,15 +214,17 @@ void subnet_update(node_t *owner, subnet_t *subnet, bool up) { // 4 and 5 are reserved for SUBNET and WEIGHT xasprintf(&envp[6], "REMOTEADDRESS=%s", address); xasprintf(&envp[7], "REMOTEPORT=%s", port); + free(port); + free(address); } name = up ? "subnet-up" : "subnet-down"; if(!subnet) { - for(node = owner->subnet_tree->head; node; node = node->next) { - subnet = node->data; + for splay_each(subnet_t, subnet, owner->subnet_tree) { 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, '#'); if(weight) @@ -512,20 +259,18 @@ void subnet_update(node_t *owner, subnet_t *subnet, bool up) { } } - for(i = 0; envp[i] && i < 8; i++) + for(int i = 0; envp[i] && i < 8; i++) free(envp[i]); } bool dump_subnets(connection_t *c) { - char netstr[MAXNETSTR]; - subnet_t *subnet; - splay_node_t *node; + for splay_each(subnet_t, subnet, subnet_tree) { + char netstr[MAXNETSTR]; - for(node = subnet_tree->head; node; node = node->next) { - subnet = node->data; if(!net2str(netstr, sizeof netstr, subnet)) continue; - send_request(c, "%d %d %s owner %s", + + send_request(c, "%d %d %s %s", CONTROL, REQ_DUMP_SUBNETS, netstr, subnet->owner->name); } diff --git a/src/subnet.h b/src/subnet.h index f22e6d5..9fd95b6 100644 --- a/src/subnet.h +++ b/src/subnet.h @@ -1,6 +1,6 @@ /* subnet.h -- header for subnet.c - Copyright (C) 2000-2009 Guus Sliepen , + Copyright (C) 2000-2012 Guus Sliepen , 2000-2005 Ivo Timmermans This program is free software; you can redistribute it and/or modify @@ -27,7 +27,7 @@ typedef enum subnet_type_t { SUBNET_MAC = 0, SUBNET_IPV4, SUBNET_IPV6, - SUBNET_TYPES /* Guardian */ + SUBNET_TYPES /* Guardian */ } subnet_type_t; typedef struct subnet_mac_t { @@ -47,11 +47,11 @@ typedef struct subnet_ipv6_t { #include "node.h" typedef struct subnet_t { - struct node_t *owner; /* the owner of this subnet */ + struct node_t *owner; /* the owner of this subnet */ - subnet_type_t type; /* subnet type (IPv4? IPv6? MAC? something even weirder?) */ - time_t expires; /* expiry time */ - int weight; /* weight (higher value is higher priority) */ + subnet_type_t type; /* subnet type (IPv4? IPv6? MAC? something even weirder?) */ + time_t expires; /* expiry time */ + int weight; /* weight (higher value is higher priority) */ /* And now for the actual subnet: */ @@ -76,6 +76,10 @@ extern void free_subnet_tree(splay_tree_t *); extern void subnet_add(struct node_t *, subnet_t *); extern void subnet_del(struct node_t *, subnet_t *); extern void subnet_update(struct node_t *, subnet_t *, bool); +extern int maskcmp(const void *, const void *, int); +extern void maskcpy(void *, const void *, int, int); +extern void mask(void *, int, int); +extern bool maskcheck(const void *, int, int); 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 *); @@ -85,4 +89,4 @@ extern subnet_t *lookup_subnet_ipv6(const ipv6_t *); extern bool dump_subnets(struct connection_t *); extern void subnet_cache_flush(void); -#endif /* __TINC_SUBNET_H__ */ +#endif /* __TINC_SUBNET_H__ */ diff --git a/src/subnet_parse.c b/src/subnet_parse.c new file mode 100644 index 0000000..f980180 --- /dev/null +++ b/src/subnet_parse.c @@ -0,0 +1,382 @@ +/* + subnet_parse.c -- handle subnet parsing + Copyright (C) 2000-2012 Guus Sliepen , + 2000-2005 Ivo Timmermans + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "system.h" + +#include "logger.h" +#include "net.h" +#include "netutl.h" +#include "subnet.h" +#include "utils.h" +#include "xalloc.h" + +/* Subnet mask handling */ + +int maskcmp(const void *va, const void *vb, int masklen) { + int i, m, result; + const char *a = va; + const char *b = vb; + + for(m = masklen, i = 0; m >= 8; m -= 8, i++) { + result = a[i] - b[i]; + if(result) + return result; + } + + if(m) + return (a[i] & (0x100 - (1 << (8 - m)))) - + (b[i] & (0x100 - (1 << (8 - m)))); + + return 0; +} + +void mask(void *va, int masklen, int len) { + int i; + char *a = va; + + i = masklen / 8; + masklen %= 8; + + if(masklen) + a[i++] &= (0x100 - (1 << (8 - masklen))); + + for(; i < len; i++) + a[i] = 0; +} + +void maskcpy(void *va, const void *vb, int masklen, int len) { + int i, m; + char *a = va; + const char *b = vb; + + for(m = masklen, i = 0; m >= 8; m -= 8, i++) + a[i] = b[i]; + + if(m) { + a[i] = b[i] & (0x100 - (1 << (8 - m))); + i++; + } + + for(; i < len; i++) + a[i] = 0; +} + +bool maskcheck(const void *va, int masklen, int len) { + int i; + const char *a = va; + + i = masklen / 8; + masklen %= 8; + + if(masklen && a[i++] & (0xff >> masklen)) + return false; + + for(; i < len; i++) + if(a[i] != 0) + return false; + + return true; +} + +/* Subnet comparison */ + +static int subnet_compare_mac(const subnet_t *a, const subnet_t *b) { + int result; + + result = memcmp(&a->net.mac.address, &b->net.mac.address, sizeof a->net.mac.address); + + if(result) + return result; + + result = a->weight - b->weight; + + if(result || !a->owner || !b->owner) + return result; + + return strcmp(a->owner->name, b->owner->name); +} + +static int subnet_compare_ipv4(const subnet_t *a, const subnet_t *b) { + int result; + + result = b->net.ipv4.prefixlength - a->net.ipv4.prefixlength; + + if(result) + return result; + + result = memcmp(&a->net.ipv4.address, &b->net.ipv4.address, sizeof(ipv4_t)); + + if(result) + return result; + + result = a->weight - b->weight; + + if(result || !a->owner || !b->owner) + return result; + + return strcmp(a->owner->name, b->owner->name); +} + +static int subnet_compare_ipv6(const subnet_t *a, const subnet_t *b) { + int result; + + result = b->net.ipv6.prefixlength - a->net.ipv6.prefixlength; + + if(result) + return result; + + result = memcmp(&a->net.ipv6.address, &b->net.ipv6.address, sizeof(ipv6_t)); + + if(result) + return result; + + result = a->weight - b->weight; + + if(result || !a->owner || !b->owner) + return result; + + return strcmp(a->owner->name, b->owner->name); +} + +int subnet_compare(const subnet_t *a, const subnet_t *b) { + int result; + + result = a->type - b->type; + + if(result) + return result; + + switch (a->type) { + case SUBNET_MAC: + return subnet_compare_mac(a, b); + case SUBNET_IPV4: + return subnet_compare_ipv4(a, b); + case SUBNET_IPV6: + return subnet_compare_ipv6(a, b); + default: + logger(DEBUG_ALWAYS, LOG_ERR, "subnet_compare() was called with unknown subnet type %d, exitting!", a->type); + exit(1); + } + + return 0; +} + +/* Ascii representation of subnets */ + +bool str2net(subnet_t *subnet, const char *subnetstr) { + int i, l; + uint16_t x[8]; + int weight = 10; + + if(sscanf(subnetstr, "%hu.%hu.%hu.%hu/%d#%d", + &x[0], &x[1], &x[2], &x[3], &l, &weight) >= 5) { + if(l < 0 || l > 32) + return false; + + subnet->type = SUBNET_IPV4; + subnet->net.ipv4.prefixlength = l; + subnet->weight = weight; + + for(int i = 0; i < 4; i++) { + if(x[i] > 255) + return false; + subnet->net.ipv4.address.x[i] = x[i]; + } + + return true; + } + + if(sscanf(subnetstr, "%hx:%hx:%hx:%hx:%hx:%hx:%hx:%hx/%d#%d", + &x[0], &x[1], &x[2], &x[3], &x[4], &x[5], &x[6], &x[7], + &l, &weight) >= 9) { + if(l < 0 || l > 128) + return false; + + subnet->type = SUBNET_IPV6; + subnet->net.ipv6.prefixlength = l; + subnet->weight = weight; + + for(i = 0; i < 8; i++) + subnet->net.ipv6.address.x[i] = htons(x[i]); + + return true; + } + + if(sscanf(subnetstr, "%hu.%hu.%hu.%hu#%d", &x[0], &x[1], &x[2], &x[3], &weight) >= 4) { + subnet->type = SUBNET_IPV4; + subnet->net.ipv4.prefixlength = 32; + subnet->weight = weight; + + for(i = 0; i < 4; i++) { + if(x[i] > 255) + return false; + subnet->net.ipv4.address.x[i] = x[i]; + } + + return true; + } + + if(sscanf(subnetstr, "%hx:%hx:%hx:%hx:%hx:%hx:%hx:%hx#%d", + &x[0], &x[1], &x[2], &x[3], &x[4], &x[5], &x[6], &x[7], &weight) >= 8) { + subnet->type = SUBNET_IPV6; + subnet->net.ipv6.prefixlength = 128; + subnet->weight = weight; + + for(i = 0; i < 8; i++) + subnet->net.ipv6.address.x[i] = htons(x[i]); + + return true; + } + + if(sscanf(subnetstr, "%hx:%hx:%hx:%hx:%hx:%hx#%d", + &x[0], &x[1], &x[2], &x[3], &x[4], &x[5], &weight) >= 6) { + subnet->type = SUBNET_MAC; + subnet->weight = weight; + + for(i = 0; i < 6; i++) + subnet->net.mac.address.x[i] = x[i]; + + return true; + } + + // IPv6 short form + if(strstr(subnetstr, "::")) { + const char *p; + char *q; + int colons = 0; + + // Count number of colons + for(p = subnetstr; *p; p++) + if(*p == ':') + colons++; + + if(colons > 7) + return false; + + // Scan numbers before the double colon + p = subnetstr; + for(i = 0; i < colons; i++) { + if(*p == ':') + break; + x[i] = strtoul(p, &q, 0x10); + if(!q || p == q || *q != ':') + return false; + p = ++q; + } + + p++; + colons -= i; + if(!i) { + p++; + colons--; + } + + if(!*p || *p == '/' || *p == '#') + colons--; + + // Fill in the blanks + for(; i < 8 - colons; i++) + x[i] = 0; + + // Scan the remaining numbers + for(; i < 8; i++) { + x[i] = strtoul(p, &q, 0x10); + if(!q || p == q) + return false; + if(i == 7) { + p = q; + break; + } + if(*q != ':') + return false; + p = ++q; + } + + l = 128; + if(*p == '/') + sscanf(p, "/%d#%d", &l, &weight); + else if(*p == '#') + sscanf(p, "#%d", &weight); + + if(l < 0 || l > 128) + return false; + + subnet->type = SUBNET_IPV6; + subnet->net.ipv6.prefixlength = l; + subnet->weight = weight; + + for(i = 0; i < 8; i++) + subnet->net.ipv6.address.x[i] = htons(x[i]); + + return true; + } + + return false; +} + +bool net2str(char *netstr, int len, const subnet_t *subnet) { + if(!netstr || !subnet) { + logger(DEBUG_ALWAYS, LOG_ERR, "net2str() was called with netstr=%p, subnet=%p!", netstr, subnet); + return false; + } + + switch (subnet->type) { + case SUBNET_MAC: + snprintf(netstr, len, "%hx:%hx:%hx:%hx:%hx:%hx#%d", + subnet->net.mac.address.x[0], + subnet->net.mac.address.x[1], + subnet->net.mac.address.x[2], + subnet->net.mac.address.x[3], + subnet->net.mac.address.x[4], + subnet->net.mac.address.x[5], + subnet->weight); + break; + + case SUBNET_IPV4: + snprintf(netstr, len, "%hu.%hu.%hu.%hu/%d#%d", + subnet->net.ipv4.address.x[0], + subnet->net.ipv4.address.x[1], + subnet->net.ipv4.address.x[2], + subnet->net.ipv4.address.x[3], + subnet->net.ipv4.prefixlength, + subnet->weight); + break; + + case SUBNET_IPV6: + snprintf(netstr, len, "%hx:%hx:%hx:%hx:%hx:%hx:%hx:%hx/%d#%d", + ntohs(subnet->net.ipv6.address.x[0]), + ntohs(subnet->net.ipv6.address.x[1]), + ntohs(subnet->net.ipv6.address.x[2]), + ntohs(subnet->net.ipv6.address.x[3]), + ntohs(subnet->net.ipv6.address.x[4]), + ntohs(subnet->net.ipv6.address.x[5]), + ntohs(subnet->net.ipv6.address.x[6]), + ntohs(subnet->net.ipv6.address.x[7]), + subnet->net.ipv6.prefixlength, + subnet->weight); + break; + + default: + logger(DEBUG_ALWAYS, LOG_ERR, "net2str() was called with unknown subnet type %d, exiting!", subnet->type); + exit(1); + } + + return true; +} diff --git a/src/tincctl.c b/src/tincctl.c index c055db5..c1cabdb 100644 --- a/src/tincctl.c +++ b/src/tincctl.c @@ -1,6 +1,6 @@ /* tincctl.c -- Controlling a running tincd - Copyright (C) 2007-2011 Guus Sliepen + Copyright (C) 2007-2012 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 @@ -21,18 +21,32 @@ #include +#ifdef HAVE_READLINE +#include "readline/readline.h" +#include "readline/history.h" +#endif + #include "xalloc.h" #include "protocol.h" #include "control_common.h" #include "ecdsagen.h" +#include "info.h" #include "rsagen.h" #include "utils.h" #include "tincctl.h" #include "top.h" +#ifdef HAVE_MINGW +#define mkdir(a, b) mkdir(a) +#endif + + /* The name this program was run with. */ static char *program_name = NULL; +static char **orig_argv; +static int orig_argc; + /* If nonzero, display usage information and exit. */ static bool show_help = false; @@ -40,11 +54,24 @@ static bool show_help = false; static bool show_version = false; static char *name = NULL; -static char *identname = NULL; /* program name for syslog */ -static char *pidfilename = NULL; /* pid file location */ +static char *identname = NULL; /* program name for syslog */ +static char *pidfilename = NULL; /* pid file location */ +static char *confdir = NULL; static char controlcookie[1024]; char *netname = NULL; char *confbase = NULL; +static char *tinc_conf = NULL; +static char *hosts_dir = NULL; + +// Horrible global variables... +static int pid = 0; +static int fd = -1; +static char line[4096]; +static int code; +static int req; +static int result; +static bool force = false; +static bool tty = true; #ifdef HAVE_MINGW static struct WSAData wsa_state; @@ -52,13 +79,32 @@ static struct WSAData wsa_state; static struct option const long_options[] = { {"config", required_argument, NULL, 'c'}, + {"debug", optional_argument, NULL, 0}, + {"no-detach", no_argument, NULL, 0}, + {"mlock", no_argument, NULL, 0}, {"net", required_argument, NULL, 'n'}, {"help", no_argument, NULL, 1}, {"version", no_argument, NULL, 2}, {"pidfile", required_argument, NULL, 5}, + {"logfile", required_argument, NULL, 0}, + {"bypass-security", no_argument, NULL, 0}, + {"chroot", no_argument, NULL, 0}, + {"user", required_argument, NULL, 0}, + {"option", required_argument, NULL, 0}, + {"force", no_argument, NULL, 6}, {NULL, 0, NULL, 0} }; +static void version(void) { + printf("%s version %s (built %s %s, protocol %d.%d)\n", PACKAGE, + VERSION, __DATE__, __TIME__, PROT_MAJOR, PROT_MINOR); + printf("Copyright (C) 1998-2012 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" + "see the file COPYING for details.\n"); +} + static void usage(bool status) { if(status) fprintf(stderr, "Try `%s --help\' for more information.\n", @@ -73,10 +119,16 @@ static void usage(bool status) { " --version Output version information and exit.\n" "\n" "Valid commands are:\n" - " start Start tincd.\n" + " init [name] Create initial configuration files.\n" + " config Change configuration:\n" + " [get] VARIABLE - print current value of VARIABLE\n" + " [set] VARIABLE VALUE - set VARIABLE to VALUE\n" + " add VARIABLE VALUE - add VARIABLE with the given VALUE\n" + " del VARIABLE [VALUE] - remove VARIABLE [only ones with watching VALUE]\n" + " start [tincd options] Start tincd.\n" " stop Stop tincd.\n" " restart Restart tincd.\n" - " reload Reload configuration of running tincd.\n" + " reload Partially reload configuration of running tincd.\n" " pid Show PID of currently running tincd.\n" " generate-keys [bits] Generate new RSA and ECDSA public/private keypairs.\n" " generate-rsa-keys [bits] Generate a new RSA public/private keypair.\n" @@ -86,16 +138,20 @@ static void usage(bool status) { " edges - all known connections in the VPN\n" " subnets - all known subnets in the VPN\n" " connections - all meta connections with ourself\n" - " graph - graph of the VPN in dotty format\n" + " [di]graph - graph of the VPN in dotty format\n" + " info NODE|SUBNET|ADDRESS Give information about a particular NODE, SUBNET or ADDRESS.\n" " purge Purge unreachable nodes\n" " debug N Set debug level\n" " retry Retry all outgoing connections\n" - " reload Partial reload of configuration\n" " disconnect NODE Close meta connection with NODE\n" #ifdef HAVE_CURSES " top Show real-time statistics\n" #endif - " pcap Dump traffic in pcap format\n" + " pcap [snaplen] Dump traffic in pcap format [up to snaplen bytes per packet]\n" + " log [level] Dump log output [up to the specified level]\n" + " export Export host configuration of local node to standard output\n" + " export-all Export all host configuration files to standard output\n" + " import [--force] Import host configuration file(s) from standard input\n" "\n"); printf("Report bugs to tinc@tinc-vpn.org.\n"); } @@ -105,32 +161,36 @@ static bool parse_options(int argc, char **argv) { int r; int option_index = 0; - while((r = getopt_long(argc, argv, "c:n:", long_options, &option_index)) != EOF) { + while((r = getopt_long(argc, argv, "c:n:Dd::Lo:RU:", long_options, &option_index)) != EOF) { switch (r) { - case 0: /* long option */ + case 0: /* long option */ break; - case 'c': /* config file */ + case 'c': /* config file */ confbase = xstrdup(optarg); break; - case 'n': /* net name given */ + case 'n': /* net name given */ netname = xstrdup(optarg); break; - case 1: /* show help */ + case 1: /* show help */ show_help = true; break; - case 2: /* show version */ + case 2: /* show version */ show_version = true; break; - case 5: /* open control socket here */ + case 5: /* open control socket here */ pidfilename = xstrdup(optarg); break; - case '?': + case 6: /* force */ + force = true; + break; + + case '?': /* wrong options */ usage(true); return false; @@ -139,17 +199,109 @@ static bool parse_options(int argc, char **argv) { } } + if(!netname && (netname = getenv("NETNAME"))) + netname = xstrdup(netname); + + /* netname "." is special: a "top-level name" */ + + if(netname && (!*netname || !strcmp(netname, "."))) { + free(netname); + netname = NULL; + } + + if(netname && (strpbrk(netname, "\\/") || *netname == '.')) { + fprintf(stderr, "Invalid character in netname!\n"); + return false; + } + return true; } -FILE *ask_and_open(const char *filename, const char *what, const char *mode) { +static void disable_old_keys(const char *filename, const char *what) { + char tmpfile[PATH_MAX] = ""; + char buf[1024]; + bool disabled = false; + bool block = false; + bool error = false; + FILE *r, *w; + + r = fopen(filename, "r"); + if(!r) + return; + + snprintf(tmpfile, sizeof tmpfile, "%s.tmp", filename); + + w = fopen(tmpfile, "w"); + + while(fgets(buf, sizeof buf, r)) { + if(!block && !strncmp(buf, "-----BEGIN ", 11)) { + if((strstr(buf, " EC ") && strstr(what, "ECDSA")) || (strstr(buf, " RSA ") && strstr(what, "RSA"))) { + disabled = true; + block = true; + } + } + + bool ecdsapubkey = !strncasecmp(buf, "ECDSAPublicKey", 14) && strchr(" \t=", buf[14]) && strstr(what, "ECDSA"); + + if(ecdsapubkey) + disabled = true; + + if(w) { + if(block || ecdsapubkey) + fputc('#', w); + if(fputs(buf, w) < 0) { + error = true; + break; + } + } + + if(block && !strncmp(buf, "-----END ", 9)) + block = false; + } + + if(w) + if(fclose(w) < 0) + error = true; + if(ferror(r) || fclose(r) < 0) + error = true; + + if(disabled) { + if(!w || error) { + fprintf(stderr, "Warning: old key(s) found, remove them by hand!\n"); + if(w) + unlink(tmpfile); + return; + } + +#ifdef HAVE_MINGW + // We cannot atomically replace files on Windows. + char bakfile[PATH_MAX] = ""; + snprintf(bakfile, sizeof bakfile, "%s.bak", filename); + if(rename(filename, bakfile) || rename(tmpfile, filename)) { + rename(bakfile, filename); +#else + if(rename(tmpfile, filename)) { +#endif + fprintf(stderr, "Warning: old key(s) found, remove them by hand!\n"); + } else { +#ifdef HAVE_MINGW + unlink(bakfile); +#endif + fprintf(stderr, "Warning: old key(s) found and disabled.\n"); + } + } + + unlink(tmpfile); +} + +static FILE *ask_and_open(const char *filename, const char *what, const char *mode, bool ask) { FILE *r; char *directory; char buf[PATH_MAX]; char buf2[PATH_MAX]; /* Check stdin and stdout */ - if(isatty(0) && isatty(1)) { + if(ask && tty) { /* Ask for a file and/or directory name. */ fprintf(stdout, "Please enter a file to save %s to [%s]: ", what, filename); @@ -176,11 +328,13 @@ FILE *ask_and_open(const char *filename, const char *what, const char *mode) { #endif /* The directory is a relative path or a filename. */ directory = get_current_dir_name(); - snprintf(buf2, sizeof buf2, "%s/%s", directory, filename); + snprintf(buf2, sizeof buf2, "%s" SLASH "%s", directory, filename); filename = buf2; } - umask(0077); /* Disallow everything for group and other */ + umask(0077); /* Disallow everything for group and other */ + + disable_old_keys(filename, what); /* Open it first to keep the inode busy */ @@ -198,10 +352,10 @@ FILE *ask_and_open(const char *filename, const char *what, const char *mode) { Generate a public/private ECDSA keypair, and ask for a file to store them in. */ -static bool ecdsa_keygen() { +static bool ecdsa_keygen(bool ask) { ecdsa_t key; FILE *f; - char *filename; + char *pubname, *privname; fprintf(stderr, "Generating ECDSA keypair:\n"); @@ -211,44 +365,38 @@ static bool ecdsa_keygen() { } else fprintf(stderr, "Done.\n"); - xasprintf(&filename, "%s/ecdsa_key.priv", confbase); - f = ask_and_open(filename, "private ECDSA key", "a"); + xasprintf(&privname, "%s" SLASH "ecdsa_key.priv", confbase); + f = ask_and_open(privname, "private ECDSA key", "a", ask); + free(privname); if(!f) return false; - + #ifdef HAVE_FCHMOD /* Make it unreadable for others. */ fchmod(fileno(f), 0600); #endif - - if(ftell(f)) - fprintf(stderr, "Appending key to existing contents.\nMake sure only one key is stored in the file.\n"); ecdsa_write_pem_private_key(&key, f); fclose(f); - free(filename); if(name) - xasprintf(&filename, "%s/hosts/%s", confbase, name); + xasprintf(&pubname, "%s" SLASH "hosts" SLASH "%s", confbase, name); else - xasprintf(&filename, "%s/ecdsa_key.pub", confbase); + xasprintf(&pubname, "%s" SLASH "ecdsa_key.pub", confbase); - f = ask_and_open(filename, "public ECDSA key", "a"); + f = ask_and_open(pubname, "public ECDSA key", "a", ask); + free(pubname); if(!f) return false; - if(ftell(f)) - fprintf(stderr, "Appending key to existing contents.\nMake sure only one key is stored in the file.\n"); - char *pubkey = ecdsa_get_base64_public_key(&key); fprintf(f, "ECDSAPublicKey = %s\n", pubkey); free(pubkey); fclose(f); - free(filename); return true; } @@ -257,10 +405,10 @@ static bool ecdsa_keygen() { Generate a public/private RSA keypair, and ask for a file to store them in. */ -static bool rsa_keygen(int bits) { +static bool rsa_keygen(int bits, bool ask) { rsa_t key; FILE *f; - char *filename; + char *pubname, *privname; fprintf(stderr, "Generating %d bits keys:\n", bits); @@ -270,42 +418,36 @@ static bool rsa_keygen(int bits) { } else fprintf(stderr, "Done.\n"); - xasprintf(&filename, "%s/rsa_key.priv", confbase); - f = ask_and_open(filename, "private RSA key", "a"); + xasprintf(&privname, "%s" SLASH "rsa_key.priv", confbase); + f = ask_and_open(privname, "private RSA key", "a", ask); + free(privname); if(!f) return false; - + #ifdef HAVE_FCHMOD /* Make it unreadable for others. */ fchmod(fileno(f), 0600); #endif - - if(ftell(f)) - fprintf(stderr, "Appending key to existing contents.\nMake sure only one key is stored in the file.\n"); rsa_write_pem_private_key(&key, f); fclose(f); - free(filename); if(name) - xasprintf(&filename, "%s/hosts/%s", confbase, name); + xasprintf(&pubname, "%s" SLASH "hosts" SLASH "%s", confbase, name); else - xasprintf(&filename, "%s/rsa_key.pub", confbase); + xasprintf(&pubname, "%s" SLASH "rsa_key.pub", confbase); - f = ask_and_open(filename, "public RSA key", "a"); + f = ask_and_open(pubname, "public RSA key", "a", ask); + free(pubname); if(!f) return false; - if(ftell(f)) - fprintf(stderr, "Appending key to existing contents.\nMake sure only one key is stored in the file.\n"); - rsa_write_pem_public_key(&key, f); fclose(f); - free(filename); return true; } @@ -330,31 +472,40 @@ static void make_names(void) { if(!RegQueryValueEx(key, NULL, 0, 0, installdir, &len)) { if(!confbase) { if(netname) - xasprintf(&confbase, "%s/%s", installdir, netname); + xasprintf(&confbase, "%s" SLASH "%s", installdir, netname); else xasprintf(&confbase, "%s", installdir); } } if(!pidfilename) - xasprintf(&pidfilename, "%s/pid", confbase); + xasprintf(&pidfilename, "%s" SLASH "pid", confbase); RegCloseKey(key); - if(*installdir) - return; } + + if(!*installdir) { #endif + confdir = xstrdup(CONFDIR); if(!pidfilename) - xasprintf(&pidfilename, "%s/run/%s.pid", LOCALSTATEDIR, identname); + xasprintf(&pidfilename, "%s" SLASH "run" SLASH "%s.pid", LOCALSTATEDIR, identname); if(netname) { if(!confbase) - xasprintf(&confbase, CONFDIR "/tinc/%s", netname); + xasprintf(&confbase, CONFDIR SLASH "tinc" SLASH "%s", netname); else fprintf(stderr, "Both netname and configuration directory given, using the latter...\n"); } else { if(!confbase) - xasprintf(&confbase, CONFDIR "/tinc"); + xasprintf(&confbase, CONFDIR SLASH "tinc"); } + +#ifdef HAVE_MINGW + } else + confdir = xstrdup(installdir); +#endif + + xasprintf(&tinc_conf, "%s" SLASH "tinc.conf", confbase); + xasprintf(&hosts_dir, "%s" SLASH "hosts", confbase); } static char buffer[4096]; @@ -385,7 +536,7 @@ bool recvline(int fd, char *line, size_t len) { return true; } -bool recvdata(int fd, char *data, size_t len) { +static bool recvdata(int fd, char *data, size_t len) { while(blen < len) { int result = recv(fd, buffer + blen, sizeof buffer - blen, 0); if(result == -1 && errno == EINTR) @@ -428,11 +579,11 @@ bool sendline(int fd, char *format, ...) { blen -= result; } - return true; + return true; } -void pcap(int fd, FILE *out) { - sendline(fd, "%d %d", CONTROL, REQ_PCAP); +static void pcap(int fd, FILE *out, int snaplen) { + sendline(fd, "%d %d %d", CONTROL, REQ_PCAP, snaplen); char data[9018]; struct { @@ -447,7 +598,7 @@ void pcap(int fd, FILE *out) { 0xa1b2c3d4, 2, 4, 0, 0, - sizeof data, + snaplen ?: sizeof data, 1, }; @@ -482,6 +633,24 @@ void pcap(int fd, FILE *out) { } } +static void logcontrol(int fd, FILE *out, int level) { + sendline(fd, "%d %d %d", CONTROL, REQ_LOG, level); + char data[1024]; + char line[32]; + + while(recvline(fd, line, sizeof line)) { + int code, req, len; + int n = sscanf(line, "%d %d %d", &code, &req, &len); + if(n != 3 || code != CONTROL || req != REQ_LOG || len < 0 || len > sizeof data) + break; + if(!recvdata(fd, data, len)) + break; + fwrite(data, len, 1, out); + fputc('\n', out); + fflush(out); + } +} + #ifdef HAVE_MINGW static bool remove_service(void) { SC_HANDLE manager = NULL; @@ -517,85 +686,45 @@ static bool remove_service(void) { } #endif -int main(int argc, char *argv[], char *envp[]) { - int fd; - int result; - char host[128]; - char port[128]; - int pid; - - program_name = argv[0]; - - if(!parse_options(argc, argv)) - return 1; - - make_names(); - - if(show_version) { - printf("%s version %s (built %s %s, protocol %d.%d)\n", PACKAGE, - VERSION, __DATE__, __TIME__, PROT_MAJOR, PROT_MINOR); - printf("Copyright (C) 1998-2009 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" - "see the file COPYING for details.\n"); - - return 0; +static bool connect_tincd(bool verbose) { + if(fd >= 0) { + fd_set r; + FD_ZERO(&r); + FD_SET(fd, &r); + struct timeval tv = {0, 0}; + if(select(fd + 1, &r, NULL, NULL, &tv)) { + fprintf(stderr, "Previous connection to tincd lost, reconnecting.\n"); + close(fd); + fd = -1; + } else { + return true; + } } - if(show_help) { - usage(false); - return 0; - } - - if(optind >= argc) { - fprintf(stderr, "Not enough arguments.\n"); - usage(true); - return 1; - } - - // First handle commands that don't involve connecting to a running tinc daemon. - - if(!strcasecmp(argv[optind], "generate-rsa-keys")) { - return !rsa_keygen(optind > argc ? atoi(argv[optind + 1]) : 2048); - } - - if(!strcasecmp(argv[optind], "generate-ecdsa-keys")) { - return !ecdsa_keygen(); - } - - if(!strcasecmp(argv[optind], "generate-keys")) { - return !(rsa_keygen(optind > argc ? atoi(argv[optind + 1]) : 2048) && ecdsa_keygen()); - } - - if(!strcasecmp(argv[optind], "start")) { - argv[optind] = NULL; - execve(SBINDIR "/tincd", argv, envp); - fprintf(stderr, "Could not start tincd: %s", strerror(errno)); - return 1; - } - - /* - * Now handle commands that do involve connecting to a running tinc daemon. - * Authenticate the server by ensuring the parent directory can be - * traversed only by root. Note this is not totally race-free unless all - * ancestors are writable only by trusted users, which we don't verify. - */ - FILE *f = fopen(pidfilename, "r"); if(!f) { - fprintf(stderr, "Could not open pid file %s: %s\n", pidfilename, strerror(errno)); - return 1; + if(verbose) + fprintf(stderr, "Could not open pid file %s: %s\n", pidfilename, strerror(errno)); + return false; } + + char host[128]; + char port[128]; + if(fscanf(f, "%20d %1024s %128s port %128s", &pid, controlcookie, host, port) != 4) { - fprintf(stderr, "Could not parse pid file %s\n", pidfilename); - return 1; + if(verbose) + fprintf(stderr, "Could not parse pid file %s\n", pidfilename); + fclose(f); + return false; } + fclose(f); + #ifdef HAVE_MINGW if(WSAStartup(MAKEWORD(2, 2), &wsa_state)) { - fprintf(stderr, "System call `%s' failed: %s", "WSAStartup", winerror(GetLastError())); - return 1; + if(verbose) + fprintf(stderr, "System call `%s' failed: %s", "WSAStartup", winerror(GetLastError())); + return false; } #endif @@ -609,225 +738,1460 @@ int main(int argc, char *argv[], char *envp[]) { struct addrinfo *res = NULL; if(getaddrinfo(host, port, &hints, &res) || !res) { - fprintf(stderr, "Cannot resolve %s port %s: %s", host, port, strerror(errno)); - return 1; + if(verbose) + fprintf(stderr, "Cannot resolve %s port %s: %s", host, port, strerror(errno)); + return false; } fd = socket(res->ai_family, SOCK_STREAM, IPPROTO_TCP); if(fd < 0) { - fprintf(stderr, "Cannot create TCP socket: %s\n", sockstrerror(sockerrno)); - return 1; + if(verbose) + fprintf(stderr, "Cannot create TCP socket: %s\n", sockstrerror(sockerrno)); + return false; } #ifdef HAVE_MINGW unsigned long arg = 0; if(ioctlsocket(fd, FIONBIO, &arg) != 0) { - fprintf(stderr, "ioctlsocket failed: %s", sockstrerror(sockerrno)); + if(verbose) + fprintf(stderr, "ioctlsocket failed: %s", sockstrerror(sockerrno)); } #endif if(connect(fd, res->ai_addr, res->ai_addrlen) < 0) { - fprintf(stderr, "Cannot connect to %s port %s: %s\n", host, port, sockstrerror(sockerrno)); - return 1; + if(verbose) + fprintf(stderr, "Cannot connect to %s port %s: %s\n", host, port, sockstrerror(sockerrno)); + close(fd); + fd = -1; + return false; } freeaddrinfo(res); - char line[4096]; char data[4096]; - int code, version, req; + int version; if(!recvline(fd, line, sizeof line) || sscanf(line, "%d %s %d", &code, data, &version) != 3 || code != 0) { - fprintf(stderr, "Cannot read greeting from control socket: %s\n", - sockstrerror(sockerrno)); - return 1; + if(verbose) + fprintf(stderr, "Cannot read greeting from control socket: %s\n", sockstrerror(sockerrno)); + close(fd); + fd = -1; + return false; } sendline(fd, "%d ^%s %d", ID, controlcookie, TINC_CTL_VERSION_CURRENT); - + if(!recvline(fd, line, sizeof line) || sscanf(line, "%d %d %d", &code, &version, &pid) != 3 || code != 4 || version != TINC_CTL_VERSION_CURRENT) { - fprintf(stderr, "Could not fully establish control socket connection\n"); + if(verbose) + fprintf(stderr, "Could not fully establish control socket connection\n"); + close(fd); + fd = -1; + return false; + } + + return true; +} + + +static int cmd_start(int argc, char *argv[]) { + if(connect_tincd(false)) { + if(netname) + fprintf(stderr, "A tincd is already running for net `%s' with pid %d.\n", netname, pid); + else + fprintf(stderr, "A tincd is already running with pid %d.\n", pid); + return 0; + } + + char *c; + char *slash = strrchr(program_name, '/'); + +#ifdef HAVE_MINGW + if ((c = strrchr(program_name, '\\')) > slash) + slash = c; +#endif + + if (slash++) + xasprintf(&c, "%.*stincd", (int)(slash - program_name), program_name); + else + c = "tincd"; + + int nargc = 0; + char **nargv = xmalloc_and_zero((optind + argc) * sizeof *nargv); + + nargv[nargc++] = c; + for(int i = 1; i < optind; i++) + nargv[nargc++] = orig_argv[i]; + for(int i = 1; i < argc; i++) + nargv[nargc++] = argv[i]; + +#ifdef HAVE_MINGW + execvp(c, nargv); + fprintf(stderr, "Error starting %s: %s\n", c, strerror(errno)); + return 1; +#else + pid_t pid = fork(); + if(pid == -1) { + fprintf(stderr, "Could not fork: %s\n", strerror(errno)); + free(nargv); return 1; } - if(!strcasecmp(argv[optind], "pid")) { - printf("%d\n", pid); - return 0; + if(!pid) + exit(execvp(c, nargv)); + + free(nargv); + + int status = -1; + if(waitpid(pid, &status, 0) != pid || !WIFEXITED(status) || WEXITSTATUS(status)) { + fprintf(stderr, "Error starting %s\n", c); + return 1; } - if(!strcasecmp(argv[optind], "stop")) { -#ifndef HAVE_MINGW - sendline(fd, "%d %d", CONTROL, REQ_STOP); - if(!recvline(fd, line, sizeof line) || sscanf(line, "%d %d %d", &code, &req, &result) != 3 || code != CONTROL || req != REQ_STOP || result) { - fprintf(stderr, "Could not stop tinc daemon\n"); - return 1; - } -#else - if(!remove_service()) - return 1; + return 0; #endif - return 0; - } +} - if(!strcasecmp(argv[optind], "reload")) { - sendline(fd, "%d %d", CONTROL, REQ_RELOAD); - if(!recvline(fd, line, sizeof line) || sscanf(line, "%d %d %d", &code, &req, &result) != 3 || code != CONTROL || req != REQ_RELOAD || result) { - fprintf(stderr, "Could not reload tinc daemon\n"); - return 1; - } - return 0; - } +static int cmd_stop(int argc, char *argv[]) { +#ifndef HAVE_MINGW + if(!connect_tincd(true)) { + if(pid) { + if(kill(pid, SIGTERM)) { + fprintf(stderr, "Could not send TERM signal to process with PID %u: %s\n", pid, strerror(errno)); + return 1; + } - if(!strcasecmp(argv[optind], "restart")) { - sendline(fd, "%d %d", CONTROL, REQ_RESTART); - if(!recvline(fd, line, sizeof line) || sscanf(line, "%d %d %d", &code, &req, &result) != 3 || code != CONTROL || req != REQ_RESTART || result) { - fprintf(stderr, "Could not restart tinc daemon\n"); - return 1; - } - return 0; - } - - if(!strcasecmp(argv[optind], "retry")) { - sendline(fd, "%d %d", CONTROL, REQ_RETRY); - if(!recvline(fd, line, sizeof line) || sscanf(line, "%d %d %d", &code, &req, &result) != 3 || code != CONTROL || req != REQ_RETRY || result) { - fprintf(stderr, "Could not retry outgoing connections\n"); - return 1; - } - return 0; - } - - if(!strcasecmp(argv[optind], "dump")) { - if(argc < optind + 2) { - fprintf(stderr, "Not enough arguments.\n"); - usage(true); - return 1; + fprintf(stderr, "Sent TERM signal to process with PID %u.\n", pid); + waitpid(pid, NULL, 0); + return 0; } - bool do_graph = false; + return 1; + } - if(!strcasecmp(argv[optind+1], "nodes")) - sendline(fd, "%d %d", CONTROL, REQ_DUMP_NODES); - else if(!strcasecmp(argv[optind+1], "edges")) - sendline(fd, "%d %d", CONTROL, REQ_DUMP_EDGES); - else if(!strcasecmp(argv[optind+1], "subnets")) - sendline(fd, "%d %d", CONTROL, REQ_DUMP_SUBNETS); - else if(!strcasecmp(argv[optind+1], "connections")) - sendline(fd, "%d %d", CONTROL, REQ_DUMP_CONNECTIONS); - else if(!strcasecmp(argv[optind+1], "graph")) { - sendline(fd, "%d %d", CONTROL, REQ_DUMP_NODES); - sendline(fd, "%d %d", CONTROL, REQ_DUMP_EDGES); - do_graph = true; - printf("digraph {\n"); + sendline(fd, "%d %d", CONTROL, REQ_STOP); + if(!recvline(fd, line, sizeof line) || sscanf(line, "%d %d %d", &code, &req, &result) != 3 || code != CONTROL || req != REQ_STOP || result) { + fprintf(stderr, "Could not stop tinc daemon.\n"); + return 1; + } + + // Wait for tincd to close the connection... + fd_set r; + FD_ZERO(&r); + FD_SET(fd, &r); + select(fd + 1, &r, NULL, NULL, NULL); +#else + if(!remove_service()) + return 1; +#endif + close(fd); + pid = 0; + fd = -1; + + return 0; +} + +static int cmd_restart(int argc, char *argv[]) { + cmd_stop(argc, argv); + return cmd_start(argc, argv); +} + +static int cmd_reload(int argc, char *argv[]) { + if(!connect_tincd(true)) + return 1; + + sendline(fd, "%d %d", CONTROL, REQ_RELOAD); + if(!recvline(fd, line, sizeof line) || sscanf(line, "%d %d %d", &code, &req, &result) != 3 || code != CONTROL || req != REQ_RELOAD || result) { + fprintf(stderr, "Could not reload configuration.\n"); + return 1; + } + + return 0; + +} + +static int cmd_dump(int argc, char *argv[]) { + if(argc != 2) { + fprintf(stderr, "Invalid number of arguments.\n"); + usage(true); + return 1; + } + + if(!connect_tincd(true)) + return 1; + + int do_graph = 0; + + if(!strcasecmp(argv[1], "nodes")) + sendline(fd, "%d %d", CONTROL, REQ_DUMP_NODES); + else if(!strcasecmp(argv[1], "edges")) + sendline(fd, "%d %d", CONTROL, REQ_DUMP_EDGES); + else if(!strcasecmp(argv[1], "subnets")) + sendline(fd, "%d %d", CONTROL, REQ_DUMP_SUBNETS); + else if(!strcasecmp(argv[1], "connections")) + sendline(fd, "%d %d", CONTROL, REQ_DUMP_CONNECTIONS); + else if(!strcasecmp(argv[1], "graph")) { + sendline(fd, "%d %d", CONTROL, REQ_DUMP_NODES); + sendline(fd, "%d %d", CONTROL, REQ_DUMP_EDGES); + do_graph = 1; + } else if(!strcasecmp(argv[1], "digraph")) { + sendline(fd, "%d %d", CONTROL, REQ_DUMP_NODES); + sendline(fd, "%d %d", CONTROL, REQ_DUMP_EDGES); + do_graph = 2; + } else { + fprintf(stderr, "Unknown dump type '%s'.\n", argv[1]); + usage(true); + return 1; + } + + if(do_graph == 1) + printf("graph {\n"); + else if(do_graph == 2) + printf("digraph {\n"); + + while(recvline(fd, line, sizeof line)) { + char node1[4096], node2[4096]; + int n = sscanf(line, "%d %d %s %s", &code, &req, node1, node2); + if(n == 2) { + if(do_graph && req == REQ_DUMP_NODES) + continue; + else { + if(do_graph) + printf("}\n"); + return 0; + } + } + if(n < 2) + break; + + char node[4096]; + char from[4096]; + char to[4096]; + char subnet[4096]; + char host[4096]; + char port[4096]; + char via[4096]; + char nexthop[4096]; + int cipher, digest, maclength, compression, distance, socket, weight; + short int pmtu, minmtu, maxmtu; + unsigned int options, status_int; + node_status_t status; + long int last_state_change; + + switch(req) { + case REQ_DUMP_NODES: { + int n = sscanf(line, "%*d %*d %s %s port %s %d %d %d %d %x %x %s %s %d %hd %hd %hd %ld", node, host, port, &cipher, &digest, &maclength, &compression, &options, &status_int, nexthop, via, &distance, &pmtu, &minmtu, &maxmtu, &last_state_change); + if(n != 16) { + fprintf(stderr, "Unable to parse node dump from tincd: %s\n", line); + return 1; + } + if(do_graph) { + memcpy(&status, &status_int, sizeof status); + const char *color = "black"; + if(!strcmp(host, "MYSELF")) + color = "green"; + else if(!status.reachable) + color = "red"; + else if(strcmp(via, node)) + color = "orange"; + else if(!status.validkey) + color = "black"; + else if(minmtu > 0) + color = "green"; + printf(" %s [label = \"%s\", color = \"%s\"%s];\n", node, node, color, strcmp(host, "MYSELF") ? "" : ", style = \"filled\""); + } else { + printf("%s at %s port %s cipher %d digest %d maclength %d compression %d options %x status %04x nexthop %s via %s distance %d pmtu %hd (min %hd max %hd)\n", + node, host, port, cipher, digest, maclength, compression, options, status_int, nexthop, via, distance, pmtu, minmtu, maxmtu); + } + } break; + + case REQ_DUMP_EDGES: { + int n = sscanf(line, "%*d %*d %s %s %s port %s %x %d", from, to, host, port, &options, &weight); + if(n != 6) { + fprintf(stderr, "Unable to parse edge dump from tincd.\n"); + return 1; + } + + if(do_graph) { + float w = 1 + 65536.0 / weight; + if(do_graph == 1 && strcmp(node1, node2) > 0) + printf(" %s -- %s [w = %f, weight = %f];\n", node1, node2, w, w); + else if(do_graph == 2) + printf(" %s -> %s [w = %f, weight = %f];\n", node1, node2, w, w); + } else { + printf("%s to %s at %s port %s options %x weight %d\n", from, to, host, port, options, weight); + } + } break; + + case REQ_DUMP_SUBNETS: { + int n = sscanf(line, "%*d %*d %s %s", subnet, node); + if(n != 2) { + fprintf(stderr, "Unable to parse subnet dump from tincd.\n"); + return 1; + } + printf("%s owner %s\n", strip_weight(subnet), node); + } break; + + case REQ_DUMP_CONNECTIONS: { + int n = sscanf(line, "%*d %*d %s %s port %s %x %d %x", node, host, port, &options, &socket, &status_int); + if(n != 6) { + fprintf(stderr, "Unable to parse connection dump from tincd.\n"); + return 1; + } + printf("%s at %s port %s options %x socket %d status %x\n", node, host, port, options, socket, status_int); + } break; + + default: + fprintf(stderr, "Unable to parse dump from tincd.\n"); + return 1; + } + } + + fprintf(stderr, "Error receiving dump.\n"); + return 1; +} + +static int cmd_purge(int argc, char *argv[]) { + if(!connect_tincd(true)) + return 1; + + sendline(fd, "%d %d", CONTROL, REQ_PURGE); + if(!recvline(fd, line, sizeof line) || sscanf(line, "%d %d %d", &code, &req, &result) != 3 || code != CONTROL || req != REQ_PURGE || result) { + fprintf(stderr, "Could not purge old information.\n"); + return 1; + } + + return 0; +} + +static int cmd_debug(int argc, char *argv[]) { + if(argc != 2) { + fprintf(stderr, "Invalid number of arguments.\n"); + return 1; + } + + if(!connect_tincd(true)) + return 1; + + int debuglevel = atoi(argv[1]); + int origlevel; + + sendline(fd, "%d %d %d", CONTROL, REQ_SET_DEBUG, debuglevel); + if(!recvline(fd, line, sizeof line) || sscanf(line, "%d %d %d", &code, &req, &origlevel) != 3 || code != CONTROL || req != REQ_SET_DEBUG) { + fprintf(stderr, "Could not set debug level.\n"); + return 1; + } + + fprintf(stderr, "Old level %d, new level %d.\n", origlevel, debuglevel); + return 0; +} + +static int cmd_retry(int argc, char *argv[]) { + if(!connect_tincd(true)) + return 1; + + sendline(fd, "%d %d", CONTROL, REQ_RETRY); + if(!recvline(fd, line, sizeof line) || sscanf(line, "%d %d %d", &code, &req, &result) != 3 || code != CONTROL || req != REQ_RETRY || result) { + fprintf(stderr, "Could not retry outgoing connections.\n"); + return 1; + } + + return 0; +} + +static int cmd_connect(int argc, char *argv[]) { + if(argc != 2) { + fprintf(stderr, "Invalid number of arguments.\n"); + return 1; + } + + if(!check_id(argv[1])) { + fprintf(stderr, "Invalid name for node.\n"); + return 1; + } + + if(!connect_tincd(true)) + return 1; + + sendline(fd, "%d %d %s", CONTROL, REQ_CONNECT, argv[1]); + if(!recvline(fd, line, sizeof line) || sscanf(line, "%d %d %d", &code, &req, &result) != 3 || code != CONTROL || req != REQ_CONNECT || result) { + fprintf(stderr, "Could not connect to %s.\n", argv[1]); + return 1; + } + + return 0; +} + +static int cmd_disconnect(int argc, char *argv[]) { + if(argc != 2) { + fprintf(stderr, "Invalid number of arguments.\n"); + return 1; + } + + if(!check_id(argv[1])) { + fprintf(stderr, "Invalid name for node.\n"); + return 1; + } + + if(!connect_tincd(true)) + return 1; + + sendline(fd, "%d %d %s", CONTROL, REQ_DISCONNECT, argv[1]); + if(!recvline(fd, line, sizeof line) || sscanf(line, "%d %d %d", &code, &req, &result) != 3 || code != CONTROL || req != REQ_DISCONNECT || result) { + fprintf(stderr, "Could not disconnect %s.\n", argv[1]); + return 1; + } + + return 0; +} + +static int cmd_top(int argc, char *argv[]) { +#ifdef HAVE_CURSES + if(!connect_tincd(true)) + return 1; + + top(fd); + return 0; +#else + fprintf(stderr, "This version of tincctl was compiled without support for the curses library.\n"); + return 1; +#endif +} + +static int cmd_pcap(int argc, char *argv[]) { + if(!connect_tincd(true)) + return 1; + + pcap(fd, stdout, argc > 1 ? atoi(argv[1]) : 0); + return 0; +} + +static int cmd_log(int argc, char *argv[]) { + if(!connect_tincd(true)) + return 1; + + logcontrol(fd, stdout, argc > 1 ? atoi(argv[1]) : -1); + return 0; +} + +static int cmd_pid(int argc, char *argv[]) { + if(!connect_tincd(true) && !pid) + return 1; + + printf("%d\n", pid); + return 0; +} + +static int rstrip(char *value) { + int len = strlen(value); + while(len && strchr("\t\r\n ", value[len - 1])) + value[--len] = 0; + return len; +} + +static char *get_my_name() { + FILE *f = fopen(tinc_conf, "r"); + if(!f) { + fprintf(stderr, "Could not open %s: %s\n", tinc_conf, strerror(errno)); + return NULL; + } + + char buf[4096]; + char *value; + while(fgets(buf, sizeof buf, f)) { + int len = strcspn(buf, "\t ="); + value = buf + len; + value += strspn(value, "\t "); + if(*value == '=') { + value++; + value += strspn(value, "\t "); + } + if(!rstrip(value)) + continue; + buf[len] = 0; + if(strcasecmp(buf, "Name")) + continue; + if(*value) { + fclose(f); + return strdup(value); + } + } + + fclose(f); + fprintf(stderr, "Could not find Name in %s.\n", tinc_conf); + return NULL; +} + +#define VAR_SERVER 1 /* Should be in tinc.conf */ +#define VAR_HOST 2 /* Can be in host config file */ +#define VAR_MULTIPLE 4 /* Multiple statements allowed */ +#define VAR_OBSOLETE 8 /* Should not be used anymore */ + +static struct { + const char *name; + int type; +} const variables[] = { + /* Server configuration */ + {"AddressFamily", VAR_SERVER}, + {"BindToAddress", VAR_SERVER | VAR_MULTIPLE}, + {"BindToInterface", VAR_SERVER}, + {"Broadcast", VAR_SERVER}, + {"ConnectTo", VAR_SERVER | VAR_MULTIPLE}, + {"DecrementTTL", VAR_SERVER}, + {"Device", VAR_SERVER}, + {"DeviceType", VAR_SERVER}, + {"DirectOnly", VAR_SERVER}, + {"ECDSAPrivateKeyFile", VAR_SERVER}, + {"ExperimentalProtocol", VAR_SERVER}, + {"Forwarding", VAR_SERVER}, + {"GraphDumpFile", VAR_SERVER | VAR_OBSOLETE}, + {"Hostnames", VAR_SERVER}, + {"IffOneQueue", VAR_SERVER}, + {"Interface", VAR_SERVER}, + {"KeyExpire", VAR_SERVER}, + {"LocalDiscovery", VAR_SERVER}, + {"MACExpire", VAR_SERVER}, + {"MaxOutputBufferSize", VAR_SERVER}, + {"MaxTimeout", VAR_SERVER}, + {"Mode", VAR_SERVER}, + {"Name", VAR_SERVER}, + {"PingInterval", VAR_SERVER}, + {"PingTimeout", VAR_SERVER}, + {"PriorityInheritance", VAR_SERVER}, + {"PrivateKey", VAR_SERVER | VAR_OBSOLETE}, + {"PrivateKeyFile", VAR_SERVER}, + {"ProcessPriority", VAR_SERVER}, + {"Proxy", VAR_SERVER}, + {"ReplayWindow", VAR_SERVER}, + {"ScriptsExtension", VAR_SERVER}, + {"ScriptsInterpreter", VAR_SERVER}, + {"StrictSubnets", VAR_SERVER}, + {"TunnelServer", VAR_SERVER}, + {"UDPRcvBuf", VAR_SERVER}, + {"UDPSndBuf", VAR_SERVER}, + {"VDEGroup", VAR_SERVER}, + {"VDEPort", VAR_SERVER}, + /* Host configuration */ + {"Address", VAR_HOST | VAR_MULTIPLE}, + {"Cipher", VAR_SERVER | VAR_HOST}, + {"ClampMSS", VAR_SERVER | VAR_HOST}, + {"Compression", VAR_SERVER | VAR_HOST}, + {"Digest", VAR_SERVER | VAR_HOST}, + {"ECDSAPublicKey", VAR_HOST}, + {"ECDSAPublicKeyFile", VAR_SERVER | VAR_HOST}, + {"IndirectData", VAR_SERVER | VAR_HOST}, + {"MACLength", VAR_SERVER | VAR_HOST}, + {"PMTU", VAR_SERVER | VAR_HOST}, + {"PMTUDiscovery", VAR_SERVER | VAR_HOST}, + {"Port", VAR_HOST}, + {"PublicKey", VAR_HOST | VAR_OBSOLETE}, + {"PublicKeyFile", VAR_SERVER | VAR_HOST | VAR_OBSOLETE}, + {"Subnet", VAR_HOST | VAR_MULTIPLE}, + {"TCPOnly", VAR_SERVER | VAR_HOST}, + {"Weight", VAR_HOST}, + {NULL, 0} +}; + +static int cmd_config(int argc, char *argv[]) { + if(argc < 2) { + fprintf(stderr, "Invalid number of arguments.\n"); + return 1; + } + + int action = -2; + if(!strcasecmp(argv[1], "get")) { + argv++, argc--; + } else if(!strcasecmp(argv[1], "add")) { + argv++, argc--, action = 1; + } else if(!strcasecmp(argv[1], "del")) { + argv++, argc--, action = -1; + } else if(!strcasecmp(argv[1], "replace") || !strcasecmp(argv[1], "set") || !strcasecmp(argv[1], "change")) { + argv++, argc--, action = 0; + } + + if(argc < 2) { + fprintf(stderr, "Invalid number of arguments.\n"); + return 1; + } + + // Concatenate the rest of the command line + strncpy(line, argv[1], sizeof line - 1); + for(int i = 2; i < argc; i++) { + strncat(line, " ", sizeof line - 1 - strlen(line)); + strncat(line, argv[i], sizeof line - 1 - strlen(line)); + } + + // Liberal parsing into node name, variable name and value. + char *node = NULL; + char *variable; + char *value; + int len; + + len = strcspn(line, "\t ="); + value = line + len; + value += strspn(value, "\t "); + if(*value == '=') { + value++; + value += strspn(value, "\t "); + } + line[len] = '\0'; + variable = strchr(line, '.'); + if(variable) { + node = line; + *variable++ = 0; + } else { + variable = line; + } + + if(!*variable) { + fprintf(stderr, "No variable given.\n"); + return 1; + } + + if(action >= 0 && !*value) { + fprintf(stderr, "No value for variable given.\n"); + return 1; + } + + if(action < -1 && *value) + action = 0; + + /* Some simple checks. */ + bool found = false; + + for(int i = 0; variables[i].name; i++) { + if(strcasecmp(variables[i].name, variable)) + continue; + + found = true; + variable = (char *)variables[i].name; + + /* Discourage use of obsolete variables. */ + + if(variables[i].type & VAR_OBSOLETE && action >= 0) { + if(force) { + fprintf(stderr, "Warning: %s is an obsolete variable!\n", variable); + } else { + fprintf(stderr, "%s is an obsolete variable! Use --force to use it anyway.\n", variable); + return 1; + } + } + + /* Don't put server variables in host config files */ + + if(node && !(variables[i].type & VAR_HOST) && action >= 0) { + if(force) { + fprintf(stderr, "Warning: %s is not a host configuration variable!\n", variable); + } else { + fprintf(stderr, "%s is not a host configuration variable! Use --force to use it anyway.\n", variable); + return 1; + } + } + + /* Should this go into our own host config file? */ + + if(!node && !(variables[i].type & VAR_SERVER)) { + node = get_my_name(); + if(!node) + return 1; + } + + break; + } + + if(node && !check_id(node)) { + fprintf(stderr, "Invalid name for node.\n"); + return 1; + } + + if(!found) { + if(force || action < 0) { + fprintf(stderr, "Warning: %s is not a known configuration variable!\n", variable); } else { - fprintf(stderr, "Unknown dump type '%s'.\n", argv[optind+1]); - usage(true); + fprintf(stderr, "%s: is not a known configuration variable! Use --force to use it anyway.\n", variable); + return 1; + } + } + + // Open the right configuration file. + char *filename; + if(node) + xasprintf(&filename, "%s" SLASH "%s", hosts_dir, node); + else + filename = tinc_conf; + + FILE *f = fopen(filename, "r"); + if(!f) { + if(action < 0 || errno != ENOENT) { + fprintf(stderr, "Could not open configuration file %s: %s\n", filename, strerror(errno)); return 1; } - while(recvline(fd, line, sizeof line)) { - char node1[4096], node2[4096]; - int n = sscanf(line, "%d %d %s to %s", &code, &req, node1, node2); - if(n == 2) { - if(do_graph && req == REQ_DUMP_NODES) + // If it doesn't exist, create it. + f = fopen(filename, "a+"); + if(!f) { + fprintf(stderr, "Could not create configuration file %s: %s\n", filename, strerror(errno)); + return 1; + } else { + fprintf(stderr, "Created configuration file %s.\n", filename); + } + } + + char *tmpfile = NULL; + FILE *tf = NULL; + + if(action >= -1) { + xasprintf(&tmpfile, "%s.config.tmp", filename); + tf = fopen(tmpfile, "w"); + if(!tf) { + fprintf(stderr, "Could not open temporary file %s: %s\n", tmpfile, strerror(errno)); + fclose(f); + return 1; + } + } + + // Copy the file, making modifications on the fly, unless we are just getting a value. + char buf1[4096]; + char buf2[4096]; + bool set = false; + bool removed = false; + found = false; + + while(fgets(buf1, sizeof buf1, f)) { + buf1[sizeof buf1 - 1] = 0; + strncpy(buf2, buf1, sizeof buf2); + + // Parse line in a simple way + char *bvalue; + int len; + + len = strcspn(buf2, "\t ="); + bvalue = buf2 + len; + bvalue += strspn(bvalue, "\t "); + if(*bvalue == '=') { + bvalue++; + bvalue += strspn(bvalue, "\t "); + } + rstrip(bvalue); + buf2[len] = '\0'; + + // Did it match? + if(!strcasecmp(buf2, variable)) { + // Get + if(action < -1) { + found = true; + printf("%s\n", bvalue); + // Del + } else if(action == -1) { + if(!*value || !strcasecmp(bvalue, value)) { + removed = true; continue; - else { - if(do_graph) - printf("}\n"); - return 0; + } + // Set + } else if(action == 0) { + // Already set? Delete the rest... + if(set) + continue; + // Otherwise, replace. + if(fprintf(tf, "%s = %s\n", variable, value) < 0) { + fprintf(stderr, "Error writing to temporary file %s: %s\n", tmpfile, strerror(errno)); + return 1; + } + set = true; + continue; + } + } + + if(action >= -1) { + // Copy original line... + if(fputs(buf1, tf) < 0) { + fprintf(stderr, "Error writing to temporary file %s: %s\n", tmpfile, strerror(errno)); + return 1; + } + + // Add newline if it is missing... + if(*buf1 && buf1[strlen(buf1) - 1] != '\n') { + if(fputc('\n', tf) < 0) { + fprintf(stderr, "Error writing to temporary file %s: %s\n", tmpfile, strerror(errno)); + return 1; } } - if(n < 2) - break; - - if(!do_graph) - printf("%s\n", line + 5); - else { - if(req == REQ_DUMP_NODES) - printf(" %s [label = \"%s\"];\n", node1, node1); - else - printf(" %s -> %s;\n", node1, node2); - } } + } - fprintf(stderr, "Error receiving dump\n"); + // Make sure we read everything... + if(ferror(f) || !feof(f)) { + fprintf(stderr, "Error while reading from configuration file %s: %s\n", filename, strerror(errno)); return 1; } - if(!strcasecmp(argv[optind], "purge")) { - sendline(fd, "%d %d", CONTROL, REQ_PURGE); - if(!recvline(fd, line, sizeof line) || sscanf(line, "%d %d %d", &code, &req, &result) != 3 || code != CONTROL || req != REQ_PURGE || result) { - fprintf(stderr, "Could not purge tinc daemon\n"); + if(fclose(f)) { + fprintf(stderr, "Error closing configuration file %s: %s\n", filename, strerror(errno)); + return 1; + } + + // Add new variable if necessary. + if(action > 0 || (action == 0 && !set)) { + if(fprintf(tf, "%s = %s\n", variable, value) < 0) { + fprintf(stderr, "Error writing to temporary file %s: %s\n", tmpfile, strerror(errno)); return 1; } + } + + if(action < -1) { + if(!found) + fprintf(stderr, "No matching configuration variables found.\n"); return 0; } - if(!strcasecmp(argv[optind], "debug")) { - int debuglevel, origlevel; - - if(argc != optind + 2) { - fprintf(stderr, "Invalid arguments.\n"); - return 1; - } - debuglevel = atoi(argv[optind+1]); - - sendline(fd, "%d %d %d", CONTROL, REQ_SET_DEBUG, debuglevel); - if(!recvline(fd, line, sizeof line) || sscanf(line, "%d %d %d", &code, &req, &origlevel) != 3 || code != CONTROL || req != REQ_SET_DEBUG) { - fprintf(stderr, "Could not purge tinc daemon\n"); - return 1; - } - - fprintf(stderr, "Old level %d, new level %d\n", origlevel, debuglevel); - return 0; + // Make sure we wrote everything... + if(fclose(tf)) { + fprintf(stderr, "Error closing temporary file %s: %s\n", tmpfile, strerror(errno)); + return 1; } - if(!strcasecmp(argv[optind], "connect")) { - if(argc != optind + 2) { - fprintf(stderr, "Invalid arguments.\n"); - return 1; - } - char *name = argv[optind + 1]; - - sendline(fd, "%d %d %s", CONTROL, REQ_CONNECT, name); - if(!recvline(fd, line, sizeof line) || sscanf(line, "%d %d %d", &code, &req, &result) != 3 || code != CONTROL || req != REQ_CONNECT || result) { - fprintf(stderr, "Could not connect to %s\n", name); - return 1; - } - return 0; + // Could we find what we had to remove? + if(action < 0 && !removed) { + remove(tmpfile); + fprintf(stderr, "No configuration variables deleted.\n"); + return *value; } - if(!strcasecmp(argv[optind], "disconnect")) { - if(argc != optind + 2) { - fprintf(stderr, "Invalid arguments.\n"); - return 1; - } - char *name = argv[optind + 1]; - - sendline(fd, "%d %d %s", CONTROL, REQ_DISCONNECT, name); - if(!recvline(fd, line, sizeof line) || sscanf(line, "%d %d %d", &code, &req, &result) != 3 || code != CONTROL || req != REQ_DISCONNECT || result) { - fprintf(stderr, "Could not disconnect %s\n", name); - return 1; - } - return 0; + // Replace the configuration file with the new one +#ifdef HAVE_MINGW + if(remove(filename)) { + fprintf(stderr, "Error replacing file %s: %s\n", filename, strerror(errno)); + return 1; + } +#endif + if(rename(tmpfile, filename)) { + fprintf(stderr, "Error renaming temporary file %s to configuration file %s: %s\n", tmpfile, filename, strerror(errno)); + return 1; } -#ifdef HAVE_CURSES - if(!strcasecmp(argv[optind], "top")) { - top(fd); - return 0; + // Silently try notifying a running tincd of changes. + if(connect_tincd(false)) + sendline(fd, "%d %d", CONTROL, REQ_RELOAD); + + return 0; +} + +bool check_id(const char *name) { + if(!name || !*name) + return false; + + for(int i = 0; i < strlen(name); i++) { + if(!isalnum(name[i]) && name[i] != '_') + return false; + } + + return true; +} + +static int cmd_init(int argc, char *argv[]) { + if(!access(tinc_conf, F_OK)) { + fprintf(stderr, "Configuration file %s already exists!\n", tinc_conf); + return 1; + } + + if(argc < 2) { + if(tty) { + char buf[1024]; + fprintf(stdout, "Enter the Name you want your tinc node to have: "); + fflush(stdout); + if(!fgets(buf, sizeof buf, stdin)) { + fprintf(stderr, "Error while reading stdin: %s\n", strerror(errno)); + return 1; + } + int len = rstrip(buf); + if(!len) { + fprintf(stderr, "No name given!\n"); + return 1; + } + name = strdup(buf); + } else { + fprintf(stderr, "No Name given!\n"); + return 1; + } + } else { + name = strdup(argv[1]); + if(!*name) { + fprintf(stderr, "No Name given!\n"); + return 1; + } + } + + if(!check_id(name)) { + fprintf(stderr, "Invalid Name! Only a-z, A-Z, 0-9 and _ are allowed characters.\n"); + return 1; + } + + if(mkdir(confdir, 0755) && errno != EEXIST) { + fprintf(stderr, "Could not create directory %s: %s\n", CONFDIR, strerror(errno)); + return 1; + } + + if(mkdir(confbase, 0755) && errno != EEXIST) { + fprintf(stderr, "Could not create directory %s: %s\n", confbase, strerror(errno)); + return 1; + } + + if(mkdir(hosts_dir, 0755) && errno != EEXIST) { + fprintf(stderr, "Could not create directory %s: %s\n", hosts_dir, strerror(errno)); + return 1; + } + + FILE *f = fopen(tinc_conf, "w"); + if(!f) { + fprintf(stderr, "Could not create file %s: %s\n", tinc_conf, strerror(errno)); + return 1; + } + + fprintf(f, "Name = %s\n", name); + fclose(f); + + if(!rsa_keygen(2048, false) || !ecdsa_keygen(false)) + return 1; + +#ifndef HAVE_MINGW + char *filename; + xasprintf(&filename, "%s" SLASH "tinc-up", confbase); + if(access(filename, F_OK)) { + FILE *f = fopen(filename, "w"); + if(!f) { + fprintf(stderr, "Could not create file %s: %s\n", filename, strerror(errno)); + return 1; + } + fchmod(fileno(f), 0755); + fprintf(f, "#!/bin/sh\n\necho 'Unconfigured tinc-up script, please edit!'\n\n#ifconfig $INTERFACE netmask \n"); + fclose(f); } #endif - if(!strcasecmp(argv[optind], "pcap")) { - pcap(fd, stdout); + return 0; + +} + +static int cmd_generate_keys(int argc, char *argv[]) { + return !(rsa_keygen(argc > 1 ? atoi(argv[1]) : 2048, true) && ecdsa_keygen(true)); +} + +static int cmd_generate_rsa_keys(int argc, char *argv[]) { + return !rsa_keygen(argc > 1 ? atoi(argv[1]) : 2048, true); +} + +static int cmd_generate_ecdsa_keys(int argc, char *argv[]) { + return !ecdsa_keygen(true); +} + +static int cmd_help(int argc, char *argv[]) { + usage(false); + return 0; +} + +static int cmd_version(int argc, char *argv[]) { + version(); + return 0; +} + +static int cmd_info(int argc, char *argv[]) { + if(argc != 2) { + fprintf(stderr, "Invalid number of arguments.\n"); + return 1; + } + + if(!connect_tincd(true)) + return 1; + + return info(fd, argv[1]); +} + +static const char *conffiles[] = { + "tinc.conf", + "tinc-up", + "tinc-down", + "subnet-up", + "subnet-down", + "host-up", + "host-down", + NULL, +}; + +static int cmd_edit(int argc, char *argv[]) { + if(argc != 2) { + fprintf(stderr, "Invalid number of arguments.\n"); + return 1; + } + + char *filename = NULL; + + if(strncmp(argv[1], "hosts" SLASH, 6)) { + for(int i = 0; conffiles[i]; i++) { + if(!strcmp(argv[1], conffiles[i])) { + xasprintf(&filename, "%s" SLASH "%s", confbase, argv[1]); + break; + } + } + } else { + argv[1] += 6; + } + + if(!filename) { + xasprintf(&filename, "%s" SLASH "%s", hosts_dir, argv[1]); + char *dash = strchr(argv[1], '-'); + if(dash) { + *dash++ = 0; + if((strcmp(dash, "up") && strcmp(dash, "down")) || !check_id(argv[1])) { + fprintf(stderr, "Invalid configuration filename.\n"); + return 1; + } + } + } + + char *command; +#ifndef HAVE_MINGW + xasprintf(&command, "\"%s\" \"%s\"", getenv("VISUAL") ?: getenv("EDITOR") ?: "vi", filename); +#else + xasprintf(&command, "edit \"%s\"", filename); +#endif + int result = system(command); + if(result) + return result; + + // Silently try notifying a running tincd of changes. + if(connect_tincd(false)) + sendline(fd, "%d %d", CONTROL, REQ_RELOAD); + + return 0; +} + +static int export(const char *name, FILE *out) { + char *filename; + xasprintf(&filename, "%s" SLASH "%s", hosts_dir, name); + FILE *in = fopen(filename, "r"); + if(!in) { + fprintf(stderr, "Could not open configuration file %s: %s\n", filename, strerror(errno)); + return 1; + } + + fprintf(out, "Name = %s\n", name); + char buf[4096]; + while(fgets(buf, sizeof buf, in)) { + if(strcspn(buf, "\t =") != 4 || strncasecmp(buf, "Name", 4)) + fputs(buf, out); + } + + if(ferror(in)) { + fprintf(stderr, "Error while reading configuration file %s: %s\n", filename, strerror(errno)); + fclose(in); + return 1; + } + + fclose(in); + return 0; +} + +static int cmd_export(int argc, char *argv[]) { + char *name = get_my_name(); + if(!name) + return 1; + + return export(name, stdout); +} + +static int cmd_export_all(int argc, char *argv[]) { + DIR *dir = opendir(hosts_dir); + if(!dir) { + fprintf(stderr, "Could not open host configuration directory %s: %s\n", hosts_dir, strerror(errno)); + return 1; + } + + bool first = true; + int result = 0; + struct dirent *ent; + + while((ent = readdir(dir))) { + if(!check_id(ent->d_name)) + continue; + + if(first) + first = false; + else + printf("#---------------------------------------------------------------#\n"); + + result |= export(ent->d_name, stdout); + } + + closedir(dir); + return result; +} + +static int cmd_import(int argc, char *argv[]) { + FILE *in = stdin; + FILE *out = NULL; + + char buf[4096]; + char name[4096]; + char *filename; + int count = 0; + bool firstline = true; + + while(fgets(buf, sizeof buf, in)) { + if(sscanf(buf, "Name = %s", name) == 1) { + if(!check_id(name)) { + fprintf(stderr, "Invalid Name in input!\n"); + return 1; + } + + if(out) + fclose(out); + + free(filename); + xasprintf(&filename, "%s" SLASH "%s", hosts_dir, name); + + if(!force && !access(filename, F_OK)) { + fprintf(stderr, "Host configuration file %s already exists, skipping.\n", filename); + out = NULL; + continue; + } + + out = fopen(filename, "w"); + if(!out) { + fprintf(stderr, "Error creating configuration file %s: %s\n", filename, strerror(errno)); + return 1; + } + + count++; + firstline = false; + continue; + } else if(firstline) { + fprintf(stderr, "Junk at the beginning of the input, ignoring.\n"); + firstline = false; + } + + + if(!strcmp(buf, "#---------------------------------------------------------------#\n")) + continue; + + if(out) { + if(fputs(buf, out) < 0) { + fprintf(stderr, "Error writing to host configuration file %s: %s\n", filename, strerror(errno)); + return 1; + } + } + } + + if(out) + fclose(out); + + if(count) { + fprintf(stderr, "Imported %d host configuration files.\n", count); return 0; + } else { + fprintf(stderr, "No host configuration files imported.\n"); + return 1; + } +} + +static const struct { + const char *command; + int (*function)(int argc, char *argv[]); +} commands[] = { + {"start", cmd_start}, + {"stop", cmd_stop}, + {"restart", cmd_restart}, + {"reload", cmd_reload}, + {"dump", cmd_dump}, + {"purge", cmd_purge}, + {"debug", cmd_debug}, + {"retry", cmd_retry}, + {"connect", cmd_connect}, + {"disconnect", cmd_disconnect}, + {"top", cmd_top}, + {"pcap", cmd_pcap}, + {"log", cmd_log}, + {"pid", cmd_pid}, + {"config", cmd_config}, + {"init", cmd_init}, + {"generate-keys", cmd_generate_keys}, + {"generate-rsa-keys", cmd_generate_rsa_keys}, + {"generate-ecdsa-keys", cmd_generate_ecdsa_keys}, + {"help", cmd_help}, + {"version", cmd_version}, + {"info", cmd_info}, + {"edit", cmd_edit}, + {"export", cmd_export}, + {"export-all", cmd_export_all}, + {"import", cmd_import}, + {NULL, NULL}, +}; + +#ifdef HAVE_READLINE +static char *complete_command(const char *text, int state) { + static int i; + + if(!state) + i = 0; + else + i++; + + while(commands[i].command) { + if(!strncasecmp(commands[i].command, text, strlen(text))) + return xstrdup(commands[i].command); + i++; + } + + return NULL; +} + +static char *complete_dump(const char *text, int state) { + const char *matches[] = {"nodes", "edges", "subnets", "connections", "graph", NULL}; + static int i; + + if(!state) + i = 0; + else + i++; + + while(matches[i]) { + if(!strncasecmp(matches[i], text, strlen(text))) + return xstrdup(matches[i]); + i++; + } + + return NULL; +} + +static char *complete_config(const char *text, int state) { + const char *sub[] = {"get", "set", "add", "del"}; + static int i; + if(!state) { + i = 0; + if(!strchr(rl_line_buffer + 7, ' ')) + i = -4; + else { + bool found = false; + for(int i = 0; i < 4; i++) { + if(!strncasecmp(rl_line_buffer + 7, sub[i], strlen(sub[i])) && rl_line_buffer[7 + strlen(sub[i])] == ' ') { + found = true; + break; + } + } + if(!found) + return NULL; + } + } else { + i++; + } + + while(i < 0 || variables[i].name) { + if(i < 0 && !strncasecmp(sub[i + 4], text, strlen(text))) + return xstrdup(sub[i + 4]); + if(i >= 0) { + char *dot = strchr(text, '.'); + if(dot) { + if((variables[i].type & VAR_HOST) && !strncasecmp(variables[i].name, dot + 1, strlen(dot + 1))) { + char *match; + xasprintf(&match, "%.*s.%s", dot - text, text, variables[i].name); + return match; + } + } else { + if(!strncasecmp(variables[i].name, text, strlen(text))) + return xstrdup(variables[i].name); + } + } + i++; + } + + return NULL; +} + +static char *complete_info(const char *text, int state) { + static int i; + if(!state) { + i = 0; + if(!connect_tincd(false)) + return NULL; + // Check the list of nodes + sendline(fd, "%d %d", CONTROL, REQ_DUMP_NODES); + sendline(fd, "%d %d", CONTROL, REQ_DUMP_SUBNETS); + } + + while(recvline(fd, line, sizeof line)) { + char item[4096]; + int n = sscanf(line, "%d %d %s", &code, &req, item); + if(n == 2) { + i++; + if(i >= 2) + break; + else + continue; + } + + if(n != 3) { + fprintf(stderr, "Unable to parse dump from tincd, n = %d, i = %d.\n", n, i); + break; + } + + if(!strncmp(item, text, strlen(text))) + return xstrdup(strip_weight(item)); + } + + return NULL; +} + +static char *complete_nothing(const char *text, int state) { + return NULL; +} + +static char **completion (const char *text, int start, int end) { + char **matches = NULL; + + if(!start) + matches = rl_completion_matches(text, complete_command); + else if(!strncasecmp(rl_line_buffer, "dump ", 5)) + matches = rl_completion_matches(text, complete_dump); + else if(!strncasecmp(rl_line_buffer, "config ", 7)) + matches = rl_completion_matches(text, complete_config); + else if(!strncasecmp(rl_line_buffer, "info ", 5)) + matches = rl_completion_matches(text, complete_info); + + return matches; +} +#endif + +static int cmd_shell(int argc, char *argv[]) { + char *prompt; + xasprintf(&prompt, "%s> ", identname); + int result = 0; + char buf[4096]; + char *line = NULL; + int maxargs = argc + 16; + char **nargv = xmalloc(maxargs * sizeof *nargv); + + for(int i = 0; i < argc; i++) + nargv[i] = argv[i]; + +#ifdef HAVE_READLINE + rl_readline_name = "tinc"; + rl_completion_entry_function = complete_nothing; + rl_attempted_completion_function = completion; + rl_filename_completion_desired = 0; + char *copy = NULL; +#endif + + while(true) { +#ifdef HAVE_READLINE + if(tty) { + free(copy); + free(line); + rl_basic_word_break_characters = "\t\n "; + line = readline(prompt); + if(line) + copy = xstrdup(line); + } else { + line = fgets(buf, sizeof buf, stdin); + } +#else + if(tty) + fputs(prompt, stdout); + + line = fgets(buf, sizeof buf, stdin); +#endif + + if(!line) + break; + + /* Ignore comments */ + + if(*line == '#') + continue; + + /* Split */ + + int nargc = argc; + char *p = line + strspn(line, " \t\n"); + char *next = strtok(p, " \t\n"); + + while(p && *p) { + if(nargc >= maxargs) { + fprintf(stderr, "next %p '%s', p %p '%s'\n", next, next, p, p); + abort(); + maxargs *= 2; + nargv = xrealloc(nargv, maxargs * sizeof *nargv); + } + + nargv[nargc++] = p; + p = next; + next = strtok(NULL, " \t\n"); + } + + if(nargc == argc) + continue; + + if(!strcasecmp(nargv[argc], "exit") || !strcasecmp(nargv[argc], "quit")) + return result; + + bool found = false; + + for(int i = 0; commands[i].command; i++) { + if(!strcasecmp(nargv[argc], commands[i].command)) { + result |= commands[i].function(nargc - argc - 1, nargv + argc + 1); + found = true; + break; + } + } + +#ifdef HAVE_READLINE + if(tty && found) + add_history(copy); +#endif + + if(!found) { + fprintf(stderr, "Unknown command `%s'.\n", nargv[argc]); + result |= 1; + } + } + + free(nargv); + + if(tty) + printf("\n"); + return result; +} + + +int main(int argc, char *argv[]) { + program_name = argv[0]; + orig_argv = argv; + orig_argc = argc; + + if(!parse_options(argc, argv)) + return 1; + + make_names(); + + if(show_version) { + version(); + return 0; + } + + if(show_help) { + usage(false); + return 0; + } + + tty = isatty(0) && isatty(1); + + if(optind >= argc) + return cmd_shell(argc, argv); + + for(int i = 0; commands[i].command; i++) { + if(!strcasecmp(argv[optind], commands[i].command)) + return commands[i].function(argc - optind, argv + optind); } fprintf(stderr, "Unknown command `%s'.\n", argv[optind]); usage(true); - - close(fd); - - return 0; + return 1; } diff --git a/src/tincd.c b/src/tincd.c index 8401b20..9f94d89 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-2011 Guus Sliepen + 2000-2012 Guus Sliepen 2008 Max Rijevski 2009 Michael Tokarev 2010 Julien Muchembled @@ -87,10 +87,10 @@ static const char *switchuser = NULL; /* If nonzero, write log entries to a separate file. */ bool use_logfile = false; -char *identname = NULL; /* program name for syslog */ -char *logfilename = NULL; /* log file location */ +char *identname = NULL; /* program name for syslog */ +char *logfilename = NULL; /* log file location */ char *pidfilename = NULL; -char **g_argv; /* a copy of the cmdline arguments */ +char **g_argv; /* a copy of the cmdline arguments */ static int status = 1; @@ -107,6 +107,7 @@ static struct option const long_options[] = { {"user", required_argument, NULL, 'U'}, {"logfile", optional_argument, NULL, 4}, {"pidfile", required_argument, NULL, 5}, + {"option", required_argument, NULL, 'o'}, {NULL, 0, NULL, 0} }; @@ -122,18 +123,18 @@ static void usage(bool status) { program_name); else { printf("Usage: %s [option]...\n\n", program_name); - printf( " -c, --config=DIR Read configuration options from DIR.\n" - " -D, --no-detach Don't fork and detach.\n" - " -d, --debug[=LEVEL] Increase debug level or set it to LEVEL.\n" - " -n, --net=NETNAME Connect to net NETNAME.\n" - " -L, --mlock Lock tinc into main memory.\n" - " --logfile[=FILENAME] Write log entries to a logfile.\n" - " --pidfile=FILENAME Write PID and control socket cookie to FILENAME.\n" - " --bypass-security Disables meta protocol security, for debugging.\n" - " -o [HOST.]KEY=VALUE Set global/host configuration value.\n" - " -R, --chroot chroot to NET dir at startup.\n" - " -U, --user=USER setuid to given USER at startup.\n" " --help Display this help and exit.\n" - " --version Output version information and exit.\n\n"); + printf( " -c, --config=DIR Read configuration options from DIR.\n" + " -D, --no-detach Don't fork and detach.\n" + " -d, --debug[=LEVEL] Increase debug level or set it to LEVEL.\n" + " -n, --net=NETNAME Connect to net NETNAME.\n" + " -L, --mlock Lock tinc into main memory.\n" + " --logfile[=FILENAME] Write log entries to a logfile.\n" + " --pidfile=FILENAME Write PID and control socket cookie to FILENAME.\n" + " --bypass-security Disables meta protocol security, for debugging.\n" + " -o, --option[HOST.]KEY=VALUE Set global/host configuration value.\n" + " -R, --chroot chroot to NET dir at startup.\n" + " -U, --user=USER setuid to given USER at startup.\n" " --help Display this help and exit.\n" + " --version Output version information and exit.\n\n"); printf("Report bugs to tinc@tinc-vpn.org.\n"); } } @@ -148,77 +149,75 @@ static bool parse_options(int argc, char **argv) { while((r = getopt_long(argc, argv, "c:DLd::n:o:RU:", long_options, &option_index)) != EOF) { switch (r) { - case 0: /* long option */ + case 0: /* long option */ break; - case 'c': /* config file */ + case 'c': /* config file */ confbase = xstrdup(optarg); break; - case 'D': /* no detach */ + case 'D': /* no detach */ do_detach = false; break; - case 'L': /* no detach */ + case 'L': /* no detach */ #ifndef HAVE_MLOCKALL - logger(LOG_ERR, "%s not supported on this platform", "mlockall()"); + logger(DEBUG_ALWAYS, LOG_ERR, "%s not supported on this platform", "mlockall()"); return false; #else do_mlock = true; break; #endif - case 'd': /* inc debug level */ + case 'd': /* inc debug level */ if(optarg) debug_level = atoi(optarg); else debug_level++; break; - case 'n': /* net name given */ - /* netname "." is special: a "top-level name" */ - netname = strcmp(optarg, ".") != 0 ? - xstrdup(optarg) : NULL; + case 'n': /* net name given */ + netname = xstrdup(optarg); break; - case 'o': /* option */ + case 'o': /* option */ cfg = parse_config_line(optarg, NULL, ++lineno); if (!cfg) return false; list_insert_tail(cmdline_conf, cfg); break; - case 'R': /* chroot to NETNAME dir */ + case 'R': /* chroot to NETNAME dir */ do_chroot = true; break; - case 'U': /* setuid to USER */ + case 'U': /* setuid to USER */ switchuser = optarg; break; - case 1: /* show help */ + case 1: /* show help */ show_help = true; break; - case 2: /* show version */ + case 2: /* show version */ show_version = true; break; - case 3: /* bypass security */ + case 3: /* bypass security */ bypass_security = true; break; - case 4: /* write log entries to a file */ + case 4: /* write log entries to a file */ use_logfile = true; if(optarg) logfilename = xstrdup(optarg); break; - case 5: /* open control socket here */ + case 5: /* open control socket here */ pidfilename = xstrdup(optarg); break; - case '?': + case '?': /* wrong options */ usage(true); return false; @@ -227,6 +226,21 @@ static bool parse_options(int argc, char **argv) { } } + if(!netname && (netname = getenv("NETNAME"))) + netname = xstrdup(netname); + + /* netname "." is special: a "top-level name" */ + + if(netname && (!*netname || !strcmp(netname, "."))) { + free(netname); + netname = NULL; + } + + if(netname && (strpbrk(netname, "\\/") || *netname == '.')) { + fprintf(stderr, "Invalid character in netname!\n"); + return false; + } + return true; } @@ -249,15 +263,15 @@ static void make_names(void) { if(!RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\tinc", 0, KEY_READ, &key)) { if(!RegQueryValueEx(key, NULL, 0, 0, installdir, &len)) { if(!logfilename) - xasprintf(&logfilename, "%s/log/%s.log", identname); + xasprintf(&logfilename, "%s" SLASH "log" SLASH "%s.log", identname); if(!confbase) { if(netname) - xasprintf(&confbase, "%s/%s", installdir, netname); + xasprintf(&confbase, "%s" SLASH "%s", installdir, netname); else xasprintf(&confbase, "%s", installdir); } if(!pidfilename) - xasprintf(&pidfilename, "%s/pid", confbase); + xasprintf(&pidfilename, "%s" SLASH "pid", confbase); } RegCloseKey(key); if(*installdir) @@ -266,19 +280,19 @@ static void make_names(void) { #endif if(!logfilename) - xasprintf(&logfilename, LOCALSTATEDIR "/log/%s.log", identname); + xasprintf(&logfilename, LOCALSTATEDIR SLASH "log" SLASH "%s.log", identname); if(!pidfilename) - xasprintf(&pidfilename, LOCALSTATEDIR "/run/%s.pid", identname); + xasprintf(&pidfilename, LOCALSTATEDIR SLASH "run" SLASH "%s.pid", identname); if(netname) { if(!confbase) - xasprintf(&confbase, CONFDIR "/tinc/%s", netname); + xasprintf(&confbase, CONFDIR SLASH "tinc" SLASH "%s", netname); else - logger(LOG_INFO, "Both netname and configuration directory given, using the latter..."); + logger(DEBUG_ALWAYS, LOG_INFO, "Both netname and configuration directory given, using the latter..."); } else { if(!confbase) - xasprintf(&confbase, CONFDIR "/tinc"); + xasprintf(&confbase, CONFDIR SLASH "tinc"); } } @@ -293,11 +307,11 @@ static void free_names(void) { static bool drop_privs(void) { #ifdef HAVE_MINGW if (switchuser) { - logger(LOG_ERR, "%s not supported on this platform", "-U"); + logger(DEBUG_ALWAYS, LOG_ERR, "%s not supported on this platform", "-U"); return false; } if (do_chroot) { - logger(LOG_ERR, "%s not supported on this platform", "-R"); + logger(DEBUG_ALWAYS, LOG_ERR, "%s not supported on this platform", "-R"); return false; } #else @@ -305,23 +319,26 @@ static bool drop_privs(void) { if (switchuser) { struct passwd *pw = getpwnam(switchuser); if (!pw) { - logger(LOG_ERR, "unknown user `%s'", switchuser); + logger(DEBUG_ALWAYS, LOG_ERR, "unknown user `%s'", switchuser); return false; } uid = pw->pw_uid; if (initgroups(switchuser, pw->pw_gid) != 0 || setgid(pw->pw_gid) != 0) { - logger(LOG_ERR, "System call `%s' failed: %s", + logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "initgroups", strerror(errno)); return false; } +#ifndef __ANDROID__ +// Not supported in android NDK endgrent(); endpwent(); +#endif } if (do_chroot) { - tzset(); /* for proper timestamps in logs */ + tzset(); /* for proper timestamps in logs */ if (chroot(confbase) != 0 || chdir("/") != 0) { - logger(LOG_ERR, "System call `%s' failed: %s", + logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "chroot", strerror(errno)); return false; } @@ -330,7 +347,7 @@ static bool drop_privs(void) { } if (switchuser) if (setuid(uid) != 0) { - logger(LOG_ERR, "System call `%s' failed: %s", + logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "setuid", strerror(errno)); return false; } @@ -352,13 +369,13 @@ int main(int argc, char **argv) { if(!parse_options(argc, argv)) return 1; - + make_names(); if(show_version) { printf("%s version %s (built %s %s, protocol %d.%d)\n", PACKAGE, VERSION, __DATE__, __TIME__, PROT_MAJOR, PROT_MINOR); - printf("Copyright (C) 1998-2011 Ivo Timmermans, Guus Sliepen and others.\n" + printf("Copyright (C) 1998-2012 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" @@ -374,20 +391,21 @@ int main(int argc, char **argv) { #ifdef HAVE_MINGW if(WSAStartup(MAKEWORD(2, 2), &wsa_state)) { - logger(LOG_ERR, "System call `%s' failed: %s", "WSAStartup", winerror(GetLastError())); + logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "WSAStartup", winerror(GetLastError())); return 1; } #endif openlogger("tinc", use_logfile?LOGMODE_FILE:LOGMODE_STDERR); - if(!event_init()) { - logger(LOG_ERR, "Error initializing libevent!"); - return 1; - } - g_argv = argv; + if(getenv("LISTEN_PID") && atoi(getenv("LISTEN_PID")) == getpid()) + do_detach = false; +#ifdef HAVE_UNSETENV + unsetenv("LISTEN_PID"); +#endif + init_configuration(&config_tree); /* Slllluuuuuuurrrrp! */ @@ -400,7 +418,7 @@ int main(int argc, char **argv) { #ifdef HAVE_LZO if(lzo_init() != LZO_E_OK) { - logger(LOG_ERR, "Error initializing LZO compressor!"); + logger(DEBUG_ALWAYS, LOG_ERR, "Error initializing LZO compressor!"); return 1; } #endif @@ -416,6 +434,7 @@ int main2(int argc, char **argv) { InitializeCriticalSection(&mutex); EnterCriticalSection(&mutex); #endif + char *priority = NULL; if(!detach()) return 1; @@ -425,12 +444,17 @@ int main2(int argc, char **argv) { * This has to be done after daemon()/fork() so it works for child. * No need to do that in parent as it's very short-lived. */ if(do_mlock && mlockall(MCL_CURRENT | MCL_FUTURE) != 0) { - logger(LOG_ERR, "System call `%s' failed: %s", "mlockall", + logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "mlockall", strerror(errno)); return 1; } #endif + if(!event_init()) { + logger(DEBUG_ALWAYS, LOG_ERR, "Error initializing libevent!"); + return 1; + } + /* Setup sockets and open device. */ if(!setup_network()) @@ -445,32 +469,27 @@ int main2(int argc, char **argv) { /* Change process priority */ - char *priority = NULL; - - if(get_config_string(lookup_config(config_tree, "ProcessPriority"), &priority)) { - if(!strcasecmp(priority, "Normal")) { - if (setpriority(NORMAL_PRIORITY_CLASS) != 0) { - logger(LOG_ERR, "System call `%s' failed: %s", - "setpriority", strerror(errno)); - goto end; - } - } else if(!strcasecmp(priority, "Low")) { - if (setpriority(BELOW_NORMAL_PRIORITY_CLASS) != 0) { - logger(LOG_ERR, "System call `%s' failed: %s", - "setpriority", strerror(errno)); - goto end; - } - } else if(!strcasecmp(priority, "High")) { - if (setpriority(HIGH_PRIORITY_CLASS) != 0) { - logger(LOG_ERR, "System call `%s' failed: %s", - "setpriority", strerror(errno)); - goto end; - } - } else { - logger(LOG_ERR, "Invalid priority `%s`!", priority); - goto end; - } - } + if(get_config_string(lookup_config(config_tree, "ProcessPriority"), &priority)) { + if(!strcasecmp(priority, "Normal")) { + if (setpriority(NORMAL_PRIORITY_CLASS) != 0) { + logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "setpriority", strerror(errno)); + goto end; + } + } else if(!strcasecmp(priority, "Low")) { + if (setpriority(BELOW_NORMAL_PRIORITY_CLASS) != 0) { + logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "setpriority", strerror(errno)); + goto end; + } + } else if(!strcasecmp(priority, "High")) { + if (setpriority(HIGH_PRIORITY_CLASS) != 0) { + logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "setpriority", strerror(errno)); + goto end; + } + } else { + logger(DEBUG_ALWAYS, LOG_ERR, "Invalid priority `%s`!", priority); + goto end; + } + } /* drop privileges */ if (!drop_privs()) @@ -482,8 +501,8 @@ int main2(int argc, char **argv) { /* Shutdown properly. */ - ifdebug(CONNECTIONS) - dump_device_stats(); + if(debug_level >= DEBUG_CONNECTIONS) + devops.dump_stats(); close_network_connections(); @@ -491,11 +510,14 @@ end: exit_control(); end_nonet: - logger(LOG_NOTICE, "Terminating"); + logger(DEBUG_ALWAYS, LOG_NOTICE, "Terminating"); + + free(priority); crypto_exit(); exit_configuration(&config_tree); + free(cmdline_conf); free_names(); return status; diff --git a/src/top.c b/src/top.c index f14395e..8232c7a 100644 --- a/src/top.c +++ b/src/top.c @@ -1,6 +1,6 @@ /* top.c -- Show real-time statistics from a running tincd - Copyright (C) 2011 Guus Sliepen + Copyright (C) 2011-2012 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 @@ -59,7 +59,6 @@ static bool cumulative = false; static list_t node_list; static struct timeval now, prev, diff; static int delay = 1000; -static bool running = true; static bool changed = true; static const char *unit = "bytes"; static float scale = 1; @@ -85,10 +84,8 @@ static void update(int fd) { uint64_t out_packets; uint64_t out_bytes; - for(list_node_t *i = node_list.head; i; i = i->next) { - nodestats_t *node = i->data; - node->known = false; - } + for list_each(nodestats_t, ns, &node_list) + ns->known = false; while(recvline(fd, line, sizeof line)) { int n = sscanf(line, "%d %d %s %"PRIu64" %"PRIu64" %"PRIu64" %"PRIu64, &code, &req, name, &in_packets, &in_bytes, &out_packets, &out_bytes); @@ -104,18 +101,17 @@ static void update(int fd) { nodestats_t *found = NULL; - for(list_node_t *i = node_list.head; i; i = i->next) { - nodestats_t *node = i->data; - int result = strcmp(name, node->name); + for list_each(nodestats_t, ns, &node_list) { + int result = strcmp(name, ns->name); if(result > 0) { continue; } if(result == 0) { - found = node; + found = ns; break; } else { found = xmalloc_and_zero(sizeof *found); found->name = xstrdup(name); - list_insert_before(&node_list, i, found); + list_insert_before(&node_list, node, found); changed = true; break; } @@ -153,14 +149,14 @@ static void redraw(void) { if(changed) { n = 0; sorted = xrealloc(sorted, node_list.count * sizeof *sorted); - for(list_node_t *i = node_list.head; i; i = i->next) - sorted[n++] = i->data; + for list_each(nodestats_t, ns, &node_list) + sorted[n++] = ns; changed = false; } for(int i = 0; i < n; i++) sorted[i]->i = i; - + int cmpfloat(float a, float b) { if(a < b) return -1; @@ -247,6 +243,7 @@ static void redraw(void) { void top(int fd) { initscr(); timeout(delay); + bool running = true; while(running) { update(fd); diff --git a/src/uml_socket/device.c b/src/uml_device.c similarity index 62% rename from src/uml_socket/device.c rename to src/uml_device.c index d8f13a5..afdded5 100644 --- a/src/uml_socket/device.c +++ b/src/uml_device.c @@ -1,7 +1,7 @@ /* device.c -- UML network socket Copyright (C) 2002-2005 Ivo Timmermans, - 2002-2009 Guus Sliepen + 2002-2012 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 @@ -28,19 +28,17 @@ #include "logger.h" #include "utils.h" #include "route.h" +#include "xalloc.h" -int device_fd = -1; static int listen_fd = -1; static int request_fd = -1; static int data_fd = -1; static int write_fd = -1; static int state = 0; -char *device = NULL; -char *iface = NULL; static char *device_info; extern char *identname; -extern bool running; +extern volatile bool running; static uint64_t device_total_in = 0; static uint64_t device_total_out = 0; @@ -56,7 +54,7 @@ static struct request { static struct sockaddr_un data_sun; -bool setup_device(void) { +static bool setup_device(void) { struct sockaddr_un listen_sun; static const int one = 1; struct { @@ -74,29 +72,37 @@ bool setup_device(void) { device_info = "UML network socket"; if((write_fd = socket(PF_UNIX, SOCK_DGRAM, 0)) < 0) { - logger(LOG_ERR, "Could not open write %s: %s", device_info, strerror(errno)); + logger(DEBUG_ALWAYS, LOG_ERR, "Could not open write %s: %s", device_info, strerror(errno)); running = false; return false; } +#ifdef FD_CLOEXEC + fcntl(write_fd, F_SETFD, FD_CLOEXEC); +#endif + setsockopt(write_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof one); if(fcntl(write_fd, F_SETFL, O_NONBLOCK) < 0) { - logger(LOG_ERR, "System call `%s' failed: %s", "fcntl", strerror(errno)); + logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "fcntl", strerror(errno)); running = false; return false; } if((data_fd = socket(PF_UNIX, SOCK_DGRAM, 0)) < 0) { - logger(LOG_ERR, "Could not open data %s: %s", device_info, strerror(errno)); + logger(DEBUG_ALWAYS, LOG_ERR, "Could not open data %s: %s", device_info, strerror(errno)); running = false; return false; } +#ifdef FD_CLOEXEC + fcntl(data_fd, F_SETFD, FD_CLOEXEC); +#endif + setsockopt(data_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof one); if(fcntl(data_fd, F_SETFL, O_NONBLOCK) < 0) { - logger(LOG_ERR, "System call `%s' failed: %s", "fcntl", strerror(errno)); + logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "fcntl", strerror(errno)); running = false; return false; } @@ -107,42 +113,46 @@ bool setup_device(void) { name.usecs = tv.tv_usec; data_sun.sun_family = AF_UNIX; memcpy(&data_sun.sun_path, &name, sizeof name); - + if(bind(data_fd, (struct sockaddr *)&data_sun, sizeof data_sun) < 0) { - logger(LOG_ERR, "Could not bind data %s: %s", device_info, strerror(errno)); + logger(DEBUG_ALWAYS, LOG_ERR, "Could not bind data %s: %s", device_info, strerror(errno)); running = false; return false; } if((listen_fd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) { - logger(LOG_ERR, "Could not open %s: %s", device_info, + logger(DEBUG_ALWAYS, LOG_ERR, "Could not open %s: %s", device_info, strerror(errno)); return false; } +#ifdef FD_CLOEXEC + fcntl(device_fd, F_SETFD, FD_CLOEXEC); +#endif + setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof one); if(fcntl(listen_fd, F_SETFL, O_NONBLOCK) < 0) { - logger(LOG_ERR, "System call `%s' failed: %s", "fcntl", strerror(errno)); + logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "fcntl", strerror(errno)); return false; } listen_sun.sun_family = AF_UNIX; strncpy(listen_sun.sun_path, device, sizeof listen_sun.sun_path); if(bind(listen_fd, (struct sockaddr *)&listen_sun, sizeof listen_sun) < 0) { - logger(LOG_ERR, "Could not bind %s to %s: %s", device_info, device, strerror(errno)); + logger(DEBUG_ALWAYS, LOG_ERR, "Could not bind %s to %s: %s", device_info, device, strerror(errno)); return false; } if(listen(listen_fd, 1) < 0) { - logger(LOG_ERR, "Could not listen on %s %s: %s", device_info, device, strerror(errno)); + logger(DEBUG_ALWAYS, LOG_ERR, "Could not listen on %s %s: %s", device_info, device, strerror(errno)); return false; } device_fd = listen_fd; state = 0; - logger(LOG_INFO, "%s is a %s", device, device_info); + logger(DEBUG_ALWAYS, LOG_INFO, "%s is a %s", device, device_info); if(routing_mode == RMODE_ROUTER) overwrite_mac = true; @@ -169,22 +179,26 @@ void close_device(void) { if(iface) free(iface); } -bool read_packet(vpn_packet_t *packet) { +static bool read_packet(vpn_packet_t *packet) { int inlen; switch(state) { case 0: { struct sockaddr sa; - int salen = sizeof sa; + socklen_t salen = sizeof sa; request_fd = accept(listen_fd, &sa, &salen); if(request_fd < 0) { - logger(LOG_ERR, "Could not accept connection to %s %s: %s", device_info, device, strerror(errno)); + logger(DEBUG_ALWAYS, LOG_ERR, "Could not accept connection to %s %s: %s", device_info, device, strerror(errno)); return false; } +#ifdef FD_CLOEXEC + fcntl(request_fd, F_SETFD, FD_CLOEXEC); +#endif + if(fcntl(listen_fd, F_SETFL, O_NONBLOCK) < 0) { - logger(LOG_ERR, "System call `%s' failed: %s", "fcntl", strerror(errno)); + logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "fcntl", strerror(errno)); running = false; return false; } @@ -199,21 +213,21 @@ bool read_packet(vpn_packet_t *packet) { case 1: { if((inlen = read(request_fd, &request, sizeof request)) != sizeof request) { - logger(LOG_ERR, "Error while reading request from %s %s: %s", device_info, + logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading request from %s %s: %s", device_info, device, strerror(errno)); running = false; return false; } if(request.magic != 0xfeedface || request.version != 3 || request.type != REQ_NEW_CONTROL) { - logger(LOG_ERR, "Unknown magic %x, version %d, request type %d from %s %s", + logger(DEBUG_ALWAYS, LOG_ERR, "Unknown magic %x, version %d, request type %d from %s %s", request.magic, request.version, request.type, device_info, device); running = false; return false; } if(connect(write_fd, &request.sock, sizeof request.sock) < 0) { - logger(LOG_ERR, "Could not bind write %s: %s", device_info, strerror(errno)); + logger(DEBUG_ALWAYS, LOG_ERR, "Could not bind write %s: %s", device_info, strerror(errno)); running = false; return false; } @@ -221,7 +235,7 @@ bool read_packet(vpn_packet_t *packet) { write(request_fd, &data_sun, sizeof data_sun); device_fd = data_fd; - logger(LOG_INFO, "Connection with UML established"); + logger(DEBUG_ALWAYS, LOG_INFO, "Connection with UML established"); state = 2; return false; @@ -229,7 +243,7 @@ bool read_packet(vpn_packet_t *packet) { case 2: { if((inlen = read(data_fd, packet->data, MTU)) <= 0) { - logger(LOG_ERR, "Error while reading from %s %s: %s", device_info, + logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info, device, strerror(errno)); running = false; return false; @@ -239,27 +253,31 @@ bool read_packet(vpn_packet_t *packet) { device_total_in += packet->len; - ifdebug(TRAFFIC) logger(LOG_DEBUG, "Read packet of %d bytes from %s", packet->len, + logger(DEBUG_TRAFFIC, LOG_DEBUG, "Read packet of %d bytes from %s", packet->len, device_info); return true; } + + default: + logger(DEBUG_ALWAYS, LOG_ERR, "Invalid value for state variable in " __FILE__); + abort(); } } -bool write_packet(vpn_packet_t *packet) { +static bool write_packet(vpn_packet_t *packet) { if(state != 2) { - ifdebug(TRAFFIC) logger(LOG_DEBUG, "Dropping packet of %d bytes to %s: not connected to UML yet", + logger(DEBUG_TRAFFIC, LOG_DEBUG, "Dropping packet of %d bytes to %s: not connected to UML yet", packet->len, device_info); return false; } - ifdebug(TRAFFIC) logger(LOG_DEBUG, "Writing packet of %d bytes to %s", + logger(DEBUG_TRAFFIC, LOG_DEBUG, "Writing packet of %d bytes to %s", packet->len, device_info); if(write(write_fd, packet->data, packet->len) < 0) { if(errno != EINTR && errno != EAGAIN) { - logger(LOG_ERR, "Can't write to %s %s: %s", device_info, device, strerror(errno)); + logger(DEBUG_ALWAYS, LOG_ERR, "Can't write to %s %s: %s", device_info, device, strerror(errno)); running = false; } @@ -271,8 +289,16 @@ bool write_packet(vpn_packet_t *packet) { return true; } -void dump_device_stats(void) { - logger(LOG_DEBUG, "Statistics for %s %s:", device_info, device); - logger(LOG_DEBUG, " total bytes in: %10"PRIu64, device_total_in); - logger(LOG_DEBUG, " total bytes out: %10"PRIu64, device_total_out); +static void dump_device_stats(void) { + logger(DEBUG_ALWAYS, LOG_DEBUG, "Statistics for %s %s:", device_info, device); + logger(DEBUG_ALWAYS, LOG_DEBUG, " total bytes in: %10"PRIu64, device_total_in); + logger(DEBUG_ALWAYS, LOG_DEBUG, " total bytes out: %10"PRIu64, device_total_out); } + +const devops_t uml_devops = { + .setup = setup_device, + .close = close_device, + .read = read_packet, + .write = write_packet, + .dump_stats = dump_device_stats, +}; diff --git a/src/utils.c b/src/utils.c index 022ac25..aefec8c 100644 --- a/src/utils.c +++ b/src/utils.c @@ -1,7 +1,7 @@ /* utils.c -- gathering of some stupid small functions Copyright (C) 1999-2005 Ivo Timmermans - 2000-2009 Guus Sliepen + 2000-2012 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 @@ -38,7 +38,7 @@ static int charb64decode(char c) { return c - 'a' + 26; else if(c >= 'A') return c - 'A'; - else if(c >= '0') + else if(c >= '0') return c - '0' + 52; else if(c == '+') return 62; @@ -48,14 +48,13 @@ static int charb64decode(char c) { int hex2bin(const char *src, char *dst, int length) { int i; - for(i = 0; i < length && src[i * 2] && src[i * 2 + 1]; i++) + for(i = 0; i < length && isxdigit(src[i * 2]) && isxdigit(src[i * 2 + 1]); i++) dst[i] = charhex2bin(src[i * 2]) * 16 + charhex2bin(src[i * 2 + 1]); return i; } int bin2hex(const char *src, char *dst, int length) { - int i; - for(i = length - 1; i >= 0; i--) { + for(int i = length - 1; i >= 0; i--) { dst[i * 2 + 1] = hexadecimals[(unsigned char) src[i] & 15]; dst[i * 2] = hexadecimals[(unsigned char) src[i] >> 4]; } @@ -66,7 +65,7 @@ int bin2hex(const char *src, char *dst, int length) { int b64decode(const char *src, char *dst, int length) { int i; uint32_t triplet = 0; - unsigned char *udst = dst; + unsigned char *udst = (unsigned char *)dst; for(i = 0; i < length / 3 * 4 && src[i]; i++) { triplet |= charb64decode(src[i]) << (6 * (i & 3)); @@ -92,12 +91,12 @@ int b64decode(const char *src, char *dst, int length) { int b64encode(const char *src, char *dst, int length) { uint32_t triplet; - const unsigned char *usrc = src; + const unsigned char *usrc = (unsigned char *)src; int si = length / 3 * 3; int di = length / 3 * 4; switch(length % 3) { - case 2: + case 2: triplet = usrc[si] | usrc[si + 1] << 8; dst[di] = base64imals[triplet & 63]; triplet >>= 6; dst[di + 1] = base64imals[triplet & 63]; triplet >>= 6; @@ -137,15 +136,17 @@ int b64encode(const char *src, char *dst, int length) { #endif const char *winerror(int err) { - static char buf[1024], *newline; + static char buf[1024], *ptr; + + ptr = buf + sprintf(buf, "(%d) ", err); if (!FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), buf, sizeof(buf), NULL)) { + NULL, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), ptr, sizeof(buf) - (ptr - buf), NULL)) { strncpy(buf, "(unable to format errormessage)", sizeof(buf)); }; - if((newline = strchr(buf, '\r'))) - *newline = '\0'; + if((ptr = strchr(buf, '\r'))) + *ptr = '\0'; return buf; } diff --git a/src/utils.h b/src/utils.h index 67c94f3..04e478a 100644 --- a/src/utils.h +++ b/src/utils.h @@ -1,7 +1,7 @@ /* utils.h -- header file for utils.c Copyright (C) 1999-2005 Ivo Timmermans - 2000-2009 Guus Sliepen + 2000-2011 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 @@ -47,4 +47,4 @@ extern const char *winerror(int); extern unsigned int bitfield_to_int(const void *bitfield, size_t size); -#endif /* __TINC_UTILS_H__ */ +#endif /* __TINC_UTILS_H__ */ diff --git a/src/vde_device.c b/src/vde_device.c new file mode 100644 index 0000000..815b956 --- /dev/null +++ b/src/vde_device.c @@ -0,0 +1,143 @@ +/* + device.c -- VDE plug + Copyright (C) 2012 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "system.h" + +#include + +#include "conf.h" +#include "device.h" +#include "net.h" +#include "logger.h" +#include "utils.h" +#include "route.h" +#include "xalloc.h" + +static struct vdepluglib plug; +static struct vdeconn *conn = NULL; +static int port = 0; +static char *group = NULL; +static char *device_info; + +extern char *identname; +extern volatile bool running; + +static uint64_t device_total_in = 0; +static uint64_t device_total_out = 0; + +static bool setup_device(void) { + libvdeplug_dynopen(plug); + + if(!plug.dl_handle) { + logger(DEBUG_ALWAYS, LOG_ERR, "Could not open libvdeplug library!"); + return false; + } + + if(!get_config_string(lookup_config(config_tree, "Device"), &device)) + xasprintf(&device, LOCALSTATEDIR "/run/vde.ctl"); + + get_config_string(lookup_config(config_tree, "Interface"), &iface); + + get_config_int(lookup_config(config_tree, "VDEPort"), &port); + + get_config_string(lookup_config(config_tree, "VDEGroup"), &group); + + device_info = "VDE socket"; + + struct vde_open_args args = { + .port = port, + .group = group, + .mode = 0700, + }; + + conn = plug.vde_open(device, identname, &args); + if(!conn) { + logger(DEBUG_ALWAYS, LOG_ERR, "Could not open VDE socket %s", device); + return false; + } + + device_fd = plug.vde_datafd(conn); + +#ifdef FD_CLOEXEC + fcntl(device_fd, F_SETFD, FD_CLOEXEC); +#endif + + logger(DEBUG_ALWAYS, LOG_INFO, "%s is a %s", device, device_info); + + if(routing_mode == RMODE_ROUTER) + overwrite_mac = true; + + return true; +} + +static void close_device(void) { + if(conn) + plug.vde_close(conn); + + if(plug.dl_handle) + libvdeplug_dynclose(plug); + + free(device); + + free(iface); +} + +static bool read_packet(vpn_packet_t *packet) { + int lenin = (ssize_t)plug.vde_recv(conn, packet->data, MTU, 0); + if(lenin <= 0) { + logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info, device, strerror(errno)); + running = false; + return false; + } + + packet->len = lenin; + device_total_in += packet->len; + logger(DEBUG_TRAFFIC, LOG_DEBUG, "Read packet of %d bytes from %s", packet->len, device_info); + + return true; +} + +static bool write_packet(vpn_packet_t *packet) { + if((ssize_t)plug.vde_send(conn, packet->data, packet->len, 0) < 0) { + if(errno != EINTR && errno != EAGAIN) { + logger(DEBUG_ALWAYS, LOG_ERR, "Can't write to %s %s: %s", device_info, device, strerror(errno)); + running = false; + } + + return false; + } + + device_total_out += packet->len; + + return true; +} + +static void dump_device_stats(void) { + logger(DEBUG_ALWAYS, LOG_DEBUG, "Statistics for %s %s:", device_info, device); + logger(DEBUG_ALWAYS, LOG_DEBUG, " total bytes in: %10"PRIu64, device_total_in); + logger(DEBUG_ALWAYS, LOG_DEBUG, " total bytes out: %10"PRIu64, device_total_out); +} + +const devops_t vde_devops = { + .setup = setup_device, + .close = close_device, + .read = read_packet, + .write = write_packet, + .dump_stats = dump_device_stats, +}; diff --git a/system.h b/system.h index 5dc1daf..c688622 100644 --- a/system.h +++ b/system.h @@ -1,7 +1,7 @@ /* system.h -- system headers Copyright (C) 1998-2005 Ivo Timmermans - 2003-2006 Guus Sliepen + 2003-2009 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 From ff64081061737cd39103f6a85ed8f7d5ba43efa2 Mon Sep 17 00:00:00 2001 From: Guus Sliepen Date: Mon, 26 Aug 2019 13:44:50 +0200 Subject: [PATCH 03/13] Import Upstream version 1.1~pre4 --- ChangeLog | 264 +++++++++++++++++++++ Makefile.in | 7 +- NEWS | 483 ++++++++++++++++++++------------------- README | 7 +- aclocal.m4 | 1 - config.h.in | 3 - configure | 112 +-------- configure.in | 11 +- doc/Makefile.in | 7 +- doc/sample-config.tar.gz | Bin 1237 -> 1237 bytes doc/tinc.conf.5.in | 152 +----------- doc/tinc.info | 304 +++++++++++++----------- doc/tinc.texi | 94 +++++--- doc/tincctl.8.in | 6 +- gui/Makefile.in | 7 +- have.h | 4 - m4/Makefile.in | 7 +- m4/libevent.m4 | 33 --- src/Makefile.am | 4 +- src/Makefile.in | 23 +- src/connection.c | 6 +- src/connection.h | 3 +- src/control.c | 4 +- src/dropin.h | 18 ++ src/ethernet.h | 4 + src/event.c | 250 ++++++++++++++++++++ src/event.h | 70 ++++++ src/graph.c | 3 +- src/hash.c | 6 +- src/logger.c | 7 +- src/meta.c | 5 +- src/net.c | 175 ++++++++++---- src/net.h | 19 +- src/net_packet.c | 220 ++++++++++-------- src/net_setup.c | 127 +++++----- src/net_socket.c | 42 ++-- src/netutl.c | 2 +- src/node.c | 10 +- src/node.h | 3 +- src/process.c | 3 +- src/protocol.c | 45 ++-- src/route.c | 120 +++++----- src/splay_tree.c | 7 + src/splay_tree.h | 2 + src/sptps_test.c | 1 + src/tincctl.c | 31 ++- src/tincd.c | 5 - src/top.c | 198 ++++++++-------- 48 files changed, 1739 insertions(+), 1176 deletions(-) delete mode 100644 m4/libevent.m4 create mode 100644 src/event.c create mode 100644 src/event.h diff --git a/ChangeLog b/ChangeLog index 831cb4e..67cebbe 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,267 @@ +commit 5b7f42bca4dbfee7a5fa2bc119f4739baaeb2f55 +Author: Guus Sliepen +Date: Wed Dec 5 22:32:10 2012 +0100 + + Releasing 1.1pre4. + +commit 4c16094e949e1f17461ac744118076a3cec437e8 +Author: Guus Sliepen +Date: Wed Dec 5 21:42:43 2012 +0100 + + Fix whitespace. + +commit 4f8abf1b29b117c5d593bfa7703966fd88e9eace +Author: Guus Sliepen +Date: Wed Dec 5 21:40:49 2012 +0100 + + Scale packet counters similar to byte counters. + +commit d5f0ff5df86d06825110527ddc252b1268e31479 +Author: Guus Sliepen +Date: Wed Dec 5 21:33:01 2012 +0100 + + Don't use nested functions. + + This allows tinc to be compiled with Clang. + +commit eb80105ea855f2c7ee0ea467574acf86cf455a77 +Author: Guus Sliepen +Date: Wed Dec 5 14:42:21 2012 +0100 + + Fix compiler warnings on OpenBSD. + +commit 5e3607b616538eac7bb70d78d4f20d847a1c3064 +Author: Guus Sliepen +Date: Mon Dec 3 13:09:40 2012 +0100 + + Remove GraphDumpFile from the manual and manpages. + + This option is not supported in tinc 1.1, "tincctl dump graph" can be used + instead. + +commit a717b9bcfbe811787fd6718fb3f8fb3f272bcfb9 +Author: Guus Sliepen +Date: Mon Dec 3 13:08:03 2012 +0100 + + Add option to dump only a list of reachable nodes. + +commit 75c619e372f02f8225d158fd514f01bd04857d3b +Author: Guus Sliepen +Date: Mon Dec 3 10:41:28 2012 +0100 + + More fixes for Windows. + + In particular, Windows does support many of the timer* macros, except timeradd + and timersub. + +commit d53384c2de6d2824b9adcec111301d86e6b25f8e +Author: Guus Sliepen +Date: Mon Dec 3 09:08:21 2012 +0100 + + Fix compiler error on Windows. + +commit 76816e119b7d38a14823d430aafeff362dfbfd41 +Author: Guus Sliepen +Date: Mon Dec 3 09:07:23 2012 +0100 + + Fix crash in timeout handling. + +commit d19b00606576d19ef206e363ac709daf3bd00f25 +Author: Guus Sliepen +Date: Mon Dec 3 09:02:08 2012 +0100 + + Set a node's pointers to zero before trying to insert it into a tree. + +commit d2b19be1a0dd3c4987aa926117f5bf281892c78b +Author: Guus Sliepen +Date: Thu Nov 29 14:35:08 2012 +0100 + + Fix use of unitialised values in hash tables. + + Not only was Valgrind unhappy about it, it could also result in cache misses. + +commit d9c70767aa6da8b62b4a1034d5f07892603beddd +Author: Guus Sliepen +Date: Thu Nov 29 14:32:12 2012 +0100 + + Fix check for expired events. + + This would trigger a infinite loop if a timeout expired and the next timeout + was not expired yet, but less than 1 second from being expired. + +commit 8825cddd0d8ed6dad00924ef382139da51ca3fc4 +Author: Guus Sliepen +Date: Thu Nov 29 12:37:04 2012 +0100 + + Allow multiple timeouts to expire at the exact same time. + +commit 6bc5d626a8726fc23365ee705761a3c666a08ad4 +Author: Guus Sliepen +Date: Thu Nov 29 12:28:23 2012 +0100 + + Drop libevent and use our own event handling again. + + There are several reasons for this: + + - MacOS/X doesn't support polling the tap device using kqueue, requiring a + workaround to fall back to select(). + - On Windows only sockets are properly handled, therefore tinc uses a second + thread that does a blocking ReadFile() on the TAP-Win32/64 device. However, + this does not mix well with libevent. + - Libevent, event just the core, is quite large, and although it is easy to get + and install on many platforms, it can be a burden. + - Libev is more lightweight and seems technically superior, but it doesn't + abstract away all the platform differences (for example, async events are not + supported on Windows). + +commit d30b9e1272fef18070d37d10b2b3e4bb2fc07f59 +Author: Guus Sliepen +Date: Mon Nov 19 14:20:50 2012 +0100 + + Ensure MTU probe replies are sent back the same way they came in. + + Also sprinkle some comments over mtu_probe_h(). + +commit 3c1b7047332f4b5e9d5ae7109e696b33712a5fb2 +Author: Guus Sliepen +Date: Mon Nov 19 13:50:17 2012 +0100 + + Improve UDP address selection. + + We don't need to search the whole edge tree, we can use the node's own edge + tree since each edge has a pointer to its reverse. Also, we do need to make + sure we try the reflexive address often. + +commit f57129ce3439f3826c12f15feb5df05e5ad8cab9 +Author: Guus Sliepen +Date: Sat Nov 17 22:48:06 2012 +0100 + + Try all known addresses of node during PMTU discovery, now also for SPTPS. + +commit 30404650b28bf72d0b05b55393f2dd492434f9f3 +Author: Guus Sliepen +Date: Sat Nov 17 22:14:52 2012 +0100 + + Choose a suitable socket when updating a node's UDP address. + +commit 8f9ee895224b39347783f3119343efc3bdaa3511 +Author: Guus Sliepen +Date: Thu Nov 15 11:24:18 2012 +0100 + + Also don't use poll() on MacOS/X. + +commit 8a77df9e28114cbfd83351070fdb266cf31fc310 +Author: Guus Sliepen +Date: Thu Nov 15 11:13:40 2012 +0100 + + Disable support for kqueue on MacOS/X. + + Apparently MacOS/X doesn't support kqueue events on character devices. + +commit 818c92e6583006bf2e38f1027044925df6cf0ca0 +Author: Guus Sliepen +Date: Wed Nov 14 10:44:35 2012 +0100 + + Remove text saying you must have one of PrivateKey or PrivateKeyFile in tinc.conf. + +commit e8bf81794f412b27261be0f2aa4eb287352041af +Author: Guus Sliepen +Date: Tue Nov 13 15:05:41 2012 +0100 + + Send broadcast packets using a random socket, and properly support IPv6. + + Before it would always use the first socket, and always send an IPv4 broadcast packet. That + works fine in a lot of situations, but it is better to try all sockets, and to send IPv6 packets + on IPv6 sockets. This is especially important for users that are on IPv6-only networks or that + have multiple physical network interfaces, although in the latter case it probably requires + them to use the ListenAddress variable to create a separate socket for each interface. + +commit 0870c7c32cf8a24f234fc066df867747ddb1ddc7 +Author: Guus Sliepen +Date: Tue Nov 13 15:01:43 2012 +0100 + + Don't take the address of a variable whose scope is about to disappear. + +commit bb3d7f3b31d4a429d1c31c6621d82f34dd552482 +Author: Guus Sliepen +Date: Sun Nov 11 19:01:28 2012 +0100 + + Fix configure script help text for --enable options. + +commit 5bfbb8f6c58307a8109f556caa30be122cc4d39f +Author: Guus Sliepen +Date: Sun Nov 11 19:01:02 2012 +0100 + + Fix index entry for section about readline library. + +commit 5766518589a5e6cc43ba77a4049059ead05fb300 +Author: Guus Sliepen +Date: Sun Nov 11 18:53:23 2012 +0100 + + Mention in the manual that support for LZO and zlib can be disabled. + +commit 6ec4596557d658f6c15c2cb9a96152c8c476118a +Author: Guus Sliepen +Date: Sun Nov 11 18:45:40 2012 +0100 + + Mention libcurses and libreadline in the manual. + +commit 0ee139e91431527015b7132e4c36f8d4ec09f66b +Author: Guus Sliepen +Date: Sat Nov 10 23:45:22 2012 +0100 + + Make sure PMTU discovery works in switch mode with VLAN tags. + + Before, when tinc saw a packet larger than the PMTU with a VLAN tag, it would + not know what to do with it, and would just forward it via TCP. Now, tinc + handles 802.1q packets correctly, as long as there is only one tag. + +commit ade4fccad6857f3d6d548e52bc94ab23751e4fef +Author: Guus Sliepen +Date: Sat Nov 10 23:13:05 2012 +0100 + + Using alloca() for a constant sized buffer is very silly. + + Cppcheck said using alloca() in the 21st century is silly anyway. + +commit b355476e917f377abb6434657933fcf4ffe6870a +Author: Guus Sliepen +Date: Sat Nov 10 23:09:31 2012 +0100 + + Fix potential buffer overflow reading the PID file. + + Found by cppcheck. + +commit edc08b73a9e353bde6db4c73866a6a730a1a7cb4 +Author: Guus Sliepen +Date: Sun Oct 21 17:45:16 2012 +0200 + + Slightly randomize all timeouts. + +commit 717ea66d7ba0c23f27d86b3d5c6992b751135455 +Author: Guus Sliepen +Date: Sun Oct 21 17:35:13 2012 +0200 + + Add the AutoConnect option. + + When set to a non-zero value, tinc will try to maintain exactly that number of + meta connections to other nodes. If there are not enough connections, it will + periodically try to set up an outgoing connection to a random node. If there + are too many connections, it will periodically try to remove an outgoing + connection. + +commit 1f8b70efa0dedbd3642e0ee82a640d125664af34 +Author: Guus Sliepen +Date: Sun Oct 21 17:34:53 2012 +0200 + + Keep track of the number of nodes in a tree. + +commit 0006c754f2e61e108aa2dd5a6ddd2e9b50d51bd6 +Author: Guus Sliepen +Date: Wed Oct 17 13:51:02 2012 +0200 + + Fix warnings from groff. + commit 0db9e471ea53b48687ea247c855cd95ec453530c Author: Guus Sliepen Date: Sun Oct 14 19:22:30 2012 +0200 diff --git a/Makefile.in b/Makefile.in index 3fe02c7..657ca58 100644 --- a/Makefile.in +++ b/Makefile.in @@ -57,10 +57,9 @@ DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \ THANKS config.guess config.sub depcomp install-sh missing ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \ - $(top_srcdir)/m4/curses.m4 $(top_srcdir)/m4/libevent.m4 \ - $(top_srcdir)/m4/lzo.m4 $(top_srcdir)/m4/openssl.m4 \ - $(top_srcdir)/m4/readline.m4 $(top_srcdir)/m4/zlib.m4 \ - $(top_srcdir)/configure.in + $(top_srcdir)/m4/curses.m4 $(top_srcdir)/m4/lzo.m4 \ + $(top_srcdir)/m4/openssl.m4 $(top_srcdir)/m4/readline.m4 \ + $(top_srcdir)/m4/zlib.m4 $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ diff --git a/NEWS b/NEWS index 806f2b7..3dea2b5 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,17 @@ +Version 1.1pre4 December 5 2012 + + * Added the "AutoConnect" option which will let tinc automatically select + which nodes to connect to. + + * Improved performance of VLAN-tagged IP traffic inside the VPN. + + * Ensured LocalDiscovery works with multiple BindToAddress statements and/or + IPv6-only LANs. + + * Dropped dependency on libevent. + + * Fixed Windows version not reading packets from the TAP adapter. + Version 1.1pre3 October 14 2012 * New experimental protocol: @@ -41,7 +55,7 @@ Version 1.1pre1 June 25 2011 * tincctl, a commandline utility * tinc-gui, a preliminary GUI implemented in Python/wxWidgets - * Code cleanups and reorganization. + * Code cleanups and reorganization. * Repleacable cryptography backend, currently supports OpenSSL and libgcrypt. @@ -247,13 +261,13 @@ Version 1.0.6 Dec 18 2006 * Fixed a bug where broadcasts in switch and hub modes sometimes would not work anymore when part of the VPN had become disconnected from the rest. -version 1.0.5 Nov 14 2006 +Version 1.0.5 Nov 14 2006 * Lots of small fixes. * Broadcast packets no longer grow in size with each hop. This should fix switch mode (again). - + * Generic host-up and host-down scripts. * Optionally dump graph in graphviz format to a file or a script. @@ -262,347 +276,354 @@ version 1.0.5 Nov 14 2006 Thanks to Scott Lamb for his contributions to this version of tinc. -version 1.0.4 May 4 2005 +Version 1.0.4 May 4 2005 * Fix switch and hub modes. * Optionally start scripts when a Subnet becomes (un)reachable. -version 1.0.3 Nov 11 2004 +Version 1.0.3 Nov 11 2004 -* Show error message when failing to write a PID file. + * Show error message when failing to write a PID file. -* Ignore spaces at end of lines in config files. + * Ignore spaces at end of lines in config files. -* Fix handling of late packets. + * Fix handling of late packets. -* Unify BSD tun/tap device handling. This allows IPv6 on tun devices and - anything on tap devices as long as the underlying OS supports it. + * Unify BSD tun/tap device handling. This allows IPv6 on tun devices and + anything on tap devices as long as the underlying OS supports it. -* Handle IPv6 on Solaris tun devices. + * Handle IPv6 on Solaris tun devices. -* Allow tinc to work properly under Windows XP SP2. + * Allow tinc to work properly under Windows XP SP2. -* Allow VLAN tagged Ethernet frames in switch and hub mode. + * Allow VLAN tagged Ethernet frames in switch and hub mode. -* Experimental PMTUDiscovery, TunnelServer and BlockingTCP options. + * Experimental PMTUDiscovery, TunnelServer and BlockingTCP options. -version 1.0.2 Nov 8 2003 +Version 1.0.2 Nov 8 2003 -* Fix address and hostname resolving under Windows. + * Fix address and hostname resolving under Windows. -* Remove warnings about non-existing scripts and unsupported address families. + * Remove warnings about non-existing scripts and unsupported address families. -* Use the event logger under Windows. + * Use the event logger under Windows. -* Fix quoting of filenames and command line arguments under Windows. + * Fix quoting of filenames and command line arguments under Windows. -* Strict checks for length incoming network packets and return values of - cryptographic functions, + * Strict checks for length incoming network packets and return values of + cryptographic functions, -* Fix a bug in metadata handling that made the tinc daemon abort. + * Fix a bug in metadata handling that made the tinc daemon abort. -version 1.0.1 Aug 14 2003 +Version 1.0.1 Aug 14 2003 -* Allow empty lines in config files. + * Allow empty lines in config files. -* Fix handling of spaces and backslashes in filenames under native Windows. + * Fix handling of spaces and backslashes in filenames under native Windows. -* Allow scripts to be executed under native Windows. + * Allow scripts to be executed under native Windows. -* Update documentation, make it less Linux specific. + * Update documentation, make it less Linux specific. -version 1.0 Aug 4 2003 +Version 1.0 Aug 4 2003 -* Lots of small bugfixes and code cleanups. + * Lots of small bugfixes and code cleanups. -* Throughput doubled and latency reduced. + * Throughput doubled and latency reduced. -* Added support for LZO compression. + * Added support for LZO compression. -* No need to set MAC address or disable ARP anymore. + * No need to set MAC address or disable ARP anymore. -* Added support for Windows 2000 and XP, both natively and in a Cygwin - environment. + * Added support for Windows 2000 and XP, both natively and in a Cygwin + environment. -version 1.0pre8 Sep 16 2002 +Version 1.0pre8 Sep 16 2002 -* More fixes for subnets with prefixlength undivisible by 8. + * More fixes for subnets with prefixlength undivisible by 8. -* Added support for NetBSD and MacOS/X. + * Added support for NetBSD and MacOS/X. -* Switched from undirected graphs to directed graphs to avoid certain race - conditions and improve scalability. + * Switched from undirected graphs to directed graphs to avoid certain race + conditions and improve scalability. -* Generalized broadcasting and forwarding of protocol messages. + * Generalized broadcasting and forwarding of protocol messages. -* Cleanup of source code. + * Cleanup of source code. +Version 1.0pre7 Apr 7 2002 -version 1.0pre7 Apr 7 2002 + * Don't do blocking read()s when getting a signal. -* Don't do blocking read()s when getting a signal. + * Remove RSA key checking code, since it sometimes thinks perfectly good RSA + keys are bad. -* Remove RSA key checking code, since it sometimes thinks perfectly good RSA - keys are bad. + * Fix handling of subnets when prefixlength isn't divisible by 8. -* Fix handling of subnets when prefixlength isn't divisible by 8. +Version 1.0pre6 Mar 27 2002 + * Improvement of redundant links: + * Non-blocking connects. + * Protocol broadcast messages can no longer go into an infinite loop. + * Graph algorithm updated to look harder for direct connections. -version 1.0pre6 Mar 27 2002 + * Good support for routing IPv6 packets over the VPN. Works on Linux, + FreeBSD, possibly OpenBSD but not on Solaris. -* Improvement of redundant links: + * Support for tunnels over IPv6 networks. Works on all supported + operating systems. - * Non-blocking connects. - - * Protocol broadcast messages can no longer go into an infinite loop. - - * Graph algorithm updated to look harder for direct connections. + * Optional compression of UDP connections using zlib. -* Good support for routing IPv6 packets over the VPN. Works on Linux, - FreeBSD, possibly OpenBSD but not on Solaris. + * Optionally let UDP connections inherit TOS field of tunneled packets. -* Support for tunnels over IPv6 networks. Works on all supported - operating systems. + * Optionally start scripts when certain hosts become (un)reachable. -* Optional compression of UDP connections using zlib. +Version 1.0pre5 Feb 9 2002 -* Optionally let UDP connections inherit TOS field of tunneled packets. + * Security enhancements: + * Added sequence number and optional message authentication code to + the packets. + * Configurable encryption cipher and digest algorithms. -* Optionally start scripts when certain hosts become (un)reachable. + * More robust handling of dis- and reconnects. + * Added a "switch" and a "hub" mode to allow bridging setups. -version 1.0pre5 Feb 9 2002 + * Preliminary support for routing of IPv6 packets. -* Security enhancements: + * Supports Linux, FreeBSD, OpenBSD and Solaris. - * Added sequence number and optional message authentication code to - the packets. +Version 1.0pre4 Jan 17 2001 - * Configurable encryption cipher and digest algorithms. + * Updated documentation; the documentation now reflects the + configuration as it is. -* More robust handling of dis- and reconnects. + * Some internal changes to make tinc scale better for large + networks, such as using AVL trees instead of linked lists for the + connection list. -* Added a "switch" and a "hub" mode to allow bridging setups. + * RSA keys can be stored in separate files if needed. See the + documentation for more information. -* Preliminary support for routing of IPv6 packets. + * Tinc has now been reported to run on Linux PowerPC and FreeBSD x86. -* Supports Linux, FreeBSD, OpenBSD and Solaris. +Version 1.0pre3 Oct 31 2000 + * The protocol has been redesigned, and although some details are + still under discussion, this is secure. Care has been taken to + resist most, if not all, attacks. -It looks like this might be the last release before 1.0. + * Unfortunately this protocol is not compatible with earlier versions, + nor are earlier versions compatible with this version. Because the + older protocol has huge security flaws, we feel that not + implementing backwards compatibility is justified. + * Some data about the protocol: + * It uses public/private RSA keys for authentication (this is the + actual fix for the security hole). + * All cryptographic functions have been taken out of tinc, instead + it uses the OpenSSL library functions. + * Offers support for multiple subnets per tinc daemon. -version 1.0pre4 Jan 17 2001 + * New is also the support for the universal tun/tap device. This + means better portability to FreeBSD and Solaris. -* Updated documentation; the documentation now reflects the - configuration as it is. + * Tinc is tested to compile on Solaris, Linux x86, Linux alpha. -* Some internal changes to make tinc scale better for large - networks, such as using AVL trees instead of linked lists for the - connection list. + * Tinc now uses the OpenSSL library for cryptographic operations. + More information on getting and installing OpenSSL is in the manual. + This also means that the GMP library is no longer required. -* RSA keys can be stored in separate files if needed. See the - documentation for more information. + * Further, thanks to Enrique Zanardi, we have Spanish messages; Matias + Carrasco provided us with a Spanish translation of the manual. -* tinc has now been reported to run on Linux PowerPC and FreeBSD x86. +Version 1.0pre2 May 31 2000 + * This version has been internationalized; and a Dutch translation has + been included. + * Two configuration variables have been added: + * VpnMask - the IP network mask for the entire VPN, not just our + subnet (as given by MyVirtualIP). The Redhat and Debian packages + use this variable in their system startup scripts, but it is + ignored by tinc. + * Hostnames - if set to `yes', look up the names of IP addresses + trying to connect to us. Default set to `no', to prevent lockups + during lookups. -version 1.0pre3 Oct 31 2000 + * The system startup scripts for Debian and Redhat use + /etc/tinc/nets.boot to find out which networks need to be started + during system boot. -* The protocol has been redesigned, and although some details are - still under discussion, this is secure. Care has been taken to - resist most, if not all, attacks. - -* Unfortunately this protocol is not compatible with earlier versions, - nor are earlier versions compatible with this version. Because the - older protocol has huge security flaws, we feel that not - implementing backwards compatibility is justified. + * Fixes to prevent denial of service attacks by sending random data + after connecting (and even when the connection has been established), + either random garbage or just nonsensical protocol fields. -* Some data about the protocol: + * Tinc will retry to connect upon startup, does not quit if it doesn't + work the first time. - * It uses public/private RSA keys for authentication (this is the - actual fix for the security hole). + * Hosts that are disconnected implicitly if we lose a connection get + deleted from the internal list, to prevent hogging eachother with + add and delete requests when the connection is restored. - * All cryptographic functions have been taken out of tinc, instead - it uses the OpenSSL library functions. +Version 1.0pre1 May 12 2000 - * Offers support for multiple subnets per tinc daemon. - -* New is also the support for the universal tun/tap device. This - means better portability to FreeBSD and Solaris. - -* tinc is tested to compile on Solaris, Linux x86, Linux alpha. - -* tinc now uses the OpenSSL library for cryptographic operations. - More information on getting and installing OpenSSL is in the manual. - This also means that the GMP library is no longer required. - -* Further, thanks to Enrique Zanardi, we have Spanish messages; Matias - Carrasco provided us with a Spanish translation of the manual. - - -What still needs to be done before 1.0: - -* Documentation. Especially since the protocol has changed, and a lot - of configuration directives have been added. - - - - -version 1.0pre2 May 31 2000 - -* This version has been internationalized; and a Dutch translation has - been included. - -* Two configuration variables have been added: - * VpnMask - the IP network mask for the entire VPN, not just our - subnet (as given by MyVirtualIP). The Redhat and Debian packages - use this variable in their system startup scripts, but it is - ignored by tinc. - * Hostnames - if set to `yes', look up the names of IP addresses - trying to connect to us. Default set to `no', to prevent lockups - during lookups. - -* The system startup scripts for Debian and Redhat use - /etc/tinc/nets.boot to find out which networks need to be started - during system boot. - -* Fixes to prevent denial of service attacks by sending random data - after connecting (and even when the connection has been established), - either random garbage or just nonsensical protocol fields. - -* tinc will retry to connect upon startup, does not quit if it doesn't - work the first time. - -* Hosts that are disconnected implicitly if we lose a connection get - deleted from the internal list, to prevent hogging eachother with - add and delete requests when the connection is restored. - - -What still needs to be done before 1.0: - -* Documentation. -* Failover ConnectTo lines, try another one if the first doesn't work. - - - - -version 1.0pre1 May 12 2000 * New meta-protocol + * Various other bugfixes + * Documentation updates -version 0.3.3 Feb 9 2000 - * Fixed bug that made tinc stop working with latest kernels (Guus - Sliepen) +Version 0.3.3 Feb 9 2000 + + * Fixed bug that made tinc stop working with latest kernels + * Updated the manual -version 0.3.2 Nov 12 1999 - * no more `Invalid filedescriptor' when working with multiple - connections - * forward unknown packets to uplink +Version 0.3.2 Nov 12 1999 -version 0.3.1 Oct 20 1999 - * fixed a bug where tinc would exit without a trace + * No more `Invalid filedescriptor' when working with multiple + connections. -version 0.3 Aug 20 1999 - * pings now work immediately - * all packet sizes get transmitted correctly + * Forward unknown packets to uplink. -version 0.2.26 Aug 15 1999 - * fixed some remaining bugs - * --sysconfdir works with configure - * last version before 0.3 +Version 0.3.1 Oct 20 1999 -version 0.2.25 Aug 8 1999 - * improved stability, going towards 0.3 now. + * Fixed a bug where tinc would exit without a trace. -version 0.2.24 Aug 7 1999 - * added key aging, there's a new config variable, KeyExpire. - * updated man and info pages +Version 0.3 Aug 20 1999 -version 0.2.23 Aug 5 1999 - * all known bugs fixed, this is a candidate for 0.3 + * Pings now work immediately. -version 0.2.22 Apr 11 1999 - * multiconnection thing is now working nearly perfect :) + * All packet sizes get transmitted correctly. + +Version 0.2.26 Aug 15 1999 + + * Fixed some remaining bugs. + + * --sysconfdir works with configure. + + * Last version before 0.3. + +Version 0.2.25 Aug 8 1999 + + * Improved stability, going towards 0.3 now. + +Version 0.2.24 Aug 7 1999 + + * Added key aging, there's a new config variable, KeyExpire. + + * Updated man and info pages. + +Version 0.2.23 Aug 5 1999 + + * All known bugs fixed, this is a candidate for 0.3. + +Version 0.2.22 Apr 11 1999 + + * Multiconnection thing is now working nearly perfect :) + +Version 0.2.21 Apr 10 1999 -version 0.2.21 Apr 10 1999 * You shouldn't notice a thing, but a lot has changed wrt key management - except that it refuses to talk to versions < 0.2.20 -version 0.2.20 +Version 0.2.19 Apr 3 1999 -version 0.2.19 Apr 3 1999 - * don't install a libcipher.so + * Don't install a libcipher.so. -version 0.2.18 Apr 3 1999 - * blowfish library dynamically loaded upon execution - * included Eric Young's IDEA library +Version 0.2.18 Apr 3 1999 -version 0.2.17 Apr 1 1999 - * tincd now re-executes itself in case of a segmentation fault. + * Blowfish library dynamically loaded upon execution. -version 0.2.16 Apr 1 1999 - * wrote tincd.conf(5) man page, which still needs a lot of work. - * config file now accepts and tolerates spaces, and any integer base -for integer variables, and better error reporting. See -doc/tincd.conf.sample for an example. + * Included Eric Young's IDEA library. -version 0.2.15 Mar 29 1999 - * fixed bugs +Version 0.2.17 Apr 1 1999 -version 0.2.14 Feb 10 1999 - * added --timeout flag and PingTimeout configuration - * did some first syslog cleanup work + * Tincd now re-executes itself in case of a segmentation fault. -version 0.2.13 Jan 23 1999 - * bugfixes +Version 0.2.16 Apr 1 1999 -version 0.2.12 Jan 23 1999 - * fixed nauseating bug so that it would crash whenever a connection -got lost + * Wrote tincd.conf(5) man page, which still needs a lot of work. -version 0.2.11 Jan 22 1999 - * framework for multiple connections has been done - * simple manpage for tincd + * Config file now accepts and tolerates spaces, and any integer base + for integer variables, and better error reporting. See + doc/tincd.conf.sample for an example. -version 0.2.10 Jan 18 1999 - * passphrase support added +Version 0.2.15 Mar 29 1999 -version 0.2.9 Jan 13 1999 - * bugs fixed. + * Fixed bugs. -version 0.2.8 Jan 11 1999 - * a reworked protocol version - * a ping/pong system - * more reliable networking code - * automatic reconnection - * still does not work with more than one connection :) - * strips MAC addresses before sending, so there's less overhead, and -less redundancy +Version 0.2.14 Feb 10 1999 -version 0.2.7 Jan 3 1999 - * several updates to make extending more easy. + * Added --timeout flag and PingTimeout configuration. + * Did some first syslog cleanup work. + +Version 0.2.13 Jan 23 1999 + + * Bugfixes. + +Version 0.2.12 Jan 23 1999 + + * Fixed nauseating bug so that it would crash whenever a connection + got lost. + +Version 0.2.11 Jan 22 1999 + + * Framework for multiple connections has been done. + + * Simple manpage for tincd. + +Version 0.2.10 Jan 18 1999 + + * Passphrase support added. + +Version 0.2.9 Jan 13 1999 + + * Bugs fixed. + +Version 0.2.8 Jan 11 1999 + + * A reworked protocol version. + + * A ping/pong system. + + * More reliable networking code. + + * Automatic reconnection. + + * Still does not work with more than one connection :) + + * Strips MAC addresses before sending, so there's less overhead, and + less redundancy. + +Version 0.2.7 Jan 3 1999 + + * Several updates to make extending more easy. + +Version 0.2.6 Dec 20 1998 -version 0.2.6 Dec 20 1998 * Point-to-Point connections have been established, including -blowfish encryption and a secret key-exchange. + Blowfish encryption and a secret key-exchange. + +Version 0.2.5 Dec 16 1998 -version 0.2.5 Dec 16 1998 * Project renamed to tinc, in honour of TINC. -version 0.2.4 Dec 16 1998 - * now it really does ;) +Version 0.2.4 Dec 16 1998 -version 0.2.3 Nov 24 1998 - * it sort of works now + * Now it really does ;) -version 0.2.2 Nov 20 1998 - * uses GNU gmp. +Version 0.2.3 Nov 24 1998 -version 0.2.1 Nov 14 1998 + * It sort of works now. + +Version 0.2.2 Nov 20 1998 + + * Uses GNU gmp. + +Version 0.2.1 Nov 14 1998 * Bare version. diff --git a/README b/README index 10cb0b5..639829c 100644 --- a/README +++ b/README @@ -1,4 +1,4 @@ -This is the README file for tinc version 1.1pre3. Installation +This is the README file for tinc version 1.1pre4. Installation instructions may be found in the INSTALL file. tinc is Copyright (C) 1998-2012 by: @@ -36,11 +36,11 @@ at your own risk. Compatibility ------------- -Version 1.1pre3 is compatible with 1.0pre8, 1.0 and later, but not with older +Version 1.1pre4 is compatible with 1.0pre8, 1.0 and later, but not with older versions of tinc. When the ExperimentalProtocol option is used, tinc is still compatible with -1.0.X and 1.1pre3 itself, but not with any other 1.1preX version. +1.0.X and 1.1pre4 itself, but not with any other 1.1preX version. Requirements @@ -50,7 +50,6 @@ In order to compile tinc, you will need a GNU C compiler environment. Please ensure you have the latest stable versions of all the required libraries: - OpenSSL (http://www.openssl.org/) version 1.0.0 or later. -- Libevent (http://monkey.org/~provos/libevent/) The following libraries are used by default, but can be disabled if necessary: diff --git a/aclocal.m4 b/aclocal.m4 index 4171fdd..181bd2f 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -1135,7 +1135,6 @@ AC_SUBST([am__untar]) m4_include([m4/attribute.m4]) m4_include([m4/curses.m4]) -m4_include([m4/libevent.m4]) m4_include([m4/lzo.m4]) m4_include([m4/openssl.m4]) m4_include([m4/readline.m4]) diff --git a/config.h.in b/config.h.in index ce11d29..7d902fe 100644 --- a/config.h.in +++ b/config.h.in @@ -64,9 +64,6 @@ /* Define to 1 if you have the `ECDSA_verify' function. */ #undef HAVE_ECDSA_VERIFY -/* Define to 1 if you have the header file. */ -#undef HAVE_EVENT_H - /* Define to 1 if you have the `EVP_EncryptInit_ex' function. */ #undef HAVE_EVP_ENCRYPTINIT_EX diff --git a/configure b/configure index ecbfc43..01cfacd 100755 --- a/configure +++ b/configure @@ -738,7 +738,6 @@ enable_uml enable_vde enable_tunemu with_windows2000 -with_libgcrypt enable_curses with_curses with_curses_include @@ -747,9 +746,6 @@ enable_readline with_readline with_readline_include with_readline_lib -with_libevent -with_libevent_include -with_libevent_lib enable_zlib with_zlib with_zlib_include @@ -1393,9 +1389,9 @@ Optional Features: --enable-dependency-tracking do not reject slow dependency extractors --enable-maintainer-mode enable make rules and dependencies not useful (and sometimes confusing) to the casual installer - --disable-uml enable support for User Mode Linux - --disable-vde enable support for Virtual Distributed Ethernet - --disable-tunemu enable support for the tunemu driver + --enable-uml enable support for User Mode Linux + --enable-vde enable support for Virtual Distributed Ethernet + --enable-tunemu enable support for the tunemu driver --disable-curses disable curses support --disable-readline disable readline support --disable-zlib disable zlib compression support @@ -1408,7 +1404,6 @@ Optional Packages: --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --without-windows2000 compile with support for Windows 2000. This disables support for tunneling over existing IPv6 networks. - --with-libgcrypt enable use of libgcrypt instead of OpenSSL] --with-curses=DIR curses base directory, or: --with-curses-include=DIR curses headers directory @@ -1417,10 +1412,6 @@ Optional Packages: --with-readline-include=DIR readline headers directory --with-readline-lib=DIR readline library directory - --with-libevent=DIR libevent base directory, or: - --with-libevent-include=DIR - libevent headers directory - --with-libevent-lib=DIR libevent library directory --with-zlib=DIR zlib base directory, or: --with-zlib-include=DIR zlib headers directory --with-zlib-lib=DIR zlib library directory @@ -4104,7 +4095,7 @@ fi # Define the identity of the package. PACKAGE=tinc - VERSION=1.1pre3 + VERSION=1.1pre4 cat >>confdefs.h <<_ACEOF @@ -5929,12 +5920,6 @@ rm -f confcache -# Check whether --with-libgcrypt was given. -if test "${with_libgcrypt+set}" = set; then : - withval=$with_libgcrypt; -fi - - # Check whether --enable-curses was given. if test "${enable_curses+set}" = set; then : @@ -6145,95 +6130,6 @@ fi - -# Check whether --with-libevent was given. -if test "${with_libevent+set}" = set; then : - withval=$with_libevent; libevent="$withval" - CPPFLAGS="$CPPFLAGS -I$withval/include" - LDFLAGS="$LDFLAGS -L$withval/lib" - -fi - - - -# Check whether --with-libevent-include was given. -if test "${with_libevent_include+set}" = set; then : - withval=$with_libevent_include; libevent_include="$withval" - CPPFLAGS="$CPPFLAGS -I$withval" - -fi - - - -# Check whether --with-libevent-lib was given. -if test "${with_libevent_lib+set}" = set; then : - withval=$with_libevent_lib; libevent_lib="$withval" - LDFLAGS="$LDFLAGS -L$withval" - -fi - - - for ac_header in event.h -do : - ac_fn_c_check_header_mongrel "$LINENO" "event.h" "ac_cv_header_event_h" "$ac_includes_default" -if test "x$ac_cv_header_event_h" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_EVENT_H 1 -_ACEOF - -else - as_fn_error $? "\"libevent header files not found.\"" "$LINENO" 5; break - -fi - -done - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for event_init in -levent" >&5 -$as_echo_n "checking for event_init in -levent... " >&6; } -if ${ac_cv_lib_event_event_init+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-levent $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char event_init (); -int -main () -{ -return event_init (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_event_event_init=yes -else - ac_cv_lib_event_event_init=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_event_event_init" >&5 -$as_echo "$ac_cv_lib_event_event_init" >&6; } -if test "x$ac_cv_lib_event_event_init" = xyes; then : - LIBS="-levent $LIBS" -else - as_fn_error $? "\"libevent libraries not found.\"" "$LINENO" 5 - -fi - - - # Check whether --enable-zlib was given. if test "${enable_zlib+set}" = set; then : enableval=$enable_zlib; diff --git a/configure.in b/configure.in index 5781537..e513248 100644 --- a/configure.in +++ b/configure.in @@ -4,7 +4,7 @@ AC_PREREQ(2.61) AC_INIT AC_CONFIG_SRCDIR([src/tincd.c]) AC_GNU_SOURCE -AM_INIT_AUTOMAKE(tinc, 1.1pre3) +AM_INIT_AUTOMAKE(tinc, 1.1pre4) AC_CONFIG_HEADERS([config.h]) AM_MAINTAINER_MODE @@ -74,7 +74,7 @@ case $host_os in esac AC_ARG_ENABLE(uml, - AS_HELP_STRING([--disable-uml], [enable support for User Mode Linux]), + AS_HELP_STRING([--enable-uml], [enable support for User Mode Linux]), [ AS_IF([test "x$enable_uml" = "xyes"], [ AC_DEFINE(ENABLE_UML, 1, [Support for UML]) uml=true @@ -85,7 +85,7 @@ AC_ARG_ENABLE(uml, ) AC_ARG_ENABLE(vde, - AS_HELP_STRING([--disable-vde], [enable support for Virtual Distributed Ethernet]), + AS_HELP_STRING([--enable-vde], [enable support for Virtual Distributed Ethernet]), [ AS_IF([test "x$enable_vde" = "xyes"], [ AC_CHECK_HEADERS(libvdeplug_dyn.h, [], [AC_MSG_ERROR([VDE plug header files not found.]); break]) AC_DEFINE(ENABLE_VDE, 1, [Support for VDE]) @@ -97,7 +97,7 @@ AC_ARG_ENABLE(vde, ) AC_ARG_ENABLE(tunemu, - AS_HELP_STRING([--disable-tunemu], [enable support for the tunemu driver]), + AS_HELP_STRING([--enable-tunemu], [enable support for the tunemu driver]), [ AS_IF([test "x$enable_tunemu" = "xyes"], [ AC_DEFINE(ENABLE_TUNEMU, 1, [Support for tunemu]) tunemu=true @@ -179,11 +179,10 @@ AC_CACHE_SAVE dnl These are defined in files in m4/ -AC_ARG_WITH(libgcrypt, AC_HELP_STRING([--with-libgcrypt], [enable use of libgcrypt instead of OpenSSL])], []) +dnl AC_ARG_WITH(libgcrypt, AC_HELP_STRING([--with-libgcrypt], [enable use of libgcrypt instead of OpenSSL])], []) tinc_CURSES tinc_READLINE -tinc_LIBEVENT tinc_ZLIB tinc_LZO diff --git a/doc/Makefile.in b/doc/Makefile.in index 4610da9..3212126 100644 --- a/doc/Makefile.in +++ b/doc/Makefile.in @@ -53,10 +53,9 @@ subdir = doc DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in texinfo.tex ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \ - $(top_srcdir)/m4/curses.m4 $(top_srcdir)/m4/libevent.m4 \ - $(top_srcdir)/m4/lzo.m4 $(top_srcdir)/m4/openssl.m4 \ - $(top_srcdir)/m4/readline.m4 $(top_srcdir)/m4/zlib.m4 \ - $(top_srcdir)/configure.in + $(top_srcdir)/m4/curses.m4 $(top_srcdir)/m4/lzo.m4 \ + $(top_srcdir)/m4/openssl.m4 $(top_srcdir)/m4/readline.m4 \ + $(top_srcdir)/m4/zlib.m4 $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d diff --git a/doc/sample-config.tar.gz b/doc/sample-config.tar.gz index d7edc13ec53c0242d6f8827c97a86c3e59c1e427..aa515c9580c1260a64261216fef38108a941b900 100644 GIT binary patch delta 16 Xcmcc0d6ko0zMF&Lu+{#J?B`ejFh&Ku delta 16 Xcmcc0d6ko0zMF$#YZuo>_H!%%E;|KD diff --git a/doc/tinc.conf.5.in b/doc/tinc.conf.5.in index f868c15..350a410 100644 --- a/doc/tinc.conf.5.in +++ b/doc/tinc.conf.5.in @@ -3,16 +3,13 @@ .\" Manual page created by: .\" Ivo Timmermans .\" Guus Sliepen - .Sh NAME .Nm tinc.conf .Nd tinc daemon configuration - .Sh DESCRIPTION The files in the .Pa @sysconfdir@/tinc/ directory contain runtime and security information for the tinc daemon. - .Sh NETWORKS To distinguish multiple instances of tinc running on one computer, you can use the @@ -44,31 +41,26 @@ the configuration file should be .Pa @sysconfdir@/tinc/tinc.conf , and the host configuration files are now expected to be in .Pa @sysconfdir@/tinc/hosts/ . - .Sh NAMES Each tinc daemon should have a name that is unique in the network which it will be part of. The name will be used by other tinc daemons for identification. The name has to be declared in the .Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /tinc.conf file. - .Pp To make things easy, choose something that will give unique and easy to remember names to your tinc daemon(s). You could try things like hostnames, owner surnames or location names. However, you are only allowed to use alphanumerical characters (a-z, A-Z, and 0-9) and underscores (_) in the name. - .Sh INITIAL CONFIGURATION If you have not configured tinc yet, you can easily create a basic configuration using the following command: .Bd -literal -offset indent .Nm tincctl Fl n Ar NETNAME Li init Ar NAME .Ed - .Pp You can further change the configuration as needed either by manually editing the configuration files, or by using .Xr tincctl 8 . - .Sh PUBLIC/PRIVATE KEYS The .Nm tincctl Li init @@ -81,24 +73,20 @@ in the directory .Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa / The public keys should be stored in the host configuration file .Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /hosts/ Ns Va NAME . - The RSA keys are used for backwards compatibility with tinc version 1.0. If you are upgrading from version 1.0 to 1.1, you can keep the old configuration files, but you will need to create ECDSA keys using the following command: .Bd -literal -offset indent .Nm tincctl Fl n Ar NETNAME Li generate-ecdsa-keys .Ed - .Sh SERVER CONFIGURATION The server configuration of the daemon is done in the file .Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /tinc.conf . This file consists of comments (lines started with a .Li # ) or assignments in the form of: - .Pp .Va Variable Li = Ar Value . - .Pp The variable names are case insensitive, and any spaces, tabs, newlines and carriage returns are ignored. @@ -106,31 +94,35 @@ Note: it is not required that you put in the .Li = sign, but doing so improves readability. If you leave it out, remember to replace it with at least one space character. - .Pp The server configuration is complemented with host specific configuration (see the next section). Although all configuration options for the local host listed in this document can also be put in .Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /tinc.conf , it is recommended to put host specific configuration options in the host configuration file, as this makes it easy to exchange with other nodes. - .Pp You can edit the config file manually, but it is recommended that you use .Xr tincctl 8 to change configuration variables for you. - .Pp Here are all valid variables, listed in alphabetical order. The default value is given between parentheses. .Bl -tag -width indent - .It Va AddressFamily Li = ipv4 | ipv6 | any Pq any This option affects the address family of listening and outgoing sockets. If .Qq any is selected, then depending on the operating system both IPv4 and IPv6 or just IPv6 listening sockets will be created. - +.It Va AutoConnect Li = Ar count Po 0 Pc Bq experimental +If set to a non-zero value, +.Nm +will try to only have +.Ar count +meta connections to other nodes, +by automatically making or breaking connections to known nodes. +Higher values increase redundancy but also increase meta data overhead. +When using this option, a good value is 3. .It Va BindToAddress Li = Ar address Op Ar port If your computer has more than one IPv4 or IPv6 address, .Nm tinc @@ -149,38 +141,31 @@ To only bind to a specific port but not to a specific address, use .Li * for the .Ar address . - .It Va BindToInterface Li = Ar interface Bq experimental If your computer has more than one network interface, .Nm tinc will by default listen on all of them for incoming connections. It is possible to bind only to a single interface with this variable. - .Pp This option may not work on all platforms. Also, on some platforms it will not actually bind to an interface, but rather to the address that the interface has at the moment a socket is created. - .It Va Broadcast Li = no | mst | direct Po mst Pc Bq experimental This option selects the way broadcast packets are sent to other daemons. NOTE: all nodes in a VPN must use the same .Va Broadcast mode, otherwise routing loops can form. - .Bl -tag -width indent .It no Broadcast packets are never sent to other nodes. - .It mst Broadcast packets are sent and forwarded via the VPN's Minimum Spanning Tree. This ensures broadcast packets reach all nodes. - .It direct Broadcast packets are sent directly to all nodes that can be reached directly. Broadcast packets received from other nodes are never forwarded. If the IndirectData option is also set, broadcast packets will only be sent to nodes which we have a meta connection to. .El - .It Va ConnectTo Li = Ar name Specifies which other tinc daemon to connect to on startup. Multiple @@ -191,14 +176,12 @@ The names should be known to this tinc daemon (i.e., there should be a host configuration file for the name on the .Va ConnectTo line). - .Pp If you don't specify a host with .Va ConnectTo , .Nm tinc won't try to connect to other daemons at all, and will instead just listen for incoming connections. - .It Va DecrementTTL Li = yes | no Po no Pc Bq experimental When enabled, .Nm tinc @@ -208,7 +191,6 @@ and will drop packets that have a TTL value of zero, in which case it will send an ICMP Time Exceeded packet back. .Pp Do not use this option if you use switch mode and want to use IPv6. - .It Va Device Li = Ar device Po Pa /dev/tap0 , Pa /dev/net/tun No or other depending on platform Pc The virtual network device to use. .Nm tinc @@ -220,18 +202,15 @@ instead of .Va Device . The info pages of the tinc package contain more information about configuring the virtual network device. - .It Va DeviceType Li = Ar type Pq platform dependent The type of the virtual network device. Tinc will normally automatically select the right type of tun/tap interface, and this option should not be used. However, this option can be used to select one of the special interface types, if support for them is compiled in. .Bl -tag -width indent - .It dummy Use a dummy interface. No packets are ever read or written to a virtual network device. Useful for testing, or when setting up a node that only forwards packets for other nodes. - .It raw_socket Open a raw socket, and bind it to a pre-existing .Va Interface @@ -239,7 +218,6 @@ Open a raw socket, and bind it to a pre-existing All packets are read from this interface. Packets received for the local node are written to the raw socket. However, at least on Linux, the operating system does not process IP packets destined for the local host. - .It multicast Open a multicast UDP socket and bind it to the address and port (separated by spaces) and optionally a TTL value specified using .Va Device . @@ -249,7 +227,6 @@ Do NOT connect multiple .Nm tinc daemons to the same multicast address, this will very likely cause routing loops. Also note that this can cause decrypted VPN packets to be sent out on a real network if misconfigured. - .It uml Pq not compiled in by default Create a UNIX socket with the filename specified by .Va Device , @@ -258,7 +235,6 @@ or if not specified. .Nm tinc will wait for a User Mode Linux instance to connect to this socket. - .It vde Pq not compiled in by default Uses the libvdeplug library to connect to a Virtual Distributed Ethernet switch, using the UNIX socket specified by @@ -267,46 +243,37 @@ or .Pa @localstatedir@/run/vde.ctl if not specified. .El - Also, in case tinc does not seem to correctly interpret packets received from the virtual network device, it can be used to change the way packets are interpreted: - .Bl -tag -width indent - .It tun Pq BSD and Linux Set type to tun. Depending on the platform, this can either be with or without an address family header (see below). - .It tunnohead Pq BSD Set type to tun without an address family header. Tinc will expect packets read from the virtual network device to start with an IP header. On some platforms IPv6 packets cannot be read from or written to the device in this mode. - .It tunifhead Pq BSD Set type to tun with an address family header. Tinc will expect packets read from the virtual network device to start with a four byte header containing the address family, followed by an IP header. This mode should support both IPv4 and IPv6 packets. - .It tap Pq BSD and Linux Set type to tap. 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 ECDSAPrivateKeyFile Li = Ar filename Po Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /ecdsa_key.priv Pc The file in which the private ECDSA key of this tinc daemon resides. This is only used if .Va ExperimentalProtocol is enabled. - .It Va ExperimentalProtocol Li = yes | no Po no Pc Bq experimental When this option is enabled, experimental protocol enhancements will be used. Ephemeral ECDH will be used for key exchanges, @@ -315,53 +282,31 @@ When enabled, an ECDSA key must have been generated before with .Nm tincctl generate-ecdsa-keys . The experimental protocol may change at any time, and there is no guarantee that tinc will run stable when it is used. - .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 -If this option is present, -.Nm tinc -will dump the current network graph to the file -.Ar filename -every minute, unless there were no changes to the graph. -The file is in a format that can be read by graphviz tools. -If -.Ar filename -starts with a pipe symbol |, -then the rest of the filename is interpreted as a shell command -that is executed, the graph is then sent to stdin. - .It Va Hostnames Li = yes | no Pq no This option selects whether IP addresses (both real and on the VPN) should be resolved. Since DNS lookups are blocking, it might affect tinc's efficiency, even stopping the daemon for a few seconds every time it does a lookup if your DNS server is not responding. - .Pp This does not affect resolving hostnames to IP addresses from the host configuration files, but whether hostnames should be resolved while logging. - .It Va IffOneQueue Li = yes | no Po no Pc Bq experimental (Linux only) Set IFF_ONE_QUEUE flag on TUN/TAP devices. - .It Va Interface Li = Ar interface Defines the name of the interface corresponding to the virtual network device. Depending on the operating system and the type of device this may or may not actually set the name of the interface. @@ -369,12 +314,10 @@ Under Windows, this variable is used to select which network interface will be u If you specified a .Va Device , this variable is almost always already correctly set. - .It Va KeyExpire Li = Ar seconds Pq 3600 This option controls the period the encryption keys used to encrypt the data are valid. It is common practice to change keys at regular intervals to make it even harder for crackers, even though it is thought to be nearly impossible to crack a single key. - .It Va LocalDiscovery Li = yes | no Pq no When enabled, .Nm tinc @@ -382,54 +325,43 @@ will try to detect peers that are on the same local network. This will allow direct communication using LAN addresses, even if both peers are behind a NAT and they only ConnectTo a third node outside the NAT, which normally would prevent the peers from learning each other's LAN address. - .Pp Currently, local discovery is implemented by sending broadcast packets to the LAN during path MTU discovery. This feature may not work in all possible situations. - .It Va MACExpire Li = Ar seconds Pq 600 This option controls the amount of time MAC addresses are kept before they are removed. This only has effect when .Va Mode is set to .Qq switch . - .It Va MaxTimeout Li = Ar seconds Pq 900 This is the maximum delay before trying to reconnect to other tinc daemons. - .It Va Mode Li = router | switch | hub Pq router This option selects the way packets are routed to other daemons. .Bl -tag -width indent - .It router In this mode .Va Subnet variables in the host configuration files will be used to form a routing table. Only unicast packets of routable protocols (IPv4 and IPv6) are supported in this mode. - .Pp This is the default mode, and unless you really know you need another mode, don't change it. - .It switch In this mode the MAC addresses of the packets on the VPN will be used to dynamically create a routing table just like an Ethernet switch does. Unicast, multicast and broadcast packets of every protocol that runs over Ethernet are supported in this mode at the cost of frequent broadcast ARP requests and routing table updates. - .Pp This mode is primarily useful if you want to bridge Ethernet segments. - .It hub This mode is almost the same as the switch mode, but instead every packet will be broadcast to the other daemons while no routing table is managed. .El - .It Va Name Li = Ar name Bq required This is the name which identifies this tinc daemon. It must be unique for the virtual private network this daemon will connect to. The Name may only consist of alphanumeric and underscore characters. - If .Va Name starts with a @@ -441,40 +373,28 @@ If is .Li $HOST , but no such environment variable exist, the hostname will be read using the gethostnname() system call. - .It Va PingInterval Li = Ar seconds Pq 60 The number of seconds of inactivity that .Nm tinc will wait before sending a probe to the other end. - .It Va PingTimeout Li = Ar seconds Pq 5 The number of seconds to wait for a response to pings or to allow meta connections to block. If the other end doesn't respond within this time, the connection is terminated, and the others will be notified of this. - .It Va PriorityInheritance Li = yes | no Po no Pc Bq experimental When this option is enabled the value of the TOS field of tunneled IPv4 packets will be inherited by the UDP packets that are sent out. - .It Va PrivateKey Li = Ar key Bq obsolete The private RSA key of this tinc daemon. It will allow this tinc daemon to authenticate itself to other daemons. - .It Va PrivateKeyFile Li = Ar filename Po Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /rsa_key.priv Pc The file in which the private RSA key of this tinc daemon resides. -Note that there must be exactly one of -.Va PrivateKey -or -.Va PrivateKeyFile -specified in the configuration file. - .It Va ProcessPriority Li = low | normal | high When this option is used the priority of the .Nm tincd process will be adjusted. Increasing the priority may help to reduce latency and packet loss on the VPN. - .It Va Proxy Li = socks4 | socks5 | http | exec Ar ... Bq experimental Use a proxy when making outgoing connections. The following proxy types are currently supported: @@ -507,7 +427,6 @@ and .Ev REMOTEPORT are available. .El - .It Va ReplayWindow Li = Ar bytes Pq 16 vhis is the size of the replay tracking window for each remote node, in bytes. The window is a bitfield which tracks 1 packet per bit, so for example @@ -517,35 +436,29 @@ the interaction of replay tracking with underlying real packet loss and/or reordering. Setting this to zero will disable replay tracking completely and pass all traffic, but leaves tinc vulnerable to replay-based attacks on your traffic. - .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. - .It Va UDPRcvBuf Li = Ar bytes Pq OS default Sets the socket receive buffer size for the UDP socket, in bytes. If unset, the default buffer size will be used by the operating system. - .It Va UDPSndBuf Li = Ar bytes Pq OS default Sets the socket send buffer size for the UDP socket, in bytes. If unset, the default buffer size will be used by the operating system. .El - .Sh HOST CONFIGURATION FILES The host configuration files contain all information needed to establish a connection to those hosts. A host configuration file is also required for the local tinc daemon, it will use it to read in it's listen port, public key and subnets. - .Pp The idea is that these files are portable. You can safely mail your own host configuration file to someone else. @@ -554,7 +467,6 @@ and now his tinc daemon will be able to connect to your tinc daemon. 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 Oo Ar 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. @@ -563,7 +475,6 @@ Multiple .Va Address variables can be specified, in which case each address will be tried until a working connection has been established. - .It Va Cipher Li = Ar cipher Pq blowfish The symmetric cipher algorithm used to encrypt UDP packets. Any cipher supported by OpenSSL is recognised. @@ -571,24 +482,20 @@ Furthermore, specifying .Qq none 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), 10 (fast lzo) and 11 (best lzo). - .It Va Digest Li = Ar digest Pq sha1 The digest algorithm used to authenticate UDP packets. Any digest supported by OpenSSL is recognised. Furthermore, specifying .Qq none will turn off packet authentication. - .It Va IndirectData Li = yes | no Pq no This option specifies whether other tinc daemons besides the one you specified with .Va ConnectTo @@ -596,33 +503,26 @@ can make a direct connection to you. This is especially useful if you are behind a firewall and it is impossible to make a connection from the outside to your tinc daemon. Otherwise, it is best to leave this option out or set it to no. - .It Va MACLength Li = Ar length Pq 4 The length of the message authentication code used to authenticate UDP packets. Can be anything from .Qq 0 up to the length of the digest produced by the digest algorithm. - .It Va PMTU Li = Ar mtu Po 1514 Pc This option controls the initial path MTU to this node. - .It Va PMTUDiscovery Li = yes | no Po yes Pc 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, 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. It will be used to cryptographically verify it's identity and to set up a secure connection. - .It Va PublicKeyFile Li = Ar filename Bq obsolete The file in which the public RSA key of this tinc daemon resides. - .Pp From version 1.0pre4 on .Nm tinc @@ -631,7 +531,6 @@ the above two options then are not necessary. Either the PEM format is used, or exactly one of the above two options must be specified in each host configuration file, if you want to be able to establish a connection with that host. - .It Va Subnet Li = Ar address Ns Op Li / Ns Ar prefixlength Ns Op Li # Ns Ar weight The subnet which this tinc daemon will serve. .Nm tinc @@ -641,7 +540,6 @@ it will be sent to the daemon who has this subnet in his host configuration file Multiple .Va Subnet variables can be specified. - .Pp Subnets can either be single MAC, IPv4 or IPv6 addresses, in which case a subnet consisting of only that single address is assumed, @@ -652,14 +550,12 @@ Note that subnets like 192.168.1.1/24 are invalid! Read a networking HOWTO/FAQ/guide if you don't understand this. IPv6 subnets are notated like fec0:0:0:1::/64. MAC addresses are notated like 0:1a:2b:3c:4d:5e. - .Pp A Subnet can be given a weight to indicate its priority over identical Subnets owned by different nodes. The default weight is 10. Lower values indicate higher priority. Packets will be sent to the node with the highest priority, unless that node is not reachable, in which case the node with the next highest priority will be tried, and so on. - .It Va TCPOnly Li = yes | no Pq no Bq obsolete If this variable is set to yes, then the packets are tunnelled over the TCP connection instead of a UDP connection. @@ -667,53 +563,42 @@ This is especially useful for those who want to run a tinc daemon from behind a masquerading firewall, or if UDP packet routing is disabled somehow. Setting this options also implicitly sets IndirectData. - .Pp Since version 1.0.10, tinc will automatically detect whether communication via UDP is possible or not. .El - .Sh SCRIPTS Apart from reading the server and host configuration files, tinc can also run scripts at certain moments. Under Windows (not Cygwin), the scripts should have the extension .Pa .bat . .Bl -tag -width indent - .It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /tinc-up This is the most important script. If it is present it will be executed right after the tinc daemon has been started and has connected to the virtual network device. It should be used to set up the corresponding network interface, but can also be used to start other things. Under Windows you can use the Network Connections control panel instead of creating this script. - .It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /tinc-down This script is started right before the tinc daemon quits. - .It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /hosts/ Ns Ar HOST Ns Pa -up This script is started when the tinc daemon with name .Ar HOST becomes reachable. - .It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /hosts/ Ns Ar HOST Ns Pa -down This script is started when the tinc daemon with name .Ar HOST becomes unreachable. - .It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /host-up This script is started when any host becomes reachable. - .It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /host-down This script is started when any host becomes unreachable. - .It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /subnet-up This script is started when a Subnet becomes reachable. The Subnet and the node it belongs to are passed in environment variables. - .It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /subnet-down This script is started when a Subnet becomes unreachable. .El - .Pp The scripts are started without command line arguments, but can make use of certain environment variables. Under UNIX like operating systems the names of environment variables must be preceded by a @@ -725,73 +610,55 @@ files, they have to be put between .Li % signs. .Bl -tag -width indent - .It Ev NETNAME If a netname was specified, this environment variable contains it. - .It Ev NAME Contains the name of this tinc daemon. - .It Ev DEVICE Contains the name of the virtual network device that tinc uses. - .It Ev INTERFACE Contains the name of the virtual network interface that tinc uses. This should be used for commands like .Pa ifconfig . - .It Ev NODE When a host becomes (un)reachable, this is set to its name. If a subnet becomes (un)reachable, this is set to the owner of that subnet. - .It Ev REMOTEADDRESS When a host becomes (un)reachable, this is set to its real address. - .It Ev REMOTEPORT When a host becomes (un)reachable, this is set to the port number it uses for communication with other tinc daemons. - .It Ev SUBNET When a subnet becomes (un)reachable, this is set to the subnet. - .It Ev WEIGHT When a subnet becomes (un)reachable, this is set to the subnet weight. .El - .Pp Do not forget that under UNIX operating systems, you have to make the scripts executable, using the command .Nm chmod Li a+x Pa script . - .Sh FILES The most important files are: .Bl -tag -width indent - .It Pa @sysconfdir@/tinc/ The top directory for configuration files. - .It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /tinc.conf The default name of the server configuration file for net .Ar NETNAME . - .It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /hosts/ Host configuration files are kept in this directory. - .It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /tinc-up If an executable file with this name exists, it will be executed right after the tinc daemon has connected to the virtual network device. It can be used to set up the corresponding network interface. - .It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /tinc-down If an executable file with this name exists, it will be executed right before the tinc daemon is going to close its connection to the virtual network device. .El - .Sh SEE ALSO .Xr tincd 8 , .Xr tincctl 8 , .Pa http://www.tinc-vpn.org/ , .Pa http://www.tldp.org/LDP/nag2/ . - .Pp The full documentation for .Nm tinc @@ -799,7 +666,6 @@ is maintained as a Texinfo manual. If the info and tinc programs are properly installed at your site, the command .Ic info tinc should give you access to the complete manual. - .Pp .Nm tinc comes with ABSOLUTELY NO WARRANTY. diff --git a/doc/tinc.info b/doc/tinc.info index 8a95302..73343b8 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.1pre2, a Virtual Private + This is the info manual for tinc version 1.1pre4, a Virtual Private Network daemon. Copyright (C) 1998-2012 Ivo Timmermans, Guus Sliepen @@ -295,7 +295,8 @@ an error message, and stop. * OpenSSL:: * zlib:: * lzo:: -* libevent:: +* libcurses:: +* libreadline::  File: tinc.info, Node: OpenSSL, Next: zlib, Up: Libraries @@ -307,8 +308,8 @@ For all cryptography-related functions, tinc uses the functions provided by the OpenSSL library. If this library is not installed, you wil get an error when -configuring tinc for build. Support for running tinc without having -OpenSSL installed _may_ be added in the future. +configuring tinc for build. Support for running tinc with other +cryptographic libraries installed _may_ be added in the future. You can use your operating system's package manager to install this if available. Make sure you install the development AND runtime @@ -363,9 +364,12 @@ File: tinc.info, Node: zlib, Next: lzo, Prev: OpenSSL, Up: Libraries For the optional compression of UDP packets, tinc uses the functions provided by the zlib library. - If this library is not installed, you wil get an error when -configuring tinc for build. Support for running tinc without having -zlib installed _may_ be added in the future. + If this library is not installed, you wil get an error when running +the configure script. You can either install the zlib library, or +disable support for zlib compression by using the "-disable-zlib" +option when running the configure script. Note that if you disable +support for zlib, the resulting binary will not work correctly on VPNs +where zlib compression is used. You can use your operating system's package manager to install this if available. Make sure you install the development AND runtime @@ -378,16 +382,19 @@ make sure you build development and runtime libraries (which is the default).  -File: tinc.info, Node: lzo, Next: libevent, Prev: zlib, Up: Libraries +File: tinc.info, Node: lzo, Next: libcurses, Prev: zlib, Up: Libraries 2.2.3 lzo --------- -Another form of compression is offered using the lzo library. +Another form of compression is offered using the LZO library. - If this library is not installed, you wil get an error when -configuring tinc for build. Support for running tinc without having lzo -installed _may_ be added in the future. + If this library is not installed, you wil get an error when running +the configure script. You can either install the LZO library, or +disable support for LZO compression by using the "-disable-lzo" option +when running the configure script. Note that if you disable support for +LZO, the resulting binary will not work correctly on VPNs where LZO +compression is used. You can use your operating system's package manager to install this if available. Make sure you install the development AND runtime @@ -400,24 +407,52 @@ package. Please make sure you build development and runtime libraries (which is the default).  -File: tinc.info, Node: libevent, Prev: lzo, Up: Libraries +File: tinc.info, Node: libcurses, Next: libreadline, Prev: lzo, Up: Libraries -2.2.4 libevent --------------- +2.2.4 libcurses +--------------- -For the main event loop, tinc uses the libevent library. +For the "tincctl top" command, tinc requires a curses library. - If this library is not installed, you wil get an error when -configuring tinc for build. + If this library is not installed, you wil get an error when running +the configure script. You can either install a suitable curses +library, or disable all functionality that depends on a curses library +by using the "-disable-curses" option when running the configure script. + + There are several curses libraries. It is recommended that you +install "ncurses" (`http://invisible-island.net/ncurses/'), however +other curses libraries should also work. In particular, "PDCurses" +(`http://pdcurses.sourceforge.net/') is recommended if you want to +compile tinc for Windows. + + You can use your operating system's package manager to install this +if available. Make sure you install the development AND runtime versions +of this package. + + +File: tinc.info, Node: libreadline, Prev: libcurses, Up: Libraries + +2.2.5 libreadline +----------------- + +For the "tincctl" command's shell functionality, tinc uses the readline +library. + + If this library is not installed, you wil get an error when running +the configure script. You can either install a suitable readline +library, or disable all functionality that depends on a readline +library by using the "-disable-readline" option when running the +configure script. You can use your operating system's package manager to install this if available. Make sure you install the development AND runtime versions of this package. - If you have to install libevent manually, you can get the source code -from `http://libevent.org/'. Instructions on how to configure, build -and install this package are included within the package. Please make -sure you build development and runtime libraries (which is the default). + If you have to install libreadline manually, you can get the source +code from `http://www.gnu.org/software/readline/'. Instructions on how +to configure, build and install this package are included within the +package. Please make sure you build development and runtime libraries +(which is the default).  File: tinc.info, Node: Installation, Next: Configuration, Prev: Preparations, Up: Top @@ -738,6 +773,13 @@ AddressFamily = (any) system both IPv4 and IPv6 or just IPv6 listening sockets will be created. +AutoConnect = (0) [experimental] + If set to a non-zero value, tinc will try to only have count meta + connections to other nodes, by automatically making or breaking + connections to known nodes. Higher values increase redundancy but + also increase meta data overhead. When using this option, a good + value is 3. + BindToAddress =
[] If your computer has more than one IPv4 or IPv6 address, tinc will by default listen on all of them for incoming connections. @@ -912,14 +954,6 @@ Forwarding = (internal) [experimental] efficient, but allows the kernel to apply its routing and firewall rules on them, and can also help debugging. -GraphDumpFile = - If this option is present, tinc will dump the current network - graph to the file FILENAME every minute, unless there were no - changes to the graph. The file is in a format that can be read by - graphviz tools. If FILENAME starts with a pipe symbol |, then the - rest of the filename is interpreted as a shell command that is - executed, the graph is then sent to stdin. - Hostnames = (no) This option selects whether IP addresses (both real and on the VPN) should be resolved. Since DNS lookups are blocking, it might @@ -1026,9 +1060,6 @@ PrivateKeyFile = (`/etc/tinc/NETNAME/rsa_key.priv') generated by `tincctl generate-keys'. It must be a full path, not a relative directory. - Note that there must be exactly one of PrivateKey or PrivateKeyFile - specified in the configuration file. - ProcessPriority = When this option is used the priority of the tincd process will be adjusted. Increasing the priority may help to reduce latency and @@ -2073,8 +2104,9 @@ File: tinc.info, Node: tincctl commands, Next: tincctl examples, Prev: tincct store the files, but will default to the configuration directory (you can use the -c or -n option). -`dump nodes' - Dump a list of all known nodes in the VPN. +`dump [reachable] nodes' + Dump a list of all known nodes in the VPN. If the reachable + keyword is used, only lists reachable nodes. `dump edges' Dump a list of all known connections in the VPN. @@ -2792,14 +2824,16 @@ Concept Index * ANS_KEY: The meta-protocol. (line 64) * authentication: Authentication protocol. (line 6) +* AutoConnect: Main configuration variables. + (line 12) * binary package: Building and installing tinc. (line 9) * BindToAddress: Main configuration variables. - (line 12) + (line 19) * BindToInterface: Main configuration variables. - (line 23) + (line 30) * Broadcast: Main configuration variables. - (line 34) + (line 41) * Cabal: Security. (line 6) * CHAL_REPLY: Authentication protocol. (line 10) @@ -2818,29 +2852,29 @@ Concept Index (line 24) * connection: The connection. (line 6) * ConnectTo: Main configuration variables. - (line 54) + (line 61) * daemon: Running tinc. (line 11) * data-protocol: The meta-connection. (line 18) * debug level: Runtime options. (line 17) * debug levels: Debug levels. (line 6) * DecrementTTL: Main configuration variables. - (line 65) + (line 72) * DEL_EDGE: The meta-protocol. (line 47) * DEL_SUBNET: The meta-protocol. (line 47) * DEVICE: Scripts. (line 55) * Device: Main configuration variables. - (line 74) + (line 81) * device files: Device files. (line 6) * DeviceType: Main configuration variables. - (line 81) + (line 88) * Digest: Host configuration variables. (line 29) * DirectOnly: Main configuration variables. - (line 146) -* dummy: Main configuration variables. - (line 88) -* ECDSAPrivateKeyFile: Main configuration variables. (line 153) +* dummy: Main configuration variables. + (line 95) +* ECDSAPrivateKeyFile: Main configuration variables. + (line 160) * encapsulating: The UDP tunnel. (line 30) * encryption: Encryption of network packets. (line 6) @@ -2848,52 +2882,51 @@ Concept Index * example: Example configuration. (line 6) * exec: Main configuration variables. - (line 326) + (line 322) * ExperimentalProtocol: Main configuration variables. - (line 157) + (line 164) * Forwarding: Main configuration variables. - (line 166) + (line 173) * frame type: The UDP tunnel. (line 6) -* GraphDumpFile: Main configuration variables. - (line 186) * Hostnames: Main configuration variables. - (line 194) + (line 193) * http: Main configuration variables. - (line 323) + (line 319) * hub: Main configuration variables. - (line 247) + (line 246) * ID: Authentication protocol. (line 10) * IndirectData: Host configuration variables. (line 34) * INTERFACE: Scripts. (line 58) * Interface: Main configuration variables. - (line 205) + (line 204) * IRC: Contact information. (line 9) * KEY_CHANGED: The meta-protocol. (line 64) * KeyExpire: Main configuration variables. - (line 252) -* libevent: libevent. (line 6) + (line 251) +* libcurses: libcurses. (line 6) * libraries: Libraries. (line 6) +* libreadline: libreadline. (line 6) * license: OpenSSL. (line 36) * LocalDiscovery: Main configuration variables. - (line 213) + (line 212) * lzo: lzo. (line 6) * MACExpire: Main configuration variables. - (line 258) + (line 257) * MACLength: Host configuration variables. (line 42) * meta-protocol: The meta-connection. (line 18) * META_KEY: Authentication protocol. (line 10) * Mode: Main configuration variables. - (line 224) + (line 223) * multicast: Main configuration variables. - (line 100) + (line 107) * multiple networks: Multiple networks. (line 6) * NAME: Scripts. (line 52) * Name: Main configuration variables. - (line 263) + (line 262) * netmask: Network interfaces. (line 39) * NETNAME <1>: tincctl environment variables. (line 6) @@ -2908,9 +2941,9 @@ Concept Index (line 67) * PING: The meta-protocol. (line 89) * PingInterval: Main configuration variables. - (line 274) + (line 273) * PingTimeout: Main configuration variables. - (line 278) + (line 277) * platforms: Supported platforms. (line 6) * PMTU: Host configuration variables. (line 47) @@ -2921,32 +2954,32 @@ Concept Index (line 55) * port numbers: Other files. (line 17) * PriorityInheritance: Main configuration variables. - (line 284) + (line 283) * private: Virtual Private Networks. (line 10) * PrivateKey: Main configuration variables. - (line 289) + (line 288) * PrivateKeyFile: Main configuration variables. - (line 295) + (line 294) * ProcessPriority: Main configuration variables. - (line 303) + (line 299) * Proxy: Main configuration variables. - (line 308) + (line 304) * PublicKey: Host configuration variables. (line 59) * PublicKeyFile: Host configuration variables. (line 62) * raw_socket: Main configuration variables. - (line 93) + (line 100) * release: Supported platforms. (line 14) * REMOTEADDRESS: Scripts. (line 67) * REMOTEPORT: Scripts. (line 70) * ReplayWindow: Main configuration variables. - (line 331) + (line 327) * REQ_KEY: The meta-protocol. (line 64) * requirements: Libraries. (line 6) * router: Main configuration variables. - (line 227) + (line 226) * runtime options: Runtime options. (line 9) * scalability: tinc. (line 19) * scripts: Scripts. (line 6) @@ -2954,17 +2987,17 @@ Concept Index (line 18) * signals: Signals. (line 6) * socks4: Main configuration variables. - (line 312) + (line 308) * socks5: Main configuration variables. - (line 317) + (line 313) * StrictSubnets: Main configuration variables. - (line 342) + (line 338) * SUBNET: Scripts. (line 74) * Subnet: Host configuration variables. (line 74) * SVPN: Security. (line 11) * switch: Main configuration variables. - (line 236) + (line 235) * TCP: The meta-connection. (line 10) * TCPonly: Host configuration variables. (line 103) @@ -2976,24 +3009,24 @@ Concept Index * tincd: tinc. (line 14) * traditional VPNs: tinc. (line 19) * tunifhead: Main configuration variables. - (line 135) + (line 142) * TunnelServer: Main configuration variables. - (line 347) + (line 343) * tunnohead: Main configuration variables. - (line 129) + (line 136) * UDP <1>: Encryption of network packets. (line 12) * UDP: The UDP tunnel. (line 30) * UDPRcvBuf: Main configuration variables. - (line 354) + (line 350) * UDPSndBuf: Main configuration variables. - (line 359) + (line 355) * UML: Main configuration variables. - (line 111) + (line 118) * Universal tun/tap: Configuration of Linux kernels. (line 6) * VDE: Main configuration variables. - (line 116) + (line 123) * virtual: Virtual Private Networks. (line 18) * virtual network device: The UDP tunnel. (line 6) @@ -3021,57 +3054,58 @@ Node: Configuration of Solaris kernels8891 Node: Configuration of Darwin (MacOS/X) kernels9552 Node: Configuration of Windows10241 Node: Libraries10755 -Node: OpenSSL11156 -Node: zlib13432 -Node: lzo14261 -Node: libevent15065 -Node: Installation15760 -Node: Building and installing tinc16776 -Node: Darwin (MacOS/X) build environment17435 -Node: Cygwin (Windows) build environment18002 -Node: MinGW (Windows) build environment18590 -Node: System files19114 -Node: Device files19379 -Node: Other files19795 -Node: Configuration20408 -Node: Configuration introduction20695 -Node: Multiple networks22242 -Node: How connections work23622 -Node: Configuration files26195 -Node: Main configuration variables27728 -Node: Host configuration variables44334 -Node: Scripts49564 -Node: How to configure52243 -Node: Network interfaces56861 -Node: Example configuration59262 -Node: Running tinc64414 -Node: Runtime options65007 -Node: Signals67711 -Node: Debug levels68561 -Node: Solving problems69497 -Node: Error messages70927 -Node: Sending bug reports75249 -Node: Controlling tinc76201 -Node: tincctl runtime options76598 -Node: tincctl environment variables77297 -Node: tincctl commands77641 -Node: tincctl examples81866 -Node: tincctl top82471 -Node: Technical information84069 -Node: The connection84304 -Node: The UDP tunnel84616 -Node: The meta-connection87677 -Node: The meta-protocol89146 -Node: Security94155 -Node: Authentication protocol95285 -Node: Encryption of network packets100289 -Node: Security issues101662 -Node: Platform specific information103279 -Node: Interface configuration103507 -Node: Routes105960 -Node: About us107876 -Node: Contact information108051 -Node: Authors108455 -Node: Concept Index108860 +Node: OpenSSL11173 +Node: zlib13461 +Node: lzo14487 +Node: libcurses15485 +Node: libreadline16405 +Node: Installation17353 +Node: Building and installing tinc18369 +Node: Darwin (MacOS/X) build environment19028 +Node: Cygwin (Windows) build environment19595 +Node: MinGW (Windows) build environment20183 +Node: System files20707 +Node: Device files20972 +Node: Other files21388 +Node: Configuration22001 +Node: Configuration introduction22288 +Node: Multiple networks23835 +Node: How connections work25215 +Node: Configuration files27788 +Node: Main configuration variables29321 +Node: Host configuration variables45731 +Node: Scripts50961 +Node: How to configure53640 +Node: Network interfaces58258 +Node: Example configuration60659 +Node: Running tinc65811 +Node: Runtime options66404 +Node: Signals69108 +Node: Debug levels69958 +Node: Solving problems70894 +Node: Error messages72324 +Node: Sending bug reports76646 +Node: Controlling tinc77598 +Node: tincctl runtime options77995 +Node: tincctl environment variables78694 +Node: tincctl commands79038 +Node: tincctl examples83343 +Node: tincctl top83948 +Node: Technical information85546 +Node: The connection85781 +Node: The UDP tunnel86093 +Node: The meta-connection89154 +Node: The meta-protocol90623 +Node: Security95632 +Node: Authentication protocol96762 +Node: Encryption of network packets101766 +Node: Security issues103139 +Node: Platform specific information104756 +Node: Interface configuration104984 +Node: Routes107437 +Node: About us109353 +Node: Contact information109528 +Node: Authors109932 +Node: Concept Index110337  End Tag Table diff --git a/doc/tinc.texi b/doc/tinc.texi index ac3a630..0e2b1eb 100644 --- a/doc/tinc.texi +++ b/doc/tinc.texi @@ -339,7 +339,8 @@ having them installed, configure will give you an error message, and stop. * OpenSSL:: * zlib:: * lzo:: -* libevent:: +* libcurses:: +* libreadline:: @end menu @@ -352,7 +353,7 @@ For all cryptography-related functions, tinc uses the functions provided by the OpenSSL library. If this library is not installed, you wil get an error when configuring -tinc for build. Support for running tinc without having OpenSSL +tinc for build. Support for running tinc with other cryptographic libraries installed @emph{may} be added in the future. You can use your operating system's package manager to install this if @@ -415,9 +416,11 @@ Markus F.X.J. Oberhumer For the optional compression of UDP packets, tinc uses the functions provided by the zlib library. -If this library is not installed, you wil get an error when configuring -tinc for build. Support for running tinc without having zlib -installed @emph{may} be added in the future. +If this library is not installed, you wil get an error when running the +configure script. You can either install the zlib library, or disable support +for zlib compression by using the "--disable-zlib" option when running the +configure script. Note that if you disable support for zlib, the resulting +binary will not work correctly on VPNs where zlib compression is used. You can use your operating system's package manager to install this if available. Make sure you install the development AND runtime versions @@ -435,11 +438,13 @@ default). @subsection lzo @cindex lzo -Another form of compression is offered using the lzo library. +Another form of compression is offered using the LZO library. -If this library is not installed, you wil get an error when configuring -tinc for build. Support for running tinc without having lzo -installed @emph{may} be added in the future. +If this library is not installed, you wil get an error when running the +configure script. You can either install the LZO library, or disable support +for LZO compression by using the "--disable-lzo" option when running the +configure script. Note that if you disable support for LZO, the resulting +binary will not work correctly on VPNs where LZO compression is used. You can use your operating system's package manager to install this if available. Make sure you install the development AND runtime versions @@ -453,24 +458,48 @@ default). @c ================================================================== -@node libevent -@subsection libevent +@node libcurses +@subsection libcurses -@cindex libevent -For the main event loop, tinc uses the libevent library. +@cindex libcurses +For the "tincctl top" command, tinc requires a curses library. -If this library is not installed, you wil get an error when configuring -tinc for build. +If this library is not installed, you wil get an error when running the +configure script. You can either install a suitable curses library, or disable +all functionality that depends on a curses library by using the +"--disable-curses" option when running the configure script. + +There are several curses libraries. It is recommended that you install +"ncurses" (@url{http://invisible-island.net/ncurses/}), +however other curses libraries should also work. +In particular, "PDCurses" (@url{http://pdcurses.sourceforge.net/}) +is recommended if you want to compile tinc for Windows. + +You can use your operating system's package manager to install this if +available. Make sure you install the development AND runtime versions +of this package. + + +@c ================================================================== +@node libreadline +@subsection libreadline + +@cindex libreadline +For the "tincctl" command's shell functionality, tinc uses the readline library. + +If this library is not installed, you wil get an error when running the +configure script. You can either install a suitable readline library, or +disable all functionality that depends on a readline library by using the +"--disable-readline" option when running the configure script. You can use your operating system's package manager to install this if available. Make sure you install the development AND runtime versions of this package. -If you have to install libevent manually, you can get the source code -from @url{http://libevent.org/}. Instructions on how to configure, -build and install this package are included within the package. Please -make sure you build development and runtime libraries (which is the -default). +If you have to install libreadline manually, you can get the source code from +@url{http://www.gnu.org/software/readline/}. Instructions on how to configure, +build and install this package are included within the package. Please make +sure you build development and runtime libraries (which is the default). @c @@ -805,6 +834,14 @@ This option affects the address family of listening and outgoing sockets. If any is selected, then depending on the operating system both IPv4 and IPv6 or just IPv6 listening sockets will be created. +@cindex AutoConnect +@item AutoConnect = (0) [experimental] +If set to a non-zero value, +tinc will try to only have count meta connections to other nodes, +by automatically making or breaking connections to known nodes. +Higher values increase redundancy but also increase meta data overhead. +When using this option, a good value is 3. + @cindex BindToAddress @item BindToAddress = <@var{address}> [<@var{port}>] If your computer has more than one IPv4 or IPv6 address, tinc @@ -990,16 +1027,6 @@ This is less efficient, but allows the kernel to apply its routing and firewall and can also help debugging. @end table -@cindex GraphDumpFile -@item GraphDumpFile = <@var{filename}> -If this option is present, -tinc will dump the current network graph to the file @var{filename} -every minute, unless there were no changes to the graph. -The file is in a format that can be read by graphviz tools. -If @var{filename} starts with a pipe symbol |, -then the rest of the filename is interpreted as a shell command -that is executed, the graph is then sent to stdin. - @cindex Hostnames @item Hostnames = (no) This option selects whether IP addresses (both real and on the VPN) @@ -1106,10 +1133,6 @@ This is the full path name of the RSA private key file that was generated by @samp{tincctl generate-keys}. It must be a full path, not a relative directory. -Note that there must be exactly one of PrivateKey -or PrivateKeyFile -specified in the configuration file. - @cindex ProcessPriority @item ProcessPriority = When this option is used the priority of the tincd process will be adjusted. @@ -2199,8 +2222,9 @@ Generate public/private keypair of @var{bits} length. If @var{bits} is not speci but will default to the configuration directory (you can use the -c or -n option). -@item dump nodes +@item dump [reachable] nodes Dump a list of all known nodes in the VPN. +If the reachable keyword is used, only lists reachable nodes. @item dump edges Dump a list of all known connections in the VPN. diff --git a/doc/tincctl.8.in b/doc/tincctl.8.in index 3834323..8fdd272 100644 --- a/doc/tincctl.8.in +++ b/doc/tincctl.8.in @@ -45,7 +45,6 @@ If no netname is specified on the command line with the option, the value of this environment variable is used. .El .Sh COMMANDS -.zZ .Bl -tag -width indent .It init Op Ar name Create initial configuration files and RSA and ECDSA keypairs with default length. @@ -115,9 +114,9 @@ If is omitted, the default length will be 2048 bits. When saving keys to existing files, tinc will not delete the old keys; you have to remove them manually. - -.It dump nodes +.It dump [reachable] nodes Dump a list of all known nodes in the VPN. +If the keyword reachable is used, only lists reachable nodes. .It dump edges Dump a list of all known connections in the VPN. .It dump subnets @@ -190,6 +189,7 @@ tincctl -n vpn config Subnet 192.168.1.0/24 tincctl -n vpn config bar.Address bar.example.com tincctl -n vpn config ConnectTo bar tincctl -n vpn export | gpg --clearsign | mail -s "My config" vpnmaster@example.com +.Ed .Sh TOP The top command connects to a running tinc daemon and repeatedly queries its per-node traffic counters. It displays a list of all the known nodes in the left-most column, diff --git a/gui/Makefile.in b/gui/Makefile.in index 2d08ef7..2e52de5 100644 --- a/gui/Makefile.in +++ b/gui/Makefile.in @@ -56,10 +56,9 @@ DIST_COMMON = $(dist_bin_SCRIPTS) $(srcdir)/Makefile.am \ $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \ - $(top_srcdir)/m4/curses.m4 $(top_srcdir)/m4/libevent.m4 \ - $(top_srcdir)/m4/lzo.m4 $(top_srcdir)/m4/openssl.m4 \ - $(top_srcdir)/m4/readline.m4 $(top_srcdir)/m4/zlib.m4 \ - $(top_srcdir)/configure.in + $(top_srcdir)/m4/curses.m4 $(top_srcdir)/m4/lzo.m4 \ + $(top_srcdir)/m4/openssl.m4 $(top_srcdir)/m4/readline.m4 \ + $(top_srcdir)/m4/zlib.m4 $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d diff --git a/have.h b/have.h index d040717..6d65bcd 100644 --- a/have.h +++ b/have.h @@ -196,10 +196,6 @@ #include #endif -#ifdef HAVE_EVENT_H -#include -#endif - #ifdef HAVE_MINGW #define SLASH "\\" #else diff --git a/m4/Makefile.in b/m4/Makefile.in index 8f1372a..557ba46 100644 --- a/m4/Makefile.in +++ b/m4/Makefile.in @@ -54,10 +54,9 @@ subdir = m4 DIST_COMMON = README $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \ - $(top_srcdir)/m4/curses.m4 $(top_srcdir)/m4/libevent.m4 \ - $(top_srcdir)/m4/lzo.m4 $(top_srcdir)/m4/openssl.m4 \ - $(top_srcdir)/m4/readline.m4 $(top_srcdir)/m4/zlib.m4 \ - $(top_srcdir)/configure.in + $(top_srcdir)/m4/curses.m4 $(top_srcdir)/m4/lzo.m4 \ + $(top_srcdir)/m4/openssl.m4 $(top_srcdir)/m4/readline.m4 \ + $(top_srcdir)/m4/zlib.m4 $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d diff --git a/m4/libevent.m4 b/m4/libevent.m4 deleted file mode 100644 index 34bdef7..0000000 --- a/m4/libevent.m4 +++ /dev/null @@ -1,33 +0,0 @@ -dnl Check to find the libevent headers/libraries - -AC_DEFUN([tinc_LIBEVENT], -[ - AC_ARG_WITH(libevent, - AS_HELP_STRING([--with-libevent=DIR], [libevent base directory, or:]), - [libevent="$withval" - CPPFLAGS="$CPPFLAGS -I$withval/include" - LDFLAGS="$LDFLAGS -L$withval/lib"] - ) - - AC_ARG_WITH(libevent-include, - AS_HELP_STRING([--with-libevent-include=DIR], [libevent headers directory]), - [libevent_include="$withval" - CPPFLAGS="$CPPFLAGS -I$withval"] - ) - - AC_ARG_WITH(libevent-lib, - AS_HELP_STRING([--with-libevent-lib=DIR], [libevent library directory]), - [libevent_lib="$withval" - LDFLAGS="$LDFLAGS -L$withval"] - ) - - AC_CHECK_HEADERS(event.h, - [], - [AC_MSG_ERROR("libevent header files not found."); break] - ) - - AC_CHECK_LIB(event, event_init, - [LIBS="-levent $LIBS"], - [AC_MSG_ERROR("libevent libraries not found.")] - ) -]) diff --git a/src/Makefile.am b/src/Makefile.am index 3bd8646..6a8737b 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -8,7 +8,7 @@ tincd_SOURCES = \ utils.c getopt.c getopt1.c list.c splay_tree.c dropin.c fake-getaddrinfo.c fake-getnameinfo.c hash.c \ buffer.c conf.c connection.c control.c edge.c graph.c logger.c meta.c net.c net_packet.c net_setup.c \ net_socket.c netutl.c node.c process.c protocol.c protocol_auth.c protocol_edge.c protocol_misc.c \ - protocol_key.c protocol_subnet.c route.c sptps.c subnet.c subnet_parse.c tincd.c \ + protocol_key.c protocol_subnet.c route.c sptps.c subnet.c subnet_parse.c event.c tincd.c \ dummy_device.c raw_socket_device.c multicast_device.c if UML @@ -46,7 +46,7 @@ INCLUDES = @INCLUDES@ -I$(top_builddir) noinst_HEADERS = \ xalloc.h utils.h getopt.h list.h splay_tree.h dropin.h fake-getaddrinfo.h fake-getnameinfo.h fake-gai-errnos.h ipv6.h ipv4.h ethernet.h \ buffer.h conf.h connection.h control.h control_common.h device.h edge.h graph.h info.h logger.h meta.h net.h netutl.h node.h process.h \ - protocol.h route.h subnet.h sptps.h tincctl.h top.h bsd/tunemu.h hash.h + protocol.h route.h subnet.h sptps.h tincctl.h top.h bsd/tunemu.h hash.h event.h nodist_noinst_HEADERS = \ cipher.h crypto.h ecdh.h ecdsa.h digest.h prf.h rsa.h ecdsagen.h rsagen.h diff --git a/src/Makefile.in b/src/Makefile.in index d2a972b..37eaa7c 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -62,10 +62,9 @@ DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \ $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \ - $(top_srcdir)/m4/curses.m4 $(top_srcdir)/m4/libevent.m4 \ - $(top_srcdir)/m4/lzo.m4 $(top_srcdir)/m4/openssl.m4 \ - $(top_srcdir)/m4/readline.m4 $(top_srcdir)/m4/zlib.m4 \ - $(top_srcdir)/configure.in + $(top_srcdir)/m4/curses.m4 $(top_srcdir)/m4/lzo.m4 \ + $(top_srcdir)/m4/openssl.m4 $(top_srcdir)/m4/readline.m4 \ + $(top_srcdir)/m4/zlib.m4 $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d @@ -95,8 +94,8 @@ am__tincd_SOURCES_DIST = utils.c getopt.c getopt1.c list.c \ netutl.c node.c process.c protocol.c protocol_auth.c \ protocol_edge.c protocol_misc.c protocol_key.c \ protocol_subnet.c route.c sptps.c subnet.c subnet_parse.c \ - tincd.c dummy_device.c raw_socket_device.c multicast_device.c \ - uml_device.c vde_device.c bsd/tunemu.c + event.c tincd.c dummy_device.c raw_socket_device.c \ + multicast_device.c uml_device.c vde_device.c bsd/tunemu.c @UML_TRUE@am__objects_1 = uml_device.$(OBJEXT) @VDE_TRUE@am__objects_2 = vde_device.$(OBJEXT) @TUNEMU_TRUE@am__objects_3 = tunemu.$(OBJEXT) @@ -112,9 +111,10 @@ am_tincd_OBJECTS = utils.$(OBJEXT) getopt.$(OBJEXT) getopt1.$(OBJEXT) \ protocol_edge.$(OBJEXT) protocol_misc.$(OBJEXT) \ protocol_key.$(OBJEXT) protocol_subnet.$(OBJEXT) \ route.$(OBJEXT) sptps.$(OBJEXT) subnet.$(OBJEXT) \ - subnet_parse.$(OBJEXT) tincd.$(OBJEXT) dummy_device.$(OBJEXT) \ - raw_socket_device.$(OBJEXT) multicast_device.$(OBJEXT) \ - $(am__objects_1) $(am__objects_2) $(am__objects_3) + subnet_parse.$(OBJEXT) event.$(OBJEXT) tincd.$(OBJEXT) \ + dummy_device.$(OBJEXT) raw_socket_device.$(OBJEXT) \ + multicast_device.$(OBJEXT) $(am__objects_1) $(am__objects_2) \ + $(am__objects_3) nodist_tincd_OBJECTS = device.$(OBJEXT) cipher.$(OBJEXT) \ crypto.$(OBJEXT) ecdh.$(OBJEXT) ecdsa.$(OBJEXT) \ digest.$(OBJEXT) prf.$(OBJEXT) rsa.$(OBJEXT) @@ -251,7 +251,7 @@ tincd_SOURCES = utils.c getopt.c getopt1.c list.c splay_tree.c \ net.c net_packet.c net_setup.c net_socket.c netutl.c node.c \ process.c protocol.c protocol_auth.c protocol_edge.c \ protocol_misc.c protocol_key.c protocol_subnet.c route.c \ - sptps.c subnet.c subnet_parse.c tincd.c dummy_device.c \ + sptps.c subnet.c subnet_parse.c event.c tincd.c dummy_device.c \ raw_socket_device.c multicast_device.c $(am__append_1) \ $(am__append_2) $(am__append_3) nodist_tincd_SOURCES = \ @@ -273,7 +273,7 @@ DEFAULT_INCLUDES = noinst_HEADERS = \ xalloc.h utils.h getopt.h list.h splay_tree.h dropin.h fake-getaddrinfo.h fake-getnameinfo.h fake-gai-errnos.h ipv6.h ipv4.h ethernet.h \ buffer.h conf.h connection.h control.h control_common.h device.h edge.h graph.h info.h logger.h meta.h net.h netutl.h node.h process.h \ - protocol.h route.h subnet.h sptps.h tincctl.h top.h bsd/tunemu.h hash.h + protocol.h route.h subnet.h sptps.h tincctl.h top.h bsd/tunemu.h hash.h event.h nodist_noinst_HEADERS = \ cipher.h crypto.h ecdh.h ecdsa.h digest.h prf.h rsa.h ecdsagen.h rsagen.h @@ -383,6 +383,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ecdsa.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ecdsagen.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/edge.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/event.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fake-getaddrinfo.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fake-getnameinfo.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getopt.Po@am__quote@ diff --git a/src/connection.c b/src/connection.c index d39f43f..4798c5a 100644 --- a/src/connection.c +++ b/src/connection.c @@ -68,11 +68,7 @@ void free_connection(connection_t *c) { buffer_clear(&c->inbuf); buffer_clear(&c->outbuf); - if(event_initialized(&c->inevent)) - event_del(&c->inevent); - - if(event_initialized(&c->outevent)) - event_del(&c->outevent); + io_del(&c->io); if(c->socket > 0) closesocket(c->socket); diff --git a/src/connection.h b/src/connection.h index 01c2bf4..10f4a76 100644 --- a/src/connection.h +++ b/src/connection.h @@ -90,8 +90,7 @@ typedef struct connection_t { struct buffer_t inbuf; struct buffer_t outbuf; - struct event inevent; /* input event on this metadata connection */ - struct event outevent; /* output event on this metadata connection */ + io_t io; /* input/output event on this metadata connection */ int tcplen; /* length of incoming TCPpacket */ int allow_request; /* defined if there's only one request possible */ diff --git a/src/control.c b/src/control.c index c166943..83a9d79 100644 --- a/src/control.c +++ b/src/control.c @@ -58,7 +58,7 @@ bool control_h(connection_t *c, const char *request) { switch (type) { case REQ_STOP: - event_loopexit(NULL); + event_exit(); return control_ok(c, REQ_STOP); case REQ_DUMP_NODES: @@ -156,7 +156,7 @@ bool init_control(void) { // Make sure we have a valid address, and map 0.0.0.0 and :: to 127.0.0.1 and ::1. - if(getsockname(listen_socket[0].tcp, (struct sockaddr *)&sa, &len)) { + if(getsockname(listen_socket[0].tcp.fd, (struct sockaddr *)&sa, &len)) { xasprintf(&localhost, "127.0.0.1 port %d", myport); } else { if(sa.sa.sa_family == AF_INET) { diff --git a/src/dropin.h b/src/dropin.h index c6cabba..61143eb 100644 --- a/src/dropin.h +++ b/src/dropin.h @@ -45,4 +45,22 @@ extern int gettimeofday(struct timeval *, void *); extern int usleep(long long usec); #endif +#ifndef timeradd +#define timeradd(a, b, r) do {\ + (r)->tv_sec = (a)->tv_sec + (b)->tv_sec;\ + (r)->tv_usec = (a)->tv_usec + (b)->tv_usec;\ + if((r)->tv_usec >= 1000000)\ + (r)->tv_sec++, (r)->tv_usec -= 1000000;\ +} while (0) +#endif + +#ifndef timersub +#define timersub(a, b, r) do {\ + (r)->tv_sec = (a)->tv_sec - (b)->tv_sec;\ + (r)->tv_usec = (a)->tv_usec - (b)->tv_usec;\ + if((r)->tv_usec < 1000000)\ + (r)->tv_sec--, (r)->tv_usec += 1000000;\ +} while (0) +#endif + #endif /* __DROPIN_H__ */ diff --git a/src/ethernet.h b/src/ethernet.h index b759ab3..a8b6420 100644 --- a/src/ethernet.h +++ b/src/ethernet.h @@ -41,6 +41,10 @@ #define ETH_P_IPV6 0x86DD #endif +#ifndef ETH_P_8021Q +#define ETH_P_8021Q 0x8100 +#endif + #ifndef HAVE_STRUCT_ETHER_HEADER struct ether_header { uint8_t ether_dhost[ETH_ALEN]; diff --git a/src/event.c b/src/event.c new file mode 100644 index 0000000..0dde994 --- /dev/null +++ b/src/event.c @@ -0,0 +1,250 @@ +/* + event.c -- I/O, timeout and signal event handling + Copyright (C) 2012 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "system.h" + +#include "dropin.h" +#include "event.h" +#include "net.h" +#include "utils.h" + +struct timeval now; + +static fd_set readfds; +static fd_set writefds; +static volatile bool running; + +static int io_compare(const io_t *a, const io_t *b) { + return a->fd - b->fd; +} + +static int timeout_compare(const timeout_t *a, const timeout_t *b) { + struct timeval diff; + timersub(&a->tv, &b->tv, &diff); + if(diff.tv_sec < 0) + return -1; + if(diff.tv_sec > 0) + return 1; + if(diff.tv_usec < 0) + return -1; + if(diff.tv_usec > 0) + return 1; + if(a < b) + return -1; + if(a > b) + return 1; + return 0; +} + +static int signal_compare(const signal_t *a, const signal_t *b) { + return a->signum - b->signum; +} + +static splay_tree_t io_tree = {.compare = (splay_compare_t)io_compare}; +static splay_tree_t timeout_tree = {.compare = (splay_compare_t)timeout_compare}; +static splay_tree_t signal_tree = {.compare = (splay_compare_t)signal_compare}; + +void io_add(io_t *io, io_cb_t cb, void *data, int fd, int flags) { + if(io->cb) + return; + + io->fd = fd; + io->cb = cb; + io->data = data; + io->node.data = io; + + io_set(io, flags); + + if(!splay_insert_node(&io_tree, &io->node)) + abort(); +} + +void io_set(io_t *io, int flags) { + io->flags = flags; + + if(flags & IO_READ) + FD_SET(io->fd, &readfds); + else + FD_CLR(io->fd, &readfds); + + if(flags & IO_WRITE) + FD_SET(io->fd, &writefds); + else + FD_CLR(io->fd, &writefds); +} + +void io_del(io_t *io) { + if(!io->cb) + return; + + io_set(io, 0); + + splay_unlink_node(&io_tree, &io->node); + io->cb = NULL; +} + +void timeout_add(timeout_t *timeout, timeout_cb_t cb, void *data, struct timeval *tv) { + timeout->cb = cb; + timeout->data = data; + timeout->node.data = timeout; + + timeout_set(timeout, tv); +} + +void timeout_set(timeout_t *timeout, struct timeval *tv) { + if(timerisset(&timeout->tv)) + splay_unlink_node(&timeout_tree, &timeout->node); + + if(!now.tv_sec) + gettimeofday(&now, NULL); + + timeradd(&now, tv, &timeout->tv); + + if(!splay_insert_node(&timeout_tree, &timeout->node)) + abort(); +} + +void timeout_del(timeout_t *timeout) { + if(!timeout->cb) + return; + + splay_unlink_node(&timeout_tree, &timeout->node); + timeout->cb = 0; + timeout->tv = (struct timeval){0, 0}; +} + +#ifndef HAVE_MINGW +static io_t signalio; +static int pipefd[2] = {-1, -1}; + +static void signal_handler(int signum) { + unsigned char num = signum; + write(pipefd[1], &num, 1); +} + +static void signalio_handler(void *data, int flags) { + unsigned char signum; + if(read(pipefd[0], &signum, 1) != 1) + return; + + signal_t *sig = splay_search(&signal_tree, &((signal_t){.signum = signum})); + if(sig) + sig->cb(sig->data); +} + +static void pipe_init(void) { + if(!pipe(pipefd)) + io_add(&signalio, signalio_handler, NULL, pipefd[0], IO_READ); +} + +void signal_add(signal_t *sig, signal_cb_t cb, void *data, int signum) { + if(sig->cb) + return; + + sig->cb = cb; + sig->data = data; + sig->signum = signum; + sig->node.data = sig; + + if(pipefd[0] == -1) + pipe_init(); + + signal(sig->signum, signal_handler); + + if(!splay_insert_node(&signal_tree, &sig->node)) + abort(); +} + +void signal_del(signal_t *sig) { + if(!sig->cb) + return; + + signal(sig->signum, SIG_DFL); + + splay_unlink_node(&signal_tree, &sig->node); + sig->cb = NULL; +} +#endif + +bool event_loop(void) { + running = true; + + fd_set readable; + fd_set writable; + + while(running) { + gettimeofday(&now, NULL); + struct timeval diff, *tv = NULL; + + while(timeout_tree.head) { + timeout_t *timeout = timeout_tree.head->data; + timersub(&timeout->tv, &now, &diff); + + if(diff.tv_sec < 0) { + timeout->cb(timeout->data); + if(timercmp(&timeout->tv, &now, <)) + timeout_del(timeout); + } else { + tv = &diff; + break; + } + } + + memcpy(&readable, &readfds, sizeof readable); + memcpy(&writable, &writefds, sizeof writable); + + int fds = 0; + + if(io_tree.tail) { + io_t *last = io_tree.tail->data; + fds = last->fd + 1; + } + +#ifdef HAVE_MINGW + LeaveCriticalSection(&mutex); +#endif + int n = select(fds, &readable, &writable, NULL, tv); +#ifdef HAVE_MINGW + EnterCriticalSection(&mutex); +#endif + + if(n < 0) { + if(sockwouldblock(errno)) + continue; + else + return false; + } + + if(!n) + continue; + + for splay_each(io_t, io, &io_tree) { + if(FD_ISSET(io->fd, &writable)) + io->cb(io->data, IO_WRITE); + else if(FD_ISSET(io->fd, &readable)) + io->cb(io->data, IO_READ); + } + } + + return true; +} + +void event_exit(void) { + running = false; +} diff --git a/src/event.h b/src/event.h new file mode 100644 index 0000000..d0129d0 --- /dev/null +++ b/src/event.h @@ -0,0 +1,70 @@ +/* + event.h -- I/O, timeout and signal event handling + Copyright (C) 2012 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#ifndef __TINC_EVENT_H__ +#define __TINC_EVENT_H__ + +#include "splay_tree.h" + +#define IO_READ 1 +#define IO_WRITE 2 + +typedef void (*io_cb_t)(void *data, int flags); +typedef void (*timeout_cb_t)(void *data); +typedef void (*signal_cb_t)(void *data); + +typedef struct io_t { + int fd; + int flags; + io_cb_t cb; + void *data; + splay_node_t node; +} io_t; + +typedef struct timeout_t { + struct timeval tv; + timeout_cb_t cb; + void *data; + splay_node_t node; +} timeout_t; + +typedef struct signal_t { + int signum; + signal_cb_t cb; + void *data; + splay_node_t node; +} signal_t; + +extern struct timeval now; + +extern void io_add(io_t *io, io_cb_t cb, void *data, int fd, int flags); +extern void io_del(io_t *io); +extern void io_set(io_t *io, int flags); + +extern void timeout_add(timeout_t *timeout, timeout_cb_t cb, void *data, struct timeval *tv); +extern void timeout_del(timeout_t *timeout); +extern void timeout_set(timeout_t *timeout, struct timeval *tv); + +extern void signal_add(signal_t *sig, signal_cb_t cb, void *data, int signum); +extern void signal_del(signal_t *sig); + +extern bool event_loop(void); +extern void event_exit(void); + +#endif diff --git a/src/graph.c b/src/graph.c index 9036c52..73db3b2 100644 --- a/src/graph.c +++ b/src/graph.c @@ -213,8 +213,7 @@ static void check_reachability(void) { n->minmtu = 0; n->mtuprobes = 0; - if(timeout_initialized(&n->mtuevent)) - event_del(&n->mtuevent); + timeout_del(&n->mtutimeout); char *name; char *address; diff --git a/src/hash.c b/src/hash.c index cf5ba90..1d203c5 100644 --- a/src/hash.c +++ b/src/hash.c @@ -55,7 +55,7 @@ hash_t *hash_alloc(size_t n, size_t size) { hash_t *hash = xmalloc_and_zero(sizeof *hash); hash->n = n; hash->size = size; - hash->keys = xmalloc(hash->n * hash->size); + hash->keys = xmalloc_and_zero(hash->n * hash->size); hash->values = xmalloc_and_zero(hash->n * sizeof *hash->values); return hash; } @@ -100,6 +100,8 @@ void hash_clear(hash_t *hash) { void hash_resize(hash_t *hash, size_t n) { hash->keys = xrealloc(hash->keys, n * hash->size); hash->values = xrealloc(hash->values, n * sizeof *hash->values); - if(n > hash->n) + if(n > hash->n) { + memset(hash->keys + hash->n * hash->size, 0, (n - hash->n) * hash->size); memset(hash->values + hash->n, 0, (n - hash->n) * sizeof *hash->values); + } } diff --git a/src/logger.c b/src/logger.c index 4527a37..e01980e 100644 --- a/src/logger.c +++ b/src/logger.c @@ -41,7 +41,6 @@ bool logcontrol = false; static void real_logger(int level, int priority, const char *message) { char timestr[32] = ""; - time_t now; static bool suppress = false; // Bail out early if there is nothing to do. @@ -58,8 +57,10 @@ static void real_logger(int level, int priority, const char *message) { fflush(stderr); break; case LOGMODE_FILE: - now = time(NULL); - strftime(timestr, sizeof timestr, "%Y-%m-%d %H:%M:%S", localtime(&now)); + if(!now.tv_sec) + gettimeofday(&now, NULL); + time_t now_sec = now.tv_sec; + strftime(timestr, sizeof timestr, "%Y-%m-%d %H:%M:%S", localtime(&now_sec)); fprintf(logfile, "%s %s[%ld]: %s\n", timestr, logident, (long)logpid, message); fflush(logfile); break; diff --git a/src/meta.c b/src/meta.c index 84fb196..1244bfd 100644 --- a/src/meta.c +++ b/src/meta.c @@ -39,7 +39,7 @@ bool send_meta_sptps(void *handle, uint8_t type, const char *buffer, size_t leng } buffer_add(&c->outbuf, buffer, length); - event_add(&c->outevent, NULL); + io_set(&c->io, IO_READ | IO_WRITE); return true; } @@ -65,12 +65,11 @@ bool send_meta(connection_t *c, const char *buffer, int length) { c->name, c->hostname); return false; } - } else { buffer_add(&c->outbuf, buffer, length); } - event_add(&c->outevent, NULL); + io_set(&c->io, IO_READ | IO_WRITE); return true; } diff --git a/src/net.c b/src/net.c index f8ffbe3..fe272db 100644 --- a/src/net.c +++ b/src/net.c @@ -74,7 +74,7 @@ void purge(void) { if(e->to == n) return; - if(!strictsubnets || !n->subnet_tree->head) + if(!autoconnect && (!strictsubnets || !n->subnet_tree->head)) /* in strictsubnets mode do not delete nodes with subnets */ node_del(n); } @@ -137,18 +137,16 @@ void terminate_connection(connection_t *c, bool report) { end does not reply in time, we consider them dead and close the connection. */ -static void timeout_handler(int fd, short events, void *event) { - time_t now = time(NULL); - +static void timeout_handler(void *data) { for list_each(connection_t, c, connection_list) { if(c->status.control) continue; - if(c->last_ping_time + pingtimeout <= now) { + if(c->last_ping_time + pingtimeout <= now.tv_sec) { if(c->status.active) { if(c->status.pinged) { - logger(DEBUG_CONNECTIONS, LOG_INFO, "%s (%s) didn't respond to PING in %ld seconds", c->name, c->hostname, (long)now - c->last_ping_time); - } else if(c->last_ping_time + pinginterval <= now) { + logger(DEBUG_CONNECTIONS, LOG_INFO, "%s (%s) didn't respond to PING in %ld seconds", c->name, c->hostname, (long)now.tv_sec - c->last_ping_time); + } else if(c->last_ping_time + pinginterval <= now.tv_sec) { send_ping(c); continue; } else { @@ -164,6 +162,15 @@ static void timeout_handler(int fd, short events, void *event) { } } + timeout_set(data, &(struct timeval){pingtimeout, rand() % 100000}); +} + +static void periodic_handler(void *data) { + /* Check if there are too many contradicting ADD_EDGE and DEL_EDGE messages. + This usually only happens when another node has the same Name as this node. + If so, sleep for a short while to prevent a storm of contradicting messages. + */ + if(contradicting_del_edge > 100 && contradicting_add_edge > 100) { logger(DEBUG_ALWAYS, LOG_WARNING, "Possible node with same Name as us! Sleeping %d seconds.", sleeptime); usleep(sleeptime * 1000000LL); @@ -179,11 +186,100 @@ static void timeout_handler(int fd, short events, void *event) { contradicting_add_edge = 0; contradicting_del_edge = 0; - event_add(event, &(struct timeval){pingtimeout, 0}); + /* If AutoConnect is set, check if we need to make or break connections. */ + + if(autoconnect && node_tree->count > 1) { + /* Count number of active connections */ + int nc = 0; + for list_each(connection_t, c, connection_list) { + if(c->status.active && !c->status.control) + nc++; + } + + if(nc < autoconnect) { + /* Not enough active connections, try to add one. + Choose a random node, if we don't have a connection to it, + and we are not already trying to make one, create an + outgoing connection to this node. + */ + int r = rand() % node_tree->count; + int i = 0; + + for splay_each(node_t, n, node_tree) { + if(i++ != r) + continue; + + if(n->connection) + break; + + bool found = false; + + for list_each(outgoing_t, outgoing, outgoing_list) { + if(!strcmp(outgoing->name, n->name)) { + found = true; + break; + } + } + + if(!found) { + logger(DEBUG_CONNECTIONS, LOG_INFO, "Autoconnecting to %s", n->name); + outgoing_t *outgoing = xmalloc_and_zero(sizeof *outgoing); + outgoing->name = xstrdup(n->name); + list_insert_tail(outgoing_list, outgoing); + setup_outgoing_connection(outgoing); + } + break; + } + } else if(nc > autoconnect) { + /* Too many active connections, try to remove one. + Choose a random outgoing connection to a node + that has at least one other connection. + */ + int r = rand() % nc; + int i = 0; + + for list_each(connection_t, c, connection_list) { + if(!c->status.active || c->status.control) + continue; + + if(i++ != r) + continue; + + if(!c->outgoing || !c->node || c->node->edge_tree->count < 2) + break; + + logger(DEBUG_CONNECTIONS, LOG_INFO, "Autodisconnecting from %s", c->name); + list_delete(outgoing_list, c->outgoing); + c->outgoing = NULL; + terminate_connection(c, c->status.active); + break; + } + } + + if(nc >= autoconnect) { + /* If we have enough active connections, + remove any pending outgoing connections. + */ + for list_each(outgoing_t, o, outgoing_list) { + bool found = false; + for list_each(connection_t, c, connection_list) { + if(c->outgoing == o) { + found = true; + break; + } + } + if(!found) { + logger(DEBUG_CONNECTIONS, LOG_INFO, "Cancelled outgoing connection to %s", o->name); + list_delete_node(outgoing_list, node); + } + } + } + } + + timeout_set(data, &(struct timeval){5, rand() % 100000}); } -void handle_meta_connection_data(int fd, short events, void *data) { - connection_t *c = data; +void handle_meta_connection_data(connection_t *c) { int result; socklen_t len = sizeof result; @@ -207,19 +303,19 @@ void handle_meta_connection_data(int fd, short events, void *data) { } } -static void sigterm_handler(int signal, short events, void *data) { - logger(DEBUG_ALWAYS, LOG_NOTICE, "Got %s signal", strsignal(signal)); - event_loopexit(NULL); +static void sigterm_handler(void *data) { + logger(DEBUG_ALWAYS, LOG_NOTICE, "Got %s signal", strsignal(((signal_t *)data)->signum)); + event_exit(); } -static void sighup_handler(int signal, short events, void *data) { - logger(DEBUG_ALWAYS, LOG_NOTICE, "Got %s signal", strsignal(signal)); +static void sighup_handler(void *data) { + logger(DEBUG_ALWAYS, LOG_NOTICE, "Got %s signal", strsignal(((signal_t *)data)->signum)); reopenlogger(); reload_configuration(); } -static void sigalrm_handler(int signal, short events, void *data) { - logger(DEBUG_ALWAYS, LOG_NOTICE, "Got %s signal", strsignal(signal)); +static void sigalrm_handler(void *data) { + logger(DEBUG_ALWAYS, LOG_NOTICE, "Got %s signal", strsignal(((signal_t *)data)->signum)); retry(); } @@ -233,7 +329,7 @@ int reload_configuration(void) { if(!read_server_config()) { logger(DEBUG_ALWAYS, LOG_ERR, "Unable to reread configuration file, exitting."); - event_loopexit(NULL); + event_exit(); return EINVAL; } @@ -332,8 +428,7 @@ int reload_configuration(void) { void retry(void) { for list_each(connection_t, c, connection_list) { if(c->outgoing && !c->node) { - if(timeout_initialized(&c->outgoing->ev)) - event_del(&c->outgoing->ev); + timeout_del(&c->outgoing->ev); if(c->status.connecting) close(c->socket); c->outgoing->timeout = 0; @@ -346,40 +441,38 @@ void retry(void) { this is where it all happens... */ int main_loop(void) { - struct event timeout_event; + timeout_t pingtimer = {{0}}; + timeout_t periodictimer = {{0}}; - timeout_set(&timeout_event, timeout_handler, &timeout_event); - event_add(&timeout_event, &(struct timeval){pingtimeout, 0}); + timeout_add(&pingtimer, timeout_handler, &pingtimer, &(struct timeval){pingtimeout, rand() % 100000}); + timeout_add(&periodictimer, periodic_handler, &periodictimer, &(struct timeval){pingtimeout, rand() % 100000}); #ifndef HAVE_MINGW - struct event sighup_event; - struct event sigterm_event; - struct event sigquit_event; - struct event sigalrm_event; + signal_t sighup = {0}; + signal_t sigterm = {0}; + signal_t sigquit = {0}; + signal_t sigalrm = {0}; - signal_set(&sighup_event, SIGHUP, sighup_handler, NULL); - signal_add(&sighup_event, NULL); - signal_set(&sigterm_event, SIGTERM, sigterm_handler, NULL); - signal_add(&sigterm_event, NULL); - signal_set(&sigquit_event, SIGQUIT, sigterm_handler, NULL); - signal_add(&sigquit_event, NULL); - signal_set(&sigalrm_event, SIGALRM, sigalrm_handler, NULL); - signal_add(&sigalrm_event, NULL); + signal_add(&sighup, sighup_handler, &sighup, SIGHUP); + signal_add(&sigterm, sigterm_handler, &sigterm, SIGTERM); + signal_add(&sigquit, sigterm_handler, &sigquit, SIGQUIT); + signal_add(&sigalrm, sigalrm_handler, &sigalrm, SIGALRM); #endif - if(event_loop(0) < 0) { + if(!event_loop()) { logger(DEBUG_ALWAYS, LOG_ERR, "Error while waiting for input: %s", strerror(errno)); return 1; } #ifndef HAVE_MINGW - signal_del(&sighup_event); - signal_del(&sigterm_event); - signal_del(&sigquit_event); - signal_del(&sigalrm_event); + signal_del(&sighup); + signal_del(&sigalrm); + signal_del(&sigquit); + signal_del(&sigterm); #endif - event_del(&timeout_event); + timeout_del(&periodictimer); + timeout_del(&pingtimer); return 0; } diff --git a/src/net.h b/src/net.h index 23b8cae..4277279 100644 --- a/src/net.h +++ b/src/net.h @@ -24,6 +24,7 @@ #include "ipv6.h" #include "cipher.h" #include "digest.h" +#include "event.h" #ifdef ENABLE_JUMBOGRAMS #define MTU 9018 /* 9000 bytes payload + 14 bytes ethernet header + 4 bytes VLAN tag */ @@ -99,10 +100,8 @@ typedef enum packet_type_t { } packet_type_t; typedef struct listen_socket_t { - struct event ev_tcp; - struct event ev_udp; - int tcp; - int udp; + io_t tcp; + io_t udp; sockaddr_t sa; } listen_socket_t; @@ -116,7 +115,7 @@ typedef struct outgoing_t { struct config_t *cfg; struct addrinfo *ai; struct addrinfo *aip; - struct event ev; + timeout_t ev; } outgoing_t; extern list_t *outgoing_list; @@ -134,6 +133,7 @@ extern int udp_rcvbuf; extern int udp_sndbuf; extern bool do_prune; extern char *myport; +extern int autoconnect; extern int contradicting_add_edge; extern int contradicting_del_edge; extern time_t last_config_check; @@ -160,10 +160,10 @@ extern char *scriptextension; #include "node.h" extern void retry_outgoing(outgoing_t *); -extern void handle_incoming_vpn_data(int, short, void *); +extern void handle_incoming_vpn_data(void *, int); extern void finish_connecting(struct connection_t *); extern bool do_outgoing_connection(struct outgoing_t *); -extern void handle_new_meta_connection(int, short, void *); +extern void handle_new_meta_connection(void *, int); extern int setup_listen_socket(const sockaddr_t *); extern int setup_vpn_in_socket(const sockaddr_t *); extern bool send_sptps_data(void *handle, uint8_t type, const char *data, size_t len); @@ -183,13 +183,14 @@ extern bool node_read_ecdsa_public_key(struct node_t *); extern bool read_ecdsa_public_key(struct connection_t *); extern bool read_rsa_public_key(struct connection_t *); extern void send_mtu_probe(struct node_t *); -extern void handle_device_data(int, short, void *); -extern void handle_meta_connection_data(int, short, void *); +extern void handle_device_data(void *, int); +extern void handle_meta_connection_data(struct connection_t *); extern void regenerate_key(void); extern void purge(void); extern void retry(void); extern int reload_configuration(void); extern void load_all_subnets(void); +extern void load_all_nodes(void); #ifndef HAVE_MINGW #define closesocket(s) close(s) diff --git a/src/net_packet.c b/src/net_packet.c index 67ebc22..3c3397c 100644 --- a/src/net_packet.c +++ b/src/net_packet.c @@ -77,7 +77,7 @@ bool localdiscovery = false; which will be broadcast to the local network. */ -static void send_mtu_probe_handler(int fd, short events, void *data) { +static void send_mtu_probe_handler(void *data) { node_t *n = data; int timeout = 1; @@ -151,23 +151,37 @@ static void send_mtu_probe_handler(int fd, short events, void *data) { } end: - event_add(&n->mtuevent, &(struct timeval){timeout, 0}); + timeout_set(&n->mtutimeout, &(struct timeval){timeout, rand() % 100000}); } void send_mtu_probe(node_t *n) { - if(!timeout_initialized(&n->mtuevent)) - timeout_set(&n->mtuevent, send_mtu_probe_handler, n); - send_mtu_probe_handler(0, 0, n); + timeout_add(&n->mtutimeout, send_mtu_probe_handler, n, &(struct timeval){1, 0}); + send_mtu_probe_handler(n); } static void mtu_probe_h(node_t *n, vpn_packet_t *packet, length_t len) { logger(DEBUG_TRAFFIC, LOG_INFO, "Got MTU probe length %d from %s (%s)", packet->len, n->name, n->hostname); if(!packet->data[0]) { + /* It's a probe request, send back a reply */ + packet->data[0] = 1; - send_udppacket(n, packet); - } else { + + /* Temporarily set udp_confirmed, so that the reply is sent + back exactly the way it came in. */ + + bool udp_confirmed = n->status.udp_confirmed; n->status.udp_confirmed = true; + send_udppacket(n, packet); + n->status.udp_confirmed = udp_confirmed; + } else { + /* It's a valid reply: now we know bidirectional communication + is possible using the address and socket that the reply + packet used. */ + + n->status.udp_confirmed = true; + + /* If we haven't established the PMTU yet, restart the discovery process. */ if(n->mtuprobes > 30) { if(n->minmtu) @@ -176,6 +190,8 @@ static void mtu_probe_h(node_t *n, vpn_packet_t *packet, length_t len) { n->mtuprobes = 1; } + /* If applicable, raise the minimum supported MTU */ + if(len > n->maxmtu) len = n->maxmtu; if(n->minmtu < len) @@ -438,6 +454,84 @@ static void send_sptps_packet(node_t *n, vpn_packet_t *origpkt) { return; } +static void choose_udp_address(const node_t *n, const sockaddr_t **sa, int *sock) { + /* Latest guess */ + *sa = &n->address; + *sock = n->sock; + + /* If the UDP address is confirmed, use it. */ + if(n->status.udp_confirmed) + return; + + /* Send every third packet to n->address; that could be set + to the node's reflexive UDP address discovered during key + exchange. */ + + static int x = 0; + if(++x >= 3) { + x = 0; + return; + } + + /* Otherwise, address are found in edges to this node. + So we pick a random edge and a random socket. */ + + int i = 0; + int j = rand() % n->edge_tree->count; + edge_t *candidate = NULL; + + for splay_each(edge_t, e, n->edge_tree) { + if(i++ == j) { + candidate = e->reverse; + break; + } + } + + if(candidate) { + *sa = &candidate->address; + *sock = rand() % listen_sockets; + } + + /* Make sure we have a suitable socket for the chosen address */ + if(listen_socket[*sock].sa.sa.sa_family != (*sa)->sa.sa_family) { + for(int i = 0; i < listen_sockets; i++) { + if(listen_socket[i].sa.sa.sa_family == (*sa)->sa.sa_family) { + *sock = i; + break; + } + } + } +} + +static void choose_broadcast_address(const node_t *n, const sockaddr_t **sa, int *sock) { + static sockaddr_t broadcast_ipv4 = { + .in = { + .sin_family = AF_INET, + .sin_addr.s_addr = -1, + } + }; + + static sockaddr_t broadcast_ipv6 = { + .in6 = { + .sin6_family = AF_INET6, + .sin6_addr.s6_addr[0x0] = 0xff, + .sin6_addr.s6_addr[0x1] = 0x02, + .sin6_addr.s6_addr[0xf] = 0x01, + } + }; + + *sock = rand() % listen_sockets; + + if(listen_socket[*sock].sa.sa.sa_family == AF_INET6) { + broadcast_ipv6.in6.sin6_port = n->prevedge->address.in.sin_port; + broadcast_ipv6.in6.sin6_scope_id = listen_socket[*sock].sa.in6.sin6_scope_id; + *sa = &broadcast_ipv6; + } else { + broadcast_ipv4.in.sin_port = n->prevedge->address.in.sin_port; + *sa = &broadcast_ipv4; + } +} + static void send_udppacket(node_t *n, vpn_packet_t *origpkt) { vpn_packet_t pkt1, pkt2; vpn_packet_t *pkt[] = { &pkt1, &pkt2, &pkt1, &pkt2 }; @@ -462,15 +556,13 @@ static void send_udppacket(node_t *n, vpn_packet_t *origpkt) { /* Make sure we have a valid key */ if(!n->status.validkey) { - time_t now = time(NULL); - logger(DEBUG_TRAFFIC, LOG_INFO, "No valid key known yet for %s (%s), forwarding via TCP", n->name, n->hostname); - if(n->last_req_key + 10 <= now) { + if(n->last_req_key + 10 <= now.tv_sec) { send_req_key(n); - n->last_req_key = now; + n->last_req_key = now.tv_sec; } send_tcppacket(n->nexthop->connection, origpkt); @@ -534,88 +626,27 @@ static void send_udppacket(node_t *n, vpn_packet_t *origpkt) { /* Send the packet */ - sockaddr_t *sa; + const sockaddr_t *sa; int sock; /* Overloaded use of priority field: -1 means local broadcast */ - if(origpriority == -1 && n->prevedge) { - sockaddr_t broadcast; - broadcast.in.sin_family = AF_INET; - broadcast.in.sin_addr.s_addr = -1; - broadcast.in.sin_port = n->prevedge->address.in.sin_port; - sa = &broadcast; - sock = 0; - } else { - if(origpriority == -1) - origpriority = 0; - - if(n->status.udp_confirmed) { - /* Address of this node is confirmed, so use it. */ - sa = &n->address; - sock = n->sock; - } else { - /* Otherwise, go through the list of known addresses of - this node. The first address we try is always the - one in n->address; that could be set to the node's - reflexive UDP address discovered during key - exchange. The other known addresses are those found - in edges to this node. */ - - static unsigned int i; - int j = 0; - edge_t *candidate = NULL; - - if(i) { - for splay_each(edge_t, e, edge_weight_tree) { - if(e->to != n) - continue; - j++; - if(!candidate || j == i) - candidate = e; - } - } - - if(!candidate) { - sa = &n->address; - sock = n->sock; - } else { - sa = &candidate->address; - sock = rand() % listen_sockets; - } - - if(i++) - if(i > j) - i = 0; - } - } - - /* Determine which socket we have to use */ - - if(sa->sa.sa_family != listen_socket[sock].sa.sa.sa_family) - for(sock = 0; sock < listen_sockets; sock++) - if(sa->sa.sa_family == listen_socket[sock].sa.sa.sa_family) - break; - - if(sock >= listen_sockets) - sock = 0; - - if(!n->status.udp_confirmed) - n->sock = sock; + if(origpriority == -1 && n->prevedge) + choose_broadcast_address(n, &sa, &sock); + else + choose_udp_address(n, &sa, &sock); #if defined(SOL_IP) && defined(IP_TOS) if(priorityinheritance && origpriority != priority && listen_socket[n->sock].sa.sa.sa_family == AF_INET) { priority = origpriority; logger(DEBUG_TRAFFIC, LOG_DEBUG, "Setting outgoing packet priority to %d", priority); - if(setsockopt(listen_socket[n->sock].udp, SOL_IP, IP_TOS, &priority, sizeof(priority))) /* SO_PRIORITY doesn't seem to work */ + if(setsockopt(listen_socket[n->sock].udp.fd, SOL_IP, IP_TOS, &priority, sizeof(priority))) /* SO_PRIORITY doesn't seem to work */ logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "setsockopt", strerror(errno)); } #endif - socklen_t sl = SALEN(n->address.sa); - - if(sendto(listen_socket[sock].udp, (char *) &inpkt->seqno, inpkt->len, 0, &sa->sa, sl) < 0 && !sockwouldblock(sockerrno)) { + if(sendto(listen_socket[sock].udp.fd, (char *) &inpkt->seqno, inpkt->len, 0, &sa->sa, SALEN(sa->sa)) < 0 && !sockwouldblock(sockerrno)) { if(sockmsgsize(sockerrno)) { if(n->maxmtu >= origlen) n->maxmtu = origlen - 1; @@ -647,15 +678,12 @@ bool send_sptps_data(void *handle, uint8_t type, const char *data, size_t len) { /* Otherwise, send the packet via UDP */ - struct sockaddr *sa; - socklen_t sl; + const sockaddr_t *sa; int sock; - sa = &(to->address.sa); - sl = SALEN(to->address.sa); - sock = to->sock; + choose_udp_address(to, &sa, &sock); - if(sendto(listen_socket[sock].udp, data, len, 0, sa, sl) < 0 && !sockwouldblock(sockerrno)) { + if(sendto(listen_socket[sock].udp.fd, data, len, 0, &sa->sa, SALEN(sa->sa)) < 0 && !sockwouldblock(sockerrno)) { if(sockmsgsize(sockerrno)) { if(to->maxmtu >= len) to->maxmtu = len - 1; @@ -711,11 +739,11 @@ bool receive_sptps_record(void *handle, uint8_t type, const char *data, uint16_t int offset = (type & PKT_MAC) ? 0 : 14; if(type & PKT_COMPRESSED) { - len = uncompress_packet(inpkt.data + offset, (const uint8_t *)data, len, from->incompression); - if(len < 0) { + length_t ulen = uncompress_packet(inpkt.data + offset, (const uint8_t *)data, len, from->incompression); + if(ulen < 0) { return false; } else { - inpkt.len = len + offset; + inpkt.len = ulen + offset; } if(inpkt.len > MAXSIZE) abort(); @@ -838,14 +866,13 @@ static node_t *try_harder(const sockaddr_t *from, const vpn_packet_t *pkt) { node_t *n = NULL; bool hard = false; static time_t last_hard_try = 0; - time_t now = time(NULL); for splay_each(edge_t, e, edge_weight_tree) { if(!e->to->status.reachable || e->to == myself) continue; if(sockaddrcmp_noport(from, &e->address)) { - if(last_hard_try == now) + if(last_hard_try == now.tv_sec) continue; hard = true; } @@ -858,13 +885,14 @@ static node_t *try_harder(const sockaddr_t *from, const vpn_packet_t *pkt) { } if(hard) - last_hard_try = now; + last_hard_try = now.tv_sec; - last_hard_try = now; + last_hard_try = now.tv_sec; return n; } -void handle_incoming_vpn_data(int sock, short events, void *data) { +void handle_incoming_vpn_data(void *data, int flags) { + listen_socket_t *ls = data; vpn_packet_t pkt; char *hostname; sockaddr_t from = {{0}}; @@ -872,7 +900,7 @@ void handle_incoming_vpn_data(int sock, short events, void *data) { node_t *n; int len; - len = recvfrom(sock, (char *) &pkt.seqno, MAXSIZE, 0, &from.sa, &fromlen); + len = recvfrom(ls->udp.fd, (char *) &pkt.seqno, MAXSIZE, 0, &from.sa, &fromlen); if(len <= 0 || len > MAXSIZE) { if(!sockwouldblock(sockerrno)) @@ -900,12 +928,12 @@ void handle_incoming_vpn_data(int sock, short events, void *data) { return; } - n->sock = (intptr_t)data; + n->sock = ls - listen_socket; receive_udppacket(n, &pkt); } -void handle_device_data(int sock, short events, void *data) { +void handle_device_data(void *data, int flags) { vpn_packet_t packet; packet.priority = 0; diff --git a/src/net_setup.c b/src/net_setup.c index 95ff5c3..c5c83e7 100644 --- a/src/net_setup.c +++ b/src/net_setup.c @@ -42,7 +42,7 @@ #include "xalloc.h" char *myport; -static struct event device_ev; +static io_t device_io; devops_t devops; char *proxyhost; @@ -50,6 +50,7 @@ char *proxyport; char *proxyuser; char *proxypass; proxytype_t proxytype; +int autoconnect; char *scriptinterpreter; char *scriptextension; @@ -269,22 +270,16 @@ static bool read_rsa_private_key(void) { return result; } -static struct event keyexpire_event; +static timeout_t keyexpire_timeout; -static void keyexpire_handler(int fd, short events, void *data) { +static void keyexpire_handler(void *data) { regenerate_key(); + timeout_set(data, &(struct timeval){keylifetime, rand() % 100000}); } void regenerate_key(void) { - if(timeout_initialized(&keyexpire_event)) { - logger(DEBUG_STATUS, LOG_INFO, "Expiring symmetric keys"); - event_del(&keyexpire_event); - send_key_changed(); - } else { - timeout_set(&keyexpire_event, keyexpire_handler, NULL); - } - - event_add(&keyexpire_event, &(struct timeval){keylifetime, 0}); + logger(DEBUG_STATUS, LOG_INFO, "Expiring symmetric keys"); + send_key_changed(); } /* @@ -347,6 +342,36 @@ void load_all_subnets(void) { closedir(dir); } +void load_all_nodes(void) { + DIR *dir; + struct dirent *ent; + char *dname; + + xasprintf(&dname, "%s" SLASH "hosts", confbase); + dir = opendir(dname); + if(!dir) { + logger(DEBUG_ALWAYS, LOG_ERR, "Could not open %s: %s", dname, strerror(errno)); + free(dname); + return; + } + + while((ent = readdir(dir))) { + if(!check_id(ent->d_name)) + continue; + + node_t *n = lookup_node(ent->d_name); + if(n) + continue; + + n = new_node(); + n->name = xstrdup(ent->d_name); + node_add(n); + } + + closedir(dir); +} + + char *get_name(void) { char *name = NULL; @@ -362,7 +387,7 @@ char *get_name(void) { logger(DEBUG_ALWAYS, LOG_ERR, "Invalid Name: environment variable %s does not exist\n", name + 1); return false; } - envname = alloca(32); + char envname[32]; if(gethostname(envname, 32)) { logger(DEBUG_ALWAYS, LOG_ERR, "Could not get hostname: %s\n", strerror(errno)); return false; @@ -570,6 +595,8 @@ bool setup_myself_reloadable(void) { if(!get_config_int(lookup_config(config_tree, "KeyExpire"), &keylifetime)) keylifetime = 3600; + get_config_int(lookup_config(config_tree, "AutoConnect"), &autoconnect); + return true; } @@ -683,7 +710,8 @@ static bool setup_myself(void) { free(cipher); - regenerate_key(); + send_key_changed(); + timeout_add(&keyexpire_timeout, keyexpire_handler, &keyexpire_timeout, &(struct timeval){keylifetime, rand() % 100000}); /* Check if we want to use message authentication codes... */ @@ -730,6 +758,8 @@ static bool setup_myself(void) { if(strictsubnets) load_all_subnets(); + else if(autoconnect) + load_all_nodes(); /* Open device */ @@ -755,15 +785,8 @@ static bool setup_myself(void) { if(!devops.setup()) return false; - if(device_fd >= 0) { - event_set(&device_ev, device_fd, EV_READ|EV_PERSIST, handle_device_data, NULL); - - if (event_add(&device_ev, NULL) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "event_add failed: %s", strerror(errno)); - devops.close(); - return false; - } - } + if(device_fd >= 0) + io_add(&device_io, handle_device_data, NULL, device_fd, IO_READ); /* Run tinc-up script to further initialize the tap interface */ char *envp[5]; @@ -805,27 +828,16 @@ static bool setup_myself(void) { return false; } - listen_socket[i].tcp = i + 3; - #ifdef FD_CLOEXEC fcntl(i + 3, F_SETFD, FD_CLOEXEC); #endif - listen_socket[i].udp = setup_vpn_in_socket(&sa); - if(listen_socket[i].udp < 0) + int udp_fd = setup_vpn_in_socket(&sa); + if(udp_fd < 0) return false; - event_set(&listen_socket[i].ev_tcp, listen_socket[i].tcp, EV_READ|EV_PERSIST, handle_new_meta_connection, NULL); - if(event_add(&listen_socket[i].ev_tcp, NULL) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "event_add failed: %s", strerror(errno)); - abort(); - } - - event_set(&listen_socket[i].ev_udp, listen_socket[i].udp, EV_READ|EV_PERSIST, handle_incoming_vpn_data, (void *)(intptr_t)listen_sockets); - if(event_add(&listen_socket[listen_sockets].ev_udp, NULL) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "event_add failed: %s", strerror(errno)); - abort(); - } + io_add(&listen_socket[i].tcp, (io_cb_t)handle_new_meta_connection, &listen_socket[i], i + 3, IO_READ); + io_add(&listen_socket[i].udp, (io_cb_t)handle_incoming_vpn_data, &listen_socket[i], udp_fd, IO_READ); if(debug_level >= DEBUG_CONNECTIONS) { hostname = sockaddr2hostname(&sa); @@ -878,37 +890,20 @@ static bool setup_myself(void) { return false; } - listen_socket[listen_sockets].tcp = - setup_listen_socket((sockaddr_t *) aip->ai_addr); + int tcp_fd = setup_listen_socket((sockaddr_t *) aip->ai_addr); - if(listen_socket[listen_sockets].tcp < 0) + if(tcp_fd < 0) continue; - listen_socket[listen_sockets].udp = - setup_vpn_in_socket((sockaddr_t *) aip->ai_addr); + int udp_fd = setup_vpn_in_socket((sockaddr_t *) aip->ai_addr); - if(listen_socket[listen_sockets].udp < 0) { - close(listen_socket[listen_sockets].tcp); + if(tcp_fd < 0) { + close(tcp_fd); continue; } - event_set(&listen_socket[listen_sockets].ev_tcp, - listen_socket[listen_sockets].tcp, - EV_READ|EV_PERSIST, - handle_new_meta_connection, NULL); - if(event_add(&listen_socket[listen_sockets].ev_tcp, NULL) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "event_add failed: %s", strerror(errno)); - abort(); - } - - event_set(&listen_socket[listen_sockets].ev_udp, - listen_socket[listen_sockets].udp, - EV_READ|EV_PERSIST, - handle_incoming_vpn_data, (void *)(intptr_t)listen_sockets); - if(event_add(&listen_socket[listen_sockets].ev_udp, NULL) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "event_add failed: %s", strerror(errno)); - abort(); - } + io_add(&listen_socket[listen_sockets].tcp, handle_new_meta_connection, &listen_socket[listen_sockets], tcp_fd, IO_READ); + io_add(&listen_socket[listen_sockets].udp, handle_incoming_vpn_data, &listen_socket[listen_sockets], udp_fd, IO_READ); if(debug_level >= DEBUG_CONNECTIONS) { hostname = sockaddr2hostname((sockaddr_t *) aip->ai_addr); @@ -990,10 +985,10 @@ void close_network_connections(void) { } for(int i = 0; i < listen_sockets; i++) { - event_del(&listen_socket[i].ev_tcp); - event_del(&listen_socket[i].ev_udp); - close(listen_socket[i].tcp); - close(listen_socket[i].udp); + io_del(&listen_socket[i].tcp); + io_del(&listen_socket[i].udp); + close(listen_socket[i].tcp.fd); + close(listen_socket[i].udp.fd); } char *envp[5]; diff --git a/src/net_socket.c b/src/net_socket.c index 09c5207..212649b 100644 --- a/src/net_socket.c +++ b/src/net_socket.c @@ -271,7 +271,7 @@ int setup_vpn_in_socket(const sockaddr_t *sa) { return nfd; } /* int setup_vpn_in_socket */ -static void retry_outgoing_handler(int fd, short events, void *data) { +static void retry_outgoing_handler(void *data) { setup_outgoing_connection(data); } @@ -281,12 +281,9 @@ void retry_outgoing(outgoing_t *outgoing) { if(outgoing->timeout > maxtimeout) outgoing->timeout = maxtimeout; - timeout_set(&outgoing->ev, retry_outgoing_handler, outgoing); - event_add(&outgoing->ev, &(struct timeval){outgoing->timeout, 0}); + timeout_add(&outgoing->ev, retry_outgoing_handler, outgoing, &(struct timeval){outgoing->timeout, rand() % 100000}); - logger(DEBUG_CONNECTIONS, LOG_NOTICE, - "Trying to re-establish outgoing connection in %d seconds", - outgoing->timeout); + logger(DEBUG_CONNECTIONS, LOG_NOTICE, "Trying to re-establish outgoing connection in %d seconds", outgoing->timeout); } void finish_connecting(connection_t *c) { @@ -349,9 +346,7 @@ static void do_outgoing_pipe(connection_t *c, char *command) { #endif } -static void handle_meta_write(int sock, short events, void *data) { - connection_t *c = data; - +static void handle_meta_write(connection_t *c) { ssize_t outlen = send(c->socket, c->outbuf.data + c->outbuf.offset, c->outbuf.len - c->outbuf.offset, 0); if(outlen <= 0) { if(!errno || errno == EPIPE) { @@ -368,10 +363,16 @@ static void handle_meta_write(int sock, short events, void *data) { } buffer_read(&c->outbuf, outlen); - if(!c->outbuf.len && event_initialized(&c->outevent)) - event_del(&c->outevent); + if(!c->outbuf.len) + io_set(&c->io, IO_READ); } +static void handle_meta_io(void *data, int flags) { + if(flags & IO_WRITE) + handle_meta_write(data); + else + handle_meta_connection_data(data); +} bool do_outgoing_connection(outgoing_t *outgoing) { char *address, *port, *space; @@ -487,16 +488,13 @@ begin: connection_add(c); - event_set(&c->inevent, c->socket, EV_READ | EV_PERSIST, handle_meta_connection_data, c); - event_set(&c->outevent, c->socket, EV_WRITE | EV_PERSIST, handle_meta_write, c); - event_add(&c->inevent, NULL); + io_add(&c->io, handle_meta_io, c, c->socket, IO_READ); return true; } void setup_outgoing_connection(outgoing_t *outgoing) { - if(event_initialized(&outgoing->ev)) - event_del(&outgoing->ev); + timeout_del(&outgoing->ev); node_t *n = lookup_node(outgoing->name); @@ -523,13 +521,14 @@ void setup_outgoing_connection(outgoing_t *outgoing) { accept a new tcp connect and create a new connection */ -void handle_new_meta_connection(int sock, short events, void *data) { +void handle_new_meta_connection(void *data, int flags) { + listen_socket_t *l = data; connection_t *c; sockaddr_t sa; int fd; socklen_t len = sizeof sa; - fd = accept(sock, &sa.sa, &len); + fd = accept(l->tcp.fd, &sa.sa, &len); if(fd < 0) { logger(DEBUG_ALWAYS, LOG_ERR, "Accepting a new connection failed: %s", sockstrerror(sockerrno)); @@ -552,9 +551,7 @@ void handle_new_meta_connection(int sock, short events, void *data) { logger(DEBUG_CONNECTIONS, LOG_NOTICE, "Connection from %s", c->hostname); - event_set(&c->inevent, c->socket, EV_READ | EV_PERSIST, handle_meta_connection_data, c); - event_set(&c->outevent, c->socket, EV_WRITE | EV_PERSIST, handle_meta_write, c); - event_add(&c->inevent, NULL); + io_add(&c->io, handle_meta_io, c, c->socket, IO_READ); configure_tcp(c); @@ -565,8 +562,7 @@ void handle_new_meta_connection(int sock, short events, void *data) { } static void free_outgoing(outgoing_t *outgoing) { - if(event_initialized(&outgoing->ev)) - event_del(&outgoing->ev); + timeout_del(&outgoing->ev); if(outgoing->ai) freeaddrinfo(outgoing->ai); diff --git a/src/netutl.c b/src/netutl.c index a71b370..a55eaea 100644 --- a/src/netutl.c +++ b/src/netutl.c @@ -52,7 +52,7 @@ struct addrinfo *str2addrinfo(const char *address, const char *service, int sock sockaddr_t str2sockaddr(const char *address, const char *port) { struct addrinfo *ai, hint = {0}; - sockaddr_t result; + sockaddr_t result = {{0}}; int err; hint.ai_family = AF_UNSPEC; diff --git a/src/node.c b/src/node.c index e67b9b9..465a48a 100644 --- a/src/node.c +++ b/src/node.c @@ -78,8 +78,7 @@ void free_node(node_t *n) { ecdsa_free(&n->ecdsa); sptps_stop(&n->sptps); - if(timeout_initialized(&n->mtuevent)) - event_del(&n->mtuevent); + timeout_del(&n->mtutimeout); if(n->hostname) free(n->hostname); @@ -129,6 +128,13 @@ void update_node_udp(node_t *n, const sockaddr_t *sa) { if(sa) { n->address = *sa; + n->sock = 0; + for(int i = 0; i < listen_sockets; i++) { + if(listen_socket[i].sa.sa.sa_family == sa->sa.sa_family) { + n->sock = i; + break; + } + } hash_insert(node_udp_cache, sa, n); free(n->hostname); n->hostname = sockaddr2hostname(&n->address); diff --git a/src/node.h b/src/node.h index 3327fca..c567ad9 100644 --- a/src/node.h +++ b/src/node.h @@ -25,6 +25,7 @@ #include "cipher.h" #include "connection.h" #include "digest.h" +#include "event.h" #include "subnet.h" typedef struct node_status_t { @@ -83,7 +84,7 @@ typedef struct node_t { length_t minmtu; /* Probed minimum MTU */ length_t maxmtu; /* Probed maximum MTU */ int mtuprobes; /* Number of probes */ - struct event mtuevent; /* Probe event */ + timeout_t mtutimeout; /* Probe event */ uint64_t in_packets; uint64_t in_bytes; diff --git a/src/process.c b/src/process.c index 37ba84b..2fd3d93 100644 --- a/src/process.c +++ b/src/process.c @@ -25,6 +25,7 @@ #include "control.h" #include "device.h" #include "edge.h" +#include "event.h" #include "logger.h" #include "net.h" #include "node.h" @@ -127,7 +128,7 @@ DWORD WINAPI controlhandler(DWORD request, DWORD type, LPVOID boe, LPVOID bah) { return ERROR_CALL_NOT_IMPLEMENTED; } - event_loopexit(NULL); + event_exit(); status.dwWaitHint = 30000; status.dwCurrentState = SERVICE_STOP_PENDING; SetServiceStatus(statushandle, &status); diff --git a/src/protocol.c b/src/protocol.c index 3c08d72..bdc0378 100644 --- a/src/protocol.c +++ b/src/protocol.c @@ -165,7 +165,24 @@ static void free_past_request(past_request_t *r) { free(r); } -static struct event past_request_event; +static timeout_t past_request_timeout; + +static void age_past_requests(void *data) { + int left = 0, deleted = 0; + + for splay_each(past_request_t, p, past_request_tree) { + if(p->firstseen + pinginterval <= now.tv_sec) + splay_delete_node(past_request_tree, node), deleted++; + else + left++; + } + + if(left || deleted) + logger(DEBUG_SCARY_THINGS, LOG_DEBUG, "Aging past requests: deleted %d, left %d", deleted, left); + + if(left) + timeout_set(&past_request_timeout, &(struct timeval){10, rand() % 100000}); +} bool seen_request(const char *request) { past_request_t *new, p = {NULL}; @@ -180,39 +197,17 @@ bool seen_request(const char *request) { new->request = xstrdup(request); new->firstseen = time(NULL); splay_insert(past_request_tree, new); - event_add(&past_request_event, &(struct timeval){10, 0}); + timeout_add(&past_request_timeout, age_past_requests, NULL, &(struct timeval){10, rand() % 100000}); return false; } } -static void age_past_requests(int fd, short events, void *data) { - int left = 0, deleted = 0; - time_t now = time(NULL); - - for splay_each(past_request_t, p, past_request_tree) { - if(p->firstseen + pinginterval <= now) - splay_delete_node(past_request_tree, node), deleted++; - else - left++; - } - - if(left || deleted) - logger(DEBUG_SCARY_THINGS, LOG_DEBUG, "Aging past requests: deleted %d, left %d", - deleted, left); - - if(left) - event_add(&past_request_event, &(struct timeval){10, 0}); -} - void init_requests(void) { past_request_tree = splay_alloc_tree((splay_compare_t) past_request_compare, (splay_action_t) free_past_request); - - timeout_set(&past_request_event, age_past_requests, NULL); } void exit_requests(void) { splay_delete_tree(past_request_tree); - if(timeout_initialized(&past_request_event)) - event_del(&past_request_event); + timeout_del(&past_request_timeout); } diff --git a/src/route.c b/src/route.c index e874d89..7bb9996 100644 --- a/src/route.c +++ b/src/route.c @@ -59,7 +59,7 @@ static const size_t opt_size = sizeof(struct nd_opt_hdr); #define MAX(a, b) ((a) > (b) ? (a) : (b)) #endif -static struct event age_subnets_event; +static timeout_t age_subnets_timeout; /* RFC 1071 */ @@ -84,13 +84,12 @@ static uint16_t inet_checksum(void *data, int len, uint16_t prevsum) { static bool ratelimit(int frequency) { static time_t lasttime = 0; static int count = 0; - time_t now = time(NULL); - if(lasttime == now) { + if(lasttime == now.tv_sec) { if(count >= frequency) return true; } else { - lasttime = now; + lasttime = now.tv_sec; count = 0; } @@ -115,15 +114,22 @@ static void clamp_mss(const node_t *source, const node_t *via, vpn_packet_t *pac mtu = via->mtu; /* Find TCP header */ - int start = 0; + int start = ether_size; 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(type == ETH_P_8021Q) { + start += 4; + type = packet->data[16] << 8 | packet->data[17]; + } - if(!start || packet->len <= start + 20) + if(type == ETH_P_IP && packet->data[start + 9] == 6) + start += (packet->data[start] & 0xf) * 4; + else if(type == ETH_P_IPV6 && packet->data[start + 6] == 6) + start += 40; + else + return; + + if(packet->len <= start + 20) return; /* Use data offset field to calculate length of options field */ @@ -185,12 +191,11 @@ static void swap_mac_addresses(vpn_packet_t *packet) { memcpy(&packet->data[6], &tmp, sizeof tmp); } -static void age_subnets(int fd, short events, void *data) { +static void age_subnets(void *data) { bool left = false; - time_t now = time(NULL); for splay_each(subnet_t, s, myself->subnet_tree) { - if(s->expires && s->expires < now) { + if(s->expires && s->expires < now.tv_sec) { if(debug_level >= DEBUG_TRAFFIC) { char netstr[MAXNETSTR]; if(net2str(netstr, sizeof netstr, s)) @@ -209,7 +214,7 @@ static void age_subnets(int fd, short events, void *data) { } if(left) - event_add(&age_subnets_event, &(struct timeval){10, 0}); + timeout_set(&age_subnets_timeout, &(struct timeval){10, rand() % 100000}); } static void learn_mac(mac_t *address) { @@ -236,9 +241,7 @@ static void learn_mac(mac_t *address) { if(c->status.active) send_add_subnet(c, subnet); - if(!timeout_initialized(&age_subnets_event)) - timeout_set(&age_subnets_event, age_subnets, NULL); - event_add(&age_subnets_event, &(struct timeval){10, 0}); + timeout_add(&age_subnets_timeout, age_subnets, NULL, &(struct timeval){10, rand() % 100000}); } else { if(subnet->expires) subnet->expires = time(NULL) + macexpire; @@ -247,7 +250,7 @@ static void learn_mac(mac_t *address) { /* RFC 792 */ -static void route_ipv4_unreachable(node_t *source, vpn_packet_t *packet, uint8_t type, uint8_t code) { +static void route_ipv4_unreachable(node_t *source, vpn_packet_t *packet, length_t ether_size, uint8_t type, uint8_t code) { struct ip ip = {0}; struct icmp icmp = {0}; @@ -320,7 +323,7 @@ static void route_ipv4_unreachable(node_t *source, vpn_packet_t *packet, uint8_t /* RFC 791 */ -static void fragment_ipv4_packet(node_t *dest, vpn_packet_t *packet) { +static void fragment_ipv4_packet(node_t *dest, vpn_packet_t *packet, length_t ether_size) { struct ip ip; vpn_packet_t fragment; int len, maxlen, todo; @@ -384,7 +387,7 @@ static void route_ipv4_unicast(node_t *source, vpn_packet_t *packet) { dest.x[2], dest.x[3]); - route_ipv4_unreachable(source, packet, ICMP_DEST_UNREACH, ICMP_NET_UNKNOWN); + route_ipv4_unreachable(source, packet, ether_size, ICMP_DEST_UNREACH, ICMP_NET_UNKNOWN); return; } @@ -394,10 +397,10 @@ static void route_ipv4_unicast(node_t *source, vpn_packet_t *packet) { } if(!subnet->owner->status.reachable) - return route_ipv4_unreachable(source, packet, ICMP_DEST_UNREACH, ICMP_NET_UNREACH); + return route_ipv4_unreachable(source, packet, ether_size, 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); + return route_ipv4_unreachable(source, packet, ether_size, ICMP_DEST_UNREACH, ICMP_NET_ANO); if(priorityinheritance) packet->priority = packet->data[15]; @@ -410,15 +413,15 @@ static void route_ipv4_unicast(node_t *source, vpn_packet_t *packet) { } if(directonly && subnet->owner != via) - return route_ipv4_unreachable(source, packet, ICMP_DEST_UNREACH, ICMP_NET_ANO); + return route_ipv4_unreachable(source, packet, ether_size, ICMP_DEST_UNREACH, ICMP_NET_ANO); if(via && packet->len > MAX(via->mtu, 590) && via != myself) { logger(DEBUG_TRAFFIC, 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); - route_ipv4_unreachable(source, packet, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED); + route_ipv4_unreachable(source, packet, ether_size, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED); } else { - fragment_ipv4_packet(via, packet); + fragment_ipv4_packet(via, packet, ether_size); } return; @@ -445,7 +448,7 @@ static void route_ipv4(node_t *source, vpn_packet_t *packet) { /* RFC 2463 */ -static void route_ipv6_unreachable(node_t *source, vpn_packet_t *packet, uint8_t type, uint8_t code) { +static void route_ipv6_unreachable(node_t *source, vpn_packet_t *packet, length_t ether_size, uint8_t type, uint8_t code) { struct ip6_hdr ip6; struct icmp6_hdr icmp6 = {0}; uint16_t checksum; @@ -543,7 +546,7 @@ static void route_ipv6_unicast(node_t *source, vpn_packet_t *packet) { ntohs(dest.x[6]), ntohs(dest.x[7])); - route_ipv6_unreachable(source, packet, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_ADDR); + route_ipv6_unreachable(source, packet, ether_size, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_ADDR); return; } @@ -553,10 +556,10 @@ static void route_ipv6_unicast(node_t *source, vpn_packet_t *packet) { } if(!subnet->owner->status.reachable) - return route_ipv6_unreachable(source, packet, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_NOROUTE); + return route_ipv6_unreachable(source, packet, ether_size, 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); + return route_ipv6_unreachable(source, packet, ether_size, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_ADMIN); via = (subnet->owner->via == myself) ? subnet->owner->nexthop : subnet->owner->via; @@ -566,12 +569,12 @@ static void route_ipv6_unicast(node_t *source, vpn_packet_t *packet) { } if(directonly && subnet->owner != via) - return route_ipv6_unreachable(source, packet, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_ADMIN); + return route_ipv6_unreachable(source, packet, ether_size, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_ADMIN); if(via && packet->len > MAX(via->mtu, 1294) && via != myself) { logger(DEBUG_TRAFFIC, 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); - route_ipv6_unreachable(source, packet, ICMP6_PACKET_TOO_BIG, 0); + route_ipv6_unreachable(source, packet, ether_size, ICMP6_PACKET_TOO_BIG, 0); return; } @@ -842,17 +845,24 @@ static void route_mac(node_t *source, vpn_packet_t *packet) { if(via && packet->len > via->mtu && via != myself) { logger(DEBUG_TRAFFIC, 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 && packet->len > 590) { - if(packet->data[20] & 0x40) { + length_t ethlen = 14; + + if(type == ETH_P_8021Q) { + type = packet->data[16] << 8 | packet->data[17]; + ethlen += 4; + } + + if(type == ETH_P_IP && packet->len > 576 + ethlen) { + if(packet->data[6 + ethlen] & 0x40) { packet->len = via->mtu; - route_ipv4_unreachable(source, packet, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED); + route_ipv4_unreachable(source, packet, ethlen, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED); } else { - fragment_ipv4_packet(via, packet); + fragment_ipv4_packet(via, packet, ethlen); } return; - } else if(type == ETH_P_IPV6 && packet->len > 1294) { + } else if(type == ETH_P_IPV6 && packet->len > 1280 + ethlen) { packet->len = via->mtu; - route_ipv6_unreachable(source, packet, ICMP6_PACKET_TOO_BIG, 0); + route_ipv6_unreachable(source, packet, ethlen, ICMP6_PACKET_TOO_BIG, 0); return; } } @@ -881,42 +891,48 @@ static void send_pcap(vpn_packet_t *packet) { static bool do_decrement_ttl(node_t *source, vpn_packet_t *packet) { uint16_t type = packet->data[12] << 8 | packet->data[13]; + length_t ethlen = ether_size; + + if(type == ETH_P_8021Q) { + type = packet->data[16] << 8 | packet->data[17]; + ethlen += 4; + } switch (type) { case ETH_P_IP: - if(!checklength(source, packet, 14 + 32)) + if(!checklength(source, packet, ethlen + ip_size)) return false; - if(packet->data[22] < 1) { - if(packet->data[25] != IPPROTO_ICMP || packet->data[46] != ICMP_TIME_EXCEEDED) - route_ipv4_unreachable(source, packet, ICMP_TIME_EXCEEDED, ICMP_EXC_TTL); + if(packet->data[ethlen + 8] < 1) { + if(packet->data[ethlen + 11] != IPPROTO_ICMP || packet->data[ethlen + 32] != ICMP_TIME_EXCEEDED) + route_ipv4_unreachable(source, packet, ethlen, ICMP_TIME_EXCEEDED, ICMP_EXC_TTL); return false; } - uint16_t old = packet->data[22] << 8 | packet->data[23]; - packet->data[22]--; - uint16_t new = packet->data[22] << 8 | packet->data[23]; + uint16_t old = packet->data[ethlen + 8] << 8 | packet->data[ethlen + 9]; + packet->data[ethlen + 8]--; + uint16_t new = packet->data[ethlen + 8] << 8 | packet->data[ethlen + 9]; - uint32_t checksum = packet->data[24] << 8 | packet->data[25]; + uint32_t checksum = packet->data[ethlen + 10] << 8 | packet->data[ethlen + 11]; checksum += old + (~new & 0xFFFF); while(checksum >> 16) checksum = (checksum & 0xFFFF) + (checksum >> 16); - packet->data[24] = checksum >> 8; - packet->data[25] = checksum & 0xff; + packet->data[ethlen + 10] = checksum >> 8; + packet->data[ethlen + 11] = checksum & 0xff; return true; case ETH_P_IPV6: - if(!checklength(source, packet, 14 + 40)) + if(!checklength(source, packet, ethlen + ip6_size)) return false; - if(packet->data[21] < 1) { - if(packet->data[20] != IPPROTO_ICMPV6 || packet->data[54] != ICMP6_TIME_EXCEEDED) - route_ipv6_unreachable(source, packet, ICMP6_TIME_EXCEEDED, ICMP6_TIME_EXCEED_TRANSIT); + if(packet->data[ethlen + 7] < 1) { + if(packet->data[ethlen + 6] != IPPROTO_ICMPV6 || packet->data[ethlen + 40] != ICMP6_TIME_EXCEEDED) + route_ipv6_unreachable(source, packet, ethlen, ICMP6_TIME_EXCEEDED, ICMP6_TIME_EXCEED_TRANSIT); return false; } - packet->data[21]--; + packet->data[ethlen + 7]--; return true; diff --git a/src/splay_tree.c b/src/splay_tree.c index e7d6dbb..54a46f2 100644 --- a/src/splay_tree.c +++ b/src/splay_tree.c @@ -398,6 +398,8 @@ splay_node_t *splay_insert_node(splay_tree_t *tree, splay_node_t *node) { splay_node_t *closest; int result; + node->left = node->right = node->parent = node->next = node->prev = NULL; + if(!tree->root) splay_insert_top(tree, node); else { @@ -418,6 +420,7 @@ splay_node_t *splay_insert_node(splay_tree_t *tree, splay_node_t *node) { void splay_insert_top(splay_tree_t *tree, splay_node_t *node) { node->prev = node->next = node->left = node->right = node->parent = NULL; tree->head = tree->tail = tree->root = node; + tree->count++; } void splay_insert_before(splay_tree_t *tree, splay_node_t *before, splay_node_t *node) { @@ -446,6 +449,7 @@ void splay_insert_before(splay_tree_t *tree, splay_node_t *before, splay_node_t node->parent = NULL; tree->root = node; + tree->count++; } void splay_insert_after(splay_tree_t *tree, splay_node_t *after, splay_node_t *node) { @@ -474,6 +478,7 @@ void splay_insert_after(splay_tree_t *tree, splay_node_t *after, splay_node_t *n node->parent = NULL; tree->root = node; + tree->count++; } splay_node_t *splay_unlink(splay_tree_t *tree, void *data) { @@ -511,6 +516,8 @@ void splay_unlink_node(splay_tree_t *tree, splay_node_t *node) { } else { tree->root = NULL; } + + tree->count--; } void splay_delete_node(splay_tree_t *tree, splay_node_t *node) { diff --git a/src/splay_tree.h b/src/splay_tree.h index 88d7516..8367ce7 100644 --- a/src/splay_tree.h +++ b/src/splay_tree.h @@ -58,6 +58,8 @@ typedef struct splay_tree_t { splay_compare_t compare; splay_action_t delete; + int count; + } splay_tree_t; /* (De)constructors */ diff --git a/src/sptps_test.c b/src/sptps_test.c index 7aafbbe..9db63ff 100644 --- a/src/sptps_test.c +++ b/src/sptps_test.c @@ -29,6 +29,7 @@ bool send_request(void *c, const char *msg, ...) { return false; } struct list_t *connection_list = NULL; bool send_meta(void *c, const char *msg , int len) { return false; } char *logfilename = NULL; +struct timeval now; ecdsa_t mykey, hiskey; diff --git a/src/tincctl.c b/src/tincctl.c index c1cabdb..dd0bbcc 100644 --- a/src/tincctl.c +++ b/src/tincctl.c @@ -57,11 +57,12 @@ static char *name = NULL; static char *identname = NULL; /* program name for syslog */ static char *pidfilename = NULL; /* pid file location */ static char *confdir = NULL; -static char controlcookie[1024]; +static char controlcookie[1025]; char *netname = NULL; char *confbase = NULL; static char *tinc_conf = NULL; static char *hosts_dir = NULL; +struct timeval now; // Horrible global variables... static int pid = 0; @@ -134,7 +135,7 @@ static void usage(bool status) { " generate-rsa-keys [bits] Generate a new RSA public/private keypair.\n" " generate-ecdsa-keys Generate a new ECDSA public/private keypair.\n" " dump Dump a list of one of the following things:\n" - " nodes - all known nodes in the VPN\n" + " [reachable] nodes - all known nodes in the VPN\n" " edges - all known connections in the VPN\n" " subnets - all known subnets in the VPN\n" " connections - all meta connections with ourself\n" @@ -708,8 +709,8 @@ static bool connect_tincd(bool verbose) { return false; } - char host[128]; - char port[128]; + char host[129]; + char port[129]; if(fscanf(f, "%20d %1024s %128s port %128s", &pid, controlcookie, host, port) != 4) { if(verbose) @@ -911,6 +912,19 @@ static int cmd_reload(int argc, char *argv[]) { } static int cmd_dump(int argc, char *argv[]) { + bool only_reachable = false; + + if(argc > 2 && !strcasecmp(argv[1], "reachable")) { + if(strcasecmp(argv[2], "nodes")) { + fprintf(stderr, "`reachable' only supported for nodes.\n"); + usage(true); + return 1; + } + only_reachable = true; + argv++; + argc--; + } + if(argc != 2) { fprintf(stderr, "Invalid number of arguments.\n"); usage(true); @@ -985,8 +999,10 @@ static int cmd_dump(int argc, char *argv[]) { fprintf(stderr, "Unable to parse node dump from tincd: %s\n", line); return 1; } + + memcpy(&status, &status_int, sizeof status); + if(do_graph) { - memcpy(&status, &status_int, sizeof status); const char *color = "black"; if(!strcmp(host, "MYSELF")) color = "green"; @@ -1000,6 +1016,8 @@ static int cmd_dump(int argc, char *argv[]) { color = "green"; printf(" %s [label = \"%s\", color = \"%s\"%s];\n", node, node, color, strcmp(host, "MYSELF") ? "" : ", style = \"filled\""); } else { + if(only_reachable && !status.reachable) + continue; printf("%s at %s port %s cipher %d digest %d maclength %d compression %d options %x status %04x nexthop %s via %s distance %d pmtu %hd (min %hd max %hd)\n", node, host, port, cipher, digest, maclength, compression, options, status_int, nexthop, via, distance, pmtu, minmtu, maxmtu); } @@ -1233,6 +1251,7 @@ static struct { } const variables[] = { /* Server configuration */ {"AddressFamily", VAR_SERVER}, + {"AutoConnect", VAR_SERVER}, {"BindToAddress", VAR_SERVER | VAR_MULTIPLE}, {"BindToInterface", VAR_SERVER}, {"Broadcast", VAR_SERVER}, @@ -1945,7 +1964,7 @@ static char *complete_command(const char *text, int state) { } static char *complete_dump(const char *text, int state) { - const char *matches[] = {"nodes", "edges", "subnets", "connections", "graph", NULL}; + const char *matches[] = {"reachable", "nodes", "edges", "subnets", "connections", "graph", NULL}; static int i; if(!state) diff --git a/src/tincd.c b/src/tincd.c index 9f94d89..3883ec2 100644 --- a/src/tincd.c +++ b/src/tincd.c @@ -450,11 +450,6 @@ int main2(int argc, char **argv) { } #endif - if(!event_init()) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error initializing libevent!"); - return 1; - } - /* Setup sockets and open device. */ if(!setup_network()) diff --git a/src/top.c b/src/top.c index 8232c7a..8cd82be 100644 --- a/src/top.c +++ b/src/top.c @@ -57,11 +57,13 @@ static int sortmode = 0; static bool cumulative = false; static list_t node_list; -static struct timeval now, prev, diff; +static struct timeval cur, prev, diff; static int delay = 1000; static bool changed = true; -static const char *unit = "bytes"; -static float scale = 1; +static const char *bunit = "bytes"; +static float bscale = 1; +static const char *punit = "pkts"; +static float pscale = 1; #ifndef timersub #define timersub(a, b, c) do {(c)->tv_sec = (a)->tv_sec - (b)->tv_sec; (c)->tv_usec = (a)->tv_usec = (b)->tv_usec;} while(0) @@ -69,10 +71,10 @@ static float scale = 1; static void update(int fd) { sendline(fd, "%d %d", CONTROL, REQ_DUMP_TRAFFIC); - gettimeofday(&now, NULL); + gettimeofday(&cur, NULL); - timersub(&now, &prev, &diff); - prev = now; + timersub(&cur, &prev, &diff); + prev = cur; float interval = diff.tv_sec + diff.tv_usec * 1e-6; char line[4096]; @@ -136,12 +138,69 @@ static void update(int fd) { } } +static int cmpfloat(float a, float b) { + if(a < b) + return -1; + else if(a > b) + return 1; + else + return 0; +} + +static int cmpu64(uint64_t a, uint64_t b) { + if(a < b) + return -1; + else if(a > b) + return 1; + else + return 0; +} + +static int sortfunc(const void *a, const void *b) { + const nodestats_t *na = *(const nodestats_t **)a; + const nodestats_t *nb = *(const nodestats_t **)b; + switch(sortmode) { + case 1: + if(cumulative) + return -cmpu64(na->in_packets, nb->in_packets) ?: na->i - nb->i; + else + return -cmpfloat(na->in_packets_rate, nb->in_packets_rate) ?: na->i - nb->i; + case 2: + if(cumulative) + return -cmpu64(na->in_bytes, nb->in_bytes) ?: na->i - nb->i; + else + return -cmpfloat(na->in_bytes_rate, nb->in_bytes_rate) ?: na->i - nb->i; + case 3: + if(cumulative) + return -cmpu64(na->out_packets, nb->out_packets) ?: na->i - nb->i; + else + return -cmpfloat(na->out_packets_rate, nb->out_packets_rate) ?: na->i - nb->i; + case 4: + if(cumulative) + return -cmpu64(na->out_bytes, nb->out_bytes) ?: na->i - nb->i; + else + return -cmpfloat(na->out_bytes_rate, nb->out_bytes_rate) ?: na->i - nb->i; + case 5: + if(cumulative) + return -cmpu64(na->in_packets + na->out_packets, nb->in_packets + nb->out_packets) ?: na->i - nb->i; + else + return -cmpfloat(na->in_packets_rate + na->out_packets_rate, nb->in_packets_rate + nb->out_packets_rate) ?: na->i - nb->i; + case 6: + if(cumulative) + return -cmpu64(na->in_bytes + na->out_bytes, nb->in_bytes + nb->out_bytes) ?: na->i - nb->i; + else + return -cmpfloat(na->in_bytes_rate + na->out_bytes_rate, nb->in_bytes_rate + nb->out_bytes_rate) ?: na->i - nb->i; + default: + return strcmp(na->name, nb->name) ?: na->i - nb->i; + } +} + static void redraw(void) { erase(); mvprintw(0, 0, "Tinc %-16s Nodes: %4d Sort: %-10s %s", netname ?: "", node_list.count, sortname[sortmode], cumulative ? "Cumulative" : "Current"); attrset(A_REVERSE); - mvprintw(2, 0, "Node IN pkts IN %s OUT pkts OUT %s", unit, unit); + mvprintw(2, 0, "Node IN %s IN %s OUT %s OUT %s", punit, bunit, punit, bunit); chgat(-1, A_REVERSE, 0, NULL); static nodestats_t **sorted = 0; @@ -157,63 +216,6 @@ static void redraw(void) { for(int i = 0; i < n; i++) sorted[i]->i = i; - int cmpfloat(float a, float b) { - if(a < b) - return -1; - else if(a > b) - return 1; - else - return 0; - } - - int cmpu64(uint64_t a, uint64_t b) { - if(a < b) - return -1; - else if(a > b) - return 1; - else - return 0; - } - - int sortfunc(const void *a, const void *b) { - const nodestats_t *na = *(const nodestats_t **)a; - const nodestats_t *nb = *(const nodestats_t **)b; - switch(sortmode) { - case 1: - if(cumulative) - return -cmpu64(na->in_packets, nb->in_packets) ?: na->i - nb->i; - else - return -cmpfloat(na->in_packets_rate, nb->in_packets_rate) ?: na->i - nb->i; - case 2: - if(cumulative) - return -cmpu64(na->in_bytes, nb->in_bytes) ?: na->i - nb->i; - else - return -cmpfloat(na->in_bytes_rate, nb->in_bytes_rate) ?: na->i - nb->i; - case 3: - if(cumulative) - return -cmpu64(na->out_packets, nb->out_packets) ?: na->i - nb->i; - else - return -cmpfloat(na->out_packets_rate, nb->out_packets_rate) ?: na->i - nb->i; - case 4: - if(cumulative) - return -cmpu64(na->out_bytes, nb->out_bytes) ?: na->i - nb->i; - else - return -cmpfloat(na->out_bytes_rate, nb->out_bytes_rate) ?: na->i - nb->i; - case 5: - if(cumulative) - return -cmpu64(na->in_packets + na->out_packets, nb->in_packets + nb->out_packets) ?: na->i - nb->i; - else - return -cmpfloat(na->in_packets_rate + na->out_packets_rate, nb->in_packets_rate + nb->out_packets_rate) ?: na->i - nb->i; - case 6: - if(cumulative) - return -cmpu64(na->in_bytes + na->out_bytes, nb->in_bytes + nb->out_bytes) ?: na->i - nb->i; - else - return -cmpfloat(na->in_bytes_rate + na->out_bytes_rate, nb->in_bytes_rate + nb->out_bytes_rate) ?: na->i - nb->i; - default: - return strcmp(na->name, nb->name) ?: na->i - nb->i; - } - } - qsort(sorted, n, sizeof *sorted, sortfunc); for(int i = 0, row = 3; i < n; i++, row++) { @@ -228,10 +230,10 @@ static void redraw(void) { if(cumulative) mvprintw(row, 0, "%-16s %10"PRIu64" %10.0f %10"PRIu64" %10.0f", - node->name, node->in_packets, node->in_bytes * scale, node->out_packets, node->out_bytes * scale); + node->name, node->in_packets * pscale, node->in_bytes * bscale, node->out_packets * pscale, node->out_bytes * bscale); else mvprintw(row, 0, "%-16s %10.0f %10.0f %10.0f %10.0f", - node->name, node->in_packets_rate, node->in_bytes_rate * scale, node->out_packets_rate, node->out_bytes_rate * scale); + node->name, node->in_packets_rate * pscale, node->in_bytes_rate * bscale, node->out_packets_rate * pscale, node->out_bytes_rate * bscale); } attrset(A_NORMAL); @@ -262,45 +264,53 @@ void top(int fd) { break; } case 'c': - cumulative = !cumulative; - break; + cumulative = !cumulative; + break; case 'n': - sortmode = 0; - break; + sortmode = 0; + break; case 'i': - sortmode = 2; - break; + sortmode = 2; + break; case 'I': - sortmode = 1; - break; + sortmode = 1; + break; case 'o': - sortmode = 4; - break; + sortmode = 4; + break; case 'O': - sortmode = 3; - break; + sortmode = 3; + break; case 't': - sortmode = 6; - break; + sortmode = 6; + break; case 'T': - sortmode = 5; - break; + sortmode = 5; + break; case 'b': - unit = "bytes"; - scale = 1; - break; + bunit = "bytes"; + bscale = 1; + punit = "pkts"; + pscale = 1; + break; case 'k': - unit = "kbyte"; - scale = 1e-3; - break; + bunit = "kbyte"; + bscale = 1e-3; + punit = "pkts"; + pscale = 1; + break; case 'M': - unit = "Mbyte"; - scale = 1e-6; - break; + bunit = "Mbyte"; + bscale = 1e-6; + punit = "kpkt"; + pscale = 1e-3; + break; case 'G': - unit = "Gbyte"; - scale = 1e-9; - break; + bunit = "Gbyte"; + bscale = 1e-9; + punit = "Mpkt"; + pscale = 1e-6; + break; case 'q': case KEY_BREAK: running = false; From 26033edb965c3cf90b7536aa555c6fd28f143e44 Mon Sep 17 00:00:00 2001 From: Guus Sliepen Date: Mon, 26 Aug 2019 13:44:50 +0200 Subject: [PATCH 04/13] Import Upstream version 1.1~pre6 --- ChangeLog | 17082 ++++++--------------------------------- NEWS | 25 + README | 8 +- THANKS | 2 + configure | 2 +- configure.in | 2 +- doc/tinc.conf.5.in | 19 +- doc/tinc.info | 177 +- doc/tinc.texi | 38 +- doc/tincctl.8.in | 12 +- doc/tincd.8.in | 5 +- gui/tinc-gui | 21 +- src/Makefile.am | 6 +- src/Makefile.in | 16 +- src/bsd/device.c | 21 +- src/bsd/device.c.orig | 386 + src/conf.c | 6 +- src/conf.h | 4 +- src/control.c | 4 +- src/cygwin/device.c | 3 +- src/dropin.c | 10 + src/dropin.h | 2 +- src/event.c | 10 +- src/graph.c | 30 +- src/info.c | 12 +- src/linux/device.c | 3 +- src/logger.c | 4 +- src/meta.c | 43 +- src/mingw/device.c | 13 +- src/multicast_device.c | 4 +- src/names.c | 106 + src/names.h | 36 + src/net.c | 24 +- src/net.h | 4 +- src/net_packet.c | 74 +- src/net_setup.c | 39 +- src/net_socket.c | 74 +- src/node.h | 10 +- src/process.c | 12 +- src/protocol.c | 2 +- src/protocol_auth.c | 2 +- src/protocol_key.c | 3 +- src/route.c | 8 +- src/solaris/device.c | 3 +- src/sptps.c | 29 +- src/sptps.h | 3 +- src/subnet.c | 3 +- src/tincctl.c | 216 +- src/tincd.c | 106 +- src/top.c | 9 +- src/uml_device.c | 28 +- src/vde_device.c | 10 +- 52 files changed, 3850 insertions(+), 14921 deletions(-) create mode 100644 src/bsd/device.c.orig create mode 100644 src/names.c create mode 100644 src/names.h diff --git a/ChangeLog b/ChangeLog index 67cebbe..2d8d985 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,14474 +1,2610 @@ -commit 5b7f42bca4dbfee7a5fa2bc119f4739baaeb2f55 -Author: Guus Sliepen -Date: Wed Dec 5 22:32:10 2012 +0100 +Version 1.1pre6 February 20 2013 +------------------------------------------------------------------------ + +Guus Sliepen (16): + Fix datagram SPTPS. + Fix a typo. + Get microsecond time resolution on Windows. + Detect increases in PMTU. + Remove direct inclusion of OpenSSL headers in net_packet.c and tincd.c. + Fix tincd terminating immediately on Windows. + Check for writability when waiting for a socket to finish connecting. + Fix segmentation fault when trying to connect via a SOCKS5 proxy. + Don't send proxy requests for incoming connections. + Derive UNIX socket filename from PID filename. + Let the GUI use UNIX sockets if available. + Don't expect a response from tincd after sending REQ_STOP. + Fix a tiny memory leak. + Fix compiler warnings on Windows. + Fix compiler warnings on some BSD variants. + Releasing 1.1pre6. + +Version 1.1pre5 January 20 2013 +------------------------------------------------------------------------ + +Guus Sliepen (24): + Clarify the description of IndirectData and Mode = router. + Fix display of cumulative packet counters. + Fix infinite loop in timeout handling on Windows. + Fix support for tunemu on iOS devices. + Fix a typo. + Note that node Names are case sensitive. + Note that tincctl import is only meant to work with data from tincctl export. + Mention that the -L, -R and -U options are not supported on all platforms. + Don't complain about garbage if we skipped importing a host file. + Better error messages when using -L, -R or -U on platforms that do not support it. + Always complain if too many arguments are given for tincctl commands. + Check HMAC before sequence number. + Add the tincctl exchange and exchange-all commands. + Count the number of correctly received UDP packets. + Estimate RTT, bandwidth and packet loss between nodes. + Fix the minimum spanning tree algorithm. + Handle SIGINT gracefully. + Move make_names() and related variables to its own source file. + Fix compilation of UML and VDE device support. + Allow connections via UNIX sockets. + Make sure PriorityInheritance also works in switch mode. + Remove possible definition of timersub(), which is also in dropin.h. + Fix tincctl init when /etc/tinc does not yet exist. + Releasing 1.1pre5. + +Version 1.1pre4 December 05 2012 +------------------------------------------------------------------------ + +Guus Sliepen (35): + Fix warnings from groff. + Keep track of the number of nodes in a tree. + Add the AutoConnect option. + Slightly randomize all timeouts. + Fix potential buffer overflow reading the PID file. + Using alloca() for a constant sized buffer is very silly. + Make sure PMTU discovery works in switch mode with VLAN tags. + Mention libcurses and libreadline in the manual. + Mention in the manual that support for LZO and zlib can be disabled. + Fix index entry for section about readline library. + Fix configure script help text for --enable options. + Don't take the address of a variable whose scope is about to disappear. + Send broadcast packets using a random socket, and properly support IPv6. + Remove text saying you must have one of PrivateKey or PrivateKeyFile in tinc.conf. + Disable support for kqueue on MacOS/X. + Also don't use poll() on MacOS/X. + Choose a suitable socket when updating a node's UDP address. + Try all known addresses of node during PMTU discovery, now also for SPTPS. + Improve UDP address selection. + Ensure MTU probe replies are sent back the same way they came in. + Drop libevent and use our own event handling again. + Allow multiple timeouts to expire at the exact same time. + Fix check for expired events. + Fix use of unitialised values in hash tables. + Set a node's pointers to zero before trying to insert it into a tree. + Fix crash in timeout handling. + Fix compiler error on Windows. + More fixes for Windows. + Add option to dump only a list of reachable nodes. + Remove GraphDumpFile from the manual and manpages. + Fix compiler warnings on OpenBSD. + Don't use nested functions. + Scale packet counters similar to byte counters. + Fix whitespace. + Releasing 1.1pre4. + +Version 1.1pre3 October 14 2012 +------------------------------------------------------------------------ + +Guus Sliepen (384): + Created the 1.1 branch where large code changes can take place, + Only free members of connection_t that have been allocated. + Port fixes from release 1.0.8. + Properly delete listener socket events on shutdown. + 128 listener sockets is way too much. + Use a separate event structure to handle meta data writes. + Use libevent to dump graphs when necessary. + Use libevent to handle HUP signal. + Configure events after obtaining a socket. + Use libevent to send MTU probes. + Use libevent for retrying outgoing connections. + Remove legacy event system. + Properly use the timeout_initialized() macro. + Use libevent to handle all non-fatal signals. + Redo SIGALRM handling. + Use libevent to age past requests. + Use libevent to age learned MAC addresses. + Use libevent to handle key expiration. + Move key regeneration handling to net_setup.c. + Remove global variable "now". + Remove the last bits of the legacy main_loop(). + Remove last references to the global variable "running". + K&R style braces + Use splay trees instead of AVL trees. + Detect duplicate outgoing connections. + More consistent variable naming. + Show branch version number. + Update documentation. + Start of control socket implementation. + We can safely delete a connection_t in terminate_connection() now. + Fix retrying outgoing connections. + Remove pidfile in favour of control socket. + Move key generation to tincctl. + Implement "stop" command, and allow tincctl to retrieve a running tincd's PID. + Use bufferevents to handle control socket buffering. + Use libevent for meta socket input/output buffering. + Parse PEM RSA keys ourself, and use libgcrypt to do RSA encryption and decryption. + Create wrappers for the cryptographic operations used in tinc. + Make sure the crypto wrapper functions can actually be compiled. + Some more crypto wrapper functions are needed. + Finish crypto wrapping. Also provide wrappers for OpenSSL. + Only check for libgcrypt if --with-gcrypt is used. + Fix formatting of --help output. + Small fixes to make gcrypt routines compile. + Apply patch from Scott Lamb: Update documentation to match tincctl changes + Fix connection weight estimation. + Use a dummy function as the read callback for connection bufferevents. Should not be triggered. + Fix meta data segfault when receiving a partial command. + Prevent double free() of a used challenge nonce. + Look in the configured sbin directory for the tincd binary. + Only show meta connection related debug messages when debug level >= 4 + Move AC_GNU_SOURCE up to make autoconf happy. + Use the crypto wrappers again instead of calling OpenSSL directly. + Backport fixes from trunk since revision 1555. + Fix compiler warnings. + Remove unnecessary parentheses from sizeof, apply sizeof to variables instead of types whereever possible. + Remove wrong checks. + Use Dijkstra's algorithm. Based on patches from Max Rijevskiy. + Make sure IPv6 sockets are IPv6 only. + Move RSA key generation into the wrappers. + Merge branch 'master' into 1.1 + Merge branch 'master' into 1.1 + Handle truncated message authentication codes. + Fix pointer arithmetic when creating and verifying message authentication codes. + Merge branch 'master' into 1.1 + Add missing #include. + Use correct format specifiers. + Replace asprintf()s not covered by the merge to xasprintf(). + Add a better autoconf check for libevent. + Merge branch 'master' into 1.1 + Drop localisation and checkpoint tracing in files not covered by the merge. + Update FSF address in files not covered by the merge. + Merge branch 'master' into 1.1 + Don't enable device events when there is no valid filedescriptor. + Use %x instead of %lx where appropriate. + Handle truncated message authentication codes with gcrypt. + Handle PKCS#5 padding in the gcrypt backend. + Make sure the 1.1 branch compiles in a MinGW environment. + Better integration of libevent in build system. + Small fixes to get really working control sockets on Windows. + Use the TCP socket infrastructure for control sockets. + Only call ioctlsocket() on Windows. + Merge branch 'master' into 1.1 + Fix compiler warnings. + Do not include OpenSSL headers directly. + Include missing header files and source directories. + Allow connections to be closed. + Start of a GUI for tinc. + Fix packet authentication. + Fix block cipher padding when using libgcrypt. + Reinitialise block cipher IV each time we encrypt a packet when using libgcrypt. + Fix reading raw RSA keys with libgcrypt. + recv() and recvfrom() return int, do not prematurely cast the return value. + Do not consider unreachable nodes when trying to determine packet origin. + Fix alignment of results of RSA operations when using libgcrypt. + Do not use hardcoded cipher block length when padding. + Remove unused AVL tree library. + Move source from lib/ to src/. + Fix experimental GUI when reading hexadecimal values. + Merge branch 'master' into 1.1 + Fix merge of commit 4a0b9981513059755b9fd15b38fc198f46a0d6f2. + Add missing return statement. + Use correct digest length when checking a received key. + Do not try to free NULL pointers. + Remove obsolete lib/ directory. + Merge branch 'master' into 1.1 + Link tincctl with dropin.o. + Merge branch 'master' into 1.1 + Do not try to dereference myself->connection->config_tree. + Merge branch 'master' of git://tinc-vpn.org/tinc into 1.1 + Fix check for event initialization due to the merge. + Add simple buffer management code. + Remove use of bufferevent and eventbuffers, use our own buffering instead. + Several fixes for the buffer code. + Add per-node traffic counters. + Dump traffic statistics over control sockets. + Add an autoconf check for the curses library. + Add a very primitive "top" command to tincctl. + Allow inserting items in the middle of a list. + Nicer top command. + Add tincctl.h. + Add top.h. + Use GetItemCount() on ListCtrls instead of directly accessing ItemCount. + Fix some compiler warnings. + Compact input buffer before trying to read instead of after. + Always compact the buffer if it has reached MAXBUFSIZE. + Check if an event is initialized before calling event_del(). + Reset tcplen after use. + Add the ability to dump all traffic going through route() over a control connection. + Allow tincctl to connect to something besides localhost. + Show hostname and port in error message when connecting to a running tincd. + Cosmetic fix when pressing 's' in tincctl top. + Initialise priority field to zero for packets read from the VPN interface. + Remove outgoing event in free_connection(). + Simplify signal handling. + Drop the GNU malloc.c, realloc.c, and xmalloc.c. + Drop the GNU memcmp.c implementation. + Don't #include anymore. + Remove unused functions and variables. + Remove support for the Ethertap device. + Fix some compiler and cppcheck warnings. + More stable sorting in tincctl top. + Make traffic statistics more readable with configurable scaling. + Fix nodes joining the VPN after tincctl top started. + Don't treat packets coming in via TCP as having zero length. + Remove debugging message that was accidentily left in. + Even simpler signal handling. + Small fixes for Windows. + Use send() when writing to sockets, and the return type is ssize_t. + Fix format strings for Windows. + Don't ignore SIGCHLD, system() needs it. + Clean up digests when freeing a connection_t. + Merge branch 'master' of git://tinc-vpn.org/tinc into 1.1 + Reopen log file after SIGHUP. + Only log UDP address changes at the appropriate debug levels. + No need to check for pselect() in tinc 1.1. + Merge branch 'master' of git://tinc-vpn.org/tinc into 1.1 + Delete mtuevent if it is not used. + Don't call event_del() from the mtuevent handler, always send_mtu_probe() in ans_key_h(). + Don't use AM_CONDITIONAL for CURSES. + Add Makefile.am in gui/. + Update manpages and info manual. + Ensure that the texinfo manual can be converted to HTML. + Releasing 1.1pre1. + Ensure the right files end up in the tarball after make dist. + Thank Scott Lamb, Sven-Haegar Koch and Loïc Grenié in the NEWS file. + Merge Tinc.py into tinc-gui to simplify make install. + Re-add support for SIGALRM. + Don't call exit_control() if we didn't do init_control(). + Rename controlcookie file to pidfile. + Make pid files backwards compatible and add address of listening socket. + Add +git to the version string. + Really stable sorting of tincctl top output. + Use pidfile in tinc-gui as well. + Don't react to escape character in tincctl top. + Update documentation to mention pidfiles instead of controlcookies. + Remove debug messages that were printed to stdout. + Add manpage for tinc-gui. + Preliminary implementation of Elliptic Curve Diffie-Hellman Ephemeral key exchange. + Support ECDH key exchange. + Add PRF to derive key material from the ECDH shared secret. + Use PRF. + Proper use of PRF. + No need to keep around pointers to EC_GROUP. + Cleanups in ECDH code. + Base64 encoding and decoding functions. + Add ECDSA key generation. + Have tincctl generate ECDSA keys. + Finish base64 decoding routine. + Add ECDSA key import. + Round up the size of the secret parts after splitting it in two. + Add a minor number to the protocol version. + Bump minor protocol to indicate ECDH capability for UDP session keys. + Implement ECDSA sign and verify operations. + Read ECDSA keys. + Very primitive ECDSA signed ECDH key exchange for the meta protocol. + Hash input before signing it with ECDSA. + Free ECDSA and RSA structures when freeing a connection_t. + Automatically exchange ECDSA keys and upgrade to new authentication protocol. + Close meta connection socket after cleaning up event structures. + Require ExperimentalProtocol = yes for new features, update documentation. + Don't use wildcards in filenames in configure.in. + Make hexadecimal and base64 routines behave the same. + Make use of the improved hex and base64 functions. + Remove unnecessary variables and functions. + Fix compiler warnings. + Use the correct direction flag when setting cipher keys. + Use the same logic as tinc 1.0.x for detecting two nodes with the same Name. + Use ECDSA to sign ECDH key exchange for UDP session keys. + Update info manual. + Use usleep() instead of sleep(), MinGW complained. + Use const pointer to source in base64 and hex routines. + Ensure symlinked files do not end up in the tarball. + Fix declaration of usleep(). + "tincctl stop" now removes the tinc service on Windows. + Write loopback address instead of "any" address in pidfile. + Add missing newline. + Releasing 1.1pre2. + Fix tinc 1.0.x daemons connecting when ExperimentalProtocol = yes. + Don't abort() on low-level crypto errors, just return false. + Start of "Simple Peer-To-Peer Security" protocol. + Handle UDP packets with unknown source addresses properly. + Fix compiler warning. + Update SPTPS protocol. + Test corner cases in the SPTPS protocol. + Add counter mode encryption. + Use counter mode encryption. + Exchange ACK records to indicate switch to new keys. + Fix compiler warnings. + Fix a few small memory leaks. + Use only one hash algorithm (SHA512) in the PRF. + Remove useless warning about signature length being shorter than expected. + Merge branch 'master' of git://tinc-vpn.org/tinc into 1.1 + Merge branch 'master' of git://tinc-vpn.org/tinc into 1.1 + Apply HMAC after encryption. + Use SPTPS when ExperimentalProtocol is enabled. + Merge branch 'master' of git://tinc-vpn.org/tinc into 1.1 + Go back to breadth first search for path finding. + Ensure all SPTPS functions are prefixed with sptps_. + Let tincctl use the NETNAME environment variable if no -n option is given. + Merge branch 'master' of git://tinc-vpn.org/tinc into 1.1 + Don't close control connections when handling a reload command. + Allow log messages to be captured by tincctl. + Merge branch 'master' of git://tinc-vpn.org/tinc into 1.1 + Allow CTR mode counter to be set to a specific value. + Add datagram mode to the SPTPS protocol. + Test SPTPS messages sent while key renegotation is in progress. + Don't send an ACK message after the first key exchange in the SPTPS protocol. + Start documenting the SPTPS protocol. + Make sure the signature also covers the session label. + Merge branch 'master' of git://tinc-vpn.org/tinc into 1.1 + Merge branch 'master' of git://tinc-vpn.org/tinc into 1.1 + Add autoconf checks for OpenSSL's elliptic curve functions. + Update README to reflect that only OpenSSL is currently supported. + Always pass request strings to other functions as const char *. + Don't forget to send a newline when forwarding requests. + Merge branch 'master' of git://tinc-vpn.org/tinc into 1.1 + Fix crash when handling the ALRM signal. + Use /dev/tap0 by default on FreeBSD and NetBSD when using Mode = switch. + Document how to load the tap driver on FreeBSD. + Update THANKS file. + Merge branch 'master' into 1.1 + "tincctl init" creates initial directory structure, tinc.conf and keypairs. + Put every command in its own function. + Allow configuration variables to be added/removed using tincctl. + Stricter checks for node names. + Add an easy way to edit a configuration file. + Have tincctl notify a running tincd of configuration file changes. + Fix tincctl start. + Let tincctl ignore tincd options, so they will be passed on. + Fix tincctl dump. + Move all functions related to subnet parsing to subnet_parse.c. + "tincctl info" gives more human readable information about nodes or subnets. + Give an error message when tincctl info cannot parse the given subnet or address. + Strip default subnet weight from output. + Add an easy way to export and import host configuration files. + When exporting configuration files, don't copy Name variables. + Put minor protocol version in connection options so other nodes can see it. + Use minor protocol version to determine whether to use ECDH key exchange between nodes. + Never remove items from cmdline_conf. + Split setup_myself() into two functions, one for reloading configuration. + Allow more configuration variables to be changed when reloading configuration. + Prefer routes with lower weight as long as they do not increase the number of hops. + Make sure tinc compiles on Windows. + Make sure sptps.h and info.h are in the tarball. + BSD make doesn't like $<. + Fix various compiler warnings. + Call event_init() after detaching. + Add some checks when changing configuration. + Add a newline to a configuration file if it is missing. + Have tincd and tincctl use the same method of determining netname. + Fix some compiler warnings. + Fix crash when no netname is specified. + Don't try to mkdir(CONFDIR) on Windows when there is a registry key for tinc. + Use backslashes on Windows. + Windows doesn't like quotes around "edit" when calling it through system(). + Fix exit code when installing tincd as a service on Windows. + tincctl init now also creates a template tinc-up script. + Have tinc-gui use same way of locating pidfile as tincd and tincctl. + Remove unused po/ directory. + Also clarify hostnames=[yes|no] in tinc.conf(5). + Merge branch 'master' into 1.1 + Use datagram SPTPS for packet exchange between nodes. + Remove unused #include. + Handle SPTPS datagrams in try_mac(). + Add Brandon Black's replay window code to SPTPS. + Use a status bit to track which nodes use SPTPS. + Try sending SIGTERM if we cannot connect to a tincd but we know its PID. + tincctl restart should work even if no tincd is running. + Add the ability to query configuration variables to tincctl. + Add missing configuration variables. + Stricter checks for netname and node names. + Update the documentation to encourage using "tincctl init" and "tincctl config". + Clear struct sptps before reusing it. + Have tincctl act as a shell when no command is given. + Optionally compress and/or strip Ethernet header from SPTPS packets. + Add readline completion for tincctl config and tincctl info. + Fork when using the "start" command in tincctl. + Make sure the top command can be used more than once in tincctl's shell. + Add bash completion script. + Fix segfault when using tincctl's shell without readline. + Quit when "exit" or "quit" commands are used in tincctl's shell. + Fix node name check for "connect" and "disconnect" commands. + Properly handle SPTPS packets with stripped Ethernet headers. + Remove some debug messages. + Remove newlines at end of log messages. + Add a simple hash table implementation. + Use hash tables to lookup owners of addresses. + Replace node_udp_tree with a hash table. + Ensure sptps_test compiles with -flto. + Attribution for Vil Brekin and some code style cleanups. + Don't ignore Makefile.am. + Fix typo in manpage. + Remove remnants of Ethertap and old TUNSETIFF ioctl(). + Keep last known address and time since reachability changed. + Let tincctl parse and format dumps. + Allow dumping either directed or undirected graphs. + Update documentation of the "dump graph" command. + Comment out old public/private keys when generating new ones. + Fix links in documentation. + Fix links in documenation. + Let the GUI handle the new dump format. + Fix column sorting, make all lists sortable. + Correctly add/remove outgoing connections when reloading configuration. + Make tincctl robust against dropped control connections. + Remove some debugging messages. + Attribution for Martin Schürrer. + Add strict checks to hex to binary conversions. + Merge branch 'master' into 1.1 + Fix not reading Port statement from host config file. + Remove unused function declaration. + Make sure sptps_test compiles without -flto. + Remove abort() call that accidentily sneaked into commit dd1b69e. + Libreadline might depend on libcurses. + Fix off-by-one error. + Improve starting/stopping tincd using tincctl. + Clear connection options and status fields in free_connection_partially(). + When terminating, keep control connections open until the end. + Useful error messages when writing to a meta connection fails. + Make datagram SPTPS key exchange more robust. + Handle packets encrypted via SPTPS that need to be forwarded via TCP. + Remove a debug message. + Fix warnings from cppcheck. + Refactor outgoing connection handling. + Replace the connection_tree with a connection_list. + C99 extravaganza. + Fix deleting connections from the connection list. + Remove unused variables, fix some #includes. + Clear Ethernet header when reading packets from a tun device. + Fix memory leaks found by valgrind. + Fix hash functions for keys whose size is not divisible by 4. + Try all known addresses of node during the PMTU discovery phase. + Fix whitespace. + Clear status and options fields of unreachable nodes. + Strip newline from incoming SPTPS requests. + Fix handling of initial datagram SPTPS packet. + Only log success of initial datagram SPTPS handshake. + Make sure the ReplayWindow option works for SPTPS as well. + Log more messages using logger(). + tincctl: add node colors and edge weight to graph dump. + Fix compile error on Windows. + Update copyright notices. + Fix a few compiler errors/warnings. + Releasing 1.1pre3. + +Sven-Haegar Koch (29): + Merge branch 'master' into 1.1 + Fixed 1.0 miss-merges + Add missing AC_CHECK_HEADERS([dirent.h]) to configure.in + Function flush_meta() does not exist anymore. + README.git: tinc 1.1 needs libevent + Demote all LOG_EMERG to LOG_ERR, spamming all xterms is bad. + Fixed metadata protokoll corruption on forwarded requests + Fixed error logging on "Input buffer full" condition. + Removed two newlines from the end of log messages which created empty lines. + Use same definition for xalloc_fail_func as is really used. + sparse fixup: error: dubious one-bit signed bitfield + sparse fixup: error: too many arguments for function send_key_changed + sparse fixup: warning: symbol '...' was not declared. Should it be static? + sparse fixup: warning: non-ANSI function declaration of function '...' + sparse fixup: warning: Using plain integer as NULL pointer + fgets() returns NULL on error, not < 0 + src/net_socket.c bind_to_address(): Use after free in error path. + do_outgoing_connection() may delete a failed connection, and the structure + sptps_stop(): clear pointers after free to avoid double free. + Remove confusing error message for failed reading in ECDSA keys. + ecdh & ecdsa: avoid some possible memory leaks in error conditions. + terminate_connection(): Avoid use-after-free and double-free for + terminate_connection(): only kill c->node->connection if it is pointing + free_connection_partially(): Avoid possible use-after-free for c->hischallenge + Label control connections for log output as "", not "". + terminate_connection(): delete non-outgoing (aka incoming) connections. + Silence SPTPS log messages, reduce them from DEBUG_ALWAYS to DEBUG_META. + free_connection_partially(): also reset remote protocol version infos + sptps.c: Add missing newline to log message. + +Scott Lamb (19): + Rename "event_t" to "tevent_t", along with associated functions. + A couple missed tevent things. + Convert to libevent. + Lots of svn:ignore entries + Revert to only requiring autoconf 2.59. + Refresh po/POTFILES.in. + Updated svn:ignores list for new symlinked sources and tincctl. + const correctness + Temporarily revert to old crypto code + Update documentation to match tincctl changes + Fix reload crash + Fancier protocol for control socket + Dump through control socket + Purge through the control socket + Alter debugging levels through control socket + Retry connections through control socket + Reload configuration through control socket + Coding style corrections + Use a control socket directory to restrict access + +Vilbrekin (5): + Basic patch for android cross-compilation. + Replace hard-code with new ScriptsInterpreter configuration property. + Add basic .gitignore file, cleaning (most) files generated by autotools. + Use __ANDROID__ define rather than dirty hard-code to allow android NDK cross-compilation. + Android cross-compilation instructions. + +Michael Tokarev (3): + don't mention reload twice in tincctl help + run tincd from the same directory as tincctl and pass all options to it + use execvp() not execve() in tincctl start + +Martin Schürrer (1): + Output details of encryption errors + +Mesar Hameed (1): + Minor clarification, tinc.conf hostnames=[yes|no] variable only resolves names for logging purposes. + +Version 1.0.19 June 25 2012 +------------------------------------------------------------------------ + +Guus Sliepen (14): + Support :: in IPv6 Subnets. + Remove newline from log message. + Add support for systemd style socket activation. + Allow environment variables to be used for Name. + Allow broadcast packets to be sent directly instead of via the MST. + Add basic support for SOCKS 4 and HTTP CONNECT proxies. + Add support for SOCKS 5 proxies. + Add support for proxying through an external command. + Document new proxy types. + Small fixes in proxy code. + #include on Windows. + Fix compiler warnings. + Fix crash when using Broadcast = direct. + Releasing 1.0.19. + +Anthony G. Basile (1): + configure.in: fix AC_ARG_ENABLE and AC_ARG_WITH + +Michael Tokarev (1): + add (errnum) in front of windows error messages + +Version 1.0.18 March 25 2012 +------------------------------------------------------------------------ + +Guus Sliepen (13): + Always try next Address when an outgoing connection fails to authenticate. + Allow a port to be specified in BindToAddress statements. + Add support for multicast communication with UML/QEMU/KVM. + Set default value of DecrementTTL to "no". + Add #ifdefs in case not all platforms support IPv4 and IPv6 multicast. + Allow scoped addresses to be used for IPv6 multicast socket. + Fix compiler warnings. + Fix return value type of vde_send(). + Fix some more compiler warnings. + Document OpenBSD "ifconfig link0" and Linux "ip tuntap" commands. + Fix return type of vde_recv() as well. + Mark DecrementTTL option experimental. + Releasing 1.0.18. + +Version 1.0.17 March 10 2012 +------------------------------------------------------------------------ + +Guus Sliepen (32): + Prevent read_rsa_public_key() from returning an uninitialized RSA structure. + Return false instead of void when there is an error. + Fix compilation of VDE and UML interfaces. + Add vde/device.c to the tarball. + Fix a few small memory leaks. + Allow linking with multiple device drivers. + Set FD_CLOEXEC flag on all sockets. + Allow multiple BindToAddress statements. + Merge branch 'master' of black:tinc + Send packets back using the same socket as they were received on. + Allow setting DeviceType to tun or tap on Linux. + Merge branch 'master' of black:tinc + Only compile raw socket code when it is supported on that platform. + Decrement TTL of incoming packets. + Don't bind outgoing TCP sockets anymore. + Rename connection_t *broadcast to everyone. + Allow disabling of broadcast packets. + Move initialization of char *priority up to prevent freeing an uninitialized pointer. + Document the command line flag -o and provide --option as well. + Fix a bug that caused tinc to ignore all but the last listening socket. + Fix check for raw socket support. + Pass index into listen_socket[] to handle_incoming_vpn_data(). + Add LocalDiscovery option which tries to detect peers on the local network. + Don't send ICMP Time Exceeded messages for other Time Exceeded messages. + Stricter checks against routing loops. + Only use broadcast at the start of the PMTU discovery phase. + Only log errors sending UDP packets when debug level >= 5. + Accept Subnets passed with the -o option when StrictSubnets = yes. + Add missing ICMP6 message type definitions. + Make sure disabling old RSA keys works on Windows. + Update copyright notices. + Releasing 1.0.17. + +Nick Hibma (1): + Add missing ICMP message type definitions. + +Version 1.0.16 July 23 2011 +------------------------------------------------------------------------ + +Guus Sliepen (4): + Make code to detect two nodes with the same Name less triggerhappy. + Flush output buffer in send_tcppacket(). + Use usleep() instead of sleep(), MinGW complained. + Releasing 1.0.16. + +Version 1.1pre2 July 17 2011 +------------------------------------------------------------------------ + +Guus Sliepen (54): + Ensure the right files end up in the tarball after make dist. + Thank Scott Lamb, Sven-Haegar Koch and Loïc Grenié in the NEWS file. + Merge Tinc.py into tinc-gui to simplify make install. + Re-add support for SIGALRM. + Don't call exit_control() if we didn't do init_control(). + Rename controlcookie file to pidfile. + Make pid files backwards compatible and add address of listening socket. + Add +git to the version string. + Really stable sorting of tincctl top output. + Use pidfile in tinc-gui as well. + Don't react to escape character in tincctl top. + Update documentation to mention pidfiles instead of controlcookies. + Remove debug messages that were printed to stdout. + Add manpage for tinc-gui. + Preliminary implementation of Elliptic Curve Diffie-Hellman Ephemeral key exchange. + Support ECDH key exchange. + Add PRF to derive key material from the ECDH shared secret. + Use PRF. + Proper use of PRF. + No need to keep around pointers to EC_GROUP. + Cleanups in ECDH code. + Base64 encoding and decoding functions. + Add ECDSA key generation. + Have tincctl generate ECDSA keys. + Finish base64 decoding routine. + Add ECDSA key import. + Round up the size of the secret parts after splitting it in two. + Add a minor number to the protocol version. + Bump minor protocol to indicate ECDH capability for UDP session keys. + Implement ECDSA sign and verify operations. + Read ECDSA keys. + Very primitive ECDSA signed ECDH key exchange for the meta protocol. + Hash input before signing it with ECDSA. + Free ECDSA and RSA structures when freeing a connection_t. + Automatically exchange ECDSA keys and upgrade to new authentication protocol. + Close meta connection socket after cleaning up event structures. + Require ExperimentalProtocol = yes for new features, update documentation. + Don't use wildcards in filenames in configure.in. + Make hexadecimal and base64 routines behave the same. + Make use of the improved hex and base64 functions. + Remove unnecessary variables and functions. + Fix compiler warnings. + Use the correct direction flag when setting cipher keys. + Use the same logic as tinc 1.0.x for detecting two nodes with the same Name. + Use ECDSA to sign ECDH key exchange for UDP session keys. + Update info manual. + Use usleep() instead of sleep(), MinGW complained. + Use const pointer to source in base64 and hex routines. + Ensure symlinked files do not end up in the tarball. + Fix declaration of usleep(). + "tincctl stop" now removes the tinc service on Windows. + Write loopback address instead of "any" address in pidfile. + Add missing newline. + Releasing 1.1pre2. + +Version 1.1pre1 June 25 2011 +------------------------------------------------------------------------ + +Guus Sliepen (164): + Created the 1.1 branch where large code changes can take place, + Only free members of connection_t that have been allocated. + Port fixes from release 1.0.8. + Properly delete listener socket events on shutdown. + 128 listener sockets is way too much. + Use a separate event structure to handle meta data writes. + Use libevent to dump graphs when necessary. + Use libevent to handle HUP signal. + Configure events after obtaining a socket. + Use libevent to send MTU probes. + Use libevent for retrying outgoing connections. + Remove legacy event system. + Properly use the timeout_initialized() macro. + Use libevent to handle all non-fatal signals. + Redo SIGALRM handling. + Use libevent to age past requests. + Use libevent to age learned MAC addresses. + Use libevent to handle key expiration. + Move key regeneration handling to net_setup.c. + Remove global variable "now". + Remove the last bits of the legacy main_loop(). + Remove last references to the global variable "running". + K&R style braces + Use splay trees instead of AVL trees. + Detect duplicate outgoing connections. + More consistent variable naming. + Show branch version number. + Update documentation. + Start of control socket implementation. + We can safely delete a connection_t in terminate_connection() now. + Fix retrying outgoing connections. + Remove pidfile in favour of control socket. + Move key generation to tincctl. + Implement "stop" command, and allow tincctl to retrieve a running tincd's PID. + Use bufferevents to handle control socket buffering. + Use libevent for meta socket input/output buffering. + Parse PEM RSA keys ourself, and use libgcrypt to do RSA encryption and decryption. + Create wrappers for the cryptographic operations used in tinc. + Make sure the crypto wrapper functions can actually be compiled. + Some more crypto wrapper functions are needed. + Finish crypto wrapping. Also provide wrappers for OpenSSL. + Only check for libgcrypt if --with-gcrypt is used. + Fix formatting of --help output. + Small fixes to make gcrypt routines compile. + Apply patch from Scott Lamb: Update documentation to match tincctl changes + Fix connection weight estimation. + Use a dummy function as the read callback for connection bufferevents. Should not be triggered. + Fix meta data segfault when receiving a partial command. + Prevent double free() of a used challenge nonce. + Look in the configured sbin directory for the tincd binary. + Only show meta connection related debug messages when debug level >= 4 + Move AC_GNU_SOURCE up to make autoconf happy. + Use the crypto wrappers again instead of calling OpenSSL directly. + Backport fixes from trunk since revision 1555. + Fix compiler warnings. + Remove unnecessary parentheses from sizeof, apply sizeof to variables instead of types whereever possible. + Remove wrong checks. + Use Dijkstra's algorithm. Based on patches from Max Rijevskiy. + Make sure IPv6 sockets are IPv6 only. + Move RSA key generation into the wrappers. + Merge branch 'master' into 1.1 + Merge branch 'master' into 1.1 + Handle truncated message authentication codes. + Fix pointer arithmetic when creating and verifying message authentication codes. + Merge branch 'master' into 1.1 + Add missing #include. + Use correct format specifiers. + Replace asprintf()s not covered by the merge to xasprintf(). + Add a better autoconf check for libevent. + Merge branch 'master' into 1.1 + Drop localisation and checkpoint tracing in files not covered by the merge. + Update FSF address in files not covered by the merge. + Merge branch 'master' into 1.1 + Don't enable device events when there is no valid filedescriptor. + Use %x instead of %lx where appropriate. + Handle truncated message authentication codes with gcrypt. + Handle PKCS#5 padding in the gcrypt backend. + Make sure the 1.1 branch compiles in a MinGW environment. + Better integration of libevent in build system. + Small fixes to get really working control sockets on Windows. + Use the TCP socket infrastructure for control sockets. + Only call ioctlsocket() on Windows. + Merge branch 'master' into 1.1 + Fix compiler warnings. + Do not include OpenSSL headers directly. + Include missing header files and source directories. + Allow connections to be closed. + Start of a GUI for tinc. + Fix packet authentication. + Fix block cipher padding when using libgcrypt. + Reinitialise block cipher IV each time we encrypt a packet when using libgcrypt. + Fix reading raw RSA keys with libgcrypt. + recv() and recvfrom() return int, do not prematurely cast the return value. + Do not consider unreachable nodes when trying to determine packet origin. + Fix alignment of results of RSA operations when using libgcrypt. + Do not use hardcoded cipher block length when padding. + Remove unused AVL tree library. + Move source from lib/ to src/. + Fix experimental GUI when reading hexadecimal values. + Merge branch 'master' into 1.1 + Fix merge of commit 4a0b9981513059755b9fd15b38fc198f46a0d6f2. + Add missing return statement. + Use correct digest length when checking a received key. + Do not try to free NULL pointers. + Remove obsolete lib/ directory. + Merge branch 'master' into 1.1 + Link tincctl with dropin.o. + Merge branch 'master' into 1.1 + Do not try to dereference myself->connection->config_tree. + Merge branch 'master' of git://tinc-vpn.org/tinc into 1.1 + Fix check for event initialization due to the merge. + Add simple buffer management code. + Remove use of bufferevent and eventbuffers, use our own buffering instead. + Several fixes for the buffer code. + Add per-node traffic counters. + Dump traffic statistics over control sockets. + Add an autoconf check for the curses library. + Add a very primitive "top" command to tincctl. + Allow inserting items in the middle of a list. + Nicer top command. + Add tincctl.h. + Add top.h. + Use GetItemCount() on ListCtrls instead of directly accessing ItemCount. + Fix some compiler warnings. + Compact input buffer before trying to read instead of after. + Always compact the buffer if it has reached MAXBUFSIZE. + Check if an event is initialized before calling event_del(). + Reset tcplen after use. + Add the ability to dump all traffic going through route() over a control connection. + Allow tincctl to connect to something besides localhost. + Show hostname and port in error message when connecting to a running tincd. + Cosmetic fix when pressing 's' in tincctl top. + Initialise priority field to zero for packets read from the VPN interface. + Remove outgoing event in free_connection(). + Simplify signal handling. + Drop the GNU malloc.c, realloc.c, and xmalloc.c. + Drop the GNU memcmp.c implementation. + Don't #include anymore. + Remove unused functions and variables. + Remove support for the Ethertap device. + Fix some compiler and cppcheck warnings. + More stable sorting in tincctl top. + Make traffic statistics more readable with configurable scaling. + Fix nodes joining the VPN after tincctl top started. + Don't treat packets coming in via TCP as having zero length. + Remove debugging message that was accidentily left in. + Even simpler signal handling. + Small fixes for Windows. + Use send() when writing to sockets, and the return type is ssize_t. + Fix format strings for Windows. + Don't ignore SIGCHLD, system() needs it. + Clean up digests when freeing a connection_t. + Merge branch 'master' of git://tinc-vpn.org/tinc into 1.1 + Reopen log file after SIGHUP. + Only log UDP address changes at the appropriate debug levels. + No need to check for pselect() in tinc 1.1. + Merge branch 'master' of git://tinc-vpn.org/tinc into 1.1 + Delete mtuevent if it is not used. + Don't call event_del() from the mtuevent handler, always send_mtu_probe() in ans_key_h(). + Don't use AM_CONDITIONAL for CURSES. + Add Makefile.am in gui/. + Update manpages and info manual. + Ensure that the texinfo manual can be converted to HTML. + Releasing 1.1pre1. + +Scott Lamb (19): + Rename "event_t" to "tevent_t", along with associated functions. + A couple missed tevent things. + Convert to libevent. + Lots of svn:ignore entries + Revert to only requiring autoconf 2.59. + Refresh po/POTFILES.in. + Updated svn:ignores list for new symlinked sources and tincctl. + const correctness + Temporarily revert to old crypto code + Update documentation to match tincctl changes + Fix reload crash + Fancier protocol for control socket + Dump through control socket + Purge through the control socket + Alter debugging levels through control socket + Retry connections through control socket + Reload configuration through control socket + Coding style corrections + Use a control socket directory to restrict access + +Sven-Haegar Koch (18): + Merge branch 'master' into 1.1 + Fixed 1.0 miss-merges + Add missing AC_CHECK_HEADERS([dirent.h]) to configure.in + Function flush_meta() does not exist anymore. + README.git: tinc 1.1 needs libevent + Demote all LOG_EMERG to LOG_ERR, spamming all xterms is bad. + Fixed metadata protokoll corruption on forwarded requests + Fixed error logging on "Input buffer full" condition. + Removed two newlines from the end of log messages which created empty lines. + Use same definition for xalloc_fail_func as is really used. + sparse fixup: error: dubious one-bit signed bitfield + sparse fixup: error: too many arguments for function send_key_changed + sparse fixup: warning: symbol '...' was not declared. Should it be static? + sparse fixup: warning: non-ANSI function declaration of function '...' + sparse fixup: warning: Using plain integer as NULL pointer + fgets() returns NULL on error, not < 0 + src/net_socket.c bind_to_address(): Use after free in error path. + do_outgoing_connection() may delete a failed connection, and the structure + +Version 1.0.15 June 24 2011 +------------------------------------------------------------------------ + +Guus Sliepen (9): + Reorder checks for libraries to allow ./configure LDFLAGS=-static. + Make return value of SetPriorityClass() behave the same as setpriority(). + Fix sparse warnings and add an extra sprinkling of const. + Remove newlines from log messages. + Remove a few unnecessary #includes. + Attribution for Loïc Grenié. + Improved --logfile option. + Remove redundant @CFLAGS@ from AM_CFLAGS. + Releasing 1.0.15. + +Loïc Grenié (1): + Nearly tickless tinc. + +Version 1.0.14 May 08 2011 +------------------------------------------------------------------------ + +Guus Sliepen (48): + Fix reading configuration files that do not end with a newline. Again. + Define WINVER before including any other header file on Windows. + Use intptr_t instead of long to store a pointer. + OpenSSL 1.0.0 compiled for 64 bit Windows requires linking with -lcrypt32. + Fix all warnings when compiling with mingw64. + Use strrchr() insteaad of rindex(). + Detect and prevent two nodes with the same Name being on the VPN simultaneously. + Use 64 bit counters to keep track of bytes sent/received from the virtual network interface. + Do not append an address to ANS_KEY messages if we don't know any address. + Merge local host configuration with server configuration. + Remove duplicate command-line option parsing. + Attribution for Julien Muchembled. + Attribution for Timothy Redaelli. + Ensure there is a newline character before a PEM key is written. + Abort disabling old PEM keys on I/O errors. + Remove unused variables. + Quit when there are too many consecutive errors on the tun/tap device. + Read error counter must be static. + Add short options -R and -U to the tincd(8) manpage. + Don't use strlen() on a NULL pointer. + Provide usleep() for Windows. + Use variable length arrays instead of alloca(). + Fix warning message when setting SO_RCVBUF or SO_SNDBUF fails. + Free replay window when freeing a node_t. + Fix variable length array declaration. + Attribution for Brandon Black. + Use setpriority() instead of nice() on UNIX-like systems. + Always send MTU probes at least once every PingInterval. + Close all filedescriptors in Solaris close_device(). + Limit field width when scanning PID file. + Replace bogus #else with #endif. + Remove unused variables. + Document the behavior of "-n." + Update the manual. + Update the NEWS. + Proper check and dropin replacement for usleep(). + Fix typo spotted by Andrew Scheller. + Add support for VDE through libvdeplug. + Fix spurious misidentification of incoming UDP packets. + Prevent anything from updating our own UDP address. + Do not set indirect flag on edges from nodes with multiple addresses. + Increase threshold for detecting two nodes with the same Name. + Always use the default signal handler for ABRT signals. + Check for EVP_EncryptInit_ex instead of SHA1_Version in OpenSSL. + Update THANKS and copyright information. + Ensure proper linking with OpenSSL with recent versions of MinGW. + Include when using intptr_t. + Releasing 1.0.14. + +Brandon L Black (4): + Experimental IFF_ONE_QUEUE support for Linux + Configurable SO_RCVBUF/SO_SNDBUF for the UDP socket + Configurable ReplayWindow size, zero disables + Improved handling of queue-jumping packets on receive + +Julien Muchembled (2): + New '-o' option to configure server or hosts from command line + Fix command-line '-o' option for host configuration + +Timothy Redaelli (2): + Fix warnings showed using -D_FORTIFY_SOURCE=2 + Fix warnings under BSD + +Michael Tokarev (1): + Treat netname="." in a special way. + +Rumko (1): + DragonFlyBSD support + +Version 1.0.13 April 11 2010 +------------------------------------------------------------------------ + +Guus Sliepen (20): + Clamp MSS to miminum MTU in both directions. + Simplify reading lines from configuration files. + Check for dirent.h. + Preload all Subnets in TunnelServer mode. + Add the StrictSubnets option. + Add the Forwarding option. + Add the DirectOnly option. + Fixes for the Forwarding option. + ConnectTo does not mean tinc does not listen for incoming connections anymore. + Log unauthorized Subnets when StrictSubnets is set. + Fix typo. + Convert Port to numeric form before sending it to other nodes. + Ensure ICMP_NET_ANO is defined. + Reload Subnets when getting a HUP signal and StrictSubnets is used. + Fix reloading Subnets when StrictSubnets is set. + Ensure subnet-up/down scripts are called after HUP when necessary. + Fixes for definitions under Windows. + Don't redefine MAX if it already exists. + Mark Forwarding and DirectOnly options as being experimental. + Releasing 1.0.13. + +Timothy Redaelli (2): + Add --disable-lzo configure option + Add --disable-zlib configure option + +Sven-Haegar Koch (1): + Never delete Subnets when StrictSubnets is set + +Version 1.0.12 February 03 2010 +------------------------------------------------------------------------ + +Guus Sliepen (21): + When learning MAC addresses, only check our own Subnets for previous entries. + Remove unused variable in lookup_subnet_*() functions. + Forget addresses of unreachable nodes. + Do not fragment packets smaller than RFC defined minimum MTUs. + Allow port to be specified in Address statements. + Use xstrdup() instead of xasprintf() to copy static strings. + Allow Port and PMTUDiscovery options in tinc.conf, always enable PMTUDiscovery by default. + Clamp MSS of IPv4 SYN packets. + Ping nodes immediately when receiving SIGALRM. + Optimise handling of select() returning <= 0. + Also clamp MSS of TCP over IPv6 packets. + Make MSS clamping configurable, but enabled by default. + Fix subnet-up/down scripts being called with an empty SUBNET. + Run subnet-up/down scripts for local MAC addresses as well. + Be liberal in accepting KEY_CHANGED/REQ_KEY/ANS_KEY requests. + Determine peer's reflexive address and port when exchanging keys. + Immediately exchange keys when establishing a meta connection. + Try to set DF bit on BSDs as well. + Update copyright notices. + Ensure peers with a meta connection always have our key. + Releasing 1.0.12. + +Version 1.0.11 November 01 2009 +------------------------------------------------------------------------ + +Guus Sliepen (16): + Fix a possible crash when sending the HUP signal. + Starting to work towards 1.0.11. + Handle weighted Subnets in switch and hub modes. + Clarify and increase level of log message about MTU probes to unreachable nodes. + Add dummy device. + Use uint32_t instead of long int for connection options. + Allow UDP packets with an address different from the corresponding TCP connection. + Always reply to MTU probes via UDP. + Make maxmtu equal to minmtu when fixing the path MTU to a node. + Forward packets to not directly reachable hosts via UDP if possible. + Use IP_DONTFRAGMENT instead of IP_MTU_DISCOVER on Windows. + Use WSAGetLastError() to determine cause of network errors on Windows. + Move socket error interpretation to utils.h. + Fast handoff of roaming MAC addresses. + Start a tinc service if it already exists. + Releasing 1.0.11. + +Michael Tokarev (1): + Remove localedir leftovers. + +Version 1.0.10 October 18 2009 +------------------------------------------------------------------------ + +Guus Sliepen (78): + Update documentation for git. + Consistently allocate device and iface variables on the heap. + Only send packets via UDP if UDP communication is possible. + Move free()s at the end om main() to the proper destructor functions. + Change flush_events() to expire_events(). + Add missing cleanup functions in close_network_connections(). + Use a global list to track outgoing connections. + Remove unused definitions from net.h. + Allow reading config files with CRLF endings on Unix systems. + Validate Name before using it in a filename when generating a keypair. + Disable old RSA keys when generating new ones. + Handle neighbor solicitation requests without link layer addresses. + Allow weight to be assigned to Subnets. + Update THANKS and copyright information. + Disable PMTUDiscovery in switch and hub modes. + Use a simple Random Early Drop algorithm in send_tcppacket(). + Handle UDP packets from different and ports than advertised. + If PMTUDiscovery is not set, do not forward packets via TCP unnecessarily. + Fix link to Mattias Nissler's tun/tap driver for MacOS/X. + Fix initialisation of packet decryption context broken by commit 3308d13e7e3bf20cfeaf6f2ab17228a9820cea66. + Use xrealloc instead of if(ptr) ptr = xmalloc(). + Add declaration for sockaddrcmp_noport(). + Use packet size before decompression to calculate path MTU. + Do not forward broadcast packets when TunnelServer is enabled. + Add ProcessPriority option. + Add some const where appropriate. + Properly set HMAC length for incoming packets. + Don't try to send MTU probes to unreachable nodes. + Remove pending MTU probe events when a node's reachability status changes. + Do not log errors when recvfrom() returns EAGAIN or EINTR. + Change level of some debug messages, zero pointer after freeing hostname. + Always remove a node from the UDP tree before freeing it. + Add xasprintf() and xvasprintf(). + Check the return value of fscanf() when reading a PID file. + Replace asprintf() by xasprintf(). + UNIX signal numbers start at 1. + Ensure tinc compiles with gcc -std=c99. + Convert bitfields to integers in a safe way. + Add the GPL license to the repository. + Another safe bitfield conversion. + Add support for iPhones and recent iPods. + Don't stat() on iPhone/iPod. + Put Subnet weight in a separate environment variable. + Allow PMTUDiscovery in switch and hub modes again. + Handle unicast packets larger than PMTU in switch mode. + Remove superfluous call to avl_delete(). + Apparently it's impolite to ask GCC to subtract two pointers. + Use only rand(), not random(). + Also do not use drand48(), it is not available on Windows. + Allow compiling for Windows XP and higher. + Remove dropin random() function, as it is not used anymore. + Use access() instead of stat() for checking whether scripts exist. + Raise default crypto algorithms to AES256 and SHA256. + Remove extra {. + Use a mutex to allow the TAP reader to process packets faster on Windows. + Raise default RSA key length to 2048 bits. + Send large packets we cannot handle properly via TCP. + Update copyright information. + Remove all occurences of $Id$. + Remove Ivo's old email addresses. + Update the address of the Free Software Foundation in all copyright headers. + K&R style braces. + Remove checkpoint tracing. + Drop support for localisation. + Add more authors to the copyright headers. + Update the NEWS. + Remove autogenerated files from EXTRA_DIST. + Don't disconnect clients in TunnelServer mode who send unauthorised ADD_SUBNETs. + Remove code duplication when checking ADD_EDGE/DEL_EDGE messages. + Revert "Raise default crypto algorithms to AES256 and SHA256." + Ensure that the texinfo manual can be converted to HTML. + Small updates to the documentation. + Use MTU probes to regularly ping other nodes over UDP. + Allow the cloning /dev/tap interface to be used on FreeBSD and NetBSD. + Remove debugging message when reading packets from a BSD device. + Include missing header. + Fix description of the WEIGHT environment variable. + Releasing 1.0.10. + +Michael Tokarev (17): + Allow tunnelserver to work with clients that have other peers. + Enable PMTUDiscovery only if BOTH sides wants it. + Rename setup_network_connections() and split out try_outgoing_connections() + Implement privilege dropping + bugfix: initialize pid (as read from pidfile) to zero + bugfix: move mlock to after detach() so it works for child, not parent + bugfix: chdir(/) after chroot + change error messages in droppriv code to match the rest + format 'not supported on this platform' error message + TunnelServer: Don't disconnect client on DEL_SUBNET too + ignore indirect edge registrations in tunnelserver mode + don't log every strange packet coming to the UDP port + Fix ans_key exchange in recent changes + tunnelserver: log which ADD_SUBNET was refused + cleanup setpriority thing to make it readable + try outgoing connections before chroot/drop_privs + Remove extra semicolon in my definition of setpriority() + +Florian Forster (2): + src/linux/device.c: Fix segfault when running without `--net'. + src/net_socket.c: Bind outgoing TCP sockets to `BindToAddress'. + +Borg (1): + Removed last gettext function. + +Version 1.0.9 December 26 2008 +------------------------------------------------------------------------ + +Guus Sliepen (18): + Handle SERVICE_CONTROL_INTERROGATE requests. Thanks to Carsten Ralle for noticing this. + Make sure the prefixlength of subnets is sane. + Fix reading configuration files that do not end with a newline. + Do not try to send REQ_KEY or ANS_KEY requests to unreachable nodes. + Prevent freeing a NULL pointer when a hostname is unresolvable. + Correct debug message. + Treat virtual network device as tap if Mode = switch or hub. + Use TUNIFHEAD by default on FreeBSD to make sure IPv6 works. + Make sure IPv6 sockets are IPv6 only. + Update Dutch translation. + Update copyright information. + Enable PMTU discovery by default. + Update documentation. + Update the manpage as well, and some whitespace to make its source more legible. + Handle broadcast and multicast packets in router mode. + Apply patch from Max Rijevski fixing a memory leak when closing connections. + Add missing parentheses in check for IPv4 multicast addresses. + Releasing 1.0.9. + +Version 1.0.8 May 16 2007 +------------------------------------------------------------------------ + +Guus Sliepen (8): + Apply patch from Scott Lamb preventing an infinite loop when sending SIGALRM. + Apply patch from Scott Lamb fixing some memory and resource leaks. + Close the proper filedescriptor (if it exists). + Apply patch from "dnk" making sockets non-blocking under Windows. + Make sure connection->name is never NULL. + Update dutch translation. + Don't free struct addrinfo too early. Spotted by Christian Cier-Zniewski. + Releasing 1.0.8. + +Version 1.0.7 January 05 2007 +------------------------------------------------------------------------ + +Guus Sliepen (7): + Use a ringbuffer in shared memory to transfer packets from the tapreader thread to the main thread. + Tapreader socket should be bound to localhost only. + Fix generic BSD tun device to write only the actual packet length. + rename() cannot replace existing files on Windows. + No things to do for the 1.0 branch except bugfixing. + Update copyright notices. + Releasing 1.0.7. + +Version 1.0.6 December 18 2006 +------------------------------------------------------------------------ + +Guus Sliepen (13): + Make sure resolved addressed for outgoing connections are freed, if there are any. + Search for lzo/lzo1x.h, lzo2/lzo1x.h and lzo1x.h. + When building the minimum spanning tree, make sure we start from a reachable node. + Use the correct next pointer. + Remove unnecessary stuff from configure.in. + Remove old Spanish translation. + Fix rule that creates html version of manpages. + Use standard autoconf macros instead of our own. + We do properly check for malloc and realloc. + Remove the test for linux/if_tun.h. + Do a simple test for linux/if_tun.h instead of no test at all. + Prevent compiler warnings about redefinition of EAI_FAMILY on FreeBSD 6.1. + Releasing 1.0.6. + +Version 1.0.5 November 14 2006 +------------------------------------------------------------------------ + +Guus Sliepen (32): + Prevent possible buffer overflows when using very large (>= 8192 bit) RSA keys. + Add alloca.h to the list of necessary header files. + Enable OpenSSL ENGINE, so crypto hardware gets used. Thanks to Andreas van Cranenburgh. + EVP_Cleanup() when quitting. + Apply patch from Scott Lamb unifying configuration of TCP socket options. + Apply patch from Scott Lamb adding an output buffer for the TCP sockets. + Make sure $NAME is set correctly when executing tinc-down script. + Missing #include. + Export flush_meta(). + Fix signedness compiler warnings. + Fix a bug in handling prefixlengths that are not a multiple of 4. + Update copyright notices, remove Ivo's email address. + Restore length of the original packet in send_udppacket(). + Use memcpy() to copy sockaddrs returned by getaddrinfo(). + Add generic host-up and host-down scripts. + Do not break strict aliasing of status_t structs. + Fix format string warnings. + Remove unused variables. + Remove unused parameter from maskcmp(). + Remove unused variable. + memcpy() addresses from packet headers before calling the lookup functions. + The "active" bit in node.status is not used. + Added graph dumping ability based on Markus Goetz's patch. + popen() requires pclose(). + Support and autodetect LZO version 2.0 and later. + Support and autodetect LZO version 2.0 and later. + Document GraphDumpFile option. + Update Dutch translation. + Nodes use events, so event system should be initialised first and destroyed last. + When deleting an entire tree, start at head, not at root. + EWOULDBLOCK does not exist on platforms without O_NONBLOCK + Releasing 1.0.5. + +Version 1.0.4 May 04 2005 +------------------------------------------------------------------------ + +Guus Sliepen (17): + Make sure broadcast packet reach the local network interface. + Fix splay tree code. + subnet-up/down hooks + subnet-up/down hooks, use list_t for the todo list. + Small fix. + Free memory used by connection_t after it is deleted from the connection tree. + Use the proper free function. + Correct size argument for strncat(). + Nodes should only be in the node_udp_tree if they are reachable. + Don't try to add a non-existing node back to the node_udp_tree. + Remove unused (and potentially segfaulting) net2str() call. + Be on the safe side with initialisation of c->name. + Searching through splay trees may change the tree variable. + Several splay tree fixes. + Describe subnet-up/down scripts in documentation. + Update copyright notices. + Releasing 1.0.4. + +Version 1.0.3 November 11 2004 +------------------------------------------------------------------------ + +Guus Sliepen (77): + Removed items in TODO list that are already implemented. Only two items + Applied patch from Jamie Briggs for bash2 conformance. + Added another semicolon for bash2 compliance (thanks to Jamie Briggs) + Adding even more stuff from the CABAL branch. + Synchronise HEAD with CABAL branch. + This will become 2.0. + Some device.c files weren't synchronised. + Makevars file was accidentily removed. + Forgot to synchronise po/ directory... + Add description of new authentication scheme. + Add Opaque option which prevent information from being forwarded to certain nodes. + Replace Opaque and Strict options with a TunnelServer option. + Complain if pid file cannot be created. + Read MaxTimeout from tinc.conf like the manpage says. + Missing space between words. + Don't retry if configuration is wrong from the beginning. + Fix proxy-neighborsolicitation. + Code beautification, start of multicast support. + Forget multicast. Always inline some function. + Let tinc figure out the exact MTU of the link. + More sensible name, and try to set PMTU discovery on IPv6 sockets as well. + Describe the TunnelServer and PMTUDiscovery options. + Better name, show probed MTU in dump. + Improvements for PMTU discovery and IPv4 packet fragmentation. + Missing definitions. + Small fixes for PMTU discovery. + Don't forget to update destination MAC address. + Small updates. + Remove autogen.sh, the autoreconf program does exactly that. + Replace cvs-clean with a much better svn-clean. + Remove CVS related cruft. + Eat trailing whitespace in config files. + Only read our public key if it wasn't already in the private key file. + Updating dutch translation. + Even better svn-clean command. + Applied Martin Kihlgren's IdentityGenerosity patch, + Fix declaration of update_node_address(). + Use Subversion to create ChangeLog, better svn-clean rule. + Revert Martin Kihlgren's patch, it doesn't work the way it should. + Move CABAL branch to its rightful place: the trunk. + Update copyrights, links, email addresses and let Subversion update $Id$ keywords. + Increase MTU by 4 bytes to allow VLAN tagged Ethernet frames in hub and switch mode. + Clean up environment after executing scripts. + Handle timeouts during connecting the same way as other errors. + Added UML network socket handling. + Don't set $INTERFACE automatically, don't quit on EINTR/EAGAIN. + Marking potential late packets was in the wrong place. + Remove duplicate #include "system.h" + Move all #ifdef HAVE_HEADER_H #include to have.h, + Fix several #includes. + strndupa() is too arcane for some environments. + Allow tinc to work with the latest TAP-Win32 driver. + Correct return value. + Don't let tinc service depend on NDIS component. + Support alternative tun/tap driver from http://www-user.rhrk.uni-kl.de/~nissler/tuntap/ + Generic device driver for *BSD and MacOS/X + static + Check for sys/uio.h, net/if_tun.h and net/if_tap.h + Don't include .svn directory in sample configuration. + Splay trees. + Hoopjumping to get the default directories in the manuals properly. + Update to make it compile again. + Fixed another bug in late packet handling. + Hopefully this really fixes late packet handling. + Missing check for NULL-pointer. + Use the generic BSD tun/tap code. + Fix order of arguments for tar. + Let compiler decide when to inline. + Support tunneling IPv6 on Solaris. + Add BlockingTCP option, useful when using TCPOnly on slow or congested links. + Update documentation. + Set BSD tuns to broadcast mode. On OpenBSD, this enables IPv6 on the tun device! + Remove duplication. + Updated dutch translation. + Short readme about how to compile tinc from a Subversion checkout. + Add more people who have contributed to tinc. + Releasing 1.0.3. + +Ivo Timmermans (52): + Check for __gmpz_powm for libgmp3. + Changed version number to 1.0pre3. + Autogenerated by gettextize. + Bring head revision up to date with cabal (try #3) + Add check for the syslog function + Generalized error handling functions + Add all the new files to the sources list for the utility library + New function: xalloc_and_zero() + Generalized list and hash handling functions + First try to create a graphical frontend for tinc configuration + Updating HEAD branch #1; removing obsolete files. + Updating HEAD branch #2; removing debian/ dir. + Updating HEAD branch #3; more obsolete files removed. + Updating HEAD branch #4; Merging CABAL -> HEAD. + Updating HEAD branch #5; Last files from CABAL. + Ok, I forgot these ;) + More updates + More... + Last bits (hopefully) + Main pokey interface files. + Pokey interface definition + Write src/pokey/Makefile + Also compile in pokey/ + Remove debug level declaration + Update copyright info + Remove debug_lvl + New logging system to replace syslog() calls with a generic function. + Rename log_message to log + Add syslog() wrapper + Add syslog wrapper + Some magic + Added priority definitions from syslog.h + log_default_hook was renamed to log_default + Added prototype for log_syslog + Use logging.h instead of syslog.h + Compile in logging.c + Things to ignore... + Use new logging system + Include logging.h + Renamed libvpn to libtinc + Rename libvpn to libtinc + ... + Print newline when writing to stderr + *** empty log message *** + Moving files, first attempt at gcrypt compatibility, more interface + Commit diff test + Another file moved; random interface stuff. + Callbacks + Moved event.c/h + test + test 2 + Hm. + +Wessel Dankers (5): + Initial revision. Lots of loose ends, not usable yet. + added bit on config file, split up sections, added Id: tag + Added extra bit about keys. + More about keys + This file is now only in the CABAL revision. + +cvs2svn (1): + This commit was generated by cvs2svn to compensate for changes in r1352, + +Version 1.0.2 November 08 2003 +------------------------------------------------------------------------ + +Guus Sliepen (47): + Simplify fake getname/addrinfo() functions, possibly fixing freeing a NULL pointer. + stat() batch files under Windows. + Don't getsockopt() SO_ERROR. We get the error from send()/recv() anyway. + Fix fake getnameinfo() and check more arguments. + Fix --logfile under Windows. + Use the event log under Windows. + Compilation fix. + Do what the SDK documentation tells. + If we're not in main_loop() and the service is stopped, exit immediately. + Allow tinc to handle unknown type addresses from other tinc daemons. + Don't overwrite the first " when installing a service. + Add checkpoints. + When purging nodes, only delete them if nobody references them anymore. + Remove debug message. + Add license exception from Markus Oberhumer. + Remove old edges from unreachable nodes to us. This prevents the hosts/NAME-up + We don't have to tell GCC how to cast. + Prevent multiple inclusions. + Remove pidfile when exitting. + Update translations. + Check for short packets from the tun/tap device and from other tinc daemons. + Generate keys with 0x10001 as public exponent, which has less prime factors + Better length checks. + Copy structs from packets to the stack before using them, to prevent + const + Ethernet protocol types. + Unused variable in struct. + Don't confuse users with "Address family not supported" warnings. + Use CPPFLAGS, LDFLAGS and LIBS as appropiate. + PIDs are of type pid_t, and use %ld when reading/writing them to the pidfile. + Make sure type of AF_UNKNOWN is sa_family_t. + Forgot to #include "xalloc.h" + Update missing definitions, structs describing headers get __packed__ attribute. + Missing declaration. + Set media status for newer TAP-Win32 driver. + Some platforms don't know sa_family_t or define it other than uint16_t. + Update documentation. + Fix ASCII art. + Check return value of EVP_* functions, and check if length before en/decryption + Check all EVP_ function calls. + Parentheses in the wrong spots. + Fix bug that could lead to an assertion failure in libcrypto when multiple + Small fixes in documentation. + Fix another bug in meta.c. + Update dutch translation. + Add missing definitions. + Release notes for 1.0.2 + +Version 1.0.1 August 14 2003 +------------------------------------------------------------------------ + +Guus Sliepen (24): + Windows uses backslashes... + Tell windows to be patient. + Remove unused stuff from doc/. + Correct error message when remote host closed connection. + Simplify execute_script(). It will probably work under Windows as well. + Allow empty lines in config files. + Make rule for sample-config.tar.gz. + Readd quotes. + Typo. + Better error messages under Windows. + Log error first, try to close later. + Quote when needed and don't try stuff that doesn't work under Windows. + Under Windows, the installation directory can be found in the registry. + Better error checking and reporting. + Small things. + Simpler checking of permissions on private RSA key and other fixes. + Check for fchmod(). + Only system() needs script name quoted. + Update documentation. + Add a description for the Service control panel. + Updated dutch translation. + Small fixes. + Fix permissions check for rsa_key.priv. + Update. + +Version 1.0 August 08 2003 +------------------------------------------------------------------------ + +Guus Sliepen (111): + Thank some more people. + Run graph() after edge_del() when updating an edge. + Add documentation for BindToAddress. + Fix PriorityInheritance. + PrivateKeyFile instead of PrivateKey. + Run graph algorithm when replacing a second connection from the same host + Add $NAME for tinc-up/down scripts. + - Fix indentation in some places. + Various fixes for autoconf and OpenSSL 0.9.7 and a missing header. + Make sure send_meta() writes everything. + Typo. + - Avoid memory leak caused by OpenSSL 0.9.7a. + - Speed up checksumming + Don't copy more than necessary. + Checksums must also work for uneven number of bytes. + HUP signal now closes connections to hosts if their host config file is + Better handling of late packets. + Make sure outgoing_t is completely freed. + - Per-node EVP_CIPHER_CTX to avoid initialisation overhead. + Small fixes to make LZO compression work. + Small fixes. + Fix links. + Fix warning and add missing checks for LZO library. + Call make_names() before doing anything else. + If we have a Linux tun/tap device and we are in router mode, open the device + AddressFamily is "any" by default. + Remove mymac stuff from device.c. + Fixes from Wessel Danker's libavl. + More braces to make gcc happy. + Update documentation. + Update dutch translation. + Typo and conversion to UTF-8. + There are two lzo compression levels. + Really make tinc default to any addressfamily. + This subtle pointer arithmetic thingy is (I'm very sure of it) the cause + - simplify configure.in + Check for IPv6 header files. + Define logger(), cleans up source code and allows us to write log entries + Sprinkling the source with static and attributes. + Provide all missing IPv6 definitions in lib/ipv6.h. + Actually add ipv6.h. + More missing definitions. + More missing IPv6 definitions and autoconf checks to make sure it compiles + Simplify logging, update copyrights and some minor cleanups. + Update copyrights. + Removing distribution specific files from CVS. + Format string checking for logger(). + Export mymac. + Make use of the CIPE driver. Woohoo, tinc for Windows! + Windows headers declare a struct interface somewhere. + Big header file cleanup: everything that has to do with standard system + Even more missing definitions. + Remove all #ifndefs from route.c + Update all device.c files. + Check for ethernet/ipv4/ipv6 related structures. + Use iface instead of interface because it might already be declared in + Oops. + No UNIX style permissions under Windows. + Be consistent. + Oops. + Check for sys/mman.h. + Use functions from logger.c + Copy cygwin driver to mingw directory. It doesn't work (yet). + Add section about configuring Cygwin and CIPE on Windows. + Option to specify pidfile location. + Use bools and enums where appropriate. + Run setup_device() after parsing configuration but before claiming we're ready. + Don't initialise a CIPHER_CTX if cipher == NULL. + Sprinkle around a lot of const and some C99 initialisers. + More generic handling of tap device under Windows. + More checks for missing functions. + Fix compile errors and warnings. + Update dutch translation and make sure all device drivers are included in + Update configure scripts. + Make sure it works. + Make sure (at least) the MinGW device driver works. + Native Windows support. + Cleanups. + Update documentation and remove stuff that's too outdated. + Remove doc/es/ and src/device.c from the distribution. + No C99 initialisers, gcc 2.95.3 doesn't like it. + Replacement for stdbool.h + Prevent definitions from messing up attributes. + Check if the compiler knows about the __malloc__ attribute. + Wrong argument. + Remove forgotten braces. + No easy way to properly detect header files... + Woops! + Wrong function... + Prevent system headers from including our own headers. + Allow whitespace in values. + Oops. + Windows has no symbolic links as we know it. + When compiling with MinGW, link with ws2_32. + Install tinc as a service under Windows (MinGW). Remove cleanup_and_exit(), + Error messages. + Cleanups and error messages. + Missing include. + Oops. + Updated dutch translation. + Explain how tinc detaches and how it is "killed" under Windows. + Typo and another thing to think about. + Clean up last part of main(). + Old gcc compilers don't like declarations in the middle of a function. + Cygwin needs windows.h. + Keep Windows happy. + Remove newlines from log messages. + Update dutch translation + Simplify translation + Use our own port when connecting to ourself. + Sync CABAL branch with release-1_0 branch. + +Ivo Timmermans (2): + Fix saving of debug level for startup level 0 + Call RSA_blinding_on(), as advised in the paper on + +Wessel Dankers (1): + its: Engels voor "van het" - 3e persoon enkelvoud, genitief, onzijdig + +Version 1.0pre8 September 16 2002 +------------------------------------------------------------------------ + +Guus Sliepen (73): + Support for MaxOS/X. + Add BindToAddress variable, similar to the late BindToIP. + Added Nick Patavalis for his RedHat package. + Informative log message if execl() failed. + Fix very stupid bug in node_del(), which might have caused corruption of + Only purge once when there are no more connections. + Support RSA_PUBKEYs (as opposed to RSAPublicKeys) so tinc accepts + Make it work correctly with NetBSD tun device. + Use correct includes on NetBSD. + Cleanup: + Use inttypes.h instead of stdint.h. + - netinet/* include files depend on netinet/in_systm.h. + Added Darwin (MacOS/X) tun device handling. + Use darwin/device.c when compiling on MacOS/X. + Include darwin/device.c in distribution. + Autoconf cleanup. Works for both 2.13 and 2.53, although running autoconf + Add configuration details for NetBSD and Darwin (MacOS/X). + Reset listen_sockets after SIGHUP. + Update comments about IPv6 autoconfiguration. + s/sliepen.warande.net/sliepen.eu.org/g + Fix for prefixlengths of 32 (IPv4) and 128 (IPv6) bits. + Allow list of environment variables to be passed to execute_script(). + Allow identical subnets from different owners. + Clear subnets before using them. + Started port to Cygwin. + Added stub device.c for Cygwin. + Include complete fake-getname/addrinfo from OpenSSH. + Allow tincd to be locked into main memory. + Don't bother to chown, and correctly document ConnectTo. + Added support for raw sockets. This can be used instead of tun/tap devices. + Gettext 1.11.5 compatibility. + Check for ranlib. + Replacement for the current routing algorithm. + Make sure setlocale() is available. + Drop graph and edge stuff. Use new node stuff instead. + A reachable node is always more preferable to an unreachable one... + Woops. + Reduce KEY_CHANGED traffic. + Prevent looping DEL_NODE/ADD_NODE messages after a node disconnects. + Don't forget to set prevhop to myself for new connections. + Just ignore wrong ADD_NODEs instead of replying with a DEL_NODE, in the + Revert to edge and graph stuff. This time, use a directed graph. + Small fixes. + Generalized request broadcasting/forwarding. + Updated dutch translation. + Small updates. + Run autopoint and libtoolize before creating initial makefiles. + Add missing headers. + Typo. + Only reset seqno's when a key is sent or received. + Remove global edge_tree. + edge_weight_compare() shouldn't rely on edge_compare(). + Reset the *correct* seqnos. + Fix MST algorithm. + Why don't these connection_t's get cleaned up? + Cleanups: + Switch to K&R style indentation. + Switch to K&R style indentation. + Remove redundant spaces. + Let GCC check format string and arguments of send_request(). + Fix compiler warnings. + Clean up after indent. + Link with libintl if necessary. + Fix placement of #include "config.h" + Make sure malloc() is declared. + What was I thinking? + MacOS/X needs #define _P1003_1B_VISIBLE in order to use mlockall(). + port_t isn't used anymore and conflicts with MacOS/X headers. + Small fixes so tinc compiles out of the box on SunOS 5.8 + Updated dutch translation. + Use /dev/net/tun as default for tun/tap device under Linux. + Update documentation. + Remarks about 1.0pre8 release. + +Ivo Timmermans (9): + Put #ifndef checks for HAVE_RAND_PSEUDO_BYTES in the correct places. + Typo + OSX support + getnameinfo fixes + Add /sw/{include,lib} to search paths if they exist + Include a few more header files + Include netbsd's device.c in make dist + Added Alessandro Gatti + Added AM_MAINTAINER_MODE + +Wessel Dankers (1): + This should work much better. + +Version 1.0pre7 April 09 2002 +------------------------------------------------------------------------ + +Guus Sliepen (9): + Make configure --help output look nicer. + Don't check_network_activity() if select() is interrupted by a signal. + check_rsa() is broken, I don't know why, just remove it for now. + Fix maskcheck() and maskcmp(). + Automake forgets about depcomp, remind it. + masklength is better known as prefixlength. + masklength is better known as prefixlength + Updated dutch translation. + Remarks about 1.0pre7 release. + +Version 1.0pre6 March 27 2002 +------------------------------------------------------------------------ + +Guus Sliepen (91): + Forgot to merge new files from pre5. + Last bits of the merger. + Sensible defaults for $INTERFACE. + - If no PrivateKeyFile is specified, /etc/tinc/netname/rsa_key.priv is assumed. + Small fix. + Added support for packet compression, thanks to Mark Glines. + Don't use sa_sigaction (which NetBSD doesn't like) at all if we don't use siginfo. + Get rid of sys/signal.h. + Added device.c for NetBSD, actually a copy of the OpenBSD one. + Add check for NetBSD. + - Non-blocking connect()s. + Fix segfault when receiving HUP signal. + Use AF_UNSPEC for listening sockets if AddressFamily = any. + Forward packets in router mode. + Fix maskcmp() and maskcpy(). + Cache results of lookup_subnet_...(). + Protocol now also exchanges cipher/digest/maclength/compression for the + Preserve inpkt->len, needed for broadcasts. + - Use gai_strerror() where appropriate + - Change SA_LEN to SALEN, former one is already defined on some platforms. + Tweaking IPv6 support. + Allow multiple listening sockets. + Fix send_request() bug. + Make BindToInterface work. + Fix listening sockets. + If "PriorityInheritance = yes" is specified in tinc.conf, the value of the + Create/bind TCP and UDP listening sockets in pairs. + Updated documentation. + Updated dutch translation. + - Global time_t now, so that we don't have to call time() too often. + Document and clean up MAC address expiry. + Woops. + Check if BindToDevice and PriorityInheritance are supported. + Fix forwarding of IPv6 packets. + po/POTFILES and po/Makefile should not be generated by configure. + Autodetect $MAKE/gmake/make. + Small fixes to improve portability. + Don't retry to make outgoing connections when exitting. + Cleanups, spelling fixes, allow symbol names for signals (-k option), + prune_connections() before build_fdset(). + Try to reply to neighbor solicitation requests. + New strategy: forward icmp6 neighbor solicitations to intended target. + Simplified implementation of Kruskal's minimum spanning tree algorithm. + Packet sequence number/authentication warnings only if debug_lvl >= 5. + Remove silly cache thingy. + Put #ifdef NEIGHBORSOL around corresponding code. + Revert changes to Kruskal's algo. + Neighbor solicitation requests now work (I think). + Oops, don't forget to actually put the checksum in the response packet. + Different way of detecting neighbor solicitation requests. + Typo. + Unmap v4mapped sockaddrs. + Only unmap IPv6 addresses. + #define s6_addr32, needed for FreeBSD. + Fix #define s6_addr32. + Remember sockaddrs of listening sockets, use appropriate one when sending + Cleanup. + Don't use s6_addr[16|32] anymore. + Updated dutch translation. + Updated SSSP algorithm to automatically detect indirect links (if a node uses + Put a break on requests that run around in circles. + - Added support for jumbograms. + Fix add_edge_h(). + Fix compiler warnings, strictly use long int and %lx for options. + send_ack() was broken. + free() request strings when deleting past requests from the tree. + Don't run graph algorithms if no edge is deleted in terminate_connection(). + Reset retry timeout when receiving the first PONG, not right after receiving the ACK. + Don't try to execute scripts unless they exist. + Execute hosts/name-up when a node becomes reachable, and hosts/name-down + Set $INTERFACE correctly when using ethertap while compiled with tun/tap support. + Updated dutch translation. + Respect type field. + OpenBSD tun device uses address family number instead of Ethernet type. + Configuration variables were still handled case sensitively. + Set myself->status.reachable. + Updated documentation. + Tell a little bit more about security. + Send REQ_KEY only once until ANS_KEY has arrived. + Fix execute_script(). + Small correction. + Merge do_prune() with build_fdset(). Probably fixes the invalid filedescriptor error. + Extend list_t with the number of elements in the list. + Limit the amount of packets in a queue to 8. + Small updates. + Remove cruft. + Recent automake uses $(AMTAR) instead of $(TAR) + Remove symlink to device.c when doing a make dist. + Fix format strings. + Update dutch translation. + Update with information about the pre6 release. + +Version 1.0pre5 February 10 2002 +------------------------------------------------------------------------ + +Guus Sliepen (109): + Small fixes to allow correct compilation under FreeBSD (tested with 4.3) + Make sure Solaris is happy too. + Fix subnet_lookup() for overlapping subnets. Needs rethinking. + Added proxy-arp support. No more ifconfig -arp needed. Works like a charm + - tinc can now act as a switch or a hub too (as opposed to a router only) + Changed some stuff to allow correct generation of po/Makefile after a + Updated dutch translation. + - This oneliner removes the need for ifconfig tap? hw ether fe:fd:0:0:0:0 + Fix bug where lookup_subnet_ipv4() could go into an infinite loop. + You can now put an option "Mode" in tinc.conf, and choose from: + Add missing? counting of total_socket_in. + Log and warn about duplicate subnet_add()'s for the same subnet. + Fixes to make switching work between hosts that have no meta-connection. + Save configure cache more often. + Changed drastically because it didn't work correctly: + Only reset seconds_till_retry when we activate the outgoing connection. + Woops - big bug in send_key_changed fixed. + - Solaris compile fixes + Check for and add -ldl. + Remove #warnings I used for debugging stuff. + Reinstated search for if_tun.h in kernel source tree, because apparently + Spanish translation removed. Nobody maintains it, and it is severely + ABOUT-NLS is created by autogen.sh. + Don't build Spanish translation. + Execute tinc-down BEFORE tap device is closed. This is a. more symmetric + es.po revived. + Also remove po/Makefile.in.in, which is generated by autogen.sh. + Log error if two hosts connect with same IP/port tuple. + Fix gcc 3.0 warnings. + Check for dlopen in standard libraries first (needed for DEC OSF). + It appears that autogen.sh doesn't like es.po if it isn't mentioned in + Update of RedHat build scripts. + Dutch translation updated. + More items marked as done. + Fix printf format bug. + Fix compiler warning. + Check for all potential duplicate entries in the id tree. + - Always use instead of just + Don't load table of verbose OpenSSL errormessages. + Correct inclusion of standard if_tun.h header file. + Split connection list into two lists: + Correctly use the active_tree. + Remove all unnecessary status.meta and status.active checks. + Added purge_tree for connection_t's which are no longer in the connection, + Updated terminate_connection() so you can choose if DEL_HOSTs should be + Always close all sockets in terminate_connection(). + Woohoo! tinc now compiles, runs and actually *works* on Solaris! + Started writing a document about how daemons connect to each other. + Described problem in more detail. + Small update. + Correctie. + Written down a possible solution. + Discuss how sending ADD_EDGEs would be better than sending ADD_HOSTs. + More on edges. + Don't use %m in fprintf(). + Write public key to rsa_key.pub instead of rsa_key.priv (if not host + The val variable in a config_t is never used as a long. + Explicitly log which type of tunnel device is used. + Don't send DEL_HOSTs when !status.meta + Fix signed comparison bug in lookup_subnet_ipv4(). + Remove IndirectData support for now, new implementation will be added + Revised reconnection mechanism, always try out all ConnectTo lines. + Optional signal number for -k option. + config_t* is a const parameter in get_config_val(). + - Try old TUN/TAP ioctl() request if the one from if_tun.h fails. + Not only keep track of nexthop, but also of lastbutonehop. If destination cl + Show next- and lastbutonehop when dumping connectionlist to syslog. + Try next connectto instead of the same over and over. + Fill in next- and lastbutonehop for myself. + - Renamed lastbutonehop to prevhop. + Fix bug where tinc would crash because of a portscan or a connection from a + - Use ping timeout mechanism to close connections that don't authenticate + Fix bug when dropping an old connection in favour of a new one from the + Updated dutch translation. + Started implementing doc/CONNECTIVITY. + Small corrections. + Further implementation of doc/CONNECTIVITY. connection.[ch] is now split into a + Removed everything from connection.c that has already been moved to node.c and + Revamp configuration handling: + More updates to new node/vertex/connection combo. + - Split tap device stuff out of net.[ch] + Added FreeBSD tap device handling. + Solaris tun device handling cleaned up a bit and added. + Forgot to remove some old #ifdef stuff. + Added OpenBSD tun device handling. Untested though. + Forgot the tun specific stuff. + Support new files (node/vertex/device.[ch]) and OpenBSD. + Big bad commit: + Make sure everything links. + Various small fixes to make tinc runnable again. + What was I thinking? s/vertex/edge/g. + - More s/vertex/edge/g + - More changes needed for Kruskal's algorithm + Working version of Kruskal's algorithm. The running time is very bad though. + Various fixes, tinc is now somewhat capable of actually working again. + More updates to protocol handlers and reimplemented terminate_connection(). + - Small fixes to graph algorithms + Don't forget to read public RSA key when making an outgoing connection. + Show cfg->variable instead of cfg->value when complaining about wrong type. + Avoid connecting to another node twice, and check name of outgoing connections. + Some very small fixes + Use PEM functions as suggested by OpenSSL docs. + Several bugfixes. + *** empty log message *** + Be liberal in what you accept: allow unknown edges to be deleted. + Correctly check if subnet owner exists. + Various fixes needed for Solaris. + More fixes for Solaris. + Merging of the entire pre5 branch. + +Ivo Timmermans (32): + New make target: `make release' + Changed version number to 1.0-cvs + Don't distribute autogen.sh in a release + Don't include the debian/ dir in a release + Small fix to make it compile again + Killing tincd with SIGINT causes it to toggle between the current + Check for getaddrinfo + Check for getnameinfo, gai_strerror, freeaddrinfo + Credit OpenSSH + Check for struct addrinfo + Deprecated get_config_ip and get_config_port + Use struct addrinfo in connection_t to hold all host data such as IP + Changed prototype for lookup_connection to use struct addrinfo + Changed lookup_connection to use struct addrinfo + Removed definitions of ipv4_t, ipv6_t, port_t + Obsoleted all IP types in favor of struct addrinfo + Changed to use struct addrinfo where needed. + get_config_{ip,port} removed. + Don't compile/link netutl.c. + Obsoleted. + Don't include netutl.h. + (re)added port to struct node_t + Added HAVE_STRUCT_ADDRINFO + Added dropin replacements for get*info and helper functions. + First part of rewriting things to use struct addrinfo. + lookup_node_udp changed. + Don't include netutl.h. + route_ipv4 and route_ipv6 replaced by route_ip. + get_config_subnet needs to be fixed. + Fixed silly typo: "np" instead of "no" + Don't include netutl.h. + Conversion to struct addrinfo is almost complete for this file. + +Wessel Dankers (1): + make is not always GNU make. + +Version 1.0pre4 May 25 2001 +------------------------------------------------------------------------ + +Guus Sliepen (97): + Porting to FreeBSD: + - Added balanced tree management stuff as well. (It is not finished yet.) + - Simplified do_detach + - Removed stray @INCLUDE@ (how did that get there?) + - Fixed searching + - Implemented deletions + - Fix tree head/tail upon insertion + - Fixed a lot of small things. Tested everything except deletions. + - Deletion also works now. + - Small fixes + - Integrate rbl trees into tinc. + - Proper initialization of rbltree structures. + - Various small fixes. + - More fixes. + - Check for NULL tree->delete callback + - Cleaned up and checked for some more NULL pointers in rbl.c + - Write pidfile AFTER detaching... + - No more %as. + - Work with the correct key buffer in ans_key_h + - More porting to FreeBSD and Solaris. + - Fixed all (except 2) compiler warnings gcc -Wall gave. + - #include instead of + - Don't link with -ldl anymore + Another big & bad commit: + - Added Armijn to the list + - Added daemon() replacement. + - Use only one socket for all UDP traffic (for compatibility) + - Don't even think about using sscanf with %as anymore + - AVL tree routines: faster than RBL, and also more stable. + - Doubled size of trace buffer for easier debugging. + - Let user choose whether keys are in the config files or separate + - Updated dutch translation. + - Check and follow symlinks in is_safe_path + - Changed license of AVL tree library to GPL. + - Updated manual pages. + - Updated texinfo manual. + - Typo. + - Changed list routines to give it the same look'n'feel as the rbl and + - Reinstated a queue for outgoing packets. + - Added header file for route.c. The routing routines in it are not used + - Description of protocol and authentication updated. + - It's 2001, all copyright notices are updated. + - Fixed IPv6 subnet lookup routine. + - Added indirectdata and tcponly functionality. + - Squashed another nasty bug. + - Sign was wrong in search_closest_smaller/greater + - Cleaned up subnet_t + - Only send out DEL_HOSTs for hosts with a meta connection + Added sample configuration directory. + - Copy entire sample-config directory to /etc/tinc/example upon installing. + - Allow ASN1 style keys to be in the config files. + FreeBSD compile fixes (thanks to XeF4) + Fix memory leak in avl_insert() if item was already inserted. + Updated dutch translation. + Removed another local definition of the variable "errno" + Added .cvsignore files to get rid of warnings and prevent autogenerated + Ignore file for src/ + - Updated CVS_CREATED to remove intl/ directory and some other + Added description of the proposed new authentication scheme. + Corrected check for errors after read() calls. + Add missing \n. + Free node->data and node, not node->data twice. + Copy packets before putting them in the queue. + Encrypt network packets in CBC mode instead of CFB mode. + Implemented new authentication scheme from doc/SECURITY2. + Added process.c to the translated files. + - Make sure METAKEY is smaller than the modulus of the RSA key + Don't forget to reconnect if outgoing connection fails during + - Fixed Interface option (untested) + Removed lots of compiler warnings. + Removed compiler warning. + Various small fixes. + Added explaination of our key exchange using RSA encryption. + - route.c is now used to determine destination + Updated translation. + Added a description of what is going on in net.c and route.c, and how + Fixed a race condition triggered by receive_meta() and the new + Fixed bug in setup_signals() that would make tinc die when unexpected + Ignore alarm signals if we do not need to respond to them. + Check indirectdata option before forwarding certain requests. + Depend on new ssl package and install alias for universal TUN/TAP module. + Correctly cycle through ConnectTo variables. + - s/ip_t/ipv4_t/g + - Make sure correct information is supplied for both old kernels (with + More revisions to the documentation: + Changed URL from kernelnotes.org to linuxdoc.org. + Add randomness to PING/PONG packets to prevent crypto attacks on quiet + Since this is incompatible with some earlier versions, PROT_CURRENT is + All features for 1.0 are implemented now, we just have to check the + Only send key_changed if it was previously requested. + Small fixes: + Small corrections to the manuals. + With recent kernels the tun device file is located in /dev/net. + TCPonly now works (in a relatively clean way too). + Merged PROTOCOL, NETWORK and SECURITY2 with the texinfo manual. + Documents are merged. Now we only need to check the ports and the TCPonly + Fix sample configuration to show keys in PEM format and correct tapdevice. + +Ivo Timmermans (88): + Add a check for openssl that accepts explicit file locations. + Identify version as 1.0pre4-cvs + Better checks for OpenSSL. I think it can now detect almost all conceivable installations. + Oops, small error. + Get rid of the annoying empty line + Also check for rand.h and err.h. If any of these files does not + Also check for sha.h. + Use the HAVE_OPENSSL_xxx_H defined from m4/openssl.m4 during + Let the output from an executed script in execute_script() go to + List management and manipulation routines. + Keep a list of running children, and in each loop in main_loop(), + Move all process-related functions into process.c. + New function: xmalloc_and_zero, which initialises the allocated memory + Delete struct ifr + Move more functions from tincd.c into process.c. + Use proper prototypes. + Added this release + More function and header checks + Also include process.h + Get rid of all libtool references at once. libtool was only used by + Honor the --localstatedir option to configure, instead of hardcoded /var. + Add more checks to ensure that filedescriptors are right in + Declare fd. + Do not use the C library's daemon() call. + Do not check for the daemon() system call + Do not attempt to retreive ChangeLog information only from the CABAL + Set localstatedir to /var + Use cvs2cl instead of rcs2log to generate the ChangeLog. + Set CFLAGS to -O2 -Wall when running configure + Alter CFLAGS, somehow INCLUDES doesn't propagate properly. Still + Set errno to 0 before trying to kill the other process. + Explain how to tell configure where OpenSSL lives. + Call autogen.sh instead of configure alone; and make cvs-clean instead + Add default tinc-up and tinc-down scripts for a Debian system. These + Updated Spanish translation, provided by Enrique Zanardi. + Give an error message if daemon() failed. + Check for the function strsignal, and define it to "" if it is not + Sort items to either 1.0 or future release goals. + Use sigaction to set signal handlers, the previous commit (1.1.2.16) + Save RSA public and private keys to a separate file, instead of + dropin.c/h contain a set of drop-in replacements for non-standard C + Check for get_current_dir_name. There is a replacement function in + Added a check for a scanf that knows about %as. + Implemented a readline() function that will read an entire line into a + xstrdup now takes a const pointer as an argument. + Use readline() in read_config_file() instead of fgets. + Also free the pointer returned by readline(). + Updated Dutch translation + Implemented is_safe_path, and extended ask_and_safe_open. + Read the PEM file pointed to by the configuration directive + The file is safe if it doesn't exist. + In readline(): initialise the line to zero length; + Better error checking when reading the RSA private key. + Avoid printing duplicate messages from read_rsa_keys + New function read_rsa_public_key(); + All full stops have two spaces after them. (Silly commit, I know.) + Tagged `Storing private key in separate file' as done. + readline() accepts two extra parameters, buf and buflen, to avoid + Use buffer instead of line in read_config_file(), line may be assigned + Stated that distributing executables linked with OpenSSL is permitted + Include COPYING.README in the distribution. + Added documentation merger + Sort configuration directives + Option -d accepts an argument to set the debug level immediately. + Massive long awaited documentation update. It's not finished yet, + Oops. I did some VERY wrong things with readline(). Fixed now. + Tiny bits of code beautifying + Install a file in /etc/modutils/tinc, containing all necessary aliases + Ported it back to /bin/sh. + Give a warning about having to re-create the keys + Re-introduced MyVirtualIP and VpnMask, as dummy options. + Various small changes. + Include autogen.sh (needed for the Debian package). + Forget router.c + Added lint target, requires lclint. + Fix error reporting of read_config + Set Architecture to `any' + Change version to 1.0pre4 + Second draft of the release notes + Merged documentation with various updates I had lying around + Get the Debian changelog up to date + Get the PO files up to date with the current source + Fixed some errors + Distribute the sample config as a .tar.gz + Unpack sample-config.tar.gz when installing + More files to ignore in CVS + tinc_TUNTAP now substitutes the values outside the AC_CACHE_CHECK + Authentication done + +Wessel Dankers (1): + Important bugfix in avl_insert_before() and avl_insert_after() + +Version 1.0pre3 November 09 2000 +------------------------------------------------------------------------ + +Guus Sliepen (119): + Debian init.d script automatically sets tap device's MTU to 1448 now. + First step for implementation of the "indirectdata" directive. This should + If we have "indirectdata" flag set, we only send data to our uplink. + Large cleanup: + Added CVS Id tags to header files. + - Log possible spoofing attacks. + Hostnames are back! + Hostlookup() is actually being called now. + - More verbose connection list + Fixes some hostlookups. Fixes indirectdata for real now (hopefully). + - Indirectdata finally REALLY REALLY works now! + - Moved all connection messages to debug level 1, without -d's only the + - Fixed KEY_CHANGED notification. A lot of notify_others() calls were + - Fixed indirectdata=no problem + - Improved handling of errors on connection attempts. + - Purge old connections that are ADD_HOSTed. + - Fixes a silly little insignificant buglet. + - Extra check op EINTR bij inlezen requests + - Fixed some spelling errors. + - Fixed missing " in nl.po + - Fixed a message in nl.po + - Added log message when SIGCHLD is received ("thanks" to Ivo van Dong) + - Updated Dutch translation. + - Removed all IP_ADDR_S macros, because gettext doesn't like them. Each + - New semantics for BASIC_INFO, ADD_HOST and DEL_HOST requests. This will + - Fixed memory leak. + - Removed segfault bug in conf.c (must have been there for ages!) + - Instead of logging an error when remote end closes the connection, + - Made tinc even more silent if no -d flag is given at all. + - Added documentation for the protocols (most important the meta protocol) + - Removed a single unused bit from status_bits_t. + - Updated PROTOCOL (a bit) + - Forgot to mention ourselves in the tincd manual page! :) + - Added Spanish translation from Enrique Zanardi. + - Updated THANKS file + - Delayed address resolving for ConnectTo lines in configuration file to + - Fixed typo. + - Added experimental hackish tunneling-over-TCP support. + - Lots o' buglets fixed (-Wall helps) + Fixed PACKET read loop. + Removed calling add_queue for tcponly packets. + - Added date/time of build and protocol number to --version output. + - Moved TCP packet reception to meta handler: less kludgy and less buggy! + - Reinstated O_NONBLOCK for meta socket + - Added two extra configuration options, Interface and InterfaceIP, to + Fixed all sprintf() spl01ts. + Ran update-po and updated dutch translation. + Commented on some size calculations. + Updated the manual: + Updated tinc.conf manual. + Fix rules (thanks to Laurence) + - Use strerror() instead of sys_errlist[] for increased portability + - New protocol. Will break everything else for now. + - Added more function skeletons for the new protocol. + - Lots of functions added for the new protocol. + - Some key exchange stuff. (Last commit before going to bed.) + - Fixed modulo in keylength check + - Lots of small changes. + Added document about the used cryptographic algorithms and the reasons + - Included authentication scheme from protocol.c + - Updated authentication scheme. + - Severe code reduction and simplification of challenge requests + - Removed options "string" stuff. It was a bad idea... + - Very detailed example of the authentication phase. + - Added meta.c which contains functions to send, receive and broadcast + - Added subnet handling code + Removing cipher directory (all will be covered by OpenSSL). + Big and bad commit of my current tree... + - Changed genauth to produce rsa keypairs instead of random passphrases. + - Generalized config file parsing to support multiple configuration trees. + - Fixing-things pass: every source file compiles into an object file now, + - Second fixing-things pass: it even links now. + - The daemon actually runs now (somewhat) + Corrected #ifdefs for tun/tap support. + - Fixing little things + - More fixing. Tinc daemons can now even create activated connections. + - Seed the PRNG using /dev/random before generating the keys. + - tinc now really does public/private key encryption! It even works, whee! + - Made Makefile.am stub for doc/es/ + - Removed last reference to genauth from Makefile.am + - Fixed all debug levels. + - route.c will contain the routing logic. + - Lots of little stuff modified + - Updated subnet list handling. Subnets are added to two lists now, the + - Lots of small fixes + - Fixed offsets when reading/writing from/to tap device + - Override destination ethernet address on incoming packets with + - Very big cleanup. + - Fixed ans_key_h + - Hit people who can't figure out subnet address/mask pairs with a + - Enforce correct order of authentication requests + - Moved connlist stuff to the proper header file. + - Updated dutch translation. + - Removed old encr stuff + - Small fixes + - Use CFB mode for encrypting packets: it works and we don't need padding. + - Finishing touch: encrypt the meta connections + - Small cleanups + - Fixed some spelling mistakes and terminology here and there. + - Update. + Removed config file parsing and interface setup. This will be handled by + - Removed unused MAC strip/add functions. + - Removed even more warnings. + - Resolve scriptname after fork() + - Removed manpage for no longer existing genauth. + - connlist.c added to translation + - Don't forget to set packet cipher for added hosts. + - Forward keys in hex notation, not as binary data. + - Check for packets that are looping back. + - Simplified ping mechanism. + - Prepended config_ to all configuration option names, because it confused + Changed execution of tinc-up: + - Open UDP connection for all known hosts. Comments please. + Porting to SunOS 5.8: + Porting to SunOS 5.8: + - Fixed --config + - Applied Jamie Brigg's patch (close sockets after error) + - Add Jamie :) + - Make checkpoint tracing a compile time option (off by default) + +Ivo Timmermans (77): + Alphabetized the list, added Lubom�r Bulej, removed Sander Smeenk and Tijs van Bakel, put merits after all names. + Don't touch VPNMASK if it's defined, otherwise use $MSK. + These files are created by gettextize (run by autogen.sh) (should have known that). + Include ../intl in the include path, and add @INTLLIBS@ to the list of libraries. + Merge changes from 1.6-1.8. + Configuration directive `IndirectData'. + Changed version number to 1.0pre3. + Version 1.0pre3. + Removed Free Software Foundation copyright, because Guus Sliepen contributed significantly. + Oops, and mention Guus too. + Include the Spanish translation in the distribution/build process. + (Quoting Laurence Lane:) + Also chomp $VPNMASK + Added a rule to create an rpm + Changed CVSROOT path in `make ChangeLog' + Link with OpenSSL crypto libraries instead of own blowfish library + Updated text, removed protocol flowchart + Include openssl/blowfish.h + Support for -lsocket and -lnsl on SunOS + Correct filenames for passphrases given in the example + Add Guus' name and shift out old protocol requests + Better checks for SunOS libraries + Added some structures and types that are needed for the overhaul. + New directive: Name. + First round of needed fixes after the overhaul + Second round of fixes + Added Spanish translation of the docs by Matias Carrasco + Many updates, parts rewritten, added, shuffled around. + Link with OpenSSL, forget libGMP + Updated new requirements, pointers to the manual + Don't look for GMP header files + Update Depends lines to reflect the dependencies on OpenSSL + Fix `Requirements'-section for GMP and OpenSSL libraries. + Add CVS id lines + Add checks for the presence of the universal tun/tap device driver. + Wrap the tun/tap code in #ifdef HAVE_TUNTAP + Linearized checks for if_tun.h + Really #include the if_tun.h files now + Output doc/es/Makefile + Process subdir es/ + Don't declare cp_file and cp_line in xmalloc() + Get the head revision up to date with cabal + Changed changelog + Include linux/sockios.h and net/if.h anyway, regardless of the value of HAVE_TUNTAP. + read_server_config: Check for result of read_config_file. + Oops, echelon change committed to cabal... :) + Skip the check for Linux kernel sources + This file is no longer needed. + - Synchronized changelog with the package's changelog. + Do not include $(top_srcdir)/cipher, it does no longer exist. + Added a perl example to turn an IP address into a MAC address. + Only check for linux/if_tun.h once + Changed `I' to `We' - small change, lots of difference :) + More exhaustive list of changes - perhaps it can be worded differently? + Change wsl to Wessel's name and email address in the ChangeLog creation + Mention fileutils, add a pointer to THANKS for more details + Changed a few messages wrt. system calls; updated and changed the Dutch translation a bit. + Don't include shlibs, as it no longer exists. + Oops, and include doc-base.tinc (new file). + - If necessary, patch po/Makefile.in from po-Makefile.in.in.diff to + Minor cosmetic change. + Save the environment on startup. + Run the scripts tinc-up and tinc-down from a separate function, which + Warnings removal pass: always include config.h first; add a few + Small change to the way the environment is copied. + Use putenv() instead of clumsy do-it-yourself in execute_script. + Do not include the passphrases directory + In execute_script: + Add route.c to the list of source files. + Updated Dutch translation + Build-depends on libtool + Build-Depends on gettext + Final release notes added, also edited release notes for 1.0pre2 to what the announcement on the mailing list looked like. + Wrapped text to 70 (72?) columns for easy reading + Bop version number to 1.0pre3-1 + Updates, updates + Add prototype for destroy_queue + +Wessel Dankers (3): + File added to CABAL (hopefully) + Grrr, recommit + Added architecture section, made a start with the kernel section. + +Version 1.0pre2 May 31 2000 +------------------------------------------------------------------------ + +Ivo Timmermans (56): + Deleted the protocol description. + Perl version of the system startup script. + Only print an error with send_termreq if debug_lvl is 2 or more. + Add check for mpz_powm in libgmp3. + Version 1.0pre1-0.1. + Changed version to 1.0pre2. + Give IP address instead of hex number when connecting tcp socket failed. + Add shlibs control file for the blowfish library. + Inserted useful content. + Add initscript, tincd->tinc. + Add description, better dependancies. + Mention both upstream authors. + tincd->tinc + .deb version number 1.0pre2-0.4. + Updated to newer version. + Exit with zero status if is empty. + Unlimited length in the config file, thanks to Cris van Pelt. + Depend on perl5. + *** empty log message *** + Look if the tap devices exist before bluntly remaking them. + Use the new VpnMask directive to add a route to the rest of the VPN. + This file is generated with dpkg-buildpackage. + Read /etc/tinc/nets.boot to find the networks that have to be started. + Create a default /etc/tinc/nets.boot after installation, containing all directories under /etc/tinc by default. + Version 1.0pre2-0.3 + Don't distribute the file files. + Find networks in instead of . + Include postinst in the distribution. + Errors will not terminate the script or result in a nonzero exit code. + Updated copyright notice. + Fixed typo. + Mask the vpn net with the vpn netmask, route would give an error if the netmask didn't match the net. + When VpnMask is not present in the config file, silently use $MSK as vpnmask. + Add an example of using VpnMask. + Use /etc/tinc/example as a base directory for an example. /etc/tinc/example/README points to /usr/share/doc/tinc/README.Debian. + Create an empty /etc/tinc/nets.boot. + Updated by Lubomir Bulej and Mads Kiilerich: it uses /etc/tinc/nets.boot and the VpnMask directive in the config files. + Internationalization of tinc. + Include intl/ directory in the list of subdirs. + Include system.h and ABOUT-NLS. + Update acconfig.h to include values for gettext inclusion. + Include GNU gettext checks. + Define LOCALEDIR in CFLAGS. + Dutch translation of tinc. + Bounds check for request id (between 0 and 255). + Updated changes list for version 1.0pre2. + Added new configuration directive `Hostnames', which controls the resolving of IP addresses to hostnames. + When a connection is terminated, all hosts that are still connected get notified of the lost connections. + In terminate_connection, only send a notification to hosts that are directly connected to us. (DEL_HOST gets forwarded automatically.) + Only accept an ADD_HOST request for a host that already exists in our conn_list if the nexthop field matches the sender. This is a workaround for older clients. + Include news for 1.0pre2. + Tell about /etc/tinc/nets.boot. + Updated Dutch translation. + Version 1.0pre2-1. + Handle locale settings. + Miscellaneous copyright updates. + +Guus Sliepen (16): + Proxymode removed. + Cleanups. + Changed ping behaviour (backwards compatible). If we don't have any data + Fixed typos. + Test for existence of configured tinc networks. This will also make + Stub for VpnMask config directive. + TODO file reinstated: + VpnMask truely works now. + Typo. + Fixed last typo. Init.d now uses ifconfig command to set both the tap's IP + Documentation updates. Removed all references to configuration variable + Fix for a DoS attack: + Fixed typos. When terminating a connection, it's status is not only set to + Made tinc persistent. If no outgoing connection can be established right + Terminate a connection on any error. Furthermore, disallow del_host, + Only activate a connection upon receiving it's public key if it's an + +Version 1.0pre1 May 08 2000 +------------------------------------------------------------------------ + +Ivo Timmermans (84): + Get rid of the message `zxnrbl\'. + Upon regeneration, free the old encryption key `securely\' by overwriting it. + Kill the parent after any error conditions in detach(). + Ignore SIGCHLD. + New option -D, don't detach. + Moved to version number 1.0. + Only one round of reading bits out of urandom; + Pass the requested size from xmalloc() and xrealloc() on to xalloc_fail_func() + Check for an illegal length of passphrase in read_passphrase(). + Check if stdout is a terminal, if so, print a verbose message. + Default passphrase length of 1024, added -h/--help options. + Submitted by Mads Kiilerich. + New manpage for genauth. + Updated manpages. + Address for bugreports changed to tinc@nl.linux.org. + Include the directory redhat in the build process. + Include genauth.8 in the distribution. + Submitted changes by Mads Kiilerich. + A short notice from Mads Kiilerich. + Keep make dist(dir) happy. + Added cvs-clean. + These files are not needed in release 1.0. + Don't compile in `idea'. + Don't include idea/idea.h. + Don't try to create cipher/idea/Makefile. + The shell script autogen.sh can create all these removed files, but be + s/Gnome/tinc/g + This file is obsolete, most of the ideas are already in echelon. + Remove check for bigendianness. + Don't define HAVE_NAMESPACES and HAVE_STL. + Use `make ChangeLog' to create this file from the CVS logs. + Remove test for GNOME. + Changes largely from Mads Kiilerich. + Added Mads Kiilerich, removed Guus Sliepen. + *** empty log message *** + Generate this Makefile.am from Makefile.am.in. + Contributed by Mads Kiilerich. + Spelling fixes. + Delete all the files that are created by autogen.sh on a `make cvs-clean'. + Propagate CFLAGS from configure to gcc. + Don't include TODO in the dist. + Remove ChangeLog with a `make cvs-clean'. + Initial CVS. + *** empty log message *** + Create a ChangeLog file, automake requires it. + *** empty log message *** + Debug level tweaking. + From Mads Kiilerich. + The make command is in /usr/bin. + Add an entry to dir. + Omit TODO. + Version to 1.0pre1; + Filled in the details, license from libblowfish copied. + Updated version number to 1.0. + Default config file name is tinc.conf, and pidfile is tinc.pid. + More updates wrt. the change from tincd->tinc. + Added `deb' target. + Filled up the protocol structs with unused bytes. + Got rid of the nasty hacks... and replaced it by another one. + Initially, the vpn_mask of a connection is 255.255.255.255 to avoid confusion with lookup_conn. + Replaced check for status.active by status.dataopen in check_network_activity. + New way of handling the meta protocol. + Read public keys the right way (tm). + Removed debug messages. + Read one less byte from an ANS_KEY request. + Send one less byte from an ANS_KEY request. + Protocol fix (ANS_KEY). This breaks 0.3.3 protocol compatibility. + Key forwarding, write one byte extra. + Committed by Lubom�r Bulej. + Updates by Mads Kiilerich. + Committed by Mads Kiilerich. + Fixed meta protocol. + More tincd->tinc updates. + Mentioned new metaprotocol. + Fix a typo, better handling of the info document. (from Mads Kiilerich) + Don't use error.h or error(), put #error in front of cpp errors. + getopt_long() support for platforms that don't have it. + Include stdio.h for fprintf. + More for getopt support. + Check for the existance of libdl. + Don't link in libdl. + Include sys/types.h. + Copied most of the code from the redhat script. + Added semicolons required by bash2 (Mads Kiilerich). + +Guus Sliepen (18): + Added extra checks for desynchronized connection lists. Hopefully this will + Bug found! Wrong pointer was used for handling multiple ADD_HOST requests + Added checkpoints to beginning and ending of every function. + Packet queues fixed. They caused the trouble when resending keys. + Fixed typo and removed some unnecessary variables. + When trying to talk to a host that is in the netmask of a tinc server but + Converted every &variable[0] to variable. + Cleanups: + Removed write_n() function. + Oops! Reference to write_n() removed and changed into neat write() call. + Meta protocol overhaul. Tinc is now incompatible with previous versions, + Fixed small mistake that would prevent forwarding requests. + Previous fix fixed. Meta protocol should be really flawless from now on! + Replaced sprintf() by safer snprintf(), removed possible buffer overflow + Outgoing packets now use network byte order in header. + Fixes typo and UDP network byte order. + Squashed gcc warning. + Added new config variable "ProxyMode". If enabled, all outgoing packets - Releasing 1.1pre4. - -commit 4c16094e949e1f17461ac744118076a3cec437e8 -Author: Guus Sliepen -Date: Wed Dec 5 21:42:43 2012 +0100 - - Fix whitespace. - -commit 4f8abf1b29b117c5d593bfa7703966fd88e9eace -Author: Guus Sliepen -Date: Wed Dec 5 21:40:49 2012 +0100 - - Scale packet counters similar to byte counters. - -commit d5f0ff5df86d06825110527ddc252b1268e31479 -Author: Guus Sliepen -Date: Wed Dec 5 21:33:01 2012 +0100 - - Don't use nested functions. - - This allows tinc to be compiled with Clang. - -commit eb80105ea855f2c7ee0ea467574acf86cf455a77 -Author: Guus Sliepen -Date: Wed Dec 5 14:42:21 2012 +0100 - - Fix compiler warnings on OpenBSD. - -commit 5e3607b616538eac7bb70d78d4f20d847a1c3064 -Author: Guus Sliepen -Date: Mon Dec 3 13:09:40 2012 +0100 - - Remove GraphDumpFile from the manual and manpages. - - This option is not supported in tinc 1.1, "tincctl dump graph" can be used - instead. - -commit a717b9bcfbe811787fd6718fb3f8fb3f272bcfb9 -Author: Guus Sliepen -Date: Mon Dec 3 13:08:03 2012 +0100 - - Add option to dump only a list of reachable nodes. - -commit 75c619e372f02f8225d158fd514f01bd04857d3b -Author: Guus Sliepen -Date: Mon Dec 3 10:41:28 2012 +0100 - - More fixes for Windows. - - In particular, Windows does support many of the timer* macros, except timeradd - and timersub. - -commit d53384c2de6d2824b9adcec111301d86e6b25f8e -Author: Guus Sliepen -Date: Mon Dec 3 09:08:21 2012 +0100 - - Fix compiler error on Windows. - -commit 76816e119b7d38a14823d430aafeff362dfbfd41 -Author: Guus Sliepen -Date: Mon Dec 3 09:07:23 2012 +0100 - - Fix crash in timeout handling. - -commit d19b00606576d19ef206e363ac709daf3bd00f25 -Author: Guus Sliepen -Date: Mon Dec 3 09:02:08 2012 +0100 - - Set a node's pointers to zero before trying to insert it into a tree. - -commit d2b19be1a0dd3c4987aa926117f5bf281892c78b -Author: Guus Sliepen -Date: Thu Nov 29 14:35:08 2012 +0100 - - Fix use of unitialised values in hash tables. - - Not only was Valgrind unhappy about it, it could also result in cache misses. - -commit d9c70767aa6da8b62b4a1034d5f07892603beddd -Author: Guus Sliepen -Date: Thu Nov 29 14:32:12 2012 +0100 - - Fix check for expired events. - - This would trigger a infinite loop if a timeout expired and the next timeout - was not expired yet, but less than 1 second from being expired. - -commit 8825cddd0d8ed6dad00924ef382139da51ca3fc4 -Author: Guus Sliepen -Date: Thu Nov 29 12:37:04 2012 +0100 - - Allow multiple timeouts to expire at the exact same time. - -commit 6bc5d626a8726fc23365ee705761a3c666a08ad4 -Author: Guus Sliepen -Date: Thu Nov 29 12:28:23 2012 +0100 - - Drop libevent and use our own event handling again. - - There are several reasons for this: - - - MacOS/X doesn't support polling the tap device using kqueue, requiring a - workaround to fall back to select(). - - On Windows only sockets are properly handled, therefore tinc uses a second - thread that does a blocking ReadFile() on the TAP-Win32/64 device. However, - this does not mix well with libevent. - - Libevent, event just the core, is quite large, and although it is easy to get - and install on many platforms, it can be a burden. - - Libev is more lightweight and seems technically superior, but it doesn't - abstract away all the platform differences (for example, async events are not - supported on Windows). - -commit d30b9e1272fef18070d37d10b2b3e4bb2fc07f59 -Author: Guus Sliepen -Date: Mon Nov 19 14:20:50 2012 +0100 - - Ensure MTU probe replies are sent back the same way they came in. - - Also sprinkle some comments over mtu_probe_h(). - -commit 3c1b7047332f4b5e9d5ae7109e696b33712a5fb2 -Author: Guus Sliepen -Date: Mon Nov 19 13:50:17 2012 +0100 - - Improve UDP address selection. - - We don't need to search the whole edge tree, we can use the node's own edge - tree since each edge has a pointer to its reverse. Also, we do need to make - sure we try the reflexive address often. - -commit f57129ce3439f3826c12f15feb5df05e5ad8cab9 -Author: Guus Sliepen -Date: Sat Nov 17 22:48:06 2012 +0100 - - Try all known addresses of node during PMTU discovery, now also for SPTPS. - -commit 30404650b28bf72d0b05b55393f2dd492434f9f3 -Author: Guus Sliepen -Date: Sat Nov 17 22:14:52 2012 +0100 - - Choose a suitable socket when updating a node's UDP address. - -commit 8f9ee895224b39347783f3119343efc3bdaa3511 -Author: Guus Sliepen -Date: Thu Nov 15 11:24:18 2012 +0100 - - Also don't use poll() on MacOS/X. - -commit 8a77df9e28114cbfd83351070fdb266cf31fc310 -Author: Guus Sliepen -Date: Thu Nov 15 11:13:40 2012 +0100 - - Disable support for kqueue on MacOS/X. - - Apparently MacOS/X doesn't support kqueue events on character devices. - -commit 818c92e6583006bf2e38f1027044925df6cf0ca0 -Author: Guus Sliepen -Date: Wed Nov 14 10:44:35 2012 +0100 - - Remove text saying you must have one of PrivateKey or PrivateKeyFile in tinc.conf. - -commit e8bf81794f412b27261be0f2aa4eb287352041af -Author: Guus Sliepen -Date: Tue Nov 13 15:05:41 2012 +0100 - - Send broadcast packets using a random socket, and properly support IPv6. - - Before it would always use the first socket, and always send an IPv4 broadcast packet. That - works fine in a lot of situations, but it is better to try all sockets, and to send IPv6 packets - on IPv6 sockets. This is especially important for users that are on IPv6-only networks or that - have multiple physical network interfaces, although in the latter case it probably requires - them to use the ListenAddress variable to create a separate socket for each interface. - -commit 0870c7c32cf8a24f234fc066df867747ddb1ddc7 -Author: Guus Sliepen -Date: Tue Nov 13 15:01:43 2012 +0100 - - Don't take the address of a variable whose scope is about to disappear. - -commit bb3d7f3b31d4a429d1c31c6621d82f34dd552482 -Author: Guus Sliepen -Date: Sun Nov 11 19:01:28 2012 +0100 - - Fix configure script help text for --enable options. - -commit 5bfbb8f6c58307a8109f556caa30be122cc4d39f -Author: Guus Sliepen -Date: Sun Nov 11 19:01:02 2012 +0100 - - Fix index entry for section about readline library. - -commit 5766518589a5e6cc43ba77a4049059ead05fb300 -Author: Guus Sliepen -Date: Sun Nov 11 18:53:23 2012 +0100 - - Mention in the manual that support for LZO and zlib can be disabled. - -commit 6ec4596557d658f6c15c2cb9a96152c8c476118a -Author: Guus Sliepen -Date: Sun Nov 11 18:45:40 2012 +0100 - - Mention libcurses and libreadline in the manual. - -commit 0ee139e91431527015b7132e4c36f8d4ec09f66b -Author: Guus Sliepen -Date: Sat Nov 10 23:45:22 2012 +0100 - - Make sure PMTU discovery works in switch mode with VLAN tags. - - Before, when tinc saw a packet larger than the PMTU with a VLAN tag, it would - not know what to do with it, and would just forward it via TCP. Now, tinc - handles 802.1q packets correctly, as long as there is only one tag. - -commit ade4fccad6857f3d6d548e52bc94ab23751e4fef -Author: Guus Sliepen -Date: Sat Nov 10 23:13:05 2012 +0100 - - Using alloca() for a constant sized buffer is very silly. - - Cppcheck said using alloca() in the 21st century is silly anyway. - -commit b355476e917f377abb6434657933fcf4ffe6870a -Author: Guus Sliepen -Date: Sat Nov 10 23:09:31 2012 +0100 - - Fix potential buffer overflow reading the PID file. - - Found by cppcheck. - -commit edc08b73a9e353bde6db4c73866a6a730a1a7cb4 -Author: Guus Sliepen -Date: Sun Oct 21 17:45:16 2012 +0200 - - Slightly randomize all timeouts. - -commit 717ea66d7ba0c23f27d86b3d5c6992b751135455 -Author: Guus Sliepen -Date: Sun Oct 21 17:35:13 2012 +0200 - - Add the AutoConnect option. - - When set to a non-zero value, tinc will try to maintain exactly that number of - meta connections to other nodes. If there are not enough connections, it will - periodically try to set up an outgoing connection to a random node. If there - are too many connections, it will periodically try to remove an outgoing - connection. - -commit 1f8b70efa0dedbd3642e0ee82a640d125664af34 -Author: Guus Sliepen -Date: Sun Oct 21 17:34:53 2012 +0200 - - Keep track of the number of nodes in a tree. - -commit 0006c754f2e61e108aa2dd5a6ddd2e9b50d51bd6 -Author: Guus Sliepen -Date: Wed Oct 17 13:51:02 2012 +0200 - - Fix warnings from groff. - -commit 0db9e471ea53b48687ea247c855cd95ec453530c -Author: Guus Sliepen -Date: Sun Oct 14 19:22:30 2012 +0200 - - Releasing 1.1pre3. - -commit 3254e75afe0ff28fed68d8682f61c184f442161d -Author: Guus Sliepen -Date: Sun Oct 14 19:21:13 2012 +0200 - - Fix a few compiler errors/warnings. - -commit 70a1a5594af5d4e6a364186b42ba4e34c676009b -Author: Guus Sliepen -Date: Sun Oct 14 17:42:49 2012 +0200 - - Update copyright notices. - -commit 4200a378c4fedf64e89b9f8481d7cd09dac14965 -Author: Guus Sliepen -Date: Sun Oct 14 16:39:16 2012 +0200 - - Fix compile error on Windows. - -commit 368727c3dac4a1f8343e2e0eccf5bc62d9b197e2 -Author: Guus Sliepen -Date: Sun Oct 14 16:07:35 2012 +0200 - - tincctl: add node colors and edge weight to graph dump. - -commit 40ed0c07dd3d4667054b0f5952b89ee39686493b -Author: Guus Sliepen -Date: Sun Oct 14 15:37:24 2012 +0200 - - Log more messages using logger(). - -commit b234304b6628aeddce63d7f751da97c3344bbb78 -Author: Guus Sliepen -Date: Sun Oct 14 14:48:35 2012 +0200 - - Make sure the ReplayWindow option works for SPTPS as well. - -commit ee1d655f2f1ede6da66b6268974d6f9585c616b3 -Author: Guus Sliepen -Date: Sun Oct 14 14:45:27 2012 +0200 - - Only log success of initial datagram SPTPS handshake. - -commit 44a24f63acc70d19904e5540986b8301b3c9b882 -Author: Guus Sliepen -Date: Sun Oct 14 14:33:54 2012 +0200 - - Fix handling of initial datagram SPTPS packet. - - Only the very first packet of an SPTPS session should be send with REQ_KEY, - this signals the peer to abort any previous session and start a new one as - well. - -commit ec1f7e525d046bcaeb8e7040b8cec9a34a568371 -Author: Sven-Haegar Koch -Date: Fri Oct 12 17:08:01 2012 +0200 - - sptps.c: Add missing newline to log message. - -commit 94ec8d34db0ddef14b5446975663e5ff37e27b45 -Author: Guus Sliepen -Date: Thu Oct 11 22:47:13 2012 +0200 - - Strip newline from incoming SPTPS requests. - - Most of the code doesn't care whether requests are terminated with a newline or - not, except that when requests are forwarded, it is assumed they do not have - one and a newline is added. When a node using SPTPS receives a request from - another SPTPS-using node, and forwards it to a non-SPTPS-using node, this will - result in two consecutive newlines, which the latter node will see as an empty, - and thus invalid, request. - -commit 45944e4514a7765f858fa33cc1d9719a603099e0 -Author: Guus Sliepen -Date: Thu Oct 11 22:21:30 2012 +0200 - - Clear status and options fields of unreachable nodes. - -commit d917c8cb6b69475d568ccbe82389b9f2b3eb5e80 -Author: Guus Sliepen -Date: Wed Oct 10 17:17:49 2012 +0200 - - Fix whitespace. - -commit 58f4b845b9a7d83739af77337f2ce263d8df7838 -Author: Guus Sliepen -Date: Wed Oct 10 14:46:22 2012 +0200 - - Try all known addresses of node during the PMTU discovery phase. - - This helps in situations where some nodes have IPv6 and others have not. - -commit 0ed0cc6f9c30537bd74222fd99a41726d488dd37 -Author: Guus Sliepen -Date: Tue Oct 9 17:49:09 2012 +0200 - - Fix hash functions for keys whose size is not divisible by 4. - -commit d1ec010660905ae0b99d783737350ccc08b37b16 -Author: Guus Sliepen -Date: Tue Oct 9 16:27:28 2012 +0200 - - Fix memory leaks found by valgrind. - -commit 72642b40b3ad476101622da202b6f977a32b472f -Author: Guus Sliepen -Date: Tue Oct 9 15:52:58 2012 +0200 - - Clear Ethernet header when reading packets from a tun device. - - This fixes a warning from valgrind about uninitialized bytes, which were being - sent to other nodes. - -commit b346338f9c2de6f71d87cb4ad8e61b0af0052688 -Author: Guus Sliepen -Date: Tue Oct 9 13:28:09 2012 +0200 - - Remove unused variables, fix some #includes. - -commit f62b4a91344bd0de09e7fb4e4c8c1993ffc027c3 -Author: Guus Sliepen -Date: Tue Oct 9 13:23:12 2012 +0200 - - Fix deleting connections from the connection list. - -commit 0b8b23e0dd7219344543f135ca0aeba8a4a42d48 -Author: Guus Sliepen -Date: Mon Oct 8 00:35:38 2012 +0200 - - C99 extravaganza. - -commit ff306f0cdaedb50de1472e7c1fb55de922a6ca60 -Author: Guus Sliepen -Date: Sun Oct 7 21:59:53 2012 +0200 - - Replace the connection_tree with a connection_list. - - The tree functions were never used on the connection_tree, a list is more appropriate. - Also be more paranoid about connections disappearing while traversing the list. - -commit ce059e36fdb3d3049c278e8b2f36b03c93778996 -Author: Guus Sliepen -Date: Sun Oct 7 21:02:40 2012 +0200 - - Refactor outgoing connection handling. - - Struct outgoing_ts and connection_ts were depending too much on each other, - causing lots of problems, especially the reuse of a connection_t. Now, whenever - a connection is closed it is immediately removed from the list of connections - and destroyed. - -commit d93a37928b75b17ac5e1eae5c2d62fd0760a6608 -Author: Guus Sliepen -Date: Sun Oct 7 17:53:23 2012 +0200 - - Fix warnings from cppcheck. - -commit 5d0812d49275ec8bda2b5b0ac813239045463777 -Author: Guus Sliepen -Date: Sun Oct 7 14:06:47 2012 +0200 - - Remove a debug message. - -commit c2a9ed9e98e3dc4218c74fff774ddfe654adfd72 -Author: Guus Sliepen -Date: Sun Oct 7 14:03:50 2012 +0200 - - Handle packets encrypted via SPTPS that need to be forwarded via TCP. - -commit bb6b97ce3493d49b79f1bd57fdac420c312ef8d6 -Author: Guus Sliepen -Date: Sun Oct 7 13:31:19 2012 +0200 - - Make datagram SPTPS key exchange more robust. - - Similar to old style key exchange requests, keep track of whether a key - exchange is already in progress and how long it took. If no key is known yet - or if key exchange takes too long, (re)start a new key exchange. - -commit b99af2f813b897e1fd49c87a7cf44241cad3a017 -Author: Guus Sliepen -Date: Sun Oct 7 11:45:54 2012 +0200 - - Useful error messages when writing to a meta connection fails. - -commit e05371346548dee977d4ee45e12e3058e749afb6 -Author: Guus Sliepen -Date: Sat Oct 6 21:16:17 2012 +0200 - - When terminating, keep control connections open until the end. - - This ensures all device files and listening sockets have been closed before - tincctl gets notified of tincd's termination. - -commit 86116bb022f0b885638ff9ba21b359fc9f55286a -Author: Guus Sliepen -Date: Sat Oct 6 21:15:19 2012 +0200 - - Clear connection options and status fields in free_connection_partially(). - - Most fields should be zero when reusing a connection. In particular, when an - outgoing connection to a node which is reachable on more than one address is - made, the second connection to that node will have status.encryptout set but - outctx will be NULL, causing a NULL pointer dereference when - EVP_EncryptUpdate() is called in send_meta() when it shouldn't. - -commit ef9358c0d616c5ff3391c8ec3da5d357286a4457 -Author: Guus Sliepen -Date: Sat Oct 6 17:45:03 2012 +0200 - - Improve starting/stopping tincd using tincctl. - - When starting tincd, tincctl now strips non-options from the command line, and - sets argv[0] to the name of the tincd command instead of copying its own - command name. - - When stopping a running tincd, tincctl now waits for it to terminate. - -commit 47f33e07ff90b557cfa96999e921d35ea537ca80 -Author: Guus Sliepen -Date: Sat Oct 6 16:53:43 2012 +0200 - - Fix off-by-one error. - - Apart from writing 1 byte beyond an array allocated on the stack, this slipped - an unitialized byte in the seed used for key generation. - -commit 20b441a6de743b2149df59cfb94a7663e1924fa3 -Author: Guus Sliepen -Date: Mon Oct 1 10:42:13 2012 +0200 - - Libreadline might depend on libcurses. - -commit 3887e6dcb54494ee11798e721e274e06b0a5621a -Author: Guus Sliepen -Date: Mon Oct 1 10:39:15 2012 +0200 - - Remove abort() call that accidentily sneaked into commit dd1b69e. - -commit 0b0949e5bb63f9545feb4714812e2aa2112fb092 -Author: Guus Sliepen -Date: Mon Oct 1 10:36:23 2012 +0200 - - Make sure sptps_test compiles without -flto. - -commit b381acd60dbadbb4bc679d35a7d86bf425f21f86 -Author: Guus Sliepen -Date: Sun Sep 30 23:12:43 2012 +0200 - - Remove unused function declaration. - -commit dd1b69e31f83e2cc200ecc10e6d927373823332b -Author: Guus Sliepen -Date: Sun Sep 30 22:43:48 2012 +0200 - - Fix not reading Port statement from host config file. - -commit 6dfdb323612184529b4b83c1be914dda8262de47 -Merge: 9e76c46 c4940a5 -Author: Guus Sliepen -Date: Sun Sep 30 15:00:47 2012 +0200 - - Merge branch 'master' into 1.1 - - Conflicts: - lib/utils.c - src/net_setup.c - src/process.c - src/protocol_auth.c - src/protocol_key.c - src/utils.h - -commit c4940a5c888d85b4c477b6face5e9a618e64718d -Author: Guus Sliepen -Date: Sun Sep 30 13:45:47 2012 +0200 - - Add strict checks to hex to binary conversions. - - The main goal is to catch misuse of the obsolete PrivateKey and PublicKey - statements. - -commit 3bd810ea79d6933839ddac4a2cf1445c51947d38 -Author: Guus Sliepen -Date: Sun Sep 30 13:45:39 2012 +0200 - - Attribution for Martin Schürrer. - -commit 5a161e86cf35351f5274d7a8e17fef4630b40686 -Author: Martin Schürrer -Date: Sun Sep 30 02:04:55 2012 +0200 - - Output details of encryption errors - -commit 9e76c464b26b066e1eb3aa5232e573792e28020d -Author: Guus Sliepen -Date: Fri Sep 28 17:51:48 2012 +0200 - - Remove some debugging messages. - -commit e971130b601064090815c31c90b876e3d0d1d5b1 -Author: Guus Sliepen -Date: Fri Sep 28 17:36:25 2012 +0200 - - Make tincctl robust against dropped control connections. - -commit c5325ffdd1c6749beaf842c272eb28ecd5a070b6 -Author: Guus Sliepen -Date: Fri Sep 28 17:05:01 2012 +0200 - - Correctly add/remove outgoing connections when reloading configuration. - -commit f417271ea1447589ea05901f54fbb0377e7afaf9 -Author: Guus Sliepen -Date: Fri Sep 28 17:03:14 2012 +0200 - - Fix column sorting, make all lists sortable. - -commit aee86011ff2d389832fc9a23081ea23ab8484607 -Author: Guus Sliepen -Date: Thu Sep 27 22:12:15 2012 +0200 - - Let the GUI handle the new dump format. - -commit fac5593f44e47f3bd4f4b425ada38ab49fbe3b42 -Author: Guus Sliepen -Date: Thu Sep 27 17:19:02 2012 +0200 - - Fix links in documenation. - -commit 2e09986a1fd6dc5b6313f10e5d86aaaf4a531235 -Author: Guus Sliepen -Date: Thu Sep 27 17:18:49 2012 +0200 - - Fix links in documentation. - -commit f70cbc9d3ee3a88cf956592007e57f7a1dde2c17 -Author: Guus Sliepen -Date: Thu Sep 27 15:45:02 2012 +0200 - - Comment out old public/private keys when generating new ones. - -commit 38dbc63f118dbfdb955b56740b8c20a9379fb3ba -Author: Guus Sliepen -Date: Wed Sep 26 23:56:21 2012 +0200 - - Update documentation of the "dump graph" command. - -commit 1f312137d5ab12a2d996d5f7972f169aeb852040 -Author: Guus Sliepen -Date: Wed Sep 26 23:52:36 2012 +0200 - - Allow dumping either directed or undirected graphs. - - Internally, tinc maintains a directed graph of the meta connections between - nodes. However, this causes graphviz to draw two lines between nodes, which is - not always desirable. The "dump graph" command now defaults to dumping an - undirected graph, the "dump digraph" command will dump a directed graph. - -commit d6388d782ede1bbe49a5c2643362e2e0f383fa89 -Author: Guus Sliepen -Date: Wed Sep 26 23:18:32 2012 +0200 - - Let tincctl parse and format dumps. - - At the moment it just reproduces the old format. - -commit 9ade39b7d5564fb6f5a41946c9a23cfa7851a19f -Author: Guus Sliepen -Date: Wed Sep 26 22:20:43 2012 +0200 - - Keep last known address and time since reachability changed. - - This allows tincctl info to show since when a node is online or offline. - -commit 1e5deec973cd366b9d9cec6c1314a97e7051ce0f -Author: Guus Sliepen -Date: Tue Sep 25 22:28:08 2012 +0200 - - Remove remnants of Ethertap and old TUNSETIFF ioctl(). - -commit 125dd0dbcf4f46033ead3486044eb00b413fe537 -Author: Guus Sliepen -Date: Tue Sep 25 22:12:36 2012 +0200 - - Fix typo in manpage. - -commit 72f08932cf6f1ac0cfb837d377b423207e8c671a -Author: Guus Sliepen -Date: Mon Sep 24 14:56:00 2012 +0200 - - Don't ignore Makefile.am. - -commit 66e702d90d83977dc089736d7e4146330bc5df28 -Author: Guus Sliepen -Date: Mon Sep 24 14:02:07 2012 +0200 - - Attribution for Vil Brekin and some code style cleanups. - -commit f421a640777bd9484c59fa6feacadcf3e05d4b44 -Author: Vilbrekin -Date: Sat Aug 25 20:32:38 2012 +0200 - - Android cross-compilation instructions. - -commit afe4bf62eccab76c75e5a661fb2c16f1391a8417 -Author: Vilbrekin -Date: Sat Aug 25 20:01:11 2012 +0200 - - Use __ANDROID__ define rather than dirty hard-code to allow android NDK cross-compilation. - -commit c6720f1a608d19c722d8601fab1048773dbad59b -Author: Vilbrekin -Date: Sat Aug 25 19:59:26 2012 +0200 - - Add basic .gitignore file, cleaning (most) files generated by autotools. - -commit f2570c1b7f5813e087c867cf002f36f0c09b5cfa -Author: Vilbrekin -Date: Sat Aug 25 19:14:00 2012 +0200 - - Replace hard-code with new ScriptsInterpreter configuration property. - - This new setting allows choosing a custom script interpreter used for the various tinc callbacks. - If none is specified, the script itself is called as executable (as before). - This is particularly useful when storing tinc configuration and script on a mount point with no-exec attribute. - -commit 8a6f278fd2606c0a8f133f05df83b2649eacf6c3 -Author: Vilbrekin -Date: Wed Aug 22 10:46:24 2012 +0200 - - Basic patch for android cross-compilation. - - Commented non-existing functions in android NDK. - Prefix scripts execution with shell binary to allow execution on no-exec mount points. - Everyything is currently hard coded, while it should use pre-compiler variables... - -commit 2dc8deb1047a076d1c040f47bedf36ad4b41b17c -Author: Guus Sliepen -Date: Thu Sep 13 21:35:29 2012 +0200 - - Ensure sptps_test compiles with -flto. - -commit 90f1cba1fd9e748ec4b8274511d5a36ec1a24d9d -Author: Guus Sliepen -Date: Wed Sep 5 13:05:48 2012 +0200 - - Replace node_udp_tree with a hash table. - -commit 4c05afd19acada4781e1b8865cf702b197882e5d -Author: Guus Sliepen -Date: Wed Sep 5 12:45:36 2012 +0200 - - Use hash tables to lookup owners of addresses. - -commit 6b6a025488f289f749498a7e6cc1994be19f53e8 -Author: Guus Sliepen -Date: Wed Sep 5 12:44:41 2012 +0200 - - Add a simple hash table implementation. - -commit e9de08be0dab58a48f9a8ce3d250516cf05d6b8e -Author: Guus Sliepen -Date: Tue Sep 4 14:21:50 2012 +0200 - - Remove newlines at end of log messages. - -commit 05dac63dbc03dc5a64a7f4b50e24eb3766135916 -Author: Guus Sliepen -Date: Tue Sep 4 14:16:05 2012 +0200 - - Remove some debug messages. - -commit 742f7bb04e72d93f2c4a858534144a599b3fc14d -Author: Guus Sliepen -Date: Thu Aug 30 14:21:23 2012 +0200 - - Properly handle SPTPS packets with stripped Ethernet headers. - -commit d74b81b61e87c66d364a8590a48d87773ad2652c -Author: Guus Sliepen -Date: Thu Aug 30 14:00:34 2012 +0200 - - Fix node name check for "connect" and "disconnect" commands. - -commit 5567c0d4107e6ff6f4639d8664651841bd59ddad -Author: Guus Sliepen -Date: Sun Aug 5 17:25:31 2012 +0200 - - Quit when "exit" or "quit" commands are used in tincctl's shell. - -commit d18519ae21345fea68dd7f0f5525adba3a7639a9 -Author: Guus Sliepen -Date: Sun Aug 5 17:03:57 2012 +0200 - - Fix segfault when using tincctl's shell without readline. - -commit b332bd964663b7109a5fc4be596d36fbf1dbaa47 -Author: Guus Sliepen -Date: Sun Aug 5 13:50:51 2012 +0200 - - Add bash completion script. - -commit e29e0fee8812851473bcf24324a15cbf3cc854a0 -Author: Guus Sliepen -Date: Fri Aug 3 14:17:02 2012 +0200 - - Make sure the top command can be used more than once in tincctl's shell. - -commit a57db1dfe0736fd902a45ed5f695630faf3f0e1e -Author: Guus Sliepen -Date: Fri Aug 3 14:15:50 2012 +0200 - - Fork when using the "start" command in tincctl. - - This allows the command to be given in its shell without immediatly exiting tincctl. - -commit 36c6afede36b6956bd86df824f5616c1afee35ed -Author: Guus Sliepen -Date: Fri Aug 3 13:23:07 2012 +0200 - - Add readline completion for tincctl config and tincctl info. - -commit 8af2f3f5a4061a8dbfd4f7d259e0038df06a373e -Author: Guus Sliepen -Date: Thu Aug 2 17:44:59 2012 +0200 - - Optionally compress and/or strip Ethernet header from SPTPS packets. - -commit 73348be58ecb9c40cf435122a00e72ac4d1a4c9b -Author: Guus Sliepen -Date: Thu Aug 2 17:24:42 2012 +0200 - - Have tincctl act as a shell when no command is given. - - By default it uses readline to read commands. If the input and output are not a - tty, no prompt is shown. - -commit 91937812bdfe74699e4f7cdf86265d07423acbba -Author: Guus Sliepen -Date: Thu Aug 2 17:23:51 2012 +0200 - - Clear struct sptps before reusing it. - -commit 6bcd03c2027636f82ab7228566717d112df7bc6d -Author: Guus Sliepen -Date: Wed Aug 1 22:22:52 2012 +0200 - - Update the documentation to encourage using "tincctl init" and "tincctl config". - -commit 6396f42d74f22ab5f8e736dc5cb04c57917f9319 -Author: Guus Sliepen -Date: Wed Aug 1 16:51:59 2012 +0200 - - Stricter checks for netname and node names. - - - Node names should not be empty. - - Net names should not contain slashes or start with a dot, because they are - used in pathnames. - -commit 61006ced88e1bf62e8883216cabc636f2d4cb12a -Author: Guus Sliepen -Date: Wed Aug 1 16:13:23 2012 +0200 - - Add missing configuration variables. - -commit b0f3a76e9bf8ceeab75c1e6f4dce6763aecddc5e -Author: Guus Sliepen -Date: Wed Aug 1 15:50:45 2012 +0200 - - Add the ability to query configuration variables to tincctl. - -commit a9caa2a6ea3aa553c9d2140ad4f5b34b7ab7297b -Author: Guus Sliepen -Date: Wed Aug 1 15:15:37 2012 +0200 - - tincctl restart should work even if no tincd is running. - -commit 07980b056c5371f8b6fdd50172f501be07155bdf -Author: Guus Sliepen -Date: Wed Aug 1 15:14:48 2012 +0200 - - Try sending SIGTERM if we cannot connect to a tincd but we know its PID. - -commit 7a71d48009e03ff1143a6e1084803f456a27c849 -Author: Guus Sliepen -Date: Tue Jul 31 21:43:49 2012 +0200 - - Use a status bit to track which nodes use SPTPS. - -commit 6bc8df3e010509f69af95d2cc14ec893def6f644 -Author: Guus Sliepen -Date: Tue Jul 31 20:39:15 2012 +0200 - - Add Brandon Black's replay window code to SPTPS. - -commit 5ede437307cc3bbb20431f4b82f4a2ef79c9b746 -Author: Guus Sliepen -Date: Tue Jul 31 20:36:35 2012 +0200 - - Handle SPTPS datagrams in try_mac(). - -commit aaff0ed08916f936b0a7b8a3d0607b8111b7a185 -Author: Guus Sliepen -Date: Tue Jul 31 20:29:13 2012 +0200 - - Remove unused #include. - -commit 153abaa4d940bf2bc9bd7275d5efe5c01c354190 -Author: Guus Sliepen -Date: Mon Jul 30 18:36:59 2012 +0200 - - Use datagram SPTPS for packet exchange between nodes. - - When two nodes which support SPTPS want to send packets to each other, they now - always use SPTPS. The node initiating the SPTPS session send the first SPTPS - packet via an extended REQ_KEY messages. All other handshake messages are sent - using ANS_KEY messages. This ensures that intermediate nodes using an older - version of tinc can still help with NAT traversal. After the authentication - phase is over, SPTPS packets are sent via UDP, or are encapsulated in extended - REQ_KEY messages instead of PACKET messages. - -commit 248d300f1be0d5f2aae39202041699ab2b46c56b -Merge: e1355e2 3391018 -Author: Guus Sliepen -Date: Fri Jul 27 22:48:24 2012 +0200 - - Merge branch 'master' into 1.1 - -commit 3391018efbd41858d42ccae6ae919749ba94c8db -Author: Guus Sliepen -Date: Fri Jul 27 22:43:01 2012 +0200 - - Also clarify hostnames=[yes|no] in tinc.conf(5). - -commit e895b358db8863d19dfa3d77c861ae19b76bc750 -Author: Mesar Hameed -Date: Tue Jul 24 07:18:50 2012 +0100 - - Minor clarification, tinc.conf hostnames=[yes|no] variable only resolves names for logging purposes. - -commit e1355e24eb7fe36bdb5dd7c818815fa266046a51 -Author: Guus Sliepen -Date: Sun Jul 22 13:05:56 2012 +0200 - - Remove unused po/ directory. - -commit 6c9b33c8b67374d38525b88f292840034c559a45 -Author: Guus Sliepen -Date: Sun Jul 22 12:55:04 2012 +0200 - - Have tinc-gui use same way of locating pidfile as tincd and tincctl. - -commit 2b97a7d7cf6ca7f4d84d3df754062a55bdf55305 -Author: Guus Sliepen -Date: Sun Jul 22 12:52:31 2012 +0200 - - tincctl init now also creates a template tinc-up script. - -commit eb430005c74b6b5f717e7e264afa3bd35284740d -Author: Guus Sliepen -Date: Sat Jul 21 17:10:10 2012 +0200 - - Fix exit code when installing tincd as a service on Windows. - -commit e5e96882c3825cee81ff163490b2f39fad3192b8 -Author: Guus Sliepen -Date: Sat Jul 21 16:33:09 2012 +0200 - - Windows doesn't like quotes around "edit" when calling it through system(). - - Even though that works fine on the command line. - -commit 18237e1f2d9dd5eef4a4e0d746d016bf94a42ad4 -Author: Guus Sliepen -Date: Sat Jul 21 16:26:55 2012 +0200 - - Use backslashes on Windows. - - Although Windows itself supports the forward slash, some programs may not. - -commit 09a8ff649cc7aa51d291c89e1556526a6265cc81 -Author: Guus Sliepen -Date: Sat Jul 21 15:58:16 2012 +0200 - - Don't try to mkdir(CONFDIR) on Windows when there is a registry key for tinc. - -commit ed8ce60845dc0568840c64c692838136f342fa54 -Author: Guus Sliepen -Date: Sat Jul 21 15:51:15 2012 +0200 - - Fix crash when no netname is specified. - -commit 7303b512b0e4f0d9cbc3236e846b2618f527b830 -Author: Guus Sliepen -Date: Sat Jul 21 15:50:50 2012 +0200 - - Fix some compiler warnings. - -commit 33521eabd4501b4add35468618453ac4f76311f3 -Author: Guus Sliepen -Date: Sat Jul 21 15:15:04 2012 +0200 - - Have tincd and tincctl use the same method of determining netname. - -commit 1d322d2eda8223f21b0c00381af34b94054f251a -Author: Guus Sliepen -Date: Sat Jul 21 15:02:44 2012 +0200 - - Add a newline to a configuration file if it is missing. - -commit dea722c4aca9a8cfa463807d279aa10cc6a0fc64 -Author: Guus Sliepen -Date: Sat Jul 21 15:02:17 2012 +0200 - - Add some checks when changing configuration. - -commit cc0c35267f8fac4f82622ff73474ed1e2d3a1e36 -Author: Guus Sliepen -Date: Sat Jul 21 14:19:23 2012 +0200 - - Call event_init() after detaching. - - Otherwise, the call to daemon() could close filedescriptors in use by libevent - itself; for example if it uses kqueue or epoll instead of a select() or poll() - backend. - -commit 4e0fc52197546bbf8a0be7af946f4b569e13048c -Author: Guus Sliepen -Date: Sat Jul 21 13:53:22 2012 +0200 - - Fix various compiler warnings. - -commit b161088b35fad1d284855f6434a895a20e34a250 -Author: Guus Sliepen -Date: Sat Jul 21 13:38:14 2012 +0200 - - BSD make doesn't like $<. - -commit 98a72d686983178f71cd2bf336c1f3d5c647f1e7 -Author: Guus Sliepen -Date: Sat Jul 21 13:02:35 2012 +0200 - - Make sure sptps.h and info.h are in the tarball. - -commit 5eeed38b8eb15f4c0464675b7d8c7722bc8be168 -Author: Guus Sliepen -Date: Sat Jul 21 12:51:53 2012 +0200 - - Make sure tinc compiles on Windows. - -commit 1d4590ca5cae09ea3b7a7e80355639e20861d349 -Author: Guus Sliepen -Date: Fri Jul 20 20:35:07 2012 +0200 - - Prefer routes with lower weight as long as they do not increase the number of hops. - - This should improve traffic to nodes that are not directly reachable somewhat. - -commit 4c8ead98743254be97c830e942f0cc53539d780c -Author: Guus Sliepen -Date: Fri Jul 20 20:01:29 2012 +0200 - - Allow more configuration variables to be changed when reloading configuration. - - In particular, Subnets may be added or removed from the local node on the fly. - -commit c678e7c4fb52d93350eafaed0f666018ed469e10 -Author: Guus Sliepen -Date: Fri Jul 20 19:59:47 2012 +0200 - - Split setup_myself() into two functions, one for reloading configuration. - -commit 4591e96c76914795aaae317c067f16abc22fb2e0 -Author: Guus Sliepen -Date: Fri Jul 20 17:29:16 2012 +0200 - - Never remove items from cmdline_conf. - - We should treat cmdline_conf as const, so we can call read_config_options() - more than once with prefix = NULL. - -commit 68a20876d0c4a6c370064d78786dd9f2aa6273cb -Author: Guus Sliepen -Date: Fri Jul 20 01:02:51 2012 +0200 - - Use minor protocol version to determine whether to use ECDH key exchange between nodes. - -commit 76a3ada4eb4032172c3d780915a07680f9954d42 -Author: Guus Sliepen -Date: Tue Jul 17 18:05:55 2012 +0200 - - Put minor protocol version in connection options so other nodes can see it. - - This allows two nodes that do not have a meta-connection with each other see - which version they are. - -commit 68de7b481e54d6a7c573d9a2d61f76d4d3a6b2f9 -Author: Guus Sliepen -Date: Mon Jul 16 18:49:39 2012 +0200 - - When exporting configuration files, don't copy Name variables. - - These interfere with tincctl import. Besides, host configuration files should - not contain Name at all. - -commit c52c46f8717aac6904f32766d774fa3fdf9611d8 -Author: Guus Sliepen -Date: Mon Jul 16 16:48:24 2012 +0200 - - Add an easy way to export and import host configuration files. - -commit 6319dc9dde3b328ba800f25a6bb4cf303d27f664 -Author: Guus Sliepen -Date: Mon Jul 16 01:14:08 2012 +0200 - - Strip default subnet weight from output. - -commit 74646a4afa6557a0363cc85e0a95d578d4ab0ac2 -Author: Guus Sliepen -Date: Mon Jul 16 01:09:47 2012 +0200 - - Give an error message when tincctl info cannot parse the given subnet or address. - -commit 53735a9d964579829d089f4b7572aef50c4e1468 -Author: Guus Sliepen -Date: Mon Jul 16 01:05:25 2012 +0200 - - "tincctl info" gives more human readable information about nodes or subnets. - -commit 3c7003893fe2f82023d0d4f54b488bb7a16d0007 -Author: Guus Sliepen -Date: Mon Jul 16 00:52:50 2012 +0200 - - Move all functions related to subnet parsing to subnet_parse.c. - -commit e72e6febfeddbd4354560388c8e0e125a8017909 -Author: Guus Sliepen -Date: Sun Jul 15 22:53:03 2012 +0200 - - Fix tincctl dump. - -commit 9be8980a2bb6245da017270f85bd6da186fb433b -Author: Guus Sliepen -Date: Sun Jul 15 21:17:10 2012 +0200 - - Let tincctl ignore tincd options, so they will be passed on. - -commit 36dee4c539521578005eed5e58b4803b73f0c889 -Author: Guus Sliepen -Date: Sun Jul 15 21:15:35 2012 +0200 - - Fix tincctl start. - -commit 439069bda62b25baaabeb765ac0557efa57b6cfb -Author: Guus Sliepen -Date: Sun Jul 15 20:59:17 2012 +0200 - - Have tincctl notify a running tincd of configuration file changes. - -commit eb01fd96258e5f99be0e4930eac04e5487a108a0 -Author: Guus Sliepen -Date: Sun Jul 15 20:37:38 2012 +0200 - - Add an easy way to edit a configuration file. - -commit cedfeccb247abb00063316068d7d2ade880f9d09 -Author: Guus Sliepen -Date: Sun Jul 15 20:22:21 2012 +0200 - - Stricter checks for node names. - -commit 03f72c6173f27198e2e68227cb41e00f8ec4ddc9 -Author: Guus Sliepen -Date: Sun Jul 15 18:16:35 2012 +0200 - - Allow configuration variables to be added/removed using tincctl. - -commit dd102efd24d847c41890adfcc7ce6d9d2592dcdb -Author: Guus Sliepen -Date: Sun Jul 15 15:46:16 2012 +0200 - - Put every command in its own function. - -commit a444ec396456a25546a4ab3d185c7fb5e4bb7ae3 -Author: Guus Sliepen -Date: Sun Jul 15 14:49:36 2012 +0200 - - "tincctl init" creates initial directory structure, tinc.conf and keypairs. - -commit 268c8545aaf83b7433f43402f5c77e39e20006ef -Merge: bce1777 f13fd8c -Author: Guus Sliepen -Date: Sat Jul 14 15:13:21 2012 +0200 - - Merge branch 'master' into 1.1 - -commit f13fd8c35068cd1f776e33362dcac40be9499035 -Author: Guus Sliepen -Date: Thu Jul 12 11:32:08 2012 +0200 - - Update THANKS file. - -commit 2eb0043e1352944b1113c1f7e40f37dffac0021d -Author: Guus Sliepen -Date: Thu Jul 12 11:30:56 2012 +0200 - - Document how to load the tap driver on FreeBSD. - -commit ae8c0b65d8f97942d7eff5f96344f781b8dec35d -Author: Guus Sliepen -Date: Thu Jul 12 11:25:11 2012 +0200 - - Use /dev/tap0 by default on FreeBSD and NetBSD when using Mode = switch. - -commit bce177767d521b47efd458c5cd570959a98d940d -Author: Guus Sliepen -Date: Tue Jun 26 14:22:57 2012 +0200 - - Fix crash when handling the ALRM signal. - - In retry() the function do_outgoing_connection() is called, which can delete - items from the connection_tree, so when walking the tree we must first save the - pointer to the next item. - -commit 19be9cf7150858311f7898fa3fb525d692d02f64 -Merge: 62b61a1 00e71ec -Author: Guus Sliepen -Date: Tue Jun 26 13:24:20 2012 +0200 - - Merge branch 'master' of git://tinc-vpn.org/tinc into 1.1 - - Conflicts: - NEWS - README - configure.in - lib/utils.c - src/linux/device.c - src/meta.c - src/net.h - src/net_setup.c - src/net_socket.c - src/protocol.c - src/protocol_auth.c - src/tincd.c - -commit 00e71ece25070dc919f9bc0696e4ff3a387360d0 -Author: Guus Sliepen -Date: Mon Jun 25 19:45:51 2012 +0200 - - Releasing 1.0.19. - -commit 236b0ba4ebba01e22e382e79897100338a039bbb -Author: Guus Sliepen -Date: Mon Jun 25 19:03:54 2012 +0200 - - Fix crash when using Broadcast = direct. - -commit 0a84f9cb8f52f2d2b4f03a5ad5ef9dfcd3509033 -Author: Guus Sliepen -Date: Mon Jun 25 19:01:51 2012 +0200 - - Fix compiler warnings. - -commit 62ee9b776d45af41c8b040ad86e50ba8f6f8e6c4 -Author: Guus Sliepen -Date: Mon Jun 25 15:01:42 2012 +0200 - - #include on Windows. - - MinGW complained about it not being included. - -commit c0af4c37d2046ffb3e07dd62f266a4fb99ea5614 -Author: Guus Sliepen -Date: Mon Jun 25 15:00:24 2012 +0200 - - Small fixes in proxy code. - -commit 62b61a1b7c2382b1bade142b3a41a9b27c1fd40d -Author: Guus Sliepen -Date: Sun May 13 22:16:42 2012 +0200 - - Don't forget to send a newline when forwarding requests. - -commit 42a8158b1dca6ee4ec1707176199cc36c26da7af -Author: Michael Tokarev -Date: Fri May 4 16:41:47 2012 +0400 - - add (errnum) in front of windows error messages - - On localized, non-English versions of windows, it is - common to have two active charsets -- for console applications - and for GUI applications, together with localized error messages - returned by windows. But two charsets are rarely compatible, - so sending the same byte sequence to console and to windows - event log makes one or another to be unreadable. So at least - include the error number, this way it will be possible to - lookup the actual error test using external ways. - - Signed-off-by: Michael Tokarev - -commit 58007d7efa3940c863c5a398f8b257a686ce37ba -Author: Guus Sliepen -Date: Tue May 8 16:44:15 2012 +0200 - - Always pass request strings to other functions as const char *. - -commit 291a59b5b732de084e392daea1433b1fdb9fbfd5 -Author: Sven-Haegar Koch -Date: Sun Apr 22 03:44:28 2012 +0200 - - free_connection_partially(): also reset remote protocol version infos - - The used remote protocol can change between two reconnects, aka if - the remote side has enabled/disabled for example their ExperimentalProtocols - setting. - -commit 32e5c5bb7c2c9127274247cb74cffa7345b04fad -Author: Sven-Haegar Koch -Date: Sun Apr 22 03:05:29 2012 +0200 - - Silence SPTPS log messages, reduce them from DEBUG_ALWAYS to DEBUG_META. - -commit c78bb143030162f0c820f08c87808e157c014a07 -Author: Sven-Haegar Koch -Date: Sun Apr 22 02:55:06 2012 +0200 - - terminate_connection(): delete non-outgoing (aka incoming) connections. - -commit 8b9e5af0d93069a81ce2ebed9899eedf3b7b184b -Author: Sven-Haegar Koch -Date: Sat Apr 21 03:44:24 2012 +0200 - - Label control connections for log output as "", not "". - -commit d3f4cf59ca917386e7c6358a98adbe3b8e9ce87a -Author: Sven-Haegar Koch -Date: Sat Apr 21 01:59:01 2012 +0200 - - free_connection_partially(): Avoid possible use-after-free for c->hischallenge - -commit 7a6ca7a993e5907497d97fef09e375698dde182f -Author: Sven-Haegar Koch -Date: Sat Apr 21 01:51:36 2012 +0200 - - terminate_connection(): only kill c->node->connection if it is pointing - to the same connection - -commit a96c4f016c9fff2392d85f762e16f5430c0b6463 -Author: Sven-Haegar Koch -Date: Fri Apr 20 00:24:38 2012 +0200 - - terminate_connection(): Avoid use-after-free and double-free for - already freed edge structure. - -commit 5c0dd104f94519c3cb50e9ca44227656c5adc7ae -Author: Guus Sliepen -Date: Thu Apr 19 15:56:08 2012 +0200 - - Document new proxy types. - -commit 5ae19cb0bb8dd6be1e9bcd560bb051f496a373ec -Author: Guus Sliepen -Date: Thu Apr 19 15:18:31 2012 +0200 - - Add support for proxying through an external command. - - Proxy type "exec" can be used to have an external script or binary set - up an outgoing connection. Standard input and output will be used to - exchange data with the external command. The variables REMOTEADDRESS and - REMOTEPORT are set to the intended destination address and port. - -commit fb5588856fa4dd6f140c72f7360302fe85b20c75 -Author: Guus Sliepen -Date: Thu Apr 19 14:10:54 2012 +0200 - - Add support for SOCKS 5 proxies. - - This only covers outgoing TCP connections, and supports only - username/password authentication or no authentication. - -commit b58d95eb29662bce4388f95dbc5762b9e2999806 -Author: Guus Sliepen -Date: Wed Apr 18 23:19:40 2012 +0200 - - Add basic support for SOCKS 4 and HTTP CONNECT proxies. - - When the Proxy option is used, outgoing connections will be made via the - specified proxy. There is no support for authentication methods or for having - the proxy forward incoming connections, and there is no attempt to proxy UDP. - -commit 84531fb6e621959e06519fdbb7f2a8f7578f66bd -Author: Guus Sliepen -Date: Mon Apr 16 01:57:25 2012 +0200 - - Allow broadcast packets to be sent directly instead of via the MST. - - When the "Broadcast = direct" option is used, broadcast packets are not sent - and forwarded via the Minimum Spanning Tree to all nodes, but are sent directly - to all nodes that can be reached in one hop. - - One use for this is to allow running ad-hoc routing protocols, such as OLSR, on - top of tinc. - -commit 9ebb34f907e8a15cb71dd20b111270d80bad1e96 -Author: Guus Sliepen -Date: Mon Apr 16 01:16:59 2012 +0200 - - Update README to reflect that only OpenSSL is currently supported. - -commit a851d8a9f6e3b69ab75695d84471ff4d525341b7 -Author: Guus Sliepen -Date: Mon Apr 16 01:14:59 2012 +0200 - - Add autoconf checks for OpenSSL's elliptic curve functions. - -commit f8e15dfe8d155b5bdb1e39bf6b9af486606145e8 -Author: Sven-Haegar Koch -Date: Sat Apr 14 02:28:43 2012 +0200 - - ecdh & ecdsa: avoid some possible memory leaks in error conditions. - -commit 8792b9a9f343e751dc3cfd789db9528da609ba9f -Author: Sven-Haegar Koch -Date: Sat Apr 14 02:02:11 2012 +0200 - - Remove confusing error message for failed reading in ECDSA keys. - - Most likeley the error is that there just is no valid key inside the used - host file, and in this case errno just contains a random value from the - last previously failed call. - -commit a5bb6d40fb517aa175510ec179091e4f9ffaf6f6 -Author: Sven-Haegar Koch -Date: Sat Apr 14 02:29:32 2012 +0200 - - sptps_stop(): clear pointers after free to avoid double free. - - sptps_stop() may get called twice on some failed connection setups. - -commit 535a55100bb77f107c85361e9f72a194e92bc8bc -Author: Guus Sliepen -Date: Thu Mar 29 16:45:25 2012 +0100 - - Allow environment variables to be used for Name. - - When the Name starts with a $, the rest will be interpreted as the name of an - environment variable containing the real Name. When Name is $HOST, but this - environment variable does not exist, gethostname() will be used to set the - Name. In both cases, illegal characters will be converted to underscores. - -commit 1d9dacb1f26971e19463b5501c2410c57f780ecb -Merge: 86c2990 89f4574 -Author: Guus Sliepen -Date: Mon Mar 26 19:06:39 2012 +0100 - - Merge branch 'master' of git://tinc-vpn.org/tinc into 1.1 - - Conflicts: - src/logger.c - src/net_setup.c - -commit 89f4574e0b1553c8e5dcbfc275e829a759b697f6 -Author: Guus Sliepen -Date: Mon Mar 26 14:46:09 2012 +0100 - - Add support for systemd style socket activation. - - If the LISTEN_FDS environment variable is set and tinc is run in the - foreground, tinc will use filedescriptors 3 to 3 + LISTEN_FDS for its listening - TCP sockets. For now, tinc will create matching listening UDP sockets itself. - - There is no dependency on systemd or on libsystemd-daemon. - -commit cc6aee784659bfbd21eb8d414e00a8f1a801cac4 -Author: Guus Sliepen -Date: Mon Mar 26 14:45:20 2012 +0100 - - Remove newline from log message. - -commit 16e6769feef21a5bf58f6022d990452987bb5efb -Author: Anthony G. Basile -Date: Mon Mar 26 06:29:40 2012 -0400 - - configure.in: fix AC_ARG_ENABLE and AC_ARG_WITH - - The current configure.in file does not correctly make use of these - macros. The resulting configure file will therefore enable an item - even if --disable-FEATURE is given. This patch restores the intended - behavior. - -commit 86c2990327fdf7ec1197aa73cb2b9a926a734db4 -Merge: d7bf63c b23681d -Author: Guus Sliepen -Date: Sun Mar 25 23:35:31 2012 +0100 - - Merge branch 'master' of git://tinc-vpn.org/tinc into 1.1 - - Conflicts: - NEWS - README - configure.in - src/Makefile.am - src/conf.c - src/conf.h - src/connection.c - src/net.c - src/tincd.c - -commit b23681dddb8987571f04d46fc14f0ba012a7929c -Author: Guus Sliepen -Date: Sun Mar 25 22:54:36 2012 +0100 - - Support :: in IPv6 Subnets. - -commit 482c6119a7ae80f320e5b519ef2e785e04a77b8e -Author: Guus Sliepen -Date: Sun Mar 25 15:32:26 2012 +0100 - - Releasing 1.0.18. - -commit 64c657b32d1eb34eb669c6d5b0ec26c1a643b194 -Author: Guus Sliepen -Date: Sun Mar 25 15:30:58 2012 +0100 - - Mark DecrementTTL option experimental. - -commit f71ce341800739c7cdee01d7cf025e7492da22ac -Author: Guus Sliepen -Date: Sun Mar 25 15:17:50 2012 +0100 - - Fix return type of vde_recv() as well. - - In this case it is not really necessary as the conversion to int will already - take care of ensuring the return value is treated as signed. - -commit 6225b1884a25af4debc2d0821a4c377ddbaec696 -Author: Guus Sliepen -Date: Sun Mar 25 14:55:56 2012 +0100 - - Document OpenBSD "ifconfig link0" and Linux "ip tuntap" commands. - -commit 399835385380d485416d6d59a8f27ce71f1db644 -Author: Guus Sliepen -Date: Sun Mar 25 14:46:50 2012 +0100 - - Fix some more compiler warnings. - -commit cfe6558d4ba4f572311aeafd62737f6f2692ad86 -Author: Guus Sliepen -Date: Sun Mar 25 14:00:21 2012 +0100 - - Fix return value type of vde_send(). - - The libvdeplug_dyn.h header file incorrectly declares the return type of - vde_send() to size_t, while in reality it is ssize_t. - -commit 95968c67f9df9102ddbce5b7c8d34107989ad51a -Author: Guus Sliepen -Date: Sun Mar 25 13:58:14 2012 +0100 - - Fix compiler warnings. - -commit e2d1b0b899ef66cd7ff227549e58b96c292f784e -Author: Guus Sliepen -Date: Sun Mar 25 13:42:10 2012 +0100 - - Allow scoped addresses to be used for IPv6 multicast socket. - -commit 251204063255d95910f9a079015e2f9b428fd983 -Author: Guus Sliepen -Date: Sun Mar 25 13:40:55 2012 +0100 - - Add #ifdefs in case not all platforms support IPv4 and IPv6 multicast. - -commit b5e3bf1a85462f0c41638c11305d28f87af24395 -Author: Guus Sliepen -Date: Fri Mar 23 13:18:36 2012 +0100 - - Set default value of DecrementTTL to "no". - - Decrementing the TTL causes IPv6 to fail when Mode = switch, and there may be - other unforeseen side-effects. - -commit c373de2e9812700c0568640727ad917b6fc7d758 -Author: Guus Sliepen -Date: Wed Mar 21 17:00:53 2012 +0100 - - Add support for multicast communication with UML/QEMU/KVM. - - DeviceType = multicast allows one to specify a multicast address and port with - a Device statement. Tinc will then read/send packets to that multicast group - instead of to a tun/tap device. This allows interaction with UML, QEMU and KVM - instances that are listening on the same group. - -commit a7dbb50c23f447a23b543c92ec096ff178bc2de3 -Author: Guus Sliepen -Date: Wed Mar 21 13:20:15 2012 +0100 - - Allow a port to be specified in BindToAddress statements. - - This can be used to let tinc listen on multiple ports for incoming connections. - -commit 80e15d8b96e5313b33c91003b1f75d7f6db9924e -Author: Guus Sliepen -Date: Tue Mar 20 23:49:16 2012 +0100 - - Always try next Address when an outgoing connection fails to authenticate. - - When making outgoing connections, tinc goes through the list of Addresses and - tries all of them until one succeeds. However, before it would consider - establishing a TCP connection a success, even when the authentication failed. - This would be a problem if the first Address would point to a hostname and port - combination that belongs to the wrong tinc node, or perhaps even to a non-tinc - service, causing tinc to endlessly try this Address instead of moving to the - next one. - - Problem found by Delf Eldkraft. - -commit d7bf63c63ab397cf3e5ca4a065922364925788e7 -Author: Guus Sliepen -Date: Sun Mar 18 21:24:46 2012 +0100 - - Make sure the signature also covers the session label. - -commit 42a0b61076d5d0f6391f0dd5c2c400b8fb89c5c5 -Author: Guus Sliepen -Date: Sun Mar 18 20:38:48 2012 +0100 - - Start documenting the SPTPS protocol. - -commit d756bb92ed52d5b1ecdd42af32f11f733db64d91 -Author: Guus Sliepen -Date: Sun Mar 18 17:46:30 2012 +0100 - - Don't send an ACK message after the first key exchange in the SPTPS protocol. - -commit c970ecdd75d4e7b3203a788f28b6e40cd532759b -Author: Guus Sliepen -Date: Sun Mar 18 17:42:43 2012 +0100 - - Test SPTPS messages sent while key renegotation is in progress. - -commit 3a4fe104a06b73fd19c550546e7c65a59ff2afe3 -Author: Guus Sliepen -Date: Sun Mar 18 16:42:02 2012 +0100 - - Add datagram mode to the SPTPS protocol. - - * Everything is identical except the headers of the records. - * Instead of sending explicit message length and having an implicit sequence - number, datagram mode has an implicit message length and an explicit sequence - number. - * The sequence number is used to set the most significant bytes of the counter. - -commit 03e06fd43aff73b4a5c9d367968a1279371ae252 -Author: Guus Sliepen -Date: Sun Mar 18 16:41:13 2012 +0100 - - Allow CTR mode counter to be set to a specific value. - -commit 28a1501b9a8b4c730f7f965d6b2e8fc50feba261 -Author: Guus Sliepen -Date: Sat Mar 10 13:31:36 2012 +0100 - - Releasing 1.0.17. - -commit 4712d8f92e63e86e835ffb624d6399343ee568ea -Author: Guus Sliepen -Date: Sat Mar 10 13:23:08 2012 +0100 - - Update copyright notices. - -commit 5b0f5ad958d6db4e73aebc5ee6c608cdae81b7b5 -Author: Guus Sliepen -Date: Thu Mar 8 23:23:39 2012 +0100 - - Make sure disabling old RSA keys works on Windows. - - Seeking in files and rewriting parts of them does not seem to work properly on - Windows. Instead, when old RSA keys are found when generating new ones, the - file containing the old keys is copied to a temporary file where the changes - are made, and that file is renamed back to the original filename. On Windows, - we cannot atomically replace files with a rename(), so we need to move the - original file out of the way first. If anything fails, the new code will warn - that the user has to solve the problem by hand. - -commit 2f1c337c541fcb7e2c62aeeab245ff7a43eb51a5 -Author: Guus Sliepen -Date: Thu Mar 8 22:19:20 2012 +0100 - - Add missing ICMP6 message type definitions. - -commit 40c28589328a2aa96c2ce1419c5d90616c758b3d -Merge: 8ac096b 9dea33f -Author: Guus Sliepen -Date: Thu Mar 8 21:15:08 2012 +0100 - - Merge branch 'master' of git://tinc-vpn.org/tinc into 1.1 - - Conflicts: - src/net_packet.c - -commit 9dea33f5301119dd4423eb962956cf2d246af3f3 -Author: Guus Sliepen -Date: Wed Mar 7 10:40:06 2012 +0100 - - Accept Subnets passed with the -o option when StrictSubnets = yes. - -commit 63f8303a5dc1758876451a580a8317dbc3d295d6 -Author: Guus Sliepen -Date: Fri Mar 2 16:09:58 2012 +0100 - - Only log errors sending UDP packets when debug level >= 5. - - Since tinc will fall back to TCP or route via another node, it is not necessary - to log such errors unconditionally. - -commit 8ac096b5bf9da1b3961a3ac4a03d083629222a63 -Author: Guus Sliepen -Date: Sun Feb 26 18:37:36 2012 +0100 - - Allow log messages to be captured by tincctl. - - This allows tincctl to receive log messages from a running tincd, - independent of what is logged to syslog or to file. Tincctl can receive - debug messages with an arbitrary level. - -commit a1bd3a291379492c8ffecd53792065dc20a28c79 -Author: Guus Sliepen -Date: Sun Feb 26 16:56:53 2012 +0100 - - Don't close control connections when handling a reload command. - - Because this would terminate the connection while the control message - handler was still running, it would lead to a segmentation fault later - on. - -commit 483c5dcfb43719e5fd50902641252e28a04fd74e -Merge: 344d6b9 ae52496 -Author: Guus Sliepen -Date: Sun Feb 26 16:27:13 2012 +0100 - - Merge branch 'master' of git://tinc-vpn.org/tinc into 1.1 - -commit ae5249610954af17c68c547bb1b45ad286ad647e -Author: Guus Sliepen -Date: Sun Feb 26 16:23:02 2012 +0100 - - Only use broadcast at the start of the PMTU discovery phase. - - For local peer discovery, only a handful of packets are necessary for - peers to detect each other. - -commit 344d6b9ac3c795f2942e457c1ab38b1dac5f7242 -Author: Guus Sliepen -Date: Sun Feb 26 12:39:46 2012 +0100 - - Let tincctl use the NETNAME environment variable if no -n option is given. - - This allows administrators who frequently want to work with one tinc - network to omit the -n option. Since the NETNAME variable is set by - tincd when executing scripts, this makes it slightly easier to use - tincctl from within scripts. - -commit 84570275acd84628586a6ca591a283d074ca10f0 -Author: Guus Sliepen -Date: Sun Feb 26 12:33:16 2012 +0100 - - Ensure all SPTPS functions are prefixed with sptps_. - -commit 8b1ad6f76f821648079818f6ff018bbc33b9d9e9 -Author: Guus Sliepen -Date: Sat Feb 25 23:03:09 2012 +0100 - - Go back to breadth first search for path finding. - - If 1.1.x nodes using Dijkstra's algorithm are mixed with 1.0.x nodes using BFS, - then routing loops can occur. - -commit 36623e15a1c8685e5d8730345c1a7f9c93710fef -Merge: 65d6f02 5140656 -Author: Guus Sliepen -Date: Sat Feb 25 22:52:57 2012 +0100 - - Merge branch 'master' of git://tinc-vpn.org/tinc into 1.1 - -commit 5140656de6bcfda72951a7827b05414ce306e3ca -Author: Guus Sliepen -Date: Sat Feb 25 22:11:30 2012 +0100 - - Stricter checks against routing loops. - - If a packet that had to be sent via an intermediate hop, and that intermediate - hop was the one that sent the packet, we drop it. - -commit f1d5eae643cdf537ef357f10f2da8ff83bdf32b4 -Author: Guus Sliepen -Date: Sat Feb 25 21:46:18 2012 +0100 - - Don't send ICMP Time Exceeded messages for other Time Exceeded messages. - - That would be silly. - -commit 65d6f023c46ac3a087f59b60762f87c869783f21 -Author: Guus Sliepen -Date: Sat Feb 25 18:25:21 2012 +0100 - - Use SPTPS when ExperimentalProtocol is enabled. - -commit efd21e232dced3225f119aeb7a585ebf55b7cf77 -Author: Guus Sliepen -Date: Sat Feb 25 15:18:15 2012 +0100 - - Apply HMAC after encryption. - -commit f5dc136cfd7a3a195b75f7174722734e25f30fd9 -Merge: 3fba801 5a28aa7 -Author: Guus Sliepen -Date: Thu Feb 23 13:26:01 2012 +0100 - - Merge branch 'master' of git://tinc-vpn.org/tinc into 1.1 - - Conflicts: - src/net.c - src/net_packet.c - src/net_socket.c - -commit 5a28aa7b8b0ab6237c2eab5f8b11253ea3ec5a05 -Author: Guus Sliepen -Date: Wed Feb 22 23:17:43 2012 +0100 - - Add LocalDiscovery option which tries to detect peers on the local network. - - Currently, this is implemented by sending IPv4 broadcast packets to the - LAN during path MTU discovery. - -commit 8e717ddb602f01f656369106ec0398efbe9ca4a4 -Author: Guus Sliepen -Date: Wed Feb 22 14:37:56 2012 +0100 - - Pass index into listen_socket[] to handle_incoming_vpn_data(). - -commit 3fba80174dbe29bcfe0d121a2a1d2e61be5ee57b -Merge: fba1c85 65e8e06 -Author: Guus Sliepen -Date: Wed Feb 22 14:23:59 2012 +0100 - - Merge branch 'master' of git://tinc-vpn.org/tinc into 1.1 - - Conflicts: - NEWS - README - configure.in - doc/tincd.8.in - src/Makefile.am - src/bsd/device.c - src/connection.c - src/connection.h - src/cygwin/device.c - src/device.h - src/dropin.h - src/linux/device.c - src/mingw/device.c - src/net.c - src/net_packet.c - src/net_setup.c - src/net_socket.c - src/process.c - src/protocol.c - src/protocol_key.c - src/raw_socket_device.c - src/route.c - src/solaris/device.c - src/tincd.c - src/uml_device.c - -commit fba1c85f44edfc56c19d35332b1eb825179a8bb6 -Author: Guus Sliepen -Date: Tue Feb 21 23:19:51 2012 +0100 - - Remove useless warning about signature length being shorter than expected. - -commit cb6cbf452f6183a00746afc5bff8f63f3f55235f -Author: Guus Sliepen -Date: Tue Feb 21 23:17:12 2012 +0100 - - Use only one hash algorithm (SHA512) in the PRF. - - On some platforms, OpenSSL by default does not support the Whirlpool algorithm. - -commit 65e8e06c6dc7349b11c3c1e8f4071b51e2994c65 -Author: Nick Hibma -Date: Tue Feb 21 15:26:58 2012 +0100 - - Add missing ICMP message type definitions. - -commit ac48c4ee8c09c8144f830cb66386b9dbe7298440 -Author: Guus Sliepen -Date: Tue Feb 21 14:06:55 2012 +0100 - - Fix check for raw socket support. - - Also, move some variables so there are no compiler warnings about unused - variables when there is no support for raw sockets. - -commit d9ad3d313d96d30ef45cd53367dff9a855a396d4 -Author: Guus Sliepen -Date: Tue Feb 21 13:31:21 2012 +0100 - - Fix a bug that caused tinc to ignore all but the last listening socket. - -commit 46506b7aaf6c6a8a85561c38fdb9c95eae21aa75 -Author: Guus Sliepen -Date: Tue Feb 21 13:13:40 2012 +0100 - - Document the command line flag -o and provide --option as well. - -commit 7d76e287598c8c18cadfb5818046d9dd1b0ad881 -Author: Guus Sliepen -Date: Tue Feb 21 11:39:21 2012 +0100 - - Move initialization of char *priority up to prevent freeing an uninitialized pointer. - -commit 8420a0c8bde1781db04dd2436eb9d5dca5a1732a -Author: Guus Sliepen -Date: Mon Feb 20 17:19:00 2012 +0100 - - Allow disabling of broadcast packets. - - The Broadcast option can be used to cause tinc to drop all broadcast and - multicast packets. This option might be expanded in the future to selectively - allow only some broadcast packet types. - -commit ea415ccc1690d6e5864a7500977b181e5c8faafe -Author: Guus Sliepen -Date: Mon Feb 20 17:12:48 2012 +0100 - - Rename connection_t *broadcast to everyone. - -commit cff5a844a3e6b494f4a4f6eb5b48a84780f2d0e5 -Author: Guus Sliepen -Date: Mon Feb 20 16:52:53 2012 +0100 - - Don't bind outgoing TCP sockets anymore. - - The code introduced in commit 41a05f59ba2c3eb5caab555f096ed1b9fbe69ee3 is not - needed anymore, since tinc has been able to handle UDP packets from a different - source address than those of the TCP packets since 1.0.10. When using multiple - BindToAddress statements, this code does not make sense anymore, we do want the - kernel to choose the source address on its own. - -commit 0233b1d710222cb09be0cbd08c1297e3ece38a9f -Author: Guus Sliepen -Date: Mon Feb 20 16:34:02 2012 +0100 - - Decrement TTL of incoming packets. - - Tinc will now, by default, decrement the TTL field of incoming IPv4 and IPv6 - packets, before forwarding them to the virtual network device or to another - node. Packets with a TTL value of zero will be dropped, and an ICMP Time - Exceeded message will be sent back. - - This behaviour can be disabled using the DecrementTTL option. - -commit 6289859ab365dc1c0d420323174418b316b14502 -Author: Guus Sliepen -Date: Mon Feb 20 15:44:52 2012 +0100 - - Only compile raw socket code when it is supported on that platform. - -commit d1dcdf8eb6f800704be426b1ce6f6c1a8e65ba0d -Merge: 1b2846d 3b1fad0 -Author: Guus Sliepen -Date: Sat Feb 18 14:31:08 2012 +0100 - - Merge branch 'master' of black:tinc - -commit 3b1fad04de6bed2f284fdf3d5b27d4162aeebc8c -Author: Guus Sliepen -Date: Sat Feb 18 14:37:52 2012 +0100 - - Allow setting DeviceType to tun or tap on Linux. - -commit 6455654d26d204cea4bbc102e5bd6550b7fff7a7 -Author: Guus Sliepen -Date: Sat Feb 18 11:48:21 2012 +0100 - - Send packets back using the same socket as they were received on. - -commit 1b2846d907adfc8472fc9da0c951c3243c7ee143 -Merge: 9f6a96a 6455654 -Author: Guus Sliepen -Date: Sat Feb 18 11:43:00 2012 +0100 - - Merge branch 'master' of black:tinc - -commit 9f6a96af3939bd2de410ce346a8c8fbcf93e7c9b -Author: Guus Sliepen -Date: Fri Feb 17 16:25:00 2012 +0100 - - Allow multiple BindToAddress statements. - -commit 708314df2f61675d0f54e541c9fff62ac1f433b5 -Author: Guus Sliepen -Date: Fri Feb 17 16:13:38 2012 +0100 - - Set FD_CLOEXEC flag on all sockets. - - Scripts called by tinc would inherit its open filedescriptors. This could - be a problem if other long-running daemons are started from those scripts, - if those daemons would not close all filedescriptors before going into the - background. - - Problem found and solution suggested by Nick Hibma. - -commit 1f00111e94b2f9a4beb9608b1e03a5e73c9c5d21 -Author: Guus Sliepen -Date: Mon Dec 26 23:11:27 2011 +0100 - - Fix a few small memory leaks. - -commit b50d6a7f2ad98239018bc5ce7a5739e3bf4f50f7 -Author: Guus Sliepen -Date: Mon Dec 26 23:04:40 2011 +0100 - - Fix compiler warnings. - -commit 178e52f76ef4ba40748c13ea7e518837394d6dbc -Author: Guus Sliepen -Date: Sun Dec 4 01:20:59 2011 +0100 - - Allow linking with multiple device drivers. - - Apart from the platform specific tun/tap driver, link with the dummy and - raw_socket devices, and optionally with support for UML and VDE devices. - At runtime, the DeviceType option can be used to select which driver to - use. - -commit 5672863e59e6a114ac6b66de98254b14266c0e61 -Author: Guus Sliepen -Date: Sat Dec 3 21:59:47 2011 +0100 - - Fix a few small memory leaks. - -commit 52ded09d1713b83222b56db7d29ff061aefb95e3 -Author: Guus Sliepen -Date: Sun Nov 27 12:13:16 2011 +0100 - - Add vde/device.c to the tarball. - -commit 2c7c87ec75c94d0b3cca9f7a5aeba34384f77cc1 -Author: Guus Sliepen -Date: Sun Nov 27 12:12:34 2011 +0100 - - Fix compilation of VDE and UML interfaces. - -commit 2a9060bba62d78f73da9b09ca791fe80993520fc -Author: Guus Sliepen -Date: Thu Oct 6 15:32:12 2011 +0200 - - Exchange ACK records to indicate switch to new keys. - - This allow application records to be sent while key renegotiation is still - happening. - -commit 3b5898078af1ab86797b3e24f2381131e6e702f7 -Author: Guus Sliepen -Date: Thu Oct 6 09:34:34 2011 +0200 - - Use counter mode encryption. - -commit a0f795ff5bd671ca10a7203e4234b37a12d8d1cd -Author: Guus Sliepen -Date: Thu Oct 6 09:33:09 2011 +0200 - - Add counter mode encryption. - -commit 67ff81ec16b8ab5f15d16efbedfecfaf0be17c13 -Author: Guus Sliepen -Date: Wed Oct 5 22:05:13 2011 +0200 - - Test corner cases in the SPTPS protocol. - - * Test zero-byte messages. - * Test maximum size (65535 byte) messages. - * Test different message types. - * Test key renegotiation. - -commit 30013511504e925729ebc67772205a74c4b8aeea -Author: Guus Sliepen -Date: Wed Oct 5 22:00:51 2011 +0200 - - Update SPTPS protocol. - - * Exchange nonce and ECDH public key first, calculate the ECDSA signature - over the complete key exchange. - * Make an explicit distinction between client and server in the signatures. - * Add more comments and replace some magic numbers by #defines. - - Thanks to Erik Tews for very helpful hints and comments! - -commit 810847248ae90140ee6f3e568add80aef88c3def -Author: Guus Sliepen -Date: Wed Oct 5 21:59:33 2011 +0200 - - Fix compiler warning. - -commit ddea7a23a66b8fee4942f2ce237dcabe02e17270 -Author: Guus Sliepen -Date: Tue Aug 30 20:49:48 2011 +0200 - - Return false instead of void when there is an error. - -commit e838289683c0039fac0ae6172d40b4177c17911b -Author: Guus Sliepen -Date: Tue Aug 30 19:56:56 2011 +0200 - - Prevent read_rsa_public_key() from returning an uninitialized RSA structure. - - In case the config file could not be opened a new but unitialized RSA structure - would be returned, causing a segmentation fault later on. This would only - happen in the case that the config file could be opened before, but not when - read_rsa_public_key() was called. This situation could occur when the --user - option was used, and the config files were not readable by the specified user. - -commit 5d4336e5429b88dcc53e80c00412e76a5269b384 -Author: Guus Sliepen -Date: Wed Aug 10 17:04:17 2011 +0200 - - Handle UDP packets with unknown source addresses properly. - - Probably due to a merge, the try_harder() function had duplicated the - rate-limiting code for detecting the sender node based on the HMAC of the - packet. This prevented this detection from running at all. The function is now - identical again to that in the 1.0 branch. - -commit bbc0ba9e87f76111529d6dc9cb00c0b9435b5858 -Author: Michael Tokarev -Date: Sun Aug 7 12:18:20 2011 +0400 - - use execvp() not execve() in tincctl start - - sometimes argv[0] will have directory-less name (when the - command is started by shell searching in $PATH for example). - For tincctl start we want the same rules to run tincd as for - tincctl itself (having full path is better but if shell does - not provide one we've no other choice). Previous code tried - to run ./tincd in this case, which is obviously wrong. - - This is a fix for the previous commit. - - Signed-off-by: Michael Tokarev - -commit a7556a9d2c943a6317d2dab66d9f742997f0d47a -Author: Michael Tokarev -Date: Sun Aug 7 12:05:07 2011 +0400 - - run tincd from the same directory as tincctl and pass all options to it - - For tincctl start, run tincd from dirname($0) not SBINDIR - - this allows painless alternative directory installation and - running from build directory too. - - Also while at it, pass the rest of command line to tincd, not - only options before "start" argument. This way it's possible - to pass options to tincd like this: - tincctl -n net start -- -d 1 -R -U tincuser ... - - And also add missing newline at the end of error message there. - - Signed-Off-By: Michael Tokarev - -commit 2696ad2cca73aee13e38f740d5530dc33e4a92e6 -Author: Michael Tokarev -Date: Sun Aug 7 11:25:03 2011 +0400 - - don't mention reload twice in tincctl help - - Signed-Off-By: Michael Tokarev - -commit 3d75dbc0880484ff6d2f689a9b981def3cd75b5e -Author: Guus Sliepen -Date: Sun Jul 24 15:44:51 2011 +0200 - - Start of "Simple Peer-To-Peer Security" protocol. - - Encryption and authentication of the meta connection is spread out over - meta.c and protocol_auth.c. The new protocol was added there as well, - leading to spaghetti code. To improve things, the new protocol will now - be implemented in sptps.[ch]. - - The goal is to have a very simplified version of TLS. There is a record - layer, and there are only two record types: application data and - handshake messages. The handshake message contains a random nonce, an - ephemeral ECDH public key, and an ECDSA signature over the former. After - the ECDH public keys are exchanged, a shared secret is calculated, and a - TLS style PRF is used to generate the key material for the cipher and - HMAC algorithm, and further communication is encrypted and authenticated. - - A lot of the simplicity comes from the fact that both sides must have - each other's public keys in advance, and there are no options to choose. - There will be one fixed cipher suite, and both peers always authenticate - each other. (Inspiration taken from Ian Grigg's hypotheses[0].) - There might be some compromise in the future, to enable or disable - encryption, authentication and compression, but there will be no choice - of algorithms. This will allow SPTPS to be built with a few embedded - crypto algorithms instead of linking with huge crypto libraries. - - The API is also kept simple. There is a start and a stop function. All - data necessary to make the connection work is passed in the start - function. Instead having both send- and receive-record functions, there - is a send-record function and a receive-data function. The latter will - pass protocol data received from the peer to the SPTPS implementation, - which will in turn call a receive-record callback function when - necessary. This hides all the handshaking from the application, and is - completely independent from any event loop or socket characteristics. - - [0] http://iang.org/ssl/hn_hypotheses_in_secure_protocol_design.html - -commit 0f2aa4bd8b698608876bec141c5aef1aa619730b -Author: Guus Sliepen -Date: Sat Jul 23 14:12:23 2011 +0200 - - Releasing 1.0.16. - -commit e16ead8dd9d4600664058069f0695832dfe068b2 -Author: Guus Sliepen -Date: Sat Jul 23 14:11:44 2011 +0200 - - Use usleep() instead of sleep(), MinGW complained. - -commit ff751903aa82bd6dd66a099f9c05dcdae9fc57f2 -Author: Guus Sliepen -Date: Wed Jul 20 08:19:18 2011 +0200 - - Don't abort() on low-level crypto errors, just return false. - - The abort() calls were accidentily left in for debugging. - -commit 2f4ccfe2473948372f7c9f14d9ffce1d77f5fd8c -Author: Guus Sliepen -Date: Tue Jul 19 21:11:11 2011 +0200 - - Fix tinc 1.0.x daemons connecting when ExperimentalProtocol = yes. - -commit f8d94f34fc5d7fe9ed4a076a2fd77eacbd83adca -Author: Guus Sliepen -Date: Sun Jul 17 20:09:08 2011 +0200 - - Releasing 1.1pre2. - -commit c259d552fa89c3e4a962d9adf2b237f24bc077da -Author: Guus Sliepen -Date: Sun Jul 17 20:06:06 2011 +0200 - - Add missing newline. - -commit f6020a5224c9c4c17c11c5f9d2c8441638ac04fc -Author: Guus Sliepen -Date: Sun Jul 17 20:01:24 2011 +0200 - - Write loopback address instead of "any" address in pidfile. - -commit 50fcfea127c9d2fdf8894498a9fdcc6fb3bbb2ce -Author: Guus Sliepen -Date: Sun Jul 17 19:34:01 2011 +0200 - - Flush output buffer in send_tcppacket(). - - This is mainly important for Windows, where the select() call in the - main thread is not being woken up when the tapreader thread calls - route(), causing a delay of up to 1 second before the output buffer is - flushed. This would cause bad performance when UDP communication is not - possible. - -commit 25091454da21941dd92375ddbee7dd6151343058 -Author: Guus Sliepen -Date: Sun Jul 17 19:23:52 2011 +0200 - - "tincctl stop" now removes the tinc service on Windows. - -commit c6c989cfa175154f4cd3830c5a77fbd2071f52af -Author: Guus Sliepen -Date: Sun Jul 17 18:02:56 2011 +0200 - - Fix declaration of usleep(). - -commit 18e9839dc861c368141bbbc9a963f719a83eba3e -Author: Guus Sliepen -Date: Sun Jul 17 10:59:54 2011 +0200 - - Ensure symlinked files do not end up in the tarball. - -commit fa4a01e4a27dd4b3a57077acbd0e69f95d55944a -Author: Guus Sliepen -Date: Sat Jul 16 22:38:50 2011 +0200 - - Use const pointer to source in base64 and hex routines. - -commit 574b380dfc75ef13ee4accba1f2416165c58a5a2 -Author: Guus Sliepen -Date: Sat Jul 16 22:38:22 2011 +0200 - - Use usleep() instead of sleep(), MinGW complained. - -commit 8efc8dc961865ceddb74cb36f0b4a2ebde39cc55 -Author: Guus Sliepen -Date: Sat Jul 16 21:44:17 2011 +0200 - - Update info manual. - -commit cff27a258f3b3a97b5d2e309c264eceea41dff3a -Author: Guus Sliepen -Date: Sat Jul 16 20:21:44 2011 +0200 - - Use ECDSA to sign ECDH key exchange for UDP session keys. - - The ECDSA public keys will also be included in the ANS_KEY requests, - but are only used when no ECDSA public key is known yet. - -commit 03ac48ea19914e4162f17a2fb0f742b99ae32499 -Author: Guus Sliepen -Date: Sat Jul 16 15:21:37 2011 +0200 - - Use the same logic as tinc 1.0.x for detecting two nodes with the same Name. - -commit 2ba61742d4c2ab82525efb806dc654a6d95d335e -Author: Guus Sliepen -Date: Sat Jul 16 15:15:29 2011 +0200 - - Use the correct direction flag when setting cipher keys. - - The flag was set incorrectly, but for most ciphers this does not have - any effect. AES in any of the block modes is picky about it though. - -commit be2fc8b0458b1e2ced3b5de410356d8d8639acff -Author: Guus Sliepen -Date: Sat Jul 16 10:47:35 2011 +0200 - - Make code to detect two nodes with the same Name less triggerhappy. - - First of all, if there really are two nodes with the same name, much - more than 10 contradicting ADD_EDGE and DEL_EDGE messages will be sent. - Also, we forgot to reset the counters when nothing happened. - - In case there is a ADD_EDGE/DEL_EDGE storm, we do not shut down, but - sleep an increasing amount of time, allowing tinc to recover gracefully - from temporary failures. - -commit 303dd1e70219a7542921f6e63d9391ab326d434f -Author: Guus Sliepen -Date: Wed Jul 13 22:52:52 2011 +0200 - - Fix compiler warnings. - -commit 791c1898ea8f92b07f1d79e90540c257ac38298d -Author: Guus Sliepen -Date: Wed Jul 13 22:29:30 2011 +0200 - - Remove unnecessary variables and functions. - -commit fec279a9c54ec8a13bd1ba4c7bec0d2a15454992 -Author: Guus Sliepen -Date: Tue Jul 12 23:43:12 2011 +0200 - - Make use of the improved hex and base64 functions. - - Also, use base64 for all EC related data, it is shorter and easy to - distinguish from the legacy protocol. - -commit 06b8271ed5d56c9bd3de459d95907d0ef4f0ea3c -Author: Guus Sliepen -Date: Tue Jul 12 22:54:49 2011 +0200 - - Make hexadecimal and base64 routines behave the same. - - The length parameter for the encoding functions is the length of the - binary input, and for the decoding functions it is the maximum size of - the binary output. - - The return value is always the length of the resulting output, excluding - the terminating NULL character for the encoding routines. - - All functions can encode and decode in-place. The encoding functions - will always write a terminating NULL character, and the decoding - functions will stop at a NULL character. - -commit c108c79a22118ef7246a3d7b3bc20e205e11d179 -Author: Guus Sliepen -Date: Mon Jul 11 22:14:06 2011 +0200 - - Don't use wildcards in filenames in configure.in. - -commit bbeab00f46a6c856573fe0d2b9b85bce35728403 -Author: Guus Sliepen -Date: Mon Jul 11 21:54:01 2011 +0200 - - Require ExperimentalProtocol = yes for new features, update documentation. - -commit d1cd3c81455ecb32149cbaa424b7870075b2b2fc -Author: Guus Sliepen -Date: Sun Jul 10 22:46:43 2011 +0200 - - Close meta connection socket after cleaning up event structures. - - Epoll doesn't like it when an already closed filedescriptor is being - removed, so we defer closing the socket until after all else is cleaned - up. - -commit 30ef2a981e1d62692b3a2363e0b3a0e8711d9604 -Author: Guus Sliepen -Date: Sun Jul 10 22:34:17 2011 +0200 - - Automatically exchange ECDSA keys and upgrade to new authentication protocol. - - If we don't have ECDSA keys for the node we connect to, set protocol_minor - to 1, to indicate this to the other end. This will first complete the - old way of authentication with RSA keys, and will then exchange ECDSA keys. - The connection will be terminated right afterwards, and the next attempt - will use ECDSA keys. - -commit 027228debee2ea6f31cd176e456c13d626380066 -Author: Guus Sliepen -Date: Sun Jul 10 21:02:34 2011 +0200 - - Free ECDSA and RSA structures when freeing a connection_t. - -commit 73863fab8ae1ecd8307aaeef486919cc76b85d63 -Author: Guus Sliepen -Date: Fri Jul 8 18:17:34 2011 +0200 - - Hash input before signing it with ECDSA. - -commit 8132be8fbd6c45be309c63a117f418ad12ced094 -Author: Guus Sliepen -Date: Thu Jul 7 22:30:55 2011 +0200 - - Very primitive ECDSA signed ECDH key exchange for the meta protocol. - - Nonces and hash of the ID requests should be included in the seed for the PRF. - -commit 210b5ceeeebdf742a74dcf95a0a13d69623ee001 -Author: Guus Sliepen -Date: Thu Jul 7 22:28:25 2011 +0200 - - Read ECDSA keys. - -commit 03582eb669494cb778ebea7b0fe3b1b841335750 -Author: Guus Sliepen -Date: Thu Jul 7 22:27:17 2011 +0200 - - Implement ECDSA sign and verify operations. - - Very basic at the moment, doesn't hash the input first, - and uses OpenSSL's DER encoded signature as output. - -commit 86d83bd9bd69e2129f4e4e8397f1c7e223685e2f -Author: Guus Sliepen -Date: Tue Jul 5 21:29:31 2011 +0200 - - Bump minor protocol to indicate ECDH capability for UDP session keys. - -commit 9708bbfa8e3094de8932a30b1d24c661558d8a03 -Author: Guus Sliepen -Date: Tue Jul 5 21:19:48 2011 +0200 - - Add a minor number to the protocol version. - -commit b99656d84a88dad7935d5981fcdb43a5b2bfa417 -Author: Guus Sliepen -Date: Mon Jul 4 07:51:47 2011 +0200 - - Round up the size of the secret parts after splitting it in two. - -commit 95e1cc36d320b47408ac3ec6f89df54e55a010d4 -Author: Guus Sliepen -Date: Sun Jul 3 23:44:43 2011 +0200 - - Add ECDSA key import. - -commit 1e2d9b08991861c8770aa2c5a73d86dc02e3067d -Author: Guus Sliepen -Date: Sun Jul 3 23:33:56 2011 +0200 - - Finish base64 decoding routine. - -commit 80b81c00b129b006981b76bdb734df3296317d6f -Author: Guus Sliepen -Date: Sun Jul 3 22:25:29 2011 +0200 - - Have tincctl generate ECDSA keys. - - The generate-keys command now generates both an RSA and an ECDSA keypair, - but one can generate-rsa-keys or generate-ecdsa-keys to just generate one type. - -commit 8ace7f3e5771957fbdda8b817fa26951d9d62c28 -Author: Guus Sliepen -Date: Sun Jul 3 22:15:00 2011 +0200 - - Add ECDSA key generation. - -commit 1d92dd62a786ecabbc05dfba5195f3f08e0f9585 -Author: Guus Sliepen -Date: Sun Jul 3 22:13:58 2011 +0200 - - Base64 encoding and decoding functions. - -commit c385d115331845e8a844322e66571d74d833e822 -Author: Guus Sliepen -Date: Sun Jul 3 22:13:34 2011 +0200 - - Cleanups in ECDH code. - -commit 895f868714f9422a757a95650345e0c662d12b49 -Author: Guus Sliepen -Date: Sun Jul 3 21:21:37 2011 +0200 - - No need to keep around pointers to EC_GROUP. - -commit ac163120d7f0300c8d555f76ace3368ce2ffa655 -Author: Guus Sliepen -Date: Sun Jul 3 16:30:49 2011 +0200 - - Proper use of PRF. - -commit 82f00ea07bffc10985ccb1a15723e6daa0ab4969 -Author: Guus Sliepen -Date: Sun Jul 3 15:59:49 2011 +0200 - - Use PRF. - -commit feb3f22fffa2620b9b11a509ce51ff9fa3be9418 -Author: Guus Sliepen -Date: Sun Jul 3 15:26:58 2011 +0200 - - Add PRF to derive key material from the ECDH shared secret. - - It is modelled after the pseudorandom function from RFC4346 (TLS 1.1), the only - significant change is the use of SHA512 and Whirlpool instead of MD5 and SHA1. - -commit 8dfa072733feab737cabf69f000c70657719826a -Author: Guus Sliepen -Date: Sun Jul 3 13:17:28 2011 +0200 - - Support ECDH key exchange. - - REQ_KEY requests have an extra field indicating key exchange version. - If it is present and > 0, the sender supports ECDH. If the receiver also - does, then it will generate a new keypair and sends the public key in a - ANS_KEY request with "ECDH:" prefixed. The ans_key_h() function will - compute the shared secret, which, at the moment,is used as is to set the - cipher and HMAC keys. However, this must be changed to use a proper KDF. - In the future, the ECDH key exchange must also be signed. - -commit ee8a214318fd6dbe6bc5d6b510896f30d92d46c6 -Author: Guus Sliepen -Date: Mon Jun 27 21:52:23 2011 +0200 - - Preliminary implementation of Elliptic Curve Diffie-Hellman Ephemeral key exchange. - -commit 6c21b5716b8e9e5ff5def8070f92b76a0f353cb0 -Author: Guus Sliepen -Date: Sun Jun 26 13:15:44 2011 +0200 - - Add manpage for tinc-gui. - -commit 4c934d0903a32e71ae83ffdf344957bd06b7164d -Author: Guus Sliepen -Date: Sun Jun 26 13:14:48 2011 +0200 - - Remove debug messages that were printed to stdout. - -commit e73052b05444679d922dbdf3d0c507873110957e -Author: Guus Sliepen -Date: Sun Jun 26 12:59:11 2011 +0200 - - Update documentation to mention pidfiles instead of controlcookies. - -commit 8c953b1bfef3c6ebee7c537c2c2f144807d0311a -Author: Guus Sliepen -Date: Sun Jun 26 12:58:50 2011 +0200 - - Don't react to escape character in tincctl top. - - Not only the ESC key generates an escape character, but many other keys - do as well, such as arrow keys. - -commit 27e6a89b155b171b0b026d5e24ee0cc68f43d010 -Author: Guus Sliepen -Date: Sun Jun 26 12:51:25 2011 +0200 - - Use pidfile in tinc-gui as well. - -commit 660f530a6ff733f96f81eefa69b38e2ea685f890 -Author: Guus Sliepen -Date: Sat Jun 25 22:20:39 2011 +0200 - - Really stable sorting of tincctl top output. - -commit 810766e1394f18b8709e9f0c75a41a2c348e3fad -Author: Guus Sliepen -Date: Sat Jun 25 21:38:59 2011 +0200 - - Add +git to the version string. - -commit ab4d289fafd1d391583935ab4c306f1f508ea1d0 -Author: Guus Sliepen -Date: Sat Jun 25 21:35:27 2011 +0200 - - Make pid files backwards compatible and add address of listening socket. - - The pid is now written first, so that a version 1.0.x tincd can be used to stop - a running version 1.1 tincd. Getsockname() is used to determine the address of - the first listening socket, so that tincctl can connect to the local tincd even - if AddressFamily = ipv6, or if BindToAddress or BindToInterface is used. - -commit a05fa7f88264599a43f9e411287e018259dc22b1 -Author: Guus Sliepen -Date: Sat Jun 25 21:21:36 2011 +0200 - - Rename controlcookie file to pidfile. - -commit c64f64b875879591873d68faf2d3cd8e9d644101 -Author: Guus Sliepen -Date: Sat Jun 25 21:16:13 2011 +0200 - - Don't call exit_control() if we didn't do init_control(). - -commit 3b237afbda86bc95703ed25386cc9a26695d4602 -Author: Guus Sliepen -Date: Sat Jun 25 20:20:07 2011 +0200 - - Re-add support for SIGALRM. - -commit 386c1aff08a3ce6e295931e2fcf4bfc607053ff0 -Author: Guus Sliepen -Date: Sat Jun 25 17:39:02 2011 +0200 - - Merge Tinc.py into tinc-gui to simplify make install. - - Autoconf/automake's Python support is strange. - -commit c4c32f40599eb8e75b1160083020d924c5807ac8 -Author: Guus Sliepen -Date: Sat Jun 25 17:11:05 2011 +0200 - - Thank Scott Lamb, Sven-Haegar Koch and Loïc Grenié in the NEWS file. - -commit 8733110dec28967d67a3c00d00cdfa608dbeb9c4 -Author: Guus Sliepen -Date: Sat Jun 25 17:08:40 2011 +0200 - - Ensure the right files end up in the tarball after make dist. - -commit e4f65db89726ac06ba7e787d420db4422d9a6e98 -Author: Guus Sliepen -Date: Sat Jun 25 15:28:54 2011 +0200 - - Releasing 1.1pre1. - -commit 2c5ded652035bfaa204a7e1cc6766efb87135569 -Author: Guus Sliepen -Date: Sat Jun 25 15:28:13 2011 +0200 - - Ensure that the texinfo manual can be converted to HTML. - - Somehow commit 2c30af6c90926340a89748c63cc453b1c0b5a589 was not properly - merged. - -commit e8deda0b23463599a7533e82cf038a01062956a7 -Author: Guus Sliepen -Date: Sat Jun 25 14:52:47 2011 +0200 - - Update manpages and info manual. - -commit 47393b5de42120dfb7d01f8b77aff16ac68177ec -Author: Guus Sliepen -Date: Sat Jun 25 00:32:45 2011 +0200 - - Add Makefile.am in gui/. - - This ensures the gui source will be included in the tarball with make dist, - and will be installed with make install. - -commit 7944cce19e4de4207a4ef20569155118acebd406 -Author: Guus Sliepen -Date: Sat Jun 25 00:06:06 2011 +0200 - - Don't use AM_CONDITIONAL for CURSES. - - For some reason, this doesn't work when cross-compiling for Windows. - -commit 365f60f3f8a8ff85a616d5014d555b470740d395 -Author: Guus Sliepen -Date: Fri Jun 24 22:49:18 2011 +0200 - - Don't call event_del() from the mtuevent handler, always send_mtu_probe() in ans_key_h(). - -commit 1fe8ba2f06c39d7c8b81f0e451bdbac94ae9375f -Author: Guus Sliepen -Date: Fri Jun 24 22:10:03 2011 +0200 - - Delete mtuevent if it is not used. - - Keeping it around prevents ans_key_h() from restarting PMTU discovery. - -commit 79e9a4f743b7b59fed968575f6b36171cf4a0063 -Merge: fb5b260 05260f9 -Author: Guus Sliepen -Date: Fri Jun 24 21:40:55 2011 +0200 - - Merge branch 'master' of git://tinc-vpn.org/tinc into 1.1 - - Conflicts: - NEWS - README - configure.in - src/Makefile.am - -commit 05260f941c2a24eb3f09070a2550cf15e431266a -Author: Guus Sliepen -Date: Fri Jun 24 14:50:20 2011 +0200 - - Releasing 1.0.15. - -commit 3c0511984f0041f79e64bcc55d58680f86e8e408 -Author: Guus Sliepen -Date: Fri Jun 24 12:27:04 2011 +0200 - - Remove redundant @CFLAGS@ from AM_CFLAGS. - -commit fb5b260190b1c6d07ec822154094aee7416f292e -Author: Guus Sliepen -Date: Tue Jun 21 23:08:05 2011 +0200 - - No need to check for pselect() in tinc 1.1. - -commit 532557beeaa60d96ac423248ff62d2cc03205c22 -Author: Guus Sliepen -Date: Tue Jun 21 23:06:53 2011 +0200 - - Only log UDP address changes at the appropriate debug levels. - -commit 60ed7fe598ccf3ac11fab616c9c85492c576b722 -Author: Guus Sliepen -Date: Mon Jun 6 21:19:30 2011 +0200 - - Reopen log file after SIGHUP. - - This was missed by the previous merge. - -commit 33f241d97852d7a171f1aaf1bda7f66356ff889e -Merge: 601f3b2 4b3fd94 -Author: Guus Sliepen -Date: Mon Jun 6 20:42:15 2011 +0200 - - Merge branch 'master' of git://tinc-vpn.org/tinc into 1.1 - - Conflicts: - NEWS - configure.in - doc/tincd.8.in - lib/pidfile.c - lib/pidfile.h - lib/xalloc.h - lib/xmalloc.c - src/conf.c - src/conf.h - src/connection.c - src/connection.h - src/event.c - src/graph.c - src/graph.h - src/net.c - src/net.h - src/node.h - src/openssl/crypto.c - src/process.c - src/protocol.c - src/protocol_key.c - src/route.c - -commit 601f3b2dd746ff5726eca256861f2ecf662b3a55 -Author: Guus Sliepen -Date: Mon Jun 6 20:12:33 2011 +0200 - - Clean up digests when freeing a connection_t. - -commit 4b3fd94b1cc79c24c4092b6b10ed4627a2648d26 -Author: Guus Sliepen -Date: Mon Jun 6 16:26:11 2011 +0200 - - Improved --logfile option. - - Instead of UNIX time, the log messages now start with the time in RFC3339 - format, which human-readable and still easy for the computer to parse and sort. - The HUP signal will also cause the log file to be closed and reopened, which is - useful when log rotation is used. If there is an error while opening the log - file, this is logged to stderr. - -commit b3bbeab6e669795f6f5a6b98590da359178bfdce -Author: Guus Sliepen -Date: Sat Jun 4 11:27:54 2011 +0200 - - Attribution for Loïc Grenié. - -commit 50af33d01f425983dd2b1d7b61092a6325be3f41 -Author: Loïc Grenié -Date: Sat Jun 4 09:05:23 2011 +0200 - - Nearly tickless tinc. - - Use pselect instead of select in main_loop (if available). This lets - tincd sleeps as long as there is nothing to do. - -commit 8b3cc695b56d4ab5e51c7e194153894f920b307f -Author: Guus Sliepen -Date: Fri Jun 3 15:50:20 2011 +0200 - - Don't ignore SIGCHLD, system() needs it. - - But we do ignore SIGPIPE, and tinc 1.0.x signals that are no longer used - (SIGUSR1 and SIGUSR2), since the default handler of these signals is to - terminate tincd immediately. - -commit 5989a29d7b53b25e8ed2f60bc3a0e089e423c02c -Author: Guus Sliepen -Date: Fri Jun 3 00:46:56 2011 +0200 - - Fix format strings for Windows. - - Windows doesn't like %zd, so cast (s)size_t to int. Also, some shorts were - incorrectly printed with %d instead of %hd. - -commit 3ade33bfac11715190ed3e6cc3589d1a738ce257 -Author: Guus Sliepen -Date: Fri Jun 3 00:34:30 2011 +0200 - - Use send() when writing to sockets, and the return type is ssize_t. - -commit 5f4d57e846b566e80557c57a72e2bad562f66e7b -Author: Guus Sliepen -Date: Thu Jun 2 23:40:27 2011 +0200 - - Small fixes for Windows. - -commit 2adc789401153ffde847f76155e07665fbf909ac -Author: Guus Sliepen -Date: Thu Jun 2 22:14:53 2011 +0200 - - Even simpler signal handling. - -commit 2f42896789a1798e71374fa2ddf555fe2fa46c44 -Author: Guus Sliepen -Date: Thu Jun 2 21:29:11 2011 +0200 - - Remove debugging message that was accidentily left in. - -commit c6b0e102ad7caabae6876849c97f8acaecf5bc1a -Author: Guus Sliepen -Date: Thu Jun 2 21:16:57 2011 +0200 - - Don't treat packets coming in via TCP as having zero length. - -commit 80ca91769d48e546d3e4cde03c2eb2820c03acc4 -Author: Guus Sliepen -Date: Thu Jun 2 21:14:50 2011 +0200 - - Fix nodes joining the VPN after tincctl top started. - -commit 311f60f4f0bdf974d4890d7eb4a752299d1c9458 -Author: Guus Sliepen -Date: Thu Jun 2 20:48:18 2011 +0200 - - Make traffic statistics more readable with configurable scaling. - -commit a8f0d21330b40993d52421327b1aa33a6ea7acb7 -Author: Guus Sliepen -Date: Thu Jun 2 20:27:16 2011 +0200 - - More stable sorting in tincctl top. - - Although we use qsort(), which is not guaranteed to be stable, resorting the - previously sorted array is more stable than recreating and resorting the array - each time. - -commit 2bda2aa8855ff3ae42aba7aa86e1d7ff2b7a3b34 -Author: Guus Sliepen -Date: Thu Jun 2 18:22:26 2011 +0200 - - Fix some compiler and cppcheck warnings. - -commit 809dfd2f5b08ecbfe55d1a06d267abeef0044b0b -Author: Guus Sliepen -Date: Thu Jun 2 18:07:50 2011 +0200 - - Remove support for the Ethertap device. - -commit af2e0c9a32642065aedd2e67ca1f5791ca7a407d -Author: Guus Sliepen -Date: Thu Jun 2 17:57:53 2011 +0200 - - Remove unused functions and variables. - -commit 9eca49329db0c3b0a80114045cf214eaeaf3d5c2 -Author: Guus Sliepen -Date: Thu Jun 2 17:55:29 2011 +0200 - - Don't #include anymore. - -commit b7754e5aaa3cc453582d6c8c2e66483fdcd1ac0d -Author: Guus Sliepen -Date: Thu Jun 2 17:53:35 2011 +0200 - - Drop the GNU memcmp.c implementation. - -commit 25b467638a23ad03524719329027225ae1da75bc -Author: Guus Sliepen -Date: Thu Jun 2 17:45:06 2011 +0200 - - Drop the GNU malloc.c, realloc.c, and xmalloc.c. - - We live in the 21st century, and we require C99 semantics, so we do not need to - work around buggy libcs. The xmalloc() and related functions are now static - inline functions. - -commit e452a933f9c53fd58db9d932afd15319129dd988 -Author: Guus Sliepen -Date: Thu Jun 2 17:14:30 2011 +0200 - - Simplify signal handling. - - We don't override any signal handlers anymore except those for SIGPIPE and - SIGCHLD. Fatal signals (SIGSEGV, SIGBUS etc.) will terminate tincd and - optionally dump core. The previous behaviour was to terminate gracefully and - try to restart, but that usually failed and made any core dump useless. - -commit 4d440336c3ce68719e23b2fc51fac368e23352ad -Author: Guus Sliepen -Date: Sun May 29 22:34:19 2011 +0200 - - Remove outgoing event in free_connection(). - -commit d29bfc9a450b4758e44757a71675bac631dd3c55 -Author: Guus Sliepen -Date: Sun May 29 22:14:35 2011 +0200 - - Initialise priority field to zero for packets read from the VPN interface. - -commit 4c403840ffdeb2a2ff04c9b7780a407920b2b794 -Author: Guus Sliepen -Date: Sun May 29 22:12:37 2011 +0200 - - Cosmetic fix when pressing 's' in tincctl top. - -commit b3aeaf0f917a895332ff937c7ab64638eacc0eae -Author: Guus Sliepen -Date: Sun May 29 22:10:54 2011 +0200 - - Show hostname and port in error message when connecting to a running tincd. - -commit 04de15984f1479d0142bdfa5bd968274aea2209e -Author: Sven-Haegar Koch -Date: Sun May 29 21:53:21 2011 +0200 - - do_outgoing_connection() may delete a failed connection, and the structure - must not be accessed afterwards. - -commit 82109868b5acd55e452569c565ab6dc090ea1de0 -Author: Sven-Haegar Koch -Date: Sun May 29 21:35:31 2011 +0200 - - src/net_socket.c bind_to_address(): Use after free in error path. - -commit 5bc957074a35e58f49cbcf8d1fb5d6237d37363d -Author: Guus Sliepen -Date: Sun May 29 14:41:05 2011 +0200 - - Allow tincctl to connect to something besides localhost. - - This would allow tincctl to connect to a remote tincd, or to a local tincd that - isn't listening on localhost, for example if it is using the BindToInterface or - BindToAddress options. - -commit 64771f73ebbff04262defcde59263e98f89f0fa1 -Author: Guus Sliepen -Date: Sat May 28 23:46:56 2011 +0200 - - Remove a few unnecessary #includes. - - Some spotted by Michael Tokarev. - -commit 5cff8c47c1781a88123c128a4cec6cdd39925aa5 -Author: Guus Sliepen -Date: Sat May 28 23:42:18 2011 +0200 - - Remove newlines from log messages. - -commit 6d08eb1614b59d5f86a43edda9db06fca72b76cd -Author: Guus Sliepen -Date: Sat May 28 23:36:52 2011 +0200 - - Fix sparse warnings and add an extra sprinkling of const. - - This is more or less the equivalent of Sven-Haegar Koch's fixes in the 1.1 - branch. - -commit e6b21e1a510691a86dcc1ecdf71a80a7c62ff17f -Author: Sven-Haegar Koch -Date: Sat May 28 03:48:07 2011 +0200 - - fgets() returns NULL on error, not < 0 - -commit 434e57ae5ee79b3d990c4d75358047bad641998b -Author: Sven-Haegar Koch -Date: Sat May 28 03:46:39 2011 +0200 - - sparse fixup: warning: Using plain integer as NULL pointer - -commit f4010694b3b16453e5e6298c208910264e326978 -Author: Sven-Haegar Koch -Date: Sat May 28 03:57:20 2011 +0200 - - sparse fixup: warning: non-ANSI function declaration of function '...' - -commit d772289f6d6adfb8932658b533349d43f08ec326 -Author: Sven-Haegar Koch -Date: Sat May 28 03:56:06 2011 +0200 - - sparse fixup: warning: symbol '...' was not declared. Should it be static? - -commit 02e32cf61ee25d3d0e2fc1fef5cd98cbfa1c9a2f -Author: Sven-Haegar Koch -Date: Sat May 28 03:12:03 2011 +0200 - - sparse fixup: error: too many arguments for function send_key_changed - -commit b995243ac3d9605003996ba879808ddcbc77ae15 -Author: Sven-Haegar Koch -Date: Sat May 28 03:08:31 2011 +0200 - - sparse fixup: error: dubious one-bit signed bitfield - -commit bbd0025ae323e7141ba04a5371ec2f3f75f9b059 -Author: Sven-Haegar Koch -Date: Sat May 28 02:57:40 2011 +0200 - - Use same definition for xalloc_fail_func as is really used. - -commit 3fca2cad485ef70360bca085c5c4d052b6deb15b -Author: Sven-Haegar Koch -Date: Sat May 28 01:36:10 2011 +0200 - - Removed two newlines from the end of log messages which created empty lines. - -commit 9cce44dfe3401867f753778b73fd1e7ac1ee3122 -Author: Sven-Haegar Koch -Date: Sat May 28 01:33:45 2011 +0200 - - Fixed error logging on "Input buffer full" condition. - -commit 07ffb1a19859791d419b83a876ba552dadedbf46 -Author: Guus Sliepen -Date: Sun May 22 15:56:04 2011 +0200 - - Make return value of SetPriorityClass() behave the same as setpriority(). - -commit 453c44e7b27d4259461795ab4ec6ef264085dd28 -Author: Guus Sliepen -Date: Sun May 22 14:17:30 2011 +0200 - - Add the ability to dump all traffic going through route() over a control connection. - - One can get the packet stream in pcap format, which can be decoded using - tcpdump, for example: - - tincctl -n pcap | tcpdump -r - - -commit 54c900e961de6065f607f5661edeb7c84be29ea5 -Author: Guus Sliepen -Date: Sun May 22 14:02:27 2011 +0200 - - Reset tcplen after use. - -commit 8ddcad5fa1908727f68abb461b615c666616064f -Author: Guus Sliepen -Date: Sun May 22 13:15:27 2011 +0200 - - Check if an event is initialized before calling event_del(). - - Libevent prints a warning to stderr if we do that. - -commit 931e30f91a9241ab8aa705c911c92ba8943f80fd -Author: Guus Sliepen -Date: Sun May 22 13:15:05 2011 +0200 - - Always compact the buffer if it has reached MAXBUFSIZE. - -commit 90c7fafe594cf6d03c15a072a3d749f3e4d78482 -Author: Guus Sliepen -Date: Sun May 22 12:56:51 2011 +0200 - - Compact input buffer before trying to read instead of after. - - Also log an error when the input buffer contains more than MAXBUFSIZE bytes - already, instead of silently claiming the other side closed the connection. - -commit 8de8f1d9e2c2c02d4a14a5506e7d0d914dc328da -Author: Guus Sliepen -Date: Tue May 17 10:58:22 2011 +0200 - - Fix some compiler warnings. - -commit a80c18dd20e5303b26d5283e6cb5062a1812ddc3 -Author: Guus Sliepen -Date: Tue May 17 10:57:30 2011 +0200 - - Use GetItemCount() on ListCtrls instead of directly accessing ItemCount. - -commit f536504a7de90927b09d16f3bf0d3c6adead9955 -Author: Guus Sliepen -Date: Mon May 16 09:48:19 2011 +0200 - - Add top.h. - -commit e272fab858d5d3eeb43ff9f36268d25d3c6d32f1 -Author: Guus Sliepen -Date: Mon May 16 09:46:54 2011 +0200 - - Add tincctl.h. - -commit 6d97cb1e229c22d1d34aa9889aeaf17644ff06dc -Author: Guus Sliepen -Date: Sun May 15 16:30:13 2011 +0200 - - Nicer top command. - - - Configurable refresh interval. - - Switch between cumulative count or current rate. - - Configurable sorting. - -commit 4574b04f79d79d53492b7e0eb592d64ff9b2362b -Author: Guus Sliepen -Date: Sun May 15 16:29:54 2011 +0200 - - Allow inserting items in the middle of a list. - -commit 97355690b9cf8d8b56a316e01f73f8ff1fee68c8 -Author: Guus Sliepen -Date: Sun May 15 13:16:48 2011 +0200 - - Add a very primitive "top" command to tincctl. - -commit ec495b2f15fc5ae22136c226c7966caf51f643f8 -Author: Guus Sliepen -Date: Sun May 15 12:06:21 2011 +0200 - - Add an autoconf check for the curses library. - -commit 362d8a6358019cb97456c8133832f18798cea41f -Author: Guus Sliepen -Date: Sun May 15 11:59:13 2011 +0200 - - Dump traffic statistics over control sockets. - -commit f5843e7d649f4a7f72cb3fd356bc935457aa492f -Author: Guus Sliepen -Date: Sun May 15 00:42:29 2011 +0200 - - Add per-node traffic counters. - -commit ffa3a443b9f01d3ea0fcb3c4fc6928a5c695cf4a -Author: Guus Sliepen -Date: Sat May 14 22:30:23 2011 +0200 - - Several fixes for the buffer code. - -commit cdb793f687262b9f56823ca9046523a609a758af -Author: Guus Sliepen -Date: Sat May 14 19:20:56 2011 +0200 - - Remove use of bufferevent and eventbuffers, use our own buffering instead. - -commit f431fcb35f400be388a905ae0f7f50c1f5c4cd5d -Author: Guus Sliepen -Date: Sat May 14 19:15:04 2011 +0200 - - Add simple buffer management code. - - Libevent 2.0's buffer code is not completely backward compatible with 1.4's. - In order to not (mis)use it anymore, we implement it ourselves. The buffers - are automatically expanding when necessary. When consuming data from the - buffer, no memmove()s are performed. Only when adding to the buffer would - write past the end do we shift everything back to the start. - -commit 3794e551c7db9aa81405f65f7b04a9951c4120b2 -Author: Guus Sliepen -Date: Sat May 14 11:52:35 2011 +0200 - - Fix check for event initialization due to the merge. - -commit 03b7118139f57033659730afb740bf5cef7c961c -Author: Guus Sliepen -Date: Fri May 13 12:37:26 2011 +0200 - - Reorder checks for libraries to allow ./configure LDFLAGS=-static. - - OpenSSL depends on libdl and libz. When linking dynamically, libcrypto will - automatically link with the other two libraries. However, when linking - statically, these libraries need to be specified explicitly while linking. By - moving the autoconf checks for libdl and libz before those for libcrypto, we - ensure the latter test will be done with the proper libraries. - -commit ce8775000ab38229a78ecf3dc26bab008ca0f332 -Merge: 3f59a26 5686ad8 -Author: Guus Sliepen -Date: Mon May 9 21:35:14 2011 +0200 - - Merge branch 'master' of git://tinc-vpn.org/tinc into 1.1 - - Conflicts: - NEWS - README - configure.in - doc/tincd.8.in - lib/pidfile.c - src/bsd/device.c - src/dropin.h - src/net.c - src/net_packet.c - src/node.c - src/process.c - src/tincd.c - -commit 5686ad80b545afa3de9ed2f4176a5346e289aaa8 -Author: Guus Sliepen -Date: Sun May 8 23:17:46 2011 +0200 - - Releasing 1.0.14. - -commit 0d906489f2ce9faf81dc230f7db6ab5378573554 -Author: Guus Sliepen -Date: Sun May 8 23:12:44 2011 +0200 - - Include when using intptr_t. - -commit dc887f5011834d5a9a6ec5deb8781c6bfd88c474 -Author: Guus Sliepen -Date: Sun May 8 23:12:06 2011 +0200 - - Ensure proper linking with OpenSSL with recent versions of MinGW. - -commit 67766d65f06854ee894d784f638c5c9cd2b50bca -Author: Guus Sliepen -Date: Sun May 8 21:22:20 2011 +0200 - - Update THANKS and copyright information. - -commit 6e6b037ef4fd9877aeb1d947da7364409fa8cbb7 -Author: Guus Sliepen -Date: Sun May 8 21:06:06 2011 +0200 - - Check for EVP_EncryptInit_ex instead of SHA1_Version in OpenSSL. - - The latter function disappeared, and wasn't actually used in tinc, so now we - check on a function that we do use. - -commit 257cb6ac60bb0924720de9e252cdf7f4759bf741 -Author: Guus Sliepen -Date: Sun May 8 12:40:44 2011 +0200 - - Always use the default signal handler for ABRT signals. - - This will allow coredumps to be generated when tinc is daemonized. - Also add the -kABRT option. - -commit eacb5a28fb4c1515633f2b8a206e7067bc7b8f0c -Author: Guus Sliepen -Date: Sun May 8 12:16:26 2011 +0200 - - Increase threshold for detecting two nodes with the same Name. - - In commit 4a21aabada23d1d2c8a10f54dd7248171c4ec82f, code was added to detect - contradicting ADD_EDGE and DEL_EDGE messages being sent, which is an indication - of two nodes with the same Name connected to the same VPN. However, these - contradictory messages can also happen when there is a network partitioning. In - the former case a loop happens which causes many contradictory message, while - in the latter case only a few of those messages will be sent. So, now we - increase the threshold to at least 10 of both ADD_EDGE and DEL_EDGE messages. - -commit f11c6101f30df645223920bef3eb7592de9bcb79 -Author: Julien Muchembled -Date: Thu Apr 28 13:21:55 2011 +0200 - - Fix command-line '-o' option for host configuration - - This fixes a regression introduced by commit 667b1ba while refactoring option - parsing code. - -commit 0aa86d4b8b3010522e6de8842f5bd29004ba3df6 -Author: Guus Sliepen -Date: Wed Mar 9 09:34:56 2011 +0100 - - Do not set indirect flag on edges from nodes with multiple addresses. - - Since tinc now handles UDP packets with a different source address and port - than used for TCP connections, the heuristic to treat edges as indirect when - tinc could detect that multiple addresses were used does not make sense - anymore, and can actually reduce performance. - -commit 7cf68b5e35c002511cc7468967de6a75934cc998 -Author: Guus Sliepen -Date: Fri Feb 18 23:11:43 2011 +0100 - - Prevent anything from updating our own UDP address. - - Because we don't want to keep track of that, and this will cause the node - structure from being relinked into the node tree, which results in myself - pointing to an invalid address. - -commit cdbbbfabea173894bd2fb5f28135a04ddc5e3fd7 -Author: Guus Sliepen -Date: Fri Feb 18 23:02:11 2011 +0100 - - Fix spurious misidentification of incoming UDP packets. - - When a UDP packet was received with an unknown source address/port, and if it - failed a HMAC check against known keys, it could still incorrectly assign that - UDP address to another node. This would temporarily cause outgoing UDP packets - to go to the wrong destination address, until packets from the correct address - were received again. - -commit 046d83bf91e01bc7a32e66a02758caf228bc4601 -Author: Rumko -Date: Sat Feb 12 18:22:14 2011 +0100 - - DragonFlyBSD support - - * added DragonFly BSD support - * added a check for sys/resource.h (needed on DragonFly) - -commit f017c7f98f8f68d6ca50ebe247f4115aadd93635 -Author: Guus Sliepen -Date: Mon Feb 7 18:34:55 2011 +0100 - - Add support for VDE through libvdeplug. - - When compiled with vde/device.c, tinc will connect to a vde_switch instance - instead of using a tun/tap device. - -commit 8d18cc6c4e625625a2437d26c587f9f382a0c589 -Author: Guus Sliepen -Date: Sat Jan 29 10:49:44 2011 +0100 - - Fix typo spotted by Andrew Scheller. - -commit b3731c04097e66a6b8908bb893c5da831d89c04d -Author: Guus Sliepen -Date: Wed Jan 12 20:57:14 2011 +0100 - - Proper check and dropin replacement for usleep(). - -commit 4b8a5993036fccc2108fcc2550649d9b78fb1ab7 -Author: Guus Sliepen -Date: Sun Jan 2 17:25:24 2011 +0100 - - Update the NEWS. - -commit c228da54d47657811dfb679e7f138cbba58a9f67 -Author: Guus Sliepen -Date: Sun Jan 2 17:25:03 2011 +0100 - - Update the manual. - -commit 4575c6c7dffe228ce302776022a2075b7ef37ab0 -Author: Guus Sliepen -Date: Sun Jan 2 17:24:23 2011 +0100 - - Document the behavior of "-n." - -commit 6c05bf082b1ce9acfc0ebb5c6f32c2ece41c7f80 -Author: Guus Sliepen -Date: Sun Jan 2 16:59:42 2011 +0100 - - Remove unused variables. - -commit 6a51d89cf706bcefce1861a1a66d40ef7d7db43b -Author: Guus Sliepen -Date: Sun Jan 2 16:55:42 2011 +0100 - - Replace bogus #else with #endif. - - Found by cppcheck, which complained about lenin not being initialized, but the - real problem is that reading packets would fail when using code compiled with - --tunemu on a normal tun device. - -commit d7636352ce359e807b392a6e5ac0a6aeff4a63d2 -Author: Guus Sliepen -Date: Sun Jan 2 16:52:36 2011 +0100 - - Limit field width when scanning PID file. - - Cppcheck warns that scanf() might otherwise crash when presented with a huge, - bogus PID file. - -commit 3ce5e292da8bab3a1316faf1ca18625f05074467 -Author: Guus Sliepen -Date: Sun Jan 2 16:50:24 2011 +0100 - - Close all filedescriptors in Solaris close_device(). - -commit f99661a4ca5bacff47239ce7978b9c9948917c54 -Author: Guus Sliepen -Date: Sun Jan 2 15:02:23 2011 +0100 - - Always send MTU probes at least once every PingInterval. - - Before, if MTU probes failed, tinc would stop sending probes until the next - time keys were regenerated (by default, once every hour). Now it continues to - send them every PingInterval, so it recovers faster from temporary failures. - -commit cac0a5c651535e8317839b0deff1ee98086a8184 -Author: Guus Sliepen -Date: Sat Nov 20 14:31:11 2010 +0000 - - Use setpriority() instead of nice() on UNIX-like systems. - - The return value of nice() can not reliably indicate errors. The return value - of the setpriority() call is well-defined. - -commit 3f59a26d8098b8b0902b8746715508360b347f47 -Author: Guus Sliepen -Date: Fri Nov 19 12:26:20 2010 +0000 - - Do not try to dereference myself->connection->config_tree. - - This was a bug introduced due to an incomplete merge (commit - ff71f289022ccb91abc2726f16522d55b5ccf0f6). - -commit 886a6f61a1f4cc48a77b42d10f34f9126377d904 -Merge: 23dddc2 d91903e -Author: Guus Sliepen -Date: Fri Nov 19 12:22:48 2010 +0000 - - Merge branch 'master' into 1.1 - - Conflicts: - src/net_packet.c - src/openssl/rsagen.h - src/protocol_auth.c - src/protocol_key.c - -commit d91903ef3c2a1f4481ae8757bb2b14282f2b7e68 -Author: Guus Sliepen -Date: Tue Nov 16 17:28:41 2010 +0100 - - Attribution for Brandon Black. - -commit e764ff7be9949c91865aff72844357e76ae6dd78 -Author: Guus Sliepen -Date: Tue Nov 16 16:45:36 2010 +0100 - - Fix variable length array declaration. - -commit 5eb0440110f99f0a49838cc00a0686c7a7595663 -Author: Guus Sliepen -Date: Sat Nov 13 21:36:51 2010 +0100 - - Free replay window when freeing a node_t. - -commit a9445e38f25bd24eca289768fc46e44e36b842ac -Author: Guus Sliepen -Date: Sat Nov 13 21:34:59 2010 +0100 - - Fix warning message when setting SO_RCVBUF or SO_SNDBUF fails. - -commit 0d61d4ae1358553fc8dde350747542f137f5cb8b -Author: Brandon L Black -Date: Sat Nov 13 12:05:51 2010 -0600 - - Improved handling of queue-jumping packets on receive - -commit 23acc19bc090051156ad895caed61848f5afb144 -Author: Brandon L Black -Date: Sat Nov 13 12:05:50 2010 -0600 - - Configurable ReplayWindow size, zero disables - -commit 8dfe1b374e165ecba5d3ae324ee834d337476be8 -Author: Brandon L Black -Date: Sat Nov 13 12:05:49 2010 -0600 - - Configurable SO_RCVBUF/SO_SNDBUF for the UDP socket - -commit 3f410e2f8f7c365630f226adf4904935698f9e0d -Author: Brandon L Black -Date: Sat Nov 13 12:05:48 2010 -0600 - - Experimental IFF_ONE_QUEUE support for Linux - -commit 9e3ca397735077f85bbde48c36e1b3e0fa950988 -Author: Guus Sliepen -Date: Sat Nov 13 15:55:38 2010 +0100 - - Use variable length arrays instead of alloca(). - -commit e2e6ec8050274b0a8678d6fc263e7dc4ef66feae -Author: Guus Sliepen -Date: Sat Nov 13 15:50:39 2010 +0100 - - Provide usleep() for Windows. - -commit 23dddc25930bc9033e5a2ac659376032aff44d82 -Author: Guus Sliepen -Date: Sat Nov 13 15:46:19 2010 +0100 - - Link tincctl with dropin.o. - -commit a22041922f160667573e9a5ae3f4195e1668906a -Merge: 8b70c5b 930bf74 -Author: Guus Sliepen -Date: Fri Nov 12 16:15:29 2010 +0100 - - Merge branch 'master' into 1.1 - - Conflicts: - doc/tincd.8.in - lib/pidfile.c - src/graph.c - src/net.c - src/net.h - src/net_packet.c - src/net_setup.c - src/net_socket.c - src/netutl.c - src/node.c - src/node.h - src/protocol_auth.c - src/protocol_key.c - src/tincd.c - -commit 930bf74fbe5ce8363b6cc2ae3a3e960e910e0996 -Author: Guus Sliepen -Date: Fri Nov 12 11:38:05 2010 +0100 - - Don't use strlen() on a NULL pointer. - - A bug introduced in commit 667b1bac77b134cf32c98d5dc25619e8c3303f52 caused tinc - to crash on startup. - -commit a07aa92176571eb7f063708640d0d486280808ef -Author: Guus Sliepen -Date: Fri Nov 12 11:33:01 2010 +0100 - - Add short options -R and -U to the tincd(8) manpage. - -commit 66b7aea294896a99df289231143a506b422b994c -Author: Guus Sliepen -Date: Tue Nov 2 14:23:43 2010 +0100 - - Read error counter must be static. - -commit a91bf2dfcd0f5857905e59da7d944654e0875503 -Author: Guus Sliepen -Date: Tue Nov 2 14:18:35 2010 +0100 - - Quit when there are too many consecutive errors on the tun/tap device. - - Although transient errors sometimes happen on the tun/tap device (for example, - if the kernel is temporarily out of buffer space), there are situations where - the tun/tap device becomes permanently broken. Instead of endlessly spamming - the syslog, we now sleep an increasing amount of time between consecutive read - errors, and if reads still fail after 10 attempts (approximately 3 seconds), - tinc will quit. - -commit aca70cd3c3fe787e62c618849e43f67b3870ac20 -Author: Michael Tokarev -Date: Sun Oct 24 15:23:10 2010 +0400 - - Treat netname="." in a special way. - - Treat netname "." in a special way as if there was no netname - specified. Before, f.e. tincd -n. -k didn't work as it tried - to open /var/run/tinc-.pid. Now -n. works as if there was no - -n option is specified. - - Signed-Off-By: Michael Tokarev - -commit 5f729f76f5a63114df582fc29f4189140c1e5ead -Author: Guus Sliepen -Date: Fri Oct 22 22:46:44 2010 +0200 - - Remove unused variables. - - These were caused by commit 667b1bac77b134cf32c98d5dc25619e8c3303f52. - -commit 20ae7dd8c12390f7360eb28cc17e1b8a8a706b06 -Author: Guus Sliepen -Date: Fri Oct 22 22:43:50 2010 +0200 - - Abort disabling old PEM keys on I/O errors. - -commit a08462bf845973016e061b8ca1233142d80416f6 -Author: Guus Sliepen -Date: Fri Oct 22 22:42:21 2010 +0200 - - Ensure there is a newline character before a PEM key is written. - -commit c6ccbadfcf93a7bd4a88dee8ff146b4db7f85e71 -Author: Guus Sliepen -Date: Fri Oct 22 13:40:04 2010 +0200 - - Attribution for Timothy Redaelli. - -commit 1c2cd7ed273ee1538ff8a13d036c68aa9992c4aa -Author: Guus Sliepen -Date: Fri Oct 22 13:17:42 2010 +0200 - - Attribution for Julien Muchembled. - -commit 667b1bac77b134cf32c98d5dc25619e8c3303f52 -Author: Guus Sliepen -Date: Fri Oct 22 13:06:06 2010 +0200 - - Remove duplicate command-line option parsing. - - Also fix parsing of command-line host configuration options for the local node. - -commit ff71f289022ccb91abc2726f16522d55b5ccf0f6 -Author: Guus Sliepen -Date: Fri Oct 22 12:47:12 2010 +0200 - - Merge local host configuration with server configuration. - - With some exceptions, tinc only accepted host configuration options for the - local node from the corresponding host configuration file. Although this is - documented, many people expect that they can also put those options in - tinc.conf. Tinc now internally merges the contents of both tinc.conf and the - local host configuration file. - -commit 8c3105283ac53f8cc9cc4dde25957ec1cf6b53a0 -Author: Julien Muchembled -Date: Fri Sep 3 13:34:22 2010 +0200 - - New '-o' option to configure server or hosts from command line - - Options given on the command line have precedence over configuration from files. - - This can be useful, for example, for a roaming node, for which 'ConnectTo' and - .Address depends on its location. - -commit 4b6a9f1c1f645ce5989692655337d9e23ca28648 -Author: Guus Sliepen -Date: Fri Jun 4 16:03:19 2010 +0200 - - Do not append an address to ANS_KEY messages if we don't know any address. - - This would let tinc raise an exception when an ANS_KEY request crossed a - DEL_EDGE request for the node sending the key. - -commit 798fa2f04c52b0639713f74b1195847bec40c16a -Author: Guus Sliepen -Date: Fri Jun 4 15:04:08 2010 +0200 - - Use 64 bit counters to keep track of bytes sent/received from the virtual network interface. - -commit 4a21aabada23d1d2c8a10f54dd7248171c4ec82f -Author: Guus Sliepen -Date: Fri Jun 4 14:53:52 2010 +0200 - - Detect and prevent two nodes with the same Name being on the VPN simultaneously. - - In this situation, the two nodes will start fighting over the edges they announced. - When we have to contradict both ADD_EDGE and DEL_EDGE messages, we log a warning, - and with 25% chance per PingTimeout we quit. - -commit dbf3d168b720045328d476f3b9e5f5e45b4ab6de -Author: Guus Sliepen -Date: Fri May 7 12:24:49 2010 +0200 - - Use strrchr() insteaad of rindex(). - - The latter function is deprecated, some build environments do not support. - -commit eda71798749e8b0abf5e8b3cbc11da82aa607f00 -Author: Timothy Redaelli -Date: Tue May 4 15:43:48 2010 +0200 - - Fix warnings under BSD - -commit df985256a766ee90f2fa4269b95fa0565c969dda -Author: Timothy Redaelli -Date: Tue May 4 00:27:44 2010 +0200 - - Fix warnings showed using -D_FORTIFY_SOURCE=2 - -commit f5122ccecee095b9185b2324dea7bcd9655462ee -Author: Guus Sliepen -Date: Sat May 1 15:39:59 2010 +0200 - - Fix all warnings when compiling with mingw64. - -commit ef92a5725c47c6e8e801e07190dd7dd3f9cb3a17 -Author: Guus Sliepen -Date: Sat May 1 15:39:03 2010 +0200 - - OpenSSL 1.0.0 compiled for 64 bit Windows requires linking with -lcrypt32. - -commit 0fdd7da52077d77a11a3646eb3e7d5b6ffa178e8 -Author: Guus Sliepen -Date: Sat May 1 15:38:04 2010 +0200 - - Use intptr_t instead of long to store a pointer. - -commit c94ede3b8708cdf105a3fecfc119a558e1583f27 -Author: Guus Sliepen -Date: Sat May 1 15:37:11 2010 +0200 - - Define WINVER before including any other header file on Windows. - -commit 8b70c5be9bc762d81354f9cd77c3748a44a4956d -Author: Guus Sliepen -Date: Fri Apr 30 23:18:22 2010 +0200 - - Remove obsolete lib/ directory. - -commit ee427cac0d04c60d09cc235c04664eab8b0c6527 -Author: Guus Sliepen -Date: Fri Apr 30 23:13:02 2010 +0200 - - Do not try to free NULL pointers. - -commit 113458c2864ec8c046ab7d63ff1b417252c8e4df -Author: Guus Sliepen -Date: Fri Apr 30 23:11:48 2010 +0200 - - Use correct digest length when checking a received key. - -commit 76b41ba20dc9783ff0d21dd738739a81d62142e7 -Author: Guus Sliepen -Date: Sat Apr 17 12:33:36 2010 +0200 - - Add missing return statement. - -commit 2911af6e23d0dba6d771fcd590551a84bd9dc932 -Author: Guus Sliepen -Date: Sat Apr 17 12:33:15 2010 +0200 - - Fix merge of commit 4a0b9981513059755b9fd15b38fc198f46a0d6f2. - -commit 79e46d08a46f2fef2ee4e8eac7ba487007160564 -Merge: 4ce4af4 4766359 -Author: Guus Sliepen -Date: Sat Apr 17 12:21:53 2010 +0200 - - Merge branch 'master' into 1.1 - - Conflicts: - NEWS - README - configure.in - src/net.c - src/net.h - -commit 4ce4af4c712c80d08630767ec34787253da1021b -Author: Guus Sliepen -Date: Sat Apr 17 12:03:08 2010 +0200 - - Fix experimental GUI when reading hexadecimal values. - -commit 4766359e1426bdf1383c898d6103d8760e5e296d -Author: Guus Sliepen -Date: Sat Apr 17 12:01:38 2010 +0200 - - Fix reading configuration files that do not end with a newline. Again. - -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 e49891e188f618a0e98f1d30bcbf240286e8ad5c -Author: Sven-Haegar Koch -Date: Wed Mar 31 03:56:53 2010 +0200 - - Fixed metadata protokoll corruption on forwarded requests - - When forwarding a metadata request through forward_request() we were - adding the required newline char to our buffer, but then sending the - data without it - this results in the forwarded request and the next one - to be garbled together. - - Additionally while at it add a warning comment that request string is - not zero terminated anymore after a call to the forward_request() - function - for now this is ok as it is not used by any caller after this. - -commit 0310deb225cad21c458fb32fd589027e3f844735 -Author: Sven-Haegar Koch -Date: Fri Mar 26 17:25:18 2010 +0100 - - Demote all LOG_EMERG to LOG_ERR, spamming all xterms is bad. - -commit d5654f568dcaf81341395b52b2711f68c0417ec6 -Author: Sven-Haegar Koch -Date: Fri Mar 26 16:54:13 2010 +0100 - - README.git: tinc 1.1 needs libevent - -commit 685509ffe10d1bf9c409e5ba90f46cd747f2d9cd -Author: Sven-Haegar Koch -Date: Sun Mar 28 17:51:26 2010 +0200 - - Function flush_meta() does not exist anymore. - -commit c6d2b9d734859ccbd9582b28351983a12b04abb0 -Author: Sven-Haegar Koch -Date: Fri Mar 26 17:07:30 2010 +0100 - - Add missing AC_CHECK_HEADERS([dirent.h]) to configure.in - -commit ffa1dc73dcd62a856325641972a13d398aa8121c -Author: Sven-Haegar Koch -Date: Fri Mar 26 17:18:04 2010 +0100 - - Fixed 1.0 miss-merges - -commit 103543aa2c15d9f1e2aa313a2e593a7524cce484 -Merge: 35b1c25 2923549 -Author: Sven-Haegar Koch -Date: Fri Mar 26 16:51:03 2010 +0100 - - Merge branch 'master' into 1.1 - - Conflicts: - NEWS - README - configure.in - have.h - src/conf.c - src/conf.h - src/net.c - src/net_packet.c - src/protocol_key.c - src/protocol_subnet.c - src/route.c - src/tincd.c - -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 - - 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 35b1c25093a478d20e01f0ff391c9cdc9c41c2b8 -Author: Guus Sliepen -Date: Thu Dec 31 13:19:13 2009 +0100 - - Move source from lib/ to src/. - - The utility functions in the lib/ directory do not really form a library. - Also, now that we build two binaries, tincctl does not need everything that was - in libvpn.a, so it is wasteful to link to it. - -commit 41497246eeccbcc417f93c2ae087e927751c6914 -Author: Guus Sliepen -Date: Thu Dec 31 13:09:14 2009 +0100 - - Remove unused AVL tree library. - -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 36261650024ba8e18f9c77396f1d7a4e51f20602 -Author: Guus Sliepen -Date: Sat Dec 19 23:23:25 2009 +0100 - - Do not use hardcoded cipher block length when padding. - -commit f542ef8f9e645bf30e11e196dd768fac4f957eac -Author: Guus Sliepen -Date: Sat Dec 19 22:17:39 2009 +0100 - - Fix alignment of results of RSA operations when using libgcrypt. - - If the result of an RSA encryption or decryption operation can be represented - in less bytes than given, gcry_mpi_print() will not add leading zero bytes. Fix - this by adding those ourself. - -commit 4c68a8cb60eb0a4c05d9ce98963b930a976b55ee -Author: Guus Sliepen -Date: Sat Dec 19 20:53:48 2009 +0100 - - Do not consider unreachable nodes when trying to determine packet origin. - -commit 74e50d52e0e23c9dd1e21fb447f1e1a59d02d0b2 -Author: Guus Sliepen -Date: Sat Dec 19 20:52:19 2009 +0100 - - recv() and recvfrom() return int, do not prematurely cast the return value. - -commit 0bfd69a2736cb98470b47c1f6cba617b58bb86ef -Author: Guus Sliepen -Date: Sat Dec 19 20:26:30 2009 +0100 - - Fix reading raw RSA keys with libgcrypt. - -commit 0ff44fc2417217d542bf0e9a7ecfd20020893bc7 -Author: Guus Sliepen -Date: Sat Dec 19 20:10:38 2009 +0100 - - Reinitialise block cipher IV each time we encrypt a packet when using libgcrypt. - -commit 3c90be7678566203d38624c4a6fe3affaffbe5e3 -Author: Guus Sliepen -Date: Sat Dec 19 18:57:54 2009 +0100 - - Fix block cipher padding when using libgcrypt. - -commit c845bc109c85e6fb350096c63e13ef8e617ee29b -Author: Guus Sliepen -Date: Fri Dec 18 01:15:25 2009 +0100 - - Fix packet authentication. - - This wasn't working at all, since we didn't do HMAC but just a plain hash. - Also, verification of packets failed because it was checking the whole packet, - not the packet minus the HMAC. - -commit 10d609b1f0dd9eeb024cd40359683d48542aecbf -Author: Guus Sliepen -Date: Wed Dec 16 21:18:21 2009 +0100 - - Start of a GUI for tinc. - -commit 55ef2f806f9840103bceb472564a711b22e73d58 -Author: Guus Sliepen -Date: Wed Dec 16 21:16:56 2009 +0100 - - Allow connections to be closed. - - This only closes existing meta connections, it may not affect node - reachability. - -commit f12c36afd5293ddbecccf13f36edb8d36e56f040 -Author: Guus Sliepen -Date: Mon Dec 14 21:25:06 2009 +0100 - - Include missing header files and source directories. - -commit 2a410cd26d25cc01b96d255644df3ad138eae776 -Author: Guus Sliepen -Date: Mon Dec 14 21:20:56 2009 +0100 - - Do not include OpenSSL headers directly. - -commit 5d78e497f1c352c8d490eed1d44d128523a34572 -Author: Guus Sliepen -Date: Fri Dec 11 22:38:06 2009 +0100 - - Fix compiler warnings. - -commit d6c50eb73ad49bd2eac67214995dff76b7a20661 -Merge: fec1479 369fe1a -Author: Guus Sliepen -Date: Fri Dec 11 22:31:27 2009 +0100 - - Merge branch 'master' into 1.1 - - Conflicts: - src/subnet.c - -commit fec14791e869180bb7994ca38ca7006cc2e957fb -Author: Guus Sliepen -Date: Fri Dec 11 22:24:07 2009 +0100 - - Only call ioctlsocket() on Windows. - -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 edebf579f2ea29e6e84360cb13731f5858a1555b -Author: Guus Sliepen -Date: Sat Nov 7 23:43:25 2009 +0100 - - Use the TCP socket infrastructure for control sockets. - - The control socket code was completely different from how meta connections are - handled, resulting in lots of extra code to handle requests. Also, not every - operating system has UNIX sockets, so we have to resort to another type of - sockets or pipes for those anyway. To reduce code duplication and make control - sockets work the same on all platforms, we now just connect to the TCP port - where tincd is already listening on. - - To authenticate, the program that wants to control a running tinc daemon must - send the contents of a cookie file. The cookie is a random 256 bits number that - is regenerated every time tincd starts. The cookie file should only be readable - by the same user that can start a tincd. - - Instead of the binary-ish protocol previously used, we now use an ASCII - protocol similar to that of the meta connections, but this can still change. - -commit c388527e341658dc915dd67c90bbc9b52b8539c0 -Author: Guus Sliepen -Date: Sat Nov 7 16:09:56 2009 +0100 - - Small fixes to get really working control sockets on Windows. - -commit 5c5548fc7185cc1462602dadcd39a53cef481d29 -Author: Guus Sliepen -Date: Sat Nov 7 14:35:48 2009 +0100 - - Better integration of libevent in build system. - - Since event.h is not part of tinc, we include it in have.h were all other - system header files are included. We also ensure -levent comes before -lgdi32 - when compiling with MinGW, apparently it doesn't work when the order is - reversed. - -commit 075264a9e18f9fd58cad044c064a91557e9ed429 -Author: Guus Sliepen -Date: Thu Nov 5 23:29:28 2009 +0100 - - Make sure the 1.1 branch compiles in a MinGW environment. - - UNIX domain sockets, of course, don't exist on Windows. For now, when compiling - tinc in a MinGW environment, try to use a TCP socket bound to localhost as an - alternative. - -commit 08615e420b2dd5054dd978bf53c88b8dde6e4788 -Author: Guus Sliepen -Date: Thu Nov 5 00:02:42 2009 +0100 - - Handle PKCS#5 padding in the gcrypt backend. - -commit d9b2ac6767f85927a26e2b95bba69c052ac503ac -Author: Guus Sliepen -Date: Thu Nov 5 00:01:25 2009 +0100 - - Handle truncated message authentication codes with gcrypt. - - Commit 4124b9682f8f890acb25d0c92f2583eef670274a did not update the gcrypt - backend. - -commit c4afc481541bff4db7f57c81796b7a5f61cdb1b5 -Author: Guus Sliepen -Date: Wed Nov 4 16:19:08 2009 +0100 - - Use %x instead of %lx where appropriate. - - Some conversions were not properly merged from the master branch. - -commit 37ccb325af5c7865eb16716780121a8a6dce8abd -Author: Guus Sliepen -Date: Wed Nov 4 16:18:08 2009 +0100 - - Don't enable device events when there is no valid filedescriptor. - -commit 108b238915c5f58b3d94ab433dc5d04e064c2b11 -Merge: 761517c 44834d0 -Author: Guus Sliepen -Date: Mon Nov 2 14:24:27 2009 +0100 - - Merge branch 'master' into 1.1 - - Conflicts: - NEWS - README - configure.in - doc/tinc.texi - doc/tincd.8.in - src/Makefile.am - src/connection.c - src/edge.c - src/meta.c - src/net.c - src/net.h - src/net_packet.c - src/net_setup.c - src/net_socket.c - src/node.c - src/openssl/rsagen.h - src/protocol_auth.c - src/protocol_edge.c - src/subnet.c - -commit 44834d030464bbe1f7733caba8d96c678f1d6cf2 -Author: Guus Sliepen -Date: Sun Nov 1 16:24:39 2009 +0100 - - Releasing 1.0.11. - -commit d331f04e4598824afc7de33ac1228cf441ae9872 -Author: Guus Sliepen -Date: Sun Nov 1 15:57:28 2009 +0100 - - Start a tinc service if it already exists. - -commit 6f6f426b353596edca77829c0477268fc2fc1925 -Author: Guus Sliepen -Date: Tue Oct 27 23:53:49 2009 +0100 - - Fast handoff of roaming MAC addresses. - - In switch mode, if a known MAC address is claimed by a second node before it - expired at the first node, it is likely that this is because a computer has - roamed from the LAN of the first node to that of the second node. To ensure - packets for that computer are routed to the second node, the first node should - delete its corresponding Subnet as soon as possible, without waiting for the - normal expiry timeout. - -commit e00b44cb98e4d50a0d426048ba01dbd80bcb5941 -Author: Guus Sliepen -Date: Sun Oct 25 01:40:07 2009 +0200 - - Move socket error interpretation to utils.h. - -commit c11dc8079b60d9f8c5b1c7e8fecd90d0fac5a20c -Author: Guus Sliepen -Date: Sun Oct 25 00:50:09 2009 +0200 - - Use WSAGetLastError() to determine cause of network errors on Windows. - - This reduces log spam and lets path MTU discovery work faster. - -commit 1bca167b7e24a9cb00ad6130c24f0bb60e208f1f -Author: Michael Tokarev -Date: Sun Oct 18 21:27:24 2009 +0400 - - Remove localedir leftovers. - -commit c3acae034c4da2d1c70f31b852b14ca098c0eeb9 -Author: Guus Sliepen -Date: Sat Oct 24 22:32:35 2009 +0200 - - Use IP_DONTFRAGMENT instead of IP_MTU_DISCOVER on Windows. - - This ensures the DF bit on outgoing UDP packets gets set on Windows when path - MTU discovery is enabled, reducing fragmentation. - -commit 242c4e2ca67d0b5c78dfe6e68a5ddcd27be1de99 -Author: Guus Sliepen -Date: Sat Oct 24 21:53:01 2009 +0200 - - Forward packets to not directly reachable hosts via UDP if possible. - - If MTU probing discovered a node was not reachable via UDP, packets for it were - forwarded to the next hop, but always via TCP, even if the next hop was - reachable via UDP. This is now fixed by retrying to send the packet using - send_packet() if the destination is not the same as the nexthop. - -commit d922db253cd098bc038449e5c591cc94c1019952 -Author: Guus Sliepen -Date: Sat Oct 24 21:35:40 2009 +0200 - - Make maxmtu equal to minmtu when fixing the path MTU to a node. - - This ensures MTU probes used to ping nodes are not too large, and prevents - restarting MTU probing unnecessarily. - -commit a8f7fccbc2b5f1c4c39fc2804abaa358b31a5080 -Author: Guus Sliepen -Date: Sat Oct 24 21:32:06 2009 +0200 - - Always reply to MTU probes via UDP. - - It could sometime happen that a node would return MTU probes via TCP, which - does not make a lot of sense. - -commit cddcdc9af34afb388a8e4bdfff6882f568b98313 -Author: Guus Sliepen -Date: Sat Oct 24 20:54:44 2009 +0200 - - Allow UDP packets with an address different from the corresponding TCP connection. - -commit 5cbddc68bade0d1f8ded1b784bb27bb44c5dc5dc -Author: Guus Sliepen -Date: Sat Oct 24 16:15:24 2009 +0200 - - Use uint32_t instead of long int for connection options. - - Options should have a fixed width anyway, but this also fixes a possible MinGW - compiler bug where %lx tries to print a 64 bit value, even though a long int is - only 32 bits. - -commit 468f393c4fabf9223a1bd15adfb3906cde90d547 -Author: Guus Sliepen -Date: Sat Oct 24 16:05:12 2009 +0200 - - Add dummy device. - -commit b6543af7626403516b5fc54c24b11d3a242a2992 -Author: Guus Sliepen -Date: Tue Oct 20 22:39:07 2009 +0200 - - Clarify and increase level of log message about MTU probes to unreachable nodes. - -commit 43a6e786648fb666a9b7be8f05c8a173031c9110 -Author: Guus Sliepen -Date: Tue Oct 20 22:33:16 2009 +0200 - - Handle weighted Subnets in switch and hub modes. - - We now handle MAC Subnets in exactly the same way as IPv4 and IPv6 Subnets. - This also fixes a problem that causes unncessary broadcasting of unicast - packets in VPNs where some daemons run 1.0.10 and some run other versions. - -commit 3a925479c2883a6a9711f7b6931863d7f2a2c09b -Author: Guus Sliepen -Date: Tue Oct 20 22:22:59 2009 +0200 - - Starting to work towards 1.0.11. - -commit 35af4051c3749cd2c2137a7eb57171a1fbb12af7 -Author: Guus Sliepen -Date: Tue Oct 20 22:14:47 2009 +0200 - - Fix a possible crash when sending the HUP signal. - - When the HUP signal is sent while some outgoing connections have not been made - yet, or are being retried, a NULL pointer could be dereferenced resulting in - tinc crashing. We fix this by more careful handling of outgoing_ts, and by - deleting all connections that have not been fully activated yet at the HUP - signal is received. - -commit 8c267d3d558ac97a4ce7381a37abb6cc4b46b133 -Author: Guus Sliepen -Date: Sun Oct 18 16:45:13 2009 +0200 - - Releasing 1.0.10. - -commit 3849de9a331ad132ed9d01c9f0cac47196624b3e -Author: Guus Sliepen -Date: Sun Oct 18 16:44:32 2009 +0200 - - Fix description of the WEIGHT environment variable. - -commit 87364c16564c897b1a2d306615804d68ea5a9ba1 -Author: Guus Sliepen -Date: Sun Oct 18 14:22:20 2009 +0200 - - Include missing header. - -commit c7fdc7d5b8d728c744b13a823e7eef9d2432c61e -Author: Guus Sliepen -Date: Mon Oct 12 23:51:57 2009 +0200 - - Remove debugging message when reading packets from a BSD device. - - This was inadvertently introduced by commit - 4a5d42178cc0954efba8b24058da9c70cc77c35a. - -commit ec4c8bcb18c1f463cf4544126e027fc8ec9b3a39 -Author: Guus Sliepen -Date: Mon Oct 12 22:14:47 2009 +0200 - - Allow the cloning /dev/tap interface to be used on FreeBSD and NetBSD. - - This device works like /dev/tun on Linux, automatically creating a new tap - interface when a program opens it. We now pass the actual name of the newly - created interface in $INTERFACE. - -commit 92b8abc921dd15b710f67335562210eb713fbb39 -Author: Guus Sliepen -Date: Sun Oct 11 18:57:58 2009 +0200 - - Use MTU probes to regularly ping other nodes over UDP. - - This keeps NAT mappings for UDP alive, and will also detect when a node is not - reachable via UDP anymore or if the path MTU is decreasing. Tinc will fall back - to TCP if the node has become unreachable. - - If UDP communication is impossible, we stop sending probes, but we retry if it - changes its keys. - - We also decouple the UDP and TCP ping mechanisms completely, to ensure tinc - properly detects failure of either method. - -commit 927064e5fd0ebf29a7ea768a7f9c4226da626a72 -Author: Guus Sliepen -Date: Sun Oct 11 15:46:52 2009 +0200 - - Small updates to the documentation. - - Mention that TCPOnly is not necessary anymore since tinc will autodetect - whether it can send via UDP or not. Also mention the WEIGHT environment - variable and the new default value (2048 bits) of RSA keys. - -commit 2c30af6c90926340a89748c63cc453b1c0b5a589 -Author: Guus Sliepen -Date: Sun Oct 11 14:20:14 2009 +0200 - - Ensure that the texinfo manual can be converted to HTML. - - The top node was made conditional with the @iftex command, since it should not - appear in PostScript and PDF output. However, it is still necessary for - texi2html, so we have to use @ifnottex instead. - - Texi2html also complains about the use of @cindex in the copyright statement, - so we remove that. - -commit a4f132770dc136d456c67b01d209e73f5f4d7a65 -Author: Guus Sliepen -Date: Sun Oct 11 13:56:04 2009 +0200 - - Revert "Raise default crypto algorithms to AES256 and SHA256." - - Although it would be better to have the new defaults, only the most recent - releases of most of the platforms supported by tinc come with a version of - OpenSSL that supports SHA256. To ensure people can compile tinc and that nodes - can interact with each other, we revert the default back to Blowfish and SHA1. - - This reverts commit 4bb3793e38b7c7f24dd308801e7f6dbb02cf02d2. - -commit 2762509be179dcb21d855f3d6f90d3ee686e3910 -Author: Guus Sliepen -Date: Sun Oct 11 13:54:05 2009 +0200 - - Remove code duplication when checking ADD_EDGE/DEL_EDGE messages. - -commit 5cddf5e52aeb20e50c887356ad23aec354e04151 -Author: Guus Sliepen -Date: Sun Oct 11 13:51:10 2009 +0200 - - Don't disconnect clients in TunnelServer mode who send unauthorised ADD_SUBNETs. - - So that we are liberal in what we accept. - -commit 430c90412c521c534113b3c4e5fc883e9b7ecff0 -Author: Borg -Date: Sat Oct 3 13:06:00 2009 +0200 - - Removed last gettext function. - -commit 3282375f4d64d9402141ac4bf142629ec2e1cd53 -Author: Guus Sliepen -Date: Tue Sep 29 16:25:20 2009 +0200 - - Remove autogenerated files from EXTRA_DIST. - - Apparently they were once necessary, but autoconf now includes them - automatically. Some of them are not used anymore, and this caused make dist to - fail. - -commit 761517c21c37a808a19b487aa116c3c19439feca -Author: Guus Sliepen -Date: Tue Sep 29 15:33:58 2009 +0200 - - Update FSF address in files not covered by the merge. - -commit 07a560eab66b575f382428a956550817697e25e2 -Author: Guus Sliepen -Date: Tue Sep 29 15:19:55 2009 +0200 - - Drop localisation and checkpoint tracing in files not covered by the merge. - -commit 7ea85043ac1fb2096baea44f6b0af27ac0d0b2cf -Merge: f1fec46 9a2b0f8 -Author: Guus Sliepen -Date: Tue Sep 29 14:55:29 2009 +0200 - - Merge branch 'master' into 1.1 - - Conflicts: - NEWS - configure.in - lib/Makefile.am - lib/pidfile.c - lib/pidfile.h - lib/utils.c - po/POTFILES.in - po/nl.po - src/Makefile.am - src/bsd/device.c - src/conf.c - src/connection.c - src/cygwin/device.c - src/edge.c - src/event.c - src/graph.c - src/linux/device.c - src/meta.c - src/mingw/device.c - src/net.c - src/net_packet.c - src/net_setup.c - src/net_socket.c - src/netutl.c - src/node.c - src/process.c - src/protocol.c - src/protocol_auth.c - src/protocol_edge.c - src/protocol_key.c - src/protocol_misc.c - src/protocol_subnet.c - src/raw_socket/device.c - src/route.c - src/solaris/device.c - src/subnet.c - src/tincd.c - src/uml_socket/device.c - -commit 9a2b0f88a9cae753ebc81c939d01403178b18a35 -Author: Guus Sliepen -Date: Sat Sep 26 12:51:52 2009 +0200 - - Update the NEWS. - -commit 46e481dc945c5572eb6091a3660f6bf258ee0cfa -Author: Guus Sliepen -Date: Fri Sep 25 21:14:56 2009 +0200 - - Add more authors to the copyright headers. - - Git's log and blame tools were used to find out which files had significant - contributions from authors who sent in patches that were applied before we used - git. - -commit 4c85542894f7fca823b119b05e07179deb24229a -Author: Guus Sliepen -Date: Fri Sep 25 00:54:07 2009 +0200 - - Drop support for localisation. - - Localised messages don't make much sense for a daemon, and there is only the - Dutch translation which costs time to maintain. - -commit a227843b739d279b63adcf3736ebb03d856080c4 -Author: Guus Sliepen -Date: Fri Sep 25 00:33:04 2009 +0200 - - Remove checkpoint tracing. - - This feature is not necessary anymore since we have tools like valgrind today - that can catch stack overflow errors before they make a backtrace in gdb - impossible. - -commit 5dde6461a321ee47b06e33f8203f2acf00a31a51 -Author: Guus Sliepen -Date: Fri Sep 25 00:14:03 2009 +0200 - - K&R style braces. - - This is essentially commit f02d3ed3e135b5326003e7f69f8331ff6a3cc219 from the - 1.1 branch, making it easier to merge between master and 1.1. - -commit ab7c61b06f6c6e991225f2fcc32d02b8e1084aee -Author: Guus Sliepen -Date: Fri Sep 25 00:01:00 2009 +0200 - - Update the address of the Free Software Foundation in all copyright headers. - -commit 0e6856b1379e278aa5ed116d0911851339a6064c -Author: Guus Sliepen -Date: Thu Sep 24 23:42:30 2009 +0200 - - Remove Ivo's old email addresses. - -commit c217d214f4f071c235bc7c463a1da6124e2570a6 -Author: Guus Sliepen -Date: Thu Sep 24 23:39:16 2009 +0200 - - Remove all occurences of $Id$. - -commit c23fcf555ee4b69f03b76a0ffb731c3a475a77e7 -Author: Guus Sliepen -Date: Thu Sep 24 23:29:46 2009 +0200 - - Update copyright information. - - - Update year numbers in copyright headers. - - Add copyright information for Michael Tokarev and Florian Forster to the - copyright headers of files to which they have contributed significantly. - - Mention Michael and Florian in AUTHORS. - - Mention that tinc is GPLv3 or later if compiled with the --enable-tunemu - flag. - -commit f1fec466e232c00c668422014029dce9114d3add -Author: Guus Sliepen -Date: Wed Sep 16 23:43:19 2009 +0200 - - Add a better autoconf check for libevent. - -commit 4bdf0e80ee4cd0d40eb6522dab05df9346a5b3d0 -Author: Guus Sliepen -Date: Wed Sep 16 20:28:30 2009 +0200 - - Replace asprintf()s not covered by the merge to xasprintf(). - -commit 1cbddbd573d786f6b2bf9812dda89d1ea5b7e021 -Author: Guus Sliepen -Date: Wed Sep 16 20:17:11 2009 +0200 - - Use correct format specifiers. - -commit 2f97bdb46b1ed0a669619e0b9acf76f43dfa648b -Author: Guus Sliepen -Date: Wed Sep 16 20:16:54 2009 +0200 - - Add missing #include. - -commit 075e6828a7533e7daa790225f17aa6bb39703278 -Merge: 9b129c0 b5ccce2 -Author: Guus Sliepen -Date: Wed Sep 16 19:55:47 2009 +0200 - - Merge branch 'master' into 1.1 - - Conflicts: - have.h - lib/dropin.c - lib/fake-getaddrinfo.c - lib/pidfile.c - src/Makefile.am - src/bsd/device.c - src/conf.c - src/connection.c - src/connection.h - src/graph.c - src/mingw/device.c - src/net.c - src/net_setup.c - src/node.c - src/protocol_key.c - src/protocol_misc.c - src/tincd.c - -commit b5ccce296848aab72d574ca3de14af5fdf3efa4d -Author: Guus Sliepen -Date: Tue Sep 15 23:22:13 2009 +0200 - - Send large packets we cannot handle properly via TCP. - - During the path MTU discovery phase, we might not know the maximum MTU yet, but - we do know a safe minimum. If we encounter a packet that is larger than that - the minimum, we now send it via TCP instead to ensure it arrives. We also - allow large packets that we cannot fragment or create ICMP replies for to be - sent via TCP. - -commit d273efb177738d429e3cef7d8db8ee5cc8dcada7 -Author: Guus Sliepen -Date: Tue Sep 15 23:04:52 2009 +0200 - - Raise default RSA key length to 2048 bits. - -commit b47c17bcdeb70b63ad9346dc97ba575597cbd803 -Author: Guus Sliepen -Date: Tue Sep 15 22:59:01 2009 +0200 - - Use a mutex to allow the TAP reader to process packets faster on Windows. - - The TAP-Win32 device is not a socket, and select() under Windows only works - with sockets. Tinc used a separate thread to read from the TAP-Win32 device, - and passed this via a local socket to the main thread which could then select() - from it. We now use a global mutex, which is only unlocked when the main thread - is waiting for select(), to allow the TAP reader thread to process packets - directly. - -commit 802a50ffcd5f39bfc6424ac841de4e41154092fc -Author: Guus Sliepen -Date: Tue Sep 15 22:58:16 2009 +0200 - - Remove extra {. - -commit 4bb3793e38b7c7f24dd308801e7f6dbb02cf02d2 -Author: Guus Sliepen -Date: Tue Sep 15 12:08:05 2009 +0200 - - Raise default crypto algorithms to AES256 and SHA256. - - In light of the recent improvements of attacks on SHA1, the default hash - algorithm in tinc is now SHA256. At the same time, the default symmetric - encryption algorithm has been changed to AES256. - -commit 633c0cf1b067d118d5453bc8522fab65ffc82d2c -Author: Guus Sliepen -Date: Tue Sep 15 00:36:07 2009 +0200 - - Use access() instead of stat() for checking whether scripts exist. - -commit 6f1e0ece4e61f30612ed84ca4640635a02892cc8 -Author: Guus Sliepen -Date: Tue Sep 15 00:28:20 2009 +0200 - - Remove dropin random() function, as it is not used anymore. - -commit fa9bedd47cf8c143e801889c78f0a0979ac4d2fc -Author: Guus Sliepen -Date: Tue Sep 15 00:24:31 2009 +0200 - - Allow compiling for Windows XP and higher. - - This allows us to use getaddrinfo(), getnameinfo() and related functions, which - allow tinc to make connections over existing IPv6 networks. These functions are - not available on Windows 2000 however. By default, support is enabled, but when - compiling for Windows 2000 the configure switch --with-windows2000 should be - used. - - Since getaddrinfo() et al. are not functions but macros on Windows, we have to - use AC_CHECK_DECLS() instead of AC_CHECK_FUNCS() in configure.in. - -commit f80bf14f28925df6eaa56f3ed77adaf418ab9890 -Author: Guus Sliepen -Date: Mon Sep 14 23:28:28 2009 +0200 - - Also do not use drand48(), it is not available on Windows. - -commit 35e87b903e08fc51975a8cc97f06251d5153a424 -Author: Guus Sliepen -Date: Mon Sep 14 23:06:00 2009 +0200 - - Use only rand(), not random(). - - We used both rand() and random() in our code. Since it returns an int, we have - to use %x in our format strings instead of %lx. This fixes a crash under - Windows when cross-compiling tinc with a recent version of MinGW. - -commit 75773efe2689d347a2f219c5f27e4a82eef1236b -Author: Guus Sliepen -Date: Sun Sep 13 14:08:59 2009 +0200 - - Apparently it's impolite to ask GCC to subtract two pointers. - - If two pointers do not belong to the same array, pointer subtraction gives - nonsensical results, depending on the level of optimisation and the - architecture one is compiling for. It is apparently not just subtracting the - pointer values and dividing by the size of the object, but uses some kind of - higher magic not intended for mere mortals. GCC will not warn about this at - all. Casting to void * is also a no-no, because then GCC does warn that strict - aliasing rules are being broken. The only safe way to query the ordering of two - pointers is to use the (in)equality operators. - - The unsafe implementation of connection_compare() has probably caused the "old - connection_t for ... still lingering" messages. Our implementation of AVL trees - is augmented with a doubly linked list, which is normally what is traversed. - Only when deleting an old connection the tree itself is traversed. - -commit 23e151aeed6b3ffe0fab10f51ffdb134deb7a852 -Author: Guus Sliepen -Date: Sun Sep 13 14:07:40 2009 +0200 - - Remove superfluous call to avl_delete(). - -commit 9915f2abbedb7f1aa2b9e2f81d52ddcfca60e82d -Author: Guus Sliepen -Date: Sat Sep 12 14:19:36 2009 +0200 - - Handle unicast packets larger than PMTU in switch mode. - - If PMTUDiscovery is enabled, and we see a unicast packet that is larger than - the path MTU in switch mode, treat it just like we would do in router mode. - -commit 7242868b64f9d6f62b6c5bbf1526eb632ed9a4d6 -Author: Guus Sliepen -Date: Sat Sep 12 13:40:32 2009 +0200 - - Allow PMTUDiscovery in switch and hub modes again. - - PMTUDiscovery was disabled in commit d5b56bbba56480b5565ffb38496175a7c1df60ac - because tinc did not handle packets larger than the path MTU in switch and hub - modes. We now allow it again in preparation of proper support, but default to - off. - -commit 052ff8b2c598358d1c5febaa9f9f5fc5d384cfd3 -Author: Guus Sliepen -Date: Sat Sep 12 13:34:11 2009 +0200 - - Put Subnet weight in a separate environment variable. - - Commit 5674bba5c54c1aee3a4ac5b3aba6b3ebded91bbc introduced weighted Subnets, - but the weight was included in the SUBNET variable passed to subnet-up/down - scripts. This makes it harder to use in those scripts. The weight is now - stripped from the SUBNET variable and put in the WEIGHT variabel. - -commit a60a0a1f1357508063ee565d672c39898a787e33 -Author: Guus Sliepen -Date: Thu Sep 10 19:51:08 2009 +0200 - - Don't stat() on iPhone/iPod. - - Grzegorz Dymarek noted that tinc segfaults at the stat() call in - execute_script() on the iPhone. We can omit the stat() call for the moment, - the subsequent call to system() will fail with just a warning. - -commit 4a5d42178cc0954efba8b24058da9c70cc77c35a -Author: Guus Sliepen -Date: Thu Sep 10 19:32:54 2009 +0200 - - Add support for iPhones and recent iPods. - - This is a slightly modified patch from Grzegorz Dymarek that allows tinc to use - the tunemu device, which allows tinc to be compiled for iPhones and recent - iPods. To enable support for tunemu, the --enable-tunemu option has to be used - when running the configure script. - -commit ff946d0423fe547ea42bb11acfb3035c3b8aee4e -Author: Guus Sliepen -Date: Wed Sep 9 14:51:36 2009 +0200 - - Another safe bitfield conversion. - -commit dd6226062c2356d2a3679e2c7972be71233cb9de -Author: Guus Sliepen -Date: Wed Sep 9 13:23:16 2009 +0200 - - Add the GPL license to the repository. - - Tinc is licensed under the GPL version 2 or later. To ensure autoconf does not - install the wrong license if COPYING is missing, we have to put the right one - in place. - -commit 81afa26e4ad53bea00da18a7666f63d33cf3f588 -Author: Guus Sliepen -Date: Wed Sep 9 12:04:08 2009 +0200 - - Convert bitfields to integers in a safe way. - - This is commit eb391c52eed46f3f03b404553df417851fc0cb90 redone, but without the - non-standard anonymous union. - -commit 9b394bc887695da6db74f4b9796b4823e553f8cc -Author: Guus Sliepen -Date: Tue Sep 8 21:45:24 2009 +0200 - - Ensure tinc compiles with gcc -std=c99. - - We use a lot of C99 features already, but also some extensions which are not in - the standard. - -commit f52ea0a7eb0383cc2a5f41db1bf24c39424fdb04 -Author: Guus Sliepen -Date: Tue Sep 8 18:21:52 2009 +0200 - - UNIX signal numbers start at 1. - -commit 73d77dd416b87b7c4e9b6aa450f64846235cd2b4 -Author: Guus Sliepen -Date: Tue Sep 8 18:18:36 2009 +0200 - - Replace asprintf() by xasprintf(). - -commit 3e55dc77f4ba19fd9e79f3d5ce9d28bb6b05019e -Author: Guus Sliepen -Date: Tue Sep 8 18:18:16 2009 +0200 - - Check the return value of fscanf() when reading a PID file. - -commit 5e0efd53e797a2b5468b91b41b6122f3b942efb2 -Author: Guus Sliepen -Date: Tue Sep 8 18:16:58 2009 +0200 - - Add xasprintf() and xvasprintf(). - - These functions wrap asprintf() and vasprintf(), and check the return value. If - the function failed, tinc will exit with an error message, similar to xmalloc() - and friends. - -commit 63fe89e9eb8ef9077bfe3cd416c86820715eb33b -Author: Michael Tokarev -Date: Sat Sep 5 17:24:41 2009 +0400 - - Remove extra semicolon in my definition of setpriority() - -commit 5a7fc58012da10b96073804994777255463d1b8d -Author: Guus Sliepen -Date: Tue Sep 8 16:35:28 2009 +0200 - - Always remove a node from the UDP tree before freeing it. - - Valgrind caught tinc reading free'd memory during a purge(). This was caused by - first removing it from the main node tree, which will already call free_node(), - and then removing it from the UDP tree. This might cause spurious segmentation - faults. - -commit de029ce46056e02908b5390da9b71a6a59133f26 -Author: Guus Sliepen -Date: Thu Jun 11 19:39:25 2009 +0200 - - Change level of some debug messages, zero pointer after freeing hostname. - -commit 66be914d35cb7e7ea4dd4aed68ae9e41addd9f70 -Author: Guus Sliepen -Date: Thu Jun 11 19:26:34 2009 +0200 - - Do not log errors when recvfrom() returns EAGAIN or EINTR. - - Although we select() before we call recvfrom(), it sometimes happens that - select() tells us we can read but a subsequent read fails anyway. This is - harmless. - -commit df4add94a4a6461758b218a9ad257efc735062fe -Author: Guus Sliepen -Date: Thu Jun 11 19:07:54 2009 +0200 - - Remove pending MTU probe events when a node's reachability status changes. - -commit 36f8e4da8b1708474505f5a1fa8cf1ba848921de -Author: Guus Sliepen -Date: Thu Jun 11 18:36:08 2009 +0200 - - Don't try to send MTU probes to unreachable nodes. - - If there is an outstanding MTU probe event for a node which is not reachable - anymore, a UDP packet would be sent to that node, which caused a key request to - be sent to that node, which triggered a NULL pointer dereference. Probes and - other UDP packets to unreachable nodes are now dropped. - -commit 9b129c07e273ae113f3c67a9feeee82e8146f3a1 -Author: Guus Sliepen -Date: Sat Jun 6 20:14:51 2009 +0200 - - Fix pointer arithmetic when creating and verifying message authentication codes. - -commit 4124b9682f8f890acb25d0c92f2583eef670274a -Author: Guus Sliepen -Date: Sat Jun 6 19:04:04 2009 +0200 - - Handle truncated message authentication codes. - -commit 5a132550deb58473285e5f91705d286aef47be71 -Merge: 08aabbf 591c38e -Author: Guus Sliepen -Date: Fri Jun 5 23:03:28 2009 +0200 - - Merge branch 'master' into 1.1 - - Conflicts: - doc/tincd.8.in - lib/pidfile.c - src/graph.c - src/net.c - src/net.h - src/net_packet.c - src/net_setup.c - src/net_socket.c - src/netutl.c - src/node.c - src/node.h - src/protocol_auth.c - src/protocol_key.c - src/tincd.c - -commit 261d1eac1c5bbe6c87aa707566f290e611169432 -Author: Guus Sliepen -Date: Fri Jun 5 16:14:31 2009 +0200 - - Properly set HMAC length for incoming packets. - -commit 591c38eb38dbf0851bdebdd50b08d1bcbf6d7b0f -Author: Michael Tokarev -Date: Fri Jun 5 13:33:58 2009 +0400 - - try outgoing connections before chroot/drop_privs - - When chrooted, we either need to force-initialize resolver - and/or nsswitch somehow (no clean way) or resolve all the - names we want before entering chroot jail. The latter - looks cleaner, easier and it is actually safe because - we still don't talk with the remote nodes there, only - initiating outgoing connections. - -commit a42a8dde45fe95aa3fd3f7f15a74c5166efe3633 -Author: Michael Tokarev -Date: Fri Jun 5 11:58:17 2009 +0400 - - cleanup setpriority thing to make it readable - -commit a5fb0d8c6c384b9ea1074fb469c0a3dd5b874e98 -Author: Guus Sliepen -Date: Thu May 28 23:18:22 2009 +0200 - - Add some const where appropriate. - -commit 41c10c5a966000531099c79d6006429253ff8fd6 -Author: Guus Sliepen -Date: Thu May 28 22:51:30 2009 +0200 - - Add ProcessPriority option. - - This option can be set to low, normal or high. On UNIX flavours, this changes - the nice value of the process by +10, 0 and -10 respectively. On Windows, it - sets the priority to BELOW_NORMAL_PRIORITY_CLASS, NORMAL_PRIORITY_CLASS and - HIGH_PRIORITY_CLASS respectively. - - A high priority might help to reduce latency and packet loss on the VPN. - -commit 41a05f59ba2c3eb5caab555f096ed1b9fbe69ee3 -Author: Florian Forster -Date: Wed May 27 14:20:24 2009 +0200 - - src/net_socket.c: Bind outgoing TCP sockets to `BindToAddress'. - - If a host has multiple addresses on an interface, the source address of the TCP - connection(s) was picked by the operating system while the UDP packets used a - bound socket, i. e. the source address was the address specified by the user. - This caused problems because the receiving code requires the TCP connection and - the UDP connection to originate from the same IP address. - - This patch adds support for the `BindToInterface' and `BindToAddress' options - to the setup of outgoing TCP connections. - - Tested with Debian Etch on x86 and Debian Lenny on x86_64. - - Signed-off-by: Florian Forster - -commit 6b415a1a7f5bad2fff7b133ef2a2febccb96d6e5 -Author: Florian Forster -Date: Wed May 27 09:27:44 2009 +0200 - - src/linux/device.c: Fix segfault when running without `--net'. - - If running without `--net', the (global) variable `netname' is NULL. This - creates a segmentation fault because this NULL-pointer is passed to strdup: - - Program terminated with signal 11, Segmentation fault. - #0 0xb7d30463 in strlen () from /lib/tls/i686/cmov/libc.so.6 - (gdb) bt - #0 0xb7d30463 in strlen () from /lib/tls/i686/cmov/libc.so.6 - #1 0xb7d30175 in strdup () from /lib/tls/i686/cmov/libc.so.6 - #2 0x0805bf47 in xstrdup (s=0x0) at xmalloc.c:118 <--- - #3 0x0805be33 in setup_device () at device.c:66 - #4 0x0805072e in setup_myself () at net_setup.c:432 - #5 0x08050db2 in setup_network () at net_setup.c:536 - #6 0x0805b27f in main (argc=Cannot access memory at address 0x0) at tincd.c:580 - - This patch fixes this by checking `netname' in `setup_device'. An alternative - would be to check for NULL-pointers in `xstrdup' and return NULL in this case. - - Signed-off-by: Florian Forster - -commit a8a65cee083a27afe42cab360596e1453e7141b9 -Author: Michael Tokarev -Date: Sun May 24 17:23:24 2009 +0400 - - tunnelserver: log which ADD_SUBNET was refused - - Add some logging about refused ADD_SUBNET - (it causes subsequent client disconnect so it's - important to know which subnet was at fault). - - Maybe we should just ignore it completely. - -commit 4e9e3ca89dba68cbacaaa15ddfb298b181a969da -Author: Guus Sliepen -Date: Mon May 25 15:04:33 2009 +0200 - - Do not forward broadcast packets when TunnelServer is enabled. - - First of all, the idea behind the TunnelServer option is to hide all other - nodes from each other, so we shouldn't forward broadcast packets from them - anyway. The other reason is that since edges from other nodes are ignored, the - calculated minimum spanning tree might not be correct, which can result in - routing loops. - -commit 7fc69bc73b15349dafc193a50464caeb2f978369 -Author: Guus Sliepen -Date: Mon May 25 12:19:37 2009 +0200 - - Use packet size before decompression to calculate path MTU. - - Since compression can either grow or shrink a packet, the size of an MTU probe - after decompression might not reflect the real path MTU. Now we use the size - before decompression, which is independent of the compression algorithm, and - substract a safety margin such that the calculated path MTU will be safe even - for packets which grow as much as possible after compression. - -commit 1b3add6c29f8eb424a62837e89fe7d384fc94a48 -Author: Guus Sliepen -Date: Mon May 25 12:19:08 2009 +0200 - - Add declaration for sockaddrcmp_noport(). - -commit ca5b67111e4d797d15623c2163f67fe489dc3bf2 -Author: Michael Tokarev -Date: Sun May 24 22:32:24 2009 +0400 - - Fix ans_key exchange in recent changes - - send_ans_key() was using the wrong in vs. outkeylength to - terminate the key being sent, so it was always empty. - -commit 7034338bc36d9ea96d152091b9d58c2afc3f0c20 -Author: Guus Sliepen -Date: Sun May 24 19:35:51 2009 +0200 - - Use xrealloc instead of if(ptr) ptr = xmalloc(). - -commit e012e752f4f1a2b06dfab4640bbbea8f084999ff -Author: Guus Sliepen -Date: Sun May 24 19:31:31 2009 +0200 - - Fix initialisation of packet decryption context broken by commit 3308d13e7e3bf20cfeaf6f2ab17228a9820cea66. - - Instead of a single, global decryption context, each node has its own context. - However, in send_ans_key(), the global context was initialised. This commit - fixes that and removes the global context completely. - - Also only set status.validkey after all checks have been evaluated. - -commit 0246939ce18e1af9660b782b6814be182a7af9da -Author: Michael Tokarev -Date: Fri May 22 01:10:16 2009 +0400 - - don't log every strange packet coming to the UDP port - - it's a sure way to fill up syslog. Only log those if - debug level is up to PROTOCOL - -commit 576899ef0dec3aaede9b8ac101d189798587a646 -Author: Guus Sliepen -Date: Sun May 24 17:13:00 2009 +0200 - - Fix link to Mattias Nissler's tun/tap driver for MacOS/X. - - Thanks to Martin Christof Kindsmüller for spotting. - -commit 2c67eafc6e6c5e210636c0d2bad15827bf2d7cf0 -Author: Guus Sliepen -Date: Sun May 24 15:58:47 2009 +0200 - - If PMTUDiscovery is not set, do not forward packets via TCP unnecessarily. - -commit 7e4d57adf54ce369e4111bde0ccd3ea4b9e853ee -Author: Michael Tokarev -Date: Fri May 22 01:01:35 2009 +0400 - - ignore indirect edge registrations in tunnelserver mode - - In tunnelserver mode we're not interested to hear about - our client edges, just like in case of subnets. Just - ignore all requests which are not about our node or the - client node. - - The fix is very similar to what was done for subnets. - - Note that we don't need to add the "unknown" nodes to - the list in tunnelserver mode too, so move allocation - of new nodes down the line. - -commit 3759aa5f7745709c43f81faa36510ff650b4bf99 -Author: Michael Tokarev -Date: Wed May 20 18:40:04 2009 +0400 - - TunnelServer: Don't disconnect client on DEL_SUBNET too - - Similar changes as was in 2327d3f6eb5982bcc922ff1ab1ec436ba6aeffdc - but for del_subnet_h(). - - Before, we vere returning false (and causing disconnect of the - client) in case of tunnelserver and the client sending DEL_SUBNET - for non-his subnet or for subnet which owner isn't in our connection - list. - - After the mentioned change to add_subnet_h() that routine does not - add such indirect owners to the connection list anymore, so that - was ok (owner == NULL and we return true). - - But if we too has a connection with the node about which the client - is sending DEL_SUBNET notification, say, because that client lost - connection with that other node, we'll disconnect this client from - us too, returning false for indirect DEL_SUBNET. - - Fix that by allowing and ignoring indirect DEL_SUBNET in tunnelserver - mode. - - Also rearranged the function a bit, to match add_subnet_h() (in - particular, syntax-check everything first, see if we've seen this - request before). - - And also fix some comments. - -commit 218adee785df7c79ac18395d056a2eb6d63c407f -Author: Michael Tokarev -Date: Mon May 18 17:34:30 2009 +0400 - - format 'not supported on this platform' error message - - Format it in a similar way in all places, to make translation happier. - No functional changes. - -commit 54cb6b1aecb06a1ca44a7a60c74dd0d65b0043dd -Author: Michael Tokarev -Date: Mon May 18 17:00:00 2009 +0400 - - change error messages in droppriv code to match the rest - - Change formatting of error messages about failed syscalls - to be the same as in other places in tincd. - - Also suggest a change in "$foo not supported on this platform" - message as it's now used more than once. - -commit d4f9863635d06665cfbd3c46dc482344de240e97 -Author: Michael Tokarev -Date: Mon May 18 16:53:08 2009 +0400 - - bugfix: chdir(/) after chroot - - Fix the famous chdir(".") vs chdir("/") after chroot(something). - -commit 6be5d4f5b67764115b37528d2fe01bd245b3cd3e -Author: Michael Tokarev -Date: Mon May 18 16:49:39 2009 +0400 - - bugfix: move mlock to after detach() so it works for child, not parent - - mlock()/mlockall() are not persistent across fork(), and it's - done in parent process before daemon() which does fork(). So - basically, current --mlock does nothing useful. - - Move mlock() to after detach() so it works for child process - instead of parent. - - Also, check if the platform supports mlock right when processing - options (since else we'll have to die after startup, not at - startup, the error message will be in log only). - -commit cdf7f13c31310da0c40819fd812e19519bf4318c -Author: Michael Tokarev -Date: Mon May 18 16:28:55 2009 +0400 - - bugfix: initialize pid (as read from pidfile) to zero - - If we didn't read any number from a pid file, we'll return - an unitialized variable to the caller, and it will treat - that garbage as a pid of a process (possible to kill). - - Fix that. - -commit ec316aa32e8567395a88c4583007f01ffae008ce -Author: Michael Tokarev -Date: Mon May 18 16:25:41 2009 +0400 - - Implement privilege dropping - - Add two options, -R/--chroot and -U/--user=user, to chroot to the - config directory (where tinc.conf is located) and to perform - setuid to the user specified, after all the initialization is done. - - What's left is handling of pid file since we can't remove it anymore. - -commit 6698f7c390a5ae2f262e30560d9df59f9d5c418d -Author: Michael Tokarev -Date: Mon May 18 16:25:10 2009 +0400 - - Rename setup_network_connections() and split out try_outgoing_connections() - - In preparation of chroot/setuid operations, split out call to - try_outgoing_connections() from setup_network_connections() - (which was the last call in setup_network_connections()). - This is because dropping privileges should be done in-between - setup_network_connections() and try_outgoing_connections(). - - This patch renames setup_network_connections() to setup_network() - and moves call to try_outgoing_connections() into main routine. - - No functional changes. - -commit 3308d13e7e3bf20cfeaf6f2ab17228a9820cea66 -Author: Guus Sliepen -Date: Fri Apr 3 01:05:23 2009 +0200 - - Handle UDP packets from different and ports than advertised. - - Previously, tinc used a fixed address and port for each node for UDP packet - exchange. The port was the one advertised by that node as its listening port. - However, due to NAT the port might be different. Now, tinc sends a different - session key to each node. This way, the sending node can be determined from - incoming packets by checking the MAC against all session keys. If a match is - found, the address and port for that node are updated. - -commit 08aabbf9317806bc50a9a6693ca866c8936ce26b -Merge: 551cd19 43fa728 -Author: Guus Sliepen -Date: Mon Mar 9 19:02:24 2009 +0100 - - Merge branch 'master' into 1.1 - - Conflicts: - NEWS - README - doc/tinc.conf.5.in - doc/tinc.texi - po/nl.po - src/conf.c - src/connection.c - src/event.c - src/graph.c - src/net.c - src/net_packet.c - src/net_socket.c - src/node.c - src/node.h - src/openssl/rsagen.h - src/protocol_auth.c - src/protocol_key.c - src/protocol_misc.c - src/subnet.c - src/subnet.h - src/tincd.c - -commit 43fa7283ac01f2ecc95381b519ef6b3342546f35 -Author: Guus Sliepen -Date: Mon Mar 9 14:04:31 2009 +0100 - - Use a simple Random Early Drop algorithm in send_tcppacket(). - -commit d5b56bbba56480b5565ffb38496175a7c1df60ac -Author: Guus Sliepen -Date: Mon Mar 9 13:48:54 2009 +0100 - - Disable PMTUDiscovery in switch and hub modes. - - In switch and hub modes, tinc does not generate ICMP packets in response to - packets that are larger than the path MTU. However, if PMTUDiscovery is - enabled, the IP_MTU_DISCOVER and IPV6_MTU_DISCOVER option is set on the UDP - sockets, which causes all UDP packets to be sent with the DF bit set, causing - large packets to be dropped, even if they would otherwise be routed fine. - -commit 78fc59e994c764d072bf0045177f690a378d1308 -Author: Guus Sliepen -Date: Thu Mar 5 14:12:36 2009 +0100 - - Update THANKS and copyright information. - -commit 5674bba5c54c1aee3a4ac5b3aba6b3ebded91bbc -Author: Guus Sliepen -Date: Thu Mar 5 13:34:13 2009 +0100 - - Allow weight to be assigned to Subnets. - - Tinc allows multiple nodes to own the same Subnet, but did not have a sensible - way to decide which one to send packets to. Tinc also did not check the - reachability of nodes when deciding where to route packets to, so it would not - automatically fail over to a reachable node. - - Tinc now assigns a weight to each Subnet. The default weight is 10, with lower - weights having higher priority. The Subnets are now internally sorted in the - same way as the kernel's routing table, and the Subnets are search linearly, - skipping those of unreachable nodes. A small cache of recently used addresses - is used to speed up the lookup functions. - -commit 76a1bcaffcf1f1abf81fdda379b703a004640cb4 -Author: Michael Tokarev -Date: Sat Feb 28 16:37:51 2009 +0300 - - Enable PMTUDiscovery only if BOTH sides wants it. - - Don't enable PMTUDiscovery if at least one side does not support it. - Before it was enabled if at least one side supported it, now both are required. - -commit 1c1a67fd93530b9d16538ab2897c3911d3b16574 -Author: Guus Sliepen -Date: Tue Feb 17 14:43:05 2009 +0100 - - Handle neighbor solicitation requests without link layer addresses. - - Apparently FreeBSD likes to send out neighbor solicitation requests, even on a - tun interface where this is completely pointless. These requests do not have an - option header containing a link layer address, so the proxy-neighborsol code - was treating these requests as invalid. We now handle such requests, and send - back equally pointless replies, also without a link layer address. This seems - to satisfy FreeBSD. - -commit 2327d3f6eb5982bcc922ff1ab1ec436ba6aeffdc -Author: Michael Tokarev -Date: Mon Feb 9 23:51:10 2009 +0100 - - Allow tunnelserver to work with clients that have other peers. - - In TunnelServer mode, tinc server disconnects any client if it announces - indirect subnets -- subnets that are not theirs (e.g. subnets for nodes - the CLIENT has connections now, even if those nodes are known to the server - too). Fix that by ignoring such (indirect) announces instead. - - While we're at it, move check for such indirect subnet registration to - before allocating new node structure, as in TunnelServer mode we don't - really need to know that other node. - -commit 23730375f27c32e0fe1a59c7a761dd85296a7a4a -Author: Guus Sliepen -Date: Tue Feb 3 14:54:45 2009 +0100 - - Disable old RSA keys when generating new ones. - - When generating an RSA keypair, the new public and private keys are appended to - files. However, when OpenSSL reads keys it only reads the first in a file, not - the last. Instead of printing an easily ignored warning, tinc now disables old - keys when appending new ones. - -commit 0d0dfd0852e9b2c9a7660880966a3c84790d5ea2 -Author: Guus Sliepen -Date: Tue Jan 20 14:21:50 2009 +0100 - - Validate Name before using it in a filename when generating a keypair. - -commit 0966cca8ab6dcde2747c717f21d73fd332e04242 -Author: Guus Sliepen -Date: Tue Jan 20 14:20:44 2009 +0100 - - Allow reading config files with CRLF endings on Unix systems. - -commit d1910ac198232573c1b18d8238a27bc29bc73f8a -Author: Guus Sliepen -Date: Tue Jan 20 13:19:31 2009 +0100 - - Remove unused definitions from net.h. - -commit 503c32eb0ef9d6329e931559082f4ddf6d487dc6 -Author: Guus Sliepen -Date: Tue Jan 20 13:12:41 2009 +0100 - - Use a global list to track outgoing connections. - - Previously an outgoing_t was maintained for each outgoing connection, - but the pointer to it was either stored in a connection_t or in an event_t. - This made it very hard to keep track of and to clean up. - - Now a list is created when tinc starts and reads all the ConnectTo variables, - and which is recreated when tinc receives a HUP signal. - -commit a7e793c94ec414eb71ec2aa3debc9e2e5ed5cfef -Author: Guus Sliepen -Date: Mon Jan 19 23:17:28 2009 +0100 - - Add missing cleanup functions in close_network_connections(). - -commit 116065afe352221ac6c2c8e34c109252004d6a59 -Author: Guus Sliepen -Date: Mon Jan 19 22:50:05 2009 +0100 - - Change flush_events() to expire_events(). - - The former function made a totally bogus shallow copy of the event_tree, called - the handler of each event and then deleted the whole tree. This should've - caused tinc to crash when an ALARM signal was sent more than once, but for some - reason it didn't. It also behaved incorrectly when a handler added a new event. - - The new function just moves the expiration time of all events to the past. - -commit a39a9506cd041a7092a98498b362eaacfd2f33c3 -Author: Guus Sliepen -Date: Fri Jan 9 12:36:06 2009 +0100 - - Move free()s at the end om main() to the proper destructor functions. - -commit 67df7fb7e1c9eefe4bbc920fdc68b595ef28abd9 -Author: Guus Sliepen -Date: Sat Jan 3 22:33:55 2009 +0100 - - Only send packets via UDP if UDP communication is possible. - - When no session key is known for a node, or when it is doing PMTU discovery but - no MTU probes have returned yet, packets are sent via TCP. Some logic is added - to make sure intermediate nodes continue forwarding via TCP. The per-node - packet queue is now no longer necessary and has been removed. - -commit b069da90d67b49dce041f513a3855b8da3d82f80 -Author: Guus Sliepen -Date: Sat Jan 3 22:06:10 2009 +0100 - - Consistently allocate device and iface variables on the heap. - - This fixes a segfault when no Device has been specified and tinc exits, and it - would try to free() a static string. Thanks to Borg for spottin. - -commit f81cea3bdc8683b27188cd8f24a2de906a29eb81 -Author: Guus Sliepen -Date: Sat Dec 27 11:09:43 2008 +0100 - - Update documentation for git. - -commit c81f90b91a054eeafcc3c8c45abc52045e4a8146 -Author: Guus Sliepen -Date: Fri Dec 26 13:47:34 2008 +0000 - - Releasing 1.0.9. - -commit a4d99ebf5042dedb609359cbbfc3fa4630b5fc70 -Author: Guus Sliepen -Date: Fri Dec 26 12:46:45 2008 +0000 - - Add missing parentheses in check for IPv4 multicast addresses. - -commit 099bc56f53e7d3cb7b799d26ff9535673ff03e1c -Author: Guus Sliepen -Date: Tue Dec 23 23:14:37 2008 +0000 - - Apply patch from Max Rijevski fixing a memory leak when closing connections. - It also cleans up more when stopping tinc, helping tools like valgrind. - -commit de032054dee67bcc406b4a15fb9e957a766d016a -Author: Guus Sliepen -Date: Tue Dec 23 22:31:38 2008 +0000 - - Handle broadcast and multicast packets in router mode. - Multicast packets are treated as broadcast packets. - Based on a patch from Max Rijevski. - -commit a5f899a9794f215e8174455ead04862a2c14a5b1 -Author: Guus Sliepen -Date: Mon Dec 22 21:49:23 2008 +0000 - - Update the manpage as well, and some whitespace to make its source more legible. - -commit e8f08ced76bf1b9a94dd0dc874ad22761ad8900b -Author: Guus Sliepen -Date: Mon Dec 22 21:29:21 2008 +0000 - - Update documentation. - - TCPOnly is not experimental. - - Do not mention old Linux kernels and Ethertap anymore. - - Document the DeviceType, PMTU and PMTUDiscovery options. - -commit 0e4d419aae8a82f2ae4552f755894a9bc70c83d2 -Author: Guus Sliepen -Date: Mon Dec 22 20:35:45 2008 +0000 - - Enable PMTU discovery by default. - -commit e9576632dc4b780b867044269d06cc50f76d8c05 -Author: Guus Sliepen -Date: Mon Dec 22 20:27:52 2008 +0000 - - Update copyright information. - -commit f50dc972cde2644588eabf35a2422fe0e372a024 -Author: Guus Sliepen -Date: Mon Dec 22 19:43:49 2008 +0000 - - Update Dutch translation. - -commit 26b490e86bc305b150200c0b08cd8e9c3bd605fb -Author: Guus Sliepen -Date: Mon Dec 22 19:40:40 2008 +0000 - - Make sure IPv6 sockets are IPv6 only. - This will get rid of the "Can't bind to 0.0.0.0 port 655/tcp: Address already - in use" message on Linux. - -commit c6830ba821e6387be961ca68b32992382a74a0e9 -Author: Guus Sliepen -Date: Mon Dec 22 19:33:37 2008 +0000 - - Use TUNIFHEAD by default on FreeBSD to make sure IPv6 works. - -commit a269ec4193900feee01ac83f0e18a6e2b98e751f -Author: Guus Sliepen -Date: Sun Dec 21 16:19:31 2008 +0000 - - Treat virtual network device as tap if Mode = switch or hub. - On OpenBSD, the link0 flag should still be set in tinc-up or by other means. - -commit 551cd19406a560d0d206bff5b4e9da064ec222b6 -Author: Guus Sliepen -Date: Sun Dec 14 12:47:26 2008 +0000 - - Move RSA key generation into the wrappers. - -commit 911c05f873ad967c40d04aa7347b1067fe62c055 -Author: Guus Sliepen -Date: Thu Dec 11 20:49:14 2008 +0000 - - Make sure IPv6 sockets are IPv6 only. - -commit 6e80da3370249caa1082c23c3ef55f338d1e9e74 -Author: Guus Sliepen -Date: Thu Dec 11 18:07:26 2008 +0000 - - Use Dijkstra's algorithm. Based on patches from Max Rijevskiy. - -commit 26a228e3025c3970fd461af777013e3807b0fc58 -Author: Guus Sliepen -Date: Thu Dec 11 18:05:59 2008 +0000 - - Remove wrong checks. - -commit 636200d1a2024982fe5b3062153daa72a8253015 -Author: Guus Sliepen -Date: Thu Dec 11 15:56:18 2008 +0000 - - Remove unnecessary parentheses from sizeof, apply sizeof to variables instead of types whereever possible. - -commit a9bdfb424e7a469d15156aa44bbe2fd0b8e28531 -Author: Guus Sliepen -Date: Thu Dec 11 15:42:46 2008 +0000 - - Fix compiler warnings. - -commit 76165488f8201a59e649b4eec02ee31398b3fb92 -Author: Guus Sliepen -Date: Thu Dec 11 15:21:40 2008 +0000 - - Backport fixes from trunk since revision 1555. - -commit 046158a216e78a0412186ec8463157f6bce45d5d -Author: Guus Sliepen -Date: Thu Dec 11 14:44:44 2008 +0000 - - Use the crypto wrappers again instead of calling OpenSSL directly. - This theoretically allows other cryptographic libraries to be used, - and it improves the readability of the code. - -commit 8c69f42d7d9b4d9d5f6b6656cfc1bf1e1abee854 -Author: Guus Sliepen -Date: Thu Dec 11 14:43:13 2008 +0000 - - Move AC_GNU_SOURCE up to make autoconf happy. - Also bump libgcrypt dependency to 1.4.0, because that version supports the OFB cipher mode. - -commit 8e8fe805c81d3edc974c12c468f793ea0c1e5ee7 -Author: Guus Sliepen -Date: Thu Dec 11 14:03:52 2008 +0000 - - Only show meta connection related debug messages when debug level >= 4 - -commit 40bebbb19fd69fa094e2f6c3c1474adc0105b048 -Author: Guus Sliepen -Date: Thu Dec 11 13:59:46 2008 +0000 - - Look in the configured sbin directory for the tincd binary. - -commit 38c2d6c1dae3f09c68baa37fd24caa2e0ec6d8ad -Author: Guus Sliepen -Date: Fri Dec 5 14:17:39 2008 +0000 - - Correct debug message. - -commit a36259435c17f76cf12476234a56f40fcd8faf41 -Author: Guus Sliepen -Date: Tue Nov 18 15:11:27 2008 +0000 - - Prevent freeing a NULL pointer when a hostname is unresolvable. - -commit 4a1740ede7c1992f7f3da5e197db9975c0344ac3 -Author: Guus Sliepen -Date: Sat Oct 25 19:54:00 2008 +0000 - - Do not try to send REQ_KEY or ANS_KEY requests to unreachable nodes. - -commit cb52aa06833a69e57b5e26337e51a4d375b6d8fb -Author: Guus Sliepen -Date: Sat Oct 25 18:10:08 2008 +0000 - - Fix reading configuration files that do not end with a newline. - -commit b2cee41b187d79c095914d1097b8ff34a0609ec3 -Author: Guus Sliepen -Date: Fri Dec 14 21:17:08 2007 +0000 - - Make sure the prefixlength of subnets is sane. - Thanks to Sven-Haegar Koch for spotting the bug and providing a fix. - -commit fe2f1fceb546ca4326435cac26bcf3f513e82b43 -Author: Scott Lamb -Date: Thu Nov 8 19:18:44 2007 +0000 - - Use a control socket directory to restrict access - - This provides reasonable security even on Solaris. The sysadmin is - responsible for securing the control socket's ancestors from the - grandparent on. - - We could add a cryptographic handshake later if desired. - -commit b1f8c65a2cfa307d9b8ed8cc3c8d4819f605e4f6 -Author: Scott Lamb -Date: Wed Nov 7 06:45:28 2007 +0000 - - Coding style corrections - -commit d82fcc88f355e3c8144478a860dfae0b299004a9 -Author: Scott Lamb -Date: Wed Nov 7 02:51:24 2007 +0000 - - Reload configuration through control socket - - I also kept the SIGHUP handler, which many people will expect to see. - The control socket is better, though - it will tell you if there is a - problem. - -commit f0a57eab4cfd64d4f8261b1885a2072177f9e76b -Author: Scott Lamb -Date: Wed Nov 7 02:50:58 2007 +0000 - - Retry connections through control socket - -commit a62a6825a8a69e279ee0688a4cd9e51fbc52054b -Author: Scott Lamb -Date: Wed Nov 7 02:50:27 2007 +0000 - - Alter debugging levels through control socket - -commit 1065879c8c6e8cdf8d3755024241f31eaabd4138 -Author: Scott Lamb -Date: Wed Nov 7 02:49:57 2007 +0000 - - Purge through the control socket - -commit 6eaefb4dbce240334e35f67d9f3db5d4f44e49c9 -Author: Scott Lamb -Date: Wed Nov 7 02:49:25 2007 +0000 - - Dump through control socket - - Note this removes SIGUSR1, SIGUSR2, and the graph dumping config option. - It seems cleaner to do everything through the control socket. - -commit 50ad3f2a895c38f8d546f87490ca96ab7d9e011e -Author: Scott Lamb -Date: Wed Nov 7 02:48:33 2007 +0000 - - Fancier protocol for control socket - - * pass error status back - * pass message boundaries - -commit b0b52991849073de059a188800d1b2f03663a188 -Author: Scott Lamb -Date: Wed Nov 7 02:48:15 2007 +0000 - - Fix reload crash - - sighup_handler was expecting the connection_tree to stay the same across - terminate_connection(), which hasn't been true since r1539. - -commit da81da064a093f94e460fc1c359b5cfab26d6b5b -Author: Scott Lamb -Date: Wed Nov 7 02:48:00 2007 +0000 - - Update documentation to match tincctl changes - - (Most of this was done in r1559, but it looks like tincctl.8.in got missed.) - -commit 40731d030fef793c6b6405efd9b3e64c26c00045 -Author: Scott Lamb -Date: Wed Nov 7 02:47:05 2007 +0000 - - Temporarily revert to old crypto code - - (The new code is still segfaulting for me, and I'd like to proceed with other - work.) - - This largely rolls back to the revision 1545 state of the existing code - (new crypto layer is still there with no callers), though I reintroduced - the segfault fix of revision 1562. - -commit 269892f70bf357de6ad66ca89daa34b225ee9e37 -Author: Guus Sliepen -Date: Sat Oct 20 11:21:44 2007 +0000 - - Prevent double free() of a used challenge nonce. - -commit b0709d2649ebd7ad01d6e24851dcdfc2707d09c5 -Author: Guus Sliepen -Date: Fri Oct 19 19:07:30 2007 +0000 - - Fix meta data segfault when receiving a partial command. - -commit 67d9a72ea2f10f1a2d2eb7c04a41183359d5e1cc -Author: Guus Sliepen -Date: Fri Oct 19 18:54:43 2007 +0000 - - Use a dummy function as the read callback for connection bufferevents. Should not be triggered. - -commit 54892b2e3efcbbbd65b26a32f487829bbb8d787c -Author: Guus Sliepen -Date: Fri Oct 19 18:53:48 2007 +0000 - - Fix connection weight estimation. - -commit 6c453769fd16125ec18e8e6d102a3eaa09d370c7 -Author: Guus Sliepen -Date: Tue Sep 4 15:06:35 2007 +0000 - - Apply patch from Scott Lamb: Update documentation to match tincctl changes - -commit 86358fabfedca395b60310799a648b4875596efb -Author: Guus Sliepen -Date: Tue Sep 4 14:58:52 2007 +0000 - - Small fixes to make gcrypt routines compile. - -commit f8733d1935ed83399c4851a31f4be710eb8c825f -Author: Guus Sliepen -Date: Tue Sep 4 14:58:11 2007 +0000 - - Fix formatting of --help output. - -commit 65375289dff849f00b3429dfe4be7e66efe48444 -Author: Guus Sliepen -Date: Tue Sep 4 14:57:37 2007 +0000 - - Only check for libgcrypt if --with-gcrypt is used. - -commit d7ca0300a3f004e9dc7d97ffb6fa6bdeda890fda -Author: Guus Sliepen -Date: Fri Aug 17 22:09:00 2007 +0000 - - Handle SERVICE_CONTROL_INTERROGATE requests. Thanks to Carsten Ralle for noticing this. - -commit 1fd1d5bd9330e02ab5dc32ad027f654ff2620099 -Author: Scott Lamb -Date: Fri Jul 20 20:10:46 2007 +0000 - - const correctness - - cipher_encrypt and cipher_decrypt should take "const void *" data - -commit 35d865a6348cd62d2992bb3d353e37471d902889 -Author: Scott Lamb -Date: Wed Jul 18 16:44:05 2007 +0000 - - Updated svn:ignores list for new symlinked sources and tincctl. - -commit dd299c06dccceeb9b4db09eee17268cf5631fa41 -Author: Scott Lamb -Date: Wed Jul 18 16:40:41 2007 +0000 - - Refresh po/POTFILES.in. - - In particular, remove lib/pidfile.c which was causing failures. Also sort - for diffability with "find . -type f -name '*.c' | cut -c3- | sort" output. - -commit 46018a1a16579ce00b02eb6a991a70615ab9bc3e -Author: Scott Lamb -Date: Wed Jul 18 16:40:29 2007 +0000 - - Revert to only requiring autoconf 2.59. - - The new autoconf macros introduced at the same time (AC_GNU_SOURCE, - AC_FUNC_MALLOC, AC_FUNC_REALLOC) exist in the autoconf 2.59 documentation, - and autoconf 2.59 appears to still work. This is more convenient, as RHEL 5 - ships with autoconf 2.59. - -commit 1b8f8918360b40a2749d40355266ed7dedbe41b5 -Author: Guus Sliepen -Date: Wed May 23 13:45:49 2007 +0000 - - Finish crypto wrapping. Also provide wrappers for OpenSSL. - Disable libgcrypt by default. Since it doesn't support the OFB cipher mode, - we can't use it in a backwards compatible way. - -commit f42e57f663a2663c830c4fb4c01927c2d3c89c09 -Author: Guus Sliepen -Date: Tue May 22 23:41:22 2007 +0000 - - Some more crypto wrapper functions are needed. - -commit 19413a8048fd851866c551ab8035f008f0c7e806 -Author: Guus Sliepen -Date: Tue May 22 21:44:17 2007 +0000 - - Make sure the crypto wrapper functions can actually be compiled. - -commit e8689a4753ca2b1665e131cc40217da6c033ebd3 -Author: Guus Sliepen -Date: Tue May 22 21:32:48 2007 +0000 - - Create wrappers for the cryptographic operations used in tinc. - Implement them using libgcrypt. - -commit 465837dd7f7b727d489b354e4b75489dd49fd6e3 -Author: Guus Sliepen -Date: Sun May 20 22:28:49 2007 +0000 - - Parse PEM RSA keys ourself, and use libgcrypt to do RSA encryption and decryption. - -commit fbf305c09d91bf34b1504b58d50392df2e6bcfba -Author: Guus Sliepen -Date: Sat May 19 22:23:02 2007 +0000 - - Use libevent for meta socket input/output buffering. - -commit 59108e4e4f7aa4632c510d16961edd8c551a6542 -Author: Guus Sliepen -Date: Sat May 19 16:21:52 2007 +0000 - - Use bufferevents to handle control socket buffering. - -commit 8c6131deda546452386f3703af968ee664cadfbd -Author: Guus Sliepen -Date: Sat May 19 15:21:26 2007 +0000 - - Implement "stop" command, and allow tincctl to retrieve a running tincd's PID. - -commit e9043e17c76f92b787c9ecdaf1a2ae7916f690a6 -Author: Guus Sliepen -Date: Sat May 19 14:55:35 2007 +0000 - - Move key generation to tincctl. - -commit bf8e3ce13dba6109757c14dc0013a315a75d2ba3 -Author: Guus Sliepen -Date: Sat May 19 14:13:21 2007 +0000 - - Remove pidfile in favour of control socket. - -commit bc0a24ec810cb911610ae7aafa245e47d1268cd2 -Author: Guus Sliepen -Date: Sat May 19 13:34:32 2007 +0000 - - Fix retrying outgoing connections. - -commit ce976717ea9756aa985699547fdbf132b694748d -Author: Guus Sliepen -Date: Sat May 19 12:07:30 2007 +0000 - - We can safely delete a connection_t in terminate_connection() now. - -commit 01f47c46af514a9d7f39c143e4558a8426a0d3eb -Author: Guus Sliepen -Date: Fri May 18 16:52:34 2007 +0000 - - Start of control socket implementation. - -commit 6ded8a3f089a22c98d2a06b960d65b44e60188d6 -Author: Guus Sliepen -Date: Fri May 18 11:54:16 2007 +0000 - - Update documentation. - -commit 86586594334e951a99845d92baed1966e394aafa -Author: Guus Sliepen -Date: Fri May 18 11:35:21 2007 +0000 - - Show branch version number. - -commit e37ef57a956507cc29e80930201731562b4266e5 -Author: Guus Sliepen -Date: Fri May 18 11:19:31 2007 +0000 - - More consistent variable naming. - -commit 29fbce4497357580fc0aa00f087e8f1a538a2a50 -Author: Guus Sliepen -Date: Fri May 18 10:29:10 2007 +0000 - - Detect duplicate outgoing connections. - -commit fb0cfccf7dc2240b576011edcf74fd5b058916cb -Author: Guus Sliepen -Date: Fri May 18 10:05:26 2007 +0000 - - Use splay trees instead of AVL trees. - -commit f02d3ed3e135b5326003e7f69f8331ff6a3cc219 -Author: Guus Sliepen -Date: Fri May 18 10:00:00 2007 +0000 - - K&R style braces - -commit 760dd966efe7dbff316a8c638e40dee162848256 -Author: Guus Sliepen -Date: Fri May 18 09:51:54 2007 +0000 - - Remove last references to the global variable "running". - -commit 3909b8e51b27b11c6d54541220cb7767bf25569c -Author: Guus Sliepen -Date: Fri May 18 09:43:52 2007 +0000 - - Remove the last bits of the legacy main_loop(). - -commit ddc6a81a854023e38b563f213aa9a449ee91add8 -Author: Guus Sliepen -Date: Fri May 18 09:34:06 2007 +0000 - - Remove global variable "now". - -commit 7e1117197ca4fc62af93fda50e28e0ff06cb736c -Author: Guus Sliepen -Date: Thu May 17 23:57:48 2007 +0000 - - Move key regeneration handling to net_setup.c. - -commit 563577a1479549fa0c20dcda45831a0fff8c7513 -Author: Guus Sliepen -Date: Thu May 17 23:33:07 2007 +0000 - - Use libevent to handle key expiration. - -commit 8852d4407d87cf5dcf2c212d352279015aa050c0 -Author: Guus Sliepen -Date: Thu May 17 23:24:40 2007 +0000 - - Use libevent to age learned MAC addresses. - -commit a530f94e7c4acd94d1cd568b384931eec6f60563 -Author: Guus Sliepen -Date: Thu May 17 23:14:42 2007 +0000 - - Use libevent to age past requests. - -commit aaf1851315023c2f960c58a0d977085a485298e7 -Author: Guus Sliepen -Date: Thu May 17 23:04:02 2007 +0000 - - Redo SIGALRM handling. - -commit 6d19ebd612e6387ba34419cce5cd4d5d861b9a9e -Author: Guus Sliepen -Date: Thu May 17 22:41:34 2007 +0000 - - Use libevent to handle all non-fatal signals. - -commit 531d5a904a3a91bca8b7d373fb6ab2869b31e7fa -Author: Guus Sliepen -Date: Thu May 17 22:17:24 2007 +0000 - - Properly use the timeout_initialized() macro. - -commit bf6490825eabdf4eda6e64f2e5fcd690db7b72ce -Author: Guus Sliepen -Date: Thu May 17 22:13:12 2007 +0000 - - Remove legacy event system. - -commit a67ab277c9fdbcfc8c0550e9046df2a00b5fed81 -Author: Guus Sliepen -Date: Thu May 17 22:09:55 2007 +0000 - - Use libevent for retrying outgoing connections. - -commit 3321591d93d00326eee01fa7c78fb0d56b3d0fba -Author: Guus Sliepen -Date: Thu May 17 22:01:07 2007 +0000 - - Use libevent to send MTU probes. - -commit ee7844905f63872e12cd12f5a3d1a62220594831 -Author: Guus Sliepen -Date: Thu May 17 21:47:27 2007 +0000 - - Configure events after obtaining a socket. - -commit 294ce72441e44c0561556c2984f0e26a74230347 -Author: Guus Sliepen -Date: Thu May 17 21:34:58 2007 +0000 - - Use libevent to handle HUP signal. - -commit 4d0621b1f39537699b0ec4655b0c6e6b84581c9a -Author: Guus Sliepen -Date: Thu May 17 21:14:30 2007 +0000 - - Use libevent to dump graphs when necessary. - event_add() can be called repeatedly, the second and later calls are ignored if - the event hasn't been removed yet. - -commit 0f6f54ff8aa96d981f68b5b71c7126b8fdbead6c -Author: Guus Sliepen -Date: Thu May 17 20:20:10 2007 +0000 - - Use a separate event structure to handle meta data writes. - Make meta socket events persistent. - -commit 17c8033029d50ce4a30b6e3585c0ee28ef45bc97 -Author: Guus Sliepen -Date: Thu May 17 19:52:12 2007 +0000 - - 128 listener sockets is way too much. - -commit d8dea8091fa2260071f775db58ba277d4ce44ea7 -Author: Guus Sliepen -Date: Thu May 17 19:51:26 2007 +0000 - - Properly delete listener socket events on shutdown. - -commit 6ea1dfc995f386b3a9406c7935642524dc755c51 -Author: Guus Sliepen -Date: Thu May 17 19:15:48 2007 +0000 - - Port fixes from release 1.0.8. - -commit cf2be574948fdd02db0503d9639d3b6e268dd4ff -Author: Guus Sliepen -Date: Wed May 16 17:16:09 2007 +0000 - - Releasing 1.0.8. - -commit 6af8900f8e1c7f2fe6a50a991ae6cbd0fd7edd43 -Author: Guus Sliepen -Date: Wed May 16 14:46:25 2007 +0000 - - Don't free struct addrinfo too early. Spotted by Christian Cier-Zniewski. - -commit 31a190dc7db21aa9bb97792563dd83e7c41b831c -Author: Guus Sliepen -Date: Wed May 16 14:42:41 2007 +0000 - - Update dutch translation. - -commit 480dd127c8a539036ff82a3810a0ad83136944f8 -Author: Guus Sliepen -Date: Wed May 16 14:42:08 2007 +0000 - - Make sure connection->name is never NULL. - -commit f0cf4991e2bd0e618c7020511fb12cb0b5c59a40 -Author: Guus Sliepen -Date: Mon May 14 09:21:09 2007 +0000 - - Apply patch from "dnk" making sockets non-blocking under Windows. - -commit 3730156165fd1aa7c8810cd8e390aba6a8badcfa -Author: Guus Sliepen -Date: Mon Mar 12 17:55:43 2007 +0000 - - Only free members of connection_t that have been allocated. - -commit 39f6d59b4b81dc2d754329e6c9f885e8211c5e70 -Author: Scott Lamb -Date: Tue Feb 27 08:13:41 2007 +0000 - - Lots of svn:ignore entries - -commit 38c25d62c2bc76908bd95fb21c8f5e39ad269884 -Author: Scott Lamb -Date: Tue Feb 27 01:57:01 2007 +0000 - - Convert to libevent. - - This is a quick initial conversion that doesn't yet show much advantage: - - We roll our own timeouts. - - We roll our own signal handling. - - We build up the meta connection fd events on each loop rather than - on state changes. - -commit 834290b00f859412ee48bef454a07083cb727130 -Author: Scott Lamb -Date: Tue Feb 27 01:30:57 2007 +0000 - - A couple missed tevent things. - (Sorry; had a couple changes queued.) - -commit 6362b12df725044f3404faceff113e469d8ac860 -Author: Scott Lamb -Date: Tue Feb 27 01:26:11 2007 +0000 - - Rename "event_t" to "tevent_t", along with associated functions. - This relieves some confusion and problems during the libevent transition. - In particular, "event_add" was defined by both. - (The 't' stands for 'timeout', 'tinc', 'temporary', or some such.) - -commit 54431094d95f3989084755fdb91883b24cf5a9f4 -Author: Guus Sliepen -Date: Sat Feb 24 22:50:42 2007 +0000 - - Created the 1.1 branch where large code changes can take place, - at the same time keeping compatibility with 1.0. - -commit ab6f76f6a9fc8028fff96322a52b770710ffa1a9 -Author: Guus Sliepen -Date: Wed Feb 14 09:32:16 2007 +0000 - - Close the proper filedescriptor (if it exists). - -commit 45fca3c723302868de3225e7509d2292008948f7 -Author: Guus Sliepen -Date: Wed Feb 14 09:21:34 2007 +0000 - - Apply patch from Scott Lamb fixing some memory and resource leaks. - -commit 6c6535a4161d04accb3a22c51477e9f92ae34086 -Author: Guus Sliepen -Date: Wed Feb 14 09:20:20 2007 +0000 - - Apply patch from Scott Lamb preventing an infinite loop when sending SIGALRM. - -commit 16c8b0e5bb7c05a0559b2d799a32204bfa0a0e3f -Author: Guus Sliepen -Date: Fri Jan 5 15:03:07 2007 +0000 - - Releasing 1.0.7. - -commit a1e72f84d08b76784c11ff723666ceeaef2756eb -Author: Guus Sliepen -Date: Fri Jan 5 13:18:36 2007 +0000 - - Update copyright notices. - -commit a22ef25f9b81993226a74b193377c7d6baf910ca -Author: Guus Sliepen -Date: Fri Jan 5 13:17:33 2007 +0000 - - No things to do for the 1.0 branch except bugfixing. - -commit d80cc7a5cc918a1dbf8dd789d2125f55c4949d27 -Author: Guus Sliepen -Date: Fri Jan 5 05:44:01 2007 +0000 - - rename() cannot replace existing files on Windows. - -commit 5214ece03009a916159c710cf436af1e92909f41 -Author: Guus Sliepen -Date: Fri Jan 5 04:49:02 2007 +0000 - - Fix generic BSD tun device to write only the actual packet length. - Due to a copy&paste bug, it tried to write a packet with the maximum size. - This was not a problem until the maximum size was increased to support VLANs. - -commit 40f02ff8eee359dc0ccc898f8da319f56af161ad -Author: Guus Sliepen -Date: Thu Jan 4 15:28:36 2007 +0000 - - Tapreader socket should be bound to localhost only. - -commit 03f3fc01e8d9402c4a14904fded883ff8cc574f6 -Author: Guus Sliepen -Date: Wed Jan 3 18:18:54 2007 +0000 - - Use a ringbuffer in shared memory to transfer packets from the tapreader thread to the main thread. - It's a wonder it ever worked before. The socket that is created is not of a - datagram type, therefore packet boundaries were not preserved, which becomes - a problem as soon as the TAP-Win32 device receives packets in fast succession. - -commit 52787a73b0211bcb4cb3cdd308b1a4c53a60f8ce -Author: Guus Sliepen -Date: Mon Dec 18 17:38:05 2006 +0000 - - Releasing 1.0.6. - -commit b32c22cf54e47677726d15a5fca7eecc2fa42754 -Author: Guus Sliepen -Date: Mon Dec 18 11:41:53 2006 +0000 - - Prevent compiler warnings about redefinition of EAI_FAMILY on FreeBSD 6.1. - -commit 855806b2f75fc1c566cfaac01c788cdc625b4687 -Author: Guus Sliepen -Date: Sat Dec 16 16:53:58 2006 +0000 - - Do a simple test for linux/if_tun.h instead of no test at all. - -commit 0322c0883b76257c0893aa75a510e264056ac15b -Author: Guus Sliepen -Date: Sat Dec 16 16:40:09 2006 +0000 - - Remove the test for linux/if_tun.h. - It has been available for years on any decent Linux distribution. - Although linux/if_tun.h is now required to compile tinc, - you can still run it on systems which only support Ethertap. - -commit b55813dc0b4a6a1f70c0f8d5f0512c8cebb4a5ba -Author: Guus Sliepen -Date: Sat Dec 16 16:34:04 2006 +0000 - - We do properly check for malloc and realloc. - -commit 5219ee25a248fe26055e54215c5027cbf8483439 -Author: Guus Sliepen -Date: Sat Dec 16 16:26:57 2006 +0000 - - Use standard autoconf macros instead of our own. - -commit 9d469a19691f9749b5d729a1ae903d7aa224a6e8 -Author: Guus Sliepen -Date: Sat Dec 16 16:26:08 2006 +0000 - - Fix rule that creates html version of manpages. - -commit dd03a003962788eb21910c3faabbda0e84eff5eb -Author: Guus Sliepen -Date: Fri Dec 15 20:44:33 2006 +0000 - - Remove old Spanish translation. - -commit 031e09f865e2c634f30fb0ed4e0b6a1f6df57588 -Author: Guus Sliepen -Date: Fri Dec 15 20:43:39 2006 +0000 - - Remove unnecessary stuff from configure.in. - -commit b834d67d7cc7d7f5d8b729b340ec0c809c7d54b6 -Author: Guus Sliepen -Date: Tue Dec 12 14:54:39 2006 +0000 - - Use the correct next pointer. - -commit 8b55dfacb199d152391aa5f7adbbbe35bceea7d7 -Author: Guus Sliepen -Date: Tue Dec 12 14:49:09 2006 +0000 - - When building the minimum spanning tree, make sure we start from a reachable node. - -commit 47d916ec5eb61fa396c0ec6962afed7885141478 -Author: Guus Sliepen -Date: Wed Nov 29 17:18:39 2006 +0000 - - Search for lzo/lzo1x.h, lzo2/lzo1x.h and lzo1x.h. - -commit 1bb5a284fec8c538f8ba243d4f9b2e46f68cd7e8 -Author: Guus Sliepen -Date: Wed Nov 29 16:57:46 2006 +0000 - - Make sure resolved addressed for outgoing connections are freed, if there are any. - -commit 5c69c390a17fc2b37218881e7285b639b79cfc5a -Author: Guus Sliepen -Date: Tue Nov 14 15:43:28 2006 +0000 - - Releasing 1.0.5. - -commit e5b1b5cefb82531e8a700c2ee251da1bb0a06fbf -Author: Guus Sliepen -Date: Tue Nov 14 12:28:04 2006 +0000 - - EWOULDBLOCK does not exist on platforms without O_NONBLOCK - -commit 3353ab37c2d6fb3652fbf7a85d85997be1c0c1b5 -Author: Guus Sliepen -Date: Sat Nov 11 22:45:45 2006 +0000 - - When deleting an entire tree, start at head, not at root. - -commit 0714ac6c59099a398e67770ad9c72fcec615812b -Author: Guus Sliepen -Date: Sat Nov 11 22:44:15 2006 +0000 - - Nodes use events, so event system should be initialised first and destroyed last. - -commit 35e4096120236db8d64a767f1ccdd6bf03a091fc -Author: Guus Sliepen -Date: Sat Nov 11 21:37:22 2006 +0000 - - Update Dutch translation. - -commit 315ef3e42bf16e03cfbea763442a52389a16b832 -Author: Guus Sliepen -Date: Sat Nov 11 20:37:58 2006 +0000 - - Document GraphDumpFile option. - -commit 8d393b30a922110ec77d5b243347416b50cd2160 -Author: Guus Sliepen -Date: Sat Nov 11 20:10:46 2006 +0000 - - Support and autodetect LZO version 2.0 and later. - -commit bdb3c24cea06e9557738b42e3c37cd036613b58d -Author: Guus Sliepen -Date: Sat Nov 11 20:06:14 2006 +0000 - - Support and autodetect LZO version 2.0 and later. - -commit 0d1ac68c59db87141616f69bcd3d79c705b1ecd0 -Author: Guus Sliepen -Date: Sat Nov 11 14:37:03 2006 +0000 - - popen() requires pclose(). - -commit 0200d3cd5d773d9b101c33264532d2a301c2af32 -Author: Guus Sliepen -Date: Sat Nov 11 14:11:16 2006 +0000 - - Added graph dumping ability based on Markus Goetz's patch. - -commit 1728d5b2c43b33700a9997f97fe8503ad1cf3585 -Author: Guus Sliepen -Date: Sat Nov 11 13:43:00 2006 +0000 - - The "active" bit in node.status is not used. - -commit 134dc8995b296b0bd8b346617c705204b0f3125c -Author: Guus Sliepen -Date: Wed Aug 9 22:31:10 2006 +0000 - - memcpy() addresses from packet headers before calling the lookup functions. - This probably fixes a problem on the ARM architecture that causes tinc to fail to lookup IPv4 addresses. - -commit 64e0519cb5042b251e7345f07429e8b82e2ac09b -Author: Guus Sliepen -Date: Tue Aug 8 13:50:58 2006 +0000 - - Remove unused variable. - -commit ddcf079cad3351f0823fc07af15787d02e5f1901 -Author: Guus Sliepen -Date: Tue Aug 8 13:44:37 2006 +0000 - - Remove unused parameter from maskcmp(). - -commit c620df3c1511643aa533ca31afc17db75b7255b8 -Author: Guus Sliepen -Date: Tue Aug 8 13:44:19 2006 +0000 - - Remove unused variables. - -commit 9fa27097dd82e20299f5277ecb4efffb4a99669c -Author: Guus Sliepen -Date: Tue Aug 8 13:29:17 2006 +0000 - - Fix format string warnings. - -commit eb391c52eed46f3f03b404553df417851fc0cb90 -Author: Guus Sliepen -Date: Tue Aug 8 13:21:08 2006 +0000 - - Do not break strict aliasing of status_t structs. - -commit 2077451e07f93edc520cf5bc31815624a2b03fdd -Author: Guus Sliepen -Date: Mon Jun 12 21:45:39 2006 +0000 - - Add generic host-up and host-down scripts. - Thanks to Menno Smits for a patch. - -commit f88c9942e1e3d4d463ec71ba5a60d045381bda8f -Author: Guus Sliepen -Date: Sun Jun 11 18:53:27 2006 +0000 - - Use memcpy() to copy sockaddrs returned by getaddrinfo(). - Thanks to Miles Nordin for spotting this. - -commit 412f3fb5101514d9a7d4d9e5729ee9c665a07cb6 -Author: Guus Sliepen -Date: Wed Apr 26 16:29:47 2006 +0000 - - Restore length of the original packet in send_udppacket(). - -commit de78d79db84c486afcc353884ec1770866beb653 -Author: Guus Sliepen -Date: Wed Apr 26 13:52:58 2006 +0000 - - Update copyright notices, remove Ivo's email address. - -commit 8ebb017a10cd85406ddf5ab60d8ef1f56df526ff -Author: Guus Sliepen -Date: Wed Apr 12 08:38:35 2006 +0000 - - Fix a bug in handling prefixlengths that are not a multiple of 4. - Thanks to Sven-Haegar Koch for spotting the bug and providing the fix. - -commit af95368c0f30955f0e13b587d5d6d4989fd5a83e -Author: Guus Sliepen -Date: Sun Mar 19 13:06:21 2006 +0000 - - Fix signedness compiler warnings. - -commit fb1cda2ca4ca74a85e88c39c11b97340e6495a08 -Author: Guus Sliepen -Date: Sun Mar 19 12:43:45 2006 +0000 - - Export flush_meta(). - -commit 098090468a9e1e8c5cdb0aeefa277329ff5f3406 -Author: Guus Sliepen -Date: Sun Mar 19 12:43:28 2006 +0000 - - Missing #include. - -commit a90f1b652c0fb52950f3b0783a7e2b7f2e0cf2db -Author: Guus Sliepen -Date: Mon Feb 6 12:30:51 2006 +0000 - - Make sure $NAME is set correctly when executing tinc-down script. - -commit 228e7a5c8f0e517dcede50f886965a44fca39853 -Author: Guus Sliepen -Date: Thu Jan 19 17:13:18 2006 +0000 - - Apply patch from Scott Lamb adding an output buffer for the TCP sockets. - This helps coalescing multiple send_meta() commands into one TCP packet. - Also limit the size of the output buffer before dropping PACKETs. - -commit a5a4d2b865879b8694760c0a5b5909c9a3675027 -Author: Guus Sliepen -Date: Fri Jan 13 11:21:59 2006 +0000 - - Apply patch from Scott Lamb unifying configuration of TCP socket options. - -commit e02f13cdb3133c33ac84d9582e2f47ca5ebd35bf -Author: Guus Sliepen -Date: Fri Jan 13 11:09:19 2006 +0000 - - EVP_Cleanup() when quitting. - -commit 0912260755021b9b836830dd99ae128c5fd912d9 -Author: Guus Sliepen -Date: Wed Nov 16 10:45:11 2005 +0000 - - Enable OpenSSL ENGINE, so crypto hardware gets used. Thanks to Andreas van Cranenburgh. - -commit 64e4c12778697f71ad3fcf33ee6cf1066322caa5 -Author: Guus Sliepen -Date: Fri Jun 3 10:56:02 2005 +0000 - - Add alloca.h to the list of necessary header files. - -commit e810545dc2ae158745624c1575b76c55f883c892 -Author: Guus Sliepen -Date: Fri Jun 3 10:16:03 2005 +0000 - - Prevent possible buffer overflows when using very large (>= 8192 bit) RSA keys. - Thanks to Tonnerre Lombard for noticing! - -commit 02746165a21a4a495d0069526c9a2355110a5784 -Author: Guus Sliepen -Date: Wed May 4 19:38:28 2005 +0000 - - Releasing 1.0.4. - -commit df3220a1549f992cbf4a9b6e67c1e67b69896c7d -Author: Guus Sliepen -Date: Wed May 4 18:09:30 2005 +0000 - - Update copyright notices. - -commit 54a30e30ad41d7c0e73fcc4e6ff23c3e85af75c4 -Author: Guus Sliepen -Date: Wed May 4 16:53:11 2005 +0000 - - Describe subnet-up/down scripts in documentation. - -commit bded1b74cc23c60e7319ed9e7465413b94a7914e -Author: Guus Sliepen -Date: Wed May 4 15:56:25 2005 +0000 - - Several splay tree fixes. - -commit faaaa1ef38dcdf19d5d5d73ab66806b15467c043 -Author: Guus Sliepen -Date: Wed May 4 15:52:55 2005 +0000 - - Searching through splay trees may change the tree variable. - -commit dc09f6fe896f5e35fffe8cc2004781b2e1b6fd5a -Author: Guus Sliepen -Date: Wed May 4 15:51:45 2005 +0000 - - Be on the safe side with initialisation of c->name. - -commit 92c4a28d7d43b68a324cf2eca741298ed6b692d6 -Author: Guus Sliepen -Date: Wed Apr 6 20:43:37 2005 +0000 - - Remove unused (and potentially segfaulting) net2str() call. - -commit 6363ed4d9c675b8b9301b694c4e4dd9c892e04e2 -Author: Guus Sliepen -Date: Thu Jan 20 15:14:25 2005 +0000 - - Don't try to add a non-existing node back to the node_udp_tree. - -commit 39fe3b445c2f20b325ee492dd1845877777b25c8 -Author: Guus Sliepen -Date: Tue Jan 4 22:19:56 2005 +0000 - - Nodes should only be in the node_udp_tree if they are reachable. - -commit fe0bfa3e65049d6e7cd46cf6caea7eb91b478008 -Author: Guus Sliepen -Date: Tue Jan 4 22:18:58 2005 +0000 - - Correct size argument for strncat(). - -commit 56c36a14d87b58c14dbc48df4d3d977207e2c06e -Author: Guus Sliepen -Date: Fri Dec 3 13:27:33 2004 +0000 - - Use the proper free function. - -commit 18c617ecf29b9dfb95227e764c76fff0f9d7af96 -Author: Guus Sliepen -Date: Fri Dec 3 13:22:18 2004 +0000 - - Free memory used by connection_t after it is deleted from the connection tree. - -commit 672ad5634cbedfbd6345e887935eed3e806f1e2d -Author: Guus Sliepen -Date: Wed Dec 1 21:26:51 2004 +0000 - - Small fix. - -commit 40b1692940a8d588c08fb6b8f24ded7c33b041b1 -Author: Guus Sliepen -Date: Wed Dec 1 20:06:39 2004 +0000 - - subnet-up/down hooks, use list_t for the todo list. - -commit c46f56a8b8bb865dd8951441b5acf4701b5b5b09 -Author: Guus Sliepen -Date: Wed Dec 1 20:06:05 2004 +0000 - - subnet-up/down hooks - -commit f08baa3072e7cd6cee7a2a7cde35b46c85363baf -Author: Guus Sliepen -Date: Thu Nov 18 20:34:48 2004 +0000 - - Fix splay tree code. - -commit 0077cfaae112b63d6af6aa1e5d079cebdde84b74 -Author: Guus Sliepen -Date: Tue Nov 16 19:02:54 2004 +0000 - - Make sure broadcast packet reach the local network interface. - -commit 79c48cfafd75dfc86a382f6454a9f009d3c099b6 -Author: Guus Sliepen -Date: Thu Nov 11 19:42:25 2004 +0000 - - Releasing 1.0.3. - -commit 2771691bfc85b2544b30ccaee8a709bd26c7e1ab -Author: Guus Sliepen -Date: Thu Nov 11 19:39:28 2004 +0000 - - Add more people who have contributed to tinc. - Remove details and sort on name; - the details were not always equally accurate and are hard to maintain. - -commit 4f3f6f07b234b4abd32bf3bae1be0551bc7dd9dc -Author: Guus Sliepen -Date: Thu Nov 11 11:17:04 2004 +0000 - - Short readme about how to compile tinc from a Subversion checkout. - -commit 704c3707c2c400b7e35ef4ac2c1d21e0f2de0187 -Author: Guus Sliepen -Date: Wed Nov 10 23:28:32 2004 +0000 - - Updated dutch translation. - -commit a20eb05714f828be7dc0f78c1a07f218a3482dff -Author: Guus Sliepen -Date: Wed Nov 10 23:21:41 2004 +0000 - - Remove duplication. - -commit d8fe2ecdd8dc5caf6f8d6acf2923a0baed64735f -Author: Guus Sliepen -Date: Wed Nov 10 23:20:59 2004 +0000 - - Set BSD tuns to broadcast mode. On OpenBSD, this enables IPv6 on the tun device! - -commit 2369b0ab09a008c519cd4307b634fd294c66014e -Author: Guus Sliepen -Date: Wed Nov 10 21:57:04 2004 +0000 - - Update documentation. - -commit 4fe7aff4d1b8605d4997b842481cc78bd062fe2a -Author: Guus Sliepen -Date: Wed Nov 10 21:56:31 2004 +0000 - - Add BlockingTCP option, useful when using TCPOnly on slow or congested links. - -commit 5bba3124c8c23568def7a4804651a53f3a6b4fd2 -Author: Guus Sliepen -Date: Wed Nov 10 21:14:08 2004 +0000 - - Support tunneling IPv6 on Solaris. - -commit d02d81ff9dbb12253957065752c56785aedccee3 -Author: Guus Sliepen -Date: Wed Nov 10 19:36:02 2004 +0000 - - Let compiler decide when to inline. - -commit db68db4b0e0f8b776f2d3dc938fb81dac975fdd8 -Author: Guus Sliepen -Date: Wed Nov 10 19:34:38 2004 +0000 - - Fix order of arguments for tar. - -commit 923abcfa35c7282251d507af83d6163df76c943b -Author: Guus Sliepen -Date: Wed Nov 10 18:11:44 2004 +0000 - - Use the generic BSD tun/tap code. - -commit e8b11b1cca11f7f50542a7b34f4251f43447db0d -Author: Guus Sliepen -Date: Wed Nov 10 18:10:59 2004 +0000 - - Missing check for NULL-pointer. - -commit ca7948fc06fd0495dc8104d7f55948f702ac09e2 -Author: Guus Sliepen -Date: Tue Nov 9 09:51:35 2004 +0000 - - Hopefully this really fixes late packet handling. - -commit f7b9761000000063bd00460af4b57117db7361e4 -Author: Guus Sliepen -Date: Mon Nov 8 22:30:13 2004 +0000 - - Fixed another bug in late packet handling. - -commit 14eab178295768311d4518289533005991add8ba -Author: Guus Sliepen -Date: Mon Nov 8 22:11:33 2004 +0000 - - Update to make it compile again. - -commit 804b2892a5e26a2dc46d19397cc8b321b43b8add -Author: Guus Sliepen -Date: Mon Nov 8 22:03:28 2004 +0000 - - Hoopjumping to get the default directories in the manuals properly. - -commit 719cb95ea4fa7a2e6f4291aed607323f290c7a91 -Author: Guus Sliepen -Date: Tue Nov 2 20:50:53 2004 +0000 - - Splay trees. - -commit 2af1538976c9c85c40becfdd8601b421ad2ab057 -Author: Guus Sliepen -Date: Mon Nov 1 17:05:09 2004 +0000 - - Don't include .svn directory in sample configuration. - -commit dced64c5c3625f6d2f0674e9fed14455aabc635e -Author: Guus Sliepen -Date: Mon Nov 1 17:04:28 2004 +0000 - - Check for sys/uio.h, net/if_tun.h and net/if_tap.h - -commit 1f00810da336f3b7132df17b7fe4625748ff4b63 -Author: Guus Sliepen -Date: Mon Nov 1 17:02:19 2004 +0000 - - static - -commit 82b29e9a3b1dc6b2104ab92ed78bf431a4e55649 -Author: Guus Sliepen -Date: Mon Nov 1 17:01:56 2004 +0000 - - Generic device driver for *BSD and MacOS/X - -commit 922e5b7beaad5bb3fcbfa6b8dd13c05bda29e5fa -Author: Guus Sliepen -Date: Mon Nov 1 15:18:53 2004 +0000 - - Support alternative tun/tap driver from http://www-user.rhrk.uni-kl.de/~nissler/tuntap/ - -commit faff6498821555e6afb3dc5e4e3b61d448a4fef1 -Author: Guus Sliepen -Date: Mon Nov 1 15:18:22 2004 +0000 - - Don't let tinc service depend on NDIS component. - -commit 396ac4be802f8b75c5a2ab5925925427c61c1da3 -Author: Guus Sliepen -Date: Mon Nov 1 15:16:12 2004 +0000 - - Correct return value. - -commit 58153cca98fd43c37ae52d3cf69474c3d736c431 -Author: Guus Sliepen -Date: Fri Oct 1 18:26:15 2004 +0000 - - Allow tinc to work with the latest TAP-Win32 driver. - -commit 6411e0d8bda8abc2cef87ca852255502f9bb03d0 -Author: Guus Sliepen -Date: Fri Oct 1 18:24:41 2004 +0000 - - strndupa() is too arcane for some environments. - -commit b0a80007e8945a11d7ce25aab096c5ee58ce0ad5 -Author: Guus Sliepen -Date: Fri Oct 1 18:23:08 2004 +0000 - - Fix several #includes. - -commit 2c40495747945bc497dac65b734a4995ab3400a3 -Author: Guus Sliepen -Date: Fri Oct 1 18:22:06 2004 +0000 - - Move all #ifdef HAVE_HEADER_H #include to have.h, - this allows for simplification of configure.in. - -commit 7717cb0c54cc1b736b9f210b180c3cb3f4663ded -Author: Guus Sliepen -Date: Mon Sep 20 20:56:14 2004 +0000 - - Remove duplicate #include "system.h" - -commit 5373129344d349ff6aeb2b3d21f947f5ecbbcfaf -Author: Guus Sliepen -Date: Mon Sep 20 20:55:49 2004 +0000 - - Marking potential late packets was in the wrong place. - -commit c44f69a30243a94ab93bd15915dbfa71db698bde -Author: Guus Sliepen -Date: Sat Jul 17 12:04:30 2004 +0000 - - Don't set $INTERFACE automatically, don't quit on EINTR/EAGAIN. - -commit dcec713675b604f5ef82e64d0671727e3f5ea518 -Author: Guus Sliepen -Date: Sat Jul 17 00:09:14 2004 +0000 - - Added UML network socket handling. - Now you can use tinc instead of uml_switch. - -commit fe84fafcb684391739a1b3366705c58683210392 -Author: Guus Sliepen -Date: Mon Jun 21 14:37:52 2004 +0000 - - Handle timeouts during connecting the same way as other errors. - -commit e5e0dd7534be5fb96032fb733ca36a09cb067f17 -Author: Guus Sliepen -Date: Mon Jun 14 14:32:10 2004 +0000 - - Clean up environment after executing scripts. - -commit 9e44f116bf0f72d1dd4f099440a351dbe0a74573 -Author: Guus Sliepen -Date: Thu Apr 15 14:09:56 2004 +0000 - - Increase MTU by 4 bytes to allow VLAN tagged Ethernet frames in hub and switch mode. - -commit 7926a156e5b118d06295228e57de0cc9de0433b4 -Author: Guus Sliepen -Date: Sun Mar 21 14:21:22 2004 +0000 - - Update copyrights, links, email addresses and let Subversion update $Id$ keywords. - -commit 42e01abd54bd36ee84a45a2b646cfa27034de8d1 -Merge: 5ca64f8 af86a32 -Author: Guus Sliepen -Date: Sun Mar 21 13:22:24 2004 +0000 - - Move CABAL branch to its rightful place: the trunk. - -commit af86a3226ea42375644b3f99c182c778d327de1e -Author: Guus Sliepen -Date: Sat Mar 20 22:23:42 2004 +0000 - - Revert Martin Kihlgren's patch, it doesn't work the way it should. - -commit 27c304940a5dbe83fb0f655c5c43150bafed3b63 -Author: Guus Sliepen -Date: Sat Mar 20 15:40:26 2004 +0000 - - Use Subversion to create ChangeLog, better svn-clean rule. - -commit 8df22248293a8cd5e6056415b6e08740e40aa2bc -Author: Guus Sliepen -Date: Sat Mar 20 15:33:07 2004 +0000 - - Fix declaration of update_node_address(). - -commit 56aad1bb486675ff9aba31418708cc179eea0381 -Author: Guus Sliepen -Date: Sat Mar 20 15:28:55 2004 +0000 - - Applied Martin Kihlgren's IdentityGenerosity patch, - simplified and renamed to StrictSource. - -commit 8c189c2a9b77fb326ab5f27a05bf2601e16af017 -Author: Guus Sliepen -Date: Mon Mar 15 19:09:52 2004 +0000 - - Even better svn-clean command. - -commit b05df3fcbfb8dbef4c87691d118c5b68aeb79e4a -Author: Guus Sliepen -Date: Mon Mar 15 18:36:14 2004 +0000 - - Updating dutch translation. - -commit a92c471a2bc0773a7473ef0361d1a51fafee50d4 -Author: Guus Sliepen -Date: Mon Mar 15 18:15:02 2004 +0000 - - Only read our public key if it wasn't already in the private key file. - -commit a67a21ef3c17d32af95373e921138429a7fc507e -Author: Guus Sliepen -Date: Mon Mar 15 18:05:41 2004 +0000 - - Eat trailing whitespace in config files. - -commit 4350704d6578656af98195b26006c6b6d6a798e3 -Author: Guus Sliepen -Date: Mon Mar 15 17:54:19 2004 +0000 - - Remove CVS related cruft. - -commit 538595f7350ba6c7d11aba7d9f481ea1641e1857 -Author: Guus Sliepen -Date: Mon Mar 15 17:53:17 2004 +0000 - - Replace cvs-clean with a much better svn-clean. - -commit 5ca64f89be71131e77a29661827dc8866a5f278c -Author: cvs2svn -Date: Sat Jan 10 23:21:36 2004 +0000 - - This commit was generated by cvs2svn to compensate for changes in r1352, - which included commits to RCS files with non-trunk default branches. - -commit fcd836c609568fab323f4af6dd525de957a6f4cc -Author: Guus Sliepen -Date: Sat Jan 10 23:21:36 2004 +0000 - - Remove autogen.sh, the autoreconf program does exactly that. - Update everything for the latest autoconf and automake versions. - -commit f2aa7466e6db9777090583ef26d923fc0a4fcea8 -Author: Guus Sliepen -Date: Sat Jan 10 23:19:20 2004 +0000 - - Small updates. - -commit 519d63bedbdcc533dd7839aae02b4d7bc2debfb0 -Author: Guus Sliepen -Date: Sat Dec 27 16:32:52 2003 +0000 - - Don't forget to update destination MAC address. - -commit aebc97a77f37ec63fbd36721f9b284c975e54270 -Author: Guus Sliepen -Date: Wed Dec 24 10:48:15 2003 +0000 - - Small fixes for PMTU discovery. - -commit 2c7ce7de12d16cb407fd40224b6cb802528ee942 -Author: Guus Sliepen -Date: Mon Dec 22 11:05:23 2003 +0000 - - Missing definitions. - -commit 35399784b695c9ac692beba7be7930ee9f24412f -Author: Guus Sliepen -Date: Mon Dec 22 11:04:17 2003 +0000 - - Improvements for PMTU discovery and IPv4 packet fragmentation. - -commit 6d41b429a26dd1acaa7c56b2124f2daf55b5b97c -Author: Guus Sliepen -Date: Sat Dec 20 21:25:17 2003 +0000 - - Better name, show probed MTU in dump. - -commit af490a745d4ddc8994ceca546b5f9139f6a6ebe2 -Author: Guus Sliepen -Date: Sat Dec 20 21:20:10 2003 +0000 - - Describe the TunnelServer and PMTUDiscovery options. - -commit 9bab08e972ae0ca4b904a659d9aed46aaa9b5dd5 -Author: Guus Sliepen -Date: Sat Dec 20 21:09:33 2003 +0000 - - More sensible name, and try to set PMTU discovery on IPv6 sockets as well. - -commit 6b12bea62fe2e4bd8b5b6bd0e5ca7f53318705db -Author: Guus Sliepen -Date: Sat Dec 20 19:47:53 2003 +0000 - - Let tinc figure out the exact MTU of the link. - -commit e8fbef5de653e4df35eee49aae6e1ac92d6466e6 -Author: Guus Sliepen -Date: Sat Dec 13 21:50:26 2003 +0000 - - Forget multicast. Always inline some function. - -commit 5a1406adefd8b51981af0da5ac0ebec830eb43b4 -Author: Guus Sliepen -Date: Fri Dec 12 19:52:25 2003 +0000 - - Code beautification, start of multicast support. - -commit 354b7ab20e04736b368985a9e9dfd54ff5b7584e -Author: Guus Sliepen -Date: Mon Dec 8 12:00:40 2003 +0000 - - Fix proxy-neighborsolicitation. - -commit 331cef948db4b3cca245ab62cb0fafb5b1e5ebb3 -Author: Guus Sliepen -Date: Sun Dec 7 14:31:09 2003 +0000 - - Don't retry if configuration is wrong from the beginning. - -commit a3cd273751fdcef90a43108a5d2e669877b0bccb -Author: Guus Sliepen -Date: Sun Dec 7 14:29:02 2003 +0000 - - Missing space between words. - -commit 25447b384173cc3c99660c784fd784c787917e80 -Author: Guus Sliepen -Date: Sun Dec 7 14:28:39 2003 +0000 - - Read MaxTimeout from tinc.conf like the manpage says. - -commit 0b5e6cf04ec0c7e3c54c74a54a32b30e6e3c1f83 -Author: Guus Sliepen -Date: Thu Nov 27 23:24:59 2003 +0000 - - Complain if pid file cannot be created. - -commit e3220cacb5bc79fc56167e61b7a342f88a33a479 -Author: Guus Sliepen -Date: Mon Nov 17 15:30:18 2003 +0000 - - Replace Opaque and Strict options with a TunnelServer option. - -commit 0e59fb022c6c015a5be7ed70e0378cb011be98b5 -Author: Guus Sliepen -Date: Mon Nov 10 22:31:53 2003 +0000 - - Add Opaque option which prevent information from being forwarded to certain nodes. - -commit a8f415e67fd316d929f9b9e6661e0d3d66fc197b -Author: Guus Sliepen -Date: Sat Nov 8 15:29:40 2003 +0000 - - Release notes for 1.0.2 - -commit 507a83c74635955f803bb26c450f3e83dd4809f9 -Author: Guus Sliepen -Date: Sat Nov 8 15:09:03 2003 +0000 - - Add missing definitions. - -commit 0271de0e80459bdebcac50d38c053d4aaf657e9a -Author: Guus Sliepen -Date: Sat Nov 8 12:56:24 2003 +0000 - - Update dutch translation. - -commit d35a510fff65a7a3318036f27c11b956526b26f6 -Author: Guus Sliepen -Date: Sun Oct 12 11:40:00 2003 +0000 - - Fix another bug in meta.c. - -commit e88ea7277a97d46fa2c3ba1896cf0d0c62bdf128 -Author: Guus Sliepen -Date: Sat Oct 11 14:42:30 2003 +0000 - - Small fixes in documentation. - -commit ffb7327c20952cefcb5578e40f9802295172c5c2 -Author: Guus Sliepen -Date: Sat Oct 11 14:18:52 2003 +0000 - - Fix bug that could lead to an assertion failure in libcrypto when multiple - requests arrive and TCP packets are heavily fragmented. - -commit 258b7ce220607bb3f2a24bb7cab5fcd19e82314a -Author: Guus Sliepen -Date: Sat Oct 11 12:28:48 2003 +0000 - - Parentheses in the wrong spots. - -commit a1ab57e2755df6c1a8fab95a0886fea368200b96 -Author: Guus Sliepen -Date: Sat Oct 11 12:16:13 2003 +0000 - - Check all EVP_ function calls. - -commit b0dd705a264f0f72a7afba6de85200598cbe083b -Author: Guus Sliepen -Date: Fri Oct 10 16:24:24 2003 +0000 - - Check return value of EVP_* functions, and check if length before en/decryption - matches that after in meta.c. - -commit 9d2bf718f233672c11a9740ed2a1539eaab1509b -Author: Guus Sliepen -Date: Fri Oct 10 16:23:30 2003 +0000 - - Fix ASCII art. - -commit e33307fc9f5354933554d26de618db1b08fc04c0 -Author: Guus Sliepen -Date: Thu Oct 9 21:33:15 2003 +0000 - - Update documentation. - -commit 98edfb14fcc7167d24d440ed2772d0755daac3b7 -Author: Guus Sliepen -Date: Wed Oct 8 12:09:37 2003 +0000 - - Some platforms don't know sa_family_t or define it other than uint16_t. - -commit f2ebdf75806d8c04138db0eb30727f846541ed75 -Author: Guus Sliepen -Date: Wed Oct 8 11:37:53 2003 +0000 - - Set media status for newer TAP-Win32 driver. - -commit acf5f9c968d17ad3e31129d2184309de06d72eed -Author: Guus Sliepen -Date: Wed Oct 8 11:37:20 2003 +0000 - - Missing declaration. - -commit 1d7706a8506d8073def0965da809960c6ad8bf9a -Author: Guus Sliepen -Date: Wed Oct 8 11:34:55 2003 +0000 - - Update missing definitions, structs describing headers get __packed__ attribute. - -commit 5b556c0971e847580b85268e57f0b29dbde5499c -Author: Guus Sliepen -Date: Wed Oct 8 11:33:54 2003 +0000 - - Forgot to #include "xalloc.h" - -commit ad39db95fecf760297b4e320ef2f6d6d9fdad605 -Author: Guus Sliepen -Date: Mon Oct 6 16:49:42 2003 +0000 - - Make sure type of AF_UNKNOWN is sa_family_t. - -commit 5900c07fab39d2833ea66429ad652ca49a91a508 -Author: Guus Sliepen -Date: Mon Oct 6 16:13:08 2003 +0000 - - PIDs are of type pid_t, and use %ld when reading/writing them to the pidfile. - -commit e898b930dcd0694a49dc8cdcf373e0fc125c9fde -Author: Guus Sliepen -Date: Mon Oct 6 16:05:30 2003 +0000 - - Use CPPFLAGS, LDFLAGS and LIBS as appropiate. - -commit 6350334aa44f85e737c1eb0b55e0392766aa1e84 -Author: Guus Sliepen -Date: Mon Oct 6 14:41:45 2003 +0000 - - Don't confuse users with "Address family not supported" warnings. - -commit 0842998c0bd46855d198923acc2c13cff7430ffe -Author: Guus Sliepen -Date: Mon Oct 6 14:33:04 2003 +0000 - - Unused variable in struct. - -commit 77cb10dac0abbfa4389a7588f51797152d91ac22 -Author: Guus Sliepen -Date: Mon Oct 6 14:16:51 2003 +0000 - - Ethernet protocol types. - -commit c97b8827ed34284535706e8017c962ff8f3a4383 -Author: Guus Sliepen -Date: Mon Oct 6 13:57:12 2003 +0000 - - const - -commit 60943122f7b3a5896ce64c9000e119931484c12c -Author: Guus Sliepen -Date: Mon Oct 6 13:49:57 2003 +0000 - - Copy structs from packets to the stack before using them, to prevent - alignment issues. - -commit 5713fb07b3e831b78d8841d56a53c2a2698fe738 -Author: Guus Sliepen -Date: Wed Oct 1 09:43:01 2003 +0000 - - Add description of new authentication scheme. - -commit acbb9d6692614539260749c7b763eca5a6f81f07 -Author: Guus Sliepen -Date: Wed Oct 1 09:14:01 2003 +0000 - - Better length checks. - -commit eeb97e3ef4eb9089851f7b71d5393df24313c993 -Author: Guus Sliepen -Date: Thu Sep 25 10:34:16 2003 +0000 - - Generate keys with 0x10001 as public exponent, which has less prime factors - than 0xFFFF. - -commit 288d956728ab4d4aabe9bc59b87991420dbda151 -Author: Guus Sliepen -Date: Tue Sep 23 20:59:01 2003 +0000 - - Check for short packets from the tun/tap device and from other tinc daemons. - -commit 4e80612ac0f38daa0f2280c293427c7f25dac278 -Author: Guus Sliepen -Date: Tue Sep 9 15:47:59 2003 +0000 - - Update translations. - -commit cbf5a741aa2af937b3db606f0894990703f77bcb -Author: Guus Sliepen -Date: Mon Sep 8 21:52:47 2003 +0000 - - Remove pidfile when exitting. - -commit 0dba26267c76982a422984b61a3196ed2cd2b04a -Author: Guus Sliepen -Date: Wed Sep 3 16:20:33 2003 +0000 - - Prevent multiple inclusions. - -commit 6c5f3d8b74ffea1522a727ef189a5ba65a939e07 -Author: Guus Sliepen -Date: Thu Aug 28 21:05:11 2003 +0000 - - We don't have to tell GCC how to cast. - -commit 762cc2d2797d62ab593ea64d8ceeb4fe96be2a0d -Author: Guus Sliepen -Date: Thu Aug 28 15:27:12 2003 +0000 - - Remove old edges from unreachable nodes to us. This prevents the hosts/NAME-up - script from being called twice in some situations. - -commit a6dc69e7f30522bf885714f6b663960b6fbfff6a -Author: Guus Sliepen -Date: Wed Aug 27 13:58:29 2003 +0000 - - Forgot to synchronise po/ directory... - -commit 62349da6f2617c7250a77af6610344ec0dbfc4f2 -Author: Guus Sliepen -Date: Wed Aug 27 13:57:04 2003 +0000 - - Makevars file was accidentily removed. - -commit dc3b7d47f3297e22161787a1d6e06205140cf0fb -Author: Guus Sliepen -Date: Wed Aug 27 13:47:52 2003 +0000 - - Some device.c files weren't synchronised. - -commit 9e81a6ab5f50df4f5ca36d5303b91a8d5a0e753e -Author: Guus Sliepen -Date: Sun Aug 24 20:50:30 2003 +0000 - - This will become 2.0. - -commit 013a2e159e42c46808ea8d0b6abd57525db30a50 -Author: Guus Sliepen -Date: Sun Aug 24 20:38:31 2003 +0000 - - Synchronise HEAD with CABAL branch. - -commit ffb55e6904426a31c03b56c3bd87bb60db0624c6 -Author: Guus Sliepen -Date: Fri Aug 22 21:32:45 2003 +0000 - - Add license exception from Markus Oberhumer. - -commit 3e0b28b0c4d874934dde7b487a56cfacc956e3b4 -Author: Guus Sliepen -Date: Fri Aug 22 15:07:57 2003 +0000 - - Remove debug message. - -commit 89c9f3ed8fddb316d0f9ef7de30bdc76fba39e41 -Author: Guus Sliepen -Date: Fri Aug 22 15:04:26 2003 +0000 - - When purging nodes, only delete them if nobody references them anymore. - -commit 22dd23b650eb9b760bc68ab3a9227caf3b449140 -Author: Guus Sliepen -Date: Fri Aug 22 15:03:59 2003 +0000 - - Add checkpoints. - -commit 570e7e9c615388cfba263c7a7c66cbc3d092d6e7 -Author: Guus Sliepen -Date: Fri Aug 22 15:05:01 2003 +0000 - - Don't overwrite the first " when installing a service. - -commit 72bdc05cb7e246e56ed21a25256d441c45fccca8 -Author: Guus Sliepen -Date: Fri Aug 22 11:18:42 2003 +0000 - - Allow tinc to handle unknown type addresses from other tinc daemons. - -commit 5ac4179df66747a7013a10d576c23531d2b4fc58 -Author: Guus Sliepen -Date: Sun Aug 17 12:05:08 2003 +0000 - - If we're not in main_loop() and the service is stopped, exit immediately. - -commit 46cfe6199449a86eb58abaeac45b4021ffa7e178 -Author: Guus Sliepen -Date: Sun Aug 17 12:04:35 2003 +0000 - - Do what the SDK documentation tells. - -commit 107448698fc078bbd4cdbacdfbf51298ddc9ea65 -Author: Guus Sliepen -Date: Sun Aug 17 12:03:40 2003 +0000 - - Compilation fix. - -commit 3112e6a863b4421eb1a0b32632b86c55e47f989e -Author: Guus Sliepen -Date: Sun Aug 17 09:04:00 2003 +0000 - - Use the event log under Windows. - -commit 5e7c52610f8c8b9c38e437ef166a08372d5b8a61 -Author: Guus Sliepen -Date: Sun Aug 17 09:03:30 2003 +0000 - - Fix --logfile under Windows. - -commit 2236e05e518c9e317d82c027596bea5228725214 -Author: Guus Sliepen -Date: Sun Aug 17 08:32:39 2003 +0000 - - Fix fake getnameinfo() and check more arguments. - -commit f4e80cc5e0d1689bcdd828ac7f158bd634b7dd20 -Author: Guus Sliepen -Date: Sat Aug 16 12:40:01 2003 +0000 - - Don't getsockopt() SO_ERROR. We get the error from send()/recv() anyway. - -commit fd40130eb6bbba34176d34936a01bb6a6f9121d4 -Author: Guus Sliepen -Date: Sat Aug 16 12:11:11 2003 +0000 - - stat() batch files under Windows. - -commit 03995ca52ee31ed505902a3c8c3d1119988c8497 -Author: Guus Sliepen -Date: Sat Aug 16 12:10:28 2003 +0000 - - Simplify fake getname/addrinfo() functions, possibly fixing freeing a NULL pointer. - -commit dbfd6f284e0ff0aa04e6d6e62b902966912da516 -Author: Guus Sliepen -Date: Thu Aug 14 14:32:34 2003 +0000 - - Update. - -commit 7ed25590257b6ed33dfa879d187a09b0d790794f -Author: Guus Sliepen -Date: Thu Aug 14 14:21:35 2003 +0000 - - Fix permissions check for rsa_key.priv. - -commit 1f2670aab295dfd09c8c655611d2a5b820cb00fc -Author: Guus Sliepen -Date: Tue Aug 12 14:48:13 2003 +0000 - - Small fixes. - -commit b038e8db376969e70f1315840428b8a14ec8420f -Author: Guus Sliepen -Date: Tue Aug 12 12:35:53 2003 +0000 - - Updated dutch translation. - -commit ae070b917066f612e9aba8611c7a5da88e19a51a -Author: Guus Sliepen -Date: Sun Aug 10 13:35:05 2003 +0000 - - Add a description for the Service control panel. - -commit 9b579eb9ffdc1fd4a3d0cacb0728ec0796526bc5 -Author: Guus Sliepen -Date: Sat Aug 9 00:53:22 2003 +0000 - - Update documentation. - -commit 7eed829d288d0fdec2f31709a18ec420e489c2e4 -Author: Guus Sliepen -Date: Fri Aug 8 22:45:46 2003 +0000 - - Only system() needs script name quoted. - -commit 91f65c277483b47343b1b64d0f4edd497a8045a3 -Author: Guus Sliepen -Date: Fri Aug 8 22:13:50 2003 +0000 - - Check for fchmod(). - -commit 9bde92ce97d5503ff2d31dcc6f0648902580ec14 -Author: Guus Sliepen -Date: Fri Aug 8 22:11:54 2003 +0000 - - Simpler checking of permissions on private RSA key and other fixes. - -commit 96f5d98fc299a53fcdad304a56eb3a77a2c229e7 -Author: Guus Sliepen -Date: Fri Aug 8 19:56:11 2003 +0000 - - Small things. - -commit ef65a64443f740e3b22d9e903f764d9a58ce0ff0 -Author: Guus Sliepen -Date: Fri Aug 8 19:49:47 2003 +0000 - - Better error checking and reporting. - -commit bb2f18a3fc8acb7802f30e06153def30eb97a994 -Author: Guus Sliepen -Date: Fri Aug 8 19:45:21 2003 +0000 - - Under Windows, the installation directory can be found in the registry. - -commit 7f05445047c6479b81b7d393543ff73a95ee0dc8 -Author: Guus Sliepen -Date: Fri Aug 8 19:43:47 2003 +0000 - - Quote when needed and don't try stuff that doesn't work under Windows. - -commit b4c913aaa926d80a72aeb97459f84f992b65d1ed -Author: Guus Sliepen -Date: Fri Aug 8 19:42:35 2003 +0000 - - Log error first, try to close later. - -commit b0825f36b7b5dade1693fdbddfec7eef3f5ed86f -Author: Guus Sliepen -Date: Fri Aug 8 19:39:41 2003 +0000 - - Better error messages under Windows. - -commit 6f3099595530280028f6ec3d0b310df523e75f98 -Author: Guus Sliepen -Date: Fri Aug 8 17:20:12 2003 +0000 - - Typo. - -commit 691907caaeb348dee3dbe8a85f3590241f2cc992 -Author: Guus Sliepen -Date: Fri Aug 8 17:17:13 2003 +0000 - - Readd quotes. - -commit f956a28147ec8596c9a51b0c1535bb4b8c87692c -Author: Guus Sliepen -Date: Fri Aug 8 16:49:29 2003 +0000 - - Make rule for sample-config.tar.gz. - -commit 7e74e00d167da659ba6c3db3e8822008d27c081b -Author: Guus Sliepen -Date: Fri Aug 8 14:59:27 2003 +0000 - - Allow empty lines in config files. - -commit 863349638beb1eaab09e2a3d537c20a7913aef30 -Author: Guus Sliepen -Date: Fri Aug 8 14:48:33 2003 +0000 - - Simplify execute_script(). It will probably work under Windows as well. - -commit deba3ed900eb4453d27412606cecfaf89b5a5643 -Author: Guus Sliepen -Date: Fri Aug 8 14:24:09 2003 +0000 - - Correct error message when remote host closed connection. - -commit 0c2256670fc0822cc5a86bca754186c50f943a1c -Author: Guus Sliepen -Date: Fri Aug 8 14:07:12 2003 +0000 - - Remove unused stuff from doc/. - Let configure update pathnames in documentation. - -commit 070aee3be16b8d8078b049c5bb43dce7b18123df -Author: Guus Sliepen -Date: Fri Aug 8 12:55:05 2003 +0000 - - Tell windows to be patient. - -commit adb68b9c2aa7ad72dd5c38b95c083c47599cb65a -Author: Guus Sliepen -Date: Fri Aug 8 12:24:52 2003 +0000 - - Windows uses backslashes... - -commit ef091d1ddb1f7ab5244db96841274dc769e85167 -Author: Guus Sliepen -Date: Fri Aug 8 11:45:37 2003 +0000 - - Sync CABAL branch with release-1_0 branch. - -commit 5193a14ddea4c20ffc708dc629a2f91f1e4ccea3 -Author: Guus Sliepen -Date: Sun Aug 3 21:45:41 2003 +0000 - - Use our own port when connecting to ourself. - -commit 62a7fa9a7bfd1cd1592fd7c381ea28aac0ed7936 -Author: Guus Sliepen -Date: Sun Aug 3 21:45:13 2003 +0000 - - Simplify translation - -commit 98f97da9d7d80b528d9a2b2f03f710cdd2b293d0 -Author: Guus Sliepen -Date: Sun Aug 3 21:43:19 2003 +0000 - - Update dutch translation - -commit e220187f484f3549df3ad3a04939b9a38051d1a0 -Author: Guus Sliepen -Date: Sun Aug 3 12:38:43 2003 +0000 - - Remove newlines from log messages. - -commit 3671ed806d7371fb6b14a5909451b20e54a1b14a -Author: Guus Sliepen -Date: Sun Aug 3 12:38:18 2003 +0000 - - Keep Windows happy. - -commit 7bed2a7099fc7359f6ec24e5f2d7050c7d63b6ac -Author: Guus Sliepen -Date: Sun Aug 3 12:37:55 2003 +0000 - - Cygwin needs windows.h. - -commit fa9c00733e4b793691bf5a068ff7f2f391854fb4 -Author: Guus Sliepen -Date: Sun Aug 3 09:55:20 2003 +0000 - - Old gcc compilers don't like declarations in the middle of a function. - -commit a65011b3c54cd4ddc66f20909ca0e495de0d6eb0 -Author: Guus Sliepen -Date: Sun Aug 3 09:08:52 2003 +0000 - - Clean up last part of main(). - -commit e20ac7b52da8e3f7da292836c6e2551fc9f64617 -Author: Guus Sliepen -Date: Sat Aug 2 22:01:50 2003 +0000 - - Typo and another thing to think about. - -commit 92938c07b17fdd30f4e7f9ae1b884b05c7aa312c -Author: Guus Sliepen -Date: Sat Aug 2 21:55:12 2003 +0000 - - Explain how tinc detaches and how it is "killed" under Windows. - -commit 8a1969bc8319761e3821fc76a7c2f7037ffb8850 -Author: Guus Sliepen -Date: Sat Aug 2 21:39:11 2003 +0000 - - Updated dutch translation. - -commit f605ec47bed26362e24ffacf71c7ae5aeed3c230 -Author: Guus Sliepen -Date: Sat Aug 2 21:34:10 2003 +0000 - - Oops. - -commit e6e32814584f82ee61f658a71cb435bbb491bd39 -Author: Guus Sliepen -Date: Sat Aug 2 21:33:52 2003 +0000 - - Missing include. - -commit c044d12dfd54c033bc5ad9fbf9f889724762f76c -Author: Guus Sliepen -Date: Sat Aug 2 21:33:19 2003 +0000 - - Cleanups and error messages. - -commit 3fd96ebec7e44a0a7288c60da1cdec2d4fe03e8c -Author: Guus Sliepen -Date: Sat Aug 2 21:01:50 2003 +0000 - - Error messages. - -commit f08fc359a0b7f638e73a8f866119b016b7dff8de -Author: Guus Sliepen -Date: Sat Aug 2 20:50:38 2003 +0000 - - Install tinc as a service under Windows (MinGW). Remove cleanup_and_exit(), - either exit() directly on errors or let main_loop() shutdown gracefully. - -commit 7c34122af7ed4667748ceae4966bd5b519ac8ad7 -Author: Guus Sliepen -Date: Sat Aug 2 16:05:33 2003 +0000 - - When compiling with MinGW, link with ws2_32. - -commit 9a491a10eee55b243dd1030ee9016ec510908a10 -Author: Guus Sliepen -Date: Sat Aug 2 15:32:57 2003 +0000 - - Windows has no symbolic links as we know it. - -commit 9c2d5d9f9212dee5ee988f4824e5e4afedb7a2dd -Author: Guus Sliepen -Date: Sat Aug 2 15:29:06 2003 +0000 - - Oops. - -commit c7bf64c7946ece3e1a6a7cdd7bce00045bddb9cd -Author: Guus Sliepen -Date: Sat Aug 2 15:27:24 2003 +0000 - - Allow whitespace in values. - -commit b79e55b183898911e2c2b7b151b281aef8d474e1 -Author: Guus Sliepen -Date: Sat Aug 2 15:13:08 2003 +0000 - - Prevent system headers from including our own headers. - -commit 998ac634d456567e7caf99fe879d4ef1602f36bf -Author: Guus Sliepen -Date: Fri Aug 1 08:18:22 2003 +0000 - - Wrong function... - -commit 2531ff59b73af3a6de85fdc33d744758a6ab9449 -Author: Guus Sliepen -Date: Thu Jul 31 14:24:19 2003 +0000 - - Woops! - -commit 1fe56637874a1e93882a2ca6ffb8c50a773f80e4 -Author: Guus Sliepen -Date: Thu Jul 31 13:18:34 2003 +0000 - - No easy way to properly detect header files... - -commit 8eca27e863d9cb139a1e4039f63aaac3c9afc3c6 -Author: Guus Sliepen -Date: Thu Jul 31 11:31:51 2003 +0000 - - Remove forgotten braces. - -commit 5c29d066688691dd1664597ba1c76195634f06c0 -Author: Guus Sliepen -Date: Thu Jul 31 11:20:32 2003 +0000 - - Wrong argument. - -commit da3078c63a3b658573f6e2f986f69ed4d7993b3a -Author: Guus Sliepen -Date: Thu Jul 31 11:17:39 2003 +0000 - - Check if the compiler knows about the __malloc__ attribute. - -commit d798b8b3d832f8c69769e08cfd64a4d8355faf0e -Author: Guus Sliepen -Date: Wed Jul 30 21:52:41 2003 +0000 - - Prevent definitions from messing up attributes. - -commit 2edc764a333764e7e5c4d3420131c13e9c81ecf7 -Author: Guus Sliepen -Date: Wed Jul 30 16:00:59 2003 +0000 - - Replacement for stdbool.h - -commit fcbe29bc4cc67530581a36cf1a3a1445c741b8e5 -Author: Guus Sliepen -Date: Wed Jul 30 11:50:45 2003 +0000 - - No C99 initialisers, gcc 2.95.3 doesn't like it. - Also make sure getopt.h is included. - -commit de223b51b94c58d1674f1ef56e9d485ff48d366d -Author: Guus Sliepen -Date: Wed Jul 30 09:45:21 2003 +0000 - - Remove doc/es/ and src/device.c from the distribution. - -commit 63568bb6bca20b4d2b2068a6367084a273eabac8 -Author: Guus Sliepen -Date: Wed Jul 30 09:22:29 2003 +0000 - - Update documentation and remove stuff that's too outdated. - -commit 2ed154e73192d5e162544bc570abbb3a1df3ec83 -Author: Guus Sliepen -Date: Tue Jul 29 23:21:01 2003 +0000 - - Cleanups. - -commit 721e4caee0f7c6e003c297c95fb6d93bd4102219 -Author: Guus Sliepen -Date: Tue Jul 29 22:59:01 2003 +0000 - - Native Windows support. - -commit 586f15ed20682413d1bddbb4518dd2714c96b255 -Author: Guus Sliepen -Date: Tue Jul 29 12:38:49 2003 +0000 - - Make sure (at least) the MinGW device driver works. - -commit 6f7cce69479f9b2796d81f458bf836287b74462e -Author: Guus Sliepen -Date: Tue Jul 29 12:18:35 2003 +0000 - - Make sure it works. - -commit 4370b98bb1dfa9eb1e400549cb6fcb6711aa1b29 -Author: Guus Sliepen -Date: Tue Jul 29 11:50:39 2003 +0000 - - Update configure scripts. - -commit ae50b0077e27c4c4d81a98da46c66865ffa069be -Author: Guus Sliepen -Date: Tue Jul 29 11:06:23 2003 +0000 - - Update dutch translation and make sure all device drivers are included in - the translation and distribution. - -commit 714fb32d0377ed9f5643ed8f0bd914843d12266b -Author: Guus Sliepen -Date: Tue Jul 29 10:50:15 2003 +0000 - - Fix compile errors and warnings. - -commit 0e945413315c9d15a3eb013fa3731dd978a8c7b8 -Author: Guus Sliepen -Date: Mon Jul 28 22:06:09 2003 +0000 - - More checks for missing functions. - -commit c15e8a96bf7e45adf750b7a36b0e8446ea049468 -Author: Guus Sliepen -Date: Mon Jul 28 21:54:03 2003 +0000 - - More generic handling of tap device under Windows. - -commit 83263b74460656ba557fd9bb84dc27258549e9cd -Author: Guus Sliepen -Date: Thu Jul 24 12:08:16 2003 +0000 - - Sprinkle around a lot of const and some C99 initialisers. - -commit 5cb147135184e3748c6f5e6e6203d22ab9f904f8 -Author: Guus Sliepen -Date: Wed Jul 23 22:17:31 2003 +0000 - - Don't initialise a CIPHER_CTX if cipher == NULL. - -commit 4aadb9500d9198f9c271deb048a2d36000bfae34 -Author: Guus Sliepen -Date: Tue Jul 22 21:13:23 2003 +0000 - - Run setup_device() after parsing configuration but before claiming we're ready. - -commit eefa28059ab989c915a7d95fb4ae728abd7ce713 -Author: Guus Sliepen -Date: Tue Jul 22 20:55:21 2003 +0000 - - Use bools and enums where appropriate. - -commit 471308e1636e7a06e1d9ebc98e82b1c0c5150dde -Author: Guus Sliepen -Date: Tue Jul 22 12:58:34 2003 +0000 - - Option to specify pidfile location. - -commit c96900f378966ca1be96ddb1c43f855c74083b70 -Author: Guus Sliepen -Date: Mon Jul 21 19:58:58 2003 +0000 - - Add section about configuring Cygwin and CIPE on Windows. - -commit bad82522ecfc1f3c72c600cbca6e8fa7e950c3bf -Author: Guus Sliepen -Date: Mon Jul 21 15:51:00 2003 +0000 - - Copy cygwin driver to mingw directory. It doesn't work (yet). - -commit e169244e4b10dbcc1910c0f7fd811304d5b1a5a5 -Author: Guus Sliepen -Date: Mon Jul 21 14:47:43 2003 +0000 - - Use functions from logger.c - -commit 2f2defc4525befd5b5cb69d03b7887db35e9e46c -Author: Guus Sliepen -Date: Mon Jul 21 13:18:44 2003 +0000 - - Check for sys/mman.h. - -commit 64fd25aa6b794bb1d957b50d48705f30ed47c878 -Author: Guus Sliepen -Date: Mon Jul 21 13:15:36 2003 +0000 - - Oops. - -commit c1e8152f4fe5e4557784d8411e50006d461b8786 -Author: Guus Sliepen -Date: Mon Jul 21 13:14:02 2003 +0000 - - Be consistent. - -commit b657f0519456d05bcea5742017165793f79e56df -Author: Guus Sliepen -Date: Fri Jul 18 14:10:27 2003 +0000 - - No UNIX style permissions under Windows. - -commit 38aa0319ef79124e59b587e6d55f37a79a9d847c -Author: Guus Sliepen -Date: Fri Jul 18 14:09:47 2003 +0000 - - Oops. - -commit 123bb765d10453fdccbe363a02e3042c588729cc -Author: Guus Sliepen -Date: Fri Jul 18 13:45:06 2003 +0000 - - Use iface instead of interface because it might already be declared in - system header files. - -commit 96ee04b678143defa1040f2defdd3424efedea11 -Author: Guus Sliepen -Date: Fri Jul 18 13:42:35 2003 +0000 - - Check for ethernet/ipv4/ipv6 related structures. - -commit 00ddbf5723511d80fbd2522fc503bd409dc6189a -Author: Guus Sliepen -Date: Fri Jul 18 13:41:37 2003 +0000 - - Update all device.c files. - -commit 271d3537fed28b3e76cf0e76082b44c8771ac5da -Author: Guus Sliepen -Date: Fri Jul 18 12:21:03 2003 +0000 - - Remove all #ifndefs from route.c - -commit b0a4f7b5551cae6fb5af2eb4bcb0dfb3443f7d89 -Author: Guus Sliepen -Date: Fri Jul 18 12:16:24 2003 +0000 - - Even more missing definitions. - -commit e449d94caef963809d417f16497f6f978e10d731 -Author: Guus Sliepen -Date: Thu Jul 17 15:06:27 2003 +0000 - - Big header file cleanup: everything that has to do with standard system - libraries is moved to system.h. - -commit 47721be760c495ec13d68181bc03b151ffc1399c -Author: Guus Sliepen -Date: Tue Jul 15 16:38:18 2003 +0000 - - Windows headers declare a struct interface somewhere. - -commit 4c52febc57f2e34f5a187f0e57782903fe1eb95e -Author: Guus Sliepen -Date: Tue Jul 15 16:27:39 2003 +0000 - - Make use of the CIPE driver. Woohoo, tinc for Windows! - -commit d26a4af4561ce4236b8224919cf4f3636f57b4c1 -Author: Guus Sliepen -Date: Tue Jul 15 16:26:18 2003 +0000 - - Export mymac. - -commit 784db4e70d2573468c82ff5dfee723b77a20322f -Author: Guus Sliepen -Date: Sat Jul 12 20:24:04 2003 +0000 - - Format string checking for logger(). - -commit a438ac911e7e60e54d7d1fc4f84373fab7e055af -Author: Guus Sliepen -Date: Sat Jul 12 20:19:22 2003 +0000 - - Removing distribution specific files from CVS. - -commit 085d33e6265e139bb08cdfda3d7498993190d187 -Author: Guus Sliepen -Date: Sat Jul 12 17:48:38 2003 +0000 - - Update copyrights. - -commit 5db596c6844169f1eb5f804b72abe99d067aaa5a -Author: Guus Sliepen -Date: Sat Jul 12 17:41:48 2003 +0000 - - Simplify logging, update copyrights and some minor cleanups. - -commit 2a7f11c0e90f5f0465bbc3c75de715454066ff72 -Author: Guus Sliepen -Date: Fri Jul 11 16:13:00 2003 +0000 - - More missing IPv6 definitions and autoconf checks to make sure it compiles - under Solaris 2.6. - -commit 71f8124ea49f2a0e00e0cedbb1b76e49e9f1425d -Author: Guus Sliepen -Date: Mon Jul 7 11:50:52 2003 +0000 - - More missing definitions. - -commit a88f1edf297152580a7729c6f3d274ba2bff7360 -Author: Guus Sliepen -Date: Mon Jul 7 11:13:31 2003 +0000 - - Actually add ipv6.h. - -commit 30c0381d71d333a99f6c83ff9d03ef4a0857f423 -Author: Guus Sliepen -Date: Mon Jul 7 11:11:33 2003 +0000 - - Provide all missing IPv6 definitions in lib/ipv6.h. - -commit 1401faf608e1c8af0d0754e545b0ec79d2bd5d93 -Author: Guus Sliepen -Date: Sun Jul 6 23:16:29 2003 +0000 - - Sprinkling the source with static and attributes. - -commit 0b9175e998c2180e5d73ef3d644a49d620c68cad -Author: Guus Sliepen -Date: Sun Jul 6 22:11:37 2003 +0000 - - Define logger(), cleans up source code and allows us to write log entries - to a separate file. - -commit 868104703003605711582c984b57f8933bf361ee -Author: Guus Sliepen -Date: Sun Jul 6 17:49:49 2003 +0000 - - Check for IPv6 header files. - -commit 81f5713ab71944d51703653eab7f364fba0c482e -Author: Guus Sliepen -Date: Sun Jul 6 17:15:25 2003 +0000 - - - simplify configure.in - - drop support for OpenSSL < 0.9.7 - - add some missing definitions/includes - -commit 6c7172d694dcb80e538518282b6c4bd51818f1d2 -Author: Guus Sliepen -Date: Wed Jun 25 20:55:05 2003 +0000 - - This subtle pointer arithmetic thingy is (I'm very sure of it) the cause - of the lingering connections problem. Hopefully it is fixed now... - -commit 9528a63c35da77ba5b825068aeffbc5587816dd5 -Author: Guus Sliepen -Date: Wed Jun 25 20:52:59 2003 +0000 - - Really make tinc default to any addressfamily. - -commit 8bfa554af97ee0694919b9f5b78ada89c6af62f5 -Author: Guus Sliepen -Date: Thu Jun 12 11:08:40 2003 +0000 - - There are two lzo compression levels. - -commit c3593491d44e8e8f239bb297f5d5f6541d581b78 -Author: Guus Sliepen -Date: Wed Jun 11 20:36:36 2003 +0000 - - Typo and conversion to UTF-8. - -commit 636e650261712e3687048fe19987fd50ce84b093 -Author: Guus Sliepen -Date: Wed Jun 11 20:19:46 2003 +0000 - - Update dutch translation. - -commit 9279b3c69982b066e2aaea4e444892b51332881a -Author: Guus Sliepen -Date: Wed Jun 11 20:18:48 2003 +0000 - - Update documentation. - -commit 0a9aef2da749f7b7d1ca183daad88f6433579b9f -Author: Guus Sliepen -Date: Wed Jun 11 19:40:43 2003 +0000 - - More braces to make gcc happy. - -commit cf63cbef2bcb6a1f21ded439cbb09842581b9020 -Author: Guus Sliepen -Date: Wed Jun 11 19:39:02 2003 +0000 - - Fixes from Wessel Danker's libavl. - -commit 12de5a8eedd985f4732e88de6185f77a8244612c -Author: Guus Sliepen -Date: Wed Jun 11 19:28:38 2003 +0000 - - Remove mymac stuff from device.c. - -commit 31f17d43346a9175aec7c29ce41c71b1d08f725e -Author: Guus Sliepen -Date: Wed Jun 11 19:27:35 2003 +0000 - - AddressFamily is "any" by default. - -commit 451800eda87e886021fabd1888e486c51e97902a -Author: Guus Sliepen -Date: Wed Jun 11 19:09:52 2003 +0000 - - If we have a Linux tun/tap device and we are in router mode, open the device - in tun mode. - -commit 9e02a3d5631b687833e4cdcde18cda66e38138fc -Author: Guus Sliepen -Date: Wed Jun 11 19:07:56 2003 +0000 - - Call make_names() before doing anything else. - -commit 4b0e5a03fe89529ebe5d471a82c29c153a12116b -Author: Guus Sliepen -Date: Sat Jun 7 13:18:32 2003 +0000 - - Fix warning and add missing checks for LZO library. - -commit f238c209f4a0ced889b8fb443753ed2cdb3548b3 -Author: Guus Sliepen -Date: Sat May 17 22:12:52 2003 +0000 - - Fix links. - -commit 249933350bda2c3fa09c7ce8eb36bf84ee30a1cb -Author: Guus Sliepen -Date: Wed May 7 11:21:58 2003 +0000 - - Small fixes. - -commit 6ba4e2da55001e17aec6a7ee71002130555ff439 -Author: Guus Sliepen -Date: Tue May 6 23:14:45 2003 +0000 - - Small fixes to make LZO compression work. - -commit c70f52087bf6f7514684bbc859b83aec2ca17ae4 -Author: Guus Sliepen -Date: Tue May 6 21:13:18 2003 +0000 - - - Per-node EVP_CIPHER_CTX to avoid initialisation overhead. - - LZO compression, thanks to Teemu Kiviniemi. - - Updated dutch translation. - -commit 1ad2394b8468593030653bbfd0dee879fb711432 -Author: Guus Sliepen -Date: Sat Apr 19 11:12:45 2003 +0000 - - Make sure outgoing_t is completely freed. - -commit bc9e78250ef6fb5169d03565b7d8d9caf309eb98 -Author: Guus Sliepen -Date: Fri Apr 18 21:18:36 2003 +0000 - - Better handling of late packets. - -commit 51a1bcf00143319c74ffb58a66a19c41be422c21 -Author: Guus Sliepen -Date: Thu Apr 3 11:43:17 2003 +0000 - - HUP signal now closes connections to hosts if their host config file is - gone or changed. The tinc.conf file is reread for changes in the ConnectTo - lines. - -commit 8285827da127e38728b60b5c5484e5cdabff2f21 -Author: Guus Sliepen -Date: Sat Mar 29 22:11:22 2003 +0000 - - Checksums must also work for uneven number of bytes. - -commit c3ad3731a8dfa34535a156a7cfdb4e18afaa8bce -Author: Guus Sliepen -Date: Sat Mar 29 21:58:35 2003 +0000 - - Don't copy more than necessary. - -commit 7d21a8d1c7fd8909fe02385dbb4717c074db4648 -Author: Guus Sliepen -Date: Sat Mar 29 21:51:21 2003 +0000 - - - Speed up checksumming - - If a destination is not found in the subnet list or the destination node - is unreachable, respond with an appropiate ICMP message. - -commit 9792ba2cac35cb50cc99b72dd4cb9d3ef350dbd4 -Author: Guus Sliepen -Date: Fri Mar 28 13:41:49 2003 +0000 - - - Avoid memory leak caused by OpenSSL 0.9.7a. - - Disable RSA_blinding_on() because it segfaults. - -commit 69158563e9f790777eb27aeb8484a86d12385af4 -Author: Guus Sliepen -Date: Wed Mar 19 11:45:05 2003 +0000 - - Typo. - -commit 88ae2e9e0c1eb62d9b74c4b38d9c0e93557fed9f -Author: Guus Sliepen -Date: Wed Mar 19 11:43:42 2003 +0000 - - Make sure send_meta() writes everything. - -commit 2fff0a91a7e3e5f44e97255b6dd5807656b255a8 -Author: Ivo Timmermans -Date: Fri Mar 14 09:43:10 2003 +0000 - - Call RSA_blinding_on(), as advised in the paper on - http://crypto.stanford.edu/~dabo/abstracts/ssl-timing.html - to offer some resistance against timing attacks. - -commit 1783a3aaa9b692ab64260a9c2adf588ed6083a1c -Author: Guus Sliepen -Date: Fri Jan 17 00:43:58 2003 +0000 - - Various fixes for autoconf and OpenSSL 0.9.7 and a missing header. - -commit c08858baa91a00e38c0f5482dbb0817dbd0361f1 -Author: Guus Sliepen -Date: Fri Jan 17 00:37:20 2003 +0000 - - - Fix indentation in some places. - - Optimise select loop. - - Remove unused function setup_outgoing_socket(). - - Clear EVP_CIPHER_CTX structures before using them. - -commit 38f562fdfcacb50d34b9a48bfaea7faa132f493a -Author: Guus Sliepen -Date: Tue Jan 14 12:53:59 2003 +0000 - - Add $NAME for tinc-up/down scripts. - -commit 44b87ddb7ac90be13ef3e3d5118acaa158184853 -Author: Guus Sliepen -Date: Sun Jan 12 17:02:23 2003 +0000 - - Run graph algorithm when replacing a second connection from the same host - replaces an older one. - -commit 4c88ff86bcd32735d4768ef3464812cd77c500be -Author: Guus Sliepen -Date: Fri Dec 27 19:32:33 2002 +0000 - - PrivateKeyFile instead of PrivateKey. - -commit 5b2a62ebb6317cd88e491ee958c54670f381aee8 -Author: Guus Sliepen -Date: Thu Nov 14 22:09:03 2002 +0000 - - Fix PriorityInheritance. - -commit 07db46a44feb283c1c17bcce918ab49274a3b11f -Author: Guus Sliepen -Date: Mon Oct 7 07:32:31 2002 +0000 - - Add documentation for BindToAddress. - -commit e310cc82d3f9c9bdb3b827daa149861a41e2e00a -Author: Ivo Timmermans -Date: Mon Sep 30 19:04:37 2002 +0000 - - Fix saving of debug level for startup level 0 - -commit 006591efe5b3e6c64040d267f8c0477468abf2bf -Author: Guus Sliepen -Date: Tue Sep 24 11:43:34 2002 +0000 - - Run graph() after edge_del() when updating an edge. - -commit 6904e0469ef52aa6100f0185d579bc205bd07be8 -Author: Wessel Dankers -Date: Mon Sep 16 14:08:04 2002 +0000 - - its: Engels voor "van het" - 3e persoon enkelvoud, genitief, onzijdig - it's: Engels voor "het is". Dus niet "van het". - -commit 4f3395ee4dad3cdd23706af180ebddfa5e576012 -Author: Guus Sliepen -Date: Sun Sep 15 22:37:59 2002 +0000 - - Thank some more people. - -commit b216297a004f083336c633aaccecb4ab175360b3 -Author: Guus Sliepen -Date: Sun Sep 15 22:34:25 2002 +0000 - - Remarks about 1.0pre8 release. - -commit 1dcbdf48eb4a642e4d70a9e67aaca78deacf352d -Author: Guus Sliepen -Date: Sun Sep 15 22:19:38 2002 +0000 - - Update documentation. - -commit bf3a11898898c0618cd1b2e7a792b7d7fe56aecb -Author: Guus Sliepen -Date: Sun Sep 15 22:19:19 2002 +0000 - - Use /dev/net/tun as default for tun/tap device under Linux. - -commit 7d76ceaebd5180f4ef37086980c799199eb7de16 -Author: Guus Sliepen -Date: Sun Sep 15 17:40:00 2002 +0000 - - Updated dutch translation. - -commit 5eca9520d93bced1275d45e5e2a933d69354cd6d -Author: Guus Sliepen -Date: Sun Sep 15 14:55:54 2002 +0000 - - Small fixes so tinc compiles out of the box on SunOS 5.8 - -commit 8d472a415e9c5fdb878386005d29cdfd97b8a404 -Author: Guus Sliepen -Date: Sun Sep 15 12:26:24 2002 +0000 - - port_t isn't used anymore and conflicts with MacOS/X headers. - -commit 38c80bdd46fab68c686a293e2820041291972f3a -Author: Guus Sliepen -Date: Sun Sep 15 12:26:04 2002 +0000 - - MacOS/X needs #define _P1003_1B_VISIBLE in order to use mlockall(). - -commit 3e3b4a3190cf950c265a8c62d577812a22b11dcc -Author: Guus Sliepen -Date: Wed Sep 11 22:25:58 2002 +0000 - - What was I thinking? - -commit f6905582d0e70ac5b44369780aaa921d9c721197 -Author: Guus Sliepen -Date: Tue Sep 10 22:13:22 2002 +0000 - - Make sure malloc() is declared. - -commit eaf1208e9d5c5a15e4b23de936830520bf3b5685 -Author: Guus Sliepen -Date: Tue Sep 10 22:13:01 2002 +0000 - - Fix placement of #include "config.h" - -commit dd888ca685176128bf41034208f3dbb220f9d832 -Author: Guus Sliepen -Date: Tue Sep 10 21:46:05 2002 +0000 - - Link with libintl if necessary. - -commit c01f78ed3603eecaec8e3649a3bfb3de9742fd24 -Author: Guus Sliepen -Date: Tue Sep 10 21:29:42 2002 +0000 - - Clean up after indent. - -commit 161f917dd03c174742fb8c6722f430a93b506cb1 -Author: Guus Sliepen -Date: Tue Sep 10 09:40:25 2002 +0000 - - Fix compiler warnings. - -commit 3bc554347560a9c24e68bb2c7c7749be07bbec3d -Author: Guus Sliepen -Date: Mon Sep 9 22:41:56 2002 +0000 - - Let GCC check format string and arguments of send_request(). - -commit 6f9f6779e6bd1dd7bb795b42dad550863a386ca8 -Author: Guus Sliepen -Date: Mon Sep 9 22:33:31 2002 +0000 - - Remove redundant spaces. - -commit 9f38e394636a177c00a4545de2a99c661de36386 -Author: Guus Sliepen -Date: Mon Sep 9 21:49:16 2002 +0000 - - Switch to K&R style indentation. - -commit f75dcef72a81a337e847adf0bae54198894f65b9 -Author: Guus Sliepen -Date: Mon Sep 9 21:25:28 2002 +0000 - - Switch to K&R style indentation. - -commit 5fc1ed17f41f0c535cf57a4b7e00cd6d45759503 -Author: Guus Sliepen -Date: Mon Sep 9 19:40:12 2002 +0000 - - Cleanups: - - Convert cp to cp(); so that automatic indenters work. - - Convert constructions like if(x == NULL) to if(!x). - - Move all assignments out of conditions. - -commit 5638b9830f9cfe43f545c37cfd7ccf1d4b4bfcc6 -Author: Guus Sliepen -Date: Fri Sep 6 21:22:35 2002 +0000 - - Why don't these connection_t's get cleaned up? - -commit a8ddba42b99d7694359f1387235596b84d297b9e -Author: Guus Sliepen -Date: Fri Sep 6 21:02:36 2002 +0000 - - Fix MST algorithm. - -commit 66741978e16cc407e5c760621c34d1aabb753cd2 -Author: Guus Sliepen -Date: Fri Sep 6 14:31:12 2002 +0000 - - Reset the *correct* seqnos. - -commit d5b61fc0cd249fd2b2751a1ff77b321323a17beb -Author: Guus Sliepen -Date: Fri Sep 6 12:19:16 2002 +0000 - - edge_weight_compare() shouldn't rely on edge_compare(). - -commit fc7116a32b798589e7731db9f9db66345c8c3e01 -Author: Ivo Timmermans -Date: Fri Sep 6 11:08:21 2002 +0000 - - Added AM_MAINTAINER_MODE - -commit fbf8a47879671541939cfdc6beb93b02b9eee303 -Author: Guus Sliepen -Date: Fri Sep 6 10:23:52 2002 +0000 - - Remove global edge_tree. - -commit 641705df90b4c41e7f5083f6cd601cbbfb1c2c85 -Author: Guus Sliepen -Date: Fri Sep 6 09:48:39 2002 +0000 - - Only reset seqno's when a key is sent or received. - -commit e4d85a6557ee45870bee0c5a16807e48b7a3c243 -Author: Guus Sliepen -Date: Wed Sep 4 23:11:58 2002 +0000 - - Typo. - -commit b4f87952bf2d37524c705b32864f802144f94d68 -Author: Guus Sliepen -Date: Wed Sep 4 23:05:49 2002 +0000 - - Add missing headers. - -commit b18bd211bec84a804f58da5f2d2908e54de3fe40 -Author: Guus Sliepen -Date: Wed Sep 4 23:04:52 2002 +0000 - - Run autopoint and libtoolize before creating initial makefiles. - -commit 6fdaa8e1caff4edb44a105b03c79403b743e9bd2 -Author: Guus Sliepen -Date: Wed Sep 4 19:57:53 2002 +0000 - - Small updates. - -commit d4277e9ee8affa59ac9b3475245360bd14af1fa8 -Author: Guus Sliepen -Date: Wed Sep 4 16:36:03 2002 +0000 - - Updated dutch translation. - -commit 8b2b67e26c5b971761f5015764d5e188f6343bc4 -Author: Guus Sliepen -Date: Wed Sep 4 16:26:45 2002 +0000 - - Generalized request broadcasting/forwarding. - -commit 431fa10b37e78172a03c952e28a0364cc0e438f0 -Author: Guus Sliepen -Date: Wed Sep 4 14:17:28 2002 +0000 - - Small fixes. - -commit 82ebfc923ddb050c88bdf5d65ac943a15ca8748a -Author: Guus Sliepen -Date: Wed Sep 4 13:48:52 2002 +0000 - - Revert to edge and graph stuff. This time, use a directed graph. - -commit 973530db628fb91106d6fb7a17151e1d036e40a2 -Author: Guus Sliepen -Date: Wed Sep 4 08:48:03 2002 +0000 - - Just ignore wrong ADD_NODEs instead of replying with a DEL_NODE, in the - hope other DEL_NODEs will catch up eventually. - -commit 2af0bcc8fd39ca34a7ff856d539cdf38728a8c25 -Author: Guus Sliepen -Date: Wed Sep 4 08:36:34 2002 +0000 - - Don't forget to set prevhop to myself for new connections. - -commit 698d6ddac6ab32d5a4b802941b02232793442684 -Author: Guus Sliepen -Date: Wed Sep 4 08:33:08 2002 +0000 - - Prevent looping DEL_NODE/ADD_NODE messages after a node disconnects. - -commit 4a7c2026aec6966f934b60d75bc472d28f8587d8 -Author: Guus Sliepen -Date: Wed Sep 4 08:02:33 2002 +0000 - - Reduce KEY_CHANGED traffic. - -commit ddb96301a39dd3dac8d3df4e2e189b13b75e0b6e -Author: Guus Sliepen -Date: Tue Sep 3 22:49:55 2002 +0000 - - Woops. - -commit b5bb06200eda170c9836e1b4474d6f5b920c2151 -Author: Guus Sliepen -Date: Tue Sep 3 22:37:49 2002 +0000 - - A reachable node is always more preferable to an unreachable one... - -commit d134c4542d4e890e1c1007f32b866742319853c5 -Author: Guus Sliepen -Date: Tue Sep 3 20:43:26 2002 +0000 - - Drop graph and edge stuff. Use new node stuff instead. - -commit 856de4c5fe8acd779aa9277d4554e34ff3625e97 -Author: Guus Sliepen -Date: Tue Sep 3 20:42:05 2002 +0000 - - Make sure setlocale() is available. - -commit 2cb21f8810a6e0241a80623e991c8308b603ae95 -Author: Guus Sliepen -Date: Mon Sep 2 22:40:42 2002 +0000 - - Replacement for the current routing algorithm. - -commit f2c2443bbcfd5e09518bd87f3fd8d4a727d73ae2 -Author: Guus Sliepen -Date: Sat Aug 24 12:54:55 2002 +0000 - - Check for ranlib. - -commit 912e7e968f4888d62b3c620893a70e825599973b -Author: Guus Sliepen -Date: Sat Aug 24 12:11:40 2002 +0000 - - Gettext 1.11.5 compatibility. - -commit 18948c5784bfedf0dd5a371e41bc2cceee76d92e -Author: Guus Sliepen -Date: Thu Jul 18 14:30:45 2002 +0000 - - Added support for raw sockets. This can be used instead of tun/tap devices. - -commit 9f370893fafaeacdd78f5488cfa8b76fdee0d224 -Author: Guus Sliepen -Date: Tue Jul 16 13:18:27 2002 +0000 - - Don't bother to chown, and correctly document ConnectTo. - -commit 227ccd3a8a5602e4c31add8da1bfd8b35c6a801f -Author: Guus Sliepen -Date: Tue Jul 16 13:12:49 2002 +0000 - - Allow tincd to be locked into main memory. - -commit c4cd19935763b379e730a6fdf53dc1ca98d0b938 -Author: Guus Sliepen -Date: Fri Jul 12 11:45:21 2002 +0000 - - Include complete fake-getname/addrinfo from OpenSSH. - -commit afabbd6b9020dd6555a7ecd320a7b3e96119d538 -Author: Guus Sliepen -Date: Thu Jul 11 12:57:06 2002 +0000 - - Added stub device.c for Cygwin. - -commit 8949404db08f4ab594e60778bb76a9061426d7cc -Author: Guus Sliepen -Date: Thu Jul 11 12:55:58 2002 +0000 - - Started port to Cygwin. - -commit c98db1b861d62430e23f26b0da18e7b3ec875767 -Author: Guus Sliepen -Date: Thu Jul 11 12:42:43 2002 +0000 - - Clear subnets before using them. - -commit 8dd09568f1604f1ac8cc0d8d5120d986f5654900 -Author: Guus Sliepen -Date: Wed Jul 10 11:32:33 2002 +0000 - - Allow identical subnets from different owners. - -commit 36cbaa32f480b481bf2ee99fd4835586a02ebc60 -Author: Guus Sliepen -Date: Wed Jul 10 11:27:06 2002 +0000 - - Allow list of environment variables to be passed to execute_script(). - When executing host-up/down scripts, include the address and port of the - remote host. - -commit a1bd878e11ae7e66e7e9a4040c3b19f9b7bc50f4 -Author: Guus Sliepen -Date: Fri Jun 21 17:49:48 2002 +0000 - - Fix for prefixlengths of 32 (IPv4) and 128 (IPv6) bits. - -commit 627f7c22b447bd464b536cd016278545674df93d -Author: Guus Sliepen -Date: Fri Jun 21 10:11:37 2002 +0000 - - s/sliepen.warande.net/sliepen.eu.org/g - s/itimmermans@bigfoot.com/ivo@o2w.nl/g - -commit faabd163adf89bd0580cd40b8735ef8d9028a942 -Author: Guus Sliepen -Date: Fri Jun 14 11:51:29 2002 +0000 - - Update comments about IPv6 autoconfiguration. - -commit 940fcb6701d055f49530f12c93371f0280efce80 -Author: Guus Sliepen -Date: Thu Jun 13 16:12:40 2002 +0000 - - Reset listen_sockets after SIGHUP. - -commit 3a3adf5b690e9be1390a5df3caee6af64b25838f -Author: Guus Sliepen -Date: Wed Jun 12 13:45:23 2002 +0000 - - Add configuration details for NetBSD and Darwin (MacOS/X). - -commit 8988b127e18435054e48cbcca8ac712ddda3d6d2 -Author: Guus Sliepen -Date: Tue Jun 11 11:03:17 2002 +0000 - - Autoconf cleanup. Works for both 2.13 and 2.53, although running autoconf - 2.53 still gives some errors. - -commit de6835a9dd1891b6435c128cc6c2293950a4d7a7 -Author: Guus Sliepen -Date: Mon Jun 10 15:08:23 2002 +0000 - - Include darwin/device.c in distribution. - -commit 40ac473cb10f9c6a59739ce70032b746d8e0bf68 -Author: Guus Sliepen -Date: Mon Jun 10 14:35:18 2002 +0000 - - Use darwin/device.c when compiling on MacOS/X. - -commit 69b758879ee6d322e89143141b98d52167845c26 -Author: Guus Sliepen -Date: Mon Jun 10 14:33:40 2002 +0000 - - Added Darwin (MacOS/X) tun device handling. - -commit bd72e14138185f342885c0ed1c0f2c5dbf571132 -Author: Ivo Timmermans -Date: Sun Jun 9 16:23:12 2002 +0000 - - Added Alessandro Gatti - -commit 944df3eeee50972fcac84cfc8eefb36033bf04ad -Author: Ivo Timmermans -Date: Sun Jun 9 16:19:20 2002 +0000 - - Include netbsd's device.c in make dist - -commit 7608136a8dae24f2df30eac8644efd0d7cd57dc9 -Author: Ivo Timmermans -Date: Sun Jun 9 16:12:04 2002 +0000 - - Include a few more header files - -commit cd3601c5df57c7544ece00bf79e82b36499a26ff -Author: Ivo Timmermans -Date: Sun Jun 9 15:58:05 2002 +0000 - - Add /sw/{include,lib} to search paths if they exist - -commit 548551fd05f58863dfbbaaf147febfab0a22889b -Author: Ivo Timmermans -Date: Sun Jun 9 15:50:12 2002 +0000 - - getnameinfo fixes - -commit 9d769e0bf2ce266e8533e5e7c16bf07e44a9be34 -Author: Ivo Timmermans -Date: Sun Jun 9 15:26:10 2002 +0000 - - OSX support - -commit 78e88521845ae3bdd963ae5a414cb9c251963fa2 -Author: Guus Sliepen -Date: Sat Jun 8 14:08:57 2002 +0000 - - - netinet/* include files depend on netinet/in_systm.h. - - Squash bashism in configure.in. - -commit e47e51e9d17416e2b614287d14a5518881decd44 -Author: Guus Sliepen -Date: Sat Jun 8 13:46:43 2002 +0000 - - Use inttypes.h instead of stdint.h. - -commit 116ba3b3da73fb857cf75b5c92c6aacd70d94dd9 -Author: Guus Sliepen -Date: Sat Jun 8 12:57:10 2002 +0000 - - Cleanup: - - Remove checks for specific OS's, instead check for #defines/#includes. - - Use uint??_t where appropriate. - - Mask handling functions use void pointers to get rid of silly casts. - -commit d333fca4d611b85dd922ddf35bd9eddcb8095c85 -Author: Wessel Dankers -Date: Fri Jun 7 11:14:05 2002 +0000 - - This should work much better. - -commit 14e570f5eeff631c1312b11fcc5d22230ec27aff -Author: Guus Sliepen -Date: Wed Jun 5 00:25:55 2002 +0000 - - Use correct includes on NetBSD. - -commit 5886b6a10d0d2edf20ff53c4926ec4e41a36b8c0 -Author: Guus Sliepen -Date: Wed Jun 5 00:20:40 2002 +0000 - - Make it work correctly with NetBSD tun device. - -commit 4856d8e1f8398780a49545f35ba9b5746c9fc060 -Author: Guus Sliepen -Date: Sun Jun 2 16:06:33 2002 +0000 - - Support RSA_PUBKEYs (as opposed to RSAPublicKeys) so tinc accepts - public keys generated by the OpenSSL command line tools. - -commit efa5148bc76effb440d807d653dda02de050fde0 -Author: Ivo Timmermans -Date: Tue May 7 14:48:41 2002 +0000 - - Hm. - -commit 151ab8c9708534e012447688ed44d711d5b5fa2d -Author: Ivo Timmermans -Date: Thu May 2 13:23:58 2002 +0000 - - test 2 - -commit be04387a0c868b22ee4427822573df8b3b479bbe -Author: Ivo Timmermans -Date: Thu May 2 13:22:44 2002 +0000 - - test - -commit a9bb66367df82d062175f2b9b4bf236d77ae3ff1 -Author: Ivo Timmermans -Date: Thu May 2 13:11:55 2002 +0000 - - Moved event.c/h - -commit 474aab6325bf94724874cb74a9b56d9da739e1b8 -Author: Ivo Timmermans -Date: Thu May 2 11:52:28 2002 +0000 - - Callbacks - -commit 4c1a4e8a790584e4c7d5c0f2485706f4c01e1911 -Author: Ivo Timmermans -Date: Thu May 2 11:50:07 2002 +0000 - - Another file moved; random interface stuff. - -commit 2be8e69ca16e1558463c39c48af76d3d4a4674b7 -Author: Guus Sliepen -Date: Wed May 1 09:15:58 2002 +0000 - - Only purge once when there are no more connections. - -commit a77b35e748b7cf4cf7ac31750cefab7b2b0325f5 -Author: Ivo Timmermans -Date: Mon Apr 29 20:19:42 2002 +0000 - - Commit diff test - -commit 7caa253df4a34e594438e3fbe80c2bddab9a2b4a -Author: Guus Sliepen -Date: Mon Apr 29 20:05:07 2002 +0000 - - Fix very stupid bug in node_del(), which might have caused corruption of - subnets. - -commit 04d33be4bd102de67bb6dba5c449e12fea0db4d2 -Author: Ivo Timmermans -Date: Sun Apr 28 12:46:26 2002 +0000 - - Moving files, first attempt at gcrypt compatibility, more interface - abstraction - -commit b0a676988a8da3120e64ef0e1a4ea4c28b1511e1 -Author: Ivo Timmermans -Date: Sun Apr 28 12:43:40 2002 +0000 - - *** empty log message *** - -commit 67a6d7bcc4891c627663c639c0e02315bd4cf437 -Author: Guus Sliepen -Date: Sat Apr 27 11:40:45 2002 +0000 - - Informative log message if execl() failed. - -commit e6a67fc439fc3b46157647bed1af59b7519adb80 -Author: Ivo Timmermans -Date: Fri Apr 26 18:13:00 2002 +0000 - - Typo - -commit 01747d73a217f7ddf2107b086476702a9d04d683 -Author: Guus Sliepen -Date: Thu Apr 25 19:17:24 2002 +0000 - - Added Nick Patavalis for his RedHat package. - -commit b6ad4ce35a4434c209ee26015f15a18180987bac -Author: Guus Sliepen -Date: Tue Apr 23 07:49:38 2002 +0000 - - Add BindToAddress variable, similar to the late BindToIP. - -commit 40c2e36a96a3f5c34d4851b30f3561123f3906b5 -Author: Guus Sliepen -Date: Fri Apr 19 14:06:40 2002 +0000 - - Support for MaxOS/X. - -commit 97d492d9e23f43fe4c8a5ca8c95747088cf32f98 -Author: Ivo Timmermans -Date: Thu Apr 18 20:09:05 2002 +0000 - - Put #ifndef checks for HAVE_RAND_PSEUDO_BYTES in the correct places. - -commit fa8faff84bbbeb818adaea80d7bf9e12e0074978 -Author: Ivo Timmermans -Date: Sat Apr 13 18:01:58 2002 +0000 - - Print newline when writing to stderr - -commit fbebc5b65606119c01e9e1e3fcc7b2cc4cfd1daf -Author: Ivo Timmermans -Date: Sat Apr 13 11:24:25 2002 +0000 - - ... - -commit 7c75090025a4b06290663e0033a62414f3368f7c -Author: Ivo Timmermans -Date: Sat Apr 13 11:23:46 2002 +0000 - - Rename libvpn to libtinc - -commit 55385cacbfb0c743fc518e54854e24b7b05a623c -Author: Ivo Timmermans -Date: Sat Apr 13 11:23:19 2002 +0000 - - Renamed libvpn to libtinc - -commit 2389dcd573d909f21c8ec2d349b079075af6c7d3 -Author: Ivo Timmermans -Date: Sat Apr 13 11:21:58 2002 +0000 - - Include logging.h - -commit 246ce12c92ccc7badbb8c8c9a88fa03a7de9811f -Author: Ivo Timmermans -Date: Sat Apr 13 11:21:01 2002 +0000 - - Use new logging system - -commit a5b3ec41214ac8aea9b82734f92b5953e04a0c09 -Author: Ivo Timmermans -Date: Sat Apr 13 11:15:43 2002 +0000 - - Things to ignore... - -commit e239504524589a0f1549ca174f927afd07d563ba -Author: Ivo Timmermans -Date: Sat Apr 13 11:14:50 2002 +0000 - - Compile in logging.c - -commit e26dd564163fca001ab1694a51e7412f9ac970de -Author: Ivo Timmermans -Date: Sat Apr 13 11:08:31 2002 +0000 - - Use logging.h instead of syslog.h - -commit 72cd8938e2c759905666ea7d2c90dc1f0b2e2cd5 -Author: Ivo Timmermans -Date: Sat Apr 13 11:00:41 2002 +0000 - - Added prototype for log_syslog - -commit 48b80c93d30d5fae4273b0b496252bbc884abe53 -Author: Ivo Timmermans -Date: Sat Apr 13 10:55:42 2002 +0000 - - log_default_hook was renamed to log_default - -commit b63c3a1f0002675b6bedbd0b235e0ad0a708d4e3 -Author: Ivo Timmermans -Date: Sat Apr 13 10:50:48 2002 +0000 - - Added priority definitions from syslog.h - -commit 490b13edcfcae0422b6bd77fdb2a7f0181b14307 -Author: Ivo Timmermans -Date: Sat Apr 13 10:45:56 2002 +0000 - - Some magic - -commit 738389581b1ba29a181f639f3d20e3e24ff546f5 -Author: Ivo Timmermans -Date: Sat Apr 13 10:43:10 2002 +0000 - - Add syslog wrapper - -commit efa59f7cf4d416c8416866baeaa72cba7e936568 -Author: Ivo Timmermans -Date: Sat Apr 13 10:40:09 2002 +0000 - - Add syslog() wrapper - -commit 8822481d7b11db72d5400717d6b491b5f36bcb1f -Author: Ivo Timmermans -Date: Sat Apr 13 10:29:07 2002 +0000 - - Rename log_message to log - -commit cc603e2765f17555ecdc2b74c27ebf96e6691bf6 -Author: Ivo Timmermans -Date: Sat Apr 13 10:25:38 2002 +0000 - - New logging system to replace syslog() calls with a generic function. - -commit 131327a729216de8ae86da0c3c4d65d409741b7b -Author: Ivo Timmermans -Date: Sat Apr 13 10:04:46 2002 +0000 - - Remove debug_lvl - -commit e3c51b61caabc1a55772f7a52e75aab642c200ed -Author: Ivo Timmermans -Date: Sat Apr 13 10:02:48 2002 +0000 - - Update copyright info - -commit 9e8468f54aa5ecdb8b63c60449791427b59a474d -Author: Ivo Timmermans -Date: Sat Apr 13 10:02:16 2002 +0000 - - Remove debug level declaration - -commit 9f2c50e159caea1884c6a7aaa33f8098539ae0f5 -Author: Guus Sliepen -Date: Fri Apr 12 08:25:01 2002 +0000 - - Adding even more stuff from the CABAL branch. - -commit 191dcd5add0afba8b5d3aaa1e188c562c621712e -Author: Ivo Timmermans -Date: Thu Apr 11 20:18:02 2002 +0000 - - Also compile in pokey/ - -commit 39e93f473d34d6cdf6f4a7f0390a3b50cbd7b564 -Author: Ivo Timmermans -Date: Thu Apr 11 20:17:33 2002 +0000 - - Write src/pokey/Makefile - -commit c351b9e25b9f7b168a47fd8e6b60c66377e1824c -Author: Ivo Timmermans -Date: Thu Apr 11 14:27:35 2002 +0000 - - Pokey interface definition - -commit 17b308f0f0879c01f6864265af2e63595e965993 -Author: Ivo Timmermans -Date: Thu Apr 11 14:23:56 2002 +0000 - - Main pokey interface files. - -commit b5b38381c643632aa88c677236cace8c60e8344e -Author: Ivo Timmermans -Date: Tue Apr 9 16:11:48 2002 +0000 - - Last bits (hopefully) - -commit 77dd7b55801a3c7c2c6221664204ffdd7b83836a -Author: Ivo Timmermans -Date: Tue Apr 9 15:51:26 2002 +0000 - - More... - -commit 58c1df4028429ed6de4dad9455e3c92928450ffe -Author: Ivo Timmermans -Date: Tue Apr 9 15:48:54 2002 +0000 - - More updates - -commit 86dc60b9808d3aac70eccda80607a91ffd2e5292 -Author: Ivo Timmermans -Date: Tue Apr 9 15:32:14 2002 +0000 - - Ok, I forgot these ;) - -commit af23dfa5efb82b35eb00b94bda56390c9e2aac6f -Author: Ivo Timmermans -Date: Tue Apr 9 15:28:45 2002 +0000 - - Updating HEAD branch #5; Last files from CABAL. - -commit 462ab530e546f5732dfd51134751da6f6910d679 -Author: Ivo Timmermans -Date: Tue Apr 9 15:26:01 2002 +0000 - - Updating HEAD branch #4; Merging CABAL -> HEAD. - -commit e64ef59df44d39c76c00dee22841bbcce7c24e47 -Author: Ivo Timmermans -Date: Tue Apr 9 15:07:27 2002 +0000 - - Updating HEAD branch #3; more obsolete files removed. - -commit db59cbfa47aa152bcfa807754189aa18f28cb569 -Author: Ivo Timmermans -Date: Tue Apr 9 14:58:14 2002 +0000 - - Updating HEAD branch #2; removing debian/ dir. - -commit 50f2afec7e6dab3d809fc1b82820d1069205b69b -Author: Ivo Timmermans -Date: Tue Apr 9 14:54:37 2002 +0000 - - Updating HEAD branch #1; removing obsolete files. - -commit e69d2258032362c85c5936a5c137c70227e59332 -Author: Guus Sliepen -Date: Tue Apr 9 11:44:47 2002 +0000 - - Remarks about 1.0pre7 release. - -commit f2a3fcbdda250e5982c3ef36808568f996f8fff1 -Author: Guus Sliepen -Date: Tue Apr 9 11:43:45 2002 +0000 - - Updated dutch translation. - -commit b1322d244ff24e900f2298b8aa775d825c8ab00b -Author: Guus Sliepen -Date: Tue Apr 9 11:43:29 2002 +0000 - - masklength is better known as prefixlength - -commit 5df8a8cb3f4a0d2290f6677b44bbcaaf27a60bbc -Author: Guus Sliepen -Date: Tue Apr 9 11:42:48 2002 +0000 - - masklength is better known as prefixlength. - -commit 630dd023b990e076fdab890ff90783dc1ac7c13f -Author: Guus Sliepen -Date: Mon Apr 8 13:27:09 2002 +0000 - - Automake forgets about depcomp, remind it. - -commit ad6b1203490699ecc708290b2af1a45e134a5e20 -Author: Guus Sliepen -Date: Fri Apr 5 09:11:38 2002 +0000 - - Fix maskcheck() and maskcmp(). - -commit d8c249008a0b2abd44e652ed70e69b3dbc05b9d8 -Author: Guus Sliepen -Date: Mon Apr 1 21:28:39 2002 +0000 - - check_rsa() is broken, I don't know why, just remove it for now. - -commit 438419734ebee38dc3f7390e5c8ae8e6ca2cb6cf -Author: Guus Sliepen -Date: Mon Apr 1 21:28:05 2002 +0000 - - Don't check_network_activity() if select() is interrupted by a signal. - -commit 3d8a373bb3a788efffc555122b9d0569b96c5944 -Author: Guus Sliepen -Date: Wed Mar 27 19:43:50 2002 +0000 - - Make configure --help output look nicer. - -commit 9a03e7fa3d52ea062b4a3ff88b5d87ee95d24772 -Author: Guus Sliepen -Date: Wed Mar 27 16:26:26 2002 +0000 - - Update with information about the pre6 release. - -commit 33d3bad87d5f3e00e3ed81b75bca2ef21fd6e983 -Author: Guus Sliepen -Date: Wed Mar 27 16:00:49 2002 +0000 - - Update dutch translation. - -commit 0fe3dc38ed0527a5cfda9218114c8ee10422086b -Author: Guus Sliepen -Date: Wed Mar 27 16:00:38 2002 +0000 - - Fix format strings. - -commit 420f46acb0551a290b3263e39347b694286b2fa4 -Author: Guus Sliepen -Date: Wed Mar 27 15:47:06 2002 +0000 - - Remove symlink to device.c when doing a make dist. - -commit a5d8be8b1a9978d58c251d1020bb730bb1dc8ea1 -Author: Guus Sliepen -Date: Wed Mar 27 15:35:07 2002 +0000 - - Recent automake uses $(AMTAR) instead of $(TAR) - -commit c6d2f6c620beae387e8f9fc995ed7c8e8a5bc3dc -Author: Guus Sliepen -Date: Wed Mar 27 15:26:44 2002 +0000 - - Remove cruft. - -commit efd29fde85481e080a676f2ba780a528a90a9925 -Author: Guus Sliepen -Date: Wed Mar 27 15:26:29 2002 +0000 - - Small updates. - -commit 5eba1e1f6feadb3f7efb1261bd65e1e9e40b7f2b -Author: Guus Sliepen -Date: Wed Mar 27 15:01:37 2002 +0000 - - Limit the amount of packets in a queue to 8. - -commit 61cb593e670107ca3041f582c5486c243d5eda9e -Author: Guus Sliepen -Date: Wed Mar 27 15:01:16 2002 +0000 - - Extend list_t with the number of elements in the list. - -commit 0e7136027ce05bfeca977f2f64f3b228ea4fda87 -Author: Guus Sliepen -Date: Wed Mar 27 14:02:36 2002 +0000 - - Merge do_prune() with build_fdset(). Probably fixes the invalid filedescriptor error. - -commit e2238047d39eacc69da5732937021c38171ec7b9 -Author: Guus Sliepen -Date: Tue Mar 26 13:19:56 2002 +0000 - - Small correction. - -commit 7d07df71f9b82afdcf23494867bb8899198a6223 -Author: Guus Sliepen -Date: Tue Mar 26 12:00:38 2002 +0000 - - Fix execute_script(). - -commit 2de5e0eef911b9ff723d562ef9c62d833f3cdc45 -Author: Guus Sliepen -Date: Mon Mar 25 15:51:58 2002 +0000 - - Send REQ_KEY only once until ANS_KEY has arrived. - -commit a0c1696515fabd2183da7d8d83fd68410d2ec834 -Author: Guus Sliepen -Date: Mon Mar 25 15:12:09 2002 +0000 - - Tell a little bit more about security. - -commit 89a2f761a6d8ae4912c2dd2e9178589001487ef5 -Author: Guus Sliepen -Date: Mon Mar 25 15:01:32 2002 +0000 - - Updated documentation. - -commit 33d8747021d57c5827c6a755739756f95c7527c8 -Author: Guus Sliepen -Date: Mon Mar 25 13:54:49 2002 +0000 - - Set myself->status.reachable. - -commit 2749b997df33749f13d05e294db0e1e327e81d12 -Author: Guus Sliepen -Date: Sun Mar 24 17:14:01 2002 +0000 - - Configuration variables were still handled case sensitively. - -commit c73bdd6bc8e213b7e27848b97307228c01570a1d -Author: Guus Sliepen -Date: Sun Mar 24 17:08:38 2002 +0000 - - OpenBSD tun device uses address family number instead of Ethernet type. - -commit 8379c14b7f7a9b1400dd3776fc21dc9ccddd991d -Author: Guus Sliepen -Date: Sun Mar 24 16:50:58 2002 +0000 - - Respect type field. - -commit ad4f5cbc5fbce23893b7d42669ba907f18cc8ff4 -Author: Guus Sliepen -Date: Sun Mar 24 16:40:14 2002 +0000 - - Updated dutch translation. - -commit 4252ae83a43ea81382ce71ba614e2d1655f2e189 -Author: Guus Sliepen -Date: Sun Mar 24 16:36:56 2002 +0000 - - Set $INTERFACE correctly when using ethertap while compiled with tun/tap support. - -commit d699f3079c658e05f928c358d110d1d27849ea71 -Author: Guus Sliepen -Date: Sun Mar 24 16:28:27 2002 +0000 - - Execute hosts/name-up when a node becomes reachable, and hosts/name-down - when it becomes unreachable. - -commit 6ad5dd1a9adb1c1322ceb44d6f0fd160229e72ff -Author: Guus Sliepen -Date: Sun Mar 24 16:22:59 2002 +0000 - - Don't try to execute scripts unless they exist. - -commit 594d5b5d15551bd802c43926c7cb8863b7531654 -Author: Guus Sliepen -Date: Sat Mar 23 20:21:10 2002 +0000 - - Reset retry timeout when receiving the first PONG, not right after receiving the ACK. - -commit cbd8133ab4a2ea8a0c46224a5f1ae79e92819e5f -Author: Guus Sliepen -Date: Sat Mar 23 20:13:56 2002 +0000 - - Don't run graph algorithms if no edge is deleted in terminate_connection(). - -commit 6aee1ad021092d37538e15da22367789a4d4a763 -Author: Guus Sliepen -Date: Sat Mar 23 20:12:29 2002 +0000 - - free() request strings when deleting past requests from the tree. - -commit ccea26e0044ea59a9722385c9d69b1bc703e884f -Author: Guus Sliepen -Date: Sat Mar 23 20:01:05 2002 +0000 - - send_ack() was broken. - -commit 3c5655f59e85d312d11fa04489123e604920f95b -Author: Guus Sliepen -Date: Fri Mar 22 13:31:18 2002 +0000 - - Fix compiler warnings, strictly use long int and %lx for options. - -commit d6b70ed6f8b7ed65f64193fcfcdb6c8f4625e03c -Author: Guus Sliepen -Date: Fri Mar 22 12:41:54 2002 +0000 - - Fix add_edge_h(). - -commit 52e7699273a3009fe4d91e608522401076922785 -Author: Guus Sliepen -Date: Fri Mar 22 11:43:48 2002 +0000 - - - Added support for jumbograms. - - Remove tcpaddress from edges, it is not used at all. - - Last bits of code to prevent looping requests. - -commit 9da5390666ad532825d820b3554da3f39d3bc511 -Author: Guus Sliepen -Date: Thu Mar 21 23:11:53 2002 +0000 - - Put a break on requests that run around in circles. - -commit f48f8f4fedba365ceea30e1133bf1c560e9a522a -Author: Guus Sliepen -Date: Tue Mar 19 22:48:25 2002 +0000 - - Updated SSSP algorithm to automatically detect indirect links (if a node uses - different addresses for connections to other nodes). - -commit 5a88a27742d305be48498a297b90ee3fbdd935bf -Author: Guus Sliepen -Date: Tue Mar 19 00:08:34 2002 +0000 - - Updated dutch translation. - -commit 5c2d74de86d1acb3774a20357ad815d000f8a7f6 -Author: Guus Sliepen -Date: Tue Mar 19 00:08:23 2002 +0000 - - Don't use s6_addr[16|32] anymore. - -commit 9d99a789c38e8a1694537e427e8d4313c948b02b -Author: Guus Sliepen -Date: Tue Mar 19 00:07:09 2002 +0000 - - Cleanup. - -commit 305505f5ec4bb738f175cd897fa409f08d2971a3 -Author: Guus Sliepen -Date: Mon Mar 18 22:47:20 2002 +0000 - - Remember sockaddrs of listening sockets, use appropriate one when sending - UDP packets. - -commit 106fc2b769a635142bf5f9233a2f03e3a0f26b7f -Author: Guus Sliepen -Date: Mon Mar 18 14:39:37 2002 +0000 - - Fix #define s6_addr32. - -commit 813c369a8faca94fc38bc66afafad063fa00f928 -Author: Guus Sliepen -Date: Mon Mar 18 14:19:02 2002 +0000 - - #define s6_addr32, needed for FreeBSD. - -commit b2579385de427c3c03d28520d3a93bd5f9bc9488 -Author: Guus Sliepen -Date: Sun Mar 17 16:08:39 2002 +0000 - - Only unmap IPv6 addresses. - -commit 8b84c44175fedb81ca38107e0067ddea750add00 -Author: Guus Sliepen -Date: Sun Mar 17 15:59:29 2002 +0000 - - Unmap v4mapped sockaddrs. - -commit 07e37f8da03fa315be39623e62d8acba617aa226 -Author: Guus Sliepen -Date: Fri Mar 15 15:50:14 2002 +0000 - - Typo. - -commit e0dee537705cdbd005f6ab1fbef5ac71dc8411c0 -Author: Guus Sliepen -Date: Fri Mar 15 15:40:40 2002 +0000 - - Different way of detecting neighbor solicitation requests. - -commit 0e93f0aa02274481c16fc9f30b795d4f063bd1c3 -Author: Guus Sliepen -Date: Fri Mar 15 15:08:21 2002 +0000 - - Oops, don't forget to actually put the checksum in the response packet. - -commit e1de9ca990ea638c7e297c5335be415e44c250c1 -Author: Guus Sliepen -Date: Fri Mar 15 14:41:57 2002 +0000 - - Neighbor solicitation requests now work (I think). - -commit 4b3aef9e6992ca78f1b17b179a3051d3fec0473d -Author: Guus Sliepen -Date: Tue Mar 12 16:30:15 2002 +0000 - - Revert changes to Kruskal's algo. - -commit f219f156cf13fd30369d7cd4632c406ffd6ff628 -Author: Guus Sliepen -Date: Tue Mar 12 14:25:04 2002 +0000 - - Put #ifdef NEIGHBORSOL around corresponding code. - -commit ecad9e9289162faec7b678be54178d22876b5d90 -Author: Guus Sliepen -Date: Tue Mar 12 14:20:44 2002 +0000 - - Remove silly cache thingy. - -commit d6c2c4f2b7a94ef6a4db0de134d015bc8d21ffb1 -Author: Guus Sliepen -Date: Tue Mar 12 14:19:51 2002 +0000 - - Packet sequence number/authentication warnings only if debug_lvl >= 5. - -commit 2e7db2a6936a77baa0a81eb566674bd76d204951 -Author: Guus Sliepen -Date: Tue Mar 12 13:42:23 2002 +0000 - - Simplified implementation of Kruskal's minimum spanning tree algorithm. - -commit d2e0ed533c8aa3c6ab538d87e004108c631cb0be -Author: Guus Sliepen -Date: Mon Mar 11 13:56:00 2002 +0000 - - New strategy: forward icmp6 neighbor solicitations to intended target. - -commit 46fa10cec7b6bf26773f5e86e7b8118d9075e807 -Author: Guus Sliepen -Date: Mon Mar 11 13:14:53 2002 +0000 - - Try to reply to neighbor solicitation requests. - -commit c2713ba7a5ff12e270d66a5d3188a3640873830e -Author: Guus Sliepen -Date: Mon Mar 11 11:45:12 2002 +0000 - - prune_connections() before build_fdset(). - -commit 4fda4560bbdd41e217ce0e1a90ba98c79e4f3519 -Author: Guus Sliepen -Date: Mon Mar 11 11:23:04 2002 +0000 - - Cleanups, spelling fixes, allow symbol names for signals (-k option), - don't remove pidfile if other tincd is still running. - -commit 5ffeb13d65313d5a191a605690a4f8fdf1604b48 -Author: Guus Sliepen -Date: Sun Mar 10 16:09:15 2002 +0000 - - Don't retry to make outgoing connections when exitting. - -commit 3cbe67a8de1da7bd042474de4d16cb4f7e9822ab -Author: Guus Sliepen -Date: Sun Mar 10 15:40:27 2002 +0000 - - Small fixes to improve portability. - -commit 9de7470bfdabacec5f3769bf5cfa97ef4e481ba0 -Author: Guus Sliepen -Date: Sun Mar 10 14:07:08 2002 +0000 - - Autodetect $MAKE/gmake/make. - -commit 0c34478cc03167208c84f3d6d2ed6e53172b4711 -Author: Guus Sliepen -Date: Sun Mar 10 14:05:35 2002 +0000 - - po/POTFILES and po/Makefile should not be generated by configure. - -commit 024ab44d98883d78cefe2c622cec9831c7f19c13 -Author: Guus Sliepen -Date: Sun Mar 10 14:04:48 2002 +0000 - - Fix forwarding of IPv6 packets. - -commit 0c16add71c6432c882c6d8f538a4b2db0026ec24 -Author: Guus Sliepen -Date: Fri Mar 1 15:14:29 2002 +0000 - - Check if BindToDevice and PriorityInheritance are supported. - -commit 7d5741859e681e6b0d0e32b978da6f309c456729 -Author: Guus Sliepen -Date: Fri Mar 1 14:33:48 2002 +0000 - - Woops. - -commit ab90fa9bd1a653a330be7ef11293000721a0e7b4 -Author: Guus Sliepen -Date: Fri Mar 1 14:25:10 2002 +0000 - - Document and clean up MAC address expiry. - -commit 14979f835df4214a7c2510852f7ffedc9e08c2c0 -Author: Guus Sliepen -Date: Fri Mar 1 14:09:31 2002 +0000 - - - Global time_t now, so that we don't have to call time() too often. - - MAC addresses expire after a time configurable by MACExpire (default 600 - seconds) - -commit 7496ecc45ab6205bcce4e576c23b9afb52004e39 -Author: Guus Sliepen -Date: Fri Mar 1 13:38:15 2002 +0000 - - Updated dutch translation. - -commit 0c879b8eeed3477b0f1cdd2f232e67e38bd9bce6 -Author: Guus Sliepen -Date: Fri Mar 1 13:38:02 2002 +0000 - - Updated documentation. - -commit f93b1334e087dd7af1b87f475b2d398fdd4d56ab -Author: Guus Sliepen -Date: Fri Mar 1 13:18:54 2002 +0000 - - Create/bind TCP and UDP listening sockets in pairs. - -commit c2b738e7b51fbec2b11fbbf030b9a5a36df55fc4 -Author: Guus Sliepen -Date: Fri Mar 1 12:26:56 2002 +0000 - - If "PriorityInheritance = yes" is specified in tinc.conf, the value of the - TOS field of the tunneled packets will be passed on to the UDP packets tinc - sends out. - -commit 80ea653e8d8050878380fbc1446571cbaf578297 -Author: Guus Sliepen -Date: Fri Mar 1 12:25:58 2002 +0000 - - Fix listening sockets. - -commit 7f58ed7685f9fcd5271359a8c896670a835e1f95 -Author: Guus Sliepen -Date: Fri Mar 1 11:18:34 2002 +0000 - - Make BindToInterface work. - -commit 17bc5220c332fdd083fd47fc600010f85171adc7 -Author: Guus Sliepen -Date: Wed Feb 27 22:37:55 2002 +0000 - - Fix send_request() bug. - -commit 50403909b6bf6536924d4693bb1f32c248f17fda -Author: Guus Sliepen -Date: Tue Feb 26 23:26:41 2002 +0000 - - Allow multiple listening sockets. - -commit 2ac7be0d51a112108dc6c2b1c6f46da022f72f40 -Author: Guus Sliepen -Date: Tue Feb 26 22:47:51 2002 +0000 - - Tweaking IPv6 support. - -commit 23fda5688e8a109f8a50511538b14e4fbe4f738c -Author: Guus Sliepen -Date: Wed Feb 20 22:37:38 2002 +0000 - - - Change SA_LEN to SALEN, former one is already defined on some platforms. - - Use SALEN everywhere appropriate. - -commit dbc5b5bb5eb3096ad930aa6b590deaba2a103dfc -Author: Guus Sliepen -Date: Wed Feb 20 22:15:32 2002 +0000 - - - Use gai_strerror() where appropriate - - Clear hints before using them with getaddrinfo() - - Use sa_len on platforms that support them - -commit 28cc9a6488f78c72152251f6fa2ee84d417223e8 -Author: Guus Sliepen -Date: Wed Feb 20 19:31:15 2002 +0000 - - Preserve inpkt->len, needed for broadcasts. - -commit c6d01588312bec7691e72b42cf20c59ffe2749c2 -Author: Guus Sliepen -Date: Wed Feb 20 19:25:09 2002 +0000 - - Protocol now also exchanges cipher/digest/maclength/compression for the - meta connection. - -commit 626d5956d2bb0660ba315fba77da6cec9776fd3b -Author: Guus Sliepen -Date: Wed Feb 20 17:16:15 2002 +0000 - - Cache results of lookup_subnet_...(). - -commit e8e69460a7090aaf6ecda8970d3060695de81b00 -Author: Guus Sliepen -Date: Wed Feb 20 17:15:33 2002 +0000 - - Fix maskcmp() and maskcpy(). - -commit ed509312906625acee4007da6262de3898846888 -Author: Guus Sliepen -Date: Wed Feb 20 16:04:59 2002 +0000 - - Forward packets in router mode. - -commit 8c91fac31570594b6249d632cefe768f33c54b19 -Author: Guus Sliepen -Date: Wed Feb 20 16:04:39 2002 +0000 - - Use AF_UNSPEC for listening sockets if AddressFamily = any. - -commit 76f01453dfa157b0070751b1025e55a1e36ebdca -Author: Guus Sliepen -Date: Wed Feb 20 16:04:07 2002 +0000 - - Fix segfault when receiving HUP signal. - -commit c2b9c06062d36bde859b630b99a08c7b7428e721 -Author: Guus Sliepen -Date: Mon Feb 18 16:25:19 2002 +0000 - - - Non-blocking connect()s. - - Socket handling revamped to use sockaddr_t. - - tinc can now tunnel over IPv6. - - Handle all addresses and subnets in network byte order. - Only convert them when they need to be printed. - - IPv6 subnets bigger than /128 now work. - - Use %s and strerror(errno) instead of %m. - -commit fc674eaae14ed2e07abc0df1285b1bd70e0d27cc -Author: Guus Sliepen -Date: Tue Feb 12 14:42:37 2002 +0000 - - Add check for NetBSD. - -commit 2fb8a62edef7cb0988e44f92c3948cde6f34875e -Author: Guus Sliepen -Date: Tue Feb 12 14:40:12 2002 +0000 - - Added device.c for NetBSD, actually a copy of the OpenBSD one. - -commit f64b41a73b3b432aae17ba990414e0be2f61ce62 -Author: Guus Sliepen -Date: Tue Feb 12 14:36:45 2002 +0000 - - Get rid of sys/signal.h. - -commit dd611fb4f91b9b17c20c458694d2765b22814c5f -Author: Guus Sliepen -Date: Tue Feb 12 14:29:00 2002 +0000 - - Don't use sa_sigaction (which NetBSD doesn't like) at all if we don't use siginfo. - -commit d9a62c6354d1e2ad78ee8c610518ae9f9ab012d1 -Author: Guus Sliepen -Date: Mon Feb 11 15:59:18 2002 +0000 - - Added support for packet compression, thanks to Mark Glines. - Add "Compression = " to the host config files, where level can be - 0 (off), or any integer between 1 (fast) and 9 (best). - -commit 94b171b3051b999e619ae19e1c9c29d356606788 -Author: Guus Sliepen -Date: Mon Feb 11 14:20:46 2002 +0000 - - Small fix. - -commit 1708997bc8ab55122f9de9cc8b81397d3a003ea9 -Author: Guus Sliepen -Date: Mon Feb 11 14:20:21 2002 +0000 - - - If no PrivateKeyFile is specified, /etc/tinc/netname/rsa_key.priv is assumed. - - Check RSA key before using it. - -commit 1c34ba7fb8580949f3bd3a0d804747bbaea28e36 -Author: Guus Sliepen -Date: Mon Feb 11 12:33:01 2002 +0000 - - Sensible defaults for $INTERFACE. - -commit 24cc2a9065a4e962fb05addac47322930099a4b5 -Author: Guus Sliepen -Date: Mon Feb 11 10:16:18 2002 +0000 - - Last bits of the merger. - -commit 5bf4b88666ecafe190e8ed71d6c14c9de8d16e1f -Author: Guus Sliepen -Date: Mon Feb 11 10:05:58 2002 +0000 - - Forgot to merge new files from pre5. - -commit f0aa9641e82fb6e09c1e485366d14dddaa7f7c36 -Author: Guus Sliepen -Date: Sun Feb 10 21:57:54 2002 +0000 - - Merging of the entire pre5 branch. - -commit c2752b961c9262386b940c2c053b9909bee22859 -Author: Ivo Timmermans -Date: Fri Nov 16 22:41:38 2001 +0000 - - Conversion to struct addrinfo is almost complete for this file. - -commit 4f47da5b87ef7da608c7e44026122f3d95deb2eb -Author: Ivo Timmermans -Date: Fri Nov 16 22:40:26 2001 +0000 - - Don't include netutl.h. - -commit a59bbc72317c9cd97243a9cbf49db01ff249eb1e -Author: Ivo Timmermans -Date: Fri Nov 16 22:31:41 2001 +0000 - - Fixed silly typo: "np" instead of "no" - -commit bf664c054fdabc30679367a752a27bb769655e4d -Author: Ivo Timmermans -Date: Fri Nov 16 22:31:15 2001 +0000 - - get_config_subnet needs to be fixed. - -commit 9b2b3747340173590b8f6f5fbdd060b42985f026 -Author: Ivo Timmermans -Date: Fri Nov 16 17:40:50 2001 +0000 - - route_ipv4 and route_ipv6 replaced by route_ip. - -commit a4938b22e7502579ce44cac42410111db11256eb -Author: Ivo Timmermans -Date: Fri Nov 16 17:39:59 2001 +0000 - - Don't include netutl.h. - -commit ccda709f8243949a3c0ffcc6133d8d8fc5125f2e -Author: Ivo Timmermans -Date: Fri Nov 16 17:39:38 2001 +0000 - - lookup_node_udp changed. - -commit 836766d4c5bc47682ab69c57337157c879517670 -Author: Ivo Timmermans -Date: Fri Nov 16 17:38:39 2001 +0000 - - First part of rewriting things to use struct addrinfo. - -commit 2ec5b5f8621d9fb91181ab155084daa1bb2d1a54 -Author: Ivo Timmermans -Date: Fri Nov 16 17:37:08 2001 +0000 - - Added dropin replacements for get*info and helper functions. - -commit aabe59f6305cdd46220e95d8927a1636d4b4819d -Author: Ivo Timmermans -Date: Fri Nov 16 16:16:33 2001 +0000 - - Added HAVE_STRUCT_ADDRINFO - -commit 251f87c842b62cf770129d8a953fb06ef5d0e466 -Author: Ivo Timmermans -Date: Fri Nov 16 15:56:44 2001 +0000 - - (re)added port to struct node_t - -commit 6cf744e4b29cfe3b135b6553851816802ba3d8a8 -Author: Ivo Timmermans -Date: Fri Nov 16 12:22:02 2001 +0000 - - Don't include netutl.h. - -commit a79252af4383b8cd71cf0d13f1ae040d518517bf -Author: Ivo Timmermans -Date: Fri Nov 16 12:21:22 2001 +0000 - - Obsoleted. - -commit 331d9402e892b4baa9cadbbb364073ae10b58d99 -Author: Ivo Timmermans -Date: Fri Nov 16 12:16:28 2001 +0000 - - Don't compile/link netutl.c. - -commit f95e6ca8f6976d7a15f4623e25c85e1c7f82c04b -Author: Ivo Timmermans -Date: Fri Nov 16 12:14:20 2001 +0000 - - get_config_{ip,port} removed. - -commit 31db57bb4a00f5ca3743b89f8bb2fbd39919bf28 -Author: Ivo Timmermans -Date: Fri Nov 16 12:13:34 2001 +0000 - - Changed to use struct addrinfo where needed. - -commit f1b20b3ded5b360e426e094cf79df3bf97f350b4 -Author: Ivo Timmermans -Date: Fri Nov 16 12:10:54 2001 +0000 - - Obsoleted all IP types in favor of struct addrinfo - -commit fb6dc0b0890ebae2471e00e7a3e1d86c1fc3d646 -Author: Ivo Timmermans -Date: Fri Nov 16 12:08:38 2001 +0000 - - Removed definitions of ipv4_t, ipv6_t, port_t - -commit 3ef15f2554d1819d6c7d2573dac6039f2e76b638 -Author: Ivo Timmermans -Date: Fri Nov 16 12:02:17 2001 +0000 - - Changed lookup_connection to use struct addrinfo - -commit 74e1299fb58025f7506c7e2608c353a76f98d8df -Author: Ivo Timmermans -Date: Fri Nov 16 12:01:48 2001 +0000 - - Changed prototype for lookup_connection to use struct addrinfo - -commit 51b72b75f254c956b62be9dfca642145b199415f -Author: Ivo Timmermans -Date: Fri Nov 16 00:23:28 2001 +0000 - - Use struct addrinfo in connection_t to hold all host data such as IP - address and port - -commit 72395f989cb44132d7c756c91b3a6d8ba63517e5 -Author: Ivo Timmermans -Date: Fri Nov 16 00:13:08 2001 +0000 - - Deprecated get_config_ip and get_config_port - -commit 93cd0e33defba46f8e51d9a98a94599ceb0d521c -Author: Ivo Timmermans -Date: Thu Nov 15 23:49:46 2001 +0000 - - Check for struct addrinfo - -commit b16bf68a6dc27b364cb76156a7be0208594f1e94 -Author: Ivo Timmermans -Date: Thu Nov 15 23:28:58 2001 +0000 - - Credit OpenSSH - -commit 18269cfbe831902b97a6171ba0346fd323583e48 -Author: Ivo Timmermans -Date: Thu Nov 15 23:26:27 2001 +0000 - - Check for getnameinfo, gai_strerror, freeaddrinfo - -commit ae11e7c3d71893c5200b12682839538a52df37b8 -Author: Ivo Timmermans -Date: Thu Nov 15 23:05:34 2001 +0000 - - Check for getaddrinfo - -commit e06415e3d9d08cd33c5983a2c49c4101377160c2 -Author: Guus Sliepen -Date: Mon Nov 5 19:09:08 2001 +0000 - - More fixes for Solaris. - -commit 25a804c94ef0dbc4e5582ea6d8459d5f9a3fe06c -Author: Guus Sliepen -Date: Mon Nov 5 19:06:07 2001 +0000 - - Various fixes needed for Solaris. - -commit b2d5002ff1ccd44fbf3a94e4c41909ab6141f3bb -Author: Guus Sliepen -Date: Sun Nov 4 23:48:27 2001 +0000 - - Correctly check if subnet owner exists. - -commit ede6671c1354eeab86936efda32f6cdb3b3fd8d5 -Author: Guus Sliepen -Date: Sun Nov 4 23:29:50 2001 +0000 - - Be liberal in what you accept: allow unknown edges to be deleted. - -commit cf0e133e191cb40954bf5b6ee0a579442fe4b60b -Author: Guus Sliepen -Date: Sat Nov 3 22:53:02 2001 +0000 - - *** empty log message *** - -commit e5047d2835f0828a9c334cc3d928c2322abfefb7 -Author: Guus Sliepen -Date: Sat Nov 3 21:22:02 2001 +0000 - - Several bugfixes. - -commit 8910cbd67e13450e93816ecafa0cc5be5e4c2378 -Author: Guus Sliepen -Date: Sat Nov 3 21:21:04 2001 +0000 - - Use PEM functions as suggested by OpenSSL docs. - -commit 8e74c5bee48f2ef363193044d5309a65e91c70d8 -Author: Guus Sliepen -Date: Wed Oct 31 20:37:54 2001 +0000 - - Some very small fixes - -commit ffb88ff6410f33de92db108bd1e0c3a915368214 -Author: Guus Sliepen -Date: Wed Oct 31 20:22:52 2001 +0000 - - Avoid connecting to another node twice, and check name of outgoing connections. - -commit 6d333ad680465c26953ad4c8ca9140e27da868c5 -Author: Guus Sliepen -Date: Wed Oct 31 20:07:17 2001 +0000 - - Show cfg->variable instead of cfg->value when complaining about wrong type. - -commit 54b756f7dfb71c5622b7738fd449e126da959864 -Author: Guus Sliepen -Date: Wed Oct 31 20:02:06 2001 +0000 - - Don't forget to read public RSA key when making an outgoing connection. - -commit c0a3f67a5d66088aaf526f1461986f9e86d5dd1f -Author: Guus Sliepen -Date: Wed Oct 31 12:50:24 2001 +0000 - - - Small fixes to graph algorithms - - More control over tap device, ability to set interface name to something - other than the netname. - - Export NETNAME, DEVICE and INTERFACE environment variables to scripts. - -commit 2165931c62f0433fd97bd3ac6aefea3627218946 -Author: Guus Sliepen -Date: Tue Oct 30 16:34:32 2001 +0000 - - More updates to protocol handlers and reimplemented terminate_connection(). - -commit 87ad5c97a9a73a65050ad7adce34503f856d8665 -Author: Guus Sliepen -Date: Tue Oct 30 12:59:12 2001 +0000 - - Various fixes, tinc is now somewhat capable of actually working again. - -commit cc9473d8c6467e9eaa82fe8a639d8edba232ee76 -Author: Guus Sliepen -Date: Mon Oct 29 13:14:57 2001 +0000 - - Working version of Kruskal's algorithm. The running time is very bad though. - -commit b6298e2c082035b8238ea08673ced15d0fb7b89a -Author: Guus Sliepen -Date: Sun Oct 28 22:42:49 2001 +0000 - - - More changes needed for Kruskal's algorithm - - Implemented a breadth-first search algorithm as a cheap substitution for a - single-source shortest path algorithm. - -commit 66067cc9c1347fb2de35660d531fdd4be8aede6a -Author: Guus Sliepen -Date: Sun Oct 28 10:16:18 2001 +0000 - - - More s/vertex/edge/g - - Implementation of Kruskal's minimum spanning tree algorithm. - -commit 94497336efc1cc60561575e74d420e9e8e8c657e -Author: Guus Sliepen -Date: Sun Oct 28 08:41:19 2001 +0000 - - What was I thinking? s/vertex/edge/g. - -commit b98d9787fdde54f33dcdb376e1e018cd418aff8d -Author: Guus Sliepen -Date: Sat Oct 27 15:19:13 2001 +0000 - - Various small fixes to make tinc runnable again. - -commit ac066bb057dcb187bf91670793ba5e6ca456e052 -Author: Guus Sliepen -Date: Sat Oct 27 13:13:35 2001 +0000 - - Make sure everything links. - -commit 82e383710980534d38bb9a8ef22f20677cd85861 -Author: Guus Sliepen -Date: Sat Oct 27 12:13:17 2001 +0000 - - Big bad commit: - - Transition to new node/vertex/connection structures - - Use new configuration handling everywhere - - Linux tun/tap device handling cleanup - - Start of IPv6 support in route.c - - It compiles, but it won't link. - -commit 1935c44a1e8ab7c31c836f90215e3c5b5f8dd776 -Author: Guus Sliepen -Date: Sat Oct 13 13:53:07 2001 +0000 - - Support new files (node/vertex/device.[ch]) and OpenBSD. - -commit 26e517dd37e995fe9db518f7ebeff023fc73ff1b -Author: Guus Sliepen -Date: Fri Oct 12 15:52:03 2001 +0000 - - Forgot the tun specific stuff. - -commit ad61c20f42d2bee5cc7976bec4370cf4747b42c3 -Author: Guus Sliepen -Date: Fri Oct 12 15:49:11 2001 +0000 - - Added OpenBSD tun device handling. Untested though. - -commit 0c6321a67f92981d3adbaf4f5c2b9867c7968964 -Author: Guus Sliepen -Date: Fri Oct 12 15:38:35 2001 +0000 - - Forgot to remove some old #ifdef stuff. - -commit 6014c7e6374089bfccea7467c2c7f4b23fefa265 -Author: Guus Sliepen -Date: Fri Oct 12 15:33:21 2001 +0000 - - Solaris tun device handling cleaned up a bit and added. - -commit 623c7ee0308aede8eada552d6ae33710ae24d176 -Author: Guus Sliepen -Date: Fri Oct 12 15:22:59 2001 +0000 - - Added FreeBSD tap device handling. - -commit ec34f25228d7a0007ce6bcb1e97f263868e9129d -Author: Guus Sliepen -Date: Fri Oct 12 15:16:03 2001 +0000 - - - Split tap device stuff out of net.[ch] - - Each OS gets it's own device.c to get rid of evil #ifdefs. - - Cleaned up Linux ethertap and tun/tap handling. - -commit 0bbace18e96cd6fc32dfa23ffd55f73ff96e8c6f -Author: Guus Sliepen -Date: Wed Oct 10 20:35:10 2001 +0000 - - More updates to new node/vertex/connection combo. - -commit ea607d2d9292d3969f9d164b432dc64a33c2dade -Author: Guus Sliepen -Date: Wed Oct 10 20:34:27 2001 +0000 - - Revamp configuration handling: - - Store everything in AVL trees (fast lookup) - - No need for hazahaza anymore - - Parse values when needed - - This simplifies a lot of config variable lookups. - -commit 5904806dc80830d4eddca857a41db2fc25598201 -Author: Guus Sliepen -Date: Wed Oct 10 09:42:29 2001 +0000 - - Removed everything from connection.c that has already been moved to node.c and - vertex.c. - -commit ec0c16b9b63f361b11a757ee1641d562e4811f93 -Author: Guus Sliepen -Date: Wed Oct 10 08:49:47 2001 +0000 - - Further implementation of doc/CONNECTIVITY. connection.[ch] is now split into a - node, vertex and connection part. - -commit 75e1ae3a287642ca4281792c94ecd07332f39c08 -Author: Wessel Dankers -Date: Tue Oct 9 19:41:56 2001 +0000 - - make is not always GNU make. - -commit f22b9417510cca258785f8958c8dfed90e26d81b -Author: Guus Sliepen -Date: Tue Oct 9 19:37:10 2001 +0000 - - Small corrections. - -commit 49a2cd806c73cff1ab6a712a996c7f7d4e1f32c0 -Author: Guus Sliepen -Date: Tue Oct 9 19:30:30 2001 +0000 - - Started implementing doc/CONNECTIVITY. - -commit 5926c82b9a29031a8c619432869d1549b51b62a0 -Author: Guus Sliepen -Date: Mon Oct 8 15:47:30 2001 +0000 - - Updated dutch translation. - -commit fcc3ded75fe9f831aeb8678ee5e3926bf4168906 -Author: Guus Sliepen -Date: Mon Oct 8 15:37:14 2001 +0000 - - Fix bug when dropping an old connection in favour of a new one from the - same host. - -commit 1ef90a87fd9fd53c25a43455ffaac5274a63dc08 -Author: Guus Sliepen -Date: Mon Oct 8 13:37:30 2001 +0000 - - - Use ping timeout mechanism to close connections that don't authenticate - in time. - - Fix potential segmentation fault in check_dead_connections(). - -commit ce9fd32c04adf83cbaf668ee42a29575ba256002 -Author: Guus Sliepen -Date: Mon Oct 8 11:59:08 2001 +0000 - - Fix bug where tinc would crash because of a portscan or a connection from a - tinc daemon with a different version. - -commit 21027b1d5702c331b1ebb262bb149c75be1f24b1 -Author: Guus Sliepen -Date: Mon Oct 8 11:47:55 2001 +0000 - - - Renamed lastbutonehop to prevhop. - - Added connection_t *via to connection_t, this keeps record of where - to send UDP packets to. - -commit 18d1233c40a5705e9123edd6f4c6764a5178003b -Author: Guus Sliepen -Date: Tue Sep 25 13:39:11 2001 +0000 - - Fill in next- and lastbutonehop for myself. - -commit ec100a58b44e412a3d2606e5213af9ec5f30235b -Author: Guus Sliepen -Date: Tue Sep 25 13:35:45 2001 +0000 - - Try next connectto instead of the same over and over. - -commit 4d3de3b6a9b55bc783c649ff33e5415b0c7b5f25 -Author: Guus Sliepen -Date: Mon Sep 24 14:16:29 2001 +0000 - - Show next- and lastbutonehop when dumping connectionlist to syslog. - -commit 24a2c7e51a0b080c4bdb55f697b3f0458ebc3fb1 -Author: Guus Sliepen -Date: Mon Sep 24 14:12:00 2001 +0000 - - Not only keep track of nexthop, but also of lastbutonehop. If destination cl - wants indirectdata, send it to the lastbutonehop instead, unless it too has - requested so, and so on. - -commit 154733927af0b27cdadb83f03b845301ce8bfbfd -Author: Guus Sliepen -Date: Mon Sep 24 13:31:15 2001 +0000 - - - Try old TUN/TAP ioctl() request if the one from if_tun.h fails. - - Be more verbose about the kind of tap device used. - -commit 950c934e0bda28e5952d699d6008ee783d81982b -Author: Ivo Timmermans -Date: Wed Sep 5 18:38:09 2001 +0000 - - Killing tincd with SIGINT causes it to toggle between the current - debug level and level 5. Useful to debug a running tincd. - -commit a54ec980e047d13ecff7f1f337aa2665072febfd -Author: Guus Sliepen -Date: Sat Sep 1 12:46:49 2001 +0000 - - config_t* is a const parameter in get_config_val(). - -commit 68e23b1c9e69b2a218b3be821ad1ba3b3b6a64f2 -Author: Guus Sliepen -Date: Sat Sep 1 12:36:53 2001 +0000 - - Optional signal number for -k option. - -commit 8ed27d40f358581d021319cc26313c9f6ddf9a71 -Author: Guus Sliepen -Date: Sat Sep 1 12:36:06 2001 +0000 - - Revised reconnection mechanism, always try out all ConnectTo lines. - -commit ef1facc60709e9474197aa3fde9d517dfd96dc87 -Author: Guus Sliepen -Date: Sat Sep 1 12:02:39 2001 +0000 - - Remove IndirectData support for now, new implementation will be added - later. - -commit 8b5e4211304aaa5d39bc95f04398bd5ecaa887d8 -Author: Guus Sliepen -Date: Tue Aug 28 20:52:39 2001 +0000 - - Fix signed comparison bug in lookup_subnet_ipv4(). - -commit e1184ad15d6b2e7d58bdcb4489026dd0a35b4e5f -Author: Guus Sliepen -Date: Fri Aug 17 18:14:04 2001 +0000 - - Don't send DEL_HOSTs when !status.meta - -commit 30d22474ccc8da9a5685a90e0b2304ec627475af -Author: Guus Sliepen -Date: Tue Jul 24 20:14:30 2001 +0000 - - Explicitly log which type of tunnel device is used. - -commit 7e86cf91e3399905e19882bcf2d5677d7986aca5 -Author: Guus Sliepen -Date: Tue Jul 24 20:13:42 2001 +0000 - - The val variable in a config_t is never used as a long. - -commit 43923d2b106bfbe9300cc8e364cf098444cd649e -Author: Guus Sliepen -Date: Tue Jul 24 20:04:22 2001 +0000 - - Write public key to rsa_key.pub instead of rsa_key.priv (if not host - configuration file is found). - -commit 44e9d6a2872fac55f7eb701ba576ed9f39a22e08 -Author: Guus Sliepen -Date: Tue Jul 24 20:03:40 2001 +0000 - - Don't use %m in fprintf(). - -commit cbd03caece25d45015a4526b94b04a34ab87b0f2 -Author: Guus Sliepen -Date: Tue Jul 24 08:51:36 2001 +0000 - - More on edges. - -commit 3cd238f4e338f257ff61d58a9979b54344ee462f -Author: Guus Sliepen -Date: Mon Jul 23 22:06:22 2001 +0000 - - Discuss how sending ADD_EDGEs would be better than sending ADD_HOSTs. - -commit 5333cada0dfc4dfc3be728e6c78d8d42dc2ace52 -Author: Guus Sliepen -Date: Sun Jul 22 17:41:52 2001 +0000 - - Written down a possible solution. - -commit 995ab86fce506e9fabcf5a9ead7d43b30f12ab09 -Author: Guus Sliepen -Date: Sun Jul 22 15:25:13 2001 +0000 - - Correctie. - -commit d7b4de0e73baf664964f6daaf63526606b6a890b -Author: Guus Sliepen -Date: Sun Jul 22 14:58:18 2001 +0000 - - Small update. - -commit 71b9041f484128219f81cbf4f22a4e11388f879d -Author: Guus Sliepen -Date: Sun Jul 22 14:46:11 2001 +0000 - - Described problem in more detail. - -commit c1a98cd37ea20f6020487b2a5586e6de432398e7 -Author: Guus Sliepen -Date: Sun Jul 22 14:04:38 2001 +0000 - - Started writing a document about how daemons connect to each other. - -commit fcbe215d64d7e2f3b159fff6422d750417877ac4 -Author: Guus Sliepen -Date: Sat Jul 21 20:21:25 2001 +0000 - - Woohoo! tinc now compiles, runs and actually *works* on Solaris! - Tested on a SparcStation 20MP running Solaris 7. (Thanks, jiggel!) - -commit 533ee1206fb6433a1f0e616db999b3655addfaf2 -Author: Guus Sliepen -Date: Sat Jul 21 15:46:34 2001 +0000 - - Always close all sockets in terminate_connection(). - -commit acb853205d6d582d919c59879393b301ad4f4fde -Author: Guus Sliepen -Date: Sat Jul 21 15:34:18 2001 +0000 - - Updated terminate_connection() so you can choose if DEL_HOSTs should be - sent or not. - -commit 12f6b80429bc05a828051d72cc46f173e4657180 -Author: Guus Sliepen -Date: Fri Jul 20 20:25:10 2001 +0000 - - Added purge_tree for connection_t's which are no longer in the connection, - active or id trees, but which may still be referenced. This tree is flushed - when it is safe, this replaces purge_connection_tree(). - - Also lots of bugfixes related to the new trees. - -commit 37ed4265fa73d4c06c74362514d78c92029b2f05 -Author: Guus Sliepen -Date: Fri Jul 20 13:54:19 2001 +0000 - - Remove all unnecessary status.meta and status.active checks. - -commit 5e2ded68bfc7b3a1bfa600c1ce46144eb50e57a2 -Author: Guus Sliepen -Date: Thu Jul 19 12:29:40 2001 +0000 - - Correctly use the active_tree. - -commit 319e0cb48eb00565a11c85b901f54141f8160334 -Author: Guus Sliepen -Date: Sun Jul 15 18:07:31 2001 +0000 - - Split connection list into two lists: - - one list to handle all incoming/outgoing TCP connections - - another list to handle all UDP connections - - This will prevent race conditions. - -commit b3074590b184c141419cf4926820dc0d78380535 -Author: Guus Sliepen -Date: Sun Jul 15 14:21:12 2001 +0000 - - Correct inclusion of standard if_tun.h header file. - -commit 5dc4ade0b9c127a3c144d9c59894bf13527fe060 -Author: Guus Sliepen -Date: Wed Jul 4 08:43:32 2001 +0000 - - Don't load table of verbose OpenSSL errormessages. - -commit 1e2bdc2b6d28c76c63fc9fd36169b90fa0994388 -Author: Guus Sliepen -Date: Wed Jul 4 08:41:36 2001 +0000 - - - Always use instead of just - - Check if RAND_pseudo_bytes() exists, otherwise just use RAND_bytes() - -commit 6bd93e4c064578b545cb6dcaa28fffb229c929ff -Author: Guus Sliepen -Date: Sun Jul 1 21:42:13 2001 +0000 - - Check for all potential duplicate entries in the id tree. - -commit 9645cabc8e8364ed4df187fab8065b0991afa6af -Author: Guus Sliepen -Date: Sun Jul 1 09:21:14 2001 +0000 - - Fix compiler warning. - -commit 6365d0627b9b1e9a31371ec891db0d2cfb4d6ed4 -Author: Guus Sliepen -Date: Sun Jul 1 09:21:01 2001 +0000 - - Fix printf format bug. - -commit 33d6de0cd5c05cbf37211924a45e4231fec3a416 -Author: Guus Sliepen -Date: Sun Jul 1 09:06:17 2001 +0000 - - More items marked as done. - -commit a111593a082ff1df26f54168ab00f83ab3a1ab49 -Author: Guus Sliepen -Date: Fri Jun 29 15:38:40 2001 +0000 - - Dutch translation updated. - -commit 748dabdbe93f7439ed7eddf491a556279250e7ac -Author: Guus Sliepen -Date: Fri Jun 29 15:33:18 2001 +0000 - - Update of RedHat build scripts. - -commit 343c8fb6388ffd4f5c41cebd666aa8a045b20bdd -Author: Guus Sliepen -Date: Fri Jun 29 15:32:26 2001 +0000 - - It appears that autogen.sh doesn't like es.po if it isn't mentioned in - the makefile/configure scripts. - -commit 9391efe4e88077723840a7c085388ba2765ca17c -Author: Guus Sliepen -Date: Fri Jun 29 14:15:46 2001 +0000 - - Check for dlopen in standard libraries first (needed for DEC OSF). - -commit c9591bd1de1abcfe10459bd8c8cdd81a7b441ec0 -Author: Guus Sliepen -Date: Fri Jun 29 13:09:55 2001 +0000 - - Fix gcc 3.0 warnings. - -commit 402b85c48284a06fbfc56aca102b33be3a4260b0 -Author: Guus Sliepen -Date: Fri Jun 29 13:09:32 2001 +0000 - - Log error if two hosts connect with same IP/port tuple. - -commit 0d3bd912acdb00dc0a8015e337f981c942aa21bc -Author: Guus Sliepen -Date: Fri Jun 29 11:09:13 2001 +0000 - - Also remove po/Makefile.in.in, which is generated by autogen.sh. - -commit 67c16924c10b25d37957843a69d993b934dd1776 -Author: Guus Sliepen -Date: Fri Jun 29 11:03:27 2001 +0000 - - es.po revived. - -commit 5d3450357482176ce92ed4832ec944519d197744 -Author: Guus Sliepen -Date: Fri Jun 29 10:30:18 2001 +0000 - - Execute tinc-down BEFORE tap device is closed. This is a. more symmetric - (tinc-up is started after tap device is opened) and b. is needed for - tun/tap device, where the interface does not exist anymore after the - device file is closed. - -commit 6666acd0012c82c0bb4d1abae87332cec3dda77a -Author: Guus Sliepen -Date: Fri Jun 29 10:27:57 2001 +0000 - - Don't build Spanish translation. - -commit 77f635e871060f63c3e62fcf879d184326c690a4 -Author: Guus Sliepen -Date: Fri Jun 29 10:27:33 2001 +0000 - - ABOUT-NLS is created by autogen.sh. - -commit 333be8fbb8790237577761e580126a6d757a46e4 -Author: Guus Sliepen -Date: Fri Jun 29 10:23:46 2001 +0000 - - Spanish translation removed. Nobody maintains it, and it is severely - outdated. - -commit 3503ba995012f658f087a196dad0cb9fd45eff3b -Author: Ivo Timmermans -Date: Tue Jun 26 22:00:57 2001 +0000 - - Small fix to make it compile again - -commit 7fc068fe5421f7ec556b0b7db6f814e18b3326a4 -Author: Guus Sliepen -Date: Thu Jun 21 18:28:52 2001 +0000 - - Reinstated search for if_tun.h in kernel source tree, because apparently - /usr/include/linux does not always have the same contents as the include - files from the currently running kernel. - -commit 9e96840da810437c45af1c4b139578f7d74d65db -Author: Guus Sliepen -Date: Thu Jun 21 16:37:47 2001 +0000 - - Remove #warnings I used for debugging stuff. - -commit b1e97ece9c495ac67e54b8c2675b1eacc645eb1c -Author: Guus Sliepen -Date: Thu Jun 21 16:37:05 2001 +0000 - - Check for and add -ldl. - -commit 04ec0b82ab9c6a2662300a9257a5aff1c4dd56e7 -Author: Guus Sliepen -Date: Thu Jun 21 16:16:32 2001 +0000 - - - Solaris compile fixes - - Set mymac to broadcast MAC so that ifconfig hw ether <...> is really not - needed anymore. - - Forwarding of indirect packets when in switch mode (because the kernel - will not do it for us then). - -commit 353a9230bb70b70028f2dc6c651a28e30b13dc63 -Author: Ivo Timmermans -Date: Wed Jun 20 21:32:40 2001 +0000 - - Don't include the debian/ dir in a release - -commit 9a0a50cd3cf2570b39e00edf1a92123acbac41b4 -Author: Guus Sliepen -Date: Sat Jun 9 10:00:34 2001 +0000 - - Woops - big bug in send_key_changed fixed. - -commit ba918dce287788aaf6a90b3c7a9f349b197068d6 -Author: Guus Sliepen -Date: Fri Jun 8 18:02:10 2001 +0000 - - Only reset seconds_till_retry when we activate the outgoing connection. - -commit c5c02a0861bf540e07fe64704cb97aae29c4cacf -Author: Guus Sliepen -Date: Thu Jun 7 07:51:04 2001 +0000 - - Changed drastically because it didn't work correctly: - - Don't cache the --with-openssl-* option arguments - - Only search for openssl/*.h, the openssl include files include other - files only from an openssl/ directory too - - Set CPPFLAGS before AC_CHECK_HEADERS - -commit 053e78654097cf353aa59b4d34e608726edd5dad -Author: Guus Sliepen -Date: Thu Jun 7 07:48:11 2001 +0000 - - Save configure cache more often. - -commit 96ef7becdd71fc63c3489e3696117c1f137eade5 -Author: Guus Sliepen -Date: Wed Jun 6 19:12:38 2001 +0000 - - Fixes to make switching work between hosts that have no meta-connection. - -commit ce6c8e6d089abac81520c517185c6ef81b09f051 -Author: Guus Sliepen -Date: Wed Jun 6 19:11:16 2001 +0000 - - Log and warn about duplicate subnet_add()'s for the same subnet. - -commit 9cd9b0392388e24ade19a43206221081b61806e7 -Author: Guus Sliepen -Date: Tue Jun 5 19:45:47 2001 +0000 - - Add missing? counting of total_socket_in. - -commit 7bd7f5b4363f222340e5c058c243d31c576fba88 -Author: Guus Sliepen -Date: Tue Jun 5 19:39:54 2001 +0000 - - You can now put an option "Mode" in tinc.conf, and choose from: - - - Mode = router (default, work like tinc has always worked) - - Mode = switch (work like a switch) - - Mode = hub (work like a hub, broadcasting everything) - -commit edd6734faa37d043b8a2cc75b125db3b1c2130fa -Author: Guus Sliepen -Date: Tue Jun 5 18:07:14 2001 +0000 - - Fix bug where lookup_subnet_ipv4() could go into an infinite loop. - -commit fa376fbd4e5151ae43e86441a1e99073eeaf46a5 -Author: Guus Sliepen -Date: Tue Jun 5 16:31:59 2001 +0000 - - - This oneliner removes the need for ifconfig tap? hw ether fe:fd:0:0:0:0 - -commit 7a736d47b264065371f35cd9da64485d798cbc80 -Author: Guus Sliepen -Date: Tue Jun 5 16:15:48 2001 +0000 - - Updated dutch translation. - -commit 92924e8482f000eb33130ce9feadc08450ff349d -Author: Guus Sliepen -Date: Tue Jun 5 16:13:41 2001 +0000 - - Changed some stuff to allow correct generation of po/Makefile after a - make cvs-clean. - -commit 4f9dad0972ac0f665a1b6050b059bd52f93e6221 -Author: Guus Sliepen -Date: Tue Jun 5 16:09:55 2001 +0000 - - - tinc can now act as a switch or a hub too (as opposed to a router only) - - cleaner initialisation of "UNKNOWN" and "MYSELF" names - -commit 428482d86f860d1fb09de722c1b6576ec2eef1ce -Author: Guus Sliepen -Date: Mon Jun 4 11:14:35 2001 +0000 - - Added proxy-arp support. No more ifconfig -arp needed. Works like a charm - under FreeBSD now :). - -commit 0a3c8cefd4a154948799baaaa246cf0eba050eff -Author: Guus Sliepen -Date: Fri Jun 1 08:02:09 2001 +0000 - - Fix subnet_lookup() for overlapping subnets. Needs rethinking. - -commit 7db1b999c82611d6c68a5d79b4754db19669d5c6 -Author: Guus Sliepen -Date: Mon May 28 08:56:57 2001 +0000 - - Make sure Solaris is happy too. - -commit 65247c063b36a76dd68156fe17b017c7460d982f -Author: Guus Sliepen -Date: Mon May 28 08:21:43 2001 +0000 - - Small fixes to allow correct compilation under FreeBSD (tested with 4.3) - -commit 4e959ee40542733e647c36831c1fc87ed8098233 -Author: Ivo Timmermans -Date: Sat May 26 09:35:28 2001 +0000 - - Don't distribute autogen.sh in a release - -commit 514f8f579d5c0608aee8ca4a43d7414ecee5c11c -Author: Ivo Timmermans -Date: Sat May 26 09:35:00 2001 +0000 - - Changed version number to 1.0-cvs - -commit 20c2b62b1802390c0f5a1757641a0a1cea8103a8 -Author: Ivo Timmermans -Date: Sat May 26 09:34:11 2001 +0000 - - New make target: `make release' - -commit 8d307c2fbf2c20eb53909f74c81e03db838fb55e -Author: Guus Sliepen -Date: Fri May 25 18:57:37 2001 +0000 - - Fix sample configuration to show keys in PEM format and correct tapdevice. - -commit e12d41f39d8dd1cd30058d08effd2e5b66cdd4fd -Author: Guus Sliepen -Date: Fri May 25 13:24:34 2001 +0000 - - Documents are merged. Now we only need to check the ports and the TCPonly - and IndirectData options. - -commit f0c64a3dac3b0469ea05fa5d44a1e7bdbfa64900 -Author: Guus Sliepen -Date: Fri May 25 12:45:37 2001 +0000 - - Merged PROTOCOL, NETWORK and SECURITY2 with the texinfo manual. - -commit fcf869cd4250a240ea8d443f70fa373e4fbacf07 -Author: Guus Sliepen -Date: Fri May 25 11:54:28 2001 +0000 - - TCPonly now works (in a relatively clean way too). - -commit a5e2ae6b2b2e1629cf05bb2a57df75f13c0f120a -Author: Guus Sliepen -Date: Fri May 25 10:08:11 2001 +0000 - - With recent kernels the tun device file is located in /dev/net. - -commit 6e09c2a99c8ac3c1391f4f2eee16d6c235c10e90 -Author: Guus Sliepen -Date: Fri May 25 10:06:13 2001 +0000 - - Small corrections to the manuals. - -commit 4dee76522e177dcb4af5d6d844a5f3b74070e4b7 -Author: Guus Sliepen -Date: Fri May 25 08:36:11 2001 +0000 - - Small fixes: - - - Fix compiler warnings (one was a real (but harmless) bug) - - Don't send PING packets if there is UDP traffic - - Correctly terminate strings containing salt for PING/PONG packets - -commit bfc5d6014e3c1563f7b6a2f10698e9ba23ba3e96 -Author: Guus Sliepen -Date: Thu May 24 21:52:26 2001 +0000 - - Only send key_changed if it was previously requested. - -commit 1a248fd5bd5aa24fa0f6a2c395f05dd569f0898d -Author: Guus Sliepen -Date: Thu May 24 21:32:30 2001 +0000 - - All features for 1.0 are implemented now, we just have to check the - FreeBSD and Solaris ports and merge some docs. - -commit 58893f0875369aafff8481825af271683c975a2a -Author: Guus Sliepen -Date: Thu May 24 21:30:36 2001 +0000 - - Since this is incompatible with some earlier versions, PROT_CURRENT is - increased. - -commit d1b597758eab68bb80d97855f25cb6dda55eeb0b -Author: Guus Sliepen -Date: Thu May 24 21:29:09 2001 +0000 - - Add randomness to PING/PONG packets to prevent crypto attacks on quiet - tunnels. - -commit 4493b0650bd487990ca9d2802496ad0ee7c06247 -Author: Guus Sliepen -Date: Thu May 24 20:40:13 2001 +0000 - - Changed URL from kernelnotes.org to linuxdoc.org. - -commit 3360c6270bcc19a8b3d81da185266fc33b5c5421 -Author: Guus Sliepen -Date: Thu May 24 20:24:12 2001 +0000 - - More revisions to the documentation: - - - Removed cruft - - Reordered some sections to make it more logical for the beginner - - Added small examples and hints about configuration files - -commit 6f7f8659a2048fd6d616f4286ccdd0e661084493 -Author: Guus Sliepen -Date: Sat May 19 15:50:51 2001 +0000 - - - Make sure correct information is supplied for both old kernels (with - ethertap) and for new kernels (with TUN/TAP driver). - - Revised example configuration and made it conform to latest (CVS) version of - tinc. - -commit e4f3d93ec62871d1ae11b460627aef0da1b23cd2 -Author: Guus Sliepen -Date: Mon May 7 19:08:46 2001 +0000 - - - s/ip_t/ipv4_t/g - - Add "salt" to the beginning of UDP packets. Replaces length field which - is not useful anyway. - -commit a26081467c197cc6b26a0c36c4508361b242fc85 -Author: Guus Sliepen -Date: Fri May 4 18:45:02 2001 +0000 - - Correctly cycle through ConnectTo variables. - -commit 80b4a851a6b62cbbf503c2225f93305966f058c0 -Author: Guus Sliepen -Date: Fri Apr 13 10:30:04 2001 +0000 - - Depend on new ssl package and install alias for universal TUN/TAP module. - -commit 156ec676525ed789364b7a77926dd0717d0cf5d7 -Author: Guus Sliepen -Date: Tue Mar 13 21:33:31 2001 +0000 - - Check indirectdata option before forwarding certain requests. - -commit c426e981eeaed3fa4801221720ee8f74d40e9223 -Author: Guus Sliepen -Date: Tue Mar 13 21:32:24 2001 +0000 - - Ignore alarm signals if we do not need to respond to them. - -commit b413257e10ae0645da43583dd8f84a1f74df5bd7 -Author: Guus Sliepen -Date: Tue Mar 13 09:55:14 2001 +0000 - - Fixed bug in setup_signals() that would make tinc die when unexpected - signals were caught. - -commit f1a082823c48d00171b814f7e14e07e6dd4632fb -Author: Guus Sliepen -Date: Mon Mar 12 23:58:19 2001 +0000 - - Fixed a race condition triggered by receive_meta() and the new - authentication scheme. - -commit f4887b981f109fc4264f50170b2d12c4033bf5e9 -Author: Guus Sliepen -Date: Sun Mar 4 14:00:24 2001 +0000 - - Added a description of what is going on in net.c and route.c, and how - packets flow through tinc. - -commit 9d5c9bf6ba74e4e8bbd12b97fdda6c665155fec6 -Author: Guus Sliepen -Date: Sun Mar 4 13:59:53 2001 +0000 - - Updated translation. - -commit 34f9e6cf2d6d2b81eb63f9f28963b447a2157740 -Author: Guus Sliepen -Date: Sun Mar 4 13:59:32 2001 +0000 - - - route.c is now used to determine destination - - flags are removed, since they were not used at all. Use options instead. - - indirectdata works now, tcponly almost... - - made functions that don't return useful information void - -commit d2a54597e029f9d4f7bd29837be1be33909d78b1 -Author: Guus Sliepen -Date: Fri Mar 2 11:25:56 2001 +0000 - - Added explaination of our key exchange using RSA encryption. - -commit 125c4978812cffa5154ce5378a276f43f78417d8 -Author: Guus Sliepen -Date: Thu Mar 1 21:32:04 2001 +0000 - - Various small fixes. - -commit 099cc867c1a0831add7f1b4046f22ad6bfa5a1ef -Author: Guus Sliepen -Date: Tue Feb 27 16:50:29 2001 +0000 - - Removed compiler warning. - -commit 4fa12eb85d72f039df5004abc201f01f5573c2e4 -Author: Guus Sliepen -Date: Tue Feb 27 16:37:31 2001 +0000 - - Removed lots of compiler warnings. - -commit 173d606514d82fc5ae7895a178238d0abcaf6606 -Author: Guus Sliepen -Date: Tue Feb 27 16:17:04 2001 +0000 - - - Fixed Interface option (untested) - - Removed error handling for non-critical socket options - - Added TCP_NODELAY and IPTOS_LOWDELAY options for meta sockets. - -commit fb4ba9b265666d9949b03209a3ff52ff1263226b -Author: Ivo Timmermans -Date: Tue Feb 27 16:15:14 2001 +0000 - - Authentication done - -commit 24fa68585923d2b52718390f3f38d1aaacef12f0 -Author: Guus Sliepen -Date: Tue Feb 27 15:33:39 2001 +0000 - - Don't forget to reconnect if outgoing connection fails during - authentication. - -commit 34b7a876c3583f7a34585cff6a694bc9e35cdc87 -Author: Guus Sliepen -Date: Mon Feb 26 11:37:20 2001 +0000 - - - Make sure METAKEY is smaller than the modulus of the RSA key - - Get symmetric key from the least significant bytes of the RSA message - -commit 4b0ad4d97abd3643c44f45841d52f3000a34ba60 -Author: Guus Sliepen -Date: Sun Feb 25 20:17:46 2001 +0000 - - Added process.c to the translated files. - -commit 82455be966027a087a2ac23e3464594c81d7b111 -Author: Guus Sliepen -Date: Sun Feb 25 19:09:45 2001 +0000 - - Implemented new authentication scheme from doc/SECURITY2. - -commit 54881faf6fdbf04fb5ee56b7809439fbc50c65cb -Author: Guus Sliepen -Date: Sun Feb 25 16:34:19 2001 +0000 - - Encrypt network packets in CBC mode instead of CFB mode. - (This breaks compatibility with all previous versions!) - -commit 9de5787574b21e94c80ddc60def2b3e514aff755 -Author: Guus Sliepen -Date: Sun Feb 25 16:04:00 2001 +0000 - - Copy packets before putting them in the queue. - -commit 38adc479a44b64afcb220cd757f77ab105cb9bcd -Author: Guus Sliepen -Date: Sun Feb 25 15:34:50 2001 +0000 - - Free node->data and node, not node->data twice. - -commit e250d64300cea2a83059866e7cbabcb33684160e -Author: Guus Sliepen -Date: Sun Feb 25 14:51:42 2001 +0000 - - Add missing \n. - -commit 153fc35e57c0104aa4ea9103bcdbca3665e4934c -Author: Guus Sliepen -Date: Sun Feb 25 11:09:29 2001 +0000 - - Corrected check for errors after read() calls. - -commit 0b0c2a372ff5d11f73af172e07a93b2656374a42 -Author: Wessel Dankers -Date: Tue Feb 20 21:53:18 2001 +0000 - - Important bugfix in avl_insert_before() and avl_insert_after() - -commit 11f8465dd9a4f81b43a31f1cb6a7fc2d76bb7838 -Author: Ivo Timmermans -Date: Sun Feb 18 02:13:26 2001 +0000 - - tinc_TUNTAP now substitutes the values outside the AC_CACHE_CHECK - block. configure should now correctly set HAVE_TUNTAP. - -commit bb0870498037565209e24fbb2ffa07b815350a0b -Author: Guus Sliepen -Date: Tue Feb 13 09:54:29 2001 +0000 - - Added description of the proposed new authentication scheme. - -commit cebb6efeb0f39bf05ca7836b7a393c8385b49335 -Author: Ivo Timmermans -Date: Sun Feb 11 11:55:28 2001 +0000 - - More files to ignore in CVS - -commit 603781831f251d2e8111e8282d8e624b8e40b175 -Author: Guus Sliepen -Date: Sun Feb 11 11:50:09 2001 +0000 - - - Updated CVS_CREATED to remove intl/ directory and some other - autogenerated files. - - Checked if all INCLUDES/LIBS/etc directives inherit the global variables. - -commit 88dfdc9dbac3f5d0aa70b77509b4a87513433987 -Author: Guus Sliepen -Date: Sun Feb 11 11:46:14 2001 +0000 - - Ignore file for src/ - -commit ef0fc4f687fc25e97551e589941d6a2a2d8ade42 -Author: Guus Sliepen -Date: Sun Feb 11 11:44:32 2001 +0000 - - Added .cvsignore files to get rid of warnings and prevent autogenerated - files from being added accidentaly. - -commit f1cb3d8fa5f69840f353ca5a62f363dad47eb46f -Author: Guus Sliepen -Date: Tue Feb 6 10:42:27 2001 +0000 - - Removed another local definition of the variable "errno" - -commit 0f715887c617723e4b450083f8b77641f8b62e80 -Author: Guus Sliepen -Date: Tue Feb 6 10:13:44 2001 +0000 - - Updated dutch translation. - -commit 4bc394a3e29f2f90434bbbfc9f23d5587398471b -Author: Guus Sliepen -Date: Tue Feb 6 10:13:22 2001 +0000 - - Fix memory leak in avl_insert() if item was already inserted. - -commit f777c1807d663eaef3e36c395094451214886898 -Author: Guus Sliepen -Date: Tue Feb 6 10:12:51 2001 +0000 - - FreeBSD compile fixes (thanks to XeF4) - -commit bb4457d6caf6e424aeaf9b09222d4e62cab939da -Author: Ivo Timmermans -Date: Thu Jan 18 13:02:34 2001 +0000 - - Unpack sample-config.tar.gz when installing - -commit fe61e1ffef186aa509a50be3be83955fe1cbb514 -Author: Ivo Timmermans -Date: Thu Jan 18 13:01:42 2001 +0000 - - Distribute the sample config as a .tar.gz - -commit a73ec9caa45bda7738376a610030c8ba9b934445 -Author: Ivo Timmermans -Date: Thu Jan 18 13:00:57 2001 +0000 - - Fixed some errors - -commit b33c5f6640e63cc4cd35285367bcb2827b732229 -Author: Ivo Timmermans -Date: Wed Jan 17 16:24:24 2001 +0000 - - First try to create a graphical frontend for tinc configuration - -commit 6bc77a7710adcbc33331c45e1b6adf7089a42075 -Author: Ivo Timmermans -Date: Wed Jan 17 01:48:44 2001 +0000 - - Get the PO files up to date with the current source - -commit 664f7e5c0b9056d88e2b63b3626ea33c4894387b -Author: Ivo Timmermans -Date: Wed Jan 17 01:47:39 2001 +0000 - - Get the Debian changelog up to date - -commit 1d898e00a964ef922617683a1d29ff24e56ed8ff -Author: Ivo Timmermans -Date: Wed Jan 17 01:40:46 2001 +0000 - - Merged documentation with various updates I had lying around - -commit 457c6fa7b63a7f2971314d8d63af71c880ec6f53 -Author: Ivo Timmermans -Date: Wed Jan 17 01:34:08 2001 +0000 - - Second draft of the release notes - -commit b236ddb1df16f8eb025d485b75153c4f25f4afc6 -Author: Ivo Timmermans -Date: Wed Jan 17 01:31:56 2001 +0000 - - Change version to 1.0pre4 - -commit a893b05cb017c04871c2faf4099f104985f4ad75 -Author: Ivo Timmermans -Date: Wed Jan 17 01:30:32 2001 +0000 - - Set Architecture to `any' - -commit 54e19d34663cfe4af05e9e1dac94f76e39858f18 -Author: Ivo Timmermans -Date: Wed Jan 17 01:30:05 2001 +0000 - - Fix error reporting of read_config - -commit a56df1e06be3f47a775919e564c147687e961b5d -Author: Guus Sliepen -Date: Sat Jan 13 16:36:23 2001 +0000 - - - Allow ASN1 style keys to be in the config files. - Note: tinc ignores private key in the main config file, tinc.conf, - because it should really be in a separate file. - - When generating new keys, check if name is known and by default append - the public key to the host configuration file (otherwise rsa_key.pub). - -commit 44c85ab07ed07165b80140da4e2910ca51fa8887 -Author: Guus Sliepen -Date: Sat Jan 13 14:56:46 2001 +0000 - - - Copy entire sample-config directory to /etc/tinc/example upon installing. - -commit b195e8815f0abb2c5527119221886b524d719019 -Author: Guus Sliepen -Date: Sat Jan 13 14:38:18 2001 +0000 - - Added sample configuration directory. - -commit d646f4e094b63720f97bfd37bb3489bd9d6231a0 -Author: Guus Sliepen -Date: Thu Jan 11 11:19:08 2001 +0000 - - - Only send out DEL_HOSTs for hosts with a meta connection - -commit c8beaf35ee923c209ee23bedcb3dc892d2c2dae3 -Author: Guus Sliepen -Date: Mon Jan 8 21:32:30 2001 +0000 - - - Cleaned up subnet_t - -commit e5e1c20a99b0d72792f28e9a075a9f4a7e8b2c95 -Author: Guus Sliepen -Date: Mon Jan 8 21:32:00 2001 +0000 - - - Sign was wrong in search_closest_smaller/greater - -commit 11f3e9d138daf6b726631cc124b14d66dfa4d1f7 -Author: Guus Sliepen -Date: Mon Jan 8 20:35:30 2001 +0000 - - - Squashed another nasty bug. - -commit 447a43d63960802a7a29201c512246be11eb9c94 -Author: Guus Sliepen -Date: Sun Jan 7 20:19:35 2001 +0000 - - - Added indirectdata and tcponly functionality. - -commit 7cd2baedc6027ef6a5b941342bc6d3931d7220ba -Author: Guus Sliepen -Date: Sun Jan 7 20:19:08 2001 +0000 - - - Fixed IPv6 subnet lookup routine. - -commit d3f889c8076dff9c00ebfe1459cb36425f8da41d -Author: Guus Sliepen -Date: Sun Jan 7 17:09:07 2001 +0000 - - - It's 2001, all copyright notices are updated. - -commit 96b6f958bc733c3963dd164caacd42513be47a86 -Author: Guus Sliepen -Date: Sun Jan 7 17:08:03 2001 +0000 - - - Description of protocol and authentication updated. - -commit 7109526c6789c73a18bbe6b228ca35f0374c8d36 -Author: Guus Sliepen -Date: Sun Jan 7 15:27:30 2001 +0000 - - - Added header file for route.c. The routing routines in it are not used - yet, but have a look at the source for the ideas behind it. - -commit 07a08f5539f441e66946d1db1711dc584f8621c4 -Author: Guus Sliepen -Date: Sun Jan 7 15:25:49 2001 +0000 - - - Reinstated a queue for outgoing packets. - -commit 049ff67817e0db5afbba30930531d8ea3f7f2d18 -Author: Guus Sliepen -Date: Sun Jan 7 15:24:52 2001 +0000 - - - Changed list routines to give it the same look'n'feel as the rbl and - avl tree library. - -commit 8b4bc5b3a7e31c198c001610c99c2993e1612376 -Author: Guus Sliepen -Date: Sat Jan 6 20:43:03 2001 +0000 - - - Typo. - -commit 3d7289cf743f89cab4c71815482a4837a21f6703 -Author: Guus Sliepen -Date: Sat Jan 6 20:02:21 2001 +0000 - - - Updated texinfo manual. - -commit 0d99ae59bd7c640d396ce978045f0911567fb9bf -Author: Guus Sliepen -Date: Sat Jan 6 18:44:55 2001 +0000 - - - Updated manual pages. - -commit 90bf1b21fa7e94d73719da0593e7c0356d05e18f -Author: Guus Sliepen -Date: Sat Jan 6 18:21:17 2001 +0000 - - - Changed license of AVL tree library to GPL. - -commit f7bb205022e02c02c02733cd43544c231373115d -Author: Guus Sliepen -Date: Sat Jan 6 18:03:41 2001 +0000 - - - Check and follow symlinks in is_safe_path - - By default write keys to tinc config directory - - Small fix in protocol.c - -commit 1398edec37336853bfca6ea3dcca7c402f102ea2 -Author: Guus Sliepen -Date: Sat Jan 6 16:51:14 2001 +0000 - - - Updated dutch translation. - -commit e924096f62655d711cd2d114a8d1ef0fecbb593b -Author: Guus Sliepen -Date: Fri Jan 5 23:53:53 2001 +0000 - - - Let user choose whether keys are in the config files or separate - - Use AVL trees instead of RBL trees - - Fixed a lot of annoying subtle bugs! Thanks to gdb... - -commit 052fbc0bdf36e0dbe2a0867ce770d426c9a44841 -Author: Guus Sliepen -Date: Fri Jan 5 23:51:41 2001 +0000 - - - Doubled size of trace buffer for easier debugging. - -commit 77509da76c61b881c9967bfb7cdafeaf6b56eb6d -Author: Guus Sliepen -Date: Fri Jan 5 23:50:56 2001 +0000 - - - AVL tree routines: faster than RBL, and also more stable. - -commit e1707f7739f450c729e26b921e459d5da07602f9 -Author: Guus Sliepen -Date: Fri Dec 22 21:34:24 2000 +0000 - - - Don't even think about using sscanf with %as anymore - - Allow keys to be inside the config files or in a seperate file - - Small fixes - -commit ecae72de94222302aa326888f70cfacdbd775b23 -Author: Ivo Timmermans -Date: Fri Dec 22 17:15:26 2000 +0000 - - Added lint target, requires lclint. - -commit c5fac35c6ce9b9fcc47508810d69aeab83d08c25 -Author: Ivo Timmermans -Date: Fri Dec 22 17:10:25 2000 +0000 - - Forget router.c - -commit 37544990e96fe5ea161e644f6417f505d666cd00 -Author: Ivo Timmermans -Date: Fri Dec 22 16:59:16 2000 +0000 - - Include autogen.sh (needed for the Debian package). - -commit 8a4daf4ea7758270a47a358f43ad97a64eb1c3ff -Author: Ivo Timmermans -Date: Fri Dec 22 16:54:56 2000 +0000 - - Various small changes. - -commit e469fca4d78e9d23698fe1e6b29b232198cc499e -Author: Ivo Timmermans -Date: Wed Dec 6 13:33:49 2000 +0000 - - Re-introduced MyVirtualIP and VpnMask, as dummy options. - -commit e50e4a54d6b40b988041a7e9bfdfbf708657f3a5 -Author: Ivo Timmermans -Date: Tue Dec 5 09:04:32 2000 +0000 - - Give a warning about having to re-create the keys - -commit 4610d98c04641fce65747e07d65cbdd03fb6fe30 -Author: Ivo Timmermans -Date: Tue Dec 5 09:03:41 2000 +0000 - - Ported it back to /bin/sh. - -commit 1e38dcc3fa6c0da2fdb21f83a588338fa8a41818 -Author: Ivo Timmermans -Date: Tue Dec 5 09:03:19 2000 +0000 - - Install a file in /etc/modutils/tinc, containing all necessary aliases - and options for kernel modules. - -commit 6327f32f43dc9109fad9952fd50a23876d0acaf0 -Author: Ivo Timmermans -Date: Tue Dec 5 08:59:30 2000 +0000 - - Tiny bits of code beautifying - -commit 9267bed9f516244b00d5c86c8dae44b7eb78a96c -Author: Ivo Timmermans -Date: Tue Dec 5 08:56:44 2000 +0000 - - Oops. I did some VERY wrong things with readline(). Fixed now. - -commit 6ddc9109d7313503895227c7876309b36681393d -Author: Ivo Timmermans -Date: Tue Dec 5 08:54:22 2000 +0000 - - Massive long awaited documentation update. It's not finished yet, - most notably the example configuration is still old. - -commit bc22ee16e6903d2caf9d22afa85020d1e3e10b56 -Author: Ivo Timmermans -Date: Sun Dec 3 12:23:06 2000 +0000 - - Option -d accepts an argument to set the debug level immediately. - -commit 01d23601a273d128ebfd13c2ffa10892e9b13094 -Author: Ivo Timmermans -Date: Sun Dec 3 12:22:19 2000 +0000 - - Sort configuration directives - -commit d6b77e18b58ad8f9bcd9b60864b95cd2a74482c5 -Author: Ivo Timmermans -Date: Sun Dec 3 12:21:20 2000 +0000 - - Added documentation merger - -commit e985f6d3cdbebdeb17333bbd3d3c20d4618128cf -Author: Ivo Timmermans -Date: Fri Dec 1 13:46:26 2000 +0000 - - Include COPYING.README in the distribution. - -commit 94192b3db10fe51ce45fa569ec068423a4491b0b -Author: Ivo Timmermans -Date: Fri Dec 1 13:45:46 2000 +0000 - - Stated that distributing executables linked with OpenSSL is permitted - provided that all other requirements of the GPL are complied with. - -commit 52575a573c1d87ee125a54a2e0b4044698904cae -Author: Ivo Timmermans -Date: Fri Dec 1 12:38:42 2000 +0000 - - Use buffer instead of line in read_config_file(), line may be assigned - NULL, so buffer always holds the pointer to the allocated space. - -commit ab33c1aa6081f07333bf1de00e4036dd2b4628a6 -Author: Ivo Timmermans -Date: Fri Dec 1 12:36:36 2000 +0000 - - readline() accepts two extra parameters, buf and buflen, to avoid - mallocing and freeing for every line that is read. - -commit 6c56a8416eded8f19076a619a27ad7b153dd91f3 -Author: Ivo Timmermans -Date: Thu Nov 30 23:44:07 2000 +0000 - - Tagged `Storing private key in separate file' as done. - -commit 8fe83e98da043e930a88ddd6b2de6c14aa791335 -Author: Ivo Timmermans -Date: Thu Nov 30 23:39:55 2000 +0000 - - All full stops have two spaces after them. (Silly commit, I know.) - -commit a0f7af3ed79c55d9680cbb0a569b3c8987581d43 -Author: Ivo Timmermans -Date: Thu Nov 30 23:18:21 2000 +0000 - - New function read_rsa_public_key(); - In net.c/setup_myself deleted old code to read the public key (which - is now implicitly read in together with the private key). - -commit 28deaeac14d619efb9830d03fd61dc7cca70a701 -Author: Ivo Timmermans -Date: Thu Nov 30 22:48:48 2000 +0000 - - Avoid printing duplicate messages from read_rsa_keys - -commit 2293304748f7e4e9a18ee848b8264bdecebae37f -Author: Ivo Timmermans -Date: Thu Nov 30 22:33:16 2000 +0000 - - Better error checking when reading the RSA private key. - -commit bf4e969899bb6cdeb05570d96a567c2833ac83bd -Author: Ivo Timmermans -Date: Thu Nov 30 22:32:14 2000 +0000 - - In readline(): initialise the line to zero length; - In read_config_file(): Test for EOF, and print the variable name that - caused an error. - -commit 113198d9c0b3be9904057673cfed165406803f86 -Author: Ivo Timmermans -Date: Thu Nov 30 21:11:03 2000 +0000 - - The file is safe if it doesn't exist. - -commit 09260b43d1ff037c22f86c82a6af830e9a6d6ae5 -Author: Ivo Timmermans -Date: Thu Nov 30 20:08:41 2000 +0000 - - Read the PEM file pointed to by the configuration directive - PrivateKey. This means thatt he meaning of this variable has changed, - it no longer should contain the private key directly. - - WARNING: This code is untested. - -commit 8ccb1ede92fbd55481fa2317c2450bb9dd94a180 -Author: Ivo Timmermans -Date: Thu Nov 30 00:24:13 2000 +0000 - - Implemented is_safe_path, and extended ask_and_safe_open. - - is_safe_path needs more work before it is useable. - -commit 75e3c296b4fa1eb02df2f5f84a1280e791f88603 -Author: Ivo Timmermans -Date: Wed Nov 29 15:22:04 2000 +0000 - - Updated Dutch translation - -commit d36da1948abdd27e9d0740c2baceb0bd155c18c6 -Author: Ivo Timmermans -Date: Wed Nov 29 14:30:07 2000 +0000 - - Also free the pointer returned by readline(). - -commit 9e55426d72fd77fda891edd0023dab2f9909639e -Author: Ivo Timmermans -Date: Wed Nov 29 14:27:24 2000 +0000 - - Use readline() in read_config_file() instead of fgets. - -commit 8ea23d9ec3f2fe0c113eac5caafb7c2bd03f3016 -Author: Ivo Timmermans -Date: Wed Nov 29 14:23:08 2000 +0000 - - xstrdup now takes a const pointer as an argument. - -commit 54ef13bf75a7a1e787716ce395ffe847fa74673f -Author: Ivo Timmermans -Date: Wed Nov 29 14:24:40 2000 +0000 - - Implemented a readline() function that will read an entire line into a - dynamically allocated buffer; - - Ask for a file name in ask_and_safe_open(). - -commit 9175d2048382c617a639fd3d437a9e06baa66d0f -Author: Ivo Timmermans -Date: Wed Nov 29 01:37:50 2000 +0000 - - Added a check for a scanf that knows about %as. - -commit 1ca04711aeab615161746c6bbb5d137388c73263 -Author: Ivo Timmermans -Date: Wed Nov 29 00:33:15 2000 +0000 - - Check for get_current_dir_name. There is a replacement function in - dropin.c. - -commit c94f7637427f4c89d56c41fe4c75f2970b664a63 -Author: Ivo Timmermans -Date: Tue Nov 28 23:23:41 2000 +0000 - - dropin.c/h contain a set of drop-in replacements for non-standard C - library functions (read: GNU extensions). - -commit 3ff76eb10acc55b6f269c1075de6bbaa5bc83516 -Author: Ivo Timmermans -Date: Tue Nov 28 23:12:57 2000 +0000 - - Save RSA public and private keys to a separate file, instead of - wanting to copy them into a configuration file. - -commit 4c502b005bfd24821e817c134e8a442a5f4606de -Author: Ivo Timmermans -Date: Tue Nov 28 08:59:27 2000 +0000 - - Use sigaction to set signal handlers, the previous commit (1.1.2.16) - already contained a large portion of what should have gone in this - one. - -commit e44dc004b3d1ce8f857971f479c917931eda7091 -Author: Ivo Timmermans -Date: Mon Nov 27 20:52:55 2000 +0000 - - Sort items to either 1.0 or future release goals. - -commit 699f3b4c93482055c0832c9a6b76dc0294967003 -Author: Ivo Timmermans -Date: Sun Nov 26 22:46:53 2000 +0000 - - Check for the function strsignal, and define it to "" if it is not - available. - -commit 67a4abda707b28b9c77cb35ff1e800e6a5b0991c -Author: Ivo Timmermans -Date: Sun Nov 26 22:42:34 2000 +0000 - - Give an error message if daemon() failed. - -commit 702e55306dfebe5c6f9a6587ed029c3bc3efbe8f -Author: Ivo Timmermans -Date: Sun Nov 26 22:32:52 2000 +0000 - - Updated Spanish translation, provided by Enrique Zanardi. - -commit 1eedf54681d4556c6874f7baee8e810cab867756 -Author: Guus Sliepen -Date: Sat Nov 25 13:33:33 2000 +0000 - - - Use only one socket for all UDP traffic (for compatibility) - - Write pidfile again after detaching - - Check OS (for handling FreeBSD/Solaris tun/tap stuff) - -commit 0806605ce383b7e89fa26eda56f8a5f3bbed9dd3 -Author: Guus Sliepen -Date: Fri Nov 24 23:30:50 2000 +0000 - - - Added daemon() replacement. - -commit cfb828784ebbcf4b3e40eb9bb351b6ed10a84b35 -Author: Guus Sliepen -Date: Fri Nov 24 23:14:52 2000 +0000 - - - Added Armijn to the list - -commit cf49b2c0647554613874cce495e4a7937a9f7863 -Author: Guus Sliepen -Date: Fri Nov 24 23:13:07 2000 +0000 - - Another big & bad commit: - - Added some extra search functions to rbl routines - - Fix subnet_lookup() - - Reorder some syslog messages to make more sense - - daemon() is back - - Don't let scripts execute in parallel (gives race conditions, and - anyway something MIGHT just be configured which is necessary for further - execution of tinc itself) - - Accidently merged check_child() with execute_script(). - - Small fixes - -commit 97c54ffb35312caf38034952b9ed2733f7e374f9 -Author: Ivo Timmermans -Date: Fri Nov 24 16:52:57 2000 +0000 - - Add default tinc-up and tinc-down scripts for a Debian system. These - do not yet work, it's just old code from init.d. - -commit b42c9abafdc102db0641f3d444bdb30fbc29140a -Author: Ivo Timmermans -Date: Fri Nov 24 14:15:20 2000 +0000 - - Call autogen.sh instead of configure alone; and make cvs-clean instead - of distclean. This way you can just cvs checkout && dpkg-buildpackage - in one go. - -commit edb9b4cad09855a9bb3c57c5d4b1b174fde1de6c -Author: Ivo Timmermans -Date: Fri Nov 24 14:13:51 2000 +0000 - - Explain how to tell configure where OpenSSL lives. - -commit 4cb4a7d298d560593f84d974bf77d0ee8a911a50 -Author: Ivo Timmermans -Date: Fri Nov 24 14:13:06 2000 +0000 - - Set errno to 0 before trying to kill the other process. - -commit ef88db63120503a8c9d34d86073795c99dedc3a9 -Author: Ivo Timmermans -Date: Fri Nov 24 14:12:31 2000 +0000 - - Alter CFLAGS, somehow INCLUDES doesn't propagate properly. Still - doesn't work exactly like it should, but getting there. - -commit b17822840150f5ba8cfb8e5a44fc10d66bd15a97 -Author: Ivo Timmermans -Date: Fri Nov 24 14:04:49 2000 +0000 - - Set CFLAGS to -O2 -Wall when running configure - -commit eb36b0c1ef7b5ed8ff59c3b41cbb361ed37d5f01 -Author: Ivo Timmermans -Date: Fri Nov 24 14:00:32 2000 +0000 - - Use cvs2cl instead of rcs2log to generate the ChangeLog. - -commit 2f37f2bd8ab6b89eb6b6c2b4bdd6ffe449b1aa98 -Author: Ivo Timmermans -Date: Fri Nov 24 14:03:13 2000 +0000 - - Set localstatedir to /var - -commit 31aa4298463498cbb755db747e901e4269cd1ef6 -Author: Ivo Timmermans -Date: Fri Nov 24 13:33:48 2000 +0000 - - Do not attempt to retreive ChangeLog information only from the CABAL - tag, it doesn't work anyway. - -commit f2dd7bb42c1f4bfa708f542e430f4a56fd43e74f -Author: Ivo Timmermans -Date: Fri Nov 24 13:32:26 2000 +0000 - - Do not check for the daemon() system call - -commit b0ff879e7c68edd447328f3d806c1ad9e336fece -Author: Ivo Timmermans -Date: Fri Nov 24 12:44:39 2000 +0000 - - Do not use the C library's daemon() call. - -commit cebcf78b9a24f70902009bea23514e55d84b096a -Author: Guus Sliepen -Date: Thu Nov 23 09:30:33 2000 +0000 - - - Don't link with -ldl anymore - - Let's not use bash' built-in pwd function anymore... it does not follow - symlinks. - -commit 7aa7895629d72391eccfcb23f3cb6290a9e3abc3 -Author: Guus Sliepen -Date: Wed Nov 22 23:09:38 2000 +0000 - - - #include instead of - -commit dac256505e1af78505c9f905bd55c11d4b87345c -Author: Guus Sliepen -Date: Wed Nov 22 22:18:03 2000 +0000 - - - Fixed all (except 2) compiler warnings gcc -Wall gave. - -commit 6f373e690236334d8f8333710b61f97ccad54bf1 -Author: Guus Sliepen -Date: Wed Nov 22 22:05:37 2000 +0000 - - - More porting to FreeBSD and Solaris. - -commit 5971e352dae2cf189f1cbdeacffa4ccdd1e98304 -Author: Guus Sliepen -Date: Wed Nov 22 20:25:27 2000 +0000 - - - Work with the correct key buffer in ans_key_h - -commit a07602c4fddfca9894f1d738959ae359695f5bf9 -Author: Guus Sliepen -Date: Wed Nov 22 19:55:53 2000 +0000 - - - No more %as. - -commit 394ed3fb174bb629bfb4b441fe58842562f955de -Author: Guus Sliepen -Date: Wed Nov 22 19:14:09 2000 +0000 - - - Write pidfile AFTER detaching... - - Minor cleanups - -commit f8b4a000d008082e5c7e511a49318b8dea8fd08d -Author: Guus Sliepen -Date: Wed Nov 22 18:54:08 2000 +0000 - - - Cleaned up and checked for some more NULL pointers in rbl.c - - Two connection lists: one for incoming connections, sorted on ip/port, - one for connections whose identity we know, sorted on id ofcourse... - -commit 785684f0ec5c9250788b4b32c0eab3f358c9db61 -Author: Ivo Timmermans -Date: Wed Nov 22 17:49:16 2000 +0000 - - Declare fd. - -commit e42255ae1374fe65e92de72de4508a84bdb91fa1 -Author: Ivo Timmermans -Date: Wed Nov 22 17:48:15 2000 +0000 - - Add more checks to ensure that filedescriptors are right in - _execute_script(). - -commit 2ed68134047a19e708c2a2af32c58968835a7043 -Author: Ivo Timmermans -Date: Wed Nov 22 16:19:07 2000 +0000 - - Honor the --localstatedir option to configure, instead of hardcoded /var. - -commit 9e9e1925b901dff87518f0e1534a33e48eab8303 -Author: Guus Sliepen -Date: Tue Nov 21 09:13:59 2000 +0000 - - - Check for NULL tree->delete callback - - Add xstrdup() function - -commit da9a1e8084a9b73306bdbc541ee8af938c3e7754 -Author: Guus Sliepen -Date: Mon Nov 20 23:29:47 2000 +0000 - - - More fixes. - -commit 3a6200c1e39b61b249db3d1f9bcffa77351863bd -Author: Guus Sliepen -Date: Mon Nov 20 22:13:14 2000 +0000 - - - Various small fixes. - -commit 06afd357b0cf4aab778b1ccabbd1be61a9500d10 -Author: Ivo Timmermans -Date: Mon Nov 20 19:56:01 2000 +0000 - - Get rid of all libtool references at once. libtool was only used by - libblowfish, which was superseded by openssl. - -commit 1857b3c97c261dda9978a67d07b315bb3ca68841 -Author: Guus Sliepen -Date: Mon Nov 20 19:41:13 2000 +0000 - - - Proper initialization of rbltree structures. - -commit 408ca91766088b6c2d38e198b0692bf394b41248 -Author: Guus Sliepen -Date: Mon Nov 20 19:12:17 2000 +0000 - - - Integrate rbl trees into tinc. - -commit 9024e01ce649b89d304a4aa5b1d6ef0b56b5a12c -Author: Ivo Timmermans -Date: Mon Nov 20 18:06:17 2000 +0000 - - Also include process.h - -commit 3cc063d23a6e3a23fd01f03b0bc99825c2b13e16 -Author: Ivo Timmermans -Date: Mon Nov 20 18:05:34 2000 +0000 - - More function and header checks - -commit 59aa15d3d1db4e948113f202dd2183f4bb23970d -Author: Ivo Timmermans -Date: Mon Nov 20 18:02:15 2000 +0000 - - Added this release - -commit 8f273f0ee265c75dd8eea65b2f1cd60a79691cd6 -Author: Guus Sliepen -Date: Sun Nov 19 22:12:46 2000 +0000 - - - Small fixes - -commit cc7c078774db955cece9b263022e6c1ca955fc10 -Author: Guus Sliepen -Date: Sun Nov 19 11:05:59 2000 +0000 - - - Deletion also works now. - -commit 3526f1e151b7a189f075d88c9d88cacaece31d02 -Author: Guus Sliepen -Date: Sun Nov 19 02:04:29 2000 +0000 - - - Fixed a lot of small things. Tested everything except deletions. - -commit 4f68e5b6133480478edba0959cb87d4eb149a8e7 -Author: Guus Sliepen -Date: Sat Nov 18 23:22:44 2000 +0000 - - - Fix tree head/tail upon insertion - -commit 880cd6f1a94ef76ebebc5bd96dd26d62e3d829f4 -Author: Guus Sliepen -Date: Sat Nov 18 23:21:01 2000 +0000 - - - Implemented deletions - - Added rbl_foreach() function - -commit 00e5d572621ad5f0263999dbfbfcb11e023bf48b -Author: Guus Sliepen -Date: Sat Nov 18 18:14:57 2000 +0000 - - - Fixed searching - - Insertion implemented - -commit 7fcc0c6415488ed6ce0089a67ab7cfdd5d0d83ca -Author: Guus Sliepen -Date: Fri Nov 17 10:03:02 2000 +0000 - - - Removed stray @INCLUDE@ (how did that get there?) - - Use 0 instead of FALSE - -commit 44cbd13e5248880b074b5068df14a4634204a1d3 -Author: Guus Sliepen -Date: Fri Nov 17 00:56:49 2000 +0000 - - - Simplified do_detach - -commit 2626c641aa714a8d776f1bb16340586d935aa6b1 -Author: Ivo Timmermans -Date: Thu Nov 16 22:13:09 2000 +0000 - - Use proper prototypes. - -commit 5d1145f2c4b3b8261ca0aa0e89a2daf321640f0b -Author: Ivo Timmermans -Date: Thu Nov 16 22:12:23 2000 +0000 - - Move more functions from tincd.c into process.c. - -commit 485f7a5043a4b3345bd02e5063502603550b4c76 -Author: Ivo Timmermans -Date: Thu Nov 16 22:11:40 2000 +0000 - - Delete struct ifr - -commit 30f34015ee11bbe1106c07e381288a702f12dac5 -Author: Ivo Timmermans -Date: Thu Nov 16 18:06:39 2000 +0000 - - New function: xmalloc_and_zero, which initialises the allocated memory - to all zeroes. - -commit 2764532ea72200d0a27ad2d79e6e299c00c62404 -Author: Ivo Timmermans -Date: Thu Nov 16 17:54:29 2000 +0000 - - Move all process-related functions into process.c. - -commit aa755206da4bcce3261ecd5dbfa41570a0155c73 -Author: Guus Sliepen -Date: Thu Nov 16 09:18:38 2000 +0000 - - - Added balanced tree management stuff as well. (It is not finished yet.) - -commit 7f87c3d9134612041d56180ea7fc3e6c37991f6b -Author: Ivo Timmermans -Date: Wed Nov 15 22:07:36 2000 +0000 - - Keep a list of running children, and in each loop in main_loop(), - check if one has exited. - -commit d9ce5a7f3f5eddb193b6a9b5974c7c49eac41ea1 -Author: Ivo Timmermans -Date: Wed Nov 15 22:04:48 2000 +0000 - - List management and manipulation routines. - -commit e118ba0a648000c48d6a401c9b9249a844d6dbcf -Author: Guus Sliepen -Date: Wed Nov 15 13:33:27 2000 +0000 - - Porting to FreeBSD: - - Reorganized and added some #includes - -commit 596e248bc588323cc7ee751286dbcaf677b5c653 -Author: Ivo Timmermans -Date: Wed Nov 15 01:28:21 2000 +0000 - - Let the output from an executed script in execute_script() go to - syslog, with proper error detection. - -commit bb2495e569fb161b42efd633eb1c471b8222b1fb -Author: Ivo Timmermans -Date: Wed Nov 15 01:06:13 2000 +0000 - - Use the HAVE_OPENSSL_xxx_H defined from m4/openssl.m4 during - configure. - -commit 6fb4a5b6be5628ece9b391b46e7858fdf5957a80 -Author: Ivo Timmermans -Date: Wed Nov 15 01:02:30 2000 +0000 - - Also check for sha.h. - -commit 8eb60d0ccde2f1de6fd917db7300e537f271783e -Author: Ivo Timmermans -Date: Wed Nov 15 00:57:26 2000 +0000 - - Also check for rand.h and err.h. If any of these files does not - exist, try the next alternative path. - -commit c5c8e99afd3fae3868f20b5c7a4f8754498b39ad -Author: Ivo Timmermans -Date: Tue Nov 14 23:18:19 2000 +0000 - - Get rid of the annoying empty line - -commit c467ee02d3ef8bed7ec2cc52cb1527ec60cdc93a -Author: Ivo Timmermans -Date: Tue Nov 14 23:02:08 2000 +0000 - - Oops, small error. - -commit 9ddb37cee0f754ef88a55f692a508010fe18c782 -Author: Ivo Timmermans -Date: Tue Nov 14 22:57:19 2000 +0000 - - Better checks for OpenSSL. I think it can now detect almost all conceivable installations. - -commit 72c3776d6ac103fa25d216c42847ecba3a4f58e5 -Author: Ivo Timmermans -Date: Mon Nov 13 22:29:22 2000 +0000 - - Identify version as 1.0pre4-cvs - -commit 5344832be1126967ff340cf6bd270a377bb8e487 -Author: Ivo Timmermans -Date: Mon Nov 13 22:01:27 2000 +0000 - - Add a check for openssl that accepts explicit file locations. - -commit 5b74909ea070fbd482340dc42193e33366a9dddb -Author: Ivo Timmermans -Date: Thu Nov 9 21:33:18 2000 +0000 - - Add prototype for destroy_queue - -commit 6e27618708233998db7e5886ed9afaa21bb9d938 -Author: Ivo Timmermans -Date: Thu Nov 9 21:29:58 2000 +0000 - - Updates, updates - -commit a91eae538d9cff8aed399a175c0bbc7d744cd22a -Author: Ivo Timmermans -Date: Thu Nov 9 20:59:35 2000 +0000 - - Bop version number to 1.0pre3-1 - -commit e65a93053cca3f8aebf63094cf160835c3108e25 -Author: Ivo Timmermans -Date: Thu Nov 9 20:42:16 2000 +0000 - - Wrapped text to 70 (72?) columns for easy reading - -commit 4310b17be9cefcc1814ddef471e4c5cd8f9f867e -Author: Ivo Timmermans -Date: Thu Nov 9 20:41:13 2000 +0000 - - Final release notes added, also edited release notes for 1.0pre2 to what the announcement on the mailing list looked like. - -commit 16847ea255fa8a7c0ed922af80a2f36b7bdf4b3b -Author: Guus Sliepen -Date: Wed Nov 8 20:52:37 2000 +0000 - - - Make checkpoint tracing a compile time option (off by default) - -commit 55d7b5a2bb1df6f55f0a93e9cfed77c1da337588 -Author: Guus Sliepen -Date: Wed Nov 8 18:05:06 2000 +0000 - - - Add Jamie :) - -commit 5055e1dedc9fe984c497448c1b2ffc4afdf18aa3 -Author: Guus Sliepen -Date: Wed Nov 8 17:56:34 2000 +0000 - - - Applied Jamie Brigg's patch (close sockets after error) - -commit 74326df7adc514798565df0a8719421adbb5fef3 -Author: Guus Sliepen -Date: Wed Nov 8 00:20:06 2000 +0000 - - - Fixed --config - - Show warning when both netname and config directory are given. - -commit f8f1007bf469d44480d95d0d78ddc156d00e059f -Author: Guus Sliepen -Date: Wed Nov 8 00:10:50 2000 +0000 - - Porting to SunOS 5.8: - - More #includes Linux doesn't seem to need - - Don't do unsetenv() on SunOS - - Use a replacement asprintf() in case the OS doesn't support it - It now compiles properly under SunOS. - -commit 56bd0864e4c5680fee59af48228b1ec3fb97b57b -Author: Guus Sliepen -Date: Tue Nov 7 22:33:33 2000 +0000 - - Porting to SunOS 5.8: - - Include all header files necessary - - Check for flock() function - -commit 7d0f82bd4b7044a5151835e25e830fd28dfaaebd -Author: Guus Sliepen -Date: Tue Nov 7 22:02:14 2000 +0000 - - - Open UDP connection for all known hosts. Comments please. - -commit f95cc86d0c14ca4c47e5459af4bb6d1170baa9f5 -Author: Guus Sliepen -Date: Tue Nov 7 21:43:28 2000 +0000 - - Changed execution of tinc-up: - - Do not free() strings that have been putenv()d, see man page of the - latter. - - Do not set IFNAME anymore, it appears that the ioctl to get the name of - the interface does not work at all. Since it is set to NETNAME in case - of tun/tap and it is known beforehand in case of ethertap, there is no - need for it anyway... (though it would've simplified things). - -commit efc3a2a466937da942afc84dde080ba8b1731140 -Author: Ivo Timmermans -Date: Sun Nov 5 02:19:58 2000 +0000 - - Build-Depends on gettext - -commit 698191fd2f512f3618e2d60592fcd57cd750b965 -Author: Guus Sliepen -Date: Sat Nov 4 22:57:33 2000 +0000 - - - Prepended config_ to all configuration option names, because it confused - everything (including myself). - - Use connection oriented UDP sockets for both incoming and outgoing - packets. - -commit afc05797077641baa33b024ffeaafd6cad3ff7a7 -Author: Guus Sliepen -Date: Sat Nov 4 20:44:28 2000 +0000 - - - Simplified ping mechanism. - -commit 2191d894bfd615e8fa7857d031ea630edc12a854 -Author: Ivo Timmermans -Date: Sat Nov 4 17:29:45 2000 +0000 - - Build-depends on libtool - -commit 5019dd879177b5ab9413e5c0aa72a15d0e585acf -Author: Guus Sliepen -Date: Sat Nov 4 17:09:10 2000 +0000 - - - Check for packets that are looping back. - -commit 20dd5aff4d2898d8b59f371671cc110b870fa09c -Author: Ivo Timmermans -Date: Sat Nov 4 17:04:17 2000 +0000 - - Updated Dutch translation - -commit 3f177e9bf02b6121055414a2cc7fd3f4cff01cba -Author: Ivo Timmermans -Date: Sat Nov 4 17:01:55 2000 +0000 - - Add route.c to the list of source files. - -commit ac47586552710425417ed80878f8f853c313b421 -Author: Guus Sliepen -Date: Sat Nov 4 16:54:21 2000 +0000 - - - Forward keys in hex notation, not as binary data. - -commit 3f8f067e8b559366b9b41dee6a4312702c82042f -Author: Guus Sliepen -Date: Sat Nov 4 16:39:19 2000 +0000 - - - Don't forget to set packet cipher for added hosts. - -commit 433858d410c1fedf8d2a5f2b4ecd7c980dd79dd2 -Author: Guus Sliepen -Date: Sat Nov 4 15:34:07 2000 +0000 - - - connlist.c added to translation - -commit 15246df85d6171c92478541a835effb96d6085c4 -Author: Ivo Timmermans -Date: Sat Nov 4 15:32:05 2000 +0000 - - In execute_script: - - add an environment variable NETNAME. - - chdir to the configuration directory before execing the script. - -commit 69618c01385eb7226cd6eab0918d1f30b0ed6c66 -Author: Ivo Timmermans -Date: Sat Nov 4 15:18:58 2000 +0000 - - Do not include the passphrases directory - -commit 417f36a07990ff9bc7de7d4e63e57146bef0dd75 -Author: Guus Sliepen -Date: Sat Nov 4 15:17:02 2000 +0000 - - - Removed manpage for no longer existing genauth. - -commit 3d7189a444fe3efed58dc93a071129007041aebf -Author: Guus Sliepen -Date: Sat Nov 4 14:52:40 2000 +0000 - - - Resolve scriptname after fork() - -commit d38772ebc42f5ad1d946ee89d955f5d43bb2fe8c -Author: Ivo Timmermans -Date: Sat Nov 4 14:16:46 2000 +0000 - - Use putenv() instead of clumsy do-it-yourself in execute_script. - -commit f83803c1bf6557d5af93982e7cd987e151eba401 -Author: Ivo Timmermans -Date: Sat Nov 4 13:25:15 2000 +0000 - - Small change to the way the environment is copied. - -commit ed0bf283e37642f9f7673f664713a16d916bd70f -Author: Guus Sliepen -Date: Sat Nov 4 11:49:58 2000 +0000 - - - Removed even more warnings. - -commit dc699f8b1265deb7606d553e36326527dbd29746 -Author: Guus Sliepen -Date: Sat Nov 4 10:37:27 2000 +0000 - - - Removed unused MAC strip/add functions. - -commit 5065ea32c32e27478d93c00a1bba0c812b7a2b8c -Author: Ivo Timmermans -Date: Fri Nov 3 22:35:12 2000 +0000 - - Warnings removal pass: always include config.h first; add a few - prototypes in the header files. - - This also fixes a few lint errors/warnings. - -commit 73aa7fbf7e1b623398d1bc1493f567ce4d846f22 -Author: Ivo Timmermans -Date: Fri Nov 3 22:33:16 2000 +0000 - - Run the scripts tinc-up and tinc-down from a separate function, which - sets the environment as it should be and checks for errors. - -commit 4ad1e382d6f10acf94ce59d85b80925cee7553a6 -Author: Ivo Timmermans -Date: Fri Nov 3 22:31:55 2000 +0000 - - Save the environment on startup. - -commit 7612c6da3890ce5a0730e4dfde9d5ba07bdbf5b3 -Author: Ivo Timmermans -Date: Thu Nov 2 23:02:49 2000 +0000 - - Minor cosmetic change. - -commit 6a10e42f734e8bec9848a11e73bc2a8211a9f401 -Author: Ivo Timmermans -Date: Thu Nov 2 22:51:16 2000 +0000 - - - If necessary, patch po/Makefile.in from po-Makefile.in.in.diff to - get DESTDIR installation (required to get locales installed - correctly). - - Use dh_perl to get accurate perl dependencies. - -commit ef12849c1a03b3aaf85dd46786d6631f66b104bd -Author: Ivo Timmermans -Date: Thu Nov 2 22:11:18 2000 +0000 - - Oops, and include doc-base.tinc (new file). - -commit 5672ddd6cb9116420a1904f7741fdbed89c2ec54 -Author: Ivo Timmermans -Date: Thu Nov 2 22:10:09 2000 +0000 - - Don't include shlibs, as it no longer exists. - -commit 013fcb0e9f9c0222f4f63ddf42a2f25bfc4a5546 -Author: Ivo Timmermans -Date: Thu Nov 2 22:05:36 2000 +0000 - - Changed a few messages wrt. system calls; updated and changed the Dutch translation a bit. - -commit c444305c0bb965aa515a503406844ceeb483c285 -Author: Ivo Timmermans -Date: Thu Nov 2 21:43:03 2000 +0000 - - Mention fileutils, add a pointer to THANKS for more details - -commit 84c842def74c5d0e9c4a69e4f584fe9eb66eb728 -Author: Ivo Timmermans -Date: Thu Nov 2 21:41:53 2000 +0000 - - Change wsl to Wessel's name and email address in the ChangeLog creation - -commit 5b6815751e581bedd64bfc63aea5b42c746bbceb -Author: Ivo Timmermans -Date: Thu Nov 2 21:40:33 2000 +0000 - - More exhaustive list of changes - perhaps it can be worded differently? - -commit e954fc8f0c731e7116fd27f38c176b83cca519f7 -Author: Ivo Timmermans -Date: Thu Nov 2 21:39:57 2000 +0000 - - Changed `I' to `We' - small change, lots of difference :) - -commit 3db3a41667f90ce74bfd0197fc867cc71a087e50 -Author: Ivo Timmermans -Date: Thu Nov 2 21:38:55 2000 +0000 - - Only check for linux/if_tun.h once - -commit 1b11bcb0128ca65580cbf28ffb16078c81e6d678 -Author: Ivo Timmermans -Date: Thu Nov 2 21:34:45 2000 +0000 - - Added a perl example to turn an IP address into a MAC address. - -commit cadf81fe67aed424504758865c2ea2bb263c76fb -Author: Ivo Timmermans -Date: Thu Nov 2 21:26:51 2000 +0000 - - Do not include $(top_srcdir)/cipher, it does no longer exist. - -commit fd32d771a84765281ea4ab8a5d9dbf5cebfa2911 -Author: Ivo Timmermans -Date: Thu Nov 2 20:29:03 2000 +0000 - - - Synchronized changelog with the package's changelog. - - Changed maintainer email address. - - New file doc-base.tinc. - - Better Build-Depends and Depends lines. - -commit a13d9c9da7434154b33e666c2236844011b87d46 -Author: Ivo Timmermans -Date: Thu Nov 2 20:25:35 2000 +0000 - - This file is no longer needed. - -commit 59528ec892e8b9a599f2b39bf432a3d842e963fe -Author: Guus Sliepen -Date: Tue Oct 31 16:22:49 2000 +0000 - - Removed config file parsing and interface setup. This will be handled by - the tinc-up and tinc-down scripts from now on. - -commit af565d00220b7536b9987c48e2a71459b45027b4 -Author: Guus Sliepen -Date: Tue Oct 31 16:10:17 2000 +0000 - - - Update. - -commit b4c1d4e2d3287acd7ca438455c64e50a2828ad24 -Author: Guus Sliepen -Date: Mon Oct 30 10:19:06 2000 +0000 - - - Fixed some spelling mistakes and terminology here and there. - -commit 4811afa073c871f2a52dfd5139bd0171046365eb -Author: Guus Sliepen -Date: Mon Oct 30 00:22:54 2000 +0000 - - - Small cleanups - - Updated dutch translation - - Updated man pages - -commit b7d4d4c17712e0bb9ee8bd497a2f525b79d5f40d -Author: Guus Sliepen -Date: Sun Oct 29 22:55:15 2000 +0000 - - - Finishing touch: encrypt the meta connections - -commit ec12269355f7979fdc0783dc15d109832f1e83cd -Author: Guus Sliepen -Date: Sun Oct 29 22:10:44 2000 +0000 - - - Use CFB mode for encrypting packets: it works and we don't need padding. - -commit cea3d8f3056d3c6aaaef473443240b8470c8ea2d -Author: Guus Sliepen -Date: Sun Oct 29 10:39:08 2000 +0000 - - - Small fixes - - Do proper key exchange - - Encrypt packets - it works, but there is something wrong with the MAC - header after decryption... - -commit 8fa9bc017d89b53798903df3fa98311067d4de90 -Author: Guus Sliepen -Date: Sun Oct 29 09:19:27 2000 +0000 - - - Removed old encr stuff - -commit a26d371d0df3bee1bdc6e9d7046e949ee29e6de7 -Author: Guus Sliepen -Date: Sun Oct 29 02:07:41 2000 +0000 - - - Updated dutch translation. - - Shutdown properly. - -commit e8391bd49975aa29fa62d6ae1d2d2ee398e0eb3e -Author: Guus Sliepen -Date: Sun Oct 29 01:27:23 2000 +0000 - - - Moved connlist stuff to the proper header file. - -commit 2689690dc37c384c4a022d03ab80f2cfb7fb9553 -Author: Guus Sliepen -Date: Sun Oct 29 01:08:09 2000 +0000 - - - Enforce correct order of authentication requests - -commit 3b9802a542f1fa439321d3386763ec33989194b5 -Author: Guus Sliepen -Date: Sun Oct 29 00:46:43 2000 +0000 - - - Hit people who can't figure out subnet address/mask pairs with a - (clue)bat. - -commit 7398002ade1397bd857953f009f4aed65ffc9218 -Author: Guus Sliepen -Date: Sun Oct 29 00:24:31 2000 +0000 - - - Fixed ans_key_h - - Removed tapsubnet configuration option. - -commit 35932fe6c8cb481eb687f98424776ce429570c21 -Author: Guus Sliepen -Date: Sun Oct 29 00:02:20 2000 +0000 - - - Very big cleanup. - -commit db21f015161aac244ec5600c4d0ff685549892c2 -Author: Guus Sliepen -Date: Sat Oct 28 21:52:22 2000 +0000 - - - Override destination ethernet address on incoming packets with - FE:FD:00:00:00:00 - -commit 8738c007b15eea024bc4ca6ee0f972b2f5bf259f -Author: Guus Sliepen -Date: Sat Oct 28 21:25:21 2000 +0000 - - - Fixed offsets when reading/writing from/to tap device - -commit f25868fd2b58bc0b350a5cfaf342480f28f804cf -Author: Guus Sliepen -Date: Sat Oct 28 21:05:20 2000 +0000 - - - Lots of small fixes - - Exchange subnets on acknowledgement of connection - - Do proper lookup when incoming packets from tap - - off-by-a small number-error when reading/sending tap packets - -commit ba6b8005ebe3a53877590c242ff581dc5dee5eae -Author: Ivo Timmermans -Date: Sat Oct 28 19:34:53 2000 +0000 - - Skip the check for Linux kernel sources - -commit d47d5932a3bbc4940aa6453ebfe617ef330783c8 -Author: Guus Sliepen -Date: Sat Oct 28 16:41:40 2000 +0000 - - - Updated subnet list handling. Subnets are added to two lists now, the - owner's list and a global list. It is all fucked up but it probably - works anyway, good enough for pre3 :). - -commit 9c2f805255fa36b05e8fe9391f639581d938b653 -Author: Guus Sliepen -Date: Tue Oct 24 15:46:18 2000 +0000 - - - Lots of little stuff modified - - Succesfully reads in subnets from host config file now and adds them to - the list. - -commit 60401d99b18ae01d91ca65faf8d2b32fac2b4474 -Author: Ivo Timmermans -Date: Mon Oct 23 21:56:56 2000 +0000 - - Oops, echelon change committed to cabal... :) - -commit c46e84837d1c84a8590e0e3507227670368884a7 -Author: Guus Sliepen -Date: Mon Oct 23 13:52:54 2000 +0000 - - - route.c will contain the routing logic. - -commit 76d794eaf7c1664a47f4d0080fcd80e4a551740b -Author: Ivo Timmermans -Date: Sun Oct 22 13:47:41 2000 +0000 - - read_server_config: Check for result of read_config_file. - -commit 56d8e862409ae91c63a27968b01a48a94aafb205 -Author: Ivo Timmermans -Date: Sun Oct 22 13:37:15 2000 +0000 - - Include linux/sockios.h and net/if.h anyway, regardless of the value of HAVE_TUNTAP. - -commit 52b842f8076d507d3a6ea07045d085ae21d1aa10 -Author: Guus Sliepen -Date: Sat Oct 21 11:52:08 2000 +0000 - - - Fixed all debug levels. - - Seed PRNG before generating a challenge - - Strange thing in challenge decryption: it fails if first bit is set!? - -commit 73f7efddd723b25c1477ec1139dc7211307ff660 -Author: Guus Sliepen -Date: Fri Oct 20 19:46:58 2000 +0000 - - - Removed last reference to genauth from Makefile.am - - Tinc spawns tinc-up and tinc-down scripts which can be used to configure - the network device. The environment variable IFNAME is set to the name - of the interface. - -commit fba19c30c92d39e74f5fd5594053793b036f30f4 -Author: Guus Sliepen -Date: Fri Oct 20 16:49:20 2000 +0000 - - - Made Makefile.am stub for doc/es/ - - Merged genauth into tincd - - Updated dutch translation - -commit 97ec5685b92ea727fe8f8b4bb8cf289a20f8580b -Author: Ivo Timmermans -Date: Fri Oct 20 16:44:32 2000 +0000 - - Generalized list and hash handling functions - -commit 699e159a7a1711034f1d16d68ad1974a82e12dfc -Author: Ivo Timmermans -Date: Fri Oct 20 16:43:13 2000 +0000 - - New function: xalloc_and_zero() - -commit 4059151732afb7d8fb52121d80e54f2ee325d30e -Author: Ivo Timmermans -Date: Fri Oct 20 16:42:22 2000 +0000 - - Add all the new files to the sources list for the utility library - -commit 9f64499e40a95a8c05c82924219517aa017fc411 -Author: Guus Sliepen -Date: Fri Oct 20 15:34:38 2000 +0000 - - - tinc now really does public/private key encryption! It even works, whee! - -commit 71f05ff8956cb2e62181fcef763709b0de8faa68 -Author: Ivo Timmermans -Date: Thu Oct 19 20:56:49 2000 +0000 - - Generalized error handling functions - -commit 95f4e8620ef8e2cdec1cc3b2ccb8cc8e3ce94e40 -Author: Ivo Timmermans -Date: Thu Oct 19 20:39:04 2000 +0000 - - Add check for the syslog function - -commit 430e14162918864f9f18aad0ec0badc1ccc3e01f -Author: Ivo Timmermans -Date: Thu Oct 19 17:29:22 2000 +0000 - - Changed changelog - -commit d5fd1344e668da0bc8536e798f347041d5377843 -Author: Guus Sliepen -Date: Thu Oct 19 14:42:00 2000 +0000 - - - Seed the PRNG using /dev/random before generating the keys. - -commit 30df5e95dbe585c6076d743d3771a42ad7c78590 -Author: Ivo Timmermans -Date: Wed Oct 18 20:12:10 2000 +0000 - - Bring head revision up to date with cabal (try #3) - -commit 571cfb5846c710a0a3cdbdddce8936f6b34f1cf1 -Author: Ivo Timmermans -Date: Wed Oct 18 19:44:11 2000 +0000 - - Get the head revision up to date with cabal - -commit e75315dae609f32041ca5ed939fd2a1b69d32d3e -Author: Ivo Timmermans -Date: Tue Oct 17 10:15:20 2000 +0000 - - Don't declare cp_file and cp_line in xmalloc() - -commit 31c543ad0fa1d19667a03a9bd183c668def23da0 -Author: Ivo Timmermans -Date: Tue Oct 17 10:14:25 2000 +0000 - - Process subdir es/ - -commit 20301888b7a0a206119d2cfc48ccf1a667bb4add -Author: Guus Sliepen -Date: Mon Oct 16 19:04:47 2000 +0000 - - - More fixing. Tinc daemons can now even create activated connections. - -commit bb3d18d56fa0dd2bc5146d0a0044b6ef0880bdb4 -Author: Guus Sliepen -Date: Mon Oct 16 16:33:30 2000 +0000 - - - Fixing little things - - Two tinc daemons can connect to eachother now (but they disconnect right - after the ACKs). - -commit 6e32b870ee127555888a115163922362c99009f9 -Author: Ivo Timmermans -Date: Mon Oct 16 11:35:10 2000 +0000 - - Output doc/es/Makefile - -commit baeac83bf465a47d46082e1de40ea14dcf1d39af -Author: Guus Sliepen -Date: Sun Oct 15 20:30:39 2000 +0000 - - Corrected #ifdefs for tun/tap support. - -commit 782171fd2c59b7cc5568d2d4b33ce041834710ec -Author: Ivo Timmermans -Date: Sun Oct 15 20:21:27 2000 +0000 - - Really #include the if_tun.h files now - -commit 8a54c51238672abd7a72c1dbdc7d17b9956a0d35 -Author: Ivo Timmermans -Date: Sun Oct 15 20:13:55 2000 +0000 - - Linearized checks for if_tun.h - -commit e5130495d7d4083d58ab76c26001aa27f5fc13db -Author: Ivo Timmermans -Date: Sun Oct 15 19:53:15 2000 +0000 - - Wrap the tun/tap code in #ifdef HAVE_TUNTAP - -commit 3b455b8f318528206b08121f5ce93d16e4ea01df -Author: Ivo Timmermans -Date: Sun Oct 15 17:26:31 2000 +0000 - - Add checks for the presence of the universal tun/tap device driver. - -commit 85adeef21275633b78a234b2660cbe3bc9dd2c33 -Author: Guus Sliepen -Date: Sun Oct 15 00:59:37 2000 +0000 - - - The daemon actually runs now (somewhat) - - Added support for tun/tap driver (autodetect!) - - More sophisticated checkpoint functionality - - Updated dutch translation - -commit 97ce045189e330e121873d1b4be1959c60062cbb -Author: Ivo Timmermans -Date: Sat Oct 14 22:22:06 2000 +0000 - - Add CVS id lines - -commit 2e159d0139e77041ad82e96bf0abef6aaf64a258 -Author: Ivo Timmermans -Date: Sat Oct 14 22:17:29 2000 +0000 - - Fix `Requirements'-section for GMP and OpenSSL libraries. - -commit 1d5bb49f261b4346b5a440ae6bbf58fe391ea46e -Author: Ivo Timmermans -Date: Sat Oct 14 22:00:09 2000 +0000 - - Update Depends lines to reflect the dependencies on OpenSSL - -commit e9635ae38e0e2e3eb92568a1e234f8348856dd69 -Author: Guus Sliepen -Date: Sat Oct 14 17:04:16 2000 +0000 - - - Second fixing-things pass: it even links now. - - Lots of FIXME comments added to the source code. - -commit 6a8c2e346e6125e58aab428e6730c18a949abe12 -Author: Ivo Timmermans -Date: Fri Oct 13 23:34:56 2000 +0000 - - Don't look for GMP header files - -commit f18e30dab3c208fd353af11e365791035534f444 -Author: Ivo Timmermans -Date: Fri Oct 13 23:30:11 2000 +0000 - - Updated new requirements, pointers to the manual - -commit a96f2f0fc8a02593d4cda5976df3c76fc5c99eae -Author: Ivo Timmermans -Date: Fri Oct 13 23:29:35 2000 +0000 - - Link with OpenSSL, forget libGMP - -commit 183a8edd22ba4bc682392c73ae02fc9e121eda68 -Author: Guus Sliepen -Date: Wed Oct 11 22:01:02 2000 +0000 - - - Fixing-things pass: every source file compiles into an object file now, - but linking tincd does not work yet (must link with openssl libs and - define some missing functions). - -commit 6e39481d8f2406e60b5e329ace08b5a005d5cc43 -Author: Guus Sliepen -Date: Wed Oct 11 13:42:52 2000 +0000 - - - Generalized config file parsing to support multiple configuration trees. - -commit 451e9e3e7a968151de541de68603a01f0922b415 -Author: Guus Sliepen -Date: Wed Oct 11 12:07:27 2000 +0000 - - - Changed genauth to produce rsa keypairs instead of random passphrases. - -commit 950fb8e916b0e248dcaa72c96859acd6046683aa -Author: Guus Sliepen -Date: Wed Oct 11 10:35:17 2000 +0000 - - Big and bad commit of my current tree... - - Added seperate file for connection list handling - - Updating everything to use connlist, meta and subnet files - - Removed dependency on libgmp - - Lots of other stuff... - -commit 73d0dcfcc1019ee745a422982b4e3ede9d59dd91 -Author: Guus Sliepen -Date: Wed Oct 4 15:09:57 2000 +0000 - - Removing cipher directory (all will be covered by OpenSSL). - -commit 2228b16159a7aff64e6559ee1635716154e67fe6 -Author: Guus Sliepen -Date: Sun Oct 1 03:21:49 2000 +0000 - - - Added subnet handling code - - Other small changes to header files - -commit 676b1c0ea111406eb94a74ae12878dfd5ad9f56d -Author: Ivo Timmermans -Date: Wed Sep 27 20:32:29 2000 +0000 - - Many updates, parts rewritten, added, shuffled around. - -commit c78a204f06182f50b0812c8e4fef6163e82097bf -Author: Guus Sliepen -Date: Tue Sep 26 14:06:11 2000 +0000 - - - Added meta.c which contains functions to send, receive and broadcast - metadata. It will also handle encryption and decryption, and possibly - compression and checksumming. - - Moved request dispatcher to protocol.c. - -commit 2c412009e5805f04c650889b19fcb38531f2aa50 -Author: Guus Sliepen -Date: Mon Sep 25 20:08:50 2000 +0000 - - - Very detailed example of the authentication phase. - -commit 361690b18c1f5464db7b9cef235c648784780dfb -Author: Guus Sliepen -Date: Fri Sep 22 16:20:07 2000 +0000 - - - Removed options "string" stuff. It was a bad idea... - - free() everything that is allocated. - -commit 5afc1e98f436c4a2ed5da4b64293275b09632c79 -Author: Guus Sliepen -Date: Fri Sep 22 15:06:28 2000 +0000 - - - Severe code reduction and simplification of challenge requests - - "Finished" [add|del]_subnet_h - - Added lots of sanity checks to [add|del]_host_h - -commit 5d0b3516d5e8a46ca2268bdb32657b72295501ec -Author: Guus Sliepen -Date: Sun Sep 17 21:42:05 2000 +0000 - - - Updated authentication scheme. - - Removed all trailing spaces from all lines. - - Added things to add_ and del_subnet_h. - -commit 84f210edd9e72a65ca8b034a0d3bbc12e506c580 -Author: Guus Sliepen -Date: Sun Sep 17 20:11:59 2000 +0000 - - - Included authentication scheme from protocol.c - - Added a few comments about the symmetric cipher. - -commit 2863134a4113b7805a662f45a21a1be0ae9606cb -Author: Guus Sliepen -Date: Sun Sep 17 19:57:39 2000 +0000 - - Added document about the used cryptographic algorithms and the reasons - behind them. Feel very free to comment on this! - -commit 33a5b4547141c11b5128d9f4863fcf6cf8e33452 -Author: Ivo Timmermans -Date: Sun Sep 17 10:28:57 2000 +0000 - - Added Spanish translation of the docs by Matias Carrasco - -commit 7f3ab38c222809b15da2fe8dd655d35432eaafe0 -Author: Ivo Timmermans -Date: Fri Sep 15 12:58:40 2000 +0000 - - Second round of fixes - -commit ed397b6ac676329b237e219c806143cccf456b3c -Author: Ivo Timmermans -Date: Thu Sep 14 21:51:21 2000 +0000 - - First round of needed fixes after the overhaul - -commit 296171d115614d61480d896cd77898f5393c191d -Author: Ivo Timmermans -Date: Thu Sep 14 14:34:38 2000 +0000 - - New directive: Name. - -commit d335c6d0d7328fd86154dc60b22deb7953ab0228 -Author: Ivo Timmermans -Date: Thu Sep 14 14:32:34 2000 +0000 - - Added some structures and types that are needed for the overhaul. - -commit c04c84c98055c6b9e9e7890d3992648a3b715a1a -Author: Guus Sliepen -Date: Thu Sep 14 11:54:51 2000 +0000 - - - Lots of small changes. - -commit cd6695df82c55454a3f5b644f5c20a8ed31e7c97 -Author: Ivo Timmermans -Date: Mon Sep 11 11:40:46 2000 +0000 - - Better checks for SunOS libraries - -commit 9c75350ac6c14886195b6d368af2f118fd5d60e0 -Author: Guus Sliepen -Date: Mon Sep 11 10:05:35 2000 +0000 - - - Fixed modulo in keylength check - - Updated header file to reflect new protocol code - -commit 76b5f255c6cb0c5dfb5a870c371ec6f7c7879bb2 -Author: Guus Sliepen -Date: Sun Sep 10 23:11:37 2000 +0000 - - - Some key exchange stuff. (Last commit before going to bed.) - -commit 675ed08a71ec28d8ae99e10e993d5c7cb717f017 -Author: Guus Sliepen -Date: Sun Sep 10 22:49:46 2000 +0000 - - - Lots of functions added for the new protocol. - -commit 9926dae4646a96ee647a2ca7d728e91600dd1cca -Author: Ivo Timmermans -Date: Sun Sep 10 21:57:11 2000 +0000 - - Add Guus' name and shift out old protocol requests - -commit 74157d3f4501f4d1ec913a986b7167d2b847e41e -Author: Ivo Timmermans -Date: Sun Sep 10 18:37:46 2000 +0000 - - Correct filenames for passphrases given in the example - -commit 6b9ec9ed1e818d5e50dda4418ffb4d02c898bcba -Author: Guus Sliepen -Date: Sun Sep 10 16:15:35 2000 +0000 - - - Added more function skeletons for the new protocol. - -commit 28cc30159565a7eda4f66215a5994d84b46b47ad -Author: Guus Sliepen -Date: Sun Sep 10 15:18:03 2000 +0000 - - - New protocol. Will break everything else for now. - -commit 7884d3ecaf78006b3f288d99f10ef541fc97087e -Author: Ivo Timmermans -Date: Sun Sep 10 15:16:07 2000 +0000 - - Support for -lsocket and -lnsl on SunOS - -commit 14554e6f421e881b01be20879e9279545f375154 -Author: Ivo Timmermans -Date: Sun Sep 10 15:15:38 2000 +0000 - - Include openssl/blowfish.h - -commit 45ea3ca432a031ff1b8072d934709aadaae12534 -Author: Ivo Timmermans -Date: Sun Sep 10 15:07:41 2000 +0000 - - Updated text, removed protocol flowchart - -commit ae17572e6b94c6e7a2123ddeb45bf66d389ac7a0 -Author: Ivo Timmermans -Date: Sun Sep 10 15:05:45 2000 +0000 - - Link with OpenSSL crypto libraries instead of own blowfish library - -commit 4dde583bc91985c3ff19ac1d1f1bc791b50658ff -Author: Guus Sliepen -Date: Wed Sep 6 11:49:05 2000 +0000 - - - Use strerror() instead of sys_errlist[] for increased portability - (Needed for SunOS) - -commit 66e535a729dd5a9e45600ab74dc19c2b4062ee96 -Author: Ivo Timmermans -Date: Sun Aug 27 11:05:47 2000 +0000 - - Changed CVSROOT path in `make ChangeLog' - -commit 39e159fbe6bbffb3229542258f956fc412bd871c -Author: Guus Sliepen -Date: Tue Aug 22 14:55:04 2000 +0000 - - Fix rules (thanks to Laurence) - -commit 47992fe59f4c1b4116e4872d59251b143edc6763 -Author: Ivo Timmermans -Date: Mon Aug 21 20:35:47 2000 +0000 - - Added a rule to create an rpm - -commit d9af4f32330a495789d8eecdabbbb49928f074a7 -Author: Guus Sliepen -Date: Mon Aug 21 12:50:15 2000 +0000 - - Updated tinc.conf manual. - -commit 94a32c4b2d2ff5d4bb1376fe5ec96c6dec55f630 -Author: Ivo Timmermans -Date: Sun Aug 20 23:08:17 2000 +0000 - - Also chomp $VPNMASK - -commit 861e808fef1f6796d837215f9ad135fb4cb50f5c -Author: Ivo Timmermans -Date: Sun Aug 20 23:07:18 2000 +0000 - - (Quoting Laurence Lane:) - - The prefix is correctly set for /usr, but is - overridden with the current make install. DESTDIR is the clean way to - relocate the installation into the debian/tmp build dir. - -commit d3f41b803bf3c38910f24f1f268f182466723149 -Author: Guus Sliepen -Date: Fri Aug 18 14:45:38 2000 +0000 - - Updated the manual: - - incorporated comments from Stefan Hartsuiker - - updated configuration variables section - - added some text about key types - -commit 5c78e158d414595ab32399645678a43bb4469be6 -Author: Guus Sliepen -Date: Fri Aug 18 11:17:09 2000 +0000 - - Commented on some size calculations. - -commit d2c062a0a440d2871939b4ffdc2dbb137a4d45e7 -Author: Guus Sliepen -Date: Thu Aug 17 17:22:01 2000 +0000 - - Ran update-po and updated dutch translation. - -commit 3831f51a53088bfcc1d148fd54b3083afe7fde32 -Author: Guus Sliepen -Date: Thu Aug 17 16:51:08 2000 +0000 - - Fixed all sprintf() spl01ts. - -commit 9acd4379f705edc8b736e21b9011434e63f7dd95 -Author: Guus Sliepen -Date: Wed Aug 9 14:02:16 2000 +0000 - - - Added two extra configuration options, Interface and InterfaceIP, to - bind the listen socket to a network device or a specific IP. - -commit f6d79366b3efaef0a458717aac5e6754630dd434 -Author: Guus Sliepen -Date: Wed Aug 9 09:34:21 2000 +0000 - - - Reinstated O_NONBLOCK for meta socket - - Set SO_KEEPALIVE on meta socket - -commit 3cfc9424f255c26f2a7775b6fa059f1e3e47a76e -Author: Guus Sliepen -Date: Tue Aug 8 17:07:48 2000 +0000 - - - Moved TCP packet reception to meta handler: less kludgy and less buggy! - -commit e092d15be17db1d69c37f2aba46c66e03631c099 -Author: Guus Sliepen -Date: Tue Aug 8 14:54:57 2000 +0000 - - - Added date/time of build and protocol number to --version output. - -commit ff87f385c3a81499eff6b848aed8548cf6e5132e -Author: Guus Sliepen -Date: Tue Aug 8 13:47:57 2000 +0000 - - Removed calling add_queue for tcponly packets. - -commit ac73c72488dd8b33464fac1f392e89df48f7a23b -Author: Guus Sliepen -Date: Tue Aug 8 08:48:50 2000 +0000 - - Fixed PACKET read loop. - -commit b6997b0050e78a2f2e517beba3ff01d9232b3d1f -Author: Guus Sliepen -Date: Mon Aug 7 16:27:29 2000 +0000 - - - Lots o' buglets fixed (-Wall helps) - - Made TCPonly work :) - -commit fdc6a2f106315cd9ed22943d8c0bd279631e66b4 -Author: Guus Sliepen -Date: Mon Aug 7 14:52:16 2000 +0000 - - - Added experimental hackish tunneling-over-TCP support. - Just use TCPonly = true in the configuration file. - -commit 42455e97a057fb4386f9d8fb2f8963b2ec6ddf24 -Author: Guus Sliepen -Date: Sun Jul 2 13:40:57 2000 +0000 - - - Fixed typo. - -commit b1ecbf977722ec473fc8007acd39eb0de581de1a -Author: Guus Sliepen -Date: Sun Jul 2 13:36:18 2000 +0000 - - - Delayed address resolving for ConnectTo lines in configuration file to - allow DynDNS to work without restarting tincd. - -commit 6642ec2ea4e97a2fb3e737653ab1b9351ac759e9 -Author: Guus Sliepen -Date: Sun Jul 2 12:48:04 2000 +0000 - - - Updated THANKS file - -commit e0de803c7e80621600409a0c760241a3d97617bd -Author: Ivo Timmermans -Date: Sun Jul 2 12:41:03 2000 +0000 - - Include the Spanish translation in the distribution/build process. - -commit 721d85f77277813345bdb63a610e984cec996613 -Author: Guus Sliepen -Date: Sun Jul 2 12:35:28 2000 +0000 - - - Added Spanish translation from Enrique Zanardi. - -commit e821a22876d15c921a4c1fbc0f792d83e90916f6 -Author: Guus Sliepen -Date: Sat Jul 1 14:40:56 2000 +0000 - - - Forgot to mention ourselves in the tincd manual page! :) - -commit 09f4ec190119298187cec09dd5049af8fd8bad94 -Author: Guus Sliepen -Date: Sat Jul 1 14:32:24 2000 +0000 - - - Updated PROTOCOL (a bit) - - Included a real tincd.8 describing the options, signals, debug levels - and files used by tincd. - -commit d3ea434b3684093d6d160b8077c1f51a50ac7f61 -Author: Ivo Timmermans -Date: Sat Jul 1 10:39:28 2000 +0000 - - Autogenerated by gettextize. - -commit 1b28f88808b9ac3193cf9a0db7a81a89eed8b4ef -Author: Guus Sliepen -Date: Sat Jul 1 07:49:21 2000 +0000 - - - Removed a single unused bit from status_bits_t. - -commit 7fdc881b86fe379216f09dd5703bb88d398c87a8 -Author: Wessel Dankers -Date: Sat Jul 1 07:29:32 2000 +0000 - - Added architecture section, made a start with the kernel section. - ToDo: install tinc myself to see if everything is as I say =) - -commit 8ec648abf438bb5fcfe84e3a1c6a31192dc32b2e -Author: Guus Sliepen -Date: Fri Jun 30 22:38:58 2000 +0000 - - - Added documentation for the protocols (most important the meta protocol) - used by tinc. - -commit ce72275a4342ff4e21d21bb740ee88dca1ddb5f1 -Author: Wessel Dankers -Date: Fri Jun 30 21:16:52 2000 +0000 - - Grrr, recommit - -commit bbbdda255d6e7a8730906a1b6c2bfdd2ce1b94cf -Author: Wessel Dankers -Date: Fri Jun 30 21:11:34 2000 +0000 - - This file is now only in the CABAL revision. - -commit 28a140668f892873b01afe104d21db4adb8fd8c7 -Author: Wessel Dankers -Date: Fri Jun 30 21:09:32 2000 +0000 - - More about keys - -commit 1a1ebefd572c18d6af187750847b024ce07551ae -Author: Guus Sliepen -Date: Fri Jun 30 21:03:51 2000 +0000 - - - Made tinc even more silent if no -d flag is given at all. - -commit 79ad21c392e56cad2556e7693b9639d8e2346a59 -Author: Wessel Dankers -Date: Fri Jun 30 20:57:30 2000 +0000 - - Added extra bit about keys. - -commit 8309e9b869c25677d674f5cecb8b7ac5469d1758 -Author: Wessel Dankers -Date: Fri Jun 30 20:50:47 2000 +0000 - - File added to CABAL (hopefully) - -commit 5cd0f940c7334959534d3ab4e1f3c7cac67ee38a -Author: Wessel Dankers -Date: Fri Jun 30 20:42:07 2000 +0000 - - added bit on config file, split up sections, added Id: tag - -commit 6f5aac4e39cd6fb2fb76c0121de3f3782f72f18e -Author: Wessel Dankers -Date: Fri Jun 30 20:16:15 2000 +0000 - - Initial revision. Lots of loose ends, not usable yet. - -commit c5737583c8a5d099a71174e1eb997e0972ae03e9 -Author: Guus Sliepen -Date: Fri Jun 30 12:41:06 2000 +0000 - - - Instead of logging an error when remote end closes the connection, - we print a nice message if appropiate debug level is set. - - If we get ADD_HOSTs or DEL_HOSTs for ourself, then connection lists - are really messed up. We restart, and hope our problems go away. - -commit 24874d0806bac5d75663ea9de67a71171bfc97b6 -Author: Guus Sliepen -Date: Fri Jun 30 11:45:16 2000 +0000 - - - Removed segfault bug in conf.c (must have been there for ages!) - - Made main_loop() signal proof - - #defined MAXTIMEOUT (15 minutes) - - If something really really bad happens, close all connections, wait - for MAXTIMEOUT seconds, and then restart tinc - -commit 0f9ad1f047efec53590dc43f07d225e5f20456cb -Author: Guus Sliepen -Date: Thu Jun 29 19:47:04 2000 +0000 - - - Fixed memory leak. - - Implemented SIGHUP configuration file reloading. - - Other small changes. - -commit 18c85caac36f7236454deef11b9eba74328dbd96 -Author: Guus Sliepen -Date: Thu Jun 29 17:09:08 2000 +0000 - - - New semantics for BASIC_INFO, ADD_HOST and DEL_HOST requests. This will - improve connection list consistency, ensures the tree property, and - allows for recovery from situations where track of connections is lost. - -commit e8e7379311ca3bf6e1fdd7d0f477a43e510e2317 -Author: Guus Sliepen -Date: Thu Jun 29 13:04:15 2000 +0000 - - - Removed all IP_ADDR_S macros, because gettext doesn't like them. Each - connection now has two hostnames: real_hostname (replacing the old), - and vpn_hostname. In those places where hostnames really aren't usefull - IP_ADDR_S has been replaced by %d.%d.%d.%d. - -commit e0ddb638d1fb7abf19969ac887f3b7a2bd8225c1 -Author: Guus Sliepen -Date: Thu Jun 29 07:11:23 2000 +0000 - - - Updated Dutch translation. - -commit 0a155580a3d55633bbc3a1e7dcbe8906f41913be -Author: Ivo Timmermans -Date: Wed Jun 28 21:06:40 2000 +0000 - - Oops, and mention Guus too. - -commit f2c9e7f3bbada3fbfe80f622ebc06540afb60c21 -Author: Ivo Timmermans -Date: Wed Jun 28 21:01:45 2000 +0000 - - Removed Free Software Foundation copyright, because Guus Sliepen contributed significantly. - -commit 3df9b89204626afdd514d5b7323801af76a5cd26 -Author: Guus Sliepen -Date: Wed Jun 28 14:34:40 2000 +0000 - - - Added log message when SIGCHLD is received ("thanks" to Ivo van Dong) - -commit 8c6c60adf3d5942c6368bafe9a4d4377ffad1abe -Author: Guus Sliepen -Date: Wed Jun 28 13:41:02 2000 +0000 - - - Fixed a message in nl.po - - Woops, we forgot to send our connection list to our uplink when we - connect to it... Fixed. - -commit 63c5192d570e2ba5952b4e5a807e4ab4d6fdad76 -Author: Guus Sliepen -Date: Wed Jun 28 11:39:40 2000 +0000 - - - Fixed missing " in nl.po - -commit ea40d3f1a05e9edf4ccfb77f4e9e0f8355e94a83 -Author: Guus Sliepen -Date: Wed Jun 28 11:38:01 2000 +0000 - - - Fixed some spelling errors. - - Paar zpelvautjes gerepareerd, en de Nederlandse vertaling weer bij de - tijd gebracht. - -commit dba2995db73313b1c0a56ce13395dac0bc7571a5 -Author: Guus Sliepen -Date: Wed Jun 28 10:11:10 2000 +0000 - - - Extra check op EINTR bij inlezen requests - -commit 4ee53e7dac93d1edad8664edffdfaf142438b85d -Author: Guus Sliepen -Date: Tue Jun 27 21:05:07 2000 +0000 - - - Fixes a silly little insignificant buglet. - -commit 070ad08118a33755835b31174e2b04e84f75556e -Author: Guus Sliepen -Date: Tue Jun 27 20:55:12 2000 +0000 - - - Purge old connections that are ADD_HOSTed. - -commit 4aeaea5e590fbd38aebbfacf2672304d04ba4ad1 -Author: Guus Sliepen -Date: Tue Jun 27 20:10:48 2000 +0000 - - - Improved handling of errors on connection attempts. - -commit 45a28b1e893d4da9d7977945a35ec6a8e4554830 -Author: Guus Sliepen -Date: Tue Jun 27 15:08:58 2000 +0000 - - - Fixed indirectdata=no problem - - Added support for multiple ConnectTo lines in tinc.conf. - -commit 4faed1b8546563def6a426c563cec2a26d927eda -Author: Guus Sliepen -Date: Tue Jun 27 12:58:04 2000 +0000 - - - Fixed KEY_CHANGED notification. A lot of notify_others() calls were - wrong (first two arguments swapped). Should probably be doublechecked. - - Don't retry to connect to hosts with different protocol versions. - -commit 04cb206298df033d254ca007205d13f9a670c402 -Author: Guus Sliepen -Date: Mon Jun 26 20:30:21 2000 +0000 - - - Moved all connection messages to debug level 1, without -d's only the - startup message will be logged. - - Fixed DEL_HOST rebound. - -commit 783c8298610d5670f6e118f49bd3d1fdfa61ae1d -Author: Guus Sliepen -Date: Mon Jun 26 19:39:34 2000 +0000 - - - Indirectdata finally REALLY REALLY works now! - - More precise debug messages - -commit b3681ebf6c255daf082ed254282cbf493af8fa93 -Author: Guus Sliepen -Date: Mon Jun 26 17:20:58 2000 +0000 - - Fixes some hostlookups. Fixes indirectdata for real now (hopefully). - -commit 03af6d8c8056d0b7006f7d8fb19bb33d303ac8f9 -Author: Ivo Timmermans -Date: Sun Jun 25 20:52:29 2000 +0000 - - Version 1.0pre3. - -commit a473ece8a0d83be5f7992888a6a3ff938dc4fb72 -Author: Guus Sliepen -Date: Sun Jun 25 16:39:17 2000 +0000 - - - More verbose connection list - - Added "myself" as hostname when logging indirect ADD_HOSTs - -commit f1f901112e44beaecd3037dae27407ea83edd86e -Author: Guus Sliepen -Date: Sun Jun 25 16:20:27 2000 +0000 - - Hostlookup() is actually being called now. - -commit 54079bdf03e74c686f556f86082b9d14b5be227c -Author: Guus Sliepen -Date: Sun Jun 25 16:01:12 2000 +0000 - - Hostnames are back! - -commit e4b586ed070908f866a450292f9759004e6affa8 -Author: Guus Sliepen -Date: Sun Jun 25 15:45:09 2000 +0000 - - - Log possible spoofing attacks. - - Don't broadcast DEL_HOSTs for hosts that haven't been activated yet. - - If a host sends a TERMREQ, deactivate them. - -commit 9a1103a7be86de3da5548fd6446e6e4fe554cc08 -Author: Ivo Timmermans -Date: Sun Jun 25 15:42:40 2000 +0000 - - Changed version number to 1.0pre3. - -commit d8d2b83350e890adae9c9cede6e21ea4169abe00 -Author: Ivo Timmermans -Date: Sun Jun 25 15:42:40 2000 +0000 - - Changed version number to 1.0pre3. - -commit 7648bc606596851942dd6437ddaa93f53ab20f09 -Author: Guus Sliepen -Date: Sun Jun 25 15:22:16 2000 +0000 - - Added CVS Id tags to header files. - -commit 7f7e158aae8df5c65211bcfa82516e7c243cdd2e -Author: Guus Sliepen -Date: Sun Jun 25 15:16:12 2000 +0000 - - Large cleanup: - - Removed hostname lookup (it blocks, and you can always do it yourself) - - Reorganized debug levels (after hints from Axel M�ller): - 0 Startup message and errors - 1 Connection logging - 2 Meta protocol information - 3 Verbose meta protocol (includes copy of transmitted requests) - 4 Packet information (logs transmission/errors of UDP packets) - 5 Verbose packet information (every single byte, not implemented yet - to protect ourselves from filling up /var/log directories) - - Made log messages more consistent - -commit 3c54a513b0c0a3acac60e03403ab4abfa0688c62 -Author: Guus Sliepen -Date: Sat Jun 24 12:35:42 2000 +0000 - - If we have "indirectdata" flag set, we only send data to our uplink. - -commit d8e2f7104c3203edbf23d2349656c765a4310dee -Author: Guus Sliepen -Date: Fri Jun 23 19:27:03 2000 +0000 - - First step for implementation of the "indirectdata" directive. This should - allow _leaf_ tincds to be behind firewalls. - The protocol has changed and is INCOMPATIBLE with previous versions. The - PROT_CURRENT value has been incremented. - -commit 33c3a25a66251606cbf20d3bd5b392d8837116e3 -Author: Ivo Timmermans -Date: Sat Jun 17 20:55:54 2000 +0000 - - Configuration directive `IndirectData'. - -commit 1c8adb5e1f12894fc9a478fbf29678fb662e03ab -Author: Ivo Timmermans -Date: Sat Jun 17 20:30:44 2000 +0000 - - Merge changes from 1.6-1.8. - -commit 0d167e1f5d8778674a9a77b2256050e3afe2896e -Author: Guus Sliepen -Date: Sat Jun 17 08:30:45 2000 +0000 - - Added another semicolon for bash2 compliance (thanks to Jamie Briggs) - -commit 00f316810aa808368cdff620b1a1efdd1fcade20 -Author: Guus Sliepen -Date: Fri Jun 16 05:44:26 2000 +0000 - - Applied patch from Jamie Briggs for bash2 conformance. - -commit ef294a69678bc7cba6d2ee0be96f683249672222 -Author: Ivo Timmermans -Date: Tue Jun 6 10:24:33 2000 +0000 - - Include ../intl in the include path, and add @INTLLIBS@ to the list of libraries. - -commit 66e98068051bc52fa064650710260f89c09f8cfd -Author: Ivo Timmermans -Date: Sun Jun 4 12:14:31 2000 +0000 - - These files are created by gettextize (run by autogen.sh) (should have known that). - -commit d1d4a524dee9d75b067ac8e25770557cf22f4afe -Author: Ivo Timmermans -Date: Sun Jun 4 11:50:46 2000 +0000 - - Check for __gmpz_powm for libgmp3. - -commit 377c4df245ceb8c19cabfe6d7a7c76841c07ba52 -Author: Ivo Timmermans -Date: Sat Jun 3 23:32:03 2000 +0000 - - Don't touch VPNMASK if it's defined, otherwise use $MSK. - -commit 9193aee8159ce53b349557ba1ad8ed23111042bb -Author: Guus Sliepen -Date: Sat Jun 3 08:27:16 2000 +0000 - - Removed items in TODO list that are already implemented. Only two items - left. - -commit 5796d2f5b7310fa8841f76bbc7bbcf2385d960c3 -Author: Ivo Timmermans -Date: Fri Jun 2 17:30:33 2000 +0000 - - Alphabetized the list, added Lubom�r Bulej, removed Sander Smeenk and Tijs van Bakel, put merits after all names. - -commit 18b3084d2525c59f62b75346fa657ccce6459712 -Author: Guus Sliepen -Date: Thu Jun 1 20:21:27 2000 +0000 - - Debian init.d script automatically sets tap device's MTU to 1448 now. - -commit 77be52422d8c28735f787b1c233b4cec73d4db56 -Author: Ivo Timmermans -Date: Wed May 31 18:23:06 2000 +0000 - - Miscellaneous copyright updates. - -commit 8cb4bb619d777022a55255c5fa17a1a55a270ff3 -Author: Ivo Timmermans -Date: Wed May 31 18:21:27 2000 +0000 - - Handle locale settings. - -commit f20df109a638ac3a86efa70fac39e1dae8e87208 -Author: Ivo Timmermans -Date: Wed May 31 18:19:33 2000 +0000 - - Version 1.0pre2-1. - -commit 4ae74c50b7faadf31086bc61af0f8158a465e521 -Author: Ivo Timmermans -Date: Wed May 31 18:18:21 2000 +0000 - - Updated Dutch translation. - -commit 7037286586151e28b7c5f1fe09dd6c5faca18cdc -Author: Ivo Timmermans -Date: Wed May 31 18:17:45 2000 +0000 - - Tell about /etc/tinc/nets.boot. - -commit 65a9eedb05387b8cf77dbbbc56347b44a28de624 -Author: Ivo Timmermans -Date: Wed May 31 18:17:27 2000 +0000 - - Include news for 1.0pre2. - -commit 17fa07510ad74d0f96f9700538d32eb8e7b2a0ce -Author: Ivo Timmermans -Date: Tue May 30 21:36:16 2000 +0000 - - Only accept an ADD_HOST request for a host that already exists in our conn_list if the nexthop field matches the sender. This is a workaround for older clients. - -commit e7f22d2f5f0a5fcd52da7512ab734b0ba52c623f -Author: Ivo Timmermans -Date: Tue May 30 12:38:15 2000 +0000 - - In terminate_connection, only send a notification to hosts that are directly connected to us. (DEL_HOST gets forwarded automatically.) - -commit 2fdda8e4fa6c6ace5f7e9421f0644a3ffec388c9 -Author: Ivo Timmermans -Date: Tue May 30 12:31:41 2000 +0000 - - When a connection is terminated, all hosts that are still connected get notified of the lost connections. - -commit f826301889e1fa1a22770919f0385c3ca04c740a -Author: Ivo Timmermans -Date: Tue May 30 11:18:12 2000 +0000 - - Added new configuration directive `Hostnames', which controls the resolving of IP addresses to hostnames. - -commit a7ad161d2b115b6a2a69c5dc8ddd33008d3562d0 -Author: Guus Sliepen -Date: Mon May 29 23:40:05 2000 +0000 - - Only activate a connection upon receiving it's public key if it's an - incoming connection. When it's outgoing, we need to receive an ack first. - -commit 5654e156a31d05ac3026790f7749d0401b2eaabc -Author: Ivo Timmermans -Date: Mon May 29 22:27:15 2000 +0000 - - Updated changes list for version 1.0pre2. - -commit a822c7466aa91a819c498336f91c63d224c3af11 -Author: Ivo Timmermans -Date: Mon May 29 22:20:04 2000 +0000 - - Bounds check for request id (between 0 and 255). - -commit 0f2cf48d304e20abb9b3cded2aaa693828c9d412 -Author: Ivo Timmermans -Date: Mon May 29 22:15:38 2000 +0000 - - Dutch translation of tinc. - -commit 386a62ff57f283b415fd757a8c4645b24c3bd3bb -Author: Ivo Timmermans -Date: Mon May 29 21:40:51 2000 +0000 - - Define LOCALEDIR in CFLAGS. - -commit 4cd009f774e4c50cdacc06d351cac19ca3247b6b -Author: Ivo Timmermans -Date: Mon May 29 21:40:20 2000 +0000 - - Include GNU gettext checks. - -commit 5814939c9d0e801bdbed6c96092fd90b6dcd859c -Author: Ivo Timmermans -Date: Mon May 29 21:38:02 2000 +0000 - - Update acconfig.h to include values for gettext inclusion. - -commit b200b0d812763563dbe09e5da116c55e45f89e4f -Author: Ivo Timmermans -Date: Mon May 29 21:36:28 2000 +0000 - - Include system.h and ABOUT-NLS. - -commit b9ea0633c7243de552d581f4486902c67aefd695 -Author: Ivo Timmermans -Date: Mon May 29 21:04:55 2000 +0000 - - Include intl/ directory in the list of subdirs. - -commit 9fd02ffcb0cacf3de26e876de5f30510bff137a3 -Author: Ivo Timmermans -Date: Mon May 29 21:01:26 2000 +0000 - - Internationalization of tinc. - -commit 61e71ab74ad9b5edb044b84ccf1111a33eb468cb -Author: Guus Sliepen -Date: Sat May 27 20:23:01 2000 +0000 - - Terminate a connection on any error. Furthermore, disallow del_host, - add_host and other important requests until remote host has properly - authenticated itself. - -commit cc01b18bc6d0bfb12e6770fc0a007c278f355d9e -Author: Guus Sliepen -Date: Sat May 27 19:44:04 2000 +0000 - - Made tinc persistent. If no outgoing connection can be established right - after the start of the daemon, it won't quit anymore but will retry in 5 - minutes. Also, 5 minutes is now the maximum time to wait for a retry. - -commit 028659bfbf164cb7a72831506896e291010b251f -Author: Guus Sliepen -Date: Sat May 27 19:23:20 2000 +0000 - - Fixed typos. When terminating a connection, it's status is not only set to - remove=1 but also active=0. - -commit e4ff969a9868ecc25a85daab620f97227de8d493 -Author: Guus Sliepen -Date: Sat May 27 19:04:12 2000 +0000 - - Fix for a DoS attack: - A remote user could telnet to the tinc daemon and type only this line: - 61 6 00000000/00000000:28f - This would deny any packets to be sent to other tinc networks (except - for to the hosts that run tincd's themselves). Solution is to skip - hosts in lookup_conn() that have not been activated yet. - Fixed potential conn_list table corruption: - If a new connection is accepted but a connection with the same subnet - would already exist in the connection list, the OLD connection is - terminated. - -commit 4d71de15e8abd137702a5dc04a743d246c3f1110 -Author: Guus Sliepen -Date: Sat May 27 13:21:20 2000 +0000 - - Documentation updates. Removed all references to configuration variable - "AllowConnect", since it is NOT used in tinc. Added information about - "VpnMask". Elaborated a bit about "private" and "virtual" networks. - -commit 85e3c1f2716c622ca8cada83d833703bf8a3ecc6 -Author: Ivo Timmermans -Date: Fri May 26 11:25:59 2000 +0000 - - Updated by Lubomir Bulej and Mads Kiilerich: it uses /etc/tinc/nets.boot and the VpnMask directive in the config files. - -commit 3a6ffe6895b681377a9553c01e3777f499b90d4a -Author: Ivo Timmermans -Date: Sun May 21 23:01:28 2000 +0000 - - Create an empty /etc/tinc/nets.boot. - -commit b9a86ec70ed4ffe5009c4979454f0d99c8559b45 -Author: Ivo Timmermans -Date: Sun May 21 22:40:41 2000 +0000 - - Use /etc/tinc/example as a base directory for an example. /etc/tinc/example/README points to /usr/share/doc/tinc/README.Debian. - -commit 63847abdfdad03a69bfd967929336e113cdeb09e -Author: Ivo Timmermans -Date: Sun May 21 22:38:01 2000 +0000 - - Add an example of using VpnMask. - -commit 2469acc0900edeb8f1e3263fbf58bf74639c1b12 -Author: Ivo Timmermans -Date: Sun May 21 22:27:31 2000 +0000 - - When VpnMask is not present in the config file, silently use $MSK as vpnmask. - -commit 73b3e7ce03cacb644a8101610933b221fdf432d6 -Author: Guus Sliepen -Date: Sun May 21 22:21:38 2000 +0000 - - Fixed last typo. Init.d now uses ifconfig command to set both the tap's IP - address as well as the correct route. Furthermore, if no VpnMask is given, - a default of 255.255.0.0 is chosen and a warning issued. - -commit 2ad4f1cc5b6013be2deee82b0cb3f731adb51616 -Author: Guus Sliepen -Date: Sun May 21 22:08:21 2000 +0000 - - Typo. - -commit e25fc3a3dc4bc407bd0645fb9891ac127a83f468 -Author: Guus Sliepen -Date: Sun May 21 22:04:56 2000 +0000 - - VpnMask truely works now. - -commit 9ec4decec17f95cc7d5be66cc18bb040cce84d47 -Author: Ivo Timmermans -Date: Fri May 19 01:17:32 2000 +0000 - - Mask the vpn net with the vpn netmask, route would give an error if the netmask didn't match the net. - -commit 20e404ab5716b06b53a4a5443f8098f227770907 -Author: Ivo Timmermans -Date: Fri May 19 00:58:01 2000 +0000 - - Fixed typo. - -commit 44af1094be90878bd6fc09c40882cf2463046908 -Author: Ivo Timmermans -Date: Fri May 19 00:33:44 2000 +0000 - - Updated copyright notice. - -commit 01352f4c525862f05988ed8687f26210c5ba10a2 -Author: Ivo Timmermans -Date: Fri May 19 00:15:37 2000 +0000 - - Errors will not terminate the script or result in a nonzero exit code. - -commit 4ef2a8cfdb13c7eb2d811fc8c9f04df8970293c5 -Author: Ivo Timmermans -Date: Fri May 19 00:14:34 2000 +0000 - - Include postinst in the distribution. - -commit 59ca017df4c9d0f7861693b4d2ec4b7dc8c98b1e -Author: Ivo Timmermans -Date: Fri May 19 00:09:20 2000 +0000 - - Find networks in instead of . - -commit 0354962c9885f04801d8469214c172cc012cdcec -Author: Ivo Timmermans -Date: Thu May 18 23:33:44 2000 +0000 - - Don't distribute the file files. - -commit b56705e18ceec9234578d7ac12939f7c59cff066 -Author: Ivo Timmermans -Date: Thu May 18 23:28:51 2000 +0000 - - Version 1.0pre2-0.3 - -commit cbf6efb617f45ffc608fe5f61d09abdd85f444ad -Author: Ivo Timmermans -Date: Thu May 18 23:18:54 2000 +0000 - - Create a default /etc/tinc/nets.boot after installation, containing all directories under /etc/tinc by default. - -commit e7d583adfaa50370d20f4cfe88ba5b6da399911d -Author: Ivo Timmermans -Date: Thu May 18 23:09:31 2000 +0000 - - Read /etc/tinc/nets.boot to find the networks that have to be started. - -commit 8d4ab991b8c35382c9cd46dd65af873d9d08f63f -Author: Ivo Timmermans -Date: Wed May 17 23:13:51 2000 +0000 - - This file is generated with dpkg-buildpackage. - -commit ffc79bcd20b2b8085c906a446318817808bc36ae -Author: Guus Sliepen -Date: Tue May 16 16:07:15 2000 +0000 - - TODO file reinstated: - - Append your name to items if you're working on them. - - Remove them if you fixed the problem/implemented that feature. - - Add any (suspected) bugs. - -commit cdab82d6fb7d7d32194cb2162a814fbc89b7db4c -Author: Ivo Timmermans -Date: Tue May 16 14:34:44 2000 +0000 - - Use the new VpnMask directive to add a route to the rest of the VPN. - -commit 85963f4c857abc2d9a4c5a3245cc11257140b9a6 -Author: Guus Sliepen -Date: Tue May 16 13:09:15 2000 +0000 - - Stub for VpnMask config directive. - -commit 30aff5ea2aebcfc0e97e60e73ed3edc2363634a0 -Author: Ivo Timmermans -Date: Tue May 16 13:03:32 2000 +0000 - - Look if the tap devices exist before bluntly remaking them. - -commit 0761eed64c4d6d2b8e9fa6a335ccdca8ea4b95db -Author: Ivo Timmermans -Date: Tue May 16 07:56:05 2000 +0000 - - *** empty log message *** - -commit 0a2e2b0c8d20baf22b550f735b1fe63b0a1d377a -Author: Ivo Timmermans -Date: Mon May 15 19:48:46 2000 +0000 - - Depend on perl5. - -commit 7e817fcf0fdd25aae58259930006c61048b017cd -Author: Ivo Timmermans -Date: Mon May 15 18:28:45 2000 +0000 - - Unlimited length in the config file, thanks to Cris van Pelt. - -commit b18af982af810ff4c050891ad2026960c43620a0 -Author: Ivo Timmermans -Date: Mon May 15 17:15:52 2000 +0000 - - Exit with zero status if is empty. - -commit 4711a87922c84241e9bb312755d7b943ea8ae4b6 -Author: Ivo Timmermans -Date: Mon May 15 15:54:37 2000 +0000 - - Updated to newer version. - -commit a0c4e7fe6d46988f3fb1100ef00db7b747c86f72 -Author: Guus Sliepen -Date: Mon May 15 09:41:34 2000 +0000 - - Test for existence of configured tinc networks. This will also make - first install of tinc possible without errors. - -commit 265bda08cd00feebb68243d4079854916b03638e -Author: Ivo Timmermans -Date: Sun May 14 23:03:37 2000 +0000 - - .deb version number 1.0pre2-0.4. - -commit 7a450d704b5a242f8bf9129af60593c90c63df5a -Author: Ivo Timmermans -Date: Sun May 14 23:00:44 2000 +0000 - - tincd->tinc - Delete libblowfish.y not be in the .deb. - -commit 7fbfa990fcd38b8241281ce6f1a4e2992239986f -Author: Ivo Timmermans -Date: Sun May 14 22:59:47 2000 +0000 - - Mention both upstream authors. - -commit f7b04ea142623a43413f74e19b1b6a9a247647ff -Author: Ivo Timmermans -Date: Sun May 14 22:59:19 2000 +0000 - - Add description, better dependancies. - -commit 9f07fe55dc4930920b9a5909d7057ca7bc16bad9 -Author: Ivo Timmermans -Date: Sun May 14 22:58:47 2000 +0000 - - Add initscript, tincd->tinc. - -commit df10baa50c3b421b03ac9eeaed4a4a19a47f611e -Author: Ivo Timmermans -Date: Sun May 14 21:18:10 2000 +0000 - - Inserted useful content. - -commit 6c722da77cc9185e48e22818ef88f2a88cf2efc7 -Author: Ivo Timmermans -Date: Sun May 14 21:14:23 2000 +0000 - - Add shlibs control file for the blowfish library. - -commit 803f908078e87f433727a3ddf2d61734e1ed9233 -Author: Ivo Timmermans -Date: Sun May 14 21:07:16 2000 +0000 - - Give IP address instead of hex number when connecting tcp socket failed. - -commit 4b1a1c2123626b50bd1a5382867986260440e9e7 -Author: Ivo Timmermans -Date: Sun May 14 21:04:53 2000 +0000 - - Changed version to 1.0pre2. - -commit ca900d388b996c629f0c87c7a62efb52bd219065 -Author: Ivo Timmermans -Date: Sun May 14 20:58:34 2000 +0000 - - Version 1.0pre1-0.1. - -commit 7d433ebd7610e0ff7e7b4c59979c446c0a1dfd03 -Author: Ivo Timmermans -Date: Sun May 14 20:56:41 2000 +0000 - - Add check for mpz_powm in libgmp3. - -commit de09916eadd4c558937d1a6367f5319ca26ed07c -Author: Ivo Timmermans -Date: Sun May 14 13:50:10 2000 +0000 - - Only print an error with send_termreq if debug_lvl is 2 or more. - -commit 9d023b1f2e7750f4a0e506c0f61498a44c0b95a8 -Author: Guus Sliepen -Date: Sun May 14 13:06:52 2000 +0000 - - Fixed typos. - -commit e20e143f1e99bdc0a7d92e97da1bd0dc40e8a83b -Author: Guus Sliepen -Date: Sun May 14 13:02:20 2000 +0000 - - Changed ping behaviour (backwards compatible). If we don't have any data - to send, we don't need to check if the connection is still alive. - Furthermore, if we receive any kind of data from the other end, we know - it's alive, so we don't need to check it either. So, PING requests are - only sent if we send packets but there is no response. - -commit ee96ccabbbf0180d5631d3c22838456f28ee9c15 -Author: Guus Sliepen -Date: Sun May 14 12:22:42 2000 +0000 - - Cleanups. - -commit 8caa1b9d750bb7467d1c3330780b05ac2bbf9883 -Author: Guus Sliepen -Date: Sun May 14 11:39:18 2000 +0000 - - Proxymode removed. - -commit 269067bb22e8f80deb43d3ac903f4e0d67af63d2 -Author: Ivo Timmermans -Date: Sat May 13 00:54:27 2000 +0000 - - Perl version of the system startup script. - -commit 12adf1af548b7d2f2baa4be16d2df956048b7855 -Author: Ivo Timmermans -Date: Fri May 12 13:31:00 2000 +0000 - - Deleted the protocol description. - -commit d0ba34ccae02d07051bc3f7012a6c116cfb3b653 -Author: Guus Sliepen -Date: Mon May 8 18:44:15 2000 +0000 - - Added new config variable "ProxyMode". If enabled, all outgoing packets - are sent to the uplink (ConnectTo), which will have to forward them for - us (kernel should do that). This is for people behind firewalls. - -commit 92387475ace9b06af39987c71ac563cf29427009 -Author: Ivo Timmermans -Date: Fri May 5 10:48:54 2000 +0000 - - Added semicolons required by bash2 (Mads Kiilerich). - -commit bce2179fe350bf34cde0caab97f72c0930539840 -Author: Ivo Timmermans -Date: Thu May 4 23:26:24 2000 +0000 - - Copied most of the code from the redhat script. - -commit 74b0cbecce5194dc5c594cc4e2aa3e97c14ea6c1 -Author: Ivo Timmermans -Date: Thu May 4 23:17:02 2000 +0000 - - Include sys/types.h. - -commit 2f7e532d703bbf6997ae04658379df0b0d844f62 -Author: Ivo Timmermans -Date: Thu May 4 23:16:43 2000 +0000 - - Don't link in libdl. - -commit d4ef7ea0e79ee0d2b7063893f7af5ece886d838b -Author: Ivo Timmermans -Date: Thu May 4 00:01:05 2000 +0000 - - Check for the existance of libdl. - -commit 87ccd613cab1947878ef60e3c927f717df089233 -Author: Ivo Timmermans -Date: Thu May 4 00:00:50 2000 +0000 - - More for getopt support. - -commit 6182664859383a86a47846cafdc1f6fcd73b5a76 -Author: Ivo Timmermans -Date: Thu May 4 00:00:06 2000 +0000 - - Include stdio.h for fprintf. - -commit 88a8826cf72297a784d597ba5a2b47058e1faf72 -Author: Ivo Timmermans -Date: Wed May 3 23:47:06 2000 +0000 - - getopt_long() support for platforms that don't have it. - -commit 3d218a31145cf6a4c625ed287cdf3f99e4fd9a03 -Author: Ivo Timmermans -Date: Wed May 3 23:00:38 2000 +0000 - - Don't use error.h or error(), put #error in front of cpp errors. - -commit a083b1cf305f3d241f2f4b36968a5b1ed9117612 -Author: Guus Sliepen -Date: Wed May 3 18:02:15 2000 +0000 - - Squashed gcc warning. - -commit 78532475238b23eb52ac88d905fbf966d97a79d2 -Author: Guus Sliepen -Date: Wed May 3 17:59:07 2000 +0000 - - Fixes typo and UDP network byte order. - -commit 505b5ec2cd9d6cf3dc655284a8c4041ce8527a07 -Author: Guus Sliepen -Date: Wed May 3 15:37:32 2000 +0000 - - Outgoing packets now use network byte order in header. - -commit 2bc7a0c92831802eec167ad193515962a63690dd -Author: Ivo Timmermans -Date: Wed May 3 15:01:54 2000 +0000 - - Fix a typo, better handling of the info document. (from Mads Kiilerich) - -commit 89610e3fbada1dee79769b8146a500c8357fd81d -Author: Guus Sliepen -Date: Tue May 2 10:16:50 2000 +0000 - - Replaced sprintf() by safer snprintf(), removed possible buffer overflow - by one byte. - -commit aeccaca829842910b4a5c8a5fa61e1738492bea6 -Author: Guus Sliepen -Date: Tue May 2 09:55:34 2000 +0000 - - Previous fix fixed. Meta protocol should be really flawless from now on! - -commit 989d7edc07fd407e7f7838b45986f4e37359ef97 -Author: Guus Sliepen -Date: Tue May 2 09:10:33 2000 +0000 - - Fixed small mistake that would prevent forwarding requests. - -commit 069c146656b8f952e465492c53ab5b514e959565 -Author: Ivo Timmermans -Date: Mon May 1 22:00:02 2000 +0000 - - Mentioned new metaprotocol. - -commit bd0325655867b1dff740d52d0505773bba0606a6 -Author: Ivo Timmermans -Date: Mon May 1 21:47:12 2000 +0000 - - More tincd->tinc updates. - -commit a9247e6f2c57bda9dc62ed050f41048847109e83 -Author: Ivo Timmermans -Date: Mon May 1 21:31:59 2000 +0000 - - Fixed meta protocol. - -commit 9ea27f76fab3663c9c83a7fe7de95f74cbfd59be -Author: Ivo Timmermans -Date: Mon May 1 21:31:17 2000 +0000 - - Committed by Mads Kiilerich. - -commit a92604fa5dffef589fc3042c5ae09ae8878e8cff -Author: Ivo Timmermans -Date: Mon May 1 19:17:09 2000 +0000 - - Updates by Mads Kiilerich. - -commit ca6abd41ea0cdf2ca6491c3945fb3c62fd40ab98 -Author: Guus Sliepen -Date: Mon May 1 18:07:12 2000 +0000 - - Meta protocol overhaul. Tinc is now incompatible with previous versions, - furthermore this version does NOT work yet because of a problem with - sending keys (these should be converted to base36 or something like that). - It is possible to telnet to the tinc daemon now and type some commands - by hand though :). - -commit 3219be5770716bdb0c8b6e9e4c674a447c5085f2 -Author: Ivo Timmermans -Date: Mon May 1 16:28:28 2000 +0000 - - Committed by Lubom�r Bulej. - -commit 33cfdf43f4309c17d6df811b3c5d0af3a1c8679f -Author: Ivo Timmermans -Date: Sun Apr 30 20:48:48 2000 +0000 - - Key forwarding, write one byte extra. - -commit 75d351eaf1264cfb7aa47166469e8ec722712a89 -Author: Ivo Timmermans -Date: Sun Apr 30 19:49:49 2000 +0000 - - Protocol fix (ANS_KEY). This breaks 0.3.3 protocol compatibility. - -commit b4290c3f4360f3cf01bb44957da0d8a20eac75f3 -Author: Ivo Timmermans -Date: Sun Apr 30 19:03:00 2000 +0000 - - Send one less byte from an ANS_KEY request. - -commit d878230ebef5f1a14a23c266dc425666d9e805eb -Author: Ivo Timmermans -Date: Sun Apr 30 18:57:16 2000 +0000 - - Read one less byte from an ANS_KEY request. - -commit 789a4c4f400de31d43b9c5f349f1de417443074a -Author: Ivo Timmermans -Date: Sun Apr 30 16:34:31 2000 +0000 - - Removed debug messages. - -commit eb1c9814e6b2a5206be1fadf19e0dc779690a69e -Author: Ivo Timmermans -Date: Sun Apr 30 16:31:23 2000 +0000 - - Read public keys the right way (tm). - -commit ca73b722cbad5a08ec9bb5026ed5129da9a24bd8 -Author: Ivo Timmermans -Date: Sun Apr 30 16:11:05 2000 +0000 - - New way of handling the meta protocol. - -commit cd12345032e8547a50a1f7450814364f39f0c4ec -Author: Ivo Timmermans -Date: Sun Apr 30 13:23:53 2000 +0000 - - Replaced check for status.active by status.dataopen in check_network_activity. - -commit 4b076ee87fcf8aaf1d9a2bd3c27524b4e3840167 -Author: Ivo Timmermans -Date: Sun Apr 30 01:16:51 2000 +0000 - - Initially, the vpn_mask of a connection is 255.255.255.255 to avoid confusion with lookup_conn. - -commit 1c007c0627ad5e71b8218fcb086240970e955c87 -Author: Ivo Timmermans -Date: Sun Apr 30 01:15:47 2000 +0000 - - Got rid of the nasty hacks... and replaced it by another one. - -commit c02745991422ac3d8097b126e8b256a9b33ad24b -Author: Ivo Timmermans -Date: Sat Apr 29 20:39:36 2000 +0000 - - Filled up the protocol structs with unused bytes. - -commit d3e8e8ca54928e48400584d8a70c42bbf4ae6aeb -Author: Ivo Timmermans -Date: Sat Apr 29 20:38:23 2000 +0000 - - Added `deb' target. - -commit 4dbf7022a25e678969856a38501318db4d420936 -Author: Ivo Timmermans -Date: Sat Apr 29 13:56:06 2000 +0000 - - More updates wrt. the change from tincd->tinc. - -commit 23715510149179089952eef0a2d6f87571ac0e7e -Author: Guus Sliepen -Date: Fri Apr 28 11:33:25 2000 +0000 - - Oops! Reference to write_n() removed and changed into neat write() call. - -commit bb8fff92e1bc594a085c2cbd12b215d334695feb -Author: Guus Sliepen -Date: Thu Apr 27 20:57:18 2000 +0000 - - Removed write_n() function. - -commit 4fec0cc45774ba313d1823cc64c3afdda3204a2e -Author: Ivo Timmermans -Date: Thu Apr 27 13:47:51 2000 +0000 - - Default config file name is tinc.conf, and pidfile is tinc.pid. - -commit eebb708cb29a121ea8d58bb6ca6caf41dea3c3b4 -Author: Ivo Timmermans -Date: Thu Apr 27 00:07:17 2000 +0000 - - Updated version number to 1.0. - -commit 5797d3fcb1ff56ad3ff577f7eb988b70f9d4d709 -Author: Ivo Timmermans -Date: Thu Apr 27 00:01:00 2000 +0000 - - Filled in the details, license from libblowfish copied. - -commit a3ccc15ac0979c4103f98e740b525634e8e17a0a -Author: Ivo Timmermans -Date: Wed Apr 26 23:56:22 2000 +0000 - - Version to 1.0pre1; - Create Makefile and build in debian/. - -commit d928703db1c4aa6caa6e4fbb0894037b10dce820 -Author: Ivo Timmermans -Date: Wed Apr 26 23:23:01 2000 +0000 - - Omit TODO. - -commit d0ea9c8ff287e879e531af9f1b52529421c0512f -Author: Ivo Timmermans -Date: Wed Apr 26 22:42:15 2000 +0000 - - Add an entry to dir. - -commit e5a7291543d41d435cc0fae56e52dc62a119a225 -Author: Ivo Timmermans -Date: Wed Apr 26 22:01:01 2000 +0000 - - The make command is in /usr/bin. - -commit 44f9449888344866406c75b178eff83b392b3530 -Author: Guus Sliepen -Date: Wed Apr 26 17:42:55 2000 +0000 - - Cleanups: - - Changed recv/send calls into read/write calls for streams - - Made all sizeof() functions use a variable name instead of type - -commit fca84d8a7d116c62423faf88e841daf1bee714e1 -Author: Ivo Timmermans -Date: Wed Apr 26 14:54:43 2000 +0000 - - From Mads Kiilerich. - -commit 8efe4874dabdfdf03a747ea98cf38b11cb591ef5 -Author: Guus Sliepen -Date: Tue Apr 25 22:15:28 2000 +0000 - - Converted every &variable[0] to variable. - -commit 643d8712eb2f82bde21f206306cdb6491eee7e08 -Author: Ivo Timmermans -Date: Tue Apr 25 22:00:49 2000 +0000 - - Debug level tweaking. - -commit 468f1d2efcce53937b7f5e0540269ae18f29ebac -Author: Guus Sliepen -Date: Tue Apr 25 20:50:59 2000 +0000 - - When trying to talk to a host that is in the netmask of a tinc server but - not the tinc server itself, and no keys have been exchanged yet, the key - request would be directed to the host instead of the server. Fixed. - -commit 6461a4b607f5e422b5809acb772e4bfe810b5570 -Author: Ivo Timmermans -Date: Tue Apr 25 20:42:54 2000 +0000 - - *** empty log message *** - -commit dad90e82d3c7af95820b1c04903bed7074e2b175 -Author: Guus Sliepen -Date: Tue Apr 25 20:17:44 2000 +0000 - - Fixed typo and removed some unnecessary variables. - -commit 5b7242285795f5143770b663055b87ebb5dd15b8 -Author: Guus Sliepen -Date: Tue Apr 25 20:10:37 2000 +0000 - - Packet queues fixed. They caused the trouble when resending keys. - -commit 04db888b1a94a7d63fdf9800cfd722aa9c16cd26 -Author: Ivo Timmermans -Date: Tue Apr 25 19:23:23 2000 +0000 - - Create a ChangeLog file, automake requires it. - -commit c78b76c53f516cf944ee738fad3e7d4607f282ab -Author: Ivo Timmermans -Date: Tue Apr 25 19:21:19 2000 +0000 - - *** empty log message *** - -commit 45b275e2542b4e8e7deac9e5e9eeddacfdbce90f -Author: Ivo Timmermans -Date: Tue Apr 25 19:11:02 2000 +0000 - - Initial CVS. - -commit 3a3356865267ff4c1e4f7d73f6d1486952d641b5 -Author: Guus Sliepen -Date: Tue Apr 25 18:57:23 2000 +0000 - - Added checkpoints to beginning and ending of every function. - -commit b6bdb9079a9e80b77443efe6c8b6da19e57e8505 -Author: Ivo Timmermans -Date: Tue Apr 25 17:38:54 2000 +0000 - - Remove ChangeLog with a `make cvs-clean'. - -commit ca373c61944a7bd2fe26faf081edea136104d326 -Author: Ivo Timmermans -Date: Tue Apr 25 17:35:45 2000 +0000 - - Don't include TODO in the dist. - -commit e1e590fe9a8c5c767933c68979418911f36d3a89 -Author: Ivo Timmermans -Date: Tue Apr 25 15:08:10 2000 +0000 - - Propagate CFLAGS from configure to gcc. - -commit 8a90de94a1b0e6cdaf51559d44f04a75d5f9ab0e -Author: Ivo Timmermans -Date: Tue Apr 25 15:07:21 2000 +0000 - - Delete all the files that are created by autogen.sh on a `make cvs-clean'. - -commit 24ee68b683de9937e917898075c62ff5f43ee46a -Author: Ivo Timmermans -Date: Tue Apr 25 10:40:08 2000 +0000 - - Spelling fixes. - -commit 4d85552c5bf134ada1d1083ec86dabbe41497c4a -Author: Ivo Timmermans -Date: Tue Apr 25 10:27:44 2000 +0000 - - Contributed by Mads Kiilerich. - -commit 94921d6e57e01b378ab8b1d8ea9cf3da9511fbef -Author: Ivo Timmermans -Date: Tue Apr 25 10:22:26 2000 +0000 - - Generate this Makefile.am from Makefile.am.in. - -commit 8c2b6537d32720b38554815181009c3098423414 -Author: Ivo Timmermans -Date: Tue Apr 25 09:43:50 2000 +0000 - - *** empty log message *** - -commit 03fa76dbf9965cc174eebe8a152307b8fbb63079 -Author: Ivo Timmermans -Date: Tue Apr 25 09:42:52 2000 +0000 - - Added Mads Kiilerich, removed Guus Sliepen. - -commit 7c665712d69d5a502d4c2f098ad85df3b17bfb92 -Author: Ivo Timmermans -Date: Tue Apr 25 01:45:34 2000 +0000 - - Changes largely from Mads Kiilerich. - Removed section about encryption. - -commit ce98ee1ed4121fbbf5d0e13e158511064ced6b16 -Author: Ivo Timmermans -Date: Tue Apr 25 01:26:35 2000 +0000 - - Remove test for GNOME. - -commit 6c99feb3e3cf6d69bcf52ae87b6c64ddbf3ffca5 -Author: Ivo Timmermans -Date: Tue Apr 25 01:25:18 2000 +0000 - - Use `make ChangeLog' to create this file from the CVS logs. - -commit f9eef5210dbc9c0fe54637cc4c3c0be134a51409 -Author: Ivo Timmermans -Date: Tue Apr 25 01:23:31 2000 +0000 - - Don't define HAVE_NAMESPACES and HAVE_STL. - -commit ea9d2f379a170077f93569a957c713452768d0a4 -Author: Ivo Timmermans -Date: Tue Apr 25 01:22:01 2000 +0000 - - Remove check for bigendianness. - -commit 18b204d17a054e991d90b7c4047ea106df64cdaf -Author: Ivo Timmermans -Date: Tue Apr 25 01:15:28 2000 +0000 - - This file is obsolete, most of the ideas are already in echelon. - -commit 62d5384ee01ae818906f2f8ba1456372a13a2420 -Author: Ivo Timmermans -Date: Tue Apr 25 01:10:38 2000 +0000 - - s/Gnome/tinc/g - -commit f0101589959496593db672c6a35704ea5fb33238 -Author: Ivo Timmermans -Date: Tue Apr 25 00:50:48 2000 +0000 - - The shell script autogen.sh can create all these removed files, but be - sure to have autoconf, automake, libtool and more installed. - -commit 6990a7455521665d3b67518e3f2297968108190b -Author: Ivo Timmermans -Date: Tue Apr 25 00:11:33 2000 +0000 - - Don't try to create cipher/idea/Makefile. - -commit cfecc82c9a3f5e8c4648eec058da2c6427cd76af -Author: Ivo Timmermans -Date: Mon Apr 24 21:12:32 2000 +0000 - - Don't include idea/idea.h. - -commit 63540ceff5c7bb7c76d96a4cef4ba803ce915ce1 -Author: Ivo Timmermans -Date: Mon Apr 24 21:10:33 2000 +0000 - - Don't compile in `idea'. - -commit 74315f4218ba50cc5ba32b6ecc8e8afa2b5cd704 -Author: Ivo Timmermans -Date: Mon Apr 24 20:57:22 2000 +0000 - - These files are not needed in release 1.0. - -commit 16d581be68bb52c08569e34e8a6b87f66b87e8ee -Author: Guus Sliepen -Date: Mon Apr 24 09:39:50 2000 +0000 - - Bug found! Wrong pointer was used for handling multiple ADD_HOST requests - at once. (See line 606.) - -commit f6802d349d946090bf9d1b6c761077c80065afa5 -Author: Guus Sliepen -Date: Mon Apr 24 08:32:57 2000 +0000 - - Added extra checks for desynchronized connection lists. Hopefully this will - fix those strange segmentation faults. - -commit 10749179127c681ce040fcf612038174b2bd474a -Author: Ivo Timmermans -Date: Thu Apr 20 22:50:48 2000 +0000 - - Added cvs-clean. - -commit c92701fcf007b67725d82a23ffaef3e6e5c2b0e1 -Author: Ivo Timmermans -Date: Thu Apr 20 19:14:09 2000 +0000 - - Keep make dist(dir) happy. - -commit 7db17968fc84127212ebba0fbccec1e75ced2bdc -Author: Ivo Timmermans -Date: Tue Apr 18 20:44:29 2000 +0000 - - A short notice from Mads Kiilerich. - -commit 2c5a555d7aefcf5699c68cb5d5f00f604b2542c7 -Author: Ivo Timmermans -Date: Tue Apr 18 20:43:24 2000 +0000 - - Submitted changes by Mads Kiilerich. - -commit 375b668dbc1e0268b49ea12901da72bbf5247ce5 -Author: Ivo Timmermans -Date: Tue Apr 18 20:30:20 2000 +0000 - - Include genauth.8 in the distribution. - -commit 57d8c30e4cbecea3b4216e4e650c4c0a3e160ed2 -Author: Ivo Timmermans -Date: Tue Apr 18 20:26:49 2000 +0000 - - Include the directory redhat in the build process. - -commit 0b02ebc4d98182cf79c670e7e556ac7f4f859b75 -Author: Ivo Timmermans -Date: Tue Apr 18 16:04:10 2000 +0000 - - Address for bugreports changed to tinc@nl.linux.org. - -commit 8770211c84cfb69f71bd204926593900d74ab579 -Author: Ivo Timmermans -Date: Tue Apr 18 15:59:42 2000 +0000 - - Updated manpages. - -commit 8cdb84951019feb6d4954cd11eb9663c5b9ce363 -Author: Ivo Timmermans -Date: Tue Apr 18 15:59:22 2000 +0000 - - New manpage for genauth. - -commit d11cfcec74e25ee2b88acea62ca5ef973ab7204b -Author: Ivo Timmermans -Date: Tue Apr 18 15:09:11 2000 +0000 - - Submitted by Mads Kiilerich. - -commit 93287d2b2c77d4b9e3f85f36ef4f9230fe3bf9b3 -Author: Ivo Timmermans -Date: Mon Apr 17 17:04:33 2000 +0000 - - Default passphrase length of 1024, added -h/--help options. - -commit 9c2ac77594d83a810c53faf6979e0b76006ecd0e -Author: Ivo Timmermans -Date: Mon Apr 17 16:59:42 2000 +0000 - - Check if stdout is a terminal, if so, print a verbose message. - -commit c9246896901ff1ebad91ac399a4ea79fad941f75 -Author: Ivo Timmermans -Date: Mon Apr 17 16:52:58 2000 +0000 - - Check for an illegal length of passphrase in read_passphrase(). - -commit baebae274913d912d76ba1d545f337dfb945fc5c -Author: Ivo Timmermans -Date: Mon Apr 17 16:23:29 2000 +0000 - - Pass the requested size from xmalloc() and xrealloc() on to xalloc_fail_func() - -commit 210a92cae90deb5b4a410b1b7d5c625c5c5f2ffb -Author: Ivo Timmermans -Date: Mon Apr 17 15:38:47 2000 +0000 - - Only one round of reading bits out of urandom; - Reading `bytes' bytes out of it; - Print a newline after completion. - -commit 5b44b91eb408d76af646b031da2364a769b44771 -Author: Ivo Timmermans -Date: Wed Apr 12 16:22:39 2000 +0000 - - Moved to version number 1.0. - -commit 18e044bde3b508c991910218989b4bacc3a4934e -Author: Ivo Timmermans -Date: Thu Apr 6 18:28:29 2000 +0000 - - New option -D, don't detach. - -commit 523c80c4e35b7ff8ad94b41a6071dbe2b8ff6ec7 -Author: Ivo Timmermans -Date: Tue Mar 28 19:16:27 2000 +0000 - - Ignore SIGCHLD. - -commit f2076e3e7031ac8ad87eb6aab0cea40f379dd0c6 -Author: Ivo Timmermans -Date: Tue Mar 28 19:09:52 2000 +0000 - - Kill the parent after any error conditions in detach(). - -commit 98de35c742498878a27fb29becd3b7154525a60f -Author: Ivo Timmermans -Date: Mon Mar 27 22:59:16 2000 +0000 - - Upon regeneration, free the old encryption key `securely\' by overwriting it. - -commit b50523dc44bbb32f03d24573e195c071cbff3fc4 -Author: Ivo Timmermans -Date: Mon Mar 27 22:30:27 2000 +0000 - - Get rid of the message `zxnrbl\'. - -commit 1243156a5e03a666b36bc4400f1402243a85c9a7 -Author: Ivo Timmermans -Date: Sun Mar 26 00:33:07 2000 +0000 - - Initial revision diff --git a/NEWS b/NEWS index 3dea2b5..a6e13d8 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,28 @@ +Version 1.1pre6 February 20 2013 + + * Fixed tincd exitting immediately on Windows. + + * Detect PMTU increases. + + * Fixed crashes when using a SOCKS5 proxy. + + * Fixed control connection when using a proxy. + +Version 1.1pre5 January 20 2013 + + * Fixed long delays and possible hangs on Windows. + + * Fixed support for the tunemu device on iOS, the UML and VDE devices. + + * Small improvements to the documentation and error messages. + + * Fixed broadcast packets not reaching the whole VPN. + + * Tincctl now connects via a UNIX socket to the tincd on platforms that + support this. + + * The PriorityInheritance option now also works in switch mode. + Version 1.1pre4 December 5 2012 * Added the "AutoConnect" option which will let tinc automatically select diff --git a/README b/README index 639829c..0709fb8 100644 --- a/README +++ b/README @@ -1,7 +1,7 @@ -This is the README file for tinc version 1.1pre4. Installation +This is the README file for tinc version 1.1pre6. Installation instructions may be found in the INSTALL file. -tinc is Copyright (C) 1998-2012 by: +tinc is Copyright (C) 1998-2013 by: Ivo Timmermans, Guus Sliepen , @@ -36,11 +36,11 @@ at your own risk. Compatibility ------------- -Version 1.1pre4 is compatible with 1.0pre8, 1.0 and later, but not with older +Version 1.1pre6 is compatible with 1.0pre8, 1.0 and later, but not with older versions of tinc. When the ExperimentalProtocol option is used, tinc is still compatible with -1.0.X and 1.1pre4 itself, but not with any other 1.1preX version. +1.0.X and 1.1pre6 itself, but not with any other 1.1preX version. Requirements diff --git a/THANKS b/THANKS index 7d91271..1f2f73c 100644 --- a/THANKS +++ b/THANKS @@ -6,7 +6,9 @@ We would like to thank the following people for their contributions to tinc: * Anthony G. Basile * Armijn Hemel * Brandon Black +* Cheng LI * Cris van Pelt +* Darius Jahandarie * Delf Eldkraft * dnk * Enrique Zanardi diff --git a/configure b/configure index 01cfacd..86d7e70 100755 --- a/configure +++ b/configure @@ -4095,7 +4095,7 @@ fi # Define the identity of the package. PACKAGE=tinc - VERSION=1.1pre4 + VERSION=1.1pre6 cat >>confdefs.h <<_ACEOF diff --git a/configure.in b/configure.in index e513248..f2ec3bd 100644 --- a/configure.in +++ b/configure.in @@ -4,7 +4,7 @@ AC_PREREQ(2.61) AC_INIT AC_CONFIG_SRCDIR([src/tincd.c]) AC_GNU_SOURCE -AM_INIT_AUTOMAKE(tinc, 1.1pre4) +AM_INIT_AUTOMAKE(tinc, 1.1pre6) AC_CONFIG_HEADERS([config.h]) AM_MAINTAINER_MODE diff --git a/doc/tinc.conf.5.in b/doc/tinc.conf.5.in index 350a410..38a4c11 100644 --- a/doc/tinc.conf.5.in +++ b/doc/tinc.conf.5.in @@ -1,4 +1,4 @@ -.Dd 2012-09-27 +.Dd 2013-01-14 .Dt TINC.CONF 5 .\" Manual page created by: .\" Ivo Timmermans @@ -343,7 +343,7 @@ This option selects the way packets are routed to other daemons. In this mode .Va Subnet variables in the host configuration files will be used to form a routing table. -Only unicast packets of routable protocols (IPv4 and IPv6) are supported in this mode. +Only packets of routable protocols (IPv4 and IPv6) are supported in this mode. .Pp This is the default mode, and unless you really know you need another mode, don't change it. .It switch @@ -361,7 +361,7 @@ while no routing table is managed. .It Va Name Li = Ar name Bq required This is the name which identifies this tinc daemon. It must be unique for the virtual private network this daemon will connect to. -The Name may only consist of alphanumeric and underscore characters. +The Name may only consist of alphanumeric and underscore characters (a-z, A-Z, 0-9 and _), and is case sensitive. If .Va Name starts with a @@ -372,7 +372,7 @@ If .Va Name is .Li $HOST , -but no such environment variable exist, the hostname will be read using the gethostnname() system call. +but no such environment variable exist, the hostname will be read using the gethostname() system call. .It Va PingInterval Li = Ar seconds Pq 60 The number of seconds of inactivity that .Nm tinc @@ -428,7 +428,7 @@ and are available. .El .It Va ReplayWindow Li = Ar bytes Pq 16 -vhis is the size of the replay tracking window for each remote node, in bytes. +This is the size of the replay tracking window for each remote node, in bytes. The window is a bitfield which tracks 1 packet per bit, so for example the default setting of 16 will track up to 128 packets in the window. In high bandwidth scenarios, setting this to a higher value can reduce packet loss from @@ -497,12 +497,9 @@ Furthermore, specifying .Qq none will turn off packet authentication. .It Va IndirectData Li = yes | no Pq no -This option specifies whether other tinc daemons besides the one you specified with -.Va ConnectTo -can make a direct connection to you. -This is especially useful if you are behind a firewall -and it is impossible to make a connection from the outside to your tinc daemon. -Otherwise, it is best to leave this option out or set it to no. +When set to yes, other nodes which do not already have a meta connection to you +will not try to establish direct communication with you. +It is best to leave this option out or set it to no. .It Va MACLength Li = Ar length Pq 4 The length of the message authentication code used to authenticate UDP packets. Can be anything from diff --git a/doc/tinc.info b/doc/tinc.info index 73343b8..690527a 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.1pre4, a Virtual Private + This is the info manual for tinc version 1.1pre5, a Virtual Private Network daemon. - Copyright (C) 1998-2012 Ivo Timmermans, Guus Sliepen + Copyright (C) 1998-2013 Ivo Timmermans, Guus Sliepen and Wessel Dankers . Permission is granted to make and distribute verbatim copies of this @@ -989,9 +989,8 @@ Mode = (router) router In this mode Subnet variables in the host configuration files - will be used to form a routing table. Only unicast packets - of routable protocols (IPv4 and IPv6) are supported in this - mode. + will be used to form a routing table. Only packets of + routable protocols (IPv4 and IPv6) are supported in this mode. This is the default mode, and unless you really know you need another mode, don't change it. @@ -1026,13 +1025,13 @@ MACExpire = (600) Name = [required] This is a symbolic name for this connection. The name should consist only of alfanumeric and underscore characters (a-z, A-Z, - 0-9 and _). + 0-9 and _), and is case sensitive. If Name starts with a $, then the contents of the environment variable that follows will be used. In that case, invalid characters will be converted to underscores. If Name is $HOST, but no such environment variable exist, the hostname will be read - using the gethostnname() system call. + using the gethostname() system call. PingInterval = (60) The number of seconds of inactivity that tinc will wait before @@ -1157,12 +1156,9 @@ Digest = (sha1) "none" will turn off packet authentication. IndirectData = (no) - This option specifies whether other tinc daemons besides the one - you specified with ConnectTo can make a direct connection to you. - This is especially useful if you are behind a firewall and it is - impossible to make a connection from the outside to your tinc - daemon. Otherwise, it is best to leave this option out or set it - to no. + When set to yes, other nodes which do not already have a meta + connection to you will not try to establish direct communication + with you. It is best to leave this option out or set it to no. MACLength = (4) The length of the message authentication code used to authenticate @@ -1412,10 +1408,11 @@ copy&paste the email: If you are the owner of bar yourself, and you have SSH access to that computer, you can also swap the host configuration files using the -following commands: +following command: - tincctl -n NETNAME export | ssh bar.example.org tincctl -n NETNAME import - ssh bar.example.org tincctl -n NETNAME export | tincctl -n NETNAME import + tincctl -n NETNAME export \ + | ssh bar.example.org tincctl -n NETNAME exchange \ + | tincctl -n NETNAME import You should repeat this for all nodes you ConnectTo, or which ConnectTo you. However, remember that you do not need to ConnectTo all @@ -1722,6 +1719,8 @@ command line options. shared private keys to be written to the system swap files/partitions. + This option is not supported on all platforms. + `--logfile[=FILE]' Write log entries to a file instead of to the system logging facility. If FILE is omitted, the default is @@ -1744,11 +1743,15 @@ command line options. or host-up), unless it's setup to be runnable inside chroot environment. + This option is not supported on all platforms. + `-U, --user=USER' Switch to the given USER after initialization, at the same time as chroot is performed (see -chroot above). With this option tinc drops privileges, for added security. + This option is not supported on all platforms. + `--help' Display a short reminder of these runtime options and terminate. @@ -2077,9 +2080,15 @@ File: tinc.info, Node: tincctl commands, Next: tincctl examples, Prev: tincct Export all host configuration files to standard output. `import [--force]' - Import host configuration file(s) from standard input. Already - existing host configuration files are not overwritten unless the - option -force is used. + Import host configuration file(s) generated by the tincctl export + command from standard input. Already existing host configuration + files are not overwritten unless the option -force is used. + +`exchange [--force]' + The same as export followed by import. + +`exchange-all [--force]' + The same as export-all followed by import. `start [tincd options]' Start `tincd', optionally with the given extra options. @@ -2840,7 +2849,7 @@ Concept Index * CHALLENGE: Authentication protocol. (line 10) * CIDR notation: Host configuration variables. - (line 91) + (line 88) * Cipher: Host configuration variables. (line 12) * ClampMSS: Host configuration variables. @@ -2882,7 +2891,7 @@ Concept Index * example: Example configuration. (line 6) * exec: Main configuration variables. - (line 322) + (line 321) * ExperimentalProtocol: Main configuration variables. (line 164) * Forwarding: Main configuration variables. @@ -2891,9 +2900,9 @@ Concept Index * Hostnames: Main configuration variables. (line 193) * http: Main configuration variables. - (line 319) + (line 318) * hub: Main configuration variables. - (line 246) + (line 245) * ID: Authentication protocol. (line 10) * IndirectData: Host configuration variables. @@ -2904,7 +2913,7 @@ Concept Index * IRC: Contact information. (line 9) * KEY_CHANGED: The meta-protocol. (line 64) * KeyExpire: Main configuration variables. - (line 251) + (line 250) * libcurses: libcurses. (line 6) * libraries: Libraries. (line 6) * libreadline: libreadline. (line 6) @@ -2913,9 +2922,9 @@ Concept Index (line 212) * lzo: lzo. (line 6) * MACExpire: Main configuration variables. - (line 257) + (line 256) * MACLength: Host configuration variables. - (line 42) + (line 39) * meta-protocol: The meta-connection. (line 18) * META_KEY: Authentication protocol. (line 10) @@ -2926,7 +2935,7 @@ Concept Index * multiple networks: Multiple networks. (line 6) * NAME: Scripts. (line 52) * Name: Main configuration variables. - (line 262) + (line 261) * netmask: Network interfaces. (line 39) * NETNAME <1>: tincctl environment variables. (line 6) @@ -2938,44 +2947,44 @@ Concept Index * OpenSSL: OpenSSL. (line 6) * options: Runtime options. (line 9) * PEM format: Host configuration variables. - (line 67) + (line 64) * PING: The meta-protocol. (line 89) * PingInterval: Main configuration variables. - (line 273) + (line 272) * PingTimeout: Main configuration variables. - (line 277) + (line 276) * platforms: Supported platforms. (line 6) * PMTU: Host configuration variables. - (line 47) + (line 44) * PMTUDiscovery: Host configuration variables. - (line 50) + (line 47) * PONG: The meta-protocol. (line 89) * Port: Host configuration variables. - (line 55) + (line 52) * port numbers: Other files. (line 17) * PriorityInheritance: Main configuration variables. - (line 283) + (line 282) * private: Virtual Private Networks. (line 10) * PrivateKey: Main configuration variables. - (line 288) + (line 287) * PrivateKeyFile: Main configuration variables. - (line 294) + (line 293) * ProcessPriority: Main configuration variables. - (line 299) + (line 298) * Proxy: Main configuration variables. - (line 304) + (line 303) * PublicKey: Host configuration variables. - (line 59) + (line 56) * PublicKeyFile: Host configuration variables. - (line 62) + (line 59) * raw_socket: Main configuration variables. (line 100) * release: Supported platforms. (line 14) * REMOTEADDRESS: Scripts. (line 67) * REMOTEPORT: Scripts. (line 70) * ReplayWindow: Main configuration variables. - (line 327) + (line 326) * REQ_KEY: The meta-protocol. (line 64) * requirements: Libraries. (line 6) * router: Main configuration variables. @@ -2987,20 +2996,20 @@ Concept Index (line 18) * signals: Signals. (line 6) * socks4: Main configuration variables. - (line 308) + (line 307) * socks5: Main configuration variables. - (line 313) + (line 312) * StrictSubnets: Main configuration variables. - (line 338) + (line 337) * SUBNET: Scripts. (line 74) * Subnet: Host configuration variables. - (line 74) + (line 71) * SVPN: Security. (line 11) * switch: Main configuration variables. - (line 235) + (line 234) * TCP: The meta-connection. (line 10) * TCPonly: Host configuration variables. - (line 103) + (line 100) * TINC: Security. (line 6) * tinc: Introduction. (line 6) * tinc-down: Scripts. (line 18) @@ -3011,16 +3020,16 @@ Concept Index * tunifhead: Main configuration variables. (line 142) * TunnelServer: Main configuration variables. - (line 343) + (line 342) * tunnohead: Main configuration variables. (line 136) * UDP <1>: Encryption of network packets. (line 12) * UDP: The UDP tunnel. (line 30) * UDPRcvBuf: Main configuration variables. - (line 350) + (line 349) * UDPSndBuf: Main configuration variables. - (line 355) + (line 354) * UML: Main configuration variables. (line 118) * Universal tun/tap: Configuration of Linux kernels. @@ -3073,39 +3082,39 @@ Node: Multiple networks23835 Node: How connections work25215 Node: Configuration files27788 Node: Main configuration variables29321 -Node: Host configuration variables45731 -Node: Scripts50961 -Node: How to configure53640 -Node: Network interfaces58258 -Node: Example configuration60659 -Node: Running tinc65811 -Node: Runtime options66404 -Node: Signals69108 -Node: Debug levels69958 -Node: Solving problems70894 -Node: Error messages72324 -Node: Sending bug reports76646 -Node: Controlling tinc77598 -Node: tincctl runtime options77995 -Node: tincctl environment variables78694 -Node: tincctl commands79038 -Node: tincctl examples83343 -Node: tincctl top83948 -Node: Technical information85546 -Node: The connection85781 -Node: The UDP tunnel86093 -Node: The meta-connection89154 -Node: The meta-protocol90623 -Node: Security95632 -Node: Authentication protocol96762 -Node: Encryption of network packets101766 -Node: Security issues103139 -Node: Platform specific information104756 -Node: Interface configuration104984 -Node: Routes107437 -Node: About us109353 -Node: Contact information109528 -Node: Authors109932 -Node: Concept Index110337 +Node: Host configuration variables45735 +Node: Scripts50810 +Node: How to configure53489 +Node: Network interfaces58079 +Node: Example configuration60480 +Node: Running tinc65632 +Node: Runtime options66225 +Node: Signals69088 +Node: Debug levels69938 +Node: Solving problems70874 +Node: Error messages72304 +Node: Sending bug reports76626 +Node: Controlling tinc77578 +Node: tincctl runtime options77975 +Node: tincctl environment variables78674 +Node: tincctl commands79018 +Node: tincctl examples83503 +Node: tincctl top84108 +Node: Technical information85706 +Node: The connection85941 +Node: The UDP tunnel86253 +Node: The meta-connection89314 +Node: The meta-protocol90783 +Node: Security95792 +Node: Authentication protocol96922 +Node: Encryption of network packets101926 +Node: Security issues103299 +Node: Platform specific information104916 +Node: Interface configuration105144 +Node: Routes107597 +Node: About us109513 +Node: Contact information109688 +Node: Authors110092 +Node: Concept Index110497  End Tag Table diff --git a/doc/tinc.texi b/doc/tinc.texi index 0e2b1eb..8910115 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-2012 Ivo Timmermans, +Copyright @copyright{} 1998-2013 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-2012 Ivo Timmermans, +Copyright @copyright{} 1998-2013 Ivo Timmermans, Guus Sliepen and Wessel Dankers . @@ -1063,7 +1063,7 @@ This option selects the way packets are routed to other daemons. @item router In this mode Subnet variables in the host configuration files will be used to form a routing table. -Only unicast packets of routable protocols (IPv4 and IPv6) are supported in this mode. +Only packets of routable protocols (IPv4 and IPv6) are supported in this mode. This is the default mode, and unless you really know you need another mode, don't change it. @@ -1098,12 +1098,12 @@ This only has effect when Mode is set to "switch". @cindex Name @item Name = <@var{name}> [required] This is a symbolic name for this connection. -The name should consist only of alfanumeric and underscore characters (a-z, A-Z, 0-9 and _). +The name should consist only of alfanumeric and underscore characters (a-z, A-Z, 0-9 and _), and is case sensitive. If Name starts with a $, then the contents of the environment variable that follows will be used. In that case, invalid characters will be converted to underscores. If Name is $HOST, but no such environment variable exist, -the hostname will be read using the gethostnname() system call. +the hostname will be read using the gethostname() system call. @cindex PingInterval @item PingInterval = <@var{seconds}> (60) @@ -1242,11 +1242,9 @@ Furthermore, specifying "none" will turn off packet authentication. @cindex IndirectData @item IndirectData = (no) -This option specifies whether other tinc daemons besides the one you -specified with ConnectTo can make a direct connection to you. This is -especially useful if you are behind a firewall and it is impossible to -make a connection from the outside to your tinc daemon. Otherwise, it -is best to leave this option out or set it to no. +When set to yes, other nodes which do not already have a meta connection to you +will not try to establish direct communication with you. +It is best to leave this option out or set it to no. @cindex MACLength @item MACLength = <@var{bytes}> (4) @@ -1515,11 +1513,12 @@ tincctl -n @var{netname} import @end example If you are the owner of bar yourself, and you have SSH access to that computer, -you can also swap the host configuration files using the following commands: +you can also swap the host configuration files using the following command: @example -tincctl -n @var{netname} export | ssh bar.example.org tincctl -n @var{netname} import -ssh bar.example.org tincctl -n @var{netname} export | tincctl -n @var{netname} import +tincctl -n @var{netname} export \ + | ssh bar.example.org tincctl -n @var{netname} exchange \ + | tincctl -n @var{netname} import @end example You should repeat this for all nodes you ConnectTo, or which ConnectTo you. @@ -1849,6 +1848,8 @@ This option can be used more than once to specify multiple configuration variabl Lock tinc into main memory. This will prevent sensitive data like shared private keys to be written to the system swap files/partitions. +This option is not supported on all platforms. + @item --logfile[=@var{file}] Write log entries to a file instead of to the system logging facility. If @var{file} is omitted, the default is @file{@value{localstatedir}/log/tinc.@var{netname}.log}. @@ -1869,11 +1870,14 @@ Note that this option alone does not do any good without -U/--user, below. Note also that tinc can't run scripts anymore (such as tinc-down or host-up), unless it's setup to be runnable inside chroot environment. +This option is not supported on all platforms. @item -U, --user=@var{user} Switch to the given @var{user} after initialization, at the same time as chroot is performed (see --chroot above). With this option tinc drops privileges, for added security. +This option is not supported on all platforms. + @item --help Display a short reminder of these runtime options and terminate. @@ -2196,9 +2200,15 @@ Export the host configuration file of the local node to standard output. Export all host configuration files to standard output. @item import [--force] -Import host configuration file(s) from standard input. +Import host configuration file(s) generated by the tincctl export command from standard input. Already existing host configuration files are not overwritten unless the option --force is used. +@item exchange [--force] +The same as export followed by import. + +@item exchange-all [--force] +The same as export-all followed by import. + @item start [tincd options] Start @samp{tincd}, optionally with the given extra options. diff --git a/doc/tincctl.8.in b/doc/tincctl.8.in index 8fdd272..e530116 100644 --- a/doc/tincctl.8.in +++ b/doc/tincctl.8.in @@ -1,4 +1,4 @@ -.Dd 2012-10-14 +.Dd 2013-01-15 .Dt TINCCTL 8 .\" Manual page created by: .\" Scott Lamb @@ -80,10 +80,16 @@ Export the host configuration file of the local node to standard output. .It export-all Export all host configuration files to standard output. .It import Op Fl -force -Import host configuration file(s) from standard input. +Import host configuration data generated by the +.Nm +export command from standard input. Already existing host configuration files are not overwritten unless the option .Fl -force is used. +.It exchange Op Fl -force +The same as export followed by import. +.It exchange-all Op Fl -force +The same as export-all followed by import. .It start Op tincd options Start .Xr tincd 8 , @@ -206,7 +212,7 @@ Fractional seconds are honored. Intervals lower than 0.1 seconds are not allowed. .It Ic c Toggle between displaying current traffic rates (in packets and bytes per second) -and cummulative traffic (total packets and bytes since the tinc daemon started). +and cumulative traffic (total packets and bytes since the tinc daemon started). .It Ic n Sort the list of nodes by name. .It Ic i diff --git a/doc/tincd.8.in b/doc/tincd.8.in index 9468120..88da75d 100644 --- a/doc/tincd.8.in +++ b/doc/tincd.8.in @@ -1,4 +1,4 @@ -.Dd 2012-02-22 +.Dd 2013-01-14 .Dt TINCD 8 .\" Manual page created by: .\" Ivo Timmermans @@ -81,6 +81,7 @@ This option can be used more than once to specify multiple configuration variabl .It Fl L, -mlock Lock tinc into main memory. This will prevent sensitive data like shared private keys to be written to the system swap files/partitions. +This option is not supported on all platforms. .It Fl -logfile Ns Op = Ns Ar FILE Write log entries to a file instead of to the system logging facility. If @@ -104,10 +105,12 @@ Only useful for debugging. With this option tinc chroots into the directory where network config is located (@sysconfdir@/tinc/NETNAME if -n option is used, or to the directory specified with -c option) after initialization. +This option is not supported on all platforms. .It Fl U, -user Ns = Ns Ar USER setuid to the specified .Ar USER after initialization. +This option is not supported on all platforms. .It Fl -help Display short list of options. .It Fl -version diff --git a/gui/tinc-gui b/gui/tinc-gui index 9c6485f..2b4f903 100755 --- a/gui/tinc-gui +++ b/gui/tinc-gui @@ -111,11 +111,28 @@ class VPN: piddir = '/var/run/' def connect(self): + # read the pidfile f = open(self.pidfile) info = string.split(f.readline()) f.close() - s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - s.connect((info[2], int(info[4]))) + + # check if there is a UNIX socket as well + if self.pidfile.endswith(".pid"): + unixfile = self.pidfile.replace(".pid", ".socket"); + else: + unixfile = self.pidfile + ".socket"; + + if os.path.exists(unixfile): + # use it if it exists + print(unixfile + " exists!"); + s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) + s.connect(unixfile) + else: + # otherwise connect via TCP + print(unixfile + " does not exist."); + s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + s.connect((info[2], int(info[4]))) + self.sf = s.makefile() s.close() hello = string.split(self.sf.readline()) diff --git a/src/Makefile.am b/src/Makefile.am index 6a8737b..eeee152 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -9,7 +9,7 @@ tincd_SOURCES = \ buffer.c conf.c connection.c control.c edge.c graph.c logger.c meta.c net.c net_packet.c net_setup.c \ net_socket.c netutl.c node.c process.c protocol.c protocol_auth.c protocol_edge.c protocol_misc.c \ protocol_key.c protocol_subnet.c route.c sptps.c subnet.c subnet_parse.c event.c tincd.c \ - dummy_device.c raw_socket_device.c multicast_device.c + dummy_device.c raw_socket_device.c multicast_device.c names.c if UML tincd_SOURCES += uml_device.c @@ -24,7 +24,7 @@ nodist_tincd_SOURCES = \ tincctl_SOURCES = \ utils.c getopt.c getopt1.c dropin.c \ - info.c list.c subnet_parse.c tincctl.c top.c + info.c list.c subnet_parse.c tincctl.c top.c names.c nodist_tincctl_SOURCES = \ ecdsagen.c rsagen.c @@ -46,7 +46,7 @@ INCLUDES = @INCLUDES@ -I$(top_builddir) noinst_HEADERS = \ xalloc.h utils.h getopt.h list.h splay_tree.h dropin.h fake-getaddrinfo.h fake-getnameinfo.h fake-gai-errnos.h ipv6.h ipv4.h ethernet.h \ buffer.h conf.h connection.h control.h control_common.h device.h edge.h graph.h info.h logger.h meta.h net.h netutl.h node.h process.h \ - protocol.h route.h subnet.h sptps.h tincctl.h top.h bsd/tunemu.h hash.h event.h + protocol.h route.h subnet.h sptps.h tincctl.h top.h bsd/tunemu.h hash.h event.h names.h nodist_noinst_HEADERS = \ cipher.h crypto.h ecdh.h ecdsa.h digest.h prf.h rsa.h ecdsagen.h rsagen.h diff --git a/src/Makefile.in b/src/Makefile.in index 37eaa7c..b1d4551 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -82,7 +82,7 @@ sptps_test_LDADD = $(LDADD) am_tincctl_OBJECTS = utils.$(OBJEXT) getopt.$(OBJEXT) \ getopt1.$(OBJEXT) dropin.$(OBJEXT) info.$(OBJEXT) \ list.$(OBJEXT) subnet_parse.$(OBJEXT) tincctl.$(OBJEXT) \ - top.$(OBJEXT) + top.$(OBJEXT) names.$(OBJEXT) nodist_tincctl_OBJECTS = ecdsagen.$(OBJEXT) rsagen.$(OBJEXT) tincctl_OBJECTS = $(am_tincctl_OBJECTS) $(nodist_tincctl_OBJECTS) am__DEPENDENCIES_1 = @@ -95,7 +95,8 @@ am__tincd_SOURCES_DIST = utils.c getopt.c getopt1.c list.c \ protocol_edge.c protocol_misc.c protocol_key.c \ protocol_subnet.c route.c sptps.c subnet.c subnet_parse.c \ event.c tincd.c dummy_device.c raw_socket_device.c \ - multicast_device.c uml_device.c vde_device.c bsd/tunemu.c + multicast_device.c names.c uml_device.c vde_device.c \ + bsd/tunemu.c @UML_TRUE@am__objects_1 = uml_device.$(OBJEXT) @VDE_TRUE@am__objects_2 = vde_device.$(OBJEXT) @TUNEMU_TRUE@am__objects_3 = tunemu.$(OBJEXT) @@ -113,8 +114,8 @@ am_tincd_OBJECTS = utils.$(OBJEXT) getopt.$(OBJEXT) getopt1.$(OBJEXT) \ route.$(OBJEXT) sptps.$(OBJEXT) subnet.$(OBJEXT) \ subnet_parse.$(OBJEXT) event.$(OBJEXT) tincd.$(OBJEXT) \ dummy_device.$(OBJEXT) raw_socket_device.$(OBJEXT) \ - multicast_device.$(OBJEXT) $(am__objects_1) $(am__objects_2) \ - $(am__objects_3) + multicast_device.$(OBJEXT) names.$(OBJEXT) $(am__objects_1) \ + $(am__objects_2) $(am__objects_3) nodist_tincd_OBJECTS = device.$(OBJEXT) cipher.$(OBJEXT) \ crypto.$(OBJEXT) ecdh.$(OBJEXT) ecdsa.$(OBJEXT) \ digest.$(OBJEXT) prf.$(OBJEXT) rsa.$(OBJEXT) @@ -252,14 +253,14 @@ tincd_SOURCES = utils.c getopt.c getopt1.c list.c splay_tree.c \ process.c protocol.c protocol_auth.c protocol_edge.c \ protocol_misc.c protocol_key.c protocol_subnet.c route.c \ sptps.c subnet.c subnet_parse.c event.c tincd.c dummy_device.c \ - raw_socket_device.c multicast_device.c $(am__append_1) \ + raw_socket_device.c multicast_device.c names.c $(am__append_1) \ $(am__append_2) $(am__append_3) nodist_tincd_SOURCES = \ device.c cipher.c crypto.c ecdh.c ecdsa.c digest.c prf.c rsa.c tincctl_SOURCES = \ utils.c getopt.c getopt1.c dropin.c \ - info.c list.c subnet_parse.c tincctl.c top.c + info.c list.c subnet_parse.c tincctl.c top.c names.c nodist_tincctl_SOURCES = \ ecdsagen.c rsagen.c @@ -273,7 +274,7 @@ DEFAULT_INCLUDES = noinst_HEADERS = \ xalloc.h utils.h getopt.h list.h splay_tree.h dropin.h fake-getaddrinfo.h fake-getnameinfo.h fake-gai-errnos.h ipv6.h ipv4.h ethernet.h \ buffer.h conf.h connection.h control.h control_common.h device.h edge.h graph.h info.h logger.h meta.h net.h netutl.h node.h process.h \ - protocol.h route.h subnet.h sptps.h tincctl.h top.h bsd/tunemu.h hash.h event.h + protocol.h route.h subnet.h sptps.h tincctl.h top.h bsd/tunemu.h hash.h event.h names.h nodist_noinst_HEADERS = \ cipher.h crypto.h ecdh.h ecdsa.h digest.h prf.h rsa.h ecdsagen.h rsagen.h @@ -395,6 +396,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/logger.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/meta.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/multicast_device.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/names.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/net.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/net_packet.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/net_setup.Po@am__quote@ diff --git a/src/bsd/device.c b/src/bsd/device.c index 3e64ba9..9bf0cd5 100644 --- a/src/bsd/device.c +++ b/src/bsd/device.c @@ -1,7 +1,7 @@ /* device.c -- Interaction BSD tun/tap device Copyright (C) 2001-2005 Ivo Timmermans, - 2001-2012 Guus Sliepen + 2001-2013 Guus Sliepen 2009 Grzegorz Dymarek This program is free software; you can redistribute it and/or modify @@ -24,12 +24,13 @@ #include "conf.h" #include "device.h" #include "logger.h" +#include "names.h" #include "net.h" #include "route.h" #include "utils.h" #include "xalloc.h" -#ifdef HAVE_TUNEMU +#ifdef ENABLE_TUNEMU #include "bsd/tunemu.h" #endif @@ -44,7 +45,7 @@ typedef enum device_type { DEVICE_TYPE_TUN, DEVICE_TYPE_TUNIFHEAD, DEVICE_TYPE_TAP, -#ifdef HAVE_TUNEMU +#ifdef ENABLE_TUNEMU DEVICE_TYPE_TUNEMU, #endif } device_type_t; @@ -55,7 +56,7 @@ char *iface = NULL; static char *device_info = NULL; static uint64_t device_total_in = 0; static uint64_t device_total_out = 0; -#if defined(TUNEMU) +#if defined(ENABLE_TUNEMU) static device_type_t device_type = DEVICE_TYPE_TUNEMU; #elif defined(HAVE_OPENBSD) || defined(HAVE_FREEBSD) || defined(HAVE_DRAGONFLY) static device_type_t device_type = DEVICE_TYPE_TUNIFHEAD; @@ -79,7 +80,7 @@ static bool setup_device(void) { if(get_config_string(lookup_config(config_tree, "DeviceType"), &type)) { if(!strcasecmp(type, "tun")) /* use default */; -#ifdef HAVE_TUNEMU +#ifdef ENABLE_TUNEMU else if(!strcasecmp(type, "tunemu")) device_type = DEVICE_TYPE_TUNEMU; #endif @@ -99,7 +100,7 @@ static bool setup_device(void) { } switch(device_type) { -#ifdef HAVE_TUNEMU +#ifdef ENABLE_TUNEMU case DEVICE_TYPE_TUNEMU: { char dynamic_name[256] = ""; device_fd = tunemu_open(dynamic_name); @@ -176,7 +177,7 @@ static bool setup_device(void) { #endif break; -#ifdef HAVE_TUNEMU +#ifdef ENABLE_TUNEMU case DEVICE_TYPE_TUNEMU: device_info = "BSD tunemu device"; break; @@ -190,7 +191,7 @@ static bool setup_device(void) { static void close_device(void) { switch(device_type) { -#ifdef HAVE_TUNEMU +#ifdef ENABLE_TUNEMU case DEVICE_TYPE_TUNEMU: tunemu_close(device_fd); break; @@ -208,7 +209,7 @@ static bool read_packet(vpn_packet_t *packet) { switch(device_type) { case DEVICE_TYPE_TUN: -#ifdef HAVE_TUNEMU +#ifdef ENABLE_TUNEMU case DEVICE_TYPE_TUNEMU: if(device_type == DEVICE_TYPE_TUNEMU) inlen = tunemu_read(device_fd, packet->data + 14, MTU - 14); @@ -347,7 +348,7 @@ static bool write_packet(vpn_packet_t *packet) { } break; -#ifdef HAVE_TUNEMU +#ifdef ENABLE_TUNEMU case DEVICE_TYPE_TUNEMU: if(tunemu_write(device_fd, packet->data + 14, packet->len - 14) < 0) { logger(DEBUG_ALWAYS, LOG_ERR, "Error while writing to %s %s: %s", device_info, diff --git a/src/bsd/device.c.orig b/src/bsd/device.c.orig new file mode 100644 index 0000000..a204040 --- /dev/null +++ b/src/bsd/device.c.orig @@ -0,0 +1,386 @@ +/* + device.c -- Interaction BSD tun/tap device + Copyright (C) 2001-2005 Ivo Timmermans, + 2001-2012 Guus Sliepen + 2009 Grzegorz Dymarek + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "system.h" + +#include "conf.h" +#include "device.h" +#include "logger.h" +#include "net.h" +#include "route.h" +#include "utils.h" +#include "xalloc.h" + +#ifdef ENABLE_TUNEMU +#include "bsd/tunemu.h" +#endif + +#define DEFAULT_TUN_DEVICE "/dev/tun0" +#if defined(HAVE_FREEBSD) || defined(HAVE_NETBSD) +#define DEFAULT_TAP_DEVICE "/dev/tap0" +#else +#define DEFAULT_TAP_DEVICE "/dev/tun0" +#endif + +typedef enum device_type { + DEVICE_TYPE_TUN, + DEVICE_TYPE_TUNIFHEAD, + DEVICE_TYPE_TAP, +#ifdef ENABLE_TUNEMU + DEVICE_TYPE_TUNEMU, +#endif +} device_type_t; + +int device_fd = -1; +char *device = NULL; +char *iface = NULL; +static char *device_info = NULL; +static uint64_t device_total_in = 0; +static uint64_t device_total_out = 0; +#if defined(ENABLE_TUNEMU) +static device_type_t device_type = DEVICE_TYPE_TUNEMU; +#elif defined(HAVE_OPENBSD) || defined(HAVE_FREEBSD) || defined(HAVE_DRAGONFLY) +static device_type_t device_type = DEVICE_TYPE_TUNIFHEAD; +#else +static device_type_t device_type = DEVICE_TYPE_TUN; +#endif + +static bool setup_device(void) { + char *type; + + if(!get_config_string(lookup_config(config_tree, "Device"), &device)) { + if(routing_mode == RMODE_ROUTER) + device = xstrdup(DEFAULT_TUN_DEVICE); + else + device = xstrdup(DEFAULT_TAP_DEVICE); + } + + if(!get_config_string(lookup_config(config_tree, "Interface"), &iface)) + iface = xstrdup(strrchr(device, '/') ? strrchr(device, '/') + 1 : device); + + if(get_config_string(lookup_config(config_tree, "DeviceType"), &type)) { + if(!strcasecmp(type, "tun")) +<<<<<<< HEAD + /* use default */; +#ifdef HAVE_TUNEMU +======= + /* use default */; +#ifdef ENABLE_TUNEMU +>>>>>>> 2a3e343... Fix support for tunemu on iOS devices. + else if(!strcasecmp(type, "tunemu")) + device_type = DEVICE_TYPE_TUNEMU; +#endif + else if(!strcasecmp(type, "tunnohead")) + device_type = DEVICE_TYPE_TUN; + else if(!strcasecmp(type, "tunifhead")) + device_type = DEVICE_TYPE_TUNIFHEAD; + else if(!strcasecmp(type, "tap")) + device_type = DEVICE_TYPE_TAP; + else { + logger(DEBUG_ALWAYS, LOG_ERR, "Unknown device type %s!", type); + return false; + } + } else { + if(strstr(device, "tap") || routing_mode != RMODE_ROUTER) + device_type = DEVICE_TYPE_TAP; + } + + switch(device_type) { +#ifdef ENABLE_TUNEMU + case DEVICE_TYPE_TUNEMU: { + char dynamic_name[256] = ""; + device_fd = tunemu_open(dynamic_name); + } + break; +#endif + default: + device_fd = open(device, O_RDWR | O_NONBLOCK); + } + + if(device_fd < 0) { + logger(DEBUG_ALWAYS, LOG_ERR, "Could not open %s: %s", device, strerror(errno)); + return false; + } + +#ifdef FD_CLOEXEC + fcntl(device_fd, F_SETFD, FD_CLOEXEC); +#endif + + switch(device_type) { + default: + device_type = DEVICE_TYPE_TUN; + case DEVICE_TYPE_TUN: +#ifdef TUNSIFHEAD + { + const int zero = 0; + if(ioctl(device_fd, TUNSIFHEAD, &zero, sizeof zero) == -1) { + logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "ioctl", strerror(errno)); + return false; + } + } +#endif +#if defined(TUNSIFMODE) && defined(IFF_BROADCAST) && defined(IFF_MULTICAST) + { + const int mode = IFF_BROADCAST | IFF_MULTICAST; + ioctl(device_fd, TUNSIFMODE, &mode, sizeof mode); + } +#endif + + device_info = "Generic BSD tun device"; + break; + case DEVICE_TYPE_TUNIFHEAD: +#ifdef TUNSIFHEAD + { + const int one = 1; + if(ioctl(device_fd, TUNSIFHEAD, &one, sizeof one) == -1) { + logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "ioctl", strerror(errno)); + return false; + } + } +#endif +#if defined(TUNSIFMODE) && defined(IFF_BROADCAST) && defined(IFF_MULTICAST) + { + const int mode = IFF_BROADCAST | IFF_MULTICAST; + ioctl(device_fd, TUNSIFMODE, &mode, sizeof mode); + } +#endif + + device_info = "Generic BSD tun device"; + break; + case DEVICE_TYPE_TAP: + if(routing_mode == RMODE_ROUTER) + overwrite_mac = true; + device_info = "Generic BSD tap device"; +#ifdef TAPGIFNAME + { + struct ifreq ifr; + if(ioctl(device_fd, TAPGIFNAME, (void*)&ifr) == 0) { + if(iface) + free(iface); + iface = xstrdup(ifr.ifr_name); + } + } + +#endif + break; +#ifdef ENABLE_TUNEMU + case DEVICE_TYPE_TUNEMU: + device_info = "BSD tunemu device"; + break; +#endif + } + + logger(DEBUG_ALWAYS, LOG_INFO, "%s is a %s", device, device_info); + + return true; +} + +static void close_device(void) { + switch(device_type) { +#ifdef ENABLE_TUNEMU + case DEVICE_TYPE_TUNEMU: + tunemu_close(device_fd); + break; +#endif + default: + close(device_fd); + } + + free(device); + free(iface); +} + +static bool read_packet(vpn_packet_t *packet) { + int inlen; + + switch(device_type) { + case DEVICE_TYPE_TUN: +#ifdef ENABLE_TUNEMU + case DEVICE_TYPE_TUNEMU: + if(device_type == DEVICE_TYPE_TUNEMU) + inlen = tunemu_read(device_fd, packet->data + 14, MTU - 14); + else +#endif + inlen = read(device_fd, packet->data + 14, MTU - 14); + + if(inlen <= 0) { + logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info, + device, strerror(errno)); + return false; + } + + switch(packet->data[14] >> 4) { + case 4: + packet->data[12] = 0x08; + packet->data[13] = 0x00; + break; + case 6: + packet->data[12] = 0x86; + packet->data[13] = 0xDD; + break; + default: + logger(DEBUG_TRAFFIC, LOG_ERR, + "Unknown IP version %d while reading packet from %s %s", + packet->data[14] >> 4, device_info, device); + return false; + } + + memset(packet->data, 0, 12); + packet->len = inlen + 14; + break; + + case DEVICE_TYPE_TUNIFHEAD: { + u_int32_t type; + struct iovec vector[2] = {{&type, sizeof type}, {packet->data + 14, MTU - 14}}; + + if((inlen = readv(device_fd, vector, 2)) <= 0) { + logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info, + device, strerror(errno)); + return false; + } + + switch (ntohl(type)) { + case AF_INET: + packet->data[12] = 0x08; + packet->data[13] = 0x00; + break; + + case AF_INET6: + packet->data[12] = 0x86; + packet->data[13] = 0xDD; + break; + + default: + logger(DEBUG_TRAFFIC, LOG_ERR, + "Unknown address family %x while reading packet from %s %s", + ntohl(type), device_info, device); + return false; + } + + memset(packet->data, 0, 12); + packet->len = inlen + 10; + break; + } + + case DEVICE_TYPE_TAP: + if((inlen = read(device_fd, packet->data, MTU)) <= 0) { + logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info, + device, strerror(errno)); + return false; + } + + packet->len = inlen; + break; + + default: + return false; + } + + device_total_in += packet->len; + + logger(DEBUG_TRAFFIC, LOG_DEBUG, "Read packet of %d bytes from %s", + packet->len, device_info); + + return true; +} + +static bool write_packet(vpn_packet_t *packet) { + logger(DEBUG_TRAFFIC, LOG_DEBUG, "Writing packet of %d bytes to %s", + packet->len, device_info); + + switch(device_type) { + case DEVICE_TYPE_TUN: + if(write(device_fd, packet->data + 14, packet->len - 14) < 0) { + logger(DEBUG_ALWAYS, LOG_ERR, "Error while writing to %s %s: %s", device_info, + device, strerror(errno)); + return false; + } + break; + + case DEVICE_TYPE_TUNIFHEAD: { + u_int32_t type; + struct iovec vector[2] = {{&type, sizeof type}, {packet->data + 14, packet->len - 14}}; + int af; + + af = (packet->data[12] << 8) + packet->data[13]; + + switch (af) { + case 0x0800: + type = htonl(AF_INET); + break; + case 0x86DD: + type = htonl(AF_INET6); + break; + default: + logger(DEBUG_TRAFFIC, LOG_ERR, + "Unknown address family %x while writing packet to %s %s", + af, device_info, device); + return false; + } + + if(writev(device_fd, vector, 2) < 0) { + logger(DEBUG_ALWAYS, LOG_ERR, "Can't write to %s %s: %s", device_info, device, + strerror(errno)); + return false; + } + break; + } + + case DEVICE_TYPE_TAP: + if(write(device_fd, packet->data, packet->len) < 0) { + logger(DEBUG_ALWAYS, LOG_ERR, "Error while writing to %s %s: %s", device_info, + device, strerror(errno)); + return false; + } + break; + +#ifdef ENABLE_TUNEMU + case DEVICE_TYPE_TUNEMU: + if(tunemu_write(device_fd, packet->data + 14, packet->len - 14) < 0) { + logger(DEBUG_ALWAYS, LOG_ERR, "Error while writing to %s %s: %s", device_info, + device, strerror(errno)); + return false; + } + break; +#endif + + default: + return false; + } + + device_total_out += packet->len; + + return true; +} + +static void dump_device_stats(void) { + logger(DEBUG_ALWAYS, LOG_DEBUG, "Statistics for %s %s:", device_info, device); + logger(DEBUG_ALWAYS, LOG_DEBUG, " total bytes in: %10"PRIu64, device_total_in); + logger(DEBUG_ALWAYS, LOG_DEBUG, " total bytes out: %10"PRIu64, device_total_out); +} + +const devops_t os_devops = { + .setup = setup_device, + .close = close_device, + .read = read_packet, + .write = write_packet, + .dump_stats = dump_device_stats, +}; diff --git a/src/conf.c b/src/conf.c index b9bfbf6..c4f8abb 100644 --- a/src/conf.c +++ b/src/conf.c @@ -2,7 +2,7 @@ conf.c -- configuration code Copyright (C) 1998 Robert van der Meulen 1998-2005 Ivo Timmermans - 2000-2012 Guus Sliepen + 2000-2013 Guus Sliepen 2010-2011 Julien Muchembled 2000 Cris van Pelt @@ -28,6 +28,7 @@ #include "conf.h" #include "list.h" #include "logger.h" +#include "names.h" #include "netutl.h" /* for str2address */ #include "protocol.h" #include "utils.h" /* for cp */ @@ -37,11 +38,8 @@ splay_tree_t *config_tree; int pinginterval = 0; /* seconds between pings */ int pingtimeout = 0; /* seconds to wait for response */ -char *confbase = NULL; /* directory in which all config files are */ -char *netname = NULL; /* name of the vpn network */ list_t *cmdline_conf = NULL; /* global/host configuration values given at the command line */ - static int config_compare(const config_t *a, const config_t *b) { int result; diff --git a/src/conf.h b/src/conf.h index 20a78a9..4f39b20 100644 --- a/src/conf.h +++ b/src/conf.h @@ -1,7 +1,7 @@ /* conf.h -- header for conf.c Copyright (C) 1998-2005 Ivo Timmermans - 2000-2012 Guus Sliepen + 2000-2013 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 @@ -39,8 +39,6 @@ extern int pinginterval; extern int pingtimeout; extern int maxtimeout; extern bool bypass_security; -extern char *confbase; -extern char *netname; extern list_t *cmdline_conf; extern void init_configuration(splay_tree_t **); diff --git a/src/control.c b/src/control.c index 83a9d79..539ff36 100644 --- a/src/control.c +++ b/src/control.c @@ -1,6 +1,6 @@ /* control.c -- Control socket handling. - Copyright (C) 2012 Guus Sliepen + Copyright (C) 2013 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 @@ -25,6 +25,7 @@ #include "graph.h" #include "logger.h" #include "meta.h" +#include "names.h" #include "net.h" #include "netutl.h" #include "protocol.h" @@ -33,7 +34,6 @@ #include "xalloc.h" char controlcookie[65]; -extern char *pidfilename; static bool control_return(connection_t *c, int type, int error) { return send_request(c, "%d %d %d", CONTROL, type, error); diff --git a/src/cygwin/device.c b/src/cygwin/device.c index 6266e87..b050140 100644 --- a/src/cygwin/device.c +++ b/src/cygwin/device.c @@ -1,7 +1,7 @@ /* device.c -- Interaction with Windows tap driver in a Cygwin environment Copyright (C) 2002-2005 Ivo Timmermans, - 2002-2012 Guus Sliepen + 2002-2013 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 @@ -26,6 +26,7 @@ #include "conf.h" #include "device.h" #include "logger.h" +#include "names.h" #include "net.h" #include "route.h" #include "utils.h" diff --git a/src/dropin.c b/src/dropin.c index f1a51ac..ab3fd6b 100644 --- a/src/dropin.c +++ b/src/dropin.c @@ -158,8 +158,18 @@ int vasprintf(char **buf, const char *fmt, va_list ap) { #ifndef HAVE_GETTIMEOFDAY int gettimeofday(struct timeval *tv, void *tz) { +#ifdef HAVE_MINGW + FILETIME ft; + GetSystemTimeAsFileTime(&ft); + uint64_t lt = (uint64_t)ft.dwLowDateTime | ((uint64_t)ft.dwHighDateTime << 32); + lt -= 116444736000000000ULL; + tv->tv_sec = lt / 10000000; + tv->tv_usec = (lt / 10) % 1000000; +#else +#warning No high resolution time source! tv->tv_sec = time(NULL); tv->tv_usec = 0; +#endif return 0; } #endif diff --git a/src/dropin.h b/src/dropin.h index 61143eb..5279de7 100644 --- a/src/dropin.h +++ b/src/dropin.h @@ -58,7 +58,7 @@ extern int usleep(long long usec); #define timersub(a, b, r) do {\ (r)->tv_sec = (a)->tv_sec - (b)->tv_sec;\ (r)->tv_usec = (a)->tv_usec - (b)->tv_usec;\ - if((r)->tv_usec < 1000000)\ + if((r)->tv_usec < 0)\ (r)->tv_sec--, (r)->tv_usec += 1000000;\ } while (0) #endif diff --git a/src/event.c b/src/event.c index 0dde994..6b730f6 100644 --- a/src/event.c +++ b/src/event.c @@ -52,13 +52,8 @@ static int timeout_compare(const timeout_t *a, const timeout_t *b) { return 0; } -static int signal_compare(const signal_t *a, const signal_t *b) { - return a->signum - b->signum; -} - static splay_tree_t io_tree = {.compare = (splay_compare_t)io_compare}; static splay_tree_t timeout_tree = {.compare = (splay_compare_t)timeout_compare}; -static splay_tree_t signal_tree = {.compare = (splay_compare_t)signal_compare}; void io_add(io_t *io, io_cb_t cb, void *data, int fd, int flags) { if(io->cb) @@ -130,8 +125,13 @@ void timeout_del(timeout_t *timeout) { } #ifndef HAVE_MINGW +static int signal_compare(const signal_t *a, const signal_t *b) { + return a->signum - b->signum; +} + static io_t signalio; static int pipefd[2] = {-1, -1}; +static splay_tree_t signal_tree = {.compare = (splay_compare_t)signal_compare}; static void signal_handler(int signum) { unsigned char num = signum; diff --git a/src/graph.c b/src/graph.c index 73db3b2..7079f93 100644 --- a/src/graph.c +++ b/src/graph.c @@ -1,6 +1,6 @@ /* graph.c -- graph algorithms - Copyright (C) 2001-2012 Guus Sliepen , + Copyright (C) 2001-2013 Guus Sliepen , 2001-2005 Ivo Timmermans This program is free software; you can redistribute it and/or modify @@ -51,6 +51,7 @@ #include "graph.h" #include "list.h" #include "logger.h" +#include "names.h" #include "netutl.h" #include "node.h" #include "process.h" @@ -61,7 +62,7 @@ #include "graph.h" /* Implementation of Kruskal's algorithm. - Running time: O(E) + Running time: O(EN) Please note that sorting on weight is already done by add_edge(). */ @@ -78,11 +79,24 @@ static void mst_kruskal(void) { for splay_each(node_t, n, node_tree) n->status.visited = false; - /* Add safe edges */ + /* Starting point */ for splay_each(edge_t, e, edge_weight_tree) { - if(!e->reverse || (e->from->status.visited && e->to->status.visited)) + if(e->from->status.reachable) { + e->from->status.visited = true; + break; + } + } + + /* Add safe edges */ + + bool skipped = false; + + for splay_each(edge_t, e, edge_weight_tree) { + if(!e->reverse || (e->from->status.visited == e->to->status.visited)) { + skipped = true; continue; + } e->from->status.visited = true; e->to->status.visited = true; @@ -93,8 +107,12 @@ static void mst_kruskal(void) { if(e->reverse->connection) e->reverse->connection->status.mst = true; - logger(DEBUG_SCARY_THINGS, LOG_DEBUG, " Adding edge %s - %s weight %d", e->from->name, - e->to->name, e->weight); + logger(DEBUG_SCARY_THINGS, LOG_DEBUG, " Adding edge %s - %s weight %d", e->from->name, e->to->name, e->weight); + + if(skipped) { + skipped = false; + next = edge_weight_tree->head; + } } } diff --git a/src/info.c b/src/info.c index 25d51bf..8e91a22 100644 --- a/src/info.c +++ b/src/info.c @@ -58,11 +58,15 @@ static int info_node(int fd, const char *item) { int code, req, cipher, digest, maclength, compression, distance; short int pmtu, minmtu, maxmtu; unsigned int options; + union { + node_status_t bits; + uint32_t raw; + } status_union; node_status_t status; long int last_state_change; while(recvline(fd, line, sizeof line)) { - int n = sscanf(line, "%d %d %s %s port %s %d %d %d %d %x %x %s %s %d %hd %hd %hd %ld", &code, &req, node, host, port, &cipher, &digest, &maclength, &compression, &options, (unsigned *)&status, nexthop, via, &distance, &pmtu, &minmtu, &maxmtu, &last_state_change); + int n = sscanf(line, "%d %d %s %s port %s %d %d %d %d %x %"PRIx32" %s %s %d %hd %hd %hd %ld", &code, &req, node, host, port, &cipher, &digest, &maclength, &compression, &options, &status_union.raw, nexthop, via, &distance, &pmtu, &minmtu, &maxmtu, &last_state_change); if(n == 2) break; @@ -92,8 +96,12 @@ static int info_node(int fd, const char *item) { printf("Address: %s port %s\n", host, port); char timestr[32] = "never"; + time_t lsc_time = last_state_change; + if(last_state_change) - strftime(timestr, sizeof timestr, "%Y-%m-%d %H:%M:%S", localtime(&last_state_change)); + strftime(timestr, sizeof timestr, "%Y-%m-%d %H:%M:%S", localtime(&lsc_time)); + + status = status_union.bits; if(status.reachable) printf("Online since: %s\n", timestr); diff --git a/src/linux/device.c b/src/linux/device.c index 18f1b6e..e262c6a 100644 --- a/src/linux/device.c +++ b/src/linux/device.c @@ -1,7 +1,7 @@ /* device.c -- Interaction with Linux ethertap and tun/tap device Copyright (C) 2001-2005 Ivo Timmermans, - 2001-2012 Guus Sliepen + 2001-2013 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 @@ -26,6 +26,7 @@ #include "conf.h" #include "device.h" #include "logger.h" +#include "names.h" #include "net.h" #include "route.h" #include "utils.h" diff --git a/src/logger.c b/src/logger.c index e01980e..2b4c7e3 100644 --- a/src/logger.c +++ b/src/logger.c @@ -1,6 +1,6 @@ /* logger.c -- logging code - Copyright (C) 2004-2012 Guus Sliepen + Copyright (C) 2004-2013 Guus Sliepen 2004-2005 Ivo Timmermans This program is free software; you can redistribute it and/or modify @@ -22,6 +22,7 @@ #include "conf.h" #include "meta.h" +#include "names.h" #include "logger.h" #include "connection.h" #include "control_common.h" @@ -30,7 +31,6 @@ debug_t debug_level = DEBUG_NOTHING; static logmode_t logmode = LOGMODE_STDERR; static pid_t logpid; -extern char *logfilename; static FILE *logfile = NULL; #ifdef HAVE_MINGW static HANDLE loghandle = NULL; diff --git a/src/meta.c b/src/meta.c index 1244bfd..fafba65 100644 --- a/src/meta.c +++ b/src/meta.c @@ -185,21 +185,50 @@ bool receive_meta(connection_t *c) { if(c->tcplen) { char *tcpbuffer = buffer_read(&c->inbuf, c->tcplen); - if(tcpbuffer) { - if(proxytype == PROXY_SOCKS4 && c->allow_request == ID) { + if(!tcpbuffer) + break; + + if(!c->node) { + if(c->outgoing && proxytype == PROXY_SOCKS4 && c->allow_request == ID) { if(tcpbuffer[0] == 0 && tcpbuffer[1] == 0x5a) { logger(DEBUG_CONNECTIONS, LOG_DEBUG, "Proxy request granted"); } else { logger(DEBUG_CONNECTIONS, LOG_ERR, "Proxy request rejected"); return false; } - } else - receive_tcppacket(c, tcpbuffer, c->tcplen); - c->tcplen = 0; - continue; + } else if(c->outgoing && proxytype == PROXY_SOCKS5 && c->allow_request == ID) { + if(tcpbuffer[0] != 5) { + logger(DEBUG_CONNECTIONS, LOG_ERR, "Invalid response from proxy server"); + return false; + } + if(tcpbuffer[1] == (char)0xff) { + logger(DEBUG_CONNECTIONS, LOG_ERR, "Proxy request rejected: unsuitable authentication method"); + return false; + } + if(tcpbuffer[2] != 5) { + logger(DEBUG_CONNECTIONS, LOG_ERR, "Invalid response from proxy server"); + return false; + } + if(tcpbuffer[3] == 0) { + logger(DEBUG_CONNECTIONS, LOG_DEBUG, "Proxy request granted"); + } else { + logger(DEBUG_CONNECTIONS, LOG_DEBUG, "Proxy request rejected"); + return false; + } + } else { + logger(DEBUG_CONNECTIONS, LOG_ERR, "c->tcplen set but c->node is NULL!"); + abort(); + } } else { - break; + if(c->allow_request == ALL) { + receive_tcppacket(c, tcpbuffer, c->tcplen); + } else { + logger(DEBUG_CONNECTIONS, LOG_ERR, "Got unauthorized TCP packet from %s (%s)", c->name, c->hostname); + return false; + } } + + c->tcplen = 0; } /* Otherwise we are waiting for a request */ diff --git a/src/mingw/device.c b/src/mingw/device.c index 3b1458c..aa05972 100644 --- a/src/mingw/device.c +++ b/src/mingw/device.c @@ -1,7 +1,7 @@ /* device.c -- Interaction with Windows tap driver in a MinGW environment Copyright (C) 2002-2005 Ivo Timmermans, - 2002-2012 Guus Sliepen + 2002-2013 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 @@ -26,6 +26,7 @@ #include "conf.h" #include "device.h" #include "logger.h" +#include "names.h" #include "net.h" #include "route.h" #include "utils.h" @@ -46,7 +47,7 @@ extern char *myport; static DWORD WINAPI tapreader(void *bla) { int status; - long len; + DWORD len; OVERLAPPED overlapped; vpn_packet_t packet; @@ -61,7 +62,7 @@ static DWORD WINAPI tapreader(void *bla) { overlapped.OffsetHigh = 0; ResetEvent(overlapped.hEvent); - status = ReadFile(device_handle, packet.data, MTU, &len, &overlapped); + status = ReadFile(device_handle, (void *)packet.data, MTU, &len, &overlapped); if(!status) { if(GetLastError() == ERROR_IO_PENDING) { @@ -91,7 +92,7 @@ static bool setup_device(void) { char adapterid[1024]; char adaptername[1024]; char tapname[1024]; - long len; + DWORD len; unsigned long status; bool found = false; @@ -122,7 +123,7 @@ static bool setup_device(void) { continue; len = sizeof adaptername; - err = RegQueryValueEx(key2, "Name", 0, 0, adaptername, &len); + err = RegQueryValueEx(key2, "Name", 0, 0, (LPBYTE)adaptername, &len); RegCloseKey(key2); @@ -222,7 +223,7 @@ static bool read_packet(vpn_packet_t *packet) { } static bool write_packet(vpn_packet_t *packet) { - long outlen; + DWORD outlen; OVERLAPPED overlapped = {0}; logger(DEBUG_TRAFFIC, LOG_DEBUG, "Writing packet of %d bytes to %s", diff --git a/src/multicast_device.c b/src/multicast_device.c index bd9ef1d..e58d293 100644 --- a/src/multicast_device.c +++ b/src/multicast_device.c @@ -165,7 +165,7 @@ static void close_device(void) { static bool read_packet(vpn_packet_t *packet) { int lenin; - if((lenin = recv(device_fd, packet->data, MTU, 0)) <= 0) { + if((lenin = recv(device_fd, (void *)packet->data, MTU, 0)) <= 0) { logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info, device, strerror(errno)); return false; @@ -191,7 +191,7 @@ static bool write_packet(vpn_packet_t *packet) { logger(DEBUG_TRAFFIC, LOG_DEBUG, "Writing packet of %d bytes to %s", packet->len, device_info); - if(sendto(device_fd, packet->data, packet->len, 0, ai->ai_addr, ai->ai_addrlen) < 0) { + if(sendto(device_fd, (void *)packet->data, packet->len, 0, ai->ai_addr, ai->ai_addrlen) < 0) { logger(DEBUG_ALWAYS, LOG_ERR, "Can't write to %s %s: %s", device_info, device, strerror(errno)); return false; diff --git a/src/names.c b/src/names.c new file mode 100644 index 0000000..cc72a11 --- /dev/null +++ b/src/names.c @@ -0,0 +1,106 @@ +/* + names.c -- generate commonly used (file)names + Copyright (C) 1998-2005 Ivo Timmermans + 2000-2013 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "system.h" + +#include "logger.h" +#include "xalloc.h" + +char *netname = NULL; +char *confdir = NULL; /* base configuration directory */ +char *confbase = NULL; /* base configuration directory for this instance of tinc */ +char *identname = NULL; /* program name for syslog */ +char *unixsocketname = NULL; /* UNIX socket location */ +char *logfilename = NULL; /* log file location */ +char *pidfilename = NULL; +char *program_name = NULL; + +/* + Set all files and paths according to netname +*/ +void make_names(void) { +#ifdef HAVE_MINGW + HKEY key; + char installdir[1024] = ""; + DWORD len = sizeof installdir; +#endif + + if(netname) + xasprintf(&identname, "tinc.%s", netname); + else + identname = xstrdup("tinc"); + +#ifdef HAVE_MINGW + if(!RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\tinc", 0, KEY_READ, &key)) { + if(!RegQueryValueEx(key, NULL, 0, 0, (LPBYTE)installdir, &len)) { + confdir = xstrdup(installdir); + if(!logfilename) + xasprintf(&logfilename, "%s" SLASH "log" SLASH "%s.log", installdir, identname); + if(!confbase) { + if(netname) + xasprintf(&confbase, "%s" SLASH "%s", installdir, netname); + else + xasprintf(&confbase, "%s", installdir); + } + if(!pidfilename) + xasprintf(&pidfilename, "%s" SLASH "pid", confbase); + } + RegCloseKey(key); + } +#endif + if(!confdir) + confdir = xstrdup(CONFDIR SLASH "tinc"); + + if(!logfilename) + xasprintf(&logfilename, LOCALSTATEDIR SLASH "log" SLASH "%s.log", identname); + + if(!pidfilename) + xasprintf(&pidfilename, LOCALSTATEDIR SLASH "run" SLASH "%s.pid", identname); + + if(!unixsocketname) { + int len = strlen(pidfilename); + unixsocketname = xmalloc(len + 8); + strcpy(unixsocketname, pidfilename); + if(len > 4 && !strcmp(pidfilename + len - 4, ".pid")) + strcpy(unixsocketname + len - 4, ".socket"); + else + strcpy(unixsocketname + len, ".socket"); + } + + if(netname) { + if(!confbase) + xasprintf(&confbase, CONFDIR SLASH "tinc" SLASH "%s", netname); + else + logger(DEBUG_ALWAYS, LOG_INFO, "Both netname and configuration directory given, using the latter..."); + } else { + if(!confbase) + xasprintf(&confbase, CONFDIR SLASH "tinc"); + } +} + +void free_names(void) { + free(identname); + free(netname); + free(unixsocketname); + free(pidfilename); + free(logfilename); + free(confbase); + free(confdir); +} diff --git a/src/names.h b/src/names.h new file mode 100644 index 0000000..6f43a2c --- /dev/null +++ b/src/names.h @@ -0,0 +1,36 @@ +/* + names.h -- header for names.c + Copyright (C) 1998-2005 Ivo Timmermans + 2000-2013 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#ifndef __TINC_NAMES_H__ +#define __TINC_NAMES_H__ + +extern char *confdir; +extern char *confbase; +extern char *netname; +extern char *identname; +extern char *unixsocketname; +extern char *logfilename; +extern char *pidfilename; +extern char *program_name; + +extern void make_names(void); +extern void free_names(void); + +#endif /* __TINC_NAMES_H__ */ diff --git a/src/net.c b/src/net.c index fe272db..0d374e6 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-2012 Guus Sliepen + 2000-2013 Guus Sliepen 2006 Scott Lamb 2011 Loïc Grenié @@ -29,6 +29,7 @@ #include "graph.h" #include "logger.h" #include "meta.h" +#include "names.h" #include "net.h" #include "netutl.h" #include "process.h" @@ -280,29 +281,13 @@ static void periodic_handler(void *data) { } void handle_meta_connection_data(connection_t *c) { - int result; - socklen_t len = sizeof result; - - if(c->status.connecting) { - c->status.connecting = false; - - getsockopt(c->socket, SOL_SOCKET, SO_ERROR, &result, &len); - - if(!result) - finish_connecting(c); - else { - logger(DEBUG_CONNECTIONS, LOG_DEBUG, "Error while connecting to %s (%s): %s", c->name, c->hostname, sockstrerror(result)); - terminate_connection(c, false); - return; - } - } - if (!receive_meta(c)) { terminate_connection(c, c->status.active); return; } } +#ifndef HAVE_MINGW static void sigterm_handler(void *data) { logger(DEBUG_ALWAYS, LOG_NOTICE, "Got %s signal", strsignal(((signal_t *)data)->signum)); event_exit(); @@ -318,6 +303,7 @@ static void sigalrm_handler(void *data) { logger(DEBUG_ALWAYS, LOG_NOTICE, "Got %s signal", strsignal(((signal_t *)data)->signum)); retry(); } +#endif int reload_configuration(void) { char *fname; @@ -451,11 +437,13 @@ int main_loop(void) { signal_t sighup = {0}; signal_t sigterm = {0}; signal_t sigquit = {0}; + signal_t sigint = {0}; signal_t sigalrm = {0}; signal_add(&sighup, sighup_handler, &sighup, SIGHUP); signal_add(&sigterm, sigterm_handler, &sigterm, SIGTERM); signal_add(&sigquit, sigterm_handler, &sigquit, SIGQUIT); + signal_add(&sigint, sigterm_handler, &sigint, SIGINT); signal_add(&sigalrm, sigalrm_handler, &sigalrm, SIGALRM); #endif diff --git a/src/net.h b/src/net.h index 4277279..8d236da 100644 --- a/src/net.h +++ b/src/net.h @@ -1,7 +1,7 @@ /* net.h -- header for net.c Copyright (C) 1998-2005 Ivo Timmermans - 2000-2012 Guus Sliepen + 2000-2013 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 @@ -128,6 +128,7 @@ extern bool localdiscovery; extern listen_socket_t listen_socket[MAXSOCKETS]; extern int listen_sockets; +extern io_t unix_socket; extern int keylifetime; extern int udp_rcvbuf; extern int udp_sndbuf; @@ -164,6 +165,7 @@ extern void handle_incoming_vpn_data(void *, int); extern void finish_connecting(struct connection_t *); extern bool do_outgoing_connection(struct outgoing_t *); extern void handle_new_meta_connection(void *, int); +extern void handle_new_unix_connection(void *, int); extern int setup_listen_socket(const sockaddr_t *); extern int setup_vpn_in_socket(const sockaddr_t *); extern bool send_sptps_data(void *handle, uint8_t type, const char *data, size_t len); diff --git a/src/net_packet.c b/src/net_packet.c index 3c3397c..5fd5632 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-2012 Guus Sliepen + 2000-2013 Guus Sliepen 2010 Timothy Redaelli 2010 Brandon Black @@ -22,12 +22,6 @@ #include "system.h" -#include -#include -#include -#include -#include - #ifdef HAVE_ZLIB #include #endif @@ -70,11 +64,15 @@ bool localdiscovery = false; mtuprobes == 32: send 1 burst, sleep pingtimeout second mtuprobes == 33: no response from other side, restart PMTU discovery process - Probes are sent in batches of three, with random sizes between the lower and - upper boundaries for the MTU thus far discovered. + Probes are sent in batches of at least three, with random sizes between the + lower and upper boundaries for the MTU thus far discovered. - In case local discovery is enabled, a fourth packet is added to each batch, + After the initial discovery, a fourth packet is added to each batch with a + size larger than the currently known PMTU, to test if the PMTU has increased. + + In case local discovery is enabled, another packet is added to each batch, which will be broadcast to the local network. + */ static void send_mtu_probe_handler(void *data) { @@ -125,13 +123,18 @@ static void send_mtu_probe_handler(void *data) { timeout = pingtimeout; } - for(int i = 0; i < 3 + localdiscovery; i++) { + for(int i = 0; i < 4 + localdiscovery; i++) { int len; - if(n->maxmtu <= n->minmtu) + if(i == 0) { + if(n->mtuprobes < 30 || n->maxmtu + 8 >= MTU) + continue; + len = n->maxmtu + 8; + } else if(n->maxmtu <= n->minmtu) { len = n->maxmtu; - else + } else { len = n->minmtu + 1 + rand() % (n->maxmtu - n->minmtu); + } if(len < 64) len = 64; @@ -140,7 +143,7 @@ static void send_mtu_probe_handler(void *data) { memset(packet.data, 0, 14); randomize(packet.data + 14, len - 14); packet.len = len; - if(i >= 3 && n->mtuprobes <= 10) + if(i >= 4 && n->mtuprobes <= 10) packet.priority = -1; else packet.priority = 0; @@ -150,6 +153,21 @@ static void send_mtu_probe_handler(void *data) { send_udppacket(n, &packet); } + n->probe_counter = 0; + gettimeofday(&n->probe_time, NULL); + + /* Calculate the packet loss of incoming traffic by comparing the rate of + packets received to the rate with which the sequence number has increased. + */ + + if(n->received > n->prev_received) + n->packetloss = 1.0 - (n->received - n->prev_received) / (float)(n->received_seqno - n->prev_received_seqno); + else + n->packetloss = n->received_seqno <= n->prev_received_seqno; + + n->prev_received_seqno = n->received_seqno; + n->prev_received = n->received; + end: timeout_set(&n->mtutimeout, &(struct timeval){timeout, rand() % 100000}); } @@ -184,6 +202,13 @@ static void mtu_probe_h(node_t *n, vpn_packet_t *packet, length_t len) { /* If we haven't established the PMTU yet, restart the discovery process. */ if(n->mtuprobes > 30) { + if (len == n->maxmtu + 8) { + logger(DEBUG_TRAFFIC, LOG_INFO, "Increase in PMTU to %s (%s) detected, restarting PMTU discovery", n->name, n->hostname); + n->maxmtu = MTU; + n->mtuprobes = 10; + return; + } + if(n->minmtu) n->mtuprobes = 30; else @@ -196,6 +221,25 @@ static void mtu_probe_h(node_t *n, vpn_packet_t *packet, length_t len) { len = n->maxmtu; if(n->minmtu < len) n->minmtu = len; + + /* Calculate RTT and bandwidth. + The RTT is the time between the MTU probe burst was sent and the first + reply is received. The bandwidth is measured using the time between the + arrival of the first and third probe reply. + */ + + struct timeval now, diff; + gettimeofday(&now, NULL); + timersub(&now, &n->probe_time, &diff); + n->probe_counter++; + + if(n->probe_counter == 1) { + n->rtt = diff.tv_sec + diff.tv_usec * 1e-6; + n->probe_time = now; + } else if(n->probe_counter == 3) { + n->bandwidth = 2.0 * len / (diff.tv_sec + diff.tv_usec * 1e-6); + logger(DEBUG_TRAFFIC, LOG_DEBUG, "%s (%s) RTT %.2f ms, burst bandwidth %.3f Mbit/s, rx packet loss %.2f %%", n->name, n->hostname, n->rtt * 1e3, n->bandwidth * 8e-6, n->packetloss * 1e2); + } } } @@ -365,6 +409,8 @@ static void receive_udppacket(node_t *n, vpn_packet_t *inpkt) { if(inpkt->seqno > n->received_seqno) n->received_seqno = inpkt->seqno; + n->received++; + if(n->received_seqno > MAX_SEQNO) regenerate_key(); diff --git a/src/net_setup.c b/src/net_setup.c index c5c83e7..a4fd3a4 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-2012 Guus Sliepen + 2000-2013 Guus Sliepen 2006 Scott Lamb 2010 Brandon Black @@ -31,6 +31,7 @@ #include "ecdsa.h" #include "graph.h" #include "logger.h" +#include "names.h" #include "net.h" #include "netutl.h" #include "process.h" @@ -807,6 +808,37 @@ static bool setup_myself(void) { /* Open sockets */ +#ifndef HAVE_MINGW + int unix_fd = socket(AF_UNIX, SOCK_STREAM, 0); + if(unix_fd < 0) { + logger(DEBUG_ALWAYS, LOG_ERR, "Could not create UNIX socket: %s", sockstrerror(errno)); + return false; + } + + struct sockaddr_un sa; + sa.sun_family = AF_UNIX; + strncpy(sa.sun_path, unixsocketname, sizeof sa.sun_path); + + if(connect(unix_fd, (struct sockaddr *)&sa, sizeof sa) >= 0) { + logger(DEBUG_ALWAYS, LOG_ERR, "UNIX socket %s is still in use!", unixsocketname); + return false; + } + + unlink(unixsocketname); + + if(bind(unix_fd, (struct sockaddr *)&sa, sizeof sa) < 0) { + logger(DEBUG_ALWAYS, LOG_ERR, "Could not bind UNIX socket to %s: %s", unixsocketname, sockstrerror(errno)); + return false; + } + + if(listen(unix_fd, 3) < 0) { + logger(DEBUG_ALWAYS, LOG_ERR, "Could not listen on UNIX socket %s: %s", unixsocketname, sockstrerror(errno)); + return false; + } + + io_add(&unix_socket, handle_new_unix_connection, &unix_socket, unix_fd, IO_READ); +#endif + if(!do_detach && getenv("LISTEN_FDS")) { sockaddr_t sa; socklen_t salen; @@ -991,6 +1023,11 @@ void close_network_connections(void) { close(listen_socket[i].udp.fd); } +#ifndef HAVE_MINGW + io_del(&unix_socket); + close(unix_socket.fd); +#endif + char *envp[5]; xasprintf(&envp[0], "NETNAME=%s", netname ? : ""); xasprintf(&envp[1], "DEVICE=%s", device ? : ""); diff --git a/src/net_socket.c b/src/net_socket.c index 212649b..a28be54 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-2012 Guus Sliepen + 2000-2013 Guus Sliepen 2006 Scott Lamb 2009 Florian Forster @@ -24,9 +24,11 @@ #include "conf.h" #include "connection.h" +#include "control_common.h" #include "list.h" #include "logger.h" #include "meta.h" +#include "names.h" #include "net.h" #include "netutl.h" #include "protocol.h" @@ -46,6 +48,9 @@ int udp_sndbuf = 0; listen_socket_t listen_socket[MAXSOCKETS]; int listen_sockets; +#ifndef HAVE_MINGW +io_t unix_socket; +#endif list_t *outgoing_list = NULL; /* Setup sockets */ @@ -289,9 +294,6 @@ void retry_outgoing(outgoing_t *outgoing) { void finish_connecting(connection_t *c) { logger(DEBUG_CONNECTIONS, LOG_INFO, "Connected to %s (%s)", c->name, c->hostname); - if(proxytype != PROXY_EXEC) - configure_tcp(c); - c->last_ping_time = time(NULL); c->status.connecting = false; @@ -368,10 +370,28 @@ static void handle_meta_write(connection_t *c) { } static void handle_meta_io(void *data, int flags) { + connection_t *c = data; + + if(c->status.connecting) { + c->status.connecting = false; + + int result; + socklen_t len = sizeof result; + getsockopt(c->socket, SOL_SOCKET, SO_ERROR, (void *)&result, &len); + + if(!result) + finish_connecting(c); + else { + logger(DEBUG_CONNECTIONS, LOG_DEBUG, "Error while connecting to %s (%s): %s", c->name, c->hostname, sockstrerror(result)); + terminate_connection(c, false); + return; + } + } + if(flags & IO_WRITE) - handle_meta_write(data); + handle_meta_write(c); else - handle_meta_connection_data(data); + handle_meta_connection_data(c); } bool do_outgoing_connection(outgoing_t *outgoing) { @@ -436,6 +456,7 @@ begin: } logger(DEBUG_CONNECTIONS, LOG_INFO, "Using proxy at %s port %s", proxyhost, proxyport); c->socket = socket(proxyai->ai_family, SOCK_STREAM, IPPROTO_TCP); + configure_tcp(c); } if(c->socket == -1) { @@ -488,7 +509,7 @@ begin: connection_add(c); - io_add(&c->io, handle_meta_io, c, c->socket, IO_READ); + io_add(&c->io, handle_meta_io, c, c->socket, IO_READ|IO_WRITE); return true; } @@ -561,6 +582,45 @@ void handle_new_meta_connection(void *data, int flags) { send_id(c); } +#ifndef HAVE_MINGW +/* + accept a new UNIX socket connection +*/ +void handle_new_unix_connection(void *data, int flags) { + io_t *io = data; + connection_t *c; + sockaddr_t sa; + int fd; + socklen_t len = sizeof sa; + + fd = accept(io->fd, &sa.sa, &len); + + if(fd < 0) { + logger(DEBUG_ALWAYS, LOG_ERR, "Accepting a new connection failed: %s", sockstrerror(sockerrno)); + return; + } + + sockaddrunmap(&sa); + + c = new_connection(); + c->name = xstrdup(""); + c->address = sa; + c->hostname = xstrdup("localhost port unix"); + c->socket = fd; + c->last_ping_time = time(NULL); + + logger(DEBUG_CONNECTIONS, LOG_NOTICE, "Connection from %s", c->hostname); + + io_add(&c->io, handle_meta_io, c, c->socket, IO_READ); + + connection_add(c); + + c->allow_request = ID; + + send_id(c); +} +#endif + static void free_outgoing(outgoing_t *outgoing) { timeout_del(&outgoing->ev); diff --git a/src/node.h b/src/node.h index c567ad9..e4b47b3 100644 --- a/src/node.h +++ b/src/node.h @@ -1,6 +1,6 @@ /* node.h -- header for node.c - Copyright (C) 2001-2012 Guus Sliepen , + Copyright (C) 2001-2013 Guus Sliepen , 2001-2005 Ivo Timmermans This program is free software; you can redistribute it and/or modify @@ -77,6 +77,9 @@ typedef struct node_t { uint32_t sent_seqno; /* Sequence number last sent to this node */ uint32_t received_seqno; /* Sequence number last received from this node */ + uint32_t received; /* Total valid packets received from this node */ + uint32_t prev_received_seqno; + uint32_t prev_received; uint32_t farfuture; /* Packets in a row that have arrived from the far future */ unsigned char* late; /* Bitfield marking late packets */ @@ -85,6 +88,11 @@ typedef struct node_t { length_t maxmtu; /* Probed maximum MTU */ int mtuprobes; /* Number of probes */ timeout_t mtutimeout; /* Probe event */ + struct timeval probe_time; /* Time the last probe was sent or received */ + int probe_counter; /* Number of probes received since last burst was sent */ + float rtt; /* Last measured round trip time */ + float bandwidth; /* Last measured bandwidth */ + float packetloss; /* Last measured packet loss rate */ uint64_t in_packets; uint64_t in_bytes; diff --git a/src/process.c b/src/process.c index 2fd3d93..cbb190a 100644 --- a/src/process.c +++ b/src/process.c @@ -1,7 +1,7 @@ /* process.c -- process management functions Copyright (C) 1999-2005 Ivo Timmermans, - 2000-2012 Guus Sliepen + 2000-2013 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 @@ -27,6 +27,7 @@ #include "edge.h" #include "event.h" #include "logger.h" +#include "names.h" #include "net.h" #include "node.h" #include "process.h" @@ -38,17 +39,12 @@ bool do_detach = true; bool sigalrm = false; -extern char *identname; extern char **g_argv; extern bool use_logfile; /* Some functions the less gifted operating systems might lack... */ #ifdef HAVE_MINGW -extern char *identname; -extern char *program_name; -extern char **g_argv; - static SC_HANDLE manager = NULL; static SC_HANDLE service = NULL; static SERVICE_STATUS status = {0}; @@ -263,8 +259,8 @@ bool execute_script(const char *name, char **envp) { } } -#ifdef WEXITSTATUS if(status != -1) { +#ifdef WEXITSTATUS if(WIFEXITED(status)) { /* Child exited by itself */ if(WEXITSTATUS(status)) { logger(DEBUG_ALWAYS, LOG_ERR, "Script %s exited with non-zero status %d", @@ -279,11 +275,11 @@ bool execute_script(const char *name, char **envp) { logger(DEBUG_ALWAYS, LOG_ERR, "Script %s terminated abnormally", name); return false; } +#endif } else { logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "system", strerror(errno)); return false; } -#endif #endif return true; } diff --git a/src/protocol.c b/src/protocol.c index bdc0378..fc16ffe 100644 --- a/src/protocol.c +++ b/src/protocol.c @@ -111,7 +111,7 @@ void forward_request(connection_t *from, const char *request) { } bool receive_request(connection_t *c, const char *request) { - if(proxytype == PROXY_HTTP && c->allow_request == ID) { + if(c->outgoing && proxytype == PROXY_HTTP && c->allow_request == ID) { if(!request[0] || request[0] == '\r') return true; if(!strncasecmp(request, "HTTP/1.1 ", 9)) { diff --git a/src/protocol_auth.c b/src/protocol_auth.c index 1b061b3..f4a30a4 100644 --- a/src/protocol_auth.c +++ b/src/protocol_auth.c @@ -139,7 +139,7 @@ bool send_id(connection_t *c) { minor = myself->connection->protocol_minor; } - if(proxytype) + if(proxytype && c->outgoing) if(!send_proxyrequest(c)) return false; diff --git a/src/protocol_key.c b/src/protocol_key.c index b54df3c..115845a 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-2012 Guus Sliepen + 2000-2013 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 @@ -278,6 +278,7 @@ bool send_ans_key(node_t *to) { // Reset sequence number and late packet window mykeyused = true; to->received_seqno = 0; + to->received = 0; if(replaywin) memset(to->late, 0, replaywin); return send_request(to->nexthop->connection, "%d %s %s %s %d %d %d %d", ANS_KEY, diff --git a/src/route.c b/src/route.c index 7bb9996..1896374 100644 --- a/src/route.c +++ b/src/route.c @@ -1,7 +1,7 @@ /* route.c -- routing Copyright (C) 2000-2005 Ivo Timmermans, - 2000-2012 Guus Sliepen + 2000-2013 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 @@ -835,6 +835,11 @@ static void route_mac(node_t *source, vpn_packet_t *packet) { if(forwarding_mode == FMODE_OFF && source != myself && subnet->owner != myself) return; + uint16_t type = packet->data[12] << 8 | packet->data[13]; + + if(priorityinheritance && type == ETH_P_IP && packet->len >= ether_size + ip_size) + packet->priority = packet->data[15]; + // Handle packets larger than PMTU node_t *via = (subnet->owner->via == myself) ? subnet->owner->nexthop : subnet->owner->via; @@ -844,7 +849,6 @@ static void route_mac(node_t *source, vpn_packet_t *packet) { if(via && packet->len > via->mtu && via != myself) { logger(DEBUG_TRAFFIC, 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]; length_t ethlen = 14; if(type == ETH_P_8021Q) { diff --git a/src/solaris/device.c b/src/solaris/device.c index cb2ece7..c8c5cbf 100644 --- a/src/solaris/device.c +++ b/src/solaris/device.c @@ -1,7 +1,7 @@ /* device.c -- Interaction with Solaris tun device Copyright (C) 2001-2005 Ivo Timmermans, - 2001-2012 Guus Sliepen + 2001-2013 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 @@ -28,6 +28,7 @@ #include "conf.h" #include "device.h" #include "logger.h" +#include "names.h" #include "net.h" #include "utils.h" #include "xalloc.h" diff --git a/src/sptps.c b/src/sptps.c index 5a99055..8242cad 100644 --- a/src/sptps.c +++ b/src/sptps.c @@ -1,6 +1,6 @@ /* sptps.c -- Simple Peer-to-Peer Security - Copyright (C) 2011-2012 Guus Sliepen , + Copyright (C) 2011-2013 Guus Sliepen , 2010 Brandon L. Black This program is free software; you can redistribute it and/or modify @@ -439,6 +439,17 @@ static bool sptps_receive_data_datagram(sptps_t *s, const char *data, size_t len return receive_handshake(s, data + 5, len - 5); } + // Check HMAC. + uint16_t netlen = htons(len - 21); + + char buffer[len + 23]; + + memcpy(buffer, &netlen, 2); + memcpy(buffer + 2, data, len); + + if(!digest_verify(&s->indigest, buffer, len - 14, buffer + len - 14)) + return error(s, EIO, "Invalid HMAC"); + // Replay protection using a sliding window of configurable size. // s->inseqno is expected sequence number // seqno is received sequence number @@ -473,19 +484,13 @@ static bool sptps_receive_data_datagram(sptps_t *s, const char *data, size_t len if(seqno > s->inseqno) s->inseqno = seqno + 1; - uint16_t netlen = htons(len - 21); - - char buffer[len + 23]; - - memcpy(buffer, &netlen, 2); - memcpy(buffer + 2, data, len); + if(!s->inseqno) + s->received = 0; + else + s->received++; + // Decrypt. memcpy(&seqno, buffer + 2, 4); - - // Check HMAC and decrypt. - if(!digest_verify(&s->indigest, buffer, len - 14, buffer + len - 14)) - return error(s, EIO, "Invalid HMAC"); - cipher_set_counter(&s->incipher, &seqno, sizeof seqno); if(!cipher_counter_xor(&s->incipher, buffer + 6, len - 4, buffer + 6)) return false; diff --git a/src/sptps.h b/src/sptps.h index a19be97..1fead07 100644 --- a/src/sptps.h +++ b/src/sptps.h @@ -1,6 +1,6 @@ /* sptps.h -- Simple Peer-to-Peer Security - Copyright (C) 2011-2012 Guus Sliepen , + Copyright (C) 2011-2013 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 @@ -56,6 +56,7 @@ typedef struct sptps { cipher_t incipher; digest_t indigest; uint32_t inseqno; + uint32_t received; unsigned int replaywin; unsigned int farfuture; char *late; diff --git a/src/subnet.c b/src/subnet.c index 4b6c068..12ca03c 100644 --- a/src/subnet.c +++ b/src/subnet.c @@ -1,6 +1,6 @@ /* subnet.c -- handle subnet lookups and lists - Copyright (C) 2000-2012 Guus Sliepen , + Copyright (C) 2000-2013 Guus Sliepen , 2000-2005 Ivo Timmermans This program is free software; you can redistribute it and/or modify @@ -25,6 +25,7 @@ #include "device.h" #include "hash.h" #include "logger.h" +#include "names.h" #include "net.h" #include "netutl.h" #include "node.h" diff --git a/src/tincctl.c b/src/tincctl.c index dd0bbcc..45bf6ee 100644 --- a/src/tincctl.c +++ b/src/tincctl.c @@ -1,6 +1,6 @@ /* tincctl.c -- Controlling a running tincd - Copyright (C) 2007-2012 Guus Sliepen + Copyright (C) 2007-2013 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 @@ -31,6 +31,7 @@ #include "control_common.h" #include "ecdsagen.h" #include "info.h" +#include "names.h" #include "rsagen.h" #include "utils.h" #include "tincctl.h" @@ -40,10 +41,6 @@ #define mkdir(a, b) mkdir(a) #endif - -/* The name this program was run with. */ -static char *program_name = NULL; - static char **orig_argv; static int orig_argc; @@ -54,12 +51,7 @@ static bool show_help = false; static bool show_version = false; static char *name = NULL; -static char *identname = NULL; /* program name for syslog */ -static char *pidfilename = NULL; /* pid file location */ -static char *confdir = NULL; static char controlcookie[1025]; -char *netname = NULL; -char *confbase = NULL; static char *tinc_conf = NULL; static char *hosts_dir = NULL; struct timeval now; @@ -107,10 +99,9 @@ static void version(void) { } static void usage(bool status) { - if(status) - fprintf(stderr, "Try `%s --help\' for more information.\n", - program_name); - else { + if(status) { + fprintf(stderr, "Try `%s --help\' for more information.\n", program_name); + } else { printf("Usage: %s [options] command\n\n", program_name); printf("Valid options are:\n" " -c, --config=DIR Read configuration options from DIR.\n" @@ -153,6 +144,8 @@ static void usage(bool status) { " export Export host configuration of local node to standard output\n" " export-all Export all host configuration files to standard output\n" " import [--force] Import host configuration file(s) from standard input\n" + " exchange [--force] Same as export followed by import\n" + " exchange-all [--force] Same as export-all followed by import\n" "\n"); printf("Report bugs to tinc@tinc-vpn.org.\n"); } @@ -453,62 +446,6 @@ static bool rsa_keygen(int bits, bool ask) { return true; } -/* - Set all files and paths according to netname -*/ -static void make_names(void) { -#ifdef HAVE_MINGW - HKEY key; - char installdir[1024] = ""; - long len = sizeof installdir; -#endif - - if(netname) - xasprintf(&identname, "tinc.%s", netname); - else - identname = xstrdup("tinc"); - -#ifdef HAVE_MINGW - if(!RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\tinc", 0, KEY_READ, &key)) { - if(!RegQueryValueEx(key, NULL, 0, 0, installdir, &len)) { - if(!confbase) { - if(netname) - xasprintf(&confbase, "%s" SLASH "%s", installdir, netname); - else - xasprintf(&confbase, "%s", installdir); - } - } - if(!pidfilename) - xasprintf(&pidfilename, "%s" SLASH "pid", confbase); - RegCloseKey(key); - } - - if(!*installdir) { -#endif - confdir = xstrdup(CONFDIR); - - if(!pidfilename) - xasprintf(&pidfilename, "%s" SLASH "run" SLASH "%s.pid", LOCALSTATEDIR, identname); - - if(netname) { - if(!confbase) - xasprintf(&confbase, CONFDIR SLASH "tinc" SLASH "%s", netname); - else - fprintf(stderr, "Both netname and configuration directory given, using the latter...\n"); - } else { - if(!confbase) - xasprintf(&confbase, CONFDIR SLASH "tinc"); - } - -#ifdef HAVE_MINGW - } else - confdir = xstrdup(installdir); -#endif - - xasprintf(&tinc_conf, "%s" SLASH "tinc.conf", confbase); - xasprintf(&hosts_dir, "%s" SLASH "hosts", confbase); -} - static char buffer[4096]; static size_t blen = 0; @@ -729,6 +666,26 @@ static bool connect_tincd(bool verbose) { } #endif +#ifndef HAVE_MINGW + struct sockaddr_un sa; + sa.sun_family = AF_UNIX; + strncpy(sa.sun_path, unixsocketname, sizeof sa.sun_path); + + fd = socket(AF_UNIX, SOCK_STREAM, 0); + if(fd < 0) { + if(verbose) + fprintf(stderr, "Cannot create UNIX socket: %s\n", sockstrerror(sockerrno)); + return false; + } + + if(connect(fd, (struct sockaddr *)&sa, sizeof sa) < 0) { + if(verbose) + fprintf(stderr, "Cannot connect to UNIX socket %s: %s\n", unixsocketname, sockstrerror(sockerrno)); + close(fd); + fd = -1; + return false; + } +#else struct addrinfo hints = { .ai_family = AF_UNSPEC, .ai_socktype = SOCK_STREAM, @@ -769,6 +726,7 @@ static bool connect_tincd(bool verbose) { } freeaddrinfo(res); +#endif char data[4096]; int version; @@ -854,6 +812,11 @@ static int cmd_start(int argc, char *argv[]) { } static int cmd_stop(int argc, char *argv[]) { + if(argc > 1) { + fprintf(stderr, "Too many arguments!\n"); + return 1; + } + #ifndef HAVE_MINGW if(!connect_tincd(true)) { if(pid) { @@ -871,16 +834,10 @@ static int cmd_stop(int argc, char *argv[]) { } sendline(fd, "%d %d", CONTROL, REQ_STOP); - if(!recvline(fd, line, sizeof line) || sscanf(line, "%d %d %d", &code, &req, &result) != 3 || code != CONTROL || req != REQ_STOP || result) { - fprintf(stderr, "Could not stop tinc daemon.\n"); - return 1; - } - // Wait for tincd to close the connection... - fd_set r; - FD_ZERO(&r); - FD_SET(fd, &r); - select(fd + 1, &r, NULL, NULL, NULL); + while(recvline(fd, line, sizeof line)) { + // Wait for tincd to close the connection... + } #else if(!remove_service()) return 1; @@ -898,6 +855,11 @@ static int cmd_restart(int argc, char *argv[]) { } static int cmd_reload(int argc, char *argv[]) { + if(argc > 1) { + fprintf(stderr, "Too many arguments!\n"); + return 1; + } + if(!connect_tincd(true)) return 1; @@ -1070,6 +1032,11 @@ static int cmd_dump(int argc, char *argv[]) { } static int cmd_purge(int argc, char *argv[]) { + if(argc > 1) { + fprintf(stderr, "Too many arguments!\n"); + return 1; + } + if(!connect_tincd(true)) return 1; @@ -1105,6 +1072,11 @@ static int cmd_debug(int argc, char *argv[]) { } static int cmd_retry(int argc, char *argv[]) { + if(argc > 1) { + fprintf(stderr, "Too many arguments!\n"); + return 1; + } + if(!connect_tincd(true)) return 1; @@ -1164,6 +1136,11 @@ static int cmd_disconnect(int argc, char *argv[]) { } static int cmd_top(int argc, char *argv[]) { + if(argc > 1) { + fprintf(stderr, "Too many arguments!\n"); + return 1; + } + #ifdef HAVE_CURSES if(!connect_tincd(true)) return 1; @@ -1177,6 +1154,11 @@ static int cmd_top(int argc, char *argv[]) { } static int cmd_pcap(int argc, char *argv[]) { + if(argc > 2) { + fprintf(stderr, "Too many arguments!\n"); + return 1; + } + if(!connect_tincd(true)) return 1; @@ -1185,6 +1167,11 @@ static int cmd_pcap(int argc, char *argv[]) { } static int cmd_log(int argc, char *argv[]) { + if(argc > 2) { + fprintf(stderr, "Too many arguments!\n"); + return 1; + } + if(!connect_tincd(true)) return 1; @@ -1193,6 +1180,11 @@ static int cmd_log(int argc, char *argv[]) { } static int cmd_pid(int argc, char *argv[]) { + if(argc > 1) { + fprintf(stderr, "Too many arguments!\n"); + return 1; + } + if(!connect_tincd(true) && !pid) return 1; @@ -1613,7 +1605,10 @@ static int cmd_init(int argc, char *argv[]) { return 1; } - if(argc < 2) { + if(argc > 2) { + fprintf(stderr, "Too many arguments!\n"); + return 1; + } else if(argc < 2) { if(tty) { char buf[1024]; fprintf(stdout, "Enter the Name you want your tinc node to have: "); @@ -1692,14 +1687,29 @@ static int cmd_init(int argc, char *argv[]) { } static int cmd_generate_keys(int argc, char *argv[]) { + if(argc > 2) { + fprintf(stderr, "Too many arguments!\n"); + return 1; + } + return !(rsa_keygen(argc > 1 ? atoi(argv[1]) : 2048, true) && ecdsa_keygen(true)); } static int cmd_generate_rsa_keys(int argc, char *argv[]) { + if(argc > 2) { + fprintf(stderr, "Too many arguments!\n"); + return 1; + } + return !rsa_keygen(argc > 1 ? atoi(argv[1]) : 2048, true); } static int cmd_generate_ecdsa_keys(int argc, char *argv[]) { + if(argc > 1) { + fprintf(stderr, "Too many arguments!\n"); + return 1; + } + return !ecdsa_keygen(true); } @@ -1709,6 +1719,11 @@ static int cmd_help(int argc, char *argv[]) { } static int cmd_version(int argc, char *argv[]) { + if(argc > 1) { + fprintf(stderr, "Too many arguments!\n"); + return 1; + } + version(); return 0; } @@ -1811,14 +1826,29 @@ static int export(const char *name, FILE *out) { } static int cmd_export(int argc, char *argv[]) { + if(argc > 1) { + fprintf(stderr, "Too many arguments!\n"); + return 1; + } + char *name = get_my_name(); if(!name) return 1; - return export(name, stdout); + int result = export(name, stdout); + if(!tty) + fclose(stdout); + + free(name); + return result; } static int cmd_export_all(int argc, char *argv[]) { + if(argc > 1) { + fprintf(stderr, "Too many arguments!\n"); + return 1; + } + DIR *dir = opendir(hosts_dir); if(!dir) { fprintf(stderr, "Could not open host configuration directory %s: %s\n", hosts_dir, strerror(errno)); @@ -1842,21 +1872,30 @@ static int cmd_export_all(int argc, char *argv[]) { } closedir(dir); + if(!tty) + fclose(stdout); return result; } static int cmd_import(int argc, char *argv[]) { + if(argc > 1) { + fprintf(stderr, "Too many arguments!\n"); + return 1; + } + FILE *in = stdin; FILE *out = NULL; char buf[4096]; char name[4096]; - char *filename; + char *filename = NULL; int count = 0; bool firstline = true; while(fgets(buf, sizeof buf, in)) { if(sscanf(buf, "Name = %s", name) == 1) { + firstline = false; + if(!check_id(name)) { fprintf(stderr, "Invalid Name in input!\n"); return 1; @@ -1881,7 +1920,6 @@ static int cmd_import(int argc, char *argv[]) { } count++; - firstline = false; continue; } else if(firstline) { fprintf(stderr, "Junk at the beginning of the input, ignoring.\n"); @@ -1912,6 +1950,14 @@ static int cmd_import(int argc, char *argv[]) { } } +static int cmd_exchange(int argc, char *argv[]) { + return cmd_export(argc, argv) ?: cmd_import(argc, argv); +} + +static int cmd_exchange_all(int argc, char *argv[]) { + return cmd_export_all(argc, argv) ?: cmd_import(argc, argv); +} + static const struct { const char *command; int (*function)(int argc, char *argv[]); @@ -1942,6 +1988,8 @@ static const struct { {"export", cmd_export}, {"export-all", cmd_export_all}, {"import", cmd_import}, + {"exchange", cmd_exchange}, + {"exchange-all", cmd_exchange_all}, {NULL, NULL}, }; @@ -2189,6 +2237,8 @@ int main(int argc, char *argv[]) { return 1; make_names(); + xasprintf(&tinc_conf, "%s" SLASH "tinc.conf", confbase); + xasprintf(&hosts_dir, "%s" SLASH "hosts", confbase); if(show_version) { version(); diff --git a/src/tincd.c b/src/tincd.c index 3883ec2..8412c8f 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-2012 Guus Sliepen + 2000-2013 Guus Sliepen 2008 Max Rijevski 2009 Michael Tokarev 2010 Julien Muchembled @@ -33,12 +33,6 @@ #include #endif -#include -#include -#include -#include -#include - #ifdef HAVE_LZO #include LZO1X_H #endif @@ -56,6 +50,7 @@ #include "crypto.h" #include "device.h" #include "logger.h" +#include "names.h" #include "net.h" #include "netutl.h" #include "process.h" @@ -63,9 +58,6 @@ #include "utils.h" #include "xalloc.h" -/* The name this program was run with. */ -char *program_name = NULL; - /* If nonzero, display usage information and exit. */ static bool show_help = false; @@ -75,21 +67,22 @@ static bool show_version = false; /* If nonzero, use null ciphers and skip all key exchanges. */ bool bypass_security = false; +#ifdef HAVE_MLOCKALL /* If nonzero, disable swapping for this process. */ static bool do_mlock = false; +#endif +#ifndef HAVE_MINGW /* If nonzero, chroot to netdir after startup. */ static bool do_chroot = false; /* If !NULL, do setuid to given user after startup */ static const char *switchuser = NULL; +#endif /* If nonzero, write log entries to a separate file. */ bool use_logfile = false; -char *identname = NULL; /* program name for syslog */ -char *logfilename = NULL; /* log file location */ -char *pidfilename = NULL; char **g_argv; /* a copy of the cmdline arguments */ static int status = 1; @@ -127,13 +120,18 @@ static void usage(bool status) { " -D, --no-detach Don't fork and detach.\n" " -d, --debug[=LEVEL] Increase debug level or set it to LEVEL.\n" " -n, --net=NETNAME Connect to net NETNAME.\n" +#ifdef HAVE_MLOCKALL " -L, --mlock Lock tinc into main memory.\n" +#endif " --logfile[=FILENAME] Write log entries to a logfile.\n" " --pidfile=FILENAME Write PID and control socket cookie to FILENAME.\n" " --bypass-security Disables meta protocol security, for debugging.\n" " -o, --option[HOST.]KEY=VALUE Set global/host configuration value.\n" +#ifndef HAVE_MINGW " -R, --chroot chroot to NET dir at startup.\n" - " -U, --user=USER setuid to given USER at startup.\n" " --help Display this help and exit.\n" + " -U, --user=USER setuid to given USER at startup.\n" +#endif + " --help Display this help and exit.\n" " --version Output version information and exit.\n\n"); printf("Report bugs to tinc@tinc-vpn.org.\n"); } @@ -162,7 +160,7 @@ static bool parse_options(int argc, char **argv) { case 'L': /* no detach */ #ifndef HAVE_MLOCKALL - logger(DEBUG_ALWAYS, LOG_ERR, "%s not supported on this platform", "mlockall()"); + logger(DEBUG_ALWAYS, LOG_ERR, "The %s option is not supported on this platform.", argv[optind - 1]); return false; #else do_mlock = true; @@ -187,6 +185,12 @@ static bool parse_options(int argc, char **argv) { list_insert_tail(cmdline_conf, cfg); break; +#ifdef HAVE_MINGW + case 'R': + case 'U': + logger(DEBUG_ALWAYS, LOG_ERR, "The %s option is not supported on this platform.", argv[optind - 1]); + return false; +#else case 'R': /* chroot to NETNAME dir */ do_chroot = true; break; @@ -194,6 +198,7 @@ static bool parse_options(int argc, char **argv) { case 'U': /* setuid to USER */ switchuser = optarg; break; +#endif case 1: /* show help */ show_help = true; @@ -244,77 +249,8 @@ static bool parse_options(int argc, char **argv) { return true; } -/* - Set all files and paths according to netname -*/ -static void make_names(void) { -#ifdef HAVE_MINGW - HKEY key; - char installdir[1024] = ""; - long len = sizeof installdir; -#endif - - if(netname) - xasprintf(&identname, "tinc.%s", netname); - else - identname = xstrdup("tinc"); - -#ifdef HAVE_MINGW - if(!RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\tinc", 0, KEY_READ, &key)) { - if(!RegQueryValueEx(key, NULL, 0, 0, installdir, &len)) { - if(!logfilename) - xasprintf(&logfilename, "%s" SLASH "log" SLASH "%s.log", identname); - if(!confbase) { - if(netname) - xasprintf(&confbase, "%s" SLASH "%s", installdir, netname); - else - xasprintf(&confbase, "%s", installdir); - } - if(!pidfilename) - xasprintf(&pidfilename, "%s" SLASH "pid", confbase); - } - RegCloseKey(key); - if(*installdir) - return; - } -#endif - - if(!logfilename) - xasprintf(&logfilename, LOCALSTATEDIR SLASH "log" SLASH "%s.log", identname); - - if(!pidfilename) - xasprintf(&pidfilename, LOCALSTATEDIR SLASH "run" SLASH "%s.pid", identname); - - if(netname) { - if(!confbase) - xasprintf(&confbase, CONFDIR SLASH "tinc" SLASH "%s", netname); - else - logger(DEBUG_ALWAYS, LOG_INFO, "Both netname and configuration directory given, using the latter..."); - } else { - if(!confbase) - xasprintf(&confbase, CONFDIR SLASH "tinc"); - } -} - -static void free_names(void) { - if (identname) free(identname); - if (netname) free(netname); - if (pidfilename) free(pidfilename); - if (logfilename) free(logfilename); - if (confbase) free(confbase); -} - static bool drop_privs(void) { -#ifdef HAVE_MINGW - if (switchuser) { - logger(DEBUG_ALWAYS, LOG_ERR, "%s not supported on this platform", "-U"); - return false; - } - if (do_chroot) { - logger(DEBUG_ALWAYS, LOG_ERR, "%s not supported on this platform", "-R"); - return false; - } -#else +#ifndef HAVE_MINGW uid_t uid = 0; if (switchuser) { struct passwd *pw = getpwnam(switchuser); diff --git a/src/top.c b/src/top.c index 8cd82be..703391c 100644 --- a/src/top.c +++ b/src/top.c @@ -1,6 +1,6 @@ /* top.c -- Show real-time statistics from a running tincd - Copyright (C) 2011-2012 Guus Sliepen + Copyright (C) 2011-2013 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 @@ -25,6 +25,7 @@ #include "control_common.h" #include "list.h" +#include "names.h" #include "tincctl.h" #include "top.h" #include "xalloc.h" @@ -65,10 +66,6 @@ static float bscale = 1; static const char *punit = "pkts"; static float pscale = 1; -#ifndef timersub -#define timersub(a, b, c) do {(c)->tv_sec = (a)->tv_sec - (b)->tv_sec; (c)->tv_usec = (a)->tv_usec = (b)->tv_usec;} while(0) -#endif - static void update(int fd) { sendline(fd, "%d %d", CONTROL, REQ_DUMP_TRAFFIC); gettimeofday(&cur, NULL); @@ -229,7 +226,7 @@ static void redraw(void) { attrset(A_DIM); if(cumulative) - mvprintw(row, 0, "%-16s %10"PRIu64" %10.0f %10"PRIu64" %10.0f", + mvprintw(row, 0, "%-16s %10.0f %10.0f %10.0f %10.0f", node->name, node->in_packets * pscale, node->in_bytes * bscale, node->out_packets * pscale, node->out_bytes * bscale); else mvprintw(row, 0, "%-16s %10.0f %10.0f %10.0f %10.0f", diff --git a/src/uml_device.c b/src/uml_device.c index afdded5..d06832b 100644 --- a/src/uml_device.c +++ b/src/uml_device.c @@ -1,7 +1,7 @@ /* device.c -- UML network socket Copyright (C) 2002-2005 Ivo Timmermans, - 2002-2012 Guus Sliepen + 2002-2013 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 @@ -24,6 +24,7 @@ #include "conf.h" #include "device.h" +#include "names.h" #include "net.h" #include "logger.h" #include "utils.h" @@ -37,9 +38,6 @@ static int write_fd = -1; static int state = 0; static char *device_info; -extern char *identname; -extern volatile bool running; - static uint64_t device_total_in = 0; static uint64_t device_total_out = 0; @@ -73,7 +71,7 @@ static bool setup_device(void) { if((write_fd = socket(PF_UNIX, SOCK_DGRAM, 0)) < 0) { logger(DEBUG_ALWAYS, LOG_ERR, "Could not open write %s: %s", device_info, strerror(errno)); - running = false; + event_exit(); return false; } @@ -85,13 +83,13 @@ static bool setup_device(void) { if(fcntl(write_fd, F_SETFL, O_NONBLOCK) < 0) { logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "fcntl", strerror(errno)); - running = false; + event_exit(); return false; } if((data_fd = socket(PF_UNIX, SOCK_DGRAM, 0)) < 0) { logger(DEBUG_ALWAYS, LOG_ERR, "Could not open data %s: %s", device_info, strerror(errno)); - running = false; + event_exit(); return false; } @@ -103,7 +101,7 @@ static bool setup_device(void) { if(fcntl(data_fd, F_SETFL, O_NONBLOCK) < 0) { logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "fcntl", strerror(errno)); - running = false; + event_exit(); return false; } @@ -116,7 +114,7 @@ static bool setup_device(void) { if(bind(data_fd, (struct sockaddr *)&data_sun, sizeof data_sun) < 0) { logger(DEBUG_ALWAYS, LOG_ERR, "Could not bind data %s: %s", device_info, strerror(errno)); - running = false; + event_exit(); return false; } @@ -199,7 +197,7 @@ static bool read_packet(vpn_packet_t *packet) { if(fcntl(listen_fd, F_SETFL, O_NONBLOCK) < 0) { logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "fcntl", strerror(errno)); - running = false; + event_exit(); return false; } @@ -215,20 +213,20 @@ static bool read_packet(vpn_packet_t *packet) { if((inlen = read(request_fd, &request, sizeof request)) != sizeof request) { logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading request from %s %s: %s", device_info, device, strerror(errno)); - running = false; + event_exit(); return false; } if(request.magic != 0xfeedface || request.version != 3 || request.type != REQ_NEW_CONTROL) { logger(DEBUG_ALWAYS, LOG_ERR, "Unknown magic %x, version %d, request type %d from %s %s", request.magic, request.version, request.type, device_info, device); - running = false; + event_exit(); return false; } if(connect(write_fd, &request.sock, sizeof request.sock) < 0) { logger(DEBUG_ALWAYS, LOG_ERR, "Could not bind write %s: %s", device_info, strerror(errno)); - running = false; + event_exit(); return false; } @@ -245,7 +243,7 @@ static bool read_packet(vpn_packet_t *packet) { if((inlen = read(data_fd, packet->data, MTU)) <= 0) { logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info, device, strerror(errno)); - running = false; + event_exit(); return false; } @@ -278,7 +276,7 @@ static bool write_packet(vpn_packet_t *packet) { if(write(write_fd, packet->data, packet->len) < 0) { if(errno != EINTR && errno != EAGAIN) { logger(DEBUG_ALWAYS, LOG_ERR, "Can't write to %s %s: %s", device_info, device, strerror(errno)); - running = false; + event_exit(); } return false; diff --git a/src/vde_device.c b/src/vde_device.c index 815b956..446ca16 100644 --- a/src/vde_device.c +++ b/src/vde_device.c @@ -1,6 +1,6 @@ /* device.c -- VDE plug - Copyright (C) 2012 Guus Sliepen + Copyright (C) 2013 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 @@ -23,6 +23,7 @@ #include "conf.h" #include "device.h" +#include "names.h" #include "net.h" #include "logger.h" #include "utils.h" @@ -35,9 +36,6 @@ static int port = 0; static char *group = NULL; static char *device_info; -extern char *identname; -extern volatile bool running; - static uint64_t device_total_in = 0; static uint64_t device_total_out = 0; @@ -102,7 +100,7 @@ static bool read_packet(vpn_packet_t *packet) { int lenin = (ssize_t)plug.vde_recv(conn, packet->data, MTU, 0); if(lenin <= 0) { logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info, device, strerror(errno)); - running = false; + event_exit(); return false; } @@ -117,7 +115,7 @@ static bool write_packet(vpn_packet_t *packet) { if((ssize_t)plug.vde_send(conn, packet->data, packet->len, 0) < 0) { if(errno != EINTR && errno != EAGAIN) { logger(DEBUG_ALWAYS, LOG_ERR, "Can't write to %s %s: %s", device_info, device, strerror(errno)); - running = false; + event_exit(); } return false; From 2ebbac3278ab57f0efb0f0968b558f15ee0df302 Mon Sep 17 00:00:00 2001 From: Guus Sliepen Date: Mon, 26 Aug 2019 13:44:50 +0200 Subject: [PATCH 05/13] Import Upstream version 1.1~pre7 --- COPYING | 2 +- ChangeLog | 17 + Makefile.am | 2 +- Makefile.in | 2 +- NEWS | 14 + README | 10 +- README.android | 20 + THANKS | 1 + configure | 2 +- configure.in | 2 +- doc/Makefile.am | 10 +- doc/Makefile.in | 10 +- doc/{tincctl.8.in => tinc.8.in} | 28 +- doc/tinc.conf.5.in | 20 +- doc/tinc.info | 1341 ++++++++++++++++++------------- doc/tinc.texi | 483 +++++++---- doc/tincd.8.in | 4 +- src/Makefile.am | 8 +- src/Makefile.in | 35 +- src/event.c | 6 + src/event.h | 1 + src/graph.c | 2 +- src/mingw/device.c | 1 + src/net.c | 2 +- src/net.h | 1 + src/net_packet.c | 5 +- src/net_setup.c | 7 +- src/net_socket.c | 11 +- src/protocol.c | 2 +- src/protocol_auth.c | 13 +- src/protocol_key.c | 4 +- src/protocol_misc.c | 2 +- src/route.c | 4 +- src/sptps_test.c | 43 +- src/tincctl.c | 100 +-- src/tincd.c | 3 +- 36 files changed, 1358 insertions(+), 860 deletions(-) create mode 100644 README.android rename doc/{tincctl.8.in => tinc.8.in} (93%) diff --git a/COPYING b/COPYING index 85c729f..f4dd065 100644 --- a/COPYING +++ b/COPYING @@ -1,4 +1,4 @@ -Copyright (C) 1998-2012 Ivo Timmermans, Guus Sliepen and others. +Copyright (C) 1998-2013 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/ChangeLog b/ChangeLog index 2d8d985..01a1494 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,20 @@ +Version 1.1pre7 April 22 2013 +------------------------------------------------------------------------ + +Guus Sliepen (12): + Use UDP when using sptps_test in datagram mode. + Flush output buffers in the tap reader thread on Windows. + Better default output file for generated public keys. + Allow changing configuration with tincctl without the "config" keyword. + Avoid calling time(NULL). + Include README.android in the tarballs. + Rename tincctl to tinc. + Remove references to the config keyword. + Describe the SPTPS protocol in the manual. + Fix completion of add/del/get/set commands. + Drop packets forwarded via TCP if they are too big (CVE-2013-1428). + Releasing 1.1pre7. + Version 1.1pre6 February 20 2013 ------------------------------------------------------------------------ diff --git a/Makefile.am b/Makefile.am index e37864d..130cd6e 100644 --- a/Makefile.am +++ b/Makefile.am @@ -6,7 +6,7 @@ SUBDIRS = m4 src doc gui ACLOCAL_AMFLAGS = -I m4 -EXTRA_DIST = have.h system.h COPYING.README +EXTRA_DIST = have.h system.h COPYING.README README.android ChangeLog: git log > ChangeLog diff --git a/Makefile.in b/Makefile.in index 657ca58..5ae644b 100644 --- a/Makefile.in +++ b/Makefile.in @@ -236,7 +236,7 @@ top_srcdir = @top_srcdir@ AUTOMAKE_OPTIONS = gnu SUBDIRS = m4 src doc gui ACLOCAL_AMFLAGS = -I m4 -EXTRA_DIST = have.h system.h COPYING.README +EXTRA_DIST = have.h system.h COPYING.README README.android all: config.h $(MAKE) $(AM_MAKEFLAGS) all-recursive diff --git a/NEWS b/NEWS index a6e13d8..960b85c 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,17 @@ +Version 1.1pre7 April 22 2013 + + * Fixed large latencies on Windows. + + * Renamed the tincctl tool to tinc. + + * Simplified changing the configuration using the tinc tool. + + * Added a full description of the ExperimentalProtocol to the manual. + + * Drop packets forwarded via TCP if they are too big (CVE-2013-1428). + +Thanks to Martin Schobert for auditing tinc and reporting the vulnerability. + Version 1.1pre6 February 20 2013 * Fixed tincd exitting immediately on Windows. diff --git a/README b/README index 0709fb8..3267829 100644 --- a/README +++ b/README @@ -1,4 +1,4 @@ -This is the README file for tinc version 1.1pre6. Installation +This is the README file for tinc version 1.1pre7. Installation instructions may be found in the INSTALL file. tinc is Copyright (C) 1998-2013 by: @@ -22,7 +22,7 @@ Please note that this is NOT a stable release. Until version 1.1.0 is released, please use one of the 1.0.x versions if you need a stable version of tinc. Although tinc 1.1 will be protocol compatible with tinc 1.0.x, the -functionality of the tincctl program may still change, and the control socket +functionality of the tinc program may still change, and the control socket protocol is not fixed yet. @@ -36,11 +36,11 @@ at your own risk. Compatibility ------------- -Version 1.1pre6 is compatible with 1.0pre8, 1.0 and later, but not with older +Version 1.1pre7 is compatible with 1.0pre8, 1.0 and later, but not with older versions of tinc. When the ExperimentalProtocol option is used, tinc is still compatible with -1.0.X and 1.1pre6 itself, but not with any other 1.1preX version. +1.0.X and 1.1pre7 itself, but not with any other 1.1preX version. Requirements @@ -88,6 +88,6 @@ Windows environment this means tinc will intall itself as a service, which will restart after reboots. To prevent tinc from detaching or running as a service, use the -D option. -The status of the VPN can be queried using the "tincctl" tool, which connects +The status of the VPN can be queried using the "tinc" command, which connects to a running tinc daemon via a control connection. The same tool also makes it easy to start and stop tinc, and to change its configuration. diff --git a/README.android b/README.android new file mode 100644 index 0000000..6fffe41 --- /dev/null +++ b/README.android @@ -0,0 +1,20 @@ +Quick how-o cross compile tinc for android (done from $HOME/android/): + +- Download android NDK and setup local ARM toolchain: +wget http://dl.google.com/android/ndk/android-ndk-r8b-linux-x86.tar.bz2 +tar xfj android-ndk-r8b-linux-x86.tar.bz2 +./android-ndk-r8b/build/tools/make-standalone-toolchain.sh --platform=android-5 --install-dir=/tmp/my-android-toolchain + +- Download and cross-compile openSSL for ARM: +wget http://www.openssl.org/source/openssl-1.0.1c.tar.gz +tar xfz openssl-1.0.1c.tar.gz +cd openssl-1.0.1c +./Configure dist +make CC=/tmp/my-android-toolchain/bin/arm-linux-androideabi-gcc AR="/tmp/my-android-toolchain/bin/arm-linux-androideabi-ar r" RANLIB=/tmp/my-android-toolchain/bin/arm-linux-androideabi-ranlib + +- Clone and cross-compile tinc: +git clone git://tinc-vpn.org/tinc +cd tinc +autoreconf -fsi +CC=/tmp/my-android-toolchain/bin/arm-linux-androideabi-gcc ./configure --host=arm-linux --disable-lzo --with-openssl-lib=$HOME/android/openssl-1.0.1c --with-openssl-include=$HOME/android/openssl-1.0.1c/include/ +make -j5 diff --git a/THANKS b/THANKS index 1f2f73c..040f33d 100644 --- a/THANKS +++ b/THANKS @@ -30,6 +30,7 @@ We would like to thank the following people for their contributions to tinc: * Mark Glines * Markus Goetz * Martin Kihlgren +* Martin Schobert * Martin Schürrer * Matias Carrasco * Max Rijevski diff --git a/configure b/configure index 86d7e70..8c3051f 100755 --- a/configure +++ b/configure @@ -4095,7 +4095,7 @@ fi # Define the identity of the package. PACKAGE=tinc - VERSION=1.1pre6 + VERSION=1.1pre7 cat >>confdefs.h <<_ACEOF diff --git a/configure.in b/configure.in index f2ec3bd..a59482a 100644 --- a/configure.in +++ b/configure.in @@ -4,7 +4,7 @@ AC_PREREQ(2.61) AC_INIT AC_CONFIG_SRCDIR([src/tincd.c]) AC_GNU_SOURCE -AM_INIT_AUTOMAKE(tinc, 1.1pre6) +AM_INIT_AUTOMAKE(tinc, 1.1pre7) AC_CONFIG_HEADERS([config.h]) AM_MAINTAINER_MODE diff --git a/doc/Makefile.am b/doc/Makefile.am index 2ada5d7..9540b49 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -2,11 +2,11 @@ info_TEXINFOS = tinc.texi -man_MANS = tincd.8 tincctl.8 tinc.conf.5 tinc-gui.8 +man_MANS = tincd.8 tinc.8 tinc.conf.5 tinc-gui.8 -EXTRA_DIST = tincinclude.texi.in tincd.8.in tincctl.8.in tinc.conf.5.in tinc-gui.8.in sample-config.tar.gz +EXTRA_DIST = tincinclude.texi.in tincd.8.in tinc.8.in tinc.conf.5.in tinc-gui.8.in sample-config.tar.gz -CLEANFILES = *.html tinc.info tincd.8 tincctl.8 tinc.conf.5 tinc-gui.8 tincinclude.texi +CLEANFILES = *.html tinc.info tincd.8 tinc.8 tinc.conf.5 tinc-gui.8 tincinclude.texi # Use `ginstall' in the definition of man_MANS to avoid # confusion with the `install' target. The install rule transforms `ginstall' @@ -25,7 +25,7 @@ texi2html: tinc.texi tincd.8.html: tincd.8 w3mman2html $? > $@ -tincctl.8.html: tincctl.8 +tinc.8.html: tinc.8 w3mman2html $? > $@ tinc-gui.8.html: tinc-gui.8 @@ -43,7 +43,7 @@ substitute = sed \ tincd.8: tincd.8.in $(substitute) $? > $@ -tincctl.8: tincctl.8.in +tinc.8: tinc.8.in $(substitute) $? > $@ tinc-gui.8: tinc-gui.8.in diff --git a/doc/Makefile.in b/doc/Makefile.in index 3212126..b95f19c 100644 --- a/doc/Makefile.in +++ b/doc/Makefile.in @@ -224,9 +224,9 @@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ info_TEXINFOS = tinc.texi -man_MANS = tincd.8 tincctl.8 tinc.conf.5 tinc-gui.8 -EXTRA_DIST = tincinclude.texi.in tincd.8.in tincctl.8.in tinc.conf.5.in tinc-gui.8.in sample-config.tar.gz -CLEANFILES = *.html tinc.info tincd.8 tincctl.8 tinc.conf.5 tinc-gui.8 tincinclude.texi +man_MANS = tincd.8 tinc.8 tinc.conf.5 tinc-gui.8 +EXTRA_DIST = tincinclude.texi.in tincd.8.in tinc.8.in tinc.conf.5.in tinc-gui.8.in sample-config.tar.gz +CLEANFILES = *.html tinc.info tincd.8 tinc.8 tinc.conf.5 tinc-gui.8 tincinclude.texi substitute = sed \ -e s,'@PACKAGE\@',"$(PACKAGE)",g \ -e s,'@VERSION\@',"$(VERSION)",g \ @@ -772,7 +772,7 @@ texi2html: tinc.texi tincd.8.html: tincd.8 w3mman2html $? > $@ -tincctl.8.html: tincctl.8 +tinc.8.html: tinc.8 w3mman2html $? > $@ tinc-gui.8.html: tinc-gui.8 @@ -784,7 +784,7 @@ tinc.conf.5.html: tinc.conf.5 tincd.8: tincd.8.in $(substitute) $? > $@ -tincctl.8: tincctl.8.in +tinc.8: tinc.8.in $(substitute) $? > $@ tinc-gui.8: tinc-gui.8.in diff --git a/doc/tincctl.8.in b/doc/tinc.8.in similarity index 93% rename from doc/tincctl.8.in rename to doc/tinc.8.in index e530116..fba373e 100644 --- a/doc/tincctl.8.in +++ b/doc/tinc.8.in @@ -3,7 +3,7 @@ .\" Manual page created by: .\" Scott Lamb .Sh NAME -.Nm tincctl +.Nm tinc .Nd tinc VPN control .Sh SYNOPSIS .Nm @@ -51,12 +51,12 @@ Create initial configuration files and RSA and ECDSA keypairs with default lengt If no .Ar name for this node is given, it will be asked for. -.It config Oo get Oc Ar variable +.It get Ar variable Print the current value of configuration variable .Ar variable . If more than one variable with the same name exists, the value of each of them will be printed on a separate line. -.It config Oo set Oc Ar variable Ar value +.It set Ar variable Ar value Set configuration variable .Ar variable to the given @@ -64,9 +64,9 @@ to the given All previously existing configuration variables with the same name are removed. To set a variable for a specific host, use the notation .Ar host Ns Li . Ns Ar variable . -.It config add Ar variable Ar value +.It add Ar variable Ar value As above, but without removing any previously existing configuration variables. -.It config del Ar variable Op Ar value +.It del Ar variable Op Ar value Remove configuration variables with the same name and .Ar value . If no @@ -147,7 +147,7 @@ Sets debug level to .It log Op Ar N Capture log messages from a running tinc daemon. An optional debug level can be given that will be applied only for log messages sent to -.Nm tincctl . +.Nm tinc . .It retry Forces .Xr tincd 8 @@ -182,19 +182,19 @@ such as .Sh EXAMPLES Examples of some commands: .Bd -literal -offset indent -tincctl -n vpn dump graph | circo -Txlib -tincctl -n vpn pcap | tcpdump -r - -tincctl -n vpn top +tinc -n vpn dump graph | circo -Txlib +tinc -n vpn pcap | tcpdump -r - +tinc -n vpn top .Pp .Ed Example of configuring tinc using .Nm : .Bd -literal -offset indent -tincctl -n vpn init foo -tincctl -n vpn config Subnet 192.168.1.0/24 -tincctl -n vpn config bar.Address bar.example.com -tincctl -n vpn config ConnectTo bar -tincctl -n vpn export | gpg --clearsign | mail -s "My config" vpnmaster@example.com +tinc -n vpn init foo +tinc -n vpn add Subnet 192.168.1.0/24 +tinc -n vpn add bar.Address bar.example.com +tinc -n vpn add ConnectTo bar +tinc -n vpn export | gpg --clearsign | mail -s "My config" vpnmaster@example.com .Ed .Sh TOP The top command connects to a running tinc daemon and repeatedly queries its per-node traffic counters. diff --git a/doc/tinc.conf.5.in b/doc/tinc.conf.5.in index 38a4c11..1cca366 100644 --- a/doc/tinc.conf.5.in +++ b/doc/tinc.conf.5.in @@ -55,15 +55,15 @@ However, you are only allowed to use alphanumerical characters (a-z, A-Z, and 0- .Sh INITIAL CONFIGURATION If you have not configured tinc yet, you can easily create a basic configuration using the following command: .Bd -literal -offset indent -.Nm tincctl Fl n Ar NETNAME Li init Ar NAME +.Nm tinc Fl n Ar NETNAME Li init Ar NAME .Ed .Pp You can further change the configuration as needed either by manually editing the configuration files, or by using -.Xr tincctl 8 . +.Xr tinc 8 . .Sh PUBLIC/PRIVATE KEYS The -.Nm tincctl Li init +.Nm tinc Li init command will have generated both RSA and ECDSA public/private keypairs. The private keys should be stored in files named .Pa rsa_key.priv @@ -77,7 +77,7 @@ The RSA keys are used for backwards compatibility with tinc version 1.0. If you are upgrading from version 1.0 to 1.1, you can keep the old configuration files, but you will need to create ECDSA keys using the following command: .Bd -literal -offset indent -.Nm tincctl Fl n Ar NETNAME Li generate-ecdsa-keys +.Nm tinc Fl n Ar NETNAME Li generate-ecdsa-keys .Ed .Sh SERVER CONFIGURATION The server configuration of the daemon is done in the file @@ -102,7 +102,7 @@ it is recommended to put host specific configuration options in the host configu as this makes it easy to exchange with other nodes. .Pp You can edit the config file manually, but it is recommended that you use -.Xr tincctl 8 +.Xr tinc 8 to change configuration variables for you. .Pp Here are all valid variables, listed in alphabetical order. @@ -279,7 +279,7 @@ When this option is enabled, experimental protocol enhancements will be used. Ephemeral ECDH will be used for key exchanges, and ECDSA will be used instead of RSA for authentication. When enabled, an ECDSA key must have been generated before with -.Nm tincctl generate-ecdsa-keys . +.Nm tinc generate-ecdsa-keys . The experimental protocol may change at any time, and there is no guarantee that tinc will run stable when it is used. .It Va Forwarding Li = off | internal | kernel Po internal Pc Bq experimental @@ -482,6 +482,8 @@ Furthermore, specifying .Qq none will turn off packet encryption. It is best to use only those ciphers which support CBC mode. +This option has no effect for connections between nodes using +.Va ExperimentalProtocol . .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 @@ -496,6 +498,8 @@ Any digest supported by OpenSSL is recognised. Furthermore, specifying .Qq none will turn off packet authentication. +This option has no effect for connections between nodes using +.Va ExperimentalProtocol . .It Va IndirectData Li = yes | no Pq no When set to yes, other nodes which do not already have a meta connection to you will not try to establish direct communication with you. @@ -505,6 +509,8 @@ The length of the message authentication code used to authenticate UDP packets. Can be anything from .Qq 0 up to the length of the digest produced by the digest algorithm. +This option has no effect for connections between nodes using +.Va ExperimentalProtocol . .It Va PMTU Li = Ar mtu Po 1514 Pc This option controls the initial path MTU to this node. .It Va PMTUDiscovery Li = yes | no Po yes Pc @@ -653,7 +659,7 @@ its connection to the virtual network device. .El .Sh SEE ALSO .Xr tincd 8 , -.Xr tincctl 8 , +.Xr tinc 8 , .Pa http://www.tinc-vpn.org/ , .Pa http://www.tldp.org/LDP/nag2/ . .Pp diff --git a/doc/tinc.info b/doc/tinc.info index 690527a..f46a430 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.1pre5, a Virtual Private + This is the info manual for tinc version 1.1pre7, a Virtual Private Network daemon. Copyright (C) 1998-2013 Ivo Timmermans, Guus Sliepen @@ -49,13 +49,13 @@ Tinc is a Virtual Private Network (VPN) daemon that uses tunneling and encryption to create a secure private network between hosts on the Internet. - Because the tunnel appears to the IP level network code as a normal +Because the tunnel appears to the IP level network code as a normal network device, there is no need to adapt any existing software. The encrypted tunnels allows VPN sites to share information with each other over the Internet without exposing any information to others. - This document is the manual for tinc. Included are chapters on how -to configure your computer to use tinc, as well as the configuration +This document is the manual for tinc. Included are chapters on how to +configure your computer to use tinc, as well as the configuration process of tinc itself. * Menu: @@ -74,15 +74,15 @@ A Virtual Private Network or VPN is a network that can only be accessed by a few elected computers that participate. This goal is achievable in more than just one way. - Private networks can consist of a single stand-alone Ethernet LAN. -Or even two computers hooked up using a null-modem cable. In these -cases, it is obvious that the network is _private_, no one can access -it from the outside. But if your computers are linked to the Internet, -the network is not private anymore, unless one uses firewalls to block -all private traffic. But then, there is no way to send private data to +Private networks can consist of a single stand-alone Ethernet LAN. Or +even two computers hooked up using a null-modem cable. In these cases, +it is obvious that the network is _private_, no one can access it from +the outside. But if your computers are linked to the Internet, the +network is not private anymore, unless one uses firewalls to block all +private traffic. But then, there is no way to send private data to trusted computers on the other end of the Internet. - This problem can be solved by using _virtual_ networks. Virtual +This problem can be solved by using _virtual_ networks. Virtual networks can live on top of other networks, but they use encapsulation to keep using their private address space so they do not interfere with the Internet. Mostly, virtual networks appear like a single LAN, even @@ -90,14 +90,14 @@ though they can span the entire world. But virtual networks can't be secured by using firewalls, because the traffic that flows through it has to go through the Internet, where other people can look at it. - As is the case with either type of VPN, anybody could eavesdrop. Or +As is the case with either type of VPN, anybody could eavesdrop. Or worse, alter data. Hence it's probably advisable to encrypt the data that flows over the network. - When one introduces encryption, we can form a true VPN. Other -people may see encrypted traffic, but if they don't know how to -decipher it (they need to know the key for that), they cannot read the -information that flows through the VPN. This is what tinc was made for. +When one introduces encryption, we can form a true VPN. Other people +may see encrypted traffic, but if they don't know how to decipher it +(they need to know the key for that), they cannot read the information +that flows through the VPN. This is what tinc was made for.  File: tinc.info, Node: tinc, Next: Supported platforms, Prev: Virtual Private Networks, Up: Introduction @@ -111,26 +111,26 @@ used the ethertap device that Linux knows of since somewhere about kernel 2.1.60. It didn't work immediately and he improved it a bit. At this stage, the project was still simply called "vpnd". - Since then, a lot has changed--to say the least. +Since then, a lot has changed--to say the least. - Tinc now supports encryption, it consists of a single daemon (tincd) -for both the receiving and sending end, it has become largely +Tinc now supports encryption, it consists of a single daemon (tincd) for +both the receiving and sending end, it has become largely runtime-configurable--in short, it has become a full-fledged professional package. - Tinc also allows more than two sites to connect to eachother and -form a single VPN. Traditionally VPNs are created by making tunnels, -which only have two endpoints. Larger VPNs with more sites are created -by adding more tunnels. Tinc takes another approach: only endpoints -are specified, the software itself will take care of creating the -tunnels. This allows for easier configuration and improved scalability. +Tinc also allows more than two sites to connect to eachother and form a +single VPN. Traditionally VPNs are created by making tunnels, which +only have two endpoints. Larger VPNs with more sites are created by +adding more tunnels. Tinc takes another approach: only endpoints are +specified, the software itself will take care of creating the tunnels. +This allows for easier configuration and improved scalability. - A lot can--and will be--changed. We have a number of things that we +A lot can--and will be--changed. We have a number of things that we would like to see in the future releases of tinc. Not everything will be available in the near future. Our first objective is to make tinc work perfectly as it stands, and then add more advanced features. - Meanwhile, we're always open-minded towards new ideas. And we're +Meanwhile, we're always open-minded towards new ideas. And we're available too.  @@ -147,8 +147,8 @@ or other virtual network device drivers. Without such a driver, tinc will most likely compile and run, but it will not be able to send or receive data packets. - For an up to date list of supported platforms, please check the list -on our website: `http://www.tinc-vpn.org/platforms/'. +For an up to date list of supported platforms, please check the list on +our website: `http://www.tinc-vpn.org/platforms/'.  File: tinc.info, Node: Preparations, Next: Installation, Prev: Introduction, Up: Top @@ -195,11 +195,11 @@ Here are the options you have to turn on when configuring a new kernel: Network device support Universal tun/tap device driver support - It's not necessary to compile this driver as a module, even if you -are going to run more than one instance of tinc. +It's not necessary to compile this driver as a module, even if you are +going to run more than one instance of tinc. - If you decide to build the tun/tap driver as a kernel module, add -these lines to `/etc/modules.conf': +If you decide to build the tun/tap driver as a kernel module, add these +lines to `/etc/modules.conf': alias char-major-10-200 tun @@ -236,7 +236,7 @@ File: tinc.info, Node: Configuration of NetBSD kernels, Next: Configuration of For NetBSD version 1.5.2 and higher, the tun driver is included in the default kernel configuration. - Tunneling IPv6 may not work on NetBSD's tun device. +Tunneling IPv6 may not work on NetBSD's tun device.  File: tinc.info, Node: Configuration of Solaris kernels, Next: Configuration of Darwin (MacOS/X) kernels, Prev: Configuration of NetBSD kernels, Up: Configuring the kernel @@ -307,23 +307,23 @@ File: tinc.info, Node: OpenSSL, Next: zlib, Up: Libraries For all cryptography-related functions, tinc uses the functions provided by the OpenSSL library. - If this library is not installed, you wil get an error when -configuring tinc for build. Support for running tinc with other -cryptographic libraries installed _may_ be added in the future. +If this library is not installed, you wil get an error when configuring +tinc for build. Support for running tinc with other cryptographic +libraries installed _may_ be added in the future. - You can use your operating system's package manager to install this -if available. Make sure you install the development AND runtime -versions of this package. +You can use your operating system's package manager to install this if +available. Make sure you install the development AND runtime versions +of this package. - If you have to install OpenSSL manually, you can get the source code +If you have to install OpenSSL manually, you can get the source code from `http://www.openssl.org/'. Instructions on how to configure, build and install this package are included within the package. Please make sure you build development and runtime libraries (which is the default). - If you installed the OpenSSL libraries from source, it may be -necessary to let configure know where they are, by passing configure -one of the -with-openssl-* parameters. +If you installed the OpenSSL libraries from source, it may be necessary +to let configure know where they are, by passing configure one of the +-with-openssl-* parameters. --with-openssl=DIR OpenSSL library and headers prefix --with-openssl-include=DIR OpenSSL headers directory @@ -346,8 +346,8 @@ everyone to create a statically or dynamically linked executable: allowed. You may provide binary packages linked to the OpenSSL libraries, provided that all other requirements of the GPL are met. - Since the LZO library used by tinc is also covered by the GPL, we -also present the following exemption: +Since the LZO library used by tinc is also covered by the GPL, we also +present the following exemption: Hereby I grant a special exception to the tinc VPN project (http://www.tinc-vpn.org/) to link the LZO library with the @@ -364,22 +364,21 @@ File: tinc.info, Node: zlib, Next: lzo, Prev: OpenSSL, Up: Libraries For the optional compression of UDP packets, tinc uses the functions provided by the zlib library. - If this library is not installed, you wil get an error when running -the configure script. You can either install the zlib library, or -disable support for zlib compression by using the "-disable-zlib" -option when running the configure script. Note that if you disable -support for zlib, the resulting binary will not work correctly on VPNs -where zlib compression is used. +If this library is not installed, you wil get an error when running the +configure script. You can either install the zlib library, or disable +support for zlib compression by using the "-disable-zlib" option when +running the configure script. Note that if you disable support for +zlib, the resulting binary will not work correctly on VPNs where zlib +compression is used. - You can use your operating system's package manager to install this -if available. Make sure you install the development AND runtime -versions of this package. +You can use your operating system's package manager to install this if +available. Make sure you install the development AND runtime versions +of this package. - If you have to install zlib manually, you can get the source code -from `http://www.gzip.org/zlib/'. Instructions on how to configure, -build and install this package are included within the package. Please -make sure you build development and runtime libraries (which is the -default). +If you have to install zlib manually, you can get the source code from +`http://www.gzip.org/zlib/'. Instructions on how to configure, build +and install this package are included within the package. Please make +sure you build development and runtime libraries (which is the default).  File: tinc.info, Node: lzo, Next: libcurses, Prev: zlib, Up: Libraries @@ -389,20 +388,20 @@ File: tinc.info, Node: lzo, Next: libcurses, Prev: zlib, Up: Libraries Another form of compression is offered using the LZO library. - If this library is not installed, you wil get an error when running -the configure script. You can either install the LZO library, or -disable support for LZO compression by using the "-disable-lzo" option -when running the configure script. Note that if you disable support for -LZO, the resulting binary will not work correctly on VPNs where LZO +If this library is not installed, you wil get an error when running the +configure script. You can either install the LZO library, or disable +support for LZO compression by using the "-disable-lzo" option when +running the configure script. Note that if you disable support for LZO, +the resulting binary will not work correctly on VPNs where LZO compression is used. - You can use your operating system's package manager to install this -if available. Make sure you install the development AND runtime -versions of this package. +You can use your operating system's package manager to install this if +available. Make sure you install the development AND runtime versions +of this package. - If you have to install lzo manually, you can get the source code -from `http://www.oberhumer.com/opensource/lzo/'. Instructions on how -to configure, build and install this package are included within the +If you have to install lzo manually, you can get the source code from +`http://www.oberhumer.com/opensource/lzo/'. Instructions on how to +configure, build and install this package are included within the package. Please make sure you build development and runtime libraries (which is the default). @@ -412,21 +411,21 @@ File: tinc.info, Node: libcurses, Next: libreadline, Prev: lzo, Up: Librarie 2.2.4 libcurses --------------- -For the "tincctl top" command, tinc requires a curses library. +For the "tinc top" command, tinc requires a curses library. - If this library is not installed, you wil get an error when running -the configure script. You can either install a suitable curses -library, or disable all functionality that depends on a curses library -by using the "-disable-curses" option when running the configure script. +If this library is not installed, you wil get an error when running the +configure script. You can either install a suitable curses library, or +disable all functionality that depends on a curses library by using the +"-disable-curses" option when running the configure script. - There are several curses libraries. It is recommended that you -install "ncurses" (`http://invisible-island.net/ncurses/'), however -other curses libraries should also work. In particular, "PDCurses" +There are several curses libraries. It is recommended that you install +"ncurses" (`http://invisible-island.net/ncurses/'), however other +curses libraries should also work. In particular, "PDCurses" (`http://pdcurses.sourceforge.net/') is recommended if you want to compile tinc for Windows. - You can use your operating system's package manager to install this -if available. Make sure you install the development AND runtime versions +You can use your operating system's package manager to install this if +available. Make sure you install the development AND runtime versions of this package.  @@ -435,20 +434,19 @@ File: tinc.info, Node: libreadline, Prev: libcurses, Up: Libraries 2.2.5 libreadline ----------------- -For the "tincctl" command's shell functionality, tinc uses the readline +For the "tinc" command's shell functionality, tinc uses the readline library. - If this library is not installed, you wil get an error when running -the configure script. You can either install a suitable readline -library, or disable all functionality that depends on a readline -library by using the "-disable-readline" option when running the -configure script. +If this library is not installed, you wil get an error when running the +configure script. You can either install a suitable readline library, +or disable all functionality that depends on a readline library by +using the "-disable-readline" option when running the configure script. - You can use your operating system's package manager to install this -if available. Make sure you install the development AND runtime -versions of this package. +You can use your operating system's package manager to install this if +available. Make sure you install the development AND runtime versions +of this package. - If you have to install libreadline manually, you can get the source +If you have to install libreadline manually, you can get the source code from `http://www.gnu.org/software/readline/'. Instructions on how to configure, build and install this package are included within the package. Please make sure you build development and runtime libraries @@ -464,15 +462,15 @@ If you use Debian, you may want to install one of the precompiled packages for your system. These packages are equipped with system startup scripts and sample configurations. - If you cannot use one of the precompiled packages, or you want to +If you cannot use one of the precompiled packages, or you want to compile tinc for yourself, you can use the source. The source is distributed under the GNU General Public License (GPL). Download the source from the download page (http://www.tinc-vpn.org/download/), which has the checksums of these files listed; you may wish to check these with md5sum before continuing. - Tinc comes in a convenient autoconf/automake package, which you can -just treat the same as any other package. Which is just untar it, type +Tinc comes in a convenient autoconf/automake package, which you can just +treat the same as any other package. Which is just untar it, type `./configure' and then `make'. More detailed instructions are in the file `INSTALL', which is included in the source distribution. @@ -490,10 +488,10 @@ File: tinc.info, Node: Building and installing tinc, Next: System files, Up: Detailed instructions on configuring the source, building tinc and installing tinc can be found in the file called `INSTALL'. - If you happen to have a binary package for tinc for your -distribution, you can use the package management tools of that -distribution to install tinc. The documentation that comes along with -your distribution will tell you how to do that. +If you happen to have a binary package for tinc for your distribution, +you can use the package management tools of that distribution to +install tinc. The documentation that comes along with your +distribution will tell you how to do that. * Menu: @@ -512,7 +510,7 @@ Developer Tools from `http://developer.apple.com/tools/macosxtools.html' and a recent version of Fink from `http://www.finkproject.org/'. - After installation use fink to download and install the following +After installation use fink to download and install the following packages: autoconf25, automake, dlcompat, m4, openssl, zlib and lzo.  @@ -524,7 +522,7 @@ File: tinc.info, Node: Cygwin (Windows) build environment, Next: MinGW (Window If Cygwin hasn't already been installed, install it directly from `http://www.cygwin.com/'. - When tinc is compiled in a Cygwin environment, it can only be run in +When tinc is compiled in a Cygwin environment, it can only be run in this environment, but all programs, including those started outside the Cygwin environment, will be able to use the VPN. It will also support all features. @@ -538,10 +536,10 @@ File: tinc.info, Node: MinGW (Windows) build environment, Prev: Cygwin (Window You will need to install the MinGW environment from `http://www.mingw.org'. - When tinc is compiled using MinGW it runs natively under Windows, it -is not necessary to keep MinGW installed. +When tinc is compiled using MinGW it runs natively under Windows, it is +not necessary to keep MinGW installed. - When detaching, tinc will install itself as a service, which will be +When detaching, tinc will install itself as a service, which will be restarted automatically after reboots.  @@ -567,8 +565,8 @@ File: tinc.info, Node: Device files, Next: Other files, Up: System files Most operating systems nowadays come with the necessary device files by default, or they have a mechanism to create them on demand. - If you use Linux and do not have udev installed, you may need to -create the following device file if it does not exist: +If you use Linux and do not have udev installed, you may need to create +the following device file if it does not exist: mknod -m 600 /dev/net/tun c 10 200 @@ -630,17 +628,17 @@ documentation. Make sure you have an adequate understanding of networks in general. A good resource on networking is the Linux Network Administrators Guide (http://www.tldp.org/LDP/nag2/). - If you have everything clearly pictured in your mind, proceed in the +If you have everything clearly pictured in your mind, proceed in the following order: First, create the initial configuration files and public/private keypairs using the following command: - tincctl -n NETNAME init NAME - Second, use `tincctl -n NETNAME config ...' to further configure -tinc. Finally, export your host configuration file using `tincctl -n -NETNAME export' and send it to those people or computers you want tinc -to connect to. They should send you their host configuration file -back, which you can import using `tincctl -n NETNAME import'. + tinc -n NETNAME init NAME +Second, use `tinc -n NETNAME add ...' to further configure tinc. +Finally, export your host configuration file using `tinc -n NETNAME +export' and send it to those people or computers you want tinc to +connect to. They should send you their host configuration file back, +which you can import using `tinc -n NETNAME import'. - These steps are described in the subsections below. +These steps are described in the subsections below.  File: tinc.info, Node: Multiple networks, Next: How connections work, Prev: Configuration introduction, Up: Configuration @@ -654,18 +652,17 @@ assign a NETNAME to your VPN. It is not required if you only run one tinc daemon, it doesn't even have to be the same on all the nodes of your VPN, but it is recommended that you choose one anyway. - We will asume you use a netname throughout this document. This -means that you call tincctl with the -n argument, which will specify -the netname. +We will asume you use a netname throughout this document. This means +that you call tinc with the -n argument, which will specify the netname. - The effect of this option is that tinc will set its configuration -root to `/etc/tinc/NETNAME/', where NETNAME is your argument to the -n +The effect of this option is that tinc will set its configuration root +to `/etc/tinc/NETNAME/', where NETNAME is your argument to the -n option. You will also notice that log messages it appears in syslog as coming from `tinc.NETNAME', and on Linux, unless specified otherwise, the name of the virtual network interface will be the same as the network name. - However, it is not strictly necessary that you call tinc with the -n +However, it is not strictly necessary that you call tinc with the -n option. If you don not use it, the network name will just be empty, and tinc will look for files in `/etc/tinc/' instead of `/etc/tinc/NETNAME/'; the configuration file will then be @@ -690,23 +687,23 @@ you tell it to stop, and failures to connect to other tinc daemons will not stop your tinc daemon for trying again later. This means you don't have to intervene if there are temporary network problems. - There is no real distinction between a server and a client in tinc. -If you wish, you can view a tinc daemon without a `ConnectTo' value as -a server, and one which does specify such a value as a client. It does +There is no real distinction between a server and a client in tinc. If +you wish, you can view a tinc daemon without a `ConnectTo' value as a +server, and one which does specify such a value as a client. It does not matter if two tinc daemons have a `ConnectTo' value pointing to each other however. - Connections specified using `ConnectTo' are so-called -meta-connections. Tinc daemons exchange information about all other -daemon they know about via these meta-connections. After learning -about all the daemons in the VPN, tinc will create other connections as -necessary in order to communicate with them. For example, if there are -three daemons named A, B and C, and A has `ConnectTo = B' in its -tinc.conf file, and C has `ConnectTo = B' in its tinc.conf file, then A -will learn about C from B, and will be able to exchange VPN packets -with C without the need to have `ConnectTo = C' in its tinc.conf file. +Connections specified using `ConnectTo' are so-called meta-connections. +Tinc daemons exchange information about all other daemon they know +about via these meta-connections. After learning about all the daemons +in the VPN, tinc will create other connections as necessary in order to +communicate with them. For example, if there are three daemons named +A, B and C, and A has `ConnectTo = B' in its tinc.conf file, and C has +`ConnectTo = B' in its tinc.conf file, then A will learn about C from B, +and will be able to exchange VPN packets with C without the need to +have `ConnectTo = C' in its tinc.conf file. - It could be that some daemons are located behind a Network Address +It could be that some daemons are located behind a Network Address Translation (NAT) device, or behind a firewall. In the above scenario with three daemons, if A and C are behind a NAT, B will automatically help A and C punch holes through their NAT, in a way similar to the @@ -715,9 +712,9 @@ directly. It is not always possible to do this however, and firewalls might also prevent direct communication. In that case, VPN packets between A and C will be forwarded by B. - In effect, all nodes in the VPN will be able to talk to each other, -as long as their is a path of meta-connections between them, and -whenever possible, two nodes will communicate with each other directly. +In effect, all nodes in the VPN will be able to talk to each other, as +long as their is a path of meta-connections between them, and whenever +possible, two nodes will communicate with each other directly.  File: tinc.info, Node: Configuration files, Next: Network interfaces, Prev: How connections work, Up: Configuration @@ -729,28 +726,27 @@ The actual configuration of the daemon is done in the file `/etc/tinc/NETNAME/tinc.conf' and at least one other file in the directory `/etc/tinc/NETNAME/hosts/'. - These file consists of comments (lines started with a #) or -assignments in the form of +These file consists of comments (lines started with a #) or assignments +in the form of Variable = Value. - The variable names are case insensitive, and any spaces, tabs, -newlines and carriage returns are ignored. Note: it is not required -that you put in the `=' sign, but doing so improves readability. If -you leave it out, remember to replace it with at least one space -character. +The variable names are case insensitive, and any spaces, tabs, newlines +and carriage returns are ignored. Note: it is not required that you put +in the `=' sign, but doing so improves readability. If you leave it +out, remember to replace it with at least one space character. - The server configuration is complemented with host specific +The server configuration is complemented with host specific configuration (see the next section). Although all host configuration options for the local node listed in this document can also be put in `/etc/tinc/NETNAME/tinc.conf', it is recommended to put host specific configuration options in the host configuration file, as this makes it easy to exchange with other nodes. - You can edit the config file manually, but it is recommended that -you use tincctl to change configuration variables for you. +You can edit the config file manually, but it is recommended that you +use the tinc command to change configuration variables for you. - In the following two subsections all valid variables are listed in +In the following two subsections all valid variables are listed in alphabetical order. The default value is given between parentheses, other comments are between square brackets. @@ -929,10 +925,10 @@ ExperimentalProtocol = (no) [experimental] When this option is enabled, experimental protocol enhancements will be used. Ephemeral ECDH will be used for key exchanges, and ECDSA will be used instead of RSA for authentication. When - enabled, an ECDSA key must have been generated before with - `tincctl generate-ecdsa-keys'. The experimental protocol may - change at any time, and there is no guarantee that tinc will run - stable when it is used. + enabled, an ECDSA key must have been generated before with `tinc + generate-ecdsa-keys'. The experimental protocol may change at any + time, and there is no guarantee that tinc will run stable when it + is used. Forwarding = (internal) [experimental] This option selects the way indirect packets are forwarded. @@ -1056,8 +1052,8 @@ PrivateKey = [obsolete] PrivateKeyFile = (`/etc/tinc/NETNAME/rsa_key.priv') This is the full path name of the RSA private key file that was - generated by `tincctl generate-keys'. It must be a full path, not - a relative directory. + generated by `tinc generate-keys'. It must be a full path, not a + relative directory. ProcessPriority = When this option is used the priority of the tincd process will be @@ -1134,10 +1130,12 @@ Address = [] [recommended] port is specified, the default Port is used. Cipher = (blowfish) - The symmetric cipher algorithm used to encrypt UDP packets. 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. + The symmetric cipher algorithm used to encrypt UDP packets using + the legacy protocol. 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. This option has no effect for connections using the + SPTPS protocol, which always use AES-256-CTR. ClampMSS = (yes) This option specifies whether tinc should clamp the maximum @@ -1151,9 +1149,11 @@ Compression = (0) (best zlib), 10 (fast lzo) and 11 (best lzo). Digest = (sha1) - The digest algorithm used to authenticate UDP packets. Any digest - supported by OpenSSL is recognized. Furthermore, specifying - "none" will turn off packet authentication. + The digest algorithm used to authenticate UDP packets using the + legacy protocol. Any digest supported by OpenSSL is recognized. + Furthermore, specifying "none" will turn off packet authentication. + This option has no effect for connections using the SPTPS + protocol, which always use HMAC-SHA-256. IndirectData = (no) When set to yes, other nodes which do not already have a meta @@ -1162,8 +1162,10 @@ IndirectData = (no) MACLength = (4) The length of the message authentication code used to authenticate - UDP packets. Can be anything from 0 up to the length of the - digest produced by the digest algorithm. + UDP packets using the legacy protocol. Can be anything from 0 up + to the length of the digest produced by the digest algorithm. + This option has no effect for connections using the SPTPS + protocol, which never truncate MACs. PMTU = (1514) This option controls the initial path MTU to this node. @@ -1182,8 +1184,8 @@ PublicKey = [obsolete] PublicKeyFile = [obsolete] This is the full path name of the RSA public key file that was - generated by `tincctl generate-keys'. It must be a full path, not - a relative directory. + generated by `tinc generate-keys'. It must be a full path, not a + relative directory. From version 1.0pre4 on tinc will store the public key directly into the host configuration file in PEM format, the above two @@ -1272,7 +1274,7 @@ scripts should have the extension .bat. `/etc/tinc/NETNAME/subnet-down' This script is started when a Subnet becomes unreachable. - The scripts are started without command line arguments, but can make +The scripts are started without command line arguments, but can make use of certain environment variables. Under UNIX like operating systems the names of environment variables must be preceded by a $ in scripts. Under Windows, in `.bat' files, they have to be put between % @@ -1319,24 +1321,24 @@ Step 1. Creating initial configuration files. The initial directory structure, configuration files and public/private keypairs are created using the following command: - tincctl -n NETNAME init NAME + tinc -n NETNAME init NAME - (You will need to run this as root, or use "sudo".) This will -create the configuration directory `/etc/tinc/NETNAME.', and inside it -will create another directory named `hosts/'. In the configuration +(You will need to run this as root, or use "sudo".) This will create +the configuration directory `/etc/tinc/NETNAME.', and inside it will +create another directory named `hosts/'. In the configuration directory, it will create the file `tinc.conf' with the following contents: Name = NAME - It will also create private RSA and ECDSA keys, which will be stored -in the files `rsa_key.priv' and `ecdsa_key.priv'. It will also create -a host configuration file `hosts/NAME', which will contain the +It will also create private RSA and ECDSA keys, which will be stored in +the files `rsa_key.priv' and `ecdsa_key.priv'. It will also create a +host configuration file `hosts/NAME', which will contain the corresponding public RSA and ECDSA keys. - Finally, on UNIX operating systems, it will create an executable -script `tinc-up', which will initially not do anything except warning -that you should edit it. +Finally, on UNIX operating systems, it will create an executable script +`tinc-up', which will initially not do anything except warning that you +should edit it. Step 2. Modifying the initial configuration. ............................................. @@ -1347,40 +1349,39 @@ will be part of a VPN which uses the address range 192.168.0.0/16, and you yourself have a smaller portion of that range: 192.168.2.0/24. Then you should run the following command: - tincctl -n NETNAME config add subnet 192.168.2.0/24 + tinc -n NETNAME add subnet 192.168.2.0/24 - This will add a Subnet statement to your host configuration file. -Try opening the file `/etc/tinc/NETNAME/hosts/NAME' in an editor. You +This will add a Subnet statement to your host configuration file. Try +opening the file `/etc/tinc/NETNAME/hosts/NAME' in an editor. You should now see a file containing the public RSA and ECDSA keys (which looks like a bunch of random characters), and the following line at the bottom: Subnet = 192.168.2.0/24 - If you will use more than one address range, you can add more -Subnets. For example, if you also use the IPv6 subnet fec0:0:0:2::/64, -you can add it as well: +If you will use more than one address range, you can add more Subnets. +For example, if you also use the IPv6 subnet fec0:0:0:2::/64, you can +add it as well: - tincctl -n NETNAME config add subnet fec0:0:0:2::/24 + tinc -n NETNAME add subnet fec0:0:0:2::/24 - This will add another line to the file `hosts/NAME'. If you make a -mistake, you can undo it by simply using `config del' instead of -`config add'. +This will add another line to the file `hosts/NAME'. If you make a +mistake, you can undo it by simply using `del' instead of `add'. - If you want other tinc daemons to create meta-connections to your +If you want other tinc daemons to create meta-connections to your daemon, you should add your public IP address or hostname to your host configuration file. For example, if your hostname is foo.example.org, run: - tincctl -n NETNAME config add address foo.example.org + tinc -n NETNAME add address foo.example.org - If you already know to which daemons your daemon should make +If you already know to which daemons your daemon should make meta-connections, you should configure that now as well. Suppose you want to connect to a daemon named "bar", run: - tincctl -n NETNAME config add connectto bar + tinc -n NETNAME add connectto bar - Note that you specify the Name of the other daemon here, not an IP +Note that you specify the Name of the other daemon here, not an IP address or hostname! When you start tinc, and it tries to make a connection to "bar", it will look for a host configuration file named `hosts/bar', and will read Address statements and public keys from that @@ -1397,29 +1398,29 @@ are on a UNIX platform, you can easily send an email containing the necessary information using the following command (assuming the owner of bar has the email address bar@example.org): - tincctl -n NETNAME export | mail -s "My config file" bar@example.org + tinc -n NETNAME export | mail -s "My config file" bar@example.org - If the owner of bar does the same to send his host configuration -file to you, you can probably pipe his email through the following -command, or you can just start this command in a terminal and -copy&paste the email: +If the owner of bar does the same to send his host configuration file +to you, you can probably pipe his email through the following command, +or you can just start this command in a terminal and copy&paste the +email: - tincctl -n NETNAME import + tinc -n NETNAME import - If you are the owner of bar yourself, and you have SSH access to -that computer, you can also swap the host configuration files using the +If you are the owner of bar yourself, and you have SSH access to that +computer, you can also swap the host configuration files using the following command: - tincctl -n NETNAME export \ - | ssh bar.example.org tincctl -n NETNAME exchange \ - | tincctl -n NETNAME import + tinc -n NETNAME export \ + | ssh bar.example.org tinc -n NETNAME exchange \ + | tinc -n NETNAME import - You should repeat this for all nodes you ConnectTo, or which -ConnectTo you. However, remember that you do not need to ConnectTo all -nodes in the VPN; it is only necessary to create one or a few -meta-connections, after the connections are made tinc will learn about -all the other nodes in the VPN, and will automatically make other -connections as necessary. +You should repeat this for all nodes you ConnectTo, or which ConnectTo +you. However, remember that you do not need to ConnectTo all nodes in +the VPN; it is only necessary to create one or a few meta-connections, +after the connections are made tinc will learn about all the other +nodes in the VPN, and will automatically make other connections as +necessary.  File: tinc.info, Node: Network interfaces, Next: Example configuration, Prev: Configuration files, Up: Configuration @@ -1430,34 +1431,33 @@ File: tinc.info, Node: Network interfaces, Next: Example configuration, Prev: Before tinc can start transmitting data over the tunnel, it must set up the virtual network interface. - First, decide which IP addresses you want to have associated with -these devices, and what network mask they must have. +First, decide which IP addresses you want to have associated with these +devices, and what network mask they must have. - Tinc will open a virtual network device (`/dev/tun', `/dev/tap0' or +Tinc will open a virtual network device (`/dev/tun', `/dev/tap0' or similar), which will also create a network interface called something like `tun0', `tap0'. If you are using the Linux tun/tap driver, the network interface will by default have the same name as the NETNAME. Under Windows you can change the name of the network interface from the Network Connections control panel. - You can configure the network interface by putting ordinary -ifconfig, route, and other commands to a script named -`/etc/tinc/NETNAME/tinc-up'. When tinc starts, this script will be -executed. When tinc exits, it will execute the script named -`/etc/tinc/NETNAME/tinc-down', but normally you don't need to create -that script. You can manually open the script in an editor, or use the -following command: +You can configure the network interface by putting ordinary ifconfig, +route, and other commands to a script named `/etc/tinc/NETNAME/tinc-up'. +When tinc starts, this script will be executed. When tinc exits, it +will execute the script named `/etc/tinc/NETNAME/tinc-down', but +normally you don't need to create that script. You can manually open +the script in an editor, or use the following command: - tincctl -n NETNAME edit tinc-up + tinc -n NETNAME edit tinc-up - An example `tinc-up' script, that would be appropriate for the -scenario in the previous section, is: +An example `tinc-up' script, that would be appropriate for the scenario +in the previous section, is: #!/bin/sh ifconfig $INTERFACE 192.168.2.1 netmask 255.255.0.0 ip addr add fec0:0:0:2::/48 dev $INTERFACE - The first command gives the interface an IPv4 address and a netmask. +The first command gives the interface an IPv4 address and a netmask. The kernel will also automatically add an IPv4 route to this interface, so normally you don't need to add route commands to the `tinc-up' script. The kernel will also bring the interface up after this command. The @@ -1468,7 +1468,7 @@ want to use "ip addr" commands on Linux, don't forget that it doesn't bring the interface up, unlike ifconfig, so you need to add `ip link set $INTERFACE up' in that case. - The exact syntax of the ifconfig and route commands differs from +The exact syntax of the ifconfig and route commands differs from platform to platform. You can look up the commands for setting addresses and adding routes in *note Platform specific information::, but it is best to consult the manpages of those utilities on your @@ -1484,36 +1484,36 @@ Imagine the following situation. Branch A of our example `company' wants to connect three branch offices in B, C and D using the Internet. All four offices have a 24/7 connection to the Internet. - A is going to serve as the center of the network. B and C will -connect to A, and D will connect to C. Each office will be assigned -their own IP network, 10.x.0.0. +A is going to serve as the center of the network. B and C will connect +to A, and D will connect to C. Each office will be assigned their own +IP network, 10.x.0.0. A: net 10.1.0.0 mask 255.255.0.0 gateway 10.1.54.1 internet IP 1.2.3.4 B: net 10.2.0.0 mask 255.255.0.0 gateway 10.2.1.12 internet IP 2.3.4.5 C: net 10.3.0.0 mask 255.255.0.0 gateway 10.3.69.254 internet IP 3.4.5.6 D: net 10.4.0.0 mask 255.255.0.0 gateway 10.4.3.32 internet IP 4.5.6.7 - Here, "gateway" is the VPN IP address of the machine that is running -the tincd, and "internet IP" is the IP address of the firewall, which -does not need to run tincd, but it must do a port forwarding of TCP and -UDP on port 655 (unless otherwise configured). +Here, "gateway" is the VPN IP address of the machine that is running the +tincd, and "internet IP" is the IP address of the firewall, which does +not need to run tincd, but it must do a port forwarding of TCP and UDP +on port 655 (unless otherwise configured). - In this example, it is assumed that eth0 is the interface that -points to the inner (physical) LAN of the office, although this could -also be the same as the interface that leads to the Internet. The -configuration of the real interface is also shown as a comment, to give -you an idea of how these example host is set up. All branches use the -netname `company' for this particular VPN. +In this example, it is assumed that eth0 is the interface that points to +the inner (physical) LAN of the office, although this could also be the +same as the interface that leads to the Internet. The configuration of +the real interface is also shown as a comment, to give you an idea of +how these example host is set up. All branches use the netname `company' +for this particular VPN. - Each branch is set up using the `tincctl init' and `tincctl config' -commands, here we just show the end results: +Each branch is set up using the `tinc init' and `tinc config' commands, +here we just show the end results: For Branch A ............ _BranchA_ would be configured like this: - In `/etc/tinc/company/tinc-up': +In `/etc/tinc/company/tinc-up': #!/bin/sh @@ -1522,11 +1522,11 @@ _BranchA_ would be configured like this: ifconfig $INTERFACE 10.1.54.1 netmask 255.0.0.0 - and in `/etc/tinc/company/tinc.conf': +and in `/etc/tinc/company/tinc.conf': Name = BranchA - On all hosts, `/etc/tinc/company/hosts/BranchA' contains: +On all hosts, `/etc/tinc/company/hosts/BranchA' contains: Subnet = 10.1.0.0/16 Address = 1.2.3.4 @@ -1535,10 +1535,10 @@ _BranchA_ would be configured like this: ... -----END RSA PUBLIC KEY----- - Note that the IP addresses of eth0 and the VPN interface 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 both -real internal network interfaces and VPN interfaces the same IP address, +Note that the IP addresses of eth0 and the VPN interface 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 both real +internal network interfaces and VPN interfaces the same IP address, since that will make things a lot easier to remember and set up. For Branch B @@ -1553,16 +1553,16 @@ In `/etc/tinc/company/tinc-up': ifconfig $INTERFACE 10.2.1.12 netmask 255.0.0.0 - and in `/etc/tinc/company/tinc.conf': +and in `/etc/tinc/company/tinc.conf': Name = BranchB ConnectTo = BranchA - Note here that the internal address (on eth0) doesn't have to be the +Note here that the internal address (on eth0) doesn't have to be the same as on the VPN interface. Also, ConnectTo is given so that this node will always try to connect to BranchA. - On all hosts, in `/etc/tinc/company/hosts/BranchB': +On all hosts, in `/etc/tinc/company/hosts/BranchB': Subnet = 10.2.0.0/16 Address = 2.3.4.5 @@ -1583,16 +1583,16 @@ In `/etc/tinc/company/tinc-up': ifconfig $INTERFACE 10.3.69.254 netmask 255.0.0.0 - and in `/etc/tinc/company/tinc.conf': +and in `/etc/tinc/company/tinc.conf': Name = BranchC ConnectTo = BranchA - C already has another daemon that runs on port 655, so they have to +C already has another daemon that runs on port 655, so they have to reserve another port for tinc. It knows the portnumber it has to listen on from it's own host configuration file. - On all hosts, in `/etc/tinc/company/hosts/BranchC': +On all hosts, in `/etc/tinc/company/hosts/BranchC': Address = 3.4.5.6 Subnet = 10.3.0.0/16 @@ -1614,16 +1614,15 @@ In `/etc/tinc/company/tinc-up': ifconfig $INTERFACE 10.4.3.32 netmask 255.0.0.0 - and in `/etc/tinc/company/tinc.conf': +and in `/etc/tinc/company/tinc.conf': Name = BranchD ConnectTo = BranchC - D will be connecting to C, which has a tincd running for this -network on port 2000. It knows the port number from the host -configuration file. +D will be connecting to C, which has a tincd running for this network on +port 2000. It knows the port number from the host configuration file. - On all hosts, in `/etc/tinc/company/hosts/BranchD': +On all hosts, in `/etc/tinc/company/hosts/BranchD': Subnet = 10.4.0.0/16 Address = 4.5.6.7 @@ -1637,10 +1636,10 @@ Key files A, B, C and D all have their own public/private keypairs: - The private RSA key is stored in `/etc/tinc/company/rsa_key.priv', -the private ECDSA key is stored in `/etc/tinc/company/ecdsa_key.priv', -and the public RSA and ECDSA keys are put into the host configuration -file in the `/etc/tinc/company/hosts/' directory. +The private RSA key is stored in `/etc/tinc/company/rsa_key.priv', the +private ECDSA key is stored in `/etc/tinc/company/ecdsa_key.priv', and +the public RSA and ECDSA keys are put into the host configuration file +in the `/etc/tinc/company/hosts/' directory. Starting ........ @@ -1660,9 +1659,9 @@ File: tinc.info, Node: Running tinc, Next: Controlling tinc, Prev: Configurat If everything else is done, you can start tinc by typing the following command: - tincctl -n NETNAME start + tinc -n NETNAME start - Tinc will detach from the terminal and continue to run in the +Tinc will detach from the terminal and continue to run in the background like a good daemon. If there are any problems however you can try to increase the debug level and look in the syslog to find out what the problems are. @@ -1704,8 +1703,8 @@ command line options. networks::. `--pidfile=FILENAME' - Store a cookie in FILENAME which allows tincctl to authenticate. - If unspecified, the default is `/var/run/tinc.NETNAME.pid'. + Store a cookie in FILENAME which allows tinc to authenticate. If + unspecified, the default is `/var/run/tinc.NETNAME.pid'. `-o, --option=[HOST.]KEY=VALUE' Without specifying a HOST, this will set server configuration @@ -1829,8 +1828,8 @@ directly see everything tinc logs: tincd -n NETNAME -d5 -D - If tinc does not log any error messages, then you might want to -check the following things: +If tinc does not log any error messages, then you might want to check +the following things: * `tinc-up' script Does this script contain the right commands? Normally you must give the interface the address of this host on @@ -1988,24 +1987,24 @@ File: tinc.info, Node: Controlling tinc, Next: Technical information, Prev: R 6 Controlling tinc ****************** -You can control and inspect a running tincd through the tincctl -command. A quick example: +You can control and inspect a running tincd through the tinc command. A +quick example: - tincctl -n NETNAME reload + tinc -n NETNAME reload * Menu: -* tincctl runtime options:: -* tincctl environment variables:: -* tincctl commands:: -* tincctl examples:: -* tincctl top:: +* tinc runtime options:: +* tinc environment variables:: +* tinc commands:: +* tinc examples:: +* tinc top::  -File: tinc.info, Node: tincctl runtime options, Next: tincctl environment variables, Up: Controlling tinc +File: tinc.info, Node: tinc runtime options, Next: tinc environment variables, Up: Controlling tinc -6.1 tincctl runtime options -=========================== +6.1 tinc runtime options +======================== `-c, --config=PATH' Read configuration options from the directory PATH. The default is @@ -2028,42 +2027,42 @@ File: tinc.info, Node: tincctl runtime options, Next: tincctl environment vari  -File: tinc.info, Node: tincctl environment variables, Next: tincctl commands, Prev: tincctl runtime options, Up: Controlling tinc +File: tinc.info, Node: tinc environment variables, Next: tinc commands, Prev: tinc runtime options, Up: Controlling tinc -6.2 tincctl environment variables -================================= +6.2 tinc environment variables +============================== `NETNAME' If no netname is specified on the command line with the `-n' option, the value of this environment variable is used.  -File: tinc.info, Node: tincctl commands, Next: tincctl examples, Prev: tincctl environment variables, Up: Controlling tinc +File: tinc.info, Node: tinc commands, Next: tinc examples, Prev: tinc environment variables, Up: Controlling tinc -6.3 tincctl commands -==================== +6.3 tinc commands +================= `init [NAME]' Create initial configuration files and RSA and ECDSA keypairs with default length. If no NAME for this node is given, it will be asked for. -`config [get] VARIABLE' +`get VARIABLE' Print the current value of configuration variable VARIABLE. If more than one variable with the same name exists, the value of each of them will be printed on a separate line. -`config [set] VARIABLE VALUE' +`set VARIABLE VALUE' Set configuration variable VARIABLE to the given VALUE. All previously existing configuration variables with the same name are removed. To set a variable for a specific host, use the notation HOST.VARIABLE. -`config add VARIABLE VALUE' +`add VARIABLE VALUE' As above, but without removing any previously existing configuration variables. -`config del VARIABLE [VALUE]' +`del VARIABLE [VALUE]' Remove configuration variables with the same name and VALUE. If no VALUE is given, all configuration variables with the same name will be removed. @@ -2080,7 +2079,7 @@ File: tinc.info, Node: tincctl commands, Next: tincctl examples, Prev: tincct Export all host configuration files to standard output. `import [--force]' - Import host configuration file(s) generated by the tincctl export + Import host configuration file(s) generated by the tinc export command from standard input. Already existing host configuration files are not overwritten unless the option -force is used. @@ -2146,7 +2145,7 @@ File: tinc.info, Node: tincctl commands, Next: tincctl examples, Prev: tincct `log [LEVEL]' Capture log messages from a running tinc daemon. An optional debug level can be given that will be applied only for log - messages sent to tincctl. + messages sent to tinc. `retry' Forces tinc to try to connect to all uplinks immediately. Usually @@ -2159,9 +2158,9 @@ File: tinc.info, Node: tincctl commands, Next: tincctl examples, Prev: tincct Closes the meta connection with the given NODE. `top' - If tincctl is compiled with libcurses support, this will display - live traffic statistics for all the known nodes, similar to the - UNIX top command. See below for more information. + If tinc is compiled with libcurses support, this will display live + traffic statistics for all the known nodes, similar to the UNIX + top command. See below for more information. `pcap' Dump VPN traffic going through the local tinc node in @@ -2171,30 +2170,30 @@ File: tinc.info, Node: tincctl commands, Next: tincctl examples, Prev: tincct  -File: tinc.info, Node: tincctl examples, Next: tincctl top, Prev: tincctl commands, Up: Controlling tinc +File: tinc.info, Node: tinc examples, Next: tinc top, Prev: tinc commands, Up: Controlling tinc -6.4 tincctl examples -==================== +6.4 tinc examples +================= Examples of some commands: - tincctl -n vpn dump graph | circo -Txlib - tincctl -n vpn pcap | tcpdump -r - - tincctl -n vpn top + tinc -n vpn dump graph | circo -Txlib + tinc -n vpn pcap | tcpdump -r - + tinc -n vpn top - Example of configuring tinc using tincctl: +Example of configuring tinc using the tinc command: - tincctl -n vpn init foo - tincctl -n vpn config Subnet 192.168.1.0/24 - tincctl -n vpn config bar.Address bar.example.com - tincctl -n vpn config ConnectTo bar - tincctl -n vpn export | gpg --clearsign | mail -s "My config" vpnmaster@example.com + tinc -n vpn init foo + tinc -n vpn add Subnet 192.168.1.0/24 + tinc -n vpn add bar.Address bar.example.com + tinc -n vpn add ConnectTo bar + tinc -n vpn export | gpg --clearsign | mail -s "My config" vpnmaster@example.com  -File: tinc.info, Node: tincctl top, Prev: tincctl examples, Up: Controlling tinc +File: tinc.info, Node: tinc top, Prev: tinc examples, Up: Controlling tinc -6.5 tincctl top -=============== +6.5 tinc top +============ The top command connects to a running tinc daemon and repeatedly queries its per-node traffic counters. It displays a list of all the @@ -2294,33 +2293,33 @@ are point-to-point devices which can only handle IPv4 and/or IPv6 packets, and `tap' style, which are Ethernet devices and handle complete Ethernet frames. - So when tinc reads an Ethernet frame from the device, it determines -its type. When tinc is in it's default routing mode, it can handle IPv4 -and IPv6 packets. Depending on the Subnet lines, it will send the -packets off to their destination IP address. In the `switch' and `hub' -mode, tinc will use broadcasts and MAC address discovery to deduce the +So when tinc reads an Ethernet frame from the device, it determines its +type. When tinc is in it's default routing mode, it can handle IPv4 and +IPv6 packets. Depending on the Subnet lines, it will send the packets +off to their destination IP address. In the `switch' and `hub' mode, +tinc will use broadcasts and MAC address discovery to deduce the destination of the packets. Since the latter modes only depend on the link layer information, any protocol that runs over Ethernet is supported (for instance IPX and Appletalk). However, only `tap' style devices provide this information. - After the destination has been determined, the packet will be +After the destination has been determined, the packet will be compressed (optionally), a sequence number will be added to the packet, the packet will then be encrypted and a message authentication code will be appended. - When that is done, time has come to actually transport the packet to +When that is done, time has come to actually transport the packet to the destination computer. We do this by sending the packet over an UDP connection to the destination host. This is called _encapsulating_, the VPN packet (though now encrypted) is encapsulated in another IP datagram. - When the destination receives this packet, the same thing happens, -only in reverse. So it checks the message authentication code, -decrypts the contents of the UDP datagram, checks the sequence number -and writes the decrypted information to its own virtual network device. +When the destination receives this packet, the same thing happens, only +in reverse. So it checks the message authentication code, decrypts the +contents of the UDP datagram, checks the sequence number and writes the +decrypted information to its own virtual network device. - If the virtual network device is a `tun' device (a point-to-point +If the virtual network device is a `tun' device (a point-to-point tunnel), there is no problem for the kernel to accept a packet. However, if it is a `tap' device (this is the only available type on FreeBSD), the destination MAC address must match that of the virtual @@ -2330,7 +2329,7 @@ sending host. Tinc solves this by letting the receiving end detect the MAC address of its own virtual network interface and overwriting the destination MAC address of the received packet. - In switch or hub modes ARP does work so the sender already knows the +In switch or hub modes ARP does work so the sender already knows the correct destination MAC address. In those modes every interface should have a unique MAC address, so make sure they are not the same. Because switch and hub modes rely on MAC addresses to function correctly, these @@ -2348,21 +2347,21 @@ Having only a UDP connection available is not enough. Though suitable for transmitting data, we want to be able to reliably send other information, such as routing and session key information to somebody. - TCP is a better alternative, because it already contains protection +TCP is a better alternative, because it already contains protection against information being lost, unlike UDP. - So we establish two connections. One for the encrypted VPN data, -and one for other information, the meta-data. Hence, we call the second +So we establish two connections. One for the encrypted VPN data, and +one for other information, the meta-data. Hence, we call the second connection the meta-connection. We can now be sure that the meta-information doesn't get lost on the way to another computer. - Like with any communication, we must have a protocol, so that -everybody knows what everything stands for, and how she should react. -Because we have two connections, we also have two protocols. The -protocol used for the UDP data is the "data-protocol," the other one is -the "meta-protocol." +Like with any communication, we must have a protocol, so that everybody +knows what everything stands for, and how she should react. Because we +have two connections, we also have two protocols. The protocol used for +the UDP data is the "data-protocol," the other one is the +"meta-protocol." - The reason we don't use TCP for both protocols is that UDP is much +The reason we don't use TCP for both protocols is that UDP is much better for encapsulation, even while it is less reliable. The real problem is that when TCP would be used to encapsulate a TCP stream that's on the private network, for every packet sent there would be @@ -2380,18 +2379,18 @@ The meta protocol is used to tie all tinc daemons together, and exchange information about which tinc daemon serves which virtual subnet. - The meta protocol consists of requests that can be sent to the other +The meta protocol consists of requests that can be sent to the other side. Each request has a unique number and several parameters. All requests are represented in the standard ASCII character set. It is possible to use tools such as telnet or netcat to connect to a tinc daemon started with the -bypass-security option and to read and write requests by hand, provided that one understands the numeric codes sent. - The authentication scheme is described in *note Authentication -protocol::. After a successful authentication, the server and the -client will exchange all the information about other tinc daemons and -subnets they know of, so that both sides (and all the other tinc -daemons behind them) have their information synchronised. +The authentication scheme is described in *note Security::. After a +successful authentication, the server and the client will exchange all +the information about other tinc daemons and subnets they know of, so +that both sides (and all the other tinc daemons behind them) have their +information synchronised. message ------------------------------------------------------------------ @@ -2409,13 +2408,13 @@ daemons behind them) have their information synchronised. +------------------> owner of this subnet ------------------------------------------------------------------ - The ADD_EDGE messages are to inform other tinc daemons that a +The ADD_EDGE messages are to inform other tinc daemons that a connection between two nodes exist. The address of the destination node is available so that VPN packets can be sent directly to that node. - The ADD_SUBNET messages inform other tinc daemons that certain -subnets belong to certain nodes. tinc will use it to determine to which -node a VPN packet has to be sent. +The ADD_SUBNET messages inform other tinc daemons that certain subnets +belong to certain nodes. tinc will use it to determine to which node a +VPN packet has to be sent. message ------------------------------------------------------------------ @@ -2429,10 +2428,10 @@ node a VPN packet has to be sent. +------------------> owner of this subnet ------------------------------------------------------------------ - In case a connection between two daemons is closed or broken, -DEL_EDGE messages are sent to inform the other daemons of that fact. -Each daemon will calculate a new route to the the daemons, or mark them -unreachable if there isn't any. +In case a connection between two daemons is closed or broken, DEL_EDGE +messages are sent to inform the other daemons of that fact. Each daemon +will calculate a new route to the the daemons, or mark them unreachable +if there isn't any. message ------------------------------------------------------------------ @@ -2452,20 +2451,20 @@ unreachable if there isn't any. +--> daemon that has changed it's packet key ------------------------------------------------------------------ - The keys used to encrypt VPN packets are not sent out directly. This -is because it would generate a lot of traffic on VPNs with many -daemons, and chances are that not every tinc daemon will ever send a -packet to every other daemon. Instead, if a daemon needs a key it sends -a request for it via the meta connection of the nearest hop in the -direction of the destination. +The keys used to encrypt VPN packets are not sent out directly. This is +because it would generate a lot of traffic on VPNs with many daemons, +and chances are that not every tinc daemon will ever send a packet to +every other daemon. Instead, if a daemon needs a key it sends a request +for it via the meta connection of the nearest hop in the direction of +the destination. - daemon message + daemon message ------------------------------------------------------------------ - origin PING - dest. PONG + origin PING + dest. PONG ------------------------------------------------------------------ - There is also a mechanism to check if hosts are still alive. Since +There is also a mechanism to check if hosts are still alive. Since network failures or a crash can cause a daemon to be killed without properly shutting down the TCP connection, this is necessary to keep an up to date connection list. PINGs are sent at regular intervals, except @@ -2474,7 +2473,7 @@ data) is added with each PING and PONG message, to make sure that long sequences of PING/PONG messages without any other traffic won't result in known plaintext. - This basically covers what is sent over the meta connection by tinc. +This basically covers what is sent over the meta connection by tinc.  File: tinc.info, Node: Security, Prev: The meta-protocol, Up: Technical information @@ -2487,32 +2486,34 @@ alleged Cabal was/is an organisation that was said to keep an eye on the entire Internet. As this is exactly what you _don't_ want, we named the tinc project after TINC. - But in order to be "immune" to eavesdropping, you'll have to encrypt -your data. Because tinc is a _Secure_ VPN (SVPN) daemon, it does -exactly that: encrypt. Tinc by default uses blowfish encryption with -128 bit keys in CBC mode, 32 bit sequence numbers and 4 byte long -message authentication codes to make sure eavesdroppers cannot get and -cannot change any information at all from the packets they can -intercept. The encryption algorithm and message authentication -algorithm can be changed in the configuration. The length of the message -authentication codes is also adjustable. The length of the key for the -encryption algorithm is always the default length used by OpenSSL. +But in order to be "immune" to eavesdropping, you'll have to encrypt +your data. Because tinc is a _Secure_ VPN (SVPN) daemon, it does +exactly that: encrypt. However, encryption in itself does not prevent +an attacker from modifying the encrypted data. Therefore, tinc also +authenticates the data. Finally, tinc uses sequence numbers (which +themselves are also authenticated) to prevent an attacker from +replaying valid packets. + +Since version 1.1pre3, tinc has two protocols used to protect your +data; the legacy protocol, and the new Simple Peer-to-Peer Security +(SPTPS) protocol. The SPTPS protocol is designed to address some +weaknesses in the legacy protocol. The new authentication protocol is +used when two nodes connect to each other that both have the +ExperimentalProtocol option set to yes, otherwise the legacy protocol +will be used. * Menu: -* Authentication protocol:: +* Legacy authentication protocol:: +* Simple Peer-to-Peer Security:: * Encryption of network packets:: * Security issues::  -File: tinc.info, Node: Authentication protocol, Next: Encryption of network packets, Up: Security +File: tinc.info, Node: Legacy authentication protocol, Next: Simple Peer-to-Peer Security, Up: Security -7.3.1 Authentication protocol ------------------------------ - -A new scheme for authentication in tinc has been devised, which offers -some improvements over the protocol used in 1.0pre2 and 1.0pre3. -Explanation is below. +7.3.1 Legacy authentication protocol +------------------------------------ daemon message -------------------------------------------------------------------------- @@ -2520,28 +2521,47 @@ Explanation is below. server - client ID client 12 - | +---> version - +-------> name of tinc daemon + client ID client 17.2 + | | +-> minor protocol version + | +----> major protocol version + +--------> name of tinc daemon - server ID server 12 - | +---> version - +-------> name of tinc daemon + server ID server 17.2 + | | +-> minor protocol version + | +----> major protocol version + +--------> name of tinc daemon - client META_KEY 5f0823a93e35b69e...7086ec7866ce582b - \_________________________________/ - +-> RSAKEYLEN bits totally random string S1, - encrypted with server's public RSA key + client META_KEY 94 64 0 0 5f0823a93e35b69e...7086ec7866ce582b + | | | | \_________________________________/ + | | | | +-> RSAKEYLEN bits totally random string S1, + | | | | encrypted with server's public RSA key + | | | +-> compression level + | | +---> MAC length + | +------> digest algorithm NID + +---------> cipher algorithm NID - server META_KEY 6ab9c1640388f8f0...45d1a07f8a672630 - \_________________________________/ - +-> RSAKEYLEN bits totally random string S2, - encrypted with client's public RSA key + server META_KEY 94 64 0 0 6ab9c1640388f8f0...45d1a07f8a672630 + | | | | \_________________________________/ + | | | | +-> RSAKEYLEN bits totally random string S2, + | | | | encrypted with client's public RSA key + | | | +-> compression level + | | +---> MAC length + | +------> digest algorithm NID + +---------> cipher algorithm NID + -------------------------------------------------------------------------- - From now on: - - the client will symmetrically encrypt outgoing traffic using S1 - - the server will symmetrically encrypt outgoing traffic using S2 +The protocol allows each side to specify encryption algorithms and +parameters, but in practice they are always fixed, since older versions +of tinc did not allow them to be different from the default values. The +cipher is always Blowfish in OFB mode, the digest is SHA1, but the MAC +length is zero and no compression is used. +From now on: + * the client will symmetrically encrypt outgoing traffic using S1 + + * the server will symmetrically encrypt outgoing traffic using S2 + + -------------------------------------------------------------------------- client CHALLENGE da02add1817c1920989ba6ae2a49cecbda0 \_________________________________/ +-> CHALLEN bits totally random string H1 @@ -2561,74 +2581,227 @@ Explanation is below. client ACK 655 123 0 | | +-> options - | +----> estimated weight - +--------> listening port of client + | +----> estimated weight + +--------> listening port of client server ACK 655 321 0 | | +-> options - | +----> estimated weight - +--------> listening port of server + | +----> estimated weight + +--------> listening port of server -------------------------------------------------------------------------- - This new scheme has several improvements, both in efficiency and -security. - - First of all, the server sends exactly the same kind of messages -over the wire as the client. The previous versions of tinc first -authenticated the client, and then the server. This scheme even allows -both sides to send their messages simultaneously, there is no need to -wait for the other to send something first. This means that any -calculations that need to be done upon sending or receiving a message -can also be done in parallel. This is especially important when doing -RSA encryption/decryption. Given that these calculations are the main -part of the CPU time spent for the authentication, speed is improved by -a factor 2. - - Second, only one RSA encrypted message is sent instead of two. This -reduces the amount of information attackers can see (and thus use for a -cryptographic attack). It also improves speed by a factor two, making -the total speedup a factor 4. - - Third, and most important: The symmetric cipher keys are exchanged -first, the challenge is done afterwards. In the previous authentication -scheme, because a man-in-the-middle could pass the challenge/chal_reply -phase (by just copying the messages between the two real tinc daemons), -but no information was exchanged that was really needed to read the -rest of the messages, the challenge/chal_reply phase was of no real -use. The man-in-the-middle was only stopped by the fact that only after -the ACK messages were encrypted with the symmetric cipher. Potentially, -it could even send it's own symmetric key to the server (if it knew the -server's public key) and read some of the metadata the server would -send it (it was impossible for the mitm to read actual network packets -though). The new scheme however prevents this. - - This new scheme makes sure that first of all, symmetric keys are -exchanged. The rest of the messages are then encrypted with the -symmetric cipher. Then, each side can only read received messages if -they have their private key. The challenge is there to let the other -side know that the private key is really known, because a challenge -reply can only be sent back if the challenge is decrypted correctly, -and that can only be done with knowledge of the private key. - - Fourth: the first thing that is sent via the symmetric cipher -encrypted connection is a totally random string, so that there is no -known plaintext (for an attacker) in the beginning of the encrypted -stream. +This legacy authentication protocol has several weaknesses, pointed out +by security export Peter Gutmann. First, data is encrypted with RSA +without padding. Padding schemes are designed to prevent attacks when +the size of the plaintext is not equal to the size of the RSA key. +Tinc always encrypts random nonces that have the same size as the RSA +key, so we do not believe this leads to a break of the security. There +might be timing or other side-channel attacks against RSA encryption +and decryption, tinc does not employ any protection against those. +Furthermore, both sides send identical messages to each other, there is +no distinction between server and client, which could make a MITM +attack easier. However, no exploit is known in which a third party who +is not already trusted by other nodes in the VPN could gain access. +Finally, the RSA keys are used to directly encrypt the session keys, +which means that if the RSA keys are compromised, it is possible to +decrypt all previous VPN traffic. In other words, the legacy protocol +does not provide perfect forward secrecy.  -File: tinc.info, Node: Encryption of network packets, Next: Security issues, Prev: Authentication protocol, Up: Security +File: tinc.info, Node: Simple Peer-to-Peer Security, Next: Encryption of network packets, Prev: Legacy authentication protocol, Up: Security -7.3.2 Encryption of network packets +7.3.2 Simple Peer-to-Peer Security +---------------------------------- + +The SPTPS protocol is designed to address the weaknesses in the legacy +protocol. SPTPS is based on TLS 1.2, but has been simplified: there is +no support for exchanging public keys, and there is no cipher suite +negotiation. Instead, SPTPS always uses a very strong cipher suite: +peers authenticate each other using 521 bits ECC keys, Diffie-Hellman +using ephemeral 521 bits ECC keys is used to provide perfect forward +secrecy (PFS), AES-256-CTR is used for encryption, and HMAC-SHA-256 for +message authentication. + +Similar to TLS, messages are split up in records. A complete logical +record contains the following information: + + * uint32_t seqno (network byte order) + + * uint16_t length (network byte order) + + * uint8_t type + + * opaque data[length] + + * opaque hmac[HMAC_SIZE] (HMAC over all preceding fields) + +Depending on whether SPTPS records are sent via TCP or UDP, either the +seqno or the length field is omitted on the wire (but they are still +included in the calculation of the HMAC); for TCP packets are +guaranteed to arrive in-order so we can infer the seqno, but packets +can be split or merged, so we still need the length field to determine +the boundaries between records; for UDP packets we know that there is +exactly one record per packet, and we know the length of a packet, but +packets can be dropped, duplicated and/or reordered, so we need to +include the seqno. + +The type field is used to distinguish between application records or +handshake records. Types 0 to 127 are application records, type 128 is +a handshake record, and types 129 to 255 are reserved. + +Before the initial handshake, no fields are encrypted, and the HMAC +field is not present. After the authentication handshake, the length +(if present), type and data fields are encrypted, and the HMAC field is +present. For UDP packets, the seqno field is not encrypted, as it is +used to determine the value of the counter used for encryption. + +The authentication consists of an exchange of Key EXchange, SIGnature +and ACKnowledge messages, transmitted using type 128 records. + +Overview: + + Initiator Responder + --------------------- + KEX -> + <- KEX + SIG -> + <- SIG + + ...encrypt and HMAC using session keys from now on... + + App -> + <- App + ... + ... + + ...key renegotiation starts here... + + KEX -> + <- KEX + SIG -> + <- SIG + ACK -> + <- ACK + + ...encrypt and HMAC using new session keys from now on... + + App -> + <- App + ... + ... + --------------------- + +Note that the responder does not need to wait before it receives the +first KEX message, it can immediately send its own once it has accepted +an incoming connection. + +Key EXchange message: + + * uint8_t kex_version (always 0 in this version of SPTPS) + + * opaque nonce[32] (random number) + + * opaque ecdh_key[ECDH_SIZE] + +SIGnature message: + + * opaque ecdsa_signature[ECDSA_SIZE] + +ACKnowledge message: + + * empty (only sent after key renegotiation) + +Remarks: + + * At the start, both peers generate a random nonce and an Elliptic + Curve public key and send it to the other in the KEX message. + + * After receiving the other's KEX message, both KEX messages are + concatenated (see below), and the result is signed using ECDSA. + The result is sent to the other. + + * After receiving the other's SIG message, the signature is verified. + If it is correct, the shared secret is calculated from the public + keys exchanged in the KEX message using the Elliptic Curve + Diffie-Helman algorithm. + + * The shared secret key is expanded using a PRF. Both nonces and + the application specific label are also used as input for the PRF. + + * An ACK message is sent only when doing key renegotiation, and is + sent using the old encryption keys. + + * The expanded key is used to key the encryption and HMAC algorithms. + +The signature is calculated over this string: + + * uint8_t initiator (0 = local peer, 1 = remote peer is initiator) + + * opaque remote_kex_message[1 + 32 + ECDH_SIZE] + + * opaque local_kex_message[1 + 32 + ECDH_SIZE] + + * opaque label[label_length] + +The PRF is calculated as follows: + + * A HMAC using SHA512 is used, the shared secret is used as the key. + + * For each block of 64 bytes, a HMAC is calculated. For block n: + hmac[n] = HMAC_SHA512(hmac[n - 1] + seed) + + * For the first block (n = 1), hmac[0] is given by + HMAC_SHA512(zeroes + seed), where zeroes is a block of 64 zero + bytes. + +The seed is as follows: + + * const char[13] "key expansion" + + * opaque responder_nonce[32] + + * opaque initiator_nonce[32] + + * opaque label[label_length] + +The expanded key is used as follows: + + * opaque responder_cipher_key[CIPHER_KEYSIZE] + + * opaque responder_digest_key[DIGEST_KEYSIZE] + + * opaque initiator_cipher_key[CIPHER_KEYSIZE] + + * opaque initiator_digest_key[DIGEST_KEYSIZE] + +Where initiator_cipher_key is the key used by session initiator to +encrypt messages sent to the responder. + +When using 521 bits EC keys, the AES-256-CTR cipher and HMAC-SHA-256 +digest algorithm, the sizes are as follows: + + ECDH_SIZE: 67 (= ceil(521/8) + 1) + ECDSA_SIZE: 141 (= 2 * ceil(521/8) + 9) + CIPHER_KEYSIZE: 48 (= 256/8 + 128/8) + DIGEST_KEYSIZE: 32 (= 256/8) + +Note that the cipher key also includes the initial value for the +counter. + + +File: tinc.info, Node: Encryption of network packets, Next: Security issues, Prev: Simple Peer-to-Peer Security, Up: Security + +7.3.3 Encryption of network packets ----------------------------------- A data packet can only be sent if the encryption key is known to both parties, and the connection is activated. If the encryption key is not known, a request is sent to the destination using the meta connection -to retrieve it. The packet is stored in a queue while waiting for the -key to arrive. +to retrieve it. - The UDP packet containing the network packet from the VPN has the -following layout: +The UDP packets can be either encrypted with the legacy protocol or +with SPTPS. In case of the legacy protocol, the UDP packet containing +the network packet from the VPN has the following layout: ... | IP header | UDP header | seqno | VPN packet | MAC | UDP trailer \___________________/\_____/ @@ -2636,18 +2809,38 @@ following layout: V +---> digest algorithm Encrypted with symmetric cipher - So, the entire VPN packet is encrypted using a symmetric cipher, +So, the entire VPN packet is encrypted using a symmetric cipher, including a 32 bits sequence number that is added in front of the actual VPN packet, to act as a unique IV for each packet and to prevent replay attacks. A message authentication code is added to the UDP -packet to prevent alteration of packets. By default the first 4 bytes -of the digest are used for this, but this can be changed using the -MACLength configuration variable. +packet to prevent alteration of packets. Tinc by default encrypts +network packets using Blowfish with 128 bit keys in CBC mode and uses 4 +byte long message authentication codes to make sure eavesdroppers +cannot get and cannot change any information at all from the packets +they can intercept. The encryption algorithm and message authentication +algorithm can be changed in the configuration. The length of the message +authentication codes is also adjustable. The length of the key for the +encryption algorithm is always the default length used by OpenSSL. + +The SPTPS protocol is described in *note Simple Peer-to-Peer Security::. +For comparison, this is how SPTPS UDP packets look: + + ... | IP header | UDP header | seqno | type | VPN packet | MAC | UDP trailer + \__________________/\_____/ + | | + V +---> digest algorithm + Encrypted with symmetric cipher + +The difference is that the seqno is not encrypted, since the encryption +cipher is used in CTR mode, and therefore the seqno must be known +before the packet can be decrypted. Furthermore, the MAC is never +truncated. The SPTPS protocol always uses the AES-256-CTR cipher and +HMAC-SHA-256 digest, this cannot be changed.  File: tinc.info, Node: Security issues, Prev: Encryption of network packets, Up: Security -7.3.3 Security issues +7.3.4 Security issues --------------------- In August 2000, we discovered the existence of a security hole in all @@ -2657,22 +2850,25 @@ authentication scheme to make tinc as secure as possible. The current version uses the OpenSSL library and uses strong authentication with RSA keys. - On the 29th of December 2001, Jerome Etienne posted a security -analysis of tinc 1.0pre4. Due to a lack of sequence numbers and a -message authentication code for each packet, an attacker could possibly -disrupt certain network services or launch a denial of service attack -by replaying intercepted packets. The current version adds sequence +On the 29th of December 2001, Jerome Etienne posted a security analysis +of tinc 1.0pre4. Due to a lack of sequence numbers and a message +authentication code for each packet, an attacker could possibly disrupt +certain network services or launch a denial of service attack by +replaying intercepted packets. The current version adds sequence numbers and message authentication codes to prevent such attacks. - On the 15th of September 2003, Peter Gutmann posted a security -analysis of tinc 1.0.1. He argues that the 32 bit sequence number used -by tinc is not a good IV, that tinc's default length of 4 bytes for the -MAC is too short, and he doesn't like tinc's use of RSA during -authentication. We do not know of a security hole in this version of -tinc, but tinc's security is not as strong as TLS or IPsec. We will -address these issues in tinc 2.0. +On the 15th of September 2003, Peter Gutmann posted a security analysis +of tinc 1.0.1. He argues that the 32 bit sequence number used by tinc +is not a good IV, that tinc's default length of 4 bytes for the MAC is +too short, and he doesn't like tinc's use of RSA during authentication. +We do not know of a security hole in the legacy protocol of tinc, but +it is not as strong as TLS or IPsec. - Cryptography is a hard thing to get right. We cannot make any +This version of tinc comes with an improved protocol, called Simple +Peer-to-Peer Security, which aims to be as strong as TLS with one of +the strongest cipher suites. + +Cryptography is a hard thing to get right. We cannot make any guarantees. Time, review and feedback are the only things that can prove the security of any cryptographic product. If you wish to review tinc or give us feedback, you are stronly encouraged to do so. @@ -2703,7 +2899,7 @@ to that interface. Because all packets for the entire VPN should go to the virtual network interface used by tinc, the netmask should be such that it encompasses the entire VPN. - For IPv4 addresses: +For IPv4 addresses: Linux `ifconfig' INTERFACE ADDRESS `netmask' NETMASK Linux iproute2 `ip addr add' ADDRESS`/'PREFIXLENGTH `dev' INTERFACE @@ -2714,7 +2910,7 @@ Solaris `ifconfig' INTERFACE ADDRESS `netmask' NETMASK Darwin (MacOS/X) `ifconfig' INTERFACE ADDRESS `netmask' NETMASK Windows `netsh interface ip set address' INTERFACE `static' ADDRESS NETMASK - For IPv6 addresses: +For IPv6 addresses: Linux `ifconfig' INTERFACE `add' ADDRESS`/'PREFIXLENGTH FreeBSD `ifconfig' INTERFACE `inet6' ADDRESS `prefixlen' PREFIXLENGTH @@ -2725,16 +2921,16 @@ Solaris `ifconfig' INTERFACE `inet6 plumb up' Darwin (MacOS/X) `ifconfig' INTERFACE `inet6' ADDRESS `prefixlen' PREFIXLENGTH Windows `netsh interface ipv6 add address' INTERFACE `static' ADDRESS/PREFIXLENGTH - On some platforms, when running tinc in switch mode, the VPN -interface must be set to tap mode with an ifconfig command: +On some platforms, when running tinc in switch mode, the VPN interface +must be set to tap mode with an ifconfig command: OpenBSD `ifconfig' INTERFACE `link0' - On Linux, it is possible to create a persistent tun/tap interface -which will continue to exist even if tinc quit, although this is -normally not required. It can be useful to set up a tun/tap interface -owned by a non-root user, so tinc can be started without needing any -root privileges at all. +On Linux, it is possible to create a persistent tun/tap interface which +will continue to exist even if tinc quit, although this is normally not +required. It can be useful to set up a tun/tap interface owned by a +non-root user, so tinc can be started without needing any root +privileges at all. Linux `ip tuntap add dev' INTERFACE `mode' TUN|TAP `user' USERNAME @@ -2751,7 +2947,7 @@ another way is to specify the (local) address that is assigned to that interface (LOCAL_ADDRESS). The former way is unambiguous and therefore preferable, but not all platforms support this. - Adding routes to IPv4 subnets: +Adding routes to IPv4 subnets: Linux `route add -net' NETWORK_ADDRESS `netmask' NETMASK INTERFACE Linux iproute2 `ip route add' NETWORK_ADDRESS`/'PREFIXLENGTH `dev' INTERFACE @@ -2763,7 +2959,7 @@ Darwin (MacOS/X) `route add' NETWORK_ADDRESS`/'PREFIXLENGTH LOCAL_ADDRESS Windows `netsh routing ip add persistentroute' NETWORK_ADDRESS NETMASK INTERFACE LOCAL_ADDRESS - Adding routes to IPv6 subnets: +Adding routes to IPv6 subnets: Linux `route add -A inet6' NETWORK_ADDRESS`/'PREFIXLENGTH INTERFACE Linux iproute2 `ip route add' NETWORK_ADDRESS`/'PREFIXLENGTH `dev' INTERFACE @@ -2794,8 +2990,8 @@ File: tinc.info, Node: Contact information, Next: Authors, Up: About us Tinc's website is at `http://www.tinc-vpn.org/', this server is located in the Netherlands. - We have an IRC channel on the FreeNode and OFTC IRC networks. -Connect to irc.freenode.net (http://www.freenode.net/) or irc.oftc.net +We have an IRC channel on the FreeNode and OFTC IRC networks. Connect to +irc.freenode.net (http://www.freenode.net/) or irc.oftc.net (http://www.oftc.net/) and join channel #tinc.  @@ -2808,10 +3004,10 @@ Ivo Timmermans (zarq) Guus Sliepen (guus) () - We have received a lot of valuable input from users. With their -help, tinc has become the flexible and robust tool that it is today. -We have composed a list of contributions, in the file called `THANKS' in -the source distribution. +We have received a lot of valuable input from users. With their help, +tinc has become the flexible and robust tool that it is today. We have +composed a list of contributions, in the file called `THANKS' in the +source distribution.  File: tinc.info, Node: Concept Index, Prev: About us, Up: Top @@ -2822,8 +3018,8 @@ Concept Index [index] * Menu: -* ACK: Authentication protocol. - (line 10) +* ACK: Legacy authentication protocol. + (line 6) * ADD_EDGE: The meta-protocol. (line 23) * ADD_SUBNET: The meta-protocol. (line 23) * Address: Host configuration variables. @@ -2831,8 +3027,6 @@ Concept Index * AddressFamily: Main configuration variables. (line 6) * ANS_KEY: The meta-protocol. (line 64) -* authentication: Authentication protocol. - (line 6) * AutoConnect: Main configuration variables. (line 12) * binary package: Building and installing tinc. @@ -2844,21 +3038,21 @@ Concept Index * Broadcast: Main configuration variables. (line 41) * Cabal: Security. (line 6) -* CHAL_REPLY: Authentication protocol. - (line 10) -* CHALLENGE: Authentication protocol. - (line 10) +* CHAL_REPLY: Legacy authentication protocol. + (line 6) +* CHALLENGE: Legacy authentication protocol. + (line 6) * CIDR notation: Host configuration variables. - (line 88) + (line 94) * Cipher: Host configuration variables. (line 12) * ClampMSS: Host configuration variables. - (line 18) + (line 20) * client: How connections work. (line 18) * command line: Runtime options. (line 9) * Compression: Host configuration variables. - (line 24) + (line 26) * connection: The connection. (line 6) * ConnectTo: Main configuration variables. (line 61) @@ -2877,7 +3071,7 @@ Concept Index * DeviceType: Main configuration variables. (line 88) * Digest: Host configuration variables. - (line 29) + (line 31) * DirectOnly: Main configuration variables. (line 153) * dummy: Main configuration variables. @@ -2903,10 +3097,10 @@ Concept Index (line 318) * hub: Main configuration variables. (line 245) -* ID: Authentication protocol. - (line 10) +* ID: Legacy authentication protocol. + (line 6) * IndirectData: Host configuration variables. - (line 34) + (line 38) * INTERFACE: Scripts. (line 58) * Interface: Main configuration variables. (line 204) @@ -2914,6 +3108,8 @@ Concept Index * KEY_CHANGED: The meta-protocol. (line 64) * KeyExpire: Main configuration variables. (line 250) +* legacy authentication protocol: Legacy authentication protocol. + (line 6) * libcurses: libcurses. (line 6) * libraries: Libraries. (line 6) * libreadline: libreadline. (line 6) @@ -2924,10 +3120,10 @@ Concept Index * MACExpire: Main configuration variables. (line 256) * MACLength: Host configuration variables. - (line 39) + (line 43) * meta-protocol: The meta-connection. (line 18) -* META_KEY: Authentication protocol. - (line 10) +* META_KEY: Legacy authentication protocol. + (line 6) * Mode: Main configuration variables. (line 223) * multicast: Main configuration variables. @@ -2936,8 +3132,8 @@ Concept Index * NAME: Scripts. (line 52) * Name: Main configuration variables. (line 261) -* netmask: Network interfaces. (line 39) -* NETNAME <1>: tincctl environment variables. +* netmask: Network interfaces. (line 38) +* NETNAME <1>: tinc environment variables. (line 6) * NETNAME: Scripts. (line 49) * netname: Multiple networks. (line 6) @@ -2947,7 +3143,7 @@ Concept Index * OpenSSL: OpenSSL. (line 6) * options: Runtime options. (line 9) * PEM format: Host configuration variables. - (line 64) + (line 70) * PING: The meta-protocol. (line 89) * PingInterval: Main configuration variables. (line 272) @@ -2955,12 +3151,12 @@ Concept Index (line 276) * platforms: Supported platforms. (line 6) * PMTU: Host configuration variables. - (line 44) + (line 50) * PMTUDiscovery: Host configuration variables. - (line 47) + (line 53) * PONG: The meta-protocol. (line 89) * Port: Host configuration variables. - (line 52) + (line 58) * port numbers: Other files. (line 17) * PriorityInheritance: Main configuration variables. (line 282) @@ -2975,9 +3171,9 @@ Concept Index * Proxy: Main configuration variables. (line 303) * PublicKey: Host configuration variables. - (line 56) + (line 62) * PublicKeyFile: Host configuration variables. - (line 59) + (line 65) * raw_socket: Main configuration variables. (line 100) * release: Supported platforms. (line 14) @@ -2999,17 +3195,19 @@ Concept Index (line 307) * socks5: Main configuration variables. (line 312) +* SPTPS: Simple Peer-to-Peer Security. + (line 6) * StrictSubnets: Main configuration variables. (line 337) * SUBNET: Scripts. (line 74) * Subnet: Host configuration variables. - (line 71) + (line 77) * SVPN: Security. (line 11) * switch: Main configuration variables. (line 234) * TCP: The meta-connection. (line 10) * TCPonly: Host configuration variables. - (line 100) + (line 106) * TINC: Security. (line 6) * tinc: Introduction. (line 6) * tinc-down: Scripts. (line 18) @@ -3024,7 +3222,7 @@ Concept Index * tunnohead: Main configuration variables. (line 136) * UDP <1>: Encryption of network packets. - (line 12) + (line 11) * UDP: The UDP tunnel. (line 30) * UDPRcvBuf: Main configuration variables. (line 349) @@ -3050,71 +3248,72 @@ Concept Index Tag Table: Node: Top811 Node: Introduction1131 -Node: Virtual Private Networks1941 -Node: tinc3667 -Node: Supported platforms5194 -Node: Preparations5893 -Node: Configuring the kernel6149 -Node: Configuration of Linux kernels6558 -Node: Configuration of FreeBSD kernels7413 -Node: Configuration of OpenBSD kernels7878 -Node: Configuration of NetBSD kernels8486 -Node: Configuration of Solaris kernels8891 -Node: Configuration of Darwin (MacOS/X) kernels9552 -Node: Configuration of Windows10241 -Node: Libraries10755 -Node: OpenSSL11173 -Node: zlib13461 -Node: lzo14487 -Node: libcurses15485 -Node: libreadline16405 -Node: Installation17353 -Node: Building and installing tinc18369 -Node: Darwin (MacOS/X) build environment19028 -Node: Cygwin (Windows) build environment19595 -Node: MinGW (Windows) build environment20183 -Node: System files20707 -Node: Device files20972 -Node: Other files21388 -Node: Configuration22001 -Node: Configuration introduction22288 -Node: Multiple networks23835 -Node: How connections work25215 -Node: Configuration files27788 -Node: Main configuration variables29321 -Node: Host configuration variables45735 -Node: Scripts50810 -Node: How to configure53489 -Node: Network interfaces58079 -Node: Example configuration60480 -Node: Running tinc65632 -Node: Runtime options66225 -Node: Signals69088 -Node: Debug levels69938 -Node: Solving problems70874 -Node: Error messages72304 -Node: Sending bug reports76626 -Node: Controlling tinc77578 -Node: tincctl runtime options77975 -Node: tincctl environment variables78674 -Node: tincctl commands79018 -Node: tincctl examples83503 -Node: tincctl top84108 -Node: Technical information85706 -Node: The connection85941 -Node: The UDP tunnel86253 -Node: The meta-connection89314 -Node: The meta-protocol90783 -Node: Security95792 -Node: Authentication protocol96922 -Node: Encryption of network packets101926 -Node: Security issues103299 -Node: Platform specific information104916 -Node: Interface configuration105144 -Node: Routes107597 -Node: About us109513 -Node: Contact information109688 -Node: Authors110092 -Node: Concept Index110497 +Node: Virtual Private Networks1935 +Node: tinc3650 +Node: Supported platforms5161 +Node: Preparations5857 +Node: Configuring the kernel6113 +Node: Configuration of Linux kernels6522 +Node: Configuration of FreeBSD kernels7371 +Node: Configuration of OpenBSD kernels7836 +Node: Configuration of NetBSD kernels8444 +Node: Configuration of Solaris kernels8846 +Node: Configuration of Darwin (MacOS/X) kernels9507 +Node: Configuration of Windows10196 +Node: Libraries10710 +Node: OpenSSL11128 +Node: zlib13401 +Node: lzo14418 +Node: libcurses15407 +Node: libreadline16315 +Node: Installation17251 +Node: Building and installing tinc18261 +Node: Darwin (MacOS/X) build environment18917 +Node: Cygwin (Windows) build environment19481 +Node: MinGW (Windows) build environment20066 +Node: System files20584 +Node: Device files20849 +Node: Other files21262 +Node: Configuration21875 +Node: Configuration introduction22162 +Node: Multiple networks23684 +Node: How connections work25052 +Node: Configuration files27613 +Node: Main configuration variables29140 +Node: Host configuration variables45548 +Node: Scripts51020 +Node: How to configure53696 +Node: Network interfaces58178 +Node: Example configuration60557 +Node: Running tinc65648 +Node: Runtime options66235 +Node: Signals69096 +Node: Debug levels69946 +Node: Solving problems70882 +Node: Error messages72309 +Node: Sending bug reports76631 +Node: Controlling tinc77583 +Node: tinc runtime options77959 +Node: tinc environment variables78646 +Node: tinc commands78975 +Node: tinc examples83404 +Node: tinc top83967 +Node: Technical information85553 +Node: The connection85788 +Node: The UDP tunnel86100 +Node: The meta-connection89143 +Node: The meta-protocol90601 +Node: Security95575 +Node: Legacy authentication protocol96911 +Node: Simple Peer-to-Peer Security101526 +Node: Encryption of network packets107223 +Node: Security issues109850 +Node: Platform specific information111576 +Node: Interface configuration111804 +Node: Routes114245 +Node: About us116155 +Node: Contact information116330 +Node: Authors116731 +Node: Concept Index117134  End Tag Table diff --git a/doc/tinc.texi b/doc/tinc.texi index 8910115..e1af55c 100644 --- a/doc/tinc.texi +++ b/doc/tinc.texi @@ -30,6 +30,10 @@ permission notice identical to this one. @end ifinfo +@afourpaper +@paragraphindent none +@finalout + @titlepage @title tinc Manual @subtitle Setting up a Virtual Private Network with tinc @@ -262,7 +266,7 @@ alias char-major-10-200 tun @subsection Configuration of FreeBSD kernels For FreeBSD version 4.1 and higher, tun and tap drivers are included in the default kernel configuration. -The tap driver can be loaded with @code{kldload if_tap}, or by adding @code{if_tap_load="YES"} to @file{/boot/loader.conf}. +The tap driver can be loaded with @code{kldload if_tap}, or by adding @code{if_tap_load="YES"} to @file{/boot/loader.conf}. @c ================================================================== @@ -462,7 +466,7 @@ default). @subsection libcurses @cindex libcurses -For the "tincctl top" command, tinc requires a curses library. +For the "tinc top" command, tinc requires a curses library. If this library is not installed, you wil get an error when running the configure script. You can either install a suitable curses library, or disable @@ -485,7 +489,7 @@ of this package. @subsection libreadline @cindex libreadline -For the "tincctl" command's shell functionality, tinc uses the readline library. +For the "tinc" command's shell functionality, tinc uses the readline library. If this library is not installed, you wil get an error when running the configure script. You can either install a suitable readline library, or @@ -696,12 +700,12 @@ If you have everything clearly pictured in your mind, proceed in the following order: First, create the initial configuration files and public/private keypairs using the following command: @example -tincctl -n @var{NETNAME} init @var{NAME} +tinc -n @var{NETNAME} init @var{NAME} @end example -Second, use @samp{tincctl -n @var{NETNAME} config ...} to further configure tinc. -Finally, export your host configuration file using @samp{tincctl -n @var{NETNAME} export} and send it to those +Second, use @samp{tinc -n @var{NETNAME} add ...} to further configure tinc. +Finally, export your host configuration file using @samp{tinc -n @var{NETNAME} export} and send it to those people or computers you want tinc to connect to. -They should send you their host configuration file back, which you can import using @samp{tincctl -n @var{NETNAME} import}. +They should send you their host configuration file back, which you can import using @samp{tinc -n @var{NETNAME} import}. These steps are described in the subsections below. @@ -721,7 +725,7 @@ it doesn't even have to be the same on all the nodes of your VPN, but it is recommended that you choose one anyway. We will asume you use a netname throughout this document. -This means that you call tincctl with the -n argument, +This means that you call tinc with the -n argument, which will specify the netname. The effect of this option is that tinc will set its configuration @@ -809,7 +813,7 @@ put host specific configuration options in the host configuration file, as this makes it easy to exchange with other nodes. You can edit the config file manually, but it is recommended that you use -tincctl to change configuration variables for you. +the tinc command to change configuration variables for you. In the following two subsections all valid variables are listed in alphabetical order. The default value is given between parentheses, @@ -1003,7 +1007,7 @@ When this option is enabled, experimental protocol enhancements will be used. Ephemeral ECDH will be used for key exchanges, and ECDSA will be used instead of RSA for authentication. When enabled, an ECDSA key must have been generated before with -@samp{tincctl generate-ecdsa-keys}. +@samp{tinc generate-ecdsa-keys}. The experimental protocol may change at any time, and there is no guarantee that tinc will run stable when it is used. @@ -1130,7 +1134,7 @@ accidental eavesdropping if you are editting the configuration file. @cindex PrivateKeyFile @item PrivateKeyFile = <@var{path}> (@file{@value{sysconfdir}/tinc/@var{netname}/rsa_key.priv}) This is the full path name of the RSA private key file that was -generated by @samp{tincctl generate-keys}. It must be a full path, not a +generated by @samp{tinc generate-keys}. It must be a full path, not a relative directory. @cindex ProcessPriority @@ -1217,10 +1221,11 @@ If no port is specified, the default Port is used. @cindex Cipher @item Cipher = <@var{cipher}> (blowfish) -The symmetric cipher algorithm used to encrypt UDP packets. +The symmetric cipher algorithm used to encrypt UDP packets using the legacy protocol. 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. +This option has no effect for connections using the SPTPS protocol, which always use AES-256-CTR. @cindex ClampMSS @item ClampMSS = (yes) @@ -1236,9 +1241,10 @@ Possible values are 0 (off), 1 (fast zlib) and any integer up to 9 (best zlib), @cindex Digest @item Digest = <@var{digest}> (sha1) -The digest algorithm used to authenticate UDP packets. +The digest algorithm used to authenticate UDP packets using the legacy protocol. Any digest supported by OpenSSL is recognized. Furthermore, specifying "none" will turn off packet authentication. +This option has no effect for connections using the SPTPS protocol, which always use HMAC-SHA-256. @cindex IndirectData @item IndirectData = (no) @@ -1248,9 +1254,10 @@ It is best to leave this option out or set it to no. @cindex MACLength @item MACLength = <@var{bytes}> (4) -The length of the message authentication code used to authenticate UDP packets. +The length of the message authentication code used to authenticate UDP packets using the legacy protocol. Can be anything from 0 up to the length of the digest produced by the digest algorithm. +This option has no effect for connections using the SPTPS protocol, which never truncate MACs. @cindex PMTU @item PMTU = <@var{mtu}> (1514) @@ -1273,7 +1280,7 @@ This is the RSA public key for this host. @cindex PublicKeyFile @item PublicKeyFile = <@var{path}> [obsolete] This is the full path name of the RSA public key file that was generated -by @samp{tincctl generate-keys}. It must be a full path, not a relative +by @samp{tinc generate-keys}. It must be a full path, not a relative directory. @cindex PEM format @@ -1421,7 +1428,7 @@ When a subnet becomes (un)reachable, this is set to the subnet. The initial directory structure, configuration files and public/private keypairs are created using the following command: @example -tincctl -n @var{netname} init @var{name} +tinc -n @var{netname} init @var{name} @end example (You will need to run this as root, or use "sudo".) @@ -1449,7 +1456,7 @@ and you yourself have a smaller portion of that range: 192.168.2.0/24. Then you should run the following command: @example -tincctl -n @var{netname} config add subnet 192.168.2.0/24 +tinc -n @var{netname} add subnet 192.168.2.0/24 @end example This will add a Subnet statement to your host configuration file. @@ -1465,18 +1472,18 @@ If you will use more than one address range, you can add more Subnets. For example, if you also use the IPv6 subnet fec0:0:0:2::/64, you can add it as well: @example -tincctl -n @var{netname} config add subnet fec0:0:0:2::/24 +tinc -n @var{netname} add subnet fec0:0:0:2::/24 @end example This will add another line to the file @file{hosts/@var{name}}. -If you make a mistake, you can undo it by simply using @samp{config del} instead of @samp{config add}. +If you make a mistake, you can undo it by simply using @samp{del} instead of @samp{add}. If you want other tinc daemons to create meta-connections to your daemon, you should add your public IP address or hostname to your host configuration file. For example, if your hostname is foo.example.org, run: @example -tincctl -n @var{netname} config add address foo.example.org +tinc -n @var{netname} add address foo.example.org @end example If you already know to which daemons your daemon should make meta-connections, @@ -1484,7 +1491,7 @@ you should configure that now as well. Suppose you want to connect to a daemon named "bar", run: @example -tincctl -n @var{netname} config add connectto bar +tinc -n @var{netname} add connectto bar @end example Note that you specify the Name of the other daemon here, not an IP address or hostname! @@ -1501,7 +1508,7 @@ If you are on a UNIX platform, you can easily send an email containing the neces (assuming the owner of bar has the email address bar@@example.org): @example -tincctl -n @var{netname} export | mail -s "My config file" bar@@example.org +tinc -n @var{netname} export | mail -s "My config file" bar@@example.org @end example If the owner of bar does the same to send his host configuration file to you, @@ -1509,16 +1516,16 @@ you can probably pipe his email through the following command, or you can just start this command in a terminal and copy&paste the email: @example -tincctl -n @var{netname} import +tinc -n @var{netname} import @end example If you are the owner of bar yourself, and you have SSH access to that computer, you can also swap the host configuration files using the following command: @example -tincctl -n @var{netname} export \ - | ssh bar.example.org tincctl -n @var{netname} exchange \ - | tincctl -n @var{netname} import +tinc -n @var{netname} export \ + | ssh bar.example.org tinc -n @var{netname} exchange \ + | tinc -n @var{netname} import @end example You should repeat this for all nodes you ConnectTo, or which ConnectTo you. @@ -1551,7 +1558,7 @@ When tinc starts, this script will be executed. When tinc exits, it will execute You can manually open the script in an editor, or use the following command: @example -tincctl -n @var{netname} edit tinc-up +tinc -n @var{netname} edit tinc-up @end example An example @file{tinc-up} script, that would be appropriate for the scenario in the previous section, is: @@ -1612,7 +1619,7 @@ the real interface is also shown as a comment, to give you an idea of how these example host is set up. All branches use the netname `company' for this particular VPN. -Each branch is set up using the @samp{tincctl init} and @samp{tincctl config} commands, +Each branch is set up using the @samp{tinc init} and @samp{tinc config} commands, here we just show the end results: @subsubheading For Branch A @@ -1783,7 +1790,7 @@ their daemons, tinc will try connecting until they are available. If everything else is done, you can start tinc by typing the following command: @example -tincctl -n @var{netname} start +tinc -n @var{netname} start @end example @cindex daemon @@ -1834,7 +1841,7 @@ Specifying . for @var{netname} is the same as not specifying any @var{netname}. @xref{Multiple networks}. @item --pidfile=@var{filename} -Store a cookie in @var{filename} which allows tincctl to authenticate. +Store a cookie in @var{filename} which allows tinc to authenticate. If unspecified, the default is @file{@value{localstatedir}/run/tinc.@var{netname}.pid}. @@ -2059,7 +2066,7 @@ Note that you will only see this message if you specified a debug level of 5 or higher! @item Chances are that a @samp{Subnet = ...} line in the host configuration file of this tinc daemon is wrong. Change it to a subnet that is accepted locally by another interface, -or if that is not the case, try changing the prefix length into /32. +or if that is not the case, try changing the prefix length into /32. @end itemize @item Node foo (1.2.3.4) is not reachable @@ -2108,25 +2115,25 @@ Be sure to include the following information in your bugreport: @node Controlling tinc @chapter Controlling tinc -You can control and inspect a running tincd through the tincctl +You can control and inspect a running tincd through the tinc command. A quick example: @example -tincctl -n @var{netname} reload +tinc -n @var{netname} reload @end example @menu -* tincctl runtime options:: -* tincctl environment variables:: -* tincctl commands:: -* tincctl examples:: -* tincctl top:: +* tinc runtime options:: +* tinc environment variables:: +* tinc commands:: +* tinc examples:: +* tinc top:: @end menu @c ================================================================== -@node tincctl runtime options -@section tincctl runtime options +@node tinc runtime options +@section tinc runtime options @c from the manpage @table @option @@ -2151,8 +2158,8 @@ Output version information and exit. @end table @c ================================================================== -@node tincctl environment variables -@section tincctl environment variables +@node tinc environment variables +@section tinc environment variables @table @env @cindex NETNAME @@ -2162,8 +2169,8 @@ the value of this environment variable is used. @end table @c ================================================================== -@node tincctl commands -@section tincctl commands +@node tinc commands +@section tinc commands @c from the manpage @table @code @@ -2172,20 +2179,20 @@ the value of this environment variable is used. Create initial configuration files and RSA and ECDSA keypairs with default length. If no @var{name} for this node is given, it will be asked for. -@item config [get] @var{variable} +@item get @var{variable} Print the current value of configuration variable @var{variable}. If more than one variable with the same name exists, the value of each of them will be printed on a separate line. -@item config [set] @var{variable} @var{value} +@item set @var{variable} @var{value} Set configuration variable @var{variable} to the given @var{value}. All previously existing configuration variables with the same name are removed. To set a variable for a specific host, use the notation @var{host}.@var{variable}. -@item config add @var{variable} @var{value} +@item add @var{variable} @var{value} As above, but without removing any previously existing configuration variables. -@item config del @var{variable} [@var{value}] +@item del @var{variable} [@var{value}] Remove configuration variables with the same name and @var{value}. If no @var{value} is given, all configuration variables with the same name will be removed. @@ -2200,7 +2207,7 @@ Export the host configuration file of the local node to standard output. Export all host configuration files to standard output. @item import [--force] -Import host configuration file(s) generated by the tincctl export command from standard input. +Import host configuration file(s) generated by the tinc export command from standard input. Already existing host configuration files are not overwritten unless the option --force is used. @item exchange [--force] @@ -2263,7 +2270,7 @@ Sets debug level to @var{level}. @item log [@var{level}] Capture log messages from a running tinc daemon. -An optional debug level can be given that will be applied only for log messages sent to tincctl. +An optional debug level can be given that will be applied only for log messages sent to tinc. @item retry Forces tinc to try to connect to all uplinks immediately. @@ -2276,7 +2283,7 @@ it defaults to the maximum time of 15 minutes. Closes the meta connection with the given @var{node}. @item top -If tincctl is compiled with libcurses support, this will display live traffic statistics for all the known nodes, +If tinc is compiled with libcurses support, this will display live traffic statistics for all the known nodes, similar to the UNIX top command. See below for more information. @@ -2288,30 +2295,30 @@ such as tcpdump. @end table @c ================================================================== -@node tincctl examples -@section tincctl examples +@node tinc examples +@section tinc examples Examples of some commands: @example -tincctl -n vpn dump graph | circo -Txlib -tincctl -n vpn pcap | tcpdump -r - -tincctl -n vpn top +tinc -n vpn dump graph | circo -Txlib +tinc -n vpn pcap | tcpdump -r - +tinc -n vpn top @end example -Example of configuring tinc using tincctl: +Example of configuring tinc using the tinc command: @example -tincctl -n vpn init foo -tincctl -n vpn config Subnet 192.168.1.0/24 -tincctl -n vpn config bar.Address bar.example.com -tincctl -n vpn config ConnectTo bar -tincctl -n vpn export | gpg --clearsign | mail -s "My config" vpnmaster@@example.com +tinc -n vpn init foo +tinc -n vpn add Subnet 192.168.1.0/24 +tinc -n vpn add bar.Address bar.example.com +tinc -n vpn add ConnectTo bar +tinc -n vpn export | gpg --clearsign | mail -s "My config" vpnmaster@@example.com @end example @c ================================================================== -@node tincctl top -@section tincctl top +@node tinc top +@section tinc top The top command connects to a running tinc daemon and repeatedly queries its per-node traffic counters. It displays a list of all the known nodes in the left-most column, @@ -2442,7 +2449,7 @@ If the virtual network device is a `tun' device (a point-to-point tunnel), there is no problem for the kernel to accept a packet. However, if it is a `tap' device (this is the only available type on FreeBSD), the destination MAC address must match that of the virtual network interface. -If tinc is in it's default routing mode, ARP does not work, so the correct destination MAC +If tinc is in it's default routing mode, ARP does not work, so the correct destination MAC can not be known by the sending host. Tinc solves this by letting the receiving end detect the MAC address of its own virtual network interface and overwriting the destination MAC address of the received packet. @@ -2504,7 +2511,7 @@ daemon started with the --bypass-security option and to read and write requests by hand, provided that one understands the numeric codes sent. -The authentication scheme is described in @ref{Authentication protocol}. After a +The authentication scheme is described in @ref{Security}. After a successful authentication, the server and the client will exchange all the information about other tinc daemons and subnets they know of, so that both sides (and all the other tinc daemons behind them) have their information @@ -2566,7 +2573,7 @@ message ------------------------------------------------------------------ REQ_KEY origin destination | +--> name of the tinc daemon it wants the key from - +----------> name of the daemon that wants the key + +----------> name of the daemon that wants the key ANS_KEY origin destination 4ae0b0a82d6e0078 91 64 4 | | \______________/ | | +--> MAC length @@ -2591,10 +2598,10 @@ destination. @cindex PING @cindex PONG @example -daemon message +daemon message ------------------------------------------------------------------ -origin PING -dest. PONG +origin PING +dest. PONG ------------------------------------------------------------------ @end example @@ -2622,31 +2629,30 @@ the tinc project after TINC. @cindex SVPN But in order to be ``immune'' to eavesdropping, you'll have to encrypt -your data. Because tinc is a @emph{Secure} VPN (SVPN) daemon, it does +your data. Because tinc is a @emph{Secure} VPN (SVPN) daemon, it does exactly that: encrypt. -Tinc by default uses blowfish encryption with 128 bit keys in CBC mode, 32 bit -sequence numbers and 4 byte long message authentication codes to make sure -eavesdroppers cannot get and cannot change any information at all from the -packets they can intercept. The encryption algorithm and message authentication -algorithm can be changed in the configuration. The length of the message -authentication codes is also adjustable. The length of the key for the -encryption algorithm is always the default length used by OpenSSL. +However, encryption in itself does not prevent an attacker from modifying the encrypted data. +Therefore, tinc also authenticates the data. +Finally, tinc uses sequence numbers (which themselves are also authenticated) to prevent an attacker from replaying valid packets. + +Since version 1.1pre3, tinc has two protocols used to protect your data; the legacy protocol, and the new Simple Peer-to-Peer Security (SPTPS) protocol. +The SPTPS protocol is designed to address some weaknesses in the legacy protocol. +The new authentication protocol is used when two nodes connect to each other that both have the ExperimentalProtocol option set to yes, +otherwise the legacy protocol will be used. @menu -* Authentication protocol:: +* Legacy authentication protocol:: +* Simple Peer-to-Peer Security:: * Encryption of network packets:: * Security issues:: @end menu @c ================================================================== -@node Authentication protocol -@subsection Authentication protocol +@node Legacy authentication protocol +@subsection Legacy authentication protocol -@cindex authentication -A new scheme for authentication in tinc has been devised, which offers some -improvements over the protocol used in 1.0pre2 and 1.0pre3. Explanation is -below. +@cindex legacy authentication protocol @cindex ID @cindex META_KEY @@ -2660,28 +2666,50 @@ client server -client ID client 12 - | +---> version - +-------> name of tinc daemon +client ID client 17.2 + | | +-> minor protocol version + | +----> major protocol version + +--------> name of tinc daemon -server ID server 12 - | +---> version - +-------> name of tinc daemon +server ID server 17.2 + | | +-> minor protocol version + | +----> major protocol version + +--------> name of tinc daemon -client META_KEY 5f0823a93e35b69e...7086ec7866ce582b - \_________________________________/ - +-> RSAKEYLEN bits totally random string S1, - encrypted with server's public RSA key +client META_KEY 94 64 0 0 5f0823a93e35b69e...7086ec7866ce582b + | | | | \_________________________________/ + | | | | +-> RSAKEYLEN bits totally random string S1, + | | | | encrypted with server's public RSA key + | | | +-> compression level + | | +---> MAC length + | +------> digest algorithm NID + +---------> cipher algorithm NID -server META_KEY 6ab9c1640388f8f0...45d1a07f8a672630 - \_________________________________/ - +-> RSAKEYLEN bits totally random string S2, - encrypted with client's public RSA key +server META_KEY 94 64 0 0 6ab9c1640388f8f0...45d1a07f8a672630 + | | | | \_________________________________/ + | | | | +-> RSAKEYLEN bits totally random string S2, + | | | | encrypted with client's public RSA key + | | | +-> compression level + | | +---> MAC length + | +------> digest algorithm NID + +---------> cipher algorithm NID +-------------------------------------------------------------------------- +@end example + +The protocol allows each side to specify encryption algorithms and parameters, +but in practice they are always fixed, since older versions of tinc did not +allow them to be different from the default values. The cipher is always +Blowfish in OFB mode, the digest is SHA1, but the MAC length is zero and no +compression is used. From now on: - - the client will symmetrically encrypt outgoing traffic using S1 - - the server will symmetrically encrypt outgoing traffic using S2 +@itemize +@item the client will symmetrically encrypt outgoing traffic using S1 +@item the server will symmetrically encrypt outgoing traffic using S2 +@end itemize +@example +-------------------------------------------------------------------------- client CHALLENGE da02add1817c1920989ba6ae2a49cecbda0 \_________________________________/ +-> CHALLEN bits totally random string H1 @@ -2701,57 +2729,188 @@ their identity. Further information is exchanged. client ACK 655 123 0 | | +-> options - | +----> estimated weight - +--------> listening port of client + | +----> estimated weight + +--------> listening port of client server ACK 655 321 0 | | +-> options - | +----> estimated weight - +--------> listening port of server + | +----> estimated weight + +--------> listening port of server -------------------------------------------------------------------------- @end example -This new scheme has several improvements, both in efficiency and security. +This legacy authentication protocol has several weaknesses, pointed out by security export Peter Gutmann. +First, data is encrypted with RSA without padding. +Padding schemes are designed to prevent attacks when the size of the plaintext is not equal to the size of the RSA key. +Tinc always encrypts random nonces that have the same size as the RSA key, so we do not believe this leads to a break of the security. +There might be timing or other side-channel attacks against RSA encryption and decryption, tinc does not employ any protection against those. +Furthermore, both sides send identical messages to each other, there is no distinction between server and client, +which could make a MITM attack easier. +However, no exploit is known in which a third party who is not already trusted by other nodes in the VPN could gain access. +Finally, the RSA keys are used to directly encrypt the session keys, which means that if the RSA keys are compromised, it is possible to decrypt all previous VPN traffic. +In other words, the legacy protocol does not provide perfect forward secrecy. -First of all, the server sends exactly the same kind of messages over the wire -as the client. The previous versions of tinc first authenticated the client, -and then the server. This scheme even allows both sides to send their messages -simultaneously, there is no need to wait for the other to send something first. -This means that any calculations that need to be done upon sending or receiving -a message can also be done in parallel. This is especially important when doing -RSA encryption/decryption. Given that these calculations are the main part of -the CPU time spent for the authentication, speed is improved by a factor 2. +@c ================================================================== +@node Simple Peer-to-Peer Security +@subsection Simple Peer-to-Peer Security +@cindex SPTPS -Second, only one RSA encrypted message is sent instead of two. This reduces the -amount of information attackers can see (and thus use for a cryptographic -attack). It also improves speed by a factor two, making the total speedup a -factor 4. +The SPTPS protocol is designed to address the weaknesses in the legacy protocol. +SPTPS is based on TLS 1.2, but has been simplified: there is no support for exchanging public keys, and there is no cipher suite negotiation. +Instead, SPTPS always uses a very strong cipher suite: +peers authenticate each other using 521 bits ECC keys, +Diffie-Hellman using ephemeral 521 bits ECC keys is used to provide perfect forward secrecy (PFS), +AES-256-CTR is used for encryption, and HMAC-SHA-256 for message authentication. -Third, and most important: -The symmetric cipher keys are exchanged first, the challenge is done -afterwards. In the previous authentication scheme, because a man-in-the-middle -could pass the challenge/chal_reply phase (by just copying the messages between -the two real tinc daemons), but no information was exchanged that was really -needed to read the rest of the messages, the challenge/chal_reply phase was of -no real use. The man-in-the-middle was only stopped by the fact that only after -the ACK messages were encrypted with the symmetric cipher. Potentially, it -could even send it's own symmetric key to the server (if it knew the server's -public key) and read some of the metadata the server would send it (it was -impossible for the mitm to read actual network packets though). The new scheme -however prevents this. +Similar to TLS, messages are split up in records. +A complete logical record contains the following information: -This new scheme makes sure that first of all, symmetric keys are exchanged. The -rest of the messages are then encrypted with the symmetric cipher. Then, each -side can only read received messages if they have their private key. The -challenge is there to let the other side know that the private key is really -known, because a challenge reply can only be sent back if the challenge is -decrypted correctly, and that can only be done with knowledge of the private -key. +@itemize +@item uint32_t seqno (network byte order) +@item uint16_t length (network byte order) +@item uint8_t type +@item opaque data[length] +@item opaque hmac[HMAC_SIZE] (HMAC over all preceding fields) +@end itemize -Fourth: the first thing that is sent via the symmetric cipher encrypted -connection is a totally random string, so that there is no known plaintext (for -an attacker) in the beginning of the encrypted stream. +Depending on whether SPTPS records are sent via TCP or UDP, either the seqno or the length field is omitted on the wire +(but they are still included in the calculation of the HMAC); +for TCP packets are guaranteed to arrive in-order so we can infer the seqno, but packets can be split or merged, so we still need the length field to determine the boundaries between records; +for UDP packets we know that there is exactly one record per packet, and we know the length of a packet, but packets can be dropped, duplicated and/or reordered, so we need to include the seqno. +The type field is used to distinguish between application records or handshake records. +Types 0 to 127 are application records, type 128 is a handshake record, and types 129 to 255 are reserved. + +Before the initial handshake, no fields are encrypted, and the HMAC field is not present. +After the authentication handshake, the length (if present), type and data fields are encrypted, and the HMAC field is present. +For UDP packets, the seqno field is not encrypted, as it is used to determine the value of the counter used for encryption. + +The authentication consists of an exchange of Key EXchange, SIGnature and ACKnowledge messages, transmitted using type 128 records. + +Overview: + +@example +Initiator Responder +--------------------- +KEX -> + <- KEX +SIG -> + <- SIG + +...encrypt and HMAC using session keys from now on... + +App -> + <- App +... + ... + +...key renegotiation starts here... + +KEX -> + <- KEX +SIG -> + <- SIG +ACK -> + <- ACK + +...encrypt and HMAC using new session keys from now on... + +App -> + <- App +... + ... +--------------------- +@end example + +Note that the responder does not need to wait before it receives the first KEX message, +it can immediately send its own once it has accepted an incoming connection. + +Key EXchange message: + +@itemize +@item uint8_t kex_version (always 0 in this version of SPTPS) +@item opaque nonce[32] (random number) +@item opaque ecdh_key[ECDH_SIZE] +@end itemize + +SIGnature message: + +@itemize +@item opaque ecdsa_signature[ECDSA_SIZE] +@end itemize + +ACKnowledge message: + +@itemize +@item empty (only sent after key renegotiation) +@end itemize + +Remarks: + +@itemize +@item At the start, both peers generate a random nonce and an Elliptic Curve public key and send it to the other in the KEX message. +@item After receiving the other's KEX message, both KEX messages are concatenated (see below), + and the result is signed using ECDSA. + The result is sent to the other. +@item After receiving the other's SIG message, the signature is verified. + If it is correct, the shared secret is calculated from the public keys exchanged in the KEX message using the Elliptic Curve Diffie-Helman algorithm. +@item The shared secret key is expanded using a PRF. + Both nonces and the application specific label are also used as input for the PRF. +@item An ACK message is sent only when doing key renegotiation, and is sent using the old encryption keys. +@item The expanded key is used to key the encryption and HMAC algorithms. +@end itemize + +The signature is calculated over this string: + +@itemize +@item uint8_t initiator (0 = local peer, 1 = remote peer is initiator) +@item opaque remote_kex_message[1 + 32 + ECDH_SIZE] +@item opaque local_kex_message[1 + 32 + ECDH_SIZE] +@item opaque label[label_length] +@end itemize + +The PRF is calculated as follows: + +@itemize +@item A HMAC using SHA512 is used, the shared secret is used as the key. +@item For each block of 64 bytes, a HMAC is calculated. For block n: hmac[n] = + HMAC_SHA512(hmac[n - 1] + seed) +@item For the first block (n = 1), hmac[0] is given by HMAC_SHA512(zeroes + seed), + where zeroes is a block of 64 zero bytes. +@end itemize + +The seed is as follows: + +@itemize +@item const char[13] "key expansion" +@item opaque responder_nonce[32] +@item opaque initiator_nonce[32] +@item opaque label[label_length] +@end itemize + +The expanded key is used as follows: + +@itemize +@item opaque responder_cipher_key[CIPHER_KEYSIZE] +@item opaque responder_digest_key[DIGEST_KEYSIZE] +@item opaque initiator_cipher_key[CIPHER_KEYSIZE] +@item opaque initiator_digest_key[DIGEST_KEYSIZE] +@end itemize + +Where initiator_cipher_key is the key used by session initiator to encrypt +messages sent to the responder. + +When using 521 bits EC keys, the AES-256-CTR cipher and HMAC-SHA-256 digest algorithm, +the sizes are as follows: + +@example +ECDH_SIZE: 67 (= ceil(521/8) + 1) +ECDSA_SIZE: 141 (= 2 * ceil(521/8) + 9) +CIPHER_KEYSIZE: 48 (= 256/8 + 128/8) +DIGEST_KEYSIZE: 32 (= 256/8) +@end example + +Note that the cipher key also includes the initial value for the counter. @c ================================================================== @node Encryption of network packets @@ -2761,11 +2920,11 @@ an attacker) in the beginning of the encrypted stream. A data packet can only be sent if the encryption key is known to both parties, and the connection is activated. If the encryption key is not known, a request is sent to the destination using the meta connection -to retrieve it. The packet is stored in a queue while waiting for the -key to arrive. +to retrieve it. @cindex UDP -The UDP packet containing the network packet from the VPN has the following layout: +The UDP packets can be either encrypted with the legacy protocol or with SPTPS. +In case of the legacy protocol, the UDP packet containing the network packet from the VPN has the following layout: @example ... | IP header | UDP header | seqno | VPN packet | MAC | UDP trailer @@ -2775,12 +2934,38 @@ The UDP packet containing the network packet from the VPN has the following layo Encrypted with symmetric cipher @end example + + + So, the entire VPN packet is encrypted using a symmetric cipher, including a 32 bits sequence number that is added in front of the actual VPN packet, to act as a unique IV for each packet and to prevent replay attacks. A message authentication code -is added to the UDP packet to prevent alteration of packets. By default the -first 4 bytes of the digest are used for this, but this can be changed using -the MACLength configuration variable. +is added to the UDP packet to prevent alteration of packets. +Tinc by default encrypts network packets using Blowfish with 128 bit keys in CBC mode +and uses 4 byte long message authentication codes to make sure +eavesdroppers cannot get and cannot change any information at all from the +packets they can intercept. The encryption algorithm and message authentication +algorithm can be changed in the configuration. The length of the message +authentication codes is also adjustable. The length of the key for the +encryption algorithm is always the default length used by OpenSSL. + +The SPTPS protocol is described in @ref{Simple Peer-to-Peer Security}. +For comparison, this is how SPTPS UDP packets look: + +@example +... | IP header | UDP header | seqno | type | VPN packet | MAC | UDP trailer + \__________________/\_____/ + | | + V +---> digest algorithm + Encrypted with symmetric cipher +@end example + +The difference is that the seqno is not encrypted, since the encryption cipher is used in CTR mode, +and therefore the seqno must be known before the packet can be decrypted. +Furthermore, the MAC is never truncated. +The SPTPS protocol always uses the AES-256-CTR cipher and HMAC-SHA-256 digest, +this cannot be changed. + @c ================================================================== @node Security issues @@ -2803,8 +2988,10 @@ On the 15th of September 2003, Peter Gutmann posted a security analysis of tinc 1.0.1. He argues that the 32 bit sequence number used by tinc is not a good IV, that tinc's default length of 4 bytes for the MAC is too short, and he doesn't like tinc's use of RSA during authentication. We do not know of a security hole -in this version of tinc, but tinc's security is not as strong as TLS or IPsec. -We will address these issues in tinc 2.0. +in the legacy protocol of tinc, but it is not as strong as TLS or IPsec. + +This version of tinc comes with an improved protocol, called Simple Peer-to-Peer Security, +which aims to be as strong as TLS with one of the strongest cipher suites. Cryptography is a hard thing to get right. We cannot make any guarantees. Time, review and feedback are the only things that can diff --git a/doc/tincd.8.in b/doc/tincd.8.in index 88da75d..3c5886b 100644 --- a/doc/tincd.8.in +++ b/doc/tincd.8.in @@ -92,7 +92,7 @@ is omitted, the default is Store a cookie in .Ar FILENAME which allows -.Xr tincctl 8 +.Xr tinc 8 to authenticate. If .Ar FILE @@ -186,7 +186,7 @@ If you find any bugs, report them to tinc@tinc-vpn.org. .Sh TODO A lot, especially security auditing. .Sh SEE ALSO -.Xr tincctl 8 , +.Xr tinc 8 , .Xr tinc.conf 5 , .Pa http://www.tinc-vpn.org/ , .Pa http://www.cabal.org/ . diff --git a/src/Makefile.am b/src/Makefile.am index eeee152..c073eec 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,6 +1,6 @@ ## Produce this file with automake to get Makefile.in -sbin_PROGRAMS = tincd tincctl sptps_test +sbin_PROGRAMS = tincd tinc sptps_test EXTRA_DIST = linux bsd solaris cygwin mingw openssl gcrypt @@ -22,11 +22,11 @@ endif nodist_tincd_SOURCES = \ device.c cipher.c crypto.c ecdh.c ecdsa.c digest.c prf.c rsa.c -tincctl_SOURCES = \ +tinc_SOURCES = \ utils.c getopt.c getopt1.c dropin.c \ info.c list.c subnet_parse.c tincctl.c top.c names.c -nodist_tincctl_SOURCES = \ +nodist_tinc_SOURCES = \ ecdsagen.c rsagen.c sptps_test_SOURCES = \ @@ -37,7 +37,7 @@ if TUNEMU tincd_SOURCES += bsd/tunemu.c endif -tincctl_LDADD = $(READLINE_LIBS) $(CURSES_LIBS) +tinc_LDADD = $(READLINE_LIBS) $(CURSES_LIBS) DEFAULT_INCLUDES = diff --git a/src/Makefile.in b/src/Makefile.in index b1d4551..48f7dad 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -52,7 +52,7 @@ PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ -sbin_PROGRAMS = tincd$(EXEEXT) tincctl$(EXEEXT) sptps_test$(EXEEXT) +sbin_PROGRAMS = tincd$(EXEEXT) tinc$(EXEEXT) sptps_test$(EXEEXT) @UML_TRUE@am__append_1 = uml_device.c @VDE_TRUE@am__append_2 = vde_device.c @TUNEMU_TRUE@am__append_3 = bsd/tunemu.c @@ -79,14 +79,14 @@ am_sptps_test_OBJECTS = logger.$(OBJEXT) cipher.$(OBJEXT) \ sptps_test.$(OBJEXT) utils.$(OBJEXT) sptps_test_OBJECTS = $(am_sptps_test_OBJECTS) sptps_test_LDADD = $(LDADD) -am_tincctl_OBJECTS = utils.$(OBJEXT) getopt.$(OBJEXT) \ - getopt1.$(OBJEXT) dropin.$(OBJEXT) info.$(OBJEXT) \ - list.$(OBJEXT) subnet_parse.$(OBJEXT) tincctl.$(OBJEXT) \ - top.$(OBJEXT) names.$(OBJEXT) -nodist_tincctl_OBJECTS = ecdsagen.$(OBJEXT) rsagen.$(OBJEXT) -tincctl_OBJECTS = $(am_tincctl_OBJECTS) $(nodist_tincctl_OBJECTS) +am_tinc_OBJECTS = utils.$(OBJEXT) getopt.$(OBJEXT) getopt1.$(OBJEXT) \ + dropin.$(OBJEXT) info.$(OBJEXT) list.$(OBJEXT) \ + subnet_parse.$(OBJEXT) tincctl.$(OBJEXT) top.$(OBJEXT) \ + names.$(OBJEXT) +nodist_tinc_OBJECTS = ecdsagen.$(OBJEXT) rsagen.$(OBJEXT) +tinc_OBJECTS = $(am_tinc_OBJECTS) $(nodist_tinc_OBJECTS) am__DEPENDENCIES_1 = -tincctl_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) +tinc_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) am__tincd_SOURCES_DIST = utils.c getopt.c getopt1.c list.c \ splay_tree.c dropin.c fake-getaddrinfo.c fake-getnameinfo.c \ hash.c buffer.c conf.c connection.c control.c edge.c graph.c \ @@ -128,10 +128,9 @@ COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ -SOURCES = $(sptps_test_SOURCES) $(tincctl_SOURCES) \ - $(nodist_tincctl_SOURCES) $(tincd_SOURCES) \ - $(nodist_tincd_SOURCES) -DIST_SOURCES = $(sptps_test_SOURCES) $(tincctl_SOURCES) \ +SOURCES = $(sptps_test_SOURCES) $(tinc_SOURCES) $(nodist_tinc_SOURCES) \ + $(tincd_SOURCES) $(nodist_tincd_SOURCES) +DIST_SOURCES = $(sptps_test_SOURCES) $(tinc_SOURCES) \ $(am__tincd_SOURCES_DIST) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ @@ -258,18 +257,18 @@ tincd_SOURCES = utils.c getopt.c getopt1.c list.c splay_tree.c \ nodist_tincd_SOURCES = \ device.c cipher.c crypto.c ecdh.c ecdsa.c digest.c prf.c rsa.c -tincctl_SOURCES = \ +tinc_SOURCES = \ utils.c getopt.c getopt1.c dropin.c \ info.c list.c subnet_parse.c tincctl.c top.c names.c -nodist_tincctl_SOURCES = \ +nodist_tinc_SOURCES = \ ecdsagen.c rsagen.c sptps_test_SOURCES = \ logger.c cipher.c crypto.c ecdh.c ecdsa.c digest.c prf.c \ sptps.c sptps_test.c utils.c -tincctl_LDADD = $(READLINE_LIBS) $(CURSES_LIBS) +tinc_LDADD = $(READLINE_LIBS) $(CURSES_LIBS) DEFAULT_INCLUDES = noinst_HEADERS = \ xalloc.h utils.h getopt.h list.h splay_tree.h dropin.h fake-getaddrinfo.h fake-getnameinfo.h fake-gai-errnos.h ipv6.h ipv4.h ethernet.h \ @@ -357,9 +356,9 @@ clean-sbinPROGRAMS: sptps_test$(EXEEXT): $(sptps_test_OBJECTS) $(sptps_test_DEPENDENCIES) $(EXTRA_sptps_test_DEPENDENCIES) @rm -f sptps_test$(EXEEXT) $(LINK) $(sptps_test_OBJECTS) $(sptps_test_LDADD) $(LIBS) -tincctl$(EXEEXT): $(tincctl_OBJECTS) $(tincctl_DEPENDENCIES) $(EXTRA_tincctl_DEPENDENCIES) - @rm -f tincctl$(EXEEXT) - $(LINK) $(tincctl_OBJECTS) $(tincctl_LDADD) $(LIBS) +tinc$(EXEEXT): $(tinc_OBJECTS) $(tinc_DEPENDENCIES) $(EXTRA_tinc_DEPENDENCIES) + @rm -f tinc$(EXEEXT) + $(LINK) $(tinc_OBJECTS) $(tinc_LDADD) $(LIBS) tincd$(EXEEXT): $(tincd_OBJECTS) $(tincd_DEPENDENCIES) $(EXTRA_tincd_DEPENDENCIES) @rm -f tincd$(EXEEXT) $(LINK) $(tincd_OBJECTS) $(tincd_LDADD) $(LIBS) diff --git a/src/event.c b/src/event.c index 6b730f6..095e7c3 100644 --- a/src/event.c +++ b/src/event.c @@ -245,6 +245,12 @@ bool event_loop(void) { return true; } +void event_flush_output(void) { + for splay_each(io_t, io, &io_tree) + if(FD_ISSET(io->fd, &writefds)) + io->cb(io->data, IO_WRITE); +} + void event_exit(void) { running = false; } diff --git a/src/event.h b/src/event.h index d0129d0..bd91b7b 100644 --- a/src/event.h +++ b/src/event.h @@ -65,6 +65,7 @@ extern void signal_add(signal_t *sig, signal_cb_t cb, void *data, int signum); extern void signal_del(signal_t *sig); extern bool event_loop(void); +extern void event_flush_output(void); extern void event_exit(void); #endif diff --git a/src/graph.c b/src/graph.c index 7079f93..4506379 100644 --- a/src/graph.c +++ b/src/graph.c @@ -204,7 +204,7 @@ static void check_reachability(void) { for splay_each(node_t, n, node_tree) { if(n->status.visited != n->status.reachable) { n->status.reachable = !n->status.reachable; - n->last_state_change = time(NULL); + n->last_state_change = now.tv_sec; if(n->status.reachable) { logger(DEBUG_TRAFFIC, LOG_DEBUG, "Node %s (%s) became reachable", diff --git a/src/mingw/device.c b/src/mingw/device.c index aa05972..ac83d8c 100644 --- a/src/mingw/device.c +++ b/src/mingw/device.c @@ -80,6 +80,7 @@ static DWORD WINAPI tapreader(void *bla) { packet.len = len; packet.priority = 0; route(myself, &packet); + event_flush_output(); LeaveCriticalSection(&mutex); } } diff --git a/src/net.c b/src/net.c index 0d374e6..1487e81 100644 --- a/src/net.c +++ b/src/net.c @@ -406,7 +406,7 @@ int reload_configuration(void) { free(fname); } - last_config_check = time(NULL); + last_config_check = now.tv_sec; return 0; } diff --git a/src/net.h b/src/net.h index 8d236da..879dfff 100644 --- a/src/net.h +++ b/src/net.h @@ -135,6 +135,7 @@ extern int udp_sndbuf; extern bool do_prune; extern char *myport; extern int autoconnect; +extern bool disablebuggypeers; extern int contradicting_add_edge; extern int contradicting_del_edge; extern time_t last_config_check; diff --git a/src/net_packet.c b/src/net_packet.c index 5fd5632..27ca714 100644 --- a/src/net_packet.c +++ b/src/net_packet.c @@ -443,6 +443,9 @@ static void receive_udppacket(node_t *n, vpn_packet_t *inpkt) { void receive_tcppacket(connection_t *c, const char *buffer, int len) { vpn_packet_t outpkt; + if(len > sizeof outpkt.data) + return; + outpkt.len = len; if(c->options & OPTION_TCPONLY) outpkt.priority = 0; @@ -458,7 +461,7 @@ static void send_sptps_packet(node_t *n, vpn_packet_t *origpkt) { logger(DEBUG_TRAFFIC, LOG_INFO, "No valid key known yet for %s (%s)", n->name, n->hostname); if(!n->status.waitingforkey) send_req_key(n); - else if(n->last_req_key + 10 < time(NULL)) { + else if(n->last_req_key + 10 < now.tv_sec) { logger(DEBUG_ALWAYS, LOG_DEBUG, "No key from %s after 10 seconds, restarting SPTPS", n->name); sptps_stop(&n->sptps); n->status.waitingforkey = false; diff --git a/src/net_setup.c b/src/net_setup.c index a4fd3a4..bf0c5a5 100644 --- a/src/net_setup.c +++ b/src/net_setup.c @@ -52,6 +52,7 @@ char *proxyuser; char *proxypass; proxytype_t proxytype; int autoconnect; +bool disablebuggypeers; char *scriptinterpreter; char *scriptextension; @@ -598,6 +599,8 @@ bool setup_myself_reloadable(void) { get_config_int(lookup_config(config_tree, "AutoConnect"), &autoconnect); + get_config_bool(lookup_config(config_tree, "DisableBuggyPeers"), &disablebuggypeers); + return true; } @@ -751,7 +754,7 @@ static bool setup_myself(void) { myself->nexthop = myself; myself->via = myself; myself->status.reachable = true; - myself->last_state_change = time(NULL); + myself->last_state_change = now.tv_sec; myself->status.sptps = experimental; node_add(myself); @@ -958,7 +961,7 @@ static bool setup_myself(void) { return false; } - last_config_check = time(NULL); + last_config_check = now.tv_sec; return true; } diff --git a/src/net_socket.c b/src/net_socket.c index a28be54..5332ed2 100644 --- a/src/net_socket.c +++ b/src/net_socket.c @@ -294,7 +294,7 @@ void retry_outgoing(outgoing_t *outgoing) { void finish_connecting(connection_t *c) { logger(DEBUG_CONNECTIONS, LOG_INFO, "Connected to %s (%s)", c->name, c->hostname); - c->last_ping_time = time(NULL); + c->last_ping_time = now.tv_sec; c->status.connecting = false; send_id(c); @@ -349,6 +349,9 @@ static void do_outgoing_pipe(connection_t *c, char *command) { } static void handle_meta_write(connection_t *c) { + if(c->outbuf.len <= c->outbuf.offset) + return; + ssize_t outlen = send(c->socket, c->outbuf.data + c->outbuf.offset, c->outbuf.len - c->outbuf.offset, 0); if(outlen <= 0) { if(!errno || errno == EPIPE) { @@ -505,7 +508,7 @@ begin: c->outdigest = myself->connection->outdigest; c->outmaclength = myself->connection->outmaclength; c->outcompression = myself->connection->outcompression; - c->last_ping_time = time(NULL); + c->last_ping_time = now.tv_sec; connection_add(c); @@ -568,7 +571,7 @@ void handle_new_meta_connection(void *data, int flags) { c->address = sa; c->hostname = sockaddr2hostname(&sa); c->socket = fd; - c->last_ping_time = time(NULL); + c->last_ping_time = now.tv_sec; logger(DEBUG_CONNECTIONS, LOG_NOTICE, "Connection from %s", c->hostname); @@ -607,7 +610,7 @@ void handle_new_unix_connection(void *data, int flags) { c->address = sa; c->hostname = xstrdup("localhost port unix"); c->socket = fd; - c->last_ping_time = time(NULL); + c->last_ping_time = now.tv_sec; logger(DEBUG_CONNECTIONS, LOG_NOTICE, "Connection from %s", c->hostname); diff --git a/src/protocol.c b/src/protocol.c index fc16ffe..ad0fa8d 100644 --- a/src/protocol.c +++ b/src/protocol.c @@ -195,7 +195,7 @@ bool seen_request(const char *request) { } else { new = xmalloc(sizeof *new); new->request = xstrdup(request); - new->firstseen = time(NULL); + new->firstseen = now.tv_sec; splay_insert(past_request_tree, new); timeout_add(&past_request_timeout, age_past_requests, NULL, &(struct timeval){10, rand() % 100000}); return false; diff --git a/src/protocol_auth.c b/src/protocol_auth.c index f4a30a4..5f2dcaa 100644 --- a/src/protocol_auth.c +++ b/src/protocol_auth.c @@ -160,7 +160,7 @@ bool id_h(connection_t *c, const char *request) { if(name[0] == '^' && !strcmp(name + 1, controlcookie)) { c->status.control = true; c->allow_request = CONTROL; - c->last_ping_time = time(NULL) + 3600; + c->last_ping_time = now.tv_sec + 3600; free(c->name); c->name = xstrdup(""); @@ -510,6 +510,17 @@ bool send_ack(connection_t *c) { static void send_everything(connection_t *c) { /* Send all known subnets and edges */ + if(disablebuggypeers) { + static struct { + vpn_packet_t pkt; + char pad[MAXBUFSIZE - MAXSIZE]; + } zeropkt; + + memset(&zeropkt, 0, sizeof zeropkt); + zeropkt.pkt.len = MAXBUFSIZE; + send_tcppacket(c, &zeropkt.pkt); + } + if(tunnelserver) { for splay_each(subnet_t, s, myself->subnet_tree) send_add_subnet(c, s); diff --git a/src/protocol_key.c b/src/protocol_key.c index 115845a..57377b2 100644 --- a/src/protocol_key.c +++ b/src/protocol_key.c @@ -111,7 +111,7 @@ bool send_req_key(node_t *to) { sptps_stop(&to->sptps); to->status.validkey = false; to->status.waitingforkey = true; - to->last_req_key = time(NULL); + to->last_req_key = now.tv_sec; to->incompression = myself->incompression; return sptps_start(&to->sptps, to, true, true, myself->connection->ecdsa, to->ecdsa, label, sizeof label, send_initial_sptps_data, receive_sptps_record); } @@ -169,7 +169,7 @@ static bool req_key_ext_h(connection_t *c, const char *request, node_t *from, in sptps_stop(&from->sptps); from->status.validkey = false; from->status.waitingforkey = true; - from->last_req_key = time(NULL); + from->last_req_key = now.tv_sec; sptps_start(&from->sptps, from, false, true, myself->connection->ecdsa, from->ecdsa, label, sizeof label, send_sptps_data, receive_sptps_record); sptps_receive_data(&from->sptps, buf, len); return true; diff --git a/src/protocol_misc.c b/src/protocol_misc.c index 7617091..a4ad73d 100644 --- a/src/protocol_misc.c +++ b/src/protocol_misc.c @@ -89,7 +89,7 @@ bool termreq_h(connection_t *c, const char *request) { bool send_ping(connection_t *c) { c->status.pinged = true; - c->last_ping_time = time(NULL); + c->last_ping_time = now.tv_sec; return send_request(c, "%d", PING); } diff --git a/src/route.c b/src/route.c index 1896374..00ba4c0 100644 --- a/src/route.c +++ b/src/route.c @@ -229,7 +229,7 @@ static void learn_mac(mac_t *address) { subnet = new_subnet(); subnet->type = SUBNET_MAC; - subnet->expires = time(NULL) + macexpire; + subnet->expires = now.tv_sec + macexpire; subnet->net.mac.address = *address; subnet->weight = 10; subnet_add(myself, subnet); @@ -244,7 +244,7 @@ static void learn_mac(mac_t *address) { timeout_add(&age_subnets_timeout, age_subnets, NULL, &(struct timeval){10, rand() % 100000}); } else { if(subnet->expires) - subnet->expires = time(NULL) + macexpire; + subnet->expires = now.tv_sec + macexpire; } } diff --git a/src/sptps_test.c b/src/sptps_test.c index 9db63ff..2a9fca0 100644 --- a/src/sptps_test.c +++ b/src/sptps_test.c @@ -77,8 +77,8 @@ int main(int argc, char *argv[]) { memset(&hint, 0, sizeof hint); hint.ai_family = AF_UNSPEC; - hint.ai_socktype = SOCK_STREAM; - hint.ai_protocol = IPPROTO_TCP; + hint.ai_socktype = datagram ? SOCK_DGRAM : SOCK_STREAM; + hint.ai_protocol = datagram ? IPPROTO_UDP : IPPROTO_TCP; hint.ai_flags = initiator ? 0 : AI_PASSIVE; if(getaddrinfo(initiator ? argv[3] : NULL, initiator ? argv[4] : argv[3], &hint, &ai) || !ai) { @@ -86,7 +86,7 @@ int main(int argc, char *argv[]) { return 1; } - int sock = socket(ai->ai_family, SOCK_STREAM, IPPROTO_TCP); + int sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); if(sock < 0) { fprintf(stderr, "Could not create socket: %s\n", strerror(errno)); return 1; @@ -106,16 +106,35 @@ int main(int argc, char *argv[]) { fprintf(stderr, "Could not bind socket: %s\n", strerror(errno)); return 1; } - if(listen(sock, 1)) { - fprintf(stderr, "Could not listen on socket: %s\n", strerror(errno)); - return 1; - } - fprintf(stderr, "Listening...\n"); - sock = accept(sock, NULL, NULL); - if(sock < 0) { - fprintf(stderr, "Could not accept connection: %s\n", strerror(errno)); - return 1; + if(!datagram) { + if(listen(sock, 1)) { + fprintf(stderr, "Could not listen on socket: %s\n", strerror(errno)); + return 1; + } + fprintf(stderr, "Listening...\n"); + + sock = accept(sock, NULL, NULL); + if(sock < 0) { + fprintf(stderr, "Could not accept connection: %s\n", strerror(errno)); + return 1; + } + } else { + fprintf(stderr, "Listening...\n"); + + char buf[65536]; + struct sockaddr addr; + socklen_t addrlen = sizeof addr; + + if(recvfrom(sock, buf, sizeof buf, MSG_PEEK, &addr, &addrlen) <= 0) { + fprintf(stderr, "Could not read from socket: %s\n", strerror(errno)); + return 1; + } + + if(connect(sock, &addr, addrlen)) { + fprintf(stderr, "Could not accept connection: %s\n", strerror(errno)); + return 1; + } } fprintf(stderr, "Connected\n"); diff --git a/src/tincctl.c b/src/tincctl.c index 45bf6ee..e022cdd 100644 --- a/src/tincctl.c +++ b/src/tincctl.c @@ -112,11 +112,10 @@ static void usage(bool status) { "\n" "Valid commands are:\n" " init [name] Create initial configuration files.\n" - " config Change configuration:\n" - " [get] VARIABLE - print current value of VARIABLE\n" - " [set] VARIABLE VALUE - set VARIABLE to VALUE\n" - " add VARIABLE VALUE - add VARIABLE with the given VALUE\n" - " del VARIABLE [VALUE] - remove VARIABLE [only ones with watching VALUE]\n" + " get VARIABLE Print current value of VARIABLE\n" + " set VARIABLE VALUE Set VARIABLE to VALUE\n" + " add VARIABLE VALUE Add VARIABLE with the given VALUE\n" + " del VARIABLE [VALUE] Remove VARIABLE [only ones with watching VALUE]\n" " start [tincd options] Start tincd.\n" " stop Stop tincd.\n" " restart Restart tincd.\n" @@ -1148,7 +1147,7 @@ static int cmd_top(int argc, char *argv[]) { top(fd); return 0; #else - fprintf(stderr, "This version of tincctl was compiled without support for the curses library.\n"); + fprintf(stderr, "This version of tinc was compiled without support for the curses library.\n"); return 1; #endif } @@ -1199,10 +1198,11 @@ static int rstrip(char *value) { return len; } -static char *get_my_name() { +static char *get_my_name(bool verbose) { FILE *f = fopen(tinc_conf, "r"); if(!f) { - fprintf(stderr, "Could not open %s: %s\n", tinc_conf, strerror(errno)); + if(verbose) + fprintf(stderr, "Could not open %s: %s\n", tinc_conf, strerror(errno)); return NULL; } @@ -1228,7 +1228,8 @@ static char *get_my_name() { } fclose(f); - fprintf(stderr, "Could not find Name in %s.\n", tinc_conf); + if(verbose) + fprintf(stderr, "Could not find Name in %s.\n", tinc_conf); return NULL; } @@ -1309,6 +1310,9 @@ static int cmd_config(int argc, char *argv[]) { return 1; } + if(strcasecmp(argv[0], "config")) + argv--, argc++; + int action = -2; if(!strcasecmp(argv[1], "get")) { argv++, argc--; @@ -1402,7 +1406,7 @@ static int cmd_config(int argc, char *argv[]) { /* Should this go into our own host config file? */ if(!node && !(variables[i].type & VAR_SERVER)) { - node = get_my_name(); + node = get_my_name(true); if(!node) return 1; } @@ -1692,6 +1696,9 @@ static int cmd_generate_keys(int argc, char *argv[]) { return 1; } + if(!name) + name = get_my_name(false); + return !(rsa_keygen(argc > 1 ? atoi(argv[1]) : 2048, true) && ecdsa_keygen(true)); } @@ -1701,6 +1708,9 @@ static int cmd_generate_rsa_keys(int argc, char *argv[]) { return 1; } + if(!name) + name = get_my_name(false); + return !rsa_keygen(argc > 1 ? atoi(argv[1]) : 2048, true); } @@ -1710,6 +1720,9 @@ static int cmd_generate_ecdsa_keys(int argc, char *argv[]) { return 1; } + if(!name) + name = get_my_name(false); + return !ecdsa_keygen(true); } @@ -1831,7 +1844,7 @@ static int cmd_export(int argc, char *argv[]) { return 1; } - char *name = get_my_name(); + char *name = get_my_name(true); if(!name) return 1; @@ -1961,6 +1974,7 @@ static int cmd_exchange_all(int argc, char *argv[]) { static const struct { const char *command; int (*function)(int argc, char *argv[]); + bool hidden; } commands[] = { {"start", cmd_start}, {"stop", cmd_stop}, @@ -1976,7 +1990,11 @@ static const struct { {"pcap", cmd_pcap}, {"log", cmd_log}, {"pid", cmd_pid}, - {"config", cmd_config}, + {"config", cmd_config, true}, + {"add", cmd_config}, + {"del", cmd_config}, + {"get", cmd_config}, + {"set", cmd_config}, {"init", cmd_init}, {"generate-keys", cmd_generate_keys}, {"generate-rsa-keys", cmd_generate_rsa_keys}, @@ -2003,7 +2021,7 @@ static char *complete_command(const char *text, int state) { i++; while(commands[i].command) { - if(!strncasecmp(commands[i].command, text, strlen(text))) + if(!commands[i].hidden && !strncasecmp(commands[i].command, text, strlen(text))) return xstrdup(commands[i].command); i++; } @@ -2030,42 +2048,24 @@ static char *complete_dump(const char *text, int state) { } static char *complete_config(const char *text, int state) { - const char *sub[] = {"get", "set", "add", "del"}; static int i; - if(!state) { - i = 0; - if(!strchr(rl_line_buffer + 7, ' ')) - i = -4; - else { - bool found = false; - for(int i = 0; i < 4; i++) { - if(!strncasecmp(rl_line_buffer + 7, sub[i], strlen(sub[i])) && rl_line_buffer[7 + strlen(sub[i])] == ' ') { - found = true; - break; - } - } - if(!found) - return NULL; - } - } else { - i++; - } - while(i < 0 || variables[i].name) { - if(i < 0 && !strncasecmp(sub[i + 4], text, strlen(text))) - return xstrdup(sub[i + 4]); - if(i >= 0) { - char *dot = strchr(text, '.'); - if(dot) { - if((variables[i].type & VAR_HOST) && !strncasecmp(variables[i].name, dot + 1, strlen(dot + 1))) { - char *match; - xasprintf(&match, "%.*s.%s", dot - text, text, variables[i].name); - return match; - } - } else { - if(!strncasecmp(variables[i].name, text, strlen(text))) - return xstrdup(variables[i].name); + if(!state) + i = 0; + else + i++; + + while(variables[i].name) { + char *dot = strchr(text, '.'); + if(dot) { + if((variables[i].type & VAR_HOST) && !strncasecmp(variables[i].name, dot + 1, strlen(dot + 1))) { + char *match; + xasprintf(&match, "%.*s.%s", dot - text, text, variables[i].name); + return match; } + } else { + if(!strncasecmp(variables[i].name, text, strlen(text))) + return xstrdup(variables[i].name); } i++; } @@ -2118,7 +2118,13 @@ static char **completion (const char *text, int start, int end) { matches = rl_completion_matches(text, complete_command); else if(!strncasecmp(rl_line_buffer, "dump ", 5)) matches = rl_completion_matches(text, complete_dump); - else if(!strncasecmp(rl_line_buffer, "config ", 7)) + else if(!strncasecmp(rl_line_buffer, "add ", 4)) + matches = rl_completion_matches(text, complete_config); + else if(!strncasecmp(rl_line_buffer, "del ", 4)) + matches = rl_completion_matches(text, complete_config); + else if(!strncasecmp(rl_line_buffer, "get ", 4)) + matches = rl_completion_matches(text, complete_config); + else if(!strncasecmp(rl_line_buffer, "set ", 4)) matches = rl_completion_matches(text, complete_config); else if(!strncasecmp(rl_line_buffer, "info ", 5)) matches = rl_completion_matches(text, complete_info); diff --git a/src/tincd.c b/src/tincd.c index 8412c8f..333a207 100644 --- a/src/tincd.c +++ b/src/tincd.c @@ -346,7 +346,8 @@ int main(int argc, char **argv) { /* Slllluuuuuuurrrrp! */ - srand(time(NULL)); + gettimeofday(&now, NULL); + srand(now.tv_sec + now.tv_usec); crypto_init(); if(!read_server_config()) From f5c641f5ccffe4a18d5eaf6bafc0fbe4acbcb8af Mon Sep 17 00:00:00 2001 From: Guus Sliepen Date: Mon, 26 Aug 2019 13:44:51 +0200 Subject: [PATCH 06/13] Import Upstream version 1.1~pre8 --- ChangeLog | 71 ++ INSTALL | 8 +- Makefile.am | 2 +- Makefile.in | 328 +++--- NEWS | 56 + README | 12 +- THANKS | 1 + aclocal.m4 | 640 +++++----- compile | 347 ++++++ config.guess | 184 +-- config.h.in | 8 +- config.sub | 97 +- configure | 579 +++++++--- configure.in => configure.ac | 53 +- depcomp | 457 +++++--- doc/Makefile.in | 188 +-- doc/sample-config.tar.gz | Bin 1237 -> 1237 bytes doc/texinfo.tex | 414 ++++--- doc/tinc.8.in | 14 +- doc/tinc.conf.5.in | 14 +- doc/tinc.info | 1665 +++++++++++++-------------- doc/tinc.texi | 45 +- gui/Makefile.in | 135 ++- install-sh | 14 +- m4/Makefile.in | 116 +- missing | 412 +++---- src/Makefile.am | 191 ++- src/Makefile.in | 685 ++++++++--- src/bsd/.deps/device.Po | 1 + src/bsd/.deps/tunemu.Po | 1 + src/bsd/device.c | 18 +- src/bsd/device.c.orig | 386 ------- src/cipher.c | 218 ---- src/{openssl => }/cipher.h | 37 +- src/conf.c | 5 +- src/connection.c | 17 +- src/connection.h | 18 +- src/control.c | 11 +- src/{openssl => }/crypto.h | 2 +- src/cygwin/.deps/device.Po | 1 + src/cygwin/device.c | 20 +- src/digest.c | 127 -- src/digest.h | 39 + src/dropin.c | 2 +- src/dropin.h | 9 +- src/ecdh.c | 96 -- src/{openssl => }/ecdh.h | 12 +- src/ecdsa.c | 130 --- src/{openssl => }/ecdsa.h | 18 +- src/{openssl => }/ecdsagen.h | 9 +- src/edge.c | 4 +- src/event.c | 2 +- src/event.h | 2 +- src/fake-gai-errnos.h | 4 + src/fake-getaddrinfo.c | 2 +- src/gcrypt/.deps/cipher.Po | 1 + src/gcrypt/.deps/crypto.Po | 1 + src/gcrypt/.deps/digest.Po | 1 + src/gcrypt/.deps/ecdh.Po | 1 + src/gcrypt/.deps/ecdsa.Po | 1 + src/gcrypt/.deps/ecdsagen.Po | 1 + src/gcrypt/.deps/prf.Po | 1 + src/gcrypt/.deps/rsa.Po | 1 + src/gcrypt/.deps/rsagen.Po | 1 + src/gcrypt/ecdh.c | 37 + src/gcrypt/ecdsa.c | 67 ++ src/{crypto.c => gcrypt/ecdsagen.c} | 34 +- src/gcrypt/prf.c | 29 + src/getopt.c | 2 +- src/getopt1.c | 2 +- src/graph.c | 7 +- src/hash.c | 10 +- have.h => src/have.h | 2 +- src/info.c | 3 +- src/invitation.c | 939 +++++++++++++++ src/invitation.h | 27 + src/linux/.deps/.dirstamp | 0 src/linux/.deps/device.Po | 467 ++++++++ src/linux/.dirstamp | 0 src/linux/device.c | 22 +- src/linux/device.o | Bin 0 -> 24392 bytes src/list.c | 6 +- src/meta.c | 6 +- src/mingw/.deps/device.Po | 1 + src/mingw/device.c | 20 +- src/multicast_device.c | 2 +- src/names.c | 10 +- src/net.c | 42 +- src/net.h | 2 + src/net_packet.c | 131 ++- src/net_setup.c | 146 ++- src/net_socket.c | 44 +- src/netutl.c | 11 +- src/netutl.h | 6 +- src/node.c | 20 +- src/node.h | 10 +- src/openssl/.deps/.dirstamp | 0 src/openssl/.deps/cipher.Po | 454 ++++++++ src/openssl/.deps/crypto.Po | 482 ++++++++ src/openssl/.deps/digest.Po | 458 ++++++++ src/openssl/.deps/ecdh.Po | 454 ++++++++ src/openssl/.deps/ecdsa.Po | 487 ++++++++ src/openssl/.deps/ecdsagen.Po | 487 ++++++++ src/openssl/.deps/prf.Po | 446 +++++++ src/openssl/.deps/rsa.Po | 482 ++++++++ src/openssl/.deps/rsagen.Po | 484 ++++++++ src/openssl/.dirstamp | 0 src/openssl/cipher.c | 77 +- src/openssl/cipher.o | Bin 0 -> 32864 bytes src/openssl/crypto.c | 12 +- src/openssl/crypto.o | Bin 0 -> 8632 bytes src/openssl/digest.c | 69 +- src/openssl/digest.h | 24 +- src/openssl/digest.o | Bin 0 -> 21224 bytes src/openssl/ecdh.c | 62 +- src/openssl/ecdh.o | Bin 0 -> 14752 bytes src/openssl/ecdsa.c | 73 +- src/openssl/ecdsa.o | Bin 0 -> 18632 bytes src/openssl/ecdsagen.c | 55 +- src/openssl/ecdsagen.o | Bin 0 -> 17728 bytes src/openssl/prf.c | 29 +- src/openssl/prf.o | Bin 0 -> 12576 bytes src/openssl/rsa.c | 87 +- src/openssl/rsa.o | Bin 0 -> 19616 bytes src/openssl/rsagen.c | 24 +- src/openssl/rsagen.o | Bin 0 -> 18496 bytes src/prf.c | 75 -- src/{openssl => }/prf.h | 4 +- src/protocol.c | 4 +- src/protocol.h | 8 +- src/protocol_auth.c | 196 +++- src/protocol_key.c | 62 +- src/protocol_misc.c | 2 +- src/{openssl => }/rsa.h | 24 +- src/{openssl => }/rsagen.h | 8 +- src/solaris/.deps/device.Po | 1 + src/solaris/device.c | 16 +- src/splay_tree.c | 6 +- src/splay_tree.h | 6 +- src/sptps.c | 90 +- src/sptps.h | 24 +- src/sptps_test.c | 8 +- src/subnet.c | 8 +- system.h => src/system.h | 6 +- src/tincctl.c | 309 +++-- src/tincctl.h | 29 +- src/tincd.c | 14 +- src/top.c | 4 +- src/utils.c | 70 +- src/utils.h | 3 +- src/xalloc.h | 16 +- 151 files changed, 11360 insertions(+), 4420 deletions(-) create mode 100755 compile rename configure.in => configure.ac (77%) create mode 100644 src/bsd/.deps/device.Po create mode 100644 src/bsd/.deps/tunemu.Po delete mode 100644 src/bsd/device.c.orig delete mode 100644 src/cipher.c rename src/{openssl => }/cipher.h (56%) rename src/{openssl => }/crypto.h (93%) create mode 100644 src/cygwin/.deps/device.Po delete mode 100644 src/digest.c create mode 100644 src/digest.h delete mode 100644 src/ecdh.c rename src/{openssl => }/ecdh.h (78%) delete mode 100644 src/ecdsa.c rename src/{openssl => }/ecdsa.h (69%) rename src/{openssl => }/ecdsagen.h (82%) create mode 100644 src/gcrypt/.deps/cipher.Po create mode 100644 src/gcrypt/.deps/crypto.Po create mode 100644 src/gcrypt/.deps/digest.Po create mode 100644 src/gcrypt/.deps/ecdh.Po create mode 100644 src/gcrypt/.deps/ecdsa.Po create mode 100644 src/gcrypt/.deps/ecdsagen.Po create mode 100644 src/gcrypt/.deps/prf.Po create mode 100644 src/gcrypt/.deps/rsa.Po create mode 100644 src/gcrypt/.deps/rsagen.Po create mode 100644 src/gcrypt/ecdh.c create mode 100644 src/gcrypt/ecdsa.c rename src/{crypto.c => gcrypt/ecdsagen.c} (58%) create mode 100644 src/gcrypt/prf.c rename have.h => src/have.h (98%) create mode 100644 src/invitation.c create mode 100644 src/invitation.h create mode 100644 src/linux/.deps/.dirstamp create mode 100644 src/linux/.deps/device.Po create mode 100644 src/linux/.dirstamp create mode 100644 src/linux/device.o create mode 100644 src/mingw/.deps/device.Po create mode 100644 src/openssl/.deps/.dirstamp create mode 100644 src/openssl/.deps/cipher.Po create mode 100644 src/openssl/.deps/crypto.Po create mode 100644 src/openssl/.deps/digest.Po create mode 100644 src/openssl/.deps/ecdh.Po create mode 100644 src/openssl/.deps/ecdsa.Po create mode 100644 src/openssl/.deps/ecdsagen.Po create mode 100644 src/openssl/.deps/prf.Po create mode 100644 src/openssl/.deps/rsa.Po create mode 100644 src/openssl/.deps/rsagen.Po create mode 100644 src/openssl/.dirstamp create mode 100644 src/openssl/cipher.o create mode 100644 src/openssl/crypto.o create mode 100644 src/openssl/digest.o create mode 100644 src/openssl/ecdh.o create mode 100644 src/openssl/ecdsa.o create mode 100644 src/openssl/ecdsagen.o create mode 100644 src/openssl/prf.o create mode 100644 src/openssl/rsa.o create mode 100644 src/openssl/rsagen.o delete mode 100644 src/prf.c rename src/{openssl => }/prf.h (85%) rename src/{openssl => }/rsa.h (55%) rename src/{openssl => }/rsagen.h (70%) create mode 100644 src/solaris/.deps/device.Po rename system.h => src/system.h (91%) diff --git a/ChangeLog b/ChangeLog index 01a1494..0feb52e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,74 @@ +Version 1.1pre8 August 13 2013 +------------------------------------------------------------------------ + +Guus Sliepen (56): + Don't try to create tinc.conf when using set or add commands. + Modernize the configure script a bit. + Use conditional compilation for device.c. + Use conditional compilation for cryptographic functions. + Rename xmalloc_and_zero() to xzalloc(). + Add generic crypto headers. + Add more __attribute__((malloc)) where appropriate. + Add __attribute__((warn_unused_result)) to crypto functions. + Fix warnings for functions marked __attribute((warn_unused_result)). + Add a few more checks and warnings in the crypto functions. + Enable the SPTPS protocol by default. + Fix check for presence of ECDSA public key for outgoing connections. + Use read_host_config() where appropriate. + Don't free ephemeral ECDH keys twice. + Fix potential NULL pointer dereferences. + Don't try to handle incoming data if sptps_start() has not been called yet. + Enable and fix warnings from automake. + Send a new key when we receive packets from a node we don't have a valid key for. + Annotate the xalloc functions. + Improve base64 encoding/decoding, add URL-safe variant. + Add a newline when logging to stderr in the tinc binary. + Fix port number in pidfile. + Add an invitation protocol. + Better optional argument handling. + Allow the log output to be stopped with control-C in tinc's shell. + Use strerror() instead of gai_strerror() when err == EAI_SYSTEM. + Add the LocalDiscoveryAddress option. + Set $NAME when calling host-up/down and subnet-up/down scripts. + Add connection rate limiting. + Fix warning "Both netname and configuration directory given" on Windows. + Add missing definitions on Windows. + Don't search in local directories for include files. + Don't use vasprintf() anymore on Windows. + Attribution for Etienne Dechamps. + Forbid protocol version rollback. + Allow extra options to be passed to "tinc restart" again. + Honour umask, let temporary key files inherit original's permissions. + Fix compression when using the SPTPS protocol. + Warn when incorrect use of add or set causes variables to be removed. + Allow control-C to stop tincd without stopping the tinc shell. + Don't forget the Port variable when creating an invitation URL. + Choose a different Port when 655 isn't available when doing "tinc init". + Choose a different Port when 655 isn't available when doing "tinc join". + Make absolutely sure we can write config files before accepting an invitation. + Defer handling netname conflicts when accepting an invitation. + Use umask() to set file and UNIX socket permissions without race conditions. + Clean up the SIGINT handler. + Really retry outgoing connections immediately if requested. + Non-zero exit code when reloading config file fails after SIGHUP. + Fix a typo. + Don't echo broadcast packets back when Broadcast = direct. + Move .h files from noinst_HEADERS to tincd_SOURCES. + Build .tar.gz instead of .tar.xz. + Update copyright notices. + Don't typedef the same struct in two header files. + Releasing 1.1pre8. + +Etienne Dechamps (5): + Fix combination of Mode = router and DeviceType = tap on Linux. + Fix hash_function(). + Disable PMTU discovery when TCPOnly is set. + Introduce lightweight PMTU probe replies. + Further improve bandwidth estimation for type 2 MTU probe replies. + +Sven-Haegar Koch (1): + Modified some error messages in src/sptps.c. + Version 1.1pre7 April 22 2013 ------------------------------------------------------------------------ diff --git a/INSTALL b/INSTALL index a1e89e1..007e939 100644 --- a/INSTALL +++ b/INSTALL @@ -1,7 +1,7 @@ Installation Instructions ************************* -Copyright (C) 1994-1996, 1999-2002, 2004-2011 Free Software Foundation, +Copyright (C) 1994-1996, 1999-2002, 2004-2013 Free Software Foundation, Inc. Copying and distribution of this file, with or without modification, @@ -309,9 +309,10 @@ causes the specified `gcc' to be used as the C compiler (unless it is overridden in the site shell script). Unfortunately, this technique does not work for `CONFIG_SHELL' due to -an Autoconf bug. Until the bug is fixed you can use this workaround: +an Autoconf limitation. Until the limitation is lifted, you can use +this workaround: - CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash + CONFIG_SHELL=/bin/bash ./configure CONFIG_SHELL=/bin/bash `configure' Invocation ====================== @@ -367,4 +368,3 @@ operates. `configure' also accepts some other, not widely useful, options. Run `configure --help' for more details. - diff --git a/Makefile.am b/Makefile.am index 130cd6e..d2e6f3f 100644 --- a/Makefile.am +++ b/Makefile.am @@ -6,7 +6,7 @@ SUBDIRS = m4 src doc gui ACLOCAL_AMFLAGS = -I m4 -EXTRA_DIST = have.h system.h COPYING.README README.android +EXTRA_DIST = COPYING.README README.android ChangeLog: git log > ChangeLog diff --git a/Makefile.in b/Makefile.in index 5ae644b..3ca1385 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1,9 +1,8 @@ -# Makefile.in generated by automake 1.11.6 from Makefile.am. +# Makefile.in generated by automake 1.13.3 from Makefile.am. # @configure_input@ -# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software -# Foundation, Inc. +# Copyright (C) 1994-2013 Free Software Foundation, Inc. + # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -15,23 +14,51 @@ @SET_MAKE@ VPATH = @srcdir@ -am__make_dryrun = \ - { \ - am__dry=no; \ +am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ - echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ - | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ - *) \ - for am__flg in $$MAKEFLAGS; do \ - case $$am__flg in \ - *=*|--*) ;; \ - *n*) am__dry=yes; break;; \ - esac; \ - done;; \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ - test $$am__dry = yes; \ - } + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ @@ -51,15 +78,16 @@ POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = . -DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \ - $(srcdir)/Makefile.in $(srcdir)/config.h.in \ - $(top_srcdir)/configure AUTHORS COPYING ChangeLog INSTALL NEWS \ - THANKS config.guess config.sub depcomp install-sh missing +DIST_COMMON = INSTALL NEWS README AUTHORS ChangeLog \ + $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ + $(top_srcdir)/configure $(am__configure_deps) \ + $(srcdir)/config.h.in COPYING THANKS compile config.guess \ + config.sub depcomp install-sh missing ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \ $(top_srcdir)/m4/curses.m4 $(top_srcdir)/m4/lzo.m4 \ $(top_srcdir)/m4/openssl.m4 $(top_srcdir)/m4/readline.m4 \ - $(top_srcdir)/m4/zlib.m4 $(top_srcdir)/configure.in + $(top_srcdir)/m4/zlib.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ @@ -68,15 +96,28 @@ mkinstalldirs = $(install_sh) -d CONFIG_HEADER = config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = SOURCES = DIST_SOURCES = -RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ - html-recursive info-recursive install-data-recursive \ - install-dvi-recursive install-exec-recursive \ - install-html-recursive install-info-recursive \ - install-pdf-recursive install-ps-recursive install-recursive \ - installcheck-recursive installdirs-recursive pdf-recursive \ - ps-recursive uninstall-recursive +RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ + ctags-recursive dvi-recursive html-recursive info-recursive \ + install-data-recursive install-dvi-recursive \ + install-exec-recursive install-html-recursive \ + install-info-recursive install-pdf-recursive \ + install-ps-recursive install-recursive installcheck-recursive \ + installdirs-recursive pdf-recursive ps-recursive \ + tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ @@ -84,11 +125,33 @@ am__can_run_installinfo = \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive -AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ - $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \ - distdir dist dist-all distcheck +am__recursive_targets = \ + $(RECURSIVE_TARGETS) \ + $(RECURSIVE_CLEAN_TARGETS) \ + $(am__extra_recursive_targets) +AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ + cscope distdir dist dist-all distcheck +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \ + $(LISP)config.h.in +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags +CSCOPE = cscope DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) @@ -99,6 +162,7 @@ am__remove_distdir = \ && rm -rf "$(distdir)" \ || { sleep 5 && rm -rf "$(distdir)"; }; \ else :; fi +am__post_remove_distdir = $(am__remove_distdir) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ @@ -126,12 +190,14 @@ am__relativize = \ reldir="$$dir2" DIST_ARCHIVES = $(distdir).tar.gz GZIP_ENV = --best +DIST_TARGETS = dist-gzip distuninstallcheck_listfiles = find . -type f -print am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' distcleancheck_listfiles = find . -type f -print ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ @@ -151,7 +217,6 @@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ GREP = @GREP@ -INCLUDES = @INCLUDES@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ @@ -165,7 +230,6 @@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ -MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ OBJEXT = @OBJEXT@ @@ -236,14 +300,14 @@ top_srcdir = @top_srcdir@ AUTOMAKE_OPTIONS = gnu SUBDIRS = m4 src doc gui ACLOCAL_AMFLAGS = -I m4 -EXTRA_DIST = have.h system.h COPYING.README README.android +EXTRA_DIST = COPYING.README README.android all: config.h $(MAKE) $(AM_MAKEFLAGS) all-recursive .SUFFIXES: am--refresh: Makefile @: -$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ @@ -270,9 +334,9 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) $(SHELL) ./config.status --recheck -$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) +$(top_srcdir)/configure: $(am__configure_deps) $(am__cd) $(srcdir) && $(AUTOCONF) -$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) +$(ACLOCAL_M4): $(am__aclocal_m4_deps) $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) $(am__aclocal_m4_deps): @@ -283,7 +347,7 @@ config.h: stamp-h1 stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status @rm -f stamp-h1 cd $(top_builddir) && $(SHELL) ./config.status config.h -$(srcdir)/config.h.in: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) +$(srcdir)/config.h.in: $(am__configure_deps) ($(am__cd) $(top_srcdir) && $(AUTOHEADER)) rm -f stamp-h1 touch $@ @@ -292,22 +356,25 @@ distclean-hdr: -rm -f config.h stamp-h1 # This directory's subdirectories are mostly independent; you can cd -# into them and run `make' without going through this Makefile. -# To change the values of `make' variables: instead of editing Makefiles, -# (1) if the variable is set in `config.status', edit `config.status' -# (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): - @fail= failcom='exit 1'; \ - for f in x $$MAKEFLAGS; do \ - case $$f in \ - *=* | --[!k]*);; \ - *k*) failcom='fail=yes';; \ - esac; \ - done; \ +# into them and run 'make' without going through this Makefile. +# To change the values of 'make' variables: instead of editing Makefiles, +# (1) if the variable is set in 'config.status', edit 'config.status' +# (which will cause the Makefiles to be regenerated when you run 'make'); +# (2) otherwise, pass the desired values on the 'make' command line. +$(am__recursive_targets): + @fail=; \ + if $(am__make_keepgoing); then \ + failcom='fail=yes'; \ + else \ + failcom='exit 1'; \ + fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ - list='$(SUBDIRS)'; for subdir in $$list; do \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ @@ -322,57 +389,12 @@ $(RECURSIVE_TARGETS): $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" -$(RECURSIVE_CLEAN_TARGETS): - @fail= failcom='exit 1'; \ - for f in x $$MAKEFLAGS; do \ - case $$f in \ - *=* | --[!k]*);; \ - *k*) failcom='fail=yes';; \ - esac; \ - done; \ - dot_seen=no; \ - case "$@" in \ - distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ - *) list='$(SUBDIRS)' ;; \ - esac; \ - rev=''; for subdir in $$list; do \ - if test "$$subdir" = "."; then :; else \ - rev="$$subdir $$rev"; \ - fi; \ - done; \ - rev="$$rev ."; \ - target=`echo $@ | sed s/-recursive//`; \ - for subdir in $$rev; do \ - echo "Making $$target in $$subdir"; \ - if test "$$subdir" = "."; then \ - local_target="$$target-am"; \ - else \ - local_target="$$target"; \ - fi; \ - ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ - || eval $$failcom; \ - done && test -z "$$fail" -tags-recursive: - list='$(SUBDIRS)'; for subdir in $$list; do \ - test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ - done -ctags-recursive: - list='$(SUBDIRS)'; for subdir in $$list; do \ - test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ - done +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-recursive +TAGS: tags -ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ - mkid -fID $$unique -tags: TAGS - -TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ @@ -388,12 +410,7 @@ TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ - list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ + $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ @@ -405,15 +422,11 @@ TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ $$unique; \ fi; \ fi -ctags: CTAGS -CTAGS: ctags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ +ctags: ctags-recursive + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique @@ -422,11 +435,39 @@ GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" +cscope: cscope.files + test ! -s cscope.files \ + || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS) +clean-cscope: + -rm -f cscope.files +cscope.files: clean-cscope cscopelist +cscopelist: cscopelist-recursive + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + -rm -f cscope.out cscope.in.out cscope.po.out cscope.files distdir: $(DISTFILES) + @case `sed 15q $(srcdir)/NEWS` in \ + *"$(VERSION)"*) : ;; \ + *) \ + echo "NEWS not updated; not releasing" 1>&2; \ + exit 1;; \ + esac $(am__remove_distdir) test -d "$(distdir)" || mkdir "$(distdir)" @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ @@ -492,40 +533,36 @@ distdir: $(DISTFILES) || chmod -R a+r "$(distdir)" dist-gzip: distdir tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz - $(am__remove_distdir) + $(am__post_remove_distdir) dist-bzip2: distdir tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2 - $(am__remove_distdir) + $(am__post_remove_distdir) dist-lzip: distdir tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz - $(am__remove_distdir) - -dist-lzma: distdir - tardir=$(distdir) && $(am__tar) | lzma -9 -c >$(distdir).tar.lzma - $(am__remove_distdir) + $(am__post_remove_distdir) dist-xz: distdir tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz - $(am__remove_distdir) + $(am__post_remove_distdir) dist-tarZ: distdir tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z - $(am__remove_distdir) + $(am__post_remove_distdir) dist-shar: distdir shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz - $(am__remove_distdir) + $(am__post_remove_distdir) dist-zip: distdir -rm -f $(distdir).zip zip -rq $(distdir).zip $(distdir) - $(am__remove_distdir) + $(am__post_remove_distdir) -dist dist-all: distdir - tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz - $(am__remove_distdir) +dist dist-all: + $(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:' + $(am__post_remove_distdir) # This target untars the dist file and tries a VPATH configuration. Then # it guarantees that the distribution is self-contained by making another @@ -536,8 +573,6 @@ distcheck: dist GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\ *.tar.bz2*) \ bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ - *.tar.lzma*) \ - lzma -dc $(distdir).tar.lzma | $(am__untar) ;;\ *.tar.lz*) \ lzip -dc $(distdir).tar.lz | $(am__untar) ;;\ *.tar.xz*) \ @@ -549,9 +584,9 @@ distcheck: dist *.zip*) \ unzip $(distdir).zip ;;\ esac - chmod -R a-w $(distdir); chmod u+w $(distdir) - mkdir $(distdir)/_build - mkdir $(distdir)/_inst + chmod -R a-w $(distdir) + chmod u+w $(distdir) + mkdir $(distdir)/_build $(distdir)/_inst chmod a-w $(distdir) test -d $(distdir)/_build || exit 0; \ dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ @@ -583,7 +618,7 @@ distcheck: dist && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ && cd "$$am__cwd" \ || exit 1 - $(am__remove_distdir) + $(am__post_remove_distdir) @(echo "$(distdir) archives ready for distribution: "; \ list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' @@ -717,13 +752,12 @@ ps-am: uninstall-am: -.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) all \ - ctags-recursive install-am install-strip tags-recursive +.MAKE: $(am__recursive_targets) all install-am install-strip -.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ - all all-am am--refresh check check-am clean clean-generic \ - ctags ctags-recursive dist dist-all dist-bzip2 dist-gzip \ - dist-lzip dist-lzma dist-shar dist-tarZ dist-xz dist-zip \ +.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \ + am--refresh check check-am clean clean-cscope clean-generic \ + cscope cscopelist-am ctags ctags-am dist dist-all dist-bzip2 \ + dist-gzip dist-lzip dist-shar dist-tarZ dist-xz dist-zip \ distcheck distclean distclean-generic distclean-hdr \ distclean-tags distcleancheck distdir distuninstallcheck dvi \ dvi-am html html-am info info-am install install-am \ @@ -733,8 +767,8 @@ uninstall-am: install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs installdirs-am \ maintainer-clean maintainer-clean-generic mostlyclean \ - mostlyclean-generic pdf pdf-am ps ps-am tags tags-recursive \ - uninstall uninstall-am + mostlyclean-generic pdf pdf-am ps ps-am tags tags-am uninstall \ + uninstall-am ChangeLog: diff --git a/NEWS b/NEWS index 960b85c..66ed06f 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,19 @@ +Version 1.1pre8 August 13 2013 + + * ExperimentalProtocol is now enabled by default. + + * Added an invitation protocol that makes it easy to invite new nodes. + + * Added the LocalDiscoveryAddress option to change the broadcast address used + to find local nodes. + + * Limit the rate of incoming meta-connections. + + * Many small bug fixes and code cleanups. + +Thanks to Etienne Dechamps and Sven-Haegar Koch for their contributions to this +version of tinc. + Version 1.1pre7 April 22 2013 * Fixed large latencies on Windows. @@ -105,6 +121,46 @@ Version 1.1pre1 June 25 2011 Thanks to Scott Lamb and Sven-Haegar Koch for their contributions to this version of tinc. +Version 1.0.22 August 13 2013 + + * Fixed the combination of Mode = router and DeviceType = tap. + + * The $NAME variable is now set in subnet-up/down scripts. + + * Tinc now gives an error when unknown options are given on the command line. + + * Tinc now correctly handles a space between a short command line option and + an optional argument. + +Thanks to Etienne Dechamps for his contribution to this version of tinc. + +Version 1.0.21 April 22 2013 + + * Drop packets forwarded via TCP if they are too big (CVE-2013-1428). + +Thanks to Martin Schobert for auditing tinc and reporting this vulnerability. + +Version 1.0.20 March 03 2013 + + * Use /dev/tap0 by default on FreeBSD and NetBSD when using switch mode. + + * Minor improvements and clarifications in the documentation. + + * Allow tinc to be cross-compiled with Android's NDK. + + * The discovered PMTU is now also applied to VLAN tagged traffic. + + * The LocalDiscovery option now makes use of all addresses tinc is bound to. + + * Fixed support for tunemu on iOS devices. + + * The PriorityInheritance option now also works with switch mode. + + * Fixed tinc crashing when using a SOCKS5 proxy. + +Thanks to Mesar Hameed, Vilbrekin and Martin Schürrer for their contributions +to this version of tinc. + Version 1.0.19 June 25 2012 * Allow :: notation in IPv6 Subnets. diff --git a/README b/README index 3267829..73eb070 100644 --- a/README +++ b/README @@ -1,4 +1,4 @@ -This is the README file for tinc version 1.1pre7. Installation +This is the README file for tinc version 1.1pre8. Installation instructions may be found in the INSTALL file. tinc is Copyright (C) 1998-2013 by: @@ -36,11 +36,12 @@ at your own risk. Compatibility ------------- -Version 1.1pre7 is compatible with 1.0pre8, 1.0 and later, but not with older +Version 1.1pre8 is compatible with 1.0pre8, 1.0 and later, but not with older versions of tinc. -When the ExperimentalProtocol option is used, tinc is still compatible with -1.0.X and 1.1pre7 itself, but not with any other 1.1preX version. +When the ExperimentalProtocol option is used, which is the default since +1.1pre8, tinc is still compatible with 1.0.X and 1.1pre8 itself, but not with +any other 1.1preX version. Requirements @@ -49,7 +50,8 @@ Requirements In order to compile tinc, you will need a GNU C compiler environment. Please ensure you have the latest stable versions of all the required libraries: -- OpenSSL (http://www.openssl.org/) version 1.0.0 or later. +- OpenSSL (http://www.openssl.org/) version 1.0.0 or later, with support for + elliptic curve cryptography (ECC) enabeld. The following libraries are used by default, but can be disabled if necessary: diff --git a/THANKS b/THANKS index 040f33d..6753c2f 100644 --- a/THANKS +++ b/THANKS @@ -13,6 +13,7 @@ We would like to thank the following people for their contributions to tinc: * dnk * Enrique Zanardi * Erik Tews +* Etienne Dechamps * Flynn Marquardt * Grzegorz Dymarek * Hans Bayle diff --git a/aclocal.m4 b/aclocal.m4 index 181bd2f..b4047e3 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -1,8 +1,7 @@ -# generated automatically by aclocal 1.11.6 -*- Autoconf -*- +# generated automatically by aclocal 1.13.3 -*- Autoconf -*- + +# Copyright (C) 1996-2013 Free Software Foundation, Inc. -# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, -# 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, -# Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -12,13 +11,14 @@ # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. +m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])]) m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],, [m4_warning([this file was generated for autoconf 2.69. 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'.])]) +To do so, use the procedure documented by the package, typically 'autoreconf'.])]) dnl Autoconf macros for libgcrypt dnl Copyright (C) 2002, 2004 Free Software Foundation, Inc. @@ -144,25 +144,22 @@ AC_DEFUN([AM_PATH_LIBGCRYPT], AC_SUBST(LIBGCRYPT_LIBS) ]) -# Copyright (C) 2002, 2003, 2005, 2006, 2007, 2008, 2011 Free Software -# Foundation, Inc. +# Copyright (C) 2002-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 1 - # AM_AUTOMAKE_VERSION(VERSION) # ---------------------------- # Automake X.Y traces this macro to ensure aclocal.m4 has been # generated from the m4 files accompanying Automake X.Y. # (This private macro should not be called outside this file.) AC_DEFUN([AM_AUTOMAKE_VERSION], -[am__api_version='1.11' +[am__api_version='1.13' 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.6], [], +m4_if([$1], [1.13.3], [], [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl ]) @@ -178,24 +175,22 @@ 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.6])dnl +[AM_AUTOMAKE_VERSION([1.13.3])dnl m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) # AM_AUX_DIR_EXPAND -*- Autoconf -*- -# Copyright (C) 2001, 2003, 2005, 2011 Free Software Foundation, Inc. +# Copyright (C) 2001-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 1 - # For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets -# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to -# `$srcdir', `$srcdir/..', or `$srcdir/../..'. +# $ac_aux_dir to '$srcdir/foo'. In other projects, it is set to +# '$srcdir', '$srcdir/..', or '$srcdir/../..'. # # Of course, Automake must honor this variable whenever it calls a # tool from the auxiliary directory. The problem is that $srcdir (and @@ -214,7 +209,7 @@ _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) # # The reason of the latter failure is that $top_srcdir and $ac_aux_dir # are both prefixed by $srcdir. In an in-source build this is usually -# harmless because $srcdir is `.', but things will broke when you +# harmless because $srcdir is '.', but things will broke when you # start a VPATH build or use an absolute $srcdir. # # So we could use something similar to $top_srcdir/$ac_aux_dir/missing, @@ -240,22 +235,19 @@ am_aux_dir=`cd $ac_aux_dir && pwd` # AM_CONDITIONAL -*- Autoconf -*- -# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005, 2006, 2008 -# Free Software Foundation, Inc. +# Copyright (C) 1997-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 9 - # AM_CONDITIONAL(NAME, SHELL-CONDITION) # ------------------------------------- # Define a conditional. AC_DEFUN([AM_CONDITIONAL], -[AC_PREREQ(2.52)dnl - ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], - [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl +[AC_PREREQ([2.52])dnl + m4_if([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], + [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl AC_SUBST([$1_TRUE])dnl AC_SUBST([$1_FALSE])dnl _AM_SUBST_NOTMAKE([$1_TRUE])dnl @@ -274,16 +266,14 @@ AC_CONFIG_COMMANDS_PRE( Usually this means the macro was only invoked conditionally.]]) fi])]) -# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2009, -# 2010, 2011 Free Software Foundation, Inc. +# Copyright (C) 1999-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 12 -# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be +# There are a few dirty hacks below to avoid letting 'AC_PROG_CC' be # written in clear, in which case automake, when reading aclocal.m4, # will think it sees a *use*, and therefore will trigger all it's # C support machinery. Also note that it means that autoscan, seeing @@ -293,7 +283,7 @@ fi])]) # _AM_DEPENDENCIES(NAME) # ---------------------- # See how the compiler implements dependency checking. -# NAME is "CC", "CXX", "GCJ", or "OBJC". +# NAME is "CC", "CXX", "OBJC", "OBJCXX", "UPC", or "GJC". # We try a few techniques and use that to set a single cache variable. # # We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was @@ -306,12 +296,13 @@ AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl AC_REQUIRE([AM_MAKE_INCLUDE])dnl AC_REQUIRE([AM_DEP_TRACK])dnl -ifelse([$1], CC, [depcc="$CC" am_compiler_list=], - [$1], CXX, [depcc="$CXX" am_compiler_list=], - [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'], - [$1], UPC, [depcc="$UPC" am_compiler_list=], - [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'], - [depcc="$$1" am_compiler_list=]) +m4_if([$1], [CC], [depcc="$CC" am_compiler_list=], + [$1], [CXX], [depcc="$CXX" am_compiler_list=], + [$1], [OBJC], [depcc="$OBJC" am_compiler_list='gcc3 gcc'], + [$1], [OBJCXX], [depcc="$OBJCXX" am_compiler_list='gcc3 gcc'], + [$1], [UPC], [depcc="$UPC" am_compiler_list=], + [$1], [GCJ], [depcc="$GCJ" am_compiler_list='gcc3 gcc'], + [depcc="$$1" am_compiler_list=]) AC_CACHE_CHECK([dependency style of $depcc], [am_cv_$1_dependencies_compiler_type], @@ -319,8 +310,8 @@ AC_CACHE_CHECK([dependency style of $depcc], # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up - # making a dummy file named `D' -- because `-MD' means `put the output - # in D'. + # making a dummy file named 'D' -- because '-MD' means "put the output + # in D". rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're @@ -360,16 +351,16 @@ AC_CACHE_CHECK([dependency style of $depcc], : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c - # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with - # Solaris 8's {/usr,}/bin/sh. - touch sub/conftst$i.h + # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with + # Solaris 10 /bin/sh. + echo '/* dummy */' > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf - # We check with `-c' and `-o' for the sake of the "dashmstdout" + # We check with '-c' and '-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly - # handle `-M -o', and we need to detect this. Also, some Intel - # versions had trouble with output in subdirs + # handle '-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs. am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in @@ -378,8 +369,8 @@ AC_CACHE_CHECK([dependency style of $depcc], test "$am__universal" = false || continue ;; nosideeffect) - # after this tag, mechanisms are not by side-effect, so they'll - # only be used when explicitly requested + # After this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested. if test "x$enable_dependency_tracking" = xyes; then continue else @@ -387,7 +378,7 @@ AC_CACHE_CHECK([dependency style of $depcc], fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) - # This compiler won't grok `-c -o', but also, the minuso test has + # This compiler won't grok '-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} @@ -435,7 +426,7 @@ AM_CONDITIONAL([am__fastdep$1], [ # AM_SET_DEPDIR # ------------- # Choose a directory name for dependency files. -# This macro is AC_REQUIREd in _AM_DEPENDENCIES +# This macro is AC_REQUIREd in _AM_DEPENDENCIES. AC_DEFUN([AM_SET_DEPDIR], [AC_REQUIRE([AM_SET_LEADING_DOT])dnl AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl @@ -445,9 +436,13 @@ AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl # AM_DEP_TRACK # ------------ AC_DEFUN([AM_DEP_TRACK], -[AC_ARG_ENABLE(dependency-tracking, -[ --disable-dependency-tracking speeds up one-time build - --enable-dependency-tracking do not reject slow dependency extractors]) +[AC_ARG_ENABLE([dependency-tracking], [dnl +AS_HELP_STRING( + [--enable-dependency-tracking], + [do not reject slow dependency extractors]) +AS_HELP_STRING( + [--disable-dependency-tracking], + [speeds up one-time build])]) if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' @@ -462,20 +457,18 @@ _AM_SUBST_NOTMAKE([am__nodep])dnl # Generate code to set up dependency tracking. -*- Autoconf -*- -# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2008 -# Free Software Foundation, Inc. +# Copyright (C) 1999-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -#serial 5 # _AM_OUTPUT_DEPENDENCY_COMMANDS # ------------------------------ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], [{ - # Autoconf 2.62 quotes --file arguments for eval, but not when files + # Older Autoconf quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. case $CONFIG_FILES in @@ -488,7 +481,7 @@ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], # Strip MF so we end up with the name of the file. mf=`echo "$mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile or not. - # We used to match only the files named `Makefile.in', but + # We used to match only the files named 'Makefile.in', but # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. @@ -500,21 +493,19 @@ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], continue fi # Extract the definition of DEPDIR, am__include, and am__quote - # from the Makefile without running `make'. + # from the Makefile without running 'make'. DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` test -z "$DEPDIR" && continue am__include=`sed -n 's/^am__include = //p' < "$mf"` - test -z "am__include" && continue + test -z "$am__include" && continue am__quote=`sed -n 's/^am__quote = //p' < "$mf"` - # When using ansi2knr, U may be empty or an underscore; expand it - U=`sed -n 's/^U = //p' < "$mf"` # Find all dependency output files, they are included files with # $(DEPDIR) in their names. We invoke sed twice because it is the # simplest approach to changing $(DEPDIR) to its actual value in the # expansion. for file in `sed -n " s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ - sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue fdir=`AS_DIRNAME(["$file"])` @@ -532,7 +523,7 @@ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], # This macro should only be invoked once -- use via AC_REQUIRE. # # This code is only required when automatic dependency tracking -# is enabled. FIXME. This creates each `.P' file that we will +# is enabled. FIXME. This creates each '.P' file that we will # need in order to bootstrap the dependency handling code. AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], [AC_CONFIG_COMMANDS([depfiles], @@ -542,15 +533,12 @@ AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], # Do all the work for Automake. -*- Autoconf -*- -# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, -# 2005, 2006, 2008, 2009 Free Software Foundation, Inc. +# Copyright (C) 1996-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 16 - # This macro actually does too much. Some checks are only needed if # your package does certain things. But this isn't really a big deal. @@ -566,7 +554,7 @@ AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], # arguments mandatory, and then we can depend on a new Autoconf # release and drop the old call support. AC_DEFUN([AM_INIT_AUTOMAKE], -[AC_PREREQ([2.62])dnl +[AC_PREREQ([2.65])dnl dnl Autoconf wants to disallow AM_ names. We explicitly allow dnl the ones we care about. m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl @@ -595,31 +583,40 @@ AC_SUBST([CYGPATH_W]) # Define the identity of the package. dnl Distinguish between old-style and new-style calls. m4_ifval([$2], -[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl +[AC_DIAGNOSE([obsolete], + [$0: two- and three-arguments forms are deprecated.]) +m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl AC_SUBST([PACKAGE], [$1])dnl AC_SUBST([VERSION], [$2])], [_AM_SET_OPTIONS([$1])dnl dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. -m4_if(m4_ifdef([AC_PACKAGE_NAME], 1)m4_ifdef([AC_PACKAGE_VERSION], 1), 11,, +m4_if( + m4_ifdef([AC_PACKAGE_NAME], [ok]):m4_ifdef([AC_PACKAGE_VERSION], [ok]), + [ok:ok],, [m4_fatal([AC_INIT should be called with package and version arguments])])dnl AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl _AM_IF_OPTION([no-define],, -[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) - AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl +[AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package]) + AC_DEFINE_UNQUOTED([VERSION], ["$VERSION"], [Version number of package])])dnl # Some tools Automake needs. AC_REQUIRE([AM_SANITY_CHECK])dnl AC_REQUIRE([AC_ARG_PROGRAM])dnl -AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version}) -AM_MISSING_PROG(AUTOCONF, autoconf) -AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version}) -AM_MISSING_PROG(AUTOHEADER, autoheader) -AM_MISSING_PROG(MAKEINFO, makeinfo) +AM_MISSING_PROG([ACLOCAL], [aclocal-${am__api_version}]) +AM_MISSING_PROG([AUTOCONF], [autoconf]) +AM_MISSING_PROG([AUTOMAKE], [automake-${am__api_version}]) +AM_MISSING_PROG([AUTOHEADER], [autoheader]) +AM_MISSING_PROG([MAKEINFO], [makeinfo]) AC_REQUIRE([AM_PROG_INSTALL_SH])dnl AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl -AC_REQUIRE([AM_PROG_MKDIR_P])dnl +AC_REQUIRE([AC_PROG_MKDIR_P])dnl +# For better backward compatibility. To be removed once Automake 1.9.x +# dies out for good. For more background, see: +# +# +AC_SUBST([mkdir_p], ['$(MKDIR_P)']) # We need awk for the "check" target. The system "awk" is bad on # some platforms. AC_REQUIRE([AC_PROG_AWK])dnl @@ -630,28 +627,32 @@ _AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], [_AM_PROG_TAR([v7])])]) _AM_IF_OPTION([no-dependencies],, [AC_PROVIDE_IFELSE([AC_PROG_CC], - [_AM_DEPENDENCIES(CC)], - [define([AC_PROG_CC], - defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl + [_AM_DEPENDENCIES([CC])], + [m4_define([AC_PROG_CC], + m4_defn([AC_PROG_CC])[_AM_DEPENDENCIES([CC])])])dnl AC_PROVIDE_IFELSE([AC_PROG_CXX], - [_AM_DEPENDENCIES(CXX)], - [define([AC_PROG_CXX], - defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl + [_AM_DEPENDENCIES([CXX])], + [m4_define([AC_PROG_CXX], + m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl AC_PROVIDE_IFELSE([AC_PROG_OBJC], - [_AM_DEPENDENCIES(OBJC)], - [define([AC_PROG_OBJC], - defn([AC_PROG_OBJC])[_AM_DEPENDENCIES(OBJC)])])dnl + [_AM_DEPENDENCIES([OBJC])], + [m4_define([AC_PROG_OBJC], + m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl +AC_PROVIDE_IFELSE([AC_PROG_OBJCXX], + [_AM_DEPENDENCIES([OBJCXX])], + [m4_define([AC_PROG_OBJCXX], + m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl ]) -_AM_IF_OPTION([silent-rules], [AC_REQUIRE([AM_SILENT_RULES])])dnl -dnl The `parallel-tests' driver may need to know about EXEEXT, so add the -dnl `am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This macro -dnl is hooked onto _AC_COMPILER_EXEEXT early, see below. +AC_REQUIRE([AM_SILENT_RULES])dnl +dnl The testsuite driver may need to know about EXEEXT, so add the +dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This +dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below. AC_CONFIG_COMMANDS_PRE(dnl [m4_provide_if([_AM_COMPILER_EXEEXT], [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl ]) -dnl Hook into `_AC_COMPILER_EXEEXT' early to learn its expansion. Do not +dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further dnl mangled by Autoconf and run in a shell conditional statement. m4_define([_AC_COMPILER_EXEEXT], @@ -679,15 +680,12 @@ for _am_header in $config_headers :; do done echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) -# Copyright (C) 2001, 2003, 2005, 2008, 2011 Free Software Foundation, -# Inc. +# Copyright (C) 2001-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 1 - # AM_PROG_INSTALL_SH # ------------------ # Define $install_sh. @@ -701,16 +699,14 @@ if test x"${install_sh}" != xset; then install_sh="\${SHELL} $am_aux_dir/install-sh" esac fi -AC_SUBST(install_sh)]) +AC_SUBST([install_sh])]) -# Copyright (C) 2003, 2005 Free Software Foundation, Inc. +# Copyright (C) 2003-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 2 - # Check whether the underlying file-system supports filenames # with a leading dot. For instance MS-DOS doesn't. AC_DEFUN([AM_SET_LEADING_DOT], @@ -724,56 +720,14 @@ fi rmdir .tst 2>/dev/null AC_SUBST([am__leading_dot])]) -# Add --enable-maintainer-mode option to configure. -*- Autoconf -*- -# From Jim Meyering - -# Copyright (C) 1996, 1998, 2000, 2001, 2002, 2003, 2004, 2005, 2008, -# 2011 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# serial 5 - -# AM_MAINTAINER_MODE([DEFAULT-MODE]) -# ---------------------------------- -# Control maintainer-specific portions of Makefiles. -# Default is to disable them, unless `enable' is passed literally. -# For symmetry, `disable' may be passed as well. Anyway, the user -# can override the default with the --enable/--disable switch. -AC_DEFUN([AM_MAINTAINER_MODE], -[m4_case(m4_default([$1], [disable]), - [enable], [m4_define([am_maintainer_other], [disable])], - [disable], [m4_define([am_maintainer_other], [enable])], - [m4_define([am_maintainer_other], [enable]) - m4_warn([syntax], [unexpected argument to AM@&t@_MAINTAINER_MODE: $1])]) -AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles]) - dnl maintainer-mode's default is 'disable' unless 'enable' is passed - AC_ARG_ENABLE([maintainer-mode], -[ --][am_maintainer_other][-maintainer-mode am_maintainer_other make rules and dependencies not useful - (and sometimes confusing) to the casual installer], - [USE_MAINTAINER_MODE=$enableval], - [USE_MAINTAINER_MODE=]m4_if(am_maintainer_other, [enable], [no], [yes])) - AC_MSG_RESULT([$USE_MAINTAINER_MODE]) - AM_CONDITIONAL([MAINTAINER_MODE], [test $USE_MAINTAINER_MODE = yes]) - MAINT=$MAINTAINER_MODE_TRUE - AC_SUBST([MAINT])dnl -] -) - -AU_DEFUN([jm_MAINTAINER_MODE], [AM_MAINTAINER_MODE]) - # Check to see how 'make' treats includes. -*- Autoconf -*- -# Copyright (C) 2001, 2002, 2003, 2005, 2009 Free Software Foundation, Inc. +# Copyright (C) 2001-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 4 - # AM_MAKE_INCLUDE() # ----------------- # Check to see how make treats includes. @@ -791,7 +745,7 @@ am__quote= _am_result=none # First try GNU make style include. echo "include confinc" > confmf -# Ignore all kinds of additional output from `make'. +# Ignore all kinds of additional output from 'make'. case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=include @@ -816,16 +770,45 @@ AC_MSG_RESULT([$_am_result]) rm -f confinc confmf ]) -# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- - -# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2004, 2005, 2008 -# Free Software Foundation, Inc. +# Copyright (C) 1999-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 6 +# AM_PROG_CC_C_O +# -------------- +# Like AC_PROG_CC_C_O, but changed for automake. +AC_DEFUN([AM_PROG_CC_C_O], +[AC_REQUIRE([AC_PROG_CC_C_O])dnl +AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +AC_REQUIRE_AUX_FILE([compile])dnl +# FIXME: we rely on the cache variable name because +# there is no other way. +set dummy $CC +am_cc=`echo $[2] | sed ['s/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/']` +eval am_t=\$ac_cv_prog_cc_${am_cc}_c_o +if test "$am_t" != yes; then + # Losing compiler, so override with the script. + # FIXME: It is wrong to rewrite CC. + # But if we don't then we get into trouble of one sort or another. + # A longer-term fix would be to have automake use am__CC in this case, + # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" + CC="$am_aux_dir/compile $CC" +fi +dnl Make sure AC_PROG_CC is never called again, or it will override our +dnl setting of CC. +m4_define([AC_PROG_CC], + [m4_fatal([AC_PROG_CC cannot be called after AM_PROG_CC_C_O])]) +]) + +# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- + +# Copyright (C) 1997-2013 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. # AM_MISSING_PROG(NAME, PROGRAM) # ------------------------------ @@ -834,11 +817,10 @@ AC_DEFUN([AM_MISSING_PROG], $1=${$1-"${am_missing_run}$2"} AC_SUBST($1)]) - # AM_MISSING_HAS_RUN # ------------------ -# Define MISSING if not defined so far and test if it supports --run. -# If it does, set am_missing_run to use it, otherwise, to nothing. +# Define MISSING if not defined so far and test if it is modern enough. +# If it is, set am_missing_run to use it, otherwise, to nothing. AC_DEFUN([AM_MISSING_HAS_RUN], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([missing])dnl @@ -851,54 +833,22 @@ if test x"${MISSING+set}" != xset; then esac fi # Use eval to expand $SHELL -if eval "$MISSING --run true"; then - am_missing_run="$MISSING --run " +if eval "$MISSING --is-lightweight"; then + am_missing_run="$MISSING " else am_missing_run= - AC_MSG_WARN([`missing' script is too old or missing]) + AC_MSG_WARN(['missing' script is too old or missing]) fi ]) -# Copyright (C) 2003, 2004, 2005, 2006, 2011 Free Software Foundation, -# Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# serial 1 - -# AM_PROG_MKDIR_P -# --------------- -# Check for `mkdir -p'. -AC_DEFUN([AM_PROG_MKDIR_P], -[AC_PREREQ([2.60])dnl -AC_REQUIRE([AC_PROG_MKDIR_P])dnl -dnl Automake 1.8 to 1.9.6 used to define mkdir_p. We now use MKDIR_P, -dnl while keeping a definition of mkdir_p for backward compatibility. -dnl @MKDIR_P@ is magic: AC_OUTPUT adjusts its value for each Makefile. -dnl However we cannot define mkdir_p as $(MKDIR_P) for the sake of -dnl Makefile.ins that do not define MKDIR_P, so we do our own -dnl adjustment using top_builddir (which is defined more often than -dnl MKDIR_P). -AC_SUBST([mkdir_p], ["$MKDIR_P"])dnl -case $mkdir_p in - [[\\/$]]* | ?:[[\\/]]*) ;; - */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; -esac -]) - # Helper functions for option handling. -*- Autoconf -*- -# Copyright (C) 2001, 2002, 2003, 2005, 2008, 2010 Free Software -# Foundation, Inc. +# Copyright (C) 2001-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 5 - # _AM_MANGLE_OPTION(NAME) # ----------------------- AC_DEFUN([_AM_MANGLE_OPTION], @@ -908,7 +858,7 @@ AC_DEFUN([_AM_MANGLE_OPTION], # -------------------- # Set option NAME. Presently that only means defining a flag for this option. AC_DEFUN([_AM_SET_OPTION], -[m4_define(_AM_MANGLE_OPTION([$1]), 1)]) +[m4_define(_AM_MANGLE_OPTION([$1]), [1])]) # _AM_SET_OPTIONS(OPTIONS) # ------------------------ @@ -924,22 +874,16 @@ AC_DEFUN([_AM_IF_OPTION], # Check to make sure that the build environment is sane. -*- Autoconf -*- -# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005, 2008 -# Free Software Foundation, Inc. +# Copyright (C) 1996-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 5 - # AM_SANITY_CHECK # --------------- AC_DEFUN([AM_SANITY_CHECK], [AC_MSG_CHECKING([whether build environment is sane]) -# Just in case -sleep 1 -echo timestamp > conftest.file # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' @@ -950,32 +894,40 @@ case `pwd` in esac case $srcdir in *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) - AC_MSG_ERROR([unsafe srcdir value: `$srcdir']);; + AC_MSG_ERROR([unsafe srcdir value: '$srcdir']);; esac -# Do `set' in a subshell so we don't clobber the current shell's +# Do 'set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( - set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` - if test "$[*]" = "X"; then - # -L didn't work. - set X `ls -t "$srcdir/configure" conftest.file` - fi - rm -f conftest.file - if test "$[*]" != "X $srcdir/configure conftest.file" \ - && test "$[*]" != "X conftest.file $srcdir/configure"; then - - # If neither matched, then we have a broken ls. This can happen - # if, for instance, CONFIG_SHELL is bash and it inherits a - # broken ls alias from the environment. This has actually - # happened. Such a system could not be considered "sane". - AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken -alias in your environment]) - fi + am_has_slept=no + for am_try in 1 2; do + echo "timestamp, slept: $am_has_slept" > conftest.file + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$[*]" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + if test "$[*]" != "X $srcdir/configure conftest.file" \ + && test "$[*]" != "X conftest.file $srcdir/configure"; then + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken + alias in your environment]) + fi + if test "$[2]" = conftest.file || test $am_try -eq 2; then + break + fi + # Just in case. + sleep 1 + am_has_slept=yes + done test "$[2]" = conftest.file ) then @@ -985,46 +937,118 @@ else AC_MSG_ERROR([newly created file is older than distributed files! Check your system clock]) fi -AC_MSG_RESULT(yes)]) +AC_MSG_RESULT([yes]) +# If we didn't sleep, we still need to ensure time stamps of config.status and +# generated files are strictly newer. +am_sleep_pid= +if grep 'slept: no' conftest.file >/dev/null 2>&1; then + ( sleep 1 ) & + am_sleep_pid=$! +fi +AC_CONFIG_COMMANDS_PRE( + [AC_MSG_CHECKING([that generated files are newer than configure]) + if test -n "$am_sleep_pid"; then + # Hide warnings about reused PIDs. + wait $am_sleep_pid 2>/dev/null + fi + AC_MSG_RESULT([done])]) +rm -f conftest.file +]) -# Copyright (C) 2001, 2003, 2005, 2011 Free Software Foundation, Inc. +# Copyright (C) 2009-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 1 +# AM_SILENT_RULES([DEFAULT]) +# -------------------------- +# Enable less verbose build rules; with the default set to DEFAULT +# ("yes" being less verbose, "no" or empty being verbose). +AC_DEFUN([AM_SILENT_RULES], +[AC_ARG_ENABLE([silent-rules], [dnl +AS_HELP_STRING( + [--enable-silent-rules], + [less verbose build output (undo: "make V=1")]) +AS_HELP_STRING( + [--disable-silent-rules], + [verbose build output (undo: "make V=0")])dnl +]) +case $enable_silent_rules in @%:@ ((( + yes) AM_DEFAULT_VERBOSITY=0;; + no) AM_DEFAULT_VERBOSITY=1;; + *) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);; +esac +dnl +dnl A few 'make' implementations (e.g., NonStop OS and NextStep) +dnl do not support nested variable expansions. +dnl See automake bug#9928 and bug#10237. +am_make=${MAKE-make} +AC_CACHE_CHECK([whether $am_make supports nested variables], + [am_cv_make_support_nested_variables], + [if AS_ECHO([['TRUE=$(BAR$(V)) +BAR0=false +BAR1=true +V=1 +am__doit: + @$(TRUE) +.PHONY: am__doit']]) | $am_make -f - >/dev/null 2>&1; then + am_cv_make_support_nested_variables=yes +else + am_cv_make_support_nested_variables=no +fi]) +if test $am_cv_make_support_nested_variables = yes; then + dnl Using '$V' instead of '$(V)' breaks IRIX make. + AM_V='$(V)' + AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' +else + AM_V=$AM_DEFAULT_VERBOSITY + AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY +fi +AC_SUBST([AM_V])dnl +AM_SUBST_NOTMAKE([AM_V])dnl +AC_SUBST([AM_DEFAULT_V])dnl +AM_SUBST_NOTMAKE([AM_DEFAULT_V])dnl +AC_SUBST([AM_DEFAULT_VERBOSITY])dnl +AM_BACKSLASH='\' +AC_SUBST([AM_BACKSLASH])dnl +_AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl +]) + +# Copyright (C) 2001-2013 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. # AM_PROG_INSTALL_STRIP # --------------------- -# One issue with vendor `install' (even GNU) is that you can't +# One issue with vendor 'install' (even GNU) is that you can't # specify the program used to strip binaries. This is especially # annoying in cross-compiling environments, where the build's strip # is unlikely to handle the host's binaries. # Fortunately install-sh will honor a STRIPPROG variable, so we -# always use install-sh in `make install-strip', and initialize +# always use install-sh in "make install-strip", and initialize # STRIPPROG with the value of the STRIP variable (set by the user). AC_DEFUN([AM_PROG_INSTALL_STRIP], [AC_REQUIRE([AM_PROG_INSTALL_SH])dnl -# Installed binaries are usually stripped using `strip' when the user -# run `make install-strip'. However `strip' might not be the right +# Installed binaries are usually stripped using 'strip' when the user +# run "make install-strip". However 'strip' might not be the right # tool to use in cross-compilation environments, therefore Automake -# will honor the `STRIP' environment variable to overrule this program. -dnl Don't test for $cross_compiling = yes, because it might be `maybe'. +# will honor the 'STRIP' environment variable to overrule this program. +dnl Don't test for $cross_compiling = yes, because it might be 'maybe'. if test "$cross_compiling" != no; then AC_CHECK_TOOL([STRIP], [strip], :) fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" AC_SUBST([INSTALL_STRIP_PROGRAM])]) -# Copyright (C) 2006, 2008, 2010 Free Software Foundation, Inc. +# Copyright (C) 2006-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 3 - # _AM_SUBST_NOTMAKE(VARIABLE) # --------------------------- # Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. @@ -1038,18 +1062,16 @@ AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) # Check how to create a tarball. -*- Autoconf -*- -# Copyright (C) 2004, 2005, 2012 Free Software Foundation, Inc. +# Copyright (C) 2004-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 2 - # _AM_PROG_TAR(FORMAT) # -------------------- # Check how to create a tarball in format FORMAT. -# FORMAT should be one of `v7', `ustar', or `pax'. +# FORMAT should be one of 'v7', 'ustar', or 'pax'. # # Substitute a variable $(am__tar) that is a command # writing to stdout a FORMAT-tarball containing the directory @@ -1059,76 +1081,114 @@ AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) # Substitute a variable $(am__untar) that extract such # a tarball read from stdin. # $(am__untar) < result.tar +# AC_DEFUN([_AM_PROG_TAR], [# Always define AMTAR for backward compatibility. Yes, it's still used # in the wild :-( We should find a proper way to deprecate it ... AC_SUBST([AMTAR], ['$${TAR-tar}']) -m4_if([$1], [v7], - [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'], - [m4_case([$1], [ustar],, [pax],, - [m4_fatal([Unknown tar format])]) -AC_MSG_CHECKING([how to create a $1 tar archive]) -# Loop over all known methods to create a tar archive until one works. + +# We'll loop over all known methods to create a tar archive until one works. _am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' -_am_tools=${am_cv_prog_tar_$1-$_am_tools} -# Do not fold the above two line into one, because Tru64 sh and -# Solaris sh will not grok spaces in the rhs of `-'. -for _am_tool in $_am_tools -do - case $_am_tool in - gnutar) - for _am_tar in tar gnutar gtar; - do - AM_RUN_LOG([$_am_tar --version]) && break - done - am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' - am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' - am__untar="$_am_tar -xf -" - ;; - plaintar) - # Must skip GNU tar: if it does not support --format= it doesn't create - # ustar tarball either. - (tar --version) >/dev/null 2>&1 && continue - am__tar='tar chf - "$$tardir"' - am__tar_='tar chf - "$tardir"' - am__untar='tar xf -' - ;; - pax) - am__tar='pax -L -x $1 -w "$$tardir"' - am__tar_='pax -L -x $1 -w "$tardir"' - am__untar='pax -r' - ;; - cpio) - am__tar='find "$$tardir" -print | cpio -o -H $1 -L' - am__tar_='find "$tardir" -print | cpio -o -H $1 -L' - am__untar='cpio -i -H $1 -d' - ;; - none) - am__tar=false - am__tar_=false - am__untar=false - ;; - esac - # If the value was cached, stop now. We just wanted to have am__tar - # and am__untar set. - test -n "${am_cv_prog_tar_$1}" && break +m4_if([$1], [v7], + [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'], - # tar/untar a dummy directory, and stop if the command works + [m4_case([$1], + [ustar], + [# The POSIX 1988 'ustar' format is defined with fixed-size fields. + # There is notably a 21 bits limit for the UID and the GID. In fact, + # the 'pax' utility can hang on bigger UID/GID (see automake bug#8343 + # and bug#13588). + am_max_uid=2097151 # 2^21 - 1 + am_max_gid=$am_max_uid + # The $UID and $GID variables are not portable, so we need to resort + # to the POSIX-mandated id(1) utility. Errors in the 'id' calls + # below are definitely unexpected, so allow the users to see them + # (that is, avoid stderr redirection). + am_uid=`id -u || echo unknown` + am_gid=`id -g || echo unknown` + AC_MSG_CHECKING([whether UID '$am_uid' is supported by ustar format]) + if test $am_uid -le $am_max_uid; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + _am_tools=none + fi + AC_MSG_CHECKING([whether GID '$am_gid' is supported by ustar format]) + if test $am_gid -le $am_max_gid; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + _am_tools=none + fi], + + [pax], + [], + + [m4_fatal([Unknown tar format])]) + + AC_MSG_CHECKING([how to create a $1 tar archive]) + + # Go ahead even if we have the value already cached. We do so because we + # need to set the values for the 'am__tar' and 'am__untar' variables. + _am_tools=${am_cv_prog_tar_$1-$_am_tools} + + for _am_tool in $_am_tools; do + case $_am_tool in + gnutar) + for _am_tar in tar gnutar gtar; do + AM_RUN_LOG([$_am_tar --version]) && break + done + am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' + am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' + am__untar="$_am_tar -xf -" + ;; + plaintar) + # Must skip GNU tar: if it does not support --format= it doesn't create + # ustar tarball either. + (tar --version) >/dev/null 2>&1 && continue + am__tar='tar chf - "$$tardir"' + am__tar_='tar chf - "$tardir"' + am__untar='tar xf -' + ;; + pax) + am__tar='pax -L -x $1 -w "$$tardir"' + am__tar_='pax -L -x $1 -w "$tardir"' + am__untar='pax -r' + ;; + cpio) + am__tar='find "$$tardir" -print | cpio -o -H $1 -L' + am__tar_='find "$tardir" -print | cpio -o -H $1 -L' + am__untar='cpio -i -H $1 -d' + ;; + none) + am__tar=false + am__tar_=false + am__untar=false + ;; + esac + + # If the value was cached, stop now. We just wanted to have am__tar + # and am__untar set. + test -n "${am_cv_prog_tar_$1}" && break + + # tar/untar a dummy directory, and stop if the command works. + rm -rf conftest.dir + mkdir conftest.dir + echo GrepMe > conftest.dir/file + AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) + rm -rf conftest.dir + if test -s conftest.tar; then + AM_RUN_LOG([$am__untar /dev/null 2>&1 && break + fi + done rm -rf conftest.dir - mkdir conftest.dir - echo GrepMe > conftest.dir/file - AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) - rm -rf conftest.dir - if test -s conftest.tar; then - AM_RUN_LOG([$am__untar /dev/null 2>&1 && break - fi -done -rm -rf conftest.dir -AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) -AC_MSG_RESULT([$am_cv_prog_tar_$1])]) + AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) + AC_MSG_RESULT([$am_cv_prog_tar_$1])]) + AC_SUBST([am__tar]) AC_SUBST([am__untar]) ]) # _AM_PROG_TAR diff --git a/compile b/compile new file mode 100755 index 0000000..531136b --- /dev/null +++ b/compile @@ -0,0 +1,347 @@ +#! /bin/sh +# Wrapper for compilers which do not understand '-c -o'. + +scriptversion=2012-10-14.11; # UTC + +# Copyright (C) 1999-2013 Free Software Foundation, Inc. +# Written by Tom Tromey . +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# This file is maintained in Automake, please report +# bugs to or send patches to +# . + +nl=' +' + +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent tools from complaining about whitespace usage. +IFS=" "" $nl" + +file_conv= + +# func_file_conv build_file lazy +# Convert a $build file to $host form and store it in $file +# Currently only supports Windows hosts. If the determined conversion +# type is listed in (the comma separated) LAZY, no conversion will +# take place. +func_file_conv () +{ + file=$1 + case $file in + / | /[!/]*) # absolute file, and not a UNC file + if test -z "$file_conv"; then + # lazily determine how to convert abs files + case `uname -s` in + MINGW*) + file_conv=mingw + ;; + CYGWIN*) + file_conv=cygwin + ;; + *) + file_conv=wine + ;; + esac + fi + case $file_conv/,$2, in + *,$file_conv,*) + ;; + mingw/*) + file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'` + ;; + cygwin/*) + file=`cygpath -m "$file" || echo "$file"` + ;; + wine/*) + file=`winepath -w "$file" || echo "$file"` + ;; + esac + ;; + esac +} + +# func_cl_dashL linkdir +# Make cl look for libraries in LINKDIR +func_cl_dashL () +{ + func_file_conv "$1" + if test -z "$lib_path"; then + lib_path=$file + else + lib_path="$lib_path;$file" + fi + linker_opts="$linker_opts -LIBPATH:$file" +} + +# func_cl_dashl library +# Do a library search-path lookup for cl +func_cl_dashl () +{ + lib=$1 + found=no + save_IFS=$IFS + IFS=';' + for dir in $lib_path $LIB + do + IFS=$save_IFS + if $shared && test -f "$dir/$lib.dll.lib"; then + found=yes + lib=$dir/$lib.dll.lib + break + fi + if test -f "$dir/$lib.lib"; then + found=yes + lib=$dir/$lib.lib + break + fi + if test -f "$dir/lib$lib.a"; then + found=yes + lib=$dir/lib$lib.a + break + fi + done + IFS=$save_IFS + + if test "$found" != yes; then + lib=$lib.lib + fi +} + +# func_cl_wrapper cl arg... +# Adjust compile command to suit cl +func_cl_wrapper () +{ + # Assume a capable shell + lib_path= + shared=: + linker_opts= + for arg + do + if test -n "$eat"; then + eat= + else + case $1 in + -o) + # configure might choose to run compile as 'compile cc -o foo foo.c'. + eat=1 + case $2 in + *.o | *.[oO][bB][jJ]) + func_file_conv "$2" + set x "$@" -Fo"$file" + shift + ;; + *) + func_file_conv "$2" + set x "$@" -Fe"$file" + shift + ;; + esac + ;; + -I) + eat=1 + func_file_conv "$2" mingw + set x "$@" -I"$file" + shift + ;; + -I*) + func_file_conv "${1#-I}" mingw + set x "$@" -I"$file" + shift + ;; + -l) + eat=1 + func_cl_dashl "$2" + set x "$@" "$lib" + shift + ;; + -l*) + func_cl_dashl "${1#-l}" + set x "$@" "$lib" + shift + ;; + -L) + eat=1 + func_cl_dashL "$2" + ;; + -L*) + func_cl_dashL "${1#-L}" + ;; + -static) + shared=false + ;; + -Wl,*) + arg=${1#-Wl,} + save_ifs="$IFS"; IFS=',' + for flag in $arg; do + IFS="$save_ifs" + linker_opts="$linker_opts $flag" + done + IFS="$save_ifs" + ;; + -Xlinker) + eat=1 + linker_opts="$linker_opts $2" + ;; + -*) + set x "$@" "$1" + shift + ;; + *.cc | *.CC | *.cxx | *.CXX | *.[cC]++) + func_file_conv "$1" + set x "$@" -Tp"$file" + shift + ;; + *.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO]) + func_file_conv "$1" mingw + set x "$@" "$file" + shift + ;; + *) + set x "$@" "$1" + shift + ;; + esac + fi + shift + done + if test -n "$linker_opts"; then + linker_opts="-link$linker_opts" + fi + exec "$@" $linker_opts + exit 1 +} + +eat= + +case $1 in + '') + echo "$0: No command. Try '$0 --help' for more information." 1>&2 + exit 1; + ;; + -h | --h*) + cat <<\EOF +Usage: compile [--help] [--version] PROGRAM [ARGS] + +Wrapper for compilers which do not understand '-c -o'. +Remove '-o dest.o' from ARGS, run PROGRAM with the remaining +arguments, and rename the output as expected. + +If you are trying to build a whole package this is not the +right script to run: please start by reading the file 'INSTALL'. + +Report bugs to . +EOF + exit $? + ;; + -v | --v*) + echo "compile $scriptversion" + exit $? + ;; + cl | *[/\\]cl | cl.exe | *[/\\]cl.exe ) + func_cl_wrapper "$@" # Doesn't return... + ;; +esac + +ofile= +cfile= + +for arg +do + if test -n "$eat"; then + eat= + else + case $1 in + -o) + # configure might choose to run compile as 'compile cc -o foo foo.c'. + # So we strip '-o arg' only if arg is an object. + eat=1 + case $2 in + *.o | *.obj) + ofile=$2 + ;; + *) + set x "$@" -o "$2" + shift + ;; + esac + ;; + *.c) + cfile=$1 + set x "$@" "$1" + shift + ;; + *) + set x "$@" "$1" + shift + ;; + esac + fi + shift +done + +if test -z "$ofile" || test -z "$cfile"; then + # If no '-o' option was seen then we might have been invoked from a + # pattern rule where we don't need one. That is ok -- this is a + # normal compilation that the losing compiler can handle. If no + # '.c' file was seen then we are probably linking. That is also + # ok. + exec "$@" +fi + +# Name of file we expect compiler to create. +cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'` + +# Create the lock directory. +# Note: use '[/\\:.-]' here to ensure that we don't use the same name +# that we are using for the .o file. Also, base the name on the expected +# object file name, since that is what matters with a parallel build. +lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d +while true; do + if mkdir "$lockdir" >/dev/null 2>&1; then + break + fi + sleep 1 +done +# FIXME: race condition here if user kills between mkdir and trap. +trap "rmdir '$lockdir'; exit 1" 1 2 15 + +# Run the compile. +"$@" +ret=$? + +if test -f "$cofile"; then + test "$cofile" = "$ofile" || mv "$cofile" "$ofile" +elif test -f "${cofile}bj"; then + test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile" +fi + +rmdir "$lockdir" +exit $ret + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/config.guess b/config.guess index d622a44..b79252d 100755 --- a/config.guess +++ b/config.guess @@ -1,14 +1,12 @@ #! /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, 2010, -# 2011, 2012 Free Software Foundation, Inc. +# Copyright 1992-2013 Free Software Foundation, Inc. -timestamp='2012-02-10' +timestamp='2013-06-10' # 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 -# the Free Software Foundation; either version 2 of the License, or +# the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but @@ -22,19 +20,17 @@ timestamp='2012-02-10' # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - - -# Originally written by Per Bothner. Please send patches (context -# diff format) to and include a ChangeLog -# entry. +# the same distribution terms that you use for the rest of that +# program. This Exception is an additional permission under section 7 +# of the GNU General Public License, version 3 ("GPLv3"). # -# 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. +# Originally written by Per Bothner. # # 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 +# +# Please send patches with a ChangeLog entry to config-patches@gnu.org. + me=`echo "$0" | sed -e 's,.*/,,'` @@ -54,9 +50,7 @@ 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, 2009, 2010, 2011, 2012 -Free Software Foundation, Inc. +Copyright 1992-2013 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." @@ -138,6 +132,27 @@ UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown +case "${UNAME_SYSTEM}" in +Linux|GNU|GNU/*) + # If the system lacks a compiler, then just pick glibc. + # We could probably try harder. + LIBC=gnu + + eval $set_cc_for_build + cat <<-EOF > $dummy.c + #include + #if defined(__UCLIBC__) + LIBC=uclibc + #elif defined(__dietlibc__) + LIBC=dietlibc + #else + LIBC=gnu + #endif + EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'` + ;; +esac + # Note: order is significant - the case branches are not exclusive. case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in @@ -200,6 +215,10 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. echo "${machine}-${os}${release}" exit ;; + *:Bitrig:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` + echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE} + exit ;; *:OpenBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} @@ -302,7 +321,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) echo arm-acorn-riscix${UNAME_RELEASE} exit ;; - arm:riscos:*:*|arm:RISCOS:*:*) + arm*:riscos:*:*|arm*:RISCOS:*:*) echo arm-unknown-riscos exit ;; SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) @@ -801,6 +820,9 @@ EOF i*:CYGWIN*:*) echo ${UNAME_MACHINE}-pc-cygwin exit ;; + *:MINGW64*:*) + echo ${UNAME_MACHINE}-pc-mingw64 + exit ;; *:MINGW*:*) echo ${UNAME_MACHINE}-pc-mingw32 exit ;; @@ -852,21 +874,21 @@ EOF exit ;; *:GNU:*:*) # the GNU system - echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` exit ;; *:GNU/*:*:*) # other systems with GNU libc and userland - echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu + echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC} exit ;; i*86:Minix:*:*) echo ${UNAME_MACHINE}-pc-minix exit ;; aarch64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; aarch64_be:Linux:*:*) UNAME_MACHINE=aarch64_be - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; alpha:Linux:*:*) case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in @@ -879,59 +901,54 @@ EOF 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} + if test "$?" = 0 ; then LIBC="gnulibc1" ; fi + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + arc:Linux:*:* | arceb:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; arm*:Linux:*:*) eval $set_cc_for_build if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_EABI__ then - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} else if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_PCS_VFP then - echo ${UNAME_MACHINE}-unknown-linux-gnueabi + echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi else - echo ${UNAME_MACHINE}-unknown-linux-gnueabihf + echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf fi fi exit ;; avr32*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; cris:Linux:*:*) - echo ${UNAME_MACHINE}-axis-linux-gnu + echo ${UNAME_MACHINE}-axis-linux-${LIBC} exit ;; crisv32:Linux:*:*) - echo ${UNAME_MACHINE}-axis-linux-gnu + echo ${UNAME_MACHINE}-axis-linux-${LIBC} exit ;; frv:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; hexagon:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} 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}" + echo ${UNAME_MACHINE}-pc-linux-${LIBC} exit ;; ia64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; m32r*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; m68*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; mips:Linux:*:* | mips64:Linux:*:*) eval $set_cc_for_build @@ -950,54 +967,63 @@ EOF #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` - test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } + test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; } ;; + or1k:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; or32:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; padre:Linux:*:*) - echo sparc-unknown-linux-gnu + echo sparc-unknown-linux-${LIBC} exit ;; parisc64:Linux:*:* | hppa64:Linux:*:*) - echo hppa64-unknown-linux-gnu + echo hppa64-unknown-linux-${LIBC} exit ;; parisc:Linux:*:* | hppa:Linux:*:*) # Look for CPU level case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in - PA7*) echo hppa1.1-unknown-linux-gnu ;; - PA8*) echo hppa2.0-unknown-linux-gnu ;; - *) echo hppa-unknown-linux-gnu ;; + PA7*) echo hppa1.1-unknown-linux-${LIBC} ;; + PA8*) echo hppa2.0-unknown-linux-${LIBC} ;; + *) echo hppa-unknown-linux-${LIBC} ;; esac exit ;; ppc64:Linux:*:*) - echo powerpc64-unknown-linux-gnu + echo powerpc64-unknown-linux-${LIBC} exit ;; ppc:Linux:*:*) - echo powerpc-unknown-linux-gnu + echo powerpc-unknown-linux-${LIBC} + exit ;; + ppc64le:Linux:*:*) + echo powerpc64le-unknown-linux-${LIBC} + exit ;; + ppcle:Linux:*:*) + echo powerpcle-unknown-linux-${LIBC} exit ;; s390:Linux:*:* | s390x:Linux:*:*) - echo ${UNAME_MACHINE}-ibm-linux + echo ${UNAME_MACHINE}-ibm-linux-${LIBC} exit ;; sh64*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; sh*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; sparc:Linux:*:* | sparc64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; tile*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; vax:Linux:*:*) - echo ${UNAME_MACHINE}-dec-linux-gnu + echo ${UNAME_MACHINE}-dec-linux-${LIBC} exit ;; x86_64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; xtensa*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; i*86:DYNIX/ptx:4*:*) # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. @@ -1201,6 +1227,9 @@ EOF BePC:Haiku:*:*) # Haiku running on Intel PC compatible. echo i586-pc-haiku exit ;; + x86_64:Haiku:*:*) + echo x86_64-unknown-haiku + exit ;; SX-4:SUPER-UX:*:*) echo sx4-nec-superux${UNAME_RELEASE} exit ;; @@ -1227,19 +1256,21 @@ EOF exit ;; *: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 + eval $set_cc_for_build + if test "$UNAME_PROCESSOR" = unknown ; then + UNAME_PROCESSOR=powerpc + fi + 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 + case $UNAME_PROCESSOR in + i386) UNAME_PROCESSOR=x86_64 ;; + powerpc) UNAME_PROCESSOR=powerpc64 ;; + esac + fi + fi echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} exit ;; *:procnto*:*:* | *:QNX:[0123456789]*:*) @@ -1256,7 +1287,7 @@ EOF NEO-?:NONSTOP_KERNEL:*:*) echo neo-tandem-nsk${UNAME_RELEASE} exit ;; - NSE-?:NONSTOP_KERNEL:*:*) + NSE-*:NONSTOP_KERNEL:*:*) echo nse-tandem-nsk${UNAME_RELEASE} exit ;; NSR-?:NONSTOP_KERNEL:*:*) @@ -1330,9 +1361,6 @@ EOF exit ;; esac -#echo '(No uname command or uname output not recognized.)' 1>&2 -#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 - eval $set_cc_for_build cat >$dummy.c <. @@ -26,11 +20,12 @@ timestamp='2012-04-18' # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. +# the same distribution terms that you use for the rest of that +# program. This Exception is an additional permission under section 7 +# of the GNU General Public License, version 3 ("GPLv3"). -# Please send patches to . Submit a context -# diff and a properly formatted GNU ChangeLog entry. +# Please send patches with a ChangeLog entry to config-patches@gnu.org. # # Configuration subroutine to validate and canonicalize a configuration type. # Supply the specified configuration type as an argument. @@ -73,9 +68,7 @@ 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, 2009, 2010, 2011, 2012 -Free Software Foundation, Inc. +Copyright 1992-2013 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." @@ -123,7 +116,7 @@ esac maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` case $maybe_os in nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ - linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ + linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ knetbsd*-gnu* | netbsd*-gnu* | \ kopensolaris*-gnu* | \ storm-chaos* | os2-emx* | rtmk-nova*) @@ -156,7 +149,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 | -microblaze) + -apple | -axis | -knuth | -cray | -microblaze*) os= basic_machine=$1 ;; @@ -259,10 +252,12 @@ case $basic_machine in | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ | am33_2.0 \ - | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \ - | be32 | be64 \ + | arc | arceb \ + | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \ + | avr | avr32 \ + | be32 | be64 \ | bfin \ - | c4x | clipper \ + | c4x | c8051 | clipper \ | d10v | d30v | dlx | dsp16xx \ | epiphany \ | fido | fr30 | frv \ @@ -273,7 +268,7 @@ case $basic_machine in | le32 | le64 \ | lm32 \ | m32c | m32r | m32rle | m68000 | m68k | m88k \ - | maxq | mb | microblaze | mcore | mep | metag \ + | maxq | mb | microblaze | microblazeel | mcore | mep | metag \ | mips | mipsbe | mipseb | mipsel | mipsle \ | mips16 \ | mips64 | mips64el \ @@ -291,16 +286,17 @@ case $basic_machine in | mipsisa64r2 | mipsisa64r2el \ | mipsisa64sb1 | mipsisa64sb1el \ | mipsisa64sr71k | mipsisa64sr71kel \ + | mipsr5900 | mipsr5900el \ | mipstx39 | mipstx39el \ | mn10200 | mn10300 \ | moxie \ | mt \ | msp430 \ | nds32 | nds32le | nds32be \ - | nios | nios2 \ + | nios | nios2 | nios2eb | nios2el \ | ns16k | ns32k \ | open8 \ - | or32 \ + | or1k | or32 \ | pdp10 | pdp11 | pj | pjl \ | powerpc | powerpc64 | powerpc64le | powerpcle \ | pyramid \ @@ -370,13 +366,13 @@ case $basic_machine in | aarch64-* | aarch64_be-* \ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ - | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ + | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ | avr-* | avr32-* \ | be32-* | be64-* \ | bfin-* | bs2000-* \ | c[123]* | c30-* | [cjt]90-* | c4x-* \ - | clipper-* | craynv-* | cydra-* \ + | c8051-* | clipper-* | craynv-* | cydra-* \ | d10v-* | d30v-* | dlx-* \ | elxsi-* \ | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ @@ -389,7 +385,8 @@ case $basic_machine in | lm32-* \ | m32c-* | m32r-* | m32rle-* \ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ - | m88110-* | m88k-* | maxq-* | mcore-* | metag-* | microblaze-* \ + | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \ + | microblaze-* | microblazeel-* \ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ | mips16-* \ | mips64-* | mips64el-* \ @@ -407,12 +404,13 @@ case $basic_machine in | mipsisa64r2-* | mipsisa64r2el-* \ | mipsisa64sb1-* | mipsisa64sb1el-* \ | mipsisa64sr71k-* | mipsisa64sr71kel-* \ + | mipsr5900-* | mipsr5900el-* \ | mipstx39-* | mipstx39el-* \ | mmix-* \ | mt-* \ | msp430-* \ | nds32-* | nds32le-* | nds32be-* \ - | nios-* | nios2-* \ + | nios-* | nios2-* | nios2eb-* | nios2el-* \ | none-* | np1-* | ns16k-* | ns32k-* \ | open8-* \ | orion-* \ @@ -788,11 +786,15 @@ case $basic_machine in basic_machine=ns32k-utek os=-sysv ;; - microblaze) + microblaze*) basic_machine=microblaze-xilinx ;; + mingw64) + basic_machine=x86_64-pc + os=-mingw64 + ;; mingw32) - basic_machine=i386-pc + basic_machine=i686-pc os=-mingw32 ;; mingw32ce) @@ -828,7 +830,7 @@ case $basic_machine in basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` ;; msys) - basic_machine=i386-pc + basic_machine=i686-pc os=-msys ;; mvs) @@ -1019,7 +1021,11 @@ case $basic_machine in basic_machine=i586-unknown os=-pw32 ;; - rdos) + rdos | rdos64) + basic_machine=x86_64-pc + os=-rdos + ;; + rdos32) basic_machine=i386-pc os=-rdos ;; @@ -1346,21 +1352,21 @@ case $os in -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ - | -sym* | -kopensolaris* \ + | -sym* | -kopensolaris* | -plan9* \ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ | -aos* | -aros* \ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ - | -openbsd* | -solidbsd* \ + | -bitrig* | -openbsd* | -solidbsd* \ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ | -chorusos* | -chorusrdb* | -cegcc* \ | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ - | -mingw32* | -linux-gnu* | -linux-android* \ - | -linux-newlib* | -linux-uclibc* \ + | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \ + | -linux-newlib* | -linux-musl* | -linux-uclibc* \ | -uxpv* | -beos* | -mpeix* | -udk* \ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ @@ -1492,9 +1498,6 @@ case $os in -aros*) os=-aros ;; - -kaos*) - os=-kaos - ;; -zvmoe) os=-zvmoe ;; @@ -1543,6 +1546,9 @@ case $basic_machine in c4x-* | tic4x-*) os=-coff ;; + c8051-*) + os=-elf + ;; hexagon-*) os=-elf ;; @@ -1586,6 +1592,9 @@ case $basic_machine in mips*-*) os=-elf ;; + or1k-*) + os=-elf + ;; or32-*) os=-coff ;; diff --git a/configure b/configure index 8c3051f..ae5c23d 100755 --- a/configure +++ b/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69. +# Generated by GNU Autoconf 2.69 for tinc 1.1pre8. # # # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. @@ -575,12 +575,12 @@ MFLAGS= MAKEFLAGS= # Identity of this package. -PACKAGE_NAME= -PACKAGE_TARNAME= -PACKAGE_VERSION= -PACKAGE_STRING= -PACKAGE_BUGREPORT= -PACKAGE_URL= +PACKAGE_NAME='tinc' +PACKAGE_TARNAME='tinc' +PACKAGE_VERSION='1.1pre8' +PACKAGE_STRING='tinc 1.1pre8' +PACKAGE_BUGREPORT='' +PACKAGE_URL='' ac_unique_file="src/tincd.c" # Factoring default headers for most tests. @@ -623,7 +623,10 @@ ac_subst_vars='am__EXEEXT_FALSE am__EXEEXT_TRUE LTLIBOBJS LIBOBJS -INCLUDES +GCRYPT_FALSE +GCRYPT_TRUE +OPENSSL_FALSE +OPENSSL_TRUE LIBGCRYPT_LIBS LIBGCRYPT_CFLAGS LIBGCRYPT_CONFIG @@ -635,6 +638,16 @@ VDE_FALSE VDE_TRUE UML_FALSE UML_TRUE +CYGWIN_FALSE +CYGWIN_TRUE +MINGW_FALSE +MINGW_TRUE +SOLARIS_FALSE +SOLARIS_TRUE +BSD_FALSE +BSD_TRUE +LINUX_FALSE +LINUX_TRUE host_os host_vendor host_cpu @@ -645,9 +658,10 @@ build_cpu build RANLIB LN_S -MAINT -MAINTAINER_MODE_FALSE -MAINTAINER_MODE_TRUE +AM_BACKSLASH +AM_DEFAULT_VERBOSITY +AM_DEFAULT_V +AM_V am__fastdepCC_FALSE am__fastdepCC_TRUE CCDEPMODE @@ -733,7 +747,7 @@ ac_subst_files='' ac_user_opts=' enable_option_checking enable_dependency_tracking -enable_maintainer_mode +enable_silent_rules enable_uml enable_vde enable_tunemu @@ -809,7 +823,7 @@ sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' includedir='${prefix}/include' oldincludedir='/usr/include' -docdir='${datarootdir}/doc/${PACKAGE}' +docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' infodir='${datarootdir}/info' htmldir='${docdir}' dvidir='${docdir}' @@ -1309,7 +1323,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures this package to adapt to many kinds of systems. +\`configure' configures tinc 1.1pre8 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1357,7 +1371,7 @@ Fine tuning of the installation directories: --infodir=DIR info documentation [DATAROOTDIR/info] --localedir=DIR locale-dependent data [DATAROOTDIR/locale] --mandir=DIR man documentation [DATAROOTDIR/man] - --docdir=DIR documentation root [DATAROOTDIR/doc/PACKAGE] + --docdir=DIR documentation root [DATAROOTDIR/doc/tinc] --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] @@ -1378,17 +1392,21 @@ _ACEOF fi if test -n "$ac_init_help"; then - + case $ac_init_help in + short | recursive ) echo "Configuration of tinc 1.1pre8:";; + esac cat <<\_ACEOF Optional Features: --disable-option-checking ignore unrecognized --enable/--with options --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] - --disable-dependency-tracking speeds up one-time build - --enable-dependency-tracking do not reject slow dependency extractors - --enable-maintainer-mode enable make rules and dependencies not useful - (and sometimes confusing) to the casual installer + --enable-dependency-tracking + do not reject slow dependency extractors + --disable-dependency-tracking + speeds up one-time build + --enable-silent-rules less verbose build output (undo: "make V=1") + --disable-silent-rules verbose build output (undo: "make V=0") --enable-uml enable support for User Mode Linux --enable-vde enable support for Virtual Distributed Ethernet --enable-tunemu enable support for the tunemu driver @@ -1502,7 +1520,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -configure +tinc configure 1.1pre8 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -1967,7 +1985,7 @@ cat >config.log <<_ACEOF 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 +It was created by tinc $as_me 1.1pre8, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -3565,7 +3583,7 @@ $as_echo "$ac_cv_safe_to_define___extensions__" >&6; } -am__api_version='1.11' +am__api_version='1.13' ac_aux_dir= for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do @@ -3691,9 +3709,6 @@ test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 $as_echo_n "checking whether build environment is sane... " >&6; } -# Just in case -sleep 1 -echo timestamp > conftest.file # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' @@ -3704,32 +3719,40 @@ case `pwd` in esac case $srcdir in *[\\\"\#\$\&\'\`$am_lf\ \ ]*) - as_fn_error $? "unsafe srcdir value: \`$srcdir'" "$LINENO" 5;; + as_fn_error $? "unsafe srcdir value: '$srcdir'" "$LINENO" 5;; esac -# Do `set' in a subshell so we don't clobber the current shell's +# Do 'set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( - set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` - if test "$*" = "X"; then - # -L didn't work. - set X `ls -t "$srcdir/configure" conftest.file` - fi - rm -f conftest.file - if test "$*" != "X $srcdir/configure conftest.file" \ - && test "$*" != "X conftest.file $srcdir/configure"; then - - # If neither matched, then we have a broken ls. This can happen - # if, for instance, CONFIG_SHELL is bash and it inherits a - # broken ls alias from the environment. This has actually - # happened. Such a system could not be considered "sane". - as_fn_error $? "ls -t appears to fail. Make sure there is not a broken -alias in your environment" "$LINENO" 5 - fi + am_has_slept=no + for am_try in 1 2; do + echo "timestamp, slept: $am_has_slept" > conftest.file + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$*" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + if test "$*" != "X $srcdir/configure conftest.file" \ + && test "$*" != "X conftest.file $srcdir/configure"; then + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + as_fn_error $? "ls -t appears to fail. Make sure there is not a broken + alias in your environment" "$LINENO" 5 + fi + if test "$2" = conftest.file || test $am_try -eq 2; then + break + fi + # Just in case. + sleep 1 + am_has_slept=yes + done test "$2" = conftest.file ) then @@ -3741,6 +3764,16 @@ Check your system clock" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } +# If we didn't sleep, we still need to ensure time stamps of config.status and +# generated files are strictly newer. +am_sleep_pid= +if grep 'slept: no' conftest.file >/dev/null 2>&1; then + ( sleep 1 ) & + am_sleep_pid=$! +fi + +rm -f conftest.file + test "$program_prefix" != NONE && program_transform_name="s&^&$program_prefix&;$program_transform_name" # Use a double $ so make ignores it. @@ -3763,12 +3796,12 @@ if test x"${MISSING+set}" != xset; then esac fi # Use eval to expand $SHELL -if eval "$MISSING --run true"; then - am_missing_run="$MISSING --run " +if eval "$MISSING --is-lightweight"; then + am_missing_run="$MISSING " else am_missing_run= - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`missing' script is too old or missing" >&5 -$as_echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5 +$as_echo "$as_me: WARNING: 'missing' script is too old or missing" >&2;} fi if test x"${install_sh}" != xset; then @@ -3780,10 +3813,10 @@ if test x"${install_sh}" != xset; then esac fi -# Installed binaries are usually stripped using `strip' when the user -# run `make install-strip'. However `strip' might not be the right +# Installed binaries are usually stripped using 'strip' when the user +# run "make install-strip". However 'strip' might not be the right # tool to use in cross-compilation environments, therefore Automake -# will honor the `STRIP' environment variable to overrule this program. +# will honor the 'STRIP' environment variable to overrule this program. if test "$cross_compiling" != no; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. @@ -3922,12 +3955,6 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 $as_echo "$MKDIR_P" >&6; } -mkdir_p="$MKDIR_P" -case $mkdir_p in - [\\/$]* | ?:[\\/]*) ;; - */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; -esac - for ac_prog in gawk mawk nawk awk do # Extract the first word of "$ac_prog", so it can be a program name with args. @@ -4029,7 +4056,7 @@ am__quote= _am_result=none # First try GNU make style include. echo "include confinc" > confmf -# Ignore all kinds of additional output from `make'. +# Ignore all kinds of additional output from 'make'. case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=include @@ -4073,6 +4100,45 @@ else fi +# Check whether --enable-silent-rules was given. +if test "${enable_silent_rules+set}" = set; then : + enableval=$enable_silent_rules; +fi + +case $enable_silent_rules in # ((( + yes) AM_DEFAULT_VERBOSITY=0;; + no) AM_DEFAULT_VERBOSITY=1;; + *) AM_DEFAULT_VERBOSITY=1;; +esac +am_make=${MAKE-make} +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 +$as_echo_n "checking whether $am_make supports nested variables... " >&6; } +if ${am_cv_make_support_nested_variables+:} false; then : + $as_echo_n "(cached) " >&6 +else + if $as_echo 'TRUE=$(BAR$(V)) +BAR0=false +BAR1=true +V=1 +am__doit: + @$(TRUE) +.PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then + am_cv_make_support_nested_variables=yes +else + am_cv_make_support_nested_variables=no +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 +$as_echo "$am_cv_make_support_nested_variables" >&6; } +if test $am_cv_make_support_nested_variables = yes; then + AM_V='$(V)' + AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' +else + AM_V=$AM_DEFAULT_VERBOSITY + AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY +fi +AM_BACKSLASH='\' + if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." @@ -4094,8 +4160,8 @@ fi # Define the identity of the package. - PACKAGE=tinc - VERSION=1.1pre7 + PACKAGE='tinc' + VERSION='1.1pre8' cat >>confdefs.h <<_ACEOF @@ -4123,17 +4189,28 @@ AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} +# For better backward compatibility. To be removed once Automake 1.9.x +# dies out for good. For more background, see: +# +# +mkdir_p='$(MKDIR_P)' + # We need awk for the "check" target. The system "awk" is bad on # some platforms. # Always define AMTAR for backward compatibility. Yes, it's still used # in the wild :-( We should find a proper way to deprecate it ... AMTAR='$${TAR-tar}' + +# We'll loop over all known methods to create a tar archive until one works. +_am_tools='gnutar pax cpio none' + am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -' + depcc="$CC" am_compiler_list= { $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 @@ -4145,8 +4222,8 @@ else # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up - # making a dummy file named `D' -- because `-MD' means `put the output - # in D'. + # making a dummy file named 'D' -- because '-MD' means "put the output + # in D". rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're @@ -4181,16 +4258,16 @@ else : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c - # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with - # Solaris 8's {/usr,}/bin/sh. - touch sub/conftst$i.h + # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with + # Solaris 10 /bin/sh. + echo '/* dummy */' > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf - # We check with `-c' and `-o' for the sake of the "dashmstdout" + # We check with '-c' and '-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly - # handle `-M -o', and we need to detect this. Also, some Intel - # versions had trouble with output in subdirs + # handle '-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs. am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in @@ -4199,8 +4276,8 @@ else test "$am__universal" = false || continue ;; nosideeffect) - # after this tag, mechanisms are not by side-effect, so they'll - # only be used when explicitly requested + # After this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested. if test "x$enable_dependency_tracking" = xyes; then continue else @@ -4208,7 +4285,7 @@ else fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) - # This compiler won't grok `-c -o', but also, the minuso test has + # This compiler won't grok '-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} @@ -4266,29 +4343,6 @@ fi ac_config_headers="$ac_config_headers config.h" -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable maintainer-specific portions of Makefiles" >&5 -$as_echo_n "checking whether to enable maintainer-specific portions of Makefiles... " >&6; } - # Check whether --enable-maintainer-mode was given. -if test "${enable_maintainer_mode+set}" = set; then : - enableval=$enable_maintainer_mode; USE_MAINTAINER_MODE=$enableval -else - USE_MAINTAINER_MODE=no -fi - - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $USE_MAINTAINER_MODE" >&5 -$as_echo "$USE_MAINTAINER_MODE" >&6; } - if test $USE_MAINTAINER_MODE = yes; then - MAINTAINER_MODE_TRUE= - MAINTAINER_MODE_FALSE='#' -else - MAINTAINER_MODE_TRUE='#' - MAINTAINER_MODE_FALSE= -fi - - MAINT=$MAINTAINER_MODE_TRUE - - - # Enable GNU extensions. # Define this here, not in acconfig's @TOP@ section, since definitions # in the latter don't make it into the configure-time tests. @@ -4716,6 +4770,133 @@ else fi +if test "x$CC" != xcc; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC and cc understand -c and -o together" >&5 +$as_echo_n "checking whether $CC and cc understand -c and -o together... " >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether cc understands -c and -o together" >&5 +$as_echo_n "checking whether cc understands -c and -o together... " >&6; } +fi +set dummy $CC; ac_cc=`$as_echo "$2" | + sed 's/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/'` +if eval \${ac_cv_prog_cc_${ac_cc}_c_o+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +# Make sure it works both with $CC and with simple cc. +# We do the test twice because some compilers refuse to overwrite an +# existing .o file with -o, though they will create one. +ac_try='$CC -c conftest.$ac_ext -o conftest2.$ac_objext >&5' +rm -f conftest2.* +if { { 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; } && + test -f conftest2.$ac_objext && { { 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 + eval ac_cv_prog_cc_${ac_cc}_c_o=yes + if test "x$CC" != xcc; then + # Test first that cc exists at all. + if { ac_try='cc -c conftest.$ac_ext >&5' + { { 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 + ac_try='cc -c conftest.$ac_ext -o conftest2.$ac_objext >&5' + rm -f conftest2.* + if { { 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; } && + test -f conftest2.$ac_objext && { { 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 + # cc works too. + : + else + # cc exists but doesn't like -o. + eval ac_cv_prog_cc_${ac_cc}_c_o=no + fi + fi + fi +else + eval ac_cv_prog_cc_${ac_cc}_c_o=no +fi +rm -f core conftest* + +fi +if eval test \$ac_cv_prog_cc_${ac_cc}_c_o = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +$as_echo "#define NO_MINUS_C_MINUS_O 1" >>confdefs.h + +fi + +# FIXME: we rely on the cache variable name because +# there is no other way. +set dummy $CC +am_cc=`echo $2 | sed 's/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/'` +eval am_t=\$ac_cv_prog_cc_${am_cc}_c_o +if test "$am_t" != yes; then + # Losing compiler, so override with the script. + # FIXME: It is wrong to rewrite CC. + # But if we don't then we get into trouble of one sort or another. + # A longer-term fix would be to have automake use am__CC in this case, + # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" + CC="$am_aux_dir/compile $CC" +fi + + + # Make sure we can run config.sub. $SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || @@ -4791,66 +4972,66 @@ case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac case $host_os in *linux*) + linux=true $as_echo "#define HAVE_LINUX 1" >>confdefs.h - rm -f src/device.c; ln -sf linux/device.c src/device.c ;; *freebsd*) + bsd=true $as_echo "#define HAVE_FREEBSD 1" >>confdefs.h - rm -f src/device.c; ln -sf bsd/device.c src/device.c ;; *darwin*) + bsd=true $as_echo "#define HAVE_DARWIN 1" >>confdefs.h - rm -f src/device.c; ln -sf bsd/device.c src/device.c ;; *solaris*) + solaris=true $as_echo "#define HAVE_SOLARIS 1" >>confdefs.h - rm -f src/device.c; ln -sf solaris/device.c src/device.c ;; *openbsd*) + bsd=true $as_echo "#define HAVE_OPENBSD 1" >>confdefs.h - rm -f src/device.c; ln -sf bsd/device.c src/device.c ;; *netbsd*) + bsd=true $as_echo "#define HAVE_NETBSD 1" >>confdefs.h - rm -f src/device.c; ln -sf bsd/device.c src/device.c ;; *dragonfly*) + bsd=true $as_echo "#define HAVE_DRAGONFLY 1" >>confdefs.h - rm -f src/device.c; ln -sf bsd/device.c src/device.c ;; *bsd*) + bsd=true { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \"Unknown BSD variant" >&5 $as_echo "$as_me: WARNING: \"Unknown BSD variant" >&2;} $as_echo "#define HAVE_BSD 1" >>confdefs.h - rm -f src/device.c; ln -sf bsd/device.c src/device.c ;; *cygwin*) + cygwin=true $as_echo "#define HAVE_CYGWIN 1" >>confdefs.h - rm -f src/device.c; ln -sf cygwin/device.c src/device.c ;; *mingw*) + mingw=true $as_echo "#define HAVE_MINGW 1" >>confdefs.h - rm -f src/device.c; cp -f src/mingw/device.c src/device.c LIBS="$LIBS -lws2_32 -lgdi32 -lcrypt32" ;; *) @@ -4939,6 +5120,46 @@ fi fi + if test "$linux" = true; then + LINUX_TRUE= + LINUX_FALSE='#' +else + LINUX_TRUE='#' + LINUX_FALSE= +fi + + if test "$bsd" = true; then + BSD_TRUE= + BSD_FALSE='#' +else + BSD_TRUE='#' + BSD_FALSE= +fi + + if test "$solaris" = true; then + SOLARIS_TRUE= + SOLARIS_FALSE='#' +else + SOLARIS_TRUE='#' + SOLARIS_FALSE= +fi + + if test "$mingw" = true; then + MINGW_TRUE= + MINGW_FALSE='#' +else + MINGW_TRUE='#' + MINGW_FALSE= +fi + + if test "$cygwin" = true; then + CYGWIN_TRUE= + CYGWIN_FALSE='#' +else + CYGWIN_TRUE='#' + CYGWIN_FALSE= +fi + if test "$uml" = true; then UML_TRUE= UML_FALSE='#' @@ -5186,7 +5407,7 @@ done for ac_header in net/if.h net/if_types.h linux/if_tun.h net/if_tun.h net/tun/if_tun.h net/if_tap.h net/tap/if_tap.h net/ethernet.h net/if_arp.h netinet/in_systm.h netinet/in.h netinet/in6.h time.h netpacket/packet.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` -ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "#include \"have.h\" +ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "#include \"src/have.h\" " if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : @@ -5201,7 +5422,7 @@ done for ac_header in netinet/if_ether.h netinet/ip.h netinet/ip6.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` -ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "#include \"have.h\" +ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "#include \"src/have.h\" " if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : @@ -5216,7 +5437,7 @@ done for ac_header in netinet/tcp.h netinet/ip_icmp.h netinet/icmp6.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` -ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "#include \"have.h\" +ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "#include \"src/have.h\" " if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : @@ -5472,7 +5693,41 @@ $as_echo "#define __malloc__ /**/" >>confdefs.h fi -ac_fn_c_check_type "$LINENO" "socklen_t" "ac_cv_type_socklen_t" "#include \"have.h\" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working __warn_unused_result__ attribute" >&5 +$as_echo_n "checking for working __warn_unused_result__ attribute... " >&6; } +if ${tinc_cv_attribute___warn_unused_result__+:} false; then : + $as_echo_n "(cached) " >&6 +else + + tempcflags="$CFLAGS" + CFLAGS="$CFLAGS -Wall -Werror" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +void test(void) __attribute__ ((__warn_unused_result__)); + void test(void) { return; } + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + tinc_cv_attribute___warn_unused_result__=yes +else + tinc_cv_attribute___warn_unused_result__=no + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + CFLAGS="$tempcflags" + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tinc_cv_attribute___warn_unused_result__" >&5 +$as_echo "$tinc_cv_attribute___warn_unused_result__" >&6; } + + if test ${tinc_cv_attribute___warn_unused_result__} = no; then + +$as_echo "#define __warn_unused_result__ /**/" >>confdefs.h + + fi + + +ac_fn_c_check_type "$LINENO" "socklen_t" "ac_cv_type_socklen_t" "#include \"src/have.h\" " if test "x$ac_cv_type_socklen_t" = xyes; then : @@ -5483,7 +5738,7 @@ _ACEOF fi -ac_fn_c_check_type "$LINENO" "struct ether_header" "ac_cv_type_struct_ether_header" "#include \"have.h\" +ac_fn_c_check_type "$LINENO" "struct ether_header" "ac_cv_type_struct_ether_header" "#include \"src/have.h\" " if test "x$ac_cv_type_struct_ether_header" = xyes; then : @@ -5494,7 +5749,7 @@ _ACEOF fi -ac_fn_c_check_type "$LINENO" "struct arphdr" "ac_cv_type_struct_arphdr" "#include \"have.h\" +ac_fn_c_check_type "$LINENO" "struct arphdr" "ac_cv_type_struct_arphdr" "#include \"src/have.h\" " if test "x$ac_cv_type_struct_arphdr" = xyes; then : @@ -5505,7 +5760,7 @@ _ACEOF fi -ac_fn_c_check_type "$LINENO" "struct ether_arp" "ac_cv_type_struct_ether_arp" "#include \"have.h\" +ac_fn_c_check_type "$LINENO" "struct ether_arp" "ac_cv_type_struct_ether_arp" "#include \"src/have.h\" " if test "x$ac_cv_type_struct_ether_arp" = xyes; then : @@ -5516,7 +5771,7 @@ _ACEOF fi -ac_fn_c_check_type "$LINENO" "struct in_addr" "ac_cv_type_struct_in_addr" "#include \"have.h\" +ac_fn_c_check_type "$LINENO" "struct in_addr" "ac_cv_type_struct_in_addr" "#include \"src/have.h\" " if test "x$ac_cv_type_struct_in_addr" = xyes; then : @@ -5527,7 +5782,7 @@ _ACEOF fi -ac_fn_c_check_type "$LINENO" "struct addrinfo" "ac_cv_type_struct_addrinfo" "#include \"have.h\" +ac_fn_c_check_type "$LINENO" "struct addrinfo" "ac_cv_type_struct_addrinfo" "#include \"src/have.h\" " if test "x$ac_cv_type_struct_addrinfo" = xyes; then : @@ -5538,7 +5793,7 @@ _ACEOF fi -ac_fn_c_check_type "$LINENO" "struct ip" "ac_cv_type_struct_ip" "#include \"have.h\" +ac_fn_c_check_type "$LINENO" "struct ip" "ac_cv_type_struct_ip" "#include \"src/have.h\" " if test "x$ac_cv_type_struct_ip" = xyes; then : @@ -5549,7 +5804,7 @@ _ACEOF fi -ac_fn_c_check_type "$LINENO" "struct icmp" "ac_cv_type_struct_icmp" "#include \"have.h\" +ac_fn_c_check_type "$LINENO" "struct icmp" "ac_cv_type_struct_icmp" "#include \"src/have.h\" " if test "x$ac_cv_type_struct_icmp" = xyes; then : @@ -5560,7 +5815,7 @@ _ACEOF fi -ac_fn_c_check_type "$LINENO" "struct in6_addr" "ac_cv_type_struct_in6_addr" "#include \"have.h\" +ac_fn_c_check_type "$LINENO" "struct in6_addr" "ac_cv_type_struct_in6_addr" "#include \"src/have.h\" " if test "x$ac_cv_type_struct_in6_addr" = xyes; then : @@ -5571,7 +5826,7 @@ _ACEOF fi -ac_fn_c_check_type "$LINENO" "struct sockaddr_in6" "ac_cv_type_struct_sockaddr_in6" "#include \"have.h\" +ac_fn_c_check_type "$LINENO" "struct sockaddr_in6" "ac_cv_type_struct_sockaddr_in6" "#include \"src/have.h\" " if test "x$ac_cv_type_struct_sockaddr_in6" = xyes; then : @@ -5582,7 +5837,7 @@ _ACEOF fi -ac_fn_c_check_type "$LINENO" "struct ip6_hdr" "ac_cv_type_struct_ip6_hdr" "#include \"have.h\" +ac_fn_c_check_type "$LINENO" "struct ip6_hdr" "ac_cv_type_struct_ip6_hdr" "#include \"src/have.h\" " if test "x$ac_cv_type_struct_ip6_hdr" = xyes; then : @@ -5593,7 +5848,7 @@ _ACEOF fi -ac_fn_c_check_type "$LINENO" "struct icmp6_hdr" "ac_cv_type_struct_icmp6_hdr" "#include \"have.h\" +ac_fn_c_check_type "$LINENO" "struct icmp6_hdr" "ac_cv_type_struct_icmp6_hdr" "#include \"src/have.h\" " if test "x$ac_cv_type_struct_icmp6_hdr" = xyes; then : @@ -5604,7 +5859,7 @@ _ACEOF fi -ac_fn_c_check_type "$LINENO" "struct nd_neighbor_solicit" "ac_cv_type_struct_nd_neighbor_solicit" "#include \"have.h\" +ac_fn_c_check_type "$LINENO" "struct nd_neighbor_solicit" "ac_cv_type_struct_nd_neighbor_solicit" "#include \"src/have.h\" " if test "x$ac_cv_type_struct_nd_neighbor_solicit" = xyes; then : @@ -5615,7 +5870,7 @@ _ACEOF fi -ac_fn_c_check_type "$LINENO" "struct nd_opt_hdr" "ac_cv_type_struct_nd_opt_hdr" "#include \"have.h\" +ac_fn_c_check_type "$LINENO" "struct nd_opt_hdr" "ac_cv_type_struct_nd_opt_hdr" "#include \"src/have.h\" " if test "x$ac_cv_type_struct_nd_opt_hdr" = xyes; then : @@ -5782,7 +6037,7 @@ fi fi -ac_fn_c_check_decl "$LINENO" "freeaddrinfo" "ac_cv_have_decl_freeaddrinfo" "#include \"have.h\" +ac_fn_c_check_decl "$LINENO" "freeaddrinfo" "ac_cv_have_decl_freeaddrinfo" "#include \"src/have.h\" " if test "x$ac_cv_have_decl_freeaddrinfo" = xyes; then : @@ -5794,7 +6049,7 @@ fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_FREEADDRINFO $ac_have_decl _ACEOF -ac_fn_c_check_decl "$LINENO" "gai_strerror" "ac_cv_have_decl_gai_strerror" "#include \"have.h\" +ac_fn_c_check_decl "$LINENO" "gai_strerror" "ac_cv_have_decl_gai_strerror" "#include \"src/have.h\" " if test "x$ac_cv_have_decl_gai_strerror" = xyes; then : @@ -5806,7 +6061,7 @@ fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_GAI_STRERROR $ac_have_decl _ACEOF -ac_fn_c_check_decl "$LINENO" "getaddrinfo" "ac_cv_have_decl_getaddrinfo" "#include \"have.h\" +ac_fn_c_check_decl "$LINENO" "getaddrinfo" "ac_cv_have_decl_getaddrinfo" "#include \"src/have.h\" " if test "x$ac_cv_have_decl_getaddrinfo" = xyes; then : @@ -5818,7 +6073,7 @@ fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_GETADDRINFO $ac_have_decl _ACEOF -ac_fn_c_check_decl "$LINENO" "getnameinfo" "ac_cv_have_decl_getnameinfo" "#include \"have.h\" +ac_fn_c_check_decl "$LINENO" "getnameinfo" "ac_cv_have_decl_getnameinfo" "#include \"src/have.h\" " if test "x$ac_cv_have_decl_getnameinfo" = xyes; then : @@ -6409,6 +6664,7 @@ fi if test "$with_libgcrypt" = yes; then + gcrypt=true # Check whether --with-libgcrypt-prefix was given. if test "${with_libgcrypt_prefix+set}" = set; then : @@ -6624,8 +6880,8 @@ $as_echo "$as_me: WARNING: - ln -sf gcrypt/cipher.c gcrypt/cipher.h gcrypt/crypto.c gcrypt/crypto.h gcrypt/digest.c gcrypt/digest.h gcrypt/ecdh.c gcrypt/ecdh.h gcrypt/ecdsa.c gcrypt/ecdsa.h gcrypt/ecdsagen.c gcrypt/ecdsagen.h gcrypt/prf.c gcrypt/prf.h gcrypt/rsa.c gcrypt/rsa.h gcrypt/rsagen.c gcrypt/rsagen.h src/ else + openssl=true case $host_os in *mingw*) @@ -6798,7 +7054,22 @@ else fi - ln -sf openssl/cipher.c openssl/cipher.h openssl/crypto.c openssl/crypto.h openssl/digest.c openssl/digest.h openssl/ecdh.c openssl/ecdh.h openssl/ecdsa.c openssl/ecdsa.h openssl/ecdsagen.c openssl/ecdsagen.h openssl/prf.c openssl/prf.h openssl/rsa.c openssl/rsa.h openssl/rsagen.c openssl/rsagen.h src/ +fi + + if test "$openssl" = true; then + OPENSSL_TRUE= + OPENSSL_FALSE='#' +else + OPENSSL_TRUE='#' + OPENSSL_FALSE= +fi + + if test "$grypt" = true; then + GCRYPT_TRUE= + GCRYPT_FALSE='#' +else + GCRYPT_TRUE='#' + GCRYPT_FALSE= fi @@ -6814,8 +7085,6 @@ fi fi - - ac_config_files="$ac_config_files Makefile src/Makefile doc/Makefile m4/Makefile gui/Makefile" @@ -6928,6 +7197,14 @@ LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5 +$as_echo_n "checking that generated files are newer than configure... " >&6; } + if test -n "$am_sleep_pid"; then + # Hide warnings about reused PIDs. + wait $am_sleep_pid 2>/dev/null + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5 +$as_echo "done" >&6; } if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then as_fn_error $? "conditional \"AMDEP\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 @@ -6944,8 +7221,24 @@ else am__EXEEXT_FALSE= fi -if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then - as_fn_error $? "conditional \"MAINTAINER_MODE\" was never defined. +if test -z "${LINUX_TRUE}" && test -z "${LINUX_FALSE}"; then + as_fn_error $? "conditional \"LINUX\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${BSD_TRUE}" && test -z "${BSD_FALSE}"; then + as_fn_error $? "conditional \"BSD\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${SOLARIS_TRUE}" && test -z "${SOLARIS_FALSE}"; then + as_fn_error $? "conditional \"SOLARIS\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MINGW_TRUE}" && test -z "${MINGW_FALSE}"; then + as_fn_error $? "conditional \"MINGW\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${CYGWIN_TRUE}" && test -z "${CYGWIN_FALSE}"; then + as_fn_error $? "conditional \"CYGWIN\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${UML_TRUE}" && test -z "${UML_FALSE}"; then @@ -6960,6 +7253,14 @@ if test -z "${TUNEMU_TRUE}" && test -z "${TUNEMU_FALSE}"; then as_fn_error $? "conditional \"TUNEMU\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi +if test -z "${OPENSSL_TRUE}" && test -z "${OPENSSL_FALSE}"; then + as_fn_error $? "conditional \"OPENSSL\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${GCRYPT_TRUE}" && test -z "${GCRYPT_FALSE}"; then + as_fn_error $? "conditional \"GCRYPT\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi : "${CONFIG_STATUS=./config.status}" ac_write_fail=0 @@ -7357,7 +7658,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by $as_me, which was +This file was extended by tinc $as_me 1.1pre8, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -7423,7 +7724,7 @@ _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 +tinc config.status 1.1pre8 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" @@ -8155,7 +8456,7 @@ $as_echo "$as_me: executing $ac_file commands" >&6;} case $ac_file$ac_mode in "depfiles":C) test x"$AMDEP_TRUE" != x"" || { - # Autoconf 2.62 quotes --file arguments for eval, but not when files + # Older Autoconf quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. case $CONFIG_FILES in @@ -8168,7 +8469,7 @@ $as_echo "$as_me: executing $ac_file commands" >&6;} # Strip MF so we end up with the name of the file. mf=`echo "$mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile or not. - # We used to match only the files named `Makefile.in', but + # We used to match only the files named 'Makefile.in', but # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. @@ -8202,21 +8503,19 @@ $as_echo X"$mf" | continue fi # Extract the definition of DEPDIR, am__include, and am__quote - # from the Makefile without running `make'. + # from the Makefile without running 'make'. DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` test -z "$DEPDIR" && continue am__include=`sed -n 's/^am__include = //p' < "$mf"` - test -z "am__include" && continue + test -z "$am__include" && continue am__quote=`sed -n 's/^am__quote = //p' < "$mf"` - # When using ansi2knr, U may be empty or an underscore; expand it - U=`sed -n 's/^U = //p' < "$mf"` # Find all dependency output files, they are included files with # $(DEPDIR) in their names. We invoke sed twice because it is the # simplest approach to changing $(DEPDIR) to its actual value in the # expansion. for file in `sed -n " s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ - sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue fdir=`$as_dirname -- "$file" || diff --git a/configure.in b/configure.ac similarity index 77% rename from configure.in rename to configure.ac index a59482a..af12f12 100644 --- a/configure.in +++ b/configure.ac @@ -1,12 +1,11 @@ dnl Process this file with autoconf to produce a configure script. AC_PREREQ(2.61) -AC_INIT +AC_INIT([tinc], [1.1pre8]) AC_CONFIG_SRCDIR([src/tincd.c]) AC_GNU_SOURCE -AM_INIT_AUTOMAKE(tinc, 1.1pre7) +AM_INIT_AUTOMAKE([check-news std-options subdir-objects -Wall]) AC_CONFIG_HEADERS([config.h]) -AM_MAINTAINER_MODE # Enable GNU extensions. # Define this here, not in acconfig's @TOP@ section, since definitions @@ -21,51 +20,53 @@ AC_PROG_INSTALL AC_PROG_LN_S AC_PROG_RANLIB +AM_PROG_CC_C_O + dnl Check and set OS AC_CANONICAL_HOST case $host_os in *linux*) + linux=true AC_DEFINE(HAVE_LINUX, 1, [Linux]) - [ rm -f src/device.c; ln -sf linux/device.c src/device.c ] ;; *freebsd*) + bsd=true AC_DEFINE(HAVE_FREEBSD, 1, [FreeBSD]) - [ rm -f src/device.c; ln -sf bsd/device.c src/device.c ] ;; *darwin*) + bsd=true AC_DEFINE(HAVE_DARWIN, 1, [Darwin (MacOS/X)]) - [ rm -f src/device.c; ln -sf bsd/device.c src/device.c ] ;; *solaris*) + solaris=true AC_DEFINE(HAVE_SOLARIS, 1, [Solaris/SunOS]) - [ rm -f src/device.c; ln -sf solaris/device.c src/device.c ] ;; *openbsd*) + bsd=true AC_DEFINE(HAVE_OPENBSD, 1, [OpenBSD]) - [ rm -f src/device.c; ln -sf bsd/device.c src/device.c ] ;; *netbsd*) + bsd=true AC_DEFINE(HAVE_NETBSD, 1, [NetBSD]) - [ rm -f src/device.c; ln -sf bsd/device.c src/device.c ] ;; *dragonfly*) + bsd=true AC_DEFINE(HAVE_DRAGONFLY, 1, [DragonFly]) - [ rm -f src/device.c; ln -sf bsd/device.c src/device.c ] ;; *bsd*) + bsd=true AC_MSG_WARN("Unknown BSD variant, tinc might not compile or work!") AC_DEFINE(HAVE_BSD, 1, [Unknown BSD variant]) - [ rm -f src/device.c; ln -sf bsd/device.c src/device.c ] ;; *cygwin*) + cygwin=true AC_DEFINE(HAVE_CYGWIN, 1, [Cygwin]) - [ rm -f src/device.c; ln -sf cygwin/device.c src/device.c ] ;; *mingw*) + mingw=true AC_DEFINE(HAVE_MINGW, 1, [MinGW]) - [ rm -f src/device.c; cp -f src/mingw/device.c src/device.c ] LIBS="$LIBS -lws2_32 -lgdi32 -lcrypt32" ;; *) @@ -114,6 +115,11 @@ AC_ARG_WITH(windows2000, ] ) +AM_CONDITIONAL(LINUX, test "$linux" = true) +AM_CONDITIONAL(BSD, test "$bsd" = true) +AM_CONDITIONAL(SOLARIS, test "$solaris" = true) +AM_CONDITIONAL(MINGW, test "$mingw" = true) +AM_CONDITIONAL(CYGWIN, test "$cygwin" = true) AM_CONDITIONAL(UML, test "$uml" = true) AM_CONDITIONAL(VDE, test "$vde" = true) AM_CONDITIONAL(TUNEMU, test "$tunemu" = true) @@ -133,13 +139,13 @@ dnl We do this in multiple stages, because unlike Linux all the other operating AC_HEADER_STDC AC_CHECK_HEADERS([stdbool.h syslog.h sys/file.h sys/ioctl.h sys/mman.h sys/param.h sys/resource.h sys/socket.h sys/time.h sys/uio.h sys/un.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/tun/if_tun.h net/if_tap.h net/tap/if_tap.h net/ethernet.h net/if_arp.h netinet/in_systm.h netinet/in.h netinet/in6.h time.h netpacket/packet.h], - [], [], [#include "have.h"] + [], [], [#include "src/have.h"] ) AC_CHECK_HEADERS([netinet/if_ether.h netinet/ip.h netinet/ip6.h], - [], [], [#include "have.h"] + [], [], [#include "src/have.h"] ) AC_CHECK_HEADERS([netinet/tcp.h netinet/ip_icmp.h netinet/icmp6.h], - [], [], [#include "have.h"] + [], [], [#include "src/have.h"] ) dnl Checks for typedefs, structures, and compiler characteristics. @@ -151,15 +157,16 @@ AC_HEADER_TIME AC_STRUCT_TM tinc_ATTRIBUTE(__malloc__) +tinc_ATTRIBUTE(__warn_unused_result__) AC_CHECK_TYPES([socklen_t, struct ether_header, struct arphdr, struct ether_arp, struct in_addr, struct addrinfo, struct ip, struct icmp, struct in6_addr, struct sockaddr_in6, struct ip6_hdr, struct icmp6_hdr, struct nd_neighbor_solicit, struct nd_opt_hdr], , , - [#include "have.h"] + [#include "src/have.h"] ) dnl Checks for library functions. AC_TYPE_SIGNAL AC_CHECK_FUNCS([asprintf daemon fchmod flock ftime fork get_current_dir_name gettimeofday mlockall putenv random select strdup strerror strsignal strtol system time usleep unsetenv vsyslog writev], - [], [], [#include "have.h"] + [], [], [#include "src/have.h"] ) dnl Support for SunOS @@ -172,7 +179,7 @@ AC_CHECK_FUNC(gethostbyname, [], [ ]) AC_CHECK_DECLS([freeaddrinfo, gai_strerror, getaddrinfo, getnameinfo], - [], [], [#include "have.h"] + [], [], [#include "src/have.h"] ) AC_CACHE_SAVE @@ -187,13 +194,15 @@ tinc_ZLIB tinc_LZO if test "$with_libgcrypt" = yes; then + gcrypt=true AM_PATH_LIBGCRYPT([1.4.0], [], []) - ln -sf gcrypt/cipher.c gcrypt/cipher.h gcrypt/crypto.c gcrypt/crypto.h gcrypt/digest.c gcrypt/digest.h gcrypt/ecdh.c gcrypt/ecdh.h gcrypt/ecdsa.c gcrypt/ecdsa.h gcrypt/ecdsagen.c gcrypt/ecdsagen.h gcrypt/prf.c gcrypt/prf.h gcrypt/rsa.c gcrypt/rsa.h gcrypt/rsagen.c gcrypt/rsagen.h src/ else + openssl=true tinc_OPENSSL - ln -sf openssl/cipher.c openssl/cipher.h openssl/crypto.c openssl/crypto.h openssl/digest.c openssl/digest.h openssl/ecdh.c openssl/ecdh.h openssl/ecdsa.c openssl/ecdsa.h openssl/ecdsagen.c openssl/ecdsagen.h openssl/prf.c openssl/prf.h openssl/rsa.c openssl/rsa.h openssl/rsagen.c openssl/rsagen.h src/ fi +AM_CONDITIONAL(OPENSSL, test "$openssl" = true) +AM_CONDITIONAL(GCRYPT, test "$grypt" = true) dnl Check if support for jumbograms is requested AC_ARG_ENABLE(jumbograms, @@ -203,8 +212,6 @@ AC_ARG_ENABLE(jumbograms, ] ) -AC_SUBST(INCLUDES) - AC_CONFIG_FILES([Makefile src/Makefile doc/Makefile m4/Makefile gui/Makefile]) AC_OUTPUT diff --git a/depcomp b/depcomp index 25a39e6..4ebd5b3 100755 --- a/depcomp +++ b/depcomp @@ -1,10 +1,9 @@ #! /bin/sh # depcomp - compile a program generating dependencies as side-effects -scriptversion=2012-03-27.16; # UTC +scriptversion=2013-05-30.07; # UTC -# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006, 2007, 2009, 2010, -# 2011, 2012 Free Software Foundation, Inc. +# Copyright (C) 1999-2013 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -28,9 +27,9 @@ scriptversion=2012-03-27.16; # UTC case $1 in '') - echo "$0: No command. Try '$0 --help' for more information." 1>&2 - exit 1; - ;; + echo "$0: No command. Try '$0 --help' for more information." 1>&2 + exit 1; + ;; -h | --h*) cat <<\EOF Usage: depcomp [--help] [--version] PROGRAM [ARGS] @@ -57,11 +56,65 @@ EOF ;; esac +# Get the directory component of the given path, and save it in the +# global variables '$dir'. Note that this directory component will +# be either empty or ending with a '/' character. This is deliberate. +set_dir_from () +{ + case $1 in + */*) dir=`echo "$1" | sed -e 's|/[^/]*$|/|'`;; + *) dir=;; + esac +} + +# Get the suffix-stripped basename of the given path, and save it the +# global variable '$base'. +set_base_from () +{ + base=`echo "$1" | sed -e 's|^.*/||' -e 's/\.[^.]*$//'` +} + +# If no dependency file was actually created by the compiler invocation, +# we still have to create a dummy depfile, to avoid errors with the +# Makefile "include basename.Plo" scheme. +make_dummy_depfile () +{ + echo "#dummy" > "$depfile" +} + +# Factor out some common post-processing of the generated depfile. +# Requires the auxiliary global variable '$tmpdepfile' to be set. +aix_post_process_depfile () +{ + # If the compiler actually managed to produce a dependency file, + # post-process it. + if test -f "$tmpdepfile"; then + # Each line is of the form 'foo.o: dependency.h'. + # Do two passes, one to just change these to + # $object: dependency.h + # and one to simply output + # dependency.h: + # which is needed to avoid the deleted-header problem. + { sed -e "s,^.*\.[$lower]*:,$object:," < "$tmpdepfile" + sed -e "s,^.*\.[$lower]*:[$tab ]*,," -e 's,$,:,' < "$tmpdepfile" + } > "$depfile" + rm -f "$tmpdepfile" + else + make_dummy_depfile + fi +} + # A tabulation character. tab=' ' # A newline character. nl=' ' +# Character ranges might be problematic outside the C locale. +# These definitions help. +upper=ABCDEFGHIJKLMNOPQRSTUVWXYZ +lower=abcdefghijklmnopqrstuvwxyz +digits=0123456789 +alpha=${upper}${lower} if test -z "$depmode" || test -z "$source" || test -z "$object"; then echo "depcomp: Variables source, object and depmode must be set" 1>&2 @@ -75,6 +128,9 @@ tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} rm -f "$tmpdepfile" +# Avoid interferences from the environment. +gccflag= dashmflag= + # Some modes work just like other modes, but use different flags. We # parameterize here, but still list the modes in the big case below, # to make depend.m4 easier to write. Note that we *cannot* use a case @@ -86,32 +142,32 @@ if test "$depmode" = hp; then fi if test "$depmode" = dashXmstdout; then - # This is just like dashmstdout with a different argument. - dashmflag=-xM - depmode=dashmstdout + # This is just like dashmstdout with a different argument. + dashmflag=-xM + depmode=dashmstdout fi cygpath_u="cygpath -u -f -" if test "$depmode" = msvcmsys; then - # This is just like msvisualcpp but w/o cygpath translation. - # Just convert the backslash-escaped backslashes to single forward - # slashes to satisfy depend.m4 - cygpath_u='sed s,\\\\,/,g' - depmode=msvisualcpp + # This is just like msvisualcpp but w/o cygpath translation. + # Just convert the backslash-escaped backslashes to single forward + # slashes to satisfy depend.m4 + cygpath_u='sed s,\\\\,/,g' + depmode=msvisualcpp fi if test "$depmode" = msvc7msys; then - # This is just like msvc7 but w/o cygpath translation. - # Just convert the backslash-escaped backslashes to single forward - # slashes to satisfy depend.m4 - cygpath_u='sed s,\\\\,/,g' - depmode=msvc7 + # This is just like msvc7 but w/o cygpath translation. + # Just convert the backslash-escaped backslashes to single forward + # slashes to satisfy depend.m4 + cygpath_u='sed s,\\\\,/,g' + depmode=msvc7 fi if test "$depmode" = xlc; then - # IBM C/C++ Compilers xlc/xlC can output gcc-like dependency informations. - gccflag=-qmakedep=gcc,-MF - depmode=gcc + # IBM C/C++ Compilers xlc/xlC can output gcc-like dependency information. + gccflag=-qmakedep=gcc,-MF + depmode=gcc fi case "$depmode" in @@ -134,8 +190,7 @@ gcc3) done "$@" stat=$? - if test $stat -eq 0; then : - else + if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi @@ -143,13 +198,17 @@ gcc3) ;; gcc) +## Note that this doesn't just cater to obsosete pre-3.x GCC compilers. +## but also to in-use compilers like IMB xlc/xlC and the HP C compiler. +## (see the conditional assignment to $gccflag above). ## There are various ways to get dependency output from gcc. Here's ## why we pick this rather obscure method: ## - Don't want to use -MD because we'd like the dependencies to end ## up in a subdir. Having to rename by hand is ugly. ## (We might end up doing this anyway to support other compilers.) ## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like -## -MM, not -M (despite what the docs say). +## -MM, not -M (despite what the docs say). Also, it might not be +## supported by the other compilers which use the 'gcc' depmode. ## - Using -M directly means running the compiler twice (even worse ## than renaming). if test -z "$gccflag"; then @@ -157,15 +216,14 @@ gcc) fi "$@" -Wp,"$gccflag$tmpdepfile" stat=$? - if test $stat -eq 0; then : - else + if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" echo "$object : \\" > "$depfile" - alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz -## The second -e expression handles DOS-style file names with drive letters. + # The second -e expression handles DOS-style file names with drive + # letters. sed -e 's/^[^:]*: / /' \ -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" ## This next piece of magic avoids the "deleted header file" problem. @@ -174,15 +232,15 @@ gcc) ## typically no way to rebuild the header). We avoid this by adding ## dummy dependencies for each header file. Too bad gcc doesn't do ## this for us directly. - tr ' ' "$nl" < "$tmpdepfile" | ## Some versions of gcc put a space before the ':'. On the theory ## that the space means something, we add a space to the output as ## well. hp depmode also adds that space, but also prefixes the VPATH ## to the object. Take care to not repeat it in the output. ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. - sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \ - | sed -e 's/$/ :/' >> "$depfile" + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \ + | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; @@ -200,8 +258,7 @@ sgi) "$@" -MDupdate "$tmpdepfile" fi stat=$? - if test $stat -eq 0; then : - else + if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi @@ -209,7 +266,6 @@ sgi) if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files echo "$object : \\" > "$depfile" - # Clip off the initial element (the dependent). Don't try to be # clever and replace this with sed code, as IRIX sed won't handle # lines with more than a fixed number of characters (4096 in @@ -217,19 +273,15 @@ sgi) # the IRIX cc adds comments like '#:fec' to the end of the # dependency line. tr ' ' "$nl" < "$tmpdepfile" \ - | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \ - tr "$nl" ' ' >> "$depfile" + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' \ + | tr "$nl" ' ' >> "$depfile" echo >> "$depfile" - # The second pass generates a dummy entry for each header file. tr ' ' "$nl" < "$tmpdepfile" \ - | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ - >> "$depfile" + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ + >> "$depfile" else - # The sourcefile does not contain any dependencies, so just - # store a dummy comment line, to avoid errors with the Makefile - # "include basename.Plo" scheme. - echo "#dummy" > "$depfile" + make_dummy_depfile fi rm -f "$tmpdepfile" ;; @@ -247,9 +299,8 @@ aix) # current directory. Also, the AIX compiler puts '$object:' at the # start of each line; $object doesn't have directory information. # Version 6 uses the directory in both cases. - dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` - test "x$dir" = "x$object" && dir= - base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` + set_dir_from "$object" + set_base_from "$object" if test "$libtool" = yes; then tmpdepfile1=$dir$base.u tmpdepfile2=$base.u @@ -262,9 +313,7 @@ aix) "$@" -M fi stat=$? - - if test $stat -eq 0; then : - else + if test $stat -ne 0; then rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" exit $stat fi @@ -273,65 +322,113 @@ aix) do test -f "$tmpdepfile" && break done - if test -f "$tmpdepfile"; then - # Each line is of the form 'foo.o: dependent.h'. - # Do two passes, one to just change these to - # '$object: dependent.h' and one to simply 'dependent.h:'. - sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" - sed -e 's,^.*\.[a-z]*:['"$tab"' ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" - else - # The sourcefile does not contain any dependencies, so just - # store a dummy comment line, to avoid errors with the Makefile - # "include basename.Plo" scheme. - echo "#dummy" > "$depfile" - fi - rm -f "$tmpdepfile" + aix_post_process_depfile ;; -icc) - # Intel's C compiler anf tcc (Tiny C Compiler) understand '-MD -MF file'. - # However on - # $CC -MD -MF foo.d -c -o sub/foo.o sub/foo.c - # ICC 7.0 will fill foo.d with something like - # foo.o: sub/foo.c - # foo.o: sub/foo.h - # which is wrong. We want - # sub/foo.o: sub/foo.c - # sub/foo.o: sub/foo.h - # sub/foo.c: - # sub/foo.h: - # ICC 7.1 will output - # foo.o: sub/foo.c sub/foo.h - # and will wrap long lines using '\': - # foo.o: sub/foo.c ... \ - # sub/foo.h ... \ - # ... - # tcc 0.9.26 (FIXME still under development at the moment of writing) - # will emit a similar output, but also prepend the continuation lines - # with horizontal tabulation characters. +tcc) + # tcc (Tiny C Compiler) understand '-MD -MF file' since version 0.9.26 + # FIXME: That version still under development at the moment of writing. + # Make that this statement remains true also for stable, released + # versions. + # It will wrap lines (doesn't matter whether long or short) with a + # trailing '\', as in: + # + # foo.o : \ + # foo.c \ + # foo.h \ + # + # It will put a trailing '\' even on the last line, and will use leading + # spaces rather than leading tabs (at least since its commit 0394caf7 + # "Emit spaces for -MD"). "$@" -MD -MF "$tmpdepfile" stat=$? - if test $stat -eq 0; then : - else + if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" - # Each line is of the form 'foo.o: dependent.h', - # or 'foo.o: dep1.h dep2.h \', or ' dep3.h dep4.h \'. + # Each non-empty line is of the form 'foo.o : \' or ' dep.h \'. + # We have to change lines of the first kind to '$object: \'. + sed -e "s|.*:|$object :|" < "$tmpdepfile" > "$depfile" + # And for each line of the second kind, we have to emit a 'dep.h:' + # dummy dependency, to avoid the deleted-header problem. + sed -n -e 's|^ *\(.*\) *\\$|\1:|p' < "$tmpdepfile" >> "$depfile" + rm -f "$tmpdepfile" + ;; + +## The order of this option in the case statement is important, since the +## shell code in configure will try each of these formats in the order +## listed in this file. A plain '-MD' option would be understood by many +## compilers, so we must ensure this comes after the gcc and icc options. +pgcc) + # Portland's C compiler understands '-MD'. + # Will always output deps to 'file.d' where file is the root name of the + # source file under compilation, even if file resides in a subdirectory. + # The object file name does not affect the name of the '.d' file. + # pgcc 10.2 will output + # foo.o: sub/foo.c sub/foo.h + # and will wrap long lines using '\' : + # foo.o: sub/foo.c ... \ + # sub/foo.h ... \ + # ... + set_dir_from "$object" + # Use the source, not the object, to determine the base name, since + # that's sadly what pgcc will do too. + set_base_from "$source" + tmpdepfile=$base.d + + # For projects that build the same source file twice into different object + # files, the pgcc approach of using the *source* file root name can cause + # problems in parallel builds. Use a locking strategy to avoid stomping on + # the same $tmpdepfile. + lockdir=$base.d-lock + trap " + echo '$0: caught signal, cleaning up...' >&2 + rmdir '$lockdir' + exit 1 + " 1 2 13 15 + numtries=100 + i=$numtries + while test $i -gt 0; do + # mkdir is a portable test-and-set. + if mkdir "$lockdir" 2>/dev/null; then + # This process acquired the lock. + "$@" -MD + stat=$? + # Release the lock. + rmdir "$lockdir" + break + else + # If the lock is being held by a different process, wait + # until the winning process is done or we timeout. + while test -d "$lockdir" && test $i -gt 0; do + sleep 1 + i=`expr $i - 1` + done + fi + i=`expr $i - 1` + done + trap - 1 2 13 15 + if test $i -le 0; then + echo "$0: failed to acquire lock after $numtries attempts" >&2 + echo "$0: check lockdir '$lockdir'" >&2 + exit 1 + fi + + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + # Each line is of the form `foo.o: dependent.h', + # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. # Do two passes, one to just change these to - # '$object: dependent.h' and one to simply 'dependent.h:'. - sed -e "s/^[ $tab][ $tab]*/ /" -e "s,^[^:]*:,$object :," \ - < "$tmpdepfile" > "$depfile" - sed ' - s/[ '"$tab"'][ '"$tab"']*/ /g - s/^ *// - s/ *\\*$// - s/^[^:]*: *// - /^$/d - /:$/d - s/$/ :/ - ' < "$tmpdepfile" >> "$depfile" + # `$object: dependent.h' and one to simply `dependent.h:'. + sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" + # Some versions of the HPUX 10.20 sed can't process this invocation + # correctly. Breaking it into two sed invocations is a workaround. + sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" \ + | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; @@ -342,9 +439,8 @@ hp2) # 'foo.d', which lands next to the object file, wherever that # happens to be. # Much of this is similar to the tru64 case; see comments there. - dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` - test "x$dir" = "x$object" && dir= - base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` + set_dir_from "$object" + set_base_from "$object" if test "$libtool" = yes; then tmpdepfile1=$dir$base.d tmpdepfile2=$dir.libs/$base.d @@ -355,8 +451,7 @@ hp2) "$@" +Maked fi stat=$? - if test $stat -eq 0; then : - else + if test $stat -ne 0; then rm -f "$tmpdepfile1" "$tmpdepfile2" exit $stat fi @@ -366,76 +461,61 @@ hp2) test -f "$tmpdepfile" && break done if test -f "$tmpdepfile"; then - sed -e "s,^.*\.[a-z]*:,$object:," "$tmpdepfile" > "$depfile" + sed -e "s,^.*\.[$lower]*:,$object:," "$tmpdepfile" > "$depfile" # Add 'dependent.h:' lines. sed -ne '2,${ - s/^ *// - s/ \\*$// - s/$/:/ - p - }' "$tmpdepfile" >> "$depfile" + s/^ *// + s/ \\*$// + s/$/:/ + p + }' "$tmpdepfile" >> "$depfile" else - echo "#dummy" > "$depfile" + make_dummy_depfile fi rm -f "$tmpdepfile" "$tmpdepfile2" ;; tru64) - # The Tru64 compiler uses -MD to generate dependencies as a side - # effect. 'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'. - # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put - # dependencies in 'foo.d' instead, so we check for that too. - # Subdirectories are respected. - dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` - test "x$dir" = "x$object" && dir= - base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` + # The Tru64 compiler uses -MD to generate dependencies as a side + # effect. 'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'. + # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put + # dependencies in 'foo.d' instead, so we check for that too. + # Subdirectories are respected. + set_dir_from "$object" + set_base_from "$object" - if test "$libtool" = yes; then - # With Tru64 cc, shared objects can also be used to make a - # static library. This mechanism is used in libtool 1.4 series to - # handle both shared and static libraries in a single compilation. - # With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d. - # - # With libtool 1.5 this exception was removed, and libtool now - # generates 2 separate objects for the 2 libraries. These two - # compilations output dependencies in $dir.libs/$base.o.d and - # in $dir$base.o.d. We have to check for both files, because - # one of the two compilations can be disabled. We should prefer - # $dir$base.o.d over $dir.libs/$base.o.d because the latter is - # automatically cleaned when .libs/ is deleted, while ignoring - # the former would cause a distcleancheck panic. - tmpdepfile1=$dir.libs/$base.lo.d # libtool 1.4 - tmpdepfile2=$dir$base.o.d # libtool 1.5 - tmpdepfile3=$dir.libs/$base.o.d # libtool 1.5 - tmpdepfile4=$dir.libs/$base.d # Compaq CCC V6.2-504 - "$@" -Wc,-MD - else - tmpdepfile1=$dir$base.o.d - tmpdepfile2=$dir$base.d - tmpdepfile3=$dir$base.d - tmpdepfile4=$dir$base.d - "$@" -MD - fi + if test "$libtool" = yes; then + # Libtool generates 2 separate objects for the 2 libraries. These + # two compilations output dependencies in $dir.libs/$base.o.d and + # in $dir$base.o.d. We have to check for both files, because + # one of the two compilations can be disabled. We should prefer + # $dir$base.o.d over $dir.libs/$base.o.d because the latter is + # automatically cleaned when .libs/ is deleted, while ignoring + # the former would cause a distcleancheck panic. + tmpdepfile1=$dir$base.o.d # libtool 1.5 + tmpdepfile2=$dir.libs/$base.o.d # Likewise. + tmpdepfile3=$dir.libs/$base.d # Compaq CCC V6.2-504 + "$@" -Wc,-MD + else + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir$base.d + tmpdepfile3=$dir$base.d + "$@" -MD + fi - stat=$? - if test $stat -eq 0; then : - else - rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" - exit $stat - fi + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + exit $stat + fi - for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" - do - test -f "$tmpdepfile" && break - done - if test -f "$tmpdepfile"; then - sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" - sed -e 's,^.*\.[a-z]*:['"$tab"' ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" - else - echo "#dummy" > "$depfile" - fi - rm -f "$tmpdepfile" - ;; + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + do + test -f "$tmpdepfile" && break + done + # Same post-processing that is required for AIX mode. + aix_post_process_depfile + ;; msvc7) if test "$libtool" = yes; then @@ -446,8 +526,7 @@ msvc7) "$@" $showIncludes > "$tmpdepfile" stat=$? grep -v '^Note: including file: ' "$tmpdepfile" - if test "$stat" = 0; then : - else + if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi @@ -473,6 +552,7 @@ $ { G p }' >> "$depfile" + echo >> "$depfile" # make sure the fragment doesn't end with a backslash rm -f "$tmpdepfile" ;; @@ -524,13 +604,14 @@ dashmstdout) # in the target name. This is to cope with DOS-style filenames: # a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise. "$@" $dashmflag | - sed 's:^['"$tab"' ]*[^:'"$tab"' ][^:][^:]*\:['"$tab"' ]*:'"$object"'\: :' > "$tmpdepfile" + sed "s|^[$tab ]*[^:$tab ][^:][^:]*:[$tab ]*|$object: |" > "$tmpdepfile" rm -f "$depfile" cat < "$tmpdepfile" > "$depfile" - tr ' ' "$nl" < "$tmpdepfile" | \ -## Some versions of the HPUX 10.20 sed can't process this invocation -## correctly. Breaking it into two sed invocations is a workaround. - sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + # Some versions of the HPUX 10.20 sed can't process this sed invocation + # correctly. Breaking it into two sed invocations is a workaround. + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ + | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; @@ -583,10 +664,12 @@ makedepend) # makedepend may prepend the VPATH from the source file name to the object. # No need to regex-escape $object, excess matching of '.' is harmless. sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile" - sed '1,2d' "$tmpdepfile" | tr ' ' "$nl" | \ -## Some versions of the HPUX 10.20 sed can't process this invocation -## correctly. Breaking it into two sed invocations is a workaround. - sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + # Some versions of the HPUX 10.20 sed can't process the last invocation + # correctly. Breaking it into two sed invocations is a workaround. + sed '1,2d' "$tmpdepfile" \ + | tr ' ' "$nl" \ + | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ + | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" "$tmpdepfile".bak ;; @@ -622,10 +705,10 @@ cpp) esac done - "$@" -E | - sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ - -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' | - sed '$ s: \\$::' > "$tmpdepfile" + "$@" -E \ + | sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ + -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ + | sed '$ s: \\$::' > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" cat < "$tmpdepfile" >> "$depfile" @@ -657,15 +740,15 @@ msvisualcpp) shift ;; "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") - set fnord "$@" - shift - shift - ;; + set fnord "$@" + shift + shift + ;; *) - set fnord "$@" "$arg" - shift - shift - ;; + set fnord "$@" "$arg" + shift + shift + ;; esac done "$@" -E 2>/dev/null | diff --git a/doc/Makefile.in b/doc/Makefile.in index b95f19c..823c951 100644 --- a/doc/Makefile.in +++ b/doc/Makefile.in @@ -1,9 +1,8 @@ -# Makefile.in generated by automake 1.11.6 from Makefile.am. +# Makefile.in generated by automake 1.13.3 from Makefile.am. # @configure_input@ -# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software -# Foundation, Inc. +# Copyright (C) 1994-2013 Free Software Foundation, Inc. + # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -15,23 +14,51 @@ @SET_MAKE@ VPATH = @srcdir@ -am__make_dryrun = \ - { \ - am__dry=no; \ +am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ - echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ - | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ - *) \ - for am__flg in $$MAKEFLAGS; do \ - case $$am__flg in \ - *=*|--*) ;; \ - *n*) am__dry=yes; break;; \ - esac; \ - done;; \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ - test $$am__dry = yes; \ - } + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ @@ -50,20 +77,60 @@ POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = doc -DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in texinfo.tex +DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am texinfo.tex ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \ $(top_srcdir)/m4/curses.m4 $(top_srcdir)/m4/lzo.m4 \ $(top_srcdir)/m4/openssl.m4 $(top_srcdir)/m4/readline.m4 \ - $(top_srcdir)/m4/zlib.m4 $(top_srcdir)/configure.in + $(top_srcdir)/m4/zlib.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = SOURCES = DIST_SOURCES = +AM_V_DVIPS = $(am__v_DVIPS_@AM_V@) +am__v_DVIPS_ = $(am__v_DVIPS_@AM_DEFAULT_V@) +am__v_DVIPS_0 = @echo " DVIPS " $@; +am__v_DVIPS_1 = +AM_V_MAKEINFO = $(am__v_MAKEINFO_@AM_V@) +am__v_MAKEINFO_ = $(am__v_MAKEINFO_@AM_DEFAULT_V@) +am__v_MAKEINFO_0 = @echo " MAKEINFO" $@; +am__v_MAKEINFO_1 = +AM_V_INFOHTML = $(am__v_INFOHTML_@AM_V@) +am__v_INFOHTML_ = $(am__v_INFOHTML_@AM_DEFAULT_V@) +am__v_INFOHTML_0 = @echo " INFOHTML" $@; +am__v_INFOHTML_1 = +AM_V_TEXI2DVI = $(am__v_TEXI2DVI_@AM_V@) +am__v_TEXI2DVI_ = $(am__v_TEXI2DVI_@AM_DEFAULT_V@) +am__v_TEXI2DVI_0 = @echo " TEXI2DVI" $@; +am__v_TEXI2DVI_1 = +AM_V_TEXI2PDF = $(am__v_TEXI2PDF_@AM_V@) +am__v_TEXI2PDF_ = $(am__v_TEXI2PDF_@AM_DEFAULT_V@) +am__v_TEXI2PDF_0 = @echo " TEXI2PDF" $@; +am__v_TEXI2PDF_1 = +AM_V_texinfo = $(am__v_texinfo_@AM_V@) +am__v_texinfo_ = $(am__v_texinfo_@AM_DEFAULT_V@) +am__v_texinfo_0 = -q +am__v_texinfo_1 = +AM_V_texidevnull = $(am__v_texidevnull_@AM_V@) +am__v_texidevnull_ = $(am__v_texidevnull_@AM_DEFAULT_V@) +am__v_texidevnull_0 = > /dev/null +am__v_texidevnull_1 = INFO_DEPS = tinc.info am__TEXINFO_TEX_DIR = $(srcdir) DVIS = tinc.dvi @@ -114,6 +181,7 @@ man5dir = $(mandir)/man5 man8dir = $(mandir)/man8 NROFF = nroff MANS = $(man_MANS) +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) # Use `ginstall' in the definition of man_MANS to avoid @@ -122,6 +190,7 @@ DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) transform = s/ginstall/install/; @program_transform_name@ ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ @@ -141,7 +210,6 @@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ GREP = @GREP@ -INCLUDES = @INCLUDES@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ @@ -155,7 +223,6 @@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ -MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ OBJEXT = @OBJEXT@ @@ -237,7 +304,7 @@ all: all-am .SUFFIXES: .SUFFIXES: .dvi .ps -$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ @@ -262,14 +329,14 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) +$(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) +$(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): tinc.info: tinc.texi - restore=: && backupdir="$(am__leading_dot)am$$$$" && \ + $(AM_V_MAKEINFO)restore=: && backupdir="$(am__leading_dot)am$$$$" && \ rm -rf $$backupdir && mkdir $$backupdir && \ if ($(MAKEINFO) --version) >/dev/null 2>&1; then \ for f in $@ $@-[0-9] $@-[0-9][0-9] $(@:.info=).i[0-9] $(@:.info=).i[0-9][0-9]; do \ @@ -287,18 +354,20 @@ tinc.info: tinc.texi rm -rf $$backupdir; exit $$rc tinc.dvi: tinc.texi - TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \ + $(AM_V_TEXI2DVI)TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \ MAKEINFO='$(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir)' \ - $(TEXI2DVI) -o $@ `test -f 'tinc.texi' || echo '$(srcdir)/'`tinc.texi + $(TEXI2DVI) $(AM_V_texinfo) --build-dir=$(@:.dvi=.t2d) -o $@ $(AM_V_texidevnull) \ + `test -f 'tinc.texi' || echo '$(srcdir)/'`tinc.texi tinc.pdf: tinc.texi - TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \ + $(AM_V_TEXI2PDF)TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \ MAKEINFO='$(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir)' \ - $(TEXI2PDF) -o $@ `test -f 'tinc.texi' || echo '$(srcdir)/'`tinc.texi + $(TEXI2PDF) $(AM_V_texinfo) --build-dir=$(@:.pdf=.t2p) -o $@ $(AM_V_texidevnull) \ + `test -f 'tinc.texi' || echo '$(srcdir)/'`tinc.texi tinc.html: tinc.texi - rm -rf $(@:.html=.htp) - if $(MAKEINFOHTML) $(AM_MAKEINFOHTMLFLAGS) $(MAKEINFOFLAGS) -I $(srcdir) \ + $(AM_V_MAKEINFO)rm -rf $(@:.html=.htp) + $(AM_V_at)if $(MAKEINFOHTML) $(AM_MAKEINFOHTMLFLAGS) $(MAKEINFOFLAGS) -I $(srcdir) \ -o $(@:.html=.htp) `test -f 'tinc.texi' || echo '$(srcdir)/'`tinc.texi; \ then \ rm -rf $@; \ @@ -310,8 +379,8 @@ tinc.html: tinc.texi exit 1; \ fi .dvi.ps: - TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \ - $(DVIPS) -o $@ $< + $(AM_V_DVIPS)TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \ + $(DVIPS) $(AM_V_texinfo) -o $@ $< uninstall-dvi-am: @$(NORMAL_UNINSTALL) @@ -390,9 +459,7 @@ dist-info: $(INFO_DEPS) done mostlyclean-aminfo: - -rm -rf tinc.aux tinc.cp tinc.cps tinc.fn tinc.fns tinc.ky tinc.kys \ - tinc.log tinc.pg tinc.pgs tinc.tmp tinc.toc tinc.tp tinc.tps \ - tinc.vr tinc.vrs + -rm -rf tinc.t2d tinc.t2p clean-aminfo: -test -z "tinc.dvi tinc.pdf tinc.ps tinc.html" \ @@ -490,27 +557,14 @@ uninstall-man8: } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ dir='$(DESTDIR)$(man8dir)'; $(am__uninstall_files_from_dir) -tags: TAGS -TAGS: +tags TAGS: -ctags: CTAGS -CTAGS: +ctags CTAGS: + +cscope cscopelist: distdir: $(DISTFILES) - @list='$(MANS)'; if test -n "$$list"; then \ - list=`for p in $$list; do \ - if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ - if test -f "$$d$$p"; then echo "$$d$$p"; else :; fi; done`; \ - if test -n "$$list" && \ - grep 'ab help2man is required to generate this page' $$list >/dev/null; then \ - echo "error: found man pages containing the \`missing help2man' replacement text:" >&2; \ - grep -l 'ab help2man is required to generate this page' $$list | sed 's/^/ /' >&2; \ - echo " to fix them, install help2man, remove and regenerate the man pages;" >&2; \ - echo " typically \`make maintainer-clean' will remove them" >&2; \ - exit 1; \ - else :; fi; \ - else :; fi @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ @@ -745,19 +799,19 @@ uninstall-man: uninstall-man5 uninstall-man8 .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-aminfo clean-generic \ - dist-info distclean distclean-generic distdir dvi dvi-am html \ - html-am info info-am install install-am install-data \ - install-data-am install-dvi install-dvi-am install-exec \ - install-exec-am install-html install-html-am install-info \ - install-info-am install-man install-man5 install-man8 \ - install-pdf install-pdf-am install-ps install-ps-am \ - install-strip installcheck installcheck-am installdirs \ - maintainer-clean maintainer-clean-aminfo \ - maintainer-clean-generic mostlyclean mostlyclean-aminfo \ - mostlyclean-generic pdf pdf-am ps ps-am uninstall uninstall-am \ - uninstall-dvi-am uninstall-html-am uninstall-info-am \ - uninstall-man uninstall-man5 uninstall-man8 uninstall-pdf-am \ - uninstall-ps-am + cscopelist-am ctags-am dist-info distclean distclean-generic \ + distdir dvi dvi-am html html-am info info-am install \ + install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-man5 install-man8 install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-aminfo maintainer-clean-generic mostlyclean \ + mostlyclean-aminfo mostlyclean-generic pdf pdf-am ps ps-am \ + tags-am uninstall uninstall-am uninstall-dvi-am \ + uninstall-html-am uninstall-info-am uninstall-man \ + uninstall-man5 uninstall-man8 uninstall-pdf-am uninstall-ps-am # For additional rules usually of interest only to the maintainer, diff --git a/doc/sample-config.tar.gz b/doc/sample-config.tar.gz index aa515c9580c1260a64261216fef38108a941b900..1a766a691ff1086b57b07104f889fe7a8cf071dc 100644 GIT binary patch delta 17 Ycmcc0d6knxzMF$V*^Mh`Bga`504+8I#sB~S delta 17 Ycmcc0d6knxzMF&Lu+{#6jT~oL05%o|4FCWD diff --git a/doc/texinfo.tex b/doc/texinfo.tex index 85b68e7..85f184c 100644 --- a/doc/texinfo.tex +++ b/doc/texinfo.tex @@ -3,11 +3,11 @@ % Load plain if necessary, i.e., if running under initex. \expandafter\ifx\csname fmtname\endcsname\relax\input plain\fi % -\def\texinfoversion{2012-03-11.15} +\def\texinfoversion{2013-02-01.11} % % Copyright 1985, 1986, 1988, 1990, 1991, 1992, 1993, 1994, 1995, % 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, -% 2007, 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc. +% 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc. % % This texinfo.tex file is free software: you can redistribute it and/or % modify it under the terms of the GNU General Public License as @@ -24,13 +24,14 @@ % % As a special exception, when this file is read by TeX when processing % a Texinfo source document, you may use the result without -% restriction. (This has been our intent since Texinfo was invented.) +% restriction. This Exception is an additional permission under section 7 +% of the GNU General Public License, version 3 ("GPLv3"). % % Please try the latest version of texinfo.tex before submitting bug % reports; you can get the latest version from: -% http://www.gnu.org/software/texinfo/ (the Texinfo home page), or -% ftp://tug.org/tex/texinfo.tex -% (and all CTAN mirrors, see http://www.ctan.org). +% http://ftp.gnu.org/gnu/texinfo/ (the Texinfo release area), or +% http://ftpmirror.gnu.org/texinfo/ (same, via a mirror), or +% http://www.gnu.org/software/texinfo/ (the Texinfo home page) % The texinfo.tex in any given distribution could well be out % of date, so if that's what you're using, please check. % @@ -594,7 +595,7 @@ \def\:{\spacefactor=1000 } % @* forces a line break. -\def\*{\hfil\break\hbox{}\ignorespaces} +\def\*{\unskip\hfil\break\hbox{}\ignorespaces} % @/ allows a line break. \let\/=\allowbreak @@ -1117,7 +1118,7 @@ where each line of input produces a line of output.} % #1 is a control sequence in which to do the replacements, % which we \xdef. \def\txiescapepdf#1{% - \ifx\pdfescapestring\relax + \ifx\pdfescapestring\thisisundefined % No primitive available; should we give a warning or log? % Many times it won't matter. \else @@ -1367,9 +1368,8 @@ output) for that.)} \def\skipspaces#1{\def\PP{#1}\def\D{|}% \ifx\PP\D\let\nextsp\relax \else\let\nextsp\skipspaces - \ifx\p\space\else\addtokens{\filename}{\PP}% - \advance\filenamelength by 1 - \fi + \addtokens{\filename}{\PP}% + \advance\filenamelength by 1 \fi \nextsp} \def\getfilename#1{% @@ -1475,9 +1475,6 @@ output) for that.)} \def\ttsl{\setfontstyle{ttsl}} -% Default leading. -\newdimen\textleading \textleading = 13.2pt - % Set the baselineskip to #1, and the lineskip and strut size % correspondingly. There is no deep meaning behind these magic numbers % used as factors; they just match (closely enough) what Knuth defined. @@ -1489,6 +1486,7 @@ output) for that.)} % can get a sort of poor man's double spacing by redefining this. \def\baselinefactor{1} % +\newdimen\textleading \def\setleading#1{% \dimen0 = #1\relax \normalbaselineskip = \baselinefactor\dimen0 @@ -1761,18 +1759,24 @@ end \fi\fi -% Set the font macro #1 to the font named #2, adding on the -% specified font prefix (normally `cm'). +% Set the font macro #1 to the font named \fontprefix#2. % #3 is the font's design size, #4 is a scale factor, #5 is the CMap -% encoding (currently only OT1, OT1IT and OT1TT are allowed, pass -% empty to omit). +% encoding (only OT1, OT1IT and OT1TT are allowed, or empty to omit). +% Example: +% #1 = \textrm +% #2 = \rmshape +% #3 = 10 +% #4 = \mainmagstep +% #5 = OT1 +% \def\setfont#1#2#3#4#5{% \font#1=\fontprefix#2#3 scaled #4 \csname cmap#5\endcsname#1% } % This is what gets called when #5 of \setfont is empty. \let\cmap\gobble -% emacs-page end of cmaps +% +% (end of cmaps) % Use cm as the default font prefix. % To specify the font prefix, you must define \fontprefix @@ -1782,7 +1786,7 @@ end \fi % Support font families that don't use the same naming scheme as CM. \def\rmshape{r} -\def\rmbshape{bx} %where the normal face is bold +\def\rmbshape{bx} % where the normal face is bold \def\bfshape{b} \def\bxshape{bx} \def\ttshape{tt} @@ -1797,8 +1801,7 @@ end \def\scshape{csc} \def\scbshape{csc} -% Definitions for a main text size of 11pt. This is the default in -% Texinfo. +% Definitions for a main text size of 11pt. (The default in Texinfo.) % \def\definetextfontsizexi{% % Text fonts (11.2pt, magstep1). @@ -1923,7 +1926,7 @@ end \textleading = 13.2pt % line spacing for 11pt CM \textfonts % reset the current fonts \rm -} % end of 11pt text font size definitions +} % end of 11pt text font size definitions, \definetextfontsizexi % Definitions to make the main text be 10pt Computer Modern, with @@ -2055,7 +2058,7 @@ end \textleading = 12pt % line spacing for 10pt CM \textfonts % reset the current fonts \rm -} % end of 10pt text font size definitions +} % end of 10pt text font size definitions, \definetextfontsizex % We provide the user-level command @@ -2270,8 +2273,6 @@ end \gdef\markupsetcodequoteleft{\let`\codequoteleft} \gdef\markupsetcodequoteright{\let'\codequoteright} - -\gdef\markupsetnoligaturesquoteleft{\let`\noligaturesquoteleft} } \let\markupsetuplqcode \markupsetcodequoteleft @@ -2280,6 +2281,9 @@ end \let\markupsetuplqexample \markupsetcodequoteleft \let\markupsetuprqexample \markupsetcodequoteright % +\let\markupsetuplqkbd \markupsetcodequoteleft +\let\markupsetuprqkbd \markupsetcodequoteright +% \let\markupsetuplqsamp \markupsetcodequoteleft \let\markupsetuprqsamp \markupsetcodequoteright % @@ -2289,8 +2293,6 @@ end \let\markupsetuplqverbatim \markupsetcodequoteleft \let\markupsetuprqverbatim \markupsetcodequoteright -\let\markupsetuplqkbd \markupsetnoligaturesquoteleft - % Allow an option to not use regular directed right quote/apostrophe % (char 0x27), but instead the undirected quote from cmtt (char 0x0d). % The undirected quote is ugly, so don't make it the default, but it @@ -2380,8 +2382,7 @@ end \aftersmartic } -% like \smartslanted except unconditionally uses \ttsl, and no ic. -% @var is set to this for defun arguments. +% Unconditional use \ttsl, and no ic. @var is set to this for defuns. \def\ttslanted#1{{\ttsl #1}} % @cite is like \smartslanted except unconditionally use \sl. We never want @@ -2446,34 +2447,12 @@ end % @samp. \def\samp#1{{\setupmarkupstyle{samp}\lq\tclose{#1}\rq\null}} -% definition of @key that produces a lozenge. Doesn't adjust to text size. -%\setfont\keyrm\rmshape{8}{1000}{OT1} -%\font\keysy=cmsy9 -%\def\key#1{{\keyrm\textfont2=\keysy \leavevmode\hbox{% -% \raise0.4pt\hbox{\angleleft}\kern-.08em\vtop{% -% \vbox{\hrule\kern-0.4pt -% \hbox{\raise0.4pt\hbox{\vphantom{\angleleft}}#1}}% -% \kern-0.4pt\hrule}% -% \kern-.06em\raise0.4pt\hbox{\angleright}}}} +% @indicateurl is \samp, that is, with quotes. +\let\indicateurl=\samp -% definition of @key with no lozenge. If the current font is already -% monospace, don't change it; that way, we respect @kbdinputstyle. But -% if it isn't monospace, then use \tt. -% -\def\key#1{{\setupmarkupstyle{key}% - \nohyphenation - \ifmonospace\else\tt\fi - #1}\null} - -% ctrl is no longer a Texinfo command. -\def\ctrl #1{{\tt \rawbackslash \hat}#1} - -% @file, @option are the same as @samp. -\let\file=\samp -\let\option=\samp - -% @code is a modification of @t, -% which makes spaces the same size as normal in the surrounding text. +% @code (and similar) prints in typewriter, but with spaces the same +% size as normal in the surrounding text, without hyphenation, etc. +% This is a subroutine for that. \def\tclose#1{% {% % Change normal interword space to be same as for the current font. @@ -2498,7 +2477,7 @@ end % We *must* turn on hyphenation at `-' and `_' in @code. % Otherwise, it is too hard to avoid overfull hboxes % in the Emacs manual, the Library manual, etc. - +% % Unfortunately, TeX uses one parameter (\hyphenchar) to control % both hyphenation at - and hyphenation within words. % We must therefore turn them both off (\tclose does that) @@ -2517,7 +2496,7 @@ end \let-\codedash \let_\codeunder \else - \let-\realdash + \let-\normaldash \let_\realunder \fi \codex @@ -2526,7 +2505,7 @@ end \def\codex #1{\tclose{#1}\endgroup} -\def\realdash{-} +\def\normaldash{-} \def\codedash{-\discretionary{}{}{}} \def\codeunder{% % this is all so @math{@code{var_name}+1} can work. In math mode, _ @@ -2541,9 +2520,9 @@ end } % An additional complication: the above will allow breaks after, e.g., -% each of the four underscores in __typeof__. This is undesirable in -% some manuals, especially if they don't have long identifiers in -% general. @allowcodebreaks provides a way to control this. +% each of the four underscores in __typeof__. This is bad. +% @allowcodebreaks provides a document-level way to turn breaking at - +% and _ on and off. % \newif\ifallowcodebreaks \allowcodebreakstrue @@ -2562,6 +2541,13 @@ end \fi\fi } +% For @command, @env, @file, @option quotes seem unnecessary, +% so use \code rather than \samp. +\let\command=\code +\let\env=\code +\let\file=\code +\let\option=\code + % @uref (abbreviation for `urlref') takes an optional (comma-separated) % second argument specifying the text to display and an optional third % arg as text to display instead of (rather than in addition to) the url @@ -2708,10 +2694,6 @@ end \let\email=\uref \fi -% @kbd is like @code, except that if the argument is just one @key command, -% then @kbd has no effect. -\def\kbd#1{{\setupmarkupstyle{kbd}\def\look{#1}\expandafter\kbdfoo\look??\par}} - % @kbdinputstyle -- arg is `distinct' (@kbd uses slanted tty font always), % `example' (@kbd uses ttsl only inside of @example and friends), % or `code' (@kbd uses normal tty font always). @@ -2735,16 +2717,36 @@ end % Default is `distinct'. \kbdinputstyle distinct -\def\xkey{\key} -\def\kbdfoo#1#2#3\par{\def\one{#1}\def\three{#3}\def\threex{??}% -\ifx\one\xkey\ifx\threex\three \key{#2}% -\else{\tclose{\kbdfont\setupmarkupstyle{kbd}\look}}\fi -\else{\tclose{\kbdfont\setupmarkupstyle{kbd}\look}}\fi} +% @kbd is like @code, except that if the argument is just one @key command, +% then @kbd has no effect. +\def\kbd#1{{\def\look{#1}\expandafter\kbdsub\look??\par}} -% For @indicateurl, @env, @command quotes seem unnecessary, so use \code. -\let\indicateurl=\code -\let\env=\code -\let\command=\code +\def\xkey{\key} +\def\kbdsub#1#2#3\par{% + \def\one{#1}\def\three{#3}\def\threex{??}% + \ifx\one\xkey\ifx\threex\three \key{#2}% + \else{\tclose{\kbdfont\setupmarkupstyle{kbd}\look}}\fi + \else{\tclose{\kbdfont\setupmarkupstyle{kbd}\look}}\fi +} + +% definition of @key that produces a lozenge. Doesn't adjust to text size. +%\setfont\keyrm\rmshape{8}{1000}{OT1} +%\font\keysy=cmsy9 +%\def\key#1{{\keyrm\textfont2=\keysy \leavevmode\hbox{% +% \raise0.4pt\hbox{\angleleft}\kern-.08em\vtop{% +% \vbox{\hrule\kern-0.4pt +% \hbox{\raise0.4pt\hbox{\vphantom{\angleleft}}#1}}% +% \kern-0.4pt\hrule}% +% \kern-.06em\raise0.4pt\hbox{\angleright}}}} + +% definition of @key with no lozenge. If the current font is already +% monospace, don't change it; that way, we respect @kbdinputstyle. But +% if it isn't monospace, then use \tt. +% +\def\key#1{{\setupmarkupstyle{key}% + \nohyphenation + \ifmonospace\else\tt\fi + #1}\null} % @clicksequence{File @click{} Open ...} \def\clicksequence#1{\begingroup #1\endgroup} @@ -2852,6 +2854,9 @@ end } } +% ctrl is no longer a Texinfo command, but leave this definition for fun. +\def\ctrl #1{{\tt \rawbackslash \hat}#1} + % @inlinefmt{FMTNAME,PROCESSED-TEXT} and @inlineraw{FMTNAME,RAW-TEXT}. % Ignore unless FMTNAME == tex; then it is like @iftex and @tex, % except specified as a normal braced arg, so no newlines to worry about. @@ -3142,12 +3147,17 @@ end % hopefully nobody will notice/care. \edef\ecsize{\csname\curfontsize ecsize\endcsname}% \edef\nominalsize{\csname\curfontsize nominalsize\endcsname}% - \ifx\curfontstyle\bfstylename - % bold: - \font\thisecfont = ecb\ifusingit{i}{x}\ecsize \space at \nominalsize + \ifmonospace + % typewriter: + \font\thisecfont = ectt\ecsize \space at \nominalsize \else - % regular: - \font\thisecfont = ec\ifusingit{ti}{rm}\ecsize \space at \nominalsize + \ifx\curfontstyle\bfstylename + % bold: + \font\thisecfont = ecb\ifusingit{i}{x}\ecsize \space at \nominalsize + \else + % regular: + \font\thisecfont = ec\ifusingit{ti}{rm}\ecsize \space at \nominalsize + \fi \fi \thisecfont } @@ -3260,6 +3270,20 @@ end \finishedtitlepagetrue } +% Settings used for typesetting titles: no hyphenation, no indentation, +% don't worry much about spacing, ragged right. This should be used +% inside a \vbox, and fonts need to be set appropriately first. Because +% it is always used for titles, nothing else, we call \rmisbold. \par +% should be specified before the end of the \vbox, since a vbox is a group. +% +\def\raggedtitlesettings{% + \rmisbold + \hyphenpenalty=10000 + \parindent=0pt + \tolerance=5000 + \ptexraggedright +} + % Macros to be used within @titlepage: \let\subtitlerm=\tenrm @@ -3267,7 +3291,7 @@ end \parseargdef\title{% \checkenv\titlepage - \leftline{\titlefonts\rmisbold #1} + \vbox{\titlefonts \raggedtitlesettings #1\par}% % print a rule at the page bottom also. \finishedtitlepagefalse \vskip4pt \hrule height 4pt width \hsize \vskip4pt @@ -4164,7 +4188,7 @@ end % ..., but we might end up with active ones in the argument if % we're called from @code, as @code{@value{foo-bar_}}, though. % So \let them to their normal equivalents. - \let-\realdash \let_\normalunderscore + \let-\normaldash \let_\normalunderscore } } @@ -4204,7 +4228,7 @@ end } \def\ifsetfail{\doignore{ifset}} -% @ifclear VAR ... @end ifclear reads the `...' iff VAR has never been +% @ifclear VAR ... @end executes the `...' iff VAR has never been % defined with @set, or has been undefined with @clear. % % The `\else' inside the `\doifset' parameter is a trick to reuse the @@ -4215,6 +4239,35 @@ end \def\ifclear{\parsearg{\doifset{\else \let\next=\ifclearfail}}} \def\ifclearfail{\doignore{ifclear}} +% @ifcommandisdefined CMD ... @end executes the `...' if CMD (written +% without the @) is in fact defined. We can only feasibly check at the +% TeX level, so something like `mathcode' is going to considered +% defined even though it is not a Texinfo command. +% +\makecond{ifcommanddefined} +\def\ifcommanddefined{\parsearg{\doifcmddefined{\let\next=\ifcmddefinedfail}}} +% +\def\doifcmddefined#1#2{{% + \makevalueexpandable + \let\next=\empty + \expandafter\ifx\csname #2\endcsname\relax + #1% If not defined, \let\next as above. + \fi + \expandafter + }\next +} +\def\ifcmddefinedfail{\doignore{ifcommanddefined}} + +% @ifcommandnotdefined CMD ... handled similar to @ifclear above. +\makecond{ifcommandnotdefined} +\def\ifcommandnotdefined{% + \parsearg{\doifcmddefined{\else \let\next=\ifcmdnotdefinedfail}}} +\def\ifcmdnotdefinedfail{\doignore{ifcommandnotdefined}} + +% Set the `txicommandconditionals' variable, so documents have a way to +% test if the @ifcommand...defined conditionals are available. +\set txicommandconditionals + % @dircategory CATEGORY -- specify a category of the dir file % which this file should belong to. Ignore this in TeX. \let\dircategory=\comment @@ -4451,6 +4504,7 @@ end \definedummyword\guillemetright \definedummyword\guilsinglleft \definedummyword\guilsinglright + \definedummyword\lbracechar \definedummyword\leq \definedummyword\minus \definedummyword\ogonek @@ -4463,6 +4517,7 @@ end \definedummyword\quoteleft \definedummyword\quoteright \definedummyword\quotesinglbase + \definedummyword\rbracechar \definedummyword\result \definedummyword\textdegree % @@ -4514,6 +4569,7 @@ end \definedummyword\t % % Commands that take arguments. + \definedummyword\abbr \definedummyword\acronym \definedummyword\anchor \definedummyword\cite @@ -4525,7 +4581,9 @@ end \definedummyword\emph \definedummyword\env \definedummyword\file + \definedummyword\image \definedummyword\indicateurl + \definedummyword\inforef \definedummyword\kbd \definedummyword\key \definedummyword\math @@ -4572,7 +4630,10 @@ end % content at all. So for index sorting, we map @{ and @} to strings % starting with |, since that ASCII character is between ASCII { and }. \def\{{|a}% + \def\lbracechar{|a}% + % \def\}{|b}% + \def\rbracechar{|b}% % % Non-English letters. \def\AA{AA}% @@ -5533,14 +5594,6 @@ end % Define @majorheading, @heading and @subheading -% NOTE on use of \vbox for chapter headings, section headings, and such: -% 1) We use \vbox rather than the earlier \line to permit -% overlong headings to fold. -% 2) \hyphenpenalty is set to 10000 because hyphenation in a -% heading is obnoxious; this forbids it. -% 3) Likewise, headings look best if no \parindent is used, and -% if justification is not attempted. Hence \raggedright. - \def\majorheading{% {\advance\chapheadingskip by 10pt \chapbreak }% \parsearg\chapheadingzzz @@ -5548,10 +5601,8 @@ end \def\chapheading{\chapbreak \parsearg\chapheadingzzz} \def\chapheadingzzz#1{% - {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000 - \parindent=0pt\ptexraggedright - \rmisbold #1\hfill}}% - \bigskip \par\penalty 200\relax + \vbox{\chapfonts \raggedtitlesettings #1\par}% + \nobreak\bigskip \nobreak \suppressfirstparagraphindent } @@ -5710,8 +5761,7 @@ end % % Typeset the actual heading. \nobreak % Avoid page breaks at the interline glue. - \vbox{\hyphenpenalty=10000 \tolerance=5000 \parindent=0pt \ptexraggedright - \hangindent=\wd0 \centerparametersmaybe + \vbox{\raggedtitlesettings \hangindent=\wd0 \centerparametersmaybe \unhbox0 #1\par}% }% \nobreak\bigskip % no page break after a chapter title @@ -5733,18 +5783,18 @@ end \def\setchapterstyle #1 {\csname CHAPF#1\endcsname} % \def\unnchfopen #1{% -\chapoddpage {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000 - \parindent=0pt\ptexraggedright - \rmisbold #1\hfill}}\bigskip \par\nobreak + \chapoddpage + \vbox{\chapfonts \raggedtitlesettings #1\par}% + \nobreak\bigskip\nobreak } \def\chfopen #1#2{\chapoddpage {\chapfonts \vbox to 3in{\vfil \hbox to\hsize{\hfil #2} \hbox to\hsize{\hfil #1} \vfil}}% \par\penalty 5000 % } \def\centerchfopen #1{% -\chapoddpage {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000 - \parindent=0pt - \hfill {\rmisbold #1}\hfill}}\bigskip \par\nobreak + \chapoddpage + \vbox{\chapfonts \raggedtitlesettings \hfill #1\hfill}% + \nobreak\bigskip \nobreak } \def\CHAPFopen{% \global\let\chapmacro=\chfopen @@ -6510,16 +6560,9 @@ end \makedispenvdef{quotation}{\quotationstart} % \def\quotationstart{% - {\parskip=0pt \aboveenvbreak}% because \aboveenvbreak inserts \parskip - \parindent=0pt - % - % @cartouche defines \nonarrowing to inhibit narrowing at next level down. + \indentedblockstart % same as \indentedblock, but increase right margin too. \ifx\nonarrowing\relax - \advance\leftskip by \lispnarrowing \advance\rightskip by \lispnarrowing - \exdentamount = \lispnarrowing - \else - \let\nonarrowing = \relax \fi \parsearg\quotationlabel } @@ -6545,6 +6588,32 @@ end \fi } +% @indentedblock is like @quotation, but indents only on the left and +% has no optional argument. +% +\makedispenvdef{indentedblock}{\indentedblockstart} +% +\def\indentedblockstart{% + {\parskip=0pt \aboveenvbreak}% because \aboveenvbreak inserts \parskip + \parindent=0pt + % + % @cartouche defines \nonarrowing to inhibit narrowing at next level down. + \ifx\nonarrowing\relax + \advance\leftskip by \lispnarrowing + \exdentamount = \lispnarrowing + \else + \let\nonarrowing = \relax + \fi +} + +% Keep a nonzero parskip for the environment, since we're doing normal filling. +% +\def\Eindentedblock{% + \par + {\parskip=0pt \afterenvbreak}% +} +\def\Esmallindentedblock{\Eindentedblock} + % LaTeX-like @verbatim...@end verbatim and @verb{...} % If we want to allow any as delimiter, @@ -7023,7 +7092,10 @@ end \df \sl \hyphenchar\font=0 % % On the other hand, if an argument has two dashes (for instance), we - % want a way to get ttsl. Let's try @var for that. + % want a way to get ttsl. We used to recommend @var for that, so + % leave the code in, but it's strange for @var to lead to typewriter. + % Nowadays we recommend @code, since the difference between a ttsl hyphen + % and a tt hyphen is pretty tiny. @code also disables ?` !`. \def\var##1{{\setupmarkupstyle{var}\ttslanted{##1}}}% #1% \sl\hyphenchar\font=45 @@ -7807,7 +7879,7 @@ end \fi\fi } - +% % @xref, @pxref, and @ref generate cross-references. For \xrefX, #1 is % the node name, #2 the name of the Info cross-reference, #3 the printed % node name, #4 the name of the Info file, #5 the name of the printed @@ -7817,16 +7889,21 @@ end \def\xref#1{\putwordSee{} \xrefX[#1,,,,,,,]} \def\ref#1{\xrefX[#1,,,,,,,]} % -\newbox\topbox +\newbox\toprefbox \newbox\printedrefnamebox +\newbox\infofilenamebox \newbox\printedmanualbox % \def\xrefX[#1,#2,#3,#4,#5,#6]{\begingroup \unsepspaces % + % Get args without leading/trailing spaces. \def\printedrefname{\ignorespaces #3}% \setbox\printedrefnamebox = \hbox{\printedrefname\unskip}% % + \def\infofilename{\ignorespaces #4}% + \setbox\infofilenamebox = \hbox{\infofilename\unskip}% + % \def\printedmanual{\ignorespaces #5}% \setbox\printedmanualbox = \hbox{\printedmanual\unskip}% % @@ -7861,11 +7938,18 @@ end \turnoffactive \makevalueexpandable % This expands tokens, so do it after making catcode changes, so _ - % etc. don't get their TeX definitions. + % etc. don't get their TeX definitions. This ignores all spaces in + % #4, including (wrongly) those in the middle of the filename. \getfilename{#4}% % + % This (wrongly) does not take account of leading or trailing + % spaces in #1, which should be ignored. \edef\pdfxrefdest{#1}% - \txiescapepdf\pdfxrefdest + \ifx\pdfxrefdest\empty + \def\pdfxrefdest{Top}% no empty targets + \else + \txiescapepdf\pdfxrefdest % escape PDF special chars + \fi % \leavevmode \startlink attr{/Border [0 0 0]}% @@ -7898,7 +7982,7 @@ end \printedrefname \fi % - % if the user also gave the printed manual name (fifth arg), append + % If the user also gave the printed manual name (fifth arg), append % "in MANUALNAME". \ifdim \wd\printedmanualbox > 0pt \space \putwordin{} \cite{\printedmanual}% @@ -7913,32 +7997,20 @@ end % this is a loss. Therefore, we give the text of the node name % again, so it is as if TeX is seeing it for the first time. % - % Cross-manual reference. Only include the "Section ``foo'' in" if - % the foo is neither missing or Top. Thus, @xref{,,,foo,The Foo Manual} - % outputs simply "see The Foo Manual". \ifdim \wd\printedmanualbox > 0pt - % What is the 7sp about? The idea is that we also want to omit - % the Section part if we would be printing "Top", since they are - % clearly trying to refer to the whole manual. But, this being - % TeX, we can't easily compare strings while ignoring the possible - % spaces before and after in the input. By adding the arbitrary - % 7sp, we make it much less likely that a real node name would - % happen to have the same width as "Top" (e.g., in a monospaced font). - % I hope it will never happen in practice. + % Cross-manual reference with a printed manual name. % - % For the same basic reason, we retypeset the "Top" at every - % reference, since the current font is indeterminate. + \crossmanualxref{\cite{\printedmanual\unskip}}% + % + \else\ifdim \wd\infofilenamebox > 0pt + % Cross-manual reference with only an info filename (arg 4), no + % printed manual name (arg 5). This is essentially the same as + % the case above; we output the filename, since we have nothing else. % - \setbox\topbox = \hbox{Top\kern7sp}% - \setbox2 = \hbox{\ignorespaces \printedrefname \unskip \kern7sp}% - \ifdim \wd2 > 7sp - \ifdim \wd2 = \wd\topbox \else - \putwordSection{} ``\printedrefname'' \putwordin{}\space - \fi - \fi - \cite{\printedmanual}% + \crossmanualxref{\code{\infofilename\unskip}}% + % \else - % Reference in this manual. + % Reference within this manual. % % _ (for example) has to be the character _ for the purposes of the % control sequence corresponding to the node, but it has to expand @@ -7959,11 +8031,37 @@ end % % output the `page 3'. \turnoffactive \putwordpage\tie\refx{#1-pg}{}% - \fi + \fi\fi \fi \endlink \endgroup} +% Output a cross-manual xref to #1. Used just above (twice). +% +% Only include the text "Section ``foo'' in" if the foo is neither +% missing or Top. Thus, @xref{,,,foo,The Foo Manual} outputs simply +% "see The Foo Manual", the idea being to refer to the whole manual. +% +% But, this being TeX, we can't easily compare our node name against the +% string "Top" while ignoring the possible spaces before and after in +% the input. By adding the arbitrary 7sp below, we make it much less +% likely that a real node name would have the same width as "Top" (e.g., +% in a monospaced font). Hopefully it will never happen in practice. +% +% For the same basic reason, we retypeset the "Top" at every +% reference, since the current font is indeterminate. +% +\def\crossmanualxref#1{% + \setbox\toprefbox = \hbox{Top\kern7sp}% + \setbox2 = \hbox{\ignorespaces \printedrefname \unskip \kern7sp}% + \ifdim \wd2 > 7sp % nonempty? + \ifdim \wd2 = \wd\toprefbox \else % same as Top? + \putwordSection{} ``\printedrefname'' \putwordin{}\space + \fi + \fi + #1% +} + % This macro is called from \xrefX for the `[nodename]' part of xref % output. It's a separate macro only so it can be changed more easily, % since square brackets don't work well in some documents. Particularly @@ -9895,22 +9993,26 @@ directory should work if nowhere else does.} @gdef@otherbackslash{@let\=@realbackslash} % Same as @turnoffactive except outputs \ as {\tt\char`\\} instead of -% the literal character `\'. +% the literal character `\'. Also revert - to its normal character, in +% case the active - from code has slipped in. % -@def@normalturnoffactive{% - @let"=@normaldoublequote - @let$=@normaldollar %$ font-lock fix - @let+=@normalplus - @let<=@normalless - @let>=@normalgreater - @let\=@normalbackslash - @let^=@normalcaret - @let_=@normalunderscore - @let|=@normalverticalbar - @let~=@normaltilde - @markupsetuplqdefault - @markupsetuprqdefault - @unsepspaces +{@catcode`- = @active + @gdef@normalturnoffactive{% + @let-=@normaldash + @let"=@normaldoublequote + @let$=@normaldollar %$ font-lock fix + @let+=@normalplus + @let<=@normalless + @let>=@normalgreater + @let\=@normalbackslash + @let^=@normalcaret + @let_=@normalunderscore + @let|=@normalverticalbar + @let~=@normaltilde + @markupsetuplqdefault + @markupsetuprqdefault + @unsepspaces + } } % Make _ and + \other characters, temporarily. diff --git a/doc/tinc.8.in b/doc/tinc.8.in index fba373e..ebf9df1 100644 --- a/doc/tinc.8.in +++ b/doc/tinc.8.in @@ -90,6 +90,15 @@ is used. The same as export followed by import. .It exchange-all Op Fl -force The same as export-all followed by import. +.It invite Ar name +Prepares an invitation for a new node with the given +.Ar name , +and prints a short invitation URL that can be used with the join command. +.It join Op Ar URL +Join an existing VPN using an invitation URL created using the invite command. +If no +.Ar URL +is given, it will be read from standard input. .It start Op tincd options Start .Xr tincd 8 , @@ -97,9 +106,10 @@ optionally with the given extra options. .It stop Stop .Xr tincd 8 . -.It restart +.It restart Op tincd options Restart -.Xr tincd 8 . +.Xr tincd 8 , +optionally with the given extra options. .It reload Partially rereads configuration files. Connections to hosts whose host config files are removed are closed. New outgoing connections specified diff --git a/doc/tinc.conf.5.in b/doc/tinc.conf.5.in index 1cca366..69deace 100644 --- a/doc/tinc.conf.5.in +++ b/doc/tinc.conf.5.in @@ -274,14 +274,12 @@ The file in which the private ECDSA key of this tinc daemon resides. This is only used if .Va ExperimentalProtocol is enabled. -.It Va ExperimentalProtocol Li = yes | no Po no Pc Bq experimental -When this option is enabled, experimental protocol enhancements will be used. +.It Va ExperimentalProtocol Li = yes | no Pq yes +When this option is enabled, the SPTPS protocol will be used when connecting to nodes that also support it. Ephemeral ECDH will be used for key exchanges, and ECDSA will be used instead of RSA for authentication. When enabled, an ECDSA key must have been generated before with .Nm tinc generate-ecdsa-keys . -The experimental protocol may change at any time, -and there is no guarantee that tinc will run stable when it is used. .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 @@ -328,12 +326,20 @@ which normally would prevent the peers from learning each other's LAN address. .Pp Currently, local discovery is implemented by sending broadcast packets to the LAN during path MTU discovery. This feature may not work in all possible situations. +.It Va LocalDiscoveryAddress Li = Ar address +If this variable is specified, local discovery packets are sent to the given +.Ar address . .It Va MACExpire Li = Ar seconds Pq 600 This option controls the amount of time MAC addresses are kept before they are removed. This only has effect when .Va Mode is set to .Qq switch . +.It Va MaxConnectionBurst Li = Ar count Pq 100 +This option controls how many connections tinc accepts in quick succession. +If there are more connections than the given number in a short time interval, +tinc will reduce the number of accepted connections to only one per second, +until the burst has passed. .It Va MaxTimeout Li = Ar seconds Pq 900 This is the maximum delay before trying to reconnect to other tinc daemons. .It Va Mode Li = router | switch | hub Pq router diff --git a/doc/tinc.info b/doc/tinc.info index f46a430..0e4c5ec 100644 --- a/doc/tinc.info +++ b/doc/tinc.info @@ -1,11 +1,11 @@ -This is tinc.info, produced by makeinfo version 4.13 from tinc.texi. +This is tinc.info, produced by makeinfo version 5.1 from tinc.texi. INFO-DIR-SECTION Networking tools START-INFO-DIR-ENTRY * tinc: (tinc). The tinc Manual. END-INFO-DIR-ENTRY - This is the info manual for tinc version 1.1pre7, a Virtual Private +This is the info manual for tinc version 1.1pre7, a Virtual Private Network daemon. Copyright (C) 1998-2013 Ivo Timmermans, Guus Sliepen @@ -74,7 +74,7 @@ A Virtual Private Network or VPN is a network that can only be accessed by a few elected computers that participate. This goal is achievable in more than just one way. -Private networks can consist of a single stand-alone Ethernet LAN. Or +Private networks can consist of a single stand-alone Ethernet LAN. Or even two computers hooked up using a null-modem cable. In these cases, it is obvious that the network is _private_, no one can access it from the outside. But if your computers are linked to the Internet, the @@ -94,10 +94,10 @@ As is the case with either type of VPN, anybody could eavesdrop. Or worse, alter data. Hence it's probably advisable to encrypt the data that flows over the network. -When one introduces encryption, we can form a true VPN. Other people -may see encrypted traffic, but if they don't know how to decipher it -(they need to know the key for that), they cannot read the information -that flows through the VPN. This is what tinc was made for. +When one introduces encryption, we can form a true VPN. Other people may +see encrypted traffic, but if they don't know how to decipher it (they +need to know the key for that), they cannot read the information that +flows through the VPN. This is what tinc was made for.  File: tinc.info, Node: tinc, Next: Supported platforms, Prev: Virtual Private Networks, Up: Introduction @@ -108,8 +108,8 @@ File: tinc.info, Node: tinc, Next: Supported platforms, Prev: Virtual Private I really don't quite remember what got us started, but it must have been Guus' idea. He wrote a simple implementation (about 50 lines of C) that used the ethertap device that Linux knows of since somewhere about -kernel 2.1.60. It didn't work immediately and he improved it a bit. -At this stage, the project was still simply called "vpnd". +kernel 2.1.60. It didn't work immediately and he improved it a bit. At +this stage, the project was still simply called "vpnd". Since then, a lot has changed--to say the least. @@ -119,13 +119,13 @@ runtime-configurable--in short, it has become a full-fledged professional package. Tinc also allows more than two sites to connect to eachother and form a -single VPN. Traditionally VPNs are created by making tunnels, which -only have two endpoints. Larger VPNs with more sites are created by -adding more tunnels. Tinc takes another approach: only endpoints are +single VPN. Traditionally VPNs are created by making tunnels, which only +have two endpoints. Larger VPNs with more sites are created by adding +more tunnels. Tinc takes another approach: only endpoints are specified, the software itself will take care of creating the tunnels. This allows for easier configuration and improved scalability. -A lot can--and will be--changed. We have a number of things that we +A lot can--and will be--changed. We have a number of things that we would like to see in the future releases of tinc. Not everything will be available in the near future. Our first objective is to make tinc work perfectly as it stands, and then add more advanced features. @@ -148,7 +148,7 @@ will most likely compile and run, but it will not be able to send or receive data packets. For an up to date list of supported platforms, please check the list on -our website: `http://www.tinc-vpn.org/platforms/'. +our website: .  File: tinc.info, Node: Preparations, Next: Installation, Prev: Introduction, Up: Top @@ -199,7 +199,7 @@ It's not necessary to compile this driver as a module, even if you are going to run more than one instance of tinc. If you decide to build the tun/tap driver as a kernel module, add these -lines to `/etc/modules.conf': +lines to '/etc/modules.conf': alias char-major-10-200 tun @@ -211,8 +211,8 @@ File: tinc.info, Node: Configuration of FreeBSD kernels, Next: Configuration o For FreeBSD version 4.1 and higher, tun and tap drivers are included in the default kernel configuration. The tap driver can be loaded with -`kldload if_tap', or by adding `if_tap_load="YES"' to -`/boot/loader.conf'. +'kldload if_tap', or by adding 'if_tap_load="YES"' to +'/boot/loader.conf'.  File: tinc.info, Node: Configuration of OpenBSD kernels, Next: Configuration of NetBSD kernels, Prev: Configuration of FreeBSD kernels, Up: Configuring the kernel @@ -222,7 +222,7 @@ File: tinc.info, Node: Configuration of OpenBSD kernels, Next: Configuration o For OpenBSD version 2.9 and higher, the tun driver is included in the default kernel configuration. There is also a kernel patch from -`http://diehard.n-r-g.com/stuff/openbsd/' which adds a tap device to + which adds a tap device to OpenBSD which should work with tinc, but with recent versions of OpenBSD, a tun device can act as a tap device by setting the link0 option with ifconfig. @@ -246,9 +246,9 @@ File: tinc.info, Node: Configuration of Solaris kernels, Next: Configuration o For Solaris 8 (SunOS 5.8) and higher, the tun driver may or may not be included in the default kernel configuration. If it isn't, the source -can be downloaded from `http://vtun.sourceforge.net/tun/'. For x86 and +can be downloaded from . For x86 and sparc64 architectures, precompiled versions can be found at -`http://www.monkey.org/~dugsong/fragroute/'. If the `net/if_tun.h' +. If the 'net/if_tun.h' header file is missing, install it from the source package.  @@ -259,11 +259,11 @@ File: tinc.info, Node: Configuration of Darwin (MacOS/X) kernels, Next: Config Tinc on Darwin relies on a tunnel driver for its data acquisition from the kernel. Tinc supports either the driver from -`http://tuntaposx.sourceforge.net/', which supports both tun and tap +, which supports both tun and tap style devices, and also the driver from from -`http://chrisp.de/en/projects/tunnel.html'. The former driver is -recommended. The tunnel driver must be loaded before starting tinc -with the following command: +. The former driver is +recommended. The tunnel driver must be loaded before starting tinc with +the following command: kmodload tunnel @@ -273,8 +273,8 @@ File: tinc.info, Node: Configuration of Windows, Prev: Configuration of Darwin 2.1.7 Configuration of Windows ------------------------------ -You will need to install the latest TAP-Win32 driver from OpenVPN. You -can download it from `http://openvpn.sourceforge.net'. Using the +You will need to install the latest TAP-Win32 driver from OpenVPN. You +can download it from . Using the Network Connections control panel, configure the TAP-Win32 network interface in the same way as you would do from the tinc-up script, as explained in the rest of the documentation. @@ -287,8 +287,8 @@ File: tinc.info, Node: Libraries, Prev: Configuring the kernel, Up: Preparati Before you can configure or build tinc, you need to have the OpenSSL, zlib and lzo libraries installed on your system. If you try to -configure tinc without having them installed, configure will give you -an error message, and stop. +configure tinc without having them installed, configure will give you an +error message, and stop. * Menu: @@ -316,10 +316,9 @@ available. Make sure you install the development AND runtime versions of this package. If you have to install OpenSSL manually, you can get the source code -from `http://www.openssl.org/'. Instructions on how to configure, -build and install this package are included within the package. Please -make sure you build development and runtime libraries (which is the -default). +from . Instructions on how to configure, build +and install this package are included within the package. Please make +sure you build development and runtime libraries (which is the default). If you installed the OpenSSL libraries from source, it may be necessary to let configure know where they are, by passing configure one of the @@ -337,21 +336,21 @@ License The complete source code of tinc is covered by the GNU GPL version 2. Since the license under which OpenSSL is distributed is not directly compatible with the terms of the GNU GPL -`http://www.openssl.org/support/faq.html#LEGAL2', we include an +, we include an exemption to the GPL (see also the file COPYING.README) to allow everyone to create a statically or dynamically linked executable: This program is released under the GPL with the additional - exemption that compiling, linking, and/or using OpenSSL is - allowed. You may provide binary packages linked to the OpenSSL - libraries, provided that all other requirements of the GPL are met. + exemption that compiling, linking, and/or using OpenSSL is allowed. + You may provide binary packages linked to the OpenSSL libraries, + provided that all other requirements of the GPL are met. Since the LZO library used by tinc is also covered by the GPL, we also present the following exemption: Hereby I grant a special exception to the tinc VPN project - (http://www.tinc-vpn.org/) to link the LZO library with the - OpenSSL library (http://www.openssl.org). + (http://www.tinc-vpn.org/) to link the LZO library with the OpenSSL + library (http://www.openssl.org). Markus F.X.J. Oberhumer @@ -367,7 +366,7 @@ provided by the zlib library. If this library is not installed, you wil get an error when running the configure script. You can either install the zlib library, or disable support for zlib compression by using the "-disable-zlib" option when -running the configure script. Note that if you disable support for +running the configure script. Note that if you disable support for zlib, the resulting binary will not work correctly on VPNs where zlib compression is used. @@ -376,7 +375,7 @@ available. Make sure you install the development AND runtime versions of this package. If you have to install zlib manually, you can get the source code from -`http://www.gzip.org/zlib/'. Instructions on how to configure, build +. Instructions on how to configure, build and install this package are included within the package. Please make sure you build development and runtime libraries (which is the default). @@ -391,7 +390,7 @@ Another form of compression is offered using the LZO library. If this library is not installed, you wil get an error when running the configure script. You can either install the LZO library, or disable support for LZO compression by using the "-disable-lzo" option when -running the configure script. Note that if you disable support for LZO, +running the configure script. Note that if you disable support for LZO, the resulting binary will not work correctly on VPNs where LZO compression is used. @@ -400,7 +399,7 @@ available. Make sure you install the development AND runtime versions of this package. If you have to install lzo manually, you can get the source code from -`http://www.oberhumer.com/opensource/lzo/'. Instructions on how to +. Instructions on how to configure, build and install this package are included within the package. Please make sure you build development and runtime libraries (which is the default). @@ -418,14 +417,14 @@ configure script. You can either install a suitable curses library, or disable all functionality that depends on a curses library by using the "-disable-curses" option when running the configure script. -There are several curses libraries. It is recommended that you install -"ncurses" (`http://invisible-island.net/ncurses/'), however other -curses libraries should also work. In particular, "PDCurses" -(`http://pdcurses.sourceforge.net/') is recommended if you want to +There are several curses libraries. It is recommended that you install +"ncurses" (), however other curses +libraries should also work. In particular, "PDCurses" +() is recommended if you want to compile tinc for Windows. You can use your operating system's package manager to install this if -available. Make sure you install the development AND runtime versions +available. Make sure you install the development AND runtime versions of this package.  @@ -439,16 +438,16 @@ library. If this library is not installed, you wil get an error when running the configure script. You can either install a suitable readline library, -or disable all functionality that depends on a readline library by -using the "-disable-readline" option when running the configure script. +or disable all functionality that depends on a readline library by using +the "-disable-readline" option when running the configure script. You can use your operating system's package manager to install this if available. Make sure you install the development AND runtime versions of this package. -If you have to install libreadline manually, you can get the source -code from `http://www.gnu.org/software/readline/'. Instructions on how -to configure, build and install this package are included within the +If you have to install libreadline manually, you can get the source code +from . Instructions on how to +configure, build and install this package are included within the package. Please make sure you build development and runtime libraries (which is the default). @@ -464,15 +463,15 @@ startup scripts and sample configurations. If you cannot use one of the precompiled packages, or you want to compile tinc for yourself, you can use the source. The source is -distributed under the GNU General Public License (GPL). Download the -source from the download page (http://www.tinc-vpn.org/download/), -which has the checksums of these files listed; you may wish to check -these with md5sum before continuing. +distributed under the GNU General Public License (GPL). Download the +source from the download page (http://www.tinc-vpn.org/download/), which +has the checksums of these files listed; you may wish to check these +with md5sum before continuing. Tinc comes in a convenient autoconf/automake package, which you can just treat the same as any other package. Which is just untar it, type -`./configure' and then `make'. More detailed instructions are in the -file `INSTALL', which is included in the source distribution. +'./configure' and then 'make'. More detailed instructions are in the +file 'INSTALL', which is included in the source distribution. * Menu: @@ -486,12 +485,12 @@ File: tinc.info, Node: Building and installing tinc, Next: System files, Up: ================================ Detailed instructions on configuring the source, building tinc and -installing tinc can be found in the file called `INSTALL'. +installing tinc can be found in the file called 'INSTALL'. If you happen to have a binary package for tinc for your distribution, -you can use the package management tools of that distribution to -install tinc. The documentation that comes along with your -distribution will tell you how to do that. +you can use the package management tools of that distribution to install +tinc. The documentation that comes along with your distribution will +tell you how to do that. * Menu: @@ -506,9 +505,8 @@ File: tinc.info, Node: Darwin (MacOS/X) build environment, Next: Cygwin (Windo ---------------------------------------- In order to build tinc on Darwin, you need to install the MacOS/X -Developer Tools from -`http://developer.apple.com/tools/macosxtools.html' and a recent -version of Fink from `http://www.finkproject.org/'. +Developer Tools from +and a recent version of Fink from . After installation use fink to download and install the following packages: autoconf25, automake, dlcompat, m4, openssl, zlib and lzo. @@ -520,11 +518,11 @@ File: tinc.info, Node: Cygwin (Windows) build environment, Next: MinGW (Window ---------------------------------------- If Cygwin hasn't already been installed, install it directly from -`http://www.cygwin.com/'. +. When tinc is compiled in a Cygwin environment, it can only be run in this environment, but all programs, including those started outside the -Cygwin environment, will be able to use the VPN. It will also support +Cygwin environment, will be able to use the VPN. It will also support all features.  @@ -534,7 +532,7 @@ File: tinc.info, Node: MinGW (Windows) build environment, Prev: Cygwin (Window --------------------------------------- You will need to install the MinGW environment from -`http://www.mingw.org'. +. When tinc is compiled using MinGW it runs natively under Windows, it is not necessary to keep MinGW installed. @@ -576,20 +574,20 @@ File: tinc.info, Node: Other files, Prev: Device files, Up: System files 3.2.2 Other files ----------------- -`/etc/networks' +'/etc/networks' ............... -You may add a line to `/etc/networks' so that your VPN will get a +You may add a line to '/etc/networks' so that your VPN will get a symbolic name. For example: myvpn 10.0.0.0 -`/etc/services' +'/etc/services' ............... -You may add this line to `/etc/services'. The effect is that you may -supply a `tinc' as a valid port number to some programs. The number -655 is registered with the IANA. +You may add this line to '/etc/services'. The effect is that you may +supply a 'tinc' as a valid port number to some programs. The number 655 +is registered with the IANA. tinc 655/tcp TINC tinc 655/udp TINC @@ -620,23 +618,23 @@ Before actually starting to configure tinc and editing files, make sure you have read this entire section so you know what to expect. Then, make it clear to yourself how you want to organize your VPN: What are the nodes (computers running tinc)? What IP addresses/subnets do they -have? What is the network mask of the entire VPN? Do you need special +have? What is the network mask of the entire VPN? Do you need special firewall rules? Do you have to set up masquerading or forwarding rules? Do you want to run tinc in router mode or switch mode? These questions can only be answered by yourself, you will not find the answers in this -documentation. Make sure you have an adequate understanding of -networks in general. A good resource on networking is the Linux -Network Administrators Guide (http://www.tldp.org/LDP/nag2/). +documentation. Make sure you have an adequate understanding of networks +in general. A good resource on networking is the Linux Network +Administrators Guide (http://www.tldp.org/LDP/nag2/). If you have everything clearly pictured in your mind, proceed in the following order: First, create the initial configuration files and public/private keypairs using the following command: tinc -n NETNAME init NAME -Second, use `tinc -n NETNAME add ...' to further configure tinc. -Finally, export your host configuration file using `tinc -n NETNAME +Second, use 'tinc -n NETNAME add ...' to further configure tinc. +Finally, export your host configuration file using 'tinc -n NETNAME export' and send it to those people or computers you want tinc to connect to. They should send you their host configuration file back, -which you can import using `tinc -n NETNAME import'. +which you can import using 'tinc -n NETNAME import'. These steps are described in the subsections below. @@ -648,7 +646,7 @@ File: tinc.info, Node: Multiple networks, Next: How connections work, Prev: C In order to allow you to run more than one tinc daemon on one computer, for instance if your computer is part of more than one VPN, you can -assign a NETNAME to your VPN. It is not required if you only run one +assign a NETNAME to your VPN. It is not required if you only run one tinc daemon, it doesn't even have to be the same on all the nodes of your VPN, but it is recommended that you choose one anyway. @@ -656,18 +654,18 @@ We will asume you use a netname throughout this document. This means that you call tinc with the -n argument, which will specify the netname. The effect of this option is that tinc will set its configuration root -to `/etc/tinc/NETNAME/', where NETNAME is your argument to the -n +to '/etc/tinc/NETNAME/', where NETNAME is your argument to the -n option. You will also notice that log messages it appears in syslog as -coming from `tinc.NETNAME', and on Linux, unless specified otherwise, +coming from 'tinc.NETNAME', and on Linux, unless specified otherwise, the name of the virtual network interface will be the same as the network name. However, it is not strictly necessary that you call tinc with the -n -option. If you don not use it, the network name will just be empty, and -tinc will look for files in `/etc/tinc/' instead of -`/etc/tinc/NETNAME/'; the configuration file will then be -`/etc/tinc/tinc.conf', and the host configuration files are expected to -be in `/etc/tinc/hosts/'. +option. If you don not use it, the network name will just be empty, and +tinc will look for files in '/etc/tinc/' instead of +'/etc/tinc/NETNAME/'; the configuration file will then be +'/etc/tinc/tinc.conf', and the host configuration files are expected to +be in '/etc/tinc/hosts/'.  File: tinc.info, Node: How connections work, Next: Configuration files, Prev: Multiple networks, Up: Configuration @@ -676,38 +674,38 @@ File: tinc.info, Node: How connections work, Next: Configuration files, Prev: ======================== When tinc starts up, it parses the command-line options and then reads -in the configuration file tinc.conf. If it sees one or more -`ConnectTo' values pointing to other tinc daemons in that file, it will -try to connect to those other daemons. Whether this succeeds or not -and whether `ConnectTo' is specified or not, tinc will listen for -incoming connection from other deamons. If you did specify a -`ConnectTo' value and the other side is not responding, tinc will keep -retrying. This means that once started, tinc will stay running until -you tell it to stop, and failures to connect to other tinc daemons will -not stop your tinc daemon for trying again later. This means you don't -have to intervene if there are temporary network problems. +in the configuration file tinc.conf. If it sees one or more 'ConnectTo' +values pointing to other tinc daemons in that file, it will try to +connect to those other daemons. Whether this succeeds or not and +whether 'ConnectTo' is specified or not, tinc will listen for incoming +connection from other deamons. If you did specify a 'ConnectTo' value +and the other side is not responding, tinc will keep retrying. This +means that once started, tinc will stay running until you tell it to +stop, and failures to connect to other tinc daemons will not stop your +tinc daemon for trying again later. This means you don't have to +intervene if there are temporary network problems. There is no real distinction between a server and a client in tinc. If -you wish, you can view a tinc daemon without a `ConnectTo' value as a +you wish, you can view a tinc daemon without a 'ConnectTo' value as a server, and one which does specify such a value as a client. It does -not matter if two tinc daemons have a `ConnectTo' value pointing to -each other however. +not matter if two tinc daemons have a 'ConnectTo' value pointing to each +other however. -Connections specified using `ConnectTo' are so-called meta-connections. -Tinc daemons exchange information about all other daemon they know -about via these meta-connections. After learning about all the daemons -in the VPN, tinc will create other connections as necessary in order to -communicate with them. For example, if there are three daemons named -A, B and C, and A has `ConnectTo = B' in its tinc.conf file, and C has -`ConnectTo = B' in its tinc.conf file, then A will learn about C from B, -and will be able to exchange VPN packets with C without the need to -have `ConnectTo = C' in its tinc.conf file. +Connections specified using 'ConnectTo' are so-called meta-connections. +Tinc daemons exchange information about all other daemon they know about +via these meta-connections. After learning about all the daemons in the +VPN, tinc will create other connections as necessary in order to +communicate with them. For example, if there are three daemons named A, +B and C, and A has 'ConnectTo = B' in its tinc.conf file, and C has +'ConnectTo = B' in its tinc.conf file, then A will learn about C from B, +and will be able to exchange VPN packets with C without the need to have +'ConnectTo = C' in its tinc.conf file. It could be that some daemons are located behind a Network Address Translation (NAT) device, or behind a firewall. In the above scenario with three daemons, if A and C are behind a NAT, B will automatically -help A and C punch holes through their NAT, in a way similar to the -STUN protocol, so that A and C can still communicate with each other +help A and C punch holes through their NAT, in a way similar to the STUN +protocol, so that A and C can still communicate with each other directly. It is not always possible to do this however, and firewalls might also prevent direct communication. In that case, VPN packets between A and C will be forwarded by B. @@ -723,8 +721,8 @@ File: tinc.info, Node: Configuration files, Next: Network interfaces, Prev: H ======================= The actual configuration of the daemon is done in the file -`/etc/tinc/NETNAME/tinc.conf' and at least one other file in the -directory `/etc/tinc/NETNAME/hosts/'. +'/etc/tinc/NETNAME/tinc.conf' and at least one other file in the +directory '/etc/tinc/NETNAME/hosts/'. These file consists of comments (lines started with a #) or assignments in the form of @@ -733,13 +731,13 @@ in the form of The variable names are case insensitive, and any spaces, tabs, newlines and carriage returns are ignored. Note: it is not required that you put -in the `=' sign, but doing so improves readability. If you leave it +in the '=' sign, but doing so improves readability. If you leave it out, remember to replace it with at least one space character. The server configuration is complemented with host specific -configuration (see the next section). Although all host configuration +configuration (see the next section). Although all host configuration options for the local node listed in this document can also be put in -`/etc/tinc/NETNAME/tinc.conf', it is recommended to put host specific +'/etc/tinc/NETNAME/tinc.conf', it is recommended to put host specific configuration options in the host configuration file, as this makes it easy to exchange with other nodes. @@ -789,34 +787,33 @@ BindToAddress =
[] BindToInterface = [experimental] If you have more than one network interface in your computer, tinc - will by default listen on all of them for incoming connections. - It is possible to bind tinc to a single interface like eth0 or - ppp0 with this variable. + will by default listen on all of them for incoming connections. It + is possible to bind tinc to a single interface like eth0 or ppp0 + with this variable. - This option may not work on all platforms. Also, on some - platforms it will not actually bind to an interface, but rather to - the address that the interface has at the moment a socket is - created. + This option may not work on all platforms. Also, on some platforms + it will not actually bind to an interface, but rather to the + address that the interface has at the moment a socket is created. Broadcast = (mst) [experimental] This option selects the way broadcast packets are sent to other daemons. _NOTE: all nodes in a VPN must use the same Broadcast mode, otherwise routing loops can form._ - no + no Broadcast packets are never sent to other nodes. - mst - Broadcast packets are sent and forwarded via the VPN's - Minimum Spanning Tree. This ensures broadcast packets reach - all nodes. + mst + Broadcast packets are sent and forwarded via the VPN's Minimum + Spanning Tree. This ensures broadcast packets reach all + nodes. - direct + direct Broadcast packets are sent directly to all nodes that can be - reached directly. Broadcast packets received from other - nodes are never forwarded. If the IndirectData option is - also set, broadcast packets will only be sent to nodes which - we have a meta connection to. + reached directly. Broadcast packets received from other nodes + are never forwarded. If the IndirectData option is also set, + broadcast packets will only be sent to nodes which we have a + meta connection to. ConnectTo = Specifies which other tinc daemon to connect to on startup. @@ -838,12 +835,12 @@ DecrementTTL = (no) [experimental] Do not use this option if you use switch mode and want to use IPv6. -Device = (`/dev/tap0', `/dev/net/tun' or other depending on platform) +Device = ('/dev/tap0', '/dev/net/tun' or other depending on platform) The virtual network device to use. Tinc will automatically detect what kind of device it is. Note that you can only use one device per daemon. Under Windows, use INTERFACE instead of DEVICE. Note - that you can only use one device per daemon. See also *note - Device files::. + that you can only use one device per daemon. See also *note Device + files::. DeviceType = (platform dependent) The type of the virtual network device. Tinc will normally @@ -852,99 +849,97 @@ DeviceType = (platform dependent) select one of the special interface types, if support for them is compiled in. - dummy - Use a dummy interface. No packets are ever read or written - to a virtual network device. Useful for testing, or when - setting up a node that only forwards packets for other nodes. + dummy + Use a dummy interface. No packets are ever read or written to + a virtual network device. Useful for testing, or when setting + up a node that only forwards packets for other nodes. - raw_socket + raw_socket Open a raw socket, and bind it to a pre-existing INTERFACE (eth0 by default). All packets are read from this interface. Packets received for the local node are written to the raw - socket. However, at least on Linux, the operating system - does not process IP packets destined for the local host. + socket. However, at least on Linux, the operating system does + not process IP packets destined for the local host. - multicast + multicast Open a multicast UDP socket and bind it to the address and port (separated by spaces) and optionally a TTL value specified using DEVICE. Packets are read from and written to this multicast socket. This can be used to connect to UML, QEMU or KVM instances listening on the same multicast address. Do NOT connect multiple tinc daemons to the same multicast - address, this will very likely cause routing loops. Also - note that this can cause decrypted VPN packets to be sent out - on a real network if misconfigured. + address, this will very likely cause routing loops. Also note + that this can cause decrypted VPN packets to be sent out on a + real network if misconfigured. - uml (not compiled in by default) - Create a UNIX socket with the filename specified by DEVICE, - or `/var/run/NETNAME.umlsocket' if not specified. Tinc will - wait for a User Mode Linux instance to connect to this socket. + uml (not compiled in by default) + Create a UNIX socket with the filename specified by DEVICE, or + '/var/run/NETNAME.umlsocket' if not specified. Tinc will wait + for a User Mode Linux instance to connect to this socket. - vde (not compiled in by default) + vde (not compiled in by default) Uses the libvdeplug library to connect to a Virtual Distributed Ethernet switch, using the UNIX socket specified - by DEVICE, or `/var/run/vde.ctl' if not specified. + by DEVICE, or '/var/run/vde.ctl' if not specified. Also, in case tinc does not seem to correctly interpret packets received from the virtual network device, it can be used to change the way packets are interpreted: - tun (BSD and Linux) + tun (BSD and Linux) Set type to tun. Depending on the platform, this can either be with or without an address family header (see below). - tunnohead (BSD) + tunnohead (BSD) Set type to tun without an address family header. Tinc will expect packets read from the virtual network device to start with an IP header. On some platforms IPv6 packets cannot be read from or written to the device in this mode. - tunifhead (BSD) + tunifhead (BSD) Set type to tun with an address family header. Tinc will expect packets read from the virtual network device to start with a four byte header containing the address family, followed by an IP header. This mode should support both IPv4 and IPv6 packets. - tap (BSD and Linux) + tap (BSD and Linux) 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 + 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. -ECDSAPrivateKeyFile = (`/etc/tinc/NETNAME/ecdsa_key.priv') +ECDSAPrivateKeyFile = ('/etc/tinc/NETNAME/ecdsa_key.priv') The file in which the private ECDSA key of this tinc daemon resides. This is only used if ExperimentalProtocol is enabled. -ExperimentalProtocol = (no) [experimental] - When this option is enabled, experimental protocol enhancements - will be used. Ephemeral ECDH will be used for key exchanges, and - ECDSA will be used instead of RSA for authentication. When - enabled, an ECDSA key must have been generated before with `tinc - generate-ecdsa-keys'. The experimental protocol may change at any - time, and there is no guarantee that tinc will run stable when it - is used. +ExperimentalProtocol = (yes) + When this option is enabled, the SPTPS protocol will be used when + connecting to nodes that also support it. Ephemeral ECDH will be + used for key exchanges, and ECDSA will be used instead of RSA for + authentication. When enabled, an ECDSA key must have been + generated before with 'tinc generate-ecdsa-keys'. Forwarding = (internal) [experimental] This option selects the way indirect packets are forwarded. - off + 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. + 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 + 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 @@ -977,13 +972,17 @@ LocalDiscovery = (no) prevent the peers from learning each other's LAN address. Currently, local discovery is implemented by sending broadcast - packets to the LAN during path MTU discovery. This feature may - not work in all possible situations. + packets to the LAN during path MTU discovery. This feature may not + work in all possible situations. + +LocalDiscoveryAddress
+ If this variable is specified, local discovery packets are sent to + the given ADDRESS. Mode = (router) This option selects the way packets are routed to other daemons. - router + router In this mode Subnet variables in the host configuration files will be used to form a routing table. Only packets of routable protocols (IPv4 and IPv6) are supported in this mode. @@ -991,7 +990,7 @@ Mode = (router) This is the default mode, and unless you really know you need another mode, don't change it. - switch + switch In this mode the MAC addresses of the packets on the VPN will be used to dynamically create a routing table just like an Ethernet switch does. Unicast, multicast and broadcast @@ -1002,7 +1001,7 @@ Mode = (router) This mode is primarily useful if you want to bridge Ethernet segments. - hub + hub This mode is almost the same as the switch mode, but instead every packet will be broadcast to the other daemons while no routing table is managed. @@ -1018,6 +1017,12 @@ MACExpire = (600) before they are removed. This only has effect when Mode is set to "switch". +MaxConnectionBurst = (100) + This option controls how many connections tinc accepts in quick + succession. If there are more connections than the given number in + a short time interval, tinc will reduce the number of accepted + connections to only one per second, until the burst has passed. + Name = [required] This is a symbolic name for this connection. The name should consist only of alfanumeric and underscore characters (a-z, A-Z, @@ -1025,9 +1030,9 @@ Name = [required] If Name starts with a $, then the contents of the environment variable that follows will be used. In that case, invalid - characters will be converted to underscores. If Name is $HOST, - but no such environment variable exist, the hostname will be read - using the gethostname() system call. + characters will be converted to underscores. If Name is $HOST, but + no such environment variable exist, the hostname will be read using + the gethostname() system call. PingInterval = (60) The number of seconds of inactivity that tinc will wait before @@ -1035,7 +1040,7 @@ PingInterval = (60) PingTimeout = (5) The number of seconds to wait for a response to pings or to allow - meta connections to block. If the other end doesn't respond within + meta connections to block. If the other end doesn't respond within this time, the connection is terminated, and the others will be notified of this. @@ -1045,14 +1050,14 @@ PriorityInheritance = (no) [experimental] out. PrivateKey = [obsolete] - This is the RSA private key for tinc. However, for safety reasons + This is the RSA private key for tinc. However, for safety reasons it is advised to store private keys of any kind in separate files. This prevents accidental eavesdropping if you are editting the configuration file. -PrivateKeyFile = (`/etc/tinc/NETNAME/rsa_key.priv') +PrivateKeyFile = ('/etc/tinc/NETNAME/rsa_key.priv') This is the full path name of the RSA private key file that was - generated by `tinc generate-keys'. It must be a full path, not a + generated by 'tinc generate-keys'. It must be a full path, not a relative directory. ProcessPriority = @@ -1064,47 +1069,47 @@ Proxy = socks4 | socks4 | http | exec ... [experimental] Use a proxy when making outgoing connections. The following proxy types are currently supported: - socks4
[] + socks4
[] Connects to the proxy using the SOCKS version 4 protocol. - Optionally, a USERNAME can be supplied which will be passed - on to the proxy server. + Optionally, a USERNAME can be supplied which will be passed on + to the proxy server. - socks4
[ ] - Connect to the proxy using the SOCKS version 5 protocol. If - a USERNAME and PASSWORD are given, basic username/password + socks4
[ ] + Connect to the proxy using the SOCKS version 5 protocol. If a + USERNAME and PASSWORD are given, basic username/password authentication will be used, otherwise no authentication will be used. - http
+ http
Connects to the proxy and sends a HTTP CONNECT request. - exec + exec Executes the given command which should set up the outgoing - connection. The environment variables `NAME', `NODE', - `REMOTEADDRES' and `REMOTEPORT' are available. + connection. The environment variables 'NAME', 'NODE', + 'REMOTEADDRES' and 'REMOTEPORT' are available. ReplayWindow = (16) This is the size of the replay tracking window for each remote - node, in bytes. The window is a bitfield which tracks 1 packet - per bit, so for example the default setting of 16 will track up to - 128 packets in the window. In high bandwidth scenarios, setting - this to a higher value can reduce packet loss from the interaction - of replay tracking with underlying real packet loss and/or - reordering. Setting this to zero will disable replay tracking - completely and pass all traffic, but leaves tinc vulnerable to - replay-based attacks on your traffic. + node, in bytes. The window is a bitfield which tracks 1 packet per + bit, so for example the default setting of 16 will track up to 128 + packets in the window. In high bandwidth scenarios, setting this + to a higher value can reduce packet loss from the interaction of + replay tracking with underlying real packet loss and/or reordering. + Setting this to zero will disable replay tracking completely and + pass all traffic, but leaves tinc vulnerable to replay-based + attacks on your traffic. 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. + '/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 - 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. + 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 + '/etc/tinc/NETNAME/hosts/' directory. Setting this options also + implicitly sets StrictSubnets. UDPRcvBuf = (OS default) Sets the socket receive buffer size for the UDP socket, in bytes. @@ -1116,7 +1121,6 @@ UDPSndBuf = Pq OS default unset, the default buffer size will be used by the operating system. -  File: tinc.info, Node: Host configuration variables, Next: Scripts, Prev: Main configuration variables, Up: Configuration files @@ -1124,24 +1128,24 @@ File: tinc.info, Node: Host configuration variables, Next: Scripts, Prev: Mai ---------------------------------- 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. If no - port is specified, the default Port is used. + 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. Cipher = (blowfish) The symmetric cipher algorithm used to encrypt UDP packets using the legacy protocol. 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. This option has no effect for connections using the - SPTPS protocol, which always use AES-256-CTR. + encryption. It is best to use only those ciphers which support CBC + mode. This option has no effect for connections using the SPTPS + protocol, which always use AES-256-CTR. 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. + 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. @@ -1152,8 +1156,8 @@ Digest = (sha1) The digest algorithm used to authenticate UDP packets using the legacy protocol. Any digest supported by OpenSSL is recognized. Furthermore, specifying "none" will turn off packet authentication. - This option has no effect for connections using the SPTPS - protocol, which always use HMAC-SHA-256. + This option has no effect for connections using the SPTPS protocol, + which always use HMAC-SHA-256. IndirectData = (no) When set to yes, other nodes which do not already have a meta @@ -1163,33 +1167,33 @@ IndirectData = (no) MACLength = (4) The length of the message authentication code used to authenticate UDP packets using the legacy protocol. Can be anything from 0 up - to the length of the digest produced by the digest algorithm. - This option has no effect for connections using the SPTPS - protocol, which never truncate MACs. + to the length of the digest produced by the digest algorithm. This + option has no effect for connections using the SPTPS protocol, + which never truncate MACs. PMTU = (1514) This option controls the initial path MTU to this node. PMTUDiscovery = (yes) - 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. + 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. Port = (655) This is the port this tinc daemon listens on. You can use decimal - portnumbers or symbolic names (as listed in `/etc/services'). + portnumbers or symbolic names (as listed in '/etc/services'). PublicKey = [obsolete] This is the RSA public key for this host. PublicKeyFile = [obsolete] This is the full path name of the RSA public key file that was - generated by `tinc generate-keys'. It must be a full path, not a + generated by 'tinc generate-keys'. It must be a full path, not a relative directory. From version 1.0pre4 on tinc will store the public key directly into the host configuration file in PEM format, the above two - options then are not necessary. Either the PEM format is used, or + options then are not necessary. Either the PEM format is used, or exactly *one of the above two options* must be specified in each host configuration file, if you want to be able to establish a connection with that host. @@ -1197,39 +1201,38 @@ PublicKeyFile = [obsolete] Subnet = The subnet which this tinc daemon will serve. Tinc tries to look up which other daemon it should send a packet to by searching the - appropiate subnet. If the packet matches a subnet, it will be - sent to the daemon who has this subnet in his host configuration - file. Multiple subnet lines can be specified for each daemon. + appropiate subnet. If the packet matches a subnet, it will be sent + to the daemon who has this subnet in his host configuration file. + Multiple subnet lines can be specified for each daemon. Subnets can either be single MAC, IPv4 or IPv6 addresses, in which - case a subnet consisting of only that single address is assumed, - or they can be a IPv4 or IPv6 network address with a prefixlength. + case a subnet consisting of only that single address is assumed, or + they can be a IPv4 or IPv6 network address with a prefixlength. For example, IPv4 subnets must be in a form like 192.168.1.0/24, where 192.168.1.0 is the network address and 24 is the number of - bits set in the netmask. Note that subnets like 192.168.1.1/24 - are invalid! Read a networking HOWTO/FAQ/guide if you don't - understand this. IPv6 subnets are notated like fec0:0:0:1::/64. - MAC addresses are notated like 0:1a:2b:3c:4d:5e. + bits set in the netmask. Note that subnets like 192.168.1.1/24 are + invalid! Read a networking HOWTO/FAQ/guide if you don't understand + this. IPv6 subnets are notated like fec0:0:0:1::/64. MAC + addresses are notated like 0:1a:2b:3c:4d:5e. Prefixlength is the number of bits set to 1 in the netmask part; for example: netmask 255.255.255.0 would become /24, 255.255.252.0 - becomes /22. This conforms to standard CIDR notation as described + becomes /22. This conforms to standard CIDR notation as described in RFC1519 (http://www.ietf.org/rfc/rfc1519.txt) A Subnet can be given a weight to indicate its priority over - identical Subnets owned by different nodes. The default weight is - 10. Lower values indicate higher priority. Packets will be sent to - the node with the highest priority, unless that node is not + identical Subnets owned by different nodes. The default weight is + 10. Lower values indicate higher priority. Packets will be sent + to the node with the highest priority, unless that node is not reachable, in which case the node with the next highest priority will be tried, and so on. TCPonly = (no) - If this variable is set to yes, then the packets are tunnelled - over a TCP connection instead of a UDP connection. This is - especially useful for those who want to run a tinc daemon from - behind a masquerading firewall, or if UDP packet routing is - disabled somehow. Setting this options also implicitly sets - IndirectData. + If this variable is set to yes, then the packets are tunnelled over + a TCP connection instead of a UDP connection. This is especially + useful for those who want to run a tinc daemon from behind a + masquerading firewall, or if UDP packet routing is disabled + somehow. Setting this options also implicitly sets IndirectData.  File: tinc.info, Node: Scripts, Next: How to configure, Prev: Host configuration variables, Up: Configuration files @@ -1241,7 +1244,7 @@ Apart from reading the server and host configuration files, tinc can also run scripts at certain moments. Under Windows (not Cygwin), the scripts should have the extension .bat. -`/etc/tinc/NETNAME/tinc-up' +'/etc/tinc/NETNAME/tinc-up' This is the most important script. If it is present it will be executed right after the tinc daemon has been started and has connected to the virtual network device. It should be used to set @@ -1249,74 +1252,71 @@ scripts should have the extension .bat. start other things. Under Windows you can use the Network Connections control panel instead of creating this script. -`/etc/tinc/NETNAME/tinc-down' +'/etc/tinc/NETNAME/tinc-down' This script is started right before the tinc daemon quits. -`/etc/tinc/NETNAME/hosts/HOST-up' +'/etc/tinc/NETNAME/hosts/HOST-up' This script is started when the tinc daemon with name HOST becomes reachable. -`/etc/tinc/NETNAME/hosts/HOST-down' +'/etc/tinc/NETNAME/hosts/HOST-down' This script is started when the tinc daemon with name HOST becomes unreachable. -`/etc/tinc/NETNAME/host-up' +'/etc/tinc/NETNAME/host-up' This script is started when any host becomes reachable. -`/etc/tinc/NETNAME/host-down' +'/etc/tinc/NETNAME/host-down' This script is started when any host becomes unreachable. -`/etc/tinc/NETNAME/subnet-up' - This script is started when a Subnet becomes reachable. The - Subnet and the node it belongs to are passed in environment - variables. +'/etc/tinc/NETNAME/subnet-up' + This script is started when a Subnet becomes reachable. The Subnet + and the node it belongs to are passed in environment variables. -`/etc/tinc/NETNAME/subnet-down' +'/etc/tinc/NETNAME/subnet-down' This script is started when a Subnet becomes unreachable. -The scripts are started without command line arguments, but can make -use of certain environment variables. Under UNIX like operating -systems the names of environment variables must be preceded by a $ in -scripts. Under Windows, in `.bat' files, they have to be put between % -signs. +The scripts are started without command line arguments, but can make use +of certain environment variables. Under UNIX like operating systems the +names of environment variables must be preceded by a $ in scripts. +Under Windows, in '.bat' files, they have to be put between % signs. -`NETNAME' +'NETNAME' If a netname was specified, this environment variable contains it. -`NAME' +'NAME' Contains the name of this tinc daemon. -`DEVICE' +'DEVICE' Contains the name of the virtual network device that tinc uses. -`INTERFACE' +'INTERFACE' Contains the name of the virtual network interface that tinc uses. This should be used for commands like ifconfig. -`NODE' +'NODE' When a host becomes (un)reachable, this is set to its name. If a subnet becomes (un)reachable, this is set to the owner of that subnet. -`REMOTEADDRESS' +'REMOTEADDRESS' When a host becomes (un)reachable, this is set to its real address. -`REMOTEPORT' +'REMOTEPORT' When a host becomes (un)reachable, this is set to the port number it uses for communication with other tinc daemons. -`SUBNET' +'SUBNET' When a subnet becomes (un)reachable, this is set to the subnet. -  File: tinc.info, Node: How to configure, Prev: Scripts, Up: Configuration files 4.4.4 How to configure ---------------------- -Step 1. Creating initial configuration files. -.............................................. +Step 1. Creating initial configuration files. +............................................. The initial directory structure, configuration files and public/private keypairs are created using the following command: @@ -1324,35 +1324,35 @@ keypairs are created using the following command: tinc -n NETNAME init NAME (You will need to run this as root, or use "sudo".) This will create -the configuration directory `/etc/tinc/NETNAME.', and inside it will -create another directory named `hosts/'. In the configuration -directory, it will create the file `tinc.conf' with the following +the configuration directory '/etc/tinc/NETNAME.', and inside it will +create another directory named 'hosts/'. In the configuration +directory, it will create the file 'tinc.conf' with the following contents: Name = NAME It will also create private RSA and ECDSA keys, which will be stored in -the files `rsa_key.priv' and `ecdsa_key.priv'. It will also create a -host configuration file `hosts/NAME', which will contain the +the files 'rsa_key.priv' and 'ecdsa_key.priv'. It will also create a +host configuration file 'hosts/NAME', which will contain the corresponding public RSA and ECDSA keys. Finally, on UNIX operating systems, it will create an executable script -`tinc-up', which will initially not do anything except warning that you +'tinc-up', which will initially not do anything except warning that you should edit it. -Step 2. Modifying the initial configuration. -............................................. +Step 2. Modifying the initial configuration. +............................................ Unless you want to use tinc in switch mode, you should now configure -which range of addresses you will use on the VPN. Let's assume you -will be part of a VPN which uses the address range 192.168.0.0/16, and -you yourself have a smaller portion of that range: 192.168.2.0/24. -Then you should run the following command: +which range of addresses you will use on the VPN. Let's assume you will +be part of a VPN which uses the address range 192.168.0.0/16, and you +yourself have a smaller portion of that range: 192.168.2.0/24. Then you +should run the following command: tinc -n NETNAME add subnet 192.168.2.0/24 This will add a Subnet statement to your host configuration file. Try -opening the file `/etc/tinc/NETNAME/hosts/NAME' in an editor. You +opening the file '/etc/tinc/NETNAME/hosts/NAME' in an editor. You should now see a file containing the public RSA and ECDSA keys (which looks like a bunch of random characters), and the following line at the bottom: @@ -1365,8 +1365,8 @@ add it as well: tinc -n NETNAME add subnet fec0:0:0:2::/24 -This will add another line to the file `hosts/NAME'. If you make a -mistake, you can undo it by simply using `del' instead of `add'. +This will add another line to the file 'hosts/NAME'. If you make a +mistake, you can undo it by simply using 'del' instead of 'add'. If you want other tinc daemons to create meta-connections to your daemon, you should add your public IP address or hostname to your host @@ -1384,26 +1384,25 @@ want to connect to a daemon named "bar", run: Note that you specify the Name of the other daemon here, not an IP address or hostname! When you start tinc, and it tries to make a connection to "bar", it will look for a host configuration file named -`hosts/bar', and will read Address statements and public keys from that +'hosts/bar', and will read Address statements and public keys from that file. -Step 2. Exchanging configuration files. -........................................ +Step 2. Exchanging configuration files. +....................................... -If your daemon has a ConnectTo = bar statement in its `tinc.conf' file, +If your daemon has a ConnectTo = bar statement in its 'tinc.conf' file, or if bar has a ConnectTo your daemon, then you both need each other's -host configuration files. You should send `hosts/NAME' to bar, and bar -should send you his file which you should move to `hosts/bar'. If you +host configuration files. You should send 'hosts/NAME' to bar, and bar +should send you his file which you should move to 'hosts/bar'. If you are on a UNIX platform, you can easily send an email containing the -necessary information using the following command (assuming the owner -of bar has the email address bar@example.org): +necessary information using the following command (assuming the owner of +bar has the email address bar@example.org): tinc -n NETNAME export | mail -s "My config file" bar@example.org -If the owner of bar does the same to send his host configuration file -to you, you can probably pipe his email through the following command, -or you can just start this command in a terminal and copy&paste the -email: +If the owner of bar does the same to send his host configuration file to +you, you can probably pipe his email through the following command, or +you can just start this command in a terminal and copy&paste the email: tinc -n NETNAME import @@ -1418,9 +1417,8 @@ following command: You should repeat this for all nodes you ConnectTo, or which ConnectTo you. However, remember that you do not need to ConnectTo all nodes in the VPN; it is only necessary to create one or a few meta-connections, -after the connections are made tinc will learn about all the other -nodes in the VPN, and will automatically make other connections as -necessary. +after the connections are made tinc will learn about all the other nodes +in the VPN, and will automatically make other connections as necessary.  File: tinc.info, Node: Network interfaces, Next: Example configuration, Prev: Configuration files, Up: Configuration @@ -1434,23 +1432,23 @@ the virtual network interface. First, decide which IP addresses you want to have associated with these devices, and what network mask they must have. -Tinc will open a virtual network device (`/dev/tun', `/dev/tap0' or +Tinc will open a virtual network device ('/dev/tun', '/dev/tap0' or similar), which will also create a network interface called something -like `tun0', `tap0'. If you are using the Linux tun/tap driver, the +like 'tun0', 'tap0'. If you are using the Linux tun/tap driver, the network interface will by default have the same name as the NETNAME. Under Windows you can change the name of the network interface from the Network Connections control panel. You can configure the network interface by putting ordinary ifconfig, -route, and other commands to a script named `/etc/tinc/NETNAME/tinc-up'. -When tinc starts, this script will be executed. When tinc exits, it -will execute the script named `/etc/tinc/NETNAME/tinc-down', but +route, and other commands to a script named '/etc/tinc/NETNAME/tinc-up'. +When tinc starts, this script will be executed. When tinc exits, it +will execute the script named '/etc/tinc/NETNAME/tinc-down', but normally you don't need to create that script. You can manually open the script in an editor, or use the following command: tinc -n NETNAME edit tinc-up -An example `tinc-up' script, that would be appropriate for the scenario +An example 'tinc-up' script, that would be appropriate for the scenario in the previous section, is: #!/bin/sh @@ -1459,14 +1457,14 @@ in the previous section, is: The first command gives the interface an IPv4 address and a netmask. The kernel will also automatically add an IPv4 route to this interface, -so normally you don't need to add route commands to the `tinc-up' -script. The kernel will also bring the interface up after this command. The -netmask is the mask of the _entire_ VPN network, not just your own +so normally you don't need to add route commands to the 'tinc-up' +script. The kernel will also bring the interface up after this command. +The netmask is the mask of the _entire_ VPN network, not just your own subnet. The second command gives the interface an IPv6 address and netmask, which will also automatically add an IPv6 route. If you only want to use "ip addr" commands on Linux, don't forget that it doesn't -bring the interface up, unlike ifconfig, so you need to add `ip link -set $INTERFACE up' in that case. +bring the interface up, unlike ifconfig, so you need to add 'ip link set +$INTERFACE up' in that case. The exact syntax of the ifconfig and route commands differs from platform to platform. You can look up the commands for setting @@ -1480,13 +1478,13 @@ File: tinc.info, Node: Example configuration, Prev: Network interfaces, Up: C 4.6 Example configuration ========================= -Imagine the following situation. Branch A of our example `company' +Imagine the following situation. Branch A of our example 'company' wants to connect three branch offices in B, C and D using the Internet. All four offices have a 24/7 connection to the Internet. A is going to serve as the center of the network. B and C will connect -to A, and D will connect to C. Each office will be assigned their own -IP network, 10.x.0.0. +to A, and D will connect to C. Each office will be assigned their own IP +network, 10.x.0.0. A: net 10.1.0.0 mask 255.255.0.0 gateway 10.1.54.1 internet IP 1.2.3.4 B: net 10.2.0.0 mask 255.255.0.0 gateway 10.2.1.12 internet IP 2.3.4.5 @@ -1502,10 +1500,10 @@ In this example, it is assumed that eth0 is the interface that points to the inner (physical) LAN of the office, although this could also be the same as the interface that leads to the Internet. The configuration of the real interface is also shown as a comment, to give you an idea of -how these example host is set up. All branches use the netname `company' -for this particular VPN. +how these example host is set up. All branches use the netname +'company' for this particular VPN. -Each branch is set up using the `tinc init' and `tinc config' commands, +Each branch is set up using the 'tinc init' and 'tinc config' commands, here we just show the end results: For Branch A @@ -1513,7 +1511,7 @@ For Branch A _BranchA_ would be configured like this: -In `/etc/tinc/company/tinc-up': +In '/etc/tinc/company/tinc-up': #!/bin/sh @@ -1522,11 +1520,11 @@ In `/etc/tinc/company/tinc-up': ifconfig $INTERFACE 10.1.54.1 netmask 255.0.0.0 -and in `/etc/tinc/company/tinc.conf': +and in '/etc/tinc/company/tinc.conf': Name = BranchA -On all hosts, `/etc/tinc/company/hosts/BranchA' contains: +On all hosts, '/etc/tinc/company/hosts/BranchA' contains: Subnet = 10.1.0.0/16 Address = 1.2.3.4 @@ -1544,7 +1542,7 @@ since that will make things a lot easier to remember and set up. For Branch B ............ -In `/etc/tinc/company/tinc-up': +In '/etc/tinc/company/tinc-up': #!/bin/sh @@ -1553,7 +1551,7 @@ In `/etc/tinc/company/tinc-up': ifconfig $INTERFACE 10.2.1.12 netmask 255.0.0.0 -and in `/etc/tinc/company/tinc.conf': +and in '/etc/tinc/company/tinc.conf': Name = BranchB ConnectTo = BranchA @@ -1562,7 +1560,7 @@ Note here that the internal address (on eth0) doesn't have to be the same as on the VPN interface. Also, ConnectTo is given so that this node will always try to connect to BranchA. -On all hosts, in `/etc/tinc/company/hosts/BranchB': +On all hosts, in '/etc/tinc/company/hosts/BranchB': Subnet = 10.2.0.0/16 Address = 2.3.4.5 @@ -1574,7 +1572,7 @@ On all hosts, in `/etc/tinc/company/hosts/BranchB': For Branch C ............ -In `/etc/tinc/company/tinc-up': +In '/etc/tinc/company/tinc-up': #!/bin/sh @@ -1583,16 +1581,16 @@ In `/etc/tinc/company/tinc-up': ifconfig $INTERFACE 10.3.69.254 netmask 255.0.0.0 -and in `/etc/tinc/company/tinc.conf': +and in '/etc/tinc/company/tinc.conf': Name = BranchC ConnectTo = BranchA C already has another daemon that runs on port 655, so they have to -reserve another port for tinc. It knows the portnumber it has to listen +reserve another port for tinc. It knows the portnumber it has to listen on from it's own host configuration file. -On all hosts, in `/etc/tinc/company/hosts/BranchC': +On all hosts, in '/etc/tinc/company/hosts/BranchC': Address = 3.4.5.6 Subnet = 10.3.0.0/16 @@ -1605,7 +1603,7 @@ On all hosts, in `/etc/tinc/company/hosts/BranchC': For Branch D ............ -In `/etc/tinc/company/tinc-up': +In '/etc/tinc/company/tinc-up': #!/bin/sh @@ -1614,15 +1612,15 @@ In `/etc/tinc/company/tinc-up': ifconfig $INTERFACE 10.4.3.32 netmask 255.0.0.0 -and in `/etc/tinc/company/tinc.conf': +and in '/etc/tinc/company/tinc.conf': Name = BranchD ConnectTo = BranchC D will be connecting to C, which has a tincd running for this network on -port 2000. It knows the port number from the host configuration file. +port 2000. It knows the port number from the host configuration file. -On all hosts, in `/etc/tinc/company/hosts/BranchD': +On all hosts, in '/etc/tinc/company/hosts/BranchD': Subnet = 10.4.0.0/16 Address = 4.5.6.7 @@ -1636,10 +1634,10 @@ Key files A, B, C and D all have their own public/private keypairs: -The private RSA key is stored in `/etc/tinc/company/rsa_key.priv', the -private ECDSA key is stored in `/etc/tinc/company/ecdsa_key.priv', and +The private RSA key is stored in '/etc/tinc/company/rsa_key.priv', the +private ECDSA key is stored in '/etc/tinc/company/ecdsa_key.priv', and the public RSA and ECDSA keys are put into the host configuration file -in the `/etc/tinc/company/hosts/' directory. +in the '/etc/tinc/company/hosts/' directory. Starting ........ @@ -1661,10 +1659,10 @@ command: tinc -n NETNAME start -Tinc will detach from the terminal and continue to run in the -background like a good daemon. If there are any problems however you -can try to increase the debug level and look in the syslog to find out -what the problems are. +Tinc will detach from the terminal and continue to run in the background +like a good daemon. If there are any problems however you can try to +increase the debug level and look in the syslog to find out what the +problems are. * Menu: @@ -1684,53 +1682,53 @@ File: tinc.info, Node: Runtime options, Next: Signals, Up: Running tinc Besides the settings in the configuration file, tinc also accepts some command line options. -`-c, --config=PATH' +'-c, --config=PATH' Read configuration options from the directory PATH. The default is - `/etc/tinc/NETNAME/'. + '/etc/tinc/NETNAME/'. -`-D, --no-detach' +'-D, --no-detach' Don't fork and detach. This will also disable the automatic restart mechanism for fatal errors. -`-d, --debug=LEVEL' +'-d, --debug=LEVEL' Set debug level to LEVEL. The higher the debug level, the more gets logged. Everything goes via syslog. -`-n, --net=NETNAME' +'-n, --net=NETNAME' Use configuration for net NETNAME. This will let tinc read all - configuration files from `/etc/tinc/NETNAME/'. Specifying . for + configuration files from '/etc/tinc/NETNAME/'. Specifying . for NETNAME is the same as not specifying any NETNAME. *Note Multiple networks::. -`--pidfile=FILENAME' +'--pidfile=FILENAME' Store a cookie in FILENAME which allows tinc to authenticate. If - unspecified, the default is `/var/run/tinc.NETNAME.pid'. + unspecified, the default is '/var/run/tinc.NETNAME.pid'. -`-o, --option=[HOST.]KEY=VALUE' +'-o, --option=[HOST.]KEY=VALUE' Without specifying a HOST, this will set server configuration variable KEY to VALUE. If specified as HOST.KEY=VALUE, this will set the host configuration variable KEY of the host named HOST to VALUE. This option can be used more than once to specify multiple configuration variables. -`-L, --mlock' +'-L, --mlock' Lock tinc into main memory. This will prevent sensitive data like shared private keys to be written to the system swap files/partitions. This option is not supported on all platforms. -`--logfile[=FILE]' +'--logfile[=FILE]' Write log entries to a file instead of to the system logging facility. If FILE is omitted, the default is - `/var/log/tinc.NETNAME.log'. + '/var/log/tinc.NETNAME.log'. -`--bypass-security' +'--bypass-security' Disables encryption and authentication. Only useful for debugging. -`-R, --chroot' +'-R, --chroot' Change process root directory to the directory where the config - file is located (`/etc/tinc/NETNAME/' as determined by -n/-net + file is located ('/etc/tinc/NETNAME/' as determined by -n/-net option or as given by -c/-config option), for added security. The chroot is performed after all the initialization is done, after writing pid files and opening network sockets. @@ -1738,26 +1736,24 @@ command line options. Note that this option alone does not do any good without -U/-user, below. - Note also that tinc can't run scripts anymore (such as tinc-down - or host-up), unless it's setup to be runnable inside chroot + Note also that tinc can't run scripts anymore (such as tinc-down or + host-up), unless it's setup to be runnable inside chroot environment. This option is not supported on all platforms. - -`-U, --user=USER' +'-U, --user=USER' Switch to the given USER after initialization, at the same time as chroot is performed (see -chroot above). With this option tinc drops privileges, for added security. This option is not supported on all platforms. -`--help' +'--help' Display a short reminder of these runtime options and terminate. -`--version' +'--version' Output version information and exit. -  File: tinc.info, Node: Signals, Next: Debug levels, Prev: Runtime options, Up: Running tinc @@ -1766,20 +1762,19 @@ File: tinc.info, Node: Signals, Next: Debug levels, Prev: Runtime options, U You can also send the following signals to a running tincd process: -`ALRM' +'ALRM' Forces tinc to try to connect to all uplinks immediately. Usually tinc attempts to do this itself, but increases the time it waits between the attempts each time it failed, and if tinc didn't - succeed to connect to an uplink the first time after it started, - it defaults to the maximum time of 15 minutes. + succeed to connect to an uplink the first time after it started, it + defaults to the maximum time of 15 minutes. -`HUP' +'HUP' Partially rereads configuration files. Connections to hosts whose host config file are removed are closed. New outgoing connections - specified in `tinc.conf' will be made. If the -logfile option is - used, this will also close and reopen the log file, useful when - log rotation is used. - + specified in 'tinc.conf' will be made. If the -logfile option is + used, this will also close and reopen the log file, useful when log + rotation is used.  File: tinc.info, Node: Debug levels, Next: Solving problems, Prev: Signals, Up: Running tinc @@ -1788,33 +1783,32 @@ File: tinc.info, Node: Debug levels, Next: Solving problems, Prev: Signals, ================ The tinc daemon can send a lot of messages to the syslog. The higher -the debug level, the more messages it will log. Each level inherits -all messages of the previous level: +the debug level, the more messages it will log. Each level inherits all +messages of the previous level: -`0' +'0' This will log a message indicating tinc has started along with a version number. It will also log any serious error. -`1' +'1' This will log all connections that are made with other tinc daemons. -`2' - This will log status and error messages from scripts and other - tinc daemons. +'2' + This will log status and error messages from scripts and other tinc + daemons. -`3' +'3' This will log all requests that are exchanged with other tinc - daemons. These include authentication, key exchange and connection + daemons. These include authentication, key exchange and connection list updates. -`4' +'4' This will log a copy of everything received on the meta socket. -`5' +'5' This will log all network traffic over the virtual private network. -  File: tinc.info, Node: Solving problems, Next: Error messages, Prev: Debug levels, Up: Running tinc @@ -1831,7 +1825,7 @@ directly see everything tinc logs: If tinc does not log any error messages, then you might want to check the following things: - * `tinc-up' script Does this script contain the right commands? + * 'tinc-up' script Does this script contain the right commands? Normally you must give the interface the address of this host on the VPN, and the netmask must be big enough so that the entire VPN is covered. @@ -1845,10 +1839,9 @@ the following things: masquerading)? If so, check that it allows TCP and UDP traffic on port 655. If it masquerades and the host running tinc is behind it, make sure that it forwards TCP and UDP traffic to port 655 to - the host running tinc. You can add `TCPOnly = yes' to your host - config file to force tinc to only use a single TCP connection, - this works through most firewalls and NATs. - + the host running tinc. You can add 'TCPOnly = yes' to your host + config file to force tinc to only use a single TCP connection, this + works through most firewalls and NATs.  File: tinc.info, Node: Error messages, Next: Sending bug reports, Prev: Solving problems, Up: Running tinc @@ -1860,98 +1853,98 @@ What follows is a list of the most common error messages you might find in the logs. Some of them will only be visible if the debug level is high enough. -`Could not open /dev/tap0: No such device' - * You forgot to `modprobe netlink_dev' or `modprobe ethertap'. +'Could not open /dev/tap0: No such device' - * You forgot to compile `Netlink device emulation' in the + * You forgot to 'modprobe netlink_dev' or 'modprobe ethertap'. + * You forgot to compile 'Netlink device emulation' in the kernel. -`Can't write to /dev/net/tun: No such device' - * You forgot to `modprobe tun'. +'Can't write to /dev/net/tun: No such device' - * You forgot to compile `Universal TUN/TAP driver' in the + * You forgot to 'modprobe tun'. + * You forgot to compile 'Universal TUN/TAP driver' in the kernel. + * The tun device is located somewhere else in '/dev/'. - * The tun device is located somewhere else in `/dev/'. +'Network address and prefix length do not match!' -`Network address and prefix length do not match!' * The Subnet field must contain a _network_ address, trailing bits should be 0. - * If you only want to use one IP address, set the netmask to /32. -`Error reading RSA key file `rsa_key.priv': No such file or directory' +'Error reading RSA key file `rsa_key.priv': No such file or directory' + * You forgot to create a public/private keypair. + * Specify the complete pathname to the private key file with the + 'PrivateKeyFile' option. - * Specify the complete pathname to the private key file with - the `PrivateKeyFile' option. +'Warning: insecure file permissions for RSA private key file `rsa_key.priv'!' -`Warning: insecure file permissions for RSA private key file `rsa_key.priv'!' * The private key file is readable by users other than root. Use chmod to correct the file permissions. -`Creating metasocket failed: Address family not supported' +'Creating metasocket failed: Address family not supported' + * By default tinc tries to create both IPv4 and IPv6 sockets. On some platforms this might not be implemented. If the logs - show `Ready' later on, then at least one metasocket was + show 'Ready' later on, then at least one metasocket was created, and you can ignore this message. You can add - `AddressFamily = ipv4' to `tinc.conf' to prevent this from + 'AddressFamily = ipv4' to 'tinc.conf' to prevent this from happening. -`Cannot route packet: unknown IPv4 destination 1.2.3.4' +'Cannot route packet: unknown IPv4 destination 1.2.3.4' + * You try to send traffic to a host on the VPN for which no Subnet is known. - * If it is a broadcast address (ending in .255), it probably is a samba server or a Windows host sending broadcast packets. You can ignore it. -`Cannot route packet: ARP request for unknown address 1.2.3.4' +'Cannot route packet: ARP request for unknown address 1.2.3.4' + * You try to send traffic to a host on the VPN for which no Subnet is known. -`Packet with destination 1.2.3.4 is looping back to us!' - * Something is not configured right. Packets are being sent out +'Packet with destination 1.2.3.4 is looping back to us!' + + * Something is not configured right. Packets are being sent out to the virtual network device, but according to the Subnet directives in your host configuration file, those packets - should go to your own host. Most common mistake is that you + should go to your own host. Most common mistake is that you have a Subnet line in your host configuration file with a prefix length which is just as large as the prefix of the - virtual network interface. The latter should in almost all - cases be larger. Rethink your configuration. Note that you - will only see this message if you specified a debug level of - 5 or higher! + virtual network interface. The latter should in almost all + cases be larger. Rethink your configuration. Note that you + will only see this message if you specified a debug level of 5 + or higher! + * Chances are that a 'Subnet = ...' line in the host + configuration file of this tinc daemon is wrong. Change it to + a subnet that is accepted locally by another interface, or if + that is not the case, try changing the prefix length into /32. - * Chances are that a `Subnet = ...' line in the host - configuration file of this tinc daemon is wrong. Change it - to a subnet that is accepted locally by another interface, or - if that is not the case, try changing the prefix length into - /32. +'Node foo (1.2.3.4) is not reachable' -`Node foo (1.2.3.4) is not reachable' * Node foo does not have a connection anymore, its tinc daemon is not running or its connection to the Internet is broken. -`Received UDP packet from unknown source 1.2.3.4 (port 12345)' +'Received UDP packet from unknown source 1.2.3.4 (port 12345)' + * If you see this only sporadically, it is harmless and caused by a node sending packets using an old key. - * If you see this often and another node is not reachable anymore, then a NAT (masquerading firewall) is changing the - source address of UDP packets. You can add `TCPOnly = yes' - to host configuration files to force all VPN traffic to go - over a TCP connection. + source address of UDP packets. You can add 'TCPOnly = yes' to + host configuration files to force all VPN traffic to go over a + TCP connection. + +'Got bad/bogus/unauthorized REQUEST from foo (1.2.3.4 port 12345)' -`Got bad/bogus/unauthorized REQUEST from foo (1.2.3.4 port 12345)' * Node foo does not have the right public/private keypair. Generate new keypairs and distribute them again. - * An attacker tries to gain access to your VPN. - * A network error caused corruption of metadata sent from foo. -  File: tinc.info, Node: Sending bug reports, Prev: Error messages, Up: Running tinc @@ -1965,19 +1958,14 @@ bugreport: * A clear description of what you are trying to achieve and what the problem is. - * What platform (operating system, version, hardware architecture) and which version of tinc you use. - - * If compiling tinc fails, a copy of `config.log' and the error + * If compiling tinc fails, a copy of 'config.log' and the error messages you get. - - * Otherwise, a copy of `tinc.conf', `tinc-up' and all files in the - `hosts/' directory. - - * The output of the commands `ifconfig -a' and `route -n' (or - `netstat -rn' if that doesn't work). - + * Otherwise, a copy of 'tinc.conf', 'tinc-up' and all files in the + 'hosts/' directory. + * The output of the commands 'ifconfig -a' and 'route -n' (or + 'netstat -rn' if that doesn't work). * The output of any command that fails to work as it should (like ping or traceroute). @@ -1987,7 +1975,7 @@ File: tinc.info, Node: Controlling tinc, Next: Technical information, Prev: R 6 Controlling tinc ****************** -You can control and inspect a running tincd through the tinc command. A +You can control and inspect a running tincd through the tinc command. A quick example: tinc -n NETNAME reload @@ -2006,34 +1994,33 @@ File: tinc.info, Node: tinc runtime options, Next: tinc environment variables, 6.1 tinc runtime options ======================== -`-c, --config=PATH' +'-c, --config=PATH' Read configuration options from the directory PATH. The default is - `/etc/tinc/NETNAME/'. + '/etc/tinc/NETNAME/'. -`-n, --net=NETNAME' - Use configuration for net NETNAME. *Note Multiple networks::. +'-n, --net=NETNAME' + Use configuration for net NETNAME. *Note Multiple networks::. -`--pidfile=FILENAME' +'--pidfile=FILENAME' Use the cookie from FILENAME to authenticate with a running tinc daemon. If unspecified, the default is - `/var/run/tinc.NETNAME.pid'. + '/var/run/tinc.NETNAME.pid'. -`--help' +'--help' Display a short reminder of runtime options and commands, then terminate. -`--version' +'--version' Output version information and exit. -  File: tinc.info, Node: tinc environment variables, Next: tinc commands, Prev: tinc runtime options, Up: Controlling tinc 6.2 tinc environment variables ============================== -`NETNAME' - If no netname is specified on the command line with the `-n' +'NETNAME' + If no netname is specified on the command line with the '-n' option, the value of this environment variable is used.  @@ -2042,132 +2029,149 @@ File: tinc.info, Node: tinc commands, Next: tinc examples, Prev: tinc environ 6.3 tinc commands ================= -`init [NAME]' +'init [NAME]' Create initial configuration files and RSA and ECDSA keypairs with default length. If no NAME for this node is given, it will be asked for. -`get VARIABLE' +'get VARIABLE' Print the current value of configuration variable VARIABLE. If - more than one variable with the same name exists, the value of - each of them will be printed on a separate line. + more than one variable with the same name exists, the value of each + of them will be printed on a separate line. -`set VARIABLE VALUE' +'set VARIABLE VALUE' Set configuration variable VARIABLE to the given VALUE. All previously existing configuration variables with the same name are removed. To set a variable for a specific host, use the notation HOST.VARIABLE. -`add VARIABLE VALUE' +'add VARIABLE VALUE' As above, but without removing any previously existing configuration variables. -`del VARIABLE [VALUE]' - Remove configuration variables with the same name and VALUE. If - no VALUE is given, all configuration variables with the same name - will be removed. +'del VARIABLE [VALUE]' + Remove configuration variables with the same name and VALUE. If no + VALUE is given, all configuration variables with the same name will + be removed. -`edit FILENAME' +'edit FILENAME' Start an editor for the given configuration file. You do not need to specify the full path to the file. -`export' +'export' Export the host configuration file of the local node to standard output. -`export-all' +'export-all' Export all host configuration files to standard output. -`import [--force]' +'import [--force]' Import host configuration file(s) generated by the tinc export command from standard input. Already existing host configuration files are not overwritten unless the option -force is used. -`exchange [--force]' +'exchange [--force]' The same as export followed by import. -`exchange-all [--force]' +'exchange-all [--force]' The same as export-all followed by import. -`start [tincd options]' - Start `tincd', optionally with the given extra options. +'invite NAME' + Prepares an invitation for a new node with the given NAME, and + prints a short invitation URL that can be used with the join + command. -`stop' - Stop `tincd'. +'join [URL]' + Join an existing VPN using an invitation URL created using the + invite command. If no URL is given, it will be read from standard + input. -`restart' - Restart `tincd'. +'start [tincd options]' + Start 'tincd', optionally with the given extra options. -`reload' - Partially rereads configuration files. Connections to hosts whose - host config files are removed are closed. New outgoing connections - specified in `tinc.conf' will be made. +'stop' + Stop 'tincd'. -`pid' - Shows the PID of the currently running `tincd'. +'restart [tincd options]' + Restart 'tincd', optionally with the given extra options. -`generate-keys [BITS]' - Generate public/private keypair of BITS length. If BITS is not - specified, 1024 is the default. tinc will ask where you want to - store the files, but will default to the configuration directory - (you can use the -c or -n option). +'reload' + Partially rereads configuration files. Connections to hosts whose + host config files are removed are closed. New outgoing connections + specified in 'tinc.conf' will be made. -`dump [reachable] nodes' - Dump a list of all known nodes in the VPN. If the reachable - keyword is used, only lists reachable nodes. +'pid' + Shows the PID of the currently running 'tincd'. -`dump edges' +'generate-keys [BITS]' + Generate both RSA and ECDSA keypairs (see below) and exit. tinc + will ask where you want to store the files, but will default to the + configuration directory (you can use the -c or -n option). + +'generate-ecdsa-keys' + Generate public/private ECDSA keypair and exit. + +'generate-rsa-keys [BITS]' + Generate public/private RSA keypair and exit. If BITS is omitted, + the default length will be 2048 bits. When saving keys to existing + files, tinc will not delete the old keys; you have to remove them + manually. + +'dump [reachable] nodes' + Dump a list of all known nodes in the VPN. If the reachable keyword + is used, only lists reachable nodes. + +'dump edges' Dump a list of all known connections in the VPN. -`dump subnets' +'dump subnets' Dump a list of all known subnets in the VPN. -`dump connections' +'dump connections' Dump a list of all meta connections with ourself. -`dump graph | digraph' +'dump graph | digraph' Dump a graph of the VPN in dotty format. Nodes are colored according to their reachability: red nodes are unreachable, orange nodes are indirectly reachable, green nodes are directly reachable. - Black nodes are either directly or indirectly reachable, but - direct reachability has not been tried yet. + Black nodes are either directly or indirectly reachable, but direct + reachability has not been tried yet. -`info NODE | SUBNET | ADDRESS' - Show information about a particular NODE, SUBNET or ADDRESS. If - an ADDRESS is given, any matching subnet will be shown. +'info NODE | SUBNET | ADDRESS' + Show information about a particular NODE, SUBNET or ADDRESS. If an + ADDRESS is given, any matching subnet will be shown. -`purge' +'purge' Purges all information remembered about unreachable nodes. -`debug LEVEL' +'debug LEVEL' Sets debug level to LEVEL. -`log [LEVEL]' - Capture log messages from a running tinc daemon. An optional - debug level can be given that will be applied only for log - messages sent to tinc. +'log [LEVEL]' + Capture log messages from a running tinc daemon. An optional debug + level can be given that will be applied only for log messages sent + to tinc. -`retry' +'retry' Forces tinc to try to connect to all uplinks immediately. Usually tinc attempts to do this itself, but increases the time it waits between the attempts each time it failed, and if tinc didn't - succeed to connect to an uplink the first time after it started, - it defaults to the maximum time of 15 minutes. + succeed to connect to an uplink the first time after it started, it + defaults to the maximum time of 15 minutes. -`disconnect NODE' +'disconnect NODE' Closes the meta connection with the given NODE. -`top' +'top' If tinc is compiled with libcurses support, this will display live - traffic statistics for all the known nodes, similar to the UNIX - top command. See below for more information. - -`pcap' - Dump VPN traffic going through the local tinc node in - pcap-savefile format to standard output, from where it can be - redirected to a file or piped through a program that can parse it - directly, such as tcpdump. + traffic statistics for all the known nodes, similar to the UNIX top + command. See below for more information. +'pcap' + Dump VPN traffic going through the local tinc node in pcap-savefile + format to standard output, from where it can be redirected to a + file or piped through a program that can parse it directly, such as + tcpdump.  File: tinc.info, Node: tinc examples, Next: tinc top, Prev: tinc commands, Up: Controlling tinc @@ -2195,12 +2199,12 @@ File: tinc.info, Node: tinc top, Prev: tinc examples, Up: Controlling tinc 6.5 tinc top ============ -The top command connects to a running tinc daemon and repeatedly -queries its per-node traffic counters. It displays a list of all the -known nodes in the left-most column, and the amount of bytes and -packets read from and sent to each node in the other columns. By -default, the information is updated every second. The behaviour of the -top command can be changed using the following keys: +The top command connects to a running tinc daemon and repeatedly queries +its per-node traffic counters. It displays a list of all the known +nodes in the left-most column, and the amount of bytes and packets read +from and sent to each node in the other columns. By default, the +information is updated every second. The behaviour of the top command +can be changed using the following keys: Change the interval between updates. After pressing the key, @@ -2251,7 +2255,6 @@ top command can be changed using the following keys: Quit. -  File: tinc.info, Node: Technical information, Next: Platform specific information, Prev: Controlling tinc, Up: Top @@ -2288,30 +2291,30 @@ The data itself is read from a character device file, the so-called _virtual network device_. This device is associated with a network interface. Any data sent to this interface can be read from the device, and any data written to the device gets sent from the interface. There -are two possible types of virtual network devices: `tun' style, which +are two possible types of virtual network devices: 'tun' style, which are point-to-point devices which can only handle IPv4 and/or IPv6 -packets, and `tap' style, which are Ethernet devices and handle -complete Ethernet frames. +packets, and 'tap' style, which are Ethernet devices and handle complete +Ethernet frames. So when tinc reads an Ethernet frame from the device, it determines its -type. When tinc is in it's default routing mode, it can handle IPv4 and -IPv6 packets. Depending on the Subnet lines, it will send the packets -off to their destination IP address. In the `switch' and `hub' mode, +type. When tinc is in it's default routing mode, it can handle IPv4 and +IPv6 packets. Depending on the Subnet lines, it will send the packets +off to their destination IP address. In the 'switch' and 'hub' mode, tinc will use broadcasts and MAC address discovery to deduce the destination of the packets. Since the latter modes only depend on the link layer information, any protocol that runs over Ethernet is -supported (for instance IPX and Appletalk). However, only `tap' style +supported (for instance IPX and Appletalk). However, only 'tap' style devices provide this information. -After the destination has been determined, the packet will be -compressed (optionally), a sequence number will be added to the packet, -the packet will then be encrypted and a message authentication code -will be appended. +After the destination has been determined, the packet will be compressed +(optionally), a sequence number will be added to the packet, the packet +will then be encrypted and a message authentication code will be +appended. -When that is done, time has come to actually transport the packet to -the destination computer. We do this by sending the packet over an UDP -connection to the destination host. This is called _encapsulating_, -the VPN packet (though now encrypted) is encapsulated in another IP +When that is done, time has come to actually transport the packet to the +destination computer. We do this by sending the packet over an UDP +connection to the destination host. This is called _encapsulating_, the +VPN packet (though now encrypted) is encapsulated in another IP datagram. When the destination receives this packet, the same thing happens, only @@ -2319,22 +2322,22 @@ in reverse. So it checks the message authentication code, decrypts the contents of the UDP datagram, checks the sequence number and writes the decrypted information to its own virtual network device. -If the virtual network device is a `tun' device (a point-to-point +If the virtual network device is a 'tun' device (a point-to-point tunnel), there is no problem for the kernel to accept a packet. -However, if it is a `tap' device (this is the only available type on +However, if it is a 'tap' device (this is the only available type on FreeBSD), the destination MAC address must match that of the virtual network interface. If tinc is in it's default routing mode, ARP does -not work, so the correct destination MAC can not be known by the -sending host. Tinc solves this by letting the receiving end detect the -MAC address of its own virtual network interface and overwriting the +not work, so the correct destination MAC can not be known by the sending +host. Tinc solves this by letting the receiving end detect the MAC +address of its own virtual network interface and overwriting the destination MAC address of the received packet. In switch or hub modes ARP does work so the sender already knows the correct destination MAC address. In those modes every interface should have a unique MAC address, so make sure they are not the same. Because switch and hub modes rely on MAC addresses to function correctly, these -modes cannot be used on the following operating systems which don't -have a `tap' style virtual network device: OpenBSD, NetBSD, Darwin and +modes cannot be used on the following operating systems which don't have +a 'tap' style virtual network device: OpenBSD, NetBSD, Darwin and Solaris.  @@ -2375,9 +2378,8 @@ File: tinc.info, Node: The meta-protocol, Next: Security, Prev: The connectio 7.2 The meta-protocol ===================== -The meta protocol is used to tie all tinc daemons together, and -exchange information about which tinc daemon serves which virtual -subnet. +The meta protocol is used to tie all tinc daemons together, and exchange +information about which tinc daemon serves which virtual subnet. The meta protocol consists of requests that can be sent to the other side. Each request has a unique number and several parameters. All @@ -2386,7 +2388,7 @@ possible to use tools such as telnet or netcat to connect to a tinc daemon started with the -bypass-security option and to read and write requests by hand, provided that one understands the numeric codes sent. -The authentication scheme is described in *note Security::. After a +The authentication scheme is described in *note Security::. After a successful authentication, the server and the client will exchange all the information about other tinc daemons and subnets they know of, so that both sides (and all the other tinc daemons behind them) have their @@ -2408,12 +2410,12 @@ information synchronised. +------------------> owner of this subnet ------------------------------------------------------------------ -The ADD_EDGE messages are to inform other tinc daemons that a -connection between two nodes exist. The address of the destination node -is available so that VPN packets can be sent directly to that node. +The ADD_EDGE messages are to inform other tinc daemons that a connection +between two nodes exist. The address of the destination node is +available so that VPN packets can be sent directly to that node. The ADD_SUBNET messages inform other tinc daemons that certain subnets -belong to certain nodes. tinc will use it to determine to which node a +belong to certain nodes. tinc will use it to determine to which node a VPN packet has to be sent. message @@ -2429,7 +2431,7 @@ VPN packet has to be sent. ------------------------------------------------------------------ In case a connection between two daemons is closed or broken, DEL_EDGE -messages are sent to inform the other daemons of that fact. Each daemon +messages are sent to inform the other daemons of that fact. Each daemon will calculate a new route to the the daemons, or mark them unreachable if there isn't any. @@ -2451,10 +2453,10 @@ if there isn't any. +--> daemon that has changed it's packet key ------------------------------------------------------------------ -The keys used to encrypt VPN packets are not sent out directly. This is +The keys used to encrypt VPN packets are not sent out directly. This is because it would generate a lot of traffic on VPNs with many daemons, and chances are that not every tinc daemon will ever send a packet to -every other daemon. Instead, if a daemon needs a key it sends a request +every other daemon. Instead, if a daemon needs a key it sends a request for it via the meta connection of the nearest hop in the direction of the destination. @@ -2464,11 +2466,11 @@ the destination. dest. PONG ------------------------------------------------------------------ -There is also a mechanism to check if hosts are still alive. Since +There is also a mechanism to check if hosts are still alive. Since network failures or a crash can cause a daemon to be killed without properly shutting down the TCP connection, this is necessary to keep an -up to date connection list. PINGs are sent at regular intervals, except -when there is also some other traffic. A little bit of salt (random +up to date connection list. PINGs are sent at regular intervals, except +when there is also some other traffic. A little bit of salt (random data) is added with each PING and PONG message, to make sure that long sequences of PING/PONG messages without any other traffic won't result in known plaintext. @@ -2483,24 +2485,23 @@ File: tinc.info, Node: Security, Prev: The meta-protocol, Up: Technical infor Tinc got its name from "TINC," short for _There Is No Cabal_; the alleged Cabal was/is an organisation that was said to keep an eye on the -entire Internet. As this is exactly what you _don't_ want, we named -the tinc project after TINC. +entire Internet. As this is exactly what you _don't_ want, we named the +tinc project after TINC. But in order to be "immune" to eavesdropping, you'll have to encrypt -your data. Because tinc is a _Secure_ VPN (SVPN) daemon, it does +your data. Because tinc is a _Secure_ VPN (SVPN) daemon, it does exactly that: encrypt. However, encryption in itself does not prevent an attacker from modifying the encrypted data. Therefore, tinc also authenticates the data. Finally, tinc uses sequence numbers (which -themselves are also authenticated) to prevent an attacker from -replaying valid packets. +themselves are also authenticated) to prevent an attacker from replaying +valid packets. -Since version 1.1pre3, tinc has two protocols used to protect your -data; the legacy protocol, and the new Simple Peer-to-Peer Security -(SPTPS) protocol. The SPTPS protocol is designed to address some -weaknesses in the legacy protocol. The new authentication protocol is -used when two nodes connect to each other that both have the -ExperimentalProtocol option set to yes, otherwise the legacy protocol -will be used. +Since version 1.1pre3, tinc has two protocols used to protect your data; +the legacy protocol, and the new Simple Peer-to-Peer Security (SPTPS) +protocol. The SPTPS protocol is designed to address some weaknesses in +the legacy protocol. The new authentication protocol is used when two +nodes connect to each other that both have the ExperimentalProtocol +option set to yes, otherwise the legacy protocol will be used. * Menu: @@ -2552,13 +2553,12 @@ File: tinc.info, Node: Legacy authentication protocol, Next: Simple Peer-to-Pe The protocol allows each side to specify encryption algorithms and parameters, but in practice they are always fixed, since older versions -of tinc did not allow them to be different from the default values. The +of tinc did not allow them to be different from the default values. The cipher is always Blowfish in OFB mode, the digest is SHA1, but the MAC length is zero and no compression is used. From now on: * the client will symmetrically encrypt outgoing traffic using S1 - * the server will symmetrically encrypt outgoing traffic using S2 -------------------------------------------------------------------------- @@ -2593,19 +2593,19 @@ From now on: This legacy authentication protocol has several weaknesses, pointed out by security export Peter Gutmann. First, data is encrypted with RSA without padding. Padding schemes are designed to prevent attacks when -the size of the plaintext is not equal to the size of the RSA key. -Tinc always encrypts random nonces that have the same size as the RSA -key, so we do not believe this leads to a break of the security. There -might be timing or other side-channel attacks against RSA encryption -and decryption, tinc does not employ any protection against those. +the size of the plaintext is not equal to the size of the RSA key. Tinc +always encrypts random nonces that have the same size as the RSA key, so +we do not believe this leads to a break of the security. There might be +timing or other side-channel attacks against RSA encryption and +decryption, tinc does not employ any protection against those. Furthermore, both sides send identical messages to each other, there is -no distinction between server and client, which could make a MITM -attack easier. However, no exploit is known in which a third party who -is not already trusted by other nodes in the VPN could gain access. -Finally, the RSA keys are used to directly encrypt the session keys, -which means that if the RSA keys are compromised, it is possible to -decrypt all previous VPN traffic. In other words, the legacy protocol -does not provide perfect forward secrecy. +no distinction between server and client, which could make a MITM attack +easier. However, no exploit is known in which a third party who is not +already trusted by other nodes in the VPN could gain access. Finally, +the RSA keys are used to directly encrypt the session keys, which means +that if the RSA keys are compromised, it is possible to decrypt all +previous VPN traffic. In other words, the legacy protocol does not +provide perfect forward secrecy.  File: tinc.info, Node: Simple Peer-to-Peer Security, Next: Encryption of network packets, Prev: Legacy authentication protocol, Up: Security @@ -2626,24 +2626,20 @@ Similar to TLS, messages are split up in records. A complete logical record contains the following information: * uint32_t seqno (network byte order) - * uint16_t length (network byte order) - * uint8_t type - * opaque data[length] - * opaque hmac[HMAC_SIZE] (HMAC over all preceding fields) Depending on whether SPTPS records are sent via TCP or UDP, either the seqno or the length field is omitted on the wire (but they are still -included in the calculation of the HMAC); for TCP packets are -guaranteed to arrive in-order so we can infer the seqno, but packets -can be split or merged, so we still need the length field to determine -the boundaries between records; for UDP packets we know that there is -exactly one record per packet, and we know the length of a packet, but -packets can be dropped, duplicated and/or reordered, so we need to -include the seqno. +included in the calculation of the HMAC); for TCP packets are guaranteed +to arrive in-order so we can infer the seqno, but packets can be split +or merged, so we still need the length field to determine the boundaries +between records; for UDP packets we know that there is exactly one +record per packet, and we know the length of a packet, but packets can +be dropped, duplicated and/or reordered, so we need to include the +seqno. The type field is used to distinguish between application records or handshake records. Types 0 to 127 are application records, type 128 is @@ -2698,9 +2694,7 @@ an incoming connection. Key EXchange message: * uint8_t kex_version (always 0 in this version of SPTPS) - * opaque nonce[32] (random number) - * opaque ecdh_key[ECDH_SIZE] SIGnature message: @@ -2715,63 +2709,46 @@ Remarks: * At the start, both peers generate a random nonce and an Elliptic Curve public key and send it to the other in the KEX message. - * After receiving the other's KEX message, both KEX messages are - concatenated (see below), and the result is signed using ECDSA. - The result is sent to the other. - + concatenated (see below), and the result is signed using ECDSA. The + result is sent to the other. * After receiving the other's SIG message, the signature is verified. - If it is correct, the shared secret is calculated from the public + If it is correct, the shared secret is calculated from the public keys exchanged in the KEX message using the Elliptic Curve Diffie-Helman algorithm. - - * The shared secret key is expanded using a PRF. Both nonces and - the application specific label are also used as input for the PRF. - + * The shared secret key is expanded using a PRF. Both nonces and the + application specific label are also used as input for the PRF. * An ACK message is sent only when doing key renegotiation, and is sent using the old encryption keys. - * The expanded key is used to key the encryption and HMAC algorithms. The signature is calculated over this string: * uint8_t initiator (0 = local peer, 1 = remote peer is initiator) - * opaque remote_kex_message[1 + 32 + ECDH_SIZE] - * opaque local_kex_message[1 + 32 + ECDH_SIZE] - * opaque label[label_length] The PRF is calculated as follows: * A HMAC using SHA512 is used, the shared secret is used as the key. - - * For each block of 64 bytes, a HMAC is calculated. For block n: - hmac[n] = HMAC_SHA512(hmac[n - 1] + seed) - - * For the first block (n = 1), hmac[0] is given by - HMAC_SHA512(zeroes + seed), where zeroes is a block of 64 zero - bytes. + * For each block of 64 bytes, a HMAC is calculated. For block n: + hmac[n] = HMAC_SHA512(hmac[n - 1] + seed) + * For the first block (n = 1), hmac[0] is given by HMAC_SHA512(zeroes + + seed), where zeroes is a block of 64 zero bytes. The seed is as follows: * const char[13] "key expansion" - * opaque responder_nonce[32] - * opaque initiator_nonce[32] - * opaque label[label_length] The expanded key is used as follows: * opaque responder_cipher_key[CIPHER_KEYSIZE] - * opaque responder_digest_key[DIGEST_KEYSIZE] - * opaque initiator_cipher_key[CIPHER_KEYSIZE] - * opaque initiator_digest_key[DIGEST_KEYSIZE] Where initiator_cipher_key is the key used by session initiator to @@ -2795,13 +2772,13 @@ File: tinc.info, Node: Encryption of network packets, Next: Security issues, ----------------------------------- A data packet can only be sent if the encryption key is known to both -parties, and the connection is activated. If the encryption key is not -known, a request is sent to the destination using the meta connection -to retrieve it. +parties, and the connection is activated. If the encryption key is not +known, a request is sent to the destination using the meta connection to +retrieve it. -The UDP packets can be either encrypted with the legacy protocol or -with SPTPS. In case of the legacy protocol, the UDP packet containing -the network packet from the VPN has the following layout: +The UDP packets can be either encrypted with the legacy protocol or with +SPTPS. In case of the legacy protocol, the UDP packet containing the +network packet from the VPN has the following layout: ... | IP header | UDP header | seqno | VPN packet | MAC | UDP trailer \___________________/\_____/ @@ -2810,17 +2787,18 @@ the network packet from the VPN has the following layout: Encrypted with symmetric cipher So, the entire VPN packet is encrypted using a symmetric cipher, -including a 32 bits sequence number that is added in front of the -actual VPN packet, to act as a unique IV for each packet and to prevent -replay attacks. A message authentication code is added to the UDP -packet to prevent alteration of packets. Tinc by default encrypts -network packets using Blowfish with 128 bit keys in CBC mode and uses 4 -byte long message authentication codes to make sure eavesdroppers -cannot get and cannot change any information at all from the packets -they can intercept. The encryption algorithm and message authentication -algorithm can be changed in the configuration. The length of the message -authentication codes is also adjustable. The length of the key for the -encryption algorithm is always the default length used by OpenSSL. +including a 32 bits sequence number that is added in front of the actual +VPN packet, to act as a unique IV for each packet and to prevent replay +attacks. A message authentication code is added to the UDP packet to +prevent alteration of packets. Tinc by default encrypts network packets +using Blowfish with 128 bit keys in CBC mode and uses 4 byte long +message authentication codes to make sure eavesdroppers cannot get and +cannot change any information at all from the packets they can +intercept. The encryption algorithm and message authentication +algorithm can be changed in the configuration. The length of the +message authentication codes is also adjustable. The length of the key +for the encryption algorithm is always the default length used by +OpenSSL. The SPTPS protocol is described in *note Simple Peer-to-Peer Security::. For comparison, this is how SPTPS UDP packets look: @@ -2832,10 +2810,10 @@ For comparison, this is how SPTPS UDP packets look: Encrypted with symmetric cipher The difference is that the seqno is not encrypted, since the encryption -cipher is used in CTR mode, and therefore the seqno must be known -before the packet can be decrypted. Furthermore, the MAC is never -truncated. The SPTPS protocol always uses the AES-256-CTR cipher and -HMAC-SHA-256 digest, this cannot be changed. +cipher is used in CTR mode, and therefore the seqno must be known before +the packet can be decrypted. Furthermore, the MAC is never truncated. +The SPTPS protocol always uses the AES-256-CTR cipher and HMAC-SHA-256 +digest, this cannot be changed.  File: tinc.info, Node: Security issues, Prev: Encryption of network packets, Up: Security @@ -2844,33 +2822,33 @@ File: tinc.info, Node: Security issues, Prev: Encryption of network packets, --------------------- In August 2000, we discovered the existence of a security hole in all -versions of tinc up to and including 1.0pre2. This had to do with the -way we exchanged keys. Since then, we have been working on a new -authentication scheme to make tinc as secure as possible. The current -version uses the OpenSSL library and uses strong authentication with -RSA keys. +versions of tinc up to and including 1.0pre2. This had to do with the +way we exchanged keys. Since then, we have been working on a new +authentication scheme to make tinc as secure as possible. The current +version uses the OpenSSL library and uses strong authentication with RSA +keys. On the 29th of December 2001, Jerome Etienne posted a security analysis -of tinc 1.0pre4. Due to a lack of sequence numbers and a message +of tinc 1.0pre4. Due to a lack of sequence numbers and a message authentication code for each packet, an attacker could possibly disrupt certain network services or launch a denial of service attack by -replaying intercepted packets. The current version adds sequence +replaying intercepted packets. The current version adds sequence numbers and message authentication codes to prevent such attacks. On the 15th of September 2003, Peter Gutmann posted a security analysis -of tinc 1.0.1. He argues that the 32 bit sequence number used by tinc +of tinc 1.0.1. He argues that the 32 bit sequence number used by tinc is not a good IV, that tinc's default length of 4 bytes for the MAC is too short, and he doesn't like tinc's use of RSA during authentication. -We do not know of a security hole in the legacy protocol of tinc, but -it is not as strong as TLS or IPsec. +We do not know of a security hole in the legacy protocol of tinc, but it +is not as strong as TLS or IPsec. This version of tinc comes with an improved protocol, called Simple -Peer-to-Peer Security, which aims to be as strong as TLS with one of -the strongest cipher suites. +Peer-to-Peer Security, which aims to be as strong as TLS with one of the +strongest cipher suites. -Cryptography is a hard thing to get right. We cannot make any -guarantees. Time, review and feedback are the only things that can -prove the security of any cryptographic product. If you wish to review +Cryptography is a hard thing to get right. We cannot make any +guarantees. Time, review and feedback are the only things that can +prove the security of any cryptographic product. If you wish to review tinc or give us feedback, you are stronly encouraged to do so.  @@ -2901,30 +2879,30 @@ that it encompasses the entire VPN. For IPv4 addresses: -Linux `ifconfig' INTERFACE ADDRESS `netmask' NETMASK -Linux iproute2 `ip addr add' ADDRESS`/'PREFIXLENGTH `dev' INTERFACE -FreeBSD `ifconfig' INTERFACE ADDRESS `netmask' NETMASK -OpenBSD `ifconfig' INTERFACE ADDRESS `netmask' NETMASK -NetBSD `ifconfig' INTERFACE ADDRESS `netmask' NETMASK -Solaris `ifconfig' INTERFACE ADDRESS `netmask' NETMASK -Darwin (MacOS/X) `ifconfig' INTERFACE ADDRESS `netmask' NETMASK -Windows `netsh interface ip set address' INTERFACE `static' ADDRESS NETMASK +Linux 'ifconfig' INTERFACE ADDRESS 'netmask' NETMASK +Linux iproute2 'ip addr add' ADDRESS'/'PREFIXLENGTH 'dev' INTERFACE +FreeBSD 'ifconfig' INTERFACE ADDRESS 'netmask' NETMASK +OpenBSD 'ifconfig' INTERFACE ADDRESS 'netmask' NETMASK +NetBSD 'ifconfig' INTERFACE ADDRESS 'netmask' NETMASK +Solaris 'ifconfig' INTERFACE ADDRESS 'netmask' NETMASK +Darwin (MacOS/X) 'ifconfig' INTERFACE ADDRESS 'netmask' NETMASK +Windows 'netsh interface ip set address' INTERFACE 'static' ADDRESS NETMASK For IPv6 addresses: -Linux `ifconfig' INTERFACE `add' ADDRESS`/'PREFIXLENGTH -FreeBSD `ifconfig' INTERFACE `inet6' ADDRESS `prefixlen' PREFIXLENGTH -OpenBSD `ifconfig' INTERFACE `inet6' ADDRESS `prefixlen' PREFIXLENGTH -NetBSD `ifconfig' INTERFACE `inet6' ADDRESS `prefixlen' PREFIXLENGTH -Solaris `ifconfig' INTERFACE `inet6 plumb up' - `ifconfig' INTERFACE `inet6 addif' ADDRESS ADDRESS -Darwin (MacOS/X) `ifconfig' INTERFACE `inet6' ADDRESS `prefixlen' PREFIXLENGTH -Windows `netsh interface ipv6 add address' INTERFACE `static' ADDRESS/PREFIXLENGTH +Linux 'ifconfig' INTERFACE 'add' ADDRESS'/'PREFIXLENGTH +FreeBSD 'ifconfig' INTERFACE 'inet6' ADDRESS 'prefixlen' PREFIXLENGTH +OpenBSD 'ifconfig' INTERFACE 'inet6' ADDRESS 'prefixlen' PREFIXLENGTH +NetBSD 'ifconfig' INTERFACE 'inet6' ADDRESS 'prefixlen' PREFIXLENGTH +Solaris 'ifconfig' INTERFACE 'inet6 plumb up' + 'ifconfig' INTERFACE 'inet6 addif' ADDRESS ADDRESS +Darwin (MacOS/X) 'ifconfig' INTERFACE 'inet6' ADDRESS 'prefixlen' PREFIXLENGTH +Windows 'netsh interface ipv6 add address' INTERFACE 'static' ADDRESS/PREFIXLENGTH On some platforms, when running tinc in switch mode, the VPN interface must be set to tap mode with an ifconfig command: -OpenBSD `ifconfig' INTERFACE `link0' +OpenBSD 'ifconfig' INTERFACE 'link0' On Linux, it is possible to create a persistent tun/tap interface which will continue to exist even if tinc quit, although this is normally not @@ -2932,7 +2910,7 @@ required. It can be useful to set up a tun/tap interface owned by a non-root user, so tinc can be started without needing any root privileges at all. -Linux `ip tuntap add dev' INTERFACE `mode' TUN|TAP `user' USERNAME +Linux 'ip tuntap add dev' INTERFACE 'mode' TUN|TAP 'user' USERNAME  File: tinc.info, Node: Routes, Prev: Interface configuration, Up: Platform specific information @@ -2944,31 +2922,31 @@ In some cases it might be necessary to add more routes to the virtual network interface. There are two ways to indicate which interface a packet should go to, one is to use the name of the interface itself, another way is to specify the (local) address that is assigned to that -interface (LOCAL_ADDRESS). The former way is unambiguous and therefore +interface (LOCAL_ADDRESS). The former way is unambiguous and therefore preferable, but not all platforms support this. Adding routes to IPv4 subnets: -Linux `route add -net' NETWORK_ADDRESS `netmask' NETMASK INTERFACE -Linux iproute2 `ip route add' NETWORK_ADDRESS`/'PREFIXLENGTH `dev' INTERFACE -FreeBSD `route add' NETWORK_ADDRESS`/'PREFIXLENGTH LOCAL_ADDRESS -OpenBSD `route add' NETWORK_ADDRESS`/'PREFIXLENGTH LOCAL_ADDRESS -NetBSD `route add' NETWORK_ADDRESS`/'PREFIXLENGTH LOCAL_ADDRESS -Solaris `route add' NETWORK_ADDRESS`/'PREFIXLENGTH LOCAL_ADDRESS `-interface' -Darwin (MacOS/X) `route add' NETWORK_ADDRESS`/'PREFIXLENGTH LOCAL_ADDRESS -Windows `netsh routing ip add persistentroute' NETWORK_ADDRESS NETMASK INTERFACE +Linux 'route add -net' NETWORK_ADDRESS 'netmask' NETMASK INTERFACE +Linux iproute2 'ip route add' NETWORK_ADDRESS'/'PREFIXLENGTH 'dev' INTERFACE +FreeBSD 'route add' NETWORK_ADDRESS'/'PREFIXLENGTH LOCAL_ADDRESS +OpenBSD 'route add' NETWORK_ADDRESS'/'PREFIXLENGTH LOCAL_ADDRESS +NetBSD 'route add' NETWORK_ADDRESS'/'PREFIXLENGTH LOCAL_ADDRESS +Solaris 'route add' NETWORK_ADDRESS'/'PREFIXLENGTH LOCAL_ADDRESS '-interface' +Darwin (MacOS/X) 'route add' NETWORK_ADDRESS'/'PREFIXLENGTH LOCAL_ADDRESS +Windows 'netsh routing ip add persistentroute' NETWORK_ADDRESS NETMASK INTERFACE LOCAL_ADDRESS Adding routes to IPv6 subnets: -Linux `route add -A inet6' NETWORK_ADDRESS`/'PREFIXLENGTH INTERFACE -Linux iproute2 `ip route add' NETWORK_ADDRESS`/'PREFIXLENGTH `dev' INTERFACE -FreeBSD `route add -inet6' NETWORK_ADDRESS`/'PREFIXLENGTH LOCAL_ADDRESS -OpenBSD `route add -inet6' NETWORK_ADDRESS LOCAL_ADDRESS `-prefixlen' PREFIXLENGTH -NetBSD `route add -inet6' NETWORK_ADDRESS LOCAL_ADDRESS `-prefixlen' PREFIXLENGTH -Solaris `route add -inet6' NETWORK_ADDRESS`/'PREFIXLENGTH LOCAL_ADDRESS `-interface' +Linux 'route add -A inet6' NETWORK_ADDRESS'/'PREFIXLENGTH INTERFACE +Linux iproute2 'ip route add' NETWORK_ADDRESS'/'PREFIXLENGTH 'dev' INTERFACE +FreeBSD 'route add -inet6' NETWORK_ADDRESS'/'PREFIXLENGTH LOCAL_ADDRESS +OpenBSD 'route add -inet6' NETWORK_ADDRESS LOCAL_ADDRESS '-prefixlen' PREFIXLENGTH +NetBSD 'route add -inet6' NETWORK_ADDRESS LOCAL_ADDRESS '-prefixlen' PREFIXLENGTH +Solaris 'route add -inet6' NETWORK_ADDRESS'/'PREFIXLENGTH LOCAL_ADDRESS '-interface' Darwin (MacOS/X) ? -Windows `netsh interface ipv6 add route' NETWORK ADDRESS/PREFIXLENGTH INTERFACE +Windows 'netsh interface ipv6 add route' NETWORK ADDRESS/PREFIXLENGTH INTERFACE  File: tinc.info, Node: About us, Next: Concept Index, Prev: Platform specific information, Up: Top @@ -2987,11 +2965,11 @@ File: tinc.info, Node: Contact information, Next: Authors, Up: About us 9.1 Contact information ======================= -Tinc's website is at `http://www.tinc-vpn.org/', this server is located +Tinc's website is at , this server is located in the Netherlands. -We have an IRC channel on the FreeNode and OFTC IRC networks. Connect to -irc.freenode.net (http://www.freenode.net/) or irc.oftc.net +We have an IRC channel on the FreeNode and OFTC IRC networks. Connect +to irc.freenode.net (http://www.freenode.net/) or irc.oftc.net (http://www.oftc.net/) and join channel #tinc.  @@ -3001,12 +2979,11 @@ File: tinc.info, Node: Authors, Prev: Contact information, Up: About us =========== Ivo Timmermans (zarq) - Guus Sliepen (guus) () We have received a lot of valuable input from users. With their help, tinc has become the flexible and robust tool that it is today. We have -composed a list of contributions, in the file called `THANKS' in the +composed a list of contributions, in the file called 'THANKS' in the source distribution.  @@ -3020,13 +2997,13 @@ Concept Index * ACK: Legacy authentication protocol. (line 6) -* ADD_EDGE: The meta-protocol. (line 23) -* ADD_SUBNET: The meta-protocol. (line 23) * Address: Host configuration variables. (line 6) * AddressFamily: Main configuration variables. (line 6) -* ANS_KEY: The meta-protocol. (line 64) +* ADD_EDGE: The meta-protocol. (line 22) +* ADD_SUBNET: The meta-protocol. (line 22) +* ANS_KEY: The meta-protocol. (line 63) * AutoConnect: Main configuration variables. (line 12) * binary package: Building and installing tinc. @@ -3036,12 +3013,12 @@ Concept Index * BindToInterface: Main configuration variables. (line 30) * Broadcast: Main configuration variables. - (line 41) + (line 40) * Cabal: Security. (line 6) -* CHAL_REPLY: Legacy authentication protocol. - (line 6) * CHALLENGE: Legacy authentication protocol. (line 6) +* CHAL_REPLY: Legacy authentication protocol. + (line 6) * CIDR notation: Host configuration variables. (line 94) * Cipher: Host configuration variables. @@ -3055,136 +3032,140 @@ Concept Index (line 26) * connection: The connection. (line 6) * ConnectTo: Main configuration variables. - (line 61) + (line 60) * daemon: Running tinc. (line 11) * data-protocol: The meta-connection. (line 18) * debug level: Runtime options. (line 17) * debug levels: Debug levels. (line 6) * DecrementTTL: Main configuration variables. - (line 72) -* DEL_EDGE: The meta-protocol. (line 47) -* DEL_SUBNET: The meta-protocol. (line 47) -* DEVICE: Scripts. (line 55) + (line 71) +* DEL_EDGE: The meta-protocol. (line 46) +* DEL_SUBNET: The meta-protocol. (line 46) * Device: Main configuration variables. - (line 81) + (line 80) +* DEVICE: Scripts. (line 53) * device files: Device files. (line 6) * DeviceType: Main configuration variables. - (line 88) + (line 87) * Digest: Host configuration variables. (line 31) * DirectOnly: Main configuration variables. - (line 153) + (line 152) * dummy: Main configuration variables. - (line 95) + (line 94) * ECDSAPrivateKeyFile: Main configuration variables. - (line 160) + (line 159) * encapsulating: The UDP tunnel. (line 30) * encryption: Encryption of network packets. (line 6) -* environment variables: Scripts. (line 43) +* environment variables: Scripts. (line 42) * example: Example configuration. (line 6) * exec: Main configuration variables. - (line 321) + (line 328) * ExperimentalProtocol: Main configuration variables. - (line 164) + (line 163) * Forwarding: Main configuration variables. - (line 173) + (line 170) * frame type: The UDP tunnel. (line 6) * Hostnames: Main configuration variables. - (line 193) + (line 190) * http: Main configuration variables. - (line 318) + (line 325) * hub: Main configuration variables. - (line 245) + (line 246) * ID: Legacy authentication protocol. (line 6) * IndirectData: Host configuration variables. (line 38) -* INTERFACE: Scripts. (line 58) * Interface: Main configuration variables. - (line 204) + (line 201) +* INTERFACE: Scripts. (line 56) * IRC: Contact information. (line 9) -* KEY_CHANGED: The meta-protocol. (line 64) * KeyExpire: Main configuration variables. - (line 250) + (line 251) +* KEY_CHANGED: The meta-protocol. (line 63) * legacy authentication protocol: Legacy authentication protocol. (line 6) * libcurses: libcurses. (line 6) * libraries: Libraries. (line 6) * libreadline: libreadline. (line 6) -* license: OpenSSL. (line 36) +* license: OpenSSL. (line 35) * LocalDiscovery: Main configuration variables. - (line 212) + (line 209) +* LocalDiscoveryAddress: Main configuration variables. + (line 220) * lzo: lzo. (line 6) * MACExpire: Main configuration variables. - (line 256) + (line 257) * MACLength: Host configuration variables. (line 43) +* MaxConnectionBurst: Main configuration variables. + (line 262) * meta-protocol: The meta-connection. (line 18) * META_KEY: Legacy authentication protocol. (line 6) * Mode: Main configuration variables. - (line 223) + (line 224) * multicast: Main configuration variables. - (line 107) + (line 106) * multiple networks: Multiple networks. (line 6) -* NAME: Scripts. (line 52) * Name: Main configuration variables. - (line 261) -* netmask: Network interfaces. (line 38) + (line 268) +* NAME: Scripts. (line 50) +* netmask: Network interfaces. (line 39) +* netname: Multiple networks. (line 6) +* NETNAME: Scripts. (line 47) * NETNAME <1>: tinc environment variables. (line 6) -* NETNAME: Scripts. (line 49) -* netname: Multiple networks. (line 6) * Network Administrators Guide: Configuration introduction. (line 15) -* NODE: Scripts. (line 62) +* NODE: Scripts. (line 60) * OpenSSL: OpenSSL. (line 6) * options: Runtime options. (line 9) * PEM format: Host configuration variables. (line 70) -* PING: The meta-protocol. (line 89) +* PING: The meta-protocol. (line 88) * PingInterval: Main configuration variables. - (line 272) + (line 279) * PingTimeout: Main configuration variables. - (line 276) + (line 283) * platforms: Supported platforms. (line 6) * PMTU: Host configuration variables. (line 50) * PMTUDiscovery: Host configuration variables. (line 53) -* PONG: The meta-protocol. (line 89) +* PONG: The meta-protocol. (line 88) * Port: Host configuration variables. (line 58) * port numbers: Other files. (line 17) * PriorityInheritance: Main configuration variables. - (line 282) + (line 289) * private: Virtual Private Networks. (line 10) * PrivateKey: Main configuration variables. - (line 287) + (line 294) * PrivateKeyFile: Main configuration variables. - (line 293) + (line 300) * ProcessPriority: Main configuration variables. - (line 298) + (line 305) * Proxy: Main configuration variables. - (line 303) + (line 310) * PublicKey: Host configuration variables. (line 62) * PublicKeyFile: Host configuration variables. (line 65) * raw_socket: Main configuration variables. - (line 100) + (line 99) * release: Supported platforms. (line 14) -* REMOTEADDRESS: Scripts. (line 67) -* REMOTEPORT: Scripts. (line 70) +* REMOTEADDRESS: Scripts. (line 65) +* REMOTEPORT: Scripts. (line 68) * ReplayWindow: Main configuration variables. - (line 326) -* REQ_KEY: The meta-protocol. (line 64) + (line 333) * requirements: Libraries. (line 6) +* REQ_KEY: The meta-protocol. (line 63) * router: Main configuration variables. - (line 226) + (line 227) * runtime options: Runtime options. (line 9) * scalability: tinc. (line 19) * scripts: Scripts. (line 6) @@ -3192,48 +3173,48 @@ Concept Index (line 18) * signals: Signals. (line 6) * socks4: Main configuration variables. - (line 307) + (line 314) * socks5: Main configuration variables. - (line 312) + (line 319) * SPTPS: Simple Peer-to-Peer Security. (line 6) * StrictSubnets: Main configuration variables. - (line 337) -* SUBNET: Scripts. (line 74) + (line 344) * Subnet: Host configuration variables. (line 77) +* SUBNET: Scripts. (line 72) * SVPN: Security. (line 11) * switch: Main configuration variables. - (line 234) + (line 235) * TCP: The meta-connection. (line 10) * TCPonly: Host configuration variables. (line 106) -* TINC: Security. (line 6) * tinc: Introduction. (line 6) +* TINC: Security. (line 6) * tinc-down: Scripts. (line 18) -* tinc-up <1>: Network interfaces. (line 19) * tinc-up: Scripts. (line 10) +* tinc-up <1>: Network interfaces. (line 19) * tincd: tinc. (line 14) * traditional VPNs: tinc. (line 19) * tunifhead: Main configuration variables. - (line 142) + (line 141) * TunnelServer: Main configuration variables. - (line 342) + (line 349) * tunnohead: Main configuration variables. - (line 136) + (line 135) +* UDP: The UDP tunnel. (line 30) * UDP <1>: Encryption of network packets. (line 11) -* UDP: The UDP tunnel. (line 30) * UDPRcvBuf: Main configuration variables. - (line 349) + (line 356) * UDPSndBuf: Main configuration variables. - (line 354) + (line 361) * UML: Main configuration variables. - (line 118) + (line 117) * Universal tun/tap: Configuration of Linux kernels. (line 6) * VDE: Main configuration variables. - (line 123) + (line 122) * virtual: Virtual Private Networks. (line 18) * virtual network device: The UDP tunnel. (line 6) @@ -3246,74 +3227,74 @@ Concept Index  Tag Table: -Node: Top811 -Node: Introduction1131 -Node: Virtual Private Networks1935 -Node: tinc3650 -Node: Supported platforms5161 -Node: Preparations5857 -Node: Configuring the kernel6113 -Node: Configuration of Linux kernels6522 -Node: Configuration of FreeBSD kernels7371 -Node: Configuration of OpenBSD kernels7836 -Node: Configuration of NetBSD kernels8444 -Node: Configuration of Solaris kernels8846 -Node: Configuration of Darwin (MacOS/X) kernels9507 -Node: Configuration of Windows10196 -Node: Libraries10710 -Node: OpenSSL11128 -Node: zlib13401 -Node: lzo14418 -Node: libcurses15407 -Node: libreadline16315 -Node: Installation17251 -Node: Building and installing tinc18261 -Node: Darwin (MacOS/X) build environment18917 -Node: Cygwin (Windows) build environment19481 -Node: MinGW (Windows) build environment20066 -Node: System files20584 -Node: Device files20849 -Node: Other files21262 -Node: Configuration21875 -Node: Configuration introduction22162 -Node: Multiple networks23684 -Node: How connections work25052 -Node: Configuration files27613 -Node: Main configuration variables29140 -Node: Host configuration variables45548 -Node: Scripts51020 -Node: How to configure53696 -Node: Network interfaces58178 -Node: Example configuration60557 -Node: Running tinc65648 -Node: Runtime options66235 -Node: Signals69096 -Node: Debug levels69946 -Node: Solving problems70882 -Node: Error messages72309 -Node: Sending bug reports76631 -Node: Controlling tinc77583 -Node: tinc runtime options77959 -Node: tinc environment variables78646 -Node: tinc commands78975 -Node: tinc examples83404 -Node: tinc top83967 -Node: Technical information85553 -Node: The connection85788 -Node: The UDP tunnel86100 -Node: The meta-connection89143 -Node: The meta-protocol90601 -Node: Security95575 -Node: Legacy authentication protocol96911 -Node: Simple Peer-to-Peer Security101526 -Node: Encryption of network packets107223 -Node: Security issues109850 -Node: Platform specific information111576 -Node: Interface configuration111804 -Node: Routes114245 -Node: About us116155 -Node: Contact information116330 -Node: Authors116731 -Node: Concept Index117134 +Node: Top807 +Node: Introduction1127 +Node: Virtual Private Networks1931 +Node: tinc3643 +Node: Supported platforms5155 +Node: Preparations5851 +Node: Configuring the kernel6107 +Node: Configuration of Linux kernels6516 +Node: Configuration of FreeBSD kernels7365 +Node: Configuration of OpenBSD kernels7830 +Node: Configuration of NetBSD kernels8438 +Node: Configuration of Solaris kernels8840 +Node: Configuration of Darwin (MacOS/X) kernels9501 +Node: Configuration of Windows10190 +Node: Libraries10703 +Node: OpenSSL11121 +Node: zlib13393 +Node: lzo14411 +Node: libcurses15401 +Node: libreadline16311 +Node: Installation17248 +Node: Building and installing tinc18257 +Node: Darwin (MacOS/X) build environment18913 +Node: Cygwin (Windows) build environment19477 +Node: MinGW (Windows) build environment20061 +Node: System files20579 +Node: Device files20844 +Node: Other files21257 +Node: Configuration21870 +Node: Configuration introduction22157 +Node: Multiple networks23678 +Node: How connections work25046 +Node: Configuration files27607 +Node: Main configuration variables29135 +Node: Host configuration variables45893 +Node: Scripts51364 +Node: How to configure54033 +Node: Network interfaces58509 +Node: Example configuration60888 +Node: Running tinc65981 +Node: Runtime options66568 +Node: Signals69428 +Node: Debug levels70277 +Node: Solving problems71213 +Node: Error messages72639 +Node: Sending bug reports76956 +Node: Controlling tinc77903 +Node: tinc runtime options78280 +Node: tinc environment variables78967 +Node: tinc commands79296 +Node: tinc examples84406 +Node: tinc top84969 +Node: Technical information86554 +Node: The connection86789 +Node: The UDP tunnel87101 +Node: The meta-connection90146 +Node: The meta-protocol91604 +Node: Security96587 +Node: Legacy authentication protocol97924 +Node: Simple Peer-to-Peer Security102541 +Node: Encryption of network packets108201 +Node: Security issues110830 +Node: Platform specific information112565 +Node: Interface configuration112793 +Node: Routes115234 +Node: About us117145 +Node: Contact information117320 +Node: Authors117722 +Node: Concept Index118124  End Tag Table diff --git a/doc/tinc.texi b/doc/tinc.texi index e1af55c..a295293 100644 --- a/doc/tinc.texi +++ b/doc/tinc.texi @@ -1002,14 +1002,12 @@ The file in which the private ECDSA key of this tinc daemon resides. This is only used if ExperimentalProtocol is enabled. @cindex ExperimentalProtocol -@item ExperimentalProtocol = (no) [experimental] -When this option is enabled, experimental protocol enhancements will be used. +@item ExperimentalProtocol = (yes) +When this option is enabled, the SPTPS protocol will be used when connecting to nodes that also support it. Ephemeral ECDH will be used for key exchanges, and ECDSA will be used instead of RSA for authentication. When enabled, an ECDSA key must have been generated before with @samp{tinc generate-ecdsa-keys}. -The experimental protocol may change at any time, -and there is no guarantee that tinc will run stable when it is used. @cindex Forwarding @item Forwarding = (internal) [experimental] @@ -1058,6 +1056,10 @@ which normally would prevent the peers from learning each other's LAN address. Currently, local discovery is implemented by sending broadcast packets to the LAN during path MTU discovery. This feature may not work in all possible situations. +@cindex LocalDiscoveryAddress +@item LocalDiscoveryAddress <@var{address}> +If this variable is specified, local discovery packets are sent to the given @var{address}. + @cindex Mode @item Mode = (router) This option selects the way packets are routed to other daemons. @@ -1099,6 +1101,13 @@ impossible to crack a single key. This option controls the amount of time MAC addresses are kept before they are removed. This only has effect when Mode is set to "switch". +@cindex MaxConnectionBurst +@item MaxConnectionBurst = <@var{count}> (100) +This option controls how many connections tinc accepts in quick succession. +If there are more connections than the given number in a short time interval, +tinc will reduce the number of accepted connections to only one per second, +until the burst has passed. + @cindex Name @item Name = <@var{name}> [required] This is a symbolic name for this connection. @@ -1180,7 +1189,6 @@ reordering. Setting this to zero will disable replay tracking completely and pass all traffic, but leaves tinc vulnerable to replay-based attacks on your traffic. - @cindex StrictSubnets @item StrictSubnets (no) [experimental] When this option is enabled tinc will only use Subnet statements which are @@ -2216,14 +2224,22 @@ The same as export followed by import. @item exchange-all [--force] The same as export-all followed by import. +@item invite @var{name} +Prepares an invitation for a new node with the given @var{name}, +and prints a short invitation URL that can be used with the join command. + +@item join [@var{URL}] +Join an existing VPN using an invitation URL created using the invite command. +If no @var{URL} is given, it will be read from standard input. + @item start [tincd options] Start @samp{tincd}, optionally with the given extra options. @item stop Stop @samp{tincd}. -@item restart -Restart @samp{tincd}. +@item restart [tincd options] +Restart @samp{tincd}, optionally with the given extra options. @item reload Partially rereads configuration files. Connections to hosts whose host @@ -2234,10 +2250,17 @@ in @file{tinc.conf} will be made. Shows the PID of the currently running @samp{tincd}. @item generate-keys [@var{bits}] -Generate public/private keypair of @var{bits} length. If @var{bits} is not specified, -1024 is the default. tinc will ask where you want to store the files, -but will default to the configuration directory (you can use the -c or -n -option). +Generate both RSA and ECDSA keypairs (see below) and exit. +tinc will ask where you want to store the files, but will default to the +configuration directory (you can use the -c or -n option). + +@item generate-ecdsa-keys +Generate public/private ECDSA keypair and exit. + +@item generate-rsa-keys [@var{bits}] +Generate public/private RSA keypair and exit. If @var{bits} is omitted, the +default length will be 2048 bits. When saving keys to existing files, tinc +will not delete the old keys; you have to remove them manually. @item dump [reachable] nodes Dump a list of all known nodes in the VPN. diff --git a/gui/Makefile.in b/gui/Makefile.in index 2e52de5..52c86ab 100644 --- a/gui/Makefile.in +++ b/gui/Makefile.in @@ -1,9 +1,8 @@ -# Makefile.in generated by automake 1.11.6 from Makefile.am. +# Makefile.in generated by automake 1.13.3 from Makefile.am. # @configure_input@ -# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software -# Foundation, Inc. +# Copyright (C) 1994-2013 Free Software Foundation, Inc. + # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -16,23 +15,51 @@ @SET_MAKE@ VPATH = @srcdir@ -am__make_dryrun = \ - { \ - am__dry=no; \ +am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ - echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ - | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ - *) \ - for am__flg in $$MAKEFLAGS; do \ - case $$am__flg in \ - *=*|--*) ;; \ - *n*) am__dry=yes; break;; \ - esac; \ - done;; \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ - test $$am__dry = yes; \ - } + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ @@ -52,13 +79,13 @@ POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = gui -DIST_COMMON = $(dist_bin_SCRIPTS) $(srcdir)/Makefile.am \ - $(srcdir)/Makefile.in +DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ + $(dist_bin_SCRIPTS) ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \ $(top_srcdir)/m4/curses.m4 $(top_srcdir)/m4/lzo.m4 \ $(top_srcdir)/m4/openssl.m4 $(top_srcdir)/m4/readline.m4 \ - $(top_srcdir)/m4/zlib.m4 $(top_srcdir)/configure.in + $(top_srcdir)/m4/zlib.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d @@ -94,6 +121,18 @@ am__uninstall_files_from_dir = { \ } am__installdirs = "$(DESTDIR)$(bindir)" SCRIPTS = $(dist_bin_SCRIPTS) +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ @@ -101,9 +140,11 @@ am__can_run_installinfo = \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ @@ -123,7 +164,6 @@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ GREP = @GREP@ -INCLUDES = @INCLUDES@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ @@ -137,7 +177,6 @@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ -MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ OBJEXT = @OBJEXT@ @@ -210,7 +249,7 @@ extra_DIST = README.gui all: all-am .SUFFIXES: -$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ @@ -235,9 +274,9 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) +$(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) +$(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-dist_binSCRIPTS: $(dist_bin_SCRIPTS) @@ -275,11 +314,26 @@ uninstall-dist_binSCRIPTS: files=`for p in $$list; do echo "$$p"; done | \ sed -e 's,.*/,,;$(transform)'`; \ dir='$(DESTDIR)$(bindir)'; $(am__uninstall_files_from_dir) -tags: TAGS -TAGS: -ctags: CTAGS -CTAGS: +installcheck-dist_binSCRIPTS: $(dist_bin_SCRIPTS) + bad=0; pid=$$$$; list="$(dist_bin_SCRIPTS)"; for p in $$list; do \ + case ' $(AM_INSTALLCHECK_STD_OPTIONS_EXEMPT) ' in \ + *" $$p "* | *" $(srcdir)/$$p "*) continue;; \ + esac; \ + f=`echo "$$p" | sed 's,^.*/,,;$(transform)'`; \ + for opt in --help --version; do \ + if "$(DESTDIR)$(bindir)/$$f" $$opt >c$${pid}_.out \ + 2>c$${pid}_.err &2; bad=1; fi; \ + done; \ + done; rm -f c$${pid}_.???; exit $$bad +tags TAGS: + +ctags CTAGS: + +cscope cscopelist: distdir: $(DISTFILES) @@ -395,7 +449,7 @@ install-ps: install-ps-am install-ps-am: -installcheck-am: +installcheck-am: installcheck-dist_binSCRIPTS maintainer-clean: maintainer-clean-am -rm -f Makefile @@ -417,16 +471,17 @@ uninstall-am: uninstall-dist_binSCRIPTS .MAKE: install-am install-strip -.PHONY: all all-am check check-am clean clean-generic distclean \ - distclean-generic distdir dvi dvi-am html html-am info info-am \ - install install-am install-data install-data-am \ - install-dist_binSCRIPTS install-dvi install-dvi-am \ - install-exec install-exec-am install-html install-html-am \ - install-info install-info-am install-man install-pdf \ - install-pdf-am install-ps install-ps-am install-strip \ - installcheck installcheck-am installdirs maintainer-clean \ +.PHONY: all all-am check check-am clean clean-generic cscopelist-am \ + ctags-am distclean distclean-generic distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dist_binSCRIPTS install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am \ + installcheck-dist_binSCRIPTS installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic pdf \ - pdf-am ps ps-am uninstall uninstall-am \ + pdf-am ps ps-am tags-am uninstall uninstall-am \ uninstall-dist_binSCRIPTS diff --git a/install-sh b/install-sh index a9244eb..377bb86 100755 --- a/install-sh +++ b/install-sh @@ -1,7 +1,7 @@ #!/bin/sh # install - install a program, script, or datafile -scriptversion=2011-01-19.21; # UTC +scriptversion=2011-11-20.07; # UTC # This originates from X11R5 (mit/util/scripts/install.sh), which was # later released in X11R6 (xc/config/util/install.sh) with the @@ -35,7 +35,7 @@ scriptversion=2011-01-19.21; # UTC # FSF changes to this file are in the public domain. # # Calling this script install-sh is preferred over install.sh, to prevent -# `make' implicit rules from creating a file called install from it +# 'make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written @@ -156,7 +156,7 @@ while test $# -ne 0; do -s) stripcmd=$stripprog;; -t) dst_arg=$2 - # Protect names problematic for `test' and other utilities. + # Protect names problematic for 'test' and other utilities. case $dst_arg in -* | [=\(\)!]) dst_arg=./$dst_arg;; esac @@ -190,7 +190,7 @@ if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then fi shift # arg dst_arg=$arg - # Protect names problematic for `test' and other utilities. + # Protect names problematic for 'test' and other utilities. case $dst_arg in -* | [=\(\)!]) dst_arg=./$dst_arg;; esac @@ -202,7 +202,7 @@ if test $# -eq 0; then echo "$0: no input file specified." >&2 exit 1 fi - # It's OK to call `install-sh -d' without argument. + # It's OK to call 'install-sh -d' without argument. # This can happen when creating conditional directories. exit 0 fi @@ -240,7 +240,7 @@ fi for src do - # Protect names problematic for `test' and other utilities. + # Protect names problematic for 'test' and other utilities. case $src in -* | [=\(\)!]) src=./$src;; esac @@ -354,7 +354,7 @@ do if test -z "$dir_arg" || { # Check for POSIX incompatibilities with -m. # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or - # other-writeable bit of parent directory when it shouldn't. + # other-writable bit of parent directory when it shouldn't. # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. ls_ld_tmpdir=`ls -ld "$tmpdir"` case $ls_ld_tmpdir in diff --git a/m4/Makefile.in b/m4/Makefile.in index 557ba46..fc5af2d 100644 --- a/m4/Makefile.in +++ b/m4/Makefile.in @@ -1,9 +1,8 @@ -# Makefile.in generated by automake 1.11.6 from Makefile.am. +# Makefile.in generated by automake 1.13.3 from Makefile.am. # @configure_input@ -# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software -# Foundation, Inc. +# Copyright (C) 1994-2013 Free Software Foundation, Inc. + # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -15,23 +14,51 @@ @SET_MAKE@ VPATH = @srcdir@ -am__make_dryrun = \ - { \ - am__dry=no; \ +am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ - echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ - | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ - *) \ - for am__flg in $$MAKEFLAGS; do \ - case $$am__flg in \ - *=*|--*) ;; \ - *n*) am__dry=yes; break;; \ - esac; \ - done;; \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ - test $$am__dry = yes; \ - } + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ @@ -51,18 +78,30 @@ POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = m4 -DIST_COMMON = README $(srcdir)/Makefile.am $(srcdir)/Makefile.in +DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am README ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \ $(top_srcdir)/m4/curses.m4 $(top_srcdir)/m4/lzo.m4 \ $(top_srcdir)/m4/openssl.m4 $(top_srcdir)/m4/readline.m4 \ - $(top_srcdir)/m4/zlib.m4 $(top_srcdir)/configure.in + $(top_srcdir)/m4/zlib.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ @@ -70,9 +109,11 @@ am__can_run_installinfo = \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ @@ -92,7 +133,6 @@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ GREP = @GREP@ -INCLUDES = @INCLUDES@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ @@ -106,7 +146,6 @@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ -MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ OBJEXT = @OBJEXT@ @@ -178,7 +217,7 @@ EXTRA_DIST = README *.m4 all: all-am .SUFFIXES: -$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ @@ -203,16 +242,16 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) +$(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) +$(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): -tags: TAGS -TAGS: +tags TAGS: -ctags: CTAGS -CTAGS: +ctags CTAGS: + +cscope cscopelist: distdir: $(DISTFILES) @@ -347,15 +386,16 @@ uninstall-am: .MAKE: install-am install-strip -.PHONY: all all-am check check-am clean clean-generic distclean \ - distclean-generic distdir dvi dvi-am html html-am info info-am \ - install install-am install-data install-data-am install-dvi \ - install-dvi-am install-exec install-exec-am install-html \ - install-html-am install-info install-info-am install-man \ - install-pdf install-pdf-am install-ps install-ps-am \ - install-strip installcheck installcheck-am installdirs \ - maintainer-clean maintainer-clean-generic mostlyclean \ - mostlyclean-generic pdf pdf-am ps ps-am uninstall uninstall-am +.PHONY: all all-am check check-am clean clean-generic cscopelist-am \ + ctags-am distclean distclean-generic distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-generic pdf \ + pdf-am ps ps-am tags-am uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. diff --git a/missing b/missing index 86a8fc3..cdea514 100755 --- a/missing +++ b/missing @@ -1,11 +1,10 @@ #! /bin/sh -# Common stub for a few missing GNU programs while installing. +# Common wrapper for a few potentially missing GNU programs. -scriptversion=2012-01-06.13; # UTC +scriptversion=2012-06-26.16; # UTC -# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006, -# 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc. -# Originally by Fran,cois Pinard , 1996. +# Copyright (C) 1996-2013 Free Software Foundation, Inc. +# Originally written by Fran,cois Pinard , 1996. # 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 @@ -26,68 +25,40 @@ scriptversion=2012-01-06.13; # UTC # the same distribution terms that you use for the rest of that program. if test $# -eq 0; then - echo 1>&2 "Try \`$0 --help' for more information" + echo 1>&2 "Try '$0 --help' for more information" exit 1 fi -run=: -sed_output='s/.* --output[ =]\([^ ]*\).*/\1/p' -sed_minuso='s/.* -o \([^ ]*\).*/\1/p' - -# In the cases where this matters, `missing' is being run in the -# srcdir already. -if test -f configure.ac; then - configure_ac=configure.ac -else - configure_ac=configure.in -fi - -msg="missing on your system" - case $1 in ---run) - # Try to run requested program, and just exit if it succeeds. - run= - shift - "$@" && exit 0 - # Exit code 63 means version mismatch. This often happens - # when the user try to use an ancient version of a tool on - # a file that requires a minimum version. In this case we - # we should proceed has if the program had been absent, or - # if --run hadn't been passed. - if test $? = 63; then - run=: - msg="probably too old" - fi - ;; + + --is-lightweight) + # Used by our autoconf macros to check whether the available missing + # script is modern enough. + exit 0 + ;; + + --run) + # Back-compat with the calling convention used by older automake. + shift + ;; -h|--h|--he|--hel|--help) echo "\ $0 [OPTION]... PROGRAM [ARGUMENT]... -Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an -error status if there is no known handling for PROGRAM. +Run 'PROGRAM [ARGUMENT]...', returning a proper advice when this fails due +to PROGRAM being missing or too old. Options: -h, --help display this help and exit -v, --version output version information and exit - --run try to run the given command, and emulate it if it fails Supported PROGRAM values: - aclocal touch file \`aclocal.m4' - autoconf touch file \`configure' - autoheader touch file \`config.h.in' - autom4te touch the output file, or create a stub one - automake touch all \`Makefile.in' files - bison create \`y.tab.[ch]', if possible, from existing .[ch] - flex create \`lex.yy.c', if possible, from existing .c - help2man touch the output file - lex create \`lex.yy.c', if possible, from existing .c - makeinfo touch the output file - yacc create \`y.tab.[ch]', if possible, from existing .[ch] + aclocal autoconf autoheader autom4te automake makeinfo + bison yacc flex lex help2man -Version suffixes to PROGRAM as well as the prefixes \`gnu-', \`gnu', and -\`g' are ignored when checking the name. +Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and +'g' are ignored when checking the name. Send bug reports to ." exit $? @@ -99,228 +70,141 @@ Send bug reports to ." ;; -*) - echo 1>&2 "$0: Unknown \`$1' option" - echo 1>&2 "Try \`$0 --help' for more information" + echo 1>&2 "$0: unknown '$1' option" + echo 1>&2 "Try '$0 --help' for more information" exit 1 ;; esac -# normalize program name to check for. -program=`echo "$1" | sed ' - s/^gnu-//; t - s/^gnu//; t - s/^g//; t'` +# Run the given program, remember its exit status. +"$@"; st=$? -# Now exit if we have it, but it failed. Also exit now if we -# don't have it and --version was passed (most likely to detect -# the program). This is about non-GNU programs, so use $1 not -# $program. -case $1 in - lex*|yacc*) - # Not GNU programs, they don't have --version. +# If it succeeded, we are done. +test $st -eq 0 && exit 0 + +# Also exit now if we it failed (or wasn't found), and '--version' was +# passed; such an option is passed most likely to detect whether the +# program is present and works. +case $2 in --version|--help) exit $st;; esac + +# Exit code 63 means version mismatch. This often happens when the user +# tries to use an ancient version of a tool on a file that requires a +# minimum version. +if test $st -eq 63; then + msg="probably too old" +elif test $st -eq 127; then + # Program was missing. + msg="missing on your system" +else + # Program was found and executed, but failed. Give up. + exit $st +fi + +perl_URL=http://www.perl.org/ +flex_URL=http://flex.sourceforge.net/ +gnu_software_URL=http://www.gnu.org/software + +program_details () +{ + case $1 in + aclocal|automake) + echo "The '$1' program is part of the GNU Automake package:" + echo "<$gnu_software_URL/automake>" + echo "It also requires GNU Autoconf, GNU m4 and Perl in order to run:" + echo "<$gnu_software_URL/autoconf>" + echo "<$gnu_software_URL/m4/>" + echo "<$perl_URL>" + ;; + autoconf|autom4te|autoheader) + echo "The '$1' program is part of the GNU Autoconf package:" + echo "<$gnu_software_URL/autoconf/>" + echo "It also requires GNU m4 and Perl in order to run:" + echo "<$gnu_software_URL/m4/>" + echo "<$perl_URL>" + ;; + esac +} + +give_advice () +{ + # Normalize program name to check for. + normalized_program=`echo "$1" | sed ' + s/^gnu-//; t + s/^gnu//; t + s/^g//; t'` + + printf '%s\n' "'$1' is $msg." + + configure_deps="'configure.ac' or m4 files included by 'configure.ac'" + case $normalized_program in + autoconf*) + echo "You should only need it if you modified 'configure.ac'," + echo "or m4 files included by it." + program_details 'autoconf' + ;; + autoheader*) + echo "You should only need it if you modified 'acconfig.h' or" + echo "$configure_deps." + program_details 'autoheader' + ;; + automake*) + echo "You should only need it if you modified 'Makefile.am' or" + echo "$configure_deps." + program_details 'automake' + ;; + aclocal*) + echo "You should only need it if you modified 'acinclude.m4' or" + echo "$configure_deps." + program_details 'aclocal' + ;; + autom4te*) + echo "You might have modified some maintainer files that require" + echo "the 'automa4te' program to be rebuilt." + program_details 'autom4te' + ;; + bison*|yacc*) + echo "You should only need it if you modified a '.y' file." + echo "You may want to install the GNU Bison package:" + echo "<$gnu_software_URL/bison/>" + ;; + lex*|flex*) + echo "You should only need it if you modified a '.l' file." + echo "You may want to install the Fast Lexical Analyzer package:" + echo "<$flex_URL>" + ;; + help2man*) + echo "You should only need it if you modified a dependency" \ + "of a man page." + echo "You may want to install the GNU Help2man package:" + echo "<$gnu_software_URL/help2man/>" ;; + makeinfo*) + echo "You should only need it if you modified a '.texi' file, or" + echo "any other file indirectly affecting the aspect of the manual." + echo "You might want to install the Texinfo package:" + echo "<$gnu_software_URL/texinfo/>" + echo "The spurious makeinfo call might also be the consequence of" + echo "using a buggy 'make' (AIX, DU, IRIX), in which case you might" + echo "want to install GNU make:" + echo "<$gnu_software_URL/make/>" + ;; + *) + echo "You might have modified some files without having the proper" + echo "tools for further handling them. Check the 'README' file, it" + echo "often tells you about the needed prerequisites for installing" + echo "this package. You may also peek at any GNU archive site, in" + echo "case some other package contains this missing '$1' program." + ;; + esac +} - *) - if test -z "$run" && ($1 --version) > /dev/null 2>&1; then - # We have it, but it failed. - exit 1 - elif test "x$2" = "x--version" || test "x$2" = "x--help"; then - # Could not run --version or --help. This is probably someone - # running `$TOOL --version' or `$TOOL --help' to check whether - # $TOOL exists and not knowing $TOOL uses missing. - exit 1 - fi - ;; -esac +give_advice "$1" | sed -e '1s/^/WARNING: /' \ + -e '2,$s/^/ /' >&2 -# If it does not exist, or fails to run (possibly an outdated version), -# try to emulate it. -case $program in - aclocal*) - echo 1>&2 "\ -WARNING: \`$1' is $msg. You should only need it if - you modified \`acinclude.m4' or \`${configure_ac}'. You might want - to install the \`Automake' and \`Perl' packages. Grab them from - any GNU archive site." - touch aclocal.m4 - ;; - - autoconf*) - echo 1>&2 "\ -WARNING: \`$1' is $msg. You should only need it if - you modified \`${configure_ac}'. You might want to install the - \`Autoconf' and \`GNU m4' packages. Grab them from any GNU - archive site." - touch configure - ;; - - autoheader*) - echo 1>&2 "\ -WARNING: \`$1' is $msg. You should only need it if - you modified \`acconfig.h' or \`${configure_ac}'. You might want - to install the \`Autoconf' and \`GNU m4' packages. Grab them - from any GNU archive site." - files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}` - test -z "$files" && files="config.h" - touch_files= - for f in $files; do - case $f in - *:*) touch_files="$touch_files "`echo "$f" | - sed -e 's/^[^:]*://' -e 's/:.*//'`;; - *) touch_files="$touch_files $f.in";; - esac - done - touch $touch_files - ;; - - automake*) - echo 1>&2 "\ -WARNING: \`$1' is $msg. You should only need it if - you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'. - You might want to install the \`Automake' and \`Perl' packages. - Grab them from any GNU archive site." - find . -type f -name Makefile.am -print | - sed 's/\.am$/.in/' | - while read f; do touch "$f"; done - ;; - - autom4te*) - echo 1>&2 "\ -WARNING: \`$1' is needed, but is $msg. - You might have modified some files without having the - proper tools for further handling them. - You can get \`$1' as part of \`Autoconf' from any GNU - archive site." - - file=`echo "$*" | sed -n "$sed_output"` - test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` - if test -f "$file"; then - touch $file - else - test -z "$file" || exec >$file - echo "#! /bin/sh" - echo "# Created by GNU Automake missing as a replacement of" - echo "# $ $@" - echo "exit 0" - chmod +x $file - exit 1 - fi - ;; - - bison*|yacc*) - echo 1>&2 "\ -WARNING: \`$1' $msg. You should only need it if - you modified a \`.y' file. You may need the \`Bison' package - in order for those modifications to take effect. You can get - \`Bison' from any GNU archive site." - rm -f y.tab.c y.tab.h - if test $# -ne 1; then - eval LASTARG=\${$#} - case $LASTARG in - *.y) - SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` - if test -f "$SRCFILE"; then - cp "$SRCFILE" y.tab.c - fi - SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` - if test -f "$SRCFILE"; then - cp "$SRCFILE" y.tab.h - fi - ;; - esac - fi - if test ! -f y.tab.h; then - echo >y.tab.h - fi - if test ! -f y.tab.c; then - echo 'main() { return 0; }' >y.tab.c - fi - ;; - - lex*|flex*) - echo 1>&2 "\ -WARNING: \`$1' is $msg. You should only need it if - you modified a \`.l' file. You may need the \`Flex' package - in order for those modifications to take effect. You can get - \`Flex' from any GNU archive site." - rm -f lex.yy.c - if test $# -ne 1; then - eval LASTARG=\${$#} - case $LASTARG in - *.l) - SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` - if test -f "$SRCFILE"; then - cp "$SRCFILE" lex.yy.c - fi - ;; - esac - fi - if test ! -f lex.yy.c; then - echo 'main() { return 0; }' >lex.yy.c - fi - ;; - - help2man*) - echo 1>&2 "\ -WARNING: \`$1' is $msg. You should only need it if - you modified a dependency of a manual page. You may need the - \`Help2man' package in order for those modifications to take - effect. You can get \`Help2man' from any GNU archive site." - - file=`echo "$*" | sed -n "$sed_output"` - test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` - if test -f "$file"; then - touch $file - else - test -z "$file" || exec >$file - echo ".ab help2man is required to generate this page" - exit $? - fi - ;; - - makeinfo*) - echo 1>&2 "\ -WARNING: \`$1' is $msg. You should only need it if - you modified a \`.texi' or \`.texinfo' file, or any other file - indirectly affecting the aspect of the manual. The spurious - call might also be the consequence of using a buggy \`make' (AIX, - DU, IRIX). You might want to install the \`Texinfo' package or - the \`GNU make' package. Grab either from any GNU archive site." - # The file to touch is that specified with -o ... - file=`echo "$*" | sed -n "$sed_output"` - test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` - if test -z "$file"; then - # ... or it is the one specified with @setfilename ... - infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` - file=`sed -n ' - /^@setfilename/{ - s/.* \([^ ]*\) *$/\1/ - p - q - }' $infile` - # ... or it is derived from the source name (dir/f.texi becomes f.info) - test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info - fi - # If the file does not exist, the user really needs makeinfo; - # let's fail without touching anything. - test -f $file || exit 1 - touch $file - ;; - - *) - echo 1>&2 "\ -WARNING: \`$1' is needed, and is $msg. - You might have modified some files without having the - proper tools for further handling them. Check the \`README' file, - it often tells you about the needed prerequisites for installing - this package. You may also peek at any GNU archive site, in case - some other package would contain this missing \`$1' program." - exit 1 - ;; -esac - -exit 0 +# Propagate the correct exit status (expected to be 127 for a program +# not found, 63 for a program that failed due to version mismatch). +exit $st # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) diff --git a/src/Makefile.am b/src/Makefile.am index c073eec..27d2330 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -4,13 +4,114 @@ sbin_PROGRAMS = tincd tinc sptps_test EXTRA_DIST = linux bsd solaris cygwin mingw openssl gcrypt +DEFAULT_INCLUDES = + tincd_SOURCES = \ - utils.c getopt.c getopt1.c list.c splay_tree.c dropin.c fake-getaddrinfo.c fake-getnameinfo.c hash.c \ - buffer.c conf.c connection.c control.c edge.c graph.c logger.c meta.c net.c net_packet.c net_setup.c \ - net_socket.c netutl.c node.c process.c protocol.c protocol_auth.c protocol_edge.c protocol_misc.c \ - protocol_key.c protocol_subnet.c route.c sptps.c subnet.c subnet_parse.c event.c tincd.c \ - dummy_device.c raw_socket_device.c multicast_device.c names.c + buffer.c buffer.h \ + cipher.h \ + conf.c conf.h \ + connection.c connection.h \ + control.c control.h \ + control_common.h \ + crypto.h \ + device.h \ + digest.h \ + dropin.c dropin.h \ + dummy_device.c \ + ecdh.h \ + ecdsa.h \ + ecdsagen.h \ + edge.c edge.h \ + ethernet.h \ + event.c event.h \ + fake-gai-errnos.h \ + fake-getaddrinfo.c fake-getaddrinfo.h \ + fake-getnameinfo.c fake-getnameinfo.h \ + getopt.c getopt.h \ + getopt1.c \ + graph.c graph.h \ + hash.c hash.h \ + have.h \ + ipv4.h \ + ipv6.h \ + list.c list.h \ + logger.c logger.h \ + meta.c meta.h \ + multicast_device.c \ + names.c names.h \ + net.c net.h \ + net_packet.c \ + net_setup.c \ + net_socket.c \ + netutl.c netutl.h \ + node.c node.h \ + prf.h \ + process.c process.h \ + protocol.c protocol.h \ + protocol_auth.c \ + protocol_edge.c \ + protocol_key.c \ + protocol_misc.c \ + protocol_subnet.c \ + raw_socket_device.c \ + route.c route.h \ + rsa.h \ + rsagen.h \ + splay_tree.c splay_tree.h \ + sptps.c sptps.h \ + subnet.c subnet.h \ + subnet_parse.c \ + system.h \ + tincd.c \ + utils.c utils.h \ + xalloc.h + +tinc_SOURCES = \ + dropin.c dropin.h \ + getopt.c getopt.h \ + getopt1.c \ + info.c info.h \ + invitation.c invitation.h \ + list.c list.h \ + names.c names.h \ + netutl.c netutl.h \ + sptps.c sptps.h \ + subnet_parse.c subnet.h \ + tincctl.c tincctl.h \ + top.c top.h \ + utils.c utils.h + +sptps_test_SOURCES = \ + logger.c logger.h \ + sptps.c sptps.h \ + sptps_test.c \ + utils.c utils.h + +## Conditionally compile device drivers +if LINUX +tincd_SOURCES += linux/device.c +endif + +if BSD +tincd_SOURCES += bsd/device.c +if TUNEMU +tincd_SOURCES += bsd/tunemu.c +endif +endif + +if SOLARIS +tincd_SOURCES += solaris/device.c +endif + +if MINGW +tincd_SOURCES += mingw/device.c +endif + +if CYGWIN +tincd_SOURCES += cygwin/device.c +endif + if UML tincd_SOURCES += uml_device.c endif @@ -19,38 +120,64 @@ if VDE tincd_SOURCES += vde_device.c endif -nodist_tincd_SOURCES = \ - device.c cipher.c crypto.c ecdh.c ecdsa.c digest.c prf.c rsa.c +if OPENSSL +tincd_SOURCES += \ + openssl/cipher.c \ + openssl/crypto.c \ + openssl/digest.c \ + openssl/ecdh.c \ + openssl/ecdsa.c \ + openssl/prf.c \ + openssl/rsa.c +tinc_SOURCES += \ + openssl/cipher.c \ + openssl/crypto.c \ + openssl/digest.c \ + openssl/ecdh.c \ + openssl/ecdsa.c \ + openssl/ecdsagen.c \ + openssl/prf.c \ + openssl/rsa.c \ + openssl/rsagen.c +sptps_test_SOURCES += \ + openssl/cipher.c \ + openssl/crypto.c \ + openssl/digest.c \ + openssl/ecdh.c \ + openssl/ecdsa.c \ + openssl/prf.c +endif -tinc_SOURCES = \ - utils.c getopt.c getopt1.c dropin.c \ - info.c list.c subnet_parse.c tincctl.c top.c names.c - -nodist_tinc_SOURCES = \ - ecdsagen.c rsagen.c - -sptps_test_SOURCES = \ - logger.c cipher.c crypto.c ecdh.c ecdsa.c digest.c prf.c \ - sptps.c sptps_test.c utils.c - -if TUNEMU -tincd_SOURCES += bsd/tunemu.c +if GCRYPT +tincd_SOURCES += \ + gcrypt/cipher.c \ + gcrypt/crypto.c \ + gcrypt/digest.c \ + gcrypt/ecdh.c \ + gcrypt/ecdsa.c \ + gcrypt/prf.c \ + gcrypt/rsa.c +tinc_SOURCES += \ + gcrypt/cipher.c \ + gcrypt/crypto.c \ + gcrypt/digest.c \ + gcrypt/ecdh.c \ + gcrypt/ecdsa.c \ + gcrypt/ecdsagen.c \ + gcrypt/prf.c \ + gcrypt/rsa.c \ + gcrypt/rsagen.c +sptps_test_SOURCES += \ + gcrypt/cipher.c \ + gcrypt/crypto.c \ + gcrypt/digest.c \ + gcrypt/ecdh.c \ + gcrypt/ecdsa.c \ + gcrypt/prf.c endif tinc_LDADD = $(READLINE_LIBS) $(CURSES_LIBS) -DEFAULT_INCLUDES = - -INCLUDES = @INCLUDES@ -I$(top_builddir) - -noinst_HEADERS = \ - xalloc.h utils.h getopt.h list.h splay_tree.h dropin.h fake-getaddrinfo.h fake-getnameinfo.h fake-gai-errnos.h ipv6.h ipv4.h ethernet.h \ - buffer.h conf.h connection.h control.h control_common.h device.h edge.h graph.h info.h logger.h meta.h net.h netutl.h node.h process.h \ - protocol.h route.h subnet.h sptps.h tincctl.h top.h bsd/tunemu.h hash.h event.h names.h - -nodist_noinst_HEADERS = \ - cipher.h crypto.h ecdh.h ecdsa.h digest.h prf.h rsa.h ecdsagen.h rsagen.h - LIBS = @LIBS@ @LIBGCRYPT_LIBS@ if TUNEMU diff --git a/src/Makefile.in b/src/Makefile.in index 48f7dad..ab5daa4 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -1,9 +1,8 @@ -# Makefile.in generated by automake 1.11.6 from Makefile.am. +# Makefile.in generated by automake 1.13.3 from Makefile.am. # @configure_input@ -# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software -# Foundation, Inc. +# Copyright (C) 1994-2013 Free Software Foundation, Inc. + # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -15,25 +14,52 @@ @SET_MAKE@ - VPATH = @srcdir@ -am__make_dryrun = \ - { \ - am__dry=no; \ +am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ - echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ - | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ - *) \ - for am__flg in $$MAKEFLAGS; do \ - case $$am__flg in \ - *=*|--*) ;; \ - *n*) am__dry=yes; break;; \ - esac; \ - done;; \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ - test $$am__dry = yes; \ - } + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ @@ -53,18 +79,79 @@ POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ sbin_PROGRAMS = tincd$(EXEEXT) tinc$(EXEEXT) sptps_test$(EXEEXT) -@UML_TRUE@am__append_1 = uml_device.c -@VDE_TRUE@am__append_2 = vde_device.c -@TUNEMU_TRUE@am__append_3 = bsd/tunemu.c -@TUNEMU_TRUE@am__append_4 = -lpcap +@LINUX_TRUE@am__append_1 = linux/device.c +@BSD_TRUE@am__append_2 = bsd/device.c +@BSD_TRUE@@TUNEMU_TRUE@am__append_3 = bsd/tunemu.c +@SOLARIS_TRUE@am__append_4 = solaris/device.c +@MINGW_TRUE@am__append_5 = mingw/device.c +@CYGWIN_TRUE@am__append_6 = cygwin/device.c +@UML_TRUE@am__append_7 = uml_device.c +@VDE_TRUE@am__append_8 = vde_device.c +@OPENSSL_TRUE@am__append_9 = \ +@OPENSSL_TRUE@ openssl/cipher.c \ +@OPENSSL_TRUE@ openssl/crypto.c \ +@OPENSSL_TRUE@ openssl/digest.c \ +@OPENSSL_TRUE@ openssl/ecdh.c \ +@OPENSSL_TRUE@ openssl/ecdsa.c \ +@OPENSSL_TRUE@ openssl/prf.c \ +@OPENSSL_TRUE@ openssl/rsa.c + +@OPENSSL_TRUE@am__append_10 = \ +@OPENSSL_TRUE@ openssl/cipher.c \ +@OPENSSL_TRUE@ openssl/crypto.c \ +@OPENSSL_TRUE@ openssl/digest.c \ +@OPENSSL_TRUE@ openssl/ecdh.c \ +@OPENSSL_TRUE@ openssl/ecdsa.c \ +@OPENSSL_TRUE@ openssl/ecdsagen.c \ +@OPENSSL_TRUE@ openssl/prf.c \ +@OPENSSL_TRUE@ openssl/rsa.c \ +@OPENSSL_TRUE@ openssl/rsagen.c + +@OPENSSL_TRUE@am__append_11 = \ +@OPENSSL_TRUE@ openssl/cipher.c \ +@OPENSSL_TRUE@ openssl/crypto.c \ +@OPENSSL_TRUE@ openssl/digest.c \ +@OPENSSL_TRUE@ openssl/ecdh.c \ +@OPENSSL_TRUE@ openssl/ecdsa.c \ +@OPENSSL_TRUE@ openssl/prf.c + +@GCRYPT_TRUE@am__append_12 = \ +@GCRYPT_TRUE@ gcrypt/cipher.c \ +@GCRYPT_TRUE@ gcrypt/crypto.c \ +@GCRYPT_TRUE@ gcrypt/digest.c \ +@GCRYPT_TRUE@ gcrypt/ecdh.c \ +@GCRYPT_TRUE@ gcrypt/ecdsa.c \ +@GCRYPT_TRUE@ gcrypt/prf.c \ +@GCRYPT_TRUE@ gcrypt/rsa.c + +@GCRYPT_TRUE@am__append_13 = \ +@GCRYPT_TRUE@ gcrypt/cipher.c \ +@GCRYPT_TRUE@ gcrypt/crypto.c \ +@GCRYPT_TRUE@ gcrypt/digest.c \ +@GCRYPT_TRUE@ gcrypt/ecdh.c \ +@GCRYPT_TRUE@ gcrypt/ecdsa.c \ +@GCRYPT_TRUE@ gcrypt/ecdsagen.c \ +@GCRYPT_TRUE@ gcrypt/prf.c \ +@GCRYPT_TRUE@ gcrypt/rsa.c \ +@GCRYPT_TRUE@ gcrypt/rsagen.c + +@GCRYPT_TRUE@am__append_14 = \ +@GCRYPT_TRUE@ gcrypt/cipher.c \ +@GCRYPT_TRUE@ gcrypt/crypto.c \ +@GCRYPT_TRUE@ gcrypt/digest.c \ +@GCRYPT_TRUE@ gcrypt/ecdh.c \ +@GCRYPT_TRUE@ gcrypt/ecdsa.c \ +@GCRYPT_TRUE@ gcrypt/prf.c + +@TUNEMU_TRUE@am__append_15 = -lpcap subdir = src -DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \ - $(srcdir)/Makefile.in +DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ + $(top_srcdir)/depcomp ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \ $(top_srcdir)/m4/curses.m4 $(top_srcdir)/m4/lzo.m4 \ $(top_srcdir)/m4/openssl.m4 $(top_srcdir)/m4/readline.m4 \ - $(top_srcdir)/m4/zlib.m4 $(top_srcdir)/configure.in + $(top_srcdir)/m4/zlib.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d @@ -73,76 +160,170 @@ CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__installdirs = "$(DESTDIR)$(sbindir)" PROGRAMS = $(sbin_PROGRAMS) -am_sptps_test_OBJECTS = logger.$(OBJEXT) cipher.$(OBJEXT) \ - crypto.$(OBJEXT) ecdh.$(OBJEXT) ecdsa.$(OBJEXT) \ - digest.$(OBJEXT) prf.$(OBJEXT) sptps.$(OBJEXT) \ - sptps_test.$(OBJEXT) utils.$(OBJEXT) +am__sptps_test_SOURCES_DIST = logger.c logger.h sptps.c sptps.h \ + sptps_test.c utils.c utils.h openssl/cipher.c openssl/crypto.c \ + openssl/digest.c openssl/ecdh.c openssl/ecdsa.c openssl/prf.c \ + gcrypt/cipher.c gcrypt/crypto.c gcrypt/digest.c gcrypt/ecdh.c \ + gcrypt/ecdsa.c gcrypt/prf.c +am__dirstamp = $(am__leading_dot)dirstamp +@OPENSSL_TRUE@am__objects_1 = openssl/cipher.$(OBJEXT) \ +@OPENSSL_TRUE@ openssl/crypto.$(OBJEXT) \ +@OPENSSL_TRUE@ openssl/digest.$(OBJEXT) openssl/ecdh.$(OBJEXT) \ +@OPENSSL_TRUE@ openssl/ecdsa.$(OBJEXT) openssl/prf.$(OBJEXT) +@GCRYPT_TRUE@am__objects_2 = gcrypt/cipher.$(OBJEXT) \ +@GCRYPT_TRUE@ gcrypt/crypto.$(OBJEXT) gcrypt/digest.$(OBJEXT) \ +@GCRYPT_TRUE@ gcrypt/ecdh.$(OBJEXT) gcrypt/ecdsa.$(OBJEXT) \ +@GCRYPT_TRUE@ gcrypt/prf.$(OBJEXT) +am_sptps_test_OBJECTS = logger.$(OBJEXT) sptps.$(OBJEXT) \ + sptps_test.$(OBJEXT) utils.$(OBJEXT) $(am__objects_1) \ + $(am__objects_2) sptps_test_OBJECTS = $(am_sptps_test_OBJECTS) sptps_test_LDADD = $(LDADD) -am_tinc_OBJECTS = utils.$(OBJEXT) getopt.$(OBJEXT) getopt1.$(OBJEXT) \ - dropin.$(OBJEXT) info.$(OBJEXT) list.$(OBJEXT) \ +am__tinc_SOURCES_DIST = dropin.c dropin.h getopt.c getopt.h getopt1.c \ + info.c info.h invitation.c invitation.h list.c list.h names.c \ + names.h netutl.c netutl.h sptps.c sptps.h subnet_parse.c \ + subnet.h tincctl.c tincctl.h top.c top.h utils.c utils.h \ + openssl/cipher.c openssl/crypto.c openssl/digest.c \ + openssl/ecdh.c openssl/ecdsa.c openssl/ecdsagen.c \ + openssl/prf.c openssl/rsa.c openssl/rsagen.c gcrypt/cipher.c \ + gcrypt/crypto.c gcrypt/digest.c gcrypt/ecdh.c gcrypt/ecdsa.c \ + gcrypt/ecdsagen.c gcrypt/prf.c gcrypt/rsa.c gcrypt/rsagen.c +@OPENSSL_TRUE@am__objects_3 = openssl/cipher.$(OBJEXT) \ +@OPENSSL_TRUE@ openssl/crypto.$(OBJEXT) \ +@OPENSSL_TRUE@ openssl/digest.$(OBJEXT) openssl/ecdh.$(OBJEXT) \ +@OPENSSL_TRUE@ openssl/ecdsa.$(OBJEXT) \ +@OPENSSL_TRUE@ openssl/ecdsagen.$(OBJEXT) openssl/prf.$(OBJEXT) \ +@OPENSSL_TRUE@ openssl/rsa.$(OBJEXT) openssl/rsagen.$(OBJEXT) +@GCRYPT_TRUE@am__objects_4 = gcrypt/cipher.$(OBJEXT) \ +@GCRYPT_TRUE@ gcrypt/crypto.$(OBJEXT) gcrypt/digest.$(OBJEXT) \ +@GCRYPT_TRUE@ gcrypt/ecdh.$(OBJEXT) gcrypt/ecdsa.$(OBJEXT) \ +@GCRYPT_TRUE@ gcrypt/ecdsagen.$(OBJEXT) gcrypt/prf.$(OBJEXT) \ +@GCRYPT_TRUE@ gcrypt/rsa.$(OBJEXT) gcrypt/rsagen.$(OBJEXT) +am_tinc_OBJECTS = dropin.$(OBJEXT) getopt.$(OBJEXT) getopt1.$(OBJEXT) \ + info.$(OBJEXT) invitation.$(OBJEXT) list.$(OBJEXT) \ + names.$(OBJEXT) netutl.$(OBJEXT) sptps.$(OBJEXT) \ subnet_parse.$(OBJEXT) tincctl.$(OBJEXT) top.$(OBJEXT) \ - names.$(OBJEXT) -nodist_tinc_OBJECTS = ecdsagen.$(OBJEXT) rsagen.$(OBJEXT) -tinc_OBJECTS = $(am_tinc_OBJECTS) $(nodist_tinc_OBJECTS) + utils.$(OBJEXT) $(am__objects_3) $(am__objects_4) +tinc_OBJECTS = $(am_tinc_OBJECTS) am__DEPENDENCIES_1 = tinc_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) -am__tincd_SOURCES_DIST = utils.c getopt.c getopt1.c list.c \ - splay_tree.c dropin.c fake-getaddrinfo.c fake-getnameinfo.c \ - hash.c buffer.c conf.c connection.c control.c edge.c graph.c \ - logger.c meta.c net.c net_packet.c net_setup.c net_socket.c \ - netutl.c node.c process.c protocol.c protocol_auth.c \ - protocol_edge.c protocol_misc.c protocol_key.c \ - protocol_subnet.c route.c sptps.c subnet.c subnet_parse.c \ - event.c tincd.c dummy_device.c raw_socket_device.c \ - multicast_device.c names.c uml_device.c vde_device.c \ - bsd/tunemu.c -@UML_TRUE@am__objects_1 = uml_device.$(OBJEXT) -@VDE_TRUE@am__objects_2 = vde_device.$(OBJEXT) -@TUNEMU_TRUE@am__objects_3 = tunemu.$(OBJEXT) -am_tincd_OBJECTS = utils.$(OBJEXT) getopt.$(OBJEXT) getopt1.$(OBJEXT) \ - list.$(OBJEXT) splay_tree.$(OBJEXT) dropin.$(OBJEXT) \ +am__tincd_SOURCES_DIST = buffer.c buffer.h cipher.h conf.c conf.h \ + connection.c connection.h control.c control.h control_common.h \ + crypto.h device.h digest.h dropin.c dropin.h dummy_device.c \ + ecdh.h ecdsa.h ecdsagen.h edge.c edge.h ethernet.h event.c \ + event.h fake-gai-errnos.h fake-getaddrinfo.c \ + fake-getaddrinfo.h fake-getnameinfo.c fake-getnameinfo.h \ + getopt.c getopt.h getopt1.c graph.c graph.h hash.c hash.h \ + have.h ipv4.h ipv6.h list.c list.h logger.c logger.h meta.c \ + meta.h multicast_device.c names.c names.h net.c net.h \ + net_packet.c net_setup.c net_socket.c netutl.c netutl.h node.c \ + node.h prf.h process.c process.h protocol.c protocol.h \ + protocol_auth.c protocol_edge.c protocol_key.c protocol_misc.c \ + protocol_subnet.c raw_socket_device.c route.c route.h rsa.h \ + rsagen.h splay_tree.c splay_tree.h sptps.c sptps.h subnet.c \ + subnet.h subnet_parse.c system.h tincd.c utils.c utils.h \ + xalloc.h linux/device.c bsd/device.c bsd/tunemu.c \ + solaris/device.c mingw/device.c cygwin/device.c uml_device.c \ + vde_device.c openssl/cipher.c openssl/crypto.c \ + openssl/digest.c openssl/ecdh.c openssl/ecdsa.c openssl/prf.c \ + openssl/rsa.c gcrypt/cipher.c gcrypt/crypto.c gcrypt/digest.c \ + gcrypt/ecdh.c gcrypt/ecdsa.c gcrypt/prf.c gcrypt/rsa.c +@LINUX_TRUE@am__objects_5 = linux/device.$(OBJEXT) +@BSD_TRUE@am__objects_6 = bsd/device.$(OBJEXT) +@BSD_TRUE@@TUNEMU_TRUE@am__objects_7 = bsd/tunemu.$(OBJEXT) +@SOLARIS_TRUE@am__objects_8 = solaris/device.$(OBJEXT) +@MINGW_TRUE@am__objects_9 = mingw/device.$(OBJEXT) +@CYGWIN_TRUE@am__objects_10 = cygwin/device.$(OBJEXT) +@UML_TRUE@am__objects_11 = uml_device.$(OBJEXT) +@VDE_TRUE@am__objects_12 = vde_device.$(OBJEXT) +@OPENSSL_TRUE@am__objects_13 = openssl/cipher.$(OBJEXT) \ +@OPENSSL_TRUE@ openssl/crypto.$(OBJEXT) \ +@OPENSSL_TRUE@ openssl/digest.$(OBJEXT) openssl/ecdh.$(OBJEXT) \ +@OPENSSL_TRUE@ openssl/ecdsa.$(OBJEXT) openssl/prf.$(OBJEXT) \ +@OPENSSL_TRUE@ openssl/rsa.$(OBJEXT) +@GCRYPT_TRUE@am__objects_14 = gcrypt/cipher.$(OBJEXT) \ +@GCRYPT_TRUE@ gcrypt/crypto.$(OBJEXT) gcrypt/digest.$(OBJEXT) \ +@GCRYPT_TRUE@ gcrypt/ecdh.$(OBJEXT) gcrypt/ecdsa.$(OBJEXT) \ +@GCRYPT_TRUE@ gcrypt/prf.$(OBJEXT) gcrypt/rsa.$(OBJEXT) +am_tincd_OBJECTS = buffer.$(OBJEXT) conf.$(OBJEXT) \ + connection.$(OBJEXT) control.$(OBJEXT) dropin.$(OBJEXT) \ + dummy_device.$(OBJEXT) edge.$(OBJEXT) event.$(OBJEXT) \ fake-getaddrinfo.$(OBJEXT) fake-getnameinfo.$(OBJEXT) \ - hash.$(OBJEXT) buffer.$(OBJEXT) conf.$(OBJEXT) \ - connection.$(OBJEXT) control.$(OBJEXT) edge.$(OBJEXT) \ - graph.$(OBJEXT) logger.$(OBJEXT) meta.$(OBJEXT) net.$(OBJEXT) \ + getopt.$(OBJEXT) getopt1.$(OBJEXT) graph.$(OBJEXT) \ + hash.$(OBJEXT) list.$(OBJEXT) logger.$(OBJEXT) meta.$(OBJEXT) \ + multicast_device.$(OBJEXT) names.$(OBJEXT) net.$(OBJEXT) \ net_packet.$(OBJEXT) net_setup.$(OBJEXT) net_socket.$(OBJEXT) \ netutl.$(OBJEXT) node.$(OBJEXT) process.$(OBJEXT) \ protocol.$(OBJEXT) protocol_auth.$(OBJEXT) \ - protocol_edge.$(OBJEXT) protocol_misc.$(OBJEXT) \ - protocol_key.$(OBJEXT) protocol_subnet.$(OBJEXT) \ - route.$(OBJEXT) sptps.$(OBJEXT) subnet.$(OBJEXT) \ - subnet_parse.$(OBJEXT) event.$(OBJEXT) tincd.$(OBJEXT) \ - dummy_device.$(OBJEXT) raw_socket_device.$(OBJEXT) \ - multicast_device.$(OBJEXT) names.$(OBJEXT) $(am__objects_1) \ - $(am__objects_2) $(am__objects_3) -nodist_tincd_OBJECTS = device.$(OBJEXT) cipher.$(OBJEXT) \ - crypto.$(OBJEXT) ecdh.$(OBJEXT) ecdsa.$(OBJEXT) \ - digest.$(OBJEXT) prf.$(OBJEXT) rsa.$(OBJEXT) -tincd_OBJECTS = $(am_tincd_OBJECTS) $(nodist_tincd_OBJECTS) + protocol_edge.$(OBJEXT) protocol_key.$(OBJEXT) \ + protocol_misc.$(OBJEXT) protocol_subnet.$(OBJEXT) \ + raw_socket_device.$(OBJEXT) route.$(OBJEXT) \ + splay_tree.$(OBJEXT) sptps.$(OBJEXT) subnet.$(OBJEXT) \ + subnet_parse.$(OBJEXT) tincd.$(OBJEXT) utils.$(OBJEXT) \ + $(am__objects_5) $(am__objects_6) $(am__objects_7) \ + $(am__objects_8) $(am__objects_9) $(am__objects_10) \ + $(am__objects_11) $(am__objects_12) $(am__objects_13) \ + $(am__objects_14) +tincd_OBJECTS = $(am_tincd_OBJECTS) tincd_LDADD = $(LDADD) +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ -SOURCES = $(sptps_test_SOURCES) $(tinc_SOURCES) $(nodist_tinc_SOURCES) \ - $(tincd_SOURCES) $(nodist_tincd_SOURCES) -DIST_SOURCES = $(sptps_test_SOURCES) $(tinc_SOURCES) \ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(sptps_test_SOURCES) $(tinc_SOURCES) $(tincd_SOURCES) +DIST_SOURCES = $(am__sptps_test_SOURCES_DIST) $(am__tinc_SOURCES_DIST) \ $(am__tincd_SOURCES_DIST) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac -HEADERS = $(nodist_noinst_HEADERS) $(noinst_HEADERS) +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ @@ -162,7 +343,6 @@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ GREP = @GREP@ -INCLUDES = @INCLUDES@ -I$(top_builddir) INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ @@ -173,10 +353,9 @@ LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ LIBOBJS = @LIBOBJS@ -LIBS = @LIBS@ @LIBGCRYPT_LIBS@ $(am__append_4) +LIBS = @LIBS@ @LIBGCRYPT_LIBS@ $(am__append_15) LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ -MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ OBJEXT = @OBJEXT@ @@ -245,45 +424,40 @@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ EXTRA_DIST = linux bsd solaris cygwin mingw openssl gcrypt -tincd_SOURCES = utils.c getopt.c getopt1.c list.c splay_tree.c \ - dropin.c fake-getaddrinfo.c fake-getnameinfo.c hash.c buffer.c \ - conf.c connection.c control.c edge.c graph.c logger.c meta.c \ - net.c net_packet.c net_setup.c net_socket.c netutl.c node.c \ - process.c protocol.c protocol_auth.c protocol_edge.c \ - protocol_misc.c protocol_key.c protocol_subnet.c route.c \ - sptps.c subnet.c subnet_parse.c event.c tincd.c dummy_device.c \ - raw_socket_device.c multicast_device.c names.c $(am__append_1) \ - $(am__append_2) $(am__append_3) -nodist_tincd_SOURCES = \ - device.c cipher.c crypto.c ecdh.c ecdsa.c digest.c prf.c rsa.c - -tinc_SOURCES = \ - utils.c getopt.c getopt1.c dropin.c \ - info.c list.c subnet_parse.c tincctl.c top.c names.c - -nodist_tinc_SOURCES = \ - ecdsagen.c rsagen.c - -sptps_test_SOURCES = \ - logger.c cipher.c crypto.c ecdh.c ecdsa.c digest.c prf.c \ - sptps.c sptps_test.c utils.c - -tinc_LDADD = $(READLINE_LIBS) $(CURSES_LIBS) DEFAULT_INCLUDES = -noinst_HEADERS = \ - xalloc.h utils.h getopt.h list.h splay_tree.h dropin.h fake-getaddrinfo.h fake-getnameinfo.h fake-gai-errnos.h ipv6.h ipv4.h ethernet.h \ - buffer.h conf.h connection.h control.h control_common.h device.h edge.h graph.h info.h logger.h meta.h net.h netutl.h node.h process.h \ - protocol.h route.h subnet.h sptps.h tincctl.h top.h bsd/tunemu.h hash.h event.h names.h - -nodist_noinst_HEADERS = \ - cipher.h crypto.h ecdh.h ecdsa.h digest.h prf.h rsa.h ecdsagen.h rsagen.h - +tincd_SOURCES = buffer.c buffer.h cipher.h conf.c conf.h connection.c \ + connection.h control.c control.h control_common.h crypto.h \ + device.h digest.h dropin.c dropin.h dummy_device.c ecdh.h \ + ecdsa.h ecdsagen.h edge.c edge.h ethernet.h event.c event.h \ + fake-gai-errnos.h fake-getaddrinfo.c fake-getaddrinfo.h \ + fake-getnameinfo.c fake-getnameinfo.h getopt.c getopt.h \ + getopt1.c graph.c graph.h hash.c hash.h have.h ipv4.h ipv6.h \ + list.c list.h logger.c logger.h meta.c meta.h \ + multicast_device.c names.c names.h net.c net.h net_packet.c \ + net_setup.c net_socket.c netutl.c netutl.h node.c node.h prf.h \ + process.c process.h protocol.c protocol.h protocol_auth.c \ + protocol_edge.c protocol_key.c protocol_misc.c \ + protocol_subnet.c raw_socket_device.c route.c route.h rsa.h \ + rsagen.h splay_tree.c splay_tree.h sptps.c sptps.h subnet.c \ + subnet.h subnet_parse.c system.h tincd.c utils.c utils.h \ + xalloc.h $(am__append_1) $(am__append_2) $(am__append_3) \ + $(am__append_4) $(am__append_5) $(am__append_6) \ + $(am__append_7) $(am__append_8) $(am__append_9) \ + $(am__append_12) +tinc_SOURCES = dropin.c dropin.h getopt.c getopt.h getopt1.c info.c \ + info.h invitation.c invitation.h list.c list.h names.c names.h \ + netutl.c netutl.h sptps.c sptps.h subnet_parse.c subnet.h \ + tincctl.c tincctl.h top.c top.h utils.c utils.h \ + $(am__append_10) $(am__append_13) +sptps_test_SOURCES = logger.c logger.h sptps.c sptps.h sptps_test.c \ + utils.c utils.h $(am__append_11) $(am__append_14) +tinc_LDADD = $(READLINE_LIBS) $(CURSES_LIBS) AM_CFLAGS = -DCONFDIR=\"$(sysconfdir)\" -DLOCALSTATEDIR=\"$(localstatedir)\" -DSBINDIR=\"$(sbindir)\" all: all-am .SUFFIXES: .SUFFIXES: .c .o .obj -$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ @@ -308,9 +482,9 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) +$(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) +$(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-sbinPROGRAMS: $(sbin_PROGRAMS) @@ -322,10 +496,11 @@ install-sbinPROGRAMS: $(sbin_PROGRAMS) fi; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ - while read p p1; do if test -f $$p; \ - then echo "$$p"; echo "$$p"; else :; fi; \ + while read p p1; do if test -f $$p \ + ; then echo "$$p"; echo "$$p"; else :; fi; \ done | \ - sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \ + sed -e 'p;s,.*/,,;n;h' \ + -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ @@ -346,42 +521,152 @@ uninstall-sbinPROGRAMS: @list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ - -e 's/$$/$(EXEEXT)/' `; \ + -e 's/$$/$(EXEEXT)/' \ + `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(sbindir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(sbindir)" && rm -f $$files clean-sbinPROGRAMS: -test -z "$(sbin_PROGRAMS)" || rm -f $(sbin_PROGRAMS) + +installcheck-sbinPROGRAMS: $(sbin_PROGRAMS) + bad=0; pid=$$$$; list="$(sbin_PROGRAMS)"; for p in $$list; do \ + case ' $(AM_INSTALLCHECK_STD_OPTIONS_EXEMPT) ' in \ + *" $$p "* | *" $(srcdir)/$$p "*) continue;; \ + esac; \ + f=`echo "$$p" | \ + sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \ + for opt in --help --version; do \ + if "$(DESTDIR)$(sbindir)/$$f" $$opt >c$${pid}_.out \ + 2>c$${pid}_.err &2; bad=1; fi; \ + done; \ + done; rm -f c$${pid}_.???; exit $$bad +openssl/$(am__dirstamp): + @$(MKDIR_P) openssl + @: > openssl/$(am__dirstamp) +openssl/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) openssl/$(DEPDIR) + @: > openssl/$(DEPDIR)/$(am__dirstamp) +openssl/cipher.$(OBJEXT): openssl/$(am__dirstamp) \ + openssl/$(DEPDIR)/$(am__dirstamp) +openssl/crypto.$(OBJEXT): openssl/$(am__dirstamp) \ + openssl/$(DEPDIR)/$(am__dirstamp) +openssl/digest.$(OBJEXT): openssl/$(am__dirstamp) \ + openssl/$(DEPDIR)/$(am__dirstamp) +openssl/ecdh.$(OBJEXT): openssl/$(am__dirstamp) \ + openssl/$(DEPDIR)/$(am__dirstamp) +openssl/ecdsa.$(OBJEXT): openssl/$(am__dirstamp) \ + openssl/$(DEPDIR)/$(am__dirstamp) +openssl/prf.$(OBJEXT): openssl/$(am__dirstamp) \ + openssl/$(DEPDIR)/$(am__dirstamp) +gcrypt/$(am__dirstamp): + @$(MKDIR_P) gcrypt + @: > gcrypt/$(am__dirstamp) +gcrypt/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) gcrypt/$(DEPDIR) + @: > gcrypt/$(DEPDIR)/$(am__dirstamp) +gcrypt/cipher.$(OBJEXT): gcrypt/$(am__dirstamp) \ + gcrypt/$(DEPDIR)/$(am__dirstamp) +gcrypt/crypto.$(OBJEXT): gcrypt/$(am__dirstamp) \ + gcrypt/$(DEPDIR)/$(am__dirstamp) +gcrypt/digest.$(OBJEXT): gcrypt/$(am__dirstamp) \ + gcrypt/$(DEPDIR)/$(am__dirstamp) +gcrypt/ecdh.$(OBJEXT): gcrypt/$(am__dirstamp) \ + gcrypt/$(DEPDIR)/$(am__dirstamp) +gcrypt/ecdsa.$(OBJEXT): gcrypt/$(am__dirstamp) \ + gcrypt/$(DEPDIR)/$(am__dirstamp) +gcrypt/prf.$(OBJEXT): gcrypt/$(am__dirstamp) \ + gcrypt/$(DEPDIR)/$(am__dirstamp) + sptps_test$(EXEEXT): $(sptps_test_OBJECTS) $(sptps_test_DEPENDENCIES) $(EXTRA_sptps_test_DEPENDENCIES) @rm -f sptps_test$(EXEEXT) - $(LINK) $(sptps_test_OBJECTS) $(sptps_test_LDADD) $(LIBS) + $(AM_V_CCLD)$(LINK) $(sptps_test_OBJECTS) $(sptps_test_LDADD) $(LIBS) +openssl/ecdsagen.$(OBJEXT): openssl/$(am__dirstamp) \ + openssl/$(DEPDIR)/$(am__dirstamp) +openssl/rsa.$(OBJEXT): openssl/$(am__dirstamp) \ + openssl/$(DEPDIR)/$(am__dirstamp) +openssl/rsagen.$(OBJEXT): openssl/$(am__dirstamp) \ + openssl/$(DEPDIR)/$(am__dirstamp) +gcrypt/ecdsagen.$(OBJEXT): gcrypt/$(am__dirstamp) \ + gcrypt/$(DEPDIR)/$(am__dirstamp) +gcrypt/rsa.$(OBJEXT): gcrypt/$(am__dirstamp) \ + gcrypt/$(DEPDIR)/$(am__dirstamp) +gcrypt/rsagen.$(OBJEXT): gcrypt/$(am__dirstamp) \ + gcrypt/$(DEPDIR)/$(am__dirstamp) + tinc$(EXEEXT): $(tinc_OBJECTS) $(tinc_DEPENDENCIES) $(EXTRA_tinc_DEPENDENCIES) @rm -f tinc$(EXEEXT) - $(LINK) $(tinc_OBJECTS) $(tinc_LDADD) $(LIBS) + $(AM_V_CCLD)$(LINK) $(tinc_OBJECTS) $(tinc_LDADD) $(LIBS) +linux/$(am__dirstamp): + @$(MKDIR_P) linux + @: > linux/$(am__dirstamp) +linux/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) linux/$(DEPDIR) + @: > linux/$(DEPDIR)/$(am__dirstamp) +linux/device.$(OBJEXT): linux/$(am__dirstamp) \ + linux/$(DEPDIR)/$(am__dirstamp) +bsd/$(am__dirstamp): + @$(MKDIR_P) bsd + @: > bsd/$(am__dirstamp) +bsd/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) bsd/$(DEPDIR) + @: > bsd/$(DEPDIR)/$(am__dirstamp) +bsd/device.$(OBJEXT): bsd/$(am__dirstamp) \ + bsd/$(DEPDIR)/$(am__dirstamp) +bsd/tunemu.$(OBJEXT): bsd/$(am__dirstamp) \ + bsd/$(DEPDIR)/$(am__dirstamp) +solaris/$(am__dirstamp): + @$(MKDIR_P) solaris + @: > solaris/$(am__dirstamp) +solaris/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) solaris/$(DEPDIR) + @: > solaris/$(DEPDIR)/$(am__dirstamp) +solaris/device.$(OBJEXT): solaris/$(am__dirstamp) \ + solaris/$(DEPDIR)/$(am__dirstamp) +mingw/$(am__dirstamp): + @$(MKDIR_P) mingw + @: > mingw/$(am__dirstamp) +mingw/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) mingw/$(DEPDIR) + @: > mingw/$(DEPDIR)/$(am__dirstamp) +mingw/device.$(OBJEXT): mingw/$(am__dirstamp) \ + mingw/$(DEPDIR)/$(am__dirstamp) +cygwin/$(am__dirstamp): + @$(MKDIR_P) cygwin + @: > cygwin/$(am__dirstamp) +cygwin/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) cygwin/$(DEPDIR) + @: > cygwin/$(DEPDIR)/$(am__dirstamp) +cygwin/device.$(OBJEXT): cygwin/$(am__dirstamp) \ + cygwin/$(DEPDIR)/$(am__dirstamp) + tincd$(EXEEXT): $(tincd_OBJECTS) $(tincd_DEPENDENCIES) $(EXTRA_tincd_DEPENDENCIES) @rm -f tincd$(EXEEXT) - $(LINK) $(tincd_OBJECTS) $(tincd_LDADD) $(LIBS) + $(AM_V_CCLD)$(LINK) $(tincd_OBJECTS) $(tincd_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) + -rm -f bsd/*.$(OBJEXT) + -rm -f cygwin/*.$(OBJEXT) + -rm -f gcrypt/*.$(OBJEXT) + -rm -f linux/*.$(OBJEXT) + -rm -f mingw/*.$(OBJEXT) + -rm -f openssl/*.$(OBJEXT) + -rm -f solaris/*.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/buffer.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cipher.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/conf.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/connection.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/control.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/crypto.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/device.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/digest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dropin.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dummy_device.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ecdh.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ecdsa.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ecdsagen.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/edge.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/event.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fake-getaddrinfo.Po@am__quote@ @@ -391,6 +676,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/graph.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hash.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/info.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/invitation.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/list.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/logger.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/meta.Po@am__quote@ @@ -402,7 +688,6 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/net_socket.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/netutl.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/node.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/prf.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/process.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protocol.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protocol_auth.Po@am__quote@ @@ -412,8 +697,6 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protocol_subnet.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/raw_socket_device.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/route.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rsa.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rsagen.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/splay_tree.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sptps.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sptps_test.Po@am__quote@ @@ -422,59 +705,59 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tincctl.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tincd.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/top.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tunemu.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uml_device.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/utils.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vde_device.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@bsd/$(DEPDIR)/device.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@bsd/$(DEPDIR)/tunemu.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@cygwin/$(DEPDIR)/device.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@gcrypt/$(DEPDIR)/cipher.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@gcrypt/$(DEPDIR)/crypto.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@gcrypt/$(DEPDIR)/digest.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@gcrypt/$(DEPDIR)/ecdh.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@gcrypt/$(DEPDIR)/ecdsa.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@gcrypt/$(DEPDIR)/ecdsagen.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@gcrypt/$(DEPDIR)/prf.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@gcrypt/$(DEPDIR)/rsa.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@gcrypt/$(DEPDIR)/rsagen.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@linux/$(DEPDIR)/device.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@mingw/$(DEPDIR)/device.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@openssl/$(DEPDIR)/cipher.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@openssl/$(DEPDIR)/crypto.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@openssl/$(DEPDIR)/digest.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@openssl/$(DEPDIR)/ecdh.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@openssl/$(DEPDIR)/ecdsa.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@openssl/$(DEPDIR)/ecdsagen.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@openssl/$(DEPDIR)/prf.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@openssl/$(DEPDIR)/rsa.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@openssl/$(DEPDIR)/rsagen.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@solaris/$(DEPDIR)/device.Po@am__quote@ .c.o: -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(COMPILE) -c $< +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` -tunemu.o: bsd/tunemu.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tunemu.o -MD -MP -MF $(DEPDIR)/tunemu.Tpo -c -o tunemu.o `test -f 'bsd/tunemu.c' || echo '$(srcdir)/'`bsd/tunemu.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/tunemu.Tpo $(DEPDIR)/tunemu.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='bsd/tunemu.c' object='tunemu.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tunemu.o `test -f 'bsd/tunemu.c' || echo '$(srcdir)/'`bsd/tunemu.c +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags -tunemu.obj: bsd/tunemu.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tunemu.obj -MD -MP -MF $(DEPDIR)/tunemu.Tpo -c -o tunemu.obj `if test -f 'bsd/tunemu.c'; then $(CYGPATH_W) 'bsd/tunemu.c'; else $(CYGPATH_W) '$(srcdir)/bsd/tunemu.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/tunemu.Tpo $(DEPDIR)/tunemu.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='bsd/tunemu.c' object='tunemu.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tunemu.obj `if test -f 'bsd/tunemu.c'; then $(CYGPATH_W) 'bsd/tunemu.c'; else $(CYGPATH_W) '$(srcdir)/bsd/tunemu.c'; fi` - -ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ - mkid -fID $$unique -tags: TAGS - -TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ + $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ @@ -486,15 +769,11 @@ TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $$unique; \ fi; \ fi -ctags: CTAGS -CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique @@ -503,6 +782,21 @@ GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags @@ -542,7 +836,7 @@ distdir: $(DISTFILES) dist-hook check-am: all-am check: check-am -all-am: Makefile $(PROGRAMS) $(HEADERS) +all-am: Makefile $(PROGRAMS) installdirs: for dir in "$(DESTDIR)$(sbindir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ @@ -573,6 +867,20 @@ clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + -rm -f bsd/$(DEPDIR)/$(am__dirstamp) + -rm -f bsd/$(am__dirstamp) + -rm -f cygwin/$(DEPDIR)/$(am__dirstamp) + -rm -f cygwin/$(am__dirstamp) + -rm -f gcrypt/$(DEPDIR)/$(am__dirstamp) + -rm -f gcrypt/$(am__dirstamp) + -rm -f linux/$(DEPDIR)/$(am__dirstamp) + -rm -f linux/$(am__dirstamp) + -rm -f mingw/$(DEPDIR)/$(am__dirstamp) + -rm -f mingw/$(am__dirstamp) + -rm -f openssl/$(DEPDIR)/$(am__dirstamp) + -rm -f openssl/$(am__dirstamp) + -rm -f solaris/$(DEPDIR)/$(am__dirstamp) + -rm -f solaris/$(am__dirstamp) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @@ -582,7 +890,7 @@ clean: clean-am clean-am: clean-generic clean-sbinPROGRAMS mostlyclean-am distclean: distclean-am - -rm -rf ./$(DEPDIR) + -rm -rf ./$(DEPDIR) bsd/$(DEPDIR) cygwin/$(DEPDIR) gcrypt/$(DEPDIR) linux/$(DEPDIR) mingw/$(DEPDIR) openssl/$(DEPDIR) solaris/$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags @@ -625,10 +933,10 @@ install-ps: install-ps-am install-ps-am: -installcheck-am: +installcheck-am: installcheck-sbinPROGRAMS maintainer-clean: maintainer-clean-am - -rm -rf ./$(DEPDIR) + -rm -rf ./$(DEPDIR) bsd/$(DEPDIR) cygwin/$(DEPDIR) gcrypt/$(DEPDIR) linux/$(DEPDIR) mingw/$(DEPDIR) openssl/$(DEPDIR) solaris/$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic @@ -648,18 +956,19 @@ uninstall-am: uninstall-sbinPROGRAMS .MAKE: install-am install-strip -.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ - clean-sbinPROGRAMS ctags dist-hook distclean distclean-compile \ - distclean-generic distclean-tags distdir dvi dvi-am html \ - html-am info info-am install install-am install-data \ - install-data-am install-dvi install-dvi-am install-exec \ - install-exec-am install-html install-html-am install-info \ - install-info-am install-man install-pdf install-pdf-am \ - install-ps install-ps-am install-sbinPROGRAMS install-strip \ - installcheck installcheck-am installdirs maintainer-clean \ - maintainer-clean-generic mostlyclean mostlyclean-compile \ - mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \ - uninstall-am uninstall-sbinPROGRAMS +.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ + clean-sbinPROGRAMS cscopelist-am ctags ctags-am dist-hook \ + distclean distclean-compile distclean-generic distclean-tags \ + distdir dvi dvi-am html html-am info info-am install \ + install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-sbinPROGRAMS install-strip installcheck \ + installcheck-am installcheck-sbinPROGRAMS installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic pdf pdf-am ps ps-am \ + tags tags-am uninstall uninstall-am uninstall-sbinPROGRAMS dist-hook: diff --git a/src/bsd/.deps/device.Po b/src/bsd/.deps/device.Po new file mode 100644 index 0000000..9ce06a8 --- /dev/null +++ b/src/bsd/.deps/device.Po @@ -0,0 +1 @@ +# dummy diff --git a/src/bsd/.deps/tunemu.Po b/src/bsd/.deps/tunemu.Po new file mode 100644 index 0000000..9ce06a8 --- /dev/null +++ b/src/bsd/.deps/tunemu.Po @@ -0,0 +1 @@ +# dummy diff --git a/src/bsd/device.c b/src/bsd/device.c index 9bf0cd5..e083519 100644 --- a/src/bsd/device.c +++ b/src/bsd/device.c @@ -19,16 +19,16 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#include "system.h" +#include "../system.h" -#include "conf.h" -#include "device.h" -#include "logger.h" -#include "names.h" -#include "net.h" -#include "route.h" -#include "utils.h" -#include "xalloc.h" +#include "../conf.h" +#include "../device.h" +#include "../logger.h" +#include "../names.h" +#include "../net.h" +#include "../route.h" +#include "../utils.h" +#include "../xalloc.h" #ifdef ENABLE_TUNEMU #include "bsd/tunemu.h" diff --git a/src/bsd/device.c.orig b/src/bsd/device.c.orig deleted file mode 100644 index a204040..0000000 --- a/src/bsd/device.c.orig +++ /dev/null @@ -1,386 +0,0 @@ -/* - device.c -- Interaction BSD tun/tap device - Copyright (C) 2001-2005 Ivo Timmermans, - 2001-2012 Guus Sliepen - 2009 Grzegorz Dymarek - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include "system.h" - -#include "conf.h" -#include "device.h" -#include "logger.h" -#include "net.h" -#include "route.h" -#include "utils.h" -#include "xalloc.h" - -#ifdef ENABLE_TUNEMU -#include "bsd/tunemu.h" -#endif - -#define DEFAULT_TUN_DEVICE "/dev/tun0" -#if defined(HAVE_FREEBSD) || defined(HAVE_NETBSD) -#define DEFAULT_TAP_DEVICE "/dev/tap0" -#else -#define DEFAULT_TAP_DEVICE "/dev/tun0" -#endif - -typedef enum device_type { - DEVICE_TYPE_TUN, - DEVICE_TYPE_TUNIFHEAD, - DEVICE_TYPE_TAP, -#ifdef ENABLE_TUNEMU - DEVICE_TYPE_TUNEMU, -#endif -} device_type_t; - -int device_fd = -1; -char *device = NULL; -char *iface = NULL; -static char *device_info = NULL; -static uint64_t device_total_in = 0; -static uint64_t device_total_out = 0; -#if defined(ENABLE_TUNEMU) -static device_type_t device_type = DEVICE_TYPE_TUNEMU; -#elif defined(HAVE_OPENBSD) || defined(HAVE_FREEBSD) || defined(HAVE_DRAGONFLY) -static device_type_t device_type = DEVICE_TYPE_TUNIFHEAD; -#else -static device_type_t device_type = DEVICE_TYPE_TUN; -#endif - -static bool setup_device(void) { - char *type; - - if(!get_config_string(lookup_config(config_tree, "Device"), &device)) { - if(routing_mode == RMODE_ROUTER) - device = xstrdup(DEFAULT_TUN_DEVICE); - else - device = xstrdup(DEFAULT_TAP_DEVICE); - } - - if(!get_config_string(lookup_config(config_tree, "Interface"), &iface)) - iface = xstrdup(strrchr(device, '/') ? strrchr(device, '/') + 1 : device); - - if(get_config_string(lookup_config(config_tree, "DeviceType"), &type)) { - if(!strcasecmp(type, "tun")) -<<<<<<< HEAD - /* use default */; -#ifdef HAVE_TUNEMU -======= - /* use default */; -#ifdef ENABLE_TUNEMU ->>>>>>> 2a3e343... Fix support for tunemu on iOS devices. - else if(!strcasecmp(type, "tunemu")) - device_type = DEVICE_TYPE_TUNEMU; -#endif - else if(!strcasecmp(type, "tunnohead")) - device_type = DEVICE_TYPE_TUN; - else if(!strcasecmp(type, "tunifhead")) - device_type = DEVICE_TYPE_TUNIFHEAD; - else if(!strcasecmp(type, "tap")) - device_type = DEVICE_TYPE_TAP; - else { - logger(DEBUG_ALWAYS, LOG_ERR, "Unknown device type %s!", type); - return false; - } - } else { - if(strstr(device, "tap") || routing_mode != RMODE_ROUTER) - device_type = DEVICE_TYPE_TAP; - } - - switch(device_type) { -#ifdef ENABLE_TUNEMU - case DEVICE_TYPE_TUNEMU: { - char dynamic_name[256] = ""; - device_fd = tunemu_open(dynamic_name); - } - break; -#endif - default: - device_fd = open(device, O_RDWR | O_NONBLOCK); - } - - if(device_fd < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not open %s: %s", device, strerror(errno)); - return false; - } - -#ifdef FD_CLOEXEC - fcntl(device_fd, F_SETFD, FD_CLOEXEC); -#endif - - switch(device_type) { - default: - device_type = DEVICE_TYPE_TUN; - case DEVICE_TYPE_TUN: -#ifdef TUNSIFHEAD - { - const int zero = 0; - if(ioctl(device_fd, TUNSIFHEAD, &zero, sizeof zero) == -1) { - logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "ioctl", strerror(errno)); - return false; - } - } -#endif -#if defined(TUNSIFMODE) && defined(IFF_BROADCAST) && defined(IFF_MULTICAST) - { - const int mode = IFF_BROADCAST | IFF_MULTICAST; - ioctl(device_fd, TUNSIFMODE, &mode, sizeof mode); - } -#endif - - device_info = "Generic BSD tun device"; - break; - case DEVICE_TYPE_TUNIFHEAD: -#ifdef TUNSIFHEAD - { - const int one = 1; - if(ioctl(device_fd, TUNSIFHEAD, &one, sizeof one) == -1) { - logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "ioctl", strerror(errno)); - return false; - } - } -#endif -#if defined(TUNSIFMODE) && defined(IFF_BROADCAST) && defined(IFF_MULTICAST) - { - const int mode = IFF_BROADCAST | IFF_MULTICAST; - ioctl(device_fd, TUNSIFMODE, &mode, sizeof mode); - } -#endif - - device_info = "Generic BSD tun device"; - break; - case DEVICE_TYPE_TAP: - if(routing_mode == RMODE_ROUTER) - overwrite_mac = true; - device_info = "Generic BSD tap device"; -#ifdef TAPGIFNAME - { - struct ifreq ifr; - if(ioctl(device_fd, TAPGIFNAME, (void*)&ifr) == 0) { - if(iface) - free(iface); - iface = xstrdup(ifr.ifr_name); - } - } - -#endif - break; -#ifdef ENABLE_TUNEMU - case DEVICE_TYPE_TUNEMU: - device_info = "BSD tunemu device"; - break; -#endif - } - - logger(DEBUG_ALWAYS, LOG_INFO, "%s is a %s", device, device_info); - - return true; -} - -static void close_device(void) { - switch(device_type) { -#ifdef ENABLE_TUNEMU - case DEVICE_TYPE_TUNEMU: - tunemu_close(device_fd); - break; -#endif - default: - close(device_fd); - } - - free(device); - free(iface); -} - -static bool read_packet(vpn_packet_t *packet) { - int inlen; - - switch(device_type) { - case DEVICE_TYPE_TUN: -#ifdef ENABLE_TUNEMU - case DEVICE_TYPE_TUNEMU: - if(device_type == DEVICE_TYPE_TUNEMU) - inlen = tunemu_read(device_fd, packet->data + 14, MTU - 14); - else -#endif - inlen = read(device_fd, packet->data + 14, MTU - 14); - - if(inlen <= 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info, - device, strerror(errno)); - return false; - } - - switch(packet->data[14] >> 4) { - case 4: - packet->data[12] = 0x08; - packet->data[13] = 0x00; - break; - case 6: - packet->data[12] = 0x86; - packet->data[13] = 0xDD; - break; - default: - logger(DEBUG_TRAFFIC, LOG_ERR, - "Unknown IP version %d while reading packet from %s %s", - packet->data[14] >> 4, device_info, device); - return false; - } - - memset(packet->data, 0, 12); - packet->len = inlen + 14; - break; - - case DEVICE_TYPE_TUNIFHEAD: { - u_int32_t type; - struct iovec vector[2] = {{&type, sizeof type}, {packet->data + 14, MTU - 14}}; - - if((inlen = readv(device_fd, vector, 2)) <= 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info, - device, strerror(errno)); - return false; - } - - switch (ntohl(type)) { - case AF_INET: - packet->data[12] = 0x08; - packet->data[13] = 0x00; - break; - - case AF_INET6: - packet->data[12] = 0x86; - packet->data[13] = 0xDD; - break; - - default: - logger(DEBUG_TRAFFIC, LOG_ERR, - "Unknown address family %x while reading packet from %s %s", - ntohl(type), device_info, device); - return false; - } - - memset(packet->data, 0, 12); - packet->len = inlen + 10; - break; - } - - case DEVICE_TYPE_TAP: - if((inlen = read(device_fd, packet->data, MTU)) <= 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info, - device, strerror(errno)); - return false; - } - - packet->len = inlen; - break; - - default: - return false; - } - - device_total_in += packet->len; - - logger(DEBUG_TRAFFIC, LOG_DEBUG, "Read packet of %d bytes from %s", - packet->len, device_info); - - return true; -} - -static bool write_packet(vpn_packet_t *packet) { - logger(DEBUG_TRAFFIC, LOG_DEBUG, "Writing packet of %d bytes to %s", - packet->len, device_info); - - switch(device_type) { - case DEVICE_TYPE_TUN: - if(write(device_fd, packet->data + 14, packet->len - 14) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error while writing to %s %s: %s", device_info, - device, strerror(errno)); - return false; - } - break; - - case DEVICE_TYPE_TUNIFHEAD: { - u_int32_t type; - struct iovec vector[2] = {{&type, sizeof type}, {packet->data + 14, packet->len - 14}}; - int af; - - af = (packet->data[12] << 8) + packet->data[13]; - - switch (af) { - case 0x0800: - type = htonl(AF_INET); - break; - case 0x86DD: - type = htonl(AF_INET6); - break; - default: - logger(DEBUG_TRAFFIC, LOG_ERR, - "Unknown address family %x while writing packet to %s %s", - af, device_info, device); - return false; - } - - if(writev(device_fd, vector, 2) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Can't write to %s %s: %s", device_info, device, - strerror(errno)); - return false; - } - break; - } - - case DEVICE_TYPE_TAP: - if(write(device_fd, packet->data, packet->len) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error while writing to %s %s: %s", device_info, - device, strerror(errno)); - return false; - } - break; - -#ifdef ENABLE_TUNEMU - case DEVICE_TYPE_TUNEMU: - if(tunemu_write(device_fd, packet->data + 14, packet->len - 14) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error while writing to %s %s: %s", device_info, - device, strerror(errno)); - return false; - } - break; -#endif - - default: - return false; - } - - device_total_out += packet->len; - - return true; -} - -static void dump_device_stats(void) { - logger(DEBUG_ALWAYS, LOG_DEBUG, "Statistics for %s %s:", device_info, device); - logger(DEBUG_ALWAYS, LOG_DEBUG, " total bytes in: %10"PRIu64, device_total_in); - logger(DEBUG_ALWAYS, LOG_DEBUG, " total bytes out: %10"PRIu64, device_total_out); -} - -const devops_t os_devops = { - .setup = setup_device, - .close = close_device, - .read = read_packet, - .write = write_packet, - .dump_stats = dump_device_stats, -}; diff --git a/src/cipher.c b/src/cipher.c deleted file mode 100644 index 553b4ad..0000000 --- a/src/cipher.c +++ /dev/null @@ -1,218 +0,0 @@ -/* - cipher.c -- Symmetric block cipher handling - Copyright (C) 2007-2012 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 - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include "system.h" - -#include -#include - -#include "cipher.h" -#include "logger.h" -#include "xalloc.h" - -typedef struct cipher_counter { - unsigned char counter[EVP_MAX_IV_LENGTH]; - unsigned char block[EVP_MAX_IV_LENGTH]; - int n; -} cipher_counter_t; - -static bool cipher_open(cipher_t *cipher) { - EVP_CIPHER_CTX_init(&cipher->ctx); - - return true; -} - -bool cipher_open_by_name(cipher_t *cipher, const char *name) { - cipher->cipher = EVP_get_cipherbyname(name); - - if(cipher->cipher) - return cipher_open(cipher); - - logger(DEBUG_ALWAYS, LOG_ERR, "Unknown cipher name '%s'!", name); - return false; -} - -bool cipher_open_by_nid(cipher_t *cipher, int nid) { - cipher->cipher = EVP_get_cipherbynid(nid); - - if(cipher->cipher) - return cipher_open(cipher); - - logger(DEBUG_ALWAYS, LOG_ERR, "Unknown cipher nid %d!", nid); - return false; -} - -bool cipher_open_blowfish_ofb(cipher_t *cipher) { - cipher->cipher = EVP_bf_ofb(); - return cipher_open(cipher); -} - -void cipher_close(cipher_t *cipher) { - EVP_CIPHER_CTX_cleanup(&cipher->ctx); - free(cipher->counter); - cipher->counter = NULL; -} - -size_t cipher_keylength(const cipher_t *cipher) { - return cipher->cipher->key_len + cipher->cipher->block_size; -} - -bool cipher_set_key(cipher_t *cipher, void *key, bool encrypt) { - bool result; - - if(encrypt) - result = EVP_EncryptInit_ex(&cipher->ctx, cipher->cipher, NULL, (unsigned char *)key, (unsigned char *)key + cipher->cipher->key_len); - else - result = EVP_DecryptInit_ex(&cipher->ctx, cipher->cipher, NULL, (unsigned char *)key, (unsigned char *)key + cipher->cipher->key_len); - - if(result) - return true; - - logger(DEBUG_ALWAYS, LOG_ERR, "Error while setting key: %s", ERR_error_string(ERR_get_error(), NULL)); - return false; -} - -bool cipher_set_key_from_rsa(cipher_t *cipher, void *key, size_t len, bool encrypt) { - bool result; - - if(encrypt) - result = EVP_EncryptInit_ex(&cipher->ctx, cipher->cipher, NULL, (unsigned char *)key + len - cipher->cipher->key_len, (unsigned char *)key + len - cipher->cipher->iv_len - cipher->cipher->key_len); - else - result = EVP_DecryptInit_ex(&cipher->ctx, cipher->cipher, NULL, (unsigned char *)key + len - cipher->cipher->key_len, (unsigned char *)key + len - cipher->cipher->iv_len - cipher->cipher->key_len); - - if(result) - return true; - - logger(DEBUG_ALWAYS, LOG_ERR, "Error while setting key: %s", ERR_error_string(ERR_get_error(), NULL)); - return false; -} - -bool cipher_set_counter(cipher_t *cipher, const void *counter, size_t len) { - if(len > cipher->cipher->block_size - 4) { - logger(DEBUG_ALWAYS, LOG_ERR, "Counter too long"); - abort(); - } - - memcpy(cipher->counter->counter + cipher->cipher->block_size - len, counter, len); - memset(cipher->counter->counter, 0, 4); - cipher->counter->n = 0; - - return true; -} - -bool cipher_set_counter_key(cipher_t *cipher, void *key) { - int result = EVP_EncryptInit_ex(&cipher->ctx, cipher->cipher, NULL, (unsigned char *)key, NULL); - if(!result) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error while setting key: %s", ERR_error_string(ERR_get_error(), NULL)); - return false; - } - - if(!cipher->counter) - cipher->counter = xmalloc_and_zero(sizeof *cipher->counter); - else - cipher->counter->n = 0; - - memcpy(cipher->counter->counter, (unsigned char *)key + cipher->cipher->key_len, cipher->cipher->block_size); - - return true; -} - -bool cipher_counter_xor(cipher_t *cipher, const void *indata, size_t inlen, void *outdata) { - if(!cipher->counter) { - logger(DEBUG_ALWAYS, LOG_ERR, "Counter not initialized"); - return false; - } - - const unsigned char *in = indata; - unsigned char *out = outdata; - - while(inlen--) { - // Encrypt the new counter value if we need it - if(!cipher->counter->n) { - int len; - if(!EVP_EncryptUpdate(&cipher->ctx, cipher->counter->block, &len, cipher->counter->counter, cipher->cipher->block_size)) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error while encrypting: %s", ERR_error_string(ERR_get_error(), NULL)); - return false; - } - - // Increase the counter value - for(int i = 0; i < cipher->cipher->block_size; i++) - if(++cipher->counter->counter[i]) - break; - } - - *out++ = *in++ ^ cipher->counter->counter[cipher->counter->n++]; - - if(cipher->counter->n >= cipher->cipher->block_size) - cipher->counter->n = 0; - } - - return true; -} - - -bool cipher_encrypt(cipher_t *cipher, const void *indata, size_t inlen, void *outdata, size_t *outlen, bool oneshot) { - if(oneshot) { - int len, pad; - if(EVP_EncryptInit_ex(&cipher->ctx, NULL, NULL, NULL, NULL) - && EVP_EncryptUpdate(&cipher->ctx, (unsigned char *)outdata, &len, indata, inlen) - && EVP_EncryptFinal(&cipher->ctx, (unsigned char *)outdata + len, &pad)) { - if(outlen) *outlen = len + pad; - return true; - } - } else { - int len; - if(EVP_EncryptUpdate(&cipher->ctx, outdata, &len, indata, inlen)) { - if(outlen) *outlen = len; - return true; - } - } - - logger(DEBUG_ALWAYS, LOG_ERR, "Error while encrypting: %s", ERR_error_string(ERR_get_error(), NULL)); - return false; -} - -bool cipher_decrypt(cipher_t *cipher, const void *indata, size_t inlen, void *outdata, size_t *outlen, bool oneshot) { - if(oneshot) { - int len, pad; - if(EVP_DecryptInit_ex(&cipher->ctx, NULL, NULL, NULL, NULL) - && EVP_DecryptUpdate(&cipher->ctx, (unsigned char *)outdata, &len, indata, inlen) - && EVP_DecryptFinal(&cipher->ctx, (unsigned char *)outdata + len, &pad)) { - if(outlen) *outlen = len + pad; - return true; - } - } else { - int len; - if(EVP_EncryptUpdate(&cipher->ctx, outdata, &len, indata, inlen)) { - if(outlen) *outlen = len; - return true; - } - } - - logger(DEBUG_ALWAYS, LOG_ERR, "Error while decrypting: %s", ERR_error_string(ERR_get_error(), NULL)); - return false; -} - -int cipher_get_nid(const cipher_t *cipher) { - return cipher->cipher ? cipher->cipher->nid : 0; -} - -bool cipher_active(const cipher_t *cipher) { - return cipher->cipher && cipher->cipher->nid != 0; -} diff --git a/src/openssl/cipher.h b/src/cipher.h similarity index 56% rename from src/openssl/cipher.h rename to src/cipher.h index c9f89eb..17ca614 100644 --- a/src/openssl/cipher.h +++ b/src/cipher.h @@ -1,6 +1,6 @@ /* cipher.h -- header file cipher.c - Copyright (C) 2007-2012 Guus Sliepen + Copyright (C) 2007-2013 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 @@ -20,30 +20,25 @@ #ifndef __TINC_CIPHER_H__ #define __TINC_CIPHER_H__ -#include +#define CIPHER_MAX_BLOCK_SIZE 32 +#define CIPHER_MAX_IV_SIZE 16 +#define CIPHER_MAX_KEY_SIZE 32 -#define CIPHER_MAX_BLOCK_SIZE EVP_MAX_BLOCK_LENGTH -#define CIPHER_MAX_KEY_SIZE EVP_MAX_KEY_LENGTH -#define CIPHER_MAX_IV_SIZE EVP_MAX_IV_LENGTH +typedef struct cipher cipher_t; -typedef struct cipher { - EVP_CIPHER_CTX ctx; - const EVP_CIPHER *cipher; - struct cipher_counter *counter; -} cipher_t; - -extern bool cipher_open_by_name(cipher_t *, const char *); -extern bool cipher_open_by_nid(cipher_t *, int); -extern bool cipher_open_blowfish_ofb(cipher_t *); +extern cipher_t *cipher_open_by_name(const char *) __attribute__ ((__malloc__)); +extern cipher_t *cipher_open_by_nid(int) __attribute__ ((__malloc__)); +extern cipher_t *cipher_open_blowfish_ofb(void) __attribute__ ((__malloc__)); extern void cipher_close(cipher_t *); extern size_t cipher_keylength(const cipher_t *); -extern bool cipher_set_key(cipher_t *, void *, bool); -extern bool cipher_set_key_from_rsa(cipher_t *, void *, size_t, bool); -extern bool cipher_set_counter(cipher_t *, const void *, size_t); -extern bool cipher_set_counter_key(cipher_t *, void *); -extern bool cipher_encrypt(cipher_t *, const void *indata, size_t inlen, void *outdata, size_t *outlen, bool); -extern bool cipher_decrypt(cipher_t *, const void *indata, size_t inlen, void *outdata, size_t *outlen, bool); -extern bool cipher_counter_xor(cipher_t *, const void *indata, size_t inlen, void *outdata); +extern void cipher_get_key(const cipher_t *, void *); +extern bool cipher_set_key(cipher_t *, void *, bool) __attribute__ ((__warn_unused_result__)); +extern bool cipher_set_key_from_rsa(cipher_t *, void *, size_t, bool) __attribute__ ((__warn_unused_result__)); +extern bool cipher_set_counter(cipher_t *, const void *, size_t) __attribute__ ((__warn_unused_result__)); +extern bool cipher_set_counter_key(cipher_t *, void *) __attribute__ ((__warn_unused_result__)); +extern bool cipher_encrypt(cipher_t *, const void *indata, size_t inlen, void *outdata, size_t *outlen, bool oneshot) __attribute__ ((__warn_unused_result__)); +extern bool cipher_decrypt(cipher_t *, const void *indata, size_t inlen, void *outdata, size_t *outlen, bool oneshot) __attribute__ ((__warn_unused_result__)); +extern bool cipher_counter_xor(cipher_t *, const void *indata, size_t inlen, void *outdata) __attribute__ ((__warn_unused_result__)); extern int cipher_get_nid(const cipher_t *); extern bool cipher_active(const cipher_t *); diff --git a/src/conf.c b/src/conf.c index c4f8abb..3c64519 100644 --- a/src/conf.c +++ b/src/conf.c @@ -71,7 +71,7 @@ void exit_configuration(splay_tree_t ** config_tree) { } config_t *new_config(void) { - return xmalloc_and_zero(sizeof(config_t)); + return xzalloc(sizeof(config_t)); } void free_config(config_t *cfg) { @@ -373,9 +373,10 @@ bool read_server_config(void) { read_config_options(config_tree, NULL); xasprintf(&fname, "%s" SLASH "tinc.conf", confbase); + errno = 0; x = read_config_file(config_tree, fname); - if(!x) + if(!x && errno) logger(DEBUG_ALWAYS, LOG_ERR, "Failed to read `%s': %s", fname, strerror(errno)); free(fname); diff --git a/src/connection.c b/src/connection.c index 4798c5a..496f674 100644 --- a/src/connection.c +++ b/src/connection.c @@ -1,6 +1,6 @@ /* connection.c -- connection list management - Copyright (C) 2000-2012 Guus Sliepen , + Copyright (C) 2000-2013 Guus Sliepen , 2000-2005 Ivo Timmermans 2008 Max Rijevski @@ -27,6 +27,7 @@ #include "control_common.h" #include "list.h" #include "logger.h" +#include "rsa.h" #include "subnet.h" #include "utils.h" #include "xalloc.h" @@ -47,21 +48,21 @@ void exit_connections(void) { } connection_t *new_connection(void) { - return xmalloc_and_zero(sizeof(connection_t)); + return xzalloc(sizeof(connection_t)); } void free_connection(connection_t *c) { if(!c) return; - cipher_close(&c->incipher); - digest_close(&c->indigest); - cipher_close(&c->outcipher); - digest_close(&c->outdigest); + cipher_close(c->incipher); + digest_close(c->indigest); + cipher_close(c->outcipher); + digest_close(c->outdigest); sptps_stop(&c->sptps); - ecdsa_free(&c->ecdsa); - rsa_free(&c->rsa); + ecdsa_free(c->ecdsa); + rsa_free(c->rsa); free(c->hischallenge); diff --git a/src/connection.h b/src/connection.h index 10f4a76..b5d3d18 100644 --- a/src/connection.h +++ b/src/connection.h @@ -1,6 +1,6 @@ /* connection.h -- header for connection.c - Copyright (C) 2000-2012 Guus Sliepen , + Copyright (C) 2000-2013 Guus Sliepen , 2000-2005 Ivo Timmermans This program is free software; you can redistribute it and/or modify @@ -47,7 +47,9 @@ typedef struct connection_status_t { unsigned int control:1; /* 1 if this is a control connection */ unsigned int pcap:1; /* 1 if this is a control connection requesting packet capture */ unsigned int log:1; /* 1 if this is a control connection requesting log dump */ - unsigned int unused:20; + unsigned int invitation:1; /* 1 if this is an invitation */ + unsigned int invitation_used:1; /* 1 if the invitation has been consumed */ + unsigned int unused:19; } connection_status_t; #include "ecdsa.h" @@ -73,12 +75,12 @@ typedef struct connection_t { struct node_t *node; /* node associated with the other end */ struct edge_t *edge; /* edge associated with this connection */ - rsa_t rsa; /* his public RSA key */ - ecdsa_t ecdsa; /* his public ECDSA key */ - cipher_t incipher; /* Cipher he will use to send data to us */ - cipher_t outcipher; /* Cipher we will use to send data to him */ - digest_t indigest; - digest_t outdigest; + rsa_t *rsa; /* his public RSA key */ + ecdsa_t *ecdsa; /* his public ECDSA key */ + cipher_t *incipher; /* Cipher he will use to send data to us */ + cipher_t *outcipher; /* Cipher we will use to send data to him */ + digest_t *indigest; + digest_t *outdigest; sptps_t sptps; int inmaclength; diff --git a/src/control.c b/src/control.c index 539ff36..84098be 100644 --- a/src/control.c +++ b/src/control.c @@ -137,17 +137,16 @@ bool init_control(void) { randomize(controlcookie, sizeof controlcookie / 2); bin2hex(controlcookie, controlcookie, sizeof controlcookie / 2); + mode_t mask = umask(0); + umask(mask | 077); FILE *f = fopen(pidfilename, "w"); + umask(mask); + if(!f) { logger(DEBUG_ALWAYS, LOG_ERR, "Cannot write control socket cookie file %s: %s", pidfilename, strerror(errno)); return false; } -#ifdef HAVE_FCHMOD - fchmod(fileno(f), 0600); -#else - chmod(pidfilename, 0600); -#endif // Get the address and port of the first listening socket char *localhost = NULL; @@ -157,7 +156,7 @@ bool init_control(void) { // Make sure we have a valid address, and map 0.0.0.0 and :: to 127.0.0.1 and ::1. if(getsockname(listen_socket[0].tcp.fd, (struct sockaddr *)&sa, &len)) { - xasprintf(&localhost, "127.0.0.1 port %d", myport); + xasprintf(&localhost, "127.0.0.1 port %s", myport); } else { if(sa.sa.sa_family == AF_INET) { if(sa.in.sin_addr.s_addr == 0) diff --git a/src/openssl/crypto.h b/src/crypto.h similarity index 93% rename from src/openssl/crypto.h rename to src/crypto.h index 8047bfb..cd3654f 100644 --- a/src/openssl/crypto.h +++ b/src/crypto.h @@ -1,6 +1,6 @@ /* crypto.h -- header for crypto.c - Copyright (C) 2007 Guus Sliepen + Copyright (C) 2007-2013 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 diff --git a/src/cygwin/.deps/device.Po b/src/cygwin/.deps/device.Po new file mode 100644 index 0000000..9ce06a8 --- /dev/null +++ b/src/cygwin/.deps/device.Po @@ -0,0 +1 @@ +# dummy diff --git a/src/cygwin/device.c b/src/cygwin/device.c index b050140..f4dcae4 100644 --- a/src/cygwin/device.c +++ b/src/cygwin/device.c @@ -18,21 +18,21 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#include "system.h" +#include "../system.h" #include #include -#include "conf.h" -#include "device.h" -#include "logger.h" -#include "names.h" -#include "net.h" -#include "route.h" -#include "utils.h" -#include "xalloc.h" +#include "../conf.h" +#include "../device.h" +#include "../logger.h" +#include "../names.h" +#include "../net.h" +#include "../route.h" +#include "../utils.h" +#include "../xalloc.h" -#include "mingw/common.h" +#include "../mingw/common.h" int device_fd = -1; static HANDLE device_handle = INVALID_HANDLE_VALUE; diff --git a/src/digest.c b/src/digest.c deleted file mode 100644 index 79db491..0000000 --- a/src/digest.c +++ /dev/null @@ -1,127 +0,0 @@ -/* - digest.c -- Digest handling - Copyright (C) 2007-2012 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 - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include "system.h" -#include "utils.h" -#include "xalloc.h" - -#include -#include - -#include "digest.h" -#include "logger.h" - -static void set_maclength(digest_t *digest, int maclength) { - int digestlen = EVP_MD_size(digest->digest); - - if(maclength > digestlen || maclength < 0) - digest->maclength = digestlen; - else - digest->maclength = maclength; -} - -bool digest_open_by_name(digest_t *digest, const char *name, int maclength) { - digest->digest = EVP_get_digestbyname(name); - digest->key = NULL; - - if(!digest->digest) { - logger(DEBUG_ALWAYS, LOG_DEBUG, "Unknown digest name '%s'!", name); - return false; - } - - set_maclength(digest, maclength); - return true; -} - -bool digest_open_by_nid(digest_t *digest, int nid, int maclength) { - digest->digest = EVP_get_digestbynid(nid); - digest->key = NULL; - - if(!digest->digest) { - logger(DEBUG_ALWAYS, LOG_DEBUG, "Unknown digest nid %d!", nid); - return false; - } - - set_maclength(digest, maclength); - return true; -} - -bool digest_open_sha1(digest_t *digest, int maclength) { - digest->digest = EVP_sha1(); - digest->key = NULL; - - set_maclength(digest, maclength); - return true; -} - -bool digest_set_key(digest_t *digest, const void *key, size_t len) { - digest->key = xrealloc(digest->key, len); - memcpy(digest->key, key, len); - digest->keylength = len; - return true; -} - -void digest_close(digest_t *digest) { - free(digest->key); - digest->key = NULL; -} - -bool digest_create(digest_t *digest, const void *indata, size_t inlen, void *outdata) { - size_t len = EVP_MD_size(digest->digest); - unsigned char tmpdata[len]; - - if(digest->key) { - HMAC(digest->digest, digest->key, digest->keylength, indata, inlen, tmpdata, NULL); - } else { - EVP_MD_CTX ctx; - - if(!EVP_DigestInit(&ctx, digest->digest) - || !EVP_DigestUpdate(&ctx, indata, inlen) - || !EVP_DigestFinal(&ctx, tmpdata, NULL)) { - logger(DEBUG_ALWAYS, LOG_DEBUG, "Error creating digest: %s", ERR_error_string(ERR_get_error(), NULL)); - return false; - } - } - - memcpy(outdata, tmpdata, digest->maclength); - return true; -} - -bool digest_verify(digest_t *digest, const void *indata, size_t inlen, const void *cmpdata) { - size_t len = digest->maclength; - unsigned char outdata[len]; - - return digest_create(digest, indata, inlen, outdata) && !memcmp(cmpdata, outdata, digest->maclength); -} - -int digest_get_nid(const digest_t *digest) { - return digest->digest ? digest->digest->type : 0; -} - -size_t digest_keylength(const digest_t *digest) { - return digest->digest->md_size; -} - -size_t digest_length(const digest_t *digest) { - return digest->maclength; -} - -bool digest_active(const digest_t *digest) { - return digest->digest && digest->digest->type != 0; -} diff --git a/src/digest.h b/src/digest.h new file mode 100644 index 0000000..1e14945 --- /dev/null +++ b/src/digest.h @@ -0,0 +1,39 @@ +/* + digest.h -- header file digest.c + Copyright (C) 2007-2013 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#ifndef __TINC_DIGEST_H__ +#define __TINC_DIGEST_H__ + +#define DIGEST_MAX_SIZE 64 + +typedef struct digest digest_t; + +extern digest_t *digest_open_by_name(const char *name, int maclength) __attribute__ ((__malloc__)); +extern digest_t *digest_open_by_nid(int nid, int maclength) __attribute__ ((__malloc__)); +extern digest_t *digest_open_sha1(int maclength) __attribute__ ((__malloc__)); +extern void digest_close(digest_t *); +extern bool digest_create(digest_t *, const void *indata, size_t inlen, void *outdata) __attribute__ ((__warn_unused_result__)); +extern bool digest_verify(digest_t *, const void *indata, size_t inlen, const void *digestdata) __attribute__ ((__warn_unused_result__)); +extern bool digest_set_key(digest_t *, const void *key, size_t len) __attribute__ ((__warn_unused_result__)); +extern int digest_get_nid(const digest_t *); +extern size_t digest_keylength(const digest_t *); +extern size_t digest_length(const digest_t *); +extern bool digest_active(const digest_t *); + +#endif diff --git a/src/dropin.c b/src/dropin.c index ab3fd6b..6d40850 100644 --- a/src/dropin.c +++ b/src/dropin.c @@ -1,7 +1,7 @@ /* dropin.c -- a set of drop-in replacements for libc functions Copyright (C) 2000-2005 Ivo Timmermans, - 2000-2011 Guus Sliepen + 2000-2013 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 diff --git a/src/dropin.h b/src/dropin.h index 5279de7..5601a31 100644 --- a/src/dropin.h +++ b/src/dropin.h @@ -1,7 +1,7 @@ /* dropin.h -- header file for dropin.c Copyright (C) 2000-2005 Ivo Timmermans, - 2000-2011 Guus Sliepen + 2000-2013 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 @@ -63,4 +63,11 @@ extern int usleep(long long usec); } while (0) #endif +#ifdef HAVE_MINGW +#define mkdir(a, b) mkdir(a) +#ifndef SHUT_RDWR +#define SHUT_RDWR SD_BOTH +#endif +#endif + #endif /* __DROPIN_H__ */ diff --git a/src/ecdh.c b/src/ecdh.c deleted file mode 100644 index f94555d..0000000 --- a/src/ecdh.c +++ /dev/null @@ -1,96 +0,0 @@ -/* - ecdh.c -- Diffie-Hellman key exchange handling - Copyright (C) 2011-2012 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 - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include "system.h" -#include "utils.h" -#include "xalloc.h" - -#include -#include -#include - -#include "ecdh.h" -#include "logger.h" - -bool ecdh_generate_public(ecdh_t *ecdh, void *pubkey) { - *ecdh = EC_KEY_new_by_curve_name(NID_secp521r1); - if(!*ecdh) { - logger(DEBUG_ALWAYS, LOG_ERR, "Generating EC key_by_curve_name failed: %s", ERR_error_string(ERR_get_error(), NULL)); - return false; - } - - if(!EC_KEY_generate_key(*ecdh)) { - EC_KEY_free(*ecdh); - *ecdh = NULL; - logger(DEBUG_ALWAYS, LOG_ERR, "Generating EC key failed: %s", ERR_error_string(ERR_get_error(), NULL)); - return false; - } - - const EC_POINT *point = EC_KEY_get0_public_key(*ecdh); - if(!point) { - EC_KEY_free(*ecdh); - *ecdh = NULL; - logger(DEBUG_ALWAYS, LOG_ERR, "Getting public key failed: %s", ERR_error_string(ERR_get_error(), NULL)); - return false; - } - - size_t result = EC_POINT_point2oct(EC_KEY_get0_group(*ecdh), point, POINT_CONVERSION_COMPRESSED, pubkey, ECDH_SIZE, NULL); - if(!result) { - EC_KEY_free(*ecdh); - *ecdh = NULL; - logger(DEBUG_ALWAYS, LOG_ERR, "Converting EC_POINT to binary failed: %s", ERR_error_string(ERR_get_error(), NULL)); - return false; - } - - return true; -} - -bool ecdh_compute_shared(ecdh_t *ecdh, const void *pubkey, void *shared) { - EC_POINT *point = EC_POINT_new(EC_KEY_get0_group(*ecdh)); - if(!point) { - logger(DEBUG_ALWAYS, LOG_ERR, "EC_POINT_new() failed: %s", ERR_error_string(ERR_get_error(), NULL)); - return false; - } - - int result = EC_POINT_oct2point(EC_KEY_get0_group(*ecdh), point, pubkey, ECDH_SIZE, NULL); - if(!result) { - EC_POINT_free(point); - logger(DEBUG_ALWAYS, LOG_ERR, "Converting binary to EC_POINT failed: %s", ERR_error_string(ERR_get_error(), NULL)); - return false; - } - - result = ECDH_compute_key(shared, ECDH_SIZE, point, *ecdh, NULL); - EC_POINT_free(point); - EC_KEY_free(*ecdh); - *ecdh = NULL; - - if(!result) { - logger(DEBUG_ALWAYS, LOG_ERR, "Computing Elliptic Curve Diffie-Hellman shared key failed: %s", ERR_error_string(ERR_get_error(), NULL)); - return false; - } - - return true; -} - -void ecdh_free(ecdh_t *ecdh) { - if(*ecdh) { - EC_KEY_free(*ecdh); - *ecdh = NULL; - } -} diff --git a/src/openssl/ecdh.h b/src/ecdh.h similarity index 78% rename from src/openssl/ecdh.h rename to src/ecdh.h index ef7de6e..fbd4729 100644 --- a/src/openssl/ecdh.h +++ b/src/ecdh.h @@ -1,6 +1,6 @@ /* ecdh.h -- header file for ecdh.c - Copyright (C) 2011 Guus Sliepen + Copyright (C) 2011-2013 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 @@ -20,15 +20,15 @@ #ifndef __TINC_ECDH_H__ #define __TINC_ECDH_H__ -#include - #define ECDH_SIZE 67 #define ECDH_SHARED_SIZE 66 -typedef EC_KEY *ecdh_t; +#ifndef __TINC_ECDH_INTERNAL__ +typedef struct ecdh ecdh_t; +#endif -extern bool ecdh_generate_public(ecdh_t *ecdh, void *pubkey); -extern bool ecdh_compute_shared(ecdh_t *ecdh, const void *pubkey, void *shared); +extern ecdh_t *ecdh_generate_public(void *pubkey) __attribute__ ((__malloc__)); +extern bool ecdh_compute_shared(ecdh_t *ecdh, const void *pubkey, void *shared) __attribute__ ((__warn_unused_result__)); extern void ecdh_free(ecdh_t *ecdh); #endif diff --git a/src/ecdsa.c b/src/ecdsa.c deleted file mode 100644 index e2af6f9..0000000 --- a/src/ecdsa.c +++ /dev/null @@ -1,130 +0,0 @@ -/* - ecdsa.c -- ECDSA key handling - Copyright (C) 2011-2012 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 - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include "system.h" - -#include -#include - -#include "logger.h" -#include "ecdsa.h" -#include "utils.h" - -// Get and set ECDSA keys -// -bool ecdsa_set_base64_public_key(ecdsa_t *ecdsa, const char *p) { - *ecdsa = EC_KEY_new_by_curve_name(NID_secp521r1); - if(!*ecdsa) { - logger(DEBUG_ALWAYS, LOG_DEBUG, "EC_KEY_new_by_curve_name failed: %s", ERR_error_string(ERR_get_error(), NULL)); - return false; - } - - int len = strlen(p); - unsigned char pubkey[len / 4 * 3 + 3]; - const unsigned char *ppubkey = pubkey; - len = b64decode(p, (char *)pubkey, len); - - if(!o2i_ECPublicKey(ecdsa, &ppubkey, len)) { - logger(DEBUG_ALWAYS, LOG_DEBUG, "o2i_ECPublicKey failed: %s", ERR_error_string(ERR_get_error(), NULL)); - return false; - } - - return true; -} - -char *ecdsa_get_base64_public_key(ecdsa_t *ecdsa) { - unsigned char *pubkey = NULL; - int len = i2o_ECPublicKey(*ecdsa, &pubkey); - - char *base64 = malloc(len * 4 / 3 + 5); - b64encode((char *)pubkey, base64, len); - - free(pubkey); - - return base64; -} - -// Read PEM ECDSA keys - -bool ecdsa_read_pem_public_key(ecdsa_t *ecdsa, FILE *fp) { - *ecdsa = PEM_read_EC_PUBKEY(fp, ecdsa, NULL, NULL); - - if(*ecdsa) - return true; - - logger(DEBUG_ALWAYS, LOG_ERR, "Unable to read ECDSA public key: %s", ERR_error_string(ERR_get_error(), NULL)); - return false; -} - -bool ecdsa_read_pem_private_key(ecdsa_t *ecdsa, FILE *fp) { - *ecdsa = PEM_read_ECPrivateKey(fp, NULL, NULL, NULL); - - if(*ecdsa) - return true; - - logger(DEBUG_ALWAYS, LOG_ERR, "Unable to read ECDSA private key: %s", ERR_error_string(ERR_get_error(), NULL)); - return false; -} - -size_t ecdsa_size(ecdsa_t *ecdsa) { - return ECDSA_size(*ecdsa); -} - -// TODO: standardise output format? - -bool ecdsa_sign(ecdsa_t *ecdsa, const void *in, size_t len, void *sig) { - unsigned int siglen = ECDSA_size(*ecdsa); - - unsigned char hash[SHA512_DIGEST_LENGTH]; - SHA512(in, len, hash); - - memset(sig, 0, siglen); - - if(!ECDSA_sign(0, hash, sizeof hash, sig, &siglen, *ecdsa)) { - logger(DEBUG_ALWAYS, LOG_DEBUG, "ECDSA_sign() failed: %s", ERR_error_string(ERR_get_error(), NULL)); - return false; - } - - return true; -} - -bool ecdsa_verify(ecdsa_t *ecdsa, const void *in, size_t len, const void *sig) { - unsigned int siglen = ECDSA_size(*ecdsa); - - unsigned char hash[SHA512_DIGEST_LENGTH]; - SHA512(in, len, hash); - - if(!ECDSA_verify(0, hash, sizeof hash, sig, siglen, *ecdsa)) { - logger(DEBUG_ALWAYS, LOG_DEBUG, "ECDSA_verify() failed: %s", ERR_error_string(ERR_get_error(), NULL)); - return false; - } - - return true; -} - -bool ecdsa_active(ecdsa_t *ecdsa) { - return *ecdsa; -} - -void ecdsa_free(ecdsa_t *ecdsa) { - if(*ecdsa) { - EC_KEY_free(*ecdsa); - *ecdsa = NULL; - } -} diff --git a/src/openssl/ecdsa.h b/src/ecdsa.h similarity index 69% rename from src/openssl/ecdsa.h rename to src/ecdsa.h index 04f9eb9..d03a58e 100644 --- a/src/openssl/ecdsa.h +++ b/src/ecdsa.h @@ -1,6 +1,6 @@ /* ecdsa.h -- ECDSA key handling - Copyright (C) 2011 Guus Sliepen + Copyright (C) 2011-2013 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 @@ -20,17 +20,17 @@ #ifndef __TINC_ECDSA_H__ #define __TINC_ECDSA_H__ -#include +#ifndef __TINC_ECDSA_INTERNAL__ +typedef struct ecdsa ecdsa_t; +#endif -typedef EC_KEY *ecdsa_t; - -extern bool ecdsa_set_base64_public_key(ecdsa_t *ecdsa, const char *p); +extern ecdsa_t *ecdsa_set_base64_public_key(const char *p) __attribute__ ((__malloc__)); extern char *ecdsa_get_base64_public_key(ecdsa_t *ecdsa); -extern bool ecdsa_read_pem_public_key(ecdsa_t *ecdsa, FILE *fp); -extern bool ecdsa_read_pem_private_key(ecdsa_t *ecdsa, FILE *fp); +extern ecdsa_t *ecdsa_read_pem_public_key(FILE *fp) __attribute__ ((__malloc__)); +extern ecdsa_t *ecdsa_read_pem_private_key(FILE *fp) __attribute__ ((__malloc__)); extern size_t ecdsa_size(ecdsa_t *ecdsa); -extern bool ecdsa_sign(ecdsa_t *ecdsa, const void *in, size_t inlen, void *out); -extern bool ecdsa_verify(ecdsa_t *ecdsa, const void *in, size_t inlen, const void *out); +extern bool ecdsa_sign(ecdsa_t *ecdsa, const void *in, size_t inlen, void *out) __attribute__ ((__warn_unused_result__)); +extern bool ecdsa_verify(ecdsa_t *ecdsa, const void *in, size_t inlen, const void *out) __attribute__ ((__warn_unused_result__)); extern bool ecdsa_active(ecdsa_t *ecdsa); extern void ecdsa_free(ecdsa_t *ecdsa); diff --git a/src/openssl/ecdsagen.h b/src/ecdsagen.h similarity index 82% rename from src/openssl/ecdsagen.h rename to src/ecdsagen.h index 8a40e45..12e5c00 100644 --- a/src/openssl/ecdsagen.h +++ b/src/ecdsagen.h @@ -1,6 +1,6 @@ /* ecdsagen.h -- ECDSA key generation and export - Copyright (C) 2011 Guus Sliepen + Copyright (C) 2011-2013 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 @@ -22,9 +22,8 @@ #include "ecdsa.h" -extern bool ecdsa_generate(ecdsa_t *ecdsa); -extern bool ecdsa_write_pem_public_key(ecdsa_t *ecdsa, FILE *fp); -extern bool ecdsa_write_pem_private_key(ecdsa_t *ecdsa, FILE *fp); -extern char *ecdsa_get_base64_public_key(ecdsa_t *ecdsa); +extern ecdsa_t *ecdsa_generate(void) __attribute__ ((__malloc__)); +extern bool ecdsa_write_pem_public_key(ecdsa_t *ecdsa, FILE *fp) __attribute__ ((__warn_unused_result__)); +extern bool ecdsa_write_pem_private_key(ecdsa_t *ecdsa, FILE *fp) __attribute__ ((__warn_unused_result__)); #endif diff --git a/src/edge.c b/src/edge.c index fd03327..f185b4f 100644 --- a/src/edge.c +++ b/src/edge.c @@ -1,6 +1,6 @@ /* edge.c -- edge tree management - Copyright (C) 2000-2012 Guus Sliepen , + Copyright (C) 2000-2013 Guus Sliepen , 2000-2005 Ivo Timmermans This program is free software; you can redistribute it and/or modify @@ -70,7 +70,7 @@ void exit_edges(void) { /* Creation and deletion of connection elements */ edge_t *new_edge(void) { - return xmalloc_and_zero(sizeof(edge_t)); + return xzalloc(sizeof(edge_t)); } void free_edge(edge_t *e) { diff --git a/src/event.c b/src/event.c index 095e7c3..5a1e4f5 100644 --- a/src/event.c +++ b/src/event.c @@ -1,6 +1,6 @@ /* event.c -- I/O, timeout and signal event handling - Copyright (C) 2012 Guus Sliepen + Copyright (C) 2012-2013 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 diff --git a/src/event.h b/src/event.h index bd91b7b..c6522c0 100644 --- a/src/event.h +++ b/src/event.h @@ -1,6 +1,6 @@ /* event.h -- I/O, timeout and signal event handling - Copyright (C) 2012 Guus Sliepen + Copyright (C) 2012-2013 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 diff --git a/src/fake-gai-errnos.h b/src/fake-gai-errnos.h index 33913eb..2f41d8f 100644 --- a/src/fake-gai-errnos.h +++ b/src/fake-gai-errnos.h @@ -17,3 +17,7 @@ #ifndef EAI_FAMILY #define EAI_FAMILY 3 #endif + +#ifndef EAI_SYSTEM +#define EAI_SYSTEM 4 +#endif diff --git a/src/fake-getaddrinfo.c b/src/fake-getaddrinfo.c index db50f73..cb821b5 100644 --- a/src/fake-getaddrinfo.c +++ b/src/fake-getaddrinfo.c @@ -48,7 +48,7 @@ void freeaddrinfo(struct addrinfo *ai) { static struct addrinfo *malloc_ai(uint16_t port, uint32_t addr) { struct addrinfo *ai; - ai = xmalloc_and_zero(sizeof(struct addrinfo) + sizeof(struct sockaddr_in)); + ai = xzalloc(sizeof(struct addrinfo) + sizeof(struct sockaddr_in)); ai->ai_addr = (struct sockaddr *)(ai + 1); ai->ai_addrlen = sizeof(struct sockaddr_in); diff --git a/src/gcrypt/.deps/cipher.Po b/src/gcrypt/.deps/cipher.Po new file mode 100644 index 0000000..9ce06a8 --- /dev/null +++ b/src/gcrypt/.deps/cipher.Po @@ -0,0 +1 @@ +# dummy diff --git a/src/gcrypt/.deps/crypto.Po b/src/gcrypt/.deps/crypto.Po new file mode 100644 index 0000000..9ce06a8 --- /dev/null +++ b/src/gcrypt/.deps/crypto.Po @@ -0,0 +1 @@ +# dummy diff --git a/src/gcrypt/.deps/digest.Po b/src/gcrypt/.deps/digest.Po new file mode 100644 index 0000000..9ce06a8 --- /dev/null +++ b/src/gcrypt/.deps/digest.Po @@ -0,0 +1 @@ +# dummy diff --git a/src/gcrypt/.deps/ecdh.Po b/src/gcrypt/.deps/ecdh.Po new file mode 100644 index 0000000..9ce06a8 --- /dev/null +++ b/src/gcrypt/.deps/ecdh.Po @@ -0,0 +1 @@ +# dummy diff --git a/src/gcrypt/.deps/ecdsa.Po b/src/gcrypt/.deps/ecdsa.Po new file mode 100644 index 0000000..9ce06a8 --- /dev/null +++ b/src/gcrypt/.deps/ecdsa.Po @@ -0,0 +1 @@ +# dummy diff --git a/src/gcrypt/.deps/ecdsagen.Po b/src/gcrypt/.deps/ecdsagen.Po new file mode 100644 index 0000000..9ce06a8 --- /dev/null +++ b/src/gcrypt/.deps/ecdsagen.Po @@ -0,0 +1 @@ +# dummy diff --git a/src/gcrypt/.deps/prf.Po b/src/gcrypt/.deps/prf.Po new file mode 100644 index 0000000..9ce06a8 --- /dev/null +++ b/src/gcrypt/.deps/prf.Po @@ -0,0 +1 @@ +# dummy diff --git a/src/gcrypt/.deps/rsa.Po b/src/gcrypt/.deps/rsa.Po new file mode 100644 index 0000000..9ce06a8 --- /dev/null +++ b/src/gcrypt/.deps/rsa.Po @@ -0,0 +1 @@ +# dummy diff --git a/src/gcrypt/.deps/rsagen.Po b/src/gcrypt/.deps/rsagen.Po new file mode 100644 index 0000000..9ce06a8 --- /dev/null +++ b/src/gcrypt/.deps/rsagen.Po @@ -0,0 +1 @@ +# dummy diff --git a/src/gcrypt/ecdh.c b/src/gcrypt/ecdh.c new file mode 100644 index 0000000..4e30733 --- /dev/null +++ b/src/gcrypt/ecdh.c @@ -0,0 +1,37 @@ +/* + ecdh.c -- Diffie-Hellman key exchange handling + Copyright (C) 2011-2013 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "../system.h" + +#include "../ecdh.h" +#include "../logger.h" +#include "../utils.h" +#include "../xalloc.h" + +ecdh_t *ecdh_generate_public(void *pubkey) { + logger(DEBUG_ALWAYS, LOG_ERR, "EC support using libgcrypt not implemented"); + return NULL; +} + +bool ecdh_compute_shared(ecdh_t *ecdh, const void *pubkey, void *shared) { + return false +} + +void ecdh_free(ecdh_t *ecdh) { +} diff --git a/src/gcrypt/ecdsa.c b/src/gcrypt/ecdsa.c new file mode 100644 index 0000000..ee19aec --- /dev/null +++ b/src/gcrypt/ecdsa.c @@ -0,0 +1,67 @@ +/* + ecdsa.c -- ECDSA key handling + Copyright (C) 2011-2013 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "../system.h" + +#include "../logger.h" +#include "../ecdsa.h" +#include "../utils.h" +#include "../xalloc.h" + +// Get and set ECDSA keys +// +ecdsa_t *ecdsa_set_base64_public_key(const char *p) { + logger(DEBUG_ALWAYS, LOG_ERR, "EC support using libgcrypt not implemented"); + return NULL; +} + +char *ecdsa_get_base64_public_key(ecdsa_t *ecdsa) { + return NULL; +} + +// Read PEM ECDSA keys + +ecdsa_t *ecdsa_read_pem_public_key(FILE *fp) { + logger(DEBUG_ALWAYS, LOG_ERR, "EC support using libgcrypt not implemented"); + return NULL; +} + +ecdsa_t *ecdsa_read_pem_private_key(FILE *fp) { + logger(DEBUG_ALWAYS, LOG_ERR, "EC support using libgcrypt not implemented"); + return NULL; +} + +size_t ecdsa_size(ecdsa_t *ecdsa) { + return 0; +} + +bool ecdsa_sign(ecdsa_t *ecdsa, const void *in, size_t len, void *sig) { + return false; +} + +bool ecdsa_verify(ecdsa_t *ecdsa, const void *in, size_t len, const void *sig) { + return false; +} + +bool ecdsa_active(ecdsa_t *ecdsa) { + return false; +} + +void ecdsa_free(ecdsa_t *ecdsa) { +} diff --git a/src/crypto.c b/src/gcrypt/ecdsagen.c similarity index 58% rename from src/crypto.c rename to src/gcrypt/ecdsagen.c index c695be8..2d4912d 100644 --- a/src/crypto.c +++ b/src/gcrypt/ecdsagen.c @@ -1,6 +1,6 @@ /* - crypto.c -- Cryptographic miscellaneous functions and initialisation - Copyright (C) 2007 Guus Sliepen + ecdsagen.c -- ECDSA key generation and export + Copyright (C) 2011-2013 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 @@ -17,27 +17,25 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#include "system.h" +#include "../system.h" -#include -#include -#include +#include "../ecdsagen.h" +#include "../utils.h" +#include "../xalloc.h" -#include "crypto.h" +// Generate ECDSA key -void crypto_init(void) { - RAND_load_file("/dev/urandom", 1024); - - ENGINE_load_builtin_engines(); - ENGINE_register_all_complete(); - - OpenSSL_add_all_algorithms(); +ecdsa_t *ecdsa_generate(void) { + logger(DEBUG_ALWAYS, LOG_ERR, "EC support using libgcrypt not implemented"); + return NULL; } -void crypto_exit(void) { - EVP_cleanup(); +// Write PEM ECDSA keys + +bool ecdsa_write_pem_public_key(ecdsa_t *ecdsa, FILE *fp) { + return false; } -void randomize(void *out, size_t outlen) { - RAND_pseudo_bytes(out, outlen); +bool ecdsa_write_pem_private_key(ecdsa_t *ecdsa, FILE *fp) { + return false; } diff --git a/src/gcrypt/prf.c b/src/gcrypt/prf.c new file mode 100644 index 0000000..f9a2112 --- /dev/null +++ b/src/gcrypt/prf.c @@ -0,0 +1,29 @@ +/* + prf.c -- Pseudo-Random Function for key material generation + Copyright (C) 2011-2013 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "../system.h" + +#include "digest.h" +#include "../digest.h" +#include "../prf.h" + +bool prf(const char *secret, size_t secretlen, char *seed, size_t seedlen, char *out, size_t outlen) { + logger(DEBUG_ALWAYS, LOG_ERR, "PRF support using libgcrypt not implemented"); + return false; +} diff --git a/src/getopt.c b/src/getopt.c index a6782ed..d63887e 100644 --- a/src/getopt.c +++ b/src/getopt.c @@ -31,7 +31,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #endif #ifdef HAVE_CONFIG_H -#include +#include "../config.h" #endif #if !defined (__STDC__) || !__STDC__ diff --git a/src/getopt1.c b/src/getopt1.c index 86545f2..19605a5 100644 --- a/src/getopt1.c +++ b/src/getopt1.c @@ -20,7 +20,7 @@ with this program; if not, write to the Free Software Foundation, Inc., */ #ifdef HAVE_CONFIG_H -#include +#include "../config.h" #endif #include "getopt.h" diff --git a/src/graph.c b/src/graph.c index 4506379..b4c01bb 100644 --- a/src/graph.c +++ b/src/graph.c @@ -44,7 +44,6 @@ #include "system.h" -#include "config.h" #include "connection.h" #include "device.h" #include "edge.h" @@ -236,7 +235,7 @@ static void check_reachability(void) { char *name; char *address; char *port; - char *envp[7]; + char *envp[8] = {NULL}; xasprintf(&envp[0], "NETNAME=%s", netname ? : ""); xasprintf(&envp[1], "DEVICE=%s", device ? : ""); @@ -245,7 +244,7 @@ static void check_reachability(void) { sockaddr2str(&n->address, &address, &port); xasprintf(&envp[4], "REMOTEADDRESS=%s", address); xasprintf(&envp[5], "REMOTEPORT=%s", port); - envp[6] = NULL; + xasprintf(&envp[6], "NAME=%s", myself->name); execute_script(n->status.reachable ? "host-up" : "host-down", envp); @@ -256,7 +255,7 @@ static void check_reachability(void) { free(address); free(port); - for(int i = 0; i < 6; i++) + for(int i = 0; i < 7; i++) free(envp[i]); subnet_update(n, NULL, n->status.reachable); diff --git a/src/hash.c b/src/hash.c index 1d203c5..8fb9ca6 100644 --- a/src/hash.c +++ b/src/hash.c @@ -1,6 +1,6 @@ /* hash.c -- hash table management - Copyright (C) 2012 Guus Sliepen + Copyright (C) 2012-2013 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 @@ -29,7 +29,7 @@ static uint32_t hash_function(const void *p, size_t len) { uint32_t hash = 0; while(true) { for(int i = len > 4 ? 4 : len; --i;) - hash += q[i] << (8 * i); + hash += q[len - i] << (8 * i); hash *= 0x9e370001UL; // Golden ratio prime. if(len <= 4) break; @@ -52,11 +52,11 @@ static uint32_t modulo(uint32_t hash, size_t n) { /* (De)allocation */ hash_t *hash_alloc(size_t n, size_t size) { - hash_t *hash = xmalloc_and_zero(sizeof *hash); + hash_t *hash = xzalloc(sizeof *hash); hash->n = n; hash->size = size; - hash->keys = xmalloc_and_zero(hash->n * hash->size); - hash->values = xmalloc_and_zero(hash->n * sizeof *hash->values); + hash->keys = xzalloc(hash->n * hash->size); + hash->values = xzalloc(hash->n * sizeof *hash->values); return hash; } diff --git a/have.h b/src/have.h similarity index 98% rename from have.h rename to src/have.h index 6d65bcd..3ada63a 100644 --- a/have.h +++ b/src/have.h @@ -1,7 +1,7 @@ /* have.h -- include headers which are known to exist Copyright (C) 1998-2005 Ivo Timmermans - 2003-2012 Guus Sliepen + 2003-2013 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 diff --git a/src/info.c b/src/info.c index 8e91a22..af085bc 100644 --- a/src/info.c +++ b/src/info.c @@ -1,6 +1,6 @@ /* info.c -- Show information about a node, subnet or address - Copyright (C) 2012 Guus Sliepen + Copyright (C) 2012-2013 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 @@ -31,6 +31,7 @@ void logger(int level, int priority, const char *format, ...) { va_start(ap, format); vfprintf(stderr, format, ap); va_end(ap); + fputc('\n', stderr); } char *strip_weight(char *netstr) { diff --git a/src/invitation.c b/src/invitation.c new file mode 100644 index 0000000..f1cde58 --- /dev/null +++ b/src/invitation.c @@ -0,0 +1,939 @@ +/* + invitation.c -- Create and accept invitations + Copyright (C) 2013 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "system.h" + +#include "control_common.h" +#include "crypto.h" +#include "ecdsa.h" +#include "ecdsagen.h" +#include "invitation.h" +#include "names.h" +#include "netutl.h" +#include "rsagen.h" +#include "sptps.h" +#include "tincctl.h" +#include "utils.h" +#include "xalloc.h" + +#ifdef HAVE_MINGW +#define SCRIPTEXTENSION ".bat" +#else +#define SCRIPTEXTENSION "" +#endif + +int addressfamily = AF_UNSPEC; + +char *get_my_hostname() { + char *hostname = NULL; + char *port = NULL; + char *hostport = NULL; + char *name = get_my_name(false); + char *filename = NULL; + + // Use first Address statement in own host config file + if(check_id(name)) { + xasprintf(&filename, "%s" SLASH "hosts" SLASH "%s", confbase, name); + FILE *f = fopen(filename, "r"); + if(f) { + while(fgets(line, sizeof line, f)) { + if(!rstrip(line)) + continue; + char *p = line, *q; + p += strcspn(p, "\t ="); + if(!*p) + continue; + q = p + strspn(p, "\t "); + if(*q == '=') + q += 1 + strspn(q + 1, "\t "); + *p = 0; + p = q + strcspn(q, "\t "); + if(*p) + *p++ = 0; + p += strspn(p, "\t "); + p[strcspn(p, "\t ")] = 0; + if(!port && !strcasecmp(line, "Port")) { + port = xstrdup(q); + continue; + } + if(strcasecmp(line, "Address")) + continue; + hostname = xstrdup(q); + if(*p) { + free(port); + port = xstrdup(p); + } + break; + } + fclose(f); + } + } + + if(hostname) + goto done; + + // If that doesn't work, guess externally visible hostname + fprintf(stderr, "Trying to discover externally visible hostname...\n"); + struct addrinfo *ai = str2addrinfo("ifconfig.me", "80", SOCK_STREAM); + static const char request[] = "GET /host HTTP/1.0\r\n\r\n"; + if(ai) { + int s = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); + if(s >= 0) { + if(connect(s, ai->ai_addr, ai->ai_addrlen)) { + closesocket(s); + s = -1; + } + } + if(s >= 0) { + send(s, request, sizeof request - 1, 0); + int len = recv(s, line, sizeof line - 1, MSG_WAITALL); + if(len > 0) { + line[len] = 0; + if(line[len - 1] == '\n') + line[--len] = 0; + char *p = strrchr(line, '\n'); + if(p && p[1]) + hostname = xstrdup(p + 1); + } + closesocket(s); + } + freeaddrinfo(ai); + } + + // Check that the hostname is reasonable + if(hostname) { + for(char *p = hostname; *p; p++) { + if(isalnum(*p) || *p == '-' || *p == '.') + continue; + // If not, forget it. + free(hostname); + hostname = NULL; + break; + } + } + +again: + printf("Please enter your host's external address or hostname"); + if(hostname) + printf(" [%s]", hostname); + printf(": "); + fflush(stdout); + + if(!fgets(line, sizeof line, stdin)) { + fprintf(stderr, "Error while reading stdin: %s\n", strerror(errno)); + free(hostname); + return NULL; + } + + if(!rstrip(line)) { + if(hostname) + goto save; + else + goto again; + } + + for(char *p = line; *p; p++) { + if(isalnum(*p) || *p == '-' || *p == '.') + continue; + fprintf(stderr, "Invalid address or hostname.\n"); + goto again; + } + + free(hostname); + hostname = xstrdup(line); + +save: + if(filename) { + FILE *f = fopen(filename, "a"); + if(f) { + fprintf(f, "\nAddress = %s\n", hostname); + fclose(f); + } else { + fprintf(stderr, "Could not append Address to %s: %s\n", filename, strerror(errno)); + } + } + +done: + if(port) { + if(strchr(hostname, ':')) + xasprintf(&hostport, "[%s]:%s", hostname, port); + else + xasprintf(&hostport, "%s:%s", hostname, port); + } else { + hostport = hostname; + hostname = NULL; + } + + free(hostname); + free(port); + free(filename); + return hostport; +} + +static bool fcopy(FILE *out, const char *filename) { + FILE *in = fopen(filename, "r"); + if(!in) { + fprintf(stderr, "Could not open %s: %s\n", filename, strerror(errno)); + return false; + } + + char buf[1024]; + size_t len; + while((len = fread(buf, 1, sizeof buf, in))) + fwrite(buf, len, 1, out); + fclose(in); + return true; +} + +int cmd_invite(int argc, char *argv[]) { + if(argc < 2) { + fprintf(stderr, "Not enough arguments!\n"); + return 1; + } + + // Check validity of the new node's name + if(!check_id(argv[1])) { + fprintf(stderr, "Invalid name for node.\n"); + return 1; + } + + char *myname = get_my_name(true); + if(!myname) + return 1; + + // Ensure no host configuration file with that name exists + char *filename = NULL; + xasprintf(&filename, "%s" SLASH "hosts" SLASH "%s", confbase, argv[1]); + if(!access(filename, F_OK)) { + free(filename); + fprintf(stderr, "A host config file for %s already exists!\n", argv[1]); + return 1; + } + free(filename); + + // If a daemon is running, ensure no other nodes now about this name + bool found = false; + if(connect_tincd(false)) { + sendline(fd, "%d %d", CONTROL, REQ_DUMP_NODES); + + while(recvline(fd, line, sizeof line)) { + char node[4096]; + int code, req; + if(sscanf(line, "%d %d %s", &code, &req, node) != 3) + break; + if(!strcmp(node, argv[1])) + found = true; + } + + if(found) { + fprintf(stderr, "A node with name %s is already known!\n", argv[1]); + return 1; + } + } + + char hash[25]; + + xasprintf(&filename, "%s" SLASH "invitations", confbase); + if(mkdir(filename, 0700) && errno != EEXIST) { + fprintf(stderr, "Could not create directory %s: %s\n", filename, strerror(errno)); + free(filename); + return 1; + } + + // Count the number of valid invitations, clean up old ones + DIR *dir = opendir(filename); + if(!dir) { + fprintf(stderr, "Could not read directory %s: %s\n", filename, strerror(errno)); + free(filename); + return 1; + } + + errno = 0; + int count = 0; + struct dirent *ent; + time_t deadline = time(NULL) - 604800; // 1 week in the past + + while((ent = readdir(dir))) { + if(strlen(ent->d_name) != 24) + continue; + char *invname; + struct stat st; + xasprintf(&invname, "%s" SLASH "%s", filename, ent->d_name); + if(!stat(invname, &st)) { + if(deadline < st.st_mtime) + count++; + else + unlink(invname); + } else { + fprintf(stderr, "Could not stat %s: %s\n", invname, strerror(errno)); + errno = 0; + } + free(invname); + } + + if(errno) { + fprintf(stderr, "Error while reading directory %s: %s\n", filename, strerror(errno)); + closedir(dir); + free(filename); + return 1; + } + + closedir(dir); + free(filename); + + ecdsa_t *key; + xasprintf(&filename, "%s" SLASH "invitations" SLASH "ecdsa_key.priv", confbase); + + // Remove the key if there are no outstanding invitations. + if(!count) + unlink(filename); + + // Create a new key if necessary. + FILE *f = fopen(filename, "r"); + if(!f) { + if(errno != ENOENT) { + fprintf(stderr, "Could not read %s: %s\n", filename, strerror(errno)); + free(filename); + return 1; + } + + key = ecdsa_generate(); + if(!key) { + free(filename); + return 1; + } + f = fopen(filename, "w"); + if(!f) { + fprintf(stderr, "Could not write %s: %s\n", filename, strerror(errno)); + free(filename); + return 1; + } + chmod(filename, 0600); + ecdsa_write_pem_private_key(key, f); + } else { + key = ecdsa_read_pem_private_key(f); + if(!key) + fprintf(stderr, "Could not read private key from %s\n", filename); + } + fclose(f); + free(filename); + if(!key) + return 1; + + // Create a hash of the key. + char *fingerprint = ecdsa_get_base64_public_key(key); + digest_t *digest = digest_open_by_name("sha256", 18); + if(!digest) + abort(); + digest_create(digest, fingerprint, strlen(fingerprint), hash); + b64encode_urlsafe(hash, hash, 18); + + // Create a random cookie for this invitation. + char cookie[25]; + randomize(cookie, 18); + b64encode_urlsafe(cookie, cookie, 18); + + // Create a file containing the details of the invitation. + xasprintf(&filename, "%s" SLASH "invitations" SLASH "%s", confbase, cookie); + int ifd = open(filename, O_RDWR | O_CREAT | O_EXCL, 0600); + if(!ifd) { + fprintf(stderr, "Could not create invitation file %s: %s\n", filename, strerror(errno)); + free(filename); + return 1; + } + free(filename); + f = fdopen(ifd, "w"); + if(!f) + abort(); + + // Fill in the details. + fprintf(f, "Name = %s\n", argv[1]); + if(netname) + fprintf(f, "NetName = %s\n", netname); + fprintf(f, "ConnectTo = %s\n", myname); + // TODO: copy Broadcast and Mode + fprintf(f, "#---------------------------------------------------------------#\n"); + fprintf(f, "Name = %s\n", myname); + + xasprintf(&filename, "%s" SLASH "hosts" SLASH "%s", confbase, myname); + fcopy(f, filename); + fclose(f); + + // Create an URL from the local address, key hash and cookie + char *address = get_my_hostname(); + printf("%s/%s%s\n", address, hash, cookie); + free(filename); + free(address); + + return 0; +} + +static int sock; +static char cookie[18]; +static sptps_t sptps; +static char *data; +static size_t datalen; +static bool success = false; + +static char cookie[18], hash[18]; + +static char *get_line(const char **data) { + if(!data || !*data) + return NULL; + + if(!**data) { + *data = NULL; + return NULL; + } + + static char line[1024]; + const char *end = strchr(*data, '\n'); + size_t len = end ? end - *data : strlen(*data); + if(len >= sizeof line) { + fprintf(stderr, "Maximum line length exceeded!\n"); + return NULL; + } + if(len && !isprint(**data)) + abort(); + + memcpy(line, *data, len); + line[len] = 0; + + if(end) + *data = end + 1; + else + *data = NULL; + + return line; +} + +static char *get_value(const char *data, const char *var) { + char *line = get_line(&data); + if(!line) + return NULL; + + char *sep = line + strcspn(line, " \t="); + char *val = sep + strspn(sep, " \t"); + if(*val == '=') + val += 1 + strspn(val + 1, " \t"); + *sep = 0; + if(strcasecmp(line, var)) + return NULL; + return val; +} + +static char *grep(const char *data, const char *var) { + static char value[1024]; + + const char *p = data; + int varlen = strlen(var); + + // Skip all lines not starting with var + while(strncasecmp(p, var, varlen) || !strchr(" \t=", p[varlen])) { + p = strchr(p, '\n'); + if(!p) + break; + else + p++; + } + + if(!p) + return NULL; + + p += varlen; + p += strspn(p, " \t"); + if(*p == '=') + p += 1 + strspn(p + 1, " \t"); + + const char *e = strchr(p, '\n'); + if(!e) + return xstrdup(p); + + if(e - p >= sizeof value) { + fprintf(stderr, "Maximum line length exceeded!\n"); + return NULL; + } + + memcpy(value, p, e - p); + value[e - p] = 0; + return value; +} + +static bool finalize_join(void) { + char *name = xstrdup(get_value(data, "Name")); + if(!name) { + fprintf(stderr, "No Name found in invitation!\n"); + return false; + } + + if(!check_id(name)) { + fprintf(stderr, "Invalid Name found in invitation: %s!\n", name); + return false; + } + + if(!netname) + netname = grep(data, "NetName"); + + bool ask_netname = false; + char temp_netname[32]; + +make_names: + if(!confbasegiven) { + free(confbase); + confbase = NULL; + } + + make_names(); + + free(tinc_conf); + free(hosts_dir); + + xasprintf(&tinc_conf, "%s" SLASH "tinc.conf", confbase); + xasprintf(&hosts_dir, "%s" SLASH "hosts", confbase); + + if(!access(tinc_conf, F_OK)) { + fprintf(stderr, "Configuration file %s already exists!\n", tinc_conf); + if(!tty || confbasegiven) + return false; + + // Generate a random netname, ask for a better one later. + ask_netname = true; + snprintf(temp_netname, sizeof temp_netname, "join_%x", rand()); + netname = temp_netname; + goto make_names; + } + + if(mkdir(confbase, 0777) && errno != EEXIST) { + fprintf(stderr, "Could not create directory %s: %s\n", confbase, strerror(errno)); + return false; + } + + if(mkdir(hosts_dir, 0777) && errno != EEXIST) { + fprintf(stderr, "Could not create directory %s: %s\n", hosts_dir, strerror(errno)); + return false; + } + + FILE *f = fopen(tinc_conf, "w"); + if(!f) { + fprintf(stderr, "Could not create file %s: %s\n", tinc_conf, strerror(errno)); + return false; + } + + fprintf(f, "Name = %s\n", name); + + char *filename; + xasprintf(&filename, "%s" SLASH "%s", hosts_dir, name); + FILE *fh = fopen(filename, "w"); + if(!fh) { + fprintf(stderr, "Could not create file %s: %s\n", filename, strerror(errno)); + return false; + } + + // Filter first chunk on approved keywords, split between tinc.conf and hosts/Name + // Other chunks go unfiltered to their respective host config files + const char *p = data; + char *l, *value; + + while((l = get_line(&p))) { + // Ignore comments + if(*l == '#') + continue; + + // Split line into variable and value + int len = strcspn(l, "\t ="); + value = l + len; + value += strspn(value, "\t "); + if(*value == '=') { + value++; + value += strspn(value, "\t "); + } + l[len] = 0; + + // Is it a Name? + if(!strcasecmp(l, "Name")) + if(strcmp(value, name)) + break; + else + continue; + else if(!strcasecmp(l, "NetName")) + continue; + + // Check the list of known variables + bool found = false; + int i; + for(i = 0; variables[i].name; i++) { + if(strcasecmp(l, variables[i].name)) + continue; + found = true; + break; + } + + // Ignore unknown and unsafe variables + if(!found) { + fprintf(stderr, "Ignoring unknown variable '%s' in invitation.\n", l); + continue; + } else if(!(variables[i].type & VAR_SAFE)) { + fprintf(stderr, "Ignoring unsafe variable '%s' in invitation.\n", l); + continue; + } + + // Copy the safe variable to the right config file + fprintf(variables[i].type & VAR_HOST ? fh : f, "%s = %s\n", l, value); + } + + fclose(f); + free(filename); + + while(l && !strcasecmp(l, "Name")) { + if(!check_id(value)) { + fprintf(stderr, "Invalid Name found in invitation.\n"); + return false; + } + + if(!strcmp(value, name)) { + fprintf(stderr, "Secondary chunk would overwrite our own host config file.\n"); + return false; + } + + xasprintf(&filename, "%s" SLASH "%s", hosts_dir, value); + f = fopen(filename, "w"); + + if(!f) { + fprintf(stderr, "Could not create file %s: %s\n", filename, strerror(errno)); + return false; + } + + while((l = get_line(&p))) { + if(!strcmp(l, "#---------------------------------------------------------------#")) + continue; + int len = strcspn(l, "\t ="); + if(len == 4 && !strncasecmp(l, "Name", 4)) { + value = l + len; + value += strspn(value, "\t "); + if(*value == '=') { + value++; + value += strspn(value, "\t "); + } + l[len] = 0; + break; + } + + fputs(l, f); + fputc('\n', f); + } + + fclose(f); + free(filename); + } + + // Generate our key and send a copy to the server + ecdsa_t *key = ecdsa_generate(); + if(!key) + return false; + + char *b64key = ecdsa_get_base64_public_key(key); + if(!b64key) + return false; + + xasprintf(&filename, "%s" SLASH "ecdsa_key.priv", confbase); + f = fopenmask(filename, "w", 0600); + + if(!ecdsa_write_pem_private_key(key, f)) { + fprintf(stderr, "Error writing private key!\n"); + ecdsa_free(key); + fclose(f); + return false; + } + + fclose(f); + + fprintf(fh, "ECDSAPublicKey = %s\n", b64key); + + sptps_send_record(&sptps, 1, b64key, strlen(b64key)); + free(b64key); + + + rsa_t *rsa = rsa_generate(2048, 0x1001); + xasprintf(&filename, "%s" SLASH "rsa_key.priv", confbase); + f = fopenmask(filename, "w", 0600); + + rsa_write_pem_private_key(rsa, f); + fclose(f); + + rsa_write_pem_public_key(rsa, fh); + fclose(fh); + + ecdsa_free(key); + rsa_free(rsa); + + check_port(name); + + fprintf(stderr, "Invitation succesfully accepted.\n"); + shutdown(sock, SHUT_RDWR); + success = true; + +ask_netname: + if(ask_netname) { + fprintf(stderr, "Enter a new netname: "); + if(!fgets(line, sizeof line, stdin)) { + fprintf(stderr, "Error while reading stdin: %s\n", strerror(errno)); + return false; + } + if(!*line || *line == '\n') + goto ask_netname; + + line[strlen(line) - 1] = 0; + + char *newbase; + xasprintf(&newbase, CONFDIR SLASH "tinc" SLASH "%s", line); + if(rename(confbase, newbase)) { + fprintf(stderr, "Error trying to rename %s to %s: %s\n", confbase, newbase, strerror(errno)); + free(newbase); + goto ask_netname; + } + + free(newbase); + netname = line; + make_names(); + } + + return true; +} + +static bool invitation_send(void *handle, uint8_t type, const char *data, size_t len) { + while(len) { + int result = send(sock, data, len, 0); + if(result == -1 && errno == EINTR) + continue; + else if(result <= 0) + return false; + data += result; + len -= result; + } + return true; +} + +static bool invitation_receive(void *handle, uint8_t type, const char *msg, uint16_t len) { + switch(type) { + case SPTPS_HANDSHAKE: + return sptps_send_record(&sptps, 0, cookie, sizeof cookie); + + case 0: + data = xrealloc(data, datalen + len + 1); + memcpy(data + datalen, msg, len); + datalen += len; + data[datalen] = 0; + break; + + case 1: + return finalize_join(); + + default: + return false; + } + + return true; +} + +int cmd_join(int argc, char *argv[]) { + free(data); + data = NULL; + datalen = 0; + + if(argc > 2) { + fprintf(stderr, "Too many arguments!\n"); + return 1; + } + + // Make sure confbase exists and is accessible. + if(strcmp(confdir, confbase) && mkdir(confdir, 0755) && errno != EEXIST) { + fprintf(stderr, "Could not create directory %s: %s\n", confdir, strerror(errno)); + return 1; + } + + if(mkdir(confbase, 0777) && errno != EEXIST) { + fprintf(stderr, "Could not create directory %s: %s\n", confbase, strerror(errno)); + return 1; + } + + if(access(confbase, R_OK | W_OK | X_OK)) { + fprintf(stderr, "No permission to write in directory %s: %s\n", confbase, strerror(errno)); + return 1; + } + + // If a netname or explicit configuration directory is specified, check for an existing tinc.conf. + if((netname || confbasegiven) && !access(tinc_conf, F_OK)) { + fprintf(stderr, "Configuration file %s already exists!\n", tinc_conf); + return 1; + } + + // Either read the invitation from the command line or from stdin. + char *invitation; + + if(argc > 1) { + invitation = argv[1]; + } else { + if(tty) { + printf("Enter invitation URL: "); + fflush(stdout); + } + errno = EPIPE; + if(!fgets(line, sizeof line, stdin)) { + fprintf(stderr, "Error while reading stdin: %s\n", strerror(errno)); + return false; + } + invitation = line; + } + + // Parse the invitation URL. + rstrip(line); + + char *slash = strchr(invitation, '/'); + if(!slash) + goto invalid; + + *slash++ = 0; + + if(strlen(slash) != 48) + goto invalid; + + char *address = invitation; + char *port = NULL; + if(*address == '[') { + address++; + char *bracket = strchr(address, ']'); + if(!bracket) + goto invalid; + *bracket = 0; + if(bracket[1] == ':') + port = bracket + 2; + } else { + port = strchr(address, ':'); + if(port) + *port++ = 0; + } + + if(!port || !*port) + port = "655"; + + if(!b64decode(slash, hash, 18) || !b64decode(slash + 24, cookie, 18)) + goto invalid; + + // Generate a throw-away key for the invitation. + ecdsa_t *key = ecdsa_generate(); + if(!key) + return 1; + + char *b64key = ecdsa_get_base64_public_key(key); + + // Connect to the tinc daemon mentioned in the URL. + struct addrinfo *ai = str2addrinfo(address, port, SOCK_STREAM); + if(!ai) + return 1; + + sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); + if(sock <= 0) { + fprintf(stderr, "Could not open socket: %s\n", strerror(errno)); + return 1; + } + + if(connect(sock, ai->ai_addr, ai->ai_addrlen)) { + fprintf(stderr, "Could not connect to %s port %s: %s\n", address, port, strerror(errno)); + closesocket(sock); + return 1; + } + + fprintf(stderr, "Connected to %s port %s...\n", address, port); + + // Tell him we have an invitation, and give him our throw-away key. + int len = snprintf(line, sizeof line, "0 ?%s %d.%d\n", b64key, PROT_MAJOR, PROT_MINOR); + if(len <= 0 || len >= sizeof line) + abort(); + + if(!sendline(sock, "0 ?%s %d.%d", b64key, PROT_MAJOR, 1)) { + fprintf(stderr, "Error sending request to %s port %s: %s\n", address, port, strerror(errno)); + closesocket(sock); + return 1; + } + + char hisname[4096] = ""; + int code, hismajor, hisminor = 0; + + if(!recvline(sock, line, sizeof line) || sscanf(line, "%d %s %d.%d", &code, hisname, &hismajor, &hisminor) < 3 || code != 0 || hismajor != PROT_MAJOR || !check_id(hisname) || !recvline(sock, line, sizeof line) || !rstrip(line) || sscanf(line, "%d ", &code) != 1 || code != ACK || strlen(line) < 3) { + fprintf(stderr, "Cannot read greeting from peer\n"); + closesocket(sock); + return 1; + } + + // Check if the hash of the key he gave us matches the hash in the URL. + char *fingerprint = line + 2; + digest_t *digest = digest_open_by_name("sha256", 18); + if(!digest) + abort(); + char hishash[18]; + if(!digest_create(digest, fingerprint, strlen(fingerprint), hishash)) { + fprintf(stderr, "Could not create digest\n%s\n", line + 2); + return 1; + } + if(memcmp(hishash, hash, 18)) { + fprintf(stderr, "Peer has an invalid key!\n%s\n", line + 2); + return 1; + + } + + ecdsa_t *hiskey = ecdsa_set_base64_public_key(fingerprint); + if(!hiskey) + return 1; + + // Start an SPTPS session + if(!sptps_start(&sptps, NULL, true, false, key, hiskey, "tinc invitation", 15, invitation_send, invitation_receive)) + return 1; + + // Feed rest of input buffer to SPTPS + if(!sptps_receive_data(&sptps, buffer, blen)) + return 1; + + while((len = recv(sock, line, sizeof line, 0))) { + if(len < 0) { + if(errno == EINTR) + continue; + fprintf(stderr, "Error reading data from %s port %s: %s\n", address, port, strerror(errno)); + return 1; + } + + if(!sptps_receive_data(&sptps, line, len)) + return 1; + } + + sptps_stop(&sptps); + ecdsa_free(hiskey); + ecdsa_free(key); + closesocket(sock); + + if(!success) { + fprintf(stderr, "Connection closed by peer, invitation cancelled.\n"); + return 1; + } + + return 0; + +invalid: + fprintf(stderr, "Invalid invitation URL.\n"); + return 1; +} diff --git a/src/invitation.h b/src/invitation.h new file mode 100644 index 0000000..3d017e9 --- /dev/null +++ b/src/invitation.h @@ -0,0 +1,27 @@ +/* + invitation.h -- header for invitation.c. + Copyright (C) 2013 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#ifndef __TINC_INVITATION_H__ +#define __TINC_INVITATION_H__ + +bool recvdata(int fd, char *data, size_t len); +int cmd_invite(int argc, char *argv[]); +int cmd_join(int argc, char *argv[]); + +#endif diff --git a/src/linux/.deps/.dirstamp b/src/linux/.deps/.dirstamp new file mode 100644 index 0000000..e69de29 diff --git a/src/linux/.deps/device.Po b/src/linux/.deps/device.Po new file mode 100644 index 0000000..8541068 --- /dev/null +++ b/src/linux/.deps/device.Po @@ -0,0 +1,467 @@ +linux/device.o: linux/device.c /usr/include/stdc-predef.h \ + /usr/include/x86_64-linux-gnu/bits/predefs.h linux/../system.h \ + linux/../../config.h linux/../have.h /usr/include/stdio.h \ + /usr/include/features.h /usr/include/x86_64-linux-gnu/sys/cdefs.h \ + /usr/include/x86_64-linux-gnu/bits/wordsize.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ + /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stddef.h \ + /usr/include/x86_64-linux-gnu/bits/types.h \ + /usr/include/x86_64-linux-gnu/bits/typesizes.h /usr/include/libio.h \ + /usr/include/_G_config.h /usr/include/wchar.h \ + /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdarg.h \ + /usr/include/x86_64-linux-gnu/bits/stdio_lim.h \ + /usr/include/x86_64-linux-gnu/bits/sys_errlist.h \ + /usr/include/x86_64-linux-gnu/bits/stdio.h /usr/include/stdlib.h \ + /usr/include/x86_64-linux-gnu/bits/waitflags.h \ + /usr/include/x86_64-linux-gnu/bits/waitstatus.h /usr/include/endian.h \ + /usr/include/x86_64-linux-gnu/bits/endian.h \ + /usr/include/x86_64-linux-gnu/bits/byteswap.h \ + /usr/include/x86_64-linux-gnu/bits/byteswap-16.h /usr/include/xlocale.h \ + /usr/include/x86_64-linux-gnu/sys/types.h /usr/include/time.h \ + /usr/include/x86_64-linux-gnu/sys/select.h \ + /usr/include/x86_64-linux-gnu/bits/select.h \ + /usr/include/x86_64-linux-gnu/bits/sigset.h \ + /usr/include/x86_64-linux-gnu/bits/time.h \ + /usr/include/x86_64-linux-gnu/sys/sysmacros.h \ + /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h /usr/include/alloca.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib-float.h /usr/include/string.h \ + /usr/include/x86_64-linux-gnu/bits/string.h \ + /usr/include/x86_64-linux-gnu/bits/string2.h /usr/include/ctype.h \ + /usr/include/signal.h /usr/include/x86_64-linux-gnu/bits/signum.h \ + /usr/include/x86_64-linux-gnu/bits/siginfo.h \ + /usr/include/x86_64-linux-gnu/bits/sigaction.h \ + /usr/include/x86_64-linux-gnu/bits/sigcontext.h \ + /usr/include/x86_64-linux-gnu/bits/sigstack.h \ + /usr/include/x86_64-linux-gnu/sys/ucontext.h \ + /usr/include/x86_64-linux-gnu/bits/sigthread.h /usr/include/errno.h \ + /usr/include/x86_64-linux-gnu/bits/errno.h /usr/include/linux/errno.h \ + /usr/include/x86_64-linux-gnu/asm/errno.h \ + /usr/include/asm-generic/errno.h /usr/include/asm-generic/errno-base.h \ + /usr/include/fcntl.h /usr/include/x86_64-linux-gnu/bits/fcntl.h \ + /usr/include/x86_64-linux-gnu/bits/fcntl-linux.h \ + /usr/include/x86_64-linux-gnu/bits/uio.h \ + /usr/include/x86_64-linux-gnu/bits/stat.h /usr/include/unistd.h \ + /usr/include/x86_64-linux-gnu/bits/posix_opt.h \ + /usr/include/x86_64-linux-gnu/bits/environments.h \ + /usr/include/x86_64-linux-gnu/bits/confname.h /usr/include/getopt.h \ + /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdbool.h \ + /usr/include/inttypes.h \ + /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdint.h /usr/include/stdint.h \ + /usr/include/x86_64-linux-gnu/bits/wchar.h /usr/include/syslog.h \ + /usr/include/x86_64-linux-gnu/sys/syslog.h \ + /usr/include/x86_64-linux-gnu/bits/syslog-path.h \ + /usr/include/x86_64-linux-gnu/sys/time.h \ + /usr/include/x86_64-linux-gnu/bits/timex.h \ + /usr/include/x86_64-linux-gnu/sys/stat.h \ + /usr/include/x86_64-linux-gnu/sys/file.h \ + /usr/include/x86_64-linux-gnu/sys/wait.h \ + /usr/include/x86_64-linux-gnu/sys/ioctl.h \ + /usr/include/x86_64-linux-gnu/bits/ioctls.h \ + /usr/include/x86_64-linux-gnu/asm/ioctls.h \ + /usr/include/asm-generic/ioctls.h /usr/include/linux/ioctl.h \ + /usr/include/x86_64-linux-gnu/asm/ioctl.h \ + /usr/include/asm-generic/ioctl.h \ + /usr/include/x86_64-linux-gnu/bits/ioctl-types.h \ + /usr/include/x86_64-linux-gnu/sys/ttydefaults.h \ + /usr/include/x86_64-linux-gnu/sys/param.h \ + /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/limits.h \ + /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/syslimits.h \ + /usr/include/limits.h /usr/include/x86_64-linux-gnu/bits/posix1_lim.h \ + /usr/include/x86_64-linux-gnu/bits/local_lim.h \ + /usr/include/linux/limits.h \ + /usr/include/x86_64-linux-gnu/bits/posix2_lim.h \ + /usr/include/x86_64-linux-gnu/bits/xopen_lim.h \ + /usr/include/x86_64-linux-gnu/bits/param.h /usr/include/linux/param.h \ + /usr/include/x86_64-linux-gnu/asm/param.h \ + /usr/include/asm-generic/param.h \ + /usr/include/x86_64-linux-gnu/sys/resource.h \ + /usr/include/x86_64-linux-gnu/bits/resource.h \ + /usr/include/x86_64-linux-gnu/sys/uio.h \ + /usr/include/x86_64-linux-gnu/sys/un.h \ + /usr/include/x86_64-linux-gnu/bits/sockaddr.h /usr/include/dirent.h \ + /usr/include/x86_64-linux-gnu/bits/dirent.h /usr/include/netdb.h \ + /usr/include/netinet/in.h /usr/include/x86_64-linux-gnu/sys/socket.h \ + /usr/include/x86_64-linux-gnu/bits/socket.h \ + /usr/include/x86_64-linux-gnu/bits/socket_type.h \ + /usr/include/x86_64-linux-gnu/asm/socket.h \ + /usr/include/asm-generic/socket.h \ + /usr/include/x86_64-linux-gnu/asm/sockios.h \ + /usr/include/asm-generic/sockios.h \ + /usr/include/x86_64-linux-gnu/bits/in.h /usr/include/rpc/netdb.h \ + /usr/include/x86_64-linux-gnu/bits/netdb.h /usr/include/net/if.h \ + /usr/include/netinet/in_systm.h /usr/include/arpa/inet.h \ + /usr/include/netinet/ip.h /usr/include/netinet/tcp.h \ + /usr/include/netinet/ip6.h /usr/include/net/ethernet.h \ + /usr/include/linux/if_ether.h /usr/include/linux/types.h \ + /usr/include/x86_64-linux-gnu/asm/types.h \ + /usr/include/asm-generic/types.h /usr/include/asm-generic/int-ll64.h \ + /usr/include/x86_64-linux-gnu/asm/bitsperlong.h \ + /usr/include/asm-generic/bitsperlong.h /usr/include/linux/posix_types.h \ + /usr/include/linux/stddef.h \ + /usr/include/x86_64-linux-gnu/asm/posix_types.h \ + /usr/include/x86_64-linux-gnu/asm/posix_types_64.h \ + /usr/include/asm-generic/posix_types.h /usr/include/net/if_arp.h \ + /usr/include/netinet/ip_icmp.h /usr/include/netinet/icmp6.h \ + /usr/include/netinet/if_ether.h linux/../dropin.h \ + linux/../fake-getaddrinfo.h linux/../fake-gai-errnos.h \ + linux/../fake-getnameinfo.h /usr/include/linux/if_tun.h \ + /usr/include/linux/filter.h linux/../conf.h linux/../splay_tree.h \ + linux/../list.h linux/../subnet.h linux/../net.h linux/../ipv6.h \ + linux/../cipher.h linux/../digest.h linux/../event.h linux/../conf.h \ + linux/../connection.h linux/../buffer.h linux/../rsa.h linux/../sptps.h \ + linux/../system.h linux/../ecdh.h linux/../ecdsa.h linux/../edge.h \ + linux/../node.h linux/../device.h linux/../logger.h linux/../names.h \ + linux/../net.h linux/../route.h linux/../utils.h linux/../xalloc.h + +/usr/include/stdc-predef.h: + +/usr/include/x86_64-linux-gnu/bits/predefs.h: + +linux/../system.h: + +linux/../../config.h: + +linux/../have.h: + +/usr/include/stdio.h: + +/usr/include/features.h: + +/usr/include/x86_64-linux-gnu/sys/cdefs.h: + +/usr/include/x86_64-linux-gnu/bits/wordsize.h: + +/usr/include/x86_64-linux-gnu/gnu/stubs.h: + +/usr/include/x86_64-linux-gnu/gnu/stubs-64.h: + +/usr/lib/gcc/x86_64-linux-gnu/4.8/include/stddef.h: + +/usr/include/x86_64-linux-gnu/bits/types.h: + +/usr/include/x86_64-linux-gnu/bits/typesizes.h: + +/usr/include/libio.h: + +/usr/include/_G_config.h: + +/usr/include/wchar.h: + +/usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdarg.h: + +/usr/include/x86_64-linux-gnu/bits/stdio_lim.h: + +/usr/include/x86_64-linux-gnu/bits/sys_errlist.h: + +/usr/include/x86_64-linux-gnu/bits/stdio.h: + +/usr/include/stdlib.h: + +/usr/include/x86_64-linux-gnu/bits/waitflags.h: + +/usr/include/x86_64-linux-gnu/bits/waitstatus.h: + +/usr/include/endian.h: + +/usr/include/x86_64-linux-gnu/bits/endian.h: + +/usr/include/x86_64-linux-gnu/bits/byteswap.h: + +/usr/include/x86_64-linux-gnu/bits/byteswap-16.h: + +/usr/include/xlocale.h: + +/usr/include/x86_64-linux-gnu/sys/types.h: + +/usr/include/time.h: + +/usr/include/x86_64-linux-gnu/sys/select.h: + +/usr/include/x86_64-linux-gnu/bits/select.h: + +/usr/include/x86_64-linux-gnu/bits/sigset.h: + +/usr/include/x86_64-linux-gnu/bits/time.h: + +/usr/include/x86_64-linux-gnu/sys/sysmacros.h: + +/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h: + +/usr/include/alloca.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib-float.h: + +/usr/include/string.h: + +/usr/include/x86_64-linux-gnu/bits/string.h: + +/usr/include/x86_64-linux-gnu/bits/string2.h: + +/usr/include/ctype.h: + +/usr/include/signal.h: + +/usr/include/x86_64-linux-gnu/bits/signum.h: + +/usr/include/x86_64-linux-gnu/bits/siginfo.h: + +/usr/include/x86_64-linux-gnu/bits/sigaction.h: + +/usr/include/x86_64-linux-gnu/bits/sigcontext.h: + +/usr/include/x86_64-linux-gnu/bits/sigstack.h: + +/usr/include/x86_64-linux-gnu/sys/ucontext.h: + +/usr/include/x86_64-linux-gnu/bits/sigthread.h: + +/usr/include/errno.h: + +/usr/include/x86_64-linux-gnu/bits/errno.h: + +/usr/include/linux/errno.h: + +/usr/include/x86_64-linux-gnu/asm/errno.h: + +/usr/include/asm-generic/errno.h: + +/usr/include/asm-generic/errno-base.h: + +/usr/include/fcntl.h: + +/usr/include/x86_64-linux-gnu/bits/fcntl.h: + +/usr/include/x86_64-linux-gnu/bits/fcntl-linux.h: + +/usr/include/x86_64-linux-gnu/bits/uio.h: + +/usr/include/x86_64-linux-gnu/bits/stat.h: + +/usr/include/unistd.h: + +/usr/include/x86_64-linux-gnu/bits/posix_opt.h: + +/usr/include/x86_64-linux-gnu/bits/environments.h: + +/usr/include/x86_64-linux-gnu/bits/confname.h: + +/usr/include/getopt.h: + +/usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdbool.h: + +/usr/include/inttypes.h: + +/usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdint.h: + +/usr/include/stdint.h: + +/usr/include/x86_64-linux-gnu/bits/wchar.h: + +/usr/include/syslog.h: + +/usr/include/x86_64-linux-gnu/sys/syslog.h: + +/usr/include/x86_64-linux-gnu/bits/syslog-path.h: + +/usr/include/x86_64-linux-gnu/sys/time.h: + +/usr/include/x86_64-linux-gnu/bits/timex.h: + +/usr/include/x86_64-linux-gnu/sys/stat.h: + +/usr/include/x86_64-linux-gnu/sys/file.h: + +/usr/include/x86_64-linux-gnu/sys/wait.h: + +/usr/include/x86_64-linux-gnu/sys/ioctl.h: + +/usr/include/x86_64-linux-gnu/bits/ioctls.h: + +/usr/include/x86_64-linux-gnu/asm/ioctls.h: + +/usr/include/asm-generic/ioctls.h: + +/usr/include/linux/ioctl.h: + +/usr/include/x86_64-linux-gnu/asm/ioctl.h: + +/usr/include/asm-generic/ioctl.h: + +/usr/include/x86_64-linux-gnu/bits/ioctl-types.h: + +/usr/include/x86_64-linux-gnu/sys/ttydefaults.h: + +/usr/include/x86_64-linux-gnu/sys/param.h: + +/usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/limits.h: + +/usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/syslimits.h: + +/usr/include/limits.h: + +/usr/include/x86_64-linux-gnu/bits/posix1_lim.h: + +/usr/include/x86_64-linux-gnu/bits/local_lim.h: + +/usr/include/linux/limits.h: + +/usr/include/x86_64-linux-gnu/bits/posix2_lim.h: + +/usr/include/x86_64-linux-gnu/bits/xopen_lim.h: + +/usr/include/x86_64-linux-gnu/bits/param.h: + +/usr/include/linux/param.h: + +/usr/include/x86_64-linux-gnu/asm/param.h: + +/usr/include/asm-generic/param.h: + +/usr/include/x86_64-linux-gnu/sys/resource.h: + +/usr/include/x86_64-linux-gnu/bits/resource.h: + +/usr/include/x86_64-linux-gnu/sys/uio.h: + +/usr/include/x86_64-linux-gnu/sys/un.h: + +/usr/include/x86_64-linux-gnu/bits/sockaddr.h: + +/usr/include/dirent.h: + +/usr/include/x86_64-linux-gnu/bits/dirent.h: + +/usr/include/netdb.h: + +/usr/include/netinet/in.h: + +/usr/include/x86_64-linux-gnu/sys/socket.h: + +/usr/include/x86_64-linux-gnu/bits/socket.h: + +/usr/include/x86_64-linux-gnu/bits/socket_type.h: + +/usr/include/x86_64-linux-gnu/asm/socket.h: + +/usr/include/asm-generic/socket.h: + +/usr/include/x86_64-linux-gnu/asm/sockios.h: + +/usr/include/asm-generic/sockios.h: + +/usr/include/x86_64-linux-gnu/bits/in.h: + +/usr/include/rpc/netdb.h: + +/usr/include/x86_64-linux-gnu/bits/netdb.h: + +/usr/include/net/if.h: + +/usr/include/netinet/in_systm.h: + +/usr/include/arpa/inet.h: + +/usr/include/netinet/ip.h: + +/usr/include/netinet/tcp.h: + +/usr/include/netinet/ip6.h: + +/usr/include/net/ethernet.h: + +/usr/include/linux/if_ether.h: + +/usr/include/linux/types.h: + +/usr/include/x86_64-linux-gnu/asm/types.h: + +/usr/include/asm-generic/types.h: + +/usr/include/asm-generic/int-ll64.h: + +/usr/include/x86_64-linux-gnu/asm/bitsperlong.h: + +/usr/include/asm-generic/bitsperlong.h: + +/usr/include/linux/posix_types.h: + +/usr/include/linux/stddef.h: + +/usr/include/x86_64-linux-gnu/asm/posix_types.h: + +/usr/include/x86_64-linux-gnu/asm/posix_types_64.h: + +/usr/include/asm-generic/posix_types.h: + +/usr/include/net/if_arp.h: + +/usr/include/netinet/ip_icmp.h: + +/usr/include/netinet/icmp6.h: + +/usr/include/netinet/if_ether.h: + +linux/../dropin.h: + +linux/../fake-getaddrinfo.h: + +linux/../fake-gai-errnos.h: + +linux/../fake-getnameinfo.h: + +/usr/include/linux/if_tun.h: + +/usr/include/linux/filter.h: + +linux/../conf.h: + +linux/../splay_tree.h: + +linux/../list.h: + +linux/../subnet.h: + +linux/../net.h: + +linux/../ipv6.h: + +linux/../cipher.h: + +linux/../digest.h: + +linux/../event.h: + +linux/../conf.h: + +linux/../connection.h: + +linux/../buffer.h: + +linux/../rsa.h: + +linux/../sptps.h: + +linux/../system.h: + +linux/../ecdh.h: + +linux/../ecdsa.h: + +linux/../edge.h: + +linux/../node.h: + +linux/../device.h: + +linux/../logger.h: + +linux/../names.h: + +linux/../net.h: + +linux/../route.h: + +linux/../utils.h: + +linux/../xalloc.h: diff --git a/src/linux/.dirstamp b/src/linux/.dirstamp new file mode 100644 index 0000000..e69de29 diff --git a/src/linux/device.c b/src/linux/device.c index e262c6a..127e3e8 100644 --- a/src/linux/device.c +++ b/src/linux/device.c @@ -18,20 +18,20 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#include "system.h" +#include "../system.h" #include #define DEFAULT_DEVICE "/dev/net/tun" -#include "conf.h" -#include "device.h" -#include "logger.h" -#include "names.h" -#include "net.h" -#include "route.h" -#include "utils.h" -#include "xalloc.h" -#include "device.h" +#include "../conf.h" +#include "../device.h" +#include "../logger.h" +#include "../names.h" +#include "../net.h" +#include "../route.h" +#include "../utils.h" +#include "../xalloc.h" +#include "../device.h" typedef enum device_type_t { DEVICE_TYPE_TUN, @@ -84,6 +84,8 @@ static bool setup_device(void) { device_type = DEVICE_TYPE_TUN; device_info = "Linux tun/tap device (tun mode)"; } else { + if (routing_mode == RMODE_ROUTER) + overwrite_mac = true; ifr.ifr_flags = IFF_TAP | IFF_NO_PI; device_type = DEVICE_TYPE_TAP; device_info = "Linux tun/tap device (tap mode)"; diff --git a/src/linux/device.o b/src/linux/device.o new file mode 100644 index 0000000000000000000000000000000000000000..650284357e0010cc29a196a64c5cb9a715026613 GIT binary patch literal 24392 zcmb_^3z(F}m3DpIGh;J%7%qc=H20fx<1Ppc43`-}KxPn#nx*t-u>-S20nwR-CG6I4v3uy`PhQ3QDzjqyFIO z^r{2zd6@;x6{o5WFGKt0BdJnjz`@gdE+gFEd_bG(HGBH}G`f1#H%X7C(b;Z0`njet z>ba)T>cDS{n>&6WlJ@=|qjj-9iD{uk3g zv;86^qglx-IVCp+51cM;KGReRnP-|t;zTOnJls_=@fH-=!GBv%_@Ct(FiX|$Uf@X#48^On<@3r}TjZ6?><@}!U29MVI~&2$S*ciT>4M)Se* z=~2c=i0B<4g2vPr$c~SZUUAz`DTGcSj1HYSNlj>Ej11FJqwLJ;sg*FWnKIRq2})+B zWa^R8t@CVbK0HA)4*s;_mVYKqT=`4QBvTLmo~pG8XLOG>IhXA^)HXF}d*Qj&Q!9*` z<|FB;70p>Urc3tSKvfk7Un3FChZkr;N3Nb)*?jPwblC}Xq4|(eYkJpky7|ygPM&Qm zXk=S5i<$KcYe1|aw@~H$6Led#4n z`^Z@10t`*F?Tyt_gKzx%U(cVX5L->re)EQ@K^1(X?ELxjko%l=q4(yqJYRLk4x9Mr zWvu0pnSA+k9Hv?G9IpAXnWK3N!5f!oMPh2j!7Hfz#&WVpYf@A?PZnoWYdV~crqa=l zRIn?N3{FeY-x3u}C(_|quzhbjk_txSOM<~^4fU~1KAy;=moVNGj?YL3cPFFi2sLFX zbW*D${n3tys_TsO*Tp00x^yP4TH@(QvMWq*Qz8@V48{}bV4^P)hvreG)R`Fut zJM)OEl^4F-PPLr>Gx!06{{{IOErRIdu})8kNG_*rz)`1K)VIsZ9ym&f7r?F3iS zC@vwaDDV`ON-&@>yYyp}0gB<&=w}42BJ^`qCkb_I(x&a zID>qZR#n`O{76+*S-k%g3DkE(#kU}9)ITrkD^yi=@vT?Wd^VgzryHhVOez4OYf+`DoXeKME5`(A2hyfCx)#+%6?)02a62`Ftb zFRA{KkV?iQYe*#%G^`t!OhVpF=aR|Do9SFK1^J-i%s{};q)~uQJ(eZ2a@jd&2r}r! ze<4Cqz+b4;sB${!h!JDzItVcW=ON4a`5HF(V&vJFC9ma-S$ZyK%rbZk#{4X6%nInz z(Ge^i_Yb0_bo?X4G+Ih0AaA0h^djVqmePrkR&C5L4W_BB?n&7qjMixSsN0LmS__LP zgkq7nDrkzC)jdK-f0WAOQ&hr2Hla`X>H({ZaPYo?BhoeI zq`dq8O8kjjQj;r``Z57QZ>v`y^xC{dLGOxTm^3Ek5nucO;v{JSi9<P98t{&VIS^M*P453Fv=x8nUmBL(K|Cb#%F_z{Ys70Ld?w?54?5rW5 zC*9e?vuYbr*-Yly&Lzr1^2;QE*wIpEVhdRI0|7T@HkjcWF_HCBN37w7764 zt1BxEx*TCuO!i{oL4`?uR#-MFAuQi$E687^%6%k|;>hY%w$p`lBYu47YP3E%bTwN4 zeCX=gRQ-;r_7~G;L00P;su)4LESSP`DGa@aTpd(4n7W}1-aK^mPLiC_)mwe3p*jr} zcMmP&dXn)aQ;l%SnRXvloVA2s;Wg$ePg3QZrd44nHUX$#WI~RB)}ttP^M*=KZ-O8y z8y%PfSzlqMuQ$!i+Psk1gLwvB?=!>!UC)XhFvauqe8tw|tZ&(H`+!9-=xsrlRUKm4 zn~iH%&Qb%`;Iia`wYZ0KL494zf%TAC^cZgNP4)}fZ0XcVH1!)m@Md8p&9yS%oP4DQ zym&CMp)k)9!<;)9IBzg;{$Sv@|4a)(&ZM%3$ynWm;TOULovp0FErH3-#X>e0y{Tx% zHL3z#G6!7T=c)Oq8xi*&qY{=SQ};5JDr!)rx2i_^d<#*ip8FN5&`qj7tsfL|70^vs zP>&Xb_1OqILamG-qbRH&#}JgJm0sXS{>sC;QvtG(Gip>Jx`WA80Xvm`_9$&QPXIm@ z7^DhN=u(NBP*cAEy`5M|Rr-L38mga0Kv|YF`mT0Dv1(|^+KhRo{pdreLhKvkQDP5O zjr5^}>1>)=R?UOfW2n(ukt3}DFQJ^d`%NHyU%a@caEoq_k+doy6lq{!ux|!rG-F_5S5K7u{0_%b*&tG0r zf<_({17%qWi-|Uji-j#!C>D!+dMNX}mMXL;rJbg#I;t$2P8qrkjq+xUHB}Xb8mXL4 z1`i*lX3$;c2oe}D7D8av7%!)LWKK7&T@VBLqqTvBV&E99j>fYZ0-h=?Fojg|koahXrcyHnd32vAqLrFXrdXsIhQzXG=Ir#5;#m`@ z^%igInC&Gybf;z)s)j1ao>M|7-D}L}at)X;MwqoF)Rhr5^Xn{qB(gqNTru`i8l?ss zfYQ0O-ioo}%}cds<`JysXYoRK+0-nkRZJ!j;udBBJr;l#*$qvz#aW1182w9fV7xr1 zVo44*Alb5$K1es2lk(J7$$l#fwMzD%87fe3ds~l7X{O#Eq`9S9B|D2DL*!Q3Q$5#S zo^7~QviD`7R>|IBHVScc1x)qD!h1vMWF$gmQq_@&qlR*1v&pbk z8jK~nyCV=sge1LX;a2f*uQrO%Oq|}?bP_{bm86#zlJ6vYB@cWq708mVj(9p|@Mxk# zXK9U$B$ILUjR=>vXQHumO*FpTjQTLrVv_%#Ja2vA?ZBOZ^)3F;{z+e37Fgjge#KuB zNVgp5-{If8-Jjfl=74|Lxoy5VBmE_{{%3AFI;tbM!e4$gu>3avuuGF0mh}JS;8i>P z{aya({=o7pmcF{|DNU}d^>6vn`X|2r^-PQZ*_(beY1{e&pMP)Q#PI^}Q~kclRaDBH z*g+S+lB4~B`ipyFfq75+YDNYoD_?9vRFg+ht0u25R7UbAZJy3pn=o7y%tZQ7thEt^7kT@>m|Csm?9lGN|MLcQS*73$~- zN8>6L{YZq`)%7HLBNWz=WU8(^lS$RlTd9tkhT4X@RFb%?0wrtwkwq}ctRSL~yyrXZgwu{7t+QTHx z*ks;-saS&EZ0SQLo{DzIBc1eOPx{rgY2(HHfkHnvjGCL_BjF!!WYGTPmfwpyYA zx1~-dRR~sgX8Kg9i{78b6Dk$iMaQgjBJoZIlc^cSccL#vwrdl#AU!GK^mdF;l0(6m zNJ4ui)EQ2PNoFkEoq`T_rI{ijnh+t=C#s}jKzE@CvolU~9mvr*Ow%sW5^0|GhEvz6 zP$Jfe5lzurA!oBrWtRm#RcMN4$ZEJTgt@JvacssCHKO`x$gC+%*7t{F^a2vb^oEny zMUtvF(o6co#LIIw4=p<(uZrVqWz+gKZCVl!9)%b8yQ@=azv%w-(o0btG9go|bRY%u zL?-cOk*uS>W9iURQ{n!I367|K1KXF3Cg@Em1x}~~{Umy4rnir!q7Ss>hG>l>*Xi+? zt3nV(&Wy?`w95{ho>x5L+9PIQF<~&rRH#24ZjVJIb`fZB z1qEk!xe6fkx7zIW0_u>;53YS<<(0ZN;;(^qcqQ)=9|-k+z^vL%=K7>GI3hRJLj@L zHg3|=%pgb25}+eZrX9Bgiu_5PS9@lx~8Tj!I`Tg?a^@DsIFN&%Vf-pPP*anKC(r5dn&zgr56N_(jD4J z!p8HRhQKoCB0Lw<+qe?_6K~$<&`V7h+~v%Di1W%Q@*NA z?d_$hN#}IZoO>jfjKspVXTU0GAroFgg*V6ZLBDEAJH1rfrEH=^; z>Pq5j^8YCXNe&G&?vnFTBbVH#4{R&h32*G^_H{tIO%Eo$v&7g?qUUj~N1lc7WRHY> z8|cqI{{f_Ql%IZF*=`we0-0|62f6*#5N0LUe(Z-rzuuj+c+&n~Eeu(3k>uRSdAI!@ zcIcBJTS@va?c1mh`RwgJa~tXL0BNQr`N+{HlM z$a*h!9P4tgC+=YOZ~ri)@CG)W5x?{r-etd~&u=YRU_P_Zb{P(3H?0=f=mpFs}hSSHj|0L_Lr?Z_-2Tf@` z$D!1Tt#Zb-2YI)B2~QmEhBVLiRoef6+h+-!naS;4T-pi#8fAbvZc@_zv=I3${TKLG zlo@RNzt8@&=P$mTBJIVm@Tt4@LH6rx{~u7Wl5789wuAm4JG7D4QGB-pQ_9tkIX#&E zm-H(er5<(^Iz?(dcml6L{o(vzwf^iV=GXcMwFLGJ=3(I6IZF(_l;^YLU&D2{2l7ac z#F_X3)&2ojPqS`A&Q1_0>3bwP!!3}r9UvvKY$fHvm(AW+bgfdCGalps3~%9XTLX)U+1T< ztqqp^dZidx<5#p>KS=VcQG=k+tG~`Qpw6GY+s##_DLb6}$gKt4YPLSFmiJbBw_!ka=;}ywZ@|O&OHw}TW9|GSz1b*cZcz6hW*AV#L zA@G}qz;7P{znAdg);yhQ+-hy758OA(KF88_Ox|9ky}w~UuIBA%ncWX;-N*wqo@DXp z!4KB_Sf16wPqtjnJ?b(*`)Aq+`&n4_M26U|pywg8E2*EhbBd&y*|gQ$4rV*e-oD7+ z3L3bxo83H>{W-n&Wp*D)v24Cr4fPHaRhex~Y~$zej^*z|=eD#kRB{`GWf|AeKjViW zl;j&#z_BLac?L;VI$V$JtJEZ2YwkC2O%gd050Ha<9>HsvFLGo>T*^53wwzTKei7wG z&N{|LPA!+C7T>mim&KR44`?6buHKJXIOO2D2Hxn{scfu!0mp?bs6|%`iLBP?gKv2!r!7i67V2>g#QlZk$_L3kKkB0k$_L7kKhF~ zpOJvu@laynwm+*F7yqx-t*MU|-yX-g7H<2q#lr1=wOaTzk}Y;dEZnvyW#M+beS~q? ziE-b|b{@9)(+QJtxzoaJ`#)>plZh|(JYnIs{rcx)#DhO=`(L*B_PD%m;r6)v&cf|+ zdB?(SKm3((>95SgQW!!BC%a$ME!?($j)l*lHqzg@77o1|=!3M#!l6_6%PritzsbUF z{$&-2=hx9!JQ&5&R}{3Ge>7T>o2ISa=cDRzF} z!fpFsvT)n~_^}NVPIkZEw(vTt6Z!93xE)s``IZya^%ft$Qb7W4`zOda`V0Sml0HaV zEWYiZZ5AK#Df2yK@ooQfS-2g~X-f|DJ^-bZZm{?bRF?jJ!oqF6_d2-D#|IcMAsGSs z^w9_Daf@&J;meGRA5I#&`kKYJ{qUTH&n2$d`7;Z*$Mha(g*1xi*L)HX5qFyvn||SALW`AOfJ`>&saFJ63>r0xWv`pGcIv;l=c3=;xDx1 zzii=C2$yku-NL6@`0p&-_RqVFi+?`KdJ8dmC?QU4|6Ihl@E_GIn)^fWmsq&%pY;|# znPiClJ6N8pw-o>-ob0&LARTb|MBPs2VQwM`9%Q`Iz*$`ON#r?I_&b>wbogA%?$p2! zBLt*#Dd&OH7aY}#MFtq|;J@bUz3ey$zma*^=R^{FOeuHm0AKFGQ78A&BIgoru$0e& zU&(%0<>1{M2Q3bcZ&D*k{ED1L#b5$dPmdXGHJy z95;s?T&@Q)Z-jp{%fHXzl-|1INk|1b9cf$_0CK7x;6JLS1R@Dld_ ze1|XhA4?rvo*&jZIDT}BBZcooa}M+cYth8G?D7Pj-(4lei2|KZ@{*bj0)DgOKhkC*uYa&Epa zWBV)kEd28<_d*As%=XCrr0`cUUhnYl;{Gmm@F%&v*1%?^%VS|J^A@M+Bdw1Xe!{yyU1<;;J|!A0-04*q$T^KA$JA@}!X z2md9@|91zkWk3AM!6hEXa9oQ&MgD9D53@ZD4qnXoLI-bVy)utQ{p#-*8wW4oaed3ddpI7>Irul2|0f5ReW*fSS7f~IU|xxXU&(TYJNPm7 zL$!m8{3#Cp2lh{$gST*8EpYIKT)x!7Mb0`0-^g}e>)_|uKYffNTp7|mxYfa@alan5 za2Bm=p0setS;740EgXD#X8W;)gMSV4|7hXh%X8g%#${ZdVg4`<7_omR<3YxS{}TIo zwuM(Q7pFQ$&MjQG(ZV^aYqncB?0=N`eGdLT#y{%dzi0fIgZ~%f4>`EU>&cfLd>Z3t zEgXJZ%W{6oxcK2Ij^|e`KJ1r$fImBY@mtX_BM@@nw~Q&O5(~%uUI4-c_zgt`5@Z|@SS6VnO6^$^0QoDu2Km9zuyDc3441rAPW(x=P0Q3LO!m(c}=|Kwz z^(p3m)xse^#SKnbIH;$X|AK|jVlGa` zZ{M=`Fh#y+_@546`sI}qiIVtP;-{E#kuUFKMmzjQ-I~55;qbr2<37jX*E4^IMPgG1@C#kbdiyB+>% zj)w;={&XWkAHU%6(`?UIE&c?Hf70R0_bSd>{7Dx7hYtS?%m1atzsTah?(kn@|NqhA zFS7W)3R93ck$u222fvx+R6F=omNmt}3)s#T4ld7+AqQW?@zCwy%NS2OcsIw}Z4NHa zt&cf)58HXt!T+A+f8W6;u>9XRxV%p-s?7IWoaN7PaM@>E>)^5<9d__PalGB&;1e0Y z-@%_`J0EiJ&$B(J9320y5$P&!hZCSKfRui3;ZWHKkP;84e!n2^)PS@2?0pC@q?ar? kJmoYV)JJnKY2%9>d?%N$c5r!K*yrFu7Iu$=%YEj51JTJk!vFvP literal 0 HcmV?d00001 diff --git a/src/list.c b/src/list.c index 2dd414a..0bbc5d4 100644 --- a/src/list.c +++ b/src/list.c @@ -1,7 +1,7 @@ /* list.c -- functions to deal with double linked lists Copyright (C) 2000-2005 Ivo Timmermans - 2000-2012 Guus Sliepen + 2000-2013 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 @@ -26,7 +26,7 @@ /* (De)constructors */ list_t *list_alloc(list_action_t delete) { - list_t *list = xmalloc_and_zero(sizeof(list_t)); + list_t *list = xzalloc(sizeof(list_t)); list->delete = delete; return list; @@ -37,7 +37,7 @@ void list_free(list_t *list) { } list_node_t *list_alloc_node(void) { - return xmalloc_and_zero(sizeof(list_node_t)); + return xzalloc(sizeof(list_node_t)); } void list_free_node(list_t *list, list_node_t *node) { diff --git a/src/meta.c b/src/meta.c index fafba65..887da4a 100644 --- a/src/meta.c +++ b/src/meta.c @@ -1,6 +1,6 @@ /* meta.c -- handle the meta communication - Copyright (C) 2000-2012 Guus Sliepen , + Copyright (C) 2000-2013 Guus Sliepen , 2000-2005 Ivo Timmermans 2006 Scott Lamb @@ -60,7 +60,7 @@ bool send_meta(connection_t *c, const char *buffer, int length) { if(c->status.encryptout) { size_t outlen = length; - if(!cipher_encrypt(&c->outcipher, buffer, length, buffer_prepare(&c->outbuf, length), &outlen, false) || outlen != length) { + if(!cipher_encrypt(c->outcipher, buffer, length, buffer_prepare(&c->outbuf, length), &outlen, false) || outlen != length) { logger(DEBUG_ALWAYS, LOG_ERR, "Error while encrypting metadata to %s (%s)", c->name, c->hostname); return false; @@ -171,7 +171,7 @@ bool receive_meta(connection_t *c) { } else { size_t outlen = inlen; - if(!cipher_decrypt(&c->incipher, bufp, inlen, buffer_prepare(&c->inbuf, inlen), &outlen, false) || inlen != outlen) { + if(!cipher_decrypt(c->incipher, bufp, inlen, buffer_prepare(&c->inbuf, inlen), &outlen, false) || inlen != outlen) { logger(DEBUG_ALWAYS, LOG_ERR, "Error while decrypting metadata from %s (%s)", c->name, c->hostname); return false; diff --git a/src/mingw/.deps/device.Po b/src/mingw/.deps/device.Po new file mode 100644 index 0000000..9ce06a8 --- /dev/null +++ b/src/mingw/.deps/device.Po @@ -0,0 +1 @@ +# dummy diff --git a/src/mingw/device.c b/src/mingw/device.c index ac83d8c..abe544e 100644 --- a/src/mingw/device.c +++ b/src/mingw/device.c @@ -18,21 +18,21 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#include "system.h" +#include "../system.h" #include #include -#include "conf.h" -#include "device.h" -#include "logger.h" -#include "names.h" -#include "net.h" -#include "route.h" -#include "utils.h" -#include "xalloc.h" +#include "../conf.h" +#include "../device.h" +#include "../logger.h" +#include "../names.h" +#include "../net.h" +#include "../route.h" +#include "../utils.h" +#include "../xalloc.h" -#include "mingw/common.h" +#include "common.h" int device_fd = -1; static HANDLE device_handle = INVALID_HANDLE_VALUE; diff --git a/src/multicast_device.c b/src/multicast_device.c index e58d293..5eaf103 100644 --- a/src/multicast_device.c +++ b/src/multicast_device.c @@ -1,7 +1,7 @@ /* device.c -- multicast socket Copyright (C) 2002-2005 Ivo Timmermans, - 2002-2012 Guus Sliepen + 2002-2013 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 diff --git a/src/names.c b/src/names.c index cc72a11..a631ad9 100644 --- a/src/names.c +++ b/src/names.c @@ -42,6 +42,9 @@ void make_names(void) { DWORD len = sizeof installdir; #endif + if(netname && confbase) + logger(DEBUG_ALWAYS, LOG_INFO, "Both netname and configuration directory given, using the latter..."); + if(netname) xasprintf(&identname, "tinc.%s", netname); else @@ -84,13 +87,10 @@ void make_names(void) { strcpy(unixsocketname + len, ".socket"); } - if(netname) { - if(!confbase) + if(!confbase) { + if(netname) xasprintf(&confbase, CONFDIR SLASH "tinc" SLASH "%s", netname); else - logger(DEBUG_ALWAYS, LOG_INFO, "Both netname and configuration directory given, using the latter..."); - } else { - if(!confbase) xasprintf(&confbase, CONFDIR SLASH "tinc"); } } diff --git a/src/net.c b/src/net.c index 1487e81..bf6cfcf 100644 --- a/src/net.c +++ b/src/net.c @@ -41,6 +41,8 @@ int contradicting_add_edge = 0; int contradicting_del_edge = 0; static int sleeptime = 10; time_t last_config_check = 0; +static timeout_t pingtimer; +static timeout_t periodictimer; /* Purge edges and subnets of unreachable nodes. Use carefully. */ @@ -224,7 +226,7 @@ static void periodic_handler(void *data) { if(!found) { logger(DEBUG_CONNECTIONS, LOG_INFO, "Autoconnecting to %s", n->name); - outgoing_t *outgoing = xmalloc_and_zero(sizeof *outgoing); + outgoing_t *outgoing = xzalloc(sizeof *outgoing); outgoing->name = xstrdup(n->name); list_insert_tail(outgoing_list, outgoing); setup_outgoing_connection(outgoing); @@ -296,7 +298,8 @@ static void sigterm_handler(void *data) { static void sighup_handler(void *data) { logger(DEBUG_ALWAYS, LOG_NOTICE, "Got %s signal", strsignal(((signal_t *)data)->signum)); reopenlogger(); - reload_configuration(); + if(reload_configuration()) + exit(1); } static void sigalrm_handler(void *data) { @@ -306,7 +309,7 @@ static void sigalrm_handler(void *data) { #endif int reload_configuration(void) { - char *fname; + char *fname = NULL; /* Reread our own configuration file */ @@ -314,8 +317,7 @@ int reload_configuration(void) { init_configuration(&config_tree); if(!read_server_config()) { - logger(DEBUG_ALWAYS, LOG_ERR, "Unable to reread configuration file, exitting."); - event_exit(); + logger(DEBUG_ALWAYS, LOG_ERR, "Unable to reread configuration file."); return EINVAL; } @@ -412,24 +414,27 @@ int reload_configuration(void) { } void retry(void) { - for list_each(connection_t, c, connection_list) { - if(c->outgoing && !c->node) { - timeout_del(&c->outgoing->ev); - if(c->status.connecting) - close(c->socket); - c->outgoing->timeout = 0; - terminate_connection(c, c->status.active); - } + /* Reset the reconnection timers for all outgoing connections */ + for list_each(outgoing_t, outgoing, outgoing_list) { + outgoing->timeout = 0; + if(outgoing->ev.cb) + timeout_set(&outgoing->ev, &(struct timeval){0, 0}); } + + /* Check for outgoing connections that are in progress, and reset their ping timers */ + for list_each(connection_t, c, connection_list) { + if(c->outgoing && !c->node) + c->last_ping_time = 0; + } + + /* Kick the ping timeout handler */ + timeout_set(&pingtimer, &(struct timeval){0, 0}); } /* this is where it all happens... */ int main_loop(void) { - timeout_t pingtimer = {{0}}; - timeout_t periodictimer = {{0}}; - timeout_add(&pingtimer, timeout_handler, &pingtimer, &(struct timeval){pingtimeout, rand() % 100000}); timeout_add(&periodictimer, periodic_handler, &periodictimer, &(struct timeval){pingtimeout, rand() % 100000}); @@ -454,9 +459,10 @@ int main_loop(void) { #ifndef HAVE_MINGW signal_del(&sighup); - signal_del(&sigalrm); - signal_del(&sigquit); signal_del(&sigterm); + signal_del(&sigquit); + signal_del(&sigint); + signal_del(&sigalrm); #endif timeout_del(&periodictimer); diff --git a/src/net.h b/src/net.h index 879dfff..9a97276 100644 --- a/src/net.h +++ b/src/net.h @@ -125,6 +125,7 @@ extern int seconds_till_retry; extern int addressfamily; extern unsigned replaywin; extern bool localdiscovery; +extern sockaddr_t localdiscovery_address; extern listen_socket_t listen_socket[MAXSOCKETS]; extern int listen_sockets; @@ -132,6 +133,7 @@ extern io_t unix_socket; extern int keylifetime; extern int udp_rcvbuf; extern int udp_sndbuf; +extern int max_connection_burst; extern bool do_prune; extern char *myport; extern int autoconnect; diff --git a/src/net_packet.c b/src/net_packet.c index 27ca714..f79c9a7 100644 --- a/src/net_packet.c +++ b/src/net_packet.c @@ -56,6 +56,7 @@ static void send_udppacket(node_t *, vpn_packet_t *); unsigned replaywin = 16; bool localdiscovery = false; +sockaddr_t localdiscovery_address; #define MAX_SEQNO 1073741824 @@ -178,12 +179,25 @@ void send_mtu_probe(node_t *n) { } static void mtu_probe_h(node_t *n, vpn_packet_t *packet, length_t len) { - logger(DEBUG_TRAFFIC, LOG_INFO, "Got MTU probe length %d from %s (%s)", packet->len, n->name, n->hostname); - if(!packet->data[0]) { + logger(DEBUG_TRAFFIC, LOG_INFO, "Got MTU probe request %d from %s (%s)", packet->len, n->name, n->hostname); + /* It's a probe request, send back a reply */ - packet->data[0] = 1; + /* Type 2 probe replies were introduced in protocol 17.3 */ + if ((n->options >> 24) == 3) { + uint8_t* data = packet->data; + *data++ = 2; + uint16_t len16 = htons(len); memcpy(data, &len16, 2); data += 2; + struct timeval now; + gettimeofday(&now, NULL); + uint32_t sec = htonl(now.tv_sec); memcpy(data, &sec, 4); data += 4; + uint32_t usec = htonl(now.tv_usec); memcpy(data, &usec, 4); data += 4; + packet->len = data - packet->data; + } else { + /* Legacy protocol: n won't understand type 2 probe replies. */ + packet->data[0] = 1; + } /* Temporarily set udp_confirmed, so that the reply is sent back exactly the way it came in. */ @@ -193,6 +207,16 @@ static void mtu_probe_h(node_t *n, vpn_packet_t *packet, length_t len) { send_udppacket(n, packet); n->status.udp_confirmed = udp_confirmed; } else { + length_t probelen = len; + if (packet->data[0] == 2) { + if (len < 3) + logger(DEBUG_TRAFFIC, LOG_WARNING, "Received invalid (too short) MTU probe reply from %s (%s)", n->name, n->hostname); + else { + uint16_t probelen16; memcpy(&probelen16, packet->data + 1, 2); probelen = ntohs(probelen16); + } + } + logger(DEBUG_TRAFFIC, LOG_INFO, "Got type %d MTU probe reply %d from %s (%s)", packet->data[0], probelen, n->name, n->hostname); + /* It's a valid reply: now we know bidirectional communication is possible using the address and socket that the reply packet used. */ @@ -202,7 +226,7 @@ static void mtu_probe_h(node_t *n, vpn_packet_t *packet, length_t len) { /* If we haven't established the PMTU yet, restart the discovery process. */ if(n->mtuprobes > 30) { - if (len == n->maxmtu + 8) { + if (probelen == n->maxmtu + 8) { logger(DEBUG_TRAFFIC, LOG_INFO, "Increase in PMTU to %s (%s) detected, restarting PMTU discovery", n->name, n->hostname); n->maxmtu = MTU; n->mtuprobes = 10; @@ -217,27 +241,38 @@ static void mtu_probe_h(node_t *n, vpn_packet_t *packet, length_t len) { /* If applicable, raise the minimum supported MTU */ - if(len > n->maxmtu) - len = n->maxmtu; - if(n->minmtu < len) - n->minmtu = len; + if(probelen > n->maxmtu) + probelen = n->maxmtu; + if(n->minmtu < probelen) + n->minmtu = probelen; /* Calculate RTT and bandwidth. The RTT is the time between the MTU probe burst was sent and the first reply is received. The bandwidth is measured using the time between the - arrival of the first and third probe reply. + arrival of the first and third probe reply (or type 2 probe requests). */ struct timeval now, diff; gettimeofday(&now, NULL); timersub(&now, &n->probe_time, &diff); + + struct timeval probe_timestamp = now; + if (packet->data[0] == 2 && packet->len >= 11) { + uint32_t sec; memcpy(&sec, packet->data + 3, 4); + uint32_t usec; memcpy(&usec, packet->data + 7, 4); + probe_timestamp.tv_sec = ntohl(sec); + probe_timestamp.tv_usec = ntohl(usec); + } + n->probe_counter++; if(n->probe_counter == 1) { n->rtt = diff.tv_sec + diff.tv_usec * 1e-6; - n->probe_time = now; + n->probe_time = probe_timestamp; } else if(n->probe_counter == 3) { - n->bandwidth = 2.0 * len / (diff.tv_sec + diff.tv_usec * 1e-6); + struct timeval probe_timestamp_diff; + timersub(&probe_timestamp, &n->probe_time, &probe_timestamp_diff); + n->bandwidth = 2.0 * probelen / (probe_timestamp_diff.tv_sec + probe_timestamp_diff.tv_usec * 1e-6); logger(DEBUG_TRAFFIC, LOG_DEBUG, "%s (%s) RTT %.2f ms, burst bandwidth %.3f Mbit/s, rx packet loss %.2f %%", n->name, n->hostname, n->rtt * 1e3, n->bandwidth * 8e-6, n->packetloss * 1e2); } } @@ -318,10 +353,10 @@ static bool try_mac(node_t *n, const vpn_packet_t *inpkt) { if(n->status.sptps) return sptps_verify_datagram(&n->sptps, (char *)&inpkt->seqno, inpkt->len); - if(!digest_active(&n->indigest) || inpkt->len < sizeof inpkt->seqno + digest_length(&n->indigest)) + if(!digest_active(n->indigest) || inpkt->len < sizeof inpkt->seqno + digest_length(n->indigest)) return false; - return digest_verify(&n->indigest, &inpkt->seqno, inpkt->len - n->indigest.maclength, (const char *)&inpkt->seqno + inpkt->len - n->indigest.maclength); + return digest_verify(n->indigest, &inpkt->seqno, inpkt->len - digest_length(n->indigest), (const char *)&inpkt->seqno + inpkt->len - digest_length(n->indigest)); } static void receive_udppacket(node_t *n, vpn_packet_t *inpkt) { @@ -332,19 +367,27 @@ static void receive_udppacket(node_t *n, vpn_packet_t *inpkt) { size_t outlen; if(n->status.sptps) { + if(!n->sptps.state) { + if(!n->status.waitingforkey) { + logger(DEBUG_TRAFFIC, LOG_DEBUG, "Got packet from %s (%s) but we haven't exchanged keys yet", n->name, n->hostname); + send_req_key(n); + } else { + logger(DEBUG_TRAFFIC, LOG_DEBUG, "Got packet from %s (%s) but he hasn't got our key yet", n->name, n->hostname); + } + return; + } sptps_receive_data(&n->sptps, (char *)&inpkt->seqno, inpkt->len); return; } - if(!cipher_active(&n->incipher)) { - logger(DEBUG_TRAFFIC, LOG_DEBUG, "Got packet from %s (%s) but he hasn't got our key yet", - n->name, n->hostname); + if(!cipher_active(n->incipher)) { + logger(DEBUG_TRAFFIC, LOG_DEBUG, "Got packet from %s (%s) but he hasn't got our key yet", n->name, n->hostname); return; } /* Check packet length */ - if(inpkt->len < sizeof inpkt->seqno + digest_length(&n->indigest)) { + if(inpkt->len < sizeof inpkt->seqno + digest_length(n->indigest)) { logger(DEBUG_TRAFFIC, LOG_DEBUG, "Got too short packet from %s (%s)", n->name, n->hostname); return; @@ -352,20 +395,20 @@ static void receive_udppacket(node_t *n, vpn_packet_t *inpkt) { /* Check the message authentication code */ - if(digest_active(&n->indigest)) { - inpkt->len -= n->indigest.maclength; - if(!digest_verify(&n->indigest, &inpkt->seqno, inpkt->len, (const char *)&inpkt->seqno + inpkt->len)) { + if(digest_active(n->indigest)) { + inpkt->len -= digest_length(n->indigest); + if(!digest_verify(n->indigest, &inpkt->seqno, inpkt->len, (const char *)&inpkt->seqno + inpkt->len)) { logger(DEBUG_TRAFFIC, LOG_DEBUG, "Got unauthenticated packet from %s (%s)", n->name, n->hostname); return; } } /* Decrypt the packet */ - if(cipher_active(&n->incipher)) { + if(cipher_active(n->incipher)) { outpkt = pkt[nextpkt++]; outlen = MAXSIZE; - if(!cipher_decrypt(&n->incipher, &inpkt->seqno, inpkt->len, &outpkt->seqno, &outlen, true)) { + if(!cipher_decrypt(n->incipher, &inpkt->seqno, inpkt->len, &outpkt->seqno, &outlen, true)) { logger(DEBUG_TRAFFIC, LOG_DEBUG, "Error decrypting packet from %s (%s)", n->name, n->hostname); return; } @@ -572,12 +615,22 @@ static void choose_broadcast_address(const node_t *n, const sockaddr_t **sa, int *sock = rand() % listen_sockets; if(listen_socket[*sock].sa.sa.sa_family == AF_INET6) { - broadcast_ipv6.in6.sin6_port = n->prevedge->address.in.sin_port; - broadcast_ipv6.in6.sin6_scope_id = listen_socket[*sock].sa.in6.sin6_scope_id; - *sa = &broadcast_ipv6; + if(localdiscovery_address.sa.sa_family == AF_INET6) { + localdiscovery_address.in6.sin6_port = n->prevedge->address.in.sin_port; + *sa = &localdiscovery_address; + } else { + broadcast_ipv6.in6.sin6_port = n->prevedge->address.in.sin_port; + broadcast_ipv6.in6.sin6_scope_id = listen_socket[*sock].sa.in6.sin6_scope_id; + *sa = &broadcast_ipv6; + } } else { - broadcast_ipv4.in.sin_port = n->prevedge->address.in.sin_port; - *sa = &broadcast_ipv4; + if(localdiscovery_address.sa.sa_family == AF_INET) { + localdiscovery_address.in.sin_port = n->prevedge->address.in.sin_port; + *sa = &localdiscovery_address; + } else { + broadcast_ipv4.in.sin_port = n->prevedge->address.in.sin_port; + *sa = &broadcast_ipv4; + } } } @@ -653,11 +706,11 @@ static void send_udppacket(node_t *n, vpn_packet_t *origpkt) { /* Encrypt the packet */ - if(cipher_active(&n->outcipher)) { + if(cipher_active(n->outcipher)) { outpkt = pkt[nextpkt++]; outlen = MAXSIZE; - if(!cipher_encrypt(&n->outcipher, &inpkt->seqno, inpkt->len, &outpkt->seqno, &outlen, true)) { + if(!cipher_encrypt(n->outcipher, &inpkt->seqno, inpkt->len, &outpkt->seqno, &outlen, true)) { logger(DEBUG_TRAFFIC, LOG_ERR, "Error while encrypting packet to %s (%s)", n->name, n->hostname); goto end; } @@ -668,9 +721,13 @@ static void send_udppacket(node_t *n, vpn_packet_t *origpkt) { /* Add the message authentication code */ - if(digest_active(&n->outdigest)) { - digest_create(&n->outdigest, &inpkt->seqno, inpkt->len, (char *)&inpkt->seqno + inpkt->len); - inpkt->len += digest_length(&n->outdigest); + if(digest_active(n->outdigest)) { + if(!digest_create(n->outdigest, &inpkt->seqno, inpkt->len, (char *)&inpkt->seqno + inpkt->len)) { + logger(DEBUG_TRAFFIC, LOG_ERR, "Error while encrypting packet to %s (%s)", n->name, n->hostname); + goto end; + } + + inpkt->len += digest_length(n->outdigest); } /* Send the packet */ @@ -719,10 +776,12 @@ bool send_sptps_data(void *handle, uint8_t type, const char *data, size_t len) { b64encode(data, buf, len); /* If no valid key is known yet, send the packets using ANS_KEY requests, to ensure we get to learn the reflexive UDP address. */ - if(!to->status.validkey) - return send_request(to->nexthop->connection, "%d %s %s %s -1 -1 -1 %d", ANS_KEY, myself->name, to->name, buf, myself->incompression); - else + if(!to->status.validkey) { + to->incompression = myself->incompression; + return send_request(to->nexthop->connection, "%d %s %s %s -1 -1 -1 %d", ANS_KEY, myself->name, to->name, buf, to->incompression); + } else { return send_request(to->nexthop->connection, "%d %s %s %d %s", REQ_KEY, myself->name, to->name, REQ_SPTPS, buf); + } } /* Otherwise, send the packet via UDP */ @@ -902,7 +961,7 @@ void broadcast_packet(const node_t *from, vpn_packet_t *packet) { break; for splay_each(node_t, n, node_tree) - if(n->status.reachable && ((n->via == myself && n->nexthop == n) || n->via == n)) + if(n->status.reachable && n != myself && ((n->via == myself && n->nexthop == n) || n->via == n)) send_packet(n, packet); break; diff --git a/src/net_setup.c b/src/net_setup.c index bf0c5a5..0fedafa 100644 --- a/src/net_setup.c +++ b/src/net_setup.c @@ -58,25 +58,22 @@ char *scriptinterpreter; char *scriptextension; bool node_read_ecdsa_public_key(node_t *n) { - if(ecdsa_active(&n->ecdsa)) + if(ecdsa_active(n->ecdsa)) return true; splay_tree_t *config_tree; FILE *fp; - char *pubname = NULL, *hcfname = NULL; + char *pubname = NULL; char *p; - bool result = false; - - xasprintf(&hcfname, "%s" SLASH "hosts" SLASH "%s", confbase, n->name); init_configuration(&config_tree); - if(!read_config_file(config_tree, hcfname)) + if(!read_host_config(config_tree, n->name)) goto exit; /* First, check for simple ECDSAPublicKey statement */ if(get_config_string(lookup_config(config_tree, "ECDSAPublicKey"), &p)) { - result = ecdsa_set_base64_public_key(&n->ecdsa, p); + n->ecdsa = ecdsa_set_base64_public_key(p); free(p); goto exit; } @@ -93,28 +90,35 @@ bool node_read_ecdsa_public_key(node_t *n) { goto exit; } - result = ecdsa_read_pem_public_key(&n->ecdsa, fp); + n->ecdsa = ecdsa_read_pem_public_key(fp); fclose(fp); exit: exit_configuration(&config_tree); - free(hcfname); free(pubname); - return result; + return n->ecdsa; } bool read_ecdsa_public_key(connection_t *c) { + if(ecdsa_active(c->ecdsa)) + return true; + FILE *fp; char *fname; char *p; - bool result; + + if(!c->config_tree) { + init_configuration(&c->config_tree); + if(!read_host_config(c->config_tree, c->name)) + return false; + } /* First, check for simple ECDSAPublicKey statement */ if(get_config_string(lookup_config(c->config_tree, "ECDSAPublicKey"), &p)) { - result = ecdsa_set_base64_public_key(&c->ecdsa, p); + c->ecdsa = ecdsa_set_base64_public_key(p); free(p); - return result; + return c->ecdsa; } /* Else, check for ECDSAPublicKeyFile statement and read it */ @@ -131,27 +135,29 @@ bool read_ecdsa_public_key(connection_t *c) { return false; } - result = ecdsa_read_pem_public_key(&c->ecdsa, fp); + c->ecdsa = ecdsa_read_pem_public_key(fp); fclose(fp); - if(!result) + if(!c->ecdsa) logger(DEBUG_ALWAYS, LOG_ERR, "Parsing ECDSA public key file `%s' failed.", fname); free(fname); - return result; + return c->ecdsa; } bool read_rsa_public_key(connection_t *c) { + if(ecdsa_active(c->ecdsa)) + return true; + FILE *fp; char *fname; char *n; - bool result; /* First, check for simple PublicKey statement */ if(get_config_string(lookup_config(c->config_tree, "PublicKey"), &n)) { - result = rsa_set_hex_public_key(&c->rsa, n, "FFFF"); + c->rsa = rsa_set_hex_public_key(n, "FFFF"); free(n); - return result; + return c->rsa; } /* Else, check for PublicKeyFile statement and read it */ @@ -167,19 +173,18 @@ bool read_rsa_public_key(connection_t *c) { return false; } - result = rsa_read_pem_public_key(&c->rsa, fp); + c->rsa = rsa_read_pem_public_key(fp); fclose(fp); - if(!result) + if(!c->rsa) logger(DEBUG_ALWAYS, LOG_ERR, "Reading RSA public key file `%s' failed: %s", fname, strerror(errno)); free(fname); - return result; + return c->rsa; } static bool read_ecdsa_private_key(void) { FILE *fp; char *fname; - bool result; /* Check for PrivateKeyFile statement and read it */ @@ -190,6 +195,8 @@ static bool read_ecdsa_private_key(void) { if(!fp) { logger(DEBUG_ALWAYS, LOG_ERR, "Error reading ECDSA private key file `%s': %s", fname, strerror(errno)); + if(errno == ENOENT) + logger(DEBUG_ALWAYS, LOG_INFO, "Create an ECDSA keypair with `tinc -n %s generate-ecdsa-keys'.", netname ?: "."); free(fname); return false; } @@ -207,20 +214,43 @@ static bool read_ecdsa_private_key(void) { logger(DEBUG_ALWAYS, LOG_WARNING, "Warning: insecure file permissions for ECDSA private key file `%s'!", fname); #endif - result = ecdsa_read_pem_private_key(&myself->connection->ecdsa, fp); + myself->connection->ecdsa = ecdsa_read_pem_private_key(fp); fclose(fp); - if(!result) + if(!myself->connection->ecdsa) logger(DEBUG_ALWAYS, LOG_ERR, "Reading ECDSA private key file `%s' failed: %s", fname, strerror(errno)); free(fname); - return result; + return myself->connection->ecdsa; +} + +static bool read_invitation_key(void) { + FILE *fp; + char *fname; + + if(invitation_key) { + ecdsa_free(invitation_key); + invitation_key = NULL; + } + + xasprintf(&fname, "%s" SLASH "invitations" SLASH "ecdsa_key.priv", confbase); + + fp = fopen(fname, "r"); + + if(fp) { + invitation_key = ecdsa_read_pem_private_key(fp); + fclose(fp); + if(!invitation_key) + logger(DEBUG_ALWAYS, LOG_ERR, "Reading ECDSA private key file `%s' failed: %s", fname, strerror(errno)); + } + + free(fname); + return invitation_key; } static bool read_rsa_private_key(void) { FILE *fp; char *fname; char *n, *d; - bool result; /* First, check for simple PrivateKey statement */ @@ -230,10 +260,10 @@ static bool read_rsa_private_key(void) { free(d); return false; } - result = rsa_set_hex_private_key(&myself->connection->rsa, n, "FFFF", d); + myself->connection->rsa = rsa_set_hex_private_key(n, "FFFF", d); free(n); free(d); - return result; + return myself->connection->rsa; } /* Else, check for PrivateKeyFile statement and read it */ @@ -263,13 +293,13 @@ static bool read_rsa_private_key(void) { logger(DEBUG_ALWAYS, LOG_WARNING, "Warning: insecure file permissions for RSA private key file `%s'!", fname); #endif - result = rsa_read_pem_private_key(&myself->connection->rsa, fp); + myself->connection->rsa = rsa_read_pem_private_key(fp); fclose(fp); - if(!result) + if(!myself->connection->rsa) logger(DEBUG_ALWAYS, LOG_ERR, "Reading RSA private key file `%s' failed: %s", fname, strerror(errno)); free(fname); - return result; + return myself->connection->rsa; } static timeout_t keyexpire_timeout; @@ -310,14 +340,10 @@ void load_all_subnets(void) { // continue; #endif - char *fname; - xasprintf(&fname, "%s" SLASH "hosts" SLASH "%s", confbase, ent->d_name); - splay_tree_t *config_tree; init_configuration(&config_tree); read_config_options(config_tree, ent->d_name); - read_config_file(config_tree, fname); - free(fname); + read_host_config(config_tree, ent->d_name); if(!n) { n = new_node(); @@ -418,6 +444,7 @@ bool setup_myself_reloadable(void) { char *fmode = NULL; char *bmode = NULL; char *afname = NULL; + char *address = NULL; char *space; bool choice; @@ -508,6 +535,16 @@ bool setup_myself_reloadable(void) { get_config_bool(lookup_config(config_tree, "DirectOnly"), &directonly); get_config_bool(lookup_config(config_tree, "LocalDiscovery"), &localdiscovery); + memset(&localdiscovery_address, 0, sizeof localdiscovery_address); + if(get_config_string(lookup_config(config_tree, "LocalDiscoveryAddress"), &address)) { + struct addrinfo *ai = str2addrinfo(address, myport, SOCK_DGRAM); + free(address); + if(!ai) + return false; + memcpy(&localdiscovery_address, ai->ai_addr, ai->ai_addrlen); + } + + if(get_config_string(lookup_config(config_tree, "Mode"), &rmode)) { if(!strcasecmp(rmode, "router")) routing_mode = RMODE_ROUTER; @@ -601,6 +638,8 @@ bool setup_myself_reloadable(void) { get_config_bool(lookup_config(config_tree, "DisableBuggyPeers"), &disablebuggypeers); + read_invitation_key(); + return true; } @@ -609,7 +648,6 @@ bool setup_myself_reloadable(void) { */ static bool setup_myself(void) { char *name, *hostname, *cipher, *digest, *type; - char *fname = NULL; char *address = NULL; if(!(name = get_name())) { @@ -621,10 +659,7 @@ static bool setup_myself(void) { myself->connection = new_connection(); myself->name = name; myself->connection->name = xstrdup(name); - xasprintf(&fname, "%s" SLASH "hosts" SLASH "%s", confbase, name); - read_config_options(config_tree, name); - read_config_file(config_tree, fname); - free(fname); + read_host_config(config_tree, name); if(!get_config_string(lookup_config(config_tree, "Port"), &myport)) myport = xstrdup("655"); @@ -676,7 +711,12 @@ static bool setup_myself(void) { get_config_bool(lookup_config(config_tree, "TunnelServer"), &tunnelserver); strictsubnets |= tunnelserver; - + if(get_config_int(lookup_config(config_tree, "MaxConnectionBurst"), &max_connection_burst)) { + if(max_connection_burst <= 0) { + logger(DEBUG_ALWAYS, LOG_ERR, "MaxConnectionBurst cannot be negative!"); + return false; + } + } if(get_config_int(lookup_config(config_tree, "UDPRcvBuf"), &udp_rcvbuf)) { if(udp_rcvbuf <= 0) { @@ -707,7 +747,7 @@ static bool setup_myself(void) { if(!get_config_string(lookup_config(config_tree, "Cipher"), &cipher)) cipher = xstrdup("blowfish"); - if(!cipher_open_by_name(&myself->incipher, cipher)) { + if(!(myself->incipher = cipher_open_by_name(cipher))) { logger(DEBUG_ALWAYS, LOG_ERR, "Unrecognized cipher type!"); return false; } @@ -730,7 +770,7 @@ static bool setup_myself(void) { if(!get_config_string(lookup_config(config_tree, "Digest"), &digest)) digest = xstrdup("sha1"); - if(!digest_open_by_name(&myself->indigest, digest, maclength)) { + if(!(myself->indigest = digest_open_by_name(digest, maclength))) { logger(DEBUG_ALWAYS, LOG_ERR, "Unrecognized digest type!"); return false; } @@ -793,12 +833,11 @@ static bool setup_myself(void) { io_add(&device_io, handle_device_data, NULL, device_fd, IO_READ); /* Run tinc-up script to further initialize the tap interface */ - char *envp[5]; + char *envp[5] = {NULL}; xasprintf(&envp[0], "NETNAME=%s", netname ? : ""); xasprintf(&envp[1], "DEVICE=%s", device ? : ""); xasprintf(&envp[2], "INTERFACE=%s", iface ? : ""); xasprintf(&envp[3], "NAME=%s", myself->name); - envp[4] = NULL; execute_script("tinc-up", envp); @@ -829,7 +868,12 @@ static bool setup_myself(void) { unlink(unixsocketname); - if(bind(unix_fd, (struct sockaddr *)&sa, sizeof sa) < 0) { + mode_t mask = umask(0); + umask(mask | 077); + int result = bind(unix_fd, (struct sockaddr *)&sa, sizeof sa); + umask(mask); + + if(result < 0) { logger(DEBUG_ALWAYS, LOG_ERR, "Could not bind UNIX socket to %s: %s", unixsocketname, sockstrerror(errno)); return false; } @@ -914,8 +958,7 @@ static bool setup_myself(void) { free(address); if(err || !ai) { - logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "getaddrinfo", - gai_strerror(err)); + logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "getaddrinfo", err == EAI_SYSTEM ? strerror(err) : gai_strerror(err)); return false; } @@ -1031,12 +1074,11 @@ void close_network_connections(void) { close(unix_socket.fd); #endif - char *envp[5]; + char *envp[5] = {NULL}; xasprintf(&envp[0], "NETNAME=%s", netname ? : ""); xasprintf(&envp[1], "DEVICE=%s", device ? : ""); xasprintf(&envp[2], "INTERFACE=%s", iface ? : ""); xasprintf(&envp[3], "NAME=%s", myself->name); - envp[4] = NULL; exit_requests(); exit_edges(); diff --git a/src/net_socket.c b/src/net_socket.c index 5332ed2..ded9224 100644 --- a/src/net_socket.c +++ b/src/net_socket.c @@ -45,6 +45,7 @@ int maxtimeout = 900; int seconds_till_retry = 5; int udp_rcvbuf = 0; int udp_sndbuf = 0; +int max_connection_burst = 100; listen_socket_t listen_socket[MAXSOCKETS]; int listen_sockets; @@ -561,6 +562,47 @@ void handle_new_meta_connection(void *data, int flags) { sockaddrunmap(&sa); + // Check if we get many connections from the same host + + static sockaddr_t prev_sa; + static time_t prev_time; + static int tarpit = -1; + + if(tarpit >= 0) { + closesocket(tarpit); + tarpit = -1; + } + + if(prev_time == now.tv_sec && !sockaddrcmp_noport(&sa, &prev_sa)) { + // if so, keep the connection open but ignore it completely. + tarpit = fd; + return; + } + + memcpy(&prev_sa, &sa, sizeof sa); + prev_time = now.tv_sec; + + // Check if we get many connections from different hosts + + static int connection_burst; + static int connection_burst_time; + + if(now.tv_sec - connection_burst_time > connection_burst) + connection_burst = 0; + else + connection_burst -= now.tv_sec - connection_burst_time; + + connection_burst_time = now.tv_sec; + connection_burst++; + + if(connection_burst >= max_connection_burst) { + connection_burst = max_connection_burst; + tarpit = fd; + return; + } + + // Accept the new connection + c = new_connection(); c->name = xstrdup(""); c->outcipher = myself->connection->outcipher; @@ -674,7 +716,7 @@ void try_outgoing_connections(void) { } if(!found) { - outgoing_t *outgoing = xmalloc_and_zero(sizeof *outgoing); + outgoing_t *outgoing = xzalloc(sizeof *outgoing); outgoing->name = name; list_insert_tail(outgoing_list, outgoing); setup_outgoing_connection(outgoing); diff --git a/src/netutl.c b/src/netutl.c index a55eaea..989a152 100644 --- a/src/netutl.c +++ b/src/netutl.c @@ -1,7 +1,7 @@ /* netutl.c -- some supporting network utility code Copyright (C) 1998-2005 Ivo Timmermans - 2000-2012 Guus Sliepen + 2000-2013 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 @@ -42,8 +42,7 @@ struct addrinfo *str2addrinfo(const char *address, const char *service, int sock err = getaddrinfo(address, service, &hint, &ai); if(err) { - logger(DEBUG_ALWAYS, LOG_WARNING, "Error looking up %s port %s: %s", address, - service, gai_strerror(err)); + logger(DEBUG_ALWAYS, LOG_WARNING, "Error looking up %s port %s: %s", address, service, err == EAI_SYSTEM ? strerror(errno) : gai_strerror(err)); return NULL; } @@ -92,8 +91,7 @@ void sockaddr2str(const sockaddr_t *sa, char **addrstr, char **portstr) { err = getnameinfo(&sa->sa, SALEN(sa->sa), address, sizeof address, port, sizeof port, NI_NUMERICHOST | NI_NUMERICSERV); if(err) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error while translating addresses: %s", - gai_strerror(err)); + logger(DEBUG_ALWAYS, LOG_ERR, "Error while translating addresses: %s", err == EAI_SYSTEM ? strerror(errno) : gai_strerror(err)); abort(); } @@ -122,8 +120,7 @@ char *sockaddr2hostname(const sockaddr_t *sa) { err = getnameinfo(&sa->sa, SALEN(sa->sa), address, sizeof address, port, sizeof port, hostnames ? 0 : (NI_NUMERICHOST | NI_NUMERICSERV)); if(err) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error while looking up hostname: %s", - gai_strerror(err)); + logger(DEBUG_ALWAYS, LOG_ERR, "Error while looking up hostname: %s", err == EAI_SYSTEM ? strerror(errno) : gai_strerror(err)); } xasprintf(&str, "%s port %s", address, port); diff --git a/src/netutl.h b/src/netutl.h index 0fef2d6..471cae7 100644 --- a/src/netutl.h +++ b/src/netutl.h @@ -1,7 +1,7 @@ /* netutl.h -- header file for netutl.c Copyright (C) 1998-2005 Ivo Timmermans - 2000-2012 Guus Sliepen + 2000-2013 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 @@ -25,10 +25,10 @@ extern bool hostnames; -extern struct addrinfo *str2addrinfo(const char *, const char *, int); +extern struct addrinfo *str2addrinfo(const char *, const char *, int) __attribute__ ((__malloc__)); extern sockaddr_t str2sockaddr(const char *, const char *); extern void sockaddr2str(const sockaddr_t *, char **, char **); -extern char *sockaddr2hostname(const sockaddr_t *); +extern char *sockaddr2hostname(const sockaddr_t *) __attribute__ ((__malloc__)); extern int sockaddrcmp(const sockaddr_t *, const sockaddr_t *); extern int sockaddrcmp_noport(const sockaddr_t *, const sockaddr_t *); extern void sockaddrunmap(sockaddr_t *); diff --git a/src/node.c b/src/node.c index 465a48a..aab83ca 100644 --- a/src/node.c +++ b/src/node.c @@ -1,6 +1,6 @@ /* node.c -- node tree management - Copyright (C) 2001-2012 Guus Sliepen , + Copyright (C) 2001-2013 Guus Sliepen , 2001-2005 Ivo Timmermans This program is free software; you can redistribute it and/or modify @@ -50,9 +50,9 @@ void exit_nodes(void) { } node_t *new_node(void) { - node_t *n = xmalloc_and_zero(sizeof *n); + node_t *n = xzalloc(sizeof *n); - if(replaywin) n->late = xmalloc_and_zero(replaywin); + if(replaywin) n->late = xzalloc(replaywin); n->subnet_tree = new_subnet_tree(); n->edge_tree = new_edge_tree(); n->mtu = MTU; @@ -70,12 +70,12 @@ void free_node(node_t *n) { sockaddrfree(&n->address); - cipher_close(&n->incipher); - digest_close(&n->indigest); - cipher_close(&n->outcipher); - digest_close(&n->outdigest); + cipher_close(n->incipher); + digest_close(n->indigest); + cipher_close(n->outcipher); + digest_close(n->outdigest); - ecdsa_free(&n->ecdsa); + ecdsa_free(n->ecdsa); sptps_stop(&n->sptps); timeout_del(&n->mtutimeout); @@ -145,8 +145,8 @@ void update_node_udp(node_t *n, const sockaddr_t *sa) { bool dump_nodes(connection_t *c) { for splay_each(node_t, n, node_tree) send_request(c, "%d %d %s %s %d %d %d %d %x %x %s %s %d %hd %hd %hd %ld", CONTROL, REQ_DUMP_NODES, - n->name, n->hostname ?: "unknown port unknown", cipher_get_nid(&n->outcipher), - digest_get_nid(&n->outdigest), (int)digest_length(&n->outdigest), n->outcompression, + n->name, n->hostname ?: "unknown port unknown", cipher_get_nid(n->outcipher), + digest_get_nid(n->outdigest), (int)digest_length(n->outdigest), n->outcompression, n->options, bitfield_to_int(&n->status, sizeof n->status), n->nexthop ? n->nexthop->name : "-", n->via ? n->via->name ?: "-" : "-", n->distance, n->mtu, n->minmtu, n->maxmtu, (long)n->last_state_change); diff --git a/src/node.h b/src/node.h index e4b47b3..e704ba8 100644 --- a/src/node.h +++ b/src/node.h @@ -52,14 +52,14 @@ typedef struct node_t { time_t last_state_change; time_t last_req_key; - ecdsa_t ecdsa; /* His public ECDSA key */ + ecdsa_t *ecdsa; /* His public ECDSA key */ sptps_t sptps; - cipher_t incipher; /* Cipher for UDP packets */ - digest_t indigest; /* Digest for UDP packets */ + cipher_t *incipher; /* Cipher for UDP packets */ + digest_t *indigest; /* Digest for UDP packets */ - cipher_t outcipher; /* Cipher for UDP packets */ - digest_t outdigest; /* Digest for UDP packets */ + cipher_t *outcipher; /* Cipher for UDP packets */ + digest_t *outdigest; /* Digest for UDP packets */ int incompression; /* Compressionlevel, 0 = no compression */ int outcompression; /* Compressionlevel, 0 = no compression */ diff --git a/src/openssl/.deps/.dirstamp b/src/openssl/.deps/.dirstamp new file mode 100644 index 0000000..e69de29 diff --git a/src/openssl/.deps/cipher.Po b/src/openssl/.deps/cipher.Po new file mode 100644 index 0000000..05e8926 --- /dev/null +++ b/src/openssl/.deps/cipher.Po @@ -0,0 +1,454 @@ +openssl/cipher.o: openssl/cipher.c /usr/include/stdc-predef.h \ + /usr/include/x86_64-linux-gnu/bits/predefs.h openssl/../system.h \ + openssl/../../config.h openssl/../have.h /usr/include/stdio.h \ + /usr/include/features.h /usr/include/x86_64-linux-gnu/sys/cdefs.h \ + /usr/include/x86_64-linux-gnu/bits/wordsize.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ + /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stddef.h \ + /usr/include/x86_64-linux-gnu/bits/types.h \ + /usr/include/x86_64-linux-gnu/bits/typesizes.h /usr/include/libio.h \ + /usr/include/_G_config.h /usr/include/wchar.h \ + /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdarg.h \ + /usr/include/x86_64-linux-gnu/bits/stdio_lim.h \ + /usr/include/x86_64-linux-gnu/bits/sys_errlist.h \ + /usr/include/x86_64-linux-gnu/bits/stdio.h /usr/include/stdlib.h \ + /usr/include/x86_64-linux-gnu/bits/waitflags.h \ + /usr/include/x86_64-linux-gnu/bits/waitstatus.h /usr/include/endian.h \ + /usr/include/x86_64-linux-gnu/bits/endian.h \ + /usr/include/x86_64-linux-gnu/bits/byteswap.h \ + /usr/include/x86_64-linux-gnu/bits/byteswap-16.h /usr/include/xlocale.h \ + /usr/include/x86_64-linux-gnu/sys/types.h /usr/include/time.h \ + /usr/include/x86_64-linux-gnu/sys/select.h \ + /usr/include/x86_64-linux-gnu/bits/select.h \ + /usr/include/x86_64-linux-gnu/bits/sigset.h \ + /usr/include/x86_64-linux-gnu/bits/time.h \ + /usr/include/x86_64-linux-gnu/sys/sysmacros.h \ + /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h /usr/include/alloca.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib-float.h /usr/include/string.h \ + /usr/include/x86_64-linux-gnu/bits/string.h \ + /usr/include/x86_64-linux-gnu/bits/string2.h /usr/include/ctype.h \ + /usr/include/signal.h /usr/include/x86_64-linux-gnu/bits/signum.h \ + /usr/include/x86_64-linux-gnu/bits/siginfo.h \ + /usr/include/x86_64-linux-gnu/bits/sigaction.h \ + /usr/include/x86_64-linux-gnu/bits/sigcontext.h \ + /usr/include/x86_64-linux-gnu/bits/sigstack.h \ + /usr/include/x86_64-linux-gnu/sys/ucontext.h \ + /usr/include/x86_64-linux-gnu/bits/sigthread.h /usr/include/errno.h \ + /usr/include/x86_64-linux-gnu/bits/errno.h /usr/include/linux/errno.h \ + /usr/include/x86_64-linux-gnu/asm/errno.h \ + /usr/include/asm-generic/errno.h /usr/include/asm-generic/errno-base.h \ + /usr/include/fcntl.h /usr/include/x86_64-linux-gnu/bits/fcntl.h \ + /usr/include/x86_64-linux-gnu/bits/fcntl-linux.h \ + /usr/include/x86_64-linux-gnu/bits/uio.h \ + /usr/include/x86_64-linux-gnu/bits/stat.h /usr/include/unistd.h \ + /usr/include/x86_64-linux-gnu/bits/posix_opt.h \ + /usr/include/x86_64-linux-gnu/bits/environments.h \ + /usr/include/x86_64-linux-gnu/bits/confname.h /usr/include/getopt.h \ + /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdbool.h \ + /usr/include/inttypes.h \ + /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdint.h /usr/include/stdint.h \ + /usr/include/x86_64-linux-gnu/bits/wchar.h /usr/include/syslog.h \ + /usr/include/x86_64-linux-gnu/sys/syslog.h \ + /usr/include/x86_64-linux-gnu/bits/syslog-path.h \ + /usr/include/x86_64-linux-gnu/sys/time.h \ + /usr/include/x86_64-linux-gnu/bits/timex.h \ + /usr/include/x86_64-linux-gnu/sys/stat.h \ + /usr/include/x86_64-linux-gnu/sys/file.h \ + /usr/include/x86_64-linux-gnu/sys/wait.h \ + /usr/include/x86_64-linux-gnu/sys/ioctl.h \ + /usr/include/x86_64-linux-gnu/bits/ioctls.h \ + /usr/include/x86_64-linux-gnu/asm/ioctls.h \ + /usr/include/asm-generic/ioctls.h /usr/include/linux/ioctl.h \ + /usr/include/x86_64-linux-gnu/asm/ioctl.h \ + /usr/include/asm-generic/ioctl.h \ + /usr/include/x86_64-linux-gnu/bits/ioctl-types.h \ + /usr/include/x86_64-linux-gnu/sys/ttydefaults.h \ + /usr/include/x86_64-linux-gnu/sys/param.h \ + /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/limits.h \ + /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/syslimits.h \ + /usr/include/limits.h /usr/include/x86_64-linux-gnu/bits/posix1_lim.h \ + /usr/include/x86_64-linux-gnu/bits/local_lim.h \ + /usr/include/linux/limits.h \ + /usr/include/x86_64-linux-gnu/bits/posix2_lim.h \ + /usr/include/x86_64-linux-gnu/bits/xopen_lim.h \ + /usr/include/x86_64-linux-gnu/bits/param.h /usr/include/linux/param.h \ + /usr/include/x86_64-linux-gnu/asm/param.h \ + /usr/include/asm-generic/param.h \ + /usr/include/x86_64-linux-gnu/sys/resource.h \ + /usr/include/x86_64-linux-gnu/bits/resource.h \ + /usr/include/x86_64-linux-gnu/sys/uio.h \ + /usr/include/x86_64-linux-gnu/sys/un.h \ + /usr/include/x86_64-linux-gnu/bits/sockaddr.h /usr/include/dirent.h \ + /usr/include/x86_64-linux-gnu/bits/dirent.h /usr/include/netdb.h \ + /usr/include/netinet/in.h /usr/include/x86_64-linux-gnu/sys/socket.h \ + /usr/include/x86_64-linux-gnu/bits/socket.h \ + /usr/include/x86_64-linux-gnu/bits/socket_type.h \ + /usr/include/x86_64-linux-gnu/asm/socket.h \ + /usr/include/asm-generic/socket.h \ + /usr/include/x86_64-linux-gnu/asm/sockios.h \ + /usr/include/asm-generic/sockios.h \ + /usr/include/x86_64-linux-gnu/bits/in.h /usr/include/rpc/netdb.h \ + /usr/include/x86_64-linux-gnu/bits/netdb.h /usr/include/net/if.h \ + /usr/include/netinet/in_systm.h /usr/include/arpa/inet.h \ + /usr/include/netinet/ip.h /usr/include/netinet/tcp.h \ + /usr/include/netinet/ip6.h /usr/include/net/ethernet.h \ + /usr/include/linux/if_ether.h /usr/include/linux/types.h \ + /usr/include/x86_64-linux-gnu/asm/types.h \ + /usr/include/asm-generic/types.h /usr/include/asm-generic/int-ll64.h \ + /usr/include/x86_64-linux-gnu/asm/bitsperlong.h \ + /usr/include/asm-generic/bitsperlong.h /usr/include/linux/posix_types.h \ + /usr/include/linux/stddef.h \ + /usr/include/x86_64-linux-gnu/asm/posix_types.h \ + /usr/include/x86_64-linux-gnu/asm/posix_types_64.h \ + /usr/include/asm-generic/posix_types.h /usr/include/net/if_arp.h \ + /usr/include/netinet/ip_icmp.h /usr/include/netinet/icmp6.h \ + /usr/include/netinet/if_ether.h openssl/../dropin.h \ + openssl/../fake-getaddrinfo.h openssl/../fake-gai-errnos.h \ + openssl/../fake-getnameinfo.h /usr/include/openssl/rand.h \ + /usr/include/openssl/ossl_typ.h /usr/include/openssl/e_os2.h \ + /usr/include/x86_64-linux-gnu/openssl/opensslconf.h \ + /usr/include/openssl/err.h /usr/include/openssl/bio.h \ + /usr/include/openssl/crypto.h /usr/include/openssl/stack.h \ + /usr/include/openssl/safestack.h /usr/include/openssl/opensslv.h \ + /usr/include/openssl/symhacks.h /usr/include/openssl/lhash.h \ + /usr/include/openssl/evp.h /usr/include/openssl/objects.h \ + /usr/include/openssl/obj_mac.h /usr/include/openssl/asn1.h \ + /usr/include/openssl/bn.h openssl/../cipher.h openssl/../logger.h \ + openssl/../xalloc.h + +/usr/include/stdc-predef.h: + +/usr/include/x86_64-linux-gnu/bits/predefs.h: + +openssl/../system.h: + +openssl/../../config.h: + +openssl/../have.h: + +/usr/include/stdio.h: + +/usr/include/features.h: + +/usr/include/x86_64-linux-gnu/sys/cdefs.h: + +/usr/include/x86_64-linux-gnu/bits/wordsize.h: + +/usr/include/x86_64-linux-gnu/gnu/stubs.h: + +/usr/include/x86_64-linux-gnu/gnu/stubs-64.h: + +/usr/lib/gcc/x86_64-linux-gnu/4.8/include/stddef.h: + +/usr/include/x86_64-linux-gnu/bits/types.h: + +/usr/include/x86_64-linux-gnu/bits/typesizes.h: + +/usr/include/libio.h: + +/usr/include/_G_config.h: + +/usr/include/wchar.h: + +/usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdarg.h: + +/usr/include/x86_64-linux-gnu/bits/stdio_lim.h: + +/usr/include/x86_64-linux-gnu/bits/sys_errlist.h: + +/usr/include/x86_64-linux-gnu/bits/stdio.h: + +/usr/include/stdlib.h: + +/usr/include/x86_64-linux-gnu/bits/waitflags.h: + +/usr/include/x86_64-linux-gnu/bits/waitstatus.h: + +/usr/include/endian.h: + +/usr/include/x86_64-linux-gnu/bits/endian.h: + +/usr/include/x86_64-linux-gnu/bits/byteswap.h: + +/usr/include/x86_64-linux-gnu/bits/byteswap-16.h: + +/usr/include/xlocale.h: + +/usr/include/x86_64-linux-gnu/sys/types.h: + +/usr/include/time.h: + +/usr/include/x86_64-linux-gnu/sys/select.h: + +/usr/include/x86_64-linux-gnu/bits/select.h: + +/usr/include/x86_64-linux-gnu/bits/sigset.h: + +/usr/include/x86_64-linux-gnu/bits/time.h: + +/usr/include/x86_64-linux-gnu/sys/sysmacros.h: + +/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h: + +/usr/include/alloca.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib-float.h: + +/usr/include/string.h: + +/usr/include/x86_64-linux-gnu/bits/string.h: + +/usr/include/x86_64-linux-gnu/bits/string2.h: + +/usr/include/ctype.h: + +/usr/include/signal.h: + +/usr/include/x86_64-linux-gnu/bits/signum.h: + +/usr/include/x86_64-linux-gnu/bits/siginfo.h: + +/usr/include/x86_64-linux-gnu/bits/sigaction.h: + +/usr/include/x86_64-linux-gnu/bits/sigcontext.h: + +/usr/include/x86_64-linux-gnu/bits/sigstack.h: + +/usr/include/x86_64-linux-gnu/sys/ucontext.h: + +/usr/include/x86_64-linux-gnu/bits/sigthread.h: + +/usr/include/errno.h: + +/usr/include/x86_64-linux-gnu/bits/errno.h: + +/usr/include/linux/errno.h: + +/usr/include/x86_64-linux-gnu/asm/errno.h: + +/usr/include/asm-generic/errno.h: + +/usr/include/asm-generic/errno-base.h: + +/usr/include/fcntl.h: + +/usr/include/x86_64-linux-gnu/bits/fcntl.h: + +/usr/include/x86_64-linux-gnu/bits/fcntl-linux.h: + +/usr/include/x86_64-linux-gnu/bits/uio.h: + +/usr/include/x86_64-linux-gnu/bits/stat.h: + +/usr/include/unistd.h: + +/usr/include/x86_64-linux-gnu/bits/posix_opt.h: + +/usr/include/x86_64-linux-gnu/bits/environments.h: + +/usr/include/x86_64-linux-gnu/bits/confname.h: + +/usr/include/getopt.h: + +/usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdbool.h: + +/usr/include/inttypes.h: + +/usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdint.h: + +/usr/include/stdint.h: + +/usr/include/x86_64-linux-gnu/bits/wchar.h: + +/usr/include/syslog.h: + +/usr/include/x86_64-linux-gnu/sys/syslog.h: + +/usr/include/x86_64-linux-gnu/bits/syslog-path.h: + +/usr/include/x86_64-linux-gnu/sys/time.h: + +/usr/include/x86_64-linux-gnu/bits/timex.h: + +/usr/include/x86_64-linux-gnu/sys/stat.h: + +/usr/include/x86_64-linux-gnu/sys/file.h: + +/usr/include/x86_64-linux-gnu/sys/wait.h: + +/usr/include/x86_64-linux-gnu/sys/ioctl.h: + +/usr/include/x86_64-linux-gnu/bits/ioctls.h: + +/usr/include/x86_64-linux-gnu/asm/ioctls.h: + +/usr/include/asm-generic/ioctls.h: + +/usr/include/linux/ioctl.h: + +/usr/include/x86_64-linux-gnu/asm/ioctl.h: + +/usr/include/asm-generic/ioctl.h: + +/usr/include/x86_64-linux-gnu/bits/ioctl-types.h: + +/usr/include/x86_64-linux-gnu/sys/ttydefaults.h: + +/usr/include/x86_64-linux-gnu/sys/param.h: + +/usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/limits.h: + +/usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/syslimits.h: + +/usr/include/limits.h: + +/usr/include/x86_64-linux-gnu/bits/posix1_lim.h: + +/usr/include/x86_64-linux-gnu/bits/local_lim.h: + +/usr/include/linux/limits.h: + +/usr/include/x86_64-linux-gnu/bits/posix2_lim.h: + +/usr/include/x86_64-linux-gnu/bits/xopen_lim.h: + +/usr/include/x86_64-linux-gnu/bits/param.h: + +/usr/include/linux/param.h: + +/usr/include/x86_64-linux-gnu/asm/param.h: + +/usr/include/asm-generic/param.h: + +/usr/include/x86_64-linux-gnu/sys/resource.h: + +/usr/include/x86_64-linux-gnu/bits/resource.h: + +/usr/include/x86_64-linux-gnu/sys/uio.h: + +/usr/include/x86_64-linux-gnu/sys/un.h: + +/usr/include/x86_64-linux-gnu/bits/sockaddr.h: + +/usr/include/dirent.h: + +/usr/include/x86_64-linux-gnu/bits/dirent.h: + +/usr/include/netdb.h: + +/usr/include/netinet/in.h: + +/usr/include/x86_64-linux-gnu/sys/socket.h: + +/usr/include/x86_64-linux-gnu/bits/socket.h: + +/usr/include/x86_64-linux-gnu/bits/socket_type.h: + +/usr/include/x86_64-linux-gnu/asm/socket.h: + +/usr/include/asm-generic/socket.h: + +/usr/include/x86_64-linux-gnu/asm/sockios.h: + +/usr/include/asm-generic/sockios.h: + +/usr/include/x86_64-linux-gnu/bits/in.h: + +/usr/include/rpc/netdb.h: + +/usr/include/x86_64-linux-gnu/bits/netdb.h: + +/usr/include/net/if.h: + +/usr/include/netinet/in_systm.h: + +/usr/include/arpa/inet.h: + +/usr/include/netinet/ip.h: + +/usr/include/netinet/tcp.h: + +/usr/include/netinet/ip6.h: + +/usr/include/net/ethernet.h: + +/usr/include/linux/if_ether.h: + +/usr/include/linux/types.h: + +/usr/include/x86_64-linux-gnu/asm/types.h: + +/usr/include/asm-generic/types.h: + +/usr/include/asm-generic/int-ll64.h: + +/usr/include/x86_64-linux-gnu/asm/bitsperlong.h: + +/usr/include/asm-generic/bitsperlong.h: + +/usr/include/linux/posix_types.h: + +/usr/include/linux/stddef.h: + +/usr/include/x86_64-linux-gnu/asm/posix_types.h: + +/usr/include/x86_64-linux-gnu/asm/posix_types_64.h: + +/usr/include/asm-generic/posix_types.h: + +/usr/include/net/if_arp.h: + +/usr/include/netinet/ip_icmp.h: + +/usr/include/netinet/icmp6.h: + +/usr/include/netinet/if_ether.h: + +openssl/../dropin.h: + +openssl/../fake-getaddrinfo.h: + +openssl/../fake-gai-errnos.h: + +openssl/../fake-getnameinfo.h: + +/usr/include/openssl/rand.h: + +/usr/include/openssl/ossl_typ.h: + +/usr/include/openssl/e_os2.h: + +/usr/include/x86_64-linux-gnu/openssl/opensslconf.h: + +/usr/include/openssl/err.h: + +/usr/include/openssl/bio.h: + +/usr/include/openssl/crypto.h: + +/usr/include/openssl/stack.h: + +/usr/include/openssl/safestack.h: + +/usr/include/openssl/opensslv.h: + +/usr/include/openssl/symhacks.h: + +/usr/include/openssl/lhash.h: + +/usr/include/openssl/evp.h: + +/usr/include/openssl/objects.h: + +/usr/include/openssl/obj_mac.h: + +/usr/include/openssl/asn1.h: + +/usr/include/openssl/bn.h: + +openssl/../cipher.h: + +openssl/../logger.h: + +openssl/../xalloc.h: diff --git a/src/openssl/.deps/crypto.Po b/src/openssl/.deps/crypto.Po new file mode 100644 index 0000000..7175d88 --- /dev/null +++ b/src/openssl/.deps/crypto.Po @@ -0,0 +1,482 @@ +openssl/crypto.o: openssl/crypto.c /usr/include/stdc-predef.h \ + /usr/include/x86_64-linux-gnu/bits/predefs.h openssl/../system.h \ + openssl/../../config.h openssl/../have.h /usr/include/stdio.h \ + /usr/include/features.h /usr/include/x86_64-linux-gnu/sys/cdefs.h \ + /usr/include/x86_64-linux-gnu/bits/wordsize.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ + /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stddef.h \ + /usr/include/x86_64-linux-gnu/bits/types.h \ + /usr/include/x86_64-linux-gnu/bits/typesizes.h /usr/include/libio.h \ + /usr/include/_G_config.h /usr/include/wchar.h \ + /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdarg.h \ + /usr/include/x86_64-linux-gnu/bits/stdio_lim.h \ + /usr/include/x86_64-linux-gnu/bits/sys_errlist.h \ + /usr/include/x86_64-linux-gnu/bits/stdio.h /usr/include/stdlib.h \ + /usr/include/x86_64-linux-gnu/bits/waitflags.h \ + /usr/include/x86_64-linux-gnu/bits/waitstatus.h /usr/include/endian.h \ + /usr/include/x86_64-linux-gnu/bits/endian.h \ + /usr/include/x86_64-linux-gnu/bits/byteswap.h \ + /usr/include/x86_64-linux-gnu/bits/byteswap-16.h /usr/include/xlocale.h \ + /usr/include/x86_64-linux-gnu/sys/types.h /usr/include/time.h \ + /usr/include/x86_64-linux-gnu/sys/select.h \ + /usr/include/x86_64-linux-gnu/bits/select.h \ + /usr/include/x86_64-linux-gnu/bits/sigset.h \ + /usr/include/x86_64-linux-gnu/bits/time.h \ + /usr/include/x86_64-linux-gnu/sys/sysmacros.h \ + /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h /usr/include/alloca.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib-float.h /usr/include/string.h \ + /usr/include/x86_64-linux-gnu/bits/string.h \ + /usr/include/x86_64-linux-gnu/bits/string2.h /usr/include/ctype.h \ + /usr/include/signal.h /usr/include/x86_64-linux-gnu/bits/signum.h \ + /usr/include/x86_64-linux-gnu/bits/siginfo.h \ + /usr/include/x86_64-linux-gnu/bits/sigaction.h \ + /usr/include/x86_64-linux-gnu/bits/sigcontext.h \ + /usr/include/x86_64-linux-gnu/bits/sigstack.h \ + /usr/include/x86_64-linux-gnu/sys/ucontext.h \ + /usr/include/x86_64-linux-gnu/bits/sigthread.h /usr/include/errno.h \ + /usr/include/x86_64-linux-gnu/bits/errno.h /usr/include/linux/errno.h \ + /usr/include/x86_64-linux-gnu/asm/errno.h \ + /usr/include/asm-generic/errno.h /usr/include/asm-generic/errno-base.h \ + /usr/include/fcntl.h /usr/include/x86_64-linux-gnu/bits/fcntl.h \ + /usr/include/x86_64-linux-gnu/bits/fcntl-linux.h \ + /usr/include/x86_64-linux-gnu/bits/uio.h \ + /usr/include/x86_64-linux-gnu/bits/stat.h /usr/include/unistd.h \ + /usr/include/x86_64-linux-gnu/bits/posix_opt.h \ + /usr/include/x86_64-linux-gnu/bits/environments.h \ + /usr/include/x86_64-linux-gnu/bits/confname.h /usr/include/getopt.h \ + /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdbool.h \ + /usr/include/inttypes.h \ + /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdint.h /usr/include/stdint.h \ + /usr/include/x86_64-linux-gnu/bits/wchar.h /usr/include/syslog.h \ + /usr/include/x86_64-linux-gnu/sys/syslog.h \ + /usr/include/x86_64-linux-gnu/bits/syslog-path.h \ + /usr/include/x86_64-linux-gnu/sys/time.h \ + /usr/include/x86_64-linux-gnu/bits/timex.h \ + /usr/include/x86_64-linux-gnu/sys/stat.h \ + /usr/include/x86_64-linux-gnu/sys/file.h \ + /usr/include/x86_64-linux-gnu/sys/wait.h \ + /usr/include/x86_64-linux-gnu/sys/ioctl.h \ + /usr/include/x86_64-linux-gnu/bits/ioctls.h \ + /usr/include/x86_64-linux-gnu/asm/ioctls.h \ + /usr/include/asm-generic/ioctls.h /usr/include/linux/ioctl.h \ + /usr/include/x86_64-linux-gnu/asm/ioctl.h \ + /usr/include/asm-generic/ioctl.h \ + /usr/include/x86_64-linux-gnu/bits/ioctl-types.h \ + /usr/include/x86_64-linux-gnu/sys/ttydefaults.h \ + /usr/include/x86_64-linux-gnu/sys/param.h \ + /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/limits.h \ + /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/syslimits.h \ + /usr/include/limits.h /usr/include/x86_64-linux-gnu/bits/posix1_lim.h \ + /usr/include/x86_64-linux-gnu/bits/local_lim.h \ + /usr/include/linux/limits.h \ + /usr/include/x86_64-linux-gnu/bits/posix2_lim.h \ + /usr/include/x86_64-linux-gnu/bits/xopen_lim.h \ + /usr/include/x86_64-linux-gnu/bits/param.h /usr/include/linux/param.h \ + /usr/include/x86_64-linux-gnu/asm/param.h \ + /usr/include/asm-generic/param.h \ + /usr/include/x86_64-linux-gnu/sys/resource.h \ + /usr/include/x86_64-linux-gnu/bits/resource.h \ + /usr/include/x86_64-linux-gnu/sys/uio.h \ + /usr/include/x86_64-linux-gnu/sys/un.h \ + /usr/include/x86_64-linux-gnu/bits/sockaddr.h /usr/include/dirent.h \ + /usr/include/x86_64-linux-gnu/bits/dirent.h /usr/include/netdb.h \ + /usr/include/netinet/in.h /usr/include/x86_64-linux-gnu/sys/socket.h \ + /usr/include/x86_64-linux-gnu/bits/socket.h \ + /usr/include/x86_64-linux-gnu/bits/socket_type.h \ + /usr/include/x86_64-linux-gnu/asm/socket.h \ + /usr/include/asm-generic/socket.h \ + /usr/include/x86_64-linux-gnu/asm/sockios.h \ + /usr/include/asm-generic/sockios.h \ + /usr/include/x86_64-linux-gnu/bits/in.h /usr/include/rpc/netdb.h \ + /usr/include/x86_64-linux-gnu/bits/netdb.h /usr/include/net/if.h \ + /usr/include/netinet/in_systm.h /usr/include/arpa/inet.h \ + /usr/include/netinet/ip.h /usr/include/netinet/tcp.h \ + /usr/include/netinet/ip6.h /usr/include/net/ethernet.h \ + /usr/include/linux/if_ether.h /usr/include/linux/types.h \ + /usr/include/x86_64-linux-gnu/asm/types.h \ + /usr/include/asm-generic/types.h /usr/include/asm-generic/int-ll64.h \ + /usr/include/x86_64-linux-gnu/asm/bitsperlong.h \ + /usr/include/asm-generic/bitsperlong.h /usr/include/linux/posix_types.h \ + /usr/include/linux/stddef.h \ + /usr/include/x86_64-linux-gnu/asm/posix_types.h \ + /usr/include/x86_64-linux-gnu/asm/posix_types_64.h \ + /usr/include/asm-generic/posix_types.h /usr/include/net/if_arp.h \ + /usr/include/netinet/ip_icmp.h /usr/include/netinet/icmp6.h \ + /usr/include/netinet/if_ether.h openssl/../dropin.h \ + openssl/../fake-getaddrinfo.h openssl/../fake-gai-errnos.h \ + openssl/../fake-getnameinfo.h /usr/include/openssl/rand.h \ + /usr/include/openssl/ossl_typ.h /usr/include/openssl/e_os2.h \ + /usr/include/x86_64-linux-gnu/openssl/opensslconf.h \ + /usr/include/openssl/evp.h /usr/include/openssl/symhacks.h \ + /usr/include/openssl/bio.h /usr/include/openssl/crypto.h \ + /usr/include/openssl/stack.h /usr/include/openssl/safestack.h \ + /usr/include/openssl/opensslv.h /usr/include/openssl/objects.h \ + /usr/include/openssl/obj_mac.h /usr/include/openssl/asn1.h \ + /usr/include/openssl/bn.h /usr/include/openssl/engine.h \ + /usr/include/openssl/rsa.h /usr/include/openssl/dsa.h \ + /usr/include/openssl/dh.h /usr/include/openssl/ecdh.h \ + /usr/include/openssl/ec.h /usr/include/openssl/ecdsa.h \ + /usr/include/openssl/ui.h /usr/include/openssl/err.h \ + /usr/include/openssl/lhash.h /usr/include/openssl/x509.h \ + /usr/include/openssl/buffer.h /usr/include/openssl/sha.h \ + /usr/include/openssl/x509_vfy.h /usr/include/openssl/pkcs7.h \ + openssl/../crypto.h + +/usr/include/stdc-predef.h: + +/usr/include/x86_64-linux-gnu/bits/predefs.h: + +openssl/../system.h: + +openssl/../../config.h: + +openssl/../have.h: + +/usr/include/stdio.h: + +/usr/include/features.h: + +/usr/include/x86_64-linux-gnu/sys/cdefs.h: + +/usr/include/x86_64-linux-gnu/bits/wordsize.h: + +/usr/include/x86_64-linux-gnu/gnu/stubs.h: + +/usr/include/x86_64-linux-gnu/gnu/stubs-64.h: + +/usr/lib/gcc/x86_64-linux-gnu/4.8/include/stddef.h: + +/usr/include/x86_64-linux-gnu/bits/types.h: + +/usr/include/x86_64-linux-gnu/bits/typesizes.h: + +/usr/include/libio.h: + +/usr/include/_G_config.h: + +/usr/include/wchar.h: + +/usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdarg.h: + +/usr/include/x86_64-linux-gnu/bits/stdio_lim.h: + +/usr/include/x86_64-linux-gnu/bits/sys_errlist.h: + +/usr/include/x86_64-linux-gnu/bits/stdio.h: + +/usr/include/stdlib.h: + +/usr/include/x86_64-linux-gnu/bits/waitflags.h: + +/usr/include/x86_64-linux-gnu/bits/waitstatus.h: + +/usr/include/endian.h: + +/usr/include/x86_64-linux-gnu/bits/endian.h: + +/usr/include/x86_64-linux-gnu/bits/byteswap.h: + +/usr/include/x86_64-linux-gnu/bits/byteswap-16.h: + +/usr/include/xlocale.h: + +/usr/include/x86_64-linux-gnu/sys/types.h: + +/usr/include/time.h: + +/usr/include/x86_64-linux-gnu/sys/select.h: + +/usr/include/x86_64-linux-gnu/bits/select.h: + +/usr/include/x86_64-linux-gnu/bits/sigset.h: + +/usr/include/x86_64-linux-gnu/bits/time.h: + +/usr/include/x86_64-linux-gnu/sys/sysmacros.h: + +/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h: + +/usr/include/alloca.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib-float.h: + +/usr/include/string.h: + +/usr/include/x86_64-linux-gnu/bits/string.h: + +/usr/include/x86_64-linux-gnu/bits/string2.h: + +/usr/include/ctype.h: + +/usr/include/signal.h: + +/usr/include/x86_64-linux-gnu/bits/signum.h: + +/usr/include/x86_64-linux-gnu/bits/siginfo.h: + +/usr/include/x86_64-linux-gnu/bits/sigaction.h: + +/usr/include/x86_64-linux-gnu/bits/sigcontext.h: + +/usr/include/x86_64-linux-gnu/bits/sigstack.h: + +/usr/include/x86_64-linux-gnu/sys/ucontext.h: + +/usr/include/x86_64-linux-gnu/bits/sigthread.h: + +/usr/include/errno.h: + +/usr/include/x86_64-linux-gnu/bits/errno.h: + +/usr/include/linux/errno.h: + +/usr/include/x86_64-linux-gnu/asm/errno.h: + +/usr/include/asm-generic/errno.h: + +/usr/include/asm-generic/errno-base.h: + +/usr/include/fcntl.h: + +/usr/include/x86_64-linux-gnu/bits/fcntl.h: + +/usr/include/x86_64-linux-gnu/bits/fcntl-linux.h: + +/usr/include/x86_64-linux-gnu/bits/uio.h: + +/usr/include/x86_64-linux-gnu/bits/stat.h: + +/usr/include/unistd.h: + +/usr/include/x86_64-linux-gnu/bits/posix_opt.h: + +/usr/include/x86_64-linux-gnu/bits/environments.h: + +/usr/include/x86_64-linux-gnu/bits/confname.h: + +/usr/include/getopt.h: + +/usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdbool.h: + +/usr/include/inttypes.h: + +/usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdint.h: + +/usr/include/stdint.h: + +/usr/include/x86_64-linux-gnu/bits/wchar.h: + +/usr/include/syslog.h: + +/usr/include/x86_64-linux-gnu/sys/syslog.h: + +/usr/include/x86_64-linux-gnu/bits/syslog-path.h: + +/usr/include/x86_64-linux-gnu/sys/time.h: + +/usr/include/x86_64-linux-gnu/bits/timex.h: + +/usr/include/x86_64-linux-gnu/sys/stat.h: + +/usr/include/x86_64-linux-gnu/sys/file.h: + +/usr/include/x86_64-linux-gnu/sys/wait.h: + +/usr/include/x86_64-linux-gnu/sys/ioctl.h: + +/usr/include/x86_64-linux-gnu/bits/ioctls.h: + +/usr/include/x86_64-linux-gnu/asm/ioctls.h: + +/usr/include/asm-generic/ioctls.h: + +/usr/include/linux/ioctl.h: + +/usr/include/x86_64-linux-gnu/asm/ioctl.h: + +/usr/include/asm-generic/ioctl.h: + +/usr/include/x86_64-linux-gnu/bits/ioctl-types.h: + +/usr/include/x86_64-linux-gnu/sys/ttydefaults.h: + +/usr/include/x86_64-linux-gnu/sys/param.h: + +/usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/limits.h: + +/usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/syslimits.h: + +/usr/include/limits.h: + +/usr/include/x86_64-linux-gnu/bits/posix1_lim.h: + +/usr/include/x86_64-linux-gnu/bits/local_lim.h: + +/usr/include/linux/limits.h: + +/usr/include/x86_64-linux-gnu/bits/posix2_lim.h: + +/usr/include/x86_64-linux-gnu/bits/xopen_lim.h: + +/usr/include/x86_64-linux-gnu/bits/param.h: + +/usr/include/linux/param.h: + +/usr/include/x86_64-linux-gnu/asm/param.h: + +/usr/include/asm-generic/param.h: + +/usr/include/x86_64-linux-gnu/sys/resource.h: + +/usr/include/x86_64-linux-gnu/bits/resource.h: + +/usr/include/x86_64-linux-gnu/sys/uio.h: + +/usr/include/x86_64-linux-gnu/sys/un.h: + +/usr/include/x86_64-linux-gnu/bits/sockaddr.h: + +/usr/include/dirent.h: + +/usr/include/x86_64-linux-gnu/bits/dirent.h: + +/usr/include/netdb.h: + +/usr/include/netinet/in.h: + +/usr/include/x86_64-linux-gnu/sys/socket.h: + +/usr/include/x86_64-linux-gnu/bits/socket.h: + +/usr/include/x86_64-linux-gnu/bits/socket_type.h: + +/usr/include/x86_64-linux-gnu/asm/socket.h: + +/usr/include/asm-generic/socket.h: + +/usr/include/x86_64-linux-gnu/asm/sockios.h: + +/usr/include/asm-generic/sockios.h: + +/usr/include/x86_64-linux-gnu/bits/in.h: + +/usr/include/rpc/netdb.h: + +/usr/include/x86_64-linux-gnu/bits/netdb.h: + +/usr/include/net/if.h: + +/usr/include/netinet/in_systm.h: + +/usr/include/arpa/inet.h: + +/usr/include/netinet/ip.h: + +/usr/include/netinet/tcp.h: + +/usr/include/netinet/ip6.h: + +/usr/include/net/ethernet.h: + +/usr/include/linux/if_ether.h: + +/usr/include/linux/types.h: + +/usr/include/x86_64-linux-gnu/asm/types.h: + +/usr/include/asm-generic/types.h: + +/usr/include/asm-generic/int-ll64.h: + +/usr/include/x86_64-linux-gnu/asm/bitsperlong.h: + +/usr/include/asm-generic/bitsperlong.h: + +/usr/include/linux/posix_types.h: + +/usr/include/linux/stddef.h: + +/usr/include/x86_64-linux-gnu/asm/posix_types.h: + +/usr/include/x86_64-linux-gnu/asm/posix_types_64.h: + +/usr/include/asm-generic/posix_types.h: + +/usr/include/net/if_arp.h: + +/usr/include/netinet/ip_icmp.h: + +/usr/include/netinet/icmp6.h: + +/usr/include/netinet/if_ether.h: + +openssl/../dropin.h: + +openssl/../fake-getaddrinfo.h: + +openssl/../fake-gai-errnos.h: + +openssl/../fake-getnameinfo.h: + +/usr/include/openssl/rand.h: + +/usr/include/openssl/ossl_typ.h: + +/usr/include/openssl/e_os2.h: + +/usr/include/x86_64-linux-gnu/openssl/opensslconf.h: + +/usr/include/openssl/evp.h: + +/usr/include/openssl/symhacks.h: + +/usr/include/openssl/bio.h: + +/usr/include/openssl/crypto.h: + +/usr/include/openssl/stack.h: + +/usr/include/openssl/safestack.h: + +/usr/include/openssl/opensslv.h: + +/usr/include/openssl/objects.h: + +/usr/include/openssl/obj_mac.h: + +/usr/include/openssl/asn1.h: + +/usr/include/openssl/bn.h: + +/usr/include/openssl/engine.h: + +/usr/include/openssl/rsa.h: + +/usr/include/openssl/dsa.h: + +/usr/include/openssl/dh.h: + +/usr/include/openssl/ecdh.h: + +/usr/include/openssl/ec.h: + +/usr/include/openssl/ecdsa.h: + +/usr/include/openssl/ui.h: + +/usr/include/openssl/err.h: + +/usr/include/openssl/lhash.h: + +/usr/include/openssl/x509.h: + +/usr/include/openssl/buffer.h: + +/usr/include/openssl/sha.h: + +/usr/include/openssl/x509_vfy.h: + +/usr/include/openssl/pkcs7.h: + +openssl/../crypto.h: diff --git a/src/openssl/.deps/digest.Po b/src/openssl/.deps/digest.Po new file mode 100644 index 0000000..6d30f41 --- /dev/null +++ b/src/openssl/.deps/digest.Po @@ -0,0 +1,458 @@ +openssl/digest.o: openssl/digest.c /usr/include/stdc-predef.h \ + /usr/include/x86_64-linux-gnu/bits/predefs.h openssl/../system.h \ + openssl/../../config.h openssl/../have.h /usr/include/stdio.h \ + /usr/include/features.h /usr/include/x86_64-linux-gnu/sys/cdefs.h \ + /usr/include/x86_64-linux-gnu/bits/wordsize.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ + /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stddef.h \ + /usr/include/x86_64-linux-gnu/bits/types.h \ + /usr/include/x86_64-linux-gnu/bits/typesizes.h /usr/include/libio.h \ + /usr/include/_G_config.h /usr/include/wchar.h \ + /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdarg.h \ + /usr/include/x86_64-linux-gnu/bits/stdio_lim.h \ + /usr/include/x86_64-linux-gnu/bits/sys_errlist.h \ + /usr/include/x86_64-linux-gnu/bits/stdio.h /usr/include/stdlib.h \ + /usr/include/x86_64-linux-gnu/bits/waitflags.h \ + /usr/include/x86_64-linux-gnu/bits/waitstatus.h /usr/include/endian.h \ + /usr/include/x86_64-linux-gnu/bits/endian.h \ + /usr/include/x86_64-linux-gnu/bits/byteswap.h \ + /usr/include/x86_64-linux-gnu/bits/byteswap-16.h /usr/include/xlocale.h \ + /usr/include/x86_64-linux-gnu/sys/types.h /usr/include/time.h \ + /usr/include/x86_64-linux-gnu/sys/select.h \ + /usr/include/x86_64-linux-gnu/bits/select.h \ + /usr/include/x86_64-linux-gnu/bits/sigset.h \ + /usr/include/x86_64-linux-gnu/bits/time.h \ + /usr/include/x86_64-linux-gnu/sys/sysmacros.h \ + /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h /usr/include/alloca.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib-float.h /usr/include/string.h \ + /usr/include/x86_64-linux-gnu/bits/string.h \ + /usr/include/x86_64-linux-gnu/bits/string2.h /usr/include/ctype.h \ + /usr/include/signal.h /usr/include/x86_64-linux-gnu/bits/signum.h \ + /usr/include/x86_64-linux-gnu/bits/siginfo.h \ + /usr/include/x86_64-linux-gnu/bits/sigaction.h \ + /usr/include/x86_64-linux-gnu/bits/sigcontext.h \ + /usr/include/x86_64-linux-gnu/bits/sigstack.h \ + /usr/include/x86_64-linux-gnu/sys/ucontext.h \ + /usr/include/x86_64-linux-gnu/bits/sigthread.h /usr/include/errno.h \ + /usr/include/x86_64-linux-gnu/bits/errno.h /usr/include/linux/errno.h \ + /usr/include/x86_64-linux-gnu/asm/errno.h \ + /usr/include/asm-generic/errno.h /usr/include/asm-generic/errno-base.h \ + /usr/include/fcntl.h /usr/include/x86_64-linux-gnu/bits/fcntl.h \ + /usr/include/x86_64-linux-gnu/bits/fcntl-linux.h \ + /usr/include/x86_64-linux-gnu/bits/uio.h \ + /usr/include/x86_64-linux-gnu/bits/stat.h /usr/include/unistd.h \ + /usr/include/x86_64-linux-gnu/bits/posix_opt.h \ + /usr/include/x86_64-linux-gnu/bits/environments.h \ + /usr/include/x86_64-linux-gnu/bits/confname.h /usr/include/getopt.h \ + /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdbool.h \ + /usr/include/inttypes.h \ + /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdint.h /usr/include/stdint.h \ + /usr/include/x86_64-linux-gnu/bits/wchar.h /usr/include/syslog.h \ + /usr/include/x86_64-linux-gnu/sys/syslog.h \ + /usr/include/x86_64-linux-gnu/bits/syslog-path.h \ + /usr/include/x86_64-linux-gnu/sys/time.h \ + /usr/include/x86_64-linux-gnu/bits/timex.h \ + /usr/include/x86_64-linux-gnu/sys/stat.h \ + /usr/include/x86_64-linux-gnu/sys/file.h \ + /usr/include/x86_64-linux-gnu/sys/wait.h \ + /usr/include/x86_64-linux-gnu/sys/ioctl.h \ + /usr/include/x86_64-linux-gnu/bits/ioctls.h \ + /usr/include/x86_64-linux-gnu/asm/ioctls.h \ + /usr/include/asm-generic/ioctls.h /usr/include/linux/ioctl.h \ + /usr/include/x86_64-linux-gnu/asm/ioctl.h \ + /usr/include/asm-generic/ioctl.h \ + /usr/include/x86_64-linux-gnu/bits/ioctl-types.h \ + /usr/include/x86_64-linux-gnu/sys/ttydefaults.h \ + /usr/include/x86_64-linux-gnu/sys/param.h \ + /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/limits.h \ + /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/syslimits.h \ + /usr/include/limits.h /usr/include/x86_64-linux-gnu/bits/posix1_lim.h \ + /usr/include/x86_64-linux-gnu/bits/local_lim.h \ + /usr/include/linux/limits.h \ + /usr/include/x86_64-linux-gnu/bits/posix2_lim.h \ + /usr/include/x86_64-linux-gnu/bits/xopen_lim.h \ + /usr/include/x86_64-linux-gnu/bits/param.h /usr/include/linux/param.h \ + /usr/include/x86_64-linux-gnu/asm/param.h \ + /usr/include/asm-generic/param.h \ + /usr/include/x86_64-linux-gnu/sys/resource.h \ + /usr/include/x86_64-linux-gnu/bits/resource.h \ + /usr/include/x86_64-linux-gnu/sys/uio.h \ + /usr/include/x86_64-linux-gnu/sys/un.h \ + /usr/include/x86_64-linux-gnu/bits/sockaddr.h /usr/include/dirent.h \ + /usr/include/x86_64-linux-gnu/bits/dirent.h /usr/include/netdb.h \ + /usr/include/netinet/in.h /usr/include/x86_64-linux-gnu/sys/socket.h \ + /usr/include/x86_64-linux-gnu/bits/socket.h \ + /usr/include/x86_64-linux-gnu/bits/socket_type.h \ + /usr/include/x86_64-linux-gnu/asm/socket.h \ + /usr/include/asm-generic/socket.h \ + /usr/include/x86_64-linux-gnu/asm/sockios.h \ + /usr/include/asm-generic/sockios.h \ + /usr/include/x86_64-linux-gnu/bits/in.h /usr/include/rpc/netdb.h \ + /usr/include/x86_64-linux-gnu/bits/netdb.h /usr/include/net/if.h \ + /usr/include/netinet/in_systm.h /usr/include/arpa/inet.h \ + /usr/include/netinet/ip.h /usr/include/netinet/tcp.h \ + /usr/include/netinet/ip6.h /usr/include/net/ethernet.h \ + /usr/include/linux/if_ether.h /usr/include/linux/types.h \ + /usr/include/x86_64-linux-gnu/asm/types.h \ + /usr/include/asm-generic/types.h /usr/include/asm-generic/int-ll64.h \ + /usr/include/x86_64-linux-gnu/asm/bitsperlong.h \ + /usr/include/asm-generic/bitsperlong.h /usr/include/linux/posix_types.h \ + /usr/include/linux/stddef.h \ + /usr/include/x86_64-linux-gnu/asm/posix_types.h \ + /usr/include/x86_64-linux-gnu/asm/posix_types_64.h \ + /usr/include/asm-generic/posix_types.h /usr/include/net/if_arp.h \ + /usr/include/netinet/ip_icmp.h /usr/include/netinet/icmp6.h \ + /usr/include/netinet/if_ether.h openssl/../dropin.h \ + openssl/../fake-getaddrinfo.h openssl/../fake-gai-errnos.h \ + openssl/../fake-getnameinfo.h openssl/../utils.h openssl/../xalloc.h \ + /usr/include/openssl/err.h /usr/include/openssl/e_os2.h \ + /usr/include/x86_64-linux-gnu/openssl/opensslconf.h \ + /usr/include/openssl/ossl_typ.h /usr/include/openssl/bio.h \ + /usr/include/openssl/crypto.h /usr/include/openssl/stack.h \ + /usr/include/openssl/safestack.h /usr/include/openssl/opensslv.h \ + /usr/include/openssl/symhacks.h /usr/include/openssl/lhash.h \ + /usr/include/openssl/hmac.h /usr/include/openssl/evp.h \ + /usr/include/openssl/objects.h /usr/include/openssl/obj_mac.h \ + /usr/include/openssl/asn1.h /usr/include/openssl/bn.h openssl/digest.h \ + openssl/../digest.h openssl/../logger.h + +/usr/include/stdc-predef.h: + +/usr/include/x86_64-linux-gnu/bits/predefs.h: + +openssl/../system.h: + +openssl/../../config.h: + +openssl/../have.h: + +/usr/include/stdio.h: + +/usr/include/features.h: + +/usr/include/x86_64-linux-gnu/sys/cdefs.h: + +/usr/include/x86_64-linux-gnu/bits/wordsize.h: + +/usr/include/x86_64-linux-gnu/gnu/stubs.h: + +/usr/include/x86_64-linux-gnu/gnu/stubs-64.h: + +/usr/lib/gcc/x86_64-linux-gnu/4.8/include/stddef.h: + +/usr/include/x86_64-linux-gnu/bits/types.h: + +/usr/include/x86_64-linux-gnu/bits/typesizes.h: + +/usr/include/libio.h: + +/usr/include/_G_config.h: + +/usr/include/wchar.h: + +/usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdarg.h: + +/usr/include/x86_64-linux-gnu/bits/stdio_lim.h: + +/usr/include/x86_64-linux-gnu/bits/sys_errlist.h: + +/usr/include/x86_64-linux-gnu/bits/stdio.h: + +/usr/include/stdlib.h: + +/usr/include/x86_64-linux-gnu/bits/waitflags.h: + +/usr/include/x86_64-linux-gnu/bits/waitstatus.h: + +/usr/include/endian.h: + +/usr/include/x86_64-linux-gnu/bits/endian.h: + +/usr/include/x86_64-linux-gnu/bits/byteswap.h: + +/usr/include/x86_64-linux-gnu/bits/byteswap-16.h: + +/usr/include/xlocale.h: + +/usr/include/x86_64-linux-gnu/sys/types.h: + +/usr/include/time.h: + +/usr/include/x86_64-linux-gnu/sys/select.h: + +/usr/include/x86_64-linux-gnu/bits/select.h: + +/usr/include/x86_64-linux-gnu/bits/sigset.h: + +/usr/include/x86_64-linux-gnu/bits/time.h: + +/usr/include/x86_64-linux-gnu/sys/sysmacros.h: + +/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h: + +/usr/include/alloca.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib-float.h: + +/usr/include/string.h: + +/usr/include/x86_64-linux-gnu/bits/string.h: + +/usr/include/x86_64-linux-gnu/bits/string2.h: + +/usr/include/ctype.h: + +/usr/include/signal.h: + +/usr/include/x86_64-linux-gnu/bits/signum.h: + +/usr/include/x86_64-linux-gnu/bits/siginfo.h: + +/usr/include/x86_64-linux-gnu/bits/sigaction.h: + +/usr/include/x86_64-linux-gnu/bits/sigcontext.h: + +/usr/include/x86_64-linux-gnu/bits/sigstack.h: + +/usr/include/x86_64-linux-gnu/sys/ucontext.h: + +/usr/include/x86_64-linux-gnu/bits/sigthread.h: + +/usr/include/errno.h: + +/usr/include/x86_64-linux-gnu/bits/errno.h: + +/usr/include/linux/errno.h: + +/usr/include/x86_64-linux-gnu/asm/errno.h: + +/usr/include/asm-generic/errno.h: + +/usr/include/asm-generic/errno-base.h: + +/usr/include/fcntl.h: + +/usr/include/x86_64-linux-gnu/bits/fcntl.h: + +/usr/include/x86_64-linux-gnu/bits/fcntl-linux.h: + +/usr/include/x86_64-linux-gnu/bits/uio.h: + +/usr/include/x86_64-linux-gnu/bits/stat.h: + +/usr/include/unistd.h: + +/usr/include/x86_64-linux-gnu/bits/posix_opt.h: + +/usr/include/x86_64-linux-gnu/bits/environments.h: + +/usr/include/x86_64-linux-gnu/bits/confname.h: + +/usr/include/getopt.h: + +/usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdbool.h: + +/usr/include/inttypes.h: + +/usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdint.h: + +/usr/include/stdint.h: + +/usr/include/x86_64-linux-gnu/bits/wchar.h: + +/usr/include/syslog.h: + +/usr/include/x86_64-linux-gnu/sys/syslog.h: + +/usr/include/x86_64-linux-gnu/bits/syslog-path.h: + +/usr/include/x86_64-linux-gnu/sys/time.h: + +/usr/include/x86_64-linux-gnu/bits/timex.h: + +/usr/include/x86_64-linux-gnu/sys/stat.h: + +/usr/include/x86_64-linux-gnu/sys/file.h: + +/usr/include/x86_64-linux-gnu/sys/wait.h: + +/usr/include/x86_64-linux-gnu/sys/ioctl.h: + +/usr/include/x86_64-linux-gnu/bits/ioctls.h: + +/usr/include/x86_64-linux-gnu/asm/ioctls.h: + +/usr/include/asm-generic/ioctls.h: + +/usr/include/linux/ioctl.h: + +/usr/include/x86_64-linux-gnu/asm/ioctl.h: + +/usr/include/asm-generic/ioctl.h: + +/usr/include/x86_64-linux-gnu/bits/ioctl-types.h: + +/usr/include/x86_64-linux-gnu/sys/ttydefaults.h: + +/usr/include/x86_64-linux-gnu/sys/param.h: + +/usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/limits.h: + +/usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/syslimits.h: + +/usr/include/limits.h: + +/usr/include/x86_64-linux-gnu/bits/posix1_lim.h: + +/usr/include/x86_64-linux-gnu/bits/local_lim.h: + +/usr/include/linux/limits.h: + +/usr/include/x86_64-linux-gnu/bits/posix2_lim.h: + +/usr/include/x86_64-linux-gnu/bits/xopen_lim.h: + +/usr/include/x86_64-linux-gnu/bits/param.h: + +/usr/include/linux/param.h: + +/usr/include/x86_64-linux-gnu/asm/param.h: + +/usr/include/asm-generic/param.h: + +/usr/include/x86_64-linux-gnu/sys/resource.h: + +/usr/include/x86_64-linux-gnu/bits/resource.h: + +/usr/include/x86_64-linux-gnu/sys/uio.h: + +/usr/include/x86_64-linux-gnu/sys/un.h: + +/usr/include/x86_64-linux-gnu/bits/sockaddr.h: + +/usr/include/dirent.h: + +/usr/include/x86_64-linux-gnu/bits/dirent.h: + +/usr/include/netdb.h: + +/usr/include/netinet/in.h: + +/usr/include/x86_64-linux-gnu/sys/socket.h: + +/usr/include/x86_64-linux-gnu/bits/socket.h: + +/usr/include/x86_64-linux-gnu/bits/socket_type.h: + +/usr/include/x86_64-linux-gnu/asm/socket.h: + +/usr/include/asm-generic/socket.h: + +/usr/include/x86_64-linux-gnu/asm/sockios.h: + +/usr/include/asm-generic/sockios.h: + +/usr/include/x86_64-linux-gnu/bits/in.h: + +/usr/include/rpc/netdb.h: + +/usr/include/x86_64-linux-gnu/bits/netdb.h: + +/usr/include/net/if.h: + +/usr/include/netinet/in_systm.h: + +/usr/include/arpa/inet.h: + +/usr/include/netinet/ip.h: + +/usr/include/netinet/tcp.h: + +/usr/include/netinet/ip6.h: + +/usr/include/net/ethernet.h: + +/usr/include/linux/if_ether.h: + +/usr/include/linux/types.h: + +/usr/include/x86_64-linux-gnu/asm/types.h: + +/usr/include/asm-generic/types.h: + +/usr/include/asm-generic/int-ll64.h: + +/usr/include/x86_64-linux-gnu/asm/bitsperlong.h: + +/usr/include/asm-generic/bitsperlong.h: + +/usr/include/linux/posix_types.h: + +/usr/include/linux/stddef.h: + +/usr/include/x86_64-linux-gnu/asm/posix_types.h: + +/usr/include/x86_64-linux-gnu/asm/posix_types_64.h: + +/usr/include/asm-generic/posix_types.h: + +/usr/include/net/if_arp.h: + +/usr/include/netinet/ip_icmp.h: + +/usr/include/netinet/icmp6.h: + +/usr/include/netinet/if_ether.h: + +openssl/../dropin.h: + +openssl/../fake-getaddrinfo.h: + +openssl/../fake-gai-errnos.h: + +openssl/../fake-getnameinfo.h: + +openssl/../utils.h: + +openssl/../xalloc.h: + +/usr/include/openssl/err.h: + +/usr/include/openssl/e_os2.h: + +/usr/include/x86_64-linux-gnu/openssl/opensslconf.h: + +/usr/include/openssl/ossl_typ.h: + +/usr/include/openssl/bio.h: + +/usr/include/openssl/crypto.h: + +/usr/include/openssl/stack.h: + +/usr/include/openssl/safestack.h: + +/usr/include/openssl/opensslv.h: + +/usr/include/openssl/symhacks.h: + +/usr/include/openssl/lhash.h: + +/usr/include/openssl/hmac.h: + +/usr/include/openssl/evp.h: + +/usr/include/openssl/objects.h: + +/usr/include/openssl/obj_mac.h: + +/usr/include/openssl/asn1.h: + +/usr/include/openssl/bn.h: + +openssl/digest.h: + +openssl/../digest.h: + +openssl/../logger.h: diff --git a/src/openssl/.deps/ecdh.Po b/src/openssl/.deps/ecdh.Po new file mode 100644 index 0000000..96dcd00 --- /dev/null +++ b/src/openssl/.deps/ecdh.Po @@ -0,0 +1,454 @@ +openssl/ecdh.o: openssl/ecdh.c /usr/include/stdc-predef.h \ + /usr/include/x86_64-linux-gnu/bits/predefs.h openssl/../system.h \ + openssl/../../config.h openssl/../have.h /usr/include/stdio.h \ + /usr/include/features.h /usr/include/x86_64-linux-gnu/sys/cdefs.h \ + /usr/include/x86_64-linux-gnu/bits/wordsize.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ + /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stddef.h \ + /usr/include/x86_64-linux-gnu/bits/types.h \ + /usr/include/x86_64-linux-gnu/bits/typesizes.h /usr/include/libio.h \ + /usr/include/_G_config.h /usr/include/wchar.h \ + /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdarg.h \ + /usr/include/x86_64-linux-gnu/bits/stdio_lim.h \ + /usr/include/x86_64-linux-gnu/bits/sys_errlist.h \ + /usr/include/x86_64-linux-gnu/bits/stdio.h /usr/include/stdlib.h \ + /usr/include/x86_64-linux-gnu/bits/waitflags.h \ + /usr/include/x86_64-linux-gnu/bits/waitstatus.h /usr/include/endian.h \ + /usr/include/x86_64-linux-gnu/bits/endian.h \ + /usr/include/x86_64-linux-gnu/bits/byteswap.h \ + /usr/include/x86_64-linux-gnu/bits/byteswap-16.h /usr/include/xlocale.h \ + /usr/include/x86_64-linux-gnu/sys/types.h /usr/include/time.h \ + /usr/include/x86_64-linux-gnu/sys/select.h \ + /usr/include/x86_64-linux-gnu/bits/select.h \ + /usr/include/x86_64-linux-gnu/bits/sigset.h \ + /usr/include/x86_64-linux-gnu/bits/time.h \ + /usr/include/x86_64-linux-gnu/sys/sysmacros.h \ + /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h /usr/include/alloca.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib-float.h /usr/include/string.h \ + /usr/include/x86_64-linux-gnu/bits/string.h \ + /usr/include/x86_64-linux-gnu/bits/string2.h /usr/include/ctype.h \ + /usr/include/signal.h /usr/include/x86_64-linux-gnu/bits/signum.h \ + /usr/include/x86_64-linux-gnu/bits/siginfo.h \ + /usr/include/x86_64-linux-gnu/bits/sigaction.h \ + /usr/include/x86_64-linux-gnu/bits/sigcontext.h \ + /usr/include/x86_64-linux-gnu/bits/sigstack.h \ + /usr/include/x86_64-linux-gnu/sys/ucontext.h \ + /usr/include/x86_64-linux-gnu/bits/sigthread.h /usr/include/errno.h \ + /usr/include/x86_64-linux-gnu/bits/errno.h /usr/include/linux/errno.h \ + /usr/include/x86_64-linux-gnu/asm/errno.h \ + /usr/include/asm-generic/errno.h /usr/include/asm-generic/errno-base.h \ + /usr/include/fcntl.h /usr/include/x86_64-linux-gnu/bits/fcntl.h \ + /usr/include/x86_64-linux-gnu/bits/fcntl-linux.h \ + /usr/include/x86_64-linux-gnu/bits/uio.h \ + /usr/include/x86_64-linux-gnu/bits/stat.h /usr/include/unistd.h \ + /usr/include/x86_64-linux-gnu/bits/posix_opt.h \ + /usr/include/x86_64-linux-gnu/bits/environments.h \ + /usr/include/x86_64-linux-gnu/bits/confname.h /usr/include/getopt.h \ + /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdbool.h \ + /usr/include/inttypes.h \ + /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdint.h /usr/include/stdint.h \ + /usr/include/x86_64-linux-gnu/bits/wchar.h /usr/include/syslog.h \ + /usr/include/x86_64-linux-gnu/sys/syslog.h \ + /usr/include/x86_64-linux-gnu/bits/syslog-path.h \ + /usr/include/x86_64-linux-gnu/sys/time.h \ + /usr/include/x86_64-linux-gnu/bits/timex.h \ + /usr/include/x86_64-linux-gnu/sys/stat.h \ + /usr/include/x86_64-linux-gnu/sys/file.h \ + /usr/include/x86_64-linux-gnu/sys/wait.h \ + /usr/include/x86_64-linux-gnu/sys/ioctl.h \ + /usr/include/x86_64-linux-gnu/bits/ioctls.h \ + /usr/include/x86_64-linux-gnu/asm/ioctls.h \ + /usr/include/asm-generic/ioctls.h /usr/include/linux/ioctl.h \ + /usr/include/x86_64-linux-gnu/asm/ioctl.h \ + /usr/include/asm-generic/ioctl.h \ + /usr/include/x86_64-linux-gnu/bits/ioctl-types.h \ + /usr/include/x86_64-linux-gnu/sys/ttydefaults.h \ + /usr/include/x86_64-linux-gnu/sys/param.h \ + /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/limits.h \ + /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/syslimits.h \ + /usr/include/limits.h /usr/include/x86_64-linux-gnu/bits/posix1_lim.h \ + /usr/include/x86_64-linux-gnu/bits/local_lim.h \ + /usr/include/linux/limits.h \ + /usr/include/x86_64-linux-gnu/bits/posix2_lim.h \ + /usr/include/x86_64-linux-gnu/bits/xopen_lim.h \ + /usr/include/x86_64-linux-gnu/bits/param.h /usr/include/linux/param.h \ + /usr/include/x86_64-linux-gnu/asm/param.h \ + /usr/include/asm-generic/param.h \ + /usr/include/x86_64-linux-gnu/sys/resource.h \ + /usr/include/x86_64-linux-gnu/bits/resource.h \ + /usr/include/x86_64-linux-gnu/sys/uio.h \ + /usr/include/x86_64-linux-gnu/sys/un.h \ + /usr/include/x86_64-linux-gnu/bits/sockaddr.h /usr/include/dirent.h \ + /usr/include/x86_64-linux-gnu/bits/dirent.h /usr/include/netdb.h \ + /usr/include/netinet/in.h /usr/include/x86_64-linux-gnu/sys/socket.h \ + /usr/include/x86_64-linux-gnu/bits/socket.h \ + /usr/include/x86_64-linux-gnu/bits/socket_type.h \ + /usr/include/x86_64-linux-gnu/asm/socket.h \ + /usr/include/asm-generic/socket.h \ + /usr/include/x86_64-linux-gnu/asm/sockios.h \ + /usr/include/asm-generic/sockios.h \ + /usr/include/x86_64-linux-gnu/bits/in.h /usr/include/rpc/netdb.h \ + /usr/include/x86_64-linux-gnu/bits/netdb.h /usr/include/net/if.h \ + /usr/include/netinet/in_systm.h /usr/include/arpa/inet.h \ + /usr/include/netinet/ip.h /usr/include/netinet/tcp.h \ + /usr/include/netinet/ip6.h /usr/include/net/ethernet.h \ + /usr/include/linux/if_ether.h /usr/include/linux/types.h \ + /usr/include/x86_64-linux-gnu/asm/types.h \ + /usr/include/asm-generic/types.h /usr/include/asm-generic/int-ll64.h \ + /usr/include/x86_64-linux-gnu/asm/bitsperlong.h \ + /usr/include/asm-generic/bitsperlong.h /usr/include/linux/posix_types.h \ + /usr/include/linux/stddef.h \ + /usr/include/x86_64-linux-gnu/asm/posix_types.h \ + /usr/include/x86_64-linux-gnu/asm/posix_types_64.h \ + /usr/include/asm-generic/posix_types.h /usr/include/net/if_arp.h \ + /usr/include/netinet/ip_icmp.h /usr/include/netinet/icmp6.h \ + /usr/include/netinet/if_ether.h openssl/../dropin.h \ + openssl/../fake-getaddrinfo.h openssl/../fake-gai-errnos.h \ + openssl/../fake-getnameinfo.h /usr/include/openssl/err.h \ + /usr/include/openssl/e_os2.h \ + /usr/include/x86_64-linux-gnu/openssl/opensslconf.h \ + /usr/include/openssl/ossl_typ.h /usr/include/openssl/bio.h \ + /usr/include/openssl/crypto.h /usr/include/openssl/stack.h \ + /usr/include/openssl/safestack.h /usr/include/openssl/opensslv.h \ + /usr/include/openssl/symhacks.h /usr/include/openssl/lhash.h \ + /usr/include/openssl/ec.h /usr/include/openssl/asn1.h \ + /usr/include/openssl/bn.h /usr/include/openssl/ecdh.h \ + /usr/include/openssl/obj_mac.h openssl/../ecdh.h openssl/../logger.h \ + openssl/../utils.h openssl/../xalloc.h + +/usr/include/stdc-predef.h: + +/usr/include/x86_64-linux-gnu/bits/predefs.h: + +openssl/../system.h: + +openssl/../../config.h: + +openssl/../have.h: + +/usr/include/stdio.h: + +/usr/include/features.h: + +/usr/include/x86_64-linux-gnu/sys/cdefs.h: + +/usr/include/x86_64-linux-gnu/bits/wordsize.h: + +/usr/include/x86_64-linux-gnu/gnu/stubs.h: + +/usr/include/x86_64-linux-gnu/gnu/stubs-64.h: + +/usr/lib/gcc/x86_64-linux-gnu/4.8/include/stddef.h: + +/usr/include/x86_64-linux-gnu/bits/types.h: + +/usr/include/x86_64-linux-gnu/bits/typesizes.h: + +/usr/include/libio.h: + +/usr/include/_G_config.h: + +/usr/include/wchar.h: + +/usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdarg.h: + +/usr/include/x86_64-linux-gnu/bits/stdio_lim.h: + +/usr/include/x86_64-linux-gnu/bits/sys_errlist.h: + +/usr/include/x86_64-linux-gnu/bits/stdio.h: + +/usr/include/stdlib.h: + +/usr/include/x86_64-linux-gnu/bits/waitflags.h: + +/usr/include/x86_64-linux-gnu/bits/waitstatus.h: + +/usr/include/endian.h: + +/usr/include/x86_64-linux-gnu/bits/endian.h: + +/usr/include/x86_64-linux-gnu/bits/byteswap.h: + +/usr/include/x86_64-linux-gnu/bits/byteswap-16.h: + +/usr/include/xlocale.h: + +/usr/include/x86_64-linux-gnu/sys/types.h: + +/usr/include/time.h: + +/usr/include/x86_64-linux-gnu/sys/select.h: + +/usr/include/x86_64-linux-gnu/bits/select.h: + +/usr/include/x86_64-linux-gnu/bits/sigset.h: + +/usr/include/x86_64-linux-gnu/bits/time.h: + +/usr/include/x86_64-linux-gnu/sys/sysmacros.h: + +/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h: + +/usr/include/alloca.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib-float.h: + +/usr/include/string.h: + +/usr/include/x86_64-linux-gnu/bits/string.h: + +/usr/include/x86_64-linux-gnu/bits/string2.h: + +/usr/include/ctype.h: + +/usr/include/signal.h: + +/usr/include/x86_64-linux-gnu/bits/signum.h: + +/usr/include/x86_64-linux-gnu/bits/siginfo.h: + +/usr/include/x86_64-linux-gnu/bits/sigaction.h: + +/usr/include/x86_64-linux-gnu/bits/sigcontext.h: + +/usr/include/x86_64-linux-gnu/bits/sigstack.h: + +/usr/include/x86_64-linux-gnu/sys/ucontext.h: + +/usr/include/x86_64-linux-gnu/bits/sigthread.h: + +/usr/include/errno.h: + +/usr/include/x86_64-linux-gnu/bits/errno.h: + +/usr/include/linux/errno.h: + +/usr/include/x86_64-linux-gnu/asm/errno.h: + +/usr/include/asm-generic/errno.h: + +/usr/include/asm-generic/errno-base.h: + +/usr/include/fcntl.h: + +/usr/include/x86_64-linux-gnu/bits/fcntl.h: + +/usr/include/x86_64-linux-gnu/bits/fcntl-linux.h: + +/usr/include/x86_64-linux-gnu/bits/uio.h: + +/usr/include/x86_64-linux-gnu/bits/stat.h: + +/usr/include/unistd.h: + +/usr/include/x86_64-linux-gnu/bits/posix_opt.h: + +/usr/include/x86_64-linux-gnu/bits/environments.h: + +/usr/include/x86_64-linux-gnu/bits/confname.h: + +/usr/include/getopt.h: + +/usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdbool.h: + +/usr/include/inttypes.h: + +/usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdint.h: + +/usr/include/stdint.h: + +/usr/include/x86_64-linux-gnu/bits/wchar.h: + +/usr/include/syslog.h: + +/usr/include/x86_64-linux-gnu/sys/syslog.h: + +/usr/include/x86_64-linux-gnu/bits/syslog-path.h: + +/usr/include/x86_64-linux-gnu/sys/time.h: + +/usr/include/x86_64-linux-gnu/bits/timex.h: + +/usr/include/x86_64-linux-gnu/sys/stat.h: + +/usr/include/x86_64-linux-gnu/sys/file.h: + +/usr/include/x86_64-linux-gnu/sys/wait.h: + +/usr/include/x86_64-linux-gnu/sys/ioctl.h: + +/usr/include/x86_64-linux-gnu/bits/ioctls.h: + +/usr/include/x86_64-linux-gnu/asm/ioctls.h: + +/usr/include/asm-generic/ioctls.h: + +/usr/include/linux/ioctl.h: + +/usr/include/x86_64-linux-gnu/asm/ioctl.h: + +/usr/include/asm-generic/ioctl.h: + +/usr/include/x86_64-linux-gnu/bits/ioctl-types.h: + +/usr/include/x86_64-linux-gnu/sys/ttydefaults.h: + +/usr/include/x86_64-linux-gnu/sys/param.h: + +/usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/limits.h: + +/usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/syslimits.h: + +/usr/include/limits.h: + +/usr/include/x86_64-linux-gnu/bits/posix1_lim.h: + +/usr/include/x86_64-linux-gnu/bits/local_lim.h: + +/usr/include/linux/limits.h: + +/usr/include/x86_64-linux-gnu/bits/posix2_lim.h: + +/usr/include/x86_64-linux-gnu/bits/xopen_lim.h: + +/usr/include/x86_64-linux-gnu/bits/param.h: + +/usr/include/linux/param.h: + +/usr/include/x86_64-linux-gnu/asm/param.h: + +/usr/include/asm-generic/param.h: + +/usr/include/x86_64-linux-gnu/sys/resource.h: + +/usr/include/x86_64-linux-gnu/bits/resource.h: + +/usr/include/x86_64-linux-gnu/sys/uio.h: + +/usr/include/x86_64-linux-gnu/sys/un.h: + +/usr/include/x86_64-linux-gnu/bits/sockaddr.h: + +/usr/include/dirent.h: + +/usr/include/x86_64-linux-gnu/bits/dirent.h: + +/usr/include/netdb.h: + +/usr/include/netinet/in.h: + +/usr/include/x86_64-linux-gnu/sys/socket.h: + +/usr/include/x86_64-linux-gnu/bits/socket.h: + +/usr/include/x86_64-linux-gnu/bits/socket_type.h: + +/usr/include/x86_64-linux-gnu/asm/socket.h: + +/usr/include/asm-generic/socket.h: + +/usr/include/x86_64-linux-gnu/asm/sockios.h: + +/usr/include/asm-generic/sockios.h: + +/usr/include/x86_64-linux-gnu/bits/in.h: + +/usr/include/rpc/netdb.h: + +/usr/include/x86_64-linux-gnu/bits/netdb.h: + +/usr/include/net/if.h: + +/usr/include/netinet/in_systm.h: + +/usr/include/arpa/inet.h: + +/usr/include/netinet/ip.h: + +/usr/include/netinet/tcp.h: + +/usr/include/netinet/ip6.h: + +/usr/include/net/ethernet.h: + +/usr/include/linux/if_ether.h: + +/usr/include/linux/types.h: + +/usr/include/x86_64-linux-gnu/asm/types.h: + +/usr/include/asm-generic/types.h: + +/usr/include/asm-generic/int-ll64.h: + +/usr/include/x86_64-linux-gnu/asm/bitsperlong.h: + +/usr/include/asm-generic/bitsperlong.h: + +/usr/include/linux/posix_types.h: + +/usr/include/linux/stddef.h: + +/usr/include/x86_64-linux-gnu/asm/posix_types.h: + +/usr/include/x86_64-linux-gnu/asm/posix_types_64.h: + +/usr/include/asm-generic/posix_types.h: + +/usr/include/net/if_arp.h: + +/usr/include/netinet/ip_icmp.h: + +/usr/include/netinet/icmp6.h: + +/usr/include/netinet/if_ether.h: + +openssl/../dropin.h: + +openssl/../fake-getaddrinfo.h: + +openssl/../fake-gai-errnos.h: + +openssl/../fake-getnameinfo.h: + +/usr/include/openssl/err.h: + +/usr/include/openssl/e_os2.h: + +/usr/include/x86_64-linux-gnu/openssl/opensslconf.h: + +/usr/include/openssl/ossl_typ.h: + +/usr/include/openssl/bio.h: + +/usr/include/openssl/crypto.h: + +/usr/include/openssl/stack.h: + +/usr/include/openssl/safestack.h: + +/usr/include/openssl/opensslv.h: + +/usr/include/openssl/symhacks.h: + +/usr/include/openssl/lhash.h: + +/usr/include/openssl/ec.h: + +/usr/include/openssl/asn1.h: + +/usr/include/openssl/bn.h: + +/usr/include/openssl/ecdh.h: + +/usr/include/openssl/obj_mac.h: + +openssl/../ecdh.h: + +openssl/../logger.h: + +openssl/../utils.h: + +openssl/../xalloc.h: diff --git a/src/openssl/.deps/ecdsa.Po b/src/openssl/.deps/ecdsa.Po new file mode 100644 index 0000000..f6e3f65 --- /dev/null +++ b/src/openssl/.deps/ecdsa.Po @@ -0,0 +1,487 @@ +openssl/ecdsa.o: openssl/ecdsa.c /usr/include/stdc-predef.h \ + /usr/include/x86_64-linux-gnu/bits/predefs.h openssl/../system.h \ + openssl/../../config.h openssl/../have.h /usr/include/stdio.h \ + /usr/include/features.h /usr/include/x86_64-linux-gnu/sys/cdefs.h \ + /usr/include/x86_64-linux-gnu/bits/wordsize.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ + /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stddef.h \ + /usr/include/x86_64-linux-gnu/bits/types.h \ + /usr/include/x86_64-linux-gnu/bits/typesizes.h /usr/include/libio.h \ + /usr/include/_G_config.h /usr/include/wchar.h \ + /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdarg.h \ + /usr/include/x86_64-linux-gnu/bits/stdio_lim.h \ + /usr/include/x86_64-linux-gnu/bits/sys_errlist.h \ + /usr/include/x86_64-linux-gnu/bits/stdio.h /usr/include/stdlib.h \ + /usr/include/x86_64-linux-gnu/bits/waitflags.h \ + /usr/include/x86_64-linux-gnu/bits/waitstatus.h /usr/include/endian.h \ + /usr/include/x86_64-linux-gnu/bits/endian.h \ + /usr/include/x86_64-linux-gnu/bits/byteswap.h \ + /usr/include/x86_64-linux-gnu/bits/byteswap-16.h /usr/include/xlocale.h \ + /usr/include/x86_64-linux-gnu/sys/types.h /usr/include/time.h \ + /usr/include/x86_64-linux-gnu/sys/select.h \ + /usr/include/x86_64-linux-gnu/bits/select.h \ + /usr/include/x86_64-linux-gnu/bits/sigset.h \ + /usr/include/x86_64-linux-gnu/bits/time.h \ + /usr/include/x86_64-linux-gnu/sys/sysmacros.h \ + /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h /usr/include/alloca.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib-float.h /usr/include/string.h \ + /usr/include/x86_64-linux-gnu/bits/string.h \ + /usr/include/x86_64-linux-gnu/bits/string2.h /usr/include/ctype.h \ + /usr/include/signal.h /usr/include/x86_64-linux-gnu/bits/signum.h \ + /usr/include/x86_64-linux-gnu/bits/siginfo.h \ + /usr/include/x86_64-linux-gnu/bits/sigaction.h \ + /usr/include/x86_64-linux-gnu/bits/sigcontext.h \ + /usr/include/x86_64-linux-gnu/bits/sigstack.h \ + /usr/include/x86_64-linux-gnu/sys/ucontext.h \ + /usr/include/x86_64-linux-gnu/bits/sigthread.h /usr/include/errno.h \ + /usr/include/x86_64-linux-gnu/bits/errno.h /usr/include/linux/errno.h \ + /usr/include/x86_64-linux-gnu/asm/errno.h \ + /usr/include/asm-generic/errno.h /usr/include/asm-generic/errno-base.h \ + /usr/include/fcntl.h /usr/include/x86_64-linux-gnu/bits/fcntl.h \ + /usr/include/x86_64-linux-gnu/bits/fcntl-linux.h \ + /usr/include/x86_64-linux-gnu/bits/uio.h \ + /usr/include/x86_64-linux-gnu/bits/stat.h /usr/include/unistd.h \ + /usr/include/x86_64-linux-gnu/bits/posix_opt.h \ + /usr/include/x86_64-linux-gnu/bits/environments.h \ + /usr/include/x86_64-linux-gnu/bits/confname.h /usr/include/getopt.h \ + /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdbool.h \ + /usr/include/inttypes.h \ + /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdint.h /usr/include/stdint.h \ + /usr/include/x86_64-linux-gnu/bits/wchar.h /usr/include/syslog.h \ + /usr/include/x86_64-linux-gnu/sys/syslog.h \ + /usr/include/x86_64-linux-gnu/bits/syslog-path.h \ + /usr/include/x86_64-linux-gnu/sys/time.h \ + /usr/include/x86_64-linux-gnu/bits/timex.h \ + /usr/include/x86_64-linux-gnu/sys/stat.h \ + /usr/include/x86_64-linux-gnu/sys/file.h \ + /usr/include/x86_64-linux-gnu/sys/wait.h \ + /usr/include/x86_64-linux-gnu/sys/ioctl.h \ + /usr/include/x86_64-linux-gnu/bits/ioctls.h \ + /usr/include/x86_64-linux-gnu/asm/ioctls.h \ + /usr/include/asm-generic/ioctls.h /usr/include/linux/ioctl.h \ + /usr/include/x86_64-linux-gnu/asm/ioctl.h \ + /usr/include/asm-generic/ioctl.h \ + /usr/include/x86_64-linux-gnu/bits/ioctl-types.h \ + /usr/include/x86_64-linux-gnu/sys/ttydefaults.h \ + /usr/include/x86_64-linux-gnu/sys/param.h \ + /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/limits.h \ + /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/syslimits.h \ + /usr/include/limits.h /usr/include/x86_64-linux-gnu/bits/posix1_lim.h \ + /usr/include/x86_64-linux-gnu/bits/local_lim.h \ + /usr/include/linux/limits.h \ + /usr/include/x86_64-linux-gnu/bits/posix2_lim.h \ + /usr/include/x86_64-linux-gnu/bits/xopen_lim.h \ + /usr/include/x86_64-linux-gnu/bits/param.h /usr/include/linux/param.h \ + /usr/include/x86_64-linux-gnu/asm/param.h \ + /usr/include/asm-generic/param.h \ + /usr/include/x86_64-linux-gnu/sys/resource.h \ + /usr/include/x86_64-linux-gnu/bits/resource.h \ + /usr/include/x86_64-linux-gnu/sys/uio.h \ + /usr/include/x86_64-linux-gnu/sys/un.h \ + /usr/include/x86_64-linux-gnu/bits/sockaddr.h /usr/include/dirent.h \ + /usr/include/x86_64-linux-gnu/bits/dirent.h /usr/include/netdb.h \ + /usr/include/netinet/in.h /usr/include/x86_64-linux-gnu/sys/socket.h \ + /usr/include/x86_64-linux-gnu/bits/socket.h \ + /usr/include/x86_64-linux-gnu/bits/socket_type.h \ + /usr/include/x86_64-linux-gnu/asm/socket.h \ + /usr/include/asm-generic/socket.h \ + /usr/include/x86_64-linux-gnu/asm/sockios.h \ + /usr/include/asm-generic/sockios.h \ + /usr/include/x86_64-linux-gnu/bits/in.h /usr/include/rpc/netdb.h \ + /usr/include/x86_64-linux-gnu/bits/netdb.h /usr/include/net/if.h \ + /usr/include/netinet/in_systm.h /usr/include/arpa/inet.h \ + /usr/include/netinet/ip.h /usr/include/netinet/tcp.h \ + /usr/include/netinet/ip6.h /usr/include/net/ethernet.h \ + /usr/include/linux/if_ether.h /usr/include/linux/types.h \ + /usr/include/x86_64-linux-gnu/asm/types.h \ + /usr/include/asm-generic/types.h /usr/include/asm-generic/int-ll64.h \ + /usr/include/x86_64-linux-gnu/asm/bitsperlong.h \ + /usr/include/asm-generic/bitsperlong.h /usr/include/linux/posix_types.h \ + /usr/include/linux/stddef.h \ + /usr/include/x86_64-linux-gnu/asm/posix_types.h \ + /usr/include/x86_64-linux-gnu/asm/posix_types_64.h \ + /usr/include/asm-generic/posix_types.h /usr/include/net/if_arp.h \ + /usr/include/netinet/ip_icmp.h /usr/include/netinet/icmp6.h \ + /usr/include/netinet/if_ether.h openssl/../dropin.h \ + openssl/../fake-getaddrinfo.h openssl/../fake-gai-errnos.h \ + openssl/../fake-getnameinfo.h /usr/include/openssl/pem.h \ + /usr/include/openssl/e_os2.h \ + /usr/include/x86_64-linux-gnu/openssl/opensslconf.h \ + /usr/include/openssl/bio.h /usr/include/openssl/crypto.h \ + /usr/include/openssl/stack.h /usr/include/openssl/safestack.h \ + /usr/include/openssl/opensslv.h /usr/include/openssl/ossl_typ.h \ + /usr/include/openssl/symhacks.h /usr/include/openssl/evp.h \ + /usr/include/openssl/objects.h /usr/include/openssl/obj_mac.h \ + /usr/include/openssl/asn1.h /usr/include/openssl/bn.h \ + /usr/include/openssl/x509.h /usr/include/openssl/buffer.h \ + /usr/include/openssl/ec.h /usr/include/openssl/ecdsa.h \ + /usr/include/openssl/ecdh.h /usr/include/openssl/rsa.h \ + /usr/include/openssl/dsa.h /usr/include/openssl/dh.h \ + /usr/include/openssl/sha.h /usr/include/openssl/x509_vfy.h \ + /usr/include/openssl/lhash.h /usr/include/openssl/pkcs7.h \ + /usr/include/openssl/pem2.h /usr/include/openssl/err.h \ + openssl/../logger.h openssl/../ecdsa.h openssl/../utils.h \ + openssl/../xalloc.h + +/usr/include/stdc-predef.h: + +/usr/include/x86_64-linux-gnu/bits/predefs.h: + +openssl/../system.h: + +openssl/../../config.h: + +openssl/../have.h: + +/usr/include/stdio.h: + +/usr/include/features.h: + +/usr/include/x86_64-linux-gnu/sys/cdefs.h: + +/usr/include/x86_64-linux-gnu/bits/wordsize.h: + +/usr/include/x86_64-linux-gnu/gnu/stubs.h: + +/usr/include/x86_64-linux-gnu/gnu/stubs-64.h: + +/usr/lib/gcc/x86_64-linux-gnu/4.8/include/stddef.h: + +/usr/include/x86_64-linux-gnu/bits/types.h: + +/usr/include/x86_64-linux-gnu/bits/typesizes.h: + +/usr/include/libio.h: + +/usr/include/_G_config.h: + +/usr/include/wchar.h: + +/usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdarg.h: + +/usr/include/x86_64-linux-gnu/bits/stdio_lim.h: + +/usr/include/x86_64-linux-gnu/bits/sys_errlist.h: + +/usr/include/x86_64-linux-gnu/bits/stdio.h: + +/usr/include/stdlib.h: + +/usr/include/x86_64-linux-gnu/bits/waitflags.h: + +/usr/include/x86_64-linux-gnu/bits/waitstatus.h: + +/usr/include/endian.h: + +/usr/include/x86_64-linux-gnu/bits/endian.h: + +/usr/include/x86_64-linux-gnu/bits/byteswap.h: + +/usr/include/x86_64-linux-gnu/bits/byteswap-16.h: + +/usr/include/xlocale.h: + +/usr/include/x86_64-linux-gnu/sys/types.h: + +/usr/include/time.h: + +/usr/include/x86_64-linux-gnu/sys/select.h: + +/usr/include/x86_64-linux-gnu/bits/select.h: + +/usr/include/x86_64-linux-gnu/bits/sigset.h: + +/usr/include/x86_64-linux-gnu/bits/time.h: + +/usr/include/x86_64-linux-gnu/sys/sysmacros.h: + +/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h: + +/usr/include/alloca.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib-float.h: + +/usr/include/string.h: + +/usr/include/x86_64-linux-gnu/bits/string.h: + +/usr/include/x86_64-linux-gnu/bits/string2.h: + +/usr/include/ctype.h: + +/usr/include/signal.h: + +/usr/include/x86_64-linux-gnu/bits/signum.h: + +/usr/include/x86_64-linux-gnu/bits/siginfo.h: + +/usr/include/x86_64-linux-gnu/bits/sigaction.h: + +/usr/include/x86_64-linux-gnu/bits/sigcontext.h: + +/usr/include/x86_64-linux-gnu/bits/sigstack.h: + +/usr/include/x86_64-linux-gnu/sys/ucontext.h: + +/usr/include/x86_64-linux-gnu/bits/sigthread.h: + +/usr/include/errno.h: + +/usr/include/x86_64-linux-gnu/bits/errno.h: + +/usr/include/linux/errno.h: + +/usr/include/x86_64-linux-gnu/asm/errno.h: + +/usr/include/asm-generic/errno.h: + +/usr/include/asm-generic/errno-base.h: + +/usr/include/fcntl.h: + +/usr/include/x86_64-linux-gnu/bits/fcntl.h: + +/usr/include/x86_64-linux-gnu/bits/fcntl-linux.h: + +/usr/include/x86_64-linux-gnu/bits/uio.h: + +/usr/include/x86_64-linux-gnu/bits/stat.h: + +/usr/include/unistd.h: + +/usr/include/x86_64-linux-gnu/bits/posix_opt.h: + +/usr/include/x86_64-linux-gnu/bits/environments.h: + +/usr/include/x86_64-linux-gnu/bits/confname.h: + +/usr/include/getopt.h: + +/usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdbool.h: + +/usr/include/inttypes.h: + +/usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdint.h: + +/usr/include/stdint.h: + +/usr/include/x86_64-linux-gnu/bits/wchar.h: + +/usr/include/syslog.h: + +/usr/include/x86_64-linux-gnu/sys/syslog.h: + +/usr/include/x86_64-linux-gnu/bits/syslog-path.h: + +/usr/include/x86_64-linux-gnu/sys/time.h: + +/usr/include/x86_64-linux-gnu/bits/timex.h: + +/usr/include/x86_64-linux-gnu/sys/stat.h: + +/usr/include/x86_64-linux-gnu/sys/file.h: + +/usr/include/x86_64-linux-gnu/sys/wait.h: + +/usr/include/x86_64-linux-gnu/sys/ioctl.h: + +/usr/include/x86_64-linux-gnu/bits/ioctls.h: + +/usr/include/x86_64-linux-gnu/asm/ioctls.h: + +/usr/include/asm-generic/ioctls.h: + +/usr/include/linux/ioctl.h: + +/usr/include/x86_64-linux-gnu/asm/ioctl.h: + +/usr/include/asm-generic/ioctl.h: + +/usr/include/x86_64-linux-gnu/bits/ioctl-types.h: + +/usr/include/x86_64-linux-gnu/sys/ttydefaults.h: + +/usr/include/x86_64-linux-gnu/sys/param.h: + +/usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/limits.h: + +/usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/syslimits.h: + +/usr/include/limits.h: + +/usr/include/x86_64-linux-gnu/bits/posix1_lim.h: + +/usr/include/x86_64-linux-gnu/bits/local_lim.h: + +/usr/include/linux/limits.h: + +/usr/include/x86_64-linux-gnu/bits/posix2_lim.h: + +/usr/include/x86_64-linux-gnu/bits/xopen_lim.h: + +/usr/include/x86_64-linux-gnu/bits/param.h: + +/usr/include/linux/param.h: + +/usr/include/x86_64-linux-gnu/asm/param.h: + +/usr/include/asm-generic/param.h: + +/usr/include/x86_64-linux-gnu/sys/resource.h: + +/usr/include/x86_64-linux-gnu/bits/resource.h: + +/usr/include/x86_64-linux-gnu/sys/uio.h: + +/usr/include/x86_64-linux-gnu/sys/un.h: + +/usr/include/x86_64-linux-gnu/bits/sockaddr.h: + +/usr/include/dirent.h: + +/usr/include/x86_64-linux-gnu/bits/dirent.h: + +/usr/include/netdb.h: + +/usr/include/netinet/in.h: + +/usr/include/x86_64-linux-gnu/sys/socket.h: + +/usr/include/x86_64-linux-gnu/bits/socket.h: + +/usr/include/x86_64-linux-gnu/bits/socket_type.h: + +/usr/include/x86_64-linux-gnu/asm/socket.h: + +/usr/include/asm-generic/socket.h: + +/usr/include/x86_64-linux-gnu/asm/sockios.h: + +/usr/include/asm-generic/sockios.h: + +/usr/include/x86_64-linux-gnu/bits/in.h: + +/usr/include/rpc/netdb.h: + +/usr/include/x86_64-linux-gnu/bits/netdb.h: + +/usr/include/net/if.h: + +/usr/include/netinet/in_systm.h: + +/usr/include/arpa/inet.h: + +/usr/include/netinet/ip.h: + +/usr/include/netinet/tcp.h: + +/usr/include/netinet/ip6.h: + +/usr/include/net/ethernet.h: + +/usr/include/linux/if_ether.h: + +/usr/include/linux/types.h: + +/usr/include/x86_64-linux-gnu/asm/types.h: + +/usr/include/asm-generic/types.h: + +/usr/include/asm-generic/int-ll64.h: + +/usr/include/x86_64-linux-gnu/asm/bitsperlong.h: + +/usr/include/asm-generic/bitsperlong.h: + +/usr/include/linux/posix_types.h: + +/usr/include/linux/stddef.h: + +/usr/include/x86_64-linux-gnu/asm/posix_types.h: + +/usr/include/x86_64-linux-gnu/asm/posix_types_64.h: + +/usr/include/asm-generic/posix_types.h: + +/usr/include/net/if_arp.h: + +/usr/include/netinet/ip_icmp.h: + +/usr/include/netinet/icmp6.h: + +/usr/include/netinet/if_ether.h: + +openssl/../dropin.h: + +openssl/../fake-getaddrinfo.h: + +openssl/../fake-gai-errnos.h: + +openssl/../fake-getnameinfo.h: + +/usr/include/openssl/pem.h: + +/usr/include/openssl/e_os2.h: + +/usr/include/x86_64-linux-gnu/openssl/opensslconf.h: + +/usr/include/openssl/bio.h: + +/usr/include/openssl/crypto.h: + +/usr/include/openssl/stack.h: + +/usr/include/openssl/safestack.h: + +/usr/include/openssl/opensslv.h: + +/usr/include/openssl/ossl_typ.h: + +/usr/include/openssl/symhacks.h: + +/usr/include/openssl/evp.h: + +/usr/include/openssl/objects.h: + +/usr/include/openssl/obj_mac.h: + +/usr/include/openssl/asn1.h: + +/usr/include/openssl/bn.h: + +/usr/include/openssl/x509.h: + +/usr/include/openssl/buffer.h: + +/usr/include/openssl/ec.h: + +/usr/include/openssl/ecdsa.h: + +/usr/include/openssl/ecdh.h: + +/usr/include/openssl/rsa.h: + +/usr/include/openssl/dsa.h: + +/usr/include/openssl/dh.h: + +/usr/include/openssl/sha.h: + +/usr/include/openssl/x509_vfy.h: + +/usr/include/openssl/lhash.h: + +/usr/include/openssl/pkcs7.h: + +/usr/include/openssl/pem2.h: + +/usr/include/openssl/err.h: + +openssl/../logger.h: + +openssl/../ecdsa.h: + +openssl/../utils.h: + +openssl/../xalloc.h: diff --git a/src/openssl/.deps/ecdsagen.Po b/src/openssl/.deps/ecdsagen.Po new file mode 100644 index 0000000..51e34f5 --- /dev/null +++ b/src/openssl/.deps/ecdsagen.Po @@ -0,0 +1,487 @@ +openssl/ecdsagen.o: openssl/ecdsagen.c /usr/include/stdc-predef.h \ + /usr/include/x86_64-linux-gnu/bits/predefs.h openssl/../system.h \ + openssl/../../config.h openssl/../have.h /usr/include/stdio.h \ + /usr/include/features.h /usr/include/x86_64-linux-gnu/sys/cdefs.h \ + /usr/include/x86_64-linux-gnu/bits/wordsize.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ + /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stddef.h \ + /usr/include/x86_64-linux-gnu/bits/types.h \ + /usr/include/x86_64-linux-gnu/bits/typesizes.h /usr/include/libio.h \ + /usr/include/_G_config.h /usr/include/wchar.h \ + /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdarg.h \ + /usr/include/x86_64-linux-gnu/bits/stdio_lim.h \ + /usr/include/x86_64-linux-gnu/bits/sys_errlist.h \ + /usr/include/x86_64-linux-gnu/bits/stdio.h /usr/include/stdlib.h \ + /usr/include/x86_64-linux-gnu/bits/waitflags.h \ + /usr/include/x86_64-linux-gnu/bits/waitstatus.h /usr/include/endian.h \ + /usr/include/x86_64-linux-gnu/bits/endian.h \ + /usr/include/x86_64-linux-gnu/bits/byteswap.h \ + /usr/include/x86_64-linux-gnu/bits/byteswap-16.h /usr/include/xlocale.h \ + /usr/include/x86_64-linux-gnu/sys/types.h /usr/include/time.h \ + /usr/include/x86_64-linux-gnu/sys/select.h \ + /usr/include/x86_64-linux-gnu/bits/select.h \ + /usr/include/x86_64-linux-gnu/bits/sigset.h \ + /usr/include/x86_64-linux-gnu/bits/time.h \ + /usr/include/x86_64-linux-gnu/sys/sysmacros.h \ + /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h /usr/include/alloca.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib-float.h /usr/include/string.h \ + /usr/include/x86_64-linux-gnu/bits/string.h \ + /usr/include/x86_64-linux-gnu/bits/string2.h /usr/include/ctype.h \ + /usr/include/signal.h /usr/include/x86_64-linux-gnu/bits/signum.h \ + /usr/include/x86_64-linux-gnu/bits/siginfo.h \ + /usr/include/x86_64-linux-gnu/bits/sigaction.h \ + /usr/include/x86_64-linux-gnu/bits/sigcontext.h \ + /usr/include/x86_64-linux-gnu/bits/sigstack.h \ + /usr/include/x86_64-linux-gnu/sys/ucontext.h \ + /usr/include/x86_64-linux-gnu/bits/sigthread.h /usr/include/errno.h \ + /usr/include/x86_64-linux-gnu/bits/errno.h /usr/include/linux/errno.h \ + /usr/include/x86_64-linux-gnu/asm/errno.h \ + /usr/include/asm-generic/errno.h /usr/include/asm-generic/errno-base.h \ + /usr/include/fcntl.h /usr/include/x86_64-linux-gnu/bits/fcntl.h \ + /usr/include/x86_64-linux-gnu/bits/fcntl-linux.h \ + /usr/include/x86_64-linux-gnu/bits/uio.h \ + /usr/include/x86_64-linux-gnu/bits/stat.h /usr/include/unistd.h \ + /usr/include/x86_64-linux-gnu/bits/posix_opt.h \ + /usr/include/x86_64-linux-gnu/bits/environments.h \ + /usr/include/x86_64-linux-gnu/bits/confname.h /usr/include/getopt.h \ + /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdbool.h \ + /usr/include/inttypes.h \ + /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdint.h /usr/include/stdint.h \ + /usr/include/x86_64-linux-gnu/bits/wchar.h /usr/include/syslog.h \ + /usr/include/x86_64-linux-gnu/sys/syslog.h \ + /usr/include/x86_64-linux-gnu/bits/syslog-path.h \ + /usr/include/x86_64-linux-gnu/sys/time.h \ + /usr/include/x86_64-linux-gnu/bits/timex.h \ + /usr/include/x86_64-linux-gnu/sys/stat.h \ + /usr/include/x86_64-linux-gnu/sys/file.h \ + /usr/include/x86_64-linux-gnu/sys/wait.h \ + /usr/include/x86_64-linux-gnu/sys/ioctl.h \ + /usr/include/x86_64-linux-gnu/bits/ioctls.h \ + /usr/include/x86_64-linux-gnu/asm/ioctls.h \ + /usr/include/asm-generic/ioctls.h /usr/include/linux/ioctl.h \ + /usr/include/x86_64-linux-gnu/asm/ioctl.h \ + /usr/include/asm-generic/ioctl.h \ + /usr/include/x86_64-linux-gnu/bits/ioctl-types.h \ + /usr/include/x86_64-linux-gnu/sys/ttydefaults.h \ + /usr/include/x86_64-linux-gnu/sys/param.h \ + /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/limits.h \ + /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/syslimits.h \ + /usr/include/limits.h /usr/include/x86_64-linux-gnu/bits/posix1_lim.h \ + /usr/include/x86_64-linux-gnu/bits/local_lim.h \ + /usr/include/linux/limits.h \ + /usr/include/x86_64-linux-gnu/bits/posix2_lim.h \ + /usr/include/x86_64-linux-gnu/bits/xopen_lim.h \ + /usr/include/x86_64-linux-gnu/bits/param.h /usr/include/linux/param.h \ + /usr/include/x86_64-linux-gnu/asm/param.h \ + /usr/include/asm-generic/param.h \ + /usr/include/x86_64-linux-gnu/sys/resource.h \ + /usr/include/x86_64-linux-gnu/bits/resource.h \ + /usr/include/x86_64-linux-gnu/sys/uio.h \ + /usr/include/x86_64-linux-gnu/sys/un.h \ + /usr/include/x86_64-linux-gnu/bits/sockaddr.h /usr/include/dirent.h \ + /usr/include/x86_64-linux-gnu/bits/dirent.h /usr/include/netdb.h \ + /usr/include/netinet/in.h /usr/include/x86_64-linux-gnu/sys/socket.h \ + /usr/include/x86_64-linux-gnu/bits/socket.h \ + /usr/include/x86_64-linux-gnu/bits/socket_type.h \ + /usr/include/x86_64-linux-gnu/asm/socket.h \ + /usr/include/asm-generic/socket.h \ + /usr/include/x86_64-linux-gnu/asm/sockios.h \ + /usr/include/asm-generic/sockios.h \ + /usr/include/x86_64-linux-gnu/bits/in.h /usr/include/rpc/netdb.h \ + /usr/include/x86_64-linux-gnu/bits/netdb.h /usr/include/net/if.h \ + /usr/include/netinet/in_systm.h /usr/include/arpa/inet.h \ + /usr/include/netinet/ip.h /usr/include/netinet/tcp.h \ + /usr/include/netinet/ip6.h /usr/include/net/ethernet.h \ + /usr/include/linux/if_ether.h /usr/include/linux/types.h \ + /usr/include/x86_64-linux-gnu/asm/types.h \ + /usr/include/asm-generic/types.h /usr/include/asm-generic/int-ll64.h \ + /usr/include/x86_64-linux-gnu/asm/bitsperlong.h \ + /usr/include/asm-generic/bitsperlong.h /usr/include/linux/posix_types.h \ + /usr/include/linux/stddef.h \ + /usr/include/x86_64-linux-gnu/asm/posix_types.h \ + /usr/include/x86_64-linux-gnu/asm/posix_types_64.h \ + /usr/include/asm-generic/posix_types.h /usr/include/net/if_arp.h \ + /usr/include/netinet/ip_icmp.h /usr/include/netinet/icmp6.h \ + /usr/include/netinet/if_ether.h openssl/../dropin.h \ + openssl/../fake-getaddrinfo.h openssl/../fake-gai-errnos.h \ + openssl/../fake-getnameinfo.h /usr/include/openssl/pem.h \ + /usr/include/openssl/e_os2.h \ + /usr/include/x86_64-linux-gnu/openssl/opensslconf.h \ + /usr/include/openssl/bio.h /usr/include/openssl/crypto.h \ + /usr/include/openssl/stack.h /usr/include/openssl/safestack.h \ + /usr/include/openssl/opensslv.h /usr/include/openssl/ossl_typ.h \ + /usr/include/openssl/symhacks.h /usr/include/openssl/evp.h \ + /usr/include/openssl/objects.h /usr/include/openssl/obj_mac.h \ + /usr/include/openssl/asn1.h /usr/include/openssl/bn.h \ + /usr/include/openssl/x509.h /usr/include/openssl/buffer.h \ + /usr/include/openssl/ec.h /usr/include/openssl/ecdsa.h \ + /usr/include/openssl/ecdh.h /usr/include/openssl/rsa.h \ + /usr/include/openssl/dsa.h /usr/include/openssl/dh.h \ + /usr/include/openssl/sha.h /usr/include/openssl/x509_vfy.h \ + /usr/include/openssl/lhash.h /usr/include/openssl/pkcs7.h \ + /usr/include/openssl/pem2.h /usr/include/openssl/err.h \ + openssl/../ecdsagen.h openssl/../ecdsa.h openssl/../utils.h \ + openssl/../xalloc.h + +/usr/include/stdc-predef.h: + +/usr/include/x86_64-linux-gnu/bits/predefs.h: + +openssl/../system.h: + +openssl/../../config.h: + +openssl/../have.h: + +/usr/include/stdio.h: + +/usr/include/features.h: + +/usr/include/x86_64-linux-gnu/sys/cdefs.h: + +/usr/include/x86_64-linux-gnu/bits/wordsize.h: + +/usr/include/x86_64-linux-gnu/gnu/stubs.h: + +/usr/include/x86_64-linux-gnu/gnu/stubs-64.h: + +/usr/lib/gcc/x86_64-linux-gnu/4.8/include/stddef.h: + +/usr/include/x86_64-linux-gnu/bits/types.h: + +/usr/include/x86_64-linux-gnu/bits/typesizes.h: + +/usr/include/libio.h: + +/usr/include/_G_config.h: + +/usr/include/wchar.h: + +/usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdarg.h: + +/usr/include/x86_64-linux-gnu/bits/stdio_lim.h: + +/usr/include/x86_64-linux-gnu/bits/sys_errlist.h: + +/usr/include/x86_64-linux-gnu/bits/stdio.h: + +/usr/include/stdlib.h: + +/usr/include/x86_64-linux-gnu/bits/waitflags.h: + +/usr/include/x86_64-linux-gnu/bits/waitstatus.h: + +/usr/include/endian.h: + +/usr/include/x86_64-linux-gnu/bits/endian.h: + +/usr/include/x86_64-linux-gnu/bits/byteswap.h: + +/usr/include/x86_64-linux-gnu/bits/byteswap-16.h: + +/usr/include/xlocale.h: + +/usr/include/x86_64-linux-gnu/sys/types.h: + +/usr/include/time.h: + +/usr/include/x86_64-linux-gnu/sys/select.h: + +/usr/include/x86_64-linux-gnu/bits/select.h: + +/usr/include/x86_64-linux-gnu/bits/sigset.h: + +/usr/include/x86_64-linux-gnu/bits/time.h: + +/usr/include/x86_64-linux-gnu/sys/sysmacros.h: + +/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h: + +/usr/include/alloca.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib-float.h: + +/usr/include/string.h: + +/usr/include/x86_64-linux-gnu/bits/string.h: + +/usr/include/x86_64-linux-gnu/bits/string2.h: + +/usr/include/ctype.h: + +/usr/include/signal.h: + +/usr/include/x86_64-linux-gnu/bits/signum.h: + +/usr/include/x86_64-linux-gnu/bits/siginfo.h: + +/usr/include/x86_64-linux-gnu/bits/sigaction.h: + +/usr/include/x86_64-linux-gnu/bits/sigcontext.h: + +/usr/include/x86_64-linux-gnu/bits/sigstack.h: + +/usr/include/x86_64-linux-gnu/sys/ucontext.h: + +/usr/include/x86_64-linux-gnu/bits/sigthread.h: + +/usr/include/errno.h: + +/usr/include/x86_64-linux-gnu/bits/errno.h: + +/usr/include/linux/errno.h: + +/usr/include/x86_64-linux-gnu/asm/errno.h: + +/usr/include/asm-generic/errno.h: + +/usr/include/asm-generic/errno-base.h: + +/usr/include/fcntl.h: + +/usr/include/x86_64-linux-gnu/bits/fcntl.h: + +/usr/include/x86_64-linux-gnu/bits/fcntl-linux.h: + +/usr/include/x86_64-linux-gnu/bits/uio.h: + +/usr/include/x86_64-linux-gnu/bits/stat.h: + +/usr/include/unistd.h: + +/usr/include/x86_64-linux-gnu/bits/posix_opt.h: + +/usr/include/x86_64-linux-gnu/bits/environments.h: + +/usr/include/x86_64-linux-gnu/bits/confname.h: + +/usr/include/getopt.h: + +/usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdbool.h: + +/usr/include/inttypes.h: + +/usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdint.h: + +/usr/include/stdint.h: + +/usr/include/x86_64-linux-gnu/bits/wchar.h: + +/usr/include/syslog.h: + +/usr/include/x86_64-linux-gnu/sys/syslog.h: + +/usr/include/x86_64-linux-gnu/bits/syslog-path.h: + +/usr/include/x86_64-linux-gnu/sys/time.h: + +/usr/include/x86_64-linux-gnu/bits/timex.h: + +/usr/include/x86_64-linux-gnu/sys/stat.h: + +/usr/include/x86_64-linux-gnu/sys/file.h: + +/usr/include/x86_64-linux-gnu/sys/wait.h: + +/usr/include/x86_64-linux-gnu/sys/ioctl.h: + +/usr/include/x86_64-linux-gnu/bits/ioctls.h: + +/usr/include/x86_64-linux-gnu/asm/ioctls.h: + +/usr/include/asm-generic/ioctls.h: + +/usr/include/linux/ioctl.h: + +/usr/include/x86_64-linux-gnu/asm/ioctl.h: + +/usr/include/asm-generic/ioctl.h: + +/usr/include/x86_64-linux-gnu/bits/ioctl-types.h: + +/usr/include/x86_64-linux-gnu/sys/ttydefaults.h: + +/usr/include/x86_64-linux-gnu/sys/param.h: + +/usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/limits.h: + +/usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/syslimits.h: + +/usr/include/limits.h: + +/usr/include/x86_64-linux-gnu/bits/posix1_lim.h: + +/usr/include/x86_64-linux-gnu/bits/local_lim.h: + +/usr/include/linux/limits.h: + +/usr/include/x86_64-linux-gnu/bits/posix2_lim.h: + +/usr/include/x86_64-linux-gnu/bits/xopen_lim.h: + +/usr/include/x86_64-linux-gnu/bits/param.h: + +/usr/include/linux/param.h: + +/usr/include/x86_64-linux-gnu/asm/param.h: + +/usr/include/asm-generic/param.h: + +/usr/include/x86_64-linux-gnu/sys/resource.h: + +/usr/include/x86_64-linux-gnu/bits/resource.h: + +/usr/include/x86_64-linux-gnu/sys/uio.h: + +/usr/include/x86_64-linux-gnu/sys/un.h: + +/usr/include/x86_64-linux-gnu/bits/sockaddr.h: + +/usr/include/dirent.h: + +/usr/include/x86_64-linux-gnu/bits/dirent.h: + +/usr/include/netdb.h: + +/usr/include/netinet/in.h: + +/usr/include/x86_64-linux-gnu/sys/socket.h: + +/usr/include/x86_64-linux-gnu/bits/socket.h: + +/usr/include/x86_64-linux-gnu/bits/socket_type.h: + +/usr/include/x86_64-linux-gnu/asm/socket.h: + +/usr/include/asm-generic/socket.h: + +/usr/include/x86_64-linux-gnu/asm/sockios.h: + +/usr/include/asm-generic/sockios.h: + +/usr/include/x86_64-linux-gnu/bits/in.h: + +/usr/include/rpc/netdb.h: + +/usr/include/x86_64-linux-gnu/bits/netdb.h: + +/usr/include/net/if.h: + +/usr/include/netinet/in_systm.h: + +/usr/include/arpa/inet.h: + +/usr/include/netinet/ip.h: + +/usr/include/netinet/tcp.h: + +/usr/include/netinet/ip6.h: + +/usr/include/net/ethernet.h: + +/usr/include/linux/if_ether.h: + +/usr/include/linux/types.h: + +/usr/include/x86_64-linux-gnu/asm/types.h: + +/usr/include/asm-generic/types.h: + +/usr/include/asm-generic/int-ll64.h: + +/usr/include/x86_64-linux-gnu/asm/bitsperlong.h: + +/usr/include/asm-generic/bitsperlong.h: + +/usr/include/linux/posix_types.h: + +/usr/include/linux/stddef.h: + +/usr/include/x86_64-linux-gnu/asm/posix_types.h: + +/usr/include/x86_64-linux-gnu/asm/posix_types_64.h: + +/usr/include/asm-generic/posix_types.h: + +/usr/include/net/if_arp.h: + +/usr/include/netinet/ip_icmp.h: + +/usr/include/netinet/icmp6.h: + +/usr/include/netinet/if_ether.h: + +openssl/../dropin.h: + +openssl/../fake-getaddrinfo.h: + +openssl/../fake-gai-errnos.h: + +openssl/../fake-getnameinfo.h: + +/usr/include/openssl/pem.h: + +/usr/include/openssl/e_os2.h: + +/usr/include/x86_64-linux-gnu/openssl/opensslconf.h: + +/usr/include/openssl/bio.h: + +/usr/include/openssl/crypto.h: + +/usr/include/openssl/stack.h: + +/usr/include/openssl/safestack.h: + +/usr/include/openssl/opensslv.h: + +/usr/include/openssl/ossl_typ.h: + +/usr/include/openssl/symhacks.h: + +/usr/include/openssl/evp.h: + +/usr/include/openssl/objects.h: + +/usr/include/openssl/obj_mac.h: + +/usr/include/openssl/asn1.h: + +/usr/include/openssl/bn.h: + +/usr/include/openssl/x509.h: + +/usr/include/openssl/buffer.h: + +/usr/include/openssl/ec.h: + +/usr/include/openssl/ecdsa.h: + +/usr/include/openssl/ecdh.h: + +/usr/include/openssl/rsa.h: + +/usr/include/openssl/dsa.h: + +/usr/include/openssl/dh.h: + +/usr/include/openssl/sha.h: + +/usr/include/openssl/x509_vfy.h: + +/usr/include/openssl/lhash.h: + +/usr/include/openssl/pkcs7.h: + +/usr/include/openssl/pem2.h: + +/usr/include/openssl/err.h: + +openssl/../ecdsagen.h: + +openssl/../ecdsa.h: + +openssl/../utils.h: + +openssl/../xalloc.h: diff --git a/src/openssl/.deps/prf.Po b/src/openssl/.deps/prf.Po new file mode 100644 index 0000000..aa2ae6d --- /dev/null +++ b/src/openssl/.deps/prf.Po @@ -0,0 +1,446 @@ +openssl/prf.o: openssl/prf.c /usr/include/stdc-predef.h \ + /usr/include/x86_64-linux-gnu/bits/predefs.h openssl/../system.h \ + openssl/../../config.h openssl/../have.h /usr/include/stdio.h \ + /usr/include/features.h /usr/include/x86_64-linux-gnu/sys/cdefs.h \ + /usr/include/x86_64-linux-gnu/bits/wordsize.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ + /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stddef.h \ + /usr/include/x86_64-linux-gnu/bits/types.h \ + /usr/include/x86_64-linux-gnu/bits/typesizes.h /usr/include/libio.h \ + /usr/include/_G_config.h /usr/include/wchar.h \ + /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdarg.h \ + /usr/include/x86_64-linux-gnu/bits/stdio_lim.h \ + /usr/include/x86_64-linux-gnu/bits/sys_errlist.h \ + /usr/include/x86_64-linux-gnu/bits/stdio.h /usr/include/stdlib.h \ + /usr/include/x86_64-linux-gnu/bits/waitflags.h \ + /usr/include/x86_64-linux-gnu/bits/waitstatus.h /usr/include/endian.h \ + /usr/include/x86_64-linux-gnu/bits/endian.h \ + /usr/include/x86_64-linux-gnu/bits/byteswap.h \ + /usr/include/x86_64-linux-gnu/bits/byteswap-16.h /usr/include/xlocale.h \ + /usr/include/x86_64-linux-gnu/sys/types.h /usr/include/time.h \ + /usr/include/x86_64-linux-gnu/sys/select.h \ + /usr/include/x86_64-linux-gnu/bits/select.h \ + /usr/include/x86_64-linux-gnu/bits/sigset.h \ + /usr/include/x86_64-linux-gnu/bits/time.h \ + /usr/include/x86_64-linux-gnu/sys/sysmacros.h \ + /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h /usr/include/alloca.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib-float.h /usr/include/string.h \ + /usr/include/x86_64-linux-gnu/bits/string.h \ + /usr/include/x86_64-linux-gnu/bits/string2.h /usr/include/ctype.h \ + /usr/include/signal.h /usr/include/x86_64-linux-gnu/bits/signum.h \ + /usr/include/x86_64-linux-gnu/bits/siginfo.h \ + /usr/include/x86_64-linux-gnu/bits/sigaction.h \ + /usr/include/x86_64-linux-gnu/bits/sigcontext.h \ + /usr/include/x86_64-linux-gnu/bits/sigstack.h \ + /usr/include/x86_64-linux-gnu/sys/ucontext.h \ + /usr/include/x86_64-linux-gnu/bits/sigthread.h /usr/include/errno.h \ + /usr/include/x86_64-linux-gnu/bits/errno.h /usr/include/linux/errno.h \ + /usr/include/x86_64-linux-gnu/asm/errno.h \ + /usr/include/asm-generic/errno.h /usr/include/asm-generic/errno-base.h \ + /usr/include/fcntl.h /usr/include/x86_64-linux-gnu/bits/fcntl.h \ + /usr/include/x86_64-linux-gnu/bits/fcntl-linux.h \ + /usr/include/x86_64-linux-gnu/bits/uio.h \ + /usr/include/x86_64-linux-gnu/bits/stat.h /usr/include/unistd.h \ + /usr/include/x86_64-linux-gnu/bits/posix_opt.h \ + /usr/include/x86_64-linux-gnu/bits/environments.h \ + /usr/include/x86_64-linux-gnu/bits/confname.h /usr/include/getopt.h \ + /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdbool.h \ + /usr/include/inttypes.h \ + /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdint.h /usr/include/stdint.h \ + /usr/include/x86_64-linux-gnu/bits/wchar.h /usr/include/syslog.h \ + /usr/include/x86_64-linux-gnu/sys/syslog.h \ + /usr/include/x86_64-linux-gnu/bits/syslog-path.h \ + /usr/include/x86_64-linux-gnu/sys/time.h \ + /usr/include/x86_64-linux-gnu/bits/timex.h \ + /usr/include/x86_64-linux-gnu/sys/stat.h \ + /usr/include/x86_64-linux-gnu/sys/file.h \ + /usr/include/x86_64-linux-gnu/sys/wait.h \ + /usr/include/x86_64-linux-gnu/sys/ioctl.h \ + /usr/include/x86_64-linux-gnu/bits/ioctls.h \ + /usr/include/x86_64-linux-gnu/asm/ioctls.h \ + /usr/include/asm-generic/ioctls.h /usr/include/linux/ioctl.h \ + /usr/include/x86_64-linux-gnu/asm/ioctl.h \ + /usr/include/asm-generic/ioctl.h \ + /usr/include/x86_64-linux-gnu/bits/ioctl-types.h \ + /usr/include/x86_64-linux-gnu/sys/ttydefaults.h \ + /usr/include/x86_64-linux-gnu/sys/param.h \ + /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/limits.h \ + /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/syslimits.h \ + /usr/include/limits.h /usr/include/x86_64-linux-gnu/bits/posix1_lim.h \ + /usr/include/x86_64-linux-gnu/bits/local_lim.h \ + /usr/include/linux/limits.h \ + /usr/include/x86_64-linux-gnu/bits/posix2_lim.h \ + /usr/include/x86_64-linux-gnu/bits/xopen_lim.h \ + /usr/include/x86_64-linux-gnu/bits/param.h /usr/include/linux/param.h \ + /usr/include/x86_64-linux-gnu/asm/param.h \ + /usr/include/asm-generic/param.h \ + /usr/include/x86_64-linux-gnu/sys/resource.h \ + /usr/include/x86_64-linux-gnu/bits/resource.h \ + /usr/include/x86_64-linux-gnu/sys/uio.h \ + /usr/include/x86_64-linux-gnu/sys/un.h \ + /usr/include/x86_64-linux-gnu/bits/sockaddr.h /usr/include/dirent.h \ + /usr/include/x86_64-linux-gnu/bits/dirent.h /usr/include/netdb.h \ + /usr/include/netinet/in.h /usr/include/x86_64-linux-gnu/sys/socket.h \ + /usr/include/x86_64-linux-gnu/bits/socket.h \ + /usr/include/x86_64-linux-gnu/bits/socket_type.h \ + /usr/include/x86_64-linux-gnu/asm/socket.h \ + /usr/include/asm-generic/socket.h \ + /usr/include/x86_64-linux-gnu/asm/sockios.h \ + /usr/include/asm-generic/sockios.h \ + /usr/include/x86_64-linux-gnu/bits/in.h /usr/include/rpc/netdb.h \ + /usr/include/x86_64-linux-gnu/bits/netdb.h /usr/include/net/if.h \ + /usr/include/netinet/in_systm.h /usr/include/arpa/inet.h \ + /usr/include/netinet/ip.h /usr/include/netinet/tcp.h \ + /usr/include/netinet/ip6.h /usr/include/net/ethernet.h \ + /usr/include/linux/if_ether.h /usr/include/linux/types.h \ + /usr/include/x86_64-linux-gnu/asm/types.h \ + /usr/include/asm-generic/types.h /usr/include/asm-generic/int-ll64.h \ + /usr/include/x86_64-linux-gnu/asm/bitsperlong.h \ + /usr/include/asm-generic/bitsperlong.h /usr/include/linux/posix_types.h \ + /usr/include/linux/stddef.h \ + /usr/include/x86_64-linux-gnu/asm/posix_types.h \ + /usr/include/x86_64-linux-gnu/asm/posix_types_64.h \ + /usr/include/asm-generic/posix_types.h /usr/include/net/if_arp.h \ + /usr/include/netinet/ip_icmp.h /usr/include/netinet/icmp6.h \ + /usr/include/netinet/if_ether.h openssl/../dropin.h \ + openssl/../fake-getaddrinfo.h openssl/../fake-gai-errnos.h \ + openssl/../fake-getnameinfo.h /usr/include/openssl/obj_mac.h \ + openssl/digest.h /usr/include/openssl/evp.h \ + /usr/include/x86_64-linux-gnu/openssl/opensslconf.h \ + /usr/include/openssl/ossl_typ.h /usr/include/openssl/e_os2.h \ + /usr/include/openssl/symhacks.h /usr/include/openssl/bio.h \ + /usr/include/openssl/crypto.h /usr/include/openssl/stack.h \ + /usr/include/openssl/safestack.h /usr/include/openssl/opensslv.h \ + /usr/include/openssl/objects.h /usr/include/openssl/asn1.h \ + /usr/include/openssl/bn.h openssl/../digest.h openssl/../prf.h + +/usr/include/stdc-predef.h: + +/usr/include/x86_64-linux-gnu/bits/predefs.h: + +openssl/../system.h: + +openssl/../../config.h: + +openssl/../have.h: + +/usr/include/stdio.h: + +/usr/include/features.h: + +/usr/include/x86_64-linux-gnu/sys/cdefs.h: + +/usr/include/x86_64-linux-gnu/bits/wordsize.h: + +/usr/include/x86_64-linux-gnu/gnu/stubs.h: + +/usr/include/x86_64-linux-gnu/gnu/stubs-64.h: + +/usr/lib/gcc/x86_64-linux-gnu/4.8/include/stddef.h: + +/usr/include/x86_64-linux-gnu/bits/types.h: + +/usr/include/x86_64-linux-gnu/bits/typesizes.h: + +/usr/include/libio.h: + +/usr/include/_G_config.h: + +/usr/include/wchar.h: + +/usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdarg.h: + +/usr/include/x86_64-linux-gnu/bits/stdio_lim.h: + +/usr/include/x86_64-linux-gnu/bits/sys_errlist.h: + +/usr/include/x86_64-linux-gnu/bits/stdio.h: + +/usr/include/stdlib.h: + +/usr/include/x86_64-linux-gnu/bits/waitflags.h: + +/usr/include/x86_64-linux-gnu/bits/waitstatus.h: + +/usr/include/endian.h: + +/usr/include/x86_64-linux-gnu/bits/endian.h: + +/usr/include/x86_64-linux-gnu/bits/byteswap.h: + +/usr/include/x86_64-linux-gnu/bits/byteswap-16.h: + +/usr/include/xlocale.h: + +/usr/include/x86_64-linux-gnu/sys/types.h: + +/usr/include/time.h: + +/usr/include/x86_64-linux-gnu/sys/select.h: + +/usr/include/x86_64-linux-gnu/bits/select.h: + +/usr/include/x86_64-linux-gnu/bits/sigset.h: + +/usr/include/x86_64-linux-gnu/bits/time.h: + +/usr/include/x86_64-linux-gnu/sys/sysmacros.h: + +/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h: + +/usr/include/alloca.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib-float.h: + +/usr/include/string.h: + +/usr/include/x86_64-linux-gnu/bits/string.h: + +/usr/include/x86_64-linux-gnu/bits/string2.h: + +/usr/include/ctype.h: + +/usr/include/signal.h: + +/usr/include/x86_64-linux-gnu/bits/signum.h: + +/usr/include/x86_64-linux-gnu/bits/siginfo.h: + +/usr/include/x86_64-linux-gnu/bits/sigaction.h: + +/usr/include/x86_64-linux-gnu/bits/sigcontext.h: + +/usr/include/x86_64-linux-gnu/bits/sigstack.h: + +/usr/include/x86_64-linux-gnu/sys/ucontext.h: + +/usr/include/x86_64-linux-gnu/bits/sigthread.h: + +/usr/include/errno.h: + +/usr/include/x86_64-linux-gnu/bits/errno.h: + +/usr/include/linux/errno.h: + +/usr/include/x86_64-linux-gnu/asm/errno.h: + +/usr/include/asm-generic/errno.h: + +/usr/include/asm-generic/errno-base.h: + +/usr/include/fcntl.h: + +/usr/include/x86_64-linux-gnu/bits/fcntl.h: + +/usr/include/x86_64-linux-gnu/bits/fcntl-linux.h: + +/usr/include/x86_64-linux-gnu/bits/uio.h: + +/usr/include/x86_64-linux-gnu/bits/stat.h: + +/usr/include/unistd.h: + +/usr/include/x86_64-linux-gnu/bits/posix_opt.h: + +/usr/include/x86_64-linux-gnu/bits/environments.h: + +/usr/include/x86_64-linux-gnu/bits/confname.h: + +/usr/include/getopt.h: + +/usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdbool.h: + +/usr/include/inttypes.h: + +/usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdint.h: + +/usr/include/stdint.h: + +/usr/include/x86_64-linux-gnu/bits/wchar.h: + +/usr/include/syslog.h: + +/usr/include/x86_64-linux-gnu/sys/syslog.h: + +/usr/include/x86_64-linux-gnu/bits/syslog-path.h: + +/usr/include/x86_64-linux-gnu/sys/time.h: + +/usr/include/x86_64-linux-gnu/bits/timex.h: + +/usr/include/x86_64-linux-gnu/sys/stat.h: + +/usr/include/x86_64-linux-gnu/sys/file.h: + +/usr/include/x86_64-linux-gnu/sys/wait.h: + +/usr/include/x86_64-linux-gnu/sys/ioctl.h: + +/usr/include/x86_64-linux-gnu/bits/ioctls.h: + +/usr/include/x86_64-linux-gnu/asm/ioctls.h: + +/usr/include/asm-generic/ioctls.h: + +/usr/include/linux/ioctl.h: + +/usr/include/x86_64-linux-gnu/asm/ioctl.h: + +/usr/include/asm-generic/ioctl.h: + +/usr/include/x86_64-linux-gnu/bits/ioctl-types.h: + +/usr/include/x86_64-linux-gnu/sys/ttydefaults.h: + +/usr/include/x86_64-linux-gnu/sys/param.h: + +/usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/limits.h: + +/usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/syslimits.h: + +/usr/include/limits.h: + +/usr/include/x86_64-linux-gnu/bits/posix1_lim.h: + +/usr/include/x86_64-linux-gnu/bits/local_lim.h: + +/usr/include/linux/limits.h: + +/usr/include/x86_64-linux-gnu/bits/posix2_lim.h: + +/usr/include/x86_64-linux-gnu/bits/xopen_lim.h: + +/usr/include/x86_64-linux-gnu/bits/param.h: + +/usr/include/linux/param.h: + +/usr/include/x86_64-linux-gnu/asm/param.h: + +/usr/include/asm-generic/param.h: + +/usr/include/x86_64-linux-gnu/sys/resource.h: + +/usr/include/x86_64-linux-gnu/bits/resource.h: + +/usr/include/x86_64-linux-gnu/sys/uio.h: + +/usr/include/x86_64-linux-gnu/sys/un.h: + +/usr/include/x86_64-linux-gnu/bits/sockaddr.h: + +/usr/include/dirent.h: + +/usr/include/x86_64-linux-gnu/bits/dirent.h: + +/usr/include/netdb.h: + +/usr/include/netinet/in.h: + +/usr/include/x86_64-linux-gnu/sys/socket.h: + +/usr/include/x86_64-linux-gnu/bits/socket.h: + +/usr/include/x86_64-linux-gnu/bits/socket_type.h: + +/usr/include/x86_64-linux-gnu/asm/socket.h: + +/usr/include/asm-generic/socket.h: + +/usr/include/x86_64-linux-gnu/asm/sockios.h: + +/usr/include/asm-generic/sockios.h: + +/usr/include/x86_64-linux-gnu/bits/in.h: + +/usr/include/rpc/netdb.h: + +/usr/include/x86_64-linux-gnu/bits/netdb.h: + +/usr/include/net/if.h: + +/usr/include/netinet/in_systm.h: + +/usr/include/arpa/inet.h: + +/usr/include/netinet/ip.h: + +/usr/include/netinet/tcp.h: + +/usr/include/netinet/ip6.h: + +/usr/include/net/ethernet.h: + +/usr/include/linux/if_ether.h: + +/usr/include/linux/types.h: + +/usr/include/x86_64-linux-gnu/asm/types.h: + +/usr/include/asm-generic/types.h: + +/usr/include/asm-generic/int-ll64.h: + +/usr/include/x86_64-linux-gnu/asm/bitsperlong.h: + +/usr/include/asm-generic/bitsperlong.h: + +/usr/include/linux/posix_types.h: + +/usr/include/linux/stddef.h: + +/usr/include/x86_64-linux-gnu/asm/posix_types.h: + +/usr/include/x86_64-linux-gnu/asm/posix_types_64.h: + +/usr/include/asm-generic/posix_types.h: + +/usr/include/net/if_arp.h: + +/usr/include/netinet/ip_icmp.h: + +/usr/include/netinet/icmp6.h: + +/usr/include/netinet/if_ether.h: + +openssl/../dropin.h: + +openssl/../fake-getaddrinfo.h: + +openssl/../fake-gai-errnos.h: + +openssl/../fake-getnameinfo.h: + +/usr/include/openssl/obj_mac.h: + +openssl/digest.h: + +/usr/include/openssl/evp.h: + +/usr/include/x86_64-linux-gnu/openssl/opensslconf.h: + +/usr/include/openssl/ossl_typ.h: + +/usr/include/openssl/e_os2.h: + +/usr/include/openssl/symhacks.h: + +/usr/include/openssl/bio.h: + +/usr/include/openssl/crypto.h: + +/usr/include/openssl/stack.h: + +/usr/include/openssl/safestack.h: + +/usr/include/openssl/opensslv.h: + +/usr/include/openssl/objects.h: + +/usr/include/openssl/asn1.h: + +/usr/include/openssl/bn.h: + +openssl/../digest.h: + +openssl/../prf.h: diff --git a/src/openssl/.deps/rsa.Po b/src/openssl/.deps/rsa.Po new file mode 100644 index 0000000..c3ac6ac --- /dev/null +++ b/src/openssl/.deps/rsa.Po @@ -0,0 +1,482 @@ +openssl/rsa.o: openssl/rsa.c /usr/include/stdc-predef.h \ + /usr/include/x86_64-linux-gnu/bits/predefs.h openssl/../system.h \ + openssl/../../config.h openssl/../have.h /usr/include/stdio.h \ + /usr/include/features.h /usr/include/x86_64-linux-gnu/sys/cdefs.h \ + /usr/include/x86_64-linux-gnu/bits/wordsize.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ + /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stddef.h \ + /usr/include/x86_64-linux-gnu/bits/types.h \ + /usr/include/x86_64-linux-gnu/bits/typesizes.h /usr/include/libio.h \ + /usr/include/_G_config.h /usr/include/wchar.h \ + /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdarg.h \ + /usr/include/x86_64-linux-gnu/bits/stdio_lim.h \ + /usr/include/x86_64-linux-gnu/bits/sys_errlist.h \ + /usr/include/x86_64-linux-gnu/bits/stdio.h /usr/include/stdlib.h \ + /usr/include/x86_64-linux-gnu/bits/waitflags.h \ + /usr/include/x86_64-linux-gnu/bits/waitstatus.h /usr/include/endian.h \ + /usr/include/x86_64-linux-gnu/bits/endian.h \ + /usr/include/x86_64-linux-gnu/bits/byteswap.h \ + /usr/include/x86_64-linux-gnu/bits/byteswap-16.h /usr/include/xlocale.h \ + /usr/include/x86_64-linux-gnu/sys/types.h /usr/include/time.h \ + /usr/include/x86_64-linux-gnu/sys/select.h \ + /usr/include/x86_64-linux-gnu/bits/select.h \ + /usr/include/x86_64-linux-gnu/bits/sigset.h \ + /usr/include/x86_64-linux-gnu/bits/time.h \ + /usr/include/x86_64-linux-gnu/sys/sysmacros.h \ + /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h /usr/include/alloca.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib-float.h /usr/include/string.h \ + /usr/include/x86_64-linux-gnu/bits/string.h \ + /usr/include/x86_64-linux-gnu/bits/string2.h /usr/include/ctype.h \ + /usr/include/signal.h /usr/include/x86_64-linux-gnu/bits/signum.h \ + /usr/include/x86_64-linux-gnu/bits/siginfo.h \ + /usr/include/x86_64-linux-gnu/bits/sigaction.h \ + /usr/include/x86_64-linux-gnu/bits/sigcontext.h \ + /usr/include/x86_64-linux-gnu/bits/sigstack.h \ + /usr/include/x86_64-linux-gnu/sys/ucontext.h \ + /usr/include/x86_64-linux-gnu/bits/sigthread.h /usr/include/errno.h \ + /usr/include/x86_64-linux-gnu/bits/errno.h /usr/include/linux/errno.h \ + /usr/include/x86_64-linux-gnu/asm/errno.h \ + /usr/include/asm-generic/errno.h /usr/include/asm-generic/errno-base.h \ + /usr/include/fcntl.h /usr/include/x86_64-linux-gnu/bits/fcntl.h \ + /usr/include/x86_64-linux-gnu/bits/fcntl-linux.h \ + /usr/include/x86_64-linux-gnu/bits/uio.h \ + /usr/include/x86_64-linux-gnu/bits/stat.h /usr/include/unistd.h \ + /usr/include/x86_64-linux-gnu/bits/posix_opt.h \ + /usr/include/x86_64-linux-gnu/bits/environments.h \ + /usr/include/x86_64-linux-gnu/bits/confname.h /usr/include/getopt.h \ + /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdbool.h \ + /usr/include/inttypes.h \ + /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdint.h /usr/include/stdint.h \ + /usr/include/x86_64-linux-gnu/bits/wchar.h /usr/include/syslog.h \ + /usr/include/x86_64-linux-gnu/sys/syslog.h \ + /usr/include/x86_64-linux-gnu/bits/syslog-path.h \ + /usr/include/x86_64-linux-gnu/sys/time.h \ + /usr/include/x86_64-linux-gnu/bits/timex.h \ + /usr/include/x86_64-linux-gnu/sys/stat.h \ + /usr/include/x86_64-linux-gnu/sys/file.h \ + /usr/include/x86_64-linux-gnu/sys/wait.h \ + /usr/include/x86_64-linux-gnu/sys/ioctl.h \ + /usr/include/x86_64-linux-gnu/bits/ioctls.h \ + /usr/include/x86_64-linux-gnu/asm/ioctls.h \ + /usr/include/asm-generic/ioctls.h /usr/include/linux/ioctl.h \ + /usr/include/x86_64-linux-gnu/asm/ioctl.h \ + /usr/include/asm-generic/ioctl.h \ + /usr/include/x86_64-linux-gnu/bits/ioctl-types.h \ + /usr/include/x86_64-linux-gnu/sys/ttydefaults.h \ + /usr/include/x86_64-linux-gnu/sys/param.h \ + /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/limits.h \ + /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/syslimits.h \ + /usr/include/limits.h /usr/include/x86_64-linux-gnu/bits/posix1_lim.h \ + /usr/include/x86_64-linux-gnu/bits/local_lim.h \ + /usr/include/linux/limits.h \ + /usr/include/x86_64-linux-gnu/bits/posix2_lim.h \ + /usr/include/x86_64-linux-gnu/bits/xopen_lim.h \ + /usr/include/x86_64-linux-gnu/bits/param.h /usr/include/linux/param.h \ + /usr/include/x86_64-linux-gnu/asm/param.h \ + /usr/include/asm-generic/param.h \ + /usr/include/x86_64-linux-gnu/sys/resource.h \ + /usr/include/x86_64-linux-gnu/bits/resource.h \ + /usr/include/x86_64-linux-gnu/sys/uio.h \ + /usr/include/x86_64-linux-gnu/sys/un.h \ + /usr/include/x86_64-linux-gnu/bits/sockaddr.h /usr/include/dirent.h \ + /usr/include/x86_64-linux-gnu/bits/dirent.h /usr/include/netdb.h \ + /usr/include/netinet/in.h /usr/include/x86_64-linux-gnu/sys/socket.h \ + /usr/include/x86_64-linux-gnu/bits/socket.h \ + /usr/include/x86_64-linux-gnu/bits/socket_type.h \ + /usr/include/x86_64-linux-gnu/asm/socket.h \ + /usr/include/asm-generic/socket.h \ + /usr/include/x86_64-linux-gnu/asm/sockios.h \ + /usr/include/asm-generic/sockios.h \ + /usr/include/x86_64-linux-gnu/bits/in.h /usr/include/rpc/netdb.h \ + /usr/include/x86_64-linux-gnu/bits/netdb.h /usr/include/net/if.h \ + /usr/include/netinet/in_systm.h /usr/include/arpa/inet.h \ + /usr/include/netinet/ip.h /usr/include/netinet/tcp.h \ + /usr/include/netinet/ip6.h /usr/include/net/ethernet.h \ + /usr/include/linux/if_ether.h /usr/include/linux/types.h \ + /usr/include/x86_64-linux-gnu/asm/types.h \ + /usr/include/asm-generic/types.h /usr/include/asm-generic/int-ll64.h \ + /usr/include/x86_64-linux-gnu/asm/bitsperlong.h \ + /usr/include/asm-generic/bitsperlong.h /usr/include/linux/posix_types.h \ + /usr/include/linux/stddef.h \ + /usr/include/x86_64-linux-gnu/asm/posix_types.h \ + /usr/include/x86_64-linux-gnu/asm/posix_types_64.h \ + /usr/include/asm-generic/posix_types.h /usr/include/net/if_arp.h \ + /usr/include/netinet/ip_icmp.h /usr/include/netinet/icmp6.h \ + /usr/include/netinet/if_ether.h openssl/../dropin.h \ + openssl/../fake-getaddrinfo.h openssl/../fake-gai-errnos.h \ + openssl/../fake-getnameinfo.h /usr/include/openssl/pem.h \ + /usr/include/openssl/e_os2.h \ + /usr/include/x86_64-linux-gnu/openssl/opensslconf.h \ + /usr/include/openssl/bio.h /usr/include/openssl/crypto.h \ + /usr/include/openssl/stack.h /usr/include/openssl/safestack.h \ + /usr/include/openssl/opensslv.h /usr/include/openssl/ossl_typ.h \ + /usr/include/openssl/symhacks.h /usr/include/openssl/evp.h \ + /usr/include/openssl/objects.h /usr/include/openssl/obj_mac.h \ + /usr/include/openssl/asn1.h /usr/include/openssl/bn.h \ + /usr/include/openssl/x509.h /usr/include/openssl/buffer.h \ + /usr/include/openssl/ec.h /usr/include/openssl/ecdsa.h \ + /usr/include/openssl/ecdh.h /usr/include/openssl/rsa.h \ + /usr/include/openssl/dsa.h /usr/include/openssl/dh.h \ + /usr/include/openssl/sha.h /usr/include/openssl/x509_vfy.h \ + /usr/include/openssl/lhash.h /usr/include/openssl/pkcs7.h \ + /usr/include/openssl/pem2.h /usr/include/openssl/err.h \ + openssl/../logger.h openssl/../rsa.h + +/usr/include/stdc-predef.h: + +/usr/include/x86_64-linux-gnu/bits/predefs.h: + +openssl/../system.h: + +openssl/../../config.h: + +openssl/../have.h: + +/usr/include/stdio.h: + +/usr/include/features.h: + +/usr/include/x86_64-linux-gnu/sys/cdefs.h: + +/usr/include/x86_64-linux-gnu/bits/wordsize.h: + +/usr/include/x86_64-linux-gnu/gnu/stubs.h: + +/usr/include/x86_64-linux-gnu/gnu/stubs-64.h: + +/usr/lib/gcc/x86_64-linux-gnu/4.8/include/stddef.h: + +/usr/include/x86_64-linux-gnu/bits/types.h: + +/usr/include/x86_64-linux-gnu/bits/typesizes.h: + +/usr/include/libio.h: + +/usr/include/_G_config.h: + +/usr/include/wchar.h: + +/usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdarg.h: + +/usr/include/x86_64-linux-gnu/bits/stdio_lim.h: + +/usr/include/x86_64-linux-gnu/bits/sys_errlist.h: + +/usr/include/x86_64-linux-gnu/bits/stdio.h: + +/usr/include/stdlib.h: + +/usr/include/x86_64-linux-gnu/bits/waitflags.h: + +/usr/include/x86_64-linux-gnu/bits/waitstatus.h: + +/usr/include/endian.h: + +/usr/include/x86_64-linux-gnu/bits/endian.h: + +/usr/include/x86_64-linux-gnu/bits/byteswap.h: + +/usr/include/x86_64-linux-gnu/bits/byteswap-16.h: + +/usr/include/xlocale.h: + +/usr/include/x86_64-linux-gnu/sys/types.h: + +/usr/include/time.h: + +/usr/include/x86_64-linux-gnu/sys/select.h: + +/usr/include/x86_64-linux-gnu/bits/select.h: + +/usr/include/x86_64-linux-gnu/bits/sigset.h: + +/usr/include/x86_64-linux-gnu/bits/time.h: + +/usr/include/x86_64-linux-gnu/sys/sysmacros.h: + +/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h: + +/usr/include/alloca.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib-float.h: + +/usr/include/string.h: + +/usr/include/x86_64-linux-gnu/bits/string.h: + +/usr/include/x86_64-linux-gnu/bits/string2.h: + +/usr/include/ctype.h: + +/usr/include/signal.h: + +/usr/include/x86_64-linux-gnu/bits/signum.h: + +/usr/include/x86_64-linux-gnu/bits/siginfo.h: + +/usr/include/x86_64-linux-gnu/bits/sigaction.h: + +/usr/include/x86_64-linux-gnu/bits/sigcontext.h: + +/usr/include/x86_64-linux-gnu/bits/sigstack.h: + +/usr/include/x86_64-linux-gnu/sys/ucontext.h: + +/usr/include/x86_64-linux-gnu/bits/sigthread.h: + +/usr/include/errno.h: + +/usr/include/x86_64-linux-gnu/bits/errno.h: + +/usr/include/linux/errno.h: + +/usr/include/x86_64-linux-gnu/asm/errno.h: + +/usr/include/asm-generic/errno.h: + +/usr/include/asm-generic/errno-base.h: + +/usr/include/fcntl.h: + +/usr/include/x86_64-linux-gnu/bits/fcntl.h: + +/usr/include/x86_64-linux-gnu/bits/fcntl-linux.h: + +/usr/include/x86_64-linux-gnu/bits/uio.h: + +/usr/include/x86_64-linux-gnu/bits/stat.h: + +/usr/include/unistd.h: + +/usr/include/x86_64-linux-gnu/bits/posix_opt.h: + +/usr/include/x86_64-linux-gnu/bits/environments.h: + +/usr/include/x86_64-linux-gnu/bits/confname.h: + +/usr/include/getopt.h: + +/usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdbool.h: + +/usr/include/inttypes.h: + +/usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdint.h: + +/usr/include/stdint.h: + +/usr/include/x86_64-linux-gnu/bits/wchar.h: + +/usr/include/syslog.h: + +/usr/include/x86_64-linux-gnu/sys/syslog.h: + +/usr/include/x86_64-linux-gnu/bits/syslog-path.h: + +/usr/include/x86_64-linux-gnu/sys/time.h: + +/usr/include/x86_64-linux-gnu/bits/timex.h: + +/usr/include/x86_64-linux-gnu/sys/stat.h: + +/usr/include/x86_64-linux-gnu/sys/file.h: + +/usr/include/x86_64-linux-gnu/sys/wait.h: + +/usr/include/x86_64-linux-gnu/sys/ioctl.h: + +/usr/include/x86_64-linux-gnu/bits/ioctls.h: + +/usr/include/x86_64-linux-gnu/asm/ioctls.h: + +/usr/include/asm-generic/ioctls.h: + +/usr/include/linux/ioctl.h: + +/usr/include/x86_64-linux-gnu/asm/ioctl.h: + +/usr/include/asm-generic/ioctl.h: + +/usr/include/x86_64-linux-gnu/bits/ioctl-types.h: + +/usr/include/x86_64-linux-gnu/sys/ttydefaults.h: + +/usr/include/x86_64-linux-gnu/sys/param.h: + +/usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/limits.h: + +/usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/syslimits.h: + +/usr/include/limits.h: + +/usr/include/x86_64-linux-gnu/bits/posix1_lim.h: + +/usr/include/x86_64-linux-gnu/bits/local_lim.h: + +/usr/include/linux/limits.h: + +/usr/include/x86_64-linux-gnu/bits/posix2_lim.h: + +/usr/include/x86_64-linux-gnu/bits/xopen_lim.h: + +/usr/include/x86_64-linux-gnu/bits/param.h: + +/usr/include/linux/param.h: + +/usr/include/x86_64-linux-gnu/asm/param.h: + +/usr/include/asm-generic/param.h: + +/usr/include/x86_64-linux-gnu/sys/resource.h: + +/usr/include/x86_64-linux-gnu/bits/resource.h: + +/usr/include/x86_64-linux-gnu/sys/uio.h: + +/usr/include/x86_64-linux-gnu/sys/un.h: + +/usr/include/x86_64-linux-gnu/bits/sockaddr.h: + +/usr/include/dirent.h: + +/usr/include/x86_64-linux-gnu/bits/dirent.h: + +/usr/include/netdb.h: + +/usr/include/netinet/in.h: + +/usr/include/x86_64-linux-gnu/sys/socket.h: + +/usr/include/x86_64-linux-gnu/bits/socket.h: + +/usr/include/x86_64-linux-gnu/bits/socket_type.h: + +/usr/include/x86_64-linux-gnu/asm/socket.h: + +/usr/include/asm-generic/socket.h: + +/usr/include/x86_64-linux-gnu/asm/sockios.h: + +/usr/include/asm-generic/sockios.h: + +/usr/include/x86_64-linux-gnu/bits/in.h: + +/usr/include/rpc/netdb.h: + +/usr/include/x86_64-linux-gnu/bits/netdb.h: + +/usr/include/net/if.h: + +/usr/include/netinet/in_systm.h: + +/usr/include/arpa/inet.h: + +/usr/include/netinet/ip.h: + +/usr/include/netinet/tcp.h: + +/usr/include/netinet/ip6.h: + +/usr/include/net/ethernet.h: + +/usr/include/linux/if_ether.h: + +/usr/include/linux/types.h: + +/usr/include/x86_64-linux-gnu/asm/types.h: + +/usr/include/asm-generic/types.h: + +/usr/include/asm-generic/int-ll64.h: + +/usr/include/x86_64-linux-gnu/asm/bitsperlong.h: + +/usr/include/asm-generic/bitsperlong.h: + +/usr/include/linux/posix_types.h: + +/usr/include/linux/stddef.h: + +/usr/include/x86_64-linux-gnu/asm/posix_types.h: + +/usr/include/x86_64-linux-gnu/asm/posix_types_64.h: + +/usr/include/asm-generic/posix_types.h: + +/usr/include/net/if_arp.h: + +/usr/include/netinet/ip_icmp.h: + +/usr/include/netinet/icmp6.h: + +/usr/include/netinet/if_ether.h: + +openssl/../dropin.h: + +openssl/../fake-getaddrinfo.h: + +openssl/../fake-gai-errnos.h: + +openssl/../fake-getnameinfo.h: + +/usr/include/openssl/pem.h: + +/usr/include/openssl/e_os2.h: + +/usr/include/x86_64-linux-gnu/openssl/opensslconf.h: + +/usr/include/openssl/bio.h: + +/usr/include/openssl/crypto.h: + +/usr/include/openssl/stack.h: + +/usr/include/openssl/safestack.h: + +/usr/include/openssl/opensslv.h: + +/usr/include/openssl/ossl_typ.h: + +/usr/include/openssl/symhacks.h: + +/usr/include/openssl/evp.h: + +/usr/include/openssl/objects.h: + +/usr/include/openssl/obj_mac.h: + +/usr/include/openssl/asn1.h: + +/usr/include/openssl/bn.h: + +/usr/include/openssl/x509.h: + +/usr/include/openssl/buffer.h: + +/usr/include/openssl/ec.h: + +/usr/include/openssl/ecdsa.h: + +/usr/include/openssl/ecdh.h: + +/usr/include/openssl/rsa.h: + +/usr/include/openssl/dsa.h: + +/usr/include/openssl/dh.h: + +/usr/include/openssl/sha.h: + +/usr/include/openssl/x509_vfy.h: + +/usr/include/openssl/lhash.h: + +/usr/include/openssl/pkcs7.h: + +/usr/include/openssl/pem2.h: + +/usr/include/openssl/err.h: + +openssl/../logger.h: + +openssl/../rsa.h: diff --git a/src/openssl/.deps/rsagen.Po b/src/openssl/.deps/rsagen.Po new file mode 100644 index 0000000..8c50bea --- /dev/null +++ b/src/openssl/.deps/rsagen.Po @@ -0,0 +1,484 @@ +openssl/rsagen.o: openssl/rsagen.c /usr/include/stdc-predef.h \ + /usr/include/x86_64-linux-gnu/bits/predefs.h openssl/../system.h \ + openssl/../../config.h openssl/../have.h /usr/include/stdio.h \ + /usr/include/features.h /usr/include/x86_64-linux-gnu/sys/cdefs.h \ + /usr/include/x86_64-linux-gnu/bits/wordsize.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ + /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stddef.h \ + /usr/include/x86_64-linux-gnu/bits/types.h \ + /usr/include/x86_64-linux-gnu/bits/typesizes.h /usr/include/libio.h \ + /usr/include/_G_config.h /usr/include/wchar.h \ + /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdarg.h \ + /usr/include/x86_64-linux-gnu/bits/stdio_lim.h \ + /usr/include/x86_64-linux-gnu/bits/sys_errlist.h \ + /usr/include/x86_64-linux-gnu/bits/stdio.h /usr/include/stdlib.h \ + /usr/include/x86_64-linux-gnu/bits/waitflags.h \ + /usr/include/x86_64-linux-gnu/bits/waitstatus.h /usr/include/endian.h \ + /usr/include/x86_64-linux-gnu/bits/endian.h \ + /usr/include/x86_64-linux-gnu/bits/byteswap.h \ + /usr/include/x86_64-linux-gnu/bits/byteswap-16.h /usr/include/xlocale.h \ + /usr/include/x86_64-linux-gnu/sys/types.h /usr/include/time.h \ + /usr/include/x86_64-linux-gnu/sys/select.h \ + /usr/include/x86_64-linux-gnu/bits/select.h \ + /usr/include/x86_64-linux-gnu/bits/sigset.h \ + /usr/include/x86_64-linux-gnu/bits/time.h \ + /usr/include/x86_64-linux-gnu/sys/sysmacros.h \ + /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h /usr/include/alloca.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib-float.h /usr/include/string.h \ + /usr/include/x86_64-linux-gnu/bits/string.h \ + /usr/include/x86_64-linux-gnu/bits/string2.h /usr/include/ctype.h \ + /usr/include/signal.h /usr/include/x86_64-linux-gnu/bits/signum.h \ + /usr/include/x86_64-linux-gnu/bits/siginfo.h \ + /usr/include/x86_64-linux-gnu/bits/sigaction.h \ + /usr/include/x86_64-linux-gnu/bits/sigcontext.h \ + /usr/include/x86_64-linux-gnu/bits/sigstack.h \ + /usr/include/x86_64-linux-gnu/sys/ucontext.h \ + /usr/include/x86_64-linux-gnu/bits/sigthread.h /usr/include/errno.h \ + /usr/include/x86_64-linux-gnu/bits/errno.h /usr/include/linux/errno.h \ + /usr/include/x86_64-linux-gnu/asm/errno.h \ + /usr/include/asm-generic/errno.h /usr/include/asm-generic/errno-base.h \ + /usr/include/fcntl.h /usr/include/x86_64-linux-gnu/bits/fcntl.h \ + /usr/include/x86_64-linux-gnu/bits/fcntl-linux.h \ + /usr/include/x86_64-linux-gnu/bits/uio.h \ + /usr/include/x86_64-linux-gnu/bits/stat.h /usr/include/unistd.h \ + /usr/include/x86_64-linux-gnu/bits/posix_opt.h \ + /usr/include/x86_64-linux-gnu/bits/environments.h \ + /usr/include/x86_64-linux-gnu/bits/confname.h /usr/include/getopt.h \ + /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdbool.h \ + /usr/include/inttypes.h \ + /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdint.h /usr/include/stdint.h \ + /usr/include/x86_64-linux-gnu/bits/wchar.h /usr/include/syslog.h \ + /usr/include/x86_64-linux-gnu/sys/syslog.h \ + /usr/include/x86_64-linux-gnu/bits/syslog-path.h \ + /usr/include/x86_64-linux-gnu/sys/time.h \ + /usr/include/x86_64-linux-gnu/bits/timex.h \ + /usr/include/x86_64-linux-gnu/sys/stat.h \ + /usr/include/x86_64-linux-gnu/sys/file.h \ + /usr/include/x86_64-linux-gnu/sys/wait.h \ + /usr/include/x86_64-linux-gnu/sys/ioctl.h \ + /usr/include/x86_64-linux-gnu/bits/ioctls.h \ + /usr/include/x86_64-linux-gnu/asm/ioctls.h \ + /usr/include/asm-generic/ioctls.h /usr/include/linux/ioctl.h \ + /usr/include/x86_64-linux-gnu/asm/ioctl.h \ + /usr/include/asm-generic/ioctl.h \ + /usr/include/x86_64-linux-gnu/bits/ioctl-types.h \ + /usr/include/x86_64-linux-gnu/sys/ttydefaults.h \ + /usr/include/x86_64-linux-gnu/sys/param.h \ + /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/limits.h \ + /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/syslimits.h \ + /usr/include/limits.h /usr/include/x86_64-linux-gnu/bits/posix1_lim.h \ + /usr/include/x86_64-linux-gnu/bits/local_lim.h \ + /usr/include/linux/limits.h \ + /usr/include/x86_64-linux-gnu/bits/posix2_lim.h \ + /usr/include/x86_64-linux-gnu/bits/xopen_lim.h \ + /usr/include/x86_64-linux-gnu/bits/param.h /usr/include/linux/param.h \ + /usr/include/x86_64-linux-gnu/asm/param.h \ + /usr/include/asm-generic/param.h \ + /usr/include/x86_64-linux-gnu/sys/resource.h \ + /usr/include/x86_64-linux-gnu/bits/resource.h \ + /usr/include/x86_64-linux-gnu/sys/uio.h \ + /usr/include/x86_64-linux-gnu/sys/un.h \ + /usr/include/x86_64-linux-gnu/bits/sockaddr.h /usr/include/dirent.h \ + /usr/include/x86_64-linux-gnu/bits/dirent.h /usr/include/netdb.h \ + /usr/include/netinet/in.h /usr/include/x86_64-linux-gnu/sys/socket.h \ + /usr/include/x86_64-linux-gnu/bits/socket.h \ + /usr/include/x86_64-linux-gnu/bits/socket_type.h \ + /usr/include/x86_64-linux-gnu/asm/socket.h \ + /usr/include/asm-generic/socket.h \ + /usr/include/x86_64-linux-gnu/asm/sockios.h \ + /usr/include/asm-generic/sockios.h \ + /usr/include/x86_64-linux-gnu/bits/in.h /usr/include/rpc/netdb.h \ + /usr/include/x86_64-linux-gnu/bits/netdb.h /usr/include/net/if.h \ + /usr/include/netinet/in_systm.h /usr/include/arpa/inet.h \ + /usr/include/netinet/ip.h /usr/include/netinet/tcp.h \ + /usr/include/netinet/ip6.h /usr/include/net/ethernet.h \ + /usr/include/linux/if_ether.h /usr/include/linux/types.h \ + /usr/include/x86_64-linux-gnu/asm/types.h \ + /usr/include/asm-generic/types.h /usr/include/asm-generic/int-ll64.h \ + /usr/include/x86_64-linux-gnu/asm/bitsperlong.h \ + /usr/include/asm-generic/bitsperlong.h /usr/include/linux/posix_types.h \ + /usr/include/linux/stddef.h \ + /usr/include/x86_64-linux-gnu/asm/posix_types.h \ + /usr/include/x86_64-linux-gnu/asm/posix_types_64.h \ + /usr/include/asm-generic/posix_types.h /usr/include/net/if_arp.h \ + /usr/include/netinet/ip_icmp.h /usr/include/netinet/icmp6.h \ + /usr/include/netinet/if_ether.h openssl/../dropin.h \ + openssl/../fake-getaddrinfo.h openssl/../fake-gai-errnos.h \ + openssl/../fake-getnameinfo.h /usr/include/openssl/pem.h \ + /usr/include/openssl/e_os2.h \ + /usr/include/x86_64-linux-gnu/openssl/opensslconf.h \ + /usr/include/openssl/bio.h /usr/include/openssl/crypto.h \ + /usr/include/openssl/stack.h /usr/include/openssl/safestack.h \ + /usr/include/openssl/opensslv.h /usr/include/openssl/ossl_typ.h \ + /usr/include/openssl/symhacks.h /usr/include/openssl/evp.h \ + /usr/include/openssl/objects.h /usr/include/openssl/obj_mac.h \ + /usr/include/openssl/asn1.h /usr/include/openssl/bn.h \ + /usr/include/openssl/x509.h /usr/include/openssl/buffer.h \ + /usr/include/openssl/ec.h /usr/include/openssl/ecdsa.h \ + /usr/include/openssl/ecdh.h /usr/include/openssl/rsa.h \ + /usr/include/openssl/dsa.h /usr/include/openssl/dh.h \ + /usr/include/openssl/sha.h /usr/include/openssl/x509_vfy.h \ + /usr/include/openssl/lhash.h /usr/include/openssl/pkcs7.h \ + /usr/include/openssl/pem2.h /usr/include/openssl/err.h \ + openssl/../logger.h openssl/../rsagen.h openssl/../rsa.h + +/usr/include/stdc-predef.h: + +/usr/include/x86_64-linux-gnu/bits/predefs.h: + +openssl/../system.h: + +openssl/../../config.h: + +openssl/../have.h: + +/usr/include/stdio.h: + +/usr/include/features.h: + +/usr/include/x86_64-linux-gnu/sys/cdefs.h: + +/usr/include/x86_64-linux-gnu/bits/wordsize.h: + +/usr/include/x86_64-linux-gnu/gnu/stubs.h: + +/usr/include/x86_64-linux-gnu/gnu/stubs-64.h: + +/usr/lib/gcc/x86_64-linux-gnu/4.8/include/stddef.h: + +/usr/include/x86_64-linux-gnu/bits/types.h: + +/usr/include/x86_64-linux-gnu/bits/typesizes.h: + +/usr/include/libio.h: + +/usr/include/_G_config.h: + +/usr/include/wchar.h: + +/usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdarg.h: + +/usr/include/x86_64-linux-gnu/bits/stdio_lim.h: + +/usr/include/x86_64-linux-gnu/bits/sys_errlist.h: + +/usr/include/x86_64-linux-gnu/bits/stdio.h: + +/usr/include/stdlib.h: + +/usr/include/x86_64-linux-gnu/bits/waitflags.h: + +/usr/include/x86_64-linux-gnu/bits/waitstatus.h: + +/usr/include/endian.h: + +/usr/include/x86_64-linux-gnu/bits/endian.h: + +/usr/include/x86_64-linux-gnu/bits/byteswap.h: + +/usr/include/x86_64-linux-gnu/bits/byteswap-16.h: + +/usr/include/xlocale.h: + +/usr/include/x86_64-linux-gnu/sys/types.h: + +/usr/include/time.h: + +/usr/include/x86_64-linux-gnu/sys/select.h: + +/usr/include/x86_64-linux-gnu/bits/select.h: + +/usr/include/x86_64-linux-gnu/bits/sigset.h: + +/usr/include/x86_64-linux-gnu/bits/time.h: + +/usr/include/x86_64-linux-gnu/sys/sysmacros.h: + +/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h: + +/usr/include/alloca.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib-float.h: + +/usr/include/string.h: + +/usr/include/x86_64-linux-gnu/bits/string.h: + +/usr/include/x86_64-linux-gnu/bits/string2.h: + +/usr/include/ctype.h: + +/usr/include/signal.h: + +/usr/include/x86_64-linux-gnu/bits/signum.h: + +/usr/include/x86_64-linux-gnu/bits/siginfo.h: + +/usr/include/x86_64-linux-gnu/bits/sigaction.h: + +/usr/include/x86_64-linux-gnu/bits/sigcontext.h: + +/usr/include/x86_64-linux-gnu/bits/sigstack.h: + +/usr/include/x86_64-linux-gnu/sys/ucontext.h: + +/usr/include/x86_64-linux-gnu/bits/sigthread.h: + +/usr/include/errno.h: + +/usr/include/x86_64-linux-gnu/bits/errno.h: + +/usr/include/linux/errno.h: + +/usr/include/x86_64-linux-gnu/asm/errno.h: + +/usr/include/asm-generic/errno.h: + +/usr/include/asm-generic/errno-base.h: + +/usr/include/fcntl.h: + +/usr/include/x86_64-linux-gnu/bits/fcntl.h: + +/usr/include/x86_64-linux-gnu/bits/fcntl-linux.h: + +/usr/include/x86_64-linux-gnu/bits/uio.h: + +/usr/include/x86_64-linux-gnu/bits/stat.h: + +/usr/include/unistd.h: + +/usr/include/x86_64-linux-gnu/bits/posix_opt.h: + +/usr/include/x86_64-linux-gnu/bits/environments.h: + +/usr/include/x86_64-linux-gnu/bits/confname.h: + +/usr/include/getopt.h: + +/usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdbool.h: + +/usr/include/inttypes.h: + +/usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdint.h: + +/usr/include/stdint.h: + +/usr/include/x86_64-linux-gnu/bits/wchar.h: + +/usr/include/syslog.h: + +/usr/include/x86_64-linux-gnu/sys/syslog.h: + +/usr/include/x86_64-linux-gnu/bits/syslog-path.h: + +/usr/include/x86_64-linux-gnu/sys/time.h: + +/usr/include/x86_64-linux-gnu/bits/timex.h: + +/usr/include/x86_64-linux-gnu/sys/stat.h: + +/usr/include/x86_64-linux-gnu/sys/file.h: + +/usr/include/x86_64-linux-gnu/sys/wait.h: + +/usr/include/x86_64-linux-gnu/sys/ioctl.h: + +/usr/include/x86_64-linux-gnu/bits/ioctls.h: + +/usr/include/x86_64-linux-gnu/asm/ioctls.h: + +/usr/include/asm-generic/ioctls.h: + +/usr/include/linux/ioctl.h: + +/usr/include/x86_64-linux-gnu/asm/ioctl.h: + +/usr/include/asm-generic/ioctl.h: + +/usr/include/x86_64-linux-gnu/bits/ioctl-types.h: + +/usr/include/x86_64-linux-gnu/sys/ttydefaults.h: + +/usr/include/x86_64-linux-gnu/sys/param.h: + +/usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/limits.h: + +/usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/syslimits.h: + +/usr/include/limits.h: + +/usr/include/x86_64-linux-gnu/bits/posix1_lim.h: + +/usr/include/x86_64-linux-gnu/bits/local_lim.h: + +/usr/include/linux/limits.h: + +/usr/include/x86_64-linux-gnu/bits/posix2_lim.h: + +/usr/include/x86_64-linux-gnu/bits/xopen_lim.h: + +/usr/include/x86_64-linux-gnu/bits/param.h: + +/usr/include/linux/param.h: + +/usr/include/x86_64-linux-gnu/asm/param.h: + +/usr/include/asm-generic/param.h: + +/usr/include/x86_64-linux-gnu/sys/resource.h: + +/usr/include/x86_64-linux-gnu/bits/resource.h: + +/usr/include/x86_64-linux-gnu/sys/uio.h: + +/usr/include/x86_64-linux-gnu/sys/un.h: + +/usr/include/x86_64-linux-gnu/bits/sockaddr.h: + +/usr/include/dirent.h: + +/usr/include/x86_64-linux-gnu/bits/dirent.h: + +/usr/include/netdb.h: + +/usr/include/netinet/in.h: + +/usr/include/x86_64-linux-gnu/sys/socket.h: + +/usr/include/x86_64-linux-gnu/bits/socket.h: + +/usr/include/x86_64-linux-gnu/bits/socket_type.h: + +/usr/include/x86_64-linux-gnu/asm/socket.h: + +/usr/include/asm-generic/socket.h: + +/usr/include/x86_64-linux-gnu/asm/sockios.h: + +/usr/include/asm-generic/sockios.h: + +/usr/include/x86_64-linux-gnu/bits/in.h: + +/usr/include/rpc/netdb.h: + +/usr/include/x86_64-linux-gnu/bits/netdb.h: + +/usr/include/net/if.h: + +/usr/include/netinet/in_systm.h: + +/usr/include/arpa/inet.h: + +/usr/include/netinet/ip.h: + +/usr/include/netinet/tcp.h: + +/usr/include/netinet/ip6.h: + +/usr/include/net/ethernet.h: + +/usr/include/linux/if_ether.h: + +/usr/include/linux/types.h: + +/usr/include/x86_64-linux-gnu/asm/types.h: + +/usr/include/asm-generic/types.h: + +/usr/include/asm-generic/int-ll64.h: + +/usr/include/x86_64-linux-gnu/asm/bitsperlong.h: + +/usr/include/asm-generic/bitsperlong.h: + +/usr/include/linux/posix_types.h: + +/usr/include/linux/stddef.h: + +/usr/include/x86_64-linux-gnu/asm/posix_types.h: + +/usr/include/x86_64-linux-gnu/asm/posix_types_64.h: + +/usr/include/asm-generic/posix_types.h: + +/usr/include/net/if_arp.h: + +/usr/include/netinet/ip_icmp.h: + +/usr/include/netinet/icmp6.h: + +/usr/include/netinet/if_ether.h: + +openssl/../dropin.h: + +openssl/../fake-getaddrinfo.h: + +openssl/../fake-gai-errnos.h: + +openssl/../fake-getnameinfo.h: + +/usr/include/openssl/pem.h: + +/usr/include/openssl/e_os2.h: + +/usr/include/x86_64-linux-gnu/openssl/opensslconf.h: + +/usr/include/openssl/bio.h: + +/usr/include/openssl/crypto.h: + +/usr/include/openssl/stack.h: + +/usr/include/openssl/safestack.h: + +/usr/include/openssl/opensslv.h: + +/usr/include/openssl/ossl_typ.h: + +/usr/include/openssl/symhacks.h: + +/usr/include/openssl/evp.h: + +/usr/include/openssl/objects.h: + +/usr/include/openssl/obj_mac.h: + +/usr/include/openssl/asn1.h: + +/usr/include/openssl/bn.h: + +/usr/include/openssl/x509.h: + +/usr/include/openssl/buffer.h: + +/usr/include/openssl/ec.h: + +/usr/include/openssl/ecdsa.h: + +/usr/include/openssl/ecdh.h: + +/usr/include/openssl/rsa.h: + +/usr/include/openssl/dsa.h: + +/usr/include/openssl/dh.h: + +/usr/include/openssl/sha.h: + +/usr/include/openssl/x509_vfy.h: + +/usr/include/openssl/lhash.h: + +/usr/include/openssl/pkcs7.h: + +/usr/include/openssl/pem2.h: + +/usr/include/openssl/err.h: + +openssl/../logger.h: + +openssl/../rsagen.h: + +openssl/../rsa.h: diff --git a/src/openssl/.dirstamp b/src/openssl/.dirstamp new file mode 100644 index 0000000..e69de29 diff --git a/src/openssl/cipher.c b/src/openssl/cipher.c index 553b4ad..c0307f8 100644 --- a/src/openssl/cipher.c +++ b/src/openssl/cipher.c @@ -1,6 +1,6 @@ /* cipher.c -- Symmetric block cipher handling - Copyright (C) 2007-2012 Guus Sliepen + Copyright (C) 2007-2013 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 @@ -17,59 +17,73 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#include "system.h" +#include "../system.h" #include #include +#include -#include "cipher.h" -#include "logger.h" -#include "xalloc.h" +#include "../cipher.h" +#include "../logger.h" +#include "../xalloc.h" + +struct cipher { + EVP_CIPHER_CTX ctx; + const EVP_CIPHER *cipher; + struct cipher_counter *counter; +}; typedef struct cipher_counter { - unsigned char counter[EVP_MAX_IV_LENGTH]; - unsigned char block[EVP_MAX_IV_LENGTH]; + unsigned char counter[CIPHER_MAX_IV_SIZE]; + unsigned char block[CIPHER_MAX_IV_SIZE]; int n; } cipher_counter_t; -static bool cipher_open(cipher_t *cipher) { +static cipher_t *cipher_open(const EVP_CIPHER *evp_cipher) { + cipher_t *cipher = xzalloc(sizeof *cipher); + cipher->cipher = evp_cipher; EVP_CIPHER_CTX_init(&cipher->ctx); - return true; + return cipher; } -bool cipher_open_by_name(cipher_t *cipher, const char *name) { - cipher->cipher = EVP_get_cipherbyname(name); +cipher_t *cipher_open_by_name(const char *name) { + const EVP_CIPHER *evp_cipher = EVP_get_cipherbyname(name); + if(!evp_cipher) { + logger(DEBUG_ALWAYS, LOG_ERR, "Unknown cipher name '%s'!", name); + return NULL; + } - if(cipher->cipher) - return cipher_open(cipher); - - logger(DEBUG_ALWAYS, LOG_ERR, "Unknown cipher name '%s'!", name); - return false; + return cipher_open(evp_cipher); } -bool cipher_open_by_nid(cipher_t *cipher, int nid) { - cipher->cipher = EVP_get_cipherbynid(nid); +cipher_t *cipher_open_by_nid(int nid) { + const EVP_CIPHER *evp_cipher = EVP_get_cipherbynid(nid); + if(!evp_cipher) { + logger(DEBUG_ALWAYS, LOG_ERR, "Unknown cipher nid %d!", nid); + return NULL; + } - if(cipher->cipher) - return cipher_open(cipher); - - logger(DEBUG_ALWAYS, LOG_ERR, "Unknown cipher nid %d!", nid); - return false; + return cipher_open(evp_cipher); } -bool cipher_open_blowfish_ofb(cipher_t *cipher) { - cipher->cipher = EVP_bf_ofb(); - return cipher_open(cipher); +cipher_t *cipher_open_blowfish_ofb(void) { + return cipher_open(EVP_bf_ofb()); } void cipher_close(cipher_t *cipher) { + if(!cipher) + return; + EVP_CIPHER_CTX_cleanup(&cipher->ctx); free(cipher->counter); - cipher->counter = NULL; + free(cipher); } size_t cipher_keylength(const cipher_t *cipher) { + if(!cipher || !cipher->cipher) + return 0; + return cipher->cipher->key_len + cipher->cipher->block_size; } @@ -124,7 +138,7 @@ bool cipher_set_counter_key(cipher_t *cipher, void *key) { } if(!cipher->counter) - cipher->counter = xmalloc_and_zero(sizeof *cipher->counter); + cipher->counter = xzalloc(sizeof *cipher->counter); else cipher->counter->n = 0; @@ -210,9 +224,12 @@ bool cipher_decrypt(cipher_t *cipher, const void *indata, size_t inlen, void *ou } int cipher_get_nid(const cipher_t *cipher) { - return cipher->cipher ? cipher->cipher->nid : 0; + if(!cipher || !cipher->cipher) + return 0; + + return cipher->cipher->nid; } bool cipher_active(const cipher_t *cipher) { - return cipher->cipher && cipher->cipher->nid != 0; + return cipher && cipher->cipher && cipher->cipher->nid != 0; } diff --git a/src/openssl/cipher.o b/src/openssl/cipher.o new file mode 100644 index 0000000000000000000000000000000000000000..3831ed895510e40ece69c075d6eba9fa7ed5f629 GIT binary patch literal 32864 zcmd^od3;nw)^^?QEDeDq5X2xV9d^_#%_bmd77{ubLY59DY)#VXB(0$nIvoUe1=I|p z;Hcv$0-~e1j-#W4qcgJTC_1?B&Zy%zIxnLB)Ny-Xb@)g4)TX8 zJ@Mt`JumntJ-uMk-UU5Rl}~!gziCjW@5OR!k7MCK^x-1#Ta@>_D6Q{X(DQuX)(`JM z|7!gkFWUuti226Cq)qnJ>hq`a|FNC%xu(YZI_>9ZtrRXkPe9DfFTyW3^qs zBH0*q)iuXjq{Uc`n~5p3O1fp@$G(4juQONUb3ucY0)xB zHMJjbU^cDF^lu7`1@GUP3lk|FhdvimJwO}wTmX^%IXZNa%jzzGJ>$5R%@xYUiqM{t zjEAOLn=Y^l*B>dle74n{0n>oqtlMMFoR@UrtJ+`=O+IpjHl80@80axZTKeqUqbG=T z(YNQ&1hD0-&!R;Odj3>YSKjkVQ2>Go>2i?LB(rq=fp`_>&H>+xzOQJ6-4`f3Kki2+ z`%$!9+fR#no~O8d=I>ES1!22u!G^EmkZE(r4l3_Sfk9+amf<)O+GAr+Y0rOE^!yFl zL-fh7jP=bhE`KOK*2D9{NelbS`gu@^ecZZn?pTi-y76BR9UZ=Q^Z)PT$3>sTdlJk< z>P7*%UI^zQIKaM7`@Pz;pgv<`=7twDuEpAmAX$-D7dnlkt$0lpKl1p@Gz-iKHtcP@%+4D3Y~gPm1SSR4r*h z8hbtYtK)zvyGj1K32I6H?kW@&{yoZ>O8yth*-AcwvUdP{h-6`*GEpg(R0@>hlFAIF zxTR94lw_&+m69TrDy5`KrCuomtU7RUg;LV2C7`q^Ww3=FcPeFwRN_j>vO1w=jZ%)b z%0RhDDcM#4luMK{!fFI->y&bwwF;EWl``Hs7igQ6l5cGS<$9$QNM(mod{Wt^l*v-L zPbpKZTxhdfDbu8Hdz5mrbvE?#xEKiaBKbx+5825#;~-UBccMu0EjV17hufO~&J-!0 zv4Ev`wt|+16N+vRx)cONaXKY>8KYT%ZUSX6a#K7_@JZ=HiIL*D8>-XcAJi}04M*iu z>L*`vBnW=9WmgDb&j~m z5zlbMdPi(<#3hcn)Df3C;&Mj}qWj9TbAJU_*%|0$y(iyV3QILJ8fg|DpPVlt=gTu$ zDoIM2A{CEPrb=ayQl?qBax;}O-P#5*%vQ<_Yab|HrOdKk17)I8PLT!*lrr1;8fs=J zWsXz|m2#>z5~A%_%4ssos%Qk~wSv=f1iL&pS|`I~DAr9@4o;9#wpnqoOipi?eUhI$ zq%thCBeGg}c3LMvo9s-KZ;|rE%%<)Z;knhC4HYvoqunco=U1{xy|R3}bY_K8cFCGH zrQ9LI(W#U>C2fsT?vk{NlybLJ)+^;6+0W%Pw7ZI7G(&K5Qaq=@r`sd9(i9IatQ5}* zs2z+r3=IOB`qFLyhIU0o>MNM~VrV;yo}oCYsjuR^t8FaxHI#>8ghcA=i=m;~(o)|* z+^ZZ&eKQOdS(0;t^&H63nPHyPL9RDp3q7hc9uuj9UAXZLm#lQxRgh0g&X61>XS&`6 zzLJNyKCtDXu8(Xv%k{Y}4|9EE%SXBXWy`}|cnVNSzARh%MNs*eP`9E5d$GBzz2jagThMMBRpr?55fq9AV?-IP{qXkEL$=$&46<& zb8y{C4uDTF_!)!QC_xQ+n&SB@*W=yt% z24(%zl88(DbW1r&ekRM$6!|$&^*q)Zi)K|1<8aR)c|6LQL!-i)fCKfyAhE}h*r9bo zF0`@m<5;Dmo5xA5(d-=GNBGpuQ4iULC+cEf%K%GZ$mA zTjo>WSyBL`e>)KNfWLzQi#&AMnoo|~(Xh5Y4Yt)nn9oDB^UDM0klR(?2_ZZl@O(Cf z3OMKfr&Wh*8H!bl3z5qh60EKN4W{=OtyRuVv;KyBONTy_5^b;>8au!d{_G zXvnrTHRLndxIF+Iatv(iLw4NjHP-7Swbxi5Qx^IhtG$|VtTLoL)HUo4x*R6It*vX| zgsmoQ4G)#n+hm+z_mM+g!$Y+Pa~Jeb1g&9X!#RV_;82}7EoaL5x;|aC7lqtkz37p( zL3i>2+sR*KvXdLwNtJUOcs^9bFKwbGy-x$1vcZO2-D7`Xbq@fN-2TTp)1tP2d)PRK zg_4G+0M1(1Y7pxoEA3HXcxzxt z_#(o(gXh4>gr^`B5vYc=S0RJ;KM zT#W21I#=dlwQGwXFD}l*oOGS9ont=-KHCLW1x@cn7`~d`eKfsxOtA-C5t!fDLfQSH z)UE(yc(L2u(zvd9!#8=gNYM!FmYlICQi)3#EG%{k`vQ2j0gW* z!o-l~Obl+RrvjM+_(Kyj6dof+buI_6pNW|be737i%wF3!dHW0T|6feZ`_i9(cVgbN z*E39vywr!IwRILuOaac7^&VY7c%^nopGW6!VULS(1nqPhF9xYRZ=Gb=h?05SlnqtwJiRDAT?jC zz2Oj9d^>?iihbBf(v5TkS6O`2h8D5;eKu6ZBAf3c%y?eG!Ui?l52+fQFVoK-FvP9o z)R^u1oG*^n{dRvR7BLNaY!84K}fs#l<#MXOE18 z%~W;2Lt*h_f|PmIzHo>vewRS(uZL}R!vKrilO<|c~c}P`-Bp)}C-0{tt=V&=S>Vcj|8eaEfuM8raWS#J>e&QBh>=8i&Z@)&!zz zqQu)3&Vui`-hx8*5)XL>Ae+BK~*})qV9)y`6jb-0q>8MZJgK zGm=Te%eRMF$6}ie)v|adK`KP7ZFPt&Zc8Atw%;L|BV|8Mv?&1=*&o<5Sd7@LMJ%#2 zDv+$*6C7AhMR9qB`qiw`D&XY+C^qx7g59 z7P)7Ye5~DT69X*1U_(n;WM@=c)*RP*%?G=7hHa~w#h=^IG8WkxG+(`)wOux`n#GrF zXc>#_jB3l85Qr47}xcpX7#t8P1M&pJdFUrivgmM>pxk*5x4 zj7nlZ8f;qu7Pr{YQWm*q^dn&Vaj#7bu=s)vEoG6NQEgdsTCEJj(?;hUrn3+t)R<{BXo4rwwX*vlV3%66CK~BV?HH@$=^ZskJIrfIv%8>$*&?i zO?1SUNwIL2Db4xZLG_Q*@hLhUq@%-B(pQj-E-?+FX<6T<4~9<*Ba3=RXE@r`)h_6m zpO+`{ySrlf?UAPZ)=(&a&5Y^6=~HvtBhl_PxvkOe{Hb{}@*~kudv|kKF-hsoY>LFY z5-15uKKCrt_dN1K=+BzQ_V$iYUK=i-u6T2ExCLaG&G_2Ra2JR$Vc=P$14M{r2Y4QY zD$ro$ja^ZnlESMABGYV++ks`UqHMHxw6=z0AVZHGO=pHfaqI`og=2`yhz?MT8A9gv zSz8)TnUmylugrTNj+T31UblPDC3C*@G$1%1kP$8G4oFH!qYS@f&M!Tu10{r%G4WOq z7uSP0ej7@&(Wo*u@)7`+Yy)kA$D4JEcaE>&kvXHbug?;$BrBypOr~g!rz1ZPvP+%z^*;FEp`w7 zyXR_mho{~>bhbMhcORA4;EsCoWbKEqxpIeiUT_aVd!6&$nR)IIb~ws2)U$oDJKf`T zjT=^;?_T4{^R&`XdfeyCU+!K7$N|qIgt;?5|9AOzWMaNHmOYQSEXea>^1EUo5$tN~h{f@BdSyD;7>Y+$hehe4 zs$fZZmA|wmSQ4lYhT6l8(e6%BR9oo_2B!OJ12yH9^JIbx{63PvZz;hylj71fFc)lU z>-Ve$OZl7MK5g~PN&WHaQep*F3>FKH>yZTGt(t^?kLscNM$VMl~$J46jkuBTHxDU(GF*R!qH|Ggdj|S@_VlOE>@Wg zO|YfCv9-$%8q!yWSB5&*D(iKX<%>#dYHj;C?o#zNFV#L4?&@xjLuPbC^hB_uy%|#n z-<0PgytXI@A-ydw4+P28NEC+_gs?UHDA7t5R#rmD$`@AFib&%$nhY6Sl3T-3n1OcE zRyVeHhdFOBuJ{Ts&g{y@*jeEiZiSGBO|UhdB@!Yhp&;fb4Kq+SgWQ7mvYH#?jS4TX z43y3*t$_@Shhe)@6Omwvk`{O6VAI;5oKRXdMJ1<~2BbS@$0G5tTq^VxIc2@HvTgy) zU7&QX(gO`urLZ2fwE%GphSXQ_gfuN(lPkvCmm8t>4oG^8Kv(1Huv!A$QCLo~E<0#l z;Z@z>h8?%KeG*e+fip@_M$8-<#&%@~oWJBumKRN6ciD?7ENOc}2?Z)$=3Y*L*sED4m_X{l0UWn85)I4U5zo(T1LqpoN=vL`Wf0~|bcEsn>5D++ zd$6;kOLRoTkOr{IRH}E$(|Aywi7^1=7$r||O-D=wi#s~nopm607$<6S7soXucXAb& zMMV{LrD(0Ovok1DkCRc&U~K@u6)w~sGFb#y%RQ7AzBX}nozNOa8egLp-I{ac1&ivX z3U=~9k+U_c_+Yp3={_1h#JV-!CZx}5BU!kxqO_=z$0?mtP6cX;%F4=1xQ0D$g2BTn zM5x7s+h=1FoOqNAw2784E}bjWFc=N5f!N|mrcZ?_42HU6un^n3SHhIXW9`lo!_3e& zDD)a9(mWwhyh@5{8iD~ooVjXc5>sMQc;sFPVZ<$QiaJbHhiN<-N)iF*7ToM6!`Hgh zm6!;2M{$RrOiQS8q3lNahG~YLsmLv;qJ%1jixLnTjd2?6B zyQASba%YKzKy8eL+UCHub?)@3-rQDi?!w95T-bi*z!mn)nc8}lCv_*cgEH}G{4%Lw zcWIeHUW$1oC9}K}=Z2dijZxKe?uPh0vjHed_ne-lxPIcwmmM5#S-RI%Y?J4vNxO04mf+Fh&Q15m zfI3&&EdsmP{|@9pIRQVQYMpEGz;w_2H0WBuOVDBu;!wt@gTVJ@UM5+7>j2ug>Y)kr zjdh<=-BvteT|3nI(_~+R@FoaK7(c+TbuQQGP>ZgJsqpV4s+YIT((ek2#|7Ybne=;J zS_I@0DVIP)ct=(=Q#<*}b#Z#;CRcHK_7(1;bnm4}Md=gQCC^JQbj1gzPXq)a42c2{IPM))2Rd+ zapTI93o);$t4rj?I#5A6TycYnB(-oO(UuON%0=AR)D#P^W(`hU2~4=Kjkbotm?E>L z*@7G0FjqrYA}`dja%C7c**y5cfN&lxYFMYRb&%O`8=U6w+V_83ykG#QS>A7I#tKO` zA01&#^@6dcrx`jd?!$?O;wQuK_NwfMA57sI!7?8HVgGQiolqX2XSN9-D3p>mjE}s~ z=6~AWM>Z$h7L~yL-)-RBKOak}y+IQ}8fXK&C69b$bZgr z^nWn?GyT5_F!afc(~(mEgz_;rP^#@ek7F0$eYO8+u4-@`wc`V~-}xTtv>{qi@{%%>MB!x_$M(t46i=7~?nlSFGNj$V(ER$y20R>$bBX zvBuq}C+J^a5k@>Y(Ew@gUS|VU0k1#y!>2DQ8?|orOC$!0{SNAdA>fuPq<58DeOWBX@^YJ7Ph51kQ!+*0M{4m?0>nFYz#+N@a zK2?PCe9^rpJhRenRP6_G_ynTY<5s%s#X9ZzGCf1aKWfl}0n;En{?hKc6KeGbKWLX8 zE)hpPlr#F{TVwfjn265(F#&wHk8SCxtNjcMp1C_uYkEC_#}>v@uSA>9VWXi0OBAN8oadVb=k5!7>IGQxNLn!jW~LlRo>V_q^qe=Wd$5DP97Jg0sK zKQxCW2SF%^?iJPSkO=1pG;VX zSP<9!8KvR6{aG50YnknrX*fQ=VEoq_K1##)X}DLz|E%FT8vX*|93LOlVR=vE>+$(a z!$$*;{h5LTg@Om&pE3>iLLKv~G+g&b{&E@cOn+K5zV6Q!4Ii!9e^SH8Y4|6Ev;757 zhvhqsuiLli{D9T^eBqA~VL@CU?_v$t`(35sUTDK{I9J21sQL4jhU=ft_E9JzSa1;pBc1SFn_tCi;;w*KRTa( z2EdGSNaK5<4aak(hUlc|GDDiv_#KzPU^y0r~hGl}jE8Y^RKLy1lmTXH&n$ z2LCOZ*Kz~r_uZ=u{3UYg3CH*{=7v2Yd83O-MPxZNfqZAcnSr($H1G(e?C8Q zzt>a0ct3!JasCN{I}~i=ACmtM8h8%rdkuUq@edmKd!)Z%;15wgyl>#A)4Y6c;3+gN zzD{QUA0-|?V`rStPb0`L#`%@4@diGe{F!3lITYtY1HY5}SzzF&kw1$K9IyAWv>JFG z%?sXdU|~OJP+nbZ;Q0G|Sgthi>15|d1Lx~4ybr;`_K#4UA2jf})GuE@F#k-#pELNY z$)CR%`1yn%GVt|;e`Vks33pRJ+;29WKQaxRpVuC5;P_LISjHJRe-X-O;Od9ygqUOC zd_LxHV6i_pk^LJD{z@9pP6NM+@Ous1P4R!&!0|T}u{>em{7Ui*2F~mDuLk~0vVX|H z)vv7zfv@Ue;c+z*pRaQm4-jt<)iZvG=H+MuZ=*aMZQwVk?nJJEA5V5>82D`zw-N(S zB7Z6k9Dh?0OM`*8ll^7`KTLjh82EF_j5x=@4^zJz415Lc8=DRMCSH#Qo{5!|M|4jSBr3Sv9_*WbFRKm9z_%Iq5=PO>rmw!T$^O`>cUqO?HZC zKVUmglU`}yd>&k4;I~s8A_mU);S0zww*Nl)Q*YqBZ*=y9pJ(7BXgoazKA!Yz4g68^ z??wX;Qk-u#@KrRf+YNj!@$WJ49P;M@11D8HY~X9j&SM7t5ZU4VmE(3Q#qAk`UrpnB z(ZKmD1#cTT$L&J{KS<+E9iSEn_dAeyM;rJd%Ae5&&ht3cz*o??&M@#3Xk3ki<1!~# zq$BF5$ert`YlyG@zW@p+7bX8P!#?}DMZ=NbE!jfcVDyWBm&CGD<6|ti{6@pk&I?rW zkcR90$NRDWXMeAv~nvlp?YwPB<-ZKq8 z|2_I*gU|c(Mh!>*c|C46?3_ye>@x8Agg+`Zl!_oA$WdCKt zIi45OdVkyC?;!q{2A|`9M8k2s_q)o>iwUi^UafPt6O z_0w(**YjtehNFqU6aN{)ISxB$yf0~d977?myMFMGH5~2dVk0P@8}{!Z`vWsoJ@?CB znI2)_1;j5h@a2S88hAJ1OAP!%!ea)0E#aFqT+j3C3Fmp-hm}xvYJ8mc=gH2)2A}6~ zzlLLcswh5BX*kZ;G@9QRH5{SWiT|30BcI=S|C@#*e->RIe4ydT|CaLnQw>M{L&X1= zfoEeQD1+$_b?652R}(%|!?CWD@?;X>Jiq)NWtqlDJ9m?v3WI+ho!8DZ@OKD5+ratx z+LZ>*U$wtO!*L4v@4Ua&a16~Tn&0O%93lR@-J68tSkd(=^5^dwAMF&7oo@|3=R-37 zF&+xX^Z!sB25LA$oDah^9OHHtozF&SIPy6k#%MV5Q)oY(sNu-xe3-1^$iJERCu=zJ zN7J~9G#vS}X`Pp8IP!NAze>ZA{~Gb@G#q2GgYxGb!a0AIlbzcPoS)ylYT#LP{{76b z&(|RyeE9|n+vn$&lMK9-`kijzs|a6U;Fl2&UkJDDBgFaEML6eAI|c*F`5Is55BYzM z!RP$hrr~H}Cav3BG#um4`E!qkBY!XP@7HkTbN)Q4;mBV~dAwJ{kKh1I~tCB&YwdXj{IEGKhbcEDPPxR;Y$xtcz%~tJWn(5uL$oj@GLrC z|BP_7jsFU0|Ge4YKR|Z&8F(w<&l&hC!ap!@ey(fL3lQi(=Fb-Rhh-4qoIm%FKf^V? z%pdYU*Wh#hoMPbJ%DgBw?C|@dOAS8TIn%)T{i<#Q&!v6xA_M<`{Jhb?->3N8V&L1! z&VvSCkAZ^njDg=x_WxnvHxvH7fxk`m2hf8xj`KQYUW_vE3hLKq;8&2HB?kTl?GLR6 zo=5gCG4N-|&fNz7J@tFQz)LA^|1|IslqXsAhddrvGsR(!fxkia$(+o6meEz(KJ4{H z?u%k-hX?9XR(Xkln2uK%cqi#=4E$ZvZ#D1&>hEy_UqSfm2ELi_FASWW%A|Vsa|b!g n{V>kg?QI61uLJq_cbU)E1N`2CjZ;wDs2>}rc{$I(c|HDL;V{q- literal 0 HcmV?d00001 diff --git a/src/openssl/crypto.c b/src/openssl/crypto.c index c695be8..6c5cbc8 100644 --- a/src/openssl/crypto.c +++ b/src/openssl/crypto.c @@ -1,6 +1,6 @@ /* crypto.c -- Cryptographic miscellaneous functions and initialisation - Copyright (C) 2007 Guus Sliepen + Copyright (C) 2007-2013 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 @@ -17,13 +17,13 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#include "system.h" +#include "../system.h" #include #include #include -#include "crypto.h" +#include "../crypto.h" void crypto_init(void) { RAND_load_file("/dev/urandom", 1024); @@ -31,7 +31,13 @@ void crypto_init(void) { ENGINE_load_builtin_engines(); ENGINE_register_all_complete(); + ERR_load_crypto_strings(); OpenSSL_add_all_algorithms(); + + if(!RAND_status()) { + fprintf(stderr, "Not enough entropy for the PRNG!\n"); + abort(); + } } void crypto_exit(void) { diff --git a/src/openssl/crypto.o b/src/openssl/crypto.o new file mode 100644 index 0000000000000000000000000000000000000000..cad569b86431858f562fe44a4caca3a254c82465 GIT binary patch literal 8632 zcmbtYeQX@X6`#HHIcGa|{E-hIA#g?{K#A{gNP+_i7zdLWQYYl24OC&Xceg$tIqx2~ zd%=NzLZHwRpjAUr3E!v$XeERc2~i0sq$+uv8RUlJ`s zybSW)*^fnMn#}F5go&-UolL&A_3P5%ivwiw5;`>O7oB++zQlWYOipHI;cUS@n5|VE zui#IkoyvqCrd`jk6{n~QtA6EBdeX0^!znktW9P({fp&46f}}qxNjbndqpZnB^@yR0 z{bHD&@#F%4xRsPuOraJgTNRl=)zXqEc_A4{BwfVsE>VLLk3eK^iDYZ?D4-=BNN2xn z`EUhk%5GXd%26xJAKwd6@&AI{t>k}0?pN|D$muqE&>$^SyvMHvI70q zZUVO|kg^=|cAEk#tQ!g3slY1h7E-%Ufvk0ezyk_gAi<*w3`uZYfi)65r@)2QAlba2 zz&aV*D+*j>-9-JI6z$Y5S{{_^(BJYH2C3%tafmEGf#LExJe4E5TeK$6CayJkj8F#_ z6k#vCg9NZxPRV{%vwg%KA$Myo_w)NtvpP;Kw>0Pn5l?64tRw z9KCZ{Ou8SDZI895jd)dhtljZ;%7tD{WJs$H)^Tzp&sj+ zSaP7@{dUq6D)#er_wt<}U>$pqeDrDhNJBNNxrXWoq`KIzg~G~W)lrtxHrro^Wk;xiEYq0n|ij-HsF6xJzK0(lx9tp#hjte=!Q zBe?~RCF|twxLlXEX;`m-S_d8idj=*T^(dSHsfQeZG;NQ?l#3hUXTYMZ2p6fRpbv@0 z*JG{h>g$MiE$`~FdKYw4^s%KP-gR-uB^~25ck#1DN5`eqPD#rmrE6jlu@p5bXf5co z;$0mbFtP|HJL?{XNv(}xV!RKqUHhkTSk`zSEEW!k@xClIcCI3Ul5-WswkTs=mQtad zlR|VO{ofu~`oA$sbKFY}v^Ybg)2GCvqbZ=p3CeUes2GiL z2|*qs;8Nv}b(gKJH(r+7n4-mt1~T5aQO1x;$VgAi2o5rFj#OSAC7>+C>2<2(oRp$g zG+cUJip0RqXwX_yU{6B{RYf1oJzA_W)gmYvA7N0h<{Iv9X1IHf;c9Y0DMCeVO;W-` zcULD^SWREJm`Kpmvi{lCNl*Em2lgwj7X)RItp(L=xs=Nm^ZD$|@Opdw+QD+ktIZ4+ zy;^o{W;k2&^5t5=RhkUuYUWB|FiT|?$m;GyzIvz<`k6eA7(rMlxRaSFj43=+aRUP_PTHFNj~zEzQ6ay5;QyZ_;x#2o3vf8Ak^8Sbh9gLzg)2W$;rSC#n@+d z*!i;Sc(sZs__bWw6|^~(T~F-1eBuhb61cU3Z|4q$ZlIX5?-cCG66wKt;2d3( zgB1EEdeb&+5IhzcyY0C%G<$Z%DGaHK`T@F7RclqXPN+PZH3B)xSxh69WcF?wZ)G8{eC^j0XOza?Z!WylWOhbxg+NT`>`f}td1rLS}y$?En`Hj!k zUwCNC{FmCC1nvxHGV+E(5L-5HzBqmE6>hHNcxoO8htE?2Z)%IVwr<`jteI|W`N9Rs z`)D`8mt3Ed_Cn{1uI`|{D|tD6y>NoTcNj&VE#POHWEz}=nc&bg4Mk)qLsdPcrK($Y zG9lI`Q*c5@WO6|uGF2Y{>Xfjv;V?ni6x>{`Nbl{WPnJ@4a=EH|P$L@tEKP^DpCY|a zQES?kU9C@ji448h({$Al8P5;h45c1r6D=Pbxl{IJ)tPpAi2rw$CJ!{tLS9!Q-bPq9 zKSK3WBe&xmMSJp`G9?dYv_5c71;;yx`V)tBMZw7fJbfW%l@qg21F*X~fsZGA{;&2! zWDB2b=s#L?|D92iWZl26N0>A1UuV0sxYm^(zqa4a_PSlye`4W##^h={t+$;7Lq#?{ z$`gDicZm7NElBsT=YKzOrca{8{ro~bVKf?0c=OnAkXJ4ts&E!5ru`SG&E%l|EZbiY zv4v>r9wM&U_|F|shT0zEr!8a7_`gY<=@XW}(fu2Z1{65`H|u{d_pj#}{Uevm`G1%= z_|$QdC`*UD$I>O*NNnA|uAe6DX7)!GDnIf9qeS`CcDjC^?IS8ue1`2!UfXH@$0UHO zpTW4{Ikw-=SXX-d8ox?Hv-ztGD2=VGi23WKe{HYlwTC!kiljw1zqmh>sPQo4Zx%bW zkJI%4J=V&HA6=3+(&U9xZ17(YB}zy%zD8Q&CRK@unGzIGRNQzS#_e z*I!NTS=I45UjxnaOEFuW{BW|);pNXS28(|2CeAH!`Gz#(q4I`iE&{`(au zdfw&x4?O8oC_ZNnda$t3t7Np z>(TsxqUHVyTg~I#gaUo+jha6nBo*+;Va;Cxk_vbn%`|@%NGgawdIrR~0tNcmYqdVk zD=6R*v*sO;RKVj*sQDW~QUQ-|k>+(@=vVKlBnti60S|c;hE(*MuK8`e)nV)?n!gzv zClx)Pfb2r@=gFtikM2U52#6!X@ZVv4 z!r<4jpC1~0Kl5)Ge3sYuR|X&Be%~?pyBYu0;NNEd`a`P6^?lY`$o@3Xv`88JK8|OV z!JlIP7aIINb~Iw}FEamWgI~#ht~2;QGha0L0gfj$cs_QBuNeF_jPEh{P3-4EgYV*g zj~o0b;}Zsdn8)?1!Qab%eroXdGyhwIe~9__4E{;x^?Re&>sjXGTxaIDJj_{? zEpHh-A8*AUBYgDx^^XV-5#Iom1kaQ9ukRPV2ES6Ni!%-WQ_Qb6_$>1q41O2$6A@m2 zJJ6Jm@Q8CS>)*({UdIEB^*ZbL_p|;zh98&tV}>7m8&DoM^!54ZwTOP3QkBowBRqVp zaVJoGm(|F+@3#{AzR`tY-e@hO9U0RyDc&PRVe4?WB;G586kF0ux%_q&S>{x#O$ zZ1DTo|J4Tnd)D7&@Jl%E>ka-X_ERwUFK}MoVeoIT{yheN7WaF + Copyright (C) 2007-2013 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 @@ -17,57 +17,55 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#include "system.h" -#include "utils.h" -#include "xalloc.h" +#include "../system.h" +#include "../utils.h" +#include "../xalloc.h" #include #include #include "digest.h" -#include "logger.h" +#include "../digest.h" +#include "../logger.h" + +static digest_t *digest_open(const EVP_MD *evp_md, int maclength) { + digest_t *digest = xzalloc(sizeof *digest); + digest->digest = evp_md; -static void set_maclength(digest_t *digest, int maclength) { int digestlen = EVP_MD_size(digest->digest); if(maclength > digestlen || maclength < 0) digest->maclength = digestlen; else digest->maclength = maclength; + + return digest; } -bool digest_open_by_name(digest_t *digest, const char *name, int maclength) { - digest->digest = EVP_get_digestbyname(name); - digest->key = NULL; +digest_t *digest_open_by_name(const char *name, int maclength) { + const EVP_MD *evp_md = EVP_get_digestbyname(name); - if(!digest->digest) { + if(!evp_md) { logger(DEBUG_ALWAYS, LOG_DEBUG, "Unknown digest name '%s'!", name); return false; } - set_maclength(digest, maclength); - return true; + return digest_open(evp_md, maclength); } -bool digest_open_by_nid(digest_t *digest, int nid, int maclength) { - digest->digest = EVP_get_digestbynid(nid); - digest->key = NULL; +digest_t *digest_open_by_nid(int nid, int maclength) { + const EVP_MD *evp_md = EVP_get_digestbynid(nid); - if(!digest->digest) { + if(!evp_md) { logger(DEBUG_ALWAYS, LOG_DEBUG, "Unknown digest nid %d!", nid); return false; } - set_maclength(digest, maclength); - return true; + return digest_open(evp_md, maclength); } -bool digest_open_sha1(digest_t *digest, int maclength) { - digest->digest = EVP_sha1(); - digest->key = NULL; - - set_maclength(digest, maclength); - return true; +digest_t *digest_open_sha1(int maclength) { + return digest_open(EVP_sha1(), maclength); } bool digest_set_key(digest_t *digest, const void *key, size_t len) { @@ -78,8 +76,11 @@ bool digest_set_key(digest_t *digest, const void *key, size_t len) { } void digest_close(digest_t *digest) { + if(!digest) + return; + free(digest->key); - digest->key = NULL; + free(digest); } bool digest_create(digest_t *digest, const void *indata, size_t inlen, void *outdata) { @@ -87,7 +88,10 @@ bool digest_create(digest_t *digest, const void *indata, size_t inlen, void *out unsigned char tmpdata[len]; if(digest->key) { - HMAC(digest->digest, digest->key, digest->keylength, indata, inlen, tmpdata, NULL); + if(!HMAC(digest->digest, digest->key, digest->keylength, indata, inlen, tmpdata, NULL)) { + logger(DEBUG_ALWAYS, LOG_DEBUG, "Error creating digest: %s", ERR_error_string(ERR_get_error(), NULL)); + return false; + } } else { EVP_MD_CTX ctx; @@ -111,17 +115,26 @@ bool digest_verify(digest_t *digest, const void *indata, size_t inlen, const voi } int digest_get_nid(const digest_t *digest) { - return digest->digest ? digest->digest->type : 0; + if(!digest || !digest->digest) + return 0; + + return digest->digest->type; } size_t digest_keylength(const digest_t *digest) { + if(!digest || !digest->digest) + return 0; + return digest->digest->md_size; } size_t digest_length(const digest_t *digest) { + if(!digest) + return 0; + return digest->maclength; } bool digest_active(const digest_t *digest) { - return digest->digest && digest->digest->type != 0; + return digest && digest->digest && digest->digest->type != 0; } diff --git a/src/openssl/digest.h b/src/openssl/digest.h index c192249..0a32707 100644 --- a/src/openssl/digest.h +++ b/src/openssl/digest.h @@ -1,6 +1,6 @@ /* digest.h -- header file digest.c - Copyright (C) 2007-2011 Guus Sliepen + Copyright (C) 2013 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 @@ -17,30 +17,16 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#ifndef __TINC_DIGEST_H__ -#define __TINC_DIGEST_H__ +#ifndef __TINC_OPENSSL_DIGEST_H__ +#define __TINC_OPENSSL_DIGEST_H__ #include -#define DIGEST_MAX_SIZE EVP_MAX_MD_SIZE - -typedef struct digest { +struct digest { const EVP_MD *digest; int maclength; int keylength; char *key; -} digest_t; - -extern bool digest_open_by_name(struct digest *, const char *name, int maclength); -extern bool digest_open_by_nid(struct digest *, int nid, int maclength); -extern bool digest_open_sha1(struct digest *, int maclength); -extern void digest_close(struct digest *); -extern bool digest_create(struct digest *, const void *indata, size_t inlen, void *outdata); -extern bool digest_verify(struct digest *, const void *indata, size_t inlen, const void *digestdata); -extern bool digest_set_key(struct digest *, const void *key, size_t len); -extern int digest_get_nid(const struct digest *); -extern size_t digest_keylength(const struct digest *); -extern size_t digest_length(const struct digest *); -extern bool digest_active(const struct digest *); +}; #endif diff --git a/src/openssl/digest.o b/src/openssl/digest.o new file mode 100644 index 0000000000000000000000000000000000000000..64e8d0d46d0f1b70347061e14d9c70f69036cd82 GIT binary patch literal 21224 zcmbtc33ydSmah9=mIomrCMrQi9y=~c2nIzIBncre3Ixa^tB)*?Bu(-XUtSPbRK)hN zxQ$zP(}HccqINruJ?+@)r%|-ER~_wE+FsP2R@>g(nQ29t^H-g7U!{_KGv7>oUv8cA z*I%bjomy_)dmn7AUa~mgc}kL}7O1o)s8WAAH7zgH;zBh}9jz)FYEy@wLXF1Mr%x79 zUjHW)N45_{QU{W!ElGu!q~6ugna^zkf>axJao~ zm9J~^*ooJ`46N2iQlCe*{WT37-~G3 zO_#DGhE2q>fwk)oY_#p!=2Fl5W{%97Ma)N_XV=WC(tkVHZc zW+e5r8P5S3QL;}XY8$^2ZoyvJ%j5`~8@s)gM({5W=>F3f{H#9GT0>KeW>UJB+>dJp zl1HN(k<>dfSGNz0y=5S>JN5y!M6+j5{F6D6o!K3wOsiU4N${KW;@$)NhP$iuYU;54Ux;$NG}tcyo6wJY!nlj7iEZ z>1+#6Yn!C16N#QgxHS=LPIkuIx!%0+v_ADCbIn+oa0K4isj3hGjQ3E&$14t zSX?UTg>)7$S_Xqz2Fyg3k&)RMPf`V~X%iW{I;p^jyCJf*%urV7R;Zpfpp6~OJT!rr zx|z)XY@t$?58nXM;9o$_H}aQ|i;R2(a(EP7RHpKv%ruIpm03m!Xl1TZf?8Q9hjOjLE*Yk>s%9@9!abrjhTvh2&XA zz90O#M*iLlBri1bKOZ7FV&sSKCD)c4`TJxx>hh97ju{m-}+X_2mCpDpa$w zM|poHMUO>xju*zlG0GV4cxobKlw42u!6M1{RiAgIxz{MprCOYO&GO1gtAN zd65}pM1%_ z=S%6S)npIJOs7>akEF}rq(eYSYjTV7HehcK-gM(uKV)y^(o+DH!|Toawkp5iFcl=y z1?hlYVFmUCI(qswW|DH7uF>GlO2b$}PZ>kQEu-{WtD^es23p&S;UPomVZ=7!x7JGR zanwsJLyY9Az!h{|jcS356xDOayD@M%mBTC@U2tzi#7eIvA%mP#xsc4R6SqgKnqVYv z&oN_U#NvZTEIxR|;>D&0<bdj98D9o;s84A(;{Dg?S{ugP3%m=?-GABG<9PDI}Dw zK&LOVHqhHl=yV_&P-41>CUh4c!E~^?*x!PtIHgzpI^t8nski+QX%c6JT1d!EZ^@U5 z|Dfqx2IzZk^J`wlHBBtH+4OWn&-wIigXlZ#(5J0`;?s99y$sEd-j8#u5$}UI8)(ie z`W%Hdua7e3Jad{Z3IsGI`%QgR##UOOH(rBw2BBcS7U=s*IqKv_uoIiZ2%@Ho=9s3& z{5=RFHbhNOr=v#pJptG;&b*;b(K;^VJS)}_>=2$}MfPf6F>_RV?my?4^9;u;R-@;s? zjbb&kwh-!Qu}`t}yxKz47&A%L7M4e+O(I_em2#&}b& zAXC!|sfCbn87&;0G02@`W>UoyXta(kAsjSR4{KM)W%@Pg{8Vl!<83lxv#{v)%JFc7 z4!IJb0LANgs>SgN6wxMPsZ=^)f>&0!(rX;IDrdEB@x)A3R(Jw=IWdP&I%ZWjY{}cUoJ^3&wusveLa+BQvZ8&5Q6h?X?;s*8 zezt)nX~|O!B3{Wwo@x^D8Xsy9QCc=bCfYqdu}MVRkA}Tm?q|I$iCGG)*xK#el4;`C zdWfYbeM+NkRcOAZphEVTw3N= zY!q>g4>gInevmEETGB+{E(>CQrcY@Qah(sX6HyGBK#P_(ziuS+bA4MYL|pAd^&*Nv zm|wA1w6yslD_p#v%(eomKmSaY>wNpm#Zq$`avkmEqRV|sqlnk~P`!vde5g^xoeY^# z6zwLTSTEwuK19#0gVR1P8c0(_JT73Uv=51hm&Qn@MbYpo8i|M^UNwj)nmkDn(bPy^ z#gAuwKN>_l!8gB7L}}Sf3ehf36GfDk4N)v6^_6{-odv0?w_d1}q zDv8Th3v)XSo|_~f2mA;&iujff)rINEk5PD zx>Cgd@S$}g+D@z-(bipDF-P@>Zpq*oFjClroNJM3Y+d>jZ1YXd1L`7|qE02m6c0Y_ z*&jXaN|~(4d77TkbdqyzA?snzWh0U^9m9S$jc1kIp^90T8)7-@3pkg3U+y5jAr@wG zUwb)Ea=w}K>o}Leck7=`px6C~~dU|?36fUC}XZ2@T)+)2vRP)Xrg;rV4Z&7ZjUlhEVa zYf2xSx27~WHuTXuwX1`h|M+oeR$$ur;3eml2e*X6!O@}Q-r5BZsz8R9^%z|Se_2Q2+WXT$=)8bOv!%Led35QbXkX_gF%^yWY}^=4szue6jWyBb zE9)BSs_K@gXl-4TeuvN&?M)_B^~#k|3SLhlYT~7$tsTvsaRmcZwX~zBJ4UlCmgp;O z@9*y`rC%?!7MGQjmG&iCRkW|8Cy{LF->3&&b;diB+BzZ8mgc^gGTx|-o$=-_8ZY|c zgTC~~`#Rg>v9>UNmSDWAs#~_Kx~ieJZdpA~geYcRwB_O`zQ0s2tEpX9EhR}6i*Js0 zw~^0kVrar2g zsTtKj-=Mfs09%?{H}&_LUPd=|HMjRE@~5pi+3ZIE7P@2It-TjZeZNQaa}gEo>1x9O z^~ES?oFiV#&#PV?t!h}MHpdd38!x7);#&c&80s(^0uYVIwj>pOfgz(Mv5xd!*r9 zUQu;kb%S=|qC{shrso=dB|~!t^F>db@E}Jx#_S{9?`z&1GZ8jr5=M$x6rY}=a9!z6 zW7DBA#5l}W(e57F@u=6-A=TR5t2QwGF`#ArumEY+(xMmBsJI-YmWE#>b@_oT~bYRwY@V=-u3qMk!yNL`cxuzVSi^L zMvD+*X56pr>FH8_O!PdZIn|m>bm?WAP@~v8wp?PCkZ~Rpsu!Q2v{NRO4J#`aFRrap%`LPC=!xFltK(wU z6D*!yPFqN{wLcMU?dj_8rb$a-(p!(-9sDsyM2*qIpBb!u}~`*n(l{{+|3=QygfEwD5XC&QWacaX~}k!#;; z;QOM%zE|X+j~Ucoq{+A}f}NG4^Frt5kefOVQ@I=m5AIKH)}kAN*Jo7k&aB>*wP;&* zpnEh0t~w{M3V9?)g^4P!EviZO>s9UwF4~rH39;xGCiE*Zwk>B-V7D+PU&Vm!cX$}L zCmbF@^q#!$;%-`|lqVA=?+_^w>uN4Z;#N?ir)Eh@U!N*T^gscfZq=lMWaf8gd}9w$ z^;~amX-UL3i-sGf&1_CI$LYt7QY@Nfi%yy`DW<0ABXv)AcZ_bACGnnQtc2DAO>eqS zve{TibYlXyfd6j_lL3T@4taypLe|`82gKS=7y~+;4oMs48c5FO_<0Z7ktY+(Po(Me z2b>POgVF;oz@D6^AWA1}{c z4E#^Rxbio2BkHTm{R*MO_5VtAjM6NV>7SF~Io0j|6@NOKS|VS(NvSash_wQq)ghE zd_QAu{i*yhXF|HFmZYBK|6S#U2J9GXw(=)GKFbQPBLtct}A|kJJ#D?C_@O6b1E3V=##E&L0eE z4eMz*{G<`^Qo;);&KoF4(q}%(tLSeyI~a%IaO~5t^AP1o@`*P=@^Jji2?t+>Sk6z^ zkHEj3`C*<~m82uxLx02Be{cl+2ZWMb!qIWqCt7~wbNTdqXFVR;rTPgKrnJB% z@>W3}?gqcQG0%AR%O-vqq#yfWYf<{GNLuB$33$tvetaMD&MnP1Zxh%fdHAGvNc3pU zpgg*=nts@4fZw06#&5)E&?(7tA%++Cg~Rl(vXEw=kP>k0HiFADA8?GV;9Vpm0mnT~ zaI8}#?9({+N%}eq;A4*x{^J&od!yh7EZnyLHsfOdIMzS3__lp{21L8yiv2k>Kaqgr zSyAvM7LGkraLjWg@a;HUVc`?0O!!Y*xE;^`vhYb3e+&#$LT0x+%fcs9nb@zg@F^C) z#KLhD6MmD0PqT3R<`PNbS!Pt#W%2EJ-fZF1i7WO8EIe%CuUPm@3;(JW2Rm*uXW);0 zca}RWaGXcC^7#^T7)kItZVz(?$;XXq{)Gj}Xr8IM1ouHC@TD#2CAd%$I}xMGV~&sa zu(3)m7yi?{|J6D;{$Uc*a+CRXA-?$|%f{z$xqe?RlCa`-p1Ki50>EXKd#;N9$xytfkjf8}<6;P4+|{TT=U z8QYi7{$l49#((SZUuXP12Y-w4Lk|8Y#)Isa*w5fN=R3Ih=Z^I6p&a}o=1+5Q`IcDb z;NstW2ba&~wGRGuwtuUG=W>7cIQTa>{*OAi+;8ytKx+u7sbuQLBW2mdG5A8~Mr{{aWTl;_V&4!(xl z{hfo$xctSzpJY4oUQqh`55_-t_^%>km12 z8^`kz2fvEv&l3**L*^fFa5*2p`V*C{aVJi%EH0F4rEFZ3kP53Posms!Rw*Q91-vA?&4mo_ef0%zUZO$$5^L4h9 znXRk&=NXCrSPKVV&eca-IQ)_EJ<-C!e~l-_6viday{0*JmV<9+yurcmWW2}1xr@5w zO2%b=KFjC^F9DMwHE2LjAE^&Cu z!0H_bf1dG=9sIY9kKu_IbA0(vDt221qD=oerD#lkcF7cH4&}!l6 z*Fx@>`A-zm&r^6mh1BoZmtUjrwCo^mzvFpwtHTeoo$oq)S?`ZnIQ-em{ygX4Uo!qn z2Vc(%{&$R{Ik+Of1$^7$V;_*`v`;J??TVc*99;I_07#U?zWj{*I0u*C63%q+mFL_Qok8xB(+#)>gjShbwx7+3LWnOKzaD@0Sj`O7!4*N2%wp%!;e`Ed*3kP53 z)h!kd>U8es*DM_Tqj=o!ws7#H%zxOyA7K1(2S3R8fQ7@p%-f$>IP7P${vziR=Vv)? zpF6nR$4mId5t@Vji5&mAjEkKQ*iN0pm-u%$_+gGi!m%UY8Bz{k?A-3)k8!(qIdXq1R{i&KE*@qA zx+zlukev4g-vE%(E|Y04%H+H{;NbcoL71Ee#g3ep + Copyright (C) 2011-2013 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 @@ -17,68 +17,70 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#include "system.h" -#include "utils.h" -#include "xalloc.h" +#include "../system.h" #include #include +#include #include -#include "ecdh.h" -#include "logger.h" +#define __TINC_ECDH_INTERNAL__ +typedef EC_KEY ecdh_t; -bool ecdh_generate_public(ecdh_t *ecdh, void *pubkey) { - *ecdh = EC_KEY_new_by_curve_name(NID_secp521r1); - if(!*ecdh) { +#include "../ecdh.h" +#include "../logger.h" +#include "../utils.h" +#include "../xalloc.h" + +ecdh_t *ecdh_generate_public(void *pubkey) { + ecdh_t *ecdh = EC_KEY_new_by_curve_name(NID_secp521r1); + if(!ecdh) { logger(DEBUG_ALWAYS, LOG_ERR, "Generating EC key_by_curve_name failed: %s", ERR_error_string(ERR_get_error(), NULL)); return false; } - if(!EC_KEY_generate_key(*ecdh)) { - EC_KEY_free(*ecdh); - *ecdh = NULL; + if(!EC_KEY_generate_key(ecdh)) { + EC_KEY_free(ecdh); logger(DEBUG_ALWAYS, LOG_ERR, "Generating EC key failed: %s", ERR_error_string(ERR_get_error(), NULL)); - return false; + return NULL; } - const EC_POINT *point = EC_KEY_get0_public_key(*ecdh); + const EC_POINT *point = EC_KEY_get0_public_key(ecdh); if(!point) { - EC_KEY_free(*ecdh); - *ecdh = NULL; + EC_KEY_free(ecdh); logger(DEBUG_ALWAYS, LOG_ERR, "Getting public key failed: %s", ERR_error_string(ERR_get_error(), NULL)); - return false; + return NULL; } - size_t result = EC_POINT_point2oct(EC_KEY_get0_group(*ecdh), point, POINT_CONVERSION_COMPRESSED, pubkey, ECDH_SIZE, NULL); + size_t result = EC_POINT_point2oct(EC_KEY_get0_group(ecdh), point, POINT_CONVERSION_COMPRESSED, pubkey, ECDH_SIZE, NULL); if(!result) { - EC_KEY_free(*ecdh); - *ecdh = NULL; + EC_KEY_free(ecdh); logger(DEBUG_ALWAYS, LOG_ERR, "Converting EC_POINT to binary failed: %s", ERR_error_string(ERR_get_error(), NULL)); - return false; + return NULL; } - return true; + return ecdh; } bool ecdh_compute_shared(ecdh_t *ecdh, const void *pubkey, void *shared) { - EC_POINT *point = EC_POINT_new(EC_KEY_get0_group(*ecdh)); + EC_POINT *point = EC_POINT_new(EC_KEY_get0_group(ecdh)); if(!point) { logger(DEBUG_ALWAYS, LOG_ERR, "EC_POINT_new() failed: %s", ERR_error_string(ERR_get_error(), NULL)); + EC_KEY_free(ecdh); return false; } - int result = EC_POINT_oct2point(EC_KEY_get0_group(*ecdh), point, pubkey, ECDH_SIZE, NULL); + int result = EC_POINT_oct2point(EC_KEY_get0_group(ecdh), point, pubkey, ECDH_SIZE, NULL); if(!result) { EC_POINT_free(point); + EC_KEY_free(ecdh); logger(DEBUG_ALWAYS, LOG_ERR, "Converting binary to EC_POINT failed: %s", ERR_error_string(ERR_get_error(), NULL)); return false; } - result = ECDH_compute_key(shared, ECDH_SIZE, point, *ecdh, NULL); + result = ECDH_compute_key(shared, ECDH_SIZE, point, ecdh, NULL); EC_POINT_free(point); - EC_KEY_free(*ecdh); - *ecdh = NULL; + EC_KEY_free(ecdh); if(!result) { logger(DEBUG_ALWAYS, LOG_ERR, "Computing Elliptic Curve Diffie-Hellman shared key failed: %s", ERR_error_string(ERR_get_error(), NULL)); @@ -89,8 +91,6 @@ bool ecdh_compute_shared(ecdh_t *ecdh, const void *pubkey, void *shared) { } void ecdh_free(ecdh_t *ecdh) { - if(*ecdh) { - EC_KEY_free(*ecdh); - *ecdh = NULL; - } + if(ecdh) + EC_KEY_free(ecdh); } diff --git a/src/openssl/ecdh.o b/src/openssl/ecdh.o new file mode 100644 index 0000000000000000000000000000000000000000..f7188b87cd26cb8d6bd6e892c3467b092e486b09 GIT binary patch literal 14752 zcmbuF4RqAimB8PBW)cPhlVC)W3T8lpxTl$9A_9s?CLbgzNJ2i4l#gMO{F6+X%*6Qs zg4!xyH9gQ}_Z+_}6-#T?wYzowsOZ{m6l`^?ty(?R?QZF=Y^%kVx(fBIcG-L1yZ1kD z-Xxx$?mNl+-~GM&?!E8x|Np<4FEy=M<+3cn$r9I!ti)7^t#h*ZI+?8#v&DrX)YUrn z$v?m35~92F9po+h##_dY7w>%x^J71f4AIH-nr!*=AQ$g_1XLtz3cd)cp<@jI){Onf z(_jti{ywXJGTpp!bIaIAp-sn&D{g^ORZl7e&#{}Qv7lw_+2Hx$_z&Eyv@v+zsap4` z^-lkA;Ls!{Pe1%;_&vRU;83W$b?go7ln=W*TgEY(6xWd-U4$EnspaYZ9`Bl}Vgq+Y(A)8EtkCBIw_LvWn^j45LnW7gjQ zq(E`SUI-uj?mM3@dKYsljt`DwUWjHpZYLw@XnfG$)ZpJ{kA{0k!+n|Lb~_x84BP&J zNHk{mU+u3)I}VI^pk)#v{qmJZ&K~ebNE#rUt5MT1Wlik&H4Q zi$zD$(LR3zM&oac4h%%?sunvI8;->Nsi8>H?#F<2r+KZ(Elf+pBbnY9m^G?$OyRh_ zW6|Y$y`iZ>cx3Cnas}rt<6c}>lw{WR`Z5sR-YE#(mRDX}O7ajaRImUq9#26uo`woi zk|x{-qEMi+2Qf?53cQ8h+flTn0cq?_&$+pvDcyMf*bAkU|KzVRtN5QVU!wB=i}^B@ zKaY7oG!YwVp|D5^mK17~;F7{JCAg(fr-TA2v?!ra3hhdmB83e~m}+%Hh+CCVWNici z`xTtdurT5gCCrpUS_!4r2$bwp!fb052)8Jq%<2MRw-U;&2w2;rgt^uYAl#;eh1QLr zc1Q`;)NQbLUs?o&cg3J)rwRtk?O;R>q?>Ks$Tl`^(*B`mdefS(g$8k7sqJ#rk% zJm0`Zs(w9+S;~JCn@i*HKri4DQRrO&tk8QHq#_(p414;1$RNexl=RC?OMxB)VTK%h zHBo3v6nei61wQx}q9FAsT#JlFMR3Z}rqhXNPueh&A*09Q=FD}gVafUg2>OWx($4%XILwPjX^>n6x< zaCsZbtRAaIlyf*Yg0>?Z1i|rpHwbqqJ5a&Fj{|;GxwUFwVOUpW>wmhjw;f}XJDdW& zhekgw!q0H*7@<;zc~=R2TIdZy{TUv}s=*8m%ax)k)H;KSR1Ic`M~}q&?cI+Im$_^+`wu**V=)VRqZ>ySgXK_7t<*bz0RFQ=2o*kbd@gX|{*yrksfG3` za67K}K7L?f1(t&82LSjXCko$oVRu)^K;|Lw)?4_1Aw%`H$=fV;b_K!;yoHPT_%XEw z=eca0`oO!%rPP+YEL=P|$7Li$Yh1lh5ht{Y4|OVzLp3e51!#NP7F4_n6>&|fV%Zwm zp;!QISP7R(EXO%mfooYQ$|_HSC>FxMDEzurp_Z~W)2j597P);F`(|1fOeulM zeODJPFKUGwi+h16D!LZRVQ?r5Ehs1k3TE(vT2o3bx38!OD_J0VXE+v?f!b6O3tCH2 zoW}OymTOt9rC4M7JkeTO4TUonLI!R-7-n%Pn7Ia)Wr@ei8lSlc=$sisTtIffEZhS< zIT2hKuvV6zHU zB6XN@j#klSU=o{lDa0uj=$tKA&a%)ADlK%%!4!t#B>8Lwk|nx1iw}gDEU}5RHz)#6 zudw2eu=FrdP~_})auiu|o+!j7Dt9itlgSAW)DrES{Q@ajqLZ`i8KULvH?vyo?k8Eq z+1DM^&e?2GomA*tmQt=UTZ^;X9JD^)-THT_^g~ChowHeY>#5MWL?{=})?(X_XOW{$ znG(9QUq)Bx6VBe@pia&nCZtA?rI)gboP8}vk)>;JAAtm8!P$C3%AzXHe&$El#nJ6@ zoNnSQyFpuBM_5|vINiiq-D%g6tUHycORr`XIm_`VMV3NN zbelP=N4G97x+P?}!ST?}**hJyp5u5qi`b*(cwEof=?-e=>gMd{38~4$Qg2q#wDnm4sub=;TH-1ilG#xR z%O&t|(6T=E&45pNP>6D3#Ez#@F;SgKC97l6-s-`=zUrOJmV}oqu8KwDnVnUG@l5sN zz_RLSyf2pNx0NOd`I^1abSg(BN2q3Zbgd2q;8mrse<;ugt4XBN{r&bpUki~4*X(Ht$WvZdfYMZz3%B=$?o-5zqouw%=_Xx zFI4K;8|qwq(p5QoRjqsEg*|)RJG`e{m8I^BcDuKI&OIyOT~pfQ!mbXtwuO5$17SPf zF9Qkp$rC3#tWK0f(oSV!X($TgVOT0HoP(i}1RT=TCi>C>PLQBbpsA!C=@0itQnm;u z1_n|#*6be&%WA8edcuQtx+XlBOk_rctPk$+04)_w#KQxLidmis+SmiK9`=`PqjJ5rt*fPV zZL?5gD#F8&vz^lgLIz!@kW!{PBK3{xyK9M6WT z6h{)UnuZd?Hmpx*arIy(ld6V8#lEUwAXuGB_K9!`I!ng2s&!41=#9d99S--UcZy6r z1p=H|_QBDmoFx=iXIH4JyA#GSTPkCbA5JZdOa(2it3C&JLy2Tsx=h6Sc?yQXMKmtL znK*>mUn|1lkx2hy(Y&_X-{6PMBM|gg4W~14d&M9g|H5Ht71-+=S^+yv)sn^jszHBM zTdlte7V-*+|EjCdb8|;qcRPg)Q?0E-$cFUWy_rFr#c_Kle4?kIx{%*1M7TbYh$(g@ z^gjfw`WaVZq;FehL`^QaaAZIcoTc)Vmi)nbSliUl1?vI&NgBxM7gGlVeF_Siy`W~xz^HC-_hC#>jRFx;|XYYV~evx$mM`lp(1pMtc#l@cC}njwQ>!@ zl2_{xRz?DL=z3VhT^mGrdpgn^vz;;GRjyecDc&Pd(?$=)3SDT z2y17Fb@B8m-a~Ltz*kIu)s~Nq^}dn=u2x^!es{>{-{Wy@ndU1C`AV96-jU57-;XZY|gnQ1_s#$yav3-RSf0_k?_l_7pVxYFx=_zC~aydY`wcC<>%O zBh5vwNG<_$CGdZY?DJWH2&6`bq2uA2PO9q==aP0T5=i5;4fIFS5fSK3r9>c^KmpZ* zfn~X35Jaq_=6p0hkbs(U{zrOyllFF&pp$bnBgsg7&_>(Y+Hg0wSs#3f0NjU$ZCK=i zcp_~FV6DRPgVjNm?4j^L626e3=Ka4fez1T;0Jr0uR7aBe?1Fu(Cp?;g2Y|e^Ouo>= zJ2w^LDGmDJCnJ0##Dr?d;dvq_9d(`uaoIDB%tZZP_g6~e6`#6d|KkA` z$It!06_{xgkXQ;Q8JG%;aWHl9eb8iB?;82_fDn%u!I`>WoTUDHa3X-IMqQjwv;HWQ z7%rr4$yKTf*T?qb-eb1^Z-JRMvF04w_--}|4N>3;)WhoR2xy^ftaCD^O?Ar_UA>DrEzKVO? zC+Ag~2YF1m-(nv!uR;h3Io>*%hY&(Sj<+=Cn-M}nj(aQfQG}3?=65 z{{@ws@&AfA+aXcBuj%Xkb57%W|M1pg+Ao0hfQkEu@6!v2qrN^~pVc_t+PL59G_LEf z*EqhXvHpn0(I@j8HGYZ4_h?*i?>98AxA$R<>*MkWaqiDU-~-dMn!Y|C{!Qb0Jf}3S z$Mden^>{wexE{|(#5ta=GMel;q&ZJY5kNA>v5Yv6<8q}YF4y$+b_F%A$G?6O&T9wl z^RoxKm`;9>WBy~Rk9!3s<};|B^f>8o{yG3-!-Q&NLduuRPh|(6n>oS3uuN?KpGf9* zGyf$$6xAF0qvWL3;LnnNyTPBLN0;jjemB|KV(?qYPR!utq<@3KSCajk4DKO5W^mp| z?lSml^80mz+vN8lgBQ}cJYn!3lHX?yzLE4_Hu!3i-!eFVHS=Ev|A^%OHuyP;pC34R z9Bat$bhZ07>w^95H4gM9fe}%#Exds#OV{E^J^sY1XPf>sJ*F>zpko*oB`s<0O z4gMzCxz*tFiGS7LqhyD_m}9^ABRNbD8v49nJYn!2r7oT`_!jD)pBmgI&if(zjS=U4 zk2(It1k*Xg4*m!albgy}KSu2;G5BecFERMXq+e-p{A~y(-rv~%2J*|__%RQYeyd@J zzq!5L;J+ikhYfx|$$VbJ_LHRln4uph`R4}bZ$kgw;76$+-!{09?Elu_yHq!bvj$&6 z{Qxf~GI5-Dko^LKHUI*@h4cA9@jYP^Yipm8b|#vj_DP^B{4*!JCLLGkApffWdDjo-+7u;euGG!E%jjidfnnxFeME@L5nNaLvg2Jzc9j`}>G zj%Xb9c^!UB>Iq`D~Ntp@i_k=dmXDlLDG0(~|IyH<|N3`HZ2@^XLBn0x3%- literal 0 HcmV?d00001 diff --git a/src/openssl/ecdsa.c b/src/openssl/ecdsa.c index e2af6f9..bca89fc 100644 --- a/src/openssl/ecdsa.c +++ b/src/openssl/ecdsa.c @@ -1,6 +1,6 @@ /* ecdsa.c -- ECDSA key handling - Copyright (C) 2011-2012 Guus Sliepen + Copyright (C) 2011-2013 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 @@ -17,22 +17,26 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#include "system.h" +#include "../system.h" #include #include -#include "logger.h" -#include "ecdsa.h" -#include "utils.h" +#define __TINC_ECDSA_INTERNAL__ +typedef EC_KEY ecdsa_t; + +#include "../logger.h" +#include "../ecdsa.h" +#include "../utils.h" +#include "../xalloc.h" // Get and set ECDSA keys // -bool ecdsa_set_base64_public_key(ecdsa_t *ecdsa, const char *p) { - *ecdsa = EC_KEY_new_by_curve_name(NID_secp521r1); - if(!*ecdsa) { +ecdsa_t *ecdsa_set_base64_public_key(const char *p) { + ecdsa_t *ecdsa = EC_KEY_new_by_curve_name(NID_secp521r1); + if(!ecdsa) { logger(DEBUG_ALWAYS, LOG_DEBUG, "EC_KEY_new_by_curve_name failed: %s", ERR_error_string(ERR_get_error(), NULL)); - return false; + return NULL; } int len = strlen(p); @@ -40,19 +44,20 @@ bool ecdsa_set_base64_public_key(ecdsa_t *ecdsa, const char *p) { const unsigned char *ppubkey = pubkey; len = b64decode(p, (char *)pubkey, len); - if(!o2i_ECPublicKey(ecdsa, &ppubkey, len)) { + if(!o2i_ECPublicKey(&ecdsa, &ppubkey, len)) { logger(DEBUG_ALWAYS, LOG_DEBUG, "o2i_ECPublicKey failed: %s", ERR_error_string(ERR_get_error(), NULL)); - return false; + EC_KEY_free(ecdsa); + return NULL; } - return true; + return ecdsa; } char *ecdsa_get_base64_public_key(ecdsa_t *ecdsa) { unsigned char *pubkey = NULL; - int len = i2o_ECPublicKey(*ecdsa, &pubkey); + int len = i2o_ECPublicKey(ecdsa, &pubkey); - char *base64 = malloc(len * 4 / 3 + 5); + char *base64 = xmalloc(len * 4 / 3 + 5); b64encode((char *)pubkey, base64, len); free(pubkey); @@ -62,41 +67,39 @@ char *ecdsa_get_base64_public_key(ecdsa_t *ecdsa) { // Read PEM ECDSA keys -bool ecdsa_read_pem_public_key(ecdsa_t *ecdsa, FILE *fp) { - *ecdsa = PEM_read_EC_PUBKEY(fp, ecdsa, NULL, NULL); +ecdsa_t *ecdsa_read_pem_public_key(FILE *fp) { + ecdsa_t *ecdsa = PEM_read_EC_PUBKEY(fp, NULL, NULL, NULL); - if(*ecdsa) - return true; + if(!ecdsa) + logger(DEBUG_ALWAYS, LOG_ERR, "Unable to read ECDSA public key: %s", ERR_error_string(ERR_get_error(), NULL)); - logger(DEBUG_ALWAYS, LOG_ERR, "Unable to read ECDSA public key: %s", ERR_error_string(ERR_get_error(), NULL)); - return false; + return ecdsa; } -bool ecdsa_read_pem_private_key(ecdsa_t *ecdsa, FILE *fp) { - *ecdsa = PEM_read_ECPrivateKey(fp, NULL, NULL, NULL); +ecdsa_t *ecdsa_read_pem_private_key(FILE *fp) { + ecdsa_t *ecdsa = PEM_read_ECPrivateKey(fp, NULL, NULL, NULL); - if(*ecdsa) - return true; + if(!ecdsa) + logger(DEBUG_ALWAYS, LOG_ERR, "Unable to read ECDSA private key: %s", ERR_error_string(ERR_get_error(), NULL)); - logger(DEBUG_ALWAYS, LOG_ERR, "Unable to read ECDSA private key: %s", ERR_error_string(ERR_get_error(), NULL)); - return false; + return ecdsa; } size_t ecdsa_size(ecdsa_t *ecdsa) { - return ECDSA_size(*ecdsa); + return ECDSA_size(ecdsa); } // TODO: standardise output format? bool ecdsa_sign(ecdsa_t *ecdsa, const void *in, size_t len, void *sig) { - unsigned int siglen = ECDSA_size(*ecdsa); + unsigned int siglen = ECDSA_size(ecdsa); unsigned char hash[SHA512_DIGEST_LENGTH]; SHA512(in, len, hash); memset(sig, 0, siglen); - if(!ECDSA_sign(0, hash, sizeof hash, sig, &siglen, *ecdsa)) { + if(!ECDSA_sign(0, hash, sizeof hash, sig, &siglen, ecdsa)) { logger(DEBUG_ALWAYS, LOG_DEBUG, "ECDSA_sign() failed: %s", ERR_error_string(ERR_get_error(), NULL)); return false; } @@ -105,12 +108,12 @@ bool ecdsa_sign(ecdsa_t *ecdsa, const void *in, size_t len, void *sig) { } bool ecdsa_verify(ecdsa_t *ecdsa, const void *in, size_t len, const void *sig) { - unsigned int siglen = ECDSA_size(*ecdsa); + unsigned int siglen = ECDSA_size(ecdsa); unsigned char hash[SHA512_DIGEST_LENGTH]; SHA512(in, len, hash); - if(!ECDSA_verify(0, hash, sizeof hash, sig, siglen, *ecdsa)) { + if(!ECDSA_verify(0, hash, sizeof hash, sig, siglen, ecdsa)) { logger(DEBUG_ALWAYS, LOG_DEBUG, "ECDSA_verify() failed: %s", ERR_error_string(ERR_get_error(), NULL)); return false; } @@ -119,12 +122,10 @@ bool ecdsa_verify(ecdsa_t *ecdsa, const void *in, size_t len, const void *sig) { } bool ecdsa_active(ecdsa_t *ecdsa) { - return *ecdsa; + return ecdsa; } void ecdsa_free(ecdsa_t *ecdsa) { - if(*ecdsa) { - EC_KEY_free(*ecdsa); - *ecdsa = NULL; - } + if(ecdsa) + EC_KEY_free(ecdsa); } diff --git a/src/openssl/ecdsa.o b/src/openssl/ecdsa.o new file mode 100644 index 0000000000000000000000000000000000000000..bbdc90564e2a66e1f33731cbdd4af36203e147c7 GIT binary patch literal 18632 zcmcIr3wTu3wcckY2?I$6NK_JejS?`ZnLLOX5H(LSkw-$3fdqtcl1v^YnZ%h1f(1oW z(Gg>z{qWLC72DpbeO+sNTd&`(jY4Z%U({Ahy?sz?Ew;T%uht5!<*v2&T4(m`ne_7Y z`|keWoVEV7_S$Q&z4ku)>@&HwVf9LfWeF~pxJD#6Muj+Bl%T66SuG00`NHpu|F+E+ z|Lb?2cL?Dd`(wdL6#DL%@WmTW#5#TPUrAuR#fi|brZ*jX`ix_|z18XKe%Uwn%yi$_ z>!*B+e-eMj7k|?i51mxi$45{4#&@0YbsuAMu`7Lh8&3H4ZvNm0N2brO77{Oi-xq&Y zQcucO<4->|1&H#A^0P`l@rM`ANzu1=*9oq1e=ij8^!Xn{lfvJIo$`&xid?>D>x*27 zNzL(`JCOd)dcWTv|8D&IPoJLumvU$<&q2H{9-fp725B3JzPzWDcKMae2^ z>}Y{6etgsBBa)pyzg~#8@*kAHT>ie2W5|xga!?04y&Kz;f;9bhg3Ru>tkC=aVh^I> zV&`4HgGXxoP4QQ1+MD9K! zGbOyqqn*v=s0^OsLZJ|Io zI27{q1_uU1JWyBP*PiOWquc%OEgIfth&A$jBTB$Do4bq=}4s20)<5aU{uFrYp;J09i{K zkP4Y)4+A3Y9?yEe7%WSr1_+Ra`%dB+;M4?$S6s z+y(Fqk>x4{EX#$1n2lqLZs+U)0#O`JiGG67d_WHZlPmK;MHUnAg3$4Yv48m$tg!2F99rR*FNiifS%cfLdfboOoBY*)CI$)lG3{HHBih) zJ|m}~2XxOvTEAKnacEbkq%-6-Q(m*=bs9W>p*RZAzVl8nc0m|84EU@O;V6{N7NCl? zAXm;2q=opgx(VwLqJ<+M#wcOA5HD5{;*R|-vj;|O0|VBT^R0DL6RXhV#$HWt?CiN1`w_GX zNricljp>9zya?0uWo$VYDK$n_m^ECs5@8*x%M#*Z2I5n5__SHA>5Qlom+c z6=<2d&g1yMYx!}+_ID)2b3lBB6t_bbz(_c@!7_>#uv`UFipxsw zHsaUe1&Vd(U8q~w3(30@DJ&{28(H1%&l<4xXp$p1{Oj=23i;uYmEn?-LoX=zK&O~> zFo&Q+Du0$F=MRkXA<$E!+01TW&4kyF!a66tZcg^Ph1G4Zw}aOK&`yN!9K9Zsl`!+q z&1>av2QC|2IdF+(+iDLx?IXTi8nB04yzA zz62?ZrBJRkTiAy}*l2)ME?^*4`5ssUq;vm0w<6pH5L`?8`H-6zh!UyNozR9dM0?F#sFh|3()J5R`N@7g;=R{WHdpT2qq3t zha8|zH0+UHz$GP?ACVR&PjfStD$RH5L4(|u#X9sIFt!+JYbOTH@{3C)w;Qim^3)CD zYrzVj;=7yUdl?A@uJ!hexE#^UM{wt&$VZWsVW09#M+vCnf4M_|l>_$$QZ{w3+%n~y=Z6J+%CA{Gf;ww9R?ZP>qKLBpW+rOY2<)Q**Q-0&X$3q_4REBbYB=>u`_~%K>OHeP@;ZQyOq!S&- z#a`CQdmL;D)uq`e!G+%Jl58pWbqg2nym3%cExF#au-OQrxO%FdN>(amx!wfhvRT)= zQWaN(w5rkp_ao@QstZWWbS04n5RwM+ej@E*46lIy!u?Arl9z;Lf|Ah|)=X=mJ3rg$p6#A#G@!0MIr2esRkH;mEe5ql0sE0 zFHn#(kSrsWAm!>)OJEItHV<;9qJB(YwM# zEe8bXLa0Xpa=;2OJ7ET;b1Fq8w1?zeO%d36@!Ktkce(8G{JU?rU}L?%7A$x`AW#6i zI2i~aE`~O_5vaQ$VG8zOb3wP&^3UqX?v&kHm?_F-i;J=Wg&e6QzL=YYrARXfZCtOmsX7O03(=v=6AfQmh=WmLSIoq?u8TbTTm z4Ye`Jwjk`L2Zu@fOLi?klfNe@y$6qz^r&62g~_*UsEtXsmBxcpr2T}bgn-9` zoI$4REWHpOPFNrtncQzf>zTZdpmVj=&bB^j+q#}f-Bx?b>`L`(9osr!+uF>eZfo5+ z*lJ~4`)pfnOzO5;Q*0fk3jb+W^fNh^-l;9o#^geR(#I>+Ry*68XWLrOq;4xUUa7X$ zv8^K8))pppTdDC%wbjbDJhrXtnbd8i#_I^h=>c$RRWwMF7tj=1KzDPkGxc8tJ%?BdSIhdVI~T6<(;D)_ zBcX6KIwh+4!(P*S}aGF_%o}N%I&=Aeoj*(ClNI2L6 zcwiVvcpU;CnG9hi*n5wJh7=KvMFzrsN^dkaFo?CmXebg<^10)$HIK))a&57-&N4RVgJS_ z$}$|z&2MyGbv5iP7kJ-%2-waCfWGX3i@v)2nu>2Z7M}mr1huNOskF$|x#`h08;`qQ zXe$Ln6|R2Q=%!`Ye${n=_)p~b9nSA`;P?fangd;Mpy2Kqv=0Q7A*0?`b> z2bMrIW)CUH7e2p$LFrQ8SqVwq6iEHBU?j} zsH`HbU{7Sf1JG4zVQFPReSgC6kSy388`#FS+goc^u57Ba{k=IvTGAjSR$xSZmy!m0 zBcTvxTVNy@jovgI=?Qdqk&`v6H`H{tY5kKOnC#0LRa(=~Uc+D4r0oDqgst2M_`U^w z4fn}$(L&XtJc5s60zbwDx`zixhr$9ITv{o%)6fM*hG8Q14-bW4YD1Vx`$k8jr7@Ve zCFS1o(rBbx1fmdW>GH~^)eT}ajGxp(J)Z9VU_^{?=0InADn+mhG6WJJp&(t87rP=R z5ayK{8L*FOg>9%&QD5eS@nw%%$Dt7K`Vr=-tQ(p=#wfo0=rSiY7mqXbWKROL3zqvlrS zpOF1lLk25O1djogQd@gXyT48Jgt|uiAOYb^=ytebV9M34Lfw{#K<)7Gpkl7T$rcLB z$)?QIHLqRUP}knnyta)Zf-_i+o1UlXgQ}(t=6C=D1gQ-^^bQ95U>uvKRzLE*y0elY0go7uUHx;2mhxLQNr7U_Iz77I`iUl6$f4xU<&nxd-d+$%LMaWi`4-99{0RI(Ko6 z+f&OX(2r`W&qtK#XFFkeXqbyPx?>1(LwI5KsCz$Ck z8B{O#Rwc9Lz+xRW=?22R!%$OBz+hKbB(#k=$cZG)U?dps3xRE=%$#NmwlyIZL(9V3 zJv=lNf~CtF9*%{)u*$%~0ken9hWZ1&5%{$Ock-XVd!QF^k?;awu^rx5;z0=(JR3utcB%-;@(B|loQ9Ymb!{a$0#=X!j{qZg)i)s0lYmCt)fXzDfto-Y2!DpiH!G#N1d zI9JU0-vF3t6Cm;BnRtbdu=a*i@un`G=$II4-hvYn%7~FzrtU4EV`5nEZTVpZ4%v{= zimAH;Wa;|<2pu_bee6FR$)@yw95B-+Kw=&yHWaR}xK!Q4AV^n#E!BV75E`twAL^&` z|2X;2^922ebL$lUacxGMrk@`9oeF+90k0=|;r99dEfA)wUwN^rMP_UhT#xS)RNq!0 zVja~tajwVsD?lJ-q?zcT`u#=)&R?#742X2`J4Nw3PKp@6eE84xIj)%I=GuW(CKljT zh+nCjeKp)k>pLnRmfy#OXd&m|AX{KtX8Z7oFm3y%ydZ$`Iio>?RZ3~DsFxxBbT*9$ z+DmW6nbs5ZFI|KYHFfk1!G|Wn zas5qa=Z;D6{eWY?PQV?D+<(ITEAT&^oo`QqADsk$aS|Nkm(Kpr07rlLU|a5S0eg26 z{VYg*)IUs9fc5dvJ)Qk4NuLjmS*Laq{WYY|3)+3)2bPXW^aGRNy_4WKlKsQ9VB$Do zxn&aly`*18i`*2YE)Ei2O}M>hmak552u80^XJwkx3E51J^PIOYDK$@c=$Ik#jw>ywV*+I--K(W`jKL>9rm}Y4qG@Y~9uzHn;pAf` z``88#DEQTo-gj9C1ga*TG$@=HC847s#mN515#;g0G(h@qXH}ucmP|i<-Z8#T)>6+| z+?p{S)bR5)9QRdN&^|spS$_;cD2U@Tjq$q>gfb2OXG%(4K1DR@<1?4_Kda%oeSX(8 z?SGB*(Z0T=d`7dQ+kZ~O3xVc#|E%G-MPqyx%m*ykF1~*=?$vPI3o%}$;rK%;#v3(! zzJ}xc$Ab1Rg8!_K^BD``dK^Bg;d-2R6V7oimbHc0uj%V?ctpc7H@MxWHC%7^IStp_ zJw`aU+d}RBTGQ9t{j-KI)Y_ee9fg879luP&F98|*xlF^cuZ;UOe6faiYq;L8Ar062 z6(OASini@yOw-r<^&c9p`~O1?*ZqH8!!OhPJf-2fpJy~&_wy{_?B^1&g#~{$iv`8H zpDQ(7&wrjfXovTrSU(3ZP!N~9D5}pp8^(*I7W^KC?u=KEf7lil9Daf%k7I-d^|>wN zX`5@e+k+sKtJKZLPm({i1|FbBnhg9Z(&s#7Kfgg+*$sw1{?;DL7Im}R-AMePfxk=n zeWQV2MD}+YxQp<(f!{{_K?A>m{Qr!B{~OtP#K6~+|KBk1Jkp;q@TUoX-oSYsJZ|7& z(tpFi`TgXSfgd6MLjylU{hCJc<8fiT+&<$}T@)Gm50O9o%LvxT-_2vW#?W7*V6n=; z-Nf_y%yxKwh7A2evL7+AXYz)h?hkCMKdep-o{|oVp4g5pWFEj9e zC4Pm0-$m{E47`Q-b^|XV{;+|+L+w6n;P(=L%)sfGO8l3Bhd7=FzK7yCljIy9eo>!e z;Jb-0Ht;`DK6?%PKC)kF;7=02+`!io&+h^3Pn2+ejxZjfc2^sAc;CS1#jKC-Ls&Wt z{ckE*Y%%axDE=HjwzH7p$m7g7uM2$Mi_MX$Y~gE~{i)O@-oB~f_`KUl{EHfn`uIML z<);RIK*8eY8jg18*j2o#;b`akr2hvEM}6LxoF<(8$2|cSUcVW~y#9QFGwhrue@| z>^u~1_eR3!8~B}sFV}EPd46ARB%I^?If~o$2L2@3>DBBYbeQm6hCYwiof?khQxwkw z20o3}ug@F!dcwbM;GZR2{RMVnAIszQjG_NF=|8LCIKDiNuM*Dj{5JLLZ3BOi@H`9{ z6xPST(81DZ;O`OMZs30>e5-+GW8gc<9|t+W z@wuP$=NkB9)ZY~bejByB*1&&6c6J!}-$?%f1Lwakc*?-}PXm8p;MdZ4oiXq)QM<)B z*ig7%Kc)Usx=5TJ1yXN@ye8%sv7(Or#T%KBA`dAbrsMSneuDTB1LytBJ_G0H{$mEt e&&Tf@I5(a_ezHG@$*Fn+=XuKK7_86p?tcO3sri2Z literal 0 HcmV?d00001 diff --git a/src/openssl/ecdsagen.c b/src/openssl/ecdsagen.c index 883c77e..31e5847 100644 --- a/src/openssl/ecdsagen.c +++ b/src/openssl/ecdsagen.c @@ -1,6 +1,6 @@ /* ecdsagen.c -- ECDSA key generation and export - Copyright (C) 2011 Guus Sliepen + Copyright (C) 2011-2013 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 @@ -17,59 +17,54 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#include "system.h" +#include "../system.h" #include #include #include -#include "ecdsagen.h" -#include "utils.h" +#define __TINC_ECDSA_INTERNAL__ +typedef EC_KEY ecdsa_t; + +#include "../ecdsagen.h" +#include "../utils.h" +#include "../xalloc.h" // Generate ECDSA key -bool ecdsa_generate(ecdsa_t *ecdsa) { - *ecdsa = EC_KEY_new_by_curve_name(NID_secp521r1); +ecdsa_t *ecdsa_generate(void) { + ecdsa_t *ecdsa = EC_KEY_new_by_curve_name(NID_secp521r1); - if(!EC_KEY_generate_key(*ecdsa)) { + if(!ecdsa || !EC_KEY_generate_key(ecdsa)) { fprintf(stderr, "Generating EC key failed: %s", ERR_error_string(ERR_get_error(), NULL)); + ecdsa_free(ecdsa); return false; } - EC_KEY_set_asn1_flag(*ecdsa, OPENSSL_EC_NAMED_CURVE); - EC_KEY_set_conv_form(*ecdsa, POINT_CONVERSION_COMPRESSED); + EC_KEY_set_asn1_flag(ecdsa, OPENSSL_EC_NAMED_CURVE); + EC_KEY_set_conv_form(ecdsa, POINT_CONVERSION_COMPRESSED); - return true; + return ecdsa; } // Write PEM ECDSA keys bool ecdsa_write_pem_public_key(ecdsa_t *ecdsa, FILE *fp) { BIO *out = BIO_new(BIO_s_file()); - BIO_set_fp(out,fp,BIO_NOCLOSE); - PEM_write_bio_EC_PUBKEY(out, *ecdsa); + if(!out) + return false; + BIO_set_fp(out, fp, BIO_NOCLOSE); + bool result = PEM_write_bio_EC_PUBKEY(out, ecdsa); BIO_free(out); - return true; + return result; } bool ecdsa_write_pem_private_key(ecdsa_t *ecdsa, FILE *fp) { BIO *out = BIO_new(BIO_s_file()); - BIO_set_fp(out,fp,BIO_NOCLOSE); - PEM_write_bio_ECPrivateKey(out, *ecdsa, NULL, NULL, 0, NULL, NULL); + if(!out) + return false; + BIO_set_fp(out, fp, BIO_NOCLOSE); + bool result = PEM_write_bio_ECPrivateKey(out, ecdsa, NULL, NULL, 0, NULL, NULL); BIO_free(out); - return true; -} - -// Convert ECDSA public key to base64 format - -char *ecdsa_get_base64_public_key(ecdsa_t *ecdsa) { - unsigned char *pubkey = NULL; - int len = i2o_ECPublicKey(*ecdsa, &pubkey); - - char *base64 = malloc(len * 4 / 3 + 5); - b64encode((char *)pubkey, base64, len); - - free(pubkey); - - return base64; + return result; } diff --git a/src/openssl/ecdsagen.o b/src/openssl/ecdsagen.o new file mode 100644 index 0000000000000000000000000000000000000000..ce7918071b82b7fa439e757a15a0f67a96b6ce15 GIT binary patch literal 17728 zcmb_j3wT@Akv>?}@*s|1N-UDtuI+>*1TK<%Z7Z=QBgsxe z!x9MT*5$p0rCXjY+Y+Eq_}JaDrKMROr4-sN6v|_}G=1>VZCMJ0LR(6^Gjrxh*JEY* zzWw%mpYNUd&zw0kbLP%H_t?HHym^DivXp6-YE*g7ph{i8AWt_D*`#KuD%JCy=R8XN z8j<$HN887r$kw!vKTZ7MquKfG<3D>0)oB4>K-e&^oc~1s_0$piz>I0XY8|N>fBZ4L zhmM+oTJ9(ep;lWy?@AO<&ApNF_qVo>f84{8dTuZzbhQ2Oe`ISyFKizF`D4356l`Ic zw+)FF|E#I}rl+W5{MYAS(7cOgD4@Un&|4LS=U6{^j&SIiaOi00na~UE<2YOU(?tu> zTv8xsZ9nv61paTQ#>{wc_KEkE5nnk!<^r@>;p6%`dHl35r)9I5bLoq!HaUV|iSEB5>RHz8}0 z0um^yzZ($J`%3W#O97)9i$9D3%=DkHLsH`(BVD2CzaU+$>AxZ!EP;zERu(c#HDeJ| zuNe<9t2E;!rb#o!#I$S1M@*MyrVz7TGbPqVVB$rZ30VEW3~Hv-LW@TorqnT?5P)G*eH^otg;| zb3`-CiFr^nXIV8c<`K=TAlr^==4|T1?U%mDWyEnIm6lE^FIU~Wic4}6cFXP z3k-P{fC`@s0ZzBYhINzvBF&sdj9)Vi#7xu73JXg{g=SV-Dgfct%qnXkFhR|%u~q}KR5NQy zLA_?qv35YuD$T4Trb#o6)}_$Xu9@|e(_QSrfn&ylBPF+34?_9TQny)$Us#nuxO)JzjG3n?UlW@46Bjbzg*&_cfIH4U^{^Wa(1YZ_=Hrb#OZ(-^&` zfejR_F5R<{7#-k1#5xL&UZfogPF+CGk{rka-tH*;sq4oD2i-XV5#-bFhX0hjBI4)3=79{$j-E01St+#jddIt4q2^L z3X$a~)ltt8p< zwHX+_0u9z8n91kA*bKv*`^2?41VTRldeZo9pi7YiJy10KKRy{kS(!;H|4SGTRXJox zew|RtE?pm`>+^K|DP7;B z>w9#?$3#~&e~ITQm=k!2alnI1#LPlZ2v9#S(jw1oAV!Pi^JBTEB>fX$<#fSyE~g8r z@cHqj=JWp)1V|F!L|PJG+*%U1MIhsYE|S3)6v+U%%z!-xEJq4@&|Jt<(~oZ`tr#cP z&jmkAHgx&?<8Upl0&4=8(D*{39a6dGA29qpHM?lq?q`6V17gZU*CM+5bk0u8pfKg^ zv?o2!gBe7ZUT?hxIC(I28kmqP1}pIOcM^ho!As5j_n#tHC(F zuzv)&H(7j9YBZ~?6c`+k3jE|@~ z9i_`!XvaeO$~tK?g-KbC`(b(t^;AWDw4K0&EXQ!uUSyd%167oth7m2NH6fjWeIDGd zkWPE*lAGh zEAFMssbFHT%BlAnwA<%DhGDQOtwm*30dLvtvPx_El!}>9xMnDC*_y!GK%@%3^%tr@ zpb`3EwU`9wilO$wXdm8CYD$&mEeiy2kOeFR!)RCqVkOKLN2-vWYV<=vwX8@Lj+i!I zMXKtcvve^KurMcEOJ?b=@?t_NFik2!lV6*Lnx^NbEk-3(+{^QvR0UR?GYdADFd>hE zip#Tu5bQB=8XQ_Z(<1Xp&#b&2*carDS5V-!78$m!tcuCSD+`i7Qjs5sD}umcK(k%0%kc*5v~z_KH#Y!T>o zv5WIlt)GQ{FUi?ejCP$v1}$}i8almJvHdKk)G{zhoskm_ECGcWCsheQ*l4>1cT05{ zk`D0*>M>*^ib4Y^Lyl+!pdO}jw}VVw%Xdp{HRRJdXqzE_%uta!Zf(7TncVFlQ$~TM zdJXvkcUfweA>F!qC+Yek55O9Y4ZJbrziXtBH^$B%=0vtJmAf5d>OH=L!-iaEY0OgF z3~7$~3OhVmSFh2vIj3uvA>FzrJNy^62i&3t4jVF(gC;GXv9m2FGRfgHK^@d~Xi!94 z&6wkYh`bzBc@!K;D9ie&tQ4+vYK?qq#7Sl{L#l2xldc;|#Oem(@w$DhR@y5YYK9WY z(S0=o$LMkkZ) z>vQ^R2hqXo{t+hwBf{nr}vL! zQ3VKV1wc4)4U9O$ES^p?fmQ(tpL9@qb+m!u4hrz zp%wlacf4P-(?9>2wVQU-`4_xQjQ?fiJS7lv+fMcO+ga6@vg3)7K_{*3NT;24qJ1`g zV}-lBZ6}>hrR_{M4X4=3jt@o?NtH=l;=ri7!PKw=i{zv;bpxZLnL0S>j@N{0Lv@*S z9Ne(s#2ZE`J2RL{XYtS`HZlrJ(cIG!vU^vCdV0Gf9UCd4DxMl1QHf+CtAe z1cfNg!Df3b1>g8IOI#?WdTbDrJo-LQ(yi^uF}dO-D4>h!Cw@D`hv z&c@h=Tf5SUG02on&VId86Vz%~J3BXrn>)xRJrbWgy;#gU!#1c#J@`C9{!!X!Q^Flv zx4$^rWDsfX-O&|>rw*Su$W}W#1Rkg)QfFE$Y zkPzs;Yyymh!$Uhm*_xZsj%U+DW*J(0BU{4cAyzCknvK&ie%7=$jvB5WR&E8QmrET+ zD>gjBX`>f;I0}ciSa)>nG0(>mnMA%Oph;u`3Q=BURbq@%7m*E-%~&A@5=lp;;#nvP zte#d>XRS_9dnCmb0unX6G29K2p`6U97yyjDw>iBUE%K#z|-I_ zi*)?Z%IwMz#}Ct()nhT-gAxG*kkwgrU*lq{^)`Jr9@*uBwCP;p;;d{XTqqr1n!1(R-BMUN$(` z7lL`<2G0QA&eFFAeOo~bLFL&LR%MSSvG^{>Dg_HlPq@wsoLtukljPbo%y8_3>e<}7 zNk_Y7OBX+7lOE=+9j>aVEBr_bDlEMdVZ{@vB)u6iE|A>#z>kjT!oa%)d>pofd)qtP z;O*&*Q3ZkB7T7@Bg*XO&bVS7)lc)Q)!+}o^QCawpMg64WuDZSwJ zs5gdnG^^?lG#X=f-} zo5jSfrFvc)%Vbn-I)x01!ww8s6zX$gqXYDk2T`JTVV8lgn*W~`1U0Z6ddurl*~GN`ynrK; z32ioTus@&F2Jw3Z+A&lP4G*u8G#@Yck&F$GCJ@gbVj`;4H9Ssp`KyF+8r1oJ9Up?R zsB<~|xSN@u4i;S;#fpEf4&eSun=U z{N|1aB!$M8&esDzDgW-`@vJ^~TgKya025|jgFgZUVq%$9J&*r_5#+mYM?DO9q4@oQ z-4H=F>+d@Lk? z!3ps63Gjm_z;8GKj?Yn{dG9;{ejniI??Jd@Ge?Hs1-g))=TCsYdIJ0xC&2%70^AEJ zi}oCYer&YQg8Mwc3)!Rh&w39jw$l9lIQgrh(1#^sxlaK)*l~gR!Srwnqi>m-B1tN-=`NUX~k-#`CV zH~8HJHN>%Y8l1}=$>Xcv;44U4>#1_#%`O~kvytEA!m(x=yxWE2tJUB;8OL|CyBbAZ z@@TV>$KT#zL;LX^VDPIDgogMj@MG}LBM1#~eAW&Abp)Xyj^7am|0aUa5XX0?!M}$f zG{jGZAA|o6L1>7(=lzgSjl1Wqf_%p&=dE|)LFhO78(p}2UOHk1IgHyB_%Y2?R>TAF zb1!$`T4OW#*ZrEuHNs}_M$Ibt9Tqj59&I&^e$NUF%Hxk|yxq*{Ih#Ay^4;j)&F|9| zfj`cR9})NmEZ-$?^Ikqr;9ui-T`2Gi*@+>6-^l#M0%uko5cm`h_PD_Ri(j#3zhnIU zCNI=&LcWdhBLd&darh^JDVd$tR_UQeqWf&ZTQ zw7_?>J(mf5l92fXpUiZHj z_*CZa5_p{TJS6Zl&GRMjn^^we1iqi+_ME`~hV{H5@Gr5Q#|8c@$I~1^nE2ena-}@K z!B_D*og(li*0V(5CZ8JwzLWW8ft&bu2>f-nXH?+kIln^Sn>aq#3H-~f=T?C~$$s4< zaKrzLz`L1$Qs8Sj&d&?{vuw{h0{@uTYcW4(CeHUWf0n=xV{w4iB=EO5{#yioGwV0| zP^14Qj>CYEAJOVnR^S6{|K$QV_2F89zrynR|Mc?DZ#T;w5%TwN{L?(n*xAJV69T`V z?SEI`=Dqx}z|H%&q(nPt^qYK}A@B=0Zu13>|A~REM&Q3?do~Ij{|g3NkHG(x^TZZ7 z{;mz%9)aUO9Aeum@UvK6|1)Mj&b@5sbwYj@+j)z?OIgp|0>6Xpe^}sVpZ6Vs1%dBkJ>S5W88qxh@>P!Kw*~&+Y|j${53*n17kDMd z;U$63VEsQA_+eg`03UD|d(LJ3GX(x9+Y@9Q(}`6BrPSF%KEdnN?84bZlHVZouzAWB zIG*)j+bi%hHLPwF_-e)<5_p*L#{}NV_)7wJ82^n6XP2nweHV^#Fz2u3@JH0xOgyJ@ zoZ%0#shPMP)U2u(@+NL;TsX$f z&rm zI$z*F;&mSo_&k=sLf{+OuiFLw8=m*;0>7Q@d{p2b_Un0phuEGE1m4YhDl4>MCJt9| z+?EKulkMbbs6H4PHLy7SM$KJUTiFl1x$z(lf`*tIZ$c27!4DD#f3VGWgCAr5e*o7H BXJG&U literal 0 HcmV?d00001 diff --git a/src/openssl/prf.c b/src/openssl/prf.c index b37efdf..4f5a52b 100644 --- a/src/openssl/prf.c +++ b/src/openssl/prf.c @@ -1,6 +1,6 @@ /* prf.c -- Pseudo-Random Function for key material generation - Copyright (C) 2011-2012 Guus Sliepen + Copyright (C) 2011-2013 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 @@ -17,27 +17,30 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#include "system.h" +#include "../system.h" #include #include "digest.h" -#include "prf.h" +#include "../digest.h" +#include "../prf.h" /* Generate key material from a master secret and a seed, based on RFC 4346 section 5. We use SHA512 instead of MD5 and SHA1. */ static bool prf_xor(int nid, const char *secret, size_t secretlen, char *seed, size_t seedlen, char *out, ssize_t outlen) { - digest_t digest; + digest_t *digest = digest_open_by_nid(nid, -1); - if(!digest_open_by_nid(&digest, nid, -1)) + if(!digest) return false; - if(!digest_set_key(&digest, secret, secretlen)) + if(!digest_set_key(digest, secret, secretlen)) { + digest_close(digest); return false; + } - size_t len = digest_length(&digest); + size_t len = digest_length(digest); /* Data is what the "inner" HMAC function processes. It consists of the previous HMAC result plus the seed. @@ -51,10 +54,16 @@ static bool prf_xor(int nid, const char *secret, size_t secretlen, char *seed, s while(outlen > 0) { /* Inner HMAC */ - digest_create(&digest, data, len + seedlen, data); + if(!digest_create(digest, data, len + seedlen, data)) { + digest_close(digest); + return false; + } /* Outer HMAC */ - digest_create(&digest, data, len + seedlen, hash); + if(!digest_create(digest, data, len + seedlen, hash)) { + digest_close(digest); + return false; + } /* XOR the results of the outer HMAC into the out buffer */ for(int i = 0; i < len && i < outlen; i++) @@ -63,7 +72,7 @@ static bool prf_xor(int nid, const char *secret, size_t secretlen, char *seed, s outlen -= len; } - digest_close(&digest); + digest_close(digest); return true; } diff --git a/src/openssl/prf.o b/src/openssl/prf.o new file mode 100644 index 0000000000000000000000000000000000000000..10ca7c76131ea3edc91ce05c3495378afddcd4a5 GIT binary patch literal 12576 zcmbtad2p21k$>NOI!5T0z(^csgfU0~jU*y-8L%WQmJBQk7#Bw$>ZFd}J$jVwbPfIyT$=UiZwW zC#lMneO3Ct?q46TyI;TW8VxtMtallP;9-chBF!->#Ea!=xpZuZ)&h3qD{^Un>pKNVOzU7Ttnc8c zKl!ttH(wNm2M}mUzR{BW#FxAzr3Xe2H(x9~a7haO>QBC=Y?3edjx>+ff!bxCG3HA) zzv$aPTIk#V$M=0zKlLTw@h9I@ibvWgp#gt${Nxke8# zeTvC9FyaBl6iX(qm{MZ^BtwdsX{-n4ZpD-tZNThPOt}#PZ~GN9*SHgy!-`pGd;`=T zP)v<60?dPosg=xe#negWlwy`j=B#4AYE*;G1;tz^V;fb>a$_IN^HVVmar&Rz*L9^L8ux`$+dG`g|?u4^S?5Jr3~~f>6|E=NPzC<+5bw8q07yDJIXT z1A$vH`G(9vF$Hpw%M?>&G=hysF(n43R7uku$OWbdr-ArjVb08EKFfUr0`4UM@E;*VKJ6ai9JApWH(EWr6fp!rD~p2z5#5fgHRZr1#r;@ifu7W=xaiK@4F+S(6tk1t6*XoZLQt}sQ|#=4Xpb;9W9U5i24Z~YRj9@sgpJLZ z1rA~{4jjZ{+&DDpT$$D8DWq55579Y?vGoy{aNaS1Pq;j)^@ib?&QCQXT2&naJ6wH{kCbdubRzM`Q}|cVd*&&; zYbo+6Bo`x^GY7W`u7kR0bRwuE71-Ta{Ss7hT;P;=0XB00#dv^S(+j73+&W9p#|Zpk z{Y#KgzA?nK5bLOf^3o}V%JV#&7)zv0EVYH)LpfJV8Emm)o0{py+GvVt_3;V2Z@BTWEKJnG2;ofvP%uKAU79{3}D^)DGw_^Er-}l ze<`xl*gq89F#M%xkyj!7r8OYTUkC);vKK_ z!VGQ|GR`pF3*jJ(Y91NVjLeh<^fWN33}@Cmm@;6<5nS7H;hA<8Mkd5;uW>`U5}{M9 zRYTdgo60e;Icaw;sNdZ5RLEXE*QhJqVzkff$lWeOnU^W*O2I~WkU*7+ToA+luP6Q* zB>YmeAQx7sBpau>Ho4CLrcM@Y;XV5d;VL`YR3^kC7QkMp7xfSxI<1l=1-q}L6TG1u z>$h0uk}A+@nZyzWVsiDMg%egg_0TXiiit8rJCpcmio+1MGs#!<4Dq4SeoToc9%m6` zh&Co4NGah$rLU@#;mu5Lr1uh2z=ew$_GXHs$A>3|q>#Flvn@kDgPFePG22g!q;~8HI(wTl}Yvq3&Nz+{q_m&my!>5V2G5jIw~Ug zY9W$+0YrAG6Fd4^%F3E(Wu?@KU@NXG)_5u%UdJ!LsO+8l$q-+%wb+oG`b+os1`3|b zV~AEJ*QW}zV`5=;=t=W>z)f8aaKvPKUA9hiv{iS+xqp`gE|CyS|1gE^5lpjpm$*~t z?h(@muUy)0&m?wxbTjcWAyrfsm#Cf4oQFy0UOJm%VE7m_JYklA=Z(5K$Mj&c#nB7H zDA1?=9s%sY6tUq6))Le$@gA+7P4OuqJ$PHB5k+wu^^<_xX(i>XhpgMTf}TtKFTjTJ zSwTJ=STvCJ~F)go2$lyGJQyIt9@N{&p@p|DkG}`0sf=j=M#k;%h9&aDkCcbyTjsa;30Z|1b zK*AdkXfPRps4dU}0o)DkK_a??y>=`PAoxqs@I(U-5~|`rnZFdq*s8%L`&w4Dn5`Xe zue!k>bpMN4x!UYleR$(Gcg6KLnd-jUXP^4>@6${>B3wXc4_oD7V zJRq8HX|*=pXsv7OkYww|=IxR}=dr+`Exkj1tf5F$#QGx9xCcLTp&tuQw%sjhEEWVo z0f6nEXfSSD1M#S^dP0HTnCQ3ry9V|O4!ScCv#C5*SJV!~ZDEH8t^RJSD?Vh!AdCJ$ zbeA2CNefWumXWA}S`dD3ypJtFyZNRK{+pU19`GfT!+BH;<7Ns)VA@b5-0P8tL^u}g z4cpx^C(DXaS{BwysbR7-Db&`&_gSke5w*G^p+tXJK)kY~)<7i2dT~+H7wNa5pCSC3 z-b5l+6NhfCuJhK_#G+loiovSMwATAunnfyxuD(E2bcO6dI58ml0x`_5HyE~|z%oWD zSH-su815bf$)1ADT1S-q#a*HgWDsizut!W!6_D_2rm zr1D6YO!Nf9fe@vEiz-tHhJ$h3E-GGL?yx-si;l6>sS`!^Rbe$nA|Zucr}`(*wJR}T zITsdpv(>rR!tV(E0VtyE59u2_e&S+dO{Fu{Byta7|1PVCwzhhL;2|Os1F%P+nkWDm z7F+Hayat3tR|MKwH5@j#+<9_!mI}v0^he-=h07sZScWWnJQ@-M5S|pteI`YGQBoJA zaTQJZz&(Zg4!1BYIHd|P;b((%YvU@QjokKeAvUaAx5`s_qum({gw--vuc%Ul`W%DT z<~z0sW2nfOotN!?04`s6mzV>8IOLt7v7qRXYh8X;)BR@ieHmXH$-Fmf{r+sT)|dts zjk&@b+uIKpA2`RO>fFav)D8u_aa?4tETXqF7872HcH5naUMm>xiGWPffzHmTJ;)rS zFitZN4TRwu%VOpnzTm!Lvls#p-mXZ0zYP`fh9hy?3%w5Q3tdER?LMm~8tAuGrvLw= z2V6k;guLoI+%*ub-(`y&I!MljKe*RS7-JO*dY>ft84c&*dw3b)`1Xl7+`7h%hY_4) z=rFE3`us=jmw~PB6Q||*$Kd7OIdoloEto9-7w0RhzvZhl<`1{t3Hdhxru#&TD7;+b z@TP9Wiq~~p0oF0pJWlgY!$}=O*WC#+9YgigC3u97-0GA%>bhSC$z=JDk|En;{#Z(V z{UdP!Y5oRe97EUL2QnQ)^;z&%jiXHyYOKKTT9d{9J_XKwit*>cpC12xfT2&$ z6G%D2XaJ*HbI$Yg8Q&Bpvwwspo-4hi4{XQh6J(#(P}BtuTobSz!#@B5F|Ex6+xu9N z&YVBP=YY^slp;61FLM}Jj$-&@d&Uvd_pWqME|21QbxIxe_$P}Um3{M+3I3jiV+Q=; zuQvMp*prjZKTrVz7~SfWI_mSM1R8;Q8RCO08Z23J(vHPACW{2|$tsMvwz+9CQ~mfc zVQMp#{dke7ezh780%r=k2x$^i?gR~#`ta>?l3}VJvL;AO*%1?9m{2r@*&Ofzyi{{uo0~VDzZ&d>quC-p9W|&|3+C z^diEXd|8001-v54fo+fZ{~iD90>&Bz%YBY}j&Zzx<3N3^8RNSVgn>9-N*R9`K^VIK zGYXbC?seAxy#vQR$oP9x;MdUxL;v{m8SCR)ISw7?=N9}moN3gQv9t7 zPT{YUAM86Etp7jchd+cd9#v{0L}$i#l0L6H<3aMzc`)8ecvAConD_@YoY(I$4S$C6 zI;G*yQ9R$*@RP)kYWQC$o>w&d9pc9{{50vmso`^J-uE?}zvz9g;Z5Xc8rgAuo+Z7R z8cwiSpy59wKm2`+{d`RIS*z*qAV>Utmi1pFyhGDpPJV0+zm?{VYWTMZAJ%Z*SNCf8 z5b+ObIN#@=)bNEA&odg%*Y!~iKT3JMs^PyOKbJN9GU4xN`0Ip!q~RL~S3j($_t9Sn zFQ7Bm8UG6e$7~H>OMI1v&!<~>t%kGxY7NJKWWeFm@Cy`on}+jxJgVWJk^UJCpHA_d z({TPu`b!Pxxc{KxF7p4DhMUBHpy3Zw-9Fdw1LP-%E37?_i7s$Rs!#jzu*6_zj zf2D>G6W^@izoU6?*6=mN@6hl?YPkeoFFAfU&708l`9AT_8a|)+5e>gUJlBu?H`BaN zX!^e<{G5h=hvK=Y;crmBuV^^e{|_3zoA|die3bYPHJsPQpuXey`F@tC;rMS^IEpnq zkK&x8;ZKpij~TVv!}b3}!}-2>MZ<5SMNt0)tnOdv z=WfD_k%58hj^qyspQYg+5qlRBi`>U03uG_~j z2aceoe+%hHH2p@UF7DHCi|}(Ao*?`s4S$sI_cWY;$DBzY5;)Gwq~E0B9}phaaK6tT z(s2G>b)0ZsuRAE;r!@T6gg>qM;ePwVp^tsLm+GHGi^|u5eDX70!!t?WtKmUR9L6RM z|46~2U&D`(pL;a?Y0^Kb;Xfh#Wes0K^HTfEex^&Ev?wAwUKe6THreU8hZL~wsr4oD Ef5UQCga7~l literal 0 HcmV?d00001 diff --git a/src/openssl/rsa.c b/src/openssl/rsa.c index 1b5ce56..20bfb65 100644 --- a/src/openssl/rsa.c +++ b/src/openssl/rsa.c @@ -1,6 +1,6 @@ /* rsa.c -- RSA key handling - Copyright (C) 2007-2012 Guus Sliepen + Copyright (C) 2007-2013 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 @@ -17,69 +17,74 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#include "system.h" +#include "../system.h" #include #include -#include "logger.h" -#include "rsa.h" +#define __TINC_RSA_INTERNAL__ +typedef RSA rsa_t; + +#include "../logger.h" +#include "../rsa.h" // Set RSA keys -bool rsa_set_hex_public_key(rsa_t *rsa, char *n, char *e) { - *rsa = RSA_new(); - if(BN_hex2bn(&(*rsa)->n, n) != strlen(n)) +rsa_t *rsa_set_hex_public_key(char *n, char *e) { + rsa_t *rsa = RSA_new(); + if(!rsa) + return NULL; + + if(BN_hex2bn(&rsa->n, n) != strlen(n) || BN_hex2bn(&rsa->e, e) != strlen(e)) { + RSA_free(rsa); return false; - if(BN_hex2bn(&(*rsa)->e, e) != strlen(e)) - return false; - return true; + } + + return rsa; } -bool rsa_set_hex_private_key(rsa_t *rsa, char *n, char *e, char *d) { - *rsa = RSA_new(); - if(BN_hex2bn(&(*rsa)->n, n) != strlen(n)) +rsa_t *rsa_set_hex_private_key(char *n, char *e, char *d) { + rsa_t *rsa = RSA_new(); + if(!rsa) + return NULL; + + if(BN_hex2bn(&rsa->n, n) != strlen(n) || BN_hex2bn(&rsa->e, e) != strlen(e) || BN_hex2bn(&rsa->d, d) != strlen(d)) { + RSA_free(rsa); return false; - if(BN_hex2bn(&(*rsa)->e, e) != strlen(e)) - return false; - if(BN_hex2bn(&(*rsa)->d, d) != strlen(d)) - return false; - return true; + } + + return rsa; } // Read PEM RSA keys -bool rsa_read_pem_public_key(rsa_t *rsa, FILE *fp) { - *rsa = PEM_read_RSAPublicKey(fp, rsa, NULL, NULL); +rsa_t *rsa_read_pem_public_key(FILE *fp) { + rsa_t *rsa = PEM_read_RSAPublicKey(fp, NULL, NULL, NULL); - if(*rsa) - return true; + if(!rsa) + rsa = PEM_read_RSA_PUBKEY(fp, NULL, NULL, NULL); - *rsa = PEM_read_RSA_PUBKEY(fp, rsa, NULL, NULL); + if(!rsa) + logger(DEBUG_ALWAYS, LOG_ERR, "Unable to read RSA public key: %s", ERR_error_string(ERR_get_error(), NULL)); - if(*rsa) - return true; - - logger(DEBUG_ALWAYS, LOG_ERR, "Unable to read RSA public key: %s", ERR_error_string(ERR_get_error(), NULL)); - return false; + return rsa; } -bool rsa_read_pem_private_key(rsa_t *rsa, FILE *fp) { - *rsa = PEM_read_RSAPrivateKey(fp, NULL, NULL, NULL); +rsa_t *rsa_read_pem_private_key(FILE *fp) { + rsa_t *rsa = PEM_read_RSAPrivateKey(fp, NULL, NULL, NULL); - if(*rsa) - return true; + if(!rsa) + logger(DEBUG_ALWAYS, LOG_ERR, "Unable to read RSA private key: %s", ERR_error_string(ERR_get_error(), NULL)); - logger(DEBUG_ALWAYS, LOG_ERR, "Unable to read RSA private key: %s", ERR_error_string(ERR_get_error(), NULL)); - return false; + return rsa; } size_t rsa_size(rsa_t *rsa) { - return RSA_size(*rsa); + return RSA_size(rsa); } bool rsa_public_encrypt(rsa_t *rsa, void *in, size_t len, void *out) { - if(RSA_public_encrypt(len, in, out, *rsa, RSA_NO_PADDING) == len) + if(RSA_public_encrypt(len, in, out, rsa, RSA_NO_PADDING) == len) return true; logger(DEBUG_ALWAYS, LOG_ERR, "Unable to perform RSA encryption: %s", ERR_error_string(ERR_get_error(), NULL)); @@ -87,7 +92,7 @@ bool rsa_public_encrypt(rsa_t *rsa, void *in, size_t len, void *out) { } bool rsa_private_decrypt(rsa_t *rsa, void *in, size_t len, void *out) { - if(RSA_private_decrypt(len, in, out, *rsa, RSA_NO_PADDING) == len) + if(RSA_private_decrypt(len, in, out, rsa, RSA_NO_PADDING) == len) return true; logger(DEBUG_ALWAYS, LOG_ERR, "Unable to perform RSA decryption: %s", ERR_error_string(ERR_get_error(), NULL)); @@ -95,12 +100,10 @@ bool rsa_private_decrypt(rsa_t *rsa, void *in, size_t len, void *out) { } bool rsa_active(rsa_t *rsa) { - return *rsa; + return rsa; } void rsa_free(rsa_t *rsa) { - if(*rsa) { - RSA_free(*rsa); - *rsa = NULL; - } + if(rsa) + RSA_free(rsa); } diff --git a/src/openssl/rsa.o b/src/openssl/rsa.o new file mode 100644 index 0000000000000000000000000000000000000000..9a12d0c988a3f11b7560ff5016960b03db2dfaad GIT binary patch literal 19616 zcmb_j3v`s#wLbq$GWbf2uNNqAt4EQAXH_@<4-b>%nUOV2-N!E zRimQV)=FCxZmm^X?X}mo($@B-_0{&`TD@W|t=jjhc-w1jwR-#Ta`!%G?|;smOuAU> z_NrPj0*8~X_{Uo$yMTf5fIg#)g29^?{5dO`LWZ>+wd`o?F9X4iqq(Vr_bfLD#VJ)&ytcQ5z#^_3UR-Y27~-q0}m ziXN2GQUUG$2LY}A2LW9QeU(k4?@_St>%saVSQSq7=4bj2ahx0@fHHoF^R1%Ut3+qj z_p4s2dM{hLrs9~TwP(`fVevm`;~0KLGHB%mNqs{mee^ru_5x8gR&`bhr_H79wJU>~ zwbW$v2~pmPR?f{bD)gy&apxSp9e$=gG{XuB-FFb8MKRkhD6}tMTsRifc z0}==^iGQ}e(EhVU_l;rjs$PIk6}*WfSL1o-8Ki~ijCOSoI>A&dm~gs!gKh2A!T50Z zV5BFw&DpgqI6tYxvdSeQJGxR%reNA$+)4Ds5<}9Y6YWXtil-v6D4WbK*Xv}+H5Chy zBLlGIS{=7wU-D3RaFV3w<)uJ+?MaAxEnA*EipwF;r@&l1<>cf>qA5_2oHXIRD*_#g zJcuM&%e8&>eaKqUfE387d;}0__jK-irGQC~x$k!aO!VLHK~mu#AYH8J|3$h)(Pxnk z=D|Va3JaN1#aNQ5RE$S5OBLgl%qqp?N+zTjpJZAUGf6TV6_aOefe^PSroie0W@P!yzZ*241ER=1fXaUWQ0%jDT4jhqU(HO|Ii^I1hlH;VRaA(+`ja53LiDXhT$PG1 zg!EK7Bwxc9L8e5&0b*Q>3qX>S5>;UGJVZ_vS92$Pq(lKt&f7OVlfRiGcoC|2GEdce>Cs55G?a4@vdHxx4#>eWlHl7 zM37YUM_0mGr9E%-U9eL!B`WgnKnuYsj>x+csnRK6;Vz^qr^H3xL8O*W*)H<#MrxI^ zbPv)YMIS=CRnhk%y;0F0F98o*6#WT|D6Z)HkWMN3@W()YMA4r@`c_4M8tK~={UFxX zAw?f;fb(HRA4B>WCGuc9j2?7wop;*cSjk+6m2xmDrG--66WMeo2u-=gT7(Z&G9|HS~r ztX1N-E(Tr}MsfZuYb`K=GCd zKKof)_L{OV01j{4Lb@+6;8O*VY7}Ps;q2aE3+a{{2LA`2{CKXLAH$9*l+-L>sPymV*HnppI=BnxO}quk+$<@ z%9}N;cy*7U&{BzFp=fso#{JLb7(iaRl$=;fSW~R|{y>4(KhrkqJzmTBxH#j znCu}4&37DSZg*OcN%pJ+nM=oU1F5(tdG89GT##_KL@Sdwl8`0Z+2hVM#J2aiP%D#Z zckR^ao(>W9u&dR{38iCG2VO!o6mE#ZeY@{neRBt+(l_Y zCfT#fDs$;L#$|PU9P2rbLf8CeCfPHZU+=~-H!a8{dsc$XrQ_Ia=HoE}zD{SDT_%05 z`F18b4v=DUW?G8fUFt%uOr|3kH{q2eUF&LfGTG@u8<^ZckeYDjK9?3`^5G0YbJ%OC zx7}52WwOJC+L;`3p;jhSF4WHCZWn50@*x*$XOiQB6q-RjLDJuJwK|#nD?w`5rs8+0 z_hnbHmC3)jP&<=sD@z3GWeZ%^;OdPHwlpS-3CbP;_s&f#GI@y$wJ~|)IoV=q*!Y;# z6+4cq7}G}%VwUT1J(D-MP&<>lt@RVy3c8AIOmZ-mSkI(xt8JXEEo39%+UjI-hYPha z`8Yw@6V0|*8j{1Lt~fq9tT^O)T+ifVF4WGXZfksU*jC(CY-5sxf#fi$+ZvyoF|zS} z*H$N!KOjhDg1MK{g6XMO6y6D{Ubu798mnlKB%gxC;Sra?(X#&LFNCA~NQ`_e?nINx zK~XWBOjHa;x-0s7dMZYiUKze}N!ef|Iy_R=A04h(Qoghz673lr?sb$TG2BdKJD zNCs2E?&w@mUM>VYiIn%i5){c)Z?Dr=E?UuxXcP%$^S!ddbC>#q0A4^(_ervv@R0-HQIQQ>f` zuP>Yub@er!Yr?Hr}GP2tNGZh1|AqVE#NhB-!hli6DDVWK!s`9FeWTHoelLN6ts(ZLkM79sb1$-fm z_Cl6KPYk$7G?J2jp+DT+m2||K=FVVk5Ne~mDp)p@8jd-CRac?U469}j79r{@-Q4tM*5>pZxBCGs!`UqG&k4Rb~Lm!w~PAb zH4V-60={yD)hF99eP+e73B%`G@TgfsBV-S9kdQ)MJ*mhJN7OWjYdbbdB(6T{hUrVJ z2=_(cMMX@s)~{1pMR%>8HI4O~(wTOmy%_?n@(XgKvrD;0&lu8BtT*h8#KGoZSAWt? z7;4Lsg~6M`;5Q5eB2%L?4uBa)2_wNZ?dB0?NM%4~wX{ zV6n8csVW%m#tI<3y6L*=P3>+6RGB+pB(bg@a)Nony-5nf+=K@pOI%M-jxt7-8k}-W zP1M-l*U0VYTR}au8GA4(={R232q_%FdDgy2q?iM z{ER`3F(taeUUkq}f_s+gRU$HI45PYZ_qxStqCpWJTffF?I=@ z0GPN?OP!nxS>|$2y>bcWzh^iR?uiW!52@mkgOhukTWUCqDwy`#>b6bcj!;AMns&A9 zU{-MTL8;+svGkzo9r-I%{$O##3c?GE2oFbL>jimbu(?GV6Jbb6ZDZ!R9GuDCO=tMj6n;$C$*L+S+Bo(mJO*(iK$~hO(s#6@gb&ey+E6w+U;c*qS+c zl6?p+{7ukzAqqf~kIXgx;)9+Vf5~0mI)Cs$PMyDWZ*HBx($kdhFRk_mtNkS)QRBB) z7a&rrA$9N)N!lBf*67m=NZ;+L_m>>>*7$>Wp}hlWZ?DheD2w1rS*$H+G?3K=q7rO9 zP4?vXjB0=J0nb{0$zF_aeZIe>&R<;Zw;Ky?VN#CgZPJn72|#DB=em5q9V&?UZJCQ= z7(2FNJb;M?!0|0iDdFo7mwKK?=#qVP6ZD~tEz}3^KV`#w^HZDrhD^99PwpCm)e7fS zLY)VgN;rdEk#ii<@1VjwE3udBN|;p|`zH+o&N zE72A0hn-5t;10uKc`z=@;Z|eFflFz5G?sG8VTHp@15`OFIRoLo1YTMGIV}igFlF*~ zPcylSX!Cwr&XXpGuZ-aSaa?O%te_FNd&P$HfPVOH9p@Muz5qp>#1NA0JQE5_&JVxz?jxWze@V8M#4Q!7ashm#L~=J@vlX4*uRl8f*t1iw{L+;~~|jGNW}6Xc)sjQ%IX zpXvV|z|cR(38ZYNW~=k##=_!Q`TS`R%cg%TE(~atM#aF9_4xddhPgsOJV5$7hBWIj zeu6NgOvEwLzui#a@w5JuKxCW0?@|6vlOX1A3jDD?=M^zpDkP~+rKRfp-3)Ym{1~1Y zJF3LtsTv#aKhuDQ4^HF!!^gj@{?FjX0Ik;;zriY@EJu{f5q~_Jr3?IJx8ltj3C5Q# z!-&J=uRHooC9nDsRVE0WSN-5J3yv#ceDezUpq8b1-LLMMonBcHnHX|j zIa8T9UeC|d^0tqR#v=}R zHv0!Az;XR&lYevq9N*YylOF>d62W9%v0?G{jMc@k#`tA&zs! zcr}91O!+1SkCPwN@Bq+k=d&8F$MZD}*W>w)hU@XXq~W^!>l&`hzop^2JgygP=6I(< z-7>Dnze>aL7K_KVRm0)yx{L4BaJ*)+{B0UOUBeF$j`vFX)!}|keugG5|BD59j31vr z+5UfO^19zwHC*@m3&Ss6zQrFkdEIX=I)sKN+{4-L#Tp*e@GCT2kLOwq*W;-pob%8M zwyVn#8+O# z@j0KbM_7~C82>umGT?m=HpW{Nt9~5|G)@nNAbaF5j(|dW{NqNqQ?8v5bzDPdw!e>z z)fo6Dil@QAUnO~-AGT9Z_;rT-VydUj2L4mRdEa0={Ec|KAy2Hh$-p~k(Tp1SA-YLD zY~b(ExcE7d{YGg5@j8x;@t={MuPE5XzfSRw8943**iNdGE6?lyw1ID>_ocnz(*+lMgyNldERK?SEz7= zW8lmu416)gbBlrV7xTLed^5%KDFgok#q)UsAEJ1kG;sVOJ~qx1=acur7Y+HtbVj;DzLOyMb5HI=aQc`ByJ@7`Xah7$NR4@TlYw)b{3y%$e2eTCP`(*oPWfDG;2$Br+rWp3j~e*H#P2rnHz>Xn2A)Iw zvj+YG@jo>1ofPM529Ez>i0zDlUqt-72JYsE>VosIkmM#C_*I0L7|d$z-Mzt50wrFae*crD>a4E%9g zM~@o#jU@jS1HVH}ml!kf%PG#22F~+!+Q9cw{(0T=xV}YlZyWM&QJjA_@EL^XQM_zN z-mpQeQw{u0^2^s%mggV-%roTMXkJzrIQ}y%wnhU#N%3qn@Fel~8hAD3?EwQ{P51^| z`QbQ!Lh;{f-~*(8r-3gd{C)#}h4T1-f%lN#hYXyb>y8_EBgy}(fuE!}ziQybifd_UnY8@Pw^@H4`3nrI4Tf$Pc`RAl(4E(E9=YKZv6_nH*bO?>}_8j4PgmZpAuf)Xp2L27gml*hSgf|)ZD}-+~ z@Lv+X$H4zY_%Q?L`}-3HUP9x2k#IcWbLBy*&mSA|{J!&jO&;^PhVt)2WoX!q_|t^r ze^y}Q{M3=(MFt)ve3OBHnD9OW-%t2Q4E!^MAJ%YMLNboyg!6bmLF?#AO&+I~->06^ zUMEE{U9>;Zx;vY5S`Imr4HF+Fj871|&AZIl$2ED(4`0`wGVo!l&*u&NON9T(!0|t@vHg^A&cjafJDEP!Fg{B7bOZl5;gtq{ zobW~s$Ncd7t__59ey*iFY|-S=1i$a!Z^(a(?B8j~j}iWuCXabrO)ts5Y{>IZiC@s< zv2OXj;Y$V{pt^e9!2g~0u{RC;uY~8|$33H104-r3R;C!8W*T8u{*Wb@e`{acGdxib-J{F=l8RzxeYv5eZ JBL>cO`+qFuU}pdT literal 0 HcmV?d00001 diff --git a/src/openssl/rsagen.c b/src/openssl/rsagen.c index 0f4a4fa..3a8c8ad 100644 --- a/src/openssl/rsagen.c +++ b/src/openssl/rsagen.c @@ -1,6 +1,6 @@ /* rsagen.c -- RSA key generation and export - Copyright (C) 2008 Guus Sliepen + Copyright (C) 2008-2013 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 @@ -17,13 +17,16 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#include "system.h" +#include "../system.h" #include #include -#include "logger.h" -#include "rsagen.h" +#define __TINC_RSA_INTERNAL__ +typedef RSA rsa_t; + +#include "../logger.h" +#include "../rsagen.h" /* This function prettyprints the key generation process */ @@ -63,21 +66,16 @@ static void indicator(int a, int b, void *p) { // Generate RSA key -bool rsa_generate(rsa_t *rsa, size_t bits, unsigned long exponent) { - *rsa = RSA_generate_key(bits, exponent, indicator, NULL); - - return *rsa; +rsa_t *rsa_generate(size_t bits, unsigned long exponent) { + return RSA_generate_key(bits, exponent, indicator, NULL); } // Write PEM RSA keys bool rsa_write_pem_public_key(rsa_t *rsa, FILE *fp) { - PEM_write_RSAPublicKey(fp, *rsa); - - return true; + return PEM_write_RSAPublicKey(fp, rsa); } bool rsa_write_pem_private_key(rsa_t *rsa, FILE *fp) { - PEM_write_RSAPrivateKey(fp, *rsa, NULL, NULL, 0, NULL, NULL); - return true; + return PEM_write_RSAPrivateKey(fp, rsa, NULL, NULL, 0, NULL, NULL); } diff --git a/src/openssl/rsagen.o b/src/openssl/rsagen.o new file mode 100644 index 0000000000000000000000000000000000000000..4d1c766aa628bf7eb24c2751149a93ee6eb214ee GIT binary patch literal 18496 zcmbVT37AyXmAg|f60yPIN52L+q%F6ah&0jd#WVo}TM?vm=NqLv2K zQDjjG5Q!@;2}CE6L`-zDXfz9cBt$=*#3d#s88b=7L^C0Y#))KNlsV_#b6&l=-OM*% z?)UY3=lu8FbIv{I+Np4h462y5bJ7% z7=x0+l))Vl;h7G^g>tSRHN(|yjzz|8nDXXQ+!z8q3M|9hm@#FER2~LMPO5MpOhAVs z4j9G%%g#mtCi?HUBB}8Ak*-nn2T0c``W({! za=3^xVIWhl7(+4(6yuUivtrzmX;Dm>WI7b%kxZ{*#!69-~v9bc?s^49NQBBl_~<}A5%a}ar3Px3M%?-q{k@w&wqitGG(4k0A53S zdQp#3xxPqlD3TkCWT;5?70FFS^710Nxkz47B(E%zA1jg{FOpXk$uPRFJj>36ZDBmH zqON>}u@x9!T$HyM@8RTp`E*8Q~6vk6hYRw@y`4I4!HI>QIB>FXBdU6SRZMlp*dqrz0NSTf^O&k_T-QWd6(rN+0s7;JQ+ zqS^QrFn+}>Gu{QJUNM(Q1q&2&sWEAs5Y38NE}0g^tT2{APlsYIle6ii09^N1p26{o z`;2E`t5s5;HdiSW*(BxY*EZ{*)yn^FUW9Y6!S$XwnH%wOR-&wIU$+7ig`rZxkXIe zuyLgrd+=qLja;F}y*IuDL~SM#7v6nX)@p@%Z%QC3SE%>qFTfG3HURH_oNrxiN_ao9 z6+HLXTEcq(srp*ba1f~lwHe_(gj93wHsSpwQY}i;tw?t$`Y_VHivASRn-zWg190D> z=sVD(jH2&EI?}PjfMc;$;E=Avq^eu}14DND=6@B!pFoPqCK8Ex$O7fxCVD>T+ z8E@ZhAfRL}$BmZg&G&*%io}&jQzWiJTAiBS2-1EvHvU7P>lJOe!PWvr57q(Qtmp*N zEsDMx=S4Buiaz%$JhvWXHY{DGA7RFI#+}S#b_3%vcfz$2U62W? zH(!1cfZAM2n6JqE)FzoUYjJZie~i{tdd#07txhWQ)f@~|sWN|xxL<|O{Mq%;F$Dl& z{*&=0&@z;hOmm#;9XQITX7X8KR=O}Na&Bgo%LE4%T`gr4UE}&6kXLlA>zqxGca_0< zQMk|Lwdo12TAQBenrzdPTr+HXvg<;du5(>v(^FhcHa*p~#HOdYF0tw9u9Y@D!?oI` zXS%w8o|?1r!kq2!{{jbnp=%?^K>Xi_TJV?{bdNbt(s-IfUgUMJyxuCW_sZ+%W` zJuRq`tS1khP?h+A)r~+s#)&35o`hvnee(WMa0Z;{Q*#uk~G(K1&Db}T&W(j z3#4QzJq}>CykMfMLk z5Gm+Ee?8{kxqq46kA_PsemZn{%vEr$#ADQp6^*;TTuIf6$Nf+8vp^J&ZRzbDfGSmT zO44N;13^5LJmxl#lH%V+anw{TDJl6ZupskYxK*NFkBQGH9`hIgauDvAjzMyyyx_=c z>;>rqa?C3{26wM&R1aO{Kubld5R{Xb&UQg>weDF@=-rVlKt zpn;dOH12-Vwi+U*OMAyY=<=9fhHE7rY98}ia9ghK%EQKKR`5D1z!j|&NRJNztF{DV zDtb2!d1JOQxk`xX5ui|NdX$L_5OT3DA;VBuPB}F zcZ@!mAlyPQMdze97z;41m_cQ8?HPy7=}H~gM09R82Z>wDPR;Fyq^*62#OINy_?vAK zY@x|Me64n2x5vC6uF6i2(@rA|HttWsXl19T#7@r$I}_pi0fbA7 z@p1)RT-yasaXwlYa~xk275RlC`9&n_Q2??94Wo$3Q15xjRm;mE>~zRQfyDr;s+YYN zp@?^ufh!pUp}OQ~d3G0tDt|4X8E_WWI5)MN<@m~9%C1hkOKv;(h^$sW+O3woQk}6#?mRm;4WcsqTNgE_+MT>^uvK6c!=4=?9J{&P_w&?WXX<9iC2ngv!WBwG? zRb3{L8Z4Ds&}1stP}6wZY#A!?Q7_q<-~+Rl!nQLJ4ALkeCQUY^qjJRLqG#}2f;Lgl z6mk&sz!6G@onGcpJ)_YG_%Mnsb$7Q)O*6|xz~_RP&hi?4lTo*S z|84_ferM~HfSma3PwX~?tL{^+b+G;%eNga?#${93T4$-=IbfDjgxcp8y+C%J(h~r4 z^B3EKmrcP~)EBj;sxZWtN=GlU;j$tK0apzx5t||Um|U(9_!b9C^(b@e2n9hV*Ov$~ zH&_&8a;QX*x$BC8Ox{=`$lM)8K_>4h5oGS`ML{O{z)+K+{t>rD_P`L6JZ~HrvZJuN zD99wwTM053D+)5n^Hze)Z7&Kk$@5l%%-vcPWRmBt1etrRD9EHU3ZbLaKjLO@x?(+( z&M2(6qtI(xSkENS8(mp{l(}S4kV&4m5@c>yQIJWVw-RLTNKueUp0^TY?nF_LNoN$+ zkBGuV8o*O_iA6_Q8IMGa#Oxc7#OQvpu4;Q=h)Greelh9PHPWw(!8SaU zK!Y>d(Rh>tk|ftm3w0c$JJ$iR_H6)sbcqY$Y8dZTRl-&N-i3TRW2JJrq-ZMSvQ5cE zv}qs~YueGgG`w_iLo$&n>}VKB6`B?|Ha8_wv1B1`DM?~RN=6g;T!}~t)5PWkJX{V~ zsm2(bO(K_%$F2TG`AH_fGh^j|bW1pq1`^&uz%eFs`ABRlpztD?2FJrNKyi^=Dxj!n zO5Lqt>H=d5iDh?Y@~9I=XRIMbTpBGTlKF;2YK00|xk?2vZolDkSD9;m;2t)gfxrAZ z_cZfTcf!oOE8x#(zV17lU;gZEYnETK+`EOXd*xxYVZ|GU*Z-D$P zhbs8UN0hluof|t_*9FOBZ?G%8J)6i|VfZrIn@tQy^43~wr^sZ%a3q?va(SQzL~v7Y zxUI9dBe)^l7TPR=-K#shgTjLEwpJE~#2o@+z{-a)o#9L*8yT|l5EEs(r*%!REhJPL z!`6;)Jd%%K5Yy4CtymtbD!kR&3DZ$?w*!z%45X~MAEFOAfKWif6RB{&bX;I$k|je5 zDH?#mlQCW$><(^NxsE0s?oYsgv{O~4kcTvJuB}uYlRT78<-@W34s;P#2Ha#U(9NNA z943$v;r?V~AZKR?2g(u$+3;{0KFUe+echd#f)HSKK$e3{Er3`{GKe^LumiaoLW^hy zesW0k?}Uh=L=s9Zo=*%}0;?3iVU=dD0Cg3^a*5)WNGnwq z4rDcw#N0-bVK@ZhB0jV&Aabzj11&A|!VVu=S=@Nx{DS>4m)oAs#>25Fg$-TEFAY$r zjvuUG9={siEnF}HIFmJi(XS#=*|Dr+Spjd`rS zM!9Mlqq&@D%%+h+ad=z;7KP$gv@j4(r25k!D(Ofxnze?R!)@Cs2@e{n0oW%Vb_s$SAsh|^yZ zFbB>y4H$TY9?_bc6!a)6hlVc|Nb)O49fHvC`yJx&L|)RaqH!f4FglDcH>mR;9UmZ_ z3*qi;Y@hw*KDN*IAapRzGI;MNu(#HUj+AYI?$P4+CKdXllhk;OALfYt;rOiwY&82{ zm%rQzF~fe{PnOABBlg4k=lxwUw2;)cd{~7Y1^Mw9a!k?bMPm_I~C$O@0 z)8_YO9zZzT=lgNMk=Dn*KSvFiLF4$wHd%AJBs^pV}X{TiQzIt zTe^MtL3?!j^i2=*<7~QpXP=WsxiRAHb54wD_ox{|KSqlL;-f_vacyyf0bFA)hkibL z(YAZUDS;^B92Ld$)vf-K0JHYpt^OUR%`@Q^e5x~|?rynqN-^ZzqIx7Kam>`n=2ril zVMK>pK5dl3xc$|XLXyMtZZ!OY^WgP>kB4}kggZ8#;S!)n)3XY2l;^tTXCU0CN0T2W z`M2PXjXxzH26{Akd_Yt0hs9?$dZMLgO7+HtkC66r+=#CL=Y7CD&l|rc?|5e`9iTe! z8v$=Wxco4ie?O<%VxX~MonrNJWw#*+O_#^GVbk%Pf=A#7&VxUA9{gVkXMczlryMxi z=JpFB5Q87(?0MDD#(?+~2mTSDu_2E8AIG5!L1>8k;E(YHg3xsQpA|d;zwSo(LMEo`l zCstgi;qY6sZ2L9*35w?t4gVx13ZFZ$aeOYIE&RBGZG0K&|Eh)u$p4cXjSNMsa>$lYgD&TS0bM{w|W6tl`b%{~Qg!nDhiR{Au!Y zg@&vDKqACi4c|*~+pOWU$RA6?e@lE;!xQAs4H~|K^dHplvy|U^G~7e@=QW(`^(z|w zF|vD7!ylr!{hNlbqWJtw!@CH7L&HOa|F?!;Nx1q)KE?Ws5?)32IltS;&uJQdEy-V` z;q?@^1scAD>grMr|1HI>L&JYV@*xe+k^W;EzMtmF@niqLN%+f}e3tzGy@vmd?4H%| zZt~Mj{jC4@#8+$h9;(CX8h(WA&e!l=#4ptFi6p;5!*3^l)@V4suVLGy;XJRXhCfC6 z(;EI9@z-ehk0~zuG<+5Dhc {Jc-Y@x2z?=QVsg)!Snl{xaq9n;O1>{Q16ypP+fY zq~Qk$e@(+rlb>&DI6qIkqv09iKhW?=w6B)aJh)DdlKu%A{vE<+Y4~oMSG$JaOY&D~ zIOj2`;lH8v!f|DP&XAt#H2GI4J~wOlZ^@s78va+}@78cH$^VCjv!8#^@bSd6KK65- zDid)r&4ck}R1Y84@TW=7dJVTIPgiO956I808or2lJ_pz?`@c_Kj$5mS$4Gy-hIf+Qk7{^?>abtKZ=?A0xyN=7k^bv7 zd5-5NH2fiwze~fvM)(67ev0rfY52wD|C1WtPyV0Q@L{UMmo@z7q~{kJzJ~1nmxlj^ z;_$A9-%t5+ksXfDVZ!mJ4Q!0RP2;C(`0Iqv)9|^p-WO{42PD5j!*5aM#2O8cl0Ta? zobwgca9&3#4Ns8WYc%{I`FWFuUr+1wb`7s5{4*NP>-IqnZz29m8qUw_-`DWJkUy_z zcst?0*6<$Urob&RMhF?K( zdriZ4lmEZd@OQ``H%bhV%1$Uc;Lx4!bq{=Y&6nAA_Kwc_gnU|9_+5 z>c0yL@s@@kp?OWOLMAy?E%PG!JX!svV{@WVKHGCTuHMI9M{L6$-q7ThnpKmL1` - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include "system.h" - -#include - -#include "digest.h" -#include "prf.h" - -/* Generate key material from a master secret and a seed, based on RFC 4346 section 5. - We use SHA512 instead of MD5 and SHA1. - */ - -static bool prf_xor(int nid, const char *secret, size_t secretlen, char *seed, size_t seedlen, char *out, ssize_t outlen) { - digest_t digest; - - if(!digest_open_by_nid(&digest, nid, -1)) - return false; - - if(!digest_set_key(&digest, secret, secretlen)) - return false; - - size_t len = digest_length(&digest); - - /* Data is what the "inner" HMAC function processes. - It consists of the previous HMAC result plus the seed. - */ - - char data[len + seedlen]; - memset(data, 0, len); - memcpy(data + len, seed, seedlen); - - char hash[len]; - - while(outlen > 0) { - /* Inner HMAC */ - digest_create(&digest, data, len + seedlen, data); - - /* Outer HMAC */ - digest_create(&digest, data, len + seedlen, hash); - - /* XOR the results of the outer HMAC into the out buffer */ - for(int i = 0; i < len && i < outlen; i++) - *out++ ^= hash[i]; - - outlen -= len; - } - - digest_close(&digest); - return true; -} - -bool prf(const char *secret, size_t secretlen, char *seed, size_t seedlen, char *out, size_t outlen) { - /* This construction allows us to easily switch back to a scheme where the PRF is calculated using two different digest algorithms. */ - memset(out, 0, outlen); - - return prf_xor(NID_sha512, secret, secretlen, seed, seedlen, out, outlen); -} diff --git a/src/openssl/prf.h b/src/prf.h similarity index 85% rename from src/openssl/prf.h rename to src/prf.h index 6525505..ef4b99b 100644 --- a/src/openssl/prf.h +++ b/src/prf.h @@ -1,6 +1,6 @@ /* prf.h -- header file for prf.c - Copyright (C) 2011 Guus Sliepen + Copyright (C) 2011-2013 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 @@ -20,6 +20,6 @@ #ifndef __TINC_PRF_H__ #define __TINC_PRF_H__ -extern bool prf(const char *secret, size_t secretlen, char *seed, size_t seedlen, char *out, size_t outlen); +extern bool prf(const char *secret, size_t secretlen, char *seed, size_t seedlen, char *out, size_t outlen) __attribute__ ((__warn_unused_result__)); #endif diff --git a/src/protocol.c b/src/protocol.c index ad0fa8d..374c522 100644 --- a/src/protocol.c +++ b/src/protocol.c @@ -1,7 +1,7 @@ /* protocol.c -- handle the meta-protocol, basic functions Copyright (C) 1999-2005 Ivo Timmermans, - 2000-2012 Guus Sliepen + 2000-2013 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 @@ -30,7 +30,7 @@ bool tunnelserver = false; bool strictsubnets = false; -bool experimental = false; +bool experimental = true; /* Jumptable for the request handlers */ diff --git a/src/protocol.h b/src/protocol.h index 1df54fc..e771c54 100644 --- a/src/protocol.h +++ b/src/protocol.h @@ -1,7 +1,7 @@ /* protocol.h -- header for protocol.c Copyright (C) 1999-2005 Ivo Timmermans, - 2000-2012 Guus Sliepen + 2000-2013 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 @@ -21,10 +21,12 @@ #ifndef __TINC_PROTOCOL_H__ #define __TINC_PROTOCOL_H__ +#include "ecdsa.h" + /* Protocol version. Different major versions are incompatible. */ #define PROT_MAJOR 17 -#define PROT_MINOR 2 /* Should not exceed 255! */ +#define PROT_MINOR 3 /* Should not exceed 255! */ /* Silly Windows */ @@ -59,6 +61,8 @@ extern bool tunnelserver; extern bool strictsubnets; extern bool experimental; +extern ecdsa_t *invitation_key; + /* Maximum size of strings in a request. * scanf terminates %2048s with a NUL character, * but the NUL character can be written after the 2048th non-NUL character. diff --git a/src/protocol_auth.c b/src/protocol_auth.c index 5f2dcaa..f8a3cc3 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-2012 Guus Sliepen + 2000-2013 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 @@ -27,10 +27,12 @@ #include "cipher.h" #include "crypto.h" #include "digest.h" +#include "ecdsa.h" #include "edge.h" #include "graph.h" #include "logger.h" #include "meta.h" +#include "names.h" #include "net.h" #include "netutl.h" #include "node.h" @@ -41,6 +43,8 @@ #include "utils.h" #include "xalloc.h" +ecdsa_t *invitation_key = NULL; + static bool send_proxyrequest(connection_t *c) { switch(proxytype) { case PROXY_HTTP: { @@ -133,7 +137,7 @@ bool send_id(connection_t *c) { int minor = 0; if(experimental) { - if(c->config_tree && !read_ecdsa_public_key(c)) + if(c->outgoing && !read_ecdsa_public_key(c)) minor = 1; else minor = myself->connection->protocol_minor; @@ -146,6 +150,107 @@ bool send_id(connection_t *c) { return send_request(c, "%d %s %d.%d", ID, myself->connection->name, myself->connection->protocol_major, minor); } +static bool finalize_invitation(connection_t *c, const char *data, uint16_t len) { + if(strchr(data, '\n')) { + logger(DEBUG_ALWAYS, LOG_ERR, "Received invalid key from invited node %s (%s)!\n", c->name, c->hostname); + return false; + } + + // Create a new host config file + char filename[PATH_MAX]; + snprintf(filename, sizeof filename, "%s" SLASH "hosts" SLASH "%s", confbase, c->name); + if(!access(filename, F_OK)) { + logger(DEBUG_ALWAYS, LOG_ERR, "Host config file for %s (%s) already exists!\n", c->name, c->hostname); + return false; + } + + FILE *f = fopen(filename, "w"); + if(!f) { + logger(DEBUG_ALWAYS, LOG_ERR, "Error trying to create %s: %s\n", filename, strerror(errno)); + return false; + } + + fprintf(f, "ECDSAPublicKey = %s\n", data); + fclose(f); + + logger(DEBUG_CONNECTIONS, LOG_INFO, "Key succesfully received from %s (%s)", c->name, c->hostname); + return true; +} + +static bool receive_invitation_sptps(void *handle, uint8_t type, const char *data, uint16_t len) { + connection_t *c = handle; + + if(type == 128) + return true; + + if(type == 1 && c->status.invitation_used) + return finalize_invitation(c, data, len); + + if(type != 0 || len != 18 || c->status.invitation_used) + return false; + + char cookie[25]; + b64encode_urlsafe(data, cookie, 18); + + char filename[PATH_MAX], usedname[PATH_MAX]; + snprintf(filename, sizeof filename, "%s" SLASH "invitations" SLASH "%s", confbase, cookie); + snprintf(usedname, sizeof usedname, "%s" SLASH "invitations" SLASH "%s.used", confbase, cookie); + + // Atomically rename the invitation file + if(rename(filename, usedname)) { + if(errno == ENOENT) + logger(DEBUG_ALWAYS, LOG_ERR, "Peer %s tried to use non-existing invitation %s\n", c->hostname, cookie); + else + logger(DEBUG_ALWAYS, LOG_ERR, "Error trying to rename invitation %s\n", cookie); + return false; + } + + // Open the renamed file + FILE *f = fopen(usedname, "r"); + if(!f) { + logger(DEBUG_ALWAYS, LOG_ERR, "Error trying to open invitation %s\n", cookie); + return false; + } + + // Read the new node's Name from the file + char buf[1024]; + fgets(buf, sizeof buf, f); + if(*buf) + buf[strlen(buf) - 1] = 0; + + len = strcspn(buf, " \t="); + char *name = buf + len; + name += strspn(name, " \t"); + if(*name == '=') { + name++; + name += strspn(name, " \t"); + } + buf[len] = 0; + + if(!*buf || !*name || strcasecmp(buf, "Name") || !check_id(name)) { + logger(DEBUG_ALWAYS, LOG_ERR, "Invalid invitation file %s\n", cookie); + fclose(f); + return false; + } + + free(c->name); + c->name = xstrdup(name); + + // Send the node the contents of the invitation file + rewind(f); + size_t result; + while((result = fread(buf, 1, sizeof buf, f))) + sptps_send_record(&c->sptps, 0, buf, result); + sptps_send_record(&c->sptps, 1, buf, 0); + fclose(f); + unlink(usedname); + + c->status.invitation_used = true; + + logger(DEBUG_CONNECTIONS, LOG_INFO, "Invitation %s succesfully sent to %s (%s)", cookie, c->name, c->hostname); + return true; +} + bool id_h(connection_t *c, const char *request) { char name[MAX_STRING_SIZE]; @@ -168,6 +273,31 @@ bool id_h(connection_t *c, const char *request) { return send_request(c, "%d %d %d", ACK, TINC_CTL_VERSION_CURRENT, getpid()); } + if(name[0] == '?') { + if(!invitation_key) { + logger(DEBUG_ALWAYS, LOG_ERR, "Got invitation from %s but we don't have an invitation key", c->hostname); + return false; + } + + c->ecdsa = ecdsa_set_base64_public_key(name + 1); + if(!c->ecdsa) { + logger(DEBUG_ALWAYS, LOG_ERR, "Got bad invitation from %s", c->hostname); + return false; + } + + c->status.invitation = true; + char *mykey = ecdsa_get_base64_public_key(invitation_key); + if(!mykey) + return false; + if(!send_request(c, "%d %s", ACK, mykey)) + return false; + free(mykey); + + c->protocol_minor = 2; + + return sptps_start(&c->sptps, c, false, false, invitation_key, c->ecdsa, "tinc invitation", 15, send_meta_sptps, receive_invitation_sptps); + } + /* Check if identity is a valid name */ if(!check_id(name)) { @@ -194,7 +324,7 @@ bool id_h(connection_t *c, const char *request) { if(c->protocol_major != myself->connection->protocol_major) { logger(DEBUG_ALWAYS, LOG_ERR, "Peer %s (%s) uses incompatible version %d.%d", - c->name, c->hostname, c->protocol_major, c->protocol_minor); + c->name, c->hostname, c->protocol_major, c->protocol_minor); return false; } @@ -216,15 +346,21 @@ bool id_h(connection_t *c, const char *request) { return false; } - if(experimental && c->protocol_minor >= 2) { - if(!read_ecdsa_public_key(c)) - return false; - } + if(experimental) + read_ecdsa_public_key(c); } else { - if(c->protocol_minor && !ecdsa_active(&c->ecdsa)) + if(c->protocol_minor && !ecdsa_active(c->ecdsa)) c->protocol_minor = 1; } + /* Forbid version rollback for nodes whose ECDSA key we know */ + + if(ecdsa_active(c->ecdsa) && c->protocol_minor < 2) { + logger(DEBUG_ALWAYS, LOG_ERR, "Peer %s (%s) tries to roll back protocol version to %d.%d", + c->name, c->hostname, c->protocol_major, c->protocol_minor); + return false; + } + c->allow_request = METAKEY; if(c->protocol_minor >= 2) { @@ -246,13 +382,13 @@ bool send_metakey(connection_t *c) { if(!read_rsa_public_key(c)) return false; - if(!cipher_open_blowfish_ofb(&c->outcipher)) + if(!(c->outcipher = cipher_open_blowfish_ofb())) return false; - if(!digest_open_sha1(&c->outdigest, -1)) + if(!(c->outdigest = digest_open_sha1(-1))) return false; - size_t len = rsa_size(&c->rsa); + size_t len = rsa_size(c->rsa); char key[len]; char enckey[len]; char hexkey[2 * len + 1]; @@ -273,7 +409,8 @@ bool send_metakey(connection_t *c) { key[0] &= 0x7F; - cipher_set_key_from_rsa(&c->outcipher, key, len, true); + if(!cipher_set_key_from_rsa(c->outcipher, key, len, true)) + return false; if(debug_level >= DEBUG_SCARY_THINGS) { bin2hex(key, hexkey, len); @@ -287,7 +424,7 @@ bool send_metakey(connection_t *c) { with a length equal to that of the modulus of the RSA key. */ - if(!rsa_public_encrypt(&c->rsa, key, len, enckey)) { + if(!rsa_public_encrypt(c->rsa, key, len, enckey)) { logger(DEBUG_ALWAYS, LOG_ERR, "Error during encryption of meta key for %s (%s)", c->name, c->hostname); return false; } @@ -299,8 +436,8 @@ bool send_metakey(connection_t *c) { /* Send the meta key */ bool result = send_request(c, "%d %d %d %d %d %s", METAKEY, - cipher_get_nid(&c->outcipher), - digest_get_nid(&c->outdigest), c->outmaclength, + cipher_get_nid(c->outcipher), + digest_get_nid(c->outdigest), c->outmaclength, c->outcompression, hexkey); c->status.encryptout = true; @@ -310,7 +447,7 @@ bool send_metakey(connection_t *c) { bool metakey_h(connection_t *c, const char *request) { char hexkey[MAX_STRING_SIZE]; int cipher, digest, maclength, compression; - size_t len = rsa_size(&myself->connection->rsa); + size_t len = rsa_size(myself->connection->rsa); char enckey[len]; char key[len]; @@ -332,7 +469,7 @@ bool metakey_h(connection_t *c, const char *request) { /* Decrypt the meta key */ - if(!rsa_private_decrypt(&myself->connection->rsa, enckey, len, key)) { + if(!rsa_private_decrypt(myself->connection->rsa, enckey, len, key)) { logger(DEBUG_ALWAYS, LOG_ERR, "Error during decryption of meta key for %s (%s)", c->name, c->hostname); return false; } @@ -344,12 +481,12 @@ bool metakey_h(connection_t *c, const char *request) { /* Check and lookup cipher and digest algorithms */ - if(!cipher_open_by_nid(&c->incipher, cipher) || !cipher_set_key_from_rsa(&c->incipher, key, len, false)) { + if(!(c->incipher = cipher_open_by_nid(cipher)) || !cipher_set_key_from_rsa(c->incipher, key, len, false)) { logger(DEBUG_ALWAYS, LOG_ERR, "Error during initialisation of cipher from %s (%s)", c->name, c->hostname); return false; } - if(!digest_open_by_nid(&c->indigest, digest, -1)) { + if(!(c->indigest = digest_open_by_nid(digest, -1))) { logger(DEBUG_ALWAYS, LOG_ERR, "Error during initialisation of digest from %s (%s)", c->name, c->hostname); return false; } @@ -362,7 +499,7 @@ bool metakey_h(connection_t *c, const char *request) { } bool send_challenge(connection_t *c) { - size_t len = rsa_size(&c->rsa); + size_t len = rsa_size(c->rsa); char buffer[len * 2 + 1]; if(!c->hischallenge) @@ -383,8 +520,8 @@ bool send_challenge(connection_t *c) { bool challenge_h(connection_t *c, const char *request) { char buffer[MAX_STRING_SIZE]; - size_t len = rsa_size(&myself->connection->rsa); - size_t digestlen = digest_length(&c->indigest); + size_t len = rsa_size(myself->connection->rsa); + size_t digestlen = digest_length(c->indigest); char digest[digestlen]; if(sscanf(request, "%*d " MAX_STRING, buffer) != 1) { @@ -403,11 +540,10 @@ bool challenge_h(connection_t *c, const char *request) { return false; } - c->allow_request = CHAL_REPLY; - /* Calculate the hash from the challenge we received */ - digest_create(&c->indigest, buffer, len, digest); + if(!digest_create(c->indigest, buffer, len, digest)) + return false; /* Convert the hash to a hexadecimal formatted string */ @@ -415,6 +551,8 @@ bool challenge_h(connection_t *c, const char *request) { /* Send the reply */ + c->allow_request = CHAL_REPLY; + return send_request(c, "%d %s", CHAL_REPLY, buffer); } @@ -433,7 +571,7 @@ bool chal_reply_h(connection_t *c, const char *request) { /* Check if the length of the hash is all right */ - if(inlen != digest_length(&c->outdigest)) { + if(inlen != digest_length(c->outdigest)) { logger(DEBUG_ALWAYS, LOG_ERR, "Possible intruder %s (%s): %s", c->name, c->hostname, "wrong challenge reply length"); return false; } @@ -441,7 +579,7 @@ bool chal_reply_h(connection_t *c, const char *request) { /* Verify the hash */ - if(!digest_verify(&c->outdigest, c->hischallenge, rsa_size(&c->rsa), hishash)) { + if(!digest_verify(c->outdigest, c->hischallenge, rsa_size(c->rsa), hishash)) { logger(DEBUG_ALWAYS, LOG_ERR, "Possible intruder %s (%s): %s", c->name, c->hostname, "wrong challenge reply"); return false; } @@ -461,7 +599,7 @@ static bool send_upgrade(connection_t *c) { /* Special case when protocol_minor is 1: the other end is ECDSA capable, * but doesn't know our key yet. So send it now. */ - char *pubkey = ecdsa_get_base64_public_key(&myself->connection->ecdsa); + char *pubkey = ecdsa_get_base64_public_key(myself->connection->ecdsa); if(!pubkey) return false; @@ -545,7 +683,7 @@ static bool upgrade_h(connection_t *c, const char *request) { return false; } - if(ecdsa_active(&c->ecdsa) || read_ecdsa_public_key(c)) { + if(ecdsa_active(c->ecdsa) || read_ecdsa_public_key(c)) { logger(DEBUG_ALWAYS, LOG_INFO, "Already have ECDSA public key from %s (%s), not upgrading.", c->name, c->hostname); return false; } diff --git a/src/protocol_key.c b/src/protocol_key.c index 57377b2..a3cf3f5 100644 --- a/src/protocol_key.c +++ b/src/protocol_key.c @@ -124,7 +124,7 @@ bool send_req_key(node_t *to) { static bool req_key_ext_h(connection_t *c, const char *request, node_t *from, int reqno) { switch(reqno) { case REQ_PUBKEY: { - char *pubkey = ecdsa_get_base64_public_key(&myself->connection->ecdsa); + char *pubkey = ecdsa_get_base64_public_key(myself->connection->ecdsa); send_request(from->nexthop->connection, "%d %s %s %d %s", REQ_KEY, myself->name, from->name, ANS_PUBKEY, pubkey); free(pubkey); return true; @@ -137,7 +137,7 @@ static bool req_key_ext_h(connection_t *c, const char *request, node_t *from, in } char pubkey[MAX_STRING_SIZE]; - if(sscanf(request, "%*d %*s %*s %*d " MAX_STRING, pubkey) != 1 || !ecdsa_set_base64_public_key(&from->ecdsa, pubkey)) { + if(sscanf(request, "%*d %*s %*s %*d " MAX_STRING, pubkey) != 1 || !(from->ecdsa = ecdsa_set_base64_public_key(pubkey))) { logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s): %s", "ANS_PUBKEY", from->name, from->hostname, "invalid pubkey"); return true; } @@ -158,11 +158,12 @@ static bool req_key_ext_h(connection_t *c, const char *request, node_t *from, in logger(DEBUG_ALWAYS, LOG_DEBUG, "Got REQ_KEY from %s while we already started a SPTPS session!", from->name); char buf[MAX_STRING_SIZE]; - if(sscanf(request, "%*d %*s %*s %*d " MAX_STRING, buf) != 1) { + int len; + + if(sscanf(request, "%*d %*s %*s %*d " MAX_STRING, buf) != 1 || !(len = b64decode(buf, buf, strlen(buf)))) { logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s): %s", "REQ_SPTPS_START", from->name, from->hostname, "invalid SPTPS data"); return true; } - int len = b64decode(buf, buf, strlen(buf)); char label[25 + strlen(from->name) + strlen(myself->name)]; snprintf(label, sizeof label, "tinc UDP key expansion %s %s", from->name, myself->name); @@ -182,11 +183,11 @@ static bool req_key_ext_h(connection_t *c, const char *request, node_t *from, in } char buf[MAX_STRING_SIZE]; - if(sscanf(request, "%*d %*s %*s %*d " MAX_STRING, buf) != 1) { + int len; + if(sscanf(request, "%*d %*s %*s %*d " MAX_STRING, buf) != 1 || !(len = b64decode(buf, buf, strlen(buf)))) { logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s): %s", "REQ_SPTPS", from->name, from->hostname, "invalid SPTPS data"); return true; } - int len = b64decode(buf, buf, strlen(buf)); sptps_receive_data(&from->sptps, buf, len); return true; } @@ -259,19 +260,24 @@ bool send_ans_key(node_t *to) { if(to->status.sptps) abort(); - size_t keylen = cipher_keylength(&myself->incipher); + size_t keylen = cipher_keylength(myself->incipher); char key[keylen * 2 + 1]; - cipher_close(&to->incipher); - digest_close(&to->indigest); + cipher_close(to->incipher); + digest_close(to->indigest); - cipher_open_by_nid(&to->incipher, cipher_get_nid(&myself->incipher)); - digest_open_by_nid(&to->indigest, digest_get_nid(&myself->indigest), digest_length(&myself->indigest)); + to->incipher = cipher_open_by_nid(cipher_get_nid(myself->incipher)); + to->indigest = digest_open_by_nid(digest_get_nid(myself->indigest), digest_length(myself->indigest)); to->incompression = myself->incompression; + if(!to->incipher || !to->indigest) + abort(); + randomize(key, keylen); - cipher_set_key(&to->incipher, key, false); - digest_set_key(&to->indigest, key, keylen); + if(!cipher_set_key(to->incipher, key, false)) + abort(); + if(!digest_set_key(to->indigest, key, keylen)) + abort(); bin2hex(key, key, keylen); @@ -283,9 +289,9 @@ bool send_ans_key(node_t *to) { return send_request(to->nexthop->connection, "%d %s %s %s %d %d %d %d", ANS_KEY, myself->name, to->name, key, - cipher_get_nid(&to->incipher), - digest_get_nid(&to->indigest), - (int)digest_length(&to->indigest), + cipher_get_nid(to->incipher), + digest_get_nid(to->indigest), + (int)digest_length(to->indigest), to->incompression); } @@ -353,8 +359,8 @@ bool ans_key_h(connection_t *c, const char *request) { } /* Don't use key material until every check has passed. */ - cipher_close(&from->outcipher); - digest_close(&from->outdigest); + cipher_close(from->outcipher); + digest_close(from->outdigest); from->status.validkey = false; if(compression < 0 || compression > 11) { @@ -370,7 +376,7 @@ bool ans_key_h(connection_t *c, const char *request) { char buf[strlen(key)]; int len = b64decode(key, buf, strlen(key)); - if(!sptps_receive_data(&from->sptps, buf, len)) + if(!len || !sptps_receive_data(&from->sptps, buf, len)) logger(DEBUG_ALWAYS, LOG_ERR, "Error processing SPTPS data from %s (%s)", from->name, from->hostname); if(from->status.validkey) { @@ -380,7 +386,7 @@ bool ans_key_h(connection_t *c, const char *request) { update_node_udp(from, &sa); } - if(from->options & OPTION_PMTU_DISCOVERY) + if(from->options & OPTION_PMTU_DISCOVERY && !(from->options & OPTION_TCPONLY)) send_mtu_probe(from); } @@ -389,17 +395,17 @@ bool ans_key_h(connection_t *c, const char *request) { /* Check and lookup cipher and digest algorithms */ - if(!cipher_open_by_nid(&from->outcipher, cipher)) { + if(!(from->outcipher = cipher_open_by_nid(cipher))) { logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses unknown cipher!", from->name, from->hostname); return false; } - if(!digest_open_by_nid(&from->outdigest, digest, maclength)) { + if(!(from->outdigest = digest_open_by_nid(digest, maclength))) { logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses unknown digest!", from->name, from->hostname); return false; } - if(maclength != digest_length(&from->outdigest)) { + if(maclength != digest_length(from->outdigest)) { logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses bogus MAC length!", from->name, from->hostname); return false; } @@ -408,15 +414,17 @@ bool ans_key_h(connection_t *c, const char *request) { keylen = hex2bin(key, key, sizeof key); - if(keylen != cipher_keylength(&from->outcipher)) { + if(keylen != cipher_keylength(from->outcipher)) { logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses wrong keylength!", from->name, from->hostname); return true; } /* Update our copy of the origin's packet key */ - cipher_set_key(&from->outcipher, key, true); - digest_set_key(&from->outdigest, key, keylen); + if(!cipher_set_key(from->outcipher, key, true)) + return false; + if(!digest_set_key(from->outdigest, key, keylen)) + return false; from->status.validkey = true; from->sent_seqno = 0; @@ -427,7 +435,7 @@ bool ans_key_h(connection_t *c, const char *request) { update_node_udp(from, &sa); } - if(from->options & OPTION_PMTU_DISCOVERY) + if(from->options & OPTION_PMTU_DISCOVERY && !(from->options & OPTION_TCPONLY)) send_mtu_probe(from); return true; diff --git a/src/protocol_misc.c b/src/protocol_misc.c index a4ad73d..022438e 100644 --- a/src/protocol_misc.c +++ b/src/protocol_misc.c @@ -1,7 +1,7 @@ /* protocol_misc.c -- handle the meta-protocol, miscellaneous functions Copyright (C) 1999-2005 Ivo Timmermans, - 2000-2012 Guus Sliepen + 2000-2013 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 diff --git a/src/openssl/rsa.h b/src/rsa.h similarity index 55% rename from src/openssl/rsa.h rename to src/rsa.h index 9a826cb..f4290d4 100644 --- a/src/openssl/rsa.h +++ b/src/rsa.h @@ -1,6 +1,6 @@ /* rsa.h -- RSA key handling - Copyright (C) 2007-2011 Guus Sliepen + Copyright (C) 2007-2013 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 @@ -20,19 +20,17 @@ #ifndef __TINC_RSA_H__ #define __TINC_RSA_H__ -#include +#ifndef __TINC_RSA_INTERNAL__ +typedef struct rsa rsa_t; +#endif -typedef RSA *rsa_t; - -extern bool rsa_set_hex_public_key(rsa_t *rsa, char *n, char *e); -extern bool rsa_set_hex_private_key(rsa_t *rsa, char *n, char *e, char *d); -extern bool rsa_read_pem_public_key(rsa_t *rsa, FILE *fp); -extern bool rsa_read_pem_private_key(rsa_t *rsa, FILE *fp); -extern size_t rsa_size(rsa_t *rsa); -extern bool rsa_public_encrypt(rsa_t *rsa, void *in, size_t inlen, void *out); -extern bool rsa_private_decrypt(rsa_t *rsa, void *in, size_t inlen, void *out); -extern bool rsa_active(rsa_t *rsa); extern void rsa_free(rsa_t *rsa); - +extern rsa_t *rsa_set_hex_public_key(char *n, char *e) __attribute__ ((__malloc__)); +extern rsa_t *rsa_set_hex_private_key(char *n, char *e, char *d) __attribute__ ((__malloc__)); +extern rsa_t *rsa_read_pem_public_key(FILE *fp) __attribute__ ((__malloc__)); +extern rsa_t *rsa_read_pem_private_key(FILE *fp) __attribute__ ((__malloc__)); +extern size_t rsa_size(rsa_t *rsa); +extern bool rsa_public_encrypt(rsa_t *rsa, void *in, size_t len, void *out) __attribute__ ((__warn_unused_result__)); +extern bool rsa_private_decrypt(rsa_t *rsa, void *in, size_t len, void *out) __attribute__ ((__warn_unused_result__)); #endif diff --git a/src/openssl/rsagen.h b/src/rsagen.h similarity index 70% rename from src/openssl/rsagen.h rename to src/rsagen.h index 422d156..58ce29f 100644 --- a/src/openssl/rsagen.h +++ b/src/rsagen.h @@ -1,6 +1,6 @@ /* rsagen.h -- RSA key generation and export - Copyright (C) 2008 Guus Sliepen + Copyright (C) 2008-2013 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 @@ -22,8 +22,8 @@ #include "rsa.h" -extern bool rsa_generate(rsa_t *rsa, size_t bits, unsigned long exponent); -extern bool rsa_write_pem_public_key(rsa_t *rsa, FILE *fp); -extern bool rsa_write_pem_private_key(rsa_t *rsa, FILE *fp); +extern rsa_t *rsa_generate(size_t bits, unsigned long exponent) __attribute__ ((__malloc__)); +extern bool rsa_write_pem_public_key(rsa_t *rsa, FILE *fp) __attribute__ ((__warn_unused_result__)); +extern bool rsa_write_pem_private_key(rsa_t *rsa, FILE *fp) __attribute__ ((__warn_unused_result__)); #endif diff --git a/src/solaris/.deps/device.Po b/src/solaris/.deps/device.Po new file mode 100644 index 0000000..9ce06a8 --- /dev/null +++ b/src/solaris/.deps/device.Po @@ -0,0 +1 @@ +# dummy diff --git a/src/solaris/device.c b/src/solaris/device.c index c8c5cbf..21ce73f 100644 --- a/src/solaris/device.c +++ b/src/solaris/device.c @@ -19,19 +19,19 @@ */ -#include "system.h" +#include "../system.h" #include #include #include -#include "conf.h" -#include "device.h" -#include "logger.h" -#include "names.h" -#include "net.h" -#include "utils.h" -#include "xalloc.h" +#include "../conf.h" +#include "../device.h" +#include "../logger.h" +#include "../names.h" +#include "../net.h" +#include "../utils.h" +#include "../xalloc.h" #define DEFAULT_DEVICE "/dev/tun" diff --git a/src/splay_tree.c b/src/splay_tree.c index 54a46f2..bd0f06b 100644 --- a/src/splay_tree.c +++ b/src/splay_tree.c @@ -1,6 +1,6 @@ /* splay_tree.c -- splay tree and linked list convenience - Copyright (C) 2004-2012 Guus Sliepen + Copyright (C) 2004-2013 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 @@ -238,7 +238,7 @@ static void splay_bottom_up(splay_tree_t *tree, splay_node_t *node) { splay_tree_t *splay_alloc_tree(splay_compare_t compare, splay_action_t delete) { splay_tree_t *tree; - tree = xmalloc_and_zero(sizeof(splay_tree_t)); + tree = xzalloc(sizeof(splay_tree_t)); tree->compare = compare; tree->delete = delete; @@ -250,7 +250,7 @@ void splay_free_tree(splay_tree_t *tree) { } splay_node_t *splay_alloc_node(void) { - return xmalloc_and_zero(sizeof(splay_node_t)); + return xzalloc(sizeof(splay_node_t)); } void splay_free_node(splay_tree_t *tree, splay_node_t *node) { diff --git a/src/splay_tree.h b/src/splay_tree.h index 8367ce7..5848870 100644 --- a/src/splay_tree.h +++ b/src/splay_tree.h @@ -1,6 +1,6 @@ /* splay_tree.h -- header file for splay_tree.c - Copyright (C) 2004-2012 Guus Sliepen + Copyright (C) 2004-2013 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 @@ -64,10 +64,10 @@ typedef struct splay_tree_t { /* (De)constructors */ -extern splay_tree_t *splay_alloc_tree(splay_compare_t, splay_action_t); +extern splay_tree_t *splay_alloc_tree(splay_compare_t, splay_action_t) __attribute__ ((__malloc__)); extern void splay_free_tree(splay_tree_t *); -extern splay_node_t *splay_alloc_node(void); +extern splay_node_t *splay_alloc_node(void) __attribute__ ((__malloc__)); extern void splay_free_node(splay_tree_t *tree, splay_node_t *); /* Insertion and deletion */ diff --git a/src/sptps.c b/src/sptps.c index 8242cad..6869575 100644 --- a/src/sptps.c +++ b/src/sptps.c @@ -98,11 +98,13 @@ static bool send_record_priv_datagram(sptps_t *s, uint8_t type, const char *data if(s->outstate) { // If first handshake has finished, encrypt and HMAC - cipher_set_counter(&s->outcipher, &seqno, sizeof seqno); - if(!cipher_counter_xor(&s->outcipher, buffer + 6, len + 1UL, buffer + 6)) + if(!cipher_set_counter(s->outcipher, &seqno, sizeof seqno)) return false; - if(!digest_create(&s->outdigest, buffer, len + 7UL, buffer + 7UL + len)) + if(!cipher_counter_xor(s->outcipher, buffer + 6, len + 1UL, buffer + 6)) + return false; + + if(!digest_create(s->outdigest, buffer, len + 7UL, buffer + 7UL + len)) return false; return s->send_data(s->handle, type, buffer + 2, len + 21UL); @@ -131,10 +133,10 @@ static bool send_record_priv(sptps_t *s, uint8_t type, const char *data, uint16_ if(s->outstate) { // If first handshake has finished, encrypt and HMAC - if(!cipher_counter_xor(&s->outcipher, buffer + 4, len + 3UL, buffer + 4)) + if(!cipher_counter_xor(s->outcipher, buffer + 4, len + 3UL, buffer + 4)) return false; - if(!digest_create(&s->outdigest, buffer, len + 7UL, buffer + 7UL + len)) + if(!digest_create(s->outdigest, buffer, len + 7UL, buffer + 7UL + len)) return false; return s->send_data(s->handle, type, buffer + 4, len + 19UL); @@ -175,7 +177,7 @@ static bool send_kex(sptps_t *s) { randomize(s->mykex + 1, 32); // Create a new ECDH public key. - if(!ecdh_generate_public(&s->ecdh, s->mykex + 1 + 32)) + if(!(s->ecdh = ecdh_generate_public(s->mykex + 1 + 32))) return false; return send_record_priv(s, SPTPS_HANDSHAKE, s->mykex, 1 + 32 + keylen); @@ -184,7 +186,7 @@ static bool send_kex(sptps_t *s) { // Send a SIGnature record, containing an ECDSA signature over both KEX records. static bool send_sig(sptps_t *s) { size_t keylen = ECDH_SIZE; - size_t siglen = ecdsa_size(&s->mykey); + size_t siglen = ecdsa_size(s->mykey); // Concatenate both KEX messages, plus tag indicating if it is from the connection originator, plus label char msg[(1 + 32 + keylen) * 2 + 1 + s->labellen]; @@ -196,7 +198,7 @@ static bool send_sig(sptps_t *s) { memcpy(msg + 1 + 2 * (33 + keylen), s->label, s->labellen); // Sign the result. - if(!ecdsa_sign(&s->mykey, msg, sizeof msg, sig)) + if(!ecdsa_sign(s->mykey, msg, sizeof msg, sig)) return false; // Send the SIG exchange record. @@ -207,17 +209,16 @@ static bool send_sig(sptps_t *s) { static bool generate_key_material(sptps_t *s, const char *shared, size_t len) { // Initialise cipher and digest structures if necessary if(!s->outstate) { - bool result - = cipher_open_by_name(&s->incipher, "aes-256-ecb") - && cipher_open_by_name(&s->outcipher, "aes-256-ecb") - && digest_open_by_name(&s->indigest, "sha256", 16) - && digest_open_by_name(&s->outdigest, "sha256", 16); - if(!result) + s->incipher = cipher_open_by_name("aes-256-ecb"); + s->outcipher = cipher_open_by_name("aes-256-ecb"); + s->indigest = digest_open_by_name("sha256", 16); + s->outdigest = digest_open_by_name("sha256", 16); + if(!s->incipher || !s->outcipher || !s->indigest || !s->outdigest) return false; } // Allocate memory for key material - size_t keylen = digest_keylength(&s->indigest) + digest_keylength(&s->outdigest) + cipher_keylength(&s->incipher) + cipher_keylength(&s->outcipher); + size_t keylen = digest_keylength(s->indigest) + digest_keylength(s->outdigest) + cipher_keylength(s->incipher) + cipher_keylength(s->outcipher); s->key = realloc(s->key, keylen); if(!s->key) @@ -254,14 +255,14 @@ static bool receive_ack(sptps_t *s, const char *data, uint16_t len) { if(s->initiator) { bool result - = cipher_set_counter_key(&s->incipher, s->key) - && digest_set_key(&s->indigest, s->key + cipher_keylength(&s->incipher), digest_keylength(&s->indigest)); + = cipher_set_counter_key(s->incipher, s->key) + && digest_set_key(s->indigest, s->key + cipher_keylength(s->incipher), digest_keylength(s->indigest)); if(!result) return false; } else { bool result - = cipher_set_counter_key(&s->incipher, s->key + cipher_keylength(&s->outcipher) + digest_keylength(&s->outdigest)) - && digest_set_key(&s->indigest, s->key + cipher_keylength(&s->outcipher) + digest_keylength(&s->outdigest) + cipher_keylength(&s->incipher), digest_keylength(&s->indigest)); + = cipher_set_counter_key(s->incipher, s->key + cipher_keylength(s->outcipher) + digest_keylength(s->outdigest)) + && digest_set_key(s->indigest, s->key + cipher_keylength(s->outcipher) + digest_keylength(s->outdigest) + cipher_keylength(s->incipher), digest_keylength(s->indigest)); if(!result) return false; } @@ -296,7 +297,7 @@ static bool receive_kex(sptps_t *s, const char *data, uint16_t len) { // Receive a SIGnature record, verify it, if it passed, compute the shared secret and calculate the session keys. static bool receive_sig(sptps_t *s, const char *data, uint16_t len) { size_t keylen = ECDH_SIZE; - size_t siglen = ecdsa_size(&s->hiskey); + size_t siglen = ecdsa_size(s->hiskey); // Verify length of KEX record. if(len != siglen) @@ -311,13 +312,14 @@ static bool receive_sig(sptps_t *s, const char *data, uint16_t len) { memcpy(msg + 1 + 2 * (33 + keylen), s->label, s->labellen); // Verify signature. - if(!ecdsa_verify(&s->hiskey, msg, sizeof msg, data)) + if(!ecdsa_verify(s->hiskey, msg, sizeof msg, data)) return false; // Compute shared secret. char shared[ECDH_SHARED_SIZE]; - if(!ecdh_compute_shared(&s->ecdh, s->hiskex + 1 + 32, shared)) + if(!ecdh_compute_shared(s->ecdh, s->hiskex + 1 + 32, shared)) return false; + s->ecdh = NULL; // Generate key material from shared secret. if(!generate_key_material(s, shared, sizeof shared)) @@ -336,14 +338,14 @@ static bool receive_sig(sptps_t *s, const char *data, uint16_t len) { // TODO: only set new keys after ACK has been set/received if(s->initiator) { bool result - = cipher_set_counter_key(&s->outcipher, s->key + cipher_keylength(&s->incipher) + digest_keylength(&s->indigest)) - && digest_set_key(&s->outdigest, s->key + cipher_keylength(&s->incipher) + digest_keylength(&s->indigest) + cipher_keylength(&s->outcipher), digest_keylength(&s->outdigest)); + = cipher_set_counter_key(s->outcipher, s->key + cipher_keylength(s->incipher) + digest_keylength(s->indigest)) + && digest_set_key(s->outdigest, s->key + cipher_keylength(s->incipher) + digest_keylength(s->indigest) + cipher_keylength(s->outcipher), digest_keylength(s->outdigest)); if(!result) return false; } else { bool result - = cipher_set_counter_key(&s->outcipher, s->key) - && digest_set_key(&s->outdigest, s->key + cipher_keylength(&s->outcipher), digest_keylength(&s->outdigest)); + = cipher_set_counter_key(s->outcipher, s->key) + && digest_set_key(s->outdigest, s->key + cipher_keylength(s->outcipher), digest_keylength(s->outdigest)); if(!result) return false; } @@ -398,7 +400,7 @@ static bool receive_handshake(sptps_t *s, const char *data, uint16_t len) { return true; // TODO: split ACK into a VERify and ACK? default: - return error(s, EIO, "Invalid session state"); + return error(s, EIO, "Invalid session state %d", s->state); } } @@ -413,7 +415,7 @@ bool sptps_verify_datagram(sptps_t *s, const char *data, size_t len) { memcpy(buffer, &netlen, 2); memcpy(buffer + 2, data, len); - return digest_verify(&s->indigest, buffer, len - 14, buffer + len - 14); + return digest_verify(s->indigest, buffer, len - 14, buffer + len - 14); } // Receive incoming data, datagram version. @@ -447,7 +449,7 @@ static bool sptps_receive_data_datagram(sptps_t *s, const char *data, size_t len memcpy(buffer, &netlen, 2); memcpy(buffer + 2, data, len); - if(!digest_verify(&s->indigest, buffer, len - 14, buffer + len - 14)) + if(!digest_verify(s->indigest, buffer, len - 14, buffer + len - 14)) return error(s, EIO, "Invalid HMAC"); // Replay protection using a sliding window of configurable size. @@ -491,8 +493,9 @@ static bool sptps_receive_data_datagram(sptps_t *s, const char *data, size_t len // Decrypt. memcpy(&seqno, buffer + 2, 4); - cipher_set_counter(&s->incipher, &seqno, sizeof seqno); - if(!cipher_counter_xor(&s->incipher, buffer + 6, len - 4, buffer + 6)) + if(!cipher_set_counter(s->incipher, &seqno, sizeof seqno)) + return false; + if(!cipher_counter_xor(s->incipher, buffer + 6, len - 4, buffer + 6)) return false; // Append a NULL byte for safety. @@ -509,7 +512,7 @@ static bool sptps_receive_data_datagram(sptps_t *s, const char *data, size_t len if(!receive_handshake(s, buffer + 7, len - 21)) return false; } else { - return error(s, EIO, "Invalid record type"); + return error(s, EIO, "Invalid record type %d", type); } return true; @@ -517,6 +520,9 @@ static bool sptps_receive_data_datagram(sptps_t *s, const char *data, size_t len // Receive incoming data. Check if it contains a complete record, if so, handle it. bool sptps_receive_data(sptps_t *s, const char *data, size_t len) { + if(!s->state) + return error(s, EIO, "Invalid session state zero"); + if(s->datagram) return sptps_receive_data_datagram(s, data, len); @@ -540,7 +546,7 @@ bool sptps_receive_data(sptps_t *s, const char *data, size_t len) { // Decrypt the length bytes if(s->instate) { - if(!cipher_counter_xor(&s->incipher, s->inbuf + 4, 2, &s->reclen)) + if(!cipher_counter_xor(s->incipher, s->inbuf + 4, 2, &s->reclen)) return false; } else { memcpy(&s->reclen, s->inbuf + 4, 2); @@ -578,10 +584,10 @@ bool sptps_receive_data(sptps_t *s, const char *data, size_t len) { // Check HMAC and decrypt. if(s->instate) { - if(!digest_verify(&s->indigest, s->inbuf, s->reclen + 7UL, s->inbuf + s->reclen + 7UL)) + if(!digest_verify(s->indigest, s->inbuf, s->reclen + 7UL, s->inbuf + s->reclen + 7UL)) return error(s, EIO, "Invalid HMAC"); - if(!cipher_counter_xor(&s->incipher, s->inbuf + 6UL, s->reclen + 1UL, s->inbuf + 6UL)) + if(!cipher_counter_xor(s->incipher, s->inbuf + 6UL, s->reclen + 1UL, s->inbuf + 6UL)) return false; } @@ -599,7 +605,7 @@ bool sptps_receive_data(sptps_t *s, const char *data, size_t len) { if(!receive_handshake(s, s->inbuf + 7, s->reclen)) return false; } else { - return error(s, EIO, "Invalid record type"); + return error(s, EIO, "Invalid record type %d", type); } s->buflen = 4; @@ -609,7 +615,7 @@ bool sptps_receive_data(sptps_t *s, const char *data, size_t len) { } // Start a SPTPS session. -bool sptps_start(sptps_t *s, void *handle, bool initiator, bool datagram, ecdsa_t mykey, ecdsa_t hiskey, const char *label, size_t labellen, send_data_t send_data, receive_record_t receive_record) { +bool sptps_start(sptps_t *s, void *handle, bool initiator, bool datagram, ecdsa_t *mykey, ecdsa_t *hiskey, const char *label, size_t labellen, send_data_t send_data, receive_record_t receive_record) { // Initialise struct sptps memset(s, 0, sizeof *s); @@ -651,11 +657,11 @@ bool sptps_start(sptps_t *s, void *handle, bool initiator, bool datagram, ecdsa_ // Stop a SPTPS session. bool sptps_stop(sptps_t *s) { // Clean up any resources. - cipher_close(&s->incipher); - cipher_close(&s->outcipher); - digest_close(&s->indigest); - digest_close(&s->outdigest); - ecdh_free(&s->ecdh); + cipher_close(s->incipher); + cipher_close(s->outcipher); + digest_close(s->indigest); + digest_close(s->outdigest); + ecdh_free(s->ecdh); free(s->inbuf); free(s->mykex); free(s->hiskex); diff --git a/src/sptps.h b/src/sptps.h index 1fead07..3a8e65f 100644 --- a/src/sptps.h +++ b/src/sptps.h @@ -35,10 +35,10 @@ #define SPTPS_CLOSE 130 // Application closed the connection // Key exchange states -#define SPTPS_KEX 0 // Waiting for the first Key EXchange record -#define SPTPS_SECONDARY_KEX 1 // Ready to receive a secondary Key EXchange record -#define SPTPS_SIG 2 // Waiting for a SIGnature record -#define SPTPS_ACK 3 // Waiting for an ACKnowledgement record +#define SPTPS_KEX 1 // Waiting for the first Key EXchange record +#define SPTPS_SECONDARY_KEX 2 // Ready to receive a secondary Key EXchange record +#define SPTPS_SIG 3 // Waiting for a SIGnature record +#define SPTPS_ACK 4 // Waiting for an ACKnowledgement record typedef bool (*send_data_t)(void *handle, uint8_t type, const char *data, size_t len); typedef bool (*receive_record_t)(void *handle, uint8_t type, const char *data, uint16_t len); @@ -53,8 +53,8 @@ typedef struct sptps { uint16_t reclen; bool instate; - cipher_t incipher; - digest_t indigest; + cipher_t *incipher; + digest_t *indigest; uint32_t inseqno; uint32_t received; unsigned int replaywin; @@ -62,13 +62,13 @@ typedef struct sptps { char *late; bool outstate; - cipher_t outcipher; - digest_t outdigest; + cipher_t *outcipher; + digest_t *outdigest; uint32_t outseqno; - ecdsa_t mykey; - ecdsa_t hiskey; - ecdh_t ecdh; + ecdsa_t *mykey; + ecdsa_t *hiskey; + ecdh_t *ecdh; char *mykex; char *hiskex; @@ -85,7 +85,7 @@ extern unsigned int sptps_replaywin; extern void sptps_log_quiet(sptps_t *s, int s_errno, const char *format, va_list ap); extern void sptps_log_stderr(sptps_t *s, int s_errno, const char *format, va_list ap); extern void (*sptps_log)(sptps_t *s, int s_errno, const char *format, va_list ap); -extern bool sptps_start(sptps_t *s, void *handle, bool initiator, bool datagram, ecdsa_t mykey, ecdsa_t hiskey, const char *label, size_t labellen, send_data_t send_data, receive_record_t receive_record); +extern bool sptps_start(sptps_t *s, void *handle, bool initiator, bool datagram, ecdsa_t *mykey, ecdsa_t *hiskey, const char *label, size_t labellen, send_data_t send_data, receive_record_t receive_record); extern bool sptps_stop(sptps_t *s); extern bool sptps_send_record(sptps_t *s, uint8_t type, const char *data, uint16_t len); extern bool sptps_receive_data(sptps_t *s, const char *data, size_t len); diff --git a/src/sptps_test.c b/src/sptps_test.c index 2a9fca0..2ce9804 100644 --- a/src/sptps_test.c +++ b/src/sptps_test.c @@ -1,6 +1,6 @@ /* sptps_test.c -- Simple Peer-to-Peer Security test program - Copyright (C) 2011-2012 Guus Sliepen , + Copyright (C) 2011-2013 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 @@ -31,7 +31,7 @@ bool send_meta(void *c, const char *msg , int len) { return false; } char *logfilename = NULL; struct timeval now; -ecdsa_t mykey, hiskey; +ecdsa_t *mykey, *hiskey; static bool send_data(void *handle, uint8_t type, const char *data, size_t len) { char hex[len * 2 + 1]; @@ -143,12 +143,12 @@ int main(int argc, char *argv[]) { crypto_init(); FILE *fp = fopen(argv[1], "r"); - if(!ecdsa_read_pem_private_key(&mykey, fp)) + if(!(mykey = ecdsa_read_pem_private_key(fp))) return 1; fclose(fp); fp = fopen(argv[2], "r"); - if(!ecdsa_read_pem_public_key(&hiskey, fp)) + if(!(hiskey = ecdsa_read_pem_public_key(fp))) return 1; fclose(fp); diff --git a/src/subnet.c b/src/subnet.c index 12ca03c..3b98030 100644 --- a/src/subnet.c +++ b/src/subnet.c @@ -79,7 +79,7 @@ void free_subnet_tree(splay_tree_t *subnet_tree) { /* Allocating and freeing space for subnets */ subnet_t *new_subnet(void) { - return xmalloc_and_zero(sizeof(subnet_t)); + return xzalloc(sizeof(subnet_t)); } void free_subnet(subnet_t *subnet) { @@ -204,7 +204,7 @@ void subnet_update(node_t *owner, subnet_t *subnet, bool up) { // Prepare environment variables to be passed to the script - char *envp[9] = {NULL}; + char *envp[10] = {NULL}; xasprintf(&envp[0], "NETNAME=%s", netname ? : ""); xasprintf(&envp[1], "DEVICE=%s", device ? : ""); xasprintf(&envp[2], "INTERFACE=%s", iface ? : ""); @@ -219,6 +219,8 @@ void subnet_update(node_t *owner, subnet_t *subnet, bool up) { free(address); } + xasprintf(&envp[8], "NAME=%s", myself->name); + name = up ? "subnet-up" : "subnet-down"; if(!subnet) { @@ -260,7 +262,7 @@ void subnet_update(node_t *owner, subnet_t *subnet, bool up) { } } - for(int i = 0; envp[i] && i < 8; i++) + for(int i = 0; envp[i] && i < 9; i++) free(envp[i]); } diff --git a/system.h b/src/system.h similarity index 91% rename from system.h rename to src/system.h index c688622..7180b87 100644 --- a/system.h +++ b/src/system.h @@ -1,7 +1,7 @@ /* system.h -- system headers Copyright (C) 1998-2005 Ivo Timmermans - 2003-2009 Guus Sliepen + 2003-2013 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 @@ -21,7 +21,7 @@ #ifndef __TINC_SYSTEM_H__ #define __TINC_SYSTEM_H__ -#include "config.h" +#include "../config.h" #include "have.h" @@ -37,7 +37,7 @@ typedef int bool; /* Other functions */ -#include "src/dropin.h" +#include "dropin.h" #ifndef HAVE_SOCKLEN_T typedef int socklen_t; diff --git a/src/tincctl.c b/src/tincctl.c index e022cdd..55e14e5 100644 --- a/src/tincctl.c +++ b/src/tincctl.c @@ -29,8 +29,10 @@ #include "xalloc.h" #include "protocol.h" #include "control_common.h" +#include "crypto.h" #include "ecdsagen.h" #include "info.h" +#include "invitation.h" #include "names.h" #include "rsagen.h" #include "utils.h" @@ -38,7 +40,9 @@ #include "top.h" #ifdef HAVE_MINGW -#define mkdir(a, b) mkdir(a) +#define SCRIPTEXTENSION ".bat" +#else +#define SCRIPTEXTENSION "" #endif static char **orig_argv; @@ -52,19 +56,21 @@ static bool show_version = false; static char *name = NULL; static char controlcookie[1025]; -static char *tinc_conf = NULL; -static char *hosts_dir = NULL; +char *tinc_conf = NULL; +char *hosts_dir = NULL; struct timeval now; // Horrible global variables... static int pid = 0; -static int fd = -1; -static char line[4096]; +int fd = -1; +char line[4096]; static int code; static int req; static int result; static bool force = false; -static bool tty = true; +bool tty = true; +bool confbasegiven = false; +bool netnamegiven = false; #ifdef HAVE_MINGW static struct WSAData wsa_state; @@ -72,19 +78,11 @@ static struct WSAData wsa_state; static struct option const long_options[] = { {"config", required_argument, NULL, 'c'}, - {"debug", optional_argument, NULL, 0}, - {"no-detach", no_argument, NULL, 0}, - {"mlock", no_argument, NULL, 0}, {"net", required_argument, NULL, 'n'}, {"help", no_argument, NULL, 1}, {"version", no_argument, NULL, 2}, - {"pidfile", required_argument, NULL, 5}, - {"logfile", required_argument, NULL, 0}, - {"bypass-security", no_argument, NULL, 0}, - {"chroot", no_argument, NULL, 0}, - {"user", required_argument, NULL, 0}, - {"option", required_argument, NULL, 0}, - {"force", no_argument, NULL, 6}, + {"pidfile", required_argument, NULL, 3}, + {"force", no_argument, NULL, 4}, {NULL, 0, NULL, 0} }; @@ -118,7 +116,7 @@ static void usage(bool status) { " del VARIABLE [VALUE] Remove VARIABLE [only ones with watching VALUE]\n" " start [tincd options] Start tincd.\n" " stop Stop tincd.\n" - " restart Restart tincd.\n" + " restart [tincd options] Restart tincd.\n" " reload Partially reload configuration of running tincd.\n" " pid Show PID of currently running tincd.\n" " generate-keys [bits] Generate new RSA and ECDSA public/private keypairs.\n" @@ -145,6 +143,8 @@ static void usage(bool status) { " import [--force] Import host configuration file(s) from standard input\n" " exchange [--force] Same as export followed by import\n" " exchange-all [--force] Same as export-all followed by import\n" + " invite NODE [...] Generate an invitation for NODE\n" + " join INVITATION Join a VPN using an INVITIATION\n" "\n"); printf("Report bugs to tinc@tinc-vpn.org.\n"); } @@ -154,13 +154,14 @@ static bool parse_options(int argc, char **argv) { int r; int option_index = 0; - while((r = getopt_long(argc, argv, "c:n:Dd::Lo:RU:", long_options, &option_index)) != EOF) { + while((r = getopt_long(argc, argv, "+c:n:", long_options, &option_index)) != EOF) { switch (r) { case 0: /* long option */ break; case 'c': /* config file */ confbase = xstrdup(optarg); + confbasegiven = true; break; case 'n': /* net name given */ @@ -175,11 +176,11 @@ static bool parse_options(int argc, char **argv) { show_version = true; break; - case 5: /* open control socket here */ + case 3: /* open control socket here */ pidfilename = xstrdup(optarg); break; - case 6: /* force */ + case 4: /* force */ force = true; break; @@ -210,6 +211,23 @@ static bool parse_options(int argc, char **argv) { return true; } +/* Open a file with the desired permissions, minus the umask. + Also, if we want to create an executable file, we call fchmod() + to set the executable bits. */ + +FILE *fopenmask(const char *filename, const char *mode, mode_t perms) { + mode_t mask = umask(0); + perms &= ~mask; + umask(~perms); + FILE *f = fopen(filename, mode); +#ifdef HAVE_FCHMOD + if((perms & 0444) && f) + fchmod(fileno(f), perms); +#endif + umask(mask); + return f; +} + static void disable_old_keys(const char *filename, const char *what) { char tmpfile[PATH_MAX] = ""; char buf[1024]; @@ -224,7 +242,9 @@ static void disable_old_keys(const char *filename, const char *what) { snprintf(tmpfile, sizeof tmpfile, "%s.tmp", filename); - w = fopen(tmpfile, "w"); + struct stat st = {.st_mode = 0600}; + fstat(fileno(r), &st); + w = fopenmask(tmpfile, "w", st.st_mode); while(fgets(buf, sizeof buf, r)) { if(!block && !strncmp(buf, "-----BEGIN ", 11)) { @@ -287,7 +307,7 @@ static void disable_old_keys(const char *filename, const char *what) { unlink(tmpfile); } -static FILE *ask_and_open(const char *filename, const char *what, const char *mode, bool ask) { +static FILE *ask_and_open(const char *filename, const char *what, const char *mode, bool ask, mode_t perms) { FILE *r; char *directory; char buf[PATH_MAX]; @@ -296,13 +316,11 @@ static FILE *ask_and_open(const char *filename, const char *what, const char *mo /* Check stdin and stdout */ if(ask && tty) { /* Ask for a file and/or directory name. */ - fprintf(stdout, "Please enter a file to save %s to [%s]: ", - what, filename); + fprintf(stdout, "Please enter a file to save %s to [%s]: ", what, filename); fflush(stdout); if(fgets(buf, sizeof buf, stdin) == NULL) { - fprintf(stderr, "Error while reading stdin: %s\n", - strerror(errno)); + fprintf(stderr, "Error while reading stdin: %s\n", strerror(errno)); return NULL; } @@ -325,13 +343,11 @@ static FILE *ask_and_open(const char *filename, const char *what, const char *mo filename = buf2; } - umask(0077); /* Disallow everything for group and other */ - disable_old_keys(filename, what); /* Open it first to keep the inode busy */ - r = fopen(filename, mode); + r = fopenmask(filename, mode, perms); if(!r) { fprintf(stderr, "Error opening file `%s': %s\n", filename, strerror(errno)); @@ -346,31 +362,31 @@ static FILE *ask_and_open(const char *filename, const char *what, const char *mo them in. */ static bool ecdsa_keygen(bool ask) { - ecdsa_t key; + ecdsa_t *key; FILE *f; char *pubname, *privname; fprintf(stderr, "Generating ECDSA keypair:\n"); - if(!ecdsa_generate(&key)) { + if(!(key = ecdsa_generate())) { fprintf(stderr, "Error during key generation!\n"); return false; } else fprintf(stderr, "Done.\n"); xasprintf(&privname, "%s" SLASH "ecdsa_key.priv", confbase); - f = ask_and_open(privname, "private ECDSA key", "a", ask); + f = ask_and_open(privname, "private ECDSA key", "a", ask, 0600); free(privname); if(!f) return false; -#ifdef HAVE_FCHMOD - /* Make it unreadable for others. */ - fchmod(fileno(f), 0600); -#endif - - ecdsa_write_pem_private_key(&key, f); + if(!ecdsa_write_pem_private_key(key, f)) { + fprintf(stderr, "Error writing private key!\n"); + ecdsa_free(key); + fclose(f); + return false; + } fclose(f); @@ -379,17 +395,18 @@ static bool ecdsa_keygen(bool ask) { else xasprintf(&pubname, "%s" SLASH "ecdsa_key.pub", confbase); - f = ask_and_open(pubname, "public ECDSA key", "a", ask); + f = ask_and_open(pubname, "public ECDSA key", "a", ask, 0666); free(pubname); if(!f) return false; - char *pubkey = ecdsa_get_base64_public_key(&key); + char *pubkey = ecdsa_get_base64_public_key(key); fprintf(f, "ECDSAPublicKey = %s\n", pubkey); free(pubkey); fclose(f); + ecdsa_free(key); return true; } @@ -399,31 +416,31 @@ static bool ecdsa_keygen(bool ask) { them in. */ static bool rsa_keygen(int bits, bool ask) { - rsa_t key; + rsa_t *key; FILE *f; char *pubname, *privname; fprintf(stderr, "Generating %d bits keys:\n", bits); - if(!rsa_generate(&key, bits, 0x10001)) { + if(!(key = rsa_generate(bits, 0x10001))) { fprintf(stderr, "Error during key generation!\n"); return false; } else fprintf(stderr, "Done.\n"); xasprintf(&privname, "%s" SLASH "rsa_key.priv", confbase); - f = ask_and_open(privname, "private RSA key", "a", ask); + f = ask_and_open(privname, "private RSA key", "a", ask, 0600); free(privname); if(!f) return false; -#ifdef HAVE_FCHMOD - /* Make it unreadable for others. */ - fchmod(fileno(f), 0600); -#endif - - rsa_write_pem_private_key(&key, f); + if(!rsa_write_pem_private_key(key, f)) { + fprintf(stderr, "Error writing private key!\n"); + fclose(f); + rsa_free(key); + return false; + } fclose(f); @@ -432,25 +449,34 @@ static bool rsa_keygen(int bits, bool ask) { else xasprintf(&pubname, "%s" SLASH "rsa_key.pub", confbase); - f = ask_and_open(pubname, "public RSA key", "a", ask); + f = ask_and_open(pubname, "public RSA key", "a", ask, 0666); free(pubname); if(!f) return false; - rsa_write_pem_public_key(&key, f); + if(!rsa_write_pem_public_key(key, f)) { + fprintf(stderr, "Error writing public key!\n"); + fclose(f); + rsa_free(key); + return false; + } fclose(f); + rsa_free(key); return true; } -static char buffer[4096]; -static size_t blen = 0; +char buffer[4096]; +size_t blen = 0; bool recvline(int fd, char *line, size_t len) { char *newline = NULL; + if(!fd) + abort(); + while(!(newline = memchr(buffer, '\n', blen))) { int result = recv(fd, buffer + blen, sizeof buffer - blen, 0); if(result == -1 && errno == EINTR) @@ -473,7 +499,10 @@ bool recvline(int fd, char *line, size_t len) { return true; } -static bool recvdata(int fd, char *data, size_t len) { +bool recvdata(int fd, char *data, size_t len) { + if(len == -1) + len = blen; + while(blen < len) { int result = recv(fd, buffer + blen, sizeof buffer - blen, 0); if(result == -1 && errno == EINTR) @@ -623,7 +652,7 @@ static bool remove_service(void) { } #endif -static bool connect_tincd(bool verbose) { +bool connect_tincd(bool verbose) { if(fd >= 0) { fd_set r; FD_ZERO(&r); @@ -775,7 +804,7 @@ static int cmd_start(int argc, char *argv[]) { c = "tincd"; int nargc = 0; - char **nargv = xmalloc_and_zero((optind + argc) * sizeof *nargv); + char **nargv = xzalloc((optind + argc) * sizeof *nargv); nargv[nargc++] = c; for(int i = 1; i < optind; i++) @@ -800,8 +829,16 @@ static int cmd_start(int argc, char *argv[]) { free(nargv); - int status = -1; - if(waitpid(pid, &status, 0) != pid || !WIFEXITED(status) || WEXITSTATUS(status)) { + int status = -1, result; +#ifdef SIGINT + signal(SIGINT, SIG_IGN); +#endif + result = waitpid(pid, &status, 0); +#ifdef SIGINT + signal(SIGINT, SIG_DFL); +#endif + + if(result != pid || !WIFEXITED(status) || WEXITSTATUS(status)) { fprintf(stderr, "Error starting %s\n", c); return 1; } @@ -849,7 +886,7 @@ static int cmd_stop(int argc, char *argv[]) { } static int cmd_restart(int argc, char *argv[]) { - cmd_stop(argc, argv); + cmd_stop(1, argv); return cmd_start(argc, argv); } @@ -1165,6 +1202,13 @@ static int cmd_pcap(int argc, char *argv[]) { return 0; } +#ifdef SIGINT +static void sigint_handler(int sig) { + fprintf(stderr, "\n"); + shutdown(fd, SHUT_RDWR); +} +#endif + static int cmd_log(int argc, char *argv[]) { if(argc > 2) { fprintf(stderr, "Too many arguments!\n"); @@ -1174,7 +1218,18 @@ static int cmd_log(int argc, char *argv[]) { if(!connect_tincd(true)) return 1; +#ifdef SIGINT + signal(SIGINT, sigint_handler); +#endif + logcontrol(fd, stdout, argc > 1 ? atoi(argv[1]) : -1); + +#ifdef SIGINT + signal(SIGINT, SIG_DFL); +#endif + + close(fd); + fd = -1; return 0; } @@ -1191,14 +1246,14 @@ static int cmd_pid(int argc, char *argv[]) { return 0; } -static int rstrip(char *value) { +int rstrip(char *value) { int len = strlen(value); while(len && strchr("\t\r\n ", value[len - 1])) value[--len] = 0; return len; } -static char *get_my_name(bool verbose) { +char *get_my_name(bool verbose) { FILE *f = fopen(tinc_conf, "r"); if(!f) { if(verbose) @@ -1233,22 +1288,14 @@ static char *get_my_name(bool verbose) { return NULL; } -#define VAR_SERVER 1 /* Should be in tinc.conf */ -#define VAR_HOST 2 /* Can be in host config file */ -#define VAR_MULTIPLE 4 /* Multiple statements allowed */ -#define VAR_OBSOLETE 8 /* Should not be used anymore */ - -static struct { - const char *name; - int type; -} const variables[] = { +const var_t variables[] = { /* Server configuration */ {"AddressFamily", VAR_SERVER}, - {"AutoConnect", VAR_SERVER}, + {"AutoConnect", VAR_SERVER | VAR_SAFE}, {"BindToAddress", VAR_SERVER | VAR_MULTIPLE}, {"BindToInterface", VAR_SERVER}, - {"Broadcast", VAR_SERVER}, - {"ConnectTo", VAR_SERVER | VAR_MULTIPLE}, + {"Broadcast", VAR_SERVER | VAR_SAFE}, + {"ConnectTo", VAR_SERVER | VAR_MULTIPLE | VAR_SAFE}, {"DecrementTTL", VAR_SERVER}, {"Device", VAR_SERVER}, {"DeviceType", VAR_SERVER}, @@ -1263,9 +1310,10 @@ static struct { {"KeyExpire", VAR_SERVER}, {"LocalDiscovery", VAR_SERVER}, {"MACExpire", VAR_SERVER}, + {"MaxConnectionBurst", VAR_SERVER}, {"MaxOutputBufferSize", VAR_SERVER}, {"MaxTimeout", VAR_SERVER}, - {"Mode", VAR_SERVER}, + {"Mode", VAR_SERVER | VAR_SAFE}, {"Name", VAR_SERVER}, {"PingInterval", VAR_SERVER}, {"PingTimeout", VAR_SERVER}, @@ -1298,9 +1346,9 @@ static struct { {"Port", VAR_HOST}, {"PublicKey", VAR_HOST | VAR_OBSOLETE}, {"PublicKeyFile", VAR_SERVER | VAR_HOST | VAR_OBSOLETE}, - {"Subnet", VAR_HOST | VAR_MULTIPLE}, + {"Subnet", VAR_HOST | VAR_MULTIPLE | VAR_SAFE}, {"TCPOnly", VAR_SERVER | VAR_HOST}, - {"Weight", VAR_HOST}, + {"Weight", VAR_HOST | VAR_SAFE}, {NULL, 0} }; @@ -1373,6 +1421,7 @@ static int cmd_config(int argc, char *argv[]) { /* Some simple checks. */ bool found = false; + bool warnonremove = false; for(int i = 0; variables[i].name; i++) { if(strcasecmp(variables[i].name, variable)) @@ -1411,6 +1460,16 @@ static int cmd_config(int argc, char *argv[]) { return 1; } + /* Change "add" into "set" for variables that do not allow multiple occurences. + Turn on warnings when it seems variables might be removed unintentionally. */ + + if(action == 1 && !(variables[i].type & VAR_MULTIPLE)) { + warnonremove = true; + action = 0; + } else if(action == 0 && (variables[i].type & VAR_MULTIPLE)) { + warnonremove = true; + } + break; } @@ -1437,19 +1496,8 @@ static int cmd_config(int argc, char *argv[]) { FILE *f = fopen(filename, "r"); if(!f) { - if(action < 0 || errno != ENOENT) { - fprintf(stderr, "Could not open configuration file %s: %s\n", filename, strerror(errno)); - return 1; - } - - // If it doesn't exist, create it. - f = fopen(filename, "a+"); - if(!f) { - fprintf(stderr, "Could not create configuration file %s: %s\n", filename, strerror(errno)); - return 1; - } else { - fprintf(stderr, "Created configuration file %s.\n", filename); - } + fprintf(stderr, "Could not open configuration file %s: %s\n", filename, strerror(errno)); + return 1; } char *tmpfile = NULL; @@ -1504,9 +1552,14 @@ static int cmd_config(int argc, char *argv[]) { } // Set } else if(action == 0) { + // Warn if "set" was used for variables that can occur multiple times + if(warnonremove && strcasecmp(bvalue, value)) + fprintf(stderr, "Warning: removing %s = %s\n", variable, bvalue); + // Already set? Delete the rest... if(set) continue; + // Otherwise, replace. if(fprintf(tf, "%s = %s\n", variable, value) < 0) { fprintf(stderr, "Error writing to temporary file %s: %s\n", tmpfile, strerror(errno)); @@ -1603,6 +1656,64 @@ bool check_id(const char *name) { return true; } +static bool try_bind(int port) { + struct addrinfo *ai = NULL; + struct addrinfo hint = { + .ai_flags = AI_PASSIVE, + .ai_family = AF_UNSPEC, + .ai_socktype = SOCK_STREAM, + .ai_protocol = IPPROTO_TCP, + }; + + char portstr[16]; + snprintf(portstr, sizeof portstr, "%d", port); + + if(getaddrinfo(NULL, portstr, &hint, &ai) || !ai) + return false; + + while(ai) { + int fd = socket(ai->ai_family, SOCK_STREAM, IPPROTO_TCP); + if(!fd) + return false; + int result = bind(fd, ai->ai_addr, ai->ai_addrlen); + closesocket(fd); + if(result) + return false; + ai = ai->ai_next; + } + + return true; +} + +int check_port(char *name) { + if(try_bind(655)) + return 655; + + fprintf(stderr, "Warning: could not bind to port 655. "); + + for(int i = 0; i < 100; i++) { + int port = 0x1000 + (rand() & 0x7fff); + if(try_bind(port)) { + char *filename; + xasprintf(&filename, "%s" SLASH "hosts" SLASH "%s", confbase, name); + FILE *f = fopen(filename, "a"); + free(filename); + if(!f) { + fprintf(stderr, "Please change tinc's Port manually.\n"); + return 0; + } + + fprintf(f, "Port = %d\n", port); + fclose(f); + fprintf(stderr, "Tinc will instead listen on port %d.\n", port); + return port; + } + } + + fprintf(stderr, "Please change tinc's Port manually.\n"); + return 0; +} + static int cmd_init(int argc, char *argv[]) { if(!access(tinc_conf, F_OK)) { fprintf(stderr, "Configuration file %s already exists!\n", tinc_conf); @@ -1644,17 +1755,17 @@ static int cmd_init(int argc, char *argv[]) { return 1; } - if(mkdir(confdir, 0755) && errno != EEXIST) { - fprintf(stderr, "Could not create directory %s: %s\n", CONFDIR, strerror(errno)); + if(strcmp(confdir, confbase) && mkdir(confdir, 0755) && errno != EEXIST) { + fprintf(stderr, "Could not create directory %s: %s\n", confdir, strerror(errno)); return 1; } - if(mkdir(confbase, 0755) && errno != EEXIST) { + if(mkdir(confbase, 0777) && errno != EEXIST) { fprintf(stderr, "Could not create directory %s: %s\n", confbase, strerror(errno)); return 1; } - if(mkdir(hosts_dir, 0755) && errno != EEXIST) { + if(mkdir(hosts_dir, 0777) && errno != EEXIST) { fprintf(stderr, "Could not create directory %s: %s\n", hosts_dir, strerror(errno)); return 1; } @@ -1671,16 +1782,17 @@ static int cmd_init(int argc, char *argv[]) { if(!rsa_keygen(2048, false) || !ecdsa_keygen(false)) return 1; + check_port(name); + #ifndef HAVE_MINGW char *filename; xasprintf(&filename, "%s" SLASH "tinc-up", confbase); if(access(filename, F_OK)) { - FILE *f = fopen(filename, "w"); + FILE *f = fopenmask(filename, "w", 0777); if(!f) { fprintf(stderr, "Could not create file %s: %s\n", filename, strerror(errno)); return 1; } - fchmod(fileno(f), 0755); fprintf(f, "#!/bin/sh\n\necho 'Unconfigured tinc-up script, please edit!'\n\n#ifconfig $INTERFACE netmask \n"); fclose(f); } @@ -2008,6 +2120,8 @@ static const struct { {"import", cmd_import}, {"exchange", cmd_exchange}, {"exchange-all", cmd_exchange_all}, + {"invite", cmd_invite}, + {"join", cmd_join}, {NULL, NULL}, }; @@ -2060,7 +2174,7 @@ static char *complete_config(const char *text, int state) { if(dot) { if((variables[i].type & VAR_HOST) && !strncasecmp(variables[i].name, dot + 1, strlen(dot + 1))) { char *match; - xasprintf(&match, "%.*s.%s", dot - text, text, variables[i].name); + xasprintf(&match, "%.*s.%s", (int)(dot - text), text, variables[i].name); return match; } } else { @@ -2256,6 +2370,9 @@ int main(int argc, char *argv[]) { return 0; } + srand(time(NULL)); + crypto_init(); + tty = isatty(0) && isatty(1); if(optind >= argc) diff --git a/src/tincctl.h b/src/tincctl.h index 114b931..e636887 100644 --- a/src/tincctl.h +++ b/src/tincctl.h @@ -1,6 +1,6 @@ /* tincctl.h -- header for tincctl.c. - Copyright (C) 2011 Guus Sliepen + Copyright (C) 2011-2013 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 @@ -20,8 +20,35 @@ #ifndef __TINC_TINCCTL_H__ #define __TINC_TINCCTL_H__ +extern bool tty; +extern char line[4096]; +extern int fd; +extern char buffer[4096]; +extern size_t blen; +extern bool confbasegiven; +extern char *tinc_conf; +extern char *hosts_dir; + +#define VAR_SERVER 1 /* Should be in tinc.conf */ +#define VAR_HOST 2 /* Can be in host config file */ +#define VAR_MULTIPLE 4 /* Multiple statements allowed */ +#define VAR_OBSOLETE 8 /* Should not be used anymore */ +#define VAR_SAFE 16 /* Variable is safe when accepting invitations */ + +typedef struct { + const char *name; + int type; +} var_t; + +extern const var_t variables[]; + +extern int rstrip(char *value); +extern char *get_my_name(bool verbose); +extern bool connect_tincd(bool verbose); extern bool sendline(int fd, char *format, ...); extern bool recvline(int fd, char *line, size_t len); +extern int check_port(char *name); +extern FILE *fopenmask(const char *filename, const char *mode, mode_t perms); #endif diff --git a/src/tincd.c b/src/tincd.c index 333a207..3d6db8b 100644 --- a/src/tincd.c +++ b/src/tincd.c @@ -167,7 +167,9 @@ static bool parse_options(int argc, char **argv) { break; #endif - case 'd': /* inc debug level */ + case 'd': /* increase debug level */ + if(!optarg && optind < argc && *argv[optind] != '-') + optarg = argv[optind++]; if(optarg) debug_level = atoi(optarg); else @@ -214,6 +216,8 @@ static bool parse_options(int argc, char **argv) { case 4: /* write log entries to a file */ use_logfile = true; + if(!optarg && optind < argc && *argv[optind] != '-') + optarg = argv[optind++]; if(optarg) logfilename = xstrdup(optarg); break; @@ -231,6 +235,12 @@ static bool parse_options(int argc, char **argv) { } } + if(optind < argc) { + fprintf(stderr, "%s: unrecognized argument '%s'\n", argv[0], argv[optind]); + usage(true); + return false; + } + if(!netname && (netname = getenv("NETNAME"))) netname = xstrdup(netname); @@ -311,7 +321,7 @@ int main(int argc, char **argv) { if(show_version) { printf("%s version %s (built %s %s, protocol %d.%d)\n", PACKAGE, VERSION, __DATE__, __TIME__, PROT_MAJOR, PROT_MINOR); - printf("Copyright (C) 1998-2012 Ivo Timmermans, Guus Sliepen and others.\n" + printf("Copyright (C) 1998-2013 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" diff --git a/src/top.c b/src/top.c index 703391c..b1ab40c 100644 --- a/src/top.c +++ b/src/top.c @@ -108,7 +108,7 @@ static void update(int fd) { found = ns; break; } else { - found = xmalloc_and_zero(sizeof *found); + found = xzalloc(sizeof *found); found->name = xstrdup(name); list_insert_before(&node_list, node, found); changed = true; @@ -117,7 +117,7 @@ static void update(int fd) { } if(!found) { - found = xmalloc_and_zero(sizeof *found); + found = xzalloc(sizeof *found); found->name = xstrdup(name); list_insert_tail(&node_list, found); changed = true; diff --git a/src/utils.c b/src/utils.c index aefec8c..edaa354 100644 --- a/src/utils.c +++ b/src/utils.c @@ -1,7 +1,7 @@ /* utils.c -- gathering of some stupid small functions Copyright (C) 1999-2005 Ivo Timmermans - 2000-2012 Guus Sliepen + 2000-2013 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 @@ -24,7 +24,26 @@ #include "utils.h" static const char hexadecimals[] = "0123456789ABCDEF"; -static const char base64imals[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; +static const char base64_original[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; +static const char base64_urlsafe[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"; +static const char base64_decode[256] = { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, 62, -1, 63, + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, + -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, 63, + -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +}; static int charhex2bin(char c) { if(isdigit(c)) @@ -33,19 +52,6 @@ static int charhex2bin(char c) { return toupper(c) - 'A' + 10; } -static int charb64decode(char c) { - if(c >= 'a') - return c - 'a' + 26; - else if(c >= 'A') - return c - 'A'; - else if(c >= '0') - return c - '0' + 52; - else if(c == '+') - return 62; - else - return 63; -} - int hex2bin(const char *src, char *dst, int length) { int i; for(i = 0; i < length && isxdigit(src[i * 2]) && isxdigit(src[i * 2 + 1]); i++) @@ -68,8 +74,10 @@ int b64decode(const char *src, char *dst, int length) { unsigned char *udst = (unsigned char *)dst; for(i = 0; i < length / 3 * 4 && src[i]; i++) { - triplet |= charb64decode(src[i]) << (6 * (i & 3)); + triplet |= base64_decode[src[i] & 0xff] << (6 * (i & 3)); if((i & 3) == 3) { + if(triplet & 0xff000000U) + return 0; udst[0] = triplet & 0xff; triplet >>= 8; udst[1] = triplet & 0xff; triplet >>= 8; udst[2] = triplet; @@ -77,6 +85,8 @@ int b64decode(const char *src, char *dst, int length) { udst += 3; } } + if(triplet & 0xff000000U) + return 0; if((i & 3) == 3) { udst[0] = triplet & 0xff; triplet >>= 8; udst[1] = triplet & 0xff; @@ -89,7 +99,7 @@ int b64decode(const char *src, char *dst, int length) { } } -int b64encode(const char *src, char *dst, int length) { +static int b64encode_internal(const char *src, char *dst, int length, const char *alphabet) { uint32_t triplet; const unsigned char *usrc = (unsigned char *)src; int si = length / 3 * 3; @@ -98,16 +108,16 @@ int b64encode(const char *src, char *dst, int length) { switch(length % 3) { case 2: triplet = usrc[si] | usrc[si + 1] << 8; - dst[di] = base64imals[triplet & 63]; triplet >>= 6; - dst[di + 1] = base64imals[triplet & 63]; triplet >>= 6; - dst[di + 2] = base64imals[triplet]; + dst[di] = alphabet[triplet & 63]; triplet >>= 6; + dst[di + 1] = alphabet[triplet & 63]; triplet >>= 6; + dst[di + 2] = alphabet[triplet]; dst[di + 3] = 0; length = di + 2; break; case 1: triplet = usrc[si]; - dst[di] = base64imals[triplet & 63]; triplet >>= 6; - dst[di + 1] = base64imals[triplet]; + dst[di] = alphabet[triplet & 63]; triplet >>= 6; + dst[di + 1] = alphabet[triplet]; dst[di + 2] = 0; length = di + 1; break; @@ -121,15 +131,23 @@ int b64encode(const char *src, char *dst, int length) { di -= 4; si -= 3; triplet = usrc[si] | usrc[si + 1] << 8 | usrc[si + 2] << 16; - dst[di] = base64imals[triplet & 63]; triplet >>= 6; - dst[di + 1] = base64imals[triplet & 63]; triplet >>= 6; - dst[di + 2] = base64imals[triplet & 63]; triplet >>= 6; - dst[di + 3] = base64imals[triplet]; + dst[di] = alphabet[triplet & 63]; triplet >>= 6; + dst[di + 1] = alphabet[triplet & 63]; triplet >>= 6; + dst[di + 2] = alphabet[triplet & 63]; triplet >>= 6; + dst[di + 3] = alphabet[triplet]; } return length; } +int b64encode(const char *src, char *dst, int length) { + return b64encode_internal(src, dst, length, base64_original); +} + +int b64encode_urlsafe(const char *src, char *dst, int length) { + return b64encode_internal(src, dst, length, base64_urlsafe); +} + #if defined(HAVE_MINGW) || defined(HAVE_CYGWIN) #ifdef HAVE_CYGWIN #include diff --git a/src/utils.h b/src/utils.h index 04e478a..85d6bf2 100644 --- a/src/utils.h +++ b/src/utils.h @@ -1,7 +1,7 @@ /* utils.h -- header file for utils.c Copyright (C) 1999-2005 Ivo Timmermans - 2000-2011 Guus Sliepen + 2000-2013 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 @@ -25,6 +25,7 @@ extern int hex2bin(const char *src, char *dst, int length); extern int bin2hex(const char *src, char *dst, int length); extern int b64encode(const char *src, char *dst, int length); +extern int b64encode_urlsafe(const char *src, char *dst, int length); extern int b64decode(const char *src, char *dst, int length); #ifdef HAVE_MINGW diff --git a/src/xalloc.h b/src/xalloc.h index 42d0d95..28960fb 100644 --- a/src/xalloc.h +++ b/src/xalloc.h @@ -1,7 +1,7 @@ /* xalloc.h -- malloc and related fuctions with out of memory checking Copyright (C) 1990, 91, 92, 93, 94, 95, 96, 97 Free Software Foundation, Inc. - Copyright (C) 2011 Guus Sliepen + Copyright (C) 2011-2013 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 @@ -20,6 +20,7 @@ #ifndef __TINC_XALLOC_H__ #define __TINC_XALLOC_H__ +static inline void *xmalloc(size_t n) __attribute__ ((__malloc__)); static inline void *xmalloc(size_t n) { void *p = malloc(n); if(!p) @@ -27,7 +28,8 @@ static inline void *xmalloc(size_t n) { return p; } -static inline void *xmalloc_and_zero(size_t n) { +static inline void *xzalloc(size_t n) __attribute__ ((__malloc__)); +static inline void *xzalloc(size_t n) { void *p = calloc(1, n); if(!p) abort(); @@ -41,6 +43,7 @@ static inline void *xrealloc(void *p, size_t n) { return p; } +static inline char *xstrdup(const char *s) __attribute__ ((__malloc__)); static inline char *xstrdup(const char *s) { char *p = strdup(s); if(!p) @@ -49,12 +52,21 @@ static inline char *xstrdup(const char *s) { } static inline int xvasprintf(char **strp, const char *fmt, va_list ap) { +#ifdef HAVE_MINGW + char buf[1024]; + int result = vsnprintf(buf, sizeof buf, fmt, ap); + if(result < 0) + abort(); + *strp = xstrdup(buf); +#else int result = vasprintf(strp, fmt, ap); if(result < 0) abort(); +#endif return result; } +static inline int xasprintf(char **strp, const char *fmt, ...) __attribute__ ((__format__(printf, 2, 3))); static inline int xasprintf(char **strp, const char *fmt, ...) { va_list ap; va_start(ap, fmt); From 60cff3039bf8fbae76a2806a2a9b3c6ad813584d Mon Sep 17 00:00:00 2001 From: Guus Sliepen Date: Mon, 26 Aug 2019 13:44:51 +0200 Subject: [PATCH 07/13] Import Upstream version 1.1~pre9 --- ChangeLog | 48 ++ Makefile.am | 2 +- Makefile.in | 14 +- NEWS | 28 + README | 6 +- aclocal.m4 | 154 +++-- config.h.in | 3 - configure | 260 ++++----- configure.ac | 8 +- doc/Makefile.am | 5 +- doc/Makefile.in | 43 +- doc/tinc.conf.5.in | 18 +- doc/tinc.info | 115 ++-- doc/tinc.texi | 27 +- gui/Makefile.in | 2 +- m4/Makefile.in | 2 +- src/Makefile.am | 23 +- src/Makefile.in | 113 ++-- src/bsd/.deps/device.Po | 1 - src/bsd/.deps/tunemu.Po | 1 - src/control.c | 41 ++ src/cygwin/.deps/device.Po | 1 - src/gcrypt/.deps/cipher.Po | 1 - src/gcrypt/.deps/crypto.Po | 1 - src/gcrypt/.deps/digest.Po | 1 - src/gcrypt/.deps/ecdh.Po | 1 - src/gcrypt/.deps/ecdsa.Po | 1 - src/gcrypt/.deps/ecdsagen.Po | 1 - src/gcrypt/.deps/prf.Po | 1 - src/gcrypt/.deps/rsa.Po | 1 - src/gcrypt/.deps/rsagen.Po | 1 - src/gcrypt/cipher.h | 52 -- src/gcrypt/rsa.h | 39 -- src/gcrypt/rsagen.h | 29 - src/graph.c | 2 +- src/invitation.c | 179 ++++-- src/linux/.deps/.dirstamp | 0 src/linux/.deps/device.Po | 467 --------------- src/linux/.dirstamp | 0 src/linux/device.o | Bin 24392 -> 0 bytes src/mingw/.deps/device.Po | 1 - src/multicast_device.c | 5 +- src/names.c | 2 + src/names.h | 1 + src/net.c | 1 - src/net_packet.c | 1 - src/net_setup.c | 89 +-- src/net_socket.c | 49 +- src/openssl/.deps/.dirstamp | 0 src/openssl/.deps/cipher.Po | 454 --------------- src/openssl/.deps/crypto.Po | 482 ---------------- src/openssl/.deps/digest.Po | 458 --------------- src/openssl/.deps/ecdh.Po | 454 --------------- src/openssl/.deps/ecdsa.Po | 487 ---------------- src/openssl/.deps/ecdsagen.Po | 487 ---------------- src/openssl/.deps/prf.Po | 446 --------------- src/openssl/.deps/rsa.Po | 482 ---------------- src/openssl/.deps/rsagen.Po | 484 ---------------- src/openssl/.dirstamp | 0 src/openssl/cipher.c | 2 +- src/openssl/cipher.o | Bin 32864 -> 0 bytes src/openssl/crypto.o | Bin 8632 -> 0 bytes src/openssl/digest.o | Bin 21224 -> 0 bytes src/openssl/ecdh.o | Bin 14752 -> 0 bytes src/openssl/ecdsa.o | Bin 18632 -> 0 bytes src/openssl/ecdsagen.o | Bin 17728 -> 0 bytes src/openssl/prf.o | Bin 12576 -> 0 bytes src/openssl/rsa.o | Bin 19616 -> 0 bytes src/openssl/rsagen.o | Bin 18496 -> 0 bytes src/process.c | 68 --- src/process.h | 3 +- src/protocol_auth.c | 34 +- src/script.c | 126 +++++ src/{gcrypt/crypto.h => script.h} | 15 +- src/solaris/.deps/device.Po | 1 - src/sptps.c | 6 +- src/sptps_test.c | 117 +++- src/subnet.c | 2 +- src/tincctl.c | 33 +- src/tincd.c | 18 +- test-driver | 127 +++++ test/Makefile.am | 23 + test/Makefile.in | 908 ++++++++++++++++++++++++++++++ test/basic.test | 20 + test/commandline.test | 49 ++ test/executables.test | 8 + test/import-export.test | 64 +++ test/invite-join.test | 49 ++ test/ping.test | 58 ++ test/pong.c | 194 +++++++ test/sptps-basic.test | 32 ++ test/testlib.sh | 48 ++ test/variables.test | 88 +++ 93 files changed, 2731 insertions(+), 5437 deletions(-) delete mode 100644 src/bsd/.deps/device.Po delete mode 100644 src/bsd/.deps/tunemu.Po delete mode 100644 src/cygwin/.deps/device.Po delete mode 100644 src/gcrypt/.deps/cipher.Po delete mode 100644 src/gcrypt/.deps/crypto.Po delete mode 100644 src/gcrypt/.deps/digest.Po delete mode 100644 src/gcrypt/.deps/ecdh.Po delete mode 100644 src/gcrypt/.deps/ecdsa.Po delete mode 100644 src/gcrypt/.deps/ecdsagen.Po delete mode 100644 src/gcrypt/.deps/prf.Po delete mode 100644 src/gcrypt/.deps/rsa.Po delete mode 100644 src/gcrypt/.deps/rsagen.Po delete mode 100644 src/gcrypt/cipher.h delete mode 100644 src/gcrypt/rsa.h delete mode 100644 src/gcrypt/rsagen.h delete mode 100644 src/linux/.deps/.dirstamp delete mode 100644 src/linux/.deps/device.Po delete mode 100644 src/linux/.dirstamp delete mode 100644 src/linux/device.o delete mode 100644 src/mingw/.deps/device.Po delete mode 100644 src/openssl/.deps/.dirstamp delete mode 100644 src/openssl/.deps/cipher.Po delete mode 100644 src/openssl/.deps/crypto.Po delete mode 100644 src/openssl/.deps/digest.Po delete mode 100644 src/openssl/.deps/ecdh.Po delete mode 100644 src/openssl/.deps/ecdsa.Po delete mode 100644 src/openssl/.deps/ecdsagen.Po delete mode 100644 src/openssl/.deps/prf.Po delete mode 100644 src/openssl/.deps/rsa.Po delete mode 100644 src/openssl/.deps/rsagen.Po delete mode 100644 src/openssl/.dirstamp delete mode 100644 src/openssl/cipher.o delete mode 100644 src/openssl/crypto.o delete mode 100644 src/openssl/digest.o delete mode 100644 src/openssl/ecdh.o delete mode 100644 src/openssl/ecdsa.o delete mode 100644 src/openssl/ecdsagen.o delete mode 100644 src/openssl/prf.o delete mode 100644 src/openssl/rsa.o delete mode 100644 src/openssl/rsagen.o create mode 100644 src/script.c rename src/{gcrypt/crypto.h => script.h} (72%) delete mode 100644 src/solaris/.deps/device.Po create mode 100755 test-driver create mode 100644 test/Makefile.am create mode 100644 test/Makefile.in create mode 100755 test/basic.test create mode 100755 test/commandline.test create mode 100755 test/executables.test create mode 100755 test/import-export.test create mode 100755 test/invite-join.test create mode 100755 test/ping.test create mode 100644 test/pong.c create mode 100755 test/sptps-basic.test create mode 100644 test/testlib.sh create mode 100755 test/variables.test diff --git a/ChangeLog b/ChangeLog index 0feb52e..9eeabde 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,51 @@ +Version 1.1pre9 September 08 2013 +------------------------------------------------------------------------ + +Guus Sliepen (40): + Stop using EXTRA_DIST in src/Makefile.am. + Remove texi2html rule in docs/Makefile. + Create UNIX socket at the same time as the PID file is created. + Don't force a .bat extension for scripts under Windows. + Fix order of tincd's initialization. + Remove broadcast of KEY_CHANGED message during tinc's initialization. + Bind outgoing sockets again. + Resolve the local host name before generating the invitation file. + Use our own infrastructure for finding out the local node's externally visible host name. + Let a server explicitly send a notification when the invitation protocol succeeded. + Ensure the invitation filenames do not reveal the secret cookie. + Execute scripts when invitations are created or accepted. + Use PATHEXT when checking for the presence of scripts on Windows. + Tell invited node about Mode and Broadcast settings. + Call WSAStartup() in main(). + When generating invitations, handle any order of Port and Adress statements. + Add an option to test datagram SPTPS with packet loss. + Fix CTR mode. + Fix the replay window in SPTPS. + Allow testing the replay window with sptps_test. + Start of a test suite. + Some shells set $_ to an absolute path. + Make sptps_test more easy to work with. + Small fixes for tests. + Add test for import, export and exchange commands. + Fix tincd logfile location when running tests. + Clean up leftover tincd and sptps_test processes. + Send a RELOAD to a running tincd when a new invitation key has been generated. + Slightly relax the connection rate limit for a single address. + Also test whether tinc daemons can connect to each other after import/export. + Add a test for invite and join commands. + Exit value 1 instead of a random non-zero value. + Fix multicast device. + Add two more test scripts. + Don't return zero-length packets when receiving multicast loopback packets. + Test running ping through two tinc daemons. + Automake doesn't like info files being mentioned in CLEANFILES. + Make sure test scripts end up in the tarball. + Don't try to mkdir(CONFDIR) if --config is used. + Releasing 1.1pre9. + +Etienne Dechamps (1): + Fix broken build with --with-openssl, --with-libgcrypt. + Version 1.1pre8 August 13 2013 ------------------------------------------------------------------------ diff --git a/Makefile.am b/Makefile.am index d2e6f3f..0a4faef 100644 --- a/Makefile.am +++ b/Makefile.am @@ -2,7 +2,7 @@ AUTOMAKE_OPTIONS = gnu -SUBDIRS = m4 src doc gui +SUBDIRS = m4 src doc gui test ACLOCAL_AMFLAGS = -I m4 diff --git a/Makefile.in b/Makefile.in index 3ca1385..a464e9e 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1,4 +1,4 @@ -# Makefile.in generated by automake 1.13.3 from Makefile.am. +# Makefile.in generated by automake 1.14 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. @@ -298,7 +298,7 @@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ AUTOMAKE_OPTIONS = gnu -SUBDIRS = m4 src doc gui +SUBDIRS = m4 src doc gui test ACLOCAL_AMFLAGS = -I m4 EXTRA_DIST = COPYING.README README.android all: config.h @@ -341,8 +341,8 @@ $(ACLOCAL_M4): $(am__aclocal_m4_deps) $(am__aclocal_m4_deps): config.h: stamp-h1 - @if test ! -f $@; then rm -f stamp-h1; else :; fi - @if test ! -f $@; then $(MAKE) $(AM_MAKEFLAGS) stamp-h1; else :; fi + @test -f $@ || rm -f stamp-h1 + @test -f $@ || $(MAKE) $(AM_MAKEFLAGS) stamp-h1 stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status @rm -f stamp-h1 @@ -548,10 +548,16 @@ dist-xz: distdir $(am__post_remove_distdir) dist-tarZ: distdir + @echo WARNING: "Support for shar distribution archives is" \ + "deprecated." >&2 + @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z $(am__post_remove_distdir) dist-shar: distdir + @echo WARNING: "Support for distribution archives compressed with" \ + "legacy program 'compress' is deprecated." >&2 + @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz $(am__post_remove_distdir) diff --git a/NEWS b/NEWS index 66ed06f..a0ca1d7 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,31 @@ +Version 1.1pre9 September 8 2013 + + * The UNIX socket is now created before tinc-up is called. + + * Windows users can now use any extension that is in %PATHEXT% for scripts, + not only .bat. + + * Outgoing sockets are bound to the address of the listening sockets again, + when there is no ambiguity. + + * Added invitation-created and invitation-accepted scripts. + + * Invited nodes now learn of the Mode and Broadcast settings of the VPN. + + * Joining a VPN with an invitation now also works on Windows. + + * The port number tincd is listening on is now always included in the + invitation URL. + + * A running tincd is now correctly informed when a new invitation has been + generated. + + * Several bug fixes for the new protocol. + + * Added a test suite. + +Thanks to Etienne Dechamps for his contribution to this version of tinc. + Version 1.1pre8 August 13 2013 * ExperimentalProtocol is now enabled by default. diff --git a/README b/README index 73eb070..ec53243 100644 --- a/README +++ b/README @@ -1,4 +1,4 @@ -This is the README file for tinc version 1.1pre8. Installation +This is the README file for tinc version 1.1pre9. Installation instructions may be found in the INSTALL file. tinc is Copyright (C) 1998-2013 by: @@ -36,11 +36,11 @@ at your own risk. Compatibility ------------- -Version 1.1pre8 is compatible with 1.0pre8, 1.0 and later, but not with older +Version 1.1pre9 is compatible with 1.0pre8, 1.0 and later, but not with older versions of tinc. When the ExperimentalProtocol option is used, which is the default since -1.1pre8, tinc is still compatible with 1.0.X and 1.1pre8 itself, but not with +1.1pre8, tinc is still compatible with 1.0.X and 1.1pre9 itself, but not with any other 1.1preX version. diff --git a/aclocal.m4 b/aclocal.m4 index b4047e3..e3a5dd9 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -1,4 +1,4 @@ -# generated automatically by aclocal 1.13.3 -*- Autoconf -*- +# generated automatically by aclocal 1.14 -*- Autoconf -*- # Copyright (C) 1996-2013 Free Software Foundation, Inc. @@ -156,10 +156,10 @@ AC_DEFUN([AM_PATH_LIBGCRYPT], # generated from the m4 files accompanying Automake X.Y. # (This private macro should not be called outside this file.) AC_DEFUN([AM_AUTOMAKE_VERSION], -[am__api_version='1.13' +[am__api_version='1.14' 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.13.3], [], +m4_if([$1], [1.14], [], [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl ]) @@ -175,7 +175,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.13.3])dnl +[AM_AUTOMAKE_VERSION([1.14])dnl m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) @@ -542,6 +542,12 @@ AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], # This macro actually does too much. Some checks are only needed if # your package does certain things. But this isn't really a big deal. +dnl Redefine AC_PROG_CC to automatically invoke _AM_PROG_CC_C_O. +m4_define([AC_PROG_CC], +m4_defn([AC_PROG_CC]) +[_AM_PROG_CC_C_O +]) + # AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) # AM_INIT_AUTOMAKE([OPTIONS]) # ----------------------------------------------- @@ -650,7 +656,48 @@ dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below. AC_CONFIG_COMMANDS_PRE(dnl [m4_provide_if([_AM_COMPILER_EXEEXT], [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl -]) + +# POSIX will say in a future version that running "rm -f" with no argument +# is OK; and we want to be able to make that assumption in our Makefile +# recipes. So use an aggressive probe to check that the usage we want is +# actually supported "in the wild" to an acceptable degree. +# See automake bug#10828. +# To make any issue more visible, cause the running configure to be aborted +# by default if the 'rm' program in use doesn't match our expectations; the +# user can still override this though. +if rm -f && rm -fr && rm -rf; then : OK; else + cat >&2 <<'END' +Oops! + +Your 'rm' program seems unable to run without file operands specified +on the command line, even when the '-f' option is present. This is contrary +to the behaviour of most rm programs out there, and not conforming with +the upcoming POSIX standard: + +Please tell bug-automake@gnu.org about your system, including the value +of your $PATH and any error possibly output before this message. This +can help us improve future automake versions. + +END + if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then + echo 'Configuration will proceed anyway, since you have set the' >&2 + echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 + echo >&2 + else + cat >&2 <<'END' +Aborting the configuration process, to ensure you take notice of the issue. + +You can download and install GNU coreutils to get an 'rm' implementation +that behaves properly: . + +If you want to complete the configuration process using your problematic +'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM +to "yes", and re-run configure. + +END + AC_MSG_ERROR([Your 'rm' program is bad, sorry.]) + fi +fi]) dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further @@ -658,7 +705,6 @@ dnl mangled by Autoconf and run in a shell conditional statement. m4_define([_AC_COMPILER_EXEEXT], m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) - # When config.status generates a header, we must update the stamp-h file. # This file resides in the same directory as the config header # that is generated. The stamp files are numbered to have different names. @@ -770,38 +816,6 @@ AC_MSG_RESULT([$_am_result]) rm -f confinc confmf ]) -# Copyright (C) 1999-2013 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# AM_PROG_CC_C_O -# -------------- -# Like AC_PROG_CC_C_O, but changed for automake. -AC_DEFUN([AM_PROG_CC_C_O], -[AC_REQUIRE([AC_PROG_CC_C_O])dnl -AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl -AC_REQUIRE_AUX_FILE([compile])dnl -# FIXME: we rely on the cache variable name because -# there is no other way. -set dummy $CC -am_cc=`echo $[2] | sed ['s/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/']` -eval am_t=\$ac_cv_prog_cc_${am_cc}_c_o -if test "$am_t" != yes; then - # Losing compiler, so override with the script. - # FIXME: It is wrong to rewrite CC. - # But if we don't then we get into trouble of one sort or another. - # A longer-term fix would be to have automake use am__CC in this case, - # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" - CC="$am_aux_dir/compile $CC" -fi -dnl Make sure AC_PROG_CC is never called again, or it will override our -dnl setting of CC. -m4_define([AC_PROG_CC], - [m4_fatal([AC_PROG_CC cannot be called after AM_PROG_CC_C_O])]) -]) - # Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- # Copyright (C) 1997-2013 Free Software Foundation, Inc. @@ -872,6 +886,70 @@ AC_DEFUN([_AM_SET_OPTIONS], AC_DEFUN([_AM_IF_OPTION], [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) +# Copyright (C) 1999-2013 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# _AM_PROG_CC_C_O +# --------------- +# Like AC_PROG_CC_C_O, but changed for automake. We rewrite AC_PROG_CC +# to automatically call this. +AC_DEFUN([_AM_PROG_CC_C_O], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +AC_REQUIRE_AUX_FILE([compile])dnl +AC_LANG_PUSH([C])dnl +AC_CACHE_CHECK( + [whether $CC understands -c and -o together], + [am_cv_prog_cc_c_o], + [AC_LANG_CONFTEST([AC_LANG_PROGRAM([])]) + # Make sure it works both with $CC and with simple cc. + # Following AC_PROG_CC_C_O, we do the test twice because some + # compilers refuse to overwrite an existing .o file with -o, + # though they will create one. + am_cv_prog_cc_c_o=yes + for am_i in 1 2; do + if AM_RUN_LOG([$CC -c conftest.$ac_ext -o conftest2.$ac_objext]) \ + && test -f conftest2.$ac_objext; then + : OK + else + am_cv_prog_cc_c_o=no + break + fi + done + rm -f core conftest* + unset am_i]) +if test "$am_cv_prog_cc_c_o" != yes; then + # Losing compiler, so override with the script. + # FIXME: It is wrong to rewrite CC. + # But if we don't then we get into trouble of one sort or another. + # A longer-term fix would be to have automake use am__CC in this case, + # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" + CC="$am_aux_dir/compile $CC" +fi +AC_LANG_POP([C])]) + +# For backward compatibility. +AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])]) + +# Copyright (C) 2001-2013 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_RUN_LOG(COMMAND) +# ------------------- +# Run COMMAND, save the exit status in ac_status, and log it. +# (This has been adapted from Autoconf's _AC_RUN_LOG macro.) +AC_DEFUN([AM_RUN_LOG], +[{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD + ($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + (exit $ac_status); }]) + # Check to make sure that the build environment is sane. -*- Autoconf -*- # Copyright (C) 1996-2013 Free Software Foundation, Inc. diff --git a/config.h.in b/config.h.in index e78f182..58eb426 100644 --- a/config.h.in +++ b/config.h.in @@ -382,9 +382,6 @@ /* Location of lzo1x.h */ #undef LZO1X_H -/* Define to 1 if your C compiler doesn't accept -c and -o together. */ -#undef NO_MINUS_C_MINUS_O - /* Name of package */ #undef PACKAGE diff --git a/configure b/configure index ae5c23d..d2816e1 100755 --- a/configure +++ b/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for tinc 1.1pre8. +# Generated by GNU Autoconf 2.69 for tinc 1.1pre9. # # # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. @@ -577,8 +577,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='tinc' PACKAGE_TARNAME='tinc' -PACKAGE_VERSION='1.1pre8' -PACKAGE_STRING='tinc 1.1pre8' +PACKAGE_VERSION='1.1pre9' +PACKAGE_STRING='tinc 1.1pre9' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1323,7 +1323,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures tinc 1.1pre8 to adapt to many kinds of systems. +\`configure' configures tinc 1.1pre9 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1393,7 +1393,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of tinc 1.1pre8:";; + short | recursive ) echo "Configuration of tinc 1.1pre9:";; esac cat <<\_ACEOF @@ -1520,7 +1520,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -tinc configure 1.1pre8 +tinc configure 1.1pre9 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -1985,7 +1985,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by tinc $as_me 1.1pre8, which was +It was created by tinc $as_me 1.1pre9, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -2334,6 +2334,9 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu +# expand $ac_aux_dir to an absolute path +am_aux_dir=`cd $ac_aux_dir && pwd` + ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' @@ -3123,6 +3126,65 @@ ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5 +$as_echo_n "checking whether $CC understands -c and -o together... " >&6; } +if ${am_cv_prog_cc_c_o+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF + # Make sure it works both with $CC and with simple cc. + # Following AC_PROG_CC_C_O, we do the test twice because some + # compilers refuse to overwrite an existing .o file with -o, + # though they will create one. + am_cv_prog_cc_c_o=yes + for am_i in 1 2; do + if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5 + ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } \ + && test -f conftest2.$ac_objext; then + : OK + else + am_cv_prog_cc_c_o=no + break + fi + done + rm -f core conftest* + unset am_i +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5 +$as_echo "$am_cv_prog_cc_c_o" >&6; } +if test "$am_cv_prog_cc_c_o" != yes; then + # Losing compiler, so override with the script. + # FIXME: It is wrong to rewrite CC. + # But if we don't then we get into trouble of one sort or another. + # A longer-term fix would be to have automake use am__CC in this case, + # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" + CC="$am_aux_dir/compile $CC" +fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + ac_ext=c ac_cpp='$CPP $CPPFLAGS' @@ -3583,7 +3645,7 @@ $as_echo "$ac_cv_safe_to_define___extensions__" >&6; } -am__api_version='1.13' +am__api_version='1.14' ac_aux_dir= for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do @@ -3784,9 +3846,6 @@ test "$program_suffix" != NONE && ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` -# expand $ac_aux_dir to an absolute path -am_aux_dir=`cd $ac_aux_dir && pwd` - if test x"${MISSING+set}" != xset; then case $am_aux_dir in *\ * | *\ *) @@ -4161,7 +4220,7 @@ fi # Define the identity of the package. PACKAGE='tinc' - VERSION='1.1pre8' + VERSION='1.1pre9' cat >>confdefs.h <<_ACEOF @@ -4340,6 +4399,47 @@ fi +# POSIX will say in a future version that running "rm -f" with no argument +# is OK; and we want to be able to make that assumption in our Makefile +# recipes. So use an aggressive probe to check that the usage we want is +# actually supported "in the wild" to an acceptable degree. +# See automake bug#10828. +# To make any issue more visible, cause the running configure to be aborted +# by default if the 'rm' program in use doesn't match our expectations; the +# user can still override this though. +if rm -f && rm -fr && rm -rf; then : OK; else + cat >&2 <<'END' +Oops! + +Your 'rm' program seems unable to run without file operands specified +on the command line, even when the '-f' option is present. This is contrary +to the behaviour of most rm programs out there, and not conforming with +the upcoming POSIX standard: + +Please tell bug-automake@gnu.org about your system, including the value +of your $PATH and any error possibly output before this message. This +can help us improve future automake versions. + +END + if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then + echo 'Configuration will proceed anyway, since you have set the' >&2 + echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 + echo >&2 + else + cat >&2 <<'END' +Aborting the configuration process, to ensure you take notice of the issue. + +You can download and install GNU coreutils to get an 'rm' implementation +that behaves properly: . + +If you want to complete the configuration process using your problematic +'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM +to "yes", and re-run configure. + +END + as_fn_error $? "Your 'rm' program is bad, sorry." "$LINENO" 5 + fi +fi ac_config_headers="$ac_config_headers config.h" @@ -4770,131 +4870,6 @@ else fi -if test "x$CC" != xcc; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC and cc understand -c and -o together" >&5 -$as_echo_n "checking whether $CC and cc understand -c and -o together... " >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether cc understands -c and -o together" >&5 -$as_echo_n "checking whether cc understands -c and -o together... " >&6; } -fi -set dummy $CC; ac_cc=`$as_echo "$2" | - sed 's/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/'` -if eval \${ac_cv_prog_cc_${ac_cc}_c_o+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -# Make sure it works both with $CC and with simple cc. -# We do the test twice because some compilers refuse to overwrite an -# existing .o file with -o, though they will create one. -ac_try='$CC -c conftest.$ac_ext -o conftest2.$ac_objext >&5' -rm -f conftest2.* -if { { 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; } && - test -f conftest2.$ac_objext && { { 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 - eval ac_cv_prog_cc_${ac_cc}_c_o=yes - if test "x$CC" != xcc; then - # Test first that cc exists at all. - if { ac_try='cc -c conftest.$ac_ext >&5' - { { 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 - ac_try='cc -c conftest.$ac_ext -o conftest2.$ac_objext >&5' - rm -f conftest2.* - if { { 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; } && - test -f conftest2.$ac_objext && { { 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 - # cc works too. - : - else - # cc exists but doesn't like -o. - eval ac_cv_prog_cc_${ac_cc}_c_o=no - fi - fi - fi -else - eval ac_cv_prog_cc_${ac_cc}_c_o=no -fi -rm -f core conftest* - -fi -if eval test \$ac_cv_prog_cc_${ac_cc}_c_o = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - -$as_echo "#define NO_MINUS_C_MINUS_O 1" >>confdefs.h - -fi - -# FIXME: we rely on the cache variable name because -# there is no other way. -set dummy $CC -am_cc=`echo $2 | sed 's/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/'` -eval am_t=\$ac_cv_prog_cc_${am_cc}_c_o -if test "$am_t" != yes; then - # Losing compiler, so override with the script. - # FIXME: It is wrong to rewrite CC. - # But if we don't then we get into trouble of one sort or another. - # A longer-term fix would be to have automake use am__CC in this case, - # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" - CC="$am_aux_dir/compile $CC" -fi - @@ -7056,7 +7031,7 @@ fi fi - if test "$openssl" = true; then + if test -n "$openssl"; then OPENSSL_TRUE= OPENSSL_FALSE='#' else @@ -7064,7 +7039,7 @@ else OPENSSL_FALSE= fi - if test "$grypt" = true; then + if test "$gcrypt" = true; then GCRYPT_TRUE= GCRYPT_FALSE='#' else @@ -7085,7 +7060,7 @@ fi fi -ac_config_files="$ac_config_files Makefile src/Makefile doc/Makefile m4/Makefile gui/Makefile" +ac_config_files="$ac_config_files Makefile src/Makefile doc/Makefile m4/Makefile gui/Makefile test/Makefile" cat >confcache <<\_ACEOF @@ -7658,7 +7633,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by tinc $as_me 1.1pre8, which was +This file was extended by tinc $as_me 1.1pre9, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -7724,7 +7699,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -tinc config.status 1.1pre8 +tinc config.status 1.1pre9 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" @@ -7860,6 +7835,7 @@ do "doc/Makefile") CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;; "m4/Makefile") CONFIG_FILES="$CONFIG_FILES m4/Makefile" ;; "gui/Makefile") CONFIG_FILES="$CONFIG_FILES gui/Makefile" ;; + "test/Makefile") CONFIG_FILES="$CONFIG_FILES test/Makefile" ;; *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; esac diff --git a/configure.ac b/configure.ac index af12f12..75456a0 100644 --- a/configure.ac +++ b/configure.ac @@ -1,7 +1,7 @@ dnl Process this file with autoconf to produce a configure script. AC_PREREQ(2.61) -AC_INIT([tinc], [1.1pre8]) +AC_INIT([tinc], [1.1pre9]) AC_CONFIG_SRCDIR([src/tincd.c]) AC_GNU_SOURCE AM_INIT_AUTOMAKE([check-news std-options subdir-objects -Wall]) @@ -201,8 +201,8 @@ else tinc_OPENSSL fi -AM_CONDITIONAL(OPENSSL, test "$openssl" = true) -AM_CONDITIONAL(GCRYPT, test "$grypt" = true) +AM_CONDITIONAL(OPENSSL, test -n "$openssl") +AM_CONDITIONAL(GCRYPT, test "$gcrypt" = true) dnl Check if support for jumbograms is requested AC_ARG_ENABLE(jumbograms, @@ -212,6 +212,6 @@ AC_ARG_ENABLE(jumbograms, ] ) -AC_CONFIG_FILES([Makefile src/Makefile doc/Makefile m4/Makefile gui/Makefile]) +AC_CONFIG_FILES([Makefile src/Makefile doc/Makefile m4/Makefile gui/Makefile test/Makefile]) AC_OUTPUT diff --git a/doc/Makefile.am b/doc/Makefile.am index 9540b49..a666d3b 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -6,7 +6,7 @@ man_MANS = tincd.8 tinc.8 tinc.conf.5 tinc-gui.8 EXTRA_DIST = tincinclude.texi.in tincd.8.in tinc.8.in tinc.conf.5.in tinc-gui.8.in sample-config.tar.gz -CLEANFILES = *.html tinc.info tincd.8 tinc.8 tinc.conf.5 tinc-gui.8 tincinclude.texi +CLEANFILES = *.html tincd.8 tinc.8 tinc.conf.5 tinc-gui.8 tincinclude.texi # Use `ginstall' in the definition of man_MANS to avoid # confusion with the `install' target. The install rule transforms `ginstall' @@ -19,9 +19,6 @@ transform = s/ginstall/install/; @program_transform_name@ sample-config.tar.gz: sample-config GZIP=$(GZIP_ENV) $(AMTAR) chozf sample-config.tar.gz --exclude .svn sample-config -texi2html: tinc.texi - texi2html -split=chapter tinc.texi - tincd.8.html: tincd.8 w3mman2html $? > $@ diff --git a/doc/Makefile.in b/doc/Makefile.in index 823c951..352e921 100644 --- a/doc/Makefile.in +++ b/doc/Makefile.in @@ -1,4 +1,4 @@ -# Makefile.in generated by automake 1.13.3 from Makefile.am. +# Makefile.in generated by automake 1.14 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. @@ -131,7 +131,7 @@ AM_V_texidevnull = $(am__v_texidevnull_@AM_V@) am__v_texidevnull_ = $(am__v_texidevnull_@AM_DEFAULT_V@) am__v_texidevnull_0 = > /dev/null am__v_texidevnull_1 = -INFO_DEPS = tinc.info +INFO_DEPS = $(srcdir)/tinc.info am__TEXINFO_TEX_DIR = $(srcdir) DVIS = tinc.dvi PDFS = tinc.pdf @@ -293,7 +293,7 @@ top_srcdir = @top_srcdir@ info_TEXINFOS = tinc.texi man_MANS = tincd.8 tinc.8 tinc.conf.5 tinc-gui.8 EXTRA_DIST = tincinclude.texi.in tincd.8.in tinc.8.in tinc.conf.5.in tinc-gui.8.in sample-config.tar.gz -CLEANFILES = *.html tinc.info tincd.8 tinc.8 tinc.conf.5 tinc-gui.8 tincinclude.texi +CLEANFILES = *.html tincd.8 tinc.8 tinc.conf.5 tinc-gui.8 tincinclude.texi substitute = sed \ -e s,'@PACKAGE\@',"$(PACKAGE)",g \ -e s,'@VERSION\@',"$(VERSION)",g \ @@ -303,7 +303,7 @@ substitute = sed \ all: all-am .SUFFIXES: -.SUFFIXES: .dvi .ps +.SUFFIXES: .dvi .html .info .pdf .ps .texi $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ @@ -335,49 +335,53 @@ $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): -tinc.info: tinc.texi +.texi.info: $(AM_V_MAKEINFO)restore=: && backupdir="$(am__leading_dot)am$$$$" && \ + am__cwd=`pwd` && $(am__cd) $(srcdir) && \ rm -rf $$backupdir && mkdir $$backupdir && \ if ($(MAKEINFO) --version) >/dev/null 2>&1; then \ for f in $@ $@-[0-9] $@-[0-9][0-9] $(@:.info=).i[0-9] $(@:.info=).i[0-9][0-9]; do \ if test -f $$f; then mv $$f $$backupdir; restore=mv; else :; fi; \ done; \ else :; fi && \ + cd "$$am__cwd"; \ if $(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir) \ - -o $@ `test -f 'tinc.texi' || echo '$(srcdir)/'`tinc.texi; \ + -o $@ $<; \ then \ rc=0; \ + $(am__cd) $(srcdir); \ else \ rc=$$?; \ + $(am__cd) $(srcdir) && \ $$restore $$backupdir/* `echo "./$@" | sed 's|[^/]*$$||'`; \ fi; \ rm -rf $$backupdir; exit $$rc -tinc.dvi: tinc.texi +.texi.dvi: $(AM_V_TEXI2DVI)TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \ MAKEINFO='$(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir)' \ $(TEXI2DVI) $(AM_V_texinfo) --build-dir=$(@:.dvi=.t2d) -o $@ $(AM_V_texidevnull) \ - `test -f 'tinc.texi' || echo '$(srcdir)/'`tinc.texi + $< -tinc.pdf: tinc.texi +.texi.pdf: $(AM_V_TEXI2PDF)TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \ MAKEINFO='$(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir)' \ $(TEXI2PDF) $(AM_V_texinfo) --build-dir=$(@:.pdf=.t2p) -o $@ $(AM_V_texidevnull) \ - `test -f 'tinc.texi' || echo '$(srcdir)/'`tinc.texi + $< -tinc.html: tinc.texi +.texi.html: $(AM_V_MAKEINFO)rm -rf $(@:.html=.htp) $(AM_V_at)if $(MAKEINFOHTML) $(AM_MAKEINFOHTMLFLAGS) $(MAKEINFOFLAGS) -I $(srcdir) \ - -o $(@:.html=.htp) `test -f 'tinc.texi' || echo '$(srcdir)/'`tinc.texi; \ + -o $(@:.html=.htp) $<; \ then \ - rm -rf $@; \ - if test ! -d $(@:.html=.htp) && test -d $(@:.html=); then \ - mv $(@:.html=) $@; else mv $(@:.html=.htp) $@; fi; \ + rm -rf $@ && mv $(@:.html=.htp) $@; \ else \ - if test ! -d $(@:.html=.htp) && test -d $(@:.html=); then \ - rm -rf $(@:.html=); else rm -Rf $(@:.html=.htp) $@; fi; \ - exit 1; \ + rm -rf $(@:.html=.htp); exit 1; \ fi +$(srcdir)/tinc.info: tinc.texi +tinc.dvi: tinc.texi +tinc.pdf: tinc.texi +tinc.html: tinc.texi .dvi.ps: $(AM_V_DVIPS)TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \ $(DVIPS) $(AM_V_texinfo) -o $@ $< @@ -820,9 +824,6 @@ uninstall-man: uninstall-man5 uninstall-man8 sample-config.tar.gz: sample-config GZIP=$(GZIP_ENV) $(AMTAR) chozf sample-config.tar.gz --exclude .svn sample-config -texi2html: tinc.texi - texi2html -split=chapter tinc.texi - tincd.8.html: tincd.8 w3mman2html $? > $@ diff --git a/doc/tinc.conf.5.in b/doc/tinc.conf.5.in index 69deace..1d5aa4e 100644 --- a/doc/tinc.conf.5.in +++ b/doc/tinc.conf.5.in @@ -580,7 +580,9 @@ UDP is possible or not. Apart from reading the server and host configuration files, tinc can also run scripts at certain moments. Under Windows (not Cygwin), the scripts should have the extension -.Pa .bat . +.Pa .bat +or +.Pa cmd . .Bl -tag -width indent .It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /tinc-up This is the most important script. @@ -607,6 +609,10 @@ This script is started when a Subnet becomes reachable. The Subnet and the node it belongs to are passed in environment variables. .It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /subnet-down This script is started when a Subnet becomes unreachable. +.It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /invitation-created +This script is started when a new invitation has been created. +.It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /invitation-accepted +This script is started when an invitation has been used. .El .Pp The scripts are started without command line arguments, but can make use of certain environment variables. @@ -615,6 +621,8 @@ Under UNIX like operating systems the names of environment variables must be pre in scripts. Under Windows, in .Pa .bat +or +.Pa .cmd files, they have to be put between .Li % signs. @@ -640,6 +648,14 @@ When a host becomes (un)reachable, this is set to the port number it uses for co When a subnet becomes (un)reachable, this is set to the subnet. .It Ev WEIGHT When a subnet becomes (un)reachable, this is set to the subnet weight. +.It Ev INVITATION_FILE +When the +.Pa invitation-created +script is called, this is set to the file where the invitation details will be stored. +.It Ev INVITATION_URL +When the +.Pa invitation-created +script is called, this is set to the invitation URL that has been created. .El .Pp Do not forget that under UNIX operating systems, you have to make the scripts executable, using the command diff --git a/doc/tinc.info b/doc/tinc.info index 0e4c5ec..9763256 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.1pre7, a Virtual Private +This is the info manual for tinc version 1.1pre9, a Virtual Private Network daemon. Copyright (C) 1998-2013 Ivo Timmermans, Guus Sliepen @@ -1242,7 +1242,7 @@ File: tinc.info, Node: Scripts, Next: How to configure, Prev: Host configurat Apart from reading the server and host configuration files, tinc can also run scripts at certain moments. Under Windows (not Cygwin), the -scripts should have the extension .bat. +scripts should have the extension '.bat' or '.cmd'. '/etc/tinc/NETNAME/tinc-up' This is the most important script. If it is present it will be @@ -1276,10 +1276,17 @@ scripts should have the extension .bat. '/etc/tinc/NETNAME/subnet-down' This script is started when a Subnet becomes unreachable. +'/etc/tinc/NETNAME/invitation-created' + This script is started when a new invitation has been created. + +'/etc/tinc/NETNAME/invitation-accepted' + This script is started when an invitation has been used. + The scripts are started without command line arguments, but can make use of certain environment variables. Under UNIX like operating systems the names of environment variables must be preceded by a $ in scripts. -Under Windows, in '.bat' files, they have to be put between % signs. +Under Windows, in '.bat' or '.cmd' files, they have to be put between % +signs. 'NETNAME' If a netname was specified, this environment variable contains it. @@ -1309,6 +1316,21 @@ Under Windows, in '.bat' files, they have to be put between % signs. 'SUBNET' When a subnet becomes (un)reachable, this is set to the subnet. +'WEIGHT' + When a subnet becomes (un)reachable, this is set to the subnet + weight. + +'INVITATION_FILE' + When the 'invitation-created' script is called, this is set to the + file where the invitation details will be stored. + +'INVITATION_URL' + When the 'invitation-created' script is called, this is set to the + invitation URL that has been created. + +Do not forget that under UNIX operating systems, you have to make the +scripts executable, using the command 'chmod a+x script'. +  File: tinc.info, Node: How to configure, Prev: Scripts, Up: Configuration files @@ -3043,7 +3065,7 @@ Concept Index * DEL_SUBNET: The meta-protocol. (line 46) * Device: Main configuration variables. (line 80) -* DEVICE: Scripts. (line 53) +* DEVICE: Scripts. (line 60) * device files: Device files. (line 6) * DeviceType: Main configuration variables. (line 87) @@ -3058,7 +3080,7 @@ Concept Index * encapsulating: The UDP tunnel. (line 30) * encryption: Encryption of network packets. (line 6) -* environment variables: Scripts. (line 42) +* environment variables: Scripts. (line 48) * example: Example configuration. (line 6) * exec: Main configuration variables. @@ -3080,7 +3102,9 @@ Concept Index (line 38) * Interface: Main configuration variables. (line 201) -* INTERFACE: Scripts. (line 56) +* INTERFACE: Scripts. (line 63) +* INVITATION_FILE: Scripts. (line 86) +* INVITATION_URL: Scripts. (line 90) * IRC: Contact information. (line 9) * KeyExpire: Main configuration variables. (line 251) @@ -3112,15 +3136,15 @@ Concept Index * multiple networks: Multiple networks. (line 6) * Name: Main configuration variables. (line 268) -* NAME: Scripts. (line 50) +* NAME: Scripts. (line 57) * netmask: Network interfaces. (line 39) * netname: Multiple networks. (line 6) -* NETNAME: Scripts. (line 47) +* NETNAME: Scripts. (line 54) * NETNAME <1>: tinc environment variables. (line 6) * Network Administrators Guide: Configuration introduction. (line 15) -* NODE: Scripts. (line 60) +* NODE: Scripts. (line 67) * OpenSSL: OpenSSL. (line 6) * options: Runtime options. (line 9) * PEM format: Host configuration variables. @@ -3158,8 +3182,8 @@ Concept Index * raw_socket: Main configuration variables. (line 99) * release: Supported platforms. (line 14) -* REMOTEADDRESS: Scripts. (line 65) -* REMOTEPORT: Scripts. (line 68) +* REMOTEADDRESS: Scripts. (line 72) +* REMOTEPORT: Scripts. (line 75) * ReplayWindow: Main configuration variables. (line 333) * requirements: Libraries. (line 6) @@ -3182,7 +3206,7 @@ Concept Index (line 344) * Subnet: Host configuration variables. (line 77) -* SUBNET: Scripts. (line 72) +* SUBNET: Scripts. (line 79) * SVPN: Security. (line 11) * switch: Main configuration variables. (line 235) @@ -3222,6 +3246,7 @@ Concept Index (line 6) * vpnd: tinc. (line 6) * website: Contact information. (line 6) +* WEIGHT: Scripts. (line 82) * zlib: zlib. (line 6) @@ -3263,38 +3288,38 @@ Node: Configuration files27607 Node: Main configuration variables29135 Node: Host configuration variables45893 Node: Scripts51364 -Node: How to configure54033 -Node: Network interfaces58509 -Node: Example configuration60888 -Node: Running tinc65981 -Node: Runtime options66568 -Node: Signals69428 -Node: Debug levels70277 -Node: Solving problems71213 -Node: Error messages72639 -Node: Sending bug reports76956 -Node: Controlling tinc77903 -Node: tinc runtime options78280 -Node: tinc environment variables78967 -Node: tinc commands79296 -Node: tinc examples84406 -Node: tinc top84969 -Node: Technical information86554 -Node: The connection86789 -Node: The UDP tunnel87101 -Node: The meta-connection90146 -Node: The meta-protocol91604 -Node: Security96587 -Node: Legacy authentication protocol97924 -Node: Simple Peer-to-Peer Security102541 -Node: Encryption of network packets108201 -Node: Security issues110830 -Node: Platform specific information112565 -Node: Interface configuration112793 -Node: Routes115234 -Node: About us117145 -Node: Contact information117320 -Node: Authors117722 -Node: Concept Index118124 +Node: How to configure54765 +Node: Network interfaces59241 +Node: Example configuration61620 +Node: Running tinc66713 +Node: Runtime options67300 +Node: Signals70160 +Node: Debug levels71009 +Node: Solving problems71945 +Node: Error messages73371 +Node: Sending bug reports77688 +Node: Controlling tinc78635 +Node: tinc runtime options79012 +Node: tinc environment variables79699 +Node: tinc commands80028 +Node: tinc examples85138 +Node: tinc top85701 +Node: Technical information87286 +Node: The connection87521 +Node: The UDP tunnel87833 +Node: The meta-connection90878 +Node: The meta-protocol92336 +Node: Security97319 +Node: Legacy authentication protocol98656 +Node: Simple Peer-to-Peer Security103273 +Node: Encryption of network packets108933 +Node: Security issues111562 +Node: Platform specific information113297 +Node: Interface configuration113525 +Node: Routes115966 +Node: About us117877 +Node: Contact information118052 +Node: Authors118454 +Node: Concept Index118856  End Tag Table diff --git a/doc/tinc.texi b/doc/tinc.texi index a295293..acbee94 100644 --- a/doc/tinc.texi +++ b/doc/tinc.texi @@ -1346,7 +1346,7 @@ Setting this options also implicitly sets IndirectData. @cindex scripts Apart from reading the server and host configuration files, tinc can also run scripts at certain moments. -Under Windows (not Cygwin), the scripts should have the extension .bat. +Under Windows (not Cygwin), the scripts should have the extension @file{.bat} or @file{.cmd}. @table @file @cindex tinc-up @@ -1380,13 +1380,20 @@ The Subnet and the node it belongs to are passed in environment variables. @item @value{sysconfdir}/tinc/@var{netname}/subnet-down This script is started when a Subnet becomes unreachable. + +@item @value{sysconfdir}/tinc/@var{netname}/invitation-created +This script is started when a new invitation has been created. + +@item @value{sysconfdir}/tinc/@var{netname}/invitation-accepted +This script is started when an invitation has been used. + @end table @cindex environment variables The scripts are started without command line arguments, but can make use of certain environment variables. Under UNIX like operating systems the names of environment variables must be preceded by a $ in scripts. -Under Windows, in @file{.bat} files, they have to be put between % signs. +Under Windows, in @file{.bat} or @file{.cmd} files, they have to be put between % signs. @table @env @cindex NETNAME @@ -1424,8 +1431,24 @@ this is set to the port number it uses for communication with other tinc daemons @item SUBNET When a subnet becomes (un)reachable, this is set to the subnet. +@cindex WEIGHT +@item WEIGHT +When a subnet becomes (un)reachable, this is set to the subnet weight. + +@cindex INVITATION_FILE +@item INVITATION_FILE +When the @file{invitation-created} script is called, +this is set to the file where the invitation details will be stored. + +@cindex INVITATION_URL +@item INVITATION_URL +When the @file{invitation-created} script is called, +this is set to the invitation URL that has been created. @end table +Do not forget that under UNIX operating systems, +you have to make the scripts executable, using the command @samp{chmod a+x script}. + @c ================================================================== @node How to configure diff --git a/gui/Makefile.in b/gui/Makefile.in index 52c86ab..7232f33 100644 --- a/gui/Makefile.in +++ b/gui/Makefile.in @@ -1,4 +1,4 @@ -# Makefile.in generated by automake 1.13.3 from Makefile.am. +# Makefile.in generated by automake 1.14 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. diff --git a/m4/Makefile.in b/m4/Makefile.in index fc5af2d..b722bcc 100644 --- a/m4/Makefile.in +++ b/m4/Makefile.in @@ -1,4 +1,4 @@ -# Makefile.in generated by automake 1.13.3 from Makefile.am. +# Makefile.in generated by automake 1.14 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. diff --git a/src/Makefile.am b/src/Makefile.am index 27d2330..9664352 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -2,8 +2,6 @@ sbin_PROGRAMS = tincd tinc sptps_test -EXTRA_DIST = linux bsd solaris cygwin mingw openssl gcrypt - DEFAULT_INCLUDES = tincd_SOURCES = \ @@ -57,6 +55,7 @@ tincd_SOURCES = \ route.c route.h \ rsa.h \ rsagen.h \ + script.c script.h \ splay_tree.c splay_tree.h \ sptps.c sptps.h \ subnet.c subnet.h \ @@ -75,6 +74,7 @@ tinc_SOURCES = \ list.c list.h \ names.c names.h \ netutl.c netutl.h \ + script.c script.h \ sptps.c sptps.h \ subnet_parse.c subnet.h \ tincctl.c tincctl.h \ @@ -96,7 +96,7 @@ endif if BSD tincd_SOURCES += bsd/device.c if TUNEMU -tincd_SOURCES += bsd/tunemu.c +tincd_SOURCES += bsd/tunemu.c bsd/tunemu.h endif endif @@ -105,7 +105,7 @@ tincd_SOURCES += solaris/device.c endif if MINGW -tincd_SOURCES += mingw/device.c +tincd_SOURCES += mingw/device.c mingw/common.h endif if CYGWIN @@ -124,7 +124,7 @@ if OPENSSL tincd_SOURCES += \ openssl/cipher.c \ openssl/crypto.c \ - openssl/digest.c \ + openssl/digest.c openssl/digest.h \ openssl/ecdh.c \ openssl/ecdsa.c \ openssl/prf.c \ @@ -132,7 +132,7 @@ tincd_SOURCES += \ tinc_SOURCES += \ openssl/cipher.c \ openssl/crypto.c \ - openssl/digest.c \ + openssl/digest.c openssl/digest.h \ openssl/ecdh.c \ openssl/ecdsa.c \ openssl/ecdsagen.c \ @@ -142,7 +142,7 @@ tinc_SOURCES += \ sptps_test_SOURCES += \ openssl/cipher.c \ openssl/crypto.c \ - openssl/digest.c \ + openssl/digest.c openssl/digest.h \ openssl/ecdh.c \ openssl/ecdsa.c \ openssl/prf.c @@ -152,7 +152,7 @@ if GCRYPT tincd_SOURCES += \ gcrypt/cipher.c \ gcrypt/crypto.c \ - gcrypt/digest.c \ + gcrypt/digest.c gcrypt/digest.h \ gcrypt/ecdh.c \ gcrypt/ecdsa.c \ gcrypt/prf.c \ @@ -160,7 +160,7 @@ tincd_SOURCES += \ tinc_SOURCES += \ gcrypt/cipher.c \ gcrypt/crypto.c \ - gcrypt/digest.c \ + gcrypt/digest.c gcrypt/digest.h \ gcrypt/ecdh.c \ gcrypt/ecdsa.c \ gcrypt/ecdsagen.c \ @@ -170,7 +170,7 @@ tinc_SOURCES += \ sptps_test_SOURCES += \ gcrypt/cipher.c \ gcrypt/crypto.c \ - gcrypt/digest.c \ + gcrypt/digest.c gcrypt/digest.h \ gcrypt/ecdh.c \ gcrypt/ecdsa.c \ gcrypt/prf.c @@ -185,6 +185,3 @@ LIBS += -lpcap endif AM_CFLAGS = -DCONFDIR=\"$(sysconfdir)\" -DLOCALSTATEDIR=\"$(localstatedir)\" -DSBINDIR=\"$(sbindir)\" - -dist-hook: - rm -f `find . -type l` diff --git a/src/Makefile.in b/src/Makefile.in index ab5daa4..a29f6a7 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -1,4 +1,4 @@ -# Makefile.in generated by automake 1.13.3 from Makefile.am. +# Makefile.in generated by automake 1.14 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. @@ -81,16 +81,16 @@ host_triplet = @host@ sbin_PROGRAMS = tincd$(EXEEXT) tinc$(EXEEXT) sptps_test$(EXEEXT) @LINUX_TRUE@am__append_1 = linux/device.c @BSD_TRUE@am__append_2 = bsd/device.c -@BSD_TRUE@@TUNEMU_TRUE@am__append_3 = bsd/tunemu.c +@BSD_TRUE@@TUNEMU_TRUE@am__append_3 = bsd/tunemu.c bsd/tunemu.h @SOLARIS_TRUE@am__append_4 = solaris/device.c -@MINGW_TRUE@am__append_5 = mingw/device.c +@MINGW_TRUE@am__append_5 = mingw/device.c mingw/common.h @CYGWIN_TRUE@am__append_6 = cygwin/device.c @UML_TRUE@am__append_7 = uml_device.c @VDE_TRUE@am__append_8 = vde_device.c @OPENSSL_TRUE@am__append_9 = \ @OPENSSL_TRUE@ openssl/cipher.c \ @OPENSSL_TRUE@ openssl/crypto.c \ -@OPENSSL_TRUE@ openssl/digest.c \ +@OPENSSL_TRUE@ openssl/digest.c openssl/digest.h \ @OPENSSL_TRUE@ openssl/ecdh.c \ @OPENSSL_TRUE@ openssl/ecdsa.c \ @OPENSSL_TRUE@ openssl/prf.c \ @@ -99,7 +99,7 @@ sbin_PROGRAMS = tincd$(EXEEXT) tinc$(EXEEXT) sptps_test$(EXEEXT) @OPENSSL_TRUE@am__append_10 = \ @OPENSSL_TRUE@ openssl/cipher.c \ @OPENSSL_TRUE@ openssl/crypto.c \ -@OPENSSL_TRUE@ openssl/digest.c \ +@OPENSSL_TRUE@ openssl/digest.c openssl/digest.h \ @OPENSSL_TRUE@ openssl/ecdh.c \ @OPENSSL_TRUE@ openssl/ecdsa.c \ @OPENSSL_TRUE@ openssl/ecdsagen.c \ @@ -110,7 +110,7 @@ sbin_PROGRAMS = tincd$(EXEEXT) tinc$(EXEEXT) sptps_test$(EXEEXT) @OPENSSL_TRUE@am__append_11 = \ @OPENSSL_TRUE@ openssl/cipher.c \ @OPENSSL_TRUE@ openssl/crypto.c \ -@OPENSSL_TRUE@ openssl/digest.c \ +@OPENSSL_TRUE@ openssl/digest.c openssl/digest.h \ @OPENSSL_TRUE@ openssl/ecdh.c \ @OPENSSL_TRUE@ openssl/ecdsa.c \ @OPENSSL_TRUE@ openssl/prf.c @@ -118,7 +118,7 @@ sbin_PROGRAMS = tincd$(EXEEXT) tinc$(EXEEXT) sptps_test$(EXEEXT) @GCRYPT_TRUE@am__append_12 = \ @GCRYPT_TRUE@ gcrypt/cipher.c \ @GCRYPT_TRUE@ gcrypt/crypto.c \ -@GCRYPT_TRUE@ gcrypt/digest.c \ +@GCRYPT_TRUE@ gcrypt/digest.c gcrypt/digest.h \ @GCRYPT_TRUE@ gcrypt/ecdh.c \ @GCRYPT_TRUE@ gcrypt/ecdsa.c \ @GCRYPT_TRUE@ gcrypt/prf.c \ @@ -127,7 +127,7 @@ sbin_PROGRAMS = tincd$(EXEEXT) tinc$(EXEEXT) sptps_test$(EXEEXT) @GCRYPT_TRUE@am__append_13 = \ @GCRYPT_TRUE@ gcrypt/cipher.c \ @GCRYPT_TRUE@ gcrypt/crypto.c \ -@GCRYPT_TRUE@ gcrypt/digest.c \ +@GCRYPT_TRUE@ gcrypt/digest.c gcrypt/digest.h \ @GCRYPT_TRUE@ gcrypt/ecdh.c \ @GCRYPT_TRUE@ gcrypt/ecdsa.c \ @GCRYPT_TRUE@ gcrypt/ecdsagen.c \ @@ -138,7 +138,7 @@ sbin_PROGRAMS = tincd$(EXEEXT) tinc$(EXEEXT) sptps_test$(EXEEXT) @GCRYPT_TRUE@am__append_14 = \ @GCRYPT_TRUE@ gcrypt/cipher.c \ @GCRYPT_TRUE@ gcrypt/crypto.c \ -@GCRYPT_TRUE@ gcrypt/digest.c \ +@GCRYPT_TRUE@ gcrypt/digest.c gcrypt/digest.h \ @GCRYPT_TRUE@ gcrypt/ecdh.c \ @GCRYPT_TRUE@ gcrypt/ecdsa.c \ @GCRYPT_TRUE@ gcrypt/prf.c @@ -162,9 +162,10 @@ am__installdirs = "$(DESTDIR)$(sbindir)" PROGRAMS = $(sbin_PROGRAMS) am__sptps_test_SOURCES_DIST = logger.c logger.h sptps.c sptps.h \ sptps_test.c utils.c utils.h openssl/cipher.c openssl/crypto.c \ - openssl/digest.c openssl/ecdh.c openssl/ecdsa.c openssl/prf.c \ - gcrypt/cipher.c gcrypt/crypto.c gcrypt/digest.c gcrypt/ecdh.c \ - gcrypt/ecdsa.c gcrypt/prf.c + openssl/digest.c openssl/digest.h openssl/ecdh.c \ + openssl/ecdsa.c openssl/prf.c gcrypt/cipher.c gcrypt/crypto.c \ + gcrypt/digest.c gcrypt/digest.h gcrypt/ecdh.c gcrypt/ecdsa.c \ + gcrypt/prf.c am__dirstamp = $(am__leading_dot)dirstamp @OPENSSL_TRUE@am__objects_1 = openssl/cipher.$(OBJEXT) \ @OPENSSL_TRUE@ openssl/crypto.$(OBJEXT) \ @@ -181,12 +182,13 @@ sptps_test_OBJECTS = $(am_sptps_test_OBJECTS) sptps_test_LDADD = $(LDADD) am__tinc_SOURCES_DIST = dropin.c dropin.h getopt.c getopt.h getopt1.c \ info.c info.h invitation.c invitation.h list.c list.h names.c \ - names.h netutl.c netutl.h sptps.c sptps.h subnet_parse.c \ - subnet.h tincctl.c tincctl.h top.c top.h utils.c utils.h \ - openssl/cipher.c openssl/crypto.c openssl/digest.c \ - openssl/ecdh.c openssl/ecdsa.c openssl/ecdsagen.c \ - openssl/prf.c openssl/rsa.c openssl/rsagen.c gcrypt/cipher.c \ - gcrypt/crypto.c gcrypt/digest.c gcrypt/ecdh.c gcrypt/ecdsa.c \ + names.h netutl.c netutl.h script.c script.h sptps.c sptps.h \ + subnet_parse.c subnet.h tincctl.c tincctl.h top.c top.h \ + utils.c utils.h openssl/cipher.c openssl/crypto.c \ + openssl/digest.c openssl/digest.h openssl/ecdh.c \ + openssl/ecdsa.c openssl/ecdsagen.c openssl/prf.c openssl/rsa.c \ + openssl/rsagen.c gcrypt/cipher.c gcrypt/crypto.c \ + gcrypt/digest.c gcrypt/digest.h gcrypt/ecdh.c gcrypt/ecdsa.c \ gcrypt/ecdsagen.c gcrypt/prf.c gcrypt/rsa.c gcrypt/rsagen.c @OPENSSL_TRUE@am__objects_3 = openssl/cipher.$(OBJEXT) \ @OPENSSL_TRUE@ openssl/crypto.$(OBJEXT) \ @@ -201,9 +203,10 @@ am__tinc_SOURCES_DIST = dropin.c dropin.h getopt.c getopt.h getopt1.c \ @GCRYPT_TRUE@ gcrypt/rsa.$(OBJEXT) gcrypt/rsagen.$(OBJEXT) am_tinc_OBJECTS = dropin.$(OBJEXT) getopt.$(OBJEXT) getopt1.$(OBJEXT) \ info.$(OBJEXT) invitation.$(OBJEXT) list.$(OBJEXT) \ - names.$(OBJEXT) netutl.$(OBJEXT) sptps.$(OBJEXT) \ - subnet_parse.$(OBJEXT) tincctl.$(OBJEXT) top.$(OBJEXT) \ - utils.$(OBJEXT) $(am__objects_3) $(am__objects_4) + names.$(OBJEXT) netutl.$(OBJEXT) script.$(OBJEXT) \ + sptps.$(OBJEXT) subnet_parse.$(OBJEXT) tincctl.$(OBJEXT) \ + top.$(OBJEXT) utils.$(OBJEXT) $(am__objects_3) \ + $(am__objects_4) tinc_OBJECTS = $(am_tinc_OBJECTS) am__DEPENDENCIES_1 = tinc_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) @@ -220,14 +223,16 @@ am__tincd_SOURCES_DIST = buffer.c buffer.h cipher.h conf.c conf.h \ node.h prf.h process.c process.h protocol.c protocol.h \ protocol_auth.c protocol_edge.c protocol_key.c protocol_misc.c \ protocol_subnet.c raw_socket_device.c route.c route.h rsa.h \ - rsagen.h splay_tree.c splay_tree.h sptps.c sptps.h subnet.c \ - subnet.h subnet_parse.c system.h tincd.c utils.c utils.h \ - xalloc.h linux/device.c bsd/device.c bsd/tunemu.c \ - solaris/device.c mingw/device.c cygwin/device.c uml_device.c \ - vde_device.c openssl/cipher.c openssl/crypto.c \ - openssl/digest.c openssl/ecdh.c openssl/ecdsa.c openssl/prf.c \ + rsagen.h script.c script.h splay_tree.c splay_tree.h sptps.c \ + sptps.h subnet.c subnet.h subnet_parse.c system.h tincd.c \ + utils.c utils.h xalloc.h linux/device.c bsd/device.c \ + bsd/tunemu.c bsd/tunemu.h solaris/device.c mingw/device.c \ + mingw/common.h cygwin/device.c uml_device.c vde_device.c \ + openssl/cipher.c openssl/crypto.c openssl/digest.c \ + openssl/digest.h openssl/ecdh.c openssl/ecdsa.c openssl/prf.c \ openssl/rsa.c gcrypt/cipher.c gcrypt/crypto.c gcrypt/digest.c \ - gcrypt/ecdh.c gcrypt/ecdsa.c gcrypt/prf.c gcrypt/rsa.c + gcrypt/digest.h gcrypt/ecdh.c gcrypt/ecdsa.c gcrypt/prf.c \ + gcrypt/rsa.c @LINUX_TRUE@am__objects_5 = linux/device.$(OBJEXT) @BSD_TRUE@am__objects_6 = bsd/device.$(OBJEXT) @BSD_TRUE@@TUNEMU_TRUE@am__objects_7 = bsd/tunemu.$(OBJEXT) @@ -257,7 +262,7 @@ am_tincd_OBJECTS = buffer.$(OBJEXT) conf.$(OBJEXT) \ protocol.$(OBJEXT) protocol_auth.$(OBJEXT) \ protocol_edge.$(OBJEXT) protocol_key.$(OBJEXT) \ protocol_misc.$(OBJEXT) protocol_subnet.$(OBJEXT) \ - raw_socket_device.$(OBJEXT) route.$(OBJEXT) \ + raw_socket_device.$(OBJEXT) route.$(OBJEXT) script.$(OBJEXT) \ splay_tree.$(OBJEXT) sptps.$(OBJEXT) subnet.$(OBJEXT) \ subnet_parse.$(OBJEXT) tincd.$(OBJEXT) utils.$(OBJEXT) \ $(am__objects_5) $(am__objects_6) $(am__objects_7) \ @@ -423,7 +428,6 @@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ -EXTRA_DIST = linux bsd solaris cygwin mingw openssl gcrypt DEFAULT_INCLUDES = tincd_SOURCES = buffer.c buffer.h cipher.h conf.c conf.h connection.c \ connection.h control.c control.h control_common.h crypto.h \ @@ -438,17 +442,17 @@ tincd_SOURCES = buffer.c buffer.h cipher.h conf.c conf.h connection.c \ process.c process.h protocol.c protocol.h protocol_auth.c \ protocol_edge.c protocol_key.c protocol_misc.c \ protocol_subnet.c raw_socket_device.c route.c route.h rsa.h \ - rsagen.h splay_tree.c splay_tree.h sptps.c sptps.h subnet.c \ - subnet.h subnet_parse.c system.h tincd.c utils.c utils.h \ - xalloc.h $(am__append_1) $(am__append_2) $(am__append_3) \ - $(am__append_4) $(am__append_5) $(am__append_6) \ - $(am__append_7) $(am__append_8) $(am__append_9) \ - $(am__append_12) + rsagen.h script.c script.h splay_tree.c splay_tree.h sptps.c \ + sptps.h subnet.c subnet.h subnet_parse.c system.h tincd.c \ + utils.c utils.h xalloc.h $(am__append_1) $(am__append_2) \ + $(am__append_3) $(am__append_4) $(am__append_5) \ + $(am__append_6) $(am__append_7) $(am__append_8) \ + $(am__append_9) $(am__append_12) tinc_SOURCES = dropin.c dropin.h getopt.c getopt.h getopt1.c info.c \ info.h invitation.c invitation.h list.c list.h names.c names.h \ - netutl.c netutl.h sptps.c sptps.h subnet_parse.c subnet.h \ - tincctl.c tincctl.h top.c top.h utils.c utils.h \ - $(am__append_10) $(am__append_13) + netutl.c netutl.h script.c script.h sptps.c sptps.h \ + subnet_parse.c subnet.h tincctl.c tincctl.h top.c top.h \ + utils.c utils.h $(am__append_10) $(am__append_13) sptps_test_SOURCES = logger.c logger.h sptps.c sptps.h sptps_test.c \ utils.c utils.h $(am__append_11) $(am__append_14) tinc_LDADD = $(READLINE_LIBS) $(CURSES_LIBS) @@ -697,6 +701,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protocol_subnet.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/raw_socket_device.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/route.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/script.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/splay_tree.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sptps.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sptps_test.Po@am__quote@ @@ -831,9 +836,6 @@ distdir: $(DISTFILES) || exit 1; \ fi; \ done - $(MAKE) $(AM_MAKEFLAGS) \ - top_distdir="$(top_distdir)" distdir="$(distdir)" \ - dist-hook check-am: all-am check: check-am all-am: Makefile $(PROGRAMS) @@ -957,23 +959,20 @@ uninstall-am: uninstall-sbinPROGRAMS .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ - clean-sbinPROGRAMS cscopelist-am ctags ctags-am dist-hook \ - distclean distclean-compile distclean-generic distclean-tags \ - distdir dvi dvi-am html html-am info info-am install \ - install-am install-data install-data-am install-dvi \ - install-dvi-am install-exec install-exec-am install-html \ - install-html-am install-info install-info-am install-man \ - install-pdf install-pdf-am install-ps install-ps-am \ - install-sbinPROGRAMS install-strip installcheck \ - installcheck-am installcheck-sbinPROGRAMS installdirs \ - maintainer-clean maintainer-clean-generic mostlyclean \ - mostlyclean-compile mostlyclean-generic pdf pdf-am ps ps-am \ - tags tags-am uninstall uninstall-am uninstall-sbinPROGRAMS + clean-sbinPROGRAMS cscopelist-am ctags ctags-am distclean \ + distclean-compile distclean-generic distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-ps install-ps-am install-sbinPROGRAMS \ + install-strip installcheck installcheck-am \ + installcheck-sbinPROGRAMS installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic pdf pdf-am ps ps-am tags tags-am uninstall \ + uninstall-am uninstall-sbinPROGRAMS -dist-hook: - rm -f `find . -type l` - # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: diff --git a/src/bsd/.deps/device.Po b/src/bsd/.deps/device.Po deleted file mode 100644 index 9ce06a8..0000000 --- a/src/bsd/.deps/device.Po +++ /dev/null @@ -1 +0,0 @@ -# dummy diff --git a/src/bsd/.deps/tunemu.Po b/src/bsd/.deps/tunemu.Po deleted file mode 100644 index 9ce06a8..0000000 --- a/src/bsd/.deps/tunemu.Po +++ /dev/null @@ -1 +0,0 @@ -# dummy diff --git a/src/control.c b/src/control.c index 84098be..f7d67ac 100644 --- a/src/control.c +++ b/src/control.c @@ -175,9 +175,50 @@ bool init_control(void) { free(localhost); fclose(f); +#ifndef HAVE_MINGW + int unix_fd = socket(AF_UNIX, SOCK_STREAM, 0); + if(unix_fd < 0) { + logger(DEBUG_ALWAYS, LOG_ERR, "Could not create UNIX socket: %s", sockstrerror(errno)); + return false; + } + + struct sockaddr_un sun; + sun.sun_family = AF_UNIX; + strncpy(sun.sun_path, unixsocketname, sizeof sun.sun_path); + + if(connect(unix_fd, (struct sockaddr *)&sun, sizeof sun) >= 0) { + logger(DEBUG_ALWAYS, LOG_ERR, "UNIX socket %s is still in use!", unixsocketname); + return false; + } + + unlink(unixsocketname); + + umask(mask | 077); + int result = bind(unix_fd, (struct sockaddr *)&sun, sizeof sun); + umask(mask); + + if(result < 0) { + logger(DEBUG_ALWAYS, LOG_ERR, "Could not bind UNIX socket to %s: %s", unixsocketname, sockstrerror(errno)); + return false; + } + + if(listen(unix_fd, 3) < 0) { + logger(DEBUG_ALWAYS, LOG_ERR, "Could not listen on UNIX socket %s: %s", unixsocketname, sockstrerror(errno)); + return false; + } + + io_add(&unix_socket, handle_new_unix_connection, &unix_socket, unix_fd, IO_READ); +#endif + return true; } void exit_control(void) { +#ifndef HAVE_MINGW + unlink(unixsocketname); + io_del(&unix_socket); + close(unix_socket.fd); +#endif + unlink(pidfilename); } diff --git a/src/cygwin/.deps/device.Po b/src/cygwin/.deps/device.Po deleted file mode 100644 index 9ce06a8..0000000 --- a/src/cygwin/.deps/device.Po +++ /dev/null @@ -1 +0,0 @@ -# dummy diff --git a/src/gcrypt/.deps/cipher.Po b/src/gcrypt/.deps/cipher.Po deleted file mode 100644 index 9ce06a8..0000000 --- a/src/gcrypt/.deps/cipher.Po +++ /dev/null @@ -1 +0,0 @@ -# dummy diff --git a/src/gcrypt/.deps/crypto.Po b/src/gcrypt/.deps/crypto.Po deleted file mode 100644 index 9ce06a8..0000000 --- a/src/gcrypt/.deps/crypto.Po +++ /dev/null @@ -1 +0,0 @@ -# dummy diff --git a/src/gcrypt/.deps/digest.Po b/src/gcrypt/.deps/digest.Po deleted file mode 100644 index 9ce06a8..0000000 --- a/src/gcrypt/.deps/digest.Po +++ /dev/null @@ -1 +0,0 @@ -# dummy diff --git a/src/gcrypt/.deps/ecdh.Po b/src/gcrypt/.deps/ecdh.Po deleted file mode 100644 index 9ce06a8..0000000 --- a/src/gcrypt/.deps/ecdh.Po +++ /dev/null @@ -1 +0,0 @@ -# dummy diff --git a/src/gcrypt/.deps/ecdsa.Po b/src/gcrypt/.deps/ecdsa.Po deleted file mode 100644 index 9ce06a8..0000000 --- a/src/gcrypt/.deps/ecdsa.Po +++ /dev/null @@ -1 +0,0 @@ -# dummy diff --git a/src/gcrypt/.deps/ecdsagen.Po b/src/gcrypt/.deps/ecdsagen.Po deleted file mode 100644 index 9ce06a8..0000000 --- a/src/gcrypt/.deps/ecdsagen.Po +++ /dev/null @@ -1 +0,0 @@ -# dummy diff --git a/src/gcrypt/.deps/prf.Po b/src/gcrypt/.deps/prf.Po deleted file mode 100644 index 9ce06a8..0000000 --- a/src/gcrypt/.deps/prf.Po +++ /dev/null @@ -1 +0,0 @@ -# dummy diff --git a/src/gcrypt/.deps/rsa.Po b/src/gcrypt/.deps/rsa.Po deleted file mode 100644 index 9ce06a8..0000000 --- a/src/gcrypt/.deps/rsa.Po +++ /dev/null @@ -1 +0,0 @@ -# dummy diff --git a/src/gcrypt/.deps/rsagen.Po b/src/gcrypt/.deps/rsagen.Po deleted file mode 100644 index 9ce06a8..0000000 --- a/src/gcrypt/.deps/rsagen.Po +++ /dev/null @@ -1 +0,0 @@ -# dummy diff --git a/src/gcrypt/cipher.h b/src/gcrypt/cipher.h deleted file mode 100644 index 389bb11..0000000 --- a/src/gcrypt/cipher.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - cipher.h -- header file cipher.c - Copyright (C) 2007-2009 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 - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#ifndef __TINC_CIPHER_H__ -#define __TINC_CIPHER_H__ - -#include - -#define CIPHER_MAX_BLOCK_SIZE 32 -#define CIPHER_MAX_IV_SIZE 16 -#define CIPHER_MAX_KEY_SIZE 32 - -typedef struct cipher { - gcry_cipher_hd_t handle; - char *key; - int nid; - uint16_t keylen; - uint16_t blklen; - bool padding; -} cipher_t; - -extern bool cipher_open_by_name(struct cipher *, const char *); -extern bool cipher_open_by_nid(struct cipher *, int); -extern bool cipher_open_blowfish_ofb(struct cipher *); -extern void cipher_close(struct cipher *); -extern size_t cipher_keylength(const struct cipher *); -extern void cipher_get_key(const struct cipher *, void *); -extern bool cipher_set_key(struct cipher *, void *, bool); -extern bool cipher_set_key_from_rsa(struct cipher *, void *, size_t, bool); -extern bool cipher_regenerate_key(struct cipher *, bool); -extern bool cipher_encrypt(struct cipher *, const void *indata, size_t inlen, void *outdata, size_t *outlen, bool oneshot); -extern bool cipher_decrypt(struct cipher *, const void *indata, size_t inlen, void *outdata, size_t *outlen, bool oneshot); -extern int cipher_get_nid(const struct cipher *); -extern bool cipher_active(const struct cipher *); - -#endif diff --git a/src/gcrypt/rsa.h b/src/gcrypt/rsa.h deleted file mode 100644 index 143f015..0000000 --- a/src/gcrypt/rsa.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - rsa.h -- RSA key handling - Copyright (C) 2007 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 - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#ifndef __TINC_RSA_H__ -#define __TINC_RSA_H__ - -#include - -typedef struct rsa { - gcry_mpi_t n; - gcry_mpi_t e; - gcry_mpi_t d; -} rsa_t; - -extern bool rsa_set_hex_public_key(rsa_t *rsa, char *n, char *e); -extern bool rsa_set_hex_private_key(rsa_t *rsa, char *n, char *e, char *d); -extern bool rsa_read_pem_public_key(rsa_t *rsa, FILE *fp); -extern bool rsa_read_pem_private_key(rsa_t *rsa, FILE *fp); -extern size_t rsa_size(rsa_t *rsa); -extern bool rsa_public_encrypt(rsa_t *rsa, void *in, size_t len, void *out); -extern bool rsa_private_decrypt(rsa_t *rsa, void *in, size_t len, void *out); - -#endif diff --git a/src/gcrypt/rsagen.h b/src/gcrypt/rsagen.h deleted file mode 100644 index 422d156..0000000 --- a/src/gcrypt/rsagen.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - rsagen.h -- RSA key generation and export - Copyright (C) 2008 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 - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#ifndef __TINC_RSAGEN_H__ -#define __TINC_RSAGEN_H__ - -#include "rsa.h" - -extern bool rsa_generate(rsa_t *rsa, size_t bits, unsigned long exponent); -extern bool rsa_write_pem_public_key(rsa_t *rsa, FILE *fp); -extern bool rsa_write_pem_private_key(rsa_t *rsa, FILE *fp); - -#endif diff --git a/src/graph.c b/src/graph.c index b4c01bb..396e35a 100644 --- a/src/graph.c +++ b/src/graph.c @@ -53,8 +53,8 @@ #include "names.h" #include "netutl.h" #include "node.h" -#include "process.h" #include "protocol.h" +#include "script.h" #include "subnet.h" #include "utils.h" #include "xalloc.h" diff --git a/src/invitation.c b/src/invitation.c index f1cde58..59bcf45 100644 --- a/src/invitation.c +++ b/src/invitation.c @@ -27,19 +27,56 @@ #include "names.h" #include "netutl.h" #include "rsagen.h" +#include "script.h" #include "sptps.h" #include "tincctl.h" #include "utils.h" #include "xalloc.h" -#ifdef HAVE_MINGW -#define SCRIPTEXTENSION ".bat" -#else -#define SCRIPTEXTENSION "" -#endif - int addressfamily = AF_UNSPEC; +static void scan_for_hostname(const char *filename, char **hostname, char **port) { + if(!filename || (*hostname && *port)) + return; + + FILE *f = fopen(filename, "r"); + if(!f) + return; + + while(fgets(line, sizeof line, f)) { + if(!rstrip(line)) + continue; + char *p = line, *q; + p += strcspn(p, "\t ="); + if(!*p) + continue; + q = p + strspn(p, "\t "); + if(*q == '=') + q += 1 + strspn(q + 1, "\t "); + *p = 0; + p = q + strcspn(q, "\t "); + if(*p) + *p++ = 0; + p += strspn(p, "\t "); + p[strcspn(p, "\t ")] = 0; + + if(!*port && !strcasecmp(line, "Port")) { + *port = xstrdup(q); + } else if(!*hostname && !strcasecmp(line, "Address")) { + *hostname = xstrdup(q); + if(*p) { + free(*port); + *port = xstrdup(p); + } + } + + if(*hostname && *port) + break; + } + + fclose(f); +} + char *get_my_hostname() { char *hostname = NULL; char *port = NULL; @@ -50,39 +87,8 @@ char *get_my_hostname() { // Use first Address statement in own host config file if(check_id(name)) { xasprintf(&filename, "%s" SLASH "hosts" SLASH "%s", confbase, name); - FILE *f = fopen(filename, "r"); - if(f) { - while(fgets(line, sizeof line, f)) { - if(!rstrip(line)) - continue; - char *p = line, *q; - p += strcspn(p, "\t ="); - if(!*p) - continue; - q = p + strspn(p, "\t "); - if(*q == '=') - q += 1 + strspn(q + 1, "\t "); - *p = 0; - p = q + strcspn(q, "\t "); - if(*p) - *p++ = 0; - p += strspn(p, "\t "); - p[strcspn(p, "\t ")] = 0; - if(!port && !strcasecmp(line, "Port")) { - port = xstrdup(q); - continue; - } - if(strcasecmp(line, "Address")) - continue; - hostname = xstrdup(q); - if(*p) { - free(port); - port = xstrdup(p); - } - break; - } - fclose(f); - } + scan_for_hostname(filename, &hostname, &port); + scan_for_hostname(tinc_conf, &hostname, &port); } if(hostname) @@ -90,12 +96,14 @@ char *get_my_hostname() { // If that doesn't work, guess externally visible hostname fprintf(stderr, "Trying to discover externally visible hostname...\n"); - struct addrinfo *ai = str2addrinfo("ifconfig.me", "80", SOCK_STREAM); - static const char request[] = "GET /host HTTP/1.0\r\n\r\n"; - if(ai) { - int s = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); + struct addrinfo *ai = str2addrinfo("tinc-vpn.org", "80", SOCK_STREAM); + struct addrinfo *aip = ai; + static const char request[] = "GET http://tinc-vpn.org/host.cgi HTTP/1.0\r\n\r\n"; + + while(aip) { + int s = socket(aip->ai_family, aip->ai_socktype, aip->ai_protocol); if(s >= 0) { - if(connect(s, ai->ai_addr, ai->ai_addrlen)) { + if(connect(s, aip->ai_addr, aip->ai_addrlen)) { closesocket(s); s = -1; } @@ -112,14 +120,20 @@ char *get_my_hostname() { hostname = xstrdup(p + 1); } closesocket(s); + if(hostname) + break; } - freeaddrinfo(ai); + aip = aip->ai_next; + continue; } + if(ai) + freeaddrinfo(ai); + // Check that the hostname is reasonable if(hostname) { for(char *p = hostname; *p; p++) { - if(isalnum(*p) || *p == '-' || *p == '.') + if(isalnum(*p) || *p == '-' || *p == '.' || *p == ':') continue; // If not, forget it. free(hostname); @@ -326,12 +340,17 @@ int cmd_invite(int argc, char *argv[]) { } chmod(filename, 0600); ecdsa_write_pem_private_key(key, f); + fclose(f); + + if(connect_tincd(false)) + sendline(fd, "%d %d", CONTROL, REQ_RELOAD); } else { key = ecdsa_read_pem_private_key(f); + fclose(f); if(!key) fprintf(stderr, "Could not read private key from %s\n", filename); } - fclose(f); + free(filename); if(!key) return 1; @@ -347,37 +366,76 @@ int cmd_invite(int argc, char *argv[]) { // Create a random cookie for this invitation. char cookie[25]; randomize(cookie, 18); + + // Create a filename that doesn't reveal the cookie itself + char buf[18 + strlen(fingerprint)]; + char cookiehash[25]; + memcpy(buf, cookie, 18); + memcpy(buf + 18, fingerprint, sizeof buf - 18); + digest_create(digest, buf, sizeof buf, cookiehash); + b64encode_urlsafe(cookiehash, cookiehash, 18); + b64encode_urlsafe(cookie, cookie, 18); // Create a file containing the details of the invitation. - xasprintf(&filename, "%s" SLASH "invitations" SLASH "%s", confbase, cookie); + xasprintf(&filename, "%s" SLASH "invitations" SLASH "%s", confbase, cookiehash); int ifd = open(filename, O_RDWR | O_CREAT | O_EXCL, 0600); if(!ifd) { fprintf(stderr, "Could not create invitation file %s: %s\n", filename, strerror(errno)); free(filename); return 1; } - free(filename); f = fdopen(ifd, "w"); if(!f) abort(); + // Get the local address + char *address = get_my_hostname(); + // Fill in the details. fprintf(f, "Name = %s\n", argv[1]); if(netname) fprintf(f, "NetName = %s\n", netname); fprintf(f, "ConnectTo = %s\n", myname); - // TODO: copy Broadcast and Mode + + // Copy Broadcast and Mode + FILE *tc = fopen(tinc_conf, "r"); + if(tc) { + char buf[1024]; + while(fgets(buf, sizeof buf, tc)) { + if((!strncasecmp(buf, "Mode", 4) && strchr(" \t=", buf[4])) + || (!strncasecmp(buf, "Broadcast", 9) && strchr(" \t=", buf[9]))) + fputs(buf, f); + } + fclose(tc); + } + fprintf(f, "#---------------------------------------------------------------#\n"); fprintf(f, "Name = %s\n", myname); - xasprintf(&filename, "%s" SLASH "hosts" SLASH "%s", confbase, myname); - fcopy(f, filename); + char *filename2; + xasprintf(&filename2, "%s" SLASH "hosts" SLASH "%s", confbase, myname); + fcopy(f, filename2); fclose(f); + free(filename2); // Create an URL from the local address, key hash and cookie - char *address = get_my_hostname(); - printf("%s/%s%s\n", address, hash, cookie); + char *url; + xasprintf(&url, "%s/%s%s", address, hash, cookie); + + // Call the inviation-created script + char *envp[6] = {}; + xasprintf(&envp[0], "NAME=%s", myname); + xasprintf(&envp[1], "NETNAME=%s", netname); + xasprintf(&envp[2], "NODE=%s", argv[1]); + xasprintf(&envp[3], "INVITATION_FILE=%s", filename); + xasprintf(&envp[4], "INVITATION_URL=%s", url); + execute_script("invitation-created", envp); + for(int i = 0; i < 6 && envp[i]; i++) + free(envp[i]); + + puts(url); + free(url); free(filename); free(address); @@ -684,10 +742,6 @@ make_names: check_port(name); - fprintf(stderr, "Invitation succesfully accepted.\n"); - shutdown(sock, SHUT_RDWR); - success = true; - ask_netname: if(ask_netname) { fprintf(stderr, "Enter a new netname: "); @@ -716,6 +770,7 @@ ask_netname: return true; } + static bool invitation_send(void *handle, uint8_t type, const char *data, size_t len) { while(len) { int result = send(sock, data, len, 0); @@ -744,6 +799,12 @@ static bool invitation_receive(void *handle, uint8_t type, const char *msg, uint case 1: return finalize_join(); + case 2: + fprintf(stderr, "Invitation succesfully accepted.\n"); + shutdown(sock, SHUT_RDWR); + success = true; + break; + default: return false; } @@ -762,7 +823,7 @@ int cmd_join(int argc, char *argv[]) { } // Make sure confbase exists and is accessible. - if(strcmp(confdir, confbase) && mkdir(confdir, 0755) && errno != EEXIST) { + if(!confbase_given && mkdir(confdir, 0755) && errno != EEXIST) { fprintf(stderr, "Could not create directory %s: %s\n", confdir, strerror(errno)); return 1; } diff --git a/src/linux/.deps/.dirstamp b/src/linux/.deps/.dirstamp deleted file mode 100644 index e69de29..0000000 diff --git a/src/linux/.deps/device.Po b/src/linux/.deps/device.Po deleted file mode 100644 index 8541068..0000000 --- a/src/linux/.deps/device.Po +++ /dev/null @@ -1,467 +0,0 @@ -linux/device.o: linux/device.c /usr/include/stdc-predef.h \ - /usr/include/x86_64-linux-gnu/bits/predefs.h linux/../system.h \ - linux/../../config.h linux/../have.h /usr/include/stdio.h \ - /usr/include/features.h /usr/include/x86_64-linux-gnu/sys/cdefs.h \ - /usr/include/x86_64-linux-gnu/bits/wordsize.h \ - /usr/include/x86_64-linux-gnu/gnu/stubs.h \ - /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ - /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stddef.h \ - /usr/include/x86_64-linux-gnu/bits/types.h \ - /usr/include/x86_64-linux-gnu/bits/typesizes.h /usr/include/libio.h \ - /usr/include/_G_config.h /usr/include/wchar.h \ - /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdarg.h \ - /usr/include/x86_64-linux-gnu/bits/stdio_lim.h \ - /usr/include/x86_64-linux-gnu/bits/sys_errlist.h \ - /usr/include/x86_64-linux-gnu/bits/stdio.h /usr/include/stdlib.h \ - /usr/include/x86_64-linux-gnu/bits/waitflags.h \ - /usr/include/x86_64-linux-gnu/bits/waitstatus.h /usr/include/endian.h \ - /usr/include/x86_64-linux-gnu/bits/endian.h \ - /usr/include/x86_64-linux-gnu/bits/byteswap.h \ - /usr/include/x86_64-linux-gnu/bits/byteswap-16.h /usr/include/xlocale.h \ - /usr/include/x86_64-linux-gnu/sys/types.h /usr/include/time.h \ - /usr/include/x86_64-linux-gnu/sys/select.h \ - /usr/include/x86_64-linux-gnu/bits/select.h \ - /usr/include/x86_64-linux-gnu/bits/sigset.h \ - /usr/include/x86_64-linux-gnu/bits/time.h \ - /usr/include/x86_64-linux-gnu/sys/sysmacros.h \ - /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h /usr/include/alloca.h \ - /usr/include/x86_64-linux-gnu/bits/stdlib-float.h /usr/include/string.h \ - /usr/include/x86_64-linux-gnu/bits/string.h \ - /usr/include/x86_64-linux-gnu/bits/string2.h /usr/include/ctype.h \ - /usr/include/signal.h /usr/include/x86_64-linux-gnu/bits/signum.h \ - /usr/include/x86_64-linux-gnu/bits/siginfo.h \ - /usr/include/x86_64-linux-gnu/bits/sigaction.h \ - /usr/include/x86_64-linux-gnu/bits/sigcontext.h \ - /usr/include/x86_64-linux-gnu/bits/sigstack.h \ - /usr/include/x86_64-linux-gnu/sys/ucontext.h \ - /usr/include/x86_64-linux-gnu/bits/sigthread.h /usr/include/errno.h \ - /usr/include/x86_64-linux-gnu/bits/errno.h /usr/include/linux/errno.h \ - /usr/include/x86_64-linux-gnu/asm/errno.h \ - /usr/include/asm-generic/errno.h /usr/include/asm-generic/errno-base.h \ - /usr/include/fcntl.h /usr/include/x86_64-linux-gnu/bits/fcntl.h \ - /usr/include/x86_64-linux-gnu/bits/fcntl-linux.h \ - /usr/include/x86_64-linux-gnu/bits/uio.h \ - /usr/include/x86_64-linux-gnu/bits/stat.h /usr/include/unistd.h \ - /usr/include/x86_64-linux-gnu/bits/posix_opt.h \ - /usr/include/x86_64-linux-gnu/bits/environments.h \ - /usr/include/x86_64-linux-gnu/bits/confname.h /usr/include/getopt.h \ - /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdbool.h \ - /usr/include/inttypes.h \ - /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdint.h /usr/include/stdint.h \ - /usr/include/x86_64-linux-gnu/bits/wchar.h /usr/include/syslog.h \ - /usr/include/x86_64-linux-gnu/sys/syslog.h \ - /usr/include/x86_64-linux-gnu/bits/syslog-path.h \ - /usr/include/x86_64-linux-gnu/sys/time.h \ - /usr/include/x86_64-linux-gnu/bits/timex.h \ - /usr/include/x86_64-linux-gnu/sys/stat.h \ - /usr/include/x86_64-linux-gnu/sys/file.h \ - /usr/include/x86_64-linux-gnu/sys/wait.h \ - /usr/include/x86_64-linux-gnu/sys/ioctl.h \ - /usr/include/x86_64-linux-gnu/bits/ioctls.h \ - /usr/include/x86_64-linux-gnu/asm/ioctls.h \ - /usr/include/asm-generic/ioctls.h /usr/include/linux/ioctl.h \ - /usr/include/x86_64-linux-gnu/asm/ioctl.h \ - /usr/include/asm-generic/ioctl.h \ - /usr/include/x86_64-linux-gnu/bits/ioctl-types.h \ - /usr/include/x86_64-linux-gnu/sys/ttydefaults.h \ - /usr/include/x86_64-linux-gnu/sys/param.h \ - /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/limits.h \ - /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/syslimits.h \ - /usr/include/limits.h /usr/include/x86_64-linux-gnu/bits/posix1_lim.h \ - /usr/include/x86_64-linux-gnu/bits/local_lim.h \ - /usr/include/linux/limits.h \ - /usr/include/x86_64-linux-gnu/bits/posix2_lim.h \ - /usr/include/x86_64-linux-gnu/bits/xopen_lim.h \ - /usr/include/x86_64-linux-gnu/bits/param.h /usr/include/linux/param.h \ - /usr/include/x86_64-linux-gnu/asm/param.h \ - /usr/include/asm-generic/param.h \ - /usr/include/x86_64-linux-gnu/sys/resource.h \ - /usr/include/x86_64-linux-gnu/bits/resource.h \ - /usr/include/x86_64-linux-gnu/sys/uio.h \ - /usr/include/x86_64-linux-gnu/sys/un.h \ - /usr/include/x86_64-linux-gnu/bits/sockaddr.h /usr/include/dirent.h \ - /usr/include/x86_64-linux-gnu/bits/dirent.h /usr/include/netdb.h \ - /usr/include/netinet/in.h /usr/include/x86_64-linux-gnu/sys/socket.h \ - /usr/include/x86_64-linux-gnu/bits/socket.h \ - /usr/include/x86_64-linux-gnu/bits/socket_type.h \ - /usr/include/x86_64-linux-gnu/asm/socket.h \ - /usr/include/asm-generic/socket.h \ - /usr/include/x86_64-linux-gnu/asm/sockios.h \ - /usr/include/asm-generic/sockios.h \ - /usr/include/x86_64-linux-gnu/bits/in.h /usr/include/rpc/netdb.h \ - /usr/include/x86_64-linux-gnu/bits/netdb.h /usr/include/net/if.h \ - /usr/include/netinet/in_systm.h /usr/include/arpa/inet.h \ - /usr/include/netinet/ip.h /usr/include/netinet/tcp.h \ - /usr/include/netinet/ip6.h /usr/include/net/ethernet.h \ - /usr/include/linux/if_ether.h /usr/include/linux/types.h \ - /usr/include/x86_64-linux-gnu/asm/types.h \ - /usr/include/asm-generic/types.h /usr/include/asm-generic/int-ll64.h \ - /usr/include/x86_64-linux-gnu/asm/bitsperlong.h \ - /usr/include/asm-generic/bitsperlong.h /usr/include/linux/posix_types.h \ - /usr/include/linux/stddef.h \ - /usr/include/x86_64-linux-gnu/asm/posix_types.h \ - /usr/include/x86_64-linux-gnu/asm/posix_types_64.h \ - /usr/include/asm-generic/posix_types.h /usr/include/net/if_arp.h \ - /usr/include/netinet/ip_icmp.h /usr/include/netinet/icmp6.h \ - /usr/include/netinet/if_ether.h linux/../dropin.h \ - linux/../fake-getaddrinfo.h linux/../fake-gai-errnos.h \ - linux/../fake-getnameinfo.h /usr/include/linux/if_tun.h \ - /usr/include/linux/filter.h linux/../conf.h linux/../splay_tree.h \ - linux/../list.h linux/../subnet.h linux/../net.h linux/../ipv6.h \ - linux/../cipher.h linux/../digest.h linux/../event.h linux/../conf.h \ - linux/../connection.h linux/../buffer.h linux/../rsa.h linux/../sptps.h \ - linux/../system.h linux/../ecdh.h linux/../ecdsa.h linux/../edge.h \ - linux/../node.h linux/../device.h linux/../logger.h linux/../names.h \ - linux/../net.h linux/../route.h linux/../utils.h linux/../xalloc.h - -/usr/include/stdc-predef.h: - -/usr/include/x86_64-linux-gnu/bits/predefs.h: - -linux/../system.h: - -linux/../../config.h: - -linux/../have.h: - -/usr/include/stdio.h: - -/usr/include/features.h: - -/usr/include/x86_64-linux-gnu/sys/cdefs.h: - -/usr/include/x86_64-linux-gnu/bits/wordsize.h: - -/usr/include/x86_64-linux-gnu/gnu/stubs.h: - -/usr/include/x86_64-linux-gnu/gnu/stubs-64.h: - -/usr/lib/gcc/x86_64-linux-gnu/4.8/include/stddef.h: - -/usr/include/x86_64-linux-gnu/bits/types.h: - -/usr/include/x86_64-linux-gnu/bits/typesizes.h: - -/usr/include/libio.h: - -/usr/include/_G_config.h: - -/usr/include/wchar.h: - -/usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdarg.h: - -/usr/include/x86_64-linux-gnu/bits/stdio_lim.h: - -/usr/include/x86_64-linux-gnu/bits/sys_errlist.h: - -/usr/include/x86_64-linux-gnu/bits/stdio.h: - -/usr/include/stdlib.h: - -/usr/include/x86_64-linux-gnu/bits/waitflags.h: - -/usr/include/x86_64-linux-gnu/bits/waitstatus.h: - -/usr/include/endian.h: - -/usr/include/x86_64-linux-gnu/bits/endian.h: - -/usr/include/x86_64-linux-gnu/bits/byteswap.h: - -/usr/include/x86_64-linux-gnu/bits/byteswap-16.h: - -/usr/include/xlocale.h: - -/usr/include/x86_64-linux-gnu/sys/types.h: - -/usr/include/time.h: - -/usr/include/x86_64-linux-gnu/sys/select.h: - -/usr/include/x86_64-linux-gnu/bits/select.h: - -/usr/include/x86_64-linux-gnu/bits/sigset.h: - -/usr/include/x86_64-linux-gnu/bits/time.h: - -/usr/include/x86_64-linux-gnu/sys/sysmacros.h: - -/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h: - -/usr/include/alloca.h: - -/usr/include/x86_64-linux-gnu/bits/stdlib-float.h: - -/usr/include/string.h: - -/usr/include/x86_64-linux-gnu/bits/string.h: - -/usr/include/x86_64-linux-gnu/bits/string2.h: - -/usr/include/ctype.h: - -/usr/include/signal.h: - -/usr/include/x86_64-linux-gnu/bits/signum.h: - -/usr/include/x86_64-linux-gnu/bits/siginfo.h: - -/usr/include/x86_64-linux-gnu/bits/sigaction.h: - -/usr/include/x86_64-linux-gnu/bits/sigcontext.h: - -/usr/include/x86_64-linux-gnu/bits/sigstack.h: - -/usr/include/x86_64-linux-gnu/sys/ucontext.h: - -/usr/include/x86_64-linux-gnu/bits/sigthread.h: - -/usr/include/errno.h: - -/usr/include/x86_64-linux-gnu/bits/errno.h: - -/usr/include/linux/errno.h: - -/usr/include/x86_64-linux-gnu/asm/errno.h: - -/usr/include/asm-generic/errno.h: - -/usr/include/asm-generic/errno-base.h: - -/usr/include/fcntl.h: - -/usr/include/x86_64-linux-gnu/bits/fcntl.h: - -/usr/include/x86_64-linux-gnu/bits/fcntl-linux.h: - -/usr/include/x86_64-linux-gnu/bits/uio.h: - -/usr/include/x86_64-linux-gnu/bits/stat.h: - -/usr/include/unistd.h: - -/usr/include/x86_64-linux-gnu/bits/posix_opt.h: - -/usr/include/x86_64-linux-gnu/bits/environments.h: - -/usr/include/x86_64-linux-gnu/bits/confname.h: - -/usr/include/getopt.h: - -/usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdbool.h: - -/usr/include/inttypes.h: - -/usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdint.h: - -/usr/include/stdint.h: - -/usr/include/x86_64-linux-gnu/bits/wchar.h: - -/usr/include/syslog.h: - -/usr/include/x86_64-linux-gnu/sys/syslog.h: - -/usr/include/x86_64-linux-gnu/bits/syslog-path.h: - -/usr/include/x86_64-linux-gnu/sys/time.h: - -/usr/include/x86_64-linux-gnu/bits/timex.h: - -/usr/include/x86_64-linux-gnu/sys/stat.h: - -/usr/include/x86_64-linux-gnu/sys/file.h: - -/usr/include/x86_64-linux-gnu/sys/wait.h: - -/usr/include/x86_64-linux-gnu/sys/ioctl.h: - -/usr/include/x86_64-linux-gnu/bits/ioctls.h: - -/usr/include/x86_64-linux-gnu/asm/ioctls.h: - -/usr/include/asm-generic/ioctls.h: - -/usr/include/linux/ioctl.h: - -/usr/include/x86_64-linux-gnu/asm/ioctl.h: - -/usr/include/asm-generic/ioctl.h: - -/usr/include/x86_64-linux-gnu/bits/ioctl-types.h: - -/usr/include/x86_64-linux-gnu/sys/ttydefaults.h: - -/usr/include/x86_64-linux-gnu/sys/param.h: - -/usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/limits.h: - -/usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/syslimits.h: - -/usr/include/limits.h: - -/usr/include/x86_64-linux-gnu/bits/posix1_lim.h: - -/usr/include/x86_64-linux-gnu/bits/local_lim.h: - -/usr/include/linux/limits.h: - -/usr/include/x86_64-linux-gnu/bits/posix2_lim.h: - -/usr/include/x86_64-linux-gnu/bits/xopen_lim.h: - -/usr/include/x86_64-linux-gnu/bits/param.h: - -/usr/include/linux/param.h: - -/usr/include/x86_64-linux-gnu/asm/param.h: - -/usr/include/asm-generic/param.h: - -/usr/include/x86_64-linux-gnu/sys/resource.h: - -/usr/include/x86_64-linux-gnu/bits/resource.h: - -/usr/include/x86_64-linux-gnu/sys/uio.h: - -/usr/include/x86_64-linux-gnu/sys/un.h: - -/usr/include/x86_64-linux-gnu/bits/sockaddr.h: - -/usr/include/dirent.h: - -/usr/include/x86_64-linux-gnu/bits/dirent.h: - -/usr/include/netdb.h: - -/usr/include/netinet/in.h: - -/usr/include/x86_64-linux-gnu/sys/socket.h: - -/usr/include/x86_64-linux-gnu/bits/socket.h: - -/usr/include/x86_64-linux-gnu/bits/socket_type.h: - -/usr/include/x86_64-linux-gnu/asm/socket.h: - -/usr/include/asm-generic/socket.h: - -/usr/include/x86_64-linux-gnu/asm/sockios.h: - -/usr/include/asm-generic/sockios.h: - -/usr/include/x86_64-linux-gnu/bits/in.h: - -/usr/include/rpc/netdb.h: - -/usr/include/x86_64-linux-gnu/bits/netdb.h: - -/usr/include/net/if.h: - -/usr/include/netinet/in_systm.h: - -/usr/include/arpa/inet.h: - -/usr/include/netinet/ip.h: - -/usr/include/netinet/tcp.h: - -/usr/include/netinet/ip6.h: - -/usr/include/net/ethernet.h: - -/usr/include/linux/if_ether.h: - -/usr/include/linux/types.h: - -/usr/include/x86_64-linux-gnu/asm/types.h: - -/usr/include/asm-generic/types.h: - -/usr/include/asm-generic/int-ll64.h: - -/usr/include/x86_64-linux-gnu/asm/bitsperlong.h: - -/usr/include/asm-generic/bitsperlong.h: - -/usr/include/linux/posix_types.h: - -/usr/include/linux/stddef.h: - -/usr/include/x86_64-linux-gnu/asm/posix_types.h: - -/usr/include/x86_64-linux-gnu/asm/posix_types_64.h: - -/usr/include/asm-generic/posix_types.h: - -/usr/include/net/if_arp.h: - -/usr/include/netinet/ip_icmp.h: - -/usr/include/netinet/icmp6.h: - -/usr/include/netinet/if_ether.h: - -linux/../dropin.h: - -linux/../fake-getaddrinfo.h: - -linux/../fake-gai-errnos.h: - -linux/../fake-getnameinfo.h: - -/usr/include/linux/if_tun.h: - -/usr/include/linux/filter.h: - -linux/../conf.h: - -linux/../splay_tree.h: - -linux/../list.h: - -linux/../subnet.h: - -linux/../net.h: - -linux/../ipv6.h: - -linux/../cipher.h: - -linux/../digest.h: - -linux/../event.h: - -linux/../conf.h: - -linux/../connection.h: - -linux/../buffer.h: - -linux/../rsa.h: - -linux/../sptps.h: - -linux/../system.h: - -linux/../ecdh.h: - -linux/../ecdsa.h: - -linux/../edge.h: - -linux/../node.h: - -linux/../device.h: - -linux/../logger.h: - -linux/../names.h: - -linux/../net.h: - -linux/../route.h: - -linux/../utils.h: - -linux/../xalloc.h: diff --git a/src/linux/.dirstamp b/src/linux/.dirstamp deleted file mode 100644 index e69de29..0000000 diff --git a/src/linux/device.o b/src/linux/device.o deleted file mode 100644 index 650284357e0010cc29a196a64c5cb9a715026613..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 24392 zcmb_^3z(F}m3DpIGh;J%7%qc=H20fx<1Ppc43`-}KxPn#nx*t-u>-S20nwR-CG6I4v3uy`PhQ3QDzjqyFIO z^r{2zd6@;x6{o5WFGKt0BdJnjz`@gdE+gFEd_bG(HGBH}G`f1#H%X7C(b;Z0`njet z>ba)T>cDS{n>&6WlJ@=|qjj-9iD{uk3g zv;86^qglx-IVCp+51cM;KGReRnP-|t;zTOnJls_=@fH-=!GBv%_@Ct(FiX|$Uf@X#48^On<@3r}TjZ6?><@}!U29MVI~&2$S*ciT>4M)Se* z=~2c=i0B<4g2vPr$c~SZUUAz`DTGcSj1HYSNlj>Ej11FJqwLJ;sg*FWnKIRq2})+B zWa^R8t@CVbK0HA)4*s;_mVYKqT=`4QBvTLmo~pG8XLOG>IhXA^)HXF}d*Qj&Q!9*` z<|FB;70p>Urc3tSKvfk7Un3FChZkr;N3Nb)*?jPwblC}Xq4|(eYkJpky7|ygPM&Qm zXk=S5i<$KcYe1|aw@~H$6Led#4n z`^Z@10t`*F?Tyt_gKzx%U(cVX5L->re)EQ@K^1(X?ELxjko%l=q4(yqJYRLk4x9Mr zWvu0pnSA+k9Hv?G9IpAXnWK3N!5f!oMPh2j!7Hfz#&WVpYf@A?PZnoWYdV~crqa=l zRIn?N3{FeY-x3u}C(_|quzhbjk_txSOM<~^4fU~1KAy;=moVNGj?YL3cPFFi2sLFX zbW*D${n3tys_TsO*Tp00x^yP4TH@(QvMWq*Qz8@V48{}bV4^P)hvreG)R`Fut zJM)OEl^4F-PPLr>Gx!06{{{IOErRIdu})8kNG_*rz)`1K)VIsZ9ym&f7r?F3iS zC@vwaDDV`ON-&@>yYyp}0gB<&=w}42BJ^`qCkb_I(x&a zID>qZR#n`O{76+*S-k%g3DkE(#kU}9)ITrkD^yi=@vT?Wd^VgzryHhVOez4OYf+`DoXeKME5`(A2hyfCx)#+%6?)02a62`Ftb zFRA{KkV?iQYe*#%G^`t!OhVpF=aR|Do9SFK1^J-i%s{};q)~uQJ(eZ2a@jd&2r}r! ze<4Cqz+b4;sB${!h!JDzItVcW=ON4a`5HF(V&vJFC9ma-S$ZyK%rbZk#{4X6%nInz z(Ge^i_Yb0_bo?X4G+Ih0AaA0h^djVqmePrkR&C5L4W_BB?n&7qjMixSsN0LmS__LP zgkq7nDrkzC)jdK-f0WAOQ&hr2Hla`X>H({ZaPYo?BhoeI zq`dq8O8kjjQj;r``Z57QZ>v`y^xC{dLGOxTm^3Ek5nucO;v{JSi9<P98t{&VIS^M*P453Fv=x8nUmBL(K|Cb#%F_z{Ys70Ld?w?54?5rW5 zC*9e?vuYbr*-Yly&Lzr1^2;QE*wIpEVhdRI0|7T@HkjcWF_HCBN37w7764 zt1BxEx*TCuO!i{oL4`?uR#-MFAuQi$E687^%6%k|;>hY%w$p`lBYu47YP3E%bTwN4 zeCX=gRQ-;r_7~G;L00P;su)4LESSP`DGa@aTpd(4n7W}1-aK^mPLiC_)mwe3p*jr} zcMmP&dXn)aQ;l%SnRXvloVA2s;Wg$ePg3QZrd44nHUX$#WI~RB)}ttP^M*=KZ-O8y z8y%PfSzlqMuQ$!i+Psk1gLwvB?=!>!UC)XhFvauqe8tw|tZ&(H`+!9-=xsrlRUKm4 zn~iH%&Qb%`;Iia`wYZ0KL494zf%TAC^cZgNP4)}fZ0XcVH1!)m@Md8p&9yS%oP4DQ zym&CMp)k)9!<;)9IBzg;{$Sv@|4a)(&ZM%3$ynWm;TOULovp0FErH3-#X>e0y{Tx% zHL3z#G6!7T=c)Oq8xi*&qY{=SQ};5JDr!)rx2i_^d<#*ip8FN5&`qj7tsfL|70^vs zP>&Xb_1OqILamG-qbRH&#}JgJm0sXS{>sC;QvtG(Gip>Jx`WA80Xvm`_9$&QPXIm@ z7^DhN=u(NBP*cAEy`5M|Rr-L38mga0Kv|YF`mT0Dv1(|^+KhRo{pdreLhKvkQDP5O zjr5^}>1>)=R?UOfW2n(ukt3}DFQJ^d`%NHyU%a@caEoq_k+doy6lq{!ux|!rG-F_5S5K7u{0_%b*&tG0r zf<_({17%qWi-|Uji-j#!C>D!+dMNX}mMXL;rJbg#I;t$2P8qrkjq+xUHB}Xb8mXL4 z1`i*lX3$;c2oe}D7D8av7%!)LWKK7&T@VBLqqTvBV&E99j>fYZ0-h=?Fojg|koahXrcyHnd32vAqLrFXrdXsIhQzXG=Ir#5;#m`@ z^%igInC&Gybf;z)s)j1ao>M|7-D}L}at)X;MwqoF)Rhr5^Xn{qB(gqNTru`i8l?ss zfYQ0O-ioo}%}cds<`JysXYoRK+0-nkRZJ!j;udBBJr;l#*$qvz#aW1182w9fV7xr1 zVo44*Alb5$K1es2lk(J7$$l#fwMzD%87fe3ds~l7X{O#Eq`9S9B|D2DL*!Q3Q$5#S zo^7~QviD`7R>|IBHVScc1x)qD!h1vMWF$gmQq_@&qlR*1v&pbk z8jK~nyCV=sge1LX;a2f*uQrO%Oq|}?bP_{bm86#zlJ6vYB@cWq708mVj(9p|@Mxk# zXK9U$B$ILUjR=>vXQHumO*FpTjQTLrVv_%#Ja2vA?ZBOZ^)3F;{z+e37Fgjge#KuB zNVgp5-{If8-Jjfl=74|Lxoy5VBmE_{{%3AFI;tbM!e4$gu>3avuuGF0mh}JS;8i>P z{aya({=o7pmcF{|DNU}d^>6vn`X|2r^-PQZ*_(beY1{e&pMP)Q#PI^}Q~kclRaDBH z*g+S+lB4~B`ipyFfq75+YDNYoD_?9vRFg+ht0u25R7UbAZJy3pn=o7y%tZQ7thEt^7kT@>m|Csm?9lGN|MLcQS*73$~- zN8>6L{YZq`)%7HLBNWz=WU8(^lS$RlTd9tkhT4X@RFb%?0wrtwkwq}ctRSL~yyrXZgwu{7t+QTHx z*ks;-saS&EZ0SQLo{DzIBc1eOPx{rgY2(HHfkHnvjGCL_BjF!!WYGTPmfwpyYA zx1~-dRR~sgX8Kg9i{78b6Dk$iMaQgjBJoZIlc^cSccL#vwrdl#AU!GK^mdF;l0(6m zNJ4ui)EQ2PNoFkEoq`T_rI{ijnh+t=C#s}jKzE@CvolU~9mvr*Ow%sW5^0|GhEvz6 zP$Jfe5lzurA!oBrWtRm#RcMN4$ZEJTgt@JvacssCHKO`x$gC+%*7t{F^a2vb^oEny zMUtvF(o6co#LIIw4=p<(uZrVqWz+gKZCVl!9)%b8yQ@=azv%w-(o0btG9go|bRY%u zL?-cOk*uS>W9iURQ{n!I367|K1KXF3Cg@Em1x}~~{Umy4rnir!q7Ss>hG>l>*Xi+? zt3nV(&Wy?`w95{ho>x5L+9PIQF<~&rRH#24ZjVJIb`fZB z1qEk!xe6fkx7zIW0_u>;53YS<<(0ZN;;(^qcqQ)=9|-k+z^vL%=K7>GI3hRJLj@L zHg3|=%pgb25}+eZrX9Bgiu_5PS9@lx~8Tj!I`Tg?a^@DsIFN&%Vf-pPP*anKC(r5dn&zgr56N_(jD4J z!p8HRhQKoCB0Lw<+qe?_6K~$<&`V7h+~v%Di1W%Q@*NA z?d_$hN#}IZoO>jfjKspVXTU0GAroFgg*V6ZLBDEAJH1rfrEH=^; z>Pq5j^8YCXNe&G&?vnFTBbVH#4{R&h32*G^_H{tIO%Eo$v&7g?qUUj~N1lc7WRHY> z8|cqI{{f_Ql%IZF*=`we0-0|62f6*#5N0LUe(Z-rzuuj+c+&n~Eeu(3k>uRSdAI!@ zcIcBJTS@va?c1mh`RwgJa~tXL0BNQr`N+{HlM z$a*h!9P4tgC+=YOZ~ri)@CG)W5x?{r-etd~&u=YRU_P_Zb{P(3H?0=f=mpFs}hSSHj|0L_Lr?Z_-2Tf@` z$D!1Tt#Zb-2YI)B2~QmEhBVLiRoef6+h+-!naS;4T-pi#8fAbvZc@_zv=I3${TKLG zlo@RNzt8@&=P$mTBJIVm@Tt4@LH6rx{~u7Wl5789wuAm4JG7D4QGB-pQ_9tkIX#&E zm-H(er5<(^Iz?(dcml6L{o(vzwf^iV=GXcMwFLGJ=3(I6IZF(_l;^YLU&D2{2l7ac z#F_X3)&2ojPqS`A&Q1_0>3bwP!!3}r9UvvKY$fHvm(AW+bgfdCGalps3~%9XTLX)U+1T< ztqqp^dZidx<5#p>KS=VcQG=k+tG~`Qpw6GY+s##_DLb6}$gKt4YPLSFmiJbBw_!ka=;}ywZ@|O&OHw}TW9|GSz1b*cZcz6hW*AV#L zA@G}qz;7P{znAdg);yhQ+-hy758OA(KF88_Ox|9ky}w~UuIBA%ncWX;-N*wqo@DXp z!4KB_Sf16wPqtjnJ?b(*`)Aq+`&n4_M26U|pywg8E2*EhbBd&y*|gQ$4rV*e-oD7+ z3L3bxo83H>{W-n&Wp*D)v24Cr4fPHaRhex~Y~$zej^*z|=eD#kRB{`GWf|AeKjViW zl;j&#z_BLac?L;VI$V$JtJEZ2YwkC2O%gd050Ha<9>HsvFLGo>T*^53wwzTKei7wG z&N{|LPA!+C7T>mim&KR44`?6buHKJXIOO2D2Hxn{scfu!0mp?bs6|%`iLBP?gKv2!r!7i67V2>g#QlZk$_L3kKkB0k$_L7kKhF~ zpOJvu@laynwm+*F7yqx-t*MU|-yX-g7H<2q#lr1=wOaTzk}Y;dEZnvyW#M+beS~q? ziE-b|b{@9)(+QJtxzoaJ`#)>plZh|(JYnIs{rcx)#DhO=`(L*B_PD%m;r6)v&cf|+ zdB?(SKm3((>95SgQW!!BC%a$ME!?($j)l*lHqzg@77o1|=!3M#!l6_6%PritzsbUF z{$&-2=hx9!JQ&5&R}{3Ge>7T>o2ISa=cDRzF} z!fpFsvT)n~_^}NVPIkZEw(vTt6Z!93xE)s``IZya^%ft$Qb7W4`zOda`V0Sml0HaV zEWYiZZ5AK#Df2yK@ooQfS-2g~X-f|DJ^-bZZm{?bRF?jJ!oqF6_d2-D#|IcMAsGSs z^w9_Daf@&J;meGRA5I#&`kKYJ{qUTH&n2$d`7;Z*$Mha(g*1xi*L)HX5qFyvn||SALW`AOfJ`>&saFJ63>r0xWv`pGcIv;l=c3=;xDx1 zzii=C2$yku-NL6@`0p&-_RqVFi+?`KdJ8dmC?QU4|6Ihl@E_GIn)^fWmsq&%pY;|# znPiClJ6N8pw-o>-ob0&LARTb|MBPs2VQwM`9%Q`Iz*$`ON#r?I_&b>wbogA%?$p2! zBLt*#Dd&OH7aY}#MFtq|;J@bUz3ey$zma*^=R^{FOeuHm0AKFGQ78A&BIgoru$0e& zU&(%0<>1{M2Q3bcZ&D*k{ED1L#b5$dPmdXGHJy z95;s?T&@Q)Z-jp{%fHXzl-|1INk|1b9cf$_0CK7x;6JLS1R@Dld_ ze1|XhA4?rvo*&jZIDT}BBZcooa}M+cYth8G?D7Pj-(4lei2|KZ@{*bj0)DgOKhkC*uYa&Epa zWBV)kEd28<_d*As%=XCrr0`cUUhnYl;{Gmm@F%&v*1%?^%VS|J^A@M+Bdw1Xe!{yyU1<;;J|!A0-04*q$T^KA$JA@}!X z2md9@|91zkWk3AM!6hEXa9oQ&MgD9D53@ZD4qnXoLI-bVy)utQ{p#-*8wW4oaed3ddpI7>Irul2|0f5ReW*fSS7f~IU|xxXU&(TYJNPm7 zL$!m8{3#Cp2lh{$gST*8EpYIKT)x!7Mb0`0-^g}e>)_|uKYffNTp7|mxYfa@alan5 za2Bm=p0setS;740EgXD#X8W;)gMSV4|7hXh%X8g%#${ZdVg4`<7_omR<3YxS{}TIo zwuM(Q7pFQ$&MjQG(ZV^aYqncB?0=N`eGdLT#y{%dzi0fIgZ~%f4>`EU>&cfLd>Z3t zEgXJZ%W{6oxcK2Ij^|e`KJ1r$fImBY@mtX_BM@@nw~Q&O5(~%uUI4-c_zgt`5@Z|@SS6VnO6^$^0QoDu2Km9zuyDc3441rAPW(x=P0Q3LO!m(c}=|Kwz z^(p3m)xse^#SKnbIH;$X|AK|jVlGa` zZ{M=`Fh#y+_@546`sI}qiIVtP;-{E#kuUFKMmzjQ-I~55;qbr2<37jX*E4^IMPgG1@C#kbdiyB+>% zj)w;={&XWkAHU%6(`?UIE&c?Hf70R0_bSd>{7Dx7hYtS?%m1atzsTah?(kn@|NqhA zFS7W)3R93ck$u222fvx+R6F=omNmt}3)s#T4ld7+AqQW?@zCwy%NS2OcsIw}Z4NHa zt&cf)58HXt!T+A+f8W6;u>9XRxV%p-s?7IWoaN7PaM@>E>)^5<9d__PalGB&;1e0Y z-@%_`J0EiJ&$B(J9320y5$P&!hZCSKfRui3;ZWHKkP;84e!n2^)PS@2?0pC@q?ar? kJmoYV)JJnKY2%9>d?%N$c5r!K*yrFu7Iu$=%YEj51JTJk!vFvP diff --git a/src/mingw/.deps/device.Po b/src/mingw/.deps/device.Po deleted file mode 100644 index 9ce06a8..0000000 --- a/src/mingw/.deps/device.Po +++ /dev/null @@ -1 +0,0 @@ -# dummy diff --git a/src/multicast_device.c b/src/multicast_device.c index 5eaf103..600b77c 100644 --- a/src/multicast_device.c +++ b/src/multicast_device.c @@ -136,8 +136,6 @@ static bool setup_device(void) { goto error; } - freeaddrinfo(ai); - logger(DEBUG_ALWAYS, LOG_INFO, "%s is a %s", device, device_info); return true; @@ -173,8 +171,7 @@ static bool read_packet(vpn_packet_t *packet) { if(!memcmp(&ignore_src, packet->data + 6, sizeof ignore_src)) { logger(DEBUG_SCARY_THINGS, LOG_DEBUG, "Ignoring loopback packet of %d bytes from %s", lenin, device_info); - packet->len = 0; - return true; + return false; } packet->len = lenin; diff --git a/src/names.c b/src/names.c index a631ad9..37708f8 100644 --- a/src/names.c +++ b/src/names.c @@ -26,6 +26,7 @@ char *netname = NULL; char *confdir = NULL; /* base configuration directory */ char *confbase = NULL; /* base configuration directory for this instance of tinc */ +bool confbase_given; char *identname = NULL; /* program name for syslog */ char *unixsocketname = NULL; /* UNIX socket location */ char *logfilename = NULL; /* log file location */ @@ -41,6 +42,7 @@ void make_names(void) { char installdir[1024] = ""; DWORD len = sizeof installdir; #endif + confbase_given = confbase; if(netname && confbase) logger(DEBUG_ALWAYS, LOG_INFO, "Both netname and configuration directory given, using the latter..."); diff --git a/src/names.h b/src/names.h index 6f43a2c..1163ff6 100644 --- a/src/names.h +++ b/src/names.h @@ -23,6 +23,7 @@ extern char *confdir; extern char *confbase; +extern bool confbase_given; extern char *netname; extern char *identname; extern char *unixsocketname; diff --git a/src/net.c b/src/net.c index bf6cfcf..286f157 100644 --- a/src/net.c +++ b/src/net.c @@ -32,7 +32,6 @@ #include "names.h" #include "net.h" #include "netutl.h" -#include "process.h" #include "protocol.h" #include "subnet.h" #include "xalloc.h" diff --git a/src/net_packet.c b/src/net_packet.c index f79c9a7..1159231 100644 --- a/src/net_packet.c +++ b/src/net_packet.c @@ -42,7 +42,6 @@ #include "net.h" #include "netutl.h" #include "protocol.h" -#include "process.h" #include "route.h" #include "utils.h" #include "xalloc.h" diff --git a/src/net_setup.c b/src/net_setup.c index 0fedafa..b9c5df7 100644 --- a/src/net_setup.c +++ b/src/net_setup.c @@ -38,6 +38,7 @@ #include "protocol.h" #include "route.h" #include "rsa.h" +#include "script.h" #include "subnet.h" #include "utils.h" #include "xalloc.h" @@ -455,11 +456,7 @@ bool setup_myself_reloadable(void) { free(scriptextension); if(!get_config_string(lookup_config(config_tree, "ScriptsExtension"), &scriptextension)) -#ifdef HAVE_MINGW - scriptextension = xstrdup(".bat"); -#else scriptextension = xstrdup(""); -#endif get_config_string(lookup_config(config_tree, "Proxy"), &proxy); if(proxy) { @@ -754,7 +751,6 @@ static bool setup_myself(void) { free(cipher); - send_key_changed(); timeout_add(&keyexpire_timeout, keyexpire_handler, &keyexpire_timeout, &(struct timeval){keylifetime, rand() % 100000}); /* Check if we want to use message authentication codes... */ @@ -832,60 +828,8 @@ static bool setup_myself(void) { if(device_fd >= 0) io_add(&device_io, handle_device_data, NULL, device_fd, IO_READ); - /* Run tinc-up script to further initialize the tap interface */ - char *envp[5] = {NULL}; - xasprintf(&envp[0], "NETNAME=%s", netname ? : ""); - xasprintf(&envp[1], "DEVICE=%s", device ? : ""); - xasprintf(&envp[2], "INTERFACE=%s", iface ? : ""); - xasprintf(&envp[3], "NAME=%s", myself->name); - - execute_script("tinc-up", envp); - - for(int i = 0; i < 4; i++) - free(envp[i]); - - /* Run subnet-up scripts for our own subnets */ - - subnet_update(myself, NULL, true); - /* Open sockets */ -#ifndef HAVE_MINGW - int unix_fd = socket(AF_UNIX, SOCK_STREAM, 0); - if(unix_fd < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not create UNIX socket: %s", sockstrerror(errno)); - return false; - } - - struct sockaddr_un sa; - sa.sun_family = AF_UNIX; - strncpy(sa.sun_path, unixsocketname, sizeof sa.sun_path); - - if(connect(unix_fd, (struct sockaddr *)&sa, sizeof sa) >= 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "UNIX socket %s is still in use!", unixsocketname); - return false; - } - - unlink(unixsocketname); - - mode_t mask = umask(0); - umask(mask | 077); - int result = bind(unix_fd, (struct sockaddr *)&sa, sizeof sa); - umask(mask); - - if(result < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not bind UNIX socket to %s: %s", unixsocketname, sockstrerror(errno)); - return false; - } - - if(listen(unix_fd, 3) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not listen on UNIX socket %s: %s", unixsocketname, sockstrerror(errno)); - return false; - } - - io_add(&unix_socket, handle_new_unix_connection, &unix_socket, unix_fd, IO_READ); -#endif - if(!do_detach && getenv("LISTEN_FDS")) { sockaddr_t sa; socklen_t salen; @@ -997,9 +941,7 @@ static bool setup_myself(void) { } while(cfg); } - if(listen_sockets) - logger(DEBUG_ALWAYS, LOG_NOTICE, "Ready"); - else { + if(!listen_sockets) { logger(DEBUG_ALWAYS, LOG_ERR, "Unable to create any listening socket!"); return false; } @@ -1037,6 +979,26 @@ bool setup_network(void) { if(!setup_myself()) return false; + if(!init_control()) + return false; + + /* Run tinc-up script to further initialize the tap interface */ + + char *envp[5] = {NULL}; + xasprintf(&envp[0], "NETNAME=%s", netname ? : ""); + xasprintf(&envp[1], "DEVICE=%s", device ? : ""); + xasprintf(&envp[2], "INTERFACE=%s", iface ? : ""); + xasprintf(&envp[3], "NAME=%s", myself->name); + + execute_script("tinc-up", envp); + + for(int i = 0; i < 4; i++) + free(envp[i]); + + /* Run subnet-up scripts for our own subnets */ + + subnet_update(myself, NULL, true); + return true; } @@ -1069,11 +1031,6 @@ void close_network_connections(void) { close(listen_socket[i].udp.fd); } -#ifndef HAVE_MINGW - io_del(&unix_socket); - close(unix_socket.fd); -#endif - char *envp[5] = {NULL}; xasprintf(&envp[0], "NETNAME=%s", netname ? : ""); xasprintf(&envp[1], "DEVICE=%s", device ? : ""); @@ -1095,5 +1052,7 @@ void close_network_connections(void) { devops.close(); + exit_control(); + return; } diff --git a/src/net_socket.c b/src/net_socket.c index ded9224..ab3c17e 100644 --- a/src/net_socket.c +++ b/src/net_socket.c @@ -113,6 +113,34 @@ static bool bind_to_interface(int sd) { return true; } +static bool bind_to_address(connection_t *c) { + int s = -1; + + for(int i = 0; i < listen_sockets; i++) { + if(listen_socket[i].sa.sa.sa_family != c->address.sa.sa_family) + continue; + if(s >= 0) + return false; + s = i; + } + + if(s < 0) + return false; + + sockaddr_t sa = listen_socket[s].sa; + if(sa.sa.sa_family == AF_INET) + sa.in.sin_port = 0; + else if(sa.sa.sa_family == AF_INET6) + sa.in6.sin6_port = 0; + + if(bind(c->socket, &sa.sa, SALEN(sa.sa))) { + logger(DEBUG_CONNECTIONS, LOG_WARNING, "Can't bind outgoing socket: %s", strerror(errno)); + return false; + } + + return true; +} + int setup_listen_socket(const sockaddr_t *sa) { int nfd; char *addrstr; @@ -481,6 +509,7 @@ begin: #endif bind_to_interface(c->socket); + bind_to_address(c); } /* Connect */ @@ -573,10 +602,22 @@ void handle_new_meta_connection(void *data, int flags) { tarpit = -1; } - if(prev_time == now.tv_sec && !sockaddrcmp_noport(&sa, &prev_sa)) { - // if so, keep the connection open but ignore it completely. - tarpit = fd; - return; + if(!sockaddrcmp_noport(&sa, &prev_sa)) { + static int samehost_burst; + static int samehost_burst_time; + + if(now.tv_sec - samehost_burst_time > samehost_burst) + samehost_burst = 0; + else + samehost_burst -= now.tv_sec - samehost_burst_time; + + samehost_burst_time = now.tv_sec; + samehost_burst++; + + if(samehost_burst > max_connection_burst) { + tarpit = fd; + return; + } } memcpy(&prev_sa, &sa, sizeof sa); diff --git a/src/openssl/.deps/.dirstamp b/src/openssl/.deps/.dirstamp deleted file mode 100644 index e69de29..0000000 diff --git a/src/openssl/.deps/cipher.Po b/src/openssl/.deps/cipher.Po deleted file mode 100644 index 05e8926..0000000 --- a/src/openssl/.deps/cipher.Po +++ /dev/null @@ -1,454 +0,0 @@ -openssl/cipher.o: openssl/cipher.c /usr/include/stdc-predef.h \ - /usr/include/x86_64-linux-gnu/bits/predefs.h openssl/../system.h \ - openssl/../../config.h openssl/../have.h /usr/include/stdio.h \ - /usr/include/features.h /usr/include/x86_64-linux-gnu/sys/cdefs.h \ - /usr/include/x86_64-linux-gnu/bits/wordsize.h \ - /usr/include/x86_64-linux-gnu/gnu/stubs.h \ - /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ - /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stddef.h \ - /usr/include/x86_64-linux-gnu/bits/types.h \ - /usr/include/x86_64-linux-gnu/bits/typesizes.h /usr/include/libio.h \ - /usr/include/_G_config.h /usr/include/wchar.h \ - /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdarg.h \ - /usr/include/x86_64-linux-gnu/bits/stdio_lim.h \ - /usr/include/x86_64-linux-gnu/bits/sys_errlist.h \ - /usr/include/x86_64-linux-gnu/bits/stdio.h /usr/include/stdlib.h \ - /usr/include/x86_64-linux-gnu/bits/waitflags.h \ - /usr/include/x86_64-linux-gnu/bits/waitstatus.h /usr/include/endian.h \ - /usr/include/x86_64-linux-gnu/bits/endian.h \ - /usr/include/x86_64-linux-gnu/bits/byteswap.h \ - /usr/include/x86_64-linux-gnu/bits/byteswap-16.h /usr/include/xlocale.h \ - /usr/include/x86_64-linux-gnu/sys/types.h /usr/include/time.h \ - /usr/include/x86_64-linux-gnu/sys/select.h \ - /usr/include/x86_64-linux-gnu/bits/select.h \ - /usr/include/x86_64-linux-gnu/bits/sigset.h \ - /usr/include/x86_64-linux-gnu/bits/time.h \ - /usr/include/x86_64-linux-gnu/sys/sysmacros.h \ - /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h /usr/include/alloca.h \ - /usr/include/x86_64-linux-gnu/bits/stdlib-float.h /usr/include/string.h \ - /usr/include/x86_64-linux-gnu/bits/string.h \ - /usr/include/x86_64-linux-gnu/bits/string2.h /usr/include/ctype.h \ - /usr/include/signal.h /usr/include/x86_64-linux-gnu/bits/signum.h \ - /usr/include/x86_64-linux-gnu/bits/siginfo.h \ - /usr/include/x86_64-linux-gnu/bits/sigaction.h \ - /usr/include/x86_64-linux-gnu/bits/sigcontext.h \ - /usr/include/x86_64-linux-gnu/bits/sigstack.h \ - /usr/include/x86_64-linux-gnu/sys/ucontext.h \ - /usr/include/x86_64-linux-gnu/bits/sigthread.h /usr/include/errno.h \ - /usr/include/x86_64-linux-gnu/bits/errno.h /usr/include/linux/errno.h \ - /usr/include/x86_64-linux-gnu/asm/errno.h \ - /usr/include/asm-generic/errno.h /usr/include/asm-generic/errno-base.h \ - /usr/include/fcntl.h /usr/include/x86_64-linux-gnu/bits/fcntl.h \ - /usr/include/x86_64-linux-gnu/bits/fcntl-linux.h \ - /usr/include/x86_64-linux-gnu/bits/uio.h \ - /usr/include/x86_64-linux-gnu/bits/stat.h /usr/include/unistd.h \ - /usr/include/x86_64-linux-gnu/bits/posix_opt.h \ - /usr/include/x86_64-linux-gnu/bits/environments.h \ - /usr/include/x86_64-linux-gnu/bits/confname.h /usr/include/getopt.h \ - /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdbool.h \ - /usr/include/inttypes.h \ - /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdint.h /usr/include/stdint.h \ - /usr/include/x86_64-linux-gnu/bits/wchar.h /usr/include/syslog.h \ - /usr/include/x86_64-linux-gnu/sys/syslog.h \ - /usr/include/x86_64-linux-gnu/bits/syslog-path.h \ - /usr/include/x86_64-linux-gnu/sys/time.h \ - /usr/include/x86_64-linux-gnu/bits/timex.h \ - /usr/include/x86_64-linux-gnu/sys/stat.h \ - /usr/include/x86_64-linux-gnu/sys/file.h \ - /usr/include/x86_64-linux-gnu/sys/wait.h \ - /usr/include/x86_64-linux-gnu/sys/ioctl.h \ - /usr/include/x86_64-linux-gnu/bits/ioctls.h \ - /usr/include/x86_64-linux-gnu/asm/ioctls.h \ - /usr/include/asm-generic/ioctls.h /usr/include/linux/ioctl.h \ - /usr/include/x86_64-linux-gnu/asm/ioctl.h \ - /usr/include/asm-generic/ioctl.h \ - /usr/include/x86_64-linux-gnu/bits/ioctl-types.h \ - /usr/include/x86_64-linux-gnu/sys/ttydefaults.h \ - /usr/include/x86_64-linux-gnu/sys/param.h \ - /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/limits.h \ - /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/syslimits.h \ - /usr/include/limits.h /usr/include/x86_64-linux-gnu/bits/posix1_lim.h \ - /usr/include/x86_64-linux-gnu/bits/local_lim.h \ - /usr/include/linux/limits.h \ - /usr/include/x86_64-linux-gnu/bits/posix2_lim.h \ - /usr/include/x86_64-linux-gnu/bits/xopen_lim.h \ - /usr/include/x86_64-linux-gnu/bits/param.h /usr/include/linux/param.h \ - /usr/include/x86_64-linux-gnu/asm/param.h \ - /usr/include/asm-generic/param.h \ - /usr/include/x86_64-linux-gnu/sys/resource.h \ - /usr/include/x86_64-linux-gnu/bits/resource.h \ - /usr/include/x86_64-linux-gnu/sys/uio.h \ - /usr/include/x86_64-linux-gnu/sys/un.h \ - /usr/include/x86_64-linux-gnu/bits/sockaddr.h /usr/include/dirent.h \ - /usr/include/x86_64-linux-gnu/bits/dirent.h /usr/include/netdb.h \ - /usr/include/netinet/in.h /usr/include/x86_64-linux-gnu/sys/socket.h \ - /usr/include/x86_64-linux-gnu/bits/socket.h \ - /usr/include/x86_64-linux-gnu/bits/socket_type.h \ - /usr/include/x86_64-linux-gnu/asm/socket.h \ - /usr/include/asm-generic/socket.h \ - /usr/include/x86_64-linux-gnu/asm/sockios.h \ - /usr/include/asm-generic/sockios.h \ - /usr/include/x86_64-linux-gnu/bits/in.h /usr/include/rpc/netdb.h \ - /usr/include/x86_64-linux-gnu/bits/netdb.h /usr/include/net/if.h \ - /usr/include/netinet/in_systm.h /usr/include/arpa/inet.h \ - /usr/include/netinet/ip.h /usr/include/netinet/tcp.h \ - /usr/include/netinet/ip6.h /usr/include/net/ethernet.h \ - /usr/include/linux/if_ether.h /usr/include/linux/types.h \ - /usr/include/x86_64-linux-gnu/asm/types.h \ - /usr/include/asm-generic/types.h /usr/include/asm-generic/int-ll64.h \ - /usr/include/x86_64-linux-gnu/asm/bitsperlong.h \ - /usr/include/asm-generic/bitsperlong.h /usr/include/linux/posix_types.h \ - /usr/include/linux/stddef.h \ - /usr/include/x86_64-linux-gnu/asm/posix_types.h \ - /usr/include/x86_64-linux-gnu/asm/posix_types_64.h \ - /usr/include/asm-generic/posix_types.h /usr/include/net/if_arp.h \ - /usr/include/netinet/ip_icmp.h /usr/include/netinet/icmp6.h \ - /usr/include/netinet/if_ether.h openssl/../dropin.h \ - openssl/../fake-getaddrinfo.h openssl/../fake-gai-errnos.h \ - openssl/../fake-getnameinfo.h /usr/include/openssl/rand.h \ - /usr/include/openssl/ossl_typ.h /usr/include/openssl/e_os2.h \ - /usr/include/x86_64-linux-gnu/openssl/opensslconf.h \ - /usr/include/openssl/err.h /usr/include/openssl/bio.h \ - /usr/include/openssl/crypto.h /usr/include/openssl/stack.h \ - /usr/include/openssl/safestack.h /usr/include/openssl/opensslv.h \ - /usr/include/openssl/symhacks.h /usr/include/openssl/lhash.h \ - /usr/include/openssl/evp.h /usr/include/openssl/objects.h \ - /usr/include/openssl/obj_mac.h /usr/include/openssl/asn1.h \ - /usr/include/openssl/bn.h openssl/../cipher.h openssl/../logger.h \ - openssl/../xalloc.h - -/usr/include/stdc-predef.h: - -/usr/include/x86_64-linux-gnu/bits/predefs.h: - -openssl/../system.h: - -openssl/../../config.h: - -openssl/../have.h: - -/usr/include/stdio.h: - -/usr/include/features.h: - -/usr/include/x86_64-linux-gnu/sys/cdefs.h: - -/usr/include/x86_64-linux-gnu/bits/wordsize.h: - -/usr/include/x86_64-linux-gnu/gnu/stubs.h: - -/usr/include/x86_64-linux-gnu/gnu/stubs-64.h: - -/usr/lib/gcc/x86_64-linux-gnu/4.8/include/stddef.h: - -/usr/include/x86_64-linux-gnu/bits/types.h: - -/usr/include/x86_64-linux-gnu/bits/typesizes.h: - -/usr/include/libio.h: - -/usr/include/_G_config.h: - -/usr/include/wchar.h: - -/usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdarg.h: - -/usr/include/x86_64-linux-gnu/bits/stdio_lim.h: - -/usr/include/x86_64-linux-gnu/bits/sys_errlist.h: - -/usr/include/x86_64-linux-gnu/bits/stdio.h: - -/usr/include/stdlib.h: - -/usr/include/x86_64-linux-gnu/bits/waitflags.h: - -/usr/include/x86_64-linux-gnu/bits/waitstatus.h: - -/usr/include/endian.h: - -/usr/include/x86_64-linux-gnu/bits/endian.h: - -/usr/include/x86_64-linux-gnu/bits/byteswap.h: - -/usr/include/x86_64-linux-gnu/bits/byteswap-16.h: - -/usr/include/xlocale.h: - -/usr/include/x86_64-linux-gnu/sys/types.h: - -/usr/include/time.h: - -/usr/include/x86_64-linux-gnu/sys/select.h: - -/usr/include/x86_64-linux-gnu/bits/select.h: - -/usr/include/x86_64-linux-gnu/bits/sigset.h: - -/usr/include/x86_64-linux-gnu/bits/time.h: - -/usr/include/x86_64-linux-gnu/sys/sysmacros.h: - -/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h: - -/usr/include/alloca.h: - -/usr/include/x86_64-linux-gnu/bits/stdlib-float.h: - -/usr/include/string.h: - -/usr/include/x86_64-linux-gnu/bits/string.h: - -/usr/include/x86_64-linux-gnu/bits/string2.h: - -/usr/include/ctype.h: - -/usr/include/signal.h: - -/usr/include/x86_64-linux-gnu/bits/signum.h: - -/usr/include/x86_64-linux-gnu/bits/siginfo.h: - -/usr/include/x86_64-linux-gnu/bits/sigaction.h: - -/usr/include/x86_64-linux-gnu/bits/sigcontext.h: - -/usr/include/x86_64-linux-gnu/bits/sigstack.h: - -/usr/include/x86_64-linux-gnu/sys/ucontext.h: - -/usr/include/x86_64-linux-gnu/bits/sigthread.h: - -/usr/include/errno.h: - -/usr/include/x86_64-linux-gnu/bits/errno.h: - -/usr/include/linux/errno.h: - -/usr/include/x86_64-linux-gnu/asm/errno.h: - -/usr/include/asm-generic/errno.h: - -/usr/include/asm-generic/errno-base.h: - -/usr/include/fcntl.h: - -/usr/include/x86_64-linux-gnu/bits/fcntl.h: - -/usr/include/x86_64-linux-gnu/bits/fcntl-linux.h: - -/usr/include/x86_64-linux-gnu/bits/uio.h: - -/usr/include/x86_64-linux-gnu/bits/stat.h: - -/usr/include/unistd.h: - -/usr/include/x86_64-linux-gnu/bits/posix_opt.h: - -/usr/include/x86_64-linux-gnu/bits/environments.h: - -/usr/include/x86_64-linux-gnu/bits/confname.h: - -/usr/include/getopt.h: - -/usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdbool.h: - -/usr/include/inttypes.h: - -/usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdint.h: - -/usr/include/stdint.h: - -/usr/include/x86_64-linux-gnu/bits/wchar.h: - -/usr/include/syslog.h: - -/usr/include/x86_64-linux-gnu/sys/syslog.h: - -/usr/include/x86_64-linux-gnu/bits/syslog-path.h: - -/usr/include/x86_64-linux-gnu/sys/time.h: - -/usr/include/x86_64-linux-gnu/bits/timex.h: - -/usr/include/x86_64-linux-gnu/sys/stat.h: - -/usr/include/x86_64-linux-gnu/sys/file.h: - -/usr/include/x86_64-linux-gnu/sys/wait.h: - -/usr/include/x86_64-linux-gnu/sys/ioctl.h: - -/usr/include/x86_64-linux-gnu/bits/ioctls.h: - -/usr/include/x86_64-linux-gnu/asm/ioctls.h: - -/usr/include/asm-generic/ioctls.h: - -/usr/include/linux/ioctl.h: - -/usr/include/x86_64-linux-gnu/asm/ioctl.h: - -/usr/include/asm-generic/ioctl.h: - -/usr/include/x86_64-linux-gnu/bits/ioctl-types.h: - -/usr/include/x86_64-linux-gnu/sys/ttydefaults.h: - -/usr/include/x86_64-linux-gnu/sys/param.h: - -/usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/limits.h: - -/usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/syslimits.h: - -/usr/include/limits.h: - -/usr/include/x86_64-linux-gnu/bits/posix1_lim.h: - -/usr/include/x86_64-linux-gnu/bits/local_lim.h: - -/usr/include/linux/limits.h: - -/usr/include/x86_64-linux-gnu/bits/posix2_lim.h: - -/usr/include/x86_64-linux-gnu/bits/xopen_lim.h: - -/usr/include/x86_64-linux-gnu/bits/param.h: - -/usr/include/linux/param.h: - -/usr/include/x86_64-linux-gnu/asm/param.h: - -/usr/include/asm-generic/param.h: - -/usr/include/x86_64-linux-gnu/sys/resource.h: - -/usr/include/x86_64-linux-gnu/bits/resource.h: - -/usr/include/x86_64-linux-gnu/sys/uio.h: - -/usr/include/x86_64-linux-gnu/sys/un.h: - -/usr/include/x86_64-linux-gnu/bits/sockaddr.h: - -/usr/include/dirent.h: - -/usr/include/x86_64-linux-gnu/bits/dirent.h: - -/usr/include/netdb.h: - -/usr/include/netinet/in.h: - -/usr/include/x86_64-linux-gnu/sys/socket.h: - -/usr/include/x86_64-linux-gnu/bits/socket.h: - -/usr/include/x86_64-linux-gnu/bits/socket_type.h: - -/usr/include/x86_64-linux-gnu/asm/socket.h: - -/usr/include/asm-generic/socket.h: - -/usr/include/x86_64-linux-gnu/asm/sockios.h: - -/usr/include/asm-generic/sockios.h: - -/usr/include/x86_64-linux-gnu/bits/in.h: - -/usr/include/rpc/netdb.h: - -/usr/include/x86_64-linux-gnu/bits/netdb.h: - -/usr/include/net/if.h: - -/usr/include/netinet/in_systm.h: - -/usr/include/arpa/inet.h: - -/usr/include/netinet/ip.h: - -/usr/include/netinet/tcp.h: - -/usr/include/netinet/ip6.h: - -/usr/include/net/ethernet.h: - -/usr/include/linux/if_ether.h: - -/usr/include/linux/types.h: - -/usr/include/x86_64-linux-gnu/asm/types.h: - -/usr/include/asm-generic/types.h: - -/usr/include/asm-generic/int-ll64.h: - -/usr/include/x86_64-linux-gnu/asm/bitsperlong.h: - -/usr/include/asm-generic/bitsperlong.h: - -/usr/include/linux/posix_types.h: - -/usr/include/linux/stddef.h: - -/usr/include/x86_64-linux-gnu/asm/posix_types.h: - -/usr/include/x86_64-linux-gnu/asm/posix_types_64.h: - -/usr/include/asm-generic/posix_types.h: - -/usr/include/net/if_arp.h: - -/usr/include/netinet/ip_icmp.h: - -/usr/include/netinet/icmp6.h: - -/usr/include/netinet/if_ether.h: - -openssl/../dropin.h: - -openssl/../fake-getaddrinfo.h: - -openssl/../fake-gai-errnos.h: - -openssl/../fake-getnameinfo.h: - -/usr/include/openssl/rand.h: - -/usr/include/openssl/ossl_typ.h: - -/usr/include/openssl/e_os2.h: - -/usr/include/x86_64-linux-gnu/openssl/opensslconf.h: - -/usr/include/openssl/err.h: - -/usr/include/openssl/bio.h: - -/usr/include/openssl/crypto.h: - -/usr/include/openssl/stack.h: - -/usr/include/openssl/safestack.h: - -/usr/include/openssl/opensslv.h: - -/usr/include/openssl/symhacks.h: - -/usr/include/openssl/lhash.h: - -/usr/include/openssl/evp.h: - -/usr/include/openssl/objects.h: - -/usr/include/openssl/obj_mac.h: - -/usr/include/openssl/asn1.h: - -/usr/include/openssl/bn.h: - -openssl/../cipher.h: - -openssl/../logger.h: - -openssl/../xalloc.h: diff --git a/src/openssl/.deps/crypto.Po b/src/openssl/.deps/crypto.Po deleted file mode 100644 index 7175d88..0000000 --- a/src/openssl/.deps/crypto.Po +++ /dev/null @@ -1,482 +0,0 @@ -openssl/crypto.o: openssl/crypto.c /usr/include/stdc-predef.h \ - /usr/include/x86_64-linux-gnu/bits/predefs.h openssl/../system.h \ - openssl/../../config.h openssl/../have.h /usr/include/stdio.h \ - /usr/include/features.h /usr/include/x86_64-linux-gnu/sys/cdefs.h \ - /usr/include/x86_64-linux-gnu/bits/wordsize.h \ - /usr/include/x86_64-linux-gnu/gnu/stubs.h \ - /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ - /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stddef.h \ - /usr/include/x86_64-linux-gnu/bits/types.h \ - /usr/include/x86_64-linux-gnu/bits/typesizes.h /usr/include/libio.h \ - /usr/include/_G_config.h /usr/include/wchar.h \ - /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdarg.h \ - /usr/include/x86_64-linux-gnu/bits/stdio_lim.h \ - /usr/include/x86_64-linux-gnu/bits/sys_errlist.h \ - /usr/include/x86_64-linux-gnu/bits/stdio.h /usr/include/stdlib.h \ - /usr/include/x86_64-linux-gnu/bits/waitflags.h \ - /usr/include/x86_64-linux-gnu/bits/waitstatus.h /usr/include/endian.h \ - /usr/include/x86_64-linux-gnu/bits/endian.h \ - /usr/include/x86_64-linux-gnu/bits/byteswap.h \ - /usr/include/x86_64-linux-gnu/bits/byteswap-16.h /usr/include/xlocale.h \ - /usr/include/x86_64-linux-gnu/sys/types.h /usr/include/time.h \ - /usr/include/x86_64-linux-gnu/sys/select.h \ - /usr/include/x86_64-linux-gnu/bits/select.h \ - /usr/include/x86_64-linux-gnu/bits/sigset.h \ - /usr/include/x86_64-linux-gnu/bits/time.h \ - /usr/include/x86_64-linux-gnu/sys/sysmacros.h \ - /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h /usr/include/alloca.h \ - /usr/include/x86_64-linux-gnu/bits/stdlib-float.h /usr/include/string.h \ - /usr/include/x86_64-linux-gnu/bits/string.h \ - /usr/include/x86_64-linux-gnu/bits/string2.h /usr/include/ctype.h \ - /usr/include/signal.h /usr/include/x86_64-linux-gnu/bits/signum.h \ - /usr/include/x86_64-linux-gnu/bits/siginfo.h \ - /usr/include/x86_64-linux-gnu/bits/sigaction.h \ - /usr/include/x86_64-linux-gnu/bits/sigcontext.h \ - /usr/include/x86_64-linux-gnu/bits/sigstack.h \ - /usr/include/x86_64-linux-gnu/sys/ucontext.h \ - /usr/include/x86_64-linux-gnu/bits/sigthread.h /usr/include/errno.h \ - /usr/include/x86_64-linux-gnu/bits/errno.h /usr/include/linux/errno.h \ - /usr/include/x86_64-linux-gnu/asm/errno.h \ - /usr/include/asm-generic/errno.h /usr/include/asm-generic/errno-base.h \ - /usr/include/fcntl.h /usr/include/x86_64-linux-gnu/bits/fcntl.h \ - /usr/include/x86_64-linux-gnu/bits/fcntl-linux.h \ - /usr/include/x86_64-linux-gnu/bits/uio.h \ - /usr/include/x86_64-linux-gnu/bits/stat.h /usr/include/unistd.h \ - /usr/include/x86_64-linux-gnu/bits/posix_opt.h \ - /usr/include/x86_64-linux-gnu/bits/environments.h \ - /usr/include/x86_64-linux-gnu/bits/confname.h /usr/include/getopt.h \ - /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdbool.h \ - /usr/include/inttypes.h \ - /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdint.h /usr/include/stdint.h \ - /usr/include/x86_64-linux-gnu/bits/wchar.h /usr/include/syslog.h \ - /usr/include/x86_64-linux-gnu/sys/syslog.h \ - /usr/include/x86_64-linux-gnu/bits/syslog-path.h \ - /usr/include/x86_64-linux-gnu/sys/time.h \ - /usr/include/x86_64-linux-gnu/bits/timex.h \ - /usr/include/x86_64-linux-gnu/sys/stat.h \ - /usr/include/x86_64-linux-gnu/sys/file.h \ - /usr/include/x86_64-linux-gnu/sys/wait.h \ - /usr/include/x86_64-linux-gnu/sys/ioctl.h \ - /usr/include/x86_64-linux-gnu/bits/ioctls.h \ - /usr/include/x86_64-linux-gnu/asm/ioctls.h \ - /usr/include/asm-generic/ioctls.h /usr/include/linux/ioctl.h \ - /usr/include/x86_64-linux-gnu/asm/ioctl.h \ - /usr/include/asm-generic/ioctl.h \ - /usr/include/x86_64-linux-gnu/bits/ioctl-types.h \ - /usr/include/x86_64-linux-gnu/sys/ttydefaults.h \ - /usr/include/x86_64-linux-gnu/sys/param.h \ - /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/limits.h \ - /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/syslimits.h \ - /usr/include/limits.h /usr/include/x86_64-linux-gnu/bits/posix1_lim.h \ - /usr/include/x86_64-linux-gnu/bits/local_lim.h \ - /usr/include/linux/limits.h \ - /usr/include/x86_64-linux-gnu/bits/posix2_lim.h \ - /usr/include/x86_64-linux-gnu/bits/xopen_lim.h \ - /usr/include/x86_64-linux-gnu/bits/param.h /usr/include/linux/param.h \ - /usr/include/x86_64-linux-gnu/asm/param.h \ - /usr/include/asm-generic/param.h \ - /usr/include/x86_64-linux-gnu/sys/resource.h \ - /usr/include/x86_64-linux-gnu/bits/resource.h \ - /usr/include/x86_64-linux-gnu/sys/uio.h \ - /usr/include/x86_64-linux-gnu/sys/un.h \ - /usr/include/x86_64-linux-gnu/bits/sockaddr.h /usr/include/dirent.h \ - /usr/include/x86_64-linux-gnu/bits/dirent.h /usr/include/netdb.h \ - /usr/include/netinet/in.h /usr/include/x86_64-linux-gnu/sys/socket.h \ - /usr/include/x86_64-linux-gnu/bits/socket.h \ - /usr/include/x86_64-linux-gnu/bits/socket_type.h \ - /usr/include/x86_64-linux-gnu/asm/socket.h \ - /usr/include/asm-generic/socket.h \ - /usr/include/x86_64-linux-gnu/asm/sockios.h \ - /usr/include/asm-generic/sockios.h \ - /usr/include/x86_64-linux-gnu/bits/in.h /usr/include/rpc/netdb.h \ - /usr/include/x86_64-linux-gnu/bits/netdb.h /usr/include/net/if.h \ - /usr/include/netinet/in_systm.h /usr/include/arpa/inet.h \ - /usr/include/netinet/ip.h /usr/include/netinet/tcp.h \ - /usr/include/netinet/ip6.h /usr/include/net/ethernet.h \ - /usr/include/linux/if_ether.h /usr/include/linux/types.h \ - /usr/include/x86_64-linux-gnu/asm/types.h \ - /usr/include/asm-generic/types.h /usr/include/asm-generic/int-ll64.h \ - /usr/include/x86_64-linux-gnu/asm/bitsperlong.h \ - /usr/include/asm-generic/bitsperlong.h /usr/include/linux/posix_types.h \ - /usr/include/linux/stddef.h \ - /usr/include/x86_64-linux-gnu/asm/posix_types.h \ - /usr/include/x86_64-linux-gnu/asm/posix_types_64.h \ - /usr/include/asm-generic/posix_types.h /usr/include/net/if_arp.h \ - /usr/include/netinet/ip_icmp.h /usr/include/netinet/icmp6.h \ - /usr/include/netinet/if_ether.h openssl/../dropin.h \ - openssl/../fake-getaddrinfo.h openssl/../fake-gai-errnos.h \ - openssl/../fake-getnameinfo.h /usr/include/openssl/rand.h \ - /usr/include/openssl/ossl_typ.h /usr/include/openssl/e_os2.h \ - /usr/include/x86_64-linux-gnu/openssl/opensslconf.h \ - /usr/include/openssl/evp.h /usr/include/openssl/symhacks.h \ - /usr/include/openssl/bio.h /usr/include/openssl/crypto.h \ - /usr/include/openssl/stack.h /usr/include/openssl/safestack.h \ - /usr/include/openssl/opensslv.h /usr/include/openssl/objects.h \ - /usr/include/openssl/obj_mac.h /usr/include/openssl/asn1.h \ - /usr/include/openssl/bn.h /usr/include/openssl/engine.h \ - /usr/include/openssl/rsa.h /usr/include/openssl/dsa.h \ - /usr/include/openssl/dh.h /usr/include/openssl/ecdh.h \ - /usr/include/openssl/ec.h /usr/include/openssl/ecdsa.h \ - /usr/include/openssl/ui.h /usr/include/openssl/err.h \ - /usr/include/openssl/lhash.h /usr/include/openssl/x509.h \ - /usr/include/openssl/buffer.h /usr/include/openssl/sha.h \ - /usr/include/openssl/x509_vfy.h /usr/include/openssl/pkcs7.h \ - openssl/../crypto.h - -/usr/include/stdc-predef.h: - -/usr/include/x86_64-linux-gnu/bits/predefs.h: - -openssl/../system.h: - -openssl/../../config.h: - -openssl/../have.h: - -/usr/include/stdio.h: - -/usr/include/features.h: - -/usr/include/x86_64-linux-gnu/sys/cdefs.h: - -/usr/include/x86_64-linux-gnu/bits/wordsize.h: - -/usr/include/x86_64-linux-gnu/gnu/stubs.h: - -/usr/include/x86_64-linux-gnu/gnu/stubs-64.h: - -/usr/lib/gcc/x86_64-linux-gnu/4.8/include/stddef.h: - -/usr/include/x86_64-linux-gnu/bits/types.h: - -/usr/include/x86_64-linux-gnu/bits/typesizes.h: - -/usr/include/libio.h: - -/usr/include/_G_config.h: - -/usr/include/wchar.h: - -/usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdarg.h: - -/usr/include/x86_64-linux-gnu/bits/stdio_lim.h: - -/usr/include/x86_64-linux-gnu/bits/sys_errlist.h: - -/usr/include/x86_64-linux-gnu/bits/stdio.h: - -/usr/include/stdlib.h: - -/usr/include/x86_64-linux-gnu/bits/waitflags.h: - -/usr/include/x86_64-linux-gnu/bits/waitstatus.h: - -/usr/include/endian.h: - -/usr/include/x86_64-linux-gnu/bits/endian.h: - -/usr/include/x86_64-linux-gnu/bits/byteswap.h: - -/usr/include/x86_64-linux-gnu/bits/byteswap-16.h: - -/usr/include/xlocale.h: - -/usr/include/x86_64-linux-gnu/sys/types.h: - -/usr/include/time.h: - -/usr/include/x86_64-linux-gnu/sys/select.h: - -/usr/include/x86_64-linux-gnu/bits/select.h: - -/usr/include/x86_64-linux-gnu/bits/sigset.h: - -/usr/include/x86_64-linux-gnu/bits/time.h: - -/usr/include/x86_64-linux-gnu/sys/sysmacros.h: - -/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h: - -/usr/include/alloca.h: - -/usr/include/x86_64-linux-gnu/bits/stdlib-float.h: - -/usr/include/string.h: - -/usr/include/x86_64-linux-gnu/bits/string.h: - -/usr/include/x86_64-linux-gnu/bits/string2.h: - -/usr/include/ctype.h: - -/usr/include/signal.h: - -/usr/include/x86_64-linux-gnu/bits/signum.h: - -/usr/include/x86_64-linux-gnu/bits/siginfo.h: - -/usr/include/x86_64-linux-gnu/bits/sigaction.h: - -/usr/include/x86_64-linux-gnu/bits/sigcontext.h: - -/usr/include/x86_64-linux-gnu/bits/sigstack.h: - -/usr/include/x86_64-linux-gnu/sys/ucontext.h: - -/usr/include/x86_64-linux-gnu/bits/sigthread.h: - -/usr/include/errno.h: - -/usr/include/x86_64-linux-gnu/bits/errno.h: - -/usr/include/linux/errno.h: - -/usr/include/x86_64-linux-gnu/asm/errno.h: - -/usr/include/asm-generic/errno.h: - -/usr/include/asm-generic/errno-base.h: - -/usr/include/fcntl.h: - -/usr/include/x86_64-linux-gnu/bits/fcntl.h: - -/usr/include/x86_64-linux-gnu/bits/fcntl-linux.h: - -/usr/include/x86_64-linux-gnu/bits/uio.h: - -/usr/include/x86_64-linux-gnu/bits/stat.h: - -/usr/include/unistd.h: - -/usr/include/x86_64-linux-gnu/bits/posix_opt.h: - -/usr/include/x86_64-linux-gnu/bits/environments.h: - -/usr/include/x86_64-linux-gnu/bits/confname.h: - -/usr/include/getopt.h: - -/usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdbool.h: - -/usr/include/inttypes.h: - -/usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdint.h: - -/usr/include/stdint.h: - -/usr/include/x86_64-linux-gnu/bits/wchar.h: - -/usr/include/syslog.h: - -/usr/include/x86_64-linux-gnu/sys/syslog.h: - -/usr/include/x86_64-linux-gnu/bits/syslog-path.h: - -/usr/include/x86_64-linux-gnu/sys/time.h: - -/usr/include/x86_64-linux-gnu/bits/timex.h: - -/usr/include/x86_64-linux-gnu/sys/stat.h: - -/usr/include/x86_64-linux-gnu/sys/file.h: - -/usr/include/x86_64-linux-gnu/sys/wait.h: - -/usr/include/x86_64-linux-gnu/sys/ioctl.h: - -/usr/include/x86_64-linux-gnu/bits/ioctls.h: - -/usr/include/x86_64-linux-gnu/asm/ioctls.h: - -/usr/include/asm-generic/ioctls.h: - -/usr/include/linux/ioctl.h: - -/usr/include/x86_64-linux-gnu/asm/ioctl.h: - -/usr/include/asm-generic/ioctl.h: - -/usr/include/x86_64-linux-gnu/bits/ioctl-types.h: - -/usr/include/x86_64-linux-gnu/sys/ttydefaults.h: - -/usr/include/x86_64-linux-gnu/sys/param.h: - -/usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/limits.h: - -/usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/syslimits.h: - -/usr/include/limits.h: - -/usr/include/x86_64-linux-gnu/bits/posix1_lim.h: - -/usr/include/x86_64-linux-gnu/bits/local_lim.h: - -/usr/include/linux/limits.h: - -/usr/include/x86_64-linux-gnu/bits/posix2_lim.h: - -/usr/include/x86_64-linux-gnu/bits/xopen_lim.h: - -/usr/include/x86_64-linux-gnu/bits/param.h: - -/usr/include/linux/param.h: - -/usr/include/x86_64-linux-gnu/asm/param.h: - -/usr/include/asm-generic/param.h: - -/usr/include/x86_64-linux-gnu/sys/resource.h: - -/usr/include/x86_64-linux-gnu/bits/resource.h: - -/usr/include/x86_64-linux-gnu/sys/uio.h: - -/usr/include/x86_64-linux-gnu/sys/un.h: - -/usr/include/x86_64-linux-gnu/bits/sockaddr.h: - -/usr/include/dirent.h: - -/usr/include/x86_64-linux-gnu/bits/dirent.h: - -/usr/include/netdb.h: - -/usr/include/netinet/in.h: - -/usr/include/x86_64-linux-gnu/sys/socket.h: - -/usr/include/x86_64-linux-gnu/bits/socket.h: - -/usr/include/x86_64-linux-gnu/bits/socket_type.h: - -/usr/include/x86_64-linux-gnu/asm/socket.h: - -/usr/include/asm-generic/socket.h: - -/usr/include/x86_64-linux-gnu/asm/sockios.h: - -/usr/include/asm-generic/sockios.h: - -/usr/include/x86_64-linux-gnu/bits/in.h: - -/usr/include/rpc/netdb.h: - -/usr/include/x86_64-linux-gnu/bits/netdb.h: - -/usr/include/net/if.h: - -/usr/include/netinet/in_systm.h: - -/usr/include/arpa/inet.h: - -/usr/include/netinet/ip.h: - -/usr/include/netinet/tcp.h: - -/usr/include/netinet/ip6.h: - -/usr/include/net/ethernet.h: - -/usr/include/linux/if_ether.h: - -/usr/include/linux/types.h: - -/usr/include/x86_64-linux-gnu/asm/types.h: - -/usr/include/asm-generic/types.h: - -/usr/include/asm-generic/int-ll64.h: - -/usr/include/x86_64-linux-gnu/asm/bitsperlong.h: - -/usr/include/asm-generic/bitsperlong.h: - -/usr/include/linux/posix_types.h: - -/usr/include/linux/stddef.h: - -/usr/include/x86_64-linux-gnu/asm/posix_types.h: - -/usr/include/x86_64-linux-gnu/asm/posix_types_64.h: - -/usr/include/asm-generic/posix_types.h: - -/usr/include/net/if_arp.h: - -/usr/include/netinet/ip_icmp.h: - -/usr/include/netinet/icmp6.h: - -/usr/include/netinet/if_ether.h: - -openssl/../dropin.h: - -openssl/../fake-getaddrinfo.h: - -openssl/../fake-gai-errnos.h: - -openssl/../fake-getnameinfo.h: - -/usr/include/openssl/rand.h: - -/usr/include/openssl/ossl_typ.h: - -/usr/include/openssl/e_os2.h: - -/usr/include/x86_64-linux-gnu/openssl/opensslconf.h: - -/usr/include/openssl/evp.h: - -/usr/include/openssl/symhacks.h: - -/usr/include/openssl/bio.h: - -/usr/include/openssl/crypto.h: - -/usr/include/openssl/stack.h: - -/usr/include/openssl/safestack.h: - -/usr/include/openssl/opensslv.h: - -/usr/include/openssl/objects.h: - -/usr/include/openssl/obj_mac.h: - -/usr/include/openssl/asn1.h: - -/usr/include/openssl/bn.h: - -/usr/include/openssl/engine.h: - -/usr/include/openssl/rsa.h: - -/usr/include/openssl/dsa.h: - -/usr/include/openssl/dh.h: - -/usr/include/openssl/ecdh.h: - -/usr/include/openssl/ec.h: - -/usr/include/openssl/ecdsa.h: - -/usr/include/openssl/ui.h: - -/usr/include/openssl/err.h: - -/usr/include/openssl/lhash.h: - -/usr/include/openssl/x509.h: - -/usr/include/openssl/buffer.h: - -/usr/include/openssl/sha.h: - -/usr/include/openssl/x509_vfy.h: - -/usr/include/openssl/pkcs7.h: - -openssl/../crypto.h: diff --git a/src/openssl/.deps/digest.Po b/src/openssl/.deps/digest.Po deleted file mode 100644 index 6d30f41..0000000 --- a/src/openssl/.deps/digest.Po +++ /dev/null @@ -1,458 +0,0 @@ -openssl/digest.o: openssl/digest.c /usr/include/stdc-predef.h \ - /usr/include/x86_64-linux-gnu/bits/predefs.h openssl/../system.h \ - openssl/../../config.h openssl/../have.h /usr/include/stdio.h \ - /usr/include/features.h /usr/include/x86_64-linux-gnu/sys/cdefs.h \ - /usr/include/x86_64-linux-gnu/bits/wordsize.h \ - /usr/include/x86_64-linux-gnu/gnu/stubs.h \ - /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ - /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stddef.h \ - /usr/include/x86_64-linux-gnu/bits/types.h \ - /usr/include/x86_64-linux-gnu/bits/typesizes.h /usr/include/libio.h \ - /usr/include/_G_config.h /usr/include/wchar.h \ - /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdarg.h \ - /usr/include/x86_64-linux-gnu/bits/stdio_lim.h \ - /usr/include/x86_64-linux-gnu/bits/sys_errlist.h \ - /usr/include/x86_64-linux-gnu/bits/stdio.h /usr/include/stdlib.h \ - /usr/include/x86_64-linux-gnu/bits/waitflags.h \ - /usr/include/x86_64-linux-gnu/bits/waitstatus.h /usr/include/endian.h \ - /usr/include/x86_64-linux-gnu/bits/endian.h \ - /usr/include/x86_64-linux-gnu/bits/byteswap.h \ - /usr/include/x86_64-linux-gnu/bits/byteswap-16.h /usr/include/xlocale.h \ - /usr/include/x86_64-linux-gnu/sys/types.h /usr/include/time.h \ - /usr/include/x86_64-linux-gnu/sys/select.h \ - /usr/include/x86_64-linux-gnu/bits/select.h \ - /usr/include/x86_64-linux-gnu/bits/sigset.h \ - /usr/include/x86_64-linux-gnu/bits/time.h \ - /usr/include/x86_64-linux-gnu/sys/sysmacros.h \ - /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h /usr/include/alloca.h \ - /usr/include/x86_64-linux-gnu/bits/stdlib-float.h /usr/include/string.h \ - /usr/include/x86_64-linux-gnu/bits/string.h \ - /usr/include/x86_64-linux-gnu/bits/string2.h /usr/include/ctype.h \ - /usr/include/signal.h /usr/include/x86_64-linux-gnu/bits/signum.h \ - /usr/include/x86_64-linux-gnu/bits/siginfo.h \ - /usr/include/x86_64-linux-gnu/bits/sigaction.h \ - /usr/include/x86_64-linux-gnu/bits/sigcontext.h \ - /usr/include/x86_64-linux-gnu/bits/sigstack.h \ - /usr/include/x86_64-linux-gnu/sys/ucontext.h \ - /usr/include/x86_64-linux-gnu/bits/sigthread.h /usr/include/errno.h \ - /usr/include/x86_64-linux-gnu/bits/errno.h /usr/include/linux/errno.h \ - /usr/include/x86_64-linux-gnu/asm/errno.h \ - /usr/include/asm-generic/errno.h /usr/include/asm-generic/errno-base.h \ - /usr/include/fcntl.h /usr/include/x86_64-linux-gnu/bits/fcntl.h \ - /usr/include/x86_64-linux-gnu/bits/fcntl-linux.h \ - /usr/include/x86_64-linux-gnu/bits/uio.h \ - /usr/include/x86_64-linux-gnu/bits/stat.h /usr/include/unistd.h \ - /usr/include/x86_64-linux-gnu/bits/posix_opt.h \ - /usr/include/x86_64-linux-gnu/bits/environments.h \ - /usr/include/x86_64-linux-gnu/bits/confname.h /usr/include/getopt.h \ - /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdbool.h \ - /usr/include/inttypes.h \ - /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdint.h /usr/include/stdint.h \ - /usr/include/x86_64-linux-gnu/bits/wchar.h /usr/include/syslog.h \ - /usr/include/x86_64-linux-gnu/sys/syslog.h \ - /usr/include/x86_64-linux-gnu/bits/syslog-path.h \ - /usr/include/x86_64-linux-gnu/sys/time.h \ - /usr/include/x86_64-linux-gnu/bits/timex.h \ - /usr/include/x86_64-linux-gnu/sys/stat.h \ - /usr/include/x86_64-linux-gnu/sys/file.h \ - /usr/include/x86_64-linux-gnu/sys/wait.h \ - /usr/include/x86_64-linux-gnu/sys/ioctl.h \ - /usr/include/x86_64-linux-gnu/bits/ioctls.h \ - /usr/include/x86_64-linux-gnu/asm/ioctls.h \ - /usr/include/asm-generic/ioctls.h /usr/include/linux/ioctl.h \ - /usr/include/x86_64-linux-gnu/asm/ioctl.h \ - /usr/include/asm-generic/ioctl.h \ - /usr/include/x86_64-linux-gnu/bits/ioctl-types.h \ - /usr/include/x86_64-linux-gnu/sys/ttydefaults.h \ - /usr/include/x86_64-linux-gnu/sys/param.h \ - /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/limits.h \ - /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/syslimits.h \ - /usr/include/limits.h /usr/include/x86_64-linux-gnu/bits/posix1_lim.h \ - /usr/include/x86_64-linux-gnu/bits/local_lim.h \ - /usr/include/linux/limits.h \ - /usr/include/x86_64-linux-gnu/bits/posix2_lim.h \ - /usr/include/x86_64-linux-gnu/bits/xopen_lim.h \ - /usr/include/x86_64-linux-gnu/bits/param.h /usr/include/linux/param.h \ - /usr/include/x86_64-linux-gnu/asm/param.h \ - /usr/include/asm-generic/param.h \ - /usr/include/x86_64-linux-gnu/sys/resource.h \ - /usr/include/x86_64-linux-gnu/bits/resource.h \ - /usr/include/x86_64-linux-gnu/sys/uio.h \ - /usr/include/x86_64-linux-gnu/sys/un.h \ - /usr/include/x86_64-linux-gnu/bits/sockaddr.h /usr/include/dirent.h \ - /usr/include/x86_64-linux-gnu/bits/dirent.h /usr/include/netdb.h \ - /usr/include/netinet/in.h /usr/include/x86_64-linux-gnu/sys/socket.h \ - /usr/include/x86_64-linux-gnu/bits/socket.h \ - /usr/include/x86_64-linux-gnu/bits/socket_type.h \ - /usr/include/x86_64-linux-gnu/asm/socket.h \ - /usr/include/asm-generic/socket.h \ - /usr/include/x86_64-linux-gnu/asm/sockios.h \ - /usr/include/asm-generic/sockios.h \ - /usr/include/x86_64-linux-gnu/bits/in.h /usr/include/rpc/netdb.h \ - /usr/include/x86_64-linux-gnu/bits/netdb.h /usr/include/net/if.h \ - /usr/include/netinet/in_systm.h /usr/include/arpa/inet.h \ - /usr/include/netinet/ip.h /usr/include/netinet/tcp.h \ - /usr/include/netinet/ip6.h /usr/include/net/ethernet.h \ - /usr/include/linux/if_ether.h /usr/include/linux/types.h \ - /usr/include/x86_64-linux-gnu/asm/types.h \ - /usr/include/asm-generic/types.h /usr/include/asm-generic/int-ll64.h \ - /usr/include/x86_64-linux-gnu/asm/bitsperlong.h \ - /usr/include/asm-generic/bitsperlong.h /usr/include/linux/posix_types.h \ - /usr/include/linux/stddef.h \ - /usr/include/x86_64-linux-gnu/asm/posix_types.h \ - /usr/include/x86_64-linux-gnu/asm/posix_types_64.h \ - /usr/include/asm-generic/posix_types.h /usr/include/net/if_arp.h \ - /usr/include/netinet/ip_icmp.h /usr/include/netinet/icmp6.h \ - /usr/include/netinet/if_ether.h openssl/../dropin.h \ - openssl/../fake-getaddrinfo.h openssl/../fake-gai-errnos.h \ - openssl/../fake-getnameinfo.h openssl/../utils.h openssl/../xalloc.h \ - /usr/include/openssl/err.h /usr/include/openssl/e_os2.h \ - /usr/include/x86_64-linux-gnu/openssl/opensslconf.h \ - /usr/include/openssl/ossl_typ.h /usr/include/openssl/bio.h \ - /usr/include/openssl/crypto.h /usr/include/openssl/stack.h \ - /usr/include/openssl/safestack.h /usr/include/openssl/opensslv.h \ - /usr/include/openssl/symhacks.h /usr/include/openssl/lhash.h \ - /usr/include/openssl/hmac.h /usr/include/openssl/evp.h \ - /usr/include/openssl/objects.h /usr/include/openssl/obj_mac.h \ - /usr/include/openssl/asn1.h /usr/include/openssl/bn.h openssl/digest.h \ - openssl/../digest.h openssl/../logger.h - -/usr/include/stdc-predef.h: - -/usr/include/x86_64-linux-gnu/bits/predefs.h: - -openssl/../system.h: - -openssl/../../config.h: - -openssl/../have.h: - -/usr/include/stdio.h: - -/usr/include/features.h: - -/usr/include/x86_64-linux-gnu/sys/cdefs.h: - -/usr/include/x86_64-linux-gnu/bits/wordsize.h: - -/usr/include/x86_64-linux-gnu/gnu/stubs.h: - -/usr/include/x86_64-linux-gnu/gnu/stubs-64.h: - -/usr/lib/gcc/x86_64-linux-gnu/4.8/include/stddef.h: - -/usr/include/x86_64-linux-gnu/bits/types.h: - -/usr/include/x86_64-linux-gnu/bits/typesizes.h: - -/usr/include/libio.h: - -/usr/include/_G_config.h: - -/usr/include/wchar.h: - -/usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdarg.h: - -/usr/include/x86_64-linux-gnu/bits/stdio_lim.h: - -/usr/include/x86_64-linux-gnu/bits/sys_errlist.h: - -/usr/include/x86_64-linux-gnu/bits/stdio.h: - -/usr/include/stdlib.h: - -/usr/include/x86_64-linux-gnu/bits/waitflags.h: - -/usr/include/x86_64-linux-gnu/bits/waitstatus.h: - -/usr/include/endian.h: - -/usr/include/x86_64-linux-gnu/bits/endian.h: - -/usr/include/x86_64-linux-gnu/bits/byteswap.h: - -/usr/include/x86_64-linux-gnu/bits/byteswap-16.h: - -/usr/include/xlocale.h: - -/usr/include/x86_64-linux-gnu/sys/types.h: - -/usr/include/time.h: - -/usr/include/x86_64-linux-gnu/sys/select.h: - -/usr/include/x86_64-linux-gnu/bits/select.h: - -/usr/include/x86_64-linux-gnu/bits/sigset.h: - -/usr/include/x86_64-linux-gnu/bits/time.h: - -/usr/include/x86_64-linux-gnu/sys/sysmacros.h: - -/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h: - -/usr/include/alloca.h: - -/usr/include/x86_64-linux-gnu/bits/stdlib-float.h: - -/usr/include/string.h: - -/usr/include/x86_64-linux-gnu/bits/string.h: - -/usr/include/x86_64-linux-gnu/bits/string2.h: - -/usr/include/ctype.h: - -/usr/include/signal.h: - -/usr/include/x86_64-linux-gnu/bits/signum.h: - -/usr/include/x86_64-linux-gnu/bits/siginfo.h: - -/usr/include/x86_64-linux-gnu/bits/sigaction.h: - -/usr/include/x86_64-linux-gnu/bits/sigcontext.h: - -/usr/include/x86_64-linux-gnu/bits/sigstack.h: - -/usr/include/x86_64-linux-gnu/sys/ucontext.h: - -/usr/include/x86_64-linux-gnu/bits/sigthread.h: - -/usr/include/errno.h: - -/usr/include/x86_64-linux-gnu/bits/errno.h: - -/usr/include/linux/errno.h: - -/usr/include/x86_64-linux-gnu/asm/errno.h: - -/usr/include/asm-generic/errno.h: - -/usr/include/asm-generic/errno-base.h: - -/usr/include/fcntl.h: - -/usr/include/x86_64-linux-gnu/bits/fcntl.h: - -/usr/include/x86_64-linux-gnu/bits/fcntl-linux.h: - -/usr/include/x86_64-linux-gnu/bits/uio.h: - -/usr/include/x86_64-linux-gnu/bits/stat.h: - -/usr/include/unistd.h: - -/usr/include/x86_64-linux-gnu/bits/posix_opt.h: - -/usr/include/x86_64-linux-gnu/bits/environments.h: - -/usr/include/x86_64-linux-gnu/bits/confname.h: - -/usr/include/getopt.h: - -/usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdbool.h: - -/usr/include/inttypes.h: - -/usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdint.h: - -/usr/include/stdint.h: - -/usr/include/x86_64-linux-gnu/bits/wchar.h: - -/usr/include/syslog.h: - -/usr/include/x86_64-linux-gnu/sys/syslog.h: - -/usr/include/x86_64-linux-gnu/bits/syslog-path.h: - -/usr/include/x86_64-linux-gnu/sys/time.h: - -/usr/include/x86_64-linux-gnu/bits/timex.h: - -/usr/include/x86_64-linux-gnu/sys/stat.h: - -/usr/include/x86_64-linux-gnu/sys/file.h: - -/usr/include/x86_64-linux-gnu/sys/wait.h: - -/usr/include/x86_64-linux-gnu/sys/ioctl.h: - -/usr/include/x86_64-linux-gnu/bits/ioctls.h: - -/usr/include/x86_64-linux-gnu/asm/ioctls.h: - -/usr/include/asm-generic/ioctls.h: - -/usr/include/linux/ioctl.h: - -/usr/include/x86_64-linux-gnu/asm/ioctl.h: - -/usr/include/asm-generic/ioctl.h: - -/usr/include/x86_64-linux-gnu/bits/ioctl-types.h: - -/usr/include/x86_64-linux-gnu/sys/ttydefaults.h: - -/usr/include/x86_64-linux-gnu/sys/param.h: - -/usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/limits.h: - -/usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/syslimits.h: - -/usr/include/limits.h: - -/usr/include/x86_64-linux-gnu/bits/posix1_lim.h: - -/usr/include/x86_64-linux-gnu/bits/local_lim.h: - -/usr/include/linux/limits.h: - -/usr/include/x86_64-linux-gnu/bits/posix2_lim.h: - -/usr/include/x86_64-linux-gnu/bits/xopen_lim.h: - -/usr/include/x86_64-linux-gnu/bits/param.h: - -/usr/include/linux/param.h: - -/usr/include/x86_64-linux-gnu/asm/param.h: - -/usr/include/asm-generic/param.h: - -/usr/include/x86_64-linux-gnu/sys/resource.h: - -/usr/include/x86_64-linux-gnu/bits/resource.h: - -/usr/include/x86_64-linux-gnu/sys/uio.h: - -/usr/include/x86_64-linux-gnu/sys/un.h: - -/usr/include/x86_64-linux-gnu/bits/sockaddr.h: - -/usr/include/dirent.h: - -/usr/include/x86_64-linux-gnu/bits/dirent.h: - -/usr/include/netdb.h: - -/usr/include/netinet/in.h: - -/usr/include/x86_64-linux-gnu/sys/socket.h: - -/usr/include/x86_64-linux-gnu/bits/socket.h: - -/usr/include/x86_64-linux-gnu/bits/socket_type.h: - -/usr/include/x86_64-linux-gnu/asm/socket.h: - -/usr/include/asm-generic/socket.h: - -/usr/include/x86_64-linux-gnu/asm/sockios.h: - -/usr/include/asm-generic/sockios.h: - -/usr/include/x86_64-linux-gnu/bits/in.h: - -/usr/include/rpc/netdb.h: - -/usr/include/x86_64-linux-gnu/bits/netdb.h: - -/usr/include/net/if.h: - -/usr/include/netinet/in_systm.h: - -/usr/include/arpa/inet.h: - -/usr/include/netinet/ip.h: - -/usr/include/netinet/tcp.h: - -/usr/include/netinet/ip6.h: - -/usr/include/net/ethernet.h: - -/usr/include/linux/if_ether.h: - -/usr/include/linux/types.h: - -/usr/include/x86_64-linux-gnu/asm/types.h: - -/usr/include/asm-generic/types.h: - -/usr/include/asm-generic/int-ll64.h: - -/usr/include/x86_64-linux-gnu/asm/bitsperlong.h: - -/usr/include/asm-generic/bitsperlong.h: - -/usr/include/linux/posix_types.h: - -/usr/include/linux/stddef.h: - -/usr/include/x86_64-linux-gnu/asm/posix_types.h: - -/usr/include/x86_64-linux-gnu/asm/posix_types_64.h: - -/usr/include/asm-generic/posix_types.h: - -/usr/include/net/if_arp.h: - -/usr/include/netinet/ip_icmp.h: - -/usr/include/netinet/icmp6.h: - -/usr/include/netinet/if_ether.h: - -openssl/../dropin.h: - -openssl/../fake-getaddrinfo.h: - -openssl/../fake-gai-errnos.h: - -openssl/../fake-getnameinfo.h: - -openssl/../utils.h: - -openssl/../xalloc.h: - -/usr/include/openssl/err.h: - -/usr/include/openssl/e_os2.h: - -/usr/include/x86_64-linux-gnu/openssl/opensslconf.h: - -/usr/include/openssl/ossl_typ.h: - -/usr/include/openssl/bio.h: - -/usr/include/openssl/crypto.h: - -/usr/include/openssl/stack.h: - -/usr/include/openssl/safestack.h: - -/usr/include/openssl/opensslv.h: - -/usr/include/openssl/symhacks.h: - -/usr/include/openssl/lhash.h: - -/usr/include/openssl/hmac.h: - -/usr/include/openssl/evp.h: - -/usr/include/openssl/objects.h: - -/usr/include/openssl/obj_mac.h: - -/usr/include/openssl/asn1.h: - -/usr/include/openssl/bn.h: - -openssl/digest.h: - -openssl/../digest.h: - -openssl/../logger.h: diff --git a/src/openssl/.deps/ecdh.Po b/src/openssl/.deps/ecdh.Po deleted file mode 100644 index 96dcd00..0000000 --- a/src/openssl/.deps/ecdh.Po +++ /dev/null @@ -1,454 +0,0 @@ -openssl/ecdh.o: openssl/ecdh.c /usr/include/stdc-predef.h \ - /usr/include/x86_64-linux-gnu/bits/predefs.h openssl/../system.h \ - openssl/../../config.h openssl/../have.h /usr/include/stdio.h \ - /usr/include/features.h /usr/include/x86_64-linux-gnu/sys/cdefs.h \ - /usr/include/x86_64-linux-gnu/bits/wordsize.h \ - /usr/include/x86_64-linux-gnu/gnu/stubs.h \ - /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ - /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stddef.h \ - /usr/include/x86_64-linux-gnu/bits/types.h \ - /usr/include/x86_64-linux-gnu/bits/typesizes.h /usr/include/libio.h \ - /usr/include/_G_config.h /usr/include/wchar.h \ - /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdarg.h \ - /usr/include/x86_64-linux-gnu/bits/stdio_lim.h \ - /usr/include/x86_64-linux-gnu/bits/sys_errlist.h \ - /usr/include/x86_64-linux-gnu/bits/stdio.h /usr/include/stdlib.h \ - /usr/include/x86_64-linux-gnu/bits/waitflags.h \ - /usr/include/x86_64-linux-gnu/bits/waitstatus.h /usr/include/endian.h \ - /usr/include/x86_64-linux-gnu/bits/endian.h \ - /usr/include/x86_64-linux-gnu/bits/byteswap.h \ - /usr/include/x86_64-linux-gnu/bits/byteswap-16.h /usr/include/xlocale.h \ - /usr/include/x86_64-linux-gnu/sys/types.h /usr/include/time.h \ - /usr/include/x86_64-linux-gnu/sys/select.h \ - /usr/include/x86_64-linux-gnu/bits/select.h \ - /usr/include/x86_64-linux-gnu/bits/sigset.h \ - /usr/include/x86_64-linux-gnu/bits/time.h \ - /usr/include/x86_64-linux-gnu/sys/sysmacros.h \ - /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h /usr/include/alloca.h \ - /usr/include/x86_64-linux-gnu/bits/stdlib-float.h /usr/include/string.h \ - /usr/include/x86_64-linux-gnu/bits/string.h \ - /usr/include/x86_64-linux-gnu/bits/string2.h /usr/include/ctype.h \ - /usr/include/signal.h /usr/include/x86_64-linux-gnu/bits/signum.h \ - /usr/include/x86_64-linux-gnu/bits/siginfo.h \ - /usr/include/x86_64-linux-gnu/bits/sigaction.h \ - /usr/include/x86_64-linux-gnu/bits/sigcontext.h \ - /usr/include/x86_64-linux-gnu/bits/sigstack.h \ - /usr/include/x86_64-linux-gnu/sys/ucontext.h \ - /usr/include/x86_64-linux-gnu/bits/sigthread.h /usr/include/errno.h \ - /usr/include/x86_64-linux-gnu/bits/errno.h /usr/include/linux/errno.h \ - /usr/include/x86_64-linux-gnu/asm/errno.h \ - /usr/include/asm-generic/errno.h /usr/include/asm-generic/errno-base.h \ - /usr/include/fcntl.h /usr/include/x86_64-linux-gnu/bits/fcntl.h \ - /usr/include/x86_64-linux-gnu/bits/fcntl-linux.h \ - /usr/include/x86_64-linux-gnu/bits/uio.h \ - /usr/include/x86_64-linux-gnu/bits/stat.h /usr/include/unistd.h \ - /usr/include/x86_64-linux-gnu/bits/posix_opt.h \ - /usr/include/x86_64-linux-gnu/bits/environments.h \ - /usr/include/x86_64-linux-gnu/bits/confname.h /usr/include/getopt.h \ - /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdbool.h \ - /usr/include/inttypes.h \ - /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdint.h /usr/include/stdint.h \ - /usr/include/x86_64-linux-gnu/bits/wchar.h /usr/include/syslog.h \ - /usr/include/x86_64-linux-gnu/sys/syslog.h \ - /usr/include/x86_64-linux-gnu/bits/syslog-path.h \ - /usr/include/x86_64-linux-gnu/sys/time.h \ - /usr/include/x86_64-linux-gnu/bits/timex.h \ - /usr/include/x86_64-linux-gnu/sys/stat.h \ - /usr/include/x86_64-linux-gnu/sys/file.h \ - /usr/include/x86_64-linux-gnu/sys/wait.h \ - /usr/include/x86_64-linux-gnu/sys/ioctl.h \ - /usr/include/x86_64-linux-gnu/bits/ioctls.h \ - /usr/include/x86_64-linux-gnu/asm/ioctls.h \ - /usr/include/asm-generic/ioctls.h /usr/include/linux/ioctl.h \ - /usr/include/x86_64-linux-gnu/asm/ioctl.h \ - /usr/include/asm-generic/ioctl.h \ - /usr/include/x86_64-linux-gnu/bits/ioctl-types.h \ - /usr/include/x86_64-linux-gnu/sys/ttydefaults.h \ - /usr/include/x86_64-linux-gnu/sys/param.h \ - /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/limits.h \ - /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/syslimits.h \ - /usr/include/limits.h /usr/include/x86_64-linux-gnu/bits/posix1_lim.h \ - /usr/include/x86_64-linux-gnu/bits/local_lim.h \ - /usr/include/linux/limits.h \ - /usr/include/x86_64-linux-gnu/bits/posix2_lim.h \ - /usr/include/x86_64-linux-gnu/bits/xopen_lim.h \ - /usr/include/x86_64-linux-gnu/bits/param.h /usr/include/linux/param.h \ - /usr/include/x86_64-linux-gnu/asm/param.h \ - /usr/include/asm-generic/param.h \ - /usr/include/x86_64-linux-gnu/sys/resource.h \ - /usr/include/x86_64-linux-gnu/bits/resource.h \ - /usr/include/x86_64-linux-gnu/sys/uio.h \ - /usr/include/x86_64-linux-gnu/sys/un.h \ - /usr/include/x86_64-linux-gnu/bits/sockaddr.h /usr/include/dirent.h \ - /usr/include/x86_64-linux-gnu/bits/dirent.h /usr/include/netdb.h \ - /usr/include/netinet/in.h /usr/include/x86_64-linux-gnu/sys/socket.h \ - /usr/include/x86_64-linux-gnu/bits/socket.h \ - /usr/include/x86_64-linux-gnu/bits/socket_type.h \ - /usr/include/x86_64-linux-gnu/asm/socket.h \ - /usr/include/asm-generic/socket.h \ - /usr/include/x86_64-linux-gnu/asm/sockios.h \ - /usr/include/asm-generic/sockios.h \ - /usr/include/x86_64-linux-gnu/bits/in.h /usr/include/rpc/netdb.h \ - /usr/include/x86_64-linux-gnu/bits/netdb.h /usr/include/net/if.h \ - /usr/include/netinet/in_systm.h /usr/include/arpa/inet.h \ - /usr/include/netinet/ip.h /usr/include/netinet/tcp.h \ - /usr/include/netinet/ip6.h /usr/include/net/ethernet.h \ - /usr/include/linux/if_ether.h /usr/include/linux/types.h \ - /usr/include/x86_64-linux-gnu/asm/types.h \ - /usr/include/asm-generic/types.h /usr/include/asm-generic/int-ll64.h \ - /usr/include/x86_64-linux-gnu/asm/bitsperlong.h \ - /usr/include/asm-generic/bitsperlong.h /usr/include/linux/posix_types.h \ - /usr/include/linux/stddef.h \ - /usr/include/x86_64-linux-gnu/asm/posix_types.h \ - /usr/include/x86_64-linux-gnu/asm/posix_types_64.h \ - /usr/include/asm-generic/posix_types.h /usr/include/net/if_arp.h \ - /usr/include/netinet/ip_icmp.h /usr/include/netinet/icmp6.h \ - /usr/include/netinet/if_ether.h openssl/../dropin.h \ - openssl/../fake-getaddrinfo.h openssl/../fake-gai-errnos.h \ - openssl/../fake-getnameinfo.h /usr/include/openssl/err.h \ - /usr/include/openssl/e_os2.h \ - /usr/include/x86_64-linux-gnu/openssl/opensslconf.h \ - /usr/include/openssl/ossl_typ.h /usr/include/openssl/bio.h \ - /usr/include/openssl/crypto.h /usr/include/openssl/stack.h \ - /usr/include/openssl/safestack.h /usr/include/openssl/opensslv.h \ - /usr/include/openssl/symhacks.h /usr/include/openssl/lhash.h \ - /usr/include/openssl/ec.h /usr/include/openssl/asn1.h \ - /usr/include/openssl/bn.h /usr/include/openssl/ecdh.h \ - /usr/include/openssl/obj_mac.h openssl/../ecdh.h openssl/../logger.h \ - openssl/../utils.h openssl/../xalloc.h - -/usr/include/stdc-predef.h: - -/usr/include/x86_64-linux-gnu/bits/predefs.h: - -openssl/../system.h: - -openssl/../../config.h: - -openssl/../have.h: - -/usr/include/stdio.h: - -/usr/include/features.h: - -/usr/include/x86_64-linux-gnu/sys/cdefs.h: - -/usr/include/x86_64-linux-gnu/bits/wordsize.h: - -/usr/include/x86_64-linux-gnu/gnu/stubs.h: - -/usr/include/x86_64-linux-gnu/gnu/stubs-64.h: - -/usr/lib/gcc/x86_64-linux-gnu/4.8/include/stddef.h: - -/usr/include/x86_64-linux-gnu/bits/types.h: - -/usr/include/x86_64-linux-gnu/bits/typesizes.h: - -/usr/include/libio.h: - -/usr/include/_G_config.h: - -/usr/include/wchar.h: - -/usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdarg.h: - -/usr/include/x86_64-linux-gnu/bits/stdio_lim.h: - -/usr/include/x86_64-linux-gnu/bits/sys_errlist.h: - -/usr/include/x86_64-linux-gnu/bits/stdio.h: - -/usr/include/stdlib.h: - -/usr/include/x86_64-linux-gnu/bits/waitflags.h: - -/usr/include/x86_64-linux-gnu/bits/waitstatus.h: - -/usr/include/endian.h: - -/usr/include/x86_64-linux-gnu/bits/endian.h: - -/usr/include/x86_64-linux-gnu/bits/byteswap.h: - -/usr/include/x86_64-linux-gnu/bits/byteswap-16.h: - -/usr/include/xlocale.h: - -/usr/include/x86_64-linux-gnu/sys/types.h: - -/usr/include/time.h: - -/usr/include/x86_64-linux-gnu/sys/select.h: - -/usr/include/x86_64-linux-gnu/bits/select.h: - -/usr/include/x86_64-linux-gnu/bits/sigset.h: - -/usr/include/x86_64-linux-gnu/bits/time.h: - -/usr/include/x86_64-linux-gnu/sys/sysmacros.h: - -/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h: - -/usr/include/alloca.h: - -/usr/include/x86_64-linux-gnu/bits/stdlib-float.h: - -/usr/include/string.h: - -/usr/include/x86_64-linux-gnu/bits/string.h: - -/usr/include/x86_64-linux-gnu/bits/string2.h: - -/usr/include/ctype.h: - -/usr/include/signal.h: - -/usr/include/x86_64-linux-gnu/bits/signum.h: - -/usr/include/x86_64-linux-gnu/bits/siginfo.h: - -/usr/include/x86_64-linux-gnu/bits/sigaction.h: - -/usr/include/x86_64-linux-gnu/bits/sigcontext.h: - -/usr/include/x86_64-linux-gnu/bits/sigstack.h: - -/usr/include/x86_64-linux-gnu/sys/ucontext.h: - -/usr/include/x86_64-linux-gnu/bits/sigthread.h: - -/usr/include/errno.h: - -/usr/include/x86_64-linux-gnu/bits/errno.h: - -/usr/include/linux/errno.h: - -/usr/include/x86_64-linux-gnu/asm/errno.h: - -/usr/include/asm-generic/errno.h: - -/usr/include/asm-generic/errno-base.h: - -/usr/include/fcntl.h: - -/usr/include/x86_64-linux-gnu/bits/fcntl.h: - -/usr/include/x86_64-linux-gnu/bits/fcntl-linux.h: - -/usr/include/x86_64-linux-gnu/bits/uio.h: - -/usr/include/x86_64-linux-gnu/bits/stat.h: - -/usr/include/unistd.h: - -/usr/include/x86_64-linux-gnu/bits/posix_opt.h: - -/usr/include/x86_64-linux-gnu/bits/environments.h: - -/usr/include/x86_64-linux-gnu/bits/confname.h: - -/usr/include/getopt.h: - -/usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdbool.h: - -/usr/include/inttypes.h: - -/usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdint.h: - -/usr/include/stdint.h: - -/usr/include/x86_64-linux-gnu/bits/wchar.h: - -/usr/include/syslog.h: - -/usr/include/x86_64-linux-gnu/sys/syslog.h: - -/usr/include/x86_64-linux-gnu/bits/syslog-path.h: - -/usr/include/x86_64-linux-gnu/sys/time.h: - -/usr/include/x86_64-linux-gnu/bits/timex.h: - -/usr/include/x86_64-linux-gnu/sys/stat.h: - -/usr/include/x86_64-linux-gnu/sys/file.h: - -/usr/include/x86_64-linux-gnu/sys/wait.h: - -/usr/include/x86_64-linux-gnu/sys/ioctl.h: - -/usr/include/x86_64-linux-gnu/bits/ioctls.h: - -/usr/include/x86_64-linux-gnu/asm/ioctls.h: - -/usr/include/asm-generic/ioctls.h: - -/usr/include/linux/ioctl.h: - -/usr/include/x86_64-linux-gnu/asm/ioctl.h: - -/usr/include/asm-generic/ioctl.h: - -/usr/include/x86_64-linux-gnu/bits/ioctl-types.h: - -/usr/include/x86_64-linux-gnu/sys/ttydefaults.h: - -/usr/include/x86_64-linux-gnu/sys/param.h: - -/usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/limits.h: - -/usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/syslimits.h: - -/usr/include/limits.h: - -/usr/include/x86_64-linux-gnu/bits/posix1_lim.h: - -/usr/include/x86_64-linux-gnu/bits/local_lim.h: - -/usr/include/linux/limits.h: - -/usr/include/x86_64-linux-gnu/bits/posix2_lim.h: - -/usr/include/x86_64-linux-gnu/bits/xopen_lim.h: - -/usr/include/x86_64-linux-gnu/bits/param.h: - -/usr/include/linux/param.h: - -/usr/include/x86_64-linux-gnu/asm/param.h: - -/usr/include/asm-generic/param.h: - -/usr/include/x86_64-linux-gnu/sys/resource.h: - -/usr/include/x86_64-linux-gnu/bits/resource.h: - -/usr/include/x86_64-linux-gnu/sys/uio.h: - -/usr/include/x86_64-linux-gnu/sys/un.h: - -/usr/include/x86_64-linux-gnu/bits/sockaddr.h: - -/usr/include/dirent.h: - -/usr/include/x86_64-linux-gnu/bits/dirent.h: - -/usr/include/netdb.h: - -/usr/include/netinet/in.h: - -/usr/include/x86_64-linux-gnu/sys/socket.h: - -/usr/include/x86_64-linux-gnu/bits/socket.h: - -/usr/include/x86_64-linux-gnu/bits/socket_type.h: - -/usr/include/x86_64-linux-gnu/asm/socket.h: - -/usr/include/asm-generic/socket.h: - -/usr/include/x86_64-linux-gnu/asm/sockios.h: - -/usr/include/asm-generic/sockios.h: - -/usr/include/x86_64-linux-gnu/bits/in.h: - -/usr/include/rpc/netdb.h: - -/usr/include/x86_64-linux-gnu/bits/netdb.h: - -/usr/include/net/if.h: - -/usr/include/netinet/in_systm.h: - -/usr/include/arpa/inet.h: - -/usr/include/netinet/ip.h: - -/usr/include/netinet/tcp.h: - -/usr/include/netinet/ip6.h: - -/usr/include/net/ethernet.h: - -/usr/include/linux/if_ether.h: - -/usr/include/linux/types.h: - -/usr/include/x86_64-linux-gnu/asm/types.h: - -/usr/include/asm-generic/types.h: - -/usr/include/asm-generic/int-ll64.h: - -/usr/include/x86_64-linux-gnu/asm/bitsperlong.h: - -/usr/include/asm-generic/bitsperlong.h: - -/usr/include/linux/posix_types.h: - -/usr/include/linux/stddef.h: - -/usr/include/x86_64-linux-gnu/asm/posix_types.h: - -/usr/include/x86_64-linux-gnu/asm/posix_types_64.h: - -/usr/include/asm-generic/posix_types.h: - -/usr/include/net/if_arp.h: - -/usr/include/netinet/ip_icmp.h: - -/usr/include/netinet/icmp6.h: - -/usr/include/netinet/if_ether.h: - -openssl/../dropin.h: - -openssl/../fake-getaddrinfo.h: - -openssl/../fake-gai-errnos.h: - -openssl/../fake-getnameinfo.h: - -/usr/include/openssl/err.h: - -/usr/include/openssl/e_os2.h: - -/usr/include/x86_64-linux-gnu/openssl/opensslconf.h: - -/usr/include/openssl/ossl_typ.h: - -/usr/include/openssl/bio.h: - -/usr/include/openssl/crypto.h: - -/usr/include/openssl/stack.h: - -/usr/include/openssl/safestack.h: - -/usr/include/openssl/opensslv.h: - -/usr/include/openssl/symhacks.h: - -/usr/include/openssl/lhash.h: - -/usr/include/openssl/ec.h: - -/usr/include/openssl/asn1.h: - -/usr/include/openssl/bn.h: - -/usr/include/openssl/ecdh.h: - -/usr/include/openssl/obj_mac.h: - -openssl/../ecdh.h: - -openssl/../logger.h: - -openssl/../utils.h: - -openssl/../xalloc.h: diff --git a/src/openssl/.deps/ecdsa.Po b/src/openssl/.deps/ecdsa.Po deleted file mode 100644 index f6e3f65..0000000 --- a/src/openssl/.deps/ecdsa.Po +++ /dev/null @@ -1,487 +0,0 @@ -openssl/ecdsa.o: openssl/ecdsa.c /usr/include/stdc-predef.h \ - /usr/include/x86_64-linux-gnu/bits/predefs.h openssl/../system.h \ - openssl/../../config.h openssl/../have.h /usr/include/stdio.h \ - /usr/include/features.h /usr/include/x86_64-linux-gnu/sys/cdefs.h \ - /usr/include/x86_64-linux-gnu/bits/wordsize.h \ - /usr/include/x86_64-linux-gnu/gnu/stubs.h \ - /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ - /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stddef.h \ - /usr/include/x86_64-linux-gnu/bits/types.h \ - /usr/include/x86_64-linux-gnu/bits/typesizes.h /usr/include/libio.h \ - /usr/include/_G_config.h /usr/include/wchar.h \ - /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdarg.h \ - /usr/include/x86_64-linux-gnu/bits/stdio_lim.h \ - /usr/include/x86_64-linux-gnu/bits/sys_errlist.h \ - /usr/include/x86_64-linux-gnu/bits/stdio.h /usr/include/stdlib.h \ - /usr/include/x86_64-linux-gnu/bits/waitflags.h \ - /usr/include/x86_64-linux-gnu/bits/waitstatus.h /usr/include/endian.h \ - /usr/include/x86_64-linux-gnu/bits/endian.h \ - /usr/include/x86_64-linux-gnu/bits/byteswap.h \ - /usr/include/x86_64-linux-gnu/bits/byteswap-16.h /usr/include/xlocale.h \ - /usr/include/x86_64-linux-gnu/sys/types.h /usr/include/time.h \ - /usr/include/x86_64-linux-gnu/sys/select.h \ - /usr/include/x86_64-linux-gnu/bits/select.h \ - /usr/include/x86_64-linux-gnu/bits/sigset.h \ - /usr/include/x86_64-linux-gnu/bits/time.h \ - /usr/include/x86_64-linux-gnu/sys/sysmacros.h \ - /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h /usr/include/alloca.h \ - /usr/include/x86_64-linux-gnu/bits/stdlib-float.h /usr/include/string.h \ - /usr/include/x86_64-linux-gnu/bits/string.h \ - /usr/include/x86_64-linux-gnu/bits/string2.h /usr/include/ctype.h \ - /usr/include/signal.h /usr/include/x86_64-linux-gnu/bits/signum.h \ - /usr/include/x86_64-linux-gnu/bits/siginfo.h \ - /usr/include/x86_64-linux-gnu/bits/sigaction.h \ - /usr/include/x86_64-linux-gnu/bits/sigcontext.h \ - /usr/include/x86_64-linux-gnu/bits/sigstack.h \ - /usr/include/x86_64-linux-gnu/sys/ucontext.h \ - /usr/include/x86_64-linux-gnu/bits/sigthread.h /usr/include/errno.h \ - /usr/include/x86_64-linux-gnu/bits/errno.h /usr/include/linux/errno.h \ - /usr/include/x86_64-linux-gnu/asm/errno.h \ - /usr/include/asm-generic/errno.h /usr/include/asm-generic/errno-base.h \ - /usr/include/fcntl.h /usr/include/x86_64-linux-gnu/bits/fcntl.h \ - /usr/include/x86_64-linux-gnu/bits/fcntl-linux.h \ - /usr/include/x86_64-linux-gnu/bits/uio.h \ - /usr/include/x86_64-linux-gnu/bits/stat.h /usr/include/unistd.h \ - /usr/include/x86_64-linux-gnu/bits/posix_opt.h \ - /usr/include/x86_64-linux-gnu/bits/environments.h \ - /usr/include/x86_64-linux-gnu/bits/confname.h /usr/include/getopt.h \ - /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdbool.h \ - /usr/include/inttypes.h \ - /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdint.h /usr/include/stdint.h \ - /usr/include/x86_64-linux-gnu/bits/wchar.h /usr/include/syslog.h \ - /usr/include/x86_64-linux-gnu/sys/syslog.h \ - /usr/include/x86_64-linux-gnu/bits/syslog-path.h \ - /usr/include/x86_64-linux-gnu/sys/time.h \ - /usr/include/x86_64-linux-gnu/bits/timex.h \ - /usr/include/x86_64-linux-gnu/sys/stat.h \ - /usr/include/x86_64-linux-gnu/sys/file.h \ - /usr/include/x86_64-linux-gnu/sys/wait.h \ - /usr/include/x86_64-linux-gnu/sys/ioctl.h \ - /usr/include/x86_64-linux-gnu/bits/ioctls.h \ - /usr/include/x86_64-linux-gnu/asm/ioctls.h \ - /usr/include/asm-generic/ioctls.h /usr/include/linux/ioctl.h \ - /usr/include/x86_64-linux-gnu/asm/ioctl.h \ - /usr/include/asm-generic/ioctl.h \ - /usr/include/x86_64-linux-gnu/bits/ioctl-types.h \ - /usr/include/x86_64-linux-gnu/sys/ttydefaults.h \ - /usr/include/x86_64-linux-gnu/sys/param.h \ - /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/limits.h \ - /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/syslimits.h \ - /usr/include/limits.h /usr/include/x86_64-linux-gnu/bits/posix1_lim.h \ - /usr/include/x86_64-linux-gnu/bits/local_lim.h \ - /usr/include/linux/limits.h \ - /usr/include/x86_64-linux-gnu/bits/posix2_lim.h \ - /usr/include/x86_64-linux-gnu/bits/xopen_lim.h \ - /usr/include/x86_64-linux-gnu/bits/param.h /usr/include/linux/param.h \ - /usr/include/x86_64-linux-gnu/asm/param.h \ - /usr/include/asm-generic/param.h \ - /usr/include/x86_64-linux-gnu/sys/resource.h \ - /usr/include/x86_64-linux-gnu/bits/resource.h \ - /usr/include/x86_64-linux-gnu/sys/uio.h \ - /usr/include/x86_64-linux-gnu/sys/un.h \ - /usr/include/x86_64-linux-gnu/bits/sockaddr.h /usr/include/dirent.h \ - /usr/include/x86_64-linux-gnu/bits/dirent.h /usr/include/netdb.h \ - /usr/include/netinet/in.h /usr/include/x86_64-linux-gnu/sys/socket.h \ - /usr/include/x86_64-linux-gnu/bits/socket.h \ - /usr/include/x86_64-linux-gnu/bits/socket_type.h \ - /usr/include/x86_64-linux-gnu/asm/socket.h \ - /usr/include/asm-generic/socket.h \ - /usr/include/x86_64-linux-gnu/asm/sockios.h \ - /usr/include/asm-generic/sockios.h \ - /usr/include/x86_64-linux-gnu/bits/in.h /usr/include/rpc/netdb.h \ - /usr/include/x86_64-linux-gnu/bits/netdb.h /usr/include/net/if.h \ - /usr/include/netinet/in_systm.h /usr/include/arpa/inet.h \ - /usr/include/netinet/ip.h /usr/include/netinet/tcp.h \ - /usr/include/netinet/ip6.h /usr/include/net/ethernet.h \ - /usr/include/linux/if_ether.h /usr/include/linux/types.h \ - /usr/include/x86_64-linux-gnu/asm/types.h \ - /usr/include/asm-generic/types.h /usr/include/asm-generic/int-ll64.h \ - /usr/include/x86_64-linux-gnu/asm/bitsperlong.h \ - /usr/include/asm-generic/bitsperlong.h /usr/include/linux/posix_types.h \ - /usr/include/linux/stddef.h \ - /usr/include/x86_64-linux-gnu/asm/posix_types.h \ - /usr/include/x86_64-linux-gnu/asm/posix_types_64.h \ - /usr/include/asm-generic/posix_types.h /usr/include/net/if_arp.h \ - /usr/include/netinet/ip_icmp.h /usr/include/netinet/icmp6.h \ - /usr/include/netinet/if_ether.h openssl/../dropin.h \ - openssl/../fake-getaddrinfo.h openssl/../fake-gai-errnos.h \ - openssl/../fake-getnameinfo.h /usr/include/openssl/pem.h \ - /usr/include/openssl/e_os2.h \ - /usr/include/x86_64-linux-gnu/openssl/opensslconf.h \ - /usr/include/openssl/bio.h /usr/include/openssl/crypto.h \ - /usr/include/openssl/stack.h /usr/include/openssl/safestack.h \ - /usr/include/openssl/opensslv.h /usr/include/openssl/ossl_typ.h \ - /usr/include/openssl/symhacks.h /usr/include/openssl/evp.h \ - /usr/include/openssl/objects.h /usr/include/openssl/obj_mac.h \ - /usr/include/openssl/asn1.h /usr/include/openssl/bn.h \ - /usr/include/openssl/x509.h /usr/include/openssl/buffer.h \ - /usr/include/openssl/ec.h /usr/include/openssl/ecdsa.h \ - /usr/include/openssl/ecdh.h /usr/include/openssl/rsa.h \ - /usr/include/openssl/dsa.h /usr/include/openssl/dh.h \ - /usr/include/openssl/sha.h /usr/include/openssl/x509_vfy.h \ - /usr/include/openssl/lhash.h /usr/include/openssl/pkcs7.h \ - /usr/include/openssl/pem2.h /usr/include/openssl/err.h \ - openssl/../logger.h openssl/../ecdsa.h openssl/../utils.h \ - openssl/../xalloc.h - -/usr/include/stdc-predef.h: - -/usr/include/x86_64-linux-gnu/bits/predefs.h: - -openssl/../system.h: - -openssl/../../config.h: - -openssl/../have.h: - -/usr/include/stdio.h: - -/usr/include/features.h: - -/usr/include/x86_64-linux-gnu/sys/cdefs.h: - -/usr/include/x86_64-linux-gnu/bits/wordsize.h: - -/usr/include/x86_64-linux-gnu/gnu/stubs.h: - -/usr/include/x86_64-linux-gnu/gnu/stubs-64.h: - -/usr/lib/gcc/x86_64-linux-gnu/4.8/include/stddef.h: - -/usr/include/x86_64-linux-gnu/bits/types.h: - -/usr/include/x86_64-linux-gnu/bits/typesizes.h: - -/usr/include/libio.h: - -/usr/include/_G_config.h: - -/usr/include/wchar.h: - -/usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdarg.h: - -/usr/include/x86_64-linux-gnu/bits/stdio_lim.h: - -/usr/include/x86_64-linux-gnu/bits/sys_errlist.h: - -/usr/include/x86_64-linux-gnu/bits/stdio.h: - -/usr/include/stdlib.h: - -/usr/include/x86_64-linux-gnu/bits/waitflags.h: - -/usr/include/x86_64-linux-gnu/bits/waitstatus.h: - -/usr/include/endian.h: - -/usr/include/x86_64-linux-gnu/bits/endian.h: - -/usr/include/x86_64-linux-gnu/bits/byteswap.h: - -/usr/include/x86_64-linux-gnu/bits/byteswap-16.h: - -/usr/include/xlocale.h: - -/usr/include/x86_64-linux-gnu/sys/types.h: - -/usr/include/time.h: - -/usr/include/x86_64-linux-gnu/sys/select.h: - -/usr/include/x86_64-linux-gnu/bits/select.h: - -/usr/include/x86_64-linux-gnu/bits/sigset.h: - -/usr/include/x86_64-linux-gnu/bits/time.h: - -/usr/include/x86_64-linux-gnu/sys/sysmacros.h: - -/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h: - -/usr/include/alloca.h: - -/usr/include/x86_64-linux-gnu/bits/stdlib-float.h: - -/usr/include/string.h: - -/usr/include/x86_64-linux-gnu/bits/string.h: - -/usr/include/x86_64-linux-gnu/bits/string2.h: - -/usr/include/ctype.h: - -/usr/include/signal.h: - -/usr/include/x86_64-linux-gnu/bits/signum.h: - -/usr/include/x86_64-linux-gnu/bits/siginfo.h: - -/usr/include/x86_64-linux-gnu/bits/sigaction.h: - -/usr/include/x86_64-linux-gnu/bits/sigcontext.h: - -/usr/include/x86_64-linux-gnu/bits/sigstack.h: - -/usr/include/x86_64-linux-gnu/sys/ucontext.h: - -/usr/include/x86_64-linux-gnu/bits/sigthread.h: - -/usr/include/errno.h: - -/usr/include/x86_64-linux-gnu/bits/errno.h: - -/usr/include/linux/errno.h: - -/usr/include/x86_64-linux-gnu/asm/errno.h: - -/usr/include/asm-generic/errno.h: - -/usr/include/asm-generic/errno-base.h: - -/usr/include/fcntl.h: - -/usr/include/x86_64-linux-gnu/bits/fcntl.h: - -/usr/include/x86_64-linux-gnu/bits/fcntl-linux.h: - -/usr/include/x86_64-linux-gnu/bits/uio.h: - -/usr/include/x86_64-linux-gnu/bits/stat.h: - -/usr/include/unistd.h: - -/usr/include/x86_64-linux-gnu/bits/posix_opt.h: - -/usr/include/x86_64-linux-gnu/bits/environments.h: - -/usr/include/x86_64-linux-gnu/bits/confname.h: - -/usr/include/getopt.h: - -/usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdbool.h: - -/usr/include/inttypes.h: - -/usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdint.h: - -/usr/include/stdint.h: - -/usr/include/x86_64-linux-gnu/bits/wchar.h: - -/usr/include/syslog.h: - -/usr/include/x86_64-linux-gnu/sys/syslog.h: - -/usr/include/x86_64-linux-gnu/bits/syslog-path.h: - -/usr/include/x86_64-linux-gnu/sys/time.h: - -/usr/include/x86_64-linux-gnu/bits/timex.h: - -/usr/include/x86_64-linux-gnu/sys/stat.h: - -/usr/include/x86_64-linux-gnu/sys/file.h: - -/usr/include/x86_64-linux-gnu/sys/wait.h: - -/usr/include/x86_64-linux-gnu/sys/ioctl.h: - -/usr/include/x86_64-linux-gnu/bits/ioctls.h: - -/usr/include/x86_64-linux-gnu/asm/ioctls.h: - -/usr/include/asm-generic/ioctls.h: - -/usr/include/linux/ioctl.h: - -/usr/include/x86_64-linux-gnu/asm/ioctl.h: - -/usr/include/asm-generic/ioctl.h: - -/usr/include/x86_64-linux-gnu/bits/ioctl-types.h: - -/usr/include/x86_64-linux-gnu/sys/ttydefaults.h: - -/usr/include/x86_64-linux-gnu/sys/param.h: - -/usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/limits.h: - -/usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/syslimits.h: - -/usr/include/limits.h: - -/usr/include/x86_64-linux-gnu/bits/posix1_lim.h: - -/usr/include/x86_64-linux-gnu/bits/local_lim.h: - -/usr/include/linux/limits.h: - -/usr/include/x86_64-linux-gnu/bits/posix2_lim.h: - -/usr/include/x86_64-linux-gnu/bits/xopen_lim.h: - -/usr/include/x86_64-linux-gnu/bits/param.h: - -/usr/include/linux/param.h: - -/usr/include/x86_64-linux-gnu/asm/param.h: - -/usr/include/asm-generic/param.h: - -/usr/include/x86_64-linux-gnu/sys/resource.h: - -/usr/include/x86_64-linux-gnu/bits/resource.h: - -/usr/include/x86_64-linux-gnu/sys/uio.h: - -/usr/include/x86_64-linux-gnu/sys/un.h: - -/usr/include/x86_64-linux-gnu/bits/sockaddr.h: - -/usr/include/dirent.h: - -/usr/include/x86_64-linux-gnu/bits/dirent.h: - -/usr/include/netdb.h: - -/usr/include/netinet/in.h: - -/usr/include/x86_64-linux-gnu/sys/socket.h: - -/usr/include/x86_64-linux-gnu/bits/socket.h: - -/usr/include/x86_64-linux-gnu/bits/socket_type.h: - -/usr/include/x86_64-linux-gnu/asm/socket.h: - -/usr/include/asm-generic/socket.h: - -/usr/include/x86_64-linux-gnu/asm/sockios.h: - -/usr/include/asm-generic/sockios.h: - -/usr/include/x86_64-linux-gnu/bits/in.h: - -/usr/include/rpc/netdb.h: - -/usr/include/x86_64-linux-gnu/bits/netdb.h: - -/usr/include/net/if.h: - -/usr/include/netinet/in_systm.h: - -/usr/include/arpa/inet.h: - -/usr/include/netinet/ip.h: - -/usr/include/netinet/tcp.h: - -/usr/include/netinet/ip6.h: - -/usr/include/net/ethernet.h: - -/usr/include/linux/if_ether.h: - -/usr/include/linux/types.h: - -/usr/include/x86_64-linux-gnu/asm/types.h: - -/usr/include/asm-generic/types.h: - -/usr/include/asm-generic/int-ll64.h: - -/usr/include/x86_64-linux-gnu/asm/bitsperlong.h: - -/usr/include/asm-generic/bitsperlong.h: - -/usr/include/linux/posix_types.h: - -/usr/include/linux/stddef.h: - -/usr/include/x86_64-linux-gnu/asm/posix_types.h: - -/usr/include/x86_64-linux-gnu/asm/posix_types_64.h: - -/usr/include/asm-generic/posix_types.h: - -/usr/include/net/if_arp.h: - -/usr/include/netinet/ip_icmp.h: - -/usr/include/netinet/icmp6.h: - -/usr/include/netinet/if_ether.h: - -openssl/../dropin.h: - -openssl/../fake-getaddrinfo.h: - -openssl/../fake-gai-errnos.h: - -openssl/../fake-getnameinfo.h: - -/usr/include/openssl/pem.h: - -/usr/include/openssl/e_os2.h: - -/usr/include/x86_64-linux-gnu/openssl/opensslconf.h: - -/usr/include/openssl/bio.h: - -/usr/include/openssl/crypto.h: - -/usr/include/openssl/stack.h: - -/usr/include/openssl/safestack.h: - -/usr/include/openssl/opensslv.h: - -/usr/include/openssl/ossl_typ.h: - -/usr/include/openssl/symhacks.h: - -/usr/include/openssl/evp.h: - -/usr/include/openssl/objects.h: - -/usr/include/openssl/obj_mac.h: - -/usr/include/openssl/asn1.h: - -/usr/include/openssl/bn.h: - -/usr/include/openssl/x509.h: - -/usr/include/openssl/buffer.h: - -/usr/include/openssl/ec.h: - -/usr/include/openssl/ecdsa.h: - -/usr/include/openssl/ecdh.h: - -/usr/include/openssl/rsa.h: - -/usr/include/openssl/dsa.h: - -/usr/include/openssl/dh.h: - -/usr/include/openssl/sha.h: - -/usr/include/openssl/x509_vfy.h: - -/usr/include/openssl/lhash.h: - -/usr/include/openssl/pkcs7.h: - -/usr/include/openssl/pem2.h: - -/usr/include/openssl/err.h: - -openssl/../logger.h: - -openssl/../ecdsa.h: - -openssl/../utils.h: - -openssl/../xalloc.h: diff --git a/src/openssl/.deps/ecdsagen.Po b/src/openssl/.deps/ecdsagen.Po deleted file mode 100644 index 51e34f5..0000000 --- a/src/openssl/.deps/ecdsagen.Po +++ /dev/null @@ -1,487 +0,0 @@ -openssl/ecdsagen.o: openssl/ecdsagen.c /usr/include/stdc-predef.h \ - /usr/include/x86_64-linux-gnu/bits/predefs.h openssl/../system.h \ - openssl/../../config.h openssl/../have.h /usr/include/stdio.h \ - /usr/include/features.h /usr/include/x86_64-linux-gnu/sys/cdefs.h \ - /usr/include/x86_64-linux-gnu/bits/wordsize.h \ - /usr/include/x86_64-linux-gnu/gnu/stubs.h \ - /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ - /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stddef.h \ - /usr/include/x86_64-linux-gnu/bits/types.h \ - /usr/include/x86_64-linux-gnu/bits/typesizes.h /usr/include/libio.h \ - /usr/include/_G_config.h /usr/include/wchar.h \ - /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdarg.h \ - /usr/include/x86_64-linux-gnu/bits/stdio_lim.h \ - /usr/include/x86_64-linux-gnu/bits/sys_errlist.h \ - /usr/include/x86_64-linux-gnu/bits/stdio.h /usr/include/stdlib.h \ - /usr/include/x86_64-linux-gnu/bits/waitflags.h \ - /usr/include/x86_64-linux-gnu/bits/waitstatus.h /usr/include/endian.h \ - /usr/include/x86_64-linux-gnu/bits/endian.h \ - /usr/include/x86_64-linux-gnu/bits/byteswap.h \ - /usr/include/x86_64-linux-gnu/bits/byteswap-16.h /usr/include/xlocale.h \ - /usr/include/x86_64-linux-gnu/sys/types.h /usr/include/time.h \ - /usr/include/x86_64-linux-gnu/sys/select.h \ - /usr/include/x86_64-linux-gnu/bits/select.h \ - /usr/include/x86_64-linux-gnu/bits/sigset.h \ - /usr/include/x86_64-linux-gnu/bits/time.h \ - /usr/include/x86_64-linux-gnu/sys/sysmacros.h \ - /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h /usr/include/alloca.h \ - /usr/include/x86_64-linux-gnu/bits/stdlib-float.h /usr/include/string.h \ - /usr/include/x86_64-linux-gnu/bits/string.h \ - /usr/include/x86_64-linux-gnu/bits/string2.h /usr/include/ctype.h \ - /usr/include/signal.h /usr/include/x86_64-linux-gnu/bits/signum.h \ - /usr/include/x86_64-linux-gnu/bits/siginfo.h \ - /usr/include/x86_64-linux-gnu/bits/sigaction.h \ - /usr/include/x86_64-linux-gnu/bits/sigcontext.h \ - /usr/include/x86_64-linux-gnu/bits/sigstack.h \ - /usr/include/x86_64-linux-gnu/sys/ucontext.h \ - /usr/include/x86_64-linux-gnu/bits/sigthread.h /usr/include/errno.h \ - /usr/include/x86_64-linux-gnu/bits/errno.h /usr/include/linux/errno.h \ - /usr/include/x86_64-linux-gnu/asm/errno.h \ - /usr/include/asm-generic/errno.h /usr/include/asm-generic/errno-base.h \ - /usr/include/fcntl.h /usr/include/x86_64-linux-gnu/bits/fcntl.h \ - /usr/include/x86_64-linux-gnu/bits/fcntl-linux.h \ - /usr/include/x86_64-linux-gnu/bits/uio.h \ - /usr/include/x86_64-linux-gnu/bits/stat.h /usr/include/unistd.h \ - /usr/include/x86_64-linux-gnu/bits/posix_opt.h \ - /usr/include/x86_64-linux-gnu/bits/environments.h \ - /usr/include/x86_64-linux-gnu/bits/confname.h /usr/include/getopt.h \ - /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdbool.h \ - /usr/include/inttypes.h \ - /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdint.h /usr/include/stdint.h \ - /usr/include/x86_64-linux-gnu/bits/wchar.h /usr/include/syslog.h \ - /usr/include/x86_64-linux-gnu/sys/syslog.h \ - /usr/include/x86_64-linux-gnu/bits/syslog-path.h \ - /usr/include/x86_64-linux-gnu/sys/time.h \ - /usr/include/x86_64-linux-gnu/bits/timex.h \ - /usr/include/x86_64-linux-gnu/sys/stat.h \ - /usr/include/x86_64-linux-gnu/sys/file.h \ - /usr/include/x86_64-linux-gnu/sys/wait.h \ - /usr/include/x86_64-linux-gnu/sys/ioctl.h \ - /usr/include/x86_64-linux-gnu/bits/ioctls.h \ - /usr/include/x86_64-linux-gnu/asm/ioctls.h \ - /usr/include/asm-generic/ioctls.h /usr/include/linux/ioctl.h \ - /usr/include/x86_64-linux-gnu/asm/ioctl.h \ - /usr/include/asm-generic/ioctl.h \ - /usr/include/x86_64-linux-gnu/bits/ioctl-types.h \ - /usr/include/x86_64-linux-gnu/sys/ttydefaults.h \ - /usr/include/x86_64-linux-gnu/sys/param.h \ - /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/limits.h \ - /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/syslimits.h \ - /usr/include/limits.h /usr/include/x86_64-linux-gnu/bits/posix1_lim.h \ - /usr/include/x86_64-linux-gnu/bits/local_lim.h \ - /usr/include/linux/limits.h \ - /usr/include/x86_64-linux-gnu/bits/posix2_lim.h \ - /usr/include/x86_64-linux-gnu/bits/xopen_lim.h \ - /usr/include/x86_64-linux-gnu/bits/param.h /usr/include/linux/param.h \ - /usr/include/x86_64-linux-gnu/asm/param.h \ - /usr/include/asm-generic/param.h \ - /usr/include/x86_64-linux-gnu/sys/resource.h \ - /usr/include/x86_64-linux-gnu/bits/resource.h \ - /usr/include/x86_64-linux-gnu/sys/uio.h \ - /usr/include/x86_64-linux-gnu/sys/un.h \ - /usr/include/x86_64-linux-gnu/bits/sockaddr.h /usr/include/dirent.h \ - /usr/include/x86_64-linux-gnu/bits/dirent.h /usr/include/netdb.h \ - /usr/include/netinet/in.h /usr/include/x86_64-linux-gnu/sys/socket.h \ - /usr/include/x86_64-linux-gnu/bits/socket.h \ - /usr/include/x86_64-linux-gnu/bits/socket_type.h \ - /usr/include/x86_64-linux-gnu/asm/socket.h \ - /usr/include/asm-generic/socket.h \ - /usr/include/x86_64-linux-gnu/asm/sockios.h \ - /usr/include/asm-generic/sockios.h \ - /usr/include/x86_64-linux-gnu/bits/in.h /usr/include/rpc/netdb.h \ - /usr/include/x86_64-linux-gnu/bits/netdb.h /usr/include/net/if.h \ - /usr/include/netinet/in_systm.h /usr/include/arpa/inet.h \ - /usr/include/netinet/ip.h /usr/include/netinet/tcp.h \ - /usr/include/netinet/ip6.h /usr/include/net/ethernet.h \ - /usr/include/linux/if_ether.h /usr/include/linux/types.h \ - /usr/include/x86_64-linux-gnu/asm/types.h \ - /usr/include/asm-generic/types.h /usr/include/asm-generic/int-ll64.h \ - /usr/include/x86_64-linux-gnu/asm/bitsperlong.h \ - /usr/include/asm-generic/bitsperlong.h /usr/include/linux/posix_types.h \ - /usr/include/linux/stddef.h \ - /usr/include/x86_64-linux-gnu/asm/posix_types.h \ - /usr/include/x86_64-linux-gnu/asm/posix_types_64.h \ - /usr/include/asm-generic/posix_types.h /usr/include/net/if_arp.h \ - /usr/include/netinet/ip_icmp.h /usr/include/netinet/icmp6.h \ - /usr/include/netinet/if_ether.h openssl/../dropin.h \ - openssl/../fake-getaddrinfo.h openssl/../fake-gai-errnos.h \ - openssl/../fake-getnameinfo.h /usr/include/openssl/pem.h \ - /usr/include/openssl/e_os2.h \ - /usr/include/x86_64-linux-gnu/openssl/opensslconf.h \ - /usr/include/openssl/bio.h /usr/include/openssl/crypto.h \ - /usr/include/openssl/stack.h /usr/include/openssl/safestack.h \ - /usr/include/openssl/opensslv.h /usr/include/openssl/ossl_typ.h \ - /usr/include/openssl/symhacks.h /usr/include/openssl/evp.h \ - /usr/include/openssl/objects.h /usr/include/openssl/obj_mac.h \ - /usr/include/openssl/asn1.h /usr/include/openssl/bn.h \ - /usr/include/openssl/x509.h /usr/include/openssl/buffer.h \ - /usr/include/openssl/ec.h /usr/include/openssl/ecdsa.h \ - /usr/include/openssl/ecdh.h /usr/include/openssl/rsa.h \ - /usr/include/openssl/dsa.h /usr/include/openssl/dh.h \ - /usr/include/openssl/sha.h /usr/include/openssl/x509_vfy.h \ - /usr/include/openssl/lhash.h /usr/include/openssl/pkcs7.h \ - /usr/include/openssl/pem2.h /usr/include/openssl/err.h \ - openssl/../ecdsagen.h openssl/../ecdsa.h openssl/../utils.h \ - openssl/../xalloc.h - -/usr/include/stdc-predef.h: - -/usr/include/x86_64-linux-gnu/bits/predefs.h: - -openssl/../system.h: - -openssl/../../config.h: - -openssl/../have.h: - -/usr/include/stdio.h: - -/usr/include/features.h: - -/usr/include/x86_64-linux-gnu/sys/cdefs.h: - -/usr/include/x86_64-linux-gnu/bits/wordsize.h: - -/usr/include/x86_64-linux-gnu/gnu/stubs.h: - -/usr/include/x86_64-linux-gnu/gnu/stubs-64.h: - -/usr/lib/gcc/x86_64-linux-gnu/4.8/include/stddef.h: - -/usr/include/x86_64-linux-gnu/bits/types.h: - -/usr/include/x86_64-linux-gnu/bits/typesizes.h: - -/usr/include/libio.h: - -/usr/include/_G_config.h: - -/usr/include/wchar.h: - -/usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdarg.h: - -/usr/include/x86_64-linux-gnu/bits/stdio_lim.h: - -/usr/include/x86_64-linux-gnu/bits/sys_errlist.h: - -/usr/include/x86_64-linux-gnu/bits/stdio.h: - -/usr/include/stdlib.h: - -/usr/include/x86_64-linux-gnu/bits/waitflags.h: - -/usr/include/x86_64-linux-gnu/bits/waitstatus.h: - -/usr/include/endian.h: - -/usr/include/x86_64-linux-gnu/bits/endian.h: - -/usr/include/x86_64-linux-gnu/bits/byteswap.h: - -/usr/include/x86_64-linux-gnu/bits/byteswap-16.h: - -/usr/include/xlocale.h: - -/usr/include/x86_64-linux-gnu/sys/types.h: - -/usr/include/time.h: - -/usr/include/x86_64-linux-gnu/sys/select.h: - -/usr/include/x86_64-linux-gnu/bits/select.h: - -/usr/include/x86_64-linux-gnu/bits/sigset.h: - -/usr/include/x86_64-linux-gnu/bits/time.h: - -/usr/include/x86_64-linux-gnu/sys/sysmacros.h: - -/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h: - -/usr/include/alloca.h: - -/usr/include/x86_64-linux-gnu/bits/stdlib-float.h: - -/usr/include/string.h: - -/usr/include/x86_64-linux-gnu/bits/string.h: - -/usr/include/x86_64-linux-gnu/bits/string2.h: - -/usr/include/ctype.h: - -/usr/include/signal.h: - -/usr/include/x86_64-linux-gnu/bits/signum.h: - -/usr/include/x86_64-linux-gnu/bits/siginfo.h: - -/usr/include/x86_64-linux-gnu/bits/sigaction.h: - -/usr/include/x86_64-linux-gnu/bits/sigcontext.h: - -/usr/include/x86_64-linux-gnu/bits/sigstack.h: - -/usr/include/x86_64-linux-gnu/sys/ucontext.h: - -/usr/include/x86_64-linux-gnu/bits/sigthread.h: - -/usr/include/errno.h: - -/usr/include/x86_64-linux-gnu/bits/errno.h: - -/usr/include/linux/errno.h: - -/usr/include/x86_64-linux-gnu/asm/errno.h: - -/usr/include/asm-generic/errno.h: - -/usr/include/asm-generic/errno-base.h: - -/usr/include/fcntl.h: - -/usr/include/x86_64-linux-gnu/bits/fcntl.h: - -/usr/include/x86_64-linux-gnu/bits/fcntl-linux.h: - -/usr/include/x86_64-linux-gnu/bits/uio.h: - -/usr/include/x86_64-linux-gnu/bits/stat.h: - -/usr/include/unistd.h: - -/usr/include/x86_64-linux-gnu/bits/posix_opt.h: - -/usr/include/x86_64-linux-gnu/bits/environments.h: - -/usr/include/x86_64-linux-gnu/bits/confname.h: - -/usr/include/getopt.h: - -/usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdbool.h: - -/usr/include/inttypes.h: - -/usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdint.h: - -/usr/include/stdint.h: - -/usr/include/x86_64-linux-gnu/bits/wchar.h: - -/usr/include/syslog.h: - -/usr/include/x86_64-linux-gnu/sys/syslog.h: - -/usr/include/x86_64-linux-gnu/bits/syslog-path.h: - -/usr/include/x86_64-linux-gnu/sys/time.h: - -/usr/include/x86_64-linux-gnu/bits/timex.h: - -/usr/include/x86_64-linux-gnu/sys/stat.h: - -/usr/include/x86_64-linux-gnu/sys/file.h: - -/usr/include/x86_64-linux-gnu/sys/wait.h: - -/usr/include/x86_64-linux-gnu/sys/ioctl.h: - -/usr/include/x86_64-linux-gnu/bits/ioctls.h: - -/usr/include/x86_64-linux-gnu/asm/ioctls.h: - -/usr/include/asm-generic/ioctls.h: - -/usr/include/linux/ioctl.h: - -/usr/include/x86_64-linux-gnu/asm/ioctl.h: - -/usr/include/asm-generic/ioctl.h: - -/usr/include/x86_64-linux-gnu/bits/ioctl-types.h: - -/usr/include/x86_64-linux-gnu/sys/ttydefaults.h: - -/usr/include/x86_64-linux-gnu/sys/param.h: - -/usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/limits.h: - -/usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/syslimits.h: - -/usr/include/limits.h: - -/usr/include/x86_64-linux-gnu/bits/posix1_lim.h: - -/usr/include/x86_64-linux-gnu/bits/local_lim.h: - -/usr/include/linux/limits.h: - -/usr/include/x86_64-linux-gnu/bits/posix2_lim.h: - -/usr/include/x86_64-linux-gnu/bits/xopen_lim.h: - -/usr/include/x86_64-linux-gnu/bits/param.h: - -/usr/include/linux/param.h: - -/usr/include/x86_64-linux-gnu/asm/param.h: - -/usr/include/asm-generic/param.h: - -/usr/include/x86_64-linux-gnu/sys/resource.h: - -/usr/include/x86_64-linux-gnu/bits/resource.h: - -/usr/include/x86_64-linux-gnu/sys/uio.h: - -/usr/include/x86_64-linux-gnu/sys/un.h: - -/usr/include/x86_64-linux-gnu/bits/sockaddr.h: - -/usr/include/dirent.h: - -/usr/include/x86_64-linux-gnu/bits/dirent.h: - -/usr/include/netdb.h: - -/usr/include/netinet/in.h: - -/usr/include/x86_64-linux-gnu/sys/socket.h: - -/usr/include/x86_64-linux-gnu/bits/socket.h: - -/usr/include/x86_64-linux-gnu/bits/socket_type.h: - -/usr/include/x86_64-linux-gnu/asm/socket.h: - -/usr/include/asm-generic/socket.h: - -/usr/include/x86_64-linux-gnu/asm/sockios.h: - -/usr/include/asm-generic/sockios.h: - -/usr/include/x86_64-linux-gnu/bits/in.h: - -/usr/include/rpc/netdb.h: - -/usr/include/x86_64-linux-gnu/bits/netdb.h: - -/usr/include/net/if.h: - -/usr/include/netinet/in_systm.h: - -/usr/include/arpa/inet.h: - -/usr/include/netinet/ip.h: - -/usr/include/netinet/tcp.h: - -/usr/include/netinet/ip6.h: - -/usr/include/net/ethernet.h: - -/usr/include/linux/if_ether.h: - -/usr/include/linux/types.h: - -/usr/include/x86_64-linux-gnu/asm/types.h: - -/usr/include/asm-generic/types.h: - -/usr/include/asm-generic/int-ll64.h: - -/usr/include/x86_64-linux-gnu/asm/bitsperlong.h: - -/usr/include/asm-generic/bitsperlong.h: - -/usr/include/linux/posix_types.h: - -/usr/include/linux/stddef.h: - -/usr/include/x86_64-linux-gnu/asm/posix_types.h: - -/usr/include/x86_64-linux-gnu/asm/posix_types_64.h: - -/usr/include/asm-generic/posix_types.h: - -/usr/include/net/if_arp.h: - -/usr/include/netinet/ip_icmp.h: - -/usr/include/netinet/icmp6.h: - -/usr/include/netinet/if_ether.h: - -openssl/../dropin.h: - -openssl/../fake-getaddrinfo.h: - -openssl/../fake-gai-errnos.h: - -openssl/../fake-getnameinfo.h: - -/usr/include/openssl/pem.h: - -/usr/include/openssl/e_os2.h: - -/usr/include/x86_64-linux-gnu/openssl/opensslconf.h: - -/usr/include/openssl/bio.h: - -/usr/include/openssl/crypto.h: - -/usr/include/openssl/stack.h: - -/usr/include/openssl/safestack.h: - -/usr/include/openssl/opensslv.h: - -/usr/include/openssl/ossl_typ.h: - -/usr/include/openssl/symhacks.h: - -/usr/include/openssl/evp.h: - -/usr/include/openssl/objects.h: - -/usr/include/openssl/obj_mac.h: - -/usr/include/openssl/asn1.h: - -/usr/include/openssl/bn.h: - -/usr/include/openssl/x509.h: - -/usr/include/openssl/buffer.h: - -/usr/include/openssl/ec.h: - -/usr/include/openssl/ecdsa.h: - -/usr/include/openssl/ecdh.h: - -/usr/include/openssl/rsa.h: - -/usr/include/openssl/dsa.h: - -/usr/include/openssl/dh.h: - -/usr/include/openssl/sha.h: - -/usr/include/openssl/x509_vfy.h: - -/usr/include/openssl/lhash.h: - -/usr/include/openssl/pkcs7.h: - -/usr/include/openssl/pem2.h: - -/usr/include/openssl/err.h: - -openssl/../ecdsagen.h: - -openssl/../ecdsa.h: - -openssl/../utils.h: - -openssl/../xalloc.h: diff --git a/src/openssl/.deps/prf.Po b/src/openssl/.deps/prf.Po deleted file mode 100644 index aa2ae6d..0000000 --- a/src/openssl/.deps/prf.Po +++ /dev/null @@ -1,446 +0,0 @@ -openssl/prf.o: openssl/prf.c /usr/include/stdc-predef.h \ - /usr/include/x86_64-linux-gnu/bits/predefs.h openssl/../system.h \ - openssl/../../config.h openssl/../have.h /usr/include/stdio.h \ - /usr/include/features.h /usr/include/x86_64-linux-gnu/sys/cdefs.h \ - /usr/include/x86_64-linux-gnu/bits/wordsize.h \ - /usr/include/x86_64-linux-gnu/gnu/stubs.h \ - /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ - /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stddef.h \ - /usr/include/x86_64-linux-gnu/bits/types.h \ - /usr/include/x86_64-linux-gnu/bits/typesizes.h /usr/include/libio.h \ - /usr/include/_G_config.h /usr/include/wchar.h \ - /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdarg.h \ - /usr/include/x86_64-linux-gnu/bits/stdio_lim.h \ - /usr/include/x86_64-linux-gnu/bits/sys_errlist.h \ - /usr/include/x86_64-linux-gnu/bits/stdio.h /usr/include/stdlib.h \ - /usr/include/x86_64-linux-gnu/bits/waitflags.h \ - /usr/include/x86_64-linux-gnu/bits/waitstatus.h /usr/include/endian.h \ - /usr/include/x86_64-linux-gnu/bits/endian.h \ - /usr/include/x86_64-linux-gnu/bits/byteswap.h \ - /usr/include/x86_64-linux-gnu/bits/byteswap-16.h /usr/include/xlocale.h \ - /usr/include/x86_64-linux-gnu/sys/types.h /usr/include/time.h \ - /usr/include/x86_64-linux-gnu/sys/select.h \ - /usr/include/x86_64-linux-gnu/bits/select.h \ - /usr/include/x86_64-linux-gnu/bits/sigset.h \ - /usr/include/x86_64-linux-gnu/bits/time.h \ - /usr/include/x86_64-linux-gnu/sys/sysmacros.h \ - /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h /usr/include/alloca.h \ - /usr/include/x86_64-linux-gnu/bits/stdlib-float.h /usr/include/string.h \ - /usr/include/x86_64-linux-gnu/bits/string.h \ - /usr/include/x86_64-linux-gnu/bits/string2.h /usr/include/ctype.h \ - /usr/include/signal.h /usr/include/x86_64-linux-gnu/bits/signum.h \ - /usr/include/x86_64-linux-gnu/bits/siginfo.h \ - /usr/include/x86_64-linux-gnu/bits/sigaction.h \ - /usr/include/x86_64-linux-gnu/bits/sigcontext.h \ - /usr/include/x86_64-linux-gnu/bits/sigstack.h \ - /usr/include/x86_64-linux-gnu/sys/ucontext.h \ - /usr/include/x86_64-linux-gnu/bits/sigthread.h /usr/include/errno.h \ - /usr/include/x86_64-linux-gnu/bits/errno.h /usr/include/linux/errno.h \ - /usr/include/x86_64-linux-gnu/asm/errno.h \ - /usr/include/asm-generic/errno.h /usr/include/asm-generic/errno-base.h \ - /usr/include/fcntl.h /usr/include/x86_64-linux-gnu/bits/fcntl.h \ - /usr/include/x86_64-linux-gnu/bits/fcntl-linux.h \ - /usr/include/x86_64-linux-gnu/bits/uio.h \ - /usr/include/x86_64-linux-gnu/bits/stat.h /usr/include/unistd.h \ - /usr/include/x86_64-linux-gnu/bits/posix_opt.h \ - /usr/include/x86_64-linux-gnu/bits/environments.h \ - /usr/include/x86_64-linux-gnu/bits/confname.h /usr/include/getopt.h \ - /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdbool.h \ - /usr/include/inttypes.h \ - /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdint.h /usr/include/stdint.h \ - /usr/include/x86_64-linux-gnu/bits/wchar.h /usr/include/syslog.h \ - /usr/include/x86_64-linux-gnu/sys/syslog.h \ - /usr/include/x86_64-linux-gnu/bits/syslog-path.h \ - /usr/include/x86_64-linux-gnu/sys/time.h \ - /usr/include/x86_64-linux-gnu/bits/timex.h \ - /usr/include/x86_64-linux-gnu/sys/stat.h \ - /usr/include/x86_64-linux-gnu/sys/file.h \ - /usr/include/x86_64-linux-gnu/sys/wait.h \ - /usr/include/x86_64-linux-gnu/sys/ioctl.h \ - /usr/include/x86_64-linux-gnu/bits/ioctls.h \ - /usr/include/x86_64-linux-gnu/asm/ioctls.h \ - /usr/include/asm-generic/ioctls.h /usr/include/linux/ioctl.h \ - /usr/include/x86_64-linux-gnu/asm/ioctl.h \ - /usr/include/asm-generic/ioctl.h \ - /usr/include/x86_64-linux-gnu/bits/ioctl-types.h \ - /usr/include/x86_64-linux-gnu/sys/ttydefaults.h \ - /usr/include/x86_64-linux-gnu/sys/param.h \ - /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/limits.h \ - /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/syslimits.h \ - /usr/include/limits.h /usr/include/x86_64-linux-gnu/bits/posix1_lim.h \ - /usr/include/x86_64-linux-gnu/bits/local_lim.h \ - /usr/include/linux/limits.h \ - /usr/include/x86_64-linux-gnu/bits/posix2_lim.h \ - /usr/include/x86_64-linux-gnu/bits/xopen_lim.h \ - /usr/include/x86_64-linux-gnu/bits/param.h /usr/include/linux/param.h \ - /usr/include/x86_64-linux-gnu/asm/param.h \ - /usr/include/asm-generic/param.h \ - /usr/include/x86_64-linux-gnu/sys/resource.h \ - /usr/include/x86_64-linux-gnu/bits/resource.h \ - /usr/include/x86_64-linux-gnu/sys/uio.h \ - /usr/include/x86_64-linux-gnu/sys/un.h \ - /usr/include/x86_64-linux-gnu/bits/sockaddr.h /usr/include/dirent.h \ - /usr/include/x86_64-linux-gnu/bits/dirent.h /usr/include/netdb.h \ - /usr/include/netinet/in.h /usr/include/x86_64-linux-gnu/sys/socket.h \ - /usr/include/x86_64-linux-gnu/bits/socket.h \ - /usr/include/x86_64-linux-gnu/bits/socket_type.h \ - /usr/include/x86_64-linux-gnu/asm/socket.h \ - /usr/include/asm-generic/socket.h \ - /usr/include/x86_64-linux-gnu/asm/sockios.h \ - /usr/include/asm-generic/sockios.h \ - /usr/include/x86_64-linux-gnu/bits/in.h /usr/include/rpc/netdb.h \ - /usr/include/x86_64-linux-gnu/bits/netdb.h /usr/include/net/if.h \ - /usr/include/netinet/in_systm.h /usr/include/arpa/inet.h \ - /usr/include/netinet/ip.h /usr/include/netinet/tcp.h \ - /usr/include/netinet/ip6.h /usr/include/net/ethernet.h \ - /usr/include/linux/if_ether.h /usr/include/linux/types.h \ - /usr/include/x86_64-linux-gnu/asm/types.h \ - /usr/include/asm-generic/types.h /usr/include/asm-generic/int-ll64.h \ - /usr/include/x86_64-linux-gnu/asm/bitsperlong.h \ - /usr/include/asm-generic/bitsperlong.h /usr/include/linux/posix_types.h \ - /usr/include/linux/stddef.h \ - /usr/include/x86_64-linux-gnu/asm/posix_types.h \ - /usr/include/x86_64-linux-gnu/asm/posix_types_64.h \ - /usr/include/asm-generic/posix_types.h /usr/include/net/if_arp.h \ - /usr/include/netinet/ip_icmp.h /usr/include/netinet/icmp6.h \ - /usr/include/netinet/if_ether.h openssl/../dropin.h \ - openssl/../fake-getaddrinfo.h openssl/../fake-gai-errnos.h \ - openssl/../fake-getnameinfo.h /usr/include/openssl/obj_mac.h \ - openssl/digest.h /usr/include/openssl/evp.h \ - /usr/include/x86_64-linux-gnu/openssl/opensslconf.h \ - /usr/include/openssl/ossl_typ.h /usr/include/openssl/e_os2.h \ - /usr/include/openssl/symhacks.h /usr/include/openssl/bio.h \ - /usr/include/openssl/crypto.h /usr/include/openssl/stack.h \ - /usr/include/openssl/safestack.h /usr/include/openssl/opensslv.h \ - /usr/include/openssl/objects.h /usr/include/openssl/asn1.h \ - /usr/include/openssl/bn.h openssl/../digest.h openssl/../prf.h - -/usr/include/stdc-predef.h: - -/usr/include/x86_64-linux-gnu/bits/predefs.h: - -openssl/../system.h: - -openssl/../../config.h: - -openssl/../have.h: - -/usr/include/stdio.h: - -/usr/include/features.h: - -/usr/include/x86_64-linux-gnu/sys/cdefs.h: - -/usr/include/x86_64-linux-gnu/bits/wordsize.h: - -/usr/include/x86_64-linux-gnu/gnu/stubs.h: - -/usr/include/x86_64-linux-gnu/gnu/stubs-64.h: - -/usr/lib/gcc/x86_64-linux-gnu/4.8/include/stddef.h: - -/usr/include/x86_64-linux-gnu/bits/types.h: - -/usr/include/x86_64-linux-gnu/bits/typesizes.h: - -/usr/include/libio.h: - -/usr/include/_G_config.h: - -/usr/include/wchar.h: - -/usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdarg.h: - -/usr/include/x86_64-linux-gnu/bits/stdio_lim.h: - -/usr/include/x86_64-linux-gnu/bits/sys_errlist.h: - -/usr/include/x86_64-linux-gnu/bits/stdio.h: - -/usr/include/stdlib.h: - -/usr/include/x86_64-linux-gnu/bits/waitflags.h: - -/usr/include/x86_64-linux-gnu/bits/waitstatus.h: - -/usr/include/endian.h: - -/usr/include/x86_64-linux-gnu/bits/endian.h: - -/usr/include/x86_64-linux-gnu/bits/byteswap.h: - -/usr/include/x86_64-linux-gnu/bits/byteswap-16.h: - -/usr/include/xlocale.h: - -/usr/include/x86_64-linux-gnu/sys/types.h: - -/usr/include/time.h: - -/usr/include/x86_64-linux-gnu/sys/select.h: - -/usr/include/x86_64-linux-gnu/bits/select.h: - -/usr/include/x86_64-linux-gnu/bits/sigset.h: - -/usr/include/x86_64-linux-gnu/bits/time.h: - -/usr/include/x86_64-linux-gnu/sys/sysmacros.h: - -/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h: - -/usr/include/alloca.h: - -/usr/include/x86_64-linux-gnu/bits/stdlib-float.h: - -/usr/include/string.h: - -/usr/include/x86_64-linux-gnu/bits/string.h: - -/usr/include/x86_64-linux-gnu/bits/string2.h: - -/usr/include/ctype.h: - -/usr/include/signal.h: - -/usr/include/x86_64-linux-gnu/bits/signum.h: - -/usr/include/x86_64-linux-gnu/bits/siginfo.h: - -/usr/include/x86_64-linux-gnu/bits/sigaction.h: - -/usr/include/x86_64-linux-gnu/bits/sigcontext.h: - -/usr/include/x86_64-linux-gnu/bits/sigstack.h: - -/usr/include/x86_64-linux-gnu/sys/ucontext.h: - -/usr/include/x86_64-linux-gnu/bits/sigthread.h: - -/usr/include/errno.h: - -/usr/include/x86_64-linux-gnu/bits/errno.h: - -/usr/include/linux/errno.h: - -/usr/include/x86_64-linux-gnu/asm/errno.h: - -/usr/include/asm-generic/errno.h: - -/usr/include/asm-generic/errno-base.h: - -/usr/include/fcntl.h: - -/usr/include/x86_64-linux-gnu/bits/fcntl.h: - -/usr/include/x86_64-linux-gnu/bits/fcntl-linux.h: - -/usr/include/x86_64-linux-gnu/bits/uio.h: - -/usr/include/x86_64-linux-gnu/bits/stat.h: - -/usr/include/unistd.h: - -/usr/include/x86_64-linux-gnu/bits/posix_opt.h: - -/usr/include/x86_64-linux-gnu/bits/environments.h: - -/usr/include/x86_64-linux-gnu/bits/confname.h: - -/usr/include/getopt.h: - -/usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdbool.h: - -/usr/include/inttypes.h: - -/usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdint.h: - -/usr/include/stdint.h: - -/usr/include/x86_64-linux-gnu/bits/wchar.h: - -/usr/include/syslog.h: - -/usr/include/x86_64-linux-gnu/sys/syslog.h: - -/usr/include/x86_64-linux-gnu/bits/syslog-path.h: - -/usr/include/x86_64-linux-gnu/sys/time.h: - -/usr/include/x86_64-linux-gnu/bits/timex.h: - -/usr/include/x86_64-linux-gnu/sys/stat.h: - -/usr/include/x86_64-linux-gnu/sys/file.h: - -/usr/include/x86_64-linux-gnu/sys/wait.h: - -/usr/include/x86_64-linux-gnu/sys/ioctl.h: - -/usr/include/x86_64-linux-gnu/bits/ioctls.h: - -/usr/include/x86_64-linux-gnu/asm/ioctls.h: - -/usr/include/asm-generic/ioctls.h: - -/usr/include/linux/ioctl.h: - -/usr/include/x86_64-linux-gnu/asm/ioctl.h: - -/usr/include/asm-generic/ioctl.h: - -/usr/include/x86_64-linux-gnu/bits/ioctl-types.h: - -/usr/include/x86_64-linux-gnu/sys/ttydefaults.h: - -/usr/include/x86_64-linux-gnu/sys/param.h: - -/usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/limits.h: - -/usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/syslimits.h: - -/usr/include/limits.h: - -/usr/include/x86_64-linux-gnu/bits/posix1_lim.h: - -/usr/include/x86_64-linux-gnu/bits/local_lim.h: - -/usr/include/linux/limits.h: - -/usr/include/x86_64-linux-gnu/bits/posix2_lim.h: - -/usr/include/x86_64-linux-gnu/bits/xopen_lim.h: - -/usr/include/x86_64-linux-gnu/bits/param.h: - -/usr/include/linux/param.h: - -/usr/include/x86_64-linux-gnu/asm/param.h: - -/usr/include/asm-generic/param.h: - -/usr/include/x86_64-linux-gnu/sys/resource.h: - -/usr/include/x86_64-linux-gnu/bits/resource.h: - -/usr/include/x86_64-linux-gnu/sys/uio.h: - -/usr/include/x86_64-linux-gnu/sys/un.h: - -/usr/include/x86_64-linux-gnu/bits/sockaddr.h: - -/usr/include/dirent.h: - -/usr/include/x86_64-linux-gnu/bits/dirent.h: - -/usr/include/netdb.h: - -/usr/include/netinet/in.h: - -/usr/include/x86_64-linux-gnu/sys/socket.h: - -/usr/include/x86_64-linux-gnu/bits/socket.h: - -/usr/include/x86_64-linux-gnu/bits/socket_type.h: - -/usr/include/x86_64-linux-gnu/asm/socket.h: - -/usr/include/asm-generic/socket.h: - -/usr/include/x86_64-linux-gnu/asm/sockios.h: - -/usr/include/asm-generic/sockios.h: - -/usr/include/x86_64-linux-gnu/bits/in.h: - -/usr/include/rpc/netdb.h: - -/usr/include/x86_64-linux-gnu/bits/netdb.h: - -/usr/include/net/if.h: - -/usr/include/netinet/in_systm.h: - -/usr/include/arpa/inet.h: - -/usr/include/netinet/ip.h: - -/usr/include/netinet/tcp.h: - -/usr/include/netinet/ip6.h: - -/usr/include/net/ethernet.h: - -/usr/include/linux/if_ether.h: - -/usr/include/linux/types.h: - -/usr/include/x86_64-linux-gnu/asm/types.h: - -/usr/include/asm-generic/types.h: - -/usr/include/asm-generic/int-ll64.h: - -/usr/include/x86_64-linux-gnu/asm/bitsperlong.h: - -/usr/include/asm-generic/bitsperlong.h: - -/usr/include/linux/posix_types.h: - -/usr/include/linux/stddef.h: - -/usr/include/x86_64-linux-gnu/asm/posix_types.h: - -/usr/include/x86_64-linux-gnu/asm/posix_types_64.h: - -/usr/include/asm-generic/posix_types.h: - -/usr/include/net/if_arp.h: - -/usr/include/netinet/ip_icmp.h: - -/usr/include/netinet/icmp6.h: - -/usr/include/netinet/if_ether.h: - -openssl/../dropin.h: - -openssl/../fake-getaddrinfo.h: - -openssl/../fake-gai-errnos.h: - -openssl/../fake-getnameinfo.h: - -/usr/include/openssl/obj_mac.h: - -openssl/digest.h: - -/usr/include/openssl/evp.h: - -/usr/include/x86_64-linux-gnu/openssl/opensslconf.h: - -/usr/include/openssl/ossl_typ.h: - -/usr/include/openssl/e_os2.h: - -/usr/include/openssl/symhacks.h: - -/usr/include/openssl/bio.h: - -/usr/include/openssl/crypto.h: - -/usr/include/openssl/stack.h: - -/usr/include/openssl/safestack.h: - -/usr/include/openssl/opensslv.h: - -/usr/include/openssl/objects.h: - -/usr/include/openssl/asn1.h: - -/usr/include/openssl/bn.h: - -openssl/../digest.h: - -openssl/../prf.h: diff --git a/src/openssl/.deps/rsa.Po b/src/openssl/.deps/rsa.Po deleted file mode 100644 index c3ac6ac..0000000 --- a/src/openssl/.deps/rsa.Po +++ /dev/null @@ -1,482 +0,0 @@ -openssl/rsa.o: openssl/rsa.c /usr/include/stdc-predef.h \ - /usr/include/x86_64-linux-gnu/bits/predefs.h openssl/../system.h \ - openssl/../../config.h openssl/../have.h /usr/include/stdio.h \ - /usr/include/features.h /usr/include/x86_64-linux-gnu/sys/cdefs.h \ - /usr/include/x86_64-linux-gnu/bits/wordsize.h \ - /usr/include/x86_64-linux-gnu/gnu/stubs.h \ - /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ - /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stddef.h \ - /usr/include/x86_64-linux-gnu/bits/types.h \ - /usr/include/x86_64-linux-gnu/bits/typesizes.h /usr/include/libio.h \ - /usr/include/_G_config.h /usr/include/wchar.h \ - /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdarg.h \ - /usr/include/x86_64-linux-gnu/bits/stdio_lim.h \ - /usr/include/x86_64-linux-gnu/bits/sys_errlist.h \ - /usr/include/x86_64-linux-gnu/bits/stdio.h /usr/include/stdlib.h \ - /usr/include/x86_64-linux-gnu/bits/waitflags.h \ - /usr/include/x86_64-linux-gnu/bits/waitstatus.h /usr/include/endian.h \ - /usr/include/x86_64-linux-gnu/bits/endian.h \ - /usr/include/x86_64-linux-gnu/bits/byteswap.h \ - /usr/include/x86_64-linux-gnu/bits/byteswap-16.h /usr/include/xlocale.h \ - /usr/include/x86_64-linux-gnu/sys/types.h /usr/include/time.h \ - /usr/include/x86_64-linux-gnu/sys/select.h \ - /usr/include/x86_64-linux-gnu/bits/select.h \ - /usr/include/x86_64-linux-gnu/bits/sigset.h \ - /usr/include/x86_64-linux-gnu/bits/time.h \ - /usr/include/x86_64-linux-gnu/sys/sysmacros.h \ - /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h /usr/include/alloca.h \ - /usr/include/x86_64-linux-gnu/bits/stdlib-float.h /usr/include/string.h \ - /usr/include/x86_64-linux-gnu/bits/string.h \ - /usr/include/x86_64-linux-gnu/bits/string2.h /usr/include/ctype.h \ - /usr/include/signal.h /usr/include/x86_64-linux-gnu/bits/signum.h \ - /usr/include/x86_64-linux-gnu/bits/siginfo.h \ - /usr/include/x86_64-linux-gnu/bits/sigaction.h \ - /usr/include/x86_64-linux-gnu/bits/sigcontext.h \ - /usr/include/x86_64-linux-gnu/bits/sigstack.h \ - /usr/include/x86_64-linux-gnu/sys/ucontext.h \ - /usr/include/x86_64-linux-gnu/bits/sigthread.h /usr/include/errno.h \ - /usr/include/x86_64-linux-gnu/bits/errno.h /usr/include/linux/errno.h \ - /usr/include/x86_64-linux-gnu/asm/errno.h \ - /usr/include/asm-generic/errno.h /usr/include/asm-generic/errno-base.h \ - /usr/include/fcntl.h /usr/include/x86_64-linux-gnu/bits/fcntl.h \ - /usr/include/x86_64-linux-gnu/bits/fcntl-linux.h \ - /usr/include/x86_64-linux-gnu/bits/uio.h \ - /usr/include/x86_64-linux-gnu/bits/stat.h /usr/include/unistd.h \ - /usr/include/x86_64-linux-gnu/bits/posix_opt.h \ - /usr/include/x86_64-linux-gnu/bits/environments.h \ - /usr/include/x86_64-linux-gnu/bits/confname.h /usr/include/getopt.h \ - /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdbool.h \ - /usr/include/inttypes.h \ - /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdint.h /usr/include/stdint.h \ - /usr/include/x86_64-linux-gnu/bits/wchar.h /usr/include/syslog.h \ - /usr/include/x86_64-linux-gnu/sys/syslog.h \ - /usr/include/x86_64-linux-gnu/bits/syslog-path.h \ - /usr/include/x86_64-linux-gnu/sys/time.h \ - /usr/include/x86_64-linux-gnu/bits/timex.h \ - /usr/include/x86_64-linux-gnu/sys/stat.h \ - /usr/include/x86_64-linux-gnu/sys/file.h \ - /usr/include/x86_64-linux-gnu/sys/wait.h \ - /usr/include/x86_64-linux-gnu/sys/ioctl.h \ - /usr/include/x86_64-linux-gnu/bits/ioctls.h \ - /usr/include/x86_64-linux-gnu/asm/ioctls.h \ - /usr/include/asm-generic/ioctls.h /usr/include/linux/ioctl.h \ - /usr/include/x86_64-linux-gnu/asm/ioctl.h \ - /usr/include/asm-generic/ioctl.h \ - /usr/include/x86_64-linux-gnu/bits/ioctl-types.h \ - /usr/include/x86_64-linux-gnu/sys/ttydefaults.h \ - /usr/include/x86_64-linux-gnu/sys/param.h \ - /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/limits.h \ - /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/syslimits.h \ - /usr/include/limits.h /usr/include/x86_64-linux-gnu/bits/posix1_lim.h \ - /usr/include/x86_64-linux-gnu/bits/local_lim.h \ - /usr/include/linux/limits.h \ - /usr/include/x86_64-linux-gnu/bits/posix2_lim.h \ - /usr/include/x86_64-linux-gnu/bits/xopen_lim.h \ - /usr/include/x86_64-linux-gnu/bits/param.h /usr/include/linux/param.h \ - /usr/include/x86_64-linux-gnu/asm/param.h \ - /usr/include/asm-generic/param.h \ - /usr/include/x86_64-linux-gnu/sys/resource.h \ - /usr/include/x86_64-linux-gnu/bits/resource.h \ - /usr/include/x86_64-linux-gnu/sys/uio.h \ - /usr/include/x86_64-linux-gnu/sys/un.h \ - /usr/include/x86_64-linux-gnu/bits/sockaddr.h /usr/include/dirent.h \ - /usr/include/x86_64-linux-gnu/bits/dirent.h /usr/include/netdb.h \ - /usr/include/netinet/in.h /usr/include/x86_64-linux-gnu/sys/socket.h \ - /usr/include/x86_64-linux-gnu/bits/socket.h \ - /usr/include/x86_64-linux-gnu/bits/socket_type.h \ - /usr/include/x86_64-linux-gnu/asm/socket.h \ - /usr/include/asm-generic/socket.h \ - /usr/include/x86_64-linux-gnu/asm/sockios.h \ - /usr/include/asm-generic/sockios.h \ - /usr/include/x86_64-linux-gnu/bits/in.h /usr/include/rpc/netdb.h \ - /usr/include/x86_64-linux-gnu/bits/netdb.h /usr/include/net/if.h \ - /usr/include/netinet/in_systm.h /usr/include/arpa/inet.h \ - /usr/include/netinet/ip.h /usr/include/netinet/tcp.h \ - /usr/include/netinet/ip6.h /usr/include/net/ethernet.h \ - /usr/include/linux/if_ether.h /usr/include/linux/types.h \ - /usr/include/x86_64-linux-gnu/asm/types.h \ - /usr/include/asm-generic/types.h /usr/include/asm-generic/int-ll64.h \ - /usr/include/x86_64-linux-gnu/asm/bitsperlong.h \ - /usr/include/asm-generic/bitsperlong.h /usr/include/linux/posix_types.h \ - /usr/include/linux/stddef.h \ - /usr/include/x86_64-linux-gnu/asm/posix_types.h \ - /usr/include/x86_64-linux-gnu/asm/posix_types_64.h \ - /usr/include/asm-generic/posix_types.h /usr/include/net/if_arp.h \ - /usr/include/netinet/ip_icmp.h /usr/include/netinet/icmp6.h \ - /usr/include/netinet/if_ether.h openssl/../dropin.h \ - openssl/../fake-getaddrinfo.h openssl/../fake-gai-errnos.h \ - openssl/../fake-getnameinfo.h /usr/include/openssl/pem.h \ - /usr/include/openssl/e_os2.h \ - /usr/include/x86_64-linux-gnu/openssl/opensslconf.h \ - /usr/include/openssl/bio.h /usr/include/openssl/crypto.h \ - /usr/include/openssl/stack.h /usr/include/openssl/safestack.h \ - /usr/include/openssl/opensslv.h /usr/include/openssl/ossl_typ.h \ - /usr/include/openssl/symhacks.h /usr/include/openssl/evp.h \ - /usr/include/openssl/objects.h /usr/include/openssl/obj_mac.h \ - /usr/include/openssl/asn1.h /usr/include/openssl/bn.h \ - /usr/include/openssl/x509.h /usr/include/openssl/buffer.h \ - /usr/include/openssl/ec.h /usr/include/openssl/ecdsa.h \ - /usr/include/openssl/ecdh.h /usr/include/openssl/rsa.h \ - /usr/include/openssl/dsa.h /usr/include/openssl/dh.h \ - /usr/include/openssl/sha.h /usr/include/openssl/x509_vfy.h \ - /usr/include/openssl/lhash.h /usr/include/openssl/pkcs7.h \ - /usr/include/openssl/pem2.h /usr/include/openssl/err.h \ - openssl/../logger.h openssl/../rsa.h - -/usr/include/stdc-predef.h: - -/usr/include/x86_64-linux-gnu/bits/predefs.h: - -openssl/../system.h: - -openssl/../../config.h: - -openssl/../have.h: - -/usr/include/stdio.h: - -/usr/include/features.h: - -/usr/include/x86_64-linux-gnu/sys/cdefs.h: - -/usr/include/x86_64-linux-gnu/bits/wordsize.h: - -/usr/include/x86_64-linux-gnu/gnu/stubs.h: - -/usr/include/x86_64-linux-gnu/gnu/stubs-64.h: - -/usr/lib/gcc/x86_64-linux-gnu/4.8/include/stddef.h: - -/usr/include/x86_64-linux-gnu/bits/types.h: - -/usr/include/x86_64-linux-gnu/bits/typesizes.h: - -/usr/include/libio.h: - -/usr/include/_G_config.h: - -/usr/include/wchar.h: - -/usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdarg.h: - -/usr/include/x86_64-linux-gnu/bits/stdio_lim.h: - -/usr/include/x86_64-linux-gnu/bits/sys_errlist.h: - -/usr/include/x86_64-linux-gnu/bits/stdio.h: - -/usr/include/stdlib.h: - -/usr/include/x86_64-linux-gnu/bits/waitflags.h: - -/usr/include/x86_64-linux-gnu/bits/waitstatus.h: - -/usr/include/endian.h: - -/usr/include/x86_64-linux-gnu/bits/endian.h: - -/usr/include/x86_64-linux-gnu/bits/byteswap.h: - -/usr/include/x86_64-linux-gnu/bits/byteswap-16.h: - -/usr/include/xlocale.h: - -/usr/include/x86_64-linux-gnu/sys/types.h: - -/usr/include/time.h: - -/usr/include/x86_64-linux-gnu/sys/select.h: - -/usr/include/x86_64-linux-gnu/bits/select.h: - -/usr/include/x86_64-linux-gnu/bits/sigset.h: - -/usr/include/x86_64-linux-gnu/bits/time.h: - -/usr/include/x86_64-linux-gnu/sys/sysmacros.h: - -/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h: - -/usr/include/alloca.h: - -/usr/include/x86_64-linux-gnu/bits/stdlib-float.h: - -/usr/include/string.h: - -/usr/include/x86_64-linux-gnu/bits/string.h: - -/usr/include/x86_64-linux-gnu/bits/string2.h: - -/usr/include/ctype.h: - -/usr/include/signal.h: - -/usr/include/x86_64-linux-gnu/bits/signum.h: - -/usr/include/x86_64-linux-gnu/bits/siginfo.h: - -/usr/include/x86_64-linux-gnu/bits/sigaction.h: - -/usr/include/x86_64-linux-gnu/bits/sigcontext.h: - -/usr/include/x86_64-linux-gnu/bits/sigstack.h: - -/usr/include/x86_64-linux-gnu/sys/ucontext.h: - -/usr/include/x86_64-linux-gnu/bits/sigthread.h: - -/usr/include/errno.h: - -/usr/include/x86_64-linux-gnu/bits/errno.h: - -/usr/include/linux/errno.h: - -/usr/include/x86_64-linux-gnu/asm/errno.h: - -/usr/include/asm-generic/errno.h: - -/usr/include/asm-generic/errno-base.h: - -/usr/include/fcntl.h: - -/usr/include/x86_64-linux-gnu/bits/fcntl.h: - -/usr/include/x86_64-linux-gnu/bits/fcntl-linux.h: - -/usr/include/x86_64-linux-gnu/bits/uio.h: - -/usr/include/x86_64-linux-gnu/bits/stat.h: - -/usr/include/unistd.h: - -/usr/include/x86_64-linux-gnu/bits/posix_opt.h: - -/usr/include/x86_64-linux-gnu/bits/environments.h: - -/usr/include/x86_64-linux-gnu/bits/confname.h: - -/usr/include/getopt.h: - -/usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdbool.h: - -/usr/include/inttypes.h: - -/usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdint.h: - -/usr/include/stdint.h: - -/usr/include/x86_64-linux-gnu/bits/wchar.h: - -/usr/include/syslog.h: - -/usr/include/x86_64-linux-gnu/sys/syslog.h: - -/usr/include/x86_64-linux-gnu/bits/syslog-path.h: - -/usr/include/x86_64-linux-gnu/sys/time.h: - -/usr/include/x86_64-linux-gnu/bits/timex.h: - -/usr/include/x86_64-linux-gnu/sys/stat.h: - -/usr/include/x86_64-linux-gnu/sys/file.h: - -/usr/include/x86_64-linux-gnu/sys/wait.h: - -/usr/include/x86_64-linux-gnu/sys/ioctl.h: - -/usr/include/x86_64-linux-gnu/bits/ioctls.h: - -/usr/include/x86_64-linux-gnu/asm/ioctls.h: - -/usr/include/asm-generic/ioctls.h: - -/usr/include/linux/ioctl.h: - -/usr/include/x86_64-linux-gnu/asm/ioctl.h: - -/usr/include/asm-generic/ioctl.h: - -/usr/include/x86_64-linux-gnu/bits/ioctl-types.h: - -/usr/include/x86_64-linux-gnu/sys/ttydefaults.h: - -/usr/include/x86_64-linux-gnu/sys/param.h: - -/usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/limits.h: - -/usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/syslimits.h: - -/usr/include/limits.h: - -/usr/include/x86_64-linux-gnu/bits/posix1_lim.h: - -/usr/include/x86_64-linux-gnu/bits/local_lim.h: - -/usr/include/linux/limits.h: - -/usr/include/x86_64-linux-gnu/bits/posix2_lim.h: - -/usr/include/x86_64-linux-gnu/bits/xopen_lim.h: - -/usr/include/x86_64-linux-gnu/bits/param.h: - -/usr/include/linux/param.h: - -/usr/include/x86_64-linux-gnu/asm/param.h: - -/usr/include/asm-generic/param.h: - -/usr/include/x86_64-linux-gnu/sys/resource.h: - -/usr/include/x86_64-linux-gnu/bits/resource.h: - -/usr/include/x86_64-linux-gnu/sys/uio.h: - -/usr/include/x86_64-linux-gnu/sys/un.h: - -/usr/include/x86_64-linux-gnu/bits/sockaddr.h: - -/usr/include/dirent.h: - -/usr/include/x86_64-linux-gnu/bits/dirent.h: - -/usr/include/netdb.h: - -/usr/include/netinet/in.h: - -/usr/include/x86_64-linux-gnu/sys/socket.h: - -/usr/include/x86_64-linux-gnu/bits/socket.h: - -/usr/include/x86_64-linux-gnu/bits/socket_type.h: - -/usr/include/x86_64-linux-gnu/asm/socket.h: - -/usr/include/asm-generic/socket.h: - -/usr/include/x86_64-linux-gnu/asm/sockios.h: - -/usr/include/asm-generic/sockios.h: - -/usr/include/x86_64-linux-gnu/bits/in.h: - -/usr/include/rpc/netdb.h: - -/usr/include/x86_64-linux-gnu/bits/netdb.h: - -/usr/include/net/if.h: - -/usr/include/netinet/in_systm.h: - -/usr/include/arpa/inet.h: - -/usr/include/netinet/ip.h: - -/usr/include/netinet/tcp.h: - -/usr/include/netinet/ip6.h: - -/usr/include/net/ethernet.h: - -/usr/include/linux/if_ether.h: - -/usr/include/linux/types.h: - -/usr/include/x86_64-linux-gnu/asm/types.h: - -/usr/include/asm-generic/types.h: - -/usr/include/asm-generic/int-ll64.h: - -/usr/include/x86_64-linux-gnu/asm/bitsperlong.h: - -/usr/include/asm-generic/bitsperlong.h: - -/usr/include/linux/posix_types.h: - -/usr/include/linux/stddef.h: - -/usr/include/x86_64-linux-gnu/asm/posix_types.h: - -/usr/include/x86_64-linux-gnu/asm/posix_types_64.h: - -/usr/include/asm-generic/posix_types.h: - -/usr/include/net/if_arp.h: - -/usr/include/netinet/ip_icmp.h: - -/usr/include/netinet/icmp6.h: - -/usr/include/netinet/if_ether.h: - -openssl/../dropin.h: - -openssl/../fake-getaddrinfo.h: - -openssl/../fake-gai-errnos.h: - -openssl/../fake-getnameinfo.h: - -/usr/include/openssl/pem.h: - -/usr/include/openssl/e_os2.h: - -/usr/include/x86_64-linux-gnu/openssl/opensslconf.h: - -/usr/include/openssl/bio.h: - -/usr/include/openssl/crypto.h: - -/usr/include/openssl/stack.h: - -/usr/include/openssl/safestack.h: - -/usr/include/openssl/opensslv.h: - -/usr/include/openssl/ossl_typ.h: - -/usr/include/openssl/symhacks.h: - -/usr/include/openssl/evp.h: - -/usr/include/openssl/objects.h: - -/usr/include/openssl/obj_mac.h: - -/usr/include/openssl/asn1.h: - -/usr/include/openssl/bn.h: - -/usr/include/openssl/x509.h: - -/usr/include/openssl/buffer.h: - -/usr/include/openssl/ec.h: - -/usr/include/openssl/ecdsa.h: - -/usr/include/openssl/ecdh.h: - -/usr/include/openssl/rsa.h: - -/usr/include/openssl/dsa.h: - -/usr/include/openssl/dh.h: - -/usr/include/openssl/sha.h: - -/usr/include/openssl/x509_vfy.h: - -/usr/include/openssl/lhash.h: - -/usr/include/openssl/pkcs7.h: - -/usr/include/openssl/pem2.h: - -/usr/include/openssl/err.h: - -openssl/../logger.h: - -openssl/../rsa.h: diff --git a/src/openssl/.deps/rsagen.Po b/src/openssl/.deps/rsagen.Po deleted file mode 100644 index 8c50bea..0000000 --- a/src/openssl/.deps/rsagen.Po +++ /dev/null @@ -1,484 +0,0 @@ -openssl/rsagen.o: openssl/rsagen.c /usr/include/stdc-predef.h \ - /usr/include/x86_64-linux-gnu/bits/predefs.h openssl/../system.h \ - openssl/../../config.h openssl/../have.h /usr/include/stdio.h \ - /usr/include/features.h /usr/include/x86_64-linux-gnu/sys/cdefs.h \ - /usr/include/x86_64-linux-gnu/bits/wordsize.h \ - /usr/include/x86_64-linux-gnu/gnu/stubs.h \ - /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ - /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stddef.h \ - /usr/include/x86_64-linux-gnu/bits/types.h \ - /usr/include/x86_64-linux-gnu/bits/typesizes.h /usr/include/libio.h \ - /usr/include/_G_config.h /usr/include/wchar.h \ - /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdarg.h \ - /usr/include/x86_64-linux-gnu/bits/stdio_lim.h \ - /usr/include/x86_64-linux-gnu/bits/sys_errlist.h \ - /usr/include/x86_64-linux-gnu/bits/stdio.h /usr/include/stdlib.h \ - /usr/include/x86_64-linux-gnu/bits/waitflags.h \ - /usr/include/x86_64-linux-gnu/bits/waitstatus.h /usr/include/endian.h \ - /usr/include/x86_64-linux-gnu/bits/endian.h \ - /usr/include/x86_64-linux-gnu/bits/byteswap.h \ - /usr/include/x86_64-linux-gnu/bits/byteswap-16.h /usr/include/xlocale.h \ - /usr/include/x86_64-linux-gnu/sys/types.h /usr/include/time.h \ - /usr/include/x86_64-linux-gnu/sys/select.h \ - /usr/include/x86_64-linux-gnu/bits/select.h \ - /usr/include/x86_64-linux-gnu/bits/sigset.h \ - /usr/include/x86_64-linux-gnu/bits/time.h \ - /usr/include/x86_64-linux-gnu/sys/sysmacros.h \ - /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h /usr/include/alloca.h \ - /usr/include/x86_64-linux-gnu/bits/stdlib-float.h /usr/include/string.h \ - /usr/include/x86_64-linux-gnu/bits/string.h \ - /usr/include/x86_64-linux-gnu/bits/string2.h /usr/include/ctype.h \ - /usr/include/signal.h /usr/include/x86_64-linux-gnu/bits/signum.h \ - /usr/include/x86_64-linux-gnu/bits/siginfo.h \ - /usr/include/x86_64-linux-gnu/bits/sigaction.h \ - /usr/include/x86_64-linux-gnu/bits/sigcontext.h \ - /usr/include/x86_64-linux-gnu/bits/sigstack.h \ - /usr/include/x86_64-linux-gnu/sys/ucontext.h \ - /usr/include/x86_64-linux-gnu/bits/sigthread.h /usr/include/errno.h \ - /usr/include/x86_64-linux-gnu/bits/errno.h /usr/include/linux/errno.h \ - /usr/include/x86_64-linux-gnu/asm/errno.h \ - /usr/include/asm-generic/errno.h /usr/include/asm-generic/errno-base.h \ - /usr/include/fcntl.h /usr/include/x86_64-linux-gnu/bits/fcntl.h \ - /usr/include/x86_64-linux-gnu/bits/fcntl-linux.h \ - /usr/include/x86_64-linux-gnu/bits/uio.h \ - /usr/include/x86_64-linux-gnu/bits/stat.h /usr/include/unistd.h \ - /usr/include/x86_64-linux-gnu/bits/posix_opt.h \ - /usr/include/x86_64-linux-gnu/bits/environments.h \ - /usr/include/x86_64-linux-gnu/bits/confname.h /usr/include/getopt.h \ - /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdbool.h \ - /usr/include/inttypes.h \ - /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdint.h /usr/include/stdint.h \ - /usr/include/x86_64-linux-gnu/bits/wchar.h /usr/include/syslog.h \ - /usr/include/x86_64-linux-gnu/sys/syslog.h \ - /usr/include/x86_64-linux-gnu/bits/syslog-path.h \ - /usr/include/x86_64-linux-gnu/sys/time.h \ - /usr/include/x86_64-linux-gnu/bits/timex.h \ - /usr/include/x86_64-linux-gnu/sys/stat.h \ - /usr/include/x86_64-linux-gnu/sys/file.h \ - /usr/include/x86_64-linux-gnu/sys/wait.h \ - /usr/include/x86_64-linux-gnu/sys/ioctl.h \ - /usr/include/x86_64-linux-gnu/bits/ioctls.h \ - /usr/include/x86_64-linux-gnu/asm/ioctls.h \ - /usr/include/asm-generic/ioctls.h /usr/include/linux/ioctl.h \ - /usr/include/x86_64-linux-gnu/asm/ioctl.h \ - /usr/include/asm-generic/ioctl.h \ - /usr/include/x86_64-linux-gnu/bits/ioctl-types.h \ - /usr/include/x86_64-linux-gnu/sys/ttydefaults.h \ - /usr/include/x86_64-linux-gnu/sys/param.h \ - /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/limits.h \ - /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/syslimits.h \ - /usr/include/limits.h /usr/include/x86_64-linux-gnu/bits/posix1_lim.h \ - /usr/include/x86_64-linux-gnu/bits/local_lim.h \ - /usr/include/linux/limits.h \ - /usr/include/x86_64-linux-gnu/bits/posix2_lim.h \ - /usr/include/x86_64-linux-gnu/bits/xopen_lim.h \ - /usr/include/x86_64-linux-gnu/bits/param.h /usr/include/linux/param.h \ - /usr/include/x86_64-linux-gnu/asm/param.h \ - /usr/include/asm-generic/param.h \ - /usr/include/x86_64-linux-gnu/sys/resource.h \ - /usr/include/x86_64-linux-gnu/bits/resource.h \ - /usr/include/x86_64-linux-gnu/sys/uio.h \ - /usr/include/x86_64-linux-gnu/sys/un.h \ - /usr/include/x86_64-linux-gnu/bits/sockaddr.h /usr/include/dirent.h \ - /usr/include/x86_64-linux-gnu/bits/dirent.h /usr/include/netdb.h \ - /usr/include/netinet/in.h /usr/include/x86_64-linux-gnu/sys/socket.h \ - /usr/include/x86_64-linux-gnu/bits/socket.h \ - /usr/include/x86_64-linux-gnu/bits/socket_type.h \ - /usr/include/x86_64-linux-gnu/asm/socket.h \ - /usr/include/asm-generic/socket.h \ - /usr/include/x86_64-linux-gnu/asm/sockios.h \ - /usr/include/asm-generic/sockios.h \ - /usr/include/x86_64-linux-gnu/bits/in.h /usr/include/rpc/netdb.h \ - /usr/include/x86_64-linux-gnu/bits/netdb.h /usr/include/net/if.h \ - /usr/include/netinet/in_systm.h /usr/include/arpa/inet.h \ - /usr/include/netinet/ip.h /usr/include/netinet/tcp.h \ - /usr/include/netinet/ip6.h /usr/include/net/ethernet.h \ - /usr/include/linux/if_ether.h /usr/include/linux/types.h \ - /usr/include/x86_64-linux-gnu/asm/types.h \ - /usr/include/asm-generic/types.h /usr/include/asm-generic/int-ll64.h \ - /usr/include/x86_64-linux-gnu/asm/bitsperlong.h \ - /usr/include/asm-generic/bitsperlong.h /usr/include/linux/posix_types.h \ - /usr/include/linux/stddef.h \ - /usr/include/x86_64-linux-gnu/asm/posix_types.h \ - /usr/include/x86_64-linux-gnu/asm/posix_types_64.h \ - /usr/include/asm-generic/posix_types.h /usr/include/net/if_arp.h \ - /usr/include/netinet/ip_icmp.h /usr/include/netinet/icmp6.h \ - /usr/include/netinet/if_ether.h openssl/../dropin.h \ - openssl/../fake-getaddrinfo.h openssl/../fake-gai-errnos.h \ - openssl/../fake-getnameinfo.h /usr/include/openssl/pem.h \ - /usr/include/openssl/e_os2.h \ - /usr/include/x86_64-linux-gnu/openssl/opensslconf.h \ - /usr/include/openssl/bio.h /usr/include/openssl/crypto.h \ - /usr/include/openssl/stack.h /usr/include/openssl/safestack.h \ - /usr/include/openssl/opensslv.h /usr/include/openssl/ossl_typ.h \ - /usr/include/openssl/symhacks.h /usr/include/openssl/evp.h \ - /usr/include/openssl/objects.h /usr/include/openssl/obj_mac.h \ - /usr/include/openssl/asn1.h /usr/include/openssl/bn.h \ - /usr/include/openssl/x509.h /usr/include/openssl/buffer.h \ - /usr/include/openssl/ec.h /usr/include/openssl/ecdsa.h \ - /usr/include/openssl/ecdh.h /usr/include/openssl/rsa.h \ - /usr/include/openssl/dsa.h /usr/include/openssl/dh.h \ - /usr/include/openssl/sha.h /usr/include/openssl/x509_vfy.h \ - /usr/include/openssl/lhash.h /usr/include/openssl/pkcs7.h \ - /usr/include/openssl/pem2.h /usr/include/openssl/err.h \ - openssl/../logger.h openssl/../rsagen.h openssl/../rsa.h - -/usr/include/stdc-predef.h: - -/usr/include/x86_64-linux-gnu/bits/predefs.h: - -openssl/../system.h: - -openssl/../../config.h: - -openssl/../have.h: - -/usr/include/stdio.h: - -/usr/include/features.h: - -/usr/include/x86_64-linux-gnu/sys/cdefs.h: - -/usr/include/x86_64-linux-gnu/bits/wordsize.h: - -/usr/include/x86_64-linux-gnu/gnu/stubs.h: - -/usr/include/x86_64-linux-gnu/gnu/stubs-64.h: - -/usr/lib/gcc/x86_64-linux-gnu/4.8/include/stddef.h: - -/usr/include/x86_64-linux-gnu/bits/types.h: - -/usr/include/x86_64-linux-gnu/bits/typesizes.h: - -/usr/include/libio.h: - -/usr/include/_G_config.h: - -/usr/include/wchar.h: - -/usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdarg.h: - -/usr/include/x86_64-linux-gnu/bits/stdio_lim.h: - -/usr/include/x86_64-linux-gnu/bits/sys_errlist.h: - -/usr/include/x86_64-linux-gnu/bits/stdio.h: - -/usr/include/stdlib.h: - -/usr/include/x86_64-linux-gnu/bits/waitflags.h: - -/usr/include/x86_64-linux-gnu/bits/waitstatus.h: - -/usr/include/endian.h: - -/usr/include/x86_64-linux-gnu/bits/endian.h: - -/usr/include/x86_64-linux-gnu/bits/byteswap.h: - -/usr/include/x86_64-linux-gnu/bits/byteswap-16.h: - -/usr/include/xlocale.h: - -/usr/include/x86_64-linux-gnu/sys/types.h: - -/usr/include/time.h: - -/usr/include/x86_64-linux-gnu/sys/select.h: - -/usr/include/x86_64-linux-gnu/bits/select.h: - -/usr/include/x86_64-linux-gnu/bits/sigset.h: - -/usr/include/x86_64-linux-gnu/bits/time.h: - -/usr/include/x86_64-linux-gnu/sys/sysmacros.h: - -/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h: - -/usr/include/alloca.h: - -/usr/include/x86_64-linux-gnu/bits/stdlib-float.h: - -/usr/include/string.h: - -/usr/include/x86_64-linux-gnu/bits/string.h: - -/usr/include/x86_64-linux-gnu/bits/string2.h: - -/usr/include/ctype.h: - -/usr/include/signal.h: - -/usr/include/x86_64-linux-gnu/bits/signum.h: - -/usr/include/x86_64-linux-gnu/bits/siginfo.h: - -/usr/include/x86_64-linux-gnu/bits/sigaction.h: - -/usr/include/x86_64-linux-gnu/bits/sigcontext.h: - -/usr/include/x86_64-linux-gnu/bits/sigstack.h: - -/usr/include/x86_64-linux-gnu/sys/ucontext.h: - -/usr/include/x86_64-linux-gnu/bits/sigthread.h: - -/usr/include/errno.h: - -/usr/include/x86_64-linux-gnu/bits/errno.h: - -/usr/include/linux/errno.h: - -/usr/include/x86_64-linux-gnu/asm/errno.h: - -/usr/include/asm-generic/errno.h: - -/usr/include/asm-generic/errno-base.h: - -/usr/include/fcntl.h: - -/usr/include/x86_64-linux-gnu/bits/fcntl.h: - -/usr/include/x86_64-linux-gnu/bits/fcntl-linux.h: - -/usr/include/x86_64-linux-gnu/bits/uio.h: - -/usr/include/x86_64-linux-gnu/bits/stat.h: - -/usr/include/unistd.h: - -/usr/include/x86_64-linux-gnu/bits/posix_opt.h: - -/usr/include/x86_64-linux-gnu/bits/environments.h: - -/usr/include/x86_64-linux-gnu/bits/confname.h: - -/usr/include/getopt.h: - -/usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdbool.h: - -/usr/include/inttypes.h: - -/usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdint.h: - -/usr/include/stdint.h: - -/usr/include/x86_64-linux-gnu/bits/wchar.h: - -/usr/include/syslog.h: - -/usr/include/x86_64-linux-gnu/sys/syslog.h: - -/usr/include/x86_64-linux-gnu/bits/syslog-path.h: - -/usr/include/x86_64-linux-gnu/sys/time.h: - -/usr/include/x86_64-linux-gnu/bits/timex.h: - -/usr/include/x86_64-linux-gnu/sys/stat.h: - -/usr/include/x86_64-linux-gnu/sys/file.h: - -/usr/include/x86_64-linux-gnu/sys/wait.h: - -/usr/include/x86_64-linux-gnu/sys/ioctl.h: - -/usr/include/x86_64-linux-gnu/bits/ioctls.h: - -/usr/include/x86_64-linux-gnu/asm/ioctls.h: - -/usr/include/asm-generic/ioctls.h: - -/usr/include/linux/ioctl.h: - -/usr/include/x86_64-linux-gnu/asm/ioctl.h: - -/usr/include/asm-generic/ioctl.h: - -/usr/include/x86_64-linux-gnu/bits/ioctl-types.h: - -/usr/include/x86_64-linux-gnu/sys/ttydefaults.h: - -/usr/include/x86_64-linux-gnu/sys/param.h: - -/usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/limits.h: - -/usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/syslimits.h: - -/usr/include/limits.h: - -/usr/include/x86_64-linux-gnu/bits/posix1_lim.h: - -/usr/include/x86_64-linux-gnu/bits/local_lim.h: - -/usr/include/linux/limits.h: - -/usr/include/x86_64-linux-gnu/bits/posix2_lim.h: - -/usr/include/x86_64-linux-gnu/bits/xopen_lim.h: - -/usr/include/x86_64-linux-gnu/bits/param.h: - -/usr/include/linux/param.h: - -/usr/include/x86_64-linux-gnu/asm/param.h: - -/usr/include/asm-generic/param.h: - -/usr/include/x86_64-linux-gnu/sys/resource.h: - -/usr/include/x86_64-linux-gnu/bits/resource.h: - -/usr/include/x86_64-linux-gnu/sys/uio.h: - -/usr/include/x86_64-linux-gnu/sys/un.h: - -/usr/include/x86_64-linux-gnu/bits/sockaddr.h: - -/usr/include/dirent.h: - -/usr/include/x86_64-linux-gnu/bits/dirent.h: - -/usr/include/netdb.h: - -/usr/include/netinet/in.h: - -/usr/include/x86_64-linux-gnu/sys/socket.h: - -/usr/include/x86_64-linux-gnu/bits/socket.h: - -/usr/include/x86_64-linux-gnu/bits/socket_type.h: - -/usr/include/x86_64-linux-gnu/asm/socket.h: - -/usr/include/asm-generic/socket.h: - -/usr/include/x86_64-linux-gnu/asm/sockios.h: - -/usr/include/asm-generic/sockios.h: - -/usr/include/x86_64-linux-gnu/bits/in.h: - -/usr/include/rpc/netdb.h: - -/usr/include/x86_64-linux-gnu/bits/netdb.h: - -/usr/include/net/if.h: - -/usr/include/netinet/in_systm.h: - -/usr/include/arpa/inet.h: - -/usr/include/netinet/ip.h: - -/usr/include/netinet/tcp.h: - -/usr/include/netinet/ip6.h: - -/usr/include/net/ethernet.h: - -/usr/include/linux/if_ether.h: - -/usr/include/linux/types.h: - -/usr/include/x86_64-linux-gnu/asm/types.h: - -/usr/include/asm-generic/types.h: - -/usr/include/asm-generic/int-ll64.h: - -/usr/include/x86_64-linux-gnu/asm/bitsperlong.h: - -/usr/include/asm-generic/bitsperlong.h: - -/usr/include/linux/posix_types.h: - -/usr/include/linux/stddef.h: - -/usr/include/x86_64-linux-gnu/asm/posix_types.h: - -/usr/include/x86_64-linux-gnu/asm/posix_types_64.h: - -/usr/include/asm-generic/posix_types.h: - -/usr/include/net/if_arp.h: - -/usr/include/netinet/ip_icmp.h: - -/usr/include/netinet/icmp6.h: - -/usr/include/netinet/if_ether.h: - -openssl/../dropin.h: - -openssl/../fake-getaddrinfo.h: - -openssl/../fake-gai-errnos.h: - -openssl/../fake-getnameinfo.h: - -/usr/include/openssl/pem.h: - -/usr/include/openssl/e_os2.h: - -/usr/include/x86_64-linux-gnu/openssl/opensslconf.h: - -/usr/include/openssl/bio.h: - -/usr/include/openssl/crypto.h: - -/usr/include/openssl/stack.h: - -/usr/include/openssl/safestack.h: - -/usr/include/openssl/opensslv.h: - -/usr/include/openssl/ossl_typ.h: - -/usr/include/openssl/symhacks.h: - -/usr/include/openssl/evp.h: - -/usr/include/openssl/objects.h: - -/usr/include/openssl/obj_mac.h: - -/usr/include/openssl/asn1.h: - -/usr/include/openssl/bn.h: - -/usr/include/openssl/x509.h: - -/usr/include/openssl/buffer.h: - -/usr/include/openssl/ec.h: - -/usr/include/openssl/ecdsa.h: - -/usr/include/openssl/ecdh.h: - -/usr/include/openssl/rsa.h: - -/usr/include/openssl/dsa.h: - -/usr/include/openssl/dh.h: - -/usr/include/openssl/sha.h: - -/usr/include/openssl/x509_vfy.h: - -/usr/include/openssl/lhash.h: - -/usr/include/openssl/pkcs7.h: - -/usr/include/openssl/pem2.h: - -/usr/include/openssl/err.h: - -openssl/../logger.h: - -openssl/../rsagen.h: - -openssl/../rsa.h: diff --git a/src/openssl/.dirstamp b/src/openssl/.dirstamp deleted file mode 100644 index e69de29..0000000 diff --git a/src/openssl/cipher.c b/src/openssl/cipher.c index c0307f8..5d9bebc 100644 --- a/src/openssl/cipher.c +++ b/src/openssl/cipher.c @@ -171,7 +171,7 @@ bool cipher_counter_xor(cipher_t *cipher, const void *indata, size_t inlen, void break; } - *out++ = *in++ ^ cipher->counter->counter[cipher->counter->n++]; + *out++ = *in++ ^ cipher->counter->block[cipher->counter->n++]; if(cipher->counter->n >= cipher->cipher->block_size) cipher->counter->n = 0; diff --git a/src/openssl/cipher.o b/src/openssl/cipher.o deleted file mode 100644 index 3831ed895510e40ece69c075d6eba9fa7ed5f629..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 32864 zcmd^od3;nw)^^?QEDeDq5X2xV9d^_#%_bmd77{ubLY59DY)#VXB(0$nIvoUe1=I|p z;Hcv$0-~e1j-#W4qcgJTC_1?B&Zy%zIxnLB)Ny-Xb@)g4)TX8 zJ@Mt`JumntJ-uMk-UU5Rl}~!gziCjW@5OR!k7MCK^x-1#Ta@>_D6Q{X(DQuX)(`JM z|7!gkFWUuti226Cq)qnJ>hq`a|FNC%xu(YZI_>9ZtrRXkPe9DfFTyW3^qs zBH0*q)iuXjq{Uc`n~5p3O1fp@$G(4juQONUb3ucY0)xB zHMJjbU^cDF^lu7`1@GUP3lk|FhdvimJwO}wTmX^%IXZNa%jzzGJ>$5R%@xYUiqM{t zjEAOLn=Y^l*B>dle74n{0n>oqtlMMFoR@UrtJ+`=O+IpjHl80@80axZTKeqUqbG=T z(YNQ&1hD0-&!R;Odj3>YSKjkVQ2>Go>2i?LB(rq=fp`_>&H>+xzOQJ6-4`f3Kki2+ z`%$!9+fR#no~O8d=I>ES1!22u!G^EmkZE(r4l3_Sfk9+amf<)O+GAr+Y0rOE^!yFl zL-fh7jP=bhE`KOK*2D9{NelbS`gu@^ecZZn?pTi-y76BR9UZ=Q^Z)PT$3>sTdlJk< z>P7*%UI^zQIKaM7`@Pz;pgv<`=7twDuEpAmAX$-D7dnlkt$0lpKl1p@Gz-iKHtcP@%+4D3Y~gPm1SSR4r*h z8hbtYtK)zvyGj1K32I6H?kW@&{yoZ>O8yth*-AcwvUdP{h-6`*GEpg(R0@>hlFAIF zxTR94lw_&+m69TrDy5`KrCuomtU7RUg;LV2C7`q^Ww3=FcPeFwRN_j>vO1w=jZ%)b z%0RhDDcM#4luMK{!fFI->y&bwwF;EWl``Hs7igQ6l5cGS<$9$QNM(mod{Wt^l*v-L zPbpKZTxhdfDbu8Hdz5mrbvE?#xEKiaBKbx+5825#;~-UBccMu0EjV17hufO~&J-!0 zv4Ev`wt|+16N+vRx)cONaXKY>8KYT%ZUSX6a#K7_@JZ=HiIL*D8>-XcAJi}04M*iu z>L*`vBnW=9WmgDb&j~m z5zlbMdPi(<#3hcn)Df3C;&Mj}qWj9TbAJU_*%|0$y(iyV3QILJ8fg|DpPVlt=gTu$ zDoIM2A{CEPrb=ayQl?qBax;}O-P#5*%vQ<_Yab|HrOdKk17)I8PLT!*lrr1;8fs=J zWsXz|m2#>z5~A%_%4ssos%Qk~wSv=f1iL&pS|`I~DAr9@4o;9#wpnqoOipi?eUhI$ zq%thCBeGg}c3LMvo9s-KZ;|rE%%<)Z;knhC4HYvoqunco=U1{xy|R3}bY_K8cFCGH zrQ9LI(W#U>C2fsT?vk{NlybLJ)+^;6+0W%Pw7ZI7G(&K5Qaq=@r`sd9(i9IatQ5}* zs2z+r3=IOB`qFLyhIU0o>MNM~VrV;yo}oCYsjuR^t8FaxHI#>8ghcA=i=m;~(o)|* z+^ZZ&eKQOdS(0;t^&H63nPHyPL9RDp3q7hc9uuj9UAXZLm#lQxRgh0g&X61>XS&`6 zzLJNyKCtDXu8(Xv%k{Y}4|9EE%SXBXWy`}|cnVNSzARh%MNs*eP`9E5d$GBzz2jagThMMBRpr?55fq9AV?-IP{qXkEL$=$&46<& zb8y{C4uDTF_!)!QC_xQ+n&SB@*W=yt% z24(%zl88(DbW1r&ekRM$6!|$&^*q)Zi)K|1<8aR)c|6LQL!-i)fCKfyAhE}h*r9bo zF0`@m<5;Dmo5xA5(d-=GNBGpuQ4iULC+cEf%K%GZ$mA zTjo>WSyBL`e>)KNfWLzQi#&AMnoo|~(Xh5Y4Yt)nn9oDB^UDM0klR(?2_ZZl@O(Cf z3OMKfr&Wh*8H!bl3z5qh60EKN4W{=OtyRuVv;KyBONTy_5^b;>8au!d{_G zXvnrTHRLndxIF+Iatv(iLw4NjHP-7Swbxi5Qx^IhtG$|VtTLoL)HUo4x*R6It*vX| zgsmoQ4G)#n+hm+z_mM+g!$Y+Pa~Jeb1g&9X!#RV_;82}7EoaL5x;|aC7lqtkz37p( zL3i>2+sR*KvXdLwNtJUOcs^9bFKwbGy-x$1vcZO2-D7`Xbq@fN-2TTp)1tP2d)PRK zg_4G+0M1(1Y7pxoEA3HXcxzxt z_#(o(gXh4>gr^`B5vYc=S0RJ;KM zT#W21I#=dlwQGwXFD}l*oOGS9ont=-KHCLW1x@cn7`~d`eKfsxOtA-C5t!fDLfQSH z)UE(yc(L2u(zvd9!#8=gNYM!FmYlICQi)3#EG%{k`vQ2j0gW* z!o-l~Obl+RrvjM+_(Kyj6dof+buI_6pNW|be737i%wF3!dHW0T|6feZ`_i9(cVgbN z*E39vywr!IwRILuOaac7^&VY7c%^nopGW6!VULS(1nqPhF9xYRZ=Gb=h?05SlnqtwJiRDAT?jC zz2Oj9d^>?iihbBf(v5TkS6O`2h8D5;eKu6ZBAf3c%y?eG!Ui?l52+fQFVoK-FvP9o z)R^u1oG*^n{dRvR7BLNaY!84K}fs#l<#MXOE18 z%~W;2Lt*h_f|PmIzHo>vewRS(uZL}R!vKrilO<|c~c}P`-Bp)}C-0{tt=V&=S>Vcj|8eaEfuM8raWS#J>e&QBh>=8i&Z@)&!zz zqQu)3&Vui`-hx8*5)XL>Ae+BK~*})qV9)y`6jb-0q>8MZJgK zGm=Te%eRMF$6}ie)v|adK`KP7ZFPt&Zc8Atw%;L|BV|8Mv?&1=*&o<5Sd7@LMJ%#2 zDv+$*6C7AhMR9qB`qiw`D&XY+C^qx7g59 z7P)7Ye5~DT69X*1U_(n;WM@=c)*RP*%?G=7hHa~w#h=^IG8WkxG+(`)wOux`n#GrF zXc>#_jB3l85Qr47}xcpX7#t8P1M&pJdFUrivgmM>pxk*5x4 zj7nlZ8f;qu7Pr{YQWm*q^dn&Vaj#7bu=s)vEoG6NQEgdsTCEJj(?;hUrn3+t)R<{BXo4rwwX*vlV3%66CK~BV?HH@$=^ZskJIrfIv%8>$*&?i zO?1SUNwIL2Db4xZLG_Q*@hLhUq@%-B(pQj-E-?+FX<6T<4~9<*Ba3=RXE@r`)h_6m zpO+`{ySrlf?UAPZ)=(&a&5Y^6=~HvtBhl_PxvkOe{Hb{}@*~kudv|kKF-hsoY>LFY z5-15uKKCrt_dN1K=+BzQ_V$iYUK=i-u6T2ExCLaG&G_2Ra2JR$Vc=P$14M{r2Y4QY zD$ro$ja^ZnlESMABGYV++ks`UqHMHxw6=z0AVZHGO=pHfaqI`og=2`yhz?MT8A9gv zSz8)TnUmylugrTNj+T31UblPDC3C*@G$1%1kP$8G4oFH!qYS@f&M!Tu10{r%G4WOq z7uSP0ej7@&(Wo*u@)7`+Yy)kA$D4JEcaE>&kvXHbug?;$BrBypOr~g!rz1ZPvP+%z^*;FEp`w7 zyXR_mho{~>bhbMhcORA4;EsCoWbKEqxpIeiUT_aVd!6&$nR)IIb~ws2)U$oDJKf`T zjT=^;?_T4{^R&`XdfeyCU+!K7$N|qIgt;?5|9AOzWMaNHmOYQSEXea>^1EUo5$tN~h{f@BdSyD;7>Y+$hehe4 zs$fZZmA|wmSQ4lYhT6l8(e6%BR9oo_2B!OJ12yH9^JIbx{63PvZz;hylj71fFc)lU z>-Ve$OZl7MK5g~PN&WHaQep*F3>FKH>yZTGt(t^?kLscNM$VMl~$J46jkuBTHxDU(GF*R!qH|Ggdj|S@_VlOE>@Wg zO|YfCv9-$%8q!yWSB5&*D(iKX<%>#dYHj;C?o#zNFV#L4?&@xjLuPbC^hB_uy%|#n z-<0PgytXI@A-ydw4+P28NEC+_gs?UHDA7t5R#rmD$`@AFib&%$nhY6Sl3T-3n1OcE zRyVeHhdFOBuJ{Ts&g{y@*jeEiZiSGBO|UhdB@!Yhp&;fb4Kq+SgWQ7mvYH#?jS4TX z43y3*t$_@Shhe)@6Omwvk`{O6VAI;5oKRXdMJ1<~2BbS@$0G5tTq^VxIc2@HvTgy) zU7&QX(gO`urLZ2fwE%GphSXQ_gfuN(lPkvCmm8t>4oG^8Kv(1Huv!A$QCLo~E<0#l z;Z@z>h8?%KeG*e+fip@_M$8-<#&%@~oWJBumKRN6ciD?7ENOc}2?Z)$=3Y*L*sED4m_X{l0UWn85)I4U5zo(T1LqpoN=vL`Wf0~|bcEsn>5D++ zd$6;kOLRoTkOr{IRH}E$(|Aywi7^1=7$r||O-D=wi#s~nopm607$<6S7soXucXAb& zMMV{LrD(0Ovok1DkCRc&U~K@u6)w~sGFb#y%RQ7AzBX}nozNOa8egLp-I{ac1&ivX z3U=~9k+U_c_+Yp3={_1h#JV-!CZx}5BU!kxqO_=z$0?mtP6cX;%F4=1xQ0D$g2BTn zM5x7s+h=1FoOqNAw2784E}bjWFc=N5f!N|mrcZ?_42HU6un^n3SHhIXW9`lo!_3e& zDD)a9(mWwhyh@5{8iD~ooVjXc5>sMQc;sFPVZ<$QiaJbHhiN<-N)iF*7ToM6!`Hgh zm6!;2M{$RrOiQS8q3lNahG~YLsmLv;qJ%1jixLnTjd2?6B zyQASba%YKzKy8eL+UCHub?)@3-rQDi?!w95T-bi*z!mn)nc8}lCv_*cgEH}G{4%Lw zcWIeHUW$1oC9}K}=Z2dijZxKe?uPh0vjHed_ne-lxPIcwmmM5#S-RI%Y?J4vNxO04mf+Fh&Q15m zfI3&&EdsmP{|@9pIRQVQYMpEGz;w_2H0WBuOVDBu;!wt@gTVJ@UM5+7>j2ug>Y)kr zjdh<=-BvteT|3nI(_~+R@FoaK7(c+TbuQQGP>ZgJsqpV4s+YIT((ek2#|7Ybne=;J zS_I@0DVIP)ct=(=Q#<*}b#Z#;CRcHK_7(1;bnm4}Md=gQCC^JQbj1gzPXq)a42c2{IPM))2Rd+ zapTI93o);$t4rj?I#5A6TycYnB(-oO(UuON%0=AR)D#P^W(`hU2~4=Kjkbotm?E>L z*@7G0FjqrYA}`dja%C7c**y5cfN&lxYFMYRb&%O`8=U6w+V_83ykG#QS>A7I#tKO` zA01&#^@6dcrx`jd?!$?O;wQuK_NwfMA57sI!7?8HVgGQiolqX2XSN9-D3p>mjE}s~ z=6~AWM>Z$h7L~yL-)-RBKOak}y+IQ}8fXK&C69b$bZgr z^nWn?GyT5_F!afc(~(mEgz_;rP^#@ek7F0$eYO8+u4-@`wc`V~-}xTtv>{qi@{%%>MB!x_$M(t46i=7~?nlSFGNj$V(ER$y20R>$bBX zvBuq}C+J^a5k@>Y(Ew@gUS|VU0k1#y!>2DQ8?|orOC$!0{SNAdA>fuPq<58DeOWBX@^YJ7Ph51kQ!+*0M{4m?0>nFYz#+N@a zK2?PCe9^rpJhRenRP6_G_ynTY<5s%s#X9ZzGCf1aKWfl}0n;En{?hKc6KeGbKWLX8 zE)hpPlr#F{TVwfjn265(F#&wHk8SCxtNjcMp1C_uYkEC_#}>v@uSA>9VWXi0OBAN8oadVb=k5!7>IGQxNLn!jW~LlRo>V_q^qe=Wd$5DP97Jg0sK zKQxCW2SF%^?iJPSkO=1pG;VX zSP<9!8KvR6{aG50YnknrX*fQ=VEoq_K1##)X}DLz|E%FT8vX*|93LOlVR=vE>+$(a z!$$*;{h5LTg@Om&pE3>iLLKv~G+g&b{&E@cOn+K5zV6Q!4Ii!9e^SH8Y4|6Ev;757 zhvhqsuiLli{D9T^eBqA~VL@CU?_v$t`(35sUTDK{I9J21sQL4jhU=ft_E9JzSa1;pBc1SFn_tCi;;w*KRTa( z2EdGSNaK5<4aak(hUlc|GDDiv_#KzPU^y0r~hGl}jE8Y^RKLy1lmTXH&n$ z2LCOZ*Kz~r_uZ=u{3UYg3CH*{=7v2Yd83O-MPxZNfqZAcnSr($H1G(e?C8Q zzt>a0ct3!JasCN{I}~i=ACmtM8h8%rdkuUq@edmKd!)Z%;15wgyl>#A)4Y6c;3+gN zzD{QUA0-|?V`rStPb0`L#`%@4@diGe{F!3lITYtY1HY5}SzzF&kw1$K9IyAWv>JFG z%?sXdU|~OJP+nbZ;Q0G|Sgthi>15|d1Lx~4ybr;`_K#4UA2jf})GuE@F#k-#pELNY z$)CR%`1yn%GVt|;e`Vks33pRJ+;29WKQaxRpVuC5;P_LISjHJRe-X-O;Od9ygqUOC zd_LxHV6i_pk^LJD{z@9pP6NM+@Ous1P4R!&!0|T}u{>em{7Ui*2F~mDuLk~0vVX|H z)vv7zfv@Ue;c+z*pRaQm4-jt<)iZvG=H+MuZ=*aMZQwVk?nJJEA5V5>82D`zw-N(S zB7Z6k9Dh?0OM`*8ll^7`KTLjh82EF_j5x=@4^zJz415Lc8=DRMCSH#Qo{5!|M|4jSBr3Sv9_*WbFRKm9z_%Iq5=PO>rmw!T$^O`>cUqO?HZC zKVUmglU`}yd>&k4;I~s8A_mU);S0zww*Nl)Q*YqBZ*=y9pJ(7BXgoazKA!Yz4g68^ z??wX;Qk-u#@KrRf+YNj!@$WJ49P;M@11D8HY~X9j&SM7t5ZU4VmE(3Q#qAk`UrpnB z(ZKmD1#cTT$L&J{KS<+E9iSEn_dAeyM;rJd%Ae5&&ht3cz*o??&M@#3Xk3ki<1!~# zq$BF5$ert`YlyG@zW@p+7bX8P!#?}DMZ=NbE!jfcVDyWBm&CGD<6|ti{6@pk&I?rW zkcR90$NRDWXMeAv~nvlp?YwPB<-ZKq8 z|2_I*gU|c(Mh!>*c|C46?3_ye>@x8Agg+`Zl!_oA$WdCKt zIi45OdVkyC?;!q{2A|`9M8k2s_q)o>iwUi^UafPt6O z_0w(**YjtehNFqU6aN{)ISxB$yf0~d977?myMFMGH5~2dVk0P@8}{!Z`vWsoJ@?CB znI2)_1;j5h@a2S88hAJ1OAP!%!ea)0E#aFqT+j3C3Fmp-hm}xvYJ8mc=gH2)2A}6~ zzlLLcswh5BX*kZ;G@9QRH5{SWiT|30BcI=S|C@#*e->RIe4ydT|CaLnQw>M{L&X1= zfoEeQD1+$_b?652R}(%|!?CWD@?;X>Jiq)NWtqlDJ9m?v3WI+ho!8DZ@OKD5+ratx z+LZ>*U$wtO!*L4v@4Ua&a16~Tn&0O%93lR@-J68tSkd(=^5^dwAMF&7oo@|3=R-37 zF&+xX^Z!sB25LA$oDah^9OHHtozF&SIPy6k#%MV5Q)oY(sNu-xe3-1^$iJERCu=zJ zN7J~9G#vS}X`Pp8IP!NAze>ZA{~Gb@G#q2GgYxGb!a0AIlbzcPoS)ylYT#LP{{76b z&(|RyeE9|n+vn$&lMK9-`kijzs|a6U;Fl2&UkJDDBgFaEML6eAI|c*F`5Is55BYzM z!RP$hrr~H}Cav3BG#um4`E!qkBY!XP@7HkTbN)Q4;mBV~dAwJ{kKh1I~tCB&YwdXj{IEGKhbcEDPPxR;Y$xtcz%~tJWn(5uL$oj@GLrC z|BP_7jsFU0|Ge4YKR|Z&8F(w<&l&hC!ap!@ey(fL3lQi(=Fb-Rhh-4qoIm%FKf^V? z%pdYU*Wh#hoMPbJ%DgBw?C|@dOAS8TIn%)T{i<#Q&!v6xA_M<`{Jhb?->3N8V&L1! z&VvSCkAZ^njDg=x_WxnvHxvH7fxk`m2hf8xj`KQYUW_vE3hLKq;8&2HB?kTl?GLR6 zo=5gCG4N-|&fNz7J@tFQz)LA^|1|IslqXsAhddrvGsR(!fxkia$(+o6meEz(KJ4{H z?u%k-hX?9XR(Xkln2uK%cqi#=4E$ZvZ#D1&>hEy_UqSfm2ELi_FASWW%A|Vsa|b!g n{V>kg?QI61uLJq_cbU)E1N`2CjZ;wDs2>}rc{$I(c|HDL;V{q- diff --git a/src/openssl/crypto.o b/src/openssl/crypto.o deleted file mode 100644 index cad569b86431858f562fe44a4caca3a254c82465..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8632 zcmbtYeQX@X6`#HHIcGa|{E-hIA#g?{K#A{gNP+_i7zdLWQYYl24OC&Xceg$tIqx2~ zd%=NzLZHwRpjAUr3E!v$XeERc2~i0sq$+uv8RUlJ`s zybSW)*^fnMn#}F5go&-UolL&A_3P5%ivwiw5;`>O7oB++zQlWYOipHI;cUS@n5|VE zui#IkoyvqCrd`jk6{n~QtA6EBdeX0^!znktW9P({fp&46f}}qxNjbndqpZnB^@yR0 z{bHD&@#F%4xRsPuOraJgTNRl=)zXqEc_A4{BwfVsE>VLLk3eK^iDYZ?D4-=BNN2xn z`EUhk%5GXd%26xJAKwd6@&AI{t>k}0?pN|D$muqE&>$^SyvMHvI70q zZUVO|kg^=|cAEk#tQ!g3slY1h7E-%Ufvk0ezyk_gAi<*w3`uZYfi)65r@)2QAlba2 zz&aV*D+*j>-9-JI6z$Y5S{{_^(BJYH2C3%tafmEGf#LExJe4E5TeK$6CayJkj8F#_ z6k#vCg9NZxPRV{%vwg%KA$Myo_w)NtvpP;Kw>0Pn5l?64tRw z9KCZ{Ou8SDZI895jd)dhtljZ;%7tD{WJs$H)^Tzp&sj+ zSaP7@{dUq6D)#er_wt<}U>$pqeDrDhNJBNNxrXWoq`KIzg~G~W)lrtxHrro^Wk;xiEYq0n|ij-HsF6xJzK0(lx9tp#hjte=!Q zBe?~RCF|twxLlXEX;`m-S_d8idj=*T^(dSHsfQeZG;NQ?l#3hUXTYMZ2p6fRpbv@0 z*JG{h>g$MiE$`~FdKYw4^s%KP-gR-uB^~25ck#1DN5`eqPD#rmrE6jlu@p5bXf5co z;$0mbFtP|HJL?{XNv(}xV!RKqUHhkTSk`zSEEW!k@xClIcCI3Ul5-WswkTs=mQtad zlR|VO{ofu~`oA$sbKFY}v^Ybg)2GCvqbZ=p3CeUes2GiL z2|*qs;8Nv}b(gKJH(r+7n4-mt1~T5aQO1x;$VgAi2o5rFj#OSAC7>+C>2<2(oRp$g zG+cUJip0RqXwX_yU{6B{RYf1oJzA_W)gmYvA7N0h<{Iv9X1IHf;c9Y0DMCeVO;W-` zcULD^SWREJm`Kpmvi{lCNl*Em2lgwj7X)RItp(L=xs=Nm^ZD$|@Opdw+QD+ktIZ4+ zy;^o{W;k2&^5t5=RhkUuYUWB|FiT|?$m;GyzIvz<`k6eA7(rMlxRaSFj43=+aRUP_PTHFNj~zEzQ6ay5;QyZ_;x#2o3vf8Ak^8Sbh9gLzg)2W$;rSC#n@+d z*!i;Sc(sZs__bWw6|^~(T~F-1eBuhb61cU3Z|4q$ZlIX5?-cCG66wKt;2d3( zgB1EEdeb&+5IhzcyY0C%G<$Z%DGaHK`T@F7RclqXPN+PZH3B)xSxh69WcF?wZ)G8{eC^j0XOza?Z!WylWOhbxg+NT`>`f}td1rLS}y$?En`Hj!k zUwCNC{FmCC1nvxHGV+E(5L-5HzBqmE6>hHNcxoO8htE?2Z)%IVwr<`jteI|W`N9Rs z`)D`8mt3Ed_Cn{1uI`|{D|tD6y>NoTcNj&VE#POHWEz}=nc&bg4Mk)qLsdPcrK($Y zG9lI`Q*c5@WO6|uGF2Y{>Xfjv;V?ni6x>{`Nbl{WPnJ@4a=EH|P$L@tEKP^DpCY|a zQES?kU9C@ji448h({$Al8P5;h45c1r6D=Pbxl{IJ)tPpAi2rw$CJ!{tLS9!Q-bPq9 zKSK3WBe&xmMSJp`G9?dYv_5c71;;yx`V)tBMZw7fJbfW%l@qg21F*X~fsZGA{;&2! zWDB2b=s#L?|D92iWZl26N0>A1UuV0sxYm^(zqa4a_PSlye`4W##^h={t+$;7Lq#?{ z$`gDicZm7NElBsT=YKzOrca{8{ro~bVKf?0c=OnAkXJ4ts&E!5ru`SG&E%l|EZbiY zv4v>r9wM&U_|F|shT0zEr!8a7_`gY<=@XW}(fu2Z1{65`H|u{d_pj#}{Uevm`G1%= z_|$QdC`*UD$I>O*NNnA|uAe6DX7)!GDnIf9qeS`CcDjC^?IS8ue1`2!UfXH@$0UHO zpTW4{Ikw-=SXX-d8ox?Hv-ztGD2=VGi23WKe{HYlwTC!kiljw1zqmh>sPQo4Zx%bW zkJI%4J=V&HA6=3+(&U9xZ17(YB}zy%zD8Q&CRK@unGzIGRNQzS#_e z*I!NTS=I45UjxnaOEFuW{BW|);pNXS28(|2CeAH!`Gz#(q4I`iE&{`(au zdfw&x4?O8oC_ZNnda$t3t7Np z>(TsxqUHVyTg~I#gaUo+jha6nBo*+;Va;Cxk_vbn%`|@%NGgawdIrR~0tNcmYqdVk zD=6R*v*sO;RKVj*sQDW~QUQ-|k>+(@=vVKlBnti60S|c;hE(*MuK8`e)nV)?n!gzv zClx)Pfb2r@=gFtikM2U52#6!X@ZVv4 z!r<4jpC1~0Kl5)Ge3sYuR|X&Be%~?pyBYu0;NNEd`a`P6^?lY`$o@3Xv`88JK8|OV z!JlIP7aIINb~Iw}FEamWgI~#ht~2;QGha0L0gfj$cs_QBuNeF_jPEh{P3-4EgYV*g zj~o0b;}Zsdn8)?1!Qab%eroXdGyhwIe~9__4E{;x^?Re&>sjXGTxaIDJj_{? zEpHh-A8*AUBYgDx^^XV-5#Iom1kaQ9ukRPV2ES6Ni!%-WQ_Qb6_$>1q41O2$6A@m2 zJJ6Jm@Q8CS>)*({UdIEB^*ZbL_p|;zh98&tV}>7m8&DoM^!54ZwTOP3QkBowBRqVp zaVJoGm(|F+@3#{AzR`tY-e@hO9U0RyDc&PRVe4?WB;G586kF0ux%_q&S>{x#O$ zZ1DTo|J4Tnd)D7&@Jl%E>ka-X_ERwUFK}MoVeoIT{yheN7WaFg(nQ29t^H-g7U!{_KGv7>oUv8cA z*I%bjomy_)dmn7AUa~mgc}kL}7O1o)s8WAAH7zgH;zBh}9jz)FYEy@wLXF1Mr%x79 zUjHW)N45_{QU{W!ElGu!q~6ugna^zkf>axJao~ zm9J~^*ooJ`46N2iQlCe*{WT37-~G3 zO_#DGhE2q>fwk)oY_#p!=2Fl5W{%97Ma)N_XV=WC(tkVHZc zW+e5r8P5S3QL;}XY8$^2ZoyvJ%j5`~8@s)gM({5W=>F3f{H#9GT0>KeW>UJB+>dJp zl1HN(k<>dfSGNz0y=5S>JN5y!M6+j5{F6D6o!K3wOsiU4N${KW;@$)NhP$iuYU;54Ux;$NG}tcyo6wJY!nlj7iEZ z>1+#6Yn!C16N#QgxHS=LPIkuIx!%0+v_ADCbIn+oa0K4isj3hGjQ3E&$14t zSX?UTg>)7$S_Xqz2Fyg3k&)RMPf`V~X%iW{I;p^jyCJf*%urV7R;Zpfpp6~OJT!rr zx|z)XY@t$?58nXM;9o$_H}aQ|i;R2(a(EP7RHpKv%ruIpm03m!Xl1TZf?8Q9hjOjLE*Yk>s%9@9!abrjhTvh2&XA zz90O#M*iLlBri1bKOZ7FV&sSKCD)c4`TJxx>hh97ju{m-}+X_2mCpDpa$w zM|poHMUO>xju*zlG0GV4cxobKlw42u!6M1{RiAgIxz{MprCOYO&GO1gtAN zd65}pM1%_ z=S%6S)npIJOs7>akEF}rq(eYSYjTV7HehcK-gM(uKV)y^(o+DH!|Toawkp5iFcl=y z1?hlYVFmUCI(qswW|DH7uF>GlO2b$}PZ>kQEu-{WtD^es23p&S;UPomVZ=7!x7JGR zanwsJLyY9Az!h{|jcS356xDOayD@M%mBTC@U2tzi#7eIvA%mP#xsc4R6SqgKnqVYv z&oN_U#NvZTEIxR|;>D&0<bdj98D9o;s84A(;{Dg?S{ugP3%m=?-GABG<9PDI}Dw zK&LOVHqhHl=yV_&P-41>CUh4c!E~^?*x!PtIHgzpI^t8nski+QX%c6JT1d!EZ^@U5 z|Dfqx2IzZk^J`wlHBBtH+4OWn&-wIigXlZ#(5J0`;?s99y$sEd-j8#u5$}UI8)(ie z`W%Hdua7e3Jad{Z3IsGI`%QgR##UOOH(rBw2BBcS7U=s*IqKv_uoIiZ2%@Ho=9s3& z{5=RFHbhNOr=v#pJptG;&b*;b(K;^VJS)}_>=2$}MfPf6F>_RV?my?4^9;u;R-@;s? zjbb&kwh-!Qu}`t}yxKz47&A%L7M4e+O(I_em2#&}b& zAXC!|sfCbn87&;0G02@`W>UoyXta(kAsjSR4{KM)W%@Pg{8Vl!<83lxv#{v)%JFc7 z4!IJb0LANgs>SgN6wxMPsZ=^)f>&0!(rX;IDrdEB@x)A3R(Jw=IWdP&I%ZWjY{}cUoJ^3&wusveLa+BQvZ8&5Q6h?X?;s*8 zezt)nX~|O!B3{Wwo@x^D8Xsy9QCc=bCfYqdu}MVRkA}Tm?q|I$iCGG)*xK#el4;`C zdWfYbeM+NkRcOAZphEVTw3N= zY!q>g4>gInevmEETGB+{E(>CQrcY@Qah(sX6HyGBK#P_(ziuS+bA4MYL|pAd^&*Nv zm|wA1w6yslD_p#v%(eomKmSaY>wNpm#Zq$`avkmEqRV|sqlnk~P`!vde5g^xoeY^# z6zwLTSTEwuK19#0gVR1P8c0(_JT73Uv=51hm&Qn@MbYpo8i|M^UNwj)nmkDn(bPy^ z#gAuwKN>_l!8gB7L}}Sf3ehf36GfDk4N)v6^_6{-odv0?w_d1}q zDv8Th3v)XSo|_~f2mA;&iujff)rINEk5PD zx>Cgd@S$}g+D@z-(bipDF-P@>Zpq*oFjClroNJM3Y+d>jZ1YXd1L`7|qE02m6c0Y_ z*&jXaN|~(4d77TkbdqyzA?snzWh0U^9m9S$jc1kIp^90T8)7-@3pkg3U+y5jAr@wG zUwb)Ea=w}K>o}Leck7=`px6C~~dU|?36fUC}XZ2@T)+)2vRP)Xrg;rV4Z&7ZjUlhEVa zYf2xSx27~WHuTXuwX1`h|M+oeR$$ur;3eml2e*X6!O@}Q-r5BZsz8R9^%z|Se_2Q2+WXT$=)8bOv!%Led35QbXkX_gF%^yWY}^=4szue6jWyBb zE9)BSs_K@gXl-4TeuvN&?M)_B^~#k|3SLhlYT~7$tsTvsaRmcZwX~zBJ4UlCmgp;O z@9*y`rC%?!7MGQjmG&iCRkW|8Cy{LF->3&&b;diB+BzZ8mgc^gGTx|-o$=-_8ZY|c zgTC~~`#Rg>v9>UNmSDWAs#~_Kx~ieJZdpA~geYcRwB_O`zQ0s2tEpX9EhR}6i*Js0 zw~^0kVrar2g zsTtKj-=Mfs09%?{H}&_LUPd=|HMjRE@~5pi+3ZIE7P@2It-TjZeZNQaa}gEo>1x9O z^~ES?oFiV#&#PV?t!h}MHpdd38!x7);#&c&80s(^0uYVIwj>pOfgz(Mv5xd!*r9 zUQu;kb%S=|qC{shrso=dB|~!t^F>db@E}Jx#_S{9?`z&1GZ8jr5=M$x6rY}=a9!z6 zW7DBA#5l}W(e57F@u=6-A=TR5t2QwGF`#ArumEY+(xMmBsJI-YmWE#>b@_oT~bYRwY@V=-u3qMk!yNL`cxuzVSi^L zMvD+*X56pr>FH8_O!PdZIn|m>bm?WAP@~v8wp?PCkZ~Rpsu!Q2v{NRO4J#`aFRrap%`LPC=!xFltK(wU z6D*!yPFqN{wLcMU?dj_8rb$a-(p!(-9sDsyM2*qIpBb!u}~`*n(l{{+|3=QygfEwD5XC&QWacaX~}k!#;; z;QOM%zE|X+j~Ucoq{+A}f}NG4^Frt5kefOVQ@I=m5AIKH)}kAN*Jo7k&aB>*wP;&* zpnEh0t~w{M3V9?)g^4P!EviZO>s9UwF4~rH39;xGCiE*Zwk>B-V7D+PU&Vm!cX$}L zCmbF@^q#!$;%-`|lqVA=?+_^w>uN4Z;#N?ir)Eh@U!N*T^gscfZq=lMWaf8gd}9w$ z^;~amX-UL3i-sGf&1_CI$LYt7QY@Nfi%yy`DW<0ABXv)AcZ_bACGnnQtc2DAO>eqS zve{TibYlXyfd6j_lL3T@4taypLe|`82gKS=7y~+;4oMs48c5FO_<0Z7ktY+(Po(Me z2b>POgVF;oz@D6^AWA1}{c z4E#^Rxbio2BkHTm{R*MO_5VtAjM6NV>7SF~Io0j|6@NOKS|VS(NvSash_wQq)ghE zd_QAu{i*yhXF|HFmZYBK|6S#U2J9GXw(=)GKFbQPBLtct}A|kJJ#D?C_@O6b1E3V=##E&L0eE z4eMz*{G<`^Qo;);&KoF4(q}%(tLSeyI~a%IaO~5t^AP1o@`*P=@^Jji2?t+>Sk6z^ zkHEj3`C*<~m82uxLx02Be{cl+2ZWMb!qIWqCt7~wbNTdqXFVR;rTPgKrnJB% z@>W3}?gqcQG0%AR%O-vqq#yfWYf<{GNLuB$33$tvetaMD&MnP1Zxh%fdHAGvNc3pU zpgg*=nts@4fZw06#&5)E&?(7tA%++Cg~Rl(vXEw=kP>k0HiFADA8?GV;9Vpm0mnT~ zaI8}#?9({+N%}eq;A4*x{^J&od!yh7EZnyLHsfOdIMzS3__lp{21L8yiv2k>Kaqgr zSyAvM7LGkraLjWg@a;HUVc`?0O!!Y*xE;^`vhYb3e+&#$LT0x+%fcs9nb@zg@F^C) z#KLhD6MmD0PqT3R<`PNbS!Pt#W%2EJ-fZF1i7WO8EIe%CuUPm@3;(JW2Rm*uXW);0 zca}RWaGXcC^7#^T7)kItZVz(?$;XXq{)Gj}Xr8IM1ouHC@TD#2CAd%$I}xMGV~&sa zu(3)m7yi?{|J6D;{$Uc*a+CRXA-?$|%f{z$xqe?RlCa`-p1Ki50>EXKd#;N9$xytfkjf8}<6;P4+|{TT=U z8QYi7{$l49#((SZUuXP12Y-w4Lk|8Y#)Isa*w5fN=R3Ih=Z^I6p&a}o=1+5Q`IcDb z;NstW2ba&~wGRGuwtuUG=W>7cIQTa>{*OAi+;8ytKx+u7sbuQLBW2mdG5A8~Mr{{aWTl;_V&4!(xl z{hfo$xctSzpJY4oUQqh`55_-t_^%>km12 z8^`kz2fvEv&l3**L*^fFa5*2p`V*C{aVJi%EH0F4rEFZ3kP53Posms!Rw*Q91-vA?&4mo_ef0%zUZO$$5^L4h9 znXRk&=NXCrSPKVV&eca-IQ)_EJ<-C!e~l-_6viday{0*JmV<9+yurcmWW2}1xr@5w zO2%b=KFjC^F9DMwHE2LjAE^&Cu z!0H_bf1dG=9sIY9kKu_IbA0(vDt221qD=oerD#lkcF7cH4&}!l6 z*Fx@>`A-zm&r^6mh1BoZmtUjrwCo^mzvFpwtHTeoo$oq)S?`ZnIQ-em{ygX4Uo!qn z2Vc(%{&$R{Ik+Of1$^7$V;_*`v`;J??TVc*99;I_07#U?zWj{*I0u*C63%q+mFL_Qok8xB(+#)>gjShbwx7+3LWnOKzaD@0Sj`O7!4*N2%wp%!;e`Ed*3kP53 z)h!kd>U8es*DM_Tqj=o!ws7#H%zxOyA7K1(2S3R8fQ7@p%-f$>IP7P${vziR=Vv)? zpF6nR$4mId5t@Vji5&mAjEkKQ*iN0pm-u%$_+gGi!m%UY8Bz{k?A-3)k8!(qIdXq1R{i&KE*@qA zx+zlukev4g-vE%(E|Y04%H+H{;NbcoL71Ee#g3ep%x^J71f4AIH-nr!*=AQ$g_1XLtz3cd)cp<@jI){Onf z(_jti{ywXJGTpp!bIaIAp-sn&D{g^ORZl7e&#{}Qv7lw_+2Hx$_z&Eyv@v+zsap4` z^-lkA;Ls!{Pe1%;_&vRU;83W$b?go7ln=W*TgEY(6xWd-U4$EnspaYZ9`Bl}Vgq+Y(A)8EtkCBIw_LvWn^j45LnW7gjQ zq(E`SUI-uj?mM3@dKYsljt`DwUWjHpZYLw@XnfG$)ZpJ{kA{0k!+n|Lb~_x84BP&J zNHk{mU+u3)I}VI^pk)#v{qmJZ&K~ebNE#rUt5MT1Wlik&H4Q zi$zD$(LR3zM&oac4h%%?sunvI8;->Nsi8>H?#F<2r+KZ(Elf+pBbnY9m^G?$OyRh_ zW6|Y$y`iZ>cx3Cnas}rt<6c}>lw{WR`Z5sR-YE#(mRDX}O7ajaRImUq9#26uo`woi zk|x{-qEMi+2Qf?53cQ8h+flTn0cq?_&$+pvDcyMf*bAkU|KzVRtN5QVU!wB=i}^B@ zKaY7oG!YwVp|D5^mK17~;F7{JCAg(fr-TA2v?!ra3hhdmB83e~m}+%Hh+CCVWNici z`xTtdurT5gCCrpUS_!4r2$bwp!fb052)8Jq%<2MRw-U;&2w2;rgt^uYAl#;eh1QLr zc1Q`;)NQbLUs?o&cg3J)rwRtk?O;R>q?>Ks$Tl`^(*B`mdefS(g$8k7sqJ#rk% zJm0`Zs(w9+S;~JCn@i*HKri4DQRrO&tk8QHq#_(p414;1$RNexl=RC?OMxB)VTK%h zHBo3v6nei61wQx}q9FAsT#JlFMR3Z}rqhXNPueh&A*09Q=FD}gVafUg2>OWx($4%XILwPjX^>n6x< zaCsZbtRAaIlyf*Yg0>?Z1i|rpHwbqqJ5a&Fj{|;GxwUFwVOUpW>wmhjw;f}XJDdW& zhekgw!q0H*7@<;zc~=R2TIdZy{TUv}s=*8m%ax)k)H;KSR1Ic`M~}q&?cI+Im$_^+`wu**V=)VRqZ>ySgXK_7t<*bz0RFQ=2o*kbd@gX|{*yrksfG3` za67K}K7L?f1(t&82LSjXCko$oVRu)^K;|Lw)?4_1Aw%`H$=fV;b_K!;yoHPT_%XEw z=eca0`oO!%rPP+YEL=P|$7Li$Yh1lh5ht{Y4|OVzLp3e51!#NP7F4_n6>&|fV%Zwm zp;!QISP7R(EXO%mfooYQ$|_HSC>FxMDEzurp_Z~W)2j597P);F`(|1fOeulM zeODJPFKUGwi+h16D!LZRVQ?r5Ehs1k3TE(vT2o3bx38!OD_J0VXE+v?f!b6O3tCH2 zoW}OymTOt9rC4M7JkeTO4TUonLI!R-7-n%Pn7Ia)Wr@ei8lSlc=$sisTtIffEZhS< zIT2hKuvV6zHU zB6XN@j#klSU=o{lDa0uj=$tKA&a%)ADlK%%!4!t#B>8Lwk|nx1iw}gDEU}5RHz)#6 zudw2eu=FrdP~_})auiu|o+!j7Dt9itlgSAW)DrES{Q@ajqLZ`i8KULvH?vyo?k8Eq z+1DM^&e?2GomA*tmQt=UTZ^;X9JD^)-THT_^g~ChowHeY>#5MWL?{=})?(X_XOW{$ znG(9QUq)Bx6VBe@pia&nCZtA?rI)gboP8}vk)>;JAAtm8!P$C3%AzXHe&$El#nJ6@ zoNnSQyFpuBM_5|vINiiq-D%g6tUHycORr`XIm_`VMV3NN zbelP=N4G97x+P?}!ST?}**hJyp5u5qi`b*(cwEof=?-e=>gMd{38~4$Qg2q#wDnm4sub=;TH-1ilG#xR z%O&t|(6T=E&45pNP>6D3#Ez#@F;SgKC97l6-s-`=zUrOJmV}oqu8KwDnVnUG@l5sN zz_RLSyf2pNx0NOd`I^1abSg(BN2q3Zbgd2q;8mrse<;ugt4XBN{r&bpUki~4*X(Ht$WvZdfYMZz3%B=$?o-5zqouw%=_Xx zFI4K;8|qwq(p5QoRjqsEg*|)RJG`e{m8I^BcDuKI&OIyOT~pfQ!mbXtwuO5$17SPf zF9Qkp$rC3#tWK0f(oSV!X($TgVOT0HoP(i}1RT=TCi>C>PLQBbpsA!C=@0itQnm;u z1_n|#*6be&%WA8edcuQtx+XlBOk_rctPk$+04)_w#KQxLidmis+SmiK9`=`PqjJ5rt*fPV zZL?5gD#F8&vz^lgLIz!@kW!{PBK3{xyK9M6WT z6h{)UnuZd?Hmpx*arIy(ld6V8#lEUwAXuGB_K9!`I!ng2s&!41=#9d99S--UcZy6r z1p=H|_QBDmoFx=iXIH4JyA#GSTPkCbA5JZdOa(2it3C&JLy2Tsx=h6Sc?yQXMKmtL znK*>mUn|1lkx2hy(Y&_X-{6PMBM|gg4W~14d&M9g|H5Ht71-+=S^+yv)sn^jszHBM zTdlte7V-*+|EjCdb8|;qcRPg)Q?0E-$cFUWy_rFr#c_Kle4?kIx{%*1M7TbYh$(g@ z^gjfw`WaVZq;FehL`^QaaAZIcoTc)Vmi)nbSliUl1?vI&NgBxM7gGlVeF_Siy`W~xz^HC-_hC#>jRFx;|XYYV~evx$mM`lp(1pMtc#l@cC}njwQ>!@ zl2_{xRz?DL=z3VhT^mGrdpgn^vz;;GRjyecDc&Pd(?$=)3SDT z2y17Fb@B8m-a~Ltz*kIu)s~Nq^}dn=u2x^!es{>{-{Wy@ndU1C`AV96-jU57-;XZY|gnQ1_s#$yav3-RSf0_k?_l_7pVxYFx=_zC~aydY`wcC<>%O zBh5vwNG<_$CGdZY?DJWH2&6`bq2uA2PO9q==aP0T5=i5;4fIFS5fSK3r9>c^KmpZ* zfn~X35Jaq_=6p0hkbs(U{zrOyllFF&pp$bnBgsg7&_>(Y+Hg0wSs#3f0NjU$ZCK=i zcp_~FV6DRPgVjNm?4j^L626e3=Ka4fez1T;0Jr0uR7aBe?1Fu(Cp?;g2Y|e^Ouo>= zJ2w^LDGmDJCnJ0##Dr?d;dvq_9d(`uaoIDB%tZZP_g6~e6`#6d|KkA` z$It!06_{xgkXQ;Q8JG%;aWHl9eb8iB?;82_fDn%u!I`>WoTUDHa3X-IMqQjwv;HWQ z7%rr4$yKTf*T?qb-eb1^Z-JRMvF04w_--}|4N>3;)WhoR2xy^ftaCD^O?Ar_UA>DrEzKVO? zC+Ag~2YF1m-(nv!uR;h3Io>*%hY&(Sj<+=Cn-M}nj(aQfQG}3?=65 z{{@ws@&AfA+aXcBuj%Xkb57%W|M1pg+Ao0hfQkEu@6!v2qrN^~pVc_t+PL59G_LEf z*EqhXvHpn0(I@j8HGYZ4_h?*i?>98AxA$R<>*MkWaqiDU-~-dMn!Y|C{!Qb0Jf}3S z$Mden^>{wexE{|(#5ta=GMel;q&ZJY5kNA>v5Yv6<8q}YF4y$+b_F%A$G?6O&T9wl z^RoxKm`;9>WBy~Rk9!3s<};|B^f>8o{yG3-!-Q&NLduuRPh|(6n>oS3uuN?KpGf9* zGyf$$6xAF0qvWL3;LnnNyTPBLN0;jjemB|KV(?qYPR!utq<@3KSCajk4DKO5W^mp| z?lSml^80mz+vN8lgBQ}cJYn!3lHX?yzLE4_Hu!3i-!eFVHS=Ev|A^%OHuyP;pC34R z9Bat$bhZ07>w^95H4gM9fe}%#Exds#OV{E^J^sY1XPf>sJ*F>zpko*oB`s<0O z4gMzCxz*tFiGS7LqhyD_m}9^ABRNbD8v49nJYn!2r7oT`_!jD)pBmgI&if(zjS=U4 zk2(It1k*Xg4*m!albgy}KSu2;G5BecFERMXq+e-p{A~y(-rv~%2J*|__%RQYeyd@J zzq!5L;J+ikhYfx|$$VbJ_LHRln4uph`R4}bZ$kgw;76$+-!{09?Elu_yHq!bvj$&6 z{Qxf~GI5-Dko^LKHUI*@h4cA9@jYP^Yipm8b|#vj_DP^B{4*!JCLLGkApffWdDjo-+7u;euGG!E%jjidfnnxFeME@L5nNaLvg2Jzc9j`}>G zj%Xb9c^!UB>Iq`D~Ntp@i_k=dmXDlLDG0(~|IyH<|N3`HZ2@^XLBn0x3%- diff --git a/src/openssl/ecdsa.o b/src/openssl/ecdsa.o deleted file mode 100644 index bbdc90564e2a66e1f33731cbdd4af36203e147c7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18632 zcmcIr3wTu3wcckY2?I$6NK_JejS?`ZnLLOX5H(LSkw-$3fdqtcl1v^YnZ%h1f(1oW z(Gg>z{qWLC72DpbeO+sNTd&`(jY4Z%U({Ahy?sz?Ew;T%uht5!<*v2&T4(m`ne_7Y z`|keWoVEV7_S$Q&z4ku)>@&HwVf9LfWeF~pxJD#6Muj+Bl%T66SuG00`NHpu|F+E+ z|Lb?2cL?Dd`(wdL6#DL%@WmTW#5#TPUrAuR#fi|brZ*jX`ix_|z18XKe%Uwn%yi$_ z>!*B+e-eMj7k|?i51mxi$45{4#&@0YbsuAMu`7Lh8&3H4ZvNm0N2brO77{Oi-xq&Y zQcucO<4->|1&H#A^0P`l@rM`ANzu1=*9oq1e=ij8^!Xn{lfvJIo$`&xid?>D>x*27 zNzL(`JCOd)dcWTv|8D&IPoJLumvU$<&q2H{9-fp725B3JzPzWDcKMae2^ z>}Y{6etgsBBa)pyzg~#8@*kAHT>ie2W5|xga!?04y&Kz;f;9bhg3Ru>tkC=aVh^I> zV&`4HgGXxoP4QQ1+MD9K! zGbOyqqn*v=s0^OsLZJ|Io zI27{q1_uU1JWyBP*PiOWquc%OEgIfth&A$jBTB$Do4bq=}4s20)<5aU{uFrYp;J09i{K zkP4Y)4+A3Y9?yEe7%WSr1_+Ra`%dB+;M4?$S6s z+y(Fqk>x4{EX#$1n2lqLZs+U)0#O`JiGG67d_WHZlPmK;MHUnAg3$4Yv48m$tg!2F99rR*FNiifS%cfLdfboOoBY*)CI$)lG3{HHBih) zJ|m}~2XxOvTEAKnacEbkq%-6-Q(m*=bs9W>p*RZAzVl8nc0m|84EU@O;V6{N7NCl? zAXm;2q=opgx(VwLqJ<+M#wcOA5HD5{;*R|-vj;|O0|VBT^R0DL6RXhV#$HWt?CiN1`w_GX zNricljp>9zya?0uWo$VYDK$n_m^ECs5@8*x%M#*Z2I5n5__SHA>5Qlom+c z6=<2d&g1yMYx!}+_ID)2b3lBB6t_bbz(_c@!7_>#uv`UFipxsw zHsaUe1&Vd(U8q~w3(30@DJ&{28(H1%&l<4xXp$p1{Oj=23i;uYmEn?-LoX=zK&O~> zFo&Q+Du0$F=MRkXA<$E!+01TW&4kyF!a66tZcg^Ph1G4Zw}aOK&`yN!9K9Zsl`!+q z&1>av2QC|2IdF+(+iDLx?IXTi8nB04yzA zz62?ZrBJRkTiAy}*l2)ME?^*4`5ssUq;vm0w<6pH5L`?8`H-6zh!UyNozR9dM0?F#sFh|3()J5R`N@7g;=R{WHdpT2qq3t zha8|zH0+UHz$GP?ACVR&PjfStD$RH5L4(|u#X9sIFt!+JYbOTH@{3C)w;Qim^3)CD zYrzVj;=7yUdl?A@uJ!hexE#^UM{wt&$VZWsVW09#M+vCnf4M_|l>_$$QZ{w3+%n~y=Z6J+%CA{Gf;ww9R?ZP>qKLBpW+rOY2<)Q**Q-0&X$3q_4REBbYB=>u`_~%K>OHeP@;ZQyOq!S&- z#a`CQdmL;D)uq`e!G+%Jl58pWbqg2nym3%cExF#au-OQrxO%FdN>(amx!wfhvRT)= zQWaN(w5rkp_ao@QstZWWbS04n5RwM+ej@E*46lIy!u?Arl9z;Lf|Ah|)=X=mJ3rg$p6#A#G@!0MIr2esRkH;mEe5ql0sE0 zFHn#(kSrsWAm!>)OJEItHV<;9qJB(YwM# zEe8bXLa0Xpa=;2OJ7ET;b1Fq8w1?zeO%d36@!Ktkce(8G{JU?rU}L?%7A$x`AW#6i zI2i~aE`~O_5vaQ$VG8zOb3wP&^3UqX?v&kHm?_F-i;J=Wg&e6QzL=YYrARXfZCtOmsX7O03(=v=6AfQmh=WmLSIoq?u8TbTTm z4Ye`Jwjk`L2Zu@fOLi?klfNe@y$6qz^r&62g~_*UsEtXsmBxcpr2T}bgn-9` zoI$4REWHpOPFNrtncQzf>zTZdpmVj=&bB^j+q#}f-Bx?b>`L`(9osr!+uF>eZfo5+ z*lJ~4`)pfnOzO5;Q*0fk3jb+W^fNh^-l;9o#^geR(#I>+Ry*68XWLrOq;4xUUa7X$ zv8^K8))pppTdDC%wbjbDJhrXtnbd8i#_I^h=>c$RRWwMF7tj=1KzDPkGxc8tJ%?BdSIhdVI~T6<(;D)_ zBcX6KIwh+4!(P*S}aGF_%o}N%I&=Aeoj*(ClNI2L6 zcwiVvcpU;CnG9hi*n5wJh7=KvMFzrsN^dkaFo?CmXebg<^10)$HIK))a&57-&N4RVgJS_ z$}$|z&2MyGbv5iP7kJ-%2-waCfWGX3i@v)2nu>2Z7M}mr1huNOskF$|x#`h08;`qQ zXe$Ln6|R2Q=%!`Ye${n=_)p~b9nSA`;P?fangd;Mpy2Kqv=0Q7A*0?`b> z2bMrIW)CUH7e2p$LFrQ8SqVwq6iEHBU?j} zsH`HbU{7Sf1JG4zVQFPReSgC6kSy388`#FS+goc^u57Ba{k=IvTGAjSR$xSZmy!m0 zBcTvxTVNy@jovgI=?Qdqk&`v6H`H{tY5kKOnC#0LRa(=~Uc+D4r0oDqgst2M_`U^w z4fn}$(L&XtJc5s60zbwDx`zixhr$9ITv{o%)6fM*hG8Q14-bW4YD1Vx`$k8jr7@Ve zCFS1o(rBbx1fmdW>GH~^)eT}ajGxp(J)Z9VU_^{?=0InADn+mhG6WJJp&(t87rP=R z5ayK{8L*FOg>9%&QD5eS@nw%%$Dt7K`Vr=-tQ(p=#wfo0=rSiY7mqXbWKROL3zqvlrS zpOF1lLk25O1djogQd@gXyT48Jgt|uiAOYb^=ytebV9M34Lfw{#K<)7Gpkl7T$rcLB z$)?QIHLqRUP}knnyta)Zf-_i+o1UlXgQ}(t=6C=D1gQ-^^bQ95U>uvKRzLE*y0elY0go7uUHx;2mhxLQNr7U_Iz77I`iUl6$f4xU<&nxd-d+$%LMaWi`4-99{0RI(Ko6 z+f&OX(2r`W&qtK#XFFkeXqbyPx?>1(LwI5KsCz$Ck z8B{O#Rwc9Lz+xRW=?22R!%$OBz+hKbB(#k=$cZG)U?dps3xRE=%$#NmwlyIZL(9V3 zJv=lNf~CtF9*%{)u*$%~0ken9hWZ1&5%{$Ock-XVd!QF^k?;awu^rx5;z0=(JR3utcB%-;@(B|loQ9Ymb!{a$0#=X!j{qZg)i)s0lYmCt)fXzDfto-Y2!DpiH!G#N1d zI9JU0-vF3t6Cm;BnRtbdu=a*i@un`G=$II4-hvYn%7~FzrtU4EV`5nEZTVpZ4%v{= zimAH;Wa;|<2pu_bee6FR$)@yw95B-+Kw=&yHWaR}xK!Q4AV^n#E!BV75E`twAL^&` z|2X;2^922ebL$lUacxGMrk@`9oeF+90k0=|;r99dEfA)wUwN^rMP_UhT#xS)RNq!0 zVja~tajwVsD?lJ-q?zcT`u#=)&R?#742X2`J4Nw3PKp@6eE84xIj)%I=GuW(CKljT zh+nCjeKp)k>pLnRmfy#OXd&m|AX{KtX8Z7oFm3y%ydZ$`Iio>?RZ3~DsFxxBbT*9$ z+DmW6nbs5ZFI|KYHFfk1!G|Wn zas5qa=Z;D6{eWY?PQV?D+<(ITEAT&^oo`QqADsk$aS|Nkm(Kpr07rlLU|a5S0eg26 z{VYg*)IUs9fc5dvJ)Qk4NuLjmS*Laq{WYY|3)+3)2bPXW^aGRNy_4WKlKsQ9VB$Do zxn&aly`*18i`*2YE)Ei2O}M>hmak552u80^XJwkx3E51J^PIOYDK$@c=$Ik#jw>ywV*+I--K(W`jKL>9rm}Y4qG@Y~9uzHn;pAf` z``88#DEQTo-gj9C1ga*TG$@=HC847s#mN515#;g0G(h@qXH}ucmP|i<-Z8#T)>6+| z+?p{S)bR5)9QRdN&^|spS$_;cD2U@Tjq$q>gfb2OXG%(4K1DR@<1?4_Kda%oeSX(8 z?SGB*(Z0T=d`7dQ+kZ~O3xVc#|E%G-MPqyx%m*ykF1~*=?$vPI3o%}$;rK%;#v3(! zzJ}xc$Ab1Rg8!_K^BD``dK^Bg;d-2R6V7oimbHc0uj%V?ctpc7H@MxWHC%7^IStp_ zJw`aU+d}RBTGQ9t{j-KI)Y_ee9fg879luP&F98|*xlF^cuZ;UOe6faiYq;L8Ar062 z6(OASini@yOw-r<^&c9p`~O1?*ZqH8!!OhPJf-2fpJy~&_wy{_?B^1&g#~{$iv`8H zpDQ(7&wrjfXovTrSU(3ZP!N~9D5}pp8^(*I7W^KC?u=KEf7lil9Daf%k7I-d^|>wN zX`5@e+k+sKtJKZLPm({i1|FbBnhg9Z(&s#7Kfgg+*$sw1{?;DL7Im}R-AMePfxk=n zeWQV2MD}+YxQp<(f!{{_K?A>m{Qr!B{~OtP#K6~+|KBk1Jkp;q@TUoX-oSYsJZ|7& z(tpFi`TgXSfgd6MLjylU{hCJc<8fiT+&<$}T@)Gm50O9o%LvxT-_2vW#?W7*V6n=; z-Nf_y%yxKwh7A2evL7+AXYz)h?hkCMKdep-o{|oVp4g5pWFEj9e zC4Pm0-$m{E47`Q-b^|XV{;+|+L+w6n;P(=L%)sfGO8l3Bhd7=FzK7yCljIy9eo>!e z;Jb-0Ht;`DK6?%PKC)kF;7=02+`!io&+h^3Pn2+ejxZjfc2^sAc;CS1#jKC-Ls&Wt z{ckE*Y%%axDE=HjwzH7p$m7g7uM2$Mi_MX$Y~gE~{i)O@-oB~f_`KUl{EHfn`uIML z<);RIK*8eY8jg18*j2o#;b`akr2hvEM}6LxoF<(8$2|cSUcVW~y#9QFGwhrue@| z>^u~1_eR3!8~B}sFV}EPd46ARB%I^?If~o$2L2@3>DBBYbeQm6hCYwiof?khQxwkw z20o3}ug@F!dcwbM;GZR2{RMVnAIszQjG_NF=|8LCIKDiNuM*Dj{5JLLZ3BOi@H`9{ z6xPST(81DZ;O`OMZs30>e5-+GW8gc<9|t+W z@wuP$=NkB9)ZY~bejByB*1&&6c6J!}-$?%f1Lwakc*?-}PXm8p;MdZ4oiXq)QM<)B z*ig7%Kc)Usx=5TJ1yXN@ye8%sv7(Or#T%KBA`dAbrsMSneuDTB1LytBJ_G0H{$mEt e&&Tf@I5(a_ezHG@$*Fn+=XuKK7_86p?tcO3sri2Z diff --git a/src/openssl/ecdsagen.o b/src/openssl/ecdsagen.o deleted file mode 100644 index ce7918071b82b7fa439e757a15a0f67a96b6ce15..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17728 zcmb_j3wT@Akv>?}@*s|1N-UDtuI+>*1TK<%Z7Z=QBgsxe z!x9MT*5$p0rCXjY+Y+Eq_}JaDrKMROr4-sN6v|_}G=1>VZCMJ0LR(6^Gjrxh*JEY* zzWw%mpYNUd&zw0kbLP%H_t?HHym^DivXp6-YE*g7ph{i8AWt_D*`#KuD%JCy=R8XN z8j<$HN887r$kw!vKTZ7MquKfG<3D>0)oB4>K-e&^oc~1s_0$piz>I0XY8|N>fBZ4L zhmM+oTJ9(ep;lWy?@AO<&ApNF_qVo>f84{8dTuZzbhQ2Oe`ISyFKizF`D4356l`Ic zw+)FF|E#I}rl+W5{MYAS(7cOgD4@Un&|4LS=U6{^j&SIiaOi00na~UE<2YOU(?tu> zTv8xsZ9nv61paTQ#>{wc_KEkE5nnk!<^r@>;p6%`dHl35r)9I5bLoq!HaUV|iSEB5>RHz8}0 z0um^yzZ($J`%3W#O97)9i$9D3%=DkHLsH`(BVD2CzaU+$>AxZ!EP;zERu(c#HDeJ| zuNe<9t2E;!rb#o!#I$S1M@*MyrVz7TGbPqVVB$rZ30VEW3~Hv-LW@TorqnT?5P)G*eH^otg;| zb3`-CiFr^nXIV8c<`K=TAlr^==4|T1?U%mDWyEnIm6lE^FIU~Wic4}6cFXP z3k-P{fC`@s0ZzBYhINzvBF&sdj9)Vi#7xu73JXg{g=SV-Dgfct%qnXkFhR|%u~q}KR5NQy zLA_?qv35YuD$T4Trb#o6)}_$Xu9@|e(_QSrfn&ylBPF+34?_9TQny)$Us#nuxO)JzjG3n?UlW@46Bjbzg*&_cfIH4U^{^Wa(1YZ_=Hrb#OZ(-^&` zfejR_F5R<{7#-k1#5xL&UZfogPF+CGk{rka-tH*;sq4oD2i-XV5#-bFhX0hjBI4)3=79{$j-E01St+#jddIt4q2^L z3X$a~)ltt8p< zwHX+_0u9z8n91kA*bKv*`^2?41VTRldeZo9pi7YiJy10KKRy{kS(!;H|4SGTRXJox zew|RtE?pm`>+^K|DP7;B z>w9#?$3#~&e~ITQm=k!2alnI1#LPlZ2v9#S(jw1oAV!Pi^JBTEB>fX$<#fSyE~g8r z@cHqj=JWp)1V|F!L|PJG+*%U1MIhsYE|S3)6v+U%%z!-xEJq4@&|Jt<(~oZ`tr#cP z&jmkAHgx&?<8Upl0&4=8(D*{39a6dGA29qpHM?lq?q`6V17gZU*CM+5bk0u8pfKg^ zv?o2!gBe7ZUT?hxIC(I28kmqP1}pIOcM^ho!As5j_n#tHC(F zuzv)&H(7j9YBZ~?6c`+k3jE|@~ z9i_`!XvaeO$~tK?g-KbC`(b(t^;AWDw4K0&EXQ!uUSyd%167oth7m2NH6fjWeIDGd zkWPE*lAGh zEAFMssbFHT%BlAnwA<%DhGDQOtwm*30dLvtvPx_El!}>9xMnDC*_y!GK%@%3^%tr@ zpb`3EwU`9wilO$wXdm8CYD$&mEeiy2kOeFR!)RCqVkOKLN2-vWYV<=vwX8@Lj+i!I zMXKtcvve^KurMcEOJ?b=@?t_NFik2!lV6*Lnx^NbEk-3(+{^QvR0UR?GYdADFd>hE zip#Tu5bQB=8XQ_Z(<1Xp&#b&2*carDS5V-!78$m!tcuCSD+`i7Qjs5sD}umcK(k%0%kc*5v~z_KH#Y!T>o zv5WIlt)GQ{FUi?ejCP$v1}$}i8almJvHdKk)G{zhoskm_ECGcWCsheQ*l4>1cT05{ zk`D0*>M>*^ib4Y^Lyl+!pdO}jw}VVw%Xdp{HRRJdXqzE_%uta!Zf(7TncVFlQ$~TM zdJXvkcUfweA>F!qC+Yek55O9Y4ZJbrziXtBH^$B%=0vtJmAf5d>OH=L!-iaEY0OgF z3~7$~3OhVmSFh2vIj3uvA>FzrJNy^62i&3t4jVF(gC;GXv9m2FGRfgHK^@d~Xi!94 z&6wkYh`bzBc@!K;D9ie&tQ4+vYK?qq#7Sl{L#l2xldc;|#Oem(@w$DhR@y5YYK9WY z(S0=o$LMkkZ) z>vQ^R2hqXo{t+hwBf{nr}vL! zQ3VKV1wc4)4U9O$ES^p?fmQ(tpL9@qb+m!u4hrz zp%wlacf4P-(?9>2wVQU-`4_xQjQ?fiJS7lv+fMcO+ga6@vg3)7K_{*3NT;24qJ1`g zV}-lBZ6}>hrR_{M4X4=3jt@o?NtH=l;=ri7!PKw=i{zv;bpxZLnL0S>j@N{0Lv@*S z9Ne(s#2ZE`J2RL{XYtS`HZlrJ(cIG!vU^vCdV0Gf9UCd4DxMl1QHf+CtAe z1cfNg!Df3b1>g8IOI#?WdTbDrJo-LQ(yi^uF}dO-D4>h!Cw@D`hv z&c@h=Tf5SUG02on&VId86Vz%~J3BXrn>)xRJrbWgy;#gU!#1c#J@`C9{!!X!Q^Flv zx4$^rWDsfX-O&|>rw*Su$W}W#1Rkg)QfFE$Y zkPzs;Yyymh!$Uhm*_xZsj%U+DW*J(0BU{4cAyzCknvK&ie%7=$jvB5WR&E8QmrET+ zD>gjBX`>f;I0}ciSa)>nG0(>mnMA%Oph;u`3Q=BURbq@%7m*E-%~&A@5=lp;;#nvP zte#d>XRS_9dnCmb0unX6G29K2p`6U97yyjDw>iBUE%K#z|-I_ zi*)?Z%IwMz#}Ct()nhT-gAxG*kkwgrU*lq{^)`Jr9@*uBwCP;p;;d{XTqqr1n!1(R-BMUN$(` z7lL`<2G0QA&eFFAeOo~bLFL&LR%MSSvG^{>Dg_HlPq@wsoLtukljPbo%y8_3>e<}7 zNk_Y7OBX+7lOE=+9j>aVEBr_bDlEMdVZ{@vB)u6iE|A>#z>kjT!oa%)d>pofd)qtP z;O*&*Q3ZkB7T7@Bg*XO&bVS7)lc)Q)!+}o^QCawpMg64WuDZSwJ zs5gdnG^^?lG#X=f-} zo5jSfrFvc)%Vbn-I)x01!ww8s6zX$gqXYDk2T`JTVV8lgn*W~`1U0Z6ddurl*~GN`ynrK; z32ioTus@&F2Jw3Z+A&lP4G*u8G#@Yck&F$GCJ@gbVj`;4H9Ssp`KyF+8r1oJ9Up?R zsB<~|xSN@u4i;S;#fpEf4&eSun=U z{N|1aB!$M8&esDzDgW-`@vJ^~TgKya025|jgFgZUVq%$9J&*r_5#+mYM?DO9q4@oQ z-4H=F>+d@Lk? z!3ps63Gjm_z;8GKj?Yn{dG9;{ejniI??Jd@Ge?Hs1-g))=TCsYdIJ0xC&2%70^AEJ zi}oCYer&YQg8Mwc3)!Rh&w39jw$l9lIQgrh(1#^sxlaK)*l~gR!Srwnqi>m-B1tN-=`NUX~k-#`CV zH~8HJHN>%Y8l1}=$>Xcv;44U4>#1_#%`O~kvytEA!m(x=yxWE2tJUB;8OL|CyBbAZ z@@TV>$KT#zL;LX^VDPIDgogMj@MG}LBM1#~eAW&Abp)Xyj^7am|0aUa5XX0?!M}$f zG{jGZAA|o6L1>7(=lzgSjl1Wqf_%p&=dE|)LFhO78(p}2UOHk1IgHyB_%Y2?R>TAF zb1!$`T4OW#*ZrEuHNs}_M$Ibt9Tqj59&I&^e$NUF%Hxk|yxq*{Ih#Ay^4;j)&F|9| zfj`cR9})NmEZ-$?^Ikqr;9ui-T`2Gi*@+>6-^l#M0%uko5cm`h_PD_Ri(j#3zhnIU zCNI=&LcWdhBLd&darh^JDVd$tR_UQeqWf&ZTQ zw7_?>J(mf5l92fXpUiZHj z_*CZa5_p{TJS6Zl&GRMjn^^we1iqi+_ME`~hV{H5@Gr5Q#|8c@$I~1^nE2ena-}@K z!B_D*og(li*0V(5CZ8JwzLWW8ft&bu2>f-nXH?+kIln^Sn>aq#3H-~f=T?C~$$s4< zaKrzLz`L1$Qs8Sj&d&?{vuw{h0{@uTYcW4(CeHUWf0n=xV{w4iB=EO5{#yioGwV0| zP^14Qj>CYEAJOVnR^S6{|K$QV_2F89zrynR|Mc?DZ#T;w5%TwN{L?(n*xAJV69T`V z?SEI`=Dqx}z|H%&q(nPt^qYK}A@B=0Zu13>|A~REM&Q3?do~Ij{|g3NkHG(x^TZZ7 z{;mz%9)aUO9Aeum@UvK6|1)Mj&b@5sbwYj@+j)z?OIgp|0>6Xpe^}sVpZ6Vs1%dBkJ>S5W88qxh@>P!Kw*~&+Y|j${53*n17kDMd z;U$63VEsQA_+eg`03UD|d(LJ3GX(x9+Y@9Q(}`6BrPSF%KEdnN?84bZlHVZouzAWB zIG*)j+bi%hHLPwF_-e)<5_p*L#{}NV_)7wJ82^n6XP2nweHV^#Fz2u3@JH0xOgyJ@ zoZ%0#shPMP)U2u(@+NL;TsX$f z&rm zI$z*F;&mSo_&k=sLf{+OuiFLw8=m*;0>7Q@d{p2b_Un0phuEGE1m4YhDl4>MCJt9| z+?EKulkMbbs6H4PHLy7SM$KJUTiFl1x$z(lf`*tIZ$c27!4DD#f3VGWgCAr5e*o7H BXJG&U diff --git a/src/openssl/prf.o b/src/openssl/prf.o deleted file mode 100644 index 10ca7c76131ea3edc91ce05c3495378afddcd4a5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12576 zcmbtad2p21k$>NOI!5T0z(^csgfU0~jU*y-8L%WQmJBQk7#Bw$>ZFd}J$jVwbPfIyT$=UiZwW zC#lMneO3Ct?q46TyI;TW8VxtMtallP;9-chBF!->#Ea!=xpZuZ)&h3qD{^Un>pKNVOzU7Ttnc8c zKl!ttH(wNm2M}mUzR{BW#FxAzr3Xe2H(x9~a7haO>QBC=Y?3edjx>+ff!bxCG3HA) zzv$aPTIk#V$M=0zKlLTw@h9I@ibvWgp#gt${Nxke8# zeTvC9FyaBl6iX(qm{MZ^BtwdsX{-n4ZpD-tZNThPOt}#PZ~GN9*SHgy!-`pGd;`=T zP)v<60?dPosg=xe#negWlwy`j=B#4AYE*;G1;tz^V;fb>a$_IN^HVVmar&Rz*L9^L8ux`$+dG`g|?u4^S?5Jr3~~f>6|E=NPzC<+5bw8q07yDJIXT z1A$vH`G(9vF$Hpw%M?>&G=hysF(n43R7uku$OWbdr-ArjVb08EKFfUr0`4UM@E;*VKJ6ai9JApWH(EWr6fp!rD~p2z5#5fgHRZr1#r;@ifu7W=xaiK@4F+S(6tk1t6*XoZLQt}sQ|#=4Xpb;9W9U5i24Z~YRj9@sgpJLZ z1rA~{4jjZ{+&DDpT$$D8DWq55579Y?vGoy{aNaS1Pq;j)^@ib?&QCQXT2&naJ6wH{kCbdubRzM`Q}|cVd*&&; zYbo+6Bo`x^GY7W`u7kR0bRwuE71-Ta{Ss7hT;P;=0XB00#dv^S(+j73+&W9p#|Zpk z{Y#KgzA?nK5bLOf^3o}V%JV#&7)zv0EVYH)LpfJV8Emm)o0{py+GvVt_3;V2Z@BTWEKJnG2;ofvP%uKAU79{3}D^)DGw_^Er-}l ze<`xl*gq89F#M%xkyj!7r8OYTUkC);vKK_ z!VGQ|GR`pF3*jJ(Y91NVjLeh<^fWN33}@Cmm@;6<5nS7H;hA<8Mkd5;uW>`U5}{M9 zRYTdgo60e;Icaw;sNdZ5RLEXE*QhJqVzkff$lWeOnU^W*O2I~WkU*7+ToA+luP6Q* zB>YmeAQx7sBpau>Ho4CLrcM@Y;XV5d;VL`YR3^kC7QkMp7xfSxI<1l=1-q}L6TG1u z>$h0uk}A+@nZyzWVsiDMg%egg_0TXiiit8rJCpcmio+1MGs#!<4Dq4SeoToc9%m6` zh&Co4NGah$rLU@#;mu5Lr1uh2z=ew$_GXHs$A>3|q>#Flvn@kDgPFePG22g!q;~8HI(wTl}Yvq3&Nz+{q_m&my!>5V2G5jIw~Ug zY9W$+0YrAG6Fd4^%F3E(Wu?@KU@NXG)_5u%UdJ!LsO+8l$q-+%wb+oG`b+os1`3|b zV~AEJ*QW}zV`5=;=t=W>z)f8aaKvPKUA9hiv{iS+xqp`gE|CyS|1gE^5lpjpm$*~t z?h(@muUy)0&m?wxbTjcWAyrfsm#Cf4oQFy0UOJm%VE7m_JYklA=Z(5K$Mj&c#nB7H zDA1?=9s%sY6tUq6))Le$@gA+7P4OuqJ$PHB5k+wu^^<_xX(i>XhpgMTf}TtKFTjTJ zSwTJ=STvCJ~F)go2$lyGJQyIt9@N{&p@p|DkG}`0sf=j=M#k;%h9&aDkCcbyTjsa;30Z|1b zK*AdkXfPRps4dU}0o)DkK_a??y>=`PAoxqs@I(U-5~|`rnZFdq*s8%L`&w4Dn5`Xe zue!k>bpMN4x!UYleR$(Gcg6KLnd-jUXP^4>@6${>B3wXc4_oD7V zJRq8HX|*=pXsv7OkYww|=IxR}=dr+`Exkj1tf5F$#QGx9xCcLTp&tuQw%sjhEEWVo z0f6nEXfSSD1M#S^dP0HTnCQ3ry9V|O4!ScCv#C5*SJV!~ZDEH8t^RJSD?Vh!AdCJ$ zbeA2CNefWumXWA}S`dD3ypJtFyZNRK{+pU19`GfT!+BH;<7Ns)VA@b5-0P8tL^u}g z4cpx^C(DXaS{BwysbR7-Db&`&_gSke5w*G^p+tXJK)kY~)<7i2dT~+H7wNa5pCSC3 z-b5l+6NhfCuJhK_#G+loiovSMwATAunnfyxuD(E2bcO6dI58ml0x`_5HyE~|z%oWD zSH-su815bf$)1ADT1S-q#a*HgWDsizut!W!6_D_2rm zr1D6YO!Nf9fe@vEiz-tHhJ$h3E-GGL?yx-si;l6>sS`!^Rbe$nA|Zucr}`(*wJR}T zITsdpv(>rR!tV(E0VtyE59u2_e&S+dO{Fu{Byta7|1PVCwzhhL;2|Os1F%P+nkWDm z7F+Hayat3tR|MKwH5@j#+<9_!mI}v0^he-=h07sZScWWnJQ@-M5S|pteI`YGQBoJA zaTQJZz&(Zg4!1BYIHd|P;b((%YvU@QjokKeAvUaAx5`s_qum({gw--vuc%Ul`W%DT z<~z0sW2nfOotN!?04`s6mzV>8IOLt7v7qRXYh8X;)BR@ieHmXH$-Fmf{r+sT)|dts zjk&@b+uIKpA2`RO>fFav)D8u_aa?4tETXqF7872HcH5naUMm>xiGWPffzHmTJ;)rS zFitZN4TRwu%VOpnzTm!Lvls#p-mXZ0zYP`fh9hy?3%w5Q3tdER?LMm~8tAuGrvLw= z2V6k;guLoI+%*ub-(`y&I!MljKe*RS7-JO*dY>ft84c&*dw3b)`1Xl7+`7h%hY_4) z=rFE3`us=jmw~PB6Q||*$Kd7OIdoloEto9-7w0RhzvZhl<`1{t3Hdhxru#&TD7;+b z@TP9Wiq~~p0oF0pJWlgY!$}=O*WC#+9YgigC3u97-0GA%>bhSC$z=JDk|En;{#Z(V z{UdP!Y5oRe97EUL2QnQ)^;z&%jiXHyYOKKTT9d{9J_XKwit*>cpC12xfT2&$ z6G%D2XaJ*HbI$Yg8Q&Bpvwwspo-4hi4{XQh6J(#(P}BtuTobSz!#@B5F|Ex6+xu9N z&YVBP=YY^slp;61FLM}Jj$-&@d&Uvd_pWqME|21QbxIxe_$P}Um3{M+3I3jiV+Q=; zuQvMp*prjZKTrVz7~SfWI_mSM1R8;Q8RCO08Z23J(vHPACW{2|$tsMvwz+9CQ~mfc zVQMp#{dke7ezh780%r=k2x$^i?gR~#`ta>?l3}VJvL;AO*%1?9m{2r@*&Ofzyi{{uo0~VDzZ&d>quC-p9W|&|3+C z^diEXd|8001-v54fo+fZ{~iD90>&Bz%YBY}j&Zzx<3N3^8RNSVgn>9-N*R9`K^VIK zGYXbC?seAxy#vQR$oP9x;MdUxL;v{m8SCR)ISw7?=N9}moN3gQv9t7 zPT{YUAM86Etp7jchd+cd9#v{0L}$i#l0L6H<3aMzc`)8ecvAConD_@YoY(I$4S$C6 zI;G*yQ9R$*@RP)kYWQC$o>w&d9pc9{{50vmso`^J-uE?}zvz9g;Z5Xc8rgAuo+Z7R z8cwiSpy59wKm2`+{d`RIS*z*qAV>Utmi1pFyhGDpPJV0+zm?{VYWTMZAJ%Z*SNCf8 z5b+ObIN#@=)bNEA&odg%*Y!~iKT3JMs^PyOKbJN9GU4xN`0Ip!q~RL~S3j($_t9Sn zFQ7Bm8UG6e$7~H>OMI1v&!<~>t%kGxY7NJKWWeFm@Cy`on}+jxJgVWJk^UJCpHA_d z({TPu`b!Pxxc{KxF7p4DhMUBHpy3Zw-9Fdw1LP-%E37?_i7s$Rs!#jzu*6_zj zf2D>G6W^@izoU6?*6=mN@6hl?YPkeoFFAfU&708l`9AT_8a|)+5e>gUJlBu?H`BaN zX!^e<{G5h=hvK=Y;crmBuV^^e{|_3zoA|die3bYPHJsPQpuXey`F@tC;rMS^IEpnq zkK&x8;ZKpij~TVv!}b3}!}-2>MZ<5SMNt0)tnOdv z=WfD_k%58hj^qyspQYg+5qlRBi`>U03uG_~j z2aceoe+%hHH2p@UF7DHCi|}(Ao*?`s4S$sI_cWY;$DBzY5;)Gwq~E0B9}phaaK6tT z(s2G>b)0ZsuRAE;r!@T6gg>qM;ePwVp^tsLm+GHGi^|u5eDX70!!t?WtKmUR9L6RM z|46~2U&D`(pL;a?Y0^Kb;Xfh#Wes0K^HTfEex^&Ev?wAwUKe6THreU8hZL~wsr4oD Ef5UQCga7~l diff --git a/src/openssl/rsa.o b/src/openssl/rsa.o deleted file mode 100644 index 9a12d0c988a3f11b7560ff5016960b03db2dfaad..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 19616 zcmb_j3v`s#wLbq$GWbf2uNNqAt4EQAXH_@<4-b>%nUOV2-N!E zRimQV)=FCxZmm^X?X}mo($@B-_0{&`TD@W|t=jjhc-w1jwR-#Ta`!%G?|;smOuAU> z_NrPj0*8~X_{Uo$yMTf5fIg#)g29^?{5dO`LWZ>+wd`o?F9X4iqq(Vr_bfLD#VJ)&ytcQ5z#^_3UR-Y27~-q0}m ziXN2GQUUG$2LY}A2LW9QeU(k4?@_St>%saVSQSq7=4bj2ahx0@fHHoF^R1%Ut3+qj z_p4s2dM{hLrs9~TwP(`fVevm`;~0KLGHB%mNqs{mee^ru_5x8gR&`bhr_H79wJU>~ zwbW$v2~pmPR?f{bD)gy&apxSp9e$=gG{XuB-FFb8MKRkhD6}tMTsRifc z0}==^iGQ}e(EhVU_l;rjs$PIk6}*WfSL1o-8Ki~ijCOSoI>A&dm~gs!gKh2A!T50Z zV5BFw&DpgqI6tYxvdSeQJGxR%reNA$+)4Ds5<}9Y6YWXtil-v6D4WbK*Xv}+H5Chy zBLlGIS{=7wU-D3RaFV3w<)uJ+?MaAxEnA*EipwF;r@&l1<>cf>qA5_2oHXIRD*_#g zJcuM&%e8&>eaKqUfE387d;}0__jK-irGQC~x$k!aO!VLHK~mu#AYH8J|3$h)(Pxnk z=D|Va3JaN1#aNQ5RE$S5OBLgl%qqp?N+zTjpJZAUGf6TV6_aOefe^PSroie0W@P!yzZ*241ER=1fXaUWQ0%jDT4jhqU(HO|Ii^I1hlH;VRaA(+`ja53LiDXhT$PG1 zg!EK7Bwxc9L8e5&0b*Q>3qX>S5>;UGJVZ_vS92$Pq(lKt&f7OVlfRiGcoC|2GEdce>Cs55G?a4@vdHxx4#>eWlHl7 zM37YUM_0mGr9E%-U9eL!B`WgnKnuYsj>x+csnRK6;Vz^qr^H3xL8O*W*)H<#MrxI^ zbPv)YMIS=CRnhk%y;0F0F98o*6#WT|D6Z)HkWMN3@W()YMA4r@`c_4M8tK~={UFxX zAw?f;fb(HRA4B>WCGuc9j2?7wop;*cSjk+6m2xmDrG--66WMeo2u-=gT7(Z&G9|HS~r ztX1N-E(Tr}MsfZuYb`K=GCd zKKof)_L{OV01j{4Lb@+6;8O*VY7}Ps;q2aE3+a{{2LA`2{CKXLAH$9*l+-L>sPymV*HnppI=BnxO}quk+$<@ z%9}N;cy*7U&{BzFp=fso#{JLb7(iaRl$=;fSW~R|{y>4(KhrkqJzmTBxH#j znCu}4&37DSZg*OcN%pJ+nM=oU1F5(tdG89GT##_KL@Sdwl8`0Z+2hVM#J2aiP%D#Z zckR^ao(>W9u&dR{38iCG2VO!o6mE#ZeY@{neRBt+(l_Y zCfT#fDs$;L#$|PU9P2rbLf8CeCfPHZU+=~-H!a8{dsc$XrQ_Ia=HoE}zD{SDT_%05 z`F18b4v=DUW?G8fUFt%uOr|3kH{q2eUF&LfGTG@u8<^ZckeYDjK9?3`^5G0YbJ%OC zx7}52WwOJC+L;`3p;jhSF4WHCZWn50@*x*$XOiQB6q-RjLDJuJwK|#nD?w`5rs8+0 z_hnbHmC3)jP&<=sD@z3GWeZ%^;OdPHwlpS-3CbP;_s&f#GI@y$wJ~|)IoV=q*!Y;# z6+4cq7}G}%VwUT1J(D-MP&<>lt@RVy3c8AIOmZ-mSkI(xt8JXEEo39%+UjI-hYPha z`8Yw@6V0|*8j{1Lt~fq9tT^O)T+ifVF4WGXZfksU*jC(CY-5sxf#fi$+ZvyoF|zS} z*H$N!KOjhDg1MK{g6XMO6y6D{Ubu798mnlKB%gxC;Sra?(X#&LFNCA~NQ`_e?nINx zK~XWBOjHa;x-0s7dMZYiUKze}N!ef|Iy_R=A04h(Qoghz673lr?sb$TG2BdKJD zNCs2E?&w@mUM>VYiIn%i5){c)Z?Dr=E?UuxXcP%$^S!ddbC>#q0A4^(_ervv@R0-HQIQQ>f` zuP>Yub@er!Yr?Hr}GP2tNGZh1|AqVE#NhB-!hli6DDVWK!s`9FeWTHoelLN6ts(ZLkM79sb1$-fm z_Cl6KPYk$7G?J2jp+DT+m2||K=FVVk5Ne~mDp)p@8jd-CRac?U469}j79r{@-Q4tM*5>pZxBCGs!`UqG&k4Rb~Lm!w~PAb zH4V-60={yD)hF99eP+e73B%`G@TgfsBV-S9kdQ)MJ*mhJN7OWjYdbbdB(6T{hUrVJ z2=_(cMMX@s)~{1pMR%>8HI4O~(wTOmy%_?n@(XgKvrD;0&lu8BtT*h8#KGoZSAWt? z7;4Lsg~6M`;5Q5eB2%L?4uBa)2_wNZ?dB0?NM%4~wX{ zV6n8csVW%m#tI<3y6L*=P3>+6RGB+pB(bg@a)Nony-5nf+=K@pOI%M-jxt7-8k}-W zP1M-l*U0VYTR}au8GA4(={R232q_%FdDgy2q?iM z{ER`3F(taeUUkq}f_s+gRU$HI45PYZ_qxStqCpWJTffF?I=@ z0GPN?OP!nxS>|$2y>bcWzh^iR?uiW!52@mkgOhukTWUCqDwy`#>b6bcj!;AMns&A9 zU{-MTL8;+svGkzo9r-I%{$O##3c?GE2oFbL>jimbu(?GV6Jbb6ZDZ!R9GuDCO=tMj6n;$C$*L+S+Bo(mJO*(iK$~hO(s#6@gb&ey+E6w+U;c*qS+c zl6?p+{7ukzAqqf~kIXgx;)9+Vf5~0mI)Cs$PMyDWZ*HBx($kdhFRk_mtNkS)QRBB) z7a&rrA$9N)N!lBf*67m=NZ;+L_m>>>*7$>Wp}hlWZ?DheD2w1rS*$H+G?3K=q7rO9 zP4?vXjB0=J0nb{0$zF_aeZIe>&R<;Zw;Ky?VN#CgZPJn72|#DB=em5q9V&?UZJCQ= z7(2FNJb;M?!0|0iDdFo7mwKK?=#qVP6ZD~tEz}3^KV`#w^HZDrhD^99PwpCm)e7fS zLY)VgN;rdEk#ii<@1VjwE3udBN|;p|`zH+o&N zE72A0hn-5t;10uKc`z=@;Z|eFflFz5G?sG8VTHp@15`OFIRoLo1YTMGIV}igFlF*~ zPcylSX!Cwr&XXpGuZ-aSaa?O%te_FNd&P$HfPVOH9p@Muz5qp>#1NA0JQE5_&JVxz?jxWze@V8M#4Q!7ashm#L~=J@vlX4*uRl8f*t1iw{L+;~~|jGNW}6Xc)sjQ%IX zpXvV|z|cR(38ZYNW~=k##=_!Q`TS`R%cg%TE(~atM#aF9_4xddhPgsOJV5$7hBWIj zeu6NgOvEwLzui#a@w5JuKxCW0?@|6vlOX1A3jDD?=M^zpDkP~+rKRfp-3)Ym{1~1Y zJF3LtsTv#aKhuDQ4^HF!!^gj@{?FjX0Ik;;zriY@EJu{f5q~_Jr3?IJx8ltj3C5Q# z!-&J=uRHooC9nDsRVE0WSN-5J3yv#ceDezUpq8b1-LLMMonBcHnHX|j zIa8T9UeC|d^0tqR#v=}R zHv0!Az;XR&lYevq9N*YylOF>d62W9%v0?G{jMc@k#`tA&zs! zcr}91O!+1SkCPwN@Bq+k=d&8F$MZD}*W>w)hU@XXq~W^!>l&`hzop^2JgygP=6I(< z-7>Dnze>aL7K_KVRm0)yx{L4BaJ*)+{B0UOUBeF$j`vFX)!}|keugG5|BD59j31vr z+5UfO^19zwHC*@m3&Ss6zQrFkdEIX=I)sKN+{4-L#Tp*e@GCT2kLOwq*W;-pob%8M zwyVn#8+O# z@j0KbM_7~C82>umGT?m=HpW{Nt9~5|G)@nNAbaF5j(|dW{NqNqQ?8v5bzDPdw!e>z z)fo6Dil@QAUnO~-AGT9Z_;rT-VydUj2L4mRdEa0={Ec|KAy2Hh$-p~k(Tp1SA-YLD zY~b(ExcE7d{YGg5@j8x;@t={MuPE5XzfSRw8943**iNdGE6?lyw1ID>_ocnz(*+lMgyNldERK?SEz7= zW8lmu416)gbBlrV7xTLed^5%KDFgok#q)UsAEJ1kG;sVOJ~qx1=acur7Y+HtbVj;DzLOyMb5HI=aQc`ByJ@7`Xah7$NR4@TlYw)b{3y%$e2eTCP`(*oPWfDG;2$Br+rWp3j~e*H#P2rnHz>Xn2A)Iw zvj+YG@jo>1ofPM529Ez>i0zDlUqt-72JYsE>VosIkmM#C_*I0L7|d$z-Mzt50wrFae*crD>a4E%9g zM~@o#jU@jS1HVH}ml!kf%PG#22F~+!+Q9cw{(0T=xV}YlZyWM&QJjA_@EL^XQM_zN z-mpQeQw{u0^2^s%mggV-%roTMXkJzrIQ}y%wnhU#N%3qn@Fel~8hAD3?EwQ{P51^| z`QbQ!Lh;{f-~*(8r-3gd{C)#}h4T1-f%lN#hYXyb>y8_EBgy}(fuE!}ziQybifd_UnY8@Pw^@H4`3nrI4Tf$Pc`RAl(4E(E9=YKZv6_nH*bO?>}_8j4PgmZpAuf)Xp2L27gml*hSgf|)ZD}-+~ z@Lv+X$H4zY_%Q?L`}-3HUP9x2k#IcWbLBy*&mSA|{J!&jO&;^PhVt)2WoX!q_|t^r ze^y}Q{M3=(MFt)ve3OBHnD9OW-%t2Q4E!^MAJ%YMLNboyg!6bmLF?#AO&+I~->06^ zUMEE{U9>;Zx;vY5S`Imr4HF+Fj871|&AZIl$2ED(4`0`wGVo!l&*u&NON9T(!0|t@vHg^A&cjafJDEP!Fg{B7bOZl5;gtq{ zobW~s$Ncd7t__59ey*iFY|-S=1i$a!Z^(a(?B8j~j}iWuCXabrO)ts5Y{>IZiC@s< zv2OXj;Y$V{pt^e9!2g~0u{RC;uY~8|$33H104-r3R;C!8W*T8u{*Wb@e`{acGdxib-J{F=l8RzxeYv5eZ JBL>cO`+qFuU}pdT diff --git a/src/openssl/rsagen.o b/src/openssl/rsagen.o deleted file mode 100644 index 4d1c766aa628bf7eb24c2751149a93ee6eb214ee..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18496 zcmbVT37AyXmAg|f60yPIN52L+q%F6ah&0jd#WVo}TM?vm=NqLv2K zQDjjG5Q!@;2}CE6L`-zDXfz9cBt$=*#3d#s88b=7L^C0Y#))KNlsV_#b6&l=-OM*% z?)UY3=lu8FbIv{I+Np4h462y5bJ7% z7=x0+l))Vl;h7G^g>tSRHN(|yjzz|8nDXXQ+!z8q3M|9hm@#FER2~LMPO5MpOhAVs z4j9G%%g#mtCi?HUBB}8Ak*-nn2T0c``W({! za=3^xVIWhl7(+4(6yuUivtrzmX;Dm>WI7b%kxZ{*#!69-~v9bc?s^49NQBBl_~<}A5%a}ar3Px3M%?-q{k@w&wqitGG(4k0A53S zdQp#3xxPqlD3TkCWT;5?70FFS^710Nxkz47B(E%zA1jg{FOpXk$uPRFJj>36ZDBmH zqON>}u@x9!T$HyM@8RTp`E*8Q~6vk6hYRw@y`4I4!HI>QIB>FXBdU6SRZMlp*dqrz0NSTf^O&k_T-QWd6(rN+0s7;JQ+ zqS^QrFn+}>Gu{QJUNM(Q1q&2&sWEAs5Y38NE}0g^tT2{APlsYIle6ii09^N1p26{o z`;2E`t5s5;HdiSW*(BxY*EZ{*)yn^FUW9Y6!S$XwnH%wOR-&wIU$+7ig`rZxkXIe zuyLgrd+=qLja;F}y*IuDL~SM#7v6nX)@p@%Z%QC3SE%>qFTfG3HURH_oNrxiN_ao9 z6+HLXTEcq(srp*ba1f~lwHe_(gj93wHsSpwQY}i;tw?t$`Y_VHivASRn-zWg190D> z=sVD(jH2&EI?}PjfMc;$;E=Avq^eu}14DND=6@B!pFoPqCK8Ex$O7fxCVD>T+ z8E@ZhAfRL}$BmZg&G&*%io}&jQzWiJTAiBS2-1EvHvU7P>lJOe!PWvr57q(Qtmp*N zEsDMx=S4Buiaz%$JhvWXHY{DGA7RFI#+}S#b_3%vcfz$2U62W? zH(!1cfZAM2n6JqE)FzoUYjJZie~i{tdd#07txhWQ)f@~|sWN|xxL<|O{Mq%;F$Dl& z{*&=0&@z;hOmm#;9XQITX7X8KR=O}Na&Bgo%LE4%T`gr4UE}&6kXLlA>zqxGca_0< zQMk|Lwdo12TAQBenrzdPTr+HXvg<;du5(>v(^FhcHa*p~#HOdYF0tw9u9Y@D!?oI` zXS%w8o|?1r!kq2!{{jbnp=%?^K>Xi_TJV?{bdNbt(s-IfUgUMJyxuCW_sZ+%W` zJuRq`tS1khP?h+A)r~+s#)&35o`hvnee(WMa0Z;{Q*#uk~G(K1&Db}T&W(j z3#4QzJq}>CykMfMLk z5Gm+Ee?8{kxqq46kA_PsemZn{%vEr$#ADQp6^*;TTuIf6$Nf+8vp^J&ZRzbDfGSmT zO44N;13^5LJmxl#lH%V+anw{TDJl6ZupskYxK*NFkBQGH9`hIgauDvAjzMyyyx_=c z>;>rqa?C3{26wM&R1aO{Kubld5R{Xb&UQg>weDF@=-rVlKt zpn;dOH12-Vwi+U*OMAyY=<=9fhHE7rY98}ia9ghK%EQKKR`5D1z!j|&NRJNztF{DV zDtb2!d1JOQxk`xX5ui|NdX$L_5OT3DA;VBuPB}F zcZ@!mAlyPQMdze97z;41m_cQ8?HPy7=}H~gM09R82Z>wDPR;Fyq^*62#OINy_?vAK zY@x|Me64n2x5vC6uF6i2(@rA|HttWsXl19T#7@r$I}_pi0fbA7 z@p1)RT-yasaXwlYa~xk275RlC`9&n_Q2??94Wo$3Q15xjRm;mE>~zRQfyDr;s+YYN zp@?^ufh!pUp}OQ~d3G0tDt|4X8E_WWI5)MN<@m~9%C1hkOKv;(h^$sW+O3woQk}6#?mRm;4WcsqTNgE_+MT>^uvK6c!=4=?9J{&P_w&?WXX<9iC2ngv!WBwG? zRb3{L8Z4Ds&}1stP}6wZY#A!?Q7_q<-~+Rl!nQLJ4ALkeCQUY^qjJRLqG#}2f;Lgl z6mk&sz!6G@onGcpJ)_YG_%Mnsb$7Q)O*6|xz~_RP&hi?4lTo*S z|84_ferM~HfSma3PwX~?tL{^+b+G;%eNga?#${93T4$-=IbfDjgxcp8y+C%J(h~r4 z^B3EKmrcP~)EBj;sxZWtN=GlU;j$tK0apzx5t||Um|U(9_!b9C^(b@e2n9hV*Ov$~ zH&_&8a;QX*x$BC8Ox{=`$lM)8K_>4h5oGS`ML{O{z)+K+{t>rD_P`L6JZ~HrvZJuN zD99wwTM053D+)5n^Hze)Z7&Kk$@5l%%-vcPWRmBt1etrRD9EHU3ZbLaKjLO@x?(+( z&M2(6qtI(xSkENS8(mp{l(}S4kV&4m5@c>yQIJWVw-RLTNKueUp0^TY?nF_LNoN$+ zkBGuV8o*O_iA6_Q8IMGa#Oxc7#OQvpu4;Q=h)Greelh9PHPWw(!8SaU zK!Y>d(Rh>tk|ftm3w0c$JJ$iR_H6)sbcqY$Y8dZTRl-&N-i3TRW2JJrq-ZMSvQ5cE zv}qs~YueGgG`w_iLo$&n>}VKB6`B?|Ha8_wv1B1`DM?~RN=6g;T!}~t)5PWkJX{V~ zsm2(bO(K_%$F2TG`AH_fGh^j|bW1pq1`^&uz%eFs`ABRlpztD?2FJrNKyi^=Dxj!n zO5Lqt>H=d5iDh?Y@~9I=XRIMbTpBGTlKF;2YK00|xk?2vZolDkSD9;m;2t)gfxrAZ z_cZfTcf!oOE8x#(zV17lU;gZEYnETK+`EOXd*xxYVZ|GU*Z-D$P zhbs8UN0hluof|t_*9FOBZ?G%8J)6i|VfZrIn@tQy^43~wr^sZ%a3q?va(SQzL~v7Y zxUI9dBe)^l7TPR=-K#shgTjLEwpJE~#2o@+z{-a)o#9L*8yT|l5EEs(r*%!REhJPL z!`6;)Jd%%K5Yy4CtymtbD!kR&3DZ$?w*!z%45X~MAEFOAfKWif6RB{&bX;I$k|je5 zDH?#mlQCW$><(^NxsE0s?oYsgv{O~4kcTvJuB}uYlRT78<-@W34s;P#2Ha#U(9NNA z943$v;r?V~AZKR?2g(u$+3;{0KFUe+echd#f)HSKK$e3{Er3`{GKe^LumiaoLW^hy zesW0k?}Uh=L=s9Zo=*%}0;?3iVU=dD0Cg3^a*5)WNGnwq z4rDcw#N0-bVK@ZhB0jV&Aabzj11&A|!VVu=S=@Nx{DS>4m)oAs#>25Fg$-TEFAY$r zjvuUG9={siEnF}HIFmJi(XS#=*|Dr+Spjd`rS zM!9Mlqq&@D%%+h+ad=z;7KP$gv@j4(r25k!D(Ofxnze?R!)@Cs2@e{n0oW%Vb_s$SAsh|^yZ zFbB>y4H$TY9?_bc6!a)6hlVc|Nb)O49fHvC`yJx&L|)RaqH!f4FglDcH>mR;9UmZ_ z3*qi;Y@hw*KDN*IAapRzGI;MNu(#HUj+AYI?$P4+CKdXllhk;OALfYt;rOiwY&82{ zm%rQzF~fe{PnOABBlg4k=lxwUw2;)cd{~7Y1^Mw9a!k?bMPm_I~C$O@0 z)8_YO9zZzT=lgNMk=Dn*KSvFiLF4$wHd%AJBs^pV}X{TiQzIt zTe^MtL3?!j^i2=*<7~QpXP=WsxiRAHb54wD_ox{|KSqlL;-f_vacyyf0bFA)hkibL z(YAZUDS;^B92Ld$)vf-K0JHYpt^OUR%`@Q^e5x~|?rynqN-^ZzqIx7Kam>`n=2ril zVMK>pK5dl3xc$|XLXyMtZZ!OY^WgP>kB4}kggZ8#;S!)n)3XY2l;^tTXCU0CN0T2W z`M2PXjXxzH26{Akd_Yt0hs9?$dZMLgO7+HtkC66r+=#CL=Y7CD&l|rc?|5e`9iTe! z8v$=Wxco4ie?O<%VxX~MonrNJWw#*+O_#^GVbk%Pf=A#7&VxUA9{gVkXMczlryMxi z=JpFB5Q87(?0MDD#(?+~2mTSDu_2E8AIG5!L1>8k;E(YHg3xsQpA|d;zwSo(LMEo`l zCstgi;qY6sZ2L9*35w?t4gVx13ZFZ$aeOYIE&RBGZG0K&|Eh)u$p4cXjSNMsa>$lYgD&TS0bM{w|W6tl`b%{~Qg!nDhiR{Au!Y zg@&vDKqACi4c|*~+pOWU$RA6?e@lE;!xQAs4H~|K^dHplvy|U^G~7e@=QW(`^(z|w zF|vD7!ylr!{hNlbqWJtw!@CH7L&HOa|F?!;Nx1q)KE?Ws5?)32IltS;&uJQdEy-V` z;q?@^1scAD>grMr|1HI>L&JYV@*xe+k^W;EzMtmF@niqLN%+f}e3tzGy@vmd?4H%| zZt~Mj{jC4@#8+$h9;(CX8h(WA&e!l=#4ptFi6p;5!*3^l)@V4suVLGy;XJRXhCfC6 z(;EI9@z-ehk0~zuG<+5Dhc {Jc-Y@x2z?=QVsg)!Snl{xaq9n;O1>{Q16ypP+fY zq~Qk$e@(+rlb>&DI6qIkqv09iKhW?=w6B)aJh)DdlKu%A{vE<+Y4~oMSG$JaOY&D~ zIOj2`;lH8v!f|DP&XAt#H2GI4J~wOlZ^@s78va+}@78cH$^VCjv!8#^@bSd6KK65- zDid)r&4ck}R1Y84@TW=7dJVTIPgiO956I808or2lJ_pz?`@c_Kj$5mS$4Gy-hIf+Qk7{^?>abtKZ=?A0xyN=7k^bv7 zd5-5NH2fiwze~fvM)(67ev0rfY52wD|C1WtPyV0Q@L{UMmo@z7q~{kJzJ~1nmxlj^ z;_$A9-%t5+ksXfDVZ!mJ4Q!0RP2;C(`0Iqv)9|^p-WO{42PD5j!*5aM#2O8cl0Ta? zobwgca9&3#4Ns8WYc%{I`FWFuUr+1wb`7s5{4*NP>-IqnZz29m8qUw_-`DWJkUy_z zcst?0*6<$Urob&RMhF?K( zdriZ4lmEZd@OQ``H%bhV%1$Uc;Lx4!bq{=Y&6nAA_Kwc_gnU|9_+5 z>c0yL@s@@kp?OWOLMAy?E%PG!JX!svV{@WVKHGCTuHMI9M{L6$-q7ThnpKmL1` + 2000-2013 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 @@ -25,7 +25,6 @@ extern bool do_detach; extern bool sigalrm; extern void setup_signals(void); -extern bool execute_script(const char *, char **); extern bool detach(void); extern bool kill_other(int); diff --git a/src/protocol_auth.c b/src/protocol_auth.c index f8a3cc3..147c3b4 100644 --- a/src/protocol_auth.c +++ b/src/protocol_auth.c @@ -26,6 +26,7 @@ #include "control_common.h" #include "cipher.h" #include "crypto.h" +#include "device.h" #include "digest.h" #include "ecdsa.h" #include "edge.h" @@ -39,6 +40,7 @@ #include "prf.h" #include "protocol.h" #include "rsa.h" +#include "script.h" #include "sptps.h" #include "utils.h" #include "xalloc.h" @@ -174,6 +176,25 @@ static bool finalize_invitation(connection_t *c, const char *data, uint16_t len) fclose(f); logger(DEBUG_CONNECTIONS, LOG_INFO, "Key succesfully received from %s (%s)", c->name, c->hostname); + + // Call invitation-accepted script + char *envp[7] = {NULL}; + char *address, *port; + + xasprintf(&envp[0], "NETNAME=%s", netname ? : ""); + xasprintf(&envp[1], "DEVICE=%s", device ? : ""); + xasprintf(&envp[2], "INTERFACE=%s", iface ? : ""); + xasprintf(&envp[3], "NODE=%s", c->name); + sockaddr2str(&c->address, &address, &port); + xasprintf(&envp[4], "REMOTEADDRESS=%s", address); + xasprintf(&envp[5], "NAME=%s", myself->name); + + execute_script("invitation-accepted", envp); + + for(int i = 0; envp[i] && i < 7; i++) + free(envp[i]); + + sptps_send_record(&c->sptps, 2, data, 0); return true; } @@ -189,8 +210,19 @@ static bool receive_invitation_sptps(void *handle, uint8_t type, const char *dat if(type != 0 || len != 18 || c->status.invitation_used) return false; + // Recover the filename from the cookie and the key + digest_t *digest = digest_open_by_name("sha256", 18); + if(!digest) + abort(); + char *fingerprint = ecdsa_get_base64_public_key(invitation_key); + char hashbuf[18 + strlen(fingerprint)]; char cookie[25]; - b64encode_urlsafe(data, cookie, 18); + memcpy(hashbuf, data, 18); + memcpy(hashbuf + 18, fingerprint, sizeof hashbuf - 18); + digest_create(digest, hashbuf, sizeof hashbuf, cookie); + b64encode_urlsafe(cookie, cookie, 18); + digest_close(digest); + free(fingerprint); char filename[PATH_MAX], usedname[PATH_MAX]; snprintf(filename, sizeof filename, "%s" SLASH "invitations" SLASH "%s", confbase, cookie); diff --git a/src/script.c b/src/script.c new file mode 100644 index 0000000..9a43d53 --- /dev/null +++ b/src/script.c @@ -0,0 +1,126 @@ +/* + script.c -- call an external script + Copyright (C) 1999-2005 Ivo Timmermans, + 2000-2013 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "system.h" + +#include "conf.h" +#include "logger.h" +#include "names.h" +#include "script.h" +#include "xalloc.h" + +bool execute_script(const char *name, char **envp) { +#ifdef HAVE_SYSTEM + char *scriptname; + char *command; + + xasprintf(&scriptname, "%s" SLASH "%s%s", confbase, name, scriptextension); + + /* First check if there is a script */ + +#ifdef HAVE_MINGW + if(!*scriptextension) { + const char *pathext = getenv("PATHEXT") ?: ".COM;.EXE;.BAT;.CMD"; + char fullname[strlen(scriptname) + strlen(pathext)]; + char *ext = fullname + strlen(scriptname); + strcpy(fullname, scriptname); + + const char *p = pathext; + bool found = false; + while(p && *p) { + const char *q = strchr(p, ';'); + if(q) { + memcpy(ext, p, q - p); + ext[q - p] = 0; + *q++; + } else { + strcpy(ext, p); + } + if((found = !access(fullname, F_OK))) + break; + p = q; + } + if(!found) { + free(scriptname); + return true; + } + } else +#endif + + if(access(scriptname, F_OK)) { + free(scriptname); + return true; + } + + logger(DEBUG_STATUS, LOG_INFO, "Executing script %s", name); + +#ifdef HAVE_PUTENV + /* Set environment */ + + for(int i = 0; envp[i]; i++) + putenv(envp[i]); +#endif + + if(scriptinterpreter) + xasprintf(&command, "%s \"%s\"", scriptinterpreter, scriptname); + else + xasprintf(&command, "\"%s\"", scriptname); + + int status = system(command); + + free(command); + free(scriptname); + + /* Unset environment */ + + for(int i = 0; envp[i]; i++) { + char *e = strchr(envp[i], '='); + if(e) { + char p[e - envp[i] + 1]; + strncpy(p, envp[i], e - envp[i]); + p[e - envp[i]] = '\0'; + putenv(p); + } + } + + if(status != -1) { +#ifdef WEXITSTATUS + if(WIFEXITED(status)) { /* Child exited by itself */ + if(WEXITSTATUS(status)) { + logger(DEBUG_ALWAYS, LOG_ERR, "Script %s exited with non-zero status %d", + name, WEXITSTATUS(status)); + return false; + } + } else if(WIFSIGNALED(status)) { /* Child was killed by a signal */ + logger(DEBUG_ALWAYS, LOG_ERR, "Script %s was killed by signal %d (%s)", + name, WTERMSIG(status), strsignal(WTERMSIG(status))); + return false; + } else { /* Something strange happened */ + logger(DEBUG_ALWAYS, LOG_ERR, "Script %s terminated abnormally", name); + return false; + } +#endif + } else { + logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "system", strerror(errno)); + return false; + } +#endif + return true; +} diff --git a/src/gcrypt/crypto.h b/src/script.h similarity index 72% rename from src/gcrypt/crypto.h rename to src/script.h index 71df50c..446a3b9 100644 --- a/src/gcrypt/crypto.h +++ b/src/script.h @@ -1,6 +1,7 @@ /* - crypto.h -- header for crypto.c - Copyright (C) 2007-2009 Guus Sliepen + script.h -- header file for script.c + Copyright (C) 1999-2005 Ivo Timmermans, + 2000-2013 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 @@ -17,11 +18,9 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#ifndef __TINC_CRYPTO_H__ -#define __TINC_CRYPTO_H__ +#ifndef __TINC_SCRIPT_H__ +#define __TINC_SCRIPT_H__ -extern void crypto_init(); -extern void crypto_exit(); -extern void randomize(void *, size_t); +extern bool execute_script(const char *, char **); -#endif +#endif /* __TINC_SCRIPT_H__ */ diff --git a/src/solaris/.deps/device.Po b/src/solaris/.deps/device.Po deleted file mode 100644 index 9ce06a8..0000000 --- a/src/solaris/.deps/device.Po +++ /dev/null @@ -1 +0,0 @@ -# dummy diff --git a/src/sptps.c b/src/sptps.c index 6869575..62cfb1f 100644 --- a/src/sptps.c +++ b/src/sptps.c @@ -466,7 +466,8 @@ static bool sptps_receive_data_datagram(sptps_t *s, const char *data, size_t len // Unless we have seen lots of them, in which case we consider the others lost. warning(s, "Lost %d packets\n", seqno - s->inseqno); - memset(s->late, 0, s->replaywin); + // Mark all packets in the replay window as being late. + memset(s->late, 255, s->replaywin); } else if (seqno < s->inseqno) { // If the sequence number is farther in the past than the bitmap goes, or if the packet was already received, drop it. if((s->inseqno >= s->replaywin * 8 && seqno < s->inseqno - s->replaywin * 8) || !(s->late[(seqno / 8) % s->replaywin] & (1 << seqno % 8))) @@ -483,7 +484,7 @@ static bool sptps_receive_data_datagram(sptps_t *s, const char *data, size_t len s->farfuture = 0; } - if(seqno > s->inseqno) + if(seqno >= s->inseqno) s->inseqno = seqno + 1; if(!s->inseqno) @@ -629,6 +630,7 @@ bool sptps_start(sptps_t *s, void *handle, bool initiator, bool datagram, ecdsa_ s->late = malloc(s->replaywin); if(!s->late) return error(s, errno, strerror(errno)); + memset(s->late, 0, s->replaywin); } s->label = malloc(labellen); diff --git a/src/sptps_test.c b/src/sptps_test.c index 2ce9804..7aa7a0a 100644 --- a/src/sptps_test.c +++ b/src/sptps_test.c @@ -19,6 +19,8 @@ #include "system.h" +#include + #include "crypto.h" #include "ecdsa.h" #include "sptps.h" @@ -31,7 +33,8 @@ bool send_meta(void *c, const char *msg , int len) { return false; } char *logfilename = NULL; struct timeval now; -ecdsa_t *mykey, *hiskey; +static bool readonly; +static bool writeonly; static bool send_data(void *handle, uint8_t type, const char *data, size_t len) { char hex[len * 2 + 1]; @@ -45,28 +48,103 @@ static bool send_data(void *handle, uint8_t type, const char *data, size_t len) static bool receive_record(void *handle, uint8_t type, const char *data, uint16_t len) { fprintf(stderr, "Received type %d record of %hu bytes:\n", type, len); - fwrite(data, len, 1, stdout); + if(!writeonly) + fwrite(data, len, 1, stdout); return true; } +static struct option const long_options[] = { + {"datagram", no_argument, NULL, 'd'}, + {"quit", no_argument, NULL, 'q'}, + {"readonly", no_argument, NULL, 'r'}, + {"writeonly", no_argument, NULL, 'w'}, + {"packet-loss", required_argument, NULL, 'L'}, + {"replay-window", required_argument, NULL, 'W'}, + {"help", no_argument, NULL, 1}, + {NULL, 0, NULL, 0} +}; + +const char *program_name; + +static void usage() { + fprintf(stderr, "Usage: %s [options] my_ecdsa_key_file his_ecdsa_key_file [host] port\n\n", program_name); + fprintf(stderr, "Valid options are:\n" + " -d, --datagram Enable datagram mode.\n" + " -q, --quit Quit when EOF occurs on stdin.\n" + " -r, --readonly Only send data from the socket to stdout.\n" + " -w, --writeonly Only send data from stdin to the socket.\n" + " -L, --packet-loss RATE Fake packet loss of RATE percent.\n" + " -R, --replay-window N Set replay window to N bytes.\n" + "\n"); + fprintf(stderr, "Report bugs to tinc@tinc-vpn.org.\n"); +} + int main(int argc, char *argv[]) { + program_name = argv[0]; bool initiator = false; bool datagram = false; + int packetloss = 0; + int r; + int option_index = 0; + ecdsa_t *mykey = NULL, *hiskey = NULL; + bool quit = false; - if(argc > 1 && !strcmp(argv[1], "-d")) { - datagram = true; - argc--; - argv++; + while((r = getopt_long(argc, argv, "dqrwL:W:", long_options, &option_index)) != EOF) { + switch (r) { + case 0: /* long option */ + break; + + case 'd': /* datagram mode */ + datagram = true; + break; + + case 'q': /* close connection on EOF from stdin */ + quit = true; + break; + + case 'r': /* read only */ + readonly = true; + break; + + case 'w': /* write only */ + writeonly = true; + break; + + case 'L': /* packet loss rate */ + packetloss = atoi(optarg); + break; + + case 'W': /* replay window size */ + sptps_replaywin = atoi(optarg); + break; + + case '?': /* wrong options */ + usage(); + return 1; + + case 1: /* help */ + usage(); + return 0; + + default: + break; + } } - if(argc < 4) { - fprintf(stderr, "Usage: %s [-d] my_ecdsa_key_file his_ecdsa_key_file [host] port\n", argv[0]); + argc -= optind - 1; + argv += optind - 1; + + if(argc < 4 || argc > 5) { + fprintf(stderr, "Wrong number of arguments.\n"); + usage(); return 1; } if(argc > 4) initiator = true; + srand(time(NULL)); + #ifdef HAVE_MINGW static struct WSAData wsa_state; if(WSAStartup(MAKEWORD(2, 2), &wsa_state)) @@ -159,12 +237,16 @@ int main(int argc, char *argv[]) { return 1; while(true) { + if(writeonly && readonly) + break; + char buf[65535] = ""; fd_set fds; FD_ZERO(&fds); #ifndef HAVE_MINGW - FD_SET(0, &fds); + if(!readonly && s.instate) + FD_SET(0, &fds); #endif FD_SET(sock, &fds); if(select(sock + 1, &fds, NULL, NULL, NULL) <= 0) @@ -172,12 +254,19 @@ int main(int argc, char *argv[]) { if(FD_ISSET(0, &fds)) { ssize_t len = read(0, buf, sizeof buf); + fprintf(stderr, "%zd\n", len); if(len < 0) { fprintf(stderr, "Could not read from stdin: %s\n", strerror(errno)); return 1; } - if(len == 0) - break; + if(len == 0) { + if(quit) + break; + readonly = true; + continue; + } + if(buf[0] == '#') + s.outseqno = atoi(buf + 1); if(buf[0] == '^') sptps_send_record(&s, SPTPS_HANDSHAKE, NULL, 0); else if(buf[0] == '$') { @@ -202,7 +291,11 @@ int main(int argc, char *argv[]) { char hex[len * 2 + 1]; bin2hex(buf, hex, len); fprintf(stderr, "Received %d bytes of data:\n%s\n", (int)len, hex); - if(!sptps_receive_data(&s, buf, len)) + if((rand() % 100) < packetloss) { + fprintf(stderr, "Dropped.\n"); + continue; + } + if(!sptps_receive_data(&s, buf, len) && !datagram) return 1; } } diff --git a/src/subnet.c b/src/subnet.c index 3b98030..7ff8f7a 100644 --- a/src/subnet.c +++ b/src/subnet.c @@ -29,7 +29,7 @@ #include "net.h" #include "netutl.h" #include "node.h" -#include "process.h" +#include "script.h" #include "subnet.h" #include "utils.h" #include "xalloc.h" diff --git a/src/tincctl.c b/src/tincctl.c index 55e14e5..a986af7 100644 --- a/src/tincctl.c +++ b/src/tincctl.c @@ -39,12 +39,6 @@ #include "tincctl.h" #include "top.h" -#ifdef HAVE_MINGW -#define SCRIPTEXTENSION ".bat" -#else -#define SCRIPTEXTENSION "" -#endif - static char **orig_argv; static int orig_argc; @@ -71,10 +65,8 @@ static bool force = false; bool tty = true; bool confbasegiven = false; bool netnamegiven = false; - -#ifdef HAVE_MINGW -static struct WSAData wsa_state; -#endif +char *scriptinterpreter = NULL; +char *scriptextension = ""; static struct option const long_options[] = { {"config", required_argument, NULL, 'c'}, @@ -686,14 +678,6 @@ bool connect_tincd(bool verbose) { fclose(f); -#ifdef HAVE_MINGW - if(WSAStartup(MAKEWORD(2, 2), &wsa_state)) { - if(verbose) - fprintf(stderr, "System call `%s' failed: %s", "WSAStartup", winerror(GetLastError())); - return false; - } -#endif - #ifndef HAVE_MINGW struct sockaddr_un sa; sa.sun_family = AF_UNIX; @@ -1622,7 +1606,7 @@ static int cmd_config(int argc, char *argv[]) { if(action < 0 && !removed) { remove(tmpfile); fprintf(stderr, "No configuration variables deleted.\n"); - return *value; + return *value != 0; } // Replace the configuration file with the new one @@ -1755,7 +1739,7 @@ static int cmd_init(int argc, char *argv[]) { return 1; } - if(strcmp(confdir, confbase) && mkdir(confdir, 0755) && errno != EEXIST) { + if(!confbase_given && mkdir(confdir, 0755) && errno != EEXIST) { fprintf(stderr, "Could not create directory %s: %s\n", confdir, strerror(errno)); return 1; } @@ -2370,6 +2354,15 @@ int main(int argc, char *argv[]) { return 0; } +#ifdef HAVE_MINGW + static struct WSAData wsa_state; + + if(WSAStartup(MAKEWORD(2, 2), &wsa_state)) { + fprintf(stderr, "System call `%s' failed: %s", "WSAStartup", winerror(GetLastError())); + return false; + } +#endif + srand(time(NULL)); crypto_init(); diff --git a/src/tincd.c b/src/tincd.c index 3d6db8b..84036ad 100644 --- a/src/tincd.c +++ b/src/tincd.c @@ -400,14 +400,7 @@ int main2(int argc, char **argv) { /* Setup sockets and open device. */ if(!setup_network()) - goto end_nonet; - - if(!init_control()) - goto end_nonet; - - /* Initiate all outgoing connections. */ - - try_outgoing_connections(); + goto end; /* Change process priority */ @@ -439,6 +432,10 @@ int main2(int argc, char **argv) { /* Start main loop. It only exits when tinc is killed. */ + logger(DEBUG_ALWAYS, LOG_NOTICE, "Ready"); + + try_outgoing_connections(); + status = main_loop(); /* Shutdown properly. */ @@ -446,12 +443,9 @@ int main2(int argc, char **argv) { if(debug_level >= DEBUG_CONNECTIONS) devops.dump_stats(); +end: close_network_connections(); -end: - exit_control(); - -end_nonet: logger(DEBUG_ALWAYS, LOG_NOTICE, "Terminating"); free(priority); diff --git a/test-driver b/test-driver new file mode 100755 index 0000000..32bf39e --- /dev/null +++ b/test-driver @@ -0,0 +1,127 @@ +#! /bin/sh +# test-driver - basic testsuite driver script. + +scriptversion=2012-06-27.10; # UTC + +# Copyright (C) 2011-2013 Free Software Foundation, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# This file is maintained in Automake, please report +# bugs to or send patches to +# . + +# Make unconditional expansion of undefined variables an error. This +# helps a lot in preventing typo-related bugs. +set -u + +usage_error () +{ + echo "$0: $*" >&2 + print_usage >&2 + exit 2 +} + +print_usage () +{ + cat <$log_file 2>&1 +estatus=$? +if test $enable_hard_errors = no && test $estatus -eq 99; then + estatus=1 +fi + +case $estatus:$expect_failure in + 0:yes) col=$red res=XPASS recheck=yes gcopy=yes;; + 0:*) col=$grn res=PASS recheck=no gcopy=no;; + 77:*) col=$blu res=SKIP recheck=no gcopy=yes;; + 99:*) col=$mgn res=ERROR recheck=yes gcopy=yes;; + *:yes) col=$lgn res=XFAIL recheck=no gcopy=yes;; + *:*) col=$red res=FAIL recheck=yes gcopy=yes;; +esac + +# Report outcome to console. +echo "${col}${res}${std}: $test_name" + +# Register the test result, and other relevant metadata. +echo ":test-result: $res" > $trs_file +echo ":global-test-result: $res" >> $trs_file +echo ":recheck: $recheck" >> $trs_file +echo ":copy-in-global-log: $gcopy" >> $trs_file + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/test/Makefile.am b/test/Makefile.am new file mode 100644 index 0000000..a9c3895 --- /dev/null +++ b/test/Makefile.am @@ -0,0 +1,23 @@ +TESTS = \ + basic.test \ + commandline.test \ + executables.test \ + import-export.test \ + invite-join.test \ + ping.test \ + sptps-basic.test \ + variables.test + +dist_check_SCRIPTS = $(TESTS) + +EXTRA_DIST = testlib.sh + +check_PROGRAMS = pong + +pong_SOURCES = pong.c + +clean-local: + -for pid in *.test.?/pid; do ../src/tinc --pidfile="$$pid" stop; done + -killall ../src/sptps_test + -killall pong + -rm -rf *.test.? diff --git a/test/Makefile.in b/test/Makefile.in new file mode 100644 index 0000000..c6421fa --- /dev/null +++ b/test/Makefile.in @@ -0,0 +1,908 @@ +# Makefile.in generated by automake 1.14 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2013 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +VPATH = @srcdir@ +am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +check_PROGRAMS = pong$(EXEEXT) +subdir = test +DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ + $(dist_check_SCRIPTS) $(top_srcdir)/depcomp \ + $(top_srcdir)/test-driver +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \ + $(top_srcdir)/m4/curses.m4 $(top_srcdir)/m4/lzo.m4 \ + $(top_srcdir)/m4/openssl.m4 $(top_srcdir)/m4/readline.m4 \ + $(top_srcdir)/m4/zlib.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am_pong_OBJECTS = pong.$(OBJEXT) +pong_OBJECTS = $(am_pong_OBJECTS) +pong_LDADD = $(LDADD) +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(pong_SOURCES) +DIST_SOURCES = $(pong_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__tty_colors_dummy = \ + mgn= red= grn= lgn= blu= brg= std=; \ + am__color_tests=no +am__tty_colors = { \ + $(am__tty_colors_dummy); \ + if test "X$(AM_COLOR_TESTS)" = Xno; then \ + am__color_tests=no; \ + elif test "X$(AM_COLOR_TESTS)" = Xalways; then \ + am__color_tests=yes; \ + elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \ + am__color_tests=yes; \ + fi; \ + if test $$am__color_tests = yes; then \ + red=''; \ + grn=''; \ + lgn=''; \ + blu=''; \ + mgn=''; \ + brg=''; \ + std=''; \ + fi; \ +} +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__recheck_rx = ^[ ]*:recheck:[ ]* +am__global_test_result_rx = ^[ ]*:global-test-result:[ ]* +am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]* +# A command that, given a newline-separated list of test names on the +# standard input, print the name of the tests that are to be re-run +# upon "make recheck". +am__list_recheck_tests = $(AWK) '{ \ + recheck = 1; \ + while ((rc = (getline line < ($$0 ".trs"))) != 0) \ + { \ + if (rc < 0) \ + { \ + if ((getline line2 < ($$0 ".log")) < 0) \ + recheck = 0; \ + break; \ + } \ + else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \ + { \ + recheck = 0; \ + break; \ + } \ + else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \ + { \ + break; \ + } \ + }; \ + if (recheck) \ + print $$0; \ + close ($$0 ".trs"); \ + close ($$0 ".log"); \ +}' +# A command that, given a newline-separated list of test names on the +# standard input, create the global log from their .trs and .log files. +am__create_global_log = $(AWK) ' \ +function fatal(msg) \ +{ \ + print "fatal: making $@: " msg | "cat >&2"; \ + exit 1; \ +} \ +function rst_section(header) \ +{ \ + print header; \ + len = length(header); \ + for (i = 1; i <= len; i = i + 1) \ + printf "="; \ + printf "\n\n"; \ +} \ +{ \ + copy_in_global_log = 1; \ + global_test_result = "RUN"; \ + while ((rc = (getline line < ($$0 ".trs"))) != 0) \ + { \ + if (rc < 0) \ + fatal("failed to read from " $$0 ".trs"); \ + if (line ~ /$(am__global_test_result_rx)/) \ + { \ + sub("$(am__global_test_result_rx)", "", line); \ + sub("[ ]*$$", "", line); \ + global_test_result = line; \ + } \ + else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \ + copy_in_global_log = 0; \ + }; \ + if (copy_in_global_log) \ + { \ + rst_section(global_test_result ": " $$0); \ + while ((rc = (getline line < ($$0 ".log"))) != 0) \ + { \ + if (rc < 0) \ + fatal("failed to read from " $$0 ".log"); \ + print line; \ + }; \ + printf "\n"; \ + }; \ + close ($$0 ".trs"); \ + close ($$0 ".log"); \ +}' +# Restructured Text title. +am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; } +# Solaris 10 'make', and several other traditional 'make' implementations, +# pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it +# by disabling -e (using the XSI extension "set +e") if it's set. +am__sh_e_setup = case $$- in *e*) set +e;; esac +# Default flags passed to test drivers. +am__common_driver_flags = \ + --color-tests "$$am__color_tests" \ + --enable-hard-errors "$$am__enable_hard_errors" \ + --expect-failure "$$am__expect_failure" +# To be inserted before the command running the test. Creates the +# directory for the log if needed. Stores in $dir the directory +# containing $f, in $tst the test, in $log the log. Executes the +# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and +# passes TESTS_ENVIRONMENT. Set up options for the wrapper that +# will run the test scripts (or their associated LOG_COMPILER, if +# thy have one). +am__check_pre = \ +$(am__sh_e_setup); \ +$(am__vpath_adj_setup) $(am__vpath_adj) \ +$(am__tty_colors); \ +srcdir=$(srcdir); export srcdir; \ +case "$@" in \ + */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \ + *) am__odir=.;; \ +esac; \ +test "x$$am__odir" = x"." || test -d "$$am__odir" \ + || $(MKDIR_P) "$$am__odir" || exit $$?; \ +if test -f "./$$f"; then dir=./; \ +elif test -f "$$f"; then dir=; \ +else dir="$(srcdir)/"; fi; \ +tst=$$dir$$f; log='$@'; \ +if test -n '$(DISABLE_HARD_ERRORS)'; then \ + am__enable_hard_errors=no; \ +else \ + am__enable_hard_errors=yes; \ +fi; \ +case " $(XFAIL_TESTS) " in \ + *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \ + am__expect_failure=yes;; \ + *) \ + am__expect_failure=no;; \ +esac; \ +$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT) +# A shell command to get the names of the tests scripts with any registered +# extension removed (i.e., equivalently, the names of the test logs, with +# the '.log' extension removed). The result is saved in the shell variable +# '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly, +# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)", +# since that might cause problem with VPATH rewrites for suffix-less tests. +# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'. +am__set_TESTS_bases = \ + bases='$(TEST_LOGS)'; \ + bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \ + bases=`echo $$bases` +RECHECK_LOGS = $(TEST_LOGS) +AM_RECURSIVE_TARGETS = check recheck +TEST_SUITE_LOG = test-suite.log +TEST_EXTENSIONS = @EXEEXT@ .test +am__test_logs1 = $(TESTS:=.log) +am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log) +TEST_LOGS = $(am__test_logs2:.test.log=.log) +TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver +TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \ + $(TEST_LOG_FLAGS) +am__set_b = \ + case '$@' in \ + */*) \ + case '$*' in \ + */*) b='$*';; \ + *) b=`echo '$@' | sed 's/\.log$$//'`; \ + esac;; \ + *) \ + b='$*';; \ + esac +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CURSES_LIBS = @CURSES_LIBS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ +LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ +LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +READLINE_LIBS = @READLINE_LIBS@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +TESTS = \ + basic.test \ + commandline.test \ + executables.test \ + import-export.test \ + invite-join.test \ + ping.test \ + sptps-basic.test \ + variables.test + +dist_check_SCRIPTS = $(TESTS) +EXTRA_DIST = testlib.sh +pong_SOURCES = pong.c +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .log .o .obj .test .test$(EXEEXT) .trs +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu test/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu test/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-checkPROGRAMS: + -test -z "$(check_PROGRAMS)" || rm -f $(check_PROGRAMS) + +pong$(EXEEXT): $(pong_OBJECTS) $(pong_DEPENDENCIES) $(EXTRA_pong_DEPENDENCIES) + @rm -f pong$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(pong_OBJECTS) $(pong_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pong.Po@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +# Recover from deleted '.trs' file; this should ensure that +# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create +# both 'foo.log' and 'foo.trs'. Break the recipe in two subshells +# to avoid problems with "make -n". +.log.trs: + rm -f $< $@ + $(MAKE) $(AM_MAKEFLAGS) $< + +# Leading 'am--fnord' is there to ensure the list of targets does not +# expand to empty, as could happen e.g. with make check TESTS=''. +am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck) +am--force-recheck: + @: + +$(TEST_SUITE_LOG): $(TEST_LOGS) + @$(am__set_TESTS_bases); \ + am__f_ok () { test -f "$$1" && test -r "$$1"; }; \ + redo_bases=`for i in $$bases; do \ + am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \ + done`; \ + if test -n "$$redo_bases"; then \ + redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \ + redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \ + if $(am__make_dryrun); then :; else \ + rm -f $$redo_logs && rm -f $$redo_results || exit 1; \ + fi; \ + fi; \ + if test -n "$$am__remaking_logs"; then \ + echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \ + "recursion detected" >&2; \ + else \ + am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \ + fi; \ + if $(am__make_dryrun); then :; else \ + st=0; \ + errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \ + for i in $$redo_bases; do \ + test -f $$i.trs && test -r $$i.trs \ + || { echo "$$errmsg $$i.trs" >&2; st=1; }; \ + test -f $$i.log && test -r $$i.log \ + || { echo "$$errmsg $$i.log" >&2; st=1; }; \ + done; \ + test $$st -eq 0 || exit 1; \ + fi + @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \ + ws='[ ]'; \ + results=`for b in $$bases; do echo $$b.trs; done`; \ + test -n "$$results" || results=/dev/null; \ + all=` grep "^$$ws*:test-result:" $$results | wc -l`; \ + pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \ + fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \ + skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \ + xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \ + xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \ + error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \ + if test `expr $$fail + $$xpass + $$error` -eq 0; then \ + success=true; \ + else \ + success=false; \ + fi; \ + br='==================='; br=$$br$$br$$br$$br; \ + result_count () \ + { \ + if test x"$$1" = x"--maybe-color"; then \ + maybe_colorize=yes; \ + elif test x"$$1" = x"--no-color"; then \ + maybe_colorize=no; \ + else \ + echo "$@: invalid 'result_count' usage" >&2; exit 4; \ + fi; \ + shift; \ + desc=$$1 count=$$2; \ + if test $$maybe_colorize = yes && test $$count -gt 0; then \ + color_start=$$3 color_end=$$std; \ + else \ + color_start= color_end=; \ + fi; \ + echo "$${color_start}# $$desc $$count$${color_end}"; \ + }; \ + create_testsuite_report () \ + { \ + result_count $$1 "TOTAL:" $$all "$$brg"; \ + result_count $$1 "PASS: " $$pass "$$grn"; \ + result_count $$1 "SKIP: " $$skip "$$blu"; \ + result_count $$1 "XFAIL:" $$xfail "$$lgn"; \ + result_count $$1 "FAIL: " $$fail "$$red"; \ + result_count $$1 "XPASS:" $$xpass "$$red"; \ + result_count $$1 "ERROR:" $$error "$$mgn"; \ + }; \ + { \ + echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \ + $(am__rst_title); \ + create_testsuite_report --no-color; \ + echo; \ + echo ".. contents:: :depth: 2"; \ + echo; \ + for b in $$bases; do echo $$b; done \ + | $(am__create_global_log); \ + } >$(TEST_SUITE_LOG).tmp || exit 1; \ + mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \ + if $$success; then \ + col="$$grn"; \ + else \ + col="$$red"; \ + test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \ + fi; \ + echo "$${col}$$br$${std}"; \ + echo "$${col}Testsuite summary for $(PACKAGE_STRING)$${std}"; \ + echo "$${col}$$br$${std}"; \ + create_testsuite_report --maybe-color; \ + echo "$$col$$br$$std"; \ + if $$success; then :; else \ + echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \ + if test -n "$(PACKAGE_BUGREPORT)"; then \ + echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \ + fi; \ + echo "$$col$$br$$std"; \ + fi; \ + $$success || exit 1 + +check-TESTS: + @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list + @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list + @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) + @set +e; $(am__set_TESTS_bases); \ + log_list=`for i in $$bases; do echo $$i.log; done`; \ + trs_list=`for i in $$bases; do echo $$i.trs; done`; \ + log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \ + $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \ + exit $$?; +recheck: all $(check_PROGRAMS) $(dist_check_SCRIPTS) + @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) + @set +e; $(am__set_TESTS_bases); \ + bases=`for i in $$bases; do echo $$i; done \ + | $(am__list_recheck_tests)` || exit 1; \ + log_list=`for i in $$bases; do echo $$i.log; done`; \ + log_list=`echo $$log_list`; \ + $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \ + am__force_recheck=am--force-recheck \ + TEST_LOGS="$$log_list"; \ + exit $$? +.test.log: + @p='$<'; \ + $(am__set_b); \ + $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +@am__EXEEXT_TRUE@.test$(EXEEXT).log: +@am__EXEEXT_TRUE@ @p='$<'; \ +@am__EXEEXT_TRUE@ $(am__set_b); \ +@am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ +@am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \ +@am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ +@am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT) + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) \ + $(dist_check_SCRIPTS) + $(MAKE) $(AM_MAKEFLAGS) check-TESTS +check: check-am +all-am: Makefile +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS) + -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs) + -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-checkPROGRAMS clean-generic clean-local mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: check-am install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am check check-TESTS check-am clean \ + clean-checkPROGRAMS clean-generic clean-local cscopelist-am \ + ctags ctags-am distclean distclean-compile distclean-generic \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic pdf pdf-am ps ps-am \ + recheck tags tags-am uninstall uninstall-am + + +clean-local: + -for pid in *.test.?/pid; do ../src/tinc --pidfile="$$pid" stop; done + -killall ../src/sptps_test + -killall pong + -rm -rf *.test.? + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/test/basic.test b/test/basic.test new file mode 100755 index 0000000..b181e75 --- /dev/null +++ b/test/basic.test @@ -0,0 +1,20 @@ +#!/bin/sh + +. ./testlib.sh + +# Initialize and test one node + +$tinc $c1 init foo +$tinc $c1 set DeviceType dummy +$tinc $c1 set Port 0 + +# Test running in the foreground + +(sleep 1; $tinc $c1 stop) & +$tinc $c1 start $r1 -D + +# Test running tinc in the background + +$tinc $c1 start $r1 +sleep 1 +$tinc $c1 stop diff --git a/test/commandline.test b/test/commandline.test new file mode 100755 index 0000000..e95c953 --- /dev/null +++ b/test/commandline.test @@ -0,0 +1,49 @@ +#!/bin/sh + +. ./testlib.sh + +# Initialize one node + +$tinc $c1 <$d1/tinc-up <$d1/tinc-up < + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "../src/system.h" + +uint8_t mymac[6] = {6, 5, 5, 6, 5, 5}; + +static ssize_t do_arp(uint8_t *buf, ssize_t len, struct sockaddr_in *in) { + struct ether_arp arp; + memcpy(&arp, buf + 14, sizeof arp); + + // Is it a valid ARP request? + if(ntohs(arp.arp_hrd) != ARPHRD_ETHER || ntohs(arp.arp_pro) != ETH_P_IP || arp.arp_hln != ETH_ALEN || arp.arp_pln != sizeof in->sin_addr.s_addr || ntohs(arp.arp_op) != ARPOP_REQUEST) + return 0; + + // Does it match our address? + if(memcmp(&in->sin_addr.s_addr, arp.arp_tpa, 4)) + return 0; + + // Swap addresses + memcpy(buf, buf + 6, 6); + memcpy(buf + 6, mymac, 6); + + arp.arp_op = htons(ARPOP_REPLY); + memcpy(arp.arp_tpa, arp.arp_spa, sizeof arp.arp_tpa); + memcpy(arp.arp_tha, arp.arp_sha, sizeof arp.arp_tha); + memcpy(arp.arp_spa, &in->sin_addr.s_addr, sizeof in->sin_addr.s_addr); + memcpy(arp.arp_sha, mymac, 6); + + memcpy(buf + 14, &arp, sizeof arp); + + return len; +} + +static ssize_t do_ipv4(uint8_t *buf, ssize_t len, struct sockaddr_in *in) { + struct ip ip; + struct icmp icmp; + + // Does it match our address? + if(memcmp(buf, mymac, 6)) + return 0; + + memcpy(&ip, buf + 14, sizeof ip); + if(memcmp(&ip.ip_dst, &in->sin_addr.s_addr, 4)) + return 0; + + // Is it an ICMP echo request? + if(ip.ip_p != IPPROTO_ICMP) + return 0; + + memcpy(&icmp, buf + 14 + sizeof ip, sizeof icmp); + if(icmp.icmp_type != ICMP_ECHO) + return 0; + + // Return an echo reply + memcpy(buf, buf + 6, 6); + memcpy(buf + 6, mymac, 6); + + ip.ip_dst = ip.ip_src; + memcpy(&ip.ip_src, &in->sin_addr.s_addr, 4); + + icmp.icmp_type = ICMP_ECHOREPLY; + + memcpy(buf + 14, &ip, sizeof ip); + memcpy(buf + 14 + sizeof ip, &icmp, sizeof icmp); + + return len; +} + +static ssize_t do_ipv6(uint8_t *buf, ssize_t len, struct sockaddr_in6 *in) { + return 0; +} + +int main(int argc, char *argv[]) { + if(argc != 4) { + fprintf(stderr, "Usage: %s \n", argv[0]); + return 1; + } + + struct addrinfo hints = {}, *ai = NULL; + hints.ai_socktype = SOCK_DGRAM; + hints.ai_flags = AI_ADDRCONFIG; + + errno = ENOENT; + if(getaddrinfo(argv[1], argv[2], &hints, &ai) || !ai) { + fprintf(stderr, "Could not resolve %s port %s: %s\n", argv[1], argv[2], strerror(errno)); + return 1; + } + + int fd; + fd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); + if(!fd) { + fprintf(stderr, "Could not create socket: %s\n", strerror(errno)); + return 1; + } + + static const int one = 1; + setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void *)&one, sizeof one); + + if(bind(fd, ai->ai_addr, ai->ai_addrlen)) { + fprintf(stderr, "Could not bind socket: %s\n", strerror(errno)); + return 1; + } + + switch(ai->ai_family) { + case AF_INET: { + struct ip_mreq mreq; + struct sockaddr_in in; + memcpy(&in, ai->ai_addr, sizeof in); + mreq.imr_multiaddr.s_addr = in.sin_addr.s_addr; + mreq.imr_interface.s_addr = htonl(INADDR_ANY); + if(setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (void *)&mreq, sizeof mreq)) { + fprintf(stderr, "Cannot join multicast group: %s\n", strerror(errno)); + return 1; + } +#ifdef IP_MULTICAST_LOOP + setsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP, (const void *)&one, sizeof one); +#endif + } break; + +#ifdef IPV6_JOIN_GROUP + case AF_INET6: { + struct ipv6_mreq mreq; + struct sockaddr_in6 in6; + memcpy(&in6, ai->ai_addr, sizeof in6); + memcpy(&mreq.ipv6mr_multiaddr, &in6.sin6_addr, sizeof mreq.ipv6mr_multiaddr); + mreq.ipv6mr_interface = in6.sin6_scope_id; + if(setsockopt(fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, (void *)&mreq, sizeof mreq)) { + fprintf(stderr, "Cannot join multicast group: %s\n", strerror(errno)); + return 1; + } +#ifdef IPV6_MULTICAST_LOOP + setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, (const void *)&one, sizeof one); +#endif + } break; +#endif + + default: + fprintf(stderr, "Multicast for address family %hx unsupported\n", ai->ai_family); + return 1; + } + + errno = ENOENT; + struct addrinfo *ai2 = NULL; + if(getaddrinfo(argv[3], NULL, &hints, &ai2) || !ai2) { + fprintf(stderr, "Could not resolve %s: %s\n", argv[3], strerror(errno)); + return 1; + } + + while(true) { + uint8_t buf[10000]; + struct sockaddr src; + socklen_t srclen; + ssize_t len = recvfrom(fd, buf, sizeof buf, 0, &src, &srclen); + if(len <= 0) + break; + + // Ignore short packets. + if(len < 14) + continue; + + uint16_t type = buf[12] << 8 | buf[13]; + + if(ai2->ai_family == AF_INET && type == ETH_P_IP) + len = do_ipv4(buf, len, (struct sockaddr_in *)ai2->ai_addr); + else if(ai2->ai_family == AF_INET && type == ETH_P_ARP) + len = do_arp(buf, len, (struct sockaddr_in *)ai2->ai_addr); + else if(ai2->ai_family == AF_INET6 && type == ETH_P_IPV6) + len = do_ipv6(buf, len, (struct sockaddr_in6 *)ai2->ai_addr); + else + continue; + + if(len > 0) + sendto(fd, buf, len, 0, ai->ai_addr, ai->ai_addrlen); + } + + return 0; +} diff --git a/test/sptps-basic.test b/test/sptps-basic.test new file mode 100755 index 0000000..2abb99c --- /dev/null +++ b/test/sptps-basic.test @@ -0,0 +1,32 @@ +#!/bin/sh + +. ./testlib.sh + +# Generate keys + +mkdir -p $d1 + +openssl ecparam -genkey -name secp521r1 -noout -out $d1/server.priv +openssl ecparam -genkey -name secp521r1 -noout -out $d1/client.priv +yes '' | openssl req -new -pubkey -key $d1/server.priv -noout -out $d1/server.pub +echo +yes '' | openssl req -new -pubkey -key $d1/client.priv -noout -out $d1/client.pub +echo + +# Test transfer of a simple file. + +(sleep 1; $sptps_test -q $d1/client.priv $d1/server.pub localhost 32750 <../README) & +$sptps_test $d1/server.priv $d1/client.pub 32750 >$d1/out1 +cmp $d1/out1 ../README + +$sptps_test -q $d1/server.priv $d1/client.pub 32750 <../NEWS & +sleep 1 +$sptps_test $d1/client.priv $d1/server.pub localhost 32750 > $d1/out2 +cmp $d1/out2 ../NEWS + +# Datagram mode + +$sptps_test -dq $d1/server.priv $d1/client.pub 32750 <../COPYING & +sleep 1 +sleep 1 | $sptps_test -dq $d1/client.priv $d1/server.pub localhost 32750 >$d1/out3 +cmp $d1/out3 ../COPYING diff --git a/test/testlib.sh b/test/testlib.sh new file mode 100644 index 0000000..39a2bf4 --- /dev/null +++ b/test/testlib.sh @@ -0,0 +1,48 @@ +#!/bin/sh + +# Paths to executables + +tincd=../src/tincd +tinc=../src/tinc +sptps_test=../src/sptps_test + +# Test directories + +case "$_" in + /*) + d1=$_.1 + d2=$_.2 + d3=$_.3 + ;; + *) + d1=$PWD/$_.1 + d2=$PWD/$_.2 + d3=$PWD/$_.3 + ;; +esac + +# Default arguments for both tinc and tincd + +c1="--config=$d1 --pidfile=$d1/pid" +c2="--config=$d2 --pidfile=$d2/pid" +c3="--config=$d3 --pidfile=$d3/pid" + +# Arguments when running tincd + +r1="--logfile=$d1/log -d5" +r2="--logfile=$d2/log -d5" +r3="--logfile=$d3/log -d5" + +# Check for leftover tinc daemons + +[ -f $d1/pid ] && $tinc $c1 stop +[ -f $d2/pid ] && $tinc $c2 stop +[ -f $d3/pid ] && $tinc $c3 stop + +# Remove test directories + +rm -rf $d1 $d2 $d3 + +# Exit on errors, log all commands being executed + +set -ex diff --git a/test/variables.test b/test/variables.test new file mode 100755 index 0000000..4cf9d5e --- /dev/null +++ b/test/variables.test @@ -0,0 +1,88 @@ +#!/bin/sh + +. ./testlib.sh + +# Initialize one node + +$tinc $c1 init foo +test "`$tinc $c1 get Name`" = "foo" + +# Test case sensitivity + +$tinc $c1 set Mode switch +test "`$tinc $c1 get Mode`" = "switch" +test "`$tinc $c1 get mode`" = "switch" +$tinc $c1 set mode router +test "`$tinc $c1 get Mode`" = "router" +test "`$tinc $c1 get mode`" = "router" +$tinc $c1 set Mode Switch +test "`$tinc $c1 get Mode`" = "Switch" + +# Test deletion + +$tinc $c1 del Mode hub && exit 1 || true +$tinc $c1 del Mode switch +test -z "`$tinc $c1 get Mode`" + +# There can only be one Mode variable + +$tinc $c1 add Mode switch +$tinc $c1 add Mode hub +test "`$tinc $c1 get Mode`" = "hub" + +# Test addition/deletion of multivalued variables + +$tinc $c1 add Subnet 1 +$tinc $c1 add Subnet 2 +$tinc $c1 add Subnet 2 +$tinc $c1 add Subnet 3 +test "`$tinc $c1 get Subnet`" = "1 +2 +2 +3" +$tinc $c1 del Subnet 2 +test "`$tinc $c1 get Subnet`" = "1 +3" +$tinc $c1 del Subnet +test -z "`$tinc $c1 get Subnet`" + +# We should not be able to get/set server variables using node.variable syntax + +test -z "`$tinc $c1 get foo.Name`" +$tinc $c1 set foo.Name bar && exit 1 || true + +# Test getting/setting host variables for other nodes + +touch $d1/hosts/bar + +$tinc $c1 add bar.PMTU 1 +$tinc $c1 add bar.PMTU 2 +test "`$tinc $c1 get bar.PMTU`" = "2" + +$tinc $c1 add bar.Subnet 1 +$tinc $c1 add bar.Subnet 2 +$tinc $c1 add bar.Subnet 2 +$tinc $c1 add bar.Subnet 3 +test "`$tinc $c1 get bar.Subnet`" = "1 +2 +2 +3" +$tinc $c1 del bar.Subnet 2 +test "`$tinc $c1 get bar.Subnet`" = "1 +3" +$tinc $c1 del bar.Subnet +test -z "`$tinc $c1 get bar.Subnet`" + +# We should not be able to get/set for nodes with invalid names + +touch $d1/hosts/qu-ux + +$tinc $c1 set qu-ux.Subnet 1 && exit 1 || true + +# We should not be able to set obsolete variables unless forced + +$tinc $c1 set PrivateKey 12345 && exit 1 || true +$tinc $c1 --force set PrivateKey 12345 +test "`$tinc $c1 get PrivateKey`" = "12345" +$tinc $c1 del PrivateKey +test -z "`$tinc $c1 get PrivateKey`" From 1813f3157e8bed35453c0c47f4ce48b2be6a3a72 Mon Sep 17 00:00:00 2001 From: Guus Sliepen Date: Mon, 26 Aug 2019 13:44:51 +0200 Subject: [PATCH 08/13] Import Upstream version 1.1~pre11 --- AUTHORS | 22 +- COPYING | 2 +- ChangeLog | 237 ++++ INSTALL | 4 +- Makefile.in | 18 +- NEWS | 78 ++ README | 17 +- THANKS | 27 +- aclocal.m4 | 143 +-- config.guess | 192 +--- config.h.in | 33 +- config.sub | 30 +- configure | 1026 ++++++++++------- configure.ac | 45 +- doc/Makefile.in | 15 +- doc/tinc.8.in | 47 +- doc/tinc.conf.5.in | 154 ++- doc/tinc.info | 460 +++++--- doc/tinc.texi | 169 ++- gui/Makefile.in | 15 +- gui/tinc-gui | 35 +- m4/Makefile.in | 15 +- m4/ax_check_compile_flag.m4 | 72 ++ m4/ax_check_link_flag.m4 | 71 ++ m4/curses.m4 | 9 +- m4/libgcrypt.m4 | 33 + m4/openssl.m4 | 6 +- missing | 4 +- src/Makefile.am | 84 +- src/Makefile.in | 373 +++++-- src/bsd/device.c | 99 +- src/chacha-poly1305/chacha-poly1305.c | 103 ++ src/chacha-poly1305/chacha-poly1305.h | 15 + src/chacha-poly1305/chacha.c | 215 ++++ src/chacha-poly1305/chacha.h | 24 + src/chacha-poly1305/poly1305.c | 197 ++++ src/chacha-poly1305/poly1305.h | 16 + src/cipher.h | 3 - src/conf.c | 30 +- src/connection.h | 4 +- src/control.c | 18 +- src/cygwin/device.c | 27 +- src/device.h | 8 +- src/dummy_device.c | 11 - src/ecdh.h | 4 +- src/ed25519/add_scalar.c | 56 + src/ed25519/ecdh.c | 51 + src/ed25519/ecdsa.c | 145 +++ src/{openssl => ed25519}/ecdsagen.c | 55 +- src/ed25519/ed25519.h | 38 + src/ed25519/fe.c | 1491 +++++++++++++++++++++++++ src/ed25519/fe.h | 41 + src/ed25519/fixedint.h | 70 ++ src/ed25519/ge.c | 467 ++++++++ src/ed25519/ge.h | 74 ++ src/ed25519/key_exchange.c | 79 ++ src/ed25519/keypair.c | 16 + src/ed25519/precomp_data.h | 1391 +++++++++++++++++++++++ src/ed25519/sc.c | 809 ++++++++++++++ src/ed25519/sc.h | 12 + src/ed25519/sha512.c | 275 +++++ src/ed25519/sha512.h | 21 + src/ed25519/sign.c | 31 + src/ed25519/verify.c | 77 ++ src/edge.c | 6 +- src/edge.h | 1 + src/event.c | 173 ++- src/event.h | 7 +- src/graph.c | 30 +- src/hash.c | 7 + src/hash.h | 1 + src/have.h | 1 + src/info.c | 7 +- src/invitation.c | 56 +- src/linux/device.c | 48 +- src/logger.h | 2 + src/meta.c | 11 +- src/meta.h | 6 +- src/mingw/device.c | 131 ++- src/multicast_device.c | 56 +- src/names.c | 24 +- src/net.c | 42 +- src/net.h | 34 +- src/net_packet.c | 471 +++++--- src/net_setup.c | 405 ++++--- src/net_socket.c | 110 +- src/node.c | 55 +- src/node.h | 5 +- src/openssl/cipher.c | 74 +- src/openssl/crypto.c | 68 +- src/openssl/ecdh.c | 96 -- src/openssl/ecdsa.c | 131 --- src/openssl/rsa.c | 4 +- src/process.c | 10 +- src/process.h | 1 + src/protocol.c | 11 - src/protocol.h | 3 +- src/protocol_auth.c | 90 +- src/protocol_edge.c | 22 +- src/protocol_key.c | 81 +- src/protocol_misc.c | 2 +- src/raw_socket_device.c | 28 +- src/route.c | 225 ++-- src/script.c | 2 +- src/solaris/device.c | 396 +++++-- src/sptps.c | 323 +++--- src/sptps.h | 26 +- src/sptps_keypair.c | 108 ++ src/sptps_speed.c | 232 ++++ src/sptps_test.c | 109 +- src/subnet.c | 44 +- src/subnet_parse.c | 307 ++--- src/tincctl.c | 232 ++-- src/tincd.c | 44 +- src/top.c | 25 +- src/uml_device.c | 45 +- src/utils.c | 75 +- src/utils.h | 15 +- src/vde_device.c | 29 +- src/version.c | 24 + src/version.h | 26 + test-driver | 20 +- test/Makefile.am | 1 + test/Makefile.in | 16 +- test/commandline.test | 1 + test/ns-ping.test | 70 ++ test/sptps-basic.test | 8 +- test/testlib.sh | 1 + 128 files changed, 10991 insertions(+), 3132 deletions(-) create mode 100644 m4/ax_check_compile_flag.m4 create mode 100644 m4/ax_check_link_flag.m4 create mode 100644 m4/libgcrypt.m4 create mode 100644 src/chacha-poly1305/chacha-poly1305.c create mode 100644 src/chacha-poly1305/chacha-poly1305.h create mode 100644 src/chacha-poly1305/chacha.c create mode 100644 src/chacha-poly1305/chacha.h create mode 100644 src/chacha-poly1305/poly1305.c create mode 100644 src/chacha-poly1305/poly1305.h create mode 100644 src/ed25519/add_scalar.c create mode 100644 src/ed25519/ecdh.c create mode 100644 src/ed25519/ecdsa.c rename src/{openssl => ed25519}/ecdsagen.c (58%) create mode 100644 src/ed25519/ed25519.h create mode 100644 src/ed25519/fe.c create mode 100644 src/ed25519/fe.h create mode 100644 src/ed25519/fixedint.h create mode 100644 src/ed25519/ge.c create mode 100644 src/ed25519/ge.h create mode 100644 src/ed25519/key_exchange.c create mode 100644 src/ed25519/keypair.c create mode 100644 src/ed25519/precomp_data.h create mode 100644 src/ed25519/sc.c create mode 100644 src/ed25519/sc.h create mode 100644 src/ed25519/sha512.c create mode 100644 src/ed25519/sha512.h create mode 100644 src/ed25519/sign.c create mode 100644 src/ed25519/verify.c delete mode 100644 src/openssl/ecdh.c delete mode 100644 src/openssl/ecdsa.c create mode 100644 src/sptps_keypair.c create mode 100644 src/sptps_speed.c create mode 100644 src/version.c create mode 100644 src/version.h create mode 100755 test/ns-ping.test diff --git a/AUTHORS b/AUTHORS index af11393..07939e8 100644 --- a/AUTHORS +++ b/AUTHORS @@ -1,20 +1,25 @@ Main tinc authors: + - Guus Sliepen - Ivo Timmermans (inactive) -Significant contributions from: -- Michael Tokarev +Significant code contributions from: + +- Brandon Black +- Etienne Dechamps - Florian Forster - Grzegorz Dymarek -- Max Rijevski -- Scott Lamb - Julien Muchembled -- Timothy Redaelli -- Brandon Black - Loïc Grenié +- Max Rijevski +- Michael Tokarev +- Scott Lamb +- Sven-Haegar Koch +- Timothy Redaelli These files are from other sources: - * lib/pidfile.h and lib/pidfile.c are by Martin Schulze, taken from + +* lib/pidfile.h and lib/pidfile.c are by Martin Schulze, taken from the syslog 1.3 sources. * src/bsd/tunemu.c and tunemu.h are by Friedrich Schöller @@ -23,5 +28,4 @@ These files are from other sources: Also some of the macro files in the directory m4, and their accompanying files in lib, were taken from GNU fileutils. -Please see the file THANKS for more information on contributions from -users. +Please see the file THANKS for a list of all contributors to tinc. diff --git a/COPYING b/COPYING index f4dd065..c3d1ceb 100644 --- a/COPYING +++ b/COPYING @@ -1,4 +1,4 @@ -Copyright (C) 1998-2013 Ivo Timmermans, Guus Sliepen and others. +Copyright (C) 1998-2014 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/ChangeLog b/ChangeLog index 9eeabde..b2faf52 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,240 @@ +Version 1.1pre11 December 27 2014 +------------------------------------------------------------------------ + +Etienne Dechamps (68): + Move Solaris if_fd to local scope. + Make device close cleaner. + Cleanly remove the device FD from the event loop before closing it. + Add DeviceStandby option to only enable the device when nodes are reachable. + Make DeviceStandby control network interface link status on Windows. + Fix Windows includes. + Fix errno references when handling socket errors. + Protect against spurious connection events. + Fix connection event error handling. + Use native Windows events for the event loop. + Make the event loop expose a Windows event interface. + Use a Windows event to stop tinc when running as a service. + Remove the TAP-Win32 reader thread. + Add local address information to edges. + Use edge local addresses for local discovery. + Remove broadcast-based local discovery mechanism. + Enable LocalDiscovery by default. + Implement sptps_verify_datagram(). + Make broadcast addresses configurable. + Make IPv4 multicast space 224.0.0.0/4 broadcast by default. + Regenerate build date and time every time tinc is built. + Use git description as the tinc version. + Rewrite, fix and improve str2net(). + When printing MAC addresses, always use trailing zeroes. + Don't print subnet prefix lengths and weights for one-host subnets. + Canonicalize IPv6 addresses as per RFC 5952 before printing them. + Fix tinc event loop reentrancy from timeout handlers. + Make sure myport is set correctly when running with Port = 0. + Fix event loop io tree inconsistency on Windows. + Fix a typo (FORTIFY_SOURCE). + Handle the "no local address" case in send_sptps_data(). + Don't initialize outpkt to an unused value. + Remove redundant connection_t::status.active field. + Only declare the origpriority variable if we support priority. + Remove an unnecessary pointer dereference in execute_script(). + Fix callback signature for TAP-Win32 device_handle_read(). + Remove unused variable in TAP-Win32 setup_device(). + Remove unused device stats variables. + Resolve KEY_EVENT conflict between Windows and ncurses. + Check if devops is valid before closing the device. + Shutdown cleanly when receiving a Windows console shutdown request. + Fix "tinc start" on Windows when the path contains spaces. + Improve subprocess behavior in tinc start command. + Add documentation about using system-assigned ports. + Verify seqno early in sptps_verify_datagram(). + Add a non-interactive mode to tinc commands. + Only read from TAP-Win32 if the device is enabled. + Handle TAP-Win32 immediate reads correctly. + Clarify copyright ownership for code authored by Etienne Dechamps. + Remove Google from the list of copyright owners. + Fix undefined HOST_NAME_MAX on Windows. + Don't enable the device if the reachable count is zero. + Fix wrong identifier in SO_NOSIGPIPE call. + Fix default TAP device on Darwin. + Ignore the Interface option if device rename is impossible. + Fix default device path selection on BSD. + Preemptively mirror REQ_PUBKEY messages from nodes with unknown keys. + Fix protocol version check for type 2 MTU probe replies. + Invalidate UDP information on address changes. + Introduce node IDs. + Change vpn_packet_t::seqno from uint32_t to uint8_t[4]. + Prepend source node ID information to UDP datagrams. + Add UDP datagram relay support to SPTPS. + Don't send MTU probes to nodes we can't reach directly. + Make sure to discover MTU with relays. + Query the Linux device for its MAC address. + Don't spontaneously start SPTPS with neighbors. + Use plain old PACKET for TCP packets sent directly to a neighbor. + +Guus Sliepen (68): + Really fix compiling under Windows. + Add missing attribution for 1.1pre10 to the NEWS file. + Add "network" command to list or switch networks. + Rewind the file before trying to use PEM_read_RSA_PUBKEY(). + Handle a disconnecting tincd better. + Fix return value of b64encode(). + Use Ed25519 keys. + Properly initialize buffers. + Merge branch '1.1-ed25519' into 1.1 + Use the ChaCha-Poly1305 cipher for the SPTPS protocol. + sptps_test: allow using a tun device instead of stdio. + Put brackets around IPv6 addresses in invitation URL, even if there is no port number. + Nexthop calculation should always use the shortest path. + Fix compiler warnings. + Change AutoConnect from int to bool. + Use void pointers to opaque buffers. + Add missing closedir(). + Fix a crash when we have a malformed public ECDSA key of another node. + Fix PMTU discovery via datagram SPTPS. + Add sanity checks when generating new RSA keys. + Rename ECDSA to Ed25519. + Implement a PEM-like format for Ed25519 keys. + Allow Cipher and Digest "none". + Fix base64 decoding of Ed25519 keys. + Return non-zero exit code when "tinc get" does not find the requested variable. + Unconditionally return non-zero exit code when "tinc del" does not find the requested variable. + Remove the warnings when IP_DONTFRAGMENT/IPV6-DONTFRAG is not supported. + Merge branch 'winevents-clean' of https://github.com/dechamps/tinc into 1.1 + Give getsockopt() a reference to a socklen_t. + Fix compiler warnings. + Fix segmentation fault when dumping subnets. + Fix incorrect format qualifiers. + Reserve legacy active bit in connection_status_t. + Fix a potential file descriptor leak. + Fix unsafe use of strncpy() and sprintf(). + Merge branch 'winwarnings' of https://github.com/dechamps/tinc into 1.1 + Merge branch 'ctrl' of https://github.com/dechamps/tinc into 1.1 + Merge branch 'tincstart' of https://github.com/dechamps/tinc into 1.1 + Merge branch 'keysegfault' of https://github.com/dechamps/tinc into 1.1 + Revert "Use git description as the tinc version." + Fix compiler warnings. + Check validity of Ed25519 key during an upgrade. + Log an error message with the node's name when receiving bad SPTPS packets. + Better log messages when we already know the peer's key during an upgrade. + Add an explicit hash_delete() function. + Cache node IDs in a hash table for faster lookups. + Avoid memmove() for legacy UDP packets. + Make UDP packet handling more efficient. + Changes that should have been in commit 46fa12e666badb79e480c4b2399787551f8266d0. + Fix segfault when receiving UDP packets with an unknown source address. + Fix reception of SPTPS UDP packets. + Avoid using OpenSSL's random number functions. + Don't pass uninitialized bytes to ioctl(). + Don't use myself->name in device_disable(), it's already freed. + Fix memory leaks found by Valgrind. + Use void pointers for opaque data blobs in the SPTPS code. + Add a variable offset to vpn_packet_t, drop sptps_packet_t. + Merge remote-tracking branch 'groxxda/gui-fixes' into 1.1 + Allow running tinc without RSA keys. + Update THANKS file. + Check whether res_init() really lives in libresolv. + BSD make doesn't like .PHONY .c files. + We don't depend on ECDH functions from OpenSSL anymore. + Linux doesn't like .PHONY .o files. + Remove AES-GCM support. + Better default paths for log and PID files on Windows. + Add BroadcastSubnet and DeviceStandby options to the manual and completion. + Releasing 1.1pre11. + +Sven-Haegar Koch (4): + Fix exit code of "tinc get". + commandline.test: Adding test that fetching non-existing config setting really fails. + Do not disconnect when no ecdsa key is known yet. + Try handling the case when the first side knows the ecdsa key of + +William A. Kennington III (3): + utils: Refactor get_name's functionality into util for global access + utils: Refactor check_id out of protocol for global access + tincctl: Use replace_name to properly replace and validate input hostnames + +Baptiste Jonglez (2): + Clarify man page regarding the IndirectData option + Fix typos in the manual page + +Alexis Hildebrandt (1): + Add support to link against libresolv Mac OS X + +Armin Fisslthaler (1): + reload /etc/resolv.conf in SIGALRM handler + +Franz Pletz (1): + tinc-gui: Use /usr/bin/env to resolve path to python + +Saverio Proto (1): + Fix typo in comment + +groxxda (1): + tinc-gui: Don't assign broadcast subnets to any node, fix parsing of Edges, fix diplay of Subnet.weight. + +Version 1.1pre10 February 07 2014 +------------------------------------------------------------------------ + +Guus Sliepen (52): + Wrong date for the 1.1pre9 release in the NEWS. + Avoid using BIOs. + Add a benchmark for the SPTPS protocol. + Don't leak memory during the key generation speed test. + Link sptps_speed with -lrt. + Fix segfault when Name = $HOST but $HOST is not set. + Fix typos in the documentation. + Use AES-256-GCM for the SPTPS protocol. + Fix sending empty SPTPS records. + Clean up child processes from proxy type exec. + Make sptps_test less verbose by default. + Fix sending bulk data starting with a newline. + Fix two warnings from Clang's static analyzer. + Remove an unused variable. + Make LocalDiscovery work for SPTPS packets. + Allow "none" for Cipher and Digest again. + Mention in the manual that multiple Address staments are allowed. + If no Port is specified, set myport to actual port of first listening socket. + Update support for Solaris. + Include for PATH_MAX. + Stricter check for raw socket support. + Avoid using a variable named "sun". Solaris doesn't like it. + Use hardcoded value for TUNNEWPPA if net/if_tun.h is missing on Solaris. + Prefer ncurses over curses. + Don't print device statistics when exiting tinc. + Allow running without ECDSA keys If ExperimentalProtocol is not explicitly set. + Give full path to unconfigured tinc-up script. + Don't print an error when no ECDSA key is known for a node using the legacy protocol. + Remove erroneous warning about SPTPS being disabled. + Enable compiler hardening flags by default. + Add our own autoconf check for libgcrypt. + Don't enable -fstack-protector-all. + Fix handling of --with-libgcrypt. + Clarify StrictSubnets. + Update the documentation of the tinc command. + Add index entries for the CLI commands. + Let tinc-gui use correct address family when connecting to tincd via TCP. + Document clearly that tinc depends on curses and readline libraries. + Document that 1.1 uses AES-256 in GCM mode. + Add the ListenAddress option. + Test two tinc daemons using network namespaces. + Add missing newlines when copying variables from tinc.conf to an invitation file. + Don't ask questions if we are not running interactively. + Document Weight and also allow it to be set from tinc.conf. + Use addresses learned from other nodes when making outgoing connections. + Attribution for various contributors. + Handle errors from TAP-Win32/64 adapter in a better way. + Attribution for Dennis Joachimsthaler. + Update copyright notices. + Fix compiling for Windows. + Check whether OpenSSL has support for GCM. + Releasing 1.1pre10. + +Dennis Joachimsthaler (2): + Fix tinc-gui on Windows. + Ensure tinc-gui running in 64 bits mode can find tinc's 32 bit registry key. + +Florent Clairambault (1): + Adding "conf.d" configuration dir support. + Version 1.1pre9 September 08 2013 ------------------------------------------------------------------------ diff --git a/INSTALL b/INSTALL index 007e939..2099840 100644 --- a/INSTALL +++ b/INSTALL @@ -12,8 +12,8 @@ without warranty of any kind. Basic Installation ================== - Briefly, the shell commands `./configure; make; make install' should -configure, build, and install this package. The following + Briefly, the shell command `./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. Some packages provide this `INSTALL' file but do not implement all of the features documented diff --git a/Makefile.in b/Makefile.in index a464e9e..797d7bf 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1,4 +1,4 @@ -# Makefile.in generated by automake 1.14 from Makefile.am. +# Makefile.in generated by automake 1.14.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. @@ -85,9 +85,12 @@ DIST_COMMON = INSTALL NEWS README AUTHORS ChangeLog \ config.sub depcomp install-sh missing ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \ - $(top_srcdir)/m4/curses.m4 $(top_srcdir)/m4/lzo.m4 \ - $(top_srcdir)/m4/openssl.m4 $(top_srcdir)/m4/readline.m4 \ - $(top_srcdir)/m4/zlib.m4 $(top_srcdir)/configure.ac + $(top_srcdir)/m4/ax_check_compile_flag.m4 \ + $(top_srcdir)/m4/ax_check_link_flag.m4 \ + $(top_srcdir)/m4/curses.m4 $(top_srcdir)/m4/libgcrypt.m4 \ + $(top_srcdir)/m4/lzo.m4 $(top_srcdir)/m4/openssl.m4 \ + $(top_srcdir)/m4/readline.m4 $(top_srcdir)/m4/zlib.m4 \ + $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ @@ -223,9 +226,6 @@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ -LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ -LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ -LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LN_S = @LN_S@ @@ -241,7 +241,6 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ -RANLIB = @RANLIB@ READLINE_LIBS = @READLINE_LIBS@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ @@ -599,9 +598,10 @@ distcheck: dist && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ && am__cwd=`pwd` \ && $(am__cd) $(distdir)/_build \ - && ../configure --srcdir=.. --prefix="$$dc_install_base" \ + && ../configure \ $(AM_DISTCHECK_CONFIGURE_FLAGS) \ $(DISTCHECK_CONFIGURE_FLAGS) \ + --srcdir=.. --prefix="$$dc_install_base" \ && $(MAKE) $(AM_MAKEFLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) dvi \ && $(MAKE) $(AM_MAKEFLAGS) check \ diff --git a/NEWS b/NEWS index a0ca1d7..abd6a6f 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,81 @@ +Version 1.1pre11 December 27 2014 + + * Added a "network" command to list or switch networks. + + * Switched to Ed25519 keys and the ChaCha-Poly1305 cipher for the new protocol. + + * AutoConnect is now a boolean option, when enabled tinc always tries to keep + at least three meta-connections open. + + * The new protocol now uses UDP much more often. + + * Tinc "del" and "get" commands now return a non-zero exit code when they + don't find the requested variable. + + * Updated documentation. + + * Added a "DeviceStandby" option to defer running tinc-up until a working + connection is made, and which on Windows will also change the network + interface link status accordingly. + + * Tinc now tells the resolver to reload /etc/resolv.conf when it receives + SIGALRM. + + * Improved error messages and event loop handling on Windows. + + * LocalDiscovery now uses local address learned from other nodes, and is + enabled by default. + + * Added a "BroadcastSubnet" option to change the behavior of broadcast packets + in router mode. + + * Added support for dotted quad notation in IPv6 (e.g. ::1.2.3.4). + + * Improved format of printed Subnets, MAC and IPv6 addresses. + + * Added a "--batch" option to force the tinc CLI to run in non-interactive + mode. + + * Improve default Device selection on *BSD and Mac OS X. + + * Allow running tinc without RSA keys. + +Thanks to Etienne Dechamps, Sven-Haegar Koch, William A. Kennington III, +Baptiste Jonglez, Alexis Hildebrandt, Armin Fisslthaler, Franz Pletz, Alexander +Ried and Saverio Proto for their contributions to this version of tinc. + +Version 1.1pre10 February 7 2014 + + * Added a benchmark tool (sptps_speed) for the new protocol. + + * Fixed a crash when using Name = $HOST while $HOST is not set. + + * Use AES-256-GCM for the new protocol. + + * Updated support for Solaris. + + * Allow running tincd without a private ECDSA key present when + ExperimentalProtocol is not explicitly set. + + * Enable various compiler hardening flags by default. + + * Added support for a "conf.d" configuration directory. + + * Fix tinc-gui on Windows, also allowing it to connect to a 32-bits tincd when + tinc-gui is run in a 64-bits Python environment. + + * Added a "ListenAddress" option, which like BindToAddress adds more listening + address/ports, but doesn't bind to them for outgoing sockets. + + * Make invitations work better when the "invite" and "join" commands are not + run interactively. + + * When creating meta-connections to a node for which no Address statement is + specified, try to use addresses learned from other nodes. + +Thanks to Dennis Joachimsthaler and Florent Clairambault for their contribution +to this version of tinc. + Version 1.1pre9 September 8 2013 * The UNIX socket is now created before tinc-up is called. diff --git a/README b/README index ec53243..c88027b 100644 --- a/README +++ b/README @@ -1,7 +1,7 @@ -This is the README file for tinc version 1.1pre9. Installation +This is the README file for tinc version 1.1pre11. Installation instructions may be found in the INSTALL file. -tinc is Copyright (C) 1998-2013 by: +tinc is Copyright (C) 1998-2014 by: Ivo Timmermans, Guus Sliepen , @@ -36,12 +36,11 @@ at your own risk. Compatibility ------------- -Version 1.1pre9 is compatible with 1.0pre8, 1.0 and later, but not with older +Version 1.1pre11 is compatible with 1.0pre8, 1.0 and later, but not with older versions of tinc. -When the ExperimentalProtocol option is used, which is the default since -1.1pre8, tinc is still compatible with 1.0.X and 1.1pre9 itself, but not with -any other 1.1preX version. +When the ExperimentalProtocol option is used, tinc is still compatible with +1.0.X and 1.1pre11 itself, but not with any other 1.1preX version. Requirements @@ -51,7 +50,7 @@ In order to compile tinc, you will need a GNU C compiler environment. Please ensure you have the latest stable versions of all the required libraries: - OpenSSL (http://www.openssl.org/) version 1.0.0 or later, with support for - elliptic curve cryptography (ECC) enabeld. + elliptic curve cryptography (ECC) and Galois counter mode (GCM) enabled. The following libraries are used by default, but can be disabled if necessary: @@ -73,8 +72,8 @@ be forwarded by intermediate nodes. By default, nodes authenticate each other using 2048 bit RSA (or 521 bit ECDSA*) keys. Traffic is encrypted using Blowfish in CBC mode (or AES-256 in -CTR mode*), authenticated using HMAC-SHA1 (or HMAC-SHA-256*), and is protected -against replay attacks. +GCM mode*), authenticated using HMAC-SHA1 (or GCM*), and is protected against +replay attacks. *) When using the ExperimentalProtocol option. diff --git a/THANKS b/THANKS index 6753c2f..d1ee6b4 100644 --- a/THANKS +++ b/THANKS @@ -1,34 +1,51 @@ We would like to thank the following people for their contributions to tinc: * Alexander Reil and Gemeinde Berg +* Alexander Ried +* Alexis Hildebrandt * Allesandro Gatti * Andreas van Cranenburgh * Anthony G. Basile * Armijn Hemel +* Armin Fisslthaler +* Baptiste Jonglez +* Borg * Brandon Black * Cheng LI * Cris van Pelt * Darius Jahandarie +* David Pflug * Delf Eldkraft +* Dennis Joachimsthaler * dnk * Enrique Zanardi * Erik Tews * Etienne Dechamps +* Florent Clairambault * Flynn Marquardt +* Franz Pletz +* Gary Kessler and Claudia Gonzalez * Grzegorz Dymarek * Hans Bayle * Ivo van Dong +* James Cook * James MacLean * Jamie Briggs * Jason Harper +* Jason Livesay +* Jelle de Jong * Jeroen Ubbink * Jerome Etienne +* Jochen Voss * Julien Muchembled +* Lavrans Laading +* Loïc Dachary * Loïc Grenié * Lubomír Bulej * Mads Kiilerich * Marc A. Lehmann * Mark Glines +* Mark Petryk * Markus Goetz * Martin Kihlgren * Martin Schobert @@ -45,16 +62,24 @@ We would like to thank the following people for their contributions to tinc: * Philipp Babel * Robert van der Meulen * Rumko +* Saverio Proto * Scott Lamb +* Steffan Karger * Sven-Haegar Koch * Teemu Kiviniemi +* Thomas Tsiakalakis * Timothy Redaelli +* Tomislav Čohar +* Tommy Arnkværn * Tonnerre Lombard * Vil Brekin +* Vittorio Gambaletta * Wessel Dankers +* William A. Kennington III +* William McArthur * Wouter van Heyst -And everyone we forgot. Thank you! +And everyone we forgot (if we did, please let us know). Thank you! Ivo Timmermans Guus Sliepen diff --git a/aclocal.m4 b/aclocal.m4 index e3a5dd9..16c89a3 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -1,4 +1,4 @@ -# generated automatically by aclocal 1.14 -*- Autoconf -*- +# generated automatically by aclocal 1.14.1 -*- Autoconf -*- # Copyright (C) 1996-2013 Free Software Foundation, Inc. @@ -20,130 +20,6 @@ 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'.])]) -dnl Autoconf macros for libgcrypt -dnl Copyright (C) 2002, 2004 Free Software Foundation, Inc. -dnl -dnl This file is free software; as a special exception the author gives -dnl unlimited permission to copy and/or distribute it, with or without -dnl modifications, as long as this notice is preserved. -dnl -dnl This file is distributed in the hope that it will be useful, but -dnl WITHOUT ANY WARRANTY, to the extent permitted by law; without even the -dnl implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - - -dnl AM_PATH_LIBGCRYPT([MINIMUM-VERSION, -dnl [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND ]]]) -dnl Test for libgcrypt and define LIBGCRYPT_CFLAGS and LIBGCRYPT_LIBS. -dnl MINIMUN-VERSION is a string with the version number optionalliy prefixed -dnl with the API version to also check the API compatibility. Example: -dnl a MINIMUN-VERSION of 1:1.2.5 won't pass the test unless the installed -dnl version of libgcrypt is at least 1.2.5 *and* the API number is 1. Using -dnl this features allows to prevent build against newer versions of libgcrypt -dnl with a changed API. -dnl -AC_DEFUN([AM_PATH_LIBGCRYPT], -[ AC_ARG_WITH(libgcrypt-prefix, - AC_HELP_STRING([--with-libgcrypt-prefix=PFX], - [prefix where LIBGCRYPT is installed (optional)]), - libgcrypt_config_prefix="$withval", libgcrypt_config_prefix="") - if test x$libgcrypt_config_prefix != x ; then - if test x${LIBGCRYPT_CONFIG+set} != xset ; then - LIBGCRYPT_CONFIG=$libgcrypt_config_prefix/bin/libgcrypt-config - fi - fi - - AC_PATH_TOOL(LIBGCRYPT_CONFIG, libgcrypt-config, no) - tmp=ifelse([$1], ,1:1.2.0,$1) - if echo "$tmp" | grep ':' >/dev/null 2>/dev/null ; then - req_libgcrypt_api=`echo "$tmp" | sed 's/\(.*\):\(.*\)/\1/'` - min_libgcrypt_version=`echo "$tmp" | sed 's/\(.*\):\(.*\)/\2/'` - else - req_libgcrypt_api=0 - min_libgcrypt_version="$tmp" - fi - - AC_MSG_CHECKING(for LIBGCRYPT - version >= $min_libgcrypt_version) - ok=no - if test "$LIBGCRYPT_CONFIG" != "no" ; then - req_major=`echo $min_libgcrypt_version | \ - sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\1/'` - req_minor=`echo $min_libgcrypt_version | \ - sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\2/'` - req_micro=`echo $min_libgcrypt_version | \ - sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\3/'` - libgcrypt_config_version=`$LIBGCRYPT_CONFIG --version` - major=`echo $libgcrypt_config_version | \ - sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*/\1/'` - minor=`echo $libgcrypt_config_version | \ - sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*/\2/'` - micro=`echo $libgcrypt_config_version | \ - sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*/\3/'` - if test "$major" -gt "$req_major"; then - ok=yes - else - if test "$major" -eq "$req_major"; then - if test "$minor" -gt "$req_minor"; then - ok=yes - else - if test "$minor" -eq "$req_minor"; then - if test "$micro" -ge "$req_micro"; then - ok=yes - fi - fi - fi - fi - fi - fi - if test $ok = yes; then - AC_MSG_RESULT([yes ($libgcrypt_config_version)]) - else - AC_MSG_RESULT(no) - fi - if test $ok = yes; then - # If we have a recent libgcrypt, we should also check that the - # API is compatible - if test "$req_libgcrypt_api" -gt 0 ; then - tmp=`$LIBGCRYPT_CONFIG --api-version 2>/dev/null || echo 0` - if test "$tmp" -gt 0 ; then - AC_MSG_CHECKING([LIBGCRYPT API version]) - if test "$req_libgcrypt_api" -eq "$tmp" ; then - AC_MSG_RESULT([okay]) - else - ok=no - AC_MSG_RESULT([does not match. want=$req_libgcrypt_api got=$tmp]) - fi - fi - fi - fi - if test $ok = yes; then - LIBGCRYPT_CFLAGS=`$LIBGCRYPT_CONFIG --cflags` - LIBGCRYPT_LIBS=`$LIBGCRYPT_CONFIG --libs` - ifelse([$2], , :, [$2]) - if test x"$host" != x ; then - libgcrypt_config_host=`$LIBGCRYPT_CONFIG --host 2>/dev/null || echo none` - if test x"$libgcrypt_config_host" != xnone ; then - if test x"$libgcrypt_config_host" != x"$host" ; then - AC_MSG_WARN([[ -*** -*** The config script $LIBGCRYPT_CONFIG was -*** built for $libgcrypt_config_host and thus may not match the -*** used host $host. -*** You may want to use the configure option --with-libgcrypt-prefix -*** to specify a matching config script. -***]]) - fi - fi - fi - else - LIBGCRYPT_CFLAGS="" - LIBGCRYPT_LIBS="" - ifelse([$3], , :, [$3]) - fi - AC_SUBST(LIBGCRYPT_CFLAGS) - AC_SUBST(LIBGCRYPT_LIBS) -]) - # Copyright (C) 2002-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation @@ -159,7 +35,7 @@ AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version='1.14' 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.14], [], +m4_if([$1], [1.14.1], [], [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl ]) @@ -175,7 +51,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.14])dnl +[AM_AUTOMAKE_VERSION([1.14.1])dnl m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) @@ -227,10 +103,9 @@ _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) # configured tree to be moved without reconfiguration. AC_DEFUN([AM_AUX_DIR_EXPAND], -[dnl Rely on autoconf to set up CDPATH properly. -AC_PREREQ([2.50])dnl -# expand $ac_aux_dir to an absolute path -am_aux_dir=`cd $ac_aux_dir && pwd` +[AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl +# Expand $ac_aux_dir to an absolute path. +am_aux_dir=`cd "$ac_aux_dir" && pwd` ]) # AM_CONDITIONAL -*- Autoconf -*- @@ -697,7 +572,8 @@ to "yes", and re-run configure. END AC_MSG_ERROR([Your 'rm' program is bad, sorry.]) fi -fi]) +fi +]) dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further @@ -1272,7 +1148,10 @@ AC_SUBST([am__untar]) ]) # _AM_PROG_TAR m4_include([m4/attribute.m4]) +m4_include([m4/ax_check_compile_flag.m4]) +m4_include([m4/ax_check_link_flag.m4]) m4_include([m4/curses.m4]) +m4_include([m4/libgcrypt.m4]) m4_include([m4/lzo.m4]) m4_include([m4/openssl.m4]) m4_include([m4/readline.m4]) diff --git a/config.guess b/config.guess index b79252d..1f5c50c 100755 --- a/config.guess +++ b/config.guess @@ -1,8 +1,8 @@ #! /bin/sh # Attempt to guess a canonical system name. -# Copyright 1992-2013 Free Software Foundation, Inc. +# Copyright 1992-2014 Free Software Foundation, Inc. -timestamp='2013-06-10' +timestamp='2014-03-23' # 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 @@ -50,7 +50,7 @@ version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. -Copyright 1992-2013 Free Software Foundation, Inc. +Copyright 1992-2014 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 +149,7 @@ Linux|GNU|GNU/*) LIBC=gnu #endif EOF - eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'` + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC' | sed 's, ,,g'` ;; esac @@ -826,7 +826,7 @@ EOF *:MINGW*:*) echo ${UNAME_MACHINE}-pc-mingw32 exit ;; - i*:MSYS*:*) + *:MSYS*:*) echo ${UNAME_MACHINE}-pc-msys exit ;; i*:windows32*:*) @@ -969,10 +969,10 @@ EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; } ;; - or1k:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + openrisc*:Linux:*:*) + echo or1k-unknown-linux-${LIBC} exit ;; - or32:Linux:*:*) + or32:Linux:*:* | or1k*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; padre:Linux:*:*) @@ -1260,16 +1260,26 @@ EOF if test "$UNAME_PROCESSOR" = unknown ; then UNAME_PROCESSOR=powerpc fi - 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 - case $UNAME_PROCESSOR in - i386) UNAME_PROCESSOR=x86_64 ;; - powerpc) UNAME_PROCESSOR=powerpc64 ;; - esac + if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then + 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 + case $UNAME_PROCESSOR in + i386) UNAME_PROCESSOR=x86_64 ;; + powerpc) UNAME_PROCESSOR=powerpc64 ;; + esac + fi fi + elif test "$UNAME_PROCESSOR" = i386 ; then + # Avoid executing cc on OS X 10.9, as it ships with a stub + # that puts up a graphical alert prompting to install + # developer tools. Any system running Mac OS X 10.7 or + # later (Darwin 11 and later) is required to have a 64-bit + # processor. This is not true of the ARM version of Darwin + # that Apple uses in portable devices. + UNAME_PROCESSOR=x86_64 fi echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} exit ;; @@ -1361,154 +1371,6 @@ EOF exit ;; esac -eval $set_cc_for_build -cat >$dummy.c < -# include -#endif -main () -{ -#if defined (sony) -#if defined (MIPSEB) - /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, - I don't know.... */ - printf ("mips-sony-bsd\n"); exit (0); -#else -#include - printf ("m68k-sony-newsos%s\n", -#ifdef NEWSOS4 - "4" -#else - "" -#endif - ); exit (0); -#endif -#endif - -#if defined (__arm) && defined (__acorn) && defined (__unix) - printf ("arm-acorn-riscix\n"); exit (0); -#endif - -#if defined (hp300) && !defined (hpux) - printf ("m68k-hp-bsd\n"); exit (0); -#endif - -#if defined (NeXT) -#if !defined (__ARCHITECTURE__) -#define __ARCHITECTURE__ "m68k" -#endif - int version; - version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; - if (version < 4) - printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); - else - printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); - exit (0); -#endif - -#if defined (MULTIMAX) || defined (n16) -#if defined (UMAXV) - printf ("ns32k-encore-sysv\n"); exit (0); -#else -#if defined (CMU) - printf ("ns32k-encore-mach\n"); exit (0); -#else - printf ("ns32k-encore-bsd\n"); exit (0); -#endif -#endif -#endif - -#if defined (__386BSD__) - printf ("i386-pc-bsd\n"); exit (0); -#endif - -#if defined (sequent) -#if defined (i386) - printf ("i386-sequent-dynix\n"); exit (0); -#endif -#if defined (ns32000) - printf ("ns32k-sequent-dynix\n"); exit (0); -#endif -#endif - -#if defined (_SEQUENT_) - struct utsname un; - - uname(&un); - - if (strncmp(un.version, "V2", 2) == 0) { - printf ("i386-sequent-ptx2\n"); exit (0); - } - if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ - printf ("i386-sequent-ptx1\n"); exit (0); - } - printf ("i386-sequent-ptx\n"); exit (0); - -#endif - -#if defined (vax) -# if !defined (ultrix) -# include -# if defined (BSD) -# if BSD == 43 - printf ("vax-dec-bsd4.3\n"); exit (0); -# else -# if BSD == 199006 - printf ("vax-dec-bsd4.3reno\n"); exit (0); -# else - printf ("vax-dec-bsd\n"); exit (0); -# endif -# endif -# else - printf ("vax-dec-bsd\n"); exit (0); -# endif -# else - printf ("vax-dec-ultrix\n"); exit (0); -# endif -#endif - -#if defined (alliant) && defined (i860) - printf ("i860-alliant-bsd\n"); exit (0); -#endif - - exit (1); -} -EOF - -$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && - { echo "$SYSTEM_NAME"; exit; } - -# Apollos put the system type in the environment. - -test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } - -# Convex versions that predate uname can use getsysinfo(1) - -if [ -x /usr/convex/getsysinfo ] -then - case `getsysinfo -f cpu_type` in - c1*) - echo c1-convex-bsd - exit ;; - c2*) - if getsysinfo -f scalar_acc - then echo c32-convex-bsd - else echo c2-convex-bsd - fi - exit ;; - c34*) - echo c34-convex-bsd - exit ;; - c38*) - echo c38-convex-bsd - exit ;; - c4*) - echo c4-convex-bsd - exit ;; - esac -fi - cat >&2 < header file. */ #undef HAVE_DIRENT_H /* DragonFly */ #undef HAVE_DRAGONFLY -/* Define to 1 if you have the `ECDH_compute_key' function. */ -#undef HAVE_ECDH_COMPUTE_KEY - -/* Define to 1 if you have the `ECDSA_verify' function. */ -#undef HAVE_ECDSA_VERIFY - /* Define to 1 if you have the `EVP_EncryptInit_ex' function. */ #undef HAVE_EVP_ENCRYPTINIT_EX @@ -82,6 +84,9 @@ /* Define to 1 if you have the `ftime' function. */ #undef HAVE_FTIME +/* Define to 1 if you have the header file. */ +#undef HAVE_GCRYPT_H + /* Define to 1 if you have the `gettimeofday' function. */ #undef HAVE_GETTIMEOFDAY @@ -94,6 +99,9 @@ /* Define to 1 if you have the `nsl' library (-lnsl). */ #undef HAVE_LIBNSL +/* Define to 1 if you have the `resolv' library (-lresolv). */ +#undef HAVE_LIBRESOLV + /* Define to 1 if you have the `socket' library (-lsocket). */ #undef HAVE_LIBSOCKET @@ -190,12 +198,6 @@ /* OpenBSD */ #undef HAVE_OPENBSD -/* Define to 1 if you have the header file. */ -#undef HAVE_OPENSSL_ECDH_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_OPENSSL_EC_H - /* Define to 1 if you have the header file. */ #undef HAVE_OPENSSL_ENGINE_H @@ -223,8 +225,8 @@ /* Define to 1 if you have the `random' function. */ #undef HAVE_RANDOM -/* Define to 1 if you have the `RAND_pseudo_bytes' function. */ -#undef HAVE_RAND_PSEUDO_BYTES +/* Define to 1 if you have the `RAND_status' function. */ +#undef HAVE_RAND_STATUS /* have readline support */ #undef HAVE_READLINE @@ -235,6 +237,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_READLINE_READLINE_H +/* Define to 1 if you have the header file. */ +#undef HAVE_RESOLV_H + /* Define to 1 if you have the `select' function. */ #undef HAVE_SELECT diff --git a/config.sub b/config.sub index 9633db7..bba4efb 100755 --- a/config.sub +++ b/config.sub @@ -1,8 +1,8 @@ #! /bin/sh # Configuration validation subroutine script. -# Copyright 1992-2013 Free Software Foundation, Inc. +# Copyright 1992-2014 Free Software Foundation, Inc. -timestamp='2013-08-10' +timestamp='2014-09-11' # 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 @@ -68,7 +68,7 @@ Report bugs and patches to ." version="\ GNU config.sub ($timestamp) -Copyright 1992-2013 Free Software Foundation, Inc. +Copyright 1992-2014 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." @@ -265,6 +265,7 @@ case $basic_machine in | hexagon \ | i370 | i860 | i960 | ia64 \ | ip2k | iq2000 \ + | k1om \ | le32 | le64 \ | lm32 \ | m32c | m32r | m32rle | m68000 | m68k | m88k \ @@ -282,8 +283,10 @@ case $basic_machine in | mips64vr5900 | mips64vr5900el \ | mipsisa32 | mipsisa32el \ | mipsisa32r2 | mipsisa32r2el \ + | mipsisa32r6 | mipsisa32r6el \ | mipsisa64 | mipsisa64el \ | mipsisa64r2 | mipsisa64r2el \ + | mipsisa64r6 | mipsisa64r6el \ | mipsisa64sb1 | mipsisa64sb1el \ | mipsisa64sr71k | mipsisa64sr71kel \ | mipsr5900 | mipsr5900el \ @@ -295,11 +298,11 @@ case $basic_machine in | nds32 | nds32le | nds32be \ | nios | nios2 | nios2eb | nios2el \ | ns16k | ns32k \ - | open8 \ - | or1k | or32 \ + | open8 | or1k | or1knd | or32 \ | pdp10 | pdp11 | pj | pjl \ | powerpc | powerpc64 | powerpc64le | powerpcle \ | pyramid \ + | riscv32 | riscv64 \ | rl78 | rx \ | score \ | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ @@ -324,7 +327,7 @@ case $basic_machine in c6x) basic_machine=tic6x-unknown ;; - m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | picochip) + m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip) basic_machine=$basic_machine-unknown os=-none ;; @@ -381,6 +384,7 @@ case $basic_machine in | hexagon-* \ | i*86-* | i860-* | i960-* | ia64-* \ | ip2k-* | iq2000-* \ + | k1om-* \ | le32-* | le64-* \ | lm32-* \ | m32c-* | m32r-* | m32rle-* \ @@ -400,8 +404,10 @@ case $basic_machine in | mips64vr5900-* | mips64vr5900el-* \ | mipsisa32-* | mipsisa32el-* \ | mipsisa32r2-* | mipsisa32r2el-* \ + | mipsisa32r6-* | mipsisa32r6el-* \ | mipsisa64-* | mipsisa64el-* \ | mipsisa64r2-* | mipsisa64r2el-* \ + | mipsisa64r6-* | mipsisa64r6el-* \ | mipsisa64sb1-* | mipsisa64sb1el-* \ | mipsisa64sr71k-* | mipsisa64sr71kel-* \ | mipsr5900-* | mipsr5900el-* \ @@ -413,6 +419,7 @@ case $basic_machine in | nios-* | nios2-* | nios2eb-* | nios2el-* \ | none-* | np1-* | ns16k-* | ns32k-* \ | open8-* \ + | or1k*-* \ | orion-* \ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ @@ -822,6 +829,10 @@ case $basic_machine in basic_machine=powerpc-unknown os=-morphos ;; + moxiebox) + basic_machine=moxie-unknown + os=-moxiebox + ;; msdos) basic_machine=i386-pc os=-msdos @@ -1367,14 +1378,14 @@ case $os in | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \ | -linux-newlib* | -linux-musl* | -linux-uclibc* \ - | -uxpv* | -beos* | -mpeix* | -udk* \ + | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ - | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*) + | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* | -tirtos*) # Remember, each alternative MUST END IN *, to match a version number. ;; -qnx*) @@ -1592,9 +1603,6 @@ case $basic_machine in mips*-*) os=-elf ;; - or1k-*) - os=-elf - ;; or32-*) os=-coff ;; diff --git a/configure b/configure index d2816e1..e1bc385 100755 --- a/configure +++ b/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for tinc 1.1pre9. +# Generated by GNU Autoconf 2.69 for tinc 1.1pre11. # # # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. @@ -577,8 +577,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='tinc' PACKAGE_TARNAME='tinc' -PACKAGE_VERSION='1.1pre9' -PACKAGE_STRING='tinc 1.1pre9' +PACKAGE_VERSION='1.1pre11' +PACKAGE_STRING='tinc 1.1pre11' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -627,9 +627,6 @@ GCRYPT_FALSE GCRYPT_TRUE OPENSSL_FALSE OPENSSL_TRUE -LIBGCRYPT_LIBS -LIBGCRYPT_CFLAGS -LIBGCRYPT_CONFIG READLINE_LIBS CURSES_LIBS TUNEMU_FALSE @@ -656,7 +653,6 @@ build_os build_vendor build_cpu build -RANLIB LN_S AM_BACKSLASH AM_DEFAULT_VERBOSITY @@ -752,6 +748,7 @@ enable_uml enable_vde enable_tunemu with_windows2000 +enable_hardening enable_curses with_curses with_curses_include @@ -768,7 +765,9 @@ enable_lzo with_lzo with_lzo_include with_lzo_lib -with_libgcrypt_prefix +with_libgcrypt +with_libgcrypt_include +with_libgcrypt_lib with_openssl with_openssl_include with_openssl_lib @@ -1323,7 +1322,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures tinc 1.1pre9 to adapt to many kinds of systems. +\`configure' configures tinc 1.1pre11 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1393,7 +1392,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of tinc 1.1pre9:";; + short | recursive ) echo "Configuration of tinc 1.1pre11:";; esac cat <<\_ACEOF @@ -1410,17 +1409,18 @@ Optional Features: --enable-uml enable support for User Mode Linux --enable-vde enable support for Virtual Distributed Ethernet --enable-tunemu enable support for the tunemu driver + --disable-hardening disable compiler and linker hardening flags --disable-curses disable curses support --disable-readline disable readline support --disable-zlib disable zlib compression support --disable-lzo disable lzo compression support - --disable-jumbograms enable support for jumbograms (packets up to 9000 + --enable-jumbograms enable support for jumbograms (packets up to 9000 bytes) Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) - --without-windows2000 compile with support for Windows 2000. This disables + --with-windows2000 compile with support for Windows 2000. This disables support for tunneling over existing IPv6 networks. --with-curses=DIR curses base directory, or: --with-curses-include=DIR @@ -1436,8 +1436,12 @@ Optional Packages: --with-lzo=DIR lzo base directory, or: --with-lzo-include=DIR lzo headers directory --with-lzo-lib=DIR lzo library directory - --with-libgcrypt-prefix=PFX - prefix where LIBGCRYPT is installed (optional) + --with-libgcrypt=DIR libgcrypt base directory, or: + --with-libgcrypt-include=DIR + libgcrypt headers directory (without trailing + /libgcrypt) + --with-libgcrypt-lib=DIR + libgcrypt library directory --with-openssl=DIR OpenSSL base directory, or: --with-openssl-include=DIR OpenSSL headers directory (without trailing @@ -1520,7 +1524,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -tinc configure 1.1pre9 +tinc configure 1.1pre11 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -1769,6 +1773,52 @@ $as_echo "$ac_res" >&6; } } # ac_fn_c_check_header_compile +# ac_fn_c_try_link LINENO +# ----------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_link () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext conftest$ac_exeext + if { { 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>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + test -x conftest$ac_exeext + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information + # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would + # interfere with the next link command; also delete a directory that is + # 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; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_link + # ac_fn_c_check_type LINENO TYPE VAR INCLUDES # ------------------------------------------- # Tests whether TYPE exists after having included INCLUDES, setting cache @@ -1823,52 +1873,6 @@ $as_echo "$ac_res" >&6; } } # ac_fn_c_check_type -# ac_fn_c_try_link LINENO -# ----------------------- -# Try to link conftest.$ac_ext, and return whether this succeeded. -ac_fn_c_try_link () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - rm -f conftest.$ac_objext conftest$ac_exeext - if { { 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>conftest.err - ac_status=$? - if test -s conftest.err; then - grep -v '^ *+' conftest.err >conftest.er1 - cat conftest.er1 >&5 - mv -f conftest.er1 conftest.err - fi - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && { - test "$cross_compiling" = yes || - test -x conftest$ac_exeext - }; then : - ac_retval=0 -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_retval=1 -fi - # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information - # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would - # interfere with the next link command; also delete a directory that is - # 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; ${as_lineno_stack:+:} unset as_lineno - as_fn_set_status $ac_retval - -} # ac_fn_c_try_link - # ac_fn_c_check_func LINENO FUNC VAR # ---------------------------------- # Tests whether FUNC exists, setting the cache variable VAR accordingly @@ -1985,7 +1989,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by tinc $as_me 1.1pre9, which was +It was created by tinc $as_me 1.1pre11, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -2334,8 +2338,37 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu -# expand $ac_aux_dir to an absolute path -am_aux_dir=`cd $ac_aux_dir && pwd` +ac_aux_dir= +for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do + if test -f "$ac_dir/install-sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f "$ac_dir/install.sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + elif test -f "$ac_dir/shtool"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/shtool install -c" + break + fi +done +if test -z "$ac_aux_dir"; then + as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 +fi + +# These three variables are undocumented and unsupported, +# and are intended to be withdrawn in a future Autoconf release. +# They can cause serious problems if a builder's source tree is in a directory +# whose full name contains unusual characters. +ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. +ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. +ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. + + +# Expand $ac_aux_dir to an absolute path. +am_aux_dir=`cd "$ac_aux_dir" && pwd` ac_ext=c ac_cpp='$CPP $CPPFLAGS' @@ -3647,35 +3680,6 @@ $as_echo "$ac_cv_safe_to_define___extensions__" >&6; } am__api_version='1.14' -ac_aux_dir= -for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do - if test -f "$ac_dir/install-sh"; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/install-sh -c" - break - elif test -f "$ac_dir/install.sh"; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/install.sh -c" - break - elif test -f "$ac_dir/shtool"; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/shtool install -c" - break - fi -done -if test -z "$ac_aux_dir"; then - as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 -fi - -# These three variables are undocumented and unsupported, -# and are intended to be withdrawn in a future Autoconf release. -# They can cause serious problems if a builder's source tree is in a directory -# whose full name contains unusual characters. -ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. -ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. -ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. - - # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: @@ -4220,7 +4224,7 @@ fi # Define the identity of the package. PACKAGE='tinc' - VERSION='1.1pre9' + VERSION='1.1pre11' cat >>confdefs.h <<_ACEOF @@ -4440,6 +4444,7 @@ END as_fn_error $? "Your 'rm' program is bad, sorry." "$LINENO" 5 fi fi + ac_config_headers="$ac_config_headers config.h" @@ -4777,98 +4782,6 @@ else $as_echo "no, using $LN_S" >&6; } fi -if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. -set dummy ${ac_tool_prefix}ranlib; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_RANLIB+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$RANLIB"; then - ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -RANLIB=$ac_cv_prog_RANLIB -if test -n "$RANLIB"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 -$as_echo "$RANLIB" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_RANLIB"; then - ac_ct_RANLIB=$RANLIB - # Extract the first word of "ranlib", so it can be a program name with args. -set dummy ranlib; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_RANLIB+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_RANLIB"; then - ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_RANLIB="ranlib" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB -if test -n "$ac_ct_RANLIB"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 -$as_echo "$ac_ct_RANLIB" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_RANLIB" = x; then - RANLIB=":" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - RANLIB=$ac_ct_RANLIB - fi -else - RANLIB="$ac_cv_prog_RANLIB" -fi - @@ -5254,6 +5167,343 @@ if test -d /sw/lib ; then fi +# Check whether --enable-hardening was given. +if test "${enable_hardening+set}" = set; then : + enableval=$enable_hardening; +fi + +if test "x$enable_hardening" != "xno"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -DFORTIFY_SOURCE=2" >&5 +$as_echo_n "checking whether C compiler accepts -DFORTIFY_SOURCE=2... " >&6; } +if ${ax_cv_check_cflags___DFORTIFY_SOURCE_2+:} false; then : + $as_echo_n "(cached) " >&6 +else + + ax_check_save_flags=$CFLAGS + CFLAGS="$CFLAGS -DFORTIFY_SOURCE=2" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ax_cv_check_cflags___DFORTIFY_SOURCE_2=yes +else + ax_cv_check_cflags___DFORTIFY_SOURCE_2=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + CFLAGS=$ax_check_save_flags +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___DFORTIFY_SOURCE_2" >&5 +$as_echo "$ax_cv_check_cflags___DFORTIFY_SOURCE_2" >&6; } +if test x"$ax_cv_check_cflags___DFORTIFY_SOURCE_2" = xyes; then : + CPPFLAGS="$CPPFLAGS -DFORTIFY_SOURCE=2" +else + : +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -fno-strict-overflow" >&5 +$as_echo_n "checking whether C compiler accepts -fno-strict-overflow... " >&6; } +if ${ax_cv_check_cflags___fno_strict_overflow+:} false; then : + $as_echo_n "(cached) " >&6 +else + + ax_check_save_flags=$CFLAGS + CFLAGS="$CFLAGS -fno-strict-overflow" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ax_cv_check_cflags___fno_strict_overflow=yes +else + ax_cv_check_cflags___fno_strict_overflow=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + CFLAGS=$ax_check_save_flags +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___fno_strict_overflow" >&5 +$as_echo "$ax_cv_check_cflags___fno_strict_overflow" >&6; } +if test x"$ax_cv_check_cflags___fno_strict_overflow" = xyes; then : + CPPFLAGS="$CPPFLAGS -fno-strict-overflow" +else + : +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -fwrapv" >&5 +$as_echo_n "checking whether C compiler accepts -fwrapv... " >&6; } +if ${ax_cv_check_cflags___fwrapv+:} false; then : + $as_echo_n "(cached) " >&6 +else + + ax_check_save_flags=$CFLAGS + CFLAGS="$CFLAGS -fwrapv" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ax_cv_check_cflags___fwrapv=yes +else + ax_cv_check_cflags___fwrapv=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + CFLAGS=$ax_check_save_flags +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___fwrapv" >&5 +$as_echo "$ax_cv_check_cflags___fwrapv" >&6; } +if test x"$ax_cv_check_cflags___fwrapv" = xyes; then : + CPPFLAGS="$CPPFLAGS -fwrapv" +else + : +fi + + case $host_os in + *mingw*) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the linker accepts -Wl,--dynamicbase" >&5 +$as_echo_n "checking whether the linker accepts -Wl,--dynamicbase... " >&6; } +if ${ax_cv_check_ldflags___Wl___dynamicbase+:} false; then : + $as_echo_n "(cached) " >&6 +else + + ax_check_save_flags=$LDFLAGS + LDFLAGS="$LDFLAGS -Wl,--dynamicbase" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ax_cv_check_ldflags___Wl___dynamicbase=yes +else + ax_cv_check_ldflags___Wl___dynamicbase=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS=$ax_check_save_flags +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_ldflags___Wl___dynamicbase" >&5 +$as_echo "$ax_cv_check_ldflags___Wl___dynamicbase" >&6; } +if test x"$ax_cv_check_ldflags___Wl___dynamicbase" = xyes; then : + LDFLAGS="$LDFLAGS -Wl,--dynamicbase" +else + : +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the linker accepts -Wl,--nxcompat" >&5 +$as_echo_n "checking whether the linker accepts -Wl,--nxcompat... " >&6; } +if ${ax_cv_check_ldflags___Wl___nxcompat+:} false; then : + $as_echo_n "(cached) " >&6 +else + + ax_check_save_flags=$LDFLAGS + LDFLAGS="$LDFLAGS -Wl,--nxcompat" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ax_cv_check_ldflags___Wl___nxcompat=yes +else + ax_cv_check_ldflags___Wl___nxcompat=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS=$ax_check_save_flags +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_ldflags___Wl___nxcompat" >&5 +$as_echo "$ax_cv_check_ldflags___Wl___nxcompat" >&6; } +if test x"$ax_cv_check_ldflags___Wl___nxcompat" = xyes; then : + LDFLAGS="$LDFLAGS -Wl,--nxcompat" +else + : +fi + + ;; + *) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -fPIE" >&5 +$as_echo_n "checking whether C compiler accepts -fPIE... " >&6; } +if ${ax_cv_check_cflags___fPIE+:} false; then : + $as_echo_n "(cached) " >&6 +else + + ax_check_save_flags=$CFLAGS + CFLAGS="$CFLAGS -fPIE" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ax_cv_check_cflags___fPIE=yes +else + ax_cv_check_cflags___fPIE=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + CFLAGS=$ax_check_save_flags +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___fPIE" >&5 +$as_echo "$ax_cv_check_cflags___fPIE" >&6; } +if test x"$ax_cv_check_cflags___fPIE" = xyes; then : + CPPFLAGS="$CPPFLAGS -fPIE" +else + : +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the linker accepts -pie" >&5 +$as_echo_n "checking whether the linker accepts -pie... " >&6; } +if ${ax_cv_check_ldflags___pie+:} false; then : + $as_echo_n "(cached) " >&6 +else + + ax_check_save_flags=$LDFLAGS + LDFLAGS="$LDFLAGS -pie" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ax_cv_check_ldflags___pie=yes +else + ax_cv_check_ldflags___pie=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS=$ax_check_save_flags +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_ldflags___pie" >&5 +$as_echo "$ax_cv_check_ldflags___pie" >&6; } +if test x"$ax_cv_check_ldflags___pie" = xyes; then : + LDFLAGS="$LDFLAGS -pie" +else + : +fi + + ;; + esac + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the linker accepts -Wl,-z,relro" >&5 +$as_echo_n "checking whether the linker accepts -Wl,-z,relro... " >&6; } +if ${ax_cv_check_ldflags___Wl__z_relro+:} false; then : + $as_echo_n "(cached) " >&6 +else + + ax_check_save_flags=$LDFLAGS + LDFLAGS="$LDFLAGS -Wl,-z,relro" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ax_cv_check_ldflags___Wl__z_relro=yes +else + ax_cv_check_ldflags___Wl__z_relro=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS=$ax_check_save_flags +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_ldflags___Wl__z_relro" >&5 +$as_echo "$ax_cv_check_ldflags___Wl__z_relro" >&6; } +if test x"$ax_cv_check_ldflags___Wl__z_relro" = xyes; then : + LDFLAGS="$LDFLAGS -Wl,-z,relro" +else + : +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the linker accepts -Wl,-z,now" >&5 +$as_echo_n "checking whether the linker accepts -Wl,-z,now... " >&6; } +if ${ax_cv_check_ldflags___Wl__z_now+:} false; then : + $as_echo_n "(cached) " >&6 +else + + ax_check_save_flags=$LDFLAGS + LDFLAGS="$LDFLAGS -Wl,-z,now" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ax_cv_check_ldflags___Wl__z_now=yes +else + ax_cv_check_ldflags___Wl__z_now=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS=$ax_check_save_flags +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_ldflags___Wl__z_now" >&5 +$as_echo "$ax_cv_check_ldflags___Wl__z_now" >&6; } +if test x"$ax_cv_check_ldflags___Wl__z_now" = xyes; then : + LDFLAGS="$LDFLAGS -Wl,-z,now" +else + : +fi + + + +fi; + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 $as_echo_n "checking for ANSI C header files... " >&6; } if ${ac_cv_header_stdc+:} false; then : @@ -5394,7 +5644,7 @@ fi done -for ac_header in netinet/if_ether.h netinet/ip.h netinet/ip6.h +for ac_header in netinet/if_ether.h netinet/ip.h netinet/ip6.h resolv.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "#include \"src/have.h\" @@ -6062,6 +6312,69 @@ cat >>confdefs.h <<_ACEOF _ACEOF +ac_fn_c_check_decl "$LINENO" "res_init" "ac_cv_have_decl_res_init" " + #include + #include + +" +if test "x$ac_cv_have_decl_res_init" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_RES_INIT $ac_have_decl +_ACEOF +if test $ac_have_decl = 1; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for res_init in -lresolv" >&5 +$as_echo_n "checking for res_init in -lresolv... " >&6; } +if ${ac_cv_lib_resolv_res_init+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lresolv $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char res_init (); +int +main () +{ +return res_init (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_resolv_res_init=yes +else + ac_cv_lib_resolv_res_init=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_resolv_res_init" >&5 +$as_echo "$ac_cv_lib_resolv_res_init" >&6; } +if test "x$ac_cv_lib_resolv_res_init" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBRESOLV 1 +_ACEOF + + LIBS="-lresolv $LIBS" + +fi + +fi + + cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure @@ -6206,7 +6519,46 @@ fi done - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for initscr in -lcurses" >&5 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for initscr in -lncurses" >&5 +$as_echo_n "checking for initscr in -lncurses... " >&6; } +if ${ac_cv_lib_ncurses_initscr+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lncurses $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char initscr (); +int +main () +{ +return initscr (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_ncurses_initscr=yes +else + ac_cv_lib_ncurses_initscr=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ncurses_initscr" >&5 +$as_echo "$ac_cv_lib_ncurses_initscr" >&6; } +if test "x$ac_cv_lib_ncurses_initscr" = xyes; then : + CURSES_LIBS="-lncurses" +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for initscr in -lcurses" >&5 $as_echo_n "checking for initscr in -lcurses... " >&6; } if ${ac_cv_lib_curses_initscr+:} false; then : $as_echo_n "(cached) " >&6 @@ -6250,6 +6602,9 @@ else fi +fi + + fi @@ -6638,221 +6993,95 @@ done fi -if test "$with_libgcrypt" = yes; then +if test -n "$with_libgcrypt"; then gcrypt=true -# Check whether --with-libgcrypt-prefix was given. -if test "${with_libgcrypt_prefix+set}" = set; then : - withval=$with_libgcrypt_prefix; libgcrypt_config_prefix="$withval" -else - libgcrypt_config_prefix="" + +# Check whether --with-libgcrypt was given. +if test "${with_libgcrypt+set}" = set; then : + withval=$with_libgcrypt; libgcrypt="$withval" + CPPFLAGS="$CPPFLAGS -I$withval/include" + LDFLAGS="$LDFLAGS -L$withval/lib" + fi - if test x$libgcrypt_config_prefix != x ; then - if test x${LIBGCRYPT_CONFIG+set} != xset ; then - LIBGCRYPT_CONFIG=$libgcrypt_config_prefix/bin/libgcrypt-config - fi - fi - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}libgcrypt-config", so it can be a program name with args. -set dummy ${ac_tool_prefix}libgcrypt-config; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_LIBGCRYPT_CONFIG+:} false; then : + +# Check whether --with-libgcrypt-include was given. +if test "${with_libgcrypt_include+set}" = set; then : + withval=$with_libgcrypt_include; libgcrypt_include="$withval" + CPPFLAGS="$CPPFLAGS -I$withval" + +fi + + + +# Check whether --with-libgcrypt-lib was given. +if test "${with_libgcrypt_lib+set}" = set; then : + withval=$with_libgcrypt_lib; libgcrypt_lib="$withval" + LDFLAGS="$LDFLAGS -L$withval" + +fi + + + for ac_header in gcrypt.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "gcrypt.h" "ac_cv_header_gcrypt_h" "$ac_includes_default" +if test "x$ac_cv_header_gcrypt_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_GCRYPT_H 1 +_ACEOF + +else + as_fn_error $? "libgcrypt header files not found." "$LINENO" 5; break + +fi + +done + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gcry_cipher_encrypt in -lgcrypt" >&5 +$as_echo_n "checking for gcry_cipher_encrypt in -lgcrypt... " >&6; } +if ${ac_cv_lib_gcrypt_gcry_cipher_encrypt+:} false; then : $as_echo_n "(cached) " >&6 else - case $LIBGCRYPT_CONFIG in - [\\/]* | ?:[\\/]*) - ac_cv_path_LIBGCRYPT_CONFIG="$LIBGCRYPT_CONFIG" # Let the user override the test with a path. - ;; - *) - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_path_LIBGCRYPT_CONFIG="$as_dir/$ac_word$ac_exec_ext" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS + ac_check_lib_save_LIBS=$LIBS +LIBS="-lgcrypt $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ - ;; -esac -fi -LIBGCRYPT_CONFIG=$ac_cv_path_LIBGCRYPT_CONFIG -if test -n "$LIBGCRYPT_CONFIG"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIBGCRYPT_CONFIG" >&5 -$as_echo "$LIBGCRYPT_CONFIG" >&6; } +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char gcry_cipher_encrypt (); +int +main () +{ +return gcry_cipher_encrypt (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_gcrypt_gcry_cipher_encrypt=yes else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + ac_cv_lib_gcrypt_gcry_cipher_encrypt=no fi - - +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS fi -if test -z "$ac_cv_path_LIBGCRYPT_CONFIG"; then - ac_pt_LIBGCRYPT_CONFIG=$LIBGCRYPT_CONFIG - # Extract the first word of "libgcrypt-config", so it can be a program name with args. -set dummy libgcrypt-config; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_ac_pt_LIBGCRYPT_CONFIG+:} false; then : - $as_echo_n "(cached) " >&6 +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_gcrypt_gcry_cipher_encrypt" >&5 +$as_echo "$ac_cv_lib_gcrypt_gcry_cipher_encrypt" >&6; } +if test "x$ac_cv_lib_gcrypt_gcry_cipher_encrypt" = xyes; then : + LIBS="-lgcrypt $LIBS" else - case $ac_pt_LIBGCRYPT_CONFIG in - [\\/]* | ?:[\\/]*) - ac_cv_path_ac_pt_LIBGCRYPT_CONFIG="$ac_pt_LIBGCRYPT_CONFIG" # Let the user override the test with a path. - ;; - *) - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_path_ac_pt_LIBGCRYPT_CONFIG="$as_dir/$ac_word$ac_exec_ext" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS + as_fn_error $? "libgcrypt libraries not found." "$LINENO" 5 - ;; -esac fi -ac_pt_LIBGCRYPT_CONFIG=$ac_cv_path_ac_pt_LIBGCRYPT_CONFIG -if test -n "$ac_pt_LIBGCRYPT_CONFIG"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_LIBGCRYPT_CONFIG" >&5 -$as_echo "$ac_pt_LIBGCRYPT_CONFIG" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_pt_LIBGCRYPT_CONFIG" = x; then - LIBGCRYPT_CONFIG="no" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - LIBGCRYPT_CONFIG=$ac_pt_LIBGCRYPT_CONFIG - fi -else - LIBGCRYPT_CONFIG="$ac_cv_path_LIBGCRYPT_CONFIG" -fi - - tmp=1.4.0 - if echo "$tmp" | grep ':' >/dev/null 2>/dev/null ; then - req_libgcrypt_api=`echo "$tmp" | sed 's/\(.*\):\(.*\)/\1/'` - min_libgcrypt_version=`echo "$tmp" | sed 's/\(.*\):\(.*\)/\2/'` - else - req_libgcrypt_api=0 - min_libgcrypt_version="$tmp" - fi - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for LIBGCRYPT - version >= $min_libgcrypt_version" >&5 -$as_echo_n "checking for LIBGCRYPT - version >= $min_libgcrypt_version... " >&6; } - ok=no - if test "$LIBGCRYPT_CONFIG" != "no" ; then - req_major=`echo $min_libgcrypt_version | \ - sed 's/\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\)/\1/'` - req_minor=`echo $min_libgcrypt_version | \ - sed 's/\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\)/\2/'` - req_micro=`echo $min_libgcrypt_version | \ - sed 's/\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\)/\3/'` - libgcrypt_config_version=`$LIBGCRYPT_CONFIG --version` - major=`echo $libgcrypt_config_version | \ - sed 's/\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\).*/\1/'` - minor=`echo $libgcrypt_config_version | \ - sed 's/\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\).*/\2/'` - micro=`echo $libgcrypt_config_version | \ - sed 's/\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\).*/\3/'` - if test "$major" -gt "$req_major"; then - ok=yes - else - if test "$major" -eq "$req_major"; then - if test "$minor" -gt "$req_minor"; then - ok=yes - else - if test "$minor" -eq "$req_minor"; then - if test "$micro" -ge "$req_micro"; then - ok=yes - fi - fi - fi - fi - fi - fi - if test $ok = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes ($libgcrypt_config_version)" >&5 -$as_echo "yes ($libgcrypt_config_version)" >&6; } - else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - fi - if test $ok = yes; then - # If we have a recent libgcrypt, we should also check that the - # API is compatible - if test "$req_libgcrypt_api" -gt 0 ; then - tmp=`$LIBGCRYPT_CONFIG --api-version 2>/dev/null || echo 0` - if test "$tmp" -gt 0 ; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking LIBGCRYPT API version" >&5 -$as_echo_n "checking LIBGCRYPT API version... " >&6; } - if test "$req_libgcrypt_api" -eq "$tmp" ; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: okay" >&5 -$as_echo "okay" >&6; } - else - ok=no - { $as_echo "$as_me:${as_lineno-$LINENO}: result: does not match. want=$req_libgcrypt_api got=$tmp" >&5 -$as_echo "does not match. want=$req_libgcrypt_api got=$tmp" >&6; } - fi - fi - fi - fi - if test $ok = yes; then - LIBGCRYPT_CFLAGS=`$LIBGCRYPT_CONFIG --cflags` - LIBGCRYPT_LIBS=`$LIBGCRYPT_CONFIG --libs` - : - if test x"$host" != x ; then - libgcrypt_config_host=`$LIBGCRYPT_CONFIG --host 2>/dev/null || echo none` - if test x"$libgcrypt_config_host" != xnone ; then - if test x"$libgcrypt_config_host" != x"$host" ; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: -*** -*** The config script $LIBGCRYPT_CONFIG was -*** built for $libgcrypt_config_host and thus may not match the -*** used host $host. -*** You may want to use the configure option --with-libgcrypt-prefix -*** to specify a matching config script. -***" >&5 -$as_echo "$as_me: WARNING: -*** -*** The config script $LIBGCRYPT_CONFIG was -*** built for $libgcrypt_config_host and thus may not match the -*** used host $host. -*** You may want to use the configure option --with-libgcrypt-prefix -*** to specify a matching config script. -***" >&2;} - fi - fi - fi - else - LIBGCRYPT_CFLAGS="" - LIBGCRYPT_LIBS="" - : - fi - else @@ -6943,7 +7172,7 @@ if test "${with_openssl_lib+set}" = set; then : fi - for ac_header in openssl/evp.h openssl/rsa.h openssl/rand.h openssl/err.h openssl/sha.h openssl/pem.h openssl/engine.h openssl/ecdh.h openssl/ec.h + for ac_header in openssl/evp.h openssl/rsa.h openssl/rand.h openssl/err.h openssl/sha.h openssl/pem.h openssl/engine.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" @@ -7004,7 +7233,7 @@ else fi - for ac_func in RAND_pseudo_bytes EVP_EncryptInit_ex ECDH_compute_key ECDSA_verify + for ac_func in RAND_status EVP_EncryptInit_ex do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" @@ -7023,6 +7252,15 @@ done " if test "x$ac_cv_have_decl_OpenSSL_add_all_algorithms" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_OPENSSL_ADD_ALL_ALGORITHMS $ac_have_decl +_ACEOF +if test $ac_have_decl = 1; then : else as_fn_error $? "Missing OpenSSL functionality, make sure you have installed the latest version." "$LINENO" 5; break @@ -7039,7 +7277,7 @@ else OPENSSL_FALSE= fi - if test "$gcrypt" = true; then + if test -n "$gcrypt"; then GCRYPT_TRUE= GCRYPT_FALSE='#' else @@ -7633,7 +7871,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by tinc $as_me 1.1pre9, which was +This file was extended by tinc $as_me 1.1pre11, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -7699,7 +7937,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -tinc config.status 1.1pre9 +tinc config.status 1.1pre11 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff --git a/configure.ac b/configure.ac index 75456a0..6fd2621 100644 --- a/configure.ac +++ b/configure.ac @@ -1,7 +1,7 @@ dnl Process this file with autoconf to produce a configure script. AC_PREREQ(2.61) -AC_INIT([tinc], [1.1pre9]) +AC_INIT([tinc], [1.1pre11]) AC_CONFIG_SRCDIR([src/tincd.c]) AC_GNU_SOURCE AM_INIT_AUTOMAKE([check-news std-options subdir-objects -Wall]) @@ -18,7 +18,6 @@ AC_PROG_CC_C99 AC_PROG_CPP AC_PROG_INSTALL AC_PROG_LN_S -AC_PROG_RANLIB AM_PROG_CC_C_O @@ -109,7 +108,7 @@ AC_ARG_ENABLE(tunemu, ) AC_ARG_WITH(windows2000, - AS_HELP_STRING([--without-windows2000], [compile with support for Windows 2000. This disables support for tunneling over existing IPv6 networks.]), + AS_HELP_STRING([--with-windows2000], [compile with support for Windows 2000. This disables support for tunneling over existing IPv6 networks.]), [ AS_IF([test "x$with_windows2000" = "xyes"], [AC_DEFINE(WITH_WINDOWS2000, 1, [Compile with support for Windows 2000])]) ] @@ -133,6 +132,29 @@ if test -d /sw/lib ; then LIBS="$LIBS -L/sw/lib" fi +dnl Compiler hardening flags +dnl No -fstack-protector-all because it doesn't work on all platforms or architectures. + +AC_ARG_ENABLE([hardening], AS_HELP_STRING([--disable-hardening], [disable compiler and linker hardening flags])) +AS_IF([test "x$enable_hardening" != "xno"], + [AX_CHECK_COMPILE_FLAG([-DFORTIFY_SOURCE=2], [CPPFLAGS="$CPPFLAGS -DFORTIFY_SOURCE=2"]) + AX_CHECK_COMPILE_FLAG([-fno-strict-overflow], [CPPFLAGS="$CPPFLAGS -fno-strict-overflow"]) + AX_CHECK_COMPILE_FLAG([-fwrapv], [CPPFLAGS="$CPPFLAGS -fwrapv"]) + case $host_os in + *mingw*) + AX_CHECK_LINK_FLAG([-Wl,--dynamicbase], [LDFLAGS="$LDFLAGS -Wl,--dynamicbase"]) + AX_CHECK_LINK_FLAG([-Wl,--nxcompat], [LDFLAGS="$LDFLAGS -Wl,--nxcompat"]) + ;; + *) + AX_CHECK_COMPILE_FLAG([-fPIE], [CPPFLAGS="$CPPFLAGS -fPIE"]) + AX_CHECK_LINK_FLAG([-pie], [LDFLAGS="$LDFLAGS -pie"]) + ;; + esac + AX_CHECK_LINK_FLAG([-Wl,-z,relro], [LDFLAGS="$LDFLAGS -Wl,-z,relro"]) + AX_CHECK_LINK_FLAG([-Wl,-z,now], [LDFLAGS="$LDFLAGS -Wl,-z,now"]) + ] +); + 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. @@ -141,7 +163,7 @@ AC_CHECK_HEADERS([stdbool.h syslog.h sys/file.h sys/ioctl.h sys/mman.h sys/param AC_CHECK_HEADERS([net/if.h net/if_types.h linux/if_tun.h net/if_tun.h net/tun/if_tun.h net/if_tap.h net/tap/if_tap.h net/ethernet.h net/if_arp.h netinet/in_systm.h netinet/in.h netinet/in6.h time.h netpacket/packet.h], [], [], [#include "src/have.h"] ) -AC_CHECK_HEADERS([netinet/if_ether.h netinet/ip.h netinet/ip6.h], +AC_CHECK_HEADERS([netinet/if_ether.h netinet/ip.h netinet/ip6.h resolv.h], [], [], [#include "src/have.h"] ) AC_CHECK_HEADERS([netinet/tcp.h netinet/ip_icmp.h netinet/icmp6.h], @@ -182,6 +204,11 @@ AC_CHECK_DECLS([freeaddrinfo, gai_strerror, getaddrinfo, getnameinfo], [], [], [#include "src/have.h"] ) +AC_CHECK_DECLS([res_init], [AC_CHECK_LIB(resolv, res_init)], [], [ + #include + #include +]) + AC_CACHE_SAVE dnl These are defined in files in m4/ @@ -193,20 +220,20 @@ tinc_READLINE tinc_ZLIB tinc_LZO -if test "$with_libgcrypt" = yes; then +if test -n "$with_libgcrypt"; then gcrypt=true - AM_PATH_LIBGCRYPT([1.4.0], [], []) + tinc_LIBGCRYPT else openssl=true tinc_OPENSSL fi AM_CONDITIONAL(OPENSSL, test -n "$openssl") -AM_CONDITIONAL(GCRYPT, test "$gcrypt" = true) +AM_CONDITIONAL(GCRYPT, test -n "$gcrypt") -dnl Check if support for jumbograms is requested +dnl Check if support for jumbograms is requested AC_ARG_ENABLE(jumbograms, - AS_HELP_STRING([--disable-jumbograms], [enable support for jumbograms (packets up to 9000 bytes)]), + AS_HELP_STRING([--enable-jumbograms], [enable support for jumbograms (packets up to 9000 bytes)]), [ AS_IF([test "x$enable_jumbograms" = "xyes"], [ AC_DEFINE(ENABLE_JUMBOGRAMS, 1, [Support for jumbograms (packets up to 9000 bytes)]) ]) ] diff --git a/doc/Makefile.in b/doc/Makefile.in index 352e921..db0d219 100644 --- a/doc/Makefile.in +++ b/doc/Makefile.in @@ -1,4 +1,4 @@ -# Makefile.in generated by automake 1.14 from Makefile.am. +# Makefile.in generated by automake 1.14.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. @@ -80,9 +80,12 @@ subdir = doc DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am texinfo.tex ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \ - $(top_srcdir)/m4/curses.m4 $(top_srcdir)/m4/lzo.m4 \ - $(top_srcdir)/m4/openssl.m4 $(top_srcdir)/m4/readline.m4 \ - $(top_srcdir)/m4/zlib.m4 $(top_srcdir)/configure.ac + $(top_srcdir)/m4/ax_check_compile_flag.m4 \ + $(top_srcdir)/m4/ax_check_link_flag.m4 \ + $(top_srcdir)/m4/curses.m4 $(top_srcdir)/m4/libgcrypt.m4 \ + $(top_srcdir)/m4/lzo.m4 $(top_srcdir)/m4/openssl.m4 \ + $(top_srcdir)/m4/readline.m4 $(top_srcdir)/m4/zlib.m4 \ + $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d @@ -216,9 +219,6 @@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ -LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ -LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ -LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LN_S = @LN_S@ @@ -234,7 +234,6 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ -RANLIB = @RANLIB@ READLINE_LIBS = @READLINE_LIBS@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ diff --git a/doc/tinc.8.in b/doc/tinc.8.in index ebf9df1..bb56386 100644 --- a/doc/tinc.8.in +++ b/doc/tinc.8.in @@ -1,4 +1,4 @@ -.Dd 2013-01-15 +.Dd 2014-01-16 .Dt TINCCTL 8 .\" Manual page created by: .\" Scott Lamb @@ -13,14 +13,36 @@ .Op Fl -pidfile Ns = Ns Ar FILENAME .Op Fl -help .Op Fl -version -.Ar COMMAND +.Op Ar COMMAND .Sh DESCRIPTION This is the control program of tinc, a secure virtual private network (VPN) project. .Nm -communicates with -.Xr tincd 8 -to alter and inspect the running VPN's state. +can start and stop +.Xr tincd 8 , +and can to alter and inspect the state of a running VPN. +It can also be used to change the configuration, +or to import or export host configuration files from other nodes. + +If +.Nm +is started with a +.Ar COMMAND , +this command is immediately executed, after which +.Nm +exits. +If no +.Ar COMMAND +is given, +.Nm +will act as a shell; +it will display a prompt, and commands can be entered on the prompt. +If +.Nm +is compiled with libreadline, history and command completion are available on the prompt. +One can also pipe a script containing commands through +.Nm . +In that case, lines starting with a # symbol will be ignored. .Sh OPTIONS .Bl -tag -width indent .It Fl n, -net Ns = Ns Ar NETNAME @@ -47,7 +69,7 @@ option, the value of this environment variable is used. .Sh COMMANDS .Bl -tag -width indent .It init Op Ar name -Create initial configuration files and RSA and ECDSA keypairs with default length. +Create initial configuration files and RSA and Ed25519 keypairs with default length. If no .Ar name for this node is given, it will be asked for. @@ -120,9 +142,9 @@ will be made. Shows the PID of the currently running .Xr tincd 8 . .It generate-keys Op bits -Generate both RSA and ECDSA keypairs (see below) and exit. -.It generate-ecdsa-keys -Generate public/private ECDSA keypair and exit. +Generate both RSA and Ed25519 keypairs (see below) and exit. +.It generate-ed25519-keys +Generate public/private Ed25519 keypair and exit. .It generate-rsa-keys Op bits Generate public/private RSA keypair and exit. If @@ -188,6 +210,11 @@ format to standard output, from where it can be redirected to a file or piped through a program that can parse it directly, such as .Xr tcpdump 8 . +.It network Op Ar netname +If +.Ar netname +is given, switch to that network. +Otherwise, display a list of all networks for which configuration files exist. .El .Sh EXAMPLES Examples of some commands: @@ -197,7 +224,7 @@ tinc -n vpn pcap | tcpdump -r - tinc -n vpn top .Pp .Ed -Example of configuring tinc using +Examples of changing the configuration using .Nm : .Bd -literal -offset indent tinc -n vpn init foo diff --git a/doc/tinc.conf.5.in b/doc/tinc.conf.5.in index 1d5aa4e..9d9bf76 100644 --- a/doc/tinc.conf.5.in +++ b/doc/tinc.conf.5.in @@ -1,4 +1,4 @@ -.Dd 2013-01-14 +.Dd 2014-01-29 .Dt TINC.CONF 5 .\" Manual page created by: .\" Ivo Timmermans @@ -64,20 +64,20 @@ or by using .Sh PUBLIC/PRIVATE KEYS The .Nm tinc Li init -command will have generated both RSA and ECDSA public/private keypairs. +command will have generated both RSA and Ed25519 public/private keypairs. The private keys should be stored in files named .Pa rsa_key.priv and -.Pa ecdsa_key.priv +.Pa ed25519_key.priv in the directory .Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa / The public keys should be stored in the host configuration file .Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /hosts/ Ns Va NAME . The RSA keys are used for backwards compatibility with tinc version 1.0. If you are upgrading from version 1.0 to 1.1, you can keep the old configuration files, -but you will need to create ECDSA keys using the following command: +but you will need to create Ed25519 keys using the following command: .Bd -literal -offset indent -.Nm tinc Fl n Ar NETNAME Li generate-ecdsa-keys +.Nm tinc Fl n Ar NETNAME Li generate-ed25519-keys .Ed .Sh SERVER CONFIGURATION The server configuration of the daemon is done in the file @@ -114,33 +114,24 @@ If .Qq any is selected, then depending on the operating system both IPv4 and IPv6 or just IPv6 listening sockets will be created. -.It Va AutoConnect Li = Ar count Po 0 Pc Bq experimental -If set to a non-zero value, -.Nm -will try to only have -.Ar count -meta connections to other nodes, -by automatically making or breaking connections to known nodes. -Higher values increase redundancy but also increase meta data overhead. -When using this option, a good value is 3. -.It Va BindToAddress Li = Ar address Op Ar port -If your computer has more than one IPv4 or IPv6 address, +.It Va AutoConnect Li = yes | no Po no Pc Bq experimental +If set to yes, .Nm tinc -will by default listen on all of them for incoming connections. -Multiple -.Va BindToAddress -variables may be specified, -in which case listening sockets for each specified address are made. +will automatically set up meta connections to other nodes, +without requiring +.Va ConnectTo +variables. .Pp -If no -.Ar port -is specified, the socket will be bound to the port specified by the -.Va Port -option, or to port 655 if neither is given. -To only bind to a specific port but not to a specific address, use -.Li * -for the -.Ar address . +Note: it is not possible to connect to nodes using zero (system-assigned) ports in this way. +.It Va BindToAddress Li = Ar address Op Ar port +This is the same as +.Va ListenAddress , +however the address given with the +.Va BindToAddress +option will also be used for outgoing connections. This is useful if your +computer has more than one IPv4 or IPv6 address, and you want +.Nm tinc +to only use a specific one for outgoing packets. .It Va BindToInterface Li = Ar interface Bq experimental If your computer has more than one network interface, .Nm tinc @@ -166,6 +157,13 @@ Broadcast packets are sent directly to all nodes that can be reached directly. Broadcast packets received from other nodes are never forwarded. If the IndirectData option is also set, broadcast packets will only be sent to nodes which we have a meta connection to. .El +.It Va BroadcastSubnet Li = Ar address Ns Op Li / Ns Ar prefixlength +Declares a broadcast subnet. Any packet with a destination address falling into such a subnet will be routed as a broadcast (provided all nodes have it declared). +This is most useful to declare subnet broadcast addresses (e.g. 10.42.255.255), otherwise +.Nm tinc +won't know what to do with them. +.Pp +Note that global broadcast addresses (MAC ff:ff:ff:ff:ff:ff, IPv4 255.255.255.255), as well as multicast space (IPv4 224.0.0.0/4, IPv6 ff00::/8) are always considered broadcast addresses and don't need to be declared. .It Va ConnectTo Li = Ar name Specifies which other tinc daemon to connect to on startup. Multiple @@ -178,7 +176,9 @@ The names should be known to this tinc daemon line). .Pp If you don't specify a host with -.Va ConnectTo , +.Va ConnectTo +and don't enable +.Va AutoConnect , .Nm tinc won't try to connect to other daemons at all, and will instead just listen for incoming connections. @@ -202,6 +202,13 @@ instead of .Va Device . The info pages of the tinc package contain more information about configuring the virtual network device. +.It Va DeviceStandby Li = yes | no Po no Pc +When disabled, +.Nm tinc +calls tinc-up on startup, and tinc-down on shutdown. When enabled, +.Nm tinc +will only call tinc-up when at least one node is reachable, and will call tinc-down as soon as no nodes are reachable. +On Windows, this also determines when the virtual network interface "cable" is "plugged". .It Va DeviceType Li = Ar type Pq platform dependent The type of the virtual network device. Tinc will normally automatically select the right type of tun/tap interface, and this option should not be used. @@ -269,17 +276,17 @@ When this option is enabled, packets that cannot be sent directly to the destina 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 ECDSAPrivateKeyFile Li = Ar filename Po Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /ecdsa_key.priv Pc -The file in which the private ECDSA key of this tinc daemon resides. +.It Va Ed25519PrivateKeyFile Li = Ar filename Po Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /ed25519_key.priv Pc +The file in which the private Ed25519 key of this tinc daemon resides. This is only used if .Va ExperimentalProtocol is enabled. .It Va ExperimentalProtocol Li = yes | no Pq yes When this option is enabled, the SPTPS protocol will be used when connecting to nodes that also support it. Ephemeral ECDH will be used for key exchanges, -and ECDSA will be used instead of RSA for authentication. -When enabled, an ECDSA key must have been generated before with -.Nm tinc generate-ecdsa-keys . +and Ed25519 will be used instead of RSA for authentication. +When enabled, an Ed25519 key must have been generated before with +.Nm tinc generate-ed25519-keys . .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 @@ -316,7 +323,34 @@ this variable is almost always already correctly set. This option controls the period the encryption keys used to encrypt the data are valid. It is common practice to change keys at regular intervals to make it even harder for crackers, even though it is thought to be nearly impossible to crack a single key. -.It Va LocalDiscovery Li = yes | no Pq no +.It Va ListenAddress Li = Ar address Op Ar port +If your computer has more than one IPv4 or IPv6 address, +.Nm tinc +will by default listen on all of them for incoming connections. +This option can be used to restrict which addresses tinc listens on. +Multiple +.Va ListenAddress +variables may be specified, +in which case listening sockets for each specified address are made. +.Pp +If no +.Ar port +is specified, the socket will listen on the port specified by the +.Va Port +option, or to port 655 if neither is given. +To only listen on a specific port but not on a specific address, use +.Li * +for the +.Ar address . +.Pp +If +.Ar port +is set to zero, it will be randomly assigned by the system. This is useful to randomize source ports of UDP packets, which can improve UDP hole punching reliability. In this case it is recommended to set +.Va AddressFamily +as well, otherwise +.Nm tinc +will assign different ports to different address families but other nodes can only know of one. +.It Va LocalDiscovery Li = yes | no Pq yes When enabled, .Nm tinc will try to detect peers that are on the same local network. @@ -324,11 +358,7 @@ This will allow direct communication using LAN addresses, even if both peers are and they only ConnectTo a third node outside the NAT, which normally would prevent the peers from learning each other's LAN address. .Pp -Currently, local discovery is implemented by sending broadcast packets to the LAN during path MTU discovery. -This feature may not work in all possible situations. -.It Va LocalDiscoveryAddress Li = Ar address -If this variable is specified, local discovery packets are sent to the given -.Ar address . +Currently, local discovery is implemented by sending some packets to the local address of the node during path MTU discovery. This will not work with old nodes that don't transmit their local address. .It Va MACExpire Li = Ar seconds Pq 600 This option controls the amount of time MAC addresses are kept before they are removed. This only has effect when @@ -367,7 +397,8 @@ while no routing table is managed. .It Va Name Li = Ar name Bq required This is the name which identifies this tinc daemon. It must be unique for the virtual private network this daemon will connect to. -The Name may only consist of alphanumeric and underscore characters (a-z, A-Z, 0-9 and _), and is case sensitive. +.Va Name +may only consist of alphanumeric and underscore characters (a-z, A-Z, 0-9 and _), and is case sensitive. If .Va Name starts with a @@ -436,17 +467,18 @@ are available. .It Va ReplayWindow Li = Ar bytes Pq 16 This is the size of the replay tracking window for each remote node, in bytes. The window is a bitfield which tracks 1 packet per bit, so for example -the default setting of 16 will track up to 128 packets in the window. In high +the default setting of 16 will track up to 128 packets in the window. In high bandwidth scenarios, setting this to a higher value can reduce packet loss from the interaction of replay tracking with underlying real packet loss and/or -reordering. Setting this to zero will disable replay tracking completely and +reordering. Setting this to zero will disable replay tracking completely and pass all traffic, but leaves tinc vulnerable to replay-based attacks on your traffic. .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. +directory. Subnets learned via connections to other nodes and which are not +present in the local host config files are ignored. .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 @@ -507,8 +539,8 @@ will turn off packet authentication. This option has no effect for connections between nodes using .Va ExperimentalProtocol . .It Va IndirectData Li = yes | no Pq no -When set to yes, other nodes which do not already have a meta connection to you -will not try to establish direct communication with you. +When set to yes, only nodes which already have a meta connection to you +will try to establish direct communication with you. It is best to leave this option out or set it to no. .It Va MACLength Li = Ar length Pq 4 The length of the message authentication code used to authenticate UDP packets. @@ -527,6 +559,14 @@ 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. +.Pp +If this is set to zero, the port will be randomly assigned by the system. This is useful to randomize source ports of UDP packets, which can improve UDP hole punching reliability. When setting +.Va Port +to zero it is recommended to set +.Va AddressFamily +as well, otherwise +.Nm tinc +will assign different ports to different address families but other nodes can only know of one. .It Va PublicKey Li = Ar key Bq obsolete The public RSA key of this tinc daemon. It will be used to cryptographically verify it's identity and to set up a secure connection. @@ -561,7 +601,7 @@ IPv6 subnets are notated like fec0:0:0:1::/64. MAC addresses are notated like 0:1a:2b:3c:4d:5e. .Pp A Subnet can be given a weight to indicate its priority over identical Subnets -owned by different nodes. The default weight is 10. Lower values indicate +owned by different nodes. The default weight is 10. Lower values indicate higher priority. Packets will be sent to the node with the highest priority, unless that node is not reachable, in which case the node with the next highest priority will be tried, and so on. @@ -575,6 +615,12 @@ Setting this options also implicitly sets IndirectData. .Pp Since version 1.0.10, tinc will automatically detect whether communication via UDP is possible or not. +.It Va Weight Li = Ar weight +If this variable is set, it overrides the weight given to connections made with +another host. A higher +.Ar weight +means a lower priority is given to this connection when broadcasting or +forwarding packets. .El .Sh SCRIPTS Apart from reading the server and host configuration files, @@ -586,12 +632,16 @@ or .Bl -tag -width indent .It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /tinc-up This is the most important script. -If it is present it will be executed right after the tinc daemon has been started and has connected to the virtual network device. +If it is present it will be executed right after the tinc daemon has been started and has connected to the virtual network device (or when the first node becomes reachable if +.Va DeviceStandby +is used). It should be used to set up the corresponding network interface, but can also be used to start other things. Under Windows you can use the Network Connections control panel instead of creating this script. .It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /tinc-down -This script is started right before the tinc daemon quits. +This script is started right before the tinc daemon quits (or when the last node becomes unreachable if +.Va DeviceStandby +is used). .It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /hosts/ Ns Ar HOST Ns Pa -up This script is started when the tinc daemon with name .Ar HOST @@ -668,6 +718,8 @@ The top directory for configuration files. .It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /tinc.conf The default name of the server configuration file for net .Ar NETNAME . +.It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /conf.d/ +Optional directory from which any .conf file will be loaded .It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /hosts/ Host configuration files are kept in this directory. .It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /tinc-up diff --git a/doc/tinc.info b/doc/tinc.info index 9763256..d294c78 100644 --- a/doc/tinc.info +++ b/doc/tinc.info @@ -1,14 +1,14 @@ -This is tinc.info, produced by makeinfo version 5.1 from tinc.texi. +This is tinc.info, produced by makeinfo version 5.2 from tinc.texi. INFO-DIR-SECTION Networking tools START-INFO-DIR-ENTRY * tinc: (tinc). The tinc Manual. END-INFO-DIR-ENTRY -This is the info manual for tinc version 1.1pre9, a Virtual Private +This is the info manual for tinc version 1.1pre10, a Virtual Private Network daemon. - Copyright (C) 1998-2013 Ivo Timmermans, Guus Sliepen + Copyright (C) 1998-2014 Ivo Timmermans, Guus Sliepen and Wessel Dankers . Permission is granted to make and distribute verbatim copies of this @@ -286,9 +286,9 @@ File: tinc.info, Node: Libraries, Prev: Configuring the kernel, Up: Preparati ============= Before you can configure or build tinc, you need to have the OpenSSL, -zlib and lzo libraries installed on your system. If you try to -configure tinc without having them installed, configure will give you an -error message, and stop. +zlib, lzo, curses and readline libraries installed on your system. If +you try to configure tinc without having them installed, configure will +give you an error message, and stop. * Menu: @@ -724,6 +724,9 @@ The actual configuration of the daemon is done in the file '/etc/tinc/NETNAME/tinc.conf' and at least one other file in the directory '/etc/tinc/NETNAME/hosts/'. +An optionnal directory '/etc/tinc/NETNAME/conf.d' can be added from +which any .conf file will be read. + These file consists of comments (lines started with a #) or assignments in the form of @@ -767,23 +770,16 @@ AddressFamily = (any) system both IPv4 and IPv6 or just IPv6 listening sockets will be created. -AutoConnect = (0) [experimental] - If set to a non-zero value, tinc will try to only have count meta - connections to other nodes, by automatically making or breaking - connections to known nodes. Higher values increase redundancy but - also increase meta data overhead. When using this option, a good - value is 3. +AutoConnect = (no) [experimental] + If set to yes, tinc will automatically set up meta connections to + other nodes, without requiring CONNECTTO variables. BindToAddress =
[] - If your computer has more than one IPv4 or IPv6 address, tinc will - by default listen on all of them for incoming connections. - Multiple BindToAddress variables may be specified, in which case - listening sockets for each specified address are made. - - If no PORT is specified, the socket will be bound to the port - specified by the Port option, or to port 655 if neither is given. - To only bind to a specific port but not to a specific address, use - "*" for the ADDRESS. + This is the same as ListenAddress, however the address given with + the BindToAddress option will also be used for outgoing + connections. This is useful if your computer has more than one + IPv4 or IPv6 address, and you want tinc to only use a specific one + for outgoing packets. BindToInterface = [experimental] If you have more than one network interface in your computer, tinc @@ -815,6 +811,18 @@ Broadcast = (mst) [experimental] broadcast packets will only be sent to nodes which we have a meta connection to. +BroadcastSubnet = ADDRESS[/PREFIXLENGTH] + Declares a broadcast subnet. Any packet with a destination address + falling into such a subnet will be routed as a broadcast (provided + all nodes have it declared). This is most useful to declare subnet + broadcast addresses (e.g. 10.42.255.255), otherwise tinc won't + know what to do with them. + + Note that global broadcast addresses (MAC ff:ff:ff:ff:ff:ff, IPv4 + 255.255.255.255), as well as multicast space (IPv4 224.0.0.0/4, + IPv6 ff00::/8) are always considered broadcast addresses and don't + need to be declared. + ConnectTo = Specifies which other tinc daemon to connect to on startup. Multiple ConnectTo variables may be specified, in which case @@ -822,9 +830,9 @@ ConnectTo = names should be known to this tinc daemon (i.e., there should be a host configuration file for the name on the ConnectTo line). - If you don't specify a host with ConnectTo, tinc won't try to - connect to other daemons at all, and will instead just listen for - incoming connections. + If you don't specify a host with ConnectTo and don't enable + AutoConnect, tinc won't try to connect to other daemons at all, and + will instead just listen for incoming connections. DecrementTTL = (no) [experimental] When enabled, tinc will decrement the Time To Live field in IPv4 @@ -842,6 +850,13 @@ Device = ('/dev/tap0', '/dev/net/tun' or other depending on platform) that you can only use one device per daemon. See also *note Device files::. +DeviceStandby = (no) + When disabled, tinc calls 'tinc-up' on startup, and 'tinc-down' on + shutdown. When enabled, tinc will only call 'tinc-up' when at + least one node is reachable, and will call 'tinc-down' as soon as + no nodes are reachable. On Windows, this also determines when the + virtual network interface "cable" is "plugged". + DeviceType = (platform dependent) The type of the virtual network device. Tinc will normally automatically select the right type of tun/tap interface, and this @@ -914,16 +929,16 @@ DirectOnly = (no) [experimental] IndirectData option, packets for nodes for which we do not have a meta connection with are also dropped. -ECDSAPrivateKeyFile = ('/etc/tinc/NETNAME/ecdsa_key.priv') - The file in which the private ECDSA key of this tinc daemon +Ed25519PrivateKeyFile = ('/etc/tinc/NETNAME/ed25519_key.priv') + The file in which the private Ed25519 key of this tinc daemon resides. This is only used if ExperimentalProtocol is enabled. ExperimentalProtocol = (yes) When this option is enabled, the SPTPS protocol will be used when connecting to nodes that also support it. Ephemeral ECDH will be - used for key exchanges, and ECDSA will be used instead of RSA for - authentication. When enabled, an ECDSA key must have been - generated before with 'tinc generate-ecdsa-keys'. + used for key exchanges, and Ed25519 will be used instead of RSA for + authentication. When enabled, an Ed25519 key must have been + generated before with 'tinc generate-ed25519-keys'. Forwarding = (internal) [experimental] This option selects the way indirect packets are forwarded. @@ -964,6 +979,18 @@ Interface = interface will be used. If you specified a Device, this variable is almost always already correctly set. +ListenAddress =
[] + If your computer has more than one IPv4 or IPv6 address, tinc will + by default listen on all of them for incoming connections. This + option can be used to restrict which addresses tinc listens on. + Multiple ListenAddress variables may be specified, in which case + listening sockets for each specified address are made. + + If no PORT is specified, the socket will listen on the port + specified by the Port option, or to port 655 if neither is given. + To only listen on a specific port but not to a specific address, + use "*" for the ADDRESS. + LocalDiscovery = (no) When enabled, tinc will try to detect peers that are on the same local network. This will allow direct communication using LAN @@ -1065,7 +1092,7 @@ ProcessPriority = adjusted. Increasing the priority may help to reduce latency and packet loss on the VPN. -Proxy = socks4 | socks4 | http | exec ... [experimental] +Proxy = socks4 | socks5 | http | exec ... [experimental] Use a proxy when making outgoing connections. The following proxy types are currently supported: @@ -1074,7 +1101,7 @@ Proxy = socks4 | socks4 | http | exec ... [experimental] Optionally, a USERNAME can be supplied which will be passed on to the proxy server. - socks4
[ ] + socks5
[ ] Connect to the proxy using the SOCKS version 5 protocol. If a USERNAME and PASSWORD are given, basic username/password authentication will be used, otherwise no authentication will @@ -1099,10 +1126,12 @@ ReplayWindow = (16) pass all traffic, but leaves tinc vulnerable to replay-based attacks on your traffic. -StrictSubnets (no) [experimental] +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. + '/etc/tinc/NETNAME/hosts/' directory. Subnets learned via + connections to other nodes and which are not present in the local + host config files are ignored. TunnelServer = (no) [experimental] When this option is enabled tinc will no longer forward information @@ -1131,7 +1160,9 @@ 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. If no port is - specified, the default Port is used. + specified, the default Port is used. Multiple Address variables + can be specified, in which case each address will be tried until a + working connection has been established. Cipher = (blowfish) The symmetric cipher algorithm used to encrypt UDP packets using @@ -1234,6 +1265,12 @@ TCPonly = (no) masquerading firewall, or if UDP packet routing is disabled somehow. Setting this options also implicitly sets IndirectData. +Weight = + If this variable is set, it overrides the weight given to + connections made with another host. A higher weight means a lower + priority is given to this connection when broadcasting or + forwarding packets. +  File: tinc.info, Node: Scripts, Next: How to configure, Prev: Host configuration variables, Up: Configuration files @@ -1353,10 +1390,10 @@ contents: Name = NAME -It will also create private RSA and ECDSA keys, which will be stored in -the files 'rsa_key.priv' and 'ecdsa_key.priv'. It will also create a -host configuration file 'hosts/NAME', which will contain the -corresponding public RSA and ECDSA keys. +It will also create private RSA and Ed25519 keys, which will be stored +in the files 'rsa_key.priv' and 'ed25519_key.priv'. It will also create +a host configuration file 'hosts/NAME', which will contain the +corresponding public RSA and Ed25519 keys. Finally, on UNIX operating systems, it will create an executable script 'tinc-up', which will initially not do anything except warning that you @@ -1375,7 +1412,7 @@ should run the following command: This will add a Subnet statement to your host configuration file. Try opening the file '/etc/tinc/NETNAME/hosts/NAME' in an editor. You -should now see a file containing the public RSA and ECDSA keys (which +should now see a file containing the public RSA and Ed25519 keys (which looks like a bunch of random characters), and the following line at the bottom: @@ -1657,9 +1694,9 @@ Key files A, B, C and D all have their own public/private keypairs: The private RSA key is stored in '/etc/tinc/company/rsa_key.priv', the -private ECDSA key is stored in '/etc/tinc/company/ecdsa_key.priv', and -the public RSA and ECDSA keys are put into the host configuration file -in the '/etc/tinc/company/hosts/' directory. +private Ed25519 key is stored in '/etc/tinc/company/ed25519_key.priv', +and the public RSA and Ed25519 keys are put into the host configuration +file in the '/etc/tinc/company/hosts/' directory. Starting ........ @@ -1997,11 +2034,17 @@ File: tinc.info, Node: Controlling tinc, Next: Technical information, Prev: R 6 Controlling tinc ****************** -You can control and inspect a running tincd through the tinc command. A -quick example: +You can start, stop, control and inspect a running tincd through the +tinc command. A quick example: tinc -n NETNAME reload +If tinc is started without a command, it will act as a shell; it will +display a prompt, and commands can be entered on the prompt. If tinc is +compiled with libreadline, history and command completion are available +on the prompt. One can also pipe a script containing commands through +tinc. In that case, lines starting with a # symbol will be ignored. + * Menu: * tinc runtime options:: @@ -2052,8 +2095,8 @@ File: tinc.info, Node: tinc commands, Next: tinc examples, Prev: tinc environ ================= 'init [NAME]' - Create initial configuration files and RSA and ECDSA keypairs with - default length. If no NAME for this node is given, it will be + Create initial configuration files and RSA and Ed25519 keypairs + with default length. If no NAME for this node is given, it will be asked for. 'get VARIABLE' @@ -2126,12 +2169,12 @@ File: tinc.info, Node: tinc commands, Next: tinc examples, Prev: tinc environ Shows the PID of the currently running 'tincd'. 'generate-keys [BITS]' - Generate both RSA and ECDSA keypairs (see below) and exit. tinc + Generate both RSA and Ed25519 keypairs (see below) and exit. tinc will ask where you want to store the files, but will default to the configuration directory (you can use the -c or -n option). -'generate-ecdsa-keys' - Generate public/private ECDSA keypair and exit. +'generate-ed25519-keys' + Generate public/private Ed25519 keypair and exit. 'generate-rsa-keys [BITS]' Generate public/private RSA keypair and exit. If BITS is omitted, @@ -2195,6 +2238,10 @@ File: tinc.info, Node: tinc commands, Next: tinc examples, Prev: tinc environ file or piped through a program that can parse it directly, such as tcpdump. +'network' + If NETNAME is given, switch to that network. Otherwise, display a + list of all networks for which configuration files exist. +  File: tinc.info, Node: tinc examples, Next: tinc top, Prev: tinc commands, Up: Controlling tinc @@ -2207,7 +2254,7 @@ Examples of some commands: tinc -n vpn pcap | tcpdump -r - tinc -n vpn top -Example of configuring tinc using the tinc command: +Examples of changing the configuration using tinc: tinc -n vpn init foo tinc -n vpn add Subnet 192.168.1.0/24 @@ -2776,11 +2823,11 @@ The expanded key is used as follows: Where initiator_cipher_key is the key used by session initiator to encrypt messages sent to the responder. -When using 521 bits EC keys, the AES-256-CTR cipher and HMAC-SHA-256 -digest algorithm, the sizes are as follows: +When using 256 bits Ed25519 keys, the AES-256-CTR cipher and +HMAC-SHA-256 digest algorithm, the sizes are as follows: - ECDH_SIZE: 67 (= ceil(521/8) + 1) - ECDSA_SIZE: 141 (= 2 * ceil(521/8) + 9) + ECDH_SIZE: 32 (= 256/8) + ECDSA_SIZE: 64 (= 2 * 256/8) CIPHER_KEYSIZE: 48 (= 256/8 + 128/8) DIGEST_KEYSIZE: 32 (= 256/8) @@ -3019,6 +3066,7 @@ Concept Index * ACK: Legacy authentication protocol. (line 6) +* add: tinc commands. (line 22) * Address: Host configuration variables. (line 6) * AddressFamily: Main configuration variables. @@ -3031,83 +3079,107 @@ Concept Index * binary package: Building and installing tinc. (line 9) * BindToAddress: Main configuration variables. - (line 19) + (line 16) * BindToInterface: Main configuration variables. - (line 30) + (line 23) * Broadcast: Main configuration variables. - (line 40) + (line 33) +* BroadcastSubnet: Main configuration variables. + (line 53) * Cabal: Security. (line 6) * CHALLENGE: Legacy authentication protocol. (line 6) * CHAL_REPLY: Legacy authentication protocol. (line 6) * CIDR notation: Host configuration variables. - (line 94) + (line 96) * Cipher: Host configuration variables. - (line 12) + (line 14) * ClampMSS: Host configuration variables. - (line 20) + (line 22) * client: How connections work. (line 18) * command line: Runtime options. (line 9) +* command line interface: Controlling tinc. (line 6) * Compression: Host configuration variables. - (line 26) + (line 28) * connection: The connection. (line 6) * ConnectTo: Main configuration variables. - (line 60) + (line 65) * daemon: Running tinc. (line 11) * data-protocol: The meta-connection. (line 18) +* debug: tinc commands. (line 121) * debug level: Runtime options. (line 17) * debug levels: Debug levels. (line 6) * DecrementTTL: Main configuration variables. - (line 71) + (line 76) +* del: tinc commands. (line 26) * DEL_EDGE: The meta-protocol. (line 46) * DEL_SUBNET: The meta-protocol. (line 46) * Device: Main configuration variables. - (line 80) + (line 85) * DEVICE: Scripts. (line 60) * device files: Device files. (line 6) +* DeviceStandby: Main configuration variables. + (line 92) * DeviceType: Main configuration variables. - (line 87) + (line 99) * Digest: Host configuration variables. - (line 31) + (line 33) * DirectOnly: Main configuration variables. - (line 152) + (line 164) +* disconnect: tinc commands. (line 136) * dummy: Main configuration variables. - (line 94) -* ECDSAPrivateKeyFile: Main configuration variables. - (line 159) + (line 106) +* dump: tinc commands. (line 94) +* Ed25519PrivateKeyFile: Main configuration variables. + (line 171) +* edit: tinc commands. (line 31) * encapsulating: The UDP tunnel. (line 30) * encryption: Encryption of network packets. (line 6) * environment variables: Scripts. (line 48) * example: Example configuration. (line 6) +* exchange: tinc commands. (line 47) +* exchange-all: tinc commands. (line 50) * exec: Main configuration variables. - (line 328) + (line 352) * ExperimentalProtocol: Main configuration variables. - (line 163) + (line 175) +* export: tinc commands. (line 35) +* export-all: tinc commands. (line 39) * Forwarding: Main configuration variables. - (line 170) + (line 182) * frame type: The UDP tunnel. (line 6) +* generate-ed25519-keys: tinc commands. (line 85) +* generate-keys: tinc commands. (line 80) +* generate-rsa-keys: tinc commands. (line 88) +* get: tinc commands. (line 11) +* graph: tinc commands. (line 107) * Hostnames: Main configuration variables. - (line 190) + (line 202) * http: Main configuration variables. - (line 325) + (line 349) * hub: Main configuration variables. - (line 246) + (line 270) * ID: Legacy authentication protocol. (line 6) +* import: tinc commands. (line 42) * IndirectData: Host configuration variables. - (line 38) + (line 40) +* info: tinc commands. (line 114) +* init: tinc commands. (line 6) * Interface: Main configuration variables. - (line 201) + (line 213) * INTERFACE: Scripts. (line 63) * INVITATION_FILE: Scripts. (line 86) * INVITATION_URL: Scripts. (line 90) +* invite: tinc commands. (line 53) * IRC: Contact information. (line 9) +* join: tinc commands. (line 58) * KeyExpire: Main configuration variables. - (line 251) + (line 275) * KEY_CHANGED: The meta-protocol. (line 63) * legacy authentication protocol: Legacy authentication protocol. (line 6) @@ -3115,27 +3187,30 @@ Concept Index * libraries: Libraries. (line 6) * libreadline: libreadline. (line 6) * license: OpenSSL. (line 35) +* ListenAddress: Main configuration variables. + (line 221) * LocalDiscovery: Main configuration variables. - (line 209) + (line 233) * LocalDiscoveryAddress: Main configuration variables. - (line 220) + (line 244) +* log: tinc commands. (line 124) * lzo: lzo. (line 6) * MACExpire: Main configuration variables. - (line 257) + (line 281) * MACLength: Host configuration variables. - (line 43) + (line 45) * MaxConnectionBurst: Main configuration variables. - (line 262) + (line 286) * meta-protocol: The meta-connection. (line 18) * META_KEY: Legacy authentication protocol. (line 6) * Mode: Main configuration variables. - (line 224) + (line 248) * multicast: Main configuration variables. - (line 106) + (line 118) * multiple networks: Multiple networks. (line 6) * Name: Main configuration variables. - (line 268) + (line 292) * NAME: Scripts. (line 57) * netmask: Network interfaces. (line 39) * netname: Multiple networks. (line 6) @@ -3144,101 +3219,114 @@ Concept Index (line 6) * Network Administrators Guide: Configuration introduction. (line 15) +* network [NETNAME]: tinc commands. (line 150) * NODE: Scripts. (line 67) * OpenSSL: OpenSSL. (line 6) * options: Runtime options. (line 9) +* pcap: tinc commands. (line 144) * PEM format: Host configuration variables. - (line 70) + (line 72) +* pid: tinc commands. (line 77) * PING: The meta-protocol. (line 88) * PingInterval: Main configuration variables. - (line 279) + (line 303) * PingTimeout: Main configuration variables. - (line 283) + (line 307) * platforms: Supported platforms. (line 6) * PMTU: Host configuration variables. - (line 50) + (line 52) * PMTUDiscovery: Host configuration variables. - (line 53) + (line 55) * PONG: The meta-protocol. (line 88) * Port: Host configuration variables. - (line 58) + (line 60) * port numbers: Other files. (line 17) * PriorityInheritance: Main configuration variables. - (line 289) + (line 313) * private: Virtual Private Networks. (line 10) * PrivateKey: Main configuration variables. - (line 294) + (line 318) * PrivateKeyFile: Main configuration variables. - (line 300) + (line 324) * ProcessPriority: Main configuration variables. - (line 305) + (line 329) * Proxy: Main configuration variables. - (line 310) + (line 334) * PublicKey: Host configuration variables. - (line 62) + (line 64) * PublicKeyFile: Host configuration variables. - (line 65) + (line 67) +* purge: tinc commands. (line 118) * raw_socket: Main configuration variables. - (line 99) + (line 111) * release: Supported platforms. (line 14) +* reload: tinc commands. (line 72) * REMOTEADDRESS: Scripts. (line 72) * REMOTEPORT: Scripts. (line 75) * ReplayWindow: Main configuration variables. - (line 333) + (line 357) * requirements: Libraries. (line 6) * REQ_KEY: The meta-protocol. (line 63) +* restart: tinc commands. (line 69) +* retry: tinc commands. (line 129) * router: Main configuration variables. - (line 227) + (line 251) * runtime options: Runtime options. (line 9) * scalability: tinc. (line 19) * scripts: Scripts. (line 6) * server: How connections work. (line 18) +* set: tinc commands. (line 16) +* shell: Controlling tinc. (line 11) * signals: Signals. (line 6) * socks4: Main configuration variables. - (line 314) + (line 338) * socks5: Main configuration variables. - (line 319) + (line 343) * SPTPS: Simple Peer-to-Peer Security. (line 6) +* start: tinc commands. (line 63) +* stop: tinc commands. (line 66) * StrictSubnets: Main configuration variables. - (line 344) + (line 368) * Subnet: Host configuration variables. - (line 77) + (line 79) * SUBNET: Scripts. (line 79) * SVPN: Security. (line 11) * switch: Main configuration variables. - (line 235) + (line 259) * TCP: The meta-connection. (line 10) * TCPonly: Host configuration variables. - (line 106) + (line 108) * tinc: Introduction. (line 6) * TINC: Security. (line 6) * tinc-down: Scripts. (line 18) * tinc-up: Scripts. (line 10) * tinc-up <1>: Network interfaces. (line 19) * tincd: tinc. (line 14) +* top: tinc commands. (line 139) +* top <1>: tinc top. (line 6) * traditional VPNs: tinc. (line 19) * tunifhead: Main configuration variables. - (line 141) + (line 153) * TunnelServer: Main configuration variables. - (line 349) + (line 375) * tunnohead: Main configuration variables. - (line 135) + (line 147) * UDP: The UDP tunnel. (line 30) * UDP <1>: Encryption of network packets. (line 11) * UDPRcvBuf: Main configuration variables. - (line 356) + (line 382) * UDPSndBuf: Main configuration variables. - (line 361) + (line 387) * UML: Main configuration variables. - (line 117) + (line 129) * Universal tun/tap: Configuration of Linux kernels. (line 6) * VDE: Main configuration variables. - (line 122) + (line 134) * virtual: Virtual Private Networks. (line 18) * virtual network device: The UDP tunnel. (line 6) @@ -3246,80 +3334,82 @@ Concept Index (line 6) * vpnd: tinc. (line 6) * website: Contact information. (line 6) +* Weight: Host configuration variables. + (line 115) * WEIGHT: Scripts. (line 82) * zlib: zlib. (line 6)  Tag Table: -Node: Top807 -Node: Introduction1127 -Node: Virtual Private Networks1931 -Node: tinc3643 -Node: Supported platforms5155 -Node: Preparations5851 -Node: Configuring the kernel6107 -Node: Configuration of Linux kernels6516 -Node: Configuration of FreeBSD kernels7365 -Node: Configuration of OpenBSD kernels7830 -Node: Configuration of NetBSD kernels8438 -Node: Configuration of Solaris kernels8840 -Node: Configuration of Darwin (MacOS/X) kernels9501 -Node: Configuration of Windows10190 -Node: Libraries10703 -Node: OpenSSL11121 -Node: zlib13393 -Node: lzo14411 -Node: libcurses15401 -Node: libreadline16311 -Node: Installation17248 -Node: Building and installing tinc18257 -Node: Darwin (MacOS/X) build environment18913 -Node: Cygwin (Windows) build environment19477 -Node: MinGW (Windows) build environment20061 -Node: System files20579 -Node: Device files20844 -Node: Other files21257 -Node: Configuration21870 -Node: Configuration introduction22157 -Node: Multiple networks23678 -Node: How connections work25046 -Node: Configuration files27607 -Node: Main configuration variables29135 -Node: Host configuration variables45893 -Node: Scripts51364 -Node: How to configure54765 -Node: Network interfaces59241 -Node: Example configuration61620 -Node: Running tinc66713 -Node: Runtime options67300 -Node: Signals70160 -Node: Debug levels71009 -Node: Solving problems71945 -Node: Error messages73371 -Node: Sending bug reports77688 -Node: Controlling tinc78635 -Node: tinc runtime options79012 -Node: tinc environment variables79699 -Node: tinc commands80028 -Node: tinc examples85138 -Node: tinc top85701 -Node: Technical information87286 -Node: The connection87521 -Node: The UDP tunnel87833 -Node: The meta-connection90878 -Node: The meta-protocol92336 -Node: Security97319 -Node: Legacy authentication protocol98656 -Node: Simple Peer-to-Peer Security103273 -Node: Encryption of network packets108933 -Node: Security issues111562 -Node: Platform specific information113297 -Node: Interface configuration113525 -Node: Routes115966 -Node: About us117877 -Node: Contact information118052 -Node: Authors118454 -Node: Concept Index118856 +Node: Top808 +Node: Introduction1128 +Node: Virtual Private Networks1932 +Node: tinc3644 +Node: Supported platforms5156 +Node: Preparations5852 +Node: Configuring the kernel6108 +Node: Configuration of Linux kernels6517 +Node: Configuration of FreeBSD kernels7366 +Node: Configuration of OpenBSD kernels7831 +Node: Configuration of NetBSD kernels8439 +Node: Configuration of Solaris kernels8841 +Node: Configuration of Darwin (MacOS/X) kernels9502 +Node: Configuration of Windows10191 +Node: Libraries10704 +Node: OpenSSL11140 +Node: zlib13412 +Node: lzo14430 +Node: libcurses15420 +Node: libreadline16330 +Node: Installation17267 +Node: Building and installing tinc18276 +Node: Darwin (MacOS/X) build environment18932 +Node: Cygwin (Windows) build environment19496 +Node: MinGW (Windows) build environment20080 +Node: System files20598 +Node: Device files20863 +Node: Other files21276 +Node: Configuration21889 +Node: Configuration introduction22176 +Node: Multiple networks23697 +Node: How connections work25065 +Node: Configuration files27626 +Node: Main configuration variables29258 +Node: Host configuration variables47397 +Node: Scripts53256 +Node: How to configure56657 +Node: Network interfaces61141 +Node: Example configuration63520 +Node: Running tinc68619 +Node: Runtime options69206 +Node: Signals72066 +Node: Debug levels72915 +Node: Solving problems73851 +Node: Error messages75277 +Node: Sending bug reports79594 +Node: Controlling tinc80541 +Node: tinc runtime options81287 +Node: tinc environment variables81974 +Node: tinc commands82303 +Node: tinc examples87567 +Node: tinc top88129 +Node: Technical information89714 +Node: The connection89949 +Node: The UDP tunnel90261 +Node: The meta-connection93306 +Node: The meta-protocol94764 +Node: Security99747 +Node: Legacy authentication protocol101084 +Node: Simple Peer-to-Peer Security105701 +Node: Encryption of network packets111346 +Node: Security issues113975 +Node: Platform specific information115710 +Node: Interface configuration115938 +Node: Routes118379 +Node: About us120290 +Node: Contact information120465 +Node: Authors120867 +Node: Concept Index121269  End Tag Table diff --git a/doc/tinc.texi b/doc/tinc.texi index acbee94..2cb55a7 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-2013 Ivo Timmermans, +Copyright @copyright{} 1998-2014 Ivo Timmermans, Guus Sliepen and Wessel Dankers . @@ -43,7 +43,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-2013 Ivo Timmermans, +Copyright @copyright{} 1998-2014 Ivo Timmermans, Guus Sliepen and Wessel Dankers . @@ -335,9 +335,10 @@ as explained in the rest of the documentation. @cindex requirements @cindex libraries -Before you can configure or build tinc, you need to have the OpenSSL, -zlib and lzo libraries installed on your system. If you try to configure tinc without -having them installed, configure will give you an error message, and stop. +Before you can configure or build tinc, you need to have the OpenSSL, zlib, +lzo, curses and readline libraries installed on your system. If you try to +configure tinc without having them installed, configure will give you an error +message, and stop. @menu * OpenSSL:: @@ -793,6 +794,9 @@ The actual configuration of the daemon is done in the file @file{@value{sysconfdir}/tinc/@var{netname}/tinc.conf} and at least one other file in the directory @file{@value{sysconfdir}/tinc/@var{netname}/hosts/}. +An optionnal directory @file{@value{sysconfdir}/tinc/@var{netname}/conf.d} can be added from which +any .conf file will be read. + These file consists of comments (lines started with a #) or assignments in the form of @@ -839,23 +843,16 @@ If any is selected, then depending on the operating system both IPv4 and IPv6 or just IPv6 listening sockets will be created. @cindex AutoConnect -@item AutoConnect = (0) [experimental] -If set to a non-zero value, -tinc will try to only have count meta connections to other nodes, -by automatically making or breaking connections to known nodes. -Higher values increase redundancy but also increase meta data overhead. -When using this option, a good value is 3. +@item AutoConnect = (no) [experimental] +If set to yes, tinc will automatically set up meta connections to other nodes, +without requiring @var{ConnectTo} variables. @cindex BindToAddress @item BindToAddress = <@var{address}> [<@var{port}>] -If your computer has more than one IPv4 or IPv6 address, tinc -will by default listen on all of them for incoming connections. -Multiple BindToAddress variables may be specified, -in which case listening sockets for each specified address are made. - -If no @var{port} is specified, the socket will be bound to the port specified by the Port option, -or to port 655 if neither is given. -To only bind to a specific port but not to a specific address, use "*" for the @var{address}. +This is the same as ListenAddress, however the address given with the BindToAddress option +will also be used for outgoing connections. +This is useful if your computer has more than one IPv4 or IPv6 address, +and you want tinc to only use a specific one for outgoing packets. @cindex BindToInterface @item BindToInterface = <@var{interface}> [experimental] @@ -887,6 +884,18 @@ Broadcast packets received from other nodes are never forwarded. If the IndirectData option is also set, broadcast packets will only be sent to nodes which we have a meta connection to. @end table +@cindex BroadcastSubnet +@item BroadcastSubnet = @var{address}[/@var{prefixlength}] +Declares a broadcast subnet. +Any packet with a destination address falling into such a subnet will be routed as a broadcast +(provided all nodes have it declared). +This is most useful to declare subnet broadcast addresses (e.g. 10.42.255.255), +otherwise tinc won't know what to do with them. + +Note that global broadcast addresses (MAC ff:ff:ff:ff:ff:ff, IPv4 255.255.255.255), +as well as multicast space (IPv4 224.0.0.0/4, IPv6 ff00::/8) +are always considered broadcast addresses and don't need to be declared. + @cindex ConnectTo @item ConnectTo = <@var{name}> Specifies which other tinc daemon to connect to on startup. @@ -895,7 +904,7 @@ in which case outgoing connections to each specified tinc daemon are made. The names should be known to this tinc daemon (i.e., there should be a host configuration file for the name on the ConnectTo line). -If you don't specify a host with ConnectTo, +If you don't specify a host with ConnectTo and don't enable AutoConnect, tinc won't try to connect to other daemons at all, and will instead just listen for incoming connections. @@ -917,6 +926,13 @@ Under Windows, use @var{Interface} instead of @var{Device}. Note that you can only use one device per daemon. See also @ref{Device files}. +@cindex DeviceStandby +@item DeviceStandby = (no) +When disabled, tinc calls @file{tinc-up} on startup, and @file{tinc-down} on shutdown. +When enabled, tinc will only call @file{tinc-up} when at least one node is reachable, +and will call @file{tinc-down} as soon as no nodes are reachable. +On Windows, this also determines when the virtual network interface "cable" is "plugged". + @cindex DeviceType @item DeviceType = <@var{type}> (platform dependent) The type of the virtual network device. @@ -996,18 +1012,18 @@ but which would have to be forwarded by an intermediate node, are dropped instea When combined with the IndirectData option, packets for nodes for which we do not have a meta connection with are also dropped. -@cindex ECDSAPrivateKeyFile -@item ECDSAPrivateKeyFile = <@var{path}> (@file{@value{sysconfdir}/tinc/@var{netname}/ecdsa_key.priv}) -The file in which the private ECDSA key of this tinc daemon resides. +@cindex Ed25519PrivateKeyFile +@item Ed25519PrivateKeyFile = <@var{path}> (@file{@value{sysconfdir}/tinc/@var{netname}/ed25519_key.priv}) +The file in which the private Ed25519 key of this tinc daemon resides. This is only used if ExperimentalProtocol is enabled. @cindex ExperimentalProtocol @item ExperimentalProtocol = (yes) When this option is enabled, the SPTPS protocol will be used when connecting to nodes that also support it. Ephemeral ECDH will be used for key exchanges, -and ECDSA will be used instead of RSA for authentication. -When enabled, an ECDSA key must have been generated before with -@samp{tinc generate-ecdsa-keys}. +and Ed25519 will be used instead of RSA for authentication. +When enabled, an Ed25519 key must have been generated before with +@samp{tinc generate-ed25519-keys}. @cindex Forwarding @item Forwarding = (internal) [experimental] @@ -1046,6 +1062,18 @@ Depending on the operating system and the type of device this may or may not act Under Windows, this variable is used to select which network interface will be used. If you specified a Device, this variable is almost always already correctly set. +@cindex ListenAddress +@item ListenAddress = <@var{address}> [<@var{port}>] +If your computer has more than one IPv4 or IPv6 address, tinc +will by default listen on all of them for incoming connections. +This option can be used to restrict which addresses tinc listens on. +Multiple ListenAddress variables may be specified, +in which case listening sockets for each specified address are made. + +If no @var{port} is specified, the socket will listen on the port specified by the Port option, +or to port 655 if neither is given. +To only listen on a specific port but not to a specific address, use "*" for the @var{address}. + @cindex LocalDiscovery @item LocalDiscovery = (no) When enabled, tinc will try to detect peers that are on the same local network. @@ -1152,7 +1180,7 @@ 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 Proxy -@item Proxy = socks4 | socks4 | http | exec @var{...} [experimental] +@item Proxy = socks4 | socks5 | http | exec @var{...} [experimental] Use a proxy when making outgoing connections. The following proxy types are currently supported: @@ -1163,7 +1191,7 @@ Connects to the proxy using the SOCKS version 4 protocol. Optionally, a @var{username} can be supplied which will be passed on to the proxy server. @cindex socks5 -@item socks4 <@var{address}> <@var{port}> [<@var{username}> <@var{password}>] +@item socks5 <@var{address}> <@var{port}> [<@var{username}> <@var{password}>] Connect to the proxy using the SOCKS version 5 protocol. If a @var{username} and @var{password} are given, basic username/password authentication will be used, otherwise no authentication will be used. @@ -1190,10 +1218,12 @@ pass all traffic, but leaves tinc vulnerable to replay-based attacks on your traffic. @cindex StrictSubnets -@item StrictSubnets (no) [experimental] +@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. +Subnets learned via connections to other nodes and which are not +present in the local host config files are ignored. @cindex TunnelServer @item TunnelServer = (no) [experimental] @@ -1226,6 +1256,8 @@ 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. +Multiple Address variables can be specified, in which case each address will be +tried until a working connection has been established. @cindex Cipher @item Cipher = <@var{cipher}> (blowfish) @@ -1336,6 +1368,12 @@ TCP connection instead of a UDP connection. This is especially useful for those who want to run a tinc daemon from behind a masquerading firewall, or if UDP packet routing is disabled somehow. Setting this options also implicitly sets IndirectData. + +@cindex Weight +@item Weight = +If this variable is set, it overrides the weight given to connections made with +another host. A higher weight means a lower priority is given to this +connection when broadcasting or forwarding packets. @end table @@ -1471,9 +1509,9 @@ In the configuration directory, it will create the file @file{tinc.conf} with th Name = @var{name} @end example -It will also create private RSA and ECDSA keys, which will be stored in the files @file{rsa_key.priv} and @file{ecdsa_key.priv}. +It will also create private RSA and Ed25519 keys, which will be stored in the files @file{rsa_key.priv} and @file{ed25519_key.priv}. It will also create a host configuration file @file{hosts/@var{name}}, -which will contain the corresponding public RSA and ECDSA keys. +which will contain the corresponding public RSA and Ed25519 keys. Finally, on UNIX operating systems, it will create an executable script @file{tinc-up}, which will initially not do anything except warning that you should edit it. @@ -1492,7 +1530,7 @@ tinc -n @var{netname} add subnet 192.168.2.0/24 This will add a Subnet statement to your host configuration file. Try opening the file @file{@value{sysconfdir}/tinc/@var{netname}/hosts/@var{name}} in an editor. -You should now see a file containing the public RSA and ECDSA keys (which looks like a bunch of random characters), +You should now see a file containing the public RSA and Ed25519 keys (which looks like a bunch of random characters), and the following line at the bottom: @example @@ -1803,8 +1841,8 @@ Address = 4.5.6.7 A, B, C and D all have their own public/private keypairs: The private RSA key is stored in @file{@value{sysconfdir}/tinc/company/rsa_key.priv}, -the private ECDSA key is stored in @file{@value{sysconfdir}/tinc/company/ecdsa_key.priv}, -and the public RSA and ECDSA keys are put into the host configuration file in the @file{@value{sysconfdir}/tinc/company/hosts/} directory. +the private Ed25519 key is stored in @file{@value{sysconfdir}/tinc/company/ed25519_key.priv}, +and the public RSA and Ed25519 keys are put into the host configuration file in the @file{@value{sysconfdir}/tinc/company/hosts/} directory. @subsubheading Starting @@ -2146,13 +2184,21 @@ Be sure to include the following information in your bugreport: @node Controlling tinc @chapter Controlling tinc -You can control and inspect a running tincd through the tinc +@cindex command line interface +You can start, stop, control and inspect a running tincd through the tinc command. A quick example: @example tinc -n @var{netname} reload @end example +@cindex shell +If tinc is started without a command, it will act as a shell; it will display a +prompt, and commands can be entered on the prompt. If tinc is compiled with +libreadline, history and command completion are available on the prompt. One +can also pipe a script containing commands through tinc. In that case, lines +starting with a # symbol will be ignored. + @menu * tinc runtime options:: * tinc environment variables:: @@ -2206,85 +2252,107 @@ the value of this environment variable is used. @c from the manpage @table @code +@cindex init @item init [@var{name}] -Create initial configuration files and RSA and ECDSA keypairs with default length. +Create initial configuration files and RSA and Ed25519 keypairs with default length. If no @var{name} for this node is given, it will be asked for. +@cindex get @item get @var{variable} Print the current value of configuration variable @var{variable}. If more than one variable with the same name exists, the value of each of them will be printed on a separate line. +@cindex set @item set @var{variable} @var{value} Set configuration variable @var{variable} to the given @var{value}. All previously existing configuration variables with the same name are removed. To set a variable for a specific host, use the notation @var{host}.@var{variable}. +@cindex add @item add @var{variable} @var{value} As above, but without removing any previously existing configuration variables. +@cindex del @item del @var{variable} [@var{value}] Remove configuration variables with the same name and @var{value}. If no @var{value} is given, all configuration variables with the same name will be removed. +@cindex edit @item edit @var{filename} Start an editor for the given configuration file. You do not need to specify the full path to the file. +@cindex export @item export Export the host configuration file of the local node to standard output. +@cindex export-all @item export-all Export all host configuration files to standard output. +@cindex import @item import [--force] Import host configuration file(s) generated by the tinc export command from standard input. Already existing host configuration files are not overwritten unless the option --force is used. +@cindex exchange @item exchange [--force] The same as export followed by import. +@cindex exchange-all @item exchange-all [--force] The same as export-all followed by import. +@cindex invite @item invite @var{name} Prepares an invitation for a new node with the given @var{name}, and prints a short invitation URL that can be used with the join command. +@cindex join @item join [@var{URL}] Join an existing VPN using an invitation URL created using the invite command. If no @var{URL} is given, it will be read from standard input. +@cindex start @item start [tincd options] Start @samp{tincd}, optionally with the given extra options. +@cindex stop @item stop Stop @samp{tincd}. +@cindex restart @item restart [tincd options] Restart @samp{tincd}, optionally with the given extra options. +@cindex reload @item reload Partially rereads configuration files. Connections to hosts whose host config files are removed are closed. New outgoing connections specified in @file{tinc.conf} will be made. +@cindex pid @item pid Shows the PID of the currently running @samp{tincd}. +@cindex generate-keys @item generate-keys [@var{bits}] -Generate both RSA and ECDSA keypairs (see below) and exit. +Generate both RSA and Ed25519 keypairs (see below) and exit. tinc will ask where you want to store the files, but will default to the configuration directory (you can use the -c or -n option). -@item generate-ecdsa-keys -Generate public/private ECDSA keypair and exit. +@cindex generate-ed25519-keys +@item generate-ed25519-keys +Generate public/private Ed25519 keypair and exit. +@cindex generate-rsa-keys @item generate-rsa-keys [@var{bits}] Generate public/private RSA keypair and exit. If @var{bits} is omitted, the default length will be 2048 bits. When saving keys to existing files, tinc will not delete the old keys; you have to remove them manually. +@cindex dump @item dump [reachable] nodes Dump a list of all known nodes in the VPN. If the reachable keyword is used, only lists reachable nodes. @@ -2298,26 +2366,32 @@ Dump a list of all known subnets in the VPN. @item dump connections Dump a list of all meta connections with ourself. +@cindex graph @item dump graph | digraph Dump a graph of the VPN in dotty format. Nodes are colored according to their reachability: red nodes are unreachable, orange nodes are indirectly reachable, green nodes are directly reachable. Black nodes are either directly or indirectly reachable, but direct reachability has not been tried yet. +@cindex info @item info @var{node} | @var{subnet} | @var{address} Show information about a particular @var{node}, @var{subnet} or @var{address}. If an @var{address} is given, any matching subnet will be shown. +@cindex purge @item purge Purges all information remembered about unreachable nodes. +@cindex debug @item debug @var{level} Sets debug level to @var{level}. +@cindex log @item log [@var{level}] Capture log messages from a running tinc daemon. An optional debug level can be given that will be applied only for log messages sent to tinc. +@cindex retry @item retry Forces tinc to try to connect to all uplinks immediately. Usually tinc attempts to do this itself, @@ -2325,19 +2399,27 @@ but increases the time it waits between the attempts each time it failed, and if tinc didn't succeed to connect to an uplink the first time after it started, it defaults to the maximum time of 15 minutes. +@cindex disconnect @item disconnect @var{node} Closes the meta connection with the given @var{node}. +@cindex top @item top If tinc is compiled with libcurses support, this will display live traffic statistics for all the known nodes, similar to the UNIX top command. See below for more information. +@cindex pcap @item pcap Dump VPN traffic going through the local tinc node in pcap-savefile format to standard output, from where it can be redirected to a file or piped through a program that can parse it directly, such as tcpdump. +@cindex network [@var{netname}] +@item network +If @var{netname} is given, switch to that network. +Otherwise, display a list of all networks for which configuration files exist. + @end table @c ================================================================== @@ -2352,7 +2434,7 @@ tinc -n vpn pcap | tcpdump -r - tinc -n vpn top @end example -Example of configuring tinc using the tinc command: +Examples of changing the configuration using tinc: @example tinc -n vpn init foo @@ -2366,6 +2448,7 @@ tinc -n vpn export | gpg --clearsign | mail -s "My config" vpnmaster@@example.co @node tinc top @section tinc top +@cindex top The top command connects to a running tinc daemon and repeatedly queries its per-node traffic counters. It displays a list of all the known nodes in the left-most column, and the amount of bytes and packets read from and sent to each node in the other columns. @@ -2946,12 +3029,12 @@ The expanded key is used as follows: Where initiator_cipher_key is the key used by session initiator to encrypt messages sent to the responder. -When using 521 bits EC keys, the AES-256-CTR cipher and HMAC-SHA-256 digest algorithm, +When using 256 bits Ed25519 keys, the AES-256-CTR cipher and HMAC-SHA-256 digest algorithm, the sizes are as follows: @example -ECDH_SIZE: 67 (= ceil(521/8) + 1) -ECDSA_SIZE: 141 (= 2 * ceil(521/8) + 9) +ECDH_SIZE: 32 (= 256/8) +ECDSA_SIZE: 64 (= 2 * 256/8) CIPHER_KEYSIZE: 48 (= 256/8 + 128/8) DIGEST_KEYSIZE: 32 (= 256/8) @end example diff --git a/gui/Makefile.in b/gui/Makefile.in index 7232f33..772b4ae 100644 --- a/gui/Makefile.in +++ b/gui/Makefile.in @@ -1,4 +1,4 @@ -# Makefile.in generated by automake 1.14 from Makefile.am. +# Makefile.in generated by automake 1.14.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. @@ -83,9 +83,12 @@ DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(dist_bin_SCRIPTS) ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \ - $(top_srcdir)/m4/curses.m4 $(top_srcdir)/m4/lzo.m4 \ - $(top_srcdir)/m4/openssl.m4 $(top_srcdir)/m4/readline.m4 \ - $(top_srcdir)/m4/zlib.m4 $(top_srcdir)/configure.ac + $(top_srcdir)/m4/ax_check_compile_flag.m4 \ + $(top_srcdir)/m4/ax_check_link_flag.m4 \ + $(top_srcdir)/m4/curses.m4 $(top_srcdir)/m4/libgcrypt.m4 \ + $(top_srcdir)/m4/lzo.m4 $(top_srcdir)/m4/openssl.m4 \ + $(top_srcdir)/m4/readline.m4 $(top_srcdir)/m4/zlib.m4 \ + $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d @@ -170,9 +173,6 @@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ -LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ -LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ -LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LN_S = @LN_S@ @@ -188,7 +188,6 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ -RANLIB = @RANLIB@ READLINE_LIBS = @READLINE_LIBS@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ diff --git a/gui/tinc-gui b/gui/tinc-gui index 2b4f903..0a6370a 100755 --- a/gui/tinc-gui +++ b/gui/tinc-gui @@ -1,7 +1,8 @@ -#!/usr/bin/python +#!/usr/bin/env python # tinc-gui -- GUI for controlling a running tincd -# Copyright (C) 2009-2012 Guus Sliepen +# Copyright (C) 2009-2014 Guus Sliepen +# 2014 Dennis Joachimsthaler # # 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 @@ -27,7 +28,7 @@ import time from wx.lib.mixins.listctrl import ColumnSorterMixin from wx.lib.mixins.listctrl import ListCtrlAutoWidthMixin -if platform.system == 'Windows': +if platform.system() == 'Windows': import _winreg # Classes to interface with a running tinc daemon @@ -77,8 +78,8 @@ class Edge: self.to = args[1] self.address = args[2] self.port = args[4] - self.options = int(args[5], 16) - self.weight = int(args[6]) + self.options = int(args[-2], 16) + self.weight = int(args[-1]) class Subnet: def parse(self, args): @@ -130,7 +131,11 @@ class VPN: else: # otherwise connect via TCP print(unixfile + " does not exist."); - s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + if ':' in info[2]: + af = socket.AF_INET6 + else: + af = socket.AF_INET + s = socket.socket(af, socket.SOCK_STREAM) s.connect((info[2], int(info[4]))) self.sf = s.makefile() @@ -187,6 +192,8 @@ class VPN: subnet.parse(resp[2:]) subnet.visited = True self.subnets[(resp[2], resp[3])] = subnet + if subnet.owner == "(broadcast)": + continue self.nodes[subnet.owner].subnets[resp[2]] = subnet elif resp[1] == '6': if len(resp) < 9: @@ -233,10 +240,16 @@ class VPN: return int(resp[2]) def __init__(self, netname = None, pidfile = None): - if platform.system == 'Windows': + if platform.system() == 'Windows': + sam = _winreg.KEY_READ + if platform.machine().endswith('64'): + sam = sam | _winreg.KEY_WOW64_64KEY try: - reg = _winreg.ConnectRegistry(None, HKEY_LOCAL_MACHINE) - key = _winreg.OpenKey(reg, "SOFTWARE\\tinc") + reg = _winreg.ConnectRegistry(None, _winreg.HKEY_LOCAL_MACHINE) + try: + key = _winreg.OpenKey(reg, "SOFTWARE\\tinc", 0, sam) + except WindowsError: + key = _winreg.OpenKey(reg, "SOFTWARE\\Wow6432Node\\tinc", 0, sam) VPN.confdir = _winreg.QueryValue(key, None) except WindowsError: pass @@ -252,7 +265,7 @@ class VPN: if pidfile != None: self.pidfile = pidfile else: - if platform.system == 'Windows': + if platform.system() == 'Windows': self.pidfile = os.path.join(self.confbase, 'pid') else: if netname: @@ -524,7 +537,7 @@ class SubnetsPage(wx.Panel): self.list.InsertStringItem(i, subnet.address + '/' + subnet.prefixlen) else: self.list.SetStringItem(i, 0, subnet.address + '/' + subnet.prefixlen) - self.list.SetStringItem(i, 1, subnet.weight) + self.list.SetStringItem(i, 1, str(subnet.weight)) self.list.SetStringItem(i, 2, subnet.owner) self.list.itemDataMap[i] = (subnet.address + '/' + subnet.prefixlen, subnet.weight, subnet.owner) self.list.SetItemData(i, i) diff --git a/m4/Makefile.in b/m4/Makefile.in index b722bcc..4097869 100644 --- a/m4/Makefile.in +++ b/m4/Makefile.in @@ -1,4 +1,4 @@ -# Makefile.in generated by automake 1.14 from Makefile.am. +# Makefile.in generated by automake 1.14.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. @@ -81,9 +81,12 @@ subdir = m4 DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am README ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \ - $(top_srcdir)/m4/curses.m4 $(top_srcdir)/m4/lzo.m4 \ - $(top_srcdir)/m4/openssl.m4 $(top_srcdir)/m4/readline.m4 \ - $(top_srcdir)/m4/zlib.m4 $(top_srcdir)/configure.ac + $(top_srcdir)/m4/ax_check_compile_flag.m4 \ + $(top_srcdir)/m4/ax_check_link_flag.m4 \ + $(top_srcdir)/m4/curses.m4 $(top_srcdir)/m4/libgcrypt.m4 \ + $(top_srcdir)/m4/lzo.m4 $(top_srcdir)/m4/openssl.m4 \ + $(top_srcdir)/m4/readline.m4 $(top_srcdir)/m4/zlib.m4 \ + $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d @@ -139,9 +142,6 @@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ -LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ -LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ -LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LN_S = @LN_S@ @@ -157,7 +157,6 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ -RANLIB = @RANLIB@ READLINE_LIBS = @READLINE_LIBS@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ diff --git a/m4/ax_check_compile_flag.m4 b/m4/ax_check_compile_flag.m4 new file mode 100644 index 0000000..c3a8d69 --- /dev/null +++ b/m4/ax_check_compile_flag.m4 @@ -0,0 +1,72 @@ +# =========================================================================== +# http://www.gnu.org/software/autoconf-archive/ax_check_compile_flag.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_CHECK_COMPILE_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS]) +# +# DESCRIPTION +# +# Check whether the given FLAG works with the current language's compiler +# or gives an error. (Warnings, however, are ignored) +# +# ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on +# success/failure. +# +# If EXTRA-FLAGS is defined, it is added to the current language's default +# flags (e.g. CFLAGS) when the check is done. The check is thus made with +# the flags: "CFLAGS EXTRA-FLAGS FLAG". This can for example be used to +# force the compiler to issue an error when a bad flag is given. +# +# NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this +# macro in sync with AX_CHECK_{PREPROC,LINK}_FLAG. +# +# LICENSE +# +# Copyright (c) 2008 Guido U. Draheim +# Copyright (c) 2011 Maarten Bosmans +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +# Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program. If not, see . +# +# As a special exception, the respective Autoconf Macro's copyright owner +# gives unlimited permission to copy, distribute and modify the configure +# scripts that are the output of Autoconf when processing the Macro. You +# need not follow the terms of the GNU General Public License when using +# or distributing such scripts, even though portions of the text of the +# Macro appear in them. The GNU General Public License (GPL) does govern +# all other use of the material that constitutes the Autoconf Macro. +# +# This special exception to the GPL applies to versions of the Autoconf +# Macro released by the Autoconf Archive. When you make and distribute a +# modified version of the Autoconf Macro, you may extend this special +# exception to the GPL to apply to your modified version as well. + +#serial 2 + +AC_DEFUN([AX_CHECK_COMPILE_FLAG], +[AC_PREREQ(2.59)dnl for _AC_LANG_PREFIX +AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_[]_AC_LANG_ABBREV[]flags_$4_$1])dnl +AC_CACHE_CHECK([whether _AC_LANG compiler accepts $1], CACHEVAR, [ + ax_check_save_flags=$[]_AC_LANG_PREFIX[]FLAGS + _AC_LANG_PREFIX[]FLAGS="$[]_AC_LANG_PREFIX[]FLAGS $4 $1" + AC_COMPILE_IFELSE([AC_LANG_PROGRAM()], + [AS_VAR_SET(CACHEVAR,[yes])], + [AS_VAR_SET(CACHEVAR,[no])]) + _AC_LANG_PREFIX[]FLAGS=$ax_check_save_flags]) +AS_IF([test x"AS_VAR_GET(CACHEVAR)" = xyes], + [m4_default([$2], :)], + [m4_default([$3], :)]) +AS_VAR_POPDEF([CACHEVAR])dnl +])dnl AX_CHECK_COMPILE_FLAGS diff --git a/m4/ax_check_link_flag.m4 b/m4/ax_check_link_flag.m4 new file mode 100644 index 0000000..e2d0d36 --- /dev/null +++ b/m4/ax_check_link_flag.m4 @@ -0,0 +1,71 @@ +# =========================================================================== +# http://www.gnu.org/software/autoconf-archive/ax_check_link_flag.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_CHECK_LINK_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS]) +# +# DESCRIPTION +# +# Check whether the given FLAG works with the linker or gives an error. +# (Warnings, however, are ignored) +# +# ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on +# success/failure. +# +# If EXTRA-FLAGS is defined, it is added to the linker's default flags +# when the check is done. The check is thus made with the flags: "LDFLAGS +# EXTRA-FLAGS FLAG". This can for example be used to force the linker to +# issue an error when a bad flag is given. +# +# NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this +# macro in sync with AX_CHECK_{PREPROC,COMPILE}_FLAG. +# +# LICENSE +# +# Copyright (c) 2008 Guido U. Draheim +# Copyright (c) 2011 Maarten Bosmans +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +# Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program. If not, see . +# +# As a special exception, the respective Autoconf Macro's copyright owner +# gives unlimited permission to copy, distribute and modify the configure +# scripts that are the output of Autoconf when processing the Macro. You +# need not follow the terms of the GNU General Public License when using +# or distributing such scripts, even though portions of the text of the +# Macro appear in them. The GNU General Public License (GPL) does govern +# all other use of the material that constitutes the Autoconf Macro. +# +# This special exception to the GPL applies to versions of the Autoconf +# Macro released by the Autoconf Archive. When you make and distribute a +# modified version of the Autoconf Macro, you may extend this special +# exception to the GPL to apply to your modified version as well. + +#serial 2 + +AC_DEFUN([AX_CHECK_LINK_FLAG], +[AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_ldflags_$4_$1])dnl +AC_CACHE_CHECK([whether the linker accepts $1], CACHEVAR, [ + ax_check_save_flags=$LDFLAGS + LDFLAGS="$LDFLAGS $4 $1" + AC_LINK_IFELSE([AC_LANG_PROGRAM()], + [AS_VAR_SET(CACHEVAR,[yes])], + [AS_VAR_SET(CACHEVAR,[no])]) + LDFLAGS=$ax_check_save_flags]) +AS_IF([test x"AS_VAR_GET(CACHEVAR)" = xyes], + [m4_default([$2], :)], + [m4_default([$3], :)]) +AS_VAR_POPDEF([CACHEVAR])dnl +])dnl AX_CHECK_LINK_FLAGS diff --git a/m4/curses.m4 b/m4/curses.m4 index 50a90a5..2e8d151 100644 --- a/m4/curses.m4 +++ b/m4/curses.m4 @@ -31,9 +31,12 @@ AC_DEFUN([tinc_CURSES], [AC_MSG_ERROR("curses header files not found."); break] ) - AC_CHECK_LIB(curses, initscr, - [CURSES_LIBS="-lcurses"], - [AC_MSG_ERROR("curses libraries not found.")] + AC_CHECK_LIB(ncurses, initscr, + [CURSES_LIBS="-lncurses"], + [AC_CHECK_LIB(curses, initscr, + [CURSES_LIBS="-lcurses"], + [AC_MSG_ERROR("curses libraries not found.")] + )] ) ]) diff --git a/m4/libgcrypt.m4 b/m4/libgcrypt.m4 new file mode 100644 index 0000000..01c7478 --- /dev/null +++ b/m4/libgcrypt.m4 @@ -0,0 +1,33 @@ +dnl Check to find the libgcrypt headers/libraries + +AC_DEFUN([tinc_LIBGCRYPT], +[ + AC_ARG_WITH(libgcrypt, + AS_HELP_STRING([--with-libgcrypt=DIR], [libgcrypt base directory, or:]), + [libgcrypt="$withval" + CPPFLAGS="$CPPFLAGS -I$withval/include" + LDFLAGS="$LDFLAGS -L$withval/lib"] + ) + + AC_ARG_WITH(libgcrypt-include, + AS_HELP_STRING([--with-libgcrypt-include=DIR], [libgcrypt headers directory (without trailing /libgcrypt)]), + [libgcrypt_include="$withval" + CPPFLAGS="$CPPFLAGS -I$withval"] + ) + + AC_ARG_WITH(libgcrypt-lib, + AS_HELP_STRING([--with-libgcrypt-lib=DIR], [libgcrypt library directory]), + [libgcrypt_lib="$withval" + LDFLAGS="$LDFLAGS -L$withval"] + ) + + AC_CHECK_HEADERS([gcrypt.h], + [], + [AC_MSG_ERROR([libgcrypt header files not found.]); break] + ) + + AC_CHECK_LIB(gcrypt, gcry_cipher_encrypt, + [LIBS="-lgcrypt $LIBS"], + [AC_MSG_ERROR([libgcrypt libraries not found.])] + ) +]) diff --git a/m4/openssl.m4 b/m4/openssl.m4 index 922e468..738c68c 100644 --- a/m4/openssl.m4 +++ b/m4/openssl.m4 @@ -35,7 +35,7 @@ AC_DEFUN([tinc_OPENSSL], LDFLAGS="$LDFLAGS -L$withval"] ) - AC_CHECK_HEADERS([openssl/evp.h openssl/rsa.h openssl/rand.h openssl/err.h openssl/sha.h openssl/pem.h openssl/engine.h openssl/ecdh.h openssl/ec.h], + AC_CHECK_HEADERS([openssl/evp.h openssl/rsa.h openssl/rand.h openssl/err.h openssl/sha.h openssl/pem.h openssl/engine.h], [], [AC_MSG_ERROR([OpenSSL header files not found.]); break] ) @@ -45,11 +45,11 @@ AC_DEFUN([tinc_OPENSSL], [AC_MSG_ERROR([OpenSSL libraries not found.])] ) - AC_CHECK_FUNCS([RAND_pseudo_bytes EVP_EncryptInit_ex ECDH_compute_key ECDSA_verify], , + AC_CHECK_FUNCS([RAND_status EVP_EncryptInit_ex], , [AC_MSG_ERROR([Missing OpenSSL functionality, make sure you have installed the latest version.]); break], ) - AC_CHECK_DECL([OpenSSL_add_all_algorithms], , + AC_CHECK_DECLS([OpenSSL_add_all_algorithms], , [AC_MSG_ERROR([Missing OpenSSL functionality, make sure you have installed the latest version.]); break], [#include ] ) diff --git a/missing b/missing index cdea514..db98974 100755 --- a/missing +++ b/missing @@ -1,7 +1,7 @@ #! /bin/sh # Common wrapper for a few potentially missing GNU programs. -scriptversion=2012-06-26.16; # UTC +scriptversion=2013-10-28.13; # UTC # Copyright (C) 1996-2013 Free Software Foundation, Inc. # Originally written by Fran,cois Pinard , 1996. @@ -160,7 +160,7 @@ give_advice () ;; autom4te*) echo "You might have modified some maintainer files that require" - echo "the 'automa4te' program to be rebuilt." + echo "the 'autom4te' program to be rebuilt." program_details 'autom4te' ;; bison*|yacc*) diff --git a/src/Makefile.am b/src/Makefile.am index 9664352..cd84f3a 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,9 +1,36 @@ ## Produce this file with automake to get Makefile.in -sbin_PROGRAMS = tincd tinc sptps_test +sbin_PROGRAMS = tincd tinc sptps_test sptps_keypair + +## Make sure version.c is always rebuilt +.PHONY: version.c +version.c: + +if LINUX +sbin_PROGRAMS += sptps_speed +endif DEFAULT_INCLUDES = +ed25519_SOURCES = \ + ed25519/add_scalar.c \ + ed25519/ed25519.h \ + ed25519/fe.c ed25519/fe.h \ + ed25519/fixedint.h \ + ed25519/ge.c ed25519/ge.h \ + ed25519/key_exchange.c \ + ed25519/keypair.c \ + ed25519/precomp_data.h \ + ed25519/sc.c ed25519/sc.h \ + ed25519/sha512.c ed25519/sha512.h \ + ed25519/sign.c \ + ed25519/verify.c + +chacha_poly1305_SOURCES = \ + chacha-poly1305/chacha.c chacha-poly1305/chacha.h \ + chacha-poly1305/chacha-poly1305.c chacha-poly1305/chacha-poly1305.h \ + chacha-poly1305/poly1305.c chacha-poly1305/poly1305.h + tincd_SOURCES = \ buffer.c buffer.h \ cipher.h \ @@ -63,7 +90,10 @@ tincd_SOURCES = \ system.h \ tincd.c \ utils.c utils.h \ - xalloc.h + xalloc.h \ + version.c version.h \ + $(ed25519_SOURCES) \ + $(chacha_poly1305_SOURCES) tinc_SOURCES = \ dropin.c dropin.h \ @@ -79,13 +109,31 @@ tinc_SOURCES = \ subnet_parse.c subnet.h \ tincctl.c tincctl.h \ top.c top.h \ - utils.c utils.h + utils.c utils.h \ + version.c version.h \ + $(ed25519_SOURCES) \ + $(chacha_poly1305_SOURCES) sptps_test_SOURCES = \ logger.c logger.h \ sptps.c sptps.h \ sptps_test.c \ - utils.c utils.h + utils.c utils.h \ + $(ed25519_SOURCES) \ + $(chacha_poly1305_SOURCES) + +sptps_keypair_SOURCES = \ + sptps_keypair.c \ + utils.c utils.h \ + $(ed25519_SOURCES) + +sptps_speed_SOURCES = \ + logger.c logger.h \ + sptps.c sptps.h \ + sptps_speed.c \ + utils.c utils.h \ + $(ed25519_SOURCES) \ + $(chacha_poly1305_SOURCES) ## Conditionally compile device drivers @@ -125,26 +173,35 @@ tincd_SOURCES += \ openssl/cipher.c \ openssl/crypto.c \ openssl/digest.c openssl/digest.h \ - openssl/ecdh.c \ - openssl/ecdsa.c \ + ed25519/ecdh.c \ + ed25519/ecdsa.c \ openssl/prf.c \ openssl/rsa.c tinc_SOURCES += \ openssl/cipher.c \ openssl/crypto.c \ openssl/digest.c openssl/digest.h \ - openssl/ecdh.c \ - openssl/ecdsa.c \ - openssl/ecdsagen.c \ + ed25519/ecdh.c \ + ed25519/ecdsa.c \ + ed25519/ecdsagen.c \ openssl/prf.c \ openssl/rsa.c \ openssl/rsagen.c sptps_test_SOURCES += \ - openssl/cipher.c \ openssl/crypto.c \ openssl/digest.c openssl/digest.h \ - openssl/ecdh.c \ - openssl/ecdsa.c \ + ed25519/ecdh.c \ + ed25519/ecdsa.c \ + openssl/prf.c +sptps_keypair_SOURCES += \ + openssl/crypto.c \ + ed25519/ecdsagen.c +sptps_speed_SOURCES += \ + openssl/crypto.c \ + openssl/digest.c openssl/digest.h \ + ed25519/ecdh.c \ + ed25519/ecdsa.c \ + ed25519/ecdsagen.c \ openssl/prf.c endif @@ -177,8 +234,9 @@ sptps_test_SOURCES += \ endif tinc_LDADD = $(READLINE_LIBS) $(CURSES_LIBS) +sptps_speed_LDADD = -lrt -LIBS = @LIBS@ @LIBGCRYPT_LIBS@ +LIBS = @LIBS@ if TUNEMU LIBS += -lpcap diff --git a/src/Makefile.in b/src/Makefile.in index a29f6a7..bb7213a 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -1,4 +1,4 @@ -# Makefile.in generated by automake 1.14 from Makefile.am. +# Makefile.in generated by automake 1.14.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. @@ -78,44 +78,57 @@ PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ -sbin_PROGRAMS = tincd$(EXEEXT) tinc$(EXEEXT) sptps_test$(EXEEXT) -@LINUX_TRUE@am__append_1 = linux/device.c -@BSD_TRUE@am__append_2 = bsd/device.c -@BSD_TRUE@@TUNEMU_TRUE@am__append_3 = bsd/tunemu.c bsd/tunemu.h -@SOLARIS_TRUE@am__append_4 = solaris/device.c -@MINGW_TRUE@am__append_5 = mingw/device.c mingw/common.h -@CYGWIN_TRUE@am__append_6 = cygwin/device.c -@UML_TRUE@am__append_7 = uml_device.c -@VDE_TRUE@am__append_8 = vde_device.c -@OPENSSL_TRUE@am__append_9 = \ -@OPENSSL_TRUE@ openssl/cipher.c \ -@OPENSSL_TRUE@ openssl/crypto.c \ -@OPENSSL_TRUE@ openssl/digest.c openssl/digest.h \ -@OPENSSL_TRUE@ openssl/ecdh.c \ -@OPENSSL_TRUE@ openssl/ecdsa.c \ -@OPENSSL_TRUE@ openssl/prf.c \ -@OPENSSL_TRUE@ openssl/rsa.c - +sbin_PROGRAMS = tincd$(EXEEXT) tinc$(EXEEXT) sptps_test$(EXEEXT) \ + sptps_keypair$(EXEEXT) $(am__EXEEXT_1) +@LINUX_TRUE@am__append_1 = sptps_speed +@LINUX_TRUE@am__append_2 = linux/device.c +@BSD_TRUE@am__append_3 = bsd/device.c +@BSD_TRUE@@TUNEMU_TRUE@am__append_4 = bsd/tunemu.c bsd/tunemu.h +@SOLARIS_TRUE@am__append_5 = solaris/device.c +@MINGW_TRUE@am__append_6 = mingw/device.c mingw/common.h +@CYGWIN_TRUE@am__append_7 = cygwin/device.c +@UML_TRUE@am__append_8 = uml_device.c +@VDE_TRUE@am__append_9 = vde_device.c @OPENSSL_TRUE@am__append_10 = \ @OPENSSL_TRUE@ openssl/cipher.c \ @OPENSSL_TRUE@ openssl/crypto.c \ @OPENSSL_TRUE@ openssl/digest.c openssl/digest.h \ -@OPENSSL_TRUE@ openssl/ecdh.c \ -@OPENSSL_TRUE@ openssl/ecdsa.c \ -@OPENSSL_TRUE@ openssl/ecdsagen.c \ +@OPENSSL_TRUE@ ed25519/ecdh.c \ +@OPENSSL_TRUE@ ed25519/ecdsa.c \ @OPENSSL_TRUE@ openssl/prf.c \ -@OPENSSL_TRUE@ openssl/rsa.c \ -@OPENSSL_TRUE@ openssl/rsagen.c +@OPENSSL_TRUE@ openssl/rsa.c @OPENSSL_TRUE@am__append_11 = \ @OPENSSL_TRUE@ openssl/cipher.c \ @OPENSSL_TRUE@ openssl/crypto.c \ @OPENSSL_TRUE@ openssl/digest.c openssl/digest.h \ -@OPENSSL_TRUE@ openssl/ecdh.c \ -@OPENSSL_TRUE@ openssl/ecdsa.c \ +@OPENSSL_TRUE@ ed25519/ecdh.c \ +@OPENSSL_TRUE@ ed25519/ecdsa.c \ +@OPENSSL_TRUE@ ed25519/ecdsagen.c \ +@OPENSSL_TRUE@ openssl/prf.c \ +@OPENSSL_TRUE@ openssl/rsa.c \ +@OPENSSL_TRUE@ openssl/rsagen.c + +@OPENSSL_TRUE@am__append_12 = \ +@OPENSSL_TRUE@ openssl/crypto.c \ +@OPENSSL_TRUE@ openssl/digest.c openssl/digest.h \ +@OPENSSL_TRUE@ ed25519/ecdh.c \ +@OPENSSL_TRUE@ ed25519/ecdsa.c \ @OPENSSL_TRUE@ openssl/prf.c -@GCRYPT_TRUE@am__append_12 = \ +@OPENSSL_TRUE@am__append_13 = \ +@OPENSSL_TRUE@ openssl/crypto.c \ +@OPENSSL_TRUE@ ed25519/ecdsagen.c + +@OPENSSL_TRUE@am__append_14 = \ +@OPENSSL_TRUE@ openssl/crypto.c \ +@OPENSSL_TRUE@ openssl/digest.c openssl/digest.h \ +@OPENSSL_TRUE@ ed25519/ecdh.c \ +@OPENSSL_TRUE@ ed25519/ecdsa.c \ +@OPENSSL_TRUE@ ed25519/ecdsagen.c \ +@OPENSSL_TRUE@ openssl/prf.c + +@GCRYPT_TRUE@am__append_15 = \ @GCRYPT_TRUE@ gcrypt/cipher.c \ @GCRYPT_TRUE@ gcrypt/crypto.c \ @GCRYPT_TRUE@ gcrypt/digest.c gcrypt/digest.h \ @@ -124,7 +137,7 @@ sbin_PROGRAMS = tincd$(EXEEXT) tinc$(EXEEXT) sptps_test$(EXEEXT) @GCRYPT_TRUE@ gcrypt/prf.c \ @GCRYPT_TRUE@ gcrypt/rsa.c -@GCRYPT_TRUE@am__append_13 = \ +@GCRYPT_TRUE@am__append_16 = \ @GCRYPT_TRUE@ gcrypt/cipher.c \ @GCRYPT_TRUE@ gcrypt/crypto.c \ @GCRYPT_TRUE@ gcrypt/digest.c gcrypt/digest.h \ @@ -135,7 +148,7 @@ sbin_PROGRAMS = tincd$(EXEEXT) tinc$(EXEEXT) sptps_test$(EXEEXT) @GCRYPT_TRUE@ gcrypt/rsa.c \ @GCRYPT_TRUE@ gcrypt/rsagen.c -@GCRYPT_TRUE@am__append_14 = \ +@GCRYPT_TRUE@am__append_17 = \ @GCRYPT_TRUE@ gcrypt/cipher.c \ @GCRYPT_TRUE@ gcrypt/crypto.c \ @GCRYPT_TRUE@ gcrypt/digest.c gcrypt/digest.h \ @@ -143,60 +156,120 @@ sbin_PROGRAMS = tincd$(EXEEXT) tinc$(EXEEXT) sptps_test$(EXEEXT) @GCRYPT_TRUE@ gcrypt/ecdsa.c \ @GCRYPT_TRUE@ gcrypt/prf.c -@TUNEMU_TRUE@am__append_15 = -lpcap +@TUNEMU_TRUE@am__append_18 = -lpcap subdir = src DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(top_srcdir)/depcomp ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \ - $(top_srcdir)/m4/curses.m4 $(top_srcdir)/m4/lzo.m4 \ - $(top_srcdir)/m4/openssl.m4 $(top_srcdir)/m4/readline.m4 \ - $(top_srcdir)/m4/zlib.m4 $(top_srcdir)/configure.ac + $(top_srcdir)/m4/ax_check_compile_flag.m4 \ + $(top_srcdir)/m4/ax_check_link_flag.m4 \ + $(top_srcdir)/m4/curses.m4 $(top_srcdir)/m4/libgcrypt.m4 \ + $(top_srcdir)/m4/lzo.m4 $(top_srcdir)/m4/openssl.m4 \ + $(top_srcdir)/m4/readline.m4 $(top_srcdir)/m4/zlib.m4 \ + $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = +@LINUX_TRUE@am__EXEEXT_1 = sptps_speed$(EXEEXT) am__installdirs = "$(DESTDIR)$(sbindir)" PROGRAMS = $(sbin_PROGRAMS) -am__sptps_test_SOURCES_DIST = logger.c logger.h sptps.c sptps.h \ - sptps_test.c utils.c utils.h openssl/cipher.c openssl/crypto.c \ - openssl/digest.c openssl/digest.h openssl/ecdh.c \ - openssl/ecdsa.c openssl/prf.c gcrypt/cipher.c gcrypt/crypto.c \ - gcrypt/digest.c gcrypt/digest.h gcrypt/ecdh.c gcrypt/ecdsa.c \ - gcrypt/prf.c +am__sptps_keypair_SOURCES_DIST = sptps_keypair.c utils.c utils.h \ + ed25519/add_scalar.c ed25519/ed25519.h ed25519/fe.c \ + ed25519/fe.h ed25519/fixedint.h ed25519/ge.c ed25519/ge.h \ + ed25519/key_exchange.c ed25519/keypair.c \ + ed25519/precomp_data.h ed25519/sc.c ed25519/sc.h \ + ed25519/sha512.c ed25519/sha512.h ed25519/sign.c \ + ed25519/verify.c openssl/crypto.c ed25519/ecdsagen.c am__dirstamp = $(am__leading_dot)dirstamp -@OPENSSL_TRUE@am__objects_1 = openssl/cipher.$(OBJEXT) \ -@OPENSSL_TRUE@ openssl/crypto.$(OBJEXT) \ -@OPENSSL_TRUE@ openssl/digest.$(OBJEXT) openssl/ecdh.$(OBJEXT) \ -@OPENSSL_TRUE@ openssl/ecdsa.$(OBJEXT) openssl/prf.$(OBJEXT) -@GCRYPT_TRUE@am__objects_2 = gcrypt/cipher.$(OBJEXT) \ +am__objects_1 = ed25519/add_scalar.$(OBJEXT) ed25519/fe.$(OBJEXT) \ + ed25519/ge.$(OBJEXT) ed25519/key_exchange.$(OBJEXT) \ + ed25519/keypair.$(OBJEXT) ed25519/sc.$(OBJEXT) \ + ed25519/sha512.$(OBJEXT) ed25519/sign.$(OBJEXT) \ + ed25519/verify.$(OBJEXT) +@OPENSSL_TRUE@am__objects_2 = openssl/crypto.$(OBJEXT) \ +@OPENSSL_TRUE@ ed25519/ecdsagen.$(OBJEXT) +am_sptps_keypair_OBJECTS = sptps_keypair.$(OBJEXT) utils.$(OBJEXT) \ + $(am__objects_1) $(am__objects_2) +sptps_keypair_OBJECTS = $(am_sptps_keypair_OBJECTS) +sptps_keypair_LDADD = $(LDADD) +am__sptps_speed_SOURCES_DIST = logger.c logger.h sptps.c sptps.h \ + sptps_speed.c utils.c utils.h ed25519/add_scalar.c \ + ed25519/ed25519.h ed25519/fe.c ed25519/fe.h ed25519/fixedint.h \ + ed25519/ge.c ed25519/ge.h ed25519/key_exchange.c \ + ed25519/keypair.c ed25519/precomp_data.h ed25519/sc.c \ + ed25519/sc.h ed25519/sha512.c ed25519/sha512.h ed25519/sign.c \ + ed25519/verify.c chacha-poly1305/chacha.c \ + chacha-poly1305/chacha.h chacha-poly1305/chacha-poly1305.c \ + chacha-poly1305/chacha-poly1305.h chacha-poly1305/poly1305.c \ + chacha-poly1305/poly1305.h openssl/crypto.c openssl/digest.c \ + openssl/digest.h ed25519/ecdh.c ed25519/ecdsa.c \ + ed25519/ecdsagen.c openssl/prf.c +am__objects_3 = chacha-poly1305/chacha.$(OBJEXT) \ + chacha-poly1305/chacha-poly1305.$(OBJEXT) \ + chacha-poly1305/poly1305.$(OBJEXT) +@OPENSSL_TRUE@am__objects_4 = openssl/crypto.$(OBJEXT) \ +@OPENSSL_TRUE@ openssl/digest.$(OBJEXT) ed25519/ecdh.$(OBJEXT) \ +@OPENSSL_TRUE@ ed25519/ecdsa.$(OBJEXT) \ +@OPENSSL_TRUE@ ed25519/ecdsagen.$(OBJEXT) openssl/prf.$(OBJEXT) +am_sptps_speed_OBJECTS = logger.$(OBJEXT) sptps.$(OBJEXT) \ + sptps_speed.$(OBJEXT) utils.$(OBJEXT) $(am__objects_1) \ + $(am__objects_3) $(am__objects_4) +sptps_speed_OBJECTS = $(am_sptps_speed_OBJECTS) +sptps_speed_DEPENDENCIES = +am__sptps_test_SOURCES_DIST = logger.c logger.h sptps.c sptps.h \ + sptps_test.c utils.c utils.h ed25519/add_scalar.c \ + ed25519/ed25519.h ed25519/fe.c ed25519/fe.h ed25519/fixedint.h \ + ed25519/ge.c ed25519/ge.h ed25519/key_exchange.c \ + ed25519/keypair.c ed25519/precomp_data.h ed25519/sc.c \ + ed25519/sc.h ed25519/sha512.c ed25519/sha512.h ed25519/sign.c \ + ed25519/verify.c chacha-poly1305/chacha.c \ + chacha-poly1305/chacha.h chacha-poly1305/chacha-poly1305.c \ + chacha-poly1305/chacha-poly1305.h chacha-poly1305/poly1305.c \ + chacha-poly1305/poly1305.h openssl/crypto.c openssl/digest.c \ + openssl/digest.h ed25519/ecdh.c ed25519/ecdsa.c openssl/prf.c \ + gcrypt/cipher.c gcrypt/crypto.c gcrypt/digest.c \ + gcrypt/digest.h gcrypt/ecdh.c gcrypt/ecdsa.c gcrypt/prf.c +@OPENSSL_TRUE@am__objects_5 = openssl/crypto.$(OBJEXT) \ +@OPENSSL_TRUE@ openssl/digest.$(OBJEXT) ed25519/ecdh.$(OBJEXT) \ +@OPENSSL_TRUE@ ed25519/ecdsa.$(OBJEXT) openssl/prf.$(OBJEXT) +@GCRYPT_TRUE@am__objects_6 = gcrypt/cipher.$(OBJEXT) \ @GCRYPT_TRUE@ gcrypt/crypto.$(OBJEXT) gcrypt/digest.$(OBJEXT) \ @GCRYPT_TRUE@ gcrypt/ecdh.$(OBJEXT) gcrypt/ecdsa.$(OBJEXT) \ @GCRYPT_TRUE@ gcrypt/prf.$(OBJEXT) am_sptps_test_OBJECTS = logger.$(OBJEXT) sptps.$(OBJEXT) \ sptps_test.$(OBJEXT) utils.$(OBJEXT) $(am__objects_1) \ - $(am__objects_2) + $(am__objects_3) $(am__objects_5) $(am__objects_6) sptps_test_OBJECTS = $(am_sptps_test_OBJECTS) sptps_test_LDADD = $(LDADD) am__tinc_SOURCES_DIST = dropin.c dropin.h getopt.c getopt.h getopt1.c \ info.c info.h invitation.c invitation.h list.c list.h names.c \ names.h netutl.c netutl.h script.c script.h sptps.c sptps.h \ subnet_parse.c subnet.h tincctl.c tincctl.h top.c top.h \ - utils.c utils.h openssl/cipher.c openssl/crypto.c \ - openssl/digest.c openssl/digest.h openssl/ecdh.c \ - openssl/ecdsa.c openssl/ecdsagen.c openssl/prf.c openssl/rsa.c \ + utils.c utils.h version.c version.h ed25519/add_scalar.c \ + ed25519/ed25519.h ed25519/fe.c ed25519/fe.h ed25519/fixedint.h \ + ed25519/ge.c ed25519/ge.h ed25519/key_exchange.c \ + ed25519/keypair.c ed25519/precomp_data.h ed25519/sc.c \ + ed25519/sc.h ed25519/sha512.c ed25519/sha512.h ed25519/sign.c \ + ed25519/verify.c chacha-poly1305/chacha.c \ + chacha-poly1305/chacha.h chacha-poly1305/chacha-poly1305.c \ + chacha-poly1305/chacha-poly1305.h chacha-poly1305/poly1305.c \ + chacha-poly1305/poly1305.h openssl/cipher.c openssl/crypto.c \ + openssl/digest.c openssl/digest.h ed25519/ecdh.c \ + ed25519/ecdsa.c ed25519/ecdsagen.c openssl/prf.c openssl/rsa.c \ openssl/rsagen.c gcrypt/cipher.c gcrypt/crypto.c \ gcrypt/digest.c gcrypt/digest.h gcrypt/ecdh.c gcrypt/ecdsa.c \ gcrypt/ecdsagen.c gcrypt/prf.c gcrypt/rsa.c gcrypt/rsagen.c -@OPENSSL_TRUE@am__objects_3 = openssl/cipher.$(OBJEXT) \ +@OPENSSL_TRUE@am__objects_7 = openssl/cipher.$(OBJEXT) \ @OPENSSL_TRUE@ openssl/crypto.$(OBJEXT) \ -@OPENSSL_TRUE@ openssl/digest.$(OBJEXT) openssl/ecdh.$(OBJEXT) \ -@OPENSSL_TRUE@ openssl/ecdsa.$(OBJEXT) \ -@OPENSSL_TRUE@ openssl/ecdsagen.$(OBJEXT) openssl/prf.$(OBJEXT) \ +@OPENSSL_TRUE@ openssl/digest.$(OBJEXT) ed25519/ecdh.$(OBJEXT) \ +@OPENSSL_TRUE@ ed25519/ecdsa.$(OBJEXT) \ +@OPENSSL_TRUE@ ed25519/ecdsagen.$(OBJEXT) openssl/prf.$(OBJEXT) \ @OPENSSL_TRUE@ openssl/rsa.$(OBJEXT) openssl/rsagen.$(OBJEXT) -@GCRYPT_TRUE@am__objects_4 = gcrypt/cipher.$(OBJEXT) \ +@GCRYPT_TRUE@am__objects_8 = gcrypt/cipher.$(OBJEXT) \ @GCRYPT_TRUE@ gcrypt/crypto.$(OBJEXT) gcrypt/digest.$(OBJEXT) \ @GCRYPT_TRUE@ gcrypt/ecdh.$(OBJEXT) gcrypt/ecdsa.$(OBJEXT) \ @GCRYPT_TRUE@ gcrypt/ecdsagen.$(OBJEXT) gcrypt/prf.$(OBJEXT) \ @@ -205,8 +278,9 @@ am_tinc_OBJECTS = dropin.$(OBJEXT) getopt.$(OBJEXT) getopt1.$(OBJEXT) \ info.$(OBJEXT) invitation.$(OBJEXT) list.$(OBJEXT) \ names.$(OBJEXT) netutl.$(OBJEXT) script.$(OBJEXT) \ sptps.$(OBJEXT) subnet_parse.$(OBJEXT) tincctl.$(OBJEXT) \ - top.$(OBJEXT) utils.$(OBJEXT) $(am__objects_3) \ - $(am__objects_4) + top.$(OBJEXT) utils.$(OBJEXT) version.$(OBJEXT) \ + $(am__objects_1) $(am__objects_3) $(am__objects_7) \ + $(am__objects_8) tinc_OBJECTS = $(am_tinc_OBJECTS) am__DEPENDENCIES_1 = tinc_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) @@ -225,28 +299,37 @@ am__tincd_SOURCES_DIST = buffer.c buffer.h cipher.h conf.c conf.h \ protocol_subnet.c raw_socket_device.c route.c route.h rsa.h \ rsagen.h script.c script.h splay_tree.c splay_tree.h sptps.c \ sptps.h subnet.c subnet.h subnet_parse.c system.h tincd.c \ - utils.c utils.h xalloc.h linux/device.c bsd/device.c \ + utils.c utils.h xalloc.h version.c version.h \ + ed25519/add_scalar.c ed25519/ed25519.h ed25519/fe.c \ + ed25519/fe.h ed25519/fixedint.h ed25519/ge.c ed25519/ge.h \ + ed25519/key_exchange.c ed25519/keypair.c \ + ed25519/precomp_data.h ed25519/sc.c ed25519/sc.h \ + ed25519/sha512.c ed25519/sha512.h ed25519/sign.c \ + ed25519/verify.c chacha-poly1305/chacha.c \ + chacha-poly1305/chacha.h chacha-poly1305/chacha-poly1305.c \ + chacha-poly1305/chacha-poly1305.h chacha-poly1305/poly1305.c \ + chacha-poly1305/poly1305.h linux/device.c bsd/device.c \ bsd/tunemu.c bsd/tunemu.h solaris/device.c mingw/device.c \ mingw/common.h cygwin/device.c uml_device.c vde_device.c \ openssl/cipher.c openssl/crypto.c openssl/digest.c \ - openssl/digest.h openssl/ecdh.c openssl/ecdsa.c openssl/prf.c \ + openssl/digest.h ed25519/ecdh.c ed25519/ecdsa.c openssl/prf.c \ openssl/rsa.c gcrypt/cipher.c gcrypt/crypto.c gcrypt/digest.c \ gcrypt/digest.h gcrypt/ecdh.c gcrypt/ecdsa.c gcrypt/prf.c \ gcrypt/rsa.c -@LINUX_TRUE@am__objects_5 = linux/device.$(OBJEXT) -@BSD_TRUE@am__objects_6 = bsd/device.$(OBJEXT) -@BSD_TRUE@@TUNEMU_TRUE@am__objects_7 = bsd/tunemu.$(OBJEXT) -@SOLARIS_TRUE@am__objects_8 = solaris/device.$(OBJEXT) -@MINGW_TRUE@am__objects_9 = mingw/device.$(OBJEXT) -@CYGWIN_TRUE@am__objects_10 = cygwin/device.$(OBJEXT) -@UML_TRUE@am__objects_11 = uml_device.$(OBJEXT) -@VDE_TRUE@am__objects_12 = vde_device.$(OBJEXT) -@OPENSSL_TRUE@am__objects_13 = openssl/cipher.$(OBJEXT) \ +@LINUX_TRUE@am__objects_9 = linux/device.$(OBJEXT) +@BSD_TRUE@am__objects_10 = bsd/device.$(OBJEXT) +@BSD_TRUE@@TUNEMU_TRUE@am__objects_11 = bsd/tunemu.$(OBJEXT) +@SOLARIS_TRUE@am__objects_12 = solaris/device.$(OBJEXT) +@MINGW_TRUE@am__objects_13 = mingw/device.$(OBJEXT) +@CYGWIN_TRUE@am__objects_14 = cygwin/device.$(OBJEXT) +@UML_TRUE@am__objects_15 = uml_device.$(OBJEXT) +@VDE_TRUE@am__objects_16 = vde_device.$(OBJEXT) +@OPENSSL_TRUE@am__objects_17 = openssl/cipher.$(OBJEXT) \ @OPENSSL_TRUE@ openssl/crypto.$(OBJEXT) \ -@OPENSSL_TRUE@ openssl/digest.$(OBJEXT) openssl/ecdh.$(OBJEXT) \ -@OPENSSL_TRUE@ openssl/ecdsa.$(OBJEXT) openssl/prf.$(OBJEXT) \ +@OPENSSL_TRUE@ openssl/digest.$(OBJEXT) ed25519/ecdh.$(OBJEXT) \ +@OPENSSL_TRUE@ ed25519/ecdsa.$(OBJEXT) openssl/prf.$(OBJEXT) \ @OPENSSL_TRUE@ openssl/rsa.$(OBJEXT) -@GCRYPT_TRUE@am__objects_14 = gcrypt/cipher.$(OBJEXT) \ +@GCRYPT_TRUE@am__objects_18 = gcrypt/cipher.$(OBJEXT) \ @GCRYPT_TRUE@ gcrypt/crypto.$(OBJEXT) gcrypt/digest.$(OBJEXT) \ @GCRYPT_TRUE@ gcrypt/ecdh.$(OBJEXT) gcrypt/ecdsa.$(OBJEXT) \ @GCRYPT_TRUE@ gcrypt/prf.$(OBJEXT) gcrypt/rsa.$(OBJEXT) @@ -265,10 +348,11 @@ am_tincd_OBJECTS = buffer.$(OBJEXT) conf.$(OBJEXT) \ raw_socket_device.$(OBJEXT) route.$(OBJEXT) script.$(OBJEXT) \ splay_tree.$(OBJEXT) sptps.$(OBJEXT) subnet.$(OBJEXT) \ subnet_parse.$(OBJEXT) tincd.$(OBJEXT) utils.$(OBJEXT) \ - $(am__objects_5) $(am__objects_6) $(am__objects_7) \ - $(am__objects_8) $(am__objects_9) $(am__objects_10) \ - $(am__objects_11) $(am__objects_12) $(am__objects_13) \ - $(am__objects_14) + version.$(OBJEXT) $(am__objects_1) $(am__objects_3) \ + $(am__objects_9) $(am__objects_10) $(am__objects_11) \ + $(am__objects_12) $(am__objects_13) $(am__objects_14) \ + $(am__objects_15) $(am__objects_16) $(am__objects_17) \ + $(am__objects_18) tincd_OBJECTS = $(am_tincd_OBJECTS) tincd_LDADD = $(LDADD) AM_V_P = $(am__v_P_@AM_V@) @@ -298,9 +382,11 @@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = -SOURCES = $(sptps_test_SOURCES) $(tinc_SOURCES) $(tincd_SOURCES) -DIST_SOURCES = $(am__sptps_test_SOURCES_DIST) $(am__tinc_SOURCES_DIST) \ - $(am__tincd_SOURCES_DIST) +SOURCES = $(sptps_keypair_SOURCES) $(sptps_speed_SOURCES) \ + $(sptps_test_SOURCES) $(tinc_SOURCES) $(tincd_SOURCES) +DIST_SOURCES = $(am__sptps_keypair_SOURCES_DIST) \ + $(am__sptps_speed_SOURCES_DIST) $(am__sptps_test_SOURCES_DIST) \ + $(am__tinc_SOURCES_DIST) $(am__tincd_SOURCES_DIST) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ @@ -354,11 +440,8 @@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ -LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ -LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ -LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ LIBOBJS = @LIBOBJS@ -LIBS = @LIBS@ @LIBGCRYPT_LIBS@ $(am__append_15) +LIBS = @LIBS@ $(am__append_18) LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ @@ -372,7 +455,6 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ -RANLIB = @RANLIB@ READLINE_LIBS = @READLINE_LIBS@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ @@ -429,6 +511,25 @@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ DEFAULT_INCLUDES = +ed25519_SOURCES = \ + ed25519/add_scalar.c \ + ed25519/ed25519.h \ + ed25519/fe.c ed25519/fe.h \ + ed25519/fixedint.h \ + ed25519/ge.c ed25519/ge.h \ + ed25519/key_exchange.c \ + ed25519/keypair.c \ + ed25519/precomp_data.h \ + ed25519/sc.c ed25519/sc.h \ + ed25519/sha512.c ed25519/sha512.h \ + ed25519/sign.c \ + ed25519/verify.c + +chacha_poly1305_SOURCES = \ + chacha-poly1305/chacha.c chacha-poly1305/chacha.h \ + chacha-poly1305/chacha-poly1305.c chacha-poly1305/chacha-poly1305.h \ + chacha-poly1305/poly1305.c chacha-poly1305/poly1305.h + tincd_SOURCES = buffer.c buffer.h cipher.h conf.c conf.h connection.c \ connection.h control.c control.h control_common.h crypto.h \ device.h digest.h dropin.c dropin.h dummy_device.c ecdh.h \ @@ -444,18 +545,27 @@ tincd_SOURCES = buffer.c buffer.h cipher.h conf.c conf.h connection.c \ protocol_subnet.c raw_socket_device.c route.c route.h rsa.h \ rsagen.h script.c script.h splay_tree.c splay_tree.h sptps.c \ sptps.h subnet.c subnet.h subnet_parse.c system.h tincd.c \ - utils.c utils.h xalloc.h $(am__append_1) $(am__append_2) \ + utils.c utils.h xalloc.h version.c version.h \ + $(ed25519_SOURCES) $(chacha_poly1305_SOURCES) $(am__append_2) \ $(am__append_3) $(am__append_4) $(am__append_5) \ $(am__append_6) $(am__append_7) $(am__append_8) \ - $(am__append_9) $(am__append_12) + $(am__append_9) $(am__append_10) $(am__append_15) tinc_SOURCES = dropin.c dropin.h getopt.c getopt.h getopt1.c info.c \ info.h invitation.c invitation.h list.c list.h names.c names.h \ netutl.c netutl.h script.c script.h sptps.c sptps.h \ subnet_parse.c subnet.h tincctl.c tincctl.h top.c top.h \ - utils.c utils.h $(am__append_10) $(am__append_13) + utils.c utils.h version.c version.h $(ed25519_SOURCES) \ + $(chacha_poly1305_SOURCES) $(am__append_11) $(am__append_16) sptps_test_SOURCES = logger.c logger.h sptps.c sptps.h sptps_test.c \ - utils.c utils.h $(am__append_11) $(am__append_14) + utils.c utils.h $(ed25519_SOURCES) $(chacha_poly1305_SOURCES) \ + $(am__append_12) $(am__append_17) +sptps_keypair_SOURCES = sptps_keypair.c utils.c utils.h \ + $(ed25519_SOURCES) $(am__append_13) +sptps_speed_SOURCES = logger.c logger.h sptps.c sptps.h sptps_speed.c \ + utils.c utils.h $(ed25519_SOURCES) $(chacha_poly1305_SOURCES) \ + $(am__append_14) tinc_LDADD = $(READLINE_LIBS) $(CURSES_LIBS) +sptps_speed_LDADD = -lrt AM_CFLAGS = -DCONFDIR=\"$(sysconfdir)\" -DLOCALSTATEDIR=\"$(localstatedir)\" -DSBINDIR=\"$(sbindir)\" all: all-am @@ -549,24 +659,69 @@ installcheck-sbinPROGRAMS: $(sbin_PROGRAMS) else echo "$$f does not support $$opt" 1>&2; bad=1; fi; \ done; \ done; rm -f c$${pid}_.???; exit $$bad +ed25519/$(am__dirstamp): + @$(MKDIR_P) ed25519 + @: > ed25519/$(am__dirstamp) +ed25519/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) ed25519/$(DEPDIR) + @: > ed25519/$(DEPDIR)/$(am__dirstamp) +ed25519/add_scalar.$(OBJEXT): ed25519/$(am__dirstamp) \ + ed25519/$(DEPDIR)/$(am__dirstamp) +ed25519/fe.$(OBJEXT): ed25519/$(am__dirstamp) \ + ed25519/$(DEPDIR)/$(am__dirstamp) +ed25519/ge.$(OBJEXT): ed25519/$(am__dirstamp) \ + ed25519/$(DEPDIR)/$(am__dirstamp) +ed25519/key_exchange.$(OBJEXT): ed25519/$(am__dirstamp) \ + ed25519/$(DEPDIR)/$(am__dirstamp) +ed25519/keypair.$(OBJEXT): ed25519/$(am__dirstamp) \ + ed25519/$(DEPDIR)/$(am__dirstamp) +ed25519/sc.$(OBJEXT): ed25519/$(am__dirstamp) \ + ed25519/$(DEPDIR)/$(am__dirstamp) +ed25519/sha512.$(OBJEXT): ed25519/$(am__dirstamp) \ + ed25519/$(DEPDIR)/$(am__dirstamp) +ed25519/sign.$(OBJEXT): ed25519/$(am__dirstamp) \ + ed25519/$(DEPDIR)/$(am__dirstamp) +ed25519/verify.$(OBJEXT): ed25519/$(am__dirstamp) \ + ed25519/$(DEPDIR)/$(am__dirstamp) openssl/$(am__dirstamp): @$(MKDIR_P) openssl @: > openssl/$(am__dirstamp) openssl/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) openssl/$(DEPDIR) @: > openssl/$(DEPDIR)/$(am__dirstamp) -openssl/cipher.$(OBJEXT): openssl/$(am__dirstamp) \ - openssl/$(DEPDIR)/$(am__dirstamp) openssl/crypto.$(OBJEXT): openssl/$(am__dirstamp) \ openssl/$(DEPDIR)/$(am__dirstamp) +ed25519/ecdsagen.$(OBJEXT): ed25519/$(am__dirstamp) \ + ed25519/$(DEPDIR)/$(am__dirstamp) + +sptps_keypair$(EXEEXT): $(sptps_keypair_OBJECTS) $(sptps_keypair_DEPENDENCIES) $(EXTRA_sptps_keypair_DEPENDENCIES) + @rm -f sptps_keypair$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(sptps_keypair_OBJECTS) $(sptps_keypair_LDADD) $(LIBS) +chacha-poly1305/$(am__dirstamp): + @$(MKDIR_P) chacha-poly1305 + @: > chacha-poly1305/$(am__dirstamp) +chacha-poly1305/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) chacha-poly1305/$(DEPDIR) + @: > chacha-poly1305/$(DEPDIR)/$(am__dirstamp) +chacha-poly1305/chacha.$(OBJEXT): chacha-poly1305/$(am__dirstamp) \ + chacha-poly1305/$(DEPDIR)/$(am__dirstamp) +chacha-poly1305/chacha-poly1305.$(OBJEXT): \ + chacha-poly1305/$(am__dirstamp) \ + chacha-poly1305/$(DEPDIR)/$(am__dirstamp) +chacha-poly1305/poly1305.$(OBJEXT): chacha-poly1305/$(am__dirstamp) \ + chacha-poly1305/$(DEPDIR)/$(am__dirstamp) openssl/digest.$(OBJEXT): openssl/$(am__dirstamp) \ openssl/$(DEPDIR)/$(am__dirstamp) -openssl/ecdh.$(OBJEXT): openssl/$(am__dirstamp) \ - openssl/$(DEPDIR)/$(am__dirstamp) -openssl/ecdsa.$(OBJEXT): openssl/$(am__dirstamp) \ - openssl/$(DEPDIR)/$(am__dirstamp) +ed25519/ecdh.$(OBJEXT): ed25519/$(am__dirstamp) \ + ed25519/$(DEPDIR)/$(am__dirstamp) +ed25519/ecdsa.$(OBJEXT): ed25519/$(am__dirstamp) \ + ed25519/$(DEPDIR)/$(am__dirstamp) openssl/prf.$(OBJEXT): openssl/$(am__dirstamp) \ openssl/$(DEPDIR)/$(am__dirstamp) + +sptps_speed$(EXEEXT): $(sptps_speed_OBJECTS) $(sptps_speed_DEPENDENCIES) $(EXTRA_sptps_speed_DEPENDENCIES) + @rm -f sptps_speed$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(sptps_speed_OBJECTS) $(sptps_speed_LDADD) $(LIBS) gcrypt/$(am__dirstamp): @$(MKDIR_P) gcrypt @: > gcrypt/$(am__dirstamp) @@ -589,7 +744,7 @@ gcrypt/prf.$(OBJEXT): gcrypt/$(am__dirstamp) \ sptps_test$(EXEEXT): $(sptps_test_OBJECTS) $(sptps_test_DEPENDENCIES) $(EXTRA_sptps_test_DEPENDENCIES) @rm -f sptps_test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(sptps_test_OBJECTS) $(sptps_test_LDADD) $(LIBS) -openssl/ecdsagen.$(OBJEXT): openssl/$(am__dirstamp) \ +openssl/cipher.$(OBJEXT): openssl/$(am__dirstamp) \ openssl/$(DEPDIR)/$(am__dirstamp) openssl/rsa.$(OBJEXT): openssl/$(am__dirstamp) \ openssl/$(DEPDIR)/$(am__dirstamp) @@ -655,7 +810,9 @@ tincd$(EXEEXT): $(tincd_OBJECTS) $(tincd_DEPENDENCIES) $(EXTRA_tincd_DEPENDENCIE mostlyclean-compile: -rm -f *.$(OBJEXT) -rm -f bsd/*.$(OBJEXT) + -rm -f chacha-poly1305/*.$(OBJEXT) -rm -f cygwin/*.$(OBJEXT) + -rm -f ed25519/*.$(OBJEXT) -rm -f gcrypt/*.$(OBJEXT) -rm -f linux/*.$(OBJEXT) -rm -f mingw/*.$(OBJEXT) @@ -704,6 +861,8 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/script.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/splay_tree.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sptps.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sptps_keypair.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sptps_speed.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sptps_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/subnet.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/subnet_parse.Po@am__quote@ @@ -713,9 +872,25 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uml_device.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/utils.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vde_device.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/version.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@bsd/$(DEPDIR)/device.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@bsd/$(DEPDIR)/tunemu.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@chacha-poly1305/$(DEPDIR)/chacha-poly1305.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@chacha-poly1305/$(DEPDIR)/chacha.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@chacha-poly1305/$(DEPDIR)/poly1305.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@cygwin/$(DEPDIR)/device.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/add_scalar.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/ecdh.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/ecdsa.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/ecdsagen.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/fe.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/ge.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/key_exchange.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/keypair.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/sc.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/sha512.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/sign.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/verify.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@gcrypt/$(DEPDIR)/cipher.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@gcrypt/$(DEPDIR)/crypto.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@gcrypt/$(DEPDIR)/digest.Po@am__quote@ @@ -730,9 +905,6 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@openssl/$(DEPDIR)/cipher.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@openssl/$(DEPDIR)/crypto.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@openssl/$(DEPDIR)/digest.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@openssl/$(DEPDIR)/ecdh.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@openssl/$(DEPDIR)/ecdsa.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@openssl/$(DEPDIR)/ecdsagen.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@openssl/$(DEPDIR)/prf.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@openssl/$(DEPDIR)/rsa.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@openssl/$(DEPDIR)/rsagen.Po@am__quote@ @@ -871,8 +1043,12 @@ distclean-generic: -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) -rm -f bsd/$(DEPDIR)/$(am__dirstamp) -rm -f bsd/$(am__dirstamp) + -rm -f chacha-poly1305/$(DEPDIR)/$(am__dirstamp) + -rm -f chacha-poly1305/$(am__dirstamp) -rm -f cygwin/$(DEPDIR)/$(am__dirstamp) -rm -f cygwin/$(am__dirstamp) + -rm -f ed25519/$(DEPDIR)/$(am__dirstamp) + -rm -f ed25519/$(am__dirstamp) -rm -f gcrypt/$(DEPDIR)/$(am__dirstamp) -rm -f gcrypt/$(am__dirstamp) -rm -f linux/$(DEPDIR)/$(am__dirstamp) @@ -892,7 +1068,7 @@ clean: clean-am clean-am: clean-generic clean-sbinPROGRAMS mostlyclean-am distclean: distclean-am - -rm -rf ./$(DEPDIR) bsd/$(DEPDIR) cygwin/$(DEPDIR) gcrypt/$(DEPDIR) linux/$(DEPDIR) mingw/$(DEPDIR) openssl/$(DEPDIR) solaris/$(DEPDIR) + -rm -rf ./$(DEPDIR) bsd/$(DEPDIR) chacha-poly1305/$(DEPDIR) cygwin/$(DEPDIR) ed25519/$(DEPDIR) gcrypt/$(DEPDIR) linux/$(DEPDIR) mingw/$(DEPDIR) openssl/$(DEPDIR) solaris/$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags @@ -938,7 +1114,7 @@ install-ps-am: installcheck-am: installcheck-sbinPROGRAMS maintainer-clean: maintainer-clean-am - -rm -rf ./$(DEPDIR) bsd/$(DEPDIR) cygwin/$(DEPDIR) gcrypt/$(DEPDIR) linux/$(DEPDIR) mingw/$(DEPDIR) openssl/$(DEPDIR) solaris/$(DEPDIR) + -rm -rf ./$(DEPDIR) bsd/$(DEPDIR) chacha-poly1305/$(DEPDIR) cygwin/$(DEPDIR) ed25519/$(DEPDIR) gcrypt/$(DEPDIR) linux/$(DEPDIR) mingw/$(DEPDIR) openssl/$(DEPDIR) solaris/$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic @@ -973,6 +1149,9 @@ uninstall-am: uninstall-sbinPROGRAMS uninstall-am uninstall-sbinPROGRAMS +.PHONY: version.c +version.c: + # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: diff --git a/src/bsd/device.c b/src/bsd/device.c index e083519..d1a993b 100644 --- a/src/bsd/device.c +++ b/src/bsd/device.c @@ -1,7 +1,7 @@ /* device.c -- Interaction BSD tun/tap device Copyright (C) 2001-2005 Ivo Timmermans, - 2001-2013 Guus Sliepen + 2001-2014 Guus Sliepen 2009 Grzegorz Dymarek This program is free software; you can redistribute it and/or modify @@ -35,7 +35,7 @@ #endif #define DEFAULT_TUN_DEVICE "/dev/tun0" -#if defined(HAVE_FREEBSD) || defined(HAVE_NETBSD) +#if defined(HAVE_DARWIN) || defined(HAVE_FREEBSD) || defined(HAVE_NETBSD) #define DEFAULT_TAP_DEVICE "/dev/tap0" #else #define DEFAULT_TAP_DEVICE "/dev/tun0" @@ -54,8 +54,6 @@ int device_fd = -1; char *device = NULL; char *iface = NULL; static char *device_info = NULL; -static uint64_t device_total_in = 0; -static uint64_t device_total_out = 0; #if defined(ENABLE_TUNEMU) static device_type_t device_type = DEVICE_TYPE_TUNEMU; #elif defined(HAVE_OPENBSD) || defined(HAVE_FREEBSD) || defined(HAVE_DRAGONFLY) @@ -65,18 +63,9 @@ static device_type_t device_type = DEVICE_TYPE_TUN; #endif static bool setup_device(void) { + get_config_string(lookup_config(config_tree, "Device"), &device); + char *type; - - if(!get_config_string(lookup_config(config_tree, "Device"), &device)) { - if(routing_mode == RMODE_ROUTER) - device = xstrdup(DEFAULT_TUN_DEVICE); - else - device = xstrdup(DEFAULT_TAP_DEVICE); - } - - if(!get_config_string(lookup_config(config_tree, "Interface"), &iface)) - iface = xstrdup(strrchr(device, '/') ? strrchr(device, '/') + 1 : device); - if(get_config_string(lookup_config(config_tree, "DeviceType"), &type)) { if(!strcasecmp(type, "tun")) /* use default */; @@ -95,10 +84,29 @@ static bool setup_device(void) { return false; } } else { - if(strstr(device, "tap") || routing_mode != RMODE_ROUTER) + if((device && strstr(device, "tap")) || routing_mode != RMODE_ROUTER) device_type = DEVICE_TYPE_TAP; } + if(!device) { + if(device_type == DEVICE_TYPE_TAP) + device = xstrdup(DEFAULT_TAP_DEVICE); + else + device = xstrdup(DEFAULT_TUN_DEVICE); + } + + if(!get_config_string(lookup_config(config_tree, "Interface"), &iface)) + iface = NULL; +#ifndef TAPGIFNAME + if (iface) { + logger(DEBUG_ALWAYS, LOG_WARNING, "Ignoring specified interface name '%s' as device rename is not supported on this platform", iface); + free(iface); + iface = NULL; + } +#endif + if (!iface) + iface = xstrdup(strrchr(device, '/') ? strrchr(device, '/') + 1 : device); + switch(device_type) { #ifdef ENABLE_TUNEMU case DEVICE_TYPE_TUNEMU: { @@ -199,9 +207,11 @@ static void close_device(void) { default: close(device_fd); } + device_fd = -1; - free(device); - free(iface); + free(device); device = NULL; + free(iface); iface = NULL; + device_info = NULL; } static bool read_packet(vpn_packet_t *packet) { @@ -212,10 +222,10 @@ static bool read_packet(vpn_packet_t *packet) { #ifdef ENABLE_TUNEMU case DEVICE_TYPE_TUNEMU: if(device_type == DEVICE_TYPE_TUNEMU) - inlen = tunemu_read(device_fd, packet->data + 14, MTU - 14); + inlen = tunemu_read(device_fd, DATA(packet) + 14, MTU - 14); else #endif - inlen = read(device_fd, packet->data + 14, MTU - 14); + inlen = read(device_fd, DATA(packet) + 14, MTU - 14); if(inlen <= 0) { logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info, @@ -223,29 +233,29 @@ static bool read_packet(vpn_packet_t *packet) { return false; } - switch(packet->data[14] >> 4) { + switch(DATA(packet)[14] >> 4) { case 4: - packet->data[12] = 0x08; - packet->data[13] = 0x00; + DATA(packet)[12] = 0x08; + DATA(packet)[13] = 0x00; break; case 6: - packet->data[12] = 0x86; - packet->data[13] = 0xDD; + DATA(packet)[12] = 0x86; + DATA(packet)[13] = 0xDD; break; default: logger(DEBUG_TRAFFIC, LOG_ERR, "Unknown IP version %d while reading packet from %s %s", - packet->data[14] >> 4, device_info, device); + DATA(packet)[14] >> 4, device_info, device); return false; } - memset(packet->data, 0, 12); + memset(DATA(packet), 0, 12); packet->len = inlen + 14; break; case DEVICE_TYPE_TUNIFHEAD: { u_int32_t type; - struct iovec vector[2] = {{&type, sizeof type}, {packet->data + 14, MTU - 14}}; + struct iovec vector[2] = {{&type, sizeof type}, {DATA(packet) + 14, MTU - 14}}; if((inlen = readv(device_fd, vector, 2)) <= 0) { logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info, @@ -255,13 +265,13 @@ static bool read_packet(vpn_packet_t *packet) { switch (ntohl(type)) { case AF_INET: - packet->data[12] = 0x08; - packet->data[13] = 0x00; + DATA(packet)[12] = 0x08; + DATA(packet)[13] = 0x00; break; case AF_INET6: - packet->data[12] = 0x86; - packet->data[13] = 0xDD; + DATA(packet)[12] = 0x86; + DATA(packet)[13] = 0xDD; break; default: @@ -271,13 +281,13 @@ static bool read_packet(vpn_packet_t *packet) { return false; } - memset(packet->data, 0, 12); + memset(DATA(packet), 0, 12); packet->len = inlen + 10; break; } case DEVICE_TYPE_TAP: - if((inlen = read(device_fd, packet->data, MTU)) <= 0) { + if((inlen = read(device_fd, DATA(packet), MTU)) <= 0) { logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info, device, strerror(errno)); return false; @@ -290,8 +300,6 @@ static bool read_packet(vpn_packet_t *packet) { return false; } - device_total_in += packet->len; - logger(DEBUG_TRAFFIC, LOG_DEBUG, "Read packet of %d bytes from %s", packet->len, device_info); @@ -304,7 +312,7 @@ static bool write_packet(vpn_packet_t *packet) { switch(device_type) { case DEVICE_TYPE_TUN: - if(write(device_fd, packet->data + 14, packet->len - 14) < 0) { + if(write(device_fd, DATA(packet) + 14, packet->len - 14) < 0) { logger(DEBUG_ALWAYS, LOG_ERR, "Error while writing to %s %s: %s", device_info, device, strerror(errno)); return false; @@ -313,10 +321,10 @@ static bool write_packet(vpn_packet_t *packet) { case DEVICE_TYPE_TUNIFHEAD: { u_int32_t type; - struct iovec vector[2] = {{&type, sizeof type}, {packet->data + 14, packet->len - 14}}; + struct iovec vector[2] = {{&type, sizeof type}, {DATA(packet) + 14, packet->len - 14}}; int af; - af = (packet->data[12] << 8) + packet->data[13]; + af = (DATA(packet)[12] << 8) + DATA(packet)[13]; switch (af) { case 0x0800: @@ -341,7 +349,7 @@ static bool write_packet(vpn_packet_t *packet) { } case DEVICE_TYPE_TAP: - if(write(device_fd, packet->data, packet->len) < 0) { + if(write(device_fd, DATA(packet), packet->len) < 0) { logger(DEBUG_ALWAYS, LOG_ERR, "Error while writing to %s %s: %s", device_info, device, strerror(errno)); return false; @@ -350,7 +358,7 @@ static bool write_packet(vpn_packet_t *packet) { #ifdef ENABLE_TUNEMU case DEVICE_TYPE_TUNEMU: - if(tunemu_write(device_fd, packet->data + 14, packet->len - 14) < 0) { + if(tunemu_write(device_fd, DATA(packet) + 14, packet->len - 14) < 0) { logger(DEBUG_ALWAYS, LOG_ERR, "Error while writing to %s %s: %s", device_info, device, strerror(errno)); return false; @@ -362,21 +370,12 @@ static bool write_packet(vpn_packet_t *packet) { return false; } - device_total_out += packet->len; - return true; } -static void dump_device_stats(void) { - logger(DEBUG_ALWAYS, LOG_DEBUG, "Statistics for %s %s:", device_info, device); - logger(DEBUG_ALWAYS, LOG_DEBUG, " total bytes in: %10"PRIu64, device_total_in); - logger(DEBUG_ALWAYS, LOG_DEBUG, " total bytes out: %10"PRIu64, device_total_out); -} - const devops_t os_devops = { .setup = setup_device, .close = close_device, .read = read_packet, .write = write_packet, - .dump_stats = dump_device_stats, }; diff --git a/src/chacha-poly1305/chacha-poly1305.c b/src/chacha-poly1305/chacha-poly1305.c new file mode 100644 index 0000000..bd5cb2c --- /dev/null +++ b/src/chacha-poly1305/chacha-poly1305.c @@ -0,0 +1,103 @@ +#include "../system.h" + +#include "../cipher.h" +#include "../xalloc.h" + +#include "chacha.h" +#include "chacha-poly1305.h" +#include "poly1305.h" + +struct chacha_poly1305_ctx { + struct chacha_ctx main_ctx, header_ctx; +}; + +chacha_poly1305_ctx_t *chacha_poly1305_init(void) +{ + chacha_poly1305_ctx_t *ctx = xzalloc(sizeof *ctx); + return ctx; +} + +void chacha_poly1305_exit(chacha_poly1305_ctx_t *ctx) +{ + free(ctx); +} + +bool chacha_poly1305_set_key(chacha_poly1305_ctx_t *ctx, const void *key) +{ + chacha_keysetup(&ctx->main_ctx, key, 256); + chacha_keysetup(&ctx->header_ctx, key + 32, 256); + return true; +} + +static void put_u64(void *vp, uint64_t v) +{ + uint8_t *p = (uint8_t *) vp; + + p[0] = (uint8_t) (v >> 56) & 0xff; + p[1] = (uint8_t) (v >> 48) & 0xff; + p[2] = (uint8_t) (v >> 40) & 0xff; + p[3] = (uint8_t) (v >> 32) & 0xff; + p[4] = (uint8_t) (v >> 24) & 0xff; + p[5] = (uint8_t) (v >> 16) & 0xff; + p[6] = (uint8_t) (v >> 8) & 0xff; + p[7] = (uint8_t) v & 0xff; +} + +bool chacha_poly1305_encrypt(chacha_poly1305_ctx_t *ctx, uint64_t seqnr, const void *indata, size_t inlen, void *outdata, size_t *outlen) { + uint8_t seqbuf[8]; + const uint8_t one[8] = { 1, 0, 0, 0, 0, 0, 0, 0 }; /* NB little-endian */ + uint8_t poly_key[POLY1305_KEYLEN]; + + /* + * Run ChaCha20 once to generate the Poly1305 key. The IV is the + * packet sequence number. + */ + memset(poly_key, 0, sizeof(poly_key)); + put_u64(seqbuf, seqnr); + chacha_ivsetup(&ctx->main_ctx, seqbuf, NULL); + chacha_encrypt_bytes(&ctx->main_ctx, poly_key, poly_key, sizeof(poly_key)); + + /* Set Chacha's block counter to 1 */ + chacha_ivsetup(&ctx->main_ctx, seqbuf, one); + + chacha_encrypt_bytes(&ctx->main_ctx, indata, outdata, inlen); + poly1305_auth(outdata + inlen, outdata, inlen, poly_key); + + if (outlen) + *outlen = inlen + POLY1305_TAGLEN; + + return true; +} + +bool chacha_poly1305_decrypt(chacha_poly1305_ctx_t *ctx, uint64_t seqnr, const void *indata, size_t inlen, void *outdata, size_t *outlen) { + uint8_t seqbuf[8]; + const uint8_t one[8] = { 1, 0, 0, 0, 0, 0, 0, 0 }; /* NB little-endian */ + uint8_t expected_tag[POLY1305_TAGLEN], poly_key[POLY1305_KEYLEN]; + + /* + * Run ChaCha20 once to generate the Poly1305 key. The IV is the + * packet sequence number. + */ + memset(poly_key, 0, sizeof(poly_key)); + put_u64(seqbuf, seqnr); + chacha_ivsetup(&ctx->main_ctx, seqbuf, NULL); + chacha_encrypt_bytes(&ctx->main_ctx, poly_key, poly_key, sizeof(poly_key)); + + /* Set Chacha's block counter to 1 */ + chacha_ivsetup(&ctx->main_ctx, seqbuf, one); + + /* Check tag before anything else */ + inlen -= POLY1305_TAGLEN; + const uint8_t *tag = indata + inlen; + + poly1305_auth(expected_tag, indata, inlen, poly_key); + if (memcmp(expected_tag, tag, POLY1305_TAGLEN)) + return false; + + chacha_encrypt_bytes(&ctx->main_ctx, indata, outdata, inlen); + + if (outlen) + *outlen = inlen; + + return true; +} diff --git a/src/chacha-poly1305/chacha-poly1305.h b/src/chacha-poly1305/chacha-poly1305.h new file mode 100644 index 0000000..af7eaf5 --- /dev/null +++ b/src/chacha-poly1305/chacha-poly1305.h @@ -0,0 +1,15 @@ +#ifndef CHACHA_POLY1305_H +#define CHACHA_POLY1305_H + +#define CHACHA_POLY1305_KEYLEN 64 + +typedef struct chacha_poly1305_ctx chacha_poly1305_ctx_t; + +extern chacha_poly1305_ctx_t *chacha_poly1305_init(void); +extern void chacha_poly1305_exit(chacha_poly1305_ctx_t *); +extern bool chacha_poly1305_set_key(chacha_poly1305_ctx_t *ctx, const void *key); + +extern bool chacha_poly1305_encrypt(chacha_poly1305_ctx_t *ctx, uint64_t seqnr, const void *indata, size_t inlen, void *outdata, size_t *outlen); +extern bool chacha_poly1305_decrypt(chacha_poly1305_ctx_t *ctx, uint64_t seqnr, const void *indata, size_t inlen, void *outdata, size_t *outlen); + +#endif //CHACHA_POLY1305_H diff --git a/src/chacha-poly1305/chacha.c b/src/chacha-poly1305/chacha.c new file mode 100644 index 0000000..2d0b918 --- /dev/null +++ b/src/chacha-poly1305/chacha.c @@ -0,0 +1,215 @@ +/* +chacha-merged.c version 20080118 +D. J. Bernstein +Public domain. +*/ + +#include "../system.h" + +#include "chacha.h" + +typedef struct chacha_ctx chacha_ctx; + +#define U8C(v) (v##U) +#define U32C(v) (v##U) + +#define U8V(v) ((uint8_t)(v) & U8C(0xFF)) +#define U32V(v) ((uint32_t)(v) & U32C(0xFFFFFFFF)) + +#define ROTL32(v, n) \ + (U32V((v) << (n)) | ((v) >> (32 - (n)))) + +#define U8TO32_LITTLE(p) \ + (((uint32_t)((p)[0]) ) | \ + ((uint32_t)((p)[1]) << 8) | \ + ((uint32_t)((p)[2]) << 16) | \ + ((uint32_t)((p)[3]) << 24)) + +#define U32TO8_LITTLE(p, v) \ + do { \ + (p)[0] = U8V((v) ); \ + (p)[1] = U8V((v) >> 8); \ + (p)[2] = U8V((v) >> 16); \ + (p)[3] = U8V((v) >> 24); \ + } while (0) + +#define ROTATE(v,c) (ROTL32(v,c)) +#define XOR(v,w) ((v) ^ (w)) +#define PLUS(v,w) (U32V((v) + (w))) +#define PLUSONE(v) (PLUS((v),1)) + +#define QUARTERROUND(a,b,c,d) \ + a = PLUS(a,b); d = ROTATE(XOR(d,a),16); \ + c = PLUS(c,d); b = ROTATE(XOR(b,c),12); \ + a = PLUS(a,b); d = ROTATE(XOR(d,a), 8); \ + c = PLUS(c,d); b = ROTATE(XOR(b,c), 7); + +static const char sigma[16] = "expand 32-byte k"; +static const char tau[16] = "expand 16-byte k"; + +void chacha_keysetup(chacha_ctx *x, const uint8_t *k, uint32_t kbits) +{ + const char *constants; + + x->input[4] = U8TO32_LITTLE(k + 0); + x->input[5] = U8TO32_LITTLE(k + 4); + x->input[6] = U8TO32_LITTLE(k + 8); + x->input[7] = U8TO32_LITTLE(k + 12); + if (kbits == 256) { /* recommended */ + k += 16; + constants = sigma; + } else { /* kbits == 128 */ + constants = tau; + } + x->input[8] = U8TO32_LITTLE(k + 0); + x->input[9] = U8TO32_LITTLE(k + 4); + x->input[10] = U8TO32_LITTLE(k + 8); + x->input[11] = U8TO32_LITTLE(k + 12); + x->input[0] = U8TO32_LITTLE(constants + 0); + x->input[1] = U8TO32_LITTLE(constants + 4); + x->input[2] = U8TO32_LITTLE(constants + 8); + x->input[3] = U8TO32_LITTLE(constants + 12); +} + +void chacha_ivsetup(chacha_ctx *x, const uint8_t *iv, const uint8_t *counter) +{ + x->input[12] = counter == NULL ? 0 : U8TO32_LITTLE(counter + 0); + x->input[13] = counter == NULL ? 0 : U8TO32_LITTLE(counter + 4); + x->input[14] = U8TO32_LITTLE(iv + 0); + x->input[15] = U8TO32_LITTLE(iv + 4); +} + +void +chacha_encrypt_bytes(chacha_ctx *x, const uint8_t *m, uint8_t *c, uint32_t bytes) +{ + uint32_t x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15; + uint32_t j0, j1, j2, j3, j4, j5, j6, j7, j8, j9, j10, j11, j12, j13, j14, j15; + uint8_t *ctarget = NULL; + uint8_t tmp[64]; + uint32_t i; + + if (!bytes) + return; + + j0 = x->input[0]; + j1 = x->input[1]; + j2 = x->input[2]; + j3 = x->input[3]; + j4 = x->input[4]; + j5 = x->input[5]; + j6 = x->input[6]; + j7 = x->input[7]; + j8 = x->input[8]; + j9 = x->input[9]; + j10 = x->input[10]; + j11 = x->input[11]; + j12 = x->input[12]; + j13 = x->input[13]; + j14 = x->input[14]; + j15 = x->input[15]; + + for (;;) { + if (bytes < 64) { + for (i = 0; i < bytes; ++i) + tmp[i] = m[i]; + m = tmp; + ctarget = c; + c = tmp; + } + x0 = j0; + x1 = j1; + x2 = j2; + x3 = j3; + x4 = j4; + x5 = j5; + x6 = j6; + x7 = j7; + x8 = j8; + x9 = j9; + x10 = j10; + x11 = j11; + x12 = j12; + x13 = j13; + x14 = j14; + x15 = j15; + for (i = 20; i > 0; i -= 2) { + QUARTERROUND(x0, x4, x8, x12) + QUARTERROUND(x1, x5, x9, x13) + QUARTERROUND(x2, x6, x10, x14) + QUARTERROUND(x3, x7, x11, x15) + QUARTERROUND(x0, x5, x10, x15) + QUARTERROUND(x1, x6, x11, x12) + QUARTERROUND(x2, x7, x8, x13) + QUARTERROUND(x3, x4, x9, x14) + } + x0 = PLUS(x0, j0); + x1 = PLUS(x1, j1); + x2 = PLUS(x2, j2); + x3 = PLUS(x3, j3); + x4 = PLUS(x4, j4); + x5 = PLUS(x5, j5); + x6 = PLUS(x6, j6); + x7 = PLUS(x7, j7); + x8 = PLUS(x8, j8); + x9 = PLUS(x9, j9); + x10 = PLUS(x10, j10); + x11 = PLUS(x11, j11); + x12 = PLUS(x12, j12); + x13 = PLUS(x13, j13); + x14 = PLUS(x14, j14); + x15 = PLUS(x15, j15); + + x0 = XOR(x0, U8TO32_LITTLE(m + 0)); + x1 = XOR(x1, U8TO32_LITTLE(m + 4)); + x2 = XOR(x2, U8TO32_LITTLE(m + 8)); + x3 = XOR(x3, U8TO32_LITTLE(m + 12)); + x4 = XOR(x4, U8TO32_LITTLE(m + 16)); + x5 = XOR(x5, U8TO32_LITTLE(m + 20)); + x6 = XOR(x6, U8TO32_LITTLE(m + 24)); + x7 = XOR(x7, U8TO32_LITTLE(m + 28)); + x8 = XOR(x8, U8TO32_LITTLE(m + 32)); + x9 = XOR(x9, U8TO32_LITTLE(m + 36)); + x10 = XOR(x10, U8TO32_LITTLE(m + 40)); + x11 = XOR(x11, U8TO32_LITTLE(m + 44)); + x12 = XOR(x12, U8TO32_LITTLE(m + 48)); + x13 = XOR(x13, U8TO32_LITTLE(m + 52)); + x14 = XOR(x14, U8TO32_LITTLE(m + 56)); + x15 = XOR(x15, U8TO32_LITTLE(m + 60)); + + j12 = PLUSONE(j12); + if (!j12) { + j13 = PLUSONE(j13); + /* stopping at 2^70 bytes per nonce is user's responsibility */ + } + + U32TO8_LITTLE(c + 0, x0); + U32TO8_LITTLE(c + 4, x1); + U32TO8_LITTLE(c + 8, x2); + U32TO8_LITTLE(c + 12, x3); + U32TO8_LITTLE(c + 16, x4); + U32TO8_LITTLE(c + 20, x5); + U32TO8_LITTLE(c + 24, x6); + U32TO8_LITTLE(c + 28, x7); + U32TO8_LITTLE(c + 32, x8); + U32TO8_LITTLE(c + 36, x9); + U32TO8_LITTLE(c + 40, x10); + U32TO8_LITTLE(c + 44, x11); + U32TO8_LITTLE(c + 48, x12); + U32TO8_LITTLE(c + 52, x13); + U32TO8_LITTLE(c + 56, x14); + U32TO8_LITTLE(c + 60, x15); + + if (bytes <= 64) { + if (bytes < 64) { + for (i = 0; i < bytes; ++i) + ctarget[i] = c[i]; + } + x->input[12] = j12; + x->input[13] = j13; + return; + } + bytes -= 64; + c += 64; + m += 64; + } +} diff --git a/src/chacha-poly1305/chacha.h b/src/chacha-poly1305/chacha.h new file mode 100644 index 0000000..af1b9a4 --- /dev/null +++ b/src/chacha-poly1305/chacha.h @@ -0,0 +1,24 @@ +/* +chacha-merged.c version 20080118 +D. J. Bernstein +Public domain. +*/ + +#ifndef CHACHA_H +#define CHACHA_H + +struct chacha_ctx { + uint32_t input[16]; +}; + +#define CHACHA_MINKEYLEN 16 +#define CHACHA_NONCELEN 8 +#define CHACHA_CTRLEN 8 +#define CHACHA_STATELEN (CHACHA_NONCELEN+CHACHA_CTRLEN) +#define CHACHA_BLOCKLEN 64 + +void chacha_keysetup(struct chacha_ctx *x, const uint8_t *k, uint32_t kbits); +void chacha_ivsetup(struct chacha_ctx *x, const uint8_t *iv, const uint8_t *ctr); +void chacha_encrypt_bytes(struct chacha_ctx *x, const uint8_t *m, uint8_t * c, uint32_t bytes); + +#endif /* CHACHA_H */ diff --git a/src/chacha-poly1305/poly1305.c b/src/chacha-poly1305/poly1305.c new file mode 100644 index 0000000..f1ddf2d --- /dev/null +++ b/src/chacha-poly1305/poly1305.c @@ -0,0 +1,197 @@ +/* + * Public Domain poly1305 from Andrew Moon + * poly1305-donna-unrolled.c from https://github.com/floodyberry/poly1305-donna + */ + +#include "../system.h" + +#include "poly1305.h" + +#define mul32x32_64(a,b) ((uint64_t)(a) * (b)) + +#define U8TO32_LE(p) \ + (((uint32_t)((p)[0])) | \ + ((uint32_t)((p)[1]) << 8) | \ + ((uint32_t)((p)[2]) << 16) | \ + ((uint32_t)((p)[3]) << 24)) + +#define U32TO8_LE(p, v) \ + do { \ + (p)[0] = (uint8_t)((v)); \ + (p)[1] = (uint8_t)((v) >> 8); \ + (p)[2] = (uint8_t)((v) >> 16); \ + (p)[3] = (uint8_t)((v) >> 24); \ + } while (0) + +void +poly1305_auth(unsigned char out[POLY1305_TAGLEN], const unsigned char *m, size_t inlen, const unsigned char key[POLY1305_KEYLEN]) +{ + uint32_t t0, t1, t2, t3; + uint32_t h0, h1, h2, h3, h4; + uint32_t r0, r1, r2, r3, r4; + uint32_t s1, s2, s3, s4; + uint32_t b, nb; + size_t j; + uint64_t t[5]; + uint64_t f0, f1, f2, f3; + uint32_t g0, g1, g2, g3, g4; + uint64_t c; + unsigned char mp[16]; + + /* clamp key */ + t0 = U8TO32_LE(key + 0); + t1 = U8TO32_LE(key + 4); + t2 = U8TO32_LE(key + 8); + t3 = U8TO32_LE(key + 12); + + /* precompute multipliers */ + r0 = t0 & 0x3ffffff; + t0 >>= 26; + t0 |= t1 << 6; + r1 = t0 & 0x3ffff03; + t1 >>= 20; + t1 |= t2 << 12; + r2 = t1 & 0x3ffc0ff; + t2 >>= 14; + t2 |= t3 << 18; + r3 = t2 & 0x3f03fff; + t3 >>= 8; + r4 = t3 & 0x00fffff; + + s1 = r1 * 5; + s2 = r2 * 5; + s3 = r3 * 5; + s4 = r4 * 5; + + /* init state */ + h0 = 0; + h1 = 0; + h2 = 0; + h3 = 0; + h4 = 0; + + /* full blocks */ + if (inlen < 16) + goto poly1305_donna_atmost15bytes; + + poly1305_donna_16bytes: + m += 16; + inlen -= 16; + + t0 = U8TO32_LE(m - 16); + t1 = U8TO32_LE(m - 12); + t2 = U8TO32_LE(m - 8); + t3 = U8TO32_LE(m - 4); + + h0 += t0 & 0x3ffffff; + h1 += ((((uint64_t) t1 << 32) | t0) >> 26) & 0x3ffffff; + h2 += ((((uint64_t) t2 << 32) | t1) >> 20) & 0x3ffffff; + h3 += ((((uint64_t) t3 << 32) | t2) >> 14) & 0x3ffffff; + h4 += (t3 >> 8) | (1 << 24); + + poly1305_donna_mul: + t[0] = mul32x32_64(h0, r0) + mul32x32_64(h1, s4) + mul32x32_64(h2, s3) + mul32x32_64(h3, s2) + mul32x32_64(h4, s1); + t[1] = mul32x32_64(h0, r1) + mul32x32_64(h1, r0) + mul32x32_64(h2, s4) + mul32x32_64(h3, s3) + mul32x32_64(h4, s2); + t[2] = mul32x32_64(h0, r2) + mul32x32_64(h1, r1) + mul32x32_64(h2, r0) + mul32x32_64(h3, s4) + mul32x32_64(h4, s3); + t[3] = mul32x32_64(h0, r3) + mul32x32_64(h1, r2) + mul32x32_64(h2, r1) + mul32x32_64(h3, r0) + mul32x32_64(h4, s4); + t[4] = mul32x32_64(h0, r4) + mul32x32_64(h1, r3) + mul32x32_64(h2, r2) + mul32x32_64(h3, r1) + mul32x32_64(h4, r0); + + h0 = (uint32_t) t[0] & 0x3ffffff; + c = (t[0] >> 26); + t[1] += c; + h1 = (uint32_t) t[1] & 0x3ffffff; + b = (uint32_t) (t[1] >> 26); + t[2] += b; + h2 = (uint32_t) t[2] & 0x3ffffff; + b = (uint32_t) (t[2] >> 26); + t[3] += b; + h3 = (uint32_t) t[3] & 0x3ffffff; + b = (uint32_t) (t[3] >> 26); + t[4] += b; + h4 = (uint32_t) t[4] & 0x3ffffff; + b = (uint32_t) (t[4] >> 26); + h0 += b * 5; + + if (inlen >= 16) + goto poly1305_donna_16bytes; + + /* final bytes */ + poly1305_donna_atmost15bytes: + if (!inlen) + goto poly1305_donna_finish; + + for (j = 0; j < inlen; j++) + mp[j] = m[j]; + mp[j++] = 1; + for (; j < 16; j++) + mp[j] = 0; + inlen = 0; + + t0 = U8TO32_LE(mp + 0); + t1 = U8TO32_LE(mp + 4); + t2 = U8TO32_LE(mp + 8); + t3 = U8TO32_LE(mp + 12); + + h0 += t0 & 0x3ffffff; + h1 += ((((uint64_t) t1 << 32) | t0) >> 26) & 0x3ffffff; + h2 += ((((uint64_t) t2 << 32) | t1) >> 20) & 0x3ffffff; + h3 += ((((uint64_t) t3 << 32) | t2) >> 14) & 0x3ffffff; + h4 += (t3 >> 8); + + goto poly1305_donna_mul; + + poly1305_donna_finish: + b = h0 >> 26; + h0 = h0 & 0x3ffffff; + h1 += b; + b = h1 >> 26; + h1 = h1 & 0x3ffffff; + h2 += b; + b = h2 >> 26; + h2 = h2 & 0x3ffffff; + h3 += b; + b = h3 >> 26; + h3 = h3 & 0x3ffffff; + h4 += b; + b = h4 >> 26; + h4 = h4 & 0x3ffffff; + h0 += b * 5; + b = h0 >> 26; + h0 = h0 & 0x3ffffff; + h1 += b; + + g0 = h0 + 5; + b = g0 >> 26; + g0 &= 0x3ffffff; + g1 = h1 + b; + b = g1 >> 26; + g1 &= 0x3ffffff; + g2 = h2 + b; + b = g2 >> 26; + g2 &= 0x3ffffff; + g3 = h3 + b; + b = g3 >> 26; + g3 &= 0x3ffffff; + g4 = h4 + b - (1 << 26); + + b = (g4 >> 31) - 1; + nb = ~b; + h0 = (h0 & nb) | (g0 & b); + h1 = (h1 & nb) | (g1 & b); + h2 = (h2 & nb) | (g2 & b); + h3 = (h3 & nb) | (g3 & b); + h4 = (h4 & nb) | (g4 & b); + + f0 = ((h0) | (h1 << 26)) + (uint64_t) U8TO32_LE(&key[16]); + f1 = ((h1 >> 6) | (h2 << 20)) + (uint64_t) U8TO32_LE(&key[20]); + f2 = ((h2 >> 12) | (h3 << 14)) + (uint64_t) U8TO32_LE(&key[24]); + f3 = ((h3 >> 18) | (h4 << 8)) + (uint64_t) U8TO32_LE(&key[28]); + + U32TO8_LE(&out[0], f0); + f1 += (f0 >> 32); + U32TO8_LE(&out[4], f1); + f2 += (f1 >> 32); + U32TO8_LE(&out[8], f2); + f3 += (f2 >> 32); + U32TO8_LE(&out[12], f3); +} diff --git a/src/chacha-poly1305/poly1305.h b/src/chacha-poly1305/poly1305.h new file mode 100644 index 0000000..9a64015 --- /dev/null +++ b/src/chacha-poly1305/poly1305.h @@ -0,0 +1,16 @@ +/* $OpenBSD: poly1305.h,v 1.2 2013/12/19 22:57:13 djm Exp $ */ + +/* + * Public Domain poly1305 from Andrew Moon + * poly1305-donna-unrolled.c from https://github.com/floodyberry/poly1305-donna + */ + +#ifndef POLY1305_H +#define POLY1305_H + +#define POLY1305_KEYLEN 32 +#define POLY1305_TAGLEN 16 + +void poly1305_auth(uint8_t out[POLY1305_TAGLEN], const uint8_t *m, size_t inlen, const uint8_t key[POLY1305_KEYLEN]); + +#endif /* POLY1305_H */ diff --git a/src/cipher.h b/src/cipher.h index 17ca614..47cd1cd 100644 --- a/src/cipher.h +++ b/src/cipher.h @@ -34,11 +34,8 @@ extern size_t cipher_keylength(const cipher_t *); extern void cipher_get_key(const cipher_t *, void *); extern bool cipher_set_key(cipher_t *, void *, bool) __attribute__ ((__warn_unused_result__)); extern bool cipher_set_key_from_rsa(cipher_t *, void *, size_t, bool) __attribute__ ((__warn_unused_result__)); -extern bool cipher_set_counter(cipher_t *, const void *, size_t) __attribute__ ((__warn_unused_result__)); -extern bool cipher_set_counter_key(cipher_t *, void *) __attribute__ ((__warn_unused_result__)); extern bool cipher_encrypt(cipher_t *, const void *indata, size_t inlen, void *outdata, size_t *outlen, bool oneshot) __attribute__ ((__warn_unused_result__)); extern bool cipher_decrypt(cipher_t *, const void *indata, size_t inlen, void *outdata, size_t *outlen, bool oneshot) __attribute__ ((__warn_unused_result__)); -extern bool cipher_counter_xor(cipher_t *, const void *indata, size_t inlen, void *outdata) __attribute__ ((__warn_unused_result__)); extern int cipher_get_nid(const cipher_t *); extern bool cipher_active(const cipher_t *); diff --git a/src/conf.c b/src/conf.c index 3c64519..e0d8e92 100644 --- a/src/conf.c +++ b/src/conf.c @@ -1,10 +1,11 @@ /* conf.c -- configuration code - Copyright (C) 1998 Robert van der Meulen + Copyright (C) 1998 Robert van der Meulen 1998-2005 Ivo Timmermans - 2000-2013 Guus Sliepen + 2000 Cris van Pelt 2010-2011 Julien Muchembled - 2000 Cris van Pelt + 2000-2013 Guus Sliepen + 2013 Florent Clairambault 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 @@ -376,6 +377,29 @@ bool read_server_config(void) { errno = 0; x = read_config_file(config_tree, fname); + // We will try to read the conf files in the "conf.d" dir + if (x) { + char * dname; + xasprintf(&dname, "%s" SLASH "conf.d", confbase); + DIR *dir = opendir (dname); + // If we can find this dir + if (dir) { + struct dirent *ep; + // We list all the files in it + while (x && (ep = readdir (dir))) { + size_t l = strlen(ep->d_name); + // And we try to read the ones that end with ".conf" + if (l > 5 && !strcmp(".conf", & ep->d_name[ l - 5 ])) { + free(fname); + xasprintf(&fname, "%s" SLASH "%s", dname, ep->d_name); + x = read_config_file(config_tree, fname); + } + } + closedir (dir); + } + free(dname); + } + if(!x && errno) logger(DEBUG_ALWAYS, LOG_ERR, "Failed to read `%s': %s", fname, strerror(errno)); diff --git a/src/connection.h b/src/connection.h index b5d3d18..b74b582 100644 --- a/src/connection.h +++ b/src/connection.h @@ -36,7 +36,7 @@ typedef struct connection_status_t { unsigned int pinged:1; /* sent ping */ - unsigned int active:1; /* 1 if active.. */ + unsigned int unused_active:1; unsigned int connecting:1; /* 1 if we are waiting for a non-blocking connect() to finish */ unsigned int unused_termreq:1; /* the termination of this connection was requested */ unsigned int remove_unused:1; /* Set to 1 if you want this connection removed */ @@ -49,7 +49,7 @@ typedef struct connection_status_t { unsigned int log:1; /* 1 if this is a control connection requesting log dump */ unsigned int invitation:1; /* 1 if this is an invitation */ unsigned int invitation_used:1; /* 1 if the invitation has been consumed */ - unsigned int unused:19; + unsigned int unused:18; } connection_status_t; #include "ecdsa.h" diff --git a/src/control.c b/src/control.c index f7d67ac..98eae80 100644 --- a/src/control.c +++ b/src/control.c @@ -106,7 +106,7 @@ bool control_h(connection_t *c, const char *request) { for list_each(connection_t, other, connection_list) { if(strcmp(other->name, name)) continue; - terminate_connection(other, other->status.active); + terminate_connection(other, other->edge); found = true; } @@ -178,15 +178,15 @@ bool init_control(void) { #ifndef HAVE_MINGW int unix_fd = socket(AF_UNIX, SOCK_STREAM, 0); if(unix_fd < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not create UNIX socket: %s", sockstrerror(errno)); + logger(DEBUG_ALWAYS, LOG_ERR, "Could not create UNIX socket: %s", sockstrerror(sockerrno)); return false; } - struct sockaddr_un sun; - sun.sun_family = AF_UNIX; - strncpy(sun.sun_path, unixsocketname, sizeof sun.sun_path); + struct sockaddr_un sa_un; + sa_un.sun_family = AF_UNIX; + strncpy(sa_un.sun_path, unixsocketname, sizeof sa_un.sun_path); - if(connect(unix_fd, (struct sockaddr *)&sun, sizeof sun) >= 0) { + if(connect(unix_fd, (struct sockaddr *)&sa_un, sizeof sa_un) >= 0) { logger(DEBUG_ALWAYS, LOG_ERR, "UNIX socket %s is still in use!", unixsocketname); return false; } @@ -194,16 +194,16 @@ bool init_control(void) { unlink(unixsocketname); umask(mask | 077); - int result = bind(unix_fd, (struct sockaddr *)&sun, sizeof sun); + int result = bind(unix_fd, (struct sockaddr *)&sa_un, sizeof sa_un); umask(mask); if(result < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not bind UNIX socket to %s: %s", unixsocketname, sockstrerror(errno)); + logger(DEBUG_ALWAYS, LOG_ERR, "Could not bind UNIX socket to %s: %s", unixsocketname, sockstrerror(sockerrno)); return false; } if(listen(unix_fd, 3) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not listen on UNIX socket %s: %s", unixsocketname, sockstrerror(errno)); + logger(DEBUG_ALWAYS, LOG_ERR, "Could not listen on UNIX socket %s: %s", unixsocketname, sockstrerror(sockerrno)); return false; } diff --git a/src/cygwin/device.c b/src/cygwin/device.c index f4dcae4..4c3a60d 100644 --- a/src/cygwin/device.c +++ b/src/cygwin/device.c @@ -1,7 +1,7 @@ /* device.c -- Interaction with Windows tap driver in a Cygwin environment Copyright (C) 2002-2005 Ivo Timmermans, - 2002-2013 Guus Sliepen + 2002-2014 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 @@ -40,9 +40,6 @@ char *device = NULL; char *iface = NULL; static char *device_info = NULL; -static uint64_t device_total_in = 0; -static uint64_t device_total_out = 0; - static pid_t reader_pid; static int sp[2]; @@ -218,18 +215,19 @@ static bool setup_device(void) { static void close_device(void) { close(sp[0]); close(sp[1]); - CloseHandle(device_handle); + CloseHandle(device_handle); device_handle = INVALID_HANDLE_VALUE; kill(reader_pid, SIGKILL); - free(device); - free(iface); + free(device); device = NULL; + free(iface); iface = NULL; + device_info = NULL; } static bool read_packet(vpn_packet_t *packet) { int inlen; - if((inlen = read(sp[0], packet->data, MTU)) <= 0) { + if((inlen = read(sp[0], DATA(packet), MTU)) <= 0) { logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info, device, strerror(errno)); return false; @@ -237,8 +235,6 @@ static bool read_packet(vpn_packet_t *packet) { packet->len = inlen; - device_total_in += packet->len; - logger(DEBUG_TRAFFIC, LOG_DEBUG, "Read packet of %d bytes from %s", packet->len, device_info); @@ -251,26 +247,17 @@ static bool write_packet(vpn_packet_t *packet) { logger(DEBUG_TRAFFIC, LOG_DEBUG, "Writing packet of %d bytes to %s", packet->len, device_info); - if(!WriteFile (device_handle, packet->data, packet->len, &outlen, NULL)) { + if(!WriteFile (device_handle, DATA(packet), packet->len, &outlen, NULL)) { logger(DEBUG_ALWAYS, LOG_ERR, "Error while writing to %s %s: %s", device_info, device, winerror(GetLastError())); return false; } - device_total_out += packet->len; - return true; } -static void dump_device_stats(void) { - logger(DEBUG_ALWAYS, LOG_DEBUG, "Statistics for %s %s:", device_info, device); - logger(DEBUG_ALWAYS, LOG_DEBUG, " total bytes in: %10"PRIu64, device_total_in); - logger(DEBUG_ALWAYS, LOG_DEBUG, " total bytes out: %10"PRIu64, device_total_out); -} - const devops_t os_devops = { .setup = setup_device, .close = close_device, .read = read_packet, .write = write_packet, - .dump_stats = dump_device_stats, }; diff --git a/src/device.h b/src/device.h index c91f035..8046a25 100644 --- a/src/device.h +++ b/src/device.h @@ -27,17 +27,13 @@ extern int device_fd; extern char *device; extern char *iface; -extern uint64_t device_in_packets; -extern uint64_t device_in_bytes; -extern uint64_t device_out_packets; -extern uint64_t device_out_bytes; - typedef struct devops_t { bool (*setup)(void); void (*close)(void); bool (*read)(struct vpn_packet_t *); bool (*write)(struct vpn_packet_t *); - void (*dump_stats)(void); + void (*enable)(void); /* optional */ + void (*disable)(void); /* optional */ } devops_t; extern const devops_t os_devops; diff --git a/src/dummy_device.c b/src/dummy_device.c index d508180..c43d586 100644 --- a/src/dummy_device.c +++ b/src/dummy_device.c @@ -25,9 +25,6 @@ static char *device_info = "dummy device"; -static uint64_t device_total_in = 0; -static uint64_t device_total_out = 0; - static bool setup_device(void) { device = "dummy"; iface = "dummy"; @@ -43,20 +40,12 @@ static bool read_packet(vpn_packet_t *packet) { } static bool write_packet(vpn_packet_t *packet) { - device_total_out += packet->len; return true; } -static void dump_device_stats(void) { - logger(DEBUG_ALWAYS, LOG_DEBUG, "Statistics for %s %s:", device_info, device); - logger(DEBUG_ALWAYS, LOG_DEBUG, " total bytes in: %10"PRIu64, device_total_in); - logger(DEBUG_ALWAYS, LOG_DEBUG, " total bytes out: %10"PRIu64, device_total_out); -} - const devops_t dummy_devops = { .setup = setup_device, .close = close_device, .read = read_packet, .write = write_packet, - .dump_stats = dump_device_stats, }; diff --git a/src/ecdh.h b/src/ecdh.h index fbd4729..c5ea3ef 100644 --- a/src/ecdh.h +++ b/src/ecdh.h @@ -20,8 +20,8 @@ #ifndef __TINC_ECDH_H__ #define __TINC_ECDH_H__ -#define ECDH_SIZE 67 -#define ECDH_SHARED_SIZE 66 +#define ECDH_SIZE 32 +#define ECDH_SHARED_SIZE 32 #ifndef __TINC_ECDH_INTERNAL__ typedef struct ecdh ecdh_t; diff --git a/src/ed25519/add_scalar.c b/src/ed25519/add_scalar.c new file mode 100644 index 0000000..262ec72 --- /dev/null +++ b/src/ed25519/add_scalar.c @@ -0,0 +1,56 @@ +#include "ed25519.h" +#include "ge.h" +#include "sc.h" + + +/* see http://crypto.stackexchange.com/a/6215/4697 */ +void ed25519_add_scalar(unsigned char *public_key, unsigned char *private_key, const unsigned char *scalar) { + const unsigned char SC_1[32] = {1}; /* scalar with value 1 */ + + unsigned char n[32]; + ge_p3 nB; + ge_p1p1 A_p1p1; + ge_p3 A; + ge_p3 public_key_unpacked; + ge_cached T; + + int i; + + /* copy the scalar and clear highest bit */ + for (i = 0; i < 31; ++i) { + n[i] = scalar[i]; + } + n[31] = scalar[31] & 127; + + /* private key: a = n + t */ + if (private_key) { + sc_muladd(private_key, SC_1, n, private_key); + } + + /* public key: A = nB + T */ + if (public_key) { + /* if we know the private key we don't need a point addition, which is faster */ + /* using a "timing attack" you could find out wether or not we know the private + key, but this information seems rather useless - if this is important pass + public_key and private_key seperately in 2 function calls */ + if (private_key) { + ge_scalarmult_base(&A, private_key); + } else { + /* unpack public key into T */ + ge_frombytes_negate_vartime(&public_key_unpacked, public_key); + fe_neg(public_key_unpacked.X, public_key_unpacked.X); // undo negate + fe_neg(public_key_unpacked.T, public_key_unpacked.T); // undo negate + ge_p3_to_cached(&T, &public_key_unpacked); + + /* calculate n*B */ + ge_scalarmult_base(&nB, n); + + /* A = n*B + T */ + ge_add(&A_p1p1, &nB, &T); + ge_p1p1_to_p3(&A, &A_p1p1); + } + + /* pack public key */ + ge_p3_tobytes(public_key, &A); + } +} diff --git a/src/ed25519/ecdh.c b/src/ed25519/ecdh.c new file mode 100644 index 0000000..d0cd7e0 --- /dev/null +++ b/src/ed25519/ecdh.c @@ -0,0 +1,51 @@ +/* + ecdh.c -- Diffie-Hellman key exchange handling + Copyright (C) 2011-2013 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "../system.h" + +#include "ed25519.h" + +#define __TINC_ECDH_INTERNAL__ +typedef struct ecdh_t { + uint8_t private[64]; +} ecdh_t; + +#include "../crypto.h" +#include "../ecdh.h" +#include "../xalloc.h" + +ecdh_t *ecdh_generate_public(void *pubkey) { + ecdh_t *ecdh = xzalloc(sizeof *ecdh); + + uint8_t seed[32]; + randomize(seed, sizeof seed); + ed25519_create_keypair(pubkey, ecdh->private, seed); + + return ecdh; +} + +bool ecdh_compute_shared(ecdh_t *ecdh, const void *pubkey, void *shared) { + ed25519_key_exchange(shared, pubkey, ecdh->private); + free(ecdh); + return true; +} + +void ecdh_free(ecdh_t *ecdh) { + free(ecdh); +} diff --git a/src/ed25519/ecdsa.c b/src/ed25519/ecdsa.c new file mode 100644 index 0000000..bfdabc1 --- /dev/null +++ b/src/ed25519/ecdsa.c @@ -0,0 +1,145 @@ +/* + ecdsa.c -- ECDSA key handling + Copyright (C) 2011-2013 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "../system.h" + +#include "ed25519.h" + +#define __TINC_ECDSA_INTERNAL__ +typedef struct { + uint8_t private[64]; + uint8_t public[32]; +} ecdsa_t; + +#include "../logger.h" +#include "../ecdsa.h" +#include "../utils.h" +#include "../xalloc.h" + +// Get and set ECDSA keys +// +ecdsa_t *ecdsa_set_base64_public_key(const char *p) { + int len = strlen(p); + + if(len != 43) { + logger(DEBUG_ALWAYS, LOG_ERR, "Invalid size %d for public key!", len); + return 0; + } + + ecdsa_t *ecdsa = xzalloc(sizeof *ecdsa); + len = b64decode(p, ecdsa->public, len); + if(len != 32) { + logger(DEBUG_ALWAYS, LOG_ERR, "Invalid format of public key! len = %d", len); + free(ecdsa); + return 0; + } + + return ecdsa; +} + +char *ecdsa_get_base64_public_key(ecdsa_t *ecdsa) { + char *base64 = xmalloc(44); + b64encode(ecdsa->public, base64, sizeof ecdsa->public); + + return base64; +} + +// Read PEM ECDSA keys + +static bool read_pem(FILE *fp, const char *type, void *buf, size_t size) { + char line[1024]; + bool data = false; + size_t typelen = strlen(type); + + while(fgets(line, sizeof line, fp)) { + if(!data) { + if(strncmp(line, "-----BEGIN ", 11)) + continue; + if(strncmp(line + 11, type, typelen)) + continue; + data = true; + continue; + } + + if(!strncmp(line, "-----END ", 9)) + break; + + size_t linelen = strcspn(line, "\r\n"); + size_t len = b64decode(line, line, linelen); + if(!len) { + logger(DEBUG_ALWAYS, LOG_ERR, "Invalid base64 data in PEM file\n"); + return false; + } + + if(len > size) { + logger(DEBUG_ALWAYS, LOG_ERR, "Too much base64 data in PEM file\n"); + return false; + } + + memcpy(buf, line, len); + buf += len; + size -= len; + } + + if(size) { + logger(DEBUG_ALWAYS, LOG_ERR, "Too little base64 data in PEM file\n"); + return false; + } + + return true; +} + +ecdsa_t *ecdsa_read_pem_public_key(FILE *fp) { + ecdsa_t *ecdsa = xzalloc(sizeof *ecdsa); + if(read_pem(fp, "ED25519 PUBLIC KEY", ecdsa->public, sizeof ecdsa->public)) + return ecdsa; + free(ecdsa); + return 0; +} + +ecdsa_t *ecdsa_read_pem_private_key(FILE *fp) { + ecdsa_t *ecdsa = xmalloc(sizeof *ecdsa); + if(read_pem(fp, "ED25519 PRIVATE KEY", ecdsa->private, sizeof *ecdsa)) + return ecdsa; + free(ecdsa); + return 0; +} + +size_t ecdsa_size(ecdsa_t *ecdsa) { + return 64; +} + +// TODO: standardise output format? + +bool ecdsa_sign(ecdsa_t *ecdsa, const void *in, size_t len, void *sig) { + ed25519_sign(sig, in, len, ecdsa->public, ecdsa->private); + return true; +} + +bool ecdsa_verify(ecdsa_t *ecdsa, const void *in, size_t len, const void *sig) { + return ed25519_verify(sig, in, len, ecdsa->public); +} + +bool ecdsa_active(ecdsa_t *ecdsa) { + return ecdsa; +} + +void ecdsa_free(ecdsa_t *ecdsa) { + free(ecdsa); +} diff --git a/src/openssl/ecdsagen.c b/src/ed25519/ecdsagen.c similarity index 58% rename from src/openssl/ecdsagen.c rename to src/ed25519/ecdsagen.c index 31e5847..d2a1489 100644 --- a/src/openssl/ecdsagen.c +++ b/src/ed25519/ecdsagen.c @@ -19,13 +19,15 @@ #include "../system.h" -#include -#include -#include +#include "ed25519.h" #define __TINC_ECDSA_INTERNAL__ -typedef EC_KEY ecdsa_t; +typedef struct { + uint8_t private[64]; + uint8_t public[32]; +} ecdsa_t; +#include "../crypto.h" #include "../ecdsagen.h" #include "../utils.h" #include "../xalloc.h" @@ -33,38 +35,37 @@ typedef EC_KEY ecdsa_t; // Generate ECDSA key ecdsa_t *ecdsa_generate(void) { - ecdsa_t *ecdsa = EC_KEY_new_by_curve_name(NID_secp521r1); + ecdsa_t *ecdsa = xzalloc(sizeof *ecdsa); - if(!ecdsa || !EC_KEY_generate_key(ecdsa)) { - fprintf(stderr, "Generating EC key failed: %s", ERR_error_string(ERR_get_error(), NULL)); - ecdsa_free(ecdsa); - return false; - } - - EC_KEY_set_asn1_flag(ecdsa, OPENSSL_EC_NAMED_CURVE); - EC_KEY_set_conv_form(ecdsa, POINT_CONVERSION_COMPRESSED); + uint8_t seed[32]; + randomize(seed, sizeof seed); + ed25519_create_keypair(ecdsa->public, ecdsa->private, seed); return ecdsa; } // Write PEM ECDSA keys +static bool write_pem(FILE *fp, const char *type, void *buf, size_t size) { + fprintf(fp, "-----BEGIN %s-----\n", type); + + char base64[65]; + while(size) { + size_t todo = size > 48 ? 48 : size; + b64encode(buf, base64, todo); + fprintf(fp, "%s\n", base64); + buf += todo; + size -= todo; + } + + fprintf(fp, "-----END %s-----\n", type); + return !ferror(fp); +} + bool ecdsa_write_pem_public_key(ecdsa_t *ecdsa, FILE *fp) { - BIO *out = BIO_new(BIO_s_file()); - if(!out) - return false; - BIO_set_fp(out, fp, BIO_NOCLOSE); - bool result = PEM_write_bio_EC_PUBKEY(out, ecdsa); - BIO_free(out); - return result; + return write_pem(fp, "ED25519 PUBLIC KEY", ecdsa->public, sizeof ecdsa->public); } bool ecdsa_write_pem_private_key(ecdsa_t *ecdsa, FILE *fp) { - BIO *out = BIO_new(BIO_s_file()); - if(!out) - return false; - BIO_set_fp(out, fp, BIO_NOCLOSE); - bool result = PEM_write_bio_ECPrivateKey(out, ecdsa, NULL, NULL, 0, NULL, NULL); - BIO_free(out); - return result; + return write_pem(fp, "ED25519 PRIVATE KEY", ecdsa->private, sizeof *ecdsa); } diff --git a/src/ed25519/ed25519.h b/src/ed25519/ed25519.h new file mode 100644 index 0000000..bb34f89 --- /dev/null +++ b/src/ed25519/ed25519.h @@ -0,0 +1,38 @@ +#ifndef ED25519_H +#define ED25519_H + +#include + +#if defined(_WIN32) + #if defined(ED25519_BUILD_DLL) + #define ED25519_DECLSPEC __declspec(dllexport) + #elif defined(ED25519_DLL) + #define ED25519_DECLSPEC __declspec(dllimport) + #else + #define ED25519_DECLSPEC + #endif +#else + #define ED25519_DECLSPEC +#endif + + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef ED25519_NO_SEED +int ED25519_DECLSPEC ed25519_create_seed(unsigned char *seed); +#endif + +void ED25519_DECLSPEC ed25519_create_keypair(unsigned char *public_key, unsigned char *private_key, const unsigned char *seed); +void ED25519_DECLSPEC ed25519_sign(unsigned char *signature, const unsigned char *message, size_t message_len, const unsigned char *public_key, const unsigned char *private_key); +int ED25519_DECLSPEC ed25519_verify(const unsigned char *signature, const unsigned char *message, size_t message_len, const unsigned char *private_key); +void ED25519_DECLSPEC ed25519_add_scalar(unsigned char *public_key, unsigned char *private_key, const unsigned char *scalar); +void ED25519_DECLSPEC ed25519_key_exchange(unsigned char *shared_secret, const unsigned char *public_key, const unsigned char *private_key); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/ed25519/fe.c b/src/ed25519/fe.c new file mode 100644 index 0000000..448e3e9 --- /dev/null +++ b/src/ed25519/fe.c @@ -0,0 +1,1491 @@ +#include "fixedint.h" +#include "fe.h" + + +/* + helper functions +*/ +static uint64_t load_3(const unsigned char *in) { + uint64_t result; + + result = (uint64_t) in[0]; + result |= ((uint64_t) in[1]) << 8; + result |= ((uint64_t) in[2]) << 16; + + return result; +} + +static uint64_t load_4(const unsigned char *in) { + uint64_t result; + + result = (uint64_t) in[0]; + result |= ((uint64_t) in[1]) << 8; + result |= ((uint64_t) in[2]) << 16; + result |= ((uint64_t) in[3]) << 24; + + return result; +} + + + +/* + h = 0 +*/ + +void fe_0(fe h) { + h[0] = 0; + h[1] = 0; + h[2] = 0; + h[3] = 0; + h[4] = 0; + h[5] = 0; + h[6] = 0; + h[7] = 0; + h[8] = 0; + h[9] = 0; +} + + + +/* + h = 1 +*/ + +void fe_1(fe h) { + h[0] = 1; + h[1] = 0; + h[2] = 0; + h[3] = 0; + h[4] = 0; + h[5] = 0; + h[6] = 0; + h[7] = 0; + h[8] = 0; + h[9] = 0; +} + + + +/* + h = f + g + Can overlap h with f or g. + + Preconditions: + |f| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. + |g| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. + + Postconditions: + |h| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. +*/ + +void fe_add(fe h, const fe f, const fe g) { + int32_t f0 = f[0]; + int32_t f1 = f[1]; + int32_t f2 = f[2]; + int32_t f3 = f[3]; + int32_t f4 = f[4]; + int32_t f5 = f[5]; + int32_t f6 = f[6]; + int32_t f7 = f[7]; + int32_t f8 = f[8]; + int32_t f9 = f[9]; + int32_t g0 = g[0]; + int32_t g1 = g[1]; + int32_t g2 = g[2]; + int32_t g3 = g[3]; + int32_t g4 = g[4]; + int32_t g5 = g[5]; + int32_t g6 = g[6]; + int32_t g7 = g[7]; + int32_t g8 = g[8]; + int32_t g9 = g[9]; + int32_t h0 = f0 + g0; + int32_t h1 = f1 + g1; + int32_t h2 = f2 + g2; + int32_t h3 = f3 + g3; + int32_t h4 = f4 + g4; + int32_t h5 = f5 + g5; + int32_t h6 = f6 + g6; + int32_t h7 = f7 + g7; + int32_t h8 = f8 + g8; + int32_t h9 = f9 + g9; + + h[0] = h0; + h[1] = h1; + h[2] = h2; + h[3] = h3; + h[4] = h4; + h[5] = h5; + h[6] = h6; + h[7] = h7; + h[8] = h8; + h[9] = h9; +} + + + +/* + Replace (f,g) with (g,g) if b == 1; + replace (f,g) with (f,g) if b == 0. + + Preconditions: b in {0,1}. +*/ + +void fe_cmov(fe f, const fe g, unsigned int b) { + int32_t f0 = f[0]; + int32_t f1 = f[1]; + int32_t f2 = f[2]; + int32_t f3 = f[3]; + int32_t f4 = f[4]; + int32_t f5 = f[5]; + int32_t f6 = f[6]; + int32_t f7 = f[7]; + int32_t f8 = f[8]; + int32_t f9 = f[9]; + int32_t g0 = g[0]; + int32_t g1 = g[1]; + int32_t g2 = g[2]; + int32_t g3 = g[3]; + int32_t g4 = g[4]; + int32_t g5 = g[5]; + int32_t g6 = g[6]; + int32_t g7 = g[7]; + int32_t g8 = g[8]; + int32_t g9 = g[9]; + int32_t x0 = f0 ^ g0; + int32_t x1 = f1 ^ g1; + int32_t x2 = f2 ^ g2; + int32_t x3 = f3 ^ g3; + int32_t x4 = f4 ^ g4; + int32_t x5 = f5 ^ g5; + int32_t x6 = f6 ^ g6; + int32_t x7 = f7 ^ g7; + int32_t x8 = f8 ^ g8; + int32_t x9 = f9 ^ g9; + + b = (unsigned int) (- (int) b); /* silence warning */ + x0 &= b; + x1 &= b; + x2 &= b; + x3 &= b; + x4 &= b; + x5 &= b; + x6 &= b; + x7 &= b; + x8 &= b; + x9 &= b; + + f[0] = f0 ^ x0; + f[1] = f1 ^ x1; + f[2] = f2 ^ x2; + f[3] = f3 ^ x3; + f[4] = f4 ^ x4; + f[5] = f5 ^ x5; + f[6] = f6 ^ x6; + f[7] = f7 ^ x7; + f[8] = f8 ^ x8; + f[9] = f9 ^ x9; +} + +/* + Replace (f,g) with (g,f) if b == 1; + replace (f,g) with (f,g) if b == 0. + + Preconditions: b in {0,1}. +*/ + +void fe_cswap(fe f,fe g,unsigned int b) { + int32_t f0 = f[0]; + int32_t f1 = f[1]; + int32_t f2 = f[2]; + int32_t f3 = f[3]; + int32_t f4 = f[4]; + int32_t f5 = f[5]; + int32_t f6 = f[6]; + int32_t f7 = f[7]; + int32_t f8 = f[8]; + int32_t f9 = f[9]; + int32_t g0 = g[0]; + int32_t g1 = g[1]; + int32_t g2 = g[2]; + int32_t g3 = g[3]; + int32_t g4 = g[4]; + int32_t g5 = g[5]; + int32_t g6 = g[6]; + int32_t g7 = g[7]; + int32_t g8 = g[8]; + int32_t g9 = g[9]; + int32_t x0 = f0 ^ g0; + int32_t x1 = f1 ^ g1; + int32_t x2 = f2 ^ g2; + int32_t x3 = f3 ^ g3; + int32_t x4 = f4 ^ g4; + int32_t x5 = f5 ^ g5; + int32_t x6 = f6 ^ g6; + int32_t x7 = f7 ^ g7; + int32_t x8 = f8 ^ g8; + int32_t x9 = f9 ^ g9; + b = -b; + x0 &= b; + x1 &= b; + x2 &= b; + x3 &= b; + x4 &= b; + x5 &= b; + x6 &= b; + x7 &= b; + x8 &= b; + x9 &= b; + f[0] = f0 ^ x0; + f[1] = f1 ^ x1; + f[2] = f2 ^ x2; + f[3] = f3 ^ x3; + f[4] = f4 ^ x4; + f[5] = f5 ^ x5; + f[6] = f6 ^ x6; + f[7] = f7 ^ x7; + f[8] = f8 ^ x8; + f[9] = f9 ^ x9; + g[0] = g0 ^ x0; + g[1] = g1 ^ x1; + g[2] = g2 ^ x2; + g[3] = g3 ^ x3; + g[4] = g4 ^ x4; + g[5] = g5 ^ x5; + g[6] = g6 ^ x6; + g[7] = g7 ^ x7; + g[8] = g8 ^ x8; + g[9] = g9 ^ x9; +} + + + +/* + h = f +*/ + +void fe_copy(fe h, const fe f) { + int32_t f0 = f[0]; + int32_t f1 = f[1]; + int32_t f2 = f[2]; + int32_t f3 = f[3]; + int32_t f4 = f[4]; + int32_t f5 = f[5]; + int32_t f6 = f[6]; + int32_t f7 = f[7]; + int32_t f8 = f[8]; + int32_t f9 = f[9]; + + h[0] = f0; + h[1] = f1; + h[2] = f2; + h[3] = f3; + h[4] = f4; + h[5] = f5; + h[6] = f6; + h[7] = f7; + h[8] = f8; + h[9] = f9; +} + + + +/* + Ignores top bit of h. +*/ + +void fe_frombytes(fe h, const unsigned char *s) { + int64_t h0 = load_4(s); + int64_t h1 = load_3(s + 4) << 6; + int64_t h2 = load_3(s + 7) << 5; + int64_t h3 = load_3(s + 10) << 3; + int64_t h4 = load_3(s + 13) << 2; + int64_t h5 = load_4(s + 16); + int64_t h6 = load_3(s + 20) << 7; + int64_t h7 = load_3(s + 23) << 5; + int64_t h8 = load_3(s + 26) << 4; + int64_t h9 = (load_3(s + 29) & 8388607) << 2; + int64_t carry0; + int64_t carry1; + int64_t carry2; + int64_t carry3; + int64_t carry4; + int64_t carry5; + int64_t carry6; + int64_t carry7; + int64_t carry8; + int64_t carry9; + + carry9 = (h9 + (int64_t) (1 << 24)) >> 25; + h0 += carry9 * 19; + h9 -= carry9 << 25; + carry1 = (h1 + (int64_t) (1 << 24)) >> 25; + h2 += carry1; + h1 -= carry1 << 25; + carry3 = (h3 + (int64_t) (1 << 24)) >> 25; + h4 += carry3; + h3 -= carry3 << 25; + carry5 = (h5 + (int64_t) (1 << 24)) >> 25; + h6 += carry5; + h5 -= carry5 << 25; + carry7 = (h7 + (int64_t) (1 << 24)) >> 25; + h8 += carry7; + h7 -= carry7 << 25; + carry0 = (h0 + (int64_t) (1 << 25)) >> 26; + h1 += carry0; + h0 -= carry0 << 26; + carry2 = (h2 + (int64_t) (1 << 25)) >> 26; + h3 += carry2; + h2 -= carry2 << 26; + carry4 = (h4 + (int64_t) (1 << 25)) >> 26; + h5 += carry4; + h4 -= carry4 << 26; + carry6 = (h6 + (int64_t) (1 << 25)) >> 26; + h7 += carry6; + h6 -= carry6 << 26; + carry8 = (h8 + (int64_t) (1 << 25)) >> 26; + h9 += carry8; + h8 -= carry8 << 26; + + h[0] = (int32_t) h0; + h[1] = (int32_t) h1; + h[2] = (int32_t) h2; + h[3] = (int32_t) h3; + h[4] = (int32_t) h4; + h[5] = (int32_t) h5; + h[6] = (int32_t) h6; + h[7] = (int32_t) h7; + h[8] = (int32_t) h8; + h[9] = (int32_t) h9; +} + + + +void fe_invert(fe out, const fe z) { + fe t0; + fe t1; + fe t2; + fe t3; + int i; + + fe_sq(t0, z); + + for (i = 1; i < 1; ++i) { + fe_sq(t0, t0); + } + + fe_sq(t1, t0); + + for (i = 1; i < 2; ++i) { + fe_sq(t1, t1); + } + + fe_mul(t1, z, t1); + fe_mul(t0, t0, t1); + fe_sq(t2, t0); + + for (i = 1; i < 1; ++i) { + fe_sq(t2, t2); + } + + fe_mul(t1, t1, t2); + fe_sq(t2, t1); + + for (i = 1; i < 5; ++i) { + fe_sq(t2, t2); + } + + fe_mul(t1, t2, t1); + fe_sq(t2, t1); + + for (i = 1; i < 10; ++i) { + fe_sq(t2, t2); + } + + fe_mul(t2, t2, t1); + fe_sq(t3, t2); + + for (i = 1; i < 20; ++i) { + fe_sq(t3, t3); + } + + fe_mul(t2, t3, t2); + fe_sq(t2, t2); + + for (i = 1; i < 10; ++i) { + fe_sq(t2, t2); + } + + fe_mul(t1, t2, t1); + fe_sq(t2, t1); + + for (i = 1; i < 50; ++i) { + fe_sq(t2, t2); + } + + fe_mul(t2, t2, t1); + fe_sq(t3, t2); + + for (i = 1; i < 100; ++i) { + fe_sq(t3, t3); + } + + fe_mul(t2, t3, t2); + fe_sq(t2, t2); + + for (i = 1; i < 50; ++i) { + fe_sq(t2, t2); + } + + fe_mul(t1, t2, t1); + fe_sq(t1, t1); + + for (i = 1; i < 5; ++i) { + fe_sq(t1, t1); + } + + fe_mul(out, t1, t0); +} + + + +/* + return 1 if f is in {1,3,5,...,q-2} + return 0 if f is in {0,2,4,...,q-1} + + Preconditions: + |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. +*/ + +int fe_isnegative(const fe f) { + unsigned char s[32]; + + fe_tobytes(s, f); + + return s[0] & 1; +} + + + +/* + return 1 if f == 0 + return 0 if f != 0 + + Preconditions: + |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. +*/ + +int fe_isnonzero(const fe f) { + unsigned char s[32]; + unsigned char r; + + fe_tobytes(s, f); + + r = s[0]; + #define F(i) r |= s[i] + F(1); + F(2); + F(3); + F(4); + F(5); + F(6); + F(7); + F(8); + F(9); + F(10); + F(11); + F(12); + F(13); + F(14); + F(15); + F(16); + F(17); + F(18); + F(19); + F(20); + F(21); + F(22); + F(23); + F(24); + F(25); + F(26); + F(27); + F(28); + F(29); + F(30); + F(31); + #undef F + + return r != 0; +} + + + +/* + h = f * g + Can overlap h with f or g. + + Preconditions: + |f| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc. + |g| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc. + + Postconditions: + |h| bounded by 1.01*2^25,1.01*2^24,1.01*2^25,1.01*2^24,etc. + */ + + /* + Notes on implementation strategy: + + Using schoolbook multiplication. + Karatsuba would save a little in some cost models. + + Most multiplications by 2 and 19 are 32-bit precomputations; + cheaper than 64-bit postcomputations. + + There is one remaining multiplication by 19 in the carry chain; + one *19 precomputation can be merged into this, + but the resulting data flow is considerably less clean. + + There are 12 carries below. + 10 of them are 2-way parallelizable and vectorizable. + Can get away with 11 carries, but then data flow is much deeper. + + With tighter constraints on inputs can squeeze carries into int32. +*/ + +void fe_mul(fe h, const fe f, const fe g) { + int32_t f0 = f[0]; + int32_t f1 = f[1]; + int32_t f2 = f[2]; + int32_t f3 = f[3]; + int32_t f4 = f[4]; + int32_t f5 = f[5]; + int32_t f6 = f[6]; + int32_t f7 = f[7]; + int32_t f8 = f[8]; + int32_t f9 = f[9]; + int32_t g0 = g[0]; + int32_t g1 = g[1]; + int32_t g2 = g[2]; + int32_t g3 = g[3]; + int32_t g4 = g[4]; + int32_t g5 = g[5]; + int32_t g6 = g[6]; + int32_t g7 = g[7]; + int32_t g8 = g[8]; + int32_t g9 = g[9]; + int32_t g1_19 = 19 * g1; /* 1.959375*2^29 */ + int32_t g2_19 = 19 * g2; /* 1.959375*2^30; still ok */ + int32_t g3_19 = 19 * g3; + int32_t g4_19 = 19 * g4; + int32_t g5_19 = 19 * g5; + int32_t g6_19 = 19 * g6; + int32_t g7_19 = 19 * g7; + int32_t g8_19 = 19 * g8; + int32_t g9_19 = 19 * g9; + int32_t f1_2 = 2 * f1; + int32_t f3_2 = 2 * f3; + int32_t f5_2 = 2 * f5; + int32_t f7_2 = 2 * f7; + int32_t f9_2 = 2 * f9; + int64_t f0g0 = f0 * (int64_t) g0; + int64_t f0g1 = f0 * (int64_t) g1; + int64_t f0g2 = f0 * (int64_t) g2; + int64_t f0g3 = f0 * (int64_t) g3; + int64_t f0g4 = f0 * (int64_t) g4; + int64_t f0g5 = f0 * (int64_t) g5; + int64_t f0g6 = f0 * (int64_t) g6; + int64_t f0g7 = f0 * (int64_t) g7; + int64_t f0g8 = f0 * (int64_t) g8; + int64_t f0g9 = f0 * (int64_t) g9; + int64_t f1g0 = f1 * (int64_t) g0; + int64_t f1g1_2 = f1_2 * (int64_t) g1; + int64_t f1g2 = f1 * (int64_t) g2; + int64_t f1g3_2 = f1_2 * (int64_t) g3; + int64_t f1g4 = f1 * (int64_t) g4; + int64_t f1g5_2 = f1_2 * (int64_t) g5; + int64_t f1g6 = f1 * (int64_t) g6; + int64_t f1g7_2 = f1_2 * (int64_t) g7; + int64_t f1g8 = f1 * (int64_t) g8; + int64_t f1g9_38 = f1_2 * (int64_t) g9_19; + int64_t f2g0 = f2 * (int64_t) g0; + int64_t f2g1 = f2 * (int64_t) g1; + int64_t f2g2 = f2 * (int64_t) g2; + int64_t f2g3 = f2 * (int64_t) g3; + int64_t f2g4 = f2 * (int64_t) g4; + int64_t f2g5 = f2 * (int64_t) g5; + int64_t f2g6 = f2 * (int64_t) g6; + int64_t f2g7 = f2 * (int64_t) g7; + int64_t f2g8_19 = f2 * (int64_t) g8_19; + int64_t f2g9_19 = f2 * (int64_t) g9_19; + int64_t f3g0 = f3 * (int64_t) g0; + int64_t f3g1_2 = f3_2 * (int64_t) g1; + int64_t f3g2 = f3 * (int64_t) g2; + int64_t f3g3_2 = f3_2 * (int64_t) g3; + int64_t f3g4 = f3 * (int64_t) g4; + int64_t f3g5_2 = f3_2 * (int64_t) g5; + int64_t f3g6 = f3 * (int64_t) g6; + int64_t f3g7_38 = f3_2 * (int64_t) g7_19; + int64_t f3g8_19 = f3 * (int64_t) g8_19; + int64_t f3g9_38 = f3_2 * (int64_t) g9_19; + int64_t f4g0 = f4 * (int64_t) g0; + int64_t f4g1 = f4 * (int64_t) g1; + int64_t f4g2 = f4 * (int64_t) g2; + int64_t f4g3 = f4 * (int64_t) g3; + int64_t f4g4 = f4 * (int64_t) g4; + int64_t f4g5 = f4 * (int64_t) g5; + int64_t f4g6_19 = f4 * (int64_t) g6_19; + int64_t f4g7_19 = f4 * (int64_t) g7_19; + int64_t f4g8_19 = f4 * (int64_t) g8_19; + int64_t f4g9_19 = f4 * (int64_t) g9_19; + int64_t f5g0 = f5 * (int64_t) g0; + int64_t f5g1_2 = f5_2 * (int64_t) g1; + int64_t f5g2 = f5 * (int64_t) g2; + int64_t f5g3_2 = f5_2 * (int64_t) g3; + int64_t f5g4 = f5 * (int64_t) g4; + int64_t f5g5_38 = f5_2 * (int64_t) g5_19; + int64_t f5g6_19 = f5 * (int64_t) g6_19; + int64_t f5g7_38 = f5_2 * (int64_t) g7_19; + int64_t f5g8_19 = f5 * (int64_t) g8_19; + int64_t f5g9_38 = f5_2 * (int64_t) g9_19; + int64_t f6g0 = f6 * (int64_t) g0; + int64_t f6g1 = f6 * (int64_t) g1; + int64_t f6g2 = f6 * (int64_t) g2; + int64_t f6g3 = f6 * (int64_t) g3; + int64_t f6g4_19 = f6 * (int64_t) g4_19; + int64_t f6g5_19 = f6 * (int64_t) g5_19; + int64_t f6g6_19 = f6 * (int64_t) g6_19; + int64_t f6g7_19 = f6 * (int64_t) g7_19; + int64_t f6g8_19 = f6 * (int64_t) g8_19; + int64_t f6g9_19 = f6 * (int64_t) g9_19; + int64_t f7g0 = f7 * (int64_t) g0; + int64_t f7g1_2 = f7_2 * (int64_t) g1; + int64_t f7g2 = f7 * (int64_t) g2; + int64_t f7g3_38 = f7_2 * (int64_t) g3_19; + int64_t f7g4_19 = f7 * (int64_t) g4_19; + int64_t f7g5_38 = f7_2 * (int64_t) g5_19; + int64_t f7g6_19 = f7 * (int64_t) g6_19; + int64_t f7g7_38 = f7_2 * (int64_t) g7_19; + int64_t f7g8_19 = f7 * (int64_t) g8_19; + int64_t f7g9_38 = f7_2 * (int64_t) g9_19; + int64_t f8g0 = f8 * (int64_t) g0; + int64_t f8g1 = f8 * (int64_t) g1; + int64_t f8g2_19 = f8 * (int64_t) g2_19; + int64_t f8g3_19 = f8 * (int64_t) g3_19; + int64_t f8g4_19 = f8 * (int64_t) g4_19; + int64_t f8g5_19 = f8 * (int64_t) g5_19; + int64_t f8g6_19 = f8 * (int64_t) g6_19; + int64_t f8g7_19 = f8 * (int64_t) g7_19; + int64_t f8g8_19 = f8 * (int64_t) g8_19; + int64_t f8g9_19 = f8 * (int64_t) g9_19; + int64_t f9g0 = f9 * (int64_t) g0; + int64_t f9g1_38 = f9_2 * (int64_t) g1_19; + int64_t f9g2_19 = f9 * (int64_t) g2_19; + int64_t f9g3_38 = f9_2 * (int64_t) g3_19; + int64_t f9g4_19 = f9 * (int64_t) g4_19; + int64_t f9g5_38 = f9_2 * (int64_t) g5_19; + int64_t f9g6_19 = f9 * (int64_t) g6_19; + int64_t f9g7_38 = f9_2 * (int64_t) g7_19; + int64_t f9g8_19 = f9 * (int64_t) g8_19; + int64_t f9g9_38 = f9_2 * (int64_t) g9_19; + int64_t h0 = f0g0 + f1g9_38 + f2g8_19 + f3g7_38 + f4g6_19 + f5g5_38 + f6g4_19 + f7g3_38 + f8g2_19 + f9g1_38; + int64_t h1 = f0g1 + f1g0 + f2g9_19 + f3g8_19 + f4g7_19 + f5g6_19 + f6g5_19 + f7g4_19 + f8g3_19 + f9g2_19; + int64_t h2 = f0g2 + f1g1_2 + f2g0 + f3g9_38 + f4g8_19 + f5g7_38 + f6g6_19 + f7g5_38 + f8g4_19 + f9g3_38; + int64_t h3 = f0g3 + f1g2 + f2g1 + f3g0 + f4g9_19 + f5g8_19 + f6g7_19 + f7g6_19 + f8g5_19 + f9g4_19; + int64_t h4 = f0g4 + f1g3_2 + f2g2 + f3g1_2 + f4g0 + f5g9_38 + f6g8_19 + f7g7_38 + f8g6_19 + f9g5_38; + int64_t h5 = f0g5 + f1g4 + f2g3 + f3g2 + f4g1 + f5g0 + f6g9_19 + f7g8_19 + f8g7_19 + f9g6_19; + int64_t h6 = f0g6 + f1g5_2 + f2g4 + f3g3_2 + f4g2 + f5g1_2 + f6g0 + f7g9_38 + f8g8_19 + f9g7_38; + int64_t h7 = f0g7 + f1g6 + f2g5 + f3g4 + f4g3 + f5g2 + f6g1 + f7g0 + f8g9_19 + f9g8_19; + int64_t h8 = f0g8 + f1g7_2 + f2g6 + f3g5_2 + f4g4 + f5g3_2 + f6g2 + f7g1_2 + f8g0 + f9g9_38; + int64_t h9 = f0g9 + f1g8 + f2g7 + f3g6 + f4g5 + f5g4 + f6g3 + f7g2 + f8g1 + f9g0 ; + int64_t carry0; + int64_t carry1; + int64_t carry2; + int64_t carry3; + int64_t carry4; + int64_t carry5; + int64_t carry6; + int64_t carry7; + int64_t carry8; + int64_t carry9; + + carry0 = (h0 + (int64_t) (1 << 25)) >> 26; + h1 += carry0; + h0 -= carry0 << 26; + carry4 = (h4 + (int64_t) (1 << 25)) >> 26; + h5 += carry4; + h4 -= carry4 << 26; + + carry1 = (h1 + (int64_t) (1 << 24)) >> 25; + h2 += carry1; + h1 -= carry1 << 25; + carry5 = (h5 + (int64_t) (1 << 24)) >> 25; + h6 += carry5; + h5 -= carry5 << 25; + + carry2 = (h2 + (int64_t) (1 << 25)) >> 26; + h3 += carry2; + h2 -= carry2 << 26; + carry6 = (h6 + (int64_t) (1 << 25)) >> 26; + h7 += carry6; + h6 -= carry6 << 26; + + carry3 = (h3 + (int64_t) (1 << 24)) >> 25; + h4 += carry3; + h3 -= carry3 << 25; + carry7 = (h7 + (int64_t) (1 << 24)) >> 25; + h8 += carry7; + h7 -= carry7 << 25; + + carry4 = (h4 + (int64_t) (1 << 25)) >> 26; + h5 += carry4; + h4 -= carry4 << 26; + carry8 = (h8 + (int64_t) (1 << 25)) >> 26; + h9 += carry8; + h8 -= carry8 << 26; + + carry9 = (h9 + (int64_t) (1 << 24)) >> 25; + h0 += carry9 * 19; + h9 -= carry9 << 25; + + carry0 = (h0 + (int64_t) (1 << 25)) >> 26; + h1 += carry0; + h0 -= carry0 << 26; + + h[0] = (int32_t) h0; + h[1] = (int32_t) h1; + h[2] = (int32_t) h2; + h[3] = (int32_t) h3; + h[4] = (int32_t) h4; + h[5] = (int32_t) h5; + h[6] = (int32_t) h6; + h[7] = (int32_t) h7; + h[8] = (int32_t) h8; + h[9] = (int32_t) h9; +} + + +/* +h = f * 121666 +Can overlap h with f. + +Preconditions: + |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. + +Postconditions: + |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. +*/ + +void fe_mul121666(fe h, fe f) { + int32_t f0 = f[0]; + int32_t f1 = f[1]; + int32_t f2 = f[2]; + int32_t f3 = f[3]; + int32_t f4 = f[4]; + int32_t f5 = f[5]; + int32_t f6 = f[6]; + int32_t f7 = f[7]; + int32_t f8 = f[8]; + int32_t f9 = f[9]; + int64_t h0 = f0 * (int64_t) 121666; + int64_t h1 = f1 * (int64_t) 121666; + int64_t h2 = f2 * (int64_t) 121666; + int64_t h3 = f3 * (int64_t) 121666; + int64_t h4 = f4 * (int64_t) 121666; + int64_t h5 = f5 * (int64_t) 121666; + int64_t h6 = f6 * (int64_t) 121666; + int64_t h7 = f7 * (int64_t) 121666; + int64_t h8 = f8 * (int64_t) 121666; + int64_t h9 = f9 * (int64_t) 121666; + int64_t carry0; + int64_t carry1; + int64_t carry2; + int64_t carry3; + int64_t carry4; + int64_t carry5; + int64_t carry6; + int64_t carry7; + int64_t carry8; + int64_t carry9; + + carry9 = (h9 + (int64_t) (1<<24)) >> 25; h0 += carry9 * 19; h9 -= carry9 << 25; + carry1 = (h1 + (int64_t) (1<<24)) >> 25; h2 += carry1; h1 -= carry1 << 25; + carry3 = (h3 + (int64_t) (1<<24)) >> 25; h4 += carry3; h3 -= carry3 << 25; + carry5 = (h5 + (int64_t) (1<<24)) >> 25; h6 += carry5; h5 -= carry5 << 25; + carry7 = (h7 + (int64_t) (1<<24)) >> 25; h8 += carry7; h7 -= carry7 << 25; + + carry0 = (h0 + (int64_t) (1<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26; + carry2 = (h2 + (int64_t) (1<<25)) >> 26; h3 += carry2; h2 -= carry2 << 26; + carry4 = (h4 + (int64_t) (1<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26; + carry6 = (h6 + (int64_t) (1<<25)) >> 26; h7 += carry6; h6 -= carry6 << 26; + carry8 = (h8 + (int64_t) (1<<25)) >> 26; h9 += carry8; h8 -= carry8 << 26; + + h[0] = h0; + h[1] = h1; + h[2] = h2; + h[3] = h3; + h[4] = h4; + h[5] = h5; + h[6] = h6; + h[7] = h7; + h[8] = h8; + h[9] = h9; +} + + +/* +h = -f + +Preconditions: + |f| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. + +Postconditions: + |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. +*/ + +void fe_neg(fe h, const fe f) { + int32_t f0 = f[0]; + int32_t f1 = f[1]; + int32_t f2 = f[2]; + int32_t f3 = f[3]; + int32_t f4 = f[4]; + int32_t f5 = f[5]; + int32_t f6 = f[6]; + int32_t f7 = f[7]; + int32_t f8 = f[8]; + int32_t f9 = f[9]; + int32_t h0 = -f0; + int32_t h1 = -f1; + int32_t h2 = -f2; + int32_t h3 = -f3; + int32_t h4 = -f4; + int32_t h5 = -f5; + int32_t h6 = -f6; + int32_t h7 = -f7; + int32_t h8 = -f8; + int32_t h9 = -f9; + + h[0] = h0; + h[1] = h1; + h[2] = h2; + h[3] = h3; + h[4] = h4; + h[5] = h5; + h[6] = h6; + h[7] = h7; + h[8] = h8; + h[9] = h9; +} + + +void fe_pow22523(fe out, const fe z) { + fe t0; + fe t1; + fe t2; + int i; + fe_sq(t0, z); + + for (i = 1; i < 1; ++i) { + fe_sq(t0, t0); + } + + fe_sq(t1, t0); + + for (i = 1; i < 2; ++i) { + fe_sq(t1, t1); + } + + fe_mul(t1, z, t1); + fe_mul(t0, t0, t1); + fe_sq(t0, t0); + + for (i = 1; i < 1; ++i) { + fe_sq(t0, t0); + } + + fe_mul(t0, t1, t0); + fe_sq(t1, t0); + + for (i = 1; i < 5; ++i) { + fe_sq(t1, t1); + } + + fe_mul(t0, t1, t0); + fe_sq(t1, t0); + + for (i = 1; i < 10; ++i) { + fe_sq(t1, t1); + } + + fe_mul(t1, t1, t0); + fe_sq(t2, t1); + + for (i = 1; i < 20; ++i) { + fe_sq(t2, t2); + } + + fe_mul(t1, t2, t1); + fe_sq(t1, t1); + + for (i = 1; i < 10; ++i) { + fe_sq(t1, t1); + } + + fe_mul(t0, t1, t0); + fe_sq(t1, t0); + + for (i = 1; i < 50; ++i) { + fe_sq(t1, t1); + } + + fe_mul(t1, t1, t0); + fe_sq(t2, t1); + + for (i = 1; i < 100; ++i) { + fe_sq(t2, t2); + } + + fe_mul(t1, t2, t1); + fe_sq(t1, t1); + + for (i = 1; i < 50; ++i) { + fe_sq(t1, t1); + } + + fe_mul(t0, t1, t0); + fe_sq(t0, t0); + + for (i = 1; i < 2; ++i) { + fe_sq(t0, t0); + } + + fe_mul(out, t0, z); + return; +} + + +/* +h = f * f +Can overlap h with f. + +Preconditions: + |f| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc. + +Postconditions: + |h| bounded by 1.01*2^25,1.01*2^24,1.01*2^25,1.01*2^24,etc. +*/ + +/* +See fe_mul.c for discussion of implementation strategy. +*/ + +void fe_sq(fe h, const fe f) { + int32_t f0 = f[0]; + int32_t f1 = f[1]; + int32_t f2 = f[2]; + int32_t f3 = f[3]; + int32_t f4 = f[4]; + int32_t f5 = f[5]; + int32_t f6 = f[6]; + int32_t f7 = f[7]; + int32_t f8 = f[8]; + int32_t f9 = f[9]; + int32_t f0_2 = 2 * f0; + int32_t f1_2 = 2 * f1; + int32_t f2_2 = 2 * f2; + int32_t f3_2 = 2 * f3; + int32_t f4_2 = 2 * f4; + int32_t f5_2 = 2 * f5; + int32_t f6_2 = 2 * f6; + int32_t f7_2 = 2 * f7; + int32_t f5_38 = 38 * f5; /* 1.959375*2^30 */ + int32_t f6_19 = 19 * f6; /* 1.959375*2^30 */ + int32_t f7_38 = 38 * f7; /* 1.959375*2^30 */ + int32_t f8_19 = 19 * f8; /* 1.959375*2^30 */ + int32_t f9_38 = 38 * f9; /* 1.959375*2^30 */ + int64_t f0f0 = f0 * (int64_t) f0; + int64_t f0f1_2 = f0_2 * (int64_t) f1; + int64_t f0f2_2 = f0_2 * (int64_t) f2; + int64_t f0f3_2 = f0_2 * (int64_t) f3; + int64_t f0f4_2 = f0_2 * (int64_t) f4; + int64_t f0f5_2 = f0_2 * (int64_t) f5; + int64_t f0f6_2 = f0_2 * (int64_t) f6; + int64_t f0f7_2 = f0_2 * (int64_t) f7; + int64_t f0f8_2 = f0_2 * (int64_t) f8; + int64_t f0f9_2 = f0_2 * (int64_t) f9; + int64_t f1f1_2 = f1_2 * (int64_t) f1; + int64_t f1f2_2 = f1_2 * (int64_t) f2; + int64_t f1f3_4 = f1_2 * (int64_t) f3_2; + int64_t f1f4_2 = f1_2 * (int64_t) f4; + int64_t f1f5_4 = f1_2 * (int64_t) f5_2; + int64_t f1f6_2 = f1_2 * (int64_t) f6; + int64_t f1f7_4 = f1_2 * (int64_t) f7_2; + int64_t f1f8_2 = f1_2 * (int64_t) f8; + int64_t f1f9_76 = f1_2 * (int64_t) f9_38; + int64_t f2f2 = f2 * (int64_t) f2; + int64_t f2f3_2 = f2_2 * (int64_t) f3; + int64_t f2f4_2 = f2_2 * (int64_t) f4; + int64_t f2f5_2 = f2_2 * (int64_t) f5; + int64_t f2f6_2 = f2_2 * (int64_t) f6; + int64_t f2f7_2 = f2_2 * (int64_t) f7; + int64_t f2f8_38 = f2_2 * (int64_t) f8_19; + int64_t f2f9_38 = f2 * (int64_t) f9_38; + int64_t f3f3_2 = f3_2 * (int64_t) f3; + int64_t f3f4_2 = f3_2 * (int64_t) f4; + int64_t f3f5_4 = f3_2 * (int64_t) f5_2; + int64_t f3f6_2 = f3_2 * (int64_t) f6; + int64_t f3f7_76 = f3_2 * (int64_t) f7_38; + int64_t f3f8_38 = f3_2 * (int64_t) f8_19; + int64_t f3f9_76 = f3_2 * (int64_t) f9_38; + int64_t f4f4 = f4 * (int64_t) f4; + int64_t f4f5_2 = f4_2 * (int64_t) f5; + int64_t f4f6_38 = f4_2 * (int64_t) f6_19; + int64_t f4f7_38 = f4 * (int64_t) f7_38; + int64_t f4f8_38 = f4_2 * (int64_t) f8_19; + int64_t f4f9_38 = f4 * (int64_t) f9_38; + int64_t f5f5_38 = f5 * (int64_t) f5_38; + int64_t f5f6_38 = f5_2 * (int64_t) f6_19; + int64_t f5f7_76 = f5_2 * (int64_t) f7_38; + int64_t f5f8_38 = f5_2 * (int64_t) f8_19; + int64_t f5f9_76 = f5_2 * (int64_t) f9_38; + int64_t f6f6_19 = f6 * (int64_t) f6_19; + int64_t f6f7_38 = f6 * (int64_t) f7_38; + int64_t f6f8_38 = f6_2 * (int64_t) f8_19; + int64_t f6f9_38 = f6 * (int64_t) f9_38; + int64_t f7f7_38 = f7 * (int64_t) f7_38; + int64_t f7f8_38 = f7_2 * (int64_t) f8_19; + int64_t f7f9_76 = f7_2 * (int64_t) f9_38; + int64_t f8f8_19 = f8 * (int64_t) f8_19; + int64_t f8f9_38 = f8 * (int64_t) f9_38; + int64_t f9f9_38 = f9 * (int64_t) f9_38; + int64_t h0 = f0f0 + f1f9_76 + f2f8_38 + f3f7_76 + f4f6_38 + f5f5_38; + int64_t h1 = f0f1_2 + f2f9_38 + f3f8_38 + f4f7_38 + f5f6_38; + int64_t h2 = f0f2_2 + f1f1_2 + f3f9_76 + f4f8_38 + f5f7_76 + f6f6_19; + int64_t h3 = f0f3_2 + f1f2_2 + f4f9_38 + f5f8_38 + f6f7_38; + int64_t h4 = f0f4_2 + f1f3_4 + f2f2 + f5f9_76 + f6f8_38 + f7f7_38; + int64_t h5 = f0f5_2 + f1f4_2 + f2f3_2 + f6f9_38 + f7f8_38; + int64_t h6 = f0f6_2 + f1f5_4 + f2f4_2 + f3f3_2 + f7f9_76 + f8f8_19; + int64_t h7 = f0f7_2 + f1f6_2 + f2f5_2 + f3f4_2 + f8f9_38; + int64_t h8 = f0f8_2 + f1f7_4 + f2f6_2 + f3f5_4 + f4f4 + f9f9_38; + int64_t h9 = f0f9_2 + f1f8_2 + f2f7_2 + f3f6_2 + f4f5_2; + int64_t carry0; + int64_t carry1; + int64_t carry2; + int64_t carry3; + int64_t carry4; + int64_t carry5; + int64_t carry6; + int64_t carry7; + int64_t carry8; + int64_t carry9; + carry0 = (h0 + (int64_t) (1 << 25)) >> 26; + h1 += carry0; + h0 -= carry0 << 26; + carry4 = (h4 + (int64_t) (1 << 25)) >> 26; + h5 += carry4; + h4 -= carry4 << 26; + carry1 = (h1 + (int64_t) (1 << 24)) >> 25; + h2 += carry1; + h1 -= carry1 << 25; + carry5 = (h5 + (int64_t) (1 << 24)) >> 25; + h6 += carry5; + h5 -= carry5 << 25; + carry2 = (h2 + (int64_t) (1 << 25)) >> 26; + h3 += carry2; + h2 -= carry2 << 26; + carry6 = (h6 + (int64_t) (1 << 25)) >> 26; + h7 += carry6; + h6 -= carry6 << 26; + carry3 = (h3 + (int64_t) (1 << 24)) >> 25; + h4 += carry3; + h3 -= carry3 << 25; + carry7 = (h7 + (int64_t) (1 << 24)) >> 25; + h8 += carry7; + h7 -= carry7 << 25; + carry4 = (h4 + (int64_t) (1 << 25)) >> 26; + h5 += carry4; + h4 -= carry4 << 26; + carry8 = (h8 + (int64_t) (1 << 25)) >> 26; + h9 += carry8; + h8 -= carry8 << 26; + carry9 = (h9 + (int64_t) (1 << 24)) >> 25; + h0 += carry9 * 19; + h9 -= carry9 << 25; + carry0 = (h0 + (int64_t) (1 << 25)) >> 26; + h1 += carry0; + h0 -= carry0 << 26; + h[0] = (int32_t) h0; + h[1] = (int32_t) h1; + h[2] = (int32_t) h2; + h[3] = (int32_t) h3; + h[4] = (int32_t) h4; + h[5] = (int32_t) h5; + h[6] = (int32_t) h6; + h[7] = (int32_t) h7; + h[8] = (int32_t) h8; + h[9] = (int32_t) h9; +} + + +/* +h = 2 * f * f +Can overlap h with f. + +Preconditions: + |f| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc. + +Postconditions: + |h| bounded by 1.01*2^25,1.01*2^24,1.01*2^25,1.01*2^24,etc. +*/ + +/* +See fe_mul.c for discussion of implementation strategy. +*/ + +void fe_sq2(fe h, const fe f) { + int32_t f0 = f[0]; + int32_t f1 = f[1]; + int32_t f2 = f[2]; + int32_t f3 = f[3]; + int32_t f4 = f[4]; + int32_t f5 = f[5]; + int32_t f6 = f[6]; + int32_t f7 = f[7]; + int32_t f8 = f[8]; + int32_t f9 = f[9]; + int32_t f0_2 = 2 * f0; + int32_t f1_2 = 2 * f1; + int32_t f2_2 = 2 * f2; + int32_t f3_2 = 2 * f3; + int32_t f4_2 = 2 * f4; + int32_t f5_2 = 2 * f5; + int32_t f6_2 = 2 * f6; + int32_t f7_2 = 2 * f7; + int32_t f5_38 = 38 * f5; /* 1.959375*2^30 */ + int32_t f6_19 = 19 * f6; /* 1.959375*2^30 */ + int32_t f7_38 = 38 * f7; /* 1.959375*2^30 */ + int32_t f8_19 = 19 * f8; /* 1.959375*2^30 */ + int32_t f9_38 = 38 * f9; /* 1.959375*2^30 */ + int64_t f0f0 = f0 * (int64_t) f0; + int64_t f0f1_2 = f0_2 * (int64_t) f1; + int64_t f0f2_2 = f0_2 * (int64_t) f2; + int64_t f0f3_2 = f0_2 * (int64_t) f3; + int64_t f0f4_2 = f0_2 * (int64_t) f4; + int64_t f0f5_2 = f0_2 * (int64_t) f5; + int64_t f0f6_2 = f0_2 * (int64_t) f6; + int64_t f0f7_2 = f0_2 * (int64_t) f7; + int64_t f0f8_2 = f0_2 * (int64_t) f8; + int64_t f0f9_2 = f0_2 * (int64_t) f9; + int64_t f1f1_2 = f1_2 * (int64_t) f1; + int64_t f1f2_2 = f1_2 * (int64_t) f2; + int64_t f1f3_4 = f1_2 * (int64_t) f3_2; + int64_t f1f4_2 = f1_2 * (int64_t) f4; + int64_t f1f5_4 = f1_2 * (int64_t) f5_2; + int64_t f1f6_2 = f1_2 * (int64_t) f6; + int64_t f1f7_4 = f1_2 * (int64_t) f7_2; + int64_t f1f8_2 = f1_2 * (int64_t) f8; + int64_t f1f9_76 = f1_2 * (int64_t) f9_38; + int64_t f2f2 = f2 * (int64_t) f2; + int64_t f2f3_2 = f2_2 * (int64_t) f3; + int64_t f2f4_2 = f2_2 * (int64_t) f4; + int64_t f2f5_2 = f2_2 * (int64_t) f5; + int64_t f2f6_2 = f2_2 * (int64_t) f6; + int64_t f2f7_2 = f2_2 * (int64_t) f7; + int64_t f2f8_38 = f2_2 * (int64_t) f8_19; + int64_t f2f9_38 = f2 * (int64_t) f9_38; + int64_t f3f3_2 = f3_2 * (int64_t) f3; + int64_t f3f4_2 = f3_2 * (int64_t) f4; + int64_t f3f5_4 = f3_2 * (int64_t) f5_2; + int64_t f3f6_2 = f3_2 * (int64_t) f6; + int64_t f3f7_76 = f3_2 * (int64_t) f7_38; + int64_t f3f8_38 = f3_2 * (int64_t) f8_19; + int64_t f3f9_76 = f3_2 * (int64_t) f9_38; + int64_t f4f4 = f4 * (int64_t) f4; + int64_t f4f5_2 = f4_2 * (int64_t) f5; + int64_t f4f6_38 = f4_2 * (int64_t) f6_19; + int64_t f4f7_38 = f4 * (int64_t) f7_38; + int64_t f4f8_38 = f4_2 * (int64_t) f8_19; + int64_t f4f9_38 = f4 * (int64_t) f9_38; + int64_t f5f5_38 = f5 * (int64_t) f5_38; + int64_t f5f6_38 = f5_2 * (int64_t) f6_19; + int64_t f5f7_76 = f5_2 * (int64_t) f7_38; + int64_t f5f8_38 = f5_2 * (int64_t) f8_19; + int64_t f5f9_76 = f5_2 * (int64_t) f9_38; + int64_t f6f6_19 = f6 * (int64_t) f6_19; + int64_t f6f7_38 = f6 * (int64_t) f7_38; + int64_t f6f8_38 = f6_2 * (int64_t) f8_19; + int64_t f6f9_38 = f6 * (int64_t) f9_38; + int64_t f7f7_38 = f7 * (int64_t) f7_38; + int64_t f7f8_38 = f7_2 * (int64_t) f8_19; + int64_t f7f9_76 = f7_2 * (int64_t) f9_38; + int64_t f8f8_19 = f8 * (int64_t) f8_19; + int64_t f8f9_38 = f8 * (int64_t) f9_38; + int64_t f9f9_38 = f9 * (int64_t) f9_38; + int64_t h0 = f0f0 + f1f9_76 + f2f8_38 + f3f7_76 + f4f6_38 + f5f5_38; + int64_t h1 = f0f1_2 + f2f9_38 + f3f8_38 + f4f7_38 + f5f6_38; + int64_t h2 = f0f2_2 + f1f1_2 + f3f9_76 + f4f8_38 + f5f7_76 + f6f6_19; + int64_t h3 = f0f3_2 + f1f2_2 + f4f9_38 + f5f8_38 + f6f7_38; + int64_t h4 = f0f4_2 + f1f3_4 + f2f2 + f5f9_76 + f6f8_38 + f7f7_38; + int64_t h5 = f0f5_2 + f1f4_2 + f2f3_2 + f6f9_38 + f7f8_38; + int64_t h6 = f0f6_2 + f1f5_4 + f2f4_2 + f3f3_2 + f7f9_76 + f8f8_19; + int64_t h7 = f0f7_2 + f1f6_2 + f2f5_2 + f3f4_2 + f8f9_38; + int64_t h8 = f0f8_2 + f1f7_4 + f2f6_2 + f3f5_4 + f4f4 + f9f9_38; + int64_t h9 = f0f9_2 + f1f8_2 + f2f7_2 + f3f6_2 + f4f5_2; + int64_t carry0; + int64_t carry1; + int64_t carry2; + int64_t carry3; + int64_t carry4; + int64_t carry5; + int64_t carry6; + int64_t carry7; + int64_t carry8; + int64_t carry9; + h0 += h0; + h1 += h1; + h2 += h2; + h3 += h3; + h4 += h4; + h5 += h5; + h6 += h6; + h7 += h7; + h8 += h8; + h9 += h9; + carry0 = (h0 + (int64_t) (1 << 25)) >> 26; + h1 += carry0; + h0 -= carry0 << 26; + carry4 = (h4 + (int64_t) (1 << 25)) >> 26; + h5 += carry4; + h4 -= carry4 << 26; + carry1 = (h1 + (int64_t) (1 << 24)) >> 25; + h2 += carry1; + h1 -= carry1 << 25; + carry5 = (h5 + (int64_t) (1 << 24)) >> 25; + h6 += carry5; + h5 -= carry5 << 25; + carry2 = (h2 + (int64_t) (1 << 25)) >> 26; + h3 += carry2; + h2 -= carry2 << 26; + carry6 = (h6 + (int64_t) (1 << 25)) >> 26; + h7 += carry6; + h6 -= carry6 << 26; + carry3 = (h3 + (int64_t) (1 << 24)) >> 25; + h4 += carry3; + h3 -= carry3 << 25; + carry7 = (h7 + (int64_t) (1 << 24)) >> 25; + h8 += carry7; + h7 -= carry7 << 25; + carry4 = (h4 + (int64_t) (1 << 25)) >> 26; + h5 += carry4; + h4 -= carry4 << 26; + carry8 = (h8 + (int64_t) (1 << 25)) >> 26; + h9 += carry8; + h8 -= carry8 << 26; + carry9 = (h9 + (int64_t) (1 << 24)) >> 25; + h0 += carry9 * 19; + h9 -= carry9 << 25; + carry0 = (h0 + (int64_t) (1 << 25)) >> 26; + h1 += carry0; + h0 -= carry0 << 26; + h[0] = (int32_t) h0; + h[1] = (int32_t) h1; + h[2] = (int32_t) h2; + h[3] = (int32_t) h3; + h[4] = (int32_t) h4; + h[5] = (int32_t) h5; + h[6] = (int32_t) h6; + h[7] = (int32_t) h7; + h[8] = (int32_t) h8; + h[9] = (int32_t) h9; +} + + +/* +h = f - g +Can overlap h with f or g. + +Preconditions: + |f| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. + |g| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. + +Postconditions: + |h| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. +*/ + +void fe_sub(fe h, const fe f, const fe g) { + int32_t f0 = f[0]; + int32_t f1 = f[1]; + int32_t f2 = f[2]; + int32_t f3 = f[3]; + int32_t f4 = f[4]; + int32_t f5 = f[5]; + int32_t f6 = f[6]; + int32_t f7 = f[7]; + int32_t f8 = f[8]; + int32_t f9 = f[9]; + int32_t g0 = g[0]; + int32_t g1 = g[1]; + int32_t g2 = g[2]; + int32_t g3 = g[3]; + int32_t g4 = g[4]; + int32_t g5 = g[5]; + int32_t g6 = g[6]; + int32_t g7 = g[7]; + int32_t g8 = g[8]; + int32_t g9 = g[9]; + int32_t h0 = f0 - g0; + int32_t h1 = f1 - g1; + int32_t h2 = f2 - g2; + int32_t h3 = f3 - g3; + int32_t h4 = f4 - g4; + int32_t h5 = f5 - g5; + int32_t h6 = f6 - g6; + int32_t h7 = f7 - g7; + int32_t h8 = f8 - g8; + int32_t h9 = f9 - g9; + + h[0] = h0; + h[1] = h1; + h[2] = h2; + h[3] = h3; + h[4] = h4; + h[5] = h5; + h[6] = h6; + h[7] = h7; + h[8] = h8; + h[9] = h9; +} + + + +/* +Preconditions: + |h| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. + +Write p=2^255-19; q=floor(h/p). +Basic claim: q = floor(2^(-255)(h + 19 2^(-25)h9 + 2^(-1))). + +Proof: + Have |h|<=p so |q|<=1 so |19^2 2^(-255) q|<1/4. + Also have |h-2^230 h9|<2^231 so |19 2^(-255)(h-2^230 h9)|<1/4. + + Write y=2^(-1)-19^2 2^(-255)q-19 2^(-255)(h-2^230 h9). + Then 0> 25; + q = (h0 + q) >> 26; + q = (h1 + q) >> 25; + q = (h2 + q) >> 26; + q = (h3 + q) >> 25; + q = (h4 + q) >> 26; + q = (h5 + q) >> 25; + q = (h6 + q) >> 26; + q = (h7 + q) >> 25; + q = (h8 + q) >> 26; + q = (h9 + q) >> 25; + /* Goal: Output h-(2^255-19)q, which is between 0 and 2^255-20. */ + h0 += 19 * q; + /* Goal: Output h-2^255 q, which is between 0 and 2^255-20. */ + carry0 = h0 >> 26; + h1 += carry0; + h0 -= carry0 << 26; + carry1 = h1 >> 25; + h2 += carry1; + h1 -= carry1 << 25; + carry2 = h2 >> 26; + h3 += carry2; + h2 -= carry2 << 26; + carry3 = h3 >> 25; + h4 += carry3; + h3 -= carry3 << 25; + carry4 = h4 >> 26; + h5 += carry4; + h4 -= carry4 << 26; + carry5 = h5 >> 25; + h6 += carry5; + h5 -= carry5 << 25; + carry6 = h6 >> 26; + h7 += carry6; + h6 -= carry6 << 26; + carry7 = h7 >> 25; + h8 += carry7; + h7 -= carry7 << 25; + carry8 = h8 >> 26; + h9 += carry8; + h8 -= carry8 << 26; + carry9 = h9 >> 25; + h9 -= carry9 << 25; + + /* h10 = carry9 */ + /* + Goal: Output h0+...+2^255 h10-2^255 q, which is between 0 and 2^255-20. + Have h0+...+2^230 h9 between 0 and 2^255-1; + evidently 2^255 h10-2^255 q = 0. + Goal: Output h0+...+2^230 h9. + */ + s[0] = (unsigned char) (h0 >> 0); + s[1] = (unsigned char) (h0 >> 8); + s[2] = (unsigned char) (h0 >> 16); + s[3] = (unsigned char) ((h0 >> 24) | (h1 << 2)); + s[4] = (unsigned char) (h1 >> 6); + s[5] = (unsigned char) (h1 >> 14); + s[6] = (unsigned char) ((h1 >> 22) | (h2 << 3)); + s[7] = (unsigned char) (h2 >> 5); + s[8] = (unsigned char) (h2 >> 13); + s[9] = (unsigned char) ((h2 >> 21) | (h3 << 5)); + s[10] = (unsigned char) (h3 >> 3); + s[11] = (unsigned char) (h3 >> 11); + s[12] = (unsigned char) ((h3 >> 19) | (h4 << 6)); + s[13] = (unsigned char) (h4 >> 2); + s[14] = (unsigned char) (h4 >> 10); + s[15] = (unsigned char) (h4 >> 18); + s[16] = (unsigned char) (h5 >> 0); + s[17] = (unsigned char) (h5 >> 8); + s[18] = (unsigned char) (h5 >> 16); + s[19] = (unsigned char) ((h5 >> 24) | (h6 << 1)); + s[20] = (unsigned char) (h6 >> 7); + s[21] = (unsigned char) (h6 >> 15); + s[22] = (unsigned char) ((h6 >> 23) | (h7 << 3)); + s[23] = (unsigned char) (h7 >> 5); + s[24] = (unsigned char) (h7 >> 13); + s[25] = (unsigned char) ((h7 >> 21) | (h8 << 4)); + s[26] = (unsigned char) (h8 >> 4); + s[27] = (unsigned char) (h8 >> 12); + s[28] = (unsigned char) ((h8 >> 20) | (h9 << 6)); + s[29] = (unsigned char) (h9 >> 2); + s[30] = (unsigned char) (h9 >> 10); + s[31] = (unsigned char) (h9 >> 18); +} diff --git a/src/ed25519/fe.h b/src/ed25519/fe.h new file mode 100644 index 0000000..b4b62d2 --- /dev/null +++ b/src/ed25519/fe.h @@ -0,0 +1,41 @@ +#ifndef FE_H +#define FE_H + +#include "fixedint.h" + + +/* + fe means field element. + Here the field is \Z/(2^255-19). + An element t, entries t[0]...t[9], represents the integer + t[0]+2^26 t[1]+2^51 t[2]+2^77 t[3]+2^102 t[4]+...+2^230 t[9]. + Bounds on each t[i] vary depending on context. +*/ + + +typedef int32_t fe[10]; + + +void fe_0(fe h); +void fe_1(fe h); + +void fe_frombytes(fe h, const unsigned char *s); +void fe_tobytes(unsigned char *s, const fe h); + +void fe_copy(fe h, const fe f); +int fe_isnegative(const fe f); +int fe_isnonzero(const fe f); +void fe_cmov(fe f, const fe g, unsigned int b); +void fe_cswap(fe f, fe g, unsigned int b); + +void fe_neg(fe h, const fe f); +void fe_add(fe h, const fe f, const fe g); +void fe_invert(fe out, const fe z); +void fe_sq(fe h, const fe f); +void fe_sq2(fe h, const fe f); +void fe_mul(fe h, const fe f, const fe g); +void fe_mul121666(fe h, fe f); +void fe_pow22523(fe out, const fe z); +void fe_sub(fe h, const fe f, const fe g); + +#endif diff --git a/src/ed25519/fixedint.h b/src/ed25519/fixedint.h new file mode 100644 index 0000000..d03e4bd --- /dev/null +++ b/src/ed25519/fixedint.h @@ -0,0 +1,70 @@ +/* + Portable header to provide the 32 and 64 bits type. + + Not a compatible replacement for , do not blindly use it as such. +*/ + +#if ((defined(__STDC__) && __STDC__ && __STDC_VERSION__ >= 199901L) || (defined(__WATCOMC__) && (defined(_STDINT_H_INCLUDED) || __WATCOMC__ >= 1250)) || (defined(__GNUC__) && (defined(_STDINT_H) || defined(_STDINT_H_) || defined(__UINT_FAST64_TYPE__)) )) && !defined(FIXEDINT_H_INCLUDED) + #include + #define FIXEDINT_H_INCLUDED + + #if defined(__WATCOMC__) && __WATCOMC__ >= 1250 && !defined(UINT64_C) + #include + #define UINT64_C(x) (x + (UINT64_MAX - UINT64_MAX)) + #endif +#endif + + +#ifndef FIXEDINT_H_INCLUDED + #define FIXEDINT_H_INCLUDED + + /* (u)int32_t */ + #ifndef uint32_t + #if (ULONG_MAX == 0xffffffffUL) + typedef unsigned long uint32_t; + #elif (UINT_MAX == 0xffffffffUL) + typedef unsigned int uint32_t; + #elif (USHRT_MAX == 0xffffffffUL) + typedef unsigned short uint32_t; + #endif + #endif + + + #ifndef int32_t + #if (LONG_MAX == 0x7fffffffL) + typedef signed long int32_t; + #elif (INT_MAX == 0x7fffffffL) + typedef signed int int32_t; + #elif (SHRT_MAX == 0x7fffffffL) + typedef signed short int32_t; + #endif + #endif + + + /* (u)int64_t */ + #if (defined(__STDC__) && defined(__STDC_VERSION__) && __STDC__ && __STDC_VERSION__ >= 199901L) + typedef long long int64_t; + typedef unsigned long long uint64_t; + + #define UINT64_C(v) v ##ULL + #define INT64_C(v) v ##LL + #elif defined(__GNUC__) + __extension__ typedef long long int64_t; + __extension__ typedef unsigned long long uint64_t; + + #define UINT64_C(v) v ##ULL + #define INT64_C(v) v ##LL + #elif defined(__MWERKS__) || defined(__SUNPRO_C) || defined(__SUNPRO_CC) || defined(__APPLE_CC__) || defined(_LONG_LONG) || defined(_CRAYC) + typedef long long int64_t; + typedef unsigned long long uint64_t; + + #define UINT64_C(v) v ##ULL + #define INT64_C(v) v ##LL + #elif (defined(__WATCOMC__) && defined(__WATCOM_INT64__)) || (defined(_MSC_VER) && _INTEGRAL_MAX_BITS >= 64) || (defined(__BORLANDC__) && __BORLANDC__ > 0x460) || defined(__alpha) || defined(__DECC) + typedef __int64 int64_t; + typedef unsigned __int64 uint64_t; + + #define UINT64_C(v) v ##UI64 + #define INT64_C(v) v ##I64 + #endif +#endif diff --git a/src/ed25519/ge.c b/src/ed25519/ge.c new file mode 100644 index 0000000..3c342b1 --- /dev/null +++ b/src/ed25519/ge.c @@ -0,0 +1,467 @@ +#include "ge.h" +#include "precomp_data.h" + + +/* +r = p + q +*/ + +void ge_add(ge_p1p1 *r, const ge_p3 *p, const ge_cached *q) { + fe t0; + fe_add(r->X, p->Y, p->X); + fe_sub(r->Y, p->Y, p->X); + fe_mul(r->Z, r->X, q->YplusX); + fe_mul(r->Y, r->Y, q->YminusX); + fe_mul(r->T, q->T2d, p->T); + fe_mul(r->X, p->Z, q->Z); + fe_add(t0, r->X, r->X); + fe_sub(r->X, r->Z, r->Y); + fe_add(r->Y, r->Z, r->Y); + fe_add(r->Z, t0, r->T); + fe_sub(r->T, t0, r->T); +} + + +static void slide(signed char *r, const unsigned char *a) { + int i; + int b; + int k; + + for (i = 0; i < 256; ++i) { + r[i] = 1 & (a[i >> 3] >> (i & 7)); + } + + for (i = 0; i < 256; ++i) + if (r[i]) { + for (b = 1; b <= 6 && i + b < 256; ++b) { + if (r[i + b]) { + if (r[i] + (r[i + b] << b) <= 15) { + r[i] += r[i + b] << b; + r[i + b] = 0; + } else if (r[i] - (r[i + b] << b) >= -15) { + r[i] -= r[i + b] << b; + + for (k = i + b; k < 256; ++k) { + if (!r[k]) { + r[k] = 1; + break; + } + + r[k] = 0; + } + } else { + break; + } + } + } + } +} + +/* +r = a * A + b * B +where a = a[0]+256*a[1]+...+256^31 a[31]. +and b = b[0]+256*b[1]+...+256^31 b[31]. +B is the Ed25519 base point (x,4/5) with x positive. +*/ + +void ge_double_scalarmult_vartime(ge_p2 *r, const unsigned char *a, const ge_p3 *A, const unsigned char *b) { + signed char aslide[256]; + signed char bslide[256]; + ge_cached Ai[8]; /* A,3A,5A,7A,9A,11A,13A,15A */ + ge_p1p1 t; + ge_p3 u; + ge_p3 A2; + int i; + slide(aslide, a); + slide(bslide, b); + ge_p3_to_cached(&Ai[0], A); + ge_p3_dbl(&t, A); + ge_p1p1_to_p3(&A2, &t); + ge_add(&t, &A2, &Ai[0]); + ge_p1p1_to_p3(&u, &t); + ge_p3_to_cached(&Ai[1], &u); + ge_add(&t, &A2, &Ai[1]); + ge_p1p1_to_p3(&u, &t); + ge_p3_to_cached(&Ai[2], &u); + ge_add(&t, &A2, &Ai[2]); + ge_p1p1_to_p3(&u, &t); + ge_p3_to_cached(&Ai[3], &u); + ge_add(&t, &A2, &Ai[3]); + ge_p1p1_to_p3(&u, &t); + ge_p3_to_cached(&Ai[4], &u); + ge_add(&t, &A2, &Ai[4]); + ge_p1p1_to_p3(&u, &t); + ge_p3_to_cached(&Ai[5], &u); + ge_add(&t, &A2, &Ai[5]); + ge_p1p1_to_p3(&u, &t); + ge_p3_to_cached(&Ai[6], &u); + ge_add(&t, &A2, &Ai[6]); + ge_p1p1_to_p3(&u, &t); + ge_p3_to_cached(&Ai[7], &u); + ge_p2_0(r); + + for (i = 255; i >= 0; --i) { + if (aslide[i] || bslide[i]) { + break; + } + } + + for (; i >= 0; --i) { + ge_p2_dbl(&t, r); + + if (aslide[i] > 0) { + ge_p1p1_to_p3(&u, &t); + ge_add(&t, &u, &Ai[aslide[i] / 2]); + } else if (aslide[i] < 0) { + ge_p1p1_to_p3(&u, &t); + ge_sub(&t, &u, &Ai[(-aslide[i]) / 2]); + } + + if (bslide[i] > 0) { + ge_p1p1_to_p3(&u, &t); + ge_madd(&t, &u, &Bi[bslide[i] / 2]); + } else if (bslide[i] < 0) { + ge_p1p1_to_p3(&u, &t); + ge_msub(&t, &u, &Bi[(-bslide[i]) / 2]); + } + + ge_p1p1_to_p2(r, &t); + } +} + + +static const fe d = { + -10913610, 13857413, -15372611, 6949391, 114729, -8787816, -6275908, -3247719, -18696448, -12055116 +}; + +static const fe sqrtm1 = { + -32595792, -7943725, 9377950, 3500415, 12389472, -272473, -25146209, -2005654, 326686, 11406482 +}; + +int ge_frombytes_negate_vartime(ge_p3 *h, const unsigned char *s) { + fe u; + fe v; + fe v3; + fe vxx; + fe check; + fe_frombytes(h->Y, s); + fe_1(h->Z); + fe_sq(u, h->Y); + fe_mul(v, u, d); + fe_sub(u, u, h->Z); /* u = y^2-1 */ + fe_add(v, v, h->Z); /* v = dy^2+1 */ + fe_sq(v3, v); + fe_mul(v3, v3, v); /* v3 = v^3 */ + fe_sq(h->X, v3); + fe_mul(h->X, h->X, v); + fe_mul(h->X, h->X, u); /* x = uv^7 */ + fe_pow22523(h->X, h->X); /* x = (uv^7)^((q-5)/8) */ + fe_mul(h->X, h->X, v3); + fe_mul(h->X, h->X, u); /* x = uv^3(uv^7)^((q-5)/8) */ + fe_sq(vxx, h->X); + fe_mul(vxx, vxx, v); + fe_sub(check, vxx, u); /* vx^2-u */ + + if (fe_isnonzero(check)) { + fe_add(check, vxx, u); /* vx^2+u */ + + if (fe_isnonzero(check)) { + return -1; + } + + fe_mul(h->X, h->X, sqrtm1); + } + + if (fe_isnegative(h->X) == (s[31] >> 7)) { + fe_neg(h->X, h->X); + } + + fe_mul(h->T, h->X, h->Y); + return 0; +} + + +/* +r = p + q +*/ + +void ge_madd(ge_p1p1 *r, const ge_p3 *p, const ge_precomp *q) { + fe t0; + fe_add(r->X, p->Y, p->X); + fe_sub(r->Y, p->Y, p->X); + fe_mul(r->Z, r->X, q->yplusx); + fe_mul(r->Y, r->Y, q->yminusx); + fe_mul(r->T, q->xy2d, p->T); + fe_add(t0, p->Z, p->Z); + fe_sub(r->X, r->Z, r->Y); + fe_add(r->Y, r->Z, r->Y); + fe_add(r->Z, t0, r->T); + fe_sub(r->T, t0, r->T); +} + + +/* +r = p - q +*/ + +void ge_msub(ge_p1p1 *r, const ge_p3 *p, const ge_precomp *q) { + fe t0; + + fe_add(r->X, p->Y, p->X); + fe_sub(r->Y, p->Y, p->X); + fe_mul(r->Z, r->X, q->yminusx); + fe_mul(r->Y, r->Y, q->yplusx); + fe_mul(r->T, q->xy2d, p->T); + fe_add(t0, p->Z, p->Z); + fe_sub(r->X, r->Z, r->Y); + fe_add(r->Y, r->Z, r->Y); + fe_sub(r->Z, t0, r->T); + fe_add(r->T, t0, r->T); +} + + +/* +r = p +*/ + +void ge_p1p1_to_p2(ge_p2 *r, const ge_p1p1 *p) { + fe_mul(r->X, p->X, p->T); + fe_mul(r->Y, p->Y, p->Z); + fe_mul(r->Z, p->Z, p->T); +} + + + +/* +r = p +*/ + +void ge_p1p1_to_p3(ge_p3 *r, const ge_p1p1 *p) { + fe_mul(r->X, p->X, p->T); + fe_mul(r->Y, p->Y, p->Z); + fe_mul(r->Z, p->Z, p->T); + fe_mul(r->T, p->X, p->Y); +} + + +void ge_p2_0(ge_p2 *h) { + fe_0(h->X); + fe_1(h->Y); + fe_1(h->Z); +} + + + +/* +r = 2 * p +*/ + +void ge_p2_dbl(ge_p1p1 *r, const ge_p2 *p) { + fe t0; + + fe_sq(r->X, p->X); + fe_sq(r->Z, p->Y); + fe_sq2(r->T, p->Z); + fe_add(r->Y, p->X, p->Y); + fe_sq(t0, r->Y); + fe_add(r->Y, r->Z, r->X); + fe_sub(r->Z, r->Z, r->X); + fe_sub(r->X, t0, r->Y); + fe_sub(r->T, r->T, r->Z); +} + + +void ge_p3_0(ge_p3 *h) { + fe_0(h->X); + fe_1(h->Y); + fe_1(h->Z); + fe_0(h->T); +} + + +/* +r = 2 * p +*/ + +void ge_p3_dbl(ge_p1p1 *r, const ge_p3 *p) { + ge_p2 q; + ge_p3_to_p2(&q, p); + ge_p2_dbl(r, &q); +} + + + +/* +r = p +*/ + +static const fe d2 = { + -21827239, -5839606, -30745221, 13898782, 229458, 15978800, -12551817, -6495438, 29715968, 9444199 +}; + +void ge_p3_to_cached(ge_cached *r, const ge_p3 *p) { + fe_add(r->YplusX, p->Y, p->X); + fe_sub(r->YminusX, p->Y, p->X); + fe_copy(r->Z, p->Z); + fe_mul(r->T2d, p->T, d2); +} + + +/* +r = p +*/ + +void ge_p3_to_p2(ge_p2 *r, const ge_p3 *p) { + fe_copy(r->X, p->X); + fe_copy(r->Y, p->Y); + fe_copy(r->Z, p->Z); +} + + +void ge_p3_tobytes(unsigned char *s, const ge_p3 *h) { + fe recip; + fe x; + fe y; + fe_invert(recip, h->Z); + fe_mul(x, h->X, recip); + fe_mul(y, h->Y, recip); + fe_tobytes(s, y); + s[31] ^= fe_isnegative(x) << 7; +} + + +static unsigned char equal(signed char b, signed char c) { + unsigned char ub = b; + unsigned char uc = c; + unsigned char x = ub ^ uc; /* 0: yes; 1..255: no */ + uint64_t y = x; /* 0: yes; 1..255: no */ + y -= 1; /* large: yes; 0..254: no */ + y >>= 63; /* 1: yes; 0: no */ + return (unsigned char) y; +} + +static unsigned char negative(signed char b) { + uint64_t x = b; /* 18446744073709551361..18446744073709551615: yes; 0..255: no */ + x >>= 63; /* 1: yes; 0: no */ + return (unsigned char) x; +} + +static void cmov(ge_precomp *t, ge_precomp *u, unsigned char b) { + fe_cmov(t->yplusx, u->yplusx, b); + fe_cmov(t->yminusx, u->yminusx, b); + fe_cmov(t->xy2d, u->xy2d, b); +} + + +static void select(ge_precomp *t, int pos, signed char b) { + ge_precomp minust; + unsigned char bnegative = negative(b); + unsigned char babs = b - (((-bnegative) & b) << 1); + fe_1(t->yplusx); + fe_1(t->yminusx); + fe_0(t->xy2d); + cmov(t, &base[pos][0], equal(babs, 1)); + cmov(t, &base[pos][1], equal(babs, 2)); + cmov(t, &base[pos][2], equal(babs, 3)); + cmov(t, &base[pos][3], equal(babs, 4)); + cmov(t, &base[pos][4], equal(babs, 5)); + cmov(t, &base[pos][5], equal(babs, 6)); + cmov(t, &base[pos][6], equal(babs, 7)); + cmov(t, &base[pos][7], equal(babs, 8)); + fe_copy(minust.yplusx, t->yminusx); + fe_copy(minust.yminusx, t->yplusx); + fe_neg(minust.xy2d, t->xy2d); + cmov(t, &minust, bnegative); +} + +/* +h = a * B +where a = a[0]+256*a[1]+...+256^31 a[31] +B is the Ed25519 base point (x,4/5) with x positive. + +Preconditions: + a[31] <= 127 +*/ + +void ge_scalarmult_base(ge_p3 *h, const unsigned char *a) { + signed char e[64]; + signed char carry; + ge_p1p1 r; + ge_p2 s; + ge_precomp t; + int i; + + for (i = 0; i < 32; ++i) { + e[2 * i + 0] = (a[i] >> 0) & 15; + e[2 * i + 1] = (a[i] >> 4) & 15; + } + + /* each e[i] is between 0 and 15 */ + /* e[63] is between 0 and 7 */ + carry = 0; + + for (i = 0; i < 63; ++i) { + e[i] += carry; + carry = e[i] + 8; + carry >>= 4; + e[i] -= carry << 4; + } + + e[63] += carry; + /* each e[i] is between -8 and 8 */ + ge_p3_0(h); + + for (i = 1; i < 64; i += 2) { + select(&t, i / 2, e[i]); + ge_madd(&r, h, &t); + ge_p1p1_to_p3(h, &r); + } + + ge_p3_dbl(&r, h); + ge_p1p1_to_p2(&s, &r); + ge_p2_dbl(&r, &s); + ge_p1p1_to_p2(&s, &r); + ge_p2_dbl(&r, &s); + ge_p1p1_to_p2(&s, &r); + ge_p2_dbl(&r, &s); + ge_p1p1_to_p3(h, &r); + + for (i = 0; i < 64; i += 2) { + select(&t, i / 2, e[i]); + ge_madd(&r, h, &t); + ge_p1p1_to_p3(h, &r); + } +} + + +/* +r = p - q +*/ + +void ge_sub(ge_p1p1 *r, const ge_p3 *p, const ge_cached *q) { + fe t0; + + fe_add(r->X, p->Y, p->X); + fe_sub(r->Y, p->Y, p->X); + fe_mul(r->Z, r->X, q->YminusX); + fe_mul(r->Y, r->Y, q->YplusX); + fe_mul(r->T, q->T2d, p->T); + fe_mul(r->X, p->Z, q->Z); + fe_add(t0, r->X, r->X); + fe_sub(r->X, r->Z, r->Y); + fe_add(r->Y, r->Z, r->Y); + fe_sub(r->Z, t0, r->T); + fe_add(r->T, t0, r->T); +} + + +void ge_tobytes(unsigned char *s, const ge_p2 *h) { + fe recip; + fe x; + fe y; + fe_invert(recip, h->Z); + fe_mul(x, h->X, recip); + fe_mul(y, h->Y, recip); + fe_tobytes(s, y); + s[31] ^= fe_isnegative(x) << 7; +} diff --git a/src/ed25519/ge.h b/src/ed25519/ge.h new file mode 100644 index 0000000..17fde2d --- /dev/null +++ b/src/ed25519/ge.h @@ -0,0 +1,74 @@ +#ifndef GE_H +#define GE_H + +#include "fe.h" + + +/* +ge means group element. + +Here the group is the set of pairs (x,y) of field elements (see fe.h) +satisfying -x^2 + y^2 = 1 + d x^2y^2 +where d = -121665/121666. + +Representations: + ge_p2 (projective): (X:Y:Z) satisfying x=X/Z, y=Y/Z + ge_p3 (extended): (X:Y:Z:T) satisfying x=X/Z, y=Y/Z, XY=ZT + ge_p1p1 (completed): ((X:Z),(Y:T)) satisfying x=X/Z, y=Y/T + ge_precomp (Duif): (y+x,y-x,2dxy) +*/ + +typedef struct { + fe X; + fe Y; + fe Z; +} ge_p2; + +typedef struct { + fe X; + fe Y; + fe Z; + fe T; +} ge_p3; + +typedef struct { + fe X; + fe Y; + fe Z; + fe T; +} ge_p1p1; + +typedef struct { + fe yplusx; + fe yminusx; + fe xy2d; +} ge_precomp; + +typedef struct { + fe YplusX; + fe YminusX; + fe Z; + fe T2d; +} ge_cached; + +void ge_p3_tobytes(unsigned char *s, const ge_p3 *h); +void ge_tobytes(unsigned char *s, const ge_p2 *h); +int ge_frombytes_negate_vartime(ge_p3 *h, const unsigned char *s); + +void ge_add(ge_p1p1 *r, const ge_p3 *p, const ge_cached *q); +void ge_sub(ge_p1p1 *r, const ge_p3 *p, const ge_cached *q); +void ge_double_scalarmult_vartime(ge_p2 *r, const unsigned char *a, const ge_p3 *A, const unsigned char *b); +void ge_madd(ge_p1p1 *r, const ge_p3 *p, const ge_precomp *q); +void ge_msub(ge_p1p1 *r, const ge_p3 *p, const ge_precomp *q); +void ge_scalarmult_base(ge_p3 *h, const unsigned char *a); + +void ge_p1p1_to_p2(ge_p2 *r, const ge_p1p1 *p); +void ge_p1p1_to_p3(ge_p3 *r, const ge_p1p1 *p); +void ge_p2_0(ge_p2 *h); +void ge_p2_dbl(ge_p1p1 *r, const ge_p2 *p); +void ge_p3_0(ge_p3 *h); +void ge_p3_dbl(ge_p1p1 *r, const ge_p3 *p); +void ge_p3_to_cached(ge_cached *r, const ge_p3 *p); +void ge_p3_to_p2(ge_p2 *r, const ge_p3 *p); + +#endif diff --git a/src/ed25519/key_exchange.c b/src/ed25519/key_exchange.c new file mode 100644 index 0000000..abd75da --- /dev/null +++ b/src/ed25519/key_exchange.c @@ -0,0 +1,79 @@ +#include "ed25519.h" +#include "fe.h" + +void ed25519_key_exchange(unsigned char *shared_secret, const unsigned char *public_key, const unsigned char *private_key) { + unsigned char e[32]; + unsigned int i; + + fe x1; + fe x2; + fe z2; + fe x3; + fe z3; + fe tmp0; + fe tmp1; + + int pos; + unsigned int swap; + unsigned int b; + + /* copy the private key and make sure it's valid */ + for (i = 0; i < 32; ++i) { + e[i] = private_key[i]; + } + + e[0] &= 248; + e[31] &= 63; + e[31] |= 64; + + /* unpack the public key and convert edwards to montgomery */ + /* due to CodesInChaos: montgomeryX = (edwardsY + 1)*inverse(1 - edwardsY) mod p */ + fe_frombytes(x1, public_key); + fe_1(tmp1); + fe_add(tmp0, x1, tmp1); + fe_sub(tmp1, tmp1, x1); + fe_invert(tmp1, tmp1); + fe_mul(x1, tmp0, tmp1); + + fe_1(x2); + fe_0(z2); + fe_copy(x3, x1); + fe_1(z3); + + swap = 0; + for (pos = 254; pos >= 0; --pos) { + b = e[pos / 8] >> (pos & 7); + b &= 1; + swap ^= b; + fe_cswap(x2, x3, swap); + fe_cswap(z2, z3, swap); + swap = b; + + /* from montgomery.h */ + fe_sub(tmp0, x3, z3); + fe_sub(tmp1, x2, z2); + fe_add(x2, x2, z2); + fe_add(z2, x3, z3); + fe_mul(z3, tmp0, x2); + fe_mul(z2, z2, tmp1); + fe_sq(tmp0, tmp1); + fe_sq(tmp1, x2); + fe_add(x3, z3, z2); + fe_sub(z2, z3, z2); + fe_mul(x2, tmp1, tmp0); + fe_sub(tmp1, tmp1, tmp0); + fe_sq(z2, z2); + fe_mul121666(z3, tmp1); + fe_sq(x3, x3); + fe_add(tmp0, tmp0, z3); + fe_mul(z3, x1, z2); + fe_mul(z2, tmp1, tmp0); + } + + fe_cswap(x2, x3, swap); + fe_cswap(z2, z3, swap); + + fe_invert(z2, z2); + fe_mul(x2, x2, z2); + fe_tobytes(shared_secret, x2); +} diff --git a/src/ed25519/keypair.c b/src/ed25519/keypair.c new file mode 100644 index 0000000..dc1b8ec --- /dev/null +++ b/src/ed25519/keypair.c @@ -0,0 +1,16 @@ +#include "ed25519.h" +#include "sha512.h" +#include "ge.h" + + +void ed25519_create_keypair(unsigned char *public_key, unsigned char *private_key, const unsigned char *seed) { + ge_p3 A; + + sha512(seed, 32, private_key); + private_key[0] &= 248; + private_key[31] &= 63; + private_key[31] |= 64; + + ge_scalarmult_base(&A, private_key); + ge_p3_tobytes(public_key, &A); +} diff --git a/src/ed25519/precomp_data.h b/src/ed25519/precomp_data.h new file mode 100644 index 0000000..776b84f --- /dev/null +++ b/src/ed25519/precomp_data.h @@ -0,0 +1,1391 @@ +static ge_precomp Bi[8] = { + { + { 25967493, -14356035, 29566456, 3660896, -12694345, 4014787, 27544626, -11754271, -6079156, 2047605 }, + { -12545711, 934262, -2722910, 3049990, -727428, 9406986, 12720692, 5043384, 19500929, -15469378 }, + { -8738181, 4489570, 9688441, -14785194, 10184609, -12363380, 29287919, 11864899, -24514362, -4438546 }, + }, + { + { 15636291, -9688557, 24204773, -7912398, 616977, -16685262, 27787600, -14772189, 28944400, -1550024 }, + { 16568933, 4717097, -11556148, -1102322, 15682896, -11807043, 16354577, -11775962, 7689662, 11199574 }, + { 30464156, -5976125, -11779434, -15670865, 23220365, 15915852, 7512774, 10017326, -17749093, -9920357 }, + }, + { + { 10861363, 11473154, 27284546, 1981175, -30064349, 12577861, 32867885, 14515107, -15438304, 10819380 }, + { 4708026, 6336745, 20377586, 9066809, -11272109, 6594696, -25653668, 12483688, -12668491, 5581306 }, + { 19563160, 16186464, -29386857, 4097519, 10237984, -4348115, 28542350, 13850243, -23678021, -15815942 }, + }, + { + { 5153746, 9909285, 1723747, -2777874, 30523605, 5516873, 19480852, 5230134, -23952439, -15175766 }, + { -30269007, -3463509, 7665486, 10083793, 28475525, 1649722, 20654025, 16520125, 30598449, 7715701 }, + { 28881845, 14381568, 9657904, 3680757, -20181635, 7843316, -31400660, 1370708, 29794553, -1409300 }, + }, + { + { -22518993, -6692182, 14201702, -8745502, -23510406, 8844726, 18474211, -1361450, -13062696, 13821877 }, + { -6455177, -7839871, 3374702, -4740862, -27098617, -10571707, 31655028, -7212327, 18853322, -14220951 }, + { 4566830, -12963868, -28974889, -12240689, -7602672, -2830569, -8514358, -10431137, 2207753, -3209784 }, + }, + { + { -25154831, -4185821, 29681144, 7868801, -6854661, -9423865, -12437364, -663000, -31111463, -16132436 }, + { 25576264, -2703214, 7349804, -11814844, 16472782, 9300885, 3844789, 15725684, 171356, 6466918 }, + { 23103977, 13316479, 9739013, -16149481, 817875, -15038942, 8965339, -14088058, -30714912, 16193877 }, + }, + { + { -33521811, 3180713, -2394130, 14003687, -16903474, -16270840, 17238398, 4729455, -18074513, 9256800 }, + { -25182317, -4174131, 32336398, 5036987, -21236817, 11360617, 22616405, 9761698, -19827198, 630305 }, + { -13720693, 2639453, -24237460, -7406481, 9494427, -5774029, -6554551, -15960994, -2449256, -14291300 }, + }, + { + { -3151181, -5046075, 9282714, 6866145, -31907062, -863023, -18940575, 15033784, 25105118, -7894876 }, + { -24326370, 15950226, -31801215, -14592823, -11662737, -5090925, 1573892, -2625887, 2198790, -15804619 }, + { -3099351, 10324967, -2241613, 7453183, -5446979, -2735503, -13812022, -16236442, -32461234, -12290683 }, + }, +}; + + +/* base[i][j] = (j+1)*256^i*B */ +static ge_precomp base[32][8] = { + { + { + { 25967493, -14356035, 29566456, 3660896, -12694345, 4014787, 27544626, -11754271, -6079156, 2047605 }, + { -12545711, 934262, -2722910, 3049990, -727428, 9406986, 12720692, 5043384, 19500929, -15469378 }, + { -8738181, 4489570, 9688441, -14785194, 10184609, -12363380, 29287919, 11864899, -24514362, -4438546 }, + }, + { + { -12815894, -12976347, -21581243, 11784320, -25355658, -2750717, -11717903, -3814571, -358445, -10211303 }, + { -21703237, 6903825, 27185491, 6451973, -29577724, -9554005, -15616551, 11189268, -26829678, -5319081 }, + { 26966642, 11152617, 32442495, 15396054, 14353839, -12752335, -3128826, -9541118, -15472047, -4166697 }, + }, + { + { 15636291, -9688557, 24204773, -7912398, 616977, -16685262, 27787600, -14772189, 28944400, -1550024 }, + { 16568933, 4717097, -11556148, -1102322, 15682896, -11807043, 16354577, -11775962, 7689662, 11199574 }, + { 30464156, -5976125, -11779434, -15670865, 23220365, 15915852, 7512774, 10017326, -17749093, -9920357 }, + }, + { + { -17036878, 13921892, 10945806, -6033431, 27105052, -16084379, -28926210, 15006023, 3284568, -6276540 }, + { 23599295, -8306047, -11193664, -7687416, 13236774, 10506355, 7464579, 9656445, 13059162, 10374397 }, + { 7798556, 16710257, 3033922, 2874086, 28997861, 2835604, 32406664, -3839045, -641708, -101325 }, + }, + { + { 10861363, 11473154, 27284546, 1981175, -30064349, 12577861, 32867885, 14515107, -15438304, 10819380 }, + { 4708026, 6336745, 20377586, 9066809, -11272109, 6594696, -25653668, 12483688, -12668491, 5581306 }, + { 19563160, 16186464, -29386857, 4097519, 10237984, -4348115, 28542350, 13850243, -23678021, -15815942 }, + }, + { + { -15371964, -12862754, 32573250, 4720197, -26436522, 5875511, -19188627, -15224819, -9818940, -12085777 }, + { -8549212, 109983, 15149363, 2178705, 22900618, 4543417, 3044240, -15689887, 1762328, 14866737 }, + { -18199695, -15951423, -10473290, 1707278, -17185920, 3916101, -28236412, 3959421, 27914454, 4383652 }, + }, + { + { 5153746, 9909285, 1723747, -2777874, 30523605, 5516873, 19480852, 5230134, -23952439, -15175766 }, + { -30269007, -3463509, 7665486, 10083793, 28475525, 1649722, 20654025, 16520125, 30598449, 7715701 }, + { 28881845, 14381568, 9657904, 3680757, -20181635, 7843316, -31400660, 1370708, 29794553, -1409300 }, + }, + { + { 14499471, -2729599, -33191113, -4254652, 28494862, 14271267, 30290735, 10876454, -33154098, 2381726 }, + { -7195431, -2655363, -14730155, 462251, -27724326, 3941372, -6236617, 3696005, -32300832, 15351955 }, + { 27431194, 8222322, 16448760, -3907995, -18707002, 11938355, -32961401, -2970515, 29551813, 10109425 }, + }, + }, + { + { + { -13657040, -13155431, -31283750, 11777098, 21447386, 6519384, -2378284, -1627556, 10092783, -4764171 }, + { 27939166, 14210322, 4677035, 16277044, -22964462, -12398139, -32508754, 12005538, -17810127, 12803510 }, + { 17228999, -15661624, -1233527, 300140, -1224870, -11714777, 30364213, -9038194, 18016357, 4397660 }, + }, + { + { -10958843, -7690207, 4776341, -14954238, 27850028, -15602212, -26619106, 14544525, -17477504, 982639 }, + { 29253598, 15796703, -2863982, -9908884, 10057023, 3163536, 7332899, -4120128, -21047696, 9934963 }, + { 5793303, 16271923, -24131614, -10116404, 29188560, 1206517, -14747930, 4559895, -30123922, -10897950 }, + }, + { + { -27643952, -11493006, 16282657, -11036493, 28414021, -15012264, 24191034, 4541697, -13338309, 5500568 }, + { 12650548, -1497113, 9052871, 11355358, -17680037, -8400164, -17430592, 12264343, 10874051, 13524335 }, + { 25556948, -3045990, 714651, 2510400, 23394682, -10415330, 33119038, 5080568, -22528059, 5376628 }, + }, + { + { -26088264, -4011052, -17013699, -3537628, -6726793, 1920897, -22321305, -9447443, 4535768, 1569007 }, + { -2255422, 14606630, -21692440, -8039818, 28430649, 8775819, -30494562, 3044290, 31848280, 12543772 }, + { -22028579, 2943893, -31857513, 6777306, 13784462, -4292203, -27377195, -2062731, 7718482, 14474653 }, + }, + { + { 2385315, 2454213, -22631320, 46603, -4437935, -15680415, 656965, -7236665, 24316168, -5253567 }, + { 13741529, 10911568, -33233417, -8603737, -20177830, -1033297, 33040651, -13424532, -20729456, 8321686 }, + { 21060490, -2212744, 15712757, -4336099, 1639040, 10656336, 23845965, -11874838, -9984458, 608372 }, + }, + { + { -13672732, -15087586, -10889693, -7557059, -6036909, 11305547, 1123968, -6780577, 27229399, 23887 }, + { -23244140, -294205, -11744728, 14712571, -29465699, -2029617, 12797024, -6440308, -1633405, 16678954 }, + { -29500620, 4770662, -16054387, 14001338, 7830047, 9564805, -1508144, -4795045, -17169265, 4904953 }, + }, + { + { 24059557, 14617003, 19037157, -15039908, 19766093, -14906429, 5169211, 16191880, 2128236, -4326833 }, + { -16981152, 4124966, -8540610, -10653797, 30336522, -14105247, -29806336, 916033, -6882542, -2986532 }, + { -22630907, 12419372, -7134229, -7473371, -16478904, 16739175, 285431, 2763829, 15736322, 4143876 }, + }, + { + { 2379352, 11839345, -4110402, -5988665, 11274298, 794957, 212801, -14594663, 23527084, -16458268 }, + { 33431127, -11130478, -17838966, -15626900, 8909499, 8376530, -32625340, 4087881, -15188911, -14416214 }, + { 1767683, 7197987, -13205226, -2022635, -13091350, 448826, 5799055, 4357868, -4774191, -16323038 }, + }, + }, + { + { + { 6721966, 13833823, -23523388, -1551314, 26354293, -11863321, 23365147, -3949732, 7390890, 2759800 }, + { 4409041, 2052381, 23373853, 10530217, 7676779, -12885954, 21302353, -4264057, 1244380, -12919645 }, + { -4421239, 7169619, 4982368, -2957590, 30256825, -2777540, 14086413, 9208236, 15886429, 16489664 }, + }, + { + { 1996075, 10375649, 14346367, 13311202, -6874135, -16438411, -13693198, 398369, -30606455, -712933 }, + { -25307465, 9795880, -2777414, 14878809, -33531835, 14780363, 13348553, 12076947, -30836462, 5113182 }, + { -17770784, 11797796, 31950843, 13929123, -25888302, 12288344, -30341101, -7336386, 13847711, 5387222 }, + }, + { + { -18582163, -3416217, 17824843, -2340966, 22744343, -10442611, 8763061, 3617786, -19600662, 10370991 }, + { 20246567, -14369378, 22358229, -543712, 18507283, -10413996, 14554437, -8746092, 32232924, 16763880 }, + { 9648505, 10094563, 26416693, 14745928, -30374318, -6472621, 11094161, 15689506, 3140038, -16510092 }, + }, + { + { -16160072, 5472695, 31895588, 4744994, 8823515, 10365685, -27224800, 9448613, -28774454, 366295 }, + { 19153450, 11523972, -11096490, -6503142, -24647631, 5420647, 28344573, 8041113, 719605, 11671788 }, + { 8678025, 2694440, -6808014, 2517372, 4964326, 11152271, -15432916, -15266516, 27000813, -10195553 }, + }, + { + { -15157904, 7134312, 8639287, -2814877, -7235688, 10421742, 564065, 5336097, 6750977, -14521026 }, + { 11836410, -3979488, 26297894, 16080799, 23455045, 15735944, 1695823, -8819122, 8169720, 16220347 }, + { -18115838, 8653647, 17578566, -6092619, -8025777, -16012763, -11144307, -2627664, -5990708, -14166033 }, + }, + { + { -23308498, -10968312, 15213228, -10081214, -30853605, -11050004, 27884329, 2847284, 2655861, 1738395 }, + { -27537433, -14253021, -25336301, -8002780, -9370762, 8129821, 21651608, -3239336, -19087449, -11005278 }, + { 1533110, 3437855, 23735889, 459276, 29970501, 11335377, 26030092, 5821408, 10478196, 8544890 }, + }, + { + { 32173121, -16129311, 24896207, 3921497, 22579056, -3410854, 19270449, 12217473, 17789017, -3395995 }, + { -30552961, -2228401, -15578829, -10147201, 13243889, 517024, 15479401, -3853233, 30460520, 1052596 }, + { -11614875, 13323618, 32618793, 8175907, -15230173, 12596687, 27491595, -4612359, 3179268, -9478891 }, + }, + { + { 31947069, -14366651, -4640583, -15339921, -15125977, -6039709, -14756777, -16411740, 19072640, -9511060 }, + { 11685058, 11822410, 3158003, -13952594, 33402194, -4165066, 5977896, -5215017, 473099, 5040608 }, + { -20290863, 8198642, -27410132, 11602123, 1290375, -2799760, 28326862, 1721092, -19558642, -3131606 }, + }, + }, + { + { + { 7881532, 10687937, 7578723, 7738378, -18951012, -2553952, 21820786, 8076149, -27868496, 11538389 }, + { -19935666, 3899861, 18283497, -6801568, -15728660, -11249211, 8754525, 7446702, -5676054, 5797016 }, + { -11295600, -3793569, -15782110, -7964573, 12708869, -8456199, 2014099, -9050574, -2369172, -5877341 }, + }, + { + { -22472376, -11568741, -27682020, 1146375, 18956691, 16640559, 1192730, -3714199, 15123619, 10811505 }, + { 14352098, -3419715, -18942044, 10822655, 32750596, 4699007, -70363, 15776356, -28886779, -11974553 }, + { -28241164, -8072475, -4978962, -5315317, 29416931, 1847569, -20654173, -16484855, 4714547, -9600655 }, + }, + { + { 15200332, 8368572, 19679101, 15970074, -31872674, 1959451, 24611599, -4543832, -11745876, 12340220 }, + { 12876937, -10480056, 33134381, 6590940, -6307776, 14872440, 9613953, 8241152, 15370987, 9608631 }, + { -4143277, -12014408, 8446281, -391603, 4407738, 13629032, -7724868, 15866074, -28210621, -8814099 }, + }, + { + { 26660628, -15677655, 8393734, 358047, -7401291, 992988, -23904233, 858697, 20571223, 8420556 }, + { 14620715, 13067227, -15447274, 8264467, 14106269, 15080814, 33531827, 12516406, -21574435, -12476749 }, + { 236881, 10476226, 57258, -14677024, 6472998, 2466984, 17258519, 7256740, 8791136, 15069930 }, + }, + { + { 1276410, -9371918, 22949635, -16322807, -23493039, -5702186, 14711875, 4874229, -30663140, -2331391 }, + { 5855666, 4990204, -13711848, 7294284, -7804282, 1924647, -1423175, -7912378, -33069337, 9234253 }, + { 20590503, -9018988, 31529744, -7352666, -2706834, 10650548, 31559055, -11609587, 18979186, 13396066 }, + }, + { + { 24474287, 4968103, 22267082, 4407354, 24063882, -8325180, -18816887, 13594782, 33514650, 7021958 }, + { -11566906, -6565505, -21365085, 15928892, -26158305, 4315421, -25948728, -3916677, -21480480, 12868082 }, + { -28635013, 13504661, 19988037, -2132761, 21078225, 6443208, -21446107, 2244500, -12455797, -8089383 }, + }, + { + { -30595528, 13793479, -5852820, 319136, -25723172, -6263899, 33086546, 8957937, -15233648, 5540521 }, + { -11630176, -11503902, -8119500, -7643073, 2620056, 1022908, -23710744, -1568984, -16128528, -14962807 }, + { 23152971, 775386, 27395463, 14006635, -9701118, 4649512, 1689819, 892185, -11513277, -15205948 }, + }, + { + { 9770129, 9586738, 26496094, 4324120, 1556511, -3550024, 27453819, 4763127, -19179614, 5867134 }, + { -32765025, 1927590, 31726409, -4753295, 23962434, -16019500, 27846559, 5931263, -29749703, -16108455 }, + { 27461885, -2977536, 22380810, 1815854, -23033753, -3031938, 7283490, -15148073, -19526700, 7734629 }, + }, + }, + { + { + { -8010264, -9590817, -11120403, 6196038, 29344158, -13430885, 7585295, -3176626, 18549497, 15302069 }, + { -32658337, -6171222, -7672793, -11051681, 6258878, 13504381, 10458790, -6418461, -8872242, 8424746 }, + { 24687205, 8613276, -30667046, -3233545, 1863892, -1830544, 19206234, 7134917, -11284482, -828919 }, + }, + { + { 11334899, -9218022, 8025293, 12707519, 17523892, -10476071, 10243738, -14685461, -5066034, 16498837 }, + { 8911542, 6887158, -9584260, -6958590, 11145641, -9543680, 17303925, -14124238, 6536641, 10543906 }, + { -28946384, 15479763, -17466835, 568876, -1497683, 11223454, -2669190, -16625574, -27235709, 8876771 }, + }, + { + { -25742899, -12566864, -15649966, -846607, -33026686, -796288, -33481822, 15824474, -604426, -9039817 }, + { 10330056, 70051, 7957388, -9002667, 9764902, 15609756, 27698697, -4890037, 1657394, 3084098 }, + { 10477963, -7470260, 12119566, -13250805, 29016247, -5365589, 31280319, 14396151, -30233575, 15272409 }, + }, + { + { -12288309, 3169463, 28813183, 16658753, 25116432, -5630466, -25173957, -12636138, -25014757, 1950504 }, + { -26180358, 9489187, 11053416, -14746161, -31053720, 5825630, -8384306, -8767532, 15341279, 8373727 }, + { 28685821, 7759505, -14378516, -12002860, -31971820, 4079242, 298136, -10232602, -2878207, 15190420 }, + }, + { + { -32932876, 13806336, -14337485, -15794431, -24004620, 10940928, 8669718, 2742393, -26033313, -6875003 }, + { -1580388, -11729417, -25979658, -11445023, -17411874, -10912854, 9291594, -16247779, -12154742, 6048605 }, + { -30305315, 14843444, 1539301, 11864366, 20201677, 1900163, 13934231, 5128323, 11213262, 9168384 }, + }, + { + { -26280513, 11007847, 19408960, -940758, -18592965, -4328580, -5088060, -11105150, 20470157, -16398701 }, + { -23136053, 9282192, 14855179, -15390078, -7362815, -14408560, -22783952, 14461608, 14042978, 5230683 }, + { 29969567, -2741594, -16711867, -8552442, 9175486, -2468974, 21556951, 3506042, -5933891, -12449708 }, + }, + { + { -3144746, 8744661, 19704003, 4581278, -20430686, 6830683, -21284170, 8971513, -28539189, 15326563 }, + { -19464629, 10110288, -17262528, -3503892, -23500387, 1355669, -15523050, 15300988, -20514118, 9168260 }, + { -5353335, 4488613, -23803248, 16314347, 7780487, -15638939, -28948358, 9601605, 33087103, -9011387 }, + }, + { + { -19443170, -15512900, -20797467, -12445323, -29824447, 10229461, -27444329, -15000531, -5996870, 15664672 }, + { 23294591, -16632613, -22650781, -8470978, 27844204, 11461195, 13099750, -2460356, 18151676, 13417686 }, + { -24722913, -4176517, -31150679, 5988919, -26858785, 6685065, 1661597, -12551441, 15271676, -15452665 }, + }, + }, + { + { + { 11433042, -13228665, 8239631, -5279517, -1985436, -725718, -18698764, 2167544, -6921301, -13440182 }, + { -31436171, 15575146, 30436815, 12192228, -22463353, 9395379, -9917708, -8638997, 12215110, 12028277 }, + { 14098400, 6555944, 23007258, 5757252, -15427832, -12950502, 30123440, 4617780, -16900089, -655628 }, + }, + { + { -4026201, -15240835, 11893168, 13718664, -14809462, 1847385, -15819999, 10154009, 23973261, -12684474 }, + { -26531820, -3695990, -1908898, 2534301, -31870557, -16550355, 18341390, -11419951, 32013174, -10103539 }, + { -25479301, 10876443, -11771086, -14625140, -12369567, 1838104, 21911214, 6354752, 4425632, -837822 }, + }, + { + { -10433389, -14612966, 22229858, -3091047, -13191166, 776729, -17415375, -12020462, 4725005, 14044970 }, + { 19268650, -7304421, 1555349, 8692754, -21474059, -9910664, 6347390, -1411784, -19522291, -16109756 }, + { -24864089, 12986008, -10898878, -5558584, -11312371, -148526, 19541418, 8180106, 9282262, 10282508 }, + }, + { + { -26205082, 4428547, -8661196, -13194263, 4098402, -14165257, 15522535, 8372215, 5542595, -10702683 }, + { -10562541, 14895633, 26814552, -16673850, -17480754, -2489360, -2781891, 6993761, -18093885, 10114655 }, + { -20107055, -929418, 31422704, 10427861, -7110749, 6150669, -29091755, -11529146, 25953725, -106158 }, + }, + { + { -4234397, -8039292, -9119125, 3046000, 2101609, -12607294, 19390020, 6094296, -3315279, 12831125 }, + { -15998678, 7578152, 5310217, 14408357, -33548620, -224739, 31575954, 6326196, 7381791, -2421839 }, + { -20902779, 3296811, 24736065, -16328389, 18374254, 7318640, 6295303, 8082724, -15362489, 12339664 }, + }, + { + { 27724736, 2291157, 6088201, -14184798, 1792727, 5857634, 13848414, 15768922, 25091167, 14856294 }, + { -18866652, 8331043, 24373479, 8541013, -701998, -9269457, 12927300, -12695493, -22182473, -9012899 }, + { -11423429, -5421590, 11632845, 3405020, 30536730, -11674039, -27260765, 13866390, 30146206, 9142070 }, + }, + { + { 3924129, -15307516, -13817122, -10054960, 12291820, -668366, -27702774, 9326384, -8237858, 4171294 }, + { -15921940, 16037937, 6713787, 16606682, -21612135, 2790944, 26396185, 3731949, 345228, -5462949 }, + { -21327538, 13448259, 25284571, 1143661, 20614966, -8849387, 2031539, -12391231, -16253183, -13582083 }, + }, + { + { 31016211, -16722429, 26371392, -14451233, -5027349, 14854137, 17477601, 3842657, 28012650, -16405420 }, + { -5075835, 9368966, -8562079, -4600902, -15249953, 6970560, -9189873, 16292057, -8867157, 3507940 }, + { 29439664, 3537914, 23333589, 6997794, -17555561, -11018068, -15209202, -15051267, -9164929, 6580396 }, + }, + }, + { + { + { -12185861, -7679788, 16438269, 10826160, -8696817, -6235611, 17860444, -9273846, -2095802, 9304567 }, + { 20714564, -4336911, 29088195, 7406487, 11426967, -5095705, 14792667, -14608617, 5289421, -477127 }, + { -16665533, -10650790, -6160345, -13305760, 9192020, -1802462, 17271490, 12349094, 26939669, -3752294 }, + }, + { + { -12889898, 9373458, 31595848, 16374215, 21471720, 13221525, -27283495, -12348559, -3698806, 117887 }, + { 22263325, -6560050, 3984570, -11174646, -15114008, -566785, 28311253, 5358056, -23319780, 541964 }, + { 16259219, 3261970, 2309254, -15534474, -16885711, -4581916, 24134070, -16705829, -13337066, -13552195 }, + }, + { + { 9378160, -13140186, -22845982, -12745264, 28198281, -7244098, -2399684, -717351, 690426, 14876244 }, + { 24977353, -314384, -8223969, -13465086, 28432343, -1176353, -13068804, -12297348, -22380984, 6618999 }, + { -1538174, 11685646, 12944378, 13682314, -24389511, -14413193, 8044829, -13817328, 32239829, -5652762 }, + }, + { + { -18603066, 4762990, -926250, 8885304, -28412480, -3187315, 9781647, -10350059, 32779359, 5095274 }, + { -33008130, -5214506, -32264887, -3685216, 9460461, -9327423, -24601656, 14506724, 21639561, -2630236 }, + { -16400943, -13112215, 25239338, 15531969, 3987758, -4499318, -1289502, -6863535, 17874574, 558605 }, + }, + { + { -13600129, 10240081, 9171883, 16131053, -20869254, 9599700, 33499487, 5080151, 2085892, 5119761 }, + { -22205145, -2519528, -16381601, 414691, -25019550, 2170430, 30634760, -8363614, -31999993, -5759884 }, + { -6845704, 15791202, 8550074, -1312654, 29928809, -12092256, 27534430, -7192145, -22351378, 12961482 }, + }, + { + { -24492060, -9570771, 10368194, 11582341, -23397293, -2245287, 16533930, 8206996, -30194652, -5159638 }, + { -11121496, -3382234, 2307366, 6362031, -135455, 8868177, -16835630, 7031275, 7589640, 8945490 }, + { -32152748, 8917967, 6661220, -11677616, -1192060, -15793393, 7251489, -11182180, 24099109, -14456170 }, + }, + { + { 5019558, -7907470, 4244127, -14714356, -26933272, 6453165, -19118182, -13289025, -6231896, -10280736 }, + { 10853594, 10721687, 26480089, 5861829, -22995819, 1972175, -1866647, -10557898, -3363451, -6441124 }, + { -17002408, 5906790, 221599, -6563147, 7828208, -13248918, 24362661, -2008168, -13866408, 7421392 }, + }, + { + { 8139927, -6546497, 32257646, -5890546, 30375719, 1886181, -21175108, 15441252, 28826358, -4123029 }, + { 6267086, 9695052, 7709135, -16603597, -32869068, -1886135, 14795160, -7840124, 13746021, -1742048 }, + { 28584902, 7787108, -6732942, -15050729, 22846041, -7571236, -3181936, -363524, 4771362, -8419958 }, + }, + }, + { + { + { 24949256, 6376279, -27466481, -8174608, -18646154, -9930606, 33543569, -12141695, 3569627, 11342593 }, + { 26514989, 4740088, 27912651, 3697550, 19331575, -11472339, 6809886, 4608608, 7325975, -14801071 }, + { -11618399, -14554430, -24321212, 7655128, -1369274, 5214312, -27400540, 10258390, -17646694, -8186692 }, + }, + { + { 11431204, 15823007, 26570245, 14329124, 18029990, 4796082, -31446179, 15580664, 9280358, -3973687 }, + { -160783, -10326257, -22855316, -4304997, -20861367, -13621002, -32810901, -11181622, -15545091, 4387441 }, + { -20799378, 12194512, 3937617, -5805892, -27154820, 9340370, -24513992, 8548137, 20617071, -7482001 }, + }, + { + { -938825, -3930586, -8714311, 16124718, 24603125, -6225393, -13775352, -11875822, 24345683, 10325460 }, + { -19855277, -1568885, -22202708, 8714034, 14007766, 6928528, 16318175, -1010689, 4766743, 3552007 }, + { -21751364, -16730916, 1351763, -803421, -4009670, 3950935, 3217514, 14481909, 10988822, -3994762 }, + }, + { + { 15564307, -14311570, 3101243, 5684148, 30446780, -8051356, 12677127, -6505343, -8295852, 13296005 }, + { -9442290, 6624296, -30298964, -11913677, -4670981, -2057379, 31521204, 9614054, -30000824, 12074674 }, + { 4771191, -135239, 14290749, -13089852, 27992298, 14998318, -1413936, -1556716, 29832613, -16391035 }, + }, + { + { 7064884, -7541174, -19161962, -5067537, -18891269, -2912736, 25825242, 5293297, -27122660, 13101590 }, + { -2298563, 2439670, -7466610, 1719965, -27267541, -16328445, 32512469, -5317593, -30356070, -4190957 }, + { -30006540, 10162316, -33180176, 3981723, -16482138, -13070044, 14413974, 9515896, 19568978, 9628812 }, + }, + { + { 33053803, 199357, 15894591, 1583059, 27380243, -4580435, -17838894, -6106839, -6291786, 3437740 }, + { -18978877, 3884493, 19469877, 12726490, 15913552, 13614290, -22961733, 70104, 7463304, 4176122 }, + { -27124001, 10659917, 11482427, -16070381, 12771467, -6635117, -32719404, -5322751, 24216882, 5944158 }, + }, + { + { 8894125, 7450974, -2664149, -9765752, -28080517, -12389115, 19345746, 14680796, 11632993, 5847885 }, + { 26942781, -2315317, 9129564, -4906607, 26024105, 11769399, -11518837, 6367194, -9727230, 4782140 }, + { 19916461, -4828410, -22910704, -11414391, 25606324, -5972441, 33253853, 8220911, 6358847, -1873857 }, + }, + { + { 801428, -2081702, 16569428, 11065167, 29875704, 96627, 7908388, -4480480, -13538503, 1387155 }, + { 19646058, 5720633, -11416706, 12814209, 11607948, 12749789, 14147075, 15156355, -21866831, 11835260 }, + { 19299512, 1155910, 28703737, 14890794, 2925026, 7269399, 26121523, 15467869, -26560550, 5052483 }, + }, + }, + { + { + { -3017432, 10058206, 1980837, 3964243, 22160966, 12322533, -6431123, -12618185, 12228557, -7003677 }, + { 32944382, 14922211, -22844894, 5188528, 21913450, -8719943, 4001465, 13238564, -6114803, 8653815 }, + { 22865569, -4652735, 27603668, -12545395, 14348958, 8234005, 24808405, 5719875, 28483275, 2841751 }, + }, + { + { -16420968, -1113305, -327719, -12107856, 21886282, -15552774, -1887966, -315658, 19932058, -12739203 }, + { -11656086, 10087521, -8864888, -5536143, -19278573, -3055912, 3999228, 13239134, -4777469, -13910208 }, + { 1382174, -11694719, 17266790, 9194690, -13324356, 9720081, 20403944, 11284705, -14013818, 3093230 }, + }, + { + { 16650921, -11037932, -1064178, 1570629, -8329746, 7352753, -302424, 16271225, -24049421, -6691850 }, + { -21911077, -5927941, -4611316, -5560156, -31744103, -10785293, 24123614, 15193618, -21652117, -16739389 }, + { -9935934, -4289447, -25279823, 4372842, 2087473, 10399484, 31870908, 14690798, 17361620, 11864968 }, + }, + { + { -11307610, 6210372, 13206574, 5806320, -29017692, -13967200, -12331205, -7486601, -25578460, -16240689 }, + { 14668462, -12270235, 26039039, 15305210, 25515617, 4542480, 10453892, 6577524, 9145645, -6443880 }, + { 5974874, 3053895, -9433049, -10385191, -31865124, 3225009, -7972642, 3936128, -5652273, -3050304 }, + }, + { + { 30625386, -4729400, -25555961, -12792866, -20484575, 7695099, 17097188, -16303496, -27999779, 1803632 }, + { -3553091, 9865099, -5228566, 4272701, -5673832, -16689700, 14911344, 12196514, -21405489, 7047412 }, + { 20093277, 9920966, -11138194, -5343857, 13161587, 12044805, -32856851, 4124601, -32343828, -10257566 }, + }, + { + { -20788824, 14084654, -13531713, 7842147, 19119038, -13822605, 4752377, -8714640, -21679658, 2288038 }, + { -26819236, -3283715, 29965059, 3039786, -14473765, 2540457, 29457502, 14625692, -24819617, 12570232 }, + { -1063558, -11551823, 16920318, 12494842, 1278292, -5869109, -21159943, -3498680, -11974704, 4724943 }, + }, + { + { 17960970, -11775534, -4140968, -9702530, -8876562, -1410617, -12907383, -8659932, -29576300, 1903856 }, + { 23134274, -14279132, -10681997, -1611936, 20684485, 15770816, -12989750, 3190296, 26955097, 14109738 }, + { 15308788, 5320727, -30113809, -14318877, 22902008, 7767164, 29425325, -11277562, 31960942, 11934971 }, + }, + { + { -27395711, 8435796, 4109644, 12222639, -24627868, 14818669, 20638173, 4875028, 10491392, 1379718 }, + { -13159415, 9197841, 3875503, -8936108, -1383712, -5879801, 33518459, 16176658, 21432314, 12180697 }, + { -11787308, 11500838, 13787581, -13832590, -22430679, 10140205, 1465425, 12689540, -10301319, -13872883 }, + }, + }, + { + { + { 5414091, -15386041, -21007664, 9643570, 12834970, 1186149, -2622916, -1342231, 26128231, 6032912 }, + { -26337395, -13766162, 32496025, -13653919, 17847801, -12669156, 3604025, 8316894, -25875034, -10437358 }, + { 3296484, 6223048, 24680646, -12246460, -23052020, 5903205, -8862297, -4639164, 12376617, 3188849 }, + }, + { + { 29190488, -14659046, 27549113, -1183516, 3520066, -10697301, 32049515, -7309113, -16109234, -9852307 }, + { -14744486, -9309156, 735818, -598978, -20407687, -5057904, 25246078, -15795669, 18640741, -960977 }, + { -6928835, -16430795, 10361374, 5642961, 4910474, 12345252, -31638386, -494430, 10530747, 1053335 }, + }, + { + { -29265967, -14186805, -13538216, -12117373, -19457059, -10655384, -31462369, -2948985, 24018831, 15026644 }, + { -22592535, -3145277, -2289276, 5953843, -13440189, 9425631, 25310643, 13003497, -2314791, -15145616 }, + { -27419985, -603321, -8043984, -1669117, -26092265, 13987819, -27297622, 187899, -23166419, -2531735 }, + }, + { + { -21744398, -13810475, 1844840, 5021428, -10434399, -15911473, 9716667, 16266922, -5070217, 726099 }, + { 29370922, -6053998, 7334071, -15342259, 9385287, 2247707, -13661962, -4839461, 30007388, -15823341 }, + { -936379, 16086691, 23751945, -543318, -1167538, -5189036, 9137109, 730663, 9835848, 4555336 }, + }, + { + { -23376435, 1410446, -22253753, -12899614, 30867635, 15826977, 17693930, 544696, -11985298, 12422646 }, + { 31117226, -12215734, -13502838, 6561947, -9876867, -12757670, -5118685, -4096706, 29120153, 13924425 }, + { -17400879, -14233209, 19675799, -2734756, -11006962, -5858820, -9383939, -11317700, 7240931, -237388 }, + }, + { + { -31361739, -11346780, -15007447, -5856218, -22453340, -12152771, 1222336, 4389483, 3293637, -15551743 }, + { -16684801, -14444245, 11038544, 11054958, -13801175, -3338533, -24319580, 7733547, 12796905, -6335822 }, + { -8759414, -10817836, -25418864, 10783769, -30615557, -9746811, -28253339, 3647836, 3222231, -11160462 }, + }, + { + { 18606113, 1693100, -25448386, -15170272, 4112353, 10045021, 23603893, -2048234, -7550776, 2484985 }, + { 9255317, -3131197, -12156162, -1004256, 13098013, -9214866, 16377220, -2102812, -19802075, -3034702 }, + { -22729289, 7496160, -5742199, 11329249, 19991973, -3347502, -31718148, 9936966, -30097688, -10618797 }, + }, + { + { 21878590, -5001297, 4338336, 13643897, -3036865, 13160960, 19708896, 5415497, -7360503, -4109293 }, + { 27736861, 10103576, 12500508, 8502413, -3413016, -9633558, 10436918, -1550276, -23659143, -8132100 }, + { 19492550, -12104365, -29681976, -852630, -3208171, 12403437, 30066266, 8367329, 13243957, 8709688 }, + }, + }, + { + { + { 12015105, 2801261, 28198131, 10151021, 24818120, -4743133, -11194191, -5645734, 5150968, 7274186 }, + { 2831366, -12492146, 1478975, 6122054, 23825128, -12733586, 31097299, 6083058, 31021603, -9793610 }, + { -2529932, -2229646, 445613, 10720828, -13849527, -11505937, -23507731, 16354465, 15067285, -14147707 }, + }, + { + { 7840942, 14037873, -33364863, 15934016, -728213, -3642706, 21403988, 1057586, -19379462, -12403220 }, + { 915865, -16469274, 15608285, -8789130, -24357026, 6060030, -17371319, 8410997, -7220461, 16527025 }, + { 32922597, -556987, 20336074, -16184568, 10903705, -5384487, 16957574, 52992, 23834301, 6588044 }, + }, + { + { 32752030, 11232950, 3381995, -8714866, 22652988, -10744103, 17159699, 16689107, -20314580, -1305992 }, + { -4689649, 9166776, -25710296, -10847306, 11576752, 12733943, 7924251, -2752281, 1976123, -7249027 }, + { 21251222, 16309901, -2983015, -6783122, 30810597, 12967303, 156041, -3371252, 12331345, -8237197 }, + }, + { + { 8651614, -4477032, -16085636, -4996994, 13002507, 2950805, 29054427, -5106970, 10008136, -4667901 }, + { 31486080, 15114593, -14261250, 12951354, 14369431, -7387845, 16347321, -13662089, 8684155, -10532952 }, + { 19443825, 11385320, 24468943, -9659068, -23919258, 2187569, -26263207, -6086921, 31316348, 14219878 }, + }, + { + { -28594490, 1193785, 32245219, 11392485, 31092169, 15722801, 27146014, 6992409, 29126555, 9207390 }, + { 32382935, 1110093, 18477781, 11028262, -27411763, -7548111, -4980517, 10843782, -7957600, -14435730 }, + { 2814918, 7836403, 27519878, -7868156, -20894015, -11553689, -21494559, 8550130, 28346258, 1994730 }, + }, + { + { -19578299, 8085545, -14000519, -3948622, 2785838, -16231307, -19516951, 7174894, 22628102, 8115180 }, + { -30405132, 955511, -11133838, -15078069, -32447087, -13278079, -25651578, 3317160, -9943017, 930272 }, + { -15303681, -6833769, 28856490, 1357446, 23421993, 1057177, 24091212, -1388970, -22765376, -10650715 }, + }, + { + { -22751231, -5303997, -12907607, -12768866, -15811511, -7797053, -14839018, -16554220, -1867018, 8398970 }, + { -31969310, 2106403, -4736360, 1362501, 12813763, 16200670, 22981545, -6291273, 18009408, -15772772 }, + { -17220923, -9545221, -27784654, 14166835, 29815394, 7444469, 29551787, -3727419, 19288549, 1325865 }, + }, + { + { 15100157, -15835752, -23923978, -1005098, -26450192, 15509408, 12376730, -3479146, 33166107, -8042750 }, + { 20909231, 13023121, -9209752, 16251778, -5778415, -8094914, 12412151, 10018715, 2213263, -13878373 }, + { 32529814, -11074689, 30361439, -16689753, -9135940, 1513226, 22922121, 6382134, -5766928, 8371348 }, + }, + }, + { + { + { 9923462, 11271500, 12616794, 3544722, -29998368, -1721626, 12891687, -8193132, -26442943, 10486144 }, + { -22597207, -7012665, 8587003, -8257861, 4084309, -12970062, 361726, 2610596, -23921530, -11455195 }, + { 5408411, -1136691, -4969122, 10561668, 24145918, 14240566, 31319731, -4235541, 19985175, -3436086 }, + }, + { + { -13994457, 16616821, 14549246, 3341099, 32155958, 13648976, -17577068, 8849297, 65030, 8370684 }, + { -8320926, -12049626, 31204563, 5839400, -20627288, -1057277, -19442942, 6922164, 12743482, -9800518 }, + { -2361371, 12678785, 28815050, 4759974, -23893047, 4884717, 23783145, 11038569, 18800704, 255233 }, + }, + { + { -5269658, -1773886, 13957886, 7990715, 23132995, 728773, 13393847, 9066957, 19258688, -14753793 }, + { -2936654, -10827535, -10432089, 14516793, -3640786, 4372541, -31934921, 2209390, -1524053, 2055794 }, + { 580882, 16705327, 5468415, -2683018, -30926419, -14696000, -7203346, -8994389, -30021019, 7394435 }, + }, + { + { 23838809, 1822728, -15738443, 15242727, 8318092, -3733104, -21672180, -3492205, -4821741, 14799921 }, + { 13345610, 9759151, 3371034, -16137791, 16353039, 8577942, 31129804, 13496856, -9056018, 7402518 }, + { 2286874, -4435931, -20042458, -2008336, -13696227, 5038122, 11006906, -15760352, 8205061, 1607563 }, + }, + { + { 14414086, -8002132, 3331830, -3208217, 22249151, -5594188, 18364661, -2906958, 30019587, -9029278 }, + { -27688051, 1585953, -10775053, 931069, -29120221, -11002319, -14410829, 12029093, 9944378, 8024 }, + { 4368715, -3709630, 29874200, -15022983, -20230386, -11410704, -16114594, -999085, -8142388, 5640030 }, + }, + { + { 10299610, 13746483, 11661824, 16234854, 7630238, 5998374, 9809887, -16694564, 15219798, -14327783 }, + { 27425505, -5719081, 3055006, 10660664, 23458024, 595578, -15398605, -1173195, -18342183, 9742717 }, + { 6744077, 2427284, 26042789, 2720740, -847906, 1118974, 32324614, 7406442, 12420155, 1994844 }, + }, + { + { 14012521, -5024720, -18384453, -9578469, -26485342, -3936439, -13033478, -10909803, 24319929, -6446333 }, + { 16412690, -4507367, 10772641, 15929391, -17068788, -4658621, 10555945, -10484049, -30102368, -4739048 }, + { 22397382, -7767684, -9293161, -12792868, 17166287, -9755136, -27333065, 6199366, 21880021, -12250760 }, + }, + { + { -4283307, 5368523, -31117018, 8163389, -30323063, 3209128, 16557151, 8890729, 8840445, 4957760 }, + { -15447727, 709327, -6919446, -10870178, -29777922, 6522332, -21720181, 12130072, -14796503, 5005757 }, + { -2114751, -14308128, 23019042, 15765735, -25269683, 6002752, 10183197, -13239326, -16395286, -2176112 }, + }, + }, + { + { + { -19025756, 1632005, 13466291, -7995100, -23640451, 16573537, -32013908, -3057104, 22208662, 2000468 }, + { 3065073, -1412761, -25598674, -361432, -17683065, -5703415, -8164212, 11248527, -3691214, -7414184 }, + { 10379208, -6045554, 8877319, 1473647, -29291284, -12507580, 16690915, 2553332, -3132688, 16400289 }, + }, + { + { 15716668, 1254266, -18472690, 7446274, -8448918, 6344164, -22097271, -7285580, 26894937, 9132066 }, + { 24158887, 12938817, 11085297, -8177598, -28063478, -4457083, -30576463, 64452, -6817084, -2692882 }, + { 13488534, 7794716, 22236231, 5989356, 25426474, -12578208, 2350710, -3418511, -4688006, 2364226 }, + }, + { + { 16335052, 9132434, 25640582, 6678888, 1725628, 8517937, -11807024, -11697457, 15445875, -7798101 }, + { 29004207, -7867081, 28661402, -640412, -12794003, -7943086, 31863255, -4135540, -278050, -15759279 }, + { -6122061, -14866665, -28614905, 14569919, -10857999, -3591829, 10343412, -6976290, -29828287, -10815811 }, + }, + { + { 27081650, 3463984, 14099042, -4517604, 1616303, -6205604, 29542636, 15372179, 17293797, 960709 }, + { 20263915, 11434237, -5765435, 11236810, 13505955, -10857102, -16111345, 6493122, -19384511, 7639714 }, + { -2830798, -14839232, 25403038, -8215196, -8317012, -16173699, 18006287, -16043750, 29994677, -15808121 }, + }, + { + { 9769828, 5202651, -24157398, -13631392, -28051003, -11561624, -24613141, -13860782, -31184575, 709464 }, + { 12286395, 13076066, -21775189, -1176622, -25003198, 4057652, -32018128, -8890874, 16102007, 13205847 }, + { 13733362, 5599946, 10557076, 3195751, -5557991, 8536970, -25540170, 8525972, 10151379, 10394400 }, + }, + { + { 4024660, -16137551, 22436262, 12276534, -9099015, -2686099, 19698229, 11743039, -33302334, 8934414 }, + { -15879800, -4525240, -8580747, -2934061, 14634845, -698278, -9449077, 3137094, -11536886, 11721158 }, + { 17555939, -5013938, 8268606, 2331751, -22738815, 9761013, 9319229, 8835153, -9205489, -1280045 }, + }, + { + { -461409, -7830014, 20614118, 16688288, -7514766, -4807119, 22300304, 505429, 6108462, -6183415 }, + { -5070281, 12367917, -30663534, 3234473, 32617080, -8422642, 29880583, -13483331, -26898490, -7867459 }, + { -31975283, 5726539, 26934134, 10237677, -3173717, -605053, 24199304, 3795095, 7592688, -14992079 }, + }, + { + { 21594432, -14964228, 17466408, -4077222, 32537084, 2739898, 6407723, 12018833, -28256052, 4298412 }, + { -20650503, -11961496, -27236275, 570498, 3767144, -1717540, 13891942, -1569194, 13717174, 10805743 }, + { -14676630, -15644296, 15287174, 11927123, 24177847, -8175568, -796431, 14860609, -26938930, -5863836 }, + }, + }, + { + { + { 12962541, 5311799, -10060768, 11658280, 18855286, -7954201, 13286263, -12808704, -4381056, 9882022 }, + { 18512079, 11319350, -20123124, 15090309, 18818594, 5271736, -22727904, 3666879, -23967430, -3299429 }, + { -6789020, -3146043, 16192429, 13241070, 15898607, -14206114, -10084880, -6661110, -2403099, 5276065 }, + }, + { + { 30169808, -5317648, 26306206, -11750859, 27814964, 7069267, 7152851, 3684982, 1449224, 13082861 }, + { 10342826, 3098505, 2119311, 193222, 25702612, 12233820, 23697382, 15056736, -21016438, -8202000 }, + { -33150110, 3261608, 22745853, 7948688, 19370557, -15177665, -26171976, 6482814, -10300080, -11060101 }, + }, + { + { 32869458, -5408545, 25609743, 15678670, -10687769, -15471071, 26112421, 2521008, -22664288, 6904815 }, + { 29506923, 4457497, 3377935, -9796444, -30510046, 12935080, 1561737, 3841096, -29003639, -6657642 }, + { 10340844, -6630377, -18656632, -2278430, 12621151, -13339055, 30878497, -11824370, -25584551, 5181966 }, + }, + { + { 25940115, -12658025, 17324188, -10307374, -8671468, 15029094, 24396252, -16450922, -2322852, -12388574 }, + { -21765684, 9916823, -1300409, 4079498, -1028346, 11909559, 1782390, 12641087, 20603771, -6561742 }, + { -18882287, -11673380, 24849422, 11501709, 13161720, -4768874, 1925523, 11914390, 4662781, 7820689 }, + }, + { + { 12241050, -425982, 8132691, 9393934, 32846760, -1599620, 29749456, 12172924, 16136752, 15264020 }, + { -10349955, -14680563, -8211979, 2330220, -17662549, -14545780, 10658213, 6671822, 19012087, 3772772 }, + { 3753511, -3421066, 10617074, 2028709, 14841030, -6721664, 28718732, -15762884, 20527771, 12988982 }, + }, + { + { -14822485, -5797269, -3707987, 12689773, -898983, -10914866, -24183046, -10564943, 3299665, -12424953 }, + { -16777703, -15253301, -9642417, 4978983, 3308785, 8755439, 6943197, 6461331, -25583147, 8991218 }, + { -17226263, 1816362, -1673288, -6086439, 31783888, -8175991, -32948145, 7417950, -30242287, 1507265 }, + }, + { + { 29692663, 6829891, -10498800, 4334896, 20945975, -11906496, -28887608, 8209391, 14606362, -10647073 }, + { -3481570, 8707081, 32188102, 5672294, 22096700, 1711240, -33020695, 9761487, 4170404, -2085325 }, + { -11587470, 14855945, -4127778, -1531857, -26649089, 15084046, 22186522, 16002000, -14276837, -8400798 }, + }, + { + { -4811456, 13761029, -31703877, -2483919, -3312471, 7869047, -7113572, -9620092, 13240845, 10965870 }, + { -7742563, -8256762, -14768334, -13656260, -23232383, 12387166, 4498947, 14147411, 29514390, 4302863 }, + { -13413405, -12407859, 20757302, -13801832, 14785143, 8976368, -5061276, -2144373, 17846988, -13971927 }, + }, + }, + { + { + { -2244452, -754728, -4597030, -1066309, -6247172, 1455299, -21647728, -9214789, -5222701, 12650267 }, + { -9906797, -16070310, 21134160, 12198166, -27064575, 708126, 387813, 13770293, -19134326, 10958663 }, + { 22470984, 12369526, 23446014, -5441109, -21520802, -9698723, -11772496, -11574455, -25083830, 4271862 }, + }, + { + { -25169565, -10053642, -19909332, 15361595, -5984358, 2159192, 75375, -4278529, -32526221, 8469673 }, + { 15854970, 4148314, -8893890, 7259002, 11666551, 13824734, -30531198, 2697372, 24154791, -9460943 }, + { 15446137, -15806644, 29759747, 14019369, 30811221, -9610191, -31582008, 12840104, 24913809, 9815020 }, + }, + { + { -4709286, -5614269, -31841498, -12288893, -14443537, 10799414, -9103676, 13438769, 18735128, 9466238 }, + { 11933045, 9281483, 5081055, -5183824, -2628162, -4905629, -7727821, -10896103, -22728655, 16199064 }, + { 14576810, 379472, -26786533, -8317236, -29426508, -10812974, -102766, 1876699, 30801119, 2164795 }, + }, + { + { 15995086, 3199873, 13672555, 13712240, -19378835, -4647646, -13081610, -15496269, -13492807, 1268052 }, + { -10290614, -3659039, -3286592, 10948818, 23037027, 3794475, -3470338, -12600221, -17055369, 3565904 }, + { 29210088, -9419337, -5919792, -4952785, 10834811, -13327726, -16512102, -10820713, -27162222, -14030531 }, + }, + { + { -13161890, 15508588, 16663704, -8156150, -28349942, 9019123, -29183421, -3769423, 2244111, -14001979 }, + { -5152875, -3800936, -9306475, -6071583, 16243069, 14684434, -25673088, -16180800, 13491506, 4641841 }, + { 10813417, 643330, -19188515, -728916, 30292062, -16600078, 27548447, -7721242, 14476989, -12767431 }, + }, + { + { 10292079, 9984945, 6481436, 8279905, -7251514, 7032743, 27282937, -1644259, -27912810, 12651324 }, + { -31185513, -813383, 22271204, 11835308, 10201545, 15351028, 17099662, 3988035, 21721536, -3148940 }, + { 10202177, -6545839, -31373232, -9574638, -32150642, -8119683, -12906320, 3852694, 13216206, 14842320 }, + }, + { + { -15815640, -10601066, -6538952, -7258995, -6984659, -6581778, -31500847, 13765824, -27434397, 9900184 }, + { 14465505, -13833331, -32133984, -14738873, -27443187, 12990492, 33046193, 15796406, -7051866, -8040114 }, + { 30924417, -8279620, 6359016, -12816335, 16508377, 9071735, -25488601, 15413635, 9524356, -7018878 }, + }, + { + { 12274201, -13175547, 32627641, -1785326, 6736625, 13267305, 5237659, -5109483, 15663516, 4035784 }, + { -2951309, 8903985, 17349946, 601635, -16432815, -4612556, -13732739, -15889334, -22258478, 4659091 }, + { -16916263, -4952973, -30393711, -15158821, 20774812, 15897498, 5736189, 15026997, -2178256, -13455585 }, + }, + }, + { + { + { -8858980, -2219056, 28571666, -10155518, -474467, -10105698, -3801496, 278095, 23440562, -290208 }, + { 10226241, -5928702, 15139956, 120818, -14867693, 5218603, 32937275, 11551483, -16571960, -7442864 }, + { 17932739, -12437276, -24039557, 10749060, 11316803, 7535897, 22503767, 5561594, -3646624, 3898661 }, + }, + { + { 7749907, -969567, -16339731, -16464, -25018111, 15122143, -1573531, 7152530, 21831162, 1245233 }, + { 26958459, -14658026, 4314586, 8346991, -5677764, 11960072, -32589295, -620035, -30402091, -16716212 }, + { -12165896, 9166947, 33491384, 13673479, 29787085, 13096535, 6280834, 14587357, -22338025, 13987525 }, + }, + { + { -24349909, 7778775, 21116000, 15572597, -4833266, -5357778, -4300898, -5124639, -7469781, -2858068 }, + { 9681908, -6737123, -31951644, 13591838, -6883821, 386950, 31622781, 6439245, -14581012, 4091397 }, + { -8426427, 1470727, -28109679, -1596990, 3978627, -5123623, -19622683, 12092163, 29077877, -14741988 }, + }, + { + { 5269168, -6859726, -13230211, -8020715, 25932563, 1763552, -5606110, -5505881, -20017847, 2357889 }, + { 32264008, -15407652, -5387735, -1160093, -2091322, -3946900, 23104804, -12869908, 5727338, 189038 }, + { 14609123, -8954470, -6000566, -16622781, -14577387, -7743898, -26745169, 10942115, -25888931, -14884697 }, + }, + { + { 20513500, 5557931, -15604613, 7829531, 26413943, -2019404, -21378968, 7471781, 13913677, -5137875 }, + { -25574376, 11967826, 29233242, 12948236, -6754465, 4713227, -8940970, 14059180, 12878652, 8511905 }, + { -25656801, 3393631, -2955415, -7075526, -2250709, 9366908, -30223418, 6812974, 5568676, -3127656 }, + }, + { + { 11630004, 12144454, 2116339, 13606037, 27378885, 15676917, -17408753, -13504373, -14395196, 8070818 }, + { 27117696, -10007378, -31282771, -5570088, 1127282, 12772488, -29845906, 10483306, -11552749, -1028714 }, + { 10637467, -5688064, 5674781, 1072708, -26343588, -6982302, -1683975, 9177853, -27493162, 15431203 }, + }, + { + { 20525145, 10892566, -12742472, 12779443, -29493034, 16150075, -28240519, 14943142, -15056790, -7935931 }, + { -30024462, 5626926, -551567, -9981087, 753598, 11981191, 25244767, -3239766, -3356550, 9594024 }, + { -23752644, 2636870, -5163910, -10103818, 585134, 7877383, 11345683, -6492290, 13352335, -10977084 }, + }, + { + { -1931799, -5407458, 3304649, -12884869, 17015806, -4877091, -29783850, -7752482, -13215537, -319204 }, + { 20239939, 6607058, 6203985, 3483793, -18386976, -779229, -20723742, 15077870, -22750759, 14523817 }, + { 27406042, -6041657, 27423596, -4497394, 4996214, 10002360, -28842031, -4545494, -30172742, -4805667 }, + }, + }, + { + { + { 11374242, 12660715, 17861383, -12540833, 10935568, 1099227, -13886076, -9091740, -27727044, 11358504 }, + { -12730809, 10311867, 1510375, 10778093, -2119455, -9145702, 32676003, 11149336, -26123651, 4985768 }, + { -19096303, 341147, -6197485, -239033, 15756973, -8796662, -983043, 13794114, -19414307, -15621255 }, + }, + { + { 6490081, 11940286, 25495923, -7726360, 8668373, -8751316, 3367603, 6970005, -1691065, -9004790 }, + { 1656497, 13457317, 15370807, 6364910, 13605745, 8362338, -19174622, -5475723, -16796596, -5031438 }, + { -22273315, -13524424, -64685, -4334223, -18605636, -10921968, -20571065, -7007978, -99853, -10237333 }, + }, + { + { 17747465, 10039260, 19368299, -4050591, -20630635, -16041286, 31992683, -15857976, -29260363, -5511971 }, + { 31932027, -4986141, -19612382, 16366580, 22023614, 88450, 11371999, -3744247, 4882242, -10626905 }, + { 29796507, 37186, 19818052, 10115756, -11829032, 3352736, 18551198, 3272828, -5190932, -4162409 }, + }, + { + { 12501286, 4044383, -8612957, -13392385, -32430052, 5136599, -19230378, -3529697, 330070, -3659409 }, + { 6384877, 2899513, 17807477, 7663917, -2358888, 12363165, 25366522, -8573892, -271295, 12071499 }, + { -8365515, -4042521, 25133448, -4517355, -6211027, 2265927, -32769618, 1936675, -5159697, 3829363 }, + }, + { + { 28425966, -5835433, -577090, -4697198, -14217555, 6870930, 7921550, -6567787, 26333140, 14267664 }, + { -11067219, 11871231, 27385719, -10559544, -4585914, -11189312, 10004786, -8709488, -21761224, 8930324 }, + { -21197785, -16396035, 25654216, -1725397, 12282012, 11008919, 1541940, 4757911, -26491501, -16408940 }, + }, + { + { 13537262, -7759490, -20604840, 10961927, -5922820, -13218065, -13156584, 6217254, -15943699, 13814990 }, + { -17422573, 15157790, 18705543, 29619, 24409717, -260476, 27361681, 9257833, -1956526, -1776914 }, + { -25045300, -10191966, 15366585, 15166509, -13105086, 8423556, -29171540, 12361135, -18685978, 4578290 }, + }, + { + { 24579768, 3711570, 1342322, -11180126, -27005135, 14124956, -22544529, 14074919, 21964432, 8235257 }, + { -6528613, -2411497, 9442966, -5925588, 12025640, -1487420, -2981514, -1669206, 13006806, 2355433 }, + { -16304899, -13605259, -6632427, -5142349, 16974359, -10911083, 27202044, 1719366, 1141648, -12796236 }, + }, + { + { -12863944, -13219986, -8318266, -11018091, -6810145, -4843894, 13475066, -3133972, 32674895, 13715045 }, + { 11423335, -5468059, 32344216, 8962751, 24989809, 9241752, -13265253, 16086212, -28740881, -15642093 }, + { -1409668, 12530728, -6368726, 10847387, 19531186, -14132160, -11709148, 7791794, -27245943, 4383347 }, + }, + }, + { + { + { -28970898, 5271447, -1266009, -9736989, -12455236, 16732599, -4862407, -4906449, 27193557, 6245191 }, + { -15193956, 5362278, -1783893, 2695834, 4960227, 12840725, 23061898, 3260492, 22510453, 8577507 }, + { -12632451, 11257346, -32692994, 13548177, -721004, 10879011, 31168030, 13952092, -29571492, -3635906 }, + }, + { + { 3877321, -9572739, 32416692, 5405324, -11004407, -13656635, 3759769, 11935320, 5611860, 8164018 }, + { -16275802, 14667797, 15906460, 12155291, -22111149, -9039718, 32003002, -8832289, 5773085, -8422109 }, + { -23788118, -8254300, 1950875, 8937633, 18686727, 16459170, -905725, 12376320, 31632953, 190926 }, + }, + { + { -24593607, -16138885, -8423991, 13378746, 14162407, 6901328, -8288749, 4508564, -25341555, -3627528 }, + { 8884438, -5884009, 6023974, 10104341, -6881569, -4941533, 18722941, -14786005, -1672488, 827625 }, + { -32720583, -16289296, -32503547, 7101210, 13354605, 2659080, -1800575, -14108036, -24878478, 1541286 }, + }, + { + { 2901347, -1117687, 3880376, -10059388, -17620940, -3612781, -21802117, -3567481, 20456845, -1885033 }, + { 27019610, 12299467, -13658288, -1603234, -12861660, -4861471, -19540150, -5016058, 29439641, 15138866 }, + { 21536104, -6626420, -32447818, -10690208, -22408077, 5175814, -5420040, -16361163, 7779328, 109896 }, + }, + { + { 30279744, 14648750, -8044871, 6425558, 13639621, -743509, 28698390, 12180118, 23177719, -554075 }, + { 26572847, 3405927, -31701700, 12890905, -19265668, 5335866, -6493768, 2378492, 4439158, -13279347 }, + { -22716706, 3489070, -9225266, -332753, 18875722, -1140095, 14819434, -12731527, -17717757, -5461437 }, + }, + { + { -5056483, 16566551, 15953661, 3767752, -10436499, 15627060, -820954, 2177225, 8550082, -15114165 }, + { -18473302, 16596775, -381660, 15663611, 22860960, 15585581, -27844109, -3582739, -23260460, -8428588 }, + { -32480551, 15707275, -8205912, -5652081, 29464558, 2713815, -22725137, 15860482, -21902570, 1494193 }, + }, + { + { -19562091, -14087393, -25583872, -9299552, 13127842, 759709, 21923482, 16529112, 8742704, 12967017 }, + { -28464899, 1553205, 32536856, -10473729, -24691605, -406174, -8914625, -2933896, -29903758, 15553883 }, + { 21877909, 3230008, 9881174, 10539357, -4797115, 2841332, 11543572, 14513274, 19375923, -12647961 }, + }, + { + { 8832269, -14495485, 13253511, 5137575, 5037871, 4078777, 24880818, -6222716, 2862653, 9455043 }, + { 29306751, 5123106, 20245049, -14149889, 9592566, 8447059, -2077124, -2990080, 15511449, 4789663 }, + { -20679756, 7004547, 8824831, -9434977, -4045704, -3750736, -5754762, 108893, 23513200, 16652362 }, + }, + }, + { + { + { -33256173, 4144782, -4476029, -6579123, 10770039, -7155542, -6650416, -12936300, -18319198, 10212860 }, + { 2756081, 8598110, 7383731, -6859892, 22312759, -1105012, 21179801, 2600940, -9988298, -12506466 }, + { -24645692, 13317462, -30449259, -15653928, 21365574, -10869657, 11344424, 864440, -2499677, -16710063 }, + }, + { + { -26432803, 6148329, -17184412, -14474154, 18782929, -275997, -22561534, 211300, 2719757, 4940997 }, + { -1323882, 3911313, -6948744, 14759765, -30027150, 7851207, 21690126, 8518463, 26699843, 5276295 }, + { -13149873, -6429067, 9396249, 365013, 24703301, -10488939, 1321586, 149635, -15452774, 7159369 }, + }, + { + { 9987780, -3404759, 17507962, 9505530, 9731535, -2165514, 22356009, 8312176, 22477218, -8403385 }, + { 18155857, -16504990, 19744716, 9006923, 15154154, -10538976, 24256460, -4864995, -22548173, 9334109 }, + { 2986088, -4911893, 10776628, -3473844, 10620590, -7083203, -21413845, 14253545, -22587149, 536906 }, + }, + { + { 4377756, 8115836, 24567078, 15495314, 11625074, 13064599, 7390551, 10589625, 10838060, -15420424 }, + { -19342404, 867880, 9277171, -3218459, -14431572, -1986443, 19295826, -15796950, 6378260, 699185 }, + { 7895026, 4057113, -7081772, -13077756, -17886831, -323126, -716039, 15693155, -5045064, -13373962 }, + }, + { + { -7737563, -5869402, -14566319, -7406919, 11385654, 13201616, 31730678, -10962840, -3918636, -9669325 }, + { 10188286, -15770834, -7336361, 13427543, 22223443, 14896287, 30743455, 7116568, -21786507, 5427593 }, + { 696102, 13206899, 27047647, -10632082, 15285305, -9853179, 10798490, -4578720, 19236243, 12477404 }, + }, + { + { -11229439, 11243796, -17054270, -8040865, -788228, -8167967, -3897669, 11180504, -23169516, 7733644 }, + { 17800790, -14036179, -27000429, -11766671, 23887827, 3149671, 23466177, -10538171, 10322027, 15313801 }, + { 26246234, 11968874, 32263343, -5468728, 6830755, -13323031, -15794704, -101982, -24449242, 10890804 }, + }, + { + { -31365647, 10271363, -12660625, -6267268, 16690207, -13062544, -14982212, 16484931, 25180797, -5334884 }, + { -586574, 10376444, -32586414, -11286356, 19801893, 10997610, 2276632, 9482883, 316878, 13820577 }, + { -9882808, -4510367, -2115506, 16457136, -11100081, 11674996, 30756178, -7515054, 30696930, -3712849 }, + }, + { + { 32988917, -9603412, 12499366, 7910787, -10617257, -11931514, -7342816, -9985397, -32349517, 7392473 }, + { -8855661, 15927861, 9866406, -3649411, -2396914, -16655781, -30409476, -9134995, 25112947, -2926644 }, + { -2504044, -436966, 25621774, -5678772, 15085042, -5479877, -24884878, -13526194, 5537438, -13914319 }, + }, + }, + { + { + { -11225584, 2320285, -9584280, 10149187, -33444663, 5808648, -14876251, -1729667, 31234590, 6090599 }, + { -9633316, 116426, 26083934, 2897444, -6364437, -2688086, 609721, 15878753, -6970405, -9034768 }, + { -27757857, 247744, -15194774, -9002551, 23288161, -10011936, -23869595, 6503646, 20650474, 1804084 }, + }, + { + { -27589786, 15456424, 8972517, 8469608, 15640622, 4439847, 3121995, -10329713, 27842616, -202328 }, + { -15306973, 2839644, 22530074, 10026331, 4602058, 5048462, 28248656, 5031932, -11375082, 12714369 }, + { 20807691, -7270825, 29286141, 11421711, -27876523, -13868230, -21227475, 1035546, -19733229, 12796920 }, + }, + { + { 12076899, -14301286, -8785001, -11848922, -25012791, 16400684, -17591495, -12899438, 3480665, -15182815 }, + { -32361549, 5457597, 28548107, 7833186, 7303070, -11953545, -24363064, -15921875, -33374054, 2771025 }, + { -21389266, 421932, 26597266, 6860826, 22486084, -6737172, -17137485, -4210226, -24552282, 15673397 }, + }, + { + { -20184622, 2338216, 19788685, -9620956, -4001265, -8740893, -20271184, 4733254, 3727144, -12934448 }, + { 6120119, 814863, -11794402, -622716, 6812205, -15747771, 2019594, 7975683, 31123697, -10958981 }, + { 30069250, -11435332, 30434654, 2958439, 18399564, -976289, 12296869, 9204260, -16432438, 9648165 }, + }, + { + { 32705432, -1550977, 30705658, 7451065, -11805606, 9631813, 3305266, 5248604, -26008332, -11377501 }, + { 17219865, 2375039, -31570947, -5575615, -19459679, 9219903, 294711, 15298639, 2662509, -16297073 }, + { -1172927, -7558695, -4366770, -4287744, -21346413, -8434326, 32087529, -1222777, 32247248, -14389861 }, + }, + { + { 14312628, 1221556, 17395390, -8700143, -4945741, -8684635, -28197744, -9637817, -16027623, -13378845 }, + { -1428825, -9678990, -9235681, 6549687, -7383069, -468664, 23046502, 9803137, 17597934, 2346211 }, + { 18510800, 15337574, 26171504, 981392, -22241552, 7827556, -23491134, -11323352, 3059833, -11782870 }, + }, + { + { 10141598, 6082907, 17829293, -1947643, 9830092, 13613136, -25556636, -5544586, -33502212, 3592096 }, + { 33114168, -15889352, -26525686, -13343397, 33076705, 8716171, 1151462, 1521897, -982665, -6837803 }, + { -32939165, -4255815, 23947181, -324178, -33072974, -12305637, -16637686, 3891704, 26353178, 693168 }, + }, + { + { 30374239, 1595580, -16884039, 13186931, 4600344, 406904, 9585294, -400668, 31375464, 14369965 }, + { -14370654, -7772529, 1510301, 6434173, -18784789, -6262728, 32732230, -13108839, 17901441, 16011505 }, + { 18171223, -11934626, -12500402, 15197122, -11038147, -15230035, -19172240, -16046376, 8764035, 12309598 }, + }, + }, + { + { + { 5975908, -5243188, -19459362, -9681747, -11541277, 14015782, -23665757, 1228319, 17544096, -10593782 }, + { 5811932, -1715293, 3442887, -2269310, -18367348, -8359541, -18044043, -15410127, -5565381, 12348900 }, + { -31399660, 11407555, 25755363, 6891399, -3256938, 14872274, -24849353, 8141295, -10632534, -585479 }, + }, + { + { -12675304, 694026, -5076145, 13300344, 14015258, -14451394, -9698672, -11329050, 30944593, 1130208 }, + { 8247766, -6710942, -26562381, -7709309, -14401939, -14648910, 4652152, 2488540, 23550156, -271232 }, + { 17294316, -3788438, 7026748, 15626851, 22990044, 113481, 2267737, -5908146, -408818, -137719 }, + }, + { + { 16091085, -16253926, 18599252, 7340678, 2137637, -1221657, -3364161, 14550936, 3260525, -7166271 }, + { -4910104, -13332887, 18550887, 10864893, -16459325, -7291596, -23028869, -13204905, -12748722, 2701326 }, + { -8574695, 16099415, 4629974, -16340524, -20786213, -6005432, -10018363, 9276971, 11329923, 1862132 }, + }, + { + { 14763076, -15903608, -30918270, 3689867, 3511892, 10313526, -21951088, 12219231, -9037963, -940300 }, + { 8894987, -3446094, 6150753, 3013931, 301220, 15693451, -31981216, -2909717, -15438168, 11595570 }, + { 15214962, 3537601, -26238722, -14058872, 4418657, -15230761, 13947276, 10730794, -13489462, -4363670 }, + }, + { + { -2538306, 7682793, 32759013, 263109, -29984731, -7955452, -22332124, -10188635, 977108, 699994 }, + { -12466472, 4195084, -9211532, 550904, -15565337, 12917920, 19118110, -439841, -30534533, -14337913 }, + { 31788461, -14507657, 4799989, 7372237, 8808585, -14747943, 9408237, -10051775, 12493932, -5409317 }, + }, + { + { -25680606, 5260744, -19235809, -6284470, -3695942, 16566087, 27218280, 2607121, 29375955, 6024730 }, + { 842132, -2794693, -4763381, -8722815, 26332018, -12405641, 11831880, 6985184, -9940361, 2854096 }, + { -4847262, -7969331, 2516242, -5847713, 9695691, -7221186, 16512645, 960770, 12121869, 16648078 }, + }, + { + { -15218652, 14667096, -13336229, 2013717, 30598287, -464137, -31504922, -7882064, 20237806, 2838411 }, + { -19288047, 4453152, 15298546, -16178388, 22115043, -15972604, 12544294, -13470457, 1068881, -12499905 }, + { -9558883, -16518835, 33238498, 13506958, 30505848, -1114596, -8486907, -2630053, 12521378, 4845654 }, + }, + { + { -28198521, 10744108, -2958380, 10199664, 7759311, -13088600, 3409348, -873400, -6482306, -12885870 }, + { -23561822, 6230156, -20382013, 10655314, -24040585, -11621172, 10477734, -1240216, -3113227, 13974498 }, + { 12966261, 15550616, -32038948, -1615346, 21025980, -629444, 5642325, 7188737, 18895762, 12629579 }, + }, + }, + { + { + { 14741879, -14946887, 22177208, -11721237, 1279741, 8058600, 11758140, 789443, 32195181, 3895677 }, + { 10758205, 15755439, -4509950, 9243698, -4879422, 6879879, -2204575, -3566119, -8982069, 4429647 }, + { -2453894, 15725973, -20436342, -10410672, -5803908, -11040220, -7135870, -11642895, 18047436, -15281743 }, + }, + { + { -25173001, -11307165, 29759956, 11776784, -22262383, -15820455, 10993114, -12850837, -17620701, -9408468 }, + { 21987233, 700364, -24505048, 14972008, -7774265, -5718395, 32155026, 2581431, -29958985, 8773375 }, + { -25568350, 454463, -13211935, 16126715, 25240068, 8594567, 20656846, 12017935, -7874389, -13920155 }, + }, + { + { 6028182, 6263078, -31011806, -11301710, -818919, 2461772, -31841174, -5468042, -1721788, -2776725 }, + { -12278994, 16624277, 987579, -5922598, 32908203, 1248608, 7719845, -4166698, 28408820, 6816612 }, + { -10358094, -8237829, 19549651, -12169222, 22082623, 16147817, 20613181, 13982702, -10339570, 5067943 }, + }, + { + { -30505967, -3821767, 12074681, 13582412, -19877972, 2443951, -19719286, 12746132, 5331210, -10105944 }, + { 30528811, 3601899, -1957090, 4619785, -27361822, -15436388, 24180793, -12570394, 27679908, -1648928 }, + { 9402404, -13957065, 32834043, 10838634, -26580150, -13237195, 26653274, -8685565, 22611444, -12715406 }, + }, + { + { 22190590, 1118029, 22736441, 15130463, -30460692, -5991321, 19189625, -4648942, 4854859, 6622139 }, + { -8310738, -2953450, -8262579, -3388049, -10401731, -271929, 13424426, -3567227, 26404409, 13001963 }, + { -31241838, -15415700, -2994250, 8939346, 11562230, -12840670, -26064365, -11621720, -15405155, 11020693 }, + }, + { + { 1866042, -7949489, -7898649, -10301010, 12483315, 13477547, 3175636, -12424163, 28761762, 1406734 }, + { -448555, -1777666, 13018551, 3194501, -9580420, -11161737, 24760585, -4347088, 25577411, -13378680 }, + { -24290378, 4759345, -690653, -1852816, 2066747, 10693769, -29595790, 9884936, -9368926, 4745410 }, + }, + { + { -9141284, 6049714, -19531061, -4341411, -31260798, 9944276, -15462008, -11311852, 10931924, -11931931 }, + { -16561513, 14112680, -8012645, 4817318, -8040464, -11414606, -22853429, 10856641, -20470770, 13434654 }, + { 22759489, -10073434, -16766264, -1871422, 13637442, -10168091, 1765144, -12654326, 28445307, -5364710 }, + }, + { + { 29875063, 12493613, 2795536, -3786330, 1710620, 15181182, -10195717, -8788675, 9074234, 1167180 }, + { -26205683, 11014233, -9842651, -2635485, -26908120, 7532294, -18716888, -9535498, 3843903, 9367684 }, + { -10969595, -6403711, 9591134, 9582310, 11349256, 108879, 16235123, 8601684, -139197, 4242895 }, + }, + }, + { + { + { 22092954, -13191123, -2042793, -11968512, 32186753, -11517388, -6574341, 2470660, -27417366, 16625501 }, + { -11057722, 3042016, 13770083, -9257922, 584236, -544855, -7770857, 2602725, -27351616, 14247413 }, + { 6314175, -10264892, -32772502, 15957557, -10157730, 168750, -8618807, 14290061, 27108877, -1180880 }, + }, + { + { -8586597, -7170966, 13241782, 10960156, -32991015, -13794596, 33547976, -11058889, -27148451, 981874 }, + { 22833440, 9293594, -32649448, -13618667, -9136966, 14756819, -22928859, -13970780, -10479804, -16197962 }, + { -7768587, 3326786, -28111797, 10783824, 19178761, 14905060, 22680049, 13906969, -15933690, 3797899 }, + }, + { + { 21721356, -4212746, -12206123, 9310182, -3882239, -13653110, 23740224, -2709232, 20491983, -8042152 }, + { 9209270, -15135055, -13256557, -6167798, -731016, 15289673, 25947805, 15286587, 30997318, -6703063 }, + { 7392032, 16618386, 23946583, -8039892, -13265164, -1533858, -14197445, -2321576, 17649998, -250080 }, + }, + { + { -9301088, -14193827, 30609526, -3049543, -25175069, -1283752, -15241566, -9525724, -2233253, 7662146 }, + { -17558673, 1763594, -33114336, 15908610, -30040870, -12174295, 7335080, -8472199, -3174674, 3440183 }, + { -19889700, -5977008, -24111293, -9688870, 10799743, -16571957, 40450, -4431835, 4862400, 1133 }, + }, + { + { -32856209, -7873957, -5422389, 14860950, -16319031, 7956142, 7258061, 311861, -30594991, -7379421 }, + { -3773428, -1565936, 28985340, 7499440, 24445838, 9325937, 29727763, 16527196, 18278453, 15405622 }, + { -4381906, 8508652, -19898366, -3674424, -5984453, 15149970, -13313598, 843523, -21875062, 13626197 }, + }, + { + { 2281448, -13487055, -10915418, -2609910, 1879358, 16164207, -10783882, 3953792, 13340839, 15928663 }, + { 31727126, -7179855, -18437503, -8283652, 2875793, -16390330, -25269894, -7014826, -23452306, 5964753 }, + { 4100420, -5959452, -17179337, 6017714, -18705837, 12227141, -26684835, 11344144, 2538215, -7570755 }, + }, + { + { -9433605, 6123113, 11159803, -2156608, 30016280, 14966241, -20474983, 1485421, -629256, -15958862 }, + { -26804558, 4260919, 11851389, 9658551, -32017107, 16367492, -20205425, -13191288, 11659922, -11115118 }, + { 26180396, 10015009, -30844224, -8581293, 5418197, 9480663, 2231568, -10170080, 33100372, -1306171 }, + }, + { + { 15121113, -5201871, -10389905, 15427821, -27509937, -15992507, 21670947, 4486675, -5931810, -14466380 }, + { 16166486, -9483733, -11104130, 6023908, -31926798, -1364923, 2340060, -16254968, -10735770, -10039824 }, + { 28042865, -3557089, -12126526, 12259706, -3717498, -6945899, 6766453, -8689599, 18036436, 5803270 }, + }, + }, + { + { + { -817581, 6763912, 11803561, 1585585, 10958447, -2671165, 23855391, 4598332, -6159431, -14117438 }, + { -31031306, -14256194, 17332029, -2383520, 31312682, -5967183, 696309, 50292, -20095739, 11763584 }, + { -594563, -2514283, -32234153, 12643980, 12650761, 14811489, 665117, -12613632, -19773211, -10713562 }, + }, + { + { 30464590, -11262872, -4127476, -12734478, 19835327, -7105613, -24396175, 2075773, -17020157, 992471 }, + { 18357185, -6994433, 7766382, 16342475, -29324918, 411174, 14578841, 8080033, -11574335, -10601610 }, + { 19598397, 10334610, 12555054, 2555664, 18821899, -10339780, 21873263, 16014234, 26224780, 16452269 }, + }, + { + { -30223925, 5145196, 5944548, 16385966, 3976735, 2009897, -11377804, -7618186, -20533829, 3698650 }, + { 14187449, 3448569, -10636236, -10810935, -22663880, -3433596, 7268410, -10890444, 27394301, 12015369 }, + { 19695761, 16087646, 28032085, 12999827, 6817792, 11427614, 20244189, -1312777, -13259127, -3402461 }, + }, + { + { 30860103, 12735208, -1888245, -4699734, -16974906, 2256940, -8166013, 12298312, -8550524, -10393462 }, + { -5719826, -11245325, -1910649, 15569035, 26642876, -7587760, -5789354, -15118654, -4976164, 12651793 }, + { -2848395, 9953421, 11531313, -5282879, 26895123, -12697089, -13118820, -16517902, 9768698, -2533218 }, + }, + { + { -24719459, 1894651, -287698, -4704085, 15348719, -8156530, 32767513, 12765450, 4940095, 10678226 }, + { 18860224, 15980149, -18987240, -1562570, -26233012, -11071856, -7843882, 13944024, -24372348, 16582019 }, + { -15504260, 4970268, -29893044, 4175593, -20993212, -2199756, -11704054, 15444560, -11003761, 7989037 }, + }, + { + { 31490452, 5568061, -2412803, 2182383, -32336847, 4531686, -32078269, 6200206, -19686113, -14800171 }, + { -17308668, -15879940, -31522777, -2831, -32887382, 16375549, 8680158, -16371713, 28550068, -6857132 }, + { -28126887, -5688091, 16837845, -1820458, -6850681, 12700016, -30039981, 4364038, 1155602, 5988841 }, + }, + { + { 21890435, -13272907, -12624011, 12154349, -7831873, 15300496, 23148983, -4470481, 24618407, 8283181 }, + { -33136107, -10512751, 9975416, 6841041, -31559793, 16356536, 3070187, -7025928, 1466169, 10740210 }, + { -1509399, -15488185, -13503385, -10655916, 32799044, 909394, -13938903, -5779719, -32164649, -15327040 }, + }, + { + { 3960823, -14267803, -28026090, -15918051, -19404858, 13146868, 15567327, 951507, -3260321, -573935 }, + { 24740841, 5052253, -30094131, 8961361, 25877428, 6165135, -24368180, 14397372, -7380369, -6144105 }, + { -28888365, 3510803, -28103278, -1158478, -11238128, -10631454, -15441463, -14453128, -1625486, -6494814 }, + }, + }, + { + { + { 793299, -9230478, 8836302, -6235707, -27360908, -2369593, 33152843, -4885251, -9906200, -621852 }, + { 5666233, 525582, 20782575, -8038419, -24538499, 14657740, 16099374, 1468826, -6171428, -15186581 }, + { -4859255, -3779343, -2917758, -6748019, 7778750, 11688288, -30404353, -9871238, -1558923, -9863646 }, + }, + { + { 10896332, -7719704, 824275, 472601, -19460308, 3009587, 25248958, 14783338, -30581476, -15757844 }, + { 10566929, 12612572, -31944212, 11118703, -12633376, 12362879, 21752402, 8822496, 24003793, 14264025 }, + { 27713862, -7355973, -11008240, 9227530, 27050101, 2504721, 23886875, -13117525, 13958495, -5732453 }, + }, + { + { -23481610, 4867226, -27247128, 3900521, 29838369, -8212291, -31889399, -10041781, 7340521, -15410068 }, + { 4646514, -8011124, -22766023, -11532654, 23184553, 8566613, 31366726, -1381061, -15066784, -10375192 }, + { -17270517, 12723032, -16993061, 14878794, 21619651, -6197576, 27584817, 3093888, -8843694, 3849921 }, + }, + { + { -9064912, 2103172, 25561640, -15125738, -5239824, 9582958, 32477045, -9017955, 5002294, -15550259 }, + { -12057553, -11177906, 21115585, -13365155, 8808712, -12030708, 16489530, 13378448, -25845716, 12741426 }, + { -5946367, 10645103, -30911586, 15390284, -3286982, -7118677, 24306472, 15852464, 28834118, -7646072 }, + }, + { + { -17335748, -9107057, -24531279, 9434953, -8472084, -583362, -13090771, 455841, 20461858, 5491305 }, + { 13669248, -16095482, -12481974, -10203039, -14569770, -11893198, -24995986, 11293807, -28588204, -9421832 }, + { 28497928, 6272777, -33022994, 14470570, 8906179, -1225630, 18504674, -14165166, 29867745, -8795943 }, + }, + { + { -16207023, 13517196, -27799630, -13697798, 24009064, -6373891, -6367600, -13175392, 22853429, -4012011 }, + { 24191378, 16712145, -13931797, 15217831, 14542237, 1646131, 18603514, -11037887, 12876623, -2112447 }, + { 17902668, 4518229, -411702, -2829247, 26878217, 5258055, -12860753, 608397, 16031844, 3723494 }, + }, + { + { -28632773, 12763728, -20446446, 7577504, 33001348, -13017745, 17558842, -7872890, 23896954, -4314245 }, + { -20005381, -12011952, 31520464, 605201, 2543521, 5991821, -2945064, 7229064, -9919646, -8826859 }, + { 28816045, 298879, -28165016, -15920938, 19000928, -1665890, -12680833, -2949325, -18051778, -2082915 }, + }, + { + { 16000882, -344896, 3493092, -11447198, -29504595, -13159789, 12577740, 16041268, -19715240, 7847707 }, + { 10151868, 10572098, 27312476, 7922682, 14825339, 4723128, -32855931, -6519018, -10020567, 3852848 }, + { -11430470, 15697596, -21121557, -4420647, 5386314, 15063598, 16514493, -15932110, 29330899, -15076224 }, + }, + }, + { + { + { -25499735, -4378794, -15222908, -6901211, 16615731, 2051784, 3303702, 15490, -27548796, 12314391 }, + { 15683520, -6003043, 18109120, -9980648, 15337968, -5997823, -16717435, 15921866, 16103996, -3731215 }, + { -23169824, -10781249, 13588192, -1628807, -3798557, -1074929, -19273607, 5402699, -29815713, -9841101 }, + }, + { + { 23190676, 2384583, -32714340, 3462154, -29903655, -1529132, -11266856, 8911517, -25205859, 2739713 }, + { 21374101, -3554250, -33524649, 9874411, 15377179, 11831242, -33529904, 6134907, 4931255, 11987849 }, + { -7732, -2978858, -16223486, 7277597, 105524, -322051, -31480539, 13861388, -30076310, 10117930 }, + }, + { + { -29501170, -10744872, -26163768, 13051539, -25625564, 5089643, -6325503, 6704079, 12890019, 15728940 }, + { -21972360, -11771379, -951059, -4418840, 14704840, 2695116, 903376, -10428139, 12885167, 8311031 }, + { -17516482, 5352194, 10384213, -13811658, 7506451, 13453191, 26423267, 4384730, 1888765, -5435404 }, + }, + { + { -25817338, -3107312, -13494599, -3182506, 30896459, -13921729, -32251644, -12707869, -19464434, -3340243 }, + { -23607977, -2665774, -526091, 4651136, 5765089, 4618330, 6092245, 14845197, 17151279, -9854116 }, + { -24830458, -12733720, -15165978, 10367250, -29530908, -265356, 22825805, -7087279, -16866484, 16176525 }, + }, + { + { -23583256, 6564961, 20063689, 3798228, -4740178, 7359225, 2006182, -10363426, -28746253, -10197509 }, + { -10626600, -4486402, -13320562, -5125317, 3432136, -6393229, 23632037, -1940610, 32808310, 1099883 }, + { 15030977, 5768825, -27451236, -2887299, -6427378, -15361371, -15277896, -6809350, 2051441, -15225865 }, + }, + { + { -3362323, -7239372, 7517890, 9824992, 23555850, 295369, 5148398, -14154188, -22686354, 16633660 }, + { 4577086, -16752288, 13249841, -15304328, 19958763, -14537274, 18559670, -10759549, 8402478, -9864273 }, + { -28406330, -1051581, -26790155, -907698, -17212414, -11030789, 9453451, -14980072, 17983010, 9967138 }, + }, + { + { -25762494, 6524722, 26585488, 9969270, 24709298, 1220360, -1677990, 7806337, 17507396, 3651560 }, + { -10420457, -4118111, 14584639, 15971087, -15768321, 8861010, 26556809, -5574557, -18553322, -11357135 }, + { 2839101, 14284142, 4029895, 3472686, 14402957, 12689363, -26642121, 8459447, -5605463, -7621941 }, + }, + { + { -4839289, -3535444, 9744961, 2871048, 25113978, 3187018, -25110813, -849066, 17258084, -7977739 }, + { 18164541, -10595176, -17154882, -1542417, 19237078, -9745295, 23357533, -15217008, 26908270, 12150756 }, + { -30264870, -7647865, 5112249, -7036672, -1499807, -6974257, 43168, -5537701, -32302074, 16215819 }, + }, + }, + { + { + { -6898905, 9824394, -12304779, -4401089, -31397141, -6276835, 32574489, 12532905, -7503072, -8675347 }, + { -27343522, -16515468, -27151524, -10722951, 946346, 16291093, 254968, 7168080, 21676107, -1943028 }, + { 21260961, -8424752, -16831886, -11920822, -23677961, 3968121, -3651949, -6215466, -3556191, -7913075 }, + }, + { + { 16544754, 13250366, -16804428, 15546242, -4583003, 12757258, -2462308, -8680336, -18907032, -9662799 }, + { -2415239, -15577728, 18312303, 4964443, -15272530, -12653564, 26820651, 16690659, 25459437, -4564609 }, + { -25144690, 11425020, 28423002, -11020557, -6144921, -15826224, 9142795, -2391602, -6432418, -1644817 }, + }, + { + { -23104652, 6253476, 16964147, -3768872, -25113972, -12296437, -27457225, -16344658, 6335692, 7249989 }, + { -30333227, 13979675, 7503222, -12368314, -11956721, -4621693, -30272269, 2682242, 25993170, -12478523 }, + { 4364628, 5930691, 32304656, -10044554, -8054781, 15091131, 22857016, -10598955, 31820368, 15075278 }, + }, + { + { 31879134, -8918693, 17258761, 90626, -8041836, -4917709, 24162788, -9650886, -17970238, 12833045 }, + { 19073683, 14851414, -24403169, -11860168, 7625278, 11091125, -19619190, 2074449, -9413939, 14905377 }, + { 24483667, -11935567, -2518866, -11547418, -1553130, 15355506, -25282080, 9253129, 27628530, -7555480 }, + }, + { + { 17597607, 8340603, 19355617, 552187, 26198470, -3176583, 4593324, -9157582, -14110875, 15297016 }, + { 510886, 14337390, -31785257, 16638632, 6328095, 2713355, -20217417, -11864220, 8683221, 2921426 }, + { 18606791, 11874196, 27155355, -5281482, -24031742, 6265446, -25178240, -1278924, 4674690, 13890525 }, + }, + { + { 13609624, 13069022, -27372361, -13055908, 24360586, 9592974, 14977157, 9835105, 4389687, 288396 }, + { 9922506, -519394, 13613107, 5883594, -18758345, -434263, -12304062, 8317628, 23388070, 16052080 }, + { 12720016, 11937594, -31970060, -5028689, 26900120, 8561328, -20155687, -11632979, -14754271, -10812892 }, + }, + { + { 15961858, 14150409, 26716931, -665832, -22794328, 13603569, 11829573, 7467844, -28822128, 929275 }, + { 11038231, -11582396, -27310482, -7316562, -10498527, -16307831, -23479533, -9371869, -21393143, 2465074 }, + { 20017163, -4323226, 27915242, 1529148, 12396362, 15675764, 13817261, -9658066, 2463391, -4622140 }, + }, + { + { -16358878, -12663911, -12065183, 4996454, -1256422, 1073572, 9583558, 12851107, 4003896, 12673717 }, + { -1731589, -15155870, -3262930, 16143082, 19294135, 13385325, 14741514, -9103726, 7903886, 2348101 }, + { 24536016, -16515207, 12715592, -3862155, 1511293, 10047386, -3842346, -7129159, -28377538, 10048127 }, + }, + }, + { + { + { -12622226, -6204820, 30718825, 2591312, -10617028, 12192840, 18873298, -7297090, -32297756, 15221632 }, + { -26478122, -11103864, 11546244, -1852483, 9180880, 7656409, -21343950, 2095755, 29769758, 6593415 }, + { -31994208, -2907461, 4176912, 3264766, 12538965, -868111, 26312345, -6118678, 30958054, 8292160 }, + }, + { + { 31429822, -13959116, 29173532, 15632448, 12174511, -2760094, 32808831, 3977186, 26143136, -3148876 }, + { 22648901, 1402143, -22799984, 13746059, 7936347, 365344, -8668633, -1674433, -3758243, -2304625 }, + { -15491917, 8012313, -2514730, -12702462, -23965846, -10254029, -1612713, -1535569, -16664475, 8194478 }, + }, + { + { 27338066, -7507420, -7414224, 10140405, -19026427, -6589889, 27277191, 8855376, 28572286, 3005164 }, + { 26287124, 4821776, 25476601, -4145903, -3764513, -15788984, -18008582, 1182479, -26094821, -13079595 }, + { -7171154, 3178080, 23970071, 6201893, -17195577, -4489192, -21876275, -13982627, 32208683, -1198248 }, + }, + { + { -16657702, 2817643, -10286362, 14811298, 6024667, 13349505, -27315504, -10497842, -27672585, -11539858 }, + { 15941029, -9405932, -21367050, 8062055, 31876073, -238629, -15278393, -1444429, 15397331, -4130193 }, + { 8934485, -13485467, -23286397, -13423241, -32446090, 14047986, 31170398, -1441021, -27505566, 15087184 }, + }, + { + { -18357243, -2156491, 24524913, -16677868, 15520427, -6360776, -15502406, 11461896, 16788528, -5868942 }, + { -1947386, 16013773, 21750665, 3714552, -17401782, -16055433, -3770287, -10323320, 31322514, -11615635 }, + { 21426655, -5650218, -13648287, -5347537, -28812189, -4920970, -18275391, -14621414, 13040862, -12112948 }, + }, + { + { 11293895, 12478086, -27136401, 15083750, -29307421, 14748872, 14555558, -13417103, 1613711, 4896935 }, + { -25894883, 15323294, -8489791, -8057900, 25967126, -13425460, 2825960, -4897045, -23971776, -11267415 }, + { -15924766, -5229880, -17443532, 6410664, 3622847, 10243618, 20615400, 12405433, -23753030, -8436416 }, + }, + { + { -7091295, 12556208, -20191352, 9025187, -17072479, 4333801, 4378436, 2432030, 23097949, -566018 }, + { 4565804, -16025654, 20084412, -7842817, 1724999, 189254, 24767264, 10103221, -18512313, 2424778 }, + { 366633, -11976806, 8173090, -6890119, 30788634, 5745705, -7168678, 1344109, -3642553, 12412659 }, + }, + { + { -24001791, 7690286, 14929416, -168257, -32210835, -13412986, 24162697, -15326504, -3141501, 11179385 }, + { 18289522, -14724954, 8056945, 16430056, -21729724, 7842514, -6001441, -1486897, -18684645, -11443503 }, + { 476239, 6601091, -6152790, -9723375, 17503545, -4863900, 27672959, 13403813, 11052904, 5219329 }, + }, + }, + { + { + { 20678546, -8375738, -32671898, 8849123, -5009758, 14574752, 31186971, -3973730, 9014762, -8579056 }, + { -13644050, -10350239, -15962508, 5075808, -1514661, -11534600, -33102500, 9160280, 8473550, -3256838 }, + { 24900749, 14435722, 17209120, -15292541, -22592275, 9878983, -7689309, -16335821, -24568481, 11788948 }, + }, + { + { -3118155, -11395194, -13802089, 14797441, 9652448, -6845904, -20037437, 10410733, -24568470, -1458691 }, + { -15659161, 16736706, -22467150, 10215878, -9097177, 7563911, 11871841, -12505194, -18513325, 8464118 }, + { -23400612, 8348507, -14585951, -861714, -3950205, -6373419, 14325289, 8628612, 33313881, -8370517 }, + }, + { + { -20186973, -4967935, 22367356, 5271547, -1097117, -4788838, -24805667, -10236854, -8940735, -5818269 }, + { -6948785, -1795212, -32625683, -16021179, 32635414, -7374245, 15989197, -12838188, 28358192, -4253904 }, + { -23561781, -2799059, -32351682, -1661963, -9147719, 10429267, -16637684, 4072016, -5351664, 5596589 }, + }, + { + { -28236598, -3390048, 12312896, 6213178, 3117142, 16078565, 29266239, 2557221, 1768301, 15373193 }, + { -7243358, -3246960, -4593467, -7553353, -127927, -912245, -1090902, -4504991, -24660491, 3442910 }, + { -30210571, 5124043, 14181784, 8197961, 18964734, -11939093, 22597931, 7176455, -18585478, 13365930 }, + }, + { + { -7877390, -1499958, 8324673, 4690079, 6261860, 890446, 24538107, -8570186, -9689599, -3031667 }, + { 25008904, -10771599, -4305031, -9638010, 16265036, 15721635, 683793, -11823784, 15723479, -15163481 }, + { -9660625, 12374379, -27006999, -7026148, -7724114, -12314514, 11879682, 5400171, 519526, -1235876 }, + }, + { + { 22258397, -16332233, -7869817, 14613016, -22520255, -2950923, -20353881, 7315967, 16648397, 7605640 }, + { -8081308, -8464597, -8223311, 9719710, 19259459, -15348212, 23994942, -5281555, -9468848, 4763278 }, + { -21699244, 9220969, -15730624, 1084137, -25476107, -2852390, 31088447, -7764523, -11356529, 728112 }, + }, + { + { 26047220, -11751471, -6900323, -16521798, 24092068, 9158119, -4273545, -12555558, -29365436, -5498272 }, + { 17510331, -322857, 5854289, 8403524, 17133918, -3112612, -28111007, 12327945, 10750447, 10014012 }, + { -10312768, 3936952, 9156313, -8897683, 16498692, -994647, -27481051, -666732, 3424691, 7540221 }, + }, + { + { 30322361, -6964110, 11361005, -4143317, 7433304, 4989748, -7071422, -16317219, -9244265, 15258046 }, + { 13054562, -2779497, 19155474, 469045, -12482797, 4566042, 5631406, 2711395, 1062915, -5136345 }, + { -19240248, -11254599, -29509029, -7499965, -5835763, 13005411, -6066489, 12194497, 32960380, 1459310 }, + }, + }, + { + { + { 19852034, 7027924, 23669353, 10020366, 8586503, -6657907, 394197, -6101885, 18638003, -11174937 }, + { 31395534, 15098109, 26581030, 8030562, -16527914, -5007134, 9012486, -7584354, -6643087, -5442636 }, + { -9192165, -2347377, -1997099, 4529534, 25766844, 607986, -13222, 9677543, -32294889, -6456008 }, + }, + { + { -2444496, -149937, 29348902, 8186665, 1873760, 12489863, -30934579, -7839692, -7852844, -8138429 }, + { -15236356, -15433509, 7766470, 746860, 26346930, -10221762, -27333451, 10754588, -9431476, 5203576 }, + { 31834314, 14135496, -770007, 5159118, 20917671, -16768096, -7467973, -7337524, 31809243, 7347066 }, + }, + { + { -9606723, -11874240, 20414459, 13033986, 13716524, -11691881, 19797970, -12211255, 15192876, -2087490 }, + { -12663563, -2181719, 1168162, -3804809, 26747877, -14138091, 10609330, 12694420, 33473243, -13382104 }, + { 33184999, 11180355, 15832085, -11385430, -1633671, 225884, 15089336, -11023903, -6135662, 14480053 }, + }, + { + { 31308717, -5619998, 31030840, -1897099, 15674547, -6582883, 5496208, 13685227, 27595050, 8737275 }, + { -20318852, -15150239, 10933843, -16178022, 8335352, -7546022, -31008351, -12610604, 26498114, 66511 }, + { 22644454, -8761729, -16671776, 4884562, -3105614, -13559366, 30540766, -4286747, -13327787, -7515095 }, + }, + { + { -28017847, 9834845, 18617207, -2681312, -3401956, -13307506, 8205540, 13585437, -17127465, 15115439 }, + { 23711543, -672915, 31206561, -8362711, 6164647, -9709987, -33535882, -1426096, 8236921, 16492939 }, + { -23910559, -13515526, -26299483, -4503841, 25005590, -7687270, 19574902, 10071562, 6708380, -6222424 }, + }, + { + { 2101391, -4930054, 19702731, 2367575, -15427167, 1047675, 5301017, 9328700, 29955601, -11678310 }, + { 3096359, 9271816, -21620864, -15521844, -14847996, -7592937, -25892142, -12635595, -9917575, 6216608 }, + { -32615849, 338663, -25195611, 2510422, -29213566, -13820213, 24822830, -6146567, -26767480, 7525079 }, + }, + { + { -23066649, -13985623, 16133487, -7896178, -3389565, 778788, -910336, -2782495, -19386633, 11994101 }, + { 21691500, -13624626, -641331, -14367021, 3285881, -3483596, -25064666, 9718258, -7477437, 13381418 }, + { 18445390, -4202236, 14979846, 11622458, -1727110, -3582980, 23111648, -6375247, 28535282, 15779576 }, + }, + { + { 30098053, 3089662, -9234387, 16662135, -21306940, 11308411, -14068454, 12021730, 9955285, -16303356 }, + { 9734894, -14576830, -7473633, -9138735, 2060392, 11313496, -18426029, 9924399, 20194861, 13380996 }, + { -26378102, -7965207, -22167821, 15789297, -18055342, -6168792, -1984914, 15707771, 26342023, 10146099 }, + }, + }, + { + { + { -26016874, -219943, 21339191, -41388, 19745256, -2878700, -29637280, 2227040, 21612326, -545728 }, + { -13077387, 1184228, 23562814, -5970442, -20351244, -6348714, 25764461, 12243797, -20856566, 11649658 }, + { -10031494, 11262626, 27384172, 2271902, 26947504, -15997771, 39944, 6114064, 33514190, 2333242 }, + }, + { + { -21433588, -12421821, 8119782, 7219913, -21830522, -9016134, -6679750, -12670638, 24350578, -13450001 }, + { -4116307, -11271533, -23886186, 4843615, -30088339, 690623, -31536088, -10406836, 8317860, 12352766 }, + { 18200138, -14475911, -33087759, -2696619, -23702521, -9102511, -23552096, -2287550, 20712163, 6719373 }, + }, + { + { 26656208, 6075253, -7858556, 1886072, -28344043, 4262326, 11117530, -3763210, 26224235, -3297458 }, + { -17168938, -14854097, -3395676, -16369877, -19954045, 14050420, 21728352, 9493610, 18620611, -16428628 }, + { -13323321, 13325349, 11432106, 5964811, 18609221, 6062965, -5269471, -9725556, -30701573, -16479657 }, + }, + { + { -23860538, -11233159, 26961357, 1640861, -32413112, -16737940, 12248509, -5240639, 13735342, 1934062 }, + { 25089769, 6742589, 17081145, -13406266, 21909293, -16067981, -15136294, -3765346, -21277997, 5473616 }, + { 31883677, -7961101, 1083432, -11572403, 22828471, 13290673, -7125085, 12469656, 29111212, -5451014 }, + }, + { + { 24244947, -15050407, -26262976, 2791540, -14997599, 16666678, 24367466, 6388839, -10295587, 452383 }, + { -25640782, -3417841, 5217916, 16224624, 19987036, -4082269, -24236251, -5915248, 15766062, 8407814 }, + { -20406999, 13990231, 15495425, 16395525, 5377168, 15166495, -8917023, -4388953, -8067909, 2276718 }, + }, + { + { 30157918, 12924066, -17712050, 9245753, 19895028, 3368142, -23827587, 5096219, 22740376, -7303417 }, + { 2041139, -14256350, 7783687, 13876377, -25946985, -13352459, 24051124, 13742383, -15637599, 13295222 }, + { 33338237, -8505733, 12532113, 7977527, 9106186, -1715251, -17720195, -4612972, -4451357, -14669444 }, + }, + { + { -20045281, 5454097, -14346548, 6447146, 28862071, 1883651, -2469266, -4141880, 7770569, 9620597 }, + { 23208068, 7979712, 33071466, 8149229, 1758231, -10834995, 30945528, -1694323, -33502340, -14767970 }, + { 1439958, -16270480, -1079989, -793782, 4625402, 10647766, -5043801, 1220118, 30494170, -11440799 }, + }, + { + { -5037580, -13028295, -2970559, -3061767, 15640974, -6701666, -26739026, 926050, -1684339, -13333647 }, + { 13908495, -3549272, 30919928, -6273825, -21521863, 7989039, 9021034, 9078865, 3353509, 4033511 }, + { -29663431, -15113610, 32259991, -344482, 24295849, -12912123, 23161163, 8839127, 27485041, 7356032 }, + }, + }, + { + { + { 9661027, 705443, 11980065, -5370154, -1628543, 14661173, -6346142, 2625015, 28431036, -16771834 }, + { -23839233, -8311415, -25945511, 7480958, -17681669, -8354183, -22545972, 14150565, 15970762, 4099461 }, + { 29262576, 16756590, 26350592, -8793563, 8529671, -11208050, 13617293, -9937143, 11465739, 8317062 }, + }, + { + { -25493081, -6962928, 32500200, -9419051, -23038724, -2302222, 14898637, 3848455, 20969334, -5157516 }, + { -20384450, -14347713, -18336405, 13884722, -33039454, 2842114, -21610826, -3649888, 11177095, 14989547 }, + { -24496721, -11716016, 16959896, 2278463, 12066309, 10137771, 13515641, 2581286, -28487508, 9930240 }, + }, + { + { -17751622, -2097826, 16544300, -13009300, -15914807, -14949081, 18345767, -13403753, 16291481, -5314038 }, + { -33229194, 2553288, 32678213, 9875984, 8534129, 6889387, -9676774, 6957617, 4368891, 9788741 }, + { 16660756, 7281060, -10830758, 12911820, 20108584, -8101676, -21722536, -8613148, 16250552, -11111103 }, + }, + { + { -19765507, 2390526, -16551031, 14161980, 1905286, 6414907, 4689584, 10604807, -30190403, 4782747 }, + { -1354539, 14736941, -7367442, -13292886, 7710542, -14155590, -9981571, 4383045, 22546403, 437323 }, + { 31665577, -12180464, -16186830, 1491339, -18368625, 3294682, 27343084, 2786261, -30633590, -14097016 }, + }, + { + { -14467279, -683715, -33374107, 7448552, 19294360, 14334329, -19690631, 2355319, -19284671, -6114373 }, + { 15121312, -15796162, 6377020, -6031361, -10798111, -12957845, 18952177, 15496498, -29380133, 11754228 }, + { -2637277, -13483075, 8488727, -14303896, 12728761, -1622493, 7141596, 11724556, 22761615, -10134141 }, + }, + { + { 16918416, 11729663, -18083579, 3022987, -31015732, -13339659, -28741185, -12227393, 32851222, 11717399 }, + { 11166634, 7338049, -6722523, 4531520, -29468672, -7302055, 31474879, 3483633, -1193175, -4030831 }, + { -185635, 9921305, 31456609, -13536438, -12013818, 13348923, 33142652, 6546660, -19985279, -3948376 }, + }, + { + { -32460596, 11266712, -11197107, -7899103, 31703694, 3855903, -8537131, -12833048, -30772034, -15486313 }, + { -18006477, 12709068, 3991746, -6479188, -21491523, -10550425, -31135347, -16049879, 10928917, 3011958 }, + { -6957757, -15594337, 31696059, 334240, 29576716, 14796075, -30831056, -12805180, 18008031, 10258577 }, + }, + { + { -22448644, 15655569, 7018479, -4410003, -30314266, -1201591, -1853465, 1367120, 25127874, 6671743 }, + { 29701166, -14373934, -10878120, 9279288, -17568, 13127210, 21382910, 11042292, 25838796, 4642684 }, + { -20430234, 14955537, -24126347, 8124619, -5369288, -5990470, 30468147, -13900640, 18423289, 4177476 }, + }, + }, +}; \ No newline at end of file diff --git a/src/ed25519/sc.c b/src/ed25519/sc.c new file mode 100644 index 0000000..ca5bad2 --- /dev/null +++ b/src/ed25519/sc.c @@ -0,0 +1,809 @@ +#include "fixedint.h" +#include "sc.h" + +static uint64_t load_3(const unsigned char *in) { + uint64_t result; + + result = (uint64_t) in[0]; + result |= ((uint64_t) in[1]) << 8; + result |= ((uint64_t) in[2]) << 16; + + return result; +} + +static uint64_t load_4(const unsigned char *in) { + uint64_t result; + + result = (uint64_t) in[0]; + result |= ((uint64_t) in[1]) << 8; + result |= ((uint64_t) in[2]) << 16; + result |= ((uint64_t) in[3]) << 24; + + return result; +} + +/* +Input: + s[0]+256*s[1]+...+256^63*s[63] = s + +Output: + s[0]+256*s[1]+...+256^31*s[31] = s mod l + where l = 2^252 + 27742317777372353535851937790883648493. + Overwrites s in place. +*/ + +void sc_reduce(unsigned char *s) { + int64_t s0 = 2097151 & load_3(s); + int64_t s1 = 2097151 & (load_4(s + 2) >> 5); + int64_t s2 = 2097151 & (load_3(s + 5) >> 2); + int64_t s3 = 2097151 & (load_4(s + 7) >> 7); + int64_t s4 = 2097151 & (load_4(s + 10) >> 4); + int64_t s5 = 2097151 & (load_3(s + 13) >> 1); + int64_t s6 = 2097151 & (load_4(s + 15) >> 6); + int64_t s7 = 2097151 & (load_3(s + 18) >> 3); + int64_t s8 = 2097151 & load_3(s + 21); + int64_t s9 = 2097151 & (load_4(s + 23) >> 5); + int64_t s10 = 2097151 & (load_3(s + 26) >> 2); + int64_t s11 = 2097151 & (load_4(s + 28) >> 7); + int64_t s12 = 2097151 & (load_4(s + 31) >> 4); + int64_t s13 = 2097151 & (load_3(s + 34) >> 1); + int64_t s14 = 2097151 & (load_4(s + 36) >> 6); + int64_t s15 = 2097151 & (load_3(s + 39) >> 3); + int64_t s16 = 2097151 & load_3(s + 42); + int64_t s17 = 2097151 & (load_4(s + 44) >> 5); + int64_t s18 = 2097151 & (load_3(s + 47) >> 2); + int64_t s19 = 2097151 & (load_4(s + 49) >> 7); + int64_t s20 = 2097151 & (load_4(s + 52) >> 4); + int64_t s21 = 2097151 & (load_3(s + 55) >> 1); + int64_t s22 = 2097151 & (load_4(s + 57) >> 6); + int64_t s23 = (load_4(s + 60) >> 3); + int64_t carry0; + int64_t carry1; + int64_t carry2; + int64_t carry3; + int64_t carry4; + int64_t carry5; + int64_t carry6; + int64_t carry7; + int64_t carry8; + int64_t carry9; + int64_t carry10; + int64_t carry11; + int64_t carry12; + int64_t carry13; + int64_t carry14; + int64_t carry15; + int64_t carry16; + + s11 += s23 * 666643; + s12 += s23 * 470296; + s13 += s23 * 654183; + s14 -= s23 * 997805; + s15 += s23 * 136657; + s16 -= s23 * 683901; + s23 = 0; + s10 += s22 * 666643; + s11 += s22 * 470296; + s12 += s22 * 654183; + s13 -= s22 * 997805; + s14 += s22 * 136657; + s15 -= s22 * 683901; + s22 = 0; + s9 += s21 * 666643; + s10 += s21 * 470296; + s11 += s21 * 654183; + s12 -= s21 * 997805; + s13 += s21 * 136657; + s14 -= s21 * 683901; + s21 = 0; + s8 += s20 * 666643; + s9 += s20 * 470296; + s10 += s20 * 654183; + s11 -= s20 * 997805; + s12 += s20 * 136657; + s13 -= s20 * 683901; + s20 = 0; + s7 += s19 * 666643; + s8 += s19 * 470296; + s9 += s19 * 654183; + s10 -= s19 * 997805; + s11 += s19 * 136657; + s12 -= s19 * 683901; + s19 = 0; + s6 += s18 * 666643; + s7 += s18 * 470296; + s8 += s18 * 654183; + s9 -= s18 * 997805; + s10 += s18 * 136657; + s11 -= s18 * 683901; + s18 = 0; + carry6 = (s6 + (1 << 20)) >> 21; + s7 += carry6; + s6 -= carry6 << 21; + carry8 = (s8 + (1 << 20)) >> 21; + s9 += carry8; + s8 -= carry8 << 21; + carry10 = (s10 + (1 << 20)) >> 21; + s11 += carry10; + s10 -= carry10 << 21; + carry12 = (s12 + (1 << 20)) >> 21; + s13 += carry12; + s12 -= carry12 << 21; + carry14 = (s14 + (1 << 20)) >> 21; + s15 += carry14; + s14 -= carry14 << 21; + carry16 = (s16 + (1 << 20)) >> 21; + s17 += carry16; + s16 -= carry16 << 21; + carry7 = (s7 + (1 << 20)) >> 21; + s8 += carry7; + s7 -= carry7 << 21; + carry9 = (s9 + (1 << 20)) >> 21; + s10 += carry9; + s9 -= carry9 << 21; + carry11 = (s11 + (1 << 20)) >> 21; + s12 += carry11; + s11 -= carry11 << 21; + carry13 = (s13 + (1 << 20)) >> 21; + s14 += carry13; + s13 -= carry13 << 21; + carry15 = (s15 + (1 << 20)) >> 21; + s16 += carry15; + s15 -= carry15 << 21; + s5 += s17 * 666643; + s6 += s17 * 470296; + s7 += s17 * 654183; + s8 -= s17 * 997805; + s9 += s17 * 136657; + s10 -= s17 * 683901; + s17 = 0; + s4 += s16 * 666643; + s5 += s16 * 470296; + s6 += s16 * 654183; + s7 -= s16 * 997805; + s8 += s16 * 136657; + s9 -= s16 * 683901; + s16 = 0; + s3 += s15 * 666643; + s4 += s15 * 470296; + s5 += s15 * 654183; + s6 -= s15 * 997805; + s7 += s15 * 136657; + s8 -= s15 * 683901; + s15 = 0; + s2 += s14 * 666643; + s3 += s14 * 470296; + s4 += s14 * 654183; + s5 -= s14 * 997805; + s6 += s14 * 136657; + s7 -= s14 * 683901; + s14 = 0; + s1 += s13 * 666643; + s2 += s13 * 470296; + s3 += s13 * 654183; + s4 -= s13 * 997805; + s5 += s13 * 136657; + s6 -= s13 * 683901; + s13 = 0; + s0 += s12 * 666643; + s1 += s12 * 470296; + s2 += s12 * 654183; + s3 -= s12 * 997805; + s4 += s12 * 136657; + s5 -= s12 * 683901; + s12 = 0; + carry0 = (s0 + (1 << 20)) >> 21; + s1 += carry0; + s0 -= carry0 << 21; + carry2 = (s2 + (1 << 20)) >> 21; + s3 += carry2; + s2 -= carry2 << 21; + carry4 = (s4 + (1 << 20)) >> 21; + s5 += carry4; + s4 -= carry4 << 21; + carry6 = (s6 + (1 << 20)) >> 21; + s7 += carry6; + s6 -= carry6 << 21; + carry8 = (s8 + (1 << 20)) >> 21; + s9 += carry8; + s8 -= carry8 << 21; + carry10 = (s10 + (1 << 20)) >> 21; + s11 += carry10; + s10 -= carry10 << 21; + carry1 = (s1 + (1 << 20)) >> 21; + s2 += carry1; + s1 -= carry1 << 21; + carry3 = (s3 + (1 << 20)) >> 21; + s4 += carry3; + s3 -= carry3 << 21; + carry5 = (s5 + (1 << 20)) >> 21; + s6 += carry5; + s5 -= carry5 << 21; + carry7 = (s7 + (1 << 20)) >> 21; + s8 += carry7; + s7 -= carry7 << 21; + carry9 = (s9 + (1 << 20)) >> 21; + s10 += carry9; + s9 -= carry9 << 21; + carry11 = (s11 + (1 << 20)) >> 21; + s12 += carry11; + s11 -= carry11 << 21; + s0 += s12 * 666643; + s1 += s12 * 470296; + s2 += s12 * 654183; + s3 -= s12 * 997805; + s4 += s12 * 136657; + s5 -= s12 * 683901; + s12 = 0; + carry0 = s0 >> 21; + s1 += carry0; + s0 -= carry0 << 21; + carry1 = s1 >> 21; + s2 += carry1; + s1 -= carry1 << 21; + carry2 = s2 >> 21; + s3 += carry2; + s2 -= carry2 << 21; + carry3 = s3 >> 21; + s4 += carry3; + s3 -= carry3 << 21; + carry4 = s4 >> 21; + s5 += carry4; + s4 -= carry4 << 21; + carry5 = s5 >> 21; + s6 += carry5; + s5 -= carry5 << 21; + carry6 = s6 >> 21; + s7 += carry6; + s6 -= carry6 << 21; + carry7 = s7 >> 21; + s8 += carry7; + s7 -= carry7 << 21; + carry8 = s8 >> 21; + s9 += carry8; + s8 -= carry8 << 21; + carry9 = s9 >> 21; + s10 += carry9; + s9 -= carry9 << 21; + carry10 = s10 >> 21; + s11 += carry10; + s10 -= carry10 << 21; + carry11 = s11 >> 21; + s12 += carry11; + s11 -= carry11 << 21; + s0 += s12 * 666643; + s1 += s12 * 470296; + s2 += s12 * 654183; + s3 -= s12 * 997805; + s4 += s12 * 136657; + s5 -= s12 * 683901; + s12 = 0; + carry0 = s0 >> 21; + s1 += carry0; + s0 -= carry0 << 21; + carry1 = s1 >> 21; + s2 += carry1; + s1 -= carry1 << 21; + carry2 = s2 >> 21; + s3 += carry2; + s2 -= carry2 << 21; + carry3 = s3 >> 21; + s4 += carry3; + s3 -= carry3 << 21; + carry4 = s4 >> 21; + s5 += carry4; + s4 -= carry4 << 21; + carry5 = s5 >> 21; + s6 += carry5; + s5 -= carry5 << 21; + carry6 = s6 >> 21; + s7 += carry6; + s6 -= carry6 << 21; + carry7 = s7 >> 21; + s8 += carry7; + s7 -= carry7 << 21; + carry8 = s8 >> 21; + s9 += carry8; + s8 -= carry8 << 21; + carry9 = s9 >> 21; + s10 += carry9; + s9 -= carry9 << 21; + carry10 = s10 >> 21; + s11 += carry10; + s10 -= carry10 << 21; + + s[0] = (unsigned char) (s0 >> 0); + s[1] = (unsigned char) (s0 >> 8); + s[2] = (unsigned char) ((s0 >> 16) | (s1 << 5)); + s[3] = (unsigned char) (s1 >> 3); + s[4] = (unsigned char) (s1 >> 11); + s[5] = (unsigned char) ((s1 >> 19) | (s2 << 2)); + s[6] = (unsigned char) (s2 >> 6); + s[7] = (unsigned char) ((s2 >> 14) | (s3 << 7)); + s[8] = (unsigned char) (s3 >> 1); + s[9] = (unsigned char) (s3 >> 9); + s[10] = (unsigned char) ((s3 >> 17) | (s4 << 4)); + s[11] = (unsigned char) (s4 >> 4); + s[12] = (unsigned char) (s4 >> 12); + s[13] = (unsigned char) ((s4 >> 20) | (s5 << 1)); + s[14] = (unsigned char) (s5 >> 7); + s[15] = (unsigned char) ((s5 >> 15) | (s6 << 6)); + s[16] = (unsigned char) (s6 >> 2); + s[17] = (unsigned char) (s6 >> 10); + s[18] = (unsigned char) ((s6 >> 18) | (s7 << 3)); + s[19] = (unsigned char) (s7 >> 5); + s[20] = (unsigned char) (s7 >> 13); + s[21] = (unsigned char) (s8 >> 0); + s[22] = (unsigned char) (s8 >> 8); + s[23] = (unsigned char) ((s8 >> 16) | (s9 << 5)); + s[24] = (unsigned char) (s9 >> 3); + s[25] = (unsigned char) (s9 >> 11); + s[26] = (unsigned char) ((s9 >> 19) | (s10 << 2)); + s[27] = (unsigned char) (s10 >> 6); + s[28] = (unsigned char) ((s10 >> 14) | (s11 << 7)); + s[29] = (unsigned char) (s11 >> 1); + s[30] = (unsigned char) (s11 >> 9); + s[31] = (unsigned char) (s11 >> 17); +} + + + +/* +Input: + a[0]+256*a[1]+...+256^31*a[31] = a + b[0]+256*b[1]+...+256^31*b[31] = b + c[0]+256*c[1]+...+256^31*c[31] = c + +Output: + s[0]+256*s[1]+...+256^31*s[31] = (ab+c) mod l + where l = 2^252 + 27742317777372353535851937790883648493. +*/ + +void sc_muladd(unsigned char *s, const unsigned char *a, const unsigned char *b, const unsigned char *c) { + int64_t a0 = 2097151 & load_3(a); + int64_t a1 = 2097151 & (load_4(a + 2) >> 5); + int64_t a2 = 2097151 & (load_3(a + 5) >> 2); + int64_t a3 = 2097151 & (load_4(a + 7) >> 7); + int64_t a4 = 2097151 & (load_4(a + 10) >> 4); + int64_t a5 = 2097151 & (load_3(a + 13) >> 1); + int64_t a6 = 2097151 & (load_4(a + 15) >> 6); + int64_t a7 = 2097151 & (load_3(a + 18) >> 3); + int64_t a8 = 2097151 & load_3(a + 21); + int64_t a9 = 2097151 & (load_4(a + 23) >> 5); + int64_t a10 = 2097151 & (load_3(a + 26) >> 2); + int64_t a11 = (load_4(a + 28) >> 7); + int64_t b0 = 2097151 & load_3(b); + int64_t b1 = 2097151 & (load_4(b + 2) >> 5); + int64_t b2 = 2097151 & (load_3(b + 5) >> 2); + int64_t b3 = 2097151 & (load_4(b + 7) >> 7); + int64_t b4 = 2097151 & (load_4(b + 10) >> 4); + int64_t b5 = 2097151 & (load_3(b + 13) >> 1); + int64_t b6 = 2097151 & (load_4(b + 15) >> 6); + int64_t b7 = 2097151 & (load_3(b + 18) >> 3); + int64_t b8 = 2097151 & load_3(b + 21); + int64_t b9 = 2097151 & (load_4(b + 23) >> 5); + int64_t b10 = 2097151 & (load_3(b + 26) >> 2); + int64_t b11 = (load_4(b + 28) >> 7); + int64_t c0 = 2097151 & load_3(c); + int64_t c1 = 2097151 & (load_4(c + 2) >> 5); + int64_t c2 = 2097151 & (load_3(c + 5) >> 2); + int64_t c3 = 2097151 & (load_4(c + 7) >> 7); + int64_t c4 = 2097151 & (load_4(c + 10) >> 4); + int64_t c5 = 2097151 & (load_3(c + 13) >> 1); + int64_t c6 = 2097151 & (load_4(c + 15) >> 6); + int64_t c7 = 2097151 & (load_3(c + 18) >> 3); + int64_t c8 = 2097151 & load_3(c + 21); + int64_t c9 = 2097151 & (load_4(c + 23) >> 5); + int64_t c10 = 2097151 & (load_3(c + 26) >> 2); + int64_t c11 = (load_4(c + 28) >> 7); + int64_t s0; + int64_t s1; + int64_t s2; + int64_t s3; + int64_t s4; + int64_t s5; + int64_t s6; + int64_t s7; + int64_t s8; + int64_t s9; + int64_t s10; + int64_t s11; + int64_t s12; + int64_t s13; + int64_t s14; + int64_t s15; + int64_t s16; + int64_t s17; + int64_t s18; + int64_t s19; + int64_t s20; + int64_t s21; + int64_t s22; + int64_t s23; + int64_t carry0; + int64_t carry1; + int64_t carry2; + int64_t carry3; + int64_t carry4; + int64_t carry5; + int64_t carry6; + int64_t carry7; + int64_t carry8; + int64_t carry9; + int64_t carry10; + int64_t carry11; + int64_t carry12; + int64_t carry13; + int64_t carry14; + int64_t carry15; + int64_t carry16; + int64_t carry17; + int64_t carry18; + int64_t carry19; + int64_t carry20; + int64_t carry21; + int64_t carry22; + + s0 = c0 + a0 * b0; + s1 = c1 + a0 * b1 + a1 * b0; + s2 = c2 + a0 * b2 + a1 * b1 + a2 * b0; + s3 = c3 + a0 * b3 + a1 * b2 + a2 * b1 + a3 * b0; + s4 = c4 + a0 * b4 + a1 * b3 + a2 * b2 + a3 * b1 + a4 * b0; + s5 = c5 + a0 * b5 + a1 * b4 + a2 * b3 + a3 * b2 + a4 * b1 + a5 * b0; + s6 = c6 + a0 * b6 + a1 * b5 + a2 * b4 + a3 * b3 + a4 * b2 + a5 * b1 + a6 * b0; + s7 = c7 + a0 * b7 + a1 * b6 + a2 * b5 + a3 * b4 + a4 * b3 + a5 * b2 + a6 * b1 + a7 * b0; + s8 = c8 + a0 * b8 + a1 * b7 + a2 * b6 + a3 * b5 + a4 * b4 + a5 * b3 + a6 * b2 + a7 * b1 + a8 * b0; + s9 = c9 + a0 * b9 + a1 * b8 + a2 * b7 + a3 * b6 + a4 * b5 + a5 * b4 + a6 * b3 + a7 * b2 + a8 * b1 + a9 * b0; + s10 = c10 + a0 * b10 + a1 * b9 + a2 * b8 + a3 * b7 + a4 * b6 + a5 * b5 + a6 * b4 + a7 * b3 + a8 * b2 + a9 * b1 + a10 * b0; + s11 = c11 + a0 * b11 + a1 * b10 + a2 * b9 + a3 * b8 + a4 * b7 + a5 * b6 + a6 * b5 + a7 * b4 + a8 * b3 + a9 * b2 + a10 * b1 + a11 * b0; + s12 = a1 * b11 + a2 * b10 + a3 * b9 + a4 * b8 + a5 * b7 + a6 * b6 + a7 * b5 + a8 * b4 + a9 * b3 + a10 * b2 + a11 * b1; + s13 = a2 * b11 + a3 * b10 + a4 * b9 + a5 * b8 + a6 * b7 + a7 * b6 + a8 * b5 + a9 * b4 + a10 * b3 + a11 * b2; + s14 = a3 * b11 + a4 * b10 + a5 * b9 + a6 * b8 + a7 * b7 + a8 * b6 + a9 * b5 + a10 * b4 + a11 * b3; + s15 = a4 * b11 + a5 * b10 + a6 * b9 + a7 * b8 + a8 * b7 + a9 * b6 + a10 * b5 + a11 * b4; + s16 = a5 * b11 + a6 * b10 + a7 * b9 + a8 * b8 + a9 * b7 + a10 * b6 + a11 * b5; + s17 = a6 * b11 + a7 * b10 + a8 * b9 + a9 * b8 + a10 * b7 + a11 * b6; + s18 = a7 * b11 + a8 * b10 + a9 * b9 + a10 * b8 + a11 * b7; + s19 = a8 * b11 + a9 * b10 + a10 * b9 + a11 * b8; + s20 = a9 * b11 + a10 * b10 + a11 * b9; + s21 = a10 * b11 + a11 * b10; + s22 = a11 * b11; + s23 = 0; + carry0 = (s0 + (1 << 20)) >> 21; + s1 += carry0; + s0 -= carry0 << 21; + carry2 = (s2 + (1 << 20)) >> 21; + s3 += carry2; + s2 -= carry2 << 21; + carry4 = (s4 + (1 << 20)) >> 21; + s5 += carry4; + s4 -= carry4 << 21; + carry6 = (s6 + (1 << 20)) >> 21; + s7 += carry6; + s6 -= carry6 << 21; + carry8 = (s8 + (1 << 20)) >> 21; + s9 += carry8; + s8 -= carry8 << 21; + carry10 = (s10 + (1 << 20)) >> 21; + s11 += carry10; + s10 -= carry10 << 21; + carry12 = (s12 + (1 << 20)) >> 21; + s13 += carry12; + s12 -= carry12 << 21; + carry14 = (s14 + (1 << 20)) >> 21; + s15 += carry14; + s14 -= carry14 << 21; + carry16 = (s16 + (1 << 20)) >> 21; + s17 += carry16; + s16 -= carry16 << 21; + carry18 = (s18 + (1 << 20)) >> 21; + s19 += carry18; + s18 -= carry18 << 21; + carry20 = (s20 + (1 << 20)) >> 21; + s21 += carry20; + s20 -= carry20 << 21; + carry22 = (s22 + (1 << 20)) >> 21; + s23 += carry22; + s22 -= carry22 << 21; + carry1 = (s1 + (1 << 20)) >> 21; + s2 += carry1; + s1 -= carry1 << 21; + carry3 = (s3 + (1 << 20)) >> 21; + s4 += carry3; + s3 -= carry3 << 21; + carry5 = (s5 + (1 << 20)) >> 21; + s6 += carry5; + s5 -= carry5 << 21; + carry7 = (s7 + (1 << 20)) >> 21; + s8 += carry7; + s7 -= carry7 << 21; + carry9 = (s9 + (1 << 20)) >> 21; + s10 += carry9; + s9 -= carry9 << 21; + carry11 = (s11 + (1 << 20)) >> 21; + s12 += carry11; + s11 -= carry11 << 21; + carry13 = (s13 + (1 << 20)) >> 21; + s14 += carry13; + s13 -= carry13 << 21; + carry15 = (s15 + (1 << 20)) >> 21; + s16 += carry15; + s15 -= carry15 << 21; + carry17 = (s17 + (1 << 20)) >> 21; + s18 += carry17; + s17 -= carry17 << 21; + carry19 = (s19 + (1 << 20)) >> 21; + s20 += carry19; + s19 -= carry19 << 21; + carry21 = (s21 + (1 << 20)) >> 21; + s22 += carry21; + s21 -= carry21 << 21; + s11 += s23 * 666643; + s12 += s23 * 470296; + s13 += s23 * 654183; + s14 -= s23 * 997805; + s15 += s23 * 136657; + s16 -= s23 * 683901; + s23 = 0; + s10 += s22 * 666643; + s11 += s22 * 470296; + s12 += s22 * 654183; + s13 -= s22 * 997805; + s14 += s22 * 136657; + s15 -= s22 * 683901; + s22 = 0; + s9 += s21 * 666643; + s10 += s21 * 470296; + s11 += s21 * 654183; + s12 -= s21 * 997805; + s13 += s21 * 136657; + s14 -= s21 * 683901; + s21 = 0; + s8 += s20 * 666643; + s9 += s20 * 470296; + s10 += s20 * 654183; + s11 -= s20 * 997805; + s12 += s20 * 136657; + s13 -= s20 * 683901; + s20 = 0; + s7 += s19 * 666643; + s8 += s19 * 470296; + s9 += s19 * 654183; + s10 -= s19 * 997805; + s11 += s19 * 136657; + s12 -= s19 * 683901; + s19 = 0; + s6 += s18 * 666643; + s7 += s18 * 470296; + s8 += s18 * 654183; + s9 -= s18 * 997805; + s10 += s18 * 136657; + s11 -= s18 * 683901; + s18 = 0; + carry6 = (s6 + (1 << 20)) >> 21; + s7 += carry6; + s6 -= carry6 << 21; + carry8 = (s8 + (1 << 20)) >> 21; + s9 += carry8; + s8 -= carry8 << 21; + carry10 = (s10 + (1 << 20)) >> 21; + s11 += carry10; + s10 -= carry10 << 21; + carry12 = (s12 + (1 << 20)) >> 21; + s13 += carry12; + s12 -= carry12 << 21; + carry14 = (s14 + (1 << 20)) >> 21; + s15 += carry14; + s14 -= carry14 << 21; + carry16 = (s16 + (1 << 20)) >> 21; + s17 += carry16; + s16 -= carry16 << 21; + carry7 = (s7 + (1 << 20)) >> 21; + s8 += carry7; + s7 -= carry7 << 21; + carry9 = (s9 + (1 << 20)) >> 21; + s10 += carry9; + s9 -= carry9 << 21; + carry11 = (s11 + (1 << 20)) >> 21; + s12 += carry11; + s11 -= carry11 << 21; + carry13 = (s13 + (1 << 20)) >> 21; + s14 += carry13; + s13 -= carry13 << 21; + carry15 = (s15 + (1 << 20)) >> 21; + s16 += carry15; + s15 -= carry15 << 21; + s5 += s17 * 666643; + s6 += s17 * 470296; + s7 += s17 * 654183; + s8 -= s17 * 997805; + s9 += s17 * 136657; + s10 -= s17 * 683901; + s17 = 0; + s4 += s16 * 666643; + s5 += s16 * 470296; + s6 += s16 * 654183; + s7 -= s16 * 997805; + s8 += s16 * 136657; + s9 -= s16 * 683901; + s16 = 0; + s3 += s15 * 666643; + s4 += s15 * 470296; + s5 += s15 * 654183; + s6 -= s15 * 997805; + s7 += s15 * 136657; + s8 -= s15 * 683901; + s15 = 0; + s2 += s14 * 666643; + s3 += s14 * 470296; + s4 += s14 * 654183; + s5 -= s14 * 997805; + s6 += s14 * 136657; + s7 -= s14 * 683901; + s14 = 0; + s1 += s13 * 666643; + s2 += s13 * 470296; + s3 += s13 * 654183; + s4 -= s13 * 997805; + s5 += s13 * 136657; + s6 -= s13 * 683901; + s13 = 0; + s0 += s12 * 666643; + s1 += s12 * 470296; + s2 += s12 * 654183; + s3 -= s12 * 997805; + s4 += s12 * 136657; + s5 -= s12 * 683901; + s12 = 0; + carry0 = (s0 + (1 << 20)) >> 21; + s1 += carry0; + s0 -= carry0 << 21; + carry2 = (s2 + (1 << 20)) >> 21; + s3 += carry2; + s2 -= carry2 << 21; + carry4 = (s4 + (1 << 20)) >> 21; + s5 += carry4; + s4 -= carry4 << 21; + carry6 = (s6 + (1 << 20)) >> 21; + s7 += carry6; + s6 -= carry6 << 21; + carry8 = (s8 + (1 << 20)) >> 21; + s9 += carry8; + s8 -= carry8 << 21; + carry10 = (s10 + (1 << 20)) >> 21; + s11 += carry10; + s10 -= carry10 << 21; + carry1 = (s1 + (1 << 20)) >> 21; + s2 += carry1; + s1 -= carry1 << 21; + carry3 = (s3 + (1 << 20)) >> 21; + s4 += carry3; + s3 -= carry3 << 21; + carry5 = (s5 + (1 << 20)) >> 21; + s6 += carry5; + s5 -= carry5 << 21; + carry7 = (s7 + (1 << 20)) >> 21; + s8 += carry7; + s7 -= carry7 << 21; + carry9 = (s9 + (1 << 20)) >> 21; + s10 += carry9; + s9 -= carry9 << 21; + carry11 = (s11 + (1 << 20)) >> 21; + s12 += carry11; + s11 -= carry11 << 21; + s0 += s12 * 666643; + s1 += s12 * 470296; + s2 += s12 * 654183; + s3 -= s12 * 997805; + s4 += s12 * 136657; + s5 -= s12 * 683901; + s12 = 0; + carry0 = s0 >> 21; + s1 += carry0; + s0 -= carry0 << 21; + carry1 = s1 >> 21; + s2 += carry1; + s1 -= carry1 << 21; + carry2 = s2 >> 21; + s3 += carry2; + s2 -= carry2 << 21; + carry3 = s3 >> 21; + s4 += carry3; + s3 -= carry3 << 21; + carry4 = s4 >> 21; + s5 += carry4; + s4 -= carry4 << 21; + carry5 = s5 >> 21; + s6 += carry5; + s5 -= carry5 << 21; + carry6 = s6 >> 21; + s7 += carry6; + s6 -= carry6 << 21; + carry7 = s7 >> 21; + s8 += carry7; + s7 -= carry7 << 21; + carry8 = s8 >> 21; + s9 += carry8; + s8 -= carry8 << 21; + carry9 = s9 >> 21; + s10 += carry9; + s9 -= carry9 << 21; + carry10 = s10 >> 21; + s11 += carry10; + s10 -= carry10 << 21; + carry11 = s11 >> 21; + s12 += carry11; + s11 -= carry11 << 21; + s0 += s12 * 666643; + s1 += s12 * 470296; + s2 += s12 * 654183; + s3 -= s12 * 997805; + s4 += s12 * 136657; + s5 -= s12 * 683901; + s12 = 0; + carry0 = s0 >> 21; + s1 += carry0; + s0 -= carry0 << 21; + carry1 = s1 >> 21; + s2 += carry1; + s1 -= carry1 << 21; + carry2 = s2 >> 21; + s3 += carry2; + s2 -= carry2 << 21; + carry3 = s3 >> 21; + s4 += carry3; + s3 -= carry3 << 21; + carry4 = s4 >> 21; + s5 += carry4; + s4 -= carry4 << 21; + carry5 = s5 >> 21; + s6 += carry5; + s5 -= carry5 << 21; + carry6 = s6 >> 21; + s7 += carry6; + s6 -= carry6 << 21; + carry7 = s7 >> 21; + s8 += carry7; + s7 -= carry7 << 21; + carry8 = s8 >> 21; + s9 += carry8; + s8 -= carry8 << 21; + carry9 = s9 >> 21; + s10 += carry9; + s9 -= carry9 << 21; + carry10 = s10 >> 21; + s11 += carry10; + s10 -= carry10 << 21; + + s[0] = (unsigned char) (s0 >> 0); + s[1] = (unsigned char) (s0 >> 8); + s[2] = (unsigned char) ((s0 >> 16) | (s1 << 5)); + s[3] = (unsigned char) (s1 >> 3); + s[4] = (unsigned char) (s1 >> 11); + s[5] = (unsigned char) ((s1 >> 19) | (s2 << 2)); + s[6] = (unsigned char) (s2 >> 6); + s[7] = (unsigned char) ((s2 >> 14) | (s3 << 7)); + s[8] = (unsigned char) (s3 >> 1); + s[9] = (unsigned char) (s3 >> 9); + s[10] = (unsigned char) ((s3 >> 17) | (s4 << 4)); + s[11] = (unsigned char) (s4 >> 4); + s[12] = (unsigned char) (s4 >> 12); + s[13] = (unsigned char) ((s4 >> 20) | (s5 << 1)); + s[14] = (unsigned char) (s5 >> 7); + s[15] = (unsigned char) ((s5 >> 15) | (s6 << 6)); + s[16] = (unsigned char) (s6 >> 2); + s[17] = (unsigned char) (s6 >> 10); + s[18] = (unsigned char) ((s6 >> 18) | (s7 << 3)); + s[19] = (unsigned char) (s7 >> 5); + s[20] = (unsigned char) (s7 >> 13); + s[21] = (unsigned char) (s8 >> 0); + s[22] = (unsigned char) (s8 >> 8); + s[23] = (unsigned char) ((s8 >> 16) | (s9 << 5)); + s[24] = (unsigned char) (s9 >> 3); + s[25] = (unsigned char) (s9 >> 11); + s[26] = (unsigned char) ((s9 >> 19) | (s10 << 2)); + s[27] = (unsigned char) (s10 >> 6); + s[28] = (unsigned char) ((s10 >> 14) | (s11 << 7)); + s[29] = (unsigned char) (s11 >> 1); + s[30] = (unsigned char) (s11 >> 9); + s[31] = (unsigned char) (s11 >> 17); +} diff --git a/src/ed25519/sc.h b/src/ed25519/sc.h new file mode 100644 index 0000000..8fa727e --- /dev/null +++ b/src/ed25519/sc.h @@ -0,0 +1,12 @@ +#ifndef SC_H +#define SC_H + +/* +The set of scalars is \Z/l +where l = 2^252 + 27742317777372353535851937790883648493. +*/ + +void sc_reduce(unsigned char *s); +void sc_muladd(unsigned char *s, const unsigned char *a, const unsigned char *b, const unsigned char *c); + +#endif \ No newline at end of file diff --git a/src/ed25519/sha512.c b/src/ed25519/sha512.c new file mode 100644 index 0000000..cb8ae71 --- /dev/null +++ b/src/ed25519/sha512.c @@ -0,0 +1,275 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +#include "fixedint.h" +#include "sha512.h" + +/* the K array */ +static const uint64_t K[80] = { + UINT64_C(0x428a2f98d728ae22), UINT64_C(0x7137449123ef65cd), + UINT64_C(0xb5c0fbcfec4d3b2f), UINT64_C(0xe9b5dba58189dbbc), + UINT64_C(0x3956c25bf348b538), UINT64_C(0x59f111f1b605d019), + UINT64_C(0x923f82a4af194f9b), UINT64_C(0xab1c5ed5da6d8118), + UINT64_C(0xd807aa98a3030242), UINT64_C(0x12835b0145706fbe), + UINT64_C(0x243185be4ee4b28c), UINT64_C(0x550c7dc3d5ffb4e2), + UINT64_C(0x72be5d74f27b896f), UINT64_C(0x80deb1fe3b1696b1), + UINT64_C(0x9bdc06a725c71235), UINT64_C(0xc19bf174cf692694), + UINT64_C(0xe49b69c19ef14ad2), UINT64_C(0xefbe4786384f25e3), + UINT64_C(0x0fc19dc68b8cd5b5), UINT64_C(0x240ca1cc77ac9c65), + UINT64_C(0x2de92c6f592b0275), UINT64_C(0x4a7484aa6ea6e483), + UINT64_C(0x5cb0a9dcbd41fbd4), UINT64_C(0x76f988da831153b5), + UINT64_C(0x983e5152ee66dfab), UINT64_C(0xa831c66d2db43210), + UINT64_C(0xb00327c898fb213f), UINT64_C(0xbf597fc7beef0ee4), + UINT64_C(0xc6e00bf33da88fc2), UINT64_C(0xd5a79147930aa725), + UINT64_C(0x06ca6351e003826f), UINT64_C(0x142929670a0e6e70), + UINT64_C(0x27b70a8546d22ffc), UINT64_C(0x2e1b21385c26c926), + UINT64_C(0x4d2c6dfc5ac42aed), UINT64_C(0x53380d139d95b3df), + UINT64_C(0x650a73548baf63de), UINT64_C(0x766a0abb3c77b2a8), + UINT64_C(0x81c2c92e47edaee6), UINT64_C(0x92722c851482353b), + UINT64_C(0xa2bfe8a14cf10364), UINT64_C(0xa81a664bbc423001), + UINT64_C(0xc24b8b70d0f89791), UINT64_C(0xc76c51a30654be30), + UINT64_C(0xd192e819d6ef5218), UINT64_C(0xd69906245565a910), + UINT64_C(0xf40e35855771202a), UINT64_C(0x106aa07032bbd1b8), + UINT64_C(0x19a4c116b8d2d0c8), UINT64_C(0x1e376c085141ab53), + UINT64_C(0x2748774cdf8eeb99), UINT64_C(0x34b0bcb5e19b48a8), + UINT64_C(0x391c0cb3c5c95a63), UINT64_C(0x4ed8aa4ae3418acb), + UINT64_C(0x5b9cca4f7763e373), UINT64_C(0x682e6ff3d6b2b8a3), + UINT64_C(0x748f82ee5defb2fc), UINT64_C(0x78a5636f43172f60), + UINT64_C(0x84c87814a1f0ab72), UINT64_C(0x8cc702081a6439ec), + UINT64_C(0x90befffa23631e28), UINT64_C(0xa4506cebde82bde9), + UINT64_C(0xbef9a3f7b2c67915), UINT64_C(0xc67178f2e372532b), + UINT64_C(0xca273eceea26619c), UINT64_C(0xd186b8c721c0c207), + UINT64_C(0xeada7dd6cde0eb1e), UINT64_C(0xf57d4f7fee6ed178), + UINT64_C(0x06f067aa72176fba), UINT64_C(0x0a637dc5a2c898a6), + UINT64_C(0x113f9804bef90dae), UINT64_C(0x1b710b35131c471b), + UINT64_C(0x28db77f523047d84), UINT64_C(0x32caab7b40c72493), + UINT64_C(0x3c9ebe0a15c9bebc), UINT64_C(0x431d67c49c100d4c), + UINT64_C(0x4cc5d4becb3e42b6), UINT64_C(0x597f299cfc657e2a), + UINT64_C(0x5fcb6fab3ad6faec), UINT64_C(0x6c44198c4a475817) +}; + +/* Various logical functions */ + +#define ROR64c(x, y) \ + ( ((((x)&UINT64_C(0xFFFFFFFFFFFFFFFF))>>((uint64_t)(y)&UINT64_C(63))) | \ + ((x)<<((uint64_t)(64-((y)&UINT64_C(63)))))) & UINT64_C(0xFFFFFFFFFFFFFFFF)) + +#define STORE64H(x, y) \ + { (y)[0] = (unsigned char)(((x)>>56)&255); (y)[1] = (unsigned char)(((x)>>48)&255); \ + (y)[2] = (unsigned char)(((x)>>40)&255); (y)[3] = (unsigned char)(((x)>>32)&255); \ + (y)[4] = (unsigned char)(((x)>>24)&255); (y)[5] = (unsigned char)(((x)>>16)&255); \ + (y)[6] = (unsigned char)(((x)>>8)&255); (y)[7] = (unsigned char)((x)&255); } + +#define LOAD64H(x, y) \ + { x = (((uint64_t)((y)[0] & 255))<<56)|(((uint64_t)((y)[1] & 255))<<48) | \ + (((uint64_t)((y)[2] & 255))<<40)|(((uint64_t)((y)[3] & 255))<<32) | \ + (((uint64_t)((y)[4] & 255))<<24)|(((uint64_t)((y)[5] & 255))<<16) | \ + (((uint64_t)((y)[6] & 255))<<8)|(((uint64_t)((y)[7] & 255))); } + + +#define Ch(x,y,z) (z ^ (x & (y ^ z))) +#define Maj(x,y,z) (((x | y) & z) | (x & y)) +#define S(x, n) ROR64c(x, n) +#define R(x, n) (((x) &UINT64_C(0xFFFFFFFFFFFFFFFF))>>((uint64_t)n)) +#define Sigma0(x) (S(x, 28) ^ S(x, 34) ^ S(x, 39)) +#define Sigma1(x) (S(x, 14) ^ S(x, 18) ^ S(x, 41)) +#define Gamma0(x) (S(x, 1) ^ S(x, 8) ^ R(x, 7)) +#define Gamma1(x) (S(x, 19) ^ S(x, 61) ^ R(x, 6)) +#ifndef MIN + #define MIN(x, y) ( ((x)<(y))?(x):(y) ) +#endif + +/* compress 1024-bits */ +static int sha512_compress(sha512_context *md, unsigned char *buf) +{ + uint64_t S[8], W[80], t0, t1; + int i; + + /* copy state into S */ + for (i = 0; i < 8; i++) { + S[i] = md->state[i]; + } + + /* copy the state into 1024-bits into W[0..15] */ + for (i = 0; i < 16; i++) { + LOAD64H(W[i], buf + (8*i)); + } + + /* fill W[16..79] */ + for (i = 16; i < 80; i++) { + W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16]; + } + +/* Compress */ + #define RND(a,b,c,d,e,f,g,h,i) \ + t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i]; \ + t1 = Sigma0(a) + Maj(a, b, c);\ + d += t0; \ + h = t0 + t1; + + for (i = 0; i < 80; i += 8) { + RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],i+0); + RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],i+1); + RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],i+2); + RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],i+3); + RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],i+4); + RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],i+5); + RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],i+6); + RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],i+7); + } + + #undef RND + + + + /* feedback */ + for (i = 0; i < 8; i++) { + md->state[i] = md->state[i] + S[i]; + } + + return 0; +} + + +/** + Initialize the hash state + @param md The hash state you wish to initialize + @return 0 if successful +*/ +int sha512_init(sha512_context * md) { + if (md == NULL) return 1; + + md->curlen = 0; + md->length = 0; + md->state[0] = UINT64_C(0x6a09e667f3bcc908); + md->state[1] = UINT64_C(0xbb67ae8584caa73b); + md->state[2] = UINT64_C(0x3c6ef372fe94f82b); + md->state[3] = UINT64_C(0xa54ff53a5f1d36f1); + md->state[4] = UINT64_C(0x510e527fade682d1); + md->state[5] = UINT64_C(0x9b05688c2b3e6c1f); + md->state[6] = UINT64_C(0x1f83d9abfb41bd6b); + md->state[7] = UINT64_C(0x5be0cd19137e2179); + + return 0; +} + +/** + Process a block of memory though the hash + @param md The hash state + @param in The data to hash + @param inlen The length of the data (octets) + @return 0 if successful +*/ +int sha512_update (sha512_context * md, const unsigned char *in, size_t inlen) +{ + size_t n; + size_t i; + int err; + if (md == NULL) return 1; + if (in == NULL) return 1; + if (md->curlen > sizeof(md->buf)) { + return 1; + } + while (inlen > 0) { + if (md->curlen == 0 && inlen >= 128) { + if ((err = sha512_compress (md, (unsigned char *)in)) != 0) { + return err; + } + md->length += 128 * 8; + in += 128; + inlen -= 128; + } else { + n = MIN(inlen, (128 - md->curlen)); + + for (i = 0; i < n; i++) { + md->buf[i + md->curlen] = in[i]; + } + + + md->curlen += n; + in += n; + inlen -= n; + if (md->curlen == 128) { + if ((err = sha512_compress (md, md->buf)) != 0) { + return err; + } + md->length += 8*128; + md->curlen = 0; + } + } + } + return 0; +} + +/** + Terminate the hash to get the digest + @param md The hash state + @param out [out] The destination of the hash (64 bytes) + @return 0 if successful +*/ + int sha512_final(sha512_context * md, unsigned char *out) + { + int i; + + if (md == NULL) return 1; + if (out == NULL) return 1; + + if (md->curlen >= sizeof(md->buf)) { + return 1; + } + + /* increase the length of the message */ + md->length += md->curlen * UINT64_C(8); + + /* append the '1' bit */ + md->buf[md->curlen++] = (unsigned char)0x80; + + /* if the length is currently above 112 bytes we append zeros + * then compress. Then we can fall back to padding zeros and length + * encoding like normal. + */ + if (md->curlen > 112) { + while (md->curlen < 128) { + md->buf[md->curlen++] = (unsigned char)0; + } + sha512_compress(md, md->buf); + md->curlen = 0; + } + + /* pad upto 120 bytes of zeroes + * note: that from 112 to 120 is the 64 MSB of the length. We assume that you won't hash + * > 2^64 bits of data... :-) + */ +while (md->curlen < 120) { + md->buf[md->curlen++] = (unsigned char)0; +} + + /* store length */ +STORE64H(md->length, md->buf+120); +sha512_compress(md, md->buf); + + /* copy output */ +for (i = 0; i < 8; i++) { + STORE64H(md->state[i], out+(8*i)); +} + +return 0; +} + +int sha512(const unsigned char *message, size_t message_len, unsigned char *out) +{ + sha512_context ctx; + int ret; + if ((ret = sha512_init(&ctx))) return ret; + if ((ret = sha512_update(&ctx, message, message_len))) return ret; + if ((ret = sha512_final(&ctx, out))) return ret; + return 0; +} diff --git a/src/ed25519/sha512.h b/src/ed25519/sha512.h new file mode 100644 index 0000000..e56b00e --- /dev/null +++ b/src/ed25519/sha512.h @@ -0,0 +1,21 @@ +#ifndef SHA512_H +#define SHA512_H + +#include + +#include "fixedint.h" + +/* state */ +typedef struct sha512_context_ { + uint64_t length, state[8]; + size_t curlen; + unsigned char buf[128]; +} sha512_context; + + +int sha512_init(sha512_context * md); +int sha512_final(sha512_context * md, unsigned char *out); +int sha512_update(sha512_context * md, const unsigned char *in, size_t inlen); +int sha512(const unsigned char *message, size_t message_len, unsigned char *out); + +#endif \ No newline at end of file diff --git a/src/ed25519/sign.c b/src/ed25519/sign.c new file mode 100644 index 0000000..199a839 --- /dev/null +++ b/src/ed25519/sign.c @@ -0,0 +1,31 @@ +#include "ed25519.h" +#include "sha512.h" +#include "ge.h" +#include "sc.h" + + +void ed25519_sign(unsigned char *signature, const unsigned char *message, size_t message_len, const unsigned char *public_key, const unsigned char *private_key) { + sha512_context hash; + unsigned char hram[64]; + unsigned char r[64]; + ge_p3 R; + + + sha512_init(&hash); + sha512_update(&hash, private_key + 32, 32); + sha512_update(&hash, message, message_len); + sha512_final(&hash, r); + + sc_reduce(r); + ge_scalarmult_base(&R, r); + ge_p3_tobytes(signature, &R); + + sha512_init(&hash); + sha512_update(&hash, signature, 32); + sha512_update(&hash, public_key, 32); + sha512_update(&hash, message, message_len); + sha512_final(&hash, hram); + + sc_reduce(hram); + sc_muladd(signature + 32, hram, private_key, r); +} diff --git a/src/ed25519/verify.c b/src/ed25519/verify.c new file mode 100644 index 0000000..32f988e --- /dev/null +++ b/src/ed25519/verify.c @@ -0,0 +1,77 @@ +#include "ed25519.h" +#include "sha512.h" +#include "ge.h" +#include "sc.h" + +static int consttime_equal(const unsigned char *x, const unsigned char *y) { + unsigned char r = 0; + + r = x[0] ^ y[0]; + #define F(i) r |= x[i] ^ y[i] + F(1); + F(2); + F(3); + F(4); + F(5); + F(6); + F(7); + F(8); + F(9); + F(10); + F(11); + F(12); + F(13); + F(14); + F(15); + F(16); + F(17); + F(18); + F(19); + F(20); + F(21); + F(22); + F(23); + F(24); + F(25); + F(26); + F(27); + F(28); + F(29); + F(30); + F(31); + #undef F + + return !r; +} + +int ed25519_verify(const unsigned char *signature, const unsigned char *message, size_t message_len, const unsigned char *public_key) { + unsigned char h[64]; + unsigned char checker[32]; + sha512_context hash; + ge_p3 A; + ge_p2 R; + + if (signature[63] & 224) { + return 0; + } + + if (ge_frombytes_negate_vartime(&A, public_key) != 0) { + return 0; + } + + sha512_init(&hash); + sha512_update(&hash, signature, 32); + sha512_update(&hash, public_key, 32); + sha512_update(&hash, message, message_len); + sha512_final(&hash, h); + + sc_reduce(h); + ge_double_scalarmult_vartime(&R, h, &A, signature + 32); + ge_tobytes(checker, &R); + + if (!consttime_equal(checker, signature)) { + return 0; + } + + return 1; +} diff --git a/src/edge.c b/src/edge.c index f185b4f..2eaae5d 100644 --- a/src/edge.c +++ b/src/edge.c @@ -110,11 +110,13 @@ bool dump_edges(connection_t *c) { for splay_each(node_t, n, node_tree) { for splay_each(edge_t, e, n->edge_tree) { char *address = sockaddr2hostname(&e->address); - send_request(c, "%d %d %s %s %s %x %d", + char* local_address = sockaddr2hostname(&e->local_address); + send_request(c, "%d %d %s %s %s %s %x %d", CONTROL, REQ_DUMP_EDGES, e->from->name, e->to->name, address, - e->options, e->weight); + local_address, e->options, e->weight); free(address); + free(local_address); } } diff --git a/src/edge.h b/src/edge.h index cbd9e5a..ed46b8a 100644 --- a/src/edge.h +++ b/src/edge.h @@ -30,6 +30,7 @@ typedef struct edge_t { struct node_t *from; struct node_t *to; sockaddr_t address; + sockaddr_t local_address; uint32_t options; /* options turned on for this edge */ int weight; /* weight of this edge */ diff --git a/src/event.c b/src/event.c index 5a1e4f5..60d357d 100644 --- a/src/event.c +++ b/src/event.c @@ -23,15 +23,26 @@ #include "event.h" #include "net.h" #include "utils.h" +#include "xalloc.h" struct timeval now; +#ifndef HAVE_MINGW static fd_set readfds; static fd_set writefds; -static volatile bool running; +#else +static const long READ_EVENTS = FD_READ | FD_ACCEPT | FD_CLOSE; +static const long WRITE_EVENTS = FD_WRITE | FD_CONNECT; +static DWORD event_count = 0; +#endif +static bool running; static int io_compare(const io_t *a, const io_t *b) { +#ifndef HAVE_MINGW return a->fd - b->fd; +#else + return a->event - b->event; +#endif } static int timeout_compare(const timeout_t *a, const timeout_t *b) { @@ -60,6 +71,14 @@ void io_add(io_t *io, io_cb_t cb, void *data, int fd, int flags) { return; io->fd = fd; +#ifdef HAVE_MINGW + if (io->fd != -1) { + io->event = WSACreateEvent(); + if (io->event == WSA_INVALID_EVENT) + abort(); + } + event_count++; +#endif io->cb = cb; io->data = data; io->node.data = io; @@ -70,9 +89,21 @@ void io_add(io_t *io, io_cb_t cb, void *data, int fd, int flags) { abort(); } -void io_set(io_t *io, int flags) { - io->flags = flags; +#ifdef HAVE_MINGW +void io_add_event(io_t *io, io_cb_t cb, void *data, WSAEVENT event) { + io->event = event; + io_add(io, cb, data, -1, 0); +} +#endif +void io_set(io_t *io, int flags) { + if (flags == io->flags) + return; + io->flags = flags; + if (io->fd == -1) + return; + +#ifndef HAVE_MINGW if(flags & IO_READ) FD_SET(io->fd, &readfds); else @@ -82,6 +113,15 @@ void io_set(io_t *io, int flags) { FD_SET(io->fd, &writefds); else FD_CLR(io->fd, &writefds); +#else + long events = 0; + if (flags & IO_WRITE) + events |= WRITE_EVENTS; + if (flags & IO_READ) + events |= READ_EVENTS; + if (WSAEventSelect(io->fd, io->event, events) != 0) + abort(); +#endif } void io_del(io_t *io) { @@ -89,6 +129,11 @@ void io_del(io_t *io) { return; io_set(io, 0); +#ifdef HAVE_MINGW + if (io->fd != -1 && WSACloseEvent(io->event) == FALSE) + abort(); + event_count--; +#endif splay_unlink_node(&io_tree, &io->node); io->cb = NULL; @@ -182,30 +227,37 @@ void signal_del(signal_t *sig) { } #endif +static struct timeval * get_time_remaining(struct timeval *diff) { + gettimeofday(&now, NULL); + struct timeval *tv = NULL; + + while(timeout_tree.head) { + timeout_t *timeout = timeout_tree.head->data; + timersub(&timeout->tv, &now, diff); + + if(diff->tv_sec < 0) { + timeout->cb(timeout->data); + if(timercmp(&timeout->tv, &now, <)) + timeout_del(timeout); + } else { + tv = diff; + break; + } + } + + return tv; +} + bool event_loop(void) { running = true; +#ifndef HAVE_MINGW fd_set readable; fd_set writable; while(running) { - gettimeofday(&now, NULL); - struct timeval diff, *tv = NULL; - - while(timeout_tree.head) { - timeout_t *timeout = timeout_tree.head->data; - timersub(&timeout->tv, &now, &diff); - - if(diff.tv_sec < 0) { - timeout->cb(timeout->data); - if(timercmp(&timeout->tv, &now, <)) - timeout_del(timeout); - } else { - tv = &diff; - break; - } - } - + struct timeval diff; + struct timeval *tv = get_time_remaining(&diff); memcpy(&readable, &readfds, sizeof readable); memcpy(&writable, &writefds, sizeof writable); @@ -216,16 +268,10 @@ bool event_loop(void) { fds = last->fd + 1; } -#ifdef HAVE_MINGW - LeaveCriticalSection(&mutex); -#endif int n = select(fds, &readable, &writable, NULL, tv); -#ifdef HAVE_MINGW - EnterCriticalSection(&mutex); -#endif if(n < 0) { - if(sockwouldblock(errno)) + if(sockwouldblock(sockerrno)) continue; else return false; @@ -241,16 +287,77 @@ bool event_loop(void) { io->cb(io->data, IO_READ); } } +#else + while (running) { + struct timeval diff; + struct timeval *tv = get_time_remaining(&diff); + DWORD timeout_ms = tv ? (tv->tv_sec * 1000 + tv->tv_usec / 1000 + 1) : WSA_INFINITE; + + if (!event_count) { + Sleep(timeout_ms); + continue; + } + + /* + For some reason, Microsoft decided to make the FD_WRITE event edge-triggered instead of level-triggered, + which is the opposite of what select() does. In practice, that means that if a FD_WRITE event triggers, + it will never trigger again until a send() returns EWOULDBLOCK. Since the semantics of this event loop + is that write events are level-triggered (i.e. they continue firing until the socket is full), we need + to emulate these semantics by making sure we fire each IO_WRITE that is still writeable. + + Note that technically FD_CLOSE has the same problem, but it's okay because user code does not rely on + this event being fired again if ignored. + */ + io_t* writeable_io = NULL; + for splay_each(io_t, io, &io_tree) + if (io->flags & IO_WRITE && send(io->fd, NULL, 0, 0) == 0) { + writeable_io = io; + break; + } + if (writeable_io) { + writeable_io->cb(writeable_io->data, IO_WRITE); + continue; + } + + WSAEVENT* events = xmalloc(event_count * sizeof(*events)); + DWORD event_index = 0; + for splay_each(io_t, io, &io_tree) { + events[event_index] = io->event; + event_index++; + } + + DWORD result = WSAWaitForMultipleEvents(event_count, events, FALSE, timeout_ms, FALSE); + + WSAEVENT event; + if (result >= WSA_WAIT_EVENT_0 && result < WSA_WAIT_EVENT_0 + event_count) + event = events[result - WSA_WAIT_EVENT_0]; + free(events); + if (result == WSA_WAIT_TIMEOUT) + continue; + if (result < WSA_WAIT_EVENT_0 || result >= WSA_WAIT_EVENT_0 + event_count) + return false; + + io_t *io = splay_search(&io_tree, &((io_t){.event = event})); + if (!io) + abort(); + + if (io->fd == -1) { + io->cb(io->data, 0); + } else { + WSANETWORKEVENTS network_events; + if (WSAEnumNetworkEvents(io->fd, io->event, &network_events) != 0) + return false; + if (network_events.lNetworkEvents & WRITE_EVENTS) + io->cb(io->data, IO_WRITE); + if (network_events.lNetworkEvents & READ_EVENTS) + io->cb(io->data, IO_READ); + } + } +#endif return true; } -void event_flush_output(void) { - for splay_each(io_t, io, &io_tree) - if(FD_ISSET(io->fd, &writefds)) - io->cb(io->data, IO_WRITE); -} - void event_exit(void) { running = false; } diff --git a/src/event.h b/src/event.h index c6522c0..0ff8e01 100644 --- a/src/event.h +++ b/src/event.h @@ -32,6 +32,9 @@ typedef void (*signal_cb_t)(void *data); typedef struct io_t { int fd; int flags; +#ifdef HAVE_MINGW + WSAEVENT event; +#endif io_cb_t cb; void *data; splay_node_t node; @@ -54,6 +57,9 @@ typedef struct signal_t { extern struct timeval now; extern void io_add(io_t *io, io_cb_t cb, void *data, int fd, int flags); +#ifdef HAVE_MINGW +extern void io_add_event(io_t *io, io_cb_t cb, void* data, WSAEVENT event); +#endif extern void io_del(io_t *io); extern void io_set(io_t *io, int flags); @@ -65,7 +71,6 @@ extern void signal_add(signal_t *sig, signal_cb_t cb, void *data, int signum); extern void signal_del(signal_t *sig); extern bool event_loop(void); -extern void event_flush_output(void); extern void event_exit(void); #endif diff --git a/src/graph.c b/src/graph.c index 396e35a..70d6573 100644 --- a/src/graph.c +++ b/src/graph.c @@ -176,9 +176,13 @@ static void sssp_bfs(void) { && (e->to->distance != n->distance + 1 || e->weight >= e->to->prevedge->weight)) continue; + // Only update nexthop if it doesn't increase the path length + + if(!e->to->status.visited || (e->to->distance == n->distance + 1 && e->weight >= e->to->prevedge->weight)) + e->to->nexthop = (n->nexthop == myself) ? e->to : n->nexthop; + e->to->status.visited = true; e->to->status.indirect = indirect; - e->to->nexthop = (n->nexthop == myself) ? e->to : n->nexthop; e->to->prevedge = e; e->to->via = indirect ? n->via : e->to; e->to->options = e->options; @@ -200,6 +204,9 @@ static void sssp_bfs(void) { static void check_reachability(void) { /* Check reachability status. */ + int reachable_count = 0; + int became_reachable_count = 0; + int became_unreachable_count = 0; for splay_each(node_t, n, node_tree) { if(n->status.visited != n->status.reachable) { n->status.reachable = !n->status.reachable; @@ -208,9 +215,13 @@ static void check_reachability(void) { if(n->status.reachable) { logger(DEBUG_TRAFFIC, LOG_DEBUG, "Node %s (%s) became reachable", n->name, n->hostname); + if (n != myself) + became_reachable_count++; } else { logger(DEBUG_TRAFFIC, LOG_DEBUG, "Node %s (%s) became unreachable", n->name, n->hostname); + if (n != myself) + became_unreachable_count++; } if(experimental && OPTION_VERSION(n->options) >= 2) @@ -264,15 +275,18 @@ static void check_reachability(void) { update_node_udp(n, NULL); memset(&n->status, 0, sizeof n->status); n->options = 0; - } else if(n->connection) { - if(n->status.sptps) { - if(n->connection->outgoing) - send_req_key(n); - } else { - send_ans_key(n); - } } } + + if(n->status.reachable && n != myself) + reachable_count++; + } + + if (device_standby) { + if (reachable_count == 0 && became_unreachable_count > 0) + device_disable(); + else if (reachable_count > 0 && reachable_count == became_reachable_count) + device_enable(); } } diff --git a/src/hash.c b/src/hash.c index 8fb9ca6..91fc3d6 100644 --- a/src/hash.c +++ b/src/hash.c @@ -91,6 +91,13 @@ void *hash_search_or_insert(hash_t *hash, const void *key, const void *value) { return NULL; } +/* Deleting */ + +void hash_delete(hash_t *hash, const void *key) { + uint32_t i = modulo(hash_function(key, hash->size), hash->n); + hash->values[i] = NULL; +} + /* Utility functions */ void hash_clear(hash_t *hash) { diff --git a/src/hash.h b/src/hash.h index 83ed6af..30a15fb 100644 --- a/src/hash.h +++ b/src/hash.h @@ -31,6 +31,7 @@ extern hash_t *hash_alloc(size_t n, size_t size) __attribute__ ((__malloc__)); extern void hash_free(hash_t *); extern void hash_insert(hash_t *, const void *key, const void *value); +extern void hash_delete(hash_t *, const void *key); extern void *hash_search(const hash_t *, const void *key); extern void *hash_search_or_insert(hash_t *, const void *key, const void *value); diff --git a/src/have.h b/src/have.h index 3ada63a..85479f7 100644 --- a/src/have.h +++ b/src/have.h @@ -39,6 +39,7 @@ #include #include #include +#include #ifdef HAVE_MINGW #include diff --git a/src/info.c b/src/info.c index af085bc..b9a6fcf 100644 --- a/src/info.c +++ b/src/info.c @@ -24,6 +24,7 @@ #include "subnet.h" #include "tincctl.h" #include "info.h" +#include "utils.h" #include "xalloc.h" void logger(int level, int priority, const char *format, ...) { @@ -49,6 +50,7 @@ static int info_node(int fd, const char *item) { char line[4096]; char node[4096]; + char id[4096]; char from[4096]; char to[4096]; char subnet[4096]; @@ -67,12 +69,12 @@ static int info_node(int fd, const char *item) { long int last_state_change; while(recvline(fd, line, sizeof line)) { - int n = sscanf(line, "%d %d %s %s port %s %d %d %d %d %x %"PRIx32" %s %s %d %hd %hd %hd %ld", &code, &req, node, host, port, &cipher, &digest, &maclength, &compression, &options, &status_union.raw, nexthop, via, &distance, &pmtu, &minmtu, &maxmtu, &last_state_change); + int n = sscanf(line, "%d %d %s %s %s port %s %d %d %d %d %x %"PRIx32" %s %s %d %hd %hd %hd %ld", &code, &req, node, id, host, port, &cipher, &digest, &maclength, &compression, &options, &status_union.raw, nexthop, via, &distance, &pmtu, &minmtu, &maxmtu, &last_state_change); if(n == 2) break; - if(n != 18) { + if(n != 19) { fprintf(stderr, "Unable to parse node dump from tincd.\n"); return 1; } @@ -94,6 +96,7 @@ static int info_node(int fd, const char *item) { } printf("Node: %s\n", item); + printf("Node ID: %s\n", id); printf("Address: %s port %s\n", host, port); char timestr[32] = "never"; diff --git a/src/invitation.c b/src/invitation.c index 59bcf45..dff8d5f 100644 --- a/src/invitation.c +++ b/src/invitation.c @@ -1,6 +1,6 @@ /* invitation.c -- Create and accept invitations - Copyright (C) 2013 Guus Sliepen + Copyright (C) 2013-2014 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 @@ -142,12 +142,19 @@ char *get_my_hostname() { } } + if(!tty) { + if(!hostname) { + fprintf(stderr, "Could not determine the external address or hostname. Please set Address manually.\n"); + return NULL; + } + goto save; + } + again: - printf("Please enter your host's external address or hostname"); + fprintf(stderr, "Please enter your host's external address or hostname"); if(hostname) - printf(" [%s]", hostname); - printf(": "); - fflush(stdout); + fprintf(stderr, " [%s]", hostname); + fprintf(stderr, ": "); if(!fgets(line, sizeof line, stdin)) { fprintf(stderr, "Error while reading stdin: %s\n", strerror(errno)); @@ -190,8 +197,10 @@ done: else xasprintf(&hostport, "%s:%s", hostname, port); } else { - hostport = hostname; - hostname = NULL; + if(strchr(hostname, ':')) + xasprintf(&hostport, "[%s]", hostname); + else + hostport = xstrdup(hostname); } free(hostname); @@ -241,7 +250,7 @@ int cmd_invite(int argc, char *argv[]) { } free(filename); - // If a daemon is running, ensure no other nodes now about this name + // If a daemon is running, ensure no other nodes know about this name bool found = false; if(connect_tincd(false)) { sendline(fd, "%d %d", CONTROL, REQ_DUMP_NODES); @@ -312,7 +321,7 @@ int cmd_invite(int argc, char *argv[]) { free(filename); ecdsa_t *key; - xasprintf(&filename, "%s" SLASH "invitations" SLASH "ecdsa_key.priv", confbase); + xasprintf(&filename, "%s" SLASH "invitations" SLASH "ed25519_key.priv", confbase); // Remove the key if there are no outstanding invitations. if(!count) @@ -404,8 +413,12 @@ int cmd_invite(int argc, char *argv[]) { char buf[1024]; while(fgets(buf, sizeof buf, tc)) { if((!strncasecmp(buf, "Mode", 4) && strchr(" \t=", buf[4])) - || (!strncasecmp(buf, "Broadcast", 9) && strchr(" \t=", buf[9]))) + || (!strncasecmp(buf, "Broadcast", 9) && strchr(" \t=", buf[9]))) { fputs(buf, f); + // Make sure there is a newline character. + if(!strchr(buf, '\n')) + fputc('\n', f); + } } fclose(tc); } @@ -567,7 +580,7 @@ make_names: if(!access(tinc_conf, F_OK)) { fprintf(stderr, "Configuration file %s already exists!\n", tinc_conf); - if(!tty || confbasegiven) + if(confbasegiven) return false; // Generate a random netname, ask for a better one later. @@ -600,6 +613,7 @@ make_names: FILE *fh = fopen(filename, "w"); if(!fh) { fprintf(stderr, "Could not create file %s: %s\n", filename, strerror(errno)); + fclose(f); return false; } @@ -709,7 +723,7 @@ make_names: if(!b64key) return false; - xasprintf(&filename, "%s" SLASH "ecdsa_key.priv", confbase); + xasprintf(&filename, "%s" SLASH "ed25519_key.priv", confbase); f = fopenmask(filename, "w", 0600); if(!ecdsa_write_pem_private_key(key, f)) { @@ -721,7 +735,7 @@ make_names: fclose(f); - fprintf(fh, "ECDSAPublicKey = %s\n", b64key); + fprintf(fh, "Ed25519PublicKey = %s\n", b64key); sptps_send_record(&sptps, 1, b64key, strlen(b64key)); free(b64key); @@ -743,7 +757,7 @@ make_names: check_port(name); ask_netname: - if(ask_netname) { + if(ask_netname && tty) { fprintf(stderr, "Enter a new netname: "); if(!fgets(line, sizeof line, stdin)) { fprintf(stderr, "Error while reading stdin: %s\n", strerror(errno)); @@ -767,11 +781,13 @@ ask_netname: make_names(); } + fprintf(stderr, "Configuration stored in: %s\n", confbase); + return true; } -static bool invitation_send(void *handle, uint8_t type, const char *data, size_t len) { +static bool invitation_send(void *handle, uint8_t type, const void *data, size_t len) { while(len) { int result = send(sock, data, len, 0); if(result == -1 && errno == EINTR) @@ -784,7 +800,7 @@ static bool invitation_send(void *handle, uint8_t type, const char *data, size_t return true; } -static bool invitation_receive(void *handle, uint8_t type, const char *msg, uint16_t len) { +static bool invitation_receive(void *handle, uint8_t type, const void *msg, uint16_t len) { switch(type) { case SPTPS_HANDSHAKE: return sptps_send_record(&sptps, 0, cookie, sizeof cookie); @@ -850,10 +866,8 @@ int cmd_join(int argc, char *argv[]) { if(argc > 1) { invitation = argv[1]; } else { - if(tty) { - printf("Enter invitation URL: "); - fflush(stdout); - } + if(tty) + fprintf(stderr, "Enter invitation URL: "); errno = EPIPE; if(!fgets(line, sizeof line, stdin)) { fprintf(stderr, "Error while reading stdin: %s\n", strerror(errno)); @@ -893,7 +907,7 @@ int cmd_join(int argc, char *argv[]) { if(!port || !*port) port = "655"; - if(!b64decode(slash, hash, 18) || !b64decode(slash + 24, cookie, 18)) + if(!b64decode(slash, hash, 24) || !b64decode(slash + 24, cookie, 24)) goto invalid; // Generate a throw-away key for the invitation. diff --git a/src/linux/device.c b/src/linux/device.c index 127e3e8..5717d92 100644 --- a/src/linux/device.c +++ b/src/linux/device.c @@ -1,7 +1,7 @@ /* device.c -- Interaction with Linux ethertap and tun/tap device Copyright (C) 2001-2005 Ivo Timmermans, - 2001-2013 Guus Sliepen + 2001-2014 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 @@ -46,11 +46,6 @@ static char *type = NULL; static char ifrname[IFNAMSIZ]; static char *device_info; -uint64_t device_in_packets = 0; -uint64_t device_in_bytes = 0; -uint64_t device_out_packets = 0; -uint64_t device_out_bytes = 0; - static bool setup_device(void) { if(!get_config_string(lookup_config(config_tree, "Device"), &device)) device = xstrdup(DEFAULT_DEVICE); @@ -110,15 +105,25 @@ static bool setup_device(void) { logger(DEBUG_ALWAYS, LOG_INFO, "%s is a %s", device, device_info); + if(ifr.ifr_flags & IFF_TAP) { + struct ifreq ifr_mac = {}; + if(!ioctl(device_fd, SIOCGIFHWADDR, &ifr_mac)) + memcpy(mymac.x, ifr_mac.ifr_hwaddr.sa_data, ETH_ALEN); + else + logger(DEBUG_ALWAYS, LOG_WARNING, "Could not get MAC address of %s: %s", device, strerror(errno)); + } + return true; } static void close_device(void) { close(device_fd); + device_fd = -1; - free(type); - free(device); - free(iface); + free(type); type = NULL; + free(device); device = NULL; + free(iface); iface = NULL; + device_info = NULL; } static bool read_packet(vpn_packet_t *packet) { @@ -126,7 +131,7 @@ static bool read_packet(vpn_packet_t *packet) { switch(device_type) { case DEVICE_TYPE_TUN: - inlen = read(device_fd, packet->data + 10, MTU - 10); + inlen = read(device_fd, DATA(packet) + 10, MTU - 10); if(inlen <= 0) { logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", @@ -134,11 +139,11 @@ static bool read_packet(vpn_packet_t *packet) { return false; } - memset(packet->data, 0, 12); + memset(DATA(packet), 0, 12); packet->len = inlen + 10; break; case DEVICE_TYPE_TAP: - inlen = read(device_fd, packet->data, MTU); + inlen = read(device_fd, DATA(packet), MTU); if(inlen <= 0) { logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", @@ -152,9 +157,6 @@ static bool read_packet(vpn_packet_t *packet) { abort(); } - device_in_packets++; - device_in_bytes += packet->len; - logger(DEBUG_TRAFFIC, LOG_DEBUG, "Read packet of %d bytes from %s", packet->len, device_info); @@ -167,15 +169,15 @@ static bool write_packet(vpn_packet_t *packet) { switch(device_type) { case DEVICE_TYPE_TUN: - packet->data[10] = packet->data[11] = 0; - if(write(device_fd, packet->data + 10, packet->len - 10) < 0) { + DATA(packet)[10] = DATA(packet)[11] = 0; + if(write(device_fd, DATA(packet) + 10, packet->len - 10) < 0) { logger(DEBUG_ALWAYS, LOG_ERR, "Can't write to %s %s: %s", device_info, device, strerror(errno)); return false; } break; case DEVICE_TYPE_TAP: - if(write(device_fd, packet->data, packet->len) < 0) { + if(write(device_fd, DATA(packet), packet->len) < 0) { logger(DEBUG_ALWAYS, LOG_ERR, "Can't write to %s %s: %s", device_info, device, strerror(errno)); return false; @@ -185,22 +187,12 @@ static bool write_packet(vpn_packet_t *packet) { abort(); } - device_out_packets++; - device_out_bytes += packet->len; - return true; } -static void dump_device_stats(void) { - logger(DEBUG_ALWAYS, LOG_DEBUG, "Statistics for %s %s:", device_info, device); - logger(DEBUG_ALWAYS, LOG_DEBUG, " total bytes in: %10"PRIu64, device_in_bytes); - logger(DEBUG_ALWAYS, LOG_DEBUG, " total bytes out: %10"PRIu64, device_out_bytes); -} - const devops_t os_devops = { .setup = setup_device, .close = close_device, .read = read_packet, .write = write_packet, - .dump_stats = dump_device_stats, }; diff --git a/src/logger.h b/src/logger.h index 637eef8..8f69029 100644 --- a/src/logger.h +++ b/src/logger.h @@ -65,6 +65,8 @@ enum { #endif #endif +#include + extern debug_t debug_level; extern bool logcontrol; extern void openlogger(const char *, logmode_t); diff --git a/src/meta.c b/src/meta.c index 887da4a..73769d9 100644 --- a/src/meta.c +++ b/src/meta.c @@ -1,6 +1,6 @@ /* meta.c -- handle the meta communication - Copyright (C) 2000-2013 Guus Sliepen , + Copyright (C) 2000-2014 Guus Sliepen , 2000-2005 Ivo Timmermans 2006 Scott Lamb @@ -30,7 +30,7 @@ #include "utils.h" #include "xalloc.h" -bool send_meta_sptps(void *handle, uint8_t type, const char *buffer, size_t length) { +bool send_meta_sptps(void *handle, uint8_t type, const void *buffer, size_t length) { connection_t *c = handle; if(!c) { @@ -76,11 +76,12 @@ bool send_meta(connection_t *c, const char *buffer, int length) { void broadcast_meta(connection_t *from, const char *buffer, int length) { for list_each(connection_t, c, connection_list) - if(c != from && c->status.active) + if(c != from && c->edge) send_meta(c, buffer, length); } -bool receive_meta_sptps(void *handle, uint8_t type, const char *data, uint16_t length) { +bool receive_meta_sptps(void *handle, uint8_t type, const void *vdata, uint16_t length) { + const char *data = vdata; connection_t *c = handle; if(!c) { @@ -142,7 +143,7 @@ bool receive_meta(connection_t *c) { inlen = recv(c->socket, inbuf, sizeof inbuf - c->inbuf.len, 0); if(inlen <= 0) { - if(!inlen || !errno) { + if(!inlen || !sockerrno) { logger(DEBUG_CONNECTIONS, LOG_NOTICE, "Connection closed by %s (%s)", c->name, c->hostname); } else if(sockwouldblock(sockerrno)) diff --git a/src/meta.h b/src/meta.h index 2a71228..ddc5418 100644 --- a/src/meta.h +++ b/src/meta.h @@ -1,6 +1,6 @@ /* meta.h -- header for meta.c - Copyright (C) 2000-2012 Guus Sliepen , + Copyright (C) 2000-2014 Guus Sliepen , 2000-2005 Ivo Timmermans This program is free software; you can redistribute it and/or modify @@ -24,8 +24,8 @@ #include "connection.h" extern bool send_meta(struct connection_t *, const char *, int); -extern bool send_meta_sptps(void *, uint8_t, const char *, size_t); -extern bool receive_meta_sptps(void *, uint8_t, const char *, uint16_t); +extern bool send_meta_sptps(void *, uint8_t, const void *, size_t); +extern bool receive_meta_sptps(void *, uint8_t, const void *, uint16_t); extern void broadcast_meta(struct connection_t *, const char *, int); extern bool receive_meta(struct connection_t *); diff --git a/src/mingw/device.c b/src/mingw/device.c index abe544e..19719a7 100644 --- a/src/mingw/device.c +++ b/src/mingw/device.c @@ -1,7 +1,7 @@ /* device.c -- Interaction with Windows tap driver in a MinGW environment Copyright (C) 2002-2005 Ivo Timmermans, - 2002-2013 Guus Sliepen + 2002-2014 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,55 +36,52 @@ int device_fd = -1; static HANDLE device_handle = INVALID_HANDLE_VALUE; +static io_t device_read_io; +static OVERLAPPED device_read_overlapped; +static vpn_packet_t device_read_packet; char *device = NULL; char *iface = NULL; static char *device_info = NULL; -static uint64_t device_total_in = 0; -static uint64_t device_total_out = 0; - extern char *myport; -static DWORD WINAPI tapreader(void *bla) { +static void device_issue_read() { + device_read_overlapped.Offset = 0; + device_read_overlapped.OffsetHigh = 0; + int status; - DWORD len; - OVERLAPPED overlapped; - vpn_packet_t packet; - - logger(DEBUG_ALWAYS, LOG_DEBUG, "Tap reader running"); - - /* Read from tap device and send to parent */ - - overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); - - for(;;) { - overlapped.Offset = 0; - overlapped.OffsetHigh = 0; - ResetEvent(overlapped.hEvent); - - status = ReadFile(device_handle, (void *)packet.data, MTU, &len, &overlapped); - - if(!status) { - if(GetLastError() == ERROR_IO_PENDING) { - WaitForSingleObject(overlapped.hEvent, INFINITE); - if(!GetOverlappedResult(device_handle, &overlapped, &len, FALSE)) - continue; - } else { + for (;;) { + DWORD len; + status = ReadFile(device_handle, (void *)device_read_packet.data, MTU, &len, &device_read_overlapped); + if (!status) { + if (GetLastError() != ERROR_IO_PENDING) logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info, device, strerror(errno)); - return -1; - } + break; } - EnterCriticalSection(&mutex); - packet.len = len; - packet.priority = 0; - route(myself, &packet); - event_flush_output(); - LeaveCriticalSection(&mutex); + device_read_packet.len = len; + device_read_packet.priority = 0; + route(myself, &device_read_packet); } } +static void device_handle_read(void *data, int flags) { + ResetEvent(device_read_overlapped.hEvent); + + DWORD len; + if (!GetOverlappedResult(device_handle, &device_read_overlapped, &len, FALSE)) { + logger(DEBUG_ALWAYS, LOG_ERR, "Error getting read result from %s %s: %s", device_info, + device, strerror(errno)); + return; + } + + device_read_packet.len = len; + device_read_packet.priority = 0; + route(myself, &device_read_packet); + device_issue_read(); +} + static bool setup_device(void) { HKEY key, key2; int i; @@ -94,12 +91,10 @@ static bool setup_device(void) { char adaptername[1024]; char tapname[1024]; DWORD len; - unsigned long status; bool found = false; int err; - HANDLE thread; get_config_string(lookup_config(config_tree, "Device"), &device); get_config_string(lookup_config(config_tree, "Interface"), &iface); @@ -191,20 +186,6 @@ static bool setup_device(void) { overwrite_mac = 1; } - /* Start the tap reader */ - - thread = CreateThread(NULL, 0, tapreader, NULL, 0, NULL); - - if(!thread) { - logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "CreateThread", winerror(GetLastError())); - return false; - } - - /* Set media status for newer TAP-Win32 devices */ - - status = true; - DeviceIoControl(device_handle, TAP_IOCTL_SET_MEDIA_STATUS, &status, sizeof status, &status, sizeof status, &len, NULL); - device_info = "Windows tap device"; logger(DEBUG_ALWAYS, LOG_INFO, "%s (%s) is a %s", device, iface, device_info); @@ -212,11 +193,36 @@ static bool setup_device(void) { return true; } -static void close_device(void) { - CloseHandle(device_handle); +static void enable_device(void) { + logger(DEBUG_ALWAYS, LOG_INFO, "Enabling %s", device_info); - free(device); - free(iface); + ULONG status = 1; + DWORD len; + DeviceIoControl(device_handle, TAP_IOCTL_SET_MEDIA_STATUS, &status, sizeof status, &status, sizeof status, &len, NULL); + + io_add_event(&device_read_io, device_handle_read, NULL, CreateEvent(NULL, TRUE, FALSE, NULL)); + device_read_overlapped.hEvent = device_read_io.event; + device_issue_read(); +} + +static void disable_device(void) { + logger(DEBUG_ALWAYS, LOG_INFO, "Disabling %s", device_info); + + io_del(&device_read_io); + CancelIo(device_handle); + CloseHandle(device_read_overlapped.hEvent); + + ULONG status = 0; + DWORD len; + DeviceIoControl(device_handle, TAP_IOCTL_SET_MEDIA_STATUS, &status, sizeof status, &status, sizeof status, &len, NULL); +} + +static void close_device(void) { + CloseHandle(device_handle); device_handle = INVALID_HANDLE_VALUE; + + free(device); device = NULL; + free(iface); iface = NULL; + device_info = NULL; } static bool read_packet(vpn_packet_t *packet) { @@ -230,26 +236,19 @@ static bool write_packet(vpn_packet_t *packet) { logger(DEBUG_TRAFFIC, LOG_DEBUG, "Writing packet of %d bytes to %s", packet->len, device_info); - if(!WriteFile(device_handle, packet->data, packet->len, &outlen, &overlapped)) { + if(!WriteFile(device_handle, DATA(packet), packet->len, &outlen, &overlapped)) { logger(DEBUG_ALWAYS, LOG_ERR, "Error while writing to %s %s: %s", device_info, device, winerror(GetLastError())); return false; } - device_total_out += packet->len; - return true; } -static void dump_device_stats(void) { - logger(DEBUG_ALWAYS, LOG_DEBUG, "Statistics for %s %s:", device_info, device); - logger(DEBUG_ALWAYS, LOG_DEBUG, " total bytes in: %10"PRIu64, device_total_in); - logger(DEBUG_ALWAYS, LOG_DEBUG, " total bytes out: %10"PRIu64, device_total_out); -} - const devops_t os_devops = { .setup = setup_device, .close = close_device, .read = read_packet, .write = write_packet, - .dump_stats = dump_device_stats, + .enable = enable_device, + .disable = disable_device, }; diff --git a/src/multicast_device.c b/src/multicast_device.c index 600b77c..931a8d0 100644 --- a/src/multicast_device.c +++ b/src/multicast_device.c @@ -31,9 +31,6 @@ static char *device_info; -static uint64_t device_total_in = 0; -static uint64_t device_total_out = 0; - static struct addrinfo *ai = NULL; static mac_t ignore_src = {{0}}; @@ -132,7 +129,7 @@ static bool setup_device(void) { #endif default: - logger(DEBUG_ALWAYS, LOG_ERR, "Multicast for address family %hx unsupported", ai->ai_family); + logger(DEBUG_ALWAYS, LOG_ERR, "Multicast for address family %x unsupported", ai->ai_family); goto error; } @@ -151,33 +148,33 @@ error: } static void close_device(void) { - close(device_fd); + close(device_fd); device_fd = -1; - free(device); - free(iface); + free(device); device = NULL; + free(iface); iface = NULL; - if(ai) - freeaddrinfo(ai); + if(ai) { + freeaddrinfo(ai); ai = NULL; + } + device_info = NULL; } static bool read_packet(vpn_packet_t *packet) { int lenin; - if((lenin = recv(device_fd, (void *)packet->data, MTU, 0)) <= 0) { + if((lenin = recv(device_fd, DATA(packet), MTU, 0)) <= 0) { logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info, - device, strerror(errno)); + device, sockstrerror(sockerrno)); return false; } - if(!memcmp(&ignore_src, packet->data + 6, sizeof ignore_src)) { + if(!memcmp(&ignore_src, DATA(packet) + 6, sizeof ignore_src)) { logger(DEBUG_SCARY_THINGS, LOG_DEBUG, "Ignoring loopback packet of %d bytes from %s", lenin, device_info); return false; } packet->len = lenin; - device_total_in += packet->len; - logger(DEBUG_TRAFFIC, LOG_DEBUG, "Read packet of %d bytes from %s", packet->len, device_info); @@ -188,45 +185,20 @@ static bool write_packet(vpn_packet_t *packet) { logger(DEBUG_TRAFFIC, LOG_DEBUG, "Writing packet of %d bytes to %s", packet->len, device_info); - if(sendto(device_fd, (void *)packet->data, packet->len, 0, ai->ai_addr, ai->ai_addrlen) < 0) { + if(sendto(device_fd, DATA(packet), packet->len, 0, ai->ai_addr, ai->ai_addrlen) < 0) { logger(DEBUG_ALWAYS, LOG_ERR, "Can't write to %s %s: %s", device_info, device, - strerror(errno)); + sockstrerror(sockerrno)); return false; } - device_total_out += packet->len; - - memcpy(&ignore_src, packet->data + 6, sizeof ignore_src); + memcpy(&ignore_src, DATA(packet) + 6, sizeof ignore_src); return true; } -static void dump_device_stats(void) { - logger(DEBUG_ALWAYS, LOG_DEBUG, "Statistics for %s %s:", device_info, device); - logger(DEBUG_ALWAYS, LOG_DEBUG, " total bytes in: %10"PRIu64, device_total_in); - logger(DEBUG_ALWAYS, LOG_DEBUG, " total bytes out: %10"PRIu64, device_total_out); -} - const devops_t multicast_devops = { .setup = setup_device, .close = close_device, .read = read_packet, .write = write_packet, - .dump_stats = dump_device_stats, }; - -#if 0 - -static bool not_supported(void) { - logger(DEBUG_ALWAYS, LOG_ERR, "Raw socket device not supported on this platform"); - return false; -} - -const devops_t multicast_devops = { - .setup = not_supported, - .close = NULL, - .read = NULL, - .write = NULL, - .dump_stats = NULL, -}; -#endif diff --git a/src/names.c b/src/names.c index 37708f8..8218216 100644 --- a/src/names.c +++ b/src/names.c @@ -64,8 +64,6 @@ void make_names(void) { else xasprintf(&confbase, "%s", installdir); } - if(!pidfilename) - xasprintf(&pidfilename, "%s" SLASH "pid", confbase); } RegCloseKey(key); } @@ -73,11 +71,26 @@ void make_names(void) { if(!confdir) confdir = xstrdup(CONFDIR SLASH "tinc"); + if(!confbase) { + if(netname) + xasprintf(&confbase, CONFDIR SLASH "tinc" SLASH "%s", netname); + else + xasprintf(&confbase, CONFDIR SLASH "tinc"); + } + +#ifdef HAVE_MINGW + if(!logfilename) + xasprintf(&logfilename, "%s" SLASH "log", confbase); + + if(!pidfilename) + xasprintf(&pidfilename, "%s" SLASH "pid", confbase); +#else if(!logfilename) xasprintf(&logfilename, LOCALSTATEDIR SLASH "log" SLASH "%s.log", identname); if(!pidfilename) xasprintf(&pidfilename, LOCALSTATEDIR SLASH "run" SLASH "%s.pid", identname); +#endif if(!unixsocketname) { int len = strlen(pidfilename); @@ -88,13 +101,6 @@ void make_names(void) { else strcpy(unixsocketname + len, ".socket"); } - - if(!confbase) { - if(netname) - xasprintf(&confbase, CONFDIR SLASH "tinc" SLASH "%s", netname); - else - xasprintf(&confbase, CONFDIR SLASH "tinc"); - } } void free_names(void) { diff --git a/src/net.c b/src/net.c index 286f157..91b9305 100644 --- a/src/net.c +++ b/src/net.c @@ -36,6 +36,10 @@ #include "subnet.h" #include "xalloc.h" +#ifdef HAVE_RESOLV_H +#include +#endif + int contradicting_add_edge = 0; int contradicting_del_edge = 0; static int sleeptime = 10; @@ -93,8 +97,6 @@ void purge(void) { void terminate_connection(connection_t *c, bool report) { logger(DEBUG_CONNECTIONS, LOG_NOTICE, "Closing connection with %s (%s)", c->name, c->hostname); - c->status.active = false; - if(c->node && c->node->connection == c) c->node->connection = NULL; @@ -129,6 +131,12 @@ void terminate_connection(connection_t *c, bool report) { if(outgoing) do_outgoing_connection(outgoing); + +#ifndef HAVE_MINGW + /* Clean up dead proxy processes */ + + while(waitpid(-1, NULL, WNOHANG) > 0); +#endif } /* @@ -145,7 +153,7 @@ static void timeout_handler(void *data) { continue; if(c->last_ping_time + pingtimeout <= now.tv_sec) { - if(c->status.active) { + if(c->edge) { if(c->status.pinged) { logger(DEBUG_CONNECTIONS, LOG_INFO, "%s (%s) didn't respond to PING in %ld seconds", c->name, c->hostname, (long)now.tv_sec - c->last_ping_time); } else if(c->last_ping_time + pinginterval <= now.tv_sec) { @@ -160,7 +168,7 @@ static void timeout_handler(void *data) { else logger(DEBUG_CONNECTIONS, LOG_WARNING, "Timeout from %s (%s) during authentication", c->name, c->hostname); } - terminate_connection(c, c->status.active); + terminate_connection(c, c->edge); } } @@ -194,11 +202,11 @@ static void periodic_handler(void *data) { /* Count number of active connections */ int nc = 0; for list_each(connection_t, c, connection_list) { - if(c->status.active && !c->status.control) + if(c->edge) nc++; } - if(nc < autoconnect) { + if(nc < 3) { /* Not enough active connections, try to add one. Choose a random node, if we don't have a connection to it, and we are not already trying to make one, create an @@ -232,7 +240,7 @@ static void periodic_handler(void *data) { } break; } - } else if(nc > autoconnect) { + } else if(nc > 3) { /* Too many active connections, try to remove one. Choose a random outgoing connection to a node that has at least one other connection. @@ -241,7 +249,7 @@ static void periodic_handler(void *data) { int i = 0; for list_each(connection_t, c, connection_list) { - if(!c->status.active || c->status.control) + if(!c->edge) continue; if(i++ != r) @@ -253,12 +261,12 @@ static void periodic_handler(void *data) { logger(DEBUG_CONNECTIONS, LOG_INFO, "Autodisconnecting from %s", c->name); list_delete(outgoing_list, c->outgoing); c->outgoing = NULL; - terminate_connection(c, c->status.active); + terminate_connection(c, c->edge); break; } } - if(nc >= autoconnect) { + if(nc >= 3) { /* If we have enough active connections, remove any pending outgoing connections. */ @@ -283,7 +291,7 @@ static void periodic_handler(void *data) { void handle_meta_connection_data(connection_t *c) { if (!receive_meta(c)) { - terminate_connection(c, c->status.active); + terminate_connection(c, c->edge); return; } } @@ -303,6 +311,9 @@ static void sighup_handler(void *data) { static void sigalrm_handler(void *data) { logger(DEBUG_ALWAYS, LOG_NOTICE, "Got %s signal", strsignal(((signal_t *)data)->signum)); +#ifdef HAVE_DECL_RES_INIT + res_init(); +#endif retry(); } #endif @@ -334,11 +345,14 @@ int reload_configuration(void) { if(strictsubnets) { for splay_each(subnet_t, subnet, subnet_tree) - subnet->expires = 1; + if (subnet->owner) + subnet->expires = 1; load_all_subnets(); for splay_each(subnet_t, subnet, subnet_tree) { + if (!subnet->owner) + continue; if(subnet->expires == 1) { send_del_subnet(everyone, subnet); if(subnet->owner->status.reachable) @@ -402,7 +416,7 @@ int reload_configuration(void) { struct stat s; if(stat(fname, &s) || s.st_mtime > last_config_check) { logger(DEBUG_CONNECTIONS, LOG_INFO, "Host config file of %s has been changed", c->name); - terminate_connection(c, c->status.active); + terminate_connection(c, c->edge); } free(fname); } @@ -452,7 +466,7 @@ int main_loop(void) { #endif if(!event_loop()) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error while waiting for input: %s", strerror(errno)); + logger(DEBUG_ALWAYS, LOG_ERR, "Error while waiting for input: %s", sockstrerror(sockerrno)); return 1; } diff --git a/src/net.h b/src/net.h index 9a97276..dcc99a4 100644 --- a/src/net.h +++ b/src/net.h @@ -1,7 +1,7 @@ /* net.h -- header for net.c Copyright (C) 1998-2005 Ivo Timmermans - 2000-2013 Guus Sliepen + 2000-2014 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 @@ -32,8 +32,8 @@ #define MTU 1518 /* 1500 bytes payload + 14 bytes ethernet header + 4 bytes VLAN tag */ #endif -/* MAXSIZE is the maximum size of an encapsulated packet: MTU + seqno + padding + HMAC + compressor overhead */ -#define MAXSIZE (MTU + 4 + CIPHER_MAX_BLOCK_SIZE + DIGEST_MAX_SIZE + MTU/64 + 20) +/* MAXSIZE is the maximum size of an encapsulated packet: MTU + seqno + srcid + dstid + padding + HMAC + compressor overhead */ +#define MAXSIZE (MTU + 4 + sizeof(node_id_t) + sizeof(node_id_t) + CIPHER_MAX_BLOCK_SIZE + DIGEST_MAX_SIZE + MTU/64 + 20) /* MAXBUFSIZE is the maximum size of a request: enough for a MAXSIZEd packet or a 8192 bits RSA key */ #define MAXBUFSIZE ((MAXSIZE > 2048 ? MAXSIZE : 2048) + 128) @@ -52,7 +52,12 @@ typedef struct ipv6_t { uint16_t x[8]; } ipv6_t; +typedef struct node_id_t { + uint8_t x[6]; +} node_id_t; + typedef short length_t; +typedef uint32_t seqno_t; #define AF_UNKNOWN 255 @@ -80,10 +85,16 @@ typedef union sockaddr_t { #define SALEN(s) (s.sa_family==AF_INET?sizeof(struct sockaddr_in):sizeof(struct sockaddr_in6)) #endif +#define SEQNO(x) ((x)->data + (x)->offset - 4) +#define SRCID(x) ((node_id_t *)((x)->data + (x)->offset - 6)) +#define DSTID(x) ((node_id_t *)((x)->data + (x)->offset - 12)) +#define DATA(x) ((x)->data + (x)->offset) +#define DEFAULT_PACKET_OFFSET 12 + typedef struct vpn_packet_t { - length_t len; /* the actual number of bytes in the `data' field */ + length_t len; /* The actual number of valid bytes in the `data' field (including seqno or dstid/srcid) */ + length_t offset; /* Offset in the buffer where the packet data starts (righter after seqno or dstid/srcid) */ int priority; /* priority or TOS */ - uint32_t seqno; /* 32 bits sequence number (network byte order of course) */ uint8_t data[MAXSIZE]; } vpn_packet_t; @@ -103,6 +114,7 @@ typedef struct listen_socket_t { io_t tcp; io_t udp; sockaddr_t sa; + bool bindto; } listen_socket_t; #include "conf.h" @@ -125,7 +137,6 @@ extern int seconds_till_retry; extern int addressfamily; extern unsigned replaywin; extern bool localdiscovery; -extern sockaddr_t localdiscovery_address; extern listen_socket_t listen_socket[MAXSOCKETS]; extern int listen_sockets; @@ -136,7 +147,8 @@ extern int udp_sndbuf; extern int max_connection_burst; extern bool do_prune; extern char *myport; -extern int autoconnect; +extern bool device_standby; +extern bool autoconnect; extern bool disablebuggypeers; extern int contradicting_add_edge; extern int contradicting_del_edge; @@ -171,12 +183,14 @@ extern void handle_new_meta_connection(void *, int); extern void handle_new_unix_connection(void *, int); extern int setup_listen_socket(const sockaddr_t *); extern int setup_vpn_in_socket(const sockaddr_t *); -extern bool send_sptps_data(void *handle, uint8_t type, const char *data, size_t len); -extern bool receive_sptps_record(void *handle, uint8_t type, const char *data, uint16_t len); +extern bool send_sptps_data(void *handle, uint8_t type, const void *data, size_t len); +extern bool receive_sptps_record(void *handle, uint8_t type, const void *data, uint16_t len); extern void send_packet(struct node_t *, vpn_packet_t *); extern void receive_tcppacket(struct connection_t *, const char *, int); extern void broadcast_packet(const struct node_t *, vpn_packet_t *); extern char *get_name(void); +extern void device_enable(void); +extern void device_disable(void); extern bool setup_myself_reloadable(void); extern bool setup_network(void); extern void setup_outgoing_connection(struct outgoing_t *); @@ -199,8 +213,6 @@ extern void load_all_nodes(void); #ifndef HAVE_MINGW #define closesocket(s) close(s) -#else -extern CRITICAL_SECTION mutex; #endif #endif /* __TINC_NET_H__ */ diff --git a/src/net_packet.c b/src/net_packet.c index 1159231..c146109 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-2013 Guus Sliepen + 2000-2014 Guus Sliepen 2010 Timothy Redaelli 2010 Brandon Black @@ -54,8 +54,7 @@ static char lzo_wrkmem[LZO1X_999_MEM_COMPRESS > LZO1X_1_MEM_COMPRESS ? LZO1X_999 static void send_udppacket(node_t *, vpn_packet_t *); unsigned replaywin = 16; -bool localdiscovery = false; -sockaddr_t localdiscovery_address; +bool localdiscovery = true; #define MAX_SEQNO 1073741824 @@ -140,19 +139,19 @@ static void send_mtu_probe_handler(void *data) { len = 64; vpn_packet_t packet; - memset(packet.data, 0, 14); - randomize(packet.data + 14, len - 14); + packet.offset = DEFAULT_PACKET_OFFSET; + memset(DATA(&packet), 0, 14); + randomize(DATA(&packet) + 14, len - 14); packet.len = len; - if(i >= 4 && n->mtuprobes <= 10) - packet.priority = -1; - else - packet.priority = 0; + packet.priority = 0; + n->status.send_locally = i >= 4 && n->mtuprobes <= 10 && n->prevedge; logger(DEBUG_TRAFFIC, LOG_INFO, "Sending MTU probe length %d to %s (%s)", len, n->name, n->hostname); send_udppacket(n, &packet); } + n->status.send_locally = false; n->probe_counter = 0; gettimeofday(&n->probe_time, NULL); @@ -178,24 +177,24 @@ void send_mtu_probe(node_t *n) { } static void mtu_probe_h(node_t *n, vpn_packet_t *packet, length_t len) { - if(!packet->data[0]) { + if(!DATA(packet)[0]) { logger(DEBUG_TRAFFIC, LOG_INFO, "Got MTU probe request %d from %s (%s)", packet->len, n->name, n->hostname); /* It's a probe request, send back a reply */ /* Type 2 probe replies were introduced in protocol 17.3 */ - if ((n->options >> 24) == 3) { - uint8_t* data = packet->data; + if ((n->options >> 24) >= 3) { + uint8_t *data = DATA(packet); *data++ = 2; uint16_t len16 = htons(len); memcpy(data, &len16, 2); data += 2; struct timeval now; gettimeofday(&now, NULL); uint32_t sec = htonl(now.tv_sec); memcpy(data, &sec, 4); data += 4; uint32_t usec = htonl(now.tv_usec); memcpy(data, &usec, 4); data += 4; - packet->len = data - packet->data; + packet->len -= 10; } else { /* Legacy protocol: n won't understand type 2 probe replies. */ - packet->data[0] = 1; + DATA(packet)[0] = 1; } /* Temporarily set udp_confirmed, so that the reply is sent @@ -207,14 +206,14 @@ static void mtu_probe_h(node_t *n, vpn_packet_t *packet, length_t len) { n->status.udp_confirmed = udp_confirmed; } else { length_t probelen = len; - if (packet->data[0] == 2) { + if (DATA(packet)[0] == 2) { if (len < 3) logger(DEBUG_TRAFFIC, LOG_WARNING, "Received invalid (too short) MTU probe reply from %s (%s)", n->name, n->hostname); else { - uint16_t probelen16; memcpy(&probelen16, packet->data + 1, 2); probelen = ntohs(probelen16); + uint16_t probelen16; memcpy(&probelen16, DATA(packet) + 1, 2); probelen = ntohs(probelen16); } } - logger(DEBUG_TRAFFIC, LOG_INFO, "Got type %d MTU probe reply %d from %s (%s)", packet->data[0], probelen, n->name, n->hostname); + logger(DEBUG_TRAFFIC, LOG_INFO, "Got type %d MTU probe reply %d from %s (%s)", DATA(packet)[0], probelen, n->name, n->hostname); /* It's a valid reply: now we know bidirectional communication is possible using the address and socket that the reply @@ -256,9 +255,9 @@ static void mtu_probe_h(node_t *n, vpn_packet_t *packet, length_t len) { timersub(&now, &n->probe_time, &diff); struct timeval probe_timestamp = now; - if (packet->data[0] == 2 && packet->len >= 11) { - uint32_t sec; memcpy(&sec, packet->data + 3, 4); - uint32_t usec; memcpy(&usec, packet->data + 7, 4); + if (DATA(packet)[0] == 2 && packet->len >= 11) { + uint32_t sec; memcpy(&sec, DATA(packet) + 3, 4); + uint32_t usec; memcpy(&usec, DATA(packet) + 7, 4); probe_timestamp.tv_sec = ntohl(sec); probe_timestamp.tv_usec = ntohl(usec); } @@ -350,20 +349,21 @@ static void receive_packet(node_t *n, vpn_packet_t *packet) { static bool try_mac(node_t *n, const vpn_packet_t *inpkt) { if(n->status.sptps) - return sptps_verify_datagram(&n->sptps, (char *)&inpkt->seqno, inpkt->len); + return sptps_verify_datagram(&n->sptps, DATA(inpkt), inpkt->len); - if(!digest_active(n->indigest) || inpkt->len < sizeof inpkt->seqno + digest_length(n->indigest)) + if(!digest_active(n->indigest) || inpkt->len < sizeof(seqno_t) + digest_length(n->indigest)) return false; - return digest_verify(n->indigest, &inpkt->seqno, inpkt->len - digest_length(n->indigest), (const char *)&inpkt->seqno + inpkt->len - digest_length(n->indigest)); + return digest_verify(n->indigest, SEQNO(inpkt), inpkt->len - digest_length(n->indigest), DATA(inpkt) + inpkt->len - digest_length(n->indigest)); } -static void receive_udppacket(node_t *n, vpn_packet_t *inpkt) { +static bool receive_udppacket(node_t *n, vpn_packet_t *inpkt) { vpn_packet_t pkt1, pkt2; vpn_packet_t *pkt[] = { &pkt1, &pkt2, &pkt1, &pkt2 }; int nextpkt = 0; - vpn_packet_t *outpkt = pkt[0]; size_t outlen; + pkt1.offset = DEFAULT_PACKET_OFFSET; + pkt2.offset = DEFAULT_PACKET_OFFSET; if(n->status.sptps) { if(!n->sptps.state) { @@ -373,43 +373,51 @@ static void receive_udppacket(node_t *n, vpn_packet_t *inpkt) { } else { logger(DEBUG_TRAFFIC, LOG_DEBUG, "Got packet from %s (%s) but he hasn't got our key yet", n->name, n->hostname); } - return; + return false; } - sptps_receive_data(&n->sptps, (char *)&inpkt->seqno, inpkt->len); - return; + inpkt->offset += 2 * sizeof(node_id_t); + if(!sptps_receive_data(&n->sptps, DATA(inpkt), inpkt->len - 2 * sizeof(node_id_t))) { + logger(DEBUG_TRAFFIC, LOG_ERR, "Got bad packet from %s (%s)", n->name, n->hostname); + return false; + } + return true; } - if(!cipher_active(n->incipher)) { + if(!n->status.validkey) { logger(DEBUG_TRAFFIC, LOG_DEBUG, "Got packet from %s (%s) but he hasn't got our key yet", n->name, n->hostname); - return; + return false; } /* Check packet length */ - if(inpkt->len < sizeof inpkt->seqno + digest_length(n->indigest)) { + if(inpkt->len < sizeof(seqno_t) + digest_length(n->indigest)) { logger(DEBUG_TRAFFIC, LOG_DEBUG, "Got too short packet from %s (%s)", n->name, n->hostname); - return; + return false; } + /* It's a legacy UDP packet, the data starts after the seqno */ + + inpkt->offset += sizeof(seqno_t); + /* Check the message authentication code */ if(digest_active(n->indigest)) { inpkt->len -= digest_length(n->indigest); - if(!digest_verify(n->indigest, &inpkt->seqno, inpkt->len, (const char *)&inpkt->seqno + inpkt->len)) { + if(!digest_verify(n->indigest, SEQNO(inpkt), inpkt->len, SEQNO(inpkt) + inpkt->len)) { logger(DEBUG_TRAFFIC, LOG_DEBUG, "Got unauthenticated packet from %s (%s)", n->name, n->hostname); - return; + return false; } } /* Decrypt the packet */ if(cipher_active(n->incipher)) { - outpkt = pkt[nextpkt++]; + vpn_packet_t *outpkt = pkt[nextpkt++]; outlen = MAXSIZE; - if(!cipher_decrypt(n->incipher, &inpkt->seqno, inpkt->len, &outpkt->seqno, &outlen, true)) { + if(!cipher_decrypt(n->incipher, SEQNO(inpkt), inpkt->len, SEQNO(outpkt), &outlen, true)) { logger(DEBUG_TRAFFIC, LOG_DEBUG, "Error decrypting packet from %s (%s)", n->name, n->hostname); - return; + return false; } outpkt->len = outlen; @@ -418,38 +426,40 @@ static void receive_udppacket(node_t *n, vpn_packet_t *inpkt) { /* Check the sequence number */ - inpkt->len -= sizeof inpkt->seqno; - inpkt->seqno = ntohl(inpkt->seqno); + seqno_t seqno; + memcpy(&seqno, SEQNO(inpkt), sizeof seqno); + seqno = ntohl(seqno); + inpkt->len -= sizeof seqno; if(replaywin) { - if(inpkt->seqno != n->received_seqno + 1) { - if(inpkt->seqno >= n->received_seqno + replaywin * 8) { + if(seqno != n->received_seqno + 1) { + if(seqno >= n->received_seqno + replaywin * 8) { if(n->farfuture++ < replaywin >> 2) { logger(DEBUG_ALWAYS, LOG_WARNING, "Packet from %s (%s) is %d seqs in the future, dropped (%u)", - n->name, n->hostname, inpkt->seqno - n->received_seqno - 1, n->farfuture); - return; + n->name, n->hostname, seqno - n->received_seqno - 1, n->farfuture); + return false; } logger(DEBUG_ALWAYS, LOG_WARNING, "Lost %d packets from %s (%s)", - inpkt->seqno - n->received_seqno - 1, n->name, n->hostname); + seqno - n->received_seqno - 1, n->name, n->hostname); memset(n->late, 0, replaywin); - } else if (inpkt->seqno <= n->received_seqno) { - if((n->received_seqno >= replaywin * 8 && inpkt->seqno <= n->received_seqno - replaywin * 8) || !(n->late[(inpkt->seqno / 8) % replaywin] & (1 << inpkt->seqno % 8))) { + } else if (seqno <= n->received_seqno) { + if((n->received_seqno >= replaywin * 8 && seqno <= n->received_seqno - replaywin * 8) || !(n->late[(seqno / 8) % replaywin] & (1 << seqno % 8))) { logger(DEBUG_ALWAYS, LOG_WARNING, "Got late or replayed packet from %s (%s), seqno %d, last received %d", - n->name, n->hostname, inpkt->seqno, n->received_seqno); - return; + n->name, n->hostname, seqno, n->received_seqno); + return false; } } else { - for(int i = n->received_seqno + 1; i < inpkt->seqno; i++) + for(int i = n->received_seqno + 1; i < seqno; i++) n->late[(i / 8) % replaywin] |= 1 << i % 8; } } n->farfuture = 0; - n->late[(inpkt->seqno / 8) % replaywin] &= ~(1 << inpkt->seqno % 8); + n->late[(seqno / 8) % replaywin] &= ~(1 << seqno % 8); } - if(inpkt->seqno > n->received_seqno) - n->received_seqno = inpkt->seqno; + if(seqno > n->received_seqno) + n->received_seqno = seqno; n->received++; @@ -461,12 +471,12 @@ static void receive_udppacket(node_t *n, vpn_packet_t *inpkt) { length_t origlen = inpkt->len; if(n->incompression) { - outpkt = pkt[nextpkt++]; + vpn_packet_t *outpkt = pkt[nextpkt++]; - if((outpkt->len = uncompress_packet(outpkt->data, inpkt->data, inpkt->len, n->incompression)) < 0) { + if((outpkt->len = uncompress_packet(DATA(outpkt), DATA(inpkt), inpkt->len, n->incompression)) < 0) { logger(DEBUG_TRAFFIC, LOG_ERR, "Error while uncompressing packet from %s (%s)", n->name, n->hostname); - return; + return false; } inpkt = outpkt; @@ -476,16 +486,18 @@ static void receive_udppacket(node_t *n, vpn_packet_t *inpkt) { inpkt->priority = 0; - if(!inpkt->data[12] && !inpkt->data[13]) + if(!DATA(inpkt)[12] && !DATA(inpkt)[13]) mtu_probe_h(n, inpkt, origlen); else receive_packet(n, inpkt); + return true; } void receive_tcppacket(connection_t *c, const char *buffer, int len) { vpn_packet_t outpkt; + outpkt.offset = DEFAULT_PACKET_OFFSET; - if(len > sizeof outpkt.data) + if(len > sizeof outpkt.data - outpkt.offset) return; outpkt.len = len; @@ -493,30 +505,46 @@ void receive_tcppacket(connection_t *c, const char *buffer, int len) { outpkt.priority = 0; else outpkt.priority = -1; - memcpy(outpkt.data, buffer, len); + memcpy(DATA(&outpkt), buffer, len); receive_packet(c->node, &outpkt); } -static void send_sptps_packet(node_t *n, vpn_packet_t *origpkt) { - if(!n->status.validkey) { - logger(DEBUG_TRAFFIC, LOG_INFO, "No valid key known yet for %s (%s)", n->name, n->hostname); - if(!n->status.waitingforkey) - send_req_key(n); - else if(n->last_req_key + 10 < now.tv_sec) { - logger(DEBUG_ALWAYS, LOG_DEBUG, "No key from %s after 10 seconds, restarting SPTPS", n->name); - sptps_stop(&n->sptps); - n->status.waitingforkey = false; - send_req_key(n); - } - return; +static bool try_sptps(node_t *n) { + if(n->status.validkey) + return true; + + /* If n is a TCP-only neighbor, we'll only use "cleartext" PACKET + messages anyway, so there's no need for SPTPS at all. */ + if(n->connection && ((myself->options | n->options) & OPTION_TCPONLY)) + return false; + + logger(DEBUG_TRAFFIC, LOG_INFO, "No valid key known yet for %s (%s)", n->name, n->hostname); + + if(!n->status.waitingforkey) + send_req_key(n); + else if(n->last_req_key + 10 < now.tv_sec) { + logger(DEBUG_ALWAYS, LOG_DEBUG, "No key from %s after 10 seconds, restarting SPTPS", n->name); + sptps_stop(&n->sptps); + n->status.waitingforkey = false; + send_req_key(n); } + return false; +} + +static void send_sptps_packet(node_t *n, vpn_packet_t *origpkt) { + /* Note: condition order is as intended - even if we have a direct + metaconnection, we want to try SPTPS anyway as it's the only way to + get UDP going */ + if(!try_sptps(n) && !n->connection) + return; + uint8_t type = 0; int offset = 0; - if(!(origpkt->data[12] | origpkt->data[13])) { - sptps_send_record(&n->sptps, PKT_PROBE, (char *)origpkt->data, origpkt->len); + if(!(DATA(origpkt)[12] | DATA(origpkt)[13])) { + sptps_send_record(&n->sptps, PKT_PROBE, (char *)DATA(origpkt), origpkt->len); return; } @@ -531,7 +559,8 @@ static void send_sptps_packet(node_t *n, vpn_packet_t *origpkt) { vpn_packet_t outpkt; if(n->outcompression) { - int len = compress_packet(outpkt.data + offset, origpkt->data + offset, origpkt->len - offset, n->outcompression); + outpkt.offset = 0; + int len = compress_packet(DATA(&outpkt) + offset, DATA(origpkt) + offset, origpkt->len - offset, n->outcompression); if(len < 0) { logger(DEBUG_TRAFFIC, LOG_ERR, "Error while compressing packet to %s (%s)", n->name, n->hostname); } else if(len < origpkt->len - offset) { @@ -541,10 +570,29 @@ static void send_sptps_packet(node_t *n, vpn_packet_t *origpkt) { } } - sptps_send_record(&n->sptps, type, (char *)origpkt->data + offset, origpkt->len - offset); + /* If we have a direct metaconnection to n, and we can't use UDP, then + don't bother with SPTPS and just use a "plaintext" PACKET message. + We don't really care about end-to-end security since we're not + sending the message through any intermediate nodes. */ + if(n->connection && origpkt->len > n->minmtu) + send_tcppacket(n->connection, origpkt); + else + sptps_send_record(&n->sptps, type, DATA(origpkt) + offset, origpkt->len - offset); return; } +static void adapt_socket(const sockaddr_t *sa, int *sock) { + /* Make sure we have a suitable socket for the chosen address */ + if(listen_socket[*sock].sa.sa.sa_family != sa->sa.sa_family) { + for(int i = 0; i < listen_sockets; i++) { + if(listen_socket[i].sa.sa.sa_family == sa->sa.sa_family) { + *sock = i; + break; + } + } + } +} + static void choose_udp_address(const node_t *n, const sockaddr_t **sa, int *sock) { /* Latest guess */ *sa = &n->address; @@ -583,54 +631,30 @@ static void choose_udp_address(const node_t *n, const sockaddr_t **sa, int *sock *sock = rand() % listen_sockets; } - /* Make sure we have a suitable socket for the chosen address */ - if(listen_socket[*sock].sa.sa.sa_family != (*sa)->sa.sa_family) { - for(int i = 0; i < listen_sockets; i++) { - if(listen_socket[i].sa.sa.sa_family == (*sa)->sa.sa_family) { - *sock = i; - break; - } - } - } + adapt_socket(*sa, sock); } -static void choose_broadcast_address(const node_t *n, const sockaddr_t **sa, int *sock) { - static sockaddr_t broadcast_ipv4 = { - .in = { - .sin_family = AF_INET, - .sin_addr.s_addr = -1, - } - }; +static void choose_local_address(const node_t *n, const sockaddr_t **sa, int *sock) { + *sa = NULL; - static sockaddr_t broadcast_ipv6 = { - .in6 = { - .sin6_family = AF_INET6, - .sin6_addr.s6_addr[0x0] = 0xff, - .sin6_addr.s6_addr[0x1] = 0x02, - .sin6_addr.s6_addr[0xf] = 0x01, - } - }; + /* Pick one of the edges from this node at random, then use its local address. */ - *sock = rand() % listen_sockets; + int i = 0; + int j = rand() % n->edge_tree->count; + edge_t *candidate = NULL; - if(listen_socket[*sock].sa.sa.sa_family == AF_INET6) { - if(localdiscovery_address.sa.sa_family == AF_INET6) { - localdiscovery_address.in6.sin6_port = n->prevedge->address.in.sin_port; - *sa = &localdiscovery_address; - } else { - broadcast_ipv6.in6.sin6_port = n->prevedge->address.in.sin_port; - broadcast_ipv6.in6.sin6_scope_id = listen_socket[*sock].sa.in6.sin6_scope_id; - *sa = &broadcast_ipv6; - } - } else { - if(localdiscovery_address.sa.sa_family == AF_INET) { - localdiscovery_address.in.sin_port = n->prevedge->address.in.sin_port; - *sa = &localdiscovery_address; - } else { - broadcast_ipv4.in.sin_port = n->prevedge->address.in.sin_port; - *sa = &broadcast_ipv4; + for splay_each(edge_t, e, n->edge_tree) { + if(i++ == j) { + candidate = e; + break; } } + + if (candidate && candidate->local_address.sa.sa_family) { + *sa = &candidate->local_address; + *sock = rand() % listen_sockets; + adapt_socket(*sa, sock); + } } static void send_udppacket(node_t *n, vpn_packet_t *origpkt) { @@ -643,8 +667,11 @@ static void send_udppacket(node_t *n, vpn_packet_t *origpkt) { size_t outlen; #if defined(SOL_IP) && defined(IP_TOS) static int priority = 0; -#endif int origpriority = origpkt->priority; +#endif + + pkt1.offset = DEFAULT_PACKET_OFFSET; + pkt2.offset = DEFAULT_PACKET_OFFSET; if(!n->status.reachable) { logger(DEBUG_TRAFFIC, LOG_INFO, "Trying to send UDP packet to unreachable node %s (%s)", n->name, n->hostname); @@ -671,7 +698,7 @@ static void send_udppacket(node_t *n, vpn_packet_t *origpkt) { return; } - if(n->options & OPTION_PMTU_DISCOVERY && inpkt->len > n->minmtu && (inpkt->data[12] | inpkt->data[13])) { + if(n->options & OPTION_PMTU_DISCOVERY && inpkt->len > n->minmtu && (DATA(inpkt)[12] | DATA(inpkt)[13])) { logger(DEBUG_TRAFFIC, LOG_INFO, "Packet for %s (%s) larger than minimum MTU, forwarding via %s", n->name, n->hostname, n != n->nexthop ? n->nexthop->name : "TCP"); @@ -689,7 +716,7 @@ static void send_udppacket(node_t *n, vpn_packet_t *origpkt) { if(n->outcompression) { outpkt = pkt[nextpkt++]; - if((outpkt->len = compress_packet(outpkt->data, inpkt->data, inpkt->len, n->outcompression)) < 0) { + if((outpkt->len = compress_packet(DATA(outpkt), DATA(inpkt), inpkt->len, n->outcompression)) < 0) { logger(DEBUG_TRAFFIC, LOG_ERR, "Error while compressing packet to %s (%s)", n->name, n->hostname); return; @@ -700,8 +727,9 @@ static void send_udppacket(node_t *n, vpn_packet_t *origpkt) { /* Add sequence number */ - inpkt->seqno = htonl(++(n->sent_seqno)); - inpkt->len += sizeof inpkt->seqno; + seqno_t seqno = htonl(++(n->sent_seqno)); + memcpy(SEQNO(inpkt), &seqno, sizeof seqno); + inpkt->len += sizeof seqno; /* Encrypt the packet */ @@ -709,7 +737,7 @@ static void send_udppacket(node_t *n, vpn_packet_t *origpkt) { outpkt = pkt[nextpkt++]; outlen = MAXSIZE; - if(!cipher_encrypt(n->outcipher, &inpkt->seqno, inpkt->len, &outpkt->seqno, &outlen, true)) { + if(!cipher_encrypt(n->outcipher, SEQNO(inpkt), inpkt->len, SEQNO(outpkt), &outlen, true)) { logger(DEBUG_TRAFFIC, LOG_ERR, "Error while encrypting packet to %s (%s)", n->name, n->hostname); goto end; } @@ -721,7 +749,7 @@ static void send_udppacket(node_t *n, vpn_packet_t *origpkt) { /* Add the message authentication code */ if(digest_active(n->outdigest)) { - if(!digest_create(n->outdigest, &inpkt->seqno, inpkt->len, (char *)&inpkt->seqno + inpkt->len)) { + if(!digest_create(n->outdigest, SEQNO(inpkt), inpkt->len, SEQNO(inpkt) + inpkt->len)) { logger(DEBUG_TRAFFIC, LOG_ERR, "Error while encrypting packet to %s (%s)", n->name, n->hostname); goto end; } @@ -731,14 +759,12 @@ static void send_udppacket(node_t *n, vpn_packet_t *origpkt) { /* Send the packet */ - const sockaddr_t *sa; + const sockaddr_t *sa = NULL; int sock; - /* Overloaded use of priority field: -1 means local broadcast */ - - if(origpriority == -1 && n->prevedge) - choose_broadcast_address(n, &sa, &sock); - else + if(n->status.send_locally) + choose_local_address(n, &sa, &sock); + if(!sa) choose_udp_address(n, &sa, &sock); #if defined(SOL_IP) && defined(IP_TOS) @@ -747,11 +773,11 @@ static void send_udppacket(node_t *n, vpn_packet_t *origpkt) { priority = origpriority; logger(DEBUG_TRAFFIC, LOG_DEBUG, "Setting outgoing packet priority to %d", priority); if(setsockopt(listen_socket[n->sock].udp.fd, SOL_IP, IP_TOS, &priority, sizeof(priority))) /* SO_PRIORITY doesn't seem to work */ - logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "setsockopt", strerror(errno)); + logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "setsockopt", sockstrerror(sockerrno)); } #endif - if(sendto(listen_socket[sock].udp.fd, (char *) &inpkt->seqno, inpkt->len, 0, &sa->sa, SALEN(sa->sa)) < 0 && !sockwouldblock(sockerrno)) { + if(sendto(listen_socket[sock].udp.fd, SEQNO(inpkt), inpkt->len, 0, &sa->sa, SALEN(sa->sa)) < 0 && !sockwouldblock(sockerrno)) { if(sockmsgsize(sockerrno)) { if(n->maxmtu >= origlen) n->maxmtu = origlen - 1; @@ -765,39 +791,67 @@ end: origpkt->len = origlen; } -bool send_sptps_data(void *handle, uint8_t type, const char *data, size_t len) { - node_t *to = handle; +static bool send_sptps_data_priv(node_t *to, node_t *from, int type, const void *data, size_t len) { + node_t *relay = (to->via != myself && (type == PKT_PROBE || (len - SPTPS_DATAGRAM_OVERHEAD) <= to->via->minmtu)) ? to->via : to->nexthop; + bool direct = from == myself && to == relay; + bool relay_supported = (relay->options >> 24) >= 4; + bool tcponly = (myself->options | relay->options) & OPTION_TCPONLY; - /* Send it via TCP if it is a handshake packet, TCPOnly is in use, or this packet is larger than the MTU. */ + /* We don't really need the relay's key, but we need to establish a UDP tunnel with it and discover its MTU. */ + if (!direct && relay_supported && !tcponly) + try_sptps(relay); - if(type >= SPTPS_HANDSHAKE || ((myself->options | to->options) & OPTION_TCPONLY) || (type != PKT_PROBE && len > to->minmtu)) { + /* Send it via TCP if it is a handshake packet, TCPOnly is in use, this is a relay packet that the other node cannot understand, or this packet is larger than the MTU. + TODO: When relaying, the original sender does not know the end-to-end PMTU (it only knows the PMTU of the first hop). + This can lead to scenarios where large packets are sent over UDP to relay, but then relay has no choice but fall back to TCP. */ + + if(type == SPTPS_HANDSHAKE || tcponly || (!direct && !relay_supported) || (type != PKT_PROBE && (len - SPTPS_DATAGRAM_OVERHEAD) > relay->minmtu)) { char buf[len * 4 / 3 + 5]; b64encode(data, buf, len); /* If no valid key is known yet, send the packets using ANS_KEY requests, to ensure we get to learn the reflexive UDP address. */ - if(!to->status.validkey) { + if(from == myself && !to->status.validkey) { to->incompression = myself->incompression; - return send_request(to->nexthop->connection, "%d %s %s %s -1 -1 -1 %d", ANS_KEY, myself->name, to->name, buf, to->incompression); + return send_request(to->nexthop->connection, "%d %s %s %s -1 -1 -1 %d", ANS_KEY, from->name, to->name, buf, to->incompression); } else { - return send_request(to->nexthop->connection, "%d %s %s %d %s", REQ_KEY, myself->name, to->name, REQ_SPTPS, buf); + return send_request(to->nexthop->connection, "%d %s %s %d %s", REQ_KEY, from->name, to->name, REQ_SPTPS, buf); } } - /* Otherwise, send the packet via UDP */ - - const sockaddr_t *sa; - int sock; - - choose_udp_address(to, &sa, &sock); - - if(sendto(listen_socket[sock].udp.fd, data, len, 0, &sa->sa, SALEN(sa->sa)) < 0 && !sockwouldblock(sockerrno)) { - if(sockmsgsize(sockerrno)) { - if(to->maxmtu >= len) - to->maxmtu = len - 1; - if(to->mtu >= len) - to->mtu = len - 1; + size_t overhead = 0; + if(relay_supported) overhead += sizeof to->id + sizeof from->id; + char buf[len + overhead]; char* buf_ptr = buf; + if(relay_supported) { + if(direct) { + /* Inform the recipient that this packet was sent directly. */ + node_id_t nullid = {}; + memcpy(buf_ptr, &nullid, sizeof nullid); buf_ptr += sizeof nullid; } else { - logger(DEBUG_TRAFFIC, LOG_WARNING, "Error sending UDP SPTPS packet to %s (%s): %s", to->name, to->hostname, sockstrerror(sockerrno)); + memcpy(buf_ptr, &to->id, sizeof to->id); buf_ptr += sizeof to->id; + } + memcpy(buf_ptr, &from->id, sizeof from->id); buf_ptr += sizeof from->id; + + } + /* TODO: if this copy turns out to be a performance concern, change sptps_send_record() to add some "pre-padding" to the buffer and use that instead */ + memcpy(buf_ptr, data, len); buf_ptr += len; + + const sockaddr_t *sa = NULL; + int sock; + if(relay->status.send_locally) + choose_local_address(relay, &sa, &sock); + if(!sa) + choose_udp_address(relay, &sa, &sock); + logger(DEBUG_TRAFFIC, LOG_INFO, "Sending packet from %s (%s) to %s (%s) via %s (%s)", from->name, from->hostname, to->name, to->hostname, relay->name, relay->hostname); + if(sendto(listen_socket[sock].udp.fd, buf, buf_ptr - buf, 0, &sa->sa, SALEN(sa->sa)) < 0 && !sockwouldblock(sockerrno)) { + if(sockmsgsize(sockerrno)) { + // Compensate for SPTPS overhead + len -= SPTPS_DATAGRAM_OVERHEAD; + if(relay->maxmtu >= len) + relay->maxmtu = len - 1; + if(relay->mtu >= len) + relay->mtu = len - 1; + } else { + logger(DEBUG_TRAFFIC, LOG_WARNING, "Error sending UDP SPTPS packet to %s (%s): %s", relay->name, relay->hostname, sockstrerror(sockerrno)); return false; } } @@ -805,7 +859,11 @@ bool send_sptps_data(void *handle, uint8_t type, const char *data, size_t len) { return true; } -bool receive_sptps_record(void *handle, uint8_t type, const char *data, uint16_t len) { +bool send_sptps_data(void *handle, uint8_t type, const void *data, size_t len) { + return send_sptps_data_priv(handle, myself, type, data, len); +} + +bool receive_sptps_record(void *handle, uint8_t type, const void *data, uint16_t len) { node_t *from = handle; if(type == SPTPS_HANDSHAKE) { @@ -823,10 +881,11 @@ bool receive_sptps_record(void *handle, uint8_t type, const char *data, uint16_t } vpn_packet_t inpkt; + inpkt.offset = DEFAULT_PACKET_OFFSET; if(type == PKT_PROBE) { inpkt.len = len; - memcpy(inpkt.data, data, len); + memcpy(DATA(&inpkt), data, len); mtu_probe_h(from, &inpkt, len); return true; } @@ -846,7 +905,7 @@ bool receive_sptps_record(void *handle, uint8_t type, const char *data, uint16_t int offset = (type & PKT_MAC) ? 0 : 14; if(type & PKT_COMPRESSED) { - length_t ulen = uncompress_packet(inpkt.data + offset, (const uint8_t *)data, len, from->incompression); + length_t ulen = uncompress_packet(DATA(&inpkt) + offset, (const uint8_t *)data, len, from->incompression); if(ulen < 0) { return false; } else { @@ -855,25 +914,25 @@ bool receive_sptps_record(void *handle, uint8_t type, const char *data, uint16_t if(inpkt.len > MAXSIZE) abort(); } else { - memcpy(inpkt.data + offset, data, len); + memcpy(DATA(&inpkt) + offset, data, len); inpkt.len = len + offset; } /* Generate the Ethernet packet type if necessary */ if(offset) { - switch(inpkt.data[14] >> 4) { + switch(DATA(&inpkt)[14] >> 4) { case 4: - inpkt.data[12] = 0x08; - inpkt.data[13] = 0x00; + DATA(&inpkt)[12] = 0x08; + DATA(&inpkt)[13] = 0x00; break; case 6: - inpkt.data[12] = 0x86; - inpkt.data[13] = 0xDD; + DATA(&inpkt)[12] = 0x86; + DATA(&inpkt)[13] = 0xDD; break; default: logger(DEBUG_TRAFFIC, LOG_ERR, "Unknown IP version %d while reading packet from %s (%s)", - inpkt.data[14] >> 4, from->name, from->hostname); + DATA(&inpkt)[14] >> 4, from->name, from->hostname); return false; } } @@ -890,7 +949,7 @@ void send_packet(node_t *n, vpn_packet_t *packet) { if(n == myself) { if(overwrite_mac) - memcpy(packet->data, mymac.x, ETH_ALEN); + memcpy(DATA(packet), mymac.x, ETH_ALEN); n->out_packets++; n->out_bytes += packet->len; devops.write(packet); @@ -948,7 +1007,7 @@ void broadcast_packet(const node_t *from, vpn_packet_t *packet) { // usually distributes the sending of broadcast packets over all nodes. case BMODE_MST: for list_each(connection_t, c, connection_list) - if(c->status.active && c->status.mst && c != from->nexthop->connection) + if(c->edge && c->status.mst && c != from->nexthop->connection) send_packet(c->node, packet); break; @@ -1002,12 +1061,14 @@ void handle_incoming_vpn_data(void *data, int flags) { listen_socket_t *ls = data; vpn_packet_t pkt; char *hostname; - sockaddr_t from = {{0}}; - socklen_t fromlen = sizeof from; - node_t *n; - int len; + node_id_t nullid = {}; + sockaddr_t addr = {}; + socklen_t addrlen = sizeof addr; + node_t *from, *to; + bool direct = false; - len = recvfrom(ls->udp.fd, (char *) &pkt.seqno, MAXSIZE, 0, &from.sa, &fromlen); + pkt.offset = 0; + int len = recvfrom(ls->udp.fd, DATA(&pkt), MAXSIZE, 0, &addr.sa, &addrlen); if(len <= 0 || len > MAXSIZE) { if(!sockwouldblock(sockerrno)) @@ -1017,32 +1078,76 @@ void handle_incoming_vpn_data(void *data, int flags) { pkt.len = len; - sockaddrunmap(&from); /* Some braindead IPv6 implementations do stupid things. */ + sockaddrunmap(&addr); /* Some braindead IPv6 implementations do stupid things. */ - n = lookup_node_udp(&from); + // Try to figure out who sent this packet. + + node_t *n = lookup_node_udp(&addr); if(!n) { - n = try_harder(&from, &pkt); - if(n) - update_node_udp(n, &from); - else if(debug_level >= DEBUG_PROTOCOL) { - hostname = sockaddr2hostname(&from); - logger(DEBUG_PROTOCOL, LOG_WARNING, "Received UDP packet from unknown source %s", hostname); - free(hostname); - return; + // It might be from a 1.1 node, which might have a source ID in the packet. + pkt.offset = 2 * sizeof(node_id_t); + from = lookup_node_id(SRCID(&pkt)); + if(from && !memcmp(DSTID(&pkt), &nullid, sizeof nullid) && from->status.sptps) { + if(sptps_verify_datagram(&from->sptps, DATA(&pkt), pkt.len - 2 * sizeof(node_id_t))) + n = from; + else + goto skip_harder; } - else - return; } - n->sock = ls - listen_socket; + if(!n) { + pkt.offset = 0; + n = try_harder(&addr, &pkt); + } - receive_udppacket(n, &pkt); +skip_harder: + if(!n) { + if(debug_level >= DEBUG_PROTOCOL) { + hostname = sockaddr2hostname(&addr); + logger(DEBUG_PROTOCOL, LOG_WARNING, "Received UDP packet from unknown source %s", hostname); + free(hostname); + } + return; + } + + if(n->status.sptps) { + pkt.offset = 2 * sizeof(node_id_t); + + if(!memcmp(DSTID(&pkt), &nullid, sizeof nullid)) { + direct = true; + from = n; + to = myself; + } else { + from = lookup_node_id(SRCID(&pkt)); + to = lookup_node_id(DSTID(&pkt)); + } + if(!from || !to) { + logger(DEBUG_PROTOCOL, LOG_WARNING, "Received UDP packet from %s (%s) with unknown source and/or destination ID", n->name, n->hostname); + return; + } + + if(to != myself) { + send_sptps_data_priv(to, n, 0, DATA(&pkt), pkt.len - 2 * sizeof(node_id_t)); + return; + } + } else { + direct = true; + from = n; + } + + pkt.offset = 0; + if(!receive_udppacket(from, &pkt)) + return; + + n->sock = ls - listen_socket; + if(direct && sockaddrcmp(&addr, &n->address)) + update_node_udp(n, &addr); } void handle_device_data(void *data, int flags) { vpn_packet_t packet; - + packet.offset = DEFAULT_PACKET_OFFSET; packet.priority = 0; if(devops.read(&packet)) { diff --git a/src/net_setup.c b/src/net_setup.c index b9c5df7..29f1212 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-2013 Guus Sliepen + 2000-2014 Guus Sliepen 2006 Scott Lamb 2010 Brandon Black @@ -44,15 +44,17 @@ #include "xalloc.h" char *myport; +static char *myname; static io_t device_io; devops_t devops; +bool device_standby = false; char *proxyhost; char *proxyport; char *proxyuser; char *proxypass; proxytype_t proxytype; -int autoconnect; +bool autoconnect; bool disablebuggypeers; char *scriptinterpreter; @@ -71,25 +73,23 @@ bool node_read_ecdsa_public_key(node_t *n) { if(!read_host_config(config_tree, n->name)) goto exit; - /* First, check for simple ECDSAPublicKey statement */ + /* First, check for simple Ed25519PublicKey statement */ - if(get_config_string(lookup_config(config_tree, "ECDSAPublicKey"), &p)) { + if(get_config_string(lookup_config(config_tree, "Ed25519PublicKey"), &p)) { n->ecdsa = ecdsa_set_base64_public_key(p); free(p); goto exit; } - /* Else, check for ECDSAPublicKeyFile statement and read it */ + /* Else, check for Ed25519PublicKeyFile statement and read it */ - if(!get_config_string(lookup_config(config_tree, "ECDSAPublicKeyFile"), &pubname)) + if(!get_config_string(lookup_config(config_tree, "Ed25519PublicKeyFile"), &pubname)) xasprintf(&pubname, "%s" SLASH "hosts" SLASH "%s", confbase, n->name); fp = fopen(pubname, "r"); - if(!fp) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error reading ECDSA public key file `%s': %s", pubname, strerror(errno)); + if(!fp) goto exit; - } n->ecdsa = ecdsa_read_pem_public_key(fp); fclose(fp); @@ -114,23 +114,23 @@ bool read_ecdsa_public_key(connection_t *c) { return false; } - /* First, check for simple ECDSAPublicKey statement */ + /* First, check for simple Ed25519PublicKey statement */ - if(get_config_string(lookup_config(c->config_tree, "ECDSAPublicKey"), &p)) { + if(get_config_string(lookup_config(c->config_tree, "Ed25519PublicKey"), &p)) { c->ecdsa = ecdsa_set_base64_public_key(p); free(p); return c->ecdsa; } - /* Else, check for ECDSAPublicKeyFile statement and read it */ + /* Else, check for Ed25519PublicKeyFile statement and read it */ - if(!get_config_string(lookup_config(c->config_tree, "ECDSAPublicKeyFile"), &fname)) + if(!get_config_string(lookup_config(c->config_tree, "Ed25519PublicKeyFile"), &fname)) xasprintf(&fname, "%s" SLASH "hosts" SLASH "%s", confbase, c->name); fp = fopen(fname, "r"); if(!fp) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error reading ECDSA public key file `%s': %s", + logger(DEBUG_ALWAYS, LOG_ERR, "Error reading Ed25519 public key file `%s': %s", fname, strerror(errno)); free(fname); return false; @@ -140,7 +140,7 @@ bool read_ecdsa_public_key(connection_t *c) { fclose(fp); if(!c->ecdsa) - logger(DEBUG_ALWAYS, LOG_ERR, "Parsing ECDSA public key file `%s' failed.", fname); + logger(DEBUG_ALWAYS, LOG_ERR, "Parsing Ed25519 public key file `%s' failed.", fname); free(fname); return c->ecdsa; } @@ -189,15 +189,15 @@ static bool read_ecdsa_private_key(void) { /* Check for PrivateKeyFile statement and read it */ - if(!get_config_string(lookup_config(config_tree, "ECDSAPrivateKeyFile"), &fname)) - xasprintf(&fname, "%s" SLASH "ecdsa_key.priv", confbase); + if(!get_config_string(lookup_config(config_tree, "Ed25519PrivateKeyFile"), &fname)) + xasprintf(&fname, "%s" SLASH "ed25519_key.priv", confbase); fp = fopen(fname, "r"); if(!fp) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error reading ECDSA private key file `%s': %s", fname, strerror(errno)); + logger(DEBUG_ALWAYS, LOG_ERR, "Error reading Ed25519 private key file `%s': %s", fname, strerror(errno)); if(errno == ENOENT) - logger(DEBUG_ALWAYS, LOG_INFO, "Create an ECDSA keypair with `tinc -n %s generate-ecdsa-keys'.", netname ?: "."); + logger(DEBUG_ALWAYS, LOG_INFO, "Create an Ed25519 keypair with `tinc -n %s generate-ed25519-keys'.", netname ?: "."); free(fname); return false; } @@ -206,20 +206,20 @@ static bool read_ecdsa_private_key(void) { struct stat s; if(fstat(fileno(fp), &s)) { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not stat ECDSA private key file `%s': %s'", fname, strerror(errno)); + logger(DEBUG_ALWAYS, LOG_ERR, "Could not stat Ed25519 private key file `%s': %s'", fname, strerror(errno)); free(fname); return false; } if(s.st_mode & ~0100700) - logger(DEBUG_ALWAYS, LOG_WARNING, "Warning: insecure file permissions for ECDSA private key file `%s'!", fname); + logger(DEBUG_ALWAYS, LOG_WARNING, "Warning: insecure file permissions for Ed25519 private key file `%s'!", fname); #endif myself->connection->ecdsa = ecdsa_read_pem_private_key(fp); fclose(fp); if(!myself->connection->ecdsa) - logger(DEBUG_ALWAYS, LOG_ERR, "Reading ECDSA private key file `%s' failed: %s", fname, strerror(errno)); + logger(DEBUG_ALWAYS, LOG_ERR, "Reading Ed25519 private key file `%s' failed", fname); free(fname); return myself->connection->ecdsa; } @@ -233,7 +233,7 @@ static bool read_invitation_key(void) { invitation_key = NULL; } - xasprintf(&fname, "%s" SLASH "invitations" SLASH "ecdsa_key.priv", confbase); + xasprintf(&fname, "%s" SLASH "invitations" SLASH "ed25519_key.priv", confbase); fp = fopen(fname, "r"); @@ -241,7 +241,7 @@ static bool read_invitation_key(void) { invitation_key = ecdsa_read_pem_private_key(fp); fclose(fp); if(!invitation_key) - logger(DEBUG_ALWAYS, LOG_ERR, "Reading ECDSA private key file `%s' failed: %s", fname, strerror(errno)); + logger(DEBUG_ALWAYS, LOG_ERR, "Reading Ed25519 private key file `%s' failed", fname); } free(fname); @@ -277,6 +277,8 @@ static bool read_rsa_private_key(void) { if(!fp) { logger(DEBUG_ALWAYS, LOG_ERR, "Error reading RSA private key file `%s': %s", fname, strerror(errno)); + if(errno == ENOENT) + logger(DEBUG_ALWAYS, LOG_INFO, "Create an RSA keypair with `tinc -n %s generate-rsa-keys'.", netname ?: "."); free(fname); return false; } @@ -403,40 +405,16 @@ void load_all_nodes(void) { char *get_name(void) { char *name = NULL; + char *returned_name; get_config_string(lookup_config(config_tree, "Name"), &name); if(!name) return NULL; - if(*name == '$') { - char *envname = getenv(name + 1); - if(!envname) { - if(strcmp(name + 1, "HOST")) { - logger(DEBUG_ALWAYS, LOG_ERR, "Invalid Name: environment variable %s does not exist\n", name + 1); - return false; - } - char envname[32]; - if(gethostname(envname, 32)) { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not get hostname: %s\n", strerror(errno)); - return false; - } - envname[31] = 0; - } - free(name); - name = xstrdup(envname); - for(char *c = name; *c; c++) - if(!isalnum(*c)) - *c = '_'; - } - - if(!check_id(name)) { - logger(DEBUG_ALWAYS, LOG_ERR, "Invalid name for myself!"); - free(name); - return false; - } - - return name; + returned_name = replace_name(name); + free(name); + return returned_name; } bool setup_myself_reloadable(void) { @@ -445,7 +423,6 @@ bool setup_myself_reloadable(void) { char *fmode = NULL; char *bmode = NULL; char *afname = NULL; - char *address = NULL; char *space; bool choice; @@ -532,16 +509,6 @@ bool setup_myself_reloadable(void) { get_config_bool(lookup_config(config_tree, "DirectOnly"), &directonly); get_config_bool(lookup_config(config_tree, "LocalDiscovery"), &localdiscovery); - memset(&localdiscovery_address, 0, sizeof localdiscovery_address); - if(get_config_string(lookup_config(config_tree, "LocalDiscoveryAddress"), &address)) { - struct addrinfo *ai = str2addrinfo(address, myport, SOCK_DGRAM); - free(address); - if(!ai) - return false; - memcpy(&localdiscovery_address, ai->ai_addr, ai->ai_addrlen); - } - - if(get_config_string(lookup_config(config_tree, "Mode"), &rmode)) { if(!strcasecmp(rmode, "router")) routing_mode = RMODE_ROUTER; @@ -596,6 +563,20 @@ bool setup_myself_reloadable(void) { free(bmode); } + const char* const DEFAULT_BROADCAST_SUBNETS[] = { "ff:ff:ff:ff:ff:ff", "255.255.255.255", "224.0.0.0/4", "ff00::/8" }; + for (size_t i = 0; i < sizeof(DEFAULT_BROADCAST_SUBNETS) / sizeof(*DEFAULT_BROADCAST_SUBNETS); i++) { + subnet_t *s = new_subnet(); + if (!str2net(s, DEFAULT_BROADCAST_SUBNETS[i])) + abort(); + subnet_add(NULL, s); + } + for (config_t* cfg = lookup_config(config_tree, "BroadcastSubnet"); cfg; cfg = lookup_config_next(config_tree, cfg)) { + subnet_t *s; + if (!get_config_subnet(cfg, &s)) + continue; + subnet_add(NULL, s); + } + #if !defined(SOL_IP) || !defined(IP_TOS) if(priorityinheritance) logger(DEBUG_ALWAYS, LOG_WARNING, "%s not supported on this platform", "PriorityInheritance"); @@ -631,7 +612,15 @@ bool setup_myself_reloadable(void) { if(!get_config_int(lookup_config(config_tree, "KeyExpire"), &keylifetime)) keylifetime = 3600; - get_config_int(lookup_config(config_tree, "AutoConnect"), &autoconnect); + config_t *cfg = lookup_config(config_tree, "AutoConnect"); + if(cfg) { + if(!get_config_bool(cfg, &autoconnect)) { + // Some backwards compatibility with when this option was an int + int val = 0; + get_config_int(cfg, &val); + autoconnect = val; + } + } get_config_bool(lookup_config(config_tree, "DisableBuggyPeers"), &disablebuggypeers); @@ -640,18 +629,133 @@ bool setup_myself_reloadable(void) { return true; } +/* + Add listening sockets. +*/ +static bool add_listen_address(char *address, bool bindto) { + char *port = myport; + + if(address) { + char *space = strchr(address, ' '); + if(space) { + *space++ = 0; + port = space; + } + + if(!strcmp(address, "*")) + *address = 0; + } + + struct addrinfo *ai, hint = {0}; + hint.ai_family = addressfamily; + hint.ai_socktype = SOCK_STREAM; + hint.ai_protocol = IPPROTO_TCP; + hint.ai_flags = AI_PASSIVE; + + int err = getaddrinfo(address && *address ? address : NULL, port, &hint, &ai); + free(address); + + if(err || !ai) { + logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "getaddrinfo", err == EAI_SYSTEM ? strerror(err) : gai_strerror(err)); + return false; + } + + for(struct addrinfo *aip = ai; aip; aip = aip->ai_next) { + // Ignore duplicate addresses + bool found = false; + + for(int i = 0; i < listen_sockets; i++) + if(!memcmp(&listen_socket[i].sa, aip->ai_addr, aip->ai_addrlen)) { + found = true; + break; + } + + if(found) + continue; + + if(listen_sockets >= MAXSOCKETS) { + logger(DEBUG_ALWAYS, LOG_ERR, "Too many listening sockets"); + return false; + } + + int tcp_fd = setup_listen_socket((sockaddr_t *) aip->ai_addr); + + if(tcp_fd < 0) + continue; + + int udp_fd = setup_vpn_in_socket((sockaddr_t *) aip->ai_addr); + + if(tcp_fd < 0) { + close(tcp_fd); + continue; + } + + io_add(&listen_socket[listen_sockets].tcp, handle_new_meta_connection, &listen_socket[listen_sockets], tcp_fd, IO_READ); + io_add(&listen_socket[listen_sockets].udp, handle_incoming_vpn_data, &listen_socket[listen_sockets], udp_fd, IO_READ); + + if(debug_level >= DEBUG_CONNECTIONS) { + char *hostname = sockaddr2hostname((sockaddr_t *) aip->ai_addr); + logger(DEBUG_CONNECTIONS, LOG_NOTICE, "Listening on %s", hostname); + free(hostname); + } + + listen_socket[listen_sockets].bindto = bindto; + memcpy(&listen_socket[listen_sockets].sa, aip->ai_addr, aip->ai_addrlen); + listen_sockets++; + } + + freeaddrinfo(ai); + return true; +} + +void device_enable(void) { + if (devops.enable) + devops.enable(); + + /* Run tinc-up script to further initialize the tap interface */ + + char *envp[5] = {NULL}; + xasprintf(&envp[0], "NETNAME=%s", netname ? : ""); + xasprintf(&envp[1], "DEVICE=%s", device ? : ""); + xasprintf(&envp[2], "INTERFACE=%s", iface ? : ""); + xasprintf(&envp[3], "NAME=%s", myname); + + execute_script("tinc-up", envp); + + for(int i = 0; i < 4; i++) + free(envp[i]); +} + +void device_disable(void) { + char *envp[5] = {NULL}; + xasprintf(&envp[0], "NETNAME=%s", netname ? : ""); + xasprintf(&envp[1], "DEVICE=%s", device ? : ""); + xasprintf(&envp[2], "INTERFACE=%s", iface ? : ""); + xasprintf(&envp[3], "NAME=%s", myname); + + execute_script("tinc-down", envp); + + for(int i = 0; i < 4; i++) + free(envp[i]); + + if (devops.disable) + devops.disable(); +} + /* Configure node_t myself and set up the local sockets (listen only) */ static bool setup_myself(void) { char *name, *hostname, *cipher, *digest, *type; char *address = NULL; + bool port_specified = false; if(!(name = get_name())) { logger(DEBUG_ALWAYS, LOG_ERR, "Name for tinc daemon required!"); return false; } + myname = xstrdup(name); myself = new_node(); myself->connection = new_connection(); myself->name = name; @@ -660,9 +764,8 @@ static bool setup_myself(void) { if(!get_config_string(lookup_config(config_tree, "Port"), &myport)) myport = xstrdup("655"); - - xasprintf(&myself->hostname, "MYSELF port %s", myport); - myself->connection->hostname = xstrdup(myself->hostname); + else + port_specified = true; myself->connection->options = 0; myself->connection->protocol_major = PROT_MAJOR; @@ -670,13 +773,25 @@ static bool setup_myself(void) { myself->options |= PROT_MINOR << 24; - get_config_bool(lookup_config(config_tree, "ExperimentalProtocol"), &experimental); + if(!get_config_bool(lookup_config(config_tree, "ExperimentalProtocol"), &experimental)) { + experimental = read_ecdsa_private_key(); + if(!experimental) + logger(DEBUG_ALWAYS, LOG_WARNING, "Support for SPTPS disabled."); + } else { + if(experimental && !read_ecdsa_private_key()) + return false; + } - if(experimental && !read_ecdsa_private_key()) - return false; + if(!read_rsa_private_key()) { + if(experimental) { + logger(DEBUG_ALWAYS, LOG_WARNING, "Support for legacy protocol disabled."); + } else { + logger(DEBUG_ALWAYS, LOG_ERR, "No private keys available, cannot start tinc!"); + return false; + } + } - if(!read_rsa_private_key()) - return false; + /* Ensure myport is numeric */ if(!atoi(myport)) { struct addrinfo *ai = str2addrinfo("localhost", myport, SOCK_DGRAM); @@ -744,7 +859,9 @@ static bool setup_myself(void) { if(!get_config_string(lookup_config(config_tree, "Cipher"), &cipher)) cipher = xstrdup("blowfish"); - if(!(myself->incipher = cipher_open_by_name(cipher))) { + if(!strcasecmp(cipher, "none")) { + myself->incipher = NULL; + } else if(!(myself->incipher = cipher_open_by_name(cipher))) { logger(DEBUG_ALWAYS, LOG_ERR, "Unrecognized cipher type!"); return false; } @@ -766,7 +883,9 @@ static bool setup_myself(void) { if(!get_config_string(lookup_config(config_tree, "Digest"), &digest)) digest = xstrdup("sha1"); - if(!(myself->indigest = digest_open_by_name(digest, maclength))) { + if(!strcasecmp(digest, "none")) { + myself->indigest = NULL; + } else if(!(myself->indigest = digest_open_by_name(digest, maclength))) { logger(DEBUG_ALWAYS, LOG_ERR, "Unrecognized digest type!"); return false; } @@ -822,6 +941,8 @@ static bool setup_myself(void) { #endif } + get_config_bool(lookup_config(config_tree, "DeviceStandby"), &device_standby); + if(!devops.setup()) return false; @@ -847,7 +968,7 @@ static bool setup_myself(void) { for(int i = 0; i < listen_sockets; i++) { salen = sizeof sa; if(getsockname(i + 3, &sa.sa, &salen) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not get address of listen fd %d: %s", i + 3, sockstrerror(errno)); + logger(DEBUG_ALWAYS, LOG_ERR, "Could not get address of listen fd %d: %s", i + 3, sockstrerror(sockerrno)); return false; } @@ -872,73 +993,25 @@ static bool setup_myself(void) { } } else { listen_sockets = 0; - config_t *cfg = lookup_config(config_tree, "BindToAddress"); + int cfgs = 0; - do { + for(config_t *cfg = lookup_config(config_tree, "BindToAddress"); cfg; cfg = lookup_config_next(config_tree, cfg)) { + cfgs++; get_config_string(cfg, &address); - if(cfg) - cfg = lookup_config_next(config_tree, cfg); - - char *port = myport; - - if(address) { - char *space = strchr(address, ' '); - if(space) { - *space++ = 0; - port = space; - } - - if(!strcmp(address, "*")) - *address = 0; - } - - struct addrinfo *ai, hint = {0}; - hint.ai_family = addressfamily; - hint.ai_socktype = SOCK_STREAM; - hint.ai_protocol = IPPROTO_TCP; - hint.ai_flags = AI_PASSIVE; - - int err = getaddrinfo(address && *address ? address : NULL, port, &hint, &ai); - free(address); - - if(err || !ai) { - logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "getaddrinfo", err == EAI_SYSTEM ? strerror(err) : gai_strerror(err)); + if(!add_listen_address(address, true)) return false; - } + } - for(struct addrinfo *aip = ai; aip; aip = aip->ai_next) { - if(listen_sockets >= MAXSOCKETS) { - logger(DEBUG_ALWAYS, LOG_ERR, "Too many listening sockets"); - return false; - } + for(config_t *cfg = lookup_config(config_tree, "ListenAddress"); cfg; cfg = lookup_config_next(config_tree, cfg)) { + cfgs++; + get_config_string(cfg, &address); + if(!add_listen_address(address, false)) + return false; + } - int tcp_fd = setup_listen_socket((sockaddr_t *) aip->ai_addr); - - if(tcp_fd < 0) - continue; - - int udp_fd = setup_vpn_in_socket((sockaddr_t *) aip->ai_addr); - - if(tcp_fd < 0) { - close(tcp_fd); - continue; - } - - io_add(&listen_socket[listen_sockets].tcp, handle_new_meta_connection, &listen_socket[listen_sockets], tcp_fd, IO_READ); - io_add(&listen_socket[listen_sockets].udp, handle_incoming_vpn_data, &listen_socket[listen_sockets], udp_fd, IO_READ); - - if(debug_level >= DEBUG_CONNECTIONS) { - hostname = sockaddr2hostname((sockaddr_t *) aip->ai_addr); - logger(DEBUG_CONNECTIONS, LOG_NOTICE, "Listening on %s", hostname); - free(hostname); - } - - memcpy(&listen_socket[listen_sockets].sa, aip->ai_addr, aip->ai_addrlen); - listen_sockets++; - } - - freeaddrinfo(ai); - } while(cfg); + if(!cfgs) + if(!add_listen_address(address, NULL)) + return false; } if(!listen_sockets) { @@ -946,6 +1019,24 @@ static bool setup_myself(void) { return false; } + /* If no Port option was specified, set myport to the port used by the first listening socket. */ + + if(!port_specified || atoi(myport) == 0) { + sockaddr_t sa; + socklen_t salen = sizeof sa; + if(!getsockname(listen_socket[0].udp.fd, &sa.sa, &salen)) { + free(myport); + sockaddr2str(&sa, NULL, &myport); + if(!myport) + myport = xstrdup("655"); + } + } + + xasprintf(&myself->hostname, "MYSELF port %s", myport); + myself->connection->hostname = xstrdup(myself->hostname); + + /* Done. */ + last_config_check = now.tv_sec; return true; @@ -982,18 +1073,8 @@ bool setup_network(void) { if(!init_control()) return false; - /* Run tinc-up script to further initialize the tap interface */ - - char *envp[5] = {NULL}; - xasprintf(&envp[0], "NETNAME=%s", netname ? : ""); - xasprintf(&envp[1], "DEVICE=%s", device ? : ""); - xasprintf(&envp[2], "INTERFACE=%s", iface ? : ""); - xasprintf(&envp[3], "NAME=%s", myself->name); - - execute_script("tinc-up", envp); - - for(int i = 0; i < 4; i++) - free(envp[i]); + if (!device_standby) + device_enable(); /* Run subnet-up scripts for our own subnets */ @@ -1016,7 +1097,8 @@ void close_network_connections(void) { terminate_connection(c, false); } - list_delete_list(outgoing_list); + if(outgoing_list) + list_delete_list(outgoing_list); if(myself && myself->connection) { subnet_update(myself, NULL, false); @@ -1031,28 +1113,27 @@ void close_network_connections(void) { close(listen_socket[i].udp.fd); } - char *envp[5] = {NULL}; - xasprintf(&envp[0], "NETNAME=%s", netname ? : ""); - xasprintf(&envp[1], "DEVICE=%s", device ? : ""); - xasprintf(&envp[2], "INTERFACE=%s", iface ? : ""); - xasprintf(&envp[3], "NAME=%s", myself->name); - exit_requests(); exit_edges(); exit_subnets(); exit_nodes(); exit_connections(); - execute_script("tinc-down", envp); + if (!device_standby) + device_disable(); - if(myport) free(myport); + free(myport); - for(int i = 0; i < 4; i++) - free(envp[i]); - - devops.close(); + if (device_fd >= 0) + io_del(&device_io); + if (devops.close) + devops.close(); exit_control(); + free(myname); + free(scriptextension); + free(scriptinterpreter); + return; } diff --git a/src/net_socket.c b/src/net_socket.c index ab3c17e..1bf9d16 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-2013 Guus Sliepen + 2000-2014 Guus Sliepen 2006 Scott Lamb 2009 Florian Forster @@ -103,7 +103,7 @@ static bool bind_to_interface(int sd) { status = setsockopt(sd, SOL_SOCKET, SO_BINDTODEVICE, (void *)&ifr, sizeof(ifr)); if(status) { logger(DEBUG_ALWAYS, LOG_ERR, "Can't bind to interface %s: %s", iface, - strerror(errno)); + sockstrerror(sockerrno)); return false; } #else /* if !defined(SOL_SOCKET) || !defined(SO_BINDTODEVICE) */ @@ -116,7 +116,7 @@ static bool bind_to_interface(int sd) { static bool bind_to_address(connection_t *c) { int s = -1; - for(int i = 0; i < listen_sockets; i++) { + for(int i = 0; i < listen_sockets && listen_socket[i].bindto; i++) { if(listen_socket[i].sa.sa.sa_family != c->address.sa.sa_family) continue; if(s >= 0) @@ -134,7 +134,7 @@ static bool bind_to_address(connection_t *c) { sa.in6.sin6_port = 0; if(bind(c->socket, &sa.sa, SALEN(sa.sa))) { - logger(DEBUG_CONNECTIONS, LOG_WARNING, "Can't bind outgoing socket: %s", strerror(errno)); + logger(DEBUG_CONNECTIONS, LOG_WARNING, "Can't bind outgoing socket: %s", sockstrerror(sockerrno)); return false; } @@ -179,7 +179,7 @@ int setup_listen_socket(const sockaddr_t *sa) { if(setsockopt(nfd, SOL_SOCKET, SO_BINDTODEVICE, (void *)&ifr, sizeof ifr)) { closesocket(nfd); logger(DEBUG_ALWAYS, LOG_ERR, "Can't bind to interface %s: %s", iface, - strerror(sockerrno)); + sockstrerror(sockerrno)); return -1; } #else @@ -247,10 +247,10 @@ int setup_vpn_in_socket(const sockaddr_t *sa) { setsockopt(nfd, SOL_SOCKET, SO_BROADCAST, (void *)&option, sizeof option); if(udp_rcvbuf && setsockopt(nfd, SOL_SOCKET, SO_RCVBUF, (void *)&udp_rcvbuf, sizeof(udp_rcvbuf))) - logger(DEBUG_ALWAYS, LOG_WARNING, "Can't set UDP SO_RCVBUF to %i: %s", udp_rcvbuf, strerror(errno)); + logger(DEBUG_ALWAYS, LOG_WARNING, "Can't set UDP SO_RCVBUF to %i: %s", udp_rcvbuf, sockstrerror(sockerrno)); if(udp_sndbuf && setsockopt(nfd, SOL_SOCKET, SO_SNDBUF, (void *)&udp_sndbuf, sizeof(udp_sndbuf))) - logger(DEBUG_ALWAYS, LOG_WARNING, "Can't set UDP SO_SNDBUF to %i: %s", udp_sndbuf, strerror(errno)); + logger(DEBUG_ALWAYS, LOG_WARNING, "Can't set UDP SO_SNDBUF to %i: %s", udp_sndbuf, sockstrerror(sockerrno)); #if defined(IPPROTO_IPV6) && defined(IPV6_V6ONLY) if(sa->sa.sa_family == AF_INET6) @@ -271,8 +271,6 @@ int setup_vpn_in_socket(const sockaddr_t *sa) { option = 1; setsockopt(nfd, IPPROTO_IP, IP_DONTFRAGMENT, (void *)&option, sizeof(option)); } -#else -#warning No way to disable IPv4 fragmentation #endif #if defined(SOL_IPV6) && defined(IPV6_MTU_DISCOVER) && defined(IPV6_PMTUDISC_DO) @@ -285,8 +283,6 @@ int setup_vpn_in_socket(const sockaddr_t *sa) { option = 1; setsockopt(nfd, IPPROTO_IPV6, IPV6_DONTFRAG, (void *)&option, sizeof(option)); } -#else -#warning No way to disable IPv6 fragmentation #endif if (!bind_to_interface(nfd)) { @@ -334,7 +330,7 @@ static void do_outgoing_pipe(connection_t *c, char *command) { int fd[2]; if(socketpair(AF_UNIX, SOCK_STREAM, 0, fd)) { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not create socketpair: %s", strerror(errno)); + logger(DEBUG_ALWAYS, LOG_ERR, "Could not create socketpair: %s", sockstrerror(sockerrno)); return; } @@ -383,16 +379,16 @@ static void handle_meta_write(connection_t *c) { ssize_t outlen = send(c->socket, c->outbuf.data + c->outbuf.offset, c->outbuf.len - c->outbuf.offset, 0); if(outlen <= 0) { - if(!errno || errno == EPIPE) { + if(!sockerrno || sockerrno == EPIPE) { logger(DEBUG_CONNECTIONS, LOG_NOTICE, "Connection closed by %s (%s)", c->name, c->hostname); } else if(sockwouldblock(sockerrno)) { logger(DEBUG_CONNECTIONS, LOG_DEBUG, "Sending %d bytes to %s (%s) would block", c->outbuf.len - c->outbuf.offset, c->name, c->hostname); return; } else { - logger(DEBUG_CONNECTIONS, LOG_ERR, "Could not send %d bytes of data to %s (%s): %s", c->outbuf.len - c->outbuf.offset, c->name, c->hostname, strerror(errno)); + logger(DEBUG_CONNECTIONS, LOG_ERR, "Could not send %d bytes of data to %s (%s): %s", c->outbuf.len - c->outbuf.offset, c->name, c->hostname, sockstrerror(sockerrno)); } - terminate_connection(c, c->status.active); + terminate_connection(c, c->edge); return; } @@ -405,19 +401,38 @@ static void handle_meta_io(void *data, int flags) { connection_t *c = data; if(c->status.connecting) { - c->status.connecting = false; + /* + The event loop does not protect against spurious events. Verify that we are actually connected + by issuing an empty send() call. - int result; - socklen_t len = sizeof result; - getsockopt(c->socket, SOL_SOCKET, SO_ERROR, (void *)&result, &len); - - if(!result) - finish_connecting(c); - else { - logger(DEBUG_CONNECTIONS, LOG_DEBUG, "Error while connecting to %s (%s): %s", c->name, c->hostname, sockstrerror(result)); - terminate_connection(c, false); + Note that the behavior of send() on potentially unconnected sockets differ between platforms: + +------------+-----------+-------------+-----------+ + | Event | POSIX | Linux | Windows | + +------------+-----------+-------------+-----------+ + | Spurious | ENOTCONN | EWOULDBLOCK | ENOTCONN | + | Failed | ENOTCONN | (cause) | ENOTCONN | + | Successful | (success) | (success) | (success) | + +------------+-----------+-------------+-----------+ + */ + if (send(c->socket, NULL, 0, 0) != 0) { + if (sockwouldblock(sockerrno)) + return; + int socket_error; + if (!socknotconn(sockerrno)) + socket_error = sockerrno; + else { + socklen_t len = sizeof socket_error; + getsockopt(c->socket, SOL_SOCKET, SO_ERROR, (void *)&socket_error, &len); + } + if (socket_error) { + logger(DEBUG_CONNECTIONS, LOG_DEBUG, "Error while connecting to %s (%s): %s", c->name, c->hostname, sockstrerror(socket_error)); + terminate_connection(c, false); + } return; } + + c->status.connecting = false; + finish_connecting(c); } if(flags & IO_WRITE) @@ -547,6 +562,39 @@ begin: return true; } +// Find edges pointing to this node, and use them to build a list of unique, known addresses. +static struct addrinfo *get_known_addresses(node_t *n) { + struct addrinfo *ai = NULL; + + for splay_each(edge_t, e, n->edge_tree) { + if(!e->reverse) + continue; + + bool found = false; + for(struct addrinfo *aip = ai; aip; aip = aip->ai_next) { + if(!sockaddrcmp(&e->reverse->address, (sockaddr_t *)aip->ai_addr)) { + found = true; + break; + } + } + if(found) + continue; + + struct addrinfo *nai = xzalloc(sizeof *nai); + if(ai) + ai->ai_next = nai; + ai = nai; + ai->ai_family = e->reverse->address.sa.sa_family; + ai->ai_socktype = SOCK_STREAM; + ai->ai_protocol = IPPROTO_TCP; + ai->ai_addrlen = SALEN(e->reverse->address.sa); + ai->ai_addr = xmalloc(ai->ai_addrlen); + memcpy(ai->ai_addr, &e->reverse->address, ai->ai_addrlen); + } + + return ai; +} + void setup_outgoing_connection(outgoing_t *outgoing) { timeout_del(&outgoing->ev); @@ -564,8 +612,12 @@ void setup_outgoing_connection(outgoing_t *outgoing) { outgoing->cfg = lookup_config(outgoing->config_tree, "Address"); if(!outgoing->cfg) { - logger(DEBUG_ALWAYS, LOG_ERR, "No address specified for %s", outgoing->name); - return; + if(n) + outgoing->aip = outgoing->ai = get_known_addresses(n); + if(!outgoing->ai) { + logger(DEBUG_ALWAYS, LOG_ERR, "No address known for %s", outgoing->name); + return; + } } do_outgoing_connection(outgoing); @@ -594,7 +646,6 @@ void handle_new_meta_connection(void *data, int flags) { // Check if we get many connections from the same host static sockaddr_t prev_sa; - static time_t prev_time; static int tarpit = -1; if(tarpit >= 0) { @@ -621,7 +672,6 @@ void handle_new_meta_connection(void *data, int flags) { } memcpy(&prev_sa, &sa, sizeof sa); - prev_time = now.tv_sec; // Check if we get many connections from different hosts @@ -770,7 +820,7 @@ void try_outgoing_connections(void) { if(c->outgoing && c->outgoing->timeout == -1) { c->outgoing = NULL; logger(DEBUG_CONNECTIONS, LOG_INFO, "No more outgoing connection to %s", c->name); - terminate_connection(c, c->status.active); + terminate_connection(c, c->edge); } } diff --git a/src/node.c b/src/node.c index aab83ca..e97bfaf 100644 --- a/src/node.c +++ b/src/node.c @@ -30,8 +30,12 @@ #include "utils.h" #include "xalloc.h" +static digest_t *sha256; + splay_tree_t *node_tree; +static splay_tree_t *node_id_tree; static hash_t *node_udp_cache; +static hash_t *node_id_cache; node_t *myself; @@ -39,14 +43,26 @@ static int node_compare(const node_t *a, const node_t *b) { return strcmp(a->name, b->name); } +static int node_id_compare(const node_t *a, const node_t *b) { + return memcmp(&a->id, &b->id, sizeof(node_id_t)); +} + void init_nodes(void) { + sha256 = digest_open_by_name("sha256", sizeof(node_id_t)); + node_tree = splay_alloc_tree((splay_compare_t) node_compare, (splay_action_t) free_node); + node_id_tree = splay_alloc_tree((splay_compare_t) node_id_compare, NULL); node_udp_cache = hash_alloc(0x100, sizeof(sockaddr_t)); + node_id_cache = hash_alloc(0x100, sizeof(node_id_t)); } void exit_nodes(void) { + hash_free(node_id_cache); hash_free(node_udp_cache); + splay_delete_tree(node_id_tree); splay_delete_tree(node_tree); + + digest_close(sha256); } node_t *new_node(void) { @@ -93,16 +109,23 @@ void free_node(node_t *n) { } void node_add(node_t *n) { + digest_create(sha256, n->name, strlen(n->name), &n->id); + splay_insert(node_tree, n); + splay_insert(node_id_tree, n); } void node_del(node_t *n) { + hash_delete(node_udp_cache, &n->address); + hash_delete(node_id_cache, &n->id); + for splay_each(subnet_t, s, n->subnet_tree) subnet_del(n, s); for splay_each(edge_t, e, n->edge_tree) edge_del(e); + splay_delete(node_id_tree, n); splay_delete(node_tree, n); } @@ -114,6 +137,18 @@ node_t *lookup_node(char *name) { return splay_search(node_tree, &n); } +node_t *lookup_node_id(const node_id_t *id) { + node_t *n = hash_search(node_id_cache, id); + if(!n) { + node_t tmp = {.id = *id}; + n = splay_search(node_id_tree, &tmp); + if(n) + hash_insert(node_id_cache, id, n); + } + + return n; +} + node_t *lookup_node_udp(const sockaddr_t *sa) { return hash_search(node_udp_cache, sa); } @@ -124,7 +159,7 @@ void update_node_udp(node_t *n, const sockaddr_t *sa) { return; } - hash_insert(node_udp_cache, &n->address, NULL); + hash_delete(node_udp_cache, &n->address); if(sa) { n->address = *sa; @@ -140,15 +175,27 @@ void update_node_udp(node_t *n, const sockaddr_t *sa) { n->hostname = sockaddr2hostname(&n->address); logger(DEBUG_PROTOCOL, LOG_DEBUG, "UDP address of %s set to %s", n->name, n->hostname); } + + /* invalidate UDP information - note that this is a security feature as well to make sure + we can't be tricked into flooding any random address with UDP packets */ + n->status.udp_confirmed = false; + n->mtuprobes = 0; + n->minmtu = 0; + n->maxmtu = MTU; } bool dump_nodes(connection_t *c) { - for splay_each(node_t, n, node_tree) - send_request(c, "%d %d %s %s %d %d %d %d %x %x %s %s %d %hd %hd %hd %ld", CONTROL, REQ_DUMP_NODES, - n->name, n->hostname ?: "unknown port unknown", cipher_get_nid(n->outcipher), + for splay_each(node_t, n, node_tree) { + char id[2 * sizeof n->id + 1]; + for (size_t c = 0; c < sizeof n->id; ++c) + sprintf(id + 2 * c, "%02hhx", n->id.x[c]); + id[sizeof id - 1] = 0; + send_request(c, "%d %d %s %s %s %d %d %d %d %x %x %s %s %d %hd %hd %hd %ld", CONTROL, REQ_DUMP_NODES, + n->name, id, n->hostname ?: "unknown port unknown", cipher_get_nid(n->outcipher), digest_get_nid(n->outdigest), (int)digest_length(n->outdigest), n->outcompression, n->options, bitfield_to_int(&n->status, sizeof n->status), n->nexthop ? n->nexthop->name : "-", n->via ? n->via->name ?: "-" : "-", n->distance, n->mtu, n->minmtu, n->maxmtu, (long)n->last_state_change); + } return send_request(c, "%d %d", CONTROL, REQ_DUMP_NODES); } diff --git a/src/node.h b/src/node.h index e704ba8..b6db18b 100644 --- a/src/node.h +++ b/src/node.h @@ -37,11 +37,13 @@ typedef struct node_status_t { unsigned int indirect:1; /* 1 if this node is not directly reachable by us */ unsigned int sptps:1; /* 1 if this node supports SPTPS */ unsigned int udp_confirmed:1; /* 1 if the address is one that we received UDP traffic on */ - unsigned int unused:24; + unsigned int send_locally:1; /* 1 if the next UDP packet should be sent on the local network */ + unsigned int unused:23; } node_status_t; typedef struct node_t { char *name; /* name of this node */ + node_id_t id; /* unique node ID (name hash) */ uint32_t options; /* options turned on for this node */ int sock; /* Socket to use for outgoing UDP packets */ @@ -110,6 +112,7 @@ extern void free_node(node_t *); extern void node_add(node_t *); extern void node_del(node_t *); extern node_t *lookup_node(char *); +extern node_t *lookup_node_id(const node_id_t *); extern node_t *lookup_node_udp(const sockaddr_t *); extern bool dump_nodes(struct connection_t *); extern bool dump_traffic(struct connection_t *); diff --git a/src/openssl/cipher.c b/src/openssl/cipher.c index 5d9bebc..9b39a28 100644 --- a/src/openssl/cipher.c +++ b/src/openssl/cipher.c @@ -30,15 +30,8 @@ struct cipher { EVP_CIPHER_CTX ctx; const EVP_CIPHER *cipher; - struct cipher_counter *counter; }; -typedef struct cipher_counter { - unsigned char counter[CIPHER_MAX_IV_SIZE]; - unsigned char block[CIPHER_MAX_IV_SIZE]; - int n; -} cipher_counter_t; - static cipher_t *cipher_open(const EVP_CIPHER *evp_cipher) { cipher_t *cipher = xzalloc(sizeof *cipher); cipher->cipher = evp_cipher; @@ -76,7 +69,6 @@ void cipher_close(cipher_t *cipher) { return; EVP_CIPHER_CTX_cleanup(&cipher->ctx); - free(cipher->counter); free(cipher); } @@ -84,7 +76,7 @@ size_t cipher_keylength(const cipher_t *cipher) { if(!cipher || !cipher->cipher) return 0; - return cipher->cipher->key_len + cipher->cipher->block_size; + return cipher->cipher->key_len + cipher->cipher->iv_len; } bool cipher_set_key(cipher_t *cipher, void *key, bool encrypt) { @@ -117,70 +109,6 @@ bool cipher_set_key_from_rsa(cipher_t *cipher, void *key, size_t len, bool encry return false; } -bool cipher_set_counter(cipher_t *cipher, const void *counter, size_t len) { - if(len > cipher->cipher->block_size - 4) { - logger(DEBUG_ALWAYS, LOG_ERR, "Counter too long"); - abort(); - } - - memcpy(cipher->counter->counter + cipher->cipher->block_size - len, counter, len); - memset(cipher->counter->counter, 0, 4); - cipher->counter->n = 0; - - return true; -} - -bool cipher_set_counter_key(cipher_t *cipher, void *key) { - int result = EVP_EncryptInit_ex(&cipher->ctx, cipher->cipher, NULL, (unsigned char *)key, NULL); - if(!result) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error while setting key: %s", ERR_error_string(ERR_get_error(), NULL)); - return false; - } - - if(!cipher->counter) - cipher->counter = xzalloc(sizeof *cipher->counter); - else - cipher->counter->n = 0; - - memcpy(cipher->counter->counter, (unsigned char *)key + cipher->cipher->key_len, cipher->cipher->block_size); - - return true; -} - -bool cipher_counter_xor(cipher_t *cipher, const void *indata, size_t inlen, void *outdata) { - if(!cipher->counter) { - logger(DEBUG_ALWAYS, LOG_ERR, "Counter not initialized"); - return false; - } - - const unsigned char *in = indata; - unsigned char *out = outdata; - - while(inlen--) { - // Encrypt the new counter value if we need it - if(!cipher->counter->n) { - int len; - if(!EVP_EncryptUpdate(&cipher->ctx, cipher->counter->block, &len, cipher->counter->counter, cipher->cipher->block_size)) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error while encrypting: %s", ERR_error_string(ERR_get_error(), NULL)); - return false; - } - - // Increase the counter value - for(int i = 0; i < cipher->cipher->block_size; i++) - if(++cipher->counter->counter[i]) - break; - } - - *out++ = *in++ ^ cipher->counter->block[cipher->counter->n++]; - - if(cipher->counter->n >= cipher->cipher->block_size) - cipher->counter->n = 0; - } - - return true; -} - - bool cipher_encrypt(cipher_t *cipher, const void *indata, size_t inlen, void *outdata, size_t *outlen, bool oneshot) { if(oneshot) { int len, pad; diff --git a/src/openssl/crypto.c b/src/openssl/crypto.c index 6c5cbc8..5b866b0 100644 --- a/src/openssl/crypto.c +++ b/src/openssl/crypto.c @@ -1,6 +1,6 @@ /* crypto.c -- Cryptographic miscellaneous functions and initialisation - Copyright (C) 2007-2013 Guus Sliepen + Copyright (C) 2007-2014 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 @@ -25,8 +25,65 @@ #include "../crypto.h" +#ifndef HAVE_MINGW + +static int random_fd = -1; + +static void random_init(void) { + random_fd = open("/dev/urandom", O_RDONLY); + if(random_fd < 0) + random_fd = open("/dev/random", O_RDONLY); + if(random_fd < 0) { + fprintf(stderr, "Could not open source of random numbers: %s\n", strerror(errno)); + abort(); + } +} + +static void random_exit(void) { + close(random_fd); +} + +void randomize(void *out, size_t outlen) { + while(outlen) { + size_t len = read(random_fd, out, outlen); + if(len <= 0) { + if(errno == EAGAIN || errno == EINTR) + continue; + fprintf(stderr, "Could not read random numbers: %s\n", strerror(errno)); + abort(); + } + out += len; + outlen -= len; + } +} + +#else + +#include +HCRYPTPROV prov; + +void random_init(void) { + if(!CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) { + fprintf(stderr, "CryptAcquireContext() failed!\n"); + abort(); + } +} + +void random_exit(void) { + CryptReleaseContext(prov, 0); +} + +void randomize(void *out, size_t outlen) { + if(!CryptGenRandom(prov, outlen, out)) { + fprintf(stderr, "CryptGenRandom() failed\n"); + abort(); + } +} + +#endif + void crypto_init(void) { - RAND_load_file("/dev/urandom", 1024); + random_init(); ENGINE_load_builtin_engines(); ENGINE_register_all_complete(); @@ -42,8 +99,7 @@ void crypto_init(void) { void crypto_exit(void) { EVP_cleanup(); -} - -void randomize(void *out, size_t outlen) { - RAND_pseudo_bytes(out, outlen); + ERR_free_strings(); + ENGINE_cleanup(); + random_exit(); } diff --git a/src/openssl/ecdh.c b/src/openssl/ecdh.c deleted file mode 100644 index d997007..0000000 --- a/src/openssl/ecdh.c +++ /dev/null @@ -1,96 +0,0 @@ -/* - ecdh.c -- Diffie-Hellman key exchange handling - Copyright (C) 2011-2013 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 - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include "../system.h" - -#include -#include -#include -#include - -#define __TINC_ECDH_INTERNAL__ -typedef EC_KEY ecdh_t; - -#include "../ecdh.h" -#include "../logger.h" -#include "../utils.h" -#include "../xalloc.h" - -ecdh_t *ecdh_generate_public(void *pubkey) { - ecdh_t *ecdh = EC_KEY_new_by_curve_name(NID_secp521r1); - if(!ecdh) { - logger(DEBUG_ALWAYS, LOG_ERR, "Generating EC key_by_curve_name failed: %s", ERR_error_string(ERR_get_error(), NULL)); - return false; - } - - if(!EC_KEY_generate_key(ecdh)) { - EC_KEY_free(ecdh); - logger(DEBUG_ALWAYS, LOG_ERR, "Generating EC key failed: %s", ERR_error_string(ERR_get_error(), NULL)); - return NULL; - } - - const EC_POINT *point = EC_KEY_get0_public_key(ecdh); - if(!point) { - EC_KEY_free(ecdh); - logger(DEBUG_ALWAYS, LOG_ERR, "Getting public key failed: %s", ERR_error_string(ERR_get_error(), NULL)); - return NULL; - } - - size_t result = EC_POINT_point2oct(EC_KEY_get0_group(ecdh), point, POINT_CONVERSION_COMPRESSED, pubkey, ECDH_SIZE, NULL); - if(!result) { - EC_KEY_free(ecdh); - logger(DEBUG_ALWAYS, LOG_ERR, "Converting EC_POINT to binary failed: %s", ERR_error_string(ERR_get_error(), NULL)); - return NULL; - } - - return ecdh; -} - -bool ecdh_compute_shared(ecdh_t *ecdh, const void *pubkey, void *shared) { - EC_POINT *point = EC_POINT_new(EC_KEY_get0_group(ecdh)); - if(!point) { - logger(DEBUG_ALWAYS, LOG_ERR, "EC_POINT_new() failed: %s", ERR_error_string(ERR_get_error(), NULL)); - EC_KEY_free(ecdh); - return false; - } - - int result = EC_POINT_oct2point(EC_KEY_get0_group(ecdh), point, pubkey, ECDH_SIZE, NULL); - if(!result) { - EC_POINT_free(point); - EC_KEY_free(ecdh); - logger(DEBUG_ALWAYS, LOG_ERR, "Converting binary to EC_POINT failed: %s", ERR_error_string(ERR_get_error(), NULL)); - return false; - } - - result = ECDH_compute_key(shared, ECDH_SIZE, point, ecdh, NULL); - EC_POINT_free(point); - EC_KEY_free(ecdh); - - if(!result) { - logger(DEBUG_ALWAYS, LOG_ERR, "Computing Elliptic Curve Diffie-Hellman shared key failed: %s", ERR_error_string(ERR_get_error(), NULL)); - return false; - } - - return true; -} - -void ecdh_free(ecdh_t *ecdh) { - if(ecdh) - EC_KEY_free(ecdh); -} diff --git a/src/openssl/ecdsa.c b/src/openssl/ecdsa.c deleted file mode 100644 index bca89fc..0000000 --- a/src/openssl/ecdsa.c +++ /dev/null @@ -1,131 +0,0 @@ -/* - ecdsa.c -- ECDSA key handling - Copyright (C) 2011-2013 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 - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include "../system.h" - -#include -#include - -#define __TINC_ECDSA_INTERNAL__ -typedef EC_KEY ecdsa_t; - -#include "../logger.h" -#include "../ecdsa.h" -#include "../utils.h" -#include "../xalloc.h" - -// Get and set ECDSA keys -// -ecdsa_t *ecdsa_set_base64_public_key(const char *p) { - ecdsa_t *ecdsa = EC_KEY_new_by_curve_name(NID_secp521r1); - if(!ecdsa) { - logger(DEBUG_ALWAYS, LOG_DEBUG, "EC_KEY_new_by_curve_name failed: %s", ERR_error_string(ERR_get_error(), NULL)); - return NULL; - } - - int len = strlen(p); - unsigned char pubkey[len / 4 * 3 + 3]; - const unsigned char *ppubkey = pubkey; - len = b64decode(p, (char *)pubkey, len); - - if(!o2i_ECPublicKey(&ecdsa, &ppubkey, len)) { - logger(DEBUG_ALWAYS, LOG_DEBUG, "o2i_ECPublicKey failed: %s", ERR_error_string(ERR_get_error(), NULL)); - EC_KEY_free(ecdsa); - return NULL; - } - - return ecdsa; -} - -char *ecdsa_get_base64_public_key(ecdsa_t *ecdsa) { - unsigned char *pubkey = NULL; - int len = i2o_ECPublicKey(ecdsa, &pubkey); - - char *base64 = xmalloc(len * 4 / 3 + 5); - b64encode((char *)pubkey, base64, len); - - free(pubkey); - - return base64; -} - -// Read PEM ECDSA keys - -ecdsa_t *ecdsa_read_pem_public_key(FILE *fp) { - ecdsa_t *ecdsa = PEM_read_EC_PUBKEY(fp, NULL, NULL, NULL); - - if(!ecdsa) - logger(DEBUG_ALWAYS, LOG_ERR, "Unable to read ECDSA public key: %s", ERR_error_string(ERR_get_error(), NULL)); - - return ecdsa; -} - -ecdsa_t *ecdsa_read_pem_private_key(FILE *fp) { - ecdsa_t *ecdsa = PEM_read_ECPrivateKey(fp, NULL, NULL, NULL); - - if(!ecdsa) - logger(DEBUG_ALWAYS, LOG_ERR, "Unable to read ECDSA private key: %s", ERR_error_string(ERR_get_error(), NULL)); - - return ecdsa; -} - -size_t ecdsa_size(ecdsa_t *ecdsa) { - return ECDSA_size(ecdsa); -} - -// TODO: standardise output format? - -bool ecdsa_sign(ecdsa_t *ecdsa, const void *in, size_t len, void *sig) { - unsigned int siglen = ECDSA_size(ecdsa); - - unsigned char hash[SHA512_DIGEST_LENGTH]; - SHA512(in, len, hash); - - memset(sig, 0, siglen); - - if(!ECDSA_sign(0, hash, sizeof hash, sig, &siglen, ecdsa)) { - logger(DEBUG_ALWAYS, LOG_DEBUG, "ECDSA_sign() failed: %s", ERR_error_string(ERR_get_error(), NULL)); - return false; - } - - return true; -} - -bool ecdsa_verify(ecdsa_t *ecdsa, const void *in, size_t len, const void *sig) { - unsigned int siglen = ECDSA_size(ecdsa); - - unsigned char hash[SHA512_DIGEST_LENGTH]; - SHA512(in, len, hash); - - if(!ECDSA_verify(0, hash, sizeof hash, sig, siglen, ecdsa)) { - logger(DEBUG_ALWAYS, LOG_DEBUG, "ECDSA_verify() failed: %s", ERR_error_string(ERR_get_error(), NULL)); - return false; - } - - return true; -} - -bool ecdsa_active(ecdsa_t *ecdsa) { - return ecdsa; -} - -void ecdsa_free(ecdsa_t *ecdsa) { - if(ecdsa) - EC_KEY_free(ecdsa); -} diff --git a/src/openssl/rsa.c b/src/openssl/rsa.c index 20bfb65..9c1f498 100644 --- a/src/openssl/rsa.c +++ b/src/openssl/rsa.c @@ -61,8 +61,10 @@ rsa_t *rsa_set_hex_private_key(char *n, char *e, char *d) { rsa_t *rsa_read_pem_public_key(FILE *fp) { rsa_t *rsa = PEM_read_RSAPublicKey(fp, NULL, NULL, NULL); - if(!rsa) + if(!rsa) { + rewind(fp); rsa = PEM_read_RSA_PUBKEY(fp, NULL, NULL, NULL); + } if(!rsa) logger(DEBUG_ALWAYS, LOG_ERR, "Unable to read RSA public key: %s", ERR_error_string(ERR_get_error(), NULL)); diff --git a/src/process.c b/src/process.c index c1038bc..2243bf9 100644 --- a/src/process.c +++ b/src/process.c @@ -34,6 +34,7 @@ #include "subnet.h" #include "utils.h" #include "xalloc.h" +#include "version.h" /* If zero, don't detach from the terminal. */ bool do_detach = true; @@ -108,6 +109,8 @@ static bool install_service(void) { return true; } +io_t stop_io; + DWORD WINAPI controlhandler(DWORD request, DWORD type, LPVOID boe, LPVOID bah) { switch(request) { case SERVICE_CONTROL_INTERROGATE: @@ -124,10 +127,11 @@ DWORD WINAPI controlhandler(DWORD request, DWORD type, LPVOID boe, LPVOID bah) { return ERROR_CALL_NOT_IMPLEMENTED; } - event_exit(); - status.dwWaitHint = 30000; + status.dwWaitHint = 1000; status.dwCurrentState = SERVICE_STOP_PENDING; SetServiceStatus(statushandle, &status); + if (WSASetEvent(stop_io.event) == FALSE) + abort(); return NO_ERROR; } @@ -209,7 +213,7 @@ bool detach(void) { openlogger(identname, use_logfile?LOGMODE_FILE:(do_detach?LOGMODE_SYSLOG:LOGMODE_STDERR)); logger(DEBUG_ALWAYS, LOG_NOTICE, "tincd %s (%s %s) starting, debug level %d", - VERSION, __DATE__, __TIME__, debug_level); + VERSION, BUILD_DATE, BUILD_TIME, debug_level); return true; } diff --git a/src/process.h b/src/process.h index 4cdf711..ce2daed 100644 --- a/src/process.h +++ b/src/process.h @@ -29,6 +29,7 @@ extern bool detach(void); extern bool kill_other(int); #ifdef HAVE_MINGW +extern io_t stop_io; extern bool init_service(void); #endif diff --git a/src/protocol.c b/src/protocol.c index 374c522..1ec169a 100644 --- a/src/protocol.c +++ b/src/protocol.c @@ -55,17 +55,6 @@ static char (*request_name[]) = { static splay_tree_t *past_request_tree; -bool check_id(const char *id) { - if(!id || !*id) - return false; - - for(; *id; id++) - if(!isalnum(*id) && *id != '_') - return false; - - return true; -} - /* Generic request routines - takes care of logging and error detection as well */ diff --git a/src/protocol.h b/src/protocol.h index e771c54..080d50c 100644 --- a/src/protocol.h +++ b/src/protocol.h @@ -26,7 +26,7 @@ /* Protocol version. Different major versions are incompatible. */ #define PROT_MAJOR 17 -#define PROT_MINOR 3 /* Should not exceed 255! */ +#define PROT_MINOR 4 /* Should not exceed 255! */ /* Silly Windows */ @@ -81,7 +81,6 @@ extern ecdsa_t *invitation_key; extern bool send_request(struct connection_t *, const char *, ...) __attribute__ ((__format__(printf, 2, 3))); extern void forward_request(struct connection_t *, const char *); extern bool receive_request(struct connection_t *, const char *); -extern bool check_id(const char *); extern void init_requests(void); extern void exit_requests(void); diff --git a/src/protocol_auth.c b/src/protocol_auth.c index 147c3b4..cd39f28 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-2013 Guus Sliepen + 2000-2014 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 @@ -172,7 +172,7 @@ static bool finalize_invitation(connection_t *c, const char *data, uint16_t len) return false; } - fprintf(f, "ECDSAPublicKey = %s\n", data); + fprintf(f, "Ed25519PublicKey = %s\n", data); fclose(f); logger(DEBUG_CONNECTIONS, LOG_INFO, "Key succesfully received from %s (%s)", c->name, c->hostname); @@ -198,7 +198,7 @@ static bool finalize_invitation(connection_t *c, const char *data, uint16_t len) return true; } -static bool receive_invitation_sptps(void *handle, uint8_t type, const char *data, uint16_t len) { +static bool receive_invitation_sptps(void *handle, uint8_t type, const void *data, uint16_t len) { connection_t *c = handle; if(type == 128) @@ -380,12 +380,13 @@ bool id_h(connection_t *c, const char *request) { if(experimental) read_ecdsa_public_key(c); - } else { - if(c->protocol_minor && !ecdsa_active(c->ecdsa)) - c->protocol_minor = 1; + /* Ignore failures if no key known yet */ } - /* Forbid version rollback for nodes whose ECDSA key we know */ + if(c->protocol_minor && !ecdsa_active(c->ecdsa)) + c->protocol_minor = 1; + + /* Forbid version rollback for nodes whose Ed25519 key we know */ if(ecdsa_active(c->ecdsa) && c->protocol_minor < 2) { logger(DEBUG_ALWAYS, LOG_ERR, "Peer %s (%s) tries to roll back protocol version to %d.%d", @@ -411,6 +412,11 @@ bool id_h(connection_t *c, const char *request) { } bool send_metakey(connection_t *c) { + if(!myself->connection->rsa) { + logger(DEBUG_CONNECTIONS, LOG_ERR, "Peer %s (%s) uses legacy protocol which we don't support", c->name, c->hostname); + return false; + } + if(!read_rsa_public_key(c)) return false; @@ -420,7 +426,7 @@ bool send_metakey(connection_t *c) { if(!(c->outdigest = digest_open_sha1(-1))) return false; - size_t len = rsa_size(c->rsa); + const size_t len = rsa_size(c->rsa); char key[len]; char enckey[len]; char hexkey[2 * len + 1]; @@ -477,9 +483,12 @@ bool send_metakey(connection_t *c) { } bool metakey_h(connection_t *c, const char *request) { + if(!myself->connection->rsa) + return false; + char hexkey[MAX_STRING_SIZE]; int cipher, digest, maclength, compression; - size_t len = rsa_size(myself->connection->rsa); + const size_t len = rsa_size(myself->connection->rsa); char enckey[len]; char key[len]; @@ -513,14 +522,22 @@ bool metakey_h(connection_t *c, const char *request) { /* Check and lookup cipher and digest algorithms */ - if(!(c->incipher = cipher_open_by_nid(cipher)) || !cipher_set_key_from_rsa(c->incipher, key, len, false)) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error during initialisation of cipher from %s (%s)", c->name, c->hostname); - return false; + if(cipher) { + if(!(c->incipher = cipher_open_by_nid(cipher)) || !cipher_set_key_from_rsa(c->incipher, key, len, false)) { + logger(DEBUG_ALWAYS, LOG_ERR, "Error during initialisation of cipher from %s (%s)", c->name, c->hostname); + return false; + } + } else { + c->incipher = NULL; } - if(!(c->indigest = digest_open_by_nid(digest, -1))) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error during initialisation of digest from %s (%s)", c->name, c->hostname); - return false; + if(digest) { + if(!(c->indigest = digest_open_by_nid(digest, -1))) { + logger(DEBUG_ALWAYS, LOG_ERR, "Error during initialisation of digest from %s (%s)", c->name, c->hostname); + return false; + } + } else { + c->indigest = NULL; } c->status.decryptin = true; @@ -531,7 +548,7 @@ bool metakey_h(connection_t *c, const char *request) { } bool send_challenge(connection_t *c) { - size_t len = rsa_size(c->rsa); + const size_t len = rsa_size(c->rsa); char buffer[len * 2 + 1]; if(!c->hischallenge) @@ -551,8 +568,11 @@ bool send_challenge(connection_t *c) { } bool challenge_h(connection_t *c, const char *request) { + if(!myself->connection->rsa) + return false; + char buffer[MAX_STRING_SIZE]; - size_t len = rsa_size(myself->connection->rsa); + const size_t len = rsa_size(myself->connection->rsa); size_t digestlen = digest_length(c->indigest); char digest[digestlen]; @@ -628,7 +648,7 @@ bool chal_reply_h(connection_t *c, const char *request) { } static bool send_upgrade(connection_t *c) { - /* Special case when protocol_minor is 1: the other end is ECDSA capable, + /* Special case when protocol_minor is 1: the other end is Ed25519 capable, * but doesn't know our key yet. So send it now. */ char *pubkey = ecdsa_get_base64_public_key(myself->connection->ecdsa); @@ -672,7 +692,8 @@ bool send_ack(connection_t *c) { if(choice) c->options |= OPTION_CLAMP_MSS; - get_config_int(lookup_config(c->config_tree, "Weight"), &c->estimated_weight); + if(!get_config_int(lookup_config(c->config_tree, "Weight"), &c->estimated_weight)) + get_config_int(lookup_config(config_tree, "Weight"), &c->estimated_weight); return send_request(c, "%d %s %d %x", ACK, myport, c->estimated_weight, (c->options & 0xffffff) | (experimental ? (PROT_MINOR << 24) : 0)); } @@ -716,12 +737,26 @@ static bool upgrade_h(connection_t *c, const char *request) { } if(ecdsa_active(c->ecdsa) || read_ecdsa_public_key(c)) { - logger(DEBUG_ALWAYS, LOG_INFO, "Already have ECDSA public key from %s (%s), not upgrading.", c->name, c->hostname); + char *knownkey = ecdsa_get_base64_public_key(c->ecdsa); + bool different = strcmp(knownkey, pubkey); + free(knownkey); + if(different) { + logger(DEBUG_ALWAYS, LOG_ERR, "Already have an Ed25519 public key from %s (%s) which is different from the one presented now!", c->name, c->hostname); + return false; + } + logger(DEBUG_ALWAYS, LOG_INFO, "Already have Ed25519 public key from %s (%s), ignoring.", c->name, c->hostname); + c->allow_request = TERMREQ; + return send_termreq(c); + } + + c->ecdsa = ecdsa_set_base64_public_key(pubkey); + if(!c->ecdsa) { + logger(DEBUG_ALWAYS, LOG_INFO, "Got bad Ed25519 public key from %s (%s), not upgrading.", c->name, c->hostname); return false; } - logger(DEBUG_ALWAYS, LOG_INFO, "Got ECDSA public key from %s (%s), upgrading!", c->name, c->hostname); - append_config_file(c->name, "ECDSAPublicKey", pubkey); + logger(DEBUG_ALWAYS, LOG_INFO, "Got Ed25519 public key from %s (%s), upgrading!", c->name, c->hostname); + append_config_file(c->name, "Ed25519PublicKey", pubkey); c->allow_request = TERMREQ; return send_termreq(c); } @@ -795,7 +830,6 @@ bool ack_h(connection_t *c, const char *request) { /* Activate this connection */ c->allow_request = ALL; - c->status.active = true; logger(DEBUG_CONNECTIONS, LOG_NOTICE, "Connection with %s (%s) activated", c->name, c->hostname); @@ -812,6 +846,16 @@ bool ack_h(connection_t *c, const char *request) { sockaddr2str(&c->address, &hisaddress, NULL); c->edge->address = str2sockaddr(hisaddress, hisport); free(hisaddress); + sockaddr_t local_sa; + socklen_t local_salen = sizeof local_sa; + if (getsockname(c->socket, &local_sa.sa, &local_salen) < 0) + logger(DEBUG_ALWAYS, LOG_WARNING, "Could not get local socket address for connection with %s", c->name); + else { + char *local_address; + sockaddr2str(&local_sa, &local_address, NULL); + c->edge->local_address = str2sockaddr(local_address, myport); + free(local_address); + } c->edge->weight = (weight + c->estimated_weight) / 2; c->edge->connection = c; c->edge->options = c->options; diff --git a/src/protocol_edge.c b/src/protocol_edge.c index e285a6d..4760162 100644 --- a/src/protocol_edge.c +++ b/src/protocol_edge.c @@ -37,14 +37,19 @@ bool send_add_edge(connection_t *c, const edge_t *e) { bool x; char *address, *port; + char *local_address, *local_port; sockaddr2str(&e->address, &address, &port); + sockaddr2str(&e->local_address, &local_address, &local_port); - x = send_request(c, "%d %x %s %s %s %s %x %d", ADD_EDGE, rand(), + x = send_request(c, "%d %x %s %s %s %s %x %d %s %s", ADD_EDGE, rand(), e->from->name, e->to->name, address, port, - e->options, e->weight); + e->options, e->weight, local_address, local_port); + free(address); free(port); + free(local_address); + free(local_port); return x; } @@ -56,12 +61,15 @@ bool add_edge_h(connection_t *c, const char *request) { char to_name[MAX_STRING_SIZE]; char to_address[MAX_STRING_SIZE]; char to_port[MAX_STRING_SIZE]; - sockaddr_t address; + char address_local[MAX_STRING_SIZE] = "unknown"; + char port_local[MAX_STRING_SIZE] = "unknown"; + sockaddr_t address, local_address; uint32_t options; int weight; - if(sscanf(request, "%*d %*x "MAX_STRING" "MAX_STRING" "MAX_STRING" "MAX_STRING" %x %d", - from_name, to_name, to_address, to_port, &options, &weight) != 6) { + int parameter_count = sscanf(request, "%*d %*x "MAX_STRING" "MAX_STRING" "MAX_STRING" "MAX_STRING" %x %d "MAX_STRING" "MAX_STRING, + from_name, to_name, to_address, to_port, &options, &weight, address_local, port_local); + if (parameter_count != 6 && parameter_count != 8) { logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "ADD_EDGE", c->name, c->hostname); return false; @@ -109,13 +117,14 @@ bool add_edge_h(connection_t *c, const char *request) { /* Convert addresses */ address = str2sockaddr(to_address, to_port); + local_address = str2sockaddr(address_local, port_local); /* Check if edge already exists */ e = lookup_edge(from, to); if(e) { - if(e->weight != weight || e->options != options || sockaddrcmp(&e->address, &address)) { + if(e->weight != weight || e->options != options || sockaddrcmp(&e->address, &address) || sockaddrcmp(&e->local_address, &local_address)) { if(from == myself) { logger(DEBUG_PROTOCOL, LOG_WARNING, "Got %s from %s (%s) for ourself which does not match existing entry", "ADD_EDGE", c->name, c->hostname); @@ -145,6 +154,7 @@ bool add_edge_h(connection_t *c, const char *request) { e->from = from; e->to = to; e->address = address; + e->local_address = local_address; e->options = options; e->weight = weight; edge_add(e); diff --git a/src/protocol_key.c b/src/protocol_key.c index a3cf3f5..8b19d90 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-2013 Guus Sliepen + 2000-2014 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 @@ -41,7 +41,7 @@ void send_key_changed(void) { /* Immediately send new keys to directly connected nodes to keep UDP mappings alive */ for list_each(connection_t, c, connection_list) - if(c->status.active && c->node && c->node->status.reachable && !c->node->status.sptps) + if(c->edge && c->node && c->node->status.reachable && !c->node->status.sptps) send_ans_key(c->node); /* Force key exchange for connections using SPTPS */ @@ -87,7 +87,7 @@ bool key_changed_h(connection_t *c, const char *request) { return true; } -static bool send_initial_sptps_data(void *handle, uint8_t type, const char *data, size_t len) { +static bool send_initial_sptps_data(void *handle, uint8_t type, const void *data, size_t len) { node_t *to = handle; to->sptps.send_data = send_sptps_data; char buf[len * 4 / 3 + 5]; @@ -98,7 +98,7 @@ static bool send_initial_sptps_data(void *handle, uint8_t type, const char *data bool send_req_key(node_t *to) { if(to->status.sptps) { if(!node_read_ecdsa_public_key(to)) { - logger(DEBUG_PROTOCOL, LOG_DEBUG, "No ECDSA key known for %s (%s)", to->name, to->hostname); + logger(DEBUG_PROTOCOL, LOG_DEBUG, "No Ed25519 key known for %s (%s)", to->name, to->hostname); send_request(to->nexthop->connection, "%d %s %s %d", REQ_KEY, myself->name, to->name, REQ_PUBKEY); return true; } @@ -124,6 +124,11 @@ bool send_req_key(node_t *to) { static bool req_key_ext_h(connection_t *c, const char *request, node_t *from, int reqno) { switch(reqno) { case REQ_PUBKEY: { + if(!node_read_ecdsa_public_key(from)) { + /* Request their key *before* we send our key back. Otherwise the first SPTPS packet from them will get dropped. */ + logger(DEBUG_PROTOCOL, LOG_DEBUG, "Preemptively requesting Ed25519 key for %s (%s)", from->name, from->hostname); + send_request(from->nexthop->connection, "%d %s %s %d", REQ_KEY, myself->name, from->name, REQ_PUBKEY); + } char *pubkey = ecdsa_get_base64_public_key(myself->connection->ecdsa); send_request(from->nexthop->connection, "%d %s %s %d %s", REQ_KEY, myself->name, from->name, ANS_PUBKEY, pubkey); free(pubkey); @@ -142,14 +147,14 @@ static bool req_key_ext_h(connection_t *c, const char *request, node_t *from, in return true; } - logger(DEBUG_PROTOCOL, LOG_INFO, "Learned ECDSA public key from %s (%s)", from->name, from->hostname); - append_config_file(from->name, "ECDSAPublicKey", pubkey); + logger(DEBUG_PROTOCOL, LOG_INFO, "Learned Ed25519 public key from %s (%s)", from->name, from->hostname); + append_config_file(from->name, "Ed25519PublicKey", pubkey); return true; } case REQ_KEY: { if(!node_read_ecdsa_public_key(from)) { - logger(DEBUG_PROTOCOL, LOG_DEBUG, "No ECDSA key known for %s (%s)", from->name, from->hostname); + logger(DEBUG_PROTOCOL, LOG_DEBUG, "No Ed25519 key known for %s (%s)", from->name, from->hostname); send_request(from->nexthop->connection, "%d %s %s %d", REQ_KEY, myself->name, from->name, REQ_PUBKEY); return true; } @@ -250,6 +255,7 @@ bool req_key_h(connection_t *c, const char *request) { return true; } + /* TODO: forwarding SPTPS packets in this way is inefficient because we send them over TCP without checking for UDP connectivity */ send_request(to->nexthop->connection, "%s", request); } @@ -260,25 +266,32 @@ bool send_ans_key(node_t *to) { if(to->status.sptps) abort(); - size_t keylen = cipher_keylength(myself->incipher); + size_t keylen = myself->incipher ? cipher_keylength(myself->incipher) : 1; char key[keylen * 2 + 1]; + randomize(key, keylen); + cipher_close(to->incipher); digest_close(to->indigest); - to->incipher = cipher_open_by_nid(cipher_get_nid(myself->incipher)); - to->indigest = digest_open_by_nid(digest_get_nid(myself->indigest), digest_length(myself->indigest)); + if(myself->incipher) { + to->incipher = cipher_open_by_nid(cipher_get_nid(myself->incipher)); + if(!to->incipher) + abort(); + if(!cipher_set_key(to->incipher, key, false)) + abort(); + } + + if(myself->indigest) { + to->indigest = digest_open_by_nid(digest_get_nid(myself->indigest), digest_length(myself->indigest)); + if(!to->indigest) + abort(); + if(!digest_set_key(to->indigest, key, keylen)) + abort(); + } + to->incompression = myself->incompression; - if(!to->incipher || !to->indigest) - abort(); - - randomize(key, keylen); - if(!cipher_set_key(to->incipher, key, false)) - abort(); - if(!digest_set_key(to->indigest, key, keylen)) - abort(); - bin2hex(key, key, keylen); // Reset sequence number and late packet window @@ -386,7 +399,9 @@ bool ans_key_h(connection_t *c, const char *request) { update_node_udp(from, &sa); } - if(from->options & OPTION_PMTU_DISCOVERY && !(from->options & OPTION_TCPONLY)) + /* Don't send probes if we can't send UDP packets directly to that node. + TODO: the indirect (via) condition can change at any time as edges are added and removed, so this should probably be moved to graph.c. */ + if((from->via == myself || from->via == from) && from->options & OPTION_PMTU_DISCOVERY && !(from->options & OPTION_TCPONLY)) send_mtu_probe(from); } @@ -395,14 +410,22 @@ bool ans_key_h(connection_t *c, const char *request) { /* Check and lookup cipher and digest algorithms */ - if(!(from->outcipher = cipher_open_by_nid(cipher))) { - logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses unknown cipher!", from->name, from->hostname); - return false; + if(cipher) { + if(!(from->outcipher = cipher_open_by_nid(cipher))) { + logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses unknown cipher!", from->name, from->hostname); + return false; + } + } else { + from->outcipher = NULL; } - if(!(from->outdigest = digest_open_by_nid(digest, maclength))) { - logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses unknown digest!", from->name, from->hostname); - return false; + if(digest) { + if(!(from->outdigest = digest_open_by_nid(digest, maclength))) { + logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses unknown digest!", from->name, from->hostname); + return false; + } + } else { + from->outdigest = NULL; } if(maclength != digest_length(from->outdigest)) { @@ -414,16 +437,16 @@ bool ans_key_h(connection_t *c, const char *request) { keylen = hex2bin(key, key, sizeof key); - if(keylen != cipher_keylength(from->outcipher)) { + if(keylen != (from->outcipher ? cipher_keylength(from->outcipher) : 1)) { logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses wrong keylength!", from->name, from->hostname); return true; } /* Update our copy of the origin's packet key */ - if(!cipher_set_key(from->outcipher, key, true)) + if(from->outcipher && !cipher_set_key(from->outcipher, key, true)) return false; - if(!digest_set_key(from->outdigest, key, keylen)) + if(from->outdigest && !digest_set_key(from->outdigest, key, keylen)) return false; from->status.validkey = true; diff --git a/src/protocol_misc.c b/src/protocol_misc.c index 022438e..713dacf 100644 --- a/src/protocol_misc.c +++ b/src/protocol_misc.c @@ -131,7 +131,7 @@ bool send_tcppacket(connection_t *c, const vpn_packet_t *packet) { if(!send_request(c, "%d %hd", PACKET, packet->len)) return false; - return send_meta(c, (char *)packet->data, packet->len); + return send_meta(c, (char *)DATA(packet), packet->len); } bool tcppacket_h(connection_t *c, const char *request) { diff --git a/src/raw_socket_device.c b/src/raw_socket_device.c index 48954d5..eb38be2 100644 --- a/src/raw_socket_device.c +++ b/src/raw_socket_device.c @@ -32,12 +32,9 @@ #include "route.h" #include "xalloc.h" -#if defined(PF_PACKET) && defined(ETH_P_ALL) && defined(AF_PACKET) +#if defined(PF_PACKET) && defined(ETH_P_ALL) && defined(AF_PACKET) && defined(SIOCGIFINDEX) static char *device_info; -static uint64_t device_total_in = 0; -static uint64_t device_total_out = 0; - static bool setup_device(void) { struct ifreq ifr; struct sockaddr_ll sa; @@ -86,16 +83,17 @@ static bool setup_device(void) { } static void close_device(void) { - close(device_fd); + close(device_fd); device_fd = -1; - free(device); - free(iface); + free(device); device = NULL; + free(iface); iface = NULL; + device_info = NULL; } static bool read_packet(vpn_packet_t *packet) { int inlen; - if((inlen = read(device_fd, packet->data, MTU)) <= 0) { + if((inlen = read(device_fd, DATA(packet), MTU)) <= 0) { logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info, device, strerror(errno)); return false; @@ -103,8 +101,6 @@ static bool read_packet(vpn_packet_t *packet) { packet->len = inlen; - device_total_in += packet->len; - logger(DEBUG_TRAFFIC, LOG_DEBUG, "Read packet of %d bytes from %s", packet->len, device_info); @@ -115,29 +111,20 @@ static bool write_packet(vpn_packet_t *packet) { logger(DEBUG_TRAFFIC, LOG_DEBUG, "Writing packet of %d bytes to %s", packet->len, device_info); - if(write(device_fd, packet->data, packet->len) < 0) { + if(write(device_fd, DATA(packet), packet->len) < 0) { logger(DEBUG_ALWAYS, LOG_ERR, "Can't write to %s %s: %s", device_info, device, strerror(errno)); return false; } - device_total_out += packet->len; - return true; } -static void dump_device_stats(void) { - logger(DEBUG_ALWAYS, LOG_DEBUG, "Statistics for %s %s:", device_info, device); - logger(DEBUG_ALWAYS, LOG_DEBUG, " total bytes in: %10"PRIu64, device_total_in); - logger(DEBUG_ALWAYS, LOG_DEBUG, " total bytes out: %10"PRIu64, device_total_out); -} - const devops_t raw_socket_devops = { .setup = setup_device, .close = close_device, .read = read_packet, .write = write_packet, - .dump_stats = dump_device_stats, }; #else @@ -152,6 +139,5 @@ const devops_t raw_socket_devops = { .close = NULL, .read = NULL, .write = NULL, - .dump_stats = NULL, }; #endif diff --git a/src/route.c b/src/route.c index 00ba4c0..2785146 100644 --- a/src/route.c +++ b/src/route.c @@ -115,16 +115,16 @@ static void clamp_mss(const node_t *source, const node_t *via, vpn_packet_t *pac /* Find TCP header */ int start = ether_size; - uint16_t type = packet->data[12] << 8 | packet->data[13]; + uint16_t type = DATA(packet)[12] << 8 | DATA(packet)[13]; if(type == ETH_P_8021Q) { start += 4; - type = packet->data[16] << 8 | packet->data[17]; + type = DATA(packet)[16] << 8 | DATA(packet)[17]; } - if(type == ETH_P_IP && packet->data[start + 9] == 6) - start += (packet->data[start] & 0xf) * 4; - else if(type == ETH_P_IPV6 && packet->data[start + 6] == 6) + if(type == ETH_P_IP && DATA(packet)[start + 9] == 6) + start += (DATA(packet)[start] & 0xf) * 4; + else if(type == ETH_P_IPV6 && DATA(packet)[start + 6] == 6) start += 40; else return; @@ -133,38 +133,38 @@ static void clamp_mss(const node_t *source, const node_t *via, vpn_packet_t *pac return; /* Use data offset field to calculate length of options field */ - int len = ((packet->data[start + 12] >> 4) - 5) * 4; + int len = ((DATA(packet)[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) + if(DATA(packet)[start + 20 + i] == 0) break; - if(packet->data[start + 20 + i] == 1) { + if(DATA(packet)[start + 20 + i] == 1) { i++; continue; } - if(i > len - 2 || i > len - packet->data[start + 21 + i]) + if(i > len - 2 || i > len - DATA(packet)[start + 21 + i]) break; - if(packet->data[start + 20 + i] != 2) { - if(packet->data[start + 21 + i] < 2) + if(DATA(packet)[start + 20 + i] != 2) { + if(DATA(packet)[start + 21 + i] < 2) break; - i += packet->data[start + 21 + i]; + i += DATA(packet)[start + 21 + i]; continue; } - if(packet->data[start + 21] != 4) + if(DATA(packet)[start + 21] != 4) break; /* Found it */ - uint16_t oldmss = packet->data[start + 22 + i] << 8 | packet->data[start + 23 + i]; + uint16_t oldmss = DATA(packet)[start + 22 + i] << 8 | DATA(packet)[start + 23 + i]; uint16_t newmss = mtu - start - 20; - uint16_t csum = packet->data[start + 16] << 8 | packet->data[start + 17]; + uint16_t csum = DATA(packet)[start + 16] << 8 | DATA(packet)[start + 17]; if(oldmss <= newmss) break; @@ -172,23 +172,23 @@ static void clamp_mss(const node_t *source, const node_t *via, vpn_packet_t *pac logger(DEBUG_TRAFFIC, 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; + DATA(packet)[start + 22 + i] = newmss >> 8; + DATA(packet)[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; + DATA(packet)[start + 16] = csum >> 8; + DATA(packet)[start + 17] = csum & 0xff; break; } } static void swap_mac_addresses(vpn_packet_t *packet) { mac_t tmp; - memcpy(&tmp, &packet->data[0], sizeof tmp); - memcpy(&packet->data[0], &packet->data[6], sizeof tmp); - memcpy(&packet->data[6], &tmp, sizeof tmp); + memcpy(&tmp, &DATA(packet)[0], sizeof tmp); + memcpy(&DATA(packet)[0], &DATA(packet)[6], sizeof tmp); + memcpy(&DATA(packet)[6], &tmp, sizeof tmp); } static void age_subnets(void *data) { @@ -203,7 +203,7 @@ static void age_subnets(void *data) { } for list_each(connection_t, c, connection_list) - if(c->status.active) + if(c->edge) send_del_subnet(c, s); subnet_del(myself, s); @@ -223,7 +223,7 @@ static void learn_mac(mac_t *address) { /* If we don't know this MAC address yet, store it */ if(!subnet) { - logger(DEBUG_TRAFFIC, LOG_INFO, "Learned new MAC address %hx:%hx:%hx:%hx:%hx:%hx", + logger(DEBUG_TRAFFIC, LOG_INFO, "Learned new MAC address %x:%x:%x:%x:%x:%x", address->x[0], address->x[1], address->x[2], address->x[3], address->x[4], address->x[5]); @@ -238,7 +238,7 @@ static void learn_mac(mac_t *address) { /* And tell all other tinc daemons it's our MAC */ for list_each(connection_t, c, connection_list) - if(c->status.active) + if(c->edge) send_add_subnet(c, subnet); timeout_add(&age_subnets_timeout, age_subnets, NULL, &(struct timeval){10, rand() % 100000}); @@ -267,7 +267,7 @@ static void route_ipv4_unreachable(node_t *source, vpn_packet_t *packet, length_ /* Copy headers from packet into properly aligned structs on the stack */ - memcpy(&ip, packet->data + ether_size, ip_size); + memcpy(&ip, DATA(packet) + ether_size, ip_size); /* Remember original source and destination */ @@ -284,7 +284,7 @@ static void route_ipv4_unreachable(node_t *source, vpn_packet_t *packet, length_ /* Copy first part of original contents to ICMP message */ - memmove(packet->data + ether_size + ip_size + icmp_size, packet->data + ether_size, oldlen); + memmove(DATA(packet) + ether_size + ip_size + icmp_size, DATA(packet) + ether_size, oldlen); /* Fill in IPv4 header */ @@ -309,12 +309,12 @@ static void route_ipv4_unreachable(node_t *source, vpn_packet_t *packet, length_ icmp.icmp_cksum = 0; icmp.icmp_cksum = inet_checksum(&icmp, icmp_size, ~0); - icmp.icmp_cksum = inet_checksum(packet->data + ether_size + ip_size + icmp_size, oldlen, icmp.icmp_cksum); + icmp.icmp_cksum = inet_checksum(DATA(packet) + ether_size + ip_size + icmp_size, oldlen, icmp.icmp_cksum); /* Copy structs on stack back to packet */ - memcpy(packet->data + ether_size, &ip, ip_size); - memcpy(packet->data + ether_size + ip_size, &icmp, icmp_size); + memcpy(DATA(packet) + ether_size, &ip, ip_size); + memcpy(DATA(packet) + ether_size + ip_size, &icmp, icmp_size); packet->len = ether_size + ip_size + icmp_size + oldlen; @@ -330,8 +330,9 @@ static void fragment_ipv4_packet(node_t *dest, vpn_packet_t *packet, length_t et uint8_t *offset; uint16_t ip_off, origf; - memcpy(&ip, packet->data + ether_size, ip_size); + memcpy(&ip, DATA(packet) + ether_size, ip_size); fragment.priority = packet->priority; + fragment.offset = DEFAULT_PACKET_OFFSET; if(ip.ip_hl != ip_size / 4) return; @@ -345,7 +346,7 @@ static void fragment_ipv4_packet(node_t *dest, vpn_packet_t *packet, length_t et logger(DEBUG_TRAFFIC, LOG_INFO, "Fragmenting packet of %d bytes to %s (%s)", packet->len, dest->name, dest->hostname); - offset = packet->data + ether_size + ip_size; + offset = DATA(packet) + ether_size + ip_size; maxlen = (dest->mtu - ether_size - ip_size) & ~0x7; ip_off = ntohs(ip.ip_off); origf = ip_off & ~IP_OFFMASK; @@ -353,7 +354,7 @@ static void fragment_ipv4_packet(node_t *dest, vpn_packet_t *packet, length_t et while(todo) { len = todo > maxlen ? maxlen : todo; - memcpy(fragment.data + ether_size + ip_size, offset, len); + memcpy(DATA(&fragment) + ether_size + ip_size, offset, len); todo -= len; offset += len; @@ -361,8 +362,8 @@ static void fragment_ipv4_packet(node_t *dest, vpn_packet_t *packet, length_t et ip.ip_off = htons(ip_off | origf | (todo ? IP_MF : 0)); ip.ip_sum = 0; ip.ip_sum = inet_checksum(&ip, ip_size, ~0); - memcpy(fragment.data, packet->data, ether_size); - memcpy(fragment.data + ether_size, &ip, ip_size); + memcpy(DATA(&fragment), DATA(packet), ether_size); + memcpy(DATA(&fragment) + ether_size, &ip, ip_size); fragment.len = ether_size + ip_size + len; send_packet(dest, &fragment); @@ -371,12 +372,15 @@ static void fragment_ipv4_packet(node_t *dest, vpn_packet_t *packet, length_t et } } -static void route_ipv4_unicast(node_t *source, vpn_packet_t *packet) { +static void route_ipv4(node_t *source, vpn_packet_t *packet) { + if(!checklength(source, packet, ether_size + ip_size)) + return; + subnet_t *subnet; node_t *via; ipv4_t dest; - memcpy(&dest, &packet->data[30], sizeof dest); + memcpy(&dest, &DATA(packet)[30], sizeof dest); subnet = lookup_subnet_ipv4(&dest); if(!subnet) { @@ -391,6 +395,11 @@ static void route_ipv4_unicast(node_t *source, vpn_packet_t *packet) { return; } + if (!subnet->owner) { + broadcast_packet(source, packet); + return; + } + if(subnet->owner == source) { logger(DEBUG_TRAFFIC, LOG_WARNING, "Packet looping back to %s (%s)!", source->name, source->hostname); return; @@ -403,7 +412,7 @@ static void route_ipv4_unicast(node_t *source, vpn_packet_t *packet) { return route_ipv4_unreachable(source, packet, ether_size, ICMP_DEST_UNREACH, ICMP_NET_ANO); if(priorityinheritance) - packet->priority = packet->data[15]; + packet->priority = DATA(packet)[15]; via = (subnet->owner->via == myself) ? subnet->owner->nexthop : subnet->owner->via; @@ -417,7 +426,7 @@ static void route_ipv4_unicast(node_t *source, vpn_packet_t *packet) { if(via && packet->len > MAX(via->mtu, 590) && via != myself) { logger(DEBUG_TRAFFIC, 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) { + if(DATA(packet)[20] & 0x40) { packet->len = MAX(via->mtu, 590); route_ipv4_unreachable(source, packet, ether_size, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED); } else { @@ -432,20 +441,6 @@ static void route_ipv4_unicast(node_t *source, vpn_packet_t *packet) { send_packet(subnet->owner, packet); } -static void route_ipv4(node_t *source, vpn_packet_t *packet) { - if(!checklength(source, packet, ether_size + ip_size)) - return; - - if(broadcast_mode && (((packet->data[30] & 0xf0) == 0xe0) || ( - packet->data[30] == 255 && - packet->data[31] == 255 && - packet->data[32] == 255 && - packet->data[33] == 255))) - broadcast_packet(source, packet); - else - route_ipv4_unicast(source, packet); -} - /* RFC 2463 */ static void route_ipv6_unreachable(node_t *source, vpn_packet_t *packet, length_t ether_size, uint8_t type, uint8_t code) { @@ -469,7 +464,7 @@ static void route_ipv6_unreachable(node_t *source, vpn_packet_t *packet, length_ /* Copy headers from packet to structs on the stack */ - memcpy(&ip6, packet->data + ether_size, ip6_size); + memcpy(&ip6, DATA(packet) + ether_size, ip6_size); /* Remember original source and destination */ @@ -486,7 +481,7 @@ static void route_ipv6_unreachable(node_t *source, vpn_packet_t *packet, length_ /* Copy first part of original contents to ICMP message */ - memmove(packet->data + ether_size + ip6_size + icmp6_size, packet->data + ether_size, pseudo.length); + memmove(DATA(packet) + ether_size + ip6_size + icmp6_size, DATA(packet) + ether_size, pseudo.length); /* Fill in IPv6 header */ @@ -512,26 +507,36 @@ static void route_ipv6_unreachable(node_t *source, vpn_packet_t *packet, length_ checksum = inet_checksum(&pseudo, sizeof pseudo, ~0); checksum = inet_checksum(&icmp6, icmp6_size, checksum); - checksum = inet_checksum(packet->data + ether_size + ip6_size + icmp6_size, ntohl(pseudo.length) - icmp6_size, checksum); + checksum = inet_checksum(DATA(packet) + ether_size + ip6_size + icmp6_size, ntohl(pseudo.length) - icmp6_size, checksum); icmp6.icmp6_cksum = checksum; /* Copy structs on stack back to packet */ - memcpy(packet->data + ether_size, &ip6, ip6_size); - memcpy(packet->data + ether_size + ip6_size, &icmp6, icmp6_size); + memcpy(DATA(packet) + ether_size, &ip6, ip6_size); + memcpy(DATA(packet) + ether_size + ip6_size, &icmp6, icmp6_size); packet->len = ether_size + ip6_size + ntohl(pseudo.length); send_packet(source, packet); } -static void route_ipv6_unicast(node_t *source, vpn_packet_t *packet) { +static void route_neighborsol(node_t *source, vpn_packet_t *packet); + +static void route_ipv6(node_t *source, vpn_packet_t *packet) { + if(!checklength(source, packet, ether_size + ip6_size)) + return; + + if(DATA(packet)[20] == IPPROTO_ICMPV6 && checklength(source, packet, ether_size + ip6_size + icmp6_size) && DATA(packet)[54] == ND_NEIGHBOR_SOLICIT) { + route_neighborsol(source, packet); + return; + } + subnet_t *subnet; node_t *via; ipv6_t dest; - memcpy(&dest, &packet->data[38], sizeof dest); + memcpy(&dest, &DATA(packet)[38], sizeof dest); subnet = lookup_subnet_ipv6(&dest); if(!subnet) { @@ -550,6 +555,11 @@ static void route_ipv6_unicast(node_t *source, vpn_packet_t *packet) { return; } + if (!subnet->owner) { + broadcast_packet(source, packet); + return; + } + if(subnet->owner == source) { logger(DEBUG_TRAFFIC, LOG_WARNING, "Packet looping back to %s (%s)!", source->name, source->hostname); return; @@ -612,15 +622,15 @@ static void route_neighborsol(node_t *source, vpn_packet_t *packet) { /* Copy headers from packet to structs on the stack */ - memcpy(&ip6, packet->data + ether_size, ip6_size); - memcpy(&ns, packet->data + ether_size + ip6_size, ns_size); + memcpy(&ip6, DATA(packet) + ether_size, ip6_size); + memcpy(&ns, DATA(packet) + ether_size + ip6_size, ns_size); if(has_opt) - memcpy(&opt, packet->data + ether_size + ip6_size + ns_size, opt_size); + memcpy(&opt, DATA(packet) + ether_size + ip6_size + ns_size, opt_size); /* First, snatch the source address from the neighbor solicitation packet */ if(overwrite_mac) - memcpy(mymac.x, packet->data + ETH_ALEN, ETH_ALEN); + memcpy(mymac.x, DATA(packet) + ETH_ALEN, ETH_ALEN); /* Check if this is a valid neighbor solicitation request */ @@ -646,7 +656,7 @@ static void route_neighborsol(node_t *source, vpn_packet_t *packet) { checksum = inet_checksum(&ns, ns_size, checksum); if(has_opt) { checksum = inet_checksum(&opt, opt_size, checksum); - checksum = inet_checksum(packet->data + ether_size + ip6_size + ns_size + opt_size, ETH_ALEN, checksum); + checksum = inet_checksum(DATA(packet) + ether_size + ip6_size + ns_size + opt_size, ETH_ALEN, checksum); } if(checksum) { @@ -679,14 +689,14 @@ static void route_neighborsol(node_t *source, vpn_packet_t *packet) { /* Create neighbor advertation reply */ - memcpy(packet->data, packet->data + ETH_ALEN, ETH_ALEN); /* copy destination address */ - packet->data[ETH_ALEN * 2 - 1] ^= 0xFF; /* mangle source address so it looks like it's not from us */ + memcpy(DATA(packet), DATA(packet) + ETH_ALEN, ETH_ALEN); /* copy destination address */ + DATA(packet)[ETH_ALEN * 2 - 1] ^= 0xFF; /* mangle source address so it looks like it's not from us */ ip6.ip6_dst = ip6.ip6_src; /* swap destination and source protocoll address */ ip6.ip6_src = ns.nd_ns_target; if(has_opt) - memcpy(packet->data + ether_size + ip6_size + ns_size + opt_size, packet->data + ETH_ALEN, ETH_ALEN); /* add fake source hard addr */ + memcpy(DATA(packet) + ether_size + ip6_size + ns_size + opt_size, DATA(packet) + ETH_ALEN, ETH_ALEN); /* add fake source hard addr */ ns.nd_ns_cksum = 0; ns.nd_ns_type = ND_NEIGHBOR_ADVERT; @@ -709,36 +719,21 @@ static void route_neighborsol(node_t *source, vpn_packet_t *packet) { checksum = inet_checksum(&ns, ns_size, checksum); if(has_opt) { checksum = inet_checksum(&opt, opt_size, checksum); - checksum = inet_checksum(packet->data + ether_size + ip6_size + ns_size + opt_size, ETH_ALEN, checksum); + checksum = inet_checksum(DATA(packet) + ether_size + ip6_size + ns_size + opt_size, ETH_ALEN, checksum); } ns.nd_ns_hdr.icmp6_cksum = checksum; /* Copy structs on stack back to packet */ - memcpy(packet->data + ether_size, &ip6, ip6_size); - memcpy(packet->data + ether_size + ip6_size, &ns, ns_size); + memcpy(DATA(packet) + ether_size, &ip6, ip6_size); + memcpy(DATA(packet) + ether_size + ip6_size, &ns, ns_size); if(has_opt) - memcpy(packet->data + ether_size + ip6_size + ns_size, &opt, opt_size); + memcpy(DATA(packet) + ether_size + ip6_size + ns_size, &opt, opt_size); send_packet(source, packet); } -static void route_ipv6(node_t *source, vpn_packet_t *packet) { - if(!checklength(source, packet, ether_size + ip6_size)) - return; - - if(packet->data[20] == IPPROTO_ICMPV6 && checklength(source, packet, ether_size + ip6_size + icmp6_size) && packet->data[54] == ND_NEIGHBOR_SOLICIT) { - route_neighborsol(source, packet); - return; - } - - if(broadcast_mode && packet->data[38] == 255) - broadcast_packet(source, packet); - else - route_ipv6_unicast(source, packet); -} - /* RFC 826 */ static void route_arp(node_t *source, vpn_packet_t *packet) { @@ -757,11 +752,11 @@ static void route_arp(node_t *source, vpn_packet_t *packet) { /* First, snatch the source address from the ARP packet */ if(overwrite_mac) - memcpy(mymac.x, packet->data + ETH_ALEN, ETH_ALEN); + memcpy(mymac.x, DATA(packet) + ETH_ALEN, ETH_ALEN); /* Copy headers from packet to structs on the stack */ - memcpy(&arp, packet->data + ether_size, arp_size); + memcpy(&arp, DATA(packet) + ether_size, arp_size); /* Check if this is a valid ARP request */ @@ -787,20 +782,20 @@ static void route_arp(node_t *source, vpn_packet_t *packet) { if(subnet->owner == myself) return; /* silently ignore */ - memcpy(packet->data, packet->data + ETH_ALEN, ETH_ALEN); /* copy destination address */ - packet->data[ETH_ALEN * 2 - 1] ^= 0xFF; /* mangle source address so it looks like it's not from us */ + memcpy(DATA(packet), DATA(packet) + ETH_ALEN, ETH_ALEN); /* copy destination address */ + DATA(packet)[ETH_ALEN * 2 - 1] ^= 0xFF; /* mangle source address so it looks like it's not from us */ memcpy(&addr, arp.arp_tpa, sizeof addr); /* save protocol addr */ memcpy(arp.arp_tpa, arp.arp_spa, sizeof addr); /* swap destination and source protocol address */ memcpy(arp.arp_spa, &addr, sizeof addr); /* ... */ memcpy(arp.arp_tha, arp.arp_sha, ETH_ALEN); /* set target hard/proto addr */ - memcpy(arp.arp_sha, packet->data + ETH_ALEN, ETH_ALEN); /* add fake source hard addr */ + memcpy(arp.arp_sha, DATA(packet) + ETH_ALEN, ETH_ALEN); /* add fake source hard addr */ arp.arp_op = htons(ARPOP_REPLY); /* Copy structs on stack back to packet */ - memcpy(packet->data + ether_size, &arp, arp_size); + memcpy(DATA(packet) + ether_size, &arp, arp_size); send_packet(source, packet); } @@ -813,16 +808,16 @@ static void route_mac(node_t *source, vpn_packet_t *packet) { if(source == myself) { mac_t src; - memcpy(&src, &packet->data[6], sizeof src); + memcpy(&src, &DATA(packet)[6], sizeof src); learn_mac(&src); } /* Lookup destination address */ - memcpy(&dest, &packet->data[0], sizeof dest); + memcpy(&dest, &DATA(packet)[0], sizeof dest); subnet = lookup_subnet_mac(NULL, &dest); - if(!subnet) { + if(!subnet || !subnet->owner) { broadcast_packet(source, packet); return; } @@ -835,10 +830,10 @@ static void route_mac(node_t *source, vpn_packet_t *packet) { if(forwarding_mode == FMODE_OFF && source != myself && subnet->owner != myself) return; - uint16_t type = packet->data[12] << 8 | packet->data[13]; + uint16_t type = DATA(packet)[12] << 8 | DATA(packet)[13]; if(priorityinheritance && type == ETH_P_IP && packet->len >= ether_size + ip_size) - packet->priority = packet->data[15]; + packet->priority = DATA(packet)[15]; // Handle packets larger than PMTU @@ -852,12 +847,12 @@ static void route_mac(node_t *source, vpn_packet_t *packet) { length_t ethlen = 14; if(type == ETH_P_8021Q) { - type = packet->data[16] << 8 | packet->data[17]; + type = DATA(packet)[16] << 8 | DATA(packet)[17]; ethlen += 4; } if(type == ETH_P_IP && packet->len > 576 + ethlen) { - if(packet->data[6 + ethlen] & 0x40) { + if(DATA(packet)[6 + ethlen] & 0x40) { packet->len = via->mtu; route_ipv4_unreachable(source, packet, ethlen, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED); } else { @@ -889,16 +884,16 @@ static void send_pcap(vpn_packet_t *packet) { len = c->outmaclength; if(send_request(c, "%d %d %d", CONTROL, REQ_PCAP, len)) - send_meta(c, (char *)packet->data, len); + send_meta(c, (char *)DATA(packet), len); } } static bool do_decrement_ttl(node_t *source, vpn_packet_t *packet) { - uint16_t type = packet->data[12] << 8 | packet->data[13]; + uint16_t type = DATA(packet)[12] << 8 | DATA(packet)[13]; length_t ethlen = ether_size; if(type == ETH_P_8021Q) { - type = packet->data[16] << 8 | packet->data[17]; + type = DATA(packet)[16] << 8 | DATA(packet)[17]; ethlen += 4; } @@ -907,22 +902,22 @@ static bool do_decrement_ttl(node_t *source, vpn_packet_t *packet) { if(!checklength(source, packet, ethlen + ip_size)) return false; - if(packet->data[ethlen + 8] < 1) { - if(packet->data[ethlen + 11] != IPPROTO_ICMP || packet->data[ethlen + 32] != ICMP_TIME_EXCEEDED) + if(DATA(packet)[ethlen + 8] < 1) { + if(DATA(packet)[ethlen + 11] != IPPROTO_ICMP || DATA(packet)[ethlen + 32] != ICMP_TIME_EXCEEDED) route_ipv4_unreachable(source, packet, ethlen, ICMP_TIME_EXCEEDED, ICMP_EXC_TTL); return false; } - uint16_t old = packet->data[ethlen + 8] << 8 | packet->data[ethlen + 9]; - packet->data[ethlen + 8]--; - uint16_t new = packet->data[ethlen + 8] << 8 | packet->data[ethlen + 9]; + uint16_t old = DATA(packet)[ethlen + 8] << 8 | DATA(packet)[ethlen + 9]; + DATA(packet)[ethlen + 8]--; + uint16_t new = DATA(packet)[ethlen + 8] << 8 | DATA(packet)[ethlen + 9]; - uint32_t checksum = packet->data[ethlen + 10] << 8 | packet->data[ethlen + 11]; + uint32_t checksum = DATA(packet)[ethlen + 10] << 8 | DATA(packet)[ethlen + 11]; checksum += old + (~new & 0xFFFF); while(checksum >> 16) checksum = (checksum & 0xFFFF) + (checksum >> 16); - packet->data[ethlen + 10] = checksum >> 8; - packet->data[ethlen + 11] = checksum & 0xff; + DATA(packet)[ethlen + 10] = checksum >> 8; + DATA(packet)[ethlen + 11] = checksum & 0xff; return true; @@ -930,13 +925,13 @@ static bool do_decrement_ttl(node_t *source, vpn_packet_t *packet) { if(!checklength(source, packet, ethlen + ip6_size)) return false; - if(packet->data[ethlen + 7] < 1) { - if(packet->data[ethlen + 6] != IPPROTO_ICMPV6 || packet->data[ethlen + 40] != ICMP6_TIME_EXCEEDED) + if(DATA(packet)[ethlen + 7] < 1) { + if(DATA(packet)[ethlen + 6] != IPPROTO_ICMPV6 || DATA(packet)[ethlen + 40] != ICMP6_TIME_EXCEEDED) route_ipv6_unreachable(source, packet, ethlen, ICMP6_TIME_EXCEEDED, ICMP6_TIME_EXCEED_TRANSIT); return false; } - packet->data[ethlen + 7]--; + DATA(packet)[ethlen + 7]--; return true; @@ -961,7 +956,7 @@ void route(node_t *source, vpn_packet_t *packet) { if(!do_decrement_ttl(source, packet)) return; - uint16_t type = packet->data[12] << 8 | packet->data[13]; + uint16_t type = DATA(packet)[12] << 8 | DATA(packet)[13]; switch (routing_mode) { case RMODE_ROUTER: diff --git a/src/script.c b/src/script.c index 9a43d53..6389cb4 100644 --- a/src/script.c +++ b/src/script.c @@ -49,7 +49,7 @@ bool execute_script(const char *name, char **envp) { if(q) { memcpy(ext, p, q - p); ext[q - p] = 0; - *q++; + q++; } else { strcpy(ext, p); } diff --git a/src/solaris/device.c b/src/solaris/device.c index 21ce73f..fadae57 100644 --- a/src/solaris/device.c +++ b/src/solaris/device.c @@ -1,7 +1,8 @@ /* device.c -- Interaction with Solaris tun device Copyright (C) 2001-2005 Ivo Timmermans, - 2001-2013 Guus Sliepen + 2002-2010 OpenVPN Technologies, Inc. + 2001-2014 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 @@ -23,171 +24,350 @@ #include #include -#include #include "../conf.h" #include "../device.h" #include "../logger.h" #include "../names.h" #include "../net.h" +#include "../route.h" #include "../utils.h" #include "../xalloc.h" -#define DEFAULT_DEVICE "/dev/tun" +#ifndef TUNNEWPPA +#warning Missing net/if_tun.h, using hardcoded value for TUNNEWPPA +#define TUNNEWPPA (('T'<<16) | 0x0001) +#endif + +#define DEFAULT_TUN_DEVICE "/dev/tun" +#define DEFAULT_TAP_DEVICE "/dev/tap" + +static enum { + DEVICE_TYPE_TUN, + DEVICE_TYPE_TAP, +} device_type = DEVICE_TYPE_TUN; int device_fd = -1; -static int ip_fd = -1, if_fd = -1; +static int ip_fd = -1; char *device = NULL; char *iface = NULL; static char *device_info = NULL; -static uint64_t device_total_in = 0; -static uint64_t device_total_out = 0; - static bool setup_device(void) { - int ppa; - char *ptr; + char *type; - if(!get_config_string(lookup_config(config_tree, "Device"), &device)) - device = xstrdup(DEFAULT_DEVICE); + if(!get_config_string(lookup_config(config_tree, "Device"), &device)) { + if(routing_mode == RMODE_ROUTER) + device = xstrdup(DEFAULT_TUN_DEVICE); + else + device = xstrdup(DEFAULT_TAP_DEVICE); + } - if((device_fd = open(device, O_RDWR | O_NONBLOCK)) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not open %s: %s", device, strerror(errno)); + if(get_config_string(lookup_config(config_tree, "DeviceType"), &type)) { + if(!strcasecmp(type, "tun")) + /* use default */; + else if(!strcasecmp(type, "tap")) + device_type = DEVICE_TYPE_TAP; + else { + logger(DEBUG_ALWAYS, LOG_ERR, "Unknown device type %s!", type); + return false; + } + } else { + if(strstr(device, "tap") || routing_mode != RMODE_ROUTER) + device_type = DEVICE_TYPE_TAP; + } + + if(device_type == DEVICE_TYPE_TUN) + device_info = "Solaris tun device"; + else + device_info = "Solaris tap device"; + + /* The following is black magic copied from OpenVPN. */ + + if((ip_fd = open("/dev/ip", O_RDWR, 0)) < 0) { + logger(DEBUG_ALWAYS, LOG_ERR, "Could not open %s: %s\n", "/dev/ip", strerror(errno)); return false; } + if((device_fd = open(device, O_RDWR, 0)) < 0) { + logger(DEBUG_ALWAYS, LOG_ERR, "Could not open %s: %s\n", device, strerror(errno)); + return false; + } + + /* Get unit number. */ + + char *ptr = device; + get_config_string(lookup_config(config_tree, "Interface"), &ptr); + + while(*ptr && !isdigit(*ptr)) + ptr++; + int ppa = atoi(ptr); + + /* Assign a new PPA and get its unit number. */ + + struct strioctl strioc_ppa = { + .ic_cmd = TUNNEWPPA, + .ic_len = sizeof ppa, + .ic_dp = (char *)&ppa, + }; + + if(!*ptr) { /* no number given, try dynamic */ + bool found = false; + while(!found && ppa < 64) { + int new_ppa = ioctl(device_fd, I_STR, &strioc_ppa); + if(new_ppa >= 0) { + ppa = new_ppa; + found = true; + break; + } + ppa++; + } + if(!found) { + logger(DEBUG_ALWAYS, LOG_ERR, "Could not find free PPA for %s %s!", device_info, device); + return false; + } + } else { /* try this particular one */ + if((ppa = ioctl(device_fd, I_STR, &strioc_ppa)) < 0) { + logger(DEBUG_ALWAYS, LOG_ERR, "Could not assign PPA %d for %s %s!", ppa, device_info, device); + return false; + } + } + + int if_fd; + if((if_fd = open(device, O_RDWR, 0)) < 0) { + logger(DEBUG_ALWAYS, LOG_ERR, "Could not open %s: %s\n", device, strerror(errno)); + return false; + } + + if(ioctl(if_fd, I_PUSH, "ip") < 0) { + logger(DEBUG_ALWAYS, LOG_ERR, "Could not push IP module onto %s %s!", device_info, device); + return false; + } + + xasprintf(&iface, "%s%d", device_type == DEVICE_TYPE_TUN ? "tun" : "tap", ppa); + + { + /* Remove muxes just in case they are left over from a crashed tincd */ + struct lifreq ifr = {}; + strncpy(ifr.lifr_name, iface, sizeof ifr.lifr_name); + if(ioctl(ip_fd, SIOCGLIFMUXID, &ifr) >= 0) { + int muxid = ifr.lifr_arp_muxid; + ioctl(ip_fd, I_PUNLINK, muxid); + muxid = ifr.lifr_ip_muxid; + ioctl(ip_fd, I_PUNLINK, muxid); + } + } + + if(device_type == DEVICE_TYPE_TUN) { + /* Assign ppa according to the unit number returned by tun device */ + if(ioctl(if_fd, IF_UNITSEL, (char *)&ppa) < 0) { + logger(DEBUG_ALWAYS, LOG_ERR, "Could not set PPA %d on %s %s!", ppa, device_info, device); + return false; + } + } + + int arp_fd = -1; + + if(device_type == DEVICE_TYPE_TAP) { + struct lifreq ifr = {}; + + if(ioctl(if_fd, SIOCGLIFFLAGS, &ifr) < 0) { + logger(DEBUG_ALWAYS, LOG_ERR, "Could not set flags on %s %s!", device_info, device); + return false; + } + + strncpy(ifr.lifr_name, iface, sizeof(ifr.lifr_name)); + ifr.lifr_ppa = ppa; + + /* Assign ppa according to the unit number returned by tun device */ + if(ioctl(if_fd, SIOCSLIFNAME, &ifr) < 0) { + logger(DEBUG_ALWAYS, LOG_ERR, "Could not set PPA %d on %s %s!", ppa, device_info, device); + return false; + } + if(ioctl(if_fd, SIOCGLIFFLAGS, &ifr) < 0) { + logger(DEBUG_ALWAYS, LOG_ERR, "Could not set flags on %s %s!", device_info, device); + return false; + } + + /* Push arp module to if_fd */ + if(ioctl(if_fd, I_PUSH, "arp") < 0) { + logger(DEBUG_ALWAYS, LOG_ERR, "Could not push ARP module onto %s %s!", device_info, device); + return false; + } + + /* Pop any modules on the stream */ + while(true) { + if(ioctl(ip_fd, I_POP, NULL) < 0) + break; + } + + /* Push arp module to ip_fd */ + if(ioctl(ip_fd, I_PUSH, "arp") < 0) { + logger(DEBUG_ALWAYS, LOG_ERR, "Could not push ARP module onto %s!", "/dev/ip"); + return false; + } + + /* Open arp_fd */ + if((arp_fd = open(device, O_RDWR, 0)) < 0) { + logger(DEBUG_ALWAYS, LOG_ERR, "Could not open %s: %s\n", device, strerror(errno)); + return false; + } + + /* Push arp module to arp_fd */ + if(ioctl(arp_fd, I_PUSH, "arp") < 0) { + logger(DEBUG_ALWAYS, LOG_ERR, "Could not push ARP module onto %s %s!", device_info, device); + return false; + } + + /* Set ifname to arp */ + struct strioctl strioc_if = { + .ic_cmd = SIOCSLIFNAME, + .ic_len = sizeof ifr, + .ic_dp = (char *)&ifr, + }; + + if(ioctl(arp_fd, I_STR, &strioc_if) < 0) { + logger(DEBUG_ALWAYS, LOG_ERR, "Could not set ifname to %s %s", device_info, device); + return false; + } + } + + int ip_muxid, arp_muxid; + + if((ip_muxid = ioctl(ip_fd, I_PLINK, if_fd)) < 0) { + logger(DEBUG_ALWAYS, LOG_ERR, "Could not link %s %s to IP", device_info, device); + return false; + } + + if(device_type == DEVICE_TYPE_TAP) { + if((arp_muxid = ioctl(ip_fd, I_PLINK, arp_fd)) < 0) { + logger(DEBUG_ALWAYS, LOG_ERR, "Could not link %s %s to ARP", device_info, device); + return false; + } + close(arp_fd); + } + + struct lifreq ifr = {}; + strncpy(ifr.lifr_name, iface, sizeof(ifr.lifr_name)); + ifr.lifr_ip_muxid = ip_muxid; + if(device_type == DEVICE_TYPE_TAP) { + ifr.lifr_arp_muxid = arp_muxid; + } + + if(ioctl(ip_fd, SIOCSLIFMUXID, &ifr) < 0) { + if(device_type == DEVICE_TYPE_TAP) { + ioctl(ip_fd, I_PUNLINK, arp_muxid); + } + ioctl(ip_fd, I_PUNLINK, ip_muxid); + logger(DEBUG_ALWAYS, LOG_ERR, "Could not set multiplexor id for %s %s", device_info, device); + return false; + } + + close(if_fd); + #ifdef FD_CLOEXEC fcntl(device_fd, F_SETFD, FD_CLOEXEC); -#endif - - ppa = 0; - - ptr = device; - while(*ptr && !isdigit((int) *ptr)) - ptr++; - ppa = atoi(ptr); - - if((ip_fd = open("/dev/ip", O_RDWR, 0)) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not open /dev/ip: %s", strerror(errno)); - return false; - } - -#ifdef FD_CLOEXEC fcntl(ip_fd, F_SETFD, FD_CLOEXEC); #endif - /* Assign a new PPA and get its unit number. */ - if((ppa = ioctl(device_fd, TUNNEWPPA, ppa)) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Can't assign new interface: %s", strerror(errno)); - return false; - } - - if((if_fd = open(device, O_RDWR, 0)) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not open %s twice: %s", device, - strerror(errno)); - return false; - } - -#ifdef FD_CLOEXEC - fcntl(if_fd, F_SETFD, FD_CLOEXEC); -#endif - - if(ioctl(if_fd, I_PUSH, "ip") < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Can't push IP module: %s", strerror(errno)); - return false; - } - - /* Assign ppa according to the unit number returned by tun device */ - if(ioctl(if_fd, IF_UNITSEL, (char *) &ppa) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Can't set PPA %d: %s", ppa, strerror(errno)); - return false; - } - - if(ioctl(ip_fd, I_LINK, if_fd) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Can't link TUN device to IP: %s", strerror(errno)); - return false; - } - - if(!get_config_string(lookup_config(config_tree, "Interface"), &iface)) - xasprintf(&iface, "tun%d", ppa); - - device_info = "Solaris tun device"; - logger(DEBUG_ALWAYS, LOG_INFO, "%s is a %s", device, device_info); return true; } static void close_device(void) { - close(if_fd); - close(ip_fd); - close(device_fd); + if(iface) { + struct lifreq ifr = {}; + strncpy(ifr.lifr_name, iface, sizeof ifr.lifr_name); + if(ioctl(ip_fd, SIOCGLIFMUXID, &ifr) >= 0) { + int muxid = ifr.lifr_arp_muxid; + ioctl(ip_fd, I_PUNLINK, muxid); + muxid = ifr.lifr_ip_muxid; + ioctl(ip_fd, I_PUNLINK, muxid); + } + } - free(device); - free(iface); + close(ip_fd); ip_fd = -1; + close(device_fd); device_fd = -1; + + free(device); device = NULL; + free(iface); iface = NULL; } static bool read_packet(vpn_packet_t *packet) { int inlen; - if((inlen = read(device_fd, packet->data + 14, MTU - 14)) <= 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info, - device, strerror(errno)); - return false; - } + switch(device_type) { + case DEVICE_TYPE_TUN: + if((inlen = read(device_fd, DATA(packet) + 14, MTU - 14)) <= 0) { + logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info, device, strerror(errno)); + return false; + } - switch(packet->data[14] >> 4) { - case 4: - packet->data[12] = 0x08; - packet->data[13] = 0x00; + switch(DATA(packet)[14] >> 4) { + case 4: + DATA(packet)[12] = 0x08; + DATA(packet)[13] = 0x00; + break; + case 6: + DATA(packet)[12] = 0x86; + DATA(packet)[13] = 0xDD; + break; + default: + logger(DEBUG_TRAFFIC, LOG_ERR, "Unknown IP version %d while reading packet from %s %s", DATA(packet)[14] >> 4, device_info, device); + return false; + } + + memset(DATA(packet), 0, 12); + packet->len = inlen + 14; break; - case 6: - packet->data[12] = 0x86; - packet->data[13] = 0xDD; + + case DEVICE_TYPE_TAP: + if((inlen = read(device_fd, DATA(packet), MTU)) <= 0) { + logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info, device, strerror(errno)); + return false; + } + + packet->len = inlen + 14; break; + default: - logger(DEBUG_TRAFFIC, LOG_ERR, - "Unknown IP version %d while reading packet from %s %s", - packet->data[14] >> 4, device_info, device); - return false; + abort(); } - memset(packet->data, 0, 12); - packet->len = inlen + 14; - - device_total_in += packet->len; - - logger(DEBUG_TRAFFIC, LOG_DEBUG, "Read packet of %d bytes from %s", packet->len, - device_info); + logger(DEBUG_TRAFFIC, LOG_DEBUG, "Read packet of %d bytes from %s", packet->len, device_info); return true; } static bool write_packet(vpn_packet_t *packet) { - logger(DEBUG_TRAFFIC, LOG_DEBUG, "Writing packet of %d bytes to %s", - packet->len, device_info); + logger(DEBUG_TRAFFIC, LOG_DEBUG, "Writing packet of %d bytes to %s", packet->len, device_info); - if(write(device_fd, packet->data + 14, packet->len - 14) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Can't write to %s %s: %s", device_info, - device, strerror(errno)); - return false; + switch(device_type) { + case DEVICE_TYPE_TUN: + if(write(device_fd, DATA(packet) + 14, packet->len - 14) < 0) { + logger(DEBUG_ALWAYS, LOG_ERR, "Can't write to %s %s: %s", device_info, device, strerror(errno)); + return false; + } + break; + + case DEVICE_TYPE_TAP: + if(write(device_fd, DATA(packet), packet->len) < 0) { + logger(DEBUG_ALWAYS, LOG_ERR, "Can't write to %s %s: %s", device_info, device, strerror(errno)); + return false; + } + break; + + default: + abort(); } - device_total_out += packet->len; - return true; } -static void dump_device_stats(void) { - logger(DEBUG_ALWAYS, LOG_DEBUG, "Statistics for %s %s:", device_info, device); - logger(DEBUG_ALWAYS, LOG_DEBUG, " total bytes in: %10"PRIu64, device_total_in); - logger(DEBUG_ALWAYS, LOG_DEBUG, " total bytes out: %10"PRIu64, device_total_out); -} - const devops_t os_devops = { .setup = setup_device, .close = close_device, .read = read_packet, .write = write_packet, - .dump_stats = dump_device_stats, }; diff --git a/src/sptps.c b/src/sptps.c index 62cfb1f..a598768 100644 --- a/src/sptps.c +++ b/src/sptps.c @@ -1,6 +1,6 @@ /* sptps.c -- Simple Peer-to-Peer Security - Copyright (C) 2011-2013 Guus Sliepen , + Copyright (C) 2011-2014 Guus Sliepen , 2010 Brandon L. Black This program is free software; you can redistribute it and/or modify @@ -20,9 +20,8 @@ #include "system.h" -#include "cipher.h" +#include "chacha-poly1305/chacha-poly1305.h" #include "crypto.h" -#include "digest.h" #include "ecdh.h" #include "ecdsa.h" #include "logger.h" @@ -40,7 +39,7 @@ unsigned int sptps_replaywin = 16; Sign all handshake messages up to ECDHE kex with long-term public keys. (done) - HMACed KEX finished message to prevent downgrade attacks and prove you have the right key material (done by virtue of ECDSA over the whole ECDHE exchange?) + HMACed KEX finished message to prevent downgrade attacks and prove you have the right key material (done by virtue of Ed25519 over the whole ECDHE exchange?) Explicit close message needs to be added. @@ -82,72 +81,53 @@ static void warning(sptps_t *s, const char *format, ...) { } // Send a record (datagram version, accepts all record types, handles encryption and authentication). -static bool send_record_priv_datagram(sptps_t *s, uint8_t type, const char *data, uint16_t len) { - char buffer[len + 23UL]; +static bool send_record_priv_datagram(sptps_t *s, uint8_t type, const void *data, uint16_t len) { + char buffer[len + 21UL]; // Create header with sequence number, length and record type - uint32_t seqno = htonl(s->outseqno++); - uint16_t netlen = htons(len); + uint32_t seqno = s->outseqno++; + uint32_t netseqno = ntohl(seqno); - memcpy(buffer, &netlen, 2); - memcpy(buffer + 2, &seqno, 4); - buffer[6] = type; - - // Add plaintext (TODO: avoid unnecessary copy) - memcpy(buffer + 7, data, len); + memcpy(buffer, &netseqno, 4); + buffer[4] = type; + memcpy(buffer + 5, data, len); if(s->outstate) { // If first handshake has finished, encrypt and HMAC - if(!cipher_set_counter(s->outcipher, &seqno, sizeof seqno)) - return false; - - if(!cipher_counter_xor(s->outcipher, buffer + 6, len + 1UL, buffer + 6)) - return false; - - if(!digest_create(s->outdigest, buffer, len + 7UL, buffer + 7UL + len)) - return false; - - return s->send_data(s->handle, type, buffer + 2, len + 21UL); + chacha_poly1305_encrypt(s->outcipher, seqno, buffer + 4, len + 1, buffer + 4, NULL); + return s->send_data(s->handle, type, buffer, len + 21UL); } else { // Otherwise send as plaintext - return s->send_data(s->handle, type, buffer + 2, len + 5UL); + return s->send_data(s->handle, type, buffer, len + 5UL); } } // Send a record (private version, accepts all record types, handles encryption and authentication). -static bool send_record_priv(sptps_t *s, uint8_t type, const char *data, uint16_t len) { +static bool send_record_priv(sptps_t *s, uint8_t type, const void *data, uint16_t len) { if(s->datagram) return send_record_priv_datagram(s, type, data, len); - char buffer[len + 23UL]; + char buffer[len + 19UL]; // Create header with sequence number, length and record type - uint32_t seqno = htonl(s->outseqno++); + uint32_t seqno = s->outseqno++; uint16_t netlen = htons(len); - memcpy(buffer, &seqno, 4); - memcpy(buffer + 4, &netlen, 2); - buffer[6] = type; - - // Add plaintext (TODO: avoid unnecessary copy) - memcpy(buffer + 7, data, len); + memcpy(buffer, &netlen, 2); + buffer[2] = type; + memcpy(buffer + 3, data, len); if(s->outstate) { // If first handshake has finished, encrypt and HMAC - if(!cipher_counter_xor(s->outcipher, buffer + 4, len + 3UL, buffer + 4)) - return false; - - if(!digest_create(s->outdigest, buffer, len + 7UL, buffer + 7UL + len)) - return false; - - return s->send_data(s->handle, type, buffer + 4, len + 19UL); + chacha_poly1305_encrypt(s->outcipher, seqno, buffer + 2, len + 1, buffer + 2, NULL); + return s->send_data(s->handle, type, buffer, len + 19UL); } else { // Otherwise send as plaintext - return s->send_data(s->handle, type, buffer + 4, len + 3UL); + return s->send_data(s->handle, type, buffer, len + 3UL); } } // Send an application record. -bool sptps_send_record(sptps_t *s, uint8_t type, const char *data, uint16_t len) { +bool sptps_send_record(sptps_t *s, uint8_t type, const void *data, uint16_t len) { // Sanity checks: application cannot send data before handshake is finished, // and only record types 0..127 are allowed. if(!s->outstate) @@ -165,7 +145,7 @@ static bool send_kex(sptps_t *s) { // Make room for our KEX message, which we will keep around since send_sig() needs it. if(s->mykex) - abort(); + return false; s->mykex = realloc(s->mykex, 1 + 32 + keylen); if(!s->mykex) return error(s, errno, strerror(errno)); @@ -178,12 +158,12 @@ static bool send_kex(sptps_t *s) { // Create a new ECDH public key. if(!(s->ecdh = ecdh_generate_public(s->mykex + 1 + 32))) - return false; + return error(s, EINVAL, "Failed to generate ECDH public key"); return send_record_priv(s, SPTPS_HANDSHAKE, s->mykex, 1 + 32 + keylen); } -// Send a SIGnature record, containing an ECDSA signature over both KEX records. +// Send a SIGnature record, containing an Ed25519 signature over both KEX records. static bool send_sig(sptps_t *s) { size_t keylen = ECDH_SIZE; size_t siglen = ecdsa_size(s->mykey); @@ -199,7 +179,7 @@ static bool send_sig(sptps_t *s) { // Sign the result. if(!ecdsa_sign(s->mykey, msg, sizeof msg, sig)) - return false; + return error(s, EINVAL, "Failed to sign SIG record"); // Send the SIG exchange record. return send_record_priv(s, SPTPS_HANDSHAKE, sig, sizeof sig); @@ -209,16 +189,14 @@ static bool send_sig(sptps_t *s) { static bool generate_key_material(sptps_t *s, const char *shared, size_t len) { // Initialise cipher and digest structures if necessary if(!s->outstate) { - s->incipher = cipher_open_by_name("aes-256-ecb"); - s->outcipher = cipher_open_by_name("aes-256-ecb"); - s->indigest = digest_open_by_name("sha256", 16); - s->outdigest = digest_open_by_name("sha256", 16); - if(!s->incipher || !s->outcipher || !s->indigest || !s->outdigest) - return false; + s->incipher = chacha_poly1305_init(); + s->outcipher = chacha_poly1305_init(); + if(!s->incipher || !s->outcipher) + return error(s, EINVAL, "Failed to open cipher"); } // Allocate memory for key material - size_t keylen = digest_keylength(s->indigest) + digest_keylength(s->outdigest) + cipher_keylength(s->incipher) + cipher_keylength(s->outcipher); + size_t keylen = 2 * CHACHA_POLY1305_KEYLEN; s->key = realloc(s->key, keylen); if(!s->key) @@ -238,7 +216,7 @@ static bool generate_key_material(sptps_t *s, const char *shared, size_t len) { // Use PRF to generate the key material if(!prf(shared, len, seed, s->labellen + 64 + 13, s->key, keylen)) - return false; + return error(s, EINVAL, "Failed to generate key material"); return true; } @@ -254,17 +232,11 @@ static bool receive_ack(sptps_t *s, const char *data, uint16_t len) { return error(s, EIO, "Invalid ACK record length"); if(s->initiator) { - bool result - = cipher_set_counter_key(s->incipher, s->key) - && digest_set_key(s->indigest, s->key + cipher_keylength(s->incipher), digest_keylength(s->indigest)); - if(!result) - return false; + if(!chacha_poly1305_set_key(s->incipher, s->key)) + return error(s, EINVAL, "Failed to set counter"); } else { - bool result - = cipher_set_counter_key(s->incipher, s->key + cipher_keylength(s->outcipher) + digest_keylength(s->outdigest)) - && digest_set_key(s->indigest, s->key + cipher_keylength(s->outcipher) + digest_keylength(s->outdigest) + cipher_keylength(s->incipher), digest_keylength(s->indigest)); - if(!result) - return false; + if(!chacha_poly1305_set_key(s->incipher, s->key + CHACHA_POLY1305_KEYLEN)) + return error(s, EINVAL, "Failed to set counter"); } free(s->key); @@ -284,7 +256,7 @@ static bool receive_kex(sptps_t *s, const char *data, uint16_t len) { // Make a copy of the KEX message, send_sig() and receive_sig() need it if(s->hiskex) - abort(); + return error(s, EINVAL, "Received a second KEX message before first has been processed"); s->hiskex = realloc(s->hiskex, len); if(!s->hiskex) return error(s, errno, strerror(errno)); @@ -313,12 +285,12 @@ static bool receive_sig(sptps_t *s, const char *data, uint16_t len) { // Verify signature. if(!ecdsa_verify(s->hiskey, msg, sizeof msg, data)) - return false; + return error(s, EIO, "Failed to verify SIG record"); // Compute shared secret. char shared[ECDH_SHARED_SIZE]; if(!ecdh_compute_shared(s->ecdh, s->hiskex + 1 + 32, shared)) - return false; + return error(s, EINVAL, "Failed to compute ECDH shared secret"); s->ecdh = NULL; // Generate key material from shared secret. @@ -337,17 +309,11 @@ static bool receive_sig(sptps_t *s, const char *data, uint16_t len) { // TODO: only set new keys after ACK has been set/received if(s->initiator) { - bool result - = cipher_set_counter_key(s->outcipher, s->key + cipher_keylength(s->incipher) + digest_keylength(s->indigest)) - && digest_set_key(s->outdigest, s->key + cipher_keylength(s->incipher) + digest_keylength(s->indigest) + cipher_keylength(s->outcipher), digest_keylength(s->outdigest)); - if(!result) - return false; + if(!chacha_poly1305_set_key(s->outcipher, s->key + CHACHA_POLY1305_KEYLEN)) + return error(s, EINVAL, "Failed to set key"); } else { - bool result - = cipher_set_counter_key(s->outcipher, s->key) - && digest_set_key(s->outdigest, s->key + cipher_keylength(s->outcipher), digest_keylength(s->outdigest)); - if(!result) - return false; + if(!chacha_poly1305_set_key(s->outcipher, s->key)) + return error(s, EINVAL, "Failed to set key"); } return true; @@ -404,18 +370,73 @@ static bool receive_handshake(sptps_t *s, const char *data, uint16_t len) { } } +static bool sptps_check_seqno(sptps_t *s, uint32_t seqno, bool update_state) { + // Replay protection using a sliding window of configurable size. + // s->inseqno is expected sequence number + // seqno is received sequence number + // s->late[] is a circular buffer, a 1 bit means a packet has not been received yet + // The circular buffer contains bits for sequence numbers from s->inseqno - s->replaywin * 8 to (but excluding) s->inseqno. + if(s->replaywin) { + if(seqno != s->inseqno) { + if(seqno >= s->inseqno + s->replaywin * 8) { + // Prevent packets that jump far ahead of the queue from causing many others to be dropped. + bool farfuture = s->farfuture < s->replaywin >> 2; + if (update_state) + s->farfuture++; + if(farfuture) + return error(s, EIO, "Packet is %d seqs in the future, dropped (%u)\n", seqno - s->inseqno, s->farfuture); + + // Unless we have seen lots of them, in which case we consider the others lost. + warning(s, "Lost %d packets\n", seqno - s->inseqno); + if (update_state) { + // Mark all packets in the replay window as being late. + memset(s->late, 255, s->replaywin); + } + } else if (seqno < s->inseqno) { + // If the sequence number is farther in the past than the bitmap goes, or if the packet was already received, drop it. + if((s->inseqno >= s->replaywin * 8 && seqno < s->inseqno - s->replaywin * 8) || !(s->late[(seqno / 8) % s->replaywin] & (1 << seqno % 8))) + return error(s, EIO, "Received late or replayed packet, seqno %d, last received %d\n", seqno, s->inseqno); + } else if (update_state) { + // We missed some packets. Mark them in the bitmap as being late. + for(int i = s->inseqno; i < seqno; i++) + s->late[(i / 8) % s->replaywin] |= 1 << i % 8; + } + } + + if (update_state) { + // Mark the current packet as not being late. + s->late[(seqno / 8) % s->replaywin] &= ~(1 << seqno % 8); + s->farfuture = 0; + } + } + + if (update_state) { + if(seqno >= s->inseqno) + s->inseqno = seqno + 1; + + if(!s->inseqno) + s->received = 0; + else + s->received++; + } + + return true; +} + // Check datagram for valid HMAC -bool sptps_verify_datagram(sptps_t *s, const char *data, size_t len) { +bool sptps_verify_datagram(sptps_t *s, const void *data, size_t len) { if(!s->instate || len < 21) + return error(s, EIO, "Received short packet"); + + uint32_t seqno; + memcpy(&seqno, data, 4); + seqno = ntohl(seqno); + if (!sptps_check_seqno(s, seqno, false)) return false; - char buffer[len + 23]; - uint16_t netlen = htons(len - 21); - - memcpy(buffer, &netlen, 2); - memcpy(buffer + 2, data, len); - - return digest_verify(s->indigest, buffer, len - 14, buffer + len - 14); + char buffer[len]; + size_t outlen; + return chacha_poly1305_decrypt(s->incipher, seqno, data + 4, len - 4, buffer, &outlen); } // Receive incoming data, datagram version. @@ -441,77 +462,31 @@ static bool sptps_receive_data_datagram(sptps_t *s, const char *data, size_t len return receive_handshake(s, data + 5, len - 5); } - // Check HMAC. - uint16_t netlen = htons(len - 21); + // Decrypt - char buffer[len + 23]; + char buffer[len]; - memcpy(buffer, &netlen, 2); - memcpy(buffer + 2, data, len); + size_t outlen; - if(!digest_verify(s->indigest, buffer, len - 14, buffer + len - 14)) - return error(s, EIO, "Invalid HMAC"); + if(!chacha_poly1305_decrypt(s->incipher, seqno, data + 4, len - 4, buffer, &outlen)) + return error(s, EIO, "Failed to decrypt and verify packet"); - // Replay protection using a sliding window of configurable size. - // s->inseqno is expected sequence number - // seqno is received sequence number - // s->late[] is a circular buffer, a 1 bit means a packet has not been received yet - // The circular buffer contains bits for sequence numbers from s->inseqno - s->replaywin * 8 to (but excluding) s->inseqno. - if(s->replaywin) { - if(seqno != s->inseqno) { - if(seqno >= s->inseqno + s->replaywin * 8) { - // Prevent packets that jump far ahead of the queue from causing many others to be dropped. - if(s->farfuture++ < s->replaywin >> 2) - return error(s, EIO, "Packet is %d seqs in the future, dropped (%u)\n", seqno - s->inseqno, s->farfuture); - - // Unless we have seen lots of them, in which case we consider the others lost. - warning(s, "Lost %d packets\n", seqno - s->inseqno); - // Mark all packets in the replay window as being late. - memset(s->late, 255, s->replaywin); - } else if (seqno < s->inseqno) { - // If the sequence number is farther in the past than the bitmap goes, or if the packet was already received, drop it. - if((s->inseqno >= s->replaywin * 8 && seqno < s->inseqno - s->replaywin * 8) || !(s->late[(seqno / 8) % s->replaywin] & (1 << seqno % 8))) - return error(s, EIO, "Received late or replayed packet, seqno %d, last received %d\n", seqno, s->inseqno); - } else { - // We missed some packets. Mark them in the bitmap as being late. - for(int i = s->inseqno; i < seqno; i++) - s->late[(i / 8) % s->replaywin] |= 1 << i % 8; - } - } - - // Mark the current packet as not being late. - s->late[(seqno / 8) % s->replaywin] &= ~(1 << seqno % 8); - s->farfuture = 0; - } - - if(seqno >= s->inseqno) - s->inseqno = seqno + 1; - - if(!s->inseqno) - s->received = 0; - else - s->received++; - - // Decrypt. - memcpy(&seqno, buffer + 2, 4); - if(!cipher_set_counter(s->incipher, &seqno, sizeof seqno)) - return false; - if(!cipher_counter_xor(s->incipher, buffer + 6, len - 4, buffer + 6)) + if(!sptps_check_seqno(s, seqno, true)) return false; // Append a NULL byte for safety. - buffer[len - 14] = 0; + buffer[len - 20] = 0; - uint8_t type = buffer[6]; + uint8_t type = buffer[0]; if(type < SPTPS_HANDSHAKE) { if(!s->instate) return error(s, EIO, "Application record received before handshake finished"); - if(!s->receive_record(s->handle, type, buffer + 7, len - 21)) - return false; + if(!s->receive_record(s->handle, type, buffer + 1, len - 21)) + abort(); } else if(type == SPTPS_HANDSHAKE) { - if(!receive_handshake(s, buffer + 7, len - 21)) - return false; + if(!receive_handshake(s, buffer + 1, len - 21)) + abort(); } else { return error(s, EIO, "Invalid record type %d", type); } @@ -520,7 +495,7 @@ static bool sptps_receive_data_datagram(sptps_t *s, const char *data, size_t len } // Receive incoming data. Check if it contains a complete record, if so, handle it. -bool sptps_receive_data(sptps_t *s, const char *data, size_t len) { +bool sptps_receive_data(sptps_t *s, const void *data, size_t len) { if(!s->state) return error(s, EIO, "Invalid session state zero"); @@ -529,8 +504,8 @@ bool sptps_receive_data(sptps_t *s, const char *data, size_t len) { while(len) { // First read the 2 length bytes. - if(s->buflen < 6) { - size_t toread = 6 - s->buflen; + if(s->buflen < 2) { + size_t toread = 2 - s->buflen; if(toread > len) toread = len; @@ -541,36 +516,26 @@ bool sptps_receive_data(sptps_t *s, const char *data, size_t len) { data += toread; // Exit early if we don't have the full length. - if(s->buflen < 6) + if(s->buflen < 2) return true; - // Decrypt the length bytes - - if(s->instate) { - if(!cipher_counter_xor(s->incipher, s->inbuf + 4, 2, &s->reclen)) - return false; - } else { - memcpy(&s->reclen, s->inbuf + 4, 2); - } + // Get the length bytes + memcpy(&s->reclen, s->inbuf, 2); s->reclen = ntohs(s->reclen); // If we have the length bytes, ensure our buffer can hold the whole request. - s->inbuf = realloc(s->inbuf, s->reclen + 23UL); + s->inbuf = realloc(s->inbuf, s->reclen + 19UL); if(!s->inbuf) return error(s, errno, strerror(errno)); - // Add sequence number. - uint32_t seqno = htonl(s->inseqno++); - memcpy(s->inbuf, &seqno, 4); - // Exit early if we have no more data to process. if(!len) return true; } // Read up to the end of the record. - size_t toread = s->reclen + (s->instate ? 23UL : 7UL) - s->buflen; + size_t toread = s->reclen + (s->instate ? 19UL : 3UL) - s->buflen; if(toread > len) toread = len; @@ -580,43 +545,44 @@ bool sptps_receive_data(sptps_t *s, const char *data, size_t len) { data += toread; // If we don't have a whole record, exit. - if(s->buflen < s->reclen + (s->instate ? 23UL : 7UL)) + if(s->buflen < s->reclen + (s->instate ? 19UL : 3UL)) return true; + // Update sequence number. + + uint32_t seqno = s->inseqno++; + // Check HMAC and decrypt. if(s->instate) { - if(!digest_verify(s->indigest, s->inbuf, s->reclen + 7UL, s->inbuf + s->reclen + 7UL)) - return error(s, EIO, "Invalid HMAC"); - - if(!cipher_counter_xor(s->incipher, s->inbuf + 6UL, s->reclen + 1UL, s->inbuf + 6UL)) - return false; + if(!chacha_poly1305_decrypt(s->incipher, seqno, s->inbuf + 2UL, s->reclen + 17UL, s->inbuf + 2UL, NULL)) + return error(s, EINVAL, "Failed to decrypt and verify record"); } // Append a NULL byte for safety. - s->inbuf[s->reclen + 7UL] = 0; + s->inbuf[s->reclen + 3UL] = 0; - uint8_t type = s->inbuf[6]; + uint8_t type = s->inbuf[2]; if(type < SPTPS_HANDSHAKE) { if(!s->instate) return error(s, EIO, "Application record received before handshake finished"); - if(!s->receive_record(s->handle, type, s->inbuf + 7, s->reclen)) + if(!s->receive_record(s->handle, type, s->inbuf + 3, s->reclen)) return false; } else if(type == SPTPS_HANDSHAKE) { - if(!receive_handshake(s, s->inbuf + 7, s->reclen)) + if(!receive_handshake(s, s->inbuf + 3, s->reclen)) return false; } else { return error(s, EIO, "Invalid record type %d", type); } - s->buflen = 4; + s->buflen = 0; } return true; } // Start a SPTPS session. -bool sptps_start(sptps_t *s, void *handle, bool initiator, bool datagram, ecdsa_t *mykey, ecdsa_t *hiskey, const char *label, size_t labellen, send_data_t send_data, receive_record_t receive_record) { +bool sptps_start(sptps_t *s, void *handle, bool initiator, bool datagram, ecdsa_t *mykey, ecdsa_t *hiskey, const void *label, size_t labellen, send_data_t send_data, receive_record_t receive_record) { // Initialise struct sptps memset(s, 0, sizeof *s); @@ -641,8 +607,7 @@ bool sptps_start(sptps_t *s, void *handle, bool initiator, bool datagram, ecdsa_ s->inbuf = malloc(7); if(!s->inbuf) return error(s, errno, strerror(errno)); - s->buflen = 4; - memset(s->inbuf, 0, 4); + s->buflen = 0; } memcpy(s->label, label, labellen); @@ -659,10 +624,8 @@ bool sptps_start(sptps_t *s, void *handle, bool initiator, bool datagram, ecdsa_ // Stop a SPTPS session. bool sptps_stop(sptps_t *s) { // Clean up any resources. - cipher_close(s->incipher); - cipher_close(s->outcipher); - digest_close(s->indigest); - digest_close(s->outdigest); + chacha_poly1305_exit(s->incipher); + chacha_poly1305_exit(s->outcipher); ecdh_free(s->ecdh); free(s->inbuf); free(s->mykex); diff --git a/src/sptps.h b/src/sptps.h index 3a8e65f..a2633bd 100644 --- a/src/sptps.h +++ b/src/sptps.h @@ -1,6 +1,6 @@ /* sptps.h -- Simple Peer-to-Peer Security - Copyright (C) 2011-2013 Guus Sliepen , + Copyright (C) 2011-2014 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 @@ -22,8 +22,7 @@ #include "system.h" -#include "cipher.h" -#include "digest.h" +#include "chacha-poly1305/chacha-poly1305.h" #include "ecdh.h" #include "ecdsa.h" @@ -40,8 +39,11 @@ #define SPTPS_SIG 3 // Waiting for a SIGnature record #define SPTPS_ACK 4 // Waiting for an ACKnowledgement record -typedef bool (*send_data_t)(void *handle, uint8_t type, const char *data, size_t len); -typedef bool (*receive_record_t)(void *handle, uint8_t type, const char *data, uint16_t len); +// Overhead for datagrams +#define SPTPS_DATAGRAM_OVERHEAD 21 + +typedef bool (*send_data_t)(void *handle, uint8_t type, const void *data, size_t len); +typedef bool (*receive_record_t)(void *handle, uint8_t type, const void *data, uint16_t len); typedef struct sptps { bool initiator; @@ -53,8 +55,7 @@ typedef struct sptps { uint16_t reclen; bool instate; - cipher_t *incipher; - digest_t *indigest; + chacha_poly1305_ctx_t *incipher; uint32_t inseqno; uint32_t received; unsigned int replaywin; @@ -62,8 +63,7 @@ typedef struct sptps { char *late; bool outstate; - cipher_t *outcipher; - digest_t *outdigest; + chacha_poly1305_ctx_t *outcipher; uint32_t outseqno; ecdsa_t *mykey; @@ -85,11 +85,11 @@ extern unsigned int sptps_replaywin; extern void sptps_log_quiet(sptps_t *s, int s_errno, const char *format, va_list ap); extern void sptps_log_stderr(sptps_t *s, int s_errno, const char *format, va_list ap); extern void (*sptps_log)(sptps_t *s, int s_errno, const char *format, va_list ap); -extern bool sptps_start(sptps_t *s, void *handle, bool initiator, bool datagram, ecdsa_t *mykey, ecdsa_t *hiskey, const char *label, size_t labellen, send_data_t send_data, receive_record_t receive_record); +extern bool sptps_start(sptps_t *s, void *handle, bool initiator, bool datagram, ecdsa_t *mykey, ecdsa_t *hiskey, const void *label, size_t labellen, send_data_t send_data, receive_record_t receive_record); extern bool sptps_stop(sptps_t *s); -extern bool sptps_send_record(sptps_t *s, uint8_t type, const char *data, uint16_t len); -extern bool sptps_receive_data(sptps_t *s, const char *data, size_t len); +extern bool sptps_send_record(sptps_t *s, uint8_t type, const void *data, uint16_t len); +extern bool sptps_receive_data(sptps_t *s, const void *data, size_t len); extern bool sptps_force_kex(sptps_t *s); -extern bool sptps_verify_datagram(sptps_t *s, const char *data, size_t len); +extern bool sptps_verify_datagram(sptps_t *s, const void *data, size_t len); #endif diff --git a/src/sptps_keypair.c b/src/sptps_keypair.c new file mode 100644 index 0000000..399404e --- /dev/null +++ b/src/sptps_keypair.c @@ -0,0 +1,108 @@ +/* + sptps_test.c -- Simple Peer-to-Peer Security test program + Copyright (C) 2011-2013 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "system.h" + +#include + +#include "crypto.h" +#include "ecdsagen.h" +#include "utils.h" + +static char *program_name; + +void logger(int level, int priority, const char *format, ...) { + va_list ap; + va_start(ap, format); + vfprintf(stderr, format, ap); + va_end(ap); + fputc('\n', stderr); +} + +static void usage() { + fprintf(stderr, "Usage: %s [options] private_key_file public_key_file\n\n", program_name); + fprintf(stderr, "Valid options are:\n" + " --help Display this help and exit.\n" + "\n"); + fprintf(stderr, "Report bugs to tinc@tinc-vpn.org.\n"); +} + +static struct option const long_options[] = { + {"help", no_argument, NULL, 1}, + {NULL, 0, NULL, 0} +}; + +int main(int argc, char *argv[]) { + program_name = argv[0]; + int r; + int option_index = 0; + + while((r = getopt_long(argc, argv, "", long_options, &option_index)) != EOF) { + switch (r) { + case 0: /* long option */ + break; + + case '?': /* wrong options */ + usage(); + return 1; + + case 1: /* help */ + usage(); + return 0; + + default: + break; + } + } + + argc -= optind - 1; + argv += optind - 1; + + if(argc != 3) { + fprintf(stderr, "Wrong number of arguments.\n"); + usage(); + return 1; + } + + crypto_init(); + + ecdsa_t *key = ecdsa_generate(); + if(!key) + return 1; + + FILE *fp = fopen(argv[1], "w"); + if(fp) { + ecdsa_write_pem_private_key(key, fp); + fclose(fp); + } else { + fprintf(stderr, "Could not open '%s' for writing: %s\n", argv[1], strerror(errno)); + return 1; + } + + fp = fopen(argv[2], "w"); + if(fp) { + ecdsa_write_pem_public_key(key, fp); + fclose(fp); + } else { + fprintf(stderr, "Could not open '%s' for writing: %s\n", argv[2], strerror(errno)); + return 1; + } + + return 0; +} diff --git a/src/sptps_speed.c b/src/sptps_speed.c new file mode 100644 index 0000000..ab41e8d --- /dev/null +++ b/src/sptps_speed.c @@ -0,0 +1,232 @@ +/* + sptps_speed.c -- SPTPS benchmark + Copyright (C) 2013-2014 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "system.h" +#include "utils.h" + +#include + +#include "crypto.h" +#include "ecdh.h" +#include "ecdsa.h" +#include "ecdsagen.h" +#include "sptps.h" + +// Symbols necessary to link with logger.o +bool send_request(void *c, const char *msg, ...) { return false; } +struct list_t *connection_list = NULL; +bool send_meta(void *c, const char *msg , int len) { return false; } +char *logfilename = NULL; +struct timeval now; + +static bool send_data(void *handle, uint8_t type, const void *data, size_t len) { + int fd = *(int *)handle; + send(fd, data, len, 0); + return true; +} + +static bool receive_record(void *handle, uint8_t type, const void *data, uint16_t len) { + return true; +} + +static void receive_data(sptps_t *sptps) { + char buf[4096]; + int fd = *(int *)sptps->handle; + size_t len = recv(fd, buf, sizeof buf, 0); + if(!sptps_receive_data(sptps, buf, len)) + abort(); +} + +struct timespec start; +struct timespec end; +double elapsed; +double rate; +unsigned int count; + +static void clock_start() { + count = 0; + clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &start); +} + +static bool clock_countto(double seconds) { + clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &end); + elapsed = end.tv_sec + end.tv_nsec * 1e-9 - start.tv_sec - start.tv_nsec * 1e-9; + if(elapsed < seconds) + return ++count; + + rate = count / elapsed; + return false; +} + +int main(int argc, char *argv[]) { + ecdsa_t *key1, *key2; + ecdh_t *ecdh1, *ecdh2; + sptps_t sptps1, sptps2; + char buf1[4096], buf2[4096], buf3[4096]; + double duration = argc > 1 ? atof(argv[1]) : 10; + + crypto_init(); + + randomize(buf1, sizeof buf1); + randomize(buf2, sizeof buf2); + randomize(buf3, sizeof buf3); + + // Key generation + + fprintf(stderr, "Generating keys for %lg seconds: ", duration); + for(clock_start(); clock_countto(duration);) + ecdsa_free(ecdsa_generate()); + fprintf(stderr, "%17.2lf op/s\n", rate); + + key1 = ecdsa_generate(); + key2 = ecdsa_generate(); + + // Ed25519 signatures + + fprintf(stderr, "Ed25519 sign for %lg seconds: ", duration); + for(clock_start(); clock_countto(duration);) + ecdsa_sign(key1, buf1, 256, buf2); + fprintf(stderr, "%22.2lf op/s\n", rate); + + fprintf(stderr, "Ed25519 verify for %lg seconds: ", duration); + for(clock_start(); clock_countto(duration);) + ecdsa_verify(key1, buf1, 256, buf2); + fprintf(stderr, "%20.2lf op/s\n", rate); + + ecdh1 = ecdh_generate_public(buf1); + fprintf(stderr, "ECDH for %lg seconds: ", duration); + for(clock_start(); clock_countto(duration);) { + ecdh2 = ecdh_generate_public(buf2); + ecdh_compute_shared(ecdh2, buf1, buf3); + } + fprintf(stderr, "%28.2lf op/s\n", rate); + ecdh_free(ecdh1); + + // SPTPS authentication phase + + int fd[2]; + if(socketpair(AF_UNIX, SOCK_STREAM, 0, fd)) { + fprintf(stderr, "Could not create a UNIX socket pair: %s\n", sockstrerror(sockerrno)); + return 1; + } + + struct pollfd pfd[2] = {{fd[0], POLLIN}, {fd[1], POLLIN}}; + + fprintf(stderr, "SPTPS/TCP authenticate for %lg seconds: ", duration); + for(clock_start(); clock_countto(duration);) { + sptps_start(&sptps1, fd + 0, true, false, key1, key2, "sptps_speed", 11, send_data, receive_record); + sptps_start(&sptps2, fd + 1, false, false, key2, key1, "sptps_speed", 11, send_data, receive_record); + while(poll(pfd, 2, 0)) { + if(pfd[0].revents) + receive_data(&sptps1); + if(pfd[1].revents) + receive_data(&sptps2); + } + sptps_stop(&sptps1); + sptps_stop(&sptps2); + } + fprintf(stderr, "%10.2lf op/s\n", rate * 2); + + // SPTPS data + + sptps_start(&sptps1, fd + 0, true, false, key1, key2, "sptps_speed", 11, send_data, receive_record); + sptps_start(&sptps2, fd + 1, false, false, key2, key1, "sptps_speed", 11, send_data, receive_record); + while(poll(pfd, 2, 0)) { + if(pfd[0].revents) + receive_data(&sptps1); + if(pfd[1].revents) + receive_data(&sptps2); + } + fprintf(stderr, "SPTPS/TCP transmit for %lg seconds: ", duration); + for(clock_start(); clock_countto(duration);) { + if(!sptps_send_record(&sptps1, 0, buf1, 1451)) + abort(); + receive_data(&sptps2); + } + rate *= 2 * 1451 * 8; + if(rate > 1e9) + fprintf(stderr, "%14.2lf Gbit/s\n", rate / 1e9); + else if(rate > 1e6) + fprintf(stderr, "%14.2lf Mbit/s\n", rate / 1e6); + else if(rate > 1e3) + fprintf(stderr, "%14.2lf kbit/s\n", rate / 1e3); + sptps_stop(&sptps1); + sptps_stop(&sptps2); + + // SPTPS datagram authentication phase + + close(fd[0]); + close(fd[1]); + + if(socketpair(AF_UNIX, SOCK_DGRAM, 0, fd)) { + fprintf(stderr, "Could not create a UNIX socket pair: %s\n", sockstrerror(sockerrno)); + return 1; + } + + fprintf(stderr, "SPTPS/UDP authenticate for %lg seconds: ", duration); + for(clock_start(); clock_countto(duration);) { + sptps_start(&sptps1, fd + 0, true, true, key1, key2, "sptps_speed", 11, send_data, receive_record); + sptps_start(&sptps2, fd + 1, false, true, key2, key1, "sptps_speed", 11, send_data, receive_record); + while(poll(pfd, 2, 0)) { + if(pfd[0].revents) + receive_data(&sptps1); + if(pfd[1].revents) + receive_data(&sptps2); + } + sptps_stop(&sptps1); + sptps_stop(&sptps2); + } + fprintf(stderr, "%10.2lf op/s\n", rate * 2); + + // SPTPS datagram data + + sptps_start(&sptps1, fd + 0, true, true, key1, key2, "sptps_speed", 11, send_data, receive_record); + sptps_start(&sptps2, fd + 1, false, true, key2, key1, "sptps_speed", 11, send_data, receive_record); + while(poll(pfd, 2, 0)) { + if(pfd[0].revents) + receive_data(&sptps1); + if(pfd[1].revents) + receive_data(&sptps2); + } + fprintf(stderr, "SPTPS/UDP transmit for %lg seconds: ", duration); + for(clock_start(); clock_countto(duration);) { + if(!sptps_send_record(&sptps1, 0, buf1, 1451)) + abort(); + receive_data(&sptps2); + } + rate *= 2 * 1451 * 8; + if(rate > 1e9) + fprintf(stderr, "%14.2lf Gbit/s\n", rate / 1e9); + else if(rate > 1e6) + fprintf(stderr, "%14.2lf Mbit/s\n", rate / 1e6); + else if(rate > 1e3) + fprintf(stderr, "%14.2lf kbit/s\n", rate / 1e3); + sptps_stop(&sptps1); + sptps_stop(&sptps2); + + // Clean up + + close(fd[0]); + close(fd[1]); + ecdsa_free(key1); + ecdsa_free(key2); + crypto_exit(); + + return 0; +} diff --git a/src/sptps_test.c b/src/sptps_test.c index 7aa7a0a..95bfda8 100644 --- a/src/sptps_test.c +++ b/src/sptps_test.c @@ -1,6 +1,6 @@ /* sptps_test.c -- Simple Peer-to-Peer Security test program - Copyright (C) 2011-2013 Guus Sliepen , + Copyright (C) 2011-2014 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 @@ -19,6 +19,10 @@ #include "system.h" +#ifdef HAVE_LINUX +#include +#endif + #include #include "crypto.h" @@ -33,23 +37,28 @@ bool send_meta(void *c, const char *msg , int len) { return false; } char *logfilename = NULL; struct timeval now; +static bool verbose; static bool readonly; static bool writeonly; +static int in = 0; +static int out = 1; -static bool send_data(void *handle, uint8_t type, const char *data, size_t len) { +static bool send_data(void *handle, uint8_t type, const void *data, size_t len) { char hex[len * 2 + 1]; bin2hex(data, hex, len); - fprintf(stderr, "Sending %d bytes of data:\n%s\n", (int)len, hex); + if(verbose) + fprintf(stderr, "Sending %d bytes of data:\n%s\n", (int)len, hex); const int *sock = handle; if(send(*sock, data, len, 0) != len) return false; return true; } -static bool receive_record(void *handle, uint8_t type, const char *data, uint16_t len) { - fprintf(stderr, "Received type %d record of %hu bytes:\n", type, len); +static bool receive_record(void *handle, uint8_t type, const void *data, uint16_t len) { + if(verbose) + fprintf(stderr, "Received type %d record of %hu bytes:\n", type, len); if(!writeonly) - fwrite(data, len, 1, stdout); + write(out, data, len); return true; } @@ -60,6 +69,7 @@ static struct option const long_options[] = { {"writeonly", no_argument, NULL, 'w'}, {"packet-loss", required_argument, NULL, 'L'}, {"replay-window", required_argument, NULL, 'W'}, + {"verbose", required_argument, NULL, 'v'}, {"help", no_argument, NULL, 1}, {NULL, 0, NULL, 0} }; @@ -67,14 +77,18 @@ static struct option const long_options[] = { const char *program_name; static void usage() { - fprintf(stderr, "Usage: %s [options] my_ecdsa_key_file his_ecdsa_key_file [host] port\n\n", program_name); + fprintf(stderr, "Usage: %s [options] my_ed25519_key_file his_ed25519_key_file [host] port\n\n", program_name); fprintf(stderr, "Valid options are:\n" " -d, --datagram Enable datagram mode.\n" " -q, --quit Quit when EOF occurs on stdin.\n" " -r, --readonly Only send data from the socket to stdout.\n" +#ifdef HAVE_LINUX + " -t, --tun Use a tun device instead of stdio.\n" +#endif " -w, --writeonly Only send data from stdin to the socket.\n" " -L, --packet-loss RATE Fake packet loss of RATE percent.\n" " -R, --replay-window N Set replay window to N bytes.\n" + " -v, --verbose Display debug messages.\n" "\n"); fprintf(stderr, "Report bugs to tinc@tinc-vpn.org.\n"); } @@ -83,13 +97,16 @@ int main(int argc, char *argv[]) { program_name = argv[0]; bool initiator = false; bool datagram = false; +#ifdef HAVE_LINUX + bool tun = false; +#endif int packetloss = 0; int r; int option_index = 0; ecdsa_t *mykey = NULL, *hiskey = NULL; bool quit = false; - while((r = getopt_long(argc, argv, "dqrwL:W:", long_options, &option_index)) != EOF) { + while((r = getopt_long(argc, argv, "dqrtwL:W:v", long_options, &option_index)) != EOF) { switch (r) { case 0: /* long option */ break; @@ -106,6 +123,16 @@ int main(int argc, char *argv[]) { readonly = true; break; + case 't': /* read only */ +#ifdef HAVE_LINUX + tun = true; +#else + fprintf(stderr, "--tun is only supported on Linux.\n"); + usage(); + return 1; +#endif + break; + case 'w': /* write only */ writeonly = true; break; @@ -118,6 +145,10 @@ int main(int argc, char *argv[]) { sptps_replaywin = atoi(optarg); break; + case 'v': /* be verbose */ + verbose = true; + break; + case '?': /* wrong options */ usage(); return 1; @@ -145,6 +176,25 @@ int main(int argc, char *argv[]) { srand(time(NULL)); +#ifdef HAVE_LINUX + if(tun) { + in = out = open("/dev/net/tun", O_RDWR | O_NONBLOCK); + if(in < 0) { + fprintf(stderr, "Could not open tun device: %s\n", strerror(errno)); + return 1; + } + struct ifreq ifr = { + .ifr_flags = IFF_TUN + }; + if(ioctl(in, TUNSETIFF, &ifr)) { + fprintf(stderr, "Could not configure tun interface: %s\n", strerror(errno)); + return 1; + } + ifr.ifr_name[IFNAMSIZ - 1] = 0; + fprintf(stderr, "Using tun interface %s\n", ifr.ifr_name); + } +#endif + #ifdef HAVE_MINGW static struct WSAData wsa_state; if(WSAStartup(MAKEWORD(2, 2), &wsa_state)) @@ -160,13 +210,13 @@ int main(int argc, char *argv[]) { hint.ai_flags = initiator ? 0 : AI_PASSIVE; if(getaddrinfo(initiator ? argv[3] : NULL, initiator ? argv[4] : argv[3], &hint, &ai) || !ai) { - fprintf(stderr, "getaddrinfo() failed: %s\n", strerror(errno)); + fprintf(stderr, "getaddrinfo() failed: %s\n", sockstrerror(sockerrno)); return 1; } int sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); if(sock < 0) { - fprintf(stderr, "Could not create socket: %s\n", strerror(errno)); + fprintf(stderr, "Could not create socket: %s\n", sockstrerror(sockerrno)); return 1; } @@ -175,26 +225,26 @@ int main(int argc, char *argv[]) { if(initiator) { if(connect(sock, ai->ai_addr, ai->ai_addrlen)) { - fprintf(stderr, "Could not connect to peer: %s\n", strerror(errno)); + fprintf(stderr, "Could not connect to peer: %s\n", sockstrerror(sockerrno)); return 1; } fprintf(stderr, "Connected\n"); } else { if(bind(sock, ai->ai_addr, ai->ai_addrlen)) { - fprintf(stderr, "Could not bind socket: %s\n", strerror(errno)); + fprintf(stderr, "Could not bind socket: %s\n", sockstrerror(sockerrno)); return 1; } if(!datagram) { if(listen(sock, 1)) { - fprintf(stderr, "Could not listen on socket: %s\n", strerror(errno)); + fprintf(stderr, "Could not listen on socket: %s\n", sockstrerror(sockerrno)); return 1; } fprintf(stderr, "Listening...\n"); sock = accept(sock, NULL, NULL); if(sock < 0) { - fprintf(stderr, "Could not accept connection: %s\n", strerror(errno)); + fprintf(stderr, "Could not accept connection: %s\n", sockstrerror(sockerrno)); return 1; } } else { @@ -205,12 +255,12 @@ int main(int argc, char *argv[]) { socklen_t addrlen = sizeof addr; if(recvfrom(sock, buf, sizeof buf, MSG_PEEK, &addr, &addrlen) <= 0) { - fprintf(stderr, "Could not read from socket: %s\n", strerror(errno)); + fprintf(stderr, "Could not read from socket: %s\n", sockstrerror(sockerrno)); return 1; } if(connect(sock, &addr, addrlen)) { - fprintf(stderr, "Could not accept connection: %s\n", strerror(errno)); + fprintf(stderr, "Could not accept connection: %s\n", sockstrerror(sockerrno)); return 1; } } @@ -230,7 +280,8 @@ int main(int argc, char *argv[]) { return 1; fclose(fp); - fprintf(stderr, "Keys loaded\n"); + if(verbose) + fprintf(stderr, "Keys loaded\n"); sptps_t s; if(!sptps_start(&s, &sock, initiator, datagram, mykey, hiskey, "sptps_test", 10, send_data, receive_record)) @@ -246,15 +297,14 @@ int main(int argc, char *argv[]) { FD_ZERO(&fds); #ifndef HAVE_MINGW if(!readonly && s.instate) - FD_SET(0, &fds); + FD_SET(in, &fds); #endif FD_SET(sock, &fds); if(select(sock + 1, &fds, NULL, NULL, NULL) <= 0) return 1; - if(FD_ISSET(0, &fds)) { - ssize_t len = read(0, buf, sizeof buf); - fprintf(stderr, "%zd\n", len); + if(FD_ISSET(in, &fds)) { + ssize_t len = read(in, buf, sizeof buf); if(len < 0) { fprintf(stderr, "Could not read from stdin: %s\n", strerror(errno)); return 1; @@ -274,25 +324,28 @@ int main(int argc, char *argv[]) { if(len > 1) sptps_send_record(&s, 0, buf, len); } else - if(!sptps_send_record(&s, buf[0] == '!' ? 1 : 0, buf, buf[0] == '\n' ? 0 : buf[0] == '*' ? sizeof buf : len)) + if(!sptps_send_record(&s, buf[0] == '!' ? 1 : 0, buf, (len == 1 && buf[0] == '\n') ? 0 : buf[0] == '*' ? sizeof buf : len)) return 1; } if(FD_ISSET(sock, &fds)) { ssize_t len = recv(sock, buf, sizeof buf, 0); if(len < 0) { - fprintf(stderr, "Could not read from socket: %s\n", strerror(errno)); + fprintf(stderr, "Could not read from socket: %s\n", sockstrerror(sockerrno)); return 1; } if(len == 0) { fprintf(stderr, "Connection terminated by peer.\n"); break; } - char hex[len * 2 + 1]; - bin2hex(buf, hex, len); - fprintf(stderr, "Received %d bytes of data:\n%s\n", (int)len, hex); - if((rand() % 100) < packetloss) { - fprintf(stderr, "Dropped.\n"); + if(verbose) { + char hex[len * 2 + 1]; + bin2hex(buf, hex, len); + fprintf(stderr, "Received %d bytes of data:\n%s\n", (int)len, hex); + } + if(packetloss && (rand() % 100) < packetloss) { + if(verbose) + fprintf(stderr, "Dropped.\n"); continue; } if(!sptps_receive_data(&s, buf, len) && !datagram) diff --git a/src/subnet.c b/src/subnet.c index 7ff8f7a..534e5b5 100644 --- a/src/subnet.c +++ b/src/subnet.c @@ -92,13 +92,15 @@ void subnet_add(node_t *n, subnet_t *subnet) { subnet->owner = n; splay_insert(subnet_tree, subnet); - splay_insert(n->subnet_tree, subnet); + if (n) + splay_insert(n->subnet_tree, subnet); subnet_cache_flush(); } void subnet_del(node_t *n, subnet_t *subnet) { - splay_delete(n->subnet_tree, subnet); + if (n) + splay_delete(n->subnet_tree, subnet); splay_delete(subnet_tree, subnet); subnet_cache_flush(); @@ -126,7 +128,7 @@ subnet_t *lookup_subnet_mac(const node_t *owner, const mac_t *address) { if(!memcmp(address, &p->net.mac.address, sizeof *address)) { r = p; - if(p->owner->status.reachable) + if(!p->owner || p->owner->status.reachable) break; } } @@ -155,7 +157,7 @@ subnet_t *lookup_subnet_ipv4(const ipv4_t *address) { if(!maskcmp(address, &p->net.ipv4.address, p->net.ipv4.prefixlength)) { r = p; - if(p->owner->status.reachable) + if(!p->owner || p->owner->status.reachable) break; } } @@ -184,7 +186,7 @@ subnet_t *lookup_subnet_ipv6(const ipv6_t *address) { if(!maskcmp(address, &p->net.ipv6.address, p->net.ipv6.prefixlength)) { r = p; - if(p->owner->status.reachable) + if(!p->owner || p->owner->status.reachable) break; } } @@ -205,21 +207,21 @@ void subnet_update(node_t *owner, subnet_t *subnet, bool up) { // Prepare environment variables to be passed to the script char *envp[10] = {NULL}; - xasprintf(&envp[0], "NETNAME=%s", netname ? : ""); - xasprintf(&envp[1], "DEVICE=%s", device ? : ""); - xasprintf(&envp[2], "INTERFACE=%s", iface ? : ""); - xasprintf(&envp[3], "NODE=%s", owner->name); + int n = 0; + xasprintf(&envp[n++], "NETNAME=%s", netname ? : ""); + xasprintf(&envp[n++], "DEVICE=%s", device ? : ""); + xasprintf(&envp[n++], "INTERFACE=%s", iface ? : ""); + xasprintf(&envp[n++], "NODE=%s", owner->name); if(owner != myself) { sockaddr2str(&owner->address, &address, &port); - // 4 and 5 are reserved for SUBNET and WEIGHT - xasprintf(&envp[6], "REMOTEADDRESS=%s", address); - xasprintf(&envp[7], "REMOTEPORT=%s", port); + xasprintf(&envp[n++], "REMOTEADDRESS=%s", address); + xasprintf(&envp[n++], "REMOTEPORT=%s", port); free(port); free(address); } - xasprintf(&envp[8], "NAME=%s", myself->name); + xasprintf(&envp[n++], "NAME=%s", myself->name); name = up ? "subnet-up" : "subnet-down"; @@ -236,12 +238,10 @@ void subnet_update(node_t *owner, subnet_t *subnet, bool up) { weight = empty; // Prepare the SUBNET and WEIGHT variables - if(envp[4]) - free(envp[4]); - if(envp[5]) - free(envp[5]); - xasprintf(&envp[4], "SUBNET=%s", netstr); - xasprintf(&envp[5], "WEIGHT=%s", weight); + free(envp[n]); + free(envp[n + 1]); + xasprintf(&envp[n], "SUBNET=%s", netstr); + xasprintf(&envp[n + 1], "WEIGHT=%s", weight); execute_script(name, envp); } @@ -255,8 +255,8 @@ void subnet_update(node_t *owner, subnet_t *subnet, bool up) { weight = empty; // Prepare the SUBNET and WEIGHT variables - xasprintf(&envp[4], "SUBNET=%s", netstr); - xasprintf(&envp[5], "WEIGHT=%s", weight); + xasprintf(&envp[n], "SUBNET=%s", netstr); + xasprintf(&envp[n + 1], "WEIGHT=%s", weight); execute_script(name, envp); } @@ -275,7 +275,7 @@ bool dump_subnets(connection_t *c) { send_request(c, "%d %d %s %s", CONTROL, REQ_DUMP_SUBNETS, - netstr, subnet->owner->name); + netstr, subnet->owner ? subnet->owner->name : "(broadcast)"); } return send_request(c, "%d %d", CONTROL, REQ_DUMP_SUBNETS); diff --git a/src/subnet_parse.c b/src/subnet_parse.c index f980180..c919b59 100644 --- a/src/subnet_parse.c +++ b/src/subnet_parse.c @@ -27,6 +27,9 @@ #include "utils.h" #include "xalloc.h" +/* Changing this default will affect ADD_SUBNET messages - beware of inconsistencies between versions */ +static const int DEFAULT_WEIGHT = 10; + /* Subnet mask handling */ int maskcmp(const void *va, const void *vb, int masklen) { @@ -181,150 +184,121 @@ int subnet_compare(const subnet_t *a, const subnet_t *b) { /* Ascii representation of subnets */ bool str2net(subnet_t *subnet, const char *subnetstr) { - int i, l; + char str[1024]; + strncpy(str, subnetstr, sizeof(str)); + str[sizeof str - 1] = 0; + int consumed; + + int weight = DEFAULT_WEIGHT; + char *weight_separator = strchr(str, '#'); + if (weight_separator) { + char *weight_str = weight_separator + 1; + if (sscanf(weight_str, "%d%n", &weight, &consumed) < 1) + return false; + if (weight_str[consumed]) + return false; + *weight_separator = 0; + } + + int prefixlength = -1; + char *prefixlength_separator = strchr(str, '/'); + if (prefixlength_separator) { + char* prefixlength_str = prefixlength_separator + 1; + if (sscanf(prefixlength_str, "%d%n", &prefixlength, &consumed) < 1) + return false; + if (prefixlength_str[consumed]) + return false; + *prefixlength_separator = 0; + + if (prefixlength < 0) + return false; + } + uint16_t x[8]; - int weight = 10; - - if(sscanf(subnetstr, "%hu.%hu.%hu.%hu/%d#%d", - &x[0], &x[1], &x[2], &x[3], &l, &weight) >= 5) { - if(l < 0 || l > 32) + if (sscanf(str, "%hx:%hx:%hx:%hx:%hx:%hx%n", &x[0], &x[1], &x[2], &x[3], &x[4], &x[5], &consumed) >= 6 && !str[consumed]) { + /* + Normally we should check that each part has two digits to prevent ambiguities. + However, in old tinc versions net2str() will agressively return MAC addresses with one-digit parts, + so we have to accept them otherwise we would be unable to parse ADD_SUBNET messages. + */ + if (prefixlength >= 0) return false; - subnet->type = SUBNET_IPV4; - subnet->net.ipv4.prefixlength = l; - subnet->weight = weight; - - for(int i = 0; i < 4; i++) { - if(x[i] > 255) - return false; - subnet->net.ipv4.address.x[i] = x[i]; - } - - return true; - } - - if(sscanf(subnetstr, "%hx:%hx:%hx:%hx:%hx:%hx:%hx:%hx/%d#%d", - &x[0], &x[1], &x[2], &x[3], &x[4], &x[5], &x[6], &x[7], - &l, &weight) >= 9) { - if(l < 0 || l > 128) - return false; - - subnet->type = SUBNET_IPV6; - subnet->net.ipv6.prefixlength = l; - subnet->weight = weight; - - for(i = 0; i < 8; i++) - subnet->net.ipv6.address.x[i] = htons(x[i]); - - return true; - } - - if(sscanf(subnetstr, "%hu.%hu.%hu.%hu#%d", &x[0], &x[1], &x[2], &x[3], &weight) >= 4) { - subnet->type = SUBNET_IPV4; - subnet->net.ipv4.prefixlength = 32; - subnet->weight = weight; - - for(i = 0; i < 4; i++) { - if(x[i] > 255) - return false; - subnet->net.ipv4.address.x[i] = x[i]; - } - - return true; - } - - if(sscanf(subnetstr, "%hx:%hx:%hx:%hx:%hx:%hx:%hx:%hx#%d", - &x[0], &x[1], &x[2], &x[3], &x[4], &x[5], &x[6], &x[7], &weight) >= 8) { - subnet->type = SUBNET_IPV6; - subnet->net.ipv6.prefixlength = 128; - subnet->weight = weight; - - for(i = 0; i < 8; i++) - subnet->net.ipv6.address.x[i] = htons(x[i]); - - return true; - } - - if(sscanf(subnetstr, "%hx:%hx:%hx:%hx:%hx:%hx#%d", - &x[0], &x[1], &x[2], &x[3], &x[4], &x[5], &weight) >= 6) { subnet->type = SUBNET_MAC; subnet->weight = weight; - - for(i = 0; i < 6; i++) + for(int i = 0; i < 6; i++) subnet->net.mac.address.x[i] = x[i]; - return true; } - // IPv6 short form - if(strstr(subnetstr, "::")) { - const char *p; - char *q; - int colons = 0; - - // Count number of colons - for(p = subnetstr; *p; p++) - if(*p == ':') - colons++; - - if(colons > 7) + if (sscanf(str, "%hu.%hu.%hu.%hu%n", &x[0], &x[1], &x[2], &x[3], &consumed) >= 4 && !str[consumed]) { + if (prefixlength == -1) + prefixlength = 32; + if (prefixlength > 32) return false; - // Scan numbers before the double colon - p = subnetstr; - for(i = 0; i < colons; i++) { - if(*p == ':') - break; - x[i] = strtoul(p, &q, 0x10); - if(!q || p == q || *q != ':') + subnet->type = SUBNET_IPV4; + subnet->net.ipv4.prefixlength = prefixlength; + subnet->weight = weight; + for(int i = 0; i < 4; i++) { + if (x[i] > 255) return false; - p = ++q; + subnet->net.ipv4.address.x[i] = x[i]; } + return true; + } - p++; - colons -= i; - if(!i) { - p++; - colons--; - } + /* IPv6 */ - if(!*p || *p == '/' || *p == '#') - colons--; - - // Fill in the blanks - for(; i < 8 - colons; i++) - x[i] = 0; - - // Scan the remaining numbers - for(; i < 8; i++) { - x[i] = strtoul(p, &q, 0x10); - if(!q || p == q) + char* last_colon = strrchr(str, ':'); + if (last_colon && sscanf(last_colon, ":%hu.%hu.%hu.%hu%n", &x[0], &x[1], &x[2], &x[3], &consumed) >= 4 && !last_colon[consumed]) { + /* Dotted quad suffix notation, convert to standard IPv6 notation */ + for (int i = 0; i < 4; i++) + if (x[i] > 255) return false; - if(i == 7) { - p = q; - break; + snprintf(last_colon, sizeof str - (last_colon - str), ":%02x%02x:%02x%02x", x[0], x[1], x[2], x[3]); + } + + char* double_colon = strstr(str, "::"); + if (double_colon) { + /* Figure out how many zero groups we need to expand */ + int zero_group_count = 8; + for (const char* cur = str; *cur; cur++) + if (*cur != ':') { + zero_group_count--; + while(cur[1] && cur[1] != ':') + cur++; } - if(*q != ':') - return false; - p = ++q; - } + if (zero_group_count < 1) + return false; - l = 128; - if(*p == '/') - sscanf(p, "/%d#%d", &l, &weight); - else if(*p == '#') - sscanf(p, "#%d", &weight); + /* Split the double colon in the middle to make room for zero groups */ + double_colon++; + memmove(double_colon + (zero_group_count * 2 - 1), double_colon, strlen(double_colon) + 1); - if(l < 0 || l > 128) + /* Write zero groups in the resulting gap, overwriting the second colon */ + for (int i = 0; i < zero_group_count; i++) + memcpy(&double_colon[i * 2], "0:", 2); + + /* Remove any leading or trailing colons */ + if (str[0] == ':') + memmove(&str[0], &str[1], strlen(&str[1]) + 1); + if (str[strlen(str) - 1] == ':') + str[strlen(str) - 1] = 0; + } + + if (sscanf(str, "%hx:%hx:%hx:%hx:%hx:%hx:%hx:%hx%n", + &x[0], &x[1], &x[2], &x[3], &x[4], &x[5], &x[6], &x[7], &consumed) >= 8 && !str[consumed]) { + if (prefixlength == -1) + prefixlength = 128; + if (prefixlength > 128) return false; subnet->type = SUBNET_IPV6; - subnet->net.ipv6.prefixlength = l; + subnet->net.ipv6.prefixlength = prefixlength; subnet->weight = weight; - - for(i = 0; i < 8; i++) + for(int i = 0; i < 8; i++) subnet->net.ipv6.address.x[i] = htons(x[i]); - return true; } @@ -337,46 +311,101 @@ bool net2str(char *netstr, int len, const subnet_t *subnet) { return false; } + int result; + int prefixlength = -1; switch (subnet->type) { case SUBNET_MAC: - snprintf(netstr, len, "%hx:%hx:%hx:%hx:%hx:%hx#%d", + result = snprintf(netstr, len, "%02x:%02x:%02x:%02x:%02x:%02x", subnet->net.mac.address.x[0], subnet->net.mac.address.x[1], subnet->net.mac.address.x[2], subnet->net.mac.address.x[3], subnet->net.mac.address.x[4], - subnet->net.mac.address.x[5], - subnet->weight); + subnet->net.mac.address.x[5]); + netstr += result; + len -= result; break; case SUBNET_IPV4: - snprintf(netstr, len, "%hu.%hu.%hu.%hu/%d#%d", + result = snprintf(netstr, len, "%u.%u.%u.%u", subnet->net.ipv4.address.x[0], subnet->net.ipv4.address.x[1], subnet->net.ipv4.address.x[2], - subnet->net.ipv4.address.x[3], - subnet->net.ipv4.prefixlength, - subnet->weight); + subnet->net.ipv4.address.x[3]); + netstr += result; + len -= result; + prefixlength = subnet->net.ipv4.prefixlength; + if (prefixlength == 32) + prefixlength = -1; break; - case SUBNET_IPV6: - snprintf(netstr, len, "%hx:%hx:%hx:%hx:%hx:%hx:%hx:%hx/%d#%d", - ntohs(subnet->net.ipv6.address.x[0]), - ntohs(subnet->net.ipv6.address.x[1]), - ntohs(subnet->net.ipv6.address.x[2]), - ntohs(subnet->net.ipv6.address.x[3]), - ntohs(subnet->net.ipv6.address.x[4]), - ntohs(subnet->net.ipv6.address.x[5]), - ntohs(subnet->net.ipv6.address.x[6]), - ntohs(subnet->net.ipv6.address.x[7]), - subnet->net.ipv6.prefixlength, - subnet->weight); + case SUBNET_IPV6: { + /* Find the longest sequence of consecutive zeroes */ + int max_zero_length = 0; + int max_zero_length_index = 0; + int current_zero_length = 0; + int current_zero_length_index = 0; + for (int i = 0; i < 8; i++) { + if (subnet->net.ipv6.address.x[i] != 0) + current_zero_length = 0; + else { + if (current_zero_length == 0) + current_zero_length_index = i; + current_zero_length++; + if (current_zero_length > max_zero_length) { + max_zero_length = current_zero_length; + max_zero_length_index = current_zero_length_index; + } + } + } + + /* Print the address */ + for (int i = 0; i < 8;) { + if (max_zero_length > 1 && max_zero_length_index == i) { + /* Shorten the representation as per RFC 5952 */ + const char* const FORMATS[] = { "%.1s", "%.2s", "%.3s" }; + const char* const* format = &FORMATS[0]; + if (i == 0) + format++; + if (i + max_zero_length == 8) + format++; + result = snprintf(netstr, len, *format, ":::"); + i += max_zero_length; + } else { + result = snprintf(netstr, len, "%hx:", ntohs(subnet->net.ipv6.address.x[i])); + i++; + } + netstr += result; + len -= result; + } + + /* Remove the trailing colon */ + netstr--; + len++; + *netstr = 0; + + prefixlength = subnet->net.ipv6.prefixlength; + if (prefixlength == 128) + prefixlength = -1; break; + } default: logger(DEBUG_ALWAYS, LOG_ERR, "net2str() was called with unknown subnet type %d, exiting!", subnet->type); exit(1); } + if (prefixlength >= 0) { + result = snprintf(netstr, len, "/%d", prefixlength); + netstr += result; + len -= result; + } + + if (subnet->weight != DEFAULT_WEIGHT) { + snprintf(netstr, len, "#%d", subnet->weight); + netstr += result; + len -= result; + } + return true; } diff --git a/src/tincctl.c b/src/tincctl.c index a986af7..abaf6ee 100644 --- a/src/tincctl.c +++ b/src/tincctl.c @@ -1,6 +1,6 @@ /* tincctl.c -- Controlling a running tincd - Copyright (C) 2007-2013 Guus Sliepen + Copyright (C) 2007-2014 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 @@ -38,6 +38,11 @@ #include "utils.h" #include "tincctl.h" #include "top.h" +#include "version.h" + +#ifndef MSG_NOSIGNAL +#define MSG_NOSIGNAL 0 +#endif static char **orig_argv; static int orig_argc; @@ -67,8 +72,10 @@ bool confbasegiven = false; bool netnamegiven = false; char *scriptinterpreter = NULL; char *scriptextension = ""; +static char *prompt; static struct option const long_options[] = { + {"batch", no_argument, NULL, 'b'}, {"config", required_argument, NULL, 'c'}, {"net", required_argument, NULL, 'n'}, {"help", no_argument, NULL, 1}, @@ -80,8 +87,8 @@ static struct option const long_options[] = { static void version(void) { printf("%s version %s (built %s %s, protocol %d.%d)\n", PACKAGE, - VERSION, __DATE__, __TIME__, PROT_MAJOR, PROT_MINOR); - printf("Copyright (C) 1998-2012 Ivo Timmermans, Guus Sliepen and others.\n" + VERSION, BUILD_DATE, BUILD_TIME, PROT_MAJOR, PROT_MINOR); + printf("Copyright (C) 1998-2014 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" @@ -94,6 +101,7 @@ static void usage(bool status) { } else { printf("Usage: %s [options] command\n\n", program_name); printf("Valid options are:\n" + " -b, --batch Don't ask for anything (non-interactive mode).\n" " -c, --config=DIR Read configuration options from DIR.\n" " -n, --net=NETNAME Connect to net NETNAME.\n" " --pidfile=FILENAME Read control cookie from FILENAME.\n" @@ -111,9 +119,9 @@ static void usage(bool status) { " restart [tincd options] Restart tincd.\n" " reload Partially reload configuration of running tincd.\n" " pid Show PID of currently running tincd.\n" - " generate-keys [bits] Generate new RSA and ECDSA public/private keypairs.\n" + " generate-keys [bits] Generate new RSA and Ed25519 public/private keypairs.\n" " generate-rsa-keys [bits] Generate a new RSA public/private keypair.\n" - " generate-ecdsa-keys Generate a new ECDSA public/private keypair.\n" + " generate-ed25519-keys Generate a new Ed25519 public/private keypair.\n" " dump Dump a list of one of the following things:\n" " [reachable] nodes - all known nodes in the VPN\n" " edges - all known connections in the VPN\n" @@ -137,6 +145,7 @@ static void usage(bool status) { " exchange-all [--force] Same as export-all followed by import\n" " invite NODE [...] Generate an invitation for NODE\n" " join INVITATION Join a VPN using an INVITIATION\n" + " network [NETNAME] List all known networks, or switch to the one named NETNAME.\n" "\n"); printf("Report bugs to tinc@tinc-vpn.org.\n"); } @@ -151,6 +160,10 @@ static bool parse_options(int argc, char **argv) { case 0: /* long option */ break; + case 'b': + tty = false; + break; + case 'c': /* config file */ confbase = xstrdup(optarg); confbasegiven = true; @@ -240,19 +253,19 @@ static void disable_old_keys(const char *filename, const char *what) { while(fgets(buf, sizeof buf, r)) { if(!block && !strncmp(buf, "-----BEGIN ", 11)) { - if((strstr(buf, " EC ") && strstr(what, "ECDSA")) || (strstr(buf, " RSA ") && strstr(what, "RSA"))) { + if((strstr(buf, " ED25519 ") && strstr(what, "Ed25519")) || (strstr(buf, " RSA ") && strstr(what, "RSA"))) { disabled = true; block = true; } } - bool ecdsapubkey = !strncasecmp(buf, "ECDSAPublicKey", 14) && strchr(" \t=", buf[14]) && strstr(what, "ECDSA"); + bool ed25519pubkey = !strncasecmp(buf, "Ed25519PublicKey", 16) && strchr(" \t=", buf[16]) && strstr(what, "Ed25519"); - if(ecdsapubkey) + if(ed25519pubkey) disabled = true; if(w) { - if(block || ecdsapubkey) + if(block || ed25519pubkey) fputc('#', w); if(fputs(buf, w) < 0) { error = true; @@ -308,8 +321,7 @@ static FILE *ask_and_open(const char *filename, const char *what, const char *mo /* Check stdin and stdout */ if(ask && tty) { /* Ask for a file and/or directory name. */ - fprintf(stdout, "Please enter a file to save %s to [%s]: ", what, filename); - fflush(stdout); + fprintf(stderr, "Please enter a file to save %s to [%s]: ", what, filename); if(fgets(buf, sizeof buf, stdin) == NULL) { fprintf(stderr, "Error while reading stdin: %s\n", strerror(errno)); @@ -350,15 +362,15 @@ static FILE *ask_and_open(const char *filename, const char *what, const char *mo } /* - Generate a public/private ECDSA keypair, and ask for a file to store + Generate a public/private Ed25519 keypair, and ask for a file to store them in. */ -static bool ecdsa_keygen(bool ask) { +static bool ed25519_keygen(bool ask) { ecdsa_t *key; FILE *f; char *pubname, *privname; - fprintf(stderr, "Generating ECDSA keypair:\n"); + fprintf(stderr, "Generating Ed25519 keypair:\n"); if(!(key = ecdsa_generate())) { fprintf(stderr, "Error during key generation!\n"); @@ -366,8 +378,8 @@ static bool ecdsa_keygen(bool ask) { } else fprintf(stderr, "Done.\n"); - xasprintf(&privname, "%s" SLASH "ecdsa_key.priv", confbase); - f = ask_and_open(privname, "private ECDSA key", "a", ask, 0600); + xasprintf(&privname, "%s" SLASH "ed25519_key.priv", confbase); + f = ask_and_open(privname, "private Ed25519 key", "a", ask, 0600); free(privname); if(!f) @@ -385,16 +397,16 @@ static bool ecdsa_keygen(bool ask) { if(name) xasprintf(&pubname, "%s" SLASH "hosts" SLASH "%s", confbase, name); else - xasprintf(&pubname, "%s" SLASH "ecdsa_key.pub", confbase); + xasprintf(&pubname, "%s" SLASH "ed25519_key.pub", confbase); - f = ask_and_open(pubname, "public ECDSA key", "a", ask, 0666); + f = ask_and_open(pubname, "public Ed25519 key", "a", ask, 0666); free(pubname); if(!f) return false; char *pubkey = ecdsa_get_base64_public_key(key); - fprintf(f, "ECDSAPublicKey = %s\n", pubkey); + fprintf(f, "Ed25519PublicKey = %s\n", pubkey); free(pubkey); fclose(f); @@ -412,6 +424,15 @@ static bool rsa_keygen(int bits, bool ask) { FILE *f; char *pubname, *privname; + // Make sure the key size is a multiple of 8 bits. + bits &= ~0x7; + + // Force them to be between 1024 and 8192 bits long. + if(bits < 1024) + bits = 1024; + if(bits > 8192) + bits = 8192; + fprintf(stderr, "Generating %d bits keys:\n", bits); if(!(key = rsa_generate(bits, 0x10001))) { @@ -471,7 +492,7 @@ bool recvline(int fd, char *line, size_t len) { while(!(newline = memchr(buffer, '\n', blen))) { int result = recv(fd, buffer + blen, sizeof buffer - blen, 0); - if(result == -1 && errno == EINTR) + if(result == -1 && sockerrno == EINTR) continue; else if(result <= 0) return false; @@ -497,7 +518,7 @@ bool recvdata(int fd, char *data, size_t len) { while(blen < len) { int result = recv(fd, buffer + blen, sizeof buffer - blen, 0); - if(result == -1 && errno == EINTR) + if(result == -1 && sockerrno == EINTR) continue; else if(result <= 0) return false; @@ -528,8 +549,8 @@ bool sendline(int fd, char *format, ...) { blen++; while(blen) { - int result = send(fd, p, blen, 0); - if(result == -1 && errno == EINTR) + int result = send(fd, p, blen, MSG_NOSIGNAL); + if(result == -1 && sockerrno == EINTR) continue; else if(result <= 0) return false; @@ -709,7 +730,7 @@ bool connect_tincd(bool verbose) { if(getaddrinfo(host, port, &hints, &res) || !res) { if(verbose) - fprintf(stderr, "Cannot resolve %s port %s: %s", host, port, strerror(errno)); + fprintf(stderr, "Cannot resolve %s port %s: %s", host, port, sockstrerror(sockerrno)); return false; } @@ -740,6 +761,11 @@ bool connect_tincd(bool verbose) { freeaddrinfo(res); #endif +#ifdef SO_NOSIGPIPE + static const int one = 1; + setsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, (void *)&one, sizeof one); +#endif + char data[4096]; int version; @@ -790,16 +816,31 @@ static int cmd_start(int argc, char *argv[]) { int nargc = 0; char **nargv = xzalloc((optind + argc) * sizeof *nargv); - nargv[nargc++] = c; + char *arg0 = c; +#ifdef HAVE_MINGW + /* + Windows has no real concept of an "argv array". A command line is just one string. + The CRT of the new process will decode the command line string to generate argv before calling main(), and (by convention) + it uses quotes to handle spaces in arguments. + Therefore we need to quote all arguments that might contain spaces. No, execvp() won't do that for us (see MSDN). + If we don't do that, then execvp() will run fine but any spaces in the filename contained in arg0 will bleed + into the next arguments when the spawned process' CRT parses its command line, resulting in chaos. + */ + xasprintf(&arg0, "\"%s\"", arg0); +#endif + nargv[nargc++] = arg0; for(int i = 1; i < optind; i++) nargv[nargc++] = orig_argv[i]; for(int i = 1; i < argc; i++) nargv[nargc++] = argv[i]; #ifdef HAVE_MINGW - execvp(c, nargv); - fprintf(stderr, "Error starting %s: %s\n", c, strerror(errno)); - return 1; + int status = spawnvp(_P_WAIT, c, nargv); + if (status == -1) { + fprintf(stderr, "Error starting %s: %s\n", c, strerror(errno)); + return 1; + } + return status; #else pid_t pid = fork(); if(pid == -1) { @@ -961,11 +1002,14 @@ static int cmd_dump(int argc, char *argv[]) { break; char node[4096]; + char id[4096]; char from[4096]; char to[4096]; char subnet[4096]; char host[4096]; char port[4096]; + char local_host[4096]; + char local_port[4096]; char via[4096]; char nexthop[4096]; int cipher, digest, maclength, compression, distance, socket, weight; @@ -976,8 +1020,8 @@ static int cmd_dump(int argc, char *argv[]) { switch(req) { case REQ_DUMP_NODES: { - int n = sscanf(line, "%*d %*d %s %s port %s %d %d %d %d %x %x %s %s %d %hd %hd %hd %ld", node, host, port, &cipher, &digest, &maclength, &compression, &options, &status_int, nexthop, via, &distance, &pmtu, &minmtu, &maxmtu, &last_state_change); - if(n != 16) { + int n = sscanf(line, "%*d %*d %s %s %s port %s %d %d %d %d %x %x %s %s %d %hd %hd %hd %ld", node, id, host, port, &cipher, &digest, &maclength, &compression, &options, &status_int, nexthop, via, &distance, &pmtu, &minmtu, &maxmtu, &last_state_change); + if(n != 17) { fprintf(stderr, "Unable to parse node dump from tincd: %s\n", line); return 1; } @@ -1000,14 +1044,14 @@ static int cmd_dump(int argc, char *argv[]) { } else { if(only_reachable && !status.reachable) continue; - printf("%s at %s port %s cipher %d digest %d maclength %d compression %d options %x status %04x nexthop %s via %s distance %d pmtu %hd (min %hd max %hd)\n", - node, host, port, cipher, digest, maclength, compression, options, status_int, nexthop, via, distance, pmtu, minmtu, maxmtu); + printf("%s id %s at %s port %s cipher %d digest %d maclength %d compression %d options %x status %04x nexthop %s via %s distance %d pmtu %hd (min %hd max %hd)\n", + node, id, host, port, cipher, digest, maclength, compression, options, status_int, nexthop, via, distance, pmtu, minmtu, maxmtu); } } break; case REQ_DUMP_EDGES: { - int n = sscanf(line, "%*d %*d %s %s %s port %s %x %d", from, to, host, port, &options, &weight); - if(n != 6) { + int n = sscanf(line, "%*d %*d %s %s %s port %s %s port %s %x %d", from, to, host, port, local_host, local_port, &options, &weight); + if(n != 8) { fprintf(stderr, "Unable to parse edge dump from tincd.\n"); return 1; } @@ -1019,7 +1063,7 @@ static int cmd_dump(int argc, char *argv[]) { else if(do_graph == 2) printf(" %s -> %s [w = %f, weight = %f];\n", node1, node2, w, w); } else { - printf("%s to %s at %s port %s options %x weight %d\n", from, to, host, port, options, weight); + printf("%s to %s at %s port %s local %s port %s options %x weight %d\n", from, to, host, port, local_host, local_port, options, weight); } } break; @@ -1262,7 +1306,7 @@ char *get_my_name(bool verbose) { continue; if(*value) { fclose(f); - return strdup(value); + return replace_name(value); } } @@ -1279,12 +1323,14 @@ const var_t variables[] = { {"BindToAddress", VAR_SERVER | VAR_MULTIPLE}, {"BindToInterface", VAR_SERVER}, {"Broadcast", VAR_SERVER | VAR_SAFE}, + {"BroadcastSubnet", VAR_SERVER | VAR_MULTIPLE | VAR_SAFE}, {"ConnectTo", VAR_SERVER | VAR_MULTIPLE | VAR_SAFE}, {"DecrementTTL", VAR_SERVER}, {"Device", VAR_SERVER}, + {"DeviceStandby", VAR_SERVER}, {"DeviceType", VAR_SERVER}, {"DirectOnly", VAR_SERVER}, - {"ECDSAPrivateKeyFile", VAR_SERVER}, + {"Ed25519PrivateKeyFile", VAR_SERVER}, {"ExperimentalProtocol", VAR_SERVER}, {"Forwarding", VAR_SERVER}, {"GraphDumpFile", VAR_SERVER | VAR_OBSOLETE}, @@ -1292,6 +1338,7 @@ const var_t variables[] = { {"IffOneQueue", VAR_SERVER}, {"Interface", VAR_SERVER}, {"KeyExpire", VAR_SERVER}, + {"ListenAddress", VAR_SERVER | VAR_MULTIPLE}, {"LocalDiscovery", VAR_SERVER}, {"MACExpire", VAR_SERVER}, {"MaxConnectionBurst", VAR_SERVER}, @@ -1321,8 +1368,8 @@ const var_t variables[] = { {"ClampMSS", VAR_SERVER | VAR_HOST}, {"Compression", VAR_SERVER | VAR_HOST}, {"Digest", VAR_SERVER | VAR_HOST}, - {"ECDSAPublicKey", VAR_HOST}, - {"ECDSAPublicKeyFile", VAR_SERVER | VAR_HOST}, + {"Ed25519PublicKey", VAR_HOST}, + {"Ed25519PublicKeyFile", VAR_SERVER | VAR_HOST}, {"IndirectData", VAR_SERVER | VAR_HOST}, {"MACLength", VAR_SERVER | VAR_HOST}, {"PMTU", VAR_SERVER | VAR_HOST}, @@ -1591,9 +1638,12 @@ static int cmd_config(int argc, char *argv[]) { } if(action < -1) { - if(!found) + if(found) { + return 0; + } else { fprintf(stderr, "No matching configuration variables found.\n"); - return 0; + return 1; + } } // Make sure we wrote everything... @@ -1606,7 +1656,7 @@ static int cmd_config(int argc, char *argv[]) { if(action < 0 && !removed) { remove(tmpfile); fprintf(stderr, "No configuration variables deleted.\n"); - return *value != 0; + return 1; } // Replace the configuration file with the new one @@ -1628,18 +1678,6 @@ static int cmd_config(int argc, char *argv[]) { return 0; } -bool check_id(const char *name) { - if(!name || !*name) - return false; - - for(int i = 0; i < strlen(name); i++) { - if(!isalnum(name[i]) && name[i] != '_') - return false; - } - - return true; -} - static bool try_bind(int port) { struct addrinfo *ai = NULL; struct addrinfo hint = { @@ -1710,8 +1748,7 @@ static int cmd_init(int argc, char *argv[]) { } else if(argc < 2) { if(tty) { char buf[1024]; - fprintf(stdout, "Enter the Name you want your tinc node to have: "); - fflush(stdout); + fprintf(stderr, "Enter the Name you want your tinc node to have: "); if(!fgets(buf, sizeof buf, stdin)) { fprintf(stderr, "Error while reading stdin: %s\n", strerror(errno)); return 1; @@ -1763,7 +1800,7 @@ static int cmd_init(int argc, char *argv[]) { fprintf(f, "Name = %s\n", name); fclose(f); - if(!rsa_keygen(2048, false) || !ecdsa_keygen(false)) + if(!rsa_keygen(2048, false) || !ed25519_keygen(false)) return 1; check_port(name); @@ -1777,7 +1814,7 @@ static int cmd_init(int argc, char *argv[]) { fprintf(stderr, "Could not create file %s: %s\n", filename, strerror(errno)); return 1; } - fprintf(f, "#!/bin/sh\n\necho 'Unconfigured tinc-up script, please edit!'\n\n#ifconfig $INTERFACE netmask \n"); + fprintf(f, "#!/bin/sh\n\necho 'Unconfigured tinc-up script, please edit '$0'!'\n\n#ifconfig $INTERFACE netmask \n"); fclose(f); } #endif @@ -1795,7 +1832,7 @@ static int cmd_generate_keys(int argc, char *argv[]) { if(!name) name = get_my_name(false); - return !(rsa_keygen(argc > 1 ? atoi(argv[1]) : 2048, true) && ecdsa_keygen(true)); + return !(rsa_keygen(argc > 1 ? atoi(argv[1]) : 2048, true) && ed25519_keygen(true)); } static int cmd_generate_rsa_keys(int argc, char *argv[]) { @@ -1810,7 +1847,7 @@ static int cmd_generate_rsa_keys(int argc, char *argv[]) { return !rsa_keygen(argc > 1 ? atoi(argv[1]) : 2048, true); } -static int cmd_generate_ecdsa_keys(int argc, char *argv[]) { +static int cmd_generate_ed25519_keys(int argc, char *argv[]) { if(argc > 1) { fprintf(stderr, "Too many arguments!\n"); return 1; @@ -1819,7 +1856,7 @@ static int cmd_generate_ecdsa_keys(int argc, char *argv[]) { if(!name) name = get_my_name(false); - return !ecdsa_keygen(true); + return !ed25519_keygen(true); } static int cmd_help(int argc, char *argv[]) { @@ -2067,6 +2104,72 @@ static int cmd_exchange_all(int argc, char *argv[]) { return cmd_export_all(argc, argv) ?: cmd_import(argc, argv); } +static int switch_network(char *name) { + if(fd >= 0) { + close(fd); + fd = -1; + } + + free(confbase); + confbase = NULL; + free(pidfilename); + pidfilename = NULL; + free(logfilename); + logfilename = NULL; + free(unixsocketname); + unixsocketname = NULL; + free(tinc_conf); + free(hosts_dir); + free(prompt); + + free(netname); + netname = strcmp(name, ".") ? xstrdup(name) : NULL; + + make_names(); + xasprintf(&tinc_conf, "%s" SLASH "tinc.conf", confbase); + xasprintf(&hosts_dir, "%s" SLASH "hosts", confbase); + xasprintf(&prompt, "%s> ", identname); + + return 0; +} + +static int cmd_network(int argc, char *argv[]) { + if(argc > 2) { + fprintf(stderr, "Too many arguments!\n"); + return 1; + } + + if(argc == 2) + return switch_network(argv[1]); + + DIR *dir = opendir(confdir); + if(!dir) { + fprintf(stderr, "Could not read directory %s: %s\n", confdir, strerror(errno)); + return 1; + } + + struct dirent *ent; + while((ent = readdir(dir))) { + if(*ent->d_name == '.') + continue; + + if(!strcmp(ent->d_name, "tinc.conf")) { + printf(".\n"); + continue; + } + + char *fname; + xasprintf(&fname, "%s/%s/tinc.conf", confdir, ent->d_name); + if(!access(fname, R_OK)) + printf("%s\n", ent->d_name); + free(fname); + } + + closedir(dir); + + return 0; +} + static const struct { const char *command; int (*function)(int argc, char *argv[]); @@ -2094,7 +2197,7 @@ static const struct { {"init", cmd_init}, {"generate-keys", cmd_generate_keys}, {"generate-rsa-keys", cmd_generate_rsa_keys}, - {"generate-ecdsa-keys", cmd_generate_ecdsa_keys}, + {"generate-ed25519-keys", cmd_generate_ed25519_keys}, {"help", cmd_help}, {"version", cmd_version}, {"info", cmd_info}, @@ -2106,6 +2209,7 @@ static const struct { {"exchange-all", cmd_exchange_all}, {"invite", cmd_invite}, {"join", cmd_join}, + {"network", cmd_network}, {NULL, NULL}, }; @@ -2232,7 +2336,6 @@ static char **completion (const char *text, int start, int end) { #endif static int cmd_shell(int argc, char *argv[]) { - char *prompt; xasprintf(&prompt, "%s> ", identname); int result = 0; char buf[4096]; @@ -2336,6 +2439,7 @@ int main(int argc, char *argv[]) { program_name = argv[0]; orig_argv = argv; orig_argc = argc; + tty = isatty(0) && isatty(1); if(!parse_options(argc, argv)) return 1; @@ -2366,8 +2470,6 @@ int main(int argc, char *argv[]) { srand(time(NULL)); crypto_init(); - tty = isatty(0) && isatty(1); - if(optind >= argc) return cmd_shell(argc, argv); diff --git a/src/tincd.c b/src/tincd.c index 84036ad..15cddb1 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-2013 Guus Sliepen + 2000-2014 Guus Sliepen 2008 Max Rijevski 2009 Michael Tokarev 2010 Julien Muchembled @@ -49,6 +49,7 @@ #include "control.h" #include "crypto.h" #include "device.h" +#include "event.h" #include "logger.h" #include "names.h" #include "net.h" @@ -57,6 +58,7 @@ #include "protocol.h" #include "utils.h" #include "xalloc.h" +#include "version.h" /* If nonzero, display usage information and exit. */ static bool show_help = false; @@ -106,7 +108,6 @@ static struct option const long_options[] = { #ifdef HAVE_MINGW static struct WSAData wsa_state; -CRITICAL_SECTION mutex; int main2(int argc, char **argv); #endif @@ -303,6 +304,17 @@ static bool drop_privs(void) { #ifdef HAVE_MINGW # define setpriority(level) !SetPriorityClass(GetCurrentProcess(), (level)) + +static void stop_handler(void *data, int flags) { + event_exit(); +} + +static BOOL WINAPI console_ctrl_handler(DWORD type) { + logger(DEBUG_ALWAYS, LOG_NOTICE, "Got console shutdown request"); + if (WSASetEvent(stop_io.event) == FALSE) + abort(); + return TRUE; +} #else # define NORMAL_PRIORITY_CLASS 0 # define BELOW_NORMAL_PRIORITY_CLASS 10 @@ -320,8 +332,8 @@ int main(int argc, char **argv) { if(show_version) { printf("%s version %s (built %s %s, protocol %d.%d)\n", PACKAGE, - VERSION, __DATE__, __TIME__, PROT_MAJOR, PROT_MINOR); - printf("Copyright (C) 1998-2013 Ivo Timmermans, Guus Sliepen and others.\n" + VERSION, BUILD_DATE, BUILD_TIME, PROT_MAJOR, PROT_MINOR); + printf("Copyright (C) 1998-2014 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" @@ -371,15 +383,24 @@ int main(int argc, char **argv) { #endif #ifdef HAVE_MINGW - if(!do_detach || !init_service()) - return main2(argc, argv); - else - return 1; + io_add_event(&stop_io, stop_handler, NULL, WSACreateEvent()); + if (stop_io.event == FALSE) + abort(); + + int result; + if(!do_detach || !init_service()) { + SetConsoleCtrlHandler(console_ctrl_handler, TRUE); + result = main2(argc, argv); + } else + result = 1; + + if (WSACloseEvent(stop_io.event) == FALSE) + abort(); + io_del(&stop_io); + return result; } int main2(int argc, char **argv) { - InitializeCriticalSection(&mutex); - EnterCriticalSection(&mutex); #endif char *priority = NULL; @@ -440,9 +461,6 @@ int main2(int argc, char **argv) { /* Shutdown properly. */ - if(debug_level >= DEBUG_CONNECTIONS) - devops.dump_stats(); - end: close_network_connections(); diff --git a/src/top.c b/src/top.c index b1ab40c..40b8047 100644 --- a/src/top.c +++ b/src/top.c @@ -21,6 +21,7 @@ #ifdef HAVE_CURSES +#undef KEY_EVENT /* There are conflicting declarations for KEY_EVENT in Windows wincon.h and curses.h. */ #include #include "control_common.h" @@ -66,8 +67,10 @@ static float bscale = 1; static const char *punit = "pkts"; static float pscale = 1; -static void update(int fd) { - sendline(fd, "%d %d", CONTROL, REQ_DUMP_TRAFFIC); +static bool update(int fd) { + if(!sendline(fd, "%d %d", CONTROL, REQ_DUMP_TRAFFIC)) + return false; + gettimeofday(&cur, NULL); timersub(&cur, &prev, &diff); @@ -90,13 +93,10 @@ static void update(int fd) { int n = sscanf(line, "%d %d %s %"PRIu64" %"PRIu64" %"PRIu64" %"PRIu64, &code, &req, name, &in_packets, &in_bytes, &out_packets, &out_bytes); if(n == 2) - break; + return true; - if(n != 7) { - endwin(); - fprintf(stderr, "Error receiving traffic information\n"); - exit(1); - } + if(n != 7) + return false; nodestats_t *found = NULL; @@ -133,6 +133,8 @@ static void update(int fd) { found->out_packets = out_packets; found->out_bytes = out_bytes; } + + return false; } static int cmpfloat(float a, float b) { @@ -213,7 +215,8 @@ static void redraw(void) { for(int i = 0; i < n; i++) sorted[i]->i = i; - qsort(sorted, n, sizeof *sorted, sortfunc); + if(sorted) + qsort(sorted, n, sizeof *sorted, sortfunc); for(int i = 0, row = 3; i < n; i++, row++) { nodestats_t *node = sorted[i]; @@ -245,7 +248,9 @@ void top(int fd) { bool running = true; while(running) { - update(fd); + if(!update(fd)) + break; + redraw(); switch(getch()) { diff --git a/src/uml_device.c b/src/uml_device.c index d06832b..57d4843 100644 --- a/src/uml_device.c +++ b/src/uml_device.c @@ -38,9 +38,6 @@ static int write_fd = -1; static int state = 0; static char *device_info; -static uint64_t device_total_in = 0; -static uint64_t device_total_out = 0; - enum request_type { REQ_NEW_CONTROL }; static struct request { @@ -159,22 +156,29 @@ static bool setup_device(void) { } void close_device(void) { - if(listen_fd >= 0) - close(listen_fd); + if(listen_fd >= 0) { + close(listen_fd); listen_fd = -1; + } - if(request_fd >= 0) - close(request_fd); + if(request_fd >= 0) { + close(request_fd); request_fd = -1; + } - if(data_fd >= 0) - close(data_fd); + if(data_fd >= 0) { + close(data_fd); data_fd = -1; + } - if(write_fd >= 0) - close(write_fd); + if(write_fd >= 0) { + close(write_fd); write_fd = -1; + } unlink(device); - free(device); - if(iface) free(iface); + free(device); device = NULL; + if(iface) { + free(iface); iface = NULL; + } + device_info = NULL; } static bool read_packet(vpn_packet_t *packet) { @@ -240,7 +244,7 @@ static bool read_packet(vpn_packet_t *packet) { } case 2: { - if((inlen = read(data_fd, packet->data, MTU)) <= 0) { + if((inlen = read(data_fd, DATA(packet), MTU)) <= 0) { logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info, device, strerror(errno)); event_exit(); @@ -249,8 +253,6 @@ static bool read_packet(vpn_packet_t *packet) { packet->len = inlen; - device_total_in += packet->len; - logger(DEBUG_TRAFFIC, LOG_DEBUG, "Read packet of %d bytes from %s", packet->len, device_info); @@ -273,7 +275,7 @@ static bool write_packet(vpn_packet_t *packet) { logger(DEBUG_TRAFFIC, LOG_DEBUG, "Writing packet of %d bytes to %s", packet->len, device_info); - if(write(write_fd, packet->data, packet->len) < 0) { + if(write(write_fd, DATA(packet), packet->len) < 0) { if(errno != EINTR && errno != EAGAIN) { logger(DEBUG_ALWAYS, LOG_ERR, "Can't write to %s %s: %s", device_info, device, strerror(errno)); event_exit(); @@ -282,21 +284,12 @@ static bool write_packet(vpn_packet_t *packet) { return false; } - device_total_out += packet->len; - return true; } -static void dump_device_stats(void) { - logger(DEBUG_ALWAYS, LOG_DEBUG, "Statistics for %s %s:", device_info, device); - logger(DEBUG_ALWAYS, LOG_DEBUG, " total bytes in: %10"PRIu64, device_total_in); - logger(DEBUG_ALWAYS, LOG_DEBUG, " total bytes out: %10"PRIu64, device_total_out); -} - const devops_t uml_devops = { .setup = setup_device, .close = close_device, .read = read_packet, .write = write_packet, - .dump_stats = dump_device_stats, }; diff --git a/src/utils.c b/src/utils.c index edaa354..65ba4b9 100644 --- a/src/utils.c +++ b/src/utils.c @@ -18,10 +18,10 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +#include "logger.h" #include "system.h" - -#include "../src/logger.h" #include "utils.h" +#include "xalloc.h" static const char hexadecimals[] = "0123456789ABCDEF"; static const char base64_original[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; @@ -52,14 +52,16 @@ static int charhex2bin(char c) { return toupper(c) - 'A' + 10; } -int hex2bin(const char *src, char *dst, int length) { +int hex2bin(const char *src, void *vdst, int length) { + char *dst = vdst; int i; for(i = 0; i < length && isxdigit(src[i * 2]) && isxdigit(src[i * 2 + 1]); i++) dst[i] = charhex2bin(src[i * 2]) * 16 + charhex2bin(src[i * 2 + 1]); return i; } -int bin2hex(const char *src, char *dst, int length) { +int bin2hex(const void *vsrc, char *dst, int length) { + const char *src = vsrc; for(int i = length - 1; i >= 0; i--) { dst[i * 2 + 1] = hexadecimals[(unsigned char) src[i] & 15]; dst[i * 2] = hexadecimals[(unsigned char) src[i] >> 4]; @@ -68,12 +70,12 @@ int bin2hex(const char *src, char *dst, int length) { return length * 2; } -int b64decode(const char *src, char *dst, int length) { +int b64decode(const char *src, void *dst, int length) { int i; uint32_t triplet = 0; unsigned char *udst = (unsigned char *)dst; - for(i = 0; i < length / 3 * 4 && src[i]; i++) { + for(i = 0; i < length && src[i]; i++) { triplet |= base64_decode[src[i] & 0xff] << (6 * (i & 3)); if((i & 3) == 3) { if(triplet & 0xff000000U) @@ -99,7 +101,7 @@ int b64decode(const char *src, char *dst, int length) { } } -static int b64encode_internal(const char *src, char *dst, int length, const char *alphabet) { +static int b64encode_internal(const void *src, char *dst, int length, const char *alphabet) { uint32_t triplet; const unsigned char *usrc = (unsigned char *)src; int si = length / 3 * 3; @@ -112,14 +114,14 @@ static int b64encode_internal(const char *src, char *dst, int length, const char dst[di + 1] = alphabet[triplet & 63]; triplet >>= 6; dst[di + 2] = alphabet[triplet]; dst[di + 3] = 0; - length = di + 2; + length = di + 3; break; case 1: triplet = usrc[si]; dst[di] = alphabet[triplet & 63]; triplet >>= 6; dst[di + 1] = alphabet[triplet]; dst[di + 2] = 0; - length = di + 1; + length = di + 2; break; default: dst[di] = 0; @@ -140,11 +142,11 @@ static int b64encode_internal(const char *src, char *dst, int length, const char return length; } -int b64encode(const char *src, char *dst, int length) { +int b64encode(const void *src, char *dst, int length) { return b64encode_internal(src, dst, length, base64_original); } -int b64encode_urlsafe(const char *src, char *dst, int length) { +int b64encode_urlsafe(const void *src, char *dst, int length) { return b64encode_internal(src, dst, length, base64_urlsafe); } @@ -177,3 +179,54 @@ unsigned int bitfield_to_int(const void *bitfield, size_t size) { memcpy(&value, bitfield, size); return value; } + +bool check_id(const char *id) { + if(!id || !*id) + return false; + + for(; *id; id++) + if(!isalnum(*id) && *id != '_') + return false; + + return true; +} + +/* Windows doesn't define HOST_NAME_MAX. */ +#ifndef HOST_NAME_MAX +#define HOST_NAME_MAX 255 +#endif + +char *replace_name(const char *name) { + char *ret_name; + + if (name[0] == '$') { + char *envname = getenv(name + 1); + char hostname[HOST_NAME_MAX+1]; + if (!envname) { + if (strcmp(name + 1, "HOST")) { + logger(DEBUG_ALWAYS, LOG_ERR, "Invalid Name: environment variable %s does not exist\n", name + 1); + return NULL; + } + if (gethostname(hostname, sizeof hostname) || !*hostname) { + logger(DEBUG_ALWAYS, LOG_ERR, "Could not get hostname: %s\n", sockstrerror(sockerrno)); + return NULL; + } + hostname[HOST_NAME_MAX] = 0; + envname = hostname; + } + ret_name = xstrdup(envname); + for (char *c = ret_name; *c; c++) + if (!isalnum(*c)) + *c = '_'; + } else { + ret_name = xstrdup(name); + } + + if (!check_id(ret_name)) { + logger(DEBUG_ALWAYS, LOG_ERR, "Invalid name for myself!"); + free(ret_name); + return NULL; + } + + return ret_name; +} diff --git a/src/utils.h b/src/utils.h index 85d6bf2..c3364ce 100644 --- a/src/utils.h +++ b/src/utils.h @@ -21,12 +21,12 @@ #ifndef __TINC_UTILS_H__ #define __TINC_UTILS_H__ -extern int hex2bin(const char *src, char *dst, int length); -extern int bin2hex(const char *src, char *dst, int length); +extern int hex2bin(const char *src, void *dst, int length); +extern int bin2hex(const void *src, char *dst, int length); -extern int b64encode(const char *src, char *dst, int length); -extern int b64encode_urlsafe(const char *src, char *dst, int length); -extern int b64decode(const char *src, char *dst, int length); +extern int b64encode(const void *src, char *dst, int length); +extern int b64encode_urlsafe(const void *src, char *dst, int length); +extern int b64decode(const char *src, void *dst, int length); #ifdef HAVE_MINGW extern const char *winerror(int); @@ -37,6 +37,7 @@ extern const char *winerror(int); #define sockmsgsize(x) ((x) == WSAEMSGSIZE) #define sockinprogress(x) ((x) == WSAEINPROGRESS || (x) == WSAEWOULDBLOCK) #define sockinuse(x) ((x) == WSAEADDRINUSE) +#define socknotconn(x) ((x) == WSAENOTCONN) #else #define sockerrno errno #define sockstrerror(x) strerror(x) @@ -44,8 +45,12 @@ extern const char *winerror(int); #define sockmsgsize(x) ((x) == EMSGSIZE) #define sockinprogress(x) ((x) == EINPROGRESS) #define sockinuse(x) ((x) == EADDRINUSE) +#define socknotconn(x) ((x) == ENOTCONN) #endif extern unsigned int bitfield_to_int(const void *bitfield, size_t size); +extern bool check_id(const char *); +char *replace_name(const char *name); + #endif /* __TINC_UTILS_H__ */ diff --git a/src/vde_device.c b/src/vde_device.c index 446ca16..73ad713 100644 --- a/src/vde_device.c +++ b/src/vde_device.c @@ -36,9 +36,6 @@ static int port = 0; static char *group = NULL; static char *device_info; -static uint64_t device_total_in = 0; -static uint64_t device_total_out = 0; - static bool setup_device(void) { libvdeplug_dynopen(plug); @@ -85,19 +82,22 @@ static bool setup_device(void) { } static void close_device(void) { - if(conn) - plug.vde_close(conn); + if(conn) { + plug.vde_close(conn); conn = NULL; + } if(plug.dl_handle) libvdeplug_dynclose(plug); - free(device); + free(device); device = NULL; - free(iface); + free(iface); iface = NULL; + + device_info = NULL; } static bool read_packet(vpn_packet_t *packet) { - int lenin = (ssize_t)plug.vde_recv(conn, packet->data, MTU, 0); + int lenin = (ssize_t)plug.vde_recv(conn, DATA(packet), MTU, 0); if(lenin <= 0) { logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info, device, strerror(errno)); event_exit(); @@ -105,14 +105,14 @@ static bool read_packet(vpn_packet_t *packet) { } packet->len = lenin; - device_total_in += packet->len; + logger(DEBUG_TRAFFIC, LOG_DEBUG, "Read packet of %d bytes from %s", packet->len, device_info); return true; } static bool write_packet(vpn_packet_t *packet) { - if((ssize_t)plug.vde_send(conn, packet->data, packet->len, 0) < 0) { + if((ssize_t)plug.vde_send(conn, DATA(packet), packet->len, 0) < 0) { if(errno != EINTR && errno != EAGAIN) { logger(DEBUG_ALWAYS, LOG_ERR, "Can't write to %s %s: %s", device_info, device, strerror(errno)); event_exit(); @@ -121,21 +121,12 @@ static bool write_packet(vpn_packet_t *packet) { return false; } - device_total_out += packet->len; - return true; } -static void dump_device_stats(void) { - logger(DEBUG_ALWAYS, LOG_DEBUG, "Statistics for %s %s:", device_info, device); - logger(DEBUG_ALWAYS, LOG_DEBUG, " total bytes in: %10"PRIu64, device_total_in); - logger(DEBUG_ALWAYS, LOG_DEBUG, " total bytes out: %10"PRIu64, device_total_out); -} - const devops_t vde_devops = { .setup = setup_device, .close = close_device, .read = read_packet, .write = write_packet, - .dump_stats = dump_device_stats, }; diff --git a/src/version.c b/src/version.c new file mode 100644 index 0000000..fc62c8a --- /dev/null +++ b/src/version.c @@ -0,0 +1,24 @@ +/* + version.c -- version information + Copyright (C) 2014 Etienne Dechamps + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "version.h" + +/* This file is always rebuilt (even if there are no changes) so that the following is updated */ +const char* const BUILD_DATE = __DATE__; +const char* const BUILD_TIME = __TIME__; diff --git a/src/version.h b/src/version.h new file mode 100644 index 0000000..d3e4a1f --- /dev/null +++ b/src/version.h @@ -0,0 +1,26 @@ +/* + version.h -- header for version.c + Copyright (C) 2014 Etienne Dechamps + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#ifndef __TINC_VERSION_H__ +#define __TINC_VERSION_H__ + +extern const char* const BUILD_DATE; +extern const char* const BUILD_TIME; + +#endif /* __TINC_VERSION_H__ */ diff --git a/test-driver b/test-driver index 32bf39e..d306056 100755 --- a/test-driver +++ b/test-driver @@ -1,7 +1,7 @@ #! /bin/sh # test-driver - basic testsuite driver script. -scriptversion=2012-06-27.10; # UTC +scriptversion=2013-07-13.22; # UTC # Copyright (C) 2011-2013 Free Software Foundation, Inc. # @@ -44,13 +44,12 @@ print_usage () Usage: test-driver --test-name=NAME --log-file=PATH --trs-file=PATH [--expect-failure={yes|no}] [--color-tests={yes|no}] - [--enable-hard-errors={yes|no}] [--] TEST-SCRIPT + [--enable-hard-errors={yes|no}] [--] + TEST-SCRIPT [TEST-SCRIPT-ARGUMENTS] The '--test-name', '--log-file' and '--trs-file' options are mandatory. END } -# TODO: better error handling in option parsing (in particular, ensure -# TODO: $log_file, $trs_file and $test_name are defined). test_name= # Used for reporting. log_file= # Where to save the output of the test script. trs_file= # Where to save the metadata of the test run. @@ -69,10 +68,23 @@ while test $# -gt 0; do --enable-hard-errors) enable_hard_errors=$2; shift;; --) shift; break;; -*) usage_error "invalid option: '$1'";; + *) break;; esac shift done +missing_opts= +test x"$test_name" = x && missing_opts="$missing_opts --test-name" +test x"$log_file" = x && missing_opts="$missing_opts --log-file" +test x"$trs_file" = x && missing_opts="$missing_opts --trs-file" +if test x"$missing_opts" != x; then + usage_error "the following mandatory options are missing:$missing_opts" +fi + +if test $# -eq 0; then + usage_error "missing argument" +fi + if test $color_tests = yes; then # Keep this in sync with 'lib/am/check.am:$(am__tty_colors)'. red='' # Red. diff --git a/test/Makefile.am b/test/Makefile.am index a9c3895..5457b2f 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -4,6 +4,7 @@ TESTS = \ executables.test \ import-export.test \ invite-join.test \ + ns-ping.test \ ping.test \ sptps-basic.test \ variables.test diff --git a/test/Makefile.in b/test/Makefile.in index c6421fa..cdea11e 100644 --- a/test/Makefile.in +++ b/test/Makefile.in @@ -1,4 +1,4 @@ -# Makefile.in generated by automake 1.14 from Makefile.am. +# Makefile.in generated by automake 1.14.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. @@ -84,9 +84,12 @@ DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(top_srcdir)/test-driver ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \ - $(top_srcdir)/m4/curses.m4 $(top_srcdir)/m4/lzo.m4 \ - $(top_srcdir)/m4/openssl.m4 $(top_srcdir)/m4/readline.m4 \ - $(top_srcdir)/m4/zlib.m4 $(top_srcdir)/configure.ac + $(top_srcdir)/m4/ax_check_compile_flag.m4 \ + $(top_srcdir)/m4/ax_check_link_flag.m4 \ + $(top_srcdir)/m4/curses.m4 $(top_srcdir)/m4/libgcrypt.m4 \ + $(top_srcdir)/m4/lzo.m4 $(top_srcdir)/m4/openssl.m4 \ + $(top_srcdir)/m4/readline.m4 $(top_srcdir)/m4/zlib.m4 \ + $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d @@ -381,9 +384,6 @@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ -LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ -LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ -LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LN_S = @LN_S@ @@ -399,7 +399,6 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ -RANLIB = @RANLIB@ READLINE_LIBS = @READLINE_LIBS@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ @@ -461,6 +460,7 @@ TESTS = \ executables.test \ import-export.test \ invite-join.test \ + ns-ping.test \ ping.test \ sptps-basic.test \ variables.test diff --git a/test/commandline.test b/test/commandline.test index e95c953..157eb54 100755 --- a/test/commandline.test +++ b/test/commandline.test @@ -44,6 +44,7 @@ $tinc $c1 --net foo get name # Test tinc command line options that should not work +$tinc $c1 -n foo get somethingreallyunknown && exit 1 || true $tinc $c1 --net && exit 1 || true $tinc $c1 --net get name && exit 1 || true $tinc $c1 foo && exit 1 || true diff --git a/test/ns-ping.test b/test/ns-ping.test new file mode 100755 index 0000000..d5f9c7f --- /dev/null +++ b/test/ns-ping.test @@ -0,0 +1,70 @@ +#!/bin/sh + +. ./testlib.sh + +# Skip this test if we aren't root or if "ip netns" does not exist + +test "`id -u`" = "0" || exit 77 +ip netns list || exit 77 + +# Initialize two nodes + +$tinc $c1 <$d1/tinc-up <$d2/tinc-up < Date: Mon, 26 Aug 2019 13:44:52 +0200 Subject: [PATCH 09/13] Import Upstream version 1.1~pre12 --- COPYING | 2 +- COPYING.README | 20 +- ChangeLog | 301 +++++++ Makefile.am | 16 +- Makefile.in | 76 +- NEWS | 1299 +++++++++++++---------------- README | 36 +- README.android | 35 +- THANKS | 26 +- aclocal.m4 | 56 +- compile | 2 +- config.guess | 47 +- config.h.in | 125 +-- config.sub | 36 +- configure | 1045 ++++++++++------------- configure.ac | 124 +-- depcomp | 2 +- doc/Makefile.am | 22 +- doc/Makefile.in | 53 +- doc/sample-config.tar.gz | Bin 1237 -> 1237 bytes doc/tinc.8.in | 45 +- doc/tinc.conf.5.in | 73 +- doc/tinc.info | 844 +++++++++++++------ doc/tinc.texi | 386 +++++++-- doc/tincd.8.in | 7 +- gui/Makefile.in | 33 +- gui/tinc-gui | 964 ++++++++++----------- install-sh | 361 ++++---- m4/Makefile.am | 4 - m4/README | 8 - m4/attribute.m4 | 4 +- m4/miniupnpc.m4 | 40 + m4/openssl.m4 | 18 +- missing | 2 +- src/Makefile.am | 111 ++- src/Makefile.in | 511 +++++++----- src/bsd/device.c | 156 +++- src/cipher.h | 5 + src/conf.c | 39 +- src/conf.h | 4 +- src/connection.c | 4 +- src/connection.h | 8 +- src/cygwin/device.c | 5 +- src/digest.h | 4 + src/dropin.c | 45 +- src/dropin.h | 17 +- src/ed25519/ecdsa.c | 9 +- src/ed25519/fe.c | 274 +++--- src/ed25519/fixedint.h | 21 + src/ed25519/ge.c | 4 +- src/ed25519/precomp_data.h | 2 +- src/ed25519/sc.c | 284 +++---- src/ed25519/sc.h | 2 +- src/ed25519/sha512.c | 144 ++-- src/ed25519/sha512.h | 8 +- src/edge.c | 1 + src/ethernet.h | 6 +- src/event.c | 10 + src/fake-gai-errnos.h | 23 - src/fake-getaddrinfo.c | 102 --- src/fake-getaddrinfo.h | 46 - src/fake-getnameinfo.c | 54 -- src/fake-getnameinfo.h | 15 - src/fsck.c | 498 +++++++++++ src/{gcrypt/ecdh.c => fsck.h} | 23 +- src/gcrypt/ecdsa.c | 67 -- src/gcrypt/prf.c | 85 +- src/graph.c | 9 +- src/hash.c | 2 +- src/have.h | 42 +- src/ifconfig.c | 198 +++++ src/ifconfig.h | 31 + src/invitation.c | 255 ++++-- src/ipv4.h | 4 +- src/ipv6.h | 33 +- src/linux/device.c | 3 + src/list.h | 6 + src/logger.c | 27 +- src/logger.h | 1 + src/meta.c | 55 +- src/meta.h | 1 + src/mingw/device.c | 67 +- src/multicast_device.c | 4 +- src/names.c | 56 +- src/names.h | 4 +- src/net.c | 32 +- src/net.h | 16 +- src/net_packet.c | 1122 +++++++++++++++++-------- src/net_setup.c | 93 ++- src/net_socket.c | 67 +- src/netutl.c | 16 +- src/node.c | 67 +- src/node.h | 25 +- src/nolegacy/crypto.c | 87 ++ src/nolegacy/prf.c | 106 +++ src/openssl/cipher.c | 7 + src/process.c | 27 +- src/protocol.c | 7 +- src/protocol.h | 11 +- src/protocol_auth.c | 40 +- src/protocol_edge.c | 83 +- src/protocol_key.c | 126 ++- src/protocol_misc.c | 233 ++++++ src/route.c | 512 +++++++----- src/script.c | 78 +- src/splay_tree.h | 6 + src/sptps.c | 167 ++-- src/sptps.h | 2 +- src/sptps_keypair.c | 8 +- src/sptps_speed.c | 29 +- src/sptps_test.c | 39 +- src/subnet.c | 6 +- src/subnet.h | 3 +- src/subnet_parse.c | 5 +- src/system.h | 12 +- src/tincctl.c | 592 +++++++++++-- src/tincctl.h | 4 +- src/tincd.c | 47 +- src/upnp.c | 164 ++++ src/{gcrypt/ecdsagen.c => upnp.h} | 28 +- src/utils.c | 18 +- src/utils.h | 1 + src/version.c | 7 + src/version.h | 1 + systemd/Makefile.am | 4 + {m4 => systemd}/Makefile.in | 117 ++- systemd/tinc.service | 20 + systemd/tinc@.service | 19 + test-driver | 15 +- test/Makefile.am | 1 + test/Makefile.in | 40 +- test/invite-join.test | 2 +- test/invite-tinc-up.test | 51 ++ test/variables.test | 2 - 134 files changed, 8673 insertions(+), 4989 deletions(-) delete mode 100644 m4/Makefile.am delete mode 100644 m4/README create mode 100644 m4/miniupnpc.m4 delete mode 100644 src/fake-gai-errnos.h delete mode 100644 src/fake-getaddrinfo.c delete mode 100644 src/fake-getaddrinfo.h delete mode 100644 src/fake-getnameinfo.c delete mode 100644 src/fake-getnameinfo.h create mode 100644 src/fsck.c rename src/{gcrypt/ecdh.c => fsck.h} (60%) delete mode 100644 src/gcrypt/ecdsa.c create mode 100644 src/ifconfig.c create mode 100644 src/ifconfig.h create mode 100644 src/nolegacy/crypto.c create mode 100644 src/nolegacy/prf.c create mode 100644 src/upnp.c rename src/{gcrypt/ecdsagen.c => upnp.h} (57%) create mode 100644 systemd/Makefile.am rename {m4 => systemd}/Makefile.in (73%) create mode 100644 systemd/tinc.service create mode 100644 systemd/tinc@.service create mode 100755 test/invite-tinc-up.test diff --git a/COPYING b/COPYING index c3d1ceb..513da31 100644 --- a/COPYING +++ b/COPYING @@ -1,4 +1,4 @@ -Copyright (C) 1998-2014 Ivo Timmermans, Guus Sliepen and others. +Copyright (C) 1998-2016 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 2eb9c1f..166102b 100644 --- a/COPYING.README +++ b/COPYING.README @@ -1,19 +1,17 @@ The following applies to tinc: -This program is released under the GPL with the additional exemption that -compiling, linking, and/or using OpenSSL is allowed. You may provide binary -packages linked to the OpenSSL libraries, provided that all other requirements -of the GPL are met. +> This program is released under the GPL with the additional exemption that +> compiling, linking, and/or using OpenSSL is allowed. You may provide binary +> packages linked to the OpenSSL libraries, provided that all other requirements +> of the GPL are met. The following applies to the LZO library: - Hereby I grant a special exception to the tinc VPN project - (http://tinc.nl.linux.org/) to link the LZO library with the OpenSSL library - (http://www.openssl.org). - - Markus F.X.J. Oberhumer +> Hereby I grant a special exception to the tinc VPN project +> (https://www.tinc-vpn.org/) to link the LZO library with the OpenSSL library +> (https://openssl.org). +> +> Markus F.X.J. Oberhumer 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 b2faf52..40b3bfb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,304 @@ +Version 1.1pre12 April 24 2016 +------------------------------------------------------------------------ + +Guus Sliepen (166): + Allow tinc to be compiled without OpenSSL. + Add missing nolegacy/crypto.c and prf.c. + Fixes for bugs in src/Makefile.am and tincctl.c introduced by cfe9285adf391ab66faeb5def811fe08e47a221a. + Fix indentation and some whitespace issues. + Use void pointers for opaque data blobs in the SHA512 code. + Use global "now" in try_udp() and try_mtu(). + Remember whether we sent our key to another node. + Try to clarify the new code in net_packet.c a bit. + Correctly estimate the initial MTU for legacy packets. + Fix size of type 2 probe replies. + Proactively send our own key when we request another node's key. + Don't send probe replies if we don't have the other's key. + Fix segfault when sptps_test cannot open the key files. + Always keep UDP mappings alive for nodes that also have a meta-connection. + Immediately send our key when a meta-connection is established. + Only send small packets during UDP probes. + Remove RTT and packet loss estimation code. + Send MTU probes only once every PingInterval. + Move detection of PMTU decrease to try_mtu(). + Keep track of the largest UDP packet size received from a node. + Move UDP probe reply code into its own function. + Send the size of the largest recently received packets in type 2 probe replies. + Send gratuitous type 2 probe replies. + Improve packet source detection. + Add the "fsck" command to the CLI. + Always call res_init() before getaddrinfo(). + Make "tinc add" idempotent. + Document that --force should precede commands. + Suppress warnings about parsing Ed25519 keys when they are not present. + Merge remote-tracking branch 'dechamps/sptpsabort' into 1.1 + Merge remote-tracking branch 'seehuhn/1.1' into 1.1 + Fix the case where we detach and use --logfile. + --syslog and --logfile are mutually exclusive. + Merge remote-tracking branch 'dechamps/staticfix' into 1.1 + Merge remote-tracking branch 'dechamps/fsckwin' into 1.1 + Merge remote-tracking branch 'dechamps/winmtu' into 1.1 + Merge remote-tracking branch 'dechamps/windevice' into 1.1 + Always call res_init() before getaddrinfo(). + Merge remote-tracking branch 'dechamps/wintapver' into 1.1 + Allow one-sided upgrades to Ed25519. + Fix a possible segmentation fault during key upgrades. + Don't log an error message when receiving a TERMREQ. + Fix typo 0fda572c88d02b0b200ef81d72cc4da594fa0e38 that prevented some errors from being logged. + Remove "release-" from displayed git version. + Don't include build-time generated version_git.h in the tarball. + Really remove "release-" from the git-derived version string. + Fix invitations. + Fix receiving UDP packets from tinc 1.0.x nodes. + Use AF_UNSPEC instead of AF_UNKNOWN for unspecified local address in add_edge_h(). + Be more liberal accepting ADD_EDGE messages with conflicting local address information. + Try all addresses for the hostname in an invitation URL. + Let sockaddr2str() handle AF_UNSPEC addresses. + Don't send local_address in ADD_EDGE messages if it's AF_UNSPEC. + Merge remote-tracking branches 'dechamps/sptpsrestart' and 'dechamps/keychanged' into 1.1 + Remove info-in-builddir option from AM_INIT_AUTOMAKE(). + Fix src/Makefile.am for *BSD. + Add newline at end of precomp_data.h and sc.h. + Add source of SPTPS errors to log messages. + Don't log seqno failures in sptps_verify_datagram(). + If LOCALSTATEDIR is inaccessible, store the pid and socket files in the configuration directory. + Quit with an error message if ioctl(TUNSETIFF) fails. + Add "list" as an alias for "dump" in the CLI. + Allow dumping a list of outstanding invitations. + Allocate temporary filenames on the stack. + Fix check for LOCALSTATEDIR accessibility for the CLI. + Ensure "tinc start" knows if the daemon really started succesfully. + Don't write log messages to the umbilical pipe if we don't detach. + Use socketpair() instead of pipe() for the umbilical. + Set the CLOEXEC flag on the umbilical socket. + Update copyright notices. + Fix missing return value caused by the previous commit. + Fix autoconf check for function attributes. + Fix warnings about missing return value checks. + Fix receiving SPTPS data in sptps_speed and sptps_test. + Fix alignment of output of sptps_speed. + Fix crash is sptps_logger(). + Don't #include OpenSSL headers when compiling without OpenSSL. + Coalesce two if statements that check for the same thing. + Call sockaddrfree(&e->local_address) in free_edge() instead of exit_edges(). + Fix undefined behaviour when left-shifting signed integers. + Remove unused code that caused warnings about an uninitialized variable. + Use AC_CONFIG_MACRO_DIRS([m4]). + Make subnet caches static. + Fix the PRF function when compiling without OpenSSL. + Use AC_CONFIG_MACRO_DIR() instead of _DIRS(). + In sssp_bfs(), never try to update myself. + Add -I m4 back to ACLOCAL_AMFLAGS. + Optionally install systemd service files. + Replace bare if statements with AS_IF in configure.ac. + Fix struct node_status_t. + Fix a few memory leaks in the CLI found by AddressSanitizer. + Avoid undefined behavior. + Update THANKS file. + Don't leave dead outgoing_t's in the outgoing_list. + list_delete() already free()s the deleted element. + Add support for recvmmsg(). + Use static buffers for recvmmsg(), initialize them only as needed. + Only add a reflexive address when we're sure it's working. + Merge remote-tracking branch 'mweinelt/tinc-gui' into 1.1 + Add the ability to sign and verify files. + Update .gitignore. + Only check for -fno-strict-overflow if -fwrapv does not work. + Use nostdinc instead of overriding DEFAULT_INCLUDES. + Improve performance of edge updates. + Fix forwarding of edge updates. + Clarify that scripts are called synchronously. + Small fixes for the documentation. + Add warnings for bad combinations of Device and Interface. + Fix for botched cherry-pick commit 60fb230. + Fix typo. + Don't compile getopt*.c if the system provides getopt_long(). + Update .gitignore. + Update THANKS. + Use iface instead of interface. + Support ToS/DiffServ for IPv6 meta and UDP connections. + Fix --logfile without a filename on Windows. + Never call putenv() with data on the stack. + Update "now" after connect() when making outgoing connections. + Update support for BSD tun/tap devices, add support for OS X utun interfaces. + Explicitly mention that LibreSSL can be used as well. + Update links in the documentation. + Enable silent builds by default. + Really don't compile getopt*.c if the system provides getopt_long(). + Remove elliptic curve stubs from gcrypt/, add PRF implementation. + Update .gitignore. + Make text files Markdown-compatible. + Remove checks for headers and functions that are in C99. + Fix compiling under MinGW. + Replace usleep() with nanosleep(). + Use getcwd() instead of get_current_dir_name(). + Fix typo in Makefile.am. + Fix version_get.h generation on BSD. + Remove checks for non-C99 compliant compilers. + Remove support for Windows 2000 and anything that doesn't support getaddrinfo(). + Make some platform-specific header checks conditional. + Add version_git.h and sample-config.tar.gz to CLEANFILES. + Don't assume sa.sa_family is a short int. + Remove use of strcpy() and sprintf(). + Don't use HAVE_SYSTEM, the autoconf check was removed. + Fix a non-working cast to get rid of a compiler warning. + Fix generation of version_git.h for some versions of BSD make. + Fix some compiler warnings from MinGW. + Fix conditional checking of tun/tap headers on DragonFly BSD. + Fix crash at startup when Device is not specified on OS X. + Stop using SOL_TCP, SOL_IP and SOL_IPV6. + Document how invitation files work. + Generate a tinc-up script from an invitation. + Move some stray #includes. + Allow gateways to be specified for routes. + Fix gateway parsing in invitation files. + Fix compiler warnings. + Add a test for tinc-up creation from invitations. + Chdir() to the configuration directory instead of /. + Use ifconfig_header(). + Add stricter checks for netnames. + Handle special characters in sptps_test only if the --special option is given. + Don't call terminate_connection(myself->connection). + Speed up AutoConnect at startup. + Fix the "network" command in tinc shell. + Move documentation of invitations to the manual. + Have "tinc fsck" recognize Ed25519PublicKey statements. + Fix possible read of freed memory when verifying the signature of a file. + Fix a compiler warning on Windows. + Fix starting tinc as a service on Windows. + Don't check file permissions on Windows during fsck. + Releasing 1.1pre12. + +Etienne Dechamps (72): + Clarify the send_mtu_probe() function. + Add the try_tx() function. + Move try_sptps() closer to try_tx(). + Add UDP discovery mechanism. + Move responsibility for local discovery to UDP discovery. + Remove PMTU discovery code redundant with UDP discovery. + Move PMTU discovery code into the TX path. + Move try_mtu() closer to try_tx(). + Fix MTU as soon as possible. + Use -1 to identify the post-initial MTU discovery state. + Send one MTU probe at a time. + Remove bandwidth estimation code. + Use a smarter algorithm for choosing MTU discovery probe sizes. + Adjust MTU probe counts. + Don't send MTU probes smaller than 512 bytes. + Add IP_MTU-based maxmtu estimation. + Fine-tune the MTU discovery multiplier for the maxmtu < MTU case. + Recalculate and resend MTU probes if they are too large for the system. + Use a different UDP discovery interval if the tunnel is established. + Fix typo in logging statement. + Fix dynamic UDP SPTPS relaying. + Fix UDP/MTU discovery in intermediate SPTPS UDP relays. + Don't abort() willy-nilly in SPTPS code. + Add UDP_INFO protocol message. + Add MTU_INFO protocol message. + Throttle the rate of UDP_INFO messages. + Throttle the rate of MTU_INFO messages. + Don't send UDP probes past static relays. + Fix invalid getuid() call on Windows. + Fix HAVE_DECL_RES_INIT conditionals. + Make sure packet header structures are correctly packed on Windows. + When disabling the Windows device, wait for pending reads to complete. + Fix Windows device asynchronous write behavior. + Set the default for UDPRcvBuf and UDPSndBuf to 1M. + Increase the ReplayWindow default from 16 to 32. + Log TAP-Windows driver version on startup. + Warn about performance if using TAP-Windows >=9.21. + Use git description as the tinc version. + Use git describe to populate autoconf's VERSION. + Remove explicit distribution rules for m4 scripts. + Add support for out-of-tree ("VPATH") builds. + When relaying, send probes to the destination, not the source. + Use the correct originator node when relaying SPTPS UDP packets. + Expose the raw SPTPS send interface from net_packet. + Try to use UDP to relay SPTPS packets received over TCP. + Rename REQ_SPTPS to SPTPS_PACKET. + Only read one record at a time in sptps_receive_data(). + Introduce raw TCP SPTPS packet transport. + Prevent SPTPS key regeneration packets from entering an UDP relay path. + Trivial: make sptps_receive_data_datagram() a little more readable. + Proactively restart the SPTPS tunnel if we get receive errors. + Don't send KEY_CHANGED messages if we don't support the legacy protocol. + Make sure the MIN() macro is defined. + Don't pollute the system header directory namespace. + Fix SPTPS condition in try_harder(). + Don't parse node IDs if the sending node doesn't support them. + Fix direct UDP communciation with pre-relaying 1.1 nodes. + Fix crashes when trying unreachable nodes. + Don't set up an ongoing connection to myself. + Fix wrong format string type in send_sptps_tcppacket(). + Fix invalid pointer use in get_my_hostname(). + Don't try to relay packets to unreachable nodes. + Protect against callbacks removing items from the io tree. + Use a splay tree for node UDP addresses in order to avoid collisions. + Revert "Cache node IDs in a hash table for faster lookups." + Make sure the packet source MAC address is always set. + Add a new optional dependency on the miniupnpc library. + Add UPnP support to tincd. + Allow tinc to be built with miniupnpc on Windows. + Try to ensure we build correctly against various libminiupnpc versions. + Don't unset validkey when receiving SPTPS handshakes over ANS_KEY. + Add upnp.h to tincd SOURCES. + +thorkill (8): + Fixed 2 leaks in setup_myself() + Cleanup edges stored in edge_weight_tree on exit + Cleanup local_address in protocol_edge.c + Removed double break; + Included missing names.h + Make sure we do not allocate new edge when talking to old nodes and the same edge already exists + Prevent tinc from forgeting e->local_address + Do not access e->to->prevedge if not defined + +Vittorio Gambaletta (VittGam) (6): + Fix DecrementTTL option. + Fix source IP address for ICMP unreachable packets generated by tinc. + Try to reply with node address only when decrementing the TTL. + Fix DecrementTTL option for packets destined to the local node. + s/broadcast_packet_helper/route_broadcast/ + Remove forward declaration for do_decrement_ttl. + +Martin Weinelt (5): + tinc-gui: Reformat codebase according to PEP8 + tinc-gui: Update Node object to correctly parse responses + tinc-gui: Fix GetListCtrl method name in SuperListCtrl + tinc-gui: Use ArgumentParser, default to python2 + tinc-gui: Properly initialize class attributes for VPN in __init__ + +Sven-Haegar Koch (3): + Fixed variables.test testsuite after 'Make "tinc add" idempotent.' change. + Let sockaddr2hostname() handle AF_UNSPEC addresses. + Fix check for public key in invite-join.test. + +Florian Klink (2): + (read|append)_config_file: log open errors as LOG_DEBUG + setup_outgoing_connection: log to LOG_DEBUG on if no known address + +LunarShaddow (2): + fix typo + re-arrange include sequence to avoid a mingw introduced bug. + +Dato Simó (1): + Fix typo in tinc.texi. + +Jo-Philipp Wich (1): + fix musl compatibility + +Jochen Voss (1): + Add a new --syslog option for tincd. + +Nathan Stratton Treadway (1): + Fix invalid checksum generation. + +Pierre Emeriaud (1): + Fix typo in tincctl help. + +xentec (1): + Fix compile errors introduced in cfe9285adf391ab66faeb5def811fe08e47a221a + Version 1.1pre11 December 27 2014 ------------------------------------------------------------------------ diff --git a/Makefile.am b/Makefile.am index 0a4faef..177f549 100644 --- a/Makefile.am +++ b/Makefile.am @@ -2,14 +2,22 @@ AUTOMAKE_OPTIONS = gnu -SUBDIRS = m4 src doc gui test +SUBDIRS = src doc gui test systemd -ACLOCAL_AMFLAGS = -I m4 +ACLOCAL_AMFLAGS = -I m4 EXTRA_DIST = COPYING.README README.android +# If git describe works, force autoconf to run in order to make sure we have the +# current version number from git in the resulting configure script. +configure-version: + -cd $(srcdir) && git describe && autoconf --force + +# Triggering the README target means we are building a distribution (make dist). +README: configure-version + ChangeLog: - git log > ChangeLog + (cd $(srcdir) && git log) > ChangeLog deb: dpkg-buildpackage -rfakeroot @@ -23,5 +31,5 @@ release: rm -f ChangeLog $(MAKE) ChangeLog echo "Please edit the NEWS file now..." - /usr/bin/editor NEWS + /usr/bin/editor $(srcdir)/NEWS $(MAKE) dist diff --git a/Makefile.in b/Makefile.in index 797d7bf..f5f609a 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.14.1 from Makefile.am. +# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2013 Free Software Foundation, Inc. +# Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -14,7 +14,17 @@ @SET_MAKE@ VPATH = @srcdir@ -am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ @@ -78,21 +88,18 @@ POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = . -DIST_COMMON = INSTALL NEWS README AUTHORS ChangeLog \ - $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ - $(top_srcdir)/configure $(am__configure_deps) \ - $(srcdir)/config.h.in COPYING THANKS compile config.guess \ - config.sub depcomp install-sh missing ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \ $(top_srcdir)/m4/ax_check_compile_flag.m4 \ $(top_srcdir)/m4/ax_check_link_flag.m4 \ $(top_srcdir)/m4/curses.m4 $(top_srcdir)/m4/libgcrypt.m4 \ - $(top_srcdir)/m4/lzo.m4 $(top_srcdir)/m4/openssl.m4 \ - $(top_srcdir)/m4/readline.m4 $(top_srcdir)/m4/zlib.m4 \ - $(top_srcdir)/configure.ac + $(top_srcdir)/m4/lzo.m4 $(top_srcdir)/m4/miniupnpc.m4 \ + $(top_srcdir)/m4/openssl.m4 $(top_srcdir)/m4/readline.m4 \ + $(top_srcdir)/m4/zlib.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \ + $(am__configure_deps) $(am__DIST_COMMON) am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ configure.lineno config.status.lineno mkinstalldirs = $(install_sh) -d @@ -156,6 +163,9 @@ ETAGS = etags CTAGS = ctags CSCOPE = cscope DIST_SUBDIRS = $(SUBDIRS) +am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/config.h.in AUTHORS \ + COPYING ChangeLog INSTALL NEWS README THANKS compile \ + config.guess config.sub depcomp install-sh missing DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) top_distdir = $(distdir) @@ -231,6 +241,7 @@ LIBS = @LIBS@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ +MINIUPNPC_LIBS = @MINIUPNPC_LIBS@ MKDIR_P = @MKDIR_P@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ @@ -288,17 +299,19 @@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ +runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ +systemd_path = @systemd_path@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ AUTOMAKE_OPTIONS = gnu -SUBDIRS = m4 src doc gui test -ACLOCAL_AMFLAGS = -I m4 +SUBDIRS = src doc gui test systemd +ACLOCAL_AMFLAGS = -I m4 EXTRA_DIST = COPYING.README README.android all: config.h $(MAKE) $(AM_MAKEFLAGS) all-recursive @@ -319,7 +332,6 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu Makefile -.PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ @@ -461,12 +473,6 @@ distclean-tags: -rm -f cscope.out cscope.in.out cscope.po.out cscope.files distdir: $(DISTFILES) - @case `sed 15q $(srcdir)/NEWS` in \ - *"$(VERSION)"*) : ;; \ - *) \ - echo "NEWS not updated; not releasing" 1>&2; \ - exit 1;; \ - esac $(am__remove_distdir) test -d "$(distdir)" || mkdir "$(distdir)" @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ @@ -547,15 +553,15 @@ dist-xz: distdir $(am__post_remove_distdir) dist-tarZ: distdir - @echo WARNING: "Support for shar distribution archives is" \ - "deprecated." >&2 + @echo WARNING: "Support for distribution archives compressed with" \ + "legacy program 'compress' is deprecated." >&2 @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z $(am__post_remove_distdir) dist-shar: distdir - @echo WARNING: "Support for distribution archives compressed with" \ - "legacy program 'compress' is deprecated." >&2 + @echo WARNING: "Support for shar distribution archives is" \ + "deprecated." >&2 @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz $(am__post_remove_distdir) @@ -591,17 +597,17 @@ distcheck: dist esac chmod -R a-w $(distdir) chmod u+w $(distdir) - mkdir $(distdir)/_build $(distdir)/_inst + mkdir $(distdir)/_build $(distdir)/_build/sub $(distdir)/_inst chmod a-w $(distdir) test -d $(distdir)/_build || exit 0; \ dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ && am__cwd=`pwd` \ - && $(am__cd) $(distdir)/_build \ - && ../configure \ + && $(am__cd) $(distdir)/_build/sub \ + && ../../configure \ $(AM_DISTCHECK_CONFIGURE_FLAGS) \ $(DISTCHECK_CONFIGURE_FLAGS) \ - --srcdir=.. --prefix="$$dc_install_base" \ + --srcdir=../.. --prefix="$$dc_install_base" \ && $(MAKE) $(AM_MAKEFLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) dvi \ && $(MAKE) $(AM_MAKEFLAGS) check \ @@ -776,9 +782,19 @@ uninstall-am: mostlyclean-generic pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am +.PRECIOUS: Makefile + + +# If git describe works, force autoconf to run in order to make sure we have the +# current version number from git in the resulting configure script. +configure-version: + -cd $(srcdir) && git describe && autoconf --force + +# Triggering the README target means we are building a distribution (make dist). +README: configure-version ChangeLog: - git log > ChangeLog + (cd $(srcdir) && git log) > ChangeLog deb: dpkg-buildpackage -rfakeroot @@ -792,7 +808,7 @@ release: rm -f ChangeLog $(MAKE) ChangeLog echo "Please edit the NEWS file now..." - /usr/bin/editor NEWS + /usr/bin/editor $(srcdir)/NEWS $(MAKE) dist # Tell versions [3.59,3.63) of GNU make to not export all variables. diff --git a/NEWS b/NEWS index abd6a6f..bedca1c 100644 --- a/NEWS +++ b/NEWS @@ -1,830 +1,667 @@ -Version 1.1pre11 December 27 2014 +# Version 1.1pre12 April 24 2016 - * Added a "network" command to list or switch networks. +* Added a "--syslog" option to force logging to syslog even if running in the + foreground. +* Fixes and improvements to the DecrementTTL function. +* Improved PMTU discovery and UDP keepalive probes. +* More efficient relaying of UDP packets through intermediate nodes. +* Improved compatibility with newer TAP-Win32 drivers. +* Added support for UPnP. +* Allow tinc to be compiled without LibreSSL or OpenSSL (this drops + compatibility with nodes running 1.0.x). +* Added a "fsck" command to check the configuration files for problems. +* Tinc "start" now checks whether the daemon really started succesfully, and + displays error messages otherwise. +* Added systemd service files. +* Use the recvmmsg() function if available. +* Support ToS/Diffserv on IPv6 connections. +* Updated support for BSD tun/tap devices. +* Added support for OS X utun interfaces. +* Dropped support for Windows 2000. +* Initial support for generating a tinc-up script from an invitation. +* Many small fixes, documentation updates. - * Switched to Ed25519 keys and the ChaCha-Poly1305 cipher for the new protocol. +Thanks to Etienne Dechamps, thorkill, Vittorio Gambaletta, Martin Weinelt, +Sven-Haegar Koch, Florian Klink, LunnarShadow, Dato Simó, Jo-Philipp Wich, +Jochen Voss, Nathan Stratton Treadway, Pierre Emeriaud, xentec, Samuel +Thibault and Michael Tokarev for their contributions to this version of tinc. - * AutoConnect is now a boolean option, when enabled tinc always tries to keep - at least three meta-connections open. +# Version 1.1pre11 December 27 2014 - * The new protocol now uses UDP much more often. - - * Tinc "del" and "get" commands now return a non-zero exit code when they - don't find the requested variable. - - * Updated documentation. - - * Added a "DeviceStandby" option to defer running tinc-up until a working - connection is made, and which on Windows will also change the network - interface link status accordingly. - - * Tinc now tells the resolver to reload /etc/resolv.conf when it receives - SIGALRM. - - * Improved error messages and event loop handling on Windows. - - * LocalDiscovery now uses local address learned from other nodes, and is - enabled by default. - - * Added a "BroadcastSubnet" option to change the behavior of broadcast packets - in router mode. - - * Added support for dotted quad notation in IPv6 (e.g. ::1.2.3.4). - - * Improved format of printed Subnets, MAC and IPv6 addresses. - - * Added a "--batch" option to force the tinc CLI to run in non-interactive - mode. - - * Improve default Device selection on *BSD and Mac OS X. - - * Allow running tinc without RSA keys. +* Added a "network" command to list or switch networks. +* Switched to Ed25519 keys and the ChaCha-Poly1305 cipher for the new protocol. +* AutoConnect is now a boolean option, when enabled tinc always tries to keep + at least three meta-connections open. +* The new protocol now uses UDP much more often. +* Tinc "del" and "get" commands now return a non-zero exit code when they + don't find the requested variable. +* Updated documentation. +* Added a "DeviceStandby" option to defer running tinc-up until a working + connection is made, and which on Windows will also change the network + interface link status accordingly. +* Tinc now tells the resolver to reload /etc/resolv.conf when it receives + SIGALRM. +* Improved error messages and event loop handling on Windows. +* LocalDiscovery now uses local address learned from other nodes, and is + enabled by default. +* Added a "BroadcastSubnet" option to change the behavior of broadcast packets + in router mode. +* Added support for dotted quad notation in IPv6 (e.g. ::1.2.3.4). +* Improved format of printed Subnets, MAC and IPv6 addresses. +* Added a "--batch" option to force the tinc CLI to run in non-interactive + mode. +* Improve default Device selection on *BSD and Mac OS X. +* Allow running tinc without RSA keys. Thanks to Etienne Dechamps, Sven-Haegar Koch, William A. Kennington III, Baptiste Jonglez, Alexis Hildebrandt, Armin Fisslthaler, Franz Pletz, Alexander Ried and Saverio Proto for their contributions to this version of tinc. -Version 1.1pre10 February 7 2014 +# Version 1.1pre10 February 7 2014 - * Added a benchmark tool (sptps_speed) for the new protocol. - - * Fixed a crash when using Name = $HOST while $HOST is not set. - - * Use AES-256-GCM for the new protocol. - - * Updated support for Solaris. - - * Allow running tincd without a private ECDSA key present when - ExperimentalProtocol is not explicitly set. - - * Enable various compiler hardening flags by default. - - * Added support for a "conf.d" configuration directory. - - * Fix tinc-gui on Windows, also allowing it to connect to a 32-bits tincd when - tinc-gui is run in a 64-bits Python environment. - - * Added a "ListenAddress" option, which like BindToAddress adds more listening - address/ports, but doesn't bind to them for outgoing sockets. - - * Make invitations work better when the "invite" and "join" commands are not - run interactively. - - * When creating meta-connections to a node for which no Address statement is - specified, try to use addresses learned from other nodes. +* Added a benchmark tool (sptps_speed) for the new protocol. +* Fixed a crash when using Name = $HOST while $HOST is not set. +* Use AES-256-GCM for the new protocol. +* Updated support for Solaris. +* Allow running tincd without a private ECDSA key present when + ExperimentalProtocol is not explicitly set. +* Enable various compiler hardening flags by default. +* Added support for a "conf.d" configuration directory. +* Fix tinc-gui on Windows, also allowing it to connect to a 32-bits tincd when + tinc-gui is run in a 64-bits Python environment. +* Added a "ListenAddress" option, which like BindToAddress adds more listening + address/ports, but doesn't bind to them for outgoing sockets. +* Make invitations work better when the "invite" and "join" commands are not + run interactively. +* When creating meta-connections to a node for which no Address statement is + specified, try to use addresses learned from other nodes. Thanks to Dennis Joachimsthaler and Florent Clairambault for their contribution to this version of tinc. -Version 1.1pre9 September 8 2013 +# Version 1.1pre9 September 8 2013 - * The UNIX socket is now created before tinc-up is called. - - * Windows users can now use any extension that is in %PATHEXT% for scripts, - not only .bat. - - * Outgoing sockets are bound to the address of the listening sockets again, - when there is no ambiguity. - - * Added invitation-created and invitation-accepted scripts. - - * Invited nodes now learn of the Mode and Broadcast settings of the VPN. - - * Joining a VPN with an invitation now also works on Windows. - - * The port number tincd is listening on is now always included in the - invitation URL. - - * A running tincd is now correctly informed when a new invitation has been - generated. - - * Several bug fixes for the new protocol. - - * Added a test suite. +* The UNIX socket is now created before tinc-up is called. +* Windows users can now use any extension that is in %PATHEXT% for scripts, + not only .bat. +* Outgoing sockets are bound to the address of the listening sockets again, + when there is no ambiguity. +* Added invitation-created and invitation-accepted scripts. +* Invited nodes now learn of the Mode and Broadcast settings of the VPN. +* Joining a VPN with an invitation now also works on Windows. +* The port number tincd is listening on is now always included in the + invitation URL. +* A running tincd is now correctly informed when a new invitation has been + generated. +* Several bug fixes for the new protocol. +* Added a test suite. Thanks to Etienne Dechamps for his contribution to this version of tinc. -Version 1.1pre8 August 13 2013 +# Version 1.1pre8 August 13 2013 - * ExperimentalProtocol is now enabled by default. - - * Added an invitation protocol that makes it easy to invite new nodes. - - * Added the LocalDiscoveryAddress option to change the broadcast address used - to find local nodes. - - * Limit the rate of incoming meta-connections. - - * Many small bug fixes and code cleanups. +* ExperimentalProtocol is now enabled by default. +* Added an invitation protocol that makes it easy to invite new nodes. +* Added the LocalDiscoveryAddress option to change the broadcast address used + to find local nodes. +* Limit the rate of incoming meta-connections. +* Many small bug fixes and code cleanups. Thanks to Etienne Dechamps and Sven-Haegar Koch for their contributions to this version of tinc. -Version 1.1pre7 April 22 2013 +# Version 1.1pre7 April 22 2013 - * Fixed large latencies on Windows. - - * Renamed the tincctl tool to tinc. - - * Simplified changing the configuration using the tinc tool. - - * Added a full description of the ExperimentalProtocol to the manual. - - * Drop packets forwarded via TCP if they are too big (CVE-2013-1428). +* Fixed large latencies on Windows. +* Renamed the tincctl tool to tinc. +* Simplified changing the configuration using the tinc tool. +* Added a full description of the ExperimentalProtocol to the manual. +* Drop packets forwarded via TCP if they are too big (CVE-2013-1428). Thanks to Martin Schobert for auditing tinc and reporting the vulnerability. -Version 1.1pre6 February 20 2013 +# Version 1.1pre6 February 20 2013 - * Fixed tincd exitting immediately on Windows. +* Fixed tincd exitting immediately on Windows. +* Detect PMTU increases. +* Fixed crashes when using a SOCKS5 proxy. +* Fixed control connection when using a proxy. - * Detect PMTU increases. +# Version 1.1pre5 January 20 2013 - * Fixed crashes when using a SOCKS5 proxy. +* Fixed long delays and possible hangs on Windows. +* Fixed support for the tunemu device on iOS, the UML and VDE devices. +* Small improvements to the documentation and error messages. +* Fixed broadcast packets not reaching the whole VPN. +* Tincctl now connects via a UNIX socket to the tincd on platforms that + support this. +* The PriorityInheritance option now also works in switch mode. - * Fixed control connection when using a proxy. +# Version 1.1pre4 December 5 2012 -Version 1.1pre5 January 20 2013 +* Added the "AutoConnect" option which will let tinc automatically select + which nodes to connect to. +* Improved performance of VLAN-tagged IP traffic inside the VPN. +* Ensured LocalDiscovery works with multiple BindToAddress statements and/or + IPv6-only LANs. +* Dropped dependency on libevent. +* Fixed Windows version not reading packets from the TAP adapter. - * Fixed long delays and possible hangs on Windows. +# Version 1.1pre3 October 14 2012 - * Fixed support for the tunemu device on iOS, the UML and VDE devices. +* New experimental protocol: + * Uses 521 bit ECDSA keys for authentication. + * Uses AES-256-CTR and HMAC-SHA256. + * Always provides perfect forward secrecy. + * Used for both meta-connections and VPN packets. + * VPN packets are encrypted end-to-end. +* Many improvements to tincctl: + * "config" command shows/adds/changes configuration variables. + * "export" and "import" commands help exchange configuration files. + * "init" command sets up initial configuration files. + * "info" command shows details about a node, subnet or address. + * "log" command shows live log messages. + * Without a command it acts as a shell, with history and TAB completion. + * Improved starting/stopping tincd. + * Improved graph output. +* When trying to directly send UDP packets to a node for which multiple + addresses are known, all of them are tried. +* Many small fixes, code cleanups and documentation updates. - * Small improvements to the documentation and error messages. +# Version 1.1pre2 July 17 2011 - * Fixed broadcast packets not reaching the whole VPN. +* .cookie files are renamed to .pid files, which are compatible with 1.0.x. +* Experimental protocol enhancements that can be enabled with the option + ExperimentalProtocol = yes: - * Tincctl now connects via a UNIX socket to the tincd on platforms that - support this. + * Ephemeral ECDH key exchange will be used for both the meta protocol and + UDP session keys. + * Key exchanges are signed with ECDSA. + * ECDSA public keys are automatically exchanged after RSA authentication if + nodes do not know each other's ECDSA public key yet. - * The PriorityInheritance option now also works in switch mode. +# Version 1.1pre1 June 25 2011 -Version 1.1pre4 December 5 2012 +* Control interface allows control of a running tinc daemon. Used by: + * tincctl, a commandline utility + * tinc-gui, a preliminary GUI implemented in Python/wxWidgets +* Code cleanups and reorganization. +* Repleacable cryptography backend, currently supports OpenSSL and libgcrypt. +* Use libevent to handle I/O events and timeouts. +* Use splay trees instead of AVL trees to manage internal datastructures. - * Added the "AutoConnect" option which will let tinc automatically select - which nodes to connect to. +Thanks to Scott Lamb and Sven-Haegar Koch for their contributions to this +version of tinc. - * Improved performance of VLAN-tagged IP traffic inside the VPN. +# Version 1.0.22 August 13 2013 - * Ensured LocalDiscovery works with multiple BindToAddress statements and/or - IPv6-only LANs. - - * Dropped dependency on libevent. - - * Fixed Windows version not reading packets from the TAP adapter. - -Version 1.1pre3 October 14 2012 - - * New experimental protocol: - * Uses 521 bit ECDSA keys for authentication. - * Uses AES-256-CTR and HMAC-SHA256. - * Always provides perfect forward secrecy. - * Used for both meta-connections and VPN packets. - * VPN packets are encrypted end-to-end. - - * Many improvements to tincctl: - * "config" command shows/adds/changes configuration variables. - * "export" and "import" commands help exchange configuration files. - * "init" command sets up initial configuration files. - * "info" command shows details about a node, subnet or address. - * "log" command shows live log messages. - * Without a command it acts as a shell, with history and TAB completion. - * Improved starting/stopping tincd. - * Improved graph output. - - * When trying to directly send UDP packets to a node for which multiple - addresses are known, all of them are tried. - - * Many small fixes, code cleanups and documentation updates. - -Version 1.1pre2 July 17 2011 - - * .cookie files are renamed to .pid files, which are compatible with 1.0.x. - - * Experimental protocol enhancements that can be enabled with the option - ExperimentalProtocol = yes: - - * Ephemeral ECDH key exchange will be used for both the meta protocol and - UDP session keys. - * Key exchanges are signed with ECDSA. - * ECDSA public keys are automatically exchanged after RSA authentication if - nodes do not know each other's ECDSA public key yet. - -Version 1.1pre1 June 25 2011 - - * Control interface allows control of a running tinc daemon. Used by: - * tincctl, a commandline utility - * tinc-gui, a preliminary GUI implemented in Python/wxWidgets - - * Code cleanups and reorganization. - - * Repleacable cryptography backend, currently supports OpenSSL and libgcrypt. - - * Use libevent to handle I/O events and timeouts. - - * Use splay trees instead of AVL trees to manage internal datastructures. - - Thanks to Scott Lamb and Sven-Haegar Koch for their contributions to this - version of tinc. - -Version 1.0.22 August 13 2013 - - * Fixed the combination of Mode = router and DeviceType = tap. - - * The $NAME variable is now set in subnet-up/down scripts. - - * Tinc now gives an error when unknown options are given on the command line. - - * Tinc now correctly handles a space between a short command line option and - an optional argument. +* Fixed the combination of Mode = router and DeviceType = tap. +* The $NAME variable is now set in subnet-up/down scripts. +* Tinc now gives an error when unknown options are given on the command line. +* Tinc now correctly handles a space between a short command line option and + an optional argument. Thanks to Etienne Dechamps for his contribution to this version of tinc. -Version 1.0.21 April 22 2013 +# Version 1.0.21 April 22 2013 - * Drop packets forwarded via TCP if they are too big (CVE-2013-1428). +* Drop packets forwarded via TCP if they are too big (CVE-2013-1428). Thanks to Martin Schobert for auditing tinc and reporting this vulnerability. -Version 1.0.20 March 03 2013 +# Version 1.0.20 March 03 2013 - * Use /dev/tap0 by default on FreeBSD and NetBSD when using switch mode. - - * Minor improvements and clarifications in the documentation. - - * Allow tinc to be cross-compiled with Android's NDK. - - * The discovered PMTU is now also applied to VLAN tagged traffic. - - * The LocalDiscovery option now makes use of all addresses tinc is bound to. - - * Fixed support for tunemu on iOS devices. - - * The PriorityInheritance option now also works with switch mode. - - * Fixed tinc crashing when using a SOCKS5 proxy. +* Use /dev/tap0 by default on FreeBSD and NetBSD when using switch mode. +* Minor improvements and clarifications in the documentation. +* Allow tinc to be cross-compiled with Android's NDK. +* The discovered PMTU is now also applied to VLAN tagged traffic. +* The LocalDiscovery option now makes use of all addresses tinc is bound to. +* Fixed support for tunemu on iOS devices. +* The PriorityInheritance option now also works with switch mode. +* Fixed tinc crashing when using a SOCKS5 proxy. Thanks to Mesar Hameed, Vilbrekin and Martin Schürrer for their contributions to this version of tinc. -Version 1.0.19 June 25 2012 +# Version 1.0.19 June 25 2012 + +* Allow :: notation in IPv6 Subnets. +* Add support for systemd style socket activation. +* Allow environment variables to be used for the Name option. +* Add basic support for SOCKS proxies, HTTP proxies, and proxying through an + external command. + +# Version 1.0.18 March 25 2012 + +* Fixed IPv6 in switch mode by turning off DecrementTTL by default. +* Allow a port number to be specified in BindToAddress, which also allows tinc + to listen on multiple ports. +* Add support for multicast communication with UML/QEMU/KVM. + +# Version 1.0.17 March 10 2012 + +* The DeviceType option can now be used to select dummy, raw socket, UML and + VDE devices without needing to recompile tinc. +* Allow multiple BindToAddress statements. +* Decrement TTL value of IPv4 and IPv6 packets. +* Add LocalDiscovery option allowing tinc to detect peers that are behind the + same NAT. +* Accept Subnets passed with the -o option when StrictSubnets = yes. +* Disabling old RSA keys when generating new ones now also works properly on + Windows. + +# Version 1.0.16 July 23 2011 + +* Fixed a performance issue with TCP communication under Windows. +* Fixed code that, during network outages, would cause tinc to exit when it + thought two nodes with identical Names were on the VPN. + +# Version 1.0.15 June 24 2011 + +* Improved logging to file. +* Reduced amount of process wakeups on platforms which support pselect(). +* Fixed ProcessPriority option under Windows. + + Thanks to Loïc Grenié for his contribution to this version of tinc. + +# Version 1.0.14 May 8 2011 + +* Fixed reading configuration files that do not end with a newline. Again. +* Allow arbitrary configuration options being specified on the command line. +* Allow all options in both tinc.conf and the local host config file. +* Configurable replay window, UDP send and receive buffers for performance tuning. +* Try harder to get UDP communication back after falling back to TCP. +* Initial support for attaching tinc to a VDE switch. +* DragonFly BSD support. +* Allow linking with OpenSSL 1.0.0. + +Thanks to Brandon Black, Julien Muchembled, Michael Tokarev, Rumko and Timothy +Redaelli for their contributions to this version of tinc. + +# 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. +* 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. +* Fixes handling of weighted Subnets in switch and hub modes, preventing + unnecessary broadcasts. +* Works around a MinGW bug that caused packets to Windows nodes to always be + sent via TCP. +* Improvements to the PMTU discovery code, especially on Windows. +* Use UDP again in certain cases where 1.0.10 was too conservative and fell + back to TCP unnecessarily. +* Allow fast roaming of hosts to other nodes in a switched VPN. + +# Version 1.0.10 Oct 18 2009 + +* Fixed potential crashes during shutdown and (in rare conditions) when other + nodes disconnected from the VPN. +* Improved NAT handling: tinc now copes with mangled port numbers, and will + automatically fall back to TCP if direct UDP connection between nodes is not + possible. The TCPOnly option should not have to be used anymore. +* Allow configuration files with CRLF line endings to be read on UNIX. +* Disable old RSA keys when generating new ones, and raise the default size of + new RSA keys to 2048 bits. +* Many fixes in the path MTU discovery code, especially when Compression is + being used. +* Tinc can now drop privileges and/or chroot itself. +* The TunnelServer code now just ignores information from clients instead of + disconnecting them. +* Improved performance on Windows by using the new ProcessPriority option and + by making the handling of packets received from the TAP-Win32 adapter more + efficient. +* Code cleanups: tinc now follows the C99 standard, copyright headers have + been updated to include patch authors, checkpoint tracing and localisation + features have been removed. +* Support for (jailbroken) iPhone and iPod Touch has been added. + +Thanks to Florian Forster, Grzegorz Dymarek and especially Michael Tokarev for +their contributions to this version of tinc. + +# Version 1.0.9 Dec 26 2008 + +* Fixed tinc as a service under Windows 2003. +* Fixed reading configuration files that do not end with a newline. +* Fixed crashes in situations where hostnames could not be resolved or hosts + would disconnect at the same time as session keys were exchanged. +* Improved default settings of tun and tap devices on BSD platforms. +* Make IPv6 sockets bind only to IPv6 on Linux. +* Enable path MTU discovery by default. +* Fixed a memory leak that occured when connections were closed. + +Thanks to Max Rijevski for his contributions to this version of tinc. + +# Version 1.0.8 May 16 2007 + +* Fixed some memory and resource leaks. +* Made network sockets non-blocking under Windows. + +Thanks to Scott Lamb and "dnk" for their contributions to this version of tinc. + +# Version 1.0.7 Jan 5 2007 + +* Fixed a bug that caused slow network speeds on Windows. +* Fixed a bug that caused tinc unable to write packets to the tun device on + OpenBSD. + +# Version 1.0.6 Dec 18 2006 + +* More flexible detection of the LZO libraries when compiling. +* Fixed a bug where broadcasts in switch and hub modes sometimes would not + work anymore when part of the VPN had become disconnected from the rest. + +# Version 1.0.5 Nov 14 2006 + +* Lots of small fixes. +* Broadcast packets no longer grow in size with each hop. This should + fix switch mode (again). +* Generic host-up and host-down scripts. +* Optionally dump graph in graphviz format to a file or a script. +* Support LZO 2.0 and later. + +Thanks to Scott Lamb for his contributions to this version of tinc. + +# Version 1.0.4 May 4 2005 + +* Fix switch and hub modes. +* Optionally start scripts when a Subnet becomes (un)reachable. + +# Version 1.0.3 Nov 11 2004 + +* Show error message when failing to write a PID file. +* Ignore spaces at end of lines in config files. +* Fix handling of late packets. +* Unify BSD tun/tap device handling. This allows IPv6 on tun devices and + anything on tap devices as long as the underlying OS supports it. +* Handle IPv6 on Solaris tun devices. +* Allow tinc to work properly under Windows XP SP2. +* Allow VLAN tagged Ethernet frames in switch and hub mode. +* Experimental PMTUDiscovery, TunnelServer and BlockingTCP options. + +# Version 1.0.2 Nov 8 2003 + +* Fix address and hostname resolving under Windows. +* Remove warnings about non-existing scripts and unsupported address families. +* Use the event logger under Windows. +* Fix quoting of filenames and command line arguments under Windows. +* Strict checks for length incoming network packets and return values of + cryptographic functions, +* Fix a bug in metadata handling that made the tinc daemon abort. + +# Version 1.0.1 Aug 14 2003 + +* Allow empty lines in config files. +* Fix handling of spaces and backslashes in filenames under native Windows. +* Allow scripts to be executed under native Windows. +* Update documentation, make it less Linux specific. + +# Version 1.0 Aug 4 2003 + +* Lots of small bugfixes and code cleanups. +* Throughput doubled and latency reduced. +* Added support for LZO compression. +* No need to set MAC address or disable ARP anymore. +* Added support for Windows 2000 and XP, both natively and in a Cygwin + environment. + +# Version 1.0pre8 Sep 16 2002 + +* More fixes for subnets with prefixlength undivisible by 8. +* Added support for NetBSD and MacOS/X. +* Switched from undirected graphs to directed graphs to avoid certain race + conditions and improve scalability. +* Generalized broadcasting and forwarding of protocol messages. +* Cleanup of source code. + +# Version 1.0pre7 Apr 7 2002 + +* Don't do blocking read()s when getting a signal. +* Remove RSA key checking code, since it sometimes thinks perfectly good RSA + keys are bad. +* Fix handling of subnets when prefixlength isn't divisible by 8. + +# Version 1.0pre6 Mar 27 2002 + +* Improvement of redundant links: + * Non-blocking connects. + * Protocol broadcast messages can no longer go into an infinite loop. + * Graph algorithm updated to look harder for direct connections. +* Good support for routing IPv6 packets over the VPN. Works on Linux, + FreeBSD, possibly OpenBSD but not on Solaris. +* Support for tunnels over IPv6 networks. Works on all supported + operating systems. +* Optional compression of UDP connections using zlib. +* Optionally let UDP connections inherit TOS field of tunneled packets. +* Optionally start scripts when certain hosts become (un)reachable. + +# Version 1.0pre5 Feb 9 2002 + +* Security enhancements: + * Added sequence number and optional message authentication code to + the packets. + * Configurable encryption cipher and digest algorithms. +* More robust handling of dis- and reconnects. +* Added a "switch" and a "hub" mode to allow bridging setups. +* Preliminary support for routing of IPv6 packets. +* Supports Linux, FreeBSD, OpenBSD and Solaris. + +# Version 1.0pre4 Jan 17 2001 + +* Updated documentation; the documentation now reflects the + configuration as it is. +* Some internal changes to make tinc scale better for large + networks, such as using AVL trees instead of linked lists for the + connection list. +* RSA keys can be stored in separate files if needed. See the + documentation for more information. +* Tinc has now been reported to run on Linux PowerPC and FreeBSD x86. + +# Version 1.0pre3 Oct 31 2000 + +* The protocol has been redesigned, and although some details are + still under discussion, this is secure. Care has been taken to + resist most, if not all, attacks. +* Unfortunately this protocol is not compatible with earlier versions, + nor are earlier versions compatible with this version. Because the + older protocol has huge security flaws, we feel that not + implementing backwards compatibility is justified. +* Some data about the protocol: + * It uses public/private RSA keys for authentication (this is the + actual fix for the security hole). + * All cryptographic functions have been taken out of tinc, instead + it uses the OpenSSL library functions. + * Offers support for multiple subnets per tinc daemon. +* New is also the support for the universal tun/tap device. This + means better portability to FreeBSD and Solaris. +* Tinc is tested to compile on Solaris, Linux x86, Linux alpha. +* Tinc now uses the OpenSSL library for cryptographic operations. + More information on getting and installing OpenSSL is in the manual. + This also means that the GMP library is no longer required. +* Further, thanks to Enrique Zanardi, we have Spanish messages; Matias + Carrasco provided us with a Spanish translation of the manual. + +# Version 1.0pre2 May 31 2000 + +* This version has been internationalized; and a Dutch translation has + been included. +* Two configuration variables have been added: + * VpnMask - the IP network mask for the entire VPN, not just our + subnet (as given by MyVirtualIP). The Redhat and Debian packages + use this variable in their system startup scripts, but it is + ignored by tinc. + * Hostnames - if set to `yes', look up the names of IP addresses + trying to connect to us. Default set to `no', to prevent lockups + during lookups. +* The system startup scripts for Debian and Redhat use + /etc/tinc/nets.boot to find out which networks need to be started + during system boot. +* Fixes to prevent denial of service attacks by sending random data + after connecting (and even when the connection has been established), + either random garbage or just nonsensical protocol fields. +* Tinc will retry to connect upon startup, does not quit if it doesn't + work the first time. +* Hosts that are disconnected implicitly if we lose a connection get + deleted from the internal list, to prevent hogging eachother with + add and delete requests when the connection is restored. + +# Version 1.0pre1 May 12 2000 + +* New meta-protocol +* Various other bugfixes +* Documentation updates + +# Version 0.3.3 Feb 9 2000 + +* Fixed bug that made tinc stop working with latest kernels +* Updated the manual + +# Version 0.3.2 Nov 12 1999 + +* No more `Invalid filedescriptor' when working with multiple + connections. +* Forward unknown packets to uplink. + +# Version 0.3.1 Oct 20 1999 + +* Fixed a bug where tinc would exit without a trace. + +# Version 0.3 Aug 20 1999 + +* Pings now work immediately. +* All packet sizes get transmitted correctly. + +# Version 0.2.26 Aug 15 1999 + +* Fixed some remaining bugs. +* --sysconfdir works with configure. +* Last version before 0.3. + +# Version 0.2.25 Aug 8 1999 + +* Improved stability, going towards 0.3 now. + +# Version 0.2.24 Aug 7 1999 - * Allow :: notation in IPv6 Subnets. +* Added key aging, there's a new config variable, KeyExpire. +* Updated man and info pages. - * Add support for systemd style socket activation. +# Version 0.2.23 Aug 5 1999 - * Allow environment variables to be used for the Name option. +* All known bugs fixed, this is a candidate for 0.3. + +# Version 0.2.22 Apr 11 1999 - * Add basic support for SOCKS proxies, HTTP proxies, and proxying through an - external command. +* Multiconnection thing is now working nearly perfect :) -Version 1.0.18 March 25 2012 +# Version 0.2.21 Apr 10 1999 - * Fixed IPv6 in switch mode by turning off DecrementTTL by default. - - * Allow a port number to be specified in BindToAddress, which also allows tinc - to listen on multiple ports. - - * Add support for multicast communication with UML/QEMU/KVM. - -Version 1.0.17 March 10 2012 - - * The DeviceType option can now be used to select dummy, raw socket, UML and - VDE devices without needing to recompile tinc. - - * Allow multiple BindToAddress statements. - - * Decrement TTL value of IPv4 and IPv6 packets. - - * Add LocalDiscovery option allowing tinc to detect peers that are behind the - same NAT. - - * Accept Subnets passed with the -o option when StrictSubnets = yes. - - * Disabling old RSA keys when generating new ones now also works properly on - Windows. - -Version 1.0.16 July 23 2011 - - * Fixed a performance issue with TCP communication under Windows. - - * Fixed code that, during network outages, would cause tinc to exit when it - thought two nodes with identical Names were on the VPN. - -Version 1.0.15 June 24 2011 - - * Improved logging to file. - - * Reduced amount of process wakeups on platforms which support pselect(). - - * Fixed ProcessPriority option under Windows. - - Thanks to Loïc Grenié for his contribution to this version of tinc. - -Version 1.0.14 May 8 2011 - - * Fixed reading configuration files that do not end with a newline. Again. - - * Allow arbitrary configuration options being specified on the command line. - - * Allow all options in both tinc.conf and the local host config file. - - * Configurable replay window, UDP send and receive buffers for performance tuning. - - * Try harder to get UDP communication back after falling back to TCP. - - * Initial support for attaching tinc to a VDE switch. - - * DragonFly BSD support. - - * Allow linking with OpenSSL 1.0.0. - - Thanks to Brandon Black, Julien Muchembled, Michael Tokarev, Rumko and Timothy - Redaelli for their contributions to this version of tinc. - -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. - - * 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. - - * Fixes handling of weighted Subnets in switch and hub modes, preventing - unnecessary broadcasts. - - * Works around a MinGW bug that caused packets to Windows nodes to always be - sent via TCP. - - * Improvements to the PMTU discovery code, especially on Windows. - - * Use UDP again in certain cases where 1.0.10 was too conservative and fell - back to TCP unnecessarily. - - * Allow fast roaming of hosts to other nodes in a switched VPN. - -Version 1.0.10 Oct 18 2009 - - * Fixed potential crashes during shutdown and (in rare conditions) when other - nodes disconnected from the VPN. - - * Improved NAT handling: tinc now copes with mangled port numbers, and will - automatically fall back to TCP if direct UDP connection between nodes is not - possible. The TCPOnly option should not have to be used anymore. - - * Allow configuration files with CRLF line endings to be read on UNIX. - - * Disable old RSA keys when generating new ones, and raise the default size of - new RSA keys to 2048 bits. - - * Many fixes in the path MTU discovery code, especially when Compression is - being used. - - * Tinc can now drop privileges and/or chroot itself. - - * The TunnelServer code now just ignores information from clients instead of - disconnecting them. - - * Improved performance on Windows by using the new ProcessPriority option and - by making the handling of packets received from the TAP-Win32 adapter more - efficient. - - * Code cleanups: tinc now follows the C99 standard, copyright headers have - been updated to include patch authors, checkpoint tracing and localisation - features have been removed. - - * Support for (jailbroken) iPhone and iPod Touch has been added. - - Thanks to Florian Forster, Grzegorz Dymarek and especially Michael Tokarev for - their contributions to this version of tinc. - -Version 1.0.9 Dec 26 2008 - - * Fixed tinc as a service under Windows 2003. - - * Fixed reading configuration files that do not end with a newline. - - * Fixed crashes in situations where hostnames could not be resolved or hosts - would disconnect at the same time as session keys were exchanged. - - * Improved default settings of tun and tap devices on BSD platforms. - - * Make IPv6 sockets bind only to IPv6 on Linux. - - * Enable path MTU discovery by default. - - * Fixed a memory leak that occured when connections were closed. - - Thanks to Max Rijevski for his contributions to this version of tinc. - -Version 1.0.8 May 16 2007 - - * Fixed some memory and resource leaks. - - * Made network sockets non-blocking under Windows. - - Thanks to Scott Lamb and "dnk" for their contributions to this version of tinc. - -Version 1.0.7 Jan 5 2007 - - * Fixed a bug that caused slow network speeds on Windows. - - * Fixed a bug that caused tinc unable to write packets to the tun device on - OpenBSD. - -Version 1.0.6 Dec 18 2006 - - * More flexible detection of the LZO libraries when compiling. - - * Fixed a bug where broadcasts in switch and hub modes sometimes would not - work anymore when part of the VPN had become disconnected from the rest. - -Version 1.0.5 Nov 14 2006 - - * Lots of small fixes. - - * Broadcast packets no longer grow in size with each hop. This should - fix switch mode (again). - - * Generic host-up and host-down scripts. - - * Optionally dump graph in graphviz format to a file or a script. - - * Support LZO 2.0 and later. - - Thanks to Scott Lamb for his contributions to this version of tinc. - -Version 1.0.4 May 4 2005 - - * Fix switch and hub modes. - - * Optionally start scripts when a Subnet becomes (un)reachable. - -Version 1.0.3 Nov 11 2004 - - * Show error message when failing to write a PID file. - - * Ignore spaces at end of lines in config files. - - * Fix handling of late packets. - - * Unify BSD tun/tap device handling. This allows IPv6 on tun devices and - anything on tap devices as long as the underlying OS supports it. - - * Handle IPv6 on Solaris tun devices. - - * Allow tinc to work properly under Windows XP SP2. - - * Allow VLAN tagged Ethernet frames in switch and hub mode. - - * Experimental PMTUDiscovery, TunnelServer and BlockingTCP options. - -Version 1.0.2 Nov 8 2003 - - * Fix address and hostname resolving under Windows. - - * Remove warnings about non-existing scripts and unsupported address families. - - * Use the event logger under Windows. - - * Fix quoting of filenames and command line arguments under Windows. - - * Strict checks for length incoming network packets and return values of - cryptographic functions, - - * Fix a bug in metadata handling that made the tinc daemon abort. - -Version 1.0.1 Aug 14 2003 - - * Allow empty lines in config files. - - * Fix handling of spaces and backslashes in filenames under native Windows. - - * Allow scripts to be executed under native Windows. - - * Update documentation, make it less Linux specific. - -Version 1.0 Aug 4 2003 - - * Lots of small bugfixes and code cleanups. - - * Throughput doubled and latency reduced. - - * Added support for LZO compression. - - * No need to set MAC address or disable ARP anymore. - - * Added support for Windows 2000 and XP, both natively and in a Cygwin - environment. - -Version 1.0pre8 Sep 16 2002 - - * More fixes for subnets with prefixlength undivisible by 8. - - * Added support for NetBSD and MacOS/X. - - * Switched from undirected graphs to directed graphs to avoid certain race - conditions and improve scalability. - - * Generalized broadcasting and forwarding of protocol messages. - - * Cleanup of source code. - -Version 1.0pre7 Apr 7 2002 - - * Don't do blocking read()s when getting a signal. - - * Remove RSA key checking code, since it sometimes thinks perfectly good RSA - keys are bad. - - * Fix handling of subnets when prefixlength isn't divisible by 8. - -Version 1.0pre6 Mar 27 2002 - - * Improvement of redundant links: - * Non-blocking connects. - * Protocol broadcast messages can no longer go into an infinite loop. - * Graph algorithm updated to look harder for direct connections. - - * Good support for routing IPv6 packets over the VPN. Works on Linux, - FreeBSD, possibly OpenBSD but not on Solaris. - - * Support for tunnels over IPv6 networks. Works on all supported - operating systems. - - * Optional compression of UDP connections using zlib. - - * Optionally let UDP connections inherit TOS field of tunneled packets. - - * Optionally start scripts when certain hosts become (un)reachable. - -Version 1.0pre5 Feb 9 2002 - - * Security enhancements: - * Added sequence number and optional message authentication code to - the packets. - * Configurable encryption cipher and digest algorithms. - - * More robust handling of dis- and reconnects. - - * Added a "switch" and a "hub" mode to allow bridging setups. - - * Preliminary support for routing of IPv6 packets. - - * Supports Linux, FreeBSD, OpenBSD and Solaris. - -Version 1.0pre4 Jan 17 2001 - - * Updated documentation; the documentation now reflects the - configuration as it is. - - * Some internal changes to make tinc scale better for large - networks, such as using AVL trees instead of linked lists for the - connection list. - - * RSA keys can be stored in separate files if needed. See the - documentation for more information. - - * Tinc has now been reported to run on Linux PowerPC and FreeBSD x86. - -Version 1.0pre3 Oct 31 2000 - - * The protocol has been redesigned, and although some details are - still under discussion, this is secure. Care has been taken to - resist most, if not all, attacks. - - * Unfortunately this protocol is not compatible with earlier versions, - nor are earlier versions compatible with this version. Because the - older protocol has huge security flaws, we feel that not - implementing backwards compatibility is justified. - - * Some data about the protocol: - * It uses public/private RSA keys for authentication (this is the - actual fix for the security hole). - * All cryptographic functions have been taken out of tinc, instead - it uses the OpenSSL library functions. - * Offers support for multiple subnets per tinc daemon. - - * New is also the support for the universal tun/tap device. This - means better portability to FreeBSD and Solaris. - - * Tinc is tested to compile on Solaris, Linux x86, Linux alpha. - - * Tinc now uses the OpenSSL library for cryptographic operations. - More information on getting and installing OpenSSL is in the manual. - This also means that the GMP library is no longer required. - - * Further, thanks to Enrique Zanardi, we have Spanish messages; Matias - Carrasco provided us with a Spanish translation of the manual. - -Version 1.0pre2 May 31 2000 - - * This version has been internationalized; and a Dutch translation has - been included. - - * Two configuration variables have been added: - * VpnMask - the IP network mask for the entire VPN, not just our - subnet (as given by MyVirtualIP). The Redhat and Debian packages - use this variable in their system startup scripts, but it is - ignored by tinc. - * Hostnames - if set to `yes', look up the names of IP addresses - trying to connect to us. Default set to `no', to prevent lockups - during lookups. - - * The system startup scripts for Debian and Redhat use - /etc/tinc/nets.boot to find out which networks need to be started - during system boot. - - * Fixes to prevent denial of service attacks by sending random data - after connecting (and even when the connection has been established), - either random garbage or just nonsensical protocol fields. - - * Tinc will retry to connect upon startup, does not quit if it doesn't - work the first time. - - * Hosts that are disconnected implicitly if we lose a connection get - deleted from the internal list, to prevent hogging eachother with - add and delete requests when the connection is restored. - -Version 1.0pre1 May 12 2000 - - * New meta-protocol - - * Various other bugfixes - - * Documentation updates - -Version 0.3.3 Feb 9 2000 - - * Fixed bug that made tinc stop working with latest kernels - - * Updated the manual - -Version 0.3.2 Nov 12 1999 - - * No more `Invalid filedescriptor' when working with multiple - connections. - - * Forward unknown packets to uplink. - -Version 0.3.1 Oct 20 1999 - - * Fixed a bug where tinc would exit without a trace. - -Version 0.3 Aug 20 1999 - - * Pings now work immediately. - - * All packet sizes get transmitted correctly. - -Version 0.2.26 Aug 15 1999 - - * Fixed some remaining bugs. - - * --sysconfdir works with configure. - - * Last version before 0.3. - -Version 0.2.25 Aug 8 1999 - - * Improved stability, going towards 0.3 now. - -Version 0.2.24 Aug 7 1999 - - * Added key aging, there's a new config variable, KeyExpire. - - * Updated man and info pages. - -Version 0.2.23 Aug 5 1999 - - * All known bugs fixed, this is a candidate for 0.3. - -Version 0.2.22 Apr 11 1999 - - * Multiconnection thing is now working nearly perfect :) - -Version 0.2.21 Apr 10 1999 - - * You shouldn't notice a thing, but a lot has changed wrt key +* You shouldn't notice a thing, but a lot has changed wrt key management - except that it refuses to talk to versions < 0.2.20 -Version 0.2.19 Apr 3 1999 +# Version 0.2.19 Apr 3 1999 - * Don't install a libcipher.so. +* Don't install a libcipher.so. -Version 0.2.18 Apr 3 1999 +# Version 0.2.18 Apr 3 1999 - * Blowfish library dynamically loaded upon execution. +* Blowfish library dynamically loaded upon execution. +* Included Eric Young's IDEA library. - * Included Eric Young's IDEA library. +# Version 0.2.17 Apr 1 1999 -Version 0.2.17 Apr 1 1999 +* Tincd now re-executes itself in case of a segmentation fault. - * Tincd now re-executes itself in case of a segmentation fault. +# Version 0.2.16 Apr 1 1999 -Version 0.2.16 Apr 1 1999 +* Wrote tincd.conf(5) man page, which still needs a lot of work. +* Config file now accepts and tolerates spaces, and any integer base + for integer variables, and better error reporting. See + doc/tincd.conf.sample for an example. - * Wrote tincd.conf(5) man page, which still needs a lot of work. +# Version 0.2.15 Mar 29 1999 - * Config file now accepts and tolerates spaces, and any integer base - for integer variables, and better error reporting. See - doc/tincd.conf.sample for an example. +* Fixed bugs. -Version 0.2.15 Mar 29 1999 +# Version 0.2.14 Feb 10 1999 - * Fixed bugs. +* Added --timeout flag and PingTimeout configuration. +* Did some first syslog cleanup work. -Version 0.2.14 Feb 10 1999 +# Version 0.2.13 Jan 23 1999 - * Added --timeout flag and PingTimeout configuration. - * Did some first syslog cleanup work. +* Bugfixes. -Version 0.2.13 Jan 23 1999 +# Version 0.2.12 Jan 23 1999 - * Bugfixes. +* Fixed nauseating bug so that it would crash whenever a connection + got lost. -Version 0.2.12 Jan 23 1999 +# Version 0.2.11 Jan 22 1999 - * Fixed nauseating bug so that it would crash whenever a connection - got lost. +* Framework for multiple connections has been done. +* Simple manpage for tincd. -Version 0.2.11 Jan 22 1999 +# Version 0.2.10 Jan 18 1999 - * Framework for multiple connections has been done. +* Passphrase support added. - * Simple manpage for tincd. +# Version 0.2.9 Jan 13 1999 -Version 0.2.10 Jan 18 1999 +* Bugs fixed. - * Passphrase support added. +# Version 0.2.8 Jan 11 1999 -Version 0.2.9 Jan 13 1999 +* A reworked protocol version. +* A ping/pong system. +* More reliable networking code. +* Automatic reconnection. +* Still does not work with more than one connection :) +* Strips MAC addresses before sending, so there's less overhead, and + less redundancy. - * Bugs fixed. +# Version 0.2.7 Jan 3 1999 -Version 0.2.8 Jan 11 1999 +* Several updates to make extending more easy. - * A reworked protocol version. +# Version 0.2.6 Dec 20 1998 - * A ping/pong system. +* Point-to-Point connections have been established, including + Blowfish encryption and a secret key-exchange. - * More reliable networking code. +# Version 0.2.5 Dec 16 1998 - * Automatic reconnection. +* Project renamed to tinc, in honour of TINC. - * Still does not work with more than one connection :) +# Version 0.2.4 Dec 16 1998 - * Strips MAC addresses before sending, so there's less overhead, and - less redundancy. +* Now it really does ;) -Version 0.2.7 Jan 3 1999 +# Version 0.2.3 Nov 24 1998 - * Several updates to make extending more easy. +* It sort of works now. -Version 0.2.6 Dec 20 1998 +# Version 0.2.2 Nov 20 1998 - * Point-to-Point connections have been established, including - Blowfish encryption and a secret key-exchange. +* Uses GNU gmp. -Version 0.2.5 Dec 16 1998 +# Version 0.2.1 Nov 14 1998 - * Project renamed to tinc, in honour of TINC. - -Version 0.2.4 Dec 16 1998 - - * Now it really does ;) - -Version 0.2.3 Nov 24 1998 - - * It sort of works now. - -Version 0.2.2 Nov 20 1998 - - * Uses GNU gmp. - -Version 0.2.1 Nov 14 1998 - - * Bare version. +* Bare version. diff --git a/README b/README index c88027b..a44853a 100644 --- a/README +++ b/README @@ -1,11 +1,7 @@ -This is the README file for tinc version 1.1pre11. Installation +This is the README file for tinc version 1.1pre12. Installation instructions may be found in the INSTALL file. -tinc is Copyright (C) 1998-2014 by: - -Ivo Timmermans, -Guus Sliepen , -and others. +tinc is Copyright © 1998-2016 Ivo Timmermans, Guus Sliepen , and others. For a complete list of authors see the AUTHORS file. @@ -36,11 +32,12 @@ at your own risk. Compatibility ------------- -Version 1.1pre11 is compatible with 1.0pre8, 1.0 and later, but not with older +Version 1.1pre12 is compatible with 1.0pre8, 1.0 and later, but not with older versions of tinc. When the ExperimentalProtocol option is used, tinc is still compatible with -1.0.X and 1.1pre11 itself, but not with any other 1.1preX version. +1.0.X, 1.1pre11 and later, but not with any version between 1.1pre1 and +1.1pre10. Requirements @@ -49,15 +46,14 @@ Requirements In order to compile tinc, you will need a GNU C compiler environment. Please ensure you have the latest stable versions of all the required libraries: -- OpenSSL (http://www.openssl.org/) version 1.0.0 or later, with support for - elliptic curve cryptography (ECC) and Galois counter mode (GCM) enabled. +- LibreSSL (http://www.libressl.org/) or OpenSSL (https://openssl.org/) version 1.0.0 or later. The following libraries are used by default, but can be disabled if necessary: -- zlib (http://www.gzip.org/zlib/) -- lzo (http://www.oberhumer.com/opensource/lzo/) +- zlib (http://www.zlib.net/) +- LZO (https://www.oberhumer.com/opensource/lzo/) - ncurses (http://invisible-island.net/ncurses/) -- readline (ftp://ftp.gnu.org/pub/gnu/readline/) +- readline (https://cnswww.cns.cwru.edu/php/chet/readline/rltop.html) Features @@ -70,12 +66,12 @@ those nodes, tinc will learn about all other nodes on the VPN, and will make connections automatically. When direct connections are not possible, data will be forwarded by intermediate nodes. -By default, nodes authenticate each other using 2048 bit RSA (or 521 bit -ECDSA*) keys. Traffic is encrypted using Blowfish in CBC mode (or AES-256 in -GCM mode*), authenticated using HMAC-SHA1 (or GCM*), and is protected against -replay attacks. - -*) When using the ExperimentalProtocol option. +Tinc 1.1 support two protocols. The first is a legacy protocol that provides +backwards compatibility with tinc 1.0 nodes, and which by default uses 2048 bit +RSA keys for authentication, and encrypts traffic using Blowfish in CBC mode +and HMAC-SHA1. The second is a new protocol which uses Curve25519 keys for +authentication, and encrypts traffic using Chacha20-Poly1305, and provides +forward secrecy. Tinc fully supports IPv6. @@ -85,7 +81,7 @@ modes, "switch" and "hub", let the tinc daemons work together to form a virtual Ethernet network switch or hub. Normally, when started tinc will detach and run in the background. In a native -Windows environment this means tinc will intall itself as a service, which will +Windows environment this means tinc will install itself as a service, which will restart after reboots. To prevent tinc from detaching or running as a service, use the -D option. diff --git a/README.android b/README.android index 6fffe41..7d8e853 100644 --- a/README.android +++ b/README.android @@ -1,20 +1,23 @@ -Quick how-o cross compile tinc for android (done from $HOME/android/): +Quick how-to cross compile tinc for Android (done from $HOME/android/): -- Download android NDK and setup local ARM toolchain: -wget http://dl.google.com/android/ndk/android-ndk-r8b-linux-x86.tar.bz2 -tar xfj android-ndk-r8b-linux-x86.tar.bz2 -./android-ndk-r8b/build/tools/make-standalone-toolchain.sh --platform=android-5 --install-dir=/tmp/my-android-toolchain +- Download Android NDK and setup local ARM toolchain: -- Download and cross-compile openSSL for ARM: -wget http://www.openssl.org/source/openssl-1.0.1c.tar.gz -tar xfz openssl-1.0.1c.tar.gz -cd openssl-1.0.1c -./Configure dist -make CC=/tmp/my-android-toolchain/bin/arm-linux-androideabi-gcc AR="/tmp/my-android-toolchain/bin/arm-linux-androideabi-ar r" RANLIB=/tmp/my-android-toolchain/bin/arm-linux-androideabi-ranlib + wget http://dl.google.com/android/ndk/android-ndk-r8b-linux-x86.tar.bz2 + tar xfj android-ndk-r8b-linux-x86.tar.bz2 + ./android-ndk-r8b/build/tools/make-standalone-toolchain.sh --platform=android-5 --install-dir=/tmp/my-android-toolchain + +- Download and cross-compile OpenSSL for ARM: + + wget http://www.openssl.org/source/openssl-1.0.1c.tar.gz + tar xfz openssl-1.0.1c.tar.gz + cd openssl-1.0.1c + ./Configure dist + make CC=/tmp/my-android-toolchain/bin/arm-linux-androideabi-gcc AR="/tmp/my-android-toolchain/bin/arm-linux-androideabi-ar r" RANLIB=/tmp/my-android-toolchain/bin/arm-linux-androideabi-ranlib - Clone and cross-compile tinc: -git clone git://tinc-vpn.org/tinc -cd tinc -autoreconf -fsi -CC=/tmp/my-android-toolchain/bin/arm-linux-androideabi-gcc ./configure --host=arm-linux --disable-lzo --with-openssl-lib=$HOME/android/openssl-1.0.1c --with-openssl-include=$HOME/android/openssl-1.0.1c/include/ -make -j5 + + git clone git://tinc-vpn.org/tinc + cd tinc + autoreconf -fsi + CC=/tmp/my-android-toolchain/bin/arm-linux-androideabi-gcc ./configure --host=arm-linux --disable-lzo --with-openssl-lib=$HOME/android/openssl-1.0.1c --with-openssl-include=$HOME/android/openssl-1.0.1c/include/ + make -j5 diff --git a/THANKS b/THANKS index d1ee6b4..527cc61 100644 --- a/THANKS +++ b/THANKS @@ -14,6 +14,7 @@ We would like to thank the following people for their contributions to tinc: * Cheng LI * Cris van Pelt * Darius Jahandarie +* Dato Simó * David Pflug * Delf Eldkraft * Dennis Joachimsthaler @@ -22,11 +23,14 @@ We would like to thank the following people for their contributions to tinc: * Erik Tews * Etienne Dechamps * Florent Clairambault +* Florian Klink +* Florian Weik * Flynn Marquardt * Franz Pletz * Gary Kessler and Claudia Gonzalez * Grzegorz Dymarek * Hans Bayle +* Harvest * Ivo van Dong * James Cook * James MacLean @@ -34,14 +38,17 @@ We would like to thank the following people for their contributions to tinc: * Jason Harper * Jason Livesay * Jelle de Jong +* Jeroen Domburg * Jeroen Ubbink * Jerome Etienne +* Jo-Philipp Wich * Jochen Voss * Julien Muchembled * Lavrans Laading * Loïc Dachary * Loïc Grenié * Lubomír Bulej +* LunarShaddow * Mads Kiilerich * Marc A. Lehmann * Mark Glines @@ -50,36 +57,51 @@ We would like to thank the following people for their contributions to tinc: * Martin Kihlgren * Martin Schobert * Martin Schürrer +* Martin Weinelt * Matias Carrasco * Max Rijevski * Menno Smits * Mesar Hameed * Michael Tokarev * Miles Nordin +* Nathan Stratton Treadway +* Murat Donmez * Nick Hibma * Nick Patavalis * Paul Littlefield * Philipp Babel +* Pierre Emeriaud +* Rafał Leśniak +* Rhosyn Celyn * Robert van der Meulen * Rumko +* Sam Bryan +* Samuel Thibault * Saverio Proto * Scott Lamb * Steffan Karger +* Stig Fagrell * Sven-Haegar Koch * Teemu Kiviniemi * Thomas Tsiakalakis +* thorkill * Timothy Redaelli +* Tomasz Fortuna * Tomislav Čohar * Tommy Arnkværn * Tonnerre Lombard +* Ulrich Seifert * Vil Brekin * Vittorio Gambaletta * Wessel Dankers * William A. Kennington III * William McArthur * Wouter van Heyst +* xentec +* 戴 鸣 And everyone we forgot (if we did, please let us know). Thank you! -Ivo Timmermans -Guus Sliepen +--- +Ivo Timmermans, +Guus Sliepen. diff --git a/aclocal.m4 b/aclocal.m4 index 16c89a3..8d101b4 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -1,6 +1,6 @@ -# generated automatically by aclocal 1.14.1 -*- Autoconf -*- +# generated automatically by aclocal 1.15 -*- Autoconf -*- -# Copyright (C) 1996-2013 Free Software Foundation, Inc. +# Copyright (C) 1996-2014 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -20,7 +20,7 @@ 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'.])]) -# Copyright (C) 2002-2013 Free Software Foundation, Inc. +# Copyright (C) 2002-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -32,10 +32,10 @@ To do so, use the procedure documented by the package, typically 'autoreconf'.]) # generated from the m4 files accompanying Automake X.Y. # (This private macro should not be called outside this file.) AC_DEFUN([AM_AUTOMAKE_VERSION], -[am__api_version='1.14' +[am__api_version='1.15' 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.14.1], [], +m4_if([$1], [1.15], [], [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl ]) @@ -51,14 +51,14 @@ 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.14.1])dnl +[AM_AUTOMAKE_VERSION([1.15])dnl m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) # AM_AUX_DIR_EXPAND -*- Autoconf -*- -# Copyright (C) 2001-2013 Free Software Foundation, Inc. +# Copyright (C) 2001-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -110,7 +110,7 @@ am_aux_dir=`cd "$ac_aux_dir" && pwd` # AM_CONDITIONAL -*- Autoconf -*- -# Copyright (C) 1997-2013 Free Software Foundation, Inc. +# Copyright (C) 1997-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -141,7 +141,7 @@ AC_CONFIG_COMMANDS_PRE( Usually this means the macro was only invoked conditionally.]]) fi])]) -# Copyright (C) 1999-2013 Free Software Foundation, Inc. +# Copyright (C) 1999-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -332,7 +332,7 @@ _AM_SUBST_NOTMAKE([am__nodep])dnl # Generate code to set up dependency tracking. -*- Autoconf -*- -# Copyright (C) 1999-2013 Free Software Foundation, Inc. +# Copyright (C) 1999-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -408,7 +408,7 @@ AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], # Do all the work for Automake. -*- Autoconf -*- -# Copyright (C) 1996-2013 Free Software Foundation, Inc. +# Copyright (C) 1996-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -498,8 +498,8 @@ AC_REQUIRE([AC_PROG_MKDIR_P])dnl # # AC_SUBST([mkdir_p], ['$(MKDIR_P)']) -# We need awk for the "check" target. The system "awk" is bad on -# some platforms. +# We need awk for the "check" target (and possibly the TAP driver). The +# system "awk" is bad on some platforms. AC_REQUIRE([AC_PROG_AWK])dnl AC_REQUIRE([AC_PROG_MAKE_SET])dnl AC_REQUIRE([AM_SET_LEADING_DOT])dnl @@ -573,6 +573,9 @@ END AC_MSG_ERROR([Your 'rm' program is bad, sorry.]) fi fi +dnl The trailing newline in this macro's definition is deliberate, for +dnl backward compatibility and to allow trailing 'dnl'-style comments +dnl after the AM_INIT_AUTOMAKE invocation. See automake bug#16841. ]) dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not @@ -602,7 +605,7 @@ for _am_header in $config_headers :; do done echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) -# Copyright (C) 2001-2013 Free Software Foundation, Inc. +# Copyright (C) 2001-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -613,7 +616,7 @@ echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_co # Define $install_sh. AC_DEFUN([AM_PROG_INSTALL_SH], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl -if test x"${install_sh}" != xset; then +if test x"${install_sh+set}" != xset; then case $am_aux_dir in *\ * | *\ *) install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; @@ -623,7 +626,7 @@ if test x"${install_sh}" != xset; then fi AC_SUBST([install_sh])]) -# Copyright (C) 2003-2013 Free Software Foundation, Inc. +# Copyright (C) 2003-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -644,7 +647,7 @@ AC_SUBST([am__leading_dot])]) # Check to see how 'make' treats includes. -*- Autoconf -*- -# Copyright (C) 2001-2013 Free Software Foundation, Inc. +# Copyright (C) 2001-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -694,7 +697,7 @@ rm -f confinc confmf # Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- -# Copyright (C) 1997-2013 Free Software Foundation, Inc. +# Copyright (C) 1997-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -733,7 +736,7 @@ fi # Helper functions for option handling. -*- Autoconf -*- -# Copyright (C) 2001-2013 Free Software Foundation, Inc. +# Copyright (C) 2001-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -762,7 +765,7 @@ AC_DEFUN([_AM_SET_OPTIONS], AC_DEFUN([_AM_IF_OPTION], [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) -# Copyright (C) 1999-2013 Free Software Foundation, Inc. +# Copyright (C) 1999-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -809,7 +812,7 @@ AC_LANG_POP([C])]) # For backward compatibility. AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])]) -# Copyright (C) 2001-2013 Free Software Foundation, Inc. +# Copyright (C) 2001-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -828,7 +831,7 @@ AC_DEFUN([AM_RUN_LOG], # Check to make sure that the build environment is sane. -*- Autoconf -*- -# Copyright (C) 1996-2013 Free Software Foundation, Inc. +# Copyright (C) 1996-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -909,7 +912,7 @@ AC_CONFIG_COMMANDS_PRE( rm -f conftest.file ]) -# Copyright (C) 2009-2013 Free Software Foundation, Inc. +# Copyright (C) 2009-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -969,7 +972,7 @@ AC_SUBST([AM_BACKSLASH])dnl _AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl ]) -# Copyright (C) 2001-2013 Free Software Foundation, Inc. +# Copyright (C) 2001-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -997,7 +1000,7 @@ fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" AC_SUBST([INSTALL_STRIP_PROGRAM])]) -# Copyright (C) 2006-2013 Free Software Foundation, Inc. +# Copyright (C) 2006-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -1016,7 +1019,7 @@ AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) # Check how to create a tarball. -*- Autoconf -*- -# Copyright (C) 2004-2013 Free Software Foundation, Inc. +# Copyright (C) 2004-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -1153,6 +1156,7 @@ m4_include([m4/ax_check_link_flag.m4]) m4_include([m4/curses.m4]) m4_include([m4/libgcrypt.m4]) m4_include([m4/lzo.m4]) +m4_include([m4/miniupnpc.m4]) m4_include([m4/openssl.m4]) m4_include([m4/readline.m4]) m4_include([m4/zlib.m4]) diff --git a/compile b/compile index 531136b..a85b723 100755 --- a/compile +++ b/compile @@ -3,7 +3,7 @@ scriptversion=2012-10-14.11; # UTC -# Copyright (C) 1999-2013 Free Software Foundation, Inc. +# Copyright (C) 1999-2014 Free Software Foundation, Inc. # Written by Tom Tromey . # # This program is free software; you can redistribute it and/or modify diff --git a/config.guess b/config.guess index 1f5c50c..1659250 100755 --- a/config.guess +++ b/config.guess @@ -1,8 +1,8 @@ #! /bin/sh # Attempt to guess a canonical system name. -# Copyright 1992-2014 Free Software Foundation, Inc. +# Copyright 1992-2015 Free Software Foundation, Inc. -timestamp='2014-03-23' +timestamp='2015-08-20' # 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 @@ -24,12 +24,12 @@ timestamp='2014-03-23' # program. This Exception is an additional permission under section 7 # of the GNU General Public License, version 3 ("GPLv3"). # -# Originally written by Per Bothner. +# Originally written by Per Bothner; maintained since 2000 by Ben Elliston. # # 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 # -# Please send patches with a ChangeLog entry to config-patches@gnu.org. +# Please send patches to . me=`echo "$0" | sed -e 's,.*/,,'` @@ -50,7 +50,7 @@ version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. -Copyright 1992-2014 Free Software Foundation, Inc. +Copyright 1992-2015 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." @@ -168,20 +168,27 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in # Note: NetBSD doesn't particularly care about the vendor # portion of the name. We always set it to "unknown". sysctl="sysctl -n hw.machine_arch" - UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ - /usr/sbin/$sysctl 2>/dev/null || echo unknown)` + UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \ + /sbin/$sysctl 2>/dev/null || \ + /usr/sbin/$sysctl 2>/dev/null || \ + echo unknown)` case "${UNAME_MACHINE_ARCH}" in armeb) machine=armeb-unknown ;; arm*) machine=arm-unknown ;; sh3el) machine=shl-unknown ;; sh3eb) machine=sh-unknown ;; sh5el) machine=sh5le-unknown ;; + earmv*) + arch=`echo ${UNAME_MACHINE_ARCH} | sed -e 's,^e\(armv[0-9]\).*$,\1,'` + endian=`echo ${UNAME_MACHINE_ARCH} | sed -ne 's,^.*\(eb\)$,\1,p'` + machine=${arch}${endian}-unknown + ;; *) machine=${UNAME_MACHINE_ARCH}-unknown ;; esac # The Operating System including object format, if it has switched # to ELF recently, or will in the future. case "${UNAME_MACHINE_ARCH}" in - arm*|i386|m68k|ns32k|sh3*|sparc|vax) + arm*|earm*|i386|m68k|ns32k|sh3*|sparc|vax) eval $set_cc_for_build if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ELF__ @@ -197,6 +204,13 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in os=netbsd ;; esac + # Determine ABI tags. + case "${UNAME_MACHINE_ARCH}" in + earm*) + expr='s/^earmv[0-9]/-eabi/;s/eb$//' + abi=`echo ${UNAME_MACHINE_ARCH} | sed -e "$expr"` + ;; + esac # The OS release # Debian GNU/NetBSD machines have a different userland, and # thus, need a distinct triplet. However, they do not need @@ -207,13 +221,13 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in release='-gnu' ;; *) - release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + release=`echo ${UNAME_RELEASE} | sed -e 's/[-_].*//' | cut -d. -f1,2` ;; esac # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: # contains redundant information, the shorter form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. - echo "${machine}-${os}${release}" + echo "${machine}-${os}${release}${abi}" exit ;; *:Bitrig:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` @@ -235,6 +249,9 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in *:MirBSD:*:*) echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} exit ;; + *:Sortix:*:*) + echo ${UNAME_MACHINE}-unknown-sortix + exit ;; alpha:OSF1:*:*) case $UNAME_RELEASE in *4.0) @@ -579,8 +596,9 @@ EOF else IBM_ARCH=powerpc fi - if [ -x /usr/bin/oslevel ] ; then - IBM_REV=`/usr/bin/oslevel` + if [ -x /usr/bin/lslpp ] ; then + IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc | + awk -F: '{ print $3 }' | sed s/[0-9]*$/0/` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi @@ -932,6 +950,9 @@ EOF crisv32:Linux:*:*) echo ${UNAME_MACHINE}-axis-linux-${LIBC} exit ;; + e2k:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; frv:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; @@ -1020,7 +1041,7 @@ EOF echo ${UNAME_MACHINE}-dec-linux-${LIBC} exit ;; x86_64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo ${UNAME_MACHINE}-pc-linux-${LIBC} exit ;; xtensa*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} diff --git a/config.h.in b/config.h.in index 96a6079..1a567a2 100644 --- a/config.h.in +++ b/config.h.in @@ -1,5 +1,8 @@ /* config.h.in. Generated from configure.ac by autoheader. */ +/* Disable support for the legacy (tinc 1.0) protocol */ +#undef DISABLE_LEGACY + /* Support for jumbograms (packets up to 9000 bytes) */ #undef ENABLE_JUMBOGRAMS @@ -36,22 +39,6 @@ /* Darwin (MacOS/X) */ #undef HAVE_DARWIN -/* Define to 1 if you have the declaration of `freeaddrinfo', and to 0 if you - don't. */ -#undef HAVE_DECL_FREEADDRINFO - -/* Define to 1 if you have the declaration of `gai_strerror', and to 0 if you - don't. */ -#undef HAVE_DECL_GAI_STRERROR - -/* Define to 1 if you have the declaration of `getaddrinfo', and to 0 if you - don't. */ -#undef HAVE_DECL_GETADDRINFO - -/* Define to 1 if you have the declaration of `getnameinfo', and to 0 if you - don't. */ -#undef HAVE_DECL_GETNAMEINFO - /* Define to 1 if you have the declaration of `OpenSSL_add_all_algorithms', and to 0 if you don't. */ #undef HAVE_DECL_OPENSSL_ADD_ALL_ALGORITHMS @@ -60,6 +47,9 @@ don't. */ #undef HAVE_DECL_RES_INIT +/* Define to 1 if you have the `devname' function. */ +#undef HAVE_DEVNAME + /* Define to 1 if you have the header file. */ #undef HAVE_DIRENT_H @@ -72,6 +62,9 @@ /* Define to 1 if you have the `fchmod' function. */ #undef HAVE_FCHMOD +/* Define to 1 if you have the `fdevname' function. */ +#undef HAVE_FDEVNAME + /* Define to 1 if you have the `flock' function. */ #undef HAVE_FLOCK @@ -87,18 +80,18 @@ /* Define to 1 if you have the header file. */ #undef HAVE_GCRYPT_H +/* Define to 1 if you have the header file. */ +#undef HAVE_GETOPT_H + +/* getopt_long() */ +#undef HAVE_GETOPT_LONG + /* Define to 1 if you have the `gettimeofday' function. */ #undef HAVE_GETTIMEOFDAY -/* Define to 1 if you have the `get_current_dir_name' function. */ -#undef HAVE_GET_CURRENT_DIR_NAME - /* Define to 1 if you have the header file. */ #undef HAVE_INTTYPES_H -/* Define to 1 if you have the `nsl' library (-lnsl). */ -#undef HAVE_LIBNSL - /* Define to 1 if you have the `resolv' library (-lresolv). */ #undef HAVE_LIBRESOLV @@ -132,9 +125,18 @@ /* MinGW */ #undef HAVE_MINGW +/* have miniupnpc support */ +#undef HAVE_MINIUPNPC + +/* Define to 1 if you have the header file. */ +#undef HAVE_MINIUPNPC_MINIUPNPC_H + /* Define to 1 if you have the `mlockall' function. */ #undef HAVE_MLOCKALL +/* Define to 1 if you have the `nanosleep' function. */ +#undef HAVE_NANOSLEEP + /* NetBSD */ #undef HAVE_NETBSD @@ -189,6 +191,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_NET_IF_TYPES_H +/* Define to 1 if you have the header file. */ +#undef HAVE_NET_IF_UTUN_H + /* Define to 1 if you have the header file. */ #undef HAVE_NET_TAP_IF_TAP_H @@ -222,9 +227,6 @@ /* Define to 1 if you have the `putenv' function. */ #undef HAVE_PUTENV -/* Define to 1 if you have the `random' function. */ -#undef HAVE_RANDOM - /* Define to 1 if you have the `RAND_status' function. */ #undef HAVE_RAND_STATUS @@ -237,33 +239,21 @@ /* Define to 1 if you have the header file. */ #undef HAVE_READLINE_READLINE_H +/* Define to 1 if you have the `recvmmsg' function. */ +#undef HAVE_RECVMMSG + /* Define to 1 if you have the header file. */ #undef HAVE_RESOLV_H -/* Define to 1 if you have the `select' function. */ -#undef HAVE_SELECT - -/* Define to 1 if the system has the type `socklen_t'. */ -#undef HAVE_SOCKLEN_T - /* Solaris/SunOS */ #undef HAVE_SOLARIS -/* Define to 1 if you have the header file. */ -#undef HAVE_STDBOOL_H - /* Define to 1 if you have the header file. */ #undef HAVE_STDINT_H /* Define to 1 if you have the header file. */ #undef HAVE_STDLIB_H -/* Define to 1 if you have the `strdup' function. */ -#undef HAVE_STRDUP - -/* Define to 1 if you have the `strerror' function. */ -#undef HAVE_STRERROR - /* Define to 1 if you have the header file. */ #undef HAVE_STRINGS_H @@ -273,12 +263,6 @@ /* Define to 1 if you have the `strsignal' function. */ #undef HAVE_STRSIGNAL -/* Define to 1 if you have the `strtol' function. */ -#undef HAVE_STRTOL - -/* Define to 1 if the system has the type `struct addrinfo'. */ -#undef HAVE_STRUCT_ADDRINFO - /* Define to 1 if the system has the type `struct arphdr'. */ #undef HAVE_STRUCT_ARPHDR @@ -294,12 +278,6 @@ /* Define to 1 if the system has the type `struct icmp6_hdr'. */ #undef HAVE_STRUCT_ICMP6_HDR -/* Define to 1 if the system has the type `struct in6_addr'. */ -#undef HAVE_STRUCT_IN6_ADDR - -/* Define to 1 if the system has the type `struct in_addr'. */ -#undef HAVE_STRUCT_IN_ADDR - /* Define to 1 if the system has the type `struct ip'. */ #undef HAVE_STRUCT_IP @@ -312,15 +290,9 @@ /* Define to 1 if the system has the type `struct nd_opt_hdr'. */ #undef HAVE_STRUCT_ND_OPT_HDR -/* Define to 1 if the system has the type `struct sockaddr_in6'. */ -#undef HAVE_STRUCT_SOCKADDR_IN6 - /* Define to 1 if you have the header file. */ #undef HAVE_SYSLOG_H -/* Define to 1 if you have the `system' function. */ -#undef HAVE_SYSTEM - /* Define to 1 if you have the header file. */ #undef HAVE_SYS_FILE_H @@ -348,36 +320,21 @@ /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TYPES_H -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_UIO_H - /* Define to 1 if you have the header file. */ #undef HAVE_SYS_UN_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_WAIT_H -/* Define to 1 if you have the `time' function. */ -#undef HAVE_TIME - -/* Define to 1 if you have the header file. */ -#undef HAVE_TIME_H - /* Define to 1 if you have the header file. */ #undef HAVE_UNISTD_H /* Define to 1 if you have the `unsetenv' function. */ #undef HAVE_UNSETENV -/* Define to 1 if you have the `usleep' function. */ -#undef HAVE_USLEEP - /* Define to 1 if you have the `vsyslog' function. */ #undef HAVE_VSYSLOG -/* Define to 1 if you have the `writev' function. */ -#undef HAVE_WRITEV - /* have zlib compression support */ #undef HAVE_ZLIB @@ -414,12 +371,6 @@ /* Define to 1 if you have the ANSI C header files. */ #undef STDC_HEADERS -/* Define to 1 if you can safely include both and . */ -#undef TIME_WITH_SYS_TIME - -/* Define to 1 if your declares `struct tm'. */ -#undef TM_IN_SYS_TIME - /* Enable extensions on AIX 3, Interix. */ #ifndef _ALL_SOURCE # undef _ALL_SOURCE @@ -445,9 +396,6 @@ /* Version number of package */ #undef VERSION -/* Compile with support for Windows 2000 */ -#undef WITH_WINDOWS2000 - /* Define to 1 if on MINIX. */ #undef _MINIX @@ -466,16 +414,3 @@ /* Defined if the __warn_unused_result__ attribute is not supported. */ #undef __warn_unused_result__ - -/* Define to empty if `const' does not conform to ANSI C. */ -#undef const - -/* Define to `int' if does not define. */ -#undef pid_t - -/* Define to `unsigned int' if does not define. */ -#undef size_t - -/* Define to empty if the keyword `volatile' does not work. Warning: valid - code using `volatile' can become incorrect without. Disable with care. */ -#undef volatile diff --git a/config.sub b/config.sub index bba4efb..1acc966 100755 --- a/config.sub +++ b/config.sub @@ -1,8 +1,8 @@ #! /bin/sh # Configuration validation subroutine script. -# Copyright 1992-2014 Free Software Foundation, Inc. +# Copyright 1992-2015 Free Software Foundation, Inc. -timestamp='2014-09-11' +timestamp='2015-08-20' # 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 @@ -25,7 +25,7 @@ timestamp='2014-09-11' # of the GNU General Public License, version 3 ("GPLv3"). -# Please send patches with a ChangeLog entry to config-patches@gnu.org. +# Please send patches to . # # Configuration subroutine to validate and canonicalize a configuration type. # Supply the specified configuration type as an argument. @@ -68,7 +68,7 @@ Report bugs and patches to ." version="\ GNU config.sub ($timestamp) -Copyright 1992-2014 Free Software Foundation, Inc. +Copyright 1992-2015 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." @@ -117,7 +117,7 @@ maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` case $maybe_os in nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ - knetbsd*-gnu* | netbsd*-gnu* | \ + knetbsd*-gnu* | netbsd*-gnu* | netbsd*-eabi* | \ kopensolaris*-gnu* | \ storm-chaos* | os2-emx* | rtmk-nova*) os=-$maybe_os @@ -255,12 +255,13 @@ case $basic_machine in | arc | arceb \ | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \ | avr | avr32 \ + | ba \ | be32 | be64 \ | bfin \ | c4x | c8051 | clipper \ | d10v | d30v | dlx | dsp16xx \ - | epiphany \ - | fido | fr30 | frv \ + | e2k | epiphany \ + | fido | fr30 | frv | ft32 \ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ | hexagon \ | i370 | i860 | i960 | ia64 \ @@ -305,7 +306,7 @@ case $basic_machine in | riscv32 | riscv64 \ | rl78 | rx \ | score \ - | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ + | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[234]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ | sh64 | sh64le \ | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ @@ -313,6 +314,7 @@ case $basic_machine in | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ | ubicom32 \ | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ + | visium \ | we32k \ | x86 | xc16x | xstormy16 | xtensa \ | z8k | z80) @@ -327,6 +329,9 @@ case $basic_machine in c6x) basic_machine=tic6x-unknown ;; + leon|leon[3-9]) + basic_machine=sparc-$basic_machine + ;; m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip) basic_machine=$basic_machine-unknown os=-none @@ -372,12 +377,13 @@ case $basic_machine in | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ | avr-* | avr32-* \ + | ba-* \ | be32-* | be64-* \ | bfin-* | bs2000-* \ | c[123]* | c30-* | [cjt]90-* | c4x-* \ | c8051-* | clipper-* | craynv-* | cydra-* \ | d10v-* | d30v-* | dlx-* \ - | elxsi-* \ + | e2k-* | elxsi-* \ | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ | h8300-* | h8500-* \ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ @@ -424,12 +430,13 @@ case $basic_machine in | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ | pyramid-* \ + | riscv32-* | riscv64-* \ | rl78-* | 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-* | sv1-* | sx?-* \ + | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx*-* \ | tahoe-* \ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ | tile*-* \ @@ -437,6 +444,7 @@ case $basic_machine in | ubicom32-* \ | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ | vax-* \ + | visium-* \ | we32k-* \ | x86-* | x86_64-* | xc16x-* | xps100-* \ | xstormy16-* | xtensa*-* \ @@ -513,6 +521,9 @@ case $basic_machine in basic_machine=i386-pc os=-aros ;; + asmjs) + basic_machine=asmjs-unknown + ;; aux) basic_machine=m68k-apple os=-aux @@ -774,6 +785,9 @@ case $basic_machine in basic_machine=m68k-isi os=-sysv ;; + leon-*|leon[3-9]-*) + basic_machine=sparc-`echo $basic_machine | sed 's/-.*//'` + ;; m68knommu) basic_machine=m68k-unknown os=-linux @@ -1365,7 +1379,7 @@ case $os in | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ | -sym* | -kopensolaris* | -plan9* \ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ - | -aos* | -aros* \ + | -aos* | -aros* | -cloudabi* | -sortix* \ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ diff --git a/configure b/configure index e1bc385..61f340b 100755 --- a/configure +++ b/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for tinc 1.1pre11. +# Generated by GNU Autoconf 2.69 for tinc tinc-1.1pre12. # # # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. @@ -577,8 +577,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='tinc' PACKAGE_TARNAME='tinc' -PACKAGE_VERSION='1.1pre11' -PACKAGE_STRING='tinc 1.1pre11' +PACKAGE_VERSION='tinc-1.1pre12' +PACKAGE_STRING='tinc tinc-1.1pre12' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -623,12 +623,19 @@ ac_subst_vars='am__EXEEXT_FALSE am__EXEEXT_TRUE LTLIBOBJS LIBOBJS +MINIUPNPC_FALSE +MINIUPNPC_TRUE +MINIUPNPC_LIBS GCRYPT_FALSE GCRYPT_TRUE OPENSSL_FALSE OPENSSL_TRUE READLINE_LIBS CURSES_LIBS +GETOPT_FALSE +GETOPT_TRUE +WITH_SYSTEMD_FALSE +WITH_SYSTEMD_TRUE TUNEMU_FALSE TUNEMU_TRUE VDE_FALSE @@ -645,6 +652,7 @@ BSD_FALSE BSD_TRUE LINUX_FALSE LINUX_TRUE +systemd_path host_os host_vendor host_cpu @@ -720,6 +728,7 @@ infodir docdir oldincludedir includedir +runstatedir localstatedir sharedstatedir sysconfdir @@ -747,8 +756,9 @@ enable_silent_rules enable_uml enable_vde enable_tunemu -with_windows2000 +with_systemd enable_hardening +enable_legacy_protocol enable_curses with_curses with_curses_include @@ -771,6 +781,10 @@ with_libgcrypt_lib with_openssl with_openssl_include with_openssl_lib +enable_miniupnpc +with_miniupnpc +with_miniupnpc_include +with_miniupnpc_lib enable_jumbograms ' ac_precious_vars='build_alias @@ -820,6 +834,7 @@ datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' +runstatedir='${localstatedir}/run' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' @@ -1072,6 +1087,15 @@ do | -silent | --silent | --silen | --sile | --sil) silent=yes ;; + -runstatedir | --runstatedir | --runstatedi | --runstated \ + | --runstate | --runstat | --runsta | --runst | --runs \ + | --run | --ru | --r) + ac_prev=runstatedir ;; + -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ + | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ + | --run=* | --ru=* | --r=*) + runstatedir=$ac_optarg ;; + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ @@ -1209,7 +1233,7 @@ fi for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ - libdir localedir mandir + libdir localedir mandir runstatedir do eval ac_val=\$$ac_var # Remove trailing slashes. @@ -1322,7 +1346,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures tinc 1.1pre11 to adapt to many kinds of systems. +\`configure' configures tinc tinc-1.1pre12 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1362,6 +1386,7 @@ Fine tuning of the installation directories: --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] @@ -1392,7 +1417,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of tinc 1.1pre11:";; + short | recursive ) echo "Configuration of tinc tinc-1.1pre12:";; esac cat <<\_ACEOF @@ -1410,18 +1435,20 @@ Optional Features: --enable-vde enable support for Virtual Distributed Ethernet --enable-tunemu enable support for the tunemu driver --disable-hardening disable compiler and linker hardening flags + --disable-legacy-protocol + disable support for the legacy (tinc 1.0) protocol --disable-curses disable curses support --disable-readline disable readline support --disable-zlib disable zlib compression support --disable-lzo disable lzo compression support + --enable-miniupnpc enable miniupnpc support --enable-jumbograms enable support for jumbograms (packets up to 9000 bytes) Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) - --with-windows2000 compile with support for Windows 2000. This disables - support for tunneling over existing IPv6 networks. + --with-systemd[=DIR] install systemd service files [to DIR if specified] --with-curses=DIR curses base directory, or: --with-curses-include=DIR curses headers directory @@ -1442,11 +1469,16 @@ Optional Packages: /libgcrypt) --with-libgcrypt-lib=DIR libgcrypt library directory - --with-openssl=DIR OpenSSL base directory, or: + --with-openssl=DIR LibreSSL/OpenSSL base directory, or: --with-openssl-include=DIR - OpenSSL headers directory (without trailing + LibreSSL/OpenSSL headers directory (without trailing /openssl) - --with-openssl-lib=DIR OpenSSL library directory + --with-openssl-lib=DIR LibreSSL/OpenSSL library directory + --with-miniupnpc=DIR miniupnpc base directory, or: + --with-miniupnpc-include=DIR + miniupnpc headers directory + --with-miniupnpc-lib=DIR + miniupnpc library directory Some influential environment variables: CC C compiler command @@ -1524,7 +1556,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -tinc configure 1.1pre11 +tinc configure tinc-1.1pre12 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -1989,7 +2021,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by tinc $as_me 1.1pre11, which was +It was created by tinc $as_me tinc-1.1pre12, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -3678,7 +3710,7 @@ $as_echo "$ac_cv_safe_to_define___extensions__" >&6; } -am__api_version='1.14' +am__api_version='1.15' # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or @@ -3867,7 +3899,7 @@ else $as_echo "$as_me: WARNING: 'missing' script is too old or missing" >&2;} fi -if test x"${install_sh}" != xset; then +if test x"${install_sh+set}" != xset; then case $am_aux_dir in *\ * | *\ *) install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; @@ -4224,7 +4256,7 @@ fi # Define the identity of the package. PACKAGE='tinc' - VERSION='1.1pre11' + VERSION='tinc-1.1pre12' cat >>confdefs.h <<_ACEOF @@ -4258,8 +4290,8 @@ MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} # mkdir_p='$(MKDIR_P)' -# We need awk for the "check" target. The system "awk" is bad on -# some platforms. +# We need awk for the "check" target (and possibly the TAP driver). The +# system "awk" is bad on some platforms. # Always define AMTAR for backward compatibility. Yes, it's still used # in the wild :-( We should find a proper way to deprecate it ... AMTAR='$${TAR-tar}' @@ -4448,6 +4480,46 @@ fi ac_config_headers="$ac_config_headers config.h" +# Check whether --enable-silent-rules was given. +if test "${enable_silent_rules+set}" = set; then : + enableval=$enable_silent_rules; +fi + +case $enable_silent_rules in # ((( + yes) AM_DEFAULT_VERBOSITY=0;; + no) AM_DEFAULT_VERBOSITY=1;; + *) AM_DEFAULT_VERBOSITY=0;; +esac +am_make=${MAKE-make} +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 +$as_echo_n "checking whether $am_make supports nested variables... " >&6; } +if ${am_cv_make_support_nested_variables+:} false; then : + $as_echo_n "(cached) " >&6 +else + if $as_echo 'TRUE=$(BAR$(V)) +BAR0=false +BAR1=true +V=1 +am__doit: + @$(TRUE) +.PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then + am_cv_make_support_nested_variables=yes +else + am_cv_make_support_nested_variables=no +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 +$as_echo "$am_cv_make_support_nested_variables" >&6; } +if test $am_cv_make_support_nested_variables = yes; then + AM_V='$(V)' + AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' +else + AM_V=$AM_DEFAULT_VERBOSITY + AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY +fi +AM_BACKSLASH='\' + + # Enable GNU extensions. # Define this here, not in acconfig's @TOP@ section, since definitions # in the latter don't make it into the configure-time tests. @@ -4920,7 +4992,9 @@ $as_echo "#define HAVE_CYGWIN 1" >>confdefs.h $as_echo "#define HAVE_MINGW 1" >>confdefs.h - LIBS="$LIBS -lws2_32 -lgdi32 -lcrypt32" + LIBS="$LIBS -lws2_32 -lgdi32 -lcrypt32 -liphlpapi" + LDFLAGS="$LDFLAGS -static" + CPPFLAGS="$CPPFLAGS -DMINIUPNP_STATICLIB" ;; *) as_fn_error $? "\"Unknown operating system.\"" "$LINENO" 5 @@ -4996,16 +5070,24 @@ fi -# Check whether --with-windows2000 was given. -if test "${with_windows2000+set}" = set; then : - withval=$with_windows2000; if test "x$with_windows2000" = "xyes"; then : - -$as_echo "#define WITH_WINDOWS2000 1" >>confdefs.h +# Check whether --with-systemd was given. +if test "${with_systemd+set}" = set; then : + withval=$with_systemd; systemd=true; systemd_path="$with_systemd" +else + systemd=false fi +if test "x$with_systemd" = "xyes"; then : + systemd_path="/lib/systemd/system" +else + if test "x$with_systemd" = "xno"; then : + systemd=false fi +fi + +systemd_path=$systemd_path if test "$linux" = true; then @@ -5072,6 +5154,14 @@ else TUNEMU_FALSE= fi + if test "$systemd" = true; then + WITH_SYSTEMD_TRUE= + WITH_SYSTEMD_FALSE='#' +else + WITH_SYSTEMD_TRUE='#' + WITH_SYSTEMD_FALSE= +fi + cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure @@ -5159,10 +5249,10 @@ $as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} fi rm -f confcache -if test -d /sw/include ; then +if test -d /sw/include; then : CPPFLAGS="$CPPFLAGS -I/sw/include" fi -if test -d /sw/lib ; then +if test -d /sw/lib; then : LIBS="$LIBS -L/sw/lib" fi @@ -5208,7 +5298,39 @@ else : fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -fno-strict-overflow" >&5 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -fwrapv" >&5 +$as_echo_n "checking whether C compiler accepts -fwrapv... " >&6; } +if ${ax_cv_check_cflags___fwrapv+:} false; then : + $as_echo_n "(cached) " >&6 +else + + ax_check_save_flags=$CFLAGS + CFLAGS="$CFLAGS -fwrapv" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ax_cv_check_cflags___fwrapv=yes +else + ax_cv_check_cflags___fwrapv=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + CFLAGS=$ax_check_save_flags +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___fwrapv" >&5 +$as_echo "$ax_cv_check_cflags___fwrapv" >&6; } +if test x"$ax_cv_check_cflags___fwrapv" = xyes; then : + CPPFLAGS="$CPPFLAGS -fwrapv" +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -fno-strict-overflow" >&5 $as_echo_n "checking whether C compiler accepts -fno-strict-overflow... " >&6; } if ${ax_cv_check_cflags___fno_strict_overflow+:} false; then : $as_echo_n "(cached) " >&6 @@ -5243,39 +5365,6 @@ else : fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -fwrapv" >&5 -$as_echo_n "checking whether C compiler accepts -fwrapv... " >&6; } -if ${ax_cv_check_cflags___fwrapv+:} false; then : - $as_echo_n "(cached) " >&6 -else - - ax_check_save_flags=$CFLAGS - CFLAGS="$CFLAGS -fwrapv" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ax_cv_check_cflags___fwrapv=yes -else - ax_cv_check_cflags___fwrapv=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - CFLAGS=$ax_check_save_flags -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___fwrapv" >&5 -$as_echo "$ax_cv_check_cflags___fwrapv" >&6; } -if test x"$ax_cv_check_cflags___fwrapv" = xyes; then : - CPPFLAGS="$CPPFLAGS -fwrapv" -else - : fi case $host_os in @@ -5504,119 +5593,7 @@ fi fi; -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 -$as_echo_n "checking for ANSI C header files... " >&6; } -if ${ac_cv_header_stdc+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -#include -#include -#include - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_header_stdc=yes -else - ac_cv_header_stdc=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - -if test $ac_cv_header_stdc = yes; then - # SunOS 4.x string.h does not declare mem*, contrary to ANSI. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include - -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "memchr" >/dev/null 2>&1; then : - -else - ac_cv_header_stdc=no -fi -rm -f conftest* - -fi - -if test $ac_cv_header_stdc = yes; then - # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include - -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "free" >/dev/null 2>&1; then : - -else - ac_cv_header_stdc=no -fi -rm -f conftest* - -fi - -if test $ac_cv_header_stdc = yes; then - # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. - if test "$cross_compiling" = yes; then : - : -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -#include -#if ((' ' & 0x0FF) == 0x020) -# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') -# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) -#else -# define ISLOWER(c) \ - (('a' <= (c) && (c) <= 'i') \ - || ('j' <= (c) && (c) <= 'r') \ - || ('s' <= (c) && (c) <= 'z')) -# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) -#endif - -#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) -int -main () -{ - int i; - for (i = 0; i < 256; i++) - if (XOR (islower (i), ISLOWER (i)) - || toupper (i) != TOUPPER (i)) - return 2; - return 0; -} -_ACEOF -if ac_fn_c_try_run "$LINENO"; then : - -else - ac_cv_header_stdc=no -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ - conftest.$ac_objext conftest.beam conftest.$ac_ext -fi - -fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 -$as_echo "$ac_cv_header_stdc" >&6; } -if test $ac_cv_header_stdc = yes; then - -$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/resource.h sys/socket.h sys/time.h sys/uio.h sys/un.h sys/wait.h netdb.h arpa/inet.h dirent.h +for ac_header in syslog.h sys/file.h sys/ioctl.h sys/mman.h sys/param.h sys/resource.h sys/socket.h sys/time.h sys/un.h sys/wait.h netdb.h arpa/inet.h dirent.h getopt.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" @@ -5629,10 +5606,10 @@ fi done -for ac_header in net/if.h net/if_types.h linux/if_tun.h net/if_tun.h net/tun/if_tun.h net/if_tap.h net/tap/if_tap.h net/ethernet.h net/if_arp.h netinet/in_systm.h netinet/in.h netinet/in6.h time.h netpacket/packet.h +for ac_header in net/if.h net/if_types.h net/ethernet.h net/if_arp.h netinet/in_systm.h netinet/in.h netinet/in6.h netpacket/packet.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` -ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "#include \"src/have.h\" +ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "#include \"$srcdir/src/have.h\" " if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : @@ -5647,7 +5624,7 @@ done for ac_header in netinet/if_ether.h netinet/ip.h netinet/ip6.h resolv.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` -ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "#include \"src/have.h\" +ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "#include \"$srcdir/src/have.h\" " if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : @@ -5662,7 +5639,7 @@ done for ac_header in netinet/tcp.h netinet/ip_icmp.h netinet/icmp6.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` -ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "#include \"src/have.h\" +ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "#include \"$srcdir/src/have.h\" " if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : @@ -5675,214 +5652,6 @@ fi done -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5 -$as_echo_n "checking for an ANSI C-conforming const... " >&6; } -if ${ac_cv_c_const+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - -#ifndef __cplusplus - /* Ultrix mips cc rejects this sort of thing. */ - typedef int charset[2]; - const charset cs = { 0, 0 }; - /* SunOS 4.1.1 cc rejects this. */ - char const *const *pcpcc; - char **ppc; - /* NEC SVR4.0.2 mips cc rejects this. */ - struct point {int x, y;}; - static struct point const zero = {0,0}; - /* AIX XL C 1.02.0.0 rejects this. - It does not let you subtract one const X* pointer from another in - an arm of an if-expression whose if-part is not a constant - expression */ - const char *g = "string"; - pcpcc = &g + (g ? g-g : 0); - /* HPUX 7.0 cc rejects these. */ - ++pcpcc; - ppc = (char**) pcpcc; - pcpcc = (char const *const *) ppc; - { /* SCO 3.2v4 cc rejects this sort of thing. */ - char tx; - char *t = &tx; - char const *s = 0 ? (char *) 0 : (char const *) 0; - - *t++ = 0; - if (s) return 0; - } - { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ - int x[] = {25, 17}; - const int *foo = &x[0]; - ++foo; - } - { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ - typedef const int *iptr; - iptr p = 0; - ++p; - } - { /* AIX XL C 1.02.0.0 rejects this sort of thing, saying - "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ - struct s { int j; const int *ap[3]; } bx; - struct s *b = &bx; b->j = 5; - } - { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ - const int foo = 10; - if (!foo) return 0; - } - return !cs[0] && !zero.x; -#endif - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_c_const=yes -else - ac_cv_c_const=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_const" >&5 -$as_echo "$ac_cv_c_const" >&6; } -if test $ac_cv_c_const = no; then - -$as_echo "#define const /**/" >>confdefs.h - -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for working volatile" >&5 -$as_echo_n "checking for working volatile... " >&6; } -if ${ac_cv_c_volatile+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - -volatile int x; -int * volatile y = (int *) 0; -return !x && !y; - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_c_volatile=yes -else - ac_cv_c_volatile=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_volatile" >&5 -$as_echo "$ac_cv_c_volatile" >&6; } -if test $ac_cv_c_volatile = no; then - -$as_echo "#define volatile /**/" >>confdefs.h - -fi - -ac_fn_c_check_type "$LINENO" "pid_t" "ac_cv_type_pid_t" "$ac_includes_default" -if test "x$ac_cv_type_pid_t" = xyes; then : - -else - -cat >>confdefs.h <<_ACEOF -#define pid_t int -_ACEOF - -fi - -ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default" -if test "x$ac_cv_type_size_t" = xyes; then : - -else - -cat >>confdefs.h <<_ACEOF -#define size_t unsigned int -_ACEOF - -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether time.h and sys/time.h may both be included" >&5 -$as_echo_n "checking whether time.h and sys/time.h may both be included... " >&6; } -if ${ac_cv_header_time+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -#include -#include - -int -main () -{ -if ((struct tm *) 0) -return 0; - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_header_time=yes -else - ac_cv_header_time=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_time" >&5 -$as_echo "$ac_cv_header_time" >&6; } -if test $ac_cv_header_time = yes; then - -$as_echo "#define TIME_WITH_SYS_TIME 1" >>confdefs.h - -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether struct tm is in sys/time.h or time.h" >&5 -$as_echo_n "checking whether struct tm is in sys/time.h or time.h... " >&6; } -if ${ac_cv_struct_tm+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -#include - -int -main () -{ -struct tm tm; - int *p = &tm.tm_sec; - return !p; - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_struct_tm=time.h -else - ac_cv_struct_tm=sys/time.h -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_struct_tm" >&5 -$as_echo "$ac_cv_struct_tm" >&6; } -if test $ac_cv_struct_tm = sys/time.h; then - -$as_echo "#define TM_IN_SYS_TIME 1" >>confdefs.h - -fi - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working __malloc__ attribute" >&5 $as_echo_n "checking for working __malloc__ attribute... " >&6; } @@ -5894,8 +5663,8 @@ else CFLAGS="$CFLAGS -Wall -Werror" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -void test(void) __attribute__ ((__malloc__)); - void test(void) { return; } +void *test(void) __attribute__ ((__malloc__)); + void *test(void) { return (void *)0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : @@ -5928,8 +5697,8 @@ else CFLAGS="$CFLAGS -Wall -Werror" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -void test(void) __attribute__ ((__warn_unused_result__)); - void test(void) { return; } +void *test(void) __attribute__ ((__warn_unused_result__)); + void *test(void) { return (void *)0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : @@ -5952,18 +5721,7 @@ $as_echo "#define __warn_unused_result__ /**/" >>confdefs.h fi -ac_fn_c_check_type "$LINENO" "socklen_t" "ac_cv_type_socklen_t" "#include \"src/have.h\" - -" -if test "x$ac_cv_type_socklen_t" = xyes; then : - -cat >>confdefs.h <<_ACEOF -#define HAVE_SOCKLEN_T 1 -_ACEOF - - -fi -ac_fn_c_check_type "$LINENO" "struct ether_header" "ac_cv_type_struct_ether_header" "#include \"src/have.h\" +ac_fn_c_check_type "$LINENO" "struct ether_header" "ac_cv_type_struct_ether_header" "#include \"$srcdir/src/have.h\" " if test "x$ac_cv_type_struct_ether_header" = xyes; then : @@ -5974,7 +5732,7 @@ _ACEOF fi -ac_fn_c_check_type "$LINENO" "struct arphdr" "ac_cv_type_struct_arphdr" "#include \"src/have.h\" +ac_fn_c_check_type "$LINENO" "struct arphdr" "ac_cv_type_struct_arphdr" "#include \"$srcdir/src/have.h\" " if test "x$ac_cv_type_struct_arphdr" = xyes; then : @@ -5985,7 +5743,7 @@ _ACEOF fi -ac_fn_c_check_type "$LINENO" "struct ether_arp" "ac_cv_type_struct_ether_arp" "#include \"src/have.h\" +ac_fn_c_check_type "$LINENO" "struct ether_arp" "ac_cv_type_struct_ether_arp" "#include \"$srcdir/src/have.h\" " if test "x$ac_cv_type_struct_ether_arp" = xyes; then : @@ -5996,29 +5754,7 @@ _ACEOF fi -ac_fn_c_check_type "$LINENO" "struct in_addr" "ac_cv_type_struct_in_addr" "#include \"src/have.h\" - -" -if test "x$ac_cv_type_struct_in_addr" = xyes; then : - -cat >>confdefs.h <<_ACEOF -#define HAVE_STRUCT_IN_ADDR 1 -_ACEOF - - -fi -ac_fn_c_check_type "$LINENO" "struct addrinfo" "ac_cv_type_struct_addrinfo" "#include \"src/have.h\" - -" -if test "x$ac_cv_type_struct_addrinfo" = xyes; then : - -cat >>confdefs.h <<_ACEOF -#define HAVE_STRUCT_ADDRINFO 1 -_ACEOF - - -fi -ac_fn_c_check_type "$LINENO" "struct ip" "ac_cv_type_struct_ip" "#include \"src/have.h\" +ac_fn_c_check_type "$LINENO" "struct ip" "ac_cv_type_struct_ip" "#include \"$srcdir/src/have.h\" " if test "x$ac_cv_type_struct_ip" = xyes; then : @@ -6029,7 +5765,7 @@ _ACEOF fi -ac_fn_c_check_type "$LINENO" "struct icmp" "ac_cv_type_struct_icmp" "#include \"src/have.h\" +ac_fn_c_check_type "$LINENO" "struct icmp" "ac_cv_type_struct_icmp" "#include \"$srcdir/src/have.h\" " if test "x$ac_cv_type_struct_icmp" = xyes; then : @@ -6040,29 +5776,7 @@ _ACEOF fi -ac_fn_c_check_type "$LINENO" "struct in6_addr" "ac_cv_type_struct_in6_addr" "#include \"src/have.h\" - -" -if test "x$ac_cv_type_struct_in6_addr" = xyes; then : - -cat >>confdefs.h <<_ACEOF -#define HAVE_STRUCT_IN6_ADDR 1 -_ACEOF - - -fi -ac_fn_c_check_type "$LINENO" "struct sockaddr_in6" "ac_cv_type_struct_sockaddr_in6" "#include \"src/have.h\" - -" -if test "x$ac_cv_type_struct_sockaddr_in6" = xyes; then : - -cat >>confdefs.h <<_ACEOF -#define HAVE_STRUCT_SOCKADDR_IN6 1 -_ACEOF - - -fi -ac_fn_c_check_type "$LINENO" "struct ip6_hdr" "ac_cv_type_struct_ip6_hdr" "#include \"src/have.h\" +ac_fn_c_check_type "$LINENO" "struct ip6_hdr" "ac_cv_type_struct_ip6_hdr" "#include \"$srcdir/src/have.h\" " if test "x$ac_cv_type_struct_ip6_hdr" = xyes; then : @@ -6073,7 +5787,7 @@ _ACEOF fi -ac_fn_c_check_type "$LINENO" "struct icmp6_hdr" "ac_cv_type_struct_icmp6_hdr" "#include \"src/have.h\" +ac_fn_c_check_type "$LINENO" "struct icmp6_hdr" "ac_cv_type_struct_icmp6_hdr" "#include \"$srcdir/src/have.h\" " if test "x$ac_cv_type_struct_icmp6_hdr" = xyes; then : @@ -6084,7 +5798,7 @@ _ACEOF fi -ac_fn_c_check_type "$LINENO" "struct nd_neighbor_solicit" "ac_cv_type_struct_nd_neighbor_solicit" "#include \"src/have.h\" +ac_fn_c_check_type "$LINENO" "struct nd_neighbor_solicit" "ac_cv_type_struct_nd_neighbor_solicit" "#include \"$srcdir/src/have.h\" " if test "x$ac_cv_type_struct_nd_neighbor_solicit" = xyes; then : @@ -6095,7 +5809,7 @@ _ACEOF fi -ac_fn_c_check_type "$LINENO" "struct nd_opt_hdr" "ac_cv_type_struct_nd_opt_hdr" "#include \"src/have.h\" +ac_fn_c_check_type "$LINENO" "struct nd_opt_hdr" "ac_cv_type_struct_nd_opt_hdr" "#include \"$srcdir/src/have.h\" " if test "x$ac_cv_type_struct_nd_opt_hdr" = xyes; then : @@ -6141,7 +5855,7 @@ cat >>confdefs.h <<_ACEOF _ACEOF -for ac_func in asprintf daemon fchmod flock ftime fork get_current_dir_name gettimeofday mlockall putenv random select strdup strerror strsignal strtol system time usleep unsetenv vsyslog writev +for ac_func in asprintf daemon fchmod flock ftime fork gettimeofday mlockall putenv recvmmsg strsignal nanosleep unsetenv vsyslog devname fdevname do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" @@ -6154,162 +5868,22 @@ fi done - -ac_fn_c_check_func "$LINENO" "socket" "ac_cv_func_socket" -if test "x$ac_cv_func_socket" = xyes; then : +ac_fn_c_check_func "$LINENO" "getopt_long" "ac_cv_func_getopt_long" +if test "x$ac_cv_func_getopt_long" = xyes; then : + getopt=true; +$as_echo "#define HAVE_GETOPT_LONG 1" >>confdefs.h else + getopt=false +fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for connect in -lsocket" >&5 -$as_echo_n "checking for connect in -lsocket... " >&6; } -if ${ac_cv_lib_socket_connect+:} false; then : - $as_echo_n "(cached) " >&6 + if test "$getopt" = true; then + GETOPT_TRUE= + GETOPT_FALSE='#' else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lsocket $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char connect (); -int -main () -{ -return connect (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_socket_connect=yes -else - ac_cv_lib_socket_connect=no + GETOPT_TRUE='#' + GETOPT_FALSE= fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_connect" >&5 -$as_echo "$ac_cv_lib_socket_connect" >&6; } -if test "x$ac_cv_lib_socket_connect" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBSOCKET 1 -_ACEOF - - LIBS="-lsocket $LIBS" - -fi - - -fi - -ac_fn_c_check_func "$LINENO" "gethostbyname" "ac_cv_func_gethostbyname" -if test "x$ac_cv_func_gethostbyname" = xyes; then : - -else - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gethostbyname in -lnsl" >&5 -$as_echo_n "checking for gethostbyname in -lnsl... " >&6; } -if ${ac_cv_lib_nsl_gethostbyname+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lnsl $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char gethostbyname (); -int -main () -{ -return gethostbyname (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_nsl_gethostbyname=yes -else - ac_cv_lib_nsl_gethostbyname=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nsl_gethostbyname" >&5 -$as_echo "$ac_cv_lib_nsl_gethostbyname" >&6; } -if test "x$ac_cv_lib_nsl_gethostbyname" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBNSL 1 -_ACEOF - - LIBS="-lnsl $LIBS" - -fi - - -fi - - -ac_fn_c_check_decl "$LINENO" "freeaddrinfo" "ac_cv_have_decl_freeaddrinfo" "#include \"src/have.h\" - -" -if test "x$ac_cv_have_decl_freeaddrinfo" = xyes; then : - ac_have_decl=1 -else - ac_have_decl=0 -fi - -cat >>confdefs.h <<_ACEOF -#define HAVE_DECL_FREEADDRINFO $ac_have_decl -_ACEOF -ac_fn_c_check_decl "$LINENO" "gai_strerror" "ac_cv_have_decl_gai_strerror" "#include \"src/have.h\" - -" -if test "x$ac_cv_have_decl_gai_strerror" = xyes; then : - ac_have_decl=1 -else - ac_have_decl=0 -fi - -cat >>confdefs.h <<_ACEOF -#define HAVE_DECL_GAI_STRERROR $ac_have_decl -_ACEOF -ac_fn_c_check_decl "$LINENO" "getaddrinfo" "ac_cv_have_decl_getaddrinfo" "#include \"src/have.h\" - -" -if test "x$ac_cv_have_decl_getaddrinfo" = xyes; then : - ac_have_decl=1 -else - ac_have_decl=0 -fi - -cat >>confdefs.h <<_ACEOF -#define HAVE_DECL_GETADDRINFO $ac_have_decl -_ACEOF -ac_fn_c_check_decl "$LINENO" "getnameinfo" "ac_cv_have_decl_getnameinfo" "#include \"src/have.h\" - -" -if test "x$ac_cv_have_decl_getnameinfo" = xyes; then : - ac_have_decl=1 -else - ac_have_decl=0 -fi - -cat >>confdefs.h <<_ACEOF -#define HAVE_DECL_GETNAMEINFO $ac_have_decl -_ACEOF ac_fn_c_check_decl "$LINENO" "res_init" "ac_cv_have_decl_res_init" " @@ -6375,6 +5949,99 @@ fi fi +case $host_os in + *linux*) + for ac_header in linux/if_tun.h +do : + ac_fn_c_check_header_compile "$LINENO" "linux/if_tun.h" "ac_cv_header_linux_if_tun_h" "#include \"$srcdir/src/have.h\" + +" +if test "x$ac_cv_header_linux_if_tun_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LINUX_IF_TUN_H 1 +_ACEOF + +else + as_fn_error $? "Required header file missng" "$LINENO" 5 +fi + +done + + ;; + *bsd*|*dragonfly*|*darwin*) + for ac_header in net/if_tun.h net/if_utun.h net/tun/if_tun.h net/if_tap.h net/tap/if_tap.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "#include \"$srcdir/src/have.h\" + +" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + ;; + *solaris*) + ac_fn_c_check_func "$LINENO" "socket" "ac_cv_func_socket" +if test "x$ac_cv_func_socket" = xyes; then : + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for connect in -lsocket" >&5 +$as_echo_n "checking for connect in -lsocket... " >&6; } +if ${ac_cv_lib_socket_connect+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lsocket $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char connect (); +int +main () +{ +return connect (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_socket_connect=yes +else + ac_cv_lib_socket_connect=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_connect" >&5 +$as_echo "$ac_cv_lib_socket_connect" >&6; } +if test "x$ac_cv_lib_socket_connect" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBSOCKET 1 +_ACEOF + + LIBS="-lsocket $LIBS" + +fi + +fi + + ;; + *) + ;; +esac + cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure @@ -6461,6 +6128,18 @@ $as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} fi rm -f confcache +# Check whether --enable-legacy-protocol was given. +if test "${enable_legacy_protocol+set}" = set; then : + enableval=$enable_legacy_protocol; if test "x$enable_legacy_protocol" = "xno"; then : + +$as_echo "#define DISABLE_LEGACY 1" >>confdefs.h + +fi + + +fi + + @@ -6993,9 +6672,9 @@ done fi -if test -n "$with_libgcrypt"; then - gcrypt=true - +if test "x$enable_legacy_protocol" != "xno"; then : + if test -n "$with_libgcrypt"; then : + gcrypt=true; # Check whether --with-libgcrypt was given. if test "${with_libgcrypt+set}" = set; then : @@ -7085,8 +6764,7 @@ fi else - openssl=true - + openssl=true; case $host_os in *mingw*) ;; @@ -7134,7 +6812,7 @@ $as_echo "$ac_cv_lib_dl_dlopen" >&6; } if test "x$ac_cv_lib_dl_dlopen" = xyes; then : LIBS="$LIBS -ldl" else - as_fn_error $? "OpenSSL depends on libdl." "$LINENO" 5; break + as_fn_error $? "LibreSSL/OpenSSL depends on libdl." "$LINENO" 5; break fi @@ -7182,7 +6860,7 @@ if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : _ACEOF else - as_fn_error $? "OpenSSL header files not found." "$LINENO" 5; break + as_fn_error $? "LibreSSL/OpenSSL header files not found." "$LINENO" 5; break fi @@ -7228,7 +6906,7 @@ $as_echo "$ac_cv_lib_crypto_EVP_EncryptInit_ex" >&6; } if test "x$ac_cv_lib_crypto_EVP_EncryptInit_ex" = xyes; then : LIBS="-lcrypto $LIBS" else - as_fn_error $? "OpenSSL libraries not found." "$LINENO" 5 + as_fn_error $? "LibreSSL/OpenSSL libraries not found." "$LINENO" 5 fi @@ -7243,7 +6921,7 @@ if eval test \"x\$"$as_ac_var"\" = x"yes"; then : _ACEOF else - as_fn_error $? "Missing OpenSSL functionality, make sure you have installed the latest version." "$LINENO" 5; break + as_fn_error $? "Missing LibreSSL/OpenSSL functionality, make sure you have installed the latest version." "$LINENO" 5; break fi done @@ -7263,7 +6941,10 @@ _ACEOF if test $ac_have_decl = 1; then : else - as_fn_error $? "Missing OpenSSL functionality, make sure you have installed the latest version." "$LINENO" 5; break + as_fn_error $? "Missing LibreSSL/OpenSSL functionality, make sure you have installed the latest version." "$LINENO" 5; break +fi + + fi @@ -7286,6 +6967,118 @@ else fi + + # Check whether --enable-miniupnpc was given. +if test "${enable_miniupnpc+set}" = set; then : + enableval=$enable_miniupnpc; +fi + + if test "x$enable_miniupnpc" = "xyes"; then : + + +$as_echo "#define HAVE_MINIUPNPC 1" >>confdefs.h + + +# Check whether --with-miniupnpc was given. +if test "${with_miniupnpc+set}" = set; then : + withval=$with_miniupnpc; miniupnpc="$withval" + CPPFLAGS="$CPPFLAGS -I$withval/include" + LDFLAGS="$LDFLAGS -L$withval/lib" + +fi + + + +# Check whether --with-miniupnpc-include was given. +if test "${with_miniupnpc_include+set}" = set; then : + withval=$with_miniupnpc_include; miniupnpc_include="$withval" + CPPFLAGS="$CPPFLAGS -I$withval" + +fi + + + +# Check whether --with-miniupnpc-lib was given. +if test "${with_miniupnpc_lib+set}" = set; then : + withval=$with_miniupnpc_lib; miniupnpc_lib="$withval" + LDFLAGS="$LDFLAGS -L$withval" + +fi + + + for ac_header in miniupnpc/miniupnpc.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "miniupnpc/miniupnpc.h" "ac_cv_header_miniupnpc_miniupnpc_h" "$ac_includes_default" +if test "x$ac_cv_header_miniupnpc_miniupnpc_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_MINIUPNPC_MINIUPNPC_H 1 +_ACEOF + +else + as_fn_error $? "\"miniupnpc header files not found.\"" "$LINENO" 5; break + +fi + +done + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for upnpDiscover in -lminiupnpc" >&5 +$as_echo_n "checking for upnpDiscover in -lminiupnpc... " >&6; } +if ${ac_cv_lib_miniupnpc_upnpDiscover+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lminiupnpc $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char upnpDiscover (); +int +main () +{ +return upnpDiscover (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_miniupnpc_upnpDiscover=yes +else + ac_cv_lib_miniupnpc_upnpDiscover=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_miniupnpc_upnpDiscover" >&5 +$as_echo "$ac_cv_lib_miniupnpc_upnpDiscover" >&6; } +if test "x$ac_cv_lib_miniupnpc_upnpDiscover" = xyes; then : + MINIUPNPC_LIBS="$LIBS -lminiupnpc" +else + as_fn_error $? "\"miniupnpc libraries not found.\"" "$LINENO" 5 + +fi + + +fi + + + + if test "x$enable_miniupnpc" = "xyes"; then + MINIUPNPC_TRUE= + MINIUPNPC_FALSE='#' +else + MINIUPNPC_TRUE='#' + MINIUPNPC_FALSE= +fi + + # Check whether --enable-jumbograms was given. if test "${enable_jumbograms+set}" = set; then : enableval=$enable_jumbograms; if test "x$enable_jumbograms" = "xyes"; then : @@ -7298,7 +7091,7 @@ fi fi -ac_config_files="$ac_config_files Makefile src/Makefile doc/Makefile m4/Makefile gui/Makefile test/Makefile" +ac_config_files="$ac_config_files Makefile src/Makefile doc/Makefile gui/Makefile test/Makefile systemd/Makefile" cat >confcache <<\_ACEOF @@ -7466,6 +7259,14 @@ if test -z "${TUNEMU_TRUE}" && test -z "${TUNEMU_FALSE}"; then as_fn_error $? "conditional \"TUNEMU\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi +if test -z "${WITH_SYSTEMD_TRUE}" && test -z "${WITH_SYSTEMD_FALSE}"; then + as_fn_error $? "conditional \"WITH_SYSTEMD\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${GETOPT_TRUE}" && test -z "${GETOPT_FALSE}"; then + as_fn_error $? "conditional \"GETOPT\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi if test -z "${OPENSSL_TRUE}" && test -z "${OPENSSL_FALSE}"; then as_fn_error $? "conditional \"OPENSSL\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 @@ -7474,6 +7275,10 @@ if test -z "${GCRYPT_TRUE}" && test -z "${GCRYPT_FALSE}"; then as_fn_error $? "conditional \"GCRYPT\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi +if test -z "${MINIUPNPC_TRUE}" && test -z "${MINIUPNPC_FALSE}"; then + as_fn_error $? "conditional \"MINIUPNPC\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi : "${CONFIG_STATUS=./config.status}" ac_write_fail=0 @@ -7871,7 +7676,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by tinc $as_me 1.1pre11, which was +This file was extended by tinc $as_me tinc-1.1pre12, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -7937,7 +7742,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -tinc config.status 1.1pre11 +tinc config.status tinc-1.1pre12 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" @@ -8071,9 +7876,9 @@ do "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; "src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;; "doc/Makefile") CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;; - "m4/Makefile") CONFIG_FILES="$CONFIG_FILES m4/Makefile" ;; "gui/Makefile") CONFIG_FILES="$CONFIG_FILES gui/Makefile" ;; "test/Makefile") CONFIG_FILES="$CONFIG_FILES test/Makefile" ;; + "systemd/Makefile") CONFIG_FILES="$CONFIG_FILES systemd/Makefile" ;; *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; esac diff --git a/configure.ac b/configure.ac index 6fd2621..4c0f926 100644 --- a/configure.ac +++ b/configure.ac @@ -1,11 +1,13 @@ dnl Process this file with autoconf to produce a configure script. AC_PREREQ(2.61) -AC_INIT([tinc], [1.1pre11]) +AC_INIT([tinc], m4_esyscmd_s((git describe || echo UNKNOWN) | sed 's/release-//')) AC_CONFIG_SRCDIR([src/tincd.c]) AC_GNU_SOURCE -AM_INIT_AUTOMAKE([check-news std-options subdir-objects -Wall]) +AM_INIT_AUTOMAKE([std-options subdir-objects nostdinc silent-rules -Wall]) AC_CONFIG_HEADERS([config.h]) +AC_CONFIG_MACRO_DIR([m4]) +AM_SILENT_RULES([yes]) # Enable GNU extensions. # Define this here, not in acconfig's @TOP@ section, since definitions @@ -66,7 +68,9 @@ case $host_os in *mingw*) mingw=true AC_DEFINE(HAVE_MINGW, 1, [MinGW]) - LIBS="$LIBS -lws2_32 -lgdi32 -lcrypt32" + LIBS="$LIBS -lws2_32 -lgdi32 -lcrypt32 -liphlpapi" + LDFLAGS="$LDFLAGS -static" + CPPFLAGS="$CPPFLAGS -DMINIUPNP_STATICLIB" ;; *) AC_MSG_ERROR("Unknown operating system.") @@ -107,13 +111,17 @@ AC_ARG_ENABLE(tunemu, [tunemu=false] ) -AC_ARG_WITH(windows2000, - AS_HELP_STRING([--with-windows2000], [compile with support for Windows 2000. This disables support for tunneling over existing IPv6 networks.]), - [ AS_IF([test "x$with_windows2000" = "xyes"], - [AC_DEFINE(WITH_WINDOWS2000, 1, [Compile with support for Windows 2000])]) - ] +AC_ARG_WITH(systemd, + AS_HELP_STRING([--with-systemd@<:@=DIR@:>@], [install systemd service files @<:@to DIR if specified@:>@]), + [ systemd=true; systemd_path="$with_systemd" ], + [ systemd=false ] ) +AS_IF([test "x$with_systemd" = "xyes"], [systemd_path="/lib/systemd/system"], + [AS_IF([test "x$with_systemd" = "xno"], [systemd=false])]) + +AC_SUBST(systemd_path, $systemd_path) + AM_CONDITIONAL(LINUX, test "$linux" = true) AM_CONDITIONAL(BSD, test "$bsd" = true) AM_CONDITIONAL(SOLARIS, test "$solaris" = true) @@ -122,15 +130,12 @@ AM_CONDITIONAL(CYGWIN, test "$cygwin" = true) AM_CONDITIONAL(UML, test "$uml" = true) AM_CONDITIONAL(VDE, test "$vde" = true) AM_CONDITIONAL(TUNEMU, test "$tunemu" = true) +AM_CONDITIONAL(WITH_SYSTEMD, test "$systemd" = true) AC_CACHE_SAVE -if test -d /sw/include ; then - CPPFLAGS="$CPPFLAGS -I/sw/include" -fi -if test -d /sw/lib ; then - LIBS="$LIBS -L/sw/lib" -fi +AS_IF([test -d /sw/include], [CPPFLAGS="$CPPFLAGS -I/sw/include"]) +AS_IF([test -d /sw/lib], [LIBS="$LIBS -L/sw/lib"]) dnl Compiler hardening flags dnl No -fstack-protector-all because it doesn't work on all platforms or architectures. @@ -138,8 +143,8 @@ dnl No -fstack-protector-all because it doesn't work on all platforms or archite AC_ARG_ENABLE([hardening], AS_HELP_STRING([--disable-hardening], [disable compiler and linker hardening flags])) AS_IF([test "x$enable_hardening" != "xno"], [AX_CHECK_COMPILE_FLAG([-DFORTIFY_SOURCE=2], [CPPFLAGS="$CPPFLAGS -DFORTIFY_SOURCE=2"]) - AX_CHECK_COMPILE_FLAG([-fno-strict-overflow], [CPPFLAGS="$CPPFLAGS -fno-strict-overflow"]) - AX_CHECK_COMPILE_FLAG([-fwrapv], [CPPFLAGS="$CPPFLAGS -fwrapv"]) + AX_CHECK_COMPILE_FLAG([-fwrapv], [CPPFLAGS="$CPPFLAGS -fwrapv"], + AX_CHECK_COMPILE_FLAG([-fno-strict-overflow], [CPPFLAGS="$CPPFLAGS -fno-strict-overflow"])) case $host_os in *mingw*) AX_CHECK_LINK_FLAG([-Wl,--dynamicbase], [LDFLAGS="$LDFLAGS -Wl,--dynamicbase"]) @@ -158,79 +163,90 @@ AS_IF([test "x$enable_hardening" != "xno"], 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/resource.h sys/socket.h sys/time.h sys/uio.h sys/un.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/tun/if_tun.h net/if_tap.h net/tap/if_tap.h net/ethernet.h net/if_arp.h netinet/in_systm.h netinet/in.h netinet/in6.h time.h netpacket/packet.h], - [], [], [#include "src/have.h"] +AC_CHECK_HEADERS([syslog.h sys/file.h sys/ioctl.h sys/mman.h sys/param.h sys/resource.h sys/socket.h sys/time.h sys/un.h sys/wait.h netdb.h arpa/inet.h dirent.h getopt.h]) +AC_CHECK_HEADERS([net/if.h net/if_types.h net/ethernet.h net/if_arp.h netinet/in_systm.h netinet/in.h netinet/in6.h netpacket/packet.h], + [], [], [#include "$srcdir/src/have.h"] ) AC_CHECK_HEADERS([netinet/if_ether.h netinet/ip.h netinet/ip6.h resolv.h], - [], [], [#include "src/have.h"] + [], [], [#include "$srcdir/src/have.h"] ) AC_CHECK_HEADERS([netinet/tcp.h netinet/ip_icmp.h netinet/icmp6.h], - [], [], [#include "src/have.h"] + [], [], [#include "$srcdir/src/have.h"] ) dnl Checks for typedefs, structures, and compiler characteristics. -AC_C_CONST -AC_C_VOLATILE -AC_TYPE_PID_T -AC_TYPE_SIZE_T -AC_HEADER_TIME -AC_STRUCT_TM - tinc_ATTRIBUTE(__malloc__) tinc_ATTRIBUTE(__warn_unused_result__) -AC_CHECK_TYPES([socklen_t, struct ether_header, struct arphdr, struct ether_arp, struct in_addr, struct addrinfo, struct ip, struct icmp, struct in6_addr, struct sockaddr_in6, struct ip6_hdr, struct icmp6_hdr, struct nd_neighbor_solicit, struct nd_opt_hdr], , , - [#include "src/have.h"] +AC_CHECK_TYPES([struct ether_header, struct arphdr, struct ether_arp, struct ip, struct icmp, struct ip6_hdr, struct icmp6_hdr, struct nd_neighbor_solicit, struct nd_opt_hdr], , , + [#include "$srcdir/src/have.h"] ) dnl Checks for library functions. AC_TYPE_SIGNAL -AC_CHECK_FUNCS([asprintf daemon fchmod flock ftime fork get_current_dir_name gettimeofday mlockall putenv random select strdup strerror strsignal strtol system time usleep unsetenv vsyslog writev], - [], [], [#include "src/have.h"] +AC_CHECK_FUNCS([asprintf daemon fchmod flock ftime fork gettimeofday mlockall putenv recvmmsg strsignal nanosleep unsetenv vsyslog devname fdevname], + [], [], [#include "$srcdir/src/have.h"] ) -dnl Support for SunOS - -AC_CHECK_FUNC(socket, [], [ - AC_CHECK_LIB(socket, connect) -]) -AC_CHECK_FUNC(gethostbyname, [], [ - AC_CHECK_LIB(nsl, gethostbyname) -]) - -AC_CHECK_DECLS([freeaddrinfo, gai_strerror, getaddrinfo, getnameinfo], - [], [], [#include "src/have.h"] -) +AC_CHECK_FUNC(getopt_long, [getopt=true; AC_DEFINE(HAVE_GETOPT_LONG, 1, [getopt_long()])], [getopt=false]) +AM_CONDITIONAL(GETOPT, test "$getopt" = true) AC_CHECK_DECLS([res_init], [AC_CHECK_LIB(resolv, res_init)], [], [ #include #include ]) +dnl Operating system specific checks +case $host_os in + *linux*) + AC_CHECK_HEADERS([linux/if_tun.h], + [], [AC_MSG_ERROR([Required header file missng])], [#include "$srcdir/src/have.h"] + ) + ;; + *bsd*|*dragonfly*|*darwin*) + AC_CHECK_HEADERS([net/if_tun.h net/if_utun.h net/tun/if_tun.h net/if_tap.h net/tap/if_tap.h], + [], [], [#include "$srcdir/src/have.h"] + ) + ;; + *solaris*) + AC_CHECK_FUNC(socket, [], [AC_CHECK_LIB(socket, connect)]) + ;; + *) + ;; +esac + AC_CACHE_SAVE +AC_ARG_ENABLE(legacy-protocol, + AS_HELP_STRING([--disable-legacy-protocol], [disable support for the legacy (tinc 1.0) protocol]), + [ AS_IF([test "x$enable_legacy_protocol" = "xno"], + [ AC_DEFINE(DISABLE_LEGACY, 1, [Disable support for the legacy (tinc 1.0) protocol]) ]) + ] +) + dnl These are defined in files in m4/ dnl AC_ARG_WITH(libgcrypt, AC_HELP_STRING([--with-libgcrypt], [enable use of libgcrypt instead of OpenSSL])], []) +dnl AC_ARG_WITH(openssl, AC_HELP_STRING([--without-openssl], [disable support for OpenSSL])], []) tinc_CURSES tinc_READLINE tinc_ZLIB tinc_LZO -if test -n "$with_libgcrypt"; then - gcrypt=true - tinc_LIBGCRYPT -else - openssl=true - tinc_OPENSSL -fi - +AS_IF([test "x$enable_legacy_protocol" != "xno"], + [AS_IF([test -n "$with_libgcrypt"], + [gcrypt=true; tinc_LIBGCRYPT], + [openssl=true; tinc_OPENSSL]) + ] +) + AM_CONDITIONAL(OPENSSL, test -n "$openssl") AM_CONDITIONAL(GCRYPT, test -n "$gcrypt") +tinc_MINIUPNPC +AM_CONDITIONAL(MINIUPNPC, test "x$enable_miniupnpc" = "xyes") + dnl Check if support for jumbograms is requested AC_ARG_ENABLE(jumbograms, AS_HELP_STRING([--enable-jumbograms], [enable support for jumbograms (packets up to 9000 bytes)]), @@ -239,6 +255,6 @@ AC_ARG_ENABLE(jumbograms, ] ) -AC_CONFIG_FILES([Makefile src/Makefile doc/Makefile m4/Makefile gui/Makefile test/Makefile]) +AC_CONFIG_FILES([Makefile src/Makefile doc/Makefile gui/Makefile test/Makefile systemd/Makefile]) AC_OUTPUT diff --git a/depcomp b/depcomp index 4ebd5b3..fc98710 100755 --- a/depcomp +++ b/depcomp @@ -3,7 +3,7 @@ scriptversion=2013-05-30.07; # UTC -# Copyright (C) 1999-2013 Free Software Foundation, Inc. +# Copyright (C) 1999-2014 Free Software Foundation, Inc. # 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 diff --git a/doc/Makefile.am b/doc/Makefile.am index a666d3b..aa15b24 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -6,7 +6,7 @@ man_MANS = tincd.8 tinc.8 tinc.conf.5 tinc-gui.8 EXTRA_DIST = tincinclude.texi.in tincd.8.in tinc.8.in tinc.conf.5.in tinc-gui.8.in sample-config.tar.gz -CLEANFILES = *.html tincd.8 tinc.8 tinc.conf.5 tinc-gui.8 tincinclude.texi +CLEANFILES = *.html tincd.8 tinc.8 tinc.conf.5 tinc-gui.8 tincinclude.texi sample-config.tar.gz # Use `ginstall' in the definition of man_MANS to avoid # confusion with the `install' target. The install rule transforms `ginstall' @@ -17,19 +17,19 @@ transform = s/ginstall/install/; @program_transform_name@ # see GNUmakefile and Makefile.maint. sample-config.tar.gz: sample-config - GZIP=$(GZIP_ENV) $(AMTAR) chozf sample-config.tar.gz --exclude .svn sample-config + $(AM_V_GEN)GZIP=$(GZIP_ENV) $(AMTAR) chozf $@ --exclude .svn $< tincd.8.html: tincd.8 - w3mman2html $? > $@ + $(AM_V_GEN)w3mman2html $? > $@ tinc.8.html: tinc.8 - w3mman2html $? > $@ + $(AM_V_GEN)w3mman2html $? > $@ tinc-gui.8.html: tinc-gui.8 - w3mman2html $? > $@ + $(AM_V_GEN)w3mman2html $? > $@ tinc.conf.5.html: tinc.conf.5 - w3mman2html $? > $@ + $(AM_V_GEN)w3mman2html $? > $@ substitute = sed \ -e s,'@PACKAGE\@',"$(PACKAGE)",g \ @@ -38,18 +38,18 @@ substitute = sed \ -e s,'@localstatedir\@',"$(localstatedir)",g tincd.8: tincd.8.in - $(substitute) $? > $@ + $(AM_V_GEN)$(substitute) $? > $@ tinc.8: tinc.8.in - $(substitute) $? > $@ + $(AM_V_GEN)$(substitute) $? > $@ tinc-gui.8: tinc-gui.8.in - $(substitute) $? > $@ + $(AM_V_GEN)$(substitute) $? > $@ tinc.conf.5: tinc.conf.5.in - $(substitute) $? > $@ + $(AM_V_GEN)$(substitute) $? > $@ tincinclude.texi: tincinclude.texi.in - $(substitute) $? > $@ + $(AM_V_GEN)$(substitute) $? > $@ tinc.texi: tincinclude.texi diff --git a/doc/Makefile.in b/doc/Makefile.in index db0d219..6f5c228 100644 --- a/doc/Makefile.in +++ b/doc/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.14.1 from Makefile.am. +# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2013 Free Software Foundation, Inc. +# Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -14,7 +14,17 @@ @SET_MAKE@ VPATH = @srcdir@ -am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ @@ -77,17 +87,17 @@ POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = doc -DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am texinfo.tex ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \ $(top_srcdir)/m4/ax_check_compile_flag.m4 \ $(top_srcdir)/m4/ax_check_link_flag.m4 \ $(top_srcdir)/m4/curses.m4 $(top_srcdir)/m4/libgcrypt.m4 \ - $(top_srcdir)/m4/lzo.m4 $(top_srcdir)/m4/openssl.m4 \ - $(top_srcdir)/m4/readline.m4 $(top_srcdir)/m4/zlib.m4 \ - $(top_srcdir)/configure.ac + $(top_srcdir)/m4/lzo.m4 $(top_srcdir)/m4/miniupnpc.m4 \ + $(top_srcdir)/m4/openssl.m4 $(top_srcdir)/m4/readline.m4 \ + $(top_srcdir)/m4/zlib.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = @@ -185,6 +195,7 @@ man8dir = $(mandir)/man8 NROFF = nroff MANS = $(man_MANS) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +am__DIST_COMMON = $(srcdir)/Makefile.in texinfo.tex DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) # Use `ginstall' in the definition of man_MANS to avoid @@ -224,6 +235,7 @@ LIBS = @LIBS@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ +MINIUPNPC_LIBS = @MINIUPNPC_LIBS@ MKDIR_P = @MKDIR_P@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ @@ -281,10 +293,12 @@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ +runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ +systemd_path = @systemd_path@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ @@ -292,7 +306,7 @@ top_srcdir = @top_srcdir@ info_TEXINFOS = tinc.texi man_MANS = tincd.8 tinc.8 tinc.conf.5 tinc-gui.8 EXTRA_DIST = tincinclude.texi.in tincd.8.in tinc.8.in tinc.conf.5.in tinc-gui.8.in sample-config.tar.gz -CLEANFILES = *.html tincd.8 tinc.8 tinc.conf.5 tinc-gui.8 tincinclude.texi +CLEANFILES = *.html tincd.8 tinc.8 tinc.conf.5 tinc-gui.8 tincinclude.texi sample-config.tar.gz substitute = sed \ -e s,'@PACKAGE\@',"$(PACKAGE)",g \ -e s,'@VERSION\@',"$(VERSION)",g \ @@ -315,7 +329,6 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu doc/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu doc/Makefile -.PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ @@ -816,39 +829,41 @@ uninstall-man: uninstall-man5 uninstall-man8 uninstall-html-am uninstall-info-am uninstall-man \ uninstall-man5 uninstall-man8 uninstall-pdf-am uninstall-ps-am +.PRECIOUS: Makefile + # For additional rules usually of interest only to the maintainer, # see GNUmakefile and Makefile.maint. sample-config.tar.gz: sample-config - GZIP=$(GZIP_ENV) $(AMTAR) chozf sample-config.tar.gz --exclude .svn sample-config + $(AM_V_GEN)GZIP=$(GZIP_ENV) $(AMTAR) chozf $@ --exclude .svn $< tincd.8.html: tincd.8 - w3mman2html $? > $@ + $(AM_V_GEN)w3mman2html $? > $@ tinc.8.html: tinc.8 - w3mman2html $? > $@ + $(AM_V_GEN)w3mman2html $? > $@ tinc-gui.8.html: tinc-gui.8 - w3mman2html $? > $@ + $(AM_V_GEN)w3mman2html $? > $@ tinc.conf.5.html: tinc.conf.5 - w3mman2html $? > $@ + $(AM_V_GEN)w3mman2html $? > $@ tincd.8: tincd.8.in - $(substitute) $? > $@ + $(AM_V_GEN)$(substitute) $? > $@ tinc.8: tinc.8.in - $(substitute) $? > $@ + $(AM_V_GEN)$(substitute) $? > $@ tinc-gui.8: tinc-gui.8.in - $(substitute) $? > $@ + $(AM_V_GEN)$(substitute) $? > $@ tinc.conf.5: tinc.conf.5.in - $(substitute) $? > $@ + $(AM_V_GEN)$(substitute) $? > $@ tincinclude.texi: tincinclude.texi.in - $(substitute) $? > $@ + $(AM_V_GEN)$(substitute) $? > $@ tinc.texi: tincinclude.texi diff --git a/doc/sample-config.tar.gz b/doc/sample-config.tar.gz index 1a766a691ff1086b57b07104f889fe7a8cf071dc..474a24faa29edfa0dea435f349ce388aee203756 100644 GIT binary patch literal 1237 zcmV;`1S3`2TG z!^AzqsNZ+bMh>DVN|OE{j^g+rjKXBlKY(O6;p|41i7cNlM9ic8w?by!T+QWHeb9Og z{$>B8sQ+aDgFgnfW>zTaN3boJmMI)Q0DfE!chaS{xMa-9U-17xYxa7D>KGUz1WDZ>k z{F`6Q?#I{U#8{?mjwkxW5kd6k?SJQqFx(YU z#4nX7*4+QVGYXf|$TZWl@O=aK;QF&2VXiMQs1*SsV|oX;g0cKef=5 z%r$A8fV&tkt%S5(6W|>xG0dh1ag0a#pZmok{`U4ki*;AF+`v||Kv;;)3m_#jeCW*t(y_Y+M2~q2| z%x8tJ+|+YX6f_}CztU0lP^X8wp_`afC}fH6@39h`jV_K*-z(M9D~%NLp73Yo&x*@N ziM~2TTtrfKx}SuszX5*ht=63jAJ@qv{r309Ey!d3*M|L#U28zi@b-Lc>i=-?3I895 z{ix;teF(NW%?-uVpTFl(&$jNe^0mcWE3LHBN-M3j(n>3>ykPkbfSE!n04M+ee^Frf literal 1237 zcmV;`1SH14RmPf~SAk#W|7Z|5{C^PHwErwG zr)-CFY~%kvez(T|{eIN&{~_cUM(zXvZ9Vv7P-$j`lCBiATwUOxIm_Yt7Fd>PZVad~ z76vRA)G;{Q0ESFL!l5!egJb~;3x|FjH$m&XwmkzZ@Iidq4NiMOe?U{*Ds5#|Bxo^K z8qi1;LQW_k$y18P1aQg6tjaCmwEbQ$Xps>*!*_BqsuIa9C||K=LfZ;MF1463%K?Yx zN;nqM^KD+xJ!?lHpnBm=Up(-~#)|_Xm z0ITp42uv;zCJ0Cxo-=7-F6 z1S4Cya}sV4gg7zTYcZL6muQaIE{K}SoLQWpFei{y2?&q7$cMYF;76qaYqLf}(Of2|3dfBD*P* zo?yH(@>nKjA|oF1)MC&c$u{F-A(0q_=c=D@^s9|m^2Z(~T1E^p(jonaL0I#|bNmPN zzSA?d1^-bzc>eoOga5k#FpCy;I z5`A=vxQL|ebUz7MeFOZ|S*<&lKCZJT`pxf+JCLXRuMPVfyVii3;oZ%#t^dQpHU2*h zyK%$+hY)OY>KlruKY!1oo^8`*)A%dBO4>QjHtW04M+eTPsuL diff --git a/doc/tinc.8.in b/doc/tinc.8.in index bb56386..6644add 100644 --- a/doc/tinc.8.in +++ b/doc/tinc.8.in @@ -11,6 +11,7 @@ .Op Fl -config Ns = Ns Ar DIR .Op Fl -net Ns = Ns Ar NETNAME .Op Fl -pidfile Ns = Ns Ar FILENAME +.Op Fl -force .Op Fl -help .Op Fl -version .Op Ar COMMAND @@ -54,6 +55,8 @@ Use the cookie from to authenticate with a running tinc daemon. If unspecified, the default is .Pa @localstatedir@/run/tinc. Ns Ar NETNAME Ns Pa .pid. +.It Fl -force +Force some commands to work despite warnings. .It Fl -help Display short list of options. .It Fl -version @@ -88,6 +91,7 @@ To set a variable for a specific host, use the notation .Ar host Ns Li . Ns Ar variable . .It add Ar variable Ar value As above, but without removing any previously existing configuration variables. +If the variable already exists with the given value, nothing happens. .It del Ar variable Op Ar value Remove configuration variables with the same name and .Ar value . @@ -101,16 +105,16 @@ You do not need to specify the full path to the file. Export the host configuration file of the local node to standard output. .It export-all Export all host configuration files to standard output. -.It import Op Fl -force +.It import Import host configuration data generated by the .Nm export command from standard input. Already existing host configuration files are not overwritten unless the option .Fl -force is used. -.It exchange Op Fl -force +.It exchange The same as export followed by import. -.It exchange-all Op Fl -force +.It exchange-all The same as export-all followed by import. .It invite Ar name Prepares an invitation for a new node with the given @@ -168,6 +172,9 @@ format. Nodes are colored according to their reachability: red nodes are unreachable, orange nodes are indirectly reachable, green nodes are directly reachable. Black nodes are either directly or indirectly reachable, but direct reachability has not been tried yet. +.It dump invitations +Dump a list of outstanding invitations. +The filename of the invitation, as well as the name of the node that is being invited is shown for each invitation. .It info Ar node | subnet | address Show information about a particular node, subnet or address. If an address is given, any matching subnet will be shown. @@ -215,6 +222,38 @@ If .Ar netname is given, switch to that network. Otherwise, display a list of all networks for which configuration files exist. +.It fsck +This will check the configuration files for possible problems, +such as unsafe file permissions, missing executable bit on script, +unknown and obsolete configuration variables, wrong public and/or private keys, and so on. +.Pp +When problems are found, this will be printed on a line with WARNING or ERROR in front of it. +Most problems must be corrected by the user itself, however in some cases (like file permissions and missing public keys), +tinc will ask if it should fix the problem. +.It sign Op Ar filename +Sign a file with the local node's private key. +If no +.Ar filename +is given, the file is read from standard input. +The signed file is written to standard output. +.It verify Ar name Op Ar filename +Check the signature of a file against a node's public key. +The +.Ar name +of the node must be given, +or can be +.Li . +to check against the local node's public key, or +.Li * +to allow a signature from any node whose public key is known. +If no +.Ar filename +is given, the file is read from standard input. +If the verification is succesful, +a copy of the input with the signature removed is written to standard output, +and the exit code will be zero. +If the verification failed, +nothing will be written to standard output, and the exit code will be non-zero. .El .Sh EXAMPLES Examples of some commands: diff --git a/doc/tinc.conf.5.in b/doc/tinc.conf.5.in index 9d9bf76..783c299 100644 --- a/doc/tinc.conf.5.in +++ b/doc/tinc.conf.5.in @@ -1,4 +1,4 @@ -.Dd 2014-01-29 +.Dd 2016-04-11 .Dt TINC.CONF 5 .\" Manual page created by: .\" Ivo Timmermans @@ -42,7 +42,7 @@ the configuration file should be and the host configuration files are now expected to be in .Pa @sysconfdir@/tinc/hosts/ . .Sh NAMES -Each tinc daemon should have a name that is unique in the network which it will be part of. +Each tinc daemon must have a name that is unique in the network which it will be part of. The name will be used by other tinc daemons for identification. The name has to be declared in the .Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /tinc.conf @@ -266,6 +266,10 @@ Tinc will expect packets read from the virtual network device to start with a four byte header containing the address family, followed by an IP header. This mode should support both IPv4 and IPv6 packets. +.It utun Pq OS X +Set type to utun. +This is only supported on OS X version 10.6.8 and higher, but doesn't require the tuntaposx module. +This mode should support both IPv4 and IPv6 packets. .It tap Pq BSD and Linux Set type to tap. Tinc will expect packets read from the virtual network device @@ -358,7 +362,7 @@ This will allow direct communication using LAN addresses, even if both peers are and they only ConnectTo a third node outside the NAT, which normally would prevent the peers from learning each other's LAN address. .Pp -Currently, local discovery is implemented by sending some packets to the local address of the node during path MTU discovery. This will not work with old nodes that don't transmit their local address. +Currently, local discovery is implemented by sending some packets to the local address of the node during UDP discovery. This will not work with old nodes that don't transmit their local address. .It Va MACExpire Li = Ar seconds Pq 600 This option controls the amount of time MAC addresses are kept before they are removed. This only has effect when @@ -464,10 +468,10 @@ and .Ev REMOTEPORT are available. .El -.It Va ReplayWindow Li = Ar bytes Pq 16 +.It Va ReplayWindow Li = Ar bytes Pq 32 This is the size of the replay tracking window for each remote node, in bytes. The window is a bitfield which tracks 1 packet per bit, so for example -the default setting of 16 will track up to 128 packets in the window. In high +the default setting of 32 will track up to 256 packets in the window. In high bandwidth scenarios, setting this to a higher value can reduce packet loss from the interaction of replay tracking with underlying real packet loss and/or reordering. Setting this to zero will disable replay tracking completely and @@ -485,12 +489,42 @@ and will only allow connections with nodes for which host config files are prese .Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /hosts/ directory. Setting this options also implicitly sets StrictSubnets. -.It Va UDPRcvBuf Li = Ar bytes Pq OS default +.It Va UDPDiscovery Li = yes | no Po yes Pc +When this option is enabled tinc will try to establish UDP connectivity to nodes, +using TCP while it determines if a node is reachable over UDP. If it is disabled, +tinc always assumes a node is reachable over UDP. +Note that tinc will never use UDP with nodes that have +.Va TCPOnly +enabled. +.It Va UDPDiscoveryKeepaliveInterval Li = Ar seconds Pq 9 +The minimum amount of time between sending UDP ping datagrams to check UDP connectivity once it has been established. +Note that these pings are large, since they are used to verify link MTU as well. +.It Va UDPDiscoveryInterval Li = Ar seconds Pq 2 +The minimum amount of time between sending UDP ping datagrams to try to establish UDP connectivity. +.It Va UDPDiscoveryTimeout Li = Ar seconds Pq 30 +If tinc doesn't receive any UDP ping replies over the specified interval, +it will assume UDP communication is broken and will fall back to TCP. +.It Va UDPInfoInterval Li = Ar seconds Pq 5 +The minimum amount of time between sending periodic updates about UDP addresses, which are mostly useful for UDP hole punching. +.It Va UDPRcvBuf Li = Ar bytes Pq 1048576 Sets the socket receive buffer size for the UDP socket, in bytes. -If unset, the default buffer size will be used by the operating system. -.It Va UDPSndBuf Li = Ar bytes Pq OS default +If set to zero, the default buffer size will be used by the operating system. +Note: this setting can have a significant impact on performance, especially raw throughput. +.It Va UDPSndBuf Li = Ar bytes Pq 1048576 Sets the socket send buffer size for the UDP socket, in bytes. -If unset, the default buffer size will be used by the operating system. +If set to zero, the default buffer size will be used by the operating system. +Note: this setting can have a significant impact on performance, especially raw throughput. +.It Va UPnP Li = yes | udponly | no Po no Pc +If this option is enabled then tinc will search for UPnP-IGD devices on the local network. +It will then create and maintain port mappings for tinc's listening TCP and UDP ports. +If set to "udponly", tinc will only create a mapping for its UDP (data) port, not for its TCP (metaconnection) port. +Note that tinc must have been built with miniupnpc support for this feature to be available. +Furthermore, be advised that enabling this can have security implications, because the miniupnpc library that +tinc uses might not be well-hardened with regard to malicious UPnP replies. +.It Va UPnPDiscoverWait Li = Ar seconds Pq 5 +The amount of time to wait for replies when probing the local network for UPnP devices. +.It Va UPnPRefreshPeriod Li = Ar seconds Pq 60 +How often tinc will re-add the port mapping, in case it gets reset on the UPnP device. This also controls the duration of the port mapping itself, which will be set to twice that duration. .El .Sh HOST CONFIGURATION FILES The host configuration files contain all information needed @@ -515,7 +549,7 @@ variables can be specified, in which case each address will be tried until a wor connection has been established. .It Va Cipher Li = Ar cipher Pq blowfish The symmetric cipher algorithm used to encrypt UDP packets. -Any cipher supported by OpenSSL is recognised. +Any cipher supported by LibreSSL or OpenSSL is recognised. Furthermore, specifying .Qq none will turn off packet encryption. @@ -532,7 +566,7 @@ Possible values are 0 (off), 1 (fast zlib) and any integer up to 9 (best zlib), 10 (fast lzo) and 11 (best lzo). .It Va Digest Li = Ar digest Pq sha1 The digest algorithm used to authenticate UDP packets. -Any digest supported by OpenSSL is recognised. +Any digest supported by LibreSSL or OpenSSL is recognised. Furthermore, specifying .Qq none will turn off packet authentication. @@ -554,6 +588,8 @@ This option controls the initial path MTU to this node. .It Va PMTUDiscovery Li = yes | no Po yes Pc 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 MTUInfoInterval Li = Ar seconds Pq 5 +The minimum amount of time between sending periodic updates about relay path MTU. Useful for quickly determining MTU to indirect nodes. .It Va Port Li = Ar port Pq 655 The port number on which this tinc daemon is listening for incoming connections, which is used if no port number is specified in an @@ -625,10 +661,18 @@ forwarding packets. .Sh SCRIPTS Apart from reading the server and host configuration files, tinc can also run scripts at certain moments. -Under Windows (not Cygwin), the scripts should have the extension +Below is a list of filenames of scripts and a description of when they are run. +A script is only run if it exists and if it is executable. +.Pp +Scripts are run synchronously; +this means that tinc will temporarily stop processing packets until the called script finishes executing. +This guarantees that scripts will execute in the exact same order as the events that trigger them. +If you need to run commands asynchronously, you have to ensure yourself that they are being run in the background. +.Pp +Under Windows (not Cygwin), the scripts must have the extension .Pa .bat or -.Pa cmd . +.Pa .cmd . .Bl -tag -width indent .It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /tinc-up This is the most important script. @@ -637,6 +681,7 @@ If it is present it will be executed right after the tinc daemon has been starte is used). It should be used to set up the corresponding network interface, but can also be used to start other things. +.Pp Under Windows you can use the Network Connections control panel instead of creating this script. .It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /tinc-down This script is started right before the tinc daemon quits (or when the last node becomes unreachable if @@ -734,7 +779,7 @@ its connection to the virtual network device. .Sh SEE ALSO .Xr tincd 8 , .Xr tinc 8 , -.Pa http://www.tinc-vpn.org/ , +.Pa https://www.tinc-vpn.org/ , .Pa http://www.tldp.org/LDP/nag2/ . .Pp The full documentation for diff --git a/doc/tinc.info b/doc/tinc.info index d294c78..9540627 100644 --- a/doc/tinc.info +++ b/doc/tinc.info @@ -1,14 +1,14 @@ -This is tinc.info, produced by makeinfo version 5.2 from tinc.texi. +This is tinc.info, produced by makeinfo version 6.1 from tinc.texi. INFO-DIR-SECTION Networking tools START-INFO-DIR-ENTRY * tinc: (tinc). The tinc Manual. END-INFO-DIR-ENTRY -This is the info manual for tinc version 1.1pre10, a Virtual Private -Network daemon. +This is the info manual for tinc version 1.1pre11-263-g51a0dc5, a +Virtual Private Network daemon. - Copyright (C) 1998-2014 Ivo Timmermans, Guus Sliepen + Copyright (C) 1998-2016 Ivo Timmermans, Guus Sliepen and Wessel Dankers . Permission is granted to make and distribute verbatim copies of this @@ -34,6 +34,7 @@ Top * Configuration:: * Running tinc:: * Controlling tinc:: +* Invitations:: * Technical information:: * Platform specific information:: * About us:: @@ -148,7 +149,7 @@ will most likely compile and run, but it will not be able to send or receive data packets. For an up to date list of supported platforms, please check the list on -our website: . +our website: .  File: tinc.info, Node: Preparations, Next: Installation, Prev: Introduction, Up: Top @@ -220,12 +221,8 @@ File: tinc.info, Node: Configuration of OpenBSD kernels, Next: Configuration o 2.1.3 Configuration of OpenBSD kernels -------------------------------------- -For OpenBSD version 2.9 and higher, the tun driver is included in the -default kernel configuration. There is also a kernel patch from - which adds a tap device to -OpenBSD which should work with tinc, but with recent versions of -OpenBSD, a tun device can act as a tap device by setting the link0 -option with ifconfig. +Recent versions of OpenBSD come with both tun and tap devices enabled in +the default kernel configuration.  File: tinc.info, Node: Configuration of NetBSD kernels, Next: Configuration of Solaris kernels, Prev: Configuration of OpenBSD kernels, Up: Configuring the kernel @@ -248,7 +245,7 @@ For Solaris 8 (SunOS 5.8) and higher, the tun driver may or may not be included in the default kernel configuration. If it isn't, the source can be downloaded from . For x86 and sparc64 architectures, precompiled versions can be found at -. If the 'net/if_tun.h' +. If the 'net/if_tun.h' header file is missing, install it from the source package.  @@ -258,14 +255,15 @@ File: tinc.info, Node: Configuration of Darwin (MacOS/X) kernels, Next: Config ----------------------------------------------- Tinc on Darwin relies on a tunnel driver for its data acquisition from -the kernel. Tinc supports either the driver from +the kernel. OS X version 10.6.8 and later have a built-in tun driver +called "utun". Tinc also supports the driver from , which supports both tun and tap -style devices, and also the driver from from -. The former driver is -recommended. The tunnel driver must be loaded before starting tinc with -the following command: +style devices, - kmodload tunnel +By default, tinc expects the tuntaposx driver to be installed. To use +the utun driver, set add 'Device = utunX' to 'tinc.conf', where X is the +desired number for the utun interface. You can also omit the number, in +which case the first free number will be chosen.  File: tinc.info, Node: Configuration of Windows, Prev: Configuration of Darwin (MacOS/X) kernels, Up: Configuring the kernel @@ -274,7 +272,8 @@ File: tinc.info, Node: Configuration of Windows, Prev: Configuration of Darwin ------------------------------ You will need to install the latest TAP-Win32 driver from OpenVPN. You -can download it from . Using the +can download it from +. Using the Network Connections control panel, configure the TAP-Win32 network interface in the same way as you would do from the tinc-up script, as explained in the rest of the documentation. @@ -285,27 +284,27 @@ File: tinc.info, Node: Libraries, Prev: Configuring the kernel, Up: Preparati 2.2 Libraries ============= -Before you can configure or build tinc, you need to have the OpenSSL, -zlib, lzo, curses and readline libraries installed on your system. If -you try to configure tinc without having them installed, configure will -give you an error message, and stop. +Before you can configure or build tinc, you need to have the LibreSSL or +OpenSSL, zlib, lzo, curses and readline libraries installed on your +system. If you try to configure tinc without having them installed, +configure will give you an error message, and stop. * Menu: -* OpenSSL:: +* LibreSSL/OpenSSL:: * zlib:: * lzo:: * libcurses:: * libreadline::  -File: tinc.info, Node: OpenSSL, Next: zlib, Up: Libraries +File: tinc.info, Node: LibreSSL/OpenSSL, Next: zlib, Up: Libraries -2.2.1 OpenSSL -------------- +2.2.1 LibreSSL/OpenSSL +---------------------- For all cryptography-related functions, tinc uses the functions provided -by the OpenSSL library. +by the LibreSSL or the OpenSSL library. If this library is not installed, you wil get an error when configuring tinc for build. Support for running tinc with other cryptographic @@ -315,19 +314,22 @@ You can use your operating system's package manager to install this if available. Make sure you install the development AND runtime versions of this package. -If you have to install OpenSSL manually, you can get the source code -from . Instructions on how to configure, build -and install this package are included within the package. Please make -sure you build development and runtime libraries (which is the default). +If your operating system comes neither with LibreSSL or OpenSSL, you +have to install one manually. It is recommended that you get the latest +version of LibreSSL from . Instructions on +how to configure, build and install this package are included within the +package. Please make sure you build development and runtime libraries +(which is the default). -If you installed the OpenSSL libraries from source, it may be necessary -to let configure know where they are, by passing configure one of the --with-openssl-* parameters. +If you installed the LibreSSL or OpenSSL libraries from source, it may +be necessary to let configure know where they are, by passing configure +one of the -with-openssl-* parameters. Note that you even have to use +-with-openssl-* if you are using LibreSSL. - --with-openssl=DIR OpenSSL library and headers prefix - --with-openssl-include=DIR OpenSSL headers directory + --with-openssl=DIR LibreSSL/OpenSSL library and headers prefix + --with-openssl-include=DIR LibreSSL/OpenSSL headers directory (Default is OPENSSL_DIR/include) - --with-openssl-lib=DIR OpenSSL library directory + --with-openssl-lib=DIR LibreSSL/OpenSSL library directory (Default is OPENSSL_DIR/lib) License @@ -336,7 +338,7 @@ License The complete source code of tinc is covered by the GNU GPL version 2. Since the license under which OpenSSL is distributed is not directly compatible with the terms of the GNU GPL -, we include an +, we include an exemption to the GPL (see also the file COPYING.README) to allow everyone to create a statically or dynamically linked executable: @@ -349,13 +351,13 @@ Since the LZO library used by tinc is also covered by the GPL, we also present the following exemption: Hereby I grant a special exception to the tinc VPN project - (http://www.tinc-vpn.org/) to link the LZO library with the OpenSSL - library (http://www.openssl.org). + (https://www.tinc-vpn.org/) to link the LZO library with the + OpenSSL library (https://www.openssl.org). Markus F.X.J. Oberhumer  -File: tinc.info, Node: zlib, Next: lzo, Prev: OpenSSL, Up: Libraries +File: tinc.info, Node: zlib, Next: lzo, Prev: LibreSSL/OpenSSL, Up: Libraries 2.2.2 zlib ---------- @@ -375,9 +377,9 @@ available. Make sure you install the development AND runtime versions of this package. If you have to install zlib manually, you can get the source code from -. Instructions on how to configure, build -and install this package are included within the package. Please make -sure you build development and runtime libraries (which is the default). +. Instructions on how to configure, build and +install this package are included within the package. Please make sure +you build development and runtime libraries (which is the default).  File: tinc.info, Node: lzo, Next: libcurses, Prev: zlib, Up: Libraries @@ -399,7 +401,7 @@ available. Make sure you install the development AND runtime versions of this package. If you have to install lzo manually, you can get the source code from -. Instructions on how to +. Instructions on how to configure, build and install this package are included within the package. Please make sure you build development and runtime libraries (which is the default). @@ -464,9 +466,7 @@ startup scripts and sample configurations. If you cannot use one of the precompiled packages, or you want to compile tinc for yourself, you can use the source. The source is distributed under the GNU General Public License (GPL). Download the -source from the download page (http://www.tinc-vpn.org/download/), which -has the checksums of these files listed; you may wish to check these -with md5sum before continuing. +source from the download page (https://www.tinc-vpn.org/download/). Tinc comes in a convenient autoconf/automake package, which you can just treat the same as any other package. Which is just untar it, type @@ -504,12 +504,12 @@ File: tinc.info, Node: Darwin (MacOS/X) build environment, Next: Cygwin (Windo 3.1.1 Darwin (MacOS/X) build environment ---------------------------------------- -In order to build tinc on Darwin, you need to install the MacOS/X -Developer Tools from -and a recent version of Fink from . +In order to build tinc on Darwin, you need to install Xcode from +. It might also help to install a +recent version of Fink from . -After installation use fink to download and install the following -packages: autoconf25, automake, dlcompat, m4, openssl, zlib and lzo. +You need to download and install LibreSSL (or OpenSSL) and LZO, either +directly from their websites (see *note Libraries::) or using Fink.  File: tinc.info, Node: Cygwin (Windows) build environment, Next: MinGW (Windows) build environment, Prev: Darwin (MacOS/X) build environment, Up: Building and installing tinc @@ -518,7 +518,7 @@ File: tinc.info, Node: Cygwin (Windows) build environment, Next: MinGW (Window ---------------------------------------- If Cygwin hasn't already been installed, install it directly from -. +. When tinc is compiled in a Cygwin environment, it can only be run in this environment, but all programs, including those started outside the @@ -532,7 +532,8 @@ File: tinc.info, Node: MinGW (Windows) build environment, Prev: Cygwin (Window --------------------------------------- You will need to install the MinGW environment from -. +. You also need to download and install LibreSSL +(or OpenSSL) and LZO. When tinc is compiled using MinGW it runs natively under Windows, it is not necessary to keep MinGW installed. @@ -661,7 +662,7 @@ the name of the virtual network interface will be the same as the network name. However, it is not strictly necessary that you call tinc with the -n -option. If you don not use it, the network name will just be empty, and +option. If you do not use it, the network name will just be empty, and tinc will look for files in '/etc/tinc/' instead of '/etc/tinc/NETNAME/'; the configuration file will then be '/etc/tinc/tinc.conf', and the host configuration files are expected to @@ -918,6 +919,11 @@ DeviceType = (platform dependent) followed by an IP header. This mode should support both IPv4 and IPv6 packets. + utun (OS X) + Set type to utun. This is only supported on OS X version + 10.6.8 and higher, but doesn't require the tuntaposx module. + This mode should support both IPv4 and IPv6 packets. + tap (BSD and Linux) Set type to tap. Tinc will expect packets read from the virtual network device to start with an Ethernet header. @@ -998,9 +1004,9 @@ LocalDiscovery = (no) ConnectTo a third node outside the NAT, which normally would prevent the peers from learning each other's LAN address. - Currently, local discovery is implemented by sending broadcast - packets to the LAN during path MTU discovery. This feature may not - work in all possible situations. + Currently, local discovery is implemented by sending some packets + to the local address of the node during UDP discovery. This will + not work with old nodes that don't transmit their local address. LocalDiscoveryAddress
If this variable is specified, local discovery packets are sent to @@ -1051,9 +1057,9 @@ MaxConnectionBurst = (100) connections to only one per second, until the burst has passed. Name = [required] - This is a symbolic name for this connection. The name should - consist only of alfanumeric and underscore characters (a-z, A-Z, - 0-9 and _), and is case sensitive. + This is a symbolic name for this connection. The name must consist + only of alfanumeric and underscore characters (a-z, A-Z, 0-9 and + _), and is case sensitive. If Name starts with a $, then the contents of the environment variable that follows will be used. In that case, invalid @@ -1092,7 +1098,7 @@ ProcessPriority = adjusted. Increasing the priority may help to reduce latency and packet loss on the VPN. -Proxy = socks4 | socks5 | http | exec ... [experimental] +Proxy = socks4 | socks5 | http | exec ... [experimental] Use a proxy when making outgoing connections. The following proxy types are currently supported: @@ -1115,10 +1121,10 @@ Proxy = socks4 | socks5 | http | exec ... [experimental] connection. The environment variables 'NAME', 'NODE', 'REMOTEADDRES' and 'REMOTEPORT' are available. -ReplayWindow = (16) +ReplayWindow = (32) This is the size of the replay tracking window for each remote node, in bytes. The window is a bitfield which tracks 1 packet per - bit, so for example the default setting of 16 will track up to 128 + bit, so for example the default setting of 32 will track up to 256 packets in the window. In high bandwidth scenarios, setting this to a higher value can reduce packet loss from the interaction of replay tracking with underlying real packet loss and/or reordering. @@ -1140,15 +1146,63 @@ TunnelServer = (no) [experimental] '/etc/tinc/NETNAME/hosts/' directory. Setting this options also implicitly sets StrictSubnets. -UDPRcvBuf = (OS default) - Sets the socket receive buffer size for the UDP socket, in bytes. - If unset, the default buffer size will be used by the operating - system. +UDPDiscovery = (yes) + When this option is enabled tinc will try to establish UDP + connectivity to nodes, using TCP while it determines if a node is + reachable over UDP. If it is disabled, tinc always assumes a node + is reachable over UDP. Note that tinc will never use UDP with nodes + that have TCPOnly enabled. -UDPSndBuf = Pq OS default +UDPDiscoveryKeepaliveInterval = (9) + The minimum amount of time between sending UDP ping datagrams to + check UDP connectivity once it has been established. Note that + these pings are large, since they are used to verify link MTU as + well. + +UDPDiscoveryInterval = (2) + The minimum amount of time between sending UDP ping datagrams to + try to establish UDP connectivity. + +UDPDiscoveryTimeout = (30) + If tinc doesn't receive any UDP ping replies over the specified + interval, it will assume UDP communication is broken and will fall + back to TCP. + +UDPInfoInterval = (5) + The minimum amount of time between sending periodic updates about + UDP addresses, which are mostly useful for UDP hole punching. + +UDPRcvBuf = (1048576) + Sets the socket receive buffer size for the UDP socket, in bytes. + If set to zero, the default buffer size will be used by the + operating system. Note: this setting can have a significant impact + on performance, especially raw throughput. + +UDPSndBuf = (1048576) Sets the socket send buffer size for the UDP socket, in bytes. If - unset, the default buffer size will be used by the operating - system. + set to zero, the default buffer size will be used by the operating + system. Note: this setting can have a significant impact on + performance, especially raw throughput. + +UPnP = (no) + If this option is enabled then tinc will search for UPnP-IGD + devices on the local network. It will then create and maintain + port mappings for tinc's listening TCP and UDP ports. If set to + "udponly", tinc will only create a mapping for its UDP (data) port, + not for its TCP (metaconnection) port. Note that tinc must have + been built with miniupnpc support for this feature to be available. + Furthermore, be advised that enabling this can have security + implications, because the miniupnpc library that tinc uses might + not be well-hardened with regard to malicious UPnP replies. + +UPnPDiscoverWait = (5) + The amount of time to wait for replies when probing the local + network for UPnP devices. + +UPnPRefreshPeriod = (5) + How often tinc will re-add the port mapping, in case it gets reset + on the UPnP device. This also controls the duration of the port + mapping itself, which will be set to twice that duration.  File: tinc.info, Node: Host configuration variables, Next: Scripts, Prev: Main configuration variables, Up: Configuration files @@ -1166,8 +1220,8 @@ Address = [] [recommended] Cipher = (blowfish) The symmetric cipher algorithm used to encrypt UDP packets using - the legacy protocol. Any cipher supported by OpenSSL is - recognized. Furthermore, specifying "none" will turn off packet + the legacy protocol. Any cipher supported by LibreSSL or OpenSSL + is recognized. Furthermore, specifying "none" will turn off packet encryption. It is best to use only those ciphers which support CBC mode. This option has no effect for connections using the SPTPS protocol, which always use AES-256-CTR. @@ -1185,10 +1239,10 @@ Compression = (0) Digest = (sha1) The digest algorithm used to authenticate UDP packets using the - legacy protocol. Any digest supported by OpenSSL is recognized. - Furthermore, specifying "none" will turn off packet authentication. - This option has no effect for connections using the SPTPS protocol, - which always use HMAC-SHA-256. + legacy protocol. Any digest supported by LibreSSL or OpenSSL is + recognized. Furthermore, specifying "none" will turn off packet + authentication. This option has no effect for connections using + the SPTPS protocol, which always use HMAC-SHA-256. IndirectData = (no) When set to yes, other nodes which do not already have a meta @@ -1210,6 +1264,11 @@ PMTUDiscovery = (yes) to this node. After the path MTU has been discovered, it will be enforced on the VPN. +MTUInfoInterval = (5) + The minimum amount of time between sending periodic updates about + relay path MTU. Useful for quickly determining MTU to indirect + nodes. + Port = (655) This is the port this tinc daemon listens on. You can use decimal portnumbers or symbolic names (as listed in '/etc/services'). @@ -1249,7 +1308,7 @@ Subnet = Prefixlength is the number of bits set to 1 in the netmask part; for example: netmask 255.255.255.0 would become /24, 255.255.252.0 becomes /22. This conforms to standard CIDR notation as described - in RFC1519 (http://www.ietf.org/rfc/rfc1519.txt) + in RFC1519 (https://www.ietf.org/rfc/rfc1519.txt) A Subnet can be given a weight to indicate its priority over identical Subnets owned by different nodes. The default weight is @@ -1278,16 +1337,28 @@ File: tinc.info, Node: Scripts, Next: How to configure, Prev: Host configurat ------------- Apart from reading the server and host configuration files, tinc can -also run scripts at certain moments. Under Windows (not Cygwin), the -scripts should have the extension '.bat' or '.cmd'. +also run scripts at certain moments. Below is a list of filenames of +scripts and a description of when they are run. A script is only run if +it exists and if it is executable. + +Scripts are run synchronously; this means that tinc will temporarily +stop processing packets until the called script finishes executing. +This guarantees that scripts will execute in the exact same order as the +events that trigger them. If you need to run commands asynchronously, +you have to ensure yourself that they are being run in the background. + +Under Windows (not Cygwin), the scripts should have the extension '.bat' +or '.cmd'. '/etc/tinc/NETNAME/tinc-up' This is the most important script. If it is present it will be executed right after the tinc daemon has been started and has connected to the virtual network device. It should be used to set up the corresponding network interface, but can also be used to - start other things. Under Windows you can use the Network - Connections control panel instead of creating this script. + start other things. + + Under Windows you can use the Network Connections control panel + instead of creating this script. '/etc/tinc/NETNAME/tinc-down' This script is started right before the tinc daemon quits. @@ -2029,7 +2100,7 @@ bugreport: ping or traceroute).  -File: tinc.info, Node: Controlling tinc, Next: Technical information, Prev: Running tinc, Up: Top +File: tinc.info, Node: Controlling tinc, Next: Invitations, Prev: Running tinc, Up: Top 6 Controlling tinc ****************** @@ -2071,6 +2142,9 @@ File: tinc.info, Node: tinc runtime options, Next: tinc environment variables, daemon. If unspecified, the default is '/var/run/tinc.NETNAME.pid'. +'--force' + Force some commands to work despite warnings. + '--help' Display a short reminder of runtime options and commands, then terminate. @@ -2112,7 +2186,8 @@ File: tinc.info, Node: tinc commands, Next: tinc examples, Prev: tinc environ 'add VARIABLE VALUE' As above, but without removing any previously existing - configuration variables. + configuration variables. If the variable already exists with the + given value, nothing happens. 'del VARIABLE [VALUE]' Remove configuration variables with the same name and VALUE. If no @@ -2130,15 +2205,15 @@ File: tinc.info, Node: tinc commands, Next: tinc examples, Prev: tinc environ 'export-all' Export all host configuration files to standard output. -'import [--force]' +'import' Import host configuration file(s) generated by the tinc export command from standard input. Already existing host configuration files are not overwritten unless the option -force is used. -'exchange [--force]' +'exchange' The same as export followed by import. -'exchange-all [--force]' +'exchange-all' The same as export-all followed by import. 'invite NAME' @@ -2202,6 +2277,11 @@ File: tinc.info, Node: tinc commands, Next: tinc examples, Prev: tinc environ Black nodes are either directly or indirectly reachable, but direct reachability has not been tried yet. +'dump invitations' + Dump a list of outstanding invitations. The filename of the + invitation, as well as the name of the node that is being invited + is shown for each invitation. + 'info NODE | SUBNET | ADDRESS' Show information about a particular NODE, SUBNET or ADDRESS. If an ADDRESS is given, any matching subnet will be shown. @@ -2238,10 +2318,39 @@ File: tinc.info, Node: tinc commands, Next: tinc examples, Prev: tinc environ file or piped through a program that can parse it directly, such as tcpdump. -'network' +'network [NETNAME]' If NETNAME is given, switch to that network. Otherwise, display a list of all networks for which configuration files exist. +'fsck' + This will check the configuration files for possible problems, such + as unsafe file permissions, missing executable bit on script, + unknown and obsolete configuration variables, wrong public and/or + private keys, and so on. + + When problems are found, this will be printed on a line with + WARNING or ERROR in front of it. Most problems must be corrected + by the user itself, however in some cases (like file permissions + and missing public keys), tinc will ask if it should fix the + problem. + +'sign [FILENAME]' + Sign a file with the local node's private key. If no FILENAME is + given, the file is read from standard input. The signed file is + written to standard output. + +'verify NAME [FILENAME]' + + Check the signature of a file against a node's public key. The + NAME of the node must be given, or can be "." to check against the + local node's public key, or "*" to allow a signature from any node + whose public key is known. If no FILENAME is given, the file is + read from standard input. If the verification is succesful, a copy + of the input with the signature removed is written to standard + output, and the exit code will be zero. If the verification + failed, nothing will be written to standard output, and the exit + code will be non-zero. +  File: tinc.info, Node: tinc examples, Next: tinc top, Prev: tinc commands, Up: Controlling tinc @@ -2325,9 +2434,170 @@ can be changed using the following keys: Quit.  -File: tinc.info, Node: Technical information, Next: Platform specific information, Prev: Controlling tinc, Up: Top +File: tinc.info, Node: Invitations, Next: Technical information, Prev: Controlling tinc, Up: Top -7 Technical information +7 Invitations +************* + +Invitations are an easy way to add new nodes to an existing VPN. +Invitations can be created on an existing node using the 'tinc invite' +command, which generates a relatively short URL which can be given to +someone else, who uses the 'tinc join' command to automatically set up +tinc so it can connect to the inviting node. The next sections describe +how invitations actually work, and how to further automate the +invitations. + +* Menu: + +* How invitations work:: +* Invitation file format:: +* Writing an invitation-created script:: + + +File: tinc.info, Node: How invitations work, Next: Invitation file format, Up: Invitations + +7.1 How invitations work +======================== + +When an invitation is created on a node (which from now on we will call +the server) using the 'tinc invite' command, an invitation file is +created that contains all the information necessary for the invitee +(which we will call the client) to create its configuration files. The +invitation file is stays on the server, but a URL is generated that has +enough information for the client to contact the server and to retrieve +the invitation file. The whole URL is around 80 characters long and +looks like this: + + server.example.org:12345/cW1NhLHS-1WPFlcFio8ztYHvewTTKYZp8BjEKg3vbMtDz7w4 + +It is composed of four parts: + + hostname : port / keyhash cookie + +The hostname and port tell the client how to reach the tinc daemon on +the server. The part after the slash looks like one blob, but is +composed of two parts. The keyhash is the hash of the public key of the +server. The cookie is a shared secret that identifies the client to the +server. + +When the client connects to the server in order to join the VPN, the +client and server will exchange temporary public keys. The client +verifies that the hash of the server's public key matches the keyhash +from the invitation URL. If not, it will immediately exit with an error. +Otherwise, an ECDH exchange will happen so the client and server can +communicate privately with each other. The client will then present the +cookie to the server. The server uses this to look up the corresponding +invitation file it generated earlier. If it exists, it will send the +invitation file to the client. The client will also create a permanent +public key, and send it to the server. After the exchange is completed, +the connection is broken. The server creates a host config file for the +client containing the client's permanent public key, and the client +creates tinc.conf, host config files and possibly a tinc-up script based +on the information in the invitation file. + +It is important that the invitation URL is kept secret until it is used; +if another person gets a copy of the invitation URL before the real +client runs the 'tinc join' command, then that other person can try to +join the VPN. + + +File: tinc.info, Node: Invitation file format, Next: Writing an invitation-created script, Prev: How invitations work, Up: Invitations + +7.2 Invitation file format +========================== + +The contents of an invitation file that is generated by the 'tinc +invite' command looks like this: + + Name = client + Netname = vpn + ConnectTo = server + #-------------------------------------# + Name = server + Ed25519PublicKey = augbnwegoij123587... + Address = server.example.com + +The file is basically a concatenation of several host config blocks. +Each host config block starts with 'Name = ...'. Lines that look like +'#---#' are not important, it just makes it easier for humans to read +the file. + +The first host config block is always the one representing the invitee. +So the first Name statement determines the name that the invitee will +get. From the first block, the 'tinc.conf' and 'hosts/client' files +will be generated; the 'tinc join' command on the client will +automatically separate statements based on whether they should be in +'tinc.conf' or in a host config file. Some statements are special and +are treated differently: + +Netname = + This is a hint to the invitee which netname to use for the VPN. It + is used if the invitee did not already specify a netname, and if + there is no pre-existing configuration with the same netname. + +Ifconfig = + This is a hint for generating a 'tinc-up' script. If an address is + specified, a command will be added to 'tinc-up' so the VPN + interface will be configured to have the given address. If it is + the word "dhcp", a command will be added to start a DHCP client on + the VPN interface. If it is the word dhcpv6, it will be a DHCPv6 + client. If it is "slaac", then it will add commands to enable IPv6 + stateless address autoconfiguration. It is also possible to + specify a MAC address, in which case a command will be added to set + the MAC address of the VPN interface. + + The exact commands added to the 'tinc-up' script depends on the + operating system the client is using. Multiple Ifconfig statements + can be specified, however one should only use one Ifconfig + statement per address family. + +Route = [] + This is a hint for generating a 'tinc-up' script. Route statements + are similar to Ifconfig statements, but add routes instead of + addresses. These only allow IPv4 and IPv6 routes. If no gateway + address is specified, the route is directed to the VPN interface. + In general, a gateway is only necessary when running tinc in switch + mode. + +Subsequent host config blocks are copied verbatim into their respective +files in 'hosts/'. The invitation file generated by 'tinc invite' will +normally only contain two blocks; one for the client and one for the +server. + + +File: tinc.info, Node: Writing an invitation-created script, Prev: Invitation file format, Up: Invitations + +7.3 Writing an invitation-created script +======================================== + +When an invitation is generated, the "invitation-created" script is +called (if it exists) right after the invitation file is written, but +before the URL has been written to stdout. This allows one to change +the invitation file automatically before the invitation URL is passed to +the invitee. Here is an example shell script that aproximately +recreates the default invitation file: + + #!/bin/sh + + cat >$INVITATION_FILE <>$INVITATION_FILE + +You can add more ConnectTo statements, and change 'tinc export' to 'tinc +export-all' for example. But you can also use the script to +automatically hand out a Subnet to the invitee. Note that the script +doesn't have to be a shell script, you can use any language, it just has +to be executable. + + +File: tinc.info, Node: Technical information, Next: Platform specific information, Prev: Invitations, Up: Top + +8 Technical information *********************** * Menu: @@ -2339,7 +2609,7 @@ File: tinc.info, Node: Technical information, Next: Platform specific informat  File: tinc.info, Node: The connection, Next: The meta-protocol, Up: Technical information -7.1 The connection +8.1 The connection ================== Tinc is a daemon that takes VPN data and transmit that to another host @@ -2353,7 +2623,7 @@ computer over the existing Internet infrastructure.  File: tinc.info, Node: The UDP tunnel, Next: The meta-connection, Up: The connection -7.1.1 The UDP tunnel +8.1.1 The UDP tunnel -------------------- The data itself is read from a character device file, the so-called @@ -2412,7 +2682,7 @@ Solaris.  File: tinc.info, Node: The meta-connection, Prev: The UDP tunnel, Up: The connection -7.1.2 The meta-connection +8.1.2 The meta-connection ------------------------- Having only a UDP connection available is not enough. Though suitable @@ -2444,7 +2714,7 @@ re-sending packets.  File: tinc.info, Node: The meta-protocol, Next: Security, Prev: The connection, Up: Technical information -7.2 The meta-protocol +8.2 The meta-protocol ===================== The meta protocol is used to tie all tinc daemons together, and exchange @@ -2549,7 +2819,7 @@ This basically covers what is sent over the meta connection by tinc.  File: tinc.info, Node: Security, Prev: The meta-protocol, Up: Technical information -7.3 Security +8.3 Security ============ Tinc got its name from "TINC," short for _There Is No Cabal_; the @@ -2582,7 +2852,7 @@ option set to yes, otherwise the legacy protocol will be used.  File: tinc.info, Node: Legacy authentication protocol, Next: Simple Peer-to-Peer Security, Up: Security -7.3.1 Legacy authentication protocol +8.3.1 Legacy authentication protocol ------------------------------------ daemon message @@ -2679,7 +2949,7 @@ provide perfect forward secrecy.  File: tinc.info, Node: Simple Peer-to-Peer Security, Next: Encryption of network packets, Prev: Legacy authentication protocol, Up: Security -7.3.2 Simple Peer-to-Peer Security +8.3.2 Simple Peer-to-Peer Security ---------------------------------- The SPTPS protocol is designed to address the weaknesses in the legacy @@ -2837,7 +3107,7 @@ counter.  File: tinc.info, Node: Encryption of network packets, Next: Security issues, Prev: Simple Peer-to-Peer Security, Up: Security -7.3.3 Encryption of network packets +8.3.3 Encryption of network packets ----------------------------------- A data packet can only be sent if the encryption key is known to both @@ -2867,7 +3137,7 @@ intercept. The encryption algorithm and message authentication algorithm can be changed in the configuration. The length of the message authentication codes is also adjustable. The length of the key for the encryption algorithm is always the default length used by -OpenSSL. +LibreSSL/OpenSSL. The SPTPS protocol is described in *note Simple Peer-to-Peer Security::. For comparison, this is how SPTPS UDP packets look: @@ -2887,15 +3157,15 @@ digest, this cannot be changed.  File: tinc.info, Node: Security issues, Prev: Encryption of network packets, Up: Security -7.3.4 Security issues +8.3.4 Security issues --------------------- In August 2000, we discovered the existence of a security hole in all versions of tinc up to and including 1.0pre2. This had to do with the way we exchanged keys. Since then, we have been working on a new authentication scheme to make tinc as secure as possible. The current -version uses the OpenSSL library and uses strong authentication with RSA -keys. +version uses the LibreSSL or OpenSSL library and uses strong +authentication with RSA keys. On the 29th of December 2001, Jerome Etienne posted a security analysis of tinc 1.0pre4. Due to a lack of sequence numbers and a message @@ -2923,7 +3193,7 @@ tinc or give us feedback, you are stronly encouraged to do so.  File: tinc.info, Node: Platform specific information, Next: About us, Prev: Technical information, Up: Top -8 Platform specific information +9 Platform specific information ******************************* * Menu: @@ -2934,7 +3204,7 @@ File: tinc.info, Node: Platform specific information, Next: About us, Prev: T  File: tinc.info, Node: Interface configuration, Next: Routes, Up: Platform specific information -8.1 Interface configuration +9.1 Interface configuration =========================== When configuring an interface, one normally assigns it an address and a @@ -2984,7 +3254,7 @@ Linux 'ip tuntap add dev' INTERFACE 'mode' TUN|TAP 'user' USERNAME  File: tinc.info, Node: Routes, Prev: Interface configuration, Up: Platform specific information -8.2 Routes +9.2 Routes ========== In some cases it might be necessary to add more routes to the virtual @@ -3020,8 +3290,8 @@ Windows 'netsh interface ipv6 add route' NETWORK ADDRESS/PREFIXLENGTH  File: tinc.info, Node: About us, Next: Concept Index, Prev: Platform specific information, Up: Top -9 About us -********** +10 About us +*********** * Menu: @@ -3031,21 +3301,21 @@ File: tinc.info, Node: About us, Next: Concept Index, Prev: Platform specific  File: tinc.info, Node: Contact information, Next: Authors, Up: About us -9.1 Contact information -======================= +10.1 Contact information +======================== -Tinc's website is at , this server is located +Tinc's website is at , this server is located in the Netherlands. We have an IRC channel on the FreeNode and OFTC IRC networks. Connect -to irc.freenode.net (http://www.freenode.net/) or irc.oftc.net -(http://www.oftc.net/) and join channel #tinc. +to irc.freenode.net (https://freenode.net/) or irc.oftc.net +(https://www.oftc.net/) and join channel #tinc.  File: tinc.info, Node: Authors, Prev: Contact information, Up: About us -9.2 Authors -=========== +10.2 Authors +============ Ivo Timmermans (zarq) Guus Sliepen (guus) () @@ -3092,7 +3362,7 @@ Concept Index * CHAL_REPLY: Legacy authentication protocol. (line 6) * CIDR notation: Host configuration variables. - (line 96) + (line 101) * Cipher: Host configuration variables. (line 14) * ClampMSS: Host configuration variables. @@ -3108,17 +3378,17 @@ Concept Index (line 65) * daemon: Running tinc. (line 11) * data-protocol: The meta-connection. (line 18) -* debug: tinc commands. (line 121) +* debug: tinc commands. (line 127) * debug level: Runtime options. (line 17) * debug levels: Debug levels. (line 6) * DecrementTTL: Main configuration variables. (line 76) -* del: tinc commands. (line 26) +* del: tinc commands. (line 27) * DEL_EDGE: The meta-protocol. (line 46) * DEL_SUBNET: The meta-protocol. (line 46) * Device: Main configuration variables. (line 85) -* DEVICE: Scripts. (line 60) +* DEVICE: Scripts. (line 72) * device files: Device files. (line 6) * DeviceStandby: Main configuration variables. (line 92) @@ -3127,111 +3397,117 @@ Concept Index * Digest: Host configuration variables. (line 33) * DirectOnly: Main configuration variables. - (line 164) -* disconnect: tinc commands. (line 136) + (line 169) +* disconnect: tinc commands. (line 142) * dummy: Main configuration variables. (line 106) -* dump: tinc commands. (line 94) +* dump: tinc commands. (line 95) * Ed25519PrivateKeyFile: Main configuration variables. - (line 171) -* edit: tinc commands. (line 31) + (line 176) +* edit: tinc commands. (line 32) * encapsulating: The UDP tunnel. (line 30) * encryption: Encryption of network packets. (line 6) -* environment variables: Scripts. (line 48) +* environment variables: Scripts. (line 60) * example: Example configuration. (line 6) -* exchange: tinc commands. (line 47) -* exchange-all: tinc commands. (line 50) +* exchange: tinc commands. (line 48) +* exchange-all: tinc commands. (line 51) * exec: Main configuration variables. - (line 352) + (line 357) * ExperimentalProtocol: Main configuration variables. - (line 175) -* export: tinc commands. (line 35) -* export-all: tinc commands. (line 39) + (line 180) +* export: tinc commands. (line 36) +* export-all: tinc commands. (line 40) * Forwarding: Main configuration variables. - (line 182) + (line 187) * frame type: The UDP tunnel. (line 6) -* generate-ed25519-keys: tinc commands. (line 85) -* generate-keys: tinc commands. (line 80) -* generate-rsa-keys: tinc commands. (line 88) +* fsck: tinc commands. (line 160) +* generate-ed25519-keys: tinc commands. (line 86) +* generate-keys: tinc commands. (line 81) +* generate-rsa-keys: tinc commands. (line 89) * get: tinc commands. (line 11) -* graph: tinc commands. (line 107) +* graph: tinc commands. (line 108) * Hostnames: Main configuration variables. - (line 202) + (line 207) * http: Main configuration variables. - (line 349) + (line 354) * hub: Main configuration variables. - (line 270) + (line 275) * ID: Legacy authentication protocol. (line 6) -* import: tinc commands. (line 42) +* Ifconfig: Invitation file format. + (line 35) +* import: tinc commands. (line 43) * IndirectData: Host configuration variables. (line 40) -* info: tinc commands. (line 114) +* info: tinc commands. (line 120) * init: tinc commands. (line 6) * Interface: Main configuration variables. - (line 213) -* INTERFACE: Scripts. (line 63) -* INVITATION_FILE: Scripts. (line 86) -* INVITATION_URL: Scripts. (line 90) -* invite: tinc commands. (line 53) + (line 218) +* INTERFACE: Scripts. (line 75) +* INVITATION_FILE: Scripts. (line 98) +* INVITATION_URL: Scripts. (line 102) +* invite: tinc commands. (line 54) * IRC: Contact information. (line 9) -* join: tinc commands. (line 58) +* join: tinc commands. (line 59) * KeyExpire: Main configuration variables. - (line 275) + (line 280) * KEY_CHANGED: The meta-protocol. (line 63) * legacy authentication protocol: Legacy authentication protocol. (line 6) * libcurses: libcurses. (line 6) * libraries: Libraries. (line 6) * libreadline: libreadline. (line 6) -* license: OpenSSL. (line 35) +* LibreSSL: LibreSSL/OpenSSL. (line 6) +* license: LibreSSL/OpenSSL. (line 38) * ListenAddress: Main configuration variables. - (line 221) + (line 226) * LocalDiscovery: Main configuration variables. - (line 233) + (line 238) * LocalDiscoveryAddress: Main configuration variables. - (line 244) -* log: tinc commands. (line 124) + (line 249) +* log: tinc commands. (line 130) * lzo: lzo. (line 6) * MACExpire: Main configuration variables. - (line 281) + (line 286) * MACLength: Host configuration variables. (line 45) * MaxConnectionBurst: Main configuration variables. - (line 286) + (line 291) * meta-protocol: The meta-connection. (line 18) * META_KEY: Legacy authentication protocol. (line 6) * Mode: Main configuration variables. - (line 248) + (line 253) +* MTUInfoInterval: Host configuration variables. + (line 60) * multicast: Main configuration variables. (line 118) * multiple networks: Multiple networks. (line 6) * Name: Main configuration variables. - (line 292) -* NAME: Scripts. (line 57) + (line 297) +* NAME: Scripts. (line 69) * netmask: Network interfaces. (line 39) * netname: Multiple networks. (line 6) -* NETNAME: Scripts. (line 54) +* NETNAME: Scripts. (line 66) * NETNAME <1>: tinc environment variables. (line 6) +* network: tinc commands. (line 156) * Network Administrators Guide: Configuration introduction. (line 15) -* network [NETNAME]: tinc commands. (line 150) -* NODE: Scripts. (line 67) -* OpenSSL: OpenSSL. (line 6) +* NODE: Scripts. (line 79) +* OpenSSL: LibreSSL/OpenSSL. (line 6) * options: Runtime options. (line 9) -* pcap: tinc commands. (line 144) +* pcap: tinc commands. (line 150) * PEM format: Host configuration variables. - (line 72) -* pid: tinc commands. (line 77) + (line 77) +* pid: tinc commands. (line 78) * PING: The meta-protocol. (line 88) * PingInterval: Main configuration variables. - (line 303) + (line 308) * PingTimeout: Main configuration variables. - (line 307) + (line 312) * platforms: Supported platforms. (line 6) * PMTU: Host configuration variables. (line 52) @@ -3239,39 +3515,41 @@ Concept Index (line 55) * PONG: The meta-protocol. (line 88) * Port: Host configuration variables. - (line 60) + (line 65) * port numbers: Other files. (line 17) * PriorityInheritance: Main configuration variables. - (line 313) + (line 318) * private: Virtual Private Networks. (line 10) * PrivateKey: Main configuration variables. - (line 318) + (line 323) * PrivateKeyFile: Main configuration variables. - (line 324) -* ProcessPriority: Main configuration variables. (line 329) -* Proxy: Main configuration variables. +* ProcessPriority: Main configuration variables. (line 334) +* Proxy: Main configuration variables. + (line 339) * PublicKey: Host configuration variables. - (line 64) + (line 69) * PublicKeyFile: Host configuration variables. - (line 67) -* purge: tinc commands. (line 118) + (line 72) +* purge: tinc commands. (line 124) * raw_socket: Main configuration variables. (line 111) * release: Supported platforms. (line 14) -* reload: tinc commands. (line 72) -* REMOTEADDRESS: Scripts. (line 72) -* REMOTEPORT: Scripts. (line 75) +* reload: tinc commands. (line 73) +* REMOTEADDRESS: Scripts. (line 84) +* REMOTEPORT: Scripts. (line 87) * ReplayWindow: Main configuration variables. - (line 357) + (line 362) * requirements: Libraries. (line 6) * REQ_KEY: The meta-protocol. (line 63) -* restart: tinc commands. (line 69) -* retry: tinc commands. (line 129) +* restart: tinc commands. (line 70) +* retry: tinc commands. (line 135) +* Route: Invitation file format. + (line 51) * router: Main configuration variables. - (line 251) + (line 256) * runtime options: Runtime options. (line 9) * scalability: tinc. (line 19) * scripts: Scripts. (line 6) @@ -3279,54 +3557,74 @@ Concept Index (line 18) * set: tinc commands. (line 16) * shell: Controlling tinc. (line 11) +* sign: tinc commands. (line 172) * signals: Signals. (line 6) * socks4: Main configuration variables. - (line 338) -* socks5: Main configuration variables. (line 343) +* socks5: Main configuration variables. + (line 348) * SPTPS: Simple Peer-to-Peer Security. (line 6) -* start: tinc commands. (line 63) -* stop: tinc commands. (line 66) +* start: tinc commands. (line 64) +* stop: tinc commands. (line 67) * StrictSubnets: Main configuration variables. - (line 368) + (line 373) * Subnet: Host configuration variables. - (line 79) -* SUBNET: Scripts. (line 79) + (line 84) +* SUBNET: Scripts. (line 91) * SVPN: Security. (line 11) * switch: Main configuration variables. - (line 259) + (line 264) * TCP: The meta-connection. (line 10) * TCPonly: Host configuration variables. - (line 108) + (line 113) * tinc: Introduction. (line 6) * TINC: Security. (line 6) -* tinc-down: Scripts. (line 18) -* tinc-up: Scripts. (line 10) +* tinc-down: Scripts. (line 30) +* tinc-up: Scripts. (line 20) * tinc-up <1>: Network interfaces. (line 19) * tincd: tinc. (line 14) -* top: tinc commands. (line 139) +* top: tinc commands. (line 145) * top <1>: tinc top. (line 6) * traditional VPNs: tinc. (line 19) * tunifhead: Main configuration variables. (line 153) * TunnelServer: Main configuration variables. - (line 375) + (line 380) * tunnohead: Main configuration variables. (line 147) * UDP: The UDP tunnel. (line 30) * UDP <1>: Encryption of network packets. (line 11) -* UDPRcvBuf: Main configuration variables. - (line 382) -* UDPSndBuf: Main configuration variables. +* UDPDiscoveryInterval: Main configuration variables. + (line 400) +* UDPDiscoveryKeepaliveInterval: Main configuration variables. + (line 394) +* UDPDiscoveryTimeout: Main configuration variables. + (line 404) +* UDPDiscovey: Main configuration variables. (line 387) +* UDPInfoInterval: Main configuration variables. + (line 409) +* UDPRcvBuf: Main configuration variables. + (line 413) +* UDPSndBuf: Main configuration variables. + (line 419) * UML: Main configuration variables. (line 129) * Universal tun/tap: Configuration of Linux kernels. (line 6) +* UPnP: Main configuration variables. + (line 425) +* UPnPDiscoverWait: Main configuration variables. + (line 436) +* UPnPRefreshPeriod: Main configuration variables. + (line 440) +* utun: Main configuration variables. + (line 160) * VDE: Main configuration variables. (line 134) +* verify: tinc commands. (line 177) * virtual: Virtual Private Networks. (line 18) * virtual network device: The UDP tunnel. (line 6) @@ -3335,81 +3633,85 @@ Concept Index * vpnd: tinc. (line 6) * website: Contact information. (line 6) * Weight: Host configuration variables. - (line 115) -* WEIGHT: Scripts. (line 82) + (line 120) +* WEIGHT: Scripts. (line 94) * zlib: zlib. (line 6)  Tag Table: -Node: Top808 -Node: Introduction1128 -Node: Virtual Private Networks1932 -Node: tinc3644 -Node: Supported platforms5156 -Node: Preparations5852 -Node: Configuring the kernel6108 -Node: Configuration of Linux kernels6517 -Node: Configuration of FreeBSD kernels7366 -Node: Configuration of OpenBSD kernels7831 -Node: Configuration of NetBSD kernels8439 -Node: Configuration of Solaris kernels8841 -Node: Configuration of Darwin (MacOS/X) kernels9502 -Node: Configuration of Windows10191 -Node: Libraries10704 -Node: OpenSSL11140 -Node: zlib13412 -Node: lzo14430 -Node: libcurses15420 -Node: libreadline16330 -Node: Installation17267 -Node: Building and installing tinc18276 -Node: Darwin (MacOS/X) build environment18932 -Node: Cygwin (Windows) build environment19496 -Node: MinGW (Windows) build environment20080 -Node: System files20598 -Node: Device files20863 -Node: Other files21276 -Node: Configuration21889 -Node: Configuration introduction22176 -Node: Multiple networks23697 -Node: How connections work25065 -Node: Configuration files27626 -Node: Main configuration variables29258 -Node: Host configuration variables47397 -Node: Scripts53256 -Node: How to configure56657 -Node: Network interfaces61141 -Node: Example configuration63520 -Node: Running tinc68619 -Node: Runtime options69206 -Node: Signals72066 -Node: Debug levels72915 -Node: Solving problems73851 -Node: Error messages75277 -Node: Sending bug reports79594 -Node: Controlling tinc80541 -Node: tinc runtime options81287 -Node: tinc environment variables81974 -Node: tinc commands82303 -Node: tinc examples87567 -Node: tinc top88129 -Node: Technical information89714 -Node: The connection89949 -Node: The UDP tunnel90261 -Node: The meta-connection93306 -Node: The meta-protocol94764 -Node: Security99747 -Node: Legacy authentication protocol101084 -Node: Simple Peer-to-Peer Security105701 -Node: Encryption of network packets111346 -Node: Security issues113975 -Node: Platform specific information115710 -Node: Interface configuration115938 -Node: Routes118379 -Node: About us120290 -Node: Contact information120465 -Node: Authors120867 -Node: Concept Index121269 +Node: Top821 +Node: Introduction1157 +Node: Virtual Private Networks1961 +Node: tinc3673 +Node: Supported platforms5185 +Node: Preparations5882 +Node: Configuring the kernel6138 +Node: Configuration of Linux kernels6547 +Node: Configuration of FreeBSD kernels7396 +Node: Configuration of OpenBSD kernels7861 +Node: Configuration of NetBSD kernels8218 +Node: Configuration of Solaris kernels8620 +Node: Configuration of Darwin (MacOS/X) kernels9282 +Node: Configuration of Windows10095 +Node: Libraries10634 +Node: LibreSSL/OpenSSL11091 +Node: zlib13617 +Node: lzo14639 +Node: libcurses15630 +Node: libreadline16540 +Node: Installation17477 +Node: Building and installing tinc18381 +Node: Darwin (MacOS/X) build environment19037 +Node: Cygwin (Windows) build environment19596 +Node: MinGW (Windows) build environment20181 +Node: System files20769 +Node: Device files21034 +Node: Other files21447 +Node: Configuration22060 +Node: Configuration introduction22347 +Node: Multiple networks23868 +Node: How connections work25235 +Node: Configuration files27796 +Node: Main configuration variables29428 +Node: Host configuration variables50169 +Node: Scripts56239 +Node: How to configure60139 +Node: Network interfaces64623 +Node: Example configuration67002 +Node: Running tinc72101 +Node: Runtime options72688 +Node: Signals75548 +Node: Debug levels76397 +Node: Solving problems77333 +Node: Error messages78759 +Node: Sending bug reports83076 +Node: Controlling tinc84023 +Node: tinc runtime options84759 +Node: tinc environment variables85508 +Node: tinc commands85837 +Node: tinc examples92695 +Node: tinc top93257 +Node: Invitations94842 +Node: How invitations work95505 +Node: Invitation file format97798 +Node: Writing an invitation-created script100723 +Node: Technical information101785 +Node: The connection102015 +Node: The UDP tunnel102327 +Node: The meta-connection105372 +Node: The meta-protocol106830 +Node: Security111813 +Node: Legacy authentication protocol113150 +Node: Simple Peer-to-Peer Security117767 +Node: Encryption of network packets123412 +Node: Security issues126050 +Node: Platform specific information127797 +Node: Interface configuration128025 +Node: Routes130466 +Node: About us132377 +Node: Contact information132554 +Node: Authors132957 +Node: Concept Index133361  End Tag Table diff --git a/doc/tinc.texi b/doc/tinc.texi index 2cb55a7..cb50e74 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-2014 Ivo Timmermans, +Copyright @copyright{} 1998-2016 Ivo Timmermans, Guus Sliepen and Wessel Dankers . @@ -43,7 +43,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-2014 Ivo Timmermans, +Copyright @copyright{} 1998-2016 Ivo Timmermans, Guus Sliepen and Wessel Dankers . @@ -70,6 +70,7 @@ permission notice identical to this one. * Configuration:: * Running tinc:: * Controlling tinc:: +* Invitations:: * Technical information:: * Platform specific information:: * About us:: @@ -191,7 +192,7 @@ packets. @cindex release For an up to date list of supported platforms, please check the list on our website: -@uref{http://www.tinc-vpn.org/platforms/}. +@uref{https://www.tinc-vpn.org/platforms/}. @c @c @@ -273,12 +274,7 @@ The tap driver can be loaded with @code{kldload if_tap}, or by adding @code{if_t @node Configuration of OpenBSD kernels @subsection Configuration of OpenBSD kernels -For OpenBSD version 2.9 and higher, -the tun driver is included in the default kernel configuration. -There is also a kernel patch from @uref{http://diehard.n-r-g.com/stuff/openbsd/} -which adds a tap device to OpenBSD which should work with tinc, -but with recent versions of OpenBSD, -a tun device can act as a tap device by setting the link0 option with ifconfig. +Recent versions of OpenBSD come with both tun and tap devices enabled in the default kernel configuration. @c ================================================================== @@ -298,7 +294,7 @@ Tunneling IPv6 may not work on NetBSD's tun device. For Solaris 8 (SunOS 5.8) and higher, the tun driver may or may not be included in the default kernel configuration. If it isn't, the source can be downloaded from @uref{http://vtun.sourceforge.net/tun/}. -For x86 and sparc64 architectures, precompiled versions can be found at @uref{http://www.monkey.org/~dugsong/fragroute/}. +For x86 and sparc64 architectures, precompiled versions can be found at @uref{https://www.monkey.org/~dugsong/fragroute/}. If the @file{net/if_tun.h} header file is missing, install it from the source package. @@ -307,15 +303,14 @@ If the @file{net/if_tun.h} header file is missing, install it from the source pa @subsection Configuration of Darwin (MacOS/X) kernels Tinc on Darwin relies on a tunnel driver for its data acquisition from the kernel. -Tinc supports either the driver from @uref{http://tuntaposx.sourceforge.net/}, +OS X version 10.6.8 and later have a built-in tun driver called "utun". +Tinc also supports the driver from @uref{http://tuntaposx.sourceforge.net/}, which supports both tun and tap style devices, -and also the driver from from @uref{http://chrisp.de/en/projects/tunnel.html}. -The former driver is recommended. -The tunnel driver must be loaded before starting tinc with the following command: -@example -kmodload tunnel -@end example +By default, tinc expects the tuntaposx driver to be installed. +To use the utun driver, set add @code{Device = utunX} to @file{tinc.conf}, +where X is the desired number for the utun interface. +You can also omit the number, in which case the first free number will be chosen. @c ================================================================== @@ -323,7 +318,7 @@ kmodload tunnel @subsection Configuration of Windows You will need to install the latest TAP-Win32 driver from OpenVPN. -You can download it from @uref{http://openvpn.sourceforge.net}. +You can download it from @uref{https://openvpn.net/index.php/open-source/downloads.html}. Using the Network Connections control panel, configure the TAP-Win32 network interface in the same way as you would do from the tinc-up script, as explained in the rest of the documentation. @@ -335,13 +330,13 @@ as explained in the rest of the documentation. @cindex requirements @cindex libraries -Before you can configure or build tinc, you need to have the OpenSSL, zlib, +Before you can configure or build tinc, you need to have the LibreSSL or OpenSSL, zlib, lzo, curses and readline libraries installed on your system. If you try to configure tinc without having them installed, configure will give you an error message, and stop. @menu -* OpenSSL:: +* LibreSSL/OpenSSL:: * zlib:: * lzo:: * libcurses:: @@ -350,12 +345,13 @@ message, and stop. @c ================================================================== -@node OpenSSL -@subsection OpenSSL +@node LibreSSL/OpenSSL +@subsection LibreSSL/OpenSSL +@cindex LibreSSL @cindex OpenSSL For all cryptography-related functions, tinc uses the functions provided -by the OpenSSL library. +by the LibreSSL or the OpenSSL library. If this library is not installed, you wil get an error when configuring tinc for build. Support for running tinc with other cryptographic libraries @@ -365,21 +361,23 @@ You can use your operating system's package manager to install this if available. Make sure you install the development AND runtime versions of this package. -If you have to install OpenSSL manually, you can get the source code -from @url{http://www.openssl.org/}. Instructions on how to configure, -build and install this package are included within the package. Please -make sure you build development and runtime libraries (which is the +If your operating system comes neither with LibreSSL or OpenSSL, you have to +install one manually. It is recommended that you get the latest version of +LibreSSL from @url{http://www.libressl.org/}. Instructions on how to +configure, build and install this package are included within the package. +Please make sure you build development and runtime libraries (which is the default). -If you installed the OpenSSL libraries from source, it may be necessary +If you installed the LibreSSL or OpenSSL libraries from source, it may be necessary to let configure know where they are, by passing configure one of the ---with-openssl-* parameters. +--with-openssl-* parameters. Note that you even have to use --with-openssl-* if you +are using LibreSSL. @example ---with-openssl=DIR OpenSSL library and headers prefix ---with-openssl-include=DIR OpenSSL headers directory +--with-openssl=DIR LibreSSL/OpenSSL library and headers prefix +--with-openssl-include=DIR LibreSSL/OpenSSL headers directory (Default is OPENSSL_DIR/include) ---with-openssl-lib=DIR OpenSSL library directory +--with-openssl-lib=DIR LibreSSL/OpenSSL library directory (Default is OPENSSL_DIR/lib) @end example @@ -390,7 +388,7 @@ to let configure know where they are, by passing configure one of the The complete source code of tinc is covered by the GNU GPL version 2. Since the license under which OpenSSL is distributed is not directly compatible with the terms of the GNU GPL -@uref{http://www.openssl.org/support/faq.html#LEGAL2}, we +@uref{https://www.openssl.org/support/faq.html#LEGAL2}, we include an exemption to the GPL (see also the file COPYING.README) to allow everyone to create a statically or dynamically linked executable: @@ -406,8 +404,8 @@ we also present the following exemption: @quotation Hereby I grant a special exception to the tinc VPN project -(http://www.tinc-vpn.org/) to link the LZO library with the OpenSSL library -(http://www.openssl.org). +(https://www.tinc-vpn.org/) to link the LZO library with the OpenSSL library +(https://www.openssl.org). Markus F.X.J. Oberhumer @end quotation @@ -432,7 +430,7 @@ available. Make sure you install the development AND runtime versions of this package. If you have to install zlib manually, you can get the source code -from @url{http://www.gzip.org/zlib/}. Instructions on how to configure, +from @url{http://www.zlib.net/}. Instructions on how to configure, build and install this package are included within the package. Please make sure you build development and runtime libraries (which is the default). @@ -456,7 +454,7 @@ available. Make sure you install the development AND runtime versions of this package. If you have to install lzo manually, you can get the source code -from @url{http://www.oberhumer.com/opensource/lzo/}. Instructions on how to configure, +from @url{https://www.oberhumer.com/opensource/lzo/}. Instructions on how to configure, build and install this package are included within the package. Please make sure you build development and runtime libraries (which is the default). @@ -527,9 +525,7 @@ system startup scripts and sample configurations. If you cannot use one of the precompiled packages, or you want to compile tinc for yourself, you can use the source. The source is distributed under the GNU General Public License (GPL). Download the source from the -@uref{http://www.tinc-vpn.org/download/, download page}, which has -the checksums of these files listed; you may wish to check these with -md5sum before continuing. +@uref{https://www.tinc-vpn.org/download/, download page}. Tinc comes in a convenient autoconf/automake package, which you can just treat the same as any other package. Which is just untar it, type @@ -566,19 +562,18 @@ The documentation that comes along with your distribution will tell you how to d @node Darwin (MacOS/X) build environment @subsection Darwin (MacOS/X) build environment -In order to build tinc on Darwin, you need to install the MacOS/X Developer Tools -from @uref{http://developer.apple.com/tools/macosxtools.html} and -a recent version of Fink from @uref{http://www.finkproject.org/}. +In order to build tinc on Darwin, you need to install Xcode from @uref{https://developer.apple.com/xcode/}. +It might also help to install a recent version of Fink from @uref{http://www.finkproject.org/}. -After installation use fink to download and install the following packages: -autoconf25, automake, dlcompat, m4, openssl, zlib and lzo. +You need to download and install LibreSSL (or OpenSSL) and LZO, +either directly from their websites (see @ref{Libraries}) or using Fink. @c ================================================================== @node Cygwin (Windows) build environment @subsection Cygwin (Windows) build environment If Cygwin hasn't already been installed, install it directly from -@uref{http://www.cygwin.com/}. +@uref{https://www.cygwin.com/}. When tinc is compiled in a Cygwin environment, it can only be run in this environment, but all programs, including those started outside the Cygwin environment, will be able to use the VPN. @@ -589,6 +584,7 @@ It will also support all features. @subsection MinGW (Windows) build environment You will need to install the MinGW environment from @uref{http://www.mingw.org}. +You also need to download and install LibreSSL (or OpenSSL) and LZO. When tinc is compiled using MinGW it runs natively under Windows, it is not necessary to keep MinGW installed. @@ -735,7 +731,7 @@ You will also notice that log messages it appears in syslog as coming from @file and on Linux, unless specified otherwise, the name of the virtual network interface will be the same as the network name. However, it is not strictly necessary that you call tinc with the -n -option. If you don not use it, the network name will just be empty, and +option. If you do not use it, the network name will just be empty, and tinc will look for files in @file{@value{sysconfdir}/tinc/} instead of @file{@value{sysconfdir}/tinc/@var{netname}/}; the configuration file will then be @file{@value{sysconfdir}/tinc/tinc.conf}, @@ -999,6 +995,12 @@ to start with a four byte header containing the address family, followed by an IP header. This mode should support both IPv4 and IPv6 packets. +@cindex utun +@item utun (OS X) +Set type to utun. +This is only supported on OS X version 10.6.8 and higher, but doesn't require the tuntaposx module. +This mode should support both IPv4 and IPv6 packets. + @item tap (BSD and Linux) Set type to tap. Tinc will expect packets read from the virtual network device @@ -1081,8 +1083,8 @@ This will allow direct communication using LAN addresses, even if both peers are and they only ConnectTo a third node outside the NAT, which normally would prevent the peers from learning each other's LAN address. -Currently, local discovery is implemented by sending broadcast packets to the LAN during path MTU discovery. -This feature may not work in all possible situations. +Currently, local discovery is implemented by sending some packets to the local address of the node during UDP discovery. +This will not work with old nodes that don't transmit their local address. @cindex LocalDiscoveryAddress @item LocalDiscoveryAddress <@var{address}> @@ -1139,7 +1141,7 @@ until the burst has passed. @cindex Name @item Name = <@var{name}> [required] This is a symbolic name for this connection. -The name should consist only of alfanumeric and underscore characters (a-z, A-Z, 0-9 and _), and is case sensitive. +The name must consist only of alfanumeric and underscore characters (a-z, A-Z, 0-9 and _), and is case sensitive. If Name starts with a $, then the contents of the environment variable that follows will be used. In that case, invalid characters will be converted to underscores. @@ -1207,10 +1209,10 @@ The environment variables @env{NAME}, @env{NODE}, @env{REMOTEADDRES} and @env{RE @end table @cindex ReplayWindow -@item ReplayWindow = (16) +@item ReplayWindow = (32) This is the size of the replay tracking window for each remote node, in bytes. The window is a bitfield which tracks 1 packet per bit, so for example -the default setting of 16 will track up to 128 packets in the window. In high +the default setting of 32 will track up to 256 packets in the window. In high bandwidth scenarios, setting this to a higher value can reduce packet loss from the interaction of replay tracking with underlying real packet loss and/or reordering. Setting this to zero will disable replay tracking completely and @@ -1232,15 +1234,60 @@ and will only allow connections with nodes for which host config files are prese @file{@value{sysconfdir}/tinc/@var{netname}/hosts/} directory. Setting this options also implicitly sets StrictSubnets. +@cindex UDPDiscovey +@item UDPDiscovery = (yes) +When this option is enabled tinc will try to establish UDP connectivity to nodes, +using TCP while it determines if a node is reachable over UDP. If it is disabled, +tinc always assumes a node is reachable over UDP. +Note that tinc will never use UDP with nodes that have TCPOnly enabled. + +@cindex UDPDiscoveryKeepaliveInterval +@item UDPDiscoveryKeepaliveInterval = (9) +The minimum amount of time between sending UDP ping datagrams to check UDP connectivity once it has been established. +Note that these pings are large, since they are used to verify link MTU as well. + +@cindex UDPDiscoveryInterval +@item UDPDiscoveryInterval = (2) +The minimum amount of time between sending UDP ping datagrams to try to establish UDP connectivity. + +@cindex UDPDiscoveryTimeout +@item UDPDiscoveryTimeout = (30) +If tinc doesn't receive any UDP ping replies over the specified interval, +it will assume UDP communication is broken and will fall back to TCP. + +@cindex UDPInfoInterval +@item UDPInfoInterval = (5) +The minimum amount of time between sending periodic updates about UDP addresses, which are mostly useful for UDP hole punching. + @cindex UDPRcvBuf -@item UDPRcvBuf = (OS default) +@item UDPRcvBuf = (1048576) Sets the socket receive buffer size for the UDP socket, in bytes. -If unset, the default buffer size will be used by the operating system. +If set to zero, the default buffer size will be used by the operating system. +Note: this setting can have a significant impact on performance, especially raw throughput. @cindex UDPSndBuf -@item UDPSndBuf = Pq OS default +@item UDPSndBuf = (1048576) Sets the socket send buffer size for the UDP socket, in bytes. -If unset, the default buffer size will be used by the operating system. +If set to zero, the default buffer size will be used by the operating system. +Note: this setting can have a significant impact on performance, especially raw throughput. + +@cindex UPnP +@item UPnP = (no) +If this option is enabled then tinc will search for UPnP-IGD devices on the local network. +It will then create and maintain port mappings for tinc's listening TCP and UDP ports. +If set to "udponly", tinc will only create a mapping for its UDP (data) port, not for its TCP (metaconnection) port. +Note that tinc must have been built with miniupnpc support for this feature to be available. +Furthermore, be advised that enabling this can have security implications, because the miniupnpc library that +tinc uses might not be well-hardened with regard to malicious UPnP replies. + +@cindex UPnPDiscoverWait +@item UPnPDiscoverWait = (5) +The amount of time to wait for replies when probing the local network for UPnP devices. + +@cindex UPnPRefreshPeriod +@item UPnPRefreshPeriod = (5) +How often tinc will re-add the port mapping, in case it gets reset on the UPnP device. +This also controls the duration of the port mapping itself, which will be set to twice that duration. @end table @@ -1262,7 +1309,7 @@ tried until a working connection has been established. @cindex Cipher @item Cipher = <@var{cipher}> (blowfish) The symmetric cipher algorithm used to encrypt UDP packets using the legacy protocol. -Any cipher supported by OpenSSL is recognized. +Any cipher supported by LibreSSL or OpenSSL is recognized. Furthermore, specifying "none" will turn off packet encryption. It is best to use only those ciphers which support CBC mode. This option has no effect for connections using the SPTPS protocol, which always use AES-256-CTR. @@ -1282,7 +1329,7 @@ Possible values are 0 (off), 1 (fast zlib) and any integer up to 9 (best zlib), @cindex Digest @item Digest = <@var{digest}> (sha1) The digest algorithm used to authenticate UDP packets using the legacy protocol. -Any digest supported by OpenSSL is recognized. +Any digest supported by LibreSSL or OpenSSL is recognized. Furthermore, specifying "none" will turn off packet authentication. This option has no effect for connections using the SPTPS protocol, which always use HMAC-SHA-256. @@ -1308,6 +1355,10 @@ This option controls the initial path MTU to this node. 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. +@cindex MTUInfoInterval +@item MTUInfoInterval = (5) +The minimum amount of time between sending periodic updates about relay path MTU. Useful for quickly determining MTU to indirect nodes. + @cindex Port @item Port = <@var{port}> (655) This is the port this tinc daemon listens on. @@ -1353,7 +1404,7 @@ MAC addresses are notated like 0:1a:2b:3c:4d:5e. Prefixlength is the number of bits set to 1 in the netmask part; for example: netmask 255.255.255.0 would become /24, 255.255.252.0 becomes /22. This conforms to standard CIDR notation as described in -@uref{http://www.ietf.org/rfc/rfc1519.txt, RFC1519} +@uref{https://www.ietf.org/rfc/rfc1519.txt, RFC1519} A Subnet can be given a weight to indicate its priority over identical Subnets owned by different nodes. The default weight is 10. Lower values indicate @@ -1384,6 +1435,14 @@ connection when broadcasting or forwarding packets. @cindex scripts Apart from reading the server and host configuration files, tinc can also run scripts at certain moments. +Below is a list of filenames of scripts and a description of when they are run. +A script is only run if it exists and if it is executable. + +Scripts are run synchronously; +this means that tinc will temporarily stop processing packets until the called script finishes executing. +This guarantees that scripts will execute in the exact same order as the events that trigger them. +If you need to run commands asynchronously, you have to ensure yourself that they are being run in the background. + Under Windows (not Cygwin), the scripts should have the extension @file{.bat} or @file{.cmd}. @table @file @@ -1394,6 +1453,7 @@ If it is present it will be executed right after the tinc daemon has been started and has connected to the virtual network device. It should be used to set up the corresponding network interface, but can also be used to start other things. + Under Windows you can use the Network Connections control panel instead of creating this script. @cindex tinc-down @@ -2226,6 +2286,9 @@ Use the cookie from @var{filename} to authenticate with a running tinc daemon. If unspecified, the default is @file{@value{localstatedir}/run/tinc.@var{netname}.pid}. +@item --force +Force some commands to work despite warnings. + @item --help Display a short reminder of runtime options and commands, then terminate. @@ -2272,6 +2335,7 @@ To set a variable for a specific host, use the notation @var{host}.@var{variable @cindex add @item add @var{variable} @var{value} As above, but without removing any previously existing configuration variables. +If the variable already exists with the given value, nothing happens. @cindex del @item del @var{variable} [@var{value}] @@ -2292,16 +2356,16 @@ Export the host configuration file of the local node to standard output. Export all host configuration files to standard output. @cindex import -@item import [--force] +@item import Import host configuration file(s) generated by the tinc export command from standard input. Already existing host configuration files are not overwritten unless the option --force is used. @cindex exchange -@item exchange [--force] +@item exchange The same as export followed by import. @cindex exchange-all -@item exchange-all [--force] +@item exchange-all The same as export-all followed by import. @cindex invite @@ -2373,6 +2437,10 @@ Nodes are colored according to their reachability: red nodes are unreachable, orange nodes are indirectly reachable, green nodes are directly reachable. Black nodes are either directly or indirectly reachable, but direct reachability has not been tried yet. +@item dump invitations +Dump a list of outstanding invitations. +The filename of the invitation, as well as the name of the node that is being invited is shown for each invitation. + @cindex info @item info @var{node} | @var{subnet} | @var{address} Show information about a particular @var{node}, @var{subnet} or @var{address}. @@ -2415,11 +2483,38 @@ Dump VPN traffic going through the local tinc node in pcap-savefile format to st from where it can be redirected to a file or piped through a program that can parse it directly, such as tcpdump. -@cindex network [@var{netname}] -@item network +@cindex network +@item network [@var{netname}] If @var{netname} is given, switch to that network. Otherwise, display a list of all networks for which configuration files exist. +@cindex fsck +@item fsck +This will check the configuration files for possible problems, +such as unsafe file permissions, missing executable bit on script, +unknown and obsolete configuration variables, wrong public and/or private keys, and so on. + +When problems are found, this will be printed on a line with WARNING or ERROR in front of it. +Most problems must be corrected by the user itself, however in some cases (like file permissions and missing public keys), +tinc will ask if it should fix the problem. + +@cindex sign +@item sign [@var{filename}] +Sign a file with the local node's private key. +If no @var{filename} is given, the file is read from standard input. +The signed file is written to standard output. + +@cindex verify +@item verify @var{name} [@var{filename}] + +Check the signature of a file against a node's public key. +The @var{name} of the node must be given, +or can be "." to check against the local node's public key, +or "*" to allow a signature from any node whose public key is known. +If no @var{filename} is given, the file is read from standard input. +If the verification is succesful, a copy of the input with the signature removed is written to standard output, and the exit code will be zero. +If the verification failed, nothing will be written to standard output, and the exit code will be non-zero. + @end table @c ================================================================== @@ -2506,6 +2601,159 @@ Quit. @end table +@c ================================================================== +@node Invitations +@chapter Invitations + +Invitations are an easy way to add new nodes to an existing VPN. Invitations +can be created on an existing node using the @code{tinc invite} command, which +generates a relatively short URL which can be given to someone else, who uses +the @code{tinc join} command to automatically set up tinc so it can connect to +the inviting node. The next sections describe how invitations actually work, +and how to further automate the invitations. + +@menu +* How invitations work:: +* Invitation file format:: +* Writing an invitation-created script:: +@end menu + + +@c ================================================================== +@node How invitations work +@section How invitations work + +When an invitation is created on a node (which from now on we will call the +server) using the @code{tinc invite} command, an invitation file is created +that contains all the information necessary for the invitee (which we will call +the client) to create its configuration files. The invitation file is stays on +the server, but a URL is generated that has enough information for the client +to contact the server and to retrieve the invitation file. The whole URL is +around 80 characters long and looks like this: + +@example +server.example.org:12345/cW1NhLHS-1WPFlcFio8ztYHvewTTKYZp8BjEKg3vbMtDz7w4 +@end example + +It is composed of four parts: + +@example +hostname : port / keyhash cookie +@end example + +The hostname and port tell the client how to reach the tinc daemon on the server. +The part after the slash looks like one blob, but is composed of two parts. +The keyhash is the hash of the public key of the server. +The cookie is a shared secret that identifies the client to the server. + +When the client connects to the server in order to join the VPN, the client and +server will exchange temporary public keys. The client verifies that the hash +of the server's public key matches the keyhash from the invitation URL. If +not, it will immediately exit with an error. Otherwise, an ECDH exchange will +happen so the client and server can communicate privately with each other. The +client will then present the cookie to the server. The server uses this to +look up the corresponding invitation file it generated earlier. If it exists, +it will send the invitation file to the client. The client will also create a +permanent public key, and send it to the server. After the exchange is +completed, the connection is broken. The server creates a host config file for +the client containing the client's permanent public key, and the client creates +tinc.conf, host config files and possibly a tinc-up script based on the +information in the invitation file. + +It is important that the invitation URL is kept secret until it is used; if +another person gets a copy of the invitation URL before the real client runs +the @code{tinc join} command, then that other person can try to join the VPN. + + +@c ================================================================== +@node Invitation file format +@section Invitation file format + +The contents of an invitation file that is generated by the @code{tinc invite} +command looks like this: + +@example +Name = client +Netname = vpn +ConnectTo = server +#-------------------------------------# +Name = server +Ed25519PublicKey = augbnwegoij123587... +Address = server.example.com +@end example + +The file is basically a concatenation of several host config blocks. Each host +config block starts with @code{Name = ...}. Lines that look like @code{#---#} +are not important, it just makes it easier for humans to read the file. + +The first host config block is always the one representing the invitee. So the +first Name statement determines the name that the invitee will get. From the +first block, the @file{tinc.conf} and @file{hosts/client} files will be +generated; the @code{tinc join} command on the client will automatically +separate statements based on whether they should be in @file{tinc.conf} or in a +host config file. Some statements are special and are treated differently: + +@table @asis +@item Netname = <@var{netname}> +This is a hint to the invitee which netname to use for the VPN. It is used if +the invitee did not already specify a netname, and if there is no pre-existing +configuration with the same netname. + +@cindex Ifconfig +@item Ifconfig = <@var{address}[/@var{netmask}] | dhcp | dhcp6 | slaac> +This is a hint for generating a @file{tinc-up} script. +If an address is specified, a command will be added to @file{tinc-up} so the VPN interface will be configured to have the given address. +If it is the word "dhcp", a command will be added to start a DHCP client on the VPN interface. +If it is the word dhcpv6, it will be a DHCPv6 client. +If it is "slaac", then it will add commands to enable IPv6 stateless address autoconfiguration. +It is also possible to specify a MAC address, in which case a command will be added to set the MAC address of the VPN interface. + +The exact commands added to the @file{tinc-up} script depends on the operating system the client is using. +Multiple Ifconfig statements can be specified, however one should only use one Ifconfig statement per address family. + +@cindex Route +@item Route = <@var{address}[/@var{netmask}]> [<@var{gateway}>] +This is a hint for generating a @file{tinc-up} script. +Route statements are similar to Ifconfig statements, but add routes instead of addresses. +These only allow IPv4 and IPv6 routes. +If no gateway address is specified, the route is directed to the VPN interface. +In general, a gateway is only necessary when running tinc in switch mode. +@end table + +Subsequent host config blocks are copied verbatim into their respective files +in @file{hosts/}. The invitation file generated by @code{tinc invite} will +normally only contain two blocks; one for the client and one for the server. + + +@c ================================================================== +@node Writing an invitation-created script +@section Writing an invitation-created script + +When an invitation is generated, the "invitation-created" script is called (if +it exists) right after the invitation file is written, but before the URL has +been written to stdout. This allows one to change the invitation file +automatically before the invitation URL is passed to the invitee. Here is an +example shell script that aproximately recreates the default invitation file: + +@example +#!/bin/sh + +cat >$INVITATION_FILE <>$INVITATION_FILE +@end example + +You can add more ConnectTo statements, and change `tinc export` to `tinc +export-all` for example. But you can also use the script to automatically hand +out a Subnet to the invitee. Note that the script doesn't have to be a shell script, +you can use any language, it just has to be executable. + + @c ================================================================== @node Technical information @chapter Technical information @@ -3076,7 +3324,7 @@ eavesdroppers cannot get and cannot change any information at all from the packets they can intercept. The encryption algorithm and message authentication algorithm can be changed in the configuration. The length of the message authentication codes is also adjustable. The length of the key for the -encryption algorithm is always the default length used by OpenSSL. +encryption algorithm is always the default length used by LibreSSL/OpenSSL. The SPTPS protocol is described in @ref{Simple Peer-to-Peer Security}. For comparison, this is how SPTPS UDP packets look: @@ -3103,7 +3351,7 @@ this cannot be changed. In August 2000, we discovered the existence of a security hole in all versions of tinc up to and including 1.0pre2. This had to do with the way we exchanged keys. Since then, we have been working on a new authentication scheme to make -tinc as secure as possible. The current version uses the OpenSSL library and +tinc as secure as possible. The current version uses the LibreSSL or OpenSSL library and uses strong authentication with RSA keys. On the 29th of December 2001, Jerome Etienne posted a security analysis of tinc @@ -3278,14 +3526,14 @@ Adding routes to IPv6 subnets: @section Contact information @cindex website -Tinc's website is at @url{http://www.tinc-vpn.org/}, +Tinc's website is at @url{https://www.tinc-vpn.org/}, this server is located in the Netherlands. @cindex IRC We have an IRC channel on the FreeNode and OFTC IRC networks. Connect to -@uref{http://www.freenode.net/, irc.freenode.net} +@uref{https://freenode.net/, irc.freenode.net} or -@uref{http://www.oftc.net/, irc.oftc.net} +@uref{https://www.oftc.net/, irc.oftc.net} and join channel #tinc. diff --git a/doc/tincd.8.in b/doc/tincd.8.in index 3c5886b..22c54a7 100644 --- a/doc/tincd.8.in +++ b/doc/tincd.8.in @@ -8,7 +8,7 @@ .Nd tinc VPN daemon .Sh SYNOPSIS .Nm -.Op Fl cdDKnoLRU +.Op Fl cdDKnsoLRU .Op Fl -config Ns = Ns Ar DIR .Op Fl -no-detach .Op Fl -debug Ns Op = Ns Ar LEVEL @@ -16,6 +16,7 @@ .Op Fl -option Ns = Ns Ar [HOST.]KEY=VALUE .Op Fl -mlock .Op Fl -logfile Ns Op = Ns Ar FILE +.Op Fl -syslog .Op Fl -bypass-security .Op Fl -chroot .Op Fl -user Ns = Ns Ar USER @@ -88,6 +89,8 @@ If .Ar FILE is omitted, the default is .Pa @localstatedir@/log/tinc. Ns Ar NETNAME Ns Pa .log. +.It Fl s, -syslog +When this option is is set, tinc uses syslog instead of stderr in --no-detach mode. .It Fl -pidfile Ns = Ns Ar FILENAME Store a cookie in .Ar FILENAME @@ -188,7 +191,7 @@ A lot, especially security auditing. .Sh SEE ALSO .Xr tinc 8 , .Xr tinc.conf 5 , -.Pa http://www.tinc-vpn.org/ , +.Pa https://www.tinc-vpn.org/ , .Pa http://www.cabal.org/ . .Pp The full documentation for tinc is maintained as a Texinfo manual. diff --git a/gui/Makefile.in b/gui/Makefile.in index 772b4ae..2924e05 100644 --- a/gui/Makefile.in +++ b/gui/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.14.1 from Makefile.am. +# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2013 Free Software Foundation, Inc. +# Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -15,7 +15,17 @@ @SET_MAKE@ VPATH = @srcdir@ -am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ @@ -79,18 +89,18 @@ POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = gui -DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ - $(dist_bin_SCRIPTS) ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \ $(top_srcdir)/m4/ax_check_compile_flag.m4 \ $(top_srcdir)/m4/ax_check_link_flag.m4 \ $(top_srcdir)/m4/curses.m4 $(top_srcdir)/m4/libgcrypt.m4 \ - $(top_srcdir)/m4/lzo.m4 $(top_srcdir)/m4/openssl.m4 \ - $(top_srcdir)/m4/readline.m4 $(top_srcdir)/m4/zlib.m4 \ - $(top_srcdir)/configure.ac + $(top_srcdir)/m4/lzo.m4 $(top_srcdir)/m4/miniupnpc.m4 \ + $(top_srcdir)/m4/openssl.m4 $(top_srcdir)/m4/readline.m4 \ + $(top_srcdir)/m4/zlib.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(dist_bin_SCRIPTS) \ + $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = @@ -144,6 +154,7 @@ am__can_run_installinfo = \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ @@ -178,6 +189,7 @@ LIBS = @LIBS@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ +MINIUPNPC_LIBS = @MINIUPNPC_LIBS@ MKDIR_P = @MKDIR_P@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ @@ -235,10 +247,12 @@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ +runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ +systemd_path = @systemd_path@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ @@ -260,7 +274,6 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu gui/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu gui/Makefile -.PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ @@ -483,6 +496,8 @@ uninstall-am: uninstall-dist_binSCRIPTS pdf-am ps ps-am tags-am uninstall uninstall-am \ uninstall-dist_binSCRIPTS +.PRECIOUS: Makefile + # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. diff --git a/gui/tinc-gui b/gui/tinc-gui index 0a6370a..65e8b14 100755 --- a/gui/tinc-gui +++ b/gui/tinc-gui @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python2 # tinc-gui -- GUI for controlling a running tincd # Copyright (C) 2009-2014 Guus Sliepen @@ -20,19 +20,19 @@ import string import socket -import wx -import sys import os import platform import time +from argparse import ArgumentParser + +import wx from wx.lib.mixins.listctrl import ColumnSorterMixin from wx.lib.mixins.listctrl import ListCtrlAutoWidthMixin if platform.system() == 'Windows': - import _winreg + import _winreg # Classes to interface with a running tinc daemon - REQ_STOP = 0 REQ_RELOAD = 1 REQ_RESTART = 2 @@ -51,272 +51,247 @@ ID = 0 ACK = 4 CONTROL = 18 -class Node: - def parse(self, args): - self.name = args[0] - self.address = args[1] - self.port = args[3] - self.cipher = int(args[4]) - self.digest = int(args[5]) - self.maclength = int(args[6]) - self.compression = int(args[7]) - self.options = int(args[8], 0x10) - self.status = int(args[9], 0x10) - self.nexthop = args[10] - self.via = args[11] - self.distance = int(args[12]) - self.pmtu = int(args[13]) - self.minmtu = int(args[14]) - self.maxmtu = int(args[15]) - self.last_state_change = float(args[16]) - self.subnets = {} +class Node(object): + def __init__(self, args): + self.name = args[0] + self.id = args[1] -class Edge: - def parse(self, args): - self.fr = args[0] - self.to = args[1] - self.address = args[2] - self.port = args[4] - self.options = int(args[-2], 16) - self.weight = int(args[-1]) + self.address = args[2] + self.port = args[4] -class Subnet: - def parse(self, args): - if args[0].find('#') >= 0: - (address, self.weight) = args[0].split('#', 1) - else: - self.weight = 10 - address = args[0] + self.cipher = int(args[5]) + self.digest = int(args[6]) + self.maclength = int(args[7]) - if address.find('/') >= 0: - (self.address, self.prefixlen) = address.split('/', 1) - else: - self.address = address - self.prefixlen = '48' + self.compression = int(args[8]) + self.options = int(args[9], 0x10) + self.status = int(args[10], 0x10) - self.owner = args[1] + self.nexthop = args[11] + self.via = args[12] + self.distance = int(args[13]) + self.pmtu = int(args[14]) + self.minmtu = int(args[15]) + self.maxmtu = int(args[16]) -class Connection: - def parse(self, args): - self.name = args[0] - self.address = args[1] - self.port = args[3] - self.options = int(args[4], 0x10) - self.socket = int(args[5]) - self.status = int(args[6], 0x10) - self.weight = 123 + self.last_state_change = float(args[17]) -class VPN: - confdir = '/etc/tinc' - piddir = '/var/run/' + self.subnets = {} - def connect(self): - # read the pidfile - f = open(self.pidfile) - info = string.split(f.readline()) - f.close() - # check if there is a UNIX socket as well - if self.pidfile.endswith(".pid"): - unixfile = self.pidfile.replace(".pid", ".socket"); - else: - unixfile = self.pidfile + ".socket"; +class Edge(object): + def __init__(self, args): + self.source = args[0] + self.sink = args[1] - if os.path.exists(unixfile): - # use it if it exists - print(unixfile + " exists!"); - s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) - s.connect(unixfile) - else: - # otherwise connect via TCP - print(unixfile + " does not exist."); - if ':' in info[2]: - af = socket.AF_INET6 - else: - af = socket.AF_INET - s = socket.socket(af, socket.SOCK_STREAM) - s.connect((info[2], int(info[4]))) + self.address = args[2] + self.port = args[4] - self.sf = s.makefile() - s.close() - hello = string.split(self.sf.readline()) - self.name = hello[1] - self.sf.write('0 ^' + info[1] + ' 17\r\n') - self.sf.flush() - resp = string.split(self.sf.readline()) - self.port = info[4] - self.nodes = {} - self.edges = {} - self.subnets = {} - self.connections = {} - self.refresh() + self.options = int(args[-2], 16) + self.weight = int(args[-1]) - def refresh(self): - self.sf.write('18 3\r\n18 4\r\n18 5\r\n18 6\r\n') - self.sf.flush() - for node in self.nodes.values(): - node.visited = False - for edge in self.edges.values(): - edge.visited = False - for subnet in self.subnets.values(): - subnet.visited = False - for connections in self.connections.values(): - connections.visited = False +class Subnet(object): + def __init__(self, args): + if args[0].find('#') >= 0: + address, self.weight = args[0].split('#', 1) + else: + self.weight = 10 + address = args[0] - while True: - resp = string.split(self.sf.readline()) - if len(resp) < 2: - break - if resp[0] != '18': - break - if resp[1] == '3': - if len(resp) < 19: - continue - node = self.nodes.get(resp[2]) or Node() - node.parse(resp[2:]) - node.visited = True - self.nodes[resp[2]] = node - elif resp[1] == '4': - if len(resp) < 9: - continue - edge = self.nodes.get((resp[2], resp[3])) or Edge() - edge.parse(resp[2:]) - edge.visited = True - self.edges[(resp[2], resp[3])] = edge - elif resp[1] == '5': - if len(resp) < 4: - continue - subnet = self.subnets.get((resp[2], resp[3])) or Subnet() - subnet.parse(resp[2:]) - subnet.visited = True - self.subnets[(resp[2], resp[3])] = subnet - if subnet.owner == "(broadcast)": - continue - self.nodes[subnet.owner].subnets[resp[2]] = subnet - elif resp[1] == '6': - if len(resp) < 9: - break - connection = self.connections.get((resp[2], resp[3], resp[5])) or Connection() - connection.parse(resp[2:]) - connection.visited = True - self.connections[(resp[2], resp[3], resp[5])] = connection - else: - break + if address.find('/') >= 0: + self.address, self.prefixlen = address.split('/', 1) + else: + self.address = address + self.prefixlen = '48' - for key, subnet in self.subnets.items(): - if not subnet.visited: - del self.subnets[key] + self.owner = args[1] - for key, edge in self.edges.items(): - if not edge.visited: - del self.edges[key] - for key, node in self.nodes.items(): - if not node.visited: - del self.nodes[key] - else: - for key, subnet in node.subnets.items(): - if not subnet.visited: - del node.subnets[key] +class Connection(object): + def __init__(self, args): + self.name = args[0] - for key, connection in self.connections.items(): - if not connection.visited: - del self.connections[key] + self.address = args[1] + self.port = args[3] - def close(self): - self.sf.close() + self.options = int(args[4], 0x10) + self.socket = int(args[5]) + self.status = int(args[6], 0x10) - def disconnect(self, name): - self.sf.write('18 12 ' + name + '\r\n') - self.sf.flush() - resp = string.split(self.sf.readline()) + self.weight = 'n/a' - def debug(self, level = -1): - self.sf.write('18 9 ' + str(level) + '\r\n') - self.sf.flush() - resp = string.split(self.sf.readline()) - return int(resp[2]) - def __init__(self, netname = None, pidfile = None): - if platform.system() == 'Windows': - sam = _winreg.KEY_READ - if platform.machine().endswith('64'): - sam = sam | _winreg.KEY_WOW64_64KEY - try: - reg = _winreg.ConnectRegistry(None, _winreg.HKEY_LOCAL_MACHINE) - try: - key = _winreg.OpenKey(reg, "SOFTWARE\\tinc", 0, sam) - except WindowsError: - key = _winreg.OpenKey(reg, "SOFTWARE\\Wow6432Node\\tinc", 0, sam) - VPN.confdir = _winreg.QueryValue(key, None) - except WindowsError: - pass +class VPN(object): + def __init__(self, netname=None, pidfile=None, confdir='/etc/tinc', piddir='/run'): + if platform.system() == 'Windows': + sam = _winreg.KEY_READ + if platform.machine().endswith('64'): + sam = sam | _winreg.KEY_WOW64_64KEY + try: + reg = _winreg.ConnectRegistry(None, _winreg.HKEY_LOCAL_MACHINE) + try: + key = _winreg.OpenKey(reg, "SOFTWARE\\tinc", 0, sam) + except WindowsError: + key = _winreg.OpenKey(reg, "SOFTWARE\\Wow6432Node\\tinc", 0, sam) + confdir = _winreg.QueryValue(key, None) + except WindowsError: + pass - if netname: - self.netname = netname - self.confbase = os.path.join(VPN.confdir, netname) - else: - self.confbase = VPN.confdir + if netname: + self.netname = netname + self.confbase = os.path.join(confdir, netname) + else: + self.confbase = confdir - self.tincconf = os.path.join(self.confbase, 'tinc.conf') + self.tincconf = os.path.join(self.confbase, 'tinc.conf') - if pidfile != None: - self.pidfile = pidfile - else: - if platform.system() == 'Windows': - self.pidfile = os.path.join(self.confbase, 'pid') - else: - if netname: - self.pidfile = os.path.join(VPN.piddir, 'tinc.' + netname + '.pid') - else: - self.pidfile = os.path.join(VPN.piddir, 'tinc.pid') + if pidfile is not None: + self.pidfile = pidfile + else: + if platform.system() == 'Windows': + self.pidfile = os.path.join(self.confbase, 'pid') + else: + if netname: + self.pidfile = os.path.join(piddir, 'tinc.' + netname + '.pid') + else: + self.pidfile = os.path.join(piddir, 'tinc.pid') -# GUI starts here + self.sf = None + self.name = None + self.port = None + self.nodes = {} + self.edges = {} + self.subnets = {} + self.connections = {} -argv0 = sys.argv[0] -del sys.argv[0] -netname = None -pidfile = None + def connect(self): + # read the pidfile + f = open(self.pidfile) + info = string.split(f.readline()) + f.close() -def usage(exitcode = 0): - print('Usage: ' + argv0 + ' [options]') - print('\nValid options are:') - print(' -n, --net=NETNAME Connect to net NETNAME.') - print(' --pidfile=FILENAME Read control cookie from FILENAME.') - print(' --help Display this help and exit.') - print('\nReport bugs to tinc@tinc-vpn.org.') - sys.exit(exitcode) + # check if there is a UNIX socket as well + if self.pidfile.endswith('.pid'): + unixfile = self.pidfile.replace('.pid', '.socket'); + else: + unixfile = self.pidfile + '.socket'; -while sys.argv: - if sys.argv[0] in ('-n', '--net'): - del sys.argv[0] - netname = sys.argv[0] - elif sys.argv[0] in ('--pidfile'): - del sys.argv[0] - pidfile = sys.argv[0] - elif sys.argv[0] in ('--help'): - usage(0) - else: - print(argv0 + ': unrecognized option \'' + sys.argv[0] + '\'') - usage(1) + if os.path.exists(unixfile): + # use it if it exists + print(unixfile + " exists!"); + s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) + s.connect(unixfile) + else: + # otherwise connect via TCP + print(unixfile + " does not exist."); + if ':' in info[2]: + af = socket.AF_INET6 + else: + af = socket.AF_INET + s = socket.socket(af, socket.SOCK_STREAM) + s.connect((info[2], int(info[4]))) - del sys.argv[0] + self.sf = s.makefile() + s.close() + hello = string.split(self.sf.readline()) + self.name = hello[1] + self.sf.write('0 ^' + info[1] + ' 17\r\n') + self.sf.flush() + resp = string.split(self.sf.readline()) + self.port = info[4] + self.refresh() -if netname == None: - netname = os.getenv("NETNAME") + def refresh(self): + for request in (REQ_DUMP_NODES, REQ_DUMP_EDGES, REQ_DUMP_SUBNETS, REQ_DUMP_CONNECTIONS): + self.sf.write('{} {}\r\n'.format(CONTROL, request)) + self.sf.flush() -if netname == ".": - netname = None + for node in self.nodes.values(): + node.visited = False + for edge in self.edges.values(): + edge.visited = False + for subnet in self.subnets.values(): + subnet.visited = False + for connections in self.connections.values(): + connections.visited = False + + while True: + resp = string.split(self.sf.readline()) + if len(resp) < 2: + break + if resp[0] != '18': + break + if resp[1] == '3': + if len(resp) < 19: + continue + node = self.nodes.get(resp[2]) or Node(resp[2:]) + node.visited = True + self.nodes[resp[2]] = node + elif resp[1] == '4': + if len(resp) < 9: + continue + edge = self.nodes.get((resp[2], resp[3])) or Edge(resp[2:]) + edge.visited = True + self.edges[(resp[2], resp[3])] = edge + elif resp[1] == '5': + if len(resp) < 4: + continue + subnet = self.subnets.get((resp[2], resp[3])) or Subnet(resp[2:]) + subnet.visited = True + self.subnets[(resp[2], resp[3])] = subnet + if subnet.owner == "(broadcast)": + continue + self.nodes[subnet.owner].subnets[resp[2]] = subnet + elif resp[1] == '6': + if len(resp) < 9: + break + connection = self.connections.get((resp[2], resp[3], resp[5])) or Connection(resp[2:]) + connection.visited = True + self.connections[(resp[2], resp[3], resp[5])] = connection + else: + break + + for key, subnet in self.subnets.items(): + if not subnet.visited: + del self.subnets[key] + + for key, edge in self.edges.items(): + if not edge.visited: + del self.edges[key] + + for key, node in self.nodes.items(): + if not node.visited: + del self.nodes[key] + else: + for key, subnet in node.subnets.items(): + if not subnet.visited: + del node.subnets[key] + + for key, connection in self.connections.items(): + if not connection.visited: + del self.connections[key] + + def close(self): + self.sf.close() + + def disconnect(self, name): + self.sf.write('18 12 ' + name + '\r\n') + self.sf.flush() + resp = string.split(self.sf.readline()) + + def debug(self, level=-1): + self.sf.write('18 9 ' + str(level) + '\r\n') + self.sf.flush() + resp = string.split(self.sf.readline()) + return int(resp[2]) -vpn = VPN(netname, pidfile) -vpn.connect() class SuperListCtrl(wx.ListCtrl, ColumnSorterMixin, ListCtrlAutoWidthMixin): def __init__(self, parent, style): wx.ListCtrl.__init__(self, parent, -1, style=wx.LC_REPORT | wx.LC_HRULES | wx.LC_VRULES) - ListCtrlAutoWidthMixin.__init__(self) + ListCtrlAutoWidthMixin.__init__(self) ColumnSorterMixin.__init__(self, 16) def GetListCtrl(self): @@ -324,299 +299,336 @@ class SuperListCtrl(wx.ListCtrl, ColumnSorterMixin, ListCtrlAutoWidthMixin): class SettingsPage(wx.Panel): - def OnDebugLevel(self, event): - vpn.debug(self.debug.GetValue()) + def on_debug_level(self, event): + vpn.debug(self.debug.GetValue()) - def __init__(self, parent, id): - wx.Panel.__init__(self, parent, id) - grid = wx.FlexGridSizer(cols = 2) - grid.AddGrowableCol(1, 1) + def __init__(self, parent, id): + wx.Panel.__init__(self, parent, id) + grid = wx.FlexGridSizer(cols=2) + grid.AddGrowableCol(1, 1) - namelabel = wx.StaticText(self, -1, 'Name:') - self.name = wx.TextCtrl(self, -1, vpn.name) - grid.Add(namelabel) - grid.Add(self.name, 1, wx.EXPAND) + namelabel = wx.StaticText(self, -1, 'Name:') + self.name = wx.TextCtrl(self, -1, vpn.name) + grid.Add(namelabel) + grid.Add(self.name, 1, wx.EXPAND) - portlabel = wx.StaticText(self, -1, 'Port:') - self.port = wx.TextCtrl(self, -1, vpn.port) - grid.Add(portlabel) - grid.Add(self.port) + portlabel = wx.StaticText(self, -1, 'Port:') + self.port = wx.TextCtrl(self, -1, vpn.port) + grid.Add(portlabel) + grid.Add(self.port) - debuglabel = wx.StaticText(self, -1, 'Debug level:') - self.debug = wx.SpinCtrl(self, min = 0, max = 5, initial = vpn.debug()) - self.debug.Bind(wx.EVT_SPINCTRL, self.OnDebugLevel) - grid.Add(debuglabel) - grid.Add(self.debug) + debuglabel = wx.StaticText(self, -1, 'Debug level:') + self.debug = wx.SpinCtrl(self, min=0, max=5, initial=vpn.debug()) + self.debug.Bind(wx.EVT_SPINCTRL, self.on_debug_level) + grid.Add(debuglabel) + grid.Add(self.debug) - modelabel = wx.StaticText(self, -1, 'Mode:') - self.mode = wx.ComboBox(self, -1, style = wx.CB_READONLY, value = 'Router', choices = ['Router', 'Switch', 'Hub']) - grid.Add(modelabel) - grid.Add(self.mode) + modelabel = wx.StaticText(self, -1, 'Mode:') + self.mode = wx.ComboBox(self, -1, style=wx.CB_READONLY, value='Router', choices=['Router', 'Switch', 'Hub']) + grid.Add(modelabel) + grid.Add(self.mode) + + self.SetSizer(grid) - self.SetSizer(grid) class ConnectionsPage(wx.Panel): - def __init__(self, parent, id): - wx.Panel.__init__(self, parent, id) - self.list = SuperListCtrl(self, id) - self.list.InsertColumn(0, 'Name') - self.list.InsertColumn(1, 'Address') - self.list.InsertColumn(2, 'Port') - self.list.InsertColumn(3, 'Options') - self.list.InsertColumn(4, 'Weight') + def __init__(self, parent, id): + wx.Panel.__init__(self, parent, id) + self.list = SuperListCtrl(self, id) + self.list.InsertColumn(0, 'Name') + self.list.InsertColumn(1, 'Address') + self.list.InsertColumn(2, 'Port') + self.list.InsertColumn(3, 'Options') + self.list.InsertColumn(4, 'Weight') - hbox = wx.BoxSizer(wx.HORIZONTAL) - hbox.Add(self.list, 1, wx.EXPAND) - self.SetSizer(hbox) - self.refresh() + hbox = wx.BoxSizer(wx.HORIZONTAL) + hbox.Add(self.list, 1, wx.EXPAND) + self.SetSizer(hbox) + self.refresh() - class ContextMenu(wx.Menu): - def __init__(self, item): - wx.Menu.__init__(self) + class ContextMenu(wx.Menu): + def __init__(self, item): + wx.Menu.__init__(self) - self.item = item + self.item = item - disconnect = wx.MenuItem(self, -1, 'Disconnect') - self.AppendItem(disconnect) - self.Bind(wx.EVT_MENU, self.OnDisconnect, id=disconnect.GetId()) + disconnect = wx.MenuItem(self, -1, 'Disconnect') + self.AppendItem(disconnect) + self.Bind(wx.EVT_MENU, self.on_disconnect, id=disconnect.GetId()) - def OnDisconnect(self, event): - vpn.disconnect(self.item[0]) + def on_disconnect(self, event): + vpn.disconnect(self.item[0]) - def OnContext(self, event): - i = event.GetIndex() - self.PopupMenu(self.ContextMenu(self.list.itemDataMap[event.GetIndex()]), event.GetPosition()) + def on_context(self, event): + idx = event.GetIndex() + self.PopupMenu(self.ContextMenu(self.list.itemDataMap[event.GetIndex()]), event.GetPosition()) - def refresh(self): - sortstate = self.list.GetSortState() - self.list.itemDataMap = {} - i = 0 + def refresh(self): + sortstate = self.list.GetSortState() + self.list.itemDataMap = {} + i = 0 - for key, connection in vpn.connections.items(): - if self.list.GetItemCount() <= i: - self.list.InsertStringItem(i, connection.name) - else: - self.list.SetStringItem(i, 0, connection.name) - self.list.SetStringItem(i, 1, connection.address) - self.list.SetStringItem(i, 2, connection.port) - self.list.SetStringItem(i, 3, str(connection.options)) - self.list.SetStringItem(i, 4, str(connection.weight)) - self.list.itemDataMap[i] = (connection.name, connection.address, connection.port, connection.options, connection.weight) - self.list.Bind(wx.EVT_LIST_ITEM_RIGHT_CLICK, self.OnContext) - self.list.SetItemData(i, i) - i += 1 + for key, connection in vpn.connections.items(): + if self.list.GetItemCount() <= i: + self.list.InsertStringItem(i, connection.name) + else: + self.list.SetStringItem(i, 0, connection.name) + self.list.SetStringItem(i, 1, connection.address) + self.list.SetStringItem(i, 2, connection.port) + self.list.SetStringItem(i, 3, str(connection.options)) + self.list.SetStringItem(i, 4, str(connection.weight)) + self.list.itemDataMap[i] = (connection.name, connection.address, connection.port, connection.options, + connection.weight) + self.list.Bind(wx.EVT_LIST_ITEM_RIGHT_CLICK, self.on_context) + self.list.SetItemData(i, i) + i += 1 - while self.list.GetItemCount() > i: - self.list.DeleteItem(self.list.GetItemCount() - 1) + while self.list.GetItemCount() > i: + self.list.DeleteItem(self.list.GetItemCount() - 1) + + self.list.SortListItems(sortstate[0], sortstate[1]) - self.list.SortListItems(sortstate[0], sortstate[1]) class NodesPage(wx.Panel): - def __init__(self, parent, id): - wx.Panel.__init__(self, parent, id) - self.list = SuperListCtrl(self, id) - self.list.InsertColumn( 0, 'Name') - self.list.InsertColumn( 1, 'Address') - self.list.InsertColumn( 2, 'Port') - self.list.InsertColumn( 3, 'Cipher') - self.list.InsertColumn( 4, 'Digest') - self.list.InsertColumn( 5, 'MACLength') - self.list.InsertColumn( 6, 'Compression') - self.list.InsertColumn( 7, 'Options') - self.list.InsertColumn( 8, 'Status') - self.list.InsertColumn( 9, 'Nexthop') - self.list.InsertColumn(10, 'Via') - self.list.InsertColumn(11, 'Distance') - self.list.InsertColumn(12, 'PMTU') - self.list.InsertColumn(13, 'Min MTU') - self.list.InsertColumn(14, 'Max MTU') - self.list.InsertColumn(15, 'Since') + def __init__(self, parent, id): + wx.Panel.__init__(self, parent, id) + self.list = SuperListCtrl(self, id) + self.list.InsertColumn(0, 'Name') + self.list.InsertColumn(1, 'Address') + self.list.InsertColumn(2, 'Port') + self.list.InsertColumn(3, 'Cipher') + self.list.InsertColumn(4, 'Digest') + self.list.InsertColumn(5, 'MACLength') + self.list.InsertColumn(6, 'Compression') + self.list.InsertColumn(7, 'Options') + self.list.InsertColumn(8, 'Status') + self.list.InsertColumn(9, 'Nexthop') + self.list.InsertColumn(10, 'Via') + self.list.InsertColumn(11, 'Distance') + self.list.InsertColumn(12, 'PMTU') + self.list.InsertColumn(13, 'Min MTU') + self.list.InsertColumn(14, 'Max MTU') + self.list.InsertColumn(15, 'Since') - hbox = wx.BoxSizer(wx.HORIZONTAL) - hbox.Add(self.list, 1, wx.EXPAND) - self.SetSizer(hbox) - self.refresh() + hbox = wx.BoxSizer(wx.HORIZONTAL) + hbox.Add(self.list, 1, wx.EXPAND) + self.SetSizer(hbox) + self.refresh() - def refresh(self): - sortstate = self.list.GetSortState() - self.list.itemDataMap = {} - i = 0 + def refresh(self): + sortstate = self.list.GetSortState() + self.list.itemDataMap = {} + i = 0 - for key, node in vpn.nodes.items(): - if self.list.GetItemCount() <= i: - self.list.InsertStringItem(i, node.name) - else: - self.list.SetStringItem(i, 0, node.name) - self.list.SetStringItem(i, 1, node.address) - self.list.SetStringItem(i, 2, node.port) - self.list.SetStringItem(i, 3, str(node.cipher)) - self.list.SetStringItem(i, 4, str(node.digest)) - self.list.SetStringItem(i, 5, str(node.maclength)) - self.list.SetStringItem(i, 6, str(node.compression)) - self.list.SetStringItem(i, 7, format(node.options, "x")) - self.list.SetStringItem(i, 8, format(node.status, "04x")) - self.list.SetStringItem(i, 9, node.nexthop) - self.list.SetStringItem(i, 10, node.via) - self.list.SetStringItem(i, 11, str(node.distance)) - self.list.SetStringItem(i, 12, str(node.pmtu)) - self.list.SetStringItem(i, 13, str(node.minmtu)) - self.list.SetStringItem(i, 14, str(node.maxmtu)) - if node.last_state_change: - since = time.strftime("%Y-%m-%d %H:%M", time.localtime(node.last_state_change)) - else: - since = "never" - self.list.SetStringItem(i, 15, since) - self.list.itemDataMap[i] = (node.name, node.address, node.port, node.cipher, node.digest, node.maclength, node.compression, node.options, node.status, node.nexthop, node.via, node.distance, node.pmtu, node.minmtu, node.maxmtu, since) - self.list.SetItemData(i, i) - i += 1 + for key, node in vpn.nodes.items(): + if self.list.GetItemCount() <= i: + self.list.InsertStringItem(i, node.name) + else: + self.list.SetStringItem(i, 0, node.name) + self.list.SetStringItem(i, 1, node.address) + self.list.SetStringItem(i, 2, node.port) + self.list.SetStringItem(i, 3, str(node.cipher)) + self.list.SetStringItem(i, 4, str(node.digest)) + self.list.SetStringItem(i, 5, str(node.maclength)) + self.list.SetStringItem(i, 6, str(node.compression)) + self.list.SetStringItem(i, 7, format(node.options, "x")) + self.list.SetStringItem(i, 8, format(node.status, "04x")) + self.list.SetStringItem(i, 9, node.nexthop) + self.list.SetStringItem(i, 10, node.via) + self.list.SetStringItem(i, 11, str(node.distance)) + self.list.SetStringItem(i, 12, str(node.pmtu)) + self.list.SetStringItem(i, 13, str(node.minmtu)) + self.list.SetStringItem(i, 14, str(node.maxmtu)) + if node.last_state_change: + since = time.strftime("%Y-%m-%d %H:%M", time.localtime(node.last_state_change)) + else: + since = "never" + self.list.SetStringItem(i, 15, since) + self.list.itemDataMap[i] = (node.name, node.address, node.port, node.cipher, node.digest, node.maclength, + node.compression, node.options, node.status, node.nexthop, node.via, + node.distance, node.pmtu, node.minmtu, node.maxmtu, since) + self.list.SetItemData(i, i) + i += 1 - while self.list.GetItemCount() > i: - self.list.DeleteItem(self.list.GetItemCount() - 1) + while self.list.GetItemCount() > i: + self.list.DeleteItem(self.list.GetItemCount() - 1) + + self.list.SortListItems(sortstate[0], sortstate[1]) - self.list.SortListItems(sortstate[0], sortstate[1]) class EdgesPage(wx.Panel): - def __init__(self, parent, id): - wx.Panel.__init__(self, parent, id) - self.list = SuperListCtrl(self, id) - self.list.InsertColumn(0, 'From') - self.list.InsertColumn(1, 'To') - self.list.InsertColumn(2, 'Address') - self.list.InsertColumn(3, 'Port') - self.list.InsertColumn(4, 'Options') - self.list.InsertColumn(5, 'Weight') + def __init__(self, parent, id): + wx.Panel.__init__(self, parent, id) + self.list = SuperListCtrl(self, id) + self.list.InsertColumn(0, 'From') + self.list.InsertColumn(1, 'To') + self.list.InsertColumn(2, 'Address') + self.list.InsertColumn(3, 'Port') + self.list.InsertColumn(4, 'Options') + self.list.InsertColumn(5, 'Weight') - hbox = wx.BoxSizer(wx.HORIZONTAL) - hbox.Add(self.list, 1, wx.EXPAND) - self.SetSizer(hbox) - self.refresh() + hbox = wx.BoxSizer(wx.HORIZONTAL) + hbox.Add(self.list, 1, wx.EXPAND) + self.SetSizer(hbox) + self.refresh() - def refresh(self): - sortstate = self.list.GetSortState() - self.list.itemDataMap = {} - i = 0 + def refresh(self): + sortstate = self.list.GetSortState() + self.list.itemDataMap = {} + i = 0 - for key, edge in vpn.edges.items(): - if self.list.GetItemCount() <= i: - self.list.InsertStringItem(i, edge.fr) - else: - self.list.SetStringItem(i, 0, edge.fr) - self.list.SetStringItem(i, 1, edge.to) - self.list.SetStringItem(i, 2, edge.address) - self.list.SetStringItem(i, 3, edge.port) - self.list.SetStringItem(i, 4, format(edge.options, "x")) - self.list.SetStringItem(i, 5, str(edge.weight)) - self.list.itemDataMap[i] = (edge.fr, edge.to, edge.address, edge.port, edge.options, edge.weight) - self.list.SetItemData(i, i) - i += 1 + for key, edge in vpn.edges.items(): + if self.list.GetItemCount() <= i: + self.list.InsertStringItem(i, edge.source) + else: + self.list.SetStringItem(i, 0, edge.source) + self.list.SetStringItem(i, 1, edge.sink) + self.list.SetStringItem(i, 2, edge.address) + self.list.SetStringItem(i, 3, edge.port) + self.list.SetStringItem(i, 4, format(edge.options, "x")) + self.list.SetStringItem(i, 5, str(edge.weight)) + self.list.itemDataMap[i] = (edge.source, edge.sink, edge.address, edge.port, edge.options, edge.weight) + self.list.SetItemData(i, i) + i += 1 - while self.list.GetItemCount() > i: - self.list.DeleteItem(self.list.GetItemCount() - 1) + while self.list.GetItemCount() > i: + self.list.DeleteItem(self.list.GetItemCount() - 1) + + self.list.SortListItems(sortstate[0], sortstate[1]) - self.list.SortListItems(sortstate[0], sortstate[1]) class SubnetsPage(wx.Panel): - def __init__(self, parent, id): - wx.Panel.__init__(self, parent, id) - self.list = SuperListCtrl(self, id) - self.list.InsertColumn(0, 'Subnet', wx.LIST_FORMAT_RIGHT) - self.list.InsertColumn(1, 'Weight', wx.LIST_FORMAT_RIGHT) - self.list.InsertColumn(2, 'Owner') - hbox = wx.BoxSizer(wx.HORIZONTAL) - hbox.Add(self.list, 1, wx.EXPAND) - self.SetSizer(hbox) - self.refresh() + def __init__(self, parent, id): + wx.Panel.__init__(self, parent, id) + self.list = SuperListCtrl(self, id) + self.list.InsertColumn(0, 'Subnet', wx.LIST_FORMAT_RIGHT) + self.list.InsertColumn(1, 'Weight', wx.LIST_FORMAT_RIGHT) + self.list.InsertColumn(2, 'Owner') + hbox = wx.BoxSizer(wx.HORIZONTAL) + hbox.Add(self.list, 1, wx.EXPAND) + self.SetSizer(hbox) + self.refresh() - def refresh(self): - sortstate = self.list.GetSortState() - self.list.itemDataMap = {} - i = 0 + def refresh(self): + sortstate = self.list.GetSortState() + self.list.itemDataMap = {} + i = 0 - for key, subnet in vpn.subnets.items(): - if self.list.GetItemCount() <= i: - self.list.InsertStringItem(i, subnet.address + '/' + subnet.prefixlen) - else: - self.list.SetStringItem(i, 0, subnet.address + '/' + subnet.prefixlen) - self.list.SetStringItem(i, 1, str(subnet.weight)) - self.list.SetStringItem(i, 2, subnet.owner) - self.list.itemDataMap[i] = (subnet.address + '/' + subnet.prefixlen, subnet.weight, subnet.owner) - self.list.SetItemData(i, i) - i += 1 + for key, subnet in vpn.subnets.items(): + if self.list.GetItemCount() <= i: + self.list.InsertStringItem(i, subnet.address + '/' + subnet.prefixlen) + else: + self.list.SetStringItem(i, 0, subnet.address + '/' + subnet.prefixlen) + self.list.SetStringItem(i, 1, str(subnet.weight)) + self.list.SetStringItem(i, 2, subnet.owner) + self.list.itemDataMap[i] = (subnet.address + '/' + subnet.prefixlen, subnet.weight, subnet.owner) + self.list.SetItemData(i, i) + i += 1 - while self.list.GetItemCount() > i: - self.list.DeleteItem(self.list.GetItemCount() - 1) + while self.list.GetItemCount() > i: + self.list.DeleteItem(self.list.GetItemCount() - 1) + + self.list.SortListItems(sortstate[0], sortstate[1]) - self.list.SortListItems(sortstate[0], sortstate[1]) class StatusPage(wx.Panel): - def __init__(self, parent, id): - wx.Panel.__init__(self, parent, id) + def __init__(self, parent, id): + wx.Panel.__init__(self, parent, id) + class GraphPage(wx.Window): - def __init__(self, parent, id): - wx.Window.__init__(self, parent, id) + def __init__(self, parent, id): + wx.Window.__init__(self, parent, id) + class NetPage(wx.Notebook): - def __init__(self, parent, id): - wx.Notebook.__init__(self, parent) - self.settings = SettingsPage(self, id) - self.connections = ConnectionsPage(self, id) - self.nodes = NodesPage(self, id) - self.edges = EdgesPage(self, id) - self.subnets = SubnetsPage(self, id) - self.graph = GraphPage(self, id) - self.status = StatusPage(self, id) + def __init__(self, parent, id): + wx.Notebook.__init__(self, parent) + self.settings = SettingsPage(self, id) + self.connections = ConnectionsPage(self, id) + self.nodes = NodesPage(self, id) + self.edges = EdgesPage(self, id) + self.subnets = SubnetsPage(self, id) + self.graph = GraphPage(self, id) + self.status = StatusPage(self, id) + + self.AddPage(self.settings, 'Settings') + # self.AddPage(self.status, 'Status') + self.AddPage(self.connections, 'Connections') + self.AddPage(self.nodes, 'Nodes') + self.AddPage(self.edges, 'Edges') + self.AddPage(self.subnets, 'Subnets') + + # self.AddPage(self.graph, 'Graph') - self.AddPage(self.settings, 'Settings') - #self.AddPage(self.status, 'Status') - self.AddPage(self.connections, 'Connections') - self.AddPage(self.nodes, 'Nodes') - self.AddPage(self.edges, 'Edges') - self.AddPage(self.subnets, 'Subnets') - #self.AddPage(self.graph, 'Graph') - class MainWindow(wx.Frame): - def OnQuit(self, event): - app.ExitMainLoop() + def __init__(self, parent, id, title): + wx.Frame.__init__(self, parent, id, title) - def OnTimer(self, event): - vpn.refresh() - self.np.nodes.refresh() - self.np.subnets.refresh() - self.np.edges.refresh() - self.np.connections.refresh() + menubar = wx.MenuBar() - def __init__(self, parent, id, title): - wx.Frame.__init__(self, parent, id, title) + menu = wx.Menu() + menu.Append(1, '&Quit\tCtrl-X', 'Quit tinc GUI') + menubar.Append(menu, '&File') - menubar = wx.MenuBar() - file = wx.Menu() - file.Append(1, '&Quit\tCtrl-X', 'Quit tinc GUI') - menubar.Append(file, '&File') + # nb = wx.Notebook(self, -1) + # nb.SetPadding((0, 0)) + self.np = NetPage(self, -1) + # nb.AddPage(np, 'VPN') - #nb = wx.Notebook(self, -1) - #nb.SetPadding((0, 0)) - self.np = NetPage(self, -1) - #nb.AddPage(np, 'VPN') - - self.timer = wx.Timer(self, -1) - self.Bind(wx.EVT_TIMER, self.OnTimer, self.timer) - self.timer.Start(1000) - self.Bind(wx.EVT_MENU, self.OnQuit, id=1) - self.SetMenuBar(menubar) - self.Show() + self.timer = wx.Timer(self, -1) + self.Bind(wx.EVT_TIMER, self.on_timer, self.timer) + self.timer.Start(1000) + self.Bind(wx.EVT_MENU, self.on_quit, id=1) + self.SetMenuBar(menubar) + self.Show() -app = wx.App() -mw = MainWindow(None, -1, 'Tinc GUI') + def on_quit(self, event): + app.ExitMainLoop() -#def OnTaskBarIcon(event): -# mw.Raise() -# -#icon = wx.Icon("tincgui.ico", wx.BITMAP_TYPE_PNG) -#taskbaricon = wx.TaskBarIcon() -#taskbaricon.SetIcon(icon, 'Tinc GUI') -#wx.EVT_TASKBAR_RIGHT_UP(taskbaricon, OnTaskBarIcon) + def on_timer(self, event): + vpn.refresh() + self.np.nodes.refresh() + self.np.subnets.refresh() + self.np.edges.refresh() + self.np.connections.refresh() -app.MainLoop() -vpn.close() + +def main(netname, pidfile): + global vpn, app + + if netname is None: + netname = os.getenv('NETNAME') + + vpn = VPN(netname, pidfile) + vpn.connect() + + app = wx.App() + mw = MainWindow(None, -1, 'Tinc GUI') + + """ + def OnTaskBarIcon(event): + mw.Raise() + """ + + """ + icon = wx.Icon("tincgui.ico", wx.BITMAP_TYPE_PNG) + taskbaricon = wx.TaskBarIcon() + taskbaricon.SetIcon(icon, 'Tinc GUI') + wx.EVT_TASKBAR_RIGHT_UP(taskbaricon, OnTaskBarIcon) + """ + + app.MainLoop() + vpn.close() + + +if __name__ == '__main__': + argparser = ArgumentParser(epilog='Report bugs to tinc@tinc-vpn.org.') + + argparser.add_argument('-n', '--net', metavar='NETNAME', dest='netname', help='Connect to net NETNAME') + argparser.add_argument('-p', '--pidfile', help='Path to the pid file (containing the controlcookie)') + + options = argparser.parse_args() + + main(options.netname, options.pidfile) diff --git a/install-sh b/install-sh index 377bb86..59990a1 100755 --- a/install-sh +++ b/install-sh @@ -1,7 +1,7 @@ #!/bin/sh # install - install a program, script, or datafile -scriptversion=2011-11-20.07; # UTC +scriptversion=2014-09-12.12; # UTC # This originates from X11R5 (mit/util/scripts/install.sh), which was # later released in X11R6 (xc/config/util/install.sh) with the @@ -41,19 +41,15 @@ scriptversion=2011-11-20.07; # UTC # This script is compatible with the BSD install script, but was written # from scratch. +tab=' ' nl=' ' -IFS=" "" $nl" +IFS=" $tab$nl" -# set DOITPROG to echo to test this script +# Set DOITPROG to "echo" to test this script. -# Don't use :- since 4.3BSD and earlier shells don't like it. doit=${DOITPROG-} -if test -z "$doit"; then - doit_exec=exec -else - doit_exec=$doit -fi +doit_exec=${doit:-exec} # Put in absolute file names if you don't have them in your path; # or use environment vars. @@ -68,17 +64,6 @@ mvprog=${MVPROG-mv} rmprog=${RMPROG-rm} stripprog=${STRIPPROG-strip} -posix_glob='?' -initialize_posix_glob=' - test "$posix_glob" != "?" || { - if (set -f) 2>/dev/null; then - posix_glob= - else - posix_glob=: - fi - } -' - posix_mkdir= # Desired mode of installed file. @@ -97,7 +82,7 @@ dir_arg= dst_arg= copy_on_change=false -no_target_directory= +is_target_a_directory=possibly usage="\ Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE @@ -137,46 +122,57 @@ while test $# -ne 0; do -d) dir_arg=true;; -g) chgrpcmd="$chgrpprog $2" - shift;; + shift;; --help) echo "$usage"; exit $?;; -m) mode=$2 - case $mode in - *' '* | *' '* | *' -'* | *'*'* | *'?'* | *'['*) - echo "$0: invalid mode: $mode" >&2 - exit 1;; - esac - shift;; + case $mode in + *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*) + echo "$0: invalid mode: $mode" >&2 + exit 1;; + esac + shift;; -o) chowncmd="$chownprog $2" - shift;; + shift;; -s) stripcmd=$stripprog;; - -t) dst_arg=$2 - # Protect names problematic for 'test' and other utilities. - case $dst_arg in - -* | [=\(\)!]) dst_arg=./$dst_arg;; - esac - shift;; + -t) + is_target_a_directory=always + dst_arg=$2 + # Protect names problematic for 'test' and other utilities. + case $dst_arg in + -* | [=\(\)!]) dst_arg=./$dst_arg;; + esac + shift;; - -T) no_target_directory=true;; + -T) is_target_a_directory=never;; --version) echo "$0 $scriptversion"; exit $?;; - --) shift - break;; + --) shift + break;; - -*) echo "$0: invalid option: $1" >&2 - exit 1;; + -*) echo "$0: invalid option: $1" >&2 + exit 1;; *) break;; esac shift done +# We allow the use of options -d and -T together, by making -d +# take the precedence; this is for compatibility with GNU install. + +if test -n "$dir_arg"; then + if test -n "$dst_arg"; then + echo "$0: target directory not allowed when installing a directory." >&2 + exit 1 + fi +fi + if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then # When -d is used, all remaining arguments are directories to create. # When -t is used, the destination is already specified. @@ -207,6 +203,15 @@ if test $# -eq 0; then exit 0 fi +if test -z "$dir_arg"; then + if test $# -gt 1 || test "$is_target_a_directory" = always; then + if test ! -d "$dst_arg"; then + echo "$0: $dst_arg: Is not a directory." >&2 + exit 1 + fi + fi +fi + if test -z "$dir_arg"; then do_exit='(exit $ret); exit $ret' trap "ret=129; $do_exit" 1 @@ -223,16 +228,16 @@ if test -z "$dir_arg"; then *[0-7]) if test -z "$stripcmd"; then - u_plus_rw= + u_plus_rw= else - u_plus_rw='% 200' + u_plus_rw='% 200' fi cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; *) if test -z "$stripcmd"; then - u_plus_rw= + u_plus_rw= else - u_plus_rw=,u+rw + u_plus_rw=,u+rw fi cp_umask=$mode$u_plus_rw;; esac @@ -269,41 +274,15 @@ do # If destination is a directory, append the input filename; won't work # if double slashes aren't ignored. if test -d "$dst"; then - if test -n "$no_target_directory"; then - echo "$0: $dst_arg: Is a directory" >&2 - exit 1 + if test "$is_target_a_directory" = never; then + echo "$0: $dst_arg: Is a directory" >&2 + exit 1 fi dstdir=$dst dst=$dstdir/`basename "$src"` dstdir_status=0 else - # Prefer dirname, but fall back on a substitute if dirname fails. - dstdir=` - (dirname "$dst") 2>/dev/null || - expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$dst" : 'X\(//\)[^/]' \| \ - X"$dst" : 'X\(//\)$' \| \ - X"$dst" : 'X\(/\)' \| . 2>/dev/null || - echo X"$dst" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q' - ` - + dstdir=`dirname "$dst"` test -d "$dstdir" dstdir_status=$? fi @@ -314,74 +293,81 @@ do if test $dstdir_status != 0; then case $posix_mkdir in '') - # Create intermediate dirs using mode 755 as modified by the umask. - # This is like FreeBSD 'install' as of 1997-10-28. - umask=`umask` - case $stripcmd.$umask in - # Optimize common cases. - *[2367][2367]) mkdir_umask=$umask;; - .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; + # Create intermediate dirs using mode 755 as modified by the umask. + # This is like FreeBSD 'install' as of 1997-10-28. + umask=`umask` + case $stripcmd.$umask in + # Optimize common cases. + *[2367][2367]) mkdir_umask=$umask;; + .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; - *[0-7]) - mkdir_umask=`expr $umask + 22 \ - - $umask % 100 % 40 + $umask % 20 \ - - $umask % 10 % 4 + $umask % 2 - `;; - *) mkdir_umask=$umask,go-w;; - esac + *[0-7]) + mkdir_umask=`expr $umask + 22 \ + - $umask % 100 % 40 + $umask % 20 \ + - $umask % 10 % 4 + $umask % 2 + `;; + *) mkdir_umask=$umask,go-w;; + esac - # With -d, create the new directory with the user-specified mode. - # Otherwise, rely on $mkdir_umask. - if test -n "$dir_arg"; then - mkdir_mode=-m$mode - else - mkdir_mode= - fi + # With -d, create the new directory with the user-specified mode. + # Otherwise, rely on $mkdir_umask. + if test -n "$dir_arg"; then + mkdir_mode=-m$mode + else + mkdir_mode= + fi - posix_mkdir=false - case $umask in - *[123567][0-7][0-7]) - # POSIX mkdir -p sets u+wx bits regardless of umask, which - # is incompatible with FreeBSD 'install' when (umask & 300) != 0. - ;; - *) - tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ - trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 + posix_mkdir=false + case $umask in + *[123567][0-7][0-7]) + # POSIX mkdir -p sets u+wx bits regardless of umask, which + # is incompatible with FreeBSD 'install' when (umask & 300) != 0. + ;; + *) + # $RANDOM is not portable (e.g. dash); use it when possible to + # lower collision chance + tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ + trap 'ret=$?; rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null; exit $ret' 0 - if (umask $mkdir_umask && - exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 - then - if test -z "$dir_arg" || { - # Check for POSIX incompatibilities with -m. - # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or - # other-writable bit of parent directory when it shouldn't. - # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. - ls_ld_tmpdir=`ls -ld "$tmpdir"` - case $ls_ld_tmpdir in - d????-?r-*) different_mode=700;; - d????-?--*) different_mode=755;; - *) false;; - esac && - $mkdirprog -m$different_mode -p -- "$tmpdir" && { - ls_ld_tmpdir_1=`ls -ld "$tmpdir"` - test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" - } - } - then posix_mkdir=: - fi - rmdir "$tmpdir/d" "$tmpdir" - else - # Remove any dirs left behind by ancient mkdir implementations. - rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null - fi - trap '' 0;; - esac;; + # As "mkdir -p" follows symlinks and we work in /tmp possibly; so + # create the $tmpdir first (and fail if unsuccessful) to make sure + # that nobody tries to guess the $tmpdir name. + if (umask $mkdir_umask && + $mkdirprog $mkdir_mode "$tmpdir" && + exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1 + then + if test -z "$dir_arg" || { + # Check for POSIX incompatibilities with -m. + # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or + # other-writable bit of parent directory when it shouldn't. + # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. + test_tmpdir="$tmpdir/a" + ls_ld_tmpdir=`ls -ld "$test_tmpdir"` + case $ls_ld_tmpdir in + d????-?r-*) different_mode=700;; + d????-?--*) different_mode=755;; + *) false;; + esac && + $mkdirprog -m$different_mode -p -- "$test_tmpdir" && { + ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"` + test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" + } + } + then posix_mkdir=: + fi + rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" + else + # Remove any dirs left behind by ancient mkdir implementations. + rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null + fi + trap '' 0;; + esac;; esac if $posix_mkdir && ( - umask $mkdir_umask && - $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" + umask $mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" ) then : else @@ -391,53 +377,51 @@ do # directory the slow way, step by step, checking for races as we go. case $dstdir in - /*) prefix='/';; - [-=\(\)!]*) prefix='./';; - *) prefix='';; + /*) prefix='/';; + [-=\(\)!]*) prefix='./';; + *) prefix='';; esac - eval "$initialize_posix_glob" - oIFS=$IFS IFS=/ - $posix_glob set -f + set -f set fnord $dstdir shift - $posix_glob set +f + set +f IFS=$oIFS prefixes= for d do - test X"$d" = X && continue + test X"$d" = X && continue - prefix=$prefix$d - if test -d "$prefix"; then - prefixes= - else - if $posix_mkdir; then - (umask=$mkdir_umask && - $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break - # Don't fail if two instances are running concurrently. - test -d "$prefix" || exit 1 - else - case $prefix in - *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; - *) qprefix=$prefix;; - esac - prefixes="$prefixes '$qprefix'" - fi - fi - prefix=$prefix/ + prefix=$prefix$d + if test -d "$prefix"; then + prefixes= + else + if $posix_mkdir; then + (umask=$mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break + # Don't fail if two instances are running concurrently. + test -d "$prefix" || exit 1 + else + case $prefix in + *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; + *) qprefix=$prefix;; + esac + prefixes="$prefixes '$qprefix'" + fi + fi + prefix=$prefix/ done if test -n "$prefixes"; then - # Don't fail if two instances are running concurrently. - (umask $mkdir_umask && - eval "\$doit_exec \$mkdirprog $prefixes") || - test -d "$dstdir" || exit 1 - obsolete_mkdir_used=true + # Don't fail if two instances are running concurrently. + (umask $mkdir_umask && + eval "\$doit_exec \$mkdirprog $prefixes") || + test -d "$dstdir" || exit 1 + obsolete_mkdir_used=true fi fi fi @@ -472,15 +456,12 @@ do # If -C, don't bother to copy if it wouldn't change the file. if $copy_on_change && - old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && - new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && - - eval "$initialize_posix_glob" && - $posix_glob set -f && + old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && + new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && + set -f && set X $old && old=:$2:$4:$5:$6 && set X $new && new=:$2:$4:$5:$6 && - $posix_glob set +f && - + set +f && test "$old" = "$new" && $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 then @@ -493,24 +474,24 @@ do # to itself, or perhaps because mv is so ancient that it does not # support -f. { - # Now remove or move aside any old file at destination location. - # We try this two ways since rm can't unlink itself on some - # systems and the destination file might be busy for other - # reasons. In this case, the final cleanup might fail but the new - # file should still install successfully. - { - test ! -f "$dst" || - $doit $rmcmd -f "$dst" 2>/dev/null || - { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && - { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } - } || - { echo "$0: cannot unlink or rename $dst" >&2 - (exit 1); exit 1 - } - } && + # Now remove or move aside any old file at destination location. + # We try this two ways since rm can't unlink itself on some + # systems and the destination file might be busy for other + # reasons. In this case, the final cleanup might fail but the new + # file should still install successfully. + { + test ! -f "$dst" || + $doit $rmcmd -f "$dst" 2>/dev/null || + { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && + { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } + } || + { echo "$0: cannot unlink or rename $dst" >&2 + (exit 1); exit 1 + } + } && - # Now rename the file to the real destination. - $doit $mvcmd "$dsttmp" "$dst" + # Now rename the file to the real destination. + $doit $mvcmd "$dsttmp" "$dst" } fi || exit 1 diff --git a/m4/Makefile.am b/m4/Makefile.am deleted file mode 100644 index 0f58aef..0000000 --- a/m4/Makefile.am +++ /dev/null @@ -1,4 +0,0 @@ -## Process this file with automake to produce Makefile.in -*-Makefile-*- - -EXTRA_DIST = README *.m4 - diff --git a/m4/README b/m4/README deleted file mode 100644 index df032df..0000000 --- a/m4/README +++ /dev/null @@ -1,8 +0,0 @@ -These files are used by a program called aclocal (part of the GNU automake -package). aclocal uses these files to create aclocal.m4 which is in turn -used by autoconf to create the configure script at the the top level in -this distribution. - -The Makefile.am file in this directory is automatically generated -from the template file, Makefile.am.in. The generation will fail -if you don't have all the right tools. diff --git a/m4/attribute.m4 b/m4/attribute.m4 index 6a8f555..9d673e9 100644 --- a/m4/attribute.m4 +++ b/m4/attribute.m4 @@ -9,8 +9,8 @@ AC_DEFUN([tinc_ATTRIBUTE], CFLAGS="$CFLAGS -Wall -Werror" AC_COMPILE_IFELSE( [AC_LANG_SOURCE( - [void test(void) __attribute__ (($1)); - void test(void) { return; } + [void *test(void) __attribute__ (($1)); + void *test(void) { return (void *)0; } ], )], [tinc_cv_attribute_$1=yes], diff --git a/m4/miniupnpc.m4 b/m4/miniupnpc.m4 new file mode 100644 index 0000000..c2aca29 --- /dev/null +++ b/m4/miniupnpc.m4 @@ -0,0 +1,40 @@ +dnl Check to find the miniupnpc headers/libraries + +AC_DEFUN([tinc_MINIUPNPC], +[ + AC_ARG_ENABLE([miniupnpc], + AS_HELP_STRING([--enable-miniupnpc], [enable miniupnpc support])) + AS_IF([test "x$enable_miniupnpc" = "xyes"], [ + AC_DEFINE(HAVE_MINIUPNPC, 1, [have miniupnpc support]) + AC_ARG_WITH(miniupnpc, + AS_HELP_STRING([--with-miniupnpc=DIR], [miniupnpc base directory, or:]), + [miniupnpc="$withval" + CPPFLAGS="$CPPFLAGS -I$withval/include" + LDFLAGS="$LDFLAGS -L$withval/lib"] + ) + + AC_ARG_WITH(miniupnpc-include, + AS_HELP_STRING([--with-miniupnpc-include=DIR], [miniupnpc headers directory]), + [miniupnpc_include="$withval" + CPPFLAGS="$CPPFLAGS -I$withval"] + ) + + AC_ARG_WITH(miniupnpc-lib, + AS_HELP_STRING([--with-miniupnpc-lib=DIR], [miniupnpc library directory]), + [miniupnpc_lib="$withval" + LDFLAGS="$LDFLAGS -L$withval"] + ) + + AC_CHECK_HEADERS(miniupnpc/miniupnpc.h, + [], + [AC_MSG_ERROR("miniupnpc header files not found."); break] + ) + + AC_CHECK_LIB(miniupnpc, upnpDiscover, + [MINIUPNPC_LIBS="$LIBS -lminiupnpc"], + [AC_MSG_ERROR("miniupnpc libraries not found.")] + ) + ]) + + AC_SUBST(MINIUPNPC_LIBS) +]) diff --git a/m4/openssl.m4 b/m4/openssl.m4 index 738c68c..26cbcbe 100644 --- a/m4/openssl.m4 +++ b/m4/openssl.m4 @@ -1,4 +1,4 @@ -dnl Check to find the OpenSSL headers/libraries +dnl Check to find the LibreSSL/OpenSSL headers/libraries AC_DEFUN([tinc_OPENSSL], [ @@ -10,47 +10,47 @@ AC_DEFUN([tinc_OPENSSL], [], [AC_CHECK_LIB(dl, dlopen, [LIBS="$LIBS -ldl"], - [AC_MSG_ERROR([OpenSSL depends on libdl.]); break] + [AC_MSG_ERROR([LibreSSL/OpenSSL depends on libdl.]); break] )] ) ;; esac AC_ARG_WITH(openssl, - AS_HELP_STRING([--with-openssl=DIR], [OpenSSL base directory, or:]), + AS_HELP_STRING([--with-openssl=DIR], [LibreSSL/OpenSSL base directory, or:]), [openssl="$withval" CPPFLAGS="$CPPFLAGS -I$withval/include" LDFLAGS="$LDFLAGS -L$withval/lib"] ) AC_ARG_WITH(openssl-include, - AS_HELP_STRING([--with-openssl-include=DIR], [OpenSSL headers directory (without trailing /openssl)]), + AS_HELP_STRING([--with-openssl-include=DIR], [LibreSSL/OpenSSL headers directory (without trailing /openssl)]), [openssl_include="$withval" CPPFLAGS="$CPPFLAGS -I$withval"] ) AC_ARG_WITH(openssl-lib, - AS_HELP_STRING([--with-openssl-lib=DIR], [OpenSSL library directory]), + AS_HELP_STRING([--with-openssl-lib=DIR], [LibreSSL/OpenSSL library directory]), [openssl_lib="$withval" LDFLAGS="$LDFLAGS -L$withval"] ) AC_CHECK_HEADERS([openssl/evp.h openssl/rsa.h openssl/rand.h openssl/err.h openssl/sha.h openssl/pem.h openssl/engine.h], [], - [AC_MSG_ERROR([OpenSSL header files not found.]); break] + [AC_MSG_ERROR([LibreSSL/OpenSSL header files not found.]); break] ) AC_CHECK_LIB(crypto, EVP_EncryptInit_ex, [LIBS="-lcrypto $LIBS"], - [AC_MSG_ERROR([OpenSSL libraries not found.])] + [AC_MSG_ERROR([LibreSSL/OpenSSL libraries not found.])] ) AC_CHECK_FUNCS([RAND_status EVP_EncryptInit_ex], , - [AC_MSG_ERROR([Missing OpenSSL functionality, make sure you have installed the latest version.]); break], + [AC_MSG_ERROR([Missing LibreSSL/OpenSSL functionality, make sure you have installed the latest version.]); break], ) AC_CHECK_DECLS([OpenSSL_add_all_algorithms], , - [AC_MSG_ERROR([Missing OpenSSL functionality, make sure you have installed the latest version.]); break], + [AC_MSG_ERROR([Missing LibreSSL/OpenSSL functionality, make sure you have installed the latest version.]); break], [#include ] ) ]) diff --git a/missing b/missing index db98974..f62bbae 100755 --- a/missing +++ b/missing @@ -3,7 +3,7 @@ scriptversion=2013-10-28.13; # UTC -# Copyright (C) 1996-2013 Free Software Foundation, Inc. +# Copyright (C) 1996-2014 Free Software Foundation, Inc. # Originally written by Fran,cois Pinard , 1996. # This program is free software; you can redistribute it and/or modify diff --git a/src/Makefile.am b/src/Makefile.am index cd84f3a..200c71f 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -2,16 +2,25 @@ sbin_PROGRAMS = tincd tinc sptps_test sptps_keypair -## Make sure version.c is always rebuilt -.PHONY: version.c -version.c: +CLEANFILES = version_git.h + +.PHONY: version-stamp +version-stamp: + +version_git.h: version-stamp + $(AM_V_GEN)echo >$@ + @-(cd $(srcdir) && git describe 2>/dev/null >/dev/null) && echo '#define GIT_DESCRIPTION "'`(cd $(srcdir) && git describe) | sed 's/release-//'`'"' >$@ ||: +${srcdir}/version.c: version_git.h + +## Now a hack to appease some versions of BSD make that don't understand that "./foo" is the same as "foo". +if BSD +version.c: ${srcdir}/version.c +endif if LINUX sbin_PROGRAMS += sptps_speed endif -DEFAULT_INCLUDES = - ed25519_SOURCES = \ ed25519/add_scalar.c \ ed25519/ed25519.h \ @@ -49,11 +58,6 @@ tincd_SOURCES = \ edge.c edge.h \ ethernet.h \ event.c event.h \ - fake-gai-errnos.h \ - fake-getaddrinfo.c fake-getaddrinfo.h \ - fake-getnameinfo.c fake-getnameinfo.h \ - getopt.c getopt.h \ - getopt1.c \ graph.c graph.h \ hash.c hash.h \ have.h \ @@ -92,13 +96,15 @@ tincd_SOURCES = \ utils.c utils.h \ xalloc.h \ version.c version.h \ + ed25519/ecdh.c \ + ed25519/ecdsa.c \ $(ed25519_SOURCES) \ $(chacha_poly1305_SOURCES) tinc_SOURCES = \ dropin.c dropin.h \ - getopt.c getopt.h \ - getopt1.c \ + fsck.c fsck.h \ + ifconfig.c ifconfig.h \ info.c info.h \ invitation.c invitation.h \ list.c list.h \ @@ -111,6 +117,9 @@ tinc_SOURCES = \ top.c top.h \ utils.c utils.h \ version.c version.h \ + ed25519/ecdh.c \ + ed25519/ecdsa.c \ + ed25519/ecdsagen.c \ $(ed25519_SOURCES) \ $(chacha_poly1305_SOURCES) @@ -119,12 +128,15 @@ sptps_test_SOURCES = \ sptps.c sptps.h \ sptps_test.c \ utils.c utils.h \ + ed25519/ecdh.c \ + ed25519/ecdsa.c \ $(ed25519_SOURCES) \ $(chacha_poly1305_SOURCES) sptps_keypair_SOURCES = \ sptps_keypair.c \ utils.c utils.h \ + ed25519/ecdsagen.c \ $(ed25519_SOURCES) sptps_speed_SOURCES = \ @@ -132,11 +144,29 @@ sptps_speed_SOURCES = \ sptps.c sptps.h \ sptps_speed.c \ utils.c utils.h \ + ed25519/ecdh.c \ + ed25519/ecdsa.c \ + ed25519/ecdsagen.c \ $(ed25519_SOURCES) \ $(chacha_poly1305_SOURCES) ## Conditionally compile device drivers - + +if !GETOPT +tincd_SOURCES += \ + getopt.c getopt.h \ + getopt1.c +tinc_SOURCES += \ + getopt.c getopt.h \ + getopt1.c +sptps_test_SOURCES += \ + getopt.c getopt.h \ + getopt1.c +sptps_keypair_SOURCES += \ + getopt.c getopt.h \ + getopt1.c +endif + if LINUX tincd_SOURCES += linux/device.c endif @@ -173,54 +203,37 @@ tincd_SOURCES += \ openssl/cipher.c \ openssl/crypto.c \ openssl/digest.c openssl/digest.h \ - ed25519/ecdh.c \ - ed25519/ecdsa.c \ openssl/prf.c \ openssl/rsa.c tinc_SOURCES += \ openssl/cipher.c \ openssl/crypto.c \ openssl/digest.c openssl/digest.h \ - ed25519/ecdh.c \ - ed25519/ecdsa.c \ - ed25519/ecdsagen.c \ openssl/prf.c \ openssl/rsa.c \ openssl/rsagen.c sptps_test_SOURCES += \ openssl/crypto.c \ openssl/digest.c openssl/digest.h \ - ed25519/ecdh.c \ - ed25519/ecdsa.c \ openssl/prf.c sptps_keypair_SOURCES += \ - openssl/crypto.c \ - ed25519/ecdsagen.c + openssl/crypto.c sptps_speed_SOURCES += \ openssl/crypto.c \ openssl/digest.c openssl/digest.h \ - ed25519/ecdh.c \ - ed25519/ecdsa.c \ - ed25519/ecdsagen.c \ openssl/prf.c -endif - +else if GCRYPT tincd_SOURCES += \ gcrypt/cipher.c \ gcrypt/crypto.c \ gcrypt/digest.c gcrypt/digest.h \ - gcrypt/ecdh.c \ - gcrypt/ecdsa.c \ gcrypt/prf.c \ gcrypt/rsa.c tinc_SOURCES += \ gcrypt/cipher.c \ gcrypt/crypto.c \ gcrypt/digest.c gcrypt/digest.h \ - gcrypt/ecdh.c \ - gcrypt/ecdsa.c \ - gcrypt/ecdsagen.c \ gcrypt/prf.c \ gcrypt/rsa.c \ gcrypt/rsagen.c @@ -228,18 +241,44 @@ sptps_test_SOURCES += \ gcrypt/cipher.c \ gcrypt/crypto.c \ gcrypt/digest.c gcrypt/digest.h \ - gcrypt/ecdh.c \ - gcrypt/ecdsa.c \ gcrypt/prf.c +sptps_keypair_SOURCES += \ + openssl/crypto.c +sptps_speed_SOURCES += \ + openssl/crypto.c \ + openssl/digest.c openssl/digest.h \ + openssl/prf.c +else +tincd_SOURCES += \ + nolegacy/crypto.c \ + nolegacy/prf.c +tinc_SOURCES += \ + nolegacy/crypto.c \ + nolegacy/prf.c +sptps_test_SOURCES += \ + nolegacy/crypto.c \ + nolegacy/prf.c +sptps_keypair_SOURCES += \ + nolegacy/crypto.c +sptps_speed_SOURCES += \ + nolegacy/crypto.c \ + nolegacy/prf.c +endif +endif + +if MINIUPNPC +tincd_SOURCES += upnp.h upnp.c +tincd_LDADD = $(MINIUPNPC_LIBS) +tincd_LDFLAGS = -pthread endif tinc_LDADD = $(READLINE_LIBS) $(CURSES_LIBS) sptps_speed_LDADD = -lrt -LIBS = @LIBS@ +LIBS = @LIBS@ -lm if TUNEMU LIBS += -lpcap endif -AM_CFLAGS = -DCONFDIR=\"$(sysconfdir)\" -DLOCALSTATEDIR=\"$(localstatedir)\" -DSBINDIR=\"$(sbindir)\" +AM_CFLAGS = -DCONFDIR=\"$(sysconfdir)\" -DLOCALSTATEDIR=\"$(localstatedir)\" -DSBINDIR=\"$(sbindir)\" -iquote. diff --git a/src/Makefile.in b/src/Makefile.in index bb7213a..da3ca9f 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.14.1 from Makefile.am. +# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2013 Free Software Foundation, Inc. +# Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -15,7 +15,17 @@ @SET_MAKE@ VPATH = @srcdir@ -am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ @@ -81,95 +91,120 @@ host_triplet = @host@ sbin_PROGRAMS = tincd$(EXEEXT) tinc$(EXEEXT) sptps_test$(EXEEXT) \ sptps_keypair$(EXEEXT) $(am__EXEEXT_1) @LINUX_TRUE@am__append_1 = sptps_speed -@LINUX_TRUE@am__append_2 = linux/device.c -@BSD_TRUE@am__append_3 = bsd/device.c -@BSD_TRUE@@TUNEMU_TRUE@am__append_4 = bsd/tunemu.c bsd/tunemu.h -@SOLARIS_TRUE@am__append_5 = solaris/device.c -@MINGW_TRUE@am__append_6 = mingw/device.c mingw/common.h -@CYGWIN_TRUE@am__append_7 = cygwin/device.c -@UML_TRUE@am__append_8 = uml_device.c -@VDE_TRUE@am__append_9 = vde_device.c -@OPENSSL_TRUE@am__append_10 = \ +@GETOPT_FALSE@am__append_2 = \ +@GETOPT_FALSE@ getopt.c getopt.h \ +@GETOPT_FALSE@ getopt1.c + +@GETOPT_FALSE@am__append_3 = \ +@GETOPT_FALSE@ getopt.c getopt.h \ +@GETOPT_FALSE@ getopt1.c + +@GETOPT_FALSE@am__append_4 = \ +@GETOPT_FALSE@ getopt.c getopt.h \ +@GETOPT_FALSE@ getopt1.c + +@GETOPT_FALSE@am__append_5 = \ +@GETOPT_FALSE@ getopt.c getopt.h \ +@GETOPT_FALSE@ getopt1.c + +@LINUX_TRUE@am__append_6 = linux/device.c +@BSD_TRUE@am__append_7 = bsd/device.c +@BSD_TRUE@@TUNEMU_TRUE@am__append_8 = bsd/tunemu.c bsd/tunemu.h +@SOLARIS_TRUE@am__append_9 = solaris/device.c +@MINGW_TRUE@am__append_10 = mingw/device.c mingw/common.h +@CYGWIN_TRUE@am__append_11 = cygwin/device.c +@UML_TRUE@am__append_12 = uml_device.c +@VDE_TRUE@am__append_13 = vde_device.c +@OPENSSL_TRUE@am__append_14 = \ @OPENSSL_TRUE@ openssl/cipher.c \ @OPENSSL_TRUE@ openssl/crypto.c \ @OPENSSL_TRUE@ openssl/digest.c openssl/digest.h \ -@OPENSSL_TRUE@ ed25519/ecdh.c \ -@OPENSSL_TRUE@ ed25519/ecdsa.c \ @OPENSSL_TRUE@ openssl/prf.c \ @OPENSSL_TRUE@ openssl/rsa.c -@OPENSSL_TRUE@am__append_11 = \ +@OPENSSL_TRUE@am__append_15 = \ @OPENSSL_TRUE@ openssl/cipher.c \ @OPENSSL_TRUE@ openssl/crypto.c \ @OPENSSL_TRUE@ openssl/digest.c openssl/digest.h \ -@OPENSSL_TRUE@ ed25519/ecdh.c \ -@OPENSSL_TRUE@ ed25519/ecdsa.c \ -@OPENSSL_TRUE@ ed25519/ecdsagen.c \ @OPENSSL_TRUE@ openssl/prf.c \ @OPENSSL_TRUE@ openssl/rsa.c \ @OPENSSL_TRUE@ openssl/rsagen.c -@OPENSSL_TRUE@am__append_12 = \ +@OPENSSL_TRUE@am__append_16 = \ @OPENSSL_TRUE@ openssl/crypto.c \ @OPENSSL_TRUE@ openssl/digest.c openssl/digest.h \ -@OPENSSL_TRUE@ ed25519/ecdh.c \ -@OPENSSL_TRUE@ ed25519/ecdsa.c \ @OPENSSL_TRUE@ openssl/prf.c -@OPENSSL_TRUE@am__append_13 = \ -@OPENSSL_TRUE@ openssl/crypto.c \ -@OPENSSL_TRUE@ ed25519/ecdsagen.c +@OPENSSL_TRUE@am__append_17 = \ +@OPENSSL_TRUE@ openssl/crypto.c -@OPENSSL_TRUE@am__append_14 = \ +@OPENSSL_TRUE@am__append_18 = \ @OPENSSL_TRUE@ openssl/crypto.c \ @OPENSSL_TRUE@ openssl/digest.c openssl/digest.h \ -@OPENSSL_TRUE@ ed25519/ecdh.c \ -@OPENSSL_TRUE@ ed25519/ecdsa.c \ -@OPENSSL_TRUE@ ed25519/ecdsagen.c \ @OPENSSL_TRUE@ openssl/prf.c -@GCRYPT_TRUE@am__append_15 = \ -@GCRYPT_TRUE@ gcrypt/cipher.c \ -@GCRYPT_TRUE@ gcrypt/crypto.c \ -@GCRYPT_TRUE@ gcrypt/digest.c gcrypt/digest.h \ -@GCRYPT_TRUE@ gcrypt/ecdh.c \ -@GCRYPT_TRUE@ gcrypt/ecdsa.c \ -@GCRYPT_TRUE@ gcrypt/prf.c \ -@GCRYPT_TRUE@ gcrypt/rsa.c +@GCRYPT_TRUE@@OPENSSL_FALSE@am__append_19 = \ +@GCRYPT_TRUE@@OPENSSL_FALSE@ gcrypt/cipher.c \ +@GCRYPT_TRUE@@OPENSSL_FALSE@ gcrypt/crypto.c \ +@GCRYPT_TRUE@@OPENSSL_FALSE@ gcrypt/digest.c gcrypt/digest.h \ +@GCRYPT_TRUE@@OPENSSL_FALSE@ gcrypt/prf.c \ +@GCRYPT_TRUE@@OPENSSL_FALSE@ gcrypt/rsa.c -@GCRYPT_TRUE@am__append_16 = \ -@GCRYPT_TRUE@ gcrypt/cipher.c \ -@GCRYPT_TRUE@ gcrypt/crypto.c \ -@GCRYPT_TRUE@ gcrypt/digest.c gcrypt/digest.h \ -@GCRYPT_TRUE@ gcrypt/ecdh.c \ -@GCRYPT_TRUE@ gcrypt/ecdsa.c \ -@GCRYPT_TRUE@ gcrypt/ecdsagen.c \ -@GCRYPT_TRUE@ gcrypt/prf.c \ -@GCRYPT_TRUE@ gcrypt/rsa.c \ -@GCRYPT_TRUE@ gcrypt/rsagen.c +@GCRYPT_TRUE@@OPENSSL_FALSE@am__append_20 = \ +@GCRYPT_TRUE@@OPENSSL_FALSE@ gcrypt/cipher.c \ +@GCRYPT_TRUE@@OPENSSL_FALSE@ gcrypt/crypto.c \ +@GCRYPT_TRUE@@OPENSSL_FALSE@ gcrypt/digest.c gcrypt/digest.h \ +@GCRYPT_TRUE@@OPENSSL_FALSE@ gcrypt/prf.c \ +@GCRYPT_TRUE@@OPENSSL_FALSE@ gcrypt/rsa.c \ +@GCRYPT_TRUE@@OPENSSL_FALSE@ gcrypt/rsagen.c -@GCRYPT_TRUE@am__append_17 = \ -@GCRYPT_TRUE@ gcrypt/cipher.c \ -@GCRYPT_TRUE@ gcrypt/crypto.c \ -@GCRYPT_TRUE@ gcrypt/digest.c gcrypt/digest.h \ -@GCRYPT_TRUE@ gcrypt/ecdh.c \ -@GCRYPT_TRUE@ gcrypt/ecdsa.c \ -@GCRYPT_TRUE@ gcrypt/prf.c +@GCRYPT_TRUE@@OPENSSL_FALSE@am__append_21 = \ +@GCRYPT_TRUE@@OPENSSL_FALSE@ gcrypt/cipher.c \ +@GCRYPT_TRUE@@OPENSSL_FALSE@ gcrypt/crypto.c \ +@GCRYPT_TRUE@@OPENSSL_FALSE@ gcrypt/digest.c gcrypt/digest.h \ +@GCRYPT_TRUE@@OPENSSL_FALSE@ gcrypt/prf.c -@TUNEMU_TRUE@am__append_18 = -lpcap +@GCRYPT_TRUE@@OPENSSL_FALSE@am__append_22 = \ +@GCRYPT_TRUE@@OPENSSL_FALSE@ openssl/crypto.c + +@GCRYPT_TRUE@@OPENSSL_FALSE@am__append_23 = \ +@GCRYPT_TRUE@@OPENSSL_FALSE@ openssl/crypto.c \ +@GCRYPT_TRUE@@OPENSSL_FALSE@ openssl/digest.c openssl/digest.h \ +@GCRYPT_TRUE@@OPENSSL_FALSE@ openssl/prf.c + +@GCRYPT_FALSE@@OPENSSL_FALSE@am__append_24 = \ +@GCRYPT_FALSE@@OPENSSL_FALSE@ nolegacy/crypto.c \ +@GCRYPT_FALSE@@OPENSSL_FALSE@ nolegacy/prf.c + +@GCRYPT_FALSE@@OPENSSL_FALSE@am__append_25 = \ +@GCRYPT_FALSE@@OPENSSL_FALSE@ nolegacy/crypto.c \ +@GCRYPT_FALSE@@OPENSSL_FALSE@ nolegacy/prf.c + +@GCRYPT_FALSE@@OPENSSL_FALSE@am__append_26 = \ +@GCRYPT_FALSE@@OPENSSL_FALSE@ nolegacy/crypto.c \ +@GCRYPT_FALSE@@OPENSSL_FALSE@ nolegacy/prf.c + +@GCRYPT_FALSE@@OPENSSL_FALSE@am__append_27 = \ +@GCRYPT_FALSE@@OPENSSL_FALSE@ nolegacy/crypto.c + +@GCRYPT_FALSE@@OPENSSL_FALSE@am__append_28 = \ +@GCRYPT_FALSE@@OPENSSL_FALSE@ nolegacy/crypto.c \ +@GCRYPT_FALSE@@OPENSSL_FALSE@ nolegacy/prf.c + +@MINIUPNPC_TRUE@am__append_29 = upnp.h upnp.c +@TUNEMU_TRUE@am__append_30 = -lpcap subdir = src -DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ - $(top_srcdir)/depcomp ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \ $(top_srcdir)/m4/ax_check_compile_flag.m4 \ $(top_srcdir)/m4/ax_check_link_flag.m4 \ $(top_srcdir)/m4/curses.m4 $(top_srcdir)/m4/libgcrypt.m4 \ - $(top_srcdir)/m4/lzo.m4 $(top_srcdir)/m4/openssl.m4 \ - $(top_srcdir)/m4/readline.m4 $(top_srcdir)/m4/zlib.m4 \ - $(top_srcdir)/configure.ac + $(top_srcdir)/m4/lzo.m4 $(top_srcdir)/m4/miniupnpc.m4 \ + $(top_srcdir)/m4/openssl.m4 $(top_srcdir)/m4/readline.m4 \ + $(top_srcdir)/m4/zlib.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = @@ -178,78 +213,91 @@ CONFIG_CLEAN_VPATH_FILES = am__installdirs = "$(DESTDIR)$(sbindir)" PROGRAMS = $(sbin_PROGRAMS) am__sptps_keypair_SOURCES_DIST = sptps_keypair.c utils.c utils.h \ - ed25519/add_scalar.c ed25519/ed25519.h ed25519/fe.c \ - ed25519/fe.h ed25519/fixedint.h ed25519/ge.c ed25519/ge.h \ - ed25519/key_exchange.c ed25519/keypair.c \ + ed25519/ecdsagen.c ed25519/add_scalar.c ed25519/ed25519.h \ + ed25519/fe.c ed25519/fe.h ed25519/fixedint.h ed25519/ge.c \ + ed25519/ge.h ed25519/key_exchange.c ed25519/keypair.c \ ed25519/precomp_data.h ed25519/sc.c ed25519/sc.h \ ed25519/sha512.c ed25519/sha512.h ed25519/sign.c \ - ed25519/verify.c openssl/crypto.c ed25519/ecdsagen.c + ed25519/verify.c getopt.c getopt.h getopt1.c openssl/crypto.c \ + nolegacy/crypto.c am__dirstamp = $(am__leading_dot)dirstamp am__objects_1 = ed25519/add_scalar.$(OBJEXT) ed25519/fe.$(OBJEXT) \ ed25519/ge.$(OBJEXT) ed25519/key_exchange.$(OBJEXT) \ ed25519/keypair.$(OBJEXT) ed25519/sc.$(OBJEXT) \ ed25519/sha512.$(OBJEXT) ed25519/sign.$(OBJEXT) \ ed25519/verify.$(OBJEXT) -@OPENSSL_TRUE@am__objects_2 = openssl/crypto.$(OBJEXT) \ -@OPENSSL_TRUE@ ed25519/ecdsagen.$(OBJEXT) +@GETOPT_FALSE@am__objects_2 = getopt.$(OBJEXT) getopt1.$(OBJEXT) +@OPENSSL_TRUE@am__objects_3 = openssl/crypto.$(OBJEXT) +@GCRYPT_TRUE@@OPENSSL_FALSE@am__objects_4 = openssl/crypto.$(OBJEXT) +@GCRYPT_FALSE@@OPENSSL_FALSE@am__objects_5 = \ +@GCRYPT_FALSE@@OPENSSL_FALSE@ nolegacy/crypto.$(OBJEXT) am_sptps_keypair_OBJECTS = sptps_keypair.$(OBJEXT) utils.$(OBJEXT) \ - $(am__objects_1) $(am__objects_2) + ed25519/ecdsagen.$(OBJEXT) $(am__objects_1) $(am__objects_2) \ + $(am__objects_3) $(am__objects_4) $(am__objects_5) sptps_keypair_OBJECTS = $(am_sptps_keypair_OBJECTS) sptps_keypair_LDADD = $(LDADD) am__sptps_speed_SOURCES_DIST = logger.c logger.h sptps.c sptps.h \ - sptps_speed.c utils.c utils.h ed25519/add_scalar.c \ - ed25519/ed25519.h ed25519/fe.c ed25519/fe.h ed25519/fixedint.h \ - ed25519/ge.c ed25519/ge.h ed25519/key_exchange.c \ - ed25519/keypair.c ed25519/precomp_data.h ed25519/sc.c \ - ed25519/sc.h ed25519/sha512.c ed25519/sha512.h ed25519/sign.c \ + sptps_speed.c utils.c utils.h ed25519/ecdh.c ed25519/ecdsa.c \ + ed25519/ecdsagen.c ed25519/add_scalar.c ed25519/ed25519.h \ + ed25519/fe.c ed25519/fe.h ed25519/fixedint.h ed25519/ge.c \ + ed25519/ge.h ed25519/key_exchange.c ed25519/keypair.c \ + ed25519/precomp_data.h ed25519/sc.c ed25519/sc.h \ + ed25519/sha512.c ed25519/sha512.h ed25519/sign.c \ ed25519/verify.c chacha-poly1305/chacha.c \ chacha-poly1305/chacha.h chacha-poly1305/chacha-poly1305.c \ chacha-poly1305/chacha-poly1305.h chacha-poly1305/poly1305.c \ chacha-poly1305/poly1305.h openssl/crypto.c openssl/digest.c \ - openssl/digest.h ed25519/ecdh.c ed25519/ecdsa.c \ - ed25519/ecdsagen.c openssl/prf.c -am__objects_3 = chacha-poly1305/chacha.$(OBJEXT) \ + openssl/digest.h openssl/prf.c nolegacy/crypto.c \ + nolegacy/prf.c +am__objects_6 = chacha-poly1305/chacha.$(OBJEXT) \ chacha-poly1305/chacha-poly1305.$(OBJEXT) \ chacha-poly1305/poly1305.$(OBJEXT) -@OPENSSL_TRUE@am__objects_4 = openssl/crypto.$(OBJEXT) \ -@OPENSSL_TRUE@ openssl/digest.$(OBJEXT) ed25519/ecdh.$(OBJEXT) \ -@OPENSSL_TRUE@ ed25519/ecdsa.$(OBJEXT) \ -@OPENSSL_TRUE@ ed25519/ecdsagen.$(OBJEXT) openssl/prf.$(OBJEXT) +@OPENSSL_TRUE@am__objects_7 = openssl/crypto.$(OBJEXT) \ +@OPENSSL_TRUE@ openssl/digest.$(OBJEXT) openssl/prf.$(OBJEXT) +@GCRYPT_TRUE@@OPENSSL_FALSE@am__objects_8 = openssl/crypto.$(OBJEXT) \ +@GCRYPT_TRUE@@OPENSSL_FALSE@ openssl/digest.$(OBJEXT) \ +@GCRYPT_TRUE@@OPENSSL_FALSE@ openssl/prf.$(OBJEXT) +@GCRYPT_FALSE@@OPENSSL_FALSE@am__objects_9 = \ +@GCRYPT_FALSE@@OPENSSL_FALSE@ nolegacy/crypto.$(OBJEXT) \ +@GCRYPT_FALSE@@OPENSSL_FALSE@ nolegacy/prf.$(OBJEXT) am_sptps_speed_OBJECTS = logger.$(OBJEXT) sptps.$(OBJEXT) \ - sptps_speed.$(OBJEXT) utils.$(OBJEXT) $(am__objects_1) \ - $(am__objects_3) $(am__objects_4) + sptps_speed.$(OBJEXT) utils.$(OBJEXT) ed25519/ecdh.$(OBJEXT) \ + ed25519/ecdsa.$(OBJEXT) ed25519/ecdsagen.$(OBJEXT) \ + $(am__objects_1) $(am__objects_6) $(am__objects_7) \ + $(am__objects_8) $(am__objects_9) sptps_speed_OBJECTS = $(am_sptps_speed_OBJECTS) sptps_speed_DEPENDENCIES = am__sptps_test_SOURCES_DIST = logger.c logger.h sptps.c sptps.h \ - sptps_test.c utils.c utils.h ed25519/add_scalar.c \ - ed25519/ed25519.h ed25519/fe.c ed25519/fe.h ed25519/fixedint.h \ - ed25519/ge.c ed25519/ge.h ed25519/key_exchange.c \ - ed25519/keypair.c ed25519/precomp_data.h ed25519/sc.c \ - ed25519/sc.h ed25519/sha512.c ed25519/sha512.h ed25519/sign.c \ + sptps_test.c utils.c utils.h ed25519/ecdh.c ed25519/ecdsa.c \ + ed25519/add_scalar.c ed25519/ed25519.h ed25519/fe.c \ + ed25519/fe.h ed25519/fixedint.h ed25519/ge.c ed25519/ge.h \ + ed25519/key_exchange.c ed25519/keypair.c \ + ed25519/precomp_data.h ed25519/sc.c ed25519/sc.h \ + ed25519/sha512.c ed25519/sha512.h ed25519/sign.c \ ed25519/verify.c chacha-poly1305/chacha.c \ chacha-poly1305/chacha.h chacha-poly1305/chacha-poly1305.c \ chacha-poly1305/chacha-poly1305.h chacha-poly1305/poly1305.c \ - chacha-poly1305/poly1305.h openssl/crypto.c openssl/digest.c \ - openssl/digest.h ed25519/ecdh.c ed25519/ecdsa.c openssl/prf.c \ - gcrypt/cipher.c gcrypt/crypto.c gcrypt/digest.c \ - gcrypt/digest.h gcrypt/ecdh.c gcrypt/ecdsa.c gcrypt/prf.c -@OPENSSL_TRUE@am__objects_5 = openssl/crypto.$(OBJEXT) \ -@OPENSSL_TRUE@ openssl/digest.$(OBJEXT) ed25519/ecdh.$(OBJEXT) \ -@OPENSSL_TRUE@ ed25519/ecdsa.$(OBJEXT) openssl/prf.$(OBJEXT) -@GCRYPT_TRUE@am__objects_6 = gcrypt/cipher.$(OBJEXT) \ -@GCRYPT_TRUE@ gcrypt/crypto.$(OBJEXT) gcrypt/digest.$(OBJEXT) \ -@GCRYPT_TRUE@ gcrypt/ecdh.$(OBJEXT) gcrypt/ecdsa.$(OBJEXT) \ -@GCRYPT_TRUE@ gcrypt/prf.$(OBJEXT) + chacha-poly1305/poly1305.h getopt.c getopt.h getopt1.c \ + openssl/crypto.c openssl/digest.c openssl/digest.h \ + openssl/prf.c gcrypt/cipher.c gcrypt/crypto.c gcrypt/digest.c \ + gcrypt/digest.h gcrypt/prf.c nolegacy/crypto.c nolegacy/prf.c +@GCRYPT_TRUE@@OPENSSL_FALSE@am__objects_10 = gcrypt/cipher.$(OBJEXT) \ +@GCRYPT_TRUE@@OPENSSL_FALSE@ gcrypt/crypto.$(OBJEXT) \ +@GCRYPT_TRUE@@OPENSSL_FALSE@ gcrypt/digest.$(OBJEXT) \ +@GCRYPT_TRUE@@OPENSSL_FALSE@ gcrypt/prf.$(OBJEXT) am_sptps_test_OBJECTS = logger.$(OBJEXT) sptps.$(OBJEXT) \ - sptps_test.$(OBJEXT) utils.$(OBJEXT) $(am__objects_1) \ - $(am__objects_3) $(am__objects_5) $(am__objects_6) + sptps_test.$(OBJEXT) utils.$(OBJEXT) ed25519/ecdh.$(OBJEXT) \ + ed25519/ecdsa.$(OBJEXT) $(am__objects_1) $(am__objects_6) \ + $(am__objects_2) $(am__objects_7) $(am__objects_10) \ + $(am__objects_9) sptps_test_OBJECTS = $(am_sptps_test_OBJECTS) sptps_test_LDADD = $(LDADD) -am__tinc_SOURCES_DIST = dropin.c dropin.h getopt.c getopt.h getopt1.c \ - info.c info.h invitation.c invitation.h list.c list.h names.c \ - names.h netutl.c netutl.h script.c script.h sptps.c sptps.h \ - subnet_parse.c subnet.h tincctl.c tincctl.h top.c top.h \ - utils.c utils.h version.c version.h ed25519/add_scalar.c \ +am__tinc_SOURCES_DIST = dropin.c dropin.h fsck.c fsck.h ifconfig.c \ + ifconfig.h info.c info.h invitation.c invitation.h list.c \ + list.h names.c names.h netutl.c netutl.h script.c script.h \ + sptps.c sptps.h subnet_parse.c subnet.h tincctl.c tincctl.h \ + top.c top.h utils.c utils.h version.c version.h ed25519/ecdh.c \ + ed25519/ecdsa.c ed25519/ecdsagen.c ed25519/add_scalar.c \ ed25519/ed25519.h ed25519/fe.c ed25519/fe.h ed25519/fixedint.h \ ed25519/ge.c ed25519/ge.h ed25519/key_exchange.c \ ed25519/keypair.c ed25519/precomp_data.h ed25519/sc.c \ @@ -257,30 +305,31 @@ am__tinc_SOURCES_DIST = dropin.c dropin.h getopt.c getopt.h getopt1.c \ ed25519/verify.c chacha-poly1305/chacha.c \ chacha-poly1305/chacha.h chacha-poly1305/chacha-poly1305.c \ chacha-poly1305/chacha-poly1305.h chacha-poly1305/poly1305.c \ - chacha-poly1305/poly1305.h openssl/cipher.c openssl/crypto.c \ - openssl/digest.c openssl/digest.h ed25519/ecdh.c \ - ed25519/ecdsa.c ed25519/ecdsagen.c openssl/prf.c openssl/rsa.c \ - openssl/rsagen.c gcrypt/cipher.c gcrypt/crypto.c \ - gcrypt/digest.c gcrypt/digest.h gcrypt/ecdh.c gcrypt/ecdsa.c \ - gcrypt/ecdsagen.c gcrypt/prf.c gcrypt/rsa.c gcrypt/rsagen.c -@OPENSSL_TRUE@am__objects_7 = openssl/cipher.$(OBJEXT) \ + chacha-poly1305/poly1305.h getopt.c getopt.h getopt1.c \ + openssl/cipher.c openssl/crypto.c openssl/digest.c \ + openssl/digest.h openssl/prf.c openssl/rsa.c openssl/rsagen.c \ + gcrypt/cipher.c gcrypt/crypto.c gcrypt/digest.c \ + gcrypt/digest.h gcrypt/prf.c gcrypt/rsa.c gcrypt/rsagen.c \ + nolegacy/crypto.c nolegacy/prf.c +@OPENSSL_TRUE@am__objects_11 = openssl/cipher.$(OBJEXT) \ @OPENSSL_TRUE@ openssl/crypto.$(OBJEXT) \ -@OPENSSL_TRUE@ openssl/digest.$(OBJEXT) ed25519/ecdh.$(OBJEXT) \ -@OPENSSL_TRUE@ ed25519/ecdsa.$(OBJEXT) \ -@OPENSSL_TRUE@ ed25519/ecdsagen.$(OBJEXT) openssl/prf.$(OBJEXT) \ +@OPENSSL_TRUE@ openssl/digest.$(OBJEXT) openssl/prf.$(OBJEXT) \ @OPENSSL_TRUE@ openssl/rsa.$(OBJEXT) openssl/rsagen.$(OBJEXT) -@GCRYPT_TRUE@am__objects_8 = gcrypt/cipher.$(OBJEXT) \ -@GCRYPT_TRUE@ gcrypt/crypto.$(OBJEXT) gcrypt/digest.$(OBJEXT) \ -@GCRYPT_TRUE@ gcrypt/ecdh.$(OBJEXT) gcrypt/ecdsa.$(OBJEXT) \ -@GCRYPT_TRUE@ gcrypt/ecdsagen.$(OBJEXT) gcrypt/prf.$(OBJEXT) \ -@GCRYPT_TRUE@ gcrypt/rsa.$(OBJEXT) gcrypt/rsagen.$(OBJEXT) -am_tinc_OBJECTS = dropin.$(OBJEXT) getopt.$(OBJEXT) getopt1.$(OBJEXT) \ +@GCRYPT_TRUE@@OPENSSL_FALSE@am__objects_12 = gcrypt/cipher.$(OBJEXT) \ +@GCRYPT_TRUE@@OPENSSL_FALSE@ gcrypt/crypto.$(OBJEXT) \ +@GCRYPT_TRUE@@OPENSSL_FALSE@ gcrypt/digest.$(OBJEXT) \ +@GCRYPT_TRUE@@OPENSSL_FALSE@ gcrypt/prf.$(OBJEXT) \ +@GCRYPT_TRUE@@OPENSSL_FALSE@ gcrypt/rsa.$(OBJEXT) \ +@GCRYPT_TRUE@@OPENSSL_FALSE@ gcrypt/rsagen.$(OBJEXT) +am_tinc_OBJECTS = dropin.$(OBJEXT) fsck.$(OBJEXT) ifconfig.$(OBJEXT) \ info.$(OBJEXT) invitation.$(OBJEXT) list.$(OBJEXT) \ names.$(OBJEXT) netutl.$(OBJEXT) script.$(OBJEXT) \ sptps.$(OBJEXT) subnet_parse.$(OBJEXT) tincctl.$(OBJEXT) \ top.$(OBJEXT) utils.$(OBJEXT) version.$(OBJEXT) \ - $(am__objects_1) $(am__objects_3) $(am__objects_7) \ - $(am__objects_8) + ed25519/ecdh.$(OBJEXT) ed25519/ecdsa.$(OBJEXT) \ + ed25519/ecdsagen.$(OBJEXT) $(am__objects_1) $(am__objects_6) \ + $(am__objects_2) $(am__objects_11) $(am__objects_12) \ + $(am__objects_9) tinc_OBJECTS = $(am_tinc_OBJECTS) am__DEPENDENCIES_1 = tinc_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) @@ -288,73 +337,74 @@ am__tincd_SOURCES_DIST = buffer.c buffer.h cipher.h conf.c conf.h \ connection.c connection.h control.c control.h control_common.h \ crypto.h device.h digest.h dropin.c dropin.h dummy_device.c \ ecdh.h ecdsa.h ecdsagen.h edge.c edge.h ethernet.h event.c \ - event.h fake-gai-errnos.h fake-getaddrinfo.c \ - fake-getaddrinfo.h fake-getnameinfo.c fake-getnameinfo.h \ - getopt.c getopt.h getopt1.c graph.c graph.h hash.c hash.h \ - have.h ipv4.h ipv6.h list.c list.h logger.c logger.h meta.c \ - meta.h multicast_device.c names.c names.h net.c net.h \ - net_packet.c net_setup.c net_socket.c netutl.c netutl.h node.c \ - node.h prf.h process.c process.h protocol.c protocol.h \ - protocol_auth.c protocol_edge.c protocol_key.c protocol_misc.c \ + event.h graph.c graph.h hash.c hash.h have.h ipv4.h ipv6.h \ + list.c list.h logger.c logger.h meta.c meta.h \ + multicast_device.c names.c names.h net.c net.h net_packet.c \ + net_setup.c net_socket.c netutl.c netutl.h node.c node.h prf.h \ + process.c process.h protocol.c protocol.h protocol_auth.c \ + protocol_edge.c protocol_key.c protocol_misc.c \ protocol_subnet.c raw_socket_device.c route.c route.h rsa.h \ rsagen.h script.c script.h splay_tree.c splay_tree.h sptps.c \ sptps.h subnet.c subnet.h subnet_parse.c system.h tincd.c \ - utils.c utils.h xalloc.h version.c version.h \ - ed25519/add_scalar.c ed25519/ed25519.h ed25519/fe.c \ - ed25519/fe.h ed25519/fixedint.h ed25519/ge.c ed25519/ge.h \ - ed25519/key_exchange.c ed25519/keypair.c \ + utils.c utils.h xalloc.h version.c version.h ed25519/ecdh.c \ + ed25519/ecdsa.c ed25519/add_scalar.c ed25519/ed25519.h \ + ed25519/fe.c ed25519/fe.h ed25519/fixedint.h ed25519/ge.c \ + ed25519/ge.h ed25519/key_exchange.c ed25519/keypair.c \ ed25519/precomp_data.h ed25519/sc.c ed25519/sc.h \ ed25519/sha512.c ed25519/sha512.h ed25519/sign.c \ ed25519/verify.c chacha-poly1305/chacha.c \ chacha-poly1305/chacha.h chacha-poly1305/chacha-poly1305.c \ chacha-poly1305/chacha-poly1305.h chacha-poly1305/poly1305.c \ - chacha-poly1305/poly1305.h linux/device.c bsd/device.c \ - bsd/tunemu.c bsd/tunemu.h solaris/device.c mingw/device.c \ - mingw/common.h cygwin/device.c uml_device.c vde_device.c \ - openssl/cipher.c openssl/crypto.c openssl/digest.c \ - openssl/digest.h ed25519/ecdh.c ed25519/ecdsa.c openssl/prf.c \ - openssl/rsa.c gcrypt/cipher.c gcrypt/crypto.c gcrypt/digest.c \ - gcrypt/digest.h gcrypt/ecdh.c gcrypt/ecdsa.c gcrypt/prf.c \ - gcrypt/rsa.c -@LINUX_TRUE@am__objects_9 = linux/device.$(OBJEXT) -@BSD_TRUE@am__objects_10 = bsd/device.$(OBJEXT) -@BSD_TRUE@@TUNEMU_TRUE@am__objects_11 = bsd/tunemu.$(OBJEXT) -@SOLARIS_TRUE@am__objects_12 = solaris/device.$(OBJEXT) -@MINGW_TRUE@am__objects_13 = mingw/device.$(OBJEXT) -@CYGWIN_TRUE@am__objects_14 = cygwin/device.$(OBJEXT) -@UML_TRUE@am__objects_15 = uml_device.$(OBJEXT) -@VDE_TRUE@am__objects_16 = vde_device.$(OBJEXT) -@OPENSSL_TRUE@am__objects_17 = openssl/cipher.$(OBJEXT) \ + chacha-poly1305/poly1305.h getopt.c getopt.h getopt1.c \ + linux/device.c bsd/device.c bsd/tunemu.c bsd/tunemu.h \ + solaris/device.c mingw/device.c mingw/common.h cygwin/device.c \ + uml_device.c vde_device.c openssl/cipher.c openssl/crypto.c \ + openssl/digest.c openssl/digest.h openssl/prf.c openssl/rsa.c \ + gcrypt/cipher.c gcrypt/crypto.c gcrypt/digest.c \ + gcrypt/digest.h gcrypt/prf.c gcrypt/rsa.c nolegacy/crypto.c \ + nolegacy/prf.c upnp.h upnp.c +@LINUX_TRUE@am__objects_13 = linux/device.$(OBJEXT) +@BSD_TRUE@am__objects_14 = bsd/device.$(OBJEXT) +@BSD_TRUE@@TUNEMU_TRUE@am__objects_15 = bsd/tunemu.$(OBJEXT) +@SOLARIS_TRUE@am__objects_16 = solaris/device.$(OBJEXT) +@MINGW_TRUE@am__objects_17 = mingw/device.$(OBJEXT) +@CYGWIN_TRUE@am__objects_18 = cygwin/device.$(OBJEXT) +@UML_TRUE@am__objects_19 = uml_device.$(OBJEXT) +@VDE_TRUE@am__objects_20 = vde_device.$(OBJEXT) +@OPENSSL_TRUE@am__objects_21 = openssl/cipher.$(OBJEXT) \ @OPENSSL_TRUE@ openssl/crypto.$(OBJEXT) \ -@OPENSSL_TRUE@ openssl/digest.$(OBJEXT) ed25519/ecdh.$(OBJEXT) \ -@OPENSSL_TRUE@ ed25519/ecdsa.$(OBJEXT) openssl/prf.$(OBJEXT) \ +@OPENSSL_TRUE@ openssl/digest.$(OBJEXT) openssl/prf.$(OBJEXT) \ @OPENSSL_TRUE@ openssl/rsa.$(OBJEXT) -@GCRYPT_TRUE@am__objects_18 = gcrypt/cipher.$(OBJEXT) \ -@GCRYPT_TRUE@ gcrypt/crypto.$(OBJEXT) gcrypt/digest.$(OBJEXT) \ -@GCRYPT_TRUE@ gcrypt/ecdh.$(OBJEXT) gcrypt/ecdsa.$(OBJEXT) \ -@GCRYPT_TRUE@ gcrypt/prf.$(OBJEXT) gcrypt/rsa.$(OBJEXT) +@GCRYPT_TRUE@@OPENSSL_FALSE@am__objects_22 = gcrypt/cipher.$(OBJEXT) \ +@GCRYPT_TRUE@@OPENSSL_FALSE@ gcrypt/crypto.$(OBJEXT) \ +@GCRYPT_TRUE@@OPENSSL_FALSE@ gcrypt/digest.$(OBJEXT) \ +@GCRYPT_TRUE@@OPENSSL_FALSE@ gcrypt/prf.$(OBJEXT) \ +@GCRYPT_TRUE@@OPENSSL_FALSE@ gcrypt/rsa.$(OBJEXT) +@MINIUPNPC_TRUE@am__objects_23 = upnp.$(OBJEXT) am_tincd_OBJECTS = buffer.$(OBJEXT) conf.$(OBJEXT) \ connection.$(OBJEXT) control.$(OBJEXT) dropin.$(OBJEXT) \ dummy_device.$(OBJEXT) edge.$(OBJEXT) event.$(OBJEXT) \ - fake-getaddrinfo.$(OBJEXT) fake-getnameinfo.$(OBJEXT) \ - getopt.$(OBJEXT) getopt1.$(OBJEXT) graph.$(OBJEXT) \ - hash.$(OBJEXT) list.$(OBJEXT) logger.$(OBJEXT) meta.$(OBJEXT) \ - multicast_device.$(OBJEXT) names.$(OBJEXT) net.$(OBJEXT) \ - net_packet.$(OBJEXT) net_setup.$(OBJEXT) net_socket.$(OBJEXT) \ - netutl.$(OBJEXT) node.$(OBJEXT) process.$(OBJEXT) \ - protocol.$(OBJEXT) protocol_auth.$(OBJEXT) \ + graph.$(OBJEXT) hash.$(OBJEXT) list.$(OBJEXT) logger.$(OBJEXT) \ + meta.$(OBJEXT) multicast_device.$(OBJEXT) names.$(OBJEXT) \ + net.$(OBJEXT) net_packet.$(OBJEXT) net_setup.$(OBJEXT) \ + net_socket.$(OBJEXT) netutl.$(OBJEXT) node.$(OBJEXT) \ + process.$(OBJEXT) protocol.$(OBJEXT) protocol_auth.$(OBJEXT) \ protocol_edge.$(OBJEXT) protocol_key.$(OBJEXT) \ protocol_misc.$(OBJEXT) protocol_subnet.$(OBJEXT) \ raw_socket_device.$(OBJEXT) route.$(OBJEXT) script.$(OBJEXT) \ splay_tree.$(OBJEXT) sptps.$(OBJEXT) subnet.$(OBJEXT) \ subnet_parse.$(OBJEXT) tincd.$(OBJEXT) utils.$(OBJEXT) \ - version.$(OBJEXT) $(am__objects_1) $(am__objects_3) \ - $(am__objects_9) $(am__objects_10) $(am__objects_11) \ - $(am__objects_12) $(am__objects_13) $(am__objects_14) \ + version.$(OBJEXT) ed25519/ecdh.$(OBJEXT) \ + ed25519/ecdsa.$(OBJEXT) $(am__objects_1) $(am__objects_6) \ + $(am__objects_2) $(am__objects_13) $(am__objects_14) \ $(am__objects_15) $(am__objects_16) $(am__objects_17) \ - $(am__objects_18) + $(am__objects_18) $(am__objects_19) $(am__objects_20) \ + $(am__objects_21) $(am__objects_22) $(am__objects_9) \ + $(am__objects_23) tincd_OBJECTS = $(am_tincd_OBJECTS) -tincd_LDADD = $(LDADD) +@MINIUPNPC_TRUE@tincd_DEPENDENCIES = $(am__DEPENDENCIES_1) +tincd_LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(tincd_LDFLAGS) \ + $(LDFLAGS) -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false @@ -367,6 +417,7 @@ AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = +DEFAULT_INCLUDES = depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f @@ -411,6 +462,7 @@ am__define_uniq_tagged_files = \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ @@ -441,10 +493,11 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ -LIBS = @LIBS@ $(am__append_18) +LIBS = @LIBS@ -lm $(am__append_30) LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ +MINIUPNPC_LIBS = @MINIUPNPC_LIBS@ MKDIR_P = @MKDIR_P@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ @@ -502,15 +555,17 @@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ +runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ +systemd_path = @systemd_path@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ -DEFAULT_INCLUDES = +CLEANFILES = version_git.h ed25519_SOURCES = \ ed25519/add_scalar.c \ ed25519/ed25519.h \ @@ -534,39 +589,47 @@ tincd_SOURCES = buffer.c buffer.h cipher.h conf.c conf.h connection.c \ connection.h control.c control.h control_common.h crypto.h \ device.h digest.h dropin.c dropin.h dummy_device.c ecdh.h \ ecdsa.h ecdsagen.h edge.c edge.h ethernet.h event.c event.h \ - fake-gai-errnos.h fake-getaddrinfo.c fake-getaddrinfo.h \ - fake-getnameinfo.c fake-getnameinfo.h getopt.c getopt.h \ - getopt1.c graph.c graph.h hash.c hash.h have.h ipv4.h ipv6.h \ - list.c list.h logger.c logger.h meta.c meta.h \ - multicast_device.c names.c names.h net.c net.h net_packet.c \ - net_setup.c net_socket.c netutl.c netutl.h node.c node.h prf.h \ - process.c process.h protocol.c protocol.h protocol_auth.c \ + graph.c graph.h hash.c hash.h have.h ipv4.h ipv6.h list.c \ + list.h logger.c logger.h meta.c meta.h multicast_device.c \ + names.c names.h net.c net.h net_packet.c net_setup.c \ + net_socket.c netutl.c netutl.h node.c node.h prf.h process.c \ + process.h protocol.c protocol.h protocol_auth.c \ protocol_edge.c protocol_key.c protocol_misc.c \ protocol_subnet.c raw_socket_device.c route.c route.h rsa.h \ rsagen.h script.c script.h splay_tree.c splay_tree.h sptps.c \ sptps.h subnet.c subnet.h subnet_parse.c system.h tincd.c \ - utils.c utils.h xalloc.h version.c version.h \ - $(ed25519_SOURCES) $(chacha_poly1305_SOURCES) $(am__append_2) \ - $(am__append_3) $(am__append_4) $(am__append_5) \ - $(am__append_6) $(am__append_7) $(am__append_8) \ - $(am__append_9) $(am__append_10) $(am__append_15) -tinc_SOURCES = dropin.c dropin.h getopt.c getopt.h getopt1.c info.c \ - info.h invitation.c invitation.h list.c list.h names.c names.h \ - netutl.c netutl.h script.c script.h sptps.c sptps.h \ + utils.c utils.h xalloc.h version.c version.h ed25519/ecdh.c \ + ed25519/ecdsa.c $(ed25519_SOURCES) $(chacha_poly1305_SOURCES) \ + $(am__append_2) $(am__append_6) $(am__append_7) \ + $(am__append_8) $(am__append_9) $(am__append_10) \ + $(am__append_11) $(am__append_12) $(am__append_13) \ + $(am__append_14) $(am__append_19) $(am__append_24) \ + $(am__append_29) +tinc_SOURCES = dropin.c dropin.h fsck.c fsck.h ifconfig.c ifconfig.h \ + info.c info.h invitation.c invitation.h list.c list.h names.c \ + names.h netutl.c netutl.h script.c script.h sptps.c sptps.h \ subnet_parse.c subnet.h tincctl.c tincctl.h top.c top.h \ - utils.c utils.h version.c version.h $(ed25519_SOURCES) \ - $(chacha_poly1305_SOURCES) $(am__append_11) $(am__append_16) + utils.c utils.h version.c version.h ed25519/ecdh.c \ + ed25519/ecdsa.c ed25519/ecdsagen.c $(ed25519_SOURCES) \ + $(chacha_poly1305_SOURCES) $(am__append_3) $(am__append_15) \ + $(am__append_20) $(am__append_25) sptps_test_SOURCES = logger.c logger.h sptps.c sptps.h sptps_test.c \ - utils.c utils.h $(ed25519_SOURCES) $(chacha_poly1305_SOURCES) \ - $(am__append_12) $(am__append_17) + utils.c utils.h ed25519/ecdh.c ed25519/ecdsa.c \ + $(ed25519_SOURCES) $(chacha_poly1305_SOURCES) $(am__append_4) \ + $(am__append_16) $(am__append_21) $(am__append_26) sptps_keypair_SOURCES = sptps_keypair.c utils.c utils.h \ - $(ed25519_SOURCES) $(am__append_13) + ed25519/ecdsagen.c $(ed25519_SOURCES) $(am__append_5) \ + $(am__append_17) $(am__append_22) $(am__append_27) sptps_speed_SOURCES = logger.c logger.h sptps.c sptps.h sptps_speed.c \ - utils.c utils.h $(ed25519_SOURCES) $(chacha_poly1305_SOURCES) \ - $(am__append_14) + utils.c utils.h ed25519/ecdh.c ed25519/ecdsa.c \ + ed25519/ecdsagen.c $(ed25519_SOURCES) \ + $(chacha_poly1305_SOURCES) $(am__append_18) $(am__append_23) \ + $(am__append_28) +@MINIUPNPC_TRUE@tincd_LDADD = $(MINIUPNPC_LIBS) +@MINIUPNPC_TRUE@tincd_LDFLAGS = -pthread tinc_LDADD = $(READLINE_LIBS) $(CURSES_LIBS) sptps_speed_LDADD = -lrt -AM_CFLAGS = -DCONFDIR=\"$(sysconfdir)\" -DLOCALSTATEDIR=\"$(localstatedir)\" -DSBINDIR=\"$(sbindir)\" +AM_CFLAGS = -DCONFDIR=\"$(sysconfdir)\" -DLOCALSTATEDIR=\"$(localstatedir)\" -DSBINDIR=\"$(sbindir)\" -iquote. all: all-am .SUFFIXES: @@ -583,7 +646,6 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu src/Makefile -.PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ @@ -665,6 +727,8 @@ ed25519/$(am__dirstamp): ed25519/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) ed25519/$(DEPDIR) @: > ed25519/$(DEPDIR)/$(am__dirstamp) +ed25519/ecdsagen.$(OBJEXT): ed25519/$(am__dirstamp) \ + ed25519/$(DEPDIR)/$(am__dirstamp) ed25519/add_scalar.$(OBJEXT): ed25519/$(am__dirstamp) \ ed25519/$(DEPDIR)/$(am__dirstamp) ed25519/fe.$(OBJEXT): ed25519/$(am__dirstamp) \ @@ -691,12 +755,22 @@ openssl/$(DEPDIR)/$(am__dirstamp): @: > openssl/$(DEPDIR)/$(am__dirstamp) openssl/crypto.$(OBJEXT): openssl/$(am__dirstamp) \ openssl/$(DEPDIR)/$(am__dirstamp) -ed25519/ecdsagen.$(OBJEXT): ed25519/$(am__dirstamp) \ - ed25519/$(DEPDIR)/$(am__dirstamp) +nolegacy/$(am__dirstamp): + @$(MKDIR_P) nolegacy + @: > nolegacy/$(am__dirstamp) +nolegacy/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) nolegacy/$(DEPDIR) + @: > nolegacy/$(DEPDIR)/$(am__dirstamp) +nolegacy/crypto.$(OBJEXT): nolegacy/$(am__dirstamp) \ + nolegacy/$(DEPDIR)/$(am__dirstamp) sptps_keypair$(EXEEXT): $(sptps_keypair_OBJECTS) $(sptps_keypair_DEPENDENCIES) $(EXTRA_sptps_keypair_DEPENDENCIES) @rm -f sptps_keypair$(EXEEXT) $(AM_V_CCLD)$(LINK) $(sptps_keypair_OBJECTS) $(sptps_keypair_LDADD) $(LIBS) +ed25519/ecdh.$(OBJEXT): ed25519/$(am__dirstamp) \ + ed25519/$(DEPDIR)/$(am__dirstamp) +ed25519/ecdsa.$(OBJEXT): ed25519/$(am__dirstamp) \ + ed25519/$(DEPDIR)/$(am__dirstamp) chacha-poly1305/$(am__dirstamp): @$(MKDIR_P) chacha-poly1305 @: > chacha-poly1305/$(am__dirstamp) @@ -712,12 +786,10 @@ chacha-poly1305/poly1305.$(OBJEXT): chacha-poly1305/$(am__dirstamp) \ chacha-poly1305/$(DEPDIR)/$(am__dirstamp) openssl/digest.$(OBJEXT): openssl/$(am__dirstamp) \ openssl/$(DEPDIR)/$(am__dirstamp) -ed25519/ecdh.$(OBJEXT): ed25519/$(am__dirstamp) \ - ed25519/$(DEPDIR)/$(am__dirstamp) -ed25519/ecdsa.$(OBJEXT): ed25519/$(am__dirstamp) \ - ed25519/$(DEPDIR)/$(am__dirstamp) openssl/prf.$(OBJEXT): openssl/$(am__dirstamp) \ openssl/$(DEPDIR)/$(am__dirstamp) +nolegacy/prf.$(OBJEXT): nolegacy/$(am__dirstamp) \ + nolegacy/$(DEPDIR)/$(am__dirstamp) sptps_speed$(EXEEXT): $(sptps_speed_OBJECTS) $(sptps_speed_DEPENDENCIES) $(EXTRA_sptps_speed_DEPENDENCIES) @rm -f sptps_speed$(EXEEXT) @@ -734,10 +806,6 @@ gcrypt/crypto.$(OBJEXT): gcrypt/$(am__dirstamp) \ gcrypt/$(DEPDIR)/$(am__dirstamp) gcrypt/digest.$(OBJEXT): gcrypt/$(am__dirstamp) \ gcrypt/$(DEPDIR)/$(am__dirstamp) -gcrypt/ecdh.$(OBJEXT): gcrypt/$(am__dirstamp) \ - gcrypt/$(DEPDIR)/$(am__dirstamp) -gcrypt/ecdsa.$(OBJEXT): gcrypt/$(am__dirstamp) \ - gcrypt/$(DEPDIR)/$(am__dirstamp) gcrypt/prf.$(OBJEXT): gcrypt/$(am__dirstamp) \ gcrypt/$(DEPDIR)/$(am__dirstamp) @@ -750,8 +818,6 @@ openssl/rsa.$(OBJEXT): openssl/$(am__dirstamp) \ openssl/$(DEPDIR)/$(am__dirstamp) openssl/rsagen.$(OBJEXT): openssl/$(am__dirstamp) \ openssl/$(DEPDIR)/$(am__dirstamp) -gcrypt/ecdsagen.$(OBJEXT): gcrypt/$(am__dirstamp) \ - gcrypt/$(DEPDIR)/$(am__dirstamp) gcrypt/rsa.$(OBJEXT): gcrypt/$(am__dirstamp) \ gcrypt/$(DEPDIR)/$(am__dirstamp) gcrypt/rsagen.$(OBJEXT): gcrypt/$(am__dirstamp) \ @@ -805,7 +871,7 @@ cygwin/device.$(OBJEXT): cygwin/$(am__dirstamp) \ tincd$(EXEEXT): $(tincd_OBJECTS) $(tincd_DEPENDENCIES) $(EXTRA_tincd_DEPENDENCIES) @rm -f tincd$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(tincd_OBJECTS) $(tincd_LDADD) $(LIBS) + $(AM_V_CCLD)$(tincd_LINK) $(tincd_OBJECTS) $(tincd_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) @@ -816,6 +882,7 @@ mostlyclean-compile: -rm -f gcrypt/*.$(OBJEXT) -rm -f linux/*.$(OBJEXT) -rm -f mingw/*.$(OBJEXT) + -rm -f nolegacy/*.$(OBJEXT) -rm -f openssl/*.$(OBJEXT) -rm -f solaris/*.$(OBJEXT) @@ -830,12 +897,12 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dummy_device.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/edge.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/event.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fake-getaddrinfo.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fake-getnameinfo.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fsck.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getopt.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getopt1.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/graph.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hash.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ifconfig.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/info.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/invitation.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/list.Po@am__quote@ @@ -870,6 +937,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tincd.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/top.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uml_device.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/upnp.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/utils.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vde_device.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/version.Po@am__quote@ @@ -894,14 +962,13 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@gcrypt/$(DEPDIR)/cipher.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@gcrypt/$(DEPDIR)/crypto.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@gcrypt/$(DEPDIR)/digest.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@gcrypt/$(DEPDIR)/ecdh.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@gcrypt/$(DEPDIR)/ecdsa.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@gcrypt/$(DEPDIR)/ecdsagen.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@gcrypt/$(DEPDIR)/prf.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@gcrypt/$(DEPDIR)/rsa.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@gcrypt/$(DEPDIR)/rsagen.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@linux/$(DEPDIR)/device.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@mingw/$(DEPDIR)/device.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@nolegacy/$(DEPDIR)/crypto.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@nolegacy/$(DEPDIR)/prf.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@openssl/$(DEPDIR)/cipher.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@openssl/$(DEPDIR)/crypto.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@openssl/$(DEPDIR)/digest.Po@am__quote@ @@ -1037,6 +1104,7 @@ install-strip: mostlyclean-generic: clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) @@ -1055,6 +1123,8 @@ distclean-generic: -rm -f linux/$(am__dirstamp) -rm -f mingw/$(DEPDIR)/$(am__dirstamp) -rm -f mingw/$(am__dirstamp) + -rm -f nolegacy/$(DEPDIR)/$(am__dirstamp) + -rm -f nolegacy/$(am__dirstamp) -rm -f openssl/$(DEPDIR)/$(am__dirstamp) -rm -f openssl/$(am__dirstamp) -rm -f solaris/$(DEPDIR)/$(am__dirstamp) @@ -1068,7 +1138,7 @@ clean: clean-am clean-am: clean-generic clean-sbinPROGRAMS mostlyclean-am distclean: distclean-am - -rm -rf ./$(DEPDIR) bsd/$(DEPDIR) chacha-poly1305/$(DEPDIR) cygwin/$(DEPDIR) ed25519/$(DEPDIR) gcrypt/$(DEPDIR) linux/$(DEPDIR) mingw/$(DEPDIR) openssl/$(DEPDIR) solaris/$(DEPDIR) + -rm -rf ./$(DEPDIR) bsd/$(DEPDIR) chacha-poly1305/$(DEPDIR) cygwin/$(DEPDIR) ed25519/$(DEPDIR) gcrypt/$(DEPDIR) linux/$(DEPDIR) mingw/$(DEPDIR) nolegacy/$(DEPDIR) openssl/$(DEPDIR) solaris/$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags @@ -1114,7 +1184,7 @@ install-ps-am: installcheck-am: installcheck-sbinPROGRAMS maintainer-clean: maintainer-clean-am - -rm -rf ./$(DEPDIR) bsd/$(DEPDIR) chacha-poly1305/$(DEPDIR) cygwin/$(DEPDIR) ed25519/$(DEPDIR) gcrypt/$(DEPDIR) linux/$(DEPDIR) mingw/$(DEPDIR) openssl/$(DEPDIR) solaris/$(DEPDIR) + -rm -rf ./$(DEPDIR) bsd/$(DEPDIR) chacha-poly1305/$(DEPDIR) cygwin/$(DEPDIR) ed25519/$(DEPDIR) gcrypt/$(DEPDIR) linux/$(DEPDIR) mingw/$(DEPDIR) nolegacy/$(DEPDIR) openssl/$(DEPDIR) solaris/$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic @@ -1148,9 +1218,18 @@ uninstall-am: uninstall-sbinPROGRAMS mostlyclean-generic pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-sbinPROGRAMS +.PRECIOUS: Makefile -.PHONY: version.c -version.c: + +.PHONY: version-stamp +version-stamp: + +version_git.h: version-stamp + $(AM_V_GEN)echo >$@ + @-(cd $(srcdir) && git describe 2>/dev/null >/dev/null) && echo '#define GIT_DESCRIPTION "'`(cd $(srcdir) && git describe) | sed 's/release-//'`'"' >$@ ||: +${srcdir}/version.c: version_git.h + +@BSD_TRUE@version.c: ${srcdir}/version.c # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. diff --git a/src/bsd/device.c b/src/bsd/device.c index d1a993b..0d41c96 100644 --- a/src/bsd/device.c +++ b/src/bsd/device.c @@ -1,7 +1,7 @@ /* device.c -- Interaction BSD tun/tap device Copyright (C) 2001-2005 Ivo Timmermans, - 2001-2014 Guus Sliepen + 2001-2016 Guus Sliepen 2009 Grzegorz Dymarek This program is free software; you can redistribute it and/or modify @@ -34,13 +34,15 @@ #include "bsd/tunemu.h" #endif -#define DEFAULT_TUN_DEVICE "/dev/tun0" -#if defined(HAVE_DARWIN) || defined(HAVE_FREEBSD) || defined(HAVE_NETBSD) -#define DEFAULT_TAP_DEVICE "/dev/tap0" -#else -#define DEFAULT_TAP_DEVICE "/dev/tun0" +#ifdef HAVE_NET_IF_UTUN_H +#include +#include +#include #endif +#define DEFAULT_TUN_DEVICE "/dev/tun0" +#define DEFAULT_TAP_DEVICE "/dev/tap0" + typedef enum device_type { DEVICE_TYPE_TUN, DEVICE_TYPE_TUNIFHEAD, @@ -48,6 +50,7 @@ typedef enum device_type { #ifdef ENABLE_TUNEMU DEVICE_TYPE_TUNEMU, #endif + DEVICE_TYPE_UTUN, } device_type_t; int device_fd = -1; @@ -62,9 +65,64 @@ static device_type_t device_type = DEVICE_TYPE_TUNIFHEAD; static device_type_t device_type = DEVICE_TYPE_TUN; #endif +#ifdef HAVE_NET_IF_UTUN_H +static bool setup_utun(void) { + device_fd = socket(PF_SYSTEM, SOCK_DGRAM, SYSPROTO_CONTROL); + if(device_fd == -1) { + logger(DEBUG_ALWAYS, LOG_ERR, "Could not open PF_SYSTEM socket: %s\n", strerror(errno)); + return false; + } + + struct ctl_info info = {}; + strlcpy(info.ctl_name, UTUN_CONTROL_NAME, sizeof info.ctl_name); + + if(ioctl(device_fd, CTLIOCGINFO, &info) == -1) { + logger(DEBUG_ALWAYS, LOG_ERR, "ioctl(CTLIOCGINFO) failed: %s", strerror(errno)); + return false; + } + + int unit = -1; + char *p = strstr(device, "utun"), *e = NULL; + if(p) { + unit = strtol(p + 4, &e, 10); + if(!e) + unit = -1; + } + + struct sockaddr_ctl sc = { + .sc_id = info.ctl_id, + .sc_len = sizeof sc, + .sc_family = AF_SYSTEM, + .ss_sysaddr = AF_SYS_CONTROL, + .sc_unit = unit + 1, + }; + + if(connect(device_fd, (struct sockaddr *)&sc, sizeof(sc)) == -1) { + logger(DEBUG_ALWAYS, LOG_ERR, "Could not connect utun socket: %s\n", strerror(errno)); + return false; + } + + char name[64] = ""; + socklen_t len = sizeof name; + if(getsockopt(device_fd, SYSPROTO_CONTROL, UTUN_OPT_IFNAME, name, &len)) { + iface = xstrdup(device); + } else { + iface = xstrdup(name); + } + + device_info = "OS X utun device"; + + logger(DEBUG_ALWAYS, LOG_INFO, "%s is a %s", device, device_info); + + return true; +} +#endif + static bool setup_device(void) { get_config_string(lookup_config(config_tree, "Device"), &device); + // Find out if it's supposed to be a tun or a tap device + char *type; if(get_config_string(lookup_config(config_tree, "DeviceType"), &type)) { if(!strcasecmp(type, "tun")) @@ -72,6 +130,10 @@ static bool setup_device(void) { #ifdef ENABLE_TUNEMU else if(!strcasecmp(type, "tunemu")) device_type = DEVICE_TYPE_TUNEMU; +#endif +#ifdef HAVE_NET_IF_UTUN_H + else if(!strcasecmp(type, "utun")) + device_type = DEVICE_TYPE_UTUN; #endif else if(!strcasecmp(type, "tunnohead")) device_type = DEVICE_TYPE_TUN; @@ -84,10 +146,22 @@ static bool setup_device(void) { return false; } } else { +#ifdef HAVE_NET_IF_UTUN_H + if(device && (strncmp(device, "utun", 4) == 0 || strncmp(device, "/dev/utun", 9) == 0)) + device_type = DEVICE_TYPE_UTUN; + else +#endif if((device && strstr(device, "tap")) || routing_mode != RMODE_ROUTER) device_type = DEVICE_TYPE_TAP; } + if(routing_mode == RMODE_SWITCH && device_type != DEVICE_TYPE_TAP) { + logger(DEBUG_ALWAYS, LOG_ERR, "Only tap devices support switch mode!"); + return false; + } + + // Find out which device file to open + if(!device) { if(device_type == DEVICE_TYPE_TAP) device = xstrdup(DEFAULT_TAP_DEVICE); @@ -95,17 +169,7 @@ static bool setup_device(void) { device = xstrdup(DEFAULT_TUN_DEVICE); } - if(!get_config_string(lookup_config(config_tree, "Interface"), &iface)) - iface = NULL; -#ifndef TAPGIFNAME - if (iface) { - logger(DEBUG_ALWAYS, LOG_WARNING, "Ignoring specified interface name '%s' as device rename is not supported on this platform", iface); - free(iface); - iface = NULL; - } -#endif - if (!iface) - iface = xstrdup(strrchr(device, '/') ? strrchr(device, '/') + 1 : device); + // Open the device switch(device_type) { #ifdef ENABLE_TUNEMU @@ -114,6 +178,10 @@ static bool setup_device(void) { device_fd = tunemu_open(dynamic_name); } break; +#endif +#ifdef HAVE_NET_IF_UTUN_H + case DEVICE_TYPE_UTUN: + return setup_utun(); #endif default: device_fd = open(device, O_RDWR | O_NONBLOCK); @@ -128,6 +196,27 @@ static bool setup_device(void) { fcntl(device_fd, F_SETFD, FD_CLOEXEC); #endif + // Guess what the corresponding interface is called + + char *realname; + +#if defined(HAVE_FDEVNAME) + realname = fdevname(device_fd) ? : device; +#elif defined(HAVE_DEVNAME) + struct stat buf; + if(!fstat(device_fd, &buf)) + realname = devname(buf.st_rdev, S_IFCHR) ? : device; +#else + realname = device; +#endif + + if(!get_config_string(lookup_config(config_tree, "Interface"), &iface)) + iface = xstrdup(strrchr(realname, '/') ? strrchr(realname, '/') + 1 : realname); + else if(strcmp(iface, strrchr(realname, '/') ? strrchr(realname, '/') + 1 : realname)) + logger(DEBUG_ALWAYS, LOG_WARNING, "Warning: Interface does not match Device. $INTERFACE might be set incorrectly."); + + // Configure the device as best as we can + switch(device_type) { default: device_type = DEVICE_TYPE_TUN; @@ -192,6 +281,11 @@ static bool setup_device(void) { #endif } +#ifdef SIOCGIFADDR + if(overwrite_mac) + ioctl(device_fd, SIOCGIFADDR, mymac.x); +#endif + logger(DEBUG_ALWAYS, LOG_INFO, "%s is a %s", device, device_info); return true; @@ -253,31 +347,29 @@ static bool read_packet(vpn_packet_t *packet) { packet->len = inlen + 14; break; + case DEVICE_TYPE_UTUN: case DEVICE_TYPE_TUNIFHEAD: { - u_int32_t type; - struct iovec vector[2] = {{&type, sizeof type}, {DATA(packet) + 14, MTU - 14}}; - - if((inlen = readv(device_fd, vector, 2)) <= 0) { + if((inlen = read(device_fd, packet->data + 10, MTU - 10)) <= 0) { logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info, device, strerror(errno)); return false; } - switch (ntohl(type)) { - case AF_INET: + switch (packet->data[14] >> 4) { + case 4: DATA(packet)[12] = 0x08; DATA(packet)[13] = 0x00; break; - case AF_INET6: + case 6: DATA(packet)[12] = 0x86; DATA(packet)[13] = 0xDD; break; default: logger(DEBUG_TRAFFIC, LOG_ERR, - "Unknown address family %x while reading packet from %s %s", - ntohl(type), device_info, device); + "Unknown IP version %d while reading packet from %s %s", + packet->data[14] >> 4, device_info, device); return false; } @@ -319,12 +411,10 @@ static bool write_packet(vpn_packet_t *packet) { } break; + case DEVICE_TYPE_UTUN: case DEVICE_TYPE_TUNIFHEAD: { - u_int32_t type; - struct iovec vector[2] = {{&type, sizeof type}, {DATA(packet) + 14, packet->len - 14}}; - int af; - - af = (DATA(packet)[12] << 8) + DATA(packet)[13]; + int af = (DATA(packet)[12] << 8) + DATA(packet)[13]; + uint32_t type; switch (af) { case 0x0800: @@ -340,7 +430,9 @@ static bool write_packet(vpn_packet_t *packet) { return false; } - if(writev(device_fd, vector, 2) < 0) { + memcpy(packet->data + 10, &type, sizeof type); + + if(write(device_fd, packet->data + 10, packet->len - 10) < 0) { logger(DEBUG_ALWAYS, LOG_ERR, "Can't write to %s %s: %s", device_info, device, strerror(errno)); return false; diff --git a/src/cipher.h b/src/cipher.h index 47cd1cd..3f98c18 100644 --- a/src/cipher.h +++ b/src/cipher.h @@ -24,6 +24,8 @@ #define CIPHER_MAX_IV_SIZE 16 #define CIPHER_MAX_KEY_SIZE 32 +#ifndef DISABLE_LEGACY + typedef struct cipher cipher_t; extern cipher_t *cipher_open_by_name(const char *) __attribute__ ((__malloc__)); @@ -31,6 +33,7 @@ extern cipher_t *cipher_open_by_nid(int) __attribute__ ((__malloc__)); extern cipher_t *cipher_open_blowfish_ofb(void) __attribute__ ((__malloc__)); extern void cipher_close(cipher_t *); extern size_t cipher_keylength(const cipher_t *); +extern size_t cipher_blocksize(const cipher_t *); extern void cipher_get_key(const cipher_t *, void *); extern bool cipher_set_key(cipher_t *, void *, bool) __attribute__ ((__warn_unused_result__)); extern bool cipher_set_key_from_rsa(cipher_t *, void *, size_t, bool) __attribute__ ((__warn_unused_result__)); @@ -40,3 +43,5 @@ extern int cipher_get_nid(const cipher_t *); extern bool cipher_active(const cipher_t *); #endif + +#endif diff --git a/src/conf.c b/src/conf.c index e0d8e92..7756247 100644 --- a/src/conf.c +++ b/src/conf.c @@ -4,7 +4,7 @@ 1998-2005 Ivo Timmermans 2000 Cris van Pelt 2010-2011 Julien Muchembled - 2000-2013 Guus Sliepen + 2000-2015 Guus Sliepen 2013 Florent Clairambault This program is free software; you can redistribute it and/or modify @@ -298,7 +298,7 @@ bool read_config_file(splay_tree_t *config_tree, const char *fname) { fp = fopen(fname, "r"); if(!fp) { - logger(DEBUG_ALWAYS, LOG_ERR, "Cannot open config file %s: %s", fname, strerror(errno)); + logger(DEBUG_ALWAYS, LOG_DEBUG, "Cannot open config file %s: %s", fname, strerror(errno)); return false; } @@ -368,19 +368,19 @@ void read_config_options(splay_tree_t *config_tree, const char *prefix) { } bool read_server_config(void) { - char *fname; + char fname[PATH_MAX]; bool x; read_config_options(config_tree, NULL); - xasprintf(&fname, "%s" SLASH "tinc.conf", confbase); + snprintf(fname, sizeof fname, "%s" SLASH "tinc.conf", confbase); errno = 0; x = read_config_file(config_tree, fname); // We will try to read the conf files in the "conf.d" dir if (x) { - char * dname; - xasprintf(&dname, "%s" SLASH "conf.d", confbase); + char dname[PATH_MAX]; + snprintf(dname, sizeof dname, "%s" SLASH "conf.d", confbase); DIR *dir = opendir (dname); // If we can find this dir if (dir) { @@ -390,51 +390,44 @@ bool read_server_config(void) { size_t l = strlen(ep->d_name); // And we try to read the ones that end with ".conf" if (l > 5 && !strcmp(".conf", & ep->d_name[ l - 5 ])) { - free(fname); - xasprintf(&fname, "%s" SLASH "%s", dname, ep->d_name); + snprintf(fname, sizeof fname, "%s" SLASH "%s", dname, ep->d_name); x = read_config_file(config_tree, fname); } } closedir (dir); } - free(dname); } if(!x && errno) logger(DEBUG_ALWAYS, LOG_ERR, "Failed to read `%s': %s", fname, strerror(errno)); - free(fname); - return x; } bool read_host_config(splay_tree_t *config_tree, const char *name) { - char *fname; + char fname[PATH_MAX]; bool x; read_config_options(config_tree, name); - xasprintf(&fname, "%s" SLASH "hosts" SLASH "%s", confbase, name); + snprintf(fname, sizeof fname, "%s" SLASH "hosts" SLASH "%s", confbase, name); x = read_config_file(config_tree, fname); - free(fname); return x; } bool append_config_file(const char *name, const char *key, const char *value) { - char *fname; - xasprintf(&fname, "%s" SLASH "hosts" SLASH "%s", confbase, name); + char fname[PATH_MAX]; + snprintf(fname, sizeof fname, "%s" SLASH "hosts" SLASH "%s", confbase, name); FILE *fp = fopen(fname, "a"); if(!fp) { - logger(DEBUG_ALWAYS, LOG_ERR, "Cannot open config file %s: %s", fname, strerror(errno)); - } else { - fprintf(fp, "\n# The following line was automatically added by tinc\n%s = %s\n", key, value); - fclose(fp); + logger(DEBUG_ALWAYS, LOG_DEBUG, "Cannot open config file %s: %s", fname, strerror(errno)); + return false; } - free(fname); - - return fp != NULL; + fprintf(fp, "\n# The following line was automatically added by tinc\n%s = %s\n", key, value); + fclose(fp); + return true; } diff --git a/src/conf.h b/src/conf.h index 4f39b20..2478c58 100644 --- a/src/conf.h +++ b/src/conf.h @@ -21,8 +21,9 @@ #ifndef __TINC_CONF_H__ #define __TINC_CONF_H__ -#include "splay_tree.h" #include "list.h" +#include "splay_tree.h" +#include "subnet.h" typedef struct config_t { char *variable; @@ -31,7 +32,6 @@ typedef struct config_t { int line; } config_t; -#include "subnet.h" extern splay_tree_t *config_tree; diff --git a/src/connection.c b/src/connection.c index 496f674..0e61132 100644 --- a/src/connection.c +++ b/src/connection.c @@ -55,14 +55,16 @@ void free_connection(connection_t *c) { if(!c) return; +#ifndef DISABLE_LEGACY cipher_close(c->incipher); digest_close(c->indigest); cipher_close(c->outcipher); digest_close(c->outdigest); + rsa_free(c->rsa); +#endif sptps_stop(&c->sptps); ecdsa_free(c->ecdsa); - rsa_free(c->rsa); free(c->hischallenge); diff --git a/src/connection.h b/src/connection.h index b74b582..7fa769f 100644 --- a/src/connection.h +++ b/src/connection.h @@ -59,9 +59,9 @@ typedef struct connection_status_t { typedef struct connection_t { char *name; /* name he claims to have */ + char *hostname; /* the hostname of its real ip */ union sockaddr_t address; /* his real (internet) ip */ - char *hostname; /* the hostname of its real ip */ int protocol_major; /* used protocol */ int protocol_minor; /* used protocol */ @@ -75,12 +75,15 @@ typedef struct connection_t { struct node_t *node; /* node associated with the other end */ struct edge_t *edge; /* edge associated with this connection */ +#ifndef DISABLE_LEGACY rsa_t *rsa; /* his public RSA key */ - ecdsa_t *ecdsa; /* his public ECDSA key */ cipher_t *incipher; /* Cipher he will use to send data to us */ cipher_t *outcipher; /* Cipher we will use to send data to him */ digest_t *indigest; digest_t *outdigest; +#endif + + ecdsa_t *ecdsa; /* his public ECDSA key */ sptps_t sptps; int inmaclength; @@ -94,6 +97,7 @@ typedef struct connection_t { struct buffer_t outbuf; io_t io; /* input/output event on this metadata connection */ int tcplen; /* length of incoming TCPpacket */ + int sptpslen; /* length of incoming SPTPS packet */ int allow_request; /* defined if there's only one request possible */ time_t last_ping_time; /* last time we saw some activity from the other end or pinged them */ diff --git a/src/cygwin/device.c b/src/cygwin/device.c index 4c3a60d..d3a4303 100644 --- a/src/cygwin/device.c +++ b/src/cygwin/device.c @@ -19,6 +19,7 @@ */ #include "../system.h" +#include "../net.h" #include #include @@ -27,7 +28,6 @@ #include "../device.h" #include "../logger.h" #include "../names.h" -#include "../net.h" #include "../route.h" #include "../utils.h" #include "../xalloc.h" @@ -59,6 +59,9 @@ static bool setup_device(void) { get_config_string(lookup_config(config_tree, "Device"), &device); get_config_string(lookup_config(config_tree, "Interface"), &iface); + if(device && iface) + logger(LOG_WARNING, "Warning: both Device and Interface specified, results may not be as expected"); + /* Open registry and look for network adapters */ if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, NETWORK_CONNECTIONS_KEY, 0, KEY_READ, &key)) { diff --git a/src/digest.h b/src/digest.h index 1e14945..204048a 100644 --- a/src/digest.h +++ b/src/digest.h @@ -22,6 +22,8 @@ #define DIGEST_MAX_SIZE 64 +#ifndef DISABLE_LEGACY + typedef struct digest digest_t; extern digest_t *digest_open_by_name(const char *name, int maclength) __attribute__ ((__malloc__)); @@ -37,3 +39,5 @@ extern size_t digest_length(const digest_t *); extern bool digest_active(const digest_t *); #endif + +#endif diff --git a/src/dropin.c b/src/dropin.c index 6d40850..fe3b7ef 100644 --- a/src/dropin.c +++ b/src/dropin.c @@ -1,7 +1,7 @@ /* dropin.c -- a set of drop-in replacements for libc functions Copyright (C) 2000-2005 Ivo Timmermans, - 2000-2013 Guus Sliepen + 2000-2016 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 @@ -86,40 +86,6 @@ int daemon(int nochdir, int noclose) { } #endif -#ifndef HAVE_GET_CURRENT_DIR_NAME -/* - Replacement for the GNU get_current_dir_name function: - - get_current_dir_name will malloc(3) an array big enough to hold the - current directory name. If the environment variable PWD is set, and - its value is correct, then that value will be returned. -*/ -char *get_current_dir_name(void) { - size_t size; - char *buf; - char *r; - - /* Start with 100 bytes. If this turns out to be insufficient to - contain the working directory, double the size. */ - size = 100; - buf = xmalloc(size); - - errno = 0; /* Success */ - r = getcwd(buf, size); - - /* getcwd returns NULL and sets errno to ERANGE if the bufferspace - is insufficient to contain the entire working directory. */ - while(r == NULL && errno == ERANGE) { - free(buf); - size <<= 1; /* double the size */ - buf = xmalloc(size); - r = getcwd(buf, size); - } - - return buf; -} -#endif - #ifndef HAVE_ASPRINTF int asprintf(char **buf, const char *fmt, ...) { int result; @@ -174,10 +140,9 @@ int gettimeofday(struct timeval *tv, void *tz) { } #endif -#ifndef HAVE_USLEEP -int usleep(long long usec) { - struct timeval tv = {usec / 1000000, (usec / 1000) % 1000}; - select(0, NULL, NULL, NULL, &tv); - return 0; +#ifndef HAVE_NANOSLEEP +int nanosleep(const struct timespec *req, struct timespec *rem) { + struct timeval tv = {req->tv_sec, req->tv_nsec / 1000}; + return select(0, NULL, NULL, NULL, &tv); } #endif diff --git a/src/dropin.h b/src/dropin.h index 5601a31..938f30d 100644 --- a/src/dropin.h +++ b/src/dropin.h @@ -1,7 +1,7 @@ /* dropin.h -- header file for dropin.c Copyright (C) 2000-2005 Ivo Timmermans, - 2000-2013 Guus Sliepen + 2000-2016 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 @@ -21,17 +21,10 @@ #ifndef __DROPIN_H__ #define __DROPIN_H__ -#include "fake-getaddrinfo.h" -#include "fake-getnameinfo.h" - #ifndef HAVE_DAEMON extern int daemon(int, int); #endif -#ifndef HAVE_GET_CURRENT_DIR_NAME -extern char *get_current_dir_name(void); -#endif - #ifndef HAVE_ASPRINTF extern int asprintf(char **, const char *, ...); extern int vasprintf(char **, const char *, va_list ap); @@ -41,8 +34,8 @@ extern int vasprintf(char **, const char *, va_list ap); extern int gettimeofday(struct timeval *, void *); #endif -#ifndef HAVE_USLEEP -extern int usleep(long long usec); +#ifndef HAVE_NANOSLEEP +extern int nanosleep(const struct timespec *req, struct timespec *rem); #endif #ifndef timeradd @@ -70,4 +63,8 @@ extern int usleep(long long usec); #endif #endif +#ifndef EAI_SYSTEM +#define EAI_SYSTEM 0 +#endif + #endif /* __DROPIN_H__ */ diff --git a/src/ed25519/ecdsa.c b/src/ed25519/ecdsa.c index bfdabc1..f8aafe4 100644 --- a/src/ed25519/ecdsa.c +++ b/src/ed25519/ecdsa.c @@ -84,11 +84,13 @@ static bool read_pem(FILE *fp, const char *type, void *buf, size_t size) { size_t len = b64decode(line, line, linelen); if(!len) { logger(DEBUG_ALWAYS, LOG_ERR, "Invalid base64 data in PEM file\n"); + errno = EINVAL; return false; } if(len > size) { logger(DEBUG_ALWAYS, LOG_ERR, "Too much base64 data in PEM file\n"); + errno = EINVAL; return false; } @@ -98,7 +100,12 @@ static bool read_pem(FILE *fp, const char *type, void *buf, size_t size) { } if(size) { - logger(DEBUG_ALWAYS, LOG_ERR, "Too little base64 data in PEM file\n"); + if(data) { + errno = EINVAL; + logger(DEBUG_ALWAYS, LOG_ERR, "Too little base64 data in PEM file\n"); + } else { + errno = ENOENT; + } return false; } diff --git a/src/ed25519/fe.c b/src/ed25519/fe.c index 448e3e9..1c459f4 100644 --- a/src/ed25519/fe.c +++ b/src/ed25519/fe.c @@ -8,9 +8,9 @@ static uint64_t load_3(const unsigned char *in) { uint64_t result; - result = (uint64_t) in[0]; - result |= ((uint64_t) in[1]) << 8; - result |= ((uint64_t) in[2]) << 16; + result = in[0]; + result |= shlu64(in[1], 8); + result |= shlu64(in[2], 16); return result; } @@ -18,10 +18,10 @@ static uint64_t load_3(const unsigned char *in) { static uint64_t load_4(const unsigned char *in) { uint64_t result; - result = (uint64_t) in[0]; - result |= ((uint64_t) in[1]) << 8; - result |= ((uint64_t) in[2]) << 16; - result |= ((uint64_t) in[3]) << 24; + result = in[0]; + result |= shlu64(in[1], 8); + result |= shlu64(in[2], 16); + result |= shlu64(in[3], 24); return result; } @@ -316,47 +316,47 @@ void fe_frombytes(fe h, const unsigned char *s) { int64_t carry8; int64_t carry9; - carry9 = (h9 + (int64_t) (1 << 24)) >> 25; + carry9 = (h9 + (1L << 24)) >> 25; h0 += carry9 * 19; - h9 -= carry9 << 25; - carry1 = (h1 + (int64_t) (1 << 24)) >> 25; + h9 -= shl64(carry9, 25); + carry1 = (h1 + (1L << 24)) >> 25; h2 += carry1; - h1 -= carry1 << 25; - carry3 = (h3 + (int64_t) (1 << 24)) >> 25; + h1 -= shl64(carry1, 25); + carry3 = (h3 + (1L << 24)) >> 25; h4 += carry3; - h3 -= carry3 << 25; - carry5 = (h5 + (int64_t) (1 << 24)) >> 25; + h3 -= shl64(carry3, 25); + carry5 = (h5 + (1L << 24)) >> 25; h6 += carry5; - h5 -= carry5 << 25; - carry7 = (h7 + (int64_t) (1 << 24)) >> 25; + h5 -= shl64(carry5, 25); + carry7 = (h7 + (1L << 24)) >> 25; h8 += carry7; - h7 -= carry7 << 25; - carry0 = (h0 + (int64_t) (1 << 25)) >> 26; + h7 -= shl64(carry7, 25); + carry0 = (h0 + (1L << 25)) >> 26; h1 += carry0; - h0 -= carry0 << 26; - carry2 = (h2 + (int64_t) (1 << 25)) >> 26; + h0 -= shl64(carry0, 26); + carry2 = (h2 + (1L << 25)) >> 26; h3 += carry2; - h2 -= carry2 << 26; - carry4 = (h4 + (int64_t) (1 << 25)) >> 26; + h2 -= shl64(carry2, 26); + carry4 = (h4 + (1L << 25)) >> 26; h5 += carry4; - h4 -= carry4 << 26; - carry6 = (h6 + (int64_t) (1 << 25)) >> 26; + h4 -= shl64(carry4, 26); + carry6 = (h6 + (1L << 25)) >> 26; h7 += carry6; - h6 -= carry6 << 26; - carry8 = (h8 + (int64_t) (1 << 25)) >> 26; + h6 -= shl64(carry6, 26); + carry8 = (h8 + (1L << 25)) >> 26; h9 += carry8; - h8 -= carry8 << 26; + h8 -= shl64(carry8, 26); - h[0] = (int32_t) h0; - h[1] = (int32_t) h1; - h[2] = (int32_t) h2; - h[3] = (int32_t) h3; - h[4] = (int32_t) h4; - h[5] = (int32_t) h5; - h[6] = (int32_t) h6; - h[7] = (int32_t) h7; - h[8] = (int32_t) h8; - h[9] = (int32_t) h9; + h[0] = h0; + h[1] = h1; + h[2] = h2; + h[3] = h3; + h[4] = h4; + h[5] = h5; + h[6] = h6; + h[7] = h7; + h[8] = h8; + h[9] = h9; } @@ -709,48 +709,48 @@ void fe_mul(fe h, const fe f, const fe g) { int64_t carry8; int64_t carry9; - carry0 = (h0 + (int64_t) (1 << 25)) >> 26; + carry0 = (h0 + (1L << 25)) >> 26; h1 += carry0; - h0 -= carry0 << 26; - carry4 = (h4 + (int64_t) (1 << 25)) >> 26; + h0 -= shl64(carry0, 26); + carry4 = (h4 + (1L << 25)) >> 26; h5 += carry4; - h4 -= carry4 << 26; + h4 -= shl64(carry4, 26); - carry1 = (h1 + (int64_t) (1 << 24)) >> 25; + carry1 = (h1 + (1L << 24)) >> 25; h2 += carry1; - h1 -= carry1 << 25; - carry5 = (h5 + (int64_t) (1 << 24)) >> 25; + h1 -= shl64(carry1, 25); + carry5 = (h5 + (1L << 24)) >> 25; h6 += carry5; - h5 -= carry5 << 25; + h5 -= shl64(carry5, 25); - carry2 = (h2 + (int64_t) (1 << 25)) >> 26; + carry2 = (h2 + (1L << 25)) >> 26; h3 += carry2; - h2 -= carry2 << 26; - carry6 = (h6 + (int64_t) (1 << 25)) >> 26; + h2 -= shl64(carry2, 26); + carry6 = (h6 + (1L << 25)) >> 26; h7 += carry6; - h6 -= carry6 << 26; + h6 -= shl64(carry6, 26); - carry3 = (h3 + (int64_t) (1 << 24)) >> 25; + carry3 = (h3 + (1L << 24)) >> 25; h4 += carry3; - h3 -= carry3 << 25; - carry7 = (h7 + (int64_t) (1 << 24)) >> 25; + h3 -= shl64(carry3, 25); + carry7 = (h7 + (1L << 24)) >> 25; h8 += carry7; - h7 -= carry7 << 25; + h7 -= shl64(carry7, 25); - carry4 = (h4 + (int64_t) (1 << 25)) >> 26; + carry4 = (h4 + (1L << 25)) >> 26; h5 += carry4; - h4 -= carry4 << 26; - carry8 = (h8 + (int64_t) (1 << 25)) >> 26; + h4 -= shl64(carry4, 26); + carry8 = (h8 + (1L << 25)) >> 26; h9 += carry8; - h8 -= carry8 << 26; + h8 -= shl64(carry8, 26); - carry9 = (h9 + (int64_t) (1 << 24)) >> 25; + carry9 = (h9 + (1L << 24)) >> 25; h0 += carry9 * 19; - h9 -= carry9 << 25; + h9 -= shl64(carry9, 25); - carry0 = (h0 + (int64_t) (1 << 25)) >> 26; + carry0 = (h0 + (1L << 25)) >> 26; h1 += carry0; - h0 -= carry0 << 26; + h0 -= shl64(carry0, 26); h[0] = (int32_t) h0; h[1] = (int32_t) h1; @@ -808,17 +808,17 @@ void fe_mul121666(fe h, fe f) { int64_t carry8; int64_t carry9; - carry9 = (h9 + (int64_t) (1<<24)) >> 25; h0 += carry9 * 19; h9 -= carry9 << 25; - carry1 = (h1 + (int64_t) (1<<24)) >> 25; h2 += carry1; h1 -= carry1 << 25; - carry3 = (h3 + (int64_t) (1<<24)) >> 25; h4 += carry3; h3 -= carry3 << 25; - carry5 = (h5 + (int64_t) (1<<24)) >> 25; h6 += carry5; h5 -= carry5 << 25; - carry7 = (h7 + (int64_t) (1<<24)) >> 25; h8 += carry7; h7 -= carry7 << 25; + carry9 = (h9 + (int64_t) (1<<24)) >> 25; h0 += carry9 * 19; h9 -= shl64(carry9, 25); + carry1 = (h1 + (int64_t) (1<<24)) >> 25; h2 += carry1; h1 -= shl64(carry1, 25); + carry3 = (h3 + (int64_t) (1<<24)) >> 25; h4 += carry3; h3 -= shl64(carry3, 25); + carry5 = (h5 + (int64_t) (1<<24)) >> 25; h6 += carry5; h5 -= shl64(carry5, 25); + carry7 = (h7 + (int64_t) (1<<24)) >> 25; h8 += carry7; h7 -= shl64(carry7, 25); - carry0 = (h0 + (int64_t) (1<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26; - carry2 = (h2 + (int64_t) (1<<25)) >> 26; h3 += carry2; h2 -= carry2 << 26; - carry4 = (h4 + (int64_t) (1<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26; - carry6 = (h6 + (int64_t) (1<<25)) >> 26; h7 += carry6; h6 -= carry6 << 26; - carry8 = (h8 + (int64_t) (1<<25)) >> 26; h9 += carry8; h8 -= carry8 << 26; + carry0 = (h0 + (int64_t) (1<<25)) >> 26; h1 += carry0; h0 -= shl64(carry0, 26); + carry2 = (h2 + (int64_t) (1<<25)) >> 26; h3 += carry2; h2 -= shl64(carry2, 26); + carry4 = (h4 + (int64_t) (1<<25)) >> 26; h5 += carry4; h4 -= shl64(carry4, 26); + carry6 = (h6 + (int64_t) (1<<25)) >> 26; h7 += carry6; h6 -= shl64(carry6, 26); + carry8 = (h8 + (int64_t) (1<<25)) >> 26; h9 += carry8; h8 -= shl64(carry8, 26); h[0] = h0; h[1] = h1; @@ -1078,42 +1078,42 @@ void fe_sq(fe h, const fe f) { int64_t carry7; int64_t carry8; int64_t carry9; - carry0 = (h0 + (int64_t) (1 << 25)) >> 26; + carry0 = (h0 + (1L << 25)) >> 26; h1 += carry0; - h0 -= carry0 << 26; - carry4 = (h4 + (int64_t) (1 << 25)) >> 26; + h0 -= shl64(carry0, 26); + carry4 = (h4 + (1L << 25)) >> 26; h5 += carry4; - h4 -= carry4 << 26; - carry1 = (h1 + (int64_t) (1 << 24)) >> 25; + h4 -= shl64(carry4, 26); + carry1 = (h1 + (1L << 24)) >> 25; h2 += carry1; - h1 -= carry1 << 25; - carry5 = (h5 + (int64_t) (1 << 24)) >> 25; + h1 -= shl64(carry1, 25); + carry5 = (h5 + (1L << 24)) >> 25; h6 += carry5; - h5 -= carry5 << 25; - carry2 = (h2 + (int64_t) (1 << 25)) >> 26; + h5 -= shl64(carry5, 25); + carry2 = (h2 + (1L << 25)) >> 26; h3 += carry2; - h2 -= carry2 << 26; - carry6 = (h6 + (int64_t) (1 << 25)) >> 26; + h2 -= shl64(carry2, 26); + carry6 = (h6 + (1L << 25)) >> 26; h7 += carry6; - h6 -= carry6 << 26; - carry3 = (h3 + (int64_t) (1 << 24)) >> 25; + h6 -= shl64(carry6, 26); + carry3 = (h3 + (1L << 24)) >> 25; h4 += carry3; - h3 -= carry3 << 25; - carry7 = (h7 + (int64_t) (1 << 24)) >> 25; + h3 -= shl64(carry3, 25); + carry7 = (h7 + (1L << 24)) >> 25; h8 += carry7; - h7 -= carry7 << 25; - carry4 = (h4 + (int64_t) (1 << 25)) >> 26; + h7 -= shl64(carry7, 25); + carry4 = (h4 + (1L << 25)) >> 26; h5 += carry4; - h4 -= carry4 << 26; - carry8 = (h8 + (int64_t) (1 << 25)) >> 26; + h4 -= shl64(carry4, 26); + carry8 = (h8 + (1L << 25)) >> 26; h9 += carry8; - h8 -= carry8 << 26; - carry9 = (h9 + (int64_t) (1 << 24)) >> 25; + h8 -= shl64(carry8, 26); + carry9 = (h9 + (1L << 24)) >> 25; h0 += carry9 * 19; - h9 -= carry9 << 25; - carry0 = (h0 + (int64_t) (1 << 25)) >> 26; + h9 -= shl64(carry9, 25); + carry0 = (h0 + (1L << 25)) >> 26; h1 += carry0; - h0 -= carry0 << 26; + h0 -= shl64(carry0, 26); h[0] = (int32_t) h0; h[1] = (int32_t) h1; h[2] = (int32_t) h2; @@ -1251,42 +1251,42 @@ void fe_sq2(fe h, const fe f) { h7 += h7; h8 += h8; h9 += h9; - carry0 = (h0 + (int64_t) (1 << 25)) >> 26; + carry0 = (h0 + (1L << 25)) >> 26; h1 += carry0; - h0 -= carry0 << 26; - carry4 = (h4 + (int64_t) (1 << 25)) >> 26; + h0 -= shl64(carry0, 26); + carry4 = (h4 + (1L << 25)) >> 26; h5 += carry4; - h4 -= carry4 << 26; - carry1 = (h1 + (int64_t) (1 << 24)) >> 25; + h4 -= shl64(carry4, 26); + carry1 = (h1 + (1L << 24)) >> 25; h2 += carry1; - h1 -= carry1 << 25; - carry5 = (h5 + (int64_t) (1 << 24)) >> 25; + h1 -= shl64(carry1, 25); + carry5 = (h5 + (1L << 24)) >> 25; h6 += carry5; - h5 -= carry5 << 25; - carry2 = (h2 + (int64_t) (1 << 25)) >> 26; + h5 -= shl64(carry5, 25); + carry2 = (h2 + (1L << 25)) >> 26; h3 += carry2; - h2 -= carry2 << 26; - carry6 = (h6 + (int64_t) (1 << 25)) >> 26; + h2 -= shl64(carry2, 26); + carry6 = (h6 + (1L << 25)) >> 26; h7 += carry6; - h6 -= carry6 << 26; - carry3 = (h3 + (int64_t) (1 << 24)) >> 25; + h6 -= shl64(carry6, 26); + carry3 = (h3 + (1L << 24)) >> 25; h4 += carry3; - h3 -= carry3 << 25; - carry7 = (h7 + (int64_t) (1 << 24)) >> 25; + h3 -= shl64(carry3, 25); + carry7 = (h7 + (1L << 24)) >> 25; h8 += carry7; - h7 -= carry7 << 25; - carry4 = (h4 + (int64_t) (1 << 25)) >> 26; + h7 -= shl64(carry7, 25); + carry4 = (h4 + (1L << 25)) >> 26; h5 += carry4; - h4 -= carry4 << 26; - carry8 = (h8 + (int64_t) (1 << 25)) >> 26; + h4 -= shl64(carry4, 26); + carry8 = (h8 + (1L << 25)) >> 26; h9 += carry8; - h8 -= carry8 << 26; - carry9 = (h9 + (int64_t) (1 << 24)) >> 25; + h8 -= shl64(carry8, 26); + carry9 = (h9 + (1L << 24)) >> 25; h0 += carry9 * 19; - h9 -= carry9 << 25; - carry0 = (h0 + (int64_t) (1 << 25)) >> 26; + h9 -= shl64(carry9, 25); + carry0 = (h0 + (1L << 25)) >> 26; h1 += carry0; - h0 -= carry0 << 26; + h0 -= shl64(carry0, 26); h[0] = (int32_t) h0; h[1] = (int32_t) h1; h[2] = (int32_t) h2; @@ -1421,33 +1421,33 @@ void fe_tobytes(unsigned char *s, const fe h) { /* Goal: Output h-2^255 q, which is between 0 and 2^255-20. */ carry0 = h0 >> 26; h1 += carry0; - h0 -= carry0 << 26; + h0 -= shl32(carry0, 26); carry1 = h1 >> 25; h2 += carry1; - h1 -= carry1 << 25; + h1 -= shl32(carry1, 25); carry2 = h2 >> 26; h3 += carry2; - h2 -= carry2 << 26; + h2 -= shl32(carry2, 26); carry3 = h3 >> 25; h4 += carry3; - h3 -= carry3 << 25; + h3 -= shl32(carry3, 25); carry4 = h4 >> 26; h5 += carry4; - h4 -= carry4 << 26; + h4 -= shl32(carry4, 26); carry5 = h5 >> 25; h6 += carry5; - h5 -= carry5 << 25; + h5 -= shl32(carry5, 25); carry6 = h6 >> 26; h7 += carry6; - h6 -= carry6 << 26; + h6 -= shl32(carry6, 26); carry7 = h7 >> 25; h8 += carry7; - h7 -= carry7 << 25; + h7 -= shl32(carry7, 25); carry8 = h8 >> 26; h9 += carry8; - h8 -= carry8 << 26; + h8 -= shl32(carry8, 26); carry9 = h9 >> 25; - h9 -= carry9 << 25; + h9 -= shl32(carry9, 25); /* h10 = carry9 */ /* @@ -1459,32 +1459,32 @@ void fe_tobytes(unsigned char *s, const fe h) { s[0] = (unsigned char) (h0 >> 0); s[1] = (unsigned char) (h0 >> 8); s[2] = (unsigned char) (h0 >> 16); - s[3] = (unsigned char) ((h0 >> 24) | (h1 << 2)); + s[3] = (unsigned char) ((h0 >> 24) | shl32(h1, 2)); s[4] = (unsigned char) (h1 >> 6); s[5] = (unsigned char) (h1 >> 14); - s[6] = (unsigned char) ((h1 >> 22) | (h2 << 3)); + s[6] = (unsigned char) ((h1 >> 22) | shl32(h2, 3)); s[7] = (unsigned char) (h2 >> 5); s[8] = (unsigned char) (h2 >> 13); - s[9] = (unsigned char) ((h2 >> 21) | (h3 << 5)); + s[9] = (unsigned char) ((h2 >> 21) | shl32(h3, 5)); s[10] = (unsigned char) (h3 >> 3); s[11] = (unsigned char) (h3 >> 11); - s[12] = (unsigned char) ((h3 >> 19) | (h4 << 6)); + s[12] = (unsigned char) ((h3 >> 19) | shl32(h4, 6)); s[13] = (unsigned char) (h4 >> 2); s[14] = (unsigned char) (h4 >> 10); s[15] = (unsigned char) (h4 >> 18); s[16] = (unsigned char) (h5 >> 0); s[17] = (unsigned char) (h5 >> 8); s[18] = (unsigned char) (h5 >> 16); - s[19] = (unsigned char) ((h5 >> 24) | (h6 << 1)); + s[19] = (unsigned char) ((h5 >> 24) | shl32(h6, 1)); s[20] = (unsigned char) (h6 >> 7); s[21] = (unsigned char) (h6 >> 15); - s[22] = (unsigned char) ((h6 >> 23) | (h7 << 3)); + s[22] = (unsigned char) ((h6 >> 23) | shl32(h7, 3)); s[23] = (unsigned char) (h7 >> 5); s[24] = (unsigned char) (h7 >> 13); - s[25] = (unsigned char) ((h7 >> 21) | (h8 << 4)); + s[25] = (unsigned char) ((h7 >> 21) | shl32(h8, 4)); s[26] = (unsigned char) (h8 >> 4); s[27] = (unsigned char) (h8 >> 12); - s[28] = (unsigned char) ((h8 >> 20) | (h9 << 6)); + s[28] = (unsigned char) ((h8 >> 20) | shl32(h9, 6)); s[29] = (unsigned char) (h9 >> 2); s[30] = (unsigned char) (h9 >> 10); s[31] = (unsigned char) (h9 >> 18); diff --git a/src/ed25519/fixedint.h b/src/ed25519/fixedint.h index d03e4bd..8abced0 100644 --- a/src/ed25519/fixedint.h +++ b/src/ed25519/fixedint.h @@ -4,6 +4,9 @@ Not a compatible replacement for , do not blindly use it as such. */ +#ifndef __TINC_FIXEDINT_H__ +#define __TINC_FIXEDINT_H__ + #if ((defined(__STDC__) && __STDC__ && __STDC_VERSION__ >= 199901L) || (defined(__WATCOMC__) && (defined(_STDINT_H_INCLUDED) || __WATCOMC__ >= 1250)) || (defined(__GNUC__) && (defined(_STDINT_H) || defined(_STDINT_H_) || defined(__UINT_FAST64_TYPE__)) )) && !defined(FIXEDINT_H_INCLUDED) #include #define FIXEDINT_H_INCLUDED @@ -68,3 +71,21 @@ #define INT64_C(v) v ##I64 #endif #endif + +static inline unsigned char shlu8(unsigned char a, uint32_t b) { + return a << b; +} + +static inline int32_t shl32(uint32_t a, uint32_t b) { + return a << b; +} + +static inline int64_t shl64(uint64_t a, uint32_t b) { + return a << b; +} + +static inline uint64_t shlu64(uint64_t a, uint32_t b) { + return a << b; +} + +#endif diff --git a/src/ed25519/ge.c b/src/ed25519/ge.c index 3c342b1..9488218 100644 --- a/src/ed25519/ge.c +++ b/src/ed25519/ge.c @@ -356,7 +356,7 @@ static void cmov(ge_precomp *t, ge_precomp *u, unsigned char b) { static void select(ge_precomp *t, int pos, signed char b) { ge_precomp minust; unsigned char bnegative = negative(b); - unsigned char babs = b - (((-bnegative) & b) << 1); + unsigned char babs = b - shlu8(((-bnegative) & b), 1); fe_1(t->yplusx); fe_1(t->yminusx); fe_0(t->xy2d); @@ -404,7 +404,7 @@ void ge_scalarmult_base(ge_p3 *h, const unsigned char *a) { e[i] += carry; carry = e[i] + 8; carry >>= 4; - e[i] -= carry << 4; + e[i] -= shl32(carry, 4); } e[63] += carry; diff --git a/src/ed25519/precomp_data.h b/src/ed25519/precomp_data.h index 776b84f..ce59788 100644 --- a/src/ed25519/precomp_data.h +++ b/src/ed25519/precomp_data.h @@ -1388,4 +1388,4 @@ static ge_precomp base[32][8] = { { -20430234, 14955537, -24126347, 8124619, -5369288, -5990470, 30468147, -13900640, 18423289, 4177476 }, }, }, -}; \ No newline at end of file +}; diff --git a/src/ed25519/sc.c b/src/ed25519/sc.c index ca5bad2..42cfc2d 100644 --- a/src/ed25519/sc.c +++ b/src/ed25519/sc.c @@ -4,9 +4,9 @@ static uint64_t load_3(const unsigned char *in) { uint64_t result; - result = (uint64_t) in[0]; - result |= ((uint64_t) in[1]) << 8; - result |= ((uint64_t) in[2]) << 16; + result = in[0]; + result |= shlu64(in[1], 8); + result |= shlu64(in[2], 16); return result; } @@ -14,10 +14,10 @@ static uint64_t load_3(const unsigned char *in) { static uint64_t load_4(const unsigned char *in) { uint64_t result; - result = (uint64_t) in[0]; - result |= ((uint64_t) in[1]) << 8; - result |= ((uint64_t) in[2]) << 16; - result |= ((uint64_t) in[3]) << 24; + result = in[0]; + result |= shlu64(in[1], 8); + result |= shlu64(in[2], 16); + result |= shlu64(in[3], 24); return result; } @@ -119,37 +119,37 @@ void sc_reduce(unsigned char *s) { s18 = 0; carry6 = (s6 + (1 << 20)) >> 21; s7 += carry6; - s6 -= carry6 << 21; + s6 -= shl64(carry6, 21); carry8 = (s8 + (1 << 20)) >> 21; s9 += carry8; - s8 -= carry8 << 21; + s8 -= shl64(carry8, 21); carry10 = (s10 + (1 << 20)) >> 21; s11 += carry10; - s10 -= carry10 << 21; + s10 -= shl64(carry10, 21); carry12 = (s12 + (1 << 20)) >> 21; s13 += carry12; - s12 -= carry12 << 21; + s12 -= shl64(carry12, 21); carry14 = (s14 + (1 << 20)) >> 21; s15 += carry14; - s14 -= carry14 << 21; + s14 -= shl64(carry14, 21); carry16 = (s16 + (1 << 20)) >> 21; s17 += carry16; - s16 -= carry16 << 21; + s16 -= shl64(carry16, 21); carry7 = (s7 + (1 << 20)) >> 21; s8 += carry7; - s7 -= carry7 << 21; + s7 -= shl64(carry7, 21); carry9 = (s9 + (1 << 20)) >> 21; s10 += carry9; - s9 -= carry9 << 21; + s9 -= shl64(carry9, 21); carry11 = (s11 + (1 << 20)) >> 21; s12 += carry11; - s11 -= carry11 << 21; + s11 -= shl64(carry11, 21); carry13 = (s13 + (1 << 20)) >> 21; s14 += carry13; - s13 -= carry13 << 21; + s13 -= shl64(carry13, 21); carry15 = (s15 + (1 << 20)) >> 21; s16 += carry15; - s15 -= carry15 << 21; + s15 -= shl64(carry15, 21); s5 += s17 * 666643; s6 += s17 * 470296; s7 += s17 * 654183; @@ -194,40 +194,40 @@ void sc_reduce(unsigned char *s) { s12 = 0; carry0 = (s0 + (1 << 20)) >> 21; s1 += carry0; - s0 -= carry0 << 21; + s0 -= shl64(carry0, 21); carry2 = (s2 + (1 << 20)) >> 21; s3 += carry2; - s2 -= carry2 << 21; + s2 -= shl64(carry2, 21); carry4 = (s4 + (1 << 20)) >> 21; s5 += carry4; - s4 -= carry4 << 21; + s4 -= shl64(carry4, 21); carry6 = (s6 + (1 << 20)) >> 21; s7 += carry6; - s6 -= carry6 << 21; + s6 -= shl64(carry6, 21); carry8 = (s8 + (1 << 20)) >> 21; s9 += carry8; - s8 -= carry8 << 21; + s8 -= shl64(carry8, 21); carry10 = (s10 + (1 << 20)) >> 21; s11 += carry10; - s10 -= carry10 << 21; + s10 -= shl64(carry10, 21); carry1 = (s1 + (1 << 20)) >> 21; s2 += carry1; - s1 -= carry1 << 21; + s1 -= shl64(carry1, 21); carry3 = (s3 + (1 << 20)) >> 21; s4 += carry3; - s3 -= carry3 << 21; + s3 -= shl64(carry3, 21); carry5 = (s5 + (1 << 20)) >> 21; s6 += carry5; - s5 -= carry5 << 21; + s5 -= shl64(carry5, 21); carry7 = (s7 + (1 << 20)) >> 21; s8 += carry7; - s7 -= carry7 << 21; + s7 -= shl64(carry7, 21); carry9 = (s9 + (1 << 20)) >> 21; s10 += carry9; - s9 -= carry9 << 21; + s9 -= shl64(carry9, 21); carry11 = (s11 + (1 << 20)) >> 21; s12 += carry11; - s11 -= carry11 << 21; + s11 -= shl64(carry11, 21); s0 += s12 * 666643; s1 += s12 * 470296; s2 += s12 * 654183; @@ -237,40 +237,40 @@ void sc_reduce(unsigned char *s) { s12 = 0; carry0 = s0 >> 21; s1 += carry0; - s0 -= carry0 << 21; + s0 -= shl64(carry0, 21); carry1 = s1 >> 21; s2 += carry1; - s1 -= carry1 << 21; + s1 -= shl64(carry1, 21); carry2 = s2 >> 21; s3 += carry2; - s2 -= carry2 << 21; + s2 -= shl64(carry2, 21); carry3 = s3 >> 21; s4 += carry3; - s3 -= carry3 << 21; + s3 -= shl64(carry3, 21); carry4 = s4 >> 21; s5 += carry4; - s4 -= carry4 << 21; + s4 -= shl64(carry4, 21); carry5 = s5 >> 21; s6 += carry5; - s5 -= carry5 << 21; + s5 -= shl64(carry5, 21); carry6 = s6 >> 21; s7 += carry6; - s6 -= carry6 << 21; + s6 -= shl64(carry6, 21); carry7 = s7 >> 21; s8 += carry7; - s7 -= carry7 << 21; + s7 -= shl64(carry7, 21); carry8 = s8 >> 21; s9 += carry8; - s8 -= carry8 << 21; + s8 -= shl64(carry8, 21); carry9 = s9 >> 21; s10 += carry9; - s9 -= carry9 << 21; + s9 -= shl64(carry9, 21); carry10 = s10 >> 21; s11 += carry10; - s10 -= carry10 << 21; + s10 -= shl64(carry10, 21); carry11 = s11 >> 21; s12 += carry11; - s11 -= carry11 << 21; + s11 -= shl64(carry11, 21); s0 += s12 * 666643; s1 += s12 * 470296; s2 += s12 * 654183; @@ -280,67 +280,67 @@ void sc_reduce(unsigned char *s) { s12 = 0; carry0 = s0 >> 21; s1 += carry0; - s0 -= carry0 << 21; + s0 -= shl64(carry0, 21); carry1 = s1 >> 21; s2 += carry1; - s1 -= carry1 << 21; + s1 -= shl64(carry1, 21); carry2 = s2 >> 21; s3 += carry2; - s2 -= carry2 << 21; + s2 -= shl64(carry2, 21); carry3 = s3 >> 21; s4 += carry3; - s3 -= carry3 << 21; + s3 -= shl64(carry3, 21); carry4 = s4 >> 21; s5 += carry4; - s4 -= carry4 << 21; + s4 -= shl64(carry4, 21); carry5 = s5 >> 21; s6 += carry5; - s5 -= carry5 << 21; + s5 -= shl64(carry5, 21); carry6 = s6 >> 21; s7 += carry6; - s6 -= carry6 << 21; + s6 -= shl64(carry6, 21); carry7 = s7 >> 21; s8 += carry7; - s7 -= carry7 << 21; + s7 -= shl64(carry7, 21); carry8 = s8 >> 21; s9 += carry8; - s8 -= carry8 << 21; + s8 -= shl64(carry8, 21); carry9 = s9 >> 21; s10 += carry9; - s9 -= carry9 << 21; + s9 -= shl64(carry9, 21); carry10 = s10 >> 21; s11 += carry10; - s10 -= carry10 << 21; + s10 -= shl64(carry10, 21); s[0] = (unsigned char) (s0 >> 0); s[1] = (unsigned char) (s0 >> 8); - s[2] = (unsigned char) ((s0 >> 16) | (s1 << 5)); + s[2] = (unsigned char) ((s0 >> 16) | shl64(s1, 5)); s[3] = (unsigned char) (s1 >> 3); s[4] = (unsigned char) (s1 >> 11); - s[5] = (unsigned char) ((s1 >> 19) | (s2 << 2)); + s[5] = (unsigned char) ((s1 >> 19) | shl64(s2, 2)); s[6] = (unsigned char) (s2 >> 6); - s[7] = (unsigned char) ((s2 >> 14) | (s3 << 7)); + s[7] = (unsigned char) ((s2 >> 14) | shl64(s3, 7)); s[8] = (unsigned char) (s3 >> 1); s[9] = (unsigned char) (s3 >> 9); - s[10] = (unsigned char) ((s3 >> 17) | (s4 << 4)); + s[10] = (unsigned char) ((s3 >> 17) | shl64(s4, 4)); s[11] = (unsigned char) (s4 >> 4); s[12] = (unsigned char) (s4 >> 12); - s[13] = (unsigned char) ((s4 >> 20) | (s5 << 1)); + s[13] = (unsigned char) ((s4 >> 20) | shl64(s5, 1)); s[14] = (unsigned char) (s5 >> 7); - s[15] = (unsigned char) ((s5 >> 15) | (s6 << 6)); + s[15] = (unsigned char) ((s5 >> 15) | shl64(s6, 6)); s[16] = (unsigned char) (s6 >> 2); s[17] = (unsigned char) (s6 >> 10); - s[18] = (unsigned char) ((s6 >> 18) | (s7 << 3)); + s[18] = (unsigned char) ((s6 >> 18) | shl64(s7, 3)); s[19] = (unsigned char) (s7 >> 5); s[20] = (unsigned char) (s7 >> 13); s[21] = (unsigned char) (s8 >> 0); s[22] = (unsigned char) (s8 >> 8); - s[23] = (unsigned char) ((s8 >> 16) | (s9 << 5)); + s[23] = (unsigned char) ((s8 >> 16) | shl64(s9, 5)); s[24] = (unsigned char) (s9 >> 3); s[25] = (unsigned char) (s9 >> 11); - s[26] = (unsigned char) ((s9 >> 19) | (s10 << 2)); + s[26] = (unsigned char) ((s9 >> 19) | shl64(s10, 2)); s[27] = (unsigned char) (s10 >> 6); - s[28] = (unsigned char) ((s10 >> 14) | (s11 << 7)); + s[28] = (unsigned char) ((s10 >> 14) | shl64(s11, 7)); s[29] = (unsigned char) (s11 >> 1); s[30] = (unsigned char) (s11 >> 9); s[31] = (unsigned char) (s11 >> 17); @@ -470,73 +470,73 @@ void sc_muladd(unsigned char *s, const unsigned char *a, const unsigned char *b, s23 = 0; carry0 = (s0 + (1 << 20)) >> 21; s1 += carry0; - s0 -= carry0 << 21; + s0 -= shl64(carry0, 21); carry2 = (s2 + (1 << 20)) >> 21; s3 += carry2; - s2 -= carry2 << 21; + s2 -= shl64(carry2, 21); carry4 = (s4 + (1 << 20)) >> 21; s5 += carry4; - s4 -= carry4 << 21; + s4 -= shl64(carry4, 21); carry6 = (s6 + (1 << 20)) >> 21; s7 += carry6; - s6 -= carry6 << 21; + s6 -= shl64(carry6, 21); carry8 = (s8 + (1 << 20)) >> 21; s9 += carry8; - s8 -= carry8 << 21; + s8 -= shl64(carry8, 21); carry10 = (s10 + (1 << 20)) >> 21; s11 += carry10; - s10 -= carry10 << 21; + s10 -= shl64(carry10, 21); carry12 = (s12 + (1 << 20)) >> 21; s13 += carry12; - s12 -= carry12 << 21; + s12 -= shl64(carry12, 21); carry14 = (s14 + (1 << 20)) >> 21; s15 += carry14; - s14 -= carry14 << 21; + s14 -= shl64(carry14, 21); carry16 = (s16 + (1 << 20)) >> 21; s17 += carry16; - s16 -= carry16 << 21; + s16 -= shl64(carry16, 21); carry18 = (s18 + (1 << 20)) >> 21; s19 += carry18; - s18 -= carry18 << 21; + s18 -= shl64(carry18, 21); carry20 = (s20 + (1 << 20)) >> 21; s21 += carry20; - s20 -= carry20 << 21; + s20 -= shl64(carry20, 21); carry22 = (s22 + (1 << 20)) >> 21; s23 += carry22; - s22 -= carry22 << 21; + s22 -= shl64(carry22, 21); carry1 = (s1 + (1 << 20)) >> 21; s2 += carry1; - s1 -= carry1 << 21; + s1 -= shl64(carry1, 21); carry3 = (s3 + (1 << 20)) >> 21; s4 += carry3; - s3 -= carry3 << 21; + s3 -= shl64(carry3, 21); carry5 = (s5 + (1 << 20)) >> 21; s6 += carry5; - s5 -= carry5 << 21; + s5 -= shl64(carry5, 21); carry7 = (s7 + (1 << 20)) >> 21; s8 += carry7; - s7 -= carry7 << 21; + s7 -= shl64(carry7, 21); carry9 = (s9 + (1 << 20)) >> 21; s10 += carry9; - s9 -= carry9 << 21; + s9 -= shl64(carry9, 21); carry11 = (s11 + (1 << 20)) >> 21; s12 += carry11; - s11 -= carry11 << 21; + s11 -= shl64(carry11, 21); carry13 = (s13 + (1 << 20)) >> 21; s14 += carry13; - s13 -= carry13 << 21; + s13 -= shl64(carry13, 21); carry15 = (s15 + (1 << 20)) >> 21; s16 += carry15; - s15 -= carry15 << 21; + s15 -= shl64(carry15, 21); carry17 = (s17 + (1 << 20)) >> 21; s18 += carry17; - s17 -= carry17 << 21; + s17 -= shl64(carry17, 21); carry19 = (s19 + (1 << 20)) >> 21; s20 += carry19; - s19 -= carry19 << 21; + s19 -= shl64(carry19, 21); carry21 = (s21 + (1 << 20)) >> 21; s22 += carry21; - s21 -= carry21 << 21; + s21 -= shl64(carry21, 21); s11 += s23 * 666643; s12 += s23 * 470296; s13 += s23 * 654183; @@ -581,37 +581,37 @@ void sc_muladd(unsigned char *s, const unsigned char *a, const unsigned char *b, s18 = 0; carry6 = (s6 + (1 << 20)) >> 21; s7 += carry6; - s6 -= carry6 << 21; + s6 -= shl64(carry6, 21); carry8 = (s8 + (1 << 20)) >> 21; s9 += carry8; - s8 -= carry8 << 21; + s8 -= shl64(carry8, 21); carry10 = (s10 + (1 << 20)) >> 21; s11 += carry10; - s10 -= carry10 << 21; + s10 -= shl64(carry10, 21); carry12 = (s12 + (1 << 20)) >> 21; s13 += carry12; - s12 -= carry12 << 21; + s12 -= shl64(carry12, 21); carry14 = (s14 + (1 << 20)) >> 21; s15 += carry14; - s14 -= carry14 << 21; + s14 -= shl64(carry14, 21); carry16 = (s16 + (1 << 20)) >> 21; s17 += carry16; - s16 -= carry16 << 21; + s16 -= shl64(carry16, 21); carry7 = (s7 + (1 << 20)) >> 21; s8 += carry7; - s7 -= carry7 << 21; + s7 -= shl64(carry7, 21); carry9 = (s9 + (1 << 20)) >> 21; s10 += carry9; - s9 -= carry9 << 21; + s9 -= shl64(carry9, 21); carry11 = (s11 + (1 << 20)) >> 21; s12 += carry11; - s11 -= carry11 << 21; + s11 -= shl64(carry11, 21); carry13 = (s13 + (1 << 20)) >> 21; s14 += carry13; - s13 -= carry13 << 21; + s13 -= shl64(carry13, 21); carry15 = (s15 + (1 << 20)) >> 21; s16 += carry15; - s15 -= carry15 << 21; + s15 -= shl64(carry15, 21); s5 += s17 * 666643; s6 += s17 * 470296; s7 += s17 * 654183; @@ -656,40 +656,40 @@ void sc_muladd(unsigned char *s, const unsigned char *a, const unsigned char *b, s12 = 0; carry0 = (s0 + (1 << 20)) >> 21; s1 += carry0; - s0 -= carry0 << 21; + s0 -= shl64(carry0, 21); carry2 = (s2 + (1 << 20)) >> 21; s3 += carry2; - s2 -= carry2 << 21; + s2 -= shl64(carry2, 21); carry4 = (s4 + (1 << 20)) >> 21; s5 += carry4; - s4 -= carry4 << 21; + s4 -= shl64(carry4, 21); carry6 = (s6 + (1 << 20)) >> 21; s7 += carry6; - s6 -= carry6 << 21; + s6 -= shl64(carry6, 21); carry8 = (s8 + (1 << 20)) >> 21; s9 += carry8; - s8 -= carry8 << 21; + s8 -= shl64(carry8, 21); carry10 = (s10 + (1 << 20)) >> 21; s11 += carry10; - s10 -= carry10 << 21; + s10 -= shl64(carry10, 21); carry1 = (s1 + (1 << 20)) >> 21; s2 += carry1; - s1 -= carry1 << 21; + s1 -= shl64(carry1, 21); carry3 = (s3 + (1 << 20)) >> 21; s4 += carry3; - s3 -= carry3 << 21; + s3 -= shl64(carry3, 21); carry5 = (s5 + (1 << 20)) >> 21; s6 += carry5; - s5 -= carry5 << 21; + s5 -= shl64(carry5, 21); carry7 = (s7 + (1 << 20)) >> 21; s8 += carry7; - s7 -= carry7 << 21; + s7 -= shl64(carry7, 21); carry9 = (s9 + (1 << 20)) >> 21; s10 += carry9; - s9 -= carry9 << 21; + s9 -= shl64(carry9, 21); carry11 = (s11 + (1 << 20)) >> 21; s12 += carry11; - s11 -= carry11 << 21; + s11 -= shl64(carry11, 21); s0 += s12 * 666643; s1 += s12 * 470296; s2 += s12 * 654183; @@ -699,40 +699,40 @@ void sc_muladd(unsigned char *s, const unsigned char *a, const unsigned char *b, s12 = 0; carry0 = s0 >> 21; s1 += carry0; - s0 -= carry0 << 21; + s0 -= shl64(carry0, 21); carry1 = s1 >> 21; s2 += carry1; - s1 -= carry1 << 21; + s1 -= shl64(carry1, 21); carry2 = s2 >> 21; s3 += carry2; - s2 -= carry2 << 21; + s2 -= shl64(carry2, 21); carry3 = s3 >> 21; s4 += carry3; - s3 -= carry3 << 21; + s3 -= shl64(carry3, 21); carry4 = s4 >> 21; s5 += carry4; - s4 -= carry4 << 21; + s4 -= shl64(carry4, 21); carry5 = s5 >> 21; s6 += carry5; - s5 -= carry5 << 21; + s5 -= shl64(carry5, 21); carry6 = s6 >> 21; s7 += carry6; - s6 -= carry6 << 21; + s6 -= shl64(carry6, 21); carry7 = s7 >> 21; s8 += carry7; - s7 -= carry7 << 21; + s7 -= shl64(carry7, 21); carry8 = s8 >> 21; s9 += carry8; - s8 -= carry8 << 21; + s8 -= shl64(carry8, 21); carry9 = s9 >> 21; s10 += carry9; - s9 -= carry9 << 21; + s9 -= shl64(carry9, 21); carry10 = s10 >> 21; s11 += carry10; - s10 -= carry10 << 21; + s10 -= shl64(carry10, 21); carry11 = s11 >> 21; s12 += carry11; - s11 -= carry11 << 21; + s11 -= shl64(carry11, 21); s0 += s12 * 666643; s1 += s12 * 470296; s2 += s12 * 654183; @@ -742,67 +742,67 @@ void sc_muladd(unsigned char *s, const unsigned char *a, const unsigned char *b, s12 = 0; carry0 = s0 >> 21; s1 += carry0; - s0 -= carry0 << 21; + s0 -= shl64(carry0, 21); carry1 = s1 >> 21; s2 += carry1; - s1 -= carry1 << 21; + s1 -= shl64(carry1, 21); carry2 = s2 >> 21; s3 += carry2; - s2 -= carry2 << 21; + s2 -= shl64(carry2, 21); carry3 = s3 >> 21; s4 += carry3; - s3 -= carry3 << 21; + s3 -= shl64(carry3, 21); carry4 = s4 >> 21; s5 += carry4; - s4 -= carry4 << 21; + s4 -= shl64(carry4, 21); carry5 = s5 >> 21; s6 += carry5; - s5 -= carry5 << 21; + s5 -= shl64(carry5, 21); carry6 = s6 >> 21; s7 += carry6; - s6 -= carry6 << 21; + s6 -= shl64(carry6, 21); carry7 = s7 >> 21; s8 += carry7; - s7 -= carry7 << 21; + s7 -= shl64(carry7, 21); carry8 = s8 >> 21; s9 += carry8; - s8 -= carry8 << 21; + s8 -= shl64(carry8, 21); carry9 = s9 >> 21; s10 += carry9; - s9 -= carry9 << 21; + s9 -= shl64(carry9, 21); carry10 = s10 >> 21; s11 += carry10; - s10 -= carry10 << 21; + s10 -= shl64(carry10, 21); s[0] = (unsigned char) (s0 >> 0); s[1] = (unsigned char) (s0 >> 8); - s[2] = (unsigned char) ((s0 >> 16) | (s1 << 5)); + s[2] = (unsigned char) ((s0 >> 16) | shl64(s1, 5)); s[3] = (unsigned char) (s1 >> 3); s[4] = (unsigned char) (s1 >> 11); - s[5] = (unsigned char) ((s1 >> 19) | (s2 << 2)); + s[5] = (unsigned char) ((s1 >> 19) | shl64(s2, 2)); s[6] = (unsigned char) (s2 >> 6); - s[7] = (unsigned char) ((s2 >> 14) | (s3 << 7)); + s[7] = (unsigned char) ((s2 >> 14) | shl64(s3, 7)); s[8] = (unsigned char) (s3 >> 1); s[9] = (unsigned char) (s3 >> 9); - s[10] = (unsigned char) ((s3 >> 17) | (s4 << 4)); + s[10] = (unsigned char) ((s3 >> 17) | shl64(s4, 4)); s[11] = (unsigned char) (s4 >> 4); s[12] = (unsigned char) (s4 >> 12); - s[13] = (unsigned char) ((s4 >> 20) | (s5 << 1)); + s[13] = (unsigned char) ((s4 >> 20) | shl64(s5, 1)); s[14] = (unsigned char) (s5 >> 7); - s[15] = (unsigned char) ((s5 >> 15) | (s6 << 6)); + s[15] = (unsigned char) ((s5 >> 15) | shl64(s6, 6)); s[16] = (unsigned char) (s6 >> 2); s[17] = (unsigned char) (s6 >> 10); - s[18] = (unsigned char) ((s6 >> 18) | (s7 << 3)); + s[18] = (unsigned char) ((s6 >> 18) | shl64(s7, 3)); s[19] = (unsigned char) (s7 >> 5); s[20] = (unsigned char) (s7 >> 13); s[21] = (unsigned char) (s8 >> 0); s[22] = (unsigned char) (s8 >> 8); - s[23] = (unsigned char) ((s8 >> 16) | (s9 << 5)); + s[23] = (unsigned char) ((s8 >> 16) | shl64(s9, 5)); s[24] = (unsigned char) (s9 >> 3); s[25] = (unsigned char) (s9 >> 11); - s[26] = (unsigned char) ((s9 >> 19) | (s10 << 2)); + s[26] = (unsigned char) ((s9 >> 19) | shl64(s10, 2)); s[27] = (unsigned char) (s10 >> 6); - s[28] = (unsigned char) ((s10 >> 14) | (s11 << 7)); + s[28] = (unsigned char) ((s10 >> 14) | shl64(s11, 7)); s[29] = (unsigned char) (s11 >> 1); s[30] = (unsigned char) (s11 >> 9); s[31] = (unsigned char) (s11 >> 17); diff --git a/src/ed25519/sc.h b/src/ed25519/sc.h index 8fa727e..e29e7fa 100644 --- a/src/ed25519/sc.h +++ b/src/ed25519/sc.h @@ -9,4 +9,4 @@ where l = 2^252 + 27742317777372353535851937790883648493. void sc_reduce(unsigned char *s); void sc_muladd(unsigned char *s, const unsigned char *a, const unsigned char *b, const unsigned char *c); -#endif \ No newline at end of file +#endif diff --git a/src/ed25519/sha512.c b/src/ed25519/sha512.c index cb8ae71..e1db1e5 100644 --- a/src/ed25519/sha512.c +++ b/src/ed25519/sha512.c @@ -14,45 +14,45 @@ /* the K array */ static const uint64_t K[80] = { - UINT64_C(0x428a2f98d728ae22), UINT64_C(0x7137449123ef65cd), + UINT64_C(0x428a2f98d728ae22), UINT64_C(0x7137449123ef65cd), UINT64_C(0xb5c0fbcfec4d3b2f), UINT64_C(0xe9b5dba58189dbbc), - UINT64_C(0x3956c25bf348b538), UINT64_C(0x59f111f1b605d019), + UINT64_C(0x3956c25bf348b538), UINT64_C(0x59f111f1b605d019), UINT64_C(0x923f82a4af194f9b), UINT64_C(0xab1c5ed5da6d8118), - UINT64_C(0xd807aa98a3030242), UINT64_C(0x12835b0145706fbe), + UINT64_C(0xd807aa98a3030242), UINT64_C(0x12835b0145706fbe), UINT64_C(0x243185be4ee4b28c), UINT64_C(0x550c7dc3d5ffb4e2), - UINT64_C(0x72be5d74f27b896f), UINT64_C(0x80deb1fe3b1696b1), + UINT64_C(0x72be5d74f27b896f), UINT64_C(0x80deb1fe3b1696b1), UINT64_C(0x9bdc06a725c71235), UINT64_C(0xc19bf174cf692694), - UINT64_C(0xe49b69c19ef14ad2), UINT64_C(0xefbe4786384f25e3), + UINT64_C(0xe49b69c19ef14ad2), UINT64_C(0xefbe4786384f25e3), UINT64_C(0x0fc19dc68b8cd5b5), UINT64_C(0x240ca1cc77ac9c65), - UINT64_C(0x2de92c6f592b0275), UINT64_C(0x4a7484aa6ea6e483), + UINT64_C(0x2de92c6f592b0275), UINT64_C(0x4a7484aa6ea6e483), UINT64_C(0x5cb0a9dcbd41fbd4), UINT64_C(0x76f988da831153b5), - UINT64_C(0x983e5152ee66dfab), UINT64_C(0xa831c66d2db43210), + UINT64_C(0x983e5152ee66dfab), UINT64_C(0xa831c66d2db43210), UINT64_C(0xb00327c898fb213f), UINT64_C(0xbf597fc7beef0ee4), - UINT64_C(0xc6e00bf33da88fc2), UINT64_C(0xd5a79147930aa725), + UINT64_C(0xc6e00bf33da88fc2), UINT64_C(0xd5a79147930aa725), UINT64_C(0x06ca6351e003826f), UINT64_C(0x142929670a0e6e70), - UINT64_C(0x27b70a8546d22ffc), UINT64_C(0x2e1b21385c26c926), + UINT64_C(0x27b70a8546d22ffc), UINT64_C(0x2e1b21385c26c926), UINT64_C(0x4d2c6dfc5ac42aed), UINT64_C(0x53380d139d95b3df), - UINT64_C(0x650a73548baf63de), UINT64_C(0x766a0abb3c77b2a8), + UINT64_C(0x650a73548baf63de), UINT64_C(0x766a0abb3c77b2a8), UINT64_C(0x81c2c92e47edaee6), UINT64_C(0x92722c851482353b), UINT64_C(0xa2bfe8a14cf10364), UINT64_C(0xa81a664bbc423001), UINT64_C(0xc24b8b70d0f89791), UINT64_C(0xc76c51a30654be30), - UINT64_C(0xd192e819d6ef5218), UINT64_C(0xd69906245565a910), + UINT64_C(0xd192e819d6ef5218), UINT64_C(0xd69906245565a910), UINT64_C(0xf40e35855771202a), UINT64_C(0x106aa07032bbd1b8), - UINT64_C(0x19a4c116b8d2d0c8), UINT64_C(0x1e376c085141ab53), + UINT64_C(0x19a4c116b8d2d0c8), UINT64_C(0x1e376c085141ab53), UINT64_C(0x2748774cdf8eeb99), UINT64_C(0x34b0bcb5e19b48a8), - UINT64_C(0x391c0cb3c5c95a63), UINT64_C(0x4ed8aa4ae3418acb), + UINT64_C(0x391c0cb3c5c95a63), UINT64_C(0x4ed8aa4ae3418acb), UINT64_C(0x5b9cca4f7763e373), UINT64_C(0x682e6ff3d6b2b8a3), - UINT64_C(0x748f82ee5defb2fc), UINT64_C(0x78a5636f43172f60), + UINT64_C(0x748f82ee5defb2fc), UINT64_C(0x78a5636f43172f60), UINT64_C(0x84c87814a1f0ab72), UINT64_C(0x8cc702081a6439ec), - UINT64_C(0x90befffa23631e28), UINT64_C(0xa4506cebde82bde9), + UINT64_C(0x90befffa23631e28), UINT64_C(0xa4506cebde82bde9), UINT64_C(0xbef9a3f7b2c67915), UINT64_C(0xc67178f2e372532b), - UINT64_C(0xca273eceea26619c), UINT64_C(0xd186b8c721c0c207), + UINT64_C(0xca273eceea26619c), UINT64_C(0xd186b8c721c0c207), UINT64_C(0xeada7dd6cde0eb1e), UINT64_C(0xf57d4f7fee6ed178), - UINT64_C(0x06f067aa72176fba), UINT64_C(0x0a637dc5a2c898a6), + UINT64_C(0x06f067aa72176fba), UINT64_C(0x0a637dc5a2c898a6), UINT64_C(0x113f9804bef90dae), UINT64_C(0x1b710b35131c471b), - UINT64_C(0x28db77f523047d84), UINT64_C(0x32caab7b40c72493), + UINT64_C(0x28db77f523047d84), UINT64_C(0x32caab7b40c72493), UINT64_C(0x3c9ebe0a15c9bebc), UINT64_C(0x431d67c49c100d4c), - UINT64_C(0x4cc5d4becb3e42b6), UINT64_C(0x597f299cfc657e2a), + UINT64_C(0x4cc5d4becb3e42b6), UINT64_C(0x597f299cfc657e2a), UINT64_C(0x5fcb6fab3ad6faec), UINT64_C(0x6c44198c4a475817) }; @@ -76,7 +76,7 @@ static const uint64_t K[80] = { #define Ch(x,y,z) (z ^ (x & (y ^ z))) -#define Maj(x,y,z) (((x | y) & z) | (x & y)) +#define Maj(x,y,z) (((x | y) & z) | (x & y)) #define S(x, n) ROR64c(x, n) #define R(x, n) (((x) &UINT64_C(0xFFFFFFFFFFFFFFFF))>>((uint64_t)n)) #define Sigma0(x) (S(x, 28) ^ S(x, 34) ^ S(x, 39)) @@ -88,7 +88,7 @@ static const uint64_t K[80] = { #endif /* compress 1024-bits */ -static int sha512_compress(sha512_context *md, unsigned char *buf) +static int sha512_compress(sha512_context *md, const unsigned char *buf) { uint64_t S[8], W[80], t0, t1; int i; @@ -106,7 +106,7 @@ static int sha512_compress(sha512_context *md, unsigned char *buf) /* fill W[16..79] */ for (i = 16; i < 80; i++) { W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16]; - } + } /* Compress */ #define RND(a,b,c,d,e,f,g,h,i) \ @@ -168,25 +168,26 @@ int sha512_init(sha512_context * md) { @param inlen The length of the data (octets) @return 0 if successful */ -int sha512_update (sha512_context * md, const unsigned char *in, size_t inlen) -{ +int sha512_update(sha512_context *md, const void *vin, size_t inlen) +{ + const unsigned char *in = vin; size_t n; - size_t i; - int err; - if (md == NULL) return 1; - if (in == NULL) return 1; - if (md->curlen > sizeof(md->buf)) { - return 1; - } - while (inlen > 0) { - if (md->curlen == 0 && inlen >= 128) { - if ((err = sha512_compress (md, (unsigned char *)in)) != 0) { - return err; - } - md->length += 128 * 8; - in += 128; - inlen -= 128; - } else { + size_t i; + int err; + if (md == NULL) return 1; + if (in == NULL) return 1; + if (md->curlen > sizeof(md->buf)) { + return 1; + } + while (inlen > 0) { + if (md->curlen == 0 && inlen >= 128) { + if ((err = sha512_compress (md, in)) != 0) { + return err; + } + md->length += 128 * 8; + in += 128; + inlen -= 128; + } else { n = MIN(inlen, (128 - md->curlen)); for (i = 0; i < n; i++) { @@ -194,19 +195,19 @@ int sha512_update (sha512_context * md, const unsigned char *in, size_t inlen) } - md->curlen += n; - in += n; - inlen -= n; - if (md->curlen == 128) { - if ((err = sha512_compress (md, md->buf)) != 0) { - return err; - } - md->length += 8*128; - md->curlen = 0; - } - } - } - return 0; + md->curlen += n; + in += n; + inlen -= n; + if (md->curlen == 128) { + if ((err = sha512_compress (md, md->buf)) != 0) { + return err; + } + md->length += 8*128; + md->curlen = 0; + } + } + } + return 0; } /** @@ -215,22 +216,23 @@ int sha512_update (sha512_context * md, const unsigned char *in, size_t inlen) @param out [out] The destination of the hash (64 bytes) @return 0 if successful */ - int sha512_final(sha512_context * md, unsigned char *out) - { +int sha512_final(sha512_context * md, void *vout) +{ int i; + unsigned char *out = vout; if (md == NULL) return 1; if (out == NULL) return 1; if (md->curlen >= sizeof(md->buf)) { - return 1; - } + return 1; + } /* increase the length of the message */ - md->length += md->curlen * UINT64_C(8); + md->length += md->curlen * UINT64_C(8); /* append the '1' bit */ - md->buf[md->curlen++] = (unsigned char)0x80; + md->buf[md->curlen++] = (unsigned char)0x80; /* if the length is currently above 112 bytes we append zeros * then compress. Then we can fall back to padding zeros and length @@ -244,27 +246,27 @@ int sha512_update (sha512_context * md, const unsigned char *in, size_t inlen) md->curlen = 0; } - /* pad upto 120 bytes of zeroes + /* pad upto 120 bytes of zeroes * note: that from 112 to 120 is the 64 MSB of the length. We assume that you won't hash * > 2^64 bits of data... :-) */ -while (md->curlen < 120) { - md->buf[md->curlen++] = (unsigned char)0; -} + while (md->curlen < 120) { + md->buf[md->curlen++] = (unsigned char)0; + } /* store length */ -STORE64H(md->length, md->buf+120); -sha512_compress(md, md->buf); + STORE64H(md->length, md->buf+120); + sha512_compress(md, md->buf); /* copy output */ -for (i = 0; i < 8; i++) { - STORE64H(md->state[i], out+(8*i)); + for (i = 0; i < 8; i++) { + STORE64H(md->state[i], out+(8*i)); + } + + return 0; } -return 0; -} - -int sha512(const unsigned char *message, size_t message_len, unsigned char *out) +int sha512(const void *message, size_t message_len, void *out) { sha512_context ctx; int ret; diff --git a/src/ed25519/sha512.h b/src/ed25519/sha512.h index e56b00e..e23f8db 100644 --- a/src/ed25519/sha512.h +++ b/src/ed25519/sha512.h @@ -14,8 +14,8 @@ typedef struct sha512_context_ { int sha512_init(sha512_context * md); -int sha512_final(sha512_context * md, unsigned char *out); -int sha512_update(sha512_context * md, const unsigned char *in, size_t inlen); -int sha512(const unsigned char *message, size_t message_len, unsigned char *out); +int sha512_final(sha512_context * md, void *out); +int sha512_update(sha512_context * md, const void *in, size_t inlen); +int sha512(const void *message, size_t message_len, void *out); -#endif \ No newline at end of file +#endif diff --git a/src/edge.c b/src/edge.c index 2eaae5d..0e35cd1 100644 --- a/src/edge.c +++ b/src/edge.c @@ -75,6 +75,7 @@ edge_t *new_edge(void) { void free_edge(edge_t *e) { sockaddrfree(&e->address); + sockaddrfree(&e->local_address); free(e); } diff --git a/src/ethernet.h b/src/ethernet.h index a8b6420..085e96a 100644 --- a/src/ethernet.h +++ b/src/ethernet.h @@ -50,7 +50,7 @@ struct ether_header { uint8_t ether_dhost[ETH_ALEN]; uint8_t ether_shost[ETH_ALEN]; uint16_t ether_type; -} __attribute__ ((__packed__)); +} __attribute__ ((__gcc_struct__, __packed__)); #endif #ifndef HAVE_STRUCT_ARPHDR @@ -60,7 +60,7 @@ struct arphdr { uint8_t ar_hln; uint8_t ar_pln; uint16_t ar_op; -} __attribute__ ((__packed__)); +} __attribute__ ((__gcc_struct__, __packed__)); #define ARPOP_REQUEST 1 #define ARPOP_REPLY 2 @@ -78,7 +78,7 @@ struct ether_arp { uint8_t arp_spa[4]; uint8_t arp_tha[ETH_ALEN]; uint8_t arp_tpa[4]; -} __attribute__ ((__packed__)); +} __attribute__ ((__gcc_struct__, __packed__)); #define arp_hrd ea_hdr.ar_hrd #define arp_pro ea_hdr.ar_pro #define arp_hln ea_hdr.ar_hln diff --git a/src/event.c b/src/event.c index 60d357d..59b96e3 100644 --- a/src/event.c +++ b/src/event.c @@ -285,6 +285,16 @@ bool event_loop(void) { io->cb(io->data, IO_WRITE); else if(FD_ISSET(io->fd, &readable)) io->cb(io->data, IO_READ); + else + continue; + + /* + There are scenarios in which the callback will remove another io_t from the tree + (e.g. closing a double connection). Since splay_each does not support that, we + need to exit the loop now. That's okay, since any remaining events will get picked + up by the next select() call. + */ + break; } } #else diff --git a/src/fake-gai-errnos.h b/src/fake-gai-errnos.h deleted file mode 100644 index 2f41d8f..0000000 --- a/src/fake-gai-errnos.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - * fake library for ssh - * - * This file is included in getaddrinfo.c and getnameinfo.c. - * See getaddrinfo.c and getnameinfo.c. - */ - -/* for old netdb.h */ -#ifndef EAI_NODATA -#define EAI_NODATA 1 -#endif - -#ifndef EAI_MEMORY -#define EAI_MEMORY 2 -#endif - -#ifndef EAI_FAMILY -#define EAI_FAMILY 3 -#endif - -#ifndef EAI_SYSTEM -#define EAI_SYSTEM 4 -#endif diff --git a/src/fake-getaddrinfo.c b/src/fake-getaddrinfo.c deleted file mode 100644 index cb821b5..0000000 --- a/src/fake-getaddrinfo.c +++ /dev/null @@ -1,102 +0,0 @@ -/* - * fake library for ssh - * - * This file includes getaddrinfo(), freeaddrinfo() and gai_strerror(). - * These funtions are defined in rfc2133. - * - * But these functions are not implemented correctly. The minimum subset - * is implemented for ssh use only. For exapmle, this routine assumes - * that ai_family is AF_INET. Don't use it for another purpose. - */ - -#include "system.h" - -#include "ipv4.h" -#include "ipv6.h" -#include "fake-getaddrinfo.h" -#include "xalloc.h" - - -#if !HAVE_DECL_GAI_STRERROR -char *gai_strerror(int ecode) { - switch (ecode) { - case EAI_NODATA: - return "No address associated with hostname"; - case EAI_MEMORY: - return "Memory allocation failure"; - case EAI_FAMILY: - return "Address family not supported"; - default: - return "Unknown error"; - } -} -#endif /* !HAVE_GAI_STRERROR */ - -#if !HAVE_DECL_FREEADDRINFO -void freeaddrinfo(struct addrinfo *ai) { - struct addrinfo *next; - - while(ai) { - next = ai->ai_next; - free(ai); - ai = next; - } -} -#endif /* !HAVE_FREEADDRINFO */ - -#if !HAVE_DECL_GETADDRINFO -static struct addrinfo *malloc_ai(uint16_t port, uint32_t addr) { - struct addrinfo *ai; - - ai = xzalloc(sizeof(struct addrinfo) + sizeof(struct sockaddr_in)); - - ai->ai_addr = (struct sockaddr *)(ai + 1); - ai->ai_addrlen = sizeof(struct sockaddr_in); - ai->ai_addr->sa_family = ai->ai_family = AF_INET; - - ((struct sockaddr_in *)(ai)->ai_addr)->sin_port = port; - ((struct sockaddr_in *)(ai)->ai_addr)->sin_addr.s_addr = addr; - - return ai; -} - -int getaddrinfo(const char *hostname, const char *servname, const struct addrinfo *hints, struct addrinfo **res) { - struct addrinfo *prev = NULL; - struct hostent *hp; - struct in_addr in = {0}; - int i; - uint16_t port = 0; - - if(hints && hints->ai_family != AF_INET && hints->ai_family != AF_UNSPEC) - return EAI_FAMILY; - - if (servname) - port = htons(atoi(servname)); - - if (hints && hints->ai_flags & AI_PASSIVE) { - *res = malloc_ai(port, htonl(0x00000000)); - return 0; - } - - if (!hostname) { - *res = malloc_ai(port, htonl(0x7f000001)); - return 0; - } - - hp = gethostbyname(hostname); - - if(!hp || !hp->h_addr_list || !hp->h_addr_list[0]) - return EAI_NODATA; - - for (i = 0; hp->h_addr_list[i]; i++) { - *res = malloc_ai(port, ((struct in_addr *)hp->h_addr_list[i])->s_addr); - - if(prev) - prev->ai_next = *res; - - prev = *res; - } - - return 0; -} -#endif /* !HAVE_GETADDRINFO */ diff --git a/src/fake-getaddrinfo.h b/src/fake-getaddrinfo.h deleted file mode 100644 index 5809985..0000000 --- a/src/fake-getaddrinfo.h +++ /dev/null @@ -1,46 +0,0 @@ -#ifndef _FAKE_GETADDRINFO_H -#define _FAKE_GETADDRINFO_H - -#include "fake-gai-errnos.h" - -#ifndef AI_PASSIVE -# define AI_PASSIVE 1 -# define AI_CANONNAME 2 -#endif - -#ifndef NI_NUMERICHOST -# define NI_NUMERICHOST 2 -# define NI_NAMEREQD 4 -# define NI_NUMERICSERV 8 -#endif - -#ifndef AI_NUMERICHOST -#define AI_NUMERICHOST 4 -#endif - -#ifndef HAVE_STRUCT_ADDRINFO -struct addrinfo { - int ai_flags; /* AI_PASSIVE, AI_CANONNAME */ - int ai_family; /* PF_xxx */ - int ai_socktype; /* SOCK_xxx */ - int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */ - size_t ai_addrlen; /* length of ai_addr */ - char *ai_canonname; /* canonical name for hostname */ - struct sockaddr *ai_addr; /* binary address */ - struct addrinfo *ai_next; /* next structure in linked list */ -}; -#endif /* !HAVE_STRUCT_ADDRINFO */ - -#if !HAVE_DECL_GETADDRINFO -int getaddrinfo(const char *hostname, const char *servname, const struct addrinfo *hints, struct addrinfo **res); -#endif /* !HAVE_GETADDRINFO */ - -#if !HAVE_DECL_GAI_STRERROR -char *gai_strerror(int ecode); -#endif /* !HAVE_GAI_STRERROR */ - -#if !HAVE_DECL_FREEADDRINFO -void freeaddrinfo(struct addrinfo *ai); -#endif /* !HAVE_FREEADDRINFO */ - -#endif /* _FAKE_GETADDRINFO_H */ diff --git a/src/fake-getnameinfo.c b/src/fake-getnameinfo.c deleted file mode 100644 index 4a4d132..0000000 --- a/src/fake-getnameinfo.c +++ /dev/null @@ -1,54 +0,0 @@ -/* - * fake library for ssh - * - * This file includes getnameinfo(). - * These funtions are defined in rfc2133. - * - * But these functions are not implemented correctly. The minimum subset - * is implemented for ssh use only. For exapmle, this routine assumes - * that ai_family is AF_INET. Don't use it for another purpose. - */ - -#include "system.h" - -#include "fake-getnameinfo.h" -#include "fake-getaddrinfo.h" - -#if !HAVE_DECL_GETNAMEINFO - -int getnameinfo(const struct sockaddr *sa, size_t salen, char *host, size_t hostlen, char *serv, size_t servlen, int flags) { - struct sockaddr_in *sin = (struct sockaddr_in *)sa; - struct hostent *hp; - int len; - - if(sa->sa_family != AF_INET) - return EAI_FAMILY; - - if(serv && servlen) { - len = snprintf(serv, servlen, "%d", ntohs(sin->sin_port)); - if(len < 0 || len >= servlen) - return EAI_MEMORY; - } - - if(!host || !hostlen) - return 0; - - if(flags & NI_NUMERICHOST) { - len = snprintf(host, hostlen, "%s", inet_ntoa(sin->sin_addr)); - if(len < 0 || len >= hostlen) - return EAI_MEMORY; - return 0; - } - - hp = gethostbyaddr((char *)&sin->sin_addr, sizeof(struct in_addr), AF_INET); - - if(!hp || !hp->h_name || !hp->h_name[0]) - return EAI_NODATA; - - len = snprintf(host, hostlen, "%s", hp->h_name); - if(len < 0 || len >= hostlen) - return EAI_MEMORY; - - return 0; -} -#endif /* !HAVE_GETNAMEINFO */ diff --git a/src/fake-getnameinfo.h b/src/fake-getnameinfo.h deleted file mode 100644 index 043ed97..0000000 --- a/src/fake-getnameinfo.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef _FAKE_GETNAMEINFO_H -#define _FAKE_GETNAMEINFO_H - -#if !HAVE_DECL_GETNAMEINFO -int getnameinfo(const struct sockaddr *sa, size_t salen, char *host, size_t hostlen, char *serv, size_t servlen, int flags); -#endif /* !HAVE_GETNAMEINFO */ - -#ifndef NI_MAXSERV -# define NI_MAXSERV 32 -#endif /* !NI_MAXSERV */ -#ifndef NI_MAXHOST -# define NI_MAXHOST 1025 -#endif /* !NI_MAXHOST */ - -#endif /* _FAKE_GETNAMEINFO_H */ diff --git a/src/fsck.c b/src/fsck.c new file mode 100644 index 0000000..b90710b --- /dev/null +++ b/src/fsck.c @@ -0,0 +1,498 @@ +/* + fsck.c -- Check the configuration files for problems + Copyright (C) 2014 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "system.h" + +#include "crypto.h" +#include "ecdsa.h" +#include "ecdsagen.h" +#include "fsck.h" +#include "names.h" +#ifndef DISABLE_LEGACY +#include "rsa.h" +#include "rsagen.h" +#endif +#include "tincctl.h" +#include "utils.h" + +static bool ask_fix(void) { + if(force) + return true; + if(!tty) + return false; +again: + fprintf(stderr, "Fix y/n? "); + char buf[1024]; + if(!fgets(buf, sizeof buf, stdin)) { + tty = false; + return false; + } + if(buf[0] == 'y' || buf[0] == 'Y') + return true; + if(buf[0] == 'n' || buf[0] == 'N') + return false; + goto again; +} + +static void print_tinc_cmd(const char *argv0, const char *format, ...) { + if(confbasegiven) + fprintf(stderr, "%s -c %s ", argv0, confbase); + else if(netname) + fprintf(stderr, "%s -n %s ", argv0, netname); + else + fprintf(stderr, "%s ", argv0); + va_list va; + va_start(va, format); + vfprintf(stderr, format, va); + va_end(va); + fputc('\n', stderr); +} + +static int strtailcmp(const char *str, const char *tail) { + size_t slen = strlen(str); + size_t tlen = strlen(tail); + if(tlen > slen) + return -1; + return memcmp(str + slen - tlen, tail, tlen); +} + +static void check_conffile(const char *fname, bool server) { + FILE *f = fopen(fname, "r"); + if(!f) { + fprintf(stderr, "ERROR: cannot read %s: %s\n", fname, strerror(errno)); + return; + } + + char line[2048]; + int lineno = 0; + bool skip = false; + const int maxvariables = 50; + int count[maxvariables]; + memset(count, 0, sizeof count); + + while(fgets(line, sizeof line, f)) { + if(skip) { + if(!strncmp(line, "-----END", 8)) + skip = false; + continue; + } else { + if(!strncmp(line, "-----BEGIN", 10)) { + skip = true; + continue; + } + } + + int len; + char *variable, *value, *eol; + variable = value = line; + + lineno++; + + eol = line + strlen(line); + while(strchr("\t \r\n", *--eol)) + *eol = '\0'; + + if(!line[0] || line[0] == '#') + continue; + + len = strcspn(value, "\t ="); + value += len; + value += strspn(value, "\t "); + if(*value == '=') { + value++; + value += strspn(value, "\t "); + } + variable[len] = '\0'; + + bool found = false; + + for(int i = 0; variables[i].name; i++) { + if(strcasecmp(variables[i].name, variable)) + continue; + + found = true; + + if(variables[i].type & VAR_OBSOLETE) { + fprintf(stderr, "WARNING: obsolete variable %s in %s line %d\n", variable, fname, lineno); + } + + if(i < maxvariables) + count[i]++; + } + + if(!found) + fprintf(stderr, "WARNING: unknown variable %s in %s line %d\n", variable, fname, lineno); + + if(!*value) + fprintf(stderr, "ERROR: no value for variable %s in %s line %d\n", variable, fname, lineno); + } + + for(int i = 0; variables[i].name && i < maxvariables; i++) { + if(count[i] > 1 && !(variables[i].type & VAR_MULTIPLE)) + fprintf(stderr, "WARNING: multiple instances of variable %s in %s\n", variables[i].name, fname); + } + + if(ferror(f)) + fprintf(stderr, "ERROR: while reading %s: %s\n", fname, strerror(errno)); + + fclose(f); +} + +int fsck(const char *argv0) { +#ifdef HAVE_MINGW + int uid = 0; +#else + uid_t uid = getuid(); +#endif + + // Check that tinc.conf is readable. + + if(access(tinc_conf, R_OK)) { + fprintf(stderr, "ERROR: cannot read %s: %s\n", tinc_conf, strerror(errno)); + if(errno == ENOENT) { + fprintf(stderr, "No tinc configuration found. Create a new one with:\n\n"); + print_tinc_cmd(argv0, "init"); + } else if(errno == EACCES) { + if(uid != 0) + fprintf(stderr, "You are currently not running tinc as root. Use sudo?\n"); + else + fprintf(stderr, "Check the permissions of each component of the path %s.\n", tinc_conf); + } + return 1; + } + + char *name = get_my_name(true); + if(!name) { + fprintf(stderr, "ERROR: tinc cannot run without a valid Name.\n"); + return 1; + } + + // Check for private keys. + // TODO: use RSAPrivateKeyFile and Ed25519PrivateKeyFile variables if present. + + struct stat st; + char fname[PATH_MAX]; + char dname[PATH_MAX]; + +#ifndef DISABLE_LEGACY + rsa_t *rsa_priv = NULL; + snprintf(fname, sizeof fname, "%s/rsa_key.priv", confbase); + + if(stat(fname, &st)) { + if(errno != ENOENT) { + // Something is seriously wrong here. If we can access the directory with tinc.conf in it, we should certainly be able to stat() an existing file. + fprintf(stderr, "ERROR: cannot read %s: %s\n", fname, strerror(errno)); + fprintf(stderr, "Please correct this error.\n"); + return 1; + } + } else { + FILE *f = fopen(fname, "r"); + if(!f) { + fprintf(stderr, "ERROR: could not open %s: %s\n", fname, strerror(errno)); + return 1; + } + rsa_priv = rsa_read_pem_private_key(f); + fclose(f); + if(!rsa_priv) { + fprintf(stderr, "ERROR: No key or unusable key found in %s.\n", fname); + fprintf(stderr, "You can generate a new RSA key with:\n\n"); + print_tinc_cmd(argv0, "generate-rsa-keys"); + return 1; + } + +#if !defined(HAVE_MINGW) && !defined(HAVE_CYGWIN) + if(st.st_mode & 077) { + fprintf(stderr, "WARNING: unsafe file permissions on %s.\n", fname); + if(st.st_uid != uid) { + fprintf(stderr, "You are not running %s as the same uid as %s.\n", argv0, fname); + } else if(ask_fix()) { + if(chmod(fname, st.st_mode & ~077)) + fprintf(stderr, "ERROR: could not change permissions of %s: %s\n", fname, strerror(errno)); + else + fprintf(stderr, "Fixed permissions of %s.\n", fname); + } + } +#endif + } +#endif + + ecdsa_t *ecdsa_priv = NULL; + snprintf(fname, sizeof fname, "%s/ed25519_key.priv", confbase); + + if(stat(fname, &st)) { + if(errno != ENOENT) { + // Something is seriously wrong here. If we can access the directory with tinc.conf in it, we should certainly be able to stat() an existing file. + fprintf(stderr, "ERROR: cannot read %s: %s\n", fname, strerror(errno)); + fprintf(stderr, "Please correct this error.\n"); + return 1; + } + } else { + FILE *f = fopen(fname, "r"); + if(!f) { + fprintf(stderr, "ERROR: could not open %s: %s\n", fname, strerror(errno)); + return 1; + } + ecdsa_priv = ecdsa_read_pem_private_key(f); + fclose(f); + if(!ecdsa_priv) { + fprintf(stderr, "ERROR: No key or unusable key found in %s.\n", fname); + fprintf(stderr, "You can generate a new Ed25519 key with:\n\n"); + print_tinc_cmd(argv0, "generate-ed25519-keys"); + return 1; + } + +#if !defined(HAVE_MINGW) && !defined(HAVE_CYGWIN) + if(st.st_mode & 077) { + fprintf(stderr, "WARNING: unsafe file permissions on %s.\n", fname); + if(st.st_uid != uid) { + fprintf(stderr, "You are not running %s as the same uid as %s.\n", argv0, fname); + } else if(ask_fix()) { + if(chmod(fname, st.st_mode & ~077)) + fprintf(stderr, "ERROR: could not change permissions of %s: %s\n", fname, strerror(errno)); + else + fprintf(stderr, "Fixed permissions of %s.\n", fname); + } + } +#endif + } + +#ifdef DISABLE_LEGACY + if(!ecdsa_priv) { + fprintf(stderr, "ERROR: No Ed25519 private key found.\n"); +#else + if(!rsa_priv && !ecdsa_priv) { + fprintf(stderr, "ERROR: Neither RSA or Ed25519 private key found.\n"); +#endif + fprintf(stderr, "You can generate new keys with:\n\n"); + print_tinc_cmd(argv0, "generate-keys"); + return 1; + } + + // Check for public keys. + // TODO: use RSAPublicKeyFile variable if present. + + snprintf(fname, sizeof fname, "%s/hosts/%s", confbase, name); + if(access(fname, R_OK)) + fprintf(stderr, "WARNING: cannot read %s\n", fname); + + FILE *f; + +#ifndef DISABLE_LEGACY + rsa_t *rsa_pub = NULL; + + f = fopen(fname, "r"); + if(f) + rsa_pub = rsa_read_pem_public_key(f); + fclose(f); + + if(rsa_priv) { + if(!rsa_pub) { + fprintf(stderr, "WARNING: No (usable) public RSA key found.\n"); + if(ask_fix()) { + FILE *f = fopen(fname, "a"); + if(f) { + if(rsa_write_pem_public_key(rsa_priv, f)) + fprintf(stderr, "Wrote RSA public key to %s.\n", fname); + else + fprintf(stderr, "ERROR: could not write RSA public key to %s.\n", fname); + fclose(f); + } else { + fprintf(stderr, "ERROR: could not append to %s: %s\n", fname, strerror(errno)); + } + } + } else { + // TODO: suggest remedies + size_t len = rsa_size(rsa_priv); + if(len != rsa_size(rsa_pub)) { + fprintf(stderr, "ERROR: public and private RSA keys do not match.\n"); + return 1; + } + char buf1[len], buf2[len], buf3[len]; + randomize(buf1, sizeof buf1); + buf1[0] &= 0x7f; + memset(buf2, 0, sizeof buf2); + memset(buf3, 0, sizeof buf2); + if(!rsa_public_encrypt(rsa_pub, buf1, sizeof buf1, buf2)) { + fprintf(stderr, "ERROR: public RSA key does not work.\n"); + return 1; + } + if(!rsa_private_decrypt(rsa_priv, buf2, sizeof buf2, buf3)) { + fprintf(stderr, "ERROR: private RSA key does not work.\n"); + return 1; + } + if(memcmp(buf1, buf3, sizeof buf1)) { + fprintf(stderr, "ERROR: public and private RSA keys do not match.\n"); + return 1; + } + } + } else { + if(rsa_pub) + fprintf(stderr, "WARNING: A public RSA key was found but no private key is known.\n"); + } +#endif + + ecdsa_t *ecdsa_pub = NULL; + + f = fopen(fname, "r"); + if(f) { + ecdsa_pub = get_pubkey(f); + if(!f) { + rewind(f); + ecdsa_pub = ecdsa_read_pem_public_key(f); + } + } + fclose(f); + + if(ecdsa_priv) { + if(!ecdsa_pub) { + fprintf(stderr, "WARNING: No (usable) public Ed25519 key found.\n"); + if(ask_fix()) { + FILE *f = fopen(fname, "a"); + if(f) { + if(ecdsa_write_pem_public_key(ecdsa_priv, f)) + fprintf(stderr, "Wrote Ed25519 public key to %s.\n", fname); + else + fprintf(stderr, "ERROR: could not write Ed25519 public key to %s.\n", fname); + fclose(f); + } else { + fprintf(stderr, "ERROR: could not append to %s: %s\n", fname, strerror(errno)); + } + } + } else { + // TODO: suggest remedies + char *key1 = ecdsa_get_base64_public_key(ecdsa_pub); + if(!key1) { + fprintf(stderr, "ERROR: public Ed25519 key does not work.\n"); + return 1; + } + char *key2 = ecdsa_get_base64_public_key(ecdsa_priv); + if(!key2) { + free(key1); + fprintf(stderr, "ERROR: private Ed25519 key does not work.\n"); + return 1; + } + int result = strcmp(key1, key2); + free(key1); + free(key2); + if(result) { + fprintf(stderr, "ERROR: public and private Ed25519 keys do not match.\n"); + return 1; + } + } + } else { + if(ecdsa_pub) + fprintf(stderr, "WARNING: A public Ed25519 key was found but no private key is known.\n"); + } + + // Check whether scripts are executable + + struct dirent *ent; + DIR *dir = opendir(confbase); + if(!dir) { + fprintf(stderr, "ERROR: cannot read directory %s: %s\n", confbase, strerror(errno)); + return 1; + } + + while((ent = readdir(dir))) { + if(strtailcmp(ent->d_name, "-up") && strtailcmp(ent->d_name, "-down")) + continue; + + strncpy(fname, ent->d_name, sizeof fname); + char *dash = strrchr(fname, '-'); + if(!dash) + continue; + *dash = 0; + + if(strcmp(fname, "tinc") && strcmp(fname, "host") && strcmp(fname, "subnet")) { + static bool explained = false; + fprintf(stderr, "WARNING: Unknown script %s" SLASH "%s found.\n", confbase, ent->d_name); + if(!explained) { + fprintf(stderr, "The only scripts in %s executed by tinc are:\n", confbase); + fprintf(stderr, "tinc-up, tinc-down, host-up, host-down, subnet-up and subnet-down.\n"); + explained = true; + } + continue; + } + + snprintf(fname, sizeof fname, "%s" SLASH "%s", confbase, ent->d_name); + if(access(fname, R_OK | X_OK)) { + if(errno != EACCES) { + fprintf(stderr, "ERROR: cannot access %s: %s\n", fname, strerror(errno)); + continue; + } + fprintf(stderr, "WARNING: cannot read and execute %s: %s\n", fname, strerror(errno)); + if(ask_fix()) { + if(chmod(fname, 0755)) + fprintf(stderr, "ERROR: cannot change permissions on %s: %s\n", fname, strerror(errno)); + } + } + } + closedir(dir); + + snprintf(dname, sizeof dname, "%s" SLASH "hosts", confbase); + dir = opendir(dname); + if(!dir) { + fprintf(stderr, "ERROR: cannot read directory %s: %s\n", dname, strerror(errno)); + return 1; + } + + while((ent = readdir(dir))) { + if(strtailcmp(ent->d_name, "-up") && strtailcmp(ent->d_name, "-down")) + continue; + + strncpy(fname, ent->d_name, sizeof fname); + char *dash = strrchr(fname, '-'); + if(!dash) + continue; + *dash = 0; + + snprintf(fname, sizeof fname, "%s" SLASH "hosts" SLASH "%s", confbase, ent->d_name); + if(access(fname, R_OK | X_OK)) { + if(errno != EACCES) { + fprintf(stderr, "ERROR: cannot access %s: %s\n", fname, strerror(errno)); + continue; + } + fprintf(stderr, "WARNING: cannot read and execute %s: %s\n", fname, strerror(errno)); + if(ask_fix()) { + if(chmod(fname, 0755)) + fprintf(stderr, "ERROR: cannot change permissions on %s: %s\n", fname, strerror(errno)); + } + } + } + closedir(dir); + + // Check for obsolete / unsafe / unknown configuration variables. + + check_conffile(tinc_conf, true); + + dir = opendir(dname); + if(dir) { + while((ent = readdir(dir))) { + if(!check_id(ent->d_name)) + continue; + + snprintf(fname, sizeof fname, "%s" SLASH "hosts" SLASH "%s", confbase, ent->d_name); + check_conffile(fname, false); + } + closedir(dir); + } + + return 0; +} + diff --git a/src/gcrypt/ecdh.c b/src/fsck.h similarity index 60% rename from src/gcrypt/ecdh.c rename to src/fsck.h index 4e30733..51e4f55 100644 --- a/src/gcrypt/ecdh.c +++ b/src/fsck.h @@ -1,6 +1,6 @@ /* - ecdh.c -- Diffie-Hellman key exchange handling - Copyright (C) 2011-2013 Guus Sliepen + fsck.h -- header for fsck.c. + Copyright (C) 2012 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 @@ -17,21 +17,10 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#include "../system.h" +#ifndef __TINC_FSCK_H__ +#define __TINC_FSCK_H__ -#include "../ecdh.h" -#include "../logger.h" -#include "../utils.h" -#include "../xalloc.h" +extern int fsck(const char *argv0); -ecdh_t *ecdh_generate_public(void *pubkey) { - logger(DEBUG_ALWAYS, LOG_ERR, "EC support using libgcrypt not implemented"); - return NULL; -} +#endif -bool ecdh_compute_shared(ecdh_t *ecdh, const void *pubkey, void *shared) { - return false -} - -void ecdh_free(ecdh_t *ecdh) { -} diff --git a/src/gcrypt/ecdsa.c b/src/gcrypt/ecdsa.c deleted file mode 100644 index ee19aec..0000000 --- a/src/gcrypt/ecdsa.c +++ /dev/null @@ -1,67 +0,0 @@ -/* - ecdsa.c -- ECDSA key handling - Copyright (C) 2011-2013 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 - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include "../system.h" - -#include "../logger.h" -#include "../ecdsa.h" -#include "../utils.h" -#include "../xalloc.h" - -// Get and set ECDSA keys -// -ecdsa_t *ecdsa_set_base64_public_key(const char *p) { - logger(DEBUG_ALWAYS, LOG_ERR, "EC support using libgcrypt not implemented"); - return NULL; -} - -char *ecdsa_get_base64_public_key(ecdsa_t *ecdsa) { - return NULL; -} - -// Read PEM ECDSA keys - -ecdsa_t *ecdsa_read_pem_public_key(FILE *fp) { - logger(DEBUG_ALWAYS, LOG_ERR, "EC support using libgcrypt not implemented"); - return NULL; -} - -ecdsa_t *ecdsa_read_pem_private_key(FILE *fp) { - logger(DEBUG_ALWAYS, LOG_ERR, "EC support using libgcrypt not implemented"); - return NULL; -} - -size_t ecdsa_size(ecdsa_t *ecdsa) { - return 0; -} - -bool ecdsa_sign(ecdsa_t *ecdsa, const void *in, size_t len, void *sig) { - return false; -} - -bool ecdsa_verify(ecdsa_t *ecdsa, const void *in, size_t len, const void *sig) { - return false; -} - -bool ecdsa_active(ecdsa_t *ecdsa) { - return false; -} - -void ecdsa_free(ecdsa_t *ecdsa) { -} diff --git a/src/gcrypt/prf.c b/src/gcrypt/prf.c index f9a2112..55c9923 100644 --- a/src/gcrypt/prf.c +++ b/src/gcrypt/prf.c @@ -19,11 +19,88 @@ #include "../system.h" -#include "digest.h" -#include "../digest.h" #include "../prf.h" +#include "../ed25519/sha512.h" + +static void memxor(char *buf, char c, size_t len) { + for(size_t i = 0; i < len; i++) + buf[i] ^= c; +} + +static const size_t mdlen = 64; +static const size_t blklen = 128; + +static bool hmac_sha512(const char *key, size_t keylen, const char *msg, size_t msglen, char *out) { + char tmp[blklen + mdlen]; + sha512_context md; + + if(keylen <= blklen) { + memcpy(tmp, key, keylen); + memset(tmp + keylen, 0, blklen - keylen); + } else { + if(sha512(key, keylen, tmp) != 0) + return false; + memset(tmp + mdlen, 0, blklen - mdlen); + } + + if(sha512_init(&md) != 0) + return false; + + // ipad + memxor(tmp, 0x36, blklen); + if(sha512_update(&md, tmp, blklen) != 0) + return false; + + // message + if(sha512_update(&md, msg, msglen) != 0) + return false; + + if(sha512_final(&md, tmp + blklen) != 0) + return false; + + // opad + memxor(tmp, 0x36 ^ 0x5c, blklen); + if(sha512(tmp, sizeof tmp, out) != 0) + return false; + + return true; +} + + +/* Generate key material from a master secret and a seed, based on RFC 4346 section 5. + We use SHA512 instead of MD5 and SHA1. + */ bool prf(const char *secret, size_t secretlen, char *seed, size_t seedlen, char *out, size_t outlen) { - logger(DEBUG_ALWAYS, LOG_ERR, "PRF support using libgcrypt not implemented"); - return false; + /* Data is what the "inner" HMAC function processes. + It consists of the previous HMAC result plus the seed. + */ + + char data[mdlen + seedlen]; + memset(data, 0, mdlen); + memcpy(data + mdlen, seed, seedlen); + + char hash[mdlen]; + + while(outlen > 0) { + /* Inner HMAC */ + if(!hmac_sha512(secret, secretlen, data, sizeof data, data)) + return false; + + /* Outer HMAC */ + if(outlen >= mdlen) { + if(!hmac_sha512(secret, secretlen, data, sizeof data, out)) + return false; + out += mdlen; + outlen -= mdlen; + } else { + if(!hmac_sha512(secret, secretlen, data, sizeof data, hash)) + return false; + memcpy(out, hash, outlen); + out += outlen; + outlen = 0; + } + } + + return true; } diff --git a/src/graph.c b/src/graph.c index 70d6573..e570feb 100644 --- a/src/graph.c +++ b/src/graph.c @@ -149,7 +149,7 @@ static void sssp_bfs(void) { abort(); for splay_each(edge_t, e, n->edge_tree) { /* "e" is the edge connected to "from" */ - if(!e->reverse) + if(!e->reverse || e->to == myself) continue; /* Situation: @@ -238,10 +238,11 @@ static void check_reachability(void) { n->status.udp_confirmed = false; n->maxmtu = MTU; + n->maxrecentlen = 0; n->minmtu = 0; n->mtuprobes = 0; - timeout_del(&n->mtutimeout); + timeout_del(&n->udp_ping_timeout); char *name; char *address; @@ -275,6 +276,10 @@ static void check_reachability(void) { update_node_udp(n, NULL); memset(&n->status, 0, sizeof n->status); n->options = 0; + } else if(n->connection) { + // Speed up UDP probing by sending our key. + if(!n->status.sptps) + send_ans_key(n); } } diff --git a/src/hash.c b/src/hash.c index 91fc3d6..50934d9 100644 --- a/src/hash.c +++ b/src/hash.c @@ -29,7 +29,7 @@ static uint32_t hash_function(const void *p, size_t len) { uint32_t hash = 0; while(true) { for(int i = len > 4 ? 4 : len; --i;) - hash += q[len - i] << (8 * i); + hash += (uint32_t)q[len - i] << (8 * i); hash *= 0x9e370001UL; // Golden ratio prime. if(len <= 4) break; diff --git a/src/have.h b/src/have.h index 85479f7..faa4c9e 100644 --- a/src/have.h +++ b/src/have.h @@ -1,7 +1,7 @@ /* have.h -- include headers which are known to exist Copyright (C) 1998-2005 Ivo Timmermans - 2003-2013 Guus Sliepen + 2003-2016 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 @@ -22,17 +22,14 @@ #define __TINC_HAVE_H__ #ifdef HAVE_MINGW -#ifdef WITH_WINDOWS2000 -#define WINVER Windows2000 -#else #define WINVER WindowsXP -#endif #define WIN32_LEAN_AND_MEAN #endif #include #include #include +#include #include #include #include @@ -40,6 +37,8 @@ #include #include #include +#include +#include #ifdef HAVE_MINGW #include @@ -48,10 +47,6 @@ #include #endif -#ifdef HAVE_STDBOOL_H -#include -#endif - #ifdef HAVE_TERMIOS_H #include #endif @@ -70,9 +65,6 @@ #include #endif -#ifdef HAVE_TIME_H -#include -#endif #ifdef HAVE_SYS_TYPES_H #include @@ -102,10 +94,6 @@ #include #endif -#ifdef HAVE_SYS_UIO_H -#include -#endif - #ifdef HAVE_SYS_UN_H #include #endif @@ -197,6 +185,28 @@ #include #endif +#ifdef HAVE_ARPA_NAMESER_H +#include +#endif + +#ifdef HAVE_RESOLV_H +#include +#endif + +#ifdef HAVE_LINUX_IF_TUN_H +#include +#endif + +#ifdef HAVE_GETOPT_H +#include +#else +#include "getopt.h" +#endif + +#ifdef STATUS +#undef STATUS +#endif + #ifdef HAVE_MINGW #define SLASH "\\" #else diff --git a/src/ifconfig.c b/src/ifconfig.c new file mode 100644 index 0000000..7688a3c --- /dev/null +++ b/src/ifconfig.c @@ -0,0 +1,198 @@ +/* + ifconfig.c -- Generate platform specific interface configuration commands + Copyright (C) 2016 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "system.h" + +#include "conf.h" +#include "ifconfig.h" +#include "subnet.h" + +static long start; + +#ifndef HAVE_MINGW +void ifconfig_header(FILE *out) { + fprintf(out, "#!/bin/sh\n"); + start = ftell(out); +} + +void ifconfig_dhcp(FILE *out) { + fprintf(out, "dhclient -nw \"$INTERFACE\"\n"); +} + +void ifconfig_dhcp6(FILE *out) { + fprintf(out, "dhclient -6 -nw \"$INTERFACE\"\n"); +} + +void ifconfig_slaac(FILE *out) { +#ifdef HAVE_LINUX + fprintf(out, "echo 1 >\"/proc/sys/net/ipv6/conf/$INTERFACE/accept_ra\"\n"); + fprintf(out, "echo 1 >\"/proc/sys/net/ipv6/conf/$INTERFACE/autoconf\"\n"); +#else + fprintf(out, "rtsol \"$INTERFACE\" &\n"); +#endif +} + +bool ifconfig_footer(FILE *out) { + if(ftell(out) == start) { + fprintf(out, "echo 'Unconfigured tinc-up script, please edit '$0'!'\n\n#ifconfig $INTERFACE netmask \n"); + return false; + } else { +#ifdef HAVE_LINUX + fprintf(out, "ip link set \"$INTERFACE\" up\n"); +#else + fprintf(out, "ifconfig \"$INTERFACE\" up\n"); +#endif + return true; + } +} +#else +void ifconfig_header(FILE *out) { + start = ftell(out); +} + +void ifconfig_dhcp(FILE *out) { + fprintf(out, "netsh interface ipv4 set address \"%%INTERFACE%%\" dhcp\n"); +} + +void ifconfig_dhcp6(FILE *out) { + fprintf(stderr, "DHCPv6 requested, but not supported by tinc on this platform\n"); +} + +void ifconfig_slaac(FILE *out) { + // It's the default? +} + +bool ifconfig_footer(FILE *out) { + return ftell(out) != start; +} +#endif + +static subnet_t ipv4, ipv6; + +void ifconfig_address(FILE *out, const char *value) { + subnet_t address = {}; + char address_str[MAXNETSTR]; + if(!str2net(&address, value) || !net2str(address_str, sizeof address_str, &address)) { + fprintf(stderr, "Could not parse address in Ifconfig statement\n"); + return; + } + switch(address.type) { + case SUBNET_IPV4: ipv4 = address; break; + case SUBNET_IPV6: ipv6 = address; break; + default: return; + } +#if defined(HAVE_LINUX) + switch(address.type) { + case SUBNET_MAC: fprintf(out, "ip link set \"$INTERFACE\" address %s\n", address_str); break; + case SUBNET_IPV4: fprintf(out, "ip addr replace %s dev \"$INTERFACE\"\n", address_str); break; + case SUBNET_IPV6: fprintf(out, "ip addr replace %s dev \"$INTERFACE\"\n", address_str); break; + default: return; + } +#elif defined(HAVE_BSD) + switch(address.type) { + case SUBNET_MAC: fprintf(out, "ifconfig \"$INTERFACE\" link %s\n", address_str); break; + case SUBNET_IPV4: fprintf(out, "ifconfig \"$INTERFACE\" %s\n", address_str); break; + case SUBNET_IPV6: fprintf(out, "ifconfig \"$INTERFACE\" inet6 %s\n", address_str); break; + default: return; + } +#elif defined(HAVE_MINGW) || defined(HAVE_CYGWIN) + switch(address.type) { + case SUBNET_MAC: fprintf(out, "ip link set \"$INTERFACE\" address %s\n", address_str); break; + case SUBNET_IPV4: fprintf(out, "netsh inetface ipv4 set address \"$INTERFACE\" static %s\n", address_str); break; + case SUBNET_IPV6: fprintf(out, "netsh inetface ipv6 set address \"$INTERFACE\" static %s\n", address_str); break; + default: return; + } +#endif +} + +void ifconfig_route(FILE *out, const char *value) { + subnet_t subnet = {}, gateway = {}; + char subnet_str[MAXNETSTR] = "", gateway_str[MAXNETSTR] = ""; + char *sep = strchr(value, ' '); + if(sep) + *sep++ = 0; + if(!str2net(&subnet, value) || !net2str(subnet_str, sizeof subnet_str, &subnet) || subnet.type == SUBNET_MAC) { + fprintf(stderr, "Could not parse subnet in Route statement\n"); + return; + } + if(sep) { + if(!str2net(&gateway, sep) || !net2str(gateway_str, sizeof gateway_str, &gateway) || gateway.type != subnet.type) { + fprintf(stderr, "Could not parse gateway in Route statement\n"); + return; + } + char *slash = strchr(gateway_str, '/'); if(slash) *slash = 0; + } +#if defined(HAVE_LINUX) + if(*gateway_str) { + switch(subnet.type) { + case SUBNET_IPV4: fprintf(out, "ip route add %s via %s dev \"$INTERFACE\"\n", subnet_str, gateway_str); break; + case SUBNET_IPV6: fprintf(out, "ip route add %s via %s dev \"$INTERFACE\"\n", subnet_str, gateway_str); break; + default: return; + } + } else { + switch(subnet.type) { + case SUBNET_IPV4: fprintf(out, "ip route add %s dev \"$INTERFACE\"\n", subnet_str); break; + case SUBNET_IPV6: fprintf(out, "ip route add %s dev \"$INTERFACE\"\n", subnet_str); break; + default: return; + } + } +#elif defined(HAVE_BSD) + // BSD route command is silly and doesn't accept an interface name as a destination. + if(!*gateway_str) { + switch(subnet.type) { + case SUBNET_IPV4: + if(!ipv4.type) { + fprintf(stderr, "Route requested but no Ifconfig\n"); + return; + } + net2str(gateway_str, sizeof gateway_str, &ipv4); + break; + case SUBNET_IPV6: + if(!ipv6.type) { + fprintf(stderr, "Route requested but no Ifconfig\n"); + return; + } + net2str(gateway_str, sizeof gateway_str, &ipv6); + break; + default: return; + } + char *slash = strchr(gateway_str, '/'); if(slash) *slash = 0; + } + + switch(subnet.type) { + case SUBNET_IPV4: fprintf(out, "route add %s %s\n", subnet_str, gateway_str); break; + case SUBNET_IPV6: fprintf(out, "route add -inet6 %s %s\n", subnet_str, gateway_str); break; + default: return; + } +#elif defined(HAVE_MINGW) || defined(HAVE_CYGWIN) + if(*gateway_str) { + switch(subnet.type) { + case SUBNET_IPV4: fprintf(out, "netsh inetface ipv4 add route %s \"%%INTERFACE%%\" %s\n", subnet_str, gateway_str); break; + case SUBNET_IPV6: fprintf(out, "netsh inetface ipv6 add route %s \"%%INTERFACE%%\" %s\n", subnet_str, gateway_str); break; + default: return; + } + } else { + switch(subnet.type) { + case SUBNET_IPV4: fprintf(out, "netsh inetface ipv4 add route %s \"%%INTERFACE%%\"\n", subnet_str); break; + case SUBNET_IPV6: fprintf(out, "netsh inetface ipv6 add route %s \"%%INTERFACE%%\"\n", subnet_str); break; + default: return; + } + } +#endif +} diff --git a/src/ifconfig.h b/src/ifconfig.h new file mode 100644 index 0000000..3dbf9f6 --- /dev/null +++ b/src/ifconfig.h @@ -0,0 +1,31 @@ +/* + ifconfig.h -- header for ifconfig.c. + Copyright (C) 2016 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#ifndef __TINC_IFCONFIG_H__ +#define __TINC_IFCONFIG_H__ + +extern void ifconfig_dhcp(FILE *out); +extern void ifconfig_dhcp6(FILE *out); +extern void ifconfig_slaac(FILE *out); +extern void ifconfig_address(FILE *out, const char *value); +extern void ifconfig_route(FILE *out, const char *value); +extern void ifconfig_header(FILE *out); +extern bool ifconfig_footer(FILE *out); + +#endif diff --git a/src/invitation.c b/src/invitation.c index dff8d5f..08afe78 100644 --- a/src/invitation.c +++ b/src/invitation.c @@ -1,6 +1,6 @@ /* invitation.c -- Create and accept invitations - Copyright (C) 2013-2014 Guus Sliepen + Copyright (C) 2013-2015 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 @@ -23,16 +23,20 @@ #include "crypto.h" #include "ecdsa.h" #include "ecdsagen.h" +#include "ifconfig.h" #include "invitation.h" #include "names.h" #include "netutl.h" #include "rsagen.h" #include "script.h" #include "sptps.h" +#include "subnet.h" #include "tincctl.h" #include "utils.h" #include "xalloc.h" +#include "ed25519/sha512.h" + int addressfamily = AF_UNSPEC; static void scan_for_hostname(const char *filename, char **hostname, char **port) { @@ -82,11 +86,11 @@ char *get_my_hostname() { char *port = NULL; char *hostport = NULL; char *name = get_my_name(false); - char *filename = NULL; + char filename[PATH_MAX] = {0}; // Use first Address statement in own host config file if(check_id(name)) { - xasprintf(&filename, "%s" SLASH "hosts" SLASH "%s", confbase, name); + snprintf(filename, sizeof filename, "%s" SLASH "hosts" SLASH "%s", confbase, name); scan_for_hostname(filename, &hostname, &port); scan_for_hostname(tinc_conf, &hostname, &port); } @@ -180,7 +184,7 @@ again: hostname = xstrdup(line); save: - if(filename) { + if(*filename) { FILE *f = fopen(filename, "a"); if(f) { fprintf(f, "\nAddress = %s\n", hostname); @@ -205,7 +209,6 @@ done: free(hostname); free(port); - free(filename); return hostport; } @@ -241,14 +244,12 @@ int cmd_invite(int argc, char *argv[]) { return 1; // Ensure no host configuration file with that name exists - char *filename = NULL; - xasprintf(&filename, "%s" SLASH "hosts" SLASH "%s", confbase, argv[1]); + char filename[PATH_MAX]; + snprintf(filename, sizeof filename, "%s" SLASH "hosts" SLASH "%s", confbase, argv[1]); if(!access(filename, F_OK)) { - free(filename); fprintf(stderr, "A host config file for %s already exists!\n", argv[1]); return 1; } - free(filename); // If a daemon is running, ensure no other nodes know about this name bool found = false; @@ -270,12 +271,9 @@ int cmd_invite(int argc, char *argv[]) { } } - char hash[25]; - - xasprintf(&filename, "%s" SLASH "invitations", confbase); + snprintf(filename, sizeof filename, "%s" SLASH "invitations", confbase); if(mkdir(filename, 0700) && errno != EEXIST) { fprintf(stderr, "Could not create directory %s: %s\n", filename, strerror(errno)); - free(filename); return 1; } @@ -283,7 +281,6 @@ int cmd_invite(int argc, char *argv[]) { DIR *dir = opendir(filename); if(!dir) { fprintf(stderr, "Could not read directory %s: %s\n", filename, strerror(errno)); - free(filename); return 1; } @@ -295,9 +292,9 @@ int cmd_invite(int argc, char *argv[]) { while((ent = readdir(dir))) { if(strlen(ent->d_name) != 24) continue; - char *invname; + char invname[PATH_MAX]; struct stat st; - xasprintf(&invname, "%s" SLASH "%s", filename, ent->d_name); + snprintf(invname, sizeof invname, "%s" SLASH "%s", filename, ent->d_name); if(!stat(invname, &st)) { if(deadline < st.st_mtime) count++; @@ -307,21 +304,17 @@ int cmd_invite(int argc, char *argv[]) { fprintf(stderr, "Could not stat %s: %s\n", invname, strerror(errno)); errno = 0; } - free(invname); } + closedir(dir); + if(errno) { fprintf(stderr, "Error while reading directory %s: %s\n", filename, strerror(errno)); - closedir(dir); - free(filename); return 1; } - closedir(dir); - free(filename); - ecdsa_t *key; - xasprintf(&filename, "%s" SLASH "invitations" SLASH "ed25519_key.priv", confbase); + snprintf(filename, sizeof filename, "%s" SLASH "invitations" SLASH "ed25519_key.priv", confbase); // Remove the key if there are no outstanding invitations. if(!count) @@ -332,23 +325,23 @@ int cmd_invite(int argc, char *argv[]) { if(!f) { if(errno != ENOENT) { fprintf(stderr, "Could not read %s: %s\n", filename, strerror(errno)); - free(filename); return 1; } key = ecdsa_generate(); - if(!key) { - free(filename); + if(!key) return 1; - } f = fopen(filename, "w"); if(!f) { fprintf(stderr, "Could not write %s: %s\n", filename, strerror(errno)); - free(filename); return 1; } chmod(filename, 0600); - ecdsa_write_pem_private_key(key, f); + if(!ecdsa_write_pem_private_key(key, f)) { + fprintf(stderr, "Could not write ECDSA private key\n"); + fclose(f); + return 1; + } fclose(f); if(connect_tincd(false)) @@ -360,16 +353,13 @@ int cmd_invite(int argc, char *argv[]) { fprintf(stderr, "Could not read private key from %s\n", filename); } - free(filename); if(!key) return 1; // Create a hash of the key. + char hash[64]; char *fingerprint = ecdsa_get_base64_public_key(key); - digest_t *digest = digest_open_by_name("sha256", 18); - if(!digest) - abort(); - digest_create(digest, fingerprint, strlen(fingerprint), hash); + sha512(fingerprint, strlen(fingerprint), hash); b64encode_urlsafe(hash, hash, 18); // Create a random cookie for this invitation. @@ -378,20 +368,19 @@ int cmd_invite(int argc, char *argv[]) { // Create a filename that doesn't reveal the cookie itself char buf[18 + strlen(fingerprint)]; - char cookiehash[25]; + char cookiehash[64]; memcpy(buf, cookie, 18); memcpy(buf + 18, fingerprint, sizeof buf - 18); - digest_create(digest, buf, sizeof buf, cookiehash); + sha512(buf, sizeof buf, cookiehash); b64encode_urlsafe(cookiehash, cookiehash, 18); b64encode_urlsafe(cookie, cookie, 18); // Create a file containing the details of the invitation. - xasprintf(&filename, "%s" SLASH "invitations" SLASH "%s", confbase, cookiehash); + snprintf(filename, sizeof filename, "%s" SLASH "invitations" SLASH "%s", confbase, cookiehash); int ifd = open(filename, O_RDWR | O_CREAT | O_EXCL, 0600); if(!ifd) { fprintf(stderr, "Could not create invitation file %s: %s\n", filename, strerror(errno)); - free(filename); return 1; } f = fdopen(ifd, "w"); @@ -403,7 +392,7 @@ int cmd_invite(int argc, char *argv[]) { // Fill in the details. fprintf(f, "Name = %s\n", argv[1]); - if(netname) + if(check_netname(netname, true)) fprintf(f, "NetName = %s\n", netname); fprintf(f, "ConnectTo = %s\n", myname); @@ -426,11 +415,10 @@ int cmd_invite(int argc, char *argv[]) { fprintf(f, "#---------------------------------------------------------------#\n"); fprintf(f, "Name = %s\n", myname); - char *filename2; - xasprintf(&filename2, "%s" SLASH "hosts" SLASH "%s", confbase, myname); + char filename2[PATH_MAX]; + snprintf(filename2, sizeof filename2, "%s" SLASH "hosts" SLASH "%s", confbase, myname); fcopy(f, filename2); fclose(f); - free(filename2); // Create an URL from the local address, key hash and cookie char *url; @@ -449,7 +437,6 @@ int cmd_invite(int argc, char *argv[]) { puts(url); free(url); - free(filename); free(address); return 0; @@ -554,12 +541,17 @@ static bool finalize_join(void) { } if(!check_id(name)) { - fprintf(stderr, "Invalid Name found in invitation: %s!\n", name); + fprintf(stderr, "Invalid Name found in invitation!\n"); return false; } - if(!netname) + if(!netname) { netname = grep(data, "NetName"); + if(netname && !check_netname(netname, true)) { + fprintf(stderr, "Unsafe NetName found in invitation!\n"); + return false; + } + } bool ask_netname = false; char temp_netname[32]; @@ -570,7 +562,7 @@ make_names: confbase = NULL; } - make_names(); + make_names(false); free(tinc_conf); free(hosts_dir); @@ -608,8 +600,8 @@ make_names: fprintf(f, "Name = %s\n", name); - char *filename; - xasprintf(&filename, "%s" SLASH "%s", hosts_dir, name); + char filename[PATH_MAX]; + snprintf(filename, sizeof filename, "%s" SLASH "%s", hosts_dir, name); FILE *fh = fopen(filename, "w"); if(!fh) { fprintf(stderr, "Could not create file %s: %s\n", filename, strerror(errno)); @@ -617,7 +609,19 @@ make_names: return false; } + snprintf(filename, sizeof filename, "%s" SLASH "tinc-up.invitation", confbase); + FILE *fup = fopen(filename, "w"); + if(!fup) { + fprintf(stderr, "Could not create file %s: %s\n", filename, strerror(errno)); + fclose(f); + fclose(fh); + return false; + } + + ifconfig_header(fup); + // Filter first chunk on approved keywords, split between tinc.conf and hosts/Name + // Generate a tinc-up script from Ifconfig and Route keywords. // Other chunks go unfiltered to their respective host config files const char *p = data; char *l, *value; @@ -656,6 +660,24 @@ make_names: break; } + // Handle Ifconfig and Route statements + if(!found) { + if(!strcasecmp(l, "Ifconfig")) { + if(!strcasecmp(value, "dhcp")) + ifconfig_dhcp(fup); + else if(!strcasecmp(value, "dhcp6")) + ifconfig_dhcp6(fup); + else if(!strcasecmp(value, "slaac")) + ifconfig_slaac(fup); + else + ifconfig_address(fup, value); + continue; + } else if(!strcasecmp(l, "Route")) { + ifconfig_route(fup, value); + continue; + } + } + // Ignore unknown and unsafe variables if(!found) { fprintf(stderr, "Ignoring unknown variable '%s' in invitation.\n", l); @@ -670,7 +692,8 @@ make_names: } fclose(f); - free(filename); + bool valid_tinc_up = ifconfig_footer(fup); + fclose(fup); while(l && !strcasecmp(l, "Name")) { if(!check_id(value)) { @@ -683,7 +706,7 @@ make_names: return false; } - xasprintf(&filename, "%s" SLASH "%s", hosts_dir, value); + snprintf(filename, sizeof filename, "%s" SLASH "%s", hosts_dir, value); f = fopen(filename, "w"); if(!f) { @@ -711,7 +734,6 @@ make_names: } fclose(f); - free(filename); } // Generate our key and send a copy to the server @@ -723,8 +745,10 @@ make_names: if(!b64key) return false; - xasprintf(&filename, "%s" SLASH "ed25519_key.priv", confbase); + snprintf(filename, sizeof filename, "%s" SLASH "ed25519_key.priv", confbase); f = fopenmask(filename, "w", 0600); + if(!f) + return false; if(!ecdsa_write_pem_private_key(key, f)) { fprintf(stderr, "Error writing private key!\n"); @@ -739,20 +763,25 @@ make_names: sptps_send_record(&sptps, 1, b64key, strlen(b64key)); free(b64key); + ecdsa_free(key); - +#ifndef DISABLE_LEGACY rsa_t *rsa = rsa_generate(2048, 0x1001); - xasprintf(&filename, "%s" SLASH "rsa_key.priv", confbase); + snprintf(filename, sizeof filename, "%s" SLASH "rsa_key.priv", confbase); f = fopenmask(filename, "w", 0600); - rsa_write_pem_private_key(rsa, f); + if(!f || !rsa_write_pem_private_key(rsa, f)) { + fprintf(stderr, "Could not write private RSA key\n"); + } else if(!rsa_write_pem_public_key(rsa, fh)) { + fprintf(stderr, "Could not write public RSA key\n"); + } + fclose(f); - rsa_write_pem_public_key(rsa, fh); fclose(fh); - ecdsa_free(key); rsa_free(rsa); +#endif check_port(name); @@ -768,17 +797,69 @@ ask_netname: line[strlen(line) - 1] = 0; - char *newbase; - xasprintf(&newbase, CONFDIR SLASH "tinc" SLASH "%s", line); + char newbase[PATH_MAX]; + snprintf(newbase, sizeof newbase, CONFDIR SLASH "tinc" SLASH "%s", line); if(rename(confbase, newbase)) { fprintf(stderr, "Error trying to rename %s to %s: %s\n", confbase, newbase, strerror(errno)); - free(newbase); goto ask_netname; } - free(newbase); netname = line; - make_names(); + make_names(false); + } + + char filename2[PATH_MAX]; + snprintf(filename, sizeof filename, "%s" SLASH "tinc-up.invitation", confbase); + snprintf(filename2, sizeof filename2, "%s" SLASH "tinc-up", confbase); + + if(valid_tinc_up) { + if(tty) { + FILE *fup = fopen(filename, "r"); + if(fup) { + fprintf(stderr, "\nPlease review the following tinc-up script:\n\n"); + + char buf[MAXSIZE]; + while(fgets(buf, sizeof buf, fup)) + fputs(buf, stderr); + fclose(fup); + + int response = 0; + do { + fprintf(stderr, "\nDo you want to use this script [y]es/[n]o/[e]dit? "); + response = tolower(getchar()); + } while(!strchr("yne", response)); + + fprintf(stderr, "\n"); + + if(response == 'e') { + char *command; +#ifndef HAVE_MINGW + xasprintf(&command, "\"%s\" \"%s\"", getenv("VISUAL") ?: getenv("EDITOR") ?: "vi", filename); +#else + xasprintf(&command, "edit \"%s\"", filename); +#endif + if(system(command)) + response = 'n'; + else + response = 'y'; + free(command); + } + + if(response == 'y') { + rename(filename, filename2); + chmod(filename2, 0755); + fprintf(stderr, "tinc-up enabled.\n"); + } else { + fprintf(stderr, "tinc-up has been left disabled.\n"); + } + } + } else { + fprintf(stderr, "A tinc-up script was generated, but has been left disabled.\n"); + } + } else { + // A placeholder was generated. + rename(filename, filename2); + chmod(filename2, 0755); } fprintf(stderr, "Configuration stored in: %s\n", confbase); @@ -922,16 +1003,31 @@ int cmd_join(int argc, char *argv[]) { if(!ai) return 1; - sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); - if(sock <= 0) { - fprintf(stderr, "Could not open socket: %s\n", strerror(errno)); - return 1; + struct addrinfo *aip = NULL; + +next: + if(!aip) + aip = ai; + else { + aip = aip->ai_next; + if(!aip) + return 1; } - if(connect(sock, ai->ai_addr, ai->ai_addrlen)) { - fprintf(stderr, "Could not connect to %s port %s: %s\n", address, port, strerror(errno)); + sock = socket(aip->ai_family, aip->ai_socktype, aip->ai_protocol); + if(sock <= 0) { + fprintf(stderr, "Could not open socket: %s\n", strerror(errno)); + goto next; + } + + if(connect(sock, aip->ai_addr, aip->ai_addrlen)) { + char *addrstr, *portstr; + sockaddr2str((sockaddr_t *)aip->ai_addr, &addrstr, &portstr); + fprintf(stderr, "Could not connect to %s port %s: %s\n", addrstr, portstr, strerror(errno)); + free(addrstr); + free(portstr); closesocket(sock); - return 1; + goto next; } fprintf(stderr, "Connected to %s port %s...\n", address, port); @@ -944,7 +1040,7 @@ int cmd_join(int argc, char *argv[]) { if(!sendline(sock, "0 ?%s %d.%d", b64key, PROT_MAJOR, 1)) { fprintf(stderr, "Error sending request to %s port %s: %s\n", address, port, strerror(errno)); closesocket(sock); - return 1; + goto next; } char hisname[4096] = ""; @@ -953,16 +1049,13 @@ int cmd_join(int argc, char *argv[]) { if(!recvline(sock, line, sizeof line) || sscanf(line, "%d %s %d.%d", &code, hisname, &hismajor, &hisminor) < 3 || code != 0 || hismajor != PROT_MAJOR || !check_id(hisname) || !recvline(sock, line, sizeof line) || !rstrip(line) || sscanf(line, "%d ", &code) != 1 || code != ACK || strlen(line) < 3) { fprintf(stderr, "Cannot read greeting from peer\n"); closesocket(sock); - return 1; + goto next; } // Check if the hash of the key he gave us matches the hash in the URL. char *fingerprint = line + 2; - digest_t *digest = digest_open_by_name("sha256", 18); - if(!digest) - abort(); - char hishash[18]; - if(!digest_create(digest, fingerprint, strlen(fingerprint), hishash)) { + char hishash[64]; + if(sha512(fingerprint, strlen(fingerprint), hishash)) { fprintf(stderr, "Could not create digest\n%s\n", line + 2); return 1; } @@ -992,8 +1085,14 @@ int cmd_join(int argc, char *argv[]) { return 1; } - if(!sptps_receive_data(&sptps, line, len)) - return 1; + char *p = line; + while(len) { + int done = sptps_receive_data(&sptps, p, len); + if(!done) + return 1; + len -= done; + p += done; + } } sptps_stop(&sptps); diff --git a/src/ipv4.h b/src/ipv4.h index 6cb969b..997b88d 100644 --- a/src/ipv4.h +++ b/src/ipv4.h @@ -81,7 +81,7 @@ struct ip { uint8_t ip_p; uint16_t ip_sum; struct in_addr ip_src, ip_dst; -} __attribute__ ((__packed__)); +} __attribute__ ((__gcc_struct__, __packed__)); #endif #ifndef IP_OFFMASK @@ -143,7 +143,7 @@ struct icmp { #define icmp_radv icmp_dun.id_radv #define icmp_mask icmp_dun.id_mask #define icmp_data icmp_dun.id_data -} __attribute__ ((__packed__)); +} __attribute__ ((__gcc_struct__, __packed__)); #endif #endif /* __TINC_IPV4_H__ */ diff --git a/src/ipv6.h b/src/ipv6.h index 37d999a..cc2c5b6 100644 --- a/src/ipv6.h +++ b/src/ipv6.h @@ -1,7 +1,7 @@ /* ipv6.h -- missing IPv6 related definitions Copyright (C) 2005 Ivo Timmermans - 2006-2012 Guus Sliepen + 2006-2016 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 @@ -29,29 +29,6 @@ #define IPPROTO_ICMPV6 58 #endif -#ifndef HAVE_STRUCT_IN6_ADDR -struct in6_addr { - union { - uint8_t u6_addr8[16]; - uint16_t u6_addr16[8]; - uint32_t u6_addr32[4]; - } in6_u; -} __attribute__ ((__packed__)); -#define s6_addr in6_u.u6_addr8 -#define s6_addr16 in6_u.u6_addr16 -#define s6_addr32 in6_u.u6_addr32 -#endif - -#ifndef HAVE_STRUCT_SOCKADDR_IN6 -struct sockaddr_in6 { - uint16_t sin6_family; - uint16_t sin6_port; - uint32_t sin6_flowinfo; - struct in6_addr sin6_addr; - uint32_t sin6_scope_id; -} __attribute__ ((__packed__)); -#endif - #ifndef IN6_IS_ADDR_V4MAPPED #define IN6_IS_ADDR_V4MAPPED(a) \ ((((__const uint32_t *) (a))[0] == 0) \ @@ -72,7 +49,7 @@ struct ip6_hdr { } ip6_ctlun; struct in6_addr ip6_src; struct in6_addr ip6_dst; -} __attribute__ ((__packed__)); +} __attribute__ ((__gcc_struct__, __packed__)); #define ip6_vfc ip6_ctlun.ip6_un2_vfc #define ip6_flow ip6_ctlun.ip6_un1.ip6_un1_flow #define ip6_plen ip6_ctlun.ip6_un1.ip6_un1_plen @@ -91,7 +68,7 @@ struct icmp6_hdr { uint16_t icmp6_un_data16[2]; uint8_t icmp6_un_data8[4]; } icmp6_dataun; -} __attribute__ ((__packed__)); +} __attribute__ ((__gcc_struct__, __packed__)); #define ICMP6_DST_UNREACH_NOROUTE 0 #define ICMP6_DST_UNREACH 1 #define ICMP6_PACKET_TOO_BIG 2 @@ -111,7 +88,7 @@ struct icmp6_hdr { struct nd_neighbor_solicit { struct icmp6_hdr nd_ns_hdr; struct in6_addr nd_ns_target; -} __attribute__ ((__packed__)); +} __attribute__ ((__gcc_struct__, __packed__)); #define ND_OPT_SOURCE_LINKADDR 1 #define ND_OPT_TARGET_LINKADDR 2 #define nd_ns_type nd_ns_hdr.icmp6_type @@ -124,7 +101,7 @@ struct nd_neighbor_solicit { struct nd_opt_hdr { uint8_t nd_opt_type; uint8_t nd_opt_len; -} __attribute__ ((__packed__)); +} __attribute__ ((__gcc_struct__, __packed__)); #endif #endif /* __TINC_IPV6_H__ */ diff --git a/src/linux/device.c b/src/linux/device.c index 5717d92..a06e6da 100644 --- a/src/linux/device.c +++ b/src/linux/device.c @@ -101,6 +101,9 @@ static bool setup_device(void) { strncpy(ifrname, ifr.ifr_name, IFNAMSIZ); free(iface); iface = xstrdup(ifrname); + } else { + logger(DEBUG_ALWAYS, LOG_ERR, "Could not create a tun/tap interface from %s: %s", device, strerror(errno)); + return false; } logger(DEBUG_ALWAYS, LOG_INFO, "%s is a %s", device, device_info); diff --git a/src/list.h b/src/list.h index 0437bd9..b0e7a84 100644 --- a/src/list.h +++ b/src/list.h @@ -79,6 +79,12 @@ extern void list_delete_list(list_t *); extern void list_foreach(list_t *, list_action_t); extern void list_foreach_node(list_t *, list_action_node_t); +/* + Iterates over a list. + + CAUTION: while this construct supports deleting the current item, + it does *not* support deleting *other* nodes while iterating on the list. + */ #define list_each(type, item, list) (type *item = (type *)1; item; item = NULL) for(list_node_t *node = (list)->head, *next; item = node ? node->data : NULL, next = node ? node->next : NULL, node; node = next) #endif /* __TINC_LIST_H__ */ diff --git a/src/logger.c b/src/logger.c index 2b4c7e3..e46d926 100644 --- a/src/logger.c +++ b/src/logger.c @@ -1,6 +1,6 @@ /* logger.c -- logging code - Copyright (C) 2004-2013 Guus Sliepen + Copyright (C) 2004-2015 Guus Sliepen 2004-2005 Ivo Timmermans This program is free software; you can redistribute it and/or modify @@ -26,6 +26,7 @@ #include "logger.h" #include "connection.h" #include "control_common.h" +#include "process.h" #include "sptps.h" debug_t debug_level = DEBUG_NOTHING; @@ -37,7 +38,7 @@ static HANDLE loghandle = NULL; #endif static const char *logident = NULL; bool logcontrol = false; - +int umbilical = 0; static void real_logger(int level, int priority, const char *message) { char timestr[32] = ""; @@ -79,6 +80,11 @@ static void real_logger(int level, int priority, const char *message) { case LOGMODE_NULL: break; } + + if(umbilical && do_detach) { + write(umbilical, message, strlen(message)); + write(umbilical, "\n", 1); + } } if(logcontrol) { @@ -114,9 +120,19 @@ void logger(int level, int priority, const char *format, ...) { static void sptps_logger(sptps_t *s, int s_errno, const char *format, va_list ap) { char message[1024] = ""; - int len = vsnprintf(message, sizeof message, format, ap); - if(len > 0 && len < sizeof message && message[len - 1] == '\n') - message[len - 1] = 0; + size_t msglen = sizeof message; + + int len = vsnprintf(message, msglen, format, ap); + if(len > 0 && len < sizeof message) { + if(message[len - 1] == '\n') + message[--len] = 0; + + // WARNING: s->handle can point to a connection_t or a node_t, + // but both types have the name and hostname fields at the same offsets. + connection_t *c = s->handle; + if(c) + snprintf(message + len, sizeof message - len, " from %s (%s)", c->name, c->hostname); + } real_logger(DEBUG_ALWAYS, LOG_ERR, message); } @@ -194,6 +210,5 @@ void closelogger(void) { case LOGMODE_NULL: case LOGMODE_STDERR: break; - break; } } diff --git a/src/logger.h b/src/logger.h index 8f69029..252497b 100644 --- a/src/logger.h +++ b/src/logger.h @@ -69,6 +69,7 @@ enum { extern debug_t debug_level; extern bool logcontrol; +extern int umbilical; extern void openlogger(const char *, logmode_t); extern void reopenlogger(void); extern void logger(int, int, const char *, ...) __attribute__ ((__format__(printf, 3, 4))); diff --git a/src/meta.c b/src/meta.c index 73769d9..260cb00 100644 --- a/src/meta.c +++ b/src/meta.c @@ -30,6 +30,10 @@ #include "utils.h" #include "xalloc.h" +#ifndef MIN +#define MIN(x, y) (((x)<(y))?(x):(y)) +#endif + bool send_meta_sptps(void *handle, uint8_t type, const void *buffer, size_t length) { connection_t *c = handle; @@ -58,6 +62,9 @@ bool send_meta(connection_t *c, const char *buffer, int length) { /* Add our data to buffer */ if(c->status.encryptout) { +#ifdef DISABLE_LEGACY + return false; +#else size_t outlen = length; if(!cipher_encrypt(c->outcipher, buffer, length, buffer_prepare(&c->outbuf, length), &outlen, false) || outlen != length) { @@ -65,6 +72,7 @@ bool send_meta(connection_t *c, const char *buffer, int length) { c->name, c->hostname); return false; } +#endif } else { buffer_add(&c->outbuf, buffer, length); } @@ -74,6 +82,20 @@ bool send_meta(connection_t *c, const char *buffer, int length) { return true; } +void send_meta_raw(connection_t *c, const char *buffer, int length) { + if(!c) { + logger(DEBUG_ALWAYS, LOG_ERR, "send_meta() called with NULL pointer!"); + abort(); + } + + logger(DEBUG_META, LOG_DEBUG, "Sending %d bytes of raw metadata to %s (%s)", length, + c->name, c->hostname); + + buffer_add(&c->outbuf, buffer, length); + + io_set(&c->io, IO_READ | IO_WRITE); +} + void broadcast_meta(connection_t *from, const char *buffer, int length) { for list_each(connection_t, c, connection_list) if(c != from && c->edge) @@ -155,8 +177,33 @@ bool receive_meta(connection_t *c) { } do { - if(c->protocol_minor >= 2) - return sptps_receive_data(&c->sptps, bufp, inlen); + /* Are we receiving a SPTPS packet? */ + + if(c->sptpslen) { + int len = MIN(inlen, c->sptpslen - c->inbuf.len); + buffer_add(&c->inbuf, bufp, len); + + char *sptpspacket = buffer_read(&c->inbuf, c->sptpslen); + if(!sptpspacket) + return true; + + if(!receive_tcppacket_sptps(c, sptpspacket, c->sptpslen)) + return false; + c->sptpslen = 0; + + bufp += len; + inlen -= len; + continue; + } + + if(c->protocol_minor >= 2) { + int len = sptps_receive_data(&c->sptps, bufp, inlen); + if(!len) + return false; + bufp += len; + inlen -= len; + continue; + } if(!c->status.decryptin) { endp = memchr(bufp, '\n', inlen); @@ -170,6 +217,9 @@ bool receive_meta(connection_t *c) { inlen -= endp - bufp; bufp = endp; } else { +#ifdef DISABLE_LEGACY + return false; +#else size_t outlen = inlen; if(!cipher_decrypt(c->incipher, bufp, inlen, buffer_prepare(&c->inbuf, inlen), &outlen, false) || inlen != outlen) { @@ -179,6 +229,7 @@ bool receive_meta(connection_t *c) { } inlen = 0; +#endif } while(c->inbuf.len) { diff --git a/src/meta.h b/src/meta.h index ddc5418..8b00a5a 100644 --- a/src/meta.h +++ b/src/meta.h @@ -24,6 +24,7 @@ #include "connection.h" extern bool send_meta(struct connection_t *, const char *, int); +extern void send_meta_raw(struct connection_t *, const char *, int); extern bool send_meta_sptps(void *, uint8_t, const void *, size_t); extern bool receive_meta_sptps(void *, uint8_t, const void *, uint16_t); extern void broadcast_meta(struct connection_t *, const char *, int); diff --git a/src/mingw/device.c b/src/mingw/device.c index 19719a7..b047615 100644 --- a/src/mingw/device.c +++ b/src/mingw/device.c @@ -38,7 +38,9 @@ int device_fd = -1; static HANDLE device_handle = INVALID_HANDLE_VALUE; static io_t device_read_io; static OVERLAPPED device_read_overlapped; +static OVERLAPPED device_write_overlapped; static vpn_packet_t device_read_packet; +static vpn_packet_t device_write_packet; char *device = NULL; char *iface = NULL; static char *device_info = NULL; @@ -99,6 +101,9 @@ static bool setup_device(void) { get_config_string(lookup_config(config_tree, "Device"), &device); get_config_string(lookup_config(config_tree, "Interface"), &iface); + if(device && iface) + logger(DEBUG_ALWAYS, LOG_WARNING, "Warning: both Device and Interface specified, results may not be as expected"); + /* Open registry and look for network adapters */ if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, NETWORK_CONNECTIONS_KEY, 0, KEY_READ, &key)) { @@ -175,6 +180,25 @@ static bool setup_device(void) { return false; } + /* Get version information from tap device */ + + { + ULONG info[3] = {0}; + DWORD len; + if(!DeviceIoControl(device_handle, TAP_IOCTL_GET_VERSION, &info, sizeof info, &info, sizeof info, &len, NULL)) + logger(DEBUG_ALWAYS, LOG_WARNING, "Could not get version information from Windows tap device %s (%s): %s", device, iface, winerror(GetLastError())); + else { + logger(DEBUG_ALWAYS, LOG_INFO, "TAP-Windows driver version: %lu.%lu%s", info[0], info[1], info[2] ? " (DEBUG)" : ""); + + /* Warn if using >=9.21. This is because starting from 9.21, TAP-Win32 seems to use a different, less efficient write path. */ + if(info[0] == 9 && info[1] >= 21) + logger(DEBUG_ALWAYS, LOG_WARNING, + "You are using the newer (>= 9.0.0.21, NDIS6) series of TAP-Win32 drivers. " + "Using these drivers with tinc is not recommanded as it can result in poor performance. " + "You might want to revert back to 9.0.0.9 instead."); + } + } + /* Get MAC address from tap device */ if(!DeviceIoControl(device_handle, TAP_IOCTL_GET_MAC, mymac.x, sizeof mymac.x, mymac.x, sizeof mymac.x, &len, 0)) { @@ -200,8 +224,12 @@ static void enable_device(void) { DWORD len; DeviceIoControl(device_handle, TAP_IOCTL_SET_MEDIA_STATUS, &status, sizeof status, &status, sizeof status, &len, NULL); - io_add_event(&device_read_io, device_handle_read, NULL, CreateEvent(NULL, TRUE, FALSE, NULL)); - device_read_overlapped.hEvent = device_read_io.event; + /* We don't use the write event directly, but GetOverlappedResult() does, internally. */ + + device_read_overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + device_write_overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + + io_add_event(&device_read_io, device_handle_read, NULL, device_read_overlapped.hEvent); device_issue_read(); } @@ -210,10 +238,22 @@ static void disable_device(void) { io_del(&device_read_io); CancelIo(device_handle); + + /* According to MSDN, CancelIo() does not necessarily wait for the operation to complete. + To prevent race conditions, make sure the operation is complete + before we close the event it's referencing. */ + + DWORD len; + if(!GetOverlappedResult(device_handle, &device_read_overlapped, &len, TRUE) && GetLastError() != ERROR_OPERATION_ABORTED) + logger(DEBUG_ALWAYS, LOG_ERR, "Could not wait for %s %s read to cancel: %s", device_info, device, winerror(GetLastError())); + if(device_write_packet.len > 0 && !GetOverlappedResult(device_handle, &device_write_overlapped, &len, TRUE) && GetLastError() != ERROR_OPERATION_ABORTED) + logger(DEBUG_ALWAYS, LOG_ERR, "Could not wait for %s %s write to cancel: %s", device_info, device, winerror(GetLastError())); + device_write_packet.len = 0; + CloseHandle(device_read_overlapped.hEvent); + CloseHandle(device_write_overlapped.hEvent); ULONG status = 0; - DWORD len; DeviceIoControl(device_handle, TAP_IOCTL_SET_MEDIA_STATUS, &status, sizeof status, &status, sizeof status, &len, NULL); } @@ -231,12 +271,29 @@ static bool read_packet(vpn_packet_t *packet) { static bool write_packet(vpn_packet_t *packet) { DWORD outlen; - OVERLAPPED overlapped = {0}; logger(DEBUG_TRAFFIC, LOG_DEBUG, "Writing packet of %d bytes to %s", packet->len, device_info); - if(!WriteFile(device_handle, DATA(packet), packet->len, &outlen, &overlapped)) { + if(device_write_packet.len > 0) { + /* Make sure the previous write operation is finished before we start the next one; + otherwise we end up with multiple write ops referencing the same OVERLAPPED structure, + which according to MSDN is a no-no. */ + + if(!GetOverlappedResult(device_handle, &device_write_overlapped, &outlen, FALSE)) { + int log_level = (GetLastError() == ERROR_IO_INCOMPLETE) ? DEBUG_TRAFFIC : DEBUG_ALWAYS; + logger(log_level, LOG_ERR, "Error while checking previous write to %s %s: %s", device_info, device, winerror(GetLastError())); + return false; + } + } + + /* Copy the packet, since the write operation might still be ongoing after we return. */ + + memcpy(&device_write_packet, packet, sizeof *packet); + + if(WriteFile(device_handle, DATA(&device_write_packet), device_write_packet.len, &outlen, &device_write_overlapped)) + device_write_packet.len = 0; + else if (GetLastError() != ERROR_IO_PENDING) { logger(DEBUG_ALWAYS, LOG_ERR, "Error while writing to %s %s: %s", device_info, device, winerror(GetLastError())); return false; } diff --git a/src/multicast_device.c b/src/multicast_device.c index 931a8d0..8dab9e0 100644 --- a/src/multicast_device.c +++ b/src/multicast_device.c @@ -162,7 +162,7 @@ static void close_device(void) { static bool read_packet(vpn_packet_t *packet) { int lenin; - if((lenin = recv(device_fd, DATA(packet), MTU, 0)) <= 0) { + if((lenin = recv(device_fd, (void *)DATA(packet), MTU, 0)) <= 0) { logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info, device, sockstrerror(sockerrno)); return false; @@ -185,7 +185,7 @@ static bool write_packet(vpn_packet_t *packet) { logger(DEBUG_TRAFFIC, LOG_DEBUG, "Writing packet of %d bytes to %s", packet->len, device_info); - if(sendto(device_fd, DATA(packet), packet->len, 0, ai->ai_addr, ai->ai_addrlen) < 0) { + if(sendto(device_fd, (void *)DATA(packet), packet->len, 0, ai->ai_addr, ai->ai_addrlen) < 0) { logger(DEBUG_ALWAYS, LOG_ERR, "Can't write to %s %s: %s", device_info, device, sockstrerror(sockerrno)); return false; diff --git a/src/names.c b/src/names.c index 8218216..6c518f2 100644 --- a/src/names.c +++ b/src/names.c @@ -1,7 +1,7 @@ /* names.c -- generate commonly used (file)names Copyright (C) 1998-2005 Ivo Timmermans - 2000-2013 Guus Sliepen + 2000-2015 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 @@ -21,6 +21,7 @@ #include "system.h" #include "logger.h" +#include "names.h" #include "xalloc.h" char *netname = NULL; @@ -36,7 +37,7 @@ char *program_name = NULL; /* Set all files and paths according to netname */ -void make_names(void) { +void make_names(bool daemon) { #ifdef HAVE_MINGW HKEY key; char installdir[1024] = ""; @@ -56,14 +57,14 @@ void make_names(void) { if(!RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\tinc", 0, KEY_READ, &key)) { if(!RegQueryValueEx(key, NULL, 0, 0, (LPBYTE)installdir, &len)) { confdir = xstrdup(installdir); - if(!logfilename) - xasprintf(&logfilename, "%s" SLASH "log" SLASH "%s.log", installdir, identname); if(!confbase) { if(netname) xasprintf(&confbase, "%s" SLASH "%s", installdir, netname); else xasprintf(&confbase, "%s", installdir); } + if(!logfilename) + xasprintf(&logfilename, "%s" SLASH "tinc.log", confbase); } RegCloseKey(key); } @@ -85,21 +86,46 @@ void make_names(void) { if(!pidfilename) xasprintf(&pidfilename, "%s" SLASH "pid", confbase); #else - if(!logfilename) - xasprintf(&logfilename, LOCALSTATEDIR SLASH "log" SLASH "%s.log", identname); + bool fallback = false; + if(daemon) { + if(access(LOCALSTATEDIR, R_OK | W_OK | X_OK)) + fallback = true; + } else { + char fname[PATH_MAX]; + snprintf(fname, sizeof fname, LOCALSTATEDIR SLASH "run" SLASH "%s.pid", identname); + if(access(fname, R_OK)) { + snprintf(fname, sizeof fname, "%s" SLASH "pid", confbase); + if(!access(fname, R_OK)) + fallback = true; + } + } - if(!pidfilename) - xasprintf(&pidfilename, LOCALSTATEDIR SLASH "run" SLASH "%s.pid", identname); + if(!fallback) { + if(!logfilename) + xasprintf(&logfilename, LOCALSTATEDIR SLASH "log" SLASH "%s.log", identname); + + if(!pidfilename) + xasprintf(&pidfilename, LOCALSTATEDIR SLASH "run" SLASH "%s.pid", identname); + } else { + if(!logfilename) + xasprintf(&logfilename, "%s" SLASH "log", confbase); + + if(!pidfilename) { + if(daemon) + logger(DEBUG_ALWAYS, LOG_WARNING, "Could not access " LOCALSTATEDIR SLASH " (%s), storing pid and socket files in %s" SLASH, strerror(errno), confbase); + xasprintf(&pidfilename, "%s" SLASH "pid", confbase); + } + } #endif if(!unixsocketname) { int len = strlen(pidfilename); unixsocketname = xmalloc(len + 8); - strcpy(unixsocketname, pidfilename); + memcpy(unixsocketname, pidfilename, len); if(len > 4 && !strcmp(pidfilename + len - 4, ".pid")) - strcpy(unixsocketname + len - 4, ".socket"); + strncpy(unixsocketname + len - 4, ".socket", 8); else - strcpy(unixsocketname + len, ".socket"); + strncpy(unixsocketname + len, ".socket", 8); } } @@ -111,4 +137,12 @@ void free_names(void) { free(logfilename); free(confbase); free(confdir); + + identname = NULL; + netname = NULL; + unixsocketname = NULL; + pidfilename = NULL; + logfilename = NULL; + confbase = NULL; + confdir = NULL; } diff --git a/src/names.h b/src/names.h index 1163ff6..a2395af 100644 --- a/src/names.h +++ b/src/names.h @@ -1,7 +1,7 @@ /* names.h -- header for names.c Copyright (C) 1998-2005 Ivo Timmermans - 2000-2013 Guus Sliepen + 2000-2015 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 @@ -31,7 +31,7 @@ extern char *logfilename; extern char *pidfilename; extern char *program_name; -extern void make_names(void); +extern void make_names(bool daemon); extern void free_names(void); #endif /* __TINC_NAMES_H__ */ diff --git a/src/net.c b/src/net.c index 91b9305..8328db9 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-2013 Guus Sliepen + 2000-2015 Guus Sliepen 2006 Scott Lamb 2011 Loïc Grenié @@ -36,10 +36,6 @@ #include "subnet.h" #include "xalloc.h" -#ifdef HAVE_RESOLV_H -#include -#endif - int contradicting_add_edge = 0; int contradicting_del_edge = 0; static int sleeptime = 10; @@ -154,8 +150,9 @@ static void timeout_handler(void *data) { if(c->last_ping_time + pingtimeout <= now.tv_sec) { if(c->edge) { + try_tx(c->node, false); if(c->status.pinged) { - logger(DEBUG_CONNECTIONS, LOG_INFO, "%s (%s) didn't respond to PING in %ld seconds", c->name, c->hostname, (long)now.tv_sec - c->last_ping_time); + logger(DEBUG_CONNECTIONS, LOG_INFO, "%s (%s) didn't respond to PING in %ld seconds", c->name, c->hostname, (long)(now.tv_sec - c->last_ping_time)); } else if(c->last_ping_time + pinginterval <= now.tv_sec) { send_ping(c); continue; @@ -170,9 +167,10 @@ static void timeout_handler(void *data) { } terminate_connection(c, c->edge); } + } - timeout_set(data, &(struct timeval){pingtimeout, rand() % 100000}); + timeout_set(data, &(struct timeval){1, rand() % 100000}); } static void periodic_handler(void *data) { @@ -183,7 +181,7 @@ static void periodic_handler(void *data) { if(contradicting_del_edge > 100 && contradicting_add_edge > 100) { logger(DEBUG_ALWAYS, LOG_WARNING, "Possible node with same Name as us! Sleeping %d seconds.", sleeptime); - usleep(sleeptime * 1000000LL); + nanosleep(&(struct timespec){sleeptime, 0}, NULL); sleeptime *= 2; if(sleeptime < 0) sleeptime = 3600; @@ -212,10 +210,13 @@ static void periodic_handler(void *data) { and we are not already trying to make one, create an outgoing connection to this node. */ - int r = rand() % node_tree->count; + int r = rand() % (node_tree->count - 1); int i = 0; for splay_each(node_t, n, node_tree) { + if(n == myself) + continue; + if(i++ != r) continue; @@ -311,15 +312,12 @@ static void sighup_handler(void *data) { static void sigalrm_handler(void *data) { logger(DEBUG_ALWAYS, LOG_NOTICE, "Got %s signal", strsignal(((signal_t *)data)->signum)); -#ifdef HAVE_DECL_RES_INIT - res_init(); -#endif retry(); } #endif int reload_configuration(void) { - char *fname = NULL; + char fname[PATH_MAX]; /* Reread our own configuration file */ @@ -333,9 +331,8 @@ int reload_configuration(void) { read_config_options(config_tree, NULL); - xasprintf(&fname, "%s" SLASH "hosts" SLASH "%s", confbase, myself->name); + snprintf(fname, sizeof fname, "%s" SLASH "hosts" SLASH "%s", confbase, myself->name); read_config_file(config_tree, fname); - free(fname); /* Parse some options that are allowed to be changed while tinc is running */ @@ -412,13 +409,12 @@ int reload_configuration(void) { if(c->status.control) continue; - xasprintf(&fname, "%s" SLASH "hosts" SLASH "%s", confbase, c->name); + snprintf(fname, sizeof fname, "%s" SLASH "hosts" SLASH "%s", confbase, c->name); struct stat s; if(stat(fname, &s) || s.st_mtime > last_config_check) { logger(DEBUG_CONNECTIONS, LOG_INFO, "Host config file of %s has been changed", c->name); terminate_connection(c, c->edge); } - free(fname); } last_config_check = now.tv_sec; @@ -449,7 +445,7 @@ void retry(void) { */ int main_loop(void) { timeout_add(&pingtimer, timeout_handler, &pingtimer, &(struct timeval){pingtimeout, rand() % 100000}); - timeout_add(&periodictimer, periodic_handler, &periodictimer, &(struct timeval){pingtimeout, rand() % 100000}); + timeout_add(&periodictimer, periodic_handler, &periodictimer, &(struct timeval){0, 0}); #ifndef HAVE_MINGW signal_t sighup = {0}; diff --git a/src/net.h b/src/net.h index dcc99a4..c3c82de 100644 --- a/src/net.h +++ b/src/net.h @@ -1,7 +1,7 @@ /* net.h -- header for net.c Copyright (C) 1998-2005 Ivo Timmermans - 2000-2014 Guus Sliepen + 2000-2016 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 @@ -115,6 +115,7 @@ typedef struct listen_socket_t { io_t udp; sockaddr_t sa; bool bindto; + int priority; } listen_socket_t; #include "conf.h" @@ -138,6 +139,14 @@ extern int addressfamily; extern unsigned replaywin; extern bool localdiscovery; +extern bool udp_discovery; +extern int udp_discovery_keepalive_interval; +extern int udp_discovery_interval; +extern int udp_discovery_timeout; + +extern int mtu_info_interval; +extern int udp_info_interval; + extern listen_socket_t listen_socket[MAXSOCKETS]; extern int listen_sockets; extern io_t unix_socket; @@ -183,10 +192,11 @@ extern void handle_new_meta_connection(void *, int); extern void handle_new_unix_connection(void *, int); extern int setup_listen_socket(const sockaddr_t *); extern int setup_vpn_in_socket(const sockaddr_t *); -extern bool send_sptps_data(void *handle, uint8_t type, const void *data, size_t len); +extern bool send_sptps_data(node_t *to, node_t *from, int type, const void *data, size_t len); extern bool receive_sptps_record(void *handle, uint8_t type, const void *data, uint16_t len); extern void send_packet(struct node_t *, vpn_packet_t *); extern void receive_tcppacket(struct connection_t *, const char *, int); +extern bool receive_tcppacket_sptps(struct connection_t *, const char *, int); extern void broadcast_packet(const struct node_t *, vpn_packet_t *); extern char *get_name(void); extern void device_enable(void); @@ -201,7 +211,6 @@ extern void terminate_connection(struct connection_t *, bool); extern bool node_read_ecdsa_public_key(struct node_t *); extern bool read_ecdsa_public_key(struct connection_t *); extern bool read_rsa_public_key(struct connection_t *); -extern void send_mtu_probe(struct node_t *); extern void handle_device_data(void *, int); extern void handle_meta_connection_data(struct connection_t *); extern void regenerate_key(void); @@ -210,6 +219,7 @@ extern void retry(void); extern int reload_configuration(void); extern void load_all_subnets(void); extern void load_all_nodes(void); +extern void try_tx(struct node_t *n, bool); #ifndef HAVE_MINGW #define closesocket(s) close(s) diff --git a/src/net_packet.c b/src/net_packet.c index c146109..21e6c2a 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-2014 Guus Sliepen + 2000-2016 Guus Sliepen 2010 Timothy Redaelli 2010 Brandon Black @@ -37,6 +37,8 @@ #include "digest.h" #include "device.h" #include "ethernet.h" +#include "ipv4.h" +#include "ipv6.h" #include "graph.h" #include "logger.h" #include "net.h" @@ -46,6 +48,15 @@ #include "utils.h" #include "xalloc.h" +#ifndef MAX +#define MAX(a, b) ((a) > (b) ? (a) : (b)) +#endif + +/* The minimum size of a probe is 14 bytes, but since we normally use CBC mode + encryption, we can add a few extra random bytes without increasing the + resulting packet size. */ +#define MIN_PROBE_SIZE 18 + int keylifetime = 0; #ifdef HAVE_LZO static char lzo_wrkmem[LZO1X_999_MEM_COMPRESS > LZO1X_1_MEM_COMPRESS ? LZO1X_999_MEM_COMPRESS : LZO1X_1_MEM_COMPRESS]; @@ -53,226 +64,118 @@ static char lzo_wrkmem[LZO1X_999_MEM_COMPRESS > LZO1X_1_MEM_COMPRESS ? LZO1X_999 static void send_udppacket(node_t *, vpn_packet_t *); -unsigned replaywin = 16; +unsigned replaywin = 32; bool localdiscovery = true; +bool udp_discovery = true; +int udp_discovery_keepalive_interval = 10; +int udp_discovery_interval = 2; +int udp_discovery_timeout = 30; #define MAX_SEQNO 1073741824 -/* mtuprobes == 1..30: initial discovery, send bursts with 1 second interval - mtuprobes == 31: sleep pinginterval seconds - mtuprobes == 32: send 1 burst, sleep pingtimeout second - mtuprobes == 33: no response from other side, restart PMTU discovery process - - Probes are sent in batches of at least three, with random sizes between the - lower and upper boundaries for the MTU thus far discovered. - - After the initial discovery, a fourth packet is added to each batch with a - size larger than the currently known PMTU, to test if the PMTU has increased. - - In case local discovery is enabled, another packet is added to each batch, - which will be broadcast to the local network. - -*/ - -static void send_mtu_probe_handler(void *data) { - node_t *n = data; - int timeout = 1; - - n->mtuprobes++; - - if(!n->status.reachable || !n->status.validkey) { - logger(DEBUG_TRAFFIC, LOG_INFO, "Trying to send MTU probe to unreachable or rekeying node %s (%s)", n->name, n->hostname); - n->mtuprobes = 0; +static void try_fix_mtu(node_t *n) { + if(n->mtuprobes < 0) return; - } - if(n->mtuprobes > 32) { - if(!n->minmtu) { - n->mtuprobes = 31; - timeout = pinginterval; - goto end; - } - - logger(DEBUG_TRAFFIC, LOG_INFO, "%s (%s) did not respond to UDP ping, restarting PMTU discovery", n->name, n->hostname); - n->status.udp_confirmed = false; - n->mtuprobes = 1; - n->minmtu = 0; - n->maxmtu = MTU; - } - - if(n->mtuprobes >= 10 && n->mtuprobes < 32 && !n->minmtu) { - logger(DEBUG_TRAFFIC, LOG_INFO, "No response to MTU probes from %s (%s)", n->name, n->hostname); - n->mtuprobes = 31; - } - - if(n->mtuprobes == 30 || (n->mtuprobes < 30 && n->minmtu >= n->maxmtu)) { + if(n->mtuprobes == 20 || n->minmtu >= n->maxmtu) { if(n->minmtu > n->maxmtu) n->minmtu = n->maxmtu; else n->maxmtu = n->minmtu; n->mtu = n->minmtu; logger(DEBUG_TRAFFIC, LOG_INFO, "Fixing MTU of %s (%s) to %d after %d probes", n->name, n->hostname, n->mtu, n->mtuprobes); - n->mtuprobes = 31; + n->mtuprobes = -1; } - - if(n->mtuprobes == 31) { - timeout = pinginterval; - goto end; - } else if(n->mtuprobes == 32) { - timeout = pingtimeout; - } - - for(int i = 0; i < 4 + localdiscovery; i++) { - int len; - - if(i == 0) { - if(n->mtuprobes < 30 || n->maxmtu + 8 >= MTU) - continue; - len = n->maxmtu + 8; - } else if(n->maxmtu <= n->minmtu) { - len = n->maxmtu; - } else { - len = n->minmtu + 1 + rand() % (n->maxmtu - n->minmtu); - } - - if(len < 64) - len = 64; - - vpn_packet_t packet; - packet.offset = DEFAULT_PACKET_OFFSET; - memset(DATA(&packet), 0, 14); - randomize(DATA(&packet) + 14, len - 14); - packet.len = len; - packet.priority = 0; - n->status.send_locally = i >= 4 && n->mtuprobes <= 10 && n->prevedge; - - logger(DEBUG_TRAFFIC, LOG_INFO, "Sending MTU probe length %d to %s (%s)", len, n->name, n->hostname); - - send_udppacket(n, &packet); - } - - n->status.send_locally = false; - n->probe_counter = 0; - gettimeofday(&n->probe_time, NULL); - - /* Calculate the packet loss of incoming traffic by comparing the rate of - packets received to the rate with which the sequence number has increased. - */ - - if(n->received > n->prev_received) - n->packetloss = 1.0 - (n->received - n->prev_received) / (float)(n->received_seqno - n->prev_received_seqno); - else - n->packetloss = n->received_seqno <= n->prev_received_seqno; - - n->prev_received_seqno = n->received_seqno; - n->prev_received = n->received; - -end: - timeout_set(&n->mtutimeout, &(struct timeval){timeout, rand() % 100000}); } -void send_mtu_probe(node_t *n) { - timeout_add(&n->mtutimeout, send_mtu_probe_handler, n, &(struct timeval){1, 0}); - send_mtu_probe_handler(n); +static void udp_probe_timeout_handler(void *data) { + node_t *n = data; + if(!n->status.udp_confirmed) + return; + + logger(DEBUG_TRAFFIC, LOG_INFO, "Too much time has elapsed since last UDP ping response from %s (%s), stopping UDP communication", n->name, n->hostname); + n->status.udp_confirmed = false; + n->maxrecentlen = 0; + n->mtuprobes = 0; + n->minmtu = 0; + n->maxmtu = MTU; } -static void mtu_probe_h(node_t *n, vpn_packet_t *packet, length_t len) { - if(!DATA(packet)[0]) { - logger(DEBUG_TRAFFIC, LOG_INFO, "Got MTU probe request %d from %s (%s)", packet->len, n->name, n->hostname); +static void send_udp_probe_reply(node_t *n, vpn_packet_t *packet, length_t len) { + if(!n->status.sptps && !n->status.validkey) { + logger(DEBUG_TRAFFIC, LOG_INFO, "Trying to send UDP probe reply to %s (%s) but we don't have his key yet", n->name, n->hostname); + return; + } - /* It's a probe request, send back a reply */ + /* Type 2 probe replies were introduced in protocol 17.3 */ + if ((n->options >> 24) >= 3) { + DATA(packet)[0] = 2; + uint16_t len16 = htons(len); + memcpy(DATA(packet) + 1, &len16, 2); + packet->len = MIN_PROBE_SIZE; + logger(DEBUG_TRAFFIC, LOG_INFO, "Sending type 2 probe reply length %u to %s (%s)", len, n->name, n->hostname); - /* Type 2 probe replies were introduced in protocol 17.3 */ - if ((n->options >> 24) >= 3) { - uint8_t *data = DATA(packet); - *data++ = 2; - uint16_t len16 = htons(len); memcpy(data, &len16, 2); data += 2; - struct timeval now; - gettimeofday(&now, NULL); - uint32_t sec = htonl(now.tv_sec); memcpy(data, &sec, 4); data += 4; - uint32_t usec = htonl(now.tv_usec); memcpy(data, &usec, 4); data += 4; - packet->len -= 10; - } else { - /* Legacy protocol: n won't understand type 2 probe replies. */ - DATA(packet)[0] = 1; - } - - /* Temporarily set udp_confirmed, so that the reply is sent - back exactly the way it came in. */ - - bool udp_confirmed = n->status.udp_confirmed; - n->status.udp_confirmed = true; - send_udppacket(n, packet); - n->status.udp_confirmed = udp_confirmed; } else { - length_t probelen = len; - if (DATA(packet)[0] == 2) { - if (len < 3) - logger(DEBUG_TRAFFIC, LOG_WARNING, "Received invalid (too short) MTU probe reply from %s (%s)", n->name, n->hostname); - else { - uint16_t probelen16; memcpy(&probelen16, DATA(packet) + 1, 2); probelen = ntohs(probelen16); - } - } - logger(DEBUG_TRAFFIC, LOG_INFO, "Got type %d MTU probe reply %d from %s (%s)", DATA(packet)[0], probelen, n->name, n->hostname); + /* Legacy protocol: n won't understand type 2 probe replies. */ + DATA(packet)[0] = 1; + logger(DEBUG_TRAFFIC, LOG_INFO, "Sending type 1 probe reply length %u to %s (%s)", len, n->name, n->hostname); + } - /* It's a valid reply: now we know bidirectional communication - is possible using the address and socket that the reply - packet used. */ + /* Temporarily set udp_confirmed, so that the reply is sent + back exactly the way it came in. */ - n->status.udp_confirmed = true; + bool udp_confirmed = n->status.udp_confirmed; + n->status.udp_confirmed = true; + send_udppacket(n, packet); + n->status.udp_confirmed = udp_confirmed; +} - /* If we haven't established the PMTU yet, restart the discovery process. */ +static void udp_probe_h(node_t *n, vpn_packet_t *packet, length_t len) { + if(!DATA(packet)[0]) { + logger(DEBUG_TRAFFIC, LOG_INFO, "Got UDP probe request %d from %s (%s)", packet->len, n->name, n->hostname); + return send_udp_probe_reply(n, packet, len); + } - if(n->mtuprobes > 30) { - if (probelen == n->maxmtu + 8) { - logger(DEBUG_TRAFFIC, LOG_INFO, "Increase in PMTU to %s (%s) detected, restarting PMTU discovery", n->name, n->hostname); - n->maxmtu = MTU; - n->mtuprobes = 10; - return; - } + if (DATA(packet)[0] == 2) { + // It's a type 2 probe reply, use the length field inside the packet + uint16_t len16; + memcpy(&len16, DATA(packet) + 1, 2); + len = ntohs(len16); + } - if(n->minmtu) - n->mtuprobes = 30; - else - n->mtuprobes = 1; - } + logger(DEBUG_TRAFFIC, LOG_INFO, "Got type %d UDP probe reply %d from %s (%s)", DATA(packet)[0], len, n->name, n->hostname); - /* If applicable, raise the minimum supported MTU */ + /* It's a valid reply: now we know bidirectional communication + is possible using the address and socket that the reply + packet used. */ + n->status.udp_confirmed = true; - if(probelen > n->maxmtu) - probelen = n->maxmtu; - if(n->minmtu < probelen) - n->minmtu = probelen; + // Reset the UDP ping timer. + n->udp_ping_sent = now; - /* Calculate RTT and bandwidth. - The RTT is the time between the MTU probe burst was sent and the first - reply is received. The bandwidth is measured using the time between the - arrival of the first and third probe reply (or type 2 probe requests). - */ + if(udp_discovery) { + timeout_del(&n->udp_ping_timeout); + timeout_add(&n->udp_ping_timeout, &udp_probe_timeout_handler, n, &(struct timeval){udp_discovery_timeout, 0}); + } - struct timeval now, diff; - gettimeofday(&now, NULL); - timersub(&now, &n->probe_time, &diff); + if(len > n->maxmtu) { + logger(DEBUG_TRAFFIC, LOG_INFO, "Increase in PMTU to %s (%s) detected, restarting PMTU discovery", n->name, n->hostname); + n->minmtu = len; + n->maxmtu = MTU; + /* Set mtuprobes to 1 so that try_mtu() doesn't reset maxmtu */ + n->mtuprobes = 1; + return; + } else if(n->mtuprobes < 0 && len == n->maxmtu) { + /* We got a maxmtu sized packet, confirming the PMTU is still valid. */ + n->mtuprobes = -1; + n->mtu_ping_sent = now; + } - struct timeval probe_timestamp = now; - if (DATA(packet)[0] == 2 && packet->len >= 11) { - uint32_t sec; memcpy(&sec, DATA(packet) + 3, 4); - uint32_t usec; memcpy(&usec, DATA(packet) + 7, 4); - probe_timestamp.tv_sec = ntohl(sec); - probe_timestamp.tv_usec = ntohl(usec); - } - - n->probe_counter++; + /* If applicable, raise the minimum supported MTU */ - if(n->probe_counter == 1) { - n->rtt = diff.tv_sec + diff.tv_usec * 1e-6; - n->probe_time = probe_timestamp; - } else if(n->probe_counter == 3) { - struct timeval probe_timestamp_diff; - timersub(&probe_timestamp, &n->probe_time, &probe_timestamp_diff); - n->bandwidth = 2.0 * probelen / (probe_timestamp_diff.tv_sec + probe_timestamp_diff.tv_usec * 1e-6); - logger(DEBUG_TRAFFIC, LOG_DEBUG, "%s (%s) RTT %.2f ms, burst bandwidth %.3f Mbit/s, rx packet loss %.2f %%", n->name, n->hostname, n->rtt * 1e3, n->bandwidth * 8e-6, n->packetloss * 1e2); - } + if(n->minmtu < len) { + n->minmtu = len; + try_fix_mtu(n); } } @@ -351,10 +254,14 @@ static bool try_mac(node_t *n, const vpn_packet_t *inpkt) { if(n->status.sptps) return sptps_verify_datagram(&n->sptps, DATA(inpkt), inpkt->len); - if(!digest_active(n->indigest) || inpkt->len < sizeof(seqno_t) + digest_length(n->indigest)) +#ifdef DISABLE_LEGACY + return false; +#else + if(!n->status.validkey_in || !digest_active(n->indigest) || inpkt->len < sizeof(seqno_t) + digest_length(n->indigest)) return false; - return digest_verify(n->indigest, SEQNO(inpkt), inpkt->len - digest_length(n->indigest), DATA(inpkt) + inpkt->len - digest_length(n->indigest)); + return digest_verify(n->indigest, inpkt->data, inpkt->len - digest_length(n->indigest), inpkt->data + inpkt->len - digest_length(n->indigest)); +#endif } static bool receive_udppacket(node_t *n, vpn_packet_t *inpkt) { @@ -375,15 +282,28 @@ static bool receive_udppacket(node_t *n, vpn_packet_t *inpkt) { } return false; } - inpkt->offset += 2 * sizeof(node_id_t); - if(!sptps_receive_data(&n->sptps, DATA(inpkt), inpkt->len - 2 * sizeof(node_id_t))) { - logger(DEBUG_TRAFFIC, LOG_ERR, "Got bad packet from %s (%s)", n->name, n->hostname); + n->status.udppacket = true; + bool result = sptps_receive_data(&n->sptps, DATA(inpkt), inpkt->len); + n->status.udppacket = false; + + if(!result) { + /* Uh-oh. It might be that the tunnel is stuck in some corrupted state, + so let's restart SPTPS in case that helps. But don't do that too often + to prevent storms, and because that would make life a little too easy + for external attackers trying to DoS us. */ + if(n->last_req_key < now.tv_sec - 10) { + logger(DEBUG_PROTOCOL, LOG_ERR, "Failed to decode raw TCP packet from %s (%s), restarting SPTPS", n->name, n->hostname); + send_req_key(n); + } return false; } return true; } - if(!n->status.validkey) { +#ifdef DISABLE_LEGACY + return false; +#else + if(!n->status.validkey_in) { logger(DEBUG_TRAFFIC, LOG_DEBUG, "Got packet from %s (%s) but he hasn't got our key yet", n->name, n->hostname); return false; } @@ -484,13 +404,17 @@ static bool receive_udppacket(node_t *n, vpn_packet_t *inpkt) { origlen -= MTU/64 + 20; } + if(inpkt->len > n->maxrecentlen) + n->maxrecentlen = inpkt->len; + inpkt->priority = 0; if(!DATA(inpkt)[12] && !DATA(inpkt)[13]) - mtu_probe_h(n, inpkt, origlen); + udp_probe_h(n, inpkt, origlen); else receive_packet(n, inpkt); return true; +#endif } void receive_tcppacket(connection_t *c, const char *buffer, int len) { @@ -510,34 +434,66 @@ void receive_tcppacket(connection_t *c, const char *buffer, int len) { receive_packet(c->node, &outpkt); } -static bool try_sptps(node_t *n) { - if(n->status.validkey) - return true; - - /* If n is a TCP-only neighbor, we'll only use "cleartext" PACKET - messages anyway, so there's no need for SPTPS at all. */ - if(n->connection && ((myself->options | n->options) & OPTION_TCPONLY)) +bool receive_tcppacket_sptps(connection_t *c, const char *data, int len) { + if (len < sizeof(node_id_t) + sizeof(node_id_t)) { + logger(DEBUG_ALWAYS, LOG_ERR, "Got too short TCP SPTPS packet from %s (%s)", c->name, c->hostname); return false; - - logger(DEBUG_TRAFFIC, LOG_INFO, "No valid key known yet for %s (%s)", n->name, n->hostname); - - if(!n->status.waitingforkey) - send_req_key(n); - else if(n->last_req_key + 10 < now.tv_sec) { - logger(DEBUG_ALWAYS, LOG_DEBUG, "No key from %s after 10 seconds, restarting SPTPS", n->name); - sptps_stop(&n->sptps); - n->status.waitingforkey = false; - send_req_key(n); } - return false; + node_t *to = lookup_node_id((node_id_t *)data); + data += sizeof(node_id_t); len -= sizeof(node_id_t); + if(!to) { + logger(DEBUG_PROTOCOL, LOG_ERR, "Got TCP SPTPS packet from %s (%s) with unknown destination ID", c->name, c->hostname); + return true; + } + + node_t *from = lookup_node_id((node_id_t *)data); + data += sizeof(node_id_t); len -= sizeof(node_id_t); + if(!from) { + logger(DEBUG_PROTOCOL, LOG_ERR, "Got TCP SPTPS packet from %s (%s) with unknown source ID", c->name, c->hostname); + return true; + } + + if(!to->status.reachable) { + /* This can happen in the form of a race condition + if the node just became unreachable. */ + logger(DEBUG_TRAFFIC, LOG_WARNING, "Cannot relay TCP packet from %s (%s) because the destination, %s (%s), is unreachable", from->name, from->hostname, to->name, to->hostname); + return true; + } + + /* Help the sender reach us over UDP. + Note that we only do this if we're the destination or the static relay; + otherwise every hop would initiate its own UDP info message, resulting in elevated chatter. */ + if(to->via == myself) + send_udp_info(myself, from); + + /* If we're not the final recipient, relay the packet. */ + + if(to != myself) { + send_sptps_data(to, from, 0, data, len); + try_tx(to, true); + return true; + } + + /* The packet is for us */ + + if(!sptps_receive_data(&from->sptps, data, len)) { + /* Uh-oh. It might be that the tunnel is stuck in some corrupted state, + so let's restart SPTPS in case that helps. But don't do that too often + to prevent storms. */ + if(from->last_req_key < now.tv_sec - 10) { + logger(DEBUG_PROTOCOL, LOG_ERR, "Failed to decode raw TCP packet from %s (%s), restarting SPTPS", from->name, from->hostname); + send_req_key(from); + } + return true; + } + + send_mtu_info(myself, from, MTU); + return true; } static void send_sptps_packet(node_t *n, vpn_packet_t *origpkt) { - /* Note: condition order is as intended - even if we have a direct - metaconnection, we want to try SPTPS anyway as it's the only way to - get UDP going */ - if(!try_sptps(n) && !n->connection) + if(!n->status.validkey && !n->connection) return; uint8_t type = 0; @@ -665,10 +621,7 @@ static void send_udppacket(node_t *n, vpn_packet_t *origpkt) { vpn_packet_t *outpkt; int origlen = origpkt->len; size_t outlen; -#if defined(SOL_IP) && defined(IP_TOS) - static int priority = 0; int origpriority = origpkt->priority; -#endif pkt1.offset = DEFAULT_PACKET_OFFSET; pkt2.offset = DEFAULT_PACKET_OFFSET; @@ -681,20 +634,16 @@ static void send_udppacket(node_t *n, vpn_packet_t *origpkt) { if(n->status.sptps) return send_sptps_packet(n, origpkt); +#ifdef DISABLE_LEGACY + return; +#else /* Make sure we have a valid key */ if(!n->status.validkey) { logger(DEBUG_TRAFFIC, LOG_INFO, "No valid key known yet for %s (%s), forwarding via TCP", n->name, n->hostname); - - if(n->last_req_key + 10 <= now.tv_sec) { - send_req_key(n); - n->last_req_key = now.tv_sec; - } - send_tcppacket(n->nexthop->connection, origpkt); - return; } @@ -767,54 +716,72 @@ static void send_udppacket(node_t *n, vpn_packet_t *origpkt) { if(!sa) choose_udp_address(n, &sa, &sock); -#if defined(SOL_IP) && defined(IP_TOS) - if(priorityinheritance && origpriority != priority - && listen_socket[n->sock].sa.sa.sa_family == AF_INET) { - priority = origpriority; - logger(DEBUG_TRAFFIC, LOG_DEBUG, "Setting outgoing packet priority to %d", priority); - if(setsockopt(listen_socket[n->sock].udp.fd, SOL_IP, IP_TOS, &priority, sizeof(priority))) /* SO_PRIORITY doesn't seem to work */ - logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "setsockopt", sockstrerror(sockerrno)); - } + if(priorityinheritance && origpriority != listen_socket[sock].priority) { + listen_socket[sock].priority = origpriority; + switch(sa->sa.sa_family) { +#if defined(IPPROTO_IP) && defined(IP_TOS) + case AF_INET: + logger(DEBUG_TRAFFIC, LOG_DEBUG, "Setting IPv4 outgoing packet priority to %d", origpriority); + if(setsockopt(listen_socket[sock].udp.fd, IPPROTO_IP, IP_TOS, (void *)&origpriority, sizeof origpriority)) /* SO_PRIORITY doesn't seem to work */ + logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "setsockopt", sockstrerror(sockerrno)); + break; #endif +#if defined(IPPROTO_IPV6) & defined(IPV6_TCLASS) + case AF_INET6: + logger(DEBUG_TRAFFIC, LOG_DEBUG, "Setting IPv6 outgoing packet priority to %d", origpriority); + if(setsockopt(listen_socket[sock].udp.fd, IPPROTO_IPV6, IPV6_TCLASS, (void *)&origpriority, sizeof origpriority)) /* SO_PRIORITY doesn't seem to work */ + logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "setsockopt", sockstrerror(sockerrno)); + break; +#endif + default: + break; + } + } - if(sendto(listen_socket[sock].udp.fd, SEQNO(inpkt), inpkt->len, 0, &sa->sa, SALEN(sa->sa)) < 0 && !sockwouldblock(sockerrno)) { + if(sendto(listen_socket[sock].udp.fd, (void *)SEQNO(inpkt), inpkt->len, 0, &sa->sa, SALEN(sa->sa)) < 0 && !sockwouldblock(sockerrno)) { if(sockmsgsize(sockerrno)) { if(n->maxmtu >= origlen) n->maxmtu = origlen - 1; if(n->mtu >= origlen) n->mtu = origlen - 1; + try_fix_mtu(n); } else logger(DEBUG_TRAFFIC, LOG_WARNING, "Error sending packet to %s (%s): %s", n->name, n->hostname, sockstrerror(sockerrno)); } end: origpkt->len = origlen; +#endif } -static bool send_sptps_data_priv(node_t *to, node_t *from, int type, const void *data, size_t len) { +bool send_sptps_data(node_t *to, node_t *from, int type, const void *data, size_t len) { node_t *relay = (to->via != myself && (type == PKT_PROBE || (len - SPTPS_DATAGRAM_OVERHEAD) <= to->via->minmtu)) ? to->via : to->nexthop; bool direct = from == myself && to == relay; bool relay_supported = (relay->options >> 24) >= 4; bool tcponly = (myself->options | relay->options) & OPTION_TCPONLY; - /* We don't really need the relay's key, but we need to establish a UDP tunnel with it and discover its MTU. */ - if (!direct && relay_supported && !tcponly) - try_sptps(relay); - - /* Send it via TCP if it is a handshake packet, TCPOnly is in use, this is a relay packet that the other node cannot understand, or this packet is larger than the MTU. - TODO: When relaying, the original sender does not know the end-to-end PMTU (it only knows the PMTU of the first hop). - This can lead to scenarios where large packets are sent over UDP to relay, but then relay has no choice but fall back to TCP. */ + /* Send it via TCP if it is a handshake packet, TCPOnly is in use, this is a relay packet that the other node cannot understand, or this packet is larger than the MTU. */ if(type == SPTPS_HANDSHAKE || tcponly || (!direct && !relay_supported) || (type != PKT_PROBE && (len - SPTPS_DATAGRAM_OVERHEAD) > relay->minmtu)) { + if(type != SPTPS_HANDSHAKE && (to->nexthop->connection->options >> 24) >= 7) { + char buf[len + sizeof to->id + sizeof from->id]; char* buf_ptr = buf; + memcpy(buf_ptr, &to->id, sizeof to->id); buf_ptr += sizeof to->id; + memcpy(buf_ptr, &from->id, sizeof from->id); buf_ptr += sizeof from->id; + memcpy(buf_ptr, data, len); buf_ptr += len; + logger(DEBUG_TRAFFIC, LOG_INFO, "Sending packet from %s (%s) to %s (%s) via %s (%s) (TCP)", from->name, from->hostname, to->name, to->hostname, to->nexthop->name, to->nexthop->hostname); + return send_sptps_tcppacket(to->nexthop->connection, buf, sizeof buf); + } + char buf[len * 4 / 3 + 5]; b64encode(data, buf, len); - /* If no valid key is known yet, send the packets using ANS_KEY requests, - to ensure we get to learn the reflexive UDP address. */ - if(from == myself && !to->status.validkey) { + /* If this is a handshake packet, use ANS_KEY instead of REQ_KEY, for two reasons: + - We don't want intermediate nodes to switch to UDP to relay these packets; + - ANS_KEY allows us to learn the reflexive UDP address. */ + if(type == SPTPS_HANDSHAKE) { to->incompression = myself->incompression; return send_request(to->nexthop->connection, "%d %s %s %s -1 -1 -1 %d", ANS_KEY, from->name, to->name, buf, to->incompression); } else { - return send_request(to->nexthop->connection, "%d %s %s %d %s", REQ_KEY, from->name, to->name, REQ_SPTPS, buf); + return send_request(to->nexthop->connection, "%d %s %s %d %s", REQ_KEY, from->name, to->name, SPTPS_PACKET, buf); } } @@ -841,7 +808,7 @@ static bool send_sptps_data_priv(node_t *to, node_t *from, int type, const void choose_local_address(relay, &sa, &sock); if(!sa) choose_udp_address(relay, &sa, &sock); - logger(DEBUG_TRAFFIC, LOG_INFO, "Sending packet from %s (%s) to %s (%s) via %s (%s)", from->name, from->hostname, to->name, to->hostname, relay->name, relay->hostname); + logger(DEBUG_TRAFFIC, LOG_INFO, "Sending packet from %s (%s) to %s (%s) via %s (%s) (UDP)", from->name, from->hostname, to->name, to->hostname, relay->name, relay->hostname); if(sendto(listen_socket[sock].udp.fd, buf, buf_ptr - buf, 0, &sa->sa, SALEN(sa->sa)) < 0 && !sockwouldblock(sockerrno)) { if(sockmsgsize(sockerrno)) { // Compensate for SPTPS overhead @@ -850,6 +817,7 @@ static bool send_sptps_data_priv(node_t *to, node_t *from, int type, const void relay->maxmtu = len - 1; if(relay->mtu >= len) relay->mtu = len - 1; + try_fix_mtu(relay); } else { logger(DEBUG_TRAFFIC, LOG_WARNING, "Error sending UDP SPTPS packet to %s (%s): %s", relay->name, relay->hostname, sockstrerror(sockerrno)); return false; @@ -859,10 +827,6 @@ static bool send_sptps_data_priv(node_t *to, node_t *from, int type, const void return true; } -bool send_sptps_data(void *handle, uint8_t type, const void *data, size_t len) { - return send_sptps_data_priv(handle, myself, type, data, len); -} - bool receive_sptps_record(void *handle, uint8_t type, const void *data, uint16_t len) { node_t *from = handle; @@ -884,9 +848,15 @@ bool receive_sptps_record(void *handle, uint8_t type, const void *data, uint16_t inpkt.offset = DEFAULT_PACKET_OFFSET; if(type == PKT_PROBE) { + if(!from->status.udppacket) { + logger(DEBUG_ALWAYS, LOG_ERR, "Got SPTPS PROBE packet from %s (%s) via TCP", from->name, from->hostname); + return false; + } inpkt.len = len; memcpy(DATA(&inpkt), data, len); - mtu_probe_h(from, &inpkt, len); + if(inpkt.len > from->maxrecentlen) + from->maxrecentlen = inpkt.len; + udp_probe_h(from, &inpkt, len); return true; } @@ -937,56 +907,412 @@ bool receive_sptps_record(void *handle, uint8_t type, const void *data, uint16_t } } + if(from->status.udppacket && inpkt.len > from->maxrecentlen) + from->maxrecentlen = inpkt.len; + receive_packet(from, &inpkt); return true; } -/* - send a packet to the given vpn ip. +// This function tries to get SPTPS keys, if they aren't already known. +// This function makes no guarantees - it is up to the caller to check the node's state to figure out if the keys are available. +static void try_sptps(node_t *n) { + if(n->status.validkey) + return; + + logger(DEBUG_TRAFFIC, LOG_INFO, "No valid key known yet for %s (%s)", n->name, n->hostname); + + if(!n->status.waitingforkey) + send_req_key(n); + else if(n->last_req_key + 10 < now.tv_sec) { + logger(DEBUG_ALWAYS, LOG_DEBUG, "No key from %s after 10 seconds, restarting SPTPS", n->name); + sptps_stop(&n->sptps); + n->status.waitingforkey = false; + send_req_key(n); + } + + return; +} + +static void send_udp_probe_packet(node_t *n, int len) { + vpn_packet_t packet; + packet.offset = DEFAULT_PACKET_OFFSET; + memset(DATA(&packet), 0, 14); + randomize(DATA(&packet) + 14, len - 14); + packet.len = len; + packet.priority = 0; + + logger(DEBUG_TRAFFIC, LOG_INFO, "Sending UDP probe length %d to %s (%s)", len, n->name, n->hostname); + + send_udppacket(n, &packet); +} + +// This function tries to establish a UDP tunnel to a node so that packets can be sent. +// If a tunnel is already established, it makes sure it stays up. +// This function makes no guarantees - it is up to the caller to check the node's state to figure out if UDP is usable. +static void try_udp(node_t* n) { + if(!udp_discovery) + return; + + /* Send gratuitous probe replies to 1.1 nodes. */ + + if((n->options >> 24) >= 3 && n->status.udp_confirmed) { + struct timeval ping_tx_elapsed; + timersub(&now, &n->udp_reply_sent, &ping_tx_elapsed); + + if(ping_tx_elapsed.tv_sec >= udp_discovery_keepalive_interval - 1) { + n->udp_reply_sent = now; + if(n->maxrecentlen) { + vpn_packet_t pkt; + pkt.len = n->maxrecentlen; + pkt.offset = DEFAULT_PACKET_OFFSET; + memset(DATA(&pkt), 0, 14); + randomize(DATA(&pkt) + 14, MIN_PROBE_SIZE - 14); + send_udp_probe_reply(n, &pkt, pkt.len); + n->maxrecentlen = 0; + } + } + } + + /* Probe request */ + + struct timeval ping_tx_elapsed; + timersub(&now, &n->udp_ping_sent, &ping_tx_elapsed); + + int interval = n->status.udp_confirmed ? udp_discovery_keepalive_interval : udp_discovery_interval; + + if(ping_tx_elapsed.tv_sec >= interval) { + send_udp_probe_packet(n, MIN_PROBE_SIZE); + n->udp_ping_sent = now; + + if(localdiscovery && !n->status.udp_confirmed && n->prevedge) { + n->status.send_locally = true; + send_udp_probe_packet(n, MIN_PROBE_SIZE); + n->status.send_locally = false; + } + } +} + +static length_t choose_initial_maxmtu(node_t *n) { +#ifdef IP_MTU + + int sock = -1; + + const sockaddr_t *sa = NULL; + int sockindex; + choose_udp_address(n, &sa, &sockindex); + if(!sa) + return MTU; + + sock = socket(sa->sa.sa_family, SOCK_DGRAM, IPPROTO_UDP); + if(sock < 0) { + logger(DEBUG_TRAFFIC, LOG_ERR, "Creating MTU assessment socket for %s (%s) failed: %s", n->name, n->hostname, sockstrerror(sockerrno)); + return MTU; + } + + if(connect(sock, &sa->sa, SALEN(sa->sa))) { + logger(DEBUG_TRAFFIC, LOG_ERR, "Connecting MTU assessment socket for %s (%s) failed: %s", n->name, n->hostname, sockstrerror(sockerrno)); + close(sock); + return MTU; + } + + int ip_mtu; + socklen_t ip_mtu_len = sizeof ip_mtu; + if(getsockopt(sock, IPPROTO_IP, IP_MTU, &ip_mtu, &ip_mtu_len)) { + logger(DEBUG_TRAFFIC, LOG_ERR, "getsockopt(IP_MTU) on %s (%s) failed: %s", n->name, n->hostname, sockstrerror(sockerrno)); + close(sock); + return MTU; + } + + close(sock); + + /* getsockopt(IP_MTU) returns the MTU of the physical interface. + We need to remove various overheads to get to the tinc MTU. */ + length_t mtu = ip_mtu; + mtu -= (sa->sa.sa_family == AF_INET6) ? sizeof(struct ip6_hdr) : sizeof(struct ip); + mtu -= 8; /* UDP */ + if(n->status.sptps) { + mtu -= SPTPS_DATAGRAM_OVERHEAD; + if((n->options >> 24) >= 4) + mtu -= sizeof(node_id_t) + sizeof(node_id_t); +#ifndef DISABLE_LEGACY + } else { + mtu -= digest_length(n->outdigest); + + /* Now it's tricky. We use CBC mode, so the length of the + encrypted payload must be a multiple of the blocksize. The + sequence number is also part of the encrypted payload, so we + must account for it after correcting for the blocksize. + Furthermore, the padding in the last block must be at least + 1 byte. */ + + length_t blocksize = cipher_blocksize(n->outcipher); + + if(blocksize > 1) { + mtu /= blocksize; + mtu *= blocksize; + mtu--; + } + + mtu -= 4; // seqno +#endif + } + + if (mtu < 512) { + logger(DEBUG_TRAFFIC, LOG_ERR, "getsockopt(IP_MTU) on %s (%s) returned absurdly small value: %d", n->name, n->hostname, ip_mtu); + return MTU; + } + if (mtu > MTU) + return MTU; + + logger(DEBUG_TRAFFIC, LOG_INFO, "Using system-provided maximum tinc MTU for %s (%s): %hd", n->name, n->hostname, mtu); + return mtu; + +#else + + return MTU; + +#endif +} + +/* This function tries to determines the MTU of a node. + By calling this function repeatedly, n->minmtu will be progressively + increased, and at some point, n->mtu will be fixed to n->minmtu. If the MTU + is already fixed, this function checks if it can be increased. */ + +static void try_mtu(node_t *n) { + if(!(n->options & OPTION_PMTU_DISCOVERY)) + return; + + if(udp_discovery && !n->status.udp_confirmed) { + n->maxrecentlen = 0; + n->mtuprobes = 0; + n->minmtu = 0; + n->maxmtu = MTU; + return; + } + + /* mtuprobes == 0..19: initial discovery, send bursts with 1 second interval, mtuprobes++ + mtuprobes == 20: fix MTU, and go to -1 + mtuprobes == -1: send one maxmtu and one maxmtu+1 probe every pinginterval + mtuprobes ==-2..-3: send one maxmtu probe every second + mtuprobes == -4: maxmtu no longer valid, reset minmtu and maxmtu and go to 0 */ + + struct timeval elapsed; + timersub(&now, &n->mtu_ping_sent, &elapsed); + if(n->mtuprobes >= 0) { + if(n->mtuprobes != 0 && elapsed.tv_sec == 0 && elapsed.tv_usec < 333333) + return; + } else { + if(n->mtuprobes < -1) { + if(elapsed.tv_sec < 1) + return; + } else { + if(elapsed.tv_sec < pinginterval) + return; + } + } + + n->mtu_ping_sent = now; + + try_fix_mtu(n); + + if(n->mtuprobes < -3) { + /* We lost three MTU probes, restart discovery */ + logger(DEBUG_TRAFFIC, LOG_INFO, "Decrease in PMTU to %s (%s) detected, restarting PMTU discovery", n->name, n->hostname); + n->mtuprobes = 0; + n->minmtu = 0; + } + + if(n->mtuprobes < 0) { + /* After the initial discovery, we only send one maxmtu and one + maxmtu+1 probe to detect PMTU increases. */ + send_udp_probe_packet(n, n->maxmtu); + if(n->mtuprobes == -1 && n->maxmtu + 1 < MTU) + send_udp_probe_packet(n, n->maxmtu + 1); + n->mtuprobes--; + } else { + /* Before initial discovery begins, set maxmtu to the most likely value. + If it's underestimated, we will correct it after initial discovery. */ + if(n->mtuprobes == 0) + n->maxmtu = choose_initial_maxmtu(n); + + for (;;) { + /* Decreasing the number of probes per cycle might make the algorithm react faster to lost packets, + but it will typically increase convergence time in the no-loss case. */ + const length_t probes_per_cycle = 8; + + /* This magic value was determined using math simulations. + It will result in a 1329-byte first probe, followed (if there was a reply) by a 1407-byte probe. + Since 1407 is just below the range of tinc MTUs over typical networks, + this fine-tuning allows tinc to cover a lot of ground very quickly. + This fine-tuning is only valid for maxmtu = MTU; if maxmtu is smaller, + then it's better to use a multiplier of 1. Indeed, this leads to an interesting scenario + if choose_initial_maxmtu() returns the actual MTU value - it will get confirmed with one single probe. */ + const float multiplier = (n->maxmtu == MTU) ? 0.97 : 1; + + const float cycle_position = probes_per_cycle - (n->mtuprobes % probes_per_cycle) - 1; + const length_t minmtu = MAX(n->minmtu, 512); + const float interval = n->maxmtu - minmtu; + + /* The core of the discovery algorithm is this exponential. + It produces very large probes early in the cycle, and then it very quickly decreases the probe size. + This reflects the fact that in the most difficult cases, we don't get any feedback for probes that + are too large, and therefore we need to concentrate on small offsets so that we can quickly converge + on the precise MTU as we are approaching it. + The last probe of the cycle is always 1 byte in size - this is to make sure we'll get at least one + reply per cycle so that we can make progress. */ + const length_t offset = powf(interval, multiplier * cycle_position / (probes_per_cycle - 1)); + + length_t maxmtu = n->maxmtu; + send_udp_probe_packet(n, minmtu + offset); + /* If maxmtu changed, it means the probe was rejected by the system because it was too large. + In that case, we recalculate with the new maxmtu and try again. */ + if(n->mtuprobes < 0 || maxmtu == n->maxmtu) + break; + } + + if(n->mtuprobes >= 0) + n->mtuprobes++; + } +} + +/* These functions try to establish a tunnel to a node (or its relay) so that + packets can be sent (e.g. exchange keys). + If a tunnel is already established, it tries to improve it (e.g. by trying + to establish a UDP tunnel instead of TCP). This function makes no + guarantees - it is up to the caller to check the node's state to figure out + if TCP and/or UDP is usable. By calling this function repeatedly, the + tunnel is gradually improved until we hit the wall imposed by the underlying + network environment. It is recommended to call this function every time a + packet is sent (or intended to be sent) to a node, so that the tunnel keeps + improving as packets flow, and then gracefully downgrades itself as it goes + idle. +*/ + +static void try_tx_sptps(node_t *n, bool mtu) { + /* If n is a TCP-only neighbor, we'll only use "cleartext" PACKET + messages anyway, so there's no need for SPTPS at all. */ + + if(n->connection && ((myself->options | n->options) & OPTION_TCPONLY)) + return; + + /* Otherwise, try to do SPTPS authentication with n if necessary. */ + + try_sptps(n); + + /* Do we need to statically relay packets? */ + + node_t *via = (n->via == myself) ? n->nexthop : n->via; + + /* If we do have a static relay, try everything with that one instead, if it supports relaying. */ + + if(via != n) { + if((via->options >> 24) < 4) + return; + return try_tx(via, mtu); + } + + /* Otherwise, try to establish UDP connectivity. */ + + try_udp(n); + if(mtu) + try_mtu(n); + + /* If we don't have UDP connectivity (yet), we need to use a dynamic relay (nexthop) + while we try to establish direct connectivity. */ + + if(!n->status.udp_confirmed && n != n->nexthop && (n->nexthop->options >> 24) >= 4) + try_tx(n->nexthop, mtu); +} + +static void try_tx_legacy(node_t *n, bool mtu) { + /* Does he have our key? If not, send one. */ + + if(!n->status.validkey_in) + send_ans_key(n); + + /* Check if we already have a key, or request one. */ + + if(!n->status.validkey) { + if(n->last_req_key + 10 <= now.tv_sec) { + send_req_key(n); + n->last_req_key = now.tv_sec; + } + return; + } + + try_udp(n); + if(mtu) + try_mtu(n); +} + +void try_tx(node_t *n, bool mtu) { + if(!n->status.reachable) + return; + if(n->status.sptps) + try_tx_sptps(n, mtu); + else + try_tx_legacy(n, mtu); +} + void send_packet(node_t *n, vpn_packet_t *packet) { - node_t *via; + // If it's for myself, write it to the tun/tap device. if(n == myself) { - if(overwrite_mac) + if(overwrite_mac) { memcpy(DATA(packet), mymac.x, ETH_ALEN); + // Use an arbitrary fake source address. + memcpy(DATA(packet) + ETH_ALEN, DATA(packet), ETH_ALEN); + DATA(packet)[ETH_ALEN * 2 - 1] ^= 0xFF; + } n->out_packets++; n->out_bytes += packet->len; devops.write(packet); return; } - logger(DEBUG_TRAFFIC, LOG_ERR, "Sending packet of %d bytes to %s (%s)", - packet->len, n->name, n->hostname); + logger(DEBUG_TRAFFIC, LOG_ERR, "Sending packet of %d bytes to %s (%s)", packet->len, n->name, n->hostname); + + // If the node is not reachable, drop it. if(!n->status.reachable) { - logger(DEBUG_TRAFFIC, LOG_INFO, "Node %s (%s) is not reachable", - n->name, n->hostname); + logger(DEBUG_TRAFFIC, LOG_INFO, "Node %s (%s) is not reachable", n->name, n->hostname); return; } + // Keep track of packet statistics. + n->out_packets++; n->out_bytes += packet->len; + // Check if it should be sent as an SPTPS packet. + if(n->status.sptps) { send_sptps_packet(n, packet); + try_tx(n, true); return; } - via = (packet->priority == -1 || n->via == myself) ? n->nexthop : n->via; + // Determine which node to actually send it to. + + node_t *via = (packet->priority == -1 || n->via == myself) ? n->nexthop : n->via; if(via != n) - logger(DEBUG_TRAFFIC, LOG_INFO, "Sending packet to %s via %s (%s)", - n->name, via->name, n->via->hostname); + logger(DEBUG_TRAFFIC, LOG_INFO, "Sending packet to %s via %s (%s)", n->name, via->name, n->via->hostname); + + // Try to send via UDP, unless TCP is forced. if(packet->priority == -1 || ((myself->options | via->options) & OPTION_TCPONLY)) { if(!send_tcppacket(via->connection, packet)) terminate_connection(via->connection, true); - } else - send_udppacket(via, packet); -} + return; + } -/* Broadcast a packet using the minimum spanning tree */ + send_udppacket(via, packet); + try_tx(via, true); +} void broadcast_packet(const node_t *from, vpn_packet_t *packet) { // Always give ourself a copy of the packet. @@ -1028,47 +1354,208 @@ void broadcast_packet(const node_t *from, vpn_packet_t *packet) { } } +/* We got a packet from some IP address, but we don't know who sent it. Try to + verify the message authentication code against all active session keys. + Since this is actually an expensive operation, we only do a full check once + a minute, the rest of the time we only check against nodes for which we know + an IP address that matches the one from the packet. */ + static node_t *try_harder(const sockaddr_t *from, const vpn_packet_t *pkt) { - node_t *n = NULL; + node_t *match = NULL; bool hard = false; static time_t last_hard_try = 0; - for splay_each(edge_t, e, edge_weight_tree) { - if(!e->to->status.reachable || e->to == myself) + for splay_each(node_t, n, node_tree) { + if(!n->status.reachable || n == myself) continue; - if(sockaddrcmp_noport(from, &e->address)) { + if(!n->status.validkey_in && !(n->status.sptps && n->sptps.instate)) + continue; + + bool soft = false; + + for splay_each(edge_t, e, n->edge_tree) { + if(!e->reverse) + continue; + if(!sockaddrcmp_noport(from, &e->reverse->address)) { + soft = true; + break; + } + } + + if(!soft) { if(last_hard_try == now.tv_sec) continue; hard = true; } - if(!try_mac(e->to, pkt)) + if(!try_mac(n, pkt)) continue; - n = e->to; + match = n; break; } if(hard) last_hard_try = now.tv_sec; - last_hard_try = now.tv_sec; - return n; + return match; +} + +static void handle_incoming_vpn_packet(listen_socket_t *ls, vpn_packet_t *pkt, sockaddr_t *addr) { + char *hostname; + node_id_t nullid = {}; + node_t *from, *to; + bool direct = false; + + sockaddrunmap(addr); /* Some braindead IPv6 implementations do stupid things. */ + + // Try to figure out who sent this packet. + + node_t *n = lookup_node_udp(addr); + + if(n && !n->status.udp_confirmed) + n = NULL; // Don't believe it if we don't have confirmation yet. + + if(!n) { + // It might be from a 1.1 node, which might have a source ID in the packet. + pkt->offset = 2 * sizeof(node_id_t); + from = lookup_node_id(SRCID(pkt)); + if(from && !memcmp(DSTID(pkt), &nullid, sizeof nullid) && from->status.sptps) { + if(sptps_verify_datagram(&from->sptps, DATA(pkt), pkt->len - 2 * sizeof(node_id_t))) + n = from; + else + goto skip_harder; + } + } + + if(!n) { + pkt->offset = 0; + n = try_harder(addr, pkt); + } + +skip_harder: + if(!n) { + if(debug_level >= DEBUG_PROTOCOL) { + hostname = sockaddr2hostname(addr); + logger(DEBUG_PROTOCOL, LOG_WARNING, "Received UDP packet from unknown source %s", hostname); + free(hostname); + } + return; + } + + pkt->offset = 0; + + if(n->status.sptps) { + bool relay_enabled = (n->options >> 24) >= 4; + if (relay_enabled) { + pkt->offset = 2 * sizeof(node_id_t); + pkt->len -= pkt->offset; + } + + if(!memcmp(DSTID(pkt), &nullid, sizeof nullid) || !relay_enabled) { + direct = true; + from = n; + to = myself; + } else { + from = lookup_node_id(SRCID(pkt)); + to = lookup_node_id(DSTID(pkt)); + } + if(!from || !to) { + logger(DEBUG_PROTOCOL, LOG_WARNING, "Received UDP packet from %s (%s) with unknown source and/or destination ID", n->name, n->hostname); + return; + } + + if(!to->status.reachable) { + /* This can happen in the form of a race condition + if the node just became unreachable. */ + logger(DEBUG_TRAFFIC, LOG_WARNING, "Cannot relay packet from %s (%s) because the destination, %s (%s), is unreachable", from->name, from->hostname, to->name, to->hostname); + return; + } + + /* The packet is supposed to come from the originator or its static relay + (i.e. with no dynamic relays in between). + If it did not, "help" the static relay by sending it UDP info. + Note that we only do this if we're the destination or the static relay; + otherwise every hop would initiate its own UDP info message, resulting in elevated chatter. */ + + if(n != from->via && to->via == myself) + send_udp_info(myself, from); + + /* If we're not the final recipient, relay the packet. */ + + if(to != myself) { + send_sptps_data(to, from, 0, DATA(pkt), pkt->len); + try_tx(to, true); + return; + } + } else { + direct = true; + from = n; + } + + if(!receive_udppacket(from, pkt)) + return; + + n->sock = ls - listen_socket; + if(direct && sockaddrcmp(addr, &n->address)) + update_node_udp(n, addr); + + /* If the packet went through a relay, help the sender find the appropriate MTU + through the relay path. */ + + if(!direct) + send_mtu_info(myself, n, MTU); } void handle_incoming_vpn_data(void *data, int flags) { listen_socket_t *ls = data; + +#ifdef HAVE_RECVMMSG +#define MAX_MSG 64 + static int num = MAX_MSG; + static vpn_packet_t pkt[MAX_MSG]; + static sockaddr_t addr[MAX_MSG]; + static struct mmsghdr msg[MAX_MSG]; + static struct iovec iov[MAX_MSG]; + + for(int i = 0; i < num; i++) { + pkt[i].offset = 0; + + iov[i] = (struct iovec){ + .iov_base = DATA(&pkt[i]), + .iov_len = MAXSIZE, + }; + + msg[i].msg_hdr = (struct msghdr){ + .msg_name = &addr[i].sa, + .msg_namelen = sizeof addr[i], + .msg_iov = &iov[i], + .msg_iovlen = 1, + }; + } + + num = recvmmsg(ls->udp.fd, msg, MAX_MSG, MSG_DONTWAIT, NULL); + + if(num < 0) { + if(!sockwouldblock(sockerrno)) + logger(DEBUG_ALWAYS, LOG_ERR, "Receiving packet failed: %s", sockstrerror(sockerrno)); + return; + } + + for(int i = 0; i < num; i++) { + pkt[i].len = msg[i].msg_len; + if(pkt[i].len <= 0 || pkt[i].len > MAXSIZE) + continue; + handle_incoming_vpn_packet(ls, &pkt[i], &addr[i]); + } +#else vpn_packet_t pkt; - char *hostname; - node_id_t nullid = {}; sockaddr_t addr = {}; socklen_t addrlen = sizeof addr; - node_t *from, *to; - bool direct = false; pkt.offset = 0; - int len = recvfrom(ls->udp.fd, DATA(&pkt), MAXSIZE, 0, &addr.sa, &addrlen); + int len = recvfrom(ls->udp.fd, (void *)DATA(&pkt), MAXSIZE, 0, &addr.sa, &addrlen); if(len <= 0 || len > MAXSIZE) { if(!sockwouldblock(sockerrno)) @@ -1078,71 +1565,8 @@ void handle_incoming_vpn_data(void *data, int flags) { pkt.len = len; - sockaddrunmap(&addr); /* Some braindead IPv6 implementations do stupid things. */ - - // Try to figure out who sent this packet. - - node_t *n = lookup_node_udp(&addr); - - if(!n) { - // It might be from a 1.1 node, which might have a source ID in the packet. - pkt.offset = 2 * sizeof(node_id_t); - from = lookup_node_id(SRCID(&pkt)); - if(from && !memcmp(DSTID(&pkt), &nullid, sizeof nullid) && from->status.sptps) { - if(sptps_verify_datagram(&from->sptps, DATA(&pkt), pkt.len - 2 * sizeof(node_id_t))) - n = from; - else - goto skip_harder; - } - } - - if(!n) { - pkt.offset = 0; - n = try_harder(&addr, &pkt); - } - -skip_harder: - if(!n) { - if(debug_level >= DEBUG_PROTOCOL) { - hostname = sockaddr2hostname(&addr); - logger(DEBUG_PROTOCOL, LOG_WARNING, "Received UDP packet from unknown source %s", hostname); - free(hostname); - } - return; - } - - if(n->status.sptps) { - pkt.offset = 2 * sizeof(node_id_t); - - if(!memcmp(DSTID(&pkt), &nullid, sizeof nullid)) { - direct = true; - from = n; - to = myself; - } else { - from = lookup_node_id(SRCID(&pkt)); - to = lookup_node_id(DSTID(&pkt)); - } - if(!from || !to) { - logger(DEBUG_PROTOCOL, LOG_WARNING, "Received UDP packet from %s (%s) with unknown source and/or destination ID", n->name, n->hostname); - return; - } - - if(to != myself) { - send_sptps_data_priv(to, n, 0, DATA(&pkt), pkt.len - 2 * sizeof(node_id_t)); - return; - } - } else { - direct = true; - from = n; - } - - pkt.offset = 0; - if(!receive_udppacket(from, &pkt)) - return; - - n->sock = ls - listen_socket; - if(direct && sockaddrcmp(&addr, &n->address)) - update_node_udp(n, &addr); + handle_incoming_vpn_packet(ls, &pkt, &addr); +#endif } void handle_device_data(void *data, int flags) { diff --git a/src/net_setup.c b/src/net_setup.c index 29f1212..30e6f84 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-2014 Guus Sliepen + 2000-2016 Guus Sliepen 2006 Scott Lamb 2010 Brandon Black @@ -43,6 +43,10 @@ #include "utils.h" #include "xalloc.h" +#ifdef HAVE_MINIUPNPC +#include "upnp.h" +#endif + char *myport; static char *myname; static io_t device_io; @@ -137,18 +141,17 @@ bool read_ecdsa_public_key(connection_t *c) { } c->ecdsa = ecdsa_read_pem_public_key(fp); - fclose(fp); - if(!c->ecdsa) + if(!c->ecdsa && errno != ENOENT) logger(DEBUG_ALWAYS, LOG_ERR, "Parsing Ed25519 public key file `%s' failed.", fname); + + fclose(fp); free(fname); return c->ecdsa; } +#ifndef DISABLE_LEGACY bool read_rsa_public_key(connection_t *c) { - if(ecdsa_active(c->ecdsa)) - return true; - FILE *fp; char *fname; char *n; @@ -182,6 +185,7 @@ bool read_rsa_public_key(connection_t *c) { free(fname); return c->rsa; } +#endif static bool read_ecdsa_private_key(void) { FILE *fp; @@ -226,14 +230,14 @@ static bool read_ecdsa_private_key(void) { static bool read_invitation_key(void) { FILE *fp; - char *fname; + char fname[PATH_MAX]; if(invitation_key) { ecdsa_free(invitation_key); invitation_key = NULL; } - xasprintf(&fname, "%s" SLASH "invitations" SLASH "ed25519_key.priv", confbase); + snprintf(fname, sizeof fname, "%s" SLASH "invitations" SLASH "ed25519_key.priv", confbase); fp = fopen(fname, "r"); @@ -244,10 +248,10 @@ static bool read_invitation_key(void) { logger(DEBUG_ALWAYS, LOG_ERR, "Reading Ed25519 private key file `%s' failed", fname); } - free(fname); return invitation_key; } +#ifndef DISABLE_LEGACY static bool read_rsa_private_key(void) { FILE *fp; char *fname; @@ -304,6 +308,7 @@ static bool read_rsa_private_key(void) { free(fname); return myself->connection->rsa; } +#endif static timeout_t keyexpire_timeout; @@ -315,6 +320,8 @@ static void keyexpire_handler(void *data) { void regenerate_key(void) { logger(DEBUG_STATUS, LOG_INFO, "Expiring symmetric keys"); send_key_changed(); + for splay_each(node_t, n, node_tree) + n->status.validkey_in = false; } /* @@ -323,13 +330,12 @@ void regenerate_key(void) { void load_all_subnets(void) { DIR *dir; struct dirent *ent; - char *dname; + char dname[PATH_MAX]; - xasprintf(&dname, "%s" SLASH "hosts", confbase); + snprintf(dname, sizeof dname, "%s" SLASH "hosts", confbase); dir = opendir(dname); if(!dir) { logger(DEBUG_ALWAYS, LOG_ERR, "Could not open %s: %s", dname, strerror(errno)); - free(dname); return; } @@ -362,6 +368,7 @@ void load_all_subnets(void) { if((s2 = lookup_subnet(n, s))) { s2->expires = -1; + free(s); } else { subnet_add(n, s); } @@ -376,13 +383,12 @@ void load_all_subnets(void) { void load_all_nodes(void) { DIR *dir; struct dirent *ent; - char *dname; + char dname[PATH_MAX]; - xasprintf(&dname, "%s" SLASH "hosts", confbase); + snprintf(dname, sizeof dname, "%s" SLASH "hosts", confbase); dir = opendir(dname); if(!dir) { logger(DEBUG_ALWAYS, LOG_ERR, "Could not open %s: %s", dname, strerror(errno)); - free(dname); return; } @@ -506,6 +512,14 @@ bool setup_myself_reloadable(void) { if(myself->options & OPTION_TCPONLY) myself->options |= OPTION_INDIRECT; + get_config_bool(lookup_config(config_tree, "UDPDiscovery"), &udp_discovery); + get_config_int(lookup_config(config_tree, "UDPDiscoveryKeepaliveInterval"), &udp_discovery_keepalive_interval); + get_config_int(lookup_config(config_tree, "UDPDiscoveryInterval"), &udp_discovery_interval); + get_config_int(lookup_config(config_tree, "UDPDiscoveryTimeout"), &udp_discovery_timeout); + + get_config_int(lookup_config(config_tree, "MTUInfoInterval"), &mtu_info_interval); + get_config_int(lookup_config(config_tree, "UDPInfoInterval"), &udp_info_interval); + get_config_bool(lookup_config(config_tree, "DirectOnly"), &directonly); get_config_bool(lookup_config(config_tree, "LocalDiscovery"), &localdiscovery); @@ -577,9 +591,14 @@ bool setup_myself_reloadable(void) { subnet_add(NULL, s); } -#if !defined(SOL_IP) || !defined(IP_TOS) +#if !defined(IPPROTO_IP) || !defined(IP_TOS) if(priorityinheritance) - logger(DEBUG_ALWAYS, LOG_WARNING, "%s not supported on this platform", "PriorityInheritance"); + logger(DEBUG_ALWAYS, LOG_WARNING, "%s not supported on this platform for IPv4 connections", "PriorityInheritance"); +#endif + +#if !defined(IPPROTO_IPV6) || !defined(IPV6_TCLASS) + if(priorityinheritance) + logger(DEBUG_ALWAYS, LOG_WARNING, "%s not supported on this platform for IPv6 connections", "PriorityInheritance"); #endif if(!get_config_int(lookup_config(config_tree, "MACExpire"), &macexpire)) @@ -652,6 +671,9 @@ static bool add_listen_address(char *address, bool bindto) { hint.ai_protocol = IPPROTO_TCP; hint.ai_flags = AI_PASSIVE; +#if HAVE_DECL_RES_INIT + res_init(); +#endif int err = getaddrinfo(address && *address ? address : NULL, port, &hint, &ai); free(address); @@ -773,6 +795,13 @@ static bool setup_myself(void) { myself->options |= PROT_MINOR << 24; +#ifdef DISABLE_LEGACY + experimental = read_ecdsa_private_key(); + if(!experimental) { + logger(DEBUG_ALWAYS, LOG_ERR, "No private key available, cannot start tinc!"); + return false; + } +#else if(!get_config_bool(lookup_config(config_tree, "ExperimentalProtocol"), &experimental)) { experimental = read_ecdsa_private_key(); if(!experimental) @@ -790,6 +819,7 @@ static bool setup_myself(void) { return false; } } +#endif /* Ensure myport is numeric */ @@ -831,14 +861,14 @@ static bool setup_myself(void) { } if(get_config_int(lookup_config(config_tree, "UDPRcvBuf"), &udp_rcvbuf)) { - if(udp_rcvbuf <= 0) { + if(udp_rcvbuf < 0) { logger(DEBUG_ALWAYS, LOG_ERR, "UDPRcvBuf cannot be negative!"); return false; } } if(get_config_int(lookup_config(config_tree, "UDPSndBuf"), &udp_sndbuf)) { - if(udp_sndbuf <= 0) { + if(udp_sndbuf < 0) { logger(DEBUG_ALWAYS, LOG_ERR, "UDPSndBuf cannot be negative!"); return false; } @@ -854,6 +884,7 @@ static bool setup_myself(void) { sptps_replaywin = replaywin; } +#ifndef DISABLE_LEGACY /* Generate packet encryption key */ if(!get_config_string(lookup_config(config_tree, "Cipher"), &cipher)) @@ -891,6 +922,7 @@ static bool setup_myself(void) { } free(digest); +#endif /* Compression */ @@ -939,6 +971,7 @@ static bool setup_myself(void) { else if(!strcasecmp(type, "vde")) devops = vde_devops; #endif + free(type); } get_config_bool(lookup_config(config_tree, "DeviceStandby"), &device_standby); @@ -1035,6 +1068,25 @@ static bool setup_myself(void) { xasprintf(&myself->hostname, "MYSELF port %s", myport); myself->connection->hostname = xstrdup(myself->hostname); + char *upnp = NULL; + get_config_string(lookup_config(config_tree, "UPnP"), &upnp); + bool upnp_tcp = false; + bool upnp_udp = false; + if (upnp) { + if (!strcasecmp(upnp, "yes")) + upnp_tcp = upnp_udp = true; + else if (!strcasecmp(upnp, "udponly")) + upnp_udp = true; + free(upnp); + } + if (upnp_tcp || upnp_udp) { +#ifdef HAVE_MINIUPNPC + upnp_init(upnp_tcp, upnp_udp); +#else + logger(DEBUG_ALWAYS, LOG_WARNING, "UPnP was requested, but tinc isn't built with miniupnpc support!"); +#endif + } + /* Done. */ last_config_check = now.tv_sec; @@ -1102,8 +1154,7 @@ void close_network_connections(void) { if(myself && myself->connection) { subnet_update(myself, NULL, false); - terminate_connection(myself->connection, false); - free_connection(myself->connection); + connection_del(myself->connection); } for(int i = 0; i < listen_sockets; i++) { diff --git a/src/net_socket.c b/src/net_socket.c index 1bf9d16..bafea64 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-2014 Guus Sliepen + 2000-2016 Guus Sliepen 2006 Scott Lamb 2009 Florian Forster @@ -35,16 +35,11 @@ #include "utils.h" #include "xalloc.h" -/* Needed on Mac OS/X */ -#ifndef SOL_TCP -#define SOL_TCP IPPROTO_TCP -#endif - int addressfamily = AF_UNSPEC; int maxtimeout = 900; int seconds_till_retry = 5; -int udp_rcvbuf = 0; -int udp_sndbuf = 0; +int udp_rcvbuf = 1024 * 1024; +int udp_sndbuf = 1024 * 1024; int max_connection_burst = 100; listen_socket_t listen_socket[MAXSOCKETS]; @@ -73,14 +68,19 @@ static void configure_tcp(connection_t *c) { } #endif -#if defined(SOL_TCP) && defined(TCP_NODELAY) +#if defined(IPPROTO_TCP) && defined(TCP_NODELAY) option = 1; - setsockopt(c->socket, SOL_TCP, TCP_NODELAY, (void *)&option, sizeof option); + setsockopt(c->socket, IPPROTO_TCP, TCP_NODELAY, (void *)&option, sizeof option); #endif -#if defined(SOL_IP) && defined(IP_TOS) && defined(IPTOS_LOWDELAY) +#if defined(IPPROTO_IP) && defined(IP_TOS) && defined(IPTOS_LOWDELAY) option = IPTOS_LOWDELAY; - setsockopt(c->socket, SOL_IP, IP_TOS, (void *)&option, sizeof option); + setsockopt(c->socket, IPPROTO_IP, IP_TOS, (void *)&option, sizeof option); +#endif + +#if defined(IPPROTO_IPV6) && defined(IPV6_TCLASS) && defined(IPTOS_LOWDELAY) + option = IPTOS_LOWDELAY; + setsockopt(c->socket, IPPROTO_IPV6, IPV6_TCLASS, (void *)&option, sizeof option); #endif } @@ -163,9 +163,9 @@ int setup_listen_socket(const sockaddr_t *sa) { option = 1; setsockopt(nfd, SOL_SOCKET, SO_REUSEADDR, (void *)&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, (void *)&option, sizeof option); + setsockopt(nfd, IPPROTO_IPV6, IPV6_V6ONLY, (void *)&option, sizeof option); #endif if(get_config_string @@ -261,10 +261,10 @@ int setup_vpn_in_socket(const sockaddr_t *sa) { #define IP_DONTFRAGMENT IP_DONTFRAG #endif -#if defined(SOL_IP) && defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DO) +#if defined(IPPROTO_IP) && defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DO) if(myself->options & OPTION_PMTU_DISCOVERY) { option = IP_PMTUDISC_DO; - setsockopt(nfd, SOL_IP, IP_MTU_DISCOVER, (void *)&option, sizeof(option)); + setsockopt(nfd, IPPROTO_IP, IP_MTU_DISCOVER, (void *)&option, sizeof(option)); } #elif defined(IPPROTO_IP) && defined(IP_DONTFRAGMENT) if(myself->options & OPTION_PMTU_DISCOVERY) { @@ -273,10 +273,10 @@ int setup_vpn_in_socket(const sockaddr_t *sa) { } #endif -#if defined(SOL_IPV6) && defined(IPV6_MTU_DISCOVER) && defined(IPV6_PMTUDISC_DO) +#if defined(IPPROTO_IPV6) && defined(IPV6_MTU_DISCOVER) && defined(IPV6_PMTUDISC_DO) if(myself->options & OPTION_PMTU_DISCOVERY) { option = IPV6_PMTUDISC_DO; - setsockopt(nfd, SOL_IPV6, IPV6_MTU_DISCOVER, (void *)&option, sizeof(option)); + setsockopt(nfd, IPPROTO_IPV6, IPV6_MTU_DISCOVER, (void *)&option, sizeof(option)); } #elif defined(IPPROTO_IPV6) && defined(IPV6_DONTFRAG) if(myself->options & OPTION_PMTU_DISCOVERY) { @@ -517,10 +517,10 @@ begin: #endif if(proxytype != PROXY_EXEC) { -#if defined(SOL_IPV6) && defined(IPV6_V6ONLY) +#if defined(IPPROTO_IPV6) && defined(IPV6_V6ONLY) int option = 1; if(c->address.sa.sa_family == AF_INET6) - setsockopt(c->socket, SOL_IPV6, IPV6_V6ONLY, (void *)&option, sizeof option); + setsockopt(c->socket, IPPROTO_IPV6, IPV6_V6ONLY, (void *)&option, sizeof option); #endif bind_to_interface(c->socket); @@ -547,10 +547,13 @@ begin: /* Now that there is a working socket, fill in the rest and register this connection. */ + c->last_ping_time = time(NULL); c->status.connecting = true; c->name = xstrdup(outgoing->name); +#ifndef DISABLE_LEGACY c->outcipher = myself->connection->outcipher; c->outdigest = myself->connection->outdigest; +#endif c->outmaclength = myself->connection->outmaclength; c->outcompression = myself->connection->outcompression; c->last_ping_time = now.tv_sec; @@ -602,9 +605,12 @@ void setup_outgoing_connection(outgoing_t *outgoing) { if(n && n->connection) { logger(DEBUG_CONNECTIONS, LOG_INFO, "Already connected to %s", outgoing->name); - - n->connection->outgoing = outgoing; - return; + if(!n->connection->outgoing) { + n->connection->outgoing = outgoing; + return; + } else { + goto remove; + } } init_configuration(&outgoing->config_tree); @@ -615,12 +621,16 @@ void setup_outgoing_connection(outgoing_t *outgoing) { if(n) outgoing->aip = outgoing->ai = get_known_addresses(n); if(!outgoing->ai) { - logger(DEBUG_ALWAYS, LOG_ERR, "No address known for %s", outgoing->name); - return; + logger(DEBUG_ALWAYS, LOG_DEBUG, "No address known for %s", outgoing->name); + goto remove; } } do_outgoing_connection(outgoing); + return; + +remove: + list_delete(outgoing_list, outgoing); } /* @@ -696,8 +706,10 @@ void handle_new_meta_connection(void *data, int flags) { c = new_connection(); c->name = xstrdup(""); +#ifndef DISABLE_LEGACY c->outcipher = myself->connection->outcipher; c->outdigest = myself->connection->outdigest; +#endif c->outmaclength = myself->connection->outmaclength; c->outcompression = myself->connection->outcompression; @@ -796,6 +808,11 @@ void try_outgoing_connections(void) { continue; } + if(!strcmp(name, myself->name)) { + free(name); + continue; + } + bool found = false; for list_each(outgoing_t, outgoing, outgoing_list) { diff --git a/src/netutl.c b/src/netutl.c index 989a152..2eebb64 100644 --- a/src/netutl.c +++ b/src/netutl.c @@ -39,6 +39,9 @@ struct addrinfo *str2addrinfo(const char *address, const char *service, int sock hint.ai_family = addressfamily; hint.ai_socktype = socktype; +#if HAVE_DECL_RES_INIT + res_init(); +#endif err = getaddrinfo(address, service, &hint, &ai); if(err) { @@ -80,7 +83,13 @@ void sockaddr2str(const sockaddr_t *sa, char **addrstr, char **portstr) { char *scopeid; int err; - if(sa->sa.sa_family == AF_UNKNOWN) { + if(sa->sa.sa_family == AF_UNSPEC) { + if(addrstr) + *addrstr = xstrdup("unspec"); + if(portstr) + *portstr = xstrdup("unspec"); + return; + } else if(sa->sa.sa_family == AF_UNKNOWN) { if(addrstr) *addrstr = xstrdup(sa->unknown.address); if(portstr) @@ -112,7 +121,10 @@ char *sockaddr2hostname(const sockaddr_t *sa) { char port[NI_MAXSERV] = "unknown"; int err; - if(sa->sa.sa_family == AF_UNKNOWN) { + if(sa->sa.sa_family == AF_UNSPEC) { + xasprintf(&str, "unspec port unspec"); + return str; + } else if(sa->sa.sa_family == AF_UNKNOWN) { xasprintf(&str, "%s port %s", sa->unknown.address, sa->unknown.port); return str; } diff --git a/src/node.c b/src/node.c index e97bfaf..7242e95 100644 --- a/src/node.c +++ b/src/node.c @@ -30,12 +30,11 @@ #include "utils.h" #include "xalloc.h" -static digest_t *sha256; +#include "ed25519/sha512.h" splay_tree_t *node_tree; static splay_tree_t *node_id_tree; -static hash_t *node_udp_cache; -static hash_t *node_id_cache; +static splay_tree_t *node_udp_tree; node_t *myself; @@ -47,22 +46,23 @@ static int node_id_compare(const node_t *a, const node_t *b) { return memcmp(&a->id, &b->id, sizeof(node_id_t)); } -void init_nodes(void) { - sha256 = digest_open_by_name("sha256", sizeof(node_id_t)); +static int node_udp_compare(const node_t *a, const node_t *b) { + int result = sockaddrcmp(&a->address, &b->address); + if (result) + return result; + return (a->name && b->name) ? strcmp(a->name, b->name) : 0; +} +void init_nodes(void) { node_tree = splay_alloc_tree((splay_compare_t) node_compare, (splay_action_t) free_node); node_id_tree = splay_alloc_tree((splay_compare_t) node_id_compare, NULL); - node_udp_cache = hash_alloc(0x100, sizeof(sockaddr_t)); - node_id_cache = hash_alloc(0x100, sizeof(node_id_t)); + node_udp_tree = splay_alloc_tree((splay_compare_t) node_udp_compare, NULL); } void exit_nodes(void) { - hash_free(node_id_cache); - hash_free(node_udp_cache); + splay_delete_tree(node_udp_tree); splay_delete_tree(node_id_tree); splay_delete_tree(node_tree); - - digest_close(sha256); } node_t *new_node(void) { @@ -86,15 +86,17 @@ void free_node(node_t *n) { sockaddrfree(&n->address); +#ifndef DISABLE_LEGACY cipher_close(n->incipher); digest_close(n->indigest); cipher_close(n->outcipher); digest_close(n->outdigest); +#endif ecdsa_free(n->ecdsa); sptps_stop(&n->sptps); - timeout_del(&n->mtutimeout); + timeout_del(&n->udp_ping_timeout); if(n->hostname) free(n->hostname); @@ -109,15 +111,16 @@ void free_node(node_t *n) { } void node_add(node_t *n) { - digest_create(sha256, n->name, strlen(n->name), &n->id); + unsigned char buf[64]; + sha512(n->name, strlen(n->name),buf); + memcpy(&n->id, buf, sizeof n->id); splay_insert(node_tree, n); splay_insert(node_id_tree, n); } void node_del(node_t *n) { - hash_delete(node_udp_cache, &n->address); - hash_delete(node_id_cache, &n->id); + splay_delete(node_udp_tree, n); for splay_each(subnet_t, s, n->subnet_tree) subnet_del(n, s); @@ -138,19 +141,13 @@ node_t *lookup_node(char *name) { } node_t *lookup_node_id(const node_id_t *id) { - node_t *n = hash_search(node_id_cache, id); - if(!n) { - node_t tmp = {.id = *id}; - n = splay_search(node_id_tree, &tmp); - if(n) - hash_insert(node_id_cache, id, n); - } - - return n; + node_t n = {.id = *id}; + return splay_search(node_id_tree, &n); } node_t *lookup_node_udp(const sockaddr_t *sa) { - return hash_search(node_udp_cache, sa); + node_t tmp = {.address = *sa}; + return splay_search(node_udp_tree, &tmp); } void update_node_udp(node_t *n, const sockaddr_t *sa) { @@ -159,7 +156,7 @@ void update_node_udp(node_t *n, const sockaddr_t *sa) { return; } - hash_delete(node_udp_cache, &n->address); + splay_delete(node_udp_tree, n); if(sa) { n->address = *sa; @@ -170,7 +167,7 @@ void update_node_udp(node_t *n, const sockaddr_t *sa) { break; } } - hash_insert(node_udp_cache, sa, n); + splay_insert(node_udp_tree, n); free(n->hostname); n->hostname = sockaddr2hostname(&n->address); logger(DEBUG_PROTOCOL, LOG_DEBUG, "UDP address of %s set to %s", n->name, n->hostname); @@ -179,6 +176,7 @@ void update_node_udp(node_t *n, const sockaddr_t *sa) { /* invalidate UDP information - note that this is a security feature as well to make sure we can't be tricked into flooding any random address with UDP packets */ n->status.udp_confirmed = false; + n->maxrecentlen = 0; n->mtuprobes = 0; n->minmtu = 0; n->maxmtu = MTU; @@ -188,13 +186,18 @@ bool dump_nodes(connection_t *c) { for splay_each(node_t, n, node_tree) { char id[2 * sizeof n->id + 1]; for (size_t c = 0; c < sizeof n->id; ++c) - sprintf(id + 2 * c, "%02hhx", n->id.x[c]); + snprintf(id + 2 * c, 3, "%02hhx", n->id.x[c]); id[sizeof id - 1] = 0; send_request(c, "%d %d %s %s %s %d %d %d %d %x %x %s %s %d %hd %hd %hd %ld", CONTROL, REQ_DUMP_NODES, - n->name, id, n->hostname ?: "unknown port unknown", cipher_get_nid(n->outcipher), - digest_get_nid(n->outdigest), (int)digest_length(n->outdigest), n->outcompression, - n->options, bitfield_to_int(&n->status, sizeof n->status), n->nexthop ? n->nexthop->name : "-", - n->via ? n->via->name ?: "-" : "-", n->distance, n->mtu, n->minmtu, n->maxmtu, (long)n->last_state_change); + n->name, id, n->hostname ?: "unknown port unknown", +#ifdef DISABLE_LEGACY + 0, 0, 0, +#else + cipher_get_nid(n->outcipher), digest_get_nid(n->outdigest), (int)digest_length(n->outdigest), +#endif + n->outcompression, n->options, bitfield_to_int(&n->status, sizeof n->status), + n->nexthop ? n->nexthop->name : "-", n->via ? n->via->name ?: "-" : "-", n->distance, + n->mtu, n->minmtu, n->maxmtu, (long)n->last_state_change); } return send_request(c, "%d %d", CONTROL, REQ_DUMP_NODES); diff --git a/src/node.h b/src/node.h index b6db18b..6ca6432 100644 --- a/src/node.h +++ b/src/node.h @@ -38,17 +38,19 @@ typedef struct node_status_t { unsigned int sptps:1; /* 1 if this node supports SPTPS */ unsigned int udp_confirmed:1; /* 1 if the address is one that we received UDP traffic on */ unsigned int send_locally:1; /* 1 if the next UDP packet should be sent on the local network */ - unsigned int unused:23; + unsigned int udppacket:1; /* 1 if the most recently received packet was UDP */ + unsigned int validkey_in:1; /* 1 if we have sent a valid key to him */ + unsigned int unused:21; } node_status_t; typedef struct node_t { char *name; /* name of this node */ + char *hostname; /* the hostname of its real ip */ node_id_t id; /* unique node ID (name hash) */ uint32_t options; /* options turned on for this node */ int sock; /* Socket to use for outgoing UDP packets */ sockaddr_t address; /* his real (internet) ip to send UDP packets to */ - char *hostname; /* the hostname of its real ip */ node_status_t status; time_t last_state_change; @@ -57,11 +59,13 @@ typedef struct node_t { ecdsa_t *ecdsa; /* His public ECDSA key */ sptps_t sptps; +#ifndef DISABLE_LEGACY cipher_t *incipher; /* Cipher for UDP packets */ digest_t *indigest; /* Digest for UDP packets */ cipher_t *outcipher; /* Cipher for UDP packets */ digest_t *outdigest; /* Digest for UDP packets */ +#endif int incompression; /* Compressionlevel, 0 = no compression */ int outcompression; /* Compressionlevel, 0 = no compression */ @@ -85,16 +89,21 @@ typedef struct node_t { uint32_t farfuture; /* Packets in a row that have arrived from the far future */ unsigned char* late; /* Bitfield marking late packets */ + struct timeval udp_reply_sent; /* Last time a (gratuitous) UDP probe reply was sent */ + struct timeval udp_ping_sent; /* Last time a UDP probe was sent */ + timeout_t udp_ping_timeout; /* Ping timeout event */ + + struct timeval mtu_ping_sent; /* Last time a MTU probe was sent */ + + struct timeval mtu_info_sent; /* Last time a MTU_INFO message was sent */ + struct timeval udp_info_sent; /* Last time a UDP_INFO message was sent */ + + length_t maxrecentlen; /* Maximum size of recently received packets */ + length_t mtu; /* Maximum size of packets to send to this node */ length_t minmtu; /* Probed minimum MTU */ length_t maxmtu; /* Probed maximum MTU */ int mtuprobes; /* Number of probes */ - timeout_t mtutimeout; /* Probe event */ - struct timeval probe_time; /* Time the last probe was sent or received */ - int probe_counter; /* Number of probes received since last burst was sent */ - float rtt; /* Last measured round trip time */ - float bandwidth; /* Last measured bandwidth */ - float packetloss; /* Last measured packet loss rate */ uint64_t in_packets; uint64_t in_bytes; diff --git a/src/nolegacy/crypto.c b/src/nolegacy/crypto.c new file mode 100644 index 0000000..f1113b4 --- /dev/null +++ b/src/nolegacy/crypto.c @@ -0,0 +1,87 @@ +/* + crypto.c -- Cryptographic miscellaneous functions and initialisation + Copyright (C) 2007-2014 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "../system.h" + +#include "../crypto.h" + +#ifndef HAVE_MINGW + +static int random_fd = -1; + +static void random_init(void) { + random_fd = open("/dev/urandom", O_RDONLY); + if(random_fd < 0) + random_fd = open("/dev/random", O_RDONLY); + if(random_fd < 0) { + fprintf(stderr, "Could not open source of random numbers: %s\n", strerror(errno)); + abort(); + } +} + +static void random_exit(void) { + close(random_fd); +} + +void randomize(void *out, size_t outlen) { + while(outlen) { + size_t len = read(random_fd, out, outlen); + if(len <= 0) { + if(errno == EAGAIN || errno == EINTR) + continue; + fprintf(stderr, "Could not read random numbers: %s\n", strerror(errno)); + abort(); + } + out += len; + outlen -= len; + } +} + +#else + +#include +HCRYPTPROV prov; + +void random_init(void) { + if(!CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) { + fprintf(stderr, "CryptAcquireContext() failed!\n"); + abort(); + } +} + +void random_exit(void) { + CryptReleaseContext(prov, 0); +} + +void randomize(void *out, size_t outlen) { + if(!CryptGenRandom(prov, outlen, out)) { + fprintf(stderr, "CryptGenRandom() failed\n"); + abort(); + } +} + +#endif + +void crypto_init(void) { + random_init(); +} + +void crypto_exit(void) { + random_exit(); +} diff --git a/src/nolegacy/prf.c b/src/nolegacy/prf.c new file mode 100644 index 0000000..55c9923 --- /dev/null +++ b/src/nolegacy/prf.c @@ -0,0 +1,106 @@ +/* + prf.c -- Pseudo-Random Function for key material generation + Copyright (C) 2011-2013 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "../system.h" + +#include "../prf.h" +#include "../ed25519/sha512.h" + +static void memxor(char *buf, char c, size_t len) { + for(size_t i = 0; i < len; i++) + buf[i] ^= c; +} + +static const size_t mdlen = 64; +static const size_t blklen = 128; + +static bool hmac_sha512(const char *key, size_t keylen, const char *msg, size_t msglen, char *out) { + char tmp[blklen + mdlen]; + sha512_context md; + + if(keylen <= blklen) { + memcpy(tmp, key, keylen); + memset(tmp + keylen, 0, blklen - keylen); + } else { + if(sha512(key, keylen, tmp) != 0) + return false; + memset(tmp + mdlen, 0, blklen - mdlen); + } + + if(sha512_init(&md) != 0) + return false; + + // ipad + memxor(tmp, 0x36, blklen); + if(sha512_update(&md, tmp, blklen) != 0) + return false; + + // message + if(sha512_update(&md, msg, msglen) != 0) + return false; + + if(sha512_final(&md, tmp + blklen) != 0) + return false; + + // opad + memxor(tmp, 0x36 ^ 0x5c, blklen); + if(sha512(tmp, sizeof tmp, out) != 0) + return false; + + return true; +} + + +/* Generate key material from a master secret and a seed, based on RFC 4346 section 5. + We use SHA512 instead of MD5 and SHA1. + */ + +bool prf(const char *secret, size_t secretlen, char *seed, size_t seedlen, char *out, size_t outlen) { + /* Data is what the "inner" HMAC function processes. + It consists of the previous HMAC result plus the seed. + */ + + char data[mdlen + seedlen]; + memset(data, 0, mdlen); + memcpy(data + mdlen, seed, seedlen); + + char hash[mdlen]; + + while(outlen > 0) { + /* Inner HMAC */ + if(!hmac_sha512(secret, secretlen, data, sizeof data, data)) + return false; + + /* Outer HMAC */ + if(outlen >= mdlen) { + if(!hmac_sha512(secret, secretlen, data, sizeof data, out)) + return false; + out += mdlen; + outlen -= mdlen; + } else { + if(!hmac_sha512(secret, secretlen, data, sizeof data, hash)) + return false; + memcpy(out, hash, outlen); + out += outlen; + outlen = 0; + } + } + + return true; +} diff --git a/src/openssl/cipher.c b/src/openssl/cipher.c index 9b39a28..04aee27 100644 --- a/src/openssl/cipher.c +++ b/src/openssl/cipher.c @@ -79,6 +79,13 @@ size_t cipher_keylength(const cipher_t *cipher) { return cipher->cipher->key_len + cipher->cipher->iv_len; } +size_t cipher_blocksize(const cipher_t *cipher) { + if(!cipher || !cipher->cipher) + return 1; + + return cipher->cipher->block_size; +} + bool cipher_set_key(cipher_t *cipher, void *key, bool encrypt) { bool result; diff --git a/src/process.c b/src/process.c index 2243bf9..5bb7eb3 100644 --- a/src/process.c +++ b/src/process.c @@ -42,6 +42,7 @@ bool sigalrm = false; extern char **g_argv; extern bool use_logfile; +extern bool use_syslog; /* Some functions the less gifted operating systems might lack... */ @@ -61,12 +62,9 @@ static bool install_service(void) { return false; } - if(!strchr(program_name, '\\')) { - GetCurrentDirectory(sizeof command - 1, command + 1); - strncat(command, "\\", sizeof command - strlen(command)); - } - - strncat(command, program_name, sizeof command - strlen(command)); + HMODULE module = GetModuleHandle(NULL); + GetModuleFileName(module, command + 1, sizeof command - 1); + command[sizeof command - 1] = 0; strncat(command, "\"", sizeof command - strlen(command)); @@ -189,6 +187,8 @@ bool init_service(void) { Detach from current terminal */ bool detach(void) { + logmode_t logmode; + #ifndef HAVE_MINGW signal(SIGPIPE, SIG_IGN); signal(SIGUSR1, SIG_IGN); @@ -200,7 +200,7 @@ bool detach(void) { if(do_detach) { #ifndef HAVE_MINGW - if(daemon(0, 0)) { + if(daemon(1, 0)) { logger(DEBUG_ALWAYS, LOG_ERR, "Couldn't detach from terminal: %s", strerror(errno)); return false; } @@ -210,12 +210,17 @@ bool detach(void) { #endif } - openlogger(identname, use_logfile?LOGMODE_FILE:(do_detach?LOGMODE_SYSLOG:LOGMODE_STDERR)); + if(use_logfile) + logmode = LOGMODE_FILE; + else if(use_syslog || do_detach) + logmode = LOGMODE_SYSLOG; + else + logmode = LOGMODE_STDERR; + + openlogger(identname, logmode); logger(DEBUG_ALWAYS, LOG_NOTICE, "tincd %s (%s %s) starting, debug level %d", - VERSION, BUILD_DATE, BUILD_TIME, debug_level); + BUILD_VERSION, BUILD_DATE, BUILD_TIME, debug_level); return true; } - - diff --git a/src/protocol.c b/src/protocol.c index 1ec169a..f533a93 100644 --- a/src/protocol.c +++ b/src/protocol.c @@ -41,6 +41,9 @@ static bool (*request_handlers[])(connection_t *, const char *) = { add_subnet_h, del_subnet_h, add_edge_h, del_edge_h, key_changed_h, req_key_h, ans_key_h, tcppacket_h, control_h, + NULL, NULL, /* Not "real" requests (yet) */ + sptps_tcppacket_h, + udp_info_h, mtu_info_h, }; /* Request names */ @@ -51,6 +54,7 @@ static char (*request_name[]) = { "PING", "PONG", "ADD_SUBNET", "DEL_SUBNET", "ADD_EDGE", "DEL_EDGE", "KEY_CHANGED", "REQ_KEY", "ANS_KEY", "PACKET", "CONTROL", + "REQ_PUBKEY", "ANS_PUBKEY", "SPTPS_PACKET", "UDP_INFO", "MTU_INFO", }; static splay_tree_t *past_request_tree; @@ -132,7 +136,8 @@ bool receive_request(connection_t *c, const char *request) { if(!request_handlers[reqno](c, request)) { /* Something went wrong. Probably scriptkiddies. Terminate. */ - logger(DEBUG_ALWAYS, LOG_ERR, "Error while processing %s from %s (%s)", request_name[reqno], c->name, c->hostname); + if(reqno != TERMREQ) + logger(DEBUG_ALWAYS, LOG_ERR, "Error while processing %s from %s (%s)", request_name[reqno], c->name, c->hostname); return false; } } else { diff --git a/src/protocol.h b/src/protocol.h index 080d50c..dee6eb8 100644 --- a/src/protocol.h +++ b/src/protocol.h @@ -26,7 +26,7 @@ /* Protocol version. Different major versions are incompatible. */ #define PROT_MAJOR 17 -#define PROT_MINOR 4 /* Should not exceed 255! */ +#define PROT_MINOR 7 /* Should not exceed 255! */ /* Silly Windows */ @@ -48,7 +48,8 @@ typedef enum request_t { /* Tinc 1.1 requests */ CONTROL, REQ_PUBKEY, ANS_PUBKEY, - REQ_SPTPS, + SPTPS_PACKET, + UDP_INFO, MTU_INFO, LAST /* Guardian for the highest request number */ } request_t; @@ -107,6 +108,9 @@ extern void send_key_changed(void); extern bool send_req_key(struct node_t *); extern bool send_ans_key(struct node_t *); extern bool send_tcppacket(struct connection_t *, const struct vpn_packet_t *); +extern bool send_sptps_tcppacket(struct connection_t *, const char*, int); +extern bool send_udp_info(struct node_t *, struct node_t *); +extern bool send_mtu_info(struct node_t *, struct node_t *, int); /* Request handlers */ @@ -128,6 +132,9 @@ extern bool key_changed_h(struct connection_t *, const char *); extern bool req_key_h(struct connection_t *, const char *); extern bool ans_key_h(struct connection_t *, const char *); extern bool tcppacket_h(struct connection_t *, const char *); +extern bool sptps_tcppacket_h(struct connection_t *, const char *); extern bool control_h(struct connection_t *, const char *); +extern bool udp_info_h(struct connection_t *, const char *); +extern bool mtu_info_h(struct connection_t *, const char *); #endif /* __TINC_PROTOCOL_H__ */ diff --git a/src/protocol_auth.c b/src/protocol_auth.c index cd39f28..0a7ad1c 100644 --- a/src/protocol_auth.c +++ b/src/protocol_auth.c @@ -45,6 +45,8 @@ #include "utils.h" #include "xalloc.h" +#include "ed25519/sha512.h" + ecdsa_t *invitation_key = NULL; static bool send_proxyrequest(connection_t *c) { @@ -115,7 +117,7 @@ static bool send_proxyrequest(connection_t *c) { i += 2; c->tcplen += 22; } else { - logger(DEBUG_ALWAYS, LOG_ERR, "Address family %hx not supported for SOCKS 5 proxies!", c->address.sa.sa_family); + logger(DEBUG_ALWAYS, LOG_ERR, "Address family %x not supported for SOCKS 5 proxies!", c->address.sa.sa_family); return false; } if(i > len) @@ -211,17 +213,13 @@ static bool receive_invitation_sptps(void *handle, uint8_t type, const void *dat return false; // Recover the filename from the cookie and the key - digest_t *digest = digest_open_by_name("sha256", 18); - if(!digest) - abort(); char *fingerprint = ecdsa_get_base64_public_key(invitation_key); char hashbuf[18 + strlen(fingerprint)]; - char cookie[25]; + char cookie[64]; memcpy(hashbuf, data, 18); memcpy(hashbuf + 18, fingerprint, sizeof hashbuf - 18); - digest_create(digest, hashbuf, sizeof hashbuf, cookie); + sha512(hashbuf, sizeof hashbuf, cookie); b64encode_urlsafe(cookie, cookie, 18); - digest_close(digest); free(fingerprint); char filename[PATH_MAX], usedname[PATH_MAX]; @@ -388,7 +386,7 @@ bool id_h(connection_t *c, const char *request) { /* Forbid version rollback for nodes whose Ed25519 key we know */ - if(ecdsa_active(c->ecdsa) && c->protocol_minor < 2) { + if(ecdsa_active(c->ecdsa) && c->protocol_minor < 1) { logger(DEBUG_ALWAYS, LOG_ERR, "Peer %s (%s) tries to roll back protocol version to %d.%d", c->name, c->hostname, c->protocol_major, c->protocol_minor); return false; @@ -412,6 +410,9 @@ bool id_h(connection_t *c, const char *request) { } bool send_metakey(connection_t *c) { +#ifdef DISABLE_LEGACY + return false; +#else if(!myself->connection->rsa) { logger(DEBUG_CONNECTIONS, LOG_ERR, "Peer %s (%s) uses legacy protocol which we don't support", c->name, c->hostname); return false; @@ -480,9 +481,13 @@ bool send_metakey(connection_t *c) { c->status.encryptout = true; return result; +#endif } bool metakey_h(connection_t *c, const char *request) { +#ifdef DISABLE_LEGACY + return false; +#else if(!myself->connection->rsa) return false; @@ -545,9 +550,13 @@ bool metakey_h(connection_t *c, const char *request) { c->allow_request = CHALLENGE; return send_challenge(c); +#endif } bool send_challenge(connection_t *c) { +#ifdef DISABLE_LEGACY + return false; +#else const size_t len = rsa_size(c->rsa); char buffer[len * 2 + 1]; @@ -565,9 +574,13 @@ bool send_challenge(connection_t *c) { /* Send the challenge */ return send_request(c, "%d %s", CHALLENGE, buffer); +#endif } bool challenge_h(connection_t *c, const char *request) { +#ifdef DISABLE_LEGACY + return false; +#else if(!myself->connection->rsa) return false; @@ -606,9 +619,13 @@ bool challenge_h(connection_t *c, const char *request) { c->allow_request = CHAL_REPLY; return send_request(c, "%d %s", CHAL_REPLY, buffer); +#endif } bool chal_reply_h(connection_t *c, const char *request) { +#ifdef DISABLE_LEGACY + return false; +#else char hishash[MAX_STRING_SIZE]; if(sscanf(request, "%*d " MAX_STRING, hishash) != 1) { @@ -645,9 +662,13 @@ bool chal_reply_h(connection_t *c, const char *request) { c->allow_request = ACK; return send_ack(c); +#endif } static bool send_upgrade(connection_t *c) { +#ifdef DISABLE_LEGACY + return false; +#else /* Special case when protocol_minor is 1: the other end is Ed25519 capable, * but doesn't know our key yet. So send it now. */ @@ -659,6 +680,7 @@ static bool send_upgrade(connection_t *c) { bool result = send_request(c, "%d %s", ACK, pubkey); free(pubkey); return result; +#endif } bool send_ack(connection_t *c) { @@ -758,6 +780,8 @@ static bool upgrade_h(connection_t *c, const char *request) { logger(DEBUG_ALWAYS, LOG_INFO, "Got Ed25519 public key from %s (%s), upgrading!", c->name, c->hostname); append_config_file(c->name, "Ed25519PublicKey", pubkey); c->allow_request = TERMREQ; + if(c->outgoing) + c->outgoing->timeout = 0; return send_termreq(c); } diff --git a/src/protocol_edge.c b/src/protocol_edge.c index 4760162..dc0cf05 100644 --- a/src/protocol_edge.c +++ b/src/protocol_edge.c @@ -37,19 +37,26 @@ bool send_add_edge(connection_t *c, const edge_t *e) { bool x; char *address, *port; - char *local_address, *local_port; sockaddr2str(&e->address, &address, &port); - sockaddr2str(&e->local_address, &local_address, &local_port); - x = send_request(c, "%d %x %s %s %s %s %x %d %s %s", ADD_EDGE, rand(), - e->from->name, e->to->name, address, port, - e->options, e->weight, local_address, local_port); + if(e->local_address.sa.sa_family) { + char *local_address, *local_port; + sockaddr2str(&e->local_address, &local_address, &local_port); + + x = send_request(c, "%d %x %s %s %s %s %x %d %s %s", ADD_EDGE, rand(), + e->from->name, e->to->name, address, port, + e->options, e->weight, local_address, local_port); + free(local_address); + free(local_port); + } else { + x = send_request(c, "%d %x %s %s %s %s %x %d", ADD_EDGE, rand(), + e->from->name, e->to->name, address, port, + e->options, e->weight); + } free(address); free(port); - free(local_address); - free(local_port); return x; } @@ -61,9 +68,9 @@ bool add_edge_h(connection_t *c, const char *request) { char to_name[MAX_STRING_SIZE]; char to_address[MAX_STRING_SIZE]; char to_port[MAX_STRING_SIZE]; - char address_local[MAX_STRING_SIZE] = "unknown"; - char port_local[MAX_STRING_SIZE] = "unknown"; - sockaddr_t address, local_address; + char address_local[MAX_STRING_SIZE]; + char port_local[MAX_STRING_SIZE]; + sockaddr_t address, local_address = {{0}}; uint32_t options; int weight; @@ -117,27 +124,71 @@ bool add_edge_h(connection_t *c, const char *request) { /* Convert addresses */ address = str2sockaddr(to_address, to_port); - local_address = str2sockaddr(address_local, port_local); + if(parameter_count >= 8) + local_address = str2sockaddr(address_local, port_local); /* Check if edge already exists */ e = lookup_edge(from, to); if(e) { - if(e->weight != weight || e->options != options || sockaddrcmp(&e->address, &address) || sockaddrcmp(&e->local_address, &local_address)) { + if(e->weight != weight || e->options != options || sockaddrcmp(&e->address, &address)) { if(from == myself) { logger(DEBUG_PROTOCOL, LOG_WARNING, "Got %s from %s (%s) for ourself which does not match existing entry", "ADD_EDGE", c->name, c->hostname); send_add_edge(c, e); + sockaddrfree(&local_address); return true; } else { logger(DEBUG_PROTOCOL, LOG_WARNING, "Got %s from %s (%s) which does not match existing entry", "ADD_EDGE", c->name, c->hostname); - edge_del(e); - graph(); + e->options = options; + if(sockaddrcmp(&e->address, &address)) { + sockaddrfree(&e->address); + e->address = address; + } + if(e->weight != weight) { + splay_node_t *node = splay_unlink(edge_weight_tree, e); + e->weight = weight; + splay_insert_node(edge_weight_tree, node); + } + + goto done; } - } else + } else if(sockaddrcmp(&e->local_address, &local_address)) { + if(from == myself) { + if(e->local_address.sa.sa_family && local_address.sa.sa_family) { + // Someone has the wrong local address for ourself. Correct then. + logger(DEBUG_PROTOCOL, LOG_WARNING, "Got %s from %s (%s) for ourself which does not match existing entry", + "ADD_EDGE", c->name, c->hostname); + send_add_edge(c, e); + sockaddrfree(&local_address); + return true; + } + // Otherwise, just ignore it. + sockaddrfree(&local_address); + return true; + } else if(local_address.sa.sa_family && local_address.sa.sa_family != AF_UNKNOWN) { + // We learned a new local address for this edge. + // local_address.sa.sa_family will be 0 if we got it from older tinc versions + // local_address.sa.sa_family will be 255 (AF_UNKNOWN) if we got it from newer versions + // but for edge which does not have local_address + sockaddrfree(&e->local_address); + e->local_address = local_address; + + // Tell others about it. + if(!tunnelserver) + forward_request(c, request); + + return true; + } else { + sockaddrfree(&local_address); + return true; + } + } else { + sockaddrfree(&local_address); return true; + } } else if(from == myself) { logger(DEBUG_PROTOCOL, LOG_WARNING, "Got %s from %s (%s) for ourself which does not exist", "ADD_EDGE", c->name, c->hostname); @@ -147,6 +198,7 @@ bool add_edge_h(connection_t *c, const char *request) { e->to = to; send_del_edge(c, e); free_edge(e); + sockaddrfree(&local_address); return true; } @@ -159,6 +211,7 @@ bool add_edge_h(connection_t *c, const char *request) { e->weight = weight; edge_add(e); +done: /* Tell the rest about the new edge */ if(!tunnelserver) diff --git a/src/protocol_key.c b/src/protocol_key.c index 8b19d90..d24d4ac 100644 --- a/src/protocol_key.c +++ b/src/protocol_key.c @@ -36,6 +36,7 @@ static bool mykeyused = false; void send_key_changed(void) { +#ifndef DISABLE_LEGACY send_request(everyone, "%d %x %s", KEY_CHANGED, rand(), myself->name); /* Immediately send new keys to directly connected nodes to keep UDP mappings alive */ @@ -43,6 +44,7 @@ void send_key_changed(void) { for list_each(connection_t, c, connection_list) if(c->edge && c->node && c->node->status.reachable && !c->node->status.sptps) send_ans_key(c->node); +#endif /* Force key exchange for connections using SPTPS */ @@ -87,9 +89,13 @@ bool key_changed_h(connection_t *c, const char *request) { return true; } +static bool send_sptps_data_myself(void *handle, uint8_t type, const void *data, size_t len) { + return send_sptps_data(handle, myself, type, data, len); +} + static bool send_initial_sptps_data(void *handle, uint8_t type, const void *data, size_t len) { node_t *to = handle; - to->sptps.send_data = send_sptps_data; + to->sptps.send_data = send_sptps_data_myself; char buf[len * 4 / 3 + 5]; b64encode(data, buf, len); return send_request(to->nexthop->connection, "%d %s %s %d %s", REQ_KEY, myself->name, to->name, REQ_KEY, buf); @@ -103,9 +109,6 @@ bool send_req_key(node_t *to) { return true; } - if(to->sptps.label) - logger(DEBUG_ALWAYS, LOG_DEBUG, "send_req_key(%s) called while sptps->label != NULL!", to->name); - char label[25 + strlen(myself->name) + strlen(to->name)]; snprintf(label, sizeof label, "tinc UDP key expansion %s %s", myself->name, to->name); sptps_stop(&to->sptps); @@ -121,7 +124,52 @@ bool send_req_key(node_t *to) { /* REQ_KEY is overloaded to allow arbitrary requests to be routed between two nodes. */ -static bool req_key_ext_h(connection_t *c, const char *request, node_t *from, int reqno) { +static bool req_key_ext_h(connection_t *c, const char *request, node_t *from, node_t *to, int reqno) { + /* If this is a SPTPS packet, see if sending UDP info helps. + Note that we only do this if we're the destination or the static relay; + otherwise every hop would initiate its own UDP info message, resulting in elevated chatter. */ + if((reqno == REQ_KEY || reqno == SPTPS_PACKET) && to->via == myself) + send_udp_info(myself, from); + + if(reqno == SPTPS_PACKET) { + /* This is a SPTPS data packet. */ + + char buf[MAX_STRING_SIZE]; + int len; + if(sscanf(request, "%*d %*s %*s %*d " MAX_STRING, buf) != 1 || !(len = b64decode(buf, buf, strlen(buf)))) { + logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s) to %s (%s): %s", "SPTPS_PACKET", from->name, from->hostname, to->name, to->hostname, "invalid SPTPS data"); + return true; + } + + if(to != myself) { + /* We don't just forward the request, because we want to use UDP if it's available. */ + send_sptps_data(to, from, 0, buf, len); + try_tx(to, true); + } else { + /* The packet is for us */ + if(!sptps_receive_data(&from->sptps, buf, len)) { + /* Uh-oh. It might be that the tunnel is stuck in some corrupted state, + so let's restart SPTPS in case that helps. But don't do that too often + to prevent storms. */ + if(from->last_req_key < now.tv_sec - 10) { + logger(DEBUG_PROTOCOL, LOG_ERR, "Failed to decode TCP packet from %s (%s), restarting SPTPS", from->name, from->hostname); + send_req_key(from); + } + return true; + } + send_mtu_info(myself, from, MTU); + } + + return true; + } + + /* Requests that are not SPTPS data packets are forwarded as-is. */ + + if (to != myself) + return send_request(to->nexthop->connection, "%s", request); + + /* The request is for us */ + switch(reqno) { case REQ_PUBKEY: { if(!node_read_ecdsa_public_key(from)) { @@ -176,24 +224,9 @@ static bool req_key_ext_h(connection_t *c, const char *request, node_t *from, in from->status.validkey = false; from->status.waitingforkey = true; from->last_req_key = now.tv_sec; - sptps_start(&from->sptps, from, false, true, myself->connection->ecdsa, from->ecdsa, label, sizeof label, send_sptps_data, receive_sptps_record); - sptps_receive_data(&from->sptps, buf, len); - return true; - } - - case REQ_SPTPS: { - if(!from->status.validkey) { - logger(DEBUG_PROTOCOL, LOG_ERR, "Got REQ_SPTPS from %s (%s) but we don't have a valid key yet", from->name, from->hostname); - return true; - } - - char buf[MAX_STRING_SIZE]; - int len; - if(sscanf(request, "%*d %*s %*s %*d " MAX_STRING, buf) != 1 || !(len = b64decode(buf, buf, strlen(buf)))) { - logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s): %s", "REQ_SPTPS", from->name, from->hostname, "invalid SPTPS data"); - return true; - } + sptps_start(&from->sptps, from, false, true, myself->connection->ecdsa, from->ecdsa, label, sizeof label, send_sptps_data_myself, receive_sptps_record); sptps_receive_data(&from->sptps, buf, len); + send_mtu_info(myself, from, MTU); return true; } @@ -241,7 +274,7 @@ bool req_key_h(connection_t *c, const char *request) { if(to == myself) { /* Yes */ /* Is this an extended REQ_KEY message? */ if(experimental && reqno) - return req_key_ext_h(c, request, from, reqno); + return req_key_ext_h(c, request, from, to, reqno); /* No, just send our key back */ send_ans_key(from); @@ -255,7 +288,10 @@ bool req_key_h(connection_t *c, const char *request) { return true; } - /* TODO: forwarding SPTPS packets in this way is inefficient because we send them over TCP without checking for UDP connectivity */ + /* Is this an extended REQ_KEY message? */ + if(experimental && reqno) + return req_key_ext_h(c, request, from, to, reqno); + send_request(to->nexthop->connection, "%s", request); } @@ -266,6 +302,9 @@ bool send_ans_key(node_t *to) { if(to->status.sptps) abort(); +#ifdef DISABLE_LEGACY + return false; +#else size_t keylen = myself->incipher ? cipher_keylength(myself->incipher) : 1; char key[keylen * 2 + 1]; @@ -300,12 +339,15 @@ bool send_ans_key(node_t *to) { to->received = 0; if(replaywin) memset(to->late, 0, replaywin); + to->status.validkey_in = true; + return send_request(to->nexthop->connection, "%d %s %s %s %d %d %d %d", ANS_KEY, myself->name, to->name, key, cipher_get_nid(to->incipher), digest_get_nid(to->indigest), (int)digest_length(to->indigest), to->incompression); +#endif } bool ans_key_h(connection_t *c, const char *request) { @@ -358,7 +400,7 @@ bool ans_key_h(connection_t *c, const char *request) { return true; } - if(!*address && from->address.sa.sa_family != AF_UNSPEC) { + if(!*address && from->address.sa.sa_family != AF_UNSPEC && to->minmtu) { char *address, *port; logger(DEBUG_PROTOCOL, LOG_DEBUG, "Appending reflexive UDP address to ANS_KEY from %s to %s", from->name, to->name); sockaddr2str(&from->address, &address, &port); @@ -371,10 +413,12 @@ bool ans_key_h(connection_t *c, const char *request) { return send_request(to->nexthop->connection, "%s", request); } +#ifndef DISABLE_LEGACY /* Don't use key material until every check has passed. */ cipher_close(from->outcipher); digest_close(from->outdigest); - from->status.validkey = false; +#endif + if (!from->status.sptps) from->status.validkey = false; if(compression < 0 || compression > 11) { logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses bogus compression level!", from->name, from->hostname); @@ -388,9 +432,18 @@ bool ans_key_h(connection_t *c, const char *request) { if(from->status.sptps) { char buf[strlen(key)]; int len = b64decode(key, buf, strlen(key)); - - if(!len || !sptps_receive_data(&from->sptps, buf, len)) - logger(DEBUG_ALWAYS, LOG_ERR, "Error processing SPTPS data from %s (%s)", from->name, from->hostname); + if(!len || !sptps_receive_data(&from->sptps, buf, len)) { + /* Uh-oh. It might be that the tunnel is stuck in some corrupted state, + so let's restart SPTPS in case that helps. But don't do that too often + to prevent storms. + Note that simply relying on handshake timeout is not enough, because + that doesn't apply to key regeneration. */ + if(from->last_req_key < now.tv_sec - 10) { + logger(DEBUG_PROTOCOL, LOG_ERR, "Failed to decode handshake TCP packet from %s (%s), restarting SPTPS", from->name, from->hostname); + send_req_key(from); + } + return true; + } if(from->status.validkey) { if(*address && *port) { @@ -398,16 +451,17 @@ bool ans_key_h(connection_t *c, const char *request) { sockaddr_t sa = str2sockaddr(address, port); update_node_udp(from, &sa); } - - /* Don't send probes if we can't send UDP packets directly to that node. - TODO: the indirect (via) condition can change at any time as edges are added and removed, so this should probably be moved to graph.c. */ - if((from->via == myself || from->via == from) && from->options & OPTION_PMTU_DISCOVERY && !(from->options & OPTION_TCPONLY)) - send_mtu_probe(from); } + send_mtu_info(myself, from, MTU); + return true; } +#ifdef DISABLE_LEGACY + logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses legacy protocol!", from->name, from->hostname); + return false; +#else /* Check and lookup cipher and digest algorithms */ if(cipher) { @@ -458,8 +512,6 @@ bool ans_key_h(connection_t *c, const char *request) { update_node_udp(from, &sa); } - if(from->options & OPTION_PMTU_DISCOVERY && !(from->options & OPTION_TCPONLY)) - send_mtu_probe(from); - return true; +#endif } diff --git a/src/protocol_misc.c b/src/protocol_misc.c index 713dacf..95bd322 100644 --- a/src/protocol_misc.c +++ b/src/protocol_misc.c @@ -28,8 +28,15 @@ #include "netutl.h" #include "protocol.h" #include "utils.h" +#include "xalloc.h" + +#ifndef MIN +#define MIN(x, y) (((x)<(y))?(x):(y)) +#endif int maxoutbufsize = 0; +int mtu_info_interval = 5; +int udp_info_interval = 5; /* Status and error notification routines */ @@ -149,3 +156,229 @@ bool tcppacket_h(connection_t *c, const char *request) { return true; } + +bool send_sptps_tcppacket(connection_t *c, const char* packet, int len) { + /* If there already is a lot of data in the outbuf buffer, discard this packet. + We use a very simple Random Early Drop algorithm. */ + + if(2.0 * c->outbuf.len / (float)maxoutbufsize - 1 > (float)rand()/(float)RAND_MAX) + return true; + + if(!send_request(c, "%d %d", SPTPS_PACKET, len)) + return false; + + send_meta_raw(c, packet, len); + return true; +} + +bool sptps_tcppacket_h(connection_t *c, const char* request) { + short int len; + + if(sscanf(request, "%*d %hd", &len) != 1) { + logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "SPTPS_PACKET", c->name, + c->hostname); + return false; + } + + /* Set sptpslen to len, this will tell receive_meta() that a SPTPS packet is coming. */ + + c->sptpslen = len; + + return true; +} + +/* Transmitting UDP information */ + +bool send_udp_info(node_t *from, node_t *to) { + /* If there's a static relay in the path, there's no point in sending the message + farther than the static relay. */ + to = (to->via == myself) ? to->nexthop : to->via; + + /* Skip cases where sending UDP info messages doesn't make sense. + This is done here in order to avoid repeating the same logic in multiple callsites. */ + + if(to == myself) + return true; + + if(!to->status.reachable) + return true; + + if(from == myself) { + if(to->connection) + return true; + + struct timeval elapsed; + timersub(&now, &to->udp_info_sent, &elapsed); + if(elapsed.tv_sec < udp_info_interval) + return true; + } + + if((myself->options | from->options | to->options) & OPTION_TCPONLY) + return true; + + if((to->nexthop->options >> 24) < 5) + return true; + + char *from_address, *from_port; + /* If we're the originator, the address we use is irrelevant + because the first intermediate node will ignore it. + We use our local address as it somewhat makes sense + and it's simpler than introducing an encoding for "null" addresses anyway. */ + sockaddr2str((from != myself) ? &from->address : &to->nexthop->connection->edge->local_address, &from_address, &from_port); + + bool x = send_request(to->nexthop->connection, "%d %s %s %s %s", UDP_INFO, from->name, to->name, from_address, from_port); + + free(from_address); + free(from_port); + + if(from == myself) + to->udp_info_sent = now; + + return x; +} + +bool udp_info_h(connection_t *c, const char* request) { + char from_name[MAX_STRING_SIZE]; + char to_name[MAX_STRING_SIZE]; + char from_address[MAX_STRING_SIZE]; + char from_port[MAX_STRING_SIZE]; + + if(sscanf(request, "%*d "MAX_STRING" "MAX_STRING" "MAX_STRING" "MAX_STRING, from_name, to_name, from_address, from_port) != 4) { + logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "UDP_INFO", c->name, c->hostname); + return false; + } + + if(!check_id(from_name) || !check_id(to_name)) { + logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s): %s", "UDP_INFO", c->name, c->hostname, "invalid name"); + return false; + } + + node_t *from = lookup_node(from_name); + if(!from) { + logger(DEBUG_ALWAYS, LOG_ERR, "Got %s from %s (%s) origin %s which does not exist in our connection list", "UDP_INFO", c->name, c->hostname, from_name); + return true; + } + + if(from != from->via) { + /* Not supposed to happen, as it means the message wandered past a static relay */ + logger(DEBUG_PROTOCOL, LOG_WARNING, "Got UDP info message from %s (%s) which we can't reach directly", from->name, from->hostname); + return true; + } + + /* If we have a direct edge to "from", we are in a better position + to guess its address than it is itself. */ + if(!from->connection && !from->status.udp_confirmed) { + sockaddr_t from_addr = str2sockaddr(from_address, from_port); + if(sockaddrcmp(&from_addr, &from->address)) + update_node_udp(from, &from_addr); + } + + node_t *to = lookup_node(to_name); + if(!to) { + logger(DEBUG_ALWAYS, LOG_ERR, "Got %s from %s (%s) destination %s which does not exist in our connection list", "UDP_INFO", c->name, c->hostname, to_name); + return true; + } + + /* Send our own data (which could be what we just received) up the chain. */ + + return send_udp_info(from, to); +} + +/* Transmitting MTU information */ + +bool send_mtu_info(node_t *from, node_t *to, int mtu) { + /* Skip cases where sending MTU info messages doesn't make sense. + This is done here in order to avoid repeating the same logic in multiple callsites. */ + + if(to == myself) + return true; + + if(!to->status.reachable) + return true; + + if(from == myself) { + if(to->connection) + return true; + + struct timeval elapsed; + timersub(&now, &to->mtu_info_sent, &elapsed); + if(elapsed.tv_sec < mtu_info_interval) + return true; + } + + if((to->nexthop->options >> 24) < 6) + return true; + + /* We will send the passed-in MTU value, unless we believe ours is better. */ + + node_t *via = (from->via == myself) ? from->nexthop : from->via; + if(from->minmtu == from->maxmtu && from->via == myself) { + /* We have a direct measurement. Override the value entirely. + Note that we only do that if we are sitting as a static relay in the path; + otherwise, we can't guarantee packets will flow through us, and increasing + MTU could therefore end up being too optimistic. */ + mtu = from->minmtu; + } else if(via->minmtu == via->maxmtu) { + /* Static relay. Ensure packets will make it through the entire relay path. */ + mtu = MIN(mtu, via->minmtu); + } else if(via->nexthop->minmtu == via->nexthop->maxmtu) { + /* Dynamic relay. Ensure packets will make it through the entire relay path. */ + mtu = MIN(mtu, via->nexthop->minmtu); + } + + if(from == myself) + to->mtu_info_sent = now; + + /* If none of the conditions above match in the steady state, it means we're using TCP, + so the MTU is irrelevant. That said, it is still important to honor the MTU that was passed in, + because other parts of the relay path might be able to use UDP, which means they care about the MTU. */ + + return send_request(to->nexthop->connection, "%d %s %s %d", MTU_INFO, from->name, to->name, mtu); +} + +bool mtu_info_h(connection_t *c, const char* request) { + char from_name[MAX_STRING_SIZE]; + char to_name[MAX_STRING_SIZE]; + int mtu; + + if(sscanf(request, "%*d "MAX_STRING" "MAX_STRING" %d", from_name, to_name, &mtu) != 3) { + logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "MTU_INFO", c->name, c->hostname); + return false; + } + + if(mtu < 512) { + logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s): %s", "MTU_INFO", c->name, c->hostname, "invalid MTU"); + return false; + } + + mtu = MIN(mtu, MTU); + + if(!check_id(from_name) || !check_id(to_name)) { + logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s): %s", "MTU_INFO", c->name, c->hostname, "invalid name"); + return false; + } + + node_t *from = lookup_node(from_name); + if(!from) { + logger(DEBUG_ALWAYS, LOG_ERR, "Got %s from %s (%s) origin %s which does not exist in our connection list", "MTU_INFO", c->name, c->hostname, from_name); + return true; + } + + /* If we don't know the current MTU for that node, use the one we received. + Even if we're about to make our own measurements, the value we got from downstream nodes should be pretty close + so it's a good idea to use it in the mean time. */ + if(from->mtu != mtu && from->minmtu != from->maxmtu) { + logger(DEBUG_TRAFFIC, LOG_INFO, "Using provisional MTU %d for node %s (%s)", mtu, from->name, from->hostname); + from->mtu = mtu; + } + + node_t *to = lookup_node(to_name); + if(!to) { + logger(DEBUG_ALWAYS, LOG_ERR, "Got %s from %s (%s) destination %s which does not exist in our connection list", "MTU_INFO", c->name, c->hostname, to_name); + return true; + } + + /* Continue passing the MTU value (or a better one if we have it) up the chain. */ + + return send_mtu_info(from, to, mtu); +} diff --git a/src/route.c b/src/route.c index 2785146..0c9f2aa 100644 --- a/src/route.c +++ b/src/route.c @@ -105,6 +105,260 @@ static bool checklength(node_t *source, vpn_packet_t *packet, length_t length) { return true; } +static void swap_mac_addresses(vpn_packet_t *packet) { + mac_t tmp; + memcpy(&tmp, &DATA(packet)[0], sizeof tmp); + memcpy(&DATA(packet)[0], &DATA(packet)[6], sizeof tmp); + memcpy(&DATA(packet)[6], &tmp, sizeof tmp); +} + +/* RFC 792 */ + +static void route_ipv4_unreachable(node_t *source, vpn_packet_t *packet, length_t ether_size, uint8_t type, uint8_t code) { + struct ip ip = {0}; + struct icmp icmp = {0}; + + struct in_addr ip_src; + struct in_addr ip_dst; + uint32_t oldlen; + + if(ratelimit(3)) + return; + + /* Swap Ethernet source and destination addresses */ + + swap_mac_addresses(packet); + + /* Copy headers from packet into properly aligned structs on the stack */ + + memcpy(&ip, DATA(packet) + ether_size, ip_size); + + /* Remember original source and destination */ + + ip_src = ip.ip_src; + ip_dst = ip.ip_dst; + + /* Try to reply with an IP address assigned to the local machine */ + + if (type == ICMP_TIME_EXCEEDED && code == ICMP_EXC_TTL) { + int sockfd = socket(AF_INET, SOCK_DGRAM, 0); + if (sockfd != -1) { + struct sockaddr_in addr; + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_addr = ip.ip_src; + if (!connect(sockfd, (const struct sockaddr*) &addr, sizeof(addr))) { + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + socklen_t addrlen = sizeof(addr); + if (!getsockname(sockfd, (struct sockaddr*) &addr, &addrlen) && addrlen <= sizeof(addr)) { + ip_dst = addr.sin_addr; + } + } + close(sockfd); + } + } + + oldlen = packet->len - ether_size; + + if(type == ICMP_DEST_UNREACH && code == ICMP_FRAG_NEEDED) + icmp.icmp_nextmtu = htons(packet->len - ether_size); + + if(oldlen >= IP_MSS - ip_size - icmp_size) + oldlen = IP_MSS - ip_size - icmp_size; + + /* Copy first part of original contents to ICMP message */ + + memmove(DATA(packet) + ether_size + ip_size + icmp_size, DATA(packet) + ether_size, oldlen); + + /* Fill in IPv4 header */ + + ip.ip_v = 4; + ip.ip_hl = ip_size / 4; + ip.ip_tos = 0; + ip.ip_len = htons(ip_size + icmp_size + oldlen); + ip.ip_id = 0; + ip.ip_off = 0; + ip.ip_ttl = 255; + ip.ip_p = IPPROTO_ICMP; + ip.ip_sum = 0; + ip.ip_src = ip_dst; + ip.ip_dst = ip_src; + + ip.ip_sum = inet_checksum(&ip, ip_size, ~0); + + /* Fill in ICMP header */ + + icmp.icmp_type = type; + icmp.icmp_code = code; + icmp.icmp_cksum = 0; + + icmp.icmp_cksum = inet_checksum(&icmp, icmp_size, ~0); + icmp.icmp_cksum = inet_checksum(DATA(packet) + ether_size + ip_size + icmp_size, oldlen, icmp.icmp_cksum); + + /* Copy structs on stack back to packet */ + + memcpy(DATA(packet) + ether_size, &ip, ip_size); + memcpy(DATA(packet) + ether_size + ip_size, &icmp, icmp_size); + + packet->len = ether_size + ip_size + icmp_size + oldlen; + + send_packet(source, packet); +} + +/* RFC 2463 */ + +static void route_ipv6_unreachable(node_t *source, vpn_packet_t *packet, length_t ether_size, uint8_t type, uint8_t code) { + struct ip6_hdr ip6; + struct icmp6_hdr icmp6 = {0}; + uint16_t checksum; + + struct { + struct in6_addr ip6_src; /* source address */ + struct in6_addr ip6_dst; /* destination address */ + uint32_t length; + uint32_t next; + } pseudo; + + if(ratelimit(3)) + return; + + /* Swap Ethernet source and destination addresses */ + + swap_mac_addresses(packet); + + /* Copy headers from packet to structs on the stack */ + + memcpy(&ip6, DATA(packet) + ether_size, ip6_size); + + /* Remember original source and destination */ + + pseudo.ip6_src = ip6.ip6_dst; + pseudo.ip6_dst = ip6.ip6_src; + + /* Try to reply with an IP address assigned to the local machine */ + + if (type == ICMP6_TIME_EXCEEDED && code == ICMP6_TIME_EXCEED_TRANSIT) { + int sockfd = socket(AF_INET6, SOCK_DGRAM, 0); + if (sockfd != -1) { + struct sockaddr_in6 addr; + memset(&addr, 0, sizeof(addr)); + addr.sin6_family = AF_INET6; + addr.sin6_addr = ip6.ip6_src; + if (!connect(sockfd, (const struct sockaddr*) &addr, sizeof(addr))) { + memset(&addr, 0, sizeof(addr)); + addr.sin6_family = AF_INET6; + socklen_t addrlen = sizeof(addr); + if (!getsockname(sockfd, (struct sockaddr*) &addr, &addrlen) && addrlen <= sizeof(addr)) { + pseudo.ip6_src = addr.sin6_addr; + } + } + close(sockfd); + } + } + + pseudo.length = packet->len - ether_size; + + if(type == ICMP6_PACKET_TOO_BIG) + icmp6.icmp6_mtu = htonl(pseudo.length); + + if(pseudo.length >= IP_MSS - ip6_size - icmp6_size) + pseudo.length = IP_MSS - ip6_size - icmp6_size; + + /* Copy first part of original contents to ICMP message */ + + memmove(DATA(packet) + ether_size + ip6_size + icmp6_size, DATA(packet) + ether_size, pseudo.length); + + /* Fill in IPv6 header */ + + ip6.ip6_flow = htonl(0x60000000UL); + ip6.ip6_plen = htons(icmp6_size + pseudo.length); + ip6.ip6_nxt = IPPROTO_ICMPV6; + ip6.ip6_hlim = 255; + ip6.ip6_src = pseudo.ip6_src; + ip6.ip6_dst = pseudo.ip6_dst; + + /* Fill in ICMP header */ + + icmp6.icmp6_type = type; + icmp6.icmp6_code = code; + icmp6.icmp6_cksum = 0; + + /* Create pseudo header */ + + pseudo.length = htonl(icmp6_size + pseudo.length); + pseudo.next = htonl(IPPROTO_ICMPV6); + + /* Generate checksum */ + + checksum = inet_checksum(&pseudo, sizeof pseudo, ~0); + checksum = inet_checksum(&icmp6, icmp6_size, checksum); + checksum = inet_checksum(DATA(packet) + ether_size + ip6_size + icmp6_size, ntohl(pseudo.length) - icmp6_size, checksum); + + icmp6.icmp6_cksum = checksum; + + /* Copy structs on stack back to packet */ + + memcpy(DATA(packet) + ether_size, &ip6, ip6_size); + memcpy(DATA(packet) + ether_size + ip6_size, &icmp6, icmp6_size); + + packet->len = ether_size + ip6_size + ntohl(pseudo.length); + + send_packet(source, packet); +} + +static bool do_decrement_ttl(node_t *source, vpn_packet_t *packet) { + uint16_t type = DATA(packet)[12] << 8 | DATA(packet)[13]; + length_t ethlen = ether_size; + + if(type == ETH_P_8021Q) { + type = DATA(packet)[16] << 8 | DATA(packet)[17]; + ethlen += 4; + } + + switch (type) { + case ETH_P_IP: + if(!checklength(source, packet, ethlen + ip_size)) + return false; + + if(DATA(packet)[ethlen + 8] <= 1) { + if(DATA(packet)[ethlen + 11] != IPPROTO_ICMP || DATA(packet)[ethlen + 32] != ICMP_TIME_EXCEEDED) + route_ipv4_unreachable(source, packet, ethlen, ICMP_TIME_EXCEEDED, ICMP_EXC_TTL); + return false; + } + + uint16_t old = DATA(packet)[ethlen + 8] << 8 | DATA(packet)[ethlen + 9]; + DATA(packet)[ethlen + 8]--; + uint16_t new = DATA(packet)[ethlen + 8] << 8 | DATA(packet)[ethlen + 9]; + + uint32_t checksum = DATA(packet)[ethlen + 10] << 8 | DATA(packet)[ethlen + 11]; + checksum += old + (~new & 0xFFFF); + while(checksum >> 16) + checksum = (checksum & 0xFFFF) + (checksum >> 16); + DATA(packet)[ethlen + 10] = checksum >> 8; + DATA(packet)[ethlen + 11] = checksum & 0xff; + + return true; + + case ETH_P_IPV6: + if(!checklength(source, packet, ethlen + ip6_size)) + return false; + + if(DATA(packet)[ethlen + 7] <= 1) { + if(DATA(packet)[ethlen + 6] != IPPROTO_ICMPV6 || DATA(packet)[ethlen + 40] != ICMP6_TIME_EXCEEDED) + route_ipv6_unreachable(source, packet, ethlen, ICMP6_TIME_EXCEEDED, ICMP6_TIME_EXCEED_TRANSIT); + return false; + } + + DATA(packet)[ethlen + 7]--; + + return true; + + default: + return true; + } +} + static void clamp_mss(const node_t *source, const node_t *via, vpn_packet_t *packet) { if(!source || !via || !(via->options & OPTION_CLAMP_MSS)) return; @@ -164,7 +418,7 @@ static void clamp_mss(const node_t *source, const node_t *via, vpn_packet_t *pac /* Found it */ uint16_t oldmss = DATA(packet)[start + 22 + i] << 8 | DATA(packet)[start + 23 + i]; uint16_t newmss = mtu - start - 20; - uint16_t csum = DATA(packet)[start + 16] << 8 | DATA(packet)[start + 17]; + uint32_t csum = DATA(packet)[start + 16] << 8 | DATA(packet)[start + 17]; if(oldmss <= newmss) break; @@ -175,22 +429,17 @@ static void clamp_mss(const node_t *source, const node_t *via, vpn_packet_t *pac DATA(packet)[start + 22 + i] = newmss >> 8; DATA(packet)[start + 23 + i] = newmss & 0xff; csum ^= 0xffff; - csum -= oldmss; + csum += oldmss ^ 0xffff; csum += newmss; + csum = (csum & 0xffff) + (csum >> 16); + csum += csum >> 16; csum ^= 0xffff; DATA(packet)[start + 16] = csum >> 8; - DATA(packet)[start + 17] = csum & 0xff; + DATA(packet)[start + 17] = csum; break; } } -static void swap_mac_addresses(vpn_packet_t *packet) { - mac_t tmp; - memcpy(&tmp, &DATA(packet)[0], sizeof tmp); - memcpy(&DATA(packet)[0], &DATA(packet)[6], sizeof tmp); - memcpy(&DATA(packet)[6], &tmp, sizeof tmp); -} - static void age_subnets(void *data) { bool left = false; @@ -248,77 +497,12 @@ static void learn_mac(mac_t *address) { } } -/* RFC 792 */ +static void route_broadcast(node_t *source, vpn_packet_t *packet) { + if(decrement_ttl && source != myself) + if(!do_decrement_ttl(source, packet)) + return; -static void route_ipv4_unreachable(node_t *source, vpn_packet_t *packet, length_t ether_size, uint8_t type, uint8_t code) { - struct ip ip = {0}; - struct icmp icmp = {0}; - - struct in_addr ip_src; - struct in_addr ip_dst; - uint32_t oldlen; - - if(ratelimit(3)) - return; - - /* Swap Ethernet source and destination addresses */ - - swap_mac_addresses(packet); - - /* Copy headers from packet into properly aligned structs on the stack */ - - memcpy(&ip, DATA(packet) + ether_size, ip_size); - - /* Remember original source and destination */ - - ip_src = ip.ip_src; - ip_dst = ip.ip_dst; - - oldlen = packet->len - ether_size; - - if(type == ICMP_DEST_UNREACH && code == ICMP_FRAG_NEEDED) - icmp.icmp_nextmtu = htons(packet->len - ether_size); - - if(oldlen >= IP_MSS - ip_size - icmp_size) - oldlen = IP_MSS - ip_size - icmp_size; - - /* Copy first part of original contents to ICMP message */ - - memmove(DATA(packet) + ether_size + ip_size + icmp_size, DATA(packet) + ether_size, oldlen); - - /* Fill in IPv4 header */ - - ip.ip_v = 4; - ip.ip_hl = ip_size / 4; - ip.ip_tos = 0; - ip.ip_len = htons(ip_size + icmp_size + oldlen); - ip.ip_id = 0; - ip.ip_off = 0; - ip.ip_ttl = 255; - ip.ip_p = IPPROTO_ICMP; - ip.ip_sum = 0; - ip.ip_src = ip_dst; - ip.ip_dst = ip_src; - - ip.ip_sum = inet_checksum(&ip, ip_size, ~0); - - /* Fill in ICMP header */ - - icmp.icmp_type = type; - icmp.icmp_code = code; - icmp.icmp_cksum = 0; - - icmp.icmp_cksum = inet_checksum(&icmp, icmp_size, ~0); - icmp.icmp_cksum = inet_checksum(DATA(packet) + ether_size + ip_size + icmp_size, oldlen, icmp.icmp_cksum); - - /* Copy structs on stack back to packet */ - - memcpy(DATA(packet) + ether_size, &ip, ip_size); - memcpy(DATA(packet) + ether_size + ip_size, &icmp, icmp_size); - - packet->len = ether_size + ip_size + icmp_size + oldlen; - - send_packet(source, packet); + broadcast_packet(source, packet); } /* RFC 791 */ @@ -396,7 +580,7 @@ static void route_ipv4(node_t *source, vpn_packet_t *packet) { } if (!subnet->owner) { - broadcast_packet(source, packet); + route_broadcast(source, packet); return; } @@ -411,6 +595,10 @@ static void route_ipv4(node_t *source, vpn_packet_t *packet) { if(forwarding_mode == FMODE_OFF && source != myself && subnet->owner != myself) return route_ipv4_unreachable(source, packet, ether_size, ICMP_DEST_UNREACH, ICMP_NET_ANO); + if(decrement_ttl && source != myself && subnet->owner != myself) + if(!do_decrement_ttl(source, packet)) + return; + if(priorityinheritance) packet->priority = DATA(packet)[15]; @@ -441,86 +629,6 @@ static void route_ipv4(node_t *source, vpn_packet_t *packet) { send_packet(subnet->owner, packet); } -/* RFC 2463 */ - -static void route_ipv6_unreachable(node_t *source, vpn_packet_t *packet, length_t ether_size, uint8_t type, uint8_t code) { - struct ip6_hdr ip6; - struct icmp6_hdr icmp6 = {0}; - uint16_t checksum; - - struct { - struct in6_addr ip6_src; /* source address */ - struct in6_addr ip6_dst; /* destination address */ - uint32_t length; - uint32_t next; - } pseudo; - - if(ratelimit(3)) - return; - - /* Swap Ethernet source and destination addresses */ - - swap_mac_addresses(packet); - - /* Copy headers from packet to structs on the stack */ - - memcpy(&ip6, DATA(packet) + ether_size, ip6_size); - - /* Remember original source and destination */ - - pseudo.ip6_src = ip6.ip6_dst; - pseudo.ip6_dst = ip6.ip6_src; - - pseudo.length = packet->len - ether_size; - - if(type == ICMP6_PACKET_TOO_BIG) - icmp6.icmp6_mtu = htonl(pseudo.length); - - if(pseudo.length >= IP_MSS - ip6_size - icmp6_size) - pseudo.length = IP_MSS - ip6_size - icmp6_size; - - /* Copy first part of original contents to ICMP message */ - - memmove(DATA(packet) + ether_size + ip6_size + icmp6_size, DATA(packet) + ether_size, pseudo.length); - - /* Fill in IPv6 header */ - - ip6.ip6_flow = htonl(0x60000000UL); - ip6.ip6_plen = htons(icmp6_size + pseudo.length); - ip6.ip6_nxt = IPPROTO_ICMPV6; - ip6.ip6_hlim = 255; - ip6.ip6_src = pseudo.ip6_src; - ip6.ip6_dst = pseudo.ip6_dst; - - /* Fill in ICMP header */ - - icmp6.icmp6_type = type; - icmp6.icmp6_code = code; - icmp6.icmp6_cksum = 0; - - /* Create pseudo header */ - - pseudo.length = htonl(icmp6_size + pseudo.length); - pseudo.next = htonl(IPPROTO_ICMPV6); - - /* Generate checksum */ - - checksum = inet_checksum(&pseudo, sizeof pseudo, ~0); - checksum = inet_checksum(&icmp6, icmp6_size, checksum); - checksum = inet_checksum(DATA(packet) + ether_size + ip6_size + icmp6_size, ntohl(pseudo.length) - icmp6_size, checksum); - - icmp6.icmp6_cksum = checksum; - - /* Copy structs on stack back to packet */ - - memcpy(DATA(packet) + ether_size, &ip6, ip6_size); - memcpy(DATA(packet) + ether_size + ip6_size, &icmp6, icmp6_size); - - packet->len = ether_size + ip6_size + ntohl(pseudo.length); - - send_packet(source, packet); -} - static void route_neighborsol(node_t *source, vpn_packet_t *packet); static void route_ipv6(node_t *source, vpn_packet_t *packet) { @@ -556,7 +664,7 @@ static void route_ipv6(node_t *source, vpn_packet_t *packet) { } if (!subnet->owner) { - broadcast_packet(source, packet); + route_broadcast(source, packet); return; } @@ -571,6 +679,10 @@ static void route_ipv6(node_t *source, vpn_packet_t *packet) { if(forwarding_mode == FMODE_OFF && source != myself && subnet->owner != myself) return route_ipv6_unreachable(source, packet, ether_size, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_ADMIN); + if(decrement_ttl && source != myself && subnet->owner != myself) + if(!do_decrement_ttl(source, packet)) + return; + via = (subnet->owner->via == myself) ? subnet->owner->nexthop : subnet->owner->via; if(via == source) { @@ -687,6 +799,10 @@ static void route_neighborsol(node_t *source, vpn_packet_t *packet) { if(subnet->owner == myself) return; /* silently ignore */ + if(decrement_ttl) + if(!do_decrement_ttl(source, packet)) + return; + /* Create neighbor advertation reply */ memcpy(DATA(packet), DATA(packet) + ETH_ALEN, ETH_ALEN); /* copy destination address */ @@ -782,15 +898,17 @@ static void route_arp(node_t *source, vpn_packet_t *packet) { if(subnet->owner == myself) return; /* silently ignore */ - memcpy(DATA(packet), DATA(packet) + ETH_ALEN, ETH_ALEN); /* copy destination address */ - DATA(packet)[ETH_ALEN * 2 - 1] ^= 0xFF; /* mangle source address so it looks like it's not from us */ + if(decrement_ttl) + if(!do_decrement_ttl(source, packet)) + return; memcpy(&addr, arp.arp_tpa, sizeof addr); /* save protocol addr */ memcpy(arp.arp_tpa, arp.arp_spa, sizeof addr); /* swap destination and source protocol address */ memcpy(arp.arp_spa, &addr, sizeof addr); /* ... */ memcpy(arp.arp_tha, arp.arp_sha, ETH_ALEN); /* set target hard/proto addr */ - memcpy(arp.arp_sha, DATA(packet) + ETH_ALEN, ETH_ALEN); /* add fake source hard addr */ + memcpy(arp.arp_sha, DATA(packet) + ETH_ALEN, ETH_ALEN); /* set source hard/proto addr */ + arp.arp_sha[ETH_ALEN - 1] ^= 0xFF; /* for consistency with route_packet() */ arp.arp_op = htons(ARPOP_REPLY); /* Copy structs on stack back to packet */ @@ -818,7 +936,7 @@ static void route_mac(node_t *source, vpn_packet_t *packet) { subnet = lookup_subnet_mac(NULL, &dest); if(!subnet || !subnet->owner) { - broadcast_packet(source, packet); + route_broadcast(source, packet); return; } @@ -830,6 +948,10 @@ static void route_mac(node_t *source, vpn_packet_t *packet) { if(forwarding_mode == FMODE_OFF && source != myself && subnet->owner != myself) return; + if(decrement_ttl && source != myself && subnet->owner != myself) + if(!do_decrement_ttl(source, packet)) + return; + uint16_t type = DATA(packet)[12] << 8 | DATA(packet)[13]; if(priorityinheritance && type == ETH_P_IP && packet->len >= ether_size + ip_size) @@ -888,58 +1010,6 @@ static void send_pcap(vpn_packet_t *packet) { } } -static bool do_decrement_ttl(node_t *source, vpn_packet_t *packet) { - uint16_t type = DATA(packet)[12] << 8 | DATA(packet)[13]; - length_t ethlen = ether_size; - - if(type == ETH_P_8021Q) { - type = DATA(packet)[16] << 8 | DATA(packet)[17]; - ethlen += 4; - } - - switch (type) { - case ETH_P_IP: - if(!checklength(source, packet, ethlen + ip_size)) - return false; - - if(DATA(packet)[ethlen + 8] < 1) { - if(DATA(packet)[ethlen + 11] != IPPROTO_ICMP || DATA(packet)[ethlen + 32] != ICMP_TIME_EXCEEDED) - route_ipv4_unreachable(source, packet, ethlen, ICMP_TIME_EXCEEDED, ICMP_EXC_TTL); - return false; - } - - uint16_t old = DATA(packet)[ethlen + 8] << 8 | DATA(packet)[ethlen + 9]; - DATA(packet)[ethlen + 8]--; - uint16_t new = DATA(packet)[ethlen + 8] << 8 | DATA(packet)[ethlen + 9]; - - uint32_t checksum = DATA(packet)[ethlen + 10] << 8 | DATA(packet)[ethlen + 11]; - checksum += old + (~new & 0xFFFF); - while(checksum >> 16) - checksum = (checksum & 0xFFFF) + (checksum >> 16); - DATA(packet)[ethlen + 10] = checksum >> 8; - DATA(packet)[ethlen + 11] = checksum & 0xff; - - return true; - - case ETH_P_IPV6: - if(!checklength(source, packet, ethlen + ip6_size)) - return false; - - if(DATA(packet)[ethlen + 7] < 1) { - if(DATA(packet)[ethlen + 6] != IPPROTO_ICMPV6 || DATA(packet)[ethlen + 40] != ICMP6_TIME_EXCEEDED) - route_ipv6_unreachable(source, packet, ethlen, ICMP6_TIME_EXCEEDED, ICMP6_TIME_EXCEED_TRANSIT); - return false; - } - - DATA(packet)[ethlen + 7]--; - - return true; - - default: - return true; - } -} - void route(node_t *source, vpn_packet_t *packet) { if(pcap) send_pcap(packet); @@ -952,10 +1022,6 @@ void route(node_t *source, vpn_packet_t *packet) { if(!checklength(source, packet, ether_size)) return; - if(decrement_ttl && source != myself) - if(!do_decrement_ttl(source, packet)) - return; - uint16_t type = DATA(packet)[12] << 8 | DATA(packet)[13]; switch (routing_mode) { @@ -984,7 +1050,7 @@ void route(node_t *source, vpn_packet_t *packet) { break; case RMODE_HUB: - broadcast_packet(source, packet); + route_broadcast(source, packet); break; } } diff --git a/src/script.c b/src/script.c index 6389cb4..d4db889 100644 --- a/src/script.c +++ b/src/script.c @@ -1,7 +1,7 @@ /* script.c -- call an external script Copyright (C) 1999-2005 Ivo Timmermans, - 2000-2013 Guus Sliepen + 2000-2015 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 @@ -26,21 +26,59 @@ #include "script.h" #include "xalloc.h" +#ifdef HAVE_PUTENV +static void unputenv(const char *p) { + const char *e = strchr(p, '='); + if(!e) + return; + int len = e - p; +#ifndef HAVE_UNSETENV +#ifdef HAVE_MINGW + // Windows requires putenv("FOO=") to unset %FOO% + len++; +#endif +#endif + char var[len + 1]; + strncpy(var, p, len); + var[len] = 0; +#ifdef HAVE_UNSETENV + unsetenv(var); +#else + // We must keep what we putenv() around in memory. + // To do this without memory leaks, keep things in a list and reuse if possible. + static list_t list = {}; + for list_each(char, data, &list) { + if(!strcmp(data, var)) { + putenv(data); + return; + } + } + char *data = xstrdup(var); + list_insert_tail(&list, data); + putenv(data); +#endif +} +#else +static void putenv(const char *p) {} +static void unputenv(const char *p) {} +#endif + bool execute_script(const char *name, char **envp) { -#ifdef HAVE_SYSTEM - char *scriptname; + char scriptname[PATH_MAX]; char *command; - xasprintf(&scriptname, "%s" SLASH "%s%s", confbase, name, scriptextension); + snprintf(scriptname, sizeof scriptname, "%s" SLASH "%s%s", confbase, name, scriptextension); /* First check if there is a script */ #ifdef HAVE_MINGW if(!*scriptextension) { const char *pathext = getenv("PATHEXT") ?: ".COM;.EXE;.BAT;.CMD"; - char fullname[strlen(scriptname) + strlen(pathext)]; - char *ext = fullname + strlen(scriptname); - strcpy(fullname, scriptname); + size_t pathlen = strlen(pathext); + size_t scriptlen = strlen(scriptname); + char fullname[scriptlen + pathlen + 1]; + char *ext = fullname + scriptlen; + strncpy(fullname, scriptname, sizeof fullname); const char *p = pathext; bool found = false; @@ -51,32 +89,26 @@ bool execute_script(const char *name, char **envp) { ext[q - p] = 0; q++; } else { - strcpy(ext, p); + strncpy(ext, p, pathlen + 1); } if((found = !access(fullname, F_OK))) break; p = q; } - if(!found) { - free(scriptname); + if(!found) return true; - } } else #endif - if(access(scriptname, F_OK)) { - free(scriptname); + if(access(scriptname, F_OK)) return true; - } logger(DEBUG_STATUS, LOG_INFO, "Executing script %s", name); -#ifdef HAVE_PUTENV /* Set environment */ for(int i = 0; envp[i]; i++) putenv(envp[i]); -#endif if(scriptinterpreter) xasprintf(&command, "%s \"%s\"", scriptinterpreter, scriptname); @@ -86,19 +118,11 @@ bool execute_script(const char *name, char **envp) { int status = system(command); free(command); - free(scriptname); /* Unset environment */ - for(int i = 0; envp[i]; i++) { - char *e = strchr(envp[i], '='); - if(e) { - char p[e - envp[i] + 1]; - strncpy(p, envp[i], e - envp[i]); - p[e - envp[i]] = '\0'; - putenv(p); - } - } + for(int i = 0; envp[i]; i++) + unputenv(envp[i]); if(status != -1) { #ifdef WEXITSTATUS @@ -121,6 +145,6 @@ bool execute_script(const char *name, char **envp) { logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "system", strerror(errno)); return false; } -#endif + return true; } diff --git a/src/splay_tree.h b/src/splay_tree.h index 5848870..3ddf217 100644 --- a/src/splay_tree.h +++ b/src/splay_tree.h @@ -106,6 +106,12 @@ extern splay_node_t *splay_search_closest_greater_node(splay_tree_t *, const voi extern void splay_foreach(const splay_tree_t *, splay_action_t); extern void splay_foreach_node(const splay_tree_t *, splay_action_t); +/* + Iterates over a tree. + + CAUTION: while this construct supports deleting the current item, + it does *not* support deleting *other* nodes while iterating on the tree. + */ #define splay_each(type, item, tree) (type *item = (type *)1; item; item = NULL) for(splay_node_t *node = (tree)->head, *next; item = node ? node->data : NULL, next = node ? node->next : NULL, node; node = next) #endif diff --git a/src/sptps.c b/src/sptps.c index a598768..712d50e 100644 --- a/src/sptps.c +++ b/src/sptps.c @@ -1,6 +1,6 @@ /* sptps.c -- Simple Peer-to-Peer Security - Copyright (C) 2011-2014 Guus Sliepen , + Copyright (C) 2011-2015 Guus Sliepen , 2010 Brandon L. Black This program is free software; you can redistribute it and/or modify @@ -204,7 +204,7 @@ static bool generate_key_material(sptps_t *s, const char *shared, size_t len) { // Create the HMAC seed, which is "key expansion" + session label + server nonce + client nonce char seed[s->labellen + 64 + 13]; - strcpy(seed, "key expansion"); + memcpy(seed, "key expansion", 13); if(s->initiator) { memcpy(seed + 13, s->mykex + 1, 32); memcpy(seed + 45, s->hiskex + 1, 32); @@ -384,10 +384,11 @@ static bool sptps_check_seqno(sptps_t *s, uint32_t seqno, bool update_state) { if (update_state) s->farfuture++; if(farfuture) - return error(s, EIO, "Packet is %d seqs in the future, dropped (%u)\n", seqno - s->inseqno, s->farfuture); + return update_state ? error(s, EIO, "Packet is %d seqs in the future, dropped (%u)\n", seqno - s->inseqno, s->farfuture) : false; // Unless we have seen lots of them, in which case we consider the others lost. - warning(s, "Lost %d packets\n", seqno - s->inseqno); + if(update_state) + warning(s, "Lost %d packets\n", seqno - s->inseqno); if (update_state) { // Mark all packets in the replay window as being late. memset(s->late, 255, s->replaywin); @@ -395,7 +396,7 @@ static bool sptps_check_seqno(sptps_t *s, uint32_t seqno, bool update_state) { } else if (seqno < s->inseqno) { // If the sequence number is farther in the past than the bitmap goes, or if the packet was already received, drop it. if((s->inseqno >= s->replaywin * 8 && seqno < s->inseqno - s->replaywin * 8) || !(s->late[(seqno / 8) % s->replaywin] & (1 << seqno % 8))) - return error(s, EIO, "Received late or replayed packet, seqno %d, last received %d\n", seqno, s->inseqno); + return update_state ? error(s, EIO, "Received late or replayed packet, seqno %d, last received %d\n", seqno, s->inseqno) : false; } else if (update_state) { // We missed some packets. Mark them in the bitmap as being late. for(int i = s->inseqno; i < seqno; i++) @@ -447,6 +448,7 @@ static bool sptps_receive_data_datagram(sptps_t *s, const char *data, size_t len uint32_t seqno; memcpy(&seqno, data, 4); seqno = ntohl(seqno); + data += 4; len -= 4; if(!s->instate) { if(seqno != s->inseqno) @@ -454,39 +456,40 @@ static bool sptps_receive_data_datagram(sptps_t *s, const char *data, size_t len s->inseqno = seqno + 1; - uint8_t type = data[4]; + uint8_t type = *(data++); len--; if(type != SPTPS_HANDSHAKE) return error(s, EIO, "Application record received before handshake finished"); - return receive_handshake(s, data + 5, len - 5); + return receive_handshake(s, data, len); } // Decrypt char buffer[len]; - size_t outlen; - - if(!chacha_poly1305_decrypt(s->incipher, seqno, data + 4, len - 4, buffer, &outlen)) + if(!chacha_poly1305_decrypt(s->incipher, seqno, data, len, buffer, &outlen)) return error(s, EIO, "Failed to decrypt and verify packet"); if(!sptps_check_seqno(s, seqno, true)) return false; // Append a NULL byte for safety. - buffer[len - 20] = 0; + buffer[outlen] = 0; - uint8_t type = buffer[0]; + data = buffer; + len = outlen; + + uint8_t type = *(data++); len--; if(type < SPTPS_HANDSHAKE) { if(!s->instate) return error(s, EIO, "Application record received before handshake finished"); - if(!s->receive_record(s->handle, type, buffer + 1, len - 21)) - abort(); + if(!s->receive_record(s->handle, type, data, len)) + return false; } else if(type == SPTPS_HANDSHAKE) { - if(!receive_handshake(s, buffer + 1, len - 21)) - abort(); + if(!receive_handshake(s, data, len)) + return false; } else { return error(s, EIO, "Invalid record type %d", type); } @@ -495,90 +498,92 @@ static bool sptps_receive_data_datagram(sptps_t *s, const char *data, size_t len } // Receive incoming data. Check if it contains a complete record, if so, handle it. -bool sptps_receive_data(sptps_t *s, const void *data, size_t len) { +size_t sptps_receive_data(sptps_t *s, const void *data, size_t len) { + size_t total_read = 0; + if(!s->state) return error(s, EIO, "Invalid session state zero"); if(s->datagram) - return sptps_receive_data_datagram(s, data, len); + return sptps_receive_data_datagram(s, data, len) ? len : false; - while(len) { - // First read the 2 length bytes. - if(s->buflen < 2) { - size_t toread = 2 - s->buflen; - if(toread > len) - toread = len; - - memcpy(s->inbuf + s->buflen, data, toread); - - s->buflen += toread; - len -= toread; - data += toread; - - // Exit early if we don't have the full length. - if(s->buflen < 2) - return true; - - // Get the length bytes - - memcpy(&s->reclen, s->inbuf, 2); - s->reclen = ntohs(s->reclen); - - // If we have the length bytes, ensure our buffer can hold the whole request. - s->inbuf = realloc(s->inbuf, s->reclen + 19UL); - if(!s->inbuf) - return error(s, errno, strerror(errno)); - - // Exit early if we have no more data to process. - if(!len) - return true; - } - - // Read up to the end of the record. - size_t toread = s->reclen + (s->instate ? 19UL : 3UL) - s->buflen; + // First read the 2 length bytes. + if(s->buflen < 2) { + size_t toread = 2 - s->buflen; if(toread > len) toread = len; memcpy(s->inbuf + s->buflen, data, toread); + + total_read += toread; s->buflen += toread; len -= toread; data += toread; - // If we don't have a whole record, exit. - if(s->buflen < s->reclen + (s->instate ? 19UL : 3UL)) - return true; + // Exit early if we don't have the full length. + if(s->buflen < 2) + return total_read; - // Update sequence number. + // Get the length bytes - uint32_t seqno = s->inseqno++; + memcpy(&s->reclen, s->inbuf, 2); + s->reclen = ntohs(s->reclen); - // Check HMAC and decrypt. - if(s->instate) { - if(!chacha_poly1305_decrypt(s->incipher, seqno, s->inbuf + 2UL, s->reclen + 17UL, s->inbuf + 2UL, NULL)) - return error(s, EINVAL, "Failed to decrypt and verify record"); - } + // If we have the length bytes, ensure our buffer can hold the whole request. + s->inbuf = realloc(s->inbuf, s->reclen + 19UL); + if(!s->inbuf) + return error(s, errno, strerror(errno)); - // Append a NULL byte for safety. - s->inbuf[s->reclen + 3UL] = 0; - - uint8_t type = s->inbuf[2]; - - if(type < SPTPS_HANDSHAKE) { - if(!s->instate) - return error(s, EIO, "Application record received before handshake finished"); - if(!s->receive_record(s->handle, type, s->inbuf + 3, s->reclen)) - return false; - } else if(type == SPTPS_HANDSHAKE) { - if(!receive_handshake(s, s->inbuf + 3, s->reclen)) - return false; - } else { - return error(s, EIO, "Invalid record type %d", type); - } - - s->buflen = 0; + // Exit early if we have no more data to process. + if(!len) + return total_read; } - return true; + // Read up to the end of the record. + size_t toread = s->reclen + (s->instate ? 19UL : 3UL) - s->buflen; + if(toread > len) + toread = len; + + memcpy(s->inbuf + s->buflen, data, toread); + total_read += toread; + s->buflen += toread; + len -= toread; + data += toread; + + // If we don't have a whole record, exit. + if(s->buflen < s->reclen + (s->instate ? 19UL : 3UL)) + return total_read; + + // Update sequence number. + + uint32_t seqno = s->inseqno++; + + // Check HMAC and decrypt. + if(s->instate) { + if(!chacha_poly1305_decrypt(s->incipher, seqno, s->inbuf + 2UL, s->reclen + 17UL, s->inbuf + 2UL, NULL)) + return error(s, EINVAL, "Failed to decrypt and verify record"); + } + + // Append a NULL byte for safety. + s->inbuf[s->reclen + 3UL] = 0; + + uint8_t type = s->inbuf[2]; + + if(type < SPTPS_HANDSHAKE) { + if(!s->instate) + return error(s, EIO, "Application record received before handshake finished"); + if(!s->receive_record(s->handle, type, s->inbuf + 3, s->reclen)) + return false; + } else if(type == SPTPS_HANDSHAKE) { + if(!receive_handshake(s, s->inbuf + 3, s->reclen)) + return false; + } else { + return error(s, EIO, "Invalid record type %d", type); + } + + s->buflen = 0; + + return total_read; } // Start a SPTPS session. diff --git a/src/sptps.h b/src/sptps.h index a2633bd..75a9565 100644 --- a/src/sptps.h +++ b/src/sptps.h @@ -88,7 +88,7 @@ extern void (*sptps_log)(sptps_t *s, int s_errno, const char *format, va_list ap extern bool sptps_start(sptps_t *s, void *handle, bool initiator, bool datagram, ecdsa_t *mykey, ecdsa_t *hiskey, const void *label, size_t labellen, send_data_t send_data, receive_record_t receive_record); extern bool sptps_stop(sptps_t *s); extern bool sptps_send_record(sptps_t *s, uint8_t type, const void *data, uint16_t len); -extern bool sptps_receive_data(sptps_t *s, const void *data, size_t len); +extern size_t sptps_receive_data(sptps_t *s, const void *data, size_t len); extern bool sptps_force_kex(sptps_t *s); extern bool sptps_verify_datagram(sptps_t *s, const void *data, size_t len); diff --git a/src/sptps_keypair.c b/src/sptps_keypair.c index 399404e..fde8622 100644 --- a/src/sptps_keypair.c +++ b/src/sptps_keypair.c @@ -88,7 +88,10 @@ int main(int argc, char *argv[]) { FILE *fp = fopen(argv[1], "w"); if(fp) { - ecdsa_write_pem_private_key(key, fp); + if(!ecdsa_write_pem_private_key(key, fp)) { + fprintf(stderr, "Could not write ECDSA private key\n"); + return 1; + } fclose(fp); } else { fprintf(stderr, "Could not open '%s' for writing: %s\n", argv[1], strerror(errno)); @@ -97,7 +100,8 @@ int main(int argc, char *argv[]) { fp = fopen(argv[2], "w"); if(fp) { - ecdsa_write_pem_public_key(key, fp); + if(!ecdsa_write_pem_public_key(key, fp)) + fprintf(stderr, "Could not write ECDSA public key\n"); fclose(fp); } else { fprintf(stderr, "Could not open '%s' for writing: %s\n", argv[2], strerror(errno)); diff --git a/src/sptps_speed.c b/src/sptps_speed.c index ab41e8d..bde3d69 100644 --- a/src/sptps_speed.c +++ b/src/sptps_speed.c @@ -33,6 +33,7 @@ bool send_request(void *c, const char *msg, ...) { return false; } struct list_t *connection_list = NULL; bool send_meta(void *c, const char *msg , int len) { return false; } char *logfilename = NULL; +bool do_detach = false; struct timeval now; static bool send_data(void *handle, uint8_t type, const void *data, size_t len) { @@ -46,11 +47,16 @@ static bool receive_record(void *handle, uint8_t type, const void *data, uint16_ } static void receive_data(sptps_t *sptps) { - char buf[4096]; + char buf[4096], *bufp = buf; int fd = *(int *)sptps->handle; size_t len = recv(fd, buf, sizeof buf, 0); - if(!sptps_receive_data(sptps, buf, len)) - abort(); + while(len) { + size_t done = sptps_receive_data(sptps, bufp, len); + if(!done) + abort(); + bufp += done; + len -= done; + } } struct timespec start; @@ -101,19 +107,26 @@ int main(int argc, char *argv[]) { fprintf(stderr, "Ed25519 sign for %lg seconds: ", duration); for(clock_start(); clock_countto(duration);) - ecdsa_sign(key1, buf1, 256, buf2); - fprintf(stderr, "%22.2lf op/s\n", rate); + if(!ecdsa_sign(key1, buf1, 256, buf2)) + return 1; + fprintf(stderr, "%20.2lf op/s\n", rate); fprintf(stderr, "Ed25519 verify for %lg seconds: ", duration); for(clock_start(); clock_countto(duration);) - ecdsa_verify(key1, buf1, 256, buf2); - fprintf(stderr, "%20.2lf op/s\n", rate); + if(!ecdsa_verify(key1, buf1, 256, buf2)) { + fprintf(stderr, "Signature verification failed\n"); + return 1; + } + fprintf(stderr, "%18.2lf op/s\n", rate); ecdh1 = ecdh_generate_public(buf1); fprintf(stderr, "ECDH for %lg seconds: ", duration); for(clock_start(); clock_countto(duration);) { ecdh2 = ecdh_generate_public(buf2); - ecdh_compute_shared(ecdh2, buf1, buf3); + if(!ecdh2) + return 1; + if(!ecdh_compute_shared(ecdh2, buf1, buf3)) + return 1; } fprintf(stderr, "%28.2lf op/s\n", rate); ecdh_free(ecdh1); diff --git a/src/sptps_test.c b/src/sptps_test.c index 95bfda8..a394175 100644 --- a/src/sptps_test.c +++ b/src/sptps_test.c @@ -35,8 +35,10 @@ bool send_request(void *c, const char *msg, ...) { return false; } struct list_t *connection_list = NULL; bool send_meta(void *c, const char *msg , int len) { return false; } char *logfilename = NULL; +bool do_detach = false; struct timeval now; +static bool special; static bool verbose; static bool readonly; static bool writeonly; @@ -69,6 +71,7 @@ static struct option const long_options[] = { {"writeonly", no_argument, NULL, 'w'}, {"packet-loss", required_argument, NULL, 'L'}, {"replay-window", required_argument, NULL, 'W'}, + {"special", no_argument, NULL, 's'}, {"verbose", required_argument, NULL, 'v'}, {"help", no_argument, NULL, 1}, {NULL, 0, NULL, 0} @@ -88,6 +91,7 @@ static void usage() { " -w, --writeonly Only send data from stdin to the socket.\n" " -L, --packet-loss RATE Fake packet loss of RATE percent.\n" " -R, --replay-window N Set replay window to N bytes.\n" + " -s, --special Enable special handling of lines starting with #, ^ and $.\n" " -v, --verbose Display debug messages.\n" "\n"); fprintf(stderr, "Report bugs to tinc@tinc-vpn.org.\n"); @@ -106,7 +110,7 @@ int main(int argc, char *argv[]) { ecdsa_t *mykey = NULL, *hiskey = NULL; bool quit = false; - while((r = getopt_long(argc, argv, "dqrtwL:W:v", long_options, &option_index)) != EOF) { + while((r = getopt_long(argc, argv, "dqrstwL:W:v", long_options, &option_index)) != EOF) { switch (r) { case 0: /* long option */ break; @@ -149,6 +153,10 @@ int main(int argc, char *argv[]) { verbose = true; break; + case 's': /* special character handling */ + special = true; + break; + case '?': /* wrong options */ usage(); return 1; @@ -271,11 +279,19 @@ int main(int argc, char *argv[]) { crypto_init(); FILE *fp = fopen(argv[1], "r"); + if(!fp) { + fprintf(stderr, "Could not open %s: %s\n", argv[1], strerror(errno)); + return 1; + } if(!(mykey = ecdsa_read_pem_private_key(fp))) return 1; fclose(fp); fp = fopen(argv[2], "r"); + if(!fp) { + fprintf(stderr, "Could not open %s: %s\n", argv[2], strerror(errno)); + return 1; + } if(!(hiskey = ecdsa_read_pem_public_key(fp))) return 1; fclose(fp); @@ -315,11 +331,11 @@ int main(int argc, char *argv[]) { readonly = true; continue; } - if(buf[0] == '#') + if(special && buf[0] == '#') s.outseqno = atoi(buf + 1); - if(buf[0] == '^') + if(special && buf[0] == '^') sptps_send_record(&s, SPTPS_HANDSHAKE, NULL, 0); - else if(buf[0] == '$') { + else if(special && buf[0] == '$') { sptps_force_kex(&s); if(len > 1) sptps_send_record(&s, 0, buf, len); @@ -348,8 +364,19 @@ int main(int argc, char *argv[]) { fprintf(stderr, "Dropped.\n"); continue; } - if(!sptps_receive_data(&s, buf, len) && !datagram) - return 1; + char *bufp = buf; + while(len) { + size_t done = sptps_receive_data(&s, bufp, len); + if(!done) { + if(!datagram) + return 1; + } else { + break; + } + + bufp += done; + len -= done; + } } } diff --git a/src/subnet.c b/src/subnet.c index 534e5b5..090a62b 100644 --- a/src/subnet.c +++ b/src/subnet.c @@ -40,9 +40,9 @@ splay_tree_t *subnet_tree; /* Subnet lookup cache */ -hash_t *ipv4_cache; -hash_t *ipv6_cache; -hash_t *mac_cache; +static hash_t *ipv4_cache; +static hash_t *ipv6_cache; +static hash_t *mac_cache; void subnet_cache_flush(void) { hash_clear(ipv4_cache); diff --git a/src/subnet.h b/src/subnet.h index 9fd95b6..6184e6b 100644 --- a/src/subnet.h +++ b/src/subnet.h @@ -22,6 +22,7 @@ #define __TINC_SUBNET_H__ #include "net.h" +#include "node.h" typedef enum subnet_type_t { SUBNET_MAC = 0, @@ -44,8 +45,6 @@ typedef struct subnet_ipv6_t { int prefixlength; } subnet_ipv6_t; -#include "node.h" - typedef struct subnet_t { struct node_t *owner; /* the owner of this subnet */ diff --git a/src/subnet_parse.c b/src/subnet_parse.c index c919b59..611d6bd 100644 --- a/src/subnet_parse.c +++ b/src/subnet_parse.c @@ -401,11 +401,8 @@ bool net2str(char *netstr, int len, const subnet_t *subnet) { len -= result; } - if (subnet->weight != DEFAULT_WEIGHT) { + if (subnet->weight != DEFAULT_WEIGHT) snprintf(netstr, len, "#%d", subnet->weight); - netstr += result; - len -= result; - } return true; } diff --git a/src/system.h b/src/system.h index 7180b87..2201ff3 100644 --- a/src/system.h +++ b/src/system.h @@ -1,7 +1,7 @@ /* system.h -- system headers Copyright (C) 1998-2005 Ivo Timmermans - 2003-2013 Guus Sliepen + 2003-2016 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 @@ -25,12 +25,6 @@ #include "have.h" -#ifndef HAVE_STDBOOL_H -typedef int bool; -#define true 1 -#define false 0 -#endif - #ifndef HAVE_STRSIGNAL # define strsignal(p) "" #endif @@ -39,8 +33,4 @@ typedef int bool; #include "dropin.h" -#ifndef HAVE_SOCKLEN_T -typedef int socklen_t; -#endif - #endif /* __TINC_SYSTEM_H__ */ diff --git a/src/tincctl.c b/src/tincctl.c index abaf6ee..e42ec2c 100644 --- a/src/tincctl.c +++ b/src/tincctl.c @@ -1,6 +1,6 @@ /* tincctl.c -- Controlling a running tincd - Copyright (C) 2007-2014 Guus Sliepen + Copyright (C) 2007-2016 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 @@ -31,6 +31,7 @@ #include "control_common.h" #include "crypto.h" #include "ecdsagen.h" +#include "fsck.h" #include "info.h" #include "invitation.h" #include "names.h" @@ -66,7 +67,7 @@ char line[4096]; static int code; static int req; static int result; -static bool force = false; +bool force = false; bool tty = true; bool confbasegiven = false; bool netnamegiven = false; @@ -87,8 +88,8 @@ static struct option const long_options[] = { static void version(void) { printf("%s version %s (built %s %s, protocol %d.%d)\n", PACKAGE, - VERSION, BUILD_DATE, BUILD_TIME, PROT_MAJOR, PROT_MINOR); - printf("Copyright (C) 1998-2014 Ivo Timmermans, Guus Sliepen and others.\n" + BUILD_VERSION, BUILD_DATE, BUILD_TIME, PROT_MAJOR, PROT_MINOR); + printf("Copyright (C) 1998-2016 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" @@ -105,6 +106,7 @@ static void usage(bool status) { " -c, --config=DIR Read configuration options from DIR.\n" " -n, --net=NETNAME Connect to net NETNAME.\n" " --pidfile=FILENAME Read control cookie from FILENAME.\n" + " --force Force some commands to work despite warnings.\n" " --help Display this help and exit.\n" " --version Output version information and exit.\n" "\n" @@ -119,8 +121,12 @@ static void usage(bool status) { " restart [tincd options] Restart tincd.\n" " reload Partially reload configuration of running tincd.\n" " pid Show PID of currently running tincd.\n" +#ifdef DISABLE_LEGACY + " generate-keys Generate a new Ed25519 public/private keypair.\n" +#else " generate-keys [bits] Generate new RSA and Ed25519 public/private keypairs.\n" " generate-rsa-keys [bits] Generate a new RSA public/private keypair.\n" +#endif " generate-ed25519-keys Generate a new Ed25519 public/private keypair.\n" " dump Dump a list of one of the following things:\n" " [reachable] nodes - all known nodes in the VPN\n" @@ -128,6 +134,7 @@ static void usage(bool status) { " subnets - all known subnets in the VPN\n" " connections - all meta connections with ourself\n" " [di]graph - graph of the VPN in dotty format\n" + " invitations - outstanding invitations\n" " info NODE|SUBNET|ADDRESS Give information about a particular NODE, SUBNET or ADDRESS.\n" " purge Purge unreachable nodes\n" " debug N Set debug level\n" @@ -140,12 +147,15 @@ static void usage(bool status) { " log [level] Dump log output [up to the specified level]\n" " export Export host configuration of local node to standard output\n" " export-all Export all host configuration files to standard output\n" - " import [--force] Import host configuration file(s) from standard input\n" - " exchange [--force] Same as export followed by import\n" - " exchange-all [--force] Same as export-all followed by import\n" + " import Import host configuration file(s) from standard input\n" + " exchange Same as export followed by import\n" + " exchange-all Same as export-all followed by import\n" " invite NODE [...] Generate an invitation for NODE\n" - " join INVITATION Join a VPN using an INVITIATION\n" + " join INVITATION Join a VPN using an INVITATION\n" " network [NETNAME] List all known networks, or switch to the one named NETNAME.\n" + " fsck Check the configuration files for problems.\n" + " sign [FILE] Generate a signed version of a file.\n" + " verify NODE [FILE] Verify that a file was signed by the given NODE.\n" "\n"); printf("Report bugs to tinc@tinc-vpn.org.\n"); } @@ -225,6 +235,12 @@ FILE *fopenmask(const char *filename, const char *mode, mode_t perms) { perms &= ~mask; umask(~perms); FILE *f = fopen(filename, mode); + + if(!f) { + fprintf(stderr, "Could not open %s: %s\n", filename, strerror(errno)); + return NULL; + } + #ifdef HAVE_FCHMOD if((perms & 0444) && f) fchmod(fileno(f), perms); @@ -314,7 +330,7 @@ static void disable_old_keys(const char *filename, const char *what) { static FILE *ask_and_open(const char *filename, const char *what, const char *mode, bool ask, mode_t perms) { FILE *r; - char *directory; + char directory[PATH_MAX] = "."; char buf[PATH_MAX]; char buf2[PATH_MAX]; @@ -342,7 +358,7 @@ static FILE *ask_and_open(const char *filename, const char *what, const char *mo if(filename[0] != '/') { #endif /* The directory is a relative path or a filename. */ - directory = get_current_dir_name(); + getcwd(directory, sizeof directory); snprintf(buf2, sizeof buf2, "%s" SLASH "%s", directory, filename); filename = buf2; } @@ -368,7 +384,7 @@ static FILE *ask_and_open(const char *filename, const char *what, const char *mo static bool ed25519_keygen(bool ask) { ecdsa_t *key; FILE *f; - char *pubname, *privname; + char fname[PATH_MAX]; fprintf(stderr, "Generating Ed25519 keypair:\n"); @@ -378,29 +394,25 @@ static bool ed25519_keygen(bool ask) { } else fprintf(stderr, "Done.\n"); - xasprintf(&privname, "%s" SLASH "ed25519_key.priv", confbase); - f = ask_and_open(privname, "private Ed25519 key", "a", ask, 0600); - free(privname); + snprintf(fname, sizeof fname, "%s" SLASH "ed25519_key.priv", confbase); + f = ask_and_open(fname, "private Ed25519 key", "a", ask, 0600); if(!f) - return false; + goto error; if(!ecdsa_write_pem_private_key(key, f)) { fprintf(stderr, "Error writing private key!\n"); - ecdsa_free(key); - fclose(f); - return false; + goto error; } fclose(f); if(name) - xasprintf(&pubname, "%s" SLASH "hosts" SLASH "%s", confbase, name); + snprintf(fname, sizeof fname, "%s" SLASH "hosts" SLASH "%s", confbase, name); else - xasprintf(&pubname, "%s" SLASH "ed25519_key.pub", confbase); + snprintf(fname, sizeof fname, "%s" SLASH "ed25519_key.pub", confbase); - f = ask_and_open(pubname, "public Ed25519 key", "a", ask, 0666); - free(pubname); + f = ask_and_open(fname, "public Ed25519 key", "a", ask, 0666); if(!f) return false; @@ -413,8 +425,15 @@ static bool ed25519_keygen(bool ask) { ecdsa_free(key); return true; + +error: + if(f) + fclose(f); + ecdsa_free(key); + return false; } +#ifndef DISABLE_LEGACY /* Generate a public/private RSA keypair, and ask for a file to store them in. @@ -422,7 +441,7 @@ static bool ed25519_keygen(bool ask) { static bool rsa_keygen(int bits, bool ask) { rsa_t *key; FILE *f; - char *pubname, *privname; + char fname[PATH_MAX]; // Make sure the key size is a multiple of 8 bits. bits &= ~0x7; @@ -441,45 +460,46 @@ static bool rsa_keygen(int bits, bool ask) { } else fprintf(stderr, "Done.\n"); - xasprintf(&privname, "%s" SLASH "rsa_key.priv", confbase); - f = ask_and_open(privname, "private RSA key", "a", ask, 0600); - free(privname); + snprintf(fname, sizeof fname, "%s" SLASH "rsa_key.priv", confbase); + f = ask_and_open(fname, "private RSA key", "a", ask, 0600); if(!f) - return false; + goto error; if(!rsa_write_pem_private_key(key, f)) { fprintf(stderr, "Error writing private key!\n"); - fclose(f); - rsa_free(key); - return false; + goto error; } fclose(f); if(name) - xasprintf(&pubname, "%s" SLASH "hosts" SLASH "%s", confbase, name); + snprintf(fname, sizeof fname, "%s" SLASH "hosts" SLASH "%s", confbase, name); else - xasprintf(&pubname, "%s" SLASH "rsa_key.pub", confbase); + snprintf(fname, sizeof fname, "%s" SLASH "rsa_key.pub", confbase); - f = ask_and_open(pubname, "public RSA key", "a", ask, 0666); - free(pubname); + f = ask_and_open(fname, "public RSA key", "a", ask, 0666); if(!f) - return false; + goto error; if(!rsa_write_pem_public_key(key, f)) { fprintf(stderr, "Error writing public key!\n"); - fclose(f); - rsa_free(key); - return false; + goto error; } fclose(f); rsa_free(key); return true; + +error: + if(f) + fclose(f); + rsa_free(key); + return false; } +#endif char buffer[4096]; size_t blen = 0; @@ -842,6 +862,13 @@ static int cmd_start(int argc, char *argv[]) { } return status; #else + int pfd[2] = {-1, -1}; + if(socketpair(AF_UNIX, SOCK_STREAM, 0, pfd)) { + fprintf(stderr, "Could not create umbilical socket: %s\n", strerror(errno)); + free(nargv); + return 1; + } + pid_t pid = fork(); if(pid == -1) { fprintf(stderr, "Could not fork: %s\n", strerror(errno)); @@ -849,8 +876,15 @@ static int cmd_start(int argc, char *argv[]) { return 1; } - if(!pid) + if(!pid) { + close(pfd[0]); + char buf[100] = ""; + snprintf(buf, sizeof buf, "%d", pfd[1]); + setenv("TINC_UMBILICAL", buf, true); exit(execvp(c, nargv)); + } else { + close(pfd[1]); + } free(nargv); @@ -858,12 +892,33 @@ static int cmd_start(int argc, char *argv[]) { #ifdef SIGINT signal(SIGINT, SIG_IGN); #endif + + // Pass all log messages from the umbilical to stderr. + // A nul-byte right before closure means tincd started succesfully. + bool failure = true; + char buf[1024]; + ssize_t len; + + while((len = read(pfd[0], buf, sizeof buf)) > 0) { + failure = buf[len - 1]; + if(!failure) + len--; + write(2, buf, len); + } + + if(len) + failure = true; + + close(pfd[0]); + + // Make sure the child process is really gone. result = waitpid(pid, &status, 0); + #ifdef SIGINT signal(SIGINT, SIG_DFL); #endif - if(result != pid || !WIFEXITED(status) || WEXITSTATUS(status)) { + if(failure || result != pid || !WIFEXITED(status) || WEXITSTATUS(status)) { fprintf(stderr, "Error starting %s\n", c); return 1; } @@ -934,6 +989,65 @@ static int cmd_reload(int argc, char *argv[]) { } +static int dump_invitations(void) { + char dname[PATH_MAX]; + snprintf(dname, sizeof dname, "%s" SLASH "invitations", confbase); + DIR *dir = opendir(dname); + if(!dir) { + if(errno == ENOENT) { + fprintf(stderr, "No outstanding invitations.\n"); + return 0; + } + + fprintf(stderr, "Cannot not read directory %s: %s\n", dname, strerror(errno)); + return 1; + } + + struct dirent *ent; + bool found = false; + + while((ent = readdir(dir))) { + char buf[MAX_STRING_SIZE]; + if(b64decode(ent->d_name, buf, 24) != 18) + continue; + + char fname[PATH_MAX]; + snprintf(fname, sizeof fname, "%s" SLASH "%s", dname, ent->d_name); + FILE *f = fopen(fname, "r"); + if(!f) { + fprintf(stderr, "Cannot open %s: %s\n", fname, strerror(errno)); + fclose(f); + continue; + } + + buf[0] = 0; + if(!fgets(buf, sizeof buf, f)) { + fprintf(stderr, "Invalid invitation file %s", fname); + fclose(f); + continue; + } + fclose(f); + + char *eol = buf + strlen(buf); + while(strchr("\t \r\n", *--eol)) + *eol = 0; + if(strncmp(buf, "Name = ", 7) || !check_id(buf + 7)) { + fprintf(stderr, "Invalid invitation file %s", fname); + continue; + } + + found = true; + printf("%s %s\n", ent->d_name, buf + 7); + } + + closedir(dir); + + if(!found) + fprintf(stderr, "No outstanding invitations.\n"); + + return 0; +} + static int cmd_dump(int argc, char *argv[]) { bool only_reachable = false; @@ -954,6 +1068,9 @@ static int cmd_dump(int argc, char *argv[]) { return 1; } + if(!strcasecmp(argv[1], "invitations")) + return dump_invitations(); + if(!connect_tincd(true)) return 1; @@ -1316,6 +1433,29 @@ char *get_my_name(bool verbose) { return NULL; } +ecdsa_t *get_pubkey(FILE *f) { + char buf[4096]; + char *value; + while(fgets(buf, sizeof buf, f)) { + int len = strcspn(buf, "\t ="); + value = buf + len; + value += strspn(value, "\t "); + if(*value == '=') { + value++; + value += strspn(value, "\t "); + } + if(!rstrip(value)) + continue; + buf[len] = 0; + if(strcasecmp(buf, "Ed25519PublicKey")) + continue; + if(*value) + return ecdsa_set_base64_public_key(value); + } + + return NULL; +} + const var_t variables[] = { /* Server configuration */ {"AddressFamily", VAR_SERVER}, @@ -1358,8 +1498,17 @@ const var_t variables[] = { {"ScriptsInterpreter", VAR_SERVER}, {"StrictSubnets", VAR_SERVER}, {"TunnelServer", VAR_SERVER}, + {"UDPDiscovery", VAR_SERVER}, + {"UDPDiscoveryKeepaliveInterval", VAR_SERVER}, + {"UDPDiscoveryInterval", VAR_SERVER}, + {"UDPDiscoveryTimeout", VAR_SERVER}, + {"MTUInfoInterval", VAR_SERVER}, + {"UDPInfoInterval", VAR_SERVER}, {"UDPRcvBuf", VAR_SERVER}, {"UDPSndBuf", VAR_SERVER}, + {"UPnP", VAR_SERVER}, + {"UPnPDiscoverWait", VAR_SERVER}, + {"UPnPRefreshPeriod", VAR_SERVER}, {"VDEGroup", VAR_SERVER}, {"VDEPort", VAR_SERVER}, /* Host configuration */ @@ -1519,11 +1668,11 @@ static int cmd_config(int argc, char *argv[]) { } // Open the right configuration file. - char *filename; + char filename[PATH_MAX]; if(node) - xasprintf(&filename, "%s" SLASH "%s", hosts_dir, node); + snprintf(filename, sizeof filename, "%s" SLASH "%s", hosts_dir, node); else - filename = tinc_conf; + snprintf(filename, sizeof filename, "%s", tinc_conf); FILE *f = fopen(filename, "r"); if(!f) { @@ -1531,11 +1680,11 @@ static int cmd_config(int argc, char *argv[]) { return 1; } - char *tmpfile = NULL; + char tmpfile[PATH_MAX]; FILE *tf = NULL; if(action >= -1) { - xasprintf(&tmpfile, "%s.config.tmp", filename); + snprintf(tmpfile, sizeof tmpfile, "%s.config.tmp", filename); tf = fopen(tmpfile, "w"); if(!tf) { fprintf(stderr, "Could not open temporary file %s: %s\n", tmpfile, strerror(errno)); @@ -1598,6 +1747,11 @@ static int cmd_config(int argc, char *argv[]) { } set = true; continue; + // Add + } else if(action > 0) { + // Check if we've already seen this variable with the same value + if(!strcasecmp(bvalue, value)) + found = true; } } @@ -1630,7 +1784,7 @@ static int cmd_config(int argc, char *argv[]) { } // Add new variable if necessary. - if(action > 0 || (action == 0 && !set)) { + if((action > 0 && !found)|| (action == 0 && !set)) { if(fprintf(tf, "%s = %s\n", variable, value) < 0) { fprintf(stderr, "Error writing to temporary file %s: %s\n", tmpfile, strerror(errno)); return 1; @@ -1679,7 +1833,7 @@ static int cmd_config(int argc, char *argv[]) { } static bool try_bind(int port) { - struct addrinfo *ai = NULL; + struct addrinfo *ai = NULL, *aip; struct addrinfo hint = { .ai_flags = AI_PASSIVE, .ai_family = AF_UNSPEC, @@ -1687,24 +1841,30 @@ static bool try_bind(int port) { .ai_protocol = IPPROTO_TCP, }; + bool success = true; char portstr[16]; snprintf(portstr, sizeof portstr, "%d", port); if(getaddrinfo(NULL, portstr, &hint, &ai) || !ai) return false; - while(ai) { + for(aip = ai; aip; aip = aip->ai_next) { int fd = socket(ai->ai_family, SOCK_STREAM, IPPROTO_TCP); - if(!fd) - return false; + if(!fd) { + success = false; + break; + } + int result = bind(fd, ai->ai_addr, ai->ai_addrlen); closesocket(fd); - if(result) - return false; - ai = ai->ai_next; + if(result) { + success = false; + break; + } } - return true; + freeaddrinfo(ai); + return success; } int check_port(char *name) { @@ -1716,11 +1876,11 @@ int check_port(char *name) { for(int i = 0; i < 100; i++) { int port = 0x1000 + (rand() & 0x7fff); if(try_bind(port)) { - char *filename; - xasprintf(&filename, "%s" SLASH "hosts" SLASH "%s", confbase, name); + char filename[PATH_MAX]; + snprintf(filename, sizeof filename, "%s" SLASH "hosts" SLASH "%s", confbase, name); FILE *f = fopen(filename, "a"); - free(filename); if(!f) { + fprintf(stderr, "Could not open %s: %s\n", filename, strerror(errno)); fprintf(stderr, "Please change tinc's Port manually.\n"); return 0; } @@ -1800,14 +1960,19 @@ static int cmd_init(int argc, char *argv[]) { fprintf(f, "Name = %s\n", name); fclose(f); - if(!rsa_keygen(2048, false) || !ed25519_keygen(false)) +#ifndef DISABLE_LEGACY + if(!rsa_keygen(2048, false)) + return 1; +#endif + + if(!ed25519_keygen(false)) return 1; check_port(name); #ifndef HAVE_MINGW - char *filename; - xasprintf(&filename, "%s" SLASH "tinc-up", confbase); + char filename[PATH_MAX]; + snprintf(filename, sizeof filename, "%s" SLASH "tinc-up", confbase); if(access(filename, F_OK)) { FILE *f = fopenmask(filename, "w", 0777); if(!f) { @@ -1824,7 +1989,11 @@ static int cmd_init(int argc, char *argv[]) { } static int cmd_generate_keys(int argc, char *argv[]) { +#ifdef DISABLE_LEGACY + if(argc > 1) { +#else if(argc > 2) { +#endif fprintf(stderr, "Too many arguments!\n"); return 1; } @@ -1832,9 +2001,18 @@ static int cmd_generate_keys(int argc, char *argv[]) { if(!name) name = get_my_name(false); - return !(rsa_keygen(argc > 1 ? atoi(argv[1]) : 2048, true) && ed25519_keygen(true)); +#ifndef DISABLE_LEGACY + if(!rsa_keygen(argc > 1 ? atoi(argv[1]) : 2048, true)) + return 1; +#endif + + if(!ed25519_keygen(true)) + return 1; + + return 0; } +#ifndef DISABLE_LEGACY static int cmd_generate_rsa_keys(int argc, char *argv[]) { if(argc > 2) { fprintf(stderr, "Too many arguments!\n"); @@ -1846,6 +2024,7 @@ static int cmd_generate_rsa_keys(int argc, char *argv[]) { return !rsa_keygen(argc > 1 ? atoi(argv[1]) : 2048, true); } +#endif static int cmd_generate_ed25519_keys(int argc, char *argv[]) { if(argc > 1) { @@ -1903,12 +2082,12 @@ static int cmd_edit(int argc, char *argv[]) { return 1; } - char *filename = NULL; + char filename[PATH_MAX] = ""; if(strncmp(argv[1], "hosts" SLASH, 6)) { for(int i = 0; conffiles[i]; i++) { if(!strcmp(argv[1], conffiles[i])) { - xasprintf(&filename, "%s" SLASH "%s", confbase, argv[1]); + snprintf(filename, sizeof filename, "%s" SLASH "%s", confbase, argv[1]); break; } } @@ -1916,8 +2095,8 @@ static int cmd_edit(int argc, char *argv[]) { argv[1] += 6; } - if(!filename) { - xasprintf(&filename, "%s" SLASH "%s", hosts_dir, argv[1]); + if(!*filename) { + snprintf(filename, sizeof filename, "%s" SLASH "%s", hosts_dir, argv[1]); char *dash = strchr(argv[1], '-'); if(dash) { *dash++ = 0; @@ -1935,6 +2114,7 @@ static int cmd_edit(int argc, char *argv[]) { xasprintf(&command, "edit \"%s\"", filename); #endif int result = system(command); + free(command); if(result) return result; @@ -1946,8 +2126,8 @@ static int cmd_edit(int argc, char *argv[]) { } static int export(const char *name, FILE *out) { - char *filename; - xasprintf(&filename, "%s" SLASH "%s", hosts_dir, name); + char filename[PATH_MAX]; + snprintf(filename, sizeof filename, "%s" SLASH "%s", hosts_dir, name); FILE *in = fopen(filename, "r"); if(!in) { fprintf(stderr, "Could not open configuration file %s: %s\n", filename, strerror(errno)); @@ -2034,7 +2214,7 @@ static int cmd_import(int argc, char *argv[]) { char buf[4096]; char name[4096]; - char *filename = NULL; + char filename[PATH_MAX] = ""; int count = 0; bool firstline = true; @@ -2050,8 +2230,7 @@ static int cmd_import(int argc, char *argv[]) { if(out) fclose(out); - free(filename); - xasprintf(&filename, "%s" SLASH "%s", hosts_dir, name); + snprintf(filename, sizeof filename, "%s" SLASH "%s", hosts_dir, name); if(!force && !access(filename, F_OK)) { fprintf(stderr, "Host configuration file %s already exists, skipping.\n", filename); @@ -2105,27 +2284,29 @@ static int cmd_exchange_all(int argc, char *argv[]) { } static int switch_network(char *name) { + if(strcmp(name, ".")) { + if(!check_netname(name, false)) { + fprintf(stderr, "Invalid character in netname!\n"); + return 1; + } + + if(!check_netname(name, true)) + fprintf(stderr, "Warning: unsafe character in netname!\n"); + } + if(fd >= 0) { close(fd); fd = -1; } - free(confbase); - confbase = NULL; - free(pidfilename); - pidfilename = NULL; - free(logfilename); - logfilename = NULL; - free(unixsocketname); - unixsocketname = NULL; + free_names(); + netname = strcmp(name, ".") ? xstrdup(name) : NULL; + make_names(false); + free(tinc_conf); free(hosts_dir); free(prompt); - free(netname); - netname = strcmp(name, ".") ? xstrdup(name) : NULL; - - make_names(); xasprintf(&tinc_conf, "%s" SLASH "tinc.conf", confbase); xasprintf(&hosts_dir, "%s" SLASH "hosts", confbase); xasprintf(&prompt, "%s> ", identname); @@ -2158,11 +2339,10 @@ static int cmd_network(int argc, char *argv[]) { continue; } - char *fname; - xasprintf(&fname, "%s/%s/tinc.conf", confdir, ent->d_name); + char fname[PATH_MAX]; + snprintf(fname, sizeof fname, "%s/%s/tinc.conf", confdir, ent->d_name); if(!access(fname, R_OK)) printf("%s\n", ent->d_name); - free(fname); } closedir(dir); @@ -2170,6 +2350,240 @@ static int cmd_network(int argc, char *argv[]) { return 0; } +static int cmd_fsck(int argc, char *argv[]) { + if(argc > 1) { + fprintf(stderr, "Too many arguments!\n"); + return 1; + } + + return fsck(orig_argv[0]); +} + +static void *readfile(FILE *in, size_t *len) { + size_t count = 0; + size_t alloced = 4096; + char *buf = xmalloc(alloced); + + while(!feof(in)) { + size_t read = fread(buf + count, 1, alloced - count, in); + if(!read) + break; + count += read; + if(count >= alloced) { + alloced *= 2; + buf = xrealloc(buf, alloced); + } + } + + if(len) + *len = count; + + return buf; +} + +static int cmd_sign(int argc, char *argv[]) { + if(argc > 2) { + fprintf(stderr, "Too many arguments!\n"); + return 1; + } + + if(!name) { + name = get_my_name(true); + if(!name) + return 1; + } + + char fname[PATH_MAX]; + snprintf(fname, sizeof fname, "%s" SLASH "ed25519_key.priv", confbase); + FILE *fp = fopen(fname, "r"); + if(!fp) { + fprintf(stderr, "Could not open %s: %s\n", fname, strerror(errno)); + return 1; + } + + ecdsa_t *key = ecdsa_read_pem_private_key(fp); + + if(!key) { + fprintf(stderr, "Could not read private key from %s\n", fname); + fclose(fp); + return 1; + } + + fclose(fp); + + FILE *in; + + if(argc == 2) { + in = fopen(argv[1], "rb"); + if(!in) { + fprintf(stderr, "Could not open %s: %s\n", argv[1], strerror(errno)); + ecdsa_free(key); + return 1; + } + } else { + in = stdin; + } + + size_t len; + char *data = readfile(in, &len); + if(in != stdin) + fclose(in); + if(!data) { + fprintf(stderr, "Error reading %s: %s\n", argv[1], strerror(errno)); + ecdsa_free(key); + return 1; + } + + // Ensure we sign our name and current time as well + long t = time(NULL); + char *trailer; + xasprintf(&trailer, " %s %ld", name, t); + int trailer_len = strlen(trailer); + + data = xrealloc(data, len + trailer_len); + memcpy(data + len, trailer, trailer_len); + free(trailer); + + char sig[87]; + if(!ecdsa_sign(key, data, len + trailer_len, sig)) { + fprintf(stderr, "Error generating signature\n"); + free(data); + ecdsa_free(key); + return 1; + } + b64encode(sig, sig, 64); + ecdsa_free(key); + + fprintf(stdout, "Signature = %s %ld %s\n", name, t, sig); + fwrite(data, len, 1, stdout); + + free(data); + return 0; +} + +static int cmd_verify(int argc, char *argv[]) { + if(argc < 2) { + fprintf(stderr, "Not enough arguments!\n"); + return 1; + } + + if(argc > 3) { + fprintf(stderr, "Too many arguments!\n"); + return 1; + } + + char *node = argv[1]; + if(!strcmp(node, ".")) { + if(!name) { + name = get_my_name(true); + if(!name) + return 1; + } + node = name; + } else if(!strcmp(node, "*")) { + node = NULL; + } else { + if(!check_id(node)) { + fprintf(stderr, "Invalid node name\n"); + return 1; + } + } + + FILE *in; + + if(argc == 3) { + in = fopen(argv[2], "rb"); + if(!in) { + fprintf(stderr, "Could not open %s: %s\n", argv[2], strerror(errno)); + return 1; + } + } else { + in = stdin; + } + + size_t len; + char *data = readfile(in, &len); + if(in != stdin) + fclose(in); + if(!data) { + fprintf(stderr, "Error reading %s: %s\n", argv[1], strerror(errno)); + return 1; + } + + char *newline = memchr(data, '\n', len); + if(!newline || (newline - data > MAX_STRING_SIZE - 1)) { + fprintf(stderr, "Invalid input\n"); + return 1; + } + + *newline++ = '\0'; + size_t skip = newline - data; + + char signer[MAX_STRING_SIZE] = ""; + char sig[MAX_STRING_SIZE] = ""; + long t = 0; + + if(sscanf(data, "Signature = %s %ld %s", signer, &t, sig) != 3 || strlen(sig) != 86 || !t || !check_id(signer)) { + fprintf(stderr, "Invalid input\n"); + return 1; + } + + if(node && strcmp(node, signer)) { + fprintf(stderr, "Signature is not made by %s\n", node); + return 1; + } + + if(!node) + node = signer; + + char *trailer; + xasprintf(&trailer, " %s %ld", signer, t); + int trailer_len = strlen(trailer); + + data = xrealloc(data, len + trailer_len); + memcpy(data + len, trailer, trailer_len); + free(trailer); + + newline = data + skip; + + char fname[PATH_MAX]; + snprintf(fname, sizeof fname, "%s" SLASH "hosts" SLASH "%s", confbase, node); + FILE *fp = fopen(fname, "r"); + if(!fp) { + fprintf(stderr, "Could not open %s: %s\n", fname, strerror(errno)); + free(data); + return 1; + } + + ecdsa_t *key = get_pubkey(fp); + if(!key) { + rewind(fp); + key = ecdsa_read_pem_public_key(fp); + } + if(!key) { + fprintf(stderr, "Could not read public key from %s\n", fname); + fclose(fp); + free(data); + return 1; + } + + fclose(fp); + + if(b64decode(sig, sig, 86) != 64 || !ecdsa_verify(key, newline, len + trailer_len - (newline - data), sig)) { + fprintf(stderr, "Invalid signature\n"); + free(data); + ecdsa_free(key); + return 1; + } + + ecdsa_free(key); + + fwrite(newline, len - (newline - data), 1, stdout); + + free(data); + return 0; +} + static const struct { const char *command; int (*function)(int argc, char *argv[]); @@ -2180,6 +2594,7 @@ static const struct { {"restart", cmd_restart}, {"reload", cmd_reload}, {"dump", cmd_dump}, + {"list", cmd_dump}, {"purge", cmd_purge}, {"debug", cmd_debug}, {"retry", cmd_retry}, @@ -2196,7 +2611,9 @@ static const struct { {"set", cmd_config}, {"init", cmd_init}, {"generate-keys", cmd_generate_keys}, +#ifndef DISABLE_LEGACY {"generate-rsa-keys", cmd_generate_rsa_keys}, +#endif {"generate-ed25519-keys", cmd_generate_ed25519_keys}, {"help", cmd_help}, {"version", cmd_version}, @@ -2210,6 +2627,9 @@ static const struct { {"invite", cmd_invite}, {"join", cmd_join}, {"network", cmd_network}, + {"fsck", cmd_fsck}, + {"sign", cmd_sign}, + {"verify", cmd_verify}, {NULL, NULL}, }; @@ -2444,7 +2864,7 @@ int main(int argc, char *argv[]) { if(!parse_options(argc, argv)) return 1; - make_names(); + make_names(false); xasprintf(&tinc_conf, "%s" SLASH "tinc.conf", confbase); xasprintf(&hosts_dir, "%s" SLASH "hosts", confbase); diff --git a/src/tincctl.h b/src/tincctl.h index e636887..6628f2b 100644 --- a/src/tincctl.h +++ b/src/tincctl.h @@ -1,6 +1,6 @@ /* tincctl.h -- header for tincctl.c. - Copyright (C) 2011-2013 Guus Sliepen + Copyright (C) 2011-2016 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 @@ -21,6 +21,7 @@ #define __TINC_TINCCTL_H__ extern bool tty; +extern bool force; extern char line[4096]; extern int fd; extern char buffer[4096]; @@ -49,6 +50,7 @@ extern bool sendline(int fd, char *format, ...); extern bool recvline(int fd, char *line, size_t len); extern int check_port(char *name); extern FILE *fopenmask(const char *filename, const char *mode, mode_t perms); +extern ecdsa_t *get_pubkey(FILE *f); #endif diff --git a/src/tincd.c b/src/tincd.c index 15cddb1..4da9bd5 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-2014 Guus Sliepen + 2000-2016 Guus Sliepen 2008 Max Rijevski 2009 Michael Tokarev 2010 Julien Muchembled @@ -43,8 +43,6 @@ #include #endif -#include - #include "conf.h" #include "control.h" #include "crypto.h" @@ -85,6 +83,9 @@ static const char *switchuser = NULL; /* If nonzero, write log entries to a separate file. */ bool use_logfile = false; +/* If nonzero, use syslog instead of stderr in no-detach mode. */ +bool use_syslog = false; + char **g_argv; /* a copy of the cmdline arguments */ static int status = 1; @@ -101,6 +102,7 @@ static struct option const long_options[] = { {"chroot", no_argument, NULL, 'R'}, {"user", required_argument, NULL, 'U'}, {"logfile", optional_argument, NULL, 4}, + {"syslog", no_argument, NULL, 's'}, {"pidfile", required_argument, NULL, 5}, {"option", required_argument, NULL, 'o'}, {NULL, 0, NULL, 0} @@ -125,6 +127,7 @@ static void usage(bool status) { " -L, --mlock Lock tinc into main memory.\n" #endif " --logfile[=FILENAME] Write log entries to a logfile.\n" + " -s --syslog Use syslog instead of stderr with --no-detach.\n" " --pidfile=FILENAME Write PID and control socket cookie to FILENAME.\n" " --bypass-security Disables meta protocol security, for debugging.\n" " -o, --option[HOST.]KEY=VALUE Set global/host configuration value.\n" @@ -146,7 +149,7 @@ static bool parse_options(int argc, char **argv) { cmdline_conf = list_alloc((list_action_t)free_config); - while((r = getopt_long(argc, argv, "c:DLd::n:o:RU:", long_options, &option_index)) != EOF) { + while((r = getopt_long(argc, argv, "c:DLd::n:so:RU:", long_options, &option_index)) != EOF) { switch (r) { case 0: /* long option */ break; @@ -181,6 +184,11 @@ static bool parse_options(int argc, char **argv) { netname = xstrdup(optarg); break; + case 's': /* syslog */ + use_logfile = false; + use_syslog = true; + break; + case 'o': /* option */ cfg = parse_config_line(optarg, NULL, ++lineno); if (!cfg) @@ -216,6 +224,7 @@ static bool parse_options(int argc, char **argv) { break; case 4: /* write log entries to a file */ + use_syslog = false; use_logfile = true; if(!optarg && optind < argc && *argv[optind] != '-') optarg = argv[optind++]; @@ -252,11 +261,14 @@ static bool parse_options(int argc, char **argv) { netname = NULL; } - if(netname && (strpbrk(netname, "\\/") || *netname == '.')) { + if(netname && !check_netname(netname, false)) { fprintf(stderr, "Invalid character in netname!\n"); return false; } + if(netname && !check_netname(netname, true)) + fprintf(stderr, "Warning: unsafe character in netname!\n"); + return true; } @@ -328,12 +340,13 @@ int main(int argc, char **argv) { if(!parse_options(argc, argv)) return 1; - make_names(); + make_names(true); + chdir(confbase); if(show_version) { printf("%s version %s (built %s %s, protocol %d.%d)\n", PACKAGE, - VERSION, BUILD_DATE, BUILD_TIME, PROT_MAJOR, PROT_MINOR); - printf("Copyright (C) 1998-2014 Ivo Timmermans, Guus Sliepen and others.\n" + BUILD_VERSION, BUILD_DATE, BUILD_TIME, PROT_MAJOR, PROT_MINOR); + printf("Copyright (C) 1998-2016 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" @@ -352,6 +365,18 @@ int main(int argc, char **argv) { logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "WSAStartup", winerror(GetLastError())); return 1; } +#else + // Check if we got an umbilical fd from the process that started us + char *umbstr = getenv("TINC_UMBILICAL"); + if(umbstr) { + umbilical = atoi(umbstr); + if(fcntl(umbilical, F_GETFL) < 0) + umbilical = 0; +#ifdef FD_CLOEXEC + if(umbilical) + fcntl(umbilical, F_SETFD, FD_CLOEXEC); +#endif + } #endif openlogger("tinc", use_logfile?LOGMODE_FILE:LOGMODE_STDERR); @@ -455,6 +480,12 @@ int main2(int argc, char **argv) { logger(DEBUG_ALWAYS, LOG_NOTICE, "Ready"); + if(umbilical) { // snip! + write(umbilical, "", 1); + close(umbilical); + umbilical = 0; + } + try_outgoing_connections(); status = main_loop(); diff --git a/src/upnp.c b/src/upnp.c new file mode 100644 index 0000000..abd2f92 --- /dev/null +++ b/src/upnp.c @@ -0,0 +1,164 @@ +/* + upnp.c -- UPnP-IGD client + Copyright (C) 2015 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "upnp.h" + +#include + +#include "miniupnpc/miniupnpc.h" +#include "miniupnpc/upnpcommands.h" +#include "miniupnpc/upnperrors.h" + +#include "system.h" +#include "logger.h" +#include "names.h" +#include "net.h" +#include "netutl.h" +#include "utils.h" + +static bool upnp_tcp; +static bool upnp_udp; +static int upnp_discover_wait = 5; +static int upnp_refresh_period = 60; + +// Unfortunately, libminiupnpc devs don't seem to care about API compatibility, +// and there are slight changes to function signatures between library versions. +// Well, at least they publish a "MINIUPNPC_API_VERSION" constant, so we got that going for us, which is nice. +// Differences between API versions are documented in "apiversions.txt" in the libminiupnpc distribution. + +#ifndef MINIUPNPC_API_VERSION +#define MINIUPNPC_API_VERSION 0 +#endif + +static struct UPNPDev *upnp_discover(int delay, int *error) { +#if MINIUPNPC_API_VERSION <= 13 + +#if MINIUPNPC_API_VERSION < 8 +#warning "The version of libminiupnpc you're building against seems to be too old. Expect trouble." +#endif + + return upnpDiscover(delay, NULL, NULL, false, false, error); + +#elif MINIUPNPC_API_VERSION <= 14 + + return upnpDiscover(delay, NULL NULL, false, false, 2, error); + +#else + +#if MINIUPNPC_API_VERSION > 15 +#warning "The version of libminiupnpc you're building against seems to be too recent. Expect trouble." +#endif + + return upnpDiscover(delay, NULL, NULL, UPNP_LOCAL_PORT_ANY, false, 2, error); + +#endif +} + +static void upnp_add_mapping(struct UPNPUrls *urls, struct IGDdatas *data, const char *myaddr, int socket, const char *proto) { + // Extract the port from the listening socket. + // Note that we can't simply use listen_socket[].sa because this won't have the port + // if we're running with Port=0 (dynamically assigned port). + sockaddr_t sa; + socklen_t salen = sizeof sa; + if (getsockname(socket, &sa.sa, &salen)) { + logger(DEBUG_PROTOCOL, LOG_ERR, "[upnp] Unable to get socket address: [%d] %s", sockerrno, sockstrerror(sockerrno)); + return; + } + char *port; + sockaddr2str(&sa, NULL, &port); + if (!port) { + logger(DEBUG_PROTOCOL, LOG_ERR, "[upnp] Unable to get socket port"); + return; + } + + // Use a lease twice as long as the refresh period so that the mapping won't expire before we refresh. + char lease_duration[16]; + snprintf(lease_duration, sizeof lease_duration, "%d", upnp_refresh_period * 2); + + int error = UPNP_AddPortMapping(urls->controlURL, data->first.servicetype, port, port, myaddr, identname, proto, NULL, lease_duration); + if (error == 0) { + logger(DEBUG_PROTOCOL, LOG_INFO, "[upnp] Successfully set port mapping (%s:%s %s for %s seconds)", myaddr, port, proto, lease_duration); + } else { + logger(DEBUG_PROTOCOL, LOG_ERR, "[upnp] Failed to set port mapping (%s:%s %s for %s seconds): [%d] %s", myaddr, port, proto, lease_duration, error, strupnperror(error)); + } + + free(port); +} + +static void upnp_refresh() { + logger(DEBUG_PROTOCOL, LOG_INFO, "[upnp] Discovering IGD devices"); + + int error; + struct UPNPDev *devices = upnp_discover(upnp_discover_wait * 1000, &error); + if (!devices) { + logger(DEBUG_PROTOCOL, LOG_WARNING, "[upnp] Unable to find IGD devices: [%d] %s", error, strupnperror(error)); + freeUPNPDevlist(devices); + return; + } + + struct UPNPUrls urls; + struct IGDdatas data; + char myaddr[64]; + int result = UPNP_GetValidIGD(devices, &urls, &data, myaddr, sizeof myaddr); + if (result <= 0) { + logger(DEBUG_PROTOCOL, LOG_WARNING, "[upnp] No IGD found"); + freeUPNPDevlist(devices); + return; + } + logger(DEBUG_PROTOCOL, LOG_INFO, "[upnp] IGD found: [%d] %s (local address: %s, service type: %s)", result, urls.controlURL, myaddr, data.first.servicetype); + + for (int i = 0; i < listen_sockets; i++) { + if (upnp_tcp) upnp_add_mapping(&urls, &data, myaddr, listen_socket[i].tcp.fd, "TCP"); + if (upnp_udp) upnp_add_mapping(&urls, &data, myaddr, listen_socket[i].udp.fd, "UDP"); + } + + FreeUPNPUrls(&urls); + freeUPNPDevlist(devices); +} + +static void *upnp_thread(void *data) { + while (true) { + time_t start = time(NULL); + upnp_refresh(); + + // Make sure we'll stick to the refresh period no matter how long upnp_refresh() takes. + time_t refresh_time = start + upnp_refresh_period; + time_t now = time(NULL); + if (now < refresh_time) sleep(refresh_time - now); + } + + // TODO: we don't have a clean thread shutdown procedure, so we can't remove the mapping. + // this is probably not a concern as long as the UPnP device honors the lease duration, + // but considering how bug-riddled these devices often are, that's a big "if". + return NULL; +} + +void upnp_init(bool tcp, bool udp) { + upnp_tcp = tcp; + upnp_udp = udp; + + get_config_int(lookup_config(config_tree, "UPnPDiscoverWait"), &upnp_discover_wait); + get_config_int(lookup_config(config_tree, "UPnPRefreshPeriod"), &upnp_refresh_period); + + pthread_t thread; + int error = pthread_create(&thread, NULL, upnp_thread, NULL); + if (error) { + logger(DEBUG_ALWAYS, LOG_ERR, "Unable to start UPnP-IGD client thread: [%d] %s", error, strerror(error)); + } +} diff --git a/src/gcrypt/ecdsagen.c b/src/upnp.h similarity index 57% rename from src/gcrypt/ecdsagen.c rename to src/upnp.h index 2d4912d..dd0531b 100644 --- a/src/gcrypt/ecdsagen.c +++ b/src/upnp.h @@ -1,6 +1,6 @@ /* - ecdsagen.c -- ECDSA key generation and export - Copyright (C) 2011-2013 Guus Sliepen + upnp.h -- UPnP-IGD client + Copyright (C) 2015 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 @@ -17,25 +17,11 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#include "../system.h" +#ifndef __UPNP_H__ +#define __UPNP_H__ -#include "../ecdsagen.h" -#include "../utils.h" -#include "../xalloc.h" +#include "system.h" -// Generate ECDSA key +extern void upnp_init(bool, bool); -ecdsa_t *ecdsa_generate(void) { - logger(DEBUG_ALWAYS, LOG_ERR, "EC support using libgcrypt not implemented"); - return NULL; -} - -// Write PEM ECDSA keys - -bool ecdsa_write_pem_public_key(ecdsa_t *ecdsa, FILE *fp) { - return false; -} - -bool ecdsa_write_pem_private_key(ecdsa_t *ecdsa, FILE *fp) { - return false; -} +#endif diff --git a/src/utils.c b/src/utils.c index 65ba4b9..fadfd05 100644 --- a/src/utils.c +++ b/src/utils.c @@ -158,7 +158,7 @@ int b64encode_urlsafe(const void *src, char *dst, int length) { const char *winerror(int err) { static char buf[1024], *ptr; - ptr = buf + sprintf(buf, "(%d) ", err); + ptr = buf + snprintf(buf, sizeof buf, "(%d) ", err); if (!FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), ptr, sizeof(buf) - (ptr - buf), NULL)) { @@ -191,6 +191,22 @@ bool check_id(const char *id) { return true; } +bool check_netname(const char *netname, bool strict) { + if(!netname || !*netname || *netname == '.') + return false; + + for(const char *c = netname; *c; c++) { + if(iscntrl(*c)) + return false; + if(*c == '/' || *c == '\\') + return false; + if(strict && strchr(" $%<>:`\"|?*", *c)) + return false; + } + + return true; +} + /* Windows doesn't define HOST_NAME_MAX. */ #ifndef HOST_NAME_MAX #define HOST_NAME_MAX 255 diff --git a/src/utils.h b/src/utils.h index c3364ce..5c387bd 100644 --- a/src/utils.h +++ b/src/utils.h @@ -51,6 +51,7 @@ extern const char *winerror(int); extern unsigned int bitfield_to_int(const void *bitfield, size_t size); extern bool check_id(const char *); +extern bool check_netname(const char *, bool strict); char *replace_name(const char *name); #endif /* __TINC_UTILS_H__ */ diff --git a/src/version.c b/src/version.c index fc62c8a..325a6f0 100644 --- a/src/version.c +++ b/src/version.c @@ -18,7 +18,14 @@ */ #include "version.h" +#include "version_git.h" +#include "../config.h" /* This file is always rebuilt (even if there are no changes) so that the following is updated */ const char* const BUILD_DATE = __DATE__; const char* const BUILD_TIME = __TIME__; +#ifdef GIT_DESCRIPTION +const char* const BUILD_VERSION = GIT_DESCRIPTION; +#else +const char* const BUILD_VERSION = VERSION; +#endif diff --git a/src/version.h b/src/version.h index d3e4a1f..9cbecb6 100644 --- a/src/version.h +++ b/src/version.h @@ -22,5 +22,6 @@ extern const char* const BUILD_DATE; extern const char* const BUILD_TIME; +extern const char* const BUILD_VERSION; #endif /* __TINC_VERSION_H__ */ diff --git a/systemd/Makefile.am b/systemd/Makefile.am new file mode 100644 index 0000000..a1bfe12 --- /dev/null +++ b/systemd/Makefile.am @@ -0,0 +1,4 @@ +if WITH_SYSTEMD +systemddir = @systemd_path@ +dist_systemd_DATA = tinc.service tinc@.service +endif diff --git a/m4/Makefile.in b/systemd/Makefile.in similarity index 73% rename from m4/Makefile.in rename to systemd/Makefile.in index 4097869..4bc2d27 100644 --- a/m4/Makefile.in +++ b/systemd/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.14.1 from Makefile.am. +# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2013 Free Software Foundation, Inc. +# Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -13,8 +13,19 @@ # PARTICULAR PURPOSE. @SET_MAKE@ + VPATH = @srcdir@ -am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ @@ -77,18 +88,19 @@ PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ -subdir = m4 -DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am README +subdir = systemd ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \ $(top_srcdir)/m4/ax_check_compile_flag.m4 \ $(top_srcdir)/m4/ax_check_link_flag.m4 \ $(top_srcdir)/m4/curses.m4 $(top_srcdir)/m4/libgcrypt.m4 \ - $(top_srcdir)/m4/lzo.m4 $(top_srcdir)/m4/openssl.m4 \ - $(top_srcdir)/m4/readline.m4 $(top_srcdir)/m4/zlib.m4 \ - $(top_srcdir)/configure.ac + $(top_srcdir)/m4/lzo.m4 $(top_srcdir)/m4/miniupnpc.m4 \ + $(top_srcdir)/m4/openssl.m4 $(top_srcdir)/m4/readline.m4 \ + $(top_srcdir)/m4/zlib.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__dist_systemd_DATA_DIST) \ + $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = @@ -112,7 +124,38 @@ am__can_run_installinfo = \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac +am__dist_systemd_DATA_DIST = tinc.service tinc@.service +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(systemddir)" +DATA = $(dist_systemd_DATA) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ @@ -147,6 +190,7 @@ LIBS = @LIBS@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ +MINIUPNPC_LIBS = @MINIUPNPC_LIBS@ MKDIR_P = @MKDIR_P@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ @@ -204,15 +248,18 @@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ +runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ +systemd_path = @systemd_path@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ -EXTRA_DIST = README *.m4 +@WITH_SYSTEMD_TRUE@systemddir = @systemd_path@ +@WITH_SYSTEMD_TRUE@dist_systemd_DATA = tinc.service tinc@.service all: all-am .SUFFIXES: @@ -225,10 +272,9 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) exit 1;; \ esac; \ done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu m4/Makefile'; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu systemd/Makefile'; \ $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --gnu m4/Makefile -.PRECIOUS: Makefile + $(AUTOMAKE) --gnu systemd/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ @@ -246,6 +292,27 @@ $(top_srcdir)/configure: $(am__configure_deps) $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): +install-dist_systemdDATA: $(dist_systemd_DATA) + @$(NORMAL_INSTALL) + @list='$(dist_systemd_DATA)'; test -n "$(systemddir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(systemddir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(systemddir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(systemddir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(systemddir)" || exit $$?; \ + done + +uninstall-dist_systemdDATA: + @$(NORMAL_UNINSTALL) + @list='$(dist_systemd_DATA)'; test -n "$(systemddir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(systemddir)'; $(am__uninstall_files_from_dir) tags TAGS: ctags CTAGS: @@ -285,8 +352,11 @@ distdir: $(DISTFILES) done check-am: all-am check: check-am -all-am: Makefile +all-am: Makefile $(DATA) installdirs: + for dir in "$(DESTDIR)$(systemddir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done install: install-am install-exec: install-exec-am install-data: install-data-am @@ -337,7 +407,7 @@ info: info-am info-am: -install-data-am: +install-data-am: install-dist_systemdDATA install-dvi: install-dvi-am @@ -381,20 +451,23 @@ ps: ps-am ps-am: -uninstall-am: +uninstall-am: uninstall-dist_systemdDATA .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic cscopelist-am \ ctags-am distclean distclean-generic distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ - install-data-am install-dvi install-dvi-am install-exec \ - install-exec-am install-html install-html-am install-info \ - install-info-am install-man install-pdf install-pdf-am \ - install-ps install-ps-am install-strip installcheck \ - installcheck-am installdirs maintainer-clean \ - maintainer-clean-generic mostlyclean mostlyclean-generic pdf \ - pdf-am ps ps-am tags-am uninstall uninstall-am + install-data-am install-dist_systemdDATA install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-generic pdf pdf-am ps ps-am tags-am uninstall \ + uninstall-am uninstall-dist_systemdDATA + +.PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. diff --git a/systemd/tinc.service b/systemd/tinc.service new file mode 100644 index 0000000..d911fa7 --- /dev/null +++ b/systemd/tinc.service @@ -0,0 +1,20 @@ +# This is a mostly empty service, but allows commands like stop, start, reload +# to propagate to all tinc@ service instances. + +[Unit] +Description=Tinc VPN +Documentation=info:tinc +Documentation=man:tinc(8) man:tinc.conf(5) +Documentation=http://tinc-vpn.org/docs/ +After=network.target +Wants=network.target + +[Service] +Type=oneshot +RemainAfterExit=yes +ExecStart=/bin/true +ExecReload=/bin/true +WorkingDirectory=/etc/tinc + +[Install] +WantedBy=multi-user.target diff --git a/systemd/tinc@.service b/systemd/tinc@.service new file mode 100644 index 0000000..78ef25b --- /dev/null +++ b/systemd/tinc@.service @@ -0,0 +1,19 @@ +[Unit] +Description=Tinc net %i +Documentation=info:tinc +Documentation=man:tinc(8) man:tinc.conf(5) +Documentation=http://tinc-vpn.org/docs/ +PartOf=tinc.service +ReloadPropagatedFrom=tinc.service + +[Service] +Type=simple +WorkingDirectory=/etc/tinc/%i +ExecStart=/usr/sbin/tincd -n %i -D +ExecReload=/usr/sbin/tinc -n %i reload +Restart=on-failure +RestartSec=5 +TimeoutStopSec=5 + +[Install] +WantedBy=tinc.service diff --git a/test-driver b/test-driver index d306056..8e575b0 100755 --- a/test-driver +++ b/test-driver @@ -3,7 +3,7 @@ scriptversion=2013-07-13.22; # UTC -# Copyright (C) 2011-2013 Free Software Foundation, Inc. +# Copyright (C) 2011-2014 Free Software Foundation, Inc. # # 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 @@ -106,11 +106,14 @@ trap "st=143; $do_exit" 15 # Test script is run here. "$@" >$log_file 2>&1 estatus=$? + if test $enable_hard_errors = no && test $estatus -eq 99; then - estatus=1 + tweaked_estatus=1 +else + tweaked_estatus=$estatus fi -case $estatus:$expect_failure in +case $tweaked_estatus:$expect_failure in 0:yes) col=$red res=XPASS recheck=yes gcopy=yes;; 0:*) col=$grn res=PASS recheck=no gcopy=no;; 77:*) col=$blu res=SKIP recheck=no gcopy=yes;; @@ -119,6 +122,12 @@ case $estatus:$expect_failure in *:*) col=$red res=FAIL recheck=yes gcopy=yes;; esac +# Report the test outcome and exit status in the logs, so that one can +# know whether the test passed or failed simply by looking at the '.log' +# file, without the need of also peaking into the corresponding '.trs' +# file (automake bug#11814). +echo "$res $test_name (exit status: $estatus)" >>$log_file + # Report outcome to console. echo "${col}${res}${std}: $test_name" diff --git a/test/Makefile.am b/test/Makefile.am index 5457b2f..df8e2c3 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -4,6 +4,7 @@ TESTS = \ executables.test \ import-export.test \ invite-join.test \ + invite-tinc-up.test \ ns-ping.test \ ping.test \ sptps-basic.test \ diff --git a/test/Makefile.in b/test/Makefile.in index cdea11e..885674d 100644 --- a/test/Makefile.in +++ b/test/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.14.1 from Makefile.am. +# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2013 Free Software Foundation, Inc. +# Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -14,7 +14,17 @@ @SET_MAKE@ VPATH = @srcdir@ -am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ @@ -79,19 +89,18 @@ build_triplet = @build@ host_triplet = @host@ check_PROGRAMS = pong$(EXEEXT) subdir = test -DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ - $(dist_check_SCRIPTS) $(top_srcdir)/depcomp \ - $(top_srcdir)/test-driver ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \ $(top_srcdir)/m4/ax_check_compile_flag.m4 \ $(top_srcdir)/m4/ax_check_link_flag.m4 \ $(top_srcdir)/m4/curses.m4 $(top_srcdir)/m4/libgcrypt.m4 \ - $(top_srcdir)/m4/lzo.m4 $(top_srcdir)/m4/openssl.m4 \ - $(top_srcdir)/m4/readline.m4 $(top_srcdir)/m4/zlib.m4 \ - $(top_srcdir)/configure.ac + $(top_srcdir)/m4/lzo.m4 $(top_srcdir)/m4/miniupnpc.m4 \ + $(top_srcdir)/m4/openssl.m4 $(top_srcdir)/m4/readline.m4 \ + $(top_srcdir)/m4/zlib.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(dist_check_SCRIPTS) \ + $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = @@ -111,7 +120,7 @@ AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = -DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +DEFAULT_INCLUDES = depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f @@ -355,6 +364,8 @@ am__set_b = \ *) \ b='$*';; \ esac +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp \ + $(top_srcdir)/test-driver DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ @@ -389,6 +400,7 @@ LIBS = @LIBS@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ +MINIUPNPC_LIBS = @MINIUPNPC_LIBS@ MKDIR_P = @MKDIR_P@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ @@ -446,10 +458,12 @@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ +runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ +systemd_path = @systemd_path@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ @@ -460,6 +474,7 @@ TESTS = \ executables.test \ import-export.test \ invite-join.test \ + invite-tinc-up.test \ ns-ping.test \ ping.test \ sptps-basic.test \ @@ -484,7 +499,6 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu test/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu test/Makefile -.PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ @@ -616,7 +630,7 @@ $(TEST_SUITE_LOG): $(TEST_LOGS) if test -n "$$am__remaking_logs"; then \ echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \ "recursion detected" >&2; \ - else \ + elif test -n "$$redo_logs"; then \ am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \ fi; \ if $(am__make_dryrun); then :; else \ @@ -896,6 +910,8 @@ uninstall-am: mostlyclean-compile mostlyclean-generic pdf pdf-am ps ps-am \ recheck tags tags-am uninstall uninstall-am +.PRECIOUS: Makefile + clean-local: -for pid in *.test.?/pid; do ../src/tinc --pidfile="$$pid" stop; done diff --git a/test/invite-join.test b/test/invite-join.test index dbe6f8a..c1bd1b8 100755 --- a/test/invite-join.test +++ b/test/invite-join.test @@ -24,7 +24,7 @@ $tinc $c1 invite bar | $tinc $c2 join # Test equivalence of host config files cmp $d1/hosts/foo $d2/hosts/foo -test "`grep ^ECDSAPublicKey $d1/hosts/bar`" = "`grep ^ECDSAPublicKey $d2/hosts/bar`" +test "`grep ^Ed25519PublicKey $d1/hosts/bar`" = "`grep ^Ed25519PublicKey $d2/hosts/bar`" # Test Mode, Broadcast and ConnectTo statements diff --git a/test/invite-tinc-up.test b/test/invite-tinc-up.test new file mode 100755 index 0000000..bc5d45b --- /dev/null +++ b/test/invite-tinc-up.test @@ -0,0 +1,51 @@ +#!/bin/sh + +. ./testlib.sh + +# Initialize one node + +$tinc $c1 <$d1/invitation-created <\$INVITATION_FILE +echo Ifconfig = 93.184.216.34/24 >>\$INVITATION_FILE +echo Route = 2606:2800:220:1::/64 2606:2800:220:1:248:1893:25c8:1946 >>\$INVITATION_FILE +echo Route = 1.2.3.4 1234:: >>\$INVITATION_FILE +$tinc $c1 export >>\$INVITATION_FILE +EOF + +chmod u+x $d1/invitation-created + +$tinc $c1 invite bar | $tinc $c2 --batch join + +# Test equivalence of host config files + +cmp $d1/hosts/foo $d2/hosts/foo +test "`grep ^Ed25519PublicKey $d1/hosts/bar`" = "`grep ^Ed25519PublicKey $d2/hosts/bar`" + +# Check if the tinc-up.invitation file is created and contains the right commands + +test -f $d2/tinc-up.invitation + +fgrep -q "93.184.216.34/24" $d2/tinc-up.invitation +fgrep -q "2606:2800:220:1::/64" $d2/tinc-up.invitation +fgrep -q "2606:2800:220:1:248:1893:25c8:1946" $d2/tinc-up.invitation +fgrep -q "1234::" $d2/tinc-up.invitation && exit 1 + +# Check that no tinc-up is created and that tinc-up.invitation is not executable + +test -x $d2/tinc-up.invitation && exit 1 +test -f $d2/tinc-up && exit 1 + +$tinc $c1 stop diff --git a/test/variables.test b/test/variables.test index 4cf9d5e..5fe6046 100755 --- a/test/variables.test +++ b/test/variables.test @@ -38,7 +38,6 @@ $tinc $c1 add Subnet 2 $tinc $c1 add Subnet 3 test "`$tinc $c1 get Subnet`" = "1 2 -2 3" $tinc $c1 del Subnet 2 test "`$tinc $c1 get Subnet`" = "1 @@ -65,7 +64,6 @@ $tinc $c1 add bar.Subnet 2 $tinc $c1 add bar.Subnet 3 test "`$tinc $c1 get bar.Subnet`" = "1 2 -2 3" $tinc $c1 del bar.Subnet 2 test "`$tinc $c1 get bar.Subnet`" = "1 From 87cef224214649a6272bc7d1ce89afeb0e9eb385 Mon Sep 17 00:00:00 2001 From: Guus Sliepen Date: Mon, 26 Aug 2019 13:44:52 +0200 Subject: [PATCH 10/13] Import Upstream version 1.1~pre14-16-g15b868e --- ChangeLog | 16 +++++ Makefile.in | 3 + NEWS | 12 +++- README | 4 +- THANKS | 1 - aclocal.m4 | 3 + config.guess | 111 ++++++++++++++++------------- config.h.in | 16 ++++- config.sub | 20 +++--- configure | 118 ++++++++++++++++++++++++++++--- configure.ac | 2 + doc/Makefile.in | 3 + doc/sample-config.tar.gz | Bin 1237 -> 1228 bytes gui/Makefile.in | 3 + m4/ax_append_flag.m4 | 71 +++++++++++++++++++ m4/ax_cflags_warn_all.m4 | 122 ++++++++++++++++++++++++++++++++ m4/ax_require_defined.m4 | 37 ++++++++++ m4/openssl.m4 | 4 +- src/Makefile.in | 3 + src/bsd/device.c | 10 +-- src/bsd/tunemu.c | 2 +- src/dropin.c | 1 + src/logger.c | 8 ++- src/net.c | 147 ++++++++++++++++++++++++++++----------- src/net.h | 1 - src/net_packet.c | 12 ++-- src/net_setup.c | 100 +++++++++----------------- src/net_socket.c | 2 + src/netutl.c | 19 +++++ src/netutl.h | 1 + src/node.h | 3 +- src/openssl/cipher.c | 40 ++++++----- src/openssl/digest.c | 19 +++-- src/openssl/rsa.c | 41 ++++++++--- src/openssl/rsagen.c | 38 +++++++++- src/protocol.c | 5 +- src/protocol_auth.c | 14 ++-- src/sptps.c | 2 - src/tincctl.c | 19 ++++- systemd/Makefile.in | 3 + test/Makefile.in | 3 + 41 files changed, 783 insertions(+), 256 deletions(-) create mode 100644 m4/ax_append_flag.m4 create mode 100644 m4/ax_cflags_warn_all.m4 create mode 100644 m4/ax_require_defined.m4 diff --git a/ChangeLog b/ChangeLog index 40b3bfb..29e545f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,19 @@ +Version 1.1pre14 May 01 2016 +------------------------------------------------------------------------ + +Guus Sliepen (2): + Revert "Remove tinc.service, it is not necessary." + Releasing 1.1pre14. + +Version 1.1pre13 April 30 2016 +------------------------------------------------------------------------ + +Guus Sliepen (4): + Fix BSD tun device support. + Remove tinc.service, it is not necessary. + AutoConnect now only chooses from nodes for which we know an address. + Releasing 1.1pre13. + Version 1.1pre12 April 24 2016 ------------------------------------------------------------------------ diff --git a/Makefile.in b/Makefile.in index f5f609a..cd24b01 100644 --- a/Makefile.in +++ b/Makefile.in @@ -90,8 +90,11 @@ host_triplet = @host@ subdir = . ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \ + $(top_srcdir)/m4/ax_append_flag.m4 \ + $(top_srcdir)/m4/ax_cflags_warn_all.m4 \ $(top_srcdir)/m4/ax_check_compile_flag.m4 \ $(top_srcdir)/m4/ax_check_link_flag.m4 \ + $(top_srcdir)/m4/ax_require_defined.m4 \ $(top_srcdir)/m4/curses.m4 $(top_srcdir)/m4/libgcrypt.m4 \ $(top_srcdir)/m4/lzo.m4 $(top_srcdir)/m4/miniupnpc.m4 \ $(top_srcdir)/m4/openssl.m4 $(top_srcdir)/m4/readline.m4 \ diff --git a/NEWS b/NEWS index bedca1c..674227e 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,13 @@ +# Version 1.1pre13 May 1 2016 + +* Add tinc.service back. + +# Version 1.1pre13 April 30 2016 + +* Fix BSD tun device support that was broken in 1.1pre12. +* Speed up AutoConnect when there are many host config files present without + an Address. + # Version 1.1pre12 April 24 2016 * Added a "--syslog" option to force logging to syslog even if running in the @@ -21,7 +31,7 @@ * Initial support for generating a tinc-up script from an invitation. * Many small fixes, documentation updates. -Thanks to Etienne Dechamps, thorkill, Vittorio Gambaletta, Martin Weinelt, +Thanks to Etienne Dechamps, Rafał Leśniak, Vittorio Gambaletta, Martin Weinelt, Sven-Haegar Koch, Florian Klink, LunnarShadow, Dato Simó, Jo-Philipp Wich, Jochen Voss, Nathan Stratton Treadway, Pierre Emeriaud, xentec, Samuel Thibault and Michael Tokarev for their contributions to this version of tinc. diff --git a/README b/README index a44853a..9b29f2c 100644 --- a/README +++ b/README @@ -1,4 +1,4 @@ -This is the README file for tinc version 1.1pre12. Installation +This is the README file for tinc version 1.1pre14. Installation instructions may be found in the INSTALL file. tinc is Copyright © 1998-2016 Ivo Timmermans, Guus Sliepen , and others. @@ -32,7 +32,7 @@ at your own risk. Compatibility ------------- -Version 1.1pre12 is compatible with 1.0pre8, 1.0 and later, but not with older +Version 1.1pre14 is compatible with 1.0pre8, 1.0 and later, but not with older versions of tinc. When the ExperimentalProtocol option is used, tinc is still compatible with diff --git a/THANKS b/THANKS index 527cc61..dfb0365 100644 --- a/THANKS +++ b/THANKS @@ -84,7 +84,6 @@ We would like to thank the following people for their contributions to tinc: * Sven-Haegar Koch * Teemu Kiviniemi * Thomas Tsiakalakis -* thorkill * Timothy Redaelli * Tomasz Fortuna * Tomislav Čohar diff --git a/aclocal.m4 b/aclocal.m4 index 8d101b4..005ea6d 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -1151,8 +1151,11 @@ AC_SUBST([am__untar]) ]) # _AM_PROG_TAR m4_include([m4/attribute.m4]) +m4_include([m4/ax_append_flag.m4]) +m4_include([m4/ax_cflags_warn_all.m4]) m4_include([m4/ax_check_compile_flag.m4]) m4_include([m4/ax_check_link_flag.m4]) +m4_include([m4/ax_require_defined.m4]) m4_include([m4/curses.m4]) m4_include([m4/libgcrypt.m4]) m4_include([m4/lzo.m4]) diff --git a/config.guess b/config.guess index 1659250..0967f2a 100755 --- a/config.guess +++ b/config.guess @@ -1,8 +1,8 @@ #! /bin/sh # Attempt to guess a canonical system name. -# Copyright 1992-2015 Free Software Foundation, Inc. +# Copyright 1992-2016 Free Software Foundation, Inc. -timestamp='2015-08-20' +timestamp='2016-04-02' # 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,7 +27,7 @@ timestamp='2015-08-20' # Originally written by Per Bothner; maintained since 2000 by Ben Elliston. # # 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 +# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess # # Please send patches to . @@ -50,7 +50,7 @@ version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. -Copyright 1992-2015 Free Software Foundation, Inc. +Copyright 1992-2016 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." @@ -237,6 +237,10 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} exit ;; + *:LibertyBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'` + echo ${UNAME_MACHINE_ARCH}-unknown-libertybsd${UNAME_RELEASE} + exit ;; *:ekkoBSD:*:*) echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} exit ;; @@ -268,42 +272,42 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` case "$ALPHA_CPU_TYPE" in "EV4 (21064)") - UNAME_MACHINE="alpha" ;; + UNAME_MACHINE=alpha ;; "EV4.5 (21064)") - UNAME_MACHINE="alpha" ;; + UNAME_MACHINE=alpha ;; "LCA4 (21066/21068)") - UNAME_MACHINE="alpha" ;; + UNAME_MACHINE=alpha ;; "EV5 (21164)") - UNAME_MACHINE="alphaev5" ;; + UNAME_MACHINE=alphaev5 ;; "EV5.6 (21164A)") - UNAME_MACHINE="alphaev56" ;; + UNAME_MACHINE=alphaev56 ;; "EV5.6 (21164PC)") - UNAME_MACHINE="alphapca56" ;; + UNAME_MACHINE=alphapca56 ;; "EV5.7 (21164PC)") - UNAME_MACHINE="alphapca57" ;; + UNAME_MACHINE=alphapca57 ;; "EV6 (21264)") - UNAME_MACHINE="alphaev6" ;; + UNAME_MACHINE=alphaev6 ;; "EV6.7 (21264A)") - UNAME_MACHINE="alphaev67" ;; + UNAME_MACHINE=alphaev67 ;; "EV6.8CB (21264C)") - UNAME_MACHINE="alphaev68" ;; + UNAME_MACHINE=alphaev68 ;; "EV6.8AL (21264B)") - UNAME_MACHINE="alphaev68" ;; + UNAME_MACHINE=alphaev68 ;; "EV6.8CX (21264D)") - UNAME_MACHINE="alphaev68" ;; + UNAME_MACHINE=alphaev68 ;; "EV6.9A (21264/EV69A)") - UNAME_MACHINE="alphaev69" ;; + UNAME_MACHINE=alphaev69 ;; "EV7 (21364)") - UNAME_MACHINE="alphaev7" ;; + UNAME_MACHINE=alphaev7 ;; "EV7.9 (21364A)") - UNAME_MACHINE="alphaev79" ;; + UNAME_MACHINE=alphaev79 ;; esac # A Pn.n version is a patched version. # A Vn.n version is a released version. # A Tn.n version is a released field test version. # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. - echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` # Reset EXIT trap before exiting to avoid spurious non-zero exit code. exitcode=$? trap '' 0 @@ -376,16 +380,16 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in exit ;; i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) eval $set_cc_for_build - SUN_ARCH="i386" + SUN_ARCH=i386 # If there is a compiler, see if it is configured for 64-bit objects. # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. # This test works for both compilers. - if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then + if [ "$CC_FOR_BUILD" != no_compiler_found ]; then if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ - (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ + (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then - SUN_ARCH="x86_64" + SUN_ARCH=x86_64 fi fi echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` @@ -410,7 +414,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in exit ;; sun*:*:4.2BSD:*) UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` - test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 + test "x${UNAME_RELEASE}" = x && UNAME_RELEASE=3 case "`/bin/arch`" in sun3) echo m68k-sun-sunos${UNAME_RELEASE} @@ -635,13 +639,13 @@ EOF sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` case "${sc_cpu_version}" in - 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 - 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 + 523) HP_ARCH=hppa1.0 ;; # CPU_PA_RISC1_0 + 528) HP_ARCH=hppa1.1 ;; # CPU_PA_RISC1_1 532) # CPU_PA_RISC2_0 case "${sc_kernel_bits}" in - 32) HP_ARCH="hppa2.0n" ;; - 64) HP_ARCH="hppa2.0w" ;; - '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 + 32) HP_ARCH=hppa2.0n ;; + 64) HP_ARCH=hppa2.0w ;; + '') HP_ARCH=hppa2.0 ;; # HP-UX 10.20 esac ;; esac fi @@ -680,11 +684,11 @@ EOF exit (0); } EOF - (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` + (CCOPTS="" $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` test -z "$HP_ARCH" && HP_ARCH=hppa fi ;; esac - if [ ${HP_ARCH} = "hppa2.0w" ] + if [ ${HP_ARCH} = hppa2.0w ] then eval $set_cc_for_build @@ -697,12 +701,12 @@ EOF # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess # => hppa64-hp-hpux11.23 - if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | + if echo __LP64__ | (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | grep -q __LP64__ then - HP_ARCH="hppa2.0w" + HP_ARCH=hppa2.0w else - HP_ARCH="hppa64" + HP_ARCH=hppa64 fi fi echo ${HP_ARCH}-hp-hpux${HPUX_REV} @@ -807,14 +811,14 @@ EOF echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) - FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` - FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_PROC=`uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` + FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; 5000:UNIX_System_V:4.*:*) - FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` - FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` + FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'` echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) @@ -896,7 +900,7 @@ EOF exit ;; *:GNU/*:*:*) # other systems with GNU libc and userland - echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC} + echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC} exit ;; i*86:Minix:*:*) echo ${UNAME_MACHINE}-pc-minix @@ -919,7 +923,7 @@ EOF EV68*) UNAME_MACHINE=alphaev68 ;; esac objdump --private-headers /bin/sh | grep -q ld.so.1 - if test "$?" = 0 ; then LIBC="gnulibc1" ; fi + if test "$?" = 0 ; then LIBC=gnulibc1 ; fi echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; arc:Linux:*:* | arceb:Linux:*:*) @@ -965,6 +969,9 @@ EOF ia64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; + k1om:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; m32r*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; @@ -1120,7 +1127,7 @@ EOF # uname -m prints for DJGPP always 'pc', but it prints nothing about # the processor, so we play safe by assuming i586. # Note: whatever this is, it MUST be the same as what config.sub - # prints for the "djgpp" host, or else GDB configury will decide that + # prints for the "djgpp" host, or else GDB configure will decide that # this is a cross-build. echo i586-pc-msdosdjgpp exit ;; @@ -1269,6 +1276,9 @@ EOF SX-8R:SUPER-UX:*:*) echo sx8r-nec-superux${UNAME_RELEASE} exit ;; + SX-ACE:SUPER-UX:*:*) + echo sxace-nec-superux${UNAME_RELEASE} + exit ;; Power*:Rhapsody:*:*) echo powerpc-apple-rhapsody${UNAME_RELEASE} exit ;; @@ -1282,9 +1292,9 @@ EOF UNAME_PROCESSOR=powerpc fi if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then - if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then + 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) | \ + (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then case $UNAME_PROCESSOR in @@ -1306,7 +1316,7 @@ EOF exit ;; *:procnto*:*:* | *:QNX:[0123456789]*:*) UNAME_PROCESSOR=`uname -p` - if test "$UNAME_PROCESSOR" = "x86"; then + if test "$UNAME_PROCESSOR" = x86; then UNAME_PROCESSOR=i386 UNAME_MACHINE=pc fi @@ -1337,7 +1347,7 @@ EOF # "uname -m" is not consistent, so use $cputype instead. 386 # is converted to i386 for consistency with other x86 # operating systems. - if test "$cputype" = "386"; then + if test "$cputype" = 386; then UNAME_MACHINE=i386 else UNAME_MACHINE="$cputype" @@ -1379,7 +1389,7 @@ EOF echo i386-pc-xenix exit ;; i*86:skyos:*:*) - echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' + echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE} | sed -e 's/ .*$//'` exit ;; i*86:rdos:*:*) echo ${UNAME_MACHINE}-pc-rdos @@ -1390,6 +1400,9 @@ EOF x86_64:VMkernel:*:*) echo ${UNAME_MACHINE}-unknown-esx exit ;; + amd64:Isilon\ OneFS:*:*) + echo x86_64-unknown-onefs + exit ;; esac cat >&2 < header file. */ #undef HAVE_RESOLV_H +/* Define to 1 if you have the `RSA_set0_key' function. */ +#undef HAVE_RSA_SET0_KEY + /* Solaris/SunOS */ #undef HAVE_SOLARIS diff --git a/config.sub b/config.sub index 1acc966..8d39c4b 100755 --- a/config.sub +++ b/config.sub @@ -1,8 +1,8 @@ #! /bin/sh # Configuration validation subroutine script. -# Copyright 1992-2015 Free Software Foundation, Inc. +# Copyright 1992-2016 Free Software Foundation, Inc. -timestamp='2015-08-20' +timestamp='2016-03-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 @@ -33,7 +33,7 @@ timestamp='2015-08-20' # 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 +# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub # This file is supposed to be the same for all GNU packages # and recognize all the CPU types, system types and aliases @@ -53,8 +53,7 @@ timestamp='2015-08-20' me=`echo "$0" | sed -e 's,.*/,,'` usage="\ -Usage: $0 [OPTION] CPU-MFR-OPSYS - $0 [OPTION] ALIAS +Usage: $0 [OPTION] CPU-MFR-OPSYS or ALIAS Canonicalize a configuration name. @@ -68,7 +67,7 @@ Report bugs and patches to ." version="\ GNU config.sub ($timestamp) -Copyright 1992-2015 Free Software Foundation, Inc. +Copyright 1992-2016 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." @@ -521,7 +520,7 @@ case $basic_machine in basic_machine=i386-pc os=-aros ;; - asmjs) + asmjs) basic_machine=asmjs-unknown ;; aux) @@ -1383,7 +1382,7 @@ case $os in | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ - | -bitrig* | -openbsd* | -solidbsd* \ + | -bitrig* | -openbsd* | -solidbsd* | -libertybsd* \ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ @@ -1399,7 +1398,8 @@ 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* | -es* | -tirtos*) + | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* \ + | -onefs* | -tirtos*) # Remember, each alternative MUST END IN *, to match a version number. ;; -qnx*) @@ -1531,6 +1531,8 @@ case $os in ;; -nacl*) ;; + -ios) + ;; -none) ;; *) diff --git a/configure b/configure index 61f340b..be77e27 100755 --- a/configure +++ b/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for tinc tinc-1.1pre12. +# Generated by GNU Autoconf 2.69 for tinc 1.1pre14-18-ge6497a2. # # # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. @@ -577,8 +577,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='tinc' PACKAGE_TARNAME='tinc' -PACKAGE_VERSION='tinc-1.1pre12' -PACKAGE_STRING='tinc tinc-1.1pre12' +PACKAGE_VERSION='1.1pre14-18-ge6497a2' +PACKAGE_STRING='tinc 1.1pre14-18-ge6497a2' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1346,7 +1346,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures tinc tinc-1.1pre12 to adapt to many kinds of systems. +\`configure' configures tinc 1.1pre14-18-ge6497a2 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1417,7 +1417,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of tinc tinc-1.1pre12:";; + short | recursive ) echo "Configuration of tinc 1.1pre14-18-ge6497a2:";; esac cat <<\_ACEOF @@ -1556,7 +1556,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -tinc configure tinc-1.1pre12 +tinc configure 1.1pre14-18-ge6497a2 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -2021,7 +2021,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by tinc $as_me tinc-1.1pre12, which was +It was created by tinc $as_me 1.1pre14-18-ge6497a2, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -4256,7 +4256,7 @@ fi # Define the identity of the package. PACKAGE='tinc' - VERSION='tinc-1.1pre12' + VERSION='1.1pre14-18-ge6497a2' cat >>confdefs.h <<_ACEOF @@ -5257,6 +5257,89 @@ if test -d /sw/lib; then : fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking CFLAGS for maximum warnings" >&5 +$as_echo_n "checking CFLAGS for maximum warnings... " >&6; } +if ${ac_cv_cflags_warn_all+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_cflags_warn_all="no, unknown" +ac_save_CFLAGS="$CFLAGS" +for ac_arg in "-warn all % -warn all" "-pedantic % -Wall" "-xstrconst % -v" "-std1 % -verbose -w0 -warnprotos" "-qlanglvl=ansi % -qsrcmsg -qinfo=all:noppt:noppc:noobs:nocnd" "-ansi -ansiE % -fullwarn" "+ESlit % +w1" "-Xc % -pvctl,fullmsg" "-h conform % -h msglevel 2" # +do CFLAGS="$ac_save_CFLAGS "`echo $ac_arg | sed -e 's,%%.*,,' -e 's,%,,'` + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_cflags_warn_all=`echo $ac_arg | sed -e 's,.*% *,,'` ; break +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +done +CFLAGS="$ac_save_CFLAGS" + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cflags_warn_all" >&5 +$as_echo "$ac_cv_cflags_warn_all" >&6; } + + +case ".$ac_cv_cflags_warn_all" in + .ok|.ok,*) ;; + .|.no|.no,*) ;; + *) +if ${CFLAGS+:} false; then : + + case " $CFLAGS " in #( + *" $ac_cv_cflags_warn_all "*) : + { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS already contains \$ac_cv_cflags_warn_all"; } >&5 + (: CFLAGS already contains $ac_cv_cflags_warn_all) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } ;; #( + *) : + + as_fn_append CFLAGS " $ac_cv_cflags_warn_all" + { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS=\"\$CFLAGS\""; } >&5 + (: CFLAGS="$CFLAGS") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + ;; +esac + +else + + CFLAGS=$ac_cv_cflags_warn_all + { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS=\"\$CFLAGS\""; } >&5 + (: CFLAGS="$CFLAGS") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + +fi + ;; +esac + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + # Check whether --enable-hardening was given. if test "${enable_hardening+set}" = set; then : enableval=$enable_hardening; @@ -6911,7 +6994,7 @@ else fi - for ac_func in RAND_status EVP_EncryptInit_ex + for ac_func in RAND_bytes EVP_EncryptInit_ex EVP_CIPHER_CTX_new do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" @@ -6945,6 +7028,19 @@ else fi + for ac_func in BN_GENCB_new ERR_remove_state RSA_set0_key +do : + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +if eval test \"x\$"$as_ac_var"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + fi @@ -7676,7 +7772,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by tinc $as_me tinc-1.1pre12, which was +This file was extended by tinc $as_me 1.1pre14-18-ge6497a2, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -7742,7 +7838,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -tinc config.status tinc-1.1pre12 +tinc config.status 1.1pre14-18-ge6497a2 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff --git a/configure.ac b/configure.ac index 4c0f926..1a032e6 100644 --- a/configure.ac +++ b/configure.ac @@ -140,6 +140,8 @@ AS_IF([test -d /sw/lib], [LIBS="$LIBS -L/sw/lib"]) dnl Compiler hardening flags dnl No -fstack-protector-all because it doesn't work on all platforms or architectures. +AX_CFLAGS_WARN_ALL(CFLAGS) + AC_ARG_ENABLE([hardening], AS_HELP_STRING([--disable-hardening], [disable compiler and linker hardening flags])) AS_IF([test "x$enable_hardening" != "xno"], [AX_CHECK_COMPILE_FLAG([-DFORTIFY_SOURCE=2], [CPPFLAGS="$CPPFLAGS -DFORTIFY_SOURCE=2"]) diff --git a/doc/Makefile.in b/doc/Makefile.in index 6f5c228..3f1feb6 100644 --- a/doc/Makefile.in +++ b/doc/Makefile.in @@ -89,8 +89,11 @@ host_triplet = @host@ subdir = doc ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \ + $(top_srcdir)/m4/ax_append_flag.m4 \ + $(top_srcdir)/m4/ax_cflags_warn_all.m4 \ $(top_srcdir)/m4/ax_check_compile_flag.m4 \ $(top_srcdir)/m4/ax_check_link_flag.m4 \ + $(top_srcdir)/m4/ax_require_defined.m4 \ $(top_srcdir)/m4/curses.m4 $(top_srcdir)/m4/libgcrypt.m4 \ $(top_srcdir)/m4/lzo.m4 $(top_srcdir)/m4/miniupnpc.m4 \ $(top_srcdir)/m4/openssl.m4 $(top_srcdir)/m4/readline.m4 \ diff --git a/doc/sample-config.tar.gz b/doc/sample-config.tar.gz index 474a24faa29edfa0dea435f349ce388aee203756..17863e9327946b62c55959b9bea0601529da8404 100644 GIT binary patch literal 1228 zcmV;-1T*^|iwFR|bm>9%M5X+Kc*=>P*$Xkn`T^7XYfPPvj ziMEMIq()M9{qJ{2%1xZOGltp5vgu$$vU#s0pNB`o%BtYqOv$mB^bU3+A<8fe=@|_Z z_Y9+c-#r^Sh@vP-`hz%%*%o8ad<_0#{Rc_(Wc}m8AUuFArm%Z?q3eGLBew&9mLB{zs5P@fNf?WQ zcRGh~H|3x?E8yw|Se|Qc45%^KsW4!L%$#ii=S)J%p*B2+bOFjvxqcWoLFcrwJ%K1b z4&vi}aGV5#A%(b6+RD02(PFGLpphztoKQlNXOxWz;DV1?U0A@dgCq$$WQ5M}om`CS zRB{WLHwK28(6+{uD=lWsa=@Xv()T#VoP$DTI7+cx8Lom(;{x-08wb(gO%MfPFYYhr zpsLeCWN^&1$nciW} z%<9f}Mzmdm-SI@9I3kGNy#41q5r(@Wiuk1x#VY+x|L__9!)Vare;;!A zs+S7cGt(8I8*UBMl>>-n736#-G9IALm4%6zaRUogyWz3sJXa-H1-Swy7YGvsBn{7* zv@jQT3c`}@XTzOIrnE+|f@CFcko7psy9PyEA~uyQIeM8fEm(?~{d9GGcX|8%^!(D{ z20@5{$zF@e)VoA;#CA#4R29r(fYKa6S|gmtm7>|;8s0hm1@gx*XPl)WMOnQRx%E)86 zn2DTt$Wx0!dnDVOkA*~H5T2`kz|pTdV(kBYJUtIROtj1xVx&X*hC$fy#B=-y^uEi-dH_+dC+5*!K4ql#rn1B3_5Qhd>f*h1iGOs8GY zVE6=#m`F4xz!|GWW{U-GM>I7Ip@)2dC#;-!45@lDb<9z+g<}swk%EFVk3@t4f`VSk zN-JU^Y&UY2ibB{0y!#o|e_Ij-F@ev@q7ogz88d`5!=(`xvHiVgaXhr9QMu)R)Iw7+ z*Q9X*?qa;O64G)_fOn|GG@Bm8F&@=_?k9_oi-A?`luCBbsYGpfF~%7!gt1(9mBeXz zXkyU%3rz#jM%}RHGD{|(bW9ZM7o4zVPgP>?Bm9!m6cE8;5w*;jBo06KQSKBLM6KJh zo=0@$T+c;OkVA6+sH5tkP7ifM=a^F}WQp(Z@gz7KT^ymlSE{8~8Y$#G;rGg~6_XcGt+digE3LHBN-M4W%jHi(!0#*oC;$Lcyk!3X literal 1237 zcmV;`1S3`2TG z!^AzqsNZ+bMh>DVN|OE{j^g+rjKXBlKY(O6;p|41i7cNlM9ic8w?by!T+QWHeb9Og z{$>B8sQ+aDgFgnfW>zTaN3boJmMI)Q0DfE!chaS{xMa-9U-17xYxa7D>KGUz1WDZ>k z{F`6Q?#I{U#8{?mjwkxW5kd6k?SJQqFx(YU z#4nX7*4+QVGYXf|$TZWl@O=aK;QF&2VXiMQs1*SsV|oX;g0cKef=5 z%r$A8fV&tkt%S5(6W|>xG0dh1ag0a#pZmok{`U4ki*;AF+`v||Kv;;)3m_#jeCW*t(y_Y+M2~q2| z%x8tJ+|+YX6f_}CztU0lP^X8wp_`afC}fH6@39h`jV_K*-z(M9D~%NLp73Yo&x*@N ziM~2TTtrfKx}SuszX5*ht=63jAJ@qv{r309Ey!d3*M|L#U28zi@b-Lc>i=-?3I895 z{ix;teF(NW%?-uVpTFl(&$jNe^0mcWE3LHBN-M3j(n>3>ykPkbfSE!n04M+ee^Frf diff --git a/gui/Makefile.in b/gui/Makefile.in index 2924e05..c81df2f 100644 --- a/gui/Makefile.in +++ b/gui/Makefile.in @@ -91,8 +91,11 @@ host_triplet = @host@ subdir = gui ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \ + $(top_srcdir)/m4/ax_append_flag.m4 \ + $(top_srcdir)/m4/ax_cflags_warn_all.m4 \ $(top_srcdir)/m4/ax_check_compile_flag.m4 \ $(top_srcdir)/m4/ax_check_link_flag.m4 \ + $(top_srcdir)/m4/ax_require_defined.m4 \ $(top_srcdir)/m4/curses.m4 $(top_srcdir)/m4/libgcrypt.m4 \ $(top_srcdir)/m4/lzo.m4 $(top_srcdir)/m4/miniupnpc.m4 \ $(top_srcdir)/m4/openssl.m4 $(top_srcdir)/m4/readline.m4 \ diff --git a/m4/ax_append_flag.m4 b/m4/ax_append_flag.m4 new file mode 100644 index 0000000..08f2e07 --- /dev/null +++ b/m4/ax_append_flag.m4 @@ -0,0 +1,71 @@ +# =========================================================================== +# http://www.gnu.org/software/autoconf-archive/ax_append_flag.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_APPEND_FLAG(FLAG, [FLAGS-VARIABLE]) +# +# DESCRIPTION +# +# FLAG is appended to the FLAGS-VARIABLE shell variable, with a space +# added in between. +# +# If FLAGS-VARIABLE is not specified, the current language's flags (e.g. +# CFLAGS) is used. FLAGS-VARIABLE is not changed if it already contains +# FLAG. If FLAGS-VARIABLE is unset in the shell, it is set to exactly +# FLAG. +# +# NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. +# +# LICENSE +# +# Copyright (c) 2008 Guido U. Draheim +# Copyright (c) 2011 Maarten Bosmans +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +# Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program. If not, see . +# +# As a special exception, the respective Autoconf Macro's copyright owner +# gives unlimited permission to copy, distribute and modify the configure +# scripts that are the output of Autoconf when processing the Macro. You +# need not follow the terms of the GNU General Public License when using +# or distributing such scripts, even though portions of the text of the +# Macro appear in them. The GNU General Public License (GPL) does govern +# all other use of the material that constitutes the Autoconf Macro. +# +# This special exception to the GPL applies to versions of the Autoconf +# Macro released by the Autoconf Archive. When you make and distribute a +# modified version of the Autoconf Macro, you may extend this special +# exception to the GPL to apply to your modified version as well. + +#serial 6 + +AC_DEFUN([AX_APPEND_FLAG], +[dnl +AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_SET_IF +AS_VAR_PUSHDEF([FLAGS], [m4_default($2,_AC_LANG_PREFIX[FLAGS])]) +AS_VAR_SET_IF(FLAGS,[ + AS_CASE([" AS_VAR_GET(FLAGS) "], + [*" $1 "*], [AC_RUN_LOG([: FLAGS already contains $1])], + [ + AS_VAR_APPEND(FLAGS,[" $1"]) + AC_RUN_LOG([: FLAGS="$FLAGS"]) + ]) + ], + [ + AS_VAR_SET(FLAGS,[$1]) + AC_RUN_LOG([: FLAGS="$FLAGS"]) + ]) +AS_VAR_POPDEF([FLAGS])dnl +])dnl AX_APPEND_FLAG diff --git a/m4/ax_cflags_warn_all.m4 b/m4/ax_cflags_warn_all.m4 new file mode 100644 index 0000000..1f07799 --- /dev/null +++ b/m4/ax_cflags_warn_all.m4 @@ -0,0 +1,122 @@ +# =========================================================================== +# http://www.gnu.org/software/autoconf-archive/ax_cflags_warn_all.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_CFLAGS_WARN_ALL [(shellvar [,default, [A/NA]])] +# AX_CXXFLAGS_WARN_ALL [(shellvar [,default, [A/NA]])] +# AX_FCFLAGS_WARN_ALL [(shellvar [,default, [A/NA]])] +# +# DESCRIPTION +# +# Try to find a compiler option that enables most reasonable warnings. +# +# For the GNU compiler it will be -Wall (and -ansi -pedantic) The result +# is added to the shellvar being CFLAGS, CXXFLAGS, or FCFLAGS by default. +# +# Currently this macro knows about the GCC, Solaris, Digital Unix, AIX, +# HP-UX, IRIX, NEC SX-5 (Super-UX 10), Cray J90 (Unicos 10.0.0.8), and +# Intel compilers. For a given compiler, the Fortran flags are much more +# experimental than their C equivalents. +# +# - $1 shell-variable-to-add-to : CFLAGS, CXXFLAGS, or FCFLAGS +# - $2 add-value-if-not-found : nothing +# - $3 action-if-found : add value to shellvariable +# - $4 action-if-not-found : nothing +# +# NOTE: These macros depend on AX_APPEND_FLAG. +# +# LICENSE +# +# Copyright (c) 2008 Guido U. Draheim +# Copyright (c) 2010 Rhys Ulerich +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation; either version 3 of the License, or (at your +# option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +# Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program. If not, see . +# +# As a special exception, the respective Autoconf Macro's copyright owner +# gives unlimited permission to copy, distribute and modify the configure +# scripts that are the output of Autoconf when processing the Macro. You +# need not follow the terms of the GNU General Public License when using +# or distributing such scripts, even though portions of the text of the +# Macro appear in them. The GNU General Public License (GPL) does govern +# all other use of the material that constitutes the Autoconf Macro. +# +# This special exception to the GPL applies to versions of the Autoconf +# Macro released by the Autoconf Archive. When you make and distribute a +# modified version of the Autoconf Macro, you may extend this special +# exception to the GPL to apply to your modified version as well. + +#serial 15 + +AC_DEFUN([AX_FLAGS_WARN_ALL],[dnl +AS_VAR_PUSHDEF([FLAGS],[_AC_LANG_PREFIX[]FLAGS])dnl +AS_VAR_PUSHDEF([VAR],[ac_cv_[]_AC_LANG_ABBREV[]flags_warn_all])dnl +AC_CACHE_CHECK([m4_ifval($1,$1,FLAGS) for maximum warnings], +VAR,[VAR="no, unknown" +ac_save_[]FLAGS="$[]FLAGS" +for ac_arg dnl +in "-warn all % -warn all" dnl Intel + "-pedantic % -Wall" dnl GCC + "-xstrconst % -v" dnl Solaris C + "-std1 % -verbose -w0 -warnprotos" dnl Digital Unix + "-qlanglvl=ansi % -qsrcmsg -qinfo=all:noppt:noppc:noobs:nocnd" dnl AIX + "-ansi -ansiE % -fullwarn" dnl IRIX + "+ESlit % +w1" dnl HP-UX C + "-Xc % -pvctl[,]fullmsg" dnl NEC SX-5 (Super-UX 10) + "-h conform % -h msglevel 2" dnl Cray C (Unicos) + # +do FLAGS="$ac_save_[]FLAGS "`echo $ac_arg | sed -e 's,%%.*,,' -e 's,%,,'` + AC_COMPILE_IFELSE([AC_LANG_PROGRAM], + [VAR=`echo $ac_arg | sed -e 's,.*% *,,'` ; break]) +done +FLAGS="$ac_save_[]FLAGS" +]) +AS_VAR_POPDEF([FLAGS])dnl +AX_REQUIRE_DEFINED([AX_APPEND_FLAG]) +case ".$VAR" in + .ok|.ok,*) m4_ifvaln($3,$3) ;; + .|.no|.no,*) m4_default($4,[m4_ifval($2,[AX_APPEND_FLAG([$2], [$1])])]) ;; + *) m4_default($3,[AX_APPEND_FLAG([$VAR], [$1])]) ;; +esac +AS_VAR_POPDEF([VAR])dnl +])dnl AX_FLAGS_WARN_ALL +dnl implementation tactics: +dnl the for-argument contains a list of options. The first part of +dnl these does only exist to detect the compiler - usually it is +dnl a global option to enable -ansi or -extrawarnings. All other +dnl compilers will fail about it. That was needed since a lot of +dnl compilers will give false positives for some option-syntax +dnl like -Woption or -Xoption as they think of it is a pass-through +dnl to later compile stages or something. The "%" is used as a +dnl delimiter. A non-option comment can be given after "%%" marks +dnl which will be shown but not added to the respective C/CXXFLAGS. + +AC_DEFUN([AX_CFLAGS_WARN_ALL],[dnl +AC_LANG_PUSH([C]) +AX_FLAGS_WARN_ALL([$1], [$2], [$3], [$4]) +AC_LANG_POP([C]) +]) + +AC_DEFUN([AX_CXXFLAGS_WARN_ALL],[dnl +AC_LANG_PUSH([C++]) +AX_FLAGS_WARN_ALL([$1], [$2], [$3], [$4]) +AC_LANG_POP([C++]) +]) + +AC_DEFUN([AX_FCFLAGS_WARN_ALL],[dnl +AC_LANG_PUSH([Fortran]) +AX_FLAGS_WARN_ALL([$1], [$2], [$3], [$4]) +AC_LANG_POP([Fortran]) +]) diff --git a/m4/ax_require_defined.m4 b/m4/ax_require_defined.m4 new file mode 100644 index 0000000..cae1111 --- /dev/null +++ b/m4/ax_require_defined.m4 @@ -0,0 +1,37 @@ +# =========================================================================== +# http://www.gnu.org/software/autoconf-archive/ax_require_defined.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_REQUIRE_DEFINED(MACRO) +# +# DESCRIPTION +# +# AX_REQUIRE_DEFINED is a simple helper for making sure other macros have +# been defined and thus are available for use. This avoids random issues +# where a macro isn't expanded. Instead the configure script emits a +# non-fatal: +# +# ./configure: line 1673: AX_CFLAGS_WARN_ALL: command not found +# +# It's like AC_REQUIRE except it doesn't expand the required macro. +# +# Here's an example: +# +# AX_REQUIRE_DEFINED([AX_CHECK_LINK_FLAG]) +# +# LICENSE +# +# Copyright (c) 2014 Mike Frysinger +# +# 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 any +# warranty. + +#serial 1 + +AC_DEFUN([AX_REQUIRE_DEFINED], [dnl + m4_ifndef([$1], [m4_fatal([macro ]$1[ is not defined; is a m4 file missing?])]) +])dnl AX_REQUIRE_DEFINED diff --git a/m4/openssl.m4 b/m4/openssl.m4 index 26cbcbe..6bb33cf 100644 --- a/m4/openssl.m4 +++ b/m4/openssl.m4 @@ -45,7 +45,7 @@ AC_DEFUN([tinc_OPENSSL], [AC_MSG_ERROR([LibreSSL/OpenSSL libraries not found.])] ) - AC_CHECK_FUNCS([RAND_status EVP_EncryptInit_ex], , + AC_CHECK_FUNCS([RAND_bytes EVP_EncryptInit_ex EVP_CIPHER_CTX_new], , [AC_MSG_ERROR([Missing LibreSSL/OpenSSL functionality, make sure you have installed the latest version.]); break], ) @@ -53,4 +53,6 @@ AC_DEFUN([tinc_OPENSSL], [AC_MSG_ERROR([Missing LibreSSL/OpenSSL functionality, make sure you have installed the latest version.]); break], [#include ] ) + + AC_CHECK_FUNCS([BN_GENCB_new ERR_remove_state RSA_set0_key], , , [#include ]) ]) diff --git a/src/Makefile.in b/src/Makefile.in index da3ca9f..6d5a8ce 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -196,8 +196,11 @@ sbin_PROGRAMS = tincd$(EXEEXT) tinc$(EXEEXT) sptps_test$(EXEEXT) \ subdir = src ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \ + $(top_srcdir)/m4/ax_append_flag.m4 \ + $(top_srcdir)/m4/ax_cflags_warn_all.m4 \ $(top_srcdir)/m4/ax_check_compile_flag.m4 \ $(top_srcdir)/m4/ax_check_link_flag.m4 \ + $(top_srcdir)/m4/ax_require_defined.m4 \ $(top_srcdir)/m4/curses.m4 $(top_srcdir)/m4/libgcrypt.m4 \ $(top_srcdir)/m4/lzo.m4 $(top_srcdir)/m4/miniupnpc.m4 \ $(top_srcdir)/m4/openssl.m4 $(top_srcdir)/m4/readline.m4 \ diff --git a/src/bsd/device.c b/src/bsd/device.c index 0d41c96..5428262 100644 --- a/src/bsd/device.c +++ b/src/bsd/device.c @@ -349,13 +349,13 @@ static bool read_packet(vpn_packet_t *packet) { case DEVICE_TYPE_UTUN: case DEVICE_TYPE_TUNIFHEAD: { - if((inlen = read(device_fd, packet->data + 10, MTU - 10)) <= 0) { + if((inlen = read(device_fd, DATA(packet) + 10, MTU - 10)) <= 0) { logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info, device, strerror(errno)); return false; } - switch (packet->data[14] >> 4) { + switch (DATA(packet)[14] >> 4) { case 4: DATA(packet)[12] = 0x08; DATA(packet)[13] = 0x00; @@ -369,7 +369,7 @@ static bool read_packet(vpn_packet_t *packet) { default: logger(DEBUG_TRAFFIC, LOG_ERR, "Unknown IP version %d while reading packet from %s %s", - packet->data[14] >> 4, device_info, device); + DATA(packet)[14] >> 4, device_info, device); return false; } @@ -430,9 +430,9 @@ static bool write_packet(vpn_packet_t *packet) { return false; } - memcpy(packet->data + 10, &type, sizeof type); + memcpy(DATA(packet) + 10, &type, sizeof type); - if(write(device_fd, packet->data + 10, packet->len - 10) < 0) { + if(write(device_fd, DATA(packet) + 10, packet->len - 10) < 0) { logger(DEBUG_ALWAYS, LOG_ERR, "Can't write to %s %s: %s", device_info, device, strerror(errno)); return false; diff --git a/src/bsd/tunemu.c b/src/bsd/tunemu.c index 1ce9007..d2b9f3d 100644 --- a/src/bsd/tunemu.c +++ b/src/bsd/tunemu.c @@ -87,7 +87,7 @@ static void tun_error(char *format, ...) { va_list vl; va_start(vl, format); - vsnprintf(tunemu_error, ERROR_BUFFER_SIZE, format, vl); + vsnprintf(tunemu_error, sizeof tunemu_error, format, vl); va_end(vl); } diff --git a/src/dropin.c b/src/dropin.c index fe3b7ef..c7b558a 100644 --- a/src/dropin.c +++ b/src/dropin.c @@ -106,6 +106,7 @@ int vasprintf(char **buf, const char *fmt, va_list ap) { va_copy(aq, ap); status = vsnprintf(*buf, len, fmt, aq); + buf[len - 1] = 0; va_end(aq); if(status >= 0) diff --git a/src/logger.c b/src/logger.c index e46d926..6028e3d 100644 --- a/src/logger.c +++ b/src/logger.c @@ -110,20 +110,22 @@ void logger(int level, int priority, const char *format, ...) { va_start(ap, format); int len = vsnprintf(message, sizeof message, format, ap); + message[sizeof message - 1] = 0; va_end(ap); - if(len > 0 && len < sizeof message && message[len - 1] == '\n') + if(len > 0 && len < sizeof message - 1 && message[len - 1] == '\n') message[len - 1] = 0; real_logger(level, priority, message); } static void sptps_logger(sptps_t *s, int s_errno, const char *format, va_list ap) { - char message[1024] = ""; + char message[1024]; size_t msglen = sizeof message; int len = vsnprintf(message, msglen, format, ap); - if(len > 0 && len < sizeof message) { + message[sizeof message - 1] = 0; + if(len > 0 && len < sizeof message - 1) { if(message[len - 1] == '\n') message[--len] = 0; diff --git a/src/net.c b/src/net.c index 8328db9..4369ff4 100644 --- a/src/net.c +++ b/src/net.c @@ -42,6 +42,7 @@ static int sleeptime = 10; time_t last_config_check = 0; static timeout_t pingtimer; static timeout_t periodictimer; +static struct timeval last_periodic_run_time; /* Purge edges and subnets of unreachable nodes. Use carefully. */ @@ -93,29 +94,31 @@ void purge(void) { void terminate_connection(connection_t *c, bool report) { logger(DEBUG_CONNECTIONS, LOG_NOTICE, "Closing connection with %s (%s)", c->name, c->hostname); - if(c->node && c->node->connection == c) - c->node->connection = NULL; + if(c->node) { + if(c->node->connection == c) + c->node->connection = NULL; - if(c->edge) { - if(report && !tunnelserver) - send_del_edge(everyone, c->edge); + if(c->edge) { + if(report && !tunnelserver) + send_del_edge(everyone, c->edge); - edge_del(c->edge); - c->edge = NULL; + edge_del(c->edge); + c->edge = NULL; - /* Run MST and SSSP algorithms */ + /* Run MST and SSSP algorithms */ - graph(); + graph(); - /* If the node is not reachable anymore but we remember it had an edge to us, clean it up */ + /* If the node is not reachable anymore but we remember it had an edge to us, clean it up */ - if(report && !c->node->status.reachable) { - edge_t *e; - e = lookup_edge(c->node, myself); - if(e) { - if(!tunnelserver) - send_del_edge(everyone, e); - edge_del(e); + if(report && !c->node->status.reachable) { + edge_t *e; + e = lookup_edge(c->node, myself); + if(e) { + if(!tunnelserver) + send_del_edge(everyone, e); + edge_del(e); + } } } } @@ -144,30 +147,76 @@ void terminate_connection(connection_t *c, bool report) { and close the connection. */ static void timeout_handler(void *data) { + + bool close_all_connections = false; + + /* + timeout_handler will start after 30 seconds from start of tincd + hold information about the elapsed time since last time the handler + has been run + */ + long sleep_time = now.tv_sec - last_periodic_run_time.tv_sec; + /* + It seems that finding sane default value is harder than expected + Since we send every second a UDP packet to make holepunching work + And default UDP state expire on firewalls is between 15-30 seconds + we drop all connections after 60 Seconds - UDPDiscoveryTimeout=30 + by default + */ + if (sleep_time > 2 * udp_discovery_timeout) { + logger(DEBUG_ALWAYS, LOG_ERR, "Awaking from dead after %ld seconds of sleep", sleep_time); + /* + Do not send any packets to tinc after we wake up. + The other node probably closed our connection but we still + are holding context information to them. This may happen on + laptops or any other hardware which can be suspended for some time. + Sending any data to node that wasn't expecting it will produce + annoying and misleading errors on the other side about failed signature + verification and or about missing sptps context + */ + close_all_connections = true; + } + last_periodic_run_time = now; + for list_each(connection_t, c, connection_list) { + // control connections (eg. tinc ctl) do not have any timeout if(c->status.control) continue; - if(c->last_ping_time + pingtimeout <= now.tv_sec) { - if(c->edge) { - try_tx(c->node, false); - if(c->status.pinged) { - logger(DEBUG_CONNECTIONS, LOG_INFO, "%s (%s) didn't respond to PING in %ld seconds", c->name, c->hostname, (long)(now.tv_sec - c->last_ping_time)); - } else if(c->last_ping_time + pinginterval <= now.tv_sec) { - send_ping(c); - continue; - } else { - continue; - } - } else { - if(c->status.connecting) - logger(DEBUG_CONNECTIONS, LOG_WARNING, "Timeout while connecting to %s (%s)", c->name, c->hostname); - else - logger(DEBUG_CONNECTIONS, LOG_WARNING, "Timeout from %s (%s) during authentication", c->name, c->hostname); - } + if(close_all_connections) { + logger(DEBUG_ALWAYS, LOG_ERR, "Forcing connection close after sleep time %s (%s)", c->name, c->hostname); terminate_connection(c, c->edge); + continue; } + // Bail out early if we haven't reached the ping timeout for this node yet + if(c->last_ping_time + pingtimeout > now.tv_sec) + continue; + + // timeout during connection establishing + if(!c->edge) { + if(c->status.connecting) + logger(DEBUG_CONNECTIONS, LOG_WARNING, "Timeout while connecting to %s (%s)", c->name, c->hostname); + else + logger(DEBUG_CONNECTIONS, LOG_WARNING, "Timeout from %s (%s) during authentication", c->name, c->hostname); + + terminate_connection(c, c->edge); + continue; + } + + // helps in UDP holepunching + try_tx(c->node, false); + + // timeout during ping + if(c->status.pinged) { + logger(DEBUG_CONNECTIONS, LOG_INFO, "%s (%s) didn't respond to PING in %ld seconds", c->name, c->hostname, (long)now.tv_sec - c->last_ping_time); + terminate_connection(c, c->edge); + continue; + } + + // check whether we need to send a new ping + if(c->last_ping_time + pinginterval <= now.tv_sec) + send_ping(c); } timeout_set(data, &(struct timeval){1, rand() % 100000}); @@ -210,19 +259,25 @@ static void periodic_handler(void *data) { and we are not already trying to make one, create an outgoing connection to this node. */ - int r = rand() % (node_tree->count - 1); - int i = 0; + int count = 0; + for splay_each(node_t, n, node_tree) { + if(n == myself || n->connection || !(n->status.has_address || n->status.reachable)) + continue; + count++; + } + + if(!count) + goto end; + + int r = rand() % count; for splay_each(node_t, n, node_tree) { - if(n == myself) + if(n == myself || n->connection || !(n->status.has_address || n->status.reachable)) continue; - if(i++ != r) + if(r--) continue; - if(n->connection) - break; - bool found = false; for list_each(outgoing_t, outgoing, outgoing_list) { @@ -239,6 +294,7 @@ static void periodic_handler(void *data) { list_insert_tail(outgoing_list, outgoing); setup_outgoing_connection(outgoing); } + break; } } else if(nc > 3) { @@ -287,6 +343,7 @@ static void periodic_handler(void *data) { } } +end: timeout_set(data, &(struct timeval){5, rand() % 100000}); } @@ -344,9 +401,14 @@ int reload_configuration(void) { for splay_each(subnet_t, subnet, subnet_tree) if (subnet->owner) subnet->expires = 1; + } - load_all_subnets(); + for splay_each(node_t, n, node_tree) + n->status.has_address = false; + load_all_nodes(); + + if(strictsubnets) { for splay_each(subnet_t, subnet, subnet_tree) { if (!subnet->owner) continue; @@ -444,6 +506,7 @@ void retry(void) { this is where it all happens... */ int main_loop(void) { + last_periodic_run_time = now; timeout_add(&pingtimer, timeout_handler, &pingtimer, &(struct timeval){pingtimeout, rand() % 100000}); timeout_add(&periodictimer, periodic_handler, &periodictimer, &(struct timeval){0, 0}); diff --git a/src/net.h b/src/net.h index c3c82de..7080869 100644 --- a/src/net.h +++ b/src/net.h @@ -217,7 +217,6 @@ extern void regenerate_key(void); extern void purge(void); extern void retry(void); extern int reload_configuration(void); -extern void load_all_subnets(void); extern void load_all_nodes(void); extern void try_tx(struct node_t *n, bool); diff --git a/src/net_packet.c b/src/net_packet.c index 21e6c2a..71f02a1 100644 --- a/src/net_packet.c +++ b/src/net_packet.c @@ -355,16 +355,16 @@ static bool receive_udppacket(node_t *n, vpn_packet_t *inpkt) { if(seqno != n->received_seqno + 1) { if(seqno >= n->received_seqno + replaywin * 8) { if(n->farfuture++ < replaywin >> 2) { - logger(DEBUG_ALWAYS, LOG_WARNING, "Packet from %s (%s) is %d seqs in the future, dropped (%u)", + logger(DEBUG_TRAFFIC, LOG_WARNING, "Packet from %s (%s) is %d seqs in the future, dropped (%u)", n->name, n->hostname, seqno - n->received_seqno - 1, n->farfuture); return false; } - logger(DEBUG_ALWAYS, LOG_WARNING, "Lost %d packets from %s (%s)", + logger(DEBUG_TRAFFIC, LOG_WARNING, "Lost %d packets from %s (%s)", seqno - n->received_seqno - 1, n->name, n->hostname); memset(n->late, 0, replaywin); } else if (seqno <= n->received_seqno) { if((n->received_seqno >= replaywin * 8 && seqno <= n->received_seqno - replaywin * 8) || !(n->late[(seqno / 8) % replaywin] & (1 << seqno % 8))) { - logger(DEBUG_ALWAYS, LOG_WARNING, "Got late or replayed packet from %s (%s), seqno %d, last received %d", + logger(DEBUG_TRAFFIC, LOG_WARNING, "Got late or replayed packet from %s (%s), seqno %d, last received %d", n->name, n->hostname, seqno, n->received_seqno); return false; } @@ -436,7 +436,7 @@ void receive_tcppacket(connection_t *c, const char *buffer, int len) { bool receive_tcppacket_sptps(connection_t *c, const char *data, int len) { if (len < sizeof(node_id_t) + sizeof(node_id_t)) { - logger(DEBUG_ALWAYS, LOG_ERR, "Got too short TCP SPTPS packet from %s (%s)", c->name, c->hostname); + logger(DEBUG_PROTOCOL, LOG_ERR, "Got too short TCP SPTPS packet from %s (%s)", c->name, c->hostname); return false; } @@ -499,7 +499,7 @@ static void send_sptps_packet(node_t *n, vpn_packet_t *origpkt) { uint8_t type = 0; int offset = 0; - if(!(DATA(origpkt)[12] | DATA(origpkt)[13])) { + if((!(DATA(origpkt)[12] | DATA(origpkt)[13])) && (n->sptps.outstate)) { sptps_send_record(&n->sptps, PKT_PROBE, (char *)DATA(origpkt), origpkt->len); return; } @@ -767,7 +767,7 @@ bool send_sptps_data(node_t *to, node_t *from, int type, const void *data, size_ char buf[len + sizeof to->id + sizeof from->id]; char* buf_ptr = buf; memcpy(buf_ptr, &to->id, sizeof to->id); buf_ptr += sizeof to->id; memcpy(buf_ptr, &from->id, sizeof from->id); buf_ptr += sizeof from->id; - memcpy(buf_ptr, data, len); buf_ptr += len; + memcpy(buf_ptr, data, len); logger(DEBUG_TRAFFIC, LOG_INFO, "Sending packet from %s (%s) to %s (%s) via %s (%s) (TCP)", from->name, from->hostname, to->name, to->hostname, to->nexthop->name, to->nexthop->hostname); return send_sptps_tcppacket(to->nexthop->connection, buf, sizeof buf); } diff --git a/src/net_setup.c b/src/net_setup.c index 30e6f84..b0a0c95 100644 --- a/src/net_setup.c +++ b/src/net_setup.c @@ -324,62 +324,6 @@ void regenerate_key(void) { n->status.validkey_in = false; } -/* - Read Subnets from all host config files -*/ -void load_all_subnets(void) { - DIR *dir; - struct dirent *ent; - char dname[PATH_MAX]; - - snprintf(dname, sizeof dname, "%s" SLASH "hosts", confbase); - dir = opendir(dname); - if(!dir) { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not open %s: %s", dname, strerror(errno)); - return; - } - - while((ent = readdir(dir))) { - if(!check_id(ent->d_name)) - continue; - - node_t *n = lookup_node(ent->d_name); - #ifdef _DIRENT_HAVE_D_TYPE - //if(ent->d_type != DT_REG) - // continue; - #endif - - splay_tree_t *config_tree; - init_configuration(&config_tree); - read_config_options(config_tree, ent->d_name); - read_host_config(config_tree, ent->d_name); - - if(!n) { - n = new_node(); - n->name = xstrdup(ent->d_name); - node_add(n); - } - - for(config_t *cfg = lookup_config(config_tree, "Subnet"); cfg; cfg = lookup_config_next(config_tree, cfg)) { - subnet_t *s, *s2; - - if(!get_config_subnet(cfg, &s)) - continue; - - if((s2 = lookup_subnet(n, s))) { - s2->expires = -1; - free(s); - } else { - subnet_add(n, s); - } - } - - exit_configuration(&config_tree); - } - - closedir(dir); -} - void load_all_nodes(void) { DIR *dir; struct dirent *ent; @@ -397,18 +341,43 @@ void load_all_nodes(void) { continue; node_t *n = lookup_node(ent->d_name); - if(n) - continue; - n = new_node(); - n->name = xstrdup(ent->d_name); - node_add(n); + splay_tree_t *config_tree; + init_configuration(&config_tree); + read_config_options(config_tree, ent->d_name); + read_host_config(config_tree, ent->d_name); + + if(!n) { + n = new_node(); + n->name = xstrdup(ent->d_name); + node_add(n); + } + + if(strictsubnets) { + for(config_t *cfg = lookup_config(config_tree, "Subnet"); cfg; cfg = lookup_config_next(config_tree, cfg)) { + subnet_t *s, *s2; + + if(!get_config_subnet(cfg, &s)) + continue; + + if((s2 = lookup_subnet(n, s))) { + s2->expires = -1; + free(s); + } else { + subnet_add(n, s); + } + } + } + + if(lookup_config(config_tree, "Address")) + n->status.has_address = true; + + exit_configuration(&config_tree); } closedir(dir); } - char *get_name(void) { char *name = NULL; char *returned_name; @@ -707,7 +676,7 @@ static bool add_listen_address(char *address, bool bindto) { int udp_fd = setup_vpn_in_socket((sockaddr_t *) aip->ai_addr); - if(tcp_fd < 0) { + if(udp_fd < 0) { close(tcp_fd); continue; } @@ -947,10 +916,7 @@ static bool setup_myself(void) { graph(); - if(strictsubnets) - load_all_subnets(); - else if(autoconnect) - load_all_nodes(); + load_all_nodes(); /* Open device */ diff --git a/src/net_socket.c b/src/net_socket.c index bafea64..8259d9a 100644 --- a/src/net_socket.c +++ b/src/net_socket.c @@ -534,6 +534,8 @@ begin: } else if(proxytype == PROXY_EXEC) { result = 0; } else { + if(!proxyai) + abort(); result = connect(c->socket, proxyai->ai_addr, proxyai->ai_addrlen); freeaddrinfo(proxyai); } diff --git a/src/netutl.c b/src/netutl.c index 2eebb64..a9ad17c 100644 --- a/src/netutl.c +++ b/src/netutl.c @@ -234,3 +234,22 @@ void sockaddrunmap(sockaddr_t *sa) { sa->in.sin_family = AF_INET; } } + +void sockaddr_setport(sockaddr_t *sa, const char *port) { + uint16_t portnum = htons(atoi(port)); + if(!portnum) + return; + switch(sa->sa.sa_family) { + case AF_INET: + sa->in.sin_port = portnum; + break; + case AF_INET6: + sa->in6.sin6_port = portnum; + break; + case AF_UNKNOWN: + free(sa->unknown.port); + sa->unknown.port = xstrdup(port); + default: + return; + } +} diff --git a/src/netutl.h b/src/netutl.h index 471cae7..2e2f293 100644 --- a/src/netutl.h +++ b/src/netutl.h @@ -34,5 +34,6 @@ extern int sockaddrcmp_noport(const sockaddr_t *, const sockaddr_t *); extern void sockaddrunmap(sockaddr_t *); extern void sockaddrfree(sockaddr_t *); extern void sockaddrcpy(sockaddr_t *, const sockaddr_t *); +extern void sockaddr_setport(sockaddr_t *, const char *); #endif /* __TINC_NETUTL_H__ */ diff --git a/src/node.h b/src/node.h index 6ca6432..b48fe88 100644 --- a/src/node.h +++ b/src/node.h @@ -40,7 +40,8 @@ typedef struct node_status_t { unsigned int send_locally:1; /* 1 if the next UDP packet should be sent on the local network */ unsigned int udppacket:1; /* 1 if the most recently received packet was UDP */ unsigned int validkey_in:1; /* 1 if we have sent a valid key to him */ - unsigned int unused:21; + unsigned int has_address:1; /* 1 if we know an external address for this node */ + unsigned int unused:20; } node_status_t; typedef struct node_t { diff --git a/src/openssl/cipher.c b/src/openssl/cipher.c index 04aee27..ae9640f 100644 --- a/src/openssl/cipher.c +++ b/src/openssl/cipher.c @@ -28,14 +28,16 @@ #include "../xalloc.h" struct cipher { - EVP_CIPHER_CTX ctx; + EVP_CIPHER_CTX *ctx; const EVP_CIPHER *cipher; }; static cipher_t *cipher_open(const EVP_CIPHER *evp_cipher) { cipher_t *cipher = xzalloc(sizeof *cipher); cipher->cipher = evp_cipher; - EVP_CIPHER_CTX_init(&cipher->ctx); + cipher->ctx = EVP_CIPHER_CTX_new(); + if(!cipher->ctx) + abort(); return cipher; } @@ -68,7 +70,7 @@ void cipher_close(cipher_t *cipher) { if(!cipher) return; - EVP_CIPHER_CTX_cleanup(&cipher->ctx); + EVP_CIPHER_CTX_free(cipher->ctx); free(cipher); } @@ -76,23 +78,23 @@ size_t cipher_keylength(const cipher_t *cipher) { if(!cipher || !cipher->cipher) return 0; - return cipher->cipher->key_len + cipher->cipher->iv_len; + return EVP_CIPHER_key_length(cipher->cipher) + EVP_CIPHER_iv_length(cipher->cipher); } size_t cipher_blocksize(const cipher_t *cipher) { if(!cipher || !cipher->cipher) return 1; - return cipher->cipher->block_size; + return EVP_CIPHER_block_size(cipher->cipher); } bool cipher_set_key(cipher_t *cipher, void *key, bool encrypt) { bool result; if(encrypt) - result = EVP_EncryptInit_ex(&cipher->ctx, cipher->cipher, NULL, (unsigned char *)key, (unsigned char *)key + cipher->cipher->key_len); + result = EVP_EncryptInit_ex(cipher->ctx, cipher->cipher, NULL, (unsigned char *)key, (unsigned char *)key + EVP_CIPHER_key_length(cipher->cipher)); else - result = EVP_DecryptInit_ex(&cipher->ctx, cipher->cipher, NULL, (unsigned char *)key, (unsigned char *)key + cipher->cipher->key_len); + result = EVP_DecryptInit_ex(cipher->ctx, cipher->cipher, NULL, (unsigned char *)key, (unsigned char *)key + EVP_CIPHER_key_length(cipher->cipher)); if(result) return true; @@ -105,9 +107,9 @@ bool cipher_set_key_from_rsa(cipher_t *cipher, void *key, size_t len, bool encry bool result; if(encrypt) - result = EVP_EncryptInit_ex(&cipher->ctx, cipher->cipher, NULL, (unsigned char *)key + len - cipher->cipher->key_len, (unsigned char *)key + len - cipher->cipher->iv_len - cipher->cipher->key_len); + result = EVP_EncryptInit_ex(cipher->ctx, cipher->cipher, NULL, (unsigned char *)key + len - EVP_CIPHER_key_length(cipher->cipher), (unsigned char *)key + len - EVP_CIPHER_iv_length(cipher->cipher) - EVP_CIPHER_key_length(cipher->cipher)); else - result = EVP_DecryptInit_ex(&cipher->ctx, cipher->cipher, NULL, (unsigned char *)key + len - cipher->cipher->key_len, (unsigned char *)key + len - cipher->cipher->iv_len - cipher->cipher->key_len); + result = EVP_DecryptInit_ex(cipher->ctx, cipher->cipher, NULL, (unsigned char *)key + len - EVP_CIPHER_key_length(cipher->cipher), (unsigned char *)key + len - EVP_CIPHER_iv_length(cipher->cipher) - EVP_CIPHER_key_length(cipher->cipher)); if(result) return true; @@ -119,15 +121,15 @@ bool cipher_set_key_from_rsa(cipher_t *cipher, void *key, size_t len, bool encry bool cipher_encrypt(cipher_t *cipher, const void *indata, size_t inlen, void *outdata, size_t *outlen, bool oneshot) { if(oneshot) { int len, pad; - if(EVP_EncryptInit_ex(&cipher->ctx, NULL, NULL, NULL, NULL) - && EVP_EncryptUpdate(&cipher->ctx, (unsigned char *)outdata, &len, indata, inlen) - && EVP_EncryptFinal(&cipher->ctx, (unsigned char *)outdata + len, &pad)) { + if(EVP_EncryptInit_ex(cipher->ctx, NULL, NULL, NULL, NULL) + && EVP_EncryptUpdate(cipher->ctx, (unsigned char *)outdata, &len, indata, inlen) + && EVP_EncryptFinal(cipher->ctx, (unsigned char *)outdata + len, &pad)) { if(outlen) *outlen = len + pad; return true; } } else { int len; - if(EVP_EncryptUpdate(&cipher->ctx, outdata, &len, indata, inlen)) { + if(EVP_EncryptUpdate(cipher->ctx, outdata, &len, indata, inlen)) { if(outlen) *outlen = len; return true; } @@ -140,15 +142,15 @@ bool cipher_encrypt(cipher_t *cipher, const void *indata, size_t inlen, void *ou bool cipher_decrypt(cipher_t *cipher, const void *indata, size_t inlen, void *outdata, size_t *outlen, bool oneshot) { if(oneshot) { int len, pad; - if(EVP_DecryptInit_ex(&cipher->ctx, NULL, NULL, NULL, NULL) - && EVP_DecryptUpdate(&cipher->ctx, (unsigned char *)outdata, &len, indata, inlen) - && EVP_DecryptFinal(&cipher->ctx, (unsigned char *)outdata + len, &pad)) { + if(EVP_DecryptInit_ex(cipher->ctx, NULL, NULL, NULL, NULL) + && EVP_DecryptUpdate(cipher->ctx, (unsigned char *)outdata, &len, indata, inlen) + && EVP_DecryptFinal(cipher->ctx, (unsigned char *)outdata + len, &pad)) { if(outlen) *outlen = len + pad; return true; } } else { int len; - if(EVP_EncryptUpdate(&cipher->ctx, outdata, &len, indata, inlen)) { + if(EVP_EncryptUpdate(cipher->ctx, outdata, &len, indata, inlen)) { if(outlen) *outlen = len; return true; } @@ -162,9 +164,9 @@ int cipher_get_nid(const cipher_t *cipher) { if(!cipher || !cipher->cipher) return 0; - return cipher->cipher->nid; + return EVP_CIPHER_nid(cipher->cipher); } bool cipher_active(const cipher_t *cipher) { - return cipher && cipher->cipher && cipher->cipher->nid != 0; + return cipher && cipher->cipher && EVP_CIPHER_nid(cipher->cipher) != 0; } diff --git a/src/openssl/digest.c b/src/openssl/digest.c index 0e600b9..c303785 100644 --- a/src/openssl/digest.c +++ b/src/openssl/digest.c @@ -93,14 +93,19 @@ bool digest_create(digest_t *digest, const void *indata, size_t inlen, void *out return false; } } else { - EVP_MD_CTX ctx; + EVP_MD_CTX *ctx = EVP_MD_CTX_create(); + if(!ctx) + abort(); - if(!EVP_DigestInit(&ctx, digest->digest) - || !EVP_DigestUpdate(&ctx, indata, inlen) - || !EVP_DigestFinal(&ctx, tmpdata, NULL)) { + if(!EVP_DigestInit(ctx, digest->digest) + || !EVP_DigestUpdate(ctx, indata, inlen) + || !EVP_DigestFinal(ctx, tmpdata, NULL)) { logger(DEBUG_ALWAYS, LOG_DEBUG, "Error creating digest: %s", ERR_error_string(ERR_get_error(), NULL)); + EVP_MD_CTX_destroy(ctx); return false; } + + EVP_MD_CTX_destroy(ctx); } memcpy(outdata, tmpdata, digest->maclength); @@ -118,14 +123,14 @@ int digest_get_nid(const digest_t *digest) { if(!digest || !digest->digest) return 0; - return digest->digest->type; + return EVP_MD_type(digest->digest); } size_t digest_keylength(const digest_t *digest) { if(!digest || !digest->digest) return 0; - return digest->digest->md_size; + return EVP_MD_size(digest->digest); } size_t digest_length(const digest_t *digest) { @@ -136,5 +141,5 @@ size_t digest_length(const digest_t *digest) { } bool digest_active(const digest_t *digest) { - return digest && digest->digest && digest->digest->type != 0; + return digest && digest->digest && EVP_MD_type(digest->digest) != 0; } diff --git a/src/openssl/rsa.c b/src/openssl/rsa.c index 9c1f498..3033bcd 100644 --- a/src/openssl/rsa.c +++ b/src/openssl/rsa.c @@ -30,28 +30,51 @@ typedef RSA rsa_t; // Set RSA keys +#ifndef HAVE_RSA_SET0_KEY +int RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d) { + BN_free(r->n); r->n = n; + BN_free(r->e); r->e = e; + BN_free(r->d); r->d = d; + return 1; +} +#endif + rsa_t *rsa_set_hex_public_key(char *n, char *e) { + BIGNUM *bn_n = NULL; + BIGNUM *bn_e = NULL; + + if(BN_hex2bn(&bn_n, n) != strlen(n) || BN_hex2bn(&bn_e, e) != strlen(e)) { + BN_free(bn_e); + BN_free(bn_n); + return false; + } + rsa_t *rsa = RSA_new(); if(!rsa) return NULL; - - if(BN_hex2bn(&rsa->n, n) != strlen(n) || BN_hex2bn(&rsa->e, e) != strlen(e)) { - RSA_free(rsa); - return false; - } + + RSA_set0_key(rsa, bn_n, bn_e, NULL); return rsa; } rsa_t *rsa_set_hex_private_key(char *n, char *e, char *d) { + BIGNUM *bn_n = NULL; + BIGNUM *bn_e = NULL; + BIGNUM *bn_d = NULL; + + if(BN_hex2bn(&bn_n, n) != strlen(n) || BN_hex2bn(&bn_e, e) != strlen(e) || BN_hex2bn(&bn_d, d) != strlen(d)) { + BN_free(bn_d); + BN_free(bn_e); + BN_free(bn_n); + return false; + } + rsa_t *rsa = RSA_new(); if(!rsa) return NULL; - if(BN_hex2bn(&rsa->n, n) != strlen(n) || BN_hex2bn(&rsa->e, e) != strlen(e) || BN_hex2bn(&rsa->d, d) != strlen(d)) { - RSA_free(rsa); - return false; - } + RSA_set0_key(rsa, bn_n, bn_e, bn_d); return rsa; } diff --git a/src/openssl/rsagen.c b/src/openssl/rsagen.c index 3a8c8ad..b7eb629 100644 --- a/src/openssl/rsagen.c +++ b/src/openssl/rsagen.c @@ -27,10 +27,11 @@ typedef RSA rsa_t; #include "../logger.h" #include "../rsagen.h" +#include "../xalloc.h" /* This function prettyprints the key generation process */ -static void indicator(int a, int b, void *p) { +static int indicator(int a, int b, BN_GENCB *cb) { switch (a) { case 0: fprintf(stderr, "."); @@ -62,12 +63,45 @@ static void indicator(int a, int b, void *p) { default: fprintf(stderr, "?"); } + + return 1; } // Generate RSA key +#ifndef HAVE_BN_GENCB_NEW +BN_GENCB *BN_GENCB_new(void) { + return xzalloc(sizeof(BN_GENCB)); +} + +void BN_GENCB_free(BN_GENCB *cb) { + free(cb); +} +#endif + rsa_t *rsa_generate(size_t bits, unsigned long exponent) { - return RSA_generate_key(bits, exponent, indicator, NULL); + BIGNUM *bn_e = BN_new(); + rsa_t *rsa = RSA_new(); + BN_GENCB *cb = BN_GENCB_new(); + + if(!bn_e || !rsa || !cb) + abort(); + + BN_set_word(bn_e, exponent); + BN_GENCB_set(cb, indicator, NULL); + + int result = RSA_generate_key_ex(rsa, bits, bn_e, cb); + + BN_GENCB_free(cb); + BN_free(bn_e); + + if(!result) { + fprintf(stderr, "Error during key generation!\n"); + RSA_free(rsa); + return NULL; + } + + return rsa; } // Write PEM RSA keys diff --git a/src/protocol.c b/src/protocol.c index f533a93..b9abccc 100644 --- a/src/protocol.c +++ b/src/protocol.c @@ -72,10 +72,11 @@ bool send_request(connection_t *c, const char *format, ...) { input buffer anyway */ va_start(args, format); - len = vsnprintf(request, MAXBUFSIZE, format, args); + len = vsnprintf(request, sizeof request, format, args); + request[sizeof request - 1] = 0; va_end(args); - if(len < 0 || len > MAXBUFSIZE - 1) { + if(len < 0 || len > sizeof request - 1) { logger(DEBUG_ALWAYS, LOG_ERR, "Output buffer overflow while sending request to %s (%s)", c->name, c->hostname); return false; diff --git a/src/protocol_auth.c b/src/protocol_auth.c index 0a7ad1c..31b1f1e 100644 --- a/src/protocol_auth.c +++ b/src/protocol_auth.c @@ -790,7 +790,6 @@ bool ack_h(connection_t *c, const char *request) { return upgrade_h(c, request); char hisport[MAX_STRING_SIZE]; - char *hisaddress; int weight, mtu; uint32_t options; node_t *n; @@ -867,19 +866,14 @@ bool ack_h(connection_t *c, const char *request) { c->edge = new_edge(); c->edge->from = myself; c->edge->to = n; - sockaddr2str(&c->address, &hisaddress, NULL); - c->edge->address = str2sockaddr(hisaddress, hisport); - free(hisaddress); + sockaddrcpy(&c->edge->address, &c->address); + sockaddr_setport(&c->edge->address, hisport); sockaddr_t local_sa; socklen_t local_salen = sizeof local_sa; if (getsockname(c->socket, &local_sa.sa, &local_salen) < 0) logger(DEBUG_ALWAYS, LOG_WARNING, "Could not get local socket address for connection with %s", c->name); - else { - char *local_address; - sockaddr2str(&local_sa, &local_address, NULL); - c->edge->local_address = str2sockaddr(local_address, myport); - free(local_address); - } + else + sockaddr_setport(&local_sa, myport); c->edge->weight = (weight + c->estimated_weight) / 2; c->edge->connection = c; c->edge->options = c->options; diff --git a/src/sptps.c b/src/sptps.c index 712d50e..a1fd5e7 100644 --- a/src/sptps.c +++ b/src/sptps.c @@ -547,8 +547,6 @@ size_t sptps_receive_data(sptps_t *s, const void *data, size_t len) { memcpy(s->inbuf + s->buflen, data, toread); total_read += toread; s->buflen += toread; - len -= toread; - data += toread; // If we don't have a whole record, exit. if(s->buflen < s->reclen + (s->instate ? 19UL : 3UL)) diff --git a/src/tincctl.c b/src/tincctl.c index e42ec2c..465c981 100644 --- a/src/tincctl.c +++ b/src/tincctl.c @@ -560,6 +560,7 @@ bool sendline(int fd, char *format, ...) { va_start(ap, format); blen = vsnprintf(buffer, sizeof buffer, format, ap); + buffer[sizeof buffer - 1] = 0; va_end(ap); if(blen < 1 || blen >= sizeof buffer) @@ -718,6 +719,13 @@ bool connect_tincd(bool verbose) { } fclose(f); + if ((pid == 0) || (kill(pid, 0) && (errno == ESRCH))) { + fprintf(stderr, "Could not find tincd running at pid %d\n", pid); + /* clean up the stale socket and pid file */ + unlink(pidfilename); + unlink(unixsocketname); + return false; + } #ifndef HAVE_MINGW struct sockaddr_un sa; @@ -878,7 +886,7 @@ static int cmd_start(int argc, char *argv[]) { if(!pid) { close(pfd[0]); - char buf[100] = ""; + char buf[100]; snprintf(buf, sizeof buf, "%d", pfd[1]); setenv("TINC_UMBILICAL", buf, true); exit(execvp(c, nargv)); @@ -1384,7 +1392,7 @@ static int cmd_pid(int argc, char *argv[]) { return 1; } - if(!connect_tincd(true) && !pid) + if(!connect_tincd(true) || !pid) return 1; printf("%d\n", pid); @@ -2513,6 +2521,7 @@ static int cmd_verify(int argc, char *argv[]) { char *newline = memchr(data, '\n', len); if(!newline || (newline - data > MAX_STRING_SIZE - 1)) { fprintf(stderr, "Invalid input\n"); + free(data); return 1; } @@ -2525,11 +2534,13 @@ static int cmd_verify(int argc, char *argv[]) { if(sscanf(data, "Signature = %s %ld %s", signer, &t, sig) != 3 || strlen(sig) != 86 || !t || !check_id(signer)) { fprintf(stderr, "Invalid input\n"); + free(data); return 1; } if(node && strcmp(node, signer)) { fprintf(stderr, "Signature is not made by %s\n", node); + free(data); return 1; } @@ -2823,8 +2834,10 @@ static int cmd_shell(int argc, char *argv[]) { if(nargc == argc) continue; - if(!strcasecmp(nargv[argc], "exit") || !strcasecmp(nargv[argc], "quit")) + if(!strcasecmp(nargv[argc], "exit") || !strcasecmp(nargv[argc], "quit")) { + free(nargv); return result; + } bool found = false; diff --git a/systemd/Makefile.in b/systemd/Makefile.in index 4bc2d27..44e6bb2 100644 --- a/systemd/Makefile.in +++ b/systemd/Makefile.in @@ -91,8 +91,11 @@ host_triplet = @host@ subdir = systemd ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \ + $(top_srcdir)/m4/ax_append_flag.m4 \ + $(top_srcdir)/m4/ax_cflags_warn_all.m4 \ $(top_srcdir)/m4/ax_check_compile_flag.m4 \ $(top_srcdir)/m4/ax_check_link_flag.m4 \ + $(top_srcdir)/m4/ax_require_defined.m4 \ $(top_srcdir)/m4/curses.m4 $(top_srcdir)/m4/libgcrypt.m4 \ $(top_srcdir)/m4/lzo.m4 $(top_srcdir)/m4/miniupnpc.m4 \ $(top_srcdir)/m4/openssl.m4 $(top_srcdir)/m4/readline.m4 \ diff --git a/test/Makefile.in b/test/Makefile.in index 885674d..0dbe653 100644 --- a/test/Makefile.in +++ b/test/Makefile.in @@ -91,8 +91,11 @@ check_PROGRAMS = pong$(EXEEXT) subdir = test ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \ + $(top_srcdir)/m4/ax_append_flag.m4 \ + $(top_srcdir)/m4/ax_cflags_warn_all.m4 \ $(top_srcdir)/m4/ax_check_compile_flag.m4 \ $(top_srcdir)/m4/ax_check_link_flag.m4 \ + $(top_srcdir)/m4/ax_require_defined.m4 \ $(top_srcdir)/m4/curses.m4 $(top_srcdir)/m4/libgcrypt.m4 \ $(top_srcdir)/m4/lzo.m4 $(top_srcdir)/m4/miniupnpc.m4 \ $(top_srcdir)/m4/openssl.m4 $(top_srcdir)/m4/readline.m4 \ From bc8ca6565352276ec40b5ac02f936060b53d296b Mon Sep 17 00:00:00 2001 From: Guus Sliepen Date: Mon, 26 Aug 2019 13:44:52 +0200 Subject: [PATCH 11/13] Import Upstream version 1.1~pre15 --- COPYING | 2 +- ChangeLog | 105 +++++++++++++ INSTALL | 316 +++++++++++++++++++-------------------- Makefile.in | 12 +- NEWS | 25 +++- README | 6 +- aclocal.m4 | 44 +++--- config.guess | 28 ++-- config.h.in | 6 +- config.sub | 22 ++- configure | 26 ++-- depcomp | 6 +- doc/Makefile.in | 4 +- doc/sample-config.tar.gz | Bin 1228 -> 1242 bytes doc/tinc.conf.5.in | 14 +- doc/tinc.info | 266 ++++++++++++++++---------------- doc/tinc.texi | 21 ++- gui/Makefile.in | 4 +- m4/openssl.m4 | 2 +- src/Makefile.am | 9 +- src/Makefile.in | 163 ++++++++++---------- src/autoconnect.c | 174 +++++++++++++++++++++ src/autoconnect.h | 25 ++++ src/bsd/device.c | 13 +- src/cipher.h | 4 +- src/connection.h | 2 + src/device.h | 1 + src/digest.h | 3 +- src/dropin.c | 3 +- src/ed25519/add_scalar.c | 56 ------- src/ed25519/ed25519.h | 1 - src/ed25519/sc.c | 24 --- src/ethernet.h | 13 ++ src/event.c | 7 +- src/fd_device.c | 123 +++++++++++++++ src/fsck.c | 9 +- src/graph.c | 23 ++- src/ifconfig.c | 47 +++--- src/info.c | 12 +- src/invitation.c | 39 +++-- src/linux/device.c | 3 + src/logger.c | 4 +- src/logger.h | 4 +- src/meta.c | 14 ++ src/mingw/device.c | 24 ++- src/names.c | 5 +- src/names.h | 3 +- src/net.c | 107 +------------ src/net.h | 3 +- src/net_packet.c | 12 +- src/net_setup.c | 41 ++--- src/net_socket.c | 33 ++-- src/node.c | 4 +- src/openssl/cipher.c | 28 +++- src/openssl/digest.c | 6 +- src/protocol.h | 3 +- src/protocol_auth.c | 58 +++++-- src/protocol_edge.c | 115 +++++++------- src/protocol_key.c | 6 +- src/protocol_misc.c | 7 +- src/route.c | 15 +- src/script.c | 64 +++++++- src/script.h | 16 +- src/solaris/device.c | 44 ++++-- src/sptps_test.c | 17 ++- src/subnet.c | 35 ++--- src/subnet_parse.c | 2 +- src/tincctl.c | 51 ++++--- src/tincd.c | 3 + src/top.c | 42 ++++-- src/uml_device.c | 4 +- src/upnp.c | 2 +- systemd/Makefile.in | 4 +- systemd/tinc@.service | 1 + test/Makefile.am | 2 + test/Makefile.in | 6 +- test/executables.test | 4 +- test/invite-join.test | 2 - test/invite-offline.test | 50 +++++++ test/invite-tinc-up.test | 2 +- test/ns-ping.test | 2 +- test/pong.c | 6 +- test/scripts.test | 112 ++++++++++++++ test/sptps-basic.test | 16 +- test/testlib.sh | 16 +- 85 files changed, 1687 insertions(+), 971 deletions(-) create mode 100644 src/autoconnect.c create mode 100644 src/autoconnect.h delete mode 100644 src/ed25519/add_scalar.c create mode 100644 src/fd_device.c create mode 100755 test/invite-offline.test create mode 100755 test/scripts.test diff --git a/COPYING b/COPYING index 513da31..c7a4498 100644 --- a/COPYING +++ b/COPYING @@ -1,4 +1,4 @@ -Copyright (C) 1998-2016 Ivo Timmermans, Guus Sliepen and others. +Copyright (C) 1998-2017 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/ChangeLog b/ChangeLog index 29e545f..59667bf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,108 @@ +Version 1.1pre15 September 02 2017 +------------------------------------------------------------------------ + +Guus Sliepen (56): + Preserve IPv6 scope_id in edges. + Fix the previous commit. + Ensure compatibility with OpenSSL 1.1.0. + Add -Wall to CFLAGS. + Check return value of RSA_generate_key_ex(). + Use EVP_MD_CTX_destroy() instead of _free(). + Force nul-termination of strings after vsnprintf(). + Fix warnings from the Clang static analyzer. + Fix potential memory leaks found by the Clang static analyzer. + Add missing m4 files. + Fix compiling with OpenSSL < 1.1.0. + Log warnings about dropped packets only with debug level 5 or higher. + Use AES256 and SHA256 by default for the legacy protocol. + Enforce maximum amount of bytes sent/received on meta-connections. + Fix potential segfault in the replacement vasprintf() function. + Don't build sptps_* binaries by default. + Remove the description of the LocalDiscoveryAddress option from the manual. + Use free_known_addresses() to free memory allocated by get_known_addresses(). + Add missing #defines used by fd_device.c. + Don't try to use kill() on Windows. + Merge remote-tracking branch 'dechamps/sleep' into 1.1 + Put script environment creation/deletion in functions. + Add DEBUG environment variable for scripts. + Use unique ports for all tests. + Remove superfluous sleep command in invite-join test. + Add the invite-offline test. + Update .gitignore. + Add the scripts test. + Ensure proper logging in the invite-offline test. + Use 127.0.0.1 instead of localhost to ensure tests are reproducible. + Ensure sptps_keypair and sptps_test get build for make check. + Use /dev/udp instead of /dev/ip on Solaris. + Use getmsg()/putmsg() instead of read()/write() on Solaris. + Ensure tests compile on *BSD. + Make sure realname is always initialized. + Fix compiler warnings on *BSD. + Fix segfault when adding environment variables. + Fix tests on *BSD. + Add missing tinc stop command to the scripts test. + Remove dead stores. + Add field widths to sscanf() calls. + Fix some minor issues found by cppcheck. + Remove unused add_scalar function. + Move logging of "would block" messages to debug level 4. + Set KillMode=mixed in the systemd service file. + Add configurable experation time for invitations. + Store the invitation data after a succesful join. + Forward-port tinc 1.0's handling of device errors. + Make autoconnect try to heal network splits. + Add missing break statements. + Force IPv4 for sptps-basic.test. + Fix a compiler warning. + Fix a file descriptor leak when using an invitation. + Ensure packet priority is cleared when sending PMTU probe replies. + Drop h and hh length modifiers from printf format strings. + Releasing 1.1pre15. + +Etienne Dechamps (7): + Fix error handling when setting up the UDP socket. + Fix crash on Windows when a socket is available for both write and read. + On Windows, don't cancel I/O when disabling the device. + Fix edge local addresses not being set when connections are established. + Fix edge updates containing local address changes. + Clarify the flow of add_edge_h(). + Fix address memory leaks in add_edge_h(). + +thorkill (4): + Send PKT_PROBE only when handshake has been done already. + Prevent tincd from sending packets to unexpecting nodes + Sanitize input in id_h - prevent integer overflows + Fix NULL pointer dereference in send_udp_info + +Sean McVeigh (2): + check for daemon pid existence before trying to connect to the control socket, and clean up stale files otherwise. + fix check in cmd_pid() for failure to connect to tincd + +Vittorio G (VittGam) (2): + fsck: Fix ed25519 public key reading, and fclose usage. + tincctl: Avoid falling back to 1024 bits RSA key generation when an invalid key size is specified. + +Dennis Lan (1): + Fix typo in src/upnp.c. + +Pacien TRAN-GIRARD (1): + Add fd_device + +Roman Savelyev (1): + Fix lost pointer trails in get_known_addresses(). + +Vittorio Gambaletta (VittGam) (1): + route: Support ToS/DiffServ priority inheritance when routing IPv6 packets. + +lemoer (1): + Added comments and unfold deep "if"-construct in timeout_handler + +pacien (1): + Add LogLevel config option + +volth (1): + Avoid infinite loop on EBADFD + Version 1.1pre14 May 01 2016 ------------------------------------------------------------------------ diff --git a/INSTALL b/INSTALL index 2099840..8865734 100644 --- a/INSTALL +++ b/INSTALL @@ -1,8 +1,8 @@ Installation Instructions ************************* -Copyright (C) 1994-1996, 1999-2002, 2004-2013 Free Software Foundation, -Inc. + Copyright (C) 1994-1996, 1999-2002, 2004-2016 Free Software +Foundation, Inc. Copying and distribution of this file, with or without modification, are permitted in any medium without royalty provided the copyright @@ -12,97 +12,96 @@ without warranty of any kind. Basic Installation ================== - Briefly, the shell command `./configure && make && make install' + Briefly, the shell command './configure && make && make install' should configure, build, and install this package. The following -more-detailed instructions are generic; see the `README' file for +more-detailed instructions are generic; see the 'README' file for instructions specific to this package. Some packages provide this -`INSTALL' file but do not implement all of the features documented +'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 + The 'configure' shell script attempts to guess correct values for various system-dependent variables used during compilation. It uses -those values to create a `Makefile' in each directory of the package. -It may also create one or more `.h' files containing system-dependent -definitions. Finally, it creates a shell script `config.status' that +those values to create a 'Makefile' in each directory of the package. +It may also create one or more '.h' files containing system-dependent +definitions. Finally, it creates a shell script 'config.status' that you can run in the future to recreate the current configuration, and a -file `config.log' containing compiler output (useful mainly for -debugging `configure'). +file 'config.log' containing compiler output (useful mainly for +debugging 'configure'). - It can also use an optional file (typically called `config.cache' -and enabled with `--cache-file=config.cache' or simply `-C') that saves -the results of its tests to speed up reconfiguring. Caching is -disabled by default to prevent problems with accidental use of stale -cache files. + It can also use an optional file (typically called 'config.cache' and +enabled with '--cache-file=config.cache' or simply '-C') that saves the +results of its tests to speed up reconfiguring. Caching is disabled by +default to prevent problems with accidental use of stale cache files. If you need to do unusual things to compile the package, please try -to figure out how `configure' could check whether to do them, and mail -diffs or instructions to the address given in the `README' so they can +to figure out how 'configure' could check whether to do them, and mail +diffs or instructions to the address given in the 'README' so they can be considered for the next release. If you are using the cache, and at -some point `config.cache' contains results you don't want to keep, you +some point 'config.cache' contains results you don't want to keep, you may remove or edit it. - The file `configure.ac' (or `configure.in') is used to create -`configure' by a program called `autoconf'. You need `configure.ac' if -you want to change it or regenerate `configure' using a newer version -of `autoconf'. + The file 'configure.ac' (or 'configure.in') is used to create +'configure' by a program called 'autoconf'. You need 'configure.ac' if +you want to change it or regenerate 'configure' using a newer version of +'autoconf'. 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. + 1. 'cd' to the directory containing the package's source code and type + './configure' to configure the package for your system. - Running `configure' might take a while. While running, it prints + Running 'configure' might take a while. While running, it prints some messages telling which features it is checking for. - 2. Type `make' to compile the package. + 2. Type 'make' to compile the package. - 3. Optionally, type `make check' to run any self-tests that come with + 3. Optionally, type 'make check' to run any self-tests that come with the package, generally using the just-built uninstalled binaries. - 4. Type `make install' to install the programs and any data files and + 4. Type 'make install' to install the programs and any data files and 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 + user, and only the 'make install' phase executed with root privileges. - 5. Optionally, type `make installcheck' to repeat any self-tests, but + 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 + 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 - also a `make maintainer-clean' target, but that is intended mainly + 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 + also a 'make maintainer-clean' target, but that is intended mainly for the package's developers. If you use it, you may have to get all sorts of other programs in order to regenerate files that came with the distribution. - 7. Often, you can also type `make uninstall' to remove the installed + 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 + 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. + targets like 'make install' and 'make uninstall' work correctly. This target is generally not run by end users. Compilers and Options ===================== Some systems require unusual options for compilation or linking that -the `configure' script does not know about. Run `./configure --help' +the 'configure' script does not know about. Run './configure --help' for details on some of the pertinent environment variables. - You can give `configure' initial values for configuration parameters -by setting variables in the command line or in the environment. Here -is an example: + You can give 'configure' initial values for configuration parameters +by setting variables in the command line or in the environment. Here is +an example: ./configure CC=c99 CFLAGS=-g LIBS=-lposix @@ -113,21 +112,21 @@ Compiling For Multiple Architectures You can compile the package for more than one kind of computer at the 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 +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 `..'. This -is known as a "VPATH" build. +the 'configure' script. 'configure' automatically checks for the 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 + 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 -installed the package for one architecture, use `make distclean' before +installed the package for one architecture, use 'make distclean' before reconfiguring for another architecture. On MacOS X 10.5 and later systems, you can create libraries and executables that work on multiple system types--known as "fat" or -"universal" binaries--by specifying multiple `-arch' options to the -compiler but only a single `-arch' option to the preprocessor. Like +"universal" binaries--by specifying multiple '-arch' options to the +compiler but only a single '-arch' option to the preprocessor. Like this: ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ @@ -136,105 +135,104 @@ this: This is not guaranteed to produce working output in all cases, you may have to build one architecture at a time and combine the results -using the `lipo' tool if you have problems. +using the 'lipo' tool if you have problems. 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', where PREFIX must be an + 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', where PREFIX must be an absolute file name. You can specify separate installation prefixes for architecture-specific files and architecture-independent files. If you -pass the option `--exec-prefix=PREFIX' to `configure', the package uses +pass the option '--exec-prefix=PREFIX' to 'configure', the package uses PREFIX as the prefix for installing programs and libraries. 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. 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 +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. 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 +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 +'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 +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. +'${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 + 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. +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'. +with an extra prefix or suffix on their names by giving 'configure' the +option '--program-prefix=PREFIX' or '--program-suffix=SUFFIX'. - 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 -is something like `gnu-as' or `x' (for the X Window System). The -`README' should mention any `--enable-' and `--with-' options that the + 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 +is something like 'gnu-as' or 'x' (for the X Window System). The +'README' should mention any '--enable-' and '--with-' options that the package recognizes. - For packages that use the X Window System, `configure' can usually + For packages that use the X Window System, 'configure' can usually 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. +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 +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 +overridden with 'make V=1'; while running './configure --disable-silent-rules' sets the default to verbose, which can be -overridden with `make V=0'. +overridden with 'make V=0'. Particular systems ================== - On HP-UX, the default C compiler is not ANSI C compatible. If GNU -CC is not installed, it is recommended to use the following options in + On HP-UX, the default C compiler is not ANSI C compatible. If GNU CC +is not installed, it is recommended to use the following options in order to use an ANSI C compiler: ./configure CC="cc -Ae -D_XOPEN_SOURCE=500" and if that doesn't work, install pre-built binaries of GCC for HP-UX. - HP-UX `make' updates targets which have the same time stamps as -their prerequisites, which makes it generally unusable when shipped -generated files such as `configure' are involved. Use GNU `make' -instead. + HP-UX 'make' updates targets which have the same time stamps as their +prerequisites, which makes it generally unusable when shipped generated +files such as 'configure' are involved. Use GNU 'make' instead. On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot -parse its `' header file. The option `-nodtk' can be used as -a workaround. If GNU CC is not installed, it is therefore recommended -to try +parse its '' header file. The option '-nodtk' can be used as a +workaround. If GNU CC is not installed, it is therefore recommended to +try ./configure CC="cc" @@ -242,26 +240,26 @@ and if that doesn't work, try ./configure CC="cc -nodtk" - On Solaris, don't put `/usr/ucb' early in your `PATH'. This + On Solaris, don't put '/usr/ucb' early in your 'PATH'. This directory contains several dysfunctional programs; working variants of -these programs are available in `/usr/bin'. So, if you need `/usr/ucb' -in your `PATH', put it _after_ `/usr/bin'. +these programs are available in '/usr/bin'. So, if you need '/usr/ucb' +in your 'PATH', put it _after_ '/usr/bin'. - On Haiku, software installed for all users goes in `/boot/common', -not `/usr/local'. It is recommended to use the following options: + On Haiku, software installed for all users goes in '/boot/common', +not '/usr/local'. It is recommended to use the following options: ./configure --prefix=/boot/common Specifying the System Type ========================== - There may be some features `configure' cannot figure out + There may be some features 'configure' cannot figure out automatically, but needs to determine by the type of machine the package will run on. Usually, assuming the package is built to be run on the -_same_ architectures, `configure' can figure that out, but if it prints +_same_ architectures, 'configure' can figure that out, but if it prints a message saying it cannot guess the machine type, give it the -`--build=TYPE' option. TYPE can either be a short name for the system -type, such as `sun4', or a canonical name which has the form: +'--build=TYPE' option. TYPE can either be a short name for the system +type, such as 'sun4', or a canonical name which has the form: CPU-COMPANY-SYSTEM @@ -270,101 +268,101 @@ where SYSTEM can have one of these forms: OS KERNEL-OS - See the file `config.sub' for the possible values of each field. If -`config.sub' isn't included in this package, then this package doesn't + See the file 'config.sub' for the possible values of each field. If +'config.sub' isn't included in this package, then this package doesn't need to know the machine type. If you are _building_ compiler tools for cross-compiling, you should -use the option `--target=TYPE' to select the type of system they will +use the option '--target=TYPE' to select the type of system they will produce code for. If you want to _use_ a cross compiler, that generates code for a platform different from the build platform, you should specify the "host" platform (i.e., that on which the generated programs will -eventually be run) with `--host=TYPE'. +eventually be run) with '--host=TYPE'. Sharing Defaults ================ - If you want to set default values for `configure' scripts to share, -you can create a site shell script called `config.site' that gives -default values for variables like `CC', `cache_file', and `prefix'. -`configure' looks for `PREFIX/share/config.site' if it exists, then -`PREFIX/etc/config.site' if it exists. Or, you can set the -`CONFIG_SITE' environment variable to the location of the site script. -A warning: not all `configure' scripts look for a site script. + If you want to set default values for 'configure' scripts to share, +you can create a site shell script called 'config.site' that gives +default values for variables like 'CC', 'cache_file', and 'prefix'. +'configure' looks for 'PREFIX/share/config.site' if it exists, then +'PREFIX/etc/config.site' if it exists. Or, you can set the +'CONFIG_SITE' environment variable to the location of the site script. +A warning: not all 'configure' scripts look for a site script. Defining Variables ================== Variables not defined in a site shell script can be set in the -environment passed to `configure'. However, some packages may run +environment passed to 'configure'. However, some packages may run configure again during the build, and the customized values of these variables may be lost. In order to avoid this problem, you should set -them in the `configure' command line, using `VAR=value'. For example: +them in the 'configure' command line, using 'VAR=value'. For example: ./configure CC=/usr/local2/bin/gcc -causes the specified `gcc' to be used as the C compiler (unless it is +causes the specified 'gcc' to be used as the C compiler (unless it is overridden in the site shell script). -Unfortunately, this technique does not work for `CONFIG_SHELL' due to -an Autoconf limitation. Until the limitation is lifted, you can use -this workaround: +Unfortunately, this technique does not work for 'CONFIG_SHELL' due to an +Autoconf limitation. Until the limitation is lifted, you can use this +workaround: CONFIG_SHELL=/bin/bash ./configure CONFIG_SHELL=/bin/bash -`configure' Invocation +'configure' Invocation ====================== - `configure' recognizes the following options to control how it + 'configure' recognizes the following options to control how it operates. -`--help' -`-h' - Print a summary of all of the options to `configure', and exit. +'--help' +'-h' + Print a summary of all of the options to 'configure', and exit. -`--help=short' -`--help=recursive' +'--help=short' +'--help=recursive' Print a summary of the options unique to this package's - `configure', and exit. The `short' variant lists options used - only in the top level, while the `recursive' variant lists options - also present in any nested packages. + 'configure', and exit. The 'short' variant lists options used only + in the top level, while the 'recursive' variant lists options also + present in any nested packages. -`--version' -`-V' - Print the version of Autoconf used to generate the `configure' +'--version' +'-V' + Print the version of Autoconf used to generate the 'configure' script, and exit. -`--cache-file=FILE' +'--cache-file=FILE' Enable the cache: use and save the results of the tests in FILE, - traditionally `config.cache'. FILE defaults to `/dev/null' to + traditionally 'config.cache'. FILE defaults to '/dev/null' to disable caching. -`--config-cache' -`-C' - Alias for `--cache-file=config.cache'. +'--config-cache' +'-C' + Alias for '--cache-file=config.cache'. -`--quiet' -`--silent' -`-q' +'--quiet' +'--silent' +'-q' Do not print messages saying which checks are being made. To - suppress all normal output, redirect it to `/dev/null' (any error + suppress all normal output, redirect it to '/dev/null' (any error messages will still be shown). -`--srcdir=DIR' +'--srcdir=DIR' Look for the package's source code in directory DIR. Usually - `configure' can determine that directory automatically. + 'configure' can determine that directory automatically. -`--prefix=DIR' - Use DIR as the installation prefix. *note Installation Names:: - for more details, including other options available for fine-tuning - the installation locations. +'--prefix=DIR' + Use DIR as the installation prefix. *note Installation Names:: for + more details, including other options available for fine-tuning the + installation locations. -`--no-create' -`-n' +'--no-create' +'-n' Run the configure checks, but stop before creating any output files. -`configure' also accepts some other, not widely useful, options. Run -`configure --help' for more details. +'configure' also accepts some other, not widely useful, options. Run +'configure --help' for more details. diff --git a/Makefile.in b/Makefile.in index cd24b01..f7099d2 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -540,7 +540,7 @@ distdir: $(DISTFILES) ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ || chmod -R a+r "$(distdir)" dist-gzip: distdir - tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz + tardir=$(distdir) && $(am__tar) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).tar.gz $(am__post_remove_distdir) dist-bzip2: distdir @@ -566,7 +566,7 @@ dist-shar: distdir @echo WARNING: "Support for shar distribution archives is" \ "deprecated." >&2 @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 - shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz + shar $(distdir) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).shar.gz $(am__post_remove_distdir) dist-zip: distdir @@ -584,7 +584,7 @@ dist dist-all: distcheck: dist case '$(DIST_ARCHIVES)' in \ *.tar.gz*) \ - GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\ + eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).tar.gz | $(am__untar) ;;\ *.tar.bz2*) \ bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ *.tar.lz*) \ @@ -594,7 +594,7 @@ distcheck: dist *.tar.Z*) \ uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ *.shar.gz*) \ - GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\ + eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).shar.gz | unshar ;;\ *.zip*) \ unzip $(distdir).zip ;;\ esac diff --git a/NEWS b/NEWS index 674227e..ec6add6 100644 --- a/NEWS +++ b/NEWS @@ -1,4 +1,27 @@ -# Version 1.1pre13 May 1 2016 +# Version 1.1pre15 September 2 2017 + +* Detect when the machine is resuming from suspension or hibernation. +* When an old PID file is found, check whether the old daemon is still alive. +* Remember scope_id for IPv6 addresses when sending UDP packets to link-local + addresses. +* Ensure compatibility with OpenSSL 1.1. +* Only log about dropped packets with debug level 5. +* Warn when trying to generate RSA keys less than 2048 bits. +* Use AES256 and SHA256 as the default encryption and digest algorithms. +* Add DeviceType = fd to support tinc on Android without requiring root. +* Support PriorityInheritance for IPv6 packets. +* Fixes for Solaris tun/tap support. +* Add a configurable expiration time for invitations. +* Store invitation data after a succesful join. +* Exit gracefully when the tun/tap device is in a bad state. +* Add the LogLevel option. +* AutoConnect now actively tries to heal split networks. + +Thanks to Etienne Dechamps, Rafał Leśniak, Sean McVeigh, Vittorio Gambaletta, +Dennis Lan, Pacien Tran-Girard, Roman Savelyev, lemoer and volth for their +contributions to this version of tinc. + +# Version 1.1pre14 May 1 2016 * Add tinc.service back. diff --git a/README b/README index 9b29f2c..d3b8f16 100644 --- a/README +++ b/README @@ -1,7 +1,7 @@ -This is the README file for tinc version 1.1pre14. Installation +This is the README file for tinc version 1.1pre15. Installation instructions may be found in the INSTALL file. -tinc is Copyright © 1998-2016 Ivo Timmermans, Guus Sliepen , and others. +tinc is Copyright © 1998-2017 Ivo Timmermans, Guus Sliepen , and others. For a complete list of authors see the AUTHORS file. @@ -32,7 +32,7 @@ at your own risk. Compatibility ------------- -Version 1.1pre14 is compatible with 1.0pre8, 1.0 and later, but not with older +Version 1.1pre15 is compatible with 1.0pre8, 1.0 and later, but not with older versions of tinc. When the ExperimentalProtocol option is used, tinc is still compatible with diff --git a/aclocal.m4 b/aclocal.m4 index 005ea6d..d4738fd 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -1,6 +1,6 @@ -# generated automatically by aclocal 1.15 -*- Autoconf -*- +# generated automatically by aclocal 1.15.1 -*- Autoconf -*- -# Copyright (C) 1996-2014 Free Software Foundation, Inc. +# Copyright (C) 1996-2017 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -20,7 +20,7 @@ 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'.])]) -# Copyright (C) 2002-2014 Free Software Foundation, Inc. +# Copyright (C) 2002-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -35,7 +35,7 @@ AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version='1.15' 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.15], [], +m4_if([$1], [1.15.1], [], [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl ]) @@ -51,14 +51,14 @@ 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.15])dnl +[AM_AUTOMAKE_VERSION([1.15.1])dnl m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) # AM_AUX_DIR_EXPAND -*- Autoconf -*- -# Copyright (C) 2001-2014 Free Software Foundation, Inc. +# Copyright (C) 2001-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -110,7 +110,7 @@ am_aux_dir=`cd "$ac_aux_dir" && pwd` # AM_CONDITIONAL -*- Autoconf -*- -# Copyright (C) 1997-2014 Free Software Foundation, Inc. +# Copyright (C) 1997-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -141,7 +141,7 @@ AC_CONFIG_COMMANDS_PRE( Usually this means the macro was only invoked conditionally.]]) fi])]) -# Copyright (C) 1999-2014 Free Software Foundation, Inc. +# Copyright (C) 1999-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -332,7 +332,7 @@ _AM_SUBST_NOTMAKE([am__nodep])dnl # Generate code to set up dependency tracking. -*- Autoconf -*- -# Copyright (C) 1999-2014 Free Software Foundation, Inc. +# Copyright (C) 1999-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -408,7 +408,7 @@ AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], # Do all the work for Automake. -*- Autoconf -*- -# Copyright (C) 1996-2014 Free Software Foundation, Inc. +# Copyright (C) 1996-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -605,7 +605,7 @@ for _am_header in $config_headers :; do done echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) -# Copyright (C) 2001-2014 Free Software Foundation, Inc. +# Copyright (C) 2001-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -626,7 +626,7 @@ if test x"${install_sh+set}" != xset; then fi AC_SUBST([install_sh])]) -# Copyright (C) 2003-2014 Free Software Foundation, Inc. +# Copyright (C) 2003-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -647,7 +647,7 @@ AC_SUBST([am__leading_dot])]) # Check to see how 'make' treats includes. -*- Autoconf -*- -# Copyright (C) 2001-2014 Free Software Foundation, Inc. +# Copyright (C) 2001-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -697,7 +697,7 @@ rm -f confinc confmf # Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- -# Copyright (C) 1997-2014 Free Software Foundation, Inc. +# Copyright (C) 1997-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -736,7 +736,7 @@ fi # Helper functions for option handling. -*- Autoconf -*- -# Copyright (C) 2001-2014 Free Software Foundation, Inc. +# Copyright (C) 2001-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -765,7 +765,7 @@ AC_DEFUN([_AM_SET_OPTIONS], AC_DEFUN([_AM_IF_OPTION], [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) -# Copyright (C) 1999-2014 Free Software Foundation, Inc. +# Copyright (C) 1999-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -812,7 +812,7 @@ AC_LANG_POP([C])]) # For backward compatibility. AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])]) -# Copyright (C) 2001-2014 Free Software Foundation, Inc. +# Copyright (C) 2001-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -831,7 +831,7 @@ AC_DEFUN([AM_RUN_LOG], # Check to make sure that the build environment is sane. -*- Autoconf -*- -# Copyright (C) 1996-2014 Free Software Foundation, Inc. +# Copyright (C) 1996-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -912,7 +912,7 @@ AC_CONFIG_COMMANDS_PRE( rm -f conftest.file ]) -# Copyright (C) 2009-2014 Free Software Foundation, Inc. +# Copyright (C) 2009-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -972,7 +972,7 @@ AC_SUBST([AM_BACKSLASH])dnl _AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl ]) -# Copyright (C) 2001-2014 Free Software Foundation, Inc. +# Copyright (C) 2001-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -1000,7 +1000,7 @@ fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" AC_SUBST([INSTALL_STRIP_PROGRAM])]) -# Copyright (C) 2006-2014 Free Software Foundation, Inc. +# Copyright (C) 2006-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -1019,7 +1019,7 @@ AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) # Check how to create a tarball. -*- Autoconf -*- -# Copyright (C) 2004-2014 Free Software Foundation, Inc. +# Copyright (C) 2004-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff --git a/config.guess b/config.guess index 0967f2a..2e9ad7f 100755 --- a/config.guess +++ b/config.guess @@ -2,7 +2,7 @@ # Attempt to guess a canonical system name. # Copyright 1992-2016 Free Software Foundation, Inc. -timestamp='2016-04-02' +timestamp='2016-10-02' # 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 @@ -186,9 +186,12 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in *) machine=${UNAME_MACHINE_ARCH}-unknown ;; esac # The Operating System including object format, if it has switched - # to ELF recently, or will in the future. + # to ELF recently (or will in the future) and ABI. case "${UNAME_MACHINE_ARCH}" in - arm*|earm*|i386|m68k|ns32k|sh3*|sparc|vax) + earm*) + os=netbsdelf + ;; + arm*|i386|m68k|ns32k|sh3*|sparc|vax) eval $set_cc_for_build if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ELF__ @@ -997,6 +1000,9 @@ EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; } ;; + mips64el:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; openrisc*:Linux:*:*) echo or1k-unknown-linux-${LIBC} exit ;; @@ -1029,6 +1035,9 @@ EOF ppcle:Linux:*:*) echo powerpcle-unknown-linux-${LIBC} exit ;; + riscv32:Linux:*:* | riscv64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; s390:Linux:*:* | s390x:Linux:*:*) echo ${UNAME_MACHINE}-ibm-linux-${LIBC} exit ;; @@ -1408,18 +1417,17 @@ esac cat >&2 < in order to provide the needed -information to handle your system. +If $0 has already been updated, send the following data and any +information you think might be pertinent to config-patches@gnu.org to +provide the necessary information to handle your system. config.guess timestamp = $timestamp diff --git a/config.h.in b/config.h.in index 2cd4574..4b6f381 100644 --- a/config.h.in +++ b/config.h.in @@ -42,9 +42,9 @@ /* Darwin (MacOS/X) */ #undef HAVE_DARWIN -/* Define to 1 if you have the declaration of `OpenSSL_add_all_algorithms', - and to 0 if you don't. */ -#undef HAVE_DECL_OPENSSL_ADD_ALL_ALGORITHMS +/* Define to 1 if you have the declaration of `OpenSSL_add_all_algorithms + EVP_aes_256_cfb', and to 0 if you don't. */ +#undef HAVE_DECL_OPENSSL_ADD_ALL_ALGORITHMS_EVP_AES_256_CFB /* Define to 1 if you have the declaration of `res_init', and to 0 if you don't. */ diff --git a/config.sub b/config.sub index 8d39c4b..dd2ca93 100755 --- a/config.sub +++ b/config.sub @@ -2,7 +2,7 @@ # Configuration validation subroutine script. # Copyright 1992-2016 Free Software Foundation, Inc. -timestamp='2016-03-30' +timestamp='2016-11-04' # 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 @@ -117,7 +117,7 @@ case $maybe_os in nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ knetbsd*-gnu* | netbsd*-gnu* | netbsd*-eabi* | \ - kopensolaris*-gnu* | \ + kopensolaris*-gnu* | cloudabi*-eabi* | \ storm-chaos* | os2-emx* | rtmk-nova*) os=-$maybe_os basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` @@ -301,6 +301,7 @@ case $basic_machine in | open8 | or1k | or1knd | or32 \ | pdp10 | pdp11 | pj | pjl \ | powerpc | powerpc64 | powerpc64le | powerpcle \ + | pru \ | pyramid \ | riscv32 | riscv64 \ | rl78 | rx \ @@ -428,6 +429,7 @@ case $basic_machine in | orion-* \ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ + | pru-* \ | pyramid-* \ | riscv32-* | riscv64-* \ | rl78-* | romp-* | rs6000-* | rx-* \ @@ -643,6 +645,14 @@ case $basic_machine in basic_machine=m68k-bull os=-sysv3 ;; + e500v[12]) + basic_machine=powerpc-unknown + os=$os"spe" + ;; + e500v[12]-*) + basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + os=$os"spe" + ;; ebmon29k) basic_machine=a29k-amd os=-ebmon @@ -1022,7 +1032,7 @@ case $basic_machine in ppc-* | ppcbe-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` ;; - ppcle | powerpclittle | ppc-le | powerpc-little) + ppcle | powerpclittle) basic_machine=powerpcle-unknown ;; ppcle-* | powerpclittle-*) @@ -1032,7 +1042,7 @@ case $basic_machine in ;; ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; - ppc64le | powerpc64little | ppc64-le | powerpc64-little) + ppc64le | powerpc64little) basic_machine=powerpc64le-unknown ;; ppc64le-* | powerpc64little-*) @@ -1389,7 +1399,7 @@ case $os in | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ | -chorusos* | -chorusrdb* | -cegcc* \ | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ - | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \ + | -midipix* | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \ | -linux-newlib* | -linux-musl* | -linux-uclibc* \ | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ @@ -1399,7 +1409,7 @@ case $os in | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* \ - | -onefs* | -tirtos*) + | -onefs* | -tirtos* | -phoenix* | -fuchsia*) # Remember, each alternative MUST END IN *, to match a version number. ;; -qnx*) diff --git a/configure b/configure index be77e27..536bafc 100755 --- a/configure +++ b/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for tinc 1.1pre14-18-ge6497a2. +# Generated by GNU Autoconf 2.69 for tinc 1.1pre15. # # # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. @@ -577,8 +577,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='tinc' PACKAGE_TARNAME='tinc' -PACKAGE_VERSION='1.1pre14-18-ge6497a2' -PACKAGE_STRING='tinc 1.1pre14-18-ge6497a2' +PACKAGE_VERSION='1.1pre15' +PACKAGE_STRING='tinc 1.1pre15' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1346,7 +1346,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures tinc 1.1pre14-18-ge6497a2 to adapt to many kinds of systems. +\`configure' configures tinc 1.1pre15 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1417,7 +1417,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of tinc 1.1pre14-18-ge6497a2:";; + short | recursive ) echo "Configuration of tinc 1.1pre15:";; esac cat <<\_ACEOF @@ -1556,7 +1556,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -tinc configure 1.1pre14-18-ge6497a2 +tinc configure 1.1pre15 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -2021,7 +2021,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by tinc $as_me 1.1pre14-18-ge6497a2, which was +It was created by tinc $as_me 1.1pre15, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -4256,7 +4256,7 @@ fi # Define the identity of the package. PACKAGE='tinc' - VERSION='1.1pre14-18-ge6497a2' + VERSION='1.1pre15' cat >>confdefs.h <<_ACEOF @@ -7009,17 +7009,17 @@ fi done - ac_fn_c_check_decl "$LINENO" "OpenSSL_add_all_algorithms" "ac_cv_have_decl_OpenSSL_add_all_algorithms" "#include + ac_fn_c_check_decl "$LINENO" "OpenSSL_add_all_algorithms EVP_aes_256_cfb" "ac_cv_have_decl_OpenSSL_add_all_algorithms_EVP_aes_256_cfb" "#include " -if test "x$ac_cv_have_decl_OpenSSL_add_all_algorithms" = xyes; then : +if test "x$ac_cv_have_decl_OpenSSL_add_all_algorithms_EVP_aes_256_cfb" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF -#define HAVE_DECL_OPENSSL_ADD_ALL_ALGORITHMS $ac_have_decl +#define HAVE_DECL_OPENSSL_ADD_ALL_ALGORITHMS_EVP_AES_256_CFB $ac_have_decl _ACEOF if test $ac_have_decl = 1; then : @@ -7772,7 +7772,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by tinc $as_me 1.1pre14-18-ge6497a2, which was +This file was extended by tinc $as_me 1.1pre15, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -7838,7 +7838,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -tinc config.status 1.1pre14-18-ge6497a2 +tinc config.status 1.1pre15 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff --git a/depcomp b/depcomp index fc98710..b39f98f 100755 --- a/depcomp +++ b/depcomp @@ -1,9 +1,9 @@ #! /bin/sh # depcomp - compile a program generating dependencies as side-effects -scriptversion=2013-05-30.07; # UTC +scriptversion=2016-01-11.22; # UTC -# Copyright (C) 1999-2014 Free Software Foundation, Inc. +# Copyright (C) 1999-2017 Free Software Foundation, Inc. # 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 @@ -786,6 +786,6 @@ exit 0 # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" -# time-stamp-time-zone: "UTC" +# time-stamp-time-zone: "UTC0" # time-stamp-end: "; # UTC" # End: diff --git a/doc/Makefile.in b/doc/Makefile.in index 3f1feb6..07a02a1 100644 --- a/doc/Makefile.in +++ b/doc/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff --git a/doc/sample-config.tar.gz b/doc/sample-config.tar.gz index 17863e9327946b62c55959b9bea0601529da8404..05b1e898092dd87c28ea91e16443fe1b45960de6 100644 GIT binary patch literal 1242 zcmV<01SR_)iwFQ-4XarI1MOLDZ`(Kw?&tgp4n1HvpmA(BFWZ2A=-Y;3yI#?B2kg^L ziJ3&GE%_ulUH<(@DOuAryWnt1?h2S_YC9q+l9C?Mj1@(hV{@q0NRC?vJE54U7sq@} zdL4g_lXlx*=X8)HNvG59rb(I}#7W%gwhy4Q8*_F;3r7~$7ee;Q`a7wH&8pn;92}4C z->iSHm#(aT8YkTY*s>YBr5C#Xhp$=#sakf@IE1^2v@nu6f<iX{T_WkMkC6KXXCr`}sMvf;zC5dYVg|-gLTsWGb zutzYc9LNz_LS~{>ugNlP?!lQEYhXn*R0vgxJfB4kQu2ZPRs8RE;~M|>L5I-yJK$&7(wKv>LBgi18xUD$ z(Aof8guq-ec-aWf3DgMVDocPhn1Lq5GLPdnYMjnxPasK;qx85P9e1K`kEgiN#;J<2 z)F%WI(gmjxGDuOXAZu&{7dR4C?il#H1Y!*qB4u>XD*AKy4Nys`!!eweMoxu8M!&^vO3~mY;TWkI{!4da{iCwc2b}JeGt9o%y($m-{G9|JKMU=`gK=nsHXpjp7(zu zzTfH`8_s`{_S&oY|G4h|?1z5jf1iMVR{s+)(4V03g4;3N%;}e6h}QQ*oEXrJLBL#6 zHs)*>%`@Q%SUFZC%ncXoj2yarMmd&5tuQn07g2^)zr04?3Le3RC6YN^o$flX7;?Fq^iCFJ++qmju*kMlPCOjF4_XE>HlZ?L2Y%8P4!=r zJjegESL6RaXnp^Gm}^VW!8_sEZvbnX&CFS!$C_%YsivB0s;Q=$YWknkcU&{@uK*|j E0NBcJAOHXW literal 1228 zcmV;-1T*^|iwFR|bm>9%M5X+Kc*=>P*$Xkn`T^7XYfPPvj ziMEMIq()M9{qJ{2%1xZOGltp5vgu$$vU#s0pNB`o%BtYqOv$mB^bU3+A<8fe=@|_Z z_Y9+c-#r^Sh@vP-`hz%%*%o8ad<_0#{Rc_(Wc}m8AUuFArm%Z?q3eGLBew&9mLB{zs5P@fNf?WQ zcRGh~H|3x?E8yw|Se|Qc45%^KsW4!L%$#ii=S)J%p*B2+bOFjvxqcWoLFcrwJ%K1b z4&vi}aGV5#A%(b6+RD02(PFGLpphztoKQlNXOxWz;DV1?U0A@dgCq$$WQ5M}om`CS zRB{WLHwK28(6+{uD=lWsa=@Xv()T#VoP$DTI7+cx8Lom(;{x-08wb(gO%MfPFYYhr zpsLeCWN^&1$nciW} z%<9f}Mzmdm-SI@9I3kGNy#41q5r(@Wiuk1x#VY+x|L__9!)Vare;;!A zs+S7cGt(8I8*UBMl>>-n736#-G9IALm4%6zaRUogyWz3sJXa-H1-Swy7YGvsBn{7* zv@jQT3c`}@XTzOIrnE+|f@CFcko7psy9PyEA~uyQIeM8fEm(?~{d9GGcX|8%^!(D{ z20@5{$zF@e)VoA;#CA#4R29r(fYKa6S|gmtm7>|;8s0hm1@gx*XPl)WMOnQRx%E)86 zn2DTt$Wx0!dnDVOkA*~H5T2`kz|pTdV(kBYJUtIROtj1xVx&X*hC$fy#B=-y^uEi-dH_+dC+5*!K4ql#rn1B3_5Qhd>f*h1iGOs8GY zVE6=#m`F4xz!|GWW{U-GM>I7Ip@)2dC#;-!45@lDb<9z+g<}swk%EFVk3@t4f`VSk zN-JU^Y&UY2ibB{0y!#o|e_Ij-F@ev@q7ogz88d`5!=(`xvHiVgaXhr9QMu)R)Iw7+ z*Q9X*?qa;O64G)_fOn|GG@Bm8F&@=_?k9_oi-A?`luCBbsYGpfF~%7!gt1(9mBeXz zXkyU%3rz#jM%}RHGD{|(bW9ZM7o4zVPgP>?Bm9!m6cE8;5w*;jBo06KQSKBLM6KJh zo=0@$T+c;OkVA6+sH5tkP7ifM=a^F}WQp(Z@gz7KT^ymlSE{8~8Y$#G;rGg~6_XcGt+digE3LHBN-M4W%jHi(!0#*oC;$Lcyk!3X diff --git a/doc/tinc.conf.5.in b/doc/tinc.conf.5.in index 783c299..cb7d1b1 100644 --- a/doc/tinc.conf.5.in +++ b/doc/tinc.conf.5.in @@ -1,4 +1,4 @@ -.Dd 2016-04-11 +.Dd 2017-09-02 .Dt TINC.CONF 5 .\" Manual page created by: .\" Ivo Timmermans @@ -234,6 +234,10 @@ Do NOT connect multiple .Nm tinc daemons to the same multicast address, this will very likely cause routing loops. Also note that this can cause decrypted VPN packets to be sent out on a real network if misconfigured. +.It fd +Use a file descriptor. +All packets are read from this interface. +Packets received for the local node are written to it. .It uml Pq not compiled in by default Create a UNIX socket with the filename specified by .Va Device , @@ -323,6 +327,8 @@ Under Windows, this variable is used to select which network interface will be u If you specified a .Va Device , this variable is almost always already correctly set. +.It Va InvitationExpire Li = Ar seconds Pq 604800 +This option controls the period invitations are valid. .It Va KeyExpire Li = Ar seconds Pq 3600 This option controls the period the encryption keys used to encrypt the data are valid. It is common practice to change keys at regular intervals to make it even harder for crackers, @@ -363,6 +369,8 @@ and they only ConnectTo a third node outside the NAT, which normally would prevent the peers from learning each other's LAN address. .Pp Currently, local discovery is implemented by sending some packets to the local address of the node during UDP discovery. This will not work with old nodes that don't transmit their local address. +.It Va LogLevel Li = level Pq 0 +This option controls the verbosity of the logging. The higher the debug level, the more messages it will log. .It Va MACExpire Li = Ar seconds Pq 600 This option controls the amount of time MAC addresses are kept before they are removed. This only has effect when @@ -775,6 +783,10 @@ It can be used to set up the corresponding network interface. If an executable file with this name exists, it will be executed right before the tinc daemon is going to close its connection to the virtual network device. +.It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /invitations/ +This directory contains outstanding invitations. +.It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /invitation-data +After a succesful join, this file contains a copy of the invitation data received. .El .Sh SEE ALSO .Xr tincd 8 , diff --git a/doc/tinc.info b/doc/tinc.info index 9540627..419de73 100644 --- a/doc/tinc.info +++ b/doc/tinc.info @@ -1,14 +1,14 @@ -This is tinc.info, produced by makeinfo version 6.1 from tinc.texi. +This is tinc.info, produced by makeinfo version 6.4.90 from tinc.texi. INFO-DIR-SECTION Networking tools START-INFO-DIR-ENTRY * tinc: (tinc). The tinc Manual. END-INFO-DIR-ENTRY -This is the info manual for tinc version 1.1pre11-263-g51a0dc5, a +This is the info manual for tinc version 1.1pre14-62-g958a751e, a Virtual Private Network daemon. - Copyright (C) 1998-2016 Ivo Timmermans, Guus Sliepen + Copyright (C) 1998-2017 Ivo Timmermans, Guus Sliepen and Wessel Dankers . Permission is granted to make and distribute verbatim copies of this @@ -888,6 +888,11 @@ DeviceType = (platform dependent) that this can cause decrypted VPN packets to be sent out on a real network if misconfigured. + fd + Use a file descriptor. All packets are read from this + interface. Packets received for the local node are written to + it. + uml (not compiled in by default) Create a UNIX socket with the filename specified by DEVICE, or '/var/run/NETNAME.umlsocket' if not specified. Tinc will wait @@ -1008,9 +1013,9 @@ LocalDiscovery = (no) to the local address of the node during UDP discovery. This will not work with old nodes that don't transmit their local address. -LocalDiscoveryAddress
- If this variable is specified, local discovery packets are sent to - the given ADDRESS. +LogLevel = (0) + This option controls the verbosity of the logging. See *note Debug + levels::. Mode = (router) This option selects the way packets are routed to other daemons. @@ -1039,6 +1044,9 @@ Mode = (router) every packet will be broadcast to the other daemons while no routing table is managed. +InvitationExpire = (604800) + This option controls the time invitations are valid. + KeyExpire = (3600) This option controls the time the encryption keys used to encrypt the data are valid. It is common practice to change keys at @@ -1098,7 +1106,7 @@ ProcessPriority = adjusted. Increasing the priority may help to reduce latency and packet loss on the VPN. -Proxy = socks4 | socks5 | http | exec ... [experimental] +Proxy = socks4 | socks5 | http | exec ... [experimental] Use a proxy when making outgoing connections. The following proxy types are currently supported: @@ -3397,13 +3405,13 @@ Concept Index * Digest: Host configuration variables. (line 33) * DirectOnly: Main configuration variables. - (line 169) + (line 174) * disconnect: tinc commands. (line 142) * dummy: Main configuration variables. (line 106) * dump: tinc commands. (line 95) * Ed25519PrivateKeyFile: Main configuration variables. - (line 176) + (line 181) * edit: tinc commands. (line 32) * encapsulating: The UDP tunnel. (line 30) * encryption: Encryption of network packets. @@ -3414,13 +3422,15 @@ Concept Index * exchange: tinc commands. (line 48) * exchange-all: tinc commands. (line 51) * exec: Main configuration variables. - (line 357) + (line 365) * ExperimentalProtocol: Main configuration variables. - (line 180) + (line 185) * export: tinc commands. (line 36) * export-all: tinc commands. (line 40) +* fd: Main configuration variables. + (line 129) * Forwarding: Main configuration variables. - (line 187) + (line 192) * frame type: The UDP tunnel. (line 6) * fsck: tinc commands. (line 160) * generate-ed25519-keys: tinc commands. (line 86) @@ -3429,11 +3439,11 @@ Concept Index * get: tinc commands. (line 11) * graph: tinc commands. (line 108) * Hostnames: Main configuration variables. - (line 207) + (line 212) * http: Main configuration variables. - (line 354) + (line 362) * hub: Main configuration variables. - (line 275) + (line 280) * ID: Legacy authentication protocol. (line 6) * Ifconfig: Invitation file format. @@ -3444,15 +3454,17 @@ Concept Index * info: tinc commands. (line 120) * init: tinc commands. (line 6) * Interface: Main configuration variables. - (line 218) + (line 223) * INTERFACE: Scripts. (line 75) +* InvitationExpire: Main configuration variables. + (line 285) * INVITATION_FILE: Scripts. (line 98) * INVITATION_URL: Scripts. (line 102) * invite: tinc commands. (line 54) * IRC: Contact information. (line 9) * join: tinc commands. (line 59) * KeyExpire: Main configuration variables. - (line 280) + (line 288) * KEY_CHANGED: The meta-protocol. (line 63) * legacy authentication protocol: Legacy authentication protocol. (line 6) @@ -3462,31 +3474,31 @@ Concept Index * LibreSSL: LibreSSL/OpenSSL. (line 6) * license: LibreSSL/OpenSSL. (line 38) * ListenAddress: Main configuration variables. - (line 226) + (line 231) * LocalDiscovery: Main configuration variables. - (line 238) -* LocalDiscoveryAddress: Main configuration variables. - (line 249) + (line 243) * log: tinc commands. (line 130) +* LogLevel: Main configuration variables. + (line 254) * lzo: lzo. (line 6) * MACExpire: Main configuration variables. - (line 286) + (line 294) * MACLength: Host configuration variables. (line 45) * MaxConnectionBurst: Main configuration variables. - (line 291) + (line 299) * meta-protocol: The meta-connection. (line 18) * META_KEY: Legacy authentication protocol. (line 6) * Mode: Main configuration variables. - (line 253) + (line 258) * MTUInfoInterval: Host configuration variables. (line 60) * multicast: Main configuration variables. (line 118) * multiple networks: Multiple networks. (line 6) * Name: Main configuration variables. - (line 297) + (line 305) * NAME: Scripts. (line 69) * netmask: Network interfaces. (line 39) * netname: Multiple networks. (line 6) @@ -3505,9 +3517,9 @@ Concept Index * pid: tinc commands. (line 78) * PING: The meta-protocol. (line 88) * PingInterval: Main configuration variables. - (line 308) + (line 316) * PingTimeout: Main configuration variables. - (line 312) + (line 320) * platforms: Supported platforms. (line 6) * PMTU: Host configuration variables. (line 52) @@ -3518,17 +3530,17 @@ Concept Index (line 65) * port numbers: Other files. (line 17) * PriorityInheritance: Main configuration variables. - (line 318) + (line 326) * private: Virtual Private Networks. (line 10) * PrivateKey: Main configuration variables. - (line 323) + (line 331) * PrivateKeyFile: Main configuration variables. - (line 329) + (line 337) * ProcessPriority: Main configuration variables. - (line 334) + (line 342) * Proxy: Main configuration variables. - (line 339) + (line 347) * PublicKey: Host configuration variables. (line 69) * PublicKeyFile: Host configuration variables. @@ -3541,7 +3553,7 @@ Concept Index * REMOTEADDRESS: Scripts. (line 84) * REMOTEPORT: Scripts. (line 87) * ReplayWindow: Main configuration variables. - (line 362) + (line 370) * requirements: Libraries. (line 6) * REQ_KEY: The meta-protocol. (line 63) * restart: tinc commands. (line 70) @@ -3549,7 +3561,7 @@ Concept Index * Route: Invitation file format. (line 51) * router: Main configuration variables. - (line 256) + (line 261) * runtime options: Runtime options. (line 9) * scalability: tinc. (line 19) * scripts: Scripts. (line 6) @@ -3560,21 +3572,21 @@ Concept Index * sign: tinc commands. (line 172) * signals: Signals. (line 6) * socks4: Main configuration variables. - (line 343) + (line 351) * socks5: Main configuration variables. - (line 348) + (line 356) * SPTPS: Simple Peer-to-Peer Security. (line 6) * start: tinc commands. (line 64) * stop: tinc commands. (line 67) * StrictSubnets: Main configuration variables. - (line 373) + (line 381) * Subnet: Host configuration variables. (line 84) * SUBNET: Scripts. (line 91) * SVPN: Security. (line 11) * switch: Main configuration variables. - (line 264) + (line 269) * TCP: The meta-connection. (line 10) * TCPonly: Host configuration variables. (line 113) @@ -3588,42 +3600,42 @@ Concept Index * top <1>: tinc top. (line 6) * traditional VPNs: tinc. (line 19) * tunifhead: Main configuration variables. - (line 153) + (line 158) * TunnelServer: Main configuration variables. - (line 380) + (line 388) * tunnohead: Main configuration variables. - (line 147) + (line 152) * UDP: The UDP tunnel. (line 30) * UDP <1>: Encryption of network packets. (line 11) * UDPDiscoveryInterval: Main configuration variables. - (line 400) + (line 408) * UDPDiscoveryKeepaliveInterval: Main configuration variables. - (line 394) + (line 402) * UDPDiscoveryTimeout: Main configuration variables. - (line 404) + (line 412) * UDPDiscovey: Main configuration variables. - (line 387) + (line 395) * UDPInfoInterval: Main configuration variables. - (line 409) + (line 417) * UDPRcvBuf: Main configuration variables. - (line 413) + (line 421) * UDPSndBuf: Main configuration variables. - (line 419) + (line 427) * UML: Main configuration variables. - (line 129) + (line 134) * Universal tun/tap: Configuration of Linux kernels. (line 6) * UPnP: Main configuration variables. - (line 425) + (line 433) * UPnPDiscoverWait: Main configuration variables. - (line 436) + (line 444) * UPnPRefreshPeriod: Main configuration variables. - (line 440) + (line 448) * utun: Main configuration variables. - (line 160) + (line 165) * VDE: Main configuration variables. - (line 134) + (line 139) * verify: tinc commands. (line 177) * virtual: Virtual Private Networks. (line 18) @@ -3640,78 +3652,78 @@ Concept Index  Tag Table: -Node: Top821 -Node: Introduction1157 -Node: Virtual Private Networks1961 -Node: tinc3673 -Node: Supported platforms5185 -Node: Preparations5882 -Node: Configuring the kernel6138 -Node: Configuration of Linux kernels6547 -Node: Configuration of FreeBSD kernels7396 -Node: Configuration of OpenBSD kernels7861 -Node: Configuration of NetBSD kernels8218 -Node: Configuration of Solaris kernels8620 -Node: Configuration of Darwin (MacOS/X) kernels9282 -Node: Configuration of Windows10095 -Node: Libraries10634 -Node: LibreSSL/OpenSSL11091 -Node: zlib13617 -Node: lzo14639 -Node: libcurses15630 -Node: libreadline16540 -Node: Installation17477 -Node: Building and installing tinc18381 -Node: Darwin (MacOS/X) build environment19037 -Node: Cygwin (Windows) build environment19596 -Node: MinGW (Windows) build environment20181 -Node: System files20769 -Node: Device files21034 -Node: Other files21447 -Node: Configuration22060 -Node: Configuration introduction22347 -Node: Multiple networks23868 -Node: How connections work25235 -Node: Configuration files27796 -Node: Main configuration variables29428 -Node: Host configuration variables50169 -Node: Scripts56239 -Node: How to configure60139 -Node: Network interfaces64623 -Node: Example configuration67002 -Node: Running tinc72101 -Node: Runtime options72688 -Node: Signals75548 -Node: Debug levels76397 -Node: Solving problems77333 -Node: Error messages78759 -Node: Sending bug reports83076 -Node: Controlling tinc84023 -Node: tinc runtime options84759 -Node: tinc environment variables85508 -Node: tinc commands85837 -Node: tinc examples92695 -Node: tinc top93257 -Node: Invitations94842 -Node: How invitations work95505 -Node: Invitation file format97798 -Node: Writing an invitation-created script100723 -Node: Technical information101785 -Node: The connection102015 -Node: The UDP tunnel102327 -Node: The meta-connection105372 -Node: The meta-protocol106830 -Node: Security111813 -Node: Legacy authentication protocol113150 -Node: Simple Peer-to-Peer Security117767 -Node: Encryption of network packets123412 -Node: Security issues126050 -Node: Platform specific information127797 -Node: Interface configuration128025 -Node: Routes130466 -Node: About us132377 -Node: Contact information132554 -Node: Authors132957 -Node: Concept Index133361 +Node: Top824 +Node: Introduction1160 +Node: Virtual Private Networks1964 +Node: tinc3676 +Node: Supported platforms5188 +Node: Preparations5885 +Node: Configuring the kernel6141 +Node: Configuration of Linux kernels6550 +Node: Configuration of FreeBSD kernels7399 +Node: Configuration of OpenBSD kernels7864 +Node: Configuration of NetBSD kernels8221 +Node: Configuration of Solaris kernels8623 +Node: Configuration of Darwin (MacOS/X) kernels9285 +Node: Configuration of Windows10098 +Node: Libraries10637 +Node: LibreSSL/OpenSSL11094 +Node: zlib13620 +Node: lzo14642 +Node: libcurses15633 +Node: libreadline16543 +Node: Installation17480 +Node: Building and installing tinc18384 +Node: Darwin (MacOS/X) build environment19040 +Node: Cygwin (Windows) build environment19599 +Node: MinGW (Windows) build environment20184 +Node: System files20772 +Node: Device files21037 +Node: Other files21450 +Node: Configuration22063 +Node: Configuration introduction22350 +Node: Multiple networks23871 +Node: How connections work25238 +Node: Configuration files27799 +Node: Main configuration variables29431 +Node: Host configuration variables50412 +Node: Scripts56482 +Node: How to configure60382 +Node: Network interfaces64866 +Node: Example configuration67245 +Node: Running tinc72344 +Node: Runtime options72931 +Node: Signals75791 +Node: Debug levels76640 +Node: Solving problems77576 +Node: Error messages79002 +Node: Sending bug reports83319 +Node: Controlling tinc84266 +Node: tinc runtime options85002 +Node: tinc environment variables85751 +Node: tinc commands86080 +Node: tinc examples92938 +Node: tinc top93500 +Node: Invitations95085 +Node: How invitations work95748 +Node: Invitation file format98041 +Node: Writing an invitation-created script100966 +Node: Technical information102028 +Node: The connection102258 +Node: The UDP tunnel102570 +Node: The meta-connection105615 +Node: The meta-protocol107073 +Node: Security112056 +Node: Legacy authentication protocol113393 +Node: Simple Peer-to-Peer Security118010 +Node: Encryption of network packets123655 +Node: Security issues126293 +Node: Platform specific information128040 +Node: Interface configuration128268 +Node: Routes130709 +Node: About us132620 +Node: Contact information132797 +Node: Authors133200 +Node: Concept Index133604  End Tag Table diff --git a/doc/tinc.texi b/doc/tinc.texi index cb50e74..83e42c6 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-2016 Ivo Timmermans, +Copyright @copyright{} 1998-2017 Ivo Timmermans, Guus Sliepen and Wessel Dankers . @@ -43,7 +43,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-2016 Ivo Timmermans, +Copyright @copyright{} 1998-2017 Ivo Timmermans, Guus Sliepen and Wessel Dankers . @@ -958,6 +958,12 @@ This can be used to connect to UML, QEMU or KVM instances listening on the same Do NOT connect multiple tinc daemons to the same multicast address, this will very likely cause routing loops. Also note that this can cause decrypted VPN packets to be sent out on a real network if misconfigured. +@cindex fd +@item fd +Use a file descriptor. +All packets are read from this interface. +Packets received for the local node are written to it. + @cindex UML @item uml (not compiled in by default) Create a UNIX socket with the filename specified by @@ -1086,9 +1092,10 @@ which normally would prevent the peers from learning each other's LAN address. Currently, local discovery is implemented by sending some packets to the local address of the node during UDP discovery. This will not work with old nodes that don't transmit their local address. -@cindex LocalDiscoveryAddress -@item LocalDiscoveryAddress <@var{address}> -If this variable is specified, local discovery packets are sent to the given @var{address}. +@cindex LogLevel +@item LogLevel = <@var{level}> (0) +This option controls the verbosity of the logging. +See @ref{Debug levels}. @cindex Mode @item Mode = (router) @@ -1119,6 +1126,10 @@ every packet will be broadcast to the other daemons while no routing table is managed. @end table +@cindex InvitationExpire +@item InvitationExpire = <@var{seconds}> (604800) +This option controls the time invitations are valid. + @cindex KeyExpire @item KeyExpire = <@var{seconds}> (3600) This option controls the time the encryption keys used to encrypt the data diff --git a/gui/Makefile.in b/gui/Makefile.in index c81df2f..178c672 100644 --- a/gui/Makefile.in +++ b/gui/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff --git a/m4/openssl.m4 b/m4/openssl.m4 index 6bb33cf..4afcff2 100644 --- a/m4/openssl.m4 +++ b/m4/openssl.m4 @@ -49,7 +49,7 @@ AC_DEFUN([tinc_OPENSSL], [AC_MSG_ERROR([Missing LibreSSL/OpenSSL functionality, make sure you have installed the latest version.]); break], ) - AC_CHECK_DECLS([OpenSSL_add_all_algorithms], , + AC_CHECK_DECLS([OpenSSL_add_all_algorithms EVP_aes_256_cfb], , [AC_MSG_ERROR([Missing LibreSSL/OpenSSL functionality, make sure you have installed the latest version.]); break], [#include ] ) diff --git a/src/Makefile.am b/src/Makefile.am index 200c71f..7be46d9 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,6 +1,8 @@ ## Produce this file with automake to get Makefile.in -sbin_PROGRAMS = tincd tinc sptps_test sptps_keypair +sbin_PROGRAMS = tincd tinc +check_PROGRAMS = sptps_test sptps_keypair +EXTRA_PROGRAMS = sptps_test sptps_keypair CLEANFILES = version_git.h @@ -18,11 +20,10 @@ version.c: ${srcdir}/version.c endif if LINUX -sbin_PROGRAMS += sptps_speed +EXTRA_PROGRAMS += sptps_speed endif ed25519_SOURCES = \ - ed25519/add_scalar.c \ ed25519/ed25519.h \ ed25519/fe.c ed25519/fe.h \ ed25519/fixedint.h \ @@ -41,6 +42,7 @@ chacha_poly1305_SOURCES = \ chacha-poly1305/poly1305.c chacha-poly1305/poly1305.h tincd_SOURCES = \ + autoconnect.c autoconnect.h \ buffer.c buffer.h \ cipher.h \ conf.c conf.h \ @@ -58,6 +60,7 @@ tincd_SOURCES = \ edge.c edge.h \ ethernet.h \ event.c event.h \ + fd_device.c \ graph.c graph.h \ hash.c hash.h \ have.h \ diff --git a/src/Makefile.in b/src/Makefile.in index 6d5a8ce..a132cf1 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -88,8 +88,10 @@ PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ -sbin_PROGRAMS = tincd$(EXEEXT) tinc$(EXEEXT) sptps_test$(EXEEXT) \ - sptps_keypair$(EXEEXT) $(am__EXEEXT_1) +sbin_PROGRAMS = tincd$(EXEEXT) tinc$(EXEEXT) +check_PROGRAMS = sptps_test$(EXEEXT) sptps_keypair$(EXEEXT) +EXTRA_PROGRAMS = sptps_test$(EXEEXT) sptps_keypair$(EXEEXT) \ + $(am__EXEEXT_1) @LINUX_TRUE@am__append_1 = sptps_speed @GETOPT_FALSE@am__append_2 = \ @GETOPT_FALSE@ getopt.c getopt.h \ @@ -216,19 +218,18 @@ CONFIG_CLEAN_VPATH_FILES = am__installdirs = "$(DESTDIR)$(sbindir)" PROGRAMS = $(sbin_PROGRAMS) am__sptps_keypair_SOURCES_DIST = sptps_keypair.c utils.c utils.h \ - ed25519/ecdsagen.c ed25519/add_scalar.c ed25519/ed25519.h \ - ed25519/fe.c ed25519/fe.h ed25519/fixedint.h ed25519/ge.c \ - ed25519/ge.h ed25519/key_exchange.c ed25519/keypair.c \ + ed25519/ecdsagen.c ed25519/ed25519.h ed25519/fe.c ed25519/fe.h \ + ed25519/fixedint.h ed25519/ge.c ed25519/ge.h \ + ed25519/key_exchange.c ed25519/keypair.c \ ed25519/precomp_data.h ed25519/sc.c ed25519/sc.h \ ed25519/sha512.c ed25519/sha512.h ed25519/sign.c \ ed25519/verify.c getopt.c getopt.h getopt1.c openssl/crypto.c \ nolegacy/crypto.c am__dirstamp = $(am__leading_dot)dirstamp -am__objects_1 = ed25519/add_scalar.$(OBJEXT) ed25519/fe.$(OBJEXT) \ - ed25519/ge.$(OBJEXT) ed25519/key_exchange.$(OBJEXT) \ - ed25519/keypair.$(OBJEXT) ed25519/sc.$(OBJEXT) \ - ed25519/sha512.$(OBJEXT) ed25519/sign.$(OBJEXT) \ - ed25519/verify.$(OBJEXT) +am__objects_1 = ed25519/fe.$(OBJEXT) ed25519/ge.$(OBJEXT) \ + ed25519/key_exchange.$(OBJEXT) ed25519/keypair.$(OBJEXT) \ + ed25519/sc.$(OBJEXT) ed25519/sha512.$(OBJEXT) \ + ed25519/sign.$(OBJEXT) ed25519/verify.$(OBJEXT) @GETOPT_FALSE@am__objects_2 = getopt.$(OBJEXT) getopt1.$(OBJEXT) @OPENSSL_TRUE@am__objects_3 = openssl/crypto.$(OBJEXT) @GCRYPT_TRUE@@OPENSSL_FALSE@am__objects_4 = openssl/crypto.$(OBJEXT) @@ -241,9 +242,9 @@ sptps_keypair_OBJECTS = $(am_sptps_keypair_OBJECTS) sptps_keypair_LDADD = $(LDADD) am__sptps_speed_SOURCES_DIST = logger.c logger.h sptps.c sptps.h \ sptps_speed.c utils.c utils.h ed25519/ecdh.c ed25519/ecdsa.c \ - ed25519/ecdsagen.c ed25519/add_scalar.c ed25519/ed25519.h \ - ed25519/fe.c ed25519/fe.h ed25519/fixedint.h ed25519/ge.c \ - ed25519/ge.h ed25519/key_exchange.c ed25519/keypair.c \ + ed25519/ecdsagen.c ed25519/ed25519.h ed25519/fe.c ed25519/fe.h \ + ed25519/fixedint.h ed25519/ge.c ed25519/ge.h \ + ed25519/key_exchange.c ed25519/keypair.c \ ed25519/precomp_data.h ed25519/sc.c ed25519/sc.h \ ed25519/sha512.c ed25519/sha512.h ed25519/sign.c \ ed25519/verify.c chacha-poly1305/chacha.c \ @@ -272,11 +273,10 @@ sptps_speed_OBJECTS = $(am_sptps_speed_OBJECTS) sptps_speed_DEPENDENCIES = am__sptps_test_SOURCES_DIST = logger.c logger.h sptps.c sptps.h \ sptps_test.c utils.c utils.h ed25519/ecdh.c ed25519/ecdsa.c \ - ed25519/add_scalar.c ed25519/ed25519.h ed25519/fe.c \ - ed25519/fe.h ed25519/fixedint.h ed25519/ge.c ed25519/ge.h \ - ed25519/key_exchange.c ed25519/keypair.c \ - ed25519/precomp_data.h ed25519/sc.c ed25519/sc.h \ - ed25519/sha512.c ed25519/sha512.h ed25519/sign.c \ + ed25519/ed25519.h ed25519/fe.c ed25519/fe.h ed25519/fixedint.h \ + ed25519/ge.c ed25519/ge.h ed25519/key_exchange.c \ + ed25519/keypair.c ed25519/precomp_data.h ed25519/sc.c \ + ed25519/sc.h ed25519/sha512.c ed25519/sha512.h ed25519/sign.c \ ed25519/verify.c chacha-poly1305/chacha.c \ chacha-poly1305/chacha.h chacha-poly1305/chacha-poly1305.c \ chacha-poly1305/chacha-poly1305.h chacha-poly1305/poly1305.c \ @@ -300,11 +300,11 @@ am__tinc_SOURCES_DIST = dropin.c dropin.h fsck.c fsck.h ifconfig.c \ list.h names.c names.h netutl.c netutl.h script.c script.h \ sptps.c sptps.h subnet_parse.c subnet.h tincctl.c tincctl.h \ top.c top.h utils.c utils.h version.c version.h ed25519/ecdh.c \ - ed25519/ecdsa.c ed25519/ecdsagen.c ed25519/add_scalar.c \ - ed25519/ed25519.h ed25519/fe.c ed25519/fe.h ed25519/fixedint.h \ - ed25519/ge.c ed25519/ge.h ed25519/key_exchange.c \ - ed25519/keypair.c ed25519/precomp_data.h ed25519/sc.c \ - ed25519/sc.h ed25519/sha512.c ed25519/sha512.h ed25519/sign.c \ + ed25519/ecdsa.c ed25519/ecdsagen.c ed25519/ed25519.h \ + ed25519/fe.c ed25519/fe.h ed25519/fixedint.h ed25519/ge.c \ + ed25519/ge.h ed25519/key_exchange.c ed25519/keypair.c \ + ed25519/precomp_data.h ed25519/sc.c ed25519/sc.h \ + ed25519/sha512.c ed25519/sha512.h ed25519/sign.c \ ed25519/verify.c chacha-poly1305/chacha.c \ chacha-poly1305/chacha.h chacha-poly1305/chacha-poly1305.c \ chacha-poly1305/chacha-poly1305.h chacha-poly1305/poly1305.c \ @@ -336,23 +336,23 @@ am_tinc_OBJECTS = dropin.$(OBJEXT) fsck.$(OBJEXT) ifconfig.$(OBJEXT) \ tinc_OBJECTS = $(am_tinc_OBJECTS) am__DEPENDENCIES_1 = tinc_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) -am__tincd_SOURCES_DIST = buffer.c buffer.h cipher.h conf.c conf.h \ - connection.c connection.h control.c control.h control_common.h \ - crypto.h device.h digest.h dropin.c dropin.h dummy_device.c \ - ecdh.h ecdsa.h ecdsagen.h edge.c edge.h ethernet.h event.c \ - event.h graph.c graph.h hash.c hash.h have.h ipv4.h ipv6.h \ - list.c list.h logger.c logger.h meta.c meta.h \ - multicast_device.c names.c names.h net.c net.h net_packet.c \ - net_setup.c net_socket.c netutl.c netutl.h node.c node.h prf.h \ - process.c process.h protocol.c protocol.h protocol_auth.c \ - protocol_edge.c protocol_key.c protocol_misc.c \ - protocol_subnet.c raw_socket_device.c route.c route.h rsa.h \ - rsagen.h script.c script.h splay_tree.c splay_tree.h sptps.c \ - sptps.h subnet.c subnet.h subnet_parse.c system.h tincd.c \ - utils.c utils.h xalloc.h version.c version.h ed25519/ecdh.c \ - ed25519/ecdsa.c ed25519/add_scalar.c ed25519/ed25519.h \ - ed25519/fe.c ed25519/fe.h ed25519/fixedint.h ed25519/ge.c \ - ed25519/ge.h ed25519/key_exchange.c ed25519/keypair.c \ +am__tincd_SOURCES_DIST = autoconnect.c autoconnect.h buffer.c buffer.h \ + cipher.h conf.c conf.h connection.c connection.h control.c \ + control.h control_common.h crypto.h device.h digest.h dropin.c \ + dropin.h dummy_device.c ecdh.h ecdsa.h ecdsagen.h edge.c \ + edge.h ethernet.h event.c event.h fd_device.c graph.c graph.h \ + hash.c hash.h have.h ipv4.h ipv6.h list.c list.h logger.c \ + logger.h meta.c meta.h multicast_device.c names.c names.h \ + net.c net.h net_packet.c net_setup.c net_socket.c netutl.c \ + netutl.h node.c node.h prf.h process.c process.h protocol.c \ + protocol.h protocol_auth.c protocol_edge.c protocol_key.c \ + protocol_misc.c protocol_subnet.c raw_socket_device.c route.c \ + route.h rsa.h rsagen.h script.c script.h splay_tree.c \ + splay_tree.h sptps.c sptps.h subnet.c subnet.h subnet_parse.c \ + system.h tincd.c utils.c utils.h xalloc.h version.c version.h \ + ed25519/ecdh.c ed25519/ecdsa.c ed25519/ed25519.h ed25519/fe.c \ + ed25519/fe.h ed25519/fixedint.h ed25519/ge.c ed25519/ge.h \ + ed25519/key_exchange.c ed25519/keypair.c \ ed25519/precomp_data.h ed25519/sc.c ed25519/sc.h \ ed25519/sha512.c ed25519/sha512.h ed25519/sign.c \ ed25519/verify.c chacha-poly1305/chacha.c \ @@ -384,14 +384,15 @@ am__tincd_SOURCES_DIST = buffer.c buffer.h cipher.h conf.c conf.h \ @GCRYPT_TRUE@@OPENSSL_FALSE@ gcrypt/prf.$(OBJEXT) \ @GCRYPT_TRUE@@OPENSSL_FALSE@ gcrypt/rsa.$(OBJEXT) @MINIUPNPC_TRUE@am__objects_23 = upnp.$(OBJEXT) -am_tincd_OBJECTS = buffer.$(OBJEXT) conf.$(OBJEXT) \ - connection.$(OBJEXT) control.$(OBJEXT) dropin.$(OBJEXT) \ - dummy_device.$(OBJEXT) edge.$(OBJEXT) event.$(OBJEXT) \ - graph.$(OBJEXT) hash.$(OBJEXT) list.$(OBJEXT) logger.$(OBJEXT) \ - meta.$(OBJEXT) multicast_device.$(OBJEXT) names.$(OBJEXT) \ - net.$(OBJEXT) net_packet.$(OBJEXT) net_setup.$(OBJEXT) \ - net_socket.$(OBJEXT) netutl.$(OBJEXT) node.$(OBJEXT) \ - process.$(OBJEXT) protocol.$(OBJEXT) protocol_auth.$(OBJEXT) \ +am_tincd_OBJECTS = autoconnect.$(OBJEXT) buffer.$(OBJEXT) \ + conf.$(OBJEXT) connection.$(OBJEXT) control.$(OBJEXT) \ + dropin.$(OBJEXT) dummy_device.$(OBJEXT) edge.$(OBJEXT) \ + event.$(OBJEXT) fd_device.$(OBJEXT) graph.$(OBJEXT) \ + hash.$(OBJEXT) list.$(OBJEXT) logger.$(OBJEXT) meta.$(OBJEXT) \ + multicast_device.$(OBJEXT) names.$(OBJEXT) net.$(OBJEXT) \ + net_packet.$(OBJEXT) net_setup.$(OBJEXT) net_socket.$(OBJEXT) \ + netutl.$(OBJEXT) node.$(OBJEXT) process.$(OBJEXT) \ + protocol.$(OBJEXT) protocol_auth.$(OBJEXT) \ protocol_edge.$(OBJEXT) protocol_key.$(OBJEXT) \ protocol_misc.$(OBJEXT) protocol_subnet.$(OBJEXT) \ raw_socket_device.$(OBJEXT) route.$(OBJEXT) script.$(OBJEXT) \ @@ -570,7 +571,6 @@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ CLEANFILES = version_git.h ed25519_SOURCES = \ - ed25519/add_scalar.c \ ed25519/ed25519.h \ ed25519/fe.c ed25519/fe.h \ ed25519/fixedint.h \ @@ -588,16 +588,16 @@ chacha_poly1305_SOURCES = \ chacha-poly1305/chacha-poly1305.c chacha-poly1305/chacha-poly1305.h \ chacha-poly1305/poly1305.c chacha-poly1305/poly1305.h -tincd_SOURCES = buffer.c buffer.h cipher.h conf.c conf.h connection.c \ - connection.h control.c control.h control_common.h crypto.h \ - device.h digest.h dropin.c dropin.h dummy_device.c ecdh.h \ - ecdsa.h ecdsagen.h edge.c edge.h ethernet.h event.c event.h \ - graph.c graph.h hash.c hash.h have.h ipv4.h ipv6.h list.c \ - list.h logger.c logger.h meta.c meta.h multicast_device.c \ - names.c names.h net.c net.h net_packet.c net_setup.c \ - net_socket.c netutl.c netutl.h node.c node.h prf.h process.c \ - process.h protocol.c protocol.h protocol_auth.c \ - protocol_edge.c protocol_key.c protocol_misc.c \ +tincd_SOURCES = autoconnect.c autoconnect.h buffer.c buffer.h cipher.h \ + conf.c conf.h connection.c connection.h control.c control.h \ + control_common.h crypto.h device.h digest.h dropin.c dropin.h \ + dummy_device.c ecdh.h ecdsa.h ecdsagen.h edge.c edge.h \ + ethernet.h event.c event.h fd_device.c graph.c graph.h hash.c \ + hash.h have.h ipv4.h ipv6.h list.c list.h logger.c logger.h \ + meta.c meta.h multicast_device.c names.c names.h net.c net.h \ + net_packet.c net_setup.c net_socket.c netutl.c netutl.h node.c \ + node.h prf.h process.c process.h protocol.c protocol.h \ + protocol_auth.c protocol_edge.c protocol_key.c protocol_misc.c \ protocol_subnet.c raw_socket_device.c route.c route.h rsa.h \ rsagen.h script.c script.h splay_tree.c splay_tree.h sptps.c \ sptps.h subnet.c subnet.h subnet_parse.c system.h tincd.c \ @@ -666,6 +666,9 @@ $(top_srcdir)/configure: $(am__configure_deps) $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): + +clean-checkPROGRAMS: + -test -z "$(check_PROGRAMS)" || rm -f $(check_PROGRAMS) install-sbinPROGRAMS: $(sbin_PROGRAMS) @$(NORMAL_INSTALL) @list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \ @@ -732,8 +735,6 @@ ed25519/$(DEPDIR)/$(am__dirstamp): @: > ed25519/$(DEPDIR)/$(am__dirstamp) ed25519/ecdsagen.$(OBJEXT): ed25519/$(am__dirstamp) \ ed25519/$(DEPDIR)/$(am__dirstamp) -ed25519/add_scalar.$(OBJEXT): ed25519/$(am__dirstamp) \ - ed25519/$(DEPDIR)/$(am__dirstamp) ed25519/fe.$(OBJEXT): ed25519/$(am__dirstamp) \ ed25519/$(DEPDIR)/$(am__dirstamp) ed25519/ge.$(OBJEXT): ed25519/$(am__dirstamp) \ @@ -892,6 +893,7 @@ mostlyclean-compile: distclean-compile: -rm -f *.tab.c +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/autoconnect.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/buffer.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/conf.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/connection.Po@am__quote@ @@ -900,6 +902,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dummy_device.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/edge.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/event.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fd_device.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fsck.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getopt.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getopt1.Po@am__quote@ @@ -950,7 +953,6 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@chacha-poly1305/$(DEPDIR)/chacha.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@chacha-poly1305/$(DEPDIR)/poly1305.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@cygwin/$(DEPDIR)/device.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/add_scalar.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/ecdh.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/ecdsa.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/ecdsagen.Po@am__quote@ @@ -1079,6 +1081,7 @@ distdir: $(DISTFILES) fi; \ done check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) check: check-am all-am: Makefile $(PROGRAMS) installdirs: @@ -1138,7 +1141,8 @@ maintainer-clean-generic: @echo "it deletes files that may require special tools to rebuild." clean: clean-am -clean-am: clean-generic clean-sbinPROGRAMS mostlyclean-am +clean-am: clean-checkPROGRAMS clean-generic clean-sbinPROGRAMS \ + mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) bsd/$(DEPDIR) chacha-poly1305/$(DEPDIR) cygwin/$(DEPDIR) ed25519/$(DEPDIR) gcrypt/$(DEPDIR) linux/$(DEPDIR) mingw/$(DEPDIR) nolegacy/$(DEPDIR) openssl/$(DEPDIR) solaris/$(DEPDIR) @@ -1205,21 +1209,22 @@ ps-am: uninstall-am: uninstall-sbinPROGRAMS -.MAKE: install-am install-strip +.MAKE: check-am install-am install-strip -.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ - clean-sbinPROGRAMS cscopelist-am ctags ctags-am distclean \ - distclean-compile distclean-generic distclean-tags distdir dvi \ - dvi-am html html-am info info-am install install-am \ - install-data install-data-am install-dvi install-dvi-am \ - install-exec install-exec-am install-html install-html-am \ - install-info install-info-am install-man install-pdf \ - install-pdf-am install-ps install-ps-am install-sbinPROGRAMS \ - install-strip installcheck installcheck-am \ - installcheck-sbinPROGRAMS installdirs maintainer-clean \ - maintainer-clean-generic mostlyclean mostlyclean-compile \ - mostlyclean-generic pdf pdf-am ps ps-am tags tags-am uninstall \ - uninstall-am uninstall-sbinPROGRAMS +.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean \ + clean-checkPROGRAMS clean-generic clean-sbinPROGRAMS \ + cscopelist-am ctags ctags-am distclean distclean-compile \ + distclean-generic distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-ps install-ps-am install-sbinPROGRAMS install-strip \ + installcheck installcheck-am installcheck-sbinPROGRAMS \ + installdirs maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-compile mostlyclean-generic pdf pdf-am \ + ps ps-am tags tags-am uninstall uninstall-am \ + uninstall-sbinPROGRAMS .PRECIOUS: Makefile diff --git a/src/autoconnect.c b/src/autoconnect.c new file mode 100644 index 0000000..1ea51b5 --- /dev/null +++ b/src/autoconnect.c @@ -0,0 +1,174 @@ +/* + autoconnect.c -- automatic connection establishment + Copyright (C) 2017 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "system.h" + +#include "connection.h" +#include "logger.h" +#include "node.h" +#include "xalloc.h" + +static void make_new_connection() { + /* Select a random node we haven't connected to yet. */ + int count = 0; + for splay_each(node_t, n, node_tree) { + if(n == myself || n->connection || !(n->status.has_address || n->status.reachable)) + continue; + count++; + } + + if(!count) + return; + + int r = rand() % count; + + for splay_each(node_t, n, node_tree) { + if(n == myself || n->connection || !(n->status.has_address || n->status.reachable)) + continue; + + if(r--) + continue; + + bool found = false; + + for list_each(outgoing_t, outgoing, outgoing_list) { + if(!strcmp(outgoing->name, n->name)) { + found = true; + break; + } + } + + if(!found) { + logger(DEBUG_CONNECTIONS, LOG_INFO, "Autoconnecting to %s", n->name); + outgoing_t *outgoing = xzalloc(sizeof *outgoing); + outgoing->name = xstrdup(n->name); + list_insert_tail(outgoing_list, outgoing); + setup_outgoing_connection(outgoing); + } + + break; + } +} + +static void connect_to_unreachable() { + /* Select a random known node. The rationale is that if there are many + * reachable nodes, and only a few unreachable nodes, we don't want all + * reachable nodes to try to connect to the unreachable ones at the + * same time. This way, we back off automatically. Conversely, if there + * are only a few reachable nodes, and many unreachable ones, we're + * going to try harder to connect to them. */ + + int r = rand() % node_tree->count; + + for splay_each(node_t, n, node_tree) { + if(r--) + continue; + + /* Is it unreachable and do we know an address for it? If not, return. */ + if(n == myself || n->connection || n->status.reachable || !n->status.has_address) + return; + + /* Are we already trying to make an outgoing connection to it? If not, return. */ + for list_each(outgoing_t, outgoing, outgoing_list) + if(!strcmp(outgoing->name, n->name)) + return; + + logger(DEBUG_CONNECTIONS, LOG_INFO, "Autoconnecting to %s", n->name); + outgoing_t *outgoing = xzalloc(sizeof *outgoing); + outgoing->name = xstrdup(n->name); + list_insert_tail(outgoing_list, outgoing); + setup_outgoing_connection(outgoing); + + return; + } +} + +static void drop_superfluous_outgoing_connection() { + /* Choose a random outgoing connection to a node that has at least one other connection. */ + int count = 0; + for list_each(connection_t, c, connection_list) { + if(!c->edge || !c->outgoing || !c->node || c->node->edge_tree->count < 2) + continue; + count++; + } + + if(!count) + return; + + int r = rand() % count; + + for list_each(connection_t, c, connection_list) { + if(!c->edge || !c->outgoing || !c->node || c->node->edge_tree->count < 2) + continue; + + if(r--) + continue; + + logger(DEBUG_CONNECTIONS, LOG_INFO, "Autodisconnecting from %s", c->name); + list_delete(outgoing_list, c->outgoing); + c->outgoing = NULL; + terminate_connection(c, c->edge); + break; + } +} + +static void drop_superfluous_pending_connections() { + for list_each(outgoing_t, o, outgoing_list) { + /* Only look for connections that are waiting to be retried later. */ + bool found = false; + for list_each(connection_t, c, connection_list) { + if(c->outgoing == o) { + found = true; + break; + } + } + + if(found) + continue; + + logger(DEBUG_CONNECTIONS, LOG_INFO, "Cancelled outgoing connection to %s", o->name); + list_delete_node(outgoing_list, node); + } +} + +void do_autoconnect() { + /* Count number of active connections. */ + int nc = 0; + for list_each(connection_t, c, connection_list) { + if(c->edge) + nc++; + } + + /* Less than 3 connections? Eagerly try to make a new one. */ + if(nc < 3) { + make_new_connection(); + return; + } + + /* More than 3 connections? See if we can get rid of a superfluous one. */ + if(nc > 3) + drop_superfluous_outgoing_connection(); + + + /* Check if there are unreachable nodes that we should try to connect to. */ + connect_to_unreachable(); + + /* Drop pending outgoing connections from the outgoing list. */ + drop_superfluous_pending_connections(); +} diff --git a/src/autoconnect.h b/src/autoconnect.h new file mode 100644 index 0000000..dc3ee1c --- /dev/null +++ b/src/autoconnect.h @@ -0,0 +1,25 @@ +/* + autoconnect.h -- header for autoconnect.c + Copyright (C) 2017 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#ifndef __TINC_AUTOCONNECT_H__ +#define __TINC_AUTOCONNECT_H__ + +extern void do_autoconnect(void); + +#endif diff --git a/src/bsd/device.c b/src/bsd/device.c index 5428262..4a63e84 100644 --- a/src/bsd/device.c +++ b/src/bsd/device.c @@ -1,7 +1,7 @@ /* device.c -- Interaction BSD tun/tap device Copyright (C) 2001-2005 Ivo Timmermans, - 2001-2016 Guus Sliepen + 2001-2017 Guus Sliepen 2009 Grzegorz Dymarek This program is free software; you can redistribute it and/or modify @@ -198,18 +198,19 @@ static bool setup_device(void) { // Guess what the corresponding interface is called - char *realname; + char *realname = NULL; #if defined(HAVE_FDEVNAME) - realname = fdevname(device_fd) ? : device; + realname = fdevname(device_fd); #elif defined(HAVE_DEVNAME) struct stat buf; if(!fstat(device_fd, &buf)) - realname = devname(buf.st_rdev, S_IFCHR) ? : device; -#else - realname = device; + realname = devname(buf.st_rdev, S_IFCHR); #endif + if(!realname) + realname = device; + if(!get_config_string(lookup_config(config_tree, "Interface"), &iface)) iface = xstrdup(strrchr(realname, '/') ? strrchr(realname, '/') + 1 : realname); else if(strcmp(iface, strrchr(realname, '/') ? strrchr(realname, '/') + 1 : realname)) diff --git a/src/cipher.h b/src/cipher.h index 3f98c18..44db40f 100644 --- a/src/cipher.h +++ b/src/cipher.h @@ -1,6 +1,6 @@ /* cipher.h -- header file cipher.c - Copyright (C) 2007-2013 Guus Sliepen + Copyright (C) 2007-2016 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 @@ -30,10 +30,10 @@ typedef struct cipher cipher_t; extern cipher_t *cipher_open_by_name(const char *) __attribute__ ((__malloc__)); extern cipher_t *cipher_open_by_nid(int) __attribute__ ((__malloc__)); -extern cipher_t *cipher_open_blowfish_ofb(void) __attribute__ ((__malloc__)); extern void cipher_close(cipher_t *); extern size_t cipher_keylength(const cipher_t *); extern size_t cipher_blocksize(const cipher_t *); +extern uint64_t cipher_budget(const cipher_t *); extern void cipher_get_key(const cipher_t *, void *); extern bool cipher_set_key(cipher_t *, void *, bool) __attribute__ ((__warn_unused_result__)); extern bool cipher_set_key_from_rsa(cipher_t *, void *, size_t, bool) __attribute__ ((__warn_unused_result__)); diff --git a/src/connection.h b/src/connection.h index 7fa769f..acd77bc 100644 --- a/src/connection.h +++ b/src/connection.h @@ -81,6 +81,8 @@ typedef struct connection_t { cipher_t *outcipher; /* Cipher we will use to send data to him */ digest_t *indigest; digest_t *outdigest; + uint64_t inbudget; + uint64_t outbudget; #endif ecdsa_t *ecdsa; /* his public ECDSA key */ diff --git a/src/device.h b/src/device.h index 8046a25..fa27df3 100644 --- a/src/device.h +++ b/src/device.h @@ -40,6 +40,7 @@ extern const devops_t os_devops; extern const devops_t dummy_devops; extern const devops_t raw_socket_devops; extern const devops_t multicast_devops; +extern const devops_t fd_devops; extern const devops_t uml_devops; extern const devops_t vde_devops; extern devops_t devops; diff --git a/src/digest.h b/src/digest.h index 204048a..a3691bf 100644 --- a/src/digest.h +++ b/src/digest.h @@ -1,6 +1,6 @@ /* digest.h -- header file digest.c - Copyright (C) 2007-2013 Guus Sliepen + Copyright (C) 2007-2016 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 @@ -28,7 +28,6 @@ typedef struct digest digest_t; extern digest_t *digest_open_by_name(const char *name, int maclength) __attribute__ ((__malloc__)); extern digest_t *digest_open_by_nid(int nid, int maclength) __attribute__ ((__malloc__)); -extern digest_t *digest_open_sha1(int maclength) __attribute__ ((__malloc__)); extern void digest_close(digest_t *); extern bool digest_create(digest_t *, const void *indata, size_t inlen, void *outdata) __attribute__ ((__warn_unused_result__)); extern bool digest_verify(digest_t *, const void *indata, size_t inlen, const void *digestdata) __attribute__ ((__warn_unused_result__)); diff --git a/src/dropin.c b/src/dropin.c index c7b558a..a4f7a65 100644 --- a/src/dropin.c +++ b/src/dropin.c @@ -106,14 +106,13 @@ int vasprintf(char **buf, const char *fmt, va_list ap) { va_copy(aq, ap); status = vsnprintf(*buf, len, fmt, aq); - buf[len - 1] = 0; va_end(aq); if(status >= 0) *buf = xrealloc(*buf, status + 1); if(status > len - 1) { - len = status; + len = status + 1; va_copy(aq, ap); status = vsnprintf(*buf, len, fmt, aq); va_end(aq); diff --git a/src/ed25519/add_scalar.c b/src/ed25519/add_scalar.c deleted file mode 100644 index 262ec72..0000000 --- a/src/ed25519/add_scalar.c +++ /dev/null @@ -1,56 +0,0 @@ -#include "ed25519.h" -#include "ge.h" -#include "sc.h" - - -/* see http://crypto.stackexchange.com/a/6215/4697 */ -void ed25519_add_scalar(unsigned char *public_key, unsigned char *private_key, const unsigned char *scalar) { - const unsigned char SC_1[32] = {1}; /* scalar with value 1 */ - - unsigned char n[32]; - ge_p3 nB; - ge_p1p1 A_p1p1; - ge_p3 A; - ge_p3 public_key_unpacked; - ge_cached T; - - int i; - - /* copy the scalar and clear highest bit */ - for (i = 0; i < 31; ++i) { - n[i] = scalar[i]; - } - n[31] = scalar[31] & 127; - - /* private key: a = n + t */ - if (private_key) { - sc_muladd(private_key, SC_1, n, private_key); - } - - /* public key: A = nB + T */ - if (public_key) { - /* if we know the private key we don't need a point addition, which is faster */ - /* using a "timing attack" you could find out wether or not we know the private - key, but this information seems rather useless - if this is important pass - public_key and private_key seperately in 2 function calls */ - if (private_key) { - ge_scalarmult_base(&A, private_key); - } else { - /* unpack public key into T */ - ge_frombytes_negate_vartime(&public_key_unpacked, public_key); - fe_neg(public_key_unpacked.X, public_key_unpacked.X); // undo negate - fe_neg(public_key_unpacked.T, public_key_unpacked.T); // undo negate - ge_p3_to_cached(&T, &public_key_unpacked); - - /* calculate n*B */ - ge_scalarmult_base(&nB, n); - - /* A = n*B + T */ - ge_add(&A_p1p1, &nB, &T); - ge_p1p1_to_p3(&A, &A_p1p1); - } - - /* pack public key */ - ge_p3_tobytes(public_key, &A); - } -} diff --git a/src/ed25519/ed25519.h b/src/ed25519/ed25519.h index bb34f89..5cb82d5 100644 --- a/src/ed25519/ed25519.h +++ b/src/ed25519/ed25519.h @@ -27,7 +27,6 @@ int ED25519_DECLSPEC ed25519_create_seed(unsigned char *seed); void ED25519_DECLSPEC ed25519_create_keypair(unsigned char *public_key, unsigned char *private_key, const unsigned char *seed); void ED25519_DECLSPEC ed25519_sign(unsigned char *signature, const unsigned char *message, size_t message_len, const unsigned char *public_key, const unsigned char *private_key); int ED25519_DECLSPEC ed25519_verify(const unsigned char *signature, const unsigned char *message, size_t message_len, const unsigned char *private_key); -void ED25519_DECLSPEC ed25519_add_scalar(unsigned char *public_key, unsigned char *private_key, const unsigned char *scalar); void ED25519_DECLSPEC ed25519_key_exchange(unsigned char *shared_secret, const unsigned char *public_key, const unsigned char *private_key); diff --git a/src/ed25519/sc.c b/src/ed25519/sc.c index 42cfc2d..3364de4 100644 --- a/src/ed25519/sc.c +++ b/src/ed25519/sc.c @@ -81,42 +81,36 @@ void sc_reduce(unsigned char *s) { s14 -= s23 * 997805; s15 += s23 * 136657; s16 -= s23 * 683901; - s23 = 0; s10 += s22 * 666643; s11 += s22 * 470296; s12 += s22 * 654183; s13 -= s22 * 997805; s14 += s22 * 136657; s15 -= s22 * 683901; - s22 = 0; s9 += s21 * 666643; s10 += s21 * 470296; s11 += s21 * 654183; s12 -= s21 * 997805; s13 += s21 * 136657; s14 -= s21 * 683901; - s21 = 0; s8 += s20 * 666643; s9 += s20 * 470296; s10 += s20 * 654183; s11 -= s20 * 997805; s12 += s20 * 136657; s13 -= s20 * 683901; - s20 = 0; s7 += s19 * 666643; s8 += s19 * 470296; s9 += s19 * 654183; s10 -= s19 * 997805; s11 += s19 * 136657; s12 -= s19 * 683901; - s19 = 0; s6 += s18 * 666643; s7 += s18 * 470296; s8 += s18 * 654183; s9 -= s18 * 997805; s10 += s18 * 136657; s11 -= s18 * 683901; - s18 = 0; carry6 = (s6 + (1 << 20)) >> 21; s7 += carry6; s6 -= shl64(carry6, 21); @@ -156,35 +150,30 @@ void sc_reduce(unsigned char *s) { s8 -= s17 * 997805; s9 += s17 * 136657; s10 -= s17 * 683901; - s17 = 0; s4 += s16 * 666643; s5 += s16 * 470296; s6 += s16 * 654183; s7 -= s16 * 997805; s8 += s16 * 136657; s9 -= s16 * 683901; - s16 = 0; s3 += s15 * 666643; s4 += s15 * 470296; s5 += s15 * 654183; s6 -= s15 * 997805; s7 += s15 * 136657; s8 -= s15 * 683901; - s15 = 0; s2 += s14 * 666643; s3 += s14 * 470296; s4 += s14 * 654183; s5 -= s14 * 997805; s6 += s14 * 136657; s7 -= s14 * 683901; - s14 = 0; s1 += s13 * 666643; s2 += s13 * 470296; s3 += s13 * 654183; s4 -= s13 * 997805; s5 += s13 * 136657; s6 -= s13 * 683901; - s13 = 0; s0 += s12 * 666643; s1 += s12 * 470296; s2 += s12 * 654183; @@ -277,7 +266,6 @@ void sc_reduce(unsigned char *s) { s3 -= s12 * 997805; s4 += s12 * 136657; s5 -= s12 * 683901; - s12 = 0; carry0 = s0 >> 21; s1 += carry0; s0 -= shl64(carry0, 21); @@ -543,42 +531,36 @@ void sc_muladd(unsigned char *s, const unsigned char *a, const unsigned char *b, s14 -= s23 * 997805; s15 += s23 * 136657; s16 -= s23 * 683901; - s23 = 0; s10 += s22 * 666643; s11 += s22 * 470296; s12 += s22 * 654183; s13 -= s22 * 997805; s14 += s22 * 136657; s15 -= s22 * 683901; - s22 = 0; s9 += s21 * 666643; s10 += s21 * 470296; s11 += s21 * 654183; s12 -= s21 * 997805; s13 += s21 * 136657; s14 -= s21 * 683901; - s21 = 0; s8 += s20 * 666643; s9 += s20 * 470296; s10 += s20 * 654183; s11 -= s20 * 997805; s12 += s20 * 136657; s13 -= s20 * 683901; - s20 = 0; s7 += s19 * 666643; s8 += s19 * 470296; s9 += s19 * 654183; s10 -= s19 * 997805; s11 += s19 * 136657; s12 -= s19 * 683901; - s19 = 0; s6 += s18 * 666643; s7 += s18 * 470296; s8 += s18 * 654183; s9 -= s18 * 997805; s10 += s18 * 136657; s11 -= s18 * 683901; - s18 = 0; carry6 = (s6 + (1 << 20)) >> 21; s7 += carry6; s6 -= shl64(carry6, 21); @@ -618,35 +600,30 @@ void sc_muladd(unsigned char *s, const unsigned char *a, const unsigned char *b, s8 -= s17 * 997805; s9 += s17 * 136657; s10 -= s17 * 683901; - s17 = 0; s4 += s16 * 666643; s5 += s16 * 470296; s6 += s16 * 654183; s7 -= s16 * 997805; s8 += s16 * 136657; s9 -= s16 * 683901; - s16 = 0; s3 += s15 * 666643; s4 += s15 * 470296; s5 += s15 * 654183; s6 -= s15 * 997805; s7 += s15 * 136657; s8 -= s15 * 683901; - s15 = 0; s2 += s14 * 666643; s3 += s14 * 470296; s4 += s14 * 654183; s5 -= s14 * 997805; s6 += s14 * 136657; s7 -= s14 * 683901; - s14 = 0; s1 += s13 * 666643; s2 += s13 * 470296; s3 += s13 * 654183; s4 -= s13 * 997805; s5 += s13 * 136657; s6 -= s13 * 683901; - s13 = 0; s0 += s12 * 666643; s1 += s12 * 470296; s2 += s12 * 654183; @@ -739,7 +716,6 @@ void sc_muladd(unsigned char *s, const unsigned char *a, const unsigned char *b, s3 -= s12 * 997805; s4 += s12 * 136657; s5 -= s12 * 683901; - s12 = 0; carry0 = s0 >> 21; s1 += carry0; s0 -= shl64(carry0, 21); diff --git a/src/ethernet.h b/src/ethernet.h index 085e96a..0b4a1db 100644 --- a/src/ethernet.h +++ b/src/ethernet.h @@ -25,6 +25,15 @@ #define ETH_ALEN 6 #endif +#ifndef ETH_HLEN +#define ETH_HLEN 14 +#endif + +#ifndef ETHER_TYPE_LEN +#define ETHER_TYPE_LEN 2 +#endif + + #ifndef ARPHRD_ETHER #define ARPHRD_ETHER 1 #endif @@ -45,6 +54,10 @@ #define ETH_P_8021Q 0x8100 #endif +#ifndef ETH_P_MAX +#define ETH_P_MAX 0xFFFF +#endif + #ifndef HAVE_STRUCT_ETHER_HEADER struct ether_header { uint8_t ether_dhost[ETH_ALEN]; diff --git a/src/event.c b/src/event.c index 59b96e3..858e1d9 100644 --- a/src/event.c +++ b/src/event.c @@ -357,10 +357,13 @@ bool event_loop(void) { WSANETWORKEVENTS network_events; if (WSAEnumNetworkEvents(io->fd, io->event, &network_events) != 0) return false; - if (network_events.lNetworkEvents & WRITE_EVENTS) - io->cb(io->data, IO_WRITE); if (network_events.lNetworkEvents & READ_EVENTS) io->cb(io->data, IO_READ); + /* + The fd might be available for write too. However, if we already fired the read callback, that + callback might have deleted the io (e.g. through terminate_connection()), so we can't fire the + write callback here. Instead, we loop back and let the writable io loop above handle it. + */ } } #endif diff --git a/src/fd_device.c b/src/fd_device.c new file mode 100644 index 0000000..67e0cb7 --- /dev/null +++ b/src/fd_device.c @@ -0,0 +1,123 @@ +/* + fd_device.c -- Interaction with Android tun fd + Copyright (C) 2001-2005 Ivo Timmermans, + 2001-2016 Guus Sliepen + 2009 Grzegorz Dymarek + 2016 Pacien TRAN-GIRARD + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "system.h" +#include "conf.h" +#include "device.h" +#include "ethernet.h" +#include "logger.h" +#include "net.h" +#include "route.h" +#include "utils.h" + +static inline bool check_config(void) { + if(routing_mode == RMODE_SWITCH) { + logger(DEBUG_ALWAYS, LOG_ERR, "Switch mode not supported (requires unsupported TAP device)!"); + return false; + } + + if(!get_config_int(lookup_config(config_tree, "Device"), &device_fd)) { + logger(DEBUG_ALWAYS, LOG_ERR, "Could not read fd from configuration!"); + return false; + } + + return true; +} + +static bool setup_device(void) { + if(!check_config()) { + return false; + } + + if(device_fd < 0) { + logger(DEBUG_ALWAYS, LOG_ERR, "Could not open %s: %s!", device, strerror(errno)); + return false; + } + + logger(DEBUG_ALWAYS, LOG_INFO, "fd/%d adapter set up.", device_fd); + + return true; +} + +static void close_device(void) { + close(device_fd); + device_fd = -1; +} + +static inline uint16_t get_ip_ethertype(vpn_packet_t *packet) { + switch (DATA(packet)[ETH_HLEN] >> 4) { + case 4: + return ETH_P_IP; + + case 6: + return ETH_P_IPV6; + + default: + return ETH_P_MAX; + } +} + +static inline void set_etherheader(vpn_packet_t *packet, uint16_t ethertype) { + memset(DATA(packet), 0, ETH_HLEN - ETHER_TYPE_LEN); + + DATA(packet)[ETH_HLEN - ETHER_TYPE_LEN] = (ethertype >> 8) & 0xFF; + DATA(packet)[ETH_HLEN - ETHER_TYPE_LEN + 1] = ethertype & 0xFF; +} + +static bool read_packet(vpn_packet_t *packet) { + int lenin = read(device_fd, DATA(packet) + ETH_HLEN, MTU - ETH_HLEN); + if(lenin <= 0) { + logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from fd/%d: %s!", device_fd, strerror(errno)); + return false; + } + + uint16_t ethertype = get_ip_ethertype(packet); + if(ethertype == ETH_P_MAX) { + logger(DEBUG_TRAFFIC, LOG_ERR, "Unknown IP version while reading packet from fd/%d!", device_fd); + return false; + } + + set_etherheader(packet, ethertype); + packet->len = lenin + ETH_HLEN; + + logger(DEBUG_TRAFFIC, LOG_DEBUG, "Read packet of %d bytes from fd/%d.", packet->len, device_fd); + + return true; +} + +static bool write_packet(vpn_packet_t *packet) { + logger(DEBUG_TRAFFIC, LOG_DEBUG, "Writing packet of %d bytes to fd/%d.", packet->len, device_fd); + + if(write(device_fd, DATA(packet) + ETH_HLEN, packet->len - ETH_HLEN) < 0) { + logger(DEBUG_ALWAYS, LOG_ERR, "Error while writing to fd/%d: %s!", device_fd, strerror(errno)); + return false; + } + + return true; +} + +const devops_t fd_devops = { + .setup = setup_device, + .close = close_device, + .read = read_packet, + .write = write_packet, +}; diff --git a/src/fsck.c b/src/fsck.c index b90710b..e5e7dd5 100644 --- a/src/fsck.c +++ b/src/fsck.c @@ -297,9 +297,10 @@ int fsck(const char *argv0) { rsa_t *rsa_pub = NULL; f = fopen(fname, "r"); - if(f) + if(f) { rsa_pub = rsa_read_pem_public_key(f); - fclose(f); + fclose(f); + } if(rsa_priv) { if(!rsa_pub) { @@ -352,12 +353,12 @@ int fsck(const char *argv0) { f = fopen(fname, "r"); if(f) { ecdsa_pub = get_pubkey(f); - if(!f) { + if(!ecdsa_pub) { rewind(f); ecdsa_pub = ecdsa_read_pem_public_key(f); } + fclose(f); } - fclose(f); if(ecdsa_priv) { if(!ecdsa_pub) { diff --git a/src/graph.c b/src/graph.c index e570feb..1f1fdb3 100644 --- a/src/graph.c +++ b/src/graph.c @@ -1,6 +1,6 @@ /* graph.c -- graph algorithms - Copyright (C) 2001-2013 Guus Sliepen , + Copyright (C) 2001-2017 Guus Sliepen , 2001-2005 Ivo Timmermans This program is free software; you can redistribute it and/or modify @@ -247,28 +247,23 @@ static void check_reachability(void) { char *name; char *address; char *port; - char *envp[8] = {NULL}; - xasprintf(&envp[0], "NETNAME=%s", netname ? : ""); - xasprintf(&envp[1], "DEVICE=%s", device ? : ""); - xasprintf(&envp[2], "INTERFACE=%s", iface ? : ""); - xasprintf(&envp[3], "NODE=%s", n->name); + environment_t env; + environment_init(&env); + environment_add(&env, "NODE=%s", n->name); sockaddr2str(&n->address, &address, &port); - xasprintf(&envp[4], "REMOTEADDRESS=%s", address); - xasprintf(&envp[5], "REMOTEPORT=%s", port); - xasprintf(&envp[6], "NAME=%s", myself->name); + environment_add(&env, "REMOTEADDRESS=%s", address); + environment_add(&env, "REMOTEPORT=%s", port); - execute_script(n->status.reachable ? "host-up" : "host-down", envp); + execute_script(n->status.reachable ? "host-up" : "host-down", &env); xasprintf(&name, n->status.reachable ? "hosts/%s-up" : "hosts/%s-down", n->name); - execute_script(name, envp); + execute_script(name, &env); free(name); free(address); free(port); - - for(int i = 0; i < 7; i++) - free(envp[i]); + environment_exit(&env); subnet_update(n, NULL, n->status.reachable); diff --git a/src/ifconfig.c b/src/ifconfig.c index 7688a3c..0b99402 100644 --- a/src/ifconfig.c +++ b/src/ifconfig.c @@ -1,6 +1,6 @@ /* ifconfig.c -- Generate platform specific interface configuration commands - Copyright (C) 2016 Guus Sliepen + Copyright (C) 2016-2017 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 @@ -104,13 +104,6 @@ void ifconfig_address(FILE *out, const char *value) { case SUBNET_IPV6: fprintf(out, "ip addr replace %s dev \"$INTERFACE\"\n", address_str); break; default: return; } -#elif defined(HAVE_BSD) - switch(address.type) { - case SUBNET_MAC: fprintf(out, "ifconfig \"$INTERFACE\" link %s\n", address_str); break; - case SUBNET_IPV4: fprintf(out, "ifconfig \"$INTERFACE\" %s\n", address_str); break; - case SUBNET_IPV6: fprintf(out, "ifconfig \"$INTERFACE\" inet6 %s\n", address_str); break; - default: return; - } #elif defined(HAVE_MINGW) || defined(HAVE_CYGWIN) switch(address.type) { case SUBNET_MAC: fprintf(out, "ip link set \"$INTERFACE\" address %s\n", address_str); break; @@ -118,6 +111,13 @@ void ifconfig_address(FILE *out, const char *value) { case SUBNET_IPV6: fprintf(out, "netsh inetface ipv6 set address \"$INTERFACE\" static %s\n", address_str); break; default: return; } +#else // assume BSD + switch(address.type) { + case SUBNET_MAC: fprintf(out, "ifconfig \"$INTERFACE\" link %s\n", address_str); break; + case SUBNET_IPV4: fprintf(out, "ifconfig \"$INTERFACE\" %s\n", address_str); break; + case SUBNET_IPV6: fprintf(out, "ifconfig \"$INTERFACE\" inet6 %s\n", address_str); break; + default: return; + } #endif } @@ -152,8 +152,21 @@ void ifconfig_route(FILE *out, const char *value) { default: return; } } -#elif defined(HAVE_BSD) - // BSD route command is silly and doesn't accept an interface name as a destination. +#elif defined(HAVE_MINGW) || defined(HAVE_CYGWIN) + if(*gateway_str) { + switch(subnet.type) { + case SUBNET_IPV4: fprintf(out, "netsh inetface ipv4 add route %s \"%%INTERFACE%%\" %s\n", subnet_str, gateway_str); break; + case SUBNET_IPV6: fprintf(out, "netsh inetface ipv6 add route %s \"%%INTERFACE%%\" %s\n", subnet_str, gateway_str); break; + default: return; + } + } else { + switch(subnet.type) { + case SUBNET_IPV4: fprintf(out, "netsh inetface ipv4 add route %s \"%%INTERFACE%%\"\n", subnet_str); break; + case SUBNET_IPV6: fprintf(out, "netsh inetface ipv6 add route %s \"%%INTERFACE%%\"\n", subnet_str); break; + default: return; + } + } +#else // assume BSD if(!*gateway_str) { switch(subnet.type) { case SUBNET_IPV4: @@ -180,19 +193,5 @@ void ifconfig_route(FILE *out, const char *value) { case SUBNET_IPV6: fprintf(out, "route add -inet6 %s %s\n", subnet_str, gateway_str); break; default: return; } -#elif defined(HAVE_MINGW) || defined(HAVE_CYGWIN) - if(*gateway_str) { - switch(subnet.type) { - case SUBNET_IPV4: fprintf(out, "netsh inetface ipv4 add route %s \"%%INTERFACE%%\" %s\n", subnet_str, gateway_str); break; - case SUBNET_IPV6: fprintf(out, "netsh inetface ipv6 add route %s \"%%INTERFACE%%\" %s\n", subnet_str, gateway_str); break; - default: return; - } - } else { - switch(subnet.type) { - case SUBNET_IPV4: fprintf(out, "netsh inetface ipv4 add route %s \"%%INTERFACE%%\"\n", subnet_str); break; - case SUBNET_IPV6: fprintf(out, "netsh inetface ipv6 add route %s \"%%INTERFACE%%\"\n", subnet_str); break; - default: return; - } - } #endif } diff --git a/src/info.c b/src/info.c index b9a6fcf..2a6934b 100644 --- a/src/info.c +++ b/src/info.c @@ -1,6 +1,6 @@ /* info.c -- Show information about a node, subnet or address - Copyright (C) 2012-2013 Guus Sliepen + Copyright (C) 2012-2017 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 @@ -69,7 +69,7 @@ static int info_node(int fd, const char *item) { long int last_state_change; while(recvline(fd, line, sizeof line)) { - int n = sscanf(line, "%d %d %s %s %s port %s %d %d %d %d %x %"PRIx32" %s %s %d %hd %hd %hd %ld", &code, &req, node, id, host, port, &cipher, &digest, &maclength, &compression, &options, &status_union.raw, nexthop, via, &distance, &pmtu, &minmtu, &maxmtu, &last_state_change); + int n = sscanf(line, "%d %d %4095s %4095s %4095s port %4095s %d %d %d %d %x %"PRIx32" %4095s %4095s %d %hd %hd %hd %ld", &code, &req, node, id, host, port, &cipher, &digest, &maclength, &compression, &options, &status_union.raw, nexthop, via, &distance, &pmtu, &minmtu, &maxmtu, &last_state_change); if(n == 2) break; @@ -91,7 +91,7 @@ static int info_node(int fd, const char *item) { } while(recvline(fd, line, sizeof line)) { - if(sscanf(line, "%d %d %s", &code, &req, node) == 2) + if(sscanf(line, "%d %d %4095s", &code, &req, node) == 2) break; } @@ -158,7 +158,7 @@ static int info_node(int fd, const char *item) { printf("Edges: "); sendline(fd, "%d %d %s", CONTROL, REQ_DUMP_EDGES, item); while(recvline(fd, line, sizeof line)) { - int n = sscanf(line, "%d %d %s %s", &code, &req, from, to); + int n = sscanf(line, "%d %d %4095s %4095s", &code, &req, from, to); if(n == 2) break; if(n != 4) { @@ -174,7 +174,7 @@ static int info_node(int fd, const char *item) { printf("Subnets: "); sendline(fd, "%d %d %s", CONTROL, REQ_DUMP_SUBNETS, item); while(recvline(fd, line, sizeof line)) { - int n = sscanf(line, "%d %d %s %s", &code, &req, subnet, from); + int n = sscanf(line, "%d %d %4095s %4095s", &code, &req, subnet, from); if(n == 2) break; if(n != 4) { @@ -209,7 +209,7 @@ static int info_subnet(int fd, const char *item) { sendline(fd, "%d %d %s", CONTROL, REQ_DUMP_SUBNETS, item); while(recvline(fd, line, sizeof line)) { - int n = sscanf(line, "%d %d %s %s", &code, &req, netstr, owner); + int n = sscanf(line, "%d %d %4095s %4095s", &code, &req, netstr, owner); if(n == 2) break; diff --git a/src/invitation.c b/src/invitation.c index 08afe78..0dfd9ea 100644 --- a/src/invitation.c +++ b/src/invitation.c @@ -1,6 +1,6 @@ /* invitation.c -- Create and accept invitations - Copyright (C) 2013-2015 Guus Sliepen + Copyright (C) 2013-2017 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 @@ -239,7 +239,7 @@ int cmd_invite(int argc, char *argv[]) { return 1; } - char *myname = get_my_name(true); + myname = get_my_name(true); if(!myname) return 1; @@ -252,14 +252,14 @@ int cmd_invite(int argc, char *argv[]) { } // If a daemon is running, ensure no other nodes know about this name - bool found = false; if(connect_tincd(false)) { + bool found = false; sendline(fd, "%d %d", CONTROL, REQ_DUMP_NODES); while(recvline(fd, line, sizeof line)) { char node[4096]; int code, req; - if(sscanf(line, "%d %d %s", &code, &req, node) != 3) + if(sscanf(line, "%d %d %4095s", &code, &req, node) != 3) break; if(!strcmp(node, argv[1])) found = true; @@ -425,15 +425,13 @@ int cmd_invite(int argc, char *argv[]) { xasprintf(&url, "%s/%s%s", address, hash, cookie); // Call the inviation-created script - char *envp[6] = {}; - xasprintf(&envp[0], "NAME=%s", myname); - xasprintf(&envp[1], "NETNAME=%s", netname); - xasprintf(&envp[2], "NODE=%s", argv[1]); - xasprintf(&envp[3], "INVITATION_FILE=%s", filename); - xasprintf(&envp[4], "INVITATION_URL=%s", url); - execute_script("invitation-created", envp); - for(int i = 0; i < 6 && envp[i]; i++) - free(envp[i]); + environment_t env; + environment_init(&env); + environment_add(&env, "NODE=%s", argv[1]); + environment_add(&env, "INVITATION_FILE=%s", filename); + environment_add(&env, "INVITATION_URL=%s", url); + execute_script("invitation-created", &env); + environment_exit(&env); puts(url); free(url); @@ -609,6 +607,17 @@ make_names: return false; } + snprintf(filename, sizeof filename, "%s" SLASH "invitation-data", confbase); + FILE *finv = fopen(filename, "w"); + if(!finv || fwrite(data, datalen, 1, finv) != 1) { + fprintf(stderr, "Could not create file %s: %s\n", filename, strerror(errno)); + fclose(fh); + fclose(f); + fclose(finv); + return false; + } + fclose(finv); + snprintf(filename, sizeof filename, "%s" SLASH "tinc-up.invitation", confbase); FILE *fup = fopen(filename, "w"); if(!fup) { @@ -688,7 +697,7 @@ make_names: } // Copy the safe variable to the right config file - fprintf(variables[i].type & VAR_HOST ? fh : f, "%s = %s\n", l, value); + fprintf((variables[i].type & VAR_HOST) ? fh : f, "%s = %s\n", l, value); } fclose(f); @@ -1046,7 +1055,7 @@ next: char hisname[4096] = ""; int code, hismajor, hisminor = 0; - if(!recvline(sock, line, sizeof line) || sscanf(line, "%d %s %d.%d", &code, hisname, &hismajor, &hisminor) < 3 || code != 0 || hismajor != PROT_MAJOR || !check_id(hisname) || !recvline(sock, line, sizeof line) || !rstrip(line) || sscanf(line, "%d ", &code) != 1 || code != ACK || strlen(line) < 3) { + if(!recvline(sock, line, sizeof line) || sscanf(line, "%d %4095s %d.%d", &code, hisname, &hismajor, &hisminor) < 3 || code != 0 || hismajor != PROT_MAJOR || !check_id(hisname) || !recvline(sock, line, sizeof line) || !rstrip(line) || sscanf(line, "%d ", &code) != 1 || code != ACK || strlen(line) < 3) { fprintf(stderr, "Cannot read greeting from peer\n"); closesocket(sock); goto next; diff --git a/src/linux/device.c b/src/linux/device.c index a06e6da..e273bfa 100644 --- a/src/linux/device.c +++ b/src/linux/device.c @@ -139,6 +139,9 @@ static bool read_packet(vpn_packet_t *packet) { if(inlen <= 0) { logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info, device, strerror(errno)); + if (errno == EBADFD) { /* File descriptor in bad state */ + event_exit(); + } return false; } diff --git a/src/logger.c b/src/logger.c index 6028e3d..4075ea8 100644 --- a/src/logger.c +++ b/src/logger.c @@ -1,6 +1,6 @@ /* logger.c -- logging code - Copyright (C) 2004-2015 Guus Sliepen + Copyright (C) 2004-2017 Guus Sliepen 2004-2005 Ivo Timmermans This program is free software; you can redistribute it and/or modify @@ -29,7 +29,7 @@ #include "process.h" #include "sptps.h" -debug_t debug_level = DEBUG_NOTHING; +int debug_level = DEBUG_NOTHING; static logmode_t logmode = LOGMODE_STDERR; static pid_t logpid; static FILE *logfile = NULL; diff --git a/src/logger.h b/src/logger.h index 252497b..f4f46f9 100644 --- a/src/logger.h +++ b/src/logger.h @@ -1,7 +1,7 @@ /* logger.h -- header file for logger.c Copyright (C) 1998-2005 Ivo Timmermans - 2000-2012 Guus Sliepen + 2000-2017 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 @@ -67,7 +67,7 @@ enum { #include -extern debug_t debug_level; +extern int debug_level; extern bool logcontrol; extern int umbilical; extern void openlogger(const char *, logmode_t); diff --git a/src/meta.c b/src/meta.c index 260cb00..4b35798 100644 --- a/src/meta.c +++ b/src/meta.c @@ -65,6 +65,13 @@ bool send_meta(connection_t *c, const char *buffer, int length) { #ifdef DISABLE_LEGACY return false; #else + if(length > c->outbudget) { + logger(DEBUG_META, LOG_ERR, "Byte limit exceeded for encryption to %s (%s)", c->name, c->hostname); + return false; + } else { + c->outbudget -= length; + } + size_t outlen = length; if(!cipher_encrypt(c->outcipher, buffer, length, buffer_prepare(&c->outbuf, length), &outlen, false) || outlen != length) { @@ -220,6 +227,13 @@ bool receive_meta(connection_t *c) { #ifdef DISABLE_LEGACY return false; #else + if(inlen > c->inbudget) { + logger(DEBUG_META, LOG_ERR, "yte limit exceeded for decryption from %s (%s)", c->name, c->hostname); + return false; + } else { + c->inbudget -= inlen; + } + size_t outlen = inlen; if(!cipher_decrypt(c->incipher, bufp, inlen, buffer_prepare(&c->inbuf, inlen), &outlen, false) || inlen != outlen) { diff --git a/src/mingw/device.c b/src/mingw/device.c index b047615..dfdb964 100644 --- a/src/mingw/device.c +++ b/src/mingw/device.c @@ -214,6 +214,9 @@ static bool setup_device(void) { logger(DEBUG_ALWAYS, LOG_INFO, "%s (%s) is a %s", device, iface, device_info); + device_read_overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + device_write_overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + return true; } @@ -226,9 +229,6 @@ static void enable_device(void) { /* We don't use the write event directly, but GetOverlappedResult() does, internally. */ - device_read_overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); - device_write_overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); - io_add_event(&device_read_io, device_handle_read, NULL, device_read_overlapped.hEvent); device_issue_read(); } @@ -237,6 +237,19 @@ static void disable_device(void) { logger(DEBUG_ALWAYS, LOG_INFO, "Disabling %s", device_info); io_del(&device_read_io); + + ULONG status = 0; + DWORD len; + DeviceIoControl(device_handle, TAP_IOCTL_SET_MEDIA_STATUS, &status, sizeof status, &status, sizeof status, &len, NULL); + + /* Note that we don't try to cancel ongoing I/O here - we just stop listening. + This is because some TAP-Win32 drivers don't seem to handle cancellation very well, + especially when combined with other events such as the computer going to sleep - cases + were observed where the GetOverlappedResult() would just block indefinitely and never + return in that case. */ +} + +static void close_device(void) { CancelIo(device_handle); /* According to MSDN, CancelIo() does not necessarily wait for the operation to complete. @@ -253,11 +266,6 @@ static void disable_device(void) { CloseHandle(device_read_overlapped.hEvent); CloseHandle(device_write_overlapped.hEvent); - ULONG status = 0; - DeviceIoControl(device_handle, TAP_IOCTL_SET_MEDIA_STATUS, &status, sizeof status, &status, sizeof status, &len, NULL); -} - -static void close_device(void) { CloseHandle(device_handle); device_handle = INVALID_HANDLE_VALUE; free(device); device = NULL; diff --git a/src/names.c b/src/names.c index 6c518f2..0cae28a 100644 --- a/src/names.c +++ b/src/names.c @@ -1,7 +1,7 @@ /* names.c -- generate commonly used (file)names Copyright (C) 1998-2005 Ivo Timmermans - 2000-2015 Guus Sliepen + 2000-2017 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 @@ -25,6 +25,7 @@ #include "xalloc.h" char *netname = NULL; +char *myname = NULL; char *confdir = NULL; /* base configuration directory */ char *confbase = NULL; /* base configuration directory for this instance of tinc */ bool confbase_given; @@ -137,6 +138,7 @@ void free_names(void) { free(logfilename); free(confbase); free(confdir); + free(myname); identname = NULL; netname = NULL; @@ -145,4 +147,5 @@ void free_names(void) { logfilename = NULL; confbase = NULL; confdir = NULL; + myname = NULL; } diff --git a/src/names.h b/src/names.h index a2395af..e6b99c5 100644 --- a/src/names.h +++ b/src/names.h @@ -1,7 +1,7 @@ /* names.h -- header for names.c Copyright (C) 1998-2005 Ivo Timmermans - 2000-2015 Guus Sliepen + 2000-2017 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 @@ -25,6 +25,7 @@ extern char *confdir; extern char *confbase; extern bool confbase_given; extern char *netname; +extern char *myname; extern char *identname; extern char *unixsocketname; extern char *logfilename; diff --git a/src/net.c b/src/net.c index 4369ff4..1cb467d 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-2015 Guus Sliepen + 2000-2017 Guus Sliepen 2006 Scott Lamb 2011 Loïc Grenié @@ -22,7 +22,7 @@ #include "system.h" -#include "utils.h" +#include "autoconnect.h" #include "conf.h" #include "connection.h" #include "device.h" @@ -34,6 +34,7 @@ #include "netutl.h" #include "protocol.h" #include "subnet.h" +#include "utils.h" #include "xalloc.h" int contradicting_add_edge = 0; @@ -209,7 +210,7 @@ static void timeout_handler(void *data) { // timeout during ping if(c->status.pinged) { - logger(DEBUG_CONNECTIONS, LOG_INFO, "%s (%s) didn't respond to PING in %ld seconds", c->name, c->hostname, (long)now.tv_sec - c->last_ping_time); + logger(DEBUG_CONNECTIONS, LOG_INFO, "%s (%s) didn't respond to PING in %ld seconds", c->name, c->hostname, (long)(now.tv_sec - c->last_ping_time)); terminate_connection(c, c->edge); continue; } @@ -245,105 +246,9 @@ static void periodic_handler(void *data) { /* If AutoConnect is set, check if we need to make or break connections. */ - if(autoconnect && node_tree->count > 1) { - /* Count number of active connections */ - int nc = 0; - for list_each(connection_t, c, connection_list) { - if(c->edge) - nc++; - } + if(autoconnect && node_tree->count > 1) + do_autoconnect(); - if(nc < 3) { - /* Not enough active connections, try to add one. - Choose a random node, if we don't have a connection to it, - and we are not already trying to make one, create an - outgoing connection to this node. - */ - int count = 0; - for splay_each(node_t, n, node_tree) { - if(n == myself || n->connection || !(n->status.has_address || n->status.reachable)) - continue; - count++; - } - - if(!count) - goto end; - - int r = rand() % count; - - for splay_each(node_t, n, node_tree) { - if(n == myself || n->connection || !(n->status.has_address || n->status.reachable)) - continue; - - if(r--) - continue; - - bool found = false; - - for list_each(outgoing_t, outgoing, outgoing_list) { - if(!strcmp(outgoing->name, n->name)) { - found = true; - break; - } - } - - if(!found) { - logger(DEBUG_CONNECTIONS, LOG_INFO, "Autoconnecting to %s", n->name); - outgoing_t *outgoing = xzalloc(sizeof *outgoing); - outgoing->name = xstrdup(n->name); - list_insert_tail(outgoing_list, outgoing); - setup_outgoing_connection(outgoing); - } - - break; - } - } else if(nc > 3) { - /* Too many active connections, try to remove one. - Choose a random outgoing connection to a node - that has at least one other connection. - */ - int r = rand() % nc; - int i = 0; - - for list_each(connection_t, c, connection_list) { - if(!c->edge) - continue; - - if(i++ != r) - continue; - - if(!c->outgoing || !c->node || c->node->edge_tree->count < 2) - break; - - logger(DEBUG_CONNECTIONS, LOG_INFO, "Autodisconnecting from %s", c->name); - list_delete(outgoing_list, c->outgoing); - c->outgoing = NULL; - terminate_connection(c, c->edge); - break; - } - } - - if(nc >= 3) { - /* If we have enough active connections, - remove any pending outgoing connections. - */ - for list_each(outgoing_t, o, outgoing_list) { - bool found = false; - for list_each(connection_t, c, connection_list) { - if(c->outgoing == o) { - found = true; - break; - } - } - if(!found) { - logger(DEBUG_CONNECTIONS, LOG_INFO, "Cancelled outgoing connection to %s", o->name); - list_delete_node(outgoing_list, node); - } - } - } - } - -end: timeout_set(data, &(struct timeval){5, rand() % 100000}); } diff --git a/src/net.h b/src/net.h index 7080869..69ca488 100644 --- a/src/net.h +++ b/src/net.h @@ -126,8 +126,9 @@ typedef struct outgoing_t { int timeout; splay_tree_t *config_tree; struct config_t *cfg; - struct addrinfo *ai; + struct addrinfo *ai; // addresses from config files struct addrinfo *aip; + struct addrinfo *kai; // addresses known via other online nodes (use free_known_addresses()) timeout_t ev; } outgoing_t; diff --git a/src/net_packet.c b/src/net_packet.c index 71f02a1..5d559bd 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-2016 Guus Sliepen + 2000-2017 Guus Sliepen 2010 Timothy Redaelli 2010 Brandon Black @@ -846,6 +846,7 @@ bool receive_sptps_record(void *handle, uint8_t type, const void *data, uint16_t vpn_packet_t inpkt; inpkt.offset = DEFAULT_PACKET_OFFSET; + inpkt.priority = 0; if(type == PKT_PROBE) { if(!from->status.udppacket) { @@ -1573,10 +1574,19 @@ void handle_device_data(void *data, int flags) { vpn_packet_t packet; packet.offset = DEFAULT_PACKET_OFFSET; packet.priority = 0; + static int errors = 0; if(devops.read(&packet)) { + errors = 0; myself->in_packets++; myself->in_bytes += packet.len; route(myself, &packet); + } else { + usleep(errors * 50000); + errors++; + if(errors > 10) { + logger(DEBUG_ALWAYS, LOG_ERR, "Too many errors from %s, exiting!", device); + event_exit(); + } } } diff --git a/src/net_setup.c b/src/net_setup.c index b0a0c95..e164214 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-2016 Guus Sliepen + 2000-2017 Guus Sliepen 2006 Scott Lamb 2010 Brandon Black @@ -48,7 +48,6 @@ #endif char *myport; -static char *myname; static io_t device_io; devops_t devops; bool device_standby = false; @@ -612,6 +611,9 @@ bool setup_myself_reloadable(void) { get_config_bool(lookup_config(config_tree, "DisableBuggyPeers"), &disablebuggypeers); + if(!get_config_int(lookup_config(config_tree, "InvitationExpire"), &invitation_lifetime)) + invitation_lifetime = 604800; // 1 week + read_invitation_key(); return true; @@ -705,29 +707,17 @@ void device_enable(void) { /* Run tinc-up script to further initialize the tap interface */ - char *envp[5] = {NULL}; - xasprintf(&envp[0], "NETNAME=%s", netname ? : ""); - xasprintf(&envp[1], "DEVICE=%s", device ? : ""); - xasprintf(&envp[2], "INTERFACE=%s", iface ? : ""); - xasprintf(&envp[3], "NAME=%s", myname); - - execute_script("tinc-up", envp); - - for(int i = 0; i < 4; i++) - free(envp[i]); + environment_t env; + environment_init(&env); + execute_script("tinc-up", &env); + environment_exit(&env); } void device_disable(void) { - char *envp[5] = {NULL}; - xasprintf(&envp[0], "NETNAME=%s", netname ? : ""); - xasprintf(&envp[1], "DEVICE=%s", device ? : ""); - xasprintf(&envp[2], "INTERFACE=%s", iface ? : ""); - xasprintf(&envp[3], "NAME=%s", myname); - - execute_script("tinc-down", envp); - - for(int i = 0; i < 4; i++) - free(envp[i]); + environment_t env; + environment_init(&env); + execute_script("tinc-down", &env); + environment_exit(&env); if (devops.disable) devops.disable(); @@ -857,7 +847,7 @@ static bool setup_myself(void) { /* Generate packet encryption key */ if(!get_config_string(lookup_config(config_tree, "Cipher"), &cipher)) - cipher = xstrdup("blowfish"); + cipher = xstrdup("aes-256-cbc"); if(!strcasecmp(cipher, "none")) { myself->incipher = NULL; @@ -881,7 +871,7 @@ static bool setup_myself(void) { } if(!get_config_string(lookup_config(config_tree, "Digest"), &digest)) - digest = xstrdup("sha1"); + digest = xstrdup("sha256"); if(!strcasecmp(digest, "none")) { myself->indigest = NULL; @@ -929,6 +919,8 @@ static bool setup_myself(void) { devops = raw_socket_devops; else if(!strcasecmp(type, "multicast")) devops = multicast_devops; + else if(!strcasecmp(type, "fd")) + devops = fd_devops; #ifdef ENABLE_UML else if(!strcasecmp(type, "uml")) devops = uml_devops; @@ -1148,7 +1140,6 @@ void close_network_connections(void) { exit_control(); - free(myname); free(scriptextension); free(scriptinterpreter); diff --git a/src/net_socket.c b/src/net_socket.c index 8259d9a..ac6b840 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-2016 Guus Sliepen + 2000-2017 Guus Sliepen 2006 Scott Lamb 2009 Florian Forster @@ -382,7 +382,7 @@ static void handle_meta_write(connection_t *c) { if(!sockerrno || sockerrno == EPIPE) { logger(DEBUG_CONNECTIONS, LOG_NOTICE, "Connection closed by %s (%s)", c->name, c->hostname); } else if(sockwouldblock(sockerrno)) { - logger(DEBUG_CONNECTIONS, LOG_DEBUG, "Sending %d bytes to %s (%s) would block", c->outbuf.len - c->outbuf.offset, c->name, c->hostname); + logger(DEBUG_META, LOG_DEBUG, "Sending %d bytes to %s (%s) would block", c->outbuf.len - c->outbuf.offset, c->name, c->hostname); return; } else { logger(DEBUG_CONNECTIONS, LOG_ERR, "Could not send %d bytes of data to %s (%s): %s", c->outbuf.len - c->outbuf.offset, c->name, c->hostname, sockstrerror(sockerrno)); @@ -441,13 +441,20 @@ static void handle_meta_io(void *data, int flags) { handle_meta_connection_data(c); } +static void free_known_addresses(struct addrinfo *ai) { + for(struct addrinfo *aip = ai, *next; aip; aip = next) { + next = aip->ai_next; + free(aip); + } +} + bool do_outgoing_connection(outgoing_t *outgoing) { char *address, *port, *space; struct addrinfo *proxyai = NULL; int result; begin: - if(!outgoing->ai) { + if(!outgoing->ai && !outgoing->kai) { if(!outgoing->cfg) { logger(DEBUG_CONNECTIONS, LOG_ERR, "Could not set up a meta connection to %s", outgoing->name); retry_outgoing(outgoing); @@ -477,6 +484,11 @@ begin: if(outgoing->ai) freeaddrinfo(outgoing->ai); outgoing->ai = NULL; + + if(outgoing->kai) + free_known_addresses(outgoing->kai); + outgoing->kai = NULL; + goto begin; } @@ -570,6 +582,7 @@ begin: // Find edges pointing to this node, and use them to build a list of unique, known addresses. static struct addrinfo *get_known_addresses(node_t *n) { struct addrinfo *ai = NULL; + struct addrinfo *oai = NULL; for splay_each(edge_t, e, n->edge_tree) { if(!e->reverse) @@ -585,16 +598,15 @@ static struct addrinfo *get_known_addresses(node_t *n) { if(found) continue; - struct addrinfo *nai = xzalloc(sizeof *nai); - if(ai) - ai->ai_next = nai; - ai = nai; + oai = ai; + ai = xzalloc(sizeof *ai); ai->ai_family = e->reverse->address.sa.sa_family; ai->ai_socktype = SOCK_STREAM; ai->ai_protocol = IPPROTO_TCP; ai->ai_addrlen = SALEN(e->reverse->address.sa); ai->ai_addr = xmalloc(ai->ai_addrlen); memcpy(ai->ai_addr, &e->reverse->address, ai->ai_addrlen); + ai->ai_next = oai; } return ai; @@ -621,8 +633,8 @@ void setup_outgoing_connection(outgoing_t *outgoing) { if(!outgoing->cfg) { if(n) - outgoing->aip = outgoing->ai = get_known_addresses(n); - if(!outgoing->ai) { + outgoing->aip = outgoing->kai = get_known_addresses(n); + if(!outgoing->kai) { logger(DEBUG_ALWAYS, LOG_DEBUG, "No address known for %s", outgoing->name); goto remove; } @@ -777,6 +789,9 @@ static void free_outgoing(outgoing_t *outgoing) { if(outgoing->ai) freeaddrinfo(outgoing->ai); + if(outgoing->kai) + free_known_addresses(outgoing->kai); + if(outgoing->config_tree) exit_configuration(&outgoing->config_tree); diff --git a/src/node.c b/src/node.c index 7242e95..b17e692 100644 --- a/src/node.c +++ b/src/node.c @@ -186,9 +186,9 @@ bool dump_nodes(connection_t *c) { for splay_each(node_t, n, node_tree) { char id[2 * sizeof n->id + 1]; for (size_t c = 0; c < sizeof n->id; ++c) - snprintf(id + 2 * c, 3, "%02hhx", n->id.x[c]); + snprintf(id + 2 * c, 3, "%02x", n->id.x[c]); id[sizeof id - 1] = 0; - send_request(c, "%d %d %s %s %s %d %d %d %d %x %x %s %s %d %hd %hd %hd %ld", CONTROL, REQ_DUMP_NODES, + send_request(c, "%d %d %s %s %s %d %d %d %d %x %x %s %s %d %d %d %d %ld", CONTROL, REQ_DUMP_NODES, n->name, id, n->hostname ?: "unknown port unknown", #ifdef DISABLE_LEGACY 0, 0, 0, diff --git a/src/openssl/cipher.c b/src/openssl/cipher.c index ae9640f..98033c5 100644 --- a/src/openssl/cipher.c +++ b/src/openssl/cipher.c @@ -1,6 +1,6 @@ /* cipher.c -- Symmetric block cipher handling - Copyright (C) 2007-2013 Guus Sliepen + Copyright (C) 2007-2017 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 @@ -62,10 +62,6 @@ cipher_t *cipher_open_by_nid(int nid) { return cipher_open(evp_cipher); } -cipher_t *cipher_open_blowfish_ofb(void) { - return cipher_open(EVP_bf_ofb()); -} - void cipher_close(cipher_t *cipher) { if(!cipher) return; @@ -81,6 +77,24 @@ size_t cipher_keylength(const cipher_t *cipher) { return EVP_CIPHER_key_length(cipher->cipher) + EVP_CIPHER_iv_length(cipher->cipher); } +uint64_t cipher_budget(const cipher_t *cipher) { + /* Hopefully some failsafe way to calculate the maximum amount of bytes to + send/receive with a given cipher before we might run into birthday paradox + attacks. Because we might use different modes, the block size of the mode + might be 1 byte. In that case, use the IV length. Ensure the whole thing + is limited to what can be represented with a 64 bits integer. + */ + + if(!cipher || !cipher->cipher) + return UINT64_MAX; // NULL cipher + + int ivlen = EVP_CIPHER_iv_length(cipher->cipher); + int blklen = EVP_CIPHER_block_size(cipher->cipher); + int len = blklen > 1 ? blklen : ivlen > 1 ? ivlen : 8; + int bits = len * 4 - 1; + return bits < 64 ? UINT64_C(1) << bits : UINT64_MAX; +} + size_t cipher_blocksize(const cipher_t *cipher) { if(!cipher || !cipher->cipher) return 1; @@ -123,7 +137,7 @@ bool cipher_encrypt(cipher_t *cipher, const void *indata, size_t inlen, void *ou int len, pad; if(EVP_EncryptInit_ex(cipher->ctx, NULL, NULL, NULL, NULL) && EVP_EncryptUpdate(cipher->ctx, (unsigned char *)outdata, &len, indata, inlen) - && EVP_EncryptFinal(cipher->ctx, (unsigned char *)outdata + len, &pad)) { + && EVP_EncryptFinal_ex(cipher->ctx, (unsigned char *)outdata + len, &pad)) { if(outlen) *outlen = len + pad; return true; } @@ -144,7 +158,7 @@ bool cipher_decrypt(cipher_t *cipher, const void *indata, size_t inlen, void *ou int len, pad; if(EVP_DecryptInit_ex(cipher->ctx, NULL, NULL, NULL, NULL) && EVP_DecryptUpdate(cipher->ctx, (unsigned char *)outdata, &len, indata, inlen) - && EVP_DecryptFinal(cipher->ctx, (unsigned char *)outdata + len, &pad)) { + && EVP_DecryptFinal_ex(cipher->ctx, (unsigned char *)outdata + len, &pad)) { if(outlen) *outlen = len + pad; return true; } diff --git a/src/openssl/digest.c b/src/openssl/digest.c index c303785..58ca167 100644 --- a/src/openssl/digest.c +++ b/src/openssl/digest.c @@ -1,6 +1,6 @@ /* digest.c -- Digest handling - Copyright (C) 2007-2013 Guus Sliepen + Copyright (C) 2007-2016 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 @@ -64,10 +64,6 @@ digest_t *digest_open_by_nid(int nid, int maclength) { return digest_open(evp_md, maclength); } -digest_t *digest_open_sha1(int maclength) { - return digest_open(EVP_sha1(), maclength); -} - bool digest_set_key(digest_t *digest, const void *key, size_t len) { digest->key = xrealloc(digest->key, len); memcpy(digest->key, key, len); diff --git a/src/protocol.h b/src/protocol.h index dee6eb8..8ce4e0d 100644 --- a/src/protocol.h +++ b/src/protocol.h @@ -1,7 +1,7 @@ /* protocol.h -- header for protocol.c Copyright (C) 1999-2005 Ivo Timmermans, - 2000-2013 Guus Sliepen + 2000-2017 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 @@ -62,6 +62,7 @@ extern bool tunnelserver; extern bool strictsubnets; extern bool experimental; +extern int invitation_lifetime; extern ecdsa_t *invitation_key; /* Maximum size of strings in a request. diff --git a/src/protocol_auth.c b/src/protocol_auth.c index 31b1f1e..a99e1d6 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-2014 Guus Sliepen + 2000-2017 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 @@ -47,6 +47,7 @@ #include "ed25519/sha512.h" +int invitation_lifetime; ecdsa_t *invitation_key = NULL; static bool send_proxyrequest(connection_t *c) { @@ -180,21 +181,18 @@ static bool finalize_invitation(connection_t *c, const char *data, uint16_t len) logger(DEBUG_CONNECTIONS, LOG_INFO, "Key succesfully received from %s (%s)", c->name, c->hostname); // Call invitation-accepted script - char *envp[7] = {NULL}; + environment_t env; char *address, *port; - xasprintf(&envp[0], "NETNAME=%s", netname ? : ""); - xasprintf(&envp[1], "DEVICE=%s", device ? : ""); - xasprintf(&envp[2], "INTERFACE=%s", iface ? : ""); - xasprintf(&envp[3], "NODE=%s", c->name); + environment_init(&env); + environment_add(&env, "NODE=%s", c->name); sockaddr2str(&c->address, &address, &port); - xasprintf(&envp[4], "REMOTEADDRESS=%s", address); - xasprintf(&envp[5], "NAME=%s", myself->name); + environment_add(&env, "REMOTEADDRESS=%s", address); + environment_add(&env, "NAME=%s", myself->name); - execute_script("invitation-accepted", envp); + execute_script("invitation-accepted", &env); - for(int i = 0; envp[i] && i < 7; i++) - free(envp[i]); + environment_exit(&env); sptps_send_record(&c->sptps, 2, data, 0); return true; @@ -235,6 +233,18 @@ static bool receive_invitation_sptps(void *handle, uint8_t type, const void *dat return false; } + // Check the timestamp of the invitation + struct stat st; + if(stat(usedname, &st)) { + logger(DEBUG_ALWAYS, LOG_ERR, "Could not stat %s", usedname); + return false; + } + + if(st.st_mtime + invitation_lifetime < now.tv_sec) { + logger(DEBUG_ALWAYS, LOG_ERR, "Peer %s tried to use expired invitation %s", c->hostname, cookie); + return false; + } + // Open the renamed file FILE *f = fopen(usedname, "r"); if(!f) { @@ -284,7 +294,7 @@ static bool receive_invitation_sptps(void *handle, uint8_t type, const void *dat bool id_h(connection_t *c, const char *request) { char name[MAX_STRING_SIZE]; - if(sscanf(request, "%*d " MAX_STRING " %d.%d", name, &c->protocol_major, &c->protocol_minor) < 2) { + if(sscanf(request, "%*d " MAX_STRING " %2d.%3d", name, &c->protocol_major, &c->protocol_minor) < 2) { logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "ID", c->name, c->hostname); return false; @@ -421,10 +431,24 @@ bool send_metakey(connection_t *c) { if(!read_rsa_public_key(c)) return false; - if(!(c->outcipher = cipher_open_blowfish_ofb())) + /* We need to use a stream mode for the meta protocol. Use AES for this, + but try to match the key size with the one from the cipher selected + by Cipher. + */ + + int keylen = cipher_keylength(myself->incipher); + if(keylen <= 16) + c->outcipher = cipher_open_by_name("aes-128-cfb"); + else if(keylen <= 24) + c->outcipher = cipher_open_by_name("aes-192-cfb"); + else + c->outcipher = cipher_open_by_name("aes-256-cfb"); + if(!c) return false; - if(!(c->outdigest = digest_open_sha1(-1))) + c->outbudget = cipher_budget(c->outcipher); + + if(!(c->outdigest = digest_open_by_name("sha256", -1))) return false; const size_t len = rsa_size(c->rsa); @@ -536,6 +560,8 @@ bool metakey_h(connection_t *c, const char *request) { c->incipher = NULL; } + c->inbudget = cipher_budget(c->incipher); + if(digest) { if(!(c->indigest = digest_open_by_nid(digest, -1))) { logger(DEBUG_ALWAYS, LOG_ERR, "Error during initialisation of digest from %s (%s)", c->name, c->hostname); @@ -872,8 +898,10 @@ bool ack_h(connection_t *c, const char *request) { socklen_t local_salen = sizeof local_sa; if (getsockname(c->socket, &local_sa.sa, &local_salen) < 0) logger(DEBUG_ALWAYS, LOG_WARNING, "Could not get local socket address for connection with %s", c->name); - else + else { sockaddr_setport(&local_sa, myport); + c->edge->local_address = local_sa; + } c->edge->weight = (weight + c->estimated_weight) / 2; c->edge->connection = c; c->edge->options = c->options; diff --git a/src/protocol_edge.c b/src/protocol_edge.c index dc0cf05..92089b1 100644 --- a/src/protocol_edge.c +++ b/src/protocol_edge.c @@ -132,63 +132,52 @@ bool add_edge_h(connection_t *c, const char *request) { e = lookup_edge(from, to); if(e) { - if(e->weight != weight || e->options != options || sockaddrcmp(&e->address, &address)) { - if(from == myself) { - logger(DEBUG_PROTOCOL, LOG_WARNING, "Got %s from %s (%s) for ourself which does not match existing entry", - "ADD_EDGE", c->name, c->hostname); - send_add_edge(c, e); - sockaddrfree(&local_address); - return true; - } else { - logger(DEBUG_PROTOCOL, LOG_WARNING, "Got %s from %s (%s) which does not match existing entry", - "ADD_EDGE", c->name, c->hostname); - e->options = options; - if(sockaddrcmp(&e->address, &address)) { - sockaddrfree(&e->address); - e->address = address; - } - if(e->weight != weight) { - splay_node_t *node = splay_unlink(edge_weight_tree, e); - e->weight = weight; - splay_insert_node(edge_weight_tree, node); - } + bool new_address = sockaddrcmp(&e->address, &address); + // local_address.sa.sa_family will be 0 if we got it from older tinc versions + // local_address.sa.sa_family will be 255 (AF_UNKNOWN) if we got it from newer versions + // but for edge which does not have local_address + bool new_local_address = local_address.sa.sa_family && local_address.sa.sa_family != AF_UNKNOWN && + sockaddrcmp(&e->local_address, &local_address); - goto done; - } - } else if(sockaddrcmp(&e->local_address, &local_address)) { - if(from == myself) { - if(e->local_address.sa.sa_family && local_address.sa.sa_family) { - // Someone has the wrong local address for ourself. Correct then. - logger(DEBUG_PROTOCOL, LOG_WARNING, "Got %s from %s (%s) for ourself which does not match existing entry", - "ADD_EDGE", c->name, c->hostname); - send_add_edge(c, e); - sockaddrfree(&local_address); - return true; - } - // Otherwise, just ignore it. - sockaddrfree(&local_address); - return true; - } else if(local_address.sa.sa_family && local_address.sa.sa_family != AF_UNKNOWN) { - // We learned a new local address for this edge. - // local_address.sa.sa_family will be 0 if we got it from older tinc versions - // local_address.sa.sa_family will be 255 (AF_UNKNOWN) if we got it from newer versions - // but for edge which does not have local_address - sockaddrfree(&e->local_address); - e->local_address = local_address; - - // Tell others about it. - if(!tunnelserver) - forward_request(c, request); - - return true; - } else { - sockaddrfree(&local_address); - return true; - } - } else { + if(e->weight == weight && e->options == options && !new_address && !new_local_address) { + sockaddrfree(&address); sockaddrfree(&local_address); return true; } + + if(from == myself) { + logger(DEBUG_PROTOCOL, LOG_WARNING, "Got %s from %s (%s) for ourself which does not match existing entry", + "ADD_EDGE", c->name, c->hostname); + send_add_edge(c, e); + sockaddrfree(&address); + sockaddrfree(&local_address); + return true; + } + + logger(DEBUG_PROTOCOL, LOG_WARNING, "Got %s from %s (%s) which does not match existing entry", + "ADD_EDGE", c->name, c->hostname); + + e->options = options; + + if(new_address) { + sockaddrfree(&e->address); + e->address = address; + } else { + sockaddrfree(&address); + } + + if(new_local_address) { + sockaddrfree(&e->local_address); + e->local_address = local_address; + } else { + sockaddrfree(&local_address); + } + + if(e->weight != weight) { + splay_node_t *node = splay_unlink(edge_weight_tree, e); + e->weight = weight; + splay_insert_node(edge_weight_tree, node); + } } else if(from == myself) { logger(DEBUG_PROTOCOL, LOG_WARNING, "Got %s from %s (%s) for ourself which does not exist", "ADD_EDGE", c->name, c->hostname); @@ -198,20 +187,20 @@ bool add_edge_h(connection_t *c, const char *request) { e->to = to; send_del_edge(c, e); free_edge(e); + sockaddrfree(&address); sockaddrfree(&local_address); return true; + } else { + e = new_edge(); + e->from = from; + e->to = to; + e->address = address; + e->local_address = local_address; + e->options = options; + e->weight = weight; + edge_add(e); } - e = new_edge(); - e->from = from; - e->to = to; - e->address = address; - e->local_address = local_address; - e->options = options; - e->weight = weight; - edge_add(e); - -done: /* Tell the rest about the new edge */ if(!tunnelserver) diff --git a/src/protocol_key.c b/src/protocol_key.c index d24d4ac..a18cefc 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-2014 Guus Sliepen + 2000-2017 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 @@ -356,7 +356,7 @@ bool ans_key_h(connection_t *c, const char *request) { char key[MAX_STRING_SIZE]; char address[MAX_STRING_SIZE] = ""; char port[MAX_STRING_SIZE] = ""; - int cipher, digest, maclength, compression, keylen; + int cipher, digest, maclength, compression; node_t *from, *to; if(sscanf(request, "%*d "MAX_STRING" "MAX_STRING" "MAX_STRING" %d %d %d %d "MAX_STRING" "MAX_STRING, @@ -489,7 +489,7 @@ bool ans_key_h(connection_t *c, const char *request) { /* Process key */ - keylen = hex2bin(key, key, sizeof key); + int keylen = hex2bin(key, key, sizeof key); if(keylen != (from->outcipher ? cipher_keylength(from->outcipher) : 1)) { logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses wrong keylength!", from->name, from->hostname); diff --git a/src/protocol_misc.c b/src/protocol_misc.c index 95bd322..05a4ada 100644 --- a/src/protocol_misc.c +++ b/src/protocol_misc.c @@ -135,7 +135,7 @@ bool send_tcppacket(connection_t *c, const vpn_packet_t *packet) { if(2.0 * c->outbuf.len / (float)maxoutbufsize - 1 > (float)rand()/(float)RAND_MAX) return true; - if(!send_request(c, "%d %hd", PACKET, packet->len)) + if(!send_request(c, "%d %d", PACKET, packet->len)) return false; return send_meta(c, (char *)DATA(packet), packet->len); @@ -194,6 +194,11 @@ bool send_udp_info(node_t *from, node_t *to) { farther than the static relay. */ to = (to->via == myself) ? to->nexthop : to->via; + if (to == NULL) { + logger(DEBUG_ALWAYS, LOG_ERR, "Something went wrong when selecting relay - possible fake UDP_INFO"); + return false; + } + /* Skip cases where sending UDP info messages doesn't make sense. This is done here in order to avoid repeating the same logic in multiple callsites. */ diff --git a/src/route.c b/src/route.c index 0c9f2aa..7ae4960 100644 --- a/src/route.c +++ b/src/route.c @@ -510,7 +510,7 @@ static void route_broadcast(node_t *source, vpn_packet_t *packet) { static void fragment_ipv4_packet(node_t *dest, vpn_packet_t *packet, length_t ether_size) { struct ip ip; vpn_packet_t fragment; - int len, maxlen, todo; + int maxlen, todo; uint8_t *offset; uint16_t ip_off, origf; @@ -537,7 +537,7 @@ static void fragment_ipv4_packet(node_t *dest, vpn_packet_t *packet, length_t et ip_off &= IP_OFFMASK; while(todo) { - len = todo > maxlen ? maxlen : todo; + int len = todo > maxlen ? maxlen : todo; memcpy(DATA(&fragment) + ether_size + ip_size, offset, len); todo -= len; offset += len; @@ -683,6 +683,9 @@ static void route_ipv6(node_t *source, vpn_packet_t *packet) { if(!do_decrement_ttl(source, packet)) return; + if(priorityinheritance) + packet->priority = ((DATA(packet)[14] & 0x0f) << 4) | (DATA(packet)[15] >> 4); + via = (subnet->owner->via == myself) ? subnet->owner->nexthop : subnet->owner->via; if(via == source) { @@ -954,8 +957,12 @@ static void route_mac(node_t *source, vpn_packet_t *packet) { uint16_t type = DATA(packet)[12] << 8 | DATA(packet)[13]; - if(priorityinheritance && type == ETH_P_IP && packet->len >= ether_size + ip_size) - packet->priority = DATA(packet)[15]; + if(priorityinheritance) { + if(type == ETH_P_IP && packet->len >= ether_size + ip_size) + packet->priority = DATA(packet)[15]; + else if(type == ETH_P_IPV6 && packet->len >= ether_size + ip6_size) + packet->priority = ((DATA(packet)[14] & 0x0f) << 4) | (DATA(packet)[15] >> 4); + } // Handle packets larger than PMTU diff --git a/src/script.c b/src/script.c index d4db889..d65551a 100644 --- a/src/script.c +++ b/src/script.c @@ -1,7 +1,7 @@ /* script.c -- call an external script Copyright (C) 1999-2005 Ivo Timmermans, - 2000-2015 Guus Sliepen + 2000-2017 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 @@ -21,6 +21,7 @@ #include "system.h" #include "conf.h" +#include "device.h" #include "logger.h" #include "names.h" #include "script.h" @@ -63,7 +64,58 @@ static void putenv(const char *p) {} static void unputenv(const char *p) {} #endif -bool execute_script(const char *name, char **envp) { +static const int min_env_size = 10; + +int environment_add(environment_t *env, const char *format, ...) { + if(env->n >= env->size) { + env->size = env->n ? env->n * 2 : min_env_size; + env->entries = xrealloc(env->entries, env->size * sizeof *env->entries); + } + + if(format) { + va_list ap; + va_start(ap, format); + vasprintf(&env->entries[env->n], format, ap); + va_end(ap); + } else { + env->entries[env->n] = NULL; + } + + return env->n++; +} + +void environment_update(environment_t *env, int pos, const char *format, ...) { + free(env->entries[pos]); + va_list ap; + va_start(ap, format); + vasprintf(&env->entries[pos], format, ap); + va_end(ap); +} + +void environment_init(environment_t *env) { + env->n = 0; + env->size = min_env_size; + env->entries = xzalloc(env->size * sizeof *env->entries); + + if(netname) + environment_add(env, "NETNAME=%s", netname); + if(myname) + environment_add(env, "NAME=%s", myname); + if(device) + environment_add(env, "DEVICE=%s", device); + if(iface) + environment_add(env, "INTERFACE=%s", iface); + if(debug_level >= 0) + environment_add(env, "DEBUG=%d", debug_level); +} + +void environment_exit(environment_t *env) { + for(int i = 0; i < env->n; i++) + free(env->entries[i]); + free(env->entries); +} + +bool execute_script(const char *name, environment_t *env) { char scriptname[PATH_MAX]; char *command; @@ -107,8 +159,8 @@ bool execute_script(const char *name, char **envp) { /* Set environment */ - for(int i = 0; envp[i]; i++) - putenv(envp[i]); + for(int i = 0; i < env->n; i++) + putenv(env->entries[i]); if(scriptinterpreter) xasprintf(&command, "%s \"%s\"", scriptinterpreter, scriptname); @@ -121,8 +173,8 @@ bool execute_script(const char *name, char **envp) { /* Unset environment */ - for(int i = 0; envp[i]; i++) - unputenv(envp[i]); + for(int i = 0; i < env->n; i++) + unputenv(env->entries[i]); if(status != -1) { #ifdef WEXITSTATUS diff --git a/src/script.h b/src/script.h index 446a3b9..2e26418 100644 --- a/src/script.h +++ b/src/script.h @@ -1,7 +1,7 @@ /* script.h -- header file for script.c Copyright (C) 1999-2005 Ivo Timmermans, - 2000-2013 Guus Sliepen + 2000-2017 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 @@ -21,6 +21,18 @@ #ifndef __TINC_SCRIPT_H__ #define __TINC_SCRIPT_H__ -extern bool execute_script(const char *, char **); +typedef struct environment { + int n; + int size; + char **entries; +} environment_t; + +extern int environment_add(environment_t *env, const char *format, ...); +extern int environment_placeholder(environment_t *env); +extern void environment_update(environment_t *env, int pos, const char *format, ...); +extern void environment_init(environment_t *env); +extern void environment_exit(environment_t *env); + +extern bool execute_script(const char *name, environment_t *env); #endif /* __TINC_SCRIPT_H__ */ diff --git a/src/solaris/device.c b/src/solaris/device.c index fadae57..89481c7 100644 --- a/src/solaris/device.c +++ b/src/solaris/device.c @@ -24,6 +24,7 @@ #include #include +#include #include "../conf.h" #include "../device.h" @@ -41,6 +42,7 @@ #define DEFAULT_TUN_DEVICE "/dev/tun" #define DEFAULT_TAP_DEVICE "/dev/tap" +#define IP_DEVICE "/dev/udp" static enum { DEVICE_TYPE_TUN, @@ -84,8 +86,8 @@ static bool setup_device(void) { /* The following is black magic copied from OpenVPN. */ - if((ip_fd = open("/dev/ip", O_RDWR, 0)) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not open %s: %s\n", "/dev/ip", strerror(errno)); + if((ip_fd = open(IP_DEVICE, O_RDWR, 0)) < 0) { + logger(DEBUG_ALWAYS, LOG_ERR, "Could not open %s: %s\n", IP_DEVICE, strerror(errno)); return false; } @@ -203,7 +205,7 @@ static bool setup_device(void) { /* Push arp module to ip_fd */ if(ioctl(ip_fd, I_PUSH, "arp") < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not push ARP module onto %s!", "/dev/ip"); + logger(DEBUG_ALWAYS, LOG_ERR, "Could not push ARP module onto %s!", IP_DEVICE); return false; } @@ -295,11 +297,16 @@ static void close_device(void) { } static bool read_packet(vpn_packet_t *packet) { - int inlen; + int result; + struct strbuf sbuf; + int f = 0; switch(device_type) { case DEVICE_TYPE_TUN: - if((inlen = read(device_fd, DATA(packet) + 14, MTU - 14)) <= 0) { + sbuf.maxlen = MTU - 14; + sbuf.buf = (char *)DATA(packet) + 14; + + if((result = getmsg(device_fd, NULL, &sbuf, &f)) < 0) { logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info, device, strerror(errno)); return false; } @@ -319,16 +326,19 @@ static bool read_packet(vpn_packet_t *packet) { } memset(DATA(packet), 0, 12); - packet->len = inlen + 14; + packet->len = sbuf.len + 14; break; case DEVICE_TYPE_TAP: - if((inlen = read(device_fd, DATA(packet), MTU)) <= 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info, device, strerror(errno)); + sbuf.maxlen = MTU; + sbuf.buf = (char *)DATA(packet); + + if((result = getmsg(device_fd, NULL, &sbuf, &f)) < 0) { + logger(LOG_ERR, "Error while reading from %s %s: %s", device_info, device, strerror(errno)); return false; } - packet->len = inlen + 14; + packet->len = sbuf.len; break; default: @@ -343,17 +353,25 @@ static bool read_packet(vpn_packet_t *packet) { static bool write_packet(vpn_packet_t *packet) { logger(DEBUG_TRAFFIC, LOG_DEBUG, "Writing packet of %d bytes to %s", packet->len, device_info); + struct strbuf sbuf; + switch(device_type) { case DEVICE_TYPE_TUN: - if(write(device_fd, DATA(packet) + 14, packet->len - 14) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Can't write to %s %s: %s", device_info, device, strerror(errno)); + sbuf.len = packet->len - 14; + sbuf.buf = (char *)DATA(packet) + 14; + + if(putmsg(device_fd, NULL, &sbuf, 0) < 0) { + logger(LOG_ERR, "Can't write to %s %s: %s", device_info, device, strerror(errno)); return false; } break; case DEVICE_TYPE_TAP: - if(write(device_fd, DATA(packet), packet->len) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Can't write to %s %s: %s", device_info, device, strerror(errno)); + sbuf.len = packet->len; + sbuf.buf = (char *)DATA(packet); + + if(putmsg(device_fd, NULL, &sbuf, 0) < 0) { + logger(LOG_ERR, "Can't write to %s %s: %s", device_info, device, strerror(errno)); return false; } break; diff --git a/src/sptps_test.c b/src/sptps_test.c index a394175..8df1046 100644 --- a/src/sptps_test.c +++ b/src/sptps_test.c @@ -44,6 +44,7 @@ static bool readonly; static bool writeonly; static int in = 0; static int out = 1; +static int addressfamily = AF_UNSPEC; static bool send_data(void *handle, uint8_t type, const void *data, size_t len) { char hex[len * 2 + 1]; @@ -58,7 +59,7 @@ static bool send_data(void *handle, uint8_t type, const void *data, size_t len) static bool receive_record(void *handle, uint8_t type, const void *data, uint16_t len) { if(verbose) - fprintf(stderr, "Received type %d record of %hu bytes:\n", type, len); + fprintf(stderr, "Received type %d record of %u bytes:\n", type, len); if(!writeonly) write(out, data, len); return true; @@ -93,6 +94,8 @@ static void usage() { " -R, --replay-window N Set replay window to N bytes.\n" " -s, --special Enable special handling of lines starting with #, ^ and $.\n" " -v, --verbose Display debug messages.\n" + " -4 Use IPv4.\n" + " -6 Use IPv6.\n" "\n"); fprintf(stderr, "Report bugs to tinc@tinc-vpn.org.\n"); } @@ -110,7 +113,7 @@ int main(int argc, char *argv[]) { ecdsa_t *mykey = NULL, *hiskey = NULL; bool quit = false; - while((r = getopt_long(argc, argv, "dqrstwL:W:v", long_options, &option_index)) != EOF) { + while((r = getopt_long(argc, argv, "dqrstwL:W:v46", long_options, &option_index)) != EOF) { switch (r) { case 0: /* long option */ break; @@ -161,6 +164,14 @@ int main(int argc, char *argv[]) { usage(); return 1; + case '4': /* IPv4 */ + addressfamily = AF_INET; + break; + + case '6': /* IPv6 */ + addressfamily = AF_INET6; + break; + case 1: /* help */ usage(); return 0; @@ -212,7 +223,7 @@ int main(int argc, char *argv[]) { struct addrinfo *ai, hint; memset(&hint, 0, sizeof hint); - hint.ai_family = AF_UNSPEC; + hint.ai_family = addressfamily; hint.ai_socktype = datagram ? SOCK_DGRAM : SOCK_STREAM; hint.ai_protocol = datagram ? IPPROTO_UDP : IPPROTO_TCP; hint.ai_flags = initiator ? 0 : AI_PASSIVE; diff --git a/src/subnet.c b/src/subnet.c index 090a62b..3d055b6 100644 --- a/src/subnet.c +++ b/src/subnet.c @@ -1,6 +1,6 @@ /* subnet.c -- handle subnet lookups and lists - Copyright (C) 2000-2013 Guus Sliepen , + Copyright (C) 2000-2017 Guus Sliepen , 2000-2005 Ivo Timmermans This program is free software; you can redistribute it and/or modify @@ -206,22 +206,20 @@ void subnet_update(node_t *owner, subnet_t *subnet, bool up) { // Prepare environment variables to be passed to the script - char *envp[10] = {NULL}; - int n = 0; - xasprintf(&envp[n++], "NETNAME=%s", netname ? : ""); - xasprintf(&envp[n++], "DEVICE=%s", device ? : ""); - xasprintf(&envp[n++], "INTERFACE=%s", iface ? : ""); - xasprintf(&envp[n++], "NODE=%s", owner->name); + environment_t env; + environment_init(&env); + environment_add(&env, "NODE=%s", owner->name); if(owner != myself) { sockaddr2str(&owner->address, &address, &port); - xasprintf(&envp[n++], "REMOTEADDRESS=%s", address); - xasprintf(&envp[n++], "REMOTEPORT=%s", port); + environment_add(&env, "REMOTEADDRESS=%s", address); + environment_add(&env, "REMOTEPORT=%s", port); free(port); free(address); } - xasprintf(&envp[n++], "NAME=%s", myself->name); + int env_subnet = environment_add(&env, NULL); + int env_weight = environment_add(&env, NULL); name = up ? "subnet-up" : "subnet-down"; @@ -238,12 +236,10 @@ void subnet_update(node_t *owner, subnet_t *subnet, bool up) { weight = empty; // Prepare the SUBNET and WEIGHT variables - free(envp[n]); - free(envp[n + 1]); - xasprintf(&envp[n], "SUBNET=%s", netstr); - xasprintf(&envp[n + 1], "WEIGHT=%s", weight); + environment_update(&env, env_subnet, "SUBNET=%s", netstr); + environment_update(&env, env_weight, "WEIGHT=%s", weight); - execute_script(name, envp); + execute_script(name, &env); } } else { if(net2str(netstr, sizeof netstr, subnet)) { @@ -255,15 +251,14 @@ void subnet_update(node_t *owner, subnet_t *subnet, bool up) { weight = empty; // Prepare the SUBNET and WEIGHT variables - xasprintf(&envp[n], "SUBNET=%s", netstr); - xasprintf(&envp[n + 1], "WEIGHT=%s", weight); + environment_update(&env, env_subnet, "SUBNET=%s", netstr); + environment_update(&env, env_weight, "WEIGHT=%s", weight); - execute_script(name, envp); + execute_script(name, &env); } } - for(int i = 0; envp[i] && i < 9; i++) - free(envp[i]); + environment_exit(&env); } bool dump_subnets(connection_t *c) { diff --git a/src/subnet_parse.c b/src/subnet_parse.c index 611d6bd..c5f6976 100644 --- a/src/subnet_parse.c +++ b/src/subnet_parse.c @@ -372,7 +372,7 @@ bool net2str(char *netstr, int len, const subnet_t *subnet) { result = snprintf(netstr, len, *format, ":::"); i += max_zero_length; } else { - result = snprintf(netstr, len, "%hx:", ntohs(subnet->net.ipv6.address.x[i])); + result = snprintf(netstr, len, "%x:", ntohs(subnet->net.ipv6.address.x[i])); i++; } netstr += result; diff --git a/src/tincctl.c b/src/tincctl.c index 465c981..9eb9a1b 100644 --- a/src/tincctl.c +++ b/src/tincctl.c @@ -1,6 +1,6 @@ /* tincctl.c -- Controlling a running tincd - Copyright (C) 2007-2016 Guus Sliepen + Copyright (C) 2007-2017 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 @@ -74,6 +74,9 @@ bool netnamegiven = false; char *scriptinterpreter = NULL; char *scriptextension = ""; static char *prompt; +char *device = NULL; +char *iface = NULL; +int debug_level = -1; static struct option const long_options[] = { {"batch", no_argument, NULL, 'b'}, @@ -89,7 +92,7 @@ static struct option const long_options[] = { static void version(void) { printf("%s version %s (built %s %s, protocol %d.%d)\n", PACKAGE, BUILD_VERSION, BUILD_DATE, BUILD_TIME, PROT_MAJOR, PROT_MINOR); - printf("Copyright (C) 1998-2016 Ivo Timmermans, Guus Sliepen and others.\n" + printf("Copyright (C) 1998-2017 Ivo Timmermans, Guus Sliepen and others.\n" "See the AUTHORS file for a complete list.\n\n" "tinc comes with ABSOLUTELY NO WARRANTY. This is free software,\n" "and you are welcome to redistribute it under certain conditions;\n" @@ -446,11 +449,13 @@ static bool rsa_keygen(int bits, bool ask) { // Make sure the key size is a multiple of 8 bits. bits &= ~0x7; - // Force them to be between 1024 and 8192 bits long. - if(bits < 1024) - bits = 1024; - if(bits > 8192) - bits = 8192; + // Make sure that a valid key size is used. + if(bits < 1024 || bits > 8192) { + fprintf(stderr, "Invalid key size %d specified! It should be between 1024 and 8192 bits.\n", bits); + return false; + } else if(bits < 2048) { + fprintf(stderr, "WARNING: generating a weak %d bits RSA key! 2048 or more bits are recommended.\n", bits); + } fprintf(stderr, "Generating %d bits keys:\n", bits); @@ -508,7 +513,7 @@ bool recvline(int fd, char *line, size_t len) { char *newline = NULL; if(!fd) - abort(); + return false; while(!(newline = memchr(buffer, '\n', blen))) { int result = recv(fd, buffer + blen, sizeof buffer - blen, 0); @@ -719,6 +724,8 @@ bool connect_tincd(bool verbose) { } fclose(f); + +#ifndef HAVE_MINGW if ((pid == 0) || (kill(pid, 0) && (errno == ESRCH))) { fprintf(stderr, "Could not find tincd running at pid %d\n", pid); /* clean up the stale socket and pid file */ @@ -727,7 +734,6 @@ bool connect_tincd(bool verbose) { return false; } -#ifndef HAVE_MINGW struct sockaddr_un sa; sa.sun_family = AF_UNIX; strncpy(sa.sun_path, unixsocketname, sizeof sa.sun_path); @@ -797,7 +803,7 @@ bool connect_tincd(bool verbose) { char data[4096]; int version; - if(!recvline(fd, line, sizeof line) || sscanf(line, "%d %s %d", &code, data, &version) != 3 || code != 0) { + if(!recvline(fd, line, sizeof line) || sscanf(line, "%d %4095s %d", &code, data, &version) != 3 || code != 0) { if(verbose) fprintf(stderr, "Cannot read greeting from control socket: %s\n", sockstrerror(sockerrno)); close(fd); @@ -945,11 +951,11 @@ static int cmd_stop(int argc, char *argv[]) { if(!connect_tincd(true)) { if(pid) { if(kill(pid, SIGTERM)) { - fprintf(stderr, "Could not send TERM signal to process with PID %u: %s\n", pid, strerror(errno)); + fprintf(stderr, "Could not send TERM signal to process with PID %d: %s\n", pid, strerror(errno)); return 1; } - fprintf(stderr, "Sent TERM signal to process with PID %u.\n", pid); + fprintf(stderr, "Sent TERM signal to process with PID %d.\n", pid); waitpid(pid, NULL, 0); return 0; } @@ -1024,7 +1030,6 @@ static int dump_invitations(void) { FILE *f = fopen(fname, "r"); if(!f) { fprintf(stderr, "Cannot open %s: %s\n", fname, strerror(errno)); - fclose(f); continue; } @@ -1113,7 +1118,7 @@ static int cmd_dump(int argc, char *argv[]) { while(recvline(fd, line, sizeof line)) { char node1[4096], node2[4096]; - int n = sscanf(line, "%d %d %s %s", &code, &req, node1, node2); + int n = sscanf(line, "%d %d %4095s %4095s", &code, &req, node1, node2); if(n == 2) { if(do_graph && req == REQ_DUMP_NODES) continue; @@ -1145,7 +1150,7 @@ static int cmd_dump(int argc, char *argv[]) { switch(req) { case REQ_DUMP_NODES: { - int n = sscanf(line, "%*d %*d %s %s %s port %s %d %d %d %d %x %x %s %s %d %hd %hd %hd %ld", node, id, host, port, &cipher, &digest, &maclength, &compression, &options, &status_int, nexthop, via, &distance, &pmtu, &minmtu, &maxmtu, &last_state_change); + int n = sscanf(line, "%*d %*d %4095s %4095s %4095s port %4095s %d %d %d %d %x %x %4095s %4095s %d %hd %hd %hd %ld", node, id, host, port, &cipher, &digest, &maclength, &compression, &options, &status_int, nexthop, via, &distance, &pmtu, &minmtu, &maxmtu, &last_state_change); if(n != 17) { fprintf(stderr, "Unable to parse node dump from tincd: %s\n", line); return 1; @@ -1169,13 +1174,13 @@ static int cmd_dump(int argc, char *argv[]) { } else { if(only_reachable && !status.reachable) continue; - printf("%s id %s at %s port %s cipher %d digest %d maclength %d compression %d options %x status %04x nexthop %s via %s distance %d pmtu %hd (min %hd max %hd)\n", + printf("%s id %s at %s port %s cipher %d digest %d maclength %d compression %d options %x status %04x nexthop %s via %s distance %d pmtu %d (min %d max %d)\n", node, id, host, port, cipher, digest, maclength, compression, options, status_int, nexthop, via, distance, pmtu, minmtu, maxmtu); } } break; case REQ_DUMP_EDGES: { - int n = sscanf(line, "%*d %*d %s %s %s port %s %s port %s %x %d", from, to, host, port, local_host, local_port, &options, &weight); + int n = sscanf(line, "%*d %*d %4095s %4095s %4095s port %4095s %4095s port %4095s %x %d", from, to, host, port, local_host, local_port, &options, &weight); if(n != 8) { fprintf(stderr, "Unable to parse edge dump from tincd.\n"); return 1; @@ -1193,7 +1198,7 @@ static int cmd_dump(int argc, char *argv[]) { } break; case REQ_DUMP_SUBNETS: { - int n = sscanf(line, "%*d %*d %s %s", subnet, node); + int n = sscanf(line, "%*d %*d %4095s %4095s", subnet, node); if(n != 2) { fprintf(stderr, "Unable to parse subnet dump from tincd.\n"); return 1; @@ -1202,7 +1207,7 @@ static int cmd_dump(int argc, char *argv[]) { } break; case REQ_DUMP_CONNECTIONS: { - int n = sscanf(line, "%*d %*d %s %s port %s %x %d %x", node, host, port, &options, &socket, &status_int); + int n = sscanf(line, "%*d %*d %4095s %4095s port %4095s %x %d %x", node, host, port, &options, &socket, &status_int); if(n != 6) { fprintf(stderr, "Unable to parse connection dump from tincd.\n"); return 1; @@ -1485,9 +1490,11 @@ const var_t variables[] = { {"Hostnames", VAR_SERVER}, {"IffOneQueue", VAR_SERVER}, {"Interface", VAR_SERVER}, + {"InvitationExpire", VAR_SERVER}, {"KeyExpire", VAR_SERVER}, {"ListenAddress", VAR_SERVER | VAR_MULTIPLE}, {"LocalDiscovery", VAR_SERVER}, + {"LogLevel", VAR_SERVER}, {"MACExpire", VAR_SERVER}, {"MaxConnectionBurst", VAR_SERVER}, {"MaxOutputBufferSize", VAR_SERVER}, @@ -2227,7 +2234,7 @@ static int cmd_import(int argc, char *argv[]) { bool firstline = true; while(fgets(buf, sizeof buf, in)) { - if(sscanf(buf, "Name = %s", name) == 1) { + if(sscanf(buf, "Name = %4095s", name) == 1) { firstline = false; if(!check_id(name)) { @@ -2719,7 +2726,7 @@ static char *complete_info(const char *text, int state) { while(recvline(fd, line, sizeof line)) { char item[4096]; - int n = sscanf(line, "%d %d %s", &code, &req, item); + int n = sscanf(line, "%d %d %4095s", &code, &req, item); if(n == 2) { i++; if(i >= 2) @@ -2820,8 +2827,6 @@ static int cmd_shell(int argc, char *argv[]) { while(p && *p) { if(nargc >= maxargs) { - fprintf(stderr, "next %p '%s', p %p '%s'\n", next, next, p, p); - abort(); maxargs *= 2; nargv = xrealloc(nargv, maxargs * sizeof *nargv); } diff --git a/src/tincd.c b/src/tincd.c index 4da9bd5..2ab9ba7 100644 --- a/src/tincd.c +++ b/src/tincd.c @@ -400,6 +400,9 @@ int main(int argc, char **argv) { if(!read_server_config()) return 1; + if(!debug_level) + get_config_int(lookup_config(config_tree, "LogLevel"), &debug_level); + #ifdef HAVE_LZO if(lzo_init() != LZO_E_OK) { logger(DEBUG_ALWAYS, LOG_ERR, "Error initializing LZO compressor!"); diff --git a/src/top.c b/src/top.c index 40b8047..8227d6c 100644 --- a/src/top.c +++ b/src/top.c @@ -90,7 +90,7 @@ static bool update(int fd) { ns->known = false; while(recvline(fd, line, sizeof line)) { - int n = sscanf(line, "%d %d %s %"PRIu64" %"PRIu64" %"PRIu64" %"PRIu64, &code, &req, name, &in_packets, &in_bytes, &out_packets, &out_bytes); + int n = sscanf(line, "%d %d %4095s %"PRIu64" %"PRIu64" %"PRIu64" %"PRIu64, &code, &req, name, &in_packets, &in_bytes, &out_packets, &out_bytes); if(n == 2) return true; @@ -158,40 +158,54 @@ static int cmpu64(uint64_t a, uint64_t b) { static int sortfunc(const void *a, const void *b) { const nodestats_t *na = *(const nodestats_t **)a; const nodestats_t *nb = *(const nodestats_t **)b; + int result; + switch(sortmode) { case 1: if(cumulative) - return -cmpu64(na->in_packets, nb->in_packets) ?: na->i - nb->i; + result = -cmpu64(na->in_packets, nb->in_packets); else - return -cmpfloat(na->in_packets_rate, nb->in_packets_rate) ?: na->i - nb->i; + result = -cmpfloat(na->in_packets_rate, nb->in_packets_rate); + break; case 2: if(cumulative) - return -cmpu64(na->in_bytes, nb->in_bytes) ?: na->i - nb->i; + result = -cmpu64(na->in_bytes, nb->in_bytes); else - return -cmpfloat(na->in_bytes_rate, nb->in_bytes_rate) ?: na->i - nb->i; + result = -cmpfloat(na->in_bytes_rate, nb->in_bytes_rate); + break; case 3: if(cumulative) - return -cmpu64(na->out_packets, nb->out_packets) ?: na->i - nb->i; + result = -cmpu64(na->out_packets, nb->out_packets); else - return -cmpfloat(na->out_packets_rate, nb->out_packets_rate) ?: na->i - nb->i; + result = -cmpfloat(na->out_packets_rate, nb->out_packets_rate); + break; case 4: if(cumulative) - return -cmpu64(na->out_bytes, nb->out_bytes) ?: na->i - nb->i; + result = -cmpu64(na->out_bytes, nb->out_bytes); else - return -cmpfloat(na->out_bytes_rate, nb->out_bytes_rate) ?: na->i - nb->i; + result = -cmpfloat(na->out_bytes_rate, nb->out_bytes_rate); + break; case 5: if(cumulative) - return -cmpu64(na->in_packets + na->out_packets, nb->in_packets + nb->out_packets) ?: na->i - nb->i; + result = -cmpu64(na->in_packets + na->out_packets, nb->in_packets + nb->out_packets); else - return -cmpfloat(na->in_packets_rate + na->out_packets_rate, nb->in_packets_rate + nb->out_packets_rate) ?: na->i - nb->i; + result = -cmpfloat(na->in_packets_rate + na->out_packets_rate, nb->in_packets_rate + nb->out_packets_rate); + break; case 6: if(cumulative) - return -cmpu64(na->in_bytes + na->out_bytes, nb->in_bytes + nb->out_bytes) ?: na->i - nb->i; + result = -cmpu64(na->in_bytes + na->out_bytes, nb->in_bytes + nb->out_bytes); else - return -cmpfloat(na->in_bytes_rate + na->out_bytes_rate, nb->in_bytes_rate + nb->out_bytes_rate) ?: na->i - nb->i; + result = -cmpfloat(na->in_bytes_rate + na->out_bytes_rate, nb->in_bytes_rate + nb->out_bytes_rate); + break; default: - return strcmp(na->name, nb->name) ?: na->i - nb->i; + result = strcmp(na->name, nb->name); + break; } + + if(result) + return result; + else + return na->i - nb->i; } static void redraw(void) { diff --git a/src/uml_device.c b/src/uml_device.c index 57d4843..68f4cd2 100644 --- a/src/uml_device.c +++ b/src/uml_device.c @@ -1,7 +1,7 @@ /* device.c -- UML network socket Copyright (C) 2002-2005 Ivo Timmermans, - 2002-2013 Guus Sliepen + 2002-2017 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 @@ -228,7 +228,7 @@ static bool read_packet(vpn_packet_t *packet) { return false; } - if(connect(write_fd, &request.sock, sizeof request.sock) < 0) { + if(connect(write_fd, (struct sockkadr *)&request.sock, sizeof request.sock) < 0) { logger(DEBUG_ALWAYS, LOG_ERR, "Could not bind write %s: %s", device_info, strerror(errno)); event_exit(); return false; diff --git a/src/upnp.c b/src/upnp.c index abd2f92..3bfc770 100644 --- a/src/upnp.c +++ b/src/upnp.c @@ -57,7 +57,7 @@ static struct UPNPDev *upnp_discover(int delay, int *error) { #elif MINIUPNPC_API_VERSION <= 14 - return upnpDiscover(delay, NULL NULL, false, false, 2, error); + return upnpDiscover(delay, NULL, NULL, false, false, 2, error); #else diff --git a/systemd/Makefile.in b/systemd/Makefile.in index 44e6bb2..f66a54e 100644 --- a/systemd/Makefile.in +++ b/systemd/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff --git a/systemd/tinc@.service b/systemd/tinc@.service index 78ef25b..d1f711d 100644 --- a/systemd/tinc@.service +++ b/systemd/tinc@.service @@ -11,6 +11,7 @@ Type=simple WorkingDirectory=/etc/tinc/%i ExecStart=/usr/sbin/tincd -n %i -D ExecReload=/usr/sbin/tinc -n %i reload +KillMode=mixed Restart=on-failure RestartSec=5 TimeoutStopSec=5 diff --git a/test/Makefile.am b/test/Makefile.am index df8e2c3..98f4a3b 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -4,9 +4,11 @@ TESTS = \ executables.test \ import-export.test \ invite-join.test \ + invite-offline.test \ invite-tinc-up.test \ ns-ping.test \ ping.test \ + scripts.test \ sptps-basic.test \ variables.test diff --git a/test/Makefile.in b/test/Makefile.in index 0dbe653..e5aadf2 100644 --- a/test/Makefile.in +++ b/test/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -477,9 +477,11 @@ TESTS = \ executables.test \ import-export.test \ invite-join.test \ + invite-offline.test \ invite-tinc-up.test \ ns-ping.test \ ping.test \ + scripts.test \ sptps-basic.test \ variables.test diff --git a/test/executables.test b/test/executables.test index 35dd2bc..801de58 100755 --- a/test/executables.test +++ b/test/executables.test @@ -5,4 +5,6 @@ # Just test whether the executables work $tincd --help $tinc --help -$sptps_test --help +if [ -e $sptps_test ]; then + $sptps_test --help +fi diff --git a/test/invite-join.test b/test/invite-join.test index c1bd1b8..28de83c 100755 --- a/test/invite-join.test +++ b/test/invite-join.test @@ -17,8 +17,6 @@ EOF # Generate an invitation and let another node join the VPN -sleep 1 - $tinc $c1 invite bar | $tinc $c2 join # Test equivalence of host config files diff --git a/test/invite-offline.test b/test/invite-offline.test new file mode 100755 index 0000000..b435493 --- /dev/null +++ b/test/invite-offline.test @@ -0,0 +1,50 @@ +#!/bin/sh + +. ./testlib.sh + +# Initialize one node + +$tinc $c1 < + Copyright (C) 2013-2017 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 @@ -19,6 +19,8 @@ #include "../src/system.h" +#include "../src/ethernet.h" + uint8_t mymac[6] = {6, 5, 5, 6, 5, 5}; static ssize_t do_arp(uint8_t *buf, ssize_t len, struct sockaddr_in *in) { @@ -152,7 +154,7 @@ int main(int argc, char *argv[]) { #endif default: - fprintf(stderr, "Multicast for address family %hx unsupported\n", ai->ai_family); + fprintf(stderr, "Multicast for address family %x unsupported\n", ai->ai_family); return 1; } diff --git a/test/scripts.test b/test/scripts.test new file mode 100755 index 0000000..3b3f274 --- /dev/null +++ b/test/scripts.test @@ -0,0 +1,112 @@ +#!/bin/sh + +. ./testlib.sh + +# Initialize server node + +$tinc $c1 <$d1/$script << EOF +#!/bin/sh +echo $script \$NETNAME,\$NAME,\$DEVICE,\$IFACE,\$NODE,\$REMOTEADDRESS,\$REMOTEPORT,\$SUBNET,\$WEIGHT,\$INVITATION_FILE,\$INVITATION_URL,\$DEBUG >>$OUT +EOF +chmod u+x $d1/$script +done + +# Start server node + +$tinc -n netname $c1 start $r1 + +echo foo-started >>$OUT + +# Invite client node + +url=`$tinc -n netname2 $c1 invite bar` +file=`cd $d1/invitations; ls | grep -v ed25519_key.priv` +echo bar-invited >>$OUT +$tinc -n netname3 $c2 join $url +echo bar-joined >>$OUT + +# Start and stop client node + +$tinc $c2 << EOF +set DeviceType dummy +set Port 32760 +add Subnet 10.0.0.2 +add Subnet fec0::/64#5 +start $r2 +EOF + +sleep 1 + +echo bar-started >>$OUT + +$tinc $c1 debug 4 +$tinc $c2 stop + +sleep 1 + +echo bar-stopped >>$OUT + +$tinc $c1 debug 5 +$tinc $c2 start $r2 + +sleep 1 + +echo bar-started >>$OUT + +# Stop server node + +$tinc $c1 stop +sleep 1 +$tinc $c2 stop + +# Check if the script output is what is expected + +cat >$OUT.expected << EOF +tinc-up netname,foo,dummy,,,,,,,,,5 +subnet-up netname,foo,dummy,,foo,,,10.0.0.1,,,,5 +subnet-up netname,foo,dummy,,foo,,,fec0::/64,,,,5 +foo-started +invitation-created netname2,foo,,,bar,,,,,$d1/invitations/$file,$url, +bar-invited +invitation-accepted netname,foo,dummy,,bar,127.0.0.1,,,,,,5 +bar-joined +host-up netname,foo,dummy,,bar,127.0.0.1,32760,,,,,5 +hosts/bar-up netname,foo,dummy,,bar,127.0.0.1,32760,,,,,5 +subnet-up netname,foo,dummy,,bar,127.0.0.1,32760,10.0.0.2,,,,5 +subnet-up netname,foo,dummy,,bar,127.0.0.1,32760,fec0::/64,5,,,5 +bar-started +host-down netname,foo,dummy,,bar,127.0.0.1,32760,,,,,4 +hosts/bar-down netname,foo,dummy,,bar,127.0.0.1,32760,,,,,4 +subnet-down netname,foo,dummy,,bar,127.0.0.1,32760,10.0.0.2,,,,4 +subnet-down netname,foo,dummy,,bar,127.0.0.1,32760,fec0::/64,5,,,4 +bar-stopped +host-up netname,foo,dummy,,bar,127.0.0.1,32760,,,,,5 +hosts/bar-up netname,foo,dummy,,bar,127.0.0.1,32760,,,,,5 +subnet-up netname,foo,dummy,,bar,127.0.0.1,32760,10.0.0.2,,,,5 +subnet-up netname,foo,dummy,,bar,127.0.0.1,32760,fec0::/64,5,,,5 +bar-started +host-down netname,foo,dummy,,bar,127.0.0.1,32760,,,,,5 +hosts/bar-down netname,foo,dummy,,bar,127.0.0.1,32760,,,,,5 +subnet-down netname,foo,dummy,,bar,127.0.0.1,32760,10.0.0.2,,,,5 +subnet-down netname,foo,dummy,,bar,127.0.0.1,32760,fec0::/64,5,,,5 +subnet-down netname,foo,dummy,,foo,,,10.0.0.1,,,,5 +subnet-down netname,foo,dummy,,foo,,,fec0::/64,,,,5 +tinc-down netname,foo,dummy,,,,,,,,,5 +EOF + +cmp $OUT $OUT.expected diff --git a/test/sptps-basic.test b/test/sptps-basic.test index 644a31e..9f86c8c 100755 --- a/test/sptps-basic.test +++ b/test/sptps-basic.test @@ -2,6 +2,10 @@ . ./testlib.sh +# Skip this test if we did not compile sptps_test + +test -e $sptps_test || exit 77 + # Generate keys mkdir -p $d1 @@ -11,18 +15,18 @@ $sptps_keypair $d1/client.priv $d1/client.pub # Test transfer of a simple file. -(sleep 1; $sptps_test -q $d1/client.priv $d1/server.pub localhost 32750 <../README) & -$sptps_test $d1/server.priv $d1/client.pub 32750 >$d1/out1 +(sleep 1; $sptps_test -4 -q $d1/client.priv $d1/server.pub localhost 32750 <../README) & +$sptps_test -4 $d1/server.priv $d1/client.pub 32750 >$d1/out1 cmp $d1/out1 ../README -$sptps_test -q $d1/server.priv $d1/client.pub 32750 <../NEWS & +$sptps_test -4 -q $d1/server.priv $d1/client.pub 32750 <../NEWS & sleep 1 -$sptps_test $d1/client.priv $d1/server.pub localhost 32750 > $d1/out2 +$sptps_test -4 $d1/client.priv $d1/server.pub localhost 32750 > $d1/out2 cmp $d1/out2 ../NEWS # Datagram mode -$sptps_test -dq $d1/server.priv $d1/client.pub 32750 <../COPYING & +$sptps_test -4 -dq $d1/server.priv $d1/client.pub 32750 <../COPYING & sleep 1 -sleep 1 | $sptps_test -dq $d1/client.priv $d1/server.pub localhost 32750 >$d1/out3 +sleep 1 | $sptps_test -4 -dq $d1/client.priv $d1/server.pub localhost 32750 >$d1/out3 cmp $d1/out3 ../COPYING diff --git a/test/testlib.sh b/test/testlib.sh index 3103335..75b60a7 100644 --- a/test/testlib.sh +++ b/test/testlib.sh @@ -9,18 +9,10 @@ sptps_keypair=../src/sptps_keypair # Test directories -case "$_" in - /*) - d1=$_.1 - d2=$_.2 - d3=$_.3 - ;; - *) - d1=$PWD/$_.1 - d2=$PWD/$_.2 - d3=$PWD/$_.3 - ;; -esac +scriptname=`basename $0` +d1=$PWD/$scriptname.1 +d2=$PWD/$scriptname.2 +d3=$PWD/$scriptname.3 # Default arguments for both tinc and tincd From b511a112e6d97b0a890bdcf87bd8d715ac8f43a2 Mon Sep 17 00:00:00 2001 From: Guus Sliepen Date: Mon, 26 Aug 2019 13:44:53 +0200 Subject: [PATCH 12/13] Import Upstream version 1.1~pre17 --- COPYING | 2 +- ChangeLog | 25974 +++++++++++++++--- Makefile.am | 7 +- Makefile.in | 34 +- NEWS | 40 +- README | 30 +- THANKS | 18 +- aclocal.m4 | 190 +- compile | 13 +- config.guess | 584 +- config.h.in | 19 +- config.sub | 258 +- configure | 2404 +- configure.ac | 21 +- depcomp | 8 +- doc/Makefile.am | 39 +- doc/Makefile.in | 75 +- doc/sample-config.tar.gz | Bin 1242 -> 0 bytes doc/sample-config/hosts/alpha | 15 + doc/sample-config/hosts/beta | 16 + doc/sample-config/rsa_key.priv | 1 + doc/sample-config/tinc-down | 4 + doc/sample-config/tinc-up | 11 + doc/sample-config/tinc.conf | 22 + doc/texinfo.tex | 5266 ++-- doc/tinc-gui.8.in | 2 +- doc/tinc.8.in | 9 +- doc/tinc.conf.5.in | 18 +- doc/tinc.info | 518 +- doc/tinc.texi | 242 +- doc/tincd.8.in | 4 +- doc/tincinclude.texi | 5 + doc/tincinclude.texi.in | 1 + gui/Makefile.am | 3 - gui/Makefile.in | 507 - gui/tinc-gui | 634 - install-sh | 36 +- m4/ax_code_coverage.m4 | 264 + m4/curses.m4 | 2 +- m4/openssl.m4 | 3 +- missing | 16 +- src/Makefile.am | 6 +- src/Makefile.in | 516 +- src/address_cache.c | 277 + src/address_cache.h | 50 + src/autoconnect.c | 73 +- src/autoconnect.h | 6 +- src/bsd/device.c | 422 +- src/bsd/tunemu.c | 213 +- src/buffer.c | 18 +- src/buffer.h | 18 +- src/chacha-poly1305/chacha-poly1305.c | 49 +- src/chacha-poly1305/chacha.c | 43 +- src/chacha-poly1305/chacha.h | 12 +- src/chacha-poly1305/poly1305.c | 42 +- src/chacha-poly1305/poly1305.h | 8 +- src/cipher.h | 31 +- src/conf.c | 186 +- src/conf.h | 42 +- src/connection.c | 23 +- src/connection.h | 52 +- src/control.c | 149 +- src/control.h | 10 +- src/control_common.h | 6 +- src/crypto.h | 12 +- src/cygwin/device.c | 64 +- src/device.h | 8 +- src/digest.h | 26 +- src/dropin.c | 6 +- src/dropin.h | 28 +- src/dummy_device.c | 9 +- src/ecdh.h | 12 +- src/ecdsa.h | 18 +- src/ecdsagen.h | 12 +- src/ed25519/ecdh.c | 6 +- src/ed25519/ecdsa.c | 40 +- src/ed25519/ecdsagen.c | 14 +- src/ed25519/ed25519.h | 16 +- src/ed25519/fe.c | 2348 +- src/ed25519/fixedint.h | 102 +- src/ed25519/ge.c | 586 +- src/ed25519/ge.h | 36 +- src/ed25519/key_exchange.c | 131 +- src/ed25519/keypair.c | 14 +- src/ed25519/precomp_data.h | 2768 +- src/ed25519/sc.c | 1484 +- src/ed25519/sha512.c | 398 +- src/ed25519/sha512.h | 12 +- src/ed25519/sign.c | 36 +- src/ed25519/verify.c | 120 +- src/edge.c | 20 +- src/edge.h | 24 +- src/ethernet.h | 14 +- src/event.c | 287 +- src/event.h | 8 +- src/fd_device.c | 4 +- src/fsck.c | 218 +- src/fsck.h | 7 +- src/gcrypt/cipher.c | 34 +- src/gcrypt/digest.c | 27 +- src/gcrypt/digest.h | 6 +- src/gcrypt/prf.c | 35 +- src/gcrypt/rsa.c | 141 +- src/gcrypt/rsagen.c | 85 +- src/getopt.c | 1313 +- src/getopt.h | 68 +- src/getopt1.c | 180 +- src/graph.c | 70 +- src/graph.h | 8 +- src/hash.c | 36 +- src/hash.h | 10 +- src/have.h | 8 +- src/ifconfig.c | 213 +- src/ifconfig.h | 6 +- src/info.c | 179 +- src/info.h | 7 +- src/invitation.c | 539 +- src/invitation.h | 7 +- src/ipv4.h | 20 +- src/ipv6.h | 20 +- src/linux/device.c | 134 +- src/list.c | 55 +- src/list.h | 46 +- src/logger.c | 178 +- src/logger.h | 12 +- src/meta.c | 102 +- src/meta.h | 20 +- src/mingw/common.h | 7 +- src/mingw/device.c | 126 +- src/multicast_device.c | 114 +- src/names.c | 83 +- src/names.h | 8 +- src/net.c | 184 +- src/net.h | 63 +- src/net_packet.c | 633 +- src/net_setup.c | 483 +- src/net_socket.c | 385 +- src/netutl.c | 146 +- src/netutl.h | 28 +- src/node.c | 73 +- src/node.h | 61 +- src/nolegacy/crypto.c | 11 +- src/nolegacy/prf.c | 35 +- src/openssl/cipher.c | 73 +- src/openssl/crypto.c | 15 +- src/openssl/digest.c | 78 +- src/openssl/digest.h | 11 +- src/openssl/prf.c | 8 +- src/openssl/rsa.c | 40 +- src/openssl/rsagen.c | 52 +- src/prf.h | 8 +- src/process.c | 90 +- src/process.h | 8 +- src/protocol.c | 86 +- src/protocol.h | 100 +- src/protocol_auth.c | 482 +- src/protocol_edge.c | 82 +- src/protocol_key.c | 231 +- src/protocol_misc.c | 175 +- src/protocol_subnet.c | 74 +- src/raw_socket_device.c | 39 +- src/route.c | 489 +- src/route.h | 10 +- src/rsa.h | 20 +- src/rsagen.h | 12 +- src/script.c | 74 +- src/script.h | 8 +- src/solaris/device.c | 173 +- src/splay_tree.c | 174 +- src/splay_tree.h | 66 +- src/sptps.c | 330 +- src/sptps.h | 6 +- src/sptps_keypair.c | 43 +- src/sptps_speed.c | 119 +- src/sptps_test.c | 257 +- src/subnet.c | 73 +- src/subnet.h | 44 +- src/subnet_parse.c | 348 +- src/system.h | 8 +- src/tincctl.c | 1380 +- src/tincctl.h | 9 +- src/tincd.c | 307 +- src/top.c | 316 +- src/top.h | 7 +- src/uml_device.c | 189 +- src/upnp.c | 51 +- src/upnp.h | 8 +- src/utils.c | 195 +- src/utils.h | 22 +- src/vde_device.c | 26 +- src/version.c | 10 +- src/version.h | 14 +- src/xalloc.h | 51 +- systemd/Makefile.am | 16 +- systemd/Makefile.in | 66 +- systemd/{tinc.service => tinc.service.in} | 2 +- systemd/{tinc@.service => tinc@.service.in} | 6 +- test-driver | 10 +- test/Makefile.am | 11 +- test/Makefile.in | 92 +- test/basic.test | 2 +- test/commandline.test | 2 +- test/executables.test | 2 +- test/import-export.test | 2 +- test/invite-join.test | 3 +- test/invite-offline.test | 3 +- test/invite-tinc-up.test | 2 +- test/legacy-protocol.test | 79 + test/ns-ping.test | 2 +- test/ping.test | 58 - test/pong.c | 196 - test/scripts.test | 2 +- test/security.test | 98 + test/splice.c | 144 + test/sptps-basic.test | 16 +- test/variables.test | 2 +- 216 files changed, 43313 insertions(+), 18448 deletions(-) delete mode 100644 doc/sample-config.tar.gz create mode 100644 doc/sample-config/hosts/alpha create mode 100644 doc/sample-config/hosts/beta create mode 100644 doc/sample-config/rsa_key.priv create mode 100644 doc/sample-config/tinc-down create mode 100644 doc/sample-config/tinc-up create mode 100644 doc/sample-config/tinc.conf create mode 100644 doc/tincinclude.texi delete mode 100644 gui/Makefile.am delete mode 100644 gui/Makefile.in delete mode 100755 gui/tinc-gui create mode 100644 m4/ax_code_coverage.m4 create mode 100644 src/address_cache.c create mode 100644 src/address_cache.h rename systemd/{tinc.service => tinc.service.in} (92%) rename systemd/{tinc@.service => tinc@.service.in} (73%) create mode 100755 test/legacy-protocol.test delete mode 100755 test/ping.test delete mode 100644 test/pong.c create mode 100755 test/security.test create mode 100644 test/splice.c diff --git a/COPYING b/COPYING index c7a4498..1a88dcf 100644 --- a/COPYING +++ b/COPYING @@ -1,4 +1,4 @@ -Copyright (C) 1998-2017 Ivo Timmermans, Guus Sliepen and others. +Copyright (C) 1998-2018 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/ChangeLog b/ChangeLog index 59667bf..e28cde2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3405 +1,22659 @@ -Version 1.1pre15 September 02 2017 ------------------------------------------------------------------------- +commit 2b74e1b01af2d56d6e7ebc135143fbe81f6ca455 +Author: Guus Sliepen +Date: Mon Oct 8 11:00:01 2018 +0200 -Guus Sliepen (56): - Preserve IPv6 scope_id in edges. - Fix the previous commit. - Ensure compatibility with OpenSSL 1.1.0. - Add -Wall to CFLAGS. - Check return value of RSA_generate_key_ex(). - Use EVP_MD_CTX_destroy() instead of _free(). - Force nul-termination of strings after vsnprintf(). - Fix warnings from the Clang static analyzer. - Fix potential memory leaks found by the Clang static analyzer. - Add missing m4 files. - Fix compiling with OpenSSL < 1.1.0. - Log warnings about dropped packets only with debug level 5 or higher. - Use AES256 and SHA256 by default for the legacy protocol. - Enforce maximum amount of bytes sent/received on meta-connections. - Fix potential segfault in the replacement vasprintf() function. - Don't build sptps_* binaries by default. - Remove the description of the LocalDiscoveryAddress option from the manual. - Use free_known_addresses() to free memory allocated by get_known_addresses(). - Add missing #defines used by fd_device.c. - Don't try to use kill() on Windows. - Merge remote-tracking branch 'dechamps/sleep' into 1.1 - Put script environment creation/deletion in functions. - Add DEBUG environment variable for scripts. - Use unique ports for all tests. - Remove superfluous sleep command in invite-join test. - Add the invite-offline test. - Update .gitignore. - Add the scripts test. - Ensure proper logging in the invite-offline test. - Use 127.0.0.1 instead of localhost to ensure tests are reproducible. - Ensure sptps_keypair and sptps_test get build for make check. - Use /dev/udp instead of /dev/ip on Solaris. - Use getmsg()/putmsg() instead of read()/write() on Solaris. - Ensure tests compile on *BSD. - Make sure realname is always initialized. - Fix compiler warnings on *BSD. - Fix segfault when adding environment variables. - Fix tests on *BSD. - Add missing tinc stop command to the scripts test. - Remove dead stores. - Add field widths to sscanf() calls. - Fix some minor issues found by cppcheck. - Remove unused add_scalar function. - Move logging of "would block" messages to debug level 4. - Set KillMode=mixed in the systemd service file. - Add configurable experation time for invitations. - Store the invitation data after a succesful join. - Forward-port tinc 1.0's handling of device errors. - Make autoconnect try to heal network splits. - Add missing break statements. - Force IPv4 for sptps-basic.test. - Fix a compiler warning. - Fix a file descriptor leak when using an invitation. - Ensure packet priority is cleared when sending PMTU probe replies. - Drop h and hh length modifiers from printf format strings. - Releasing 1.1pre15. + Releasing 1.1pre17. -Etienne Dechamps (7): - Fix error handling when setting up the UDP socket. - Fix crash on Windows when a socket is available for both write and read. - On Windows, don't cancel I/O when disabling the device. - Fix edge local addresses not being set when connections are established. - Fix edge updates containing local address changes. - Clarify the flow of add_edge_h(). - Fix address memory leaks in add_edge_h(). +commit 32ff5ab8a22ab80cd6c141625538dcc027458c0e +Author: Guus Sliepen +Date: Sun Oct 7 18:05:50 2018 +0200 -thorkill (4): - Send PKT_PROBE only when handshake has been done already. - Prevent tincd from sending packets to unexpecting nodes - Sanitize input in id_h - prevent integer overflows - Fix NULL pointer dereference in send_udp_info + Update THANKS. -Sean McVeigh (2): - check for daemon pid existence before trying to connect to the control socket, and clean up stale files otherwise. - fix check in cmd_pid() for failure to connect to tincd +commit 5f3e9858952277ef3d6ac9d119826cbdda0746d7 +Author: Rafael Sadowski +Date: Mon Oct 1 15:14:24 2018 +0200 -Vittorio G (VittGam) (2): - fsck: Fix ed25519 public key reading, and fclose usage. - tincctl: Avoid falling back to 1024 bits RSA key generation when an invalid key size is specified. + OpenBSD has a proper tap device. -Dennis Lan (1): - Fix typo in src/upnp.c. +commit 5e1f7fb11138bc552facfb4b64eca9131f3f25b1 +Author: Guus Sliepen +Date: Sun Oct 7 13:41:23 2018 +0200 -Pacien TRAN-GIRARD (1): - Add fd_device + Update README and links to required libraries. -Roman Savelyev (1): - Fix lost pointer trails in get_known_addresses(). +commit a03991b7911a5f0afbf1269ac47143d09be76c52 +Author: Guus Sliepen +Date: Sun Oct 7 13:32:25 2018 +0200 -Vittorio Gambaletta (VittGam) (1): - route: Support ToS/DiffServ priority inheritance when routing IPv6 packets. + Don't check for NULL-pointers before calling free(). -lemoer (1): - Added comments and unfold deep "if"-construct in timeout_handler +commit b0ffeb7eeb21920842382c302ca15ec0d758e9b6 +Author: Guus Sliepen +Date: Sun Oct 7 13:05:49 2018 +0200 -pacien (1): - Add LogLevel config option + Fix spelling errors. + + Found by codespell. -volth (1): - Avoid infinite loop on EBADFD +commit 1c475ecb575367a6b3f9328b0f643ad636155341 +Author: Guus Sliepen +Date: Sat Oct 6 23:31:05 2018 +0200 -Version 1.1pre14 May 01 2016 ------------------------------------------------------------------------- + Fix all warnings when compiling with -Wall -W -pedantic. -Guus Sliepen (2): - Revert "Remove tinc.service, it is not necessary." - Releasing 1.1pre14. +commit 953f5b4231bbbb8269bb0c55b96a1c8c4bb34a59 +Author: Guus Sliepen +Date: Sat Oct 6 18:18:45 2018 +0200 -Version 1.1pre13 April 30 2016 ------------------------------------------------------------------------- + Fix warnings from the Clang static analyzer. -Guus Sliepen (4): - Fix BSD tun device support. - Remove tinc.service, it is not necessary. - AutoConnect now only chooses from nodes for which we know an address. - Releasing 1.1pre13. +commit a6448291834ca7419553a807ee367c719c2956d0 +Author: Guus Sliepen +Date: Sat Oct 6 17:51:41 2018 +0200 -Version 1.1pre12 April 24 2016 ------------------------------------------------------------------------- + Fix compiler warnings. -Guus Sliepen (166): - Allow tinc to be compiled without OpenSSL. - Add missing nolegacy/crypto.c and prf.c. - Fixes for bugs in src/Makefile.am and tincctl.c introduced by cfe9285adf391ab66faeb5def811fe08e47a221a. - Fix indentation and some whitespace issues. - Use void pointers for opaque data blobs in the SHA512 code. - Use global "now" in try_udp() and try_mtu(). - Remember whether we sent our key to another node. - Try to clarify the new code in net_packet.c a bit. - Correctly estimate the initial MTU for legacy packets. - Fix size of type 2 probe replies. - Proactively send our own key when we request another node's key. - Don't send probe replies if we don't have the other's key. - Fix segfault when sptps_test cannot open the key files. - Always keep UDP mappings alive for nodes that also have a meta-connection. - Immediately send our key when a meta-connection is established. - Only send small packets during UDP probes. - Remove RTT and packet loss estimation code. - Send MTU probes only once every PingInterval. - Move detection of PMTU decrease to try_mtu(). - Keep track of the largest UDP packet size received from a node. - Move UDP probe reply code into its own function. - Send the size of the largest recently received packets in type 2 probe replies. - Send gratuitous type 2 probe replies. - Improve packet source detection. - Add the "fsck" command to the CLI. - Always call res_init() before getaddrinfo(). - Make "tinc add" idempotent. - Document that --force should precede commands. - Suppress warnings about parsing Ed25519 keys when they are not present. - Merge remote-tracking branch 'dechamps/sptpsabort' into 1.1 - Merge remote-tracking branch 'seehuhn/1.1' into 1.1 - Fix the case where we detach and use --logfile. - --syslog and --logfile are mutually exclusive. - Merge remote-tracking branch 'dechamps/staticfix' into 1.1 - Merge remote-tracking branch 'dechamps/fsckwin' into 1.1 - Merge remote-tracking branch 'dechamps/winmtu' into 1.1 - Merge remote-tracking branch 'dechamps/windevice' into 1.1 - Always call res_init() before getaddrinfo(). - Merge remote-tracking branch 'dechamps/wintapver' into 1.1 - Allow one-sided upgrades to Ed25519. - Fix a possible segmentation fault during key upgrades. - Don't log an error message when receiving a TERMREQ. - Fix typo 0fda572c88d02b0b200ef81d72cc4da594fa0e38 that prevented some errors from being logged. - Remove "release-" from displayed git version. - Don't include build-time generated version_git.h in the tarball. - Really remove "release-" from the git-derived version string. - Fix invitations. - Fix receiving UDP packets from tinc 1.0.x nodes. - Use AF_UNSPEC instead of AF_UNKNOWN for unspecified local address in add_edge_h(). - Be more liberal accepting ADD_EDGE messages with conflicting local address information. - Try all addresses for the hostname in an invitation URL. - Let sockaddr2str() handle AF_UNSPEC addresses. - Don't send local_address in ADD_EDGE messages if it's AF_UNSPEC. - Merge remote-tracking branches 'dechamps/sptpsrestart' and 'dechamps/keychanged' into 1.1 - Remove info-in-builddir option from AM_INIT_AUTOMAKE(). - Fix src/Makefile.am for *BSD. - Add newline at end of precomp_data.h and sc.h. - Add source of SPTPS errors to log messages. - Don't log seqno failures in sptps_verify_datagram(). - If LOCALSTATEDIR is inaccessible, store the pid and socket files in the configuration directory. - Quit with an error message if ioctl(TUNSETIFF) fails. - Add "list" as an alias for "dump" in the CLI. - Allow dumping a list of outstanding invitations. - Allocate temporary filenames on the stack. - Fix check for LOCALSTATEDIR accessibility for the CLI. - Ensure "tinc start" knows if the daemon really started succesfully. - Don't write log messages to the umbilical pipe if we don't detach. - Use socketpair() instead of pipe() for the umbilical. - Set the CLOEXEC flag on the umbilical socket. - Update copyright notices. - Fix missing return value caused by the previous commit. - Fix autoconf check for function attributes. - Fix warnings about missing return value checks. - Fix receiving SPTPS data in sptps_speed and sptps_test. - Fix alignment of output of sptps_speed. - Fix crash is sptps_logger(). - Don't #include OpenSSL headers when compiling without OpenSSL. - Coalesce two if statements that check for the same thing. - Call sockaddrfree(&e->local_address) in free_edge() instead of exit_edges(). - Fix undefined behaviour when left-shifting signed integers. - Remove unused code that caused warnings about an uninitialized variable. - Use AC_CONFIG_MACRO_DIRS([m4]). - Make subnet caches static. - Fix the PRF function when compiling without OpenSSL. - Use AC_CONFIG_MACRO_DIR() instead of _DIRS(). - In sssp_bfs(), never try to update myself. - Add -I m4 back to ACLOCAL_AMFLAGS. - Optionally install systemd service files. - Replace bare if statements with AS_IF in configure.ac. - Fix struct node_status_t. - Fix a few memory leaks in the CLI found by AddressSanitizer. - Avoid undefined behavior. - Update THANKS file. - Don't leave dead outgoing_t's in the outgoing_list. - list_delete() already free()s the deleted element. - Add support for recvmmsg(). - Use static buffers for recvmmsg(), initialize them only as needed. - Only add a reflexive address when we're sure it's working. - Merge remote-tracking branch 'mweinelt/tinc-gui' into 1.1 - Add the ability to sign and verify files. - Update .gitignore. - Only check for -fno-strict-overflow if -fwrapv does not work. - Use nostdinc instead of overriding DEFAULT_INCLUDES. - Improve performance of edge updates. - Fix forwarding of edge updates. - Clarify that scripts are called synchronously. - Small fixes for the documentation. - Add warnings for bad combinations of Device and Interface. - Fix for botched cherry-pick commit 60fb230. - Fix typo. - Don't compile getopt*.c if the system provides getopt_long(). - Update .gitignore. - Update THANKS. - Use iface instead of interface. - Support ToS/DiffServ for IPv6 meta and UDP connections. - Fix --logfile without a filename on Windows. - Never call putenv() with data on the stack. - Update "now" after connect() when making outgoing connections. - Update support for BSD tun/tap devices, add support for OS X utun interfaces. - Explicitly mention that LibreSSL can be used as well. - Update links in the documentation. - Enable silent builds by default. - Really don't compile getopt*.c if the system provides getopt_long(). - Remove elliptic curve stubs from gcrypt/, add PRF implementation. - Update .gitignore. - Make text files Markdown-compatible. - Remove checks for headers and functions that are in C99. - Fix compiling under MinGW. - Replace usleep() with nanosleep(). - Use getcwd() instead of get_current_dir_name(). - Fix typo in Makefile.am. - Fix version_get.h generation on BSD. - Remove checks for non-C99 compliant compilers. - Remove support for Windows 2000 and anything that doesn't support getaddrinfo(). - Make some platform-specific header checks conditional. - Add version_git.h and sample-config.tar.gz to CLEANFILES. - Don't assume sa.sa_family is a short int. - Remove use of strcpy() and sprintf(). - Don't use HAVE_SYSTEM, the autoconf check was removed. - Fix a non-working cast to get rid of a compiler warning. - Fix generation of version_git.h for some versions of BSD make. - Fix some compiler warnings from MinGW. - Fix conditional checking of tun/tap headers on DragonFly BSD. - Fix crash at startup when Device is not specified on OS X. - Stop using SOL_TCP, SOL_IP and SOL_IPV6. - Document how invitation files work. - Generate a tinc-up script from an invitation. - Move some stray #includes. - Allow gateways to be specified for routes. - Fix gateway parsing in invitation files. - Fix compiler warnings. - Add a test for tinc-up creation from invitations. - Chdir() to the configuration directory instead of /. - Use ifconfig_header(). - Add stricter checks for netnames. - Handle special characters in sptps_test only if the --special option is given. - Don't call terminate_connection(myself->connection). - Speed up AutoConnect at startup. - Fix the "network" command in tinc shell. - Move documentation of invitations to the manual. - Have "tinc fsck" recognize Ed25519PublicKey statements. - Fix possible read of freed memory when verifying the signature of a file. - Fix a compiler warning on Windows. - Fix starting tinc as a service on Windows. - Don't check file permissions on Windows during fsck. - Releasing 1.1pre12. +commit 69e550f5950e31fb97eb4558c3d6e564211ab03a +Author: Guus Sliepen +Date: Sun Sep 9 22:13:43 2018 +0200 -Etienne Dechamps (72): - Clarify the send_mtu_probe() function. - Add the try_tx() function. - Move try_sptps() closer to try_tx(). - Add UDP discovery mechanism. - Move responsibility for local discovery to UDP discovery. - Remove PMTU discovery code redundant with UDP discovery. - Move PMTU discovery code into the TX path. - Move try_mtu() closer to try_tx(). - Fix MTU as soon as possible. - Use -1 to identify the post-initial MTU discovery state. - Send one MTU probe at a time. - Remove bandwidth estimation code. - Use a smarter algorithm for choosing MTU discovery probe sizes. - Adjust MTU probe counts. - Don't send MTU probes smaller than 512 bytes. - Add IP_MTU-based maxmtu estimation. - Fine-tune the MTU discovery multiplier for the maxmtu < MTU case. - Recalculate and resend MTU probes if they are too large for the system. - Use a different UDP discovery interval if the tunnel is established. - Fix typo in logging statement. - Fix dynamic UDP SPTPS relaying. - Fix UDP/MTU discovery in intermediate SPTPS UDP relays. - Don't abort() willy-nilly in SPTPS code. - Add UDP_INFO protocol message. - Add MTU_INFO protocol message. - Throttle the rate of UDP_INFO messages. - Throttle the rate of MTU_INFO messages. - Don't send UDP probes past static relays. - Fix invalid getuid() call on Windows. - Fix HAVE_DECL_RES_INIT conditionals. - Make sure packet header structures are correctly packed on Windows. - When disabling the Windows device, wait for pending reads to complete. - Fix Windows device asynchronous write behavior. - Set the default for UDPRcvBuf and UDPSndBuf to 1M. - Increase the ReplayWindow default from 16 to 32. - Log TAP-Windows driver version on startup. - Warn about performance if using TAP-Windows >=9.21. - Use git description as the tinc version. - Use git describe to populate autoconf's VERSION. - Remove explicit distribution rules for m4 scripts. - Add support for out-of-tree ("VPATH") builds. - When relaying, send probes to the destination, not the source. - Use the correct originator node when relaying SPTPS UDP packets. - Expose the raw SPTPS send interface from net_packet. - Try to use UDP to relay SPTPS packets received over TCP. - Rename REQ_SPTPS to SPTPS_PACKET. - Only read one record at a time in sptps_receive_data(). - Introduce raw TCP SPTPS packet transport. - Prevent SPTPS key regeneration packets from entering an UDP relay path. - Trivial: make sptps_receive_data_datagram() a little more readable. - Proactively restart the SPTPS tunnel if we get receive errors. - Don't send KEY_CHANGED messages if we don't support the legacy protocol. - Make sure the MIN() macro is defined. - Don't pollute the system header directory namespace. - Fix SPTPS condition in try_harder(). - Don't parse node IDs if the sending node doesn't support them. - Fix direct UDP communciation with pre-relaying 1.1 nodes. - Fix crashes when trying unreachable nodes. - Don't set up an ongoing connection to myself. - Fix wrong format string type in send_sptps_tcppacket(). - Fix invalid pointer use in get_my_hostname(). - Don't try to relay packets to unreachable nodes. - Protect against callbacks removing items from the io tree. - Use a splay tree for node UDP addresses in order to avoid collisions. - Revert "Cache node IDs in a hash table for faster lookups." - Make sure the packet source MAC address is always set. - Add a new optional dependency on the miniupnpc library. - Add UPnP support to tincd. - Allow tinc to be built with miniupnpc on Windows. - Try to ensure we build correctly against various libminiupnpc versions. - Don't unset validkey when receiving SPTPS handshakes over ANS_KEY. - Add upnp.h to tincd SOURCES. + Add a test for backwards compatibility with the legacy protocol. -thorkill (8): - Fixed 2 leaks in setup_myself() - Cleanup edges stored in edge_weight_tree on exit - Cleanup local_address in protocol_edge.c - Removed double break; - Included missing names.h - Make sure we do not allocate new edge when talking to old nodes and the same edge already exists - Prevent tinc from forgeting e->local_address - Do not access e->to->prevedge if not defined +commit 46f3eba7755089ff68fdc137b0754cae2fa523eb +Author: Guus Sliepen +Date: Sun Sep 9 18:19:15 2018 +0200 -Vittorio Gambaletta (VittGam) (6): - Fix DecrementTTL option. - Fix source IP address for ICMP unreachable packets generated by tinc. - Try to reply with node address only when decrementing the TTL. - Fix DecrementTTL option for packets destined to the local node. - s/broadcast_packet_helper/route_broadcast/ - Remove forward declaration for do_decrement_ttl. + Prevent oracle attacks in the legacy protocol (CVE-2018-16737, CVE-2018-16738) + + The legacy authentication protocol allows an oracle attack that could + potentially be exploited. This commit contains several mitigations: + + - Connections are no longer closed immediately on error, but put in + a "tarpit". + - The authentication protocol now requires a valid CHAL_REPLY from the + initiator of a connection before sending a CHAL_REPLY of its own. + - Reduce the amount of connections per second accepted. + - Null ciphers or digests are no longer allowed in METAKEYs. + - Connections that claim to have the same name as the local node are + rejected. + + Just to be on the safe side: + + - The new protocol now requires a valid SIG from the initiator of a + connection before sending a SIG of its own. -Martin Weinelt (5): - tinc-gui: Reformat codebase according to PEP8 - tinc-gui: Update Node object to correctly parse responses - tinc-gui: Fix GetListCtrl method name in SuperListCtrl - tinc-gui: Use ArgumentParser, default to python2 - tinc-gui: Properly initialize class attributes for VPN in __init__ +commit 01cb1961eac33de9e9d9cecd0910850a2cb549c3 +Author: Guus Sliepen +Date: Sun Jun 24 16:19:10 2018 +0200 -Sven-Haegar Koch (3): - Fixed variables.test testsuite after 'Make "tinc add" idempotent.' change. - Let sockaddr2hostname() handle AF_UNSPEC addresses. - Fix check for public key in invite-join.test. + Enable AutoConnect by default. -Florian Klink (2): - (read|append)_config_file: log open errors as LOG_DEBUG - setup_outgoing_connection: log to LOG_DEBUG on if no known address +commit 291b8f864ea57dd68b894a3b1482ee822aad66ed +Author: Guus Sliepen +Date: Sat Jun 23 22:32:19 2018 +0200 -LunarShaddow (2): - fix typo - re-arrange include sequence to avoid a mingw introduced bug. + Remove address cache debug messages printed to stderr. -Dato Simó (1): - Fix typo in tinc.texi. +commit e5b9bd324cc24355956e9e59e5ec2df72cf9d469 +Author: Guus Sliepen +Date: Sat Jun 23 22:26:12 2018 +0200 -Jo-Philipp Wich (1): - fix musl compatibility + Avoid treating compressed MTU probes as having a negative length. + + This was not harmful, but caused negative values being logged. -Jochen Voss (1): - Add a new --syslog option for tincd. +commit 950bbc8f2f9c580ac85bef7bab9a3ae36ea99c4b +Author: Guus Sliepen +Date: Wed Jun 13 22:41:02 2018 +0200 -Nathan Stratton Treadway (1): - Fix invalid checksum generation. + Print UDP RTT on its own line. -Pierre Emeriaud (1): - Fix typo in tincctl help. +commit 22ae0c3549628739ca7c40e48ce1a276469ded92 +Merge: 15341e76 70e1e467 +Author: Guus Sliepen +Date: Wed Jun 13 22:23:27 2018 +0200 -xentec (1): - Fix compile errors introduced in cfe9285adf391ab66faeb5def811fe08e47a221a + Merge remote-tracking branch 'volth/release-1.1pre16-rtt' into 1.1 + + Also, reformat the code and fix a compiler warning. -Version 1.1pre11 December 27 2014 ------------------------------------------------------------------------- +commit 15341e7697fe88a9f3b4646a2cb784dc515609bd +Author: Guus Sliepen +Date: Tue Jun 12 20:50:58 2018 +0200 -Etienne Dechamps (68): - Move Solaris if_fd to local scope. - Make device close cleaner. - Cleanly remove the device FD from the event loop before closing it. - Add DeviceStandby option to only enable the device when nodes are reachable. - Make DeviceStandby control network interface link status on Windows. - Fix Windows includes. - Fix errno references when handling socket errors. - Protect against spurious connection events. - Fix connection event error handling. - Use native Windows events for the event loop. - Make the event loop expose a Windows event interface. - Use a Windows event to stop tinc when running as a service. - Remove the TAP-Win32 reader thread. - Add local address information to edges. - Use edge local addresses for local discovery. - Remove broadcast-based local discovery mechanism. - Enable LocalDiscovery by default. - Implement sptps_verify_datagram(). - Make broadcast addresses configurable. - Make IPv4 multicast space 224.0.0.0/4 broadcast by default. - Regenerate build date and time every time tinc is built. - Use git description as the tinc version. - Rewrite, fix and improve str2net(). - When printing MAC addresses, always use trailing zeroes. - Don't print subnet prefix lengths and weights for one-host subnets. - Canonicalize IPv6 addresses as per RFC 5952 before printing them. - Fix tinc event loop reentrancy from timeout handlers. - Make sure myport is set correctly when running with Port = 0. - Fix event loop io tree inconsistency on Windows. - Fix a typo (FORTIFY_SOURCE). - Handle the "no local address" case in send_sptps_data(). - Don't initialize outpkt to an unused value. - Remove redundant connection_t::status.active field. - Only declare the origpriority variable if we support priority. - Remove an unnecessary pointer dereference in execute_script(). - Fix callback signature for TAP-Win32 device_handle_read(). - Remove unused variable in TAP-Win32 setup_device(). - Remove unused device stats variables. - Resolve KEY_EVENT conflict between Windows and ncurses. - Check if devops is valid before closing the device. - Shutdown cleanly when receiving a Windows console shutdown request. - Fix "tinc start" on Windows when the path contains spaces. - Improve subprocess behavior in tinc start command. - Add documentation about using system-assigned ports. - Verify seqno early in sptps_verify_datagram(). - Add a non-interactive mode to tinc commands. - Only read from TAP-Win32 if the device is enabled. - Handle TAP-Win32 immediate reads correctly. - Clarify copyright ownership for code authored by Etienne Dechamps. - Remove Google from the list of copyright owners. - Fix undefined HOST_NAME_MAX on Windows. - Don't enable the device if the reachable count is zero. - Fix wrong identifier in SO_NOSIGPIPE call. - Fix default TAP device on Darwin. - Ignore the Interface option if device rename is impossible. - Fix default device path selection on BSD. - Preemptively mirror REQ_PUBKEY messages from nodes with unknown keys. - Fix protocol version check for type 2 MTU probe replies. - Invalidate UDP information on address changes. - Introduce node IDs. - Change vpn_packet_t::seqno from uint32_t to uint8_t[4]. - Prepend source node ID information to UDP datagrams. - Add UDP datagram relay support to SPTPS. - Don't send MTU probes to nodes we can't reach directly. - Make sure to discover MTU with relays. - Query the Linux device for its MAC address. - Don't spontaneously start SPTPS with neighbors. - Use plain old PACKET for TCP packets sent directly to a neighbor. + Add missing item and attribution to NEWS. -Guus Sliepen (68): - Really fix compiling under Windows. - Add missing attribution for 1.1pre10 to the NEWS file. - Add "network" command to list or switch networks. - Rewind the file before trying to use PEM_read_RSA_PUBKEY(). - Handle a disconnecting tincd better. - Fix return value of b64encode(). - Use Ed25519 keys. - Properly initialize buffers. - Merge branch '1.1-ed25519' into 1.1 - Use the ChaCha-Poly1305 cipher for the SPTPS protocol. - sptps_test: allow using a tun device instead of stdio. - Put brackets around IPv6 addresses in invitation URL, even if there is no port number. - Nexthop calculation should always use the shortest path. - Fix compiler warnings. - Change AutoConnect from int to bool. - Use void pointers to opaque buffers. - Add missing closedir(). - Fix a crash when we have a malformed public ECDSA key of another node. - Fix PMTU discovery via datagram SPTPS. - Add sanity checks when generating new RSA keys. - Rename ECDSA to Ed25519. - Implement a PEM-like format for Ed25519 keys. - Allow Cipher and Digest "none". - Fix base64 decoding of Ed25519 keys. - Return non-zero exit code when "tinc get" does not find the requested variable. - Unconditionally return non-zero exit code when "tinc del" does not find the requested variable. - Remove the warnings when IP_DONTFRAGMENT/IPV6-DONTFRAG is not supported. - Merge branch 'winevents-clean' of https://github.com/dechamps/tinc into 1.1 - Give getsockopt() a reference to a socklen_t. - Fix compiler warnings. - Fix segmentation fault when dumping subnets. - Fix incorrect format qualifiers. - Reserve legacy active bit in connection_status_t. - Fix a potential file descriptor leak. - Fix unsafe use of strncpy() and sprintf(). - Merge branch 'winwarnings' of https://github.com/dechamps/tinc into 1.1 - Merge branch 'ctrl' of https://github.com/dechamps/tinc into 1.1 - Merge branch 'tincstart' of https://github.com/dechamps/tinc into 1.1 - Merge branch 'keysegfault' of https://github.com/dechamps/tinc into 1.1 - Revert "Use git description as the tinc version." - Fix compiler warnings. - Check validity of Ed25519 key during an upgrade. - Log an error message with the node's name when receiving bad SPTPS packets. - Better log messages when we already know the peer's key during an upgrade. - Add an explicit hash_delete() function. - Cache node IDs in a hash table for faster lookups. - Avoid memmove() for legacy UDP packets. - Make UDP packet handling more efficient. - Changes that should have been in commit 46fa12e666badb79e480c4b2399787551f8266d0. - Fix segfault when receiving UDP packets with an unknown source address. - Fix reception of SPTPS UDP packets. - Avoid using OpenSSL's random number functions. - Don't pass uninitialized bytes to ioctl(). - Don't use myself->name in device_disable(), it's already freed. - Fix memory leaks found by Valgrind. - Use void pointers for opaque data blobs in the SPTPS code. - Add a variable offset to vpn_packet_t, drop sptps_packet_t. - Merge remote-tracking branch 'groxxda/gui-fixes' into 1.1 - Allow running tinc without RSA keys. - Update THANKS file. - Check whether res_init() really lives in libresolv. - BSD make doesn't like .PHONY .c files. - We don't depend on ECDH functions from OpenSSL anymore. - Linux doesn't like .PHONY .o files. - Remove AES-GCM support. - Better default paths for log and PID files on Windows. - Add BroadcastSubnet and DeviceStandby options to the manual and completion. - Releasing 1.1pre11. +commit e60405831565062c914fe5498cf3b17b0bd13e8b +Author: Guus Sliepen +Date: Tue Jun 12 20:50:37 2018 +0200 -Sven-Haegar Koch (4): - Fix exit code of "tinc get". - commandline.test: Adding test that fetching non-existing config setting really fails. - Do not disconnect when no ecdsa key is known yet. - Try handling the case when the first side knows the ecdsa key of + Remove the ping test. + + This was kind of a hack. The ns-ping test is a much better test, although + it only works on Linux. -William A. Kennington III (3): - utils: Refactor get_name's functionality into util for global access - utils: Refactor check_id out of protocol for global access - tincctl: Use replace_name to properly replace and validate input hostnames +commit 70e1e467f93f885da3e49289e96757d5cd2ae5ba +Author: volth +Date: Wed Jun 13 18:10:47 2018 +0000 -Baptiste Jonglez (2): - Clarify man page regarding the IndirectData option - Fix typos in the manual page + minor -Alexis Hildebrandt (1): - Add support to link against libresolv Mac OS X +commit 72136f8418bc7e8a0a5bf3c11215aa49dc679659 +Author: volth +Date: Wed Jun 13 14:12:02 2018 +0000 -Armin Fisslthaler (1): - reload /etc/resolv.conf in SIGALRM handler + expose traffic stats to 'tinc info ___' and 'tinc dump nodes' -Franz Pletz (1): - tinc-gui: Use /usr/bin/env to resolve path to python +commit 0f0585d71b28428792e53258bc570dddc17b0b27 +Author: volth +Date: Tue Jun 12 21:17:30 2018 +0000 -Saverio Proto (1): - Fix typo in comment + keep track of round trip times of UDP pings + +commit 6c0584c55b99dd9814fed5c13536d831b3e5317e +Author: Guus Sliepen +Date: Tue Jun 12 20:01:43 2018 +0200 + + Releasing 1.1pre16. + +commit 75271559a9dc2536b9da1c655a012eb837c58761 +Author: Guus Sliepen +Date: Tue Jun 12 19:47:02 2018 +0200 + + Remove the wxPython GUI. + + This GUI is missing a lot of functionality, and won't be part of an 1.1.0 + release. Therefore, it's being removed, and might be brought back after + 1.1.0. + +commit 809ee79b458b0c45d4d60761b1d71171648bdbd5 +Author: Oliver Freyermuth +Date: Wed Apr 4 22:01:52 2018 +0200 + + Fix compiling when support for UML sockets is enabled. + +commit f52e4d07706e6314bb11cf9b553f58210f5dd181 +Author: Guus Sliepen +Date: Mon Apr 2 16:49:06 2018 +0200 + + Reformat all code using astyle. + +commit 7ee885a1f6776be85e5397eda04f75d98ff0b631 +Author: Guus Sliepen +Date: Mon Apr 2 16:33:14 2018 +0200 + + Add the ability to set a firewall mark on sockets. + + The FWMark option is added, when set it will use setsockopt(SOL_SOCKET, SO_MARK) + to set the given value as the mark on all sockets created by tinc. + + Thanks to Olivier Tirat for submitting a similar patch in the past. + +commit d32226bc14428864df08beccb3cf4f8a472f2eef +Author: Guus Sliepen +Date: Mon Apr 2 12:29:46 2018 +0200 + + Fix invitation tests if port 655 is available. + + Running the "del Port" command when no Port is set returns an error. But + it is not necessary anyway since the later "set Port" command will + overwrite it. + +commit 63fbaf7b4a33d5657cd3338b7ea91a173b9973fb +Author: Guus Sliepen +Date: Fri Mar 30 11:50:40 2018 +0200 + + Prevent an infinite loop in get_recent_address(). + + When a node is offline, but we still have edges to it that have the same + address as we already have in our address cache, an infinite loop would + happen in get_recent_address(), because we forgot to advance the pointer + in the list of known addresses, and kept looking at the same one over + and over. + + Thanks to Sven-Haegar Koch for spotting the bug and providing + diagnostics. + +commit 04e498f8b79c1ebfd7080338ffa0399d01862424 +Author: Guus Sliepen +Date: Fri Mar 30 11:38:22 2018 +0200 + + Properly implement tinc.texi's dependency on tincinclude.texi. + + With this, make distcheck succeeds even without the info-in-builddir + option to AM_INIT_AUTOMAKE. + +commit 63a3369cbc41ba68e221da174c28f5f909c2ed8d +Author: Guus Sliepen +Date: Tue Mar 27 22:54:15 2018 +0200 + + Warn if we cannot reload the tincd when creating an invitation. + +commit 2d268fc06bc01419e7f7f32d4da1b560e72e4ad3 +Author: Mike Sullivan +Date: Mon Mar 26 14:19:04 2018 -0500 + + Fix handling partial SPTPS messages in sptps_test. + +commit 69a18395931d657b77641b68ca12473ad6b996da +Author: Guus Sliepen +Date: Tue Mar 6 19:31:17 2018 +0100 + + Ensure we call CloseServiceHandle() in case of errors. + +commit a3f04cf74463e783eeddd45e998c1d15db0f868a +Author: Guus Sliepen +Date: Tue Mar 6 19:24:14 2018 +0100 + + Reformat all code using astyle. + +commit fa305d9570bc7350d04c7de66cfec28b9a2f53d1 +Author: Gjergji +Date: Tue Mar 6 11:10:41 2018 +0100 + + fix service removal. + Windows service was not removed until tincctl exits + +commit 7761a6992025ef06bf8dbf88d39a3bf9e459346a +Author: Guus Sliepen +Date: Wed Feb 28 21:34:48 2018 +0100 + + Fix compatibility with LibreSSL and OpenSSL < 1.1. + + Closes #184 on GitHub. + +commit a742ea4d040ecfaabbc875c63f2625654ce68923 +Author: Guus Sliepen +Date: Wed Feb 28 21:28:16 2018 +0100 + + Try to process all pending events after select(). + + If we break out of the loop every time at the first filedescriptor that + is read/writeable, we risk starving the other filedescriptors. + +commit d6c8a1a3d3e945142b251b2897517e10ce0dfce4 +Author: Todd C. Miller +Date: Tue Feb 27 14:20:46 2018 -0700 + + Call WSAWaitForMultipleEvents() in a loop until we have checked all events. + WSAWaitForMultipleEvents() only returns the index of the first event that is read. We need to call WSAWaitForMultipleEvents() repeatedly to check if other events are also ready. Otherwise, a single busy event (such as the TAP device) can starve the other events. + +commit 7c73cb3ace6659df58ec2382b8d47bb521dad886 +Author: Guus Sliepen +Date: Tue Feb 27 21:08:57 2018 +0100 + + Work around a GCC bug that causes inet_checksum() to give wrong results. + + Valgrind reports the following bug: + + ==24877== Conditional jump or move depends on uninitialised value(s) + ==24877== at 0x12283E: inet_checksum (route.c:80) + ==24877== by 0x12283E: route_ipv6_unreachable (route.c:315) + ==24877== by 0x1236AC: route_ipv6 (route.c:751) + ==24877== by 0x1236AC: route (route.c:1160) + ==24877== by 0x113DE0: receive_tcppacket (net_packet.c:493) + ==24877== by 0x1119D4: receive_meta (meta.c:315) + ==24877== by 0x113288: handle_meta_connection_data (net.c:287) + ==24877== by 0x11A091: handle_meta_io (net_socket.c:491) + ==24877== by 0x10FB0C: event_loop (event.c:370) + ==24877== by 0x11362E: main_loop (net.c:489) + ==24877== by 0x10CACA: main (tincd.c:551) + + Clearing the variable pseudo in route_ipv6_unreachable removes this error, + but the resulting checksum is still bad. If one instead adds a dummy + write that depends on checksum, the error goes away and the checksum is + correct. + +commit d661c7c7353da90911e9f2d0195ac861d6837f5c +Author: Guus Sliepen +Date: Tue Feb 27 19:11:38 2018 +0100 + + Revert "Unconditionally remove timeouts from the queue before calling the callback." + + This reverts commit e8a60109fc91a42420ec626b63956771675f89b0. + +commit e8a60109fc91a42420ec626b63956771675f89b0 +Author: Guus Sliepen +Date: Mon Feb 26 22:19:43 2018 +0100 + + Unconditionally remove timeouts from the queue before calling the callback. + + We are going to unlink the timeout from the splay tree anyway, so do it + unconditionally before the callback, instead of waiting until after the + callback to check whether or not to remove it based on its expiration + time. + +commit 03a94cb3148544230bdd306e905d2ce88c551c12 +Author: Todd C. Miller +Date: Thu Feb 22 14:27:37 2018 -0700 + + In device_handle_read() we need to reset the read event on error or + it will keep firing. This is easy to reproduce by suspending the + machine while tinc is running. + +commit f10e98f5e5a3537b43fbc53f07ab691265de999a +Author: Guus Sliepen +Date: Wed Feb 21 20:34:42 2018 +0100 + + Update the documentation of the control protocol. + +commit 89102b02047d0220766f55ec041c8fc46234cf69 +Author: Todd C. Miller +Date: Tue Feb 20 20:18:38 2018 -0700 + + Fix heap corruption on Windows exposed by the use-after free fix. + reset_address_cache() could call free_known_addresses() on a struct + addrinfo * that was returned by getaddrinfo(). It seems safest to just + make a copy of the addresses returned by getaddrinfo() so we can always + use free_known_addresses() instead of trying to determine whether or + not we need to use freeaddrinfo(). + +commit 8f73169567fed6703acbad4f0f5fd5cff700d619 +Author: Guus Sliepen +Date: Mon Feb 19 20:41:21 2018 +0100 + + Document the control protocol. + +commit ecfef0eeb9b52f6d75b4aa936a1e11e6d8e678e3 +Author: Guus Sliepen +Date: Sun Feb 18 16:51:06 2018 +0100 + + Reduce memory allocations due to HMAC() and EVP_MD_*(). + + HMAC() allocates a temporary buffer on the heap each time it is called. + Similarly, we called EVP_MD_CTX_create() every time we wanted to + calculate a hash. Use HMAC_CTX and EVP_MD_CTX variables to store the + state so no (re)allocations are necessary. HMAC() was called for every + legacy packet sent and received. + + This issue was found thanks to heaptrack. + +commit 6be453fc63da9f87455b5e579cb686f95fa92102 +Author: Guus Sliepen +Date: Sun Feb 18 15:38:12 2018 +0100 + + Reduce memory allocations due to zlib's uncompress(). + + Everytime uncompress() is called, zlib allocates some buffer on the heap + and frees it again. When compression is enabled, this is the biggest source + of memory allocations in tinc. Instead of using this function, use + inflate(), which can store its state in a z_stream variable, which avoids + (re)allocating memory for every packet received. + + This issue was found thanks to heaptrack. + +commit 8f2ef1a174d18a9efdf9b0bd2417132fe7d84e9f +Author: Guus Sliepen +Date: Sun Feb 18 15:33:36 2018 +0100 + + Add code coverage testing support. + + Allows configure to be run with the --enable-code-coverage flag, allowing + one to run make check-code-coverage, which runs the test suite and produces + a code coverage report. + +commit d2b03f006f98d504e3e30f2d4b91ce02abd19c51 +Author: Guus Sliepen +Date: Sat Feb 17 14:39:29 2018 +0100 + + Reformat all code using astyle. + +commit 536fe3ffcdc4c894ed986dfb5fdc0d6f78d6fe25 +Author: Todd C. Miller +Date: Fri Feb 16 14:17:39 2018 -0700 + + Fix a use-after-free bug in get_recent_address() and two related issues. + 1) The sockaddr_t * returned may be part of memory freed by the call to + freeaddrinfo(). + 2) The sockaddr_t * returned from a recently seen address not in the + cache was cast from struct addrinfo *ai, not the struct sockaddr * + inside of it. + 3) In do_outgoing_connection(), when filling in the address in the + connection_t, there is a buffer overflow (read, not write) if + the sa returned by get_recent_address() didn't come from the + cache of recently seen addresses. That is, it was really a + struct sockaddr * and not a sockaddr_t *. This last was + found by building tinc with address sanitizer. + +commit 8145a3392bdcff4d7856ba72e66a90d73d887c00 +Author: Todd C. Miller +Date: Wed Jan 31 14:55:20 2018 -0700 + + In device_issue_read() there is no need to reset Offset and OffsetHigh + to 0; they are only used for seekable files (not sockets). + + Reset the write event before the call to WriteFile(). This is + consistent with how the read event is reset before ReadFile(). + + Clear device_write_packet.len() if WriteFile() fails with an error + other than ERROR_IO_PENDING; otherwise write_packet() will call + GetOverlappedResult() the next time it is run even though there is + no write in progress. + +commit 5ec513ec0ffc735e30c559a03378659ba4cc4515 +Author: Todd C. Miller +Date: Tue Jan 23 15:57:58 2018 -0700 + + WSAEVENT is a pointer, so we cannot simply return the different of two + events in io_compare(), which returns an int. This can return the wrong + result for 64-bit executables. + +commit 92d66492e0824674f68d26e787dd1ba4444a4601 +Author: Todd C. Miller +Date: Mon Jan 22 10:27:16 2018 -0700 + + Add some missing freeaddrinfo() calls to avoid leaking memory. + +commit e0f6d90e7fac4c567900e98c354af979c97f8d59 +Author: Guus Sliepen +Date: Mon Jan 22 18:05:09 2018 +0100 + + Fix calling freeaddrinfo() on the wrong pointer. + + Thanks to Todd C. Miller for finding this issue. + +commit 7bf4d225a994d8ce9fb45d42afd53793c4232e8e +Author: Etienne Dechamps +Date: Wed Jan 17 19:37:53 2018 +0000 + + Move ResetEvent() call before ReadFile(). + + Commit 313a752 changed the Windows device code such that ResetEvent() is + called on the read OVERLAPPED structure before GetOverlappedResult(), as + opposed to before ReadFile(). In [1] Guus pointed out that this doesn't + make a ton of sense, and I agree with him; it must have been an + oversight on my part when I wrote this code. + + Surprisingly, none of this makes any difference in my testing, at least + with the standard TAP 9.0.0.9 driver. Nevertheless, this code is + probably wrong and fixing it will make me sleep better at night. + + [1]: https://www.tinc-vpn.org/pipermail/tinc/2018-January/005091.html + +commit 43cf631bc10097448db041639ad07f84f647017e +Author: Etienne Dechamps +Date: Sun Jan 7 14:48:08 2018 +0000 + + Fix "use of GNU empty initializer extension" warning. + +commit 1b777010e7255cb354e31ca28c6442ee86383bac +Author: Etienne Dechamps +Date: Sun Jan 7 14:44:12 2018 +0000 + + Fix "void function should not return void expression" warning. + +commit ddf798a0ef7df21d682d2f6763d5417400c987ba +Author: Etienne Dechamps +Date: Sun Jan 7 14:26:00 2018 +0000 + + Fix AC_CHECK_DECLS usage in openssl.m4. + + See: + + https://www.gnu.org/software/autoconf/manual/autoconf-2.62/html_node/Generic-Declarations.html + + "For each of the symbols (comma-separated list)" + + When building with aggressive warning settings the current code results + in the following configure test code being generated: + + #ifndef OpenSSL_add_all_algorithms EVP_aes_256_cfb + #ifdef __cplusplus + (void) OpenSSL_add_all_algorithms EVP_aes_256_cfb; + #else + (void) OpenSSL_add_all_algorithms EVP_aes_256_cfb; + #endif + #endif + + Which is obviously wrong and makes the configure check fail. + +commit 04543a57e73e29c3e2a1968fd330f03c94dd6059 +Author: Guus Sliepen +Date: Fri Jan 5 22:49:30 2018 +0100 + + Add a cache of recently seen addresses. + + This maintains a cache file for each host we have communicated with, either + via TCP or UDP. The cache is used when trying to make outgoing connections, + and is updated whenever a successful TCP or UDP connection is established. + Up to 8 addresses are stored in the cache. + + Currently, the cache is stored in /etc/tinc/NETNAME/cache. The directory + has to be manually created to opt in to this feature for now. + +commit ca989c0c8b19901cbd7664a9d2b42aa85c9c176e +Author: Guus Sliepen +Date: Sat Jan 6 20:46:22 2018 +0100 + + Fix all spelling errors found by codespell. + +commit 6989a070c35b9672683ebb0764ab9051e0650469 +Author: Guus Sliepen +Date: Sat Jan 6 20:34:37 2018 +0100 + + Document how to enable tinc at boot time using systemd. + +commit fe9089337093c917d172aa26eedc9285c8bafb6a +Author: Guus Sliepen +Date: Sat Jan 6 16:59:21 2018 +0100 + + Don't include generated files into the tarball. + +commit e56589082f6198380d7f2246a776e41d388496f6 +Author: Guus Sliepen +Date: Sat Jan 6 16:21:19 2018 +0100 + + Update .gitignore. + +commit ee5e3404e49ef08437cd6b6e4c5b83d190efa053 +Author: Guus Sliepen +Date: Sat Jan 6 16:20:25 2018 +0100 + + Ensure the sptps-basic test doesn't fail during make distcheck. + +commit c2d8264dbe8478d27ba694062cebecee0a0342c4 +Author: Guus Sliepen +Date: Sat Jan 6 16:20:03 2018 +0100 + + Set default systemd unit path to ${libdir}/systemd/system. + + This installs systemd unit files into /usr/local, just like the binaries. + The systemd documentation claims to read this directory as well. + +commit c550c85d75ae38b9621147fdca4bf4380d54edda +Author: Guus Sliepen +Date: Sat Jan 6 16:17:35 2018 +0100 + + Remove hardcoded paths from systemd unit files. + + Closes #160 on GitHub. + +commit bdeba3f9c26f9225c17c097ca490dc651cd40b90 +Merge: 696dc2ad 9ca5a3c4 +Author: Guus Sliepen +Date: Fri Jan 5 19:58:28 2018 +0100 + + Merge remote-tracking branch 'dechamps/ipip' into 1.1 + +commit 9ca5a3c43854fba782d87be080d7a97a88ef3427 +Author: Etienne Dechamps +Date: Tue Jan 2 09:55:26 2018 +0000 + + Support MSS clamping for IP in IP (RFC 2003) packets. + + This change allows tinc MSS clamping to operate on TCP streams that are + inside an IP in IP tunnel. + +commit 696dc2ad9743c62e56a6d21addb8c4e8efbffec1 +Author: Guus Sliepen +Date: Fri Jan 5 17:13:57 2018 +0100 + + Add missing newlines to some error messages. + +commit 313b05b67c59c316c0eff631598e0700e0fd3c8d +Author: Guus Sliepen +Date: Fri Jan 5 17:13:25 2018 +0100 + + Document that invitation files MUST always start with Name = ... + +commit 356118324f7cde276f393162fca54040f8c67f04 +Author: Guus Sliepen +Date: Fri Jan 5 17:12:06 2018 +0100 + + Don't warn about empty lines in invitation files. + +commit 50afa82a8f14ead7d4d3eafd2a1347b3bb9a2879 +Author: Guus Sliepen +Date: Mon Dec 18 10:47:40 2017 +0100 + + Document the --batch option. + +commit 0b2361a9399944cd57def87226f2be7f92646aa5 +Author: Guus Sliepen +Date: Sat Dec 16 22:54:31 2017 +0100 + + Assume all IPPROTO_* macros exist. + +commit b8acb89add4e553d141a45392bc0126c331deee6 +Author: Guus Sliepen +Date: Mon Nov 6 22:52:17 2017 +0100 + + Fix building documentation when using OpenBSD's make. + +commit 4986917cb11be70a9103917d58e7aa47ab88f09d +Author: Guus Sliepen +Date: Mon Nov 6 22:49:41 2017 +0100 + + Update THANKS. + +commit 38489e37f50e807e51bfd28ebb8b20396eed1447 +Author: Guus Sliepen +Date: Mon Nov 6 22:44:12 2017 +0100 + + Const correctness. + +commit 61b441dc995c1e6dd21fd85e2014dd981e9c9350 +Author: Guus Sliepen +Date: Mon Nov 6 22:35:28 2017 +0100 + + Support autoconf's --runstatedir option. + + Put the PID file in @runstatedir@ instead of @localstatedir@/run. This + requires autoconf 2.70, which is not released yet, so add a fallback to + use @localstatedir@/run if @runstatedir@ is not set. + +commit 42d2dff33306beae8ddbd9cc991ad80f135950a6 +Author: Guus Sliepen +Date: Mon Nov 6 22:28:32 2017 +0100 + + Ensure all parameters have names in header files. + +commit b34eb5555d40b7e87c1e06988250e4977a793c09 +Author: Guus Sliepen +Date: Mon Nov 6 22:27:57 2017 +0100 + + Remove unused functions. + +commit 6123ed30992d671b94fc016660086be6a62a3871 +Author: Guus Sliepen +Date: Mon Nov 6 21:46:17 2017 +0100 + + Don't log errors when autoconnecting fails and debuglevel is 0. + +commit c84fce52d2191df06e24737449e8983174984ddc +Author: Guus Sliepen +Date: Thu Oct 26 21:33:46 2017 +0200 + + If we are using libncurses, also try to link with libtinfo. + + On some distributions, tinc might not be linked correctly if -ltinfo is + not explicitly specified. + +commit e88b3fb52fb375cd8ab233a671f38ed2240ed828 +Author: Guus Sliepen +Date: Wed Oct 25 21:08:29 2017 +0200 + + Only forward SPTPS packets if Forwarding = internal. + + This tries to match what is done for packets using the legacy protocol. + However, since SPTPS is end-to-end encrypted, Forwarding = kernel cannot + be implemented. In that case, we also drop the packets. + +commit 87f96aec8c48327d879c20ff2b789c88a675173d +Author: Todd C. Miller +Date: Wed Oct 25 10:05:06 2017 -0600 + + Replace remaining sizeof foo with sizeof(foo). + +commit 9e7c6d4dce8b87d40cea537fd0b035a2612580e3 +Author: Guus Sliepen +Date: Mon Oct 23 21:10:20 2017 +0200 + + Disable PMTU discovery when TCPOnly is used. + +commit 7c359313aca273319f94fe18121831ab4b62a4b4 +Author: Guus Sliepen +Date: Wed Oct 11 19:30:17 2017 +0200 + + Add some information about the requirements of a chroot environment. + +commit a0baeddb8aa745007d0302ed06247cabb8facb32 +Author: Guus Sliepen +Date: Sun Oct 8 21:32:12 2017 +0200 + + Ensure "make distcheck" really runs without errors. + +commit f6e87ab476a0faf8b124ecaaa27f967d825e6457 +Author: Guus Sliepen +Date: Sat Oct 7 17:50:22 2017 +0200 + + Reformat all code using astyle. + +commit 3a316823b971396a428f020f401b9fe41252d98d +Author: Guus Sliepen +Date: Sat Oct 7 17:47:19 2017 +0200 + + Convert sizeof foo to sizeof(foo). + + While technically sizeof is an operator and doesn't need the parentheses + around expressions it operates on, except if they are type names, code + formatters don't seem to handle this very well. + +commit 5822f817aa802c2c5a83e9d99a8ae78cb822799b +Author: Guus Sliepen +Date: Sat Oct 7 17:40:34 2017 +0200 + + Update all header guards. + + Don't start with underscores, as those are reserved for system + libraries. Make sure all start with TINC_, and that they appear at + the top of the file. + +commit 3465746b9bf75124b21eab21cdf390696b608405 +Author: Guus Sliepen +Date: Sat Oct 7 16:51:32 2017 +0200 + + Remove unused/obsolete checks from configure.ac. + +commit ced6c3151d6012df560f088d39d306370bb115b7 +Author: Daniel Lublin +Date: Thu Oct 5 09:23:20 2017 +0200 + + doc: there is, not their is + +commit d3cb2a7342218c1aadfacd92d640c426d725112f +Author: Guus Sliepen +Date: Tue Oct 3 21:23:28 2017 +0200 + + Prepare for automatic code formatting using Artistic Style. + +commit e3d914a4d5f5be1c263ec77b9b5c62afb5fc1b78 +Author: Guus Sliepen +Date: Sun Oct 1 22:04:40 2017 +0200 + + Update THANKS. + +commit 453e6070ddfab2157f52536bdd7a79fc16f851f4 +Author: Todd C. Miller +Date: Thu Sep 28 16:39:59 2017 -0600 + + Fix parsing of -b flag + + Only the short -b option is missing, --batch works as expected. + +commit af81c436d6e11a53803747af7cc8ecfd449ccd4c +Author: Guus Sliepen +Date: Sat Sep 2 21:56:17 2017 +0200 + + Releasing 1.1pre15. + +commit 4e5c2193a1fa1ed054956fc0b1df387b19c546a5 +Author: Guus Sliepen +Date: Sat Sep 2 21:55:47 2017 +0200 + + Drop h and hh length modifiers from printf format strings. + +commit 91d50f8b375503be6b6081985f5948773d64b9d3 +Author: Guus Sliepen +Date: Sat Sep 2 21:54:34 2017 +0200 + + Ensure packet priority is cleared when sending PMTU probe replies. + + Found by the Clang static analyzer. + +commit 00d81ee6236e76f80b84372ac5c635636ad48136 +Author: Guus Sliepen +Date: Sat Sep 2 21:52:44 2017 +0200 + + Fix a file descriptor leak when using an invitation. + + Found by cppcheck. + +commit a073b2cb0bca646685a83479db6b66d518240bc5 +Author: Guus Sliepen +Date: Sat Sep 2 21:06:25 2017 +0200 + + Fix a compiler warning. + +commit 843990d8df0c060db9b64e170996e9d49c8c921d +Author: Guus Sliepen +Date: Sat Sep 2 17:24:05 2017 +0200 + + Force IPv4 for sptps-basic.test. + + Allow forcing either IPv4 or IPv6 for sptps_test, and use IPv4 for the + sptps-basic test. Since sptps_test is only opening a single listening + socket, and you cannot control which address family it uses, this gets + around a problem where the listening side is using a different address + family than the one connecting to it. + +commit 5f89950f47a9cf73169e797d4e2d6ef8b7f74a5a +Author: Guus Sliepen +Date: Sat Sep 2 17:04:25 2017 +0200 + + Add missing break statements. + +commit 92fdabc439bdb5e16f64a4bf2ed1deda54f7c544 +Author: Guus Sliepen +Date: Tue Aug 22 20:51:44 2017 +0200 + + Make autoconnect try to heal network splits. + + When we have less than three connections, we greedily try to connect to any + viable node. However, once we have three connections, try to connect to + nodes that we know of but that aren't reachable. + + We also make sure that if there are 100 reachable nodes, and 1 unreachable + one, that not all 100 reachable nodes try to connect to the unreachable + at the same time. + +commit 7c223917cb3d478fc3f5b23ee5602925f083e4d4 +Author: pacien +Date: Tue Aug 15 19:56:06 2017 +0200 + + Add LogLevel config option + +commit e4544dbc6989e4a146c19519924e52c116bfc343 +Author: Guus Sliepen +Date: Thu Jul 27 10:06:13 2017 +0200 + + Forward-port tinc 1.0's handling of device errors. + +commit d73cdee5df3e6c7395270c69e944b3c853f013ae +Author: volth +Date: Thu Jul 27 06:32:28 2017 +0000 + + Avoid infinite loop on EBADFD + + On Linux network restart, Tinc can get into a loop writing millions of error messages "Error while reading from Linux tun/tap device (tun mode) /dev/net/tun: File descriptor in bad state" to the log. https://github.com/NixOS/nixpkgs/pull/27675 + + It should be somehow aborted. + Here is my quick hack. + +commit acefa66dbd97617d86dee270b2b95ecdb763434b +Author: Guus Sliepen +Date: Sun Jul 9 16:12:55 2017 +0200 + + Store the invitation data after a succesful join. + + This can be used by the invitee to examine the file after a join, and + process it in different ways than the tinc CLI does. + +commit cd854fa86a9dc177dcaa56fa774afb127b29651a +Author: Guus Sliepen +Date: Sun Jul 9 15:57:51 2017 +0200 + + Add configurable experation time for invitations. + +commit 93584bc1cad7c7cc9c95859a8cde548bc18b6fa8 +Author: Guus Sliepen +Date: Sun May 28 12:48:32 2017 +0200 + + Set KillMode=mixed in the systemd service file. + + This ensures only the main process is sent the SIGTERM, and not anything + else that might have started in the same control group, including the + tinc-down script. + + Closes #145 on GitHub. + +commit 970799aa3406c22a575f665d3964c15d7c9ab555 +Author: Guus Sliepen +Date: Sun May 28 12:26:44 2017 +0200 + + Move logging of "would block" messages to debug level 4. + +commit 3d8a8363544bfcf75a9124251eff0caae3a8f1a2 +Author: Guus Sliepen +Date: Sun May 7 15:29:22 2017 +0200 + + Remove unused add_scalar function. + +commit 958a751e20270da821fee651ff9ecda8a2afc5d0 +Author: thorkill +Date: Thu May 4 23:44:56 2017 +0200 + + Fix NULL pointer dereference in send_udp_info + +commit 9527f4f22cd71feeee8a49866e29cce98408f1e7 +Author: thorkill +Date: Mon May 1 12:40:22 2017 +0200 + + Sanitize input in id_h - prevent integer overflows + +commit 18646deca120f0ccc3bfad643dba83547ecc2f20 +Author: Guus Sliepen +Date: Tue Apr 18 20:09:38 2017 +0200 + + Fix some minor issues found by cppcheck. + +commit 060ab1cd7cdf750a0477f2a8b6193d28849877e8 +Author: Guus Sliepen +Date: Tue Apr 18 20:09:08 2017 +0200 + + Add field widths to sscanf() calls. + + Found by cppcheck. + +commit be8e5cbd1cfcd198f975542e52085abdd543ec80 +Author: Guus Sliepen +Date: Tue Apr 18 20:07:33 2017 +0200 + + Remove dead stores. + + Found by the Clang static analyzer. + +commit 70fed5f7ffdeb0416ee6b77881098faab9a7cd47 +Author: Guus Sliepen +Date: Mon Apr 17 16:05:30 2017 +0200 + + Add missing tinc stop command to the scripts test. + +commit a14414731925cd59e64b3a90309b5a9ec60ac690 +Author: Guus Sliepen +Date: Mon Apr 17 13:54:02 2017 +0200 + + Fix tests on *BSD. + +commit db80dbbac93ce3c714247e0af2147f5e1474a135 +Author: Guus Sliepen +Date: Mon Apr 17 13:53:48 2017 +0200 + + Fix segfault when adding environment variables. + +commit 1be0c284c7c8d34c2dd6c2160ce49aeae468e867 +Author: Guus Sliepen +Date: Mon Apr 17 13:07:15 2017 +0200 + + Fix compiler warnings on *BSD. + +commit 2b4c0c63628ff9b432ec5d4b4c7b7ab2d4b02fb2 +Author: Guus Sliepen +Date: Mon Apr 17 13:02:39 2017 +0200 + + Make sure realname is always initialized. + +commit c87a77b5fd2a0378f2b992a5d579a80ee4033cec +Author: Guus Sliepen +Date: Mon Apr 17 12:50:30 2017 +0200 + + Ensure tests compile on *BSD. + +commit 95f09569beb2e304e6a2112d20cee6fab88f3729 +Author: Guus Sliepen +Date: Sat Apr 8 13:34:40 2017 +0200 + + Use getmsg()/putmsg() instead of read()/write() on Solaris. + + This fixes a problem where read() returns packets from the IP layer before + fragmentation is done. + + # Conflicts: + # src/solaris/device.c + +commit 6011197be5cdb18aa79713990d6a1887b9261d12 +Author: Guus Sliepen +Date: Sat Apr 8 13:31:04 2017 +0200 + + Use /dev/udp instead of /dev/ip on Solaris. + + # Conflicts: + # src/solaris/device.c + +commit 9a113db0a61242a0273a7ac95dd536f3a4bdb581 +Author: Guus Sliepen +Date: Wed Mar 29 08:08:56 2017 +0200 + + Ensure sptps_keypair and sptps_test get build for make check. + +commit d9a7f2d1054a7155b5f23855ba28dd98e0df73be +Author: Guus Sliepen +Date: Wed Mar 29 08:08:19 2017 +0200 + + Use 127.0.0.1 instead of localhost to ensure tests are reproducible. + +commit 3ab1893a4b6c2895075ac889cf06c511e2001a9e +Author: Guus Sliepen +Date: Sun Mar 26 17:54:37 2017 +0200 + + Ensure proper logging in the invite-offline test. + +commit 0af3dcf7a838dede699194c02444f1607644bb28 +Author: Guus Sliepen +Date: Sun Mar 26 17:43:33 2017 +0200 + + Add the scripts test. + + This test whether all the scripts are run with the right information in + the right order. + +commit ebade1e8f80ebaa476f701089da7ae654837397c +Author: Guus Sliepen +Date: Sun Mar 26 16:48:02 2017 +0200 + + Update .gitignore. + +commit fd3ec60757a84b7551e03b3a48dd30f35015c448 +Author: Guus Sliepen +Date: Sun Mar 26 16:47:54 2017 +0200 + + Add the invite-offline test. + + This tests generating an invitation on the server while no tinc daemon is + running. + +commit 5fcf6e16acccdaac573eebae21a5a47294e346e4 +Author: Guus Sliepen +Date: Sun Mar 26 16:46:31 2017 +0200 + + Remove superfluous sleep command in invite-join test. + +commit ccb4fb6f7ac2efbb99d044aa072e75c035f504aa +Author: Guus Sliepen +Date: Sun Mar 26 16:46:03 2017 +0200 + + Use unique ports for all tests. + +commit add75303e918af5e94ff545d969872799fac5cef +Author: Guus Sliepen +Date: Tue Mar 21 21:25:27 2017 +0100 + + Add DEBUG environment variable for scripts. + + This contains the current debug level used by tinc. Scripts can use it + to decide whether to log debugging information of their own. + + Closes #138 on GitHub. + +commit 5cbef906209eb5005f821af8f55a6f5d7e7d060c +Author: Guus Sliepen +Date: Tue Mar 21 21:21:23 2017 +0100 + + Put script environment creation/deletion in functions. + + This makes environment handling safer, and also has a single place where + we can add new environment variables that should be present for all + scripts. + +commit 3e643d5d7e5c7db35eacb3703d497c584e93cf18 +Author: Vittorio Gambaletta (VittGam) +Date: Wed Oct 12 13:52:17 2016 +0200 + + route: Support ToS/DiffServ priority inheritance when routing IPv6 packets. + + Signed-off-by: Vittorio Gambaletta + +commit aebaaa8db80ec3931346af710f2182d129c74c41 +Merge: 2c333f0f d21d97ea +Author: Guus Sliepen +Date: Mon Mar 20 22:33:18 2017 +0100 + + Merge remote-tracking branch 'dechamps/sleep' into 1.1 + +commit 2c333f0f45f445d0811a364817d03df0c8cf2d2f +Author: Guus Sliepen +Date: Mon Mar 20 22:19:36 2017 +0100 + + Don't try to use kill() on Windows. + +commit 26dc50599d6e38be1e7304602ffea0ba282c1091 +Author: Guus Sliepen +Date: Mon Mar 20 22:15:20 2017 +0100 + + Add missing #defines used by fd_device.c. + +commit 3fc678a8df4d6c057ef9f2c602b86ed106651e68 +Author: Guus Sliepen +Date: Tue Mar 7 19:19:19 2017 +0100 + + Use free_known_addresses() to free memory allocated by get_known_addresses(). + + We know what struct addrinfo looks like, but the standard says nothing + about how it is allocated. So we cannot trust freeaddrinfo() to work + correctly on the struct addrinfo list we allocated ourselves in + get_known_addresses(). To make a distinction by allocations from the + latter and from str2addrinfo(), we keep two pointers (*ai and *kai) in + struct outgoing, and use the freeing function that is appropriate for + each. + +commit ef661316f163f2ecf6c75a3dd28e2cad51772c56 +Author: Roman Savelyev +Date: Tue Mar 7 19:07:19 2017 +0100 + + Fix lost pointer trails in get_known_addresses(). + +commit 7a54fe5e884e98ade91af527c67f9c5df1452a50 +Author: Pacien TRAN-GIRARD +Date: Mon Feb 27 20:56:55 2017 +0100 + + Add fd_device + +commit 4a45a65fe2555efc5b6763a293d30251755e78a8 +Author: Guus Sliepen +Date: Tue Feb 14 20:51:43 2017 +0100 + + Remove the description of the LocalDiscoveryAddress option from the manual. + + This option is no longer implemented. + +commit d3cc96b027a919e22bbf06d634edb0a2a069ac92 +Author: Guus Sliepen +Date: Tue Jan 31 12:05:03 2017 +0100 + + Don't build sptps_* binaries by default. + +commit 88d158e15b9e16b4227b374d8bb4640010670cef +Author: Guus Sliepen +Date: Tue Jan 31 12:03:27 2017 +0100 + + Fix potential segfault in the replacement vasprintf() function. + +commit 06b820133285f83f7e1a839cccbed13358b84081 +Author: Etienne Dechamps +Date: Sun Dec 18 14:53:33 2016 +0000 + + Fix address memory leaks in add_edge_h(). + + Note that this is not as bad as it looks, because in practice + sockaddrfree() is a no-op for typical address types. + +commit 02093b12b0133b51dd04613c94c762ad2761cd3c +Author: Etienne Dechamps +Date: Sun Dec 18 14:32:25 2016 +0000 + + Clarify the flow of add_edge_h(). + + This is an attempt at making the control flow through this function + easier to understand by rearranging branches and cutting back on + indentation levels. + + This is a pure refactoring; there is no change in behavior. + +commit 3bf3d7d3e7d51034bda873861c52578f3abe6b5d +Author: Etienne Dechamps +Date: Sun Dec 18 14:25:20 2016 +0000 + + Fix edge updates containing local address changes. + + This commit fixes a logic bug in the edge update code where local + address changes are not taken into account if they are bundled in with + other changes. This bug breaks local discovery in some scenarios. + + The regression was introduced by commit + e4670fc4a0576eb76f1807ce29fa9455dd247632. + +commit 0792a10a5a66bcbf56185e479feed78252122667 +Author: Etienne Dechamps +Date: Sun Dec 18 16:56:27 2016 +0000 + + Fix edge local addresses not being set when connections are established. + + This bug prevented nodes from advertising their local addresses, thus + breaking local discovery. + + The regression was introduced in + ab13c14a1480561bb9f59ccfbbd6045e0484ce9c. + +commit d21d97eaf5db9e848d8eee28784c4f54af85f43d +Author: Etienne Dechamps +Date: Sat Dec 3 23:13:46 2016 +0000 + + On Windows, don't cancel I/O when disabling the device. + + I have observed cases where disable_device() can get stuck on the + GetOverlappedResult() call, especially when the computer is waking up + from sleep. This is problematic when combined with DeviceStandby=yes: + + other_side (1.2.3.4 port 655) didn't respond to PING in 5 seconds + Closing connection with other_side (1.2.3.4 port 655) + Disabling Windows tap device + + + gdb reveals the following stack trace: + + #0 0x77c7dd3c in ?? () + #1 0x7482aad0 in KERNELBASE!GetOverlappedResult () from C:\WINDOWS\SysWoW64\KernelBase.dll + #2 0x0043c343 in disable_device () at mingw/device.c:244 + #3 0x0040fcee in device_disable () at net_setup.c:759 + #4 0x00405bb5 in check_reachability () at graph.c:292 + #5 0x00405be2 in graph () at graph.c:301 + #6 0x004088db in terminate_connection (c=0x4dea5c0, report=true) at net.c:108 + #7 0x00408aed in timeout_handler (data=0x5af0c0 ) at net.c:168 + #8 0x00403af8 in get_time_remaining (diff=0x2a8fd64) at event.c:239 + #9 0x00403b6c in event_loop () at event.c:303 + #10 0x00409904 in main_loop () at net.c:461 + #11 0x00424a95 in main2 (argc=6, argv=0x2b42a60) at tincd.c:489 + #12 0x00424788 in main (argc=6, argv=0x2b42a60) at tincd.c:416 + + This is with TAP-Win32 9.0.0.9. I suspect driver bugs related to sleep. + In any case, this commit fixes the issue by cancelling I/O only when the + entire tinc process is being gracefully shut down, as opposed to every + time the device is disabled. Thankfully, the driver seems to be + perfectly fine with this code issuing TAP_IOCTL_SET_MEDIA_STATUS ioctls + while there are I/O operations inflight. + +commit 1672dbd66b619f84cb86950298ad89df93e1dcba +Author: Etienne Dechamps +Date: Sat Dec 3 22:52:30 2016 +0000 + + Fix crash on Windows when a socket is available for both write and read. + + Currently, if both write and read events fire at the same time on a + socket, the Windows-specific event loop will call both the write and + read callbacks, in that order. Problem is, the write callback could have + deleted the io handle, which makes the next call to the write callback a + use-after-free typically resulting in a hard crash. + + In practice, this issue is triggered quite easily by putting the + computer to sleep, which basically freezes the tinc process. When the + computer wakes up and the process resumes, all TCP connections are + suddenly gone; as a result, the following sequence of events might + appear in the logs: + + Metadata socket read error for node1 (1.2.3.4 port 655): (10054) An existing connection was forcibly closed by the remote host. + Closing connection with node1 (1.2.3.4 port 655) + Sending DEL_EDGE to everyone (BROADCAST): 13 4bf6 mynode node1 + Sending 43 bytes of metadata to node2 (5.6.7.8 port 655) + Could not send 10891 bytes of data to node2 (5.6.7.8 port 655): (10054) An existing connection was forcibly closed by the remote host.a + Closing connection with node2 (5.6.7.8 port 655) + + + In this example the crash occurs because the socket to node2 was + signaled for reading *in addition* to writing, but since the connection + was terminated, the attempt to call the read callback crashed the + process. + + This commit fixes the problem by not even attempting to fire the write + callback when the write event on the socket is signaled - instead, we + just rely on the part of the event loop that simulates level-triggered + write events. Arguably that's even cleaner and faster, because the code + being removed was technically redundant - we have to go through that + write check loop anyway. + +commit 979acc48aded5bb04f1574128d174d56550be302 +Author: Guus Sliepen +Date: Sun Oct 30 15:19:12 2016 +0100 + + Enforce maximum amount of bytes sent/received on meta-connections. + + This is 2^{block_length_in_bits / 2 - 1}. + +commit edc1efed3c0cf5aebb1c765066c0413757229a31 +Author: Guus Sliepen +Date: Sun Oct 30 15:17:52 2016 +0100 + + Use AES256 and SHA256 by default for the legacy protocol. + + At the start of the decade, there were still distributions that shipped + with versions of OpenSSL that did not support these algorithms. By now + everyone should support them. The old defaults were Blowfish and SHA1, + both of which are not considered secure anymore. + + The meta-protocol now always uses AES in CFB mode, but the key length + will adapt to the one specified by the Cipher option. The digest for the + meta-protocol is hardcoded to SHA256. + +commit fcaf158494af7cb015d8658a3241c324518e8d7f +Author: Dennis Lan +Date: Wed Oct 12 13:35:39 2016 +0200 + + Fix typo in src/upnp.c. + +commit 9cbd3c2b5b03c29c116a14f196db8a32c7135391 +Author: Vittorio G (VittGam) +Date: Tue Oct 11 20:30:41 2016 +0200 + + tincctl: Avoid falling back to 1024 bits RSA key generation when an invalid key size is specified. + + Also warn the user if a key smaller than 2048 bits is being generated. + + Signed-off-by: Vittorio Gambaletta + +commit c7c5c74d4af7442b92d863fc9eb04395c456b0be +Author: Vittorio G (VittGam) +Date: Tue Oct 11 13:30:05 2016 +0200 + + fsck: Fix ed25519 public key reading, and fclose usage. + + Signed-off-by: Vittorio Gambaletta + +commit e6497a23f7689663aa2c19311a278e20661bddc1 +Author: Guus Sliepen +Date: Tue Jul 26 16:47:45 2016 +0200 + + Log warnings about dropped packets only with debug level 5 or higher. + +commit 2784a171ec39e2a34aabf8194a651de570e19e0e +Author: Etienne Dechamps +Date: Thu Jul 14 19:15:35 2016 +0100 + + Fix error handling when setting up the UDP socket. + + Due to this typo, if tinc managed to set up the TCP socket but not the + UDP socket, it would continue anyway. + + The regression was introduced in + 6bc5d626a8726fc23365ee705761a3c666a08ad4. + +commit b1c29464b68d756035acc4b4d1681f05d8831eaf +Author: Guus Sliepen +Date: Fri Jun 24 11:22:24 2016 +0200 + + Fix compiling with OpenSSL < 1.1.0. + +commit 9a9f6fac009caf31c3786e13231eb05b3bad0681 +Author: Guus Sliepen +Date: Fri Jun 24 11:22:11 2016 +0200 + + Add missing m4 files. + + ax_cflags_warn_all.m4 depends on them. + +commit b9b0defaf422bcc1272f87d791d9ac53c9539734 +Author: Guus Sliepen +Date: Thu Jun 23 15:59:43 2016 +0200 + + Fix potential memory leaks found by the Clang static analyzer. + +commit 49edf9c53a31714b740d0ee67c29aca503973d81 +Author: Guus Sliepen +Date: Thu Jun 23 15:59:16 2016 +0200 + + Fix warnings from the Clang static analyzer. + + These are all false positives or harmless dead stores. + +commit e16ab7b89948c24a2c47652e8eb1a817a4b1424c +Author: Guus Sliepen +Date: Thu Jun 23 15:26:58 2016 +0200 + + Force nul-termination of strings after vsnprintf(). + + Apparently, on Windows this function might not always be properly + terminated. + +commit 2de5d866b5e4d4e6b827dcfb985c24edbda71f4f +Author: Guus Sliepen +Date: Wed Jun 22 23:08:30 2016 +0200 + + Use EVP_MD_CTX_destroy() instead of _free(). + + Thanks to azrdev for pointing out the build failure on Fedora 23. + +commit 9b148fd844587fbf956e28f57e4bd39a11edc07f +Author: Guus Sliepen +Date: Wed Jun 22 17:42:25 2016 +0200 + + Check return value of RSA_generate_key_ex(). + +commit 172763f4af4340ac2c2549e8fbb7490f5f995d47 +Author: Guus Sliepen +Date: Wed Jun 22 17:35:12 2016 +0200 + + Add -Wall to CFLAGS. + +commit 323c17e232539f3f06e7cebc664ab48f60127e0e +Author: Guus Sliepen +Date: Wed Jun 22 16:32:05 2016 +0200 + + Ensure compatibility with OpenSSL 1.1.0. + +commit 74eb4cc974f6d24370f439a1761dc4412d7fa58d +Author: Guus Sliepen +Date: Sun Jun 5 15:20:57 2016 +0200 + + Fix the previous commit. + +commit ab13c14a1480561bb9f59ccfbbd6045e0484ce9c +Author: Guus Sliepen +Date: Sun Jun 5 14:47:21 2016 +0200 + + Preserve IPv6 scope_id in edges. + + When creating an edge after authenticating a peer, we copy the + address used for the TCP connection, but change the port to that used + for UDP. But the way we did it discarded the scope_id for IPv6 + addresses. This prevented UDP communication from working correctly when + connecting to a peer on the same LAN using an IPv6 link-local address. + + Thanks to Rafał Leśniak for pointing out this issue. + +commit e47fe48aed76bfd7d2cb957e402a8cdcb0c84759 +Author: Sean McVeigh +Date: Sat May 21 17:38:14 2016 -0400 + + fix check in cmd_pid() for failure to connect to tincd + +commit 4314df644e22778a554ca1760941a2bfae08bce2 +Author: Sean McVeigh +Date: Sat May 21 17:25:18 2016 -0400 + + check for daemon pid existence before trying to connect to the control socket, and clean up stale files otherwise. + +commit 9d0e86683cdb7d53263569ad2e49dd87bd217939 +Author: lemoer +Date: Thu May 19 17:24:31 2016 +0200 + + Added comments and unfold deep "if"-construct in timeout_handler + +commit 5baecfd11be67bb80aab6c482e0b0ac98b267cca +Author: thorkill +Date: Thu May 19 15:48:15 2016 +0200 + + Prevent tincd from sending packets to unexpecting nodes + + Make tincd recognize when it was asleep and close connections to it's + peers. This happens when e.g. RoadWarrior has been suspended for + "longer" time period. After resume, it will start to communicate + with it's peers using the contextes it had before suspend. + + On the other side, the nodes closed the connections since PingTimeout + and/or TCP connection went down. + + Sending data to such unaware (sptps mostly) nodes will cause + havoc in the logs. Misleading the developers to wrong assumptions + that something is wrong with sptps. + + # Conflicts: + # src/net.c + +commit 0cf943753ab16704c818bebe74b4e7ea96399b05 +Author: thorkill +Date: Wed May 11 19:27:05 2016 +0200 + + Send PKT_PROBE only when handshake has been done already. + +commit 0edef996a6d944e9143f87dd3c72390979c33630 +Author: Guus Sliepen +Date: Sun May 1 20:35:26 2016 +0200 + + Releasing 1.1pre14. + +commit 3f6c663a06aac728912c4e47cbc2dc4343a3798c +Author: Guus Sliepen +Date: Sun May 1 12:07:44 2016 +0200 + + Revert "Remove tinc.service, it is not necessary." + + This reverts commit 0b6f84f96eeed20a0d771fedb72c0e19941adb7e. Although + systemd does automatically provide a "tinc.slice" when there is only a + tinc@.service template, it doesn't quite work the same way as + tinc.service. + +commit 0a6d89acc6417399dcf95efd68553d21e1f744e3 +Author: Guus Sliepen +Date: Sat Apr 30 20:55:12 2016 +0200 + + Releasing 1.1pre13. + +commit 2055c3e21d5b3f4217883d52d5e5b0fbad504785 +Author: Guus Sliepen +Date: Sat Apr 30 20:05:22 2016 +0200 + + AutoConnect now only chooses from nodes for which we know an address. + + Based partially on work from Rafał Leśniak. + +commit 0b6f84f96eeed20a0d771fedb72c0e19941adb7e +Author: Guus Sliepen +Date: Sat Apr 30 18:08:31 2016 +0200 + + Remove tinc.service, it is not necessary. + + Thanks to Alexander Ried for pointing out that if you have + tinc@.service template, systemd will provide a default slice containing + all instances of that template. So "systemctl start tinc" will still do + what we want it to do. + +commit 8377d0b8569b8d5240ad88683ad527c67237617a +Author: Guus Sliepen +Date: Wed Apr 27 20:30:36 2016 +0200 + + Fix BSD tun device support. + + This was broken by a botched merge from the master branch in commit d7f6737. + +commit 390d25f0b80dd7418e147de3561c70461628574d +Author: Guus Sliepen +Date: Sun Apr 24 13:23:06 2016 +0200 + + Releasing 1.1pre12. + +commit 5a7c6546a46bdcc97cf73a9aef206d2a83bb1eb4 +Author: Guus Sliepen +Date: Sat Apr 23 21:39:53 2016 +0200 + + Don't check file permissions on Windows during fsck. + +commit 83fa44ce42c67837dad30ba1538bf1fa8c49a47d +Author: Guus Sliepen +Date: Sat Apr 23 21:32:42 2016 +0200 + + Fix starting tinc as a service on Windows. + + Don't assume tincd.exe is in the working directory, especially now that + chdir() is called very early. We use GetModuleFileName() instead. + +commit 9a66d7499ae2c838c25f9c6bfcc277c3fa231dea +Author: Guus Sliepen +Date: Sat Apr 23 21:32:29 2016 +0200 + + Fix a compiler warning on Windows. + +commit ab5f4cbdc65cbc55062b36a6c11482c217884fe8 +Author: Guus Sliepen +Date: Sat Apr 23 17:28:30 2016 +0200 + + Fix possible read of freed memory when verifying the signature of a file. + +commit 76955a6c8b7a76d00ed401853c9d283e32d9ce1c +Author: Guus Sliepen +Date: Sat Apr 23 17:20:08 2016 +0200 + + Have "tinc fsck" recognize Ed25519PublicKey statements. + +commit 6805b157312c1f9adeee0035f540f4cbd63a79fd +Author: Guus Sliepen +Date: Sat Apr 23 16:05:41 2016 +0200 + + Move documentation of invitations to the manual. + +commit 51a0dc51451897cc0290d5040e42616dda9bdc8a +Author: Guus Sliepen +Date: Sun Apr 17 18:11:04 2016 +0200 + + Fix the "network" command in tinc shell. + +commit b6b302cee9de92d157f73d7739cc259d269c0ca0 +Author: Guus Sliepen +Date: Sun Apr 17 17:06:11 2016 +0200 + + Speed up AutoConnect at startup. + + Call periodic_handler() immediately at startup. Also, don't try to + connect to ourself. + +commit f934417aa658367587dadc81bd5c466baef407ef +Author: Guus Sliepen +Date: Sun Apr 17 16:23:31 2016 +0200 + + Don't call terminate_connection(myself->connection). + + It doesn't do anything except give a confusing error message that we are + closing the connection to ourself. Replace it with connection_del(). + This also fixes a double free. + +commit 2213ecaea550ce81c595464ad4347414bcb5d786 +Author: Guus Sliepen +Date: Sun Apr 17 16:01:49 2016 +0200 + + Handle special characters in sptps_test only if the --special option is given. + + sptps_test treats lines starting with #, ^ and $ specially, in order to + test the SPTPS protocol. However, this should only be done if explicitly + requested, otherwise it can unexpectedly fail. + +commit c2dc3784f127ef6db6e9960a4abecc1aab6f4e31 +Author: Guus Sliepen +Date: Sun Apr 17 14:38:37 2016 +0200 + + Add stricter checks for netnames. + + When passing a NetName via an invitation, we don't allow any characters + that are unsafe (either because they could cause shells to expand things, + or because they are not allowed on some filesystems). + + Also, warn when tinc is started with unsafe netnames. + +commit 097c69fc6a223213302fe9ffbe00a4c05357e660 +Author: Guus Sliepen +Date: Sun Apr 17 14:36:29 2016 +0200 + + Use ifconfig_header(). + +commit af9ee7ff003fb448b783ccf39347907adc239cb2 +Author: Guus Sliepen +Date: Sun Apr 17 14:04:57 2016 +0200 + + Chdir() to the configuration directory instead of /. + +commit 9bd978cc8ebf2fd9075f2be646fafd90128d403f +Author: Guus Sliepen +Date: Sun Apr 17 13:56:37 2016 +0200 + + Add a test for tinc-up creation from invitations. + +commit 0b96b6967256803c739a6b0a89d54ab8d6f63335 +Author: Guus Sliepen +Date: Sun Apr 17 13:55:36 2016 +0200 + + Fix compiler warnings. + +commit a08860ff8c2ad859836ed51c5629d6a85343e802 +Author: Guus Sliepen +Date: Sun Apr 17 13:55:18 2016 +0200 + + Fix gateway parsing in invitation files. + +commit 6d0452896673c36226c24144d4bde824a49c3950 +Author: Guus Sliepen +Date: Sun Apr 17 13:23:01 2016 +0200 + + Allow gateways to be specified for routes. + + Also improve the variable names, and ensure the % symbols in + %INTERFACE% are properly quoted. + +commit 03878f12150cbdb1aeb43e207404a0929a35ff13 +Author: Guus Sliepen +Date: Sun Apr 17 01:13:56 2016 +0200 + + Move some stray #includes. + +commit 3273e3254107a4b89cd9963012d5fac8927c417c +Author: Guus Sliepen +Date: Sun Apr 17 01:13:27 2016 +0200 + + Generate a tinc-up script from an invitation. + + This adds the ability for an invitation to provision an invitee with a + tinc-up script. This is quite strictly controlled; only address configuration + and routes are supported by adding "Ifconfig" and "Route" statements to + the invitation file. The "tinc join" command will generate a tinc-up script + from those statements, and will ask before enabling the tinc-up script. + +commit b2200f216658e07ab4e45592fa7de012a2ed96df +Author: Guus Sliepen +Date: Sat Apr 16 22:06:47 2016 +0200 + + Document how invitation files work. + + This should eventually be merged in to tinc.texi. + +commit a31e1f03c4eff16403178695d971a0838996ba2e +Author: Guus Sliepen +Date: Fri Apr 15 16:56:56 2016 +0200 + + Stop using SOL_TCP, SOL_IP and SOL_IPV6. + + Instead, use IPPROTO_TCP, _IP and _IPv6. This fixes an issue on OS X where + it didn't create an UDP socket that listened on IPv4. + +commit a0a8f8f81fc8da068e93088c7c13f689a96fac66 +Author: Guus Sliepen +Date: Fri Apr 15 16:30:45 2016 +0200 + + Fix crash at startup when Device is not specified on OS X. + +commit 8afb52a39a72805cd24b6979248135e0d8b17c32 +Author: Guus Sliepen +Date: Fri Apr 15 14:27:52 2016 +0200 + + Fix conditional checking of tun/tap headers on DragonFly BSD. + +commit 039d6d48afe00a0fa9e11bcdbfea8e996cce4ad0 +Author: Guus Sliepen +Date: Fri Apr 15 12:42:30 2016 +0200 + + Fix some compiler warnings from MinGW. + +commit 1f5c26102e228420fd954af1d73d3a89fc700d9d +Author: Guus Sliepen +Date: Fri Apr 15 12:30:01 2016 +0200 + + Fix generation of version_git.h for some versions of BSD make. + + In order to support VPATH builds, we have to use ${srcdir}/version.c as + the target for the rule that depends on the generation of version_git.h. + When not doing a VPATH build, ${srcdir} expands to ".", so the target + will be "./version.c". However, on some BSDs, make does not understand + that "./version.c" is the same as "version.c", and therefore it doesn't + trigger generating version_git.h when trying to build version.o. (It + works fine if you do a VPATH build, and OpenBSD's make does the right + thing in all cases.) + + The trick is to have version.c depend on ${srcdir}/version.c. Of course, + Linux's make knows this is nonsense and will complain about a circular + dependency, so add this rule only on BSD platforms. + +commit 0037ec7cb38994dda6ab5e4fa85ce595b9a59f6b +Author: Guus Sliepen +Date: Fri Apr 15 12:29:31 2016 +0200 + + Fix a non-working cast to get rid of a compiler warning. + +commit 25bcdad878eb7349d19ea877fdcc058d4c6b2242 +Author: Guus Sliepen +Date: Fri Apr 15 11:38:56 2016 +0200 + + Don't use HAVE_SYSTEM, the autoconf check was removed. + +commit cd5f222cc4e769395a7c6c8646abefe1d657f844 +Author: Guus Sliepen +Date: Fri Apr 15 11:25:18 2016 +0200 + + Remove use of strcpy() and sprintf(). + + Even though they were safe, compilers like to warn about them nowadays. + +commit d4410d0cce40929db9a0ce7042ef962f1867234d +Author: Guus Sliepen +Date: Fri Apr 15 11:10:50 2016 +0200 + + Don't assume sa.sa_family is a short int. + + Because FreeBSD's compiler complained about it. + +commit d704a89ecc0811eb0cdac4e4be8ff3bdb0838976 +Author: Guus Sliepen +Date: Fri Apr 15 11:00:14 2016 +0200 + + Add version_git.h and sample-config.tar.gz to CLEANFILES. + +commit 3cceae93f61a44d4f9f38d729555b2f31e209beb +Author: Guus Sliepen +Date: Thu Apr 14 23:51:18 2016 +0200 + + Make some platform-specific header checks conditional. + + Don't check for linux/if_tun.h on BSD platforms for example. + +commit d10834e92015f1e0e5bf74e03b161b3a5dc363fb +Author: Guus Sliepen +Date: Thu Apr 14 23:24:22 2016 +0200 + + Remove support for Windows 2000 and anything that doesn't support getaddrinfo(). + +commit 615ecb7a8a6e0ffc8d37f08fe46d5c50cef8b3e0 +Author: Guus Sliepen +Date: Thu Apr 14 23:10:59 2016 +0200 + + Remove checks for non-C99 compliant compilers. + +commit ed09fa4e03c907736b2be0a831d10863ce4cae84 +Author: Guus Sliepen +Date: Thu Apr 14 23:01:18 2016 +0200 + + Fix version_get.h generation on BSD. + + It doesn't like .PHONY rules that are actually doing stuff. So make a really + phony rule that does nothing and depend in it in the version_git.h rule. + +commit 2802b3a49797a0f58d6a8f4d9945d54acc64d996 +Author: Guus Sliepen +Date: Thu Apr 14 22:59:42 2016 +0200 + + Fix typo in Makefile.am. + +commit 46ebfbb6eb9966239f7826e002d99554420bbbc8 +Author: Guus Sliepen +Date: Thu Apr 14 17:29:25 2016 +0200 + + Use getcwd() instead of get_current_dir_name(). + +commit b5b04910b928c63a31a0859f04bf067ca9bd1cc2 +Author: Guus Sliepen +Date: Thu Apr 14 17:20:36 2016 +0200 + + Replace usleep() with nanosleep(). + +commit 491839a81aba00d4af50b66563cedaac4fa7028c +Author: Guus Sliepen +Date: Thu Apr 14 17:05:10 2016 +0200 + + Fix compiling under MinGW. + +commit 34ea20af73a35cd918ce9dc25796bebf9493b49c +Author: Guus Sliepen +Date: Thu Apr 14 17:03:01 2016 +0200 + + Remove checks for headers and functions that are in C99. + +commit fd3800324f4e4c67b087eaf5e0a61a184a270812 +Author: Guus Sliepen +Date: Wed Apr 13 15:34:16 2016 +0200 + + Make text files Markdown-compatible. + +commit 7f749c7e75c08549d7ce43838622624a8093de85 +Author: Guus Sliepen +Date: Mon Apr 11 15:28:26 2016 +0200 + + Update .gitignore. + +commit 9ba3e95a9a559240d16de71ca1513c7bfa98a70c +Author: Guus Sliepen +Date: Mon Apr 11 15:27:08 2016 +0200 + + Remove elliptic curve stubs from gcrypt/, add PRF implementation. + +commit 20dd1c21dc6d238200e62a1111a7d0d145168548 +Author: Guus Sliepen +Date: Fri Apr 8 17:49:49 2016 +0200 + + Really don't compile getopt*.c if the system provides getopt_long(). + +commit 9527622abc75ef41498de70ed6ded6bf5b38cfac +Author: Guus Sliepen +Date: Sat Apr 9 22:17:47 2016 +0200 + + Enable silent builds by default. + + Cleaner build messages make it easier to spot compiler warnings and errors. + Use make V=1 to get the verbose output back. + + # Conflicts: + # configure.ac + # doc/Makefile.am + +commit 413faffca356b25cf69ddf0a718730d46f9941bc +Author: Guus Sliepen +Date: Sun Apr 10 15:04:59 2016 +0200 + + Update links in the documentation. + + # Conflicts: + # doc/tinc.conf.5.in + # doc/tinc.texi + # src/avl_tree.c + # src/avl_tree.h + +commit 5cbc12b3d482231fc7e71fbe176c91971993760e +Author: Guus Sliepen +Date: Sun Apr 10 14:47:21 2016 +0200 + + Explicitly mention that LibreSSL can be used as well. + + # Conflicts: + # doc/tinc.texi + # m4/openssl.m4 + +commit d7f6737cfcae75e8c2f522c68aaedee0519a6131 +Author: Guus Sliepen +Date: Mon Apr 11 14:49:51 2016 +0200 + + Update support for BSD tun/tap devices, add support for OS X utun interfaces. + +commit 2a7871990bc401921b8bb9accbc6a8206d564f72 +Author: Guus Sliepen +Date: Sun Nov 1 21:07:56 2015 +0100 + + Update "now" after connect() when making outgoing connections. + + It could be that address resolution takes a long time, don't let that + count against a connection. This is especially important when using a + nameserver from the VPN. + + # Conflicts: + # src/net_socket.c + +commit cadbf587a09bd4adde664cd635b962315228b3f5 +Author: Guus Sliepen +Date: Sun May 3 20:06:12 2015 +0200 + + Never call putenv() with data on the stack. + + Even though we are using putenv() here to remove items from the + environment, there is no guarantee that putenv() doesn't add the + argument to the environment anyway. In that case, we have to make sure + that it doesn't go away. We also don't want a memory leak, so keep a + list of things we unputenv()ed around, so we can reuse things. + + Thanks to Poul-Henning Kamp for pointing out this problem. + + # Conflicts: + # src/process.c + +commit 0e8e53b4cee8f1ea27bad501cbc18292ced54fa1 +Author: Guus Sliepen +Date: Tue Apr 14 11:20:24 2015 +0200 + + Fix --logfile without a filename on Windows. + + On Windows, the log filename now defaults to "tinc.log" in the same + directory as tinc.conf. + + # Conflicts: + # src/tincd.c + +commit c544e5e8fe22250b230a46f0340483db5403a6c1 +Author: Guus Sliepen +Date: Sun Apr 10 17:22:41 2016 +0200 + + Support ToS/DiffServ for IPv6 meta and UDP connections. + + Also remember ToS/DiffServ priority for each socket individually. This + is a port of commits c72e237 and 042a6c1. + +commit e355088535ee9ebb12a4db0043bf6a9743085b28 +Author: Guus Sliepen +Date: Fri Apr 8 18:09:30 2016 +0200 + + Use iface instead of interface. + + This was accidentally added in commit 2f03a5d. + +commit 6f97c0011572a1e12fa6267068b7f3fd46ceffd8 +Author: Guus Sliepen +Date: Sun Apr 10 17:01:04 2016 +0200 + + Update THANKS. + +commit 8be447ac0227a8ecb89facb2831c121a7ca81748 +Author: Guus Sliepen +Date: Sun Apr 10 16:51:03 2016 +0200 + + Update .gitignore. + +commit 9f0fb224a6c2eab93b6917ef6c034423c49126cd +Author: Guus Sliepen +Date: Fri Apr 8 17:49:49 2016 +0200 + + Don't compile getopt*.c if the system provides getopt_long(). + + # Conflicts: + # configure.ac + # src/Makefile.am + # src/tincd.c + +commit c2726dae62d632883f822741f9619265640e57b3 +Author: Guus Sliepen +Date: Sun Apr 10 16:38:45 2016 +0200 + + Fix typo. + + Found by LunarShaddow. + +commit e44c337eae674120745f7c7c56a1a70919ff40ca +Author: LunarShaddow +Date: Mon Mar 7 15:43:04 2016 +0800 + + re-arrange include sequence to avoid a mingw introduced bug. + refers: https://www.cygwin.com/ml/cygwin/2012-12/msg00194.html + + # Conflicts: + # src/cygwin/device.c + +commit af83d0b9e87fe795a3d01d0ee3fb35e0d8579b88 +Author: LunarShaddow +Date: Mon Mar 7 15:42:34 2016 +0800 + + fix typo + +commit bf50b3502a022b406424d0d03aaf7670133452b2 +Author: Guus Sliepen +Date: Sun Feb 28 16:38:49 2016 +0100 + + Fix for botched cherry-pick commit 60fb230. + +commit 1ceea259c3ba5efb9b8b12161e75256270ba4804 +Author: Guus Sliepen +Date: Sat Feb 27 14:46:01 2016 +0100 + + Add warnings for bad combinations of Device and Interface. + + On Linux, the name of the tun/tap interface can be set freely. However, + on most other operating systems, tinc cannot change the name of the + interface. In those situations, it is possible to specify a Device and + an Interface that conflict with each other. On BSD, this can cause + $INTERFACE to be set incorrectly, on Windows, this results in a + potentially unreliable way in which a TAP-Win32 interface is selected. + + # Conflicts: + # src/bsd/device.c + +commit e3f80e9167ecef8db8add9359b6660ecdcaeb7af +Author: Guus Sliepen +Date: Sat Feb 27 14:22:36 2016 +0100 + + Small fixes for the documentation. + + # Conflicts: + # doc/tinc.texi + +commit 72cfd4f047210cc7cab9014cbf48e007bfd704e6 +Author: Guus Sliepen +Date: Sat Feb 27 14:21:53 2016 +0100 + + Clarify that scripts are called synchronously. + + # Conflicts: + # doc/tinc.conf.5.in + # doc/tinc.texi + +commit 4d7469e0da6652bddc8acde499068db4b41b646d +Author: Guus Sliepen +Date: Sun Feb 28 16:28:28 2016 +0100 + + Fix forwarding of edge updates. + + Commit e4670fc accidentily prevented ADD_EDGE messages from propagating + in some cases. + +commit 60fb2308e5bf1fd9ce642f6c4bcde81997593504 +Author: Guus Sliepen +Date: Sat Feb 27 14:18:20 2016 +0100 + + Improve performance of edge updates. + +commit 994adadf2752fd7515ee30ed5fdb91178a615fe9 +Author: Vittorio Gambaletta (VittGam) +Date: Fri Sep 25 16:51:51 2015 +0200 + + Remove forward declaration for do_decrement_ttl. + + Signed-off-by: Vittorio Gambaletta + + # Conflicts: + # src/route.c + +commit 0f3ae1a9f29c845a69e44a4f691f43d6a6651583 +Author: Vittorio Gambaletta (VittGam) +Date: Fri Sep 25 15:35:28 2015 +0200 + + s/broadcast_packet_helper/route_broadcast/ + + Signed-off-by: Vittorio Gambaletta + + # Conflicts: + # src/route.c + +commit 496f775568873bb769e48ceb644b15ab9f150d62 +Author: Vittorio Gambaletta (VittGam) +Date: Fri Sep 25 04:52:25 2015 +0200 + + Fix DecrementTTL option for packets destined to the local node. + + Signed-off-by: Vittorio Gambaletta + + # Conflicts: + # src/route.c + +commit 17e54ea0bec4d3a3b9a760854dde6039c7a1c421 +Author: Vittorio Gambaletta (VittGam) +Date: Fri Sep 4 17:04:03 2015 +0200 + + Try to reply with node address only when decrementing the TTL. + + Signed-off-by: Vittorio Gambaletta + +commit 92203bdbcb1af4a52c7ca9d0e1a271168435c905 +Author: Vittorio Gambaletta (VittGam) +Date: Fri Sep 4 04:00:57 2015 +0200 + + Fix source IP address for ICMP unreachable packets generated by tinc. + + Try to send ICMP unreachable replies from an address assigned to the + local machine, instead of the destination address of the original + packet. + + The address is found by looking up the route towards the sender of + the packet that generated the error; in usual configurations, this + is the tinc interface. + + This also fixes the traceroute display in mtr when using the + DecrementTTL option. + + Signed-off-by: Vittorio Gambaletta + + # Conflicts: + # src/route.c + +commit a8a3a2c8ceb19bcb6c2c3ef0647c94d7d0624b7a +Author: Vittorio Gambaletta (VittGam) +Date: Thu Sep 3 16:02:50 2015 +0200 + + Fix DecrementTTL option. + + The option was not actually working, as it could be seen on traceroute or mtr. + + The problem is that it was checking if the TTL was < 1 (so equal to 0) before decrementing it. + + This meant that a packet with a TTL of 1 was being sent with a TTL of 0 on the VPN, instead of being discarded with the ICMP error message. + + Signed-off-by: Vittorio Gambaletta + + # Conflicts: + # src/route.c + +commit ac9e32ff91ee2318c49808522f0c7d458c79eb44 +Author: Guus Sliepen +Date: Sun Feb 28 15:48:19 2016 +0100 + + Use nostdinc instead of overriding DEFAULT_INCLUDES. + +commit 96dd6e5f6c6f3f7717102fb3b38759b6cc0c0555 +Author: Guus Sliepen +Date: Sun Jul 5 16:03:03 2015 +0200 + + Only check for -fno-strict-overflow if -fwrapv does not work. + +commit 92f0c4db77a5e2733442491227625d0233f94a97 +Author: Guus Sliepen +Date: Sun Feb 28 15:39:41 2016 +0100 + + Update .gitignore. + +commit d8ca00fe40ff4b6d87e7e64c273f536fab462356 +Author: Guus Sliepen +Date: Wed Jan 27 00:09:29 2016 +0100 + + Add the ability to sign and verify files. + +commit 7418e9077f84db10ef6bb082a375870a7130bd7d +Merge: 420989e4 b6ed5c13 +Author: Guus Sliepen +Date: Sun Jan 17 23:29:23 2016 +0100 + + Merge remote-tracking branch 'mweinelt/tinc-gui' into 1.1 + +commit 420989e4c3ff109c7d077b2f8c06506540f1c0bd +Author: Guus Sliepen +Date: Thu Jan 14 15:07:22 2016 +0100 + + Only add a reflexive address when we're sure it's working. + +commit cda5a477c8138226d184a176256d559971b4f7ed +Author: Guus Sliepen +Date: Thu Dec 10 16:45:05 2015 +0100 + + Use static buffers for recvmmsg(), initialize them only as needed. + + As suggested by Michael Tokarev. + +commit e4fd81ed2d66b8fe3c2857244fe3da85c803cf60 +Author: Guus Sliepen +Date: Thu Dec 10 16:30:32 2015 +0100 + + Add support for recvmmsg(). + + Based on a patch from Samuel Thibault and input from Michael Tokarev. + +commit cef40b8b978694fc0e7c02e292fcbb60806bf028 +Author: Guus Sliepen +Date: Thu Nov 26 11:29:54 2015 +0100 + + list_delete() already free()s the deleted element. + +commit 9fdf4278f8c8c1563d45205c9e9f1bc351bd814f +Author: Guus Sliepen +Date: Tue Nov 24 16:48:44 2015 +0100 + + Don't leave dead outgoing_t's in the outgoing_list. + + If an outgoing connection cannot be made because no address is known for + it, it should be removed from the outgoing_list, otherwise it will + prevent it from being re-added later when we do know addresses for it. + +commit c58eba587da3ac884c6c18b64c262aed8fd1c452 +Author: Etienne Dechamps +Date: Sun Nov 22 18:57:59 2015 +0000 + + Add upnp.h to tincd SOURCES. + + This was missing from 513bffe1fee07bcbcb50691e221874adc1507857. + +commit 613d586afd22159cee57c9524218c7200f4f1096 +Author: Etienne Dechamps +Date: Sun Nov 22 17:14:14 2015 +0000 + + Don't unset validkey when receiving SPTPS handshakes over ANS_KEY. + + This fixes a hairy race condition that was introduced in + 1e89a63f1638e43dee79afbb18d5f733b27d830b, which changed + the underlying transport of handshake packets from REQ_KEY to ANS_KEY. + Unfortunately, what I missed in that commit is, on the receiving side, + there is a slight difference between req_key_h() and ans_key_h(): + indeed, the latter resets validkey to false. + + The reason why this is not a problem during typical operation is + because the normal SPTPS key regeneration procedure looks like this: + + KEX -> + <- KEX + SIG -> + <- SIG + + All these messages are sent over ANS_KEY, therefore the receiving side + will unset validkey. However, that's typically not a problem in practice + because upon reception of the last message (SIG), SPTPS will call + sptps_receive_record(), which will set validkey to true again, and + everything works out fine in the end. + + However, that was the *typical* scenario. Now let's assume that the + SPTPS channel is in active use at the same time key regeneration + happens. Specifically, let's assume a normal VPN data packet sneaks in + during the key regeneration procedure: + + KEX -> + <- KEX + <- (SPTPS packet, over TCP or UDP) + <- KEX (wtf?) + SIG -> (refused with Invalid packet seqno: XXX != 0) + + At this point, both nodes are extremely confused and the SPTPS channel + becomes unusable with various errors being thrown on both sides. The + channel will stay down until automatic SPTPS channel restart kicks in + after 10 seconds. + + (Note: the above is just an example - the race can occur on either side + whenever a packet is sent during the period of time between KEX and SIG + messages are received by the node sending the packet.) + + I've seen this race occur in the wild - it is very likely to occur if + key regeneration occurs on a heavily loaded channel. It can be + reproduced fairly easily by setting KeyExpire to a short value (a few + seconds) and then running something like ping -f foobar -i 0.01. + + The reason why this occurs is because tinc's TX code path triggers the + following: + + - send_packet() + - try_tx() + - try_tx_sptps() + - validkey is false because we just received an ANS_KEY message + - waitingforkey is false because it's not used for key regeneration + - send_req_key() + - SPTPS channel restart (sptps_stop(), sptps_start()). + + Obviously, it all goes downhill from there and the two nodes get very + confused quickly (for example the seqno gets reset, hence the error + messages). + + This commit fixes the issue by keeping validkey set when SPTPS data is + received over ANS_KEY messages. + +commit 95935cecb6290fd13b1266a96be1b8f9c1c54d0f +Author: Guus Sliepen +Date: Sat Nov 21 19:41:14 2015 +0100 + + Update THANKS file. + +commit 0f6d34dc1b43edc6f5bea45c17ce2d6a417265f1 +Author: Etienne Dechamps +Date: Sun Nov 15 17:42:14 2015 +0000 + + Try to ensure we build correctly against various libminiupnpc versions. + + Unfortunately, libminiupnpc has a somewhat... "peculiar" approach to + backwards compatibility for their API, where they reserve the right to + make breaking changes when they feel like it, forcing users to resort + to #ifdefs to ensure they use the correct API. Sigh. + + Previously, tinc would only build against API versions <= 13, because I + was doing my initial development using miniupnpc-1.9.20140610 which is + the version that ships with Debian. The changes in this commit are + required for tinc to build against more recent versions, from + 1.9.20150730 to the latest one at the time of this commit, 1.9.20151026. + +commit 675e3b497bdc87f5a4dfdef7508cd2070850e69e +Author: Etienne Dechamps +Date: Sun Nov 15 15:30:01 2015 +0000 + + Allow tinc to be built with miniupnpc on Windows. + + Contrary to what I expected, it so happens that modern versions of MinGW + include an implementation of pthread natively by default, so there is no + need to introduce Win32-specific threading code. This means the only + changes required to make UPnP work on Windows are just build parameter + tuning. + + This commit forces MinGW to be built statically. This makes linking + against miniupnpc simpler (otherwise we would have to handle the mess + of dllimport & co.) and it also prevents libwinpthread from being linked + dynamically (which it is by default), as this would require additional + DLLs to be distributed. Since static linking is how tinc is + traditionally built on Windows, I don't expect this to be a big deal. + +commit 513bffe1fee07bcbcb50691e221874adc1507857 +Author: Etienne Dechamps +Date: Sun Nov 15 13:40:07 2015 +0000 + + Add UPnP support to tincd. + + This commit makes tincd capable of discovering UPnP-IGD devices on the + local network, and add mappings (port redirects) for its TCP and/or UDP + port. + + The goal is to improve reliability and performance of tinc with nodes + sitting behind home routers that support UPnP, by making it less reliant + on UDP Hole Punching, which is prone to failure when "hostile" NATs are + involved. + + The way this is implemented is by leveraging the libminiupnpc library, + which we have just added a new dependency on. We use pthread to run the + UPnP client code in a dedicated thread; we can't use the tinc event loop + because libminiupnpc doesn't have a non-blocking API. + +commit 2bb567c6a31e333ebdd16d6d076ba9976e6ed4fb +Author: Etienne Dechamps +Date: Sat Nov 14 14:47:42 2015 +0000 + + Add a new optional dependency on the miniupnpc library. + + The miniupnpc library is a lightweight UPnP-IGD client. + + http://miniupnp.free.fr/ + + Contrary to other libraries, this dependency is disabled by default. + This is because the library is somewhat obscure and is only tangentially + useful, so enabling it by default would probably annoy most users. + +commit bdd84660c756437cf3bc8f64adf612055acc84ea +Author: Etienne Dechamps +Date: Sat Nov 7 11:04:13 2015 +0000 + + Make sure the packet source MAC address is always set. + + When tinc is used in router mode with a TAP device, Ethernet (MAC) + headers are not present in packets flowing over the VPN; it is the + node's responsibility to fill out this header before handing the + packet over to the TAP interface (which expects such headers). + + Currently, tinc fills out the destination MAC address of the packet + (otherwise the host would not recognize the packets, and nothing would + work), but it does not fill out the source MAC address. In practice this + doesn't seem to cause any real issues (the host doesn't care about the + source address), but it does look weird when looking at the packets with + a sniffer, and it also result in the following valgrind warning: + + ==13651== Syscall param write(buf) points to uninitialised byte(s) + ==13651== at 0x5C4B620: __write_nocancel (syscall-template.S:81) + ==13651== by 0x1445AA: write_packet (device.c:183) + ==13651== by 0x118C7C: send_packet (net_packet.c:1259) + ==13651== by 0x12B70A: route_ipv4 (route.c:443) + ==13651== by 0x12D5F8: route (route.c:971) + ==13651== by 0x1152BC: receive_packet (net_packet.c:250) + ==13651== by 0x117E1B: receive_sptps_record (net_packet.c:904) + ==13651== by 0x1309A8: sptps_receive_data_datagram (sptps.c:488) + ==13651== by 0x130A90: sptps_receive_data (sptps.c:508) + ==13651== by 0x115569: receive_udppacket (net_packet.c:286) + ==13651== by 0x119856: handle_incoming_vpn_data (net_packet.c:1499) + ==13651== by 0x10F3DA: event_loop (event.c:287) + ==13651== Address 0xffeffea3a is on thread 1's stack + ==13651== in frame #6, created by receive_sptps_record (net_packet.c:821) + ==13651== + + This commit fixes the issue by filling out the source MAC address. It is + generated by negating the last byte of the device MAC address, which is + consistent with what route_arp() does. + + In addition, this commit stops route_arp() from filling out the Ethernet + header of the packet - this is the responsibility of send_packet(), not + route(). + +commit 684bd659ae0c6ca623422851c245188037658698 +Author: Etienne Dechamps +Date: Wed Nov 4 19:18:12 2015 +0000 + + Revert "Cache node IDs in a hash table for faster lookups." + + This reverts commit c2319e90b16962fe899bc60abc8af0e2542bb176. + + As a general principle, I do not believe it is worthwhile to cache + nodes. Sure, it brings lookup time down from O(log n) to O(1), but + considering that the scalability target of tinc is around 1000 nodes + and log2(1000) is 10, that looks like premature optimization; tree + lookups should already be very fast. Therefore, I believe it makes sense + to remove the cache as a code cleanup initiative. + +commit eeebff55c07c09c5bc5e62a7b2a21f68ecd1c802 +Author: Etienne Dechamps +Date: Wed Nov 4 19:07:14 2015 +0000 + + Use a splay tree for node UDP addresses in order to avoid collisions. + + This commit replaces the node UDP address hash table "cache" with a + full-blown splay tree, aligning it with node_tree (name-indexed) and + node_id_tree (ID-indexed). + + I'm doing this for two reasons. The first reason is to make sure we + don't suddenly degrade to O(n) performance when two "hot" nodes end up + in the same hash table bucket (collision). + + The second, and most important, reason, has to do with the fact that + the hash table that was being used overrides elements that collide. + Indeed, it turns out that there is one scenario in which the contents of + node_udp_cache has *correctness* implications, not just performance + implications. This has to do with the way handle_incoming_vpn_data() is + implemented. + + Assume the following topology: + + A <-> B <-> C + + Now let's consider the perspective of tincd running on B, and let's + assume the following is true: + + - All nodes are using the 1.1 protocol with node IDs and relaying + support. + - Nodes A and C have UDP addresses that hash to the same value. + - Node C "wins" in the node_udp_cache (i.e. it overwrites A in the + cache). + - Node A has a "dynamic" UDP address (i.e. an UDP address that has been + detected dynamically and cannot be deduced from edge addresses). + + Then, before this commit, A would be unable to relay packets through B. + + This is because handle_incoming_vpn_data() will fall back to + try_harder(), which won't be able to match any edge addresses, doesn't + check the dynamic UDP addresses, and won't be able to match any keys + because this is a relayed packet which is encrypted with C's key, not + B's. As a result, tinc will fail to match the source of the packet and + will drop the packet with a "Received UDP packet from unknown source" + message. + + I have seen this happen in the wild; it is actually quite likely to + occur when there are more than a handful of nodes because node_udp_cache + only has 256 buckets, making collisions quite likely. This problem is + quite severe because it can completely prevent all packet communication + between nodes - indeed, if node A tries to initiate some communication + with C, it will use relaying at first, until C responds and helps A + establish direct communication with it (e.g. hole punching). If relaying + is broken, C will not help establish direct communication, and as a + result no packets can make it through at all. + + The bug can be reproduced fairly easily by reproducing the topology + above while changing the (hardcoded) node_udp_cache size to 1 to force a + collision. One will quickly observe various issues when trying to make A + talk to C. Setting IndirectData on B will make the issue even more + severe and prevent all communication. + + Arguably, another way to fix this problem is to make try_harder() + compare the packet's source address to each node's dynamic UDP + addresses. However, I do not like this solution because if two "hot" + nodes are contending on the same hash bucket, try_harder() will be + called very often and packet routing performance will degrade closer to + O(N) (where N is the total number of nodes in the graph). Using a more + appropriate data structure fixes the bug without introducing this + performance problem. + +commit 7a8515112a4bf94da3cec157ada6e0794a03b946 +Author: Guus Sliepen +Date: Mon Oct 26 13:46:30 2015 +0100 + + Avoid undefined behavior. + + Left shifts of negative values is undefined in C. This happens a lot in + the Ed25519 code. Cast to unsigned first, then cast the result back to + signed where necessary. + +commit b6ed5c134fc43d438c622d24f949c240632f5e67 +Author: Martin Weinelt +Date: Mon Sep 28 06:34:15 2015 +0200 + + tinc-gui: Properly initialize class attributes for VPN in __init__ + +commit 927efeff6242e262b176976a1eb298891578f77d +Author: Martin Weinelt +Date: Mon Sep 28 05:54:17 2015 +0200 + + tinc-gui: Use ArgumentParser, default to python2 + +commit e92bb7d1dd7adc02503e3ee795e53b15634df570 +Author: Martin Weinelt +Date: Mon Sep 28 05:34:22 2015 +0200 + + tinc-gui: Fix GetListCtrl method name in SuperListCtrl + + wxPython wrongly expects camelcase method names, this however + is against PEP8 + +commit 53333d6d0d870de6801352bda106286255f14319 +Author: Martin Weinelt +Date: Mon Sep 28 05:31:59 2015 +0200 + + tinc-gui: Update Node object to correctly parse responses + + The application was expecting a different respoonse from tinc + and wouldn't properly it, and thus not start at all. + +commit 0c7e0210d900185d4c1a9ffd969dc2a26d9523a9 +Author: Martin Weinelt +Date: Mon Sep 28 05:20:03 2015 +0200 + + tinc-gui: Reformat codebase according to PEP8 + +commit 73068238436d8a22abb86e67b08f573b09fd04e1 +Author: Guus Sliepen +Date: Fri Sep 25 10:06:18 2015 +0200 + + Fix a few memory leaks in the CLI found by AddressSanitizer. + +commit 543c0abbd91a7b076670b8763548b8d5849860a0 +Author: Guus Sliepen +Date: Fri Sep 25 10:05:24 2015 +0200 + + Fix struct node_status_t. + + Although not a problem for tinc internally, the size of the struct was 12 + bytes instead of 4, causing some problems when interpreting the value + received from tincd by the CLI. + +commit 706d855e507980de3845556989d7de7a3b9c76e8 +Author: Guus Sliepen +Date: Thu Sep 24 22:20:00 2015 +0200 + + Replace bare if statements with AS_IF in configure.ac. + +commit f54a87b800d551bec4532a5d3bf124d02e167856 +Author: Guus Sliepen +Date: Thu Sep 24 21:53:49 2015 +0200 + + Optionally install systemd service files. + + If --with-systemd is given when running the configure script, two + systemd service files will be installed. There is a template + tinc@.service, which can be used to control individual instances of + tinc. For example: + + systemctl enable tinc@foo + + Will create an instance for tinc with netname foo. There is also a + tinc.service, which can be used to start and stop all instances at once. + +commit 5ad43673acf03f86643f1463f1ebfa6e9ca189cc +Author: Guus Sliepen +Date: Thu Sep 24 17:10:25 2015 +0200 + + Add -I m4 back to ACLOCAL_AMFLAGS. + + In commit b7b5d51, AC_CONFIG_MACRO_DIRS([m4]) was added to configure.ac, + which is the current proper way of including the m4 directory. However, + old versions of autoconf ignore it and need the -I m4 statement in + Makefile.am. Both the old and new way of indicating that the m4/ + directory should be included can coexist. + +commit ae89a25695411149a7499189c9771762ad1f1726 +Author: Nathan Stratton Treadway +Date: Sat Sep 12 16:33:52 2015 +0200 + + Fix invalid checksum generation. + + Use equation 3 given in RFC 1624 and the UpdateTTL() example function given + RFC 1141. + + # Conflicts: + # src/route.c + +commit 56a8b90d863171d62e0a337b5635fbfc53a67fb0 +Author: Guus Sliepen +Date: Wed Jul 22 14:33:56 2015 +0200 + + In sssp_bfs(), never try to update myself. + +commit f75e6f61f280b138082b87ce69bdbdee3e4ba56e +Author: thorkill +Date: Sun Jul 19 18:53:29 2015 +0200 + + Do not access e->to->prevedge if not defined + + In some cases - mostly when e->to == myself the prevedge is set to NULL, + causing invalid memory access. In rare cases this may lead to malformed mst + or segfaults. + +commit f92c3446f2052a59d1e6a28f1bc7cec278cb1e48 +Author: Guus Sliepen +Date: Wed Jul 15 15:12:53 2015 +0200 + + Use AC_CONFIG_MACRO_DIR() instead of _DIRS(). + + The former is guaranteed to work with autoconf 2.58 and later, and we + don't have multiple m4 directories anyway. + +commit 9ca1750245b28ed8306f150b6371139c656be111 +Author: Guus Sliepen +Date: Sun Jul 12 16:31:32 2015 +0200 + + Fix the PRF function when compiling without OpenSSL. + +commit 3c54765bcdf8bd6114da0cb31f45404950089e3a +Author: thorkill +Date: Tue Jul 7 23:14:08 2015 +0200 + + Prevent tinc from forgeting e->local_address + + If ADD_EDGE came from tinc version 1.0.x local_address.sa.sa_family is set to 0. + If it came from tinc version 1.1.x forwarded for older verion it will be 255 - AF_UNKNOWN. + +commit 1e7ef381980a5c4c84d699522265290dde5ac728 +Author: thorkill +Date: Tue Jul 7 21:19:26 2015 +0200 + + Make sure we do not allocate new edge when talking to old nodes and the same edge already exists + + When tinc gets ADD_EDGE from older versions it will allocate + new edge in protocol_edge.c:189 due to missed case in lines 149-171 where + local_address is not defined. + +commit 7b831804aafa370a6c8d9e86caee31cda1a3dd72 +Author: Guus Sliepen +Date: Sun Jul 12 13:08:34 2015 +0200 + + Make subnet caches static. + +commit 322ffadac43c7e357cc12340d7b8112a0aaad5af +Author: thorkill +Date: Tue Jun 30 19:11:45 2015 +0200 + + Included missing names.h + +commit b7b5d516137713c594990cd982a29f7e5718b45b +Author: Guus Sliepen +Date: Sun Jul 12 13:05:51 2015 +0200 + + Use AC_CONFIG_MACRO_DIRS([m4]). + +commit 97457716d7efc541d18d08263bbd338e94195bd9 +Author: Guus Sliepen +Date: Sun Jul 12 12:55:13 2015 +0200 + + Remove unused code that caused warnings about an uninitialized variable. + +commit b22b9d438970a0442559949da35be9cc0ffaec00 +Author: thorkill +Date: Mon Jun 29 00:23:13 2015 +0200 + + Removed double break; + +commit b396585383fe12c890ef7953efaa13a83963b5d7 +Author: Guus Sliepen +Date: Sun Jul 12 12:33:07 2015 +0200 + + Fix undefined behaviour when left-shifting signed integers. + + Found by -fsanitize=undefined. + +commit de7d9ee437bc0e5d72f8c6744e1df7ea7b64d2e9 +Author: Guus Sliepen +Date: Sat Jul 4 17:53:11 2015 +0200 + + Call sockaddrfree(&e->local_address) in free_edge() instead of exit_edges(). + + The proper place to clean up resources of objects is in their + destructor. This makes sure proper cleanup when edge_del() is called as + well. At exit, free_edge() is called on all edges by free_edge_tree(), + which is called by exit_nodes(). + +commit 36cec9af88909cb2cf012d609e5c4d8c444ddab9 +Author: Guus Sliepen +Date: Sat Jul 4 17:51:05 2015 +0200 + + Coalesce two if statements that check for the same thing. + +commit 14ccf509540e338502ad806f60bdc3f71ddce66f +Author: Jo-Philipp Wich +Date: Thu Jun 18 23:58:31 2015 +0200 + + fix musl compatibility + + Let configure include sys/if_tun.h when testing for netinet/if_ether.h + to detect the Kernel/libc header conflict on musl. + + After this patch, configure will correctly detect netinet/if_ether.h as + unusable and the subsequent compilation will not attempt to use it. + + Conflicts: + src/have.h + +commit 37588b8d5cface1bc72424a198b1cc1a6044adb0 +Author: Guus Sliepen +Date: Sat Jul 4 17:18:40 2015 +0200 + + Don't #include OpenSSL headers when compiling without OpenSSL. + +commit abb24e9d71b3edb9cacf4c04361cc0dfd4e6a061 +Author: thorkill +Date: Sat Jul 4 03:21:01 2015 +0200 + + Cleanup local_address in protocol_edge.c + + In line 131 local_address has been defined, + but the memory was never freed on return. + +commit 92df36a610421ed5fcae90e832f64e3acfb7d431 +Author: thorkill +Date: Sat Jul 4 02:39:12 2015 +0200 + + Cleanup edges stored in edge_weight_tree on exit + + protocol_edge.c: 131 defines local_address using str2sockaddr + + str2sockaddr() allocates memory which has to be freed on exit. + +commit 1140ca6d3004b228947bad8736f0b49d6b169267 +Author: thorkill +Date: Sat Jul 4 00:29:36 2015 +0200 + + Fixed 2 leaks in setup_myself() + +commit 0267aef826ba627aba3a525b36c0e7bfc0f9a221 +Author: Florian Klink +Date: Thu Jul 2 12:35:42 2015 +0200 + + setup_outgoing_connection: log to LOG_DEBUG on if no known address + + With AutoConnect = yes, tinc tries to establish connections to known hosts. + However, you could have set no Address for this host, which is perfectly fine + (as long as there is at least one bootstrap node with an address or a local + discovered node already part of the network) + + So log this to LOG_DEBUG + +commit 91355b9ac5a80d6d7da6951a72ea0c22651bdfa8 +Author: Florian Klink +Date: Thu Jul 2 12:35:41 2015 +0200 + + (read|append)_config_file: log open errors as LOG_DEBUG + + In a "decentrally managed vpn" it is very likely that host config + files for some reachable nodes do not exist. Currently, tinc + fills the logs with "Cannot open config file" messages. + + This commit changes the log level to LOG_DEBUG so + syslog doesn't get filled by default. + +commit ebffa40aa7832459f63801e3a91cc741e6b339a8 +Author: Etienne Dechamps +Date: Sat Jun 20 11:41:20 2015 +0100 + + Protect against callbacks removing items from the io tree. + + The definition of the splay_each() macro is somewhat complicated for + syntactic reasons. Here's what it does in a more readable way: + + for (splay_node_t* node = tree->head; node;) { + type* item = node->data; + splay_node_t* next = node->next; + + // RUN USER BLOCK with (item) + + node = next; + } + + list_each() works in the same way. Since node->next is saved before the + user block runs, this construct supports removing the current item from + within the user block. However, what it does *not* support is removing + *other items* from within the user block, especially the next item. + Indeed, that will invalide the next pointer in the above loop and + therefore result in an invalid pointer dereference. + + Unfortunately, there is at least one code path where that unsupported + operation happens. It is located in ack_h(), where the authentication + protocol code detects a double connection (i.e. being connected to + another node twice). Running in the context of a socket read event, this + code will happily terminate the *other* metaconnection, resulting in its + socket being removed from the io tree. If, by misfortune, this other + metaconnection happened to have the next socket FD number (which is + quite possible due to FD reuse - albeit unlikely), and was part of the + io tree (which is quite likely because if that connection is stuck, it + will most likely have pending writes) then this will result in the next + pending io item being destroyed. Invalid pointer dereference ensues. + + I did a quick audit of other uses of splay_each() and list_each() and + I believe this is the only scenario in which this "next pointer + invalidation" problem can occur in practice. While this bug has been + there since at least 6bc5d626a8726fc23365ee705761a3c666a08ad4 (November + 2012), if not sooner, it happens quite rarely due to the very specific + set of conditions required to trigger it. Nevertheless, it does manage + to crash my central production nodes every other week or so. + +commit 7f020cf456b327313f0cfa8d103fb14f06f71994 +Author: Dato Simó +Date: Tue Jun 16 20:44:45 2015 -0300 + + Fix typo in tinc.texi. + +commit 45a46f068cf8fbe6cc8c59673de2d8580d18f87f +Author: Guus Sliepen +Date: Wed Jun 10 23:42:17 2015 +0200 + + Fix crash is sptps_logger(). + + Unfortunately, sptps_logger() cannot know if s->handle is pointing to a + connection_t or a node_t. But it needs to print name and hostname in + both cases. So make sure both types have name and hostname fields at the + start with the same offset. + +commit bfe231b977284ba78a582db96a05b5854ddf0d91 +Author: Guus Sliepen +Date: Sun Jun 7 23:20:14 2015 +0200 + + Fix alignment of output of sptps_speed. + +commit a797b4a19235be740c51bcb3bb6ec5de01915f46 +Author: Guus Sliepen +Date: Sun Jun 7 23:14:48 2015 +0200 + + Fix receiving SPTPS data in sptps_speed and sptps_test. + + The sptps_receive_data() was changed in commit d237efd to only process + one SPTPS record from a stream input. So now we have to put a loop + around it to ensure we process everything. + +commit d8d1ab4ee1e92ec84fe9ea86eec2396275483a92 +Author: Guus Sliepen +Date: Sun Jun 7 22:50:05 2015 +0200 + + Fix warnings about missing return value checks. + + In some harmless places, checks for the return value of ECDSA and RSA + key generation and verification was omitted. Add them to keep the + compiler happy and to warn end users in case something is wrong. + +commit ab0576a2034b03f92943ac477e4e97731a899554 +Author: Guus Sliepen +Date: Sun Jun 7 22:25:22 2015 +0200 + + Fix autoconf check for function attributes. + + GCC warns when a function attribute has no effect. The autoconf check + turns warnings about attributes into errors, therefore thinking that + they did not work. The reason was that the test function returned void, + which is not suitable for checking both __malloc__ and + __warn_unused_result__. + +commit 84ecc972e5c11f683ac618c5a734a17c295d9b46 +Author: Guus Sliepen +Date: Sun May 31 23:51:39 2015 +0200 + + Fix missing return value caused by the previous commit. + +commit eca357ed916c9782a64a68a2f30b144d84027795 +Author: Etienne Dechamps +Date: Sun May 31 20:19:48 2015 +0100 + + Don't try to relay packets to unreachable nodes. + + It is not unusual for tinc to receive SPTPS packets to be relayed to + nodes that just became unreachable, due to state propagation delays in + the metagraph. + + Unfortunately, the current code doesn't handle that situation correctly, + and still tries to relay the packet to the unreachable node. This + typically ends up segfaulting. + + This commit fixes the issue by checking for reachability before relaying + the packet. + +commit 9e3adef5cb31cb73fbbbd25d3fce115aac107714 +Author: Etienne Dechamps +Date: Sun May 24 09:49:16 2015 +0100 + + Fix invalid pointer use in get_my_hostname(). + + clang-3.7 warnings surfaced an actual bug: + + invitation.c:185:5: error: address of array 'filename' will always evaluate to 'true' + [-Werror,-Wpointer-bool-conversion] + if(filename) { + ~~ ^~~~~~~~ + + The regression was introduced in 3ccdf50beb6b2d3f2730bdc66006b43190537cde. + +commit 7fcfbe2bd2d14d13e06e3e2addfe0ea12b67873f +Author: Etienne Dechamps +Date: Sun May 24 09:45:09 2015 +0100 + + Fix wrong format string type in send_sptps_tcppacket(). + + This issue was found through a clang-3.7 warning: + + protocol_misc.c:167:46: error: format specifies type 'short' but the argument has type 'int' + [-Werror,-Wformat] + if(!send_request(c, "%d %hd", SPTPS_PACKET, len)) + ~~~ ^~~ + %d + +commit 3e61c7233b087b8400c29ca7a8d079aad8b706d8 +Author: Etienne Dechamps +Date: Sat May 23 17:24:05 2015 +0100 + + Don't set up an ongoing connection to myself. + + It is entirely possible that the configuration file could contain a + ConnectTo statement refering to its own name; that's a reasonable + scenario when one deploys semi-automatically generated tinc.conf files. + + Amusingly, tinc does not like that at all, and actually sets up an + outgoing_t structure to myself (which obviously makes no sense). This is + mostly benign, though it does result in non-sensical "Already connected + to myself" messages every retry interval. + + However, that also makes things blow up in close_network_connections(), + because there we delete the entire outgoing list and *then* the myself + node, which still has a reference to the freshly deleted outgoing + structure. Boom. + +commit 8587e8c0d9ac997fcd2040470c1ccf5930bc18c3 +Author: Etienne Dechamps +Date: Sat May 23 10:24:00 2015 +0100 + + Fix crashes when trying unreachable nodes. + + timeout_handler() calls try_tx(c->node) when c->edge exists. + Unfortunately, the existence of c->edge is not enough to conclude that + the node is reachable. + + In fact, during connection establishment, there is a short period of + time where we create an edge for the node at the other end of the + metaconnection, but we don't have one from the other side yet. + Unfortunately, if timeout_handler() runs during that short time + window, it will call try_tx() on an unreachable node, which makes + things explode because that function is not prepared to handle that + case. + + A typical symptom of this race condition is a hard SEGFAULT while trying + to send packets using metaconnections that don't exist, due to + n->nexthop containing garbage. + + This patch fixes the issue by making try_tx() check for reachability, + and then making all code paths use try_tx() instead of the more + specialized methods so that they go through the check. + + This regression was introduced in + eb7a0db18ea71a44999d6a37b4b179dac0ed9bc7. + +commit 537a9366718b39278fd4eb33b2ac568011e374cc +Author: Guus Sliepen +Date: Thu May 21 11:09:01 2015 +0200 + + Update copyright notices. + +commit 0a786ffbb9d293d7704b8e264f3943a616ed25cc +Author: Guus Sliepen +Date: Thu May 21 11:06:38 2015 +0200 + + Set the CLOEXEC flag on the umbilical socket. + +commit 87e09527735632aae3f595f5a28667880ca4c8c1 +Author: Guus Sliepen +Date: Wed May 20 21:28:54 2015 +0200 + + Use socketpair() instead of pipe() for the umbilical. + + This prepares for a possible conversion of the umbilical socket to a + control socket. + +commit 19e0d449ebd06450c9d7f16f032c0806242c7515 +Author: Guus Sliepen +Date: Wed May 20 21:25:06 2015 +0200 + + Don't write log messages to the umbilical pipe if we don't detach. + + If we run in the foreground and are started by the CLI, this would + otherwise cause the first few log messages to appear twice. + +commit 11868b890d1a7f4cfbfb37099393b32019010f66 +Author: Guus Sliepen +Date: Wed May 20 16:59:43 2015 +0200 + + Ensure "tinc start" knows if the daemon really started succesfully. + + We do this by creating an umbilical between the CLI and the daemon. The + daemon pipes log messages to the CLI until it starts the main loop. The + daemon then cuts the umbilical. The CLI copies all the received log + messages to stderr, and the last byte indicates whether the daemon + started succesfully or not, so the CLI can exit with a useful exit code. + +commit 7f96ef081dc0dc41e3955e35c1a36a62fd47f72b +Author: Guus Sliepen +Date: Wed May 20 11:11:12 2015 +0200 + + Fix check for LOCALSTATEDIR accessibility for the CLI. + + The CLI does not need write access to the directory where the PID file + is stored, it just needs to be able to read the PID file. + +commit 3ccdf50beb6b2d3f2730bdc66006b43190537cde +Author: Guus Sliepen +Date: Wed May 20 00:55:00 2015 +0200 + + Allocate temporary filenames on the stack. + + This gets rid of xasprintf() in a number of places, and removes the need + to free() the temporary strings. A few potential memory leaks have been + fixed. + +commit 58e8f598f38dbb2f210d8a62c8fb4b46513dc39f +Author: Guus Sliepen +Date: Wed May 20 00:12:01 2015 +0200 + + Allow dumping a list of outstanding invitations. + + This dumps the name of the invitation file, as well as the name of the + node that is being invited. This can make it easier to find the + invitation file belonging to a given node. + +commit 7c8f54cdb2925ba787209f5358b62d3cee414d43 +Author: Guus Sliepen +Date: Wed May 20 00:02:53 2015 +0200 + + Add "list" as an alias for "dump" in the CLI. + +commit 69ba5f621e4931417f9f41061a7689e36c70e3d9 +Author: Guus Sliepen +Date: Tue May 19 22:26:32 2015 +0200 + + Quit with an error message if ioctl(TUNSETIFF) fails. + + It is possible that opening /dev/net/tun works but that interface + creation itself fails, for example if a non-root user tries to create a + new interface, or if the desired interface is already opened by another + process. In this case, the ioctl() fails, but we actually silently + ignored this condition. + +commit 60fbdb3f2cf0216afb2cfcc2c4128fb5765471ac +Author: Guus Sliepen +Date: Tue May 19 22:17:18 2015 +0200 + + If LOCALSTATEDIR is inaccessible, store the pid and socket files in the configuration directory. + + The compile time local state directory is usually /var or + /usr/local/var. If this is not accessible for some reason, for example + because someone ./configured tinc without --localstatedir and + /usr/local/var does not exist, or if tinc is started by a non-root user, + then tinc will fall back to the directory where tinc.conf is stored. + A warning is logged when this happens. + +commit dece2db78e2c4ccd6e617e69195754639b086170 +Author: Guus Sliepen +Date: Tue May 19 21:32:30 2015 +0200 + + Don't log seqno failures in sptps_verify_datagram(). + + This function is not used for normal traffic, only when a packet from an + unknown source is received and we need to check against candidates. No + failures should be logger in this case; if the packet is really not + valid this will be logged by handle_incoming_vpn_data(). + +commit a7522118018928e17fc53840b420df570cf1bec5 +Author: Guus Sliepen +Date: Tue May 19 21:23:35 2015 +0200 + + Add source of SPTPS errors to log messages. + +commit d89f37eb17196e38105a92d746ed7cb6b6f6ba45 +Author: Guus Sliepen +Date: Tue May 19 14:25:20 2015 +0200 + + Add newline at end of precomp_data.h and sc.h. + +commit d8a3a182de30d649ed6764dd5d64b57ad77a446e +Author: Guus Sliepen +Date: Tue May 19 14:09:53 2015 +0200 + + Fix src/Makefile.am for *BSD. + + Apparently the BSDs don't like $(srcdir) but want to see ${srcdir} in + their rules. + +commit 96a323e16a1f3e99d0b498aa90423b060c3d458f +Author: Guus Sliepen +Date: Tue May 19 13:31:26 2015 +0200 + + Remove info-in-builddir option from AM_INIT_AUTOMAKE(). + + This option is not supported by older, but still widely used versions of + automake. The drawback is that when doing multiple VPATH builds in a + row, the info manual may mention incorrect paths, but it doesn't affect + the executables at all. + +commit 51b5aab9b042dffc6ef0791358f097895a3234eb +Author: Sven-Haegar Koch +Date: Wed May 13 21:24:29 2015 +0200 + + Fix check for public key in invite-join.test. + + Small fix to test/invite-join.test, comparing no-longer-existing + ECDSAPublicKey does not make sense. + +commit a196e9b0fde1e8a67108eacd51ac663eac5a63ae +Author: Etienne Dechamps +Date: Mon May 18 21:06:16 2015 +0100 + + Fix direct UDP communciation with pre-relaying 1.1 nodes. + + try_tx_sptps() gives up on UDP communication if the recipient doesn't + support relaying. This is too restrictive - we only need the other node + to support relaying if we actually want to relay through them. If the + packet is sent directly, it's fine to send it to an old pre-node-IDs + tinc-1.1 node. + +commit fef29d0193afc7e0a9dc766ef75b79cd4dc6fa37 +Author: Etienne Dechamps +Date: Mon May 18 20:48:45 2015 +0100 + + Don't parse node IDs if the sending node doesn't support them. + + Currently, tinc tries to parse node IDs for all SPTPS packets, including + ones sent from older, pre-node-IDs tinc-1.1 nodes, and therefore doesn't + recognize packets from these nodes. This commit fixes that. + + It also makes code slightly clearer by reducing the amount of fiddling + around packet offset/length. + +commit 643149b44991121c618a2412c64072ad22955991 +Author: Etienne Dechamps +Date: Mon May 18 20:35:44 2015 +0100 + + Fix SPTPS condition in try_harder(). + + A condition in try_harder() is always evaluating to false when talking + to a SPTPS node because n->status.validkey_in is always false in that + case. Fix the condition so that the SPTPS status is correctly checked. + + This prevented recent tinc-1.1 nodes from talking to older, pre-node-ID + tinc-1.1 nodes. + + The regression was introduced in + 6056f1c13bb37bf711dff9c25a6eaea99f14d31f. + +commit 01d251986260faf306927aa91daff705ee0523d6 +Author: Etienne Dechamps +Date: Sun May 17 22:36:15 2015 +0100 + + Don't pollute the system header directory namespace. + + Since commit 13f9bc1ff199bea46d3dde391a848f119e2cc0f0, tinc passes the + -I. option to the preprocessor so that version_git.h can be found during + out-of-tree ("VPATH") builds. + + The problem is, this option also affects the directory search for files + included *from* system headers. For example, on MinGW, unistd.h contains + the following line: + + #include + + Which, due to -I. putting the tinc directory at the head of the search + order, results in tinc's process.h being included instead of the file + from MinGW. Hilarity ensues. + + This commit fixes the issue by using -iquote, which doesn't affect + system headers. + +commit c1154bf696b0b3ad22126a76750d610e32e2ffc1 +Author: Etienne Dechamps +Date: Sun May 17 22:21:11 2015 +0100 + + Make sure the MIN() macro is defined. + + On MinGW this is not automatically the case, thereby breaking the build. + +commit 5c32bd1578d59e005f634621d17ca96af32bb630 +Merge: aa52300b 1a7a9078 2cb216d8 +Author: Guus Sliepen +Date: Sun May 17 21:07:45 2015 +0200 + + Merge remote-tracking branches 'dechamps/sptpsrestart' and 'dechamps/keychanged' into 1.1 + +commit 2cb216d83d825fcca2fa2b66c756b253f8f0828b +Author: Etienne Dechamps +Date: Sun May 17 19:23:12 2015 +0100 + + Don't send KEY_CHANGED messages if we don't support the legacy protocol. + + KEY_CHANGED messages are only useful to invalidate keys for non-SPTPS nodes; + SPTPS nodes use a different internal mechanism (forced KEX) for that purpose. + Therefore, if we know we can't talk to legacy nodes, there's no point in + sending them these messages. + +commit 1a7a9078c093f77950192c32be009bbe463fe372 +Author: Etienne Dechamps +Date: Sun May 17 18:50:11 2015 +0100 + + Proactively restart the SPTPS tunnel if we get receive errors. + + There are a number of ways a SPTPS tunnel can get into a corrupt state. + For example, during key regeneration, the KEX and SIG messages from + other nodes might arrive out of order, which confuses the hell out of + the SPTPS code. Another possible scenario is not noticing another node + crashed and restarted because there was no point in time where the node + was seen completely disconnected from *all* nodes; this could result in + using the wrong (old) key. There are probably other scenarios which have + not even been considered yet. Distributed systems are hard. + + When SPTPS got confused by a packet, it used to crash the entire + process; fortunately that was fixed by commit + 2e7f68ad2b51648b89c4b5c61aeb4cec67c2fbbb. However, the error handling + (or lack thereof) leaves a lot to be desired. Currently, when SPTPS + encounters an error when receiving a packet, it just shrugs it off and + continues as if nothing happened. The problem is, sometimes getting + receive errors mean the tunnel is completely stuck and will not recover + on its own. In that case, the node will become unreachable - possibly + indefinitely. + + The goal of this commit is to improve SPTPS error handling by taking + proactive action when an incoming packet triggers a failure, which is + often an indicator that the tunnel is stuck in some way. When that + happens, we simply restart SPTPS entirely, which should make the tunnel + recover quickly. + + To prevent "storms" where two buggy nodes flood each other with invalid + packets and therefore spend all their time negotiating new tunnels, we + limit the frequency at which tunnel restarts happen to ten seconds. + + It is likely this commit will solve the "Invalid KEX record length + during key regeneration" issue that has been seen in the wild. It is + difficult to be sure though because we do not have a full understanding + of all the possible conditions that can trigger this problem. + +commit aa52300b2b6e9d923d6d5b8c95fa500f549620d0 +Author: Etienne Dechamps +Date: Sun May 17 17:51:05 2015 +0100 + + Trivial: make sptps_receive_data_datagram() a little more readable. + + The new code updates variables as stuff is being consumed, so that the + reader doesn't have to do that in his head. + +commit 30e839b0a1810b9cb0a2de2595cef2f8ebb06357 +Author: Guus Sliepen +Date: Sun May 17 18:44:09 2015 +0200 + + Don't send local_address in ADD_EDGE messages if it's AF_UNSPEC. + +commit 23fda4db6d1bb400a97f6d2a07d9b700f9546129 +Author: Sven-Haegar Koch +Date: Sun May 17 05:29:21 2015 +0200 + + Let sockaddr2hostname() handle AF_UNSPEC addresses. + +commit 1e89a63f1638e43dee79afbb18d5f733b27d830b +Author: Etienne Dechamps +Date: Sun May 17 17:09:56 2015 +0100 + + Prevent SPTPS key regeneration packets from entering an UDP relay path. + + Commit 10c1f60c643607d9dafd79271c3475cddf81e903 introduced a mechanism + by which a packet received by REQ_KEY could continue its journey over + UDP. This was based on the assumption that REQ_KEY messages would never + be used for handshake packets (which should never be sent over UDP, + because SPTPS currently doesn't handle lost handshake packets very + well). + + Unfortunately, there is one case where handshake packets are sent using + REQ_KEY: when regenerating the SPTPS key for a pre-established channel. + With the current code, such packets risk getting relayed over UDP. + + When processing a REQ_KEY message, it is impossible for the receiving + end to distinguish between a data SPTPS packet and a handshake packet, + because this information is stored in the type field which is encrypted + with the end-to-end key. + + This commit fixes the issue by making tinc use ANS_KEY for all SPTPS + handshake messages. This works because ANS_KEY messages are never + forwarded using the SPTPS relay mechanisms, therefore they are + guaranteed to stick to TCP. + +commit eecfeadeb4fc70ee002b81c20ba12ba3e3acb843 +Author: Guus Sliepen +Date: Sat May 16 02:01:54 2015 +0200 + + Let sockaddr2str() handle AF_UNSPEC addresses. + +commit 613c121cdceec0199dc4d056857be021ed1d21de +Author: Guus Sliepen +Date: Fri May 15 23:35:46 2015 +0200 + + Try all addresses for the hostname in an invitation URL. + +commit 54a8bd78e3fbe2de4d9daea748643f9c9b5b240e +Author: Guus Sliepen +Date: Fri May 15 23:08:53 2015 +0200 + + Be more liberal accepting ADD_EDGE messages with conflicting local address information. + + If the ADD_EDGE is for one of the edges we own, and if it is not the + same as we actually have, send a correcting ADD_EDGE back. Otherwise, if + the ADD_EDGE contains new information, update our idea of the local + address for that edge. + + If the ADD_EDGE does not contain local address information, then we + never make a correction nor log a warning. + +commit 8028e01100eb40f64da5e50ef33fbf9e3f8099de +Author: Guus Sliepen +Date: Fri May 15 23:01:06 2015 +0200 + + Use AF_UNSPEC instead of AF_UNKNOWN for unspecified local address in add_edge_h(). + + AF_UNKNOWN is reserved for valid addresses that the local node cannot + parse, but remote nodes possibly can. + +commit fd1cff6df23c3f16a46edaff8a52a7212914b2f0 +Author: Guus Sliepen +Date: Fri May 15 00:21:48 2015 +0200 + + Fix receiving UDP packets from tinc 1.0.x nodes. + + In try_mac(), the wrong offsets were used into the packet buffer, + causing the digest verification to always fail. + +commit 44e9f1e1d8d6dbd4625e5458cfffcf6b5168374a +Author: Guus Sliepen +Date: Wed May 13 14:28:28 2015 +0200 + + Fix invitations. + + These were broken due to a change in behaviour of sptps_receive_data() + introduced in commit d237efd325cd7bdd73f5eb111c769470238dce6e. + +commit 7e6b2dd1ea51057b7135139c200d97a9e8f9c9cb +Author: Etienne Dechamps +Date: Sun May 10 19:00:03 2015 +0100 + + Introduce raw TCP SPTPS packet transport. + + Currently, SPTPS packets are transported over TCP metaconnections using + extended REQ_KEY requests, in order for the packets to pass through + tinc-1.0 nodes unaltered. Unfortunately, this method presents two + significant downsides: + + - An already encrypted SPTPS packet is decrypted and then encrypted + again every time it passes through a node, since it is transported + over the SPTPS channels of the metaconnections. This + double-encryption is unnecessary and wastes CPU cycles. + + - More importantly, the only way to transport binary data over + standard metaconnection messages such as REQ_KEY is to encode it + in base64, which has a 33% encoding overhead. This wastes 25% of the + network bandwidth. + + This commit introduces a new protocol message, SPTPS_PACKET, which can + be used to transport SPTPS packets over a TCP metaconnection in an + efficient way. The new message is appropriately protected through a + minor protocol version increment, and extended REQ_KEY messages are + still used with nodes that do not support the new message, as well as + for the intial handshake packets, for which efficiency is not a concern. + + The way SPTPS_PACKET works is very similar to how the traditional PACKET + message works: after the SPTPS_PACKET message, the raw binary packet is + sent directly over the metaconnection. There is one important + difference, however: in the case of SPTPS_PACKET, the packet is sent + directly over the TCP stream completely bypassing the SPTPS channel of + the metaconnection itself for maximum efficiency. This is secure because + the SPTPS packet that is being sent is already encrypted with an + end-to-end key. + +commit d237efd325cd7bdd73f5eb111c769470238dce6e +Author: Etienne Dechamps +Date: Sun May 10 19:28:11 2015 +0100 + + Only read one record at a time in sptps_receive_data(). + + sptps_receive_data() always consumes the entire buffer passed to it, + which is somewhat inflexible. This commit improves the interface so that + sptps_receive_data() consumes at most one record. The goal is to allow + non-SPTPS stuff to be interleaved with SPTPS records in a single TCP + stream. + +commit de14308840a96060d700c93117789e83ec948c01 +Author: Etienne Dechamps +Date: Sun May 10 18:05:19 2015 +0100 + + Rename REQ_SPTPS to SPTPS_PACKET. + + REQ_SPTPS implies the message has an ANS_ counterpart (like REQ_KEY, + ANS_KEY), but it doesn't. Therefore dropping the REQ_ seems more + appropriate, and we add a _PACKET suffix to reduce the likelihood of + naming conflicts. + +commit 10c1f60c643607d9dafd79271c3475cddf81e903 +Author: Etienne Dechamps +Date: Sat May 9 18:09:23 2015 +0100 + + Try to use UDP to relay SPTPS packets received over TCP. + + Currently, when tinc receives a SPTPS packet over TCP via the REQ_KEY + encapsulation mechanism, it forwards it like any other TCP request. This + is inefficient, because even though we received the packet over TCP, + we might have an UDP link with the next hop, which means the packet + could be sent over UDP. + + This commit removes that limitation by making sure SPTPS data packets + received through REQ_KEY requests are not forwarded as-is but passed + to send_sptps_data() instead, thereby using the same code path as if + the packet was received over UDP. + +commit 1296f715b57c88c17299cacadaccdc0be898e0b1 +Author: Etienne Dechamps +Date: Sat May 9 17:54:34 2015 +0100 + + Expose the raw SPTPS send interface from net_packet. + + net_packet doesn't actually use send_sptps_data(); it only uses + send_sptps_data_priv(). In addition, the only user of send_sptps_data() + is protocol_key. Therefore it makes sense to expose + send_sptps_data_priv() directly, and move send_sptps_data() (which is + basically just boilerplate) as a local function in protocol_key. + +commit 8e43a2fc744559956640d3eb9a7a26a945d94fde +Author: Etienne Dechamps +Date: Sun May 10 18:46:47 2015 +0100 + + Use the correct originator node when relaying SPTPS UDP packets. + + Currently, when relaying SPTPS UDP packets, the code uses the direct + sender as the originator, instead of preserving the original source ID. + + This wouldn't cause any issues in most cases because the originator and + the sender are the same in simple one-hop relay chains, but this will + break as soon as there is more than one relay. + +commit 9d223cb7e7f337c6b9707f07e3e9796108a3b597 +Author: Etienne Dechamps +Date: Sun May 10 18:37:30 2015 +0100 + + When relaying, send probes to the destination, not the source. + + This seems to be a typo from c23e50385d9de538af676706596f6508b2ceb01a. + Achievement unlocked: got a one-line commit wrong. + +commit 13f9bc1ff199bea46d3dde391a848f119e2cc0f0 +Author: Etienne Dechamps +Date: Sat Jul 12 16:01:41 2014 +0100 + + Add support for out-of-tree ("VPATH") builds. + + This fixes some issues with the build system when building out of tree. + + With this commit, it is now possible to do the following: + + $ cd /tmp/build + $ /path/to/tinc/configure + $ make + +commit 462e9892ae2765d0c7036005fafe036fd2a9f4f2 +Author: Etienne Dechamps +Date: Sat Jul 12 16:21:32 2014 +0100 + + Remove explicit distribution rules for m4 scripts. + + It turns out Automake is smart enough to include these files in the + distribution by itself. + +commit 362b79176439a2eb643612633aa0ff210a6a4d81 +Author: Guus Sliepen +Date: Sat May 9 15:41:37 2015 +0200 + + Really remove "release-" from the git-derived version string. + +commit b109e8b16488f9bbfdc4aefe0e9b00c4f202e905 +Author: Etienne Dechamps +Date: Sun Jun 29 18:26:55 2014 +0100 + + Use git describe to populate autoconf's VERSION. + + This uses the output of "git describe" directly in configure.ac to + determine the version number to use, instead of hardcoding it. + + With this change, current version information is completely removed + from the codebase itself, and is always fetched on-the-fly from git as + the single source of truth. + + In order to ensure make dist always uses the current version number in + the contents of the packaged configure script as well as the package + name, a dependency is added to the dist target such that autoconf is + always run before dist to regenerate the version number. If this wasn't + the case, make dist would use the version number from when autoconf was + originally run, not the version number that make dist is running from. + That said, errors from that rule are ignored so that people can still + run make dist without a working autoconf. + + In addition, the NEWS check is dropped, as it would then become annoying + because it would force make dist users to always have a line for the + current commit in the NEWS file. + +commit 1c77069064e0cf0e0ddd81bab1b1354a8952fb33 +Author: Pierre Emeriaud +Date: Sat May 9 00:03:51 2015 +0200 + + Fix typo in tincctl help. + +commit 54554cc2765befc2e95fd7fe2fedfd75a94b5926 +Author: Guus Sliepen +Date: Tue May 5 23:05:22 2015 +0200 + + Don't include build-time generated version_git.h in the tarball. + +commit c46bdbde18629f0a0613c776c13a79fea0ec6093 +Author: Guus Sliepen +Date: Tue May 5 23:03:41 2015 +0200 + + Remove "release-" from displayed git version. + + Also make sure that version_git.h is only written to if the "git + describe" command succeeds. + +commit 120e0567cba17eeb57c12a34686fddbbb491b62f +Author: Etienne Dechamps +Date: Sun Jun 29 15:22:10 2014 +0100 + + Use git description as the tinc version. + + Instead of using the hardcoded version number in configure.ac, this + makes tinc use the live version reported by "git describe", + queried on-the-fly during the build process and regenerated for every + build. + + This makes tinc version output more useful, as tinc will now display the + number of commits since the last tag as well as the commit the binary is + built from, following the format described in git-describe(1). + + Here's an example of tincd --version output: + + tinc version release-1.1pre10-48-gc149315 (built Jun 29 2014 15:21:10, protocol 17.3) + + When building directly from a release tag, this will look like the following: + + tinc version release-1.1pre10 (built Jun 29 2014 15:21:10, protocol 17.3) + + (Note that the format is slightly different - because of the way the + tags are named, it says "release-1.1pre10" instead of just "1.1pre10") + + If git describe fails (for example when building from a release + tarball), the build automatically falls back to the autoconf-provided + VERSION macro (i.e. the old behavior). + +commit 95594f47384b60a6f994f0fca6fd9f79b2b283aa +Author: Guus Sliepen +Date: Fri Apr 24 23:51:29 2015 +0200 + + Fix typo 0fda572c88d02b0b200ef81d72cc4da594fa0e38 that prevented some errors from being logged. + +commit 0fda572c88d02b0b200ef81d72cc4da594fa0e38 +Author: Guus Sliepen +Date: Fri Apr 24 23:43:58 2015 +0200 + + Don't log an error message when receiving a TERMREQ. + +commit ea1e815223e99f3747f94cf0d10eb06e52f70b21 +Author: Guus Sliepen +Date: Fri Apr 24 23:43:19 2015 +0200 + + Fix a possible segmentation fault during key upgrades. + + read_rsa_public_key() was bailing out early if the given node already has an Ed25519 key, and + returned true even though c->rsa was NULL. The early bailout code isn't necessary anymore, so just + remove it. + +commit 2059814238320b761fb93608b7f8a114de861302 +Author: Guus Sliepen +Date: Fri Apr 24 23:40:20 2015 +0200 + + Allow one-sided upgrades to Ed25519. + + This deals with the case where one node knows the Ed25519 key of another node, but not the other + way around. This was blocked by an overly paranoid check in id_h(). The upgrade_h() function already + handled this case, and the node that already knows the other's Ed25519 key checks that it has not + been changed, otherwise the connection will be aborted. + +commit 3def9d2ad88a9015af4c42aac329e0e2a80679f7 +Merge: 95921696 0c010ff9 +Author: Guus Sliepen +Date: Sun Apr 12 15:43:05 2015 +0200 + + Merge remote-tracking branch 'dechamps/wintapver' into 1.1 + +commit 95921696a49d1eff058880c90a80efd208de959d +Merge: f500a3d4 7027bba5 +Author: Guus Sliepen +Date: Sun Apr 12 15:42:48 2015 +0200 + + Always call res_init() before getaddrinfo(). + + Unfortunately, glibc assumes that /etc/resolv.conf is a static file that + never changes. Even on servers, /etc/resolv.conf might be a dynamically + generated file, and we never know when it changes. So just call + res_init() every time, so glibc uses up-to-date nameserver information. + + Conflicts: + src/have.h + src/net.c + src/net_setup.c + +commit f500a3d4e6e51ea1d88235e89e494ecb8f71ba5b +Merge: 41798146 89715454 +Author: Guus Sliepen +Date: Sun Apr 12 15:36:50 2015 +0200 + + Merge remote-tracking branch 'dechamps/windevice' into 1.1 + +commit 417981462a2dde7800768eb58cf8f4e5238d4ad7 +Merge: 11effab8 176ee015 +Author: Guus Sliepen +Date: Sun Apr 12 15:35:50 2015 +0200 + + Merge remote-tracking branch 'dechamps/winmtu' into 1.1 + +commit 11effab85b6b278ccf0ac3ba52a12bbca3e3dcc5 +Merge: 9e71b74e 43b41e90 +Author: Guus Sliepen +Date: Sun Apr 12 15:35:37 2015 +0200 + + Merge remote-tracking branch 'dechamps/fsckwin' into 1.1 + +commit 9e71b74ed83c51e0b35114a4f153b62b54fd3702 +Merge: 76a9be5b fa432426 +Author: Guus Sliepen +Date: Sun Apr 12 15:34:50 2015 +0200 + + Merge remote-tracking branch 'dechamps/staticfix' into 1.1 + +commit 0c010ff9fe50b4046b5c7977bafac3e74037f075 +Author: Etienne Dechamps +Date: Sun Mar 15 18:30:39 2015 +0000 + + Warn about performance if using TAP-Windows >=9.21. + + Testing has revealed that the newer series of Windows TAP drivers (i.e. + 9.0.0.21 and later, also known as NDIS6, tap-windows6) suffer from + serious performance issues in the write path. Write operations seems to + take a very long time to complete, resulting in massive packet loss even + for throughputs as low as 10 Mbit/s. + + I've made some attempts to alleviate the problem using parellelism. By + using custom code that allows up to 256 write operations at the same + time the results are much better, but it's still about 2 times worse + than the traditional 9.0.0.9 driver. + + We need to investigate more and file a bug against tap-windows6, but in + the mean time, let's inform the user that he might not want to use the + latest drivers. + +commit 0f328d9d2853ca723ff3205f39bb22207d21a932 +Author: Etienne Dechamps +Date: Sun Mar 15 18:18:04 2015 +0000 + + Log TAP-Windows driver version on startup. + + This is generally useful. We've seen issues that are specific to some + version of these drivers (especially the newer 9.0.0.21 version), so + it's relevant to log it, especially since that means it will be + copy-pasted by people posting their logs asking for help. + +commit 7027bba541eca3e34f689bebd6f6e408ba4e7710 +Author: Etienne Dechamps +Date: Sun Mar 15 18:01:03 2015 +0000 + + Increase the ReplayWindow default from 16 to 32. + + As a rule, it seems reasonable to make sure that tinc operates correctly + on at least 1G links, since these are pretty common. However, I have + observed replay window issues when operating at speeds of 600 Mbit/s and + above, especially when the receiving end is a Windows system (not sure + why). This commit increases the default so that this won't occur on + fresh setups. + +commit 94f49a163aa570ea272bf3bbd7734187098d88b7 +Author: Etienne Dechamps +Date: Sun Mar 15 17:50:53 2015 +0000 + + Set the default for UDPRcvBuf and UDPSndBuf to 1M. + + It may not be obvious, but due to the way tinc operates (single-threaded + control loop with no intermediate packet buffer), UDP send and receive + buffers can have a massive impact on performance. It is therefore of + paramount importance that the buffers be large enough to prevent packet + drops that could occur while tinc is processing a packet. + + Leaving that value to the OS default could be reasonable if we weren't + relying on it so much. Instead, this makes performance somewhat + unpredictable. + + In practice, the worst case scenario occurs on Windows, where Microsoft + had the brillant idea of making the buffers 8K in size by default, no + matter what the link speed is. Considering that 8K flies past in a + matter of microseconds on >1G links, this is extremely inappropriate. On + these systems, changing the buffer size to 1M results in *obscene* + raw throughput improvements; I have observed a 10X jump from 40 Mbit/s + to 400 Mbit/s on my system. + + In this commit, we stop trusting the OS to get this right and we use a + fixed 1M value instead, which should be enough for <=1G links. + +commit 89715454c083aaeb4dc73340f2d0ab9a3d9503e0 +Author: Etienne Dechamps +Date: Sat Mar 14 18:19:22 2015 +0000 + + Fix Windows device asynchronous write behavior. + + Write operations to the Windows device do not necessarily complete + immediately; in fact, with the latest TAP-Win32 drivers, this never + seems to be the case. + + write_packet() does not handle that case correctly, because the + OVERLAPPED structure and the packet data go out of scope before the + write operation completes, resulting in race conditions. + + This commit fixes the issue by making sure these data structures are + kept in global scope, and by dropping any packets that may arrive while + the previous write operation is still pending. + +commit 675142c7d88c9d325c0ca0bc5761072a5d810c75 +Author: Etienne Dechamps +Date: Sat Mar 14 17:27:14 2015 +0000 + + When disabling the Windows device, wait for pending reads to complete. + + On Windows, when disabling the device, tinc uses the CancelIo() to + cancel the pending read operation, and then proceeds to delete the event + handle immediately. + + This assumes that CancelIo() blocks until the pending read request is + completely torn down and no references to it remain. While MSDN is not + completely clear on that subject, it does suggest that this is not the + case: + + http://msdn.microsoft.com/en-us/library/windows/desktop/aa363791.aspx + If the function succeeds [...] the cancel operation for all pending + I/O operations issued by the calling thread for the specified file + handle was successfully requested. + + This implies that cancellation was merely "requested", and that there + are no guarantees as to the state of the operation when CancelIo() + returns. Therefore, care must be taken not to close event handles + prematurely. + + While I'm no aware of this potential race condition causing any problems + in practice, I don't want to take any chances. + +commit 176ee015267d87ff4fd4d2615e9f5ac978116171 +Author: Etienne Dechamps +Date: Sun Mar 15 10:00:56 2015 +0000 + + Make sure packet header structures are correctly packed on Windows. + + Modern versions of GCC handle structure packing differently when + compiling for Windows, as reported in the following GCC bug report: + + http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52991 + + In practice, this affects tinc because it uses packed structs as a + convenient way to populate packet headers. "struct ip" is especially + affected - on Linux, sizeof(struct ip) returns 20 as expected, while on + Windows, it returns 24 because of the broken alignment. + + This in turn completely breaks code that has to populate an IP header. + Specifically, this breaks route_ipv4_unreachable() which is responsible, + among other things, for the generation of ICMP Fragmentation Needed + messages. On Windows, these messages are corrupted beyond hope because + of this alignment issue. For TCP connections that are established + before tinc obtains a fix on the MTU (and thus are not MSS clamped), + this can result in massive disruption. + + This commit fixes the issue by forcing GCC to use standard alignment + for all packed structures in the tinc codebase instead of the MSVC + alignment. + +commit 43b41e9095e6261c53da1ae46117d018296c3b68 +Author: Etienne Dechamps +Date: Sat Mar 14 16:17:32 2015 +0000 + + Fix HAVE_DECL_RES_INIT conditionals. + + HAVE_DECL_RES_INIT is generated using AC_CHECK_DECLS. tinc checks this + symbol using #ifdef, which is wrong because (according to autoconf docs) + the symbol is always defined, it's just set to zero if the check failed. + + This broke the Windows build starting from + 0b310bf406dbe58afe37fa31156b9ea47599d7be, because it introduced this + conditional in code that's not excluded from the Windows build. + +commit 4989362300f800a6f407508f1e0127867cf80cba +Author: Etienne Dechamps +Date: Sat Mar 14 16:07:54 2015 +0000 + + Fix invalid getuid() call on Windows. + + This is breaking the Windows build. Regression was introduced in + 268e3ffca7b45cfc736e1bc9bec7a113c6c45701. + +commit fa432426df7e2e364e310ab4bac28e60f732a3c9 +Author: Etienne Dechamps +Date: Sat Mar 14 14:04:50 2015 +0000 + + Don't send UDP probes past static relays. + + Ironically, commit 0f8e2cc78cafe47a087d3fc9b480551b841aeb30 introduced + a regression on its own, since it accidently removed a return statement + that prevented try_tx_sptps() from sending UDP/MTU probes to nodes that + are past static relays. + +commit 76a9be5bce43a1a7363c670882f5315c824c903c +Author: Etienne Dechamps +Date: Sun Mar 8 20:17:27 2015 +0000 + + Throttle the rate of MTU_INFO messages. + + This makes sure MTU_INFO messages are only sent at the maximum rate of + 5 per second (by default). As usual with these "probe" mechanisms, the + rate of these messages cannot be higher than the rate of data packets + themselves, since they are sent from the RX path. + +commit 467397f25d3a99ec1a97d4419502c37b64276f49 +Author: Etienne Dechamps +Date: Sun Mar 8 19:54:44 2015 +0000 + + Throttle the rate of UDP_INFO messages. + + This makes sure UDP_INFO messages are only sent at the maximum rate of + 5 per second (by default). As usual with these "probe" mechanisms, the + rate of these messages cannot be higher than the rate of data packets + themselves, since they are sent from the RX path. + +commit b1421b919090351e885ed3d06df67fb2eb69e765 +Author: Etienne Dechamps +Date: Sun Mar 8 18:54:50 2015 +0000 + + Add MTU_INFO protocol message. + + In this commit, nodes use MTU_INFO messages to provide MTU information. + + The issue this code is meant to address is the non-trivial problem of + finding the proper MTU when UDP SPTPS relays are involved. Currently, + tinc has no idea what the MTU looks like beyond the first relay, and + will arbitrarily use the first relay's MTU as the limit. This will fail + miserably if the MTU decreases after the first relay, forcing relays to + fall back to TCP. More generally, one should keep in mind that relay + paths can be arbitrarily complex, resulting in packets taking "epic + journeys" through the graph, switching back and forth between UDP (with + variable MTUs) and TCP multiple times along the path. + + A solution that was considered consists in sending standard MTU probes + through the relays. This is inefficient (if there are 3 nodes on one + side of relay and 3 nodes on the other side, we end up with 3*3=9 MTU + discoveries taking place at the same time, while technically only + 3+3=6 are needed) and would involve eyebrow-raising behaviors such as + probes being sent over TCP. + + This commit implements an alternative solution, which consists in + the packet receiver sending MTU_INFO messages to the packet sender. + The message contains an MTU value which is set to maximum when the + message is originally sent. The message gets altered as it travels + through the metagraph, such that when the message arrives to the + destination, the MTU value contained in the message can be used to + send packets while making sure no relays will be forced to fall back to + TCP to deliver them. + + The operating principles behind such a protocol message are similar to + how the UDP_INFO message works, but there is a key difference that + prevents us from simply reusing the same message: the UDP_INFO message + only cares about relay-to-relay links (i.e. it is sent between static + relays and the information it contains only makes sense between two + adjacent static relays), while the MTU_INFO cares about the end-to-end + MTU, including the entire relay path. Therefore, UDP_INFO messages stop + when they encounter static relays, while MTU_INFO messages don't stop + until they get to the original packet sender. + + Note that, technically, the MTU that is obtained through this mechanism + can be slightly pessimistic, because it can be lowered by an + intermediate node that is not being used as a relay. Since nodes have no + way of knowing whether they'll be used as dynamic relays or not (and + have no say in the matter), this is not a trivial problem. That said, + this is highly unlikely to result in noticeable issues in realistic + scenarios. + +commit 9bb230f30f665779eb89dcce077a15360ec50be1 +Author: Etienne Dechamps +Date: Sat Jan 3 17:46:33 2015 +0000 + + Add UDP_INFO protocol message. + + In this commit, nodes use UDP_INFO messages to provide UDP address + information. The basic principle is that the node that receives packets + sends UDP_INFO messages to the node that's sending the packets. The + message originally contains no address information, and is (hopefully) + updated with relevant address information as it gets relayed through the + metagraph - specifically, each intermediate node will update the message + with its best guess as to what the address is while forwarding it. + + When a node receives an UDP_INFO message, and it doesn't have a + confirmed UDP tunnel with the originator node, it will update its + records with the new address for that node, so that it always has the + best possible guess as to how to reach that node. This applies to the + destination node of course, but also to any intermediate nodes, because + there's no reason they should pass on the free intel, and because it + results in nice behavior in the presence of relay chains (multiple nodes + in a path all trying to reach the same destination). + + If, on the other hand, the node does have a confirmed UDP tunnel, it + will ignore the address information contained in the message. + + In all cases, if the node that receives the message is not the + destination node specified in the message, it will forward the message + but not before overriding the address information with the one from its + own records. If the node has a confirmed UDP tunnel, that means the + message is updated with the address of the confirmed tunnel; if not, + the message simply reflects the records of the intermediate node, which + just happen to be the contents of the UDP_INFO message it just got, so + it's simply forwarded with no modification. + + This is similar to the way ANS_KEY messages are currently + overloaded to provide UDP address information, with two differences: + + - UDP_INFO messages are sent way more often than ANS_KEY messages, + thereby keeping the address information fresh. Previously, if the UDP + situation were to change after the ANS_KEY message was sent, the + sender would virtually never get the updated information. + + - Once a node puts address information in an ANS_KEY message, it is + never changed again as the message travels through the metagraph; in + contrast, UDP_INFO messages behave the opposite way, as they get + rewritten every time they travel through a node with a confirmed UDP + tunnel. The latter behavior seems more appropriate because UDP tunnel + information becomes more relevant as it moves closer to the + destination node. The ANS_KEY behavior is not satisfactory in some + cases such as multi-layered graphs where the first hop is located + before a NAT. + + Ultimately, the rationale behind this whole process is to improve UDP + hole punching capabilities when port translation is in effect, and more + generally, to make tinc more reliable in (very) hostile network + conditions (such as multi-layered NAT). + +commit 6568cffd52d4803effaf52a9bb9c98d69cf7922a +Author: Guus Sliepen +Date: Sat Mar 14 12:02:29 2015 +0000 + + --syslog and --logfile are mutually exclusive. + +commit 15ad628f06895175d7e629ce0188805dc00159fd +Author: Guus Sliepen +Date: Sat Mar 14 12:02:06 2015 +0000 + + Fix the case where we detach and use --logfile. + +commit 04fc19112da5e7fcefefcf6e490987cdcfb6f620 +Merge: f9ecaa10 19d16e40 +Author: Guus Sliepen +Date: Sat Mar 14 11:45:55 2015 +0000 + + Merge remote-tracking branch 'seehuhn/1.1' into 1.1 + +commit f9ecaa10768926302f24a70975f36e360b51c8ce +Merge: c23e5038 2e7f68ad +Author: Guus Sliepen +Date: Sat Mar 14 11:44:38 2015 +0000 + + Merge remote-tracking branch 'dechamps/sptpsabort' into 1.1 + +commit 19d16e40ccfb39461eda5336f4e754e10a640aba +Author: Jochen Voss +Date: Fri Mar 13 11:05:22 2015 +0000 + + Add a new --syslog option for tincd. + + This commit adds a new command line option for tincd which allows to + use tincd in non-detached mode with log messages still going to + syslog. The motivation for this change is to ease use of tincd + in Docker containers. + +commit 2e7f68ad2b51648b89c4b5c61aeb4cec67c2fbbb +Author: Etienne Dechamps +Date: Sun Mar 8 17:32:39 2015 +0000 + + Don't abort() willy-nilly in SPTPS code. + + If receive_handshake() or the receive_record() user callback returns an + error, sptps_receive_data_datagram() crashes the entire process. This is + heavy-handed, makes tinc very brittle to certain failures (i.e. + unexpected packets), and is inconsistent with the rest of SPTPS code. + +commit c23e50385d9de538af676706596f6508b2ceb01a +Author: Etienne Dechamps +Date: Sun Mar 8 14:32:01 2015 +0000 + + Fix UDP/MTU discovery in intermediate SPTPS UDP relays. + + Refactoring commit 81578484dc74fd92f1b01f71f882016f120ab1de seems to + have introduced a regression as it moved discovery code away from + send_sptps_data_priv() and within send_packet(). The issue is, + send_packet() is not called when the node is simply relaying an UDP + SPTPS packet: indeed, send_sptps_data_priv() is called directly from + handle_incoming_vpn_data() in that case. + + As a result, try_tx_sptps() is not called in the relaying case, which in + practice means that a relay doesn't initiate UDP/MTU discovery with the + next relay (unless some other activity compels it to do so). This can + result in packets getting sent over TCP instead of UDP from the relay. + +commit 0f8e2cc78cafe47a087d3fc9b480551b841aeb30 +Author: Etienne Dechamps +Date: Sun Mar 8 14:20:15 2015 +0000 + + Fix dynamic UDP SPTPS relaying. + + Refactoring commit 0e653260478005eb7c824a9a1a3df04f39938cd6 broke UDP + SPTPS relaying by accidently removing try_tx_sptps() logic related to + establishing connectivity to so-called "dynamic" relays (i.e. relays + that are not specified by IndirectData configuration statements, but + are used on-the-fly to circumvent loss of direct UDP connectivity). + + Specifically, the TX path was not trying to establish a tunnel to + dynamic relays (nexthop) anymore. This meant that MTU was not being + discovered with dynamic relays, which basically meant that all packets + being sent to dynamic relays went over TCP, thereby defeating the whole + purpose of SPTPS UDP relaying. + + Note that this bug could easily go unnoticed if a tunnel was established + with the dynamic tunnel for some other reason (i.e. exchanging actual + data packets with the relay node). + +commit 537c3528863c4736e877c4d1b6c6579940e6df5d +Author: xentec +Date: Tue Feb 17 04:02:35 2015 +0100 + + Fix compile errors introduced in cfe9285adf391ab66faeb5def811fe08e47a221a + + Compiling with `--disable-legacy-protocol` resulted in failure caused by the missing exclusion of some symbols in net_packet.c. + +commit cffcaf966b65a61943a00120f1ec5c868c917c1f +Author: Guus Sliepen +Date: Mon Feb 16 08:42:30 2015 +0100 + + Suppress warnings about parsing Ed25519 keys when they are not present. + +commit 833a8a048b22612cd12d703d55a71448b7179b4a +Author: Guus Sliepen +Date: Mon Feb 16 08:26:49 2015 +0100 + + Document that --force should precede commands. + +commit 85000a30ca68d3c8e9a98eb9537f4d1505bd849e +Author: Sven-Haegar Koch +Date: Tue Feb 10 01:17:12 2015 +0100 + + Fixed variables.test testsuite after 'Make "tinc add" idempotent.' change. + +commit 4b2ddded2c8ae1a1a5930637552eeb48f30d6530 +Author: Guus Sliepen +Date: Mon Feb 9 15:23:59 2015 +0100 + + Make "tinc add" idempotent. + + When calling "tinc add" multiple times with the same variable and value, + make sure only one unique line is added to the configuration file. + +commit 0b310bf406dbe58afe37fa31156b9ea47599d7be +Author: Guus Sliepen +Date: Mon Feb 9 15:16:36 2015 +0100 + + Always call res_init() before getaddrinfo(). + + Unfortunately, glibc assumes that /etc/resolv.conf is a static file that + never changes. Even on servers, /etc/resolv.conf might be a dynamically + generated file, and we never know when it changes. So just call + res_init() every time, so glibc uses up-to-date nameserver information. + +commit 268e3ffca7b45cfc736e1bc9bec7a113c6c45701 +Author: Guus Sliepen +Date: Thu Jan 15 22:57:56 2015 +0100 + + Add the "fsck" command to the CLI. + + This will report possible problems in the configuration files, and in + some cases offers to fix them. + + The code is far from perfect yet. It expects keys to be in their default + locations, it doesn't check for Public/PrivateKey[File] statemetns yet. + It also does not correctly handle Ed25519 public keys yet. + +commit a95e182d9ca54960383bfe3950b2b798e1f24f9e +Author: Guus Sliepen +Date: Mon Jan 12 14:43:32 2015 +0100 + + Improve packet source detection. + + When no UDP communication has been done yet, tinc establishes a guess + for the UDP address+port of each node. However, when there are multiple nodes + behind a NAT, tinc will guess the exact same address+port combination + for them, because it doesn't know about the NAT mappings yet. So when + receiving a packet, don't trust that guess unless we have confirmed UDP + communication. + + This ensures try_harder() is called in such cases. However, this + function was actually very inefficient, trying to verify packets + multiple times for nodes with multiple edges. Only call try_mac() at + most once per node. + +commit ae5b56c03d1e1af7561d7f1d1d8a333c3a9691ff +Author: Guus Sliepen +Date: Sun Jan 11 17:44:50 2015 +0100 + + Send gratuitous type 2 probe replies. + + If we receive any traffic from another node, we periodically send back a + gratuitous type 2 probe reply with the maximum received packet length. + On the other node, this causes the udp and perhaps mtu probe timers to + be reset, so it does not need to send a probe request. Gratuitous probe + replies from another node also count as received traffic for this + purpose, so for nodes that also have a meta-connection, UDP keepalive + packets in principle can now solely be type 2 replies. This reduces the + amount of probe traffic even more. + + To work, gratuitous replies should be sent slightly more often than + udp_discovery_keepalive_interval, so probe requests won't be triggered. + This also means that the timer resolution must be smaller than the + difference between the two, and at the moment it's kind of a hack. + +commit 7b76b7ac35b49b8a94ad91c432886a0a54e144d1 +Author: Guus Sliepen +Date: Sun Jan 11 16:14:05 2015 +0100 + + Send the size of the largest recently received packets in type 2 probe replies. + +commit 79b6adb489dde4ae92207ae7b9146f4e141c946c +Author: Guus Sliepen +Date: Sun Jan 11 16:12:57 2015 +0100 + + Move UDP probe reply code into its own function. + + This reduces the level of indentation, and prepares for sending gratuitous type 2 probe replies. + +commit f0afde0467443969eb408090d6b8ee542768ee33 +Author: Guus Sliepen +Date: Sun Jan 11 16:10:58 2015 +0100 + + Keep track of the largest UDP packet size received from a node. + +commit d63941593736fbf268f2770d42e7f3f6a2132fae +Author: Guus Sliepen +Date: Sun Jan 11 15:38:56 2015 +0100 + + Move detection of PMTU decrease to try_mtu(). + + When we have fixed the PMTU, n->mtuprobes == -1. When we send MTU probes + when mtuprobes == -1, decrease mtuprobes, and reset it back to -1 in + mtu_probe_h(). If mtuprobes < -1, send MTU probes every second, until + mtuprobes <= -4, in which case we will restart MTU discovery. + +commit e97e9b22cb6061070611212a06756fb493846955 +Author: Guus Sliepen +Date: Sun Jan 11 14:44:27 2015 +0100 + + Send MTU probes only once every PingInterval. + +commit 088b5fd9ee6d5f566e8726eae861cbc7cd832b17 +Author: Guus Sliepen +Date: Sun Jan 11 14:44:15 2015 +0100 + + Remove RTT and packet loss estimation code. + + This is not working at all anymore. Just remove it, and we'll do another + attempt at RTT, bandwidth and packet loss estimation after the new + probing code stabilizes. + +commit ce7079f4af3157eaef514d6d160933a016b2ab62 +Author: Guus Sliepen +Date: Sun Jan 11 13:53:16 2015 +0100 + + Only send small packets during UDP probes. + + We are trying to decouple UDP probing from MTU probing, so only send + very small packets during UDP probing. This significantly reduces the + amount of traffic sent (54 to 67 bytes per probe instead of 1500 bytes). + + This means the MTU probing code takes over sending PMTU sized probes, + but this commit does not take care of detecting PMTU decreases. + +commit e4077c00c6fead63467d296c89d5afc2860e2935 +Author: Guus Sliepen +Date: Sun Jan 11 13:51:55 2015 +0100 + + Immediately send our key when a meta-connection is established. + + This is what 1.0 does, and speeds up the UDP probing. + +commit eb7a0db18ea71a44999d6a37b4b179dac0ed9bc7 +Author: Guus Sliepen +Date: Sun Jan 11 13:31:01 2015 +0100 + + Always keep UDP mappings alive for nodes that also have a meta-connection. + + This is necessary for assisting with UDP hole punching. But we don't + need to know the PMTU for this, so only send UDP probes. + +commit 545ecb339654573b3ee91bffb45c8282154885c6 +Author: Guus Sliepen +Date: Sun Jan 11 01:52:37 2015 +0100 + + Fix segfault when sptps_test cannot open the key files. + +commit 69d4ccc43781152dc90521b3f517b0d9588ae207 +Author: Etienne Dechamps +Date: Tue Dec 30 09:56:30 2014 +0000 + + Fix typo in logging statement. + + This was introduced in cfe9285adf391ab66faeb5def811fe08e47a221a. + +commit 6fcfe763aa54e0522e726dc088b23d24899794d8 +Author: Guus Sliepen +Date: Sat Jan 10 23:58:35 2015 +0100 + + Don't send probe replies if we don't have the other's key. + + This can happen with the legacy protocol. Don't try to send anything + back in this case, otherwise it will be sent via TCP, which is silly. + +commit f3801cb54311da2c30cbe27cd66559a2ea5daa91 +Author: Guus Sliepen +Date: Sat Jan 10 23:52:23 2015 +0100 + + Proactively send our own key when we request another node's key. + +commit c26bb47af130d48d003afd29af4d7ea6ad0538c5 +Author: Guus Sliepen +Date: Sat Jan 10 23:33:55 2015 +0100 + + Fix size of type 2 probe replies. + + Type 2 replies should be as small as possible. The minimum payload size + for probe packets is 14 bytes, otherwise they won't be recognized as + such. + +commit 0209f12d27d29f3aedc09b228bd289305851c75d +Author: Guus Sliepen +Date: Sat Jan 10 23:00:51 2015 +0100 + + Correctly estimate the initial MTU for legacy packets. + +commit 0e653260478005eb7c824a9a1a3df04f39938cd6 +Author: Guus Sliepen +Date: Sat Jan 10 22:28:47 2015 +0100 + + Try to clarify the new code in net_packet.c a bit. + + Mainly by trying to reduce complex if statements, by splitting try_tx() into try_tx_legacy() and + try_tx_sptps(), since they don't share a lot of code. + +commit 6056f1c13bb37bf711dff9c25a6eaea99f14d31f +Author: Guus Sliepen +Date: Sat Jan 10 22:26:33 2015 +0100 + + Remember whether we sent our key to another node. + + In tinc 1.0.x, this was tracked in node->inkey, however in tinc 1.1 we have an abstraction layer for + the legacy cipher and digest, and we don't keep an explicit copy of the key around. We cannot use + cipher_active() or digest_active(), since it is possible to set both to the null algorithm. So add a bit to + node_status_t. + +commit f1f2df07387bc48a3b165c85a0493ff2774de737 +Author: Guus Sliepen +Date: Sun Jan 4 16:00:02 2015 +0100 + + Use global "now" in try_udp() and try_mtu(). + +commit b737103a9187e0191dbc1995da3399ab3dbcdc66 +Author: Guus Sliepen +Date: Sun Jan 4 14:19:23 2015 +0100 + + Use void pointers for opaque data blobs in the SHA512 code. + +commit 4b42518813de7459a1fb264fe9ddfaf066ecc22b +Author: Guus Sliepen +Date: Sun Jan 4 14:15:35 2015 +0100 + + Fix indentation and some whitespace issues. + +commit 07108117ceddaff0654f9def703e717c002f3e2d +Author: Etienne Dechamps +Date: Sat Jan 3 10:05:57 2015 +0000 + + Use a different UDP discovery interval if the tunnel is established. + + This introduces a new configuration option, + UDPDiscoveryKeepaliveInterval, which is used as the UDP discovery + interval once the UDP tunnel is established. The pre-existing option, + UDPDiscoveryInterval, is therefore only used before UDP connectivity + is established. + + The defaults are set so that tinc sends UDP pings more aggressively + if the tunnel is not established yet. This is appropriate since the + size of probes in that scenario is very small (16 bytes). + +commit 06345f89b9a1e9acaf74cbbf896559b4286c102e +Author: Etienne Dechamps +Date: Thu Jan 1 16:59:45 2015 +0000 + + Recalculate and resend MTU probes if they are too large for the system. + + Currently, if a MTU probe is sent and gets rejected by the system + because it is too large (i.e. send() returns EMSGSIZE), the MTU + discovery algorithm is not aware of it and still behaves as if the probe + was actually sent. + + This patch makes the MTU discovery algorithm recalculate and send a new + probe when this happens, so that the probe "slot" does not go to waste. + +commit f89319f9815da5ece8e96f1a2a777fb6d2e31c33 +Author: Etienne Dechamps +Date: Wed Dec 31 16:21:08 2014 +0000 + + Fine-tune the MTU discovery multiplier for the maxmtu < MTU case. + + The original multiplier constant for the MTU discovery algorithm, 0.97, + assumes a somewhat pessmistic scenario where we don't get any help from + the OS - i.e. maxmtu never changes. This can happen if IP_MTU is not + usable and the OS doesn't reject overly large packets. + + However, in most systems the OS will, in fact, contribute to the MTU + discovery process. In these situations, an actual MTU equal to maxmtu + is quite likely (as opposed to the maxmtu = 1518 case where that is + highly unlikely, unless the physical network supports jumbo frames). + It therefore makes sense to use a multiplier of 1 - that will make the + first probe length equal to maxmtu. + + The best results are obtained if the OS supports the getsockopt(IP_MTU) + call, and its result is accurate. In that case, tinc will typically fix + the MTU after one single probe(!), like so: + + Using system-provided maximum tinc MTU for foobar (1.2.3.4 port 655): 1442 + Sending UDP probe length 1442 to foobar (1.2.3.4 port 655) + Got type 2 UDP probe reply 1442 from foobar (1.2.3.4 port 655) + Fixing MTU of foobar (1.2.3.4 port 655) to 1442 after 1 probes + +commit bce17c83e871cb8a8c9158045eaf13f1be4b3d13 +Author: Etienne Dechamps +Date: Wed Dec 31 16:12:11 2014 +0000 + + Add IP_MTU-based maxmtu estimation. + + Linux provides a getsockopt() option, IP_MTU, to get the kernel's best + guess at a connection MTU. In practice, it seems to return the MTU of + the physical interface the socket is using. + + This patch uses this option to initialize maxmtu to a better value when + MTU discovery starts. + + Unfortunately, this is not supported on Windows. Winsock has options + such as SO_MAX_MSG_SIZE, SO_MAXDG and SO_MAXPATHDG but they seem useless + as they always return absurdly large values (typically, 65507), as + confirmed by http://support.microsoft.com/kb/822061/ + +commit c1532035e2850dc4ec0eb22a6d51208e3128eb94 +Author: Etienne Dechamps +Date: Wed Dec 31 09:26:14 2014 +0000 + + Don't send MTU probes smaller than 512 bytes. + + If MTU discovery comes up with an MTU smaller than 512 bytes (e.g. due + to massive packet loss), it's pretty much guaranteed to be wrong. Even + if it's not, most Internet applications assume the MTU will be at least + 512, so fixing the MTU to a small value is likely to cause trouble + anyway. + + This also makes the discovery algorithm converge even faster, since the + interval it has to consider is smaller. + +commit 172cbe6771fd3b98233f71e42ac9c9407d534568 +Author: Etienne Dechamps +Date: Tue Dec 30 17:02:38 2014 +0000 + + Adjust MTU probe counts. + + The recently introduced new MTU discovery algorithm converges much + faster than the previous one, which allows us to reduce the number + of probes required before we can confidently fix the MTU. This commit + reduces the number of initial discovery probes from 90 to 20. With the + new algorithm this is more than enough to get to the precise (byte-level + accuracy) MTU value; in cases of packet loss or weird MTU values for + which the algorithm is not optimized, we should get close to the actual + value, and then we rely on MTU increase detection (steady state probes) + to fine-tune it later if the need arises. + + This patch also triggers MTU increase detection even if the MTU we have + is off by only one byte. Previously we only did that if it was off by at + least 8 bytes. Considering that (1) this should happen less often, + (2) restarting MTU discovery is cheaper than before and (3) having MTUs + that are subtly off from their intended values by just a few bytes + sounds like trouble, this sounds like a good idea. + +commit 24d28adf64934c8d726959e25dce8c10dbd10d1f +Author: Etienne Dechamps +Date: Tue Dec 30 16:34:48 2014 +0000 + + Use a smarter algorithm for choosing MTU discovery probe sizes. + + Currently, tinc uses a naive algorithm for choosing MTU discovery probe + sizes, picking a size at random between minmtu and maxmtu. + + This is of course suboptimal - since the behavior of probes is + deterministic (assuming no packet loss), it seems likely that using a + non-deterministic discovery algorithm will not yield the best results. + Furthermore, the randomness introduces a lot of variation in convergence + times. + + The random solution also suffers from pathological cases - since it's + using a uniform distribution, it doesn't take into account the fact that + it's often more interesting to send small probes rather than large ones, + because getting replies is the only way we can make progress (assuming + the worst case scenario in which the OS doesn't know anything, therefore + keeping maxmtu constant). This can lead to absurd situations where the + discovery algorithm is close to the real MTU, but can't get to it + because the random number generator keeps generating numbers that are + past it. + + The algorithm implemented in this patch aims to improve on the naive + random algorithm. It is organized around "cycles" of 8 probes; the sizes + of the probes decrease as we go through the cycle, thus making sure the + algorithm can cover lots of ground quickly (in case we're far from + actual MTU), but also examining the local area (in case we're close to + actual MTU). Using cycles ensures that the algorithm will "go back" to + large probes to better cover the new interval and to protect against + packet loss. + + For the probe size itself, various mathematical models were simulated in + an attempt to find the one that converges the fastest; it has been + determined that using an exponential based on the size of the remaining + interval was the most effective option. The exponential is adjusted with + a magic multiplier fine-tuned to make tinc jump to the "most + interesting" (i.e. 1400+) section as soon as discovery starts. + + Simulations indicate that assuming no packet loss and no help from the + OS (i.e. maxmtu stays constant), this algorithm will typically converge + to the *exact* MTU value in less than 10 probes, and will get within 8 + bytes in less than 5 probes, for actual MTUs between 1417 and ~1450 + (which is the range the algorithm is fine-tuned for). In contrast, the + previous algorithm gives results all over the place, sometimes taking + 30+ probes to get in the ballpark. Because of the issues with the + distribution, the previous algorithm sometimes never gets to the precise + MTU value within any reasonable amount of time - in contrast, the new + algorithm will always get to the precise value in less than 30 probes, + even if the actual MTU is completely outside the optimized range. + +commit c22560ae3283a8f5f12eee8ee4dcaa5e65ee8cf9 +Author: Etienne Dechamps +Date: Tue Dec 30 10:47:56 2014 +0000 + + Remove bandwidth estimation code. + + tinc bandwidth estimation has always been quite unreliable (at least in + my experience), but there's no chance of it working anymore since the + last changes to MTU discovery code, because packets are not sent in + batches of three anymore. + + This commit removes the dead code - fortunately, nothing depends on this + estimation (it's not even shown in node info). We probably need be + smarter about this if we do want this estimation back. + +commit 1b972f22733dc979568bc0ad8ebe0c711887e447 +Author: Etienne Dechamps +Date: Tue Dec 30 10:16:32 2014 +0000 + + Send one MTU probe at a time. + + Currently, tinc sends MTU probes in batches of three every second. This + commit changes that to send one packet every 333 milliseconds instead. + + This change brings two benefits: + + - It makes MTU probing faster, because MTU probe lengths are calculated + based on minmtu, and minmtu is adjusted based on the replies. When + sending batches of three packets, all three packets are based on the + same minmtu estimation; in contrast, by sending one packet more + frequently, each subsequent packet can benefit from the replies that + have been received since the last packet was sent. As a result, MTU + discovery converges much faster (2-3 times as fast, typically). + + - It reduces network spikiness - it's more network-friendly to send + one packet from time to time as opposed to sending bursts. + +commit 5bdc1f2b82869d379812879334dbf2b549ff48db +Author: Etienne Dechamps +Date: Thu Jan 1 16:04:08 2015 +0000 + + Use -1 to identify the post-initial MTU discovery state. + + This is a minor cosmetic nit to emphasise the distinction between the + initial MTU discovery phase, and the post-initial phase (i.e. maxmtu + checking). + + Furthermore, this is an improvement with regard to the DRY (Don't + Repeat Yourself) principle, as the maximum mtuprobes value is only + written once. + +commit df6f67895723dd0c4226fa0f94257245a81a273f +Author: Etienne Dechamps +Date: Thu Jan 1 10:32:14 2015 +0000 + + Fix MTU as soon as possible. + + If a probe reply is received that makes minmtu equal to maxmtu, we + have to wait until try_mtu() runs to realize that. Since try_mtu() + runs after a packet is sent, this means there is at least one packet + (possibly more, depending on timing) that won't benefit from the + fixed MTU. This also happens when maxmtu is updated from the send() + path. + + This commit fixes that by making sure we check whether the MTU can be + fixed every time minmtu or maxmtu is touched. + +commit 97cf4783188b8027d2309ce594fea5fc6daf31d1 +Author: Etienne Dechamps +Date: Mon Dec 29 17:05:19 2014 +0000 + + Move try_mtu() closer to try_tx(). + + This moves related functions together, and is a pure cut-and-paste + change. The reason it was not done in the previous commit is because it + would have made the diff harder to review. + +commit 98716a227ee39fdcdfafa7309adb73499311a2ce +Author: Etienne Dechamps +Date: Mon Dec 29 16:47:49 2014 +0000 + + Move PMTU discovery code into the TX path. + + Currently, the PMTU discovery code is run by a timeout callback, + independently of tunnel activity. This commit moves it into the TX + path, meaning that send_mtu_probe_handler() is only called if a + packet is about to be sent. Consequently, it has been renamed to + try_mtu() for consistency with try_tx(), try_udp() and try_sptps(). + + Running PMTU discovery code only as part of the TX path prevents + PMTU discovery from generating unreasonable amounts of traffic when + the "real" traffic is negligible. One extreme example is sending one + real packet and then going silent: in the current code this one little + packet will result in the entire PMTU discovery algorithm being run + from start to finish, resulting in absurd write traffic amplification. + With this patch, PMTU discovery stops as soon as "real" packets stop + flowing, and will be no more aggressive than the underlying traffic. + + Furthermore, try_mtu() only runs if there is confirmed UDP + connectivity as per the UDP discovery mechanism. This prevents + unnecessary network chatter - previously, the PMTU discovery code + would send bursts of (potentially large) probe packets every second + even if there was nothing on the other side. With this patch, the + PMTU code only does that if something replied to the lightweight UDP + discovery pings. + + These inefficiencies were made even worse when the node is not a + direct neighbour, as tinc will use PMTU discovery both on the + destination node *and* the relay. UDP discovery is more lightweight for + this purpose. + + As a bonus, this code simplifies overall code somewhat - state is + easier to manage when code is run in predictable contexts as opposed + to "surprise callbacks". In addition, there is no need to call PMTU + discovery code outside of net_packet.c anymore, thereby simplifying + module boundaries. + +commit eef792c01ed1704c03d55163de3f302a3c1d42fa +Author: Etienne Dechamps +Date: Mon Dec 29 16:11:04 2014 +0000 + + Remove PMTU discovery code redundant with UDP discovery. + + This is a rewrite of the send_mtu_probe_handler() function to make it + focus on the actual discovery of PMTU. In particular, the PMTU + discovery code doesn't care about tunnel state anymore - it only cares + about doing the initial PMTU discovery, and once that's done, making + sure PMTU did not increase by checking it from time to time. All other + duties have already been rewritten in the UDP discovery code. + + As a result, the send_mtu_probe_handler(), which previously implemented + a nightmarish state machine which was very difficult to follow and + understand, has been massively simplified. We moved from four persistent + states to only two - initial discovery and steady state. + + Furthermore, a side effect is that network chatter is reduced: instead + of sending bursts of three minmtu-sized packets in the steady state, + there is only one such packet that's sent from the UDP discovery code. + However, that introduces a slight regression in the bandwidth estimation + code, which relies on three-packet bursts in order to function. + Considering that this estimation is extremely unreliable (in my + experience) and isn't relied on by anything, this seems like an + acceptable regression. + +commit 88026f27715774a7647c109ba5594068f0ba56af +Author: Etienne Dechamps +Date: Mon Dec 29 15:40:55 2014 +0000 + + Move responsibility for local discovery to UDP discovery. + + Since UDP discovery is the place where UDP feasibility is checked, it + makes sense to test for local connectivity as well. This was previously + done as part of PMTU discovery. + +commit 7939ee12836bf2ef772f2a6a1e805ee0d64a8e70 +Author: Etienne Dechamps +Date: Mon Dec 29 10:34:39 2014 +0000 + + Add UDP discovery mechanism. + + This adds a new mechanism by which tinc can determine if a node is + reachable via UDP. The new mechanism is currently redundant with the + PMTU discovery mechanism - that will be fixed in a future commit. + + Conceptually, the UDP discovery mechanism works similarly to PMTU + discovery: it sends UDP probes (of minmtu size, to make sure the tunnel + is fully usable), and assumes UDP is usable if it gets replies. It + assumes UDP is broken if too much time has passed since the last reply. + + The big difference with the current PMTU discovery mechanism, however, + is that UDP discovery probes are only triggered as part of the + packet TX path (through try_tx()). This is quite interesting, because + it means tinc will never send UDP pings more often than normal packets, + and most importantly, it will automatically stop sending pings as soon + as packets stop flowing, thereby nicely reducing network chatter. + + Of course, there are small drawbacks in some edge cases: for example, + if a node only sends one packet every minute to another node, these + packets will only be sent over TCP, because the interval between packets + is too long for tinc to maintain the UDP tunnel. I consider this a + feature, not a bug: I believe it is appropriate to use TCP in scenarios + where traffic is negligible, so that we don't pollute the network with + pings just to maintain a UDP tunnel that's seeing negligible usage. + +commit 5d6478b9fbb7379fe6017b2b74c0f1ccb3d2501f +Author: Etienne Dechamps +Date: Sun Dec 28 17:29:03 2014 +0000 + + Move try_sptps() closer to try_tx(). + + This moves related functions together. try_tx() is at the right place + since its only caller is send_packet(). + + This is a pure cut-and-paste change. The reason it was not done in the + previous commit is because it would have made the diff harder to review. + +commit 81578484dc74fd92f1b01f71f882016f120ab1de +Author: Etienne Dechamps +Date: Sun Dec 28 17:16:27 2014 +0000 + + Add the try_tx() function. + + Currently, the TX path (starting from send_packet()) in tinc has three + responsabilities: + + - Making sure packets can be sent (e.g. fetching SPTPS keys); + - Making sure they can be sent optimally (e.g. fetching non-SPTPS keys + so that UDP can be used); + - Sending the actual packet, if feasible. + + The first two are closely related; the third one, however, can be + cleanly separated from the other two - meaning, we can loosen code + coupling between sending packets and "optimizing" the way packets are + sent. This will become increasingly important as future commits will + move more tunnel establishment and maintenance code into the TX path, + so we will benefit from a cleaner separation of concerns. + + This is especially relevant because of the dual nature of the TX path + (SPTPS versus non-SPTPS), which can make things really complicated when + trying to share low-level code between both. + + In this commit, code related to establishing or improving tunnels is + moved away from the core TX path by introducing the "try_*()" family of + function, of which try_sptps() already existed before this commit. + + This is a pure refactoring; this commit shouldn't introduce any change + in behavior. + +commit 950edc0744dfa04790ae274e8b7f55b1a990a43c +Author: Etienne Dechamps +Date: Sun Oct 12 19:44:33 2014 +0100 + + Clarify the send_mtu_probe() function. + + This cleans up the PMTU probing function a little bit. It moves the + low-level sending of packets to a separate function, so that the code + reads naturally instead of using a weird for loop with "special + indexes". In addition, comments are moved inside the body of the + function for additional context. + + This shouldn't introduce any change of behavior, except for local + discovery which has some minor logic fixes and which now always uses + small packets (16 bytes) because there's no need for a full-length + probe just to try the local network. + +commit d28f33228635e78dac8f9e9bcaec92690f2ca10a +Author: Guus Sliepen +Date: Thu Jan 1 00:52:39 2015 +0100 + + Fixes for bugs in src/Makefile.am and tincctl.c introduced by cfe9285adf391ab66faeb5def811fe08e47a221a. + +commit 4d50f9f3485503099f5cb6e8486e9b98b72cb9be +Author: Guus Sliepen +Date: Tue Dec 30 11:16:08 2014 +0100 + + Add missing nolegacy/crypto.c and prf.c. + +commit cfe9285adf391ab66faeb5def811fe08e47a221a +Author: Guus Sliepen +Date: Mon Dec 29 22:57:18 2014 +0100 + + Allow tinc to be compiled without OpenSSL. + + The option "--disable-legacy-protocol" was added to the configure + script. The new protocol does not depend on any external crypto + libraries, so when the option is used tinc is no longer linked to + OpenSSL's libcrypto. + +commit 8d32b283b016e205b051b0bacb49a1e86fd5e1bc +Author: Guus Sliepen +Date: Sat Dec 27 09:22:31 2014 +0100 + + Releasing 1.1pre11. + +commit db465434e2736f6e052e5c52d3613ad81b4bde10 +Author: Guus Sliepen +Date: Sat Dec 27 09:20:46 2014 +0100 + + Add BroadcastSubnet and DeviceStandby options to the manual and completion. + +commit 26d3ee0dd9b770a857615752b5c5588be0354a16 +Author: Guus Sliepen +Date: Sat Dec 27 09:08:34 2014 +0100 + + Better default paths for log and PID files on Windows. + +commit b78436ff1e9afd767c3da473d34b7553d8411b6a +Author: Guus Sliepen +Date: Fri Dec 26 18:22:13 2014 +0100 + + Remove AES-GCM support. + +commit 128a37397432e5e63099633e275c65a652c16673 +Author: Guus Sliepen +Date: Fri Dec 26 18:12:28 2014 +0100 + + Linux doesn't like .PHONY .o files. + + In order to please every OS, make version.c .PHONY again, and add an + empty rule to make version.c. + +commit 69689f908b0c9a14b7108b7ab8edd92facc53ddf +Author: Guus Sliepen +Date: Fri Dec 26 17:53:40 2014 +0100 + + We don't depend on ECDH functions from OpenSSL anymore. + +commit aa2d4f8dd9bab794dd197b92ba54e6428400555f +Author: Guus Sliepen +Date: Fri Dec 26 15:58:28 2014 +0100 + + BSD make doesn't like .PHONY .c files. + + It then thinks there should be a rule to make the .c file, which does + not exist of course. Luckily, we can tell it that version.o is .PHONY, + and this will still cause the .o file to be regenerated and linked into + the binaries everytime make is called. + +commit 8ee4004edfbc79b1a17bf03c262f063f2f4c128d +Author: Guus Sliepen +Date: Fri Dec 26 15:40:09 2014 +0100 + + Check whether res_init() really lives in libresolv. + + On some platforms (Mac OS X for example), the res_init() function requires + linking with libresolv. On others (Linux, OpenBSD for example), res_init() + lives in libc. + +commit 9f20922d62d258d7f5f1ef30dcd538c661062439 +Author: Guus Sliepen +Date: Fri Dec 26 14:59:15 2014 +0100 + + Update THANKS file. + +commit 880d74ad2d8a6d73c2e94ec54df542b88dc0c6f4 +Author: Guus Sliepen +Date: Fri Dec 26 14:38:01 2014 +0100 + + Allow running tinc without RSA keys. + + This allows one to run tinc with only Ed25519 keys, forcing tinc to + always use the SPTPS protocol. + +commit 266afc6c63d3d02584feb24b69063f97057daac8 +Merge: 7730d5f3 c269a17c +Author: Guus Sliepen +Date: Thu Dec 25 18:13:24 2014 +0100 + + Merge remote-tracking branch 'groxxda/gui-fixes' into 1.1 + +commit 7730d5f3ed9bd7c011dced5808130ffcbd74ea6b +Author: Etienne Dechamps +Date: Sun Oct 12 12:14:46 2014 +0100 + + Use plain old PACKET for TCP packets sent directly to a neighbor. + + Currently, when sending packets over TCP where the final recipient is + a node we have a direct metaconnection to, tinc first establishes a + SPTPS handshake between the two neighbors. + + It turns out this SPTPS tunnel is not actually useful, because the + packet is only being sent over one metaconnection with no intermediate + nodes, and the metaconnection itself is already secured using a separate + SPTPS handshake. + + Therefore it seems simpler and more efficient to simply send these + packets directly over the metaconnection itself without any additional + layer. This commits implements this solution without any changes to the + metaprotocol, since the appropriate message already exists: it's the + good old "plaintext" PACKET message. + + This change brings two significant benefits: + + - Packets to neighbors can be sent immediately - there is no initial + delay and packet loss previously caused by the SPTPS handshake; + + - Performance of sending packets to neighbors over TCP is greatly + improved since the data only goes through one round of encryption + instead of two. + + Conflicts: + src/net_packet.c + +commit 0356efecb6385b59a69bea220057396d6daa30bc +Author: Etienne Dechamps +Date: Sun Oct 12 11:41:08 2014 +0100 + + Don't spontaneously start SPTPS with neighbors. + + Currently, when tinc establishes a metaconnection, it automatically + starts a VPN SPTPS tunnel with the other side of the metaconnection. + + It is not clear what this is trying to accomplish. Having a + metaconnection with a node does not necessarily mean we're going to send + packets to that node. This patch removes this behavior, thereby + simplifying code paths and removing unnecessary network chatter. + + Naturally, this introduces a slight delay (as well as at least one + initial packet loss) between the moment a metaconnection is established + and the moment VPN packets can be exchanged between the two nodes. + However this is no different to the non-neighbor case, so it makes + things more consistent and therefore easier to reason about. + +commit 6b92ac505d2cd5c7e390d49bf1f0b399ef9f8327 +Author: Guus Sliepen +Date: Wed Dec 24 22:23:24 2014 +0100 + + Add a variable offset to vpn_packet_t, drop sptps_packet_t. + + The offset value indicates where the actual payload starts, so we can + process both legacy and SPTPS UDP packets without having to do casting + tricks and/or moving memory around. + +commit 107d9c7da5b206425a8e1643a6849ea990f725f8 +Author: Guus Sliepen +Date: Wed Dec 24 22:15:40 2014 +0100 + + Use void pointers for opaque data blobs in the SPTPS code. + +commit 3df86ef17bce9f24c3dad79ccc2b17aa6e93ea34 +Author: Guus Sliepen +Date: Wed Dec 24 17:31:33 2014 +0100 + + Fix memory leaks found by Valgrind. + +commit d00d8dbb9b122a17ef93090de10396ebdd2c4a84 +Author: Guus Sliepen +Date: Wed Dec 24 17:06:05 2014 +0100 + + Don't use myself->name in device_disable(), it's already freed. + +commit 313de46e70b249de2938b04e7fc9c3872d99474a +Author: Guus Sliepen +Date: Wed Dec 24 16:59:08 2014 +0100 + + Don't pass uninitialized bytes to ioctl(). + +commit a99ded7d987c3242f972162e02767c498257f2b8 +Author: Guus Sliepen +Date: Wed Dec 24 16:54:12 2014 +0100 + + Avoid using OpenSSL's random number functions. + +commit 199573f1e834290290a1c278072a153b90443b05 +Author: Guus Sliepen +Date: Sun Dec 14 13:05:30 2014 +0100 + + Fix reception of SPTPS UDP packets. + + Some bugs were introduced in 46fa12e666badb79e480c4b2399787551f8266d0. + +commit 558b19c2432d938afc4a659668bd461ace6ed744 +Author: Guus Sliepen +Date: Sun Dec 14 12:42:03 2014 +0100 + + Fix segfault when receiving UDP packets with an unknown source address. + +commit 5104001bae7d09040703ddbe18cf8781c7aaa94f +Author: Guus Sliepen +Date: Mon Dec 8 08:43:15 2014 +0100 + + Changes that should have been in commit 46fa12e666badb79e480c4b2399787551f8266d0. + +commit 46fa12e666badb79e480c4b2399787551f8266d0 +Author: Guus Sliepen +Date: Mon Dec 8 00:58:09 2014 +0100 + + Make UDP packet handling more efficient. + + Limit the amount of address/ID lookups to the minimum in all cases: + + 1) Legacy packets, need an address lookup. + 2) Indirect SPTPS packets, need an address lookup + two ID lookups. + 3) Direct SPTPS packets, need an ID or an address lookup. + + So we start with an address lookup. If the source is an 1.1 node, we know it's an SPTPS packet, + and then the check for direct packets is a simple check if dstid is zero. If not, do the srcid and dstid + lookup. If the source is an 1.0 node, we don't have to do anything else. + + If the address is unknown, we first check whether it's from a 1.1 node by assuming it has a valid srcid + and verifying the packet. If not, use the old try_harder(). + +commit 263d9903826ffb65aec89bdf5d46f72bd183d467 +Author: Guus Sliepen +Date: Mon Dec 8 00:44:38 2014 +0100 + + Avoid memmove() for legacy UDP packets. + +commit c2319e90b16962fe899bc60abc8af0e2542bb176 +Author: Guus Sliepen +Date: Sun Dec 7 22:11:37 2014 +0100 + + Cache node IDs in a hash table for faster lookups. + +commit 9d48d5b7d48ad23e23eae02feae69bdc5ae80c8e +Author: Guus Sliepen +Date: Sun Dec 7 22:10:16 2014 +0100 + + Add an explicit hash_delete() function. + +commit 6062df4a0fa6214d21ac83d885087e9dbdac3f39 +Author: Guus Sliepen +Date: Sun Dec 7 21:42:20 2014 +0100 + + Better log messages when we already know the peer's key during an upgrade. + + If the peer presents a different one from the one we already know, log + an error. Otherwise, log an informational message, and terminate in the + same way as we would if we didn't already have that key. + +commit 148a4c9161735a76b0a4ce73ffaaec21d76ca702 +Author: Sven-Haegar Koch +Date: Fri Dec 5 03:06:44 2014 +0100 + + Try handling the case when the first side knows the ecdsa key of + the second, but the second not the key of the first. + (And both have the experimental protocol enabled) + +commit b90c42a33b78f22b7046da5a5445c712020f30eb +Author: Guus Sliepen +Date: Sun Dec 7 17:25:30 2014 +0100 + + Log an error message with the node's name when receiving bad SPTPS packets. + + The SPTPS code doesn't know about nodes, so when it logs an error about + a bad packet, it doesn't log which node it came from. So add a log + message with the node's name and hostname in receive_udppacket(). + +commit 660a2c7d1bf7f5fba905b525bc7c3b9a5ac2ec99 +Author: Guus Sliepen +Date: Sun Dec 7 17:20:18 2014 +0100 + + Check validity of Ed25519 key during an upgrade. + +commit 5716c8877fd705d5af36d82e27632b123fa5dde0 +Author: Sven-Haegar Koch +Date: Fri Dec 5 02:41:55 2014 +0100 + + Do not disconnect when no ecdsa key is known yet. + + This is the normal case when we support the experimental protocol, + but the other side is a tinc 1.0 which does not. + +commit dd6b0e65b96280235893705a947eac4a1c71276e +Author: Guus Sliepen +Date: Wed Dec 3 14:51:45 2014 +0100 + + Fix compiler warnings. + +commit 790b107f668a886c3b335e68b9440ef5152a2844 +Author: Etienne Dechamps +Date: Sat Oct 4 16:33:33 2014 +0100 + + Query the Linux device for its MAC address. + + On Linux, tinc doesn't know the MAC address of the TAP device until the + first read. This means that if no packets are sent through the + interface, tinc won't be able to figure out which MAC address to tag + incoming packets with. As a result, it is impossible to receive any + packet until at least one packet has been sent. + + When IPv6 is disabled Linux does not spontanously send any packets + when the interface comes up. At first users wonder why the node is not + responding to ICMP pings, and then as soon as at least one packet is + sent through the interface, pings mysteriously start working, resulting + in user confusion. + + This change fixes that problem by making sure tinc is aware of the + device's MAC address even before the first packet is sent. + +commit c269a17ca4d4e4946a3f8ab05da8cdd338d97ffb +Author: groxxda +Date: Tue Oct 14 22:18:56 2014 +0200 -groxxda (1): tinc-gui: Don't assign broadcast subnets to any node, fix parsing of Edges, fix diplay of Subnet.weight. -Version 1.1pre10 February 07 2014 ------------------------------------------------------------------------- - -Guus Sliepen (52): - Wrong date for the 1.1pre9 release in the NEWS. - Avoid using BIOs. - Add a benchmark for the SPTPS protocol. - Don't leak memory during the key generation speed test. - Link sptps_speed with -lrt. - Fix segfault when Name = $HOST but $HOST is not set. - Fix typos in the documentation. - Use AES-256-GCM for the SPTPS protocol. - Fix sending empty SPTPS records. - Clean up child processes from proxy type exec. - Make sptps_test less verbose by default. - Fix sending bulk data starting with a newline. - Fix two warnings from Clang's static analyzer. - Remove an unused variable. - Make LocalDiscovery work for SPTPS packets. - Allow "none" for Cipher and Digest again. - Mention in the manual that multiple Address staments are allowed. - If no Port is specified, set myport to actual port of first listening socket. - Update support for Solaris. - Include for PATH_MAX. - Stricter check for raw socket support. - Avoid using a variable named "sun". Solaris doesn't like it. - Use hardcoded value for TUNNEWPPA if net/if_tun.h is missing on Solaris. - Prefer ncurses over curses. - Don't print device statistics when exiting tinc. - Allow running without ECDSA keys If ExperimentalProtocol is not explicitly set. - Give full path to unconfigured tinc-up script. - Don't print an error when no ECDSA key is known for a node using the legacy protocol. - Remove erroneous warning about SPTPS being disabled. - Enable compiler hardening flags by default. - Add our own autoconf check for libgcrypt. - Don't enable -fstack-protector-all. - Fix handling of --with-libgcrypt. - Clarify StrictSubnets. - Update the documentation of the tinc command. - Add index entries for the CLI commands. - Let tinc-gui use correct address family when connecting to tincd via TCP. - Document clearly that tinc depends on curses and readline libraries. - Document that 1.1 uses AES-256 in GCM mode. - Add the ListenAddress option. - Test two tinc daemons using network namespaces. - Add missing newlines when copying variables from tinc.conf to an invitation file. - Don't ask questions if we are not running interactively. - Document Weight and also allow it to be set from tinc.conf. - Use addresses learned from other nodes when making outgoing connections. - Attribution for various contributors. - Handle errors from TAP-Win32/64 adapter in a better way. - Attribution for Dennis Joachimsthaler. - Update copyright notices. - Fix compiling for Windows. - Check whether OpenSSL has support for GCM. - Releasing 1.1pre10. - -Dennis Joachimsthaler (2): - Fix tinc-gui on Windows. - Ensure tinc-gui running in 64 bits mode can find tinc's 32 bit registry key. - -Florent Clairambault (1): - Adding "conf.d" configuration dir support. - -Version 1.1pre9 September 08 2013 ------------------------------------------------------------------------- - -Guus Sliepen (40): - Stop using EXTRA_DIST in src/Makefile.am. - Remove texi2html rule in docs/Makefile. - Create UNIX socket at the same time as the PID file is created. - Don't force a .bat extension for scripts under Windows. - Fix order of tincd's initialization. - Remove broadcast of KEY_CHANGED message during tinc's initialization. - Bind outgoing sockets again. - Resolve the local host name before generating the invitation file. - Use our own infrastructure for finding out the local node's externally visible host name. - Let a server explicitly send a notification when the invitation protocol succeeded. - Ensure the invitation filenames do not reveal the secret cookie. - Execute scripts when invitations are created or accepted. - Use PATHEXT when checking for the presence of scripts on Windows. - Tell invited node about Mode and Broadcast settings. - Call WSAStartup() in main(). - When generating invitations, handle any order of Port and Adress statements. - Add an option to test datagram SPTPS with packet loss. - Fix CTR mode. - Fix the replay window in SPTPS. - Allow testing the replay window with sptps_test. - Start of a test suite. - Some shells set $_ to an absolute path. - Make sptps_test more easy to work with. - Small fixes for tests. - Add test for import, export and exchange commands. - Fix tincd logfile location when running tests. - Clean up leftover tincd and sptps_test processes. - Send a RELOAD to a running tincd when a new invitation key has been generated. - Slightly relax the connection rate limit for a single address. - Also test whether tinc daemons can connect to each other after import/export. - Add a test for invite and join commands. - Exit value 1 instead of a random non-zero value. - Fix multicast device. - Add two more test scripts. - Don't return zero-length packets when receiving multicast loopback packets. - Test running ping through two tinc daemons. - Automake doesn't like info files being mentioned in CLEANFILES. - Make sure test scripts end up in the tarball. - Don't try to mkdir(CONFDIR) if --config is used. - Releasing 1.1pre9. - -Etienne Dechamps (1): - Fix broken build with --with-openssl, --with-libgcrypt. - -Version 1.1pre8 August 13 2013 ------------------------------------------------------------------------- - -Guus Sliepen (56): - Don't try to create tinc.conf when using set or add commands. - Modernize the configure script a bit. - Use conditional compilation for device.c. - Use conditional compilation for cryptographic functions. - Rename xmalloc_and_zero() to xzalloc(). - Add generic crypto headers. - Add more __attribute__((malloc)) where appropriate. - Add __attribute__((warn_unused_result)) to crypto functions. - Fix warnings for functions marked __attribute((warn_unused_result)). - Add a few more checks and warnings in the crypto functions. - Enable the SPTPS protocol by default. - Fix check for presence of ECDSA public key for outgoing connections. - Use read_host_config() where appropriate. - Don't free ephemeral ECDH keys twice. - Fix potential NULL pointer dereferences. - Don't try to handle incoming data if sptps_start() has not been called yet. - Enable and fix warnings from automake. - Send a new key when we receive packets from a node we don't have a valid key for. - Annotate the xalloc functions. - Improve base64 encoding/decoding, add URL-safe variant. - Add a newline when logging to stderr in the tinc binary. - Fix port number in pidfile. - Add an invitation protocol. - Better optional argument handling. - Allow the log output to be stopped with control-C in tinc's shell. - Use strerror() instead of gai_strerror() when err == EAI_SYSTEM. - Add the LocalDiscoveryAddress option. - Set $NAME when calling host-up/down and subnet-up/down scripts. - Add connection rate limiting. - Fix warning "Both netname and configuration directory given" on Windows. - Add missing definitions on Windows. - Don't search in local directories for include files. - Don't use vasprintf() anymore on Windows. - Attribution for Etienne Dechamps. - Forbid protocol version rollback. - Allow extra options to be passed to "tinc restart" again. - Honour umask, let temporary key files inherit original's permissions. - Fix compression when using the SPTPS protocol. - Warn when incorrect use of add or set causes variables to be removed. - Allow control-C to stop tincd without stopping the tinc shell. - Don't forget the Port variable when creating an invitation URL. - Choose a different Port when 655 isn't available when doing "tinc init". - Choose a different Port when 655 isn't available when doing "tinc join". - Make absolutely sure we can write config files before accepting an invitation. - Defer handling netname conflicts when accepting an invitation. - Use umask() to set file and UNIX socket permissions without race conditions. - Clean up the SIGINT handler. - Really retry outgoing connections immediately if requested. - Non-zero exit code when reloading config file fails after SIGHUP. - Fix a typo. - Don't echo broadcast packets back when Broadcast = direct. - Move .h files from noinst_HEADERS to tincd_SOURCES. - Build .tar.gz instead of .tar.xz. - Update copyright notices. - Don't typedef the same struct in two header files. - Releasing 1.1pre8. - -Etienne Dechamps (5): - Fix combination of Mode = router and DeviceType = tap on Linux. - Fix hash_function(). - Disable PMTU discovery when TCPOnly is set. - Introduce lightweight PMTU probe replies. - Further improve bandwidth estimation for type 2 MTU probe replies. - -Sven-Haegar Koch (1): - Modified some error messages in src/sptps.c. - -Version 1.1pre7 April 22 2013 ------------------------------------------------------------------------- - -Guus Sliepen (12): - Use UDP when using sptps_test in datagram mode. - Flush output buffers in the tap reader thread on Windows. - Better default output file for generated public keys. - Allow changing configuration with tincctl without the "config" keyword. - Avoid calling time(NULL). - Include README.android in the tarballs. - Rename tincctl to tinc. - Remove references to the config keyword. - Describe the SPTPS protocol in the manual. - Fix completion of add/del/get/set commands. - Drop packets forwarded via TCP if they are too big (CVE-2013-1428). - Releasing 1.1pre7. - -Version 1.1pre6 February 20 2013 ------------------------------------------------------------------------- - -Guus Sliepen (16): - Fix datagram SPTPS. - Fix a typo. - Get microsecond time resolution on Windows. - Detect increases in PMTU. - Remove direct inclusion of OpenSSL headers in net_packet.c and tincd.c. - Fix tincd terminating immediately on Windows. - Check for writability when waiting for a socket to finish connecting. - Fix segmentation fault when trying to connect via a SOCKS5 proxy. - Don't send proxy requests for incoming connections. - Derive UNIX socket filename from PID filename. - Let the GUI use UNIX sockets if available. - Don't expect a response from tincd after sending REQ_STOP. - Fix a tiny memory leak. - Fix compiler warnings on Windows. - Fix compiler warnings on some BSD variants. - Releasing 1.1pre6. - -Version 1.1pre5 January 20 2013 ------------------------------------------------------------------------- - -Guus Sliepen (24): - Clarify the description of IndirectData and Mode = router. - Fix display of cumulative packet counters. - Fix infinite loop in timeout handling on Windows. - Fix support for tunemu on iOS devices. - Fix a typo. - Note that node Names are case sensitive. - Note that tincctl import is only meant to work with data from tincctl export. - Mention that the -L, -R and -U options are not supported on all platforms. - Don't complain about garbage if we skipped importing a host file. - Better error messages when using -L, -R or -U on platforms that do not support it. - Always complain if too many arguments are given for tincctl commands. - Check HMAC before sequence number. - Add the tincctl exchange and exchange-all commands. - Count the number of correctly received UDP packets. - Estimate RTT, bandwidth and packet loss between nodes. - Fix the minimum spanning tree algorithm. - Handle SIGINT gracefully. - Move make_names() and related variables to its own source file. - Fix compilation of UML and VDE device support. - Allow connections via UNIX sockets. - Make sure PriorityInheritance also works in switch mode. - Remove possible definition of timersub(), which is also in dropin.h. - Fix tincctl init when /etc/tinc does not yet exist. - Releasing 1.1pre5. - -Version 1.1pre4 December 05 2012 ------------------------------------------------------------------------- - -Guus Sliepen (35): - Fix warnings from groff. - Keep track of the number of nodes in a tree. - Add the AutoConnect option. - Slightly randomize all timeouts. - Fix potential buffer overflow reading the PID file. - Using alloca() for a constant sized buffer is very silly. - Make sure PMTU discovery works in switch mode with VLAN tags. - Mention libcurses and libreadline in the manual. - Mention in the manual that support for LZO and zlib can be disabled. - Fix index entry for section about readline library. - Fix configure script help text for --enable options. - Don't take the address of a variable whose scope is about to disappear. - Send broadcast packets using a random socket, and properly support IPv6. - Remove text saying you must have one of PrivateKey or PrivateKeyFile in tinc.conf. - Disable support for kqueue on MacOS/X. - Also don't use poll() on MacOS/X. - Choose a suitable socket when updating a node's UDP address. - Try all known addresses of node during PMTU discovery, now also for SPTPS. - Improve UDP address selection. - Ensure MTU probe replies are sent back the same way they came in. - Drop libevent and use our own event handling again. - Allow multiple timeouts to expire at the exact same time. - Fix check for expired events. - Fix use of unitialised values in hash tables. - Set a node's pointers to zero before trying to insert it into a tree. - Fix crash in timeout handling. - Fix compiler error on Windows. - More fixes for Windows. - Add option to dump only a list of reachable nodes. - Remove GraphDumpFile from the manual and manpages. - Fix compiler warnings on OpenBSD. - Don't use nested functions. - Scale packet counters similar to byte counters. - Fix whitespace. - Releasing 1.1pre4. - -Version 1.1pre3 October 14 2012 ------------------------------------------------------------------------- - -Guus Sliepen (384): - Created the 1.1 branch where large code changes can take place, - Only free members of connection_t that have been allocated. - Port fixes from release 1.0.8. - Properly delete listener socket events on shutdown. - 128 listener sockets is way too much. - Use a separate event structure to handle meta data writes. - Use libevent to dump graphs when necessary. - Use libevent to handle HUP signal. - Configure events after obtaining a socket. - Use libevent to send MTU probes. - Use libevent for retrying outgoing connections. - Remove legacy event system. - Properly use the timeout_initialized() macro. - Use libevent to handle all non-fatal signals. - Redo SIGALRM handling. - Use libevent to age past requests. - Use libevent to age learned MAC addresses. - Use libevent to handle key expiration. - Move key regeneration handling to net_setup.c. - Remove global variable "now". - Remove the last bits of the legacy main_loop(). - Remove last references to the global variable "running". - K&R style braces - Use splay trees instead of AVL trees. - Detect duplicate outgoing connections. - More consistent variable naming. - Show branch version number. - Update documentation. - Start of control socket implementation. - We can safely delete a connection_t in terminate_connection() now. - Fix retrying outgoing connections. - Remove pidfile in favour of control socket. - Move key generation to tincctl. - Implement "stop" command, and allow tincctl to retrieve a running tincd's PID. - Use bufferevents to handle control socket buffering. - Use libevent for meta socket input/output buffering. - Parse PEM RSA keys ourself, and use libgcrypt to do RSA encryption and decryption. - Create wrappers for the cryptographic operations used in tinc. - Make sure the crypto wrapper functions can actually be compiled. - Some more crypto wrapper functions are needed. - Finish crypto wrapping. Also provide wrappers for OpenSSL. - Only check for libgcrypt if --with-gcrypt is used. - Fix formatting of --help output. - Small fixes to make gcrypt routines compile. - Apply patch from Scott Lamb: Update documentation to match tincctl changes - Fix connection weight estimation. - Use a dummy function as the read callback for connection bufferevents. Should not be triggered. - Fix meta data segfault when receiving a partial command. - Prevent double free() of a used challenge nonce. - Look in the configured sbin directory for the tincd binary. - Only show meta connection related debug messages when debug level >= 4 - Move AC_GNU_SOURCE up to make autoconf happy. - Use the crypto wrappers again instead of calling OpenSSL directly. - Backport fixes from trunk since revision 1555. - Fix compiler warnings. - Remove unnecessary parentheses from sizeof, apply sizeof to variables instead of types whereever possible. - Remove wrong checks. - Use Dijkstra's algorithm. Based on patches from Max Rijevskiy. - Make sure IPv6 sockets are IPv6 only. - Move RSA key generation into the wrappers. - Merge branch 'master' into 1.1 - Merge branch 'master' into 1.1 - Handle truncated message authentication codes. - Fix pointer arithmetic when creating and verifying message authentication codes. - Merge branch 'master' into 1.1 - Add missing #include. - Use correct format specifiers. - Replace asprintf()s not covered by the merge to xasprintf(). - Add a better autoconf check for libevent. - Merge branch 'master' into 1.1 - Drop localisation and checkpoint tracing in files not covered by the merge. - Update FSF address in files not covered by the merge. - Merge branch 'master' into 1.1 - Don't enable device events when there is no valid filedescriptor. - Use %x instead of %lx where appropriate. - Handle truncated message authentication codes with gcrypt. - Handle PKCS#5 padding in the gcrypt backend. - Make sure the 1.1 branch compiles in a MinGW environment. - Better integration of libevent in build system. - Small fixes to get really working control sockets on Windows. - Use the TCP socket infrastructure for control sockets. - Only call ioctlsocket() on Windows. - Merge branch 'master' into 1.1 - Fix compiler warnings. - Do not include OpenSSL headers directly. - Include missing header files and source directories. - Allow connections to be closed. - Start of a GUI for tinc. - Fix packet authentication. - Fix block cipher padding when using libgcrypt. - Reinitialise block cipher IV each time we encrypt a packet when using libgcrypt. - Fix reading raw RSA keys with libgcrypt. - recv() and recvfrom() return int, do not prematurely cast the return value. - Do not consider unreachable nodes when trying to determine packet origin. - Fix alignment of results of RSA operations when using libgcrypt. - Do not use hardcoded cipher block length when padding. - Remove unused AVL tree library. - Move source from lib/ to src/. - Fix experimental GUI when reading hexadecimal values. - Merge branch 'master' into 1.1 - Fix merge of commit 4a0b9981513059755b9fd15b38fc198f46a0d6f2. - Add missing return statement. - Use correct digest length when checking a received key. - Do not try to free NULL pointers. - Remove obsolete lib/ directory. - Merge branch 'master' into 1.1 - Link tincctl with dropin.o. - Merge branch 'master' into 1.1 - Do not try to dereference myself->connection->config_tree. - Merge branch 'master' of git://tinc-vpn.org/tinc into 1.1 - Fix check for event initialization due to the merge. - Add simple buffer management code. - Remove use of bufferevent and eventbuffers, use our own buffering instead. - Several fixes for the buffer code. - Add per-node traffic counters. - Dump traffic statistics over control sockets. - Add an autoconf check for the curses library. - Add a very primitive "top" command to tincctl. - Allow inserting items in the middle of a list. - Nicer top command. - Add tincctl.h. - Add top.h. - Use GetItemCount() on ListCtrls instead of directly accessing ItemCount. - Fix some compiler warnings. - Compact input buffer before trying to read instead of after. - Always compact the buffer if it has reached MAXBUFSIZE. - Check if an event is initialized before calling event_del(). - Reset tcplen after use. - Add the ability to dump all traffic going through route() over a control connection. - Allow tincctl to connect to something besides localhost. - Show hostname and port in error message when connecting to a running tincd. - Cosmetic fix when pressing 's' in tincctl top. - Initialise priority field to zero for packets read from the VPN interface. - Remove outgoing event in free_connection(). - Simplify signal handling. - Drop the GNU malloc.c, realloc.c, and xmalloc.c. - Drop the GNU memcmp.c implementation. - Don't #include anymore. - Remove unused functions and variables. - Remove support for the Ethertap device. - Fix some compiler and cppcheck warnings. - More stable sorting in tincctl top. - Make traffic statistics more readable with configurable scaling. - Fix nodes joining the VPN after tincctl top started. - Don't treat packets coming in via TCP as having zero length. - Remove debugging message that was accidentily left in. - Even simpler signal handling. - Small fixes for Windows. - Use send() when writing to sockets, and the return type is ssize_t. - Fix format strings for Windows. - Don't ignore SIGCHLD, system() needs it. - Clean up digests when freeing a connection_t. - Merge branch 'master' of git://tinc-vpn.org/tinc into 1.1 - Reopen log file after SIGHUP. - Only log UDP address changes at the appropriate debug levels. - No need to check for pselect() in tinc 1.1. - Merge branch 'master' of git://tinc-vpn.org/tinc into 1.1 - Delete mtuevent if it is not used. - Don't call event_del() from the mtuevent handler, always send_mtu_probe() in ans_key_h(). - Don't use AM_CONDITIONAL for CURSES. - Add Makefile.am in gui/. - Update manpages and info manual. - Ensure that the texinfo manual can be converted to HTML. - Releasing 1.1pre1. - Ensure the right files end up in the tarball after make dist. - Thank Scott Lamb, Sven-Haegar Koch and Loïc Grenié in the NEWS file. - Merge Tinc.py into tinc-gui to simplify make install. - Re-add support for SIGALRM. - Don't call exit_control() if we didn't do init_control(). - Rename controlcookie file to pidfile. - Make pid files backwards compatible and add address of listening socket. - Add +git to the version string. - Really stable sorting of tincctl top output. - Use pidfile in tinc-gui as well. - Don't react to escape character in tincctl top. - Update documentation to mention pidfiles instead of controlcookies. - Remove debug messages that were printed to stdout. - Add manpage for tinc-gui. - Preliminary implementation of Elliptic Curve Diffie-Hellman Ephemeral key exchange. - Support ECDH key exchange. - Add PRF to derive key material from the ECDH shared secret. - Use PRF. - Proper use of PRF. - No need to keep around pointers to EC_GROUP. - Cleanups in ECDH code. - Base64 encoding and decoding functions. - Add ECDSA key generation. - Have tincctl generate ECDSA keys. - Finish base64 decoding routine. - Add ECDSA key import. - Round up the size of the secret parts after splitting it in two. - Add a minor number to the protocol version. - Bump minor protocol to indicate ECDH capability for UDP session keys. - Implement ECDSA sign and verify operations. - Read ECDSA keys. - Very primitive ECDSA signed ECDH key exchange for the meta protocol. - Hash input before signing it with ECDSA. - Free ECDSA and RSA structures when freeing a connection_t. - Automatically exchange ECDSA keys and upgrade to new authentication protocol. - Close meta connection socket after cleaning up event structures. - Require ExperimentalProtocol = yes for new features, update documentation. - Don't use wildcards in filenames in configure.in. - Make hexadecimal and base64 routines behave the same. - Make use of the improved hex and base64 functions. - Remove unnecessary variables and functions. - Fix compiler warnings. - Use the correct direction flag when setting cipher keys. - Use the same logic as tinc 1.0.x for detecting two nodes with the same Name. - Use ECDSA to sign ECDH key exchange for UDP session keys. - Update info manual. - Use usleep() instead of sleep(), MinGW complained. - Use const pointer to source in base64 and hex routines. - Ensure symlinked files do not end up in the tarball. - Fix declaration of usleep(). - "tincctl stop" now removes the tinc service on Windows. - Write loopback address instead of "any" address in pidfile. - Add missing newline. - Releasing 1.1pre2. - Fix tinc 1.0.x daemons connecting when ExperimentalProtocol = yes. - Don't abort() on low-level crypto errors, just return false. - Start of "Simple Peer-To-Peer Security" protocol. - Handle UDP packets with unknown source addresses properly. - Fix compiler warning. - Update SPTPS protocol. - Test corner cases in the SPTPS protocol. - Add counter mode encryption. - Use counter mode encryption. - Exchange ACK records to indicate switch to new keys. - Fix compiler warnings. - Fix a few small memory leaks. - Use only one hash algorithm (SHA512) in the PRF. - Remove useless warning about signature length being shorter than expected. - Merge branch 'master' of git://tinc-vpn.org/tinc into 1.1 - Merge branch 'master' of git://tinc-vpn.org/tinc into 1.1 - Apply HMAC after encryption. - Use SPTPS when ExperimentalProtocol is enabled. - Merge branch 'master' of git://tinc-vpn.org/tinc into 1.1 - Go back to breadth first search for path finding. - Ensure all SPTPS functions are prefixed with sptps_. - Let tincctl use the NETNAME environment variable if no -n option is given. - Merge branch 'master' of git://tinc-vpn.org/tinc into 1.1 - Don't close control connections when handling a reload command. - Allow log messages to be captured by tincctl. - Merge branch 'master' of git://tinc-vpn.org/tinc into 1.1 - Allow CTR mode counter to be set to a specific value. - Add datagram mode to the SPTPS protocol. - Test SPTPS messages sent while key renegotation is in progress. - Don't send an ACK message after the first key exchange in the SPTPS protocol. - Start documenting the SPTPS protocol. - Make sure the signature also covers the session label. - Merge branch 'master' of git://tinc-vpn.org/tinc into 1.1 - Merge branch 'master' of git://tinc-vpn.org/tinc into 1.1 - Add autoconf checks for OpenSSL's elliptic curve functions. - Update README to reflect that only OpenSSL is currently supported. - Always pass request strings to other functions as const char *. - Don't forget to send a newline when forwarding requests. - Merge branch 'master' of git://tinc-vpn.org/tinc into 1.1 - Fix crash when handling the ALRM signal. - Use /dev/tap0 by default on FreeBSD and NetBSD when using Mode = switch. - Document how to load the tap driver on FreeBSD. - Update THANKS file. - Merge branch 'master' into 1.1 - "tincctl init" creates initial directory structure, tinc.conf and keypairs. - Put every command in its own function. - Allow configuration variables to be added/removed using tincctl. - Stricter checks for node names. - Add an easy way to edit a configuration file. - Have tincctl notify a running tincd of configuration file changes. - Fix tincctl start. - Let tincctl ignore tincd options, so they will be passed on. - Fix tincctl dump. - Move all functions related to subnet parsing to subnet_parse.c. - "tincctl info" gives more human readable information about nodes or subnets. - Give an error message when tincctl info cannot parse the given subnet or address. - Strip default subnet weight from output. - Add an easy way to export and import host configuration files. - When exporting configuration files, don't copy Name variables. - Put minor protocol version in connection options so other nodes can see it. - Use minor protocol version to determine whether to use ECDH key exchange between nodes. - Never remove items from cmdline_conf. - Split setup_myself() into two functions, one for reloading configuration. - Allow more configuration variables to be changed when reloading configuration. - Prefer routes with lower weight as long as they do not increase the number of hops. - Make sure tinc compiles on Windows. - Make sure sptps.h and info.h are in the tarball. - BSD make doesn't like $<. - Fix various compiler warnings. - Call event_init() after detaching. - Add some checks when changing configuration. - Add a newline to a configuration file if it is missing. - Have tincd and tincctl use the same method of determining netname. - Fix some compiler warnings. - Fix crash when no netname is specified. - Don't try to mkdir(CONFDIR) on Windows when there is a registry key for tinc. - Use backslashes on Windows. - Windows doesn't like quotes around "edit" when calling it through system(). - Fix exit code when installing tincd as a service on Windows. - tincctl init now also creates a template tinc-up script. - Have tinc-gui use same way of locating pidfile as tincd and tincctl. - Remove unused po/ directory. - Also clarify hostnames=[yes|no] in tinc.conf(5). - Merge branch 'master' into 1.1 - Use datagram SPTPS for packet exchange between nodes. - Remove unused #include. - Handle SPTPS datagrams in try_mac(). - Add Brandon Black's replay window code to SPTPS. - Use a status bit to track which nodes use SPTPS. - Try sending SIGTERM if we cannot connect to a tincd but we know its PID. - tincctl restart should work even if no tincd is running. - Add the ability to query configuration variables to tincctl. - Add missing configuration variables. - Stricter checks for netname and node names. - Update the documentation to encourage using "tincctl init" and "tincctl config". - Clear struct sptps before reusing it. - Have tincctl act as a shell when no command is given. - Optionally compress and/or strip Ethernet header from SPTPS packets. - Add readline completion for tincctl config and tincctl info. - Fork when using the "start" command in tincctl. - Make sure the top command can be used more than once in tincctl's shell. - Add bash completion script. - Fix segfault when using tincctl's shell without readline. - Quit when "exit" or "quit" commands are used in tincctl's shell. - Fix node name check for "connect" and "disconnect" commands. - Properly handle SPTPS packets with stripped Ethernet headers. - Remove some debug messages. - Remove newlines at end of log messages. - Add a simple hash table implementation. - Use hash tables to lookup owners of addresses. - Replace node_udp_tree with a hash table. - Ensure sptps_test compiles with -flto. - Attribution for Vil Brekin and some code style cleanups. - Don't ignore Makefile.am. - Fix typo in manpage. - Remove remnants of Ethertap and old TUNSETIFF ioctl(). - Keep last known address and time since reachability changed. - Let tincctl parse and format dumps. - Allow dumping either directed or undirected graphs. - Update documentation of the "dump graph" command. - Comment out old public/private keys when generating new ones. - Fix links in documentation. - Fix links in documenation. - Let the GUI handle the new dump format. - Fix column sorting, make all lists sortable. - Correctly add/remove outgoing connections when reloading configuration. - Make tincctl robust against dropped control connections. - Remove some debugging messages. - Attribution for Martin Schürrer. - Add strict checks to hex to binary conversions. - Merge branch 'master' into 1.1 - Fix not reading Port statement from host config file. - Remove unused function declaration. - Make sure sptps_test compiles without -flto. - Remove abort() call that accidentily sneaked into commit dd1b69e. - Libreadline might depend on libcurses. - Fix off-by-one error. - Improve starting/stopping tincd using tincctl. - Clear connection options and status fields in free_connection_partially(). - When terminating, keep control connections open until the end. - Useful error messages when writing to a meta connection fails. - Make datagram SPTPS key exchange more robust. - Handle packets encrypted via SPTPS that need to be forwarded via TCP. - Remove a debug message. - Fix warnings from cppcheck. - Refactor outgoing connection handling. - Replace the connection_tree with a connection_list. - C99 extravaganza. - Fix deleting connections from the connection list. - Remove unused variables, fix some #includes. - Clear Ethernet header when reading packets from a tun device. - Fix memory leaks found by valgrind. - Fix hash functions for keys whose size is not divisible by 4. - Try all known addresses of node during the PMTU discovery phase. - Fix whitespace. - Clear status and options fields of unreachable nodes. - Strip newline from incoming SPTPS requests. - Fix handling of initial datagram SPTPS packet. - Only log success of initial datagram SPTPS handshake. - Make sure the ReplayWindow option works for SPTPS as well. - Log more messages using logger(). - tincctl: add node colors and edge weight to graph dump. - Fix compile error on Windows. - Update copyright notices. - Fix a few compiler errors/warnings. - Releasing 1.1pre3. - -Sven-Haegar Koch (29): - Merge branch 'master' into 1.1 - Fixed 1.0 miss-merges - Add missing AC_CHECK_HEADERS([dirent.h]) to configure.in - Function flush_meta() does not exist anymore. - README.git: tinc 1.1 needs libevent - Demote all LOG_EMERG to LOG_ERR, spamming all xterms is bad. - Fixed metadata protokoll corruption on forwarded requests - Fixed error logging on "Input buffer full" condition. - Removed two newlines from the end of log messages which created empty lines. - Use same definition for xalloc_fail_func as is really used. - sparse fixup: error: dubious one-bit signed bitfield - sparse fixup: error: too many arguments for function send_key_changed - sparse fixup: warning: symbol '...' was not declared. Should it be static? - sparse fixup: warning: non-ANSI function declaration of function '...' - sparse fixup: warning: Using plain integer as NULL pointer - fgets() returns NULL on error, not < 0 - src/net_socket.c bind_to_address(): Use after free in error path. - do_outgoing_connection() may delete a failed connection, and the structure - sptps_stop(): clear pointers after free to avoid double free. - Remove confusing error message for failed reading in ECDSA keys. - ecdh & ecdsa: avoid some possible memory leaks in error conditions. - terminate_connection(): Avoid use-after-free and double-free for - terminate_connection(): only kill c->node->connection if it is pointing - free_connection_partially(): Avoid possible use-after-free for c->hischallenge - Label control connections for log output as "", not "". - terminate_connection(): delete non-outgoing (aka incoming) connections. - Silence SPTPS log messages, reduce them from DEBUG_ALWAYS to DEBUG_META. - free_connection_partially(): also reset remote protocol version infos - sptps.c: Add missing newline to log message. - -Scott Lamb (19): - Rename "event_t" to "tevent_t", along with associated functions. - A couple missed tevent things. - Convert to libevent. - Lots of svn:ignore entries - Revert to only requiring autoconf 2.59. - Refresh po/POTFILES.in. - Updated svn:ignores list for new symlinked sources and tincctl. - const correctness - Temporarily revert to old crypto code - Update documentation to match tincctl changes - Fix reload crash - Fancier protocol for control socket - Dump through control socket - Purge through the control socket - Alter debugging levels through control socket - Retry connections through control socket - Reload configuration through control socket - Coding style corrections - Use a control socket directory to restrict access - -Vilbrekin (5): - Basic patch for android cross-compilation. - Replace hard-code with new ScriptsInterpreter configuration property. - Add basic .gitignore file, cleaning (most) files generated by autotools. - Use __ANDROID__ define rather than dirty hard-code to allow android NDK cross-compilation. - Android cross-compilation instructions. - -Michael Tokarev (3): - don't mention reload twice in tincctl help - run tincd from the same directory as tincctl and pass all options to it - use execvp() not execve() in tincctl start - -Martin Schürrer (1): - Output details of encryption errors - -Mesar Hameed (1): - Minor clarification, tinc.conf hostnames=[yes|no] variable only resolves names for logging purposes. - -Version 1.0.19 June 25 2012 ------------------------------------------------------------------------- - -Guus Sliepen (14): - Support :: in IPv6 Subnets. - Remove newline from log message. - Add support for systemd style socket activation. - Allow environment variables to be used for Name. - Allow broadcast packets to be sent directly instead of via the MST. - Add basic support for SOCKS 4 and HTTP CONNECT proxies. - Add support for SOCKS 5 proxies. - Add support for proxying through an external command. - Document new proxy types. - Small fixes in proxy code. - #include on Windows. - Fix compiler warnings. - Fix crash when using Broadcast = direct. - Releasing 1.0.19. - -Anthony G. Basile (1): - configure.in: fix AC_ARG_ENABLE and AC_ARG_WITH - -Michael Tokarev (1): - add (errnum) in front of windows error messages - -Version 1.0.18 March 25 2012 ------------------------------------------------------------------------- - -Guus Sliepen (13): - Always try next Address when an outgoing connection fails to authenticate. - Allow a port to be specified in BindToAddress statements. - Add support for multicast communication with UML/QEMU/KVM. - Set default value of DecrementTTL to "no". - Add #ifdefs in case not all platforms support IPv4 and IPv6 multicast. - Allow scoped addresses to be used for IPv6 multicast socket. - Fix compiler warnings. - Fix return value type of vde_send(). - Fix some more compiler warnings. - Document OpenBSD "ifconfig link0" and Linux "ip tuntap" commands. - Fix return type of vde_recv() as well. - Mark DecrementTTL option experimental. - Releasing 1.0.18. - -Version 1.0.17 March 10 2012 ------------------------------------------------------------------------- - -Guus Sliepen (32): - Prevent read_rsa_public_key() from returning an uninitialized RSA structure. - Return false instead of void when there is an error. - Fix compilation of VDE and UML interfaces. - Add vde/device.c to the tarball. - Fix a few small memory leaks. - Allow linking with multiple device drivers. - Set FD_CLOEXEC flag on all sockets. - Allow multiple BindToAddress statements. - Merge branch 'master' of black:tinc - Send packets back using the same socket as they were received on. - Allow setting DeviceType to tun or tap on Linux. - Merge branch 'master' of black:tinc - Only compile raw socket code when it is supported on that platform. - Decrement TTL of incoming packets. - Don't bind outgoing TCP sockets anymore. - Rename connection_t *broadcast to everyone. - Allow disabling of broadcast packets. - Move initialization of char *priority up to prevent freeing an uninitialized pointer. - Document the command line flag -o and provide --option as well. - Fix a bug that caused tinc to ignore all but the last listening socket. - Fix check for raw socket support. - Pass index into listen_socket[] to handle_incoming_vpn_data(). - Add LocalDiscovery option which tries to detect peers on the local network. - Don't send ICMP Time Exceeded messages for other Time Exceeded messages. - Stricter checks against routing loops. - Only use broadcast at the start of the PMTU discovery phase. - Only log errors sending UDP packets when debug level >= 5. - Accept Subnets passed with the -o option when StrictSubnets = yes. - Add missing ICMP6 message type definitions. - Make sure disabling old RSA keys works on Windows. - Update copyright notices. - Releasing 1.0.17. - -Nick Hibma (1): - Add missing ICMP message type definitions. - -Version 1.0.16 July 23 2011 ------------------------------------------------------------------------- - -Guus Sliepen (4): - Make code to detect two nodes with the same Name less triggerhappy. - Flush output buffer in send_tcppacket(). - Use usleep() instead of sleep(), MinGW complained. - Releasing 1.0.16. - -Version 1.1pre2 July 17 2011 ------------------------------------------------------------------------- - -Guus Sliepen (54): - Ensure the right files end up in the tarball after make dist. - Thank Scott Lamb, Sven-Haegar Koch and Loïc Grenié in the NEWS file. - Merge Tinc.py into tinc-gui to simplify make install. - Re-add support for SIGALRM. - Don't call exit_control() if we didn't do init_control(). - Rename controlcookie file to pidfile. - Make pid files backwards compatible and add address of listening socket. - Add +git to the version string. - Really stable sorting of tincctl top output. - Use pidfile in tinc-gui as well. - Don't react to escape character in tincctl top. - Update documentation to mention pidfiles instead of controlcookies. - Remove debug messages that were printed to stdout. - Add manpage for tinc-gui. - Preliminary implementation of Elliptic Curve Diffie-Hellman Ephemeral key exchange. - Support ECDH key exchange. - Add PRF to derive key material from the ECDH shared secret. - Use PRF. - Proper use of PRF. - No need to keep around pointers to EC_GROUP. - Cleanups in ECDH code. - Base64 encoding and decoding functions. - Add ECDSA key generation. - Have tincctl generate ECDSA keys. - Finish base64 decoding routine. - Add ECDSA key import. - Round up the size of the secret parts after splitting it in two. - Add a minor number to the protocol version. - Bump minor protocol to indicate ECDH capability for UDP session keys. - Implement ECDSA sign and verify operations. - Read ECDSA keys. - Very primitive ECDSA signed ECDH key exchange for the meta protocol. - Hash input before signing it with ECDSA. - Free ECDSA and RSA structures when freeing a connection_t. - Automatically exchange ECDSA keys and upgrade to new authentication protocol. - Close meta connection socket after cleaning up event structures. - Require ExperimentalProtocol = yes for new features, update documentation. - Don't use wildcards in filenames in configure.in. - Make hexadecimal and base64 routines behave the same. - Make use of the improved hex and base64 functions. - Remove unnecessary variables and functions. - Fix compiler warnings. - Use the correct direction flag when setting cipher keys. - Use the same logic as tinc 1.0.x for detecting two nodes with the same Name. - Use ECDSA to sign ECDH key exchange for UDP session keys. - Update info manual. - Use usleep() instead of sleep(), MinGW complained. - Use const pointer to source in base64 and hex routines. - Ensure symlinked files do not end up in the tarball. - Fix declaration of usleep(). - "tincctl stop" now removes the tinc service on Windows. - Write loopback address instead of "any" address in pidfile. - Add missing newline. - Releasing 1.1pre2. - -Version 1.1pre1 June 25 2011 ------------------------------------------------------------------------- - -Guus Sliepen (164): - Created the 1.1 branch where large code changes can take place, - Only free members of connection_t that have been allocated. - Port fixes from release 1.0.8. - Properly delete listener socket events on shutdown. - 128 listener sockets is way too much. - Use a separate event structure to handle meta data writes. - Use libevent to dump graphs when necessary. - Use libevent to handle HUP signal. - Configure events after obtaining a socket. - Use libevent to send MTU probes. - Use libevent for retrying outgoing connections. - Remove legacy event system. - Properly use the timeout_initialized() macro. - Use libevent to handle all non-fatal signals. - Redo SIGALRM handling. - Use libevent to age past requests. - Use libevent to age learned MAC addresses. - Use libevent to handle key expiration. - Move key regeneration handling to net_setup.c. - Remove global variable "now". - Remove the last bits of the legacy main_loop(). - Remove last references to the global variable "running". - K&R style braces - Use splay trees instead of AVL trees. - Detect duplicate outgoing connections. - More consistent variable naming. - Show branch version number. - Update documentation. - Start of control socket implementation. - We can safely delete a connection_t in terminate_connection() now. - Fix retrying outgoing connections. - Remove pidfile in favour of control socket. - Move key generation to tincctl. - Implement "stop" command, and allow tincctl to retrieve a running tincd's PID. - Use bufferevents to handle control socket buffering. - Use libevent for meta socket input/output buffering. - Parse PEM RSA keys ourself, and use libgcrypt to do RSA encryption and decryption. - Create wrappers for the cryptographic operations used in tinc. - Make sure the crypto wrapper functions can actually be compiled. - Some more crypto wrapper functions are needed. - Finish crypto wrapping. Also provide wrappers for OpenSSL. - Only check for libgcrypt if --with-gcrypt is used. - Fix formatting of --help output. - Small fixes to make gcrypt routines compile. - Apply patch from Scott Lamb: Update documentation to match tincctl changes - Fix connection weight estimation. - Use a dummy function as the read callback for connection bufferevents. Should not be triggered. - Fix meta data segfault when receiving a partial command. - Prevent double free() of a used challenge nonce. - Look in the configured sbin directory for the tincd binary. - Only show meta connection related debug messages when debug level >= 4 - Move AC_GNU_SOURCE up to make autoconf happy. - Use the crypto wrappers again instead of calling OpenSSL directly. - Backport fixes from trunk since revision 1555. - Fix compiler warnings. - Remove unnecessary parentheses from sizeof, apply sizeof to variables instead of types whereever possible. - Remove wrong checks. - Use Dijkstra's algorithm. Based on patches from Max Rijevskiy. - Make sure IPv6 sockets are IPv6 only. - Move RSA key generation into the wrappers. - Merge branch 'master' into 1.1 - Merge branch 'master' into 1.1 - Handle truncated message authentication codes. - Fix pointer arithmetic when creating and verifying message authentication codes. - Merge branch 'master' into 1.1 - Add missing #include. - Use correct format specifiers. - Replace asprintf()s not covered by the merge to xasprintf(). - Add a better autoconf check for libevent. - Merge branch 'master' into 1.1 - Drop localisation and checkpoint tracing in files not covered by the merge. - Update FSF address in files not covered by the merge. - Merge branch 'master' into 1.1 - Don't enable device events when there is no valid filedescriptor. - Use %x instead of %lx where appropriate. - Handle truncated message authentication codes with gcrypt. - Handle PKCS#5 padding in the gcrypt backend. - Make sure the 1.1 branch compiles in a MinGW environment. - Better integration of libevent in build system. - Small fixes to get really working control sockets on Windows. - Use the TCP socket infrastructure for control sockets. - Only call ioctlsocket() on Windows. - Merge branch 'master' into 1.1 - Fix compiler warnings. - Do not include OpenSSL headers directly. - Include missing header files and source directories. - Allow connections to be closed. - Start of a GUI for tinc. - Fix packet authentication. - Fix block cipher padding when using libgcrypt. - Reinitialise block cipher IV each time we encrypt a packet when using libgcrypt. - Fix reading raw RSA keys with libgcrypt. - recv() and recvfrom() return int, do not prematurely cast the return value. - Do not consider unreachable nodes when trying to determine packet origin. - Fix alignment of results of RSA operations when using libgcrypt. - Do not use hardcoded cipher block length when padding. - Remove unused AVL tree library. - Move source from lib/ to src/. - Fix experimental GUI when reading hexadecimal values. - Merge branch 'master' into 1.1 - Fix merge of commit 4a0b9981513059755b9fd15b38fc198f46a0d6f2. - Add missing return statement. - Use correct digest length when checking a received key. - Do not try to free NULL pointers. - Remove obsolete lib/ directory. - Merge branch 'master' into 1.1 - Link tincctl with dropin.o. - Merge branch 'master' into 1.1 - Do not try to dereference myself->connection->config_tree. - Merge branch 'master' of git://tinc-vpn.org/tinc into 1.1 - Fix check for event initialization due to the merge. - Add simple buffer management code. - Remove use of bufferevent and eventbuffers, use our own buffering instead. - Several fixes for the buffer code. - Add per-node traffic counters. - Dump traffic statistics over control sockets. - Add an autoconf check for the curses library. - Add a very primitive "top" command to tincctl. - Allow inserting items in the middle of a list. - Nicer top command. - Add tincctl.h. - Add top.h. - Use GetItemCount() on ListCtrls instead of directly accessing ItemCount. - Fix some compiler warnings. - Compact input buffer before trying to read instead of after. - Always compact the buffer if it has reached MAXBUFSIZE. - Check if an event is initialized before calling event_del(). - Reset tcplen after use. - Add the ability to dump all traffic going through route() over a control connection. - Allow tincctl to connect to something besides localhost. - Show hostname and port in error message when connecting to a running tincd. - Cosmetic fix when pressing 's' in tincctl top. - Initialise priority field to zero for packets read from the VPN interface. - Remove outgoing event in free_connection(). - Simplify signal handling. - Drop the GNU malloc.c, realloc.c, and xmalloc.c. - Drop the GNU memcmp.c implementation. - Don't #include anymore. - Remove unused functions and variables. - Remove support for the Ethertap device. - Fix some compiler and cppcheck warnings. - More stable sorting in tincctl top. - Make traffic statistics more readable with configurable scaling. - Fix nodes joining the VPN after tincctl top started. - Don't treat packets coming in via TCP as having zero length. - Remove debugging message that was accidentily left in. - Even simpler signal handling. - Small fixes for Windows. - Use send() when writing to sockets, and the return type is ssize_t. - Fix format strings for Windows. - Don't ignore SIGCHLD, system() needs it. - Clean up digests when freeing a connection_t. - Merge branch 'master' of git://tinc-vpn.org/tinc into 1.1 - Reopen log file after SIGHUP. - Only log UDP address changes at the appropriate debug levels. - No need to check for pselect() in tinc 1.1. - Merge branch 'master' of git://tinc-vpn.org/tinc into 1.1 - Delete mtuevent if it is not used. - Don't call event_del() from the mtuevent handler, always send_mtu_probe() in ans_key_h(). - Don't use AM_CONDITIONAL for CURSES. - Add Makefile.am in gui/. - Update manpages and info manual. - Ensure that the texinfo manual can be converted to HTML. - Releasing 1.1pre1. - -Scott Lamb (19): - Rename "event_t" to "tevent_t", along with associated functions. - A couple missed tevent things. - Convert to libevent. - Lots of svn:ignore entries - Revert to only requiring autoconf 2.59. - Refresh po/POTFILES.in. - Updated svn:ignores list for new symlinked sources and tincctl. - const correctness - Temporarily revert to old crypto code - Update documentation to match tincctl changes - Fix reload crash - Fancier protocol for control socket - Dump through control socket - Purge through the control socket - Alter debugging levels through control socket - Retry connections through control socket - Reload configuration through control socket - Coding style corrections - Use a control socket directory to restrict access - -Sven-Haegar Koch (18): - Merge branch 'master' into 1.1 - Fixed 1.0 miss-merges - Add missing AC_CHECK_HEADERS([dirent.h]) to configure.in - Function flush_meta() does not exist anymore. - README.git: tinc 1.1 needs libevent - Demote all LOG_EMERG to LOG_ERR, spamming all xterms is bad. - Fixed metadata protokoll corruption on forwarded requests - Fixed error logging on "Input buffer full" condition. - Removed two newlines from the end of log messages which created empty lines. - Use same definition for xalloc_fail_func as is really used. - sparse fixup: error: dubious one-bit signed bitfield - sparse fixup: error: too many arguments for function send_key_changed - sparse fixup: warning: symbol '...' was not declared. Should it be static? - sparse fixup: warning: non-ANSI function declaration of function '...' - sparse fixup: warning: Using plain integer as NULL pointer - fgets() returns NULL on error, not < 0 - src/net_socket.c bind_to_address(): Use after free in error path. - do_outgoing_connection() may delete a failed connection, and the structure - -Version 1.0.15 June 24 2011 ------------------------------------------------------------------------- - -Guus Sliepen (9): - Reorder checks for libraries to allow ./configure LDFLAGS=-static. - Make return value of SetPriorityClass() behave the same as setpriority(). - Fix sparse warnings and add an extra sprinkling of const. - Remove newlines from log messages. - Remove a few unnecessary #includes. - Attribution for Loïc Grenié. - Improved --logfile option. - Remove redundant @CFLAGS@ from AM_CFLAGS. - Releasing 1.0.15. - -Loïc Grenié (1): - Nearly tickless tinc. - -Version 1.0.14 May 08 2011 ------------------------------------------------------------------------- - -Guus Sliepen (48): - Fix reading configuration files that do not end with a newline. Again. - Define WINVER before including any other header file on Windows. - Use intptr_t instead of long to store a pointer. - OpenSSL 1.0.0 compiled for 64 bit Windows requires linking with -lcrypt32. - Fix all warnings when compiling with mingw64. - Use strrchr() insteaad of rindex(). - Detect and prevent two nodes with the same Name being on the VPN simultaneously. - Use 64 bit counters to keep track of bytes sent/received from the virtual network interface. - Do not append an address to ANS_KEY messages if we don't know any address. - Merge local host configuration with server configuration. - Remove duplicate command-line option parsing. - Attribution for Julien Muchembled. - Attribution for Timothy Redaelli. - Ensure there is a newline character before a PEM key is written. - Abort disabling old PEM keys on I/O errors. - Remove unused variables. - Quit when there are too many consecutive errors on the tun/tap device. - Read error counter must be static. - Add short options -R and -U to the tincd(8) manpage. - Don't use strlen() on a NULL pointer. - Provide usleep() for Windows. - Use variable length arrays instead of alloca(). - Fix warning message when setting SO_RCVBUF or SO_SNDBUF fails. - Free replay window when freeing a node_t. - Fix variable length array declaration. - Attribution for Brandon Black. - Use setpriority() instead of nice() on UNIX-like systems. - Always send MTU probes at least once every PingInterval. - Close all filedescriptors in Solaris close_device(). - Limit field width when scanning PID file. - Replace bogus #else with #endif. - Remove unused variables. - Document the behavior of "-n." - Update the manual. - Update the NEWS. - Proper check and dropin replacement for usleep(). - Fix typo spotted by Andrew Scheller. - Add support for VDE through libvdeplug. - Fix spurious misidentification of incoming UDP packets. - Prevent anything from updating our own UDP address. - Do not set indirect flag on edges from nodes with multiple addresses. - Increase threshold for detecting two nodes with the same Name. - Always use the default signal handler for ABRT signals. - Check for EVP_EncryptInit_ex instead of SHA1_Version in OpenSSL. - Update THANKS and copyright information. - Ensure proper linking with OpenSSL with recent versions of MinGW. - Include when using intptr_t. - Releasing 1.0.14. - -Brandon L Black (4): - Experimental IFF_ONE_QUEUE support for Linux - Configurable SO_RCVBUF/SO_SNDBUF for the UDP socket - Configurable ReplayWindow size, zero disables - Improved handling of queue-jumping packets on receive - -Julien Muchembled (2): - New '-o' option to configure server or hosts from command line - Fix command-line '-o' option for host configuration - -Timothy Redaelli (2): - Fix warnings showed using -D_FORTIFY_SOURCE=2 - Fix warnings under BSD - -Michael Tokarev (1): - Treat netname="." in a special way. - -Rumko (1): - DragonFlyBSD support - -Version 1.0.13 April 11 2010 ------------------------------------------------------------------------- - -Guus Sliepen (20): - Clamp MSS to miminum MTU in both directions. - Simplify reading lines from configuration files. - Check for dirent.h. - Preload all Subnets in TunnelServer mode. - Add the StrictSubnets option. - Add the Forwarding option. - Add the DirectOnly option. - Fixes for the Forwarding option. - ConnectTo does not mean tinc does not listen for incoming connections anymore. - Log unauthorized Subnets when StrictSubnets is set. - Fix typo. - Convert Port to numeric form before sending it to other nodes. - Ensure ICMP_NET_ANO is defined. - Reload Subnets when getting a HUP signal and StrictSubnets is used. - Fix reloading Subnets when StrictSubnets is set. - Ensure subnet-up/down scripts are called after HUP when necessary. - Fixes for definitions under Windows. - Don't redefine MAX if it already exists. - Mark Forwarding and DirectOnly options as being experimental. - Releasing 1.0.13. - -Timothy Redaelli (2): - Add --disable-lzo configure option - Add --disable-zlib configure option - -Sven-Haegar Koch (1): - Never delete Subnets when StrictSubnets is set - -Version 1.0.12 February 03 2010 ------------------------------------------------------------------------- - -Guus Sliepen (21): - When learning MAC addresses, only check our own Subnets for previous entries. - Remove unused variable in lookup_subnet_*() functions. - Forget addresses of unreachable nodes. - Do not fragment packets smaller than RFC defined minimum MTUs. - Allow port to be specified in Address statements. - Use xstrdup() instead of xasprintf() to copy static strings. - Allow Port and PMTUDiscovery options in tinc.conf, always enable PMTUDiscovery by default. - Clamp MSS of IPv4 SYN packets. - Ping nodes immediately when receiving SIGALRM. - Optimise handling of select() returning <= 0. - Also clamp MSS of TCP over IPv6 packets. - Make MSS clamping configurable, but enabled by default. - Fix subnet-up/down scripts being called with an empty SUBNET. - Run subnet-up/down scripts for local MAC addresses as well. - Be liberal in accepting KEY_CHANGED/REQ_KEY/ANS_KEY requests. - Determine peer's reflexive address and port when exchanging keys. - Immediately exchange keys when establishing a meta connection. - Try to set DF bit on BSDs as well. - Update copyright notices. - Ensure peers with a meta connection always have our key. - Releasing 1.0.12. - -Version 1.0.11 November 01 2009 ------------------------------------------------------------------------- - -Guus Sliepen (16): - Fix a possible crash when sending the HUP signal. - Starting to work towards 1.0.11. - Handle weighted Subnets in switch and hub modes. - Clarify and increase level of log message about MTU probes to unreachable nodes. - Add dummy device. - Use uint32_t instead of long int for connection options. - Allow UDP packets with an address different from the corresponding TCP connection. - Always reply to MTU probes via UDP. - Make maxmtu equal to minmtu when fixing the path MTU to a node. - Forward packets to not directly reachable hosts via UDP if possible. - Use IP_DONTFRAGMENT instead of IP_MTU_DISCOVER on Windows. - Use WSAGetLastError() to determine cause of network errors on Windows. - Move socket error interpretation to utils.h. - Fast handoff of roaming MAC addresses. - Start a tinc service if it already exists. - Releasing 1.0.11. - -Michael Tokarev (1): - Remove localedir leftovers. - -Version 1.0.10 October 18 2009 ------------------------------------------------------------------------- - -Guus Sliepen (78): - Update documentation for git. - Consistently allocate device and iface variables on the heap. - Only send packets via UDP if UDP communication is possible. - Move free()s at the end om main() to the proper destructor functions. - Change flush_events() to expire_events(). - Add missing cleanup functions in close_network_connections(). - Use a global list to track outgoing connections. - Remove unused definitions from net.h. - Allow reading config files with CRLF endings on Unix systems. - Validate Name before using it in a filename when generating a keypair. - Disable old RSA keys when generating new ones. - Handle neighbor solicitation requests without link layer addresses. - Allow weight to be assigned to Subnets. - Update THANKS and copyright information. - Disable PMTUDiscovery in switch and hub modes. - Use a simple Random Early Drop algorithm in send_tcppacket(). - Handle UDP packets from different and ports than advertised. - If PMTUDiscovery is not set, do not forward packets via TCP unnecessarily. - Fix link to Mattias Nissler's tun/tap driver for MacOS/X. - Fix initialisation of packet decryption context broken by commit 3308d13e7e3bf20cfeaf6f2ab17228a9820cea66. - Use xrealloc instead of if(ptr) ptr = xmalloc(). - Add declaration for sockaddrcmp_noport(). - Use packet size before decompression to calculate path MTU. - Do not forward broadcast packets when TunnelServer is enabled. - Add ProcessPriority option. - Add some const where appropriate. - Properly set HMAC length for incoming packets. - Don't try to send MTU probes to unreachable nodes. - Remove pending MTU probe events when a node's reachability status changes. - Do not log errors when recvfrom() returns EAGAIN or EINTR. - Change level of some debug messages, zero pointer after freeing hostname. - Always remove a node from the UDP tree before freeing it. - Add xasprintf() and xvasprintf(). - Check the return value of fscanf() when reading a PID file. - Replace asprintf() by xasprintf(). - UNIX signal numbers start at 1. - Ensure tinc compiles with gcc -std=c99. - Convert bitfields to integers in a safe way. - Add the GPL license to the repository. - Another safe bitfield conversion. - Add support for iPhones and recent iPods. - Don't stat() on iPhone/iPod. - Put Subnet weight in a separate environment variable. - Allow PMTUDiscovery in switch and hub modes again. - Handle unicast packets larger than PMTU in switch mode. - Remove superfluous call to avl_delete(). - Apparently it's impolite to ask GCC to subtract two pointers. - Use only rand(), not random(). - Also do not use drand48(), it is not available on Windows. - Allow compiling for Windows XP and higher. - Remove dropin random() function, as it is not used anymore. - Use access() instead of stat() for checking whether scripts exist. - Raise default crypto algorithms to AES256 and SHA256. - Remove extra {. - Use a mutex to allow the TAP reader to process packets faster on Windows. - Raise default RSA key length to 2048 bits. - Send large packets we cannot handle properly via TCP. - Update copyright information. - Remove all occurences of $Id$. - Remove Ivo's old email addresses. - Update the address of the Free Software Foundation in all copyright headers. - K&R style braces. - Remove checkpoint tracing. - Drop support for localisation. - Add more authors to the copyright headers. - Update the NEWS. - Remove autogenerated files from EXTRA_DIST. - Don't disconnect clients in TunnelServer mode who send unauthorised ADD_SUBNETs. - Remove code duplication when checking ADD_EDGE/DEL_EDGE messages. - Revert "Raise default crypto algorithms to AES256 and SHA256." - Ensure that the texinfo manual can be converted to HTML. - Small updates to the documentation. - Use MTU probes to regularly ping other nodes over UDP. - Allow the cloning /dev/tap interface to be used on FreeBSD and NetBSD. - Remove debugging message when reading packets from a BSD device. - Include missing header. - Fix description of the WEIGHT environment variable. - Releasing 1.0.10. - -Michael Tokarev (17): - Allow tunnelserver to work with clients that have other peers. - Enable PMTUDiscovery only if BOTH sides wants it. - Rename setup_network_connections() and split out try_outgoing_connections() - Implement privilege dropping - bugfix: initialize pid (as read from pidfile) to zero - bugfix: move mlock to after detach() so it works for child, not parent - bugfix: chdir(/) after chroot - change error messages in droppriv code to match the rest - format 'not supported on this platform' error message - TunnelServer: Don't disconnect client on DEL_SUBNET too - ignore indirect edge registrations in tunnelserver mode - don't log every strange packet coming to the UDP port - Fix ans_key exchange in recent changes - tunnelserver: log which ADD_SUBNET was refused - cleanup setpriority thing to make it readable - try outgoing connections before chroot/drop_privs - Remove extra semicolon in my definition of setpriority() - -Florian Forster (2): - src/linux/device.c: Fix segfault when running without `--net'. - src/net_socket.c: Bind outgoing TCP sockets to `BindToAddress'. - -Borg (1): - Removed last gettext function. - -Version 1.0.9 December 26 2008 ------------------------------------------------------------------------- - -Guus Sliepen (18): - Handle SERVICE_CONTROL_INTERROGATE requests. Thanks to Carsten Ralle for noticing this. - Make sure the prefixlength of subnets is sane. - Fix reading configuration files that do not end with a newline. - Do not try to send REQ_KEY or ANS_KEY requests to unreachable nodes. - Prevent freeing a NULL pointer when a hostname is unresolvable. - Correct debug message. - Treat virtual network device as tap if Mode = switch or hub. - Use TUNIFHEAD by default on FreeBSD to make sure IPv6 works. - Make sure IPv6 sockets are IPv6 only. - Update Dutch translation. - Update copyright information. - Enable PMTU discovery by default. - Update documentation. - Update the manpage as well, and some whitespace to make its source more legible. - Handle broadcast and multicast packets in router mode. - Apply patch from Max Rijevski fixing a memory leak when closing connections. - Add missing parentheses in check for IPv4 multicast addresses. - Releasing 1.0.9. - -Version 1.0.8 May 16 2007 ------------------------------------------------------------------------- - -Guus Sliepen (8): - Apply patch from Scott Lamb preventing an infinite loop when sending SIGALRM. - Apply patch from Scott Lamb fixing some memory and resource leaks. - Close the proper filedescriptor (if it exists). - Apply patch from "dnk" making sockets non-blocking under Windows. - Make sure connection->name is never NULL. - Update dutch translation. - Don't free struct addrinfo too early. Spotted by Christian Cier-Zniewski. - Releasing 1.0.8. - -Version 1.0.7 January 05 2007 ------------------------------------------------------------------------- - -Guus Sliepen (7): - Use a ringbuffer in shared memory to transfer packets from the tapreader thread to the main thread. - Tapreader socket should be bound to localhost only. - Fix generic BSD tun device to write only the actual packet length. - rename() cannot replace existing files on Windows. - No things to do for the 1.0 branch except bugfixing. - Update copyright notices. - Releasing 1.0.7. - -Version 1.0.6 December 18 2006 ------------------------------------------------------------------------- - -Guus Sliepen (13): - Make sure resolved addressed for outgoing connections are freed, if there are any. - Search for lzo/lzo1x.h, lzo2/lzo1x.h and lzo1x.h. - When building the minimum spanning tree, make sure we start from a reachable node. - Use the correct next pointer. - Remove unnecessary stuff from configure.in. - Remove old Spanish translation. - Fix rule that creates html version of manpages. - Use standard autoconf macros instead of our own. - We do properly check for malloc and realloc. - Remove the test for linux/if_tun.h. - Do a simple test for linux/if_tun.h instead of no test at all. - Prevent compiler warnings about redefinition of EAI_FAMILY on FreeBSD 6.1. - Releasing 1.0.6. - -Version 1.0.5 November 14 2006 ------------------------------------------------------------------------- - -Guus Sliepen (32): - Prevent possible buffer overflows when using very large (>= 8192 bit) RSA keys. - Add alloca.h to the list of necessary header files. - Enable OpenSSL ENGINE, so crypto hardware gets used. Thanks to Andreas van Cranenburgh. - EVP_Cleanup() when quitting. - Apply patch from Scott Lamb unifying configuration of TCP socket options. - Apply patch from Scott Lamb adding an output buffer for the TCP sockets. - Make sure $NAME is set correctly when executing tinc-down script. - Missing #include. - Export flush_meta(). - Fix signedness compiler warnings. - Fix a bug in handling prefixlengths that are not a multiple of 4. - Update copyright notices, remove Ivo's email address. - Restore length of the original packet in send_udppacket(). - Use memcpy() to copy sockaddrs returned by getaddrinfo(). - Add generic host-up and host-down scripts. - Do not break strict aliasing of status_t structs. - Fix format string warnings. - Remove unused variables. - Remove unused parameter from maskcmp(). - Remove unused variable. - memcpy() addresses from packet headers before calling the lookup functions. - The "active" bit in node.status is not used. - Added graph dumping ability based on Markus Goetz's patch. - popen() requires pclose(). - Support and autodetect LZO version 2.0 and later. - Support and autodetect LZO version 2.0 and later. - Document GraphDumpFile option. - Update Dutch translation. - Nodes use events, so event system should be initialised first and destroyed last. - When deleting an entire tree, start at head, not at root. - EWOULDBLOCK does not exist on platforms without O_NONBLOCK - Releasing 1.0.5. - -Version 1.0.4 May 04 2005 ------------------------------------------------------------------------- - -Guus Sliepen (17): - Make sure broadcast packet reach the local network interface. - Fix splay tree code. - subnet-up/down hooks - subnet-up/down hooks, use list_t for the todo list. - Small fix. - Free memory used by connection_t after it is deleted from the connection tree. - Use the proper free function. - Correct size argument for strncat(). - Nodes should only be in the node_udp_tree if they are reachable. - Don't try to add a non-existing node back to the node_udp_tree. - Remove unused (and potentially segfaulting) net2str() call. - Be on the safe side with initialisation of c->name. - Searching through splay trees may change the tree variable. - Several splay tree fixes. - Describe subnet-up/down scripts in documentation. - Update copyright notices. - Releasing 1.0.4. - -Version 1.0.3 November 11 2004 ------------------------------------------------------------------------- - -Guus Sliepen (77): - Removed items in TODO list that are already implemented. Only two items - Applied patch from Jamie Briggs for bash2 conformance. - Added another semicolon for bash2 compliance (thanks to Jamie Briggs) - Adding even more stuff from the CABAL branch. - Synchronise HEAD with CABAL branch. - This will become 2.0. - Some device.c files weren't synchronised. - Makevars file was accidentily removed. - Forgot to synchronise po/ directory... - Add description of new authentication scheme. - Add Opaque option which prevent information from being forwarded to certain nodes. - Replace Opaque and Strict options with a TunnelServer option. - Complain if pid file cannot be created. - Read MaxTimeout from tinc.conf like the manpage says. - Missing space between words. - Don't retry if configuration is wrong from the beginning. - Fix proxy-neighborsolicitation. - Code beautification, start of multicast support. - Forget multicast. Always inline some function. - Let tinc figure out the exact MTU of the link. - More sensible name, and try to set PMTU discovery on IPv6 sockets as well. - Describe the TunnelServer and PMTUDiscovery options. - Better name, show probed MTU in dump. - Improvements for PMTU discovery and IPv4 packet fragmentation. - Missing definitions. - Small fixes for PMTU discovery. - Don't forget to update destination MAC address. - Small updates. - Remove autogen.sh, the autoreconf program does exactly that. - Replace cvs-clean with a much better svn-clean. - Remove CVS related cruft. - Eat trailing whitespace in config files. - Only read our public key if it wasn't already in the private key file. - Updating dutch translation. - Even better svn-clean command. - Applied Martin Kihlgren's IdentityGenerosity patch, - Fix declaration of update_node_address(). - Use Subversion to create ChangeLog, better svn-clean rule. - Revert Martin Kihlgren's patch, it doesn't work the way it should. - Move CABAL branch to its rightful place: the trunk. - Update copyrights, links, email addresses and let Subversion update $Id$ keywords. - Increase MTU by 4 bytes to allow VLAN tagged Ethernet frames in hub and switch mode. - Clean up environment after executing scripts. - Handle timeouts during connecting the same way as other errors. - Added UML network socket handling. - Don't set $INTERFACE automatically, don't quit on EINTR/EAGAIN. - Marking potential late packets was in the wrong place. - Remove duplicate #include "system.h" - Move all #ifdef HAVE_HEADER_H #include to have.h, - Fix several #includes. - strndupa() is too arcane for some environments. - Allow tinc to work with the latest TAP-Win32 driver. - Correct return value. - Don't let tinc service depend on NDIS component. - Support alternative tun/tap driver from http://www-user.rhrk.uni-kl.de/~nissler/tuntap/ - Generic device driver for *BSD and MacOS/X - static - Check for sys/uio.h, net/if_tun.h and net/if_tap.h - Don't include .svn directory in sample configuration. - Splay trees. - Hoopjumping to get the default directories in the manuals properly. - Update to make it compile again. - Fixed another bug in late packet handling. - Hopefully this really fixes late packet handling. - Missing check for NULL-pointer. - Use the generic BSD tun/tap code. - Fix order of arguments for tar. - Let compiler decide when to inline. - Support tunneling IPv6 on Solaris. - Add BlockingTCP option, useful when using TCPOnly on slow or congested links. - Update documentation. - Set BSD tuns to broadcast mode. On OpenBSD, this enables IPv6 on the tun device! - Remove duplication. - Updated dutch translation. - Short readme about how to compile tinc from a Subversion checkout. - Add more people who have contributed to tinc. - Releasing 1.0.3. - -Ivo Timmermans (52): - Check for __gmpz_powm for libgmp3. - Changed version number to 1.0pre3. - Autogenerated by gettextize. - Bring head revision up to date with cabal (try #3) - Add check for the syslog function - Generalized error handling functions - Add all the new files to the sources list for the utility library - New function: xalloc_and_zero() - Generalized list and hash handling functions - First try to create a graphical frontend for tinc configuration - Updating HEAD branch #1; removing obsolete files. - Updating HEAD branch #2; removing debian/ dir. - Updating HEAD branch #3; more obsolete files removed. - Updating HEAD branch #4; Merging CABAL -> HEAD. - Updating HEAD branch #5; Last files from CABAL. - Ok, I forgot these ;) - More updates - More... - Last bits (hopefully) - Main pokey interface files. - Pokey interface definition - Write src/pokey/Makefile - Also compile in pokey/ - Remove debug level declaration - Update copyright info - Remove debug_lvl - New logging system to replace syslog() calls with a generic function. - Rename log_message to log - Add syslog() wrapper - Add syslog wrapper - Some magic - Added priority definitions from syslog.h - log_default_hook was renamed to log_default - Added prototype for log_syslog - Use logging.h instead of syslog.h - Compile in logging.c - Things to ignore... - Use new logging system - Include logging.h - Renamed libvpn to libtinc - Rename libvpn to libtinc - ... - Print newline when writing to stderr - *** empty log message *** - Moving files, first attempt at gcrypt compatibility, more interface - Commit diff test - Another file moved; random interface stuff. - Callbacks - Moved event.c/h - test - test 2 - Hm. - -Wessel Dankers (5): - Initial revision. Lots of loose ends, not usable yet. - added bit on config file, split up sections, added Id: tag - Added extra bit about keys. - More about keys - This file is now only in the CABAL revision. - -cvs2svn (1): - This commit was generated by cvs2svn to compensate for changes in r1352, - -Version 1.0.2 November 08 2003 ------------------------------------------------------------------------- - -Guus Sliepen (47): - Simplify fake getname/addrinfo() functions, possibly fixing freeing a NULL pointer. - stat() batch files under Windows. - Don't getsockopt() SO_ERROR. We get the error from send()/recv() anyway. - Fix fake getnameinfo() and check more arguments. - Fix --logfile under Windows. - Use the event log under Windows. - Compilation fix. - Do what the SDK documentation tells. - If we're not in main_loop() and the service is stopped, exit immediately. - Allow tinc to handle unknown type addresses from other tinc daemons. - Don't overwrite the first " when installing a service. - Add checkpoints. - When purging nodes, only delete them if nobody references them anymore. - Remove debug message. - Add license exception from Markus Oberhumer. - Remove old edges from unreachable nodes to us. This prevents the hosts/NAME-up - We don't have to tell GCC how to cast. - Prevent multiple inclusions. - Remove pidfile when exitting. - Update translations. - Check for short packets from the tun/tap device and from other tinc daemons. - Generate keys with 0x10001 as public exponent, which has less prime factors - Better length checks. - Copy structs from packets to the stack before using them, to prevent - const - Ethernet protocol types. - Unused variable in struct. - Don't confuse users with "Address family not supported" warnings. - Use CPPFLAGS, LDFLAGS and LIBS as appropiate. - PIDs are of type pid_t, and use %ld when reading/writing them to the pidfile. - Make sure type of AF_UNKNOWN is sa_family_t. - Forgot to #include "xalloc.h" - Update missing definitions, structs describing headers get __packed__ attribute. - Missing declaration. - Set media status for newer TAP-Win32 driver. - Some platforms don't know sa_family_t or define it other than uint16_t. - Update documentation. - Fix ASCII art. - Check return value of EVP_* functions, and check if length before en/decryption - Check all EVP_ function calls. - Parentheses in the wrong spots. - Fix bug that could lead to an assertion failure in libcrypto when multiple - Small fixes in documentation. - Fix another bug in meta.c. - Update dutch translation. - Add missing definitions. - Release notes for 1.0.2 - -Version 1.0.1 August 14 2003 ------------------------------------------------------------------------- - -Guus Sliepen (24): - Windows uses backslashes... - Tell windows to be patient. - Remove unused stuff from doc/. - Correct error message when remote host closed connection. - Simplify execute_script(). It will probably work under Windows as well. - Allow empty lines in config files. - Make rule for sample-config.tar.gz. - Readd quotes. - Typo. - Better error messages under Windows. - Log error first, try to close later. - Quote when needed and don't try stuff that doesn't work under Windows. - Under Windows, the installation directory can be found in the registry. - Better error checking and reporting. - Small things. - Simpler checking of permissions on private RSA key and other fixes. - Check for fchmod(). - Only system() needs script name quoted. - Update documentation. - Add a description for the Service control panel. - Updated dutch translation. - Small fixes. - Fix permissions check for rsa_key.priv. - Update. - -Version 1.0 August 08 2003 ------------------------------------------------------------------------- - -Guus Sliepen (111): - Thank some more people. - Run graph() after edge_del() when updating an edge. - Add documentation for BindToAddress. - Fix PriorityInheritance. - PrivateKeyFile instead of PrivateKey. - Run graph algorithm when replacing a second connection from the same host - Add $NAME for tinc-up/down scripts. - - Fix indentation in some places. - Various fixes for autoconf and OpenSSL 0.9.7 and a missing header. - Make sure send_meta() writes everything. - Typo. - - Avoid memory leak caused by OpenSSL 0.9.7a. - - Speed up checksumming - Don't copy more than necessary. - Checksums must also work for uneven number of bytes. - HUP signal now closes connections to hosts if their host config file is - Better handling of late packets. - Make sure outgoing_t is completely freed. - - Per-node EVP_CIPHER_CTX to avoid initialisation overhead. - Small fixes to make LZO compression work. - Small fixes. - Fix links. - Fix warning and add missing checks for LZO library. - Call make_names() before doing anything else. - If we have a Linux tun/tap device and we are in router mode, open the device - AddressFamily is "any" by default. - Remove mymac stuff from device.c. - Fixes from Wessel Danker's libavl. - More braces to make gcc happy. - Update documentation. - Update dutch translation. - Typo and conversion to UTF-8. - There are two lzo compression levels. - Really make tinc default to any addressfamily. - This subtle pointer arithmetic thingy is (I'm very sure of it) the cause - - simplify configure.in - Check for IPv6 header files. - Define logger(), cleans up source code and allows us to write log entries - Sprinkling the source with static and attributes. - Provide all missing IPv6 definitions in lib/ipv6.h. - Actually add ipv6.h. - More missing definitions. - More missing IPv6 definitions and autoconf checks to make sure it compiles - Simplify logging, update copyrights and some minor cleanups. - Update copyrights. - Removing distribution specific files from CVS. - Format string checking for logger(). - Export mymac. - Make use of the CIPE driver. Woohoo, tinc for Windows! - Windows headers declare a struct interface somewhere. - Big header file cleanup: everything that has to do with standard system - Even more missing definitions. - Remove all #ifndefs from route.c - Update all device.c files. - Check for ethernet/ipv4/ipv6 related structures. - Use iface instead of interface because it might already be declared in - Oops. - No UNIX style permissions under Windows. - Be consistent. - Oops. - Check for sys/mman.h. - Use functions from logger.c - Copy cygwin driver to mingw directory. It doesn't work (yet). - Add section about configuring Cygwin and CIPE on Windows. - Option to specify pidfile location. - Use bools and enums where appropriate. - Run setup_device() after parsing configuration but before claiming we're ready. - Don't initialise a CIPHER_CTX if cipher == NULL. - Sprinkle around a lot of const and some C99 initialisers. - More generic handling of tap device under Windows. - More checks for missing functions. - Fix compile errors and warnings. - Update dutch translation and make sure all device drivers are included in - Update configure scripts. - Make sure it works. - Make sure (at least) the MinGW device driver works. - Native Windows support. - Cleanups. - Update documentation and remove stuff that's too outdated. - Remove doc/es/ and src/device.c from the distribution. - No C99 initialisers, gcc 2.95.3 doesn't like it. - Replacement for stdbool.h - Prevent definitions from messing up attributes. - Check if the compiler knows about the __malloc__ attribute. - Wrong argument. - Remove forgotten braces. - No easy way to properly detect header files... - Woops! - Wrong function... - Prevent system headers from including our own headers. - Allow whitespace in values. - Oops. - Windows has no symbolic links as we know it. - When compiling with MinGW, link with ws2_32. - Install tinc as a service under Windows (MinGW). Remove cleanup_and_exit(), - Error messages. - Cleanups and error messages. - Missing include. - Oops. - Updated dutch translation. - Explain how tinc detaches and how it is "killed" under Windows. - Typo and another thing to think about. - Clean up last part of main(). - Old gcc compilers don't like declarations in the middle of a function. - Cygwin needs windows.h. - Keep Windows happy. - Remove newlines from log messages. - Update dutch translation - Simplify translation - Use our own port when connecting to ourself. - Sync CABAL branch with release-1_0 branch. - -Ivo Timmermans (2): - Fix saving of debug level for startup level 0 - Call RSA_blinding_on(), as advised in the paper on - -Wessel Dankers (1): - its: Engels voor "van het" - 3e persoon enkelvoud, genitief, onzijdig - -Version 1.0pre8 September 16 2002 ------------------------------------------------------------------------- - -Guus Sliepen (73): - Support for MaxOS/X. - Add BindToAddress variable, similar to the late BindToIP. - Added Nick Patavalis for his RedHat package. - Informative log message if execl() failed. - Fix very stupid bug in node_del(), which might have caused corruption of - Only purge once when there are no more connections. - Support RSA_PUBKEYs (as opposed to RSAPublicKeys) so tinc accepts - Make it work correctly with NetBSD tun device. - Use correct includes on NetBSD. - Cleanup: - Use inttypes.h instead of stdint.h. - - netinet/* include files depend on netinet/in_systm.h. - Added Darwin (MacOS/X) tun device handling. - Use darwin/device.c when compiling on MacOS/X. - Include darwin/device.c in distribution. - Autoconf cleanup. Works for both 2.13 and 2.53, although running autoconf - Add configuration details for NetBSD and Darwin (MacOS/X). - Reset listen_sockets after SIGHUP. - Update comments about IPv6 autoconfiguration. - s/sliepen.warande.net/sliepen.eu.org/g - Fix for prefixlengths of 32 (IPv4) and 128 (IPv6) bits. - Allow list of environment variables to be passed to execute_script(). - Allow identical subnets from different owners. - Clear subnets before using them. - Started port to Cygwin. - Added stub device.c for Cygwin. - Include complete fake-getname/addrinfo from OpenSSH. - Allow tincd to be locked into main memory. - Don't bother to chown, and correctly document ConnectTo. - Added support for raw sockets. This can be used instead of tun/tap devices. - Gettext 1.11.5 compatibility. - Check for ranlib. - Replacement for the current routing algorithm. - Make sure setlocale() is available. - Drop graph and edge stuff. Use new node stuff instead. - A reachable node is always more preferable to an unreachable one... - Woops. - Reduce KEY_CHANGED traffic. - Prevent looping DEL_NODE/ADD_NODE messages after a node disconnects. - Don't forget to set prevhop to myself for new connections. - Just ignore wrong ADD_NODEs instead of replying with a DEL_NODE, in the - Revert to edge and graph stuff. This time, use a directed graph. - Small fixes. - Generalized request broadcasting/forwarding. - Updated dutch translation. - Small updates. - Run autopoint and libtoolize before creating initial makefiles. - Add missing headers. - Typo. - Only reset seqno's when a key is sent or received. - Remove global edge_tree. - edge_weight_compare() shouldn't rely on edge_compare(). - Reset the *correct* seqnos. - Fix MST algorithm. - Why don't these connection_t's get cleaned up? - Cleanups: - Switch to K&R style indentation. - Switch to K&R style indentation. - Remove redundant spaces. - Let GCC check format string and arguments of send_request(). - Fix compiler warnings. - Clean up after indent. - Link with libintl if necessary. - Fix placement of #include "config.h" - Make sure malloc() is declared. - What was I thinking? - MacOS/X needs #define _P1003_1B_VISIBLE in order to use mlockall(). - port_t isn't used anymore and conflicts with MacOS/X headers. - Small fixes so tinc compiles out of the box on SunOS 5.8 - Updated dutch translation. - Use /dev/net/tun as default for tun/tap device under Linux. - Update documentation. - Remarks about 1.0pre8 release. - -Ivo Timmermans (9): - Put #ifndef checks for HAVE_RAND_PSEUDO_BYTES in the correct places. - Typo - OSX support - getnameinfo fixes - Add /sw/{include,lib} to search paths if they exist - Include a few more header files - Include netbsd's device.c in make dist - Added Alessandro Gatti - Added AM_MAINTAINER_MODE - -Wessel Dankers (1): - This should work much better. - -Version 1.0pre7 April 09 2002 ------------------------------------------------------------------------- - -Guus Sliepen (9): - Make configure --help output look nicer. - Don't check_network_activity() if select() is interrupted by a signal. - check_rsa() is broken, I don't know why, just remove it for now. - Fix maskcheck() and maskcmp(). - Automake forgets about depcomp, remind it. - masklength is better known as prefixlength. - masklength is better known as prefixlength - Updated dutch translation. - Remarks about 1.0pre7 release. - -Version 1.0pre6 March 27 2002 ------------------------------------------------------------------------- - -Guus Sliepen (91): - Forgot to merge new files from pre5. - Last bits of the merger. - Sensible defaults for $INTERFACE. - - If no PrivateKeyFile is specified, /etc/tinc/netname/rsa_key.priv is assumed. - Small fix. - Added support for packet compression, thanks to Mark Glines. - Don't use sa_sigaction (which NetBSD doesn't like) at all if we don't use siginfo. - Get rid of sys/signal.h. - Added device.c for NetBSD, actually a copy of the OpenBSD one. - Add check for NetBSD. - - Non-blocking connect()s. - Fix segfault when receiving HUP signal. - Use AF_UNSPEC for listening sockets if AddressFamily = any. - Forward packets in router mode. - Fix maskcmp() and maskcpy(). - Cache results of lookup_subnet_...(). - Protocol now also exchanges cipher/digest/maclength/compression for the - Preserve inpkt->len, needed for broadcasts. - - Use gai_strerror() where appropriate - - Change SA_LEN to SALEN, former one is already defined on some platforms. - Tweaking IPv6 support. - Allow multiple listening sockets. - Fix send_request() bug. - Make BindToInterface work. - Fix listening sockets. - If "PriorityInheritance = yes" is specified in tinc.conf, the value of the - Create/bind TCP and UDP listening sockets in pairs. - Updated documentation. - Updated dutch translation. - - Global time_t now, so that we don't have to call time() too often. - Document and clean up MAC address expiry. - Woops. - Check if BindToDevice and PriorityInheritance are supported. - Fix forwarding of IPv6 packets. - po/POTFILES and po/Makefile should not be generated by configure. - Autodetect $MAKE/gmake/make. - Small fixes to improve portability. - Don't retry to make outgoing connections when exitting. - Cleanups, spelling fixes, allow symbol names for signals (-k option), - prune_connections() before build_fdset(). - Try to reply to neighbor solicitation requests. - New strategy: forward icmp6 neighbor solicitations to intended target. - Simplified implementation of Kruskal's minimum spanning tree algorithm. - Packet sequence number/authentication warnings only if debug_lvl >= 5. - Remove silly cache thingy. - Put #ifdef NEIGHBORSOL around corresponding code. - Revert changes to Kruskal's algo. - Neighbor solicitation requests now work (I think). - Oops, don't forget to actually put the checksum in the response packet. - Different way of detecting neighbor solicitation requests. - Typo. - Unmap v4mapped sockaddrs. - Only unmap IPv6 addresses. - #define s6_addr32, needed for FreeBSD. - Fix #define s6_addr32. - Remember sockaddrs of listening sockets, use appropriate one when sending - Cleanup. - Don't use s6_addr[16|32] anymore. - Updated dutch translation. - Updated SSSP algorithm to automatically detect indirect links (if a node uses - Put a break on requests that run around in circles. - - Added support for jumbograms. - Fix add_edge_h(). - Fix compiler warnings, strictly use long int and %lx for options. - send_ack() was broken. - free() request strings when deleting past requests from the tree. - Don't run graph algorithms if no edge is deleted in terminate_connection(). - Reset retry timeout when receiving the first PONG, not right after receiving the ACK. - Don't try to execute scripts unless they exist. - Execute hosts/name-up when a node becomes reachable, and hosts/name-down - Set $INTERFACE correctly when using ethertap while compiled with tun/tap support. - Updated dutch translation. - Respect type field. - OpenBSD tun device uses address family number instead of Ethernet type. - Configuration variables were still handled case sensitively. - Set myself->status.reachable. - Updated documentation. - Tell a little bit more about security. - Send REQ_KEY only once until ANS_KEY has arrived. - Fix execute_script(). - Small correction. - Merge do_prune() with build_fdset(). Probably fixes the invalid filedescriptor error. - Extend list_t with the number of elements in the list. - Limit the amount of packets in a queue to 8. - Small updates. - Remove cruft. - Recent automake uses $(AMTAR) instead of $(TAR) - Remove symlink to device.c when doing a make dist. - Fix format strings. - Update dutch translation. - Update with information about the pre6 release. - -Version 1.0pre5 February 10 2002 ------------------------------------------------------------------------- - -Guus Sliepen (109): - Small fixes to allow correct compilation under FreeBSD (tested with 4.3) - Make sure Solaris is happy too. - Fix subnet_lookup() for overlapping subnets. Needs rethinking. - Added proxy-arp support. No more ifconfig -arp needed. Works like a charm - - tinc can now act as a switch or a hub too (as opposed to a router only) - Changed some stuff to allow correct generation of po/Makefile after a - Updated dutch translation. - - This oneliner removes the need for ifconfig tap? hw ether fe:fd:0:0:0:0 - Fix bug where lookup_subnet_ipv4() could go into an infinite loop. - You can now put an option "Mode" in tinc.conf, and choose from: - Add missing? counting of total_socket_in. - Log and warn about duplicate subnet_add()'s for the same subnet. - Fixes to make switching work between hosts that have no meta-connection. - Save configure cache more often. - Changed drastically because it didn't work correctly: - Only reset seconds_till_retry when we activate the outgoing connection. - Woops - big bug in send_key_changed fixed. - - Solaris compile fixes - Check for and add -ldl. - Remove #warnings I used for debugging stuff. - Reinstated search for if_tun.h in kernel source tree, because apparently - Spanish translation removed. Nobody maintains it, and it is severely - ABOUT-NLS is created by autogen.sh. - Don't build Spanish translation. - Execute tinc-down BEFORE tap device is closed. This is a. more symmetric - es.po revived. - Also remove po/Makefile.in.in, which is generated by autogen.sh. - Log error if two hosts connect with same IP/port tuple. - Fix gcc 3.0 warnings. - Check for dlopen in standard libraries first (needed for DEC OSF). - It appears that autogen.sh doesn't like es.po if it isn't mentioned in - Update of RedHat build scripts. - Dutch translation updated. - More items marked as done. - Fix printf format bug. - Fix compiler warning. - Check for all potential duplicate entries in the id tree. - - Always use instead of just - Don't load table of verbose OpenSSL errormessages. - Correct inclusion of standard if_tun.h header file. - Split connection list into two lists: - Correctly use the active_tree. - Remove all unnecessary status.meta and status.active checks. - Added purge_tree for connection_t's which are no longer in the connection, - Updated terminate_connection() so you can choose if DEL_HOSTs should be - Always close all sockets in terminate_connection(). - Woohoo! tinc now compiles, runs and actually *works* on Solaris! - Started writing a document about how daemons connect to each other. - Described problem in more detail. - Small update. - Correctie. - Written down a possible solution. - Discuss how sending ADD_EDGEs would be better than sending ADD_HOSTs. - More on edges. - Don't use %m in fprintf(). - Write public key to rsa_key.pub instead of rsa_key.priv (if not host - The val variable in a config_t is never used as a long. - Explicitly log which type of tunnel device is used. - Don't send DEL_HOSTs when !status.meta - Fix signed comparison bug in lookup_subnet_ipv4(). - Remove IndirectData support for now, new implementation will be added - Revised reconnection mechanism, always try out all ConnectTo lines. - Optional signal number for -k option. - config_t* is a const parameter in get_config_val(). - - Try old TUN/TAP ioctl() request if the one from if_tun.h fails. - Not only keep track of nexthop, but also of lastbutonehop. If destination cl - Show next- and lastbutonehop when dumping connectionlist to syslog. - Try next connectto instead of the same over and over. - Fill in next- and lastbutonehop for myself. - - Renamed lastbutonehop to prevhop. - Fix bug where tinc would crash because of a portscan or a connection from a - - Use ping timeout mechanism to close connections that don't authenticate - Fix bug when dropping an old connection in favour of a new one from the - Updated dutch translation. - Started implementing doc/CONNECTIVITY. - Small corrections. - Further implementation of doc/CONNECTIVITY. connection.[ch] is now split into a - Removed everything from connection.c that has already been moved to node.c and - Revamp configuration handling: - More updates to new node/vertex/connection combo. - - Split tap device stuff out of net.[ch] - Added FreeBSD tap device handling. - Solaris tun device handling cleaned up a bit and added. - Forgot to remove some old #ifdef stuff. - Added OpenBSD tun device handling. Untested though. - Forgot the tun specific stuff. - Support new files (node/vertex/device.[ch]) and OpenBSD. - Big bad commit: - Make sure everything links. - Various small fixes to make tinc runnable again. - What was I thinking? s/vertex/edge/g. - - More s/vertex/edge/g - - More changes needed for Kruskal's algorithm - Working version of Kruskal's algorithm. The running time is very bad though. - Various fixes, tinc is now somewhat capable of actually working again. - More updates to protocol handlers and reimplemented terminate_connection(). - - Small fixes to graph algorithms - Don't forget to read public RSA key when making an outgoing connection. - Show cfg->variable instead of cfg->value when complaining about wrong type. - Avoid connecting to another node twice, and check name of outgoing connections. - Some very small fixes - Use PEM functions as suggested by OpenSSL docs. - Several bugfixes. - *** empty log message *** - Be liberal in what you accept: allow unknown edges to be deleted. - Correctly check if subnet owner exists. - Various fixes needed for Solaris. - More fixes for Solaris. - Merging of the entire pre5 branch. - -Ivo Timmermans (32): - New make target: `make release' - Changed version number to 1.0-cvs - Don't distribute autogen.sh in a release - Don't include the debian/ dir in a release - Small fix to make it compile again - Killing tincd with SIGINT causes it to toggle between the current - Check for getaddrinfo - Check for getnameinfo, gai_strerror, freeaddrinfo - Credit OpenSSH - Check for struct addrinfo - Deprecated get_config_ip and get_config_port - Use struct addrinfo in connection_t to hold all host data such as IP - Changed prototype for lookup_connection to use struct addrinfo - Changed lookup_connection to use struct addrinfo - Removed definitions of ipv4_t, ipv6_t, port_t - Obsoleted all IP types in favor of struct addrinfo - Changed to use struct addrinfo where needed. - get_config_{ip,port} removed. - Don't compile/link netutl.c. - Obsoleted. - Don't include netutl.h. - (re)added port to struct node_t - Added HAVE_STRUCT_ADDRINFO - Added dropin replacements for get*info and helper functions. - First part of rewriting things to use struct addrinfo. - lookup_node_udp changed. - Don't include netutl.h. - route_ipv4 and route_ipv6 replaced by route_ip. - get_config_subnet needs to be fixed. - Fixed silly typo: "np" instead of "no" - Don't include netutl.h. - Conversion to struct addrinfo is almost complete for this file. - -Wessel Dankers (1): - make is not always GNU make. - -Version 1.0pre4 May 25 2001 ------------------------------------------------------------------------- - -Guus Sliepen (97): - Porting to FreeBSD: - - Added balanced tree management stuff as well. (It is not finished yet.) - - Simplified do_detach - - Removed stray @INCLUDE@ (how did that get there?) - - Fixed searching - - Implemented deletions - - Fix tree head/tail upon insertion - - Fixed a lot of small things. Tested everything except deletions. - - Deletion also works now. - - Small fixes - - Integrate rbl trees into tinc. - - Proper initialization of rbltree structures. - - Various small fixes. - - More fixes. - - Check for NULL tree->delete callback - - Cleaned up and checked for some more NULL pointers in rbl.c - - Write pidfile AFTER detaching... - - No more %as. - - Work with the correct key buffer in ans_key_h - - More porting to FreeBSD and Solaris. - - Fixed all (except 2) compiler warnings gcc -Wall gave. - - #include instead of - - Don't link with -ldl anymore - Another big & bad commit: - - Added Armijn to the list - - Added daemon() replacement. - - Use only one socket for all UDP traffic (for compatibility) - - Don't even think about using sscanf with %as anymore - - AVL tree routines: faster than RBL, and also more stable. - - Doubled size of trace buffer for easier debugging. - - Let user choose whether keys are in the config files or separate - - Updated dutch translation. - - Check and follow symlinks in is_safe_path - - Changed license of AVL tree library to GPL. - - Updated manual pages. - - Updated texinfo manual. - - Typo. - - Changed list routines to give it the same look'n'feel as the rbl and - - Reinstated a queue for outgoing packets. - - Added header file for route.c. The routing routines in it are not used - - Description of protocol and authentication updated. - - It's 2001, all copyright notices are updated. - - Fixed IPv6 subnet lookup routine. - - Added indirectdata and tcponly functionality. - - Squashed another nasty bug. - - Sign was wrong in search_closest_smaller/greater - - Cleaned up subnet_t - - Only send out DEL_HOSTs for hosts with a meta connection - Added sample configuration directory. - - Copy entire sample-config directory to /etc/tinc/example upon installing. - - Allow ASN1 style keys to be in the config files. - FreeBSD compile fixes (thanks to XeF4) - Fix memory leak in avl_insert() if item was already inserted. - Updated dutch translation. - Removed another local definition of the variable "errno" - Added .cvsignore files to get rid of warnings and prevent autogenerated - Ignore file for src/ - - Updated CVS_CREATED to remove intl/ directory and some other - Added description of the proposed new authentication scheme. - Corrected check for errors after read() calls. - Add missing \n. - Free node->data and node, not node->data twice. - Copy packets before putting them in the queue. - Encrypt network packets in CBC mode instead of CFB mode. - Implemented new authentication scheme from doc/SECURITY2. - Added process.c to the translated files. - - Make sure METAKEY is smaller than the modulus of the RSA key - Don't forget to reconnect if outgoing connection fails during - - Fixed Interface option (untested) - Removed lots of compiler warnings. - Removed compiler warning. - Various small fixes. - Added explaination of our key exchange using RSA encryption. - - route.c is now used to determine destination - Updated translation. - Added a description of what is going on in net.c and route.c, and how - Fixed a race condition triggered by receive_meta() and the new - Fixed bug in setup_signals() that would make tinc die when unexpected - Ignore alarm signals if we do not need to respond to them. - Check indirectdata option before forwarding certain requests. - Depend on new ssl package and install alias for universal TUN/TAP module. - Correctly cycle through ConnectTo variables. - - s/ip_t/ipv4_t/g - - Make sure correct information is supplied for both old kernels (with - More revisions to the documentation: - Changed URL from kernelnotes.org to linuxdoc.org. - Add randomness to PING/PONG packets to prevent crypto attacks on quiet - Since this is incompatible with some earlier versions, PROT_CURRENT is - All features for 1.0 are implemented now, we just have to check the - Only send key_changed if it was previously requested. - Small fixes: - Small corrections to the manuals. - With recent kernels the tun device file is located in /dev/net. - TCPonly now works (in a relatively clean way too). - Merged PROTOCOL, NETWORK and SECURITY2 with the texinfo manual. - Documents are merged. Now we only need to check the ports and the TCPonly - Fix sample configuration to show keys in PEM format and correct tapdevice. - -Ivo Timmermans (88): - Add a check for openssl that accepts explicit file locations. - Identify version as 1.0pre4-cvs - Better checks for OpenSSL. I think it can now detect almost all conceivable installations. - Oops, small error. - Get rid of the annoying empty line - Also check for rand.h and err.h. If any of these files does not - Also check for sha.h. - Use the HAVE_OPENSSL_xxx_H defined from m4/openssl.m4 during - Let the output from an executed script in execute_script() go to - List management and manipulation routines. - Keep a list of running children, and in each loop in main_loop(), - Move all process-related functions into process.c. - New function: xmalloc_and_zero, which initialises the allocated memory - Delete struct ifr - Move more functions from tincd.c into process.c. - Use proper prototypes. - Added this release - More function and header checks - Also include process.h - Get rid of all libtool references at once. libtool was only used by - Honor the --localstatedir option to configure, instead of hardcoded /var. - Add more checks to ensure that filedescriptors are right in - Declare fd. - Do not use the C library's daemon() call. - Do not check for the daemon() system call - Do not attempt to retreive ChangeLog information only from the CABAL - Set localstatedir to /var - Use cvs2cl instead of rcs2log to generate the ChangeLog. - Set CFLAGS to -O2 -Wall when running configure - Alter CFLAGS, somehow INCLUDES doesn't propagate properly. Still - Set errno to 0 before trying to kill the other process. - Explain how to tell configure where OpenSSL lives. - Call autogen.sh instead of configure alone; and make cvs-clean instead - Add default tinc-up and tinc-down scripts for a Debian system. These - Updated Spanish translation, provided by Enrique Zanardi. - Give an error message if daemon() failed. - Check for the function strsignal, and define it to "" if it is not - Sort items to either 1.0 or future release goals. - Use sigaction to set signal handlers, the previous commit (1.1.2.16) - Save RSA public and private keys to a separate file, instead of - dropin.c/h contain a set of drop-in replacements for non-standard C - Check for get_current_dir_name. There is a replacement function in - Added a check for a scanf that knows about %as. - Implemented a readline() function that will read an entire line into a - xstrdup now takes a const pointer as an argument. - Use readline() in read_config_file() instead of fgets. - Also free the pointer returned by readline(). - Updated Dutch translation - Implemented is_safe_path, and extended ask_and_safe_open. - Read the PEM file pointed to by the configuration directive - The file is safe if it doesn't exist. - In readline(): initialise the line to zero length; - Better error checking when reading the RSA private key. - Avoid printing duplicate messages from read_rsa_keys - New function read_rsa_public_key(); - All full stops have two spaces after them. (Silly commit, I know.) - Tagged `Storing private key in separate file' as done. - readline() accepts two extra parameters, buf and buflen, to avoid - Use buffer instead of line in read_config_file(), line may be assigned - Stated that distributing executables linked with OpenSSL is permitted - Include COPYING.README in the distribution. - Added documentation merger - Sort configuration directives - Option -d accepts an argument to set the debug level immediately. - Massive long awaited documentation update. It's not finished yet, - Oops. I did some VERY wrong things with readline(). Fixed now. - Tiny bits of code beautifying - Install a file in /etc/modutils/tinc, containing all necessary aliases - Ported it back to /bin/sh. - Give a warning about having to re-create the keys - Re-introduced MyVirtualIP and VpnMask, as dummy options. - Various small changes. - Include autogen.sh (needed for the Debian package). - Forget router.c - Added lint target, requires lclint. - Fix error reporting of read_config - Set Architecture to `any' - Change version to 1.0pre4 - Second draft of the release notes - Merged documentation with various updates I had lying around - Get the Debian changelog up to date - Get the PO files up to date with the current source - Fixed some errors - Distribute the sample config as a .tar.gz - Unpack sample-config.tar.gz when installing - More files to ignore in CVS - tinc_TUNTAP now substitutes the values outside the AC_CACHE_CHECK - Authentication done - -Wessel Dankers (1): - Important bugfix in avl_insert_before() and avl_insert_after() - -Version 1.0pre3 November 09 2000 ------------------------------------------------------------------------- - -Guus Sliepen (119): - Debian init.d script automatically sets tap device's MTU to 1448 now. - First step for implementation of the "indirectdata" directive. This should - If we have "indirectdata" flag set, we only send data to our uplink. - Large cleanup: - Added CVS Id tags to header files. - - Log possible spoofing attacks. - Hostnames are back! - Hostlookup() is actually being called now. - - More verbose connection list - Fixes some hostlookups. Fixes indirectdata for real now (hopefully). - - Indirectdata finally REALLY REALLY works now! - - Moved all connection messages to debug level 1, without -d's only the - - Fixed KEY_CHANGED notification. A lot of notify_others() calls were - - Fixed indirectdata=no problem - - Improved handling of errors on connection attempts. - - Purge old connections that are ADD_HOSTed. - - Fixes a silly little insignificant buglet. - - Extra check op EINTR bij inlezen requests - - Fixed some spelling errors. - - Fixed missing " in nl.po - - Fixed a message in nl.po - - Added log message when SIGCHLD is received ("thanks" to Ivo van Dong) - - Updated Dutch translation. - - Removed all IP_ADDR_S macros, because gettext doesn't like them. Each - - New semantics for BASIC_INFO, ADD_HOST and DEL_HOST requests. This will - - Fixed memory leak. - - Removed segfault bug in conf.c (must have been there for ages!) - - Instead of logging an error when remote end closes the connection, - - Made tinc even more silent if no -d flag is given at all. - - Added documentation for the protocols (most important the meta protocol) - - Removed a single unused bit from status_bits_t. - - Updated PROTOCOL (a bit) - - Forgot to mention ourselves in the tincd manual page! :) - - Added Spanish translation from Enrique Zanardi. - - Updated THANKS file - - Delayed address resolving for ConnectTo lines in configuration file to - - Fixed typo. - - Added experimental hackish tunneling-over-TCP support. - - Lots o' buglets fixed (-Wall helps) - Fixed PACKET read loop. - Removed calling add_queue for tcponly packets. - - Added date/time of build and protocol number to --version output. - - Moved TCP packet reception to meta handler: less kludgy and less buggy! - - Reinstated O_NONBLOCK for meta socket - - Added two extra configuration options, Interface and InterfaceIP, to - Fixed all sprintf() spl01ts. - Ran update-po and updated dutch translation. - Commented on some size calculations. - Updated the manual: - Updated tinc.conf manual. - Fix rules (thanks to Laurence) - - Use strerror() instead of sys_errlist[] for increased portability - - New protocol. Will break everything else for now. - - Added more function skeletons for the new protocol. - - Lots of functions added for the new protocol. - - Some key exchange stuff. (Last commit before going to bed.) - - Fixed modulo in keylength check - - Lots of small changes. - Added document about the used cryptographic algorithms and the reasons - - Included authentication scheme from protocol.c - - Updated authentication scheme. - - Severe code reduction and simplification of challenge requests - - Removed options "string" stuff. It was a bad idea... - - Very detailed example of the authentication phase. - - Added meta.c which contains functions to send, receive and broadcast - - Added subnet handling code - Removing cipher directory (all will be covered by OpenSSL). - Big and bad commit of my current tree... - - Changed genauth to produce rsa keypairs instead of random passphrases. - - Generalized config file parsing to support multiple configuration trees. - - Fixing-things pass: every source file compiles into an object file now, - - Second fixing-things pass: it even links now. - - The daemon actually runs now (somewhat) - Corrected #ifdefs for tun/tap support. - - Fixing little things - - More fixing. Tinc daemons can now even create activated connections. - - Seed the PRNG using /dev/random before generating the keys. - - tinc now really does public/private key encryption! It even works, whee! - - Made Makefile.am stub for doc/es/ - - Removed last reference to genauth from Makefile.am - - Fixed all debug levels. - - route.c will contain the routing logic. - - Lots of little stuff modified - - Updated subnet list handling. Subnets are added to two lists now, the - - Lots of small fixes - - Fixed offsets when reading/writing from/to tap device - - Override destination ethernet address on incoming packets with - - Very big cleanup. - - Fixed ans_key_h - - Hit people who can't figure out subnet address/mask pairs with a - - Enforce correct order of authentication requests - - Moved connlist stuff to the proper header file. - - Updated dutch translation. - - Removed old encr stuff - - Small fixes - - Use CFB mode for encrypting packets: it works and we don't need padding. - - Finishing touch: encrypt the meta connections - - Small cleanups - - Fixed some spelling mistakes and terminology here and there. - - Update. - Removed config file parsing and interface setup. This will be handled by - - Removed unused MAC strip/add functions. - - Removed even more warnings. - - Resolve scriptname after fork() - - Removed manpage for no longer existing genauth. - - connlist.c added to translation - - Don't forget to set packet cipher for added hosts. - - Forward keys in hex notation, not as binary data. - - Check for packets that are looping back. - - Simplified ping mechanism. - - Prepended config_ to all configuration option names, because it confused - Changed execution of tinc-up: - - Open UDP connection for all known hosts. Comments please. - Porting to SunOS 5.8: - Porting to SunOS 5.8: - - Fixed --config - - Applied Jamie Brigg's patch (close sockets after error) - - Add Jamie :) - - Make checkpoint tracing a compile time option (off by default) - -Ivo Timmermans (77): - Alphabetized the list, added Lubom�r Bulej, removed Sander Smeenk and Tijs van Bakel, put merits after all names. - Don't touch VPNMASK if it's defined, otherwise use $MSK. - These files are created by gettextize (run by autogen.sh) (should have known that). - Include ../intl in the include path, and add @INTLLIBS@ to the list of libraries. - Merge changes from 1.6-1.8. - Configuration directive `IndirectData'. - Changed version number to 1.0pre3. - Version 1.0pre3. - Removed Free Software Foundation copyright, because Guus Sliepen contributed significantly. - Oops, and mention Guus too. - Include the Spanish translation in the distribution/build process. - (Quoting Laurence Lane:) - Also chomp $VPNMASK - Added a rule to create an rpm - Changed CVSROOT path in `make ChangeLog' - Link with OpenSSL crypto libraries instead of own blowfish library - Updated text, removed protocol flowchart - Include openssl/blowfish.h - Support for -lsocket and -lnsl on SunOS - Correct filenames for passphrases given in the example - Add Guus' name and shift out old protocol requests - Better checks for SunOS libraries - Added some structures and types that are needed for the overhaul. - New directive: Name. - First round of needed fixes after the overhaul - Second round of fixes - Added Spanish translation of the docs by Matias Carrasco - Many updates, parts rewritten, added, shuffled around. - Link with OpenSSL, forget libGMP - Updated new requirements, pointers to the manual - Don't look for GMP header files - Update Depends lines to reflect the dependencies on OpenSSL - Fix `Requirements'-section for GMP and OpenSSL libraries. - Add CVS id lines - Add checks for the presence of the universal tun/tap device driver. - Wrap the tun/tap code in #ifdef HAVE_TUNTAP - Linearized checks for if_tun.h - Really #include the if_tun.h files now - Output doc/es/Makefile - Process subdir es/ - Don't declare cp_file and cp_line in xmalloc() - Get the head revision up to date with cabal - Changed changelog - Include linux/sockios.h and net/if.h anyway, regardless of the value of HAVE_TUNTAP. - read_server_config: Check for result of read_config_file. - Oops, echelon change committed to cabal... :) - Skip the check for Linux kernel sources - This file is no longer needed. - - Synchronized changelog with the package's changelog. - Do not include $(top_srcdir)/cipher, it does no longer exist. - Added a perl example to turn an IP address into a MAC address. - Only check for linux/if_tun.h once - Changed `I' to `We' - small change, lots of difference :) - More exhaustive list of changes - perhaps it can be worded differently? - Change wsl to Wessel's name and email address in the ChangeLog creation - Mention fileutils, add a pointer to THANKS for more details - Changed a few messages wrt. system calls; updated and changed the Dutch translation a bit. - Don't include shlibs, as it no longer exists. - Oops, and include doc-base.tinc (new file). - - If necessary, patch po/Makefile.in from po-Makefile.in.in.diff to - Minor cosmetic change. - Save the environment on startup. - Run the scripts tinc-up and tinc-down from a separate function, which - Warnings removal pass: always include config.h first; add a few - Small change to the way the environment is copied. - Use putenv() instead of clumsy do-it-yourself in execute_script. - Do not include the passphrases directory - In execute_script: - Add route.c to the list of source files. - Updated Dutch translation - Build-depends on libtool - Build-Depends on gettext - Final release notes added, also edited release notes for 1.0pre2 to what the announcement on the mailing list looked like. - Wrapped text to 70 (72?) columns for easy reading - Bop version number to 1.0pre3-1 - Updates, updates - Add prototype for destroy_queue - -Wessel Dankers (3): - File added to CABAL (hopefully) - Grrr, recommit - Added architecture section, made a start with the kernel section. - -Version 1.0pre2 May 31 2000 ------------------------------------------------------------------------- - -Ivo Timmermans (56): - Deleted the protocol description. - Perl version of the system startup script. - Only print an error with send_termreq if debug_lvl is 2 or more. - Add check for mpz_powm in libgmp3. - Version 1.0pre1-0.1. - Changed version to 1.0pre2. - Give IP address instead of hex number when connecting tcp socket failed. - Add shlibs control file for the blowfish library. - Inserted useful content. - Add initscript, tincd->tinc. - Add description, better dependancies. - Mention both upstream authors. - tincd->tinc - .deb version number 1.0pre2-0.4. - Updated to newer version. - Exit with zero status if is empty. - Unlimited length in the config file, thanks to Cris van Pelt. - Depend on perl5. - *** empty log message *** - Look if the tap devices exist before bluntly remaking them. - Use the new VpnMask directive to add a route to the rest of the VPN. - This file is generated with dpkg-buildpackage. - Read /etc/tinc/nets.boot to find the networks that have to be started. - Create a default /etc/tinc/nets.boot after installation, containing all directories under /etc/tinc by default. - Version 1.0pre2-0.3 - Don't distribute the file files. - Find networks in instead of . - Include postinst in the distribution. - Errors will not terminate the script or result in a nonzero exit code. - Updated copyright notice. - Fixed typo. - Mask the vpn net with the vpn netmask, route would give an error if the netmask didn't match the net. - When VpnMask is not present in the config file, silently use $MSK as vpnmask. - Add an example of using VpnMask. - Use /etc/tinc/example as a base directory for an example. /etc/tinc/example/README points to /usr/share/doc/tinc/README.Debian. - Create an empty /etc/tinc/nets.boot. - Updated by Lubomir Bulej and Mads Kiilerich: it uses /etc/tinc/nets.boot and the VpnMask directive in the config files. - Internationalization of tinc. - Include intl/ directory in the list of subdirs. - Include system.h and ABOUT-NLS. - Update acconfig.h to include values for gettext inclusion. - Include GNU gettext checks. - Define LOCALEDIR in CFLAGS. - Dutch translation of tinc. - Bounds check for request id (between 0 and 255). - Updated changes list for version 1.0pre2. - Added new configuration directive `Hostnames', which controls the resolving of IP addresses to hostnames. - When a connection is terminated, all hosts that are still connected get notified of the lost connections. - In terminate_connection, only send a notification to hosts that are directly connected to us. (DEL_HOST gets forwarded automatically.) - Only accept an ADD_HOST request for a host that already exists in our conn_list if the nexthop field matches the sender. This is a workaround for older clients. - Include news for 1.0pre2. - Tell about /etc/tinc/nets.boot. - Updated Dutch translation. - Version 1.0pre2-1. - Handle locale settings. - Miscellaneous copyright updates. - -Guus Sliepen (16): - Proxymode removed. - Cleanups. - Changed ping behaviour (backwards compatible). If we don't have any data - Fixed typos. - Test for existence of configured tinc networks. This will also make - Stub for VpnMask config directive. - TODO file reinstated: - VpnMask truely works now. - Typo. - Fixed last typo. Init.d now uses ifconfig command to set both the tap's IP - Documentation updates. Removed all references to configuration variable - Fix for a DoS attack: - Fixed typos. When terminating a connection, it's status is not only set to - Made tinc persistent. If no outgoing connection can be established right - Terminate a connection on any error. Furthermore, disallow del_host, - Only activate a connection upon receiving it's public key if it's an - -Version 1.0pre1 May 08 2000 ------------------------------------------------------------------------- - -Ivo Timmermans (84): - Get rid of the message `zxnrbl\'. - Upon regeneration, free the old encryption key `securely\' by overwriting it. - Kill the parent after any error conditions in detach(). - Ignore SIGCHLD. - New option -D, don't detach. - Moved to version number 1.0. - Only one round of reading bits out of urandom; - Pass the requested size from xmalloc() and xrealloc() on to xalloc_fail_func() - Check for an illegal length of passphrase in read_passphrase(). - Check if stdout is a terminal, if so, print a verbose message. - Default passphrase length of 1024, added -h/--help options. - Submitted by Mads Kiilerich. - New manpage for genauth. - Updated manpages. - Address for bugreports changed to tinc@nl.linux.org. - Include the directory redhat in the build process. - Include genauth.8 in the distribution. - Submitted changes by Mads Kiilerich. - A short notice from Mads Kiilerich. - Keep make dist(dir) happy. - Added cvs-clean. - These files are not needed in release 1.0. - Don't compile in `idea'. - Don't include idea/idea.h. - Don't try to create cipher/idea/Makefile. - The shell script autogen.sh can create all these removed files, but be - s/Gnome/tinc/g - This file is obsolete, most of the ideas are already in echelon. - Remove check for bigendianness. - Don't define HAVE_NAMESPACES and HAVE_STL. - Use `make ChangeLog' to create this file from the CVS logs. - Remove test for GNOME. - Changes largely from Mads Kiilerich. - Added Mads Kiilerich, removed Guus Sliepen. - *** empty log message *** - Generate this Makefile.am from Makefile.am.in. - Contributed by Mads Kiilerich. - Spelling fixes. - Delete all the files that are created by autogen.sh on a `make cvs-clean'. - Propagate CFLAGS from configure to gcc. - Don't include TODO in the dist. - Remove ChangeLog with a `make cvs-clean'. - Initial CVS. - *** empty log message *** - Create a ChangeLog file, automake requires it. - *** empty log message *** - Debug level tweaking. - From Mads Kiilerich. - The make command is in /usr/bin. - Add an entry to dir. - Omit TODO. - Version to 1.0pre1; - Filled in the details, license from libblowfish copied. - Updated version number to 1.0. - Default config file name is tinc.conf, and pidfile is tinc.pid. - More updates wrt. the change from tincd->tinc. - Added `deb' target. - Filled up the protocol structs with unused bytes. - Got rid of the nasty hacks... and replaced it by another one. - Initially, the vpn_mask of a connection is 255.255.255.255 to avoid confusion with lookup_conn. - Replaced check for status.active by status.dataopen in check_network_activity. - New way of handling the meta protocol. - Read public keys the right way (tm). - Removed debug messages. - Read one less byte from an ANS_KEY request. - Send one less byte from an ANS_KEY request. - Protocol fix (ANS_KEY). This breaks 0.3.3 protocol compatibility. - Key forwarding, write one byte extra. - Committed by Lubom�r Bulej. - Updates by Mads Kiilerich. - Committed by Mads Kiilerich. - Fixed meta protocol. - More tincd->tinc updates. - Mentioned new metaprotocol. - Fix a typo, better handling of the info document. (from Mads Kiilerich) - Don't use error.h or error(), put #error in front of cpp errors. - getopt_long() support for platforms that don't have it. - Include stdio.h for fprintf. - More for getopt support. - Check for the existance of libdl. - Don't link in libdl. - Include sys/types.h. - Copied most of the code from the redhat script. - Added semicolons required by bash2 (Mads Kiilerich). - -Guus Sliepen (18): - Added extra checks for desynchronized connection lists. Hopefully this will - Bug found! Wrong pointer was used for handling multiple ADD_HOST requests - Added checkpoints to beginning and ending of every function. - Packet queues fixed. They caused the trouble when resending keys. - Fixed typo and removed some unnecessary variables. - When trying to talk to a host that is in the netmask of a tinc server but - Converted every &variable[0] to variable. - Cleanups: - Removed write_n() function. - Oops! Reference to write_n() removed and changed into neat write() call. - Meta protocol overhaul. Tinc is now incompatible with previous versions, - Fixed small mistake that would prevent forwarding requests. - Previous fix fixed. Meta protocol should be really flawless from now on! - Replaced sprintf() by safer snprintf(), removed possible buffer overflow - Outgoing packets now use network byte order in header. - Fixes typo and UDP network byte order. - Squashed gcc warning. - Added new config variable "ProxyMode". If enabled, all outgoing packets +commit 9a366544c297d5c558800f9ffc301e2cb5a6a672 +Author: Etienne Dechamps +Date: Sat Oct 4 15:01:11 2014 +0100 + Make sure to discover MTU with relays. + + Currently, when tinc sends UDP SPTPS datagrams through a relay, it + doesn't automatically start discovering PMTU with the relay. This means + that unless something else triggers PMTU discovery, tinc will keep using + TCP when sending packets through the relay. + + This patches fixes the issue by explicitly establishing UDP tunnels with + relays. + +commit 63daebcd1ec2975c0c2ad8e0ee0fced33b1fbbf0 +Author: Etienne Dechamps +Date: Sat Oct 4 14:25:16 2014 +0100 + + Don't send MTU probes to nodes we can't reach directly. + + Currently, we send MTU probes to each node we receive a key for, even if + we know we will never send UDP packets to that node because of + indirection. This commit disables MTU probing between nodes that have + direct communication disabled, otherwise MTU probes end up getting sent + through relays. + + With the legacy protocol this was never a problem because we would never + request the key of a node with indirection enabled; with SPTPS this was + not a problem until we introduced relaying because send_sptps_data() + would simply ignore indirections, but this is not the case anymore. + + Note that the fix is implemented in a quick and dirty way, by disabling + the call to send_mtu_probe() in ans_key_h(); this is not a clean fix + because there's no code to resume sending MTU probes in case the + indirection disappears because of a graph change. + +commit 111040d7d1993c67246c52cbfd073183818655f9 +Author: Etienne Dechamps +Date: Sun Sep 28 12:38:06 2014 +0100 + + Add UDP datagram relay support to SPTPS. + + This commit changes the layout of UDP datagrams to include a 6-byte + destination node ID at the very beginning of the datagram (i.e. before + the source node ID and the seqno). Note that this only applies to SPTPS. + + Thanks to this new field, it is now possible to send SPTPS datagrams to + nodes that are not the final recipient of the packets, thereby using + these nodes as relay nodes. Previously SPTPS was unable to relay packets + using UDP, and required a fallback to TCP if the final recipient could + not be contacted directly using UDP. In that sense it fixes a regression + that SPTPS introduced with regard to the legacy protocol. + + This change also updates tinc's low-level routing logic (i.e. + send_sptps_data()) to automatically use this relaying facility if at all + possible. Specifically, it will relay packets if we don't have a + confirmed UDP link to the final recipient (but we have one with the next + hop node), or if IndirectData is specified. This is similar to how the + legacy protocol forwards packets. + + When sending packets directly without any relaying, the sender node uses + a special value for the destination node ID: instead of setting the + field to the ID of the recipient node, it writes a zero ID instead. This + allows the recipient node to distinguish between a relayed packet and a + direct packet, which is important when determining the UDP address of + the sending node. + + On the relay side, relay nodes will happily relay packets that have a + destination ID which is non-zero *and* is different from their own, + provided that the source IP address of the packet is known. This is to + prevent abuse by random strangers, since a node can't authenticate the + packets that are being relayed through it. + + This change keeps the protocol number from the previous datagram format + change (source IDs), 17.4. Compatibility is still preserved with 1.0 and + with pre-1.1 releases. Note, however, that nodes running this code won't + understand datagrams sent from nodes that only use source IDs and + vice-versa (not that we really care). + + There is one caveat: in the current state, there is no way for the + original sender to know what the PMTU is beyond the first hop, and + contrary to the legacy protocol, relay nodes can't apply MSS clamping + because they can't decrypt the relayed packets. This leads to + inefficient scenarios where a reduced PMTU over some link that's part of + the relay path will result in relays falling back to TCP to send packets + to their final destinations. + + Another caveat is that once a packet gets sent over TCP, it will use + TCP over the entire path, even if it is technically possible to use UDP + beyond the TCP-only link(s). + + Arguably, these two caveats can be fixed by improving the + metaconnection protocol, but that's out of scope for this change. TODOs + are added instead. In any case, this is no worse than before. + + In addition, this change increases SPTPS datagram overhead by another + 6 bytes for the destination ID, on top of the existing 6-byte overhead + from the source ID. + +commit 8dd1c8a020e3babf5054179b0d30e2aa850d2e2b +Author: Etienne Dechamps +Date: Sat Sep 27 18:13:33 2014 +0100 + + Prepend source node ID information to UDP datagrams. + + This commit changes the layout of UDP datagrams to include the 6-byte ID + (i.e. node name hash) of the node that crafted the packet at the very + beginning of the datagram (i.e. before the seqno). Note that this only + applies to SPTPS. + + This is implemented at the lowest layer, i.e. in + handle_incoming_vpn_data() and send_sptps_data() functions. Source ID is + added and removed there, in such a way that the upper layers are unaware + of its presence. + + This is the first stepping stone towards supporting UDP relaying in + SPTPS, by providing information about the original sender in the packet + itself. Nevertheless, even without relaying this commit already provides + a few benefits such as being able to reliably determine the source node + of a packet in the presence of an unknown source IP address, without + having to painfully go through all node keys. This makes tinc's behavior + much more scalable in this regard. + + This change does not break anything with regard to the protocol: It + preserves compatibility with 1.0 and even with older pre-1.1 releases + thanks to a minor protocol version change (17.4). Source ID information + won't be included in packets sent to nodes with minor version < 4. + + One drawback, however, is that this change increases SPTPS datagram + overhead by 6 bytes (the size of the source ID itself). + +commit 092d620dbb3fdc8226ea0a4e1cfd5cd53d608420 +Author: Etienne Dechamps +Date: Sat Sep 27 13:34:56 2014 +0100 + + Change vpn_packet_t::seqno from uint32_t to uint8_t[4]. + + This is to make sure on-wire vpn_packet_t fields are always 1-byte + aligned, otherwise padding could get in the way. + +commit 55a78da4e0b496fc599704473f41d5ea52669737 +Author: Etienne Dechamps +Date: Sun Sep 21 18:17:02 2014 +0100 + + Introduce node IDs. + + This introduces a new type of identifier for nodes, which complements + node names: node IDs. Node IDs are defined as the first 6 bytes of the + SHA-256 hash of the node name. They will be used in future code in lieu + of node names as unique node identifiers in contexts where space is at + a premium (such as VPN packets). + + The semantics of node IDs is that they are supposed to be unique in a + tinc graph; i.e. two different nodes that are part of the same graph + should not have the same ID, otherwise things could break. This + solution provides this guarantee based on realistic probabilities: + indeed, according to the birthday problem, with a 48-bit hash, the + probability of at least one collision is 1e-13 with 10 nodes, 1e-11 + with 100 nodes, 1e-9 with 1000 nodes and 1e-7 with 10000 nodes. Things + only start getting hairy with more than 1 million nodes, as the + probability gets over 0.2%. + +commit ac77e3c1eb9d7503e30dd69e96e411e7baaa1dfd +Author: Etienne Dechamps +Date: Sun Sep 21 15:44:59 2014 +0100 + + Invalidate UDP information on address changes. + + Currently, when tinc receives an UDP packet from an unexpected address + (i.e. an address different from the node's current address), it just + updates its internal UDP address record and carries on like nothing + happened. + + This poses two problems: + + - It assumes that the PMTU for the new address is the same as the + old address, which is risky. Packets might get dropped if the PMTU + turns out to be smaller (or if UDP communication on the new address + turns out to be impossible). + + - Because the source address in the UDP packet itself is not + authenticated (i.e. it can be forged by an attacker), this + introduces a potential vulnerability by which an attacker with + control over one link can trick a tinc node into dumping its network + traffic to an arbitrary IP address. + + This commit fixes the issue by invalidating UDP/PMTU state for a node + when its UDP address changes. This will trigger a temporary fallback + to indirect communication until we get confirmation via PMTU discovery + that the node is indeed sitting at the other end of the new UDP address. + +commit f57d53c3ad9af89489e15a8cfd94b56937bf3179 +Author: Etienne Dechamps +Date: Sat Sep 27 17:51:33 2014 +0100 + + Fix protocol version check for type 2 MTU probe replies. + + Currently tinc only uses type 2 MTU probe replies if the recipient uses + protocol version 17.3. It should of course support any higher minor + protocol version as well. + +commit f6b008d7317cb1c3766419bdf6bd97d7b4d561f1 +Author: Franz Pletz +Date: Mon Sep 22 22:43:15 2014 +0200 + + tinc-gui: Use /usr/bin/env to resolve path to python + +commit daf65919d1ccc40f6c11f3f723f325de9021c422 +Author: Etienne Dechamps +Date: Sun Sep 21 11:38:41 2014 +0200 + + Preemptively mirror REQ_PUBKEY messages from nodes with unknown keys. + + In this commit, if a node receives a REQ_PUBKEY message from a node it + doesn't have the key for, it will send a REQ_PUBKEY message in return + *before* sending its own key. + + The rationale is to prevent delays when establishing communication + between two nodes that see each other for the first time. These delays + are caused by the first SPTPS packet being dropped on the floor, as + shown in the following typical exchange: + + node1: No Ed25519 key known for node2 + REQ_PUBKEY -> + <- ANS_PUBKEY + node1: Learned Ed25519 public key from node2 + REQ_SPTPS_START -> + node2: No Ed25519 key known for zyklos + <- REQ_PUBKEY + ANS_PUBKEY -> + node2: Learned Ed25519 public key from node1 + -- 10-second delay -- + node1: No key from node2 after 10 seconds, restarting SPTPS + REQ_SPTPS_START -> + <- SPTPS -> + node1: SPTPS key exchange with node2 succesful + node2: SPTPS key exchange with node1 succesful + + With this patch, the following happens instead: + + node1: No Ed25519 key known for node2 + REQ_PUBKEY -> + node2: Preemptively requesting Ed25519 key for node1 + <- REQ_PUBKEY + <- ANS_PUBKEY + ANS_PUBKEY -> + node2: Learned Ed25519 public key from node1 + node1: Learned Ed25519 public key from node2 + REQ_SPTPS_START -> + <- SPTPS -> + node1: SPTPS key exchange with node2 succesful + node2: SPTPS key exchange with node1 succesful + +commit c897f8c99e0b0827cff60f098bd3f9852a062233 +Author: Etienne Dechamps +Date: Sun Sep 21 12:58:23 2014 +0200 + + Fix default device path selection on BSD. + + Currently, if DeviceType = tap but Mode = router, the default + device path is /dev/tun0, which is wrong. This commit fixes that. + +commit a649aa51bf8e5b5fcc76061c9f660122a08245a8 +Author: Etienne Dechamps +Date: Sun Sep 21 11:25:49 2014 +0100 + + Ignore the Interface option if device rename is impossible. + + There are platforms on which it is impossible to rename the TUN/TAP + device. An example is Mac OS X (tuntapx). On these platforms, + specifying the Interface option will not rename the interface, but + the specified name will still be passed to tinc-up scripts and the + like, resulting in potential confusion for the user. + +commit 053925efebf466b5866de12434010c1e8127c172 +Author: Etienne Dechamps +Date: Sun Sep 21 11:14:19 2014 +0100 + + Fix default TAP device on Darwin. + + On Darwin (tuntapx), the first TAP device is /dev/tap0, not /dev/tun0. + +commit 1ac9a3fbd18f961d604c2c080374b8fc32f155d6 +Author: Etienne Dechamps +Date: Sat Sep 6 18:16:46 2014 +0100 + + Fix wrong identifier in SO_NOSIGPIPE call. + + f134bd0c9c2213fbbb3967f3d784759cb65e2c76 broke the Mac OS X build by + introducing a reference to an identifier, c, that doesn't exist. + +commit 7ac52637659b7f17ab5139010f0436aefcf9625c +Author: Etienne Dechamps +Date: Sat Sep 6 10:43:15 2014 +0100 + + Don't enable the device if the reachable count is zero. + + A logic bug was introduced in bd451cfe1512fa69eac35a60dbe6df17bfc39154 + in which running graph() several times with zero reachable nodes had + the effect of calling device_enable() (instead of keeping the device + disabled). + + This results in weird behavior when DeviceStandby is enabled, especially + on Windows where calling device_enable() several times in a row corrupts + I/O structures for the device, rendering it unusable. + +commit 9ad656b512582ed95a574b3fd74b948f876953ce +Author: Etienne Dechamps +Date: Sun Aug 31 13:59:30 2014 +0100 + + Fix undefined HOST_NAME_MAX on Windows. + + The Windows build was broken by commit + 826ad11e419db90b66b3f76a90b54df021bb39fc which introduced a dependency + on the HOST_NAME_MAX macro, which is not defined on Windows. According + to MSDN for gethostname(), the maximum length of the returned string + is 256 bytes (including the terminating null byte), so let's use that + as a fallback. + +commit 0f09260b1377f2d6f14bcdf5de7cbad415743c1e +Author: Etienne Dechamps +Date: Sat Aug 30 10:57:57 2014 +0100 + + Remove Google from the list of copyright owners. + + Google released copyright to me for my own contributions. + +commit 38d7e730e619a8b86dfbf68d77773564595f12a1 +Author: William A. Kennington III +Date: Sun Aug 24 22:35:25 2014 -0700 + + tincctl: Use replace_name to properly replace and validate input hostnames + +commit 511b51ffe60c20a9091829c03863197b76027716 +Author: William A. Kennington III +Date: Sun Aug 24 21:55:42 2014 -0700 + + utils: Refactor check_id out of protocol for global access + +commit 826ad11e419db90b66b3f76a90b54df021bb39fc +Author: William A. Kennington III +Date: Sun Aug 24 19:49:27 2014 -0700 + + utils: Refactor get_name's functionality into util for global access + +commit 78bf82cf332327889f0f61388b73053850d8e59b +Author: Etienne Dechamps +Date: Sun Aug 17 20:22:44 2014 +0100 + + Clarify copyright ownership for code authored by Etienne Dechamps. + +commit 73d8393bd6c54e0ec28d5f6c114a6eb3821a8ec1 +Author: Sven-Haegar Koch +Date: Thu Aug 7 22:14:20 2014 +0200 + + commandline.test: Adding test that fetching non-existing config setting really fails. + +commit 9fe5ab7ccb60537810b60b76a415507ef2cadfdd +Author: Sven-Haegar Koch +Date: Thu Aug 7 23:01:05 2014 +0200 + + Fix exit code of "tinc get". + + Successfully getting an existing variable ("tinc get name") should + not result in an error exitcode (1) from the tinc command. + + This changes the result of test/commandline.test from FAIL to PASS. + +commit 5ae1ec8d80393182b6ff235062b6816b64edfa9b +Author: Etienne Dechamps +Date: Sat Jul 19 18:11:42 2014 +0100 + + Handle TAP-Win32 immediate reads correctly. + + The handling of TAP-Win32 virtual network device reads that complete + immediately (ReadFile() returns TRUE) is incorrect - instead of + starting a new read, tinc will continue listening for the overlapped + read completion event which will never fire. As a result, tinc stops + receiving packets on the interface. + +commit 1d10afd3d33f5623494d9eeb2fa8237712f8aa2e +Author: Etienne Dechamps +Date: Sat Jul 19 16:05:23 2014 +0100 + + Only read from TAP-Win32 if the device is enabled. + + With newer TAP-Win32 versions (such as the experimental + tap-windows6 9.21.0), tinc is unable to read from the virtual network + device: + + Error while reading from (null) {23810A13-BCA9-44CE-94C6-9AEDFBF85736}: No such file or directory + + This is because these new drivers apparently don't accept reads when + the device is not in the connected state (media status). + + This commit fixes the issue by making sure we start reading no sooner + than when the device is enabled, and that we stop reading when the + device is disabled. This also makes the behavior somewhat cleaner, + because it doesn't make much sense to read from a disabled device + anyway. + +commit cc9203ee75c49360dd29710ac12bb67fe503f97b +Author: Etienne Dechamps +Date: Sun Jul 13 15:54:34 2014 +0100 + + Add a non-interactive mode to tinc commands. + + Some tinc commands, such as "tinc generate-keys", use the terminal to + ask the user for information. This can be bypassed by making sure + there is no terminal, which is trivial on *nix but might require + jumping through some hoops on Windows depending on how the command is + invoked. + + This commit adds a --batch option that ensures tinc will never ask the + user for input, even if it is attached to a terminal. + +commit afb175873e6aa10d2d4dca3572edf054968c538d +Author: Guus Sliepen +Date: Sat Jul 12 22:51:37 2014 +0200 + + Revert "Use git description as the tinc version." + + This reverts commit e024b7a2c50e23311834e6d180e5acc72783b339. Automatic version + number generation needs a little bit more work to get it working correctly in + all cases. + +commit 19e42b76f546dc3baee4a5d6a4f161155d279c74 +Merge: f7043048 b12f122f +Author: Guus Sliepen +Date: Sat Jul 12 22:25:55 2014 +0200 + + Merge branch 'keysegfault' of https://github.com/dechamps/tinc into 1.1 + +commit f704304823df0ac868786ac89355eda38592dc3f +Merge: 54fd228e ea12a0fb +Author: Guus Sliepen +Date: Sat Jul 12 22:22:31 2014 +0200 + + Merge branch 'tincstart' of https://github.com/dechamps/tinc into 1.1 + +commit 54fd228e696acc9d78a17845402640cc04e2c54c +Merge: 53036a58 14be1d30 +Author: Guus Sliepen +Date: Sat Jul 12 22:21:01 2014 +0200 + + Merge branch 'ctrl' of https://github.com/dechamps/tinc into 1.1 + +commit 53036a58790168e18f524bd923f9a7d34691ba2d +Merge: ddd0cd47 b2a6381a +Author: Guus Sliepen +Date: Sat Jul 12 22:19:45 2014 +0200 + + Merge branch 'winwarnings' of https://github.com/dechamps/tinc into 1.1 + +commit ddd0cd47bc0bb3478b7d250192248a1e3aa2a243 +Author: Etienne Dechamps +Date: Mon Jun 30 14:03:17 2014 +0100 + + Verify seqno early in sptps_verify_datagram(). + + This is a slight optimization for sptps_verify_datagram(), which might + come in handy since this function is called in a loop via try_harder(). + + It turns out that since sptps_verify_datagram() doesn't update any + state, it doesn't matter in which order verifications are done. However, + it does affect performance since it's much cheaper to check the seqno + than to try to decrypt the packet. + + Since this function is called with the wrong node most of the time, it + makes verification vastly faster for the majority of calls because the + seqno will be wrong in most cases. + +commit 7bf61575fe1009ecb93b3f6b8f5145525874e470 +Author: Etienne Dechamps +Date: Sun Jul 6 11:34:57 2014 +0100 + + Add documentation about using system-assigned ports. + + There are two caveats to be aware of which are documented in this + commit: + + - Because the system will likely assign different ports when binding + several times to different address families, it is recommended to + only use a single address family, otherwise other nodes will only + get one port among the several that were assigned, possibly breaking + communication. + + - AutoConnect won't work in this scenario, because it relies on the UDP + port being the same as the TCP port, which is not the case when using + system-assigned ports. + +commit ea12a0fb066793c316ccc9ef21444f092f74b4ba +Author: Etienne Dechamps +Date: Sat Jul 12 18:53:25 2014 +0100 + + Improve subprocess behavior in tinc start command. + + When invoking tincd, tinc start currently uses the execvp() function, + which doesn't behave well in a console as the console displays a new + prompt before the subprocess finishes (which makes me suspect the exit + value is not handled at all). This new code uses spawnvp() instead, + which seems like a better fit. + +commit b22499668a7aa63c619cb8fa8535282a38841ce9 +Author: Etienne Dechamps +Date: Sat Jul 12 18:37:56 2014 +0100 + + Fix "tinc start" on Windows when the path contains spaces. + + When invoking "tinc start" with spaces in the path, the following + happens: + + > "c:\Program Files (x86)\tinc\tinc.exe" start + c:\Program: unrecognized argument 'Files' + Try `c:\Program --help' for more information. + + This is caused by inconsistent handling of command line strings between + execvp() and the spawned process' CRT, as documented on MSDN: + http://msdn.microsoft.com/library/431x4c1w.aspx + +commit 14be1d30ec3727906907dad49d3bcb868c19d777 +Author: Etienne Dechamps +Date: Sat Jul 12 17:47:01 2014 +0100 + + Shutdown cleanly when receiving a Windows console shutdown request. + + This commit makes tinc exit cleanly on Windows when hitting CTRL+C at + the console or when the user logs off. This change has no effect when + running tinc as a service. + +commit b12f122f1be89b49d8a3e39fb1b10c6e4d3ada94 +Author: Etienne Dechamps +Date: Sat Jul 12 13:56:01 2014 +0100 + + Check if devops is valid before closing the device. + + This fixes a segfault that occurs on exit if tinc fails before the + device is initialized (for example, if it fails to read the private + key). + +commit 5ffdff685a0e7d25f7c016f3a6cd89bb82fed71c +Author: Guus Sliepen +Date: Sat Jul 12 14:35:29 2014 +0200 + + Fix unsafe use of strncpy() and sprintf(). + + The strncpy() problem was found by cppcheck. + +commit 31361075d36fd3f4a393eeb90b75ae2567992ef2 +Author: Guus Sliepen +Date: Sat Jul 12 14:34:39 2014 +0200 + + Fix a potential file descriptor leak. + + Found by cppcheck. + +commit b2a6381ab28dbae4bf976627afccbf6c2fcb0625 +Author: Etienne Dechamps +Date: Sat Jul 12 13:32:23 2014 +0100 + + Resolve KEY_EVENT conflict between Windows and ncurses. + + This fixes the following compiler warning when building for Windows: + + In file included from top.c:24:0: + /usr/local/mingw/ncurses/include/curses.h:1478:0: error: "KEY_EVENT" redefined [-Werror] + #define KEY_EVENT 0633 /* We were interrupted by an event */ + ^ + In file included from /usr/share/mingw-w64/include/windows.h:74:0, + from /usr/share/mingw-w64/include/winsock2.h:23, + from have.h:46, + from system.h:26, + from top.c:20: + /usr/share/mingw-w64/include/wincon.h:101:0: note: this is the location of the previous definition + #define KEY_EVENT 0x1 + ^ + +commit 5217c16db4babd64580c2fd7aa36180bb9bd838c +Author: Etienne Dechamps +Date: Sat Jul 12 13:27:05 2014 +0100 + + Remove unused device stats variables. + + This removes a bunch of variables that are never actually used anywhere. + + This fixes the following compiler warning when building for Windows: + + mingw/device.c:46:17: error: ‘device_total_in’ defined but not used [-Werror=unused-variable] + static uint64_t device_total_in = 0; + ^ + +commit 6e221a828f87a511aecee9d9263a1db0836701c4 +Author: Etienne Dechamps +Date: Sat Jul 12 12:57:11 2014 +0100 + + Remove unused variable in TAP-Win32 setup_device(). + + This fixes the following compiler warning when building for Windows: + + mingw/device.c: In function ‘setup_device’: + mingw/device.c:92:9: error: unused variable ‘thread’ [-Werror=unused-variable] + HANDLE thread; + ^ + +commit 2d2e94406c5f595eff67a01ee6bb1190f77c37ff +Author: Etienne Dechamps +Date: Sat Jul 12 12:54:45 2014 +0100 + + Fix callback signature for TAP-Win32 device_handle_read(). + + This fixes the following compiler warning when building for Windows: + + mingw/device.c: In function ‘setup_device’: + mingw/device.c:186:2: error: passing argument 2 of ‘io_add_event’ from incompatible pointer type [-Werror] + io_add_event(&device_read_io, device_handle_read, NULL, CreateEvent(NULL, TRUE, FALSE, NULL)); + ^ + In file included from mingw/../net.h:27:0, + from mingw/../subnet.h:24, + from mingw/../conf.h:34, + from mingw/device.c:26: + mingw/../event.h:61:13: note: expected ‘io_cb_t’ but argument is of type ‘void (*)(void *)’ + extern void io_add_event(io_t *io, io_cb_t cb, void* data, WSAEVENT event); + +commit f693cb7295298ecd6993a4feac1faf9129aa204d +Author: Etienne Dechamps +Date: Sat Jul 12 12:52:25 2014 +0100 + + Remove an unnecessary pointer dereference in execute_script(). + + This fixes the following compiler warning when building for Windows: + + script.c: In function ‘execute_script’: + script.c:52:5: error: value computed is not used [-Werror=unused-value] + *q++; + ^ + +commit d7f89a79448dd1633342ea5ee344d403c8e6890b +Author: Etienne Dechamps +Date: Sat Jul 12 12:49:59 2014 +0100 + + Only declare the origpriority variable if we support priority. + + This fixes the following compiler warning when building for Windows: + + net_packet.c: In function ‘send_udppacket’: + net_packet.c:633:6: error: unused variable ‘origpriority’ [-Werror=unused-variable] + int origpriority = origpkt->priority; + ^ + +commit 5aed916ef4fd75e6843f8fe739444dae91ea106a +Author: Guus Sliepen +Date: Sat Jul 12 14:24:16 2014 +0200 + + Reserve legacy active bit in connection_status_t. + + This is so the positions of the other bits don't change, making it easier to + debug problems with different versions of tinc. + + Also fix the padding so connection_status_t is exactly 32 bits. + +commit b23bf132838156d2fe5a18d50a2b5e068ae18ec3 +Author: Etienne Dechamps +Date: Sat Jul 12 11:57:03 2014 +0100 + + Remove redundant connection_t::status.active field. + + The only places where connection_t::status.active is modified is in + ack_h() and terminate_connection(). In both cases, connection_t::edge + is added and removed at the same time, and that's the only places + connection_t::edge is set. Therefore, the following is true at all + times: + + !c->status.active == !c->edge + + This commit removes the redundant state information by getting rid of + connection_t::status.active, and using connection_t::edge instead. + +commit 127f2f99f3d43e0565782750f26f1d3980c72711 +Author: Etienne Dechamps +Date: Sat Jul 12 11:13:04 2014 +0100 + + Don't initialize outpkt to an unused value. + + in receive_udppacket(), we initialize outpkt to a default value but the + value is never read anywhere, as every read is preceded by a write. + + This issue was found by the clang static analyzer tool: + http://clang-analyzer.llvm.org/ + +commit 77e96c07912c2a8b280d3e812c71fa1f12efb0ff +Author: Etienne Dechamps +Date: Sat Jul 12 11:06:36 2014 +0100 + + Handle the "no local address" case in send_sptps_data(). + + If choose_local_address() is unable to find a local address (e.g. + because of old nodes that don't send their local address information), + then send_sptps_data() ends up using uninitialized variables for the + socket and address. + + This regression was introduced in + 415910897122da0073a862784d148802ca390020. The commit took care of + handling that case in send_udppacket() but was missing the same fix + for send_sptps_data(). + + This bug was found by the clang static analyzer tool: + http://clang-analyzer.llvm.org/ + +commit 45a30f71572fab8e73c456737b7506b2cf12be25 +Author: Guus Sliepen +Date: Thu Jul 10 22:41:01 2014 +0200 + + Fix incorrect format qualifiers. + + Based on a patch from Etienne Dechamps. We avoid the use of %hhx, since even + though it is C99, not all compilers support it yet. We use %x instead, since + it's guaranteed that the minimum size of function arguments on the stack or in + registers is that of an int. + +commit d8ed5cf36d0c6d5a863497674248c8e8b63b9d98 +Author: Etienne Dechamps +Date: Thu Jul 10 20:29:12 2014 +0100 + + Fix a typo (FORTIFY_SOURCE). + +commit 2f4075f7da2c6ddf777c5bab93992a6c6ac5ec40 +Author: Baptiste Jonglez +Date: Sun Jul 6 20:55:26 2014 +0900 + + Fix typos in the manual page + +commit d8ea4c11dec5946c135ad2d2d05954473a0bfda9 +Author: Guus Sliepen +Date: Tue Jul 8 14:20:11 2014 +0200 + + Fix segmentation fault when dumping subnets. + +commit 23a22ea1ceb9d0a6b6c288142130f0e30c0fdec9 +Author: Guus Sliepen +Date: Tue Jul 8 14:20:01 2014 +0200 + + Fix compiler warnings. + +commit 163773d7107b7726bed24cb1c31b1cecc0d0c239 +Author: Etienne Dechamps +Date: Sun Jul 6 12:35:32 2014 +0100 + + Fix event loop io tree inconsistency on Windows. + + On Windows, the event loop io tree uses the Windows Event handle to + differentiate between io_t objects. Unfortunately, there is a bug in + the io_add_event() function (introduced in + 2f9a1d4ab5ff51b05a5e8cc41a1528fdeb36c723) as it sets the event after + inserting the object into the tree, resulting in objects appearing in + io_tree out of order. + + This can lead to crashes on Windows as the event loop is unable to + determine which events fired. + +commit fcf5b53e785fd191dd951b77ad831fe6ac78dce4 +Author: Etienne Dechamps +Date: Sun Jul 6 10:55:23 2014 +0100 + + Make sure myport is set correctly when running with Port = 0. + + Setting the Port configuration variable to zero can be used to make tinc + listen on a system-assigned port. Unfortunately, in this scenario myport + will be zero, which means that tinc won't transmit its actual UDP + listening port to other nodes. This breaks UDP hole punching and local + discovery. + +commit c786ed116805c0bc911f592c03dc0d5562287283 +Author: Etienne Dechamps +Date: Sat Jul 5 00:23:05 2014 +0100 + + Fix tinc event loop reentrancy from timeout handlers. + + Commit 611217c96ec684799882cf330f40a0936131b6b5 introduced a regression + because it accidentally reordered the timeout handler calls and the + fdset setup code. This means that any io_add(), io_del() or io_set() + calls in timeout handlers would be ignored in the current event loop + iteration, resulting in erratic behavior. + + The most visible symptom is when a metaconnection timeout occurs and the + connection is closed; the timeout handler closes the socket but it still + ends up in the select() call, typically resulting in the following + crash: + + Error while waiting for input: Bad file descriptor + +commit d0d01a44485ee04f60a8fccf9bdf8311e23ffa43 +Author: Etienne Dechamps +Date: Sat Jul 5 19:51:19 2014 +0100 + + Canonicalize IPv6 addresses as per RFC 5952 before printing them. + + Currently we don't do any shortening on IPv6 addresses (aside from + removing trailing zeroes) before printing them. This commit makes + textual addresses smaller by shortening them according to the rules + described in RFC 5952. This is also the canonical textual representation + for IPv6 addresses, thus making them easier to compare. + +commit dec0400714cc6b125f615c224ac37903f44addb9 +Author: Etienne Dechamps +Date: Sat Jul 5 19:02:02 2014 +0100 + + Don't print subnet prefix lengths and weights for one-host subnets. + + This commit suppresses subnet prefix length output (/xx) for subnets + that only contain one address (/32 for IPv4, /128 for IPv6). It also + suppresses weight information if the subnet is using the default + weight. This improves readability of net2str() output in the majority + of cases. + +commit dc55691ca7399bab28963f92e4c3dea9d6bf8eb1 +Author: Etienne Dechamps +Date: Sat Jul 5 18:52:03 2014 +0100 + + When printing MAC addresses, always use trailing zeroes. + + tinc currently prints MAC addresses without trailing zeroes, for example: + + 1:2:3:4:5:6 + + This looks weird and is inconsistent with how MAC addresses are + displayed everywhere else. This commit adds trailing zeroes, so the + above address will be printed as the following: + + 01:02:03:04:05:06 + +commit 3d730a40a42d9b238da8725438a612296dea3860 +Author: Etienne Dechamps +Date: Sat Jul 5 18:05:55 2014 +0100 + + Rewrite, fix and improve str2net(). + + This is a complete rewrite of the str2net() function. Besides + refactoring duplicate code, this new code brings the following fixes + and improvements: + + - Fixes handling of leading/trailing double colon in IPv6 addresses. + For example, with the previous code the address + 2001:0db8:85a3:0000:0000:8a2e:0370:: is interpreted as a MAC address, + and ::0db8:85a3:0000:0000:8a2e:0370:7334 is rejected. + + - Catches more invalid cases, such as garbage at the end of the string. + + - Adds support for dotted quad notation in IPv6 (e.g. ::1.2.3.4). + + See RFC 4291, section 2.2 for details on the textual format of IPv6 + addresses. + +commit e024b7a2c50e23311834e6d180e5acc72783b339 +Author: Etienne Dechamps +Date: Sun Jun 29 15:22:10 2014 +0100 + + Use git description as the tinc version. + + Instead of using a hardcoded version number in configure.ac, this makes + tinc use the live version reported by "git describe", queried on-the-fly + during the build process and regenerated for every build. + + This provides several advantages: + - Less redundancy: git is now the source of truth for version + information, no need to store it in the repository itself. + - Simpler release process: just creating a git tag automatically + updates the version. No need to change files. + - More useful version information: tinc will now display the number of + commits since the last tag as well as the commit the binary is built + from, following the format described in git-describe(1). + + Here's an example of tincd --version output: + + tinc version release-1.1pre10-48-gc149315 (built Jun 29 2014 15:21:10, protocol 17.3) + + When building directly from a release tag, this would like the following: + + tinc version release-1.1pre10 (built Jun 29 2014 15:21:10, protocol 17.3) + + (Note that the format is slightly different - because of the way the + tags are named, it says "release-1.1pre10" instead of just "1.1pre10") + +commit aec82bb1c94af6d3142cdef0c51f42f38e9be3e0 +Author: Etienne Dechamps +Date: Sun Jun 29 14:57:42 2014 +0100 + + Regenerate build date and time every time tinc is built. + + This prevents the date and time shown in version information from + getting stale because of partial builds. With these changes, date and + time information is written to a dedicated object file that gets rebuilt + every time make is run, even if there are no changes. + +commit 116f2ed27a74982e4d1a19b7a8fd08b0aaee1f8d +Author: Etienne Dechamps +Date: Sun Jun 29 14:15:58 2014 +0100 + + Make IPv4 multicast space 224.0.0.0/4 broadcast by default. + + We already do this for IPv6 multicast space (ff00::/8), so why not + extend it to IPv4. + +commit 46a5aa0d674914f4220d8583b1b2f87c7f05a804 +Author: Etienne Dechamps +Date: Sun Jun 29 13:18:25 2014 +0100 + + Make broadcast addresses configurable. + + This adds a new option, BroadcastSubnet, that allows the user to + declare broadcast subnets, i.e. subnets which are considered broadcast + addresses by the tinc routing layer. Previously only the global IPv4 + and IPv6 broadcast addresses were supported by virtue of being + hardcoded. + + This is useful when using tinc in router mode with Ethernet virtual + devices, as it can be used to provide broadcast support for a local + broadcast address (e.g. 10.42.255.255) instead of just the global + address (255.255.255.255). + + This is implemented by removing hardcoded broadcast addresses and + introducing "broadcast subnets", which are subnets with a NULL owner. + By default, behavior is unchanged; this is accomplished by adding + the global broadcast addresses for Ethernet, IPv4 and IPv6 at start + time. + +commit b54fde67474e7201e94fa4be34dae65d295b2936 +Author: Etienne Dechamps +Date: Sun Jun 29 09:57:11 2014 +0100 + + Implement sptps_verify_datagram(). + + Implementation of sptps_verify_datagram() was left as a TODO. This + causes problems when using SPTPS in tinc, because this function is + used in try_mac(), which itself is used in try_harder() to locate + nodes sending UDP packets from unexpected addresses. In the current + state this function always returns true, resulting in UDP addresses + of random nodes getting changed which makes UDP communication + fragile and unreliable. In addition, this makes UDP communication + impossible through port translation and local discovery. + + This commit adds the missing implementation, thus fixing the issue. + +commit 498f1b1d5835ab1ac21886cdf0d1471ac90f75b2 +Author: Etienne Dechamps +Date: Sun Jun 29 11:06:44 2014 +0100 + + Enable LocalDiscovery by default. + + Recent improvements to the local discovery mechanism makes it cheaper, + more network-friendly, and now it cannot make things worse (as opposed + to the old mechanism). Thus there is no reason not to enable it by + default. + +commit 415910897122da0073a862784d148802ca390020 +Author: Etienne Dechamps +Date: Sun Jun 29 11:01:24 2014 +0100 + + Remove broadcast-based local discovery mechanism. + + The new local address based local discovery mechanism is technically + superior to the old broadcast-based one. In fact, the old algorithm + can technically make things worse by e.g. sending broadcasts over the + VPN itself and then selecting the VPN address as the node's UDP + address. This cannot happen with the new mechanism. + + Note that this means old nodes that don't send their local addresses in + ADD_EDGE messages can't be discovered, because there is no address to + send discovery packets to. Old nodes can still discover new nodes by + sending them broadcasts, though. + +commit e16ade874d08f82481dca7302b98305bcfbe27cf +Author: Etienne Dechamps +Date: Sun Jun 22 17:27:55 2014 +0100 + + Use edge local addresses for local discovery. + + This introduces a new way of doing local discovery: when tinc has + local address information for the recipient node, it will send local + discovery packets directly to the local address of that node, instead + of using broadcast packets. + + This new way of doing local discovery provides numerous advantages compared to + using broadcasts: + + - No broadcast packets "polluting" the local network; + + - Reliable even if the sending host has multiple network interfaces (in + contrast, broadcasts will only be sent through one unpredictable + interface) + + - Works even if the two hosts are not on the same broadcast domain. One + example is a large LAN where the two hosts might be on different local + subnets. In fact, thanks to UDP hole punching this might even work if + there is a NAT sitting in the middle of the LAN between the two nodes! + + - Sometimes a node is reachable through its "normal" address, and via a + local subnet as well. One might think the local subnet is the best route + to the node in this case, but more often than not it's actually worse - + one example is where the local segment is a third party VPN running in + parallel, or ironically it can be the local segment formed by the tinc + VPN itself! Because this new algorithm only checks the addresses for + which an edge is already established, it is less likely to fall into + these traps. + +commit bfce56d473e1e01a8af0260262ca84f09154e71f +Author: Etienne Dechamps +Date: Sun Jun 22 16:29:30 2014 +0100 + + Add local address information to edges. + + In addition to the remote address, each edge now stores the local address from + the point of view of the "from" node. This information is then made available + to other nodes through a backwards-compatible extension to ADD_EDGE messages. + + This information can be used in future code to improve packet routing. + +commit 762db91ef7d3b2eab00c23250ca61c7f814899c7 +Author: Guus Sliepen +Date: Sat Jun 28 21:54:34 2014 +0200 + + Give getsockopt() a reference to a socklen_t. + +commit e57daac63b6f703af8e7c8209ef61a4d3b2180c3 +Merge: cc284e7c 313a752c +Author: Guus Sliepen +Date: Sat Jun 28 21:49:55 2014 +0200 + + Merge branch 'winevents-clean' of https://github.com/dechamps/tinc into 1.1 + +commit 313a752cb5fbf27450d34c15b0085d2d8a4147af +Author: Etienne Dechamps +Date: Sat Jun 28 18:39:00 2014 +0100 + + Remove the TAP-Win32 reader thread. + + tinc is using a separate thread to read from the TAP device on Windows. + The rationale was that the notification mechanism for packets arriving + on the virtual network device is based on Win32 events, and the event + loop did not support listening to these events. + + Thanks to recent improvements, this event loop limitation has been + lifted. Therefore we can get rid of the separate thread and simply add + the Win32 "incoming packet" event to the event loop, just like a socket. + The result is cleaner code that's easier to reason about. + +commit ffbc99558cae4dff876645fe205349d8c4cd7acb +Author: Etienne Dechamps +Date: Sat Jun 28 15:19:11 2014 +0100 + + Use a Windows event to stop tinc when running as a service. + + Currently, when the tinc service handler callback (which runs in a + separate thread) receives a service shutdown request, it calls + event_exit() to request the event loop to exit. + + This approach has a few issues: + + - The event loop will only notice the exit request when the next event + fires. This slows down tinc service shutdown. In some extreme cases + (DeviceStandby enabled, long PingTimeout and no connections), + shutdown can take ages. + + - Strictly speaking, because of the absence of memory barriers, there + is no guarantee that the event loop will even notice an exit request + coming from another thread. I suppose marking the "running" variable + as "volatile" is supposed to alleviate that, but it's unclear whether + that provides any guarantees with modern systems and compilers. + + This commit fixes the issue by leveraging the new event loop Windows + interface, using a custom Windows event that is manually set when + shutdown is requested. + +commit 2f9a1d4ab5ff51b05a5e8cc41a1528fdeb36c723 +Author: Etienne Dechamps +Date: Sat Jun 28 15:15:41 2014 +0100 + + Make the event loop expose a Windows event interface. + + This allows event loop users to specify Win32 events to wait on, + thus making the event loop more flexible. + +commit 611217c96ec684799882cf330f40a0936131b6b5 +Author: Etienne Dechamps +Date: Fri Jun 27 21:58:35 2014 +0100 + + Use native Windows events for the event loop. + + This commit changes the event loop to use WSAEventSelect() and + WSAWaitForMultipleEvents() on Windows. This paves the way for making the + event loop more flexible on Windows by introducing the required + infrastructure to make the event loop wait on any Win32 event. + + This commit only affects the internal implementation of the event + module. Externally visible behavior remains strictly unchanged (for + now). + +commit cc284e7c5d298ca887c07f918da35e376bf98720 +Author: Etienne Dechamps +Date: Sat Jun 28 11:13:29 2014 +0100 + + Fix connection event error handling. + + Commit 86a99c6b999671ed444711139db1937617e802a0 changed the way we + handle connection events to protect against spurious event loop + callbacks. Unfortunately, it turns out that calling connect() twice on + the same socket results in different behaviors depending on the platform + (even though it seems well defined in POSIX). On Windows this resulted + in the connection handling code being unable to react to connection + errors (such as connection refused), always hitting the timeout; on + Linux this resulted in spurious error messages about connect() returning + success. + + In POSIX and on Linux, using connect() on a socket where the previous + attempt failed will attempt to connect again, resulting in unnecessary + network activity. Using getsockopt(SO_ERROR) before connect() solves + that, but introduces a race condition if a connection failure happens + between the two calls. + + For this reason, this commit switches from connect() to a zero-sized + send() call, which is more consistent (though not completely, see the + truth table in the comments) and simpler to use for that purpose. Note + that Windows explictly support empty send() calls; POSIX says nothing + on the subject, but testing shows it works at least on Linux. + + (Surprisingly enough, Windows seems more POSIX-compliant than Linux on + this one!) + +commit 86a99c6b999671ed444711139db1937617e802a0 +Author: Etienne Dechamps +Date: Fri Jun 27 19:33:31 2014 +0100 + + Protect against spurious connection events. + + The event loop does not guarantee that spurious write I/O events do not + happen; in fact, they are guaranteed to happen on Windows when + event_flush_output() is called. Because handle_meta_io() does not check + for spurious events, a metaconnection socket might appear connected even + though it's not, and will fail immediately when sending the ID request. + + This commit fixes this issue by making handle_meta_io() check the + connection status before assuming the socket is connected. It seems that + the only reliable way to do that is to try to call connect() again and + look at the error code, which will be EISCONN if the socket is + connected, or EALREADY if it's not. + +commit 0c026f3c6dec784c3267ad7e2c4709d5393dc292 +Author: Etienne Dechamps +Date: Thu Jun 26 20:42:40 2014 +0100 + + Fix errno references when handling socket errors. + + When using socket functions, "sockerrno" is supposed to be used to + retrieve the error code as opposed to "errno", so that it is translated + to the correct call on Windows (WSAGetLastError() - Windows does not + update errno on socket errors). Unfortunately, the use of sockerrno is + inconsistent throughout the tinc codebase, as errno is often used + incorrectly on socket-related calls. + + This commit fixes these oversights, which improves socket error + handling on Windows. + +commit 058473dc8d4cf60f79aee18d473342b8a3c25fbe +Author: Etienne Dechamps +Date: Sun Jun 22 18:45:49 2014 +0100 + + Fix Windows includes. + + These Windows include lines are capitalized, which causes the build to fail + when cross-compiling from Linux to Windows using MinGW as the MinGW headers + are entirely lower case. + +commit b24faf3cbe07dd931911ec4d70f1a9e0d6a87519 +Author: Guus Sliepen +Date: Sun May 11 17:11:02 2014 +0200 + + Remove the warnings when IP_DONTFRAGMENT/IPV6-DONTFRAG is not supported. + + There is nothing we can do about it, and tinc will run fine anyway. + +commit b99e1a306c7fb8f43dd61e432f3c896f5142e4ac +Author: Alexis Hildebrandt +Date: Sun Jun 22 16:43:15 2014 +0200 + + Add support to link against libresolv Mac OS X + +commit e76df30cb2af7a22e9c1dc91bb47a76c2fcbc43d +Author: Armin Fisslthaler +Date: Fri Apr 25 14:44:06 2014 +0200 + + reload /etc/resolv.conf in SIGALRM handler + +commit 132bdb77a0792d85d03ad89f846cbd4024037393 +Author: Etienne Dechamps +Date: Sun Jun 22 10:48:34 2014 +0100 + + Make DeviceStandby control network interface link status on Windows. + + Besides controlling when tinc-up and tinc-down get called, this commit makes + DeviceStandby control when the virtual network interface "cable" is "plugged" + on Windows. This is more user-friendly as the status of the tinc network can + be seen just by looking at the state of the network interface, and it makes + Windows behave better when isolated. + +commit bd451cfe1512fa69eac35a60dbe6df17bfc39154 +Author: Etienne Dechamps +Date: Sun Jun 22 10:48:34 2014 +0100 + + Add DeviceStandby option to only enable the device when nodes are reachable. + + This adds a new DeviceStandby option; when it is disabled (the default), + behavior is unchanged. If it is enabled, tinc-up will not be called during + tinc initialization, but will instead be deferred until the first node is + reachable, and it will be closed as soon as no nodes are reachable. + + This is useful because it means the device won't be set up until we are fairly + sure there is something listening on the other side. This is more user-friendly, + as one can check on the status of the tinc network connection just by checking + the status of the network interface. Besides, it prevents the OS from thinking + it is connected to some network when it is in fact completely isolated. + +commit f0885b8d2fe69610e7e294735795d98db11157a5 +Author: Etienne Dechamps +Date: Sun Jun 22 14:06:44 2014 +0100 + + Cleanly remove the device FD from the event loop before closing it. + +commit ed1d0878afe53032a4b63e87afd4a435015cf5de +Author: Etienne Dechamps +Date: Sun Jun 22 09:53:26 2014 +0100 + + Make device close cleaner. + +commit 638260865399693c3ced9337ef2664c5ba968a2a +Author: Etienne Dechamps +Date: Sun Jun 22 09:54:45 2014 +0100 + + Move Solaris if_fd to local scope. + + This variable is never used outside of setup_device(), therefore there is no + reason to declare it in global scope. + +commit 9bfc228ef5fcd4166897e32fbe82f4cc4e252922 +Author: Baptiste Jonglez +Date: Fri Jun 20 15:56:13 2014 +0900 + + Clarify man page regarding the IndirectData option + +commit 31c68993989fbca3c88df1449ea2077baafce481 +Author: Guus Sliepen +Date: Sun Jun 15 12:19:10 2014 +0200 + + Unconditionally return non-zero exit code when "tinc del" does not find the requested variable. + +commit 1ce0f7613964c7441ef683f9d875dd09cbfd667c +Author: Guus Sliepen +Date: Sun Jun 15 12:14:01 2014 +0200 + + Return non-zero exit code when "tinc get" does not find the requested variable. + +commit ef5e8b6920d1dd3097f36bd0c50170100acf2f28 +Author: Guus Sliepen +Date: Tue Jun 3 11:02:58 2014 +0200 + + Fix base64 decoding of Ed25519 keys. + +commit b0d80c7f28528c2c8857c5662b4aca779b3184bb +Author: Guus Sliepen +Date: Sun May 18 21:51:42 2014 +0200 + + Allow Cipher and Digest "none". + + This is for backwards compatibility with tinc 1.0, it has no effect on + the SPTPS protocol. + +commit 666718998eaa044f6f25fe99810a78dca8471393 +Author: Guus Sliepen +Date: Sun May 18 20:49:35 2014 +0200 + + Implement a PEM-like format for Ed25519 keys. + + We don't require compatibility with any other software, but we do want Ed25519 keys to work + the same as RSA keys for now. + +commit f0e7e6b03e34e69cac5b01a2d943ad3b9b59d36c +Author: Guus Sliepen +Date: Sun May 18 20:47:04 2014 +0200 + + Rename ECDSA to Ed25519. + +commit 35437a50e2a46861742b6fb8e49d065aa52a04dc +Author: Guus Sliepen +Date: Tue May 13 20:29:09 2014 +0200 + + Add sanity checks when generating new RSA keys. + + The key size should be a multiple of 8 bits, and it should be between 1024 and + 8192 bits. + +commit 66f325f4674e70d83744626f3b8dda6760f8d613 +Author: Guus Sliepen +Date: Mon May 12 15:57:40 2014 +0200 + + Fix PMTU discovery via datagram SPTPS. + + In send_sptps_data(), the len variable contains the length of the whole + datagram that needs to be sent to the peer, including the overhead from SPTPS + itself. + +commit c35bfa18ec49439d4a028990fcf0ae6d8c4508a5 +Author: Guus Sliepen +Date: Mon May 12 15:56:29 2014 +0200 + + Fix a crash when we have a malformed public ECDSA key of another node. + +commit c32fcdfc1dde289c52bc359b7b6c5f8c30186e58 +Author: Guus Sliepen +Date: Mon May 12 14:35:56 2014 +0200 + + Add missing closedir(). + +commit 75e5b2e906bd8563bf0f53a76065618c88122e1c +Author: Guus Sliepen +Date: Mon May 12 14:35:12 2014 +0200 + + Use void pointers to opaque buffers. + +commit 332b55d4720fadea76c0a5d9b9d484af6a724006 +Author: Guus Sliepen +Date: Tue May 6 14:11:55 2014 +0200 + + Change AutoConnect from int to bool. + + The proper value is 3, not 2 or 4, and 5 is right out. So just hardcode this value, + and only have the option to turn AutoConnect on or off. + +commit 27acb5d04792f2da70e937543de9110e16aae21c +Author: Guus Sliepen +Date: Tue May 6 13:01:48 2014 +0200 + + Fix compiler warnings. + +commit bc33a073d82cd4b5e75d00e379ddfeeaa6ade962 +Author: Guus Sliepen +Date: Tue May 6 12:58:25 2014 +0200 + + Nexthop calculation should always use the shortest path. + + When tinc runs the graph algorithms and updates the nexthop and via pointers, + it uses a breadth-first search, but it can sometimes revisit nodes that have + already been visited if the previous path is marked as being indirect, and + there is a longer path that is "direct". The via pointer should be updated in + this case, because this points to the closest hop to the destination that can + be reached directly. However, the nexthop pointer should not be updated. + + This fixes a bug where there could potentially be a routing loop if a node in + the graph has an edge with the indirect flag set, and some other edge without + that flag, the indirect edge is part of the minimum spanning tree, and a + broadcast packet is being sent. + +commit b6e2b416bf9a5788c8847267b849efcd9e5bbf95 +Author: Saverio Proto +Date: Mon May 5 15:23:25 2014 +0200 + + Fix typo in comment + +commit 18698c4e123d1ed22f3a2fc5529fac62fbabaf19 +Author: Guus Sliepen +Date: Fri Apr 25 17:00:55 2014 +0200 + + Put brackets around IPv6 addresses in invitation URL, even if there is no port number. + +commit 475088ed77df925ce0680c9993305cd746742708 +Author: Guus Sliepen +Date: Tue Apr 15 17:26:08 2014 +0200 + + sptps_test: allow using a tun device instead of stdio. + +commit 2980173ee7f8142598fe5e1ab117e463751da310 +Author: Guus Sliepen +Date: Mon Apr 14 21:43:45 2014 +0200 + + Use the ChaCha-Poly1305 cipher for the SPTPS protocol. + + The main reason to switch from AES-256-GCM to ChaCha-Poly1305 is to remove a + dependency on OpenSSL, whose behaviour of the AES-256-GCM decryption function + changes between versions. The source code for ChaCha-Pol1305 is small and in + the public domain, and can therefore be easily included in tinc itself. + Moreover, it is very fast even without using any optimized assembler, easily + outperforming AES-256-GCM on platforms that don't have special AES instructions + in hardware. + +commit 49e3baec20ddad9cc297c3eeb1d13f0e421f69c8 +Merge: 37b729d7 2f01744f +Author: Guus Sliepen +Date: Mon Apr 14 20:49:43 2014 +0200 + + Merge branch '1.1-ed25519' into 1.1 + +commit 37b729d7fdd49da5466696f7995a96ebb54fbcbb +Author: Guus Sliepen +Date: Sun Apr 13 12:09:48 2014 +0200 + + Properly initialize buffers. + + Valgrind complained about use of uninitialized data. + +commit 2f01744f82be542894fe2ceecbfb9ead93c9ffa5 +Author: Guus Sliepen +Date: Sun Apr 6 22:47:26 2014 +0200 + + Use Ed25519 keys. + + This uses the portable Ed25519 library made by Orson Peters, which in turn uses + the reference implementation made by Daniel J. Bernstein. + + This implementation also allows Ed25519 keys to be used for key exchange, so + there is no need to add a separate implementation of Curve25519. + +commit d6734a2da483675f5bcc9cf7b15723a409b1019f +Author: Guus Sliepen +Date: Sun Apr 6 22:46:06 2014 +0200 + + Fix return value of b64encode(). + +commit f134bd0c9c2213fbbb3967f3d784759cb65e2c76 +Author: Guus Sliepen +Date: Sun Mar 9 15:32:10 2014 +0100 + + Handle a disconnecting tincd better. + + - Try to prevent SIGPIPE from being sent for errors sending to the control + socket. We don't outright block the SIGPIPE signal because we still want the + tinc CLI to exit when its output is actually sent to a real (broken) pipe. + + - Don't call exit() from top(), and properly detect when the control socket is + closed by the tincd. + +commit 09e000ba54fd4a4ffe3e5c15ee7aeadac35d6996 +Author: Guus Sliepen +Date: Wed Feb 26 17:27:57 2014 +0100 + + Rewind the file before trying to use PEM_read_RSA_PUBKEY(). + +commit 44c7f554c7a6eb411428cfd30ca2cb21a613830e +Author: Guus Sliepen +Date: Wed Feb 26 11:00:30 2014 +0100 + + Add "network" command to list or switch networks. + +commit 48ecff6ddb7e6f9d6b6df7f8952c4cfb318572fa +Author: Guus Sliepen +Date: Fri Feb 7 23:06:26 2014 +0100 + + Add missing attribution for 1.1pre10 to the NEWS file. + +commit 9f7e2dffb27297385c56698638386b264c9aff1a +Author: Guus Sliepen +Date: Fri Feb 7 23:05:33 2014 +0100 + + Really fix compiling under Windows. + +commit 173072ff078a8917b60c24dbe58aa7c258450de2 +Author: Guus Sliepen +Date: Fri Feb 7 21:40:42 2014 +0100 + + Releasing 1.1pre10. + +commit cb5c1b5986861361207fa244662bb2c7f3d6a3a4 +Author: Guus Sliepen +Date: Fri Feb 7 21:40:29 2014 +0100 + + Check whether OpenSSL has support for GCM. + +commit cdda0388a82eb44ff260e25c0902794c8db9643a +Author: Guus Sliepen +Date: Fri Feb 7 21:14:41 2014 +0100 + + Fix compiling for Windows. + +commit 06a4a8c153407b690a3ce3f0e7fdaa8568ccb1a3 +Author: Guus Sliepen +Date: Fri Feb 7 20:38:48 2014 +0100 + + Update copyright notices. + +commit bc9347042bf6586d23bf17efd9fdf64a2c4a4d27 +Author: Guus Sliepen +Date: Fri Feb 7 19:57:06 2014 +0100 + + Attribution for Dennis Joachimsthaler. + +commit ac7f82cb235008d1711781a87ffdce5d45465134 +Author: Guus Sliepen +Date: Fri Feb 7 16:34:08 2014 +0100 + + Handle errors from TAP-Win32/64 adapter in a better way. + + Before, the tapreader thread would just exit immediately after encountering the + first error, without notifying the main thread. Now, the tapreader thead never + exits itself, but tells the main thread to stop when more than ten errors are + encountered in a row. + +commit 2f41780023bffc81fa42b0e72f67be86a52b370c +Author: Guus Sliepen +Date: Fri Feb 7 19:48:11 2014 +0100 + + Attribution for various contributors. + + Conflicts: + THANKS + +commit e717e424c22233aa728b75c4c8bb047e13b0107a +Author: Guus Sliepen +Date: Thu Jan 30 17:10:30 2014 +0100 + + Use addresses learned from other nodes when making outgoing connections. + + Before, when making a meta-connection to a node (either because of a ConnectTo + or because AutoConnect is set), tinc required one or more Address statements + in the corresponding host config file. However, tinc learns addresses from + other nodes that it uses for UDP connections. We can use those just as well for + TCP connections. + +commit 995444c4f96bafecf7fb5d59510b3034459cf85c +Author: Guus Sliepen +Date: Wed Jan 29 17:32:18 2014 +0100 + + Document Weight and also allow it to be set from tinc.conf. + +commit 2e318f379992a730f592b4c5261d26d8e1a38cfd +Author: Guus Sliepen +Date: Wed Jan 29 17:17:59 2014 +0100 + + Don't ask questions if we are not running interactively. + + When creating invitations or using them to join a VPN, and the tinc command is + not run interactively (ie, when stdin and stdout are not connected or + redirected to/from a file), don't ask questions. If normally tinc would ask for + a confirmation, just assume the default answer instead. If tinc really needs + some input, just print an error message instead. + + In case an invitation is used for a VPN which uses a netname that is already in + use on the local host, tinc will store the configuration in a temporary + directory. Normally it asks for an alternative netname and then renames the + temporary directory, but when not run interactively, it now just prints the + location of the unchanged temporary directory. + +commit 00398a60ec317740bcec83c5a524c5a95ce7f1c2 +Author: Guus Sliepen +Date: Mon Jan 27 23:21:25 2014 +0100 + + Add missing newlines when copying variables from tinc.conf to an invitation file. + +commit fa1e9b046128db81c207c9ed920d068a144cd687 +Author: Guus Sliepen +Date: Fri Jan 24 16:09:32 2014 +0100 + + Test two tinc daemons using network namespaces. + + Testing multiple daemons connecting to each other on the same computer is + usually difficult, because connections to local IP addresses will bypass most + of the network stack. However, recent versions of Linux support network + namespaces, which can isolate network interfaces. We use this to isolate the + virtual interface of the daemons from each other, so we get the behaviour as if + the daemons were each running on their own machine. This can also be used for + more complicated tests (including those with firewall rules) without disturbing + the real network setup of the host computer. + +commit 38adc8bf548c2c465d5f4147866c3d3f9112d3a8 +Author: Guus Sliepen +Date: Mon Jan 20 21:19:13 2014 +0100 + + Add the ListenAddress option. + + ListenAddress works the same as BindToAddress, except that from now on, + explicitly binding outgoing packets to the address of a socket is only done for + sockets specified with BindToAddress. + +commit e187758a7e163cb2d2e57db8b093823f68f1491f +Author: Guus Sliepen +Date: Mon Jan 20 20:21:15 2014 +0100 + + Document that 1.1 uses AES-256 in GCM mode. + +commit 1a115d1d1c58db179df6568e9b33fab3e8f80486 +Author: Guus Sliepen +Date: Mon Jan 20 20:16:58 2014 +0100 + + Document clearly that tinc depends on curses and readline libraries. + +commit a3decd09513370fbb3aa22dae11435103d179c30 +Author: Guus Sliepen +Date: Sun Jan 19 21:15:23 2014 +0100 + + Let tinc-gui use correct address family when connecting to tincd via TCP. + +commit c10f3105b354c523d4d4d36b09dd46f890e94a30 +Author: Dennis Joachimsthaler +Date: Fri Jan 17 18:15:40 2014 +0100 + + Ensure tinc-gui running in 64 bits mode can find tinc's 32 bit registry key. + +commit ab583f7e8c550822c63a1a6b73a7a329f622d9e0 +Author: Dennis Joachimsthaler +Date: Fri Jan 17 16:10:10 2014 +0100 + + Fix tinc-gui on Windows. + +commit 11d562e9b2b3ce483b04bb8c8cadb22a0beb1ab6 +Author: Guus Sliepen +Date: Thu Jan 16 14:52:44 2014 +0100 + + Add index entries for the CLI commands. + +commit d8ea66ff1fc68ca9ea672727b0274663df6f4866 +Author: Guus Sliepen +Date: Thu Jan 16 14:46:44 2014 +0100 + + Update the documentation of the tinc command. + +commit 8af6d64fd9dfdd684a56534249e12d201628055c +Author: Guus Sliepen +Date: Thu Jan 16 14:02:56 2014 +0100 + + Clarify StrictSubnets. + +commit c8543bbe6b9ae2de318b0ed4f54cdebcbc3fe5a4 +Author: Florent Clairambault +Date: Sun Dec 29 23:11:54 2013 +0100 + + Adding "conf.d" configuration dir support. + + Any file matching the pattern /etc/tinc/$NETNAME/conf.d/*.conf will be + parsed after the tinc.conf file. + +commit e6b32936c569d9f2ceaea76af2f8f0551d163dd9 +Author: Guus Sliepen +Date: Tue Dec 10 17:13:15 2013 +0100 + + Fix handling of --with-libgcrypt. + +commit b7d59f035bfa2e546428cac2b72318d4f5c517fb +Author: Guus Sliepen +Date: Tue Dec 10 17:02:52 2013 +0100 + + Don't enable -fstack-protector-all. + + It is not supported on all architectures and is problematic on some + platforms. + +commit 53b00f8c1abda0d477c75e4d70a7341301fa1733 +Author: Guus Sliepen +Date: Tue Dec 10 11:18:04 2013 +0100 + + Add our own autoconf check for libgcrypt. + + This one doesn't require one to have libgcrypt installed while running + autoreconf, making life easier for people who compile tinc from git. + +commit 283c5d1cf07f77d29fc1fc2f09532508f5124679 +Author: Guus Sliepen +Date: Tue Dec 10 10:48:00 2013 +0100 + + Enable compiler hardening flags by default. + + Check whether the compiler supports hardening flags and enable them unless + --disable-hardening is specified. + + Conflicts: + configure.ac + +commit ef8efdfff1de2b18092f9d4f383e3f2898bf86cd +Author: Guus Sliepen +Date: Sun Dec 8 21:37:56 2013 +0100 + + Remove erroneous warning about SPTPS being disabled. + +commit be1446f5d0e8831b60ea473a5b7b9ba40f18986e +Author: Guus Sliepen +Date: Sun Dec 8 21:32:21 2013 +0100 + + Don't print an error when no ECDSA key is known for a node using the legacy protocol. + +commit c151cfa2e978e92c1e5394bfcc8b41c6155f8436 +Author: Guus Sliepen +Date: Sun Dec 8 21:31:50 2013 +0100 + + Give full path to unconfigured tinc-up script. + +commit 1b580b2a6beee9d32488a1d95c45de336dee9c2e +Author: Guus Sliepen +Date: Sun Dec 8 21:06:03 2013 +0100 + + Allow running without ECDSA keys If ExperimentalProtocol is not explicitly set. + + To make upgrading less painful, allow running tinc 1.1 without ECDSA keys + unless ExperimentalProtocol is explicitly set to yes. + +commit 41583d5dcfc1277b1a203478de4cce2cd0cda1b1 +Author: Guus Sliepen +Date: Sun Dec 8 20:23:44 2013 +0100 + + Don't print device statistics when exiting tinc. + + Much more detailed statistics are now kept per node, which can be queried at + any time, which makes the device statistics obsolete. + +commit 19b97e79aa63bcb6f81c2dbfd7ca91d89a230387 +Author: Guus Sliepen +Date: Sat Dec 7 22:59:37 2013 +0100 + + Prefer ncurses over curses. + +commit b115de21990ecb1a2f377a73d07ff26e35980aba +Author: Guus Sliepen +Date: Sat Dec 7 22:54:02 2013 +0100 + + Use hardcoded value for TUNNEWPPA if net/if_tun.h is missing on Solaris. + +commit cf9bea4e938f4eec531782e2e947d711cac16014 +Author: Guus Sliepen +Date: Sat Dec 7 22:39:24 2013 +0100 + + Avoid using a variable named "sun". Solaris doesn't like it. + +commit 221f559bcf13febc9a4135c5eb54c236c543ee19 +Author: Guus Sliepen +Date: Sat Dec 7 22:20:10 2013 +0100 + + Stricter check for raw socket support. + +commit c1f7357e7dca18f43f02541cff2684f737512686 +Author: Guus Sliepen +Date: Sat Dec 7 22:19:39 2013 +0100 + + Include for PATH_MAX. + +commit c9bdac68e1b56d34b8fd8bff03bddda1d2cca516 +Author: Guus Sliepen +Date: Sat Dec 7 21:52:41 2013 +0100 + + Update support for Solaris. + + Adds support for the latest TAP driver from + http://www.whiteboard.ne.jp/~admin2/tuntap/, so tinc now also works in switch + mode on Solaris 11. + +commit 06943e828c45d8f4f1da6dc51907499f92957a39 +Author: Guus Sliepen +Date: Thu Dec 5 15:01:30 2013 +0100 + + If no Port is specified, set myport to actual port of first listening socket. + + If the Port statement is not used, there are two other ways to let tinc listen + on a non-default port: either by specifying one or more BindToAddress + statements including port numbers, or by starting it from systemd with socket + activation. Tinc announces its own port to other nodes, but before it only + announced what was set using the Port statement. + +commit 3e924045ccaab1441b77ff43a2d7eb759b313f7b +Author: Guus Sliepen +Date: Thu Dec 5 14:30:00 2013 +0100 + + Mention in the manual that multiple Address staments are allowed. + +commit 51bddfd4dd95161afae2cac4aa5d31970fef5714 +Author: Guus Sliepen +Date: Thu Nov 28 14:19:55 2013 +0100 + + Allow "none" for Cipher and Digest again. + +commit 3d41e7d71247998b7c4a3dd4eacb93bd3529428d +Author: Guus Sliepen +Date: Thu Nov 21 22:13:14 2013 +0100 + + Make LocalDiscovery work for SPTPS packets. + +commit c1703ea9172be05f501d636510834e31d5d4f98c +Author: Guus Sliepen +Date: Wed Nov 20 23:02:20 2013 +0100 + + Remove an unused variable. + +commit 6168a9b6d51b19378af9ba9977227042cf6eafc6 +Author: Guus Sliepen +Date: Fri Nov 15 15:32:53 2013 +0100 + + Fix two warnings from Clang's static analyzer. + +commit 29b42aa17ede17bc67963292e86b186cc09039b1 +Author: Guus Sliepen +Date: Tue Oct 22 21:28:44 2013 +0200 + + Fix sending bulk data starting with a newline. + +commit a5bcb29fdffe9bb2a9dd59c2e315f13fda6d5b34 +Author: Guus Sliepen +Date: Tue Oct 22 21:19:41 2013 +0200 + + Make sptps_test less verbose by default. + +commit 7da999f4aee4e9c8b192769fddbe1c61cd31d7d0 +Author: Guus Sliepen +Date: Fri Oct 18 16:58:47 2013 +0200 + + Clean up child processes from proxy type exec. + +commit 9b2eaebdf6eb46321403bfc6af1145d051d3bbdc +Author: Guus Sliepen +Date: Tue Oct 15 14:09:42 2013 +0200 + + Fix sending empty SPTPS records. + +commit 0da07280882253b792ddf9c6bd8b6690ba585b7a +Author: Guus Sliepen +Date: Sun Oct 13 01:02:52 2013 +0200 + + Use AES-256-GCM for the SPTPS protocol. + + It is faster than AES-256-CTR + HMAC-SHA256, especially on Intel chips with AES + and PCLMULQDQ instructions. + +commit e42bd6009785263b545c1651840943c01461ffda +Author: Guus Sliepen +Date: Fri Sep 27 10:43:56 2013 +0200 + + Fix typos in the documentation. + + Thanks to Thomas Sattler for finding and reporting them. + +commit 68e3efe34980cc82ffc143fc33d3c11b69ec8e2b +Author: Guus Sliepen +Date: Fri Sep 27 11:36:46 2013 +0200 + + Fix segfault when Name = $HOST but $HOST is not set. + + Conflicts: + src/net_setup.c + +commit 22d804d4467cfe9f3926ab6d37b69c3760395b6c +Author: Guus Sliepen +Date: Sun Sep 15 22:03:00 2013 +0200 + + Link sptps_speed with -lrt. + + This is necessary for clock_gettime() on older versions of libc. + +commit c621dd62c74284bfc307a351bec875eb6918bf0f +Author: Guus Sliepen +Date: Sun Sep 15 22:02:33 2013 +0200 + + Don't leak memory during the key generation speed test. + +commit b7b68c3e979994a70f3adb9b40784f65cadf6a75 +Author: Guus Sliepen +Date: Sun Sep 15 17:35:55 2013 +0200 + + Add a benchmark for the SPTPS protocol. + +commit 87b017c71062bbc75ab5a98795abaf87f96ceba6 +Author: Guus Sliepen +Date: Sun Sep 15 16:21:25 2013 +0200 + + Avoid using BIOs. + +commit aaa7caad3d2a03d799264b0d62cddac6b4ee4092 +Author: Guus Sliepen +Date: Sun Sep 15 13:36:53 2013 +0200 + + Wrong date for the 1.1pre9 release in the NEWS. + +commit 85d33e563a0e4ce5910c9ba3b34eba8fbb1cbd30 +Author: Guus Sliepen +Date: Sun Sep 8 17:29:12 2013 +0200 + + Releasing 1.1pre9. + +commit e11daa264615f6eb5782f1f349b23f47518577dd +Author: Guus Sliepen +Date: Sun Sep 8 15:03:06 2013 +0200 + + Don't try to mkdir(CONFDIR) if --config is used. + +commit c25c684a847e11be80916e6de0608f11958d701d +Author: Guus Sliepen +Date: Sun Sep 8 14:47:59 2013 +0200 + + Make sure test scripts end up in the tarball. + +commit 6072759bcb6118923685ace08048c2917425680a +Author: Guus Sliepen +Date: Sun Sep 8 14:42:32 2013 +0200 + + Automake doesn't like info files being mentioned in CLEANFILES. + +commit b80cbaba040775ba20159b20d02c8c903c84e0e1 +Author: Guus Sliepen +Date: Thu Sep 5 17:42:31 2013 +0200 + + Test running ping through two tinc daemons. + + This is a more complicated test with one tinc daemon using a tap interface + (therefore requiring root), and a second one using a multicast interface. A + separate program "pong" is listening on the same multicast address, and waits + for ARP and ICMP packets, responding to ICMP echo packets with replies. + This test doesn't require any configuration of the tap interface. + +commit fe1d0043c81b26f337bdce63dd290d882b01cf21 +Author: Guus Sliepen +Date: Thu Sep 5 17:41:05 2013 +0200 + + Don't return zero-length packets when receiving multicast loopback packets. + +commit 2faf3e91af90716180bde27f54370fe4cbfc64c2 +Author: Guus Sliepen +Date: Thu Sep 5 14:59:56 2013 +0200 + + Add two more test scripts. + +commit 6242b68242646fa94bdacc94be93f0e894ae757e +Author: Guus Sliepen +Date: Thu Sep 5 14:51:13 2013 +0200 + + Fix multicast device. + +commit 09b5a3c02057fe9448c4e9494a99c93a61f98280 +Author: Guus Sliepen +Date: Thu Sep 5 14:50:10 2013 +0200 + + Exit value 1 instead of a random non-zero value. + +commit bdbb710060bef4b3ec63f5592e4def57a4817bd9 +Author: Guus Sliepen +Date: Mon Sep 2 00:15:50 2013 +0200 + + Add a test for invite and join commands. + +commit 566ef6bcbae2bb17c30d500c96331d0c7bdca070 +Author: Guus Sliepen +Date: Mon Sep 2 00:15:18 2013 +0200 + + Also test whether tinc daemons can connect to each other after import/export. + +commit 796c14b75c9e8066b4f68f6ce7cdaddd97c46a87 +Author: Guus Sliepen +Date: Mon Sep 2 00:11:04 2013 +0200 + + Slightly relax the connection rate limit for a single address. + + The restriction of accepting only 1 connection per second from a single address + is a bit too much, especially if one wants to join a VPN using an invitation, + which requires two connections. + +commit 933f7f7526d89a4ad41e2c2936c26cb41997ed78 +Author: Guus Sliepen +Date: Sun Sep 1 22:59:51 2013 +0200 + + Send a RELOAD to a running tincd when a new invitation key has been generated. + +commit 4e7e4818b771af47a10ce0b8f4046ab455ef14a9 +Author: Guus Sliepen +Date: Sun Sep 1 22:58:45 2013 +0200 + + Clean up leftover tincd and sptps_test processes. + +commit b00a6d0666f13b5206b6fcb21479281270169584 +Author: Guus Sliepen +Date: Sun Sep 1 21:55:16 2013 +0200 + + Fix tincd logfile location when running tests. + +commit c179dd0fc8ba0d20e8b29b0a5d2485a637e999e6 +Author: Etienne Dechamps +Date: Sun Sep 1 20:07:32 2013 +0100 + + Fix broken build with --with-openssl, --with-libgcrypt. + + When --with-openssl is used, $openssl is set to the specified path. + Unfortunately, that confuses the OPENSSL conditional which expects it to + be set to "true". The result is that the contents of the openssl/ + directory are not built when --with-openssl is used, resulting in + undefined references and a broken build. + + In addition, there is a typo in the GCRYPT conditional definition + ("grypt" instead of "gcrypt") which means GCRYPT never gets set, + (presumably) breaking builds using libgcrypt. + + These regressions were introduced in + 9b9230a0a79c670b86f54fadd2807b864ff9d91f. + +commit a4e49f45664cfc9414d6eaaa7bd45f1eb3012e37 +Author: Guus Sliepen +Date: Sun Sep 1 21:07:02 2013 +0200 + + Add test for import, export and exchange commands. + +commit 2cd8e2b8e8d60fdeb633afe54eaf38e18afb04dc +Author: Guus Sliepen +Date: Sun Sep 1 21:06:25 2013 +0200 + + Small fixes for tests. + +commit 09cd7ac62a40851a73f0bf7e8721848c10a7b1ff +Author: Guus Sliepen +Date: Sun Sep 1 16:02:49 2013 +0200 + + Make sptps_test more easy to work with. + + It now defers reading from stdin until after the authentication phase is + completed. Furthermore, it supports the -q, -r, -w options similar to those of + Jürgen Nickelsen's socket. + +commit 1cdb0c21d42d600d0e89857f4e9f33843f9372c8 +Author: Guus Sliepen +Date: Sun Sep 1 15:40:59 2013 +0200 + + Some shells set $_ to an absolute path. + +commit 05a7f0b2fb07f8ee7752604a2a87b85f2430aaa3 +Author: Guus Sliepen +Date: Sun Sep 1 00:39:14 2013 +0200 + + Start of a test suite. + +commit d01ab07f78f84d7d30c5788416c8d4ca0e1f74bf +Author: Guus Sliepen +Date: Fri Aug 30 14:23:02 2013 +0200 + + Allow testing the replay window with sptps_test. + +commit ccbf70b66f8e5ac18e672309a7bad899cfc0f400 +Author: Guus Sliepen +Date: Fri Aug 30 14:22:05 2013 +0200 + + Fix the replay window in SPTPS. + +commit c7752ca73e582d63412e7f40984cff2fca02c22f +Author: Guus Sliepen +Date: Fri Aug 30 13:43:23 2013 +0200 + + Fix CTR mode. + +commit d0aa0817d2387e89555ed090d900f61c56b19caa +Author: Guus Sliepen +Date: Fri Aug 30 13:04:14 2013 +0200 + + Add an option to test datagram SPTPS with packet loss. + +commit 5da0ebd421572230fbd213ca0749df6771f4cb10 +Author: Guus Sliepen +Date: Wed Aug 28 14:24:07 2013 +0200 + + When generating invitations, handle any order of Port and Adress statements. + +commit f0e11cd2c55a83662049646d2f6ffba3ac697989 +Author: Guus Sliepen +Date: Tue Aug 27 21:19:50 2013 +0200 + + Call WSAStartup() in main(). + + The tinc utility defered calling WSAStartup() until it tried to connect to a + running tinc daemon. However, socket functions are now also used for other + things (like joining another VPN using an invitation). Now we just + unconditionally call WSAStartup() early in main(). + +commit 82575bd44dc02bd1febd265c1db0f05b298329af +Author: Guus Sliepen +Date: Sat Aug 24 00:48:24 2013 +0200 + + Tell invited node about Mode and Broadcast settings. + + Since these settings really should be the same for all nodes in a VPN. + +commit 57991e264202ad83e2c1b663777b358bf5573652 +Author: Guus Sliepen +Date: Fri Aug 23 19:24:36 2013 +0200 + + Use PATHEXT when checking for the presence of scripts on Windows. + + It seems like a lot of overhead to call access() for every possible extension + defined in PATHEXT, but apparently this is what Windows does itself too. At + least this avoids calling system() when the script one is looking for does not + exist at all. + + Since the tinc utility also needs to call scripts, execute_script() is now + split off into its own source file. + +commit 21184674b38ea1da87588de97dab076c9b9e4a81 +Author: Guus Sliepen +Date: Wed Aug 21 00:24:55 2013 +0200 + + Execute scripts when invitations are created or accepted. + +commit 9699f08afc6420d2bdac1063ea6789b585aaf42e +Author: Guus Sliepen +Date: Tue Aug 20 23:09:36 2013 +0200 + + Ensure the invitation filenames do not reveal the secret cookie. + + Since filenames could potentially leak to unprivileged users (for example, + because of locatedb), it should not contain the cookie used for invitations. + Instead, tinc now uses the hash of the cookie and the invitation key as the + filename to store pending invitations in. + +commit 5dec1c25713a19c49fcbb885200184a9682ef175 +Author: Guus Sliepen +Date: Tue Aug 20 22:36:31 2013 +0200 + + Let a server explicitly send a notification when the invitation protocol succeeded. + +commit c798f7309337fc4c6dec7fd99d45cd76f809ab02 +Author: Guus Sliepen +Date: Tue Aug 20 16:49:03 2013 +0200 + + Use our own infrastructure for finding out the local node's externally visible host name. + +commit 160b7cb5e3e9b7869f6ca38e6a7ab2db39aba979 +Author: Guus Sliepen +Date: Tue Aug 20 16:47:07 2013 +0200 + + Resolve the local host name before generating the invitation file. + +commit 65f5e8fba45c6c51cfdfa2a41ab6db14663cdf73 +Author: Guus Sliepen +Date: Sun Aug 18 23:55:40 2013 +0200 + + Bind outgoing sockets again. + + Commit cff5a84 removed the feature of binding outgoing TCP sockets to a local + address. We now call bind() again, but only if there is exactly one listening + socket with the same address family as the destination address of the outgoing + socket. + +commit 0c54f365534fcb345e87961e71d452e269e170fe +Author: Guus Sliepen +Date: Sun Aug 18 22:43:55 2013 +0200 + + Remove broadcast of KEY_CHANGED message during tinc's initialization. + +commit 09b0b49b98cc16f6b281e4e635c2c70234e38865 +Author: Guus Sliepen +Date: Sun Aug 18 22:35:27 2013 +0200 + + Fix order of tincd's initialization. + + The order in which tinc initialized things was not completely correct. Now, it + is done as follows: + + - Load and parse configuration files. + - Create all TCP and UDP listening sockets. + - Create PID file and UNIX socket. + - Run the tinc-up script. + - Drop privileges. + - Start outgoing connections. + - Run the main loop. + + The PID file can only be created correctly if the listening sockets have been + set up ,as it includes the address and port of the first listening socket. The + tinc-up script has to be run after the PID file and UNIX socket have been + created so it can change their permissions if necessary. Outgoing connections + should only be started right before the main loop, because this is not really + part of the initialization. + +commit 8f8424445810aa7d5e9d4d537494e64811a8e29f +Author: Guus Sliepen +Date: Sun Aug 18 18:20:41 2013 +0200 + + Don't force a .bat extension for scripts under Windows. + +commit b180c1af99c559809d0e7b23fce3022817ec56a9 +Author: Guus Sliepen +Date: Sun Aug 18 17:02:49 2013 +0200 + + Create UNIX socket at the same time as the PID file is created. + + The PID file was created before tinc-up was called, but the UNIX socket was + created afterwards, which meant one could not change the UNIX socket's owner or + permissions from the tinc-up script. + +commit 707914e0e4b45183b1f687b44d97731127df3078 +Author: Guus Sliepen +Date: Wed Aug 14 16:20:32 2013 +0200 + + Remove texi2html rule in docs/Makefile. + + According to Debian, texi2html is deprecated and makeinfo --html should be used + instead. Automake already provides a html target that invokes makeinfo. + +commit 5e50a56dd9ebef71683b60856f904d352a3b89dc +Author: Guus Sliepen +Date: Wed Aug 14 16:17:12 2013 +0200 + + Stop using EXTRA_DIST in src/Makefile.am. + + Automake finds the files in the subdirectories of src/ now that they are + properly declared in the _SOURCES variables. Using EXTRA_DIST would now cause + .o files to be included in the tarball. + +commit 60e774942826cb28c53ac6fd23887162323696e9 +Author: Guus Sliepen +Date: Tue Aug 13 22:05:43 2013 +0200 + + Releasing 1.1pre8. + +commit 6aa864baa626b366f5bba1f1b349a870b68d7c01 +Author: Guus Sliepen +Date: Tue Aug 13 20:40:40 2013 +0200 + + Don't typedef the same struct in two header files. + + Some (older?) versions of GCC don't like this. + +commit 5e00a24e1f13fa70a6945831c409d873b7809d11 +Author: Guus Sliepen +Date: Tue Aug 13 20:38:57 2013 +0200 + + Update copyright notices. + +commit a61d3d1c0b6d0dc1b53040ae2e1a055fb34eb832 +Author: Guus Sliepen +Date: Tue Aug 13 20:37:55 2013 +0200 + + Build .tar.gz instead of .tar.xz. + + Only FreeBSD's tar supports xz compression, the other BSDs do not. NetBSD doesn't even + like bzip2. + +commit 2df534808d75c5898a819a7a4063c7a6f2445bd4 +Author: Guus Sliepen +Date: Tue Aug 13 20:35:48 2013 +0200 + + Move .h files from noinst_HEADERS to tincd_SOURCES. + + This is the recommended way according to the Automake manual. + +commit de8e6bf452227094a8aadd32dd5ea0d94d4b5db9 +Author: Guus Sliepen +Date: Thu Aug 8 17:40:15 2013 +0200 + + Don't echo broadcast packets back when Broadcast = direct. + +commit 81c71203201f6642a496f466660236efdd522ceb +Author: Guus Sliepen +Date: Fri Aug 2 23:51:55 2013 +0200 + + Fix a typo. + +commit 76c90e1639ee900fca4fc858260f0078ba32b9b1 +Author: Guus Sliepen +Date: Fri Aug 2 23:46:19 2013 +0200 + + Non-zero exit code when reloading config file fails after SIGHUP. + + When reloading the configuration file via the tinc command, the user will get + an error message if reloading has failed. However, no such warning exists when + sending a HUP signal. Previously, tincd would exit in both cases, but with a + zero exit code. Now it will exit with code 1 when reloading fails after a + SIGHUP, but tincd will keep running if it is signaled via the tinc command. + Instead, the tinc command will exit with a non-zero exit code. + +commit f3a2bed063d98961d0619ca318185740f8cf6f99 +Author: Guus Sliepen +Date: Fri Aug 2 20:53:54 2013 +0200 + + Really retry outgoing connections immediately if requested. + + The retry() function would only abort connections that were in progress of + being made, it wouldn't reschedule the outgoing connections that had been + sleeping. + +commit 1e7d1cd3c72cc478482fb75b15f9f50745b68504 +Author: Guus Sliepen +Date: Fri Aug 2 20:50:19 2013 +0200 + + Clean up the SIGINT handler. + +commit a38e0d621397d6d69c939ccc287d5a803b668195 +Author: Guus Sliepen +Date: Fri Aug 2 19:27:06 2013 +0200 + + Use umask() to set file and UNIX socket permissions without race conditions. + + As mentioned by Erik Tews, calling fchmod() after fopen() leaves a small window + for exploits. As long as tinc is single-threaded, we can use umask() instead to + reduce file permissions. This also works when creating the AF_UNIX control socket. + + The umask of the user running tinc(d) is used for most files, except for the + private keys, invitation files, PID file and control socket. + +commit a1f4f14c6c5e269c901e6e019418fb8f789cf96b +Author: Guus Sliepen +Date: Fri Jul 26 15:48:52 2013 +0200 + + Defer handling netname conflicts when accepting an invitation. + + In case no explicit netname of configuration directory is specified when + accepting an invitation, the netname specified in the invitation data is + used. However, this new netname is only known after making the connection + to the server. If the new netname conflicts with an existing one at the + client, we ask the user for a netname that doesn't conflict. However, we + should first finish accepting the invitation, so we don't run into the + problem that the server times out and cancels the invitation. So, we create + a random netname and store the files there, and only after we finish + accepting the invitation we ask the user for a better netname, and then + just rename the temporary directory to the final name. + +commit d47c79533f831a2714aff277aff31c46da1ec684 +Author: Guus Sliepen +Date: Fri Jul 26 15:44:05 2013 +0200 + + Make absolutely sure we can write config files before accepting an invitation. + +commit 37cca72e6c973b77b5d11dcf721ae050edc23586 +Author: Guus Sliepen +Date: Fri Jul 26 14:53:36 2013 +0200 + + Choose a different Port when 655 isn't available when doing "tinc join". + +commit 8f2db4afddf109e59c7ec0cdb7ad79db75d698e5 +Author: Guus Sliepen +Date: Fri Jul 26 14:17:15 2013 +0200 + + Choose a different Port when 655 isn't available when doing "tinc init". + + If port 655 cannot be bound to when using the init command, tinc will try to + find a random port number that can be bound to, and will add the appropriate + Port variable to its host config file. A warning will be printed as well. + +commit d6a67266c812a85f11c734503ae5560ab8983edb +Author: Guus Sliepen +Date: Thu Jul 25 17:17:33 2013 +0200 + + Don't forget the Port variable when creating an invitation URL. + +commit d1e01bc880a6970050e55f19bafe8eaf1f0b9be2 +Author: Guus Sliepen +Date: Thu Jul 25 17:14:07 2013 +0200 + + Allow control-C to stop tincd without stopping the tinc shell. + +commit d219fe2c09652fcdc6b457bb5fd72ad18a3a33c5 +Author: Guus Sliepen +Date: Thu Jul 25 16:21:11 2013 +0200 + + Warn when incorrect use of add or set causes variables to be removed. + +commit e6249695684dcddc5d7ae0269adc7764ecec925a +Author: Guus Sliepen +Date: Wed Jul 24 20:48:31 2013 +0200 + + Fix compression when using the SPTPS protocol. + +commit 5fca595b80f5d2a6629d74e89ca2ef46ba9ae292 +Author: Guus Sliepen +Date: Mon Jul 22 22:58:13 2013 +0200 + + Honour umask, let temporary key files inherit original's permissions. + + During the init command, tinc changed the umask to 077 when writing the public + and private key files, to prevent the temporary copies from being world + readable. However, subsequently created files would therefore also be + unreadable for others. Now we don't change the umask anymore, therefore + allowing the user to choose whether the files are world readable or not by + setting the umask as desired. The private key files are still made unreadable + for others of course. Temporary files now inherit the permissions of the + original, and the tinc-up script's permissions now also honour the umask. + +commit ae85a020303d523f24ddf45a816e6a2ceb4fc935 +Author: Etienne Dechamps +Date: Mon Jul 22 21:22:26 2013 +0100 + + Further improve bandwidth estimation for type 2 MTU probe replies. + + This patch adds timestamp information to type 2 MTU probe replies. This + timestamp can then be used by the recipient to estimate bandwidth more + accurately, as jitter in the RX direction won't affect the results. + +commit e3c763eae89df9a69bb2d611238ef18f78de311f +Author: Etienne Dechamps +Date: Sun Jul 21 13:05:42 2013 +0100 + + Introduce lightweight PMTU probe replies. + + When replying to a PMTU probe, tinc sends a packet with the same length + as the PMTU probe itself, which is usually large (~1450 bytes). This is + not necessary: the other node wants to know the size of the PMTU probes + that have been received, but encoding this information as the actual + reply length is probably the most inefficient way to do it. It doubles + the bandwidth usage of the PMTU discovery process, and makes it less + reliable since large packets are more likely to be dropped. + + This patch introduces a new PMTU probe reply type, encoded as type "2" + in the first byte of the packet, that indicates that the length of the + PMTU probe that is being replied to is encoded in the next two bytes of + the packet. Thus reply packets are only 3 bytes long. + + (This also protects against very broken networks that drop very small + packets - yes, I've seen it happen on a subnet of a national ISP - in + such a case the PMTU probe replies will be dropped, and tinc won't + enable UDP communication, which is a good thing.) + + Because legacy nodes won't understand type 2 probe replies, the minor + protocol number is bumped to 3. + + Note that this also improves bandwidth estimation, as it is able to + measure bandwidth in both directions independently (the node receiving + the replies is measuring in the TX direction) and the use of smaller + reply packets might decrease the influence of jitter. + +commit e3a4672afb8eb341b380e74b2bf6d098f61c08a3 +Author: Etienne Dechamps +Date: Sat Jul 20 22:59:57 2013 +0100 + + Disable PMTU discovery when TCPOnly is set. + + Obviously, PMTU discovery doesn't make much sense when we know we'll be + using TCP anyway. + +commit b03bbaa38561e790873de3adabc3d4405be17fb8 +Author: Guus Sliepen +Date: Sun Jul 21 00:20:54 2013 +0200 + + Allow extra options to be passed to "tinc restart" again. + +commit e82bec667059b370b0cfd5df2a34647b8f32829c +Author: Guus Sliepen +Date: Sun Jul 21 00:13:38 2013 +0200 + + Forbid protocol version rollback. + + When we know a node's ECDSA key, we only allow communication via the SPTPS + protocol. + +commit fab2965d381f2f71ea8d249d30294918e954d2db +Author: Guus Sliepen +Date: Sat Jul 20 23:41:01 2013 +0200 + + Attribution for Etienne Dechamps. + +commit 51c1639884b409a98a4581a7b661ef65b94e9d86 +Author: Etienne Dechamps +Date: Sat Jul 20 14:50:28 2013 +0100 + + Fix hash_function(). + + The hashing function that tinc uses is currently broken as it only looks + at the first 4 bytes of data. + + This leads to interesting bugs, like the node UDP address cache being + subtly broken because two addresses with the same protocol and port (but + not the same IP address) will override each other. This is because + the first four bytes of sockaddr_in contains the IP protocol and port, + while the IP address itself is contained in the four remaining bytes + that are never used when the hash is computed. + +commit 182890814881be90e28ac5183039e25709766992 +Author: Guus Sliepen +Date: Wed Jul 17 18:06:56 2013 +0200 + + Don't use vasprintf() anymore on Windows. + + Windows doesn't actually support it, but MinGW provides it. However, with some versions of + MinGW it doesn't work correctly. Instead, we vsnprintf() to a local buffer and xstrdup() the + results. + +commit 54127996ca4156668b6c7df3bb5d8f952dc598ad +Author: Guus Sliepen +Date: Wed Jul 17 18:02:07 2013 +0200 + + Don't search in local directories for include files. + + Tinc's source code doesn't rely on this anymore, and this gets rid of potential conflicts with + system headers. + +commit fb1e69072e9c1dda35033cc2785c27e324a2abda +Author: Guus Sliepen +Date: Wed Jul 17 18:00:40 2013 +0200 + + Add missing definitions on Windows. + +commit 918067f117d5b9983a8f2273fd81983362a2ff88 +Author: Guus Sliepen +Date: Mon Jul 15 14:48:43 2013 +0200 + + Fix warning "Both netname and configuration directory given" on Windows. + +commit 633b7cbb452ea19e515cadee9bc63e631f8183c2 +Author: Etienne Dechamps +Date: Sat Jul 13 23:34:42 2013 +0100 + + Fix combination of Mode = router and DeviceType = tap on Linux. + + I believe I have found a bug in tinc on Linux when it is used with + Mode = router and DeviceType = tap. This combination is useful because + it allows global broadcast packets to be used in router mode. However, + when tinc receives a packet in this situation, it needs to make sure its + destination MAC address matches the address of the TAP adapter, which is + typically not the case since the sending node doesn't know the MAC + address of the recipient. Unfortunately, this is not the case on Linux, + which breaks connectivity. + +commit 24e3ec863ec463186501f76961c6d4b1dfe122af +Author: Guus Sliepen +Date: Thu Jul 11 23:38:38 2013 +0200 + + Add connection rate limiting. + + Tinc now strictly limits incoming connections from the same host to 1 per + second. For incoming connections from multiple hosts short bursts of incoming + connections are allowed (by default 100), but on average also only 1 connection + per second is allowed. + + When an incoming connection exceeds the limit, tinc will keep the connection in + a tarpit; the connection will be kept open but it is ignored completely. Only + one connection is in a tarpit at a time to limit the number of useless open + connections. + +commit 2eba7933053d7d21bf82e647978ee90abe98dc3a +Author: Guus Sliepen +Date: Fri Jul 5 21:36:51 2013 +0200 + + Set $NAME when calling host-up/down and subnet-up/down scripts. + +commit b811e980e3a2a301c019459b91df2252468fd572 +Author: Guus Sliepen +Date: Fri May 31 18:50:34 2013 +0200 + + Add the LocalDiscoveryAddress option. + + When LocalDiscovery is enabled, tinc normally sends broadcast packets during + PMTU discovery to the broadcast address (255.255.255.255 or ff02::1). This + option lets tinc use a different address. + + At the moment only one LocalDiscoveryAddress can be specified. + +commit e92b2004e20e1c8e6bc56f97bf4a45c6da4a630c +Author: Guus Sliepen +Date: Fri May 31 17:23:00 2013 +0200 + + Use strerror() instead of gai_strerror() when err == EAI_SYSTEM. + +commit ce5e0f6557edba19f8077661c034f48cdfd64b9a +Author: Guus Sliepen +Date: Thu May 30 17:38:48 2013 +0200 + + Allow the log output to be stopped with control-C in tinc's shell. + +commit 6bf3595a915111770b7a167c54ccbca86cfbec78 +Author: Guus Sliepen +Date: Thu May 30 16:53:16 2013 +0200 + + Better optional argument handling. + + Some options can take an optional argument. However, in this case GNU getopt + requires that the optional argument is right next to the option without + whitespace inbetween. If there is whitespace, getopt will treat it as a + non-option argument, but tincd ignored those without a warning. Now tincd will + allow optional arguments with whitespace inbetween, and will give an error when + it encounters any other non-option arguments. + + The tinc binary now requires that all options for itself are given before the + command. + +commit ced4c1a327b321a6d73028a3a15b41b0be64d910 +Author: Guus Sliepen +Date: Wed May 29 18:31:10 2013 +0200 + + Add an invitation protocol. + + Using the tinc command, an administrator of an existing VPN can generate + invitations for new nodes. The invitation is a small URL that can easily + be copy&pasted into email or live chat. Another person can have tinc + automatically setup the necessary configuration files and exchange keys + with the server, by only using the invitation URL. + + The invitation protocol uses temporary ECDSA keys. The invitation URL + consists of the hostname and port of the server, a hash of the server's + temporary ECDSA key and a cookie. When the client wants to accept an + invitation, it also creates a temporary ECDSA key, connects to the server + and says it wants to accept an invitation. Both sides exchange their + temporary keys. The client verifies that the server's key matches the hash + in the invitation URL. After setting up an SPTPS connection using the + temporary keys, the client gives the cookie to the server. If the cookie + is valid, the server sends the client an invitation file containing the + client's new name and a copy of the server's host config file. If everything + is ok, the client will generate a long-term ECDSA key and send it to the + server, which will add it to a new host config file for the client. + + The invitation protocol currently allows multiple host config files to be + send from the server to the client. However, the client filters out + most configuration variables for its own host configuration file. In + particular, it only accepts Name, Mode, Broadcast, ConnectTo, Subnet and + AutoConnect. Also, at the moment no tinc-up script is generated. + + When an invitation has succesfully been accepted, the client needs to start + the tinc daemon manually. + +commit 12e68b95e6a84582a016492a467d0a16337a3c4b +Author: Guus Sliepen +Date: Tue May 28 13:41:53 2013 +0200 + + Fix port number in pidfile. + +commit cbe03b09324dcf930e9bec71a809c66e2d3d77d5 +Author: Guus Sliepen +Date: Tue May 28 13:40:32 2013 +0200 + + Add a newline when logging to stderr in the tinc binary. + +commit c3d357af6c73d538f7cbcaca293ebbca666d3a82 +Author: Guus Sliepen +Date: Tue May 28 13:39:15 2013 +0200 + + Improve base64 encoding/decoding, add URL-safe variant. + + b64decode() now returns length 0 when an invalid character was encountered. + +commit ad93dc3a4b89799e8d5c1154e1dacc5b9a31c83b +Author: Guus Sliepen +Date: Tue May 28 13:36:26 2013 +0200 + + Annotate the xalloc functions. + + Most important is the annotation of xasprintf() with the format attribute, + which allows the compiler to give warnings about the format string and + arguments. + +commit bc87b450034382858822b918f43bdf31ad8e6995 +Author: Guus Sliepen +Date: Sat May 18 16:11:30 2013 +0200 + + Send a new key when we receive packets from a node we don't have a valid key for. + +commit a9b80226e10b0a957604ad55edd945f49bc5f334 +Author: Guus Sliepen +Date: Wed May 15 13:55:06 2013 +0200 + + Enable and fix warnings from automake. + +commit a518f82af79036527cb8d1a592a6778ec1657e9c +Author: Sven-Haegar Koch +Date: Tue May 14 02:57:35 2013 +0200 + + Modified some error messages in src/sptps.c. + +commit fa20cfceecee1756ecb7882b6fe9167f4db92777 +Author: Guus Sliepen +Date: Sun May 12 13:39:22 2013 +0200 + + Don't try to handle incoming data if sptps_start() has not been called yet. + +commit 52f64cdf954a525bf7de1c5f9d3be60dfbe220b5 +Author: Guus Sliepen +Date: Sat May 11 16:54:50 2013 +0200 + + Fix potential NULL pointer dereferences. + +commit d03dc91e27b31851f87351c03cfc9a43c1b06458 +Author: Guus Sliepen +Date: Sat May 11 14:13:23 2013 +0200 + + Don't free ephemeral ECDH keys twice. + + ecdh_compute_shared() was changed to immediately delete the ephemeral key after + the shared secret was computed. Therefore, the pointer to the ecdh_t struct + should be zeroed so it won't be freed again when a struct sptps_t is freed. + +commit fc119fb0096a9221f2cff279b07c886bcd794d28 +Author: Guus Sliepen +Date: Sat May 11 14:05:28 2013 +0200 + + Use read_host_config() where appropriate. + +commit 3c163a3796c984deb874fb1cca1ed9a85fc1d087 +Author: Guus Sliepen +Date: Sat May 11 14:04:39 2013 +0200 + + Fix check for presence of ECDSA public key for outgoing connections. + + At this point, c->config_tree may or may not be NULL, but this does not tell us whether it is an + outgoing connection or not. For incoming connections, we do not know the peer's name yet, + so we always have to claim ECDSA support. For outgoing connections, we always need to check + whether we have the peer's ECDSA public key, so that if we don't, we correctly tell the peer that + we want to upgrade. + +commit c83c2d080f21b12db42ef664d7c3272b8b700656 +Author: Guus Sliepen +Date: Fri May 10 21:11:45 2013 +0200 + + Enable the SPTPS protocol by default. + +commit ee34ac3d6125b7d1f41afa82c7e30f0a7205546c +Author: Guus Sliepen +Date: Fri May 10 20:55:52 2013 +0200 + + Add a few more checks and warnings in the crypto functions. + +commit 214060ef20499332b0369030b664a8e239518661 +Author: Guus Sliepen +Date: Fri May 10 20:30:47 2013 +0200 + + Fix warnings for functions marked __attribute((warn_unused_result)). + +commit 7b949262c4c01fdeff30a612d43f4b64f1ad426f +Author: Guus Sliepen +Date: Fri May 10 20:23:01 2013 +0200 + + Add __attribute__((warn_unused_result)) to crypto functions. + +commit 45063953fd3f2c25c7f8cc65860b32a35b3ba80e +Author: Guus Sliepen +Date: Fri May 10 20:15:27 2013 +0200 + + Add more __attribute__((malloc)) where appropriate. + +commit 0acdce222ff21c84cafc82c137e3d1e107a66fd9 +Author: Guus Sliepen +Date: Wed May 1 17:45:38 2013 +0200 + + Add generic crypto headers. + + They should have been included in commit 9b9230a. + +commit 5b07039b0712bee0f19749d63116a10fb08a2d8b +Author: Guus Sliepen +Date: Wed May 1 17:31:33 2013 +0200 + + Rename xmalloc_and_zero() to xzalloc(). + + The former name is more or less only used by tinc, the latter is used by other + projects as well, and shorter as well. + +commit 9b9230a0a79c670b86f54fadd2807b864ff9d91f +Author: Guus Sliepen +Date: Wed May 1 17:17:22 2013 +0200 + + Use conditional compilation for cryptographic functions. + + This gets rid of the rest of the symbolic links. However, as a consequence, the + crypto header files have now moved to src/, and can no longer contain + library-specific declarations. Therefore, cipher_t, digest_t, ecdh_t, ecdsa_t + and rsa_t are now all opaque types, and only pointers to those types can be + used. + +commit e70b5b5bd77bb66e8dd324c17d86d9bff151aa82 +Author: Guus Sliepen +Date: Wed May 1 12:20:06 2013 +0200 + + Use conditional compilation for device.c. + + This requires the automake option "subdir-objects" to be enabled, and it + becomes more critical to specify the exact path to local header files. + +commit 9f8020a09ce08210a10a0c65cefd83d2646395ab +Author: Guus Sliepen +Date: Wed May 1 11:46:40 2013 +0200 + + Modernize the configure script a bit. + +commit 43c72093ade72f14cb2fc78bef55dade8cd38df7 +Author: Guus Sliepen +Date: Sun Apr 28 19:33:04 2013 +0200 + + Don't try to create tinc.conf when using set or add commands. + + It is almost certainly an error. If one really wants to create a new tinc.conf + file, one should use the init command. + +commit 8e732fcbbb5ac627ea302bf5c0ea17ec9b3cea7c +Author: Guus Sliepen +Date: Mon Apr 22 15:54:05 2013 +0200 + + Releasing 1.1pre7. + +commit 258bf7ea0fe69bae395a084843ba59b9770199f1 +Author: Guus Sliepen +Date: Fri Apr 12 17:15:05 2013 +0200 + + Drop packets forwarded via TCP if they are too big (CVE-2013-1428). + + Normally all requests sent via the meta connections are checked so that they + cannot be larger than the input buffer. However, when packets are forwarded via + meta connections, they are copied into a packet buffer without checking whether + it fits into it. Since the packet buffer is allocated on the stack, this in + effect allows an authenticated remote node to cause a stack overflow. + + This issue was found by Martin Schobert. + +commit 9e2ae03d1dc3b0d9a32a748320b9ed1565fa1374 +Author: Guus Sliepen +Date: Tue Mar 12 11:28:40 2013 +0100 + + Fix completion of add/del/get/set commands. + +commit f8f250ca1289990cb1fe69dfa252f0796aa38255 +Author: Guus Sliepen +Date: Tue Mar 12 10:49:45 2013 +0100 + + Describe the SPTPS protocol in the manual. + + Also mention that Cipher, Digest and MACLength have no influence on the SPTPS protocol, + since that uses a fixed ciphersuite. + +commit 40666a5f5b85aa0151c3ba60950267f3c2a3a6bc +Author: Guus Sliepen +Date: Fri Mar 8 16:26:21 2013 +0100 + + Remove references to the config keyword. + +commit 23a634becf09ac84c71250474fcb96e23b0ebdf1 +Author: Guus Sliepen +Date: Fri Mar 8 16:22:56 2013 +0100 + + Rename tincctl to tinc. + +commit 3793cf10da488b9f4f7a1ac71f60bc270bdf31c6 +Author: Guus Sliepen +Date: Fri Mar 8 14:12:48 2013 +0100 + + Include README.android in the tarballs. + +commit 4c30004cb6dc23616d7295b0ce631f066e7f1f82 +Author: Guus Sliepen +Date: Fri Mar 8 14:11:15 2013 +0100 + + Avoid calling time(NULL). + + In most cases we can use the cached time. + +commit af77e5d475d4d4ab7ad036e926a05f4f3b5c6589 +Author: Guus Sliepen +Date: Fri Mar 8 11:40:40 2013 +0100 + + Allow changing configuration with tincctl without the "config" keyword. + + This saves typing some characters, and forces one to be more explicit about the + desired command (get, set). + +commit 1d226977a43cc6c3e4ff32e1a41a06dde08356e0 +Author: Guus Sliepen +Date: Fri Mar 8 11:24:37 2013 +0100 + + Better default output file for generated public keys. + +commit f9ab8e266b93aa3be772374ef4a8fdb06e376568 +Author: Guus Sliepen +Date: Fri Mar 1 17:15:26 2013 +0100 + + Flush output buffers in the tap reader thread on Windows. + + This is basically a port of commit 50fcfea1 to 1.1. + +commit 4d05e695ab68a16cc5ed853b50482c443c6e12a9 +Author: Guus Sliepen +Date: Fri Feb 22 15:37:48 2013 +0100 + + Use UDP when using sptps_test in datagram mode. + +commit a93c0139c5734f89180483b5fe160b334f7ece4b +Author: Guus Sliepen +Date: Wed Feb 20 15:35:19 2013 +0100 + + Releasing 1.1pre6. + +commit d298ebe91c9209d139f38b6de2e42bf7c5bb5899 +Author: Guus Sliepen +Date: Wed Feb 20 15:35:08 2013 +0100 + + Fix compiler warnings on some BSD variants. + +commit 3847b78ba5900fe4311e9ef62474e32e1a6750e5 +Author: Guus Sliepen +Date: Wed Feb 20 14:39:24 2013 +0100 + + Fix compiler warnings on Windows. + +commit 1bb969c9306812d0d5c954fe8db32ed1a248bf20 +Author: Guus Sliepen +Date: Wed Feb 20 13:59:50 2013 +0100 + + Fix a tiny memory leak. + + Found by cppcheck. + +commit d21f63d5b39280b653ca72a272f3a70c7c3f03be +Author: Guus Sliepen +Date: Fri Feb 8 16:44:50 2013 +0100 + + Don't expect a response from tincd after sending REQ_STOP. + +commit 26eca516508829c3f9d8f2549335f613b569e8f5 +Author: Guus Sliepen +Date: Thu Feb 7 15:27:16 2013 +0100 + + Let the GUI use UNIX sockets if available. + +commit a8b52becbbd86a52dc50a6a1b725a80737f2c760 +Author: Guus Sliepen +Date: Thu Feb 7 15:26:56 2013 +0100 + + Derive UNIX socket filename from PID filename. + +commit 079dcd01794187d2857e1233f6c9930310812593 +Author: Guus Sliepen +Date: Thu Feb 7 14:22:28 2013 +0100 + + Don't send proxy requests for incoming connections. + +commit ee63f2a32be398c31301e9ce9154511b24089d8d +Author: Guus Sliepen +Date: Wed Feb 6 15:24:02 2013 +0100 + + Fix segmentation fault when trying to connect via a SOCKS5 proxy. + +commit 053af97c9e729ab485609e4202f5195fdc8aeeb5 +Author: Guus Sliepen +Date: Wed Feb 6 15:12:53 2013 +0100 + + Check for writability when waiting for a socket to finish connecting. + + We were checking only for readability, which is not a problem for normal + connections, since the server side of a connection will always send an ID + request. But when using a proxy, the proxy server doesn't send anything before + the client, so tinc would not see that its connection to the proxy had already + been established. + +commit 1135669b3c6820f5473ea451a58865f552ba768f +Author: Guus Sliepen +Date: Wed Feb 6 11:30:35 2013 +0100 + + Fix tincd terminating immediately on Windows. + +commit 9c878bf56f81049397a35d3a41aa69749c697fce +Author: Guus Sliepen +Date: Thu Jan 31 16:12:56 2013 +0100 + + Remove direct inclusion of OpenSSL headers in net_packet.c and tincd.c. + +commit 42b222ecb66b1957d7b439e5d8be8b287aef0054 +Author: Guus Sliepen +Date: Thu Jan 31 15:58:33 2013 +0100 + + Detect increases in PMTU. + + Tinc never restarts PMTU discovery unless a node becomes unreachable. However, + it can be that the PMTU was very low during the initial discovery, but has + increased later. To detect this, tinc now tries to send an extra packet every + PingInterval, with a size slightly higher than the currently known PMTU. If + this packet is succesfully received back, we partially restart PMTU discovery + to find out the new maximum. + + Conflicts: + src/net_packet.c + +commit 87416bcd8bd3e8816750150e2dbe90a970400a00 +Author: Guus Sliepen +Date: Mon Jan 21 16:12:18 2013 +0100 + + Get microsecond time resolution on Windows. + +commit 8aadbd4b37cddaf021949e93bceab98146f4c499 +Author: Guus Sliepen +Date: Mon Jan 21 13:59:52 2013 +0100 + + Fix a typo. + +commit 3a039ece25198c87e67950f0c4687587bf268075 +Author: Guus Sliepen +Date: Mon Jan 21 13:47:46 2013 +0100 + + Fix datagram SPTPS. + + Commit dd07c9fc1f37bed8d1f67ffe7b203f61e7914edf broke the reception of datagram + SPTPS packets, by undoing the conversion of the sequence number to host byte + order before comparison. This caused error messages like "Packet is 16777215 + seqs in the future, dropped (1)". + +commit cc3c69c892b0dad9a6ece0a0f4ccd429a22fcbff +Author: Guus Sliepen +Date: Sun Jan 20 21:03:22 2013 +0100 + + Releasing 1.1pre5. + +commit 76dbcf89895e87144e1bcb3b5cb98ffce03c383b +Author: Guus Sliepen +Date: Sun Jan 20 21:02:58 2013 +0100 + + Fix tincctl init when /etc/tinc does not yet exist. + +commit aa465969918ce3f3332f5829dbc482fc3b732012 +Author: Guus Sliepen +Date: Sun Jan 20 20:19:08 2013 +0100 + + Remove possible definition of timersub(), which is also in dropin.h. + +commit 1be7dc759a64d436fd7586aad43b545f2dc665b5 +Author: Guus Sliepen +Date: Sun Jan 20 15:16:13 2013 +0100 + + Make sure PriorityInheritance also works in switch mode. + + Conflicts: + src/route.c + +commit 94587264bda45cce0295aaa37b59905d4b9843a8 +Author: Guus Sliepen +Date: Thu Jan 17 18:12:55 2013 +0100 + + Allow connections via UNIX sockets. + + This is mainly useful for control connections. The client must still present + the control cookie from the PID file. + +commit 2c1412306242d26f7803829873e582b50adde922 +Author: Guus Sliepen +Date: Thu Jan 17 16:39:41 2013 +0100 + + Fix compilation of UML and VDE device support. + +commit f5bb64b36ae0807cdd3f241f81a8e933065437f6 +Author: Guus Sliepen +Date: Thu Jan 17 16:39:02 2013 +0100 + + Move make_names() and related variables to its own source file. + +commit a9eba276a4ccec1c67611e8496ac0a30137b7493 +Author: Guus Sliepen +Date: Thu Jan 17 14:14:17 2013 +0100 + + Handle SIGINT gracefully. + +commit 1ddd6111a40733929089316838020f89176cbda2 +Author: Guus Sliepen +Date: Thu Jan 17 11:21:18 2013 +0100 + + Fix the minimum spanning tree algorithm. + + Tinc uses Kruskal's algorithm to calculate a MST. However, this was broken in + commit 6e80da3370249caa1082c23c3ef55f338d1e9e74. Revert back to the working + algorithm from tinc 1.0. + + Thanks to Cheng LI for spotting the problem. + +commit 61275547cdf950e1c4499f19044ff171a9a74af7 +Author: Guus Sliepen +Date: Wed Jan 16 16:31:56 2013 +0100 + + Estimate RTT, bandwidth and packet loss between nodes. + + Without adding any extra traffic, we can measure round trip times, estimate the + bandwidth and packet loss between nodes. The RTT and bandwidth can be measured + by timing the MTU probe packets. The RTT is the difference between the time a + burst of MTU probes was sent and when the first reply is received. The + bandwidth can be estimated by multiplying the size of the probe packets by the + time between succesive received probe replies of the same burst. The packet + loss can be estimated for incoming traffic by comparing how many packets have + actually been received to the increase in the sequence numbers. + + The estimates are not perfect. Especially bandwidth is difficult to measure, + the only accurate way is to continuously send as much data as possible, but + that is obviously not desirable. The packet loss rate is also almost always + a few percent when sending a lot of data over the VPN via TCP, since TCP + *needs* packet loss to work properly. + +commit eef25266cb862b5e2c24450d158d99e3cb43e511 +Author: Guus Sliepen +Date: Tue Jan 15 13:33:16 2013 +0100 + + Count the number of correctly received UDP packets. + + Keep track of the number of correct, non-replayed UDP packets that have been + received, regardless of their content. This can be compared to the sequence + number to determine the real packet loss. + +commit b50a92d0c3d26edfeb7c8d6c1b8c3adc28edd6fe +Author: Guus Sliepen +Date: Tue Jan 15 13:31:51 2013 +0100 + + Add the tincctl exchange and exchange-all commands. + + These are identical to an export/export-all followed by an import, and make + it simpler to exchange host config files with other nodes. + +commit dd07c9fc1f37bed8d1f67ffe7b203f61e7914edf +Author: Guus Sliepen +Date: Mon Jan 14 13:08:35 2013 +0100 + + Check HMAC before sequence number. + +commit 83a94ab08fb36b88a473a56b164a9795637fe798 +Author: Guus Sliepen +Date: Mon Jan 14 13:02:39 2013 +0100 + + Always complain if too many arguments are given for tincctl commands. + +commit 50e1790101efa1d695ce27498e7d7dede7ed3f9b +Author: Guus Sliepen +Date: Mon Jan 14 13:01:47 2013 +0100 + + Better error messages when using -L, -R or -U on platforms that do not support it. + +commit cad86108f3a47e9bba885ccd8decf20057f909f7 +Author: Guus Sliepen +Date: Mon Jan 14 12:59:17 2013 +0100 + + Don't complain about garbage if we skipped importing a host file. + +commit c90c431bc93c1478836149a8724fdc68d1ec455c +Author: Guus Sliepen +Date: Mon Jan 14 12:58:24 2013 +0100 + + Mention that the -L, -R and -U options are not supported on all platforms. + +commit 5b88f5ba74fa9aa2cad82576308847e08cea88b1 +Author: Guus Sliepen +Date: Mon Jan 14 12:57:33 2013 +0100 + + Note that tincctl import is only meant to work with data from tincctl export. + +commit bb228e2f058c1274dca29ba255714e6fa2be494f +Author: Guus Sliepen +Date: Mon Jan 14 12:56:54 2013 +0100 + + Note that node Names are case sensitive. + +commit 2c7ecdcd0c50d4d3da6ff0b8fc2ea39573338d7f +Author: Guus Sliepen +Date: Mon Jan 14 12:56:14 2013 +0100 + + Fix a typo. + +commit 17a0b3a8907d7e618eb94ee2792d10c7cb8d3f30 +Author: Guus Sliepen +Date: Sun Dec 16 15:36:06 2012 +0100 + + Fix support for tunemu on iOS devices. + + The actual code was fine but the #ifdefs tested for the wrong preprocessor + variable. + + Conflicts: + src/bsd/device.c + src/process.c + +commit c26581e29f1f8f23217da266b57082e81dfc8320 +Author: Guus Sliepen +Date: Fri Dec 7 15:49:21 2012 +0100 + + Fix infinite loop in timeout handling on Windows. + +commit 58026f72a17b316f1b9756400f0ee9e9f519f877 +Author: Guus Sliepen +Date: Thu Dec 6 16:57:57 2012 +0100 + + Fix display of cumulative packet counters. + +commit b300f99dfbda5fc57a5366cdcb2a347e38723417 +Author: Guus Sliepen +Date: Thu Dec 6 16:55:28 2012 +0100 + + Clarify the description of IndirectData and Mode = router. + +commit 5b7f42bca4dbfee7a5fa2bc119f4739baaeb2f55 +Author: Guus Sliepen +Date: Wed Dec 5 22:32:10 2012 +0100 + + Releasing 1.1pre4. + +commit 4c16094e949e1f17461ac744118076a3cec437e8 +Author: Guus Sliepen +Date: Wed Dec 5 21:42:43 2012 +0100 + + Fix whitespace. + +commit 4f8abf1b29b117c5d593bfa7703966fd88e9eace +Author: Guus Sliepen +Date: Wed Dec 5 21:40:49 2012 +0100 + + Scale packet counters similar to byte counters. + +commit d5f0ff5df86d06825110527ddc252b1268e31479 +Author: Guus Sliepen +Date: Wed Dec 5 21:33:01 2012 +0100 + + Don't use nested functions. + + This allows tinc to be compiled with Clang. + +commit eb80105ea855f2c7ee0ea467574acf86cf455a77 +Author: Guus Sliepen +Date: Wed Dec 5 14:42:21 2012 +0100 + + Fix compiler warnings on OpenBSD. + +commit 5e3607b616538eac7bb70d78d4f20d847a1c3064 +Author: Guus Sliepen +Date: Mon Dec 3 13:09:40 2012 +0100 + + Remove GraphDumpFile from the manual and manpages. + + This option is not supported in tinc 1.1, "tincctl dump graph" can be used + instead. + +commit a717b9bcfbe811787fd6718fb3f8fb3f272bcfb9 +Author: Guus Sliepen +Date: Mon Dec 3 13:08:03 2012 +0100 + + Add option to dump only a list of reachable nodes. + +commit 75c619e372f02f8225d158fd514f01bd04857d3b +Author: Guus Sliepen +Date: Mon Dec 3 10:41:28 2012 +0100 + + More fixes for Windows. + + In particular, Windows does support many of the timer* macros, except timeradd + and timersub. + +commit d53384c2de6d2824b9adcec111301d86e6b25f8e +Author: Guus Sliepen +Date: Mon Dec 3 09:08:21 2012 +0100 + + Fix compiler error on Windows. + +commit 76816e119b7d38a14823d430aafeff362dfbfd41 +Author: Guus Sliepen +Date: Mon Dec 3 09:07:23 2012 +0100 + + Fix crash in timeout handling. + +commit d19b00606576d19ef206e363ac709daf3bd00f25 +Author: Guus Sliepen +Date: Mon Dec 3 09:02:08 2012 +0100 + + Set a node's pointers to zero before trying to insert it into a tree. + +commit d2b19be1a0dd3c4987aa926117f5bf281892c78b +Author: Guus Sliepen +Date: Thu Nov 29 14:35:08 2012 +0100 + + Fix use of unitialised values in hash tables. + + Not only was Valgrind unhappy about it, it could also result in cache misses. + +commit d9c70767aa6da8b62b4a1034d5f07892603beddd +Author: Guus Sliepen +Date: Thu Nov 29 14:32:12 2012 +0100 + + Fix check for expired events. + + This would trigger a infinite loop if a timeout expired and the next timeout + was not expired yet, but less than 1 second from being expired. + +commit 8825cddd0d8ed6dad00924ef382139da51ca3fc4 +Author: Guus Sliepen +Date: Thu Nov 29 12:37:04 2012 +0100 + + Allow multiple timeouts to expire at the exact same time. + +commit 6bc5d626a8726fc23365ee705761a3c666a08ad4 +Author: Guus Sliepen +Date: Thu Nov 29 12:28:23 2012 +0100 + + Drop libevent and use our own event handling again. + + There are several reasons for this: + + - MacOS/X doesn't support polling the tap device using kqueue, requiring a + workaround to fall back to select(). + - On Windows only sockets are properly handled, therefore tinc uses a second + thread that does a blocking ReadFile() on the TAP-Win32/64 device. However, + this does not mix well with libevent. + - Libevent, event just the core, is quite large, and although it is easy to get + and install on many platforms, it can be a burden. + - Libev is more lightweight and seems technically superior, but it doesn't + abstract away all the platform differences (for example, async events are not + supported on Windows). + +commit d30b9e1272fef18070d37d10b2b3e4bb2fc07f59 +Author: Guus Sliepen +Date: Mon Nov 19 14:20:50 2012 +0100 + + Ensure MTU probe replies are sent back the same way they came in. + + Also sprinkle some comments over mtu_probe_h(). + +commit 3c1b7047332f4b5e9d5ae7109e696b33712a5fb2 +Author: Guus Sliepen +Date: Mon Nov 19 13:50:17 2012 +0100 + + Improve UDP address selection. + + We don't need to search the whole edge tree, we can use the node's own edge + tree since each edge has a pointer to its reverse. Also, we do need to make + sure we try the reflexive address often. + +commit f57129ce3439f3826c12f15feb5df05e5ad8cab9 +Author: Guus Sliepen +Date: Sat Nov 17 22:48:06 2012 +0100 + + Try all known addresses of node during PMTU discovery, now also for SPTPS. + +commit 30404650b28bf72d0b05b55393f2dd492434f9f3 +Author: Guus Sliepen +Date: Sat Nov 17 22:14:52 2012 +0100 + + Choose a suitable socket when updating a node's UDP address. + +commit 8f9ee895224b39347783f3119343efc3bdaa3511 +Author: Guus Sliepen +Date: Thu Nov 15 11:24:18 2012 +0100 + + Also don't use poll() on MacOS/X. + +commit 8a77df9e28114cbfd83351070fdb266cf31fc310 +Author: Guus Sliepen +Date: Thu Nov 15 11:13:40 2012 +0100 + + Disable support for kqueue on MacOS/X. + + Apparently MacOS/X doesn't support kqueue events on character devices. + +commit 818c92e6583006bf2e38f1027044925df6cf0ca0 +Author: Guus Sliepen +Date: Wed Nov 14 10:44:35 2012 +0100 + + Remove text saying you must have one of PrivateKey or PrivateKeyFile in tinc.conf. + +commit e8bf81794f412b27261be0f2aa4eb287352041af +Author: Guus Sliepen +Date: Tue Nov 13 15:05:41 2012 +0100 + + Send broadcast packets using a random socket, and properly support IPv6. + + Before it would always use the first socket, and always send an IPv4 broadcast packet. That + works fine in a lot of situations, but it is better to try all sockets, and to send IPv6 packets + on IPv6 sockets. This is especially important for users that are on IPv6-only networks or that + have multiple physical network interfaces, although in the latter case it probably requires + them to use the ListenAddress variable to create a separate socket for each interface. + +commit 0870c7c32cf8a24f234fc066df867747ddb1ddc7 +Author: Guus Sliepen +Date: Tue Nov 13 15:01:43 2012 +0100 + + Don't take the address of a variable whose scope is about to disappear. + +commit bb3d7f3b31d4a429d1c31c6621d82f34dd552482 +Author: Guus Sliepen +Date: Sun Nov 11 19:01:28 2012 +0100 + + Fix configure script help text for --enable options. + +commit 5bfbb8f6c58307a8109f556caa30be122cc4d39f +Author: Guus Sliepen +Date: Sun Nov 11 19:01:02 2012 +0100 + + Fix index entry for section about readline library. + +commit 5766518589a5e6cc43ba77a4049059ead05fb300 +Author: Guus Sliepen +Date: Sun Nov 11 18:53:23 2012 +0100 + + Mention in the manual that support for LZO and zlib can be disabled. + +commit 6ec4596557d658f6c15c2cb9a96152c8c476118a +Author: Guus Sliepen +Date: Sun Nov 11 18:45:40 2012 +0100 + + Mention libcurses and libreadline in the manual. + +commit 0ee139e91431527015b7132e4c36f8d4ec09f66b +Author: Guus Sliepen +Date: Sat Nov 10 23:45:22 2012 +0100 + + Make sure PMTU discovery works in switch mode with VLAN tags. + + Before, when tinc saw a packet larger than the PMTU with a VLAN tag, it would + not know what to do with it, and would just forward it via TCP. Now, tinc + handles 802.1q packets correctly, as long as there is only one tag. + +commit ade4fccad6857f3d6d548e52bc94ab23751e4fef +Author: Guus Sliepen +Date: Sat Nov 10 23:13:05 2012 +0100 + + Using alloca() for a constant sized buffer is very silly. + + Cppcheck said using alloca() in the 21st century is silly anyway. + +commit b355476e917f377abb6434657933fcf4ffe6870a +Author: Guus Sliepen +Date: Sat Nov 10 23:09:31 2012 +0100 + + Fix potential buffer overflow reading the PID file. + + Found by cppcheck. + +commit edc08b73a9e353bde6db4c73866a6a730a1a7cb4 +Author: Guus Sliepen +Date: Sun Oct 21 17:45:16 2012 +0200 + + Slightly randomize all timeouts. + +commit 717ea66d7ba0c23f27d86b3d5c6992b751135455 +Author: Guus Sliepen +Date: Sun Oct 21 17:35:13 2012 +0200 + + Add the AutoConnect option. + + When set to a non-zero value, tinc will try to maintain exactly that number of + meta connections to other nodes. If there are not enough connections, it will + periodically try to set up an outgoing connection to a random node. If there + are too many connections, it will periodically try to remove an outgoing + connection. + +commit 1f8b70efa0dedbd3642e0ee82a640d125664af34 +Author: Guus Sliepen +Date: Sun Oct 21 17:34:53 2012 +0200 + + Keep track of the number of nodes in a tree. + +commit 0006c754f2e61e108aa2dd5a6ddd2e9b50d51bd6 +Author: Guus Sliepen +Date: Wed Oct 17 13:51:02 2012 +0200 + + Fix warnings from groff. + +commit 0db9e471ea53b48687ea247c855cd95ec453530c +Author: Guus Sliepen +Date: Sun Oct 14 19:22:30 2012 +0200 + + Releasing 1.1pre3. + +commit 3254e75afe0ff28fed68d8682f61c184f442161d +Author: Guus Sliepen +Date: Sun Oct 14 19:21:13 2012 +0200 + + Fix a few compiler errors/warnings. + +commit 70a1a5594af5d4e6a364186b42ba4e34c676009b +Author: Guus Sliepen +Date: Sun Oct 14 17:42:49 2012 +0200 + + Update copyright notices. + +commit 4200a378c4fedf64e89b9f8481d7cd09dac14965 +Author: Guus Sliepen +Date: Sun Oct 14 16:39:16 2012 +0200 + + Fix compile error on Windows. + +commit 368727c3dac4a1f8343e2e0eccf5bc62d9b197e2 +Author: Guus Sliepen +Date: Sun Oct 14 16:07:35 2012 +0200 + + tincctl: add node colors and edge weight to graph dump. + +commit 40ed0c07dd3d4667054b0f5952b89ee39686493b +Author: Guus Sliepen +Date: Sun Oct 14 15:37:24 2012 +0200 + + Log more messages using logger(). + +commit b234304b6628aeddce63d7f751da97c3344bbb78 +Author: Guus Sliepen +Date: Sun Oct 14 14:48:35 2012 +0200 + + Make sure the ReplayWindow option works for SPTPS as well. + +commit ee1d655f2f1ede6da66b6268974d6f9585c616b3 +Author: Guus Sliepen +Date: Sun Oct 14 14:45:27 2012 +0200 + + Only log success of initial datagram SPTPS handshake. + +commit 44a24f63acc70d19904e5540986b8301b3c9b882 +Author: Guus Sliepen +Date: Sun Oct 14 14:33:54 2012 +0200 + + Fix handling of initial datagram SPTPS packet. + + Only the very first packet of an SPTPS session should be send with REQ_KEY, + this signals the peer to abort any previous session and start a new one as + well. + +commit ec1f7e525d046bcaeb8e7040b8cec9a34a568371 +Author: Sven-Haegar Koch +Date: Fri Oct 12 17:08:01 2012 +0200 + + sptps.c: Add missing newline to log message. + +commit 94ec8d34db0ddef14b5446975663e5ff37e27b45 +Author: Guus Sliepen +Date: Thu Oct 11 22:47:13 2012 +0200 + + Strip newline from incoming SPTPS requests. + + Most of the code doesn't care whether requests are terminated with a newline or + not, except that when requests are forwarded, it is assumed they do not have + one and a newline is added. When a node using SPTPS receives a request from + another SPTPS-using node, and forwards it to a non-SPTPS-using node, this will + result in two consecutive newlines, which the latter node will see as an empty, + and thus invalid, request. + +commit 45944e4514a7765f858fa33cc1d9719a603099e0 +Author: Guus Sliepen +Date: Thu Oct 11 22:21:30 2012 +0200 + + Clear status and options fields of unreachable nodes. + +commit d917c8cb6b69475d568ccbe82389b9f2b3eb5e80 +Author: Guus Sliepen +Date: Wed Oct 10 17:17:49 2012 +0200 + + Fix whitespace. + +commit 58f4b845b9a7d83739af77337f2ce263d8df7838 +Author: Guus Sliepen +Date: Wed Oct 10 14:46:22 2012 +0200 + + Try all known addresses of node during the PMTU discovery phase. + + This helps in situations where some nodes have IPv6 and others have not. + +commit 0ed0cc6f9c30537bd74222fd99a41726d488dd37 +Author: Guus Sliepen +Date: Tue Oct 9 17:49:09 2012 +0200 + + Fix hash functions for keys whose size is not divisible by 4. + +commit d1ec010660905ae0b99d783737350ccc08b37b16 +Author: Guus Sliepen +Date: Tue Oct 9 16:27:28 2012 +0200 + + Fix memory leaks found by valgrind. + +commit 72642b40b3ad476101622da202b6f977a32b472f +Author: Guus Sliepen +Date: Tue Oct 9 15:52:58 2012 +0200 + + Clear Ethernet header when reading packets from a tun device. + + This fixes a warning from valgrind about uninitialized bytes, which were being + sent to other nodes. + +commit b346338f9c2de6f71d87cb4ad8e61b0af0052688 +Author: Guus Sliepen +Date: Tue Oct 9 13:28:09 2012 +0200 + + Remove unused variables, fix some #includes. + +commit f62b4a91344bd0de09e7fb4e4c8c1993ffc027c3 +Author: Guus Sliepen +Date: Tue Oct 9 13:23:12 2012 +0200 + + Fix deleting connections from the connection list. + +commit 0b8b23e0dd7219344543f135ca0aeba8a4a42d48 +Author: Guus Sliepen +Date: Mon Oct 8 00:35:38 2012 +0200 + + C99 extravaganza. + +commit ff306f0cdaedb50de1472e7c1fb55de922a6ca60 +Author: Guus Sliepen +Date: Sun Oct 7 21:59:53 2012 +0200 + + Replace the connection_tree with a connection_list. + + The tree functions were never used on the connection_tree, a list is more appropriate. + Also be more paranoid about connections disappearing while traversing the list. + +commit ce059e36fdb3d3049c278e8b2f36b03c93778996 +Author: Guus Sliepen +Date: Sun Oct 7 21:02:40 2012 +0200 + + Refactor outgoing connection handling. + + Struct outgoing_ts and connection_ts were depending too much on each other, + causing lots of problems, especially the reuse of a connection_t. Now, whenever + a connection is closed it is immediately removed from the list of connections + and destroyed. + +commit d93a37928b75b17ac5e1eae5c2d62fd0760a6608 +Author: Guus Sliepen +Date: Sun Oct 7 17:53:23 2012 +0200 + + Fix warnings from cppcheck. + +commit 5d0812d49275ec8bda2b5b0ac813239045463777 +Author: Guus Sliepen +Date: Sun Oct 7 14:06:47 2012 +0200 + + Remove a debug message. + +commit c2a9ed9e98e3dc4218c74fff774ddfe654adfd72 +Author: Guus Sliepen +Date: Sun Oct 7 14:03:50 2012 +0200 + + Handle packets encrypted via SPTPS that need to be forwarded via TCP. + +commit bb6b97ce3493d49b79f1bd57fdac420c312ef8d6 +Author: Guus Sliepen +Date: Sun Oct 7 13:31:19 2012 +0200 + + Make datagram SPTPS key exchange more robust. + + Similar to old style key exchange requests, keep track of whether a key + exchange is already in progress and how long it took. If no key is known yet + or if key exchange takes too long, (re)start a new key exchange. + +commit b99af2f813b897e1fd49c87a7cf44241cad3a017 +Author: Guus Sliepen +Date: Sun Oct 7 11:45:54 2012 +0200 + + Useful error messages when writing to a meta connection fails. + +commit e05371346548dee977d4ee45e12e3058e749afb6 +Author: Guus Sliepen +Date: Sat Oct 6 21:16:17 2012 +0200 + + When terminating, keep control connections open until the end. + + This ensures all device files and listening sockets have been closed before + tincctl gets notified of tincd's termination. + +commit 86116bb022f0b885638ff9ba21b359fc9f55286a +Author: Guus Sliepen +Date: Sat Oct 6 21:15:19 2012 +0200 + + Clear connection options and status fields in free_connection_partially(). + + Most fields should be zero when reusing a connection. In particular, when an + outgoing connection to a node which is reachable on more than one address is + made, the second connection to that node will have status.encryptout set but + outctx will be NULL, causing a NULL pointer dereference when + EVP_EncryptUpdate() is called in send_meta() when it shouldn't. + +commit ef9358c0d616c5ff3391c8ec3da5d357286a4457 +Author: Guus Sliepen +Date: Sat Oct 6 17:45:03 2012 +0200 + + Improve starting/stopping tincd using tincctl. + + When starting tincd, tincctl now strips non-options from the command line, and + sets argv[0] to the name of the tincd command instead of copying its own + command name. + + When stopping a running tincd, tincctl now waits for it to terminate. + +commit 47f33e07ff90b557cfa96999e921d35ea537ca80 +Author: Guus Sliepen +Date: Sat Oct 6 16:53:43 2012 +0200 + + Fix off-by-one error. + + Apart from writing 1 byte beyond an array allocated on the stack, this slipped + an unitialized byte in the seed used for key generation. + +commit 20b441a6de743b2149df59cfb94a7663e1924fa3 +Author: Guus Sliepen +Date: Mon Oct 1 10:42:13 2012 +0200 + + Libreadline might depend on libcurses. + +commit 3887e6dcb54494ee11798e721e274e06b0a5621a +Author: Guus Sliepen +Date: Mon Oct 1 10:39:15 2012 +0200 + + Remove abort() call that accidentily sneaked into commit dd1b69e. + +commit 0b0949e5bb63f9545feb4714812e2aa2112fb092 +Author: Guus Sliepen +Date: Mon Oct 1 10:36:23 2012 +0200 + + Make sure sptps_test compiles without -flto. + +commit b381acd60dbadbb4bc679d35a7d86bf425f21f86 +Author: Guus Sliepen +Date: Sun Sep 30 23:12:43 2012 +0200 + + Remove unused function declaration. + +commit dd1b69e31f83e2cc200ecc10e6d927373823332b +Author: Guus Sliepen +Date: Sun Sep 30 22:43:48 2012 +0200 + + Fix not reading Port statement from host config file. + +commit 6dfdb323612184529b4b83c1be914dda8262de47 +Merge: 9e76c464 c4940a5c +Author: Guus Sliepen +Date: Sun Sep 30 15:00:47 2012 +0200 + + Merge branch 'master' into 1.1 + + Conflicts: + lib/utils.c + src/net_setup.c + src/process.c + src/protocol_auth.c + src/protocol_key.c + src/utils.h + +commit c4940a5c888d85b4c477b6face5e9a618e64718d +Author: Guus Sliepen +Date: Sun Sep 30 13:45:47 2012 +0200 + + Add strict checks to hex to binary conversions. + + The main goal is to catch misuse of the obsolete PrivateKey and PublicKey + statements. + +commit 3bd810ea79d6933839ddac4a2cf1445c51947d38 +Author: Guus Sliepen +Date: Sun Sep 30 13:45:39 2012 +0200 + + Attribution for Martin Schürrer. + +commit 5a161e86cf35351f5274d7a8e17fef4630b40686 +Author: Martin Schürrer +Date: Sun Sep 30 02:04:55 2012 +0200 + + Output details of encryption errors + +commit 9e76c464b26b066e1eb3aa5232e573792e28020d +Author: Guus Sliepen +Date: Fri Sep 28 17:51:48 2012 +0200 + + Remove some debugging messages. + +commit e971130b601064090815c31c90b876e3d0d1d5b1 +Author: Guus Sliepen +Date: Fri Sep 28 17:36:25 2012 +0200 + + Make tincctl robust against dropped control connections. + +commit c5325ffdd1c6749beaf842c272eb28ecd5a070b6 +Author: Guus Sliepen +Date: Fri Sep 28 17:05:01 2012 +0200 + + Correctly add/remove outgoing connections when reloading configuration. + +commit f417271ea1447589ea05901f54fbb0377e7afaf9 +Author: Guus Sliepen +Date: Fri Sep 28 17:03:14 2012 +0200 + + Fix column sorting, make all lists sortable. + +commit aee86011ff2d389832fc9a23081ea23ab8484607 +Author: Guus Sliepen +Date: Thu Sep 27 22:12:15 2012 +0200 + + Let the GUI handle the new dump format. + +commit fac5593f44e47f3bd4f4b425ada38ab49fbe3b42 +Author: Guus Sliepen +Date: Thu Sep 27 17:19:02 2012 +0200 + + Fix links in documenation. + +commit 2e09986a1fd6dc5b6313f10e5d86aaaf4a531235 +Author: Guus Sliepen +Date: Thu Sep 27 17:18:49 2012 +0200 + + Fix links in documentation. + +commit f70cbc9d3ee3a88cf956592007e57f7a1dde2c17 +Author: Guus Sliepen +Date: Thu Sep 27 15:45:02 2012 +0200 + + Comment out old public/private keys when generating new ones. + +commit 38dbc63f118dbfdb955b56740b8c20a9379fb3ba +Author: Guus Sliepen +Date: Wed Sep 26 23:56:21 2012 +0200 + + Update documentation of the "dump graph" command. + +commit 1f312137d5ab12a2d996d5f7972f169aeb852040 +Author: Guus Sliepen +Date: Wed Sep 26 23:52:36 2012 +0200 + + Allow dumping either directed or undirected graphs. + + Internally, tinc maintains a directed graph of the meta connections between + nodes. However, this causes graphviz to draw two lines between nodes, which is + not always desirable. The "dump graph" command now defaults to dumping an + undirected graph, the "dump digraph" command will dump a directed graph. + +commit d6388d782ede1bbe49a5c2643362e2e0f383fa89 +Author: Guus Sliepen +Date: Wed Sep 26 23:18:32 2012 +0200 + + Let tincctl parse and format dumps. + + At the moment it just reproduces the old format. + +commit 9ade39b7d5564fb6f5a41946c9a23cfa7851a19f +Author: Guus Sliepen +Date: Wed Sep 26 22:20:43 2012 +0200 + + Keep last known address and time since reachability changed. + + This allows tincctl info to show since when a node is online or offline. + +commit 1e5deec973cd366b9d9cec6c1314a97e7051ce0f +Author: Guus Sliepen +Date: Tue Sep 25 22:28:08 2012 +0200 + + Remove remnants of Ethertap and old TUNSETIFF ioctl(). + +commit 125dd0dbcf4f46033ead3486044eb00b413fe537 +Author: Guus Sliepen +Date: Tue Sep 25 22:12:36 2012 +0200 + + Fix typo in manpage. + +commit 72f08932cf6f1ac0cfb837d377b423207e8c671a +Author: Guus Sliepen +Date: Mon Sep 24 14:56:00 2012 +0200 + + Don't ignore Makefile.am. + +commit 66e702d90d83977dc089736d7e4146330bc5df28 +Author: Guus Sliepen +Date: Mon Sep 24 14:02:07 2012 +0200 + + Attribution for Vil Brekin and some code style cleanups. + +commit f421a640777bd9484c59fa6feacadcf3e05d4b44 +Author: Vilbrekin +Date: Sat Aug 25 20:32:38 2012 +0200 + + Android cross-compilation instructions. + +commit afe4bf62eccab76c75e5a661fb2c16f1391a8417 +Author: Vilbrekin +Date: Sat Aug 25 20:01:11 2012 +0200 + + Use __ANDROID__ define rather than dirty hard-code to allow android NDK cross-compilation. + +commit c6720f1a608d19c722d8601fab1048773dbad59b +Author: Vilbrekin +Date: Sat Aug 25 19:59:26 2012 +0200 + + Add basic .gitignore file, cleaning (most) files generated by autotools. + +commit f2570c1b7f5813e087c867cf002f36f0c09b5cfa +Author: Vilbrekin +Date: Sat Aug 25 19:14:00 2012 +0200 + + Replace hard-code with new ScriptsInterpreter configuration property. + + This new setting allows choosing a custom script interpreter used for the various tinc callbacks. + If none is specified, the script itself is called as executable (as before). + This is particularly useful when storing tinc configuration and script on a mount point with no-exec attribute. + +commit 8a6f278fd2606c0a8f133f05df83b2649eacf6c3 +Author: Vilbrekin +Date: Wed Aug 22 10:46:24 2012 +0200 + + Basic patch for android cross-compilation. + + Commented non-existing functions in android NDK. + Prefix scripts execution with shell binary to allow execution on no-exec mount points. + Everyything is currently hard coded, while it should use pre-compiler variables... + +commit 2dc8deb1047a076d1c040f47bedf36ad4b41b17c +Author: Guus Sliepen +Date: Thu Sep 13 21:35:29 2012 +0200 + + Ensure sptps_test compiles with -flto. + +commit 90f1cba1fd9e748ec4b8274511d5a36ec1a24d9d +Author: Guus Sliepen +Date: Wed Sep 5 13:05:48 2012 +0200 + + Replace node_udp_tree with a hash table. + +commit 4c05afd19acada4781e1b8865cf702b197882e5d +Author: Guus Sliepen +Date: Wed Sep 5 12:45:36 2012 +0200 + + Use hash tables to lookup owners of addresses. + +commit 6b6a025488f289f749498a7e6cc1994be19f53e8 +Author: Guus Sliepen +Date: Wed Sep 5 12:44:41 2012 +0200 + + Add a simple hash table implementation. + +commit e9de08be0dab58a48f9a8ce3d250516cf05d6b8e +Author: Guus Sliepen +Date: Tue Sep 4 14:21:50 2012 +0200 + + Remove newlines at end of log messages. + +commit 05dac63dbc03dc5a64a7f4b50e24eb3766135916 +Author: Guus Sliepen +Date: Tue Sep 4 14:16:05 2012 +0200 + + Remove some debug messages. + +commit 742f7bb04e72d93f2c4a858534144a599b3fc14d +Author: Guus Sliepen +Date: Thu Aug 30 14:21:23 2012 +0200 + + Properly handle SPTPS packets with stripped Ethernet headers. + +commit d74b81b61e87c66d364a8590a48d87773ad2652c +Author: Guus Sliepen +Date: Thu Aug 30 14:00:34 2012 +0200 + + Fix node name check for "connect" and "disconnect" commands. + +commit 5567c0d4107e6ff6f4639d8664651841bd59ddad +Author: Guus Sliepen +Date: Sun Aug 5 17:25:31 2012 +0200 + + Quit when "exit" or "quit" commands are used in tincctl's shell. + +commit d18519ae21345fea68dd7f0f5525adba3a7639a9 +Author: Guus Sliepen +Date: Sun Aug 5 17:03:57 2012 +0200 + + Fix segfault when using tincctl's shell without readline. + +commit b332bd964663b7109a5fc4be596d36fbf1dbaa47 +Author: Guus Sliepen +Date: Sun Aug 5 13:50:51 2012 +0200 + + Add bash completion script. + +commit e29e0fee8812851473bcf24324a15cbf3cc854a0 +Author: Guus Sliepen +Date: Fri Aug 3 14:17:02 2012 +0200 + + Make sure the top command can be used more than once in tincctl's shell. + +commit a57db1dfe0736fd902a45ed5f695630faf3f0e1e +Author: Guus Sliepen +Date: Fri Aug 3 14:15:50 2012 +0200 + + Fork when using the "start" command in tincctl. + + This allows the command to be given in its shell without immediatly exiting tincctl. + +commit 36c6afede36b6956bd86df824f5616c1afee35ed +Author: Guus Sliepen +Date: Fri Aug 3 13:23:07 2012 +0200 + + Add readline completion for tincctl config and tincctl info. + +commit 8af2f3f5a4061a8dbfd4f7d259e0038df06a373e +Author: Guus Sliepen +Date: Thu Aug 2 17:44:59 2012 +0200 + + Optionally compress and/or strip Ethernet header from SPTPS packets. + +commit 73348be58ecb9c40cf435122a00e72ac4d1a4c9b +Author: Guus Sliepen +Date: Thu Aug 2 17:24:42 2012 +0200 + + Have tincctl act as a shell when no command is given. + + By default it uses readline to read commands. If the input and output are not a + tty, no prompt is shown. + +commit 91937812bdfe74699e4f7cdf86265d07423acbba +Author: Guus Sliepen +Date: Thu Aug 2 17:23:51 2012 +0200 + + Clear struct sptps before reusing it. + +commit 6bcd03c2027636f82ab7228566717d112df7bc6d +Author: Guus Sliepen +Date: Wed Aug 1 22:22:52 2012 +0200 + + Update the documentation to encourage using "tincctl init" and "tincctl config". + +commit 6396f42d74f22ab5f8e736dc5cb04c57917f9319 +Author: Guus Sliepen +Date: Wed Aug 1 16:51:59 2012 +0200 + + Stricter checks for netname and node names. + + - Node names should not be empty. + - Net names should not contain slashes or start with a dot, because they are + used in pathnames. + +commit 61006ced88e1bf62e8883216cabc636f2d4cb12a +Author: Guus Sliepen +Date: Wed Aug 1 16:13:23 2012 +0200 + + Add missing configuration variables. + +commit b0f3a76e9bf8ceeab75c1e6f4dce6763aecddc5e +Author: Guus Sliepen +Date: Wed Aug 1 15:50:45 2012 +0200 + + Add the ability to query configuration variables to tincctl. + +commit a9caa2a6ea3aa553c9d2140ad4f5b34b7ab7297b +Author: Guus Sliepen +Date: Wed Aug 1 15:15:37 2012 +0200 + + tincctl restart should work even if no tincd is running. + +commit 07980b056c5371f8b6fdd50172f501be07155bdf +Author: Guus Sliepen +Date: Wed Aug 1 15:14:48 2012 +0200 + + Try sending SIGTERM if we cannot connect to a tincd but we know its PID. + +commit 7a71d48009e03ff1143a6e1084803f456a27c849 +Author: Guus Sliepen +Date: Tue Jul 31 21:43:49 2012 +0200 + + Use a status bit to track which nodes use SPTPS. + +commit 6bc8df3e010509f69af95d2cc14ec893def6f644 +Author: Guus Sliepen +Date: Tue Jul 31 20:39:15 2012 +0200 + + Add Brandon Black's replay window code to SPTPS. + +commit 5ede437307cc3bbb20431f4b82f4a2ef79c9b746 +Author: Guus Sliepen +Date: Tue Jul 31 20:36:35 2012 +0200 + + Handle SPTPS datagrams in try_mac(). + +commit aaff0ed08916f936b0a7b8a3d0607b8111b7a185 +Author: Guus Sliepen +Date: Tue Jul 31 20:29:13 2012 +0200 + + Remove unused #include. + +commit 153abaa4d940bf2bc9bd7275d5efe5c01c354190 +Author: Guus Sliepen +Date: Mon Jul 30 18:36:59 2012 +0200 + + Use datagram SPTPS for packet exchange between nodes. + + When two nodes which support SPTPS want to send packets to each other, they now + always use SPTPS. The node initiating the SPTPS session send the first SPTPS + packet via an extended REQ_KEY messages. All other handshake messages are sent + using ANS_KEY messages. This ensures that intermediate nodes using an older + version of tinc can still help with NAT traversal. After the authentication + phase is over, SPTPS packets are sent via UDP, or are encapsulated in extended + REQ_KEY messages instead of PACKET messages. + +commit 248d300f1be0d5f2aae39202041699ab2b46c56b +Merge: e1355e24 3391018e +Author: Guus Sliepen +Date: Fri Jul 27 22:48:24 2012 +0200 + + Merge branch 'master' into 1.1 + +commit 3391018efbd41858d42ccae6ae919749ba94c8db +Author: Guus Sliepen +Date: Fri Jul 27 22:43:01 2012 +0200 + + Also clarify hostnames=[yes|no] in tinc.conf(5). + +commit e895b358db8863d19dfa3d77c861ae19b76bc750 +Author: Mesar Hameed +Date: Tue Jul 24 07:18:50 2012 +0100 + + Minor clarification, tinc.conf hostnames=[yes|no] variable only resolves names for logging purposes. + +commit e1355e24eb7fe36bdb5dd7c818815fa266046a51 +Author: Guus Sliepen +Date: Sun Jul 22 13:05:56 2012 +0200 + + Remove unused po/ directory. + +commit 6c9b33c8b67374d38525b88f292840034c559a45 +Author: Guus Sliepen +Date: Sun Jul 22 12:55:04 2012 +0200 + + Have tinc-gui use same way of locating pidfile as tincd and tincctl. + +commit 2b97a7d7cf6ca7f4d84d3df754062a55bdf55305 +Author: Guus Sliepen +Date: Sun Jul 22 12:52:31 2012 +0200 + + tincctl init now also creates a template tinc-up script. + +commit eb430005c74b6b5f717e7e264afa3bd35284740d +Author: Guus Sliepen +Date: Sat Jul 21 17:10:10 2012 +0200 + + Fix exit code when installing tincd as a service on Windows. + +commit e5e96882c3825cee81ff163490b2f39fad3192b8 +Author: Guus Sliepen +Date: Sat Jul 21 16:33:09 2012 +0200 + + Windows doesn't like quotes around "edit" when calling it through system(). + + Even though that works fine on the command line. + +commit 18237e1f2d9dd5eef4a4e0d746d016bf94a42ad4 +Author: Guus Sliepen +Date: Sat Jul 21 16:26:55 2012 +0200 + + Use backslashes on Windows. + + Although Windows itself supports the forward slash, some programs may not. + +commit 09a8ff649cc7aa51d291c89e1556526a6265cc81 +Author: Guus Sliepen +Date: Sat Jul 21 15:58:16 2012 +0200 + + Don't try to mkdir(CONFDIR) on Windows when there is a registry key for tinc. + +commit ed8ce60845dc0568840c64c692838136f342fa54 +Author: Guus Sliepen +Date: Sat Jul 21 15:51:15 2012 +0200 + + Fix crash when no netname is specified. + +commit 7303b512b0e4f0d9cbc3236e846b2618f527b830 +Author: Guus Sliepen +Date: Sat Jul 21 15:50:50 2012 +0200 + + Fix some compiler warnings. + +commit 33521eabd4501b4add35468618453ac4f76311f3 +Author: Guus Sliepen +Date: Sat Jul 21 15:15:04 2012 +0200 + + Have tincd and tincctl use the same method of determining netname. + +commit 1d322d2eda8223f21b0c00381af34b94054f251a +Author: Guus Sliepen +Date: Sat Jul 21 15:02:44 2012 +0200 + + Add a newline to a configuration file if it is missing. + +commit dea722c4aca9a8cfa463807d279aa10cc6a0fc64 +Author: Guus Sliepen +Date: Sat Jul 21 15:02:17 2012 +0200 + + Add some checks when changing configuration. + +commit cc0c35267f8fac4f82622ff73474ed1e2d3a1e36 +Author: Guus Sliepen +Date: Sat Jul 21 14:19:23 2012 +0200 + + Call event_init() after detaching. + + Otherwise, the call to daemon() could close filedescriptors in use by libevent + itself; for example if it uses kqueue or epoll instead of a select() or poll() + backend. + +commit 4e0fc52197546bbf8a0be7af946f4b569e13048c +Author: Guus Sliepen +Date: Sat Jul 21 13:53:22 2012 +0200 + + Fix various compiler warnings. + +commit b161088b35fad1d284855f6434a895a20e34a250 +Author: Guus Sliepen +Date: Sat Jul 21 13:38:14 2012 +0200 + + BSD make doesn't like $<. + +commit 98a72d686983178f71cd2bf336c1f3d5c647f1e7 +Author: Guus Sliepen +Date: Sat Jul 21 13:02:35 2012 +0200 + + Make sure sptps.h and info.h are in the tarball. + +commit 5eeed38b8eb15f4c0464675b7d8c7722bc8be168 +Author: Guus Sliepen +Date: Sat Jul 21 12:51:53 2012 +0200 + + Make sure tinc compiles on Windows. + +commit 1d4590ca5cae09ea3b7a7e80355639e20861d349 +Author: Guus Sliepen +Date: Fri Jul 20 20:35:07 2012 +0200 + + Prefer routes with lower weight as long as they do not increase the number of hops. + + This should improve traffic to nodes that are not directly reachable somewhat. + +commit 4c8ead98743254be97c830e942f0cc53539d780c +Author: Guus Sliepen +Date: Fri Jul 20 20:01:29 2012 +0200 + + Allow more configuration variables to be changed when reloading configuration. + + In particular, Subnets may be added or removed from the local node on the fly. + +commit c678e7c4fb52d93350eafaed0f666018ed469e10 +Author: Guus Sliepen +Date: Fri Jul 20 19:59:47 2012 +0200 + + Split setup_myself() into two functions, one for reloading configuration. + +commit 4591e96c76914795aaae317c067f16abc22fb2e0 +Author: Guus Sliepen +Date: Fri Jul 20 17:29:16 2012 +0200 + + Never remove items from cmdline_conf. + + We should treat cmdline_conf as const, so we can call read_config_options() + more than once with prefix = NULL. + +commit 68a20876d0c4a6c370064d78786dd9f2aa6273cb +Author: Guus Sliepen +Date: Fri Jul 20 01:02:51 2012 +0200 + + Use minor protocol version to determine whether to use ECDH key exchange between nodes. + +commit 76a3ada4eb4032172c3d780915a07680f9954d42 +Author: Guus Sliepen +Date: Tue Jul 17 18:05:55 2012 +0200 + + Put minor protocol version in connection options so other nodes can see it. + + This allows two nodes that do not have a meta-connection with each other see + which version they are. + +commit 68de7b481e54d6a7c573d9a2d61f76d4d3a6b2f9 +Author: Guus Sliepen +Date: Mon Jul 16 18:49:39 2012 +0200 + + When exporting configuration files, don't copy Name variables. + + These interfere with tincctl import. Besides, host configuration files should + not contain Name at all. + +commit c52c46f8717aac6904f32766d774fa3fdf9611d8 +Author: Guus Sliepen +Date: Mon Jul 16 16:48:24 2012 +0200 + + Add an easy way to export and import host configuration files. + +commit 6319dc9dde3b328ba800f25a6bb4cf303d27f664 +Author: Guus Sliepen +Date: Mon Jul 16 01:14:08 2012 +0200 + + Strip default subnet weight from output. + +commit 74646a4afa6557a0363cc85e0a95d578d4ab0ac2 +Author: Guus Sliepen +Date: Mon Jul 16 01:09:47 2012 +0200 + + Give an error message when tincctl info cannot parse the given subnet or address. + +commit 53735a9d964579829d089f4b7572aef50c4e1468 +Author: Guus Sliepen +Date: Mon Jul 16 01:05:25 2012 +0200 + + "tincctl info" gives more human readable information about nodes or subnets. + +commit 3c7003893fe2f82023d0d4f54b488bb7a16d0007 +Author: Guus Sliepen +Date: Mon Jul 16 00:52:50 2012 +0200 + + Move all functions related to subnet parsing to subnet_parse.c. + +commit e72e6febfeddbd4354560388c8e0e125a8017909 +Author: Guus Sliepen +Date: Sun Jul 15 22:53:03 2012 +0200 + + Fix tincctl dump. + +commit 9be8980a2bb6245da017270f85bd6da186fb433b +Author: Guus Sliepen +Date: Sun Jul 15 21:17:10 2012 +0200 + + Let tincctl ignore tincd options, so they will be passed on. + +commit 36dee4c539521578005eed5e58b4803b73f0c889 +Author: Guus Sliepen +Date: Sun Jul 15 21:15:35 2012 +0200 + + Fix tincctl start. + +commit 439069bda62b25baaabeb765ac0557efa57b6cfb +Author: Guus Sliepen +Date: Sun Jul 15 20:59:17 2012 +0200 + + Have tincctl notify a running tincd of configuration file changes. + +commit eb01fd96258e5f99be0e4930eac04e5487a108a0 +Author: Guus Sliepen +Date: Sun Jul 15 20:37:38 2012 +0200 + + Add an easy way to edit a configuration file. + +commit cedfeccb247abb00063316068d7d2ade880f9d09 +Author: Guus Sliepen +Date: Sun Jul 15 20:22:21 2012 +0200 + + Stricter checks for node names. + +commit 03f72c6173f27198e2e68227cb41e00f8ec4ddc9 +Author: Guus Sliepen +Date: Sun Jul 15 18:16:35 2012 +0200 + + Allow configuration variables to be added/removed using tincctl. + +commit dd102efd24d847c41890adfcc7ce6d9d2592dcdb +Author: Guus Sliepen +Date: Sun Jul 15 15:46:16 2012 +0200 + + Put every command in its own function. + +commit a444ec396456a25546a4ab3d185c7fb5e4bb7ae3 +Author: Guus Sliepen +Date: Sun Jul 15 14:49:36 2012 +0200 + + "tincctl init" creates initial directory structure, tinc.conf and keypairs. + +commit 268c8545aaf83b7433f43402f5c77e39e20006ef +Merge: bce17776 f13fd8c3 +Author: Guus Sliepen +Date: Sat Jul 14 15:13:21 2012 +0200 + + Merge branch 'master' into 1.1 + +commit f13fd8c35068cd1f776e33362dcac40be9499035 +Author: Guus Sliepen +Date: Thu Jul 12 11:32:08 2012 +0200 + + Update THANKS file. + +commit 2eb0043e1352944b1113c1f7e40f37dffac0021d +Author: Guus Sliepen +Date: Thu Jul 12 11:30:56 2012 +0200 + + Document how to load the tap driver on FreeBSD. + +commit ae8c0b65d8f97942d7eff5f96344f781b8dec35d +Author: Guus Sliepen +Date: Thu Jul 12 11:25:11 2012 +0200 + + Use /dev/tap0 by default on FreeBSD and NetBSD when using Mode = switch. + +commit bce177767d521b47efd458c5cd570959a98d940d +Author: Guus Sliepen +Date: Tue Jun 26 14:22:57 2012 +0200 + + Fix crash when handling the ALRM signal. + + In retry() the function do_outgoing_connection() is called, which can delete + items from the connection_tree, so when walking the tree we must first save the + pointer to the next item. + +commit 19be9cf7150858311f7898fa3fb525d692d02f64 +Merge: 62b61a1b 00e71ece +Author: Guus Sliepen +Date: Tue Jun 26 13:24:20 2012 +0200 + + Merge branch 'master' of git://tinc-vpn.org/tinc into 1.1 + + Conflicts: + NEWS + README + configure.in + lib/utils.c + src/linux/device.c + src/meta.c + src/net.h + src/net_setup.c + src/net_socket.c + src/protocol.c + src/protocol_auth.c + src/tincd.c + +commit 00e71ece25070dc919f9bc0696e4ff3a387360d0 +Author: Guus Sliepen +Date: Mon Jun 25 19:45:51 2012 +0200 + + Releasing 1.0.19. + +commit 236b0ba4ebba01e22e382e79897100338a039bbb +Author: Guus Sliepen +Date: Mon Jun 25 19:03:54 2012 +0200 + + Fix crash when using Broadcast = direct. + +commit 0a84f9cb8f52f2d2b4f03a5ad5ef9dfcd3509033 +Author: Guus Sliepen +Date: Mon Jun 25 19:01:51 2012 +0200 + + Fix compiler warnings. + +commit 62ee9b776d45af41c8b040ad86e50ba8f6f8e6c4 +Author: Guus Sliepen +Date: Mon Jun 25 15:01:42 2012 +0200 + + #include on Windows. + + MinGW complained about it not being included. + +commit c0af4c37d2046ffb3e07dd62f266a4fb99ea5614 +Author: Guus Sliepen +Date: Mon Jun 25 15:00:24 2012 +0200 + + Small fixes in proxy code. + +commit 62b61a1b7c2382b1bade142b3a41a9b27c1fd40d +Author: Guus Sliepen +Date: Sun May 13 22:16:42 2012 +0200 + + Don't forget to send a newline when forwarding requests. + +commit 42a8158b1dca6ee4ec1707176199cc36c26da7af +Author: Michael Tokarev +Date: Fri May 4 16:41:47 2012 +0400 + + add (errnum) in front of windows error messages + + On localized, non-English versions of windows, it is + common to have two active charsets -- for console applications + and for GUI applications, together with localized error messages + returned by windows. But two charsets are rarely compatible, + so sending the same byte sequence to console and to windows + event log makes one or another to be unreadable. So at least + include the error number, this way it will be possible to + lookup the actual error test using external ways. + + Signed-off-by: Michael Tokarev + +commit 58007d7efa3940c863c5a398f8b257a686ce37ba +Author: Guus Sliepen +Date: Tue May 8 16:44:15 2012 +0200 + + Always pass request strings to other functions as const char *. + +commit 291a59b5b732de084e392daea1433b1fdb9fbfd5 +Author: Sven-Haegar Koch +Date: Sun Apr 22 03:44:28 2012 +0200 + + free_connection_partially(): also reset remote protocol version infos + + The used remote protocol can change between two reconnects, aka if + the remote side has enabled/disabled for example their ExperimentalProtocols + setting. + +commit 32e5c5bb7c2c9127274247cb74cffa7345b04fad +Author: Sven-Haegar Koch +Date: Sun Apr 22 03:05:29 2012 +0200 + + Silence SPTPS log messages, reduce them from DEBUG_ALWAYS to DEBUG_META. + +commit c78bb143030162f0c820f08c87808e157c014a07 +Author: Sven-Haegar Koch +Date: Sun Apr 22 02:55:06 2012 +0200 + + terminate_connection(): delete non-outgoing (aka incoming) connections. + +commit 8b9e5af0d93069a81ce2ebed9899eedf3b7b184b +Author: Sven-Haegar Koch +Date: Sat Apr 21 03:44:24 2012 +0200 + + Label control connections for log output as "", not "". + +commit d3f4cf59ca917386e7c6358a98adbe3b8e9ce87a +Author: Sven-Haegar Koch +Date: Sat Apr 21 01:59:01 2012 +0200 + + free_connection_partially(): Avoid possible use-after-free for c->hischallenge + +commit 7a6ca7a993e5907497d97fef09e375698dde182f +Author: Sven-Haegar Koch +Date: Sat Apr 21 01:51:36 2012 +0200 + + terminate_connection(): only kill c->node->connection if it is pointing + to the same connection + +commit a96c4f016c9fff2392d85f762e16f5430c0b6463 +Author: Sven-Haegar Koch +Date: Fri Apr 20 00:24:38 2012 +0200 + + terminate_connection(): Avoid use-after-free and double-free for + already freed edge structure. + +commit 5c0dd104f94519c3cb50e9ca44227656c5adc7ae +Author: Guus Sliepen +Date: Thu Apr 19 15:56:08 2012 +0200 + + Document new proxy types. + +commit 5ae19cb0bb8dd6be1e9bcd560bb051f496a373ec +Author: Guus Sliepen +Date: Thu Apr 19 15:18:31 2012 +0200 + + Add support for proxying through an external command. + + Proxy type "exec" can be used to have an external script or binary set + up an outgoing connection. Standard input and output will be used to + exchange data with the external command. The variables REMOTEADDRESS and + REMOTEPORT are set to the intended destination address and port. + +commit fb5588856fa4dd6f140c72f7360302fe85b20c75 +Author: Guus Sliepen +Date: Thu Apr 19 14:10:54 2012 +0200 + + Add support for SOCKS 5 proxies. + + This only covers outgoing TCP connections, and supports only + username/password authentication or no authentication. + +commit b58d95eb29662bce4388f95dbc5762b9e2999806 +Author: Guus Sliepen +Date: Wed Apr 18 23:19:40 2012 +0200 + + Add basic support for SOCKS 4 and HTTP CONNECT proxies. + + When the Proxy option is used, outgoing connections will be made via the + specified proxy. There is no support for authentication methods or for having + the proxy forward incoming connections, and there is no attempt to proxy UDP. + +commit 84531fb6e621959e06519fdbb7f2a8f7578f66bd +Author: Guus Sliepen +Date: Mon Apr 16 01:57:25 2012 +0200 + + Allow broadcast packets to be sent directly instead of via the MST. + + When the "Broadcast = direct" option is used, broadcast packets are not sent + and forwarded via the Minimum Spanning Tree to all nodes, but are sent directly + to all nodes that can be reached in one hop. + + One use for this is to allow running ad-hoc routing protocols, such as OLSR, on + top of tinc. + +commit 9ebb34f907e8a15cb71dd20b111270d80bad1e96 +Author: Guus Sliepen +Date: Mon Apr 16 01:16:59 2012 +0200 + + Update README to reflect that only OpenSSL is currently supported. + +commit a851d8a9f6e3b69ab75695d84471ff4d525341b7 +Author: Guus Sliepen +Date: Mon Apr 16 01:14:59 2012 +0200 + + Add autoconf checks for OpenSSL's elliptic curve functions. + +commit f8e15dfe8d155b5bdb1e39bf6b9af486606145e8 +Author: Sven-Haegar Koch +Date: Sat Apr 14 02:28:43 2012 +0200 + + ecdh & ecdsa: avoid some possible memory leaks in error conditions. + +commit 8792b9a9f343e751dc3cfd789db9528da609ba9f +Author: Sven-Haegar Koch +Date: Sat Apr 14 02:02:11 2012 +0200 + + Remove confusing error message for failed reading in ECDSA keys. + + Most likeley the error is that there just is no valid key inside the used + host file, and in this case errno just contains a random value from the + last previously failed call. + +commit a5bb6d40fb517aa175510ec179091e4f9ffaf6f6 +Author: Sven-Haegar Koch +Date: Sat Apr 14 02:29:32 2012 +0200 + + sptps_stop(): clear pointers after free to avoid double free. + + sptps_stop() may get called twice on some failed connection setups. + +commit 535a55100bb77f107c85361e9f72a194e92bc8bc +Author: Guus Sliepen +Date: Thu Mar 29 16:45:25 2012 +0100 + + Allow environment variables to be used for Name. + + When the Name starts with a $, the rest will be interpreted as the name of an + environment variable containing the real Name. When Name is $HOST, but this + environment variable does not exist, gethostname() will be used to set the + Name. In both cases, illegal characters will be converted to underscores. + +commit 1d9dacb1f26971e19463b5501c2410c57f780ecb +Merge: 86c29903 89f4574e +Author: Guus Sliepen +Date: Mon Mar 26 19:06:39 2012 +0100 + + Merge branch 'master' of git://tinc-vpn.org/tinc into 1.1 + + Conflicts: + src/logger.c + src/net_setup.c + +commit 89f4574e0b1553c8e5dcbfc275e829a759b697f6 +Author: Guus Sliepen +Date: Mon Mar 26 14:46:09 2012 +0100 + + Add support for systemd style socket activation. + + If the LISTEN_FDS environment variable is set and tinc is run in the + foreground, tinc will use filedescriptors 3 to 3 + LISTEN_FDS for its listening + TCP sockets. For now, tinc will create matching listening UDP sockets itself. + + There is no dependency on systemd or on libsystemd-daemon. + +commit cc6aee784659bfbd21eb8d414e00a8f1a801cac4 +Author: Guus Sliepen +Date: Mon Mar 26 14:45:20 2012 +0100 + + Remove newline from log message. + +commit 16e6769feef21a5bf58f6022d990452987bb5efb +Author: Anthony G. Basile +Date: Mon Mar 26 06:29:40 2012 -0400 + + configure.in: fix AC_ARG_ENABLE and AC_ARG_WITH + + The current configure.in file does not correctly make use of these + macros. The resulting configure file will therefore enable an item + even if --disable-FEATURE is given. This patch restores the intended + behavior. + +commit 86c2990327fdf7ec1197aa73cb2b9a926a734db4 +Merge: d7bf63c6 b23681dd +Author: Guus Sliepen +Date: Sun Mar 25 23:35:31 2012 +0100 + + Merge branch 'master' of git://tinc-vpn.org/tinc into 1.1 + + Conflicts: + NEWS + README + configure.in + src/Makefile.am + src/conf.c + src/conf.h + src/connection.c + src/net.c + src/tincd.c + +commit b23681dddb8987571f04d46fc14f0ba012a7929c +Author: Guus Sliepen +Date: Sun Mar 25 22:54:36 2012 +0100 + + Support :: in IPv6 Subnets. + +commit 482c6119a7ae80f320e5b519ef2e785e04a77b8e +Author: Guus Sliepen +Date: Sun Mar 25 15:32:26 2012 +0100 + + Releasing 1.0.18. + +commit 64c657b32d1eb34eb669c6d5b0ec26c1a643b194 +Author: Guus Sliepen +Date: Sun Mar 25 15:30:58 2012 +0100 + + Mark DecrementTTL option experimental. + +commit f71ce341800739c7cdee01d7cf025e7492da22ac +Author: Guus Sliepen +Date: Sun Mar 25 15:17:50 2012 +0100 + + Fix return type of vde_recv() as well. + + In this case it is not really necessary as the conversion to int will already + take care of ensuring the return value is treated as signed. + +commit 6225b1884a25af4debc2d0821a4c377ddbaec696 +Author: Guus Sliepen +Date: Sun Mar 25 14:55:56 2012 +0100 + + Document OpenBSD "ifconfig link0" and Linux "ip tuntap" commands. + +commit 399835385380d485416d6d59a8f27ce71f1db644 +Author: Guus Sliepen +Date: Sun Mar 25 14:46:50 2012 +0100 + + Fix some more compiler warnings. + +commit cfe6558d4ba4f572311aeafd62737f6f2692ad86 +Author: Guus Sliepen +Date: Sun Mar 25 14:00:21 2012 +0100 + + Fix return value type of vde_send(). + + The libvdeplug_dyn.h header file incorrectly declares the return type of + vde_send() to size_t, while in reality it is ssize_t. + +commit 95968c67f9df9102ddbce5b7c8d34107989ad51a +Author: Guus Sliepen +Date: Sun Mar 25 13:58:14 2012 +0100 + + Fix compiler warnings. + +commit e2d1b0b899ef66cd7ff227549e58b96c292f784e +Author: Guus Sliepen +Date: Sun Mar 25 13:42:10 2012 +0100 + + Allow scoped addresses to be used for IPv6 multicast socket. + +commit 251204063255d95910f9a079015e2f9b428fd983 +Author: Guus Sliepen +Date: Sun Mar 25 13:40:55 2012 +0100 + + Add #ifdefs in case not all platforms support IPv4 and IPv6 multicast. + +commit b5e3bf1a85462f0c41638c11305d28f87af24395 +Author: Guus Sliepen +Date: Fri Mar 23 13:18:36 2012 +0100 + + Set default value of DecrementTTL to "no". + + Decrementing the TTL causes IPv6 to fail when Mode = switch, and there may be + other unforeseen side-effects. + +commit c373de2e9812700c0568640727ad917b6fc7d758 +Author: Guus Sliepen +Date: Wed Mar 21 17:00:53 2012 +0100 + + Add support for multicast communication with UML/QEMU/KVM. + + DeviceType = multicast allows one to specify a multicast address and port with + a Device statement. Tinc will then read/send packets to that multicast group + instead of to a tun/tap device. This allows interaction with UML, QEMU and KVM + instances that are listening on the same group. + +commit a7dbb50c23f447a23b543c92ec096ff178bc2de3 +Author: Guus Sliepen +Date: Wed Mar 21 13:20:15 2012 +0100 + + Allow a port to be specified in BindToAddress statements. + + This can be used to let tinc listen on multiple ports for incoming connections. + +commit 80e15d8b96e5313b33c91003b1f75d7f6db9924e +Author: Guus Sliepen +Date: Tue Mar 20 23:49:16 2012 +0100 + + Always try next Address when an outgoing connection fails to authenticate. + + When making outgoing connections, tinc goes through the list of Addresses and + tries all of them until one succeeds. However, before it would consider + establishing a TCP connection a success, even when the authentication failed. + This would be a problem if the first Address would point to a hostname and port + combination that belongs to the wrong tinc node, or perhaps even to a non-tinc + service, causing tinc to endlessly try this Address instead of moving to the + next one. + + Problem found by Delf Eldkraft. + +commit d7bf63c63ab397cf3e5ca4a065922364925788e7 +Author: Guus Sliepen +Date: Sun Mar 18 21:24:46 2012 +0100 + + Make sure the signature also covers the session label. + +commit 42a0b61076d5d0f6391f0dd5c2c400b8fb89c5c5 +Author: Guus Sliepen +Date: Sun Mar 18 20:38:48 2012 +0100 + + Start documenting the SPTPS protocol. + +commit d756bb92ed52d5b1ecdd42af32f11f733db64d91 +Author: Guus Sliepen +Date: Sun Mar 18 17:46:30 2012 +0100 + + Don't send an ACK message after the first key exchange in the SPTPS protocol. + +commit c970ecdd75d4e7b3203a788f28b6e40cd532759b +Author: Guus Sliepen +Date: Sun Mar 18 17:42:43 2012 +0100 + + Test SPTPS messages sent while key renegotation is in progress. + +commit 3a4fe104a06b73fd19c550546e7c65a59ff2afe3 +Author: Guus Sliepen +Date: Sun Mar 18 16:42:02 2012 +0100 + + Add datagram mode to the SPTPS protocol. + + * Everything is identical except the headers of the records. + * Instead of sending explicit message length and having an implicit sequence + number, datagram mode has an implicit message length and an explicit sequence + number. + * The sequence number is used to set the most significant bytes of the counter. + +commit 03e06fd43aff73b4a5c9d367968a1279371ae252 +Author: Guus Sliepen +Date: Sun Mar 18 16:41:13 2012 +0100 + + Allow CTR mode counter to be set to a specific value. + +commit 28a1501b9a8b4c730f7f965d6b2e8fc50feba261 +Author: Guus Sliepen +Date: Sat Mar 10 13:31:36 2012 +0100 + + Releasing 1.0.17. + +commit 4712d8f92e63e86e835ffb624d6399343ee568ea +Author: Guus Sliepen +Date: Sat Mar 10 13:23:08 2012 +0100 + + Update copyright notices. + +commit 5b0f5ad958d6db4e73aebc5ee6c608cdae81b7b5 +Author: Guus Sliepen +Date: Thu Mar 8 23:23:39 2012 +0100 + + Make sure disabling old RSA keys works on Windows. + + Seeking in files and rewriting parts of them does not seem to work properly on + Windows. Instead, when old RSA keys are found when generating new ones, the + file containing the old keys is copied to a temporary file where the changes + are made, and that file is renamed back to the original filename. On Windows, + we cannot atomically replace files with a rename(), so we need to move the + original file out of the way first. If anything fails, the new code will warn + that the user has to solve the problem by hand. + +commit 2f1c337c541fcb7e2c62aeeab245ff7a43eb51a5 +Author: Guus Sliepen +Date: Thu Mar 8 22:19:20 2012 +0100 + + Add missing ICMP6 message type definitions. + +commit 40c28589328a2aa96c2ce1419c5d90616c758b3d +Merge: 8ac096b5 9dea33f5 +Author: Guus Sliepen +Date: Thu Mar 8 21:15:08 2012 +0100 + + Merge branch 'master' of git://tinc-vpn.org/tinc into 1.1 + + Conflicts: + src/net_packet.c + +commit 9dea33f5301119dd4423eb962956cf2d246af3f3 +Author: Guus Sliepen +Date: Wed Mar 7 10:40:06 2012 +0100 + + Accept Subnets passed with the -o option when StrictSubnets = yes. + +commit 63f8303a5dc1758876451a580a8317dbc3d295d6 +Author: Guus Sliepen +Date: Fri Mar 2 16:09:58 2012 +0100 + + Only log errors sending UDP packets when debug level >= 5. + + Since tinc will fall back to TCP or route via another node, it is not necessary + to log such errors unconditionally. + +commit 8ac096b5bf9da1b3961a3ac4a03d083629222a63 +Author: Guus Sliepen +Date: Sun Feb 26 18:37:36 2012 +0100 + + Allow log messages to be captured by tincctl. + + This allows tincctl to receive log messages from a running tincd, + independent of what is logged to syslog or to file. Tincctl can receive + debug messages with an arbitrary level. + +commit a1bd3a291379492c8ffecd53792065dc20a28c79 +Author: Guus Sliepen +Date: Sun Feb 26 16:56:53 2012 +0100 + + Don't close control connections when handling a reload command. + + Because this would terminate the connection while the control message + handler was still running, it would lead to a segmentation fault later + on. + +commit 483c5dcfb43719e5fd50902641252e28a04fd74e +Merge: 344d6b9a ae524961 +Author: Guus Sliepen +Date: Sun Feb 26 16:27:13 2012 +0100 + + Merge branch 'master' of git://tinc-vpn.org/tinc into 1.1 + +commit ae5249610954af17c68c547bb1b45ad286ad647e +Author: Guus Sliepen +Date: Sun Feb 26 16:23:02 2012 +0100 + + Only use broadcast at the start of the PMTU discovery phase. + + For local peer discovery, only a handful of packets are necessary for + peers to detect each other. + +commit 344d6b9ac3c795f2942e457c1ab38b1dac5f7242 +Author: Guus Sliepen +Date: Sun Feb 26 12:39:46 2012 +0100 + + Let tincctl use the NETNAME environment variable if no -n option is given. + + This allows administrators who frequently want to work with one tinc + network to omit the -n option. Since the NETNAME variable is set by + tincd when executing scripts, this makes it slightly easier to use + tincctl from within scripts. + +commit 84570275acd84628586a6ca591a283d074ca10f0 +Author: Guus Sliepen +Date: Sun Feb 26 12:33:16 2012 +0100 + + Ensure all SPTPS functions are prefixed with sptps_. + +commit 8b1ad6f76f821648079818f6ff018bbc33b9d9e9 +Author: Guus Sliepen +Date: Sat Feb 25 23:03:09 2012 +0100 + + Go back to breadth first search for path finding. + + If 1.1.x nodes using Dijkstra's algorithm are mixed with 1.0.x nodes using BFS, + then routing loops can occur. + +commit 36623e15a1c8685e5d8730345c1a7f9c93710fef +Merge: 65d6f023 5140656d +Author: Guus Sliepen +Date: Sat Feb 25 22:52:57 2012 +0100 + + Merge branch 'master' of git://tinc-vpn.org/tinc into 1.1 + +commit 5140656de6bcfda72951a7827b05414ce306e3ca +Author: Guus Sliepen +Date: Sat Feb 25 22:11:30 2012 +0100 + + Stricter checks against routing loops. + + If a packet that had to be sent via an intermediate hop, and that intermediate + hop was the one that sent the packet, we drop it. + +commit f1d5eae643cdf537ef357f10f2da8ff83bdf32b4 +Author: Guus Sliepen +Date: Sat Feb 25 21:46:18 2012 +0100 + + Don't send ICMP Time Exceeded messages for other Time Exceeded messages. + + That would be silly. + +commit 65d6f023c46ac3a087f59b60762f87c869783f21 +Author: Guus Sliepen +Date: Sat Feb 25 18:25:21 2012 +0100 + + Use SPTPS when ExperimentalProtocol is enabled. + +commit efd21e232dced3225f119aeb7a585ebf55b7cf77 +Author: Guus Sliepen +Date: Sat Feb 25 15:18:15 2012 +0100 + + Apply HMAC after encryption. + +commit f5dc136cfd7a3a195b75f7174722734e25f30fd9 +Merge: 3fba8017 5a28aa7b +Author: Guus Sliepen +Date: Thu Feb 23 13:26:01 2012 +0100 + + Merge branch 'master' of git://tinc-vpn.org/tinc into 1.1 + + Conflicts: + src/net.c + src/net_packet.c + src/net_socket.c + +commit 5a28aa7b8b0ab6237c2eab5f8b11253ea3ec5a05 +Author: Guus Sliepen +Date: Wed Feb 22 23:17:43 2012 +0100 + + Add LocalDiscovery option which tries to detect peers on the local network. + + Currently, this is implemented by sending IPv4 broadcast packets to the + LAN during path MTU discovery. + +commit 8e717ddb602f01f656369106ec0398efbe9ca4a4 +Author: Guus Sliepen +Date: Wed Feb 22 14:37:56 2012 +0100 + + Pass index into listen_socket[] to handle_incoming_vpn_data(). + +commit 3fba80174dbe29bcfe0d121a2a1d2e61be5ee57b +Merge: fba1c85f 65e8e06c +Author: Guus Sliepen +Date: Wed Feb 22 14:23:59 2012 +0100 + + Merge branch 'master' of git://tinc-vpn.org/tinc into 1.1 + + Conflicts: + NEWS + README + configure.in + doc/tincd.8.in + src/Makefile.am + src/bsd/device.c + src/connection.c + src/connection.h + src/cygwin/device.c + src/device.h + src/dropin.h + src/linux/device.c + src/mingw/device.c + src/net.c + src/net_packet.c + src/net_setup.c + src/net_socket.c + src/process.c + src/protocol.c + src/protocol_key.c + src/raw_socket_device.c + src/route.c + src/solaris/device.c + src/tincd.c + src/uml_device.c + +commit fba1c85f44edfc56c19d35332b1eb825179a8bb6 +Author: Guus Sliepen +Date: Tue Feb 21 23:19:51 2012 +0100 + + Remove useless warning about signature length being shorter than expected. + +commit cb6cbf452f6183a00746afc5bff8f63f3f55235f +Author: Guus Sliepen +Date: Tue Feb 21 23:17:12 2012 +0100 + + Use only one hash algorithm (SHA512) in the PRF. + + On some platforms, OpenSSL by default does not support the Whirlpool algorithm. + +commit 65e8e06c6dc7349b11c3c1e8f4071b51e2994c65 +Author: Nick Hibma +Date: Tue Feb 21 15:26:58 2012 +0100 + + Add missing ICMP message type definitions. + +commit ac48c4ee8c09c8144f830cb66386b9dbe7298440 +Author: Guus Sliepen +Date: Tue Feb 21 14:06:55 2012 +0100 + + Fix check for raw socket support. + + Also, move some variables so there are no compiler warnings about unused + variables when there is no support for raw sockets. + +commit d9ad3d313d96d30ef45cd53367dff9a855a396d4 +Author: Guus Sliepen +Date: Tue Feb 21 13:31:21 2012 +0100 + + Fix a bug that caused tinc to ignore all but the last listening socket. + +commit 46506b7aaf6c6a8a85561c38fdb9c95eae21aa75 +Author: Guus Sliepen +Date: Tue Feb 21 13:13:40 2012 +0100 + + Document the command line flag -o and provide --option as well. + +commit 7d76e287598c8c18cadfb5818046d9dd1b0ad881 +Author: Guus Sliepen +Date: Tue Feb 21 11:39:21 2012 +0100 + + Move initialization of char *priority up to prevent freeing an uninitialized pointer. + +commit 8420a0c8bde1781db04dd2436eb9d5dca5a1732a +Author: Guus Sliepen +Date: Mon Feb 20 17:19:00 2012 +0100 + + Allow disabling of broadcast packets. + + The Broadcast option can be used to cause tinc to drop all broadcast and + multicast packets. This option might be expanded in the future to selectively + allow only some broadcast packet types. + +commit ea415ccc1690d6e5864a7500977b181e5c8faafe +Author: Guus Sliepen +Date: Mon Feb 20 17:12:48 2012 +0100 + + Rename connection_t *broadcast to everyone. + +commit cff5a844a3e6b494f4a4f6eb5b48a84780f2d0e5 +Author: Guus Sliepen +Date: Mon Feb 20 16:52:53 2012 +0100 + + Don't bind outgoing TCP sockets anymore. + + The code introduced in commit 41a05f59ba2c3eb5caab555f096ed1b9fbe69ee3 is not + needed anymore, since tinc has been able to handle UDP packets from a different + source address than those of the TCP packets since 1.0.10. When using multiple + BindToAddress statements, this code does not make sense anymore, we do want the + kernel to choose the source address on its own. + +commit 0233b1d710222cb09be0cbd08c1297e3ece38a9f +Author: Guus Sliepen +Date: Mon Feb 20 16:34:02 2012 +0100 + + Decrement TTL of incoming packets. + + Tinc will now, by default, decrement the TTL field of incoming IPv4 and IPv6 + packets, before forwarding them to the virtual network device or to another + node. Packets with a TTL value of zero will be dropped, and an ICMP Time + Exceeded message will be sent back. + + This behaviour can be disabled using the DecrementTTL option. + +commit 6289859ab365dc1c0d420323174418b316b14502 +Author: Guus Sliepen +Date: Mon Feb 20 15:44:52 2012 +0100 + + Only compile raw socket code when it is supported on that platform. + +commit d1dcdf8eb6f800704be426b1ce6f6c1a8e65ba0d +Merge: 1b2846d9 3b1fad04 +Author: Guus Sliepen +Date: Sat Feb 18 14:31:08 2012 +0100 + + Merge branch 'master' of black:tinc + +commit 3b1fad04de6bed2f284fdf3d5b27d4162aeebc8c +Author: Guus Sliepen +Date: Sat Feb 18 14:37:52 2012 +0100 + + Allow setting DeviceType to tun or tap on Linux. + +commit 6455654d26d204cea4bbc102e5bd6550b7fff7a7 +Author: Guus Sliepen +Date: Sat Feb 18 11:48:21 2012 +0100 + + Send packets back using the same socket as they were received on. + +commit 1b2846d907adfc8472fc9da0c951c3243c7ee143 +Merge: 9f6a96af 6455654d +Author: Guus Sliepen +Date: Sat Feb 18 11:43:00 2012 +0100 + + Merge branch 'master' of black:tinc + +commit 9f6a96af3939bd2de410ce346a8c8fbcf93e7c9b +Author: Guus Sliepen +Date: Fri Feb 17 16:25:00 2012 +0100 + + Allow multiple BindToAddress statements. + +commit 708314df2f61675d0f54e541c9fff62ac1f433b5 +Author: Guus Sliepen +Date: Fri Feb 17 16:13:38 2012 +0100 + + Set FD_CLOEXEC flag on all sockets. + + Scripts called by tinc would inherit its open filedescriptors. This could + be a problem if other long-running daemons are started from those scripts, + if those daemons would not close all filedescriptors before going into the + background. + + Problem found and solution suggested by Nick Hibma. + +commit 1f00111e94b2f9a4beb9608b1e03a5e73c9c5d21 +Author: Guus Sliepen +Date: Mon Dec 26 23:11:27 2011 +0100 + + Fix a few small memory leaks. + +commit b50d6a7f2ad98239018bc5ce7a5739e3bf4f50f7 +Author: Guus Sliepen +Date: Mon Dec 26 23:04:40 2011 +0100 + + Fix compiler warnings. + +commit 178e52f76ef4ba40748c13ea7e518837394d6dbc +Author: Guus Sliepen +Date: Sun Dec 4 01:20:59 2011 +0100 + + Allow linking with multiple device drivers. + + Apart from the platform specific tun/tap driver, link with the dummy and + raw_socket devices, and optionally with support for UML and VDE devices. + At runtime, the DeviceType option can be used to select which driver to + use. + +commit 5672863e59e6a114ac6b66de98254b14266c0e61 +Author: Guus Sliepen +Date: Sat Dec 3 21:59:47 2011 +0100 + + Fix a few small memory leaks. + +commit 52ded09d1713b83222b56db7d29ff061aefb95e3 +Author: Guus Sliepen +Date: Sun Nov 27 12:13:16 2011 +0100 + + Add vde/device.c to the tarball. + +commit 2c7c87ec75c94d0b3cca9f7a5aeba34384f77cc1 +Author: Guus Sliepen +Date: Sun Nov 27 12:12:34 2011 +0100 + + Fix compilation of VDE and UML interfaces. + +commit 2a9060bba62d78f73da9b09ca791fe80993520fc +Author: Guus Sliepen +Date: Thu Oct 6 15:32:12 2011 +0200 + + Exchange ACK records to indicate switch to new keys. + + This allow application records to be sent while key renegotiation is still + happening. + +commit 3b5898078af1ab86797b3e24f2381131e6e702f7 +Author: Guus Sliepen +Date: Thu Oct 6 09:34:34 2011 +0200 + + Use counter mode encryption. + +commit a0f795ff5bd671ca10a7203e4234b37a12d8d1cd +Author: Guus Sliepen +Date: Thu Oct 6 09:33:09 2011 +0200 + + Add counter mode encryption. + +commit 67ff81ec16b8ab5f15d16efbedfecfaf0be17c13 +Author: Guus Sliepen +Date: Wed Oct 5 22:05:13 2011 +0200 + + Test corner cases in the SPTPS protocol. + + * Test zero-byte messages. + * Test maximum size (65535 byte) messages. + * Test different message types. + * Test key renegotiation. + +commit 30013511504e925729ebc67772205a74c4b8aeea +Author: Guus Sliepen +Date: Wed Oct 5 22:00:51 2011 +0200 + + Update SPTPS protocol. + + * Exchange nonce and ECDH public key first, calculate the ECDSA signature + over the complete key exchange. + * Make an explicit distinction between client and server in the signatures. + * Add more comments and replace some magic numbers by #defines. + + Thanks to Erik Tews for very helpful hints and comments! + +commit 810847248ae90140ee6f3e568add80aef88c3def +Author: Guus Sliepen +Date: Wed Oct 5 21:59:33 2011 +0200 + + Fix compiler warning. + +commit ddea7a23a66b8fee4942f2ce237dcabe02e17270 +Author: Guus Sliepen +Date: Tue Aug 30 20:49:48 2011 +0200 + + Return false instead of void when there is an error. + +commit e838289683c0039fac0ae6172d40b4177c17911b +Author: Guus Sliepen +Date: Tue Aug 30 19:56:56 2011 +0200 + + Prevent read_rsa_public_key() from returning an uninitialized RSA structure. + + In case the config file could not be opened a new but unitialized RSA structure + would be returned, causing a segmentation fault later on. This would only + happen in the case that the config file could be opened before, but not when + read_rsa_public_key() was called. This situation could occur when the --user + option was used, and the config files were not readable by the specified user. + +commit 5d4336e5429b88dcc53e80c00412e76a5269b384 +Author: Guus Sliepen +Date: Wed Aug 10 17:04:17 2011 +0200 + + Handle UDP packets with unknown source addresses properly. + + Probably due to a merge, the try_harder() function had duplicated the + rate-limiting code for detecting the sender node based on the HMAC of the + packet. This prevented this detection from running at all. The function is now + identical again to that in the 1.0 branch. + +commit bbc0ba9e87f76111529d6dc9cb00c0b9435b5858 +Author: Michael Tokarev +Date: Sun Aug 7 12:18:20 2011 +0400 + + use execvp() not execve() in tincctl start + + sometimes argv[0] will have directory-less name (when the + command is started by shell searching in $PATH for example). + For tincctl start we want the same rules to run tincd as for + tincctl itself (having full path is better but if shell does + not provide one we've no other choice). Previous code tried + to run ./tincd in this case, which is obviously wrong. + + This is a fix for the previous commit. + + Signed-off-by: Michael Tokarev + +commit a7556a9d2c943a6317d2dab66d9f742997f0d47a +Author: Michael Tokarev +Date: Sun Aug 7 12:05:07 2011 +0400 + + run tincd from the same directory as tincctl and pass all options to it + + For tincctl start, run tincd from dirname($0) not SBINDIR - + this allows painless alternative directory installation and + running from build directory too. + + Also while at it, pass the rest of command line to tincd, not + only options before "start" argument. This way it's possible + to pass options to tincd like this: + tincctl -n net start -- -d 1 -R -U tincuser ... + + And also add missing newline at the end of error message there. + + Signed-Off-By: Michael Tokarev + +commit 2696ad2cca73aee13e38f740d5530dc33e4a92e6 +Author: Michael Tokarev +Date: Sun Aug 7 11:25:03 2011 +0400 + + don't mention reload twice in tincctl help + + Signed-Off-By: Michael Tokarev + +commit 3d75dbc0880484ff6d2f689a9b981def3cd75b5e +Author: Guus Sliepen +Date: Sun Jul 24 15:44:51 2011 +0200 + + Start of "Simple Peer-To-Peer Security" protocol. + + Encryption and authentication of the meta connection is spread out over + meta.c and protocol_auth.c. The new protocol was added there as well, + leading to spaghetti code. To improve things, the new protocol will now + be implemented in sptps.[ch]. + + The goal is to have a very simplified version of TLS. There is a record + layer, and there are only two record types: application data and + handshake messages. The handshake message contains a random nonce, an + ephemeral ECDH public key, and an ECDSA signature over the former. After + the ECDH public keys are exchanged, a shared secret is calculated, and a + TLS style PRF is used to generate the key material for the cipher and + HMAC algorithm, and further communication is encrypted and authenticated. + + A lot of the simplicity comes from the fact that both sides must have + each other's public keys in advance, and there are no options to choose. + There will be one fixed cipher suite, and both peers always authenticate + each other. (Inspiration taken from Ian Grigg's hypotheses[0].) + There might be some compromise in the future, to enable or disable + encryption, authentication and compression, but there will be no choice + of algorithms. This will allow SPTPS to be built with a few embedded + crypto algorithms instead of linking with huge crypto libraries. + + The API is also kept simple. There is a start and a stop function. All + data necessary to make the connection work is passed in the start + function. Instead having both send- and receive-record functions, there + is a send-record function and a receive-data function. The latter will + pass protocol data received from the peer to the SPTPS implementation, + which will in turn call a receive-record callback function when + necessary. This hides all the handshaking from the application, and is + completely independent from any event loop or socket characteristics. + + [0] http://iang.org/ssl/hn_hypotheses_in_secure_protocol_design.html + +commit 0f2aa4bd8b698608876bec141c5aef1aa619730b +Author: Guus Sliepen +Date: Sat Jul 23 14:12:23 2011 +0200 + + Releasing 1.0.16. + +commit e16ead8dd9d4600664058069f0695832dfe068b2 +Author: Guus Sliepen +Date: Sat Jul 23 14:11:44 2011 +0200 + + Use usleep() instead of sleep(), MinGW complained. + +commit ff751903aa82bd6dd66a099f9c05dcdae9fc57f2 +Author: Guus Sliepen +Date: Wed Jul 20 08:19:18 2011 +0200 + + Don't abort() on low-level crypto errors, just return false. + + The abort() calls were accidentily left in for debugging. + +commit 2f4ccfe2473948372f7c9f14d9ffce1d77f5fd8c +Author: Guus Sliepen +Date: Tue Jul 19 21:11:11 2011 +0200 + + Fix tinc 1.0.x daemons connecting when ExperimentalProtocol = yes. + +commit f8d94f34fc5d7fe9ed4a076a2fd77eacbd83adca +Author: Guus Sliepen +Date: Sun Jul 17 20:09:08 2011 +0200 + + Releasing 1.1pre2. + +commit c259d552fa89c3e4a962d9adf2b237f24bc077da +Author: Guus Sliepen +Date: Sun Jul 17 20:06:06 2011 +0200 + + Add missing newline. + +commit f6020a5224c9c4c17c11c5f9d2c8441638ac04fc +Author: Guus Sliepen +Date: Sun Jul 17 20:01:24 2011 +0200 + + Write loopback address instead of "any" address in pidfile. + +commit 50fcfea127c9d2fdf8894498a9fdcc6fb3bbb2ce +Author: Guus Sliepen +Date: Sun Jul 17 19:34:01 2011 +0200 + + Flush output buffer in send_tcppacket(). + + This is mainly important for Windows, where the select() call in the + main thread is not being woken up when the tapreader thread calls + route(), causing a delay of up to 1 second before the output buffer is + flushed. This would cause bad performance when UDP communication is not + possible. + +commit 25091454da21941dd92375ddbee7dd6151343058 +Author: Guus Sliepen +Date: Sun Jul 17 19:23:52 2011 +0200 + + "tincctl stop" now removes the tinc service on Windows. + +commit c6c989cfa175154f4cd3830c5a77fbd2071f52af +Author: Guus Sliepen +Date: Sun Jul 17 18:02:56 2011 +0200 + + Fix declaration of usleep(). + +commit 18e9839dc861c368141bbbc9a963f719a83eba3e +Author: Guus Sliepen +Date: Sun Jul 17 10:59:54 2011 +0200 + + Ensure symlinked files do not end up in the tarball. + +commit fa4a01e4a27dd4b3a57077acbd0e69f95d55944a +Author: Guus Sliepen +Date: Sat Jul 16 22:38:50 2011 +0200 + + Use const pointer to source in base64 and hex routines. + +commit 574b380dfc75ef13ee4accba1f2416165c58a5a2 +Author: Guus Sliepen +Date: Sat Jul 16 22:38:22 2011 +0200 + + Use usleep() instead of sleep(), MinGW complained. + +commit 8efc8dc961865ceddb74cb36f0b4a2ebde39cc55 +Author: Guus Sliepen +Date: Sat Jul 16 21:44:17 2011 +0200 + + Update info manual. + +commit cff27a258f3b3a97b5d2e309c264eceea41dff3a +Author: Guus Sliepen +Date: Sat Jul 16 20:21:44 2011 +0200 + + Use ECDSA to sign ECDH key exchange for UDP session keys. + + The ECDSA public keys will also be included in the ANS_KEY requests, + but are only used when no ECDSA public key is known yet. + +commit 03ac48ea19914e4162f17a2fb0f742b99ae32499 +Author: Guus Sliepen +Date: Sat Jul 16 15:21:37 2011 +0200 + + Use the same logic as tinc 1.0.x for detecting two nodes with the same Name. + +commit 2ba61742d4c2ab82525efb806dc654a6d95d335e +Author: Guus Sliepen +Date: Sat Jul 16 15:15:29 2011 +0200 + + Use the correct direction flag when setting cipher keys. + + The flag was set incorrectly, but for most ciphers this does not have + any effect. AES in any of the block modes is picky about it though. + +commit be2fc8b0458b1e2ced3b5de410356d8d8639acff +Author: Guus Sliepen +Date: Sat Jul 16 10:47:35 2011 +0200 + + Make code to detect two nodes with the same Name less triggerhappy. + + First of all, if there really are two nodes with the same name, much + more than 10 contradicting ADD_EDGE and DEL_EDGE messages will be sent. + Also, we forgot to reset the counters when nothing happened. + + In case there is a ADD_EDGE/DEL_EDGE storm, we do not shut down, but + sleep an increasing amount of time, allowing tinc to recover gracefully + from temporary failures. + +commit 303dd1e70219a7542921f6e63d9391ab326d434f +Author: Guus Sliepen +Date: Wed Jul 13 22:52:52 2011 +0200 + + Fix compiler warnings. + +commit 791c1898ea8f92b07f1d79e90540c257ac38298d +Author: Guus Sliepen +Date: Wed Jul 13 22:29:30 2011 +0200 + + Remove unnecessary variables and functions. + +commit fec279a9c54ec8a13bd1ba4c7bec0d2a15454992 +Author: Guus Sliepen +Date: Tue Jul 12 23:43:12 2011 +0200 + + Make use of the improved hex and base64 functions. + + Also, use base64 for all EC related data, it is shorter and easy to + distinguish from the legacy protocol. + +commit 06b8271ed5d56c9bd3de459d95907d0ef4f0ea3c +Author: Guus Sliepen +Date: Tue Jul 12 22:54:49 2011 +0200 + + Make hexadecimal and base64 routines behave the same. + + The length parameter for the encoding functions is the length of the + binary input, and for the decoding functions it is the maximum size of + the binary output. + + The return value is always the length of the resulting output, excluding + the terminating NULL character for the encoding routines. + + All functions can encode and decode in-place. The encoding functions + will always write a terminating NULL character, and the decoding + functions will stop at a NULL character. + +commit c108c79a22118ef7246a3d7b3bc20e205e11d179 +Author: Guus Sliepen +Date: Mon Jul 11 22:14:06 2011 +0200 + + Don't use wildcards in filenames in configure.in. + +commit bbeab00f46a6c856573fe0d2b9b85bce35728403 +Author: Guus Sliepen +Date: Mon Jul 11 21:54:01 2011 +0200 + + Require ExperimentalProtocol = yes for new features, update documentation. + +commit d1cd3c81455ecb32149cbaa424b7870075b2b2fc +Author: Guus Sliepen +Date: Sun Jul 10 22:46:43 2011 +0200 + + Close meta connection socket after cleaning up event structures. + + Epoll doesn't like it when an already closed filedescriptor is being + removed, so we defer closing the socket until after all else is cleaned + up. + +commit 30ef2a981e1d62692b3a2363e0b3a0e8711d9604 +Author: Guus Sliepen +Date: Sun Jul 10 22:34:17 2011 +0200 + + Automatically exchange ECDSA keys and upgrade to new authentication protocol. + + If we don't have ECDSA keys for the node we connect to, set protocol_minor + to 1, to indicate this to the other end. This will first complete the + old way of authentication with RSA keys, and will then exchange ECDSA keys. + The connection will be terminated right afterwards, and the next attempt + will use ECDSA keys. + +commit 027228debee2ea6f31cd176e456c13d626380066 +Author: Guus Sliepen +Date: Sun Jul 10 21:02:34 2011 +0200 + + Free ECDSA and RSA structures when freeing a connection_t. + +commit 73863fab8ae1ecd8307aaeef486919cc76b85d63 +Author: Guus Sliepen +Date: Fri Jul 8 18:17:34 2011 +0200 + + Hash input before signing it with ECDSA. + +commit 8132be8fbd6c45be309c63a117f418ad12ced094 +Author: Guus Sliepen +Date: Thu Jul 7 22:30:55 2011 +0200 + + Very primitive ECDSA signed ECDH key exchange for the meta protocol. + + Nonces and hash of the ID requests should be included in the seed for the PRF. + +commit 210b5ceeeebdf742a74dcf95a0a13d69623ee001 +Author: Guus Sliepen +Date: Thu Jul 7 22:28:25 2011 +0200 + + Read ECDSA keys. + +commit 03582eb669494cb778ebea7b0fe3b1b841335750 +Author: Guus Sliepen +Date: Thu Jul 7 22:27:17 2011 +0200 + + Implement ECDSA sign and verify operations. + + Very basic at the moment, doesn't hash the input first, + and uses OpenSSL's DER encoded signature as output. + +commit 86d83bd9bd69e2129f4e4e8397f1c7e223685e2f +Author: Guus Sliepen +Date: Tue Jul 5 21:29:31 2011 +0200 + + Bump minor protocol to indicate ECDH capability for UDP session keys. + +commit 9708bbfa8e3094de8932a30b1d24c661558d8a03 +Author: Guus Sliepen +Date: Tue Jul 5 21:19:48 2011 +0200 + + Add a minor number to the protocol version. + +commit b99656d84a88dad7935d5981fcdb43a5b2bfa417 +Author: Guus Sliepen +Date: Mon Jul 4 07:51:47 2011 +0200 + + Round up the size of the secret parts after splitting it in two. + +commit 95e1cc36d320b47408ac3ec6f89df54e55a010d4 +Author: Guus Sliepen +Date: Sun Jul 3 23:44:43 2011 +0200 + + Add ECDSA key import. + +commit 1e2d9b08991861c8770aa2c5a73d86dc02e3067d +Author: Guus Sliepen +Date: Sun Jul 3 23:33:56 2011 +0200 + + Finish base64 decoding routine. + +commit 80b81c00b129b006981b76bdb734df3296317d6f +Author: Guus Sliepen +Date: Sun Jul 3 22:25:29 2011 +0200 + + Have tincctl generate ECDSA keys. + + The generate-keys command now generates both an RSA and an ECDSA keypair, + but one can generate-rsa-keys or generate-ecdsa-keys to just generate one type. + +commit 8ace7f3e5771957fbdda8b817fa26951d9d62c28 +Author: Guus Sliepen +Date: Sun Jul 3 22:15:00 2011 +0200 + + Add ECDSA key generation. + +commit 1d92dd62a786ecabbc05dfba5195f3f08e0f9585 +Author: Guus Sliepen +Date: Sun Jul 3 22:13:58 2011 +0200 + + Base64 encoding and decoding functions. + +commit c385d115331845e8a844322e66571d74d833e822 +Author: Guus Sliepen +Date: Sun Jul 3 22:13:34 2011 +0200 + + Cleanups in ECDH code. + +commit 895f868714f9422a757a95650345e0c662d12b49 +Author: Guus Sliepen +Date: Sun Jul 3 21:21:37 2011 +0200 + + No need to keep around pointers to EC_GROUP. + +commit ac163120d7f0300c8d555f76ace3368ce2ffa655 +Author: Guus Sliepen +Date: Sun Jul 3 16:30:49 2011 +0200 + + Proper use of PRF. + +commit 82f00ea07bffc10985ccb1a15723e6daa0ab4969 +Author: Guus Sliepen +Date: Sun Jul 3 15:59:49 2011 +0200 + + Use PRF. + +commit feb3f22fffa2620b9b11a509ce51ff9fa3be9418 +Author: Guus Sliepen +Date: Sun Jul 3 15:26:58 2011 +0200 + + Add PRF to derive key material from the ECDH shared secret. + + It is modelled after the pseudorandom function from RFC4346 (TLS 1.1), the only + significant change is the use of SHA512 and Whirlpool instead of MD5 and SHA1. + +commit 8dfa072733feab737cabf69f000c70657719826a +Author: Guus Sliepen +Date: Sun Jul 3 13:17:28 2011 +0200 + + Support ECDH key exchange. + + REQ_KEY requests have an extra field indicating key exchange version. + If it is present and > 0, the sender supports ECDH. If the receiver also + does, then it will generate a new keypair and sends the public key in a + ANS_KEY request with "ECDH:" prefixed. The ans_key_h() function will + compute the shared secret, which, at the moment,is used as is to set the + cipher and HMAC keys. However, this must be changed to use a proper KDF. + In the future, the ECDH key exchange must also be signed. + +commit ee8a214318fd6dbe6bc5d6b510896f30d92d46c6 +Author: Guus Sliepen +Date: Mon Jun 27 21:52:23 2011 +0200 + + Preliminary implementation of Elliptic Curve Diffie-Hellman Ephemeral key exchange. + +commit 6c21b5716b8e9e5ff5def8070f92b76a0f353cb0 +Author: Guus Sliepen +Date: Sun Jun 26 13:15:44 2011 +0200 + + Add manpage for tinc-gui. + +commit 4c934d0903a32e71ae83ffdf344957bd06b7164d +Author: Guus Sliepen +Date: Sun Jun 26 13:14:48 2011 +0200 + + Remove debug messages that were printed to stdout. + +commit e73052b05444679d922dbdf3d0c507873110957e +Author: Guus Sliepen +Date: Sun Jun 26 12:59:11 2011 +0200 + + Update documentation to mention pidfiles instead of controlcookies. + +commit 8c953b1bfef3c6ebee7c537c2c2f144807d0311a +Author: Guus Sliepen +Date: Sun Jun 26 12:58:50 2011 +0200 + + Don't react to escape character in tincctl top. + + Not only the ESC key generates an escape character, but many other keys + do as well, such as arrow keys. + +commit 27e6a89b155b171b0b026d5e24ee0cc68f43d010 +Author: Guus Sliepen +Date: Sun Jun 26 12:51:25 2011 +0200 + + Use pidfile in tinc-gui as well. + +commit 660f530a6ff733f96f81eefa69b38e2ea685f890 +Author: Guus Sliepen +Date: Sat Jun 25 22:20:39 2011 +0200 + + Really stable sorting of tincctl top output. + +commit 810766e1394f18b8709e9f0c75a41a2c348e3fad +Author: Guus Sliepen +Date: Sat Jun 25 21:38:59 2011 +0200 + + Add +git to the version string. + +commit ab4d289fafd1d391583935ab4c306f1f508ea1d0 +Author: Guus Sliepen +Date: Sat Jun 25 21:35:27 2011 +0200 + + Make pid files backwards compatible and add address of listening socket. + + The pid is now written first, so that a version 1.0.x tincd can be used to stop + a running version 1.1 tincd. Getsockname() is used to determine the address of + the first listening socket, so that tincctl can connect to the local tincd even + if AddressFamily = ipv6, or if BindToAddress or BindToInterface is used. + +commit a05fa7f88264599a43f9e411287e018259dc22b1 +Author: Guus Sliepen +Date: Sat Jun 25 21:21:36 2011 +0200 + + Rename controlcookie file to pidfile. + +commit c64f64b875879591873d68faf2d3cd8e9d644101 +Author: Guus Sliepen +Date: Sat Jun 25 21:16:13 2011 +0200 + + Don't call exit_control() if we didn't do init_control(). + +commit 3b237afbda86bc95703ed25386cc9a26695d4602 +Author: Guus Sliepen +Date: Sat Jun 25 20:20:07 2011 +0200 + + Re-add support for SIGALRM. + +commit 386c1aff08a3ce6e295931e2fcf4bfc607053ff0 +Author: Guus Sliepen +Date: Sat Jun 25 17:39:02 2011 +0200 + + Merge Tinc.py into tinc-gui to simplify make install. + + Autoconf/automake's Python support is strange. + +commit c4c32f40599eb8e75b1160083020d924c5807ac8 +Author: Guus Sliepen +Date: Sat Jun 25 17:11:05 2011 +0200 + + Thank Scott Lamb, Sven-Haegar Koch and Loïc Grenié in the NEWS file. + +commit 8733110dec28967d67a3c00d00cdfa608dbeb9c4 +Author: Guus Sliepen +Date: Sat Jun 25 17:08:40 2011 +0200 + + Ensure the right files end up in the tarball after make dist. + +commit e4f65db89726ac06ba7e787d420db4422d9a6e98 +Author: Guus Sliepen +Date: Sat Jun 25 15:28:54 2011 +0200 + + Releasing 1.1pre1. + +commit 2c5ded652035bfaa204a7e1cc6766efb87135569 +Author: Guus Sliepen +Date: Sat Jun 25 15:28:13 2011 +0200 + + Ensure that the texinfo manual can be converted to HTML. + + Somehow commit 2c30af6c90926340a89748c63cc453b1c0b5a589 was not properly + merged. + +commit e8deda0b23463599a7533e82cf038a01062956a7 +Author: Guus Sliepen +Date: Sat Jun 25 14:52:47 2011 +0200 + + Update manpages and info manual. + +commit 47393b5de42120dfb7d01f8b77aff16ac68177ec +Author: Guus Sliepen +Date: Sat Jun 25 00:32:45 2011 +0200 + + Add Makefile.am in gui/. + + This ensures the gui source will be included in the tarball with make dist, + and will be installed with make install. + +commit 7944cce19e4de4207a4ef20569155118acebd406 +Author: Guus Sliepen +Date: Sat Jun 25 00:06:06 2011 +0200 + + Don't use AM_CONDITIONAL for CURSES. + + For some reason, this doesn't work when cross-compiling for Windows. + +commit 365f60f3f8a8ff85a616d5014d555b470740d395 +Author: Guus Sliepen +Date: Fri Jun 24 22:49:18 2011 +0200 + + Don't call event_del() from the mtuevent handler, always send_mtu_probe() in ans_key_h(). + +commit 1fe8ba2f06c39d7c8b81f0e451bdbac94ae9375f +Author: Guus Sliepen +Date: Fri Jun 24 22:10:03 2011 +0200 + + Delete mtuevent if it is not used. + + Keeping it around prevents ans_key_h() from restarting PMTU discovery. + +commit 79e9a4f743b7b59fed968575f6b36171cf4a0063 +Merge: fb5b2601 05260f94 +Author: Guus Sliepen +Date: Fri Jun 24 21:40:55 2011 +0200 + + Merge branch 'master' of git://tinc-vpn.org/tinc into 1.1 + + Conflicts: + NEWS + README + configure.in + src/Makefile.am + +commit 05260f941c2a24eb3f09070a2550cf15e431266a +Author: Guus Sliepen +Date: Fri Jun 24 14:50:20 2011 +0200 + + Releasing 1.0.15. + +commit 3c0511984f0041f79e64bcc55d58680f86e8e408 +Author: Guus Sliepen +Date: Fri Jun 24 12:27:04 2011 +0200 + + Remove redundant @CFLAGS@ from AM_CFLAGS. + +commit fb5b260190b1c6d07ec822154094aee7416f292e +Author: Guus Sliepen +Date: Tue Jun 21 23:08:05 2011 +0200 + + No need to check for pselect() in tinc 1.1. + +commit 532557beeaa60d96ac423248ff62d2cc03205c22 +Author: Guus Sliepen +Date: Tue Jun 21 23:06:53 2011 +0200 + + Only log UDP address changes at the appropriate debug levels. + +commit 60ed7fe598ccf3ac11fab616c9c85492c576b722 +Author: Guus Sliepen +Date: Mon Jun 6 21:19:30 2011 +0200 + + Reopen log file after SIGHUP. + + This was missed by the previous merge. + +commit 33f241d97852d7a171f1aaf1bda7f66356ff889e +Merge: 601f3b2d 4b3fd94b +Author: Guus Sliepen +Date: Mon Jun 6 20:42:15 2011 +0200 + + Merge branch 'master' of git://tinc-vpn.org/tinc into 1.1 + + Conflicts: + NEWS + configure.in + doc/tincd.8.in + lib/pidfile.c + lib/pidfile.h + lib/xalloc.h + lib/xmalloc.c + src/conf.c + src/conf.h + src/connection.c + src/connection.h + src/event.c + src/graph.c + src/graph.h + src/net.c + src/net.h + src/node.h + src/openssl/crypto.c + src/process.c + src/protocol.c + src/protocol_key.c + src/route.c + +commit 601f3b2dd746ff5726eca256861f2ecf662b3a55 +Author: Guus Sliepen +Date: Mon Jun 6 20:12:33 2011 +0200 + + Clean up digests when freeing a connection_t. + +commit 4b3fd94b1cc79c24c4092b6b10ed4627a2648d26 +Author: Guus Sliepen +Date: Mon Jun 6 16:26:11 2011 +0200 + + Improved --logfile option. + + Instead of UNIX time, the log messages now start with the time in RFC3339 + format, which human-readable and still easy for the computer to parse and sort. + The HUP signal will also cause the log file to be closed and reopened, which is + useful when log rotation is used. If there is an error while opening the log + file, this is logged to stderr. + +commit b3bbeab6e669795f6f5a6b98590da359178bfdce +Author: Guus Sliepen +Date: Sat Jun 4 11:27:54 2011 +0200 + + Attribution for Loïc Grenié. + +commit 50af33d01f425983dd2b1d7b61092a6325be3f41 +Author: Loïc Grenié +Date: Sat Jun 4 09:05:23 2011 +0200 + + Nearly tickless tinc. + + Use pselect instead of select in main_loop (if available). This lets + tincd sleeps as long as there is nothing to do. + +commit 8b3cc695b56d4ab5e51c7e194153894f920b307f +Author: Guus Sliepen +Date: Fri Jun 3 15:50:20 2011 +0200 + + Don't ignore SIGCHLD, system() needs it. + + But we do ignore SIGPIPE, and tinc 1.0.x signals that are no longer used + (SIGUSR1 and SIGUSR2), since the default handler of these signals is to + terminate tincd immediately. + +commit 5989a29d7b53b25e8ed2f60bc3a0e089e423c02c +Author: Guus Sliepen +Date: Fri Jun 3 00:46:56 2011 +0200 + + Fix format strings for Windows. + + Windows doesn't like %zd, so cast (s)size_t to int. Also, some shorts were + incorrectly printed with %d instead of %hd. + +commit 3ade33bfac11715190ed3e6cc3589d1a738ce257 +Author: Guus Sliepen +Date: Fri Jun 3 00:34:30 2011 +0200 + + Use send() when writing to sockets, and the return type is ssize_t. + +commit 5f4d57e846b566e80557c57a72e2bad562f66e7b +Author: Guus Sliepen +Date: Thu Jun 2 23:40:27 2011 +0200 + + Small fixes for Windows. + +commit 2adc789401153ffde847f76155e07665fbf909ac +Author: Guus Sliepen +Date: Thu Jun 2 22:14:53 2011 +0200 + + Even simpler signal handling. + +commit 2f42896789a1798e71374fa2ddf555fe2fa46c44 +Author: Guus Sliepen +Date: Thu Jun 2 21:29:11 2011 +0200 + + Remove debugging message that was accidentily left in. + +commit c6b0e102ad7caabae6876849c97f8acaecf5bc1a +Author: Guus Sliepen +Date: Thu Jun 2 21:16:57 2011 +0200 + + Don't treat packets coming in via TCP as having zero length. + +commit 80ca91769d48e546d3e4cde03c2eb2820c03acc4 +Author: Guus Sliepen +Date: Thu Jun 2 21:14:50 2011 +0200 + + Fix nodes joining the VPN after tincctl top started. + +commit 311f60f4f0bdf974d4890d7eb4a752299d1c9458 +Author: Guus Sliepen +Date: Thu Jun 2 20:48:18 2011 +0200 + + Make traffic statistics more readable with configurable scaling. + +commit a8f0d21330b40993d52421327b1aa33a6ea7acb7 +Author: Guus Sliepen +Date: Thu Jun 2 20:27:16 2011 +0200 + + More stable sorting in tincctl top. + + Although we use qsort(), which is not guaranteed to be stable, resorting the + previously sorted array is more stable than recreating and resorting the array + each time. + +commit 2bda2aa8855ff3ae42aba7aa86e1d7ff2b7a3b34 +Author: Guus Sliepen +Date: Thu Jun 2 18:22:26 2011 +0200 + + Fix some compiler and cppcheck warnings. + +commit 809dfd2f5b08ecbfe55d1a06d267abeef0044b0b +Author: Guus Sliepen +Date: Thu Jun 2 18:07:50 2011 +0200 + + Remove support for the Ethertap device. + +commit af2e0c9a32642065aedd2e67ca1f5791ca7a407d +Author: Guus Sliepen +Date: Thu Jun 2 17:57:53 2011 +0200 + + Remove unused functions and variables. + +commit 9eca49329db0c3b0a80114045cf214eaeaf3d5c2 +Author: Guus Sliepen +Date: Thu Jun 2 17:55:29 2011 +0200 + + Don't #include anymore. + +commit b7754e5aaa3cc453582d6c8c2e66483fdcd1ac0d +Author: Guus Sliepen +Date: Thu Jun 2 17:53:35 2011 +0200 + + Drop the GNU memcmp.c implementation. + +commit 25b467638a23ad03524719329027225ae1da75bc +Author: Guus Sliepen +Date: Thu Jun 2 17:45:06 2011 +0200 + + Drop the GNU malloc.c, realloc.c, and xmalloc.c. + + We live in the 21st century, and we require C99 semantics, so we do not need to + work around buggy libcs. The xmalloc() and related functions are now static + inline functions. + +commit e452a933f9c53fd58db9d932afd15319129dd988 +Author: Guus Sliepen +Date: Thu Jun 2 17:14:30 2011 +0200 + + Simplify signal handling. + + We don't override any signal handlers anymore except those for SIGPIPE and + SIGCHLD. Fatal signals (SIGSEGV, SIGBUS etc.) will terminate tincd and + optionally dump core. The previous behaviour was to terminate gracefully and + try to restart, but that usually failed and made any core dump useless. + +commit 4d440336c3ce68719e23b2fc51fac368e23352ad +Author: Guus Sliepen +Date: Sun May 29 22:34:19 2011 +0200 + + Remove outgoing event in free_connection(). + +commit d29bfc9a450b4758e44757a71675bac631dd3c55 +Author: Guus Sliepen +Date: Sun May 29 22:14:35 2011 +0200 + + Initialise priority field to zero for packets read from the VPN interface. + +commit 4c403840ffdeb2a2ff04c9b7780a407920b2b794 +Author: Guus Sliepen +Date: Sun May 29 22:12:37 2011 +0200 + + Cosmetic fix when pressing 's' in tincctl top. + +commit b3aeaf0f917a895332ff937c7ab64638eacc0eae +Author: Guus Sliepen +Date: Sun May 29 22:10:54 2011 +0200 + + Show hostname and port in error message when connecting to a running tincd. + +commit 04de15984f1479d0142bdfa5bd968274aea2209e +Author: Sven-Haegar Koch +Date: Sun May 29 21:53:21 2011 +0200 + + do_outgoing_connection() may delete a failed connection, and the structure + must not be accessed afterwards. + +commit 82109868b5acd55e452569c565ab6dc090ea1de0 +Author: Sven-Haegar Koch +Date: Sun May 29 21:35:31 2011 +0200 + + src/net_socket.c bind_to_address(): Use after free in error path. + +commit 5bc957074a35e58f49cbcf8d1fb5d6237d37363d +Author: Guus Sliepen +Date: Sun May 29 14:41:05 2011 +0200 + + Allow tincctl to connect to something besides localhost. + + This would allow tincctl to connect to a remote tincd, or to a local tincd that + isn't listening on localhost, for example if it is using the BindToInterface or + BindToAddress options. + +commit 64771f73ebbff04262defcde59263e98f89f0fa1 +Author: Guus Sliepen +Date: Sat May 28 23:46:56 2011 +0200 + + Remove a few unnecessary #includes. + + Some spotted by Michael Tokarev. + +commit 5cff8c47c1781a88123c128a4cec6cdd39925aa5 +Author: Guus Sliepen +Date: Sat May 28 23:42:18 2011 +0200 + + Remove newlines from log messages. + +commit 6d08eb1614b59d5f86a43edda9db06fca72b76cd +Author: Guus Sliepen +Date: Sat May 28 23:36:52 2011 +0200 + + Fix sparse warnings and add an extra sprinkling of const. + + This is more or less the equivalent of Sven-Haegar Koch's fixes in the 1.1 + branch. + +commit e6b21e1a510691a86dcc1ecdf71a80a7c62ff17f +Author: Sven-Haegar Koch +Date: Sat May 28 03:48:07 2011 +0200 + + fgets() returns NULL on error, not < 0 + +commit 434e57ae5ee79b3d990c4d75358047bad641998b +Author: Sven-Haegar Koch +Date: Sat May 28 03:46:39 2011 +0200 + + sparse fixup: warning: Using plain integer as NULL pointer + +commit f4010694b3b16453e5e6298c208910264e326978 +Author: Sven-Haegar Koch +Date: Sat May 28 03:57:20 2011 +0200 + + sparse fixup: warning: non-ANSI function declaration of function '...' + +commit d772289f6d6adfb8932658b533349d43f08ec326 +Author: Sven-Haegar Koch +Date: Sat May 28 03:56:06 2011 +0200 + + sparse fixup: warning: symbol '...' was not declared. Should it be static? + +commit 02e32cf61ee25d3d0e2fc1fef5cd98cbfa1c9a2f +Author: Sven-Haegar Koch +Date: Sat May 28 03:12:03 2011 +0200 + + sparse fixup: error: too many arguments for function send_key_changed + +commit b995243ac3d9605003996ba879808ddcbc77ae15 +Author: Sven-Haegar Koch +Date: Sat May 28 03:08:31 2011 +0200 + + sparse fixup: error: dubious one-bit signed bitfield + +commit bbd0025ae323e7141ba04a5371ec2f3f75f9b059 +Author: Sven-Haegar Koch +Date: Sat May 28 02:57:40 2011 +0200 + + Use same definition for xalloc_fail_func as is really used. + +commit 3fca2cad485ef70360bca085c5c4d052b6deb15b +Author: Sven-Haegar Koch +Date: Sat May 28 01:36:10 2011 +0200 + + Removed two newlines from the end of log messages which created empty lines. + +commit 9cce44dfe3401867f753778b73fd1e7ac1ee3122 +Author: Sven-Haegar Koch +Date: Sat May 28 01:33:45 2011 +0200 + + Fixed error logging on "Input buffer full" condition. + +commit 07ffb1a19859791d419b83a876ba552dadedbf46 +Author: Guus Sliepen +Date: Sun May 22 15:56:04 2011 +0200 + + Make return value of SetPriorityClass() behave the same as setpriority(). + +commit 453c44e7b27d4259461795ab4ec6ef264085dd28 +Author: Guus Sliepen +Date: Sun May 22 14:17:30 2011 +0200 + + Add the ability to dump all traffic going through route() over a control connection. + + One can get the packet stream in pcap format, which can be decoded using + tcpdump, for example: + + tincctl -n pcap | tcpdump -r - + +commit 54c900e961de6065f607f5661edeb7c84be29ea5 +Author: Guus Sliepen +Date: Sun May 22 14:02:27 2011 +0200 + + Reset tcplen after use. + +commit 8ddcad5fa1908727f68abb461b615c666616064f +Author: Guus Sliepen +Date: Sun May 22 13:15:27 2011 +0200 + + Check if an event is initialized before calling event_del(). + + Libevent prints a warning to stderr if we do that. + +commit 931e30f91a9241ab8aa705c911c92ba8943f80fd +Author: Guus Sliepen +Date: Sun May 22 13:15:05 2011 +0200 + + Always compact the buffer if it has reached MAXBUFSIZE. + +commit 90c7fafe594cf6d03c15a072a3d749f3e4d78482 +Author: Guus Sliepen +Date: Sun May 22 12:56:51 2011 +0200 + + Compact input buffer before trying to read instead of after. + + Also log an error when the input buffer contains more than MAXBUFSIZE bytes + already, instead of silently claiming the other side closed the connection. + +commit 8de8f1d9e2c2c02d4a14a5506e7d0d914dc328da +Author: Guus Sliepen +Date: Tue May 17 10:58:22 2011 +0200 + + Fix some compiler warnings. + +commit a80c18dd20e5303b26d5283e6cb5062a1812ddc3 +Author: Guus Sliepen +Date: Tue May 17 10:57:30 2011 +0200 + + Use GetItemCount() on ListCtrls instead of directly accessing ItemCount. + +commit f536504a7de90927b09d16f3bf0d3c6adead9955 +Author: Guus Sliepen +Date: Mon May 16 09:48:19 2011 +0200 + + Add top.h. + +commit e272fab858d5d3eeb43ff9f36268d25d3c6d32f1 +Author: Guus Sliepen +Date: Mon May 16 09:46:54 2011 +0200 + + Add tincctl.h. + +commit 6d97cb1e229c22d1d34aa9889aeaf17644ff06dc +Author: Guus Sliepen +Date: Sun May 15 16:30:13 2011 +0200 + + Nicer top command. + + - Configurable refresh interval. + - Switch between cumulative count or current rate. + - Configurable sorting. + +commit 4574b04f79d79d53492b7e0eb592d64ff9b2362b +Author: Guus Sliepen +Date: Sun May 15 16:29:54 2011 +0200 + + Allow inserting items in the middle of a list. + +commit 97355690b9cf8d8b56a316e01f73f8ff1fee68c8 +Author: Guus Sliepen +Date: Sun May 15 13:16:48 2011 +0200 + + Add a very primitive "top" command to tincctl. + +commit ec495b2f15fc5ae22136c226c7966caf51f643f8 +Author: Guus Sliepen +Date: Sun May 15 12:06:21 2011 +0200 + + Add an autoconf check for the curses library. + +commit 362d8a6358019cb97456c8133832f18798cea41f +Author: Guus Sliepen +Date: Sun May 15 11:59:13 2011 +0200 + + Dump traffic statistics over control sockets. + +commit f5843e7d649f4a7f72cb3fd356bc935457aa492f +Author: Guus Sliepen +Date: Sun May 15 00:42:29 2011 +0200 + + Add per-node traffic counters. + +commit ffa3a443b9f01d3ea0fcb3c4fc6928a5c695cf4a +Author: Guus Sliepen +Date: Sat May 14 22:30:23 2011 +0200 + + Several fixes for the buffer code. + +commit cdb793f687262b9f56823ca9046523a609a758af +Author: Guus Sliepen +Date: Sat May 14 19:20:56 2011 +0200 + + Remove use of bufferevent and eventbuffers, use our own buffering instead. + +commit f431fcb35f400be388a905ae0f7f50c1f5c4cd5d +Author: Guus Sliepen +Date: Sat May 14 19:15:04 2011 +0200 + + Add simple buffer management code. + + Libevent 2.0's buffer code is not completely backward compatible with 1.4's. + In order to not (mis)use it anymore, we implement it ourselves. The buffers + are automatically expanding when necessary. When consuming data from the + buffer, no memmove()s are performed. Only when adding to the buffer would + write past the end do we shift everything back to the start. + +commit 3794e551c7db9aa81405f65f7b04a9951c4120b2 +Author: Guus Sliepen +Date: Sat May 14 11:52:35 2011 +0200 + + Fix check for event initialization due to the merge. + +commit 03b7118139f57033659730afb740bf5cef7c961c +Author: Guus Sliepen +Date: Fri May 13 12:37:26 2011 +0200 + + Reorder checks for libraries to allow ./configure LDFLAGS=-static. + + OpenSSL depends on libdl and libz. When linking dynamically, libcrypto will + automatically link with the other two libraries. However, when linking + statically, these libraries need to be specified explicitly while linking. By + moving the autoconf checks for libdl and libz before those for libcrypto, we + ensure the latter test will be done with the proper libraries. + +commit ce8775000ab38229a78ecf3dc26bab008ca0f332 +Merge: 3f59a26d 5686ad80 +Author: Guus Sliepen +Date: Mon May 9 21:35:14 2011 +0200 + + Merge branch 'master' of git://tinc-vpn.org/tinc into 1.1 + + Conflicts: + NEWS + README + configure.in + doc/tincd.8.in + lib/pidfile.c + src/bsd/device.c + src/dropin.h + src/net.c + src/net_packet.c + src/node.c + src/process.c + src/tincd.c + +commit 5686ad80b545afa3de9ed2f4176a5346e289aaa8 +Author: Guus Sliepen +Date: Sun May 8 23:17:46 2011 +0200 + + Releasing 1.0.14. + +commit 0d906489f2ce9faf81dc230f7db6ab5378573554 +Author: Guus Sliepen +Date: Sun May 8 23:12:44 2011 +0200 + + Include when using intptr_t. + +commit dc887f5011834d5a9a6ec5deb8781c6bfd88c474 +Author: Guus Sliepen +Date: Sun May 8 23:12:06 2011 +0200 + + Ensure proper linking with OpenSSL with recent versions of MinGW. + +commit 67766d65f06854ee894d784f638c5c9cd2b50bca +Author: Guus Sliepen +Date: Sun May 8 21:22:20 2011 +0200 + + Update THANKS and copyright information. + +commit 6e6b037ef4fd9877aeb1d947da7364409fa8cbb7 +Author: Guus Sliepen +Date: Sun May 8 21:06:06 2011 +0200 + + Check for EVP_EncryptInit_ex instead of SHA1_Version in OpenSSL. + + The latter function disappeared, and wasn't actually used in tinc, so now we + check on a function that we do use. + +commit 257cb6ac60bb0924720de9e252cdf7f4759bf741 +Author: Guus Sliepen +Date: Sun May 8 12:40:44 2011 +0200 + + Always use the default signal handler for ABRT signals. + + This will allow coredumps to be generated when tinc is daemonized. + Also add the -kABRT option. + +commit eacb5a28fb4c1515633f2b8a206e7067bc7b8f0c +Author: Guus Sliepen +Date: Sun May 8 12:16:26 2011 +0200 + + Increase threshold for detecting two nodes with the same Name. + + In commit 4a21aabada23d1d2c8a10f54dd7248171c4ec82f, code was added to detect + contradicting ADD_EDGE and DEL_EDGE messages being sent, which is an indication + of two nodes with the same Name connected to the same VPN. However, these + contradictory messages can also happen when there is a network partitioning. In + the former case a loop happens which causes many contradictory message, while + in the latter case only a few of those messages will be sent. So, now we + increase the threshold to at least 10 of both ADD_EDGE and DEL_EDGE messages. + +commit f11c6101f30df645223920bef3eb7592de9bcb79 +Author: Julien Muchembled +Date: Thu Apr 28 13:21:55 2011 +0200 + + Fix command-line '-o' option for host configuration + + This fixes a regression introduced by commit 667b1ba while refactoring option + parsing code. + +commit 0aa86d4b8b3010522e6de8842f5bd29004ba3df6 +Author: Guus Sliepen +Date: Wed Mar 9 09:34:56 2011 +0100 + + Do not set indirect flag on edges from nodes with multiple addresses. + + Since tinc now handles UDP packets with a different source address and port + than used for TCP connections, the heuristic to treat edges as indirect when + tinc could detect that multiple addresses were used does not make sense + anymore, and can actually reduce performance. + +commit 7cf68b5e35c002511cc7468967de6a75934cc998 +Author: Guus Sliepen +Date: Fri Feb 18 23:11:43 2011 +0100 + + Prevent anything from updating our own UDP address. + + Because we don't want to keep track of that, and this will cause the node + structure from being relinked into the node tree, which results in myself + pointing to an invalid address. + +commit cdbbbfabea173894bd2fb5f28135a04ddc5e3fd7 +Author: Guus Sliepen +Date: Fri Feb 18 23:02:11 2011 +0100 + + Fix spurious misidentification of incoming UDP packets. + + When a UDP packet was received with an unknown source address/port, and if it + failed a HMAC check against known keys, it could still incorrectly assign that + UDP address to another node. This would temporarily cause outgoing UDP packets + to go to the wrong destination address, until packets from the correct address + were received again. + +commit 046d83bf91e01bc7a32e66a02758caf228bc4601 +Author: Rumko +Date: Sat Feb 12 18:22:14 2011 +0100 + + DragonFlyBSD support + + * added DragonFly BSD support + * added a check for sys/resource.h (needed on DragonFly) + +commit f017c7f98f8f68d6ca50ebe247f4115aadd93635 +Author: Guus Sliepen +Date: Mon Feb 7 18:34:55 2011 +0100 + + Add support for VDE through libvdeplug. + + When compiled with vde/device.c, tinc will connect to a vde_switch instance + instead of using a tun/tap device. + +commit 8d18cc6c4e625625a2437d26c587f9f382a0c589 +Author: Guus Sliepen +Date: Sat Jan 29 10:49:44 2011 +0100 + + Fix typo spotted by Andrew Scheller. + +commit b3731c04097e66a6b8908bb893c5da831d89c04d +Author: Guus Sliepen +Date: Wed Jan 12 20:57:14 2011 +0100 + + Proper check and dropin replacement for usleep(). + +commit 4b8a5993036fccc2108fcc2550649d9b78fb1ab7 +Author: Guus Sliepen +Date: Sun Jan 2 17:25:24 2011 +0100 + + Update the NEWS. + +commit c228da54d47657811dfb679e7f138cbba58a9f67 +Author: Guus Sliepen +Date: Sun Jan 2 17:25:03 2011 +0100 + + Update the manual. + +commit 4575c6c7dffe228ce302776022a2075b7ef37ab0 +Author: Guus Sliepen +Date: Sun Jan 2 17:24:23 2011 +0100 + + Document the behavior of "-n." + +commit 6c05bf082b1ce9acfc0ebb5c6f32c2ece41c7f80 +Author: Guus Sliepen +Date: Sun Jan 2 16:59:42 2011 +0100 + + Remove unused variables. + +commit 6a51d89cf706bcefce1861a1a66d40ef7d7db43b +Author: Guus Sliepen +Date: Sun Jan 2 16:55:42 2011 +0100 + + Replace bogus #else with #endif. + + Found by cppcheck, which complained about lenin not being initialized, but the + real problem is that reading packets would fail when using code compiled with + --tunemu on a normal tun device. + +commit d7636352ce359e807b392a6e5ac0a6aeff4a63d2 +Author: Guus Sliepen +Date: Sun Jan 2 16:52:36 2011 +0100 + + Limit field width when scanning PID file. + + Cppcheck warns that scanf() might otherwise crash when presented with a huge, + bogus PID file. + +commit 3ce5e292da8bab3a1316faf1ca18625f05074467 +Author: Guus Sliepen +Date: Sun Jan 2 16:50:24 2011 +0100 + + Close all filedescriptors in Solaris close_device(). + +commit f99661a4ca5bacff47239ce7978b9c9948917c54 +Author: Guus Sliepen +Date: Sun Jan 2 15:02:23 2011 +0100 + + Always send MTU probes at least once every PingInterval. + + Before, if MTU probes failed, tinc would stop sending probes until the next + time keys were regenerated (by default, once every hour). Now it continues to + send them every PingInterval, so it recovers faster from temporary failures. + +commit cac0a5c651535e8317839b0deff1ee98086a8184 +Author: Guus Sliepen +Date: Sat Nov 20 14:31:11 2010 +0000 + + Use setpriority() instead of nice() on UNIX-like systems. + + The return value of nice() can not reliably indicate errors. The return value + of the setpriority() call is well-defined. + +commit 3f59a26d8098b8b0902b8746715508360b347f47 +Author: Guus Sliepen +Date: Fri Nov 19 12:26:20 2010 +0000 + + Do not try to dereference myself->connection->config_tree. + + This was a bug introduced due to an incomplete merge (commit + ff71f289022ccb91abc2726f16522d55b5ccf0f6). + +commit 886a6f61a1f4cc48a77b42d10f34f9126377d904 +Merge: 23dddc25 d91903ef +Author: Guus Sliepen +Date: Fri Nov 19 12:22:48 2010 +0000 + + Merge branch 'master' into 1.1 + + Conflicts: + src/net_packet.c + src/openssl/rsagen.h + src/protocol_auth.c + src/protocol_key.c + +commit d91903ef3c2a1f4481ae8757bb2b14282f2b7e68 +Author: Guus Sliepen +Date: Tue Nov 16 17:28:41 2010 +0100 + + Attribution for Brandon Black. + +commit e764ff7be9949c91865aff72844357e76ae6dd78 +Author: Guus Sliepen +Date: Tue Nov 16 16:45:36 2010 +0100 + + Fix variable length array declaration. + +commit 5eb0440110f99f0a49838cc00a0686c7a7595663 +Author: Guus Sliepen +Date: Sat Nov 13 21:36:51 2010 +0100 + + Free replay window when freeing a node_t. + +commit a9445e38f25bd24eca289768fc46e44e36b842ac +Author: Guus Sliepen +Date: Sat Nov 13 21:34:59 2010 +0100 + + Fix warning message when setting SO_RCVBUF or SO_SNDBUF fails. + +commit 0d61d4ae1358553fc8dde350747542f137f5cb8b +Author: Brandon L Black +Date: Sat Nov 13 12:05:51 2010 -0600 + + Improved handling of queue-jumping packets on receive + +commit 23acc19bc090051156ad895caed61848f5afb144 +Author: Brandon L Black +Date: Sat Nov 13 12:05:50 2010 -0600 + + Configurable ReplayWindow size, zero disables + +commit 8dfe1b374e165ecba5d3ae324ee834d337476be8 +Author: Brandon L Black +Date: Sat Nov 13 12:05:49 2010 -0600 + + Configurable SO_RCVBUF/SO_SNDBUF for the UDP socket + +commit 3f410e2f8f7c365630f226adf4904935698f9e0d +Author: Brandon L Black +Date: Sat Nov 13 12:05:48 2010 -0600 + + Experimental IFF_ONE_QUEUE support for Linux + +commit 9e3ca397735077f85bbde48c36e1b3e0fa950988 +Author: Guus Sliepen +Date: Sat Nov 13 15:55:38 2010 +0100 + + Use variable length arrays instead of alloca(). + +commit e2e6ec8050274b0a8678d6fc263e7dc4ef66feae +Author: Guus Sliepen +Date: Sat Nov 13 15:50:39 2010 +0100 + + Provide usleep() for Windows. + +commit 23dddc25930bc9033e5a2ac659376032aff44d82 +Author: Guus Sliepen +Date: Sat Nov 13 15:46:19 2010 +0100 + + Link tincctl with dropin.o. + +commit a22041922f160667573e9a5ae3f4195e1668906a +Merge: 8b70c5be 930bf74f +Author: Guus Sliepen +Date: Fri Nov 12 16:15:29 2010 +0100 + + Merge branch 'master' into 1.1 + + Conflicts: + doc/tincd.8.in + lib/pidfile.c + src/graph.c + src/net.c + src/net.h + src/net_packet.c + src/net_setup.c + src/net_socket.c + src/netutl.c + src/node.c + src/node.h + src/protocol_auth.c + src/protocol_key.c + src/tincd.c + +commit 930bf74fbe5ce8363b6cc2ae3a3e960e910e0996 +Author: Guus Sliepen +Date: Fri Nov 12 11:38:05 2010 +0100 + + Don't use strlen() on a NULL pointer. + + A bug introduced in commit 667b1bac77b134cf32c98d5dc25619e8c3303f52 caused tinc + to crash on startup. + +commit a07aa92176571eb7f063708640d0d486280808ef +Author: Guus Sliepen +Date: Fri Nov 12 11:33:01 2010 +0100 + + Add short options -R and -U to the tincd(8) manpage. + +commit 66b7aea294896a99df289231143a506b422b994c +Author: Guus Sliepen +Date: Tue Nov 2 14:23:43 2010 +0100 + + Read error counter must be static. + +commit a91bf2dfcd0f5857905e59da7d944654e0875503 +Author: Guus Sliepen +Date: Tue Nov 2 14:18:35 2010 +0100 + + Quit when there are too many consecutive errors on the tun/tap device. + + Although transient errors sometimes happen on the tun/tap device (for example, + if the kernel is temporarily out of buffer space), there are situations where + the tun/tap device becomes permanently broken. Instead of endlessly spamming + the syslog, we now sleep an increasing amount of time between consecutive read + errors, and if reads still fail after 10 attempts (approximately 3 seconds), + tinc will quit. + +commit aca70cd3c3fe787e62c618849e43f67b3870ac20 +Author: Michael Tokarev +Date: Sun Oct 24 15:23:10 2010 +0400 + + Treat netname="." in a special way. + + Treat netname "." in a special way as if there was no netname + specified. Before, f.e. tincd -n. -k didn't work as it tried + to open /var/run/tinc-.pid. Now -n. works as if there was no + -n option is specified. + + Signed-Off-By: Michael Tokarev + +commit 5f729f76f5a63114df582fc29f4189140c1e5ead +Author: Guus Sliepen +Date: Fri Oct 22 22:46:44 2010 +0200 + + Remove unused variables. + + These were caused by commit 667b1bac77b134cf32c98d5dc25619e8c3303f52. + +commit 20ae7dd8c12390f7360eb28cc17e1b8a8a706b06 +Author: Guus Sliepen +Date: Fri Oct 22 22:43:50 2010 +0200 + + Abort disabling old PEM keys on I/O errors. + +commit a08462bf845973016e061b8ca1233142d80416f6 +Author: Guus Sliepen +Date: Fri Oct 22 22:42:21 2010 +0200 + + Ensure there is a newline character before a PEM key is written. + +commit c6ccbadfcf93a7bd4a88dee8ff146b4db7f85e71 +Author: Guus Sliepen +Date: Fri Oct 22 13:40:04 2010 +0200 + + Attribution for Timothy Redaelli. + +commit 1c2cd7ed273ee1538ff8a13d036c68aa9992c4aa +Author: Guus Sliepen +Date: Fri Oct 22 13:17:42 2010 +0200 + + Attribution for Julien Muchembled. + +commit 667b1bac77b134cf32c98d5dc25619e8c3303f52 +Author: Guus Sliepen +Date: Fri Oct 22 13:06:06 2010 +0200 + + Remove duplicate command-line option parsing. + + Also fix parsing of command-line host configuration options for the local node. + +commit ff71f289022ccb91abc2726f16522d55b5ccf0f6 +Author: Guus Sliepen +Date: Fri Oct 22 12:47:12 2010 +0200 + + Merge local host configuration with server configuration. + + With some exceptions, tinc only accepted host configuration options for the + local node from the corresponding host configuration file. Although this is + documented, many people expect that they can also put those options in + tinc.conf. Tinc now internally merges the contents of both tinc.conf and the + local host configuration file. + +commit 8c3105283ac53f8cc9cc4dde25957ec1cf6b53a0 +Author: Julien Muchembled +Date: Fri Sep 3 13:34:22 2010 +0200 + + New '-o' option to configure server or hosts from command line + + Options given on the command line have precedence over configuration from files. + + This can be useful, for example, for a roaming node, for which 'ConnectTo' and + .Address depends on its location. + +commit 4b6a9f1c1f645ce5989692655337d9e23ca28648 +Author: Guus Sliepen +Date: Fri Jun 4 16:03:19 2010 +0200 + + Do not append an address to ANS_KEY messages if we don't know any address. + + This would let tinc raise an exception when an ANS_KEY request crossed a + DEL_EDGE request for the node sending the key. + +commit 798fa2f04c52b0639713f74b1195847bec40c16a +Author: Guus Sliepen +Date: Fri Jun 4 15:04:08 2010 +0200 + + Use 64 bit counters to keep track of bytes sent/received from the virtual network interface. + +commit 4a21aabada23d1d2c8a10f54dd7248171c4ec82f +Author: Guus Sliepen +Date: Fri Jun 4 14:53:52 2010 +0200 + + Detect and prevent two nodes with the same Name being on the VPN simultaneously. + + In this situation, the two nodes will start fighting over the edges they announced. + When we have to contradict both ADD_EDGE and DEL_EDGE messages, we log a warning, + and with 25% chance per PingTimeout we quit. + +commit dbf3d168b720045328d476f3b9e5f5e45b4ab6de +Author: Guus Sliepen +Date: Fri May 7 12:24:49 2010 +0200 + + Use strrchr() insteaad of rindex(). + + The latter function is deprecated, some build environments do not support. + +commit eda71798749e8b0abf5e8b3cbc11da82aa607f00 +Author: Timothy Redaelli +Date: Tue May 4 15:43:48 2010 +0200 + + Fix warnings under BSD + +commit df985256a766ee90f2fa4269b95fa0565c969dda +Author: Timothy Redaelli +Date: Tue May 4 00:27:44 2010 +0200 + + Fix warnings showed using -D_FORTIFY_SOURCE=2 + +commit f5122ccecee095b9185b2324dea7bcd9655462ee +Author: Guus Sliepen +Date: Sat May 1 15:39:59 2010 +0200 + + Fix all warnings when compiling with mingw64. + +commit ef92a5725c47c6e8e801e07190dd7dd3f9cb3a17 +Author: Guus Sliepen +Date: Sat May 1 15:39:03 2010 +0200 + + OpenSSL 1.0.0 compiled for 64 bit Windows requires linking with -lcrypt32. + +commit 0fdd7da52077d77a11a3646eb3e7d5b6ffa178e8 +Author: Guus Sliepen +Date: Sat May 1 15:38:04 2010 +0200 + + Use intptr_t instead of long to store a pointer. + +commit c94ede3b8708cdf105a3fecfc119a558e1583f27 +Author: Guus Sliepen +Date: Sat May 1 15:37:11 2010 +0200 + + Define WINVER before including any other header file on Windows. + +commit 8b70c5be9bc762d81354f9cd77c3748a44a4956d +Author: Guus Sliepen +Date: Fri Apr 30 23:18:22 2010 +0200 + + Remove obsolete lib/ directory. + +commit ee427cac0d04c60d09cc235c04664eab8b0c6527 +Author: Guus Sliepen +Date: Fri Apr 30 23:13:02 2010 +0200 + + Do not try to free NULL pointers. + +commit 113458c2864ec8c046ab7d63ff1b417252c8e4df +Author: Guus Sliepen +Date: Fri Apr 30 23:11:48 2010 +0200 + + Use correct digest length when checking a received key. + +commit 76b41ba20dc9783ff0d21dd738739a81d62142e7 +Author: Guus Sliepen +Date: Sat Apr 17 12:33:36 2010 +0200 + + Add missing return statement. + +commit 2911af6e23d0dba6d771fcd590551a84bd9dc932 +Author: Guus Sliepen +Date: Sat Apr 17 12:33:15 2010 +0200 + + Fix merge of commit 4a0b9981513059755b9fd15b38fc198f46a0d6f2. + +commit 79e46d08a46f2fef2ee4e8eac7ba487007160564 +Merge: 4ce4af4c 4766359e +Author: Guus Sliepen +Date: Sat Apr 17 12:21:53 2010 +0200 + + Merge branch 'master' into 1.1 + + Conflicts: + NEWS + README + configure.in + src/net.c + src/net.h + +commit 4ce4af4c712c80d08630767ec34787253da1021b +Author: Guus Sliepen +Date: Sat Apr 17 12:03:08 2010 +0200 + + Fix experimental GUI when reading hexadecimal values. + +commit 4766359e1426bdf1383c898d6103d8760e5e296d +Author: Guus Sliepen +Date: Sat Apr 17 12:01:38 2010 +0200 + + Fix reading configuration files that do not end with a newline. Again. + +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 e49891e188f618a0e98f1d30bcbf240286e8ad5c +Author: Sven-Haegar Koch +Date: Wed Mar 31 03:56:53 2010 +0200 + + Fixed metadata protokoll corruption on forwarded requests + + When forwarding a metadata request through forward_request() we were + adding the required newline char to our buffer, but then sending the + data without it - this results in the forwarded request and the next one + to be garbled together. + + Additionally while at it add a warning comment that request string is + not zero terminated anymore after a call to the forward_request() + function - for now this is ok as it is not used by any caller after this. + +commit 0310deb225cad21c458fb32fd589027e3f844735 +Author: Sven-Haegar Koch +Date: Fri Mar 26 17:25:18 2010 +0100 + + Demote all LOG_EMERG to LOG_ERR, spamming all xterms is bad. + +commit d5654f568dcaf81341395b52b2711f68c0417ec6 +Author: Sven-Haegar Koch +Date: Fri Mar 26 16:54:13 2010 +0100 + + README.git: tinc 1.1 needs libevent + +commit 685509ffe10d1bf9c409e5ba90f46cd747f2d9cd +Author: Sven-Haegar Koch +Date: Sun Mar 28 17:51:26 2010 +0200 + + Function flush_meta() does not exist anymore. + +commit c6d2b9d734859ccbd9582b28351983a12b04abb0 +Author: Sven-Haegar Koch +Date: Fri Mar 26 17:07:30 2010 +0100 + + Add missing AC_CHECK_HEADERS([dirent.h]) to configure.in + +commit ffa1dc73dcd62a856325641972a13d398aa8121c +Author: Sven-Haegar Koch +Date: Fri Mar 26 17:18:04 2010 +0100 + + Fixed 1.0 miss-merges + +commit 103543aa2c15d9f1e2aa313a2e593a7524cce484 +Merge: 35b1c250 29235491 +Author: Sven-Haegar Koch +Date: Fri Mar 26 16:51:03 2010 +0100 + + Merge branch 'master' into 1.1 + + Conflicts: + NEWS + README + configure.in + have.h + src/conf.c + src/conf.h + src/net.c + src/net_packet.c + src/protocol_key.c + src/protocol_subnet.c + src/route.c + src/tincd.c + +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 + + 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 35b1c25093a478d20e01f0ff391c9cdc9c41c2b8 +Author: Guus Sliepen +Date: Thu Dec 31 13:19:13 2009 +0100 + + Move source from lib/ to src/. + + The utility functions in the lib/ directory do not really form a library. + Also, now that we build two binaries, tincctl does not need everything that was + in libvpn.a, so it is wasteful to link to it. + +commit 41497246eeccbcc417f93c2ae087e927751c6914 +Author: Guus Sliepen +Date: Thu Dec 31 13:09:14 2009 +0100 + + Remove unused AVL tree library. + +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 36261650024ba8e18f9c77396f1d7a4e51f20602 +Author: Guus Sliepen +Date: Sat Dec 19 23:23:25 2009 +0100 + + Do not use hardcoded cipher block length when padding. + +commit f542ef8f9e645bf30e11e196dd768fac4f957eac +Author: Guus Sliepen +Date: Sat Dec 19 22:17:39 2009 +0100 + + Fix alignment of results of RSA operations when using libgcrypt. + + If the result of an RSA encryption or decryption operation can be represented + in less bytes than given, gcry_mpi_print() will not add leading zero bytes. Fix + this by adding those ourself. + +commit 4c68a8cb60eb0a4c05d9ce98963b930a976b55ee +Author: Guus Sliepen +Date: Sat Dec 19 20:53:48 2009 +0100 + + Do not consider unreachable nodes when trying to determine packet origin. + +commit 74e50d52e0e23c9dd1e21fb447f1e1a59d02d0b2 +Author: Guus Sliepen +Date: Sat Dec 19 20:52:19 2009 +0100 + + recv() and recvfrom() return int, do not prematurely cast the return value. + +commit 0bfd69a2736cb98470b47c1f6cba617b58bb86ef +Author: Guus Sliepen +Date: Sat Dec 19 20:26:30 2009 +0100 + + Fix reading raw RSA keys with libgcrypt. + +commit 0ff44fc2417217d542bf0e9a7ecfd20020893bc7 +Author: Guus Sliepen +Date: Sat Dec 19 20:10:38 2009 +0100 + + Reinitialise block cipher IV each time we encrypt a packet when using libgcrypt. + +commit 3c90be7678566203d38624c4a6fe3affaffbe5e3 +Author: Guus Sliepen +Date: Sat Dec 19 18:57:54 2009 +0100 + + Fix block cipher padding when using libgcrypt. + +commit c845bc109c85e6fb350096c63e13ef8e617ee29b +Author: Guus Sliepen +Date: Fri Dec 18 01:15:25 2009 +0100 + + Fix packet authentication. + + This wasn't working at all, since we didn't do HMAC but just a plain hash. + Also, verification of packets failed because it was checking the whole packet, + not the packet minus the HMAC. + +commit 10d609b1f0dd9eeb024cd40359683d48542aecbf +Author: Guus Sliepen +Date: Wed Dec 16 21:18:21 2009 +0100 + + Start of a GUI for tinc. + +commit 55ef2f806f9840103bceb472564a711b22e73d58 +Author: Guus Sliepen +Date: Wed Dec 16 21:16:56 2009 +0100 + + Allow connections to be closed. + + This only closes existing meta connections, it may not affect node + reachability. + +commit f12c36afd5293ddbecccf13f36edb8d36e56f040 +Author: Guus Sliepen +Date: Mon Dec 14 21:25:06 2009 +0100 + + Include missing header files and source directories. + +commit 2a410cd26d25cc01b96d255644df3ad138eae776 +Author: Guus Sliepen +Date: Mon Dec 14 21:20:56 2009 +0100 + + Do not include OpenSSL headers directly. + +commit 5d78e497f1c352c8d490eed1d44d128523a34572 +Author: Guus Sliepen +Date: Fri Dec 11 22:38:06 2009 +0100 + + Fix compiler warnings. + +commit d6c50eb73ad49bd2eac67214995dff76b7a20661 +Merge: fec14791 369fe1ab +Author: Guus Sliepen +Date: Fri Dec 11 22:31:27 2009 +0100 + + Merge branch 'master' into 1.1 + + Conflicts: + src/subnet.c + +commit fec14791e869180bb7994ca38ca7006cc2e957fb +Author: Guus Sliepen +Date: Fri Dec 11 22:24:07 2009 +0100 + + Only call ioctlsocket() on Windows. + +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 edebf579f2ea29e6e84360cb13731f5858a1555b +Author: Guus Sliepen +Date: Sat Nov 7 23:43:25 2009 +0100 + + Use the TCP socket infrastructure for control sockets. + + The control socket code was completely different from how meta connections are + handled, resulting in lots of extra code to handle requests. Also, not every + operating system has UNIX sockets, so we have to resort to another type of + sockets or pipes for those anyway. To reduce code duplication and make control + sockets work the same on all platforms, we now just connect to the TCP port + where tincd is already listening on. + + To authenticate, the program that wants to control a running tinc daemon must + send the contents of a cookie file. The cookie is a random 256 bits number that + is regenerated every time tincd starts. The cookie file should only be readable + by the same user that can start a tincd. + + Instead of the binary-ish protocol previously used, we now use an ASCII + protocol similar to that of the meta connections, but this can still change. + +commit c388527e341658dc915dd67c90bbc9b52b8539c0 +Author: Guus Sliepen +Date: Sat Nov 7 16:09:56 2009 +0100 + + Small fixes to get really working control sockets on Windows. + +commit 5c5548fc7185cc1462602dadcd39a53cef481d29 +Author: Guus Sliepen +Date: Sat Nov 7 14:35:48 2009 +0100 + + Better integration of libevent in build system. + + Since event.h is not part of tinc, we include it in have.h were all other + system header files are included. We also ensure -levent comes before -lgdi32 + when compiling with MinGW, apparently it doesn't work when the order is + reversed. + +commit 075264a9e18f9fd58cad044c064a91557e9ed429 +Author: Guus Sliepen +Date: Thu Nov 5 23:29:28 2009 +0100 + + Make sure the 1.1 branch compiles in a MinGW environment. + + UNIX domain sockets, of course, don't exist on Windows. For now, when compiling + tinc in a MinGW environment, try to use a TCP socket bound to localhost as an + alternative. + +commit 08615e420b2dd5054dd978bf53c88b8dde6e4788 +Author: Guus Sliepen +Date: Thu Nov 5 00:02:42 2009 +0100 + + Handle PKCS#5 padding in the gcrypt backend. + +commit d9b2ac6767f85927a26e2b95bba69c052ac503ac +Author: Guus Sliepen +Date: Thu Nov 5 00:01:25 2009 +0100 + + Handle truncated message authentication codes with gcrypt. + + Commit 4124b9682f8f890acb25d0c92f2583eef670274a did not update the gcrypt + backend. + +commit c4afc481541bff4db7f57c81796b7a5f61cdb1b5 +Author: Guus Sliepen +Date: Wed Nov 4 16:19:08 2009 +0100 + + Use %x instead of %lx where appropriate. + + Some conversions were not properly merged from the master branch. + +commit 37ccb325af5c7865eb16716780121a8a6dce8abd +Author: Guus Sliepen +Date: Wed Nov 4 16:18:08 2009 +0100 + + Don't enable device events when there is no valid filedescriptor. + +commit 108b238915c5f58b3d94ab433dc5d04e064c2b11 +Merge: 761517c2 44834d03 +Author: Guus Sliepen +Date: Mon Nov 2 14:24:27 2009 +0100 + + Merge branch 'master' into 1.1 + + Conflicts: + NEWS + README + configure.in + doc/tinc.texi + doc/tincd.8.in + src/Makefile.am + src/connection.c + src/edge.c + src/meta.c + src/net.c + src/net.h + src/net_packet.c + src/net_setup.c + src/net_socket.c + src/node.c + src/openssl/rsagen.h + src/protocol_auth.c + src/protocol_edge.c + src/subnet.c + +commit 44834d030464bbe1f7733caba8d96c678f1d6cf2 +Author: Guus Sliepen +Date: Sun Nov 1 16:24:39 2009 +0100 + + Releasing 1.0.11. + +commit d331f04e4598824afc7de33ac1228cf441ae9872 +Author: Guus Sliepen +Date: Sun Nov 1 15:57:28 2009 +0100 + + Start a tinc service if it already exists. + +commit 6f6f426b353596edca77829c0477268fc2fc1925 +Author: Guus Sliepen +Date: Tue Oct 27 23:53:49 2009 +0100 + + Fast handoff of roaming MAC addresses. + + In switch mode, if a known MAC address is claimed by a second node before it + expired at the first node, it is likely that this is because a computer has + roamed from the LAN of the first node to that of the second node. To ensure + packets for that computer are routed to the second node, the first node should + delete its corresponding Subnet as soon as possible, without waiting for the + normal expiry timeout. + +commit e00b44cb98e4d50a0d426048ba01dbd80bcb5941 +Author: Guus Sliepen +Date: Sun Oct 25 01:40:07 2009 +0200 + + Move socket error interpretation to utils.h. + +commit c11dc8079b60d9f8c5b1c7e8fecd90d0fac5a20c +Author: Guus Sliepen +Date: Sun Oct 25 00:50:09 2009 +0200 + + Use WSAGetLastError() to determine cause of network errors on Windows. + + This reduces log spam and lets path MTU discovery work faster. + +commit 1bca167b7e24a9cb00ad6130c24f0bb60e208f1f +Author: Michael Tokarev +Date: Sun Oct 18 21:27:24 2009 +0400 + + Remove localedir leftovers. + +commit c3acae034c4da2d1c70f31b852b14ca098c0eeb9 +Author: Guus Sliepen +Date: Sat Oct 24 22:32:35 2009 +0200 + + Use IP_DONTFRAGMENT instead of IP_MTU_DISCOVER on Windows. + + This ensures the DF bit on outgoing UDP packets gets set on Windows when path + MTU discovery is enabled, reducing fragmentation. + +commit 242c4e2ca67d0b5c78dfe6e68a5ddcd27be1de99 +Author: Guus Sliepen +Date: Sat Oct 24 21:53:01 2009 +0200 + + Forward packets to not directly reachable hosts via UDP if possible. + + If MTU probing discovered a node was not reachable via UDP, packets for it were + forwarded to the next hop, but always via TCP, even if the next hop was + reachable via UDP. This is now fixed by retrying to send the packet using + send_packet() if the destination is not the same as the nexthop. + +commit d922db253cd098bc038449e5c591cc94c1019952 +Author: Guus Sliepen +Date: Sat Oct 24 21:35:40 2009 +0200 + + Make maxmtu equal to minmtu when fixing the path MTU to a node. + + This ensures MTU probes used to ping nodes are not too large, and prevents + restarting MTU probing unnecessarily. + +commit a8f7fccbc2b5f1c4c39fc2804abaa358b31a5080 +Author: Guus Sliepen +Date: Sat Oct 24 21:32:06 2009 +0200 + + Always reply to MTU probes via UDP. + + It could sometime happen that a node would return MTU probes via TCP, which + does not make a lot of sense. + +commit cddcdc9af34afb388a8e4bdfff6882f568b98313 +Author: Guus Sliepen +Date: Sat Oct 24 20:54:44 2009 +0200 + + Allow UDP packets with an address different from the corresponding TCP connection. + +commit 5cbddc68bade0d1f8ded1b784bb27bb44c5dc5dc +Author: Guus Sliepen +Date: Sat Oct 24 16:15:24 2009 +0200 + + Use uint32_t instead of long int for connection options. + + Options should have a fixed width anyway, but this also fixes a possible MinGW + compiler bug where %lx tries to print a 64 bit value, even though a long int is + only 32 bits. + +commit 468f393c4fabf9223a1bd15adfb3906cde90d547 +Author: Guus Sliepen +Date: Sat Oct 24 16:05:12 2009 +0200 + + Add dummy device. + +commit b6543af7626403516b5fc54c24b11d3a242a2992 +Author: Guus Sliepen +Date: Tue Oct 20 22:39:07 2009 +0200 + + Clarify and increase level of log message about MTU probes to unreachable nodes. + +commit 43a6e786648fb666a9b7be8f05c8a173031c9110 +Author: Guus Sliepen +Date: Tue Oct 20 22:33:16 2009 +0200 + + Handle weighted Subnets in switch and hub modes. + + We now handle MAC Subnets in exactly the same way as IPv4 and IPv6 Subnets. + This also fixes a problem that causes unncessary broadcasting of unicast + packets in VPNs where some daemons run 1.0.10 and some run other versions. + +commit 3a925479c2883a6a9711f7b6931863d7f2a2c09b +Author: Guus Sliepen +Date: Tue Oct 20 22:22:59 2009 +0200 + + Starting to work towards 1.0.11. + +commit 35af4051c3749cd2c2137a7eb57171a1fbb12af7 +Author: Guus Sliepen +Date: Tue Oct 20 22:14:47 2009 +0200 + + Fix a possible crash when sending the HUP signal. + + When the HUP signal is sent while some outgoing connections have not been made + yet, or are being retried, a NULL pointer could be dereferenced resulting in + tinc crashing. We fix this by more careful handling of outgoing_ts, and by + deleting all connections that have not been fully activated yet at the HUP + signal is received. + +commit 8c267d3d558ac97a4ce7381a37abb6cc4b46b133 +Author: Guus Sliepen +Date: Sun Oct 18 16:45:13 2009 +0200 + + Releasing 1.0.10. + +commit 3849de9a331ad132ed9d01c9f0cac47196624b3e +Author: Guus Sliepen +Date: Sun Oct 18 16:44:32 2009 +0200 + + Fix description of the WEIGHT environment variable. + +commit 87364c16564c897b1a2d306615804d68ea5a9ba1 +Author: Guus Sliepen +Date: Sun Oct 18 14:22:20 2009 +0200 + + Include missing header. + +commit c7fdc7d5b8d728c744b13a823e7eef9d2432c61e +Author: Guus Sliepen +Date: Mon Oct 12 23:51:57 2009 +0200 + + Remove debugging message when reading packets from a BSD device. + + This was inadvertently introduced by commit + 4a5d42178cc0954efba8b24058da9c70cc77c35a. + +commit ec4c8bcb18c1f463cf4544126e027fc8ec9b3a39 +Author: Guus Sliepen +Date: Mon Oct 12 22:14:47 2009 +0200 + + Allow the cloning /dev/tap interface to be used on FreeBSD and NetBSD. + + This device works like /dev/tun on Linux, automatically creating a new tap + interface when a program opens it. We now pass the actual name of the newly + created interface in $INTERFACE. + +commit 92b8abc921dd15b710f67335562210eb713fbb39 +Author: Guus Sliepen +Date: Sun Oct 11 18:57:58 2009 +0200 + + Use MTU probes to regularly ping other nodes over UDP. + + This keeps NAT mappings for UDP alive, and will also detect when a node is not + reachable via UDP anymore or if the path MTU is decreasing. Tinc will fall back + to TCP if the node has become unreachable. + + If UDP communication is impossible, we stop sending probes, but we retry if it + changes its keys. + + We also decouple the UDP and TCP ping mechanisms completely, to ensure tinc + properly detects failure of either method. + +commit 927064e5fd0ebf29a7ea768a7f9c4226da626a72 +Author: Guus Sliepen +Date: Sun Oct 11 15:46:52 2009 +0200 + + Small updates to the documentation. + + Mention that TCPOnly is not necessary anymore since tinc will autodetect + whether it can send via UDP or not. Also mention the WEIGHT environment + variable and the new default value (2048 bits) of RSA keys. + +commit 2c30af6c90926340a89748c63cc453b1c0b5a589 +Author: Guus Sliepen +Date: Sun Oct 11 14:20:14 2009 +0200 + + Ensure that the texinfo manual can be converted to HTML. + + The top node was made conditional with the @iftex command, since it should not + appear in PostScript and PDF output. However, it is still necessary for + texi2html, so we have to use @ifnottex instead. + + Texi2html also complains about the use of @cindex in the copyright statement, + so we remove that. + +commit a4f132770dc136d456c67b01d209e73f5f4d7a65 +Author: Guus Sliepen +Date: Sun Oct 11 13:56:04 2009 +0200 + + Revert "Raise default crypto algorithms to AES256 and SHA256." + + Although it would be better to have the new defaults, only the most recent + releases of most of the platforms supported by tinc come with a version of + OpenSSL that supports SHA256. To ensure people can compile tinc and that nodes + can interact with each other, we revert the default back to Blowfish and SHA1. + + This reverts commit 4bb3793e38b7c7f24dd308801e7f6dbb02cf02d2. + +commit 2762509be179dcb21d855f3d6f90d3ee686e3910 +Author: Guus Sliepen +Date: Sun Oct 11 13:54:05 2009 +0200 + + Remove code duplication when checking ADD_EDGE/DEL_EDGE messages. + +commit 5cddf5e52aeb20e50c887356ad23aec354e04151 +Author: Guus Sliepen +Date: Sun Oct 11 13:51:10 2009 +0200 + + Don't disconnect clients in TunnelServer mode who send unauthorised ADD_SUBNETs. + + So that we are liberal in what we accept. + +commit 430c90412c521c534113b3c4e5fc883e9b7ecff0 +Author: Borg +Date: Sat Oct 3 13:06:00 2009 +0200 + + Removed last gettext function. + +commit 3282375f4d64d9402141ac4bf142629ec2e1cd53 +Author: Guus Sliepen +Date: Tue Sep 29 16:25:20 2009 +0200 + + Remove autogenerated files from EXTRA_DIST. + + Apparently they were once necessary, but autoconf now includes them + automatically. Some of them are not used anymore, and this caused make dist to + fail. + +commit 761517c21c37a808a19b487aa116c3c19439feca +Author: Guus Sliepen +Date: Tue Sep 29 15:33:58 2009 +0200 + + Update FSF address in files not covered by the merge. + +commit 07a560eab66b575f382428a956550817697e25e2 +Author: Guus Sliepen +Date: Tue Sep 29 15:19:55 2009 +0200 + + Drop localisation and checkpoint tracing in files not covered by the merge. + +commit 7ea85043ac1fb2096baea44f6b0af27ac0d0b2cf +Merge: f1fec466 9a2b0f88 +Author: Guus Sliepen +Date: Tue Sep 29 14:55:29 2009 +0200 + + Merge branch 'master' into 1.1 + + Conflicts: + NEWS + configure.in + lib/Makefile.am + lib/pidfile.c + lib/pidfile.h + lib/utils.c + po/POTFILES.in + po/nl.po + src/Makefile.am + src/bsd/device.c + src/conf.c + src/connection.c + src/cygwin/device.c + src/edge.c + src/event.c + src/graph.c + src/linux/device.c + src/meta.c + src/mingw/device.c + src/net.c + src/net_packet.c + src/net_setup.c + src/net_socket.c + src/netutl.c + src/node.c + src/process.c + src/protocol.c + src/protocol_auth.c + src/protocol_edge.c + src/protocol_key.c + src/protocol_misc.c + src/protocol_subnet.c + src/raw_socket/device.c + src/route.c + src/solaris/device.c + src/subnet.c + src/tincd.c + src/uml_socket/device.c + +commit 9a2b0f88a9cae753ebc81c939d01403178b18a35 +Author: Guus Sliepen +Date: Sat Sep 26 12:51:52 2009 +0200 + + Update the NEWS. + +commit 46e481dc945c5572eb6091a3660f6bf258ee0cfa +Author: Guus Sliepen +Date: Fri Sep 25 21:14:56 2009 +0200 + + Add more authors to the copyright headers. + + Git's log and blame tools were used to find out which files had significant + contributions from authors who sent in patches that were applied before we used + git. + +commit 4c85542894f7fca823b119b05e07179deb24229a +Author: Guus Sliepen +Date: Fri Sep 25 00:54:07 2009 +0200 + + Drop support for localisation. + + Localised messages don't make much sense for a daemon, and there is only the + Dutch translation which costs time to maintain. + +commit a227843b739d279b63adcf3736ebb03d856080c4 +Author: Guus Sliepen +Date: Fri Sep 25 00:33:04 2009 +0200 + + Remove checkpoint tracing. + + This feature is not necessary anymore since we have tools like valgrind today + that can catch stack overflow errors before they make a backtrace in gdb + impossible. + +commit 5dde6461a321ee47b06e33f8203f2acf00a31a51 +Author: Guus Sliepen +Date: Fri Sep 25 00:14:03 2009 +0200 + + K&R style braces. + + This is essentially commit f02d3ed3e135b5326003e7f69f8331ff6a3cc219 from the + 1.1 branch, making it easier to merge between master and 1.1. + +commit ab7c61b06f6c6e991225f2fcc32d02b8e1084aee +Author: Guus Sliepen +Date: Fri Sep 25 00:01:00 2009 +0200 + + Update the address of the Free Software Foundation in all copyright headers. + +commit 0e6856b1379e278aa5ed116d0911851339a6064c +Author: Guus Sliepen +Date: Thu Sep 24 23:42:30 2009 +0200 + + Remove Ivo's old email addresses. + +commit c217d214f4f071c235bc7c463a1da6124e2570a6 +Author: Guus Sliepen +Date: Thu Sep 24 23:39:16 2009 +0200 + + Remove all occurences of $Id$. + +commit c23fcf555ee4b69f03b76a0ffb731c3a475a77e7 +Author: Guus Sliepen +Date: Thu Sep 24 23:29:46 2009 +0200 + + Update copyright information. + + - Update year numbers in copyright headers. + - Add copyright information for Michael Tokarev and Florian Forster to the + copyright headers of files to which they have contributed significantly. + - Mention Michael and Florian in AUTHORS. + - Mention that tinc is GPLv3 or later if compiled with the --enable-tunemu + flag. + +commit f1fec466e232c00c668422014029dce9114d3add +Author: Guus Sliepen +Date: Wed Sep 16 23:43:19 2009 +0200 + + Add a better autoconf check for libevent. + +commit 4bdf0e80ee4cd0d40eb6522dab05df9346a5b3d0 +Author: Guus Sliepen +Date: Wed Sep 16 20:28:30 2009 +0200 + + Replace asprintf()s not covered by the merge to xasprintf(). + +commit 1cbddbd573d786f6b2bf9812dda89d1ea5b7e021 +Author: Guus Sliepen +Date: Wed Sep 16 20:17:11 2009 +0200 + + Use correct format specifiers. + +commit 2f97bdb46b1ed0a669619e0b9acf76f43dfa648b +Author: Guus Sliepen +Date: Wed Sep 16 20:16:54 2009 +0200 + + Add missing #include. + +commit 075e6828a7533e7daa790225f17aa6bb39703278 +Merge: 9b129c07 b5ccce29 +Author: Guus Sliepen +Date: Wed Sep 16 19:55:47 2009 +0200 + + Merge branch 'master' into 1.1 + + Conflicts: + have.h + lib/dropin.c + lib/fake-getaddrinfo.c + lib/pidfile.c + src/Makefile.am + src/bsd/device.c + src/conf.c + src/connection.c + src/connection.h + src/graph.c + src/mingw/device.c + src/net.c + src/net_setup.c + src/node.c + src/protocol_key.c + src/protocol_misc.c + src/tincd.c + +commit b5ccce296848aab72d574ca3de14af5fdf3efa4d +Author: Guus Sliepen +Date: Tue Sep 15 23:22:13 2009 +0200 + + Send large packets we cannot handle properly via TCP. + + During the path MTU discovery phase, we might not know the maximum MTU yet, but + we do know a safe minimum. If we encounter a packet that is larger than that + the minimum, we now send it via TCP instead to ensure it arrives. We also + allow large packets that we cannot fragment or create ICMP replies for to be + sent via TCP. + +commit d273efb177738d429e3cef7d8db8ee5cc8dcada7 +Author: Guus Sliepen +Date: Tue Sep 15 23:04:52 2009 +0200 + + Raise default RSA key length to 2048 bits. + +commit b47c17bcdeb70b63ad9346dc97ba575597cbd803 +Author: Guus Sliepen +Date: Tue Sep 15 22:59:01 2009 +0200 + + Use a mutex to allow the TAP reader to process packets faster on Windows. + + The TAP-Win32 device is not a socket, and select() under Windows only works + with sockets. Tinc used a separate thread to read from the TAP-Win32 device, + and passed this via a local socket to the main thread which could then select() + from it. We now use a global mutex, which is only unlocked when the main thread + is waiting for select(), to allow the TAP reader thread to process packets + directly. + +commit 802a50ffcd5f39bfc6424ac841de4e41154092fc +Author: Guus Sliepen +Date: Tue Sep 15 22:58:16 2009 +0200 + + Remove extra {. + +commit 4bb3793e38b7c7f24dd308801e7f6dbb02cf02d2 +Author: Guus Sliepen +Date: Tue Sep 15 12:08:05 2009 +0200 + + Raise default crypto algorithms to AES256 and SHA256. + + In light of the recent improvements of attacks on SHA1, the default hash + algorithm in tinc is now SHA256. At the same time, the default symmetric + encryption algorithm has been changed to AES256. + +commit 633c0cf1b067d118d5453bc8522fab65ffc82d2c +Author: Guus Sliepen +Date: Tue Sep 15 00:36:07 2009 +0200 + + Use access() instead of stat() for checking whether scripts exist. + +commit 6f1e0ece4e61f30612ed84ca4640635a02892cc8 +Author: Guus Sliepen +Date: Tue Sep 15 00:28:20 2009 +0200 + + Remove dropin random() function, as it is not used anymore. + +commit fa9bedd47cf8c143e801889c78f0a0979ac4d2fc +Author: Guus Sliepen +Date: Tue Sep 15 00:24:31 2009 +0200 + + Allow compiling for Windows XP and higher. + + This allows us to use getaddrinfo(), getnameinfo() and related functions, which + allow tinc to make connections over existing IPv6 networks. These functions are + not available on Windows 2000 however. By default, support is enabled, but when + compiling for Windows 2000 the configure switch --with-windows2000 should be + used. + + Since getaddrinfo() et al. are not functions but macros on Windows, we have to + use AC_CHECK_DECLS() instead of AC_CHECK_FUNCS() in configure.in. + +commit f80bf14f28925df6eaa56f3ed77adaf418ab9890 +Author: Guus Sliepen +Date: Mon Sep 14 23:28:28 2009 +0200 + + Also do not use drand48(), it is not available on Windows. + +commit 35e87b903e08fc51975a8cc97f06251d5153a424 +Author: Guus Sliepen +Date: Mon Sep 14 23:06:00 2009 +0200 + + Use only rand(), not random(). + + We used both rand() and random() in our code. Since it returns an int, we have + to use %x in our format strings instead of %lx. This fixes a crash under + Windows when cross-compiling tinc with a recent version of MinGW. + +commit 75773efe2689d347a2f219c5f27e4a82eef1236b +Author: Guus Sliepen +Date: Sun Sep 13 14:08:59 2009 +0200 + + Apparently it's impolite to ask GCC to subtract two pointers. + + If two pointers do not belong to the same array, pointer subtraction gives + nonsensical results, depending on the level of optimisation and the + architecture one is compiling for. It is apparently not just subtracting the + pointer values and dividing by the size of the object, but uses some kind of + higher magic not intended for mere mortals. GCC will not warn about this at + all. Casting to void * is also a no-no, because then GCC does warn that strict + aliasing rules are being broken. The only safe way to query the ordering of two + pointers is to use the (in)equality operators. + + The unsafe implementation of connection_compare() has probably caused the "old + connection_t for ... still lingering" messages. Our implementation of AVL trees + is augmented with a doubly linked list, which is normally what is traversed. + Only when deleting an old connection the tree itself is traversed. + +commit 23e151aeed6b3ffe0fab10f51ffdb134deb7a852 +Author: Guus Sliepen +Date: Sun Sep 13 14:07:40 2009 +0200 + + Remove superfluous call to avl_delete(). + +commit 9915f2abbedb7f1aa2b9e2f81d52ddcfca60e82d +Author: Guus Sliepen +Date: Sat Sep 12 14:19:36 2009 +0200 + + Handle unicast packets larger than PMTU in switch mode. + + If PMTUDiscovery is enabled, and we see a unicast packet that is larger than + the path MTU in switch mode, treat it just like we would do in router mode. + +commit 7242868b64f9d6f62b6c5bbf1526eb632ed9a4d6 +Author: Guus Sliepen +Date: Sat Sep 12 13:40:32 2009 +0200 + + Allow PMTUDiscovery in switch and hub modes again. + + PMTUDiscovery was disabled in commit d5b56bbba56480b5565ffb38496175a7c1df60ac + because tinc did not handle packets larger than the path MTU in switch and hub + modes. We now allow it again in preparation of proper support, but default to + off. + +commit 052ff8b2c598358d1c5febaa9f9f5fc5d384cfd3 +Author: Guus Sliepen +Date: Sat Sep 12 13:34:11 2009 +0200 + + Put Subnet weight in a separate environment variable. + + Commit 5674bba5c54c1aee3a4ac5b3aba6b3ebded91bbc introduced weighted Subnets, + but the weight was included in the SUBNET variable passed to subnet-up/down + scripts. This makes it harder to use in those scripts. The weight is now + stripped from the SUBNET variable and put in the WEIGHT variabel. + +commit a60a0a1f1357508063ee565d672c39898a787e33 +Author: Guus Sliepen +Date: Thu Sep 10 19:51:08 2009 +0200 + + Don't stat() on iPhone/iPod. + + Grzegorz Dymarek noted that tinc segfaults at the stat() call in + execute_script() on the iPhone. We can omit the stat() call for the moment, + the subsequent call to system() will fail with just a warning. + +commit 4a5d42178cc0954efba8b24058da9c70cc77c35a +Author: Guus Sliepen +Date: Thu Sep 10 19:32:54 2009 +0200 + + Add support for iPhones and recent iPods. + + This is a slightly modified patch from Grzegorz Dymarek that allows tinc to use + the tunemu device, which allows tinc to be compiled for iPhones and recent + iPods. To enable support for tunemu, the --enable-tunemu option has to be used + when running the configure script. + +commit ff946d0423fe547ea42bb11acfb3035c3b8aee4e +Author: Guus Sliepen +Date: Wed Sep 9 14:51:36 2009 +0200 + + Another safe bitfield conversion. + +commit dd6226062c2356d2a3679e2c7972be71233cb9de +Author: Guus Sliepen +Date: Wed Sep 9 13:23:16 2009 +0200 + + Add the GPL license to the repository. + + Tinc is licensed under the GPL version 2 or later. To ensure autoconf does not + install the wrong license if COPYING is missing, we have to put the right one + in place. + +commit 81afa26e4ad53bea00da18a7666f63d33cf3f588 +Author: Guus Sliepen +Date: Wed Sep 9 12:04:08 2009 +0200 + + Convert bitfields to integers in a safe way. + + This is commit eb391c52eed46f3f03b404553df417851fc0cb90 redone, but without the + non-standard anonymous union. + +commit 9b394bc887695da6db74f4b9796b4823e553f8cc +Author: Guus Sliepen +Date: Tue Sep 8 21:45:24 2009 +0200 + + Ensure tinc compiles with gcc -std=c99. + + We use a lot of C99 features already, but also some extensions which are not in + the standard. + +commit f52ea0a7eb0383cc2a5f41db1bf24c39424fdb04 +Author: Guus Sliepen +Date: Tue Sep 8 18:21:52 2009 +0200 + + UNIX signal numbers start at 1. + +commit 73d77dd416b87b7c4e9b6aa450f64846235cd2b4 +Author: Guus Sliepen +Date: Tue Sep 8 18:18:36 2009 +0200 + + Replace asprintf() by xasprintf(). + +commit 3e55dc77f4ba19fd9e79f3d5ce9d28bb6b05019e +Author: Guus Sliepen +Date: Tue Sep 8 18:18:16 2009 +0200 + + Check the return value of fscanf() when reading a PID file. + +commit 5e0efd53e797a2b5468b91b41b6122f3b942efb2 +Author: Guus Sliepen +Date: Tue Sep 8 18:16:58 2009 +0200 + + Add xasprintf() and xvasprintf(). + + These functions wrap asprintf() and vasprintf(), and check the return value. If + the function failed, tinc will exit with an error message, similar to xmalloc() + and friends. + +commit 63fe89e9eb8ef9077bfe3cd416c86820715eb33b +Author: Michael Tokarev +Date: Sat Sep 5 17:24:41 2009 +0400 + + Remove extra semicolon in my definition of setpriority() + +commit 5a7fc58012da10b96073804994777255463d1b8d +Author: Guus Sliepen +Date: Tue Sep 8 16:35:28 2009 +0200 + + Always remove a node from the UDP tree before freeing it. + + Valgrind caught tinc reading free'd memory during a purge(). This was caused by + first removing it from the main node tree, which will already call free_node(), + and then removing it from the UDP tree. This might cause spurious segmentation + faults. + +commit de029ce46056e02908b5390da9b71a6a59133f26 +Author: Guus Sliepen +Date: Thu Jun 11 19:39:25 2009 +0200 + + Change level of some debug messages, zero pointer after freeing hostname. + +commit 66be914d35cb7e7ea4dd4aed68ae9e41addd9f70 +Author: Guus Sliepen +Date: Thu Jun 11 19:26:34 2009 +0200 + + Do not log errors when recvfrom() returns EAGAIN or EINTR. + + Although we select() before we call recvfrom(), it sometimes happens that + select() tells us we can read but a subsequent read fails anyway. This is + harmless. + +commit df4add94a4a6461758b218a9ad257efc735062fe +Author: Guus Sliepen +Date: Thu Jun 11 19:07:54 2009 +0200 + + Remove pending MTU probe events when a node's reachability status changes. + +commit 36f8e4da8b1708474505f5a1fa8cf1ba848921de +Author: Guus Sliepen +Date: Thu Jun 11 18:36:08 2009 +0200 + + Don't try to send MTU probes to unreachable nodes. + + If there is an outstanding MTU probe event for a node which is not reachable + anymore, a UDP packet would be sent to that node, which caused a key request to + be sent to that node, which triggered a NULL pointer dereference. Probes and + other UDP packets to unreachable nodes are now dropped. + +commit 9b129c07e273ae113f3c67a9feeee82e8146f3a1 +Author: Guus Sliepen +Date: Sat Jun 6 20:14:51 2009 +0200 + + Fix pointer arithmetic when creating and verifying message authentication codes. + +commit 4124b9682f8f890acb25d0c92f2583eef670274a +Author: Guus Sliepen +Date: Sat Jun 6 19:04:04 2009 +0200 + + Handle truncated message authentication codes. + +commit 5a132550deb58473285e5f91705d286aef47be71 +Merge: 08aabbf9 591c38eb +Author: Guus Sliepen +Date: Fri Jun 5 23:03:28 2009 +0200 + + Merge branch 'master' into 1.1 + + Conflicts: + doc/tincd.8.in + lib/pidfile.c + src/graph.c + src/net.c + src/net.h + src/net_packet.c + src/net_setup.c + src/net_socket.c + src/netutl.c + src/node.c + src/node.h + src/protocol_auth.c + src/protocol_key.c + src/tincd.c + +commit 261d1eac1c5bbe6c87aa707566f290e611169432 +Author: Guus Sliepen +Date: Fri Jun 5 16:14:31 2009 +0200 + + Properly set HMAC length for incoming packets. + +commit 591c38eb38dbf0851bdebdd50b08d1bcbf6d7b0f +Author: Michael Tokarev +Date: Fri Jun 5 13:33:58 2009 +0400 + + try outgoing connections before chroot/drop_privs + + When chrooted, we either need to force-initialize resolver + and/or nsswitch somehow (no clean way) or resolve all the + names we want before entering chroot jail. The latter + looks cleaner, easier and it is actually safe because + we still don't talk with the remote nodes there, only + initiating outgoing connections. + +commit a42a8dde45fe95aa3fd3f7f15a74c5166efe3633 +Author: Michael Tokarev +Date: Fri Jun 5 11:58:17 2009 +0400 + + cleanup setpriority thing to make it readable + +commit a5fb0d8c6c384b9ea1074fb469c0a3dd5b874e98 +Author: Guus Sliepen +Date: Thu May 28 23:18:22 2009 +0200 + + Add some const where appropriate. + +commit 41c10c5a966000531099c79d6006429253ff8fd6 +Author: Guus Sliepen +Date: Thu May 28 22:51:30 2009 +0200 + + Add ProcessPriority option. + + This option can be set to low, normal or high. On UNIX flavours, this changes + the nice value of the process by +10, 0 and -10 respectively. On Windows, it + sets the priority to BELOW_NORMAL_PRIORITY_CLASS, NORMAL_PRIORITY_CLASS and + HIGH_PRIORITY_CLASS respectively. + + A high priority might help to reduce latency and packet loss on the VPN. + +commit 41a05f59ba2c3eb5caab555f096ed1b9fbe69ee3 +Author: Florian Forster +Date: Wed May 27 14:20:24 2009 +0200 + + src/net_socket.c: Bind outgoing TCP sockets to `BindToAddress'. + + If a host has multiple addresses on an interface, the source address of the TCP + connection(s) was picked by the operating system while the UDP packets used a + bound socket, i. e. the source address was the address specified by the user. + This caused problems because the receiving code requires the TCP connection and + the UDP connection to originate from the same IP address. + + This patch adds support for the `BindToInterface' and `BindToAddress' options + to the setup of outgoing TCP connections. + + Tested with Debian Etch on x86 and Debian Lenny on x86_64. + + Signed-off-by: Florian Forster + +commit 6b415a1a7f5bad2fff7b133ef2a2febccb96d6e5 +Author: Florian Forster +Date: Wed May 27 09:27:44 2009 +0200 + + src/linux/device.c: Fix segfault when running without `--net'. + + If running without `--net', the (global) variable `netname' is NULL. This + creates a segmentation fault because this NULL-pointer is passed to strdup: + + Program terminated with signal 11, Segmentation fault. + #0 0xb7d30463 in strlen () from /lib/tls/i686/cmov/libc.so.6 + (gdb) bt + #0 0xb7d30463 in strlen () from /lib/tls/i686/cmov/libc.so.6 + #1 0xb7d30175 in strdup () from /lib/tls/i686/cmov/libc.so.6 + #2 0x0805bf47 in xstrdup (s=0x0) at xmalloc.c:118 <--- + #3 0x0805be33 in setup_device () at device.c:66 + #4 0x0805072e in setup_myself () at net_setup.c:432 + #5 0x08050db2 in setup_network () at net_setup.c:536 + #6 0x0805b27f in main (argc=Cannot access memory at address 0x0) at tincd.c:580 + + This patch fixes this by checking `netname' in `setup_device'. An alternative + would be to check for NULL-pointers in `xstrdup' and return NULL in this case. + + Signed-off-by: Florian Forster + +commit a8a65cee083a27afe42cab360596e1453e7141b9 +Author: Michael Tokarev +Date: Sun May 24 17:23:24 2009 +0400 + + tunnelserver: log which ADD_SUBNET was refused + + Add some logging about refused ADD_SUBNET + (it causes subsequent client disconnect so it's + important to know which subnet was at fault). + + Maybe we should just ignore it completely. + +commit 4e9e3ca89dba68cbacaaa15ddfb298b181a969da +Author: Guus Sliepen +Date: Mon May 25 15:04:33 2009 +0200 + + Do not forward broadcast packets when TunnelServer is enabled. + + First of all, the idea behind the TunnelServer option is to hide all other + nodes from each other, so we shouldn't forward broadcast packets from them + anyway. The other reason is that since edges from other nodes are ignored, the + calculated minimum spanning tree might not be correct, which can result in + routing loops. + +commit 7fc69bc73b15349dafc193a50464caeb2f978369 +Author: Guus Sliepen +Date: Mon May 25 12:19:37 2009 +0200 + + Use packet size before decompression to calculate path MTU. + + Since compression can either grow or shrink a packet, the size of an MTU probe + after decompression might not reflect the real path MTU. Now we use the size + before decompression, which is independent of the compression algorithm, and + substract a safety margin such that the calculated path MTU will be safe even + for packets which grow as much as possible after compression. + +commit 1b3add6c29f8eb424a62837e89fe7d384fc94a48 +Author: Guus Sliepen +Date: Mon May 25 12:19:08 2009 +0200 + + Add declaration for sockaddrcmp_noport(). + +commit ca5b67111e4d797d15623c2163f67fe489dc3bf2 +Author: Michael Tokarev +Date: Sun May 24 22:32:24 2009 +0400 + + Fix ans_key exchange in recent changes + + send_ans_key() was using the wrong in vs. outkeylength to + terminate the key being sent, so it was always empty. + +commit 7034338bc36d9ea96d152091b9d58c2afc3f0c20 +Author: Guus Sliepen +Date: Sun May 24 19:35:51 2009 +0200 + + Use xrealloc instead of if(ptr) ptr = xmalloc(). + +commit e012e752f4f1a2b06dfab4640bbbea8f084999ff +Author: Guus Sliepen +Date: Sun May 24 19:31:31 2009 +0200 + + Fix initialisation of packet decryption context broken by commit 3308d13e7e3bf20cfeaf6f2ab17228a9820cea66. + + Instead of a single, global decryption context, each node has its own context. + However, in send_ans_key(), the global context was initialised. This commit + fixes that and removes the global context completely. + + Also only set status.validkey after all checks have been evaluated. + +commit 0246939ce18e1af9660b782b6814be182a7af9da +Author: Michael Tokarev +Date: Fri May 22 01:10:16 2009 +0400 + + don't log every strange packet coming to the UDP port + + it's a sure way to fill up syslog. Only log those if + debug level is up to PROTOCOL + +commit 576899ef0dec3aaede9b8ac101d189798587a646 +Author: Guus Sliepen +Date: Sun May 24 17:13:00 2009 +0200 + + Fix link to Mattias Nissler's tun/tap driver for MacOS/X. + + Thanks to Martin Christof Kindsmüller for spotting. + +commit 2c67eafc6e6c5e210636c0d2bad15827bf2d7cf0 +Author: Guus Sliepen +Date: Sun May 24 15:58:47 2009 +0200 + + If PMTUDiscovery is not set, do not forward packets via TCP unnecessarily. + +commit 7e4d57adf54ce369e4111bde0ccd3ea4b9e853ee +Author: Michael Tokarev +Date: Fri May 22 01:01:35 2009 +0400 + + ignore indirect edge registrations in tunnelserver mode + + In tunnelserver mode we're not interested to hear about + our client edges, just like in case of subnets. Just + ignore all requests which are not about our node or the + client node. + + The fix is very similar to what was done for subnets. + + Note that we don't need to add the "unknown" nodes to + the list in tunnelserver mode too, so move allocation + of new nodes down the line. + +commit 3759aa5f7745709c43f81faa36510ff650b4bf99 +Author: Michael Tokarev +Date: Wed May 20 18:40:04 2009 +0400 + + TunnelServer: Don't disconnect client on DEL_SUBNET too + + Similar changes as was in 2327d3f6eb5982bcc922ff1ab1ec436ba6aeffdc + but for del_subnet_h(). + + Before, we vere returning false (and causing disconnect of the + client) in case of tunnelserver and the client sending DEL_SUBNET + for non-his subnet or for subnet which owner isn't in our connection + list. + + After the mentioned change to add_subnet_h() that routine does not + add such indirect owners to the connection list anymore, so that + was ok (owner == NULL and we return true). + + But if we too has a connection with the node about which the client + is sending DEL_SUBNET notification, say, because that client lost + connection with that other node, we'll disconnect this client from + us too, returning false for indirect DEL_SUBNET. + + Fix that by allowing and ignoring indirect DEL_SUBNET in tunnelserver + mode. + + Also rearranged the function a bit, to match add_subnet_h() (in + particular, syntax-check everything first, see if we've seen this + request before). + + And also fix some comments. + +commit 218adee785df7c79ac18395d056a2eb6d63c407f +Author: Michael Tokarev +Date: Mon May 18 17:34:30 2009 +0400 + + format 'not supported on this platform' error message + + Format it in a similar way in all places, to make translation happier. + No functional changes. + +commit 54cb6b1aecb06a1ca44a7a60c74dd0d65b0043dd +Author: Michael Tokarev +Date: Mon May 18 17:00:00 2009 +0400 + + change error messages in droppriv code to match the rest + + Change formatting of error messages about failed syscalls + to be the same as in other places in tincd. + + Also suggest a change in "$foo not supported on this platform" + message as it's now used more than once. + +commit d4f9863635d06665cfbd3c46dc482344de240e97 +Author: Michael Tokarev +Date: Mon May 18 16:53:08 2009 +0400 + + bugfix: chdir(/) after chroot + + Fix the famous chdir(".") vs chdir("/") after chroot(something). + +commit 6be5d4f5b67764115b37528d2fe01bd245b3cd3e +Author: Michael Tokarev +Date: Mon May 18 16:49:39 2009 +0400 + + bugfix: move mlock to after detach() so it works for child, not parent + + mlock()/mlockall() are not persistent across fork(), and it's + done in parent process before daemon() which does fork(). So + basically, current --mlock does nothing useful. + + Move mlock() to after detach() so it works for child process + instead of parent. + + Also, check if the platform supports mlock right when processing + options (since else we'll have to die after startup, not at + startup, the error message will be in log only). + +commit cdf7f13c31310da0c40819fd812e19519bf4318c +Author: Michael Tokarev +Date: Mon May 18 16:28:55 2009 +0400 + + bugfix: initialize pid (as read from pidfile) to zero + + If we didn't read any number from a pid file, we'll return + an unitialized variable to the caller, and it will treat + that garbage as a pid of a process (possible to kill). + + Fix that. + +commit ec316aa32e8567395a88c4583007f01ffae008ce +Author: Michael Tokarev +Date: Mon May 18 16:25:41 2009 +0400 + + Implement privilege dropping + + Add two options, -R/--chroot and -U/--user=user, to chroot to the + config directory (where tinc.conf is located) and to perform + setuid to the user specified, after all the initialization is done. + + What's left is handling of pid file since we can't remove it anymore. + +commit 6698f7c390a5ae2f262e30560d9df59f9d5c418d +Author: Michael Tokarev +Date: Mon May 18 16:25:10 2009 +0400 + + Rename setup_network_connections() and split out try_outgoing_connections() + + In preparation of chroot/setuid operations, split out call to + try_outgoing_connections() from setup_network_connections() + (which was the last call in setup_network_connections()). + This is because dropping privileges should be done in-between + setup_network_connections() and try_outgoing_connections(). + + This patch renames setup_network_connections() to setup_network() + and moves call to try_outgoing_connections() into main routine. + + No functional changes. + +commit 3308d13e7e3bf20cfeaf6f2ab17228a9820cea66 +Author: Guus Sliepen +Date: Fri Apr 3 01:05:23 2009 +0200 + + Handle UDP packets from different and ports than advertised. + + Previously, tinc used a fixed address and port for each node for UDP packet + exchange. The port was the one advertised by that node as its listening port. + However, due to NAT the port might be different. Now, tinc sends a different + session key to each node. This way, the sending node can be determined from + incoming packets by checking the MAC against all session keys. If a match is + found, the address and port for that node are updated. + +commit 08aabbf9317806bc50a9a6693ca866c8936ce26b +Merge: 551cd194 43fa7283 +Author: Guus Sliepen +Date: Mon Mar 9 19:02:24 2009 +0100 + + Merge branch 'master' into 1.1 + + Conflicts: + NEWS + README + doc/tinc.conf.5.in + doc/tinc.texi + po/nl.po + src/conf.c + src/connection.c + src/event.c + src/graph.c + src/net.c + src/net_packet.c + src/net_socket.c + src/node.c + src/node.h + src/openssl/rsagen.h + src/protocol_auth.c + src/protocol_key.c + src/protocol_misc.c + src/subnet.c + src/subnet.h + src/tincd.c + +commit 43fa7283ac01f2ecc95381b519ef6b3342546f35 +Author: Guus Sliepen +Date: Mon Mar 9 14:04:31 2009 +0100 + + Use a simple Random Early Drop algorithm in send_tcppacket(). + +commit d5b56bbba56480b5565ffb38496175a7c1df60ac +Author: Guus Sliepen +Date: Mon Mar 9 13:48:54 2009 +0100 + + Disable PMTUDiscovery in switch and hub modes. + + In switch and hub modes, tinc does not generate ICMP packets in response to + packets that are larger than the path MTU. However, if PMTUDiscovery is + enabled, the IP_MTU_DISCOVER and IPV6_MTU_DISCOVER option is set on the UDP + sockets, which causes all UDP packets to be sent with the DF bit set, causing + large packets to be dropped, even if they would otherwise be routed fine. + +commit 78fc59e994c764d072bf0045177f690a378d1308 +Author: Guus Sliepen +Date: Thu Mar 5 14:12:36 2009 +0100 + + Update THANKS and copyright information. + +commit 5674bba5c54c1aee3a4ac5b3aba6b3ebded91bbc +Author: Guus Sliepen +Date: Thu Mar 5 13:34:13 2009 +0100 + + Allow weight to be assigned to Subnets. + + Tinc allows multiple nodes to own the same Subnet, but did not have a sensible + way to decide which one to send packets to. Tinc also did not check the + reachability of nodes when deciding where to route packets to, so it would not + automatically fail over to a reachable node. + + Tinc now assigns a weight to each Subnet. The default weight is 10, with lower + weights having higher priority. The Subnets are now internally sorted in the + same way as the kernel's routing table, and the Subnets are search linearly, + skipping those of unreachable nodes. A small cache of recently used addresses + is used to speed up the lookup functions. + +commit 76a1bcaffcf1f1abf81fdda379b703a004640cb4 +Author: Michael Tokarev +Date: Sat Feb 28 16:37:51 2009 +0300 + + Enable PMTUDiscovery only if BOTH sides wants it. + + Don't enable PMTUDiscovery if at least one side does not support it. + Before it was enabled if at least one side supported it, now both are required. + +commit 1c1a67fd93530b9d16538ab2897c3911d3b16574 +Author: Guus Sliepen +Date: Tue Feb 17 14:43:05 2009 +0100 + + Handle neighbor solicitation requests without link layer addresses. + + Apparently FreeBSD likes to send out neighbor solicitation requests, even on a + tun interface where this is completely pointless. These requests do not have an + option header containing a link layer address, so the proxy-neighborsol code + was treating these requests as invalid. We now handle such requests, and send + back equally pointless replies, also without a link layer address. This seems + to satisfy FreeBSD. + +commit 2327d3f6eb5982bcc922ff1ab1ec436ba6aeffdc +Author: Michael Tokarev +Date: Mon Feb 9 23:51:10 2009 +0100 + + Allow tunnelserver to work with clients that have other peers. + + In TunnelServer mode, tinc server disconnects any client if it announces + indirect subnets -- subnets that are not theirs (e.g. subnets for nodes + the CLIENT has connections now, even if those nodes are known to the server + too). Fix that by ignoring such (indirect) announces instead. + + While we're at it, move check for such indirect subnet registration to + before allocating new node structure, as in TunnelServer mode we don't + really need to know that other node. + +commit 23730375f27c32e0fe1a59c7a761dd85296a7a4a +Author: Guus Sliepen +Date: Tue Feb 3 14:54:45 2009 +0100 + + Disable old RSA keys when generating new ones. + + When generating an RSA keypair, the new public and private keys are appended to + files. However, when OpenSSL reads keys it only reads the first in a file, not + the last. Instead of printing an easily ignored warning, tinc now disables old + keys when appending new ones. + +commit 0d0dfd0852e9b2c9a7660880966a3c84790d5ea2 +Author: Guus Sliepen +Date: Tue Jan 20 14:21:50 2009 +0100 + + Validate Name before using it in a filename when generating a keypair. + +commit 0966cca8ab6dcde2747c717f21d73fd332e04242 +Author: Guus Sliepen +Date: Tue Jan 20 14:20:44 2009 +0100 + + Allow reading config files with CRLF endings on Unix systems. + +commit d1910ac198232573c1b18d8238a27bc29bc73f8a +Author: Guus Sliepen +Date: Tue Jan 20 13:19:31 2009 +0100 + + Remove unused definitions from net.h. + +commit 503c32eb0ef9d6329e931559082f4ddf6d487dc6 +Author: Guus Sliepen +Date: Tue Jan 20 13:12:41 2009 +0100 + + Use a global list to track outgoing connections. + + Previously an outgoing_t was maintained for each outgoing connection, + but the pointer to it was either stored in a connection_t or in an event_t. + This made it very hard to keep track of and to clean up. + + Now a list is created when tinc starts and reads all the ConnectTo variables, + and which is recreated when tinc receives a HUP signal. + +commit a7e793c94ec414eb71ec2aa3debc9e2e5ed5cfef +Author: Guus Sliepen +Date: Mon Jan 19 23:17:28 2009 +0100 + + Add missing cleanup functions in close_network_connections(). + +commit 116065afe352221ac6c2c8e34c109252004d6a59 +Author: Guus Sliepen +Date: Mon Jan 19 22:50:05 2009 +0100 + + Change flush_events() to expire_events(). + + The former function made a totally bogus shallow copy of the event_tree, called + the handler of each event and then deleted the whole tree. This should've + caused tinc to crash when an ALARM signal was sent more than once, but for some + reason it didn't. It also behaved incorrectly when a handler added a new event. + + The new function just moves the expiration time of all events to the past. + +commit a39a9506cd041a7092a98498b362eaacfd2f33c3 +Author: Guus Sliepen +Date: Fri Jan 9 12:36:06 2009 +0100 + + Move free()s at the end om main() to the proper destructor functions. + +commit 67df7fb7e1c9eefe4bbc920fdc68b595ef28abd9 +Author: Guus Sliepen +Date: Sat Jan 3 22:33:55 2009 +0100 + + Only send packets via UDP if UDP communication is possible. + + When no session key is known for a node, or when it is doing PMTU discovery but + no MTU probes have returned yet, packets are sent via TCP. Some logic is added + to make sure intermediate nodes continue forwarding via TCP. The per-node + packet queue is now no longer necessary and has been removed. + +commit b069da90d67b49dce041f513a3855b8da3d82f80 +Author: Guus Sliepen +Date: Sat Jan 3 22:06:10 2009 +0100 + + Consistently allocate device and iface variables on the heap. + + This fixes a segfault when no Device has been specified and tinc exits, and it + would try to free() a static string. Thanks to Borg for spottin. + +commit f81cea3bdc8683b27188cd8f24a2de906a29eb81 +Author: Guus Sliepen +Date: Sat Dec 27 11:09:43 2008 +0100 + + Update documentation for git. + +commit c81f90b91a054eeafcc3c8c45abc52045e4a8146 +Author: Guus Sliepen +Date: Fri Dec 26 13:47:34 2008 +0000 + + Releasing 1.0.9. + +commit a4d99ebf5042dedb609359cbbfc3fa4630b5fc70 +Author: Guus Sliepen +Date: Fri Dec 26 12:46:45 2008 +0000 + + Add missing parentheses in check for IPv4 multicast addresses. + +commit 099bc56f53e7d3cb7b799d26ff9535673ff03e1c +Author: Guus Sliepen +Date: Tue Dec 23 23:14:37 2008 +0000 + + Apply patch from Max Rijevski fixing a memory leak when closing connections. + It also cleans up more when stopping tinc, helping tools like valgrind. + +commit de032054dee67bcc406b4a15fb9e957a766d016a +Author: Guus Sliepen +Date: Tue Dec 23 22:31:38 2008 +0000 + + Handle broadcast and multicast packets in router mode. + Multicast packets are treated as broadcast packets. + Based on a patch from Max Rijevski. + +commit a5f899a9794f215e8174455ead04862a2c14a5b1 +Author: Guus Sliepen +Date: Mon Dec 22 21:49:23 2008 +0000 + + Update the manpage as well, and some whitespace to make its source more legible. + +commit e8f08ced76bf1b9a94dd0dc874ad22761ad8900b +Author: Guus Sliepen +Date: Mon Dec 22 21:29:21 2008 +0000 + + Update documentation. + - TCPOnly is not experimental. + - Do not mention old Linux kernels and Ethertap anymore. + - Document the DeviceType, PMTU and PMTUDiscovery options. + +commit 0e4d419aae8a82f2ae4552f755894a9bc70c83d2 +Author: Guus Sliepen +Date: Mon Dec 22 20:35:45 2008 +0000 + + Enable PMTU discovery by default. + +commit e9576632dc4b780b867044269d06cc50f76d8c05 +Author: Guus Sliepen +Date: Mon Dec 22 20:27:52 2008 +0000 + + Update copyright information. + +commit f50dc972cde2644588eabf35a2422fe0e372a024 +Author: Guus Sliepen +Date: Mon Dec 22 19:43:49 2008 +0000 + + Update Dutch translation. + +commit 26b490e86bc305b150200c0b08cd8e9c3bd605fb +Author: Guus Sliepen +Date: Mon Dec 22 19:40:40 2008 +0000 + + Make sure IPv6 sockets are IPv6 only. + This will get rid of the "Can't bind to 0.0.0.0 port 655/tcp: Address already + in use" message on Linux. + +commit c6830ba821e6387be961ca68b32992382a74a0e9 +Author: Guus Sliepen +Date: Mon Dec 22 19:33:37 2008 +0000 + + Use TUNIFHEAD by default on FreeBSD to make sure IPv6 works. + +commit a269ec4193900feee01ac83f0e18a6e2b98e751f +Author: Guus Sliepen +Date: Sun Dec 21 16:19:31 2008 +0000 + + Treat virtual network device as tap if Mode = switch or hub. + On OpenBSD, the link0 flag should still be set in tinc-up or by other means. + +commit 551cd19406a560d0d206bff5b4e9da064ec222b6 +Author: Guus Sliepen +Date: Sun Dec 14 12:47:26 2008 +0000 + + Move RSA key generation into the wrappers. + +commit 911c05f873ad967c40d04aa7347b1067fe62c055 +Author: Guus Sliepen +Date: Thu Dec 11 20:49:14 2008 +0000 + + Make sure IPv6 sockets are IPv6 only. + +commit 6e80da3370249caa1082c23c3ef55f338d1e9e74 +Author: Guus Sliepen +Date: Thu Dec 11 18:07:26 2008 +0000 + + Use Dijkstra's algorithm. Based on patches from Max Rijevskiy. + +commit 26a228e3025c3970fd461af777013e3807b0fc58 +Author: Guus Sliepen +Date: Thu Dec 11 18:05:59 2008 +0000 + + Remove wrong checks. + +commit 636200d1a2024982fe5b3062153daa72a8253015 +Author: Guus Sliepen +Date: Thu Dec 11 15:56:18 2008 +0000 + + Remove unnecessary parentheses from sizeof, apply sizeof to variables instead of types whereever possible. + +commit a9bdfb424e7a469d15156aa44bbe2fd0b8e28531 +Author: Guus Sliepen +Date: Thu Dec 11 15:42:46 2008 +0000 + + Fix compiler warnings. + +commit 76165488f8201a59e649b4eec02ee31398b3fb92 +Author: Guus Sliepen +Date: Thu Dec 11 15:21:40 2008 +0000 + + Backport fixes from trunk since revision 1555. + +commit 046158a216e78a0412186ec8463157f6bce45d5d +Author: Guus Sliepen +Date: Thu Dec 11 14:44:44 2008 +0000 + + Use the crypto wrappers again instead of calling OpenSSL directly. + This theoretically allows other cryptographic libraries to be used, + and it improves the readability of the code. + +commit 8c69f42d7d9b4d9d5f6b6656cfc1bf1e1abee854 +Author: Guus Sliepen +Date: Thu Dec 11 14:43:13 2008 +0000 + + Move AC_GNU_SOURCE up to make autoconf happy. + Also bump libgcrypt dependency to 1.4.0, because that version supports the OFB cipher mode. + +commit 8e8fe805c81d3edc974c12c468f793ea0c1e5ee7 +Author: Guus Sliepen +Date: Thu Dec 11 14:03:52 2008 +0000 + + Only show meta connection related debug messages when debug level >= 4 + +commit 40bebbb19fd69fa094e2f6c3c1474adc0105b048 +Author: Guus Sliepen +Date: Thu Dec 11 13:59:46 2008 +0000 + + Look in the configured sbin directory for the tincd binary. + +commit 38c2d6c1dae3f09c68baa37fd24caa2e0ec6d8ad +Author: Guus Sliepen +Date: Fri Dec 5 14:17:39 2008 +0000 + + Correct debug message. + +commit a36259435c17f76cf12476234a56f40fcd8faf41 +Author: Guus Sliepen +Date: Tue Nov 18 15:11:27 2008 +0000 + + Prevent freeing a NULL pointer when a hostname is unresolvable. + +commit 4a1740ede7c1992f7f3da5e197db9975c0344ac3 +Author: Guus Sliepen +Date: Sat Oct 25 19:54:00 2008 +0000 + + Do not try to send REQ_KEY or ANS_KEY requests to unreachable nodes. + +commit cb52aa06833a69e57b5e26337e51a4d375b6d8fb +Author: Guus Sliepen +Date: Sat Oct 25 18:10:08 2008 +0000 + + Fix reading configuration files that do not end with a newline. + +commit b2cee41b187d79c095914d1097b8ff34a0609ec3 +Author: Guus Sliepen +Date: Fri Dec 14 21:17:08 2007 +0000 + + Make sure the prefixlength of subnets is sane. + Thanks to Sven-Haegar Koch for spotting the bug and providing a fix. + +commit fe2f1fceb546ca4326435cac26bcf3f513e82b43 +Author: Scott Lamb +Date: Thu Nov 8 19:18:44 2007 +0000 + + Use a control socket directory to restrict access + + This provides reasonable security even on Solaris. The sysadmin is + responsible for securing the control socket's ancestors from the + grandparent on. + + We could add a cryptographic handshake later if desired. + +commit b1f8c65a2cfa307d9b8ed8cc3c8d4819f605e4f6 +Author: Scott Lamb +Date: Wed Nov 7 06:45:28 2007 +0000 + + Coding style corrections + +commit d82fcc88f355e3c8144478a860dfae0b299004a9 +Author: Scott Lamb +Date: Wed Nov 7 02:51:24 2007 +0000 + + Reload configuration through control socket + + I also kept the SIGHUP handler, which many people will expect to see. + The control socket is better, though - it will tell you if there is a + problem. + +commit f0a57eab4cfd64d4f8261b1885a2072177f9e76b +Author: Scott Lamb +Date: Wed Nov 7 02:50:58 2007 +0000 + + Retry connections through control socket + +commit a62a6825a8a69e279ee0688a4cd9e51fbc52054b +Author: Scott Lamb +Date: Wed Nov 7 02:50:27 2007 +0000 + + Alter debugging levels through control socket + +commit 1065879c8c6e8cdf8d3755024241f31eaabd4138 +Author: Scott Lamb +Date: Wed Nov 7 02:49:57 2007 +0000 + + Purge through the control socket + +commit 6eaefb4dbce240334e35f67d9f3db5d4f44e49c9 +Author: Scott Lamb +Date: Wed Nov 7 02:49:25 2007 +0000 + + Dump through control socket + + Note this removes SIGUSR1, SIGUSR2, and the graph dumping config option. + It seems cleaner to do everything through the control socket. + +commit 50ad3f2a895c38f8d546f87490ca96ab7d9e011e +Author: Scott Lamb +Date: Wed Nov 7 02:48:33 2007 +0000 + + Fancier protocol for control socket + + * pass error status back + * pass message boundaries + +commit b0b52991849073de059a188800d1b2f03663a188 +Author: Scott Lamb +Date: Wed Nov 7 02:48:15 2007 +0000 + + Fix reload crash + + sighup_handler was expecting the connection_tree to stay the same across + terminate_connection(), which hasn't been true since r1539. + +commit da81da064a093f94e460fc1c359b5cfab26d6b5b +Author: Scott Lamb +Date: Wed Nov 7 02:48:00 2007 +0000 + + Update documentation to match tincctl changes + + (Most of this was done in r1559, but it looks like tincctl.8.in got missed.) + +commit 40731d030fef793c6b6405efd9b3e64c26c00045 +Author: Scott Lamb +Date: Wed Nov 7 02:47:05 2007 +0000 + + Temporarily revert to old crypto code + + (The new code is still segfaulting for me, and I'd like to proceed with other + work.) + + This largely rolls back to the revision 1545 state of the existing code + (new crypto layer is still there with no callers), though I reintroduced + the segfault fix of revision 1562. + +commit 269892f70bf357de6ad66ca89daa34b225ee9e37 +Author: Guus Sliepen +Date: Sat Oct 20 11:21:44 2007 +0000 + + Prevent double free() of a used challenge nonce. + +commit b0709d2649ebd7ad01d6e24851dcdfc2707d09c5 +Author: Guus Sliepen +Date: Fri Oct 19 19:07:30 2007 +0000 + + Fix meta data segfault when receiving a partial command. + +commit 67d9a72ea2f10f1a2d2eb7c04a41183359d5e1cc +Author: Guus Sliepen +Date: Fri Oct 19 18:54:43 2007 +0000 + + Use a dummy function as the read callback for connection bufferevents. Should not be triggered. + +commit 54892b2e3efcbbbd65b26a32f487829bbb8d787c +Author: Guus Sliepen +Date: Fri Oct 19 18:53:48 2007 +0000 + + Fix connection weight estimation. + +commit 6c453769fd16125ec18e8e6d102a3eaa09d370c7 +Author: Guus Sliepen +Date: Tue Sep 4 15:06:35 2007 +0000 + + Apply patch from Scott Lamb: Update documentation to match tincctl changes + +commit 86358fabfedca395b60310799a648b4875596efb +Author: Guus Sliepen +Date: Tue Sep 4 14:58:52 2007 +0000 + + Small fixes to make gcrypt routines compile. + +commit f8733d1935ed83399c4851a31f4be710eb8c825f +Author: Guus Sliepen +Date: Tue Sep 4 14:58:11 2007 +0000 + + Fix formatting of --help output. + +commit 65375289dff849f00b3429dfe4be7e66efe48444 +Author: Guus Sliepen +Date: Tue Sep 4 14:57:37 2007 +0000 + + Only check for libgcrypt if --with-gcrypt is used. + +commit d7ca0300a3f004e9dc7d97ffb6fa6bdeda890fda +Author: Guus Sliepen +Date: Fri Aug 17 22:09:00 2007 +0000 + + Handle SERVICE_CONTROL_INTERROGATE requests. Thanks to Carsten Ralle for noticing this. + +commit 1fd1d5bd9330e02ab5dc32ad027f654ff2620099 +Author: Scott Lamb +Date: Fri Jul 20 20:10:46 2007 +0000 + + const correctness + + cipher_encrypt and cipher_decrypt should take "const void *" data + +commit 35d865a6348cd62d2992bb3d353e37471d902889 +Author: Scott Lamb +Date: Wed Jul 18 16:44:05 2007 +0000 + + Updated svn:ignores list for new symlinked sources and tincctl. + +commit dd299c06dccceeb9b4db09eee17268cf5631fa41 +Author: Scott Lamb +Date: Wed Jul 18 16:40:41 2007 +0000 + + Refresh po/POTFILES.in. + + In particular, remove lib/pidfile.c which was causing failures. Also sort + for diffability with "find . -type f -name '*.c' | cut -c3- | sort" output. + +commit 46018a1a16579ce00b02eb6a991a70615ab9bc3e +Author: Scott Lamb +Date: Wed Jul 18 16:40:29 2007 +0000 + + Revert to only requiring autoconf 2.59. + + The new autoconf macros introduced at the same time (AC_GNU_SOURCE, + AC_FUNC_MALLOC, AC_FUNC_REALLOC) exist in the autoconf 2.59 documentation, + and autoconf 2.59 appears to still work. This is more convenient, as RHEL 5 + ships with autoconf 2.59. + +commit 1b8f8918360b40a2749d40355266ed7dedbe41b5 +Author: Guus Sliepen +Date: Wed May 23 13:45:49 2007 +0000 + + Finish crypto wrapping. Also provide wrappers for OpenSSL. + Disable libgcrypt by default. Since it doesn't support the OFB cipher mode, + we can't use it in a backwards compatible way. + +commit f42e57f663a2663c830c4fb4c01927c2d3c89c09 +Author: Guus Sliepen +Date: Tue May 22 23:41:22 2007 +0000 + + Some more crypto wrapper functions are needed. + +commit 19413a8048fd851866c551ab8035f008f0c7e806 +Author: Guus Sliepen +Date: Tue May 22 21:44:17 2007 +0000 + + Make sure the crypto wrapper functions can actually be compiled. + +commit e8689a4753ca2b1665e131cc40217da6c033ebd3 +Author: Guus Sliepen +Date: Tue May 22 21:32:48 2007 +0000 + + Create wrappers for the cryptographic operations used in tinc. + Implement them using libgcrypt. + +commit 465837dd7f7b727d489b354e4b75489dd49fd6e3 +Author: Guus Sliepen +Date: Sun May 20 22:28:49 2007 +0000 + + Parse PEM RSA keys ourself, and use libgcrypt to do RSA encryption and decryption. + +commit fbf305c09d91bf34b1504b58d50392df2e6bcfba +Author: Guus Sliepen +Date: Sat May 19 22:23:02 2007 +0000 + + Use libevent for meta socket input/output buffering. + +commit 59108e4e4f7aa4632c510d16961edd8c551a6542 +Author: Guus Sliepen +Date: Sat May 19 16:21:52 2007 +0000 + + Use bufferevents to handle control socket buffering. + +commit 8c6131deda546452386f3703af968ee664cadfbd +Author: Guus Sliepen +Date: Sat May 19 15:21:26 2007 +0000 + + Implement "stop" command, and allow tincctl to retrieve a running tincd's PID. + +commit e9043e17c76f92b787c9ecdaf1a2ae7916f690a6 +Author: Guus Sliepen +Date: Sat May 19 14:55:35 2007 +0000 + + Move key generation to tincctl. + +commit bf8e3ce13dba6109757c14dc0013a315a75d2ba3 +Author: Guus Sliepen +Date: Sat May 19 14:13:21 2007 +0000 + + Remove pidfile in favour of control socket. + +commit bc0a24ec810cb911610ae7aafa245e47d1268cd2 +Author: Guus Sliepen +Date: Sat May 19 13:34:32 2007 +0000 + + Fix retrying outgoing connections. + +commit ce976717ea9756aa985699547fdbf132b694748d +Author: Guus Sliepen +Date: Sat May 19 12:07:30 2007 +0000 + + We can safely delete a connection_t in terminate_connection() now. + +commit 01f47c46af514a9d7f39c143e4558a8426a0d3eb +Author: Guus Sliepen +Date: Fri May 18 16:52:34 2007 +0000 + + Start of control socket implementation. + +commit 6ded8a3f089a22c98d2a06b960d65b44e60188d6 +Author: Guus Sliepen +Date: Fri May 18 11:54:16 2007 +0000 + + Update documentation. + +commit 86586594334e951a99845d92baed1966e394aafa +Author: Guus Sliepen +Date: Fri May 18 11:35:21 2007 +0000 + + Show branch version number. + +commit e37ef57a956507cc29e80930201731562b4266e5 +Author: Guus Sliepen +Date: Fri May 18 11:19:31 2007 +0000 + + More consistent variable naming. + +commit 29fbce4497357580fc0aa00f087e8f1a538a2a50 +Author: Guus Sliepen +Date: Fri May 18 10:29:10 2007 +0000 + + Detect duplicate outgoing connections. + +commit fb0cfccf7dc2240b576011edcf74fd5b058916cb +Author: Guus Sliepen +Date: Fri May 18 10:05:26 2007 +0000 + + Use splay trees instead of AVL trees. + +commit f02d3ed3e135b5326003e7f69f8331ff6a3cc219 +Author: Guus Sliepen +Date: Fri May 18 10:00:00 2007 +0000 + + K&R style braces + +commit 760dd966efe7dbff316a8c638e40dee162848256 +Author: Guus Sliepen +Date: Fri May 18 09:51:54 2007 +0000 + + Remove last references to the global variable "running". + +commit 3909b8e51b27b11c6d54541220cb7767bf25569c +Author: Guus Sliepen +Date: Fri May 18 09:43:52 2007 +0000 + + Remove the last bits of the legacy main_loop(). + +commit ddc6a81a854023e38b563f213aa9a449ee91add8 +Author: Guus Sliepen +Date: Fri May 18 09:34:06 2007 +0000 + + Remove global variable "now". + +commit 7e1117197ca4fc62af93fda50e28e0ff06cb736c +Author: Guus Sliepen +Date: Thu May 17 23:57:48 2007 +0000 + + Move key regeneration handling to net_setup.c. + +commit 563577a1479549fa0c20dcda45831a0fff8c7513 +Author: Guus Sliepen +Date: Thu May 17 23:33:07 2007 +0000 + + Use libevent to handle key expiration. + +commit 8852d4407d87cf5dcf2c212d352279015aa050c0 +Author: Guus Sliepen +Date: Thu May 17 23:24:40 2007 +0000 + + Use libevent to age learned MAC addresses. + +commit a530f94e7c4acd94d1cd568b384931eec6f60563 +Author: Guus Sliepen +Date: Thu May 17 23:14:42 2007 +0000 + + Use libevent to age past requests. + +commit aaf1851315023c2f960c58a0d977085a485298e7 +Author: Guus Sliepen +Date: Thu May 17 23:04:02 2007 +0000 + + Redo SIGALRM handling. + +commit 6d19ebd612e6387ba34419cce5cd4d5d861b9a9e +Author: Guus Sliepen +Date: Thu May 17 22:41:34 2007 +0000 + + Use libevent to handle all non-fatal signals. + +commit 531d5a904a3a91bca8b7d373fb6ab2869b31e7fa +Author: Guus Sliepen +Date: Thu May 17 22:17:24 2007 +0000 + + Properly use the timeout_initialized() macro. + +commit bf6490825eabdf4eda6e64f2e5fcd690db7b72ce +Author: Guus Sliepen +Date: Thu May 17 22:13:12 2007 +0000 + + Remove legacy event system. + +commit a67ab277c9fdbcfc8c0550e9046df2a00b5fed81 +Author: Guus Sliepen +Date: Thu May 17 22:09:55 2007 +0000 + + Use libevent for retrying outgoing connections. + +commit 3321591d93d00326eee01fa7c78fb0d56b3d0fba +Author: Guus Sliepen +Date: Thu May 17 22:01:07 2007 +0000 + + Use libevent to send MTU probes. + +commit ee7844905f63872e12cd12f5a3d1a62220594831 +Author: Guus Sliepen +Date: Thu May 17 21:47:27 2007 +0000 + + Configure events after obtaining a socket. + +commit 294ce72441e44c0561556c2984f0e26a74230347 +Author: Guus Sliepen +Date: Thu May 17 21:34:58 2007 +0000 + + Use libevent to handle HUP signal. + +commit 4d0621b1f39537699b0ec4655b0c6e6b84581c9a +Author: Guus Sliepen +Date: Thu May 17 21:14:30 2007 +0000 + + Use libevent to dump graphs when necessary. + event_add() can be called repeatedly, the second and later calls are ignored if + the event hasn't been removed yet. + +commit 0f6f54ff8aa96d981f68b5b71c7126b8fdbead6c +Author: Guus Sliepen +Date: Thu May 17 20:20:10 2007 +0000 + + Use a separate event structure to handle meta data writes. + Make meta socket events persistent. + +commit 17c8033029d50ce4a30b6e3585c0ee28ef45bc97 +Author: Guus Sliepen +Date: Thu May 17 19:52:12 2007 +0000 + + 128 listener sockets is way too much. + +commit d8dea8091fa2260071f775db58ba277d4ce44ea7 +Author: Guus Sliepen +Date: Thu May 17 19:51:26 2007 +0000 + + Properly delete listener socket events on shutdown. + +commit 6ea1dfc995f386b3a9406c7935642524dc755c51 +Author: Guus Sliepen +Date: Thu May 17 19:15:48 2007 +0000 + + Port fixes from release 1.0.8. + +commit cf2be574948fdd02db0503d9639d3b6e268dd4ff +Author: Guus Sliepen +Date: Wed May 16 17:16:09 2007 +0000 + + Releasing 1.0.8. + +commit 6af8900f8e1c7f2fe6a50a991ae6cbd0fd7edd43 +Author: Guus Sliepen +Date: Wed May 16 14:46:25 2007 +0000 + + Don't free struct addrinfo too early. Spotted by Christian Cier-Zniewski. + +commit 31a190dc7db21aa9bb97792563dd83e7c41b831c +Author: Guus Sliepen +Date: Wed May 16 14:42:41 2007 +0000 + + Update dutch translation. + +commit 480dd127c8a539036ff82a3810a0ad83136944f8 +Author: Guus Sliepen +Date: Wed May 16 14:42:08 2007 +0000 + + Make sure connection->name is never NULL. + +commit f0cf4991e2bd0e618c7020511fb12cb0b5c59a40 +Author: Guus Sliepen +Date: Mon May 14 09:21:09 2007 +0000 + + Apply patch from "dnk" making sockets non-blocking under Windows. + +commit 3730156165fd1aa7c8810cd8e390aba6a8badcfa +Author: Guus Sliepen +Date: Mon Mar 12 17:55:43 2007 +0000 + + Only free members of connection_t that have been allocated. + +commit 39f6d59b4b81dc2d754329e6c9f885e8211c5e70 +Author: Scott Lamb +Date: Tue Feb 27 08:13:41 2007 +0000 + + Lots of svn:ignore entries + +commit 38c25d62c2bc76908bd95fb21c8f5e39ad269884 +Author: Scott Lamb +Date: Tue Feb 27 01:57:01 2007 +0000 + + Convert to libevent. + + This is a quick initial conversion that doesn't yet show much advantage: + - We roll our own timeouts. + - We roll our own signal handling. + - We build up the meta connection fd events on each loop rather than + on state changes. + +commit 834290b00f859412ee48bef454a07083cb727130 +Author: Scott Lamb +Date: Tue Feb 27 01:30:57 2007 +0000 + + A couple missed tevent things. + (Sorry; had a couple changes queued.) + +commit 6362b12df725044f3404faceff113e469d8ac860 +Author: Scott Lamb +Date: Tue Feb 27 01:26:11 2007 +0000 + + Rename "event_t" to "tevent_t", along with associated functions. + This relieves some confusion and problems during the libevent transition. + In particular, "event_add" was defined by both. + (The 't' stands for 'timeout', 'tinc', 'temporary', or some such.) + +commit 54431094d95f3989084755fdb91883b24cf5a9f4 +Author: Guus Sliepen +Date: Sat Feb 24 22:50:42 2007 +0000 + + Created the 1.1 branch where large code changes can take place, + at the same time keeping compatibility with 1.0. + +commit ab6f76f6a9fc8028fff96322a52b770710ffa1a9 +Author: Guus Sliepen +Date: Wed Feb 14 09:32:16 2007 +0000 + + Close the proper filedescriptor (if it exists). + +commit 45fca3c723302868de3225e7509d2292008948f7 +Author: Guus Sliepen +Date: Wed Feb 14 09:21:34 2007 +0000 + + Apply patch from Scott Lamb fixing some memory and resource leaks. + +commit 6c6535a4161d04accb3a22c51477e9f92ae34086 +Author: Guus Sliepen +Date: Wed Feb 14 09:20:20 2007 +0000 + + Apply patch from Scott Lamb preventing an infinite loop when sending SIGALRM. + +commit 16c8b0e5bb7c05a0559b2d799a32204bfa0a0e3f +Author: Guus Sliepen +Date: Fri Jan 5 15:03:07 2007 +0000 + + Releasing 1.0.7. + +commit a1e72f84d08b76784c11ff723666ceeaef2756eb +Author: Guus Sliepen +Date: Fri Jan 5 13:18:36 2007 +0000 + + Update copyright notices. + +commit a22ef25f9b81993226a74b193377c7d6baf910ca +Author: Guus Sliepen +Date: Fri Jan 5 13:17:33 2007 +0000 + + No things to do for the 1.0 branch except bugfixing. + +commit d80cc7a5cc918a1dbf8dd789d2125f55c4949d27 +Author: Guus Sliepen +Date: Fri Jan 5 05:44:01 2007 +0000 + + rename() cannot replace existing files on Windows. + +commit 5214ece03009a916159c710cf436af1e92909f41 +Author: Guus Sliepen +Date: Fri Jan 5 04:49:02 2007 +0000 + + Fix generic BSD tun device to write only the actual packet length. + Due to a copy&paste bug, it tried to write a packet with the maximum size. + This was not a problem until the maximum size was increased to support VLANs. + +commit 40f02ff8eee359dc0ccc898f8da319f56af161ad +Author: Guus Sliepen +Date: Thu Jan 4 15:28:36 2007 +0000 + + Tapreader socket should be bound to localhost only. + +commit 03f3fc01e8d9402c4a14904fded883ff8cc574f6 +Author: Guus Sliepen +Date: Wed Jan 3 18:18:54 2007 +0000 + + Use a ringbuffer in shared memory to transfer packets from the tapreader thread to the main thread. + It's a wonder it ever worked before. The socket that is created is not of a + datagram type, therefore packet boundaries were not preserved, which becomes + a problem as soon as the TAP-Win32 device receives packets in fast succession. + +commit 52787a73b0211bcb4cb3cdd308b1a4c53a60f8ce +Author: Guus Sliepen +Date: Mon Dec 18 17:38:05 2006 +0000 + + Releasing 1.0.6. + +commit b32c22cf54e47677726d15a5fca7eecc2fa42754 +Author: Guus Sliepen +Date: Mon Dec 18 11:41:53 2006 +0000 + + Prevent compiler warnings about redefinition of EAI_FAMILY on FreeBSD 6.1. + +commit 855806b2f75fc1c566cfaac01c788cdc625b4687 +Author: Guus Sliepen +Date: Sat Dec 16 16:53:58 2006 +0000 + + Do a simple test for linux/if_tun.h instead of no test at all. + +commit 0322c0883b76257c0893aa75a510e264056ac15b +Author: Guus Sliepen +Date: Sat Dec 16 16:40:09 2006 +0000 + + Remove the test for linux/if_tun.h. + It has been available for years on any decent Linux distribution. + Although linux/if_tun.h is now required to compile tinc, + you can still run it on systems which only support Ethertap. + +commit b55813dc0b4a6a1f70c0f8d5f0512c8cebb4a5ba +Author: Guus Sliepen +Date: Sat Dec 16 16:34:04 2006 +0000 + + We do properly check for malloc and realloc. + +commit 5219ee25a248fe26055e54215c5027cbf8483439 +Author: Guus Sliepen +Date: Sat Dec 16 16:26:57 2006 +0000 + + Use standard autoconf macros instead of our own. + +commit 9d469a19691f9749b5d729a1ae903d7aa224a6e8 +Author: Guus Sliepen +Date: Sat Dec 16 16:26:08 2006 +0000 + + Fix rule that creates html version of manpages. + +commit dd03a003962788eb21910c3faabbda0e84eff5eb +Author: Guus Sliepen +Date: Fri Dec 15 20:44:33 2006 +0000 + + Remove old Spanish translation. + +commit 031e09f865e2c634f30fb0ed4e0b6a1f6df57588 +Author: Guus Sliepen +Date: Fri Dec 15 20:43:39 2006 +0000 + + Remove unnecessary stuff from configure.in. + +commit b834d67d7cc7d7f5d8b729b340ec0c809c7d54b6 +Author: Guus Sliepen +Date: Tue Dec 12 14:54:39 2006 +0000 + + Use the correct next pointer. + +commit 8b55dfacb199d152391aa5f7adbbbe35bceea7d7 +Author: Guus Sliepen +Date: Tue Dec 12 14:49:09 2006 +0000 + + When building the minimum spanning tree, make sure we start from a reachable node. + +commit 47d916ec5eb61fa396c0ec6962afed7885141478 +Author: Guus Sliepen +Date: Wed Nov 29 17:18:39 2006 +0000 + + Search for lzo/lzo1x.h, lzo2/lzo1x.h and lzo1x.h. + +commit 1bb5a284fec8c538f8ba243d4f9b2e46f68cd7e8 +Author: Guus Sliepen +Date: Wed Nov 29 16:57:46 2006 +0000 + + Make sure resolved addressed for outgoing connections are freed, if there are any. + +commit 5c69c390a17fc2b37218881e7285b639b79cfc5a +Author: Guus Sliepen +Date: Tue Nov 14 15:43:28 2006 +0000 + + Releasing 1.0.5. + +commit e5b1b5cefb82531e8a700c2ee251da1bb0a06fbf +Author: Guus Sliepen +Date: Tue Nov 14 12:28:04 2006 +0000 + + EWOULDBLOCK does not exist on platforms without O_NONBLOCK + +commit 3353ab37c2d6fb3652fbf7a85d85997be1c0c1b5 +Author: Guus Sliepen +Date: Sat Nov 11 22:45:45 2006 +0000 + + When deleting an entire tree, start at head, not at root. + +commit 0714ac6c59099a398e67770ad9c72fcec615812b +Author: Guus Sliepen +Date: Sat Nov 11 22:44:15 2006 +0000 + + Nodes use events, so event system should be initialised first and destroyed last. + +commit 35e4096120236db8d64a767f1ccdd6bf03a091fc +Author: Guus Sliepen +Date: Sat Nov 11 21:37:22 2006 +0000 + + Update Dutch translation. + +commit 315ef3e42bf16e03cfbea763442a52389a16b832 +Author: Guus Sliepen +Date: Sat Nov 11 20:37:58 2006 +0000 + + Document GraphDumpFile option. + +commit 8d393b30a922110ec77d5b243347416b50cd2160 +Author: Guus Sliepen +Date: Sat Nov 11 20:10:46 2006 +0000 + + Support and autodetect LZO version 2.0 and later. + +commit bdb3c24cea06e9557738b42e3c37cd036613b58d +Author: Guus Sliepen +Date: Sat Nov 11 20:06:14 2006 +0000 + + Support and autodetect LZO version 2.0 and later. + +commit 0d1ac68c59db87141616f69bcd3d79c705b1ecd0 +Author: Guus Sliepen +Date: Sat Nov 11 14:37:03 2006 +0000 + + popen() requires pclose(). + +commit 0200d3cd5d773d9b101c33264532d2a301c2af32 +Author: Guus Sliepen +Date: Sat Nov 11 14:11:16 2006 +0000 + + Added graph dumping ability based on Markus Goetz's patch. + +commit 1728d5b2c43b33700a9997f97fe8503ad1cf3585 +Author: Guus Sliepen +Date: Sat Nov 11 13:43:00 2006 +0000 + + The "active" bit in node.status is not used. + +commit 134dc8995b296b0bd8b346617c705204b0f3125c +Author: Guus Sliepen +Date: Wed Aug 9 22:31:10 2006 +0000 + + memcpy() addresses from packet headers before calling the lookup functions. + This probably fixes a problem on the ARM architecture that causes tinc to fail to lookup IPv4 addresses. + +commit 64e0519cb5042b251e7345f07429e8b82e2ac09b +Author: Guus Sliepen +Date: Tue Aug 8 13:50:58 2006 +0000 + + Remove unused variable. + +commit ddcf079cad3351f0823fc07af15787d02e5f1901 +Author: Guus Sliepen +Date: Tue Aug 8 13:44:37 2006 +0000 + + Remove unused parameter from maskcmp(). + +commit c620df3c1511643aa533ca31afc17db75b7255b8 +Author: Guus Sliepen +Date: Tue Aug 8 13:44:19 2006 +0000 + + Remove unused variables. + +commit 9fa27097dd82e20299f5277ecb4efffb4a99669c +Author: Guus Sliepen +Date: Tue Aug 8 13:29:17 2006 +0000 + + Fix format string warnings. + +commit eb391c52eed46f3f03b404553df417851fc0cb90 +Author: Guus Sliepen +Date: Tue Aug 8 13:21:08 2006 +0000 + + Do not break strict aliasing of status_t structs. + +commit 2077451e07f93edc520cf5bc31815624a2b03fdd +Author: Guus Sliepen +Date: Mon Jun 12 21:45:39 2006 +0000 + + Add generic host-up and host-down scripts. + Thanks to Menno Smits for a patch. + +commit f88c9942e1e3d4d463ec71ba5a60d045381bda8f +Author: Guus Sliepen +Date: Sun Jun 11 18:53:27 2006 +0000 + + Use memcpy() to copy sockaddrs returned by getaddrinfo(). + Thanks to Miles Nordin for spotting this. + +commit 412f3fb5101514d9a7d4d9e5729ee9c665a07cb6 +Author: Guus Sliepen +Date: Wed Apr 26 16:29:47 2006 +0000 + + Restore length of the original packet in send_udppacket(). + +commit de78d79db84c486afcc353884ec1770866beb653 +Author: Guus Sliepen +Date: Wed Apr 26 13:52:58 2006 +0000 + + Update copyright notices, remove Ivo's email address. + +commit 8ebb017a10cd85406ddf5ab60d8ef1f56df526ff +Author: Guus Sliepen +Date: Wed Apr 12 08:38:35 2006 +0000 + + Fix a bug in handling prefixlengths that are not a multiple of 4. + Thanks to Sven-Haegar Koch for spotting the bug and providing the fix. + +commit af95368c0f30955f0e13b587d5d6d4989fd5a83e +Author: Guus Sliepen +Date: Sun Mar 19 13:06:21 2006 +0000 + + Fix signedness compiler warnings. + +commit fb1cda2ca4ca74a85e88c39c11b97340e6495a08 +Author: Guus Sliepen +Date: Sun Mar 19 12:43:45 2006 +0000 + + Export flush_meta(). + +commit 098090468a9e1e8c5cdb0aeefa277329ff5f3406 +Author: Guus Sliepen +Date: Sun Mar 19 12:43:28 2006 +0000 + + Missing #include. + +commit a90f1b652c0fb52950f3b0783a7e2b7f2e0cf2db +Author: Guus Sliepen +Date: Mon Feb 6 12:30:51 2006 +0000 + + Make sure $NAME is set correctly when executing tinc-down script. + +commit 228e7a5c8f0e517dcede50f886965a44fca39853 +Author: Guus Sliepen +Date: Thu Jan 19 17:13:18 2006 +0000 + + Apply patch from Scott Lamb adding an output buffer for the TCP sockets. + This helps coalescing multiple send_meta() commands into one TCP packet. + Also limit the size of the output buffer before dropping PACKETs. + +commit a5a4d2b865879b8694760c0a5b5909c9a3675027 +Author: Guus Sliepen +Date: Fri Jan 13 11:21:59 2006 +0000 + + Apply patch from Scott Lamb unifying configuration of TCP socket options. + +commit e02f13cdb3133c33ac84d9582e2f47ca5ebd35bf +Author: Guus Sliepen +Date: Fri Jan 13 11:09:19 2006 +0000 + + EVP_Cleanup() when quitting. + +commit 0912260755021b9b836830dd99ae128c5fd912d9 +Author: Guus Sliepen +Date: Wed Nov 16 10:45:11 2005 +0000 + + Enable OpenSSL ENGINE, so crypto hardware gets used. Thanks to Andreas van Cranenburgh. + +commit 64e4c12778697f71ad3fcf33ee6cf1066322caa5 +Author: Guus Sliepen +Date: Fri Jun 3 10:56:02 2005 +0000 + + Add alloca.h to the list of necessary header files. + +commit e810545dc2ae158745624c1575b76c55f883c892 +Author: Guus Sliepen +Date: Fri Jun 3 10:16:03 2005 +0000 + + Prevent possible buffer overflows when using very large (>= 8192 bit) RSA keys. + Thanks to Tonnerre Lombard for noticing! + +commit 02746165a21a4a495d0069526c9a2355110a5784 +Author: Guus Sliepen +Date: Wed May 4 19:38:28 2005 +0000 + + Releasing 1.0.4. + +commit df3220a1549f992cbf4a9b6e67c1e67b69896c7d +Author: Guus Sliepen +Date: Wed May 4 18:09:30 2005 +0000 + + Update copyright notices. + +commit 54a30e30ad41d7c0e73fcc4e6ff23c3e85af75c4 +Author: Guus Sliepen +Date: Wed May 4 16:53:11 2005 +0000 + + Describe subnet-up/down scripts in documentation. + +commit bded1b74cc23c60e7319ed9e7465413b94a7914e +Author: Guus Sliepen +Date: Wed May 4 15:56:25 2005 +0000 + + Several splay tree fixes. + +commit faaaa1ef38dcdf19d5d5d73ab66806b15467c043 +Author: Guus Sliepen +Date: Wed May 4 15:52:55 2005 +0000 + + Searching through splay trees may change the tree variable. + +commit dc09f6fe896f5e35fffe8cc2004781b2e1b6fd5a +Author: Guus Sliepen +Date: Wed May 4 15:51:45 2005 +0000 + + Be on the safe side with initialisation of c->name. + +commit 92c4a28d7d43b68a324cf2eca741298ed6b692d6 +Author: Guus Sliepen +Date: Wed Apr 6 20:43:37 2005 +0000 + + Remove unused (and potentially segfaulting) net2str() call. + +commit 6363ed4d9c675b8b9301b694c4e4dd9c892e04e2 +Author: Guus Sliepen +Date: Thu Jan 20 15:14:25 2005 +0000 + + Don't try to add a non-existing node back to the node_udp_tree. + +commit 39fe3b445c2f20b325ee492dd1845877777b25c8 +Author: Guus Sliepen +Date: Tue Jan 4 22:19:56 2005 +0000 + + Nodes should only be in the node_udp_tree if they are reachable. + +commit fe0bfa3e65049d6e7cd46cf6caea7eb91b478008 +Author: Guus Sliepen +Date: Tue Jan 4 22:18:58 2005 +0000 + + Correct size argument for strncat(). + +commit 56c36a14d87b58c14dbc48df4d3d977207e2c06e +Author: Guus Sliepen +Date: Fri Dec 3 13:27:33 2004 +0000 + + Use the proper free function. + +commit 18c617ecf29b9dfb95227e764c76fff0f9d7af96 +Author: Guus Sliepen +Date: Fri Dec 3 13:22:18 2004 +0000 + + Free memory used by connection_t after it is deleted from the connection tree. + +commit 672ad5634cbedfbd6345e887935eed3e806f1e2d +Author: Guus Sliepen +Date: Wed Dec 1 21:26:51 2004 +0000 + + Small fix. + +commit 40b1692940a8d588c08fb6b8f24ded7c33b041b1 +Author: Guus Sliepen +Date: Wed Dec 1 20:06:39 2004 +0000 + + subnet-up/down hooks, use list_t for the todo list. + +commit c46f56a8b8bb865dd8951441b5acf4701b5b5b09 +Author: Guus Sliepen +Date: Wed Dec 1 20:06:05 2004 +0000 + + subnet-up/down hooks + +commit f08baa3072e7cd6cee7a2a7cde35b46c85363baf +Author: Guus Sliepen +Date: Thu Nov 18 20:34:48 2004 +0000 + + Fix splay tree code. + +commit 0077cfaae112b63d6af6aa1e5d079cebdde84b74 +Author: Guus Sliepen +Date: Tue Nov 16 19:02:54 2004 +0000 + + Make sure broadcast packet reach the local network interface. + +commit 79c48cfafd75dfc86a382f6454a9f009d3c099b6 +Author: Guus Sliepen +Date: Thu Nov 11 19:42:25 2004 +0000 + + Releasing 1.0.3. + +commit 2771691bfc85b2544b30ccaee8a709bd26c7e1ab +Author: Guus Sliepen +Date: Thu Nov 11 19:39:28 2004 +0000 + + Add more people who have contributed to tinc. + Remove details and sort on name; + the details were not always equally accurate and are hard to maintain. + +commit 4f3f6f07b234b4abd32bf3bae1be0551bc7dd9dc +Author: Guus Sliepen +Date: Thu Nov 11 11:17:04 2004 +0000 + + Short readme about how to compile tinc from a Subversion checkout. + +commit 704c3707c2c400b7e35ef4ac2c1d21e0f2de0187 +Author: Guus Sliepen +Date: Wed Nov 10 23:28:32 2004 +0000 + + Updated dutch translation. + +commit a20eb05714f828be7dc0f78c1a07f218a3482dff +Author: Guus Sliepen +Date: Wed Nov 10 23:21:41 2004 +0000 + + Remove duplication. + +commit d8fe2ecdd8dc5caf6f8d6acf2923a0baed64735f +Author: Guus Sliepen +Date: Wed Nov 10 23:20:59 2004 +0000 + + Set BSD tuns to broadcast mode. On OpenBSD, this enables IPv6 on the tun device! + +commit 2369b0ab09a008c519cd4307b634fd294c66014e +Author: Guus Sliepen +Date: Wed Nov 10 21:57:04 2004 +0000 + + Update documentation. + +commit 4fe7aff4d1b8605d4997b842481cc78bd062fe2a +Author: Guus Sliepen +Date: Wed Nov 10 21:56:31 2004 +0000 + + Add BlockingTCP option, useful when using TCPOnly on slow or congested links. + +commit 5bba3124c8c23568def7a4804651a53f3a6b4fd2 +Author: Guus Sliepen +Date: Wed Nov 10 21:14:08 2004 +0000 + + Support tunneling IPv6 on Solaris. + +commit d02d81ff9dbb12253957065752c56785aedccee3 +Author: Guus Sliepen +Date: Wed Nov 10 19:36:02 2004 +0000 + + Let compiler decide when to inline. + +commit db68db4b0e0f8b776f2d3dc938fb81dac975fdd8 +Author: Guus Sliepen +Date: Wed Nov 10 19:34:38 2004 +0000 + + Fix order of arguments for tar. + +commit 923abcfa35c7282251d507af83d6163df76c943b +Author: Guus Sliepen +Date: Wed Nov 10 18:11:44 2004 +0000 + + Use the generic BSD tun/tap code. + +commit e8b11b1cca11f7f50542a7b34f4251f43447db0d +Author: Guus Sliepen +Date: Wed Nov 10 18:10:59 2004 +0000 + + Missing check for NULL-pointer. + +commit ca7948fc06fd0495dc8104d7f55948f702ac09e2 +Author: Guus Sliepen +Date: Tue Nov 9 09:51:35 2004 +0000 + + Hopefully this really fixes late packet handling. + +commit f7b9761000000063bd00460af4b57117db7361e4 +Author: Guus Sliepen +Date: Mon Nov 8 22:30:13 2004 +0000 + + Fixed another bug in late packet handling. + +commit 14eab178295768311d4518289533005991add8ba +Author: Guus Sliepen +Date: Mon Nov 8 22:11:33 2004 +0000 + + Update to make it compile again. + +commit 804b2892a5e26a2dc46d19397cc8b321b43b8add +Author: Guus Sliepen +Date: Mon Nov 8 22:03:28 2004 +0000 + + Hoopjumping to get the default directories in the manuals properly. + +commit 719cb95ea4fa7a2e6f4291aed607323f290c7a91 +Author: Guus Sliepen +Date: Tue Nov 2 20:50:53 2004 +0000 + + Splay trees. + +commit 2af1538976c9c85c40becfdd8601b421ad2ab057 +Author: Guus Sliepen +Date: Mon Nov 1 17:05:09 2004 +0000 + + Don't include .svn directory in sample configuration. + +commit dced64c5c3625f6d2f0674e9fed14455aabc635e +Author: Guus Sliepen +Date: Mon Nov 1 17:04:28 2004 +0000 + + Check for sys/uio.h, net/if_tun.h and net/if_tap.h + +commit 1f00810da336f3b7132df17b7fe4625748ff4b63 +Author: Guus Sliepen +Date: Mon Nov 1 17:02:19 2004 +0000 + + static + +commit 82b29e9a3b1dc6b2104ab92ed78bf431a4e55649 +Author: Guus Sliepen +Date: Mon Nov 1 17:01:56 2004 +0000 + + Generic device driver for *BSD and MacOS/X + +commit 922e5b7beaad5bb3fcbfa6b8dd13c05bda29e5fa +Author: Guus Sliepen +Date: Mon Nov 1 15:18:53 2004 +0000 + + Support alternative tun/tap driver from http://www-user.rhrk.uni-kl.de/~nissler/tuntap/ + +commit faff6498821555e6afb3dc5e4e3b61d448a4fef1 +Author: Guus Sliepen +Date: Mon Nov 1 15:18:22 2004 +0000 + + Don't let tinc service depend on NDIS component. + +commit 396ac4be802f8b75c5a2ab5925925427c61c1da3 +Author: Guus Sliepen +Date: Mon Nov 1 15:16:12 2004 +0000 + + Correct return value. + +commit 58153cca98fd43c37ae52d3cf69474c3d736c431 +Author: Guus Sliepen +Date: Fri Oct 1 18:26:15 2004 +0000 + + Allow tinc to work with the latest TAP-Win32 driver. + +commit 6411e0d8bda8abc2cef87ca852255502f9bb03d0 +Author: Guus Sliepen +Date: Fri Oct 1 18:24:41 2004 +0000 + + strndupa() is too arcane for some environments. + +commit b0a80007e8945a11d7ce25aab096c5ee58ce0ad5 +Author: Guus Sliepen +Date: Fri Oct 1 18:23:08 2004 +0000 + + Fix several #includes. + +commit 2c40495747945bc497dac65b734a4995ab3400a3 +Author: Guus Sliepen +Date: Fri Oct 1 18:22:06 2004 +0000 + + Move all #ifdef HAVE_HEADER_H #include to have.h, + this allows for simplification of configure.in. + +commit 7717cb0c54cc1b736b9f210b180c3cb3f4663ded +Author: Guus Sliepen +Date: Mon Sep 20 20:56:14 2004 +0000 + + Remove duplicate #include "system.h" + +commit 5373129344d349ff6aeb2b3d21f947f5ecbbcfaf +Author: Guus Sliepen +Date: Mon Sep 20 20:55:49 2004 +0000 + + Marking potential late packets was in the wrong place. + +commit c44f69a30243a94ab93bd15915dbfa71db698bde +Author: Guus Sliepen +Date: Sat Jul 17 12:04:30 2004 +0000 + + Don't set $INTERFACE automatically, don't quit on EINTR/EAGAIN. + +commit dcec713675b604f5ef82e64d0671727e3f5ea518 +Author: Guus Sliepen +Date: Sat Jul 17 00:09:14 2004 +0000 + + Added UML network socket handling. + Now you can use tinc instead of uml_switch. + +commit fe84fafcb684391739a1b3366705c58683210392 +Author: Guus Sliepen +Date: Mon Jun 21 14:37:52 2004 +0000 + + Handle timeouts during connecting the same way as other errors. + +commit e5e0dd7534be5fb96032fb733ca36a09cb067f17 +Author: Guus Sliepen +Date: Mon Jun 14 14:32:10 2004 +0000 + + Clean up environment after executing scripts. + +commit 9e44f116bf0f72d1dd4f099440a351dbe0a74573 +Author: Guus Sliepen +Date: Thu Apr 15 14:09:56 2004 +0000 + + Increase MTU by 4 bytes to allow VLAN tagged Ethernet frames in hub and switch mode. + +commit 7926a156e5b118d06295228e57de0cc9de0433b4 +Author: Guus Sliepen +Date: Sun Mar 21 14:21:22 2004 +0000 + + Update copyrights, links, email addresses and let Subversion update $Id$ keywords. + +commit 42e01abd54bd36ee84a45a2b646cfa27034de8d1 +Merge: 5ca64f89 af86a322 +Author: Guus Sliepen +Date: Sun Mar 21 13:22:24 2004 +0000 + + Move CABAL branch to its rightful place: the trunk. + +commit af86a3226ea42375644b3f99c182c778d327de1e +Author: Guus Sliepen +Date: Sat Mar 20 22:23:42 2004 +0000 + + Revert Martin Kihlgren's patch, it doesn't work the way it should. + +commit 27c304940a5dbe83fb0f655c5c43150bafed3b63 +Author: Guus Sliepen +Date: Sat Mar 20 15:40:26 2004 +0000 + + Use Subversion to create ChangeLog, better svn-clean rule. + +commit 8df22248293a8cd5e6056415b6e08740e40aa2bc +Author: Guus Sliepen +Date: Sat Mar 20 15:33:07 2004 +0000 + + Fix declaration of update_node_address(). + +commit 56aad1bb486675ff9aba31418708cc179eea0381 +Author: Guus Sliepen +Date: Sat Mar 20 15:28:55 2004 +0000 + + Applied Martin Kihlgren's IdentityGenerosity patch, + simplified and renamed to StrictSource. + +commit 8c189c2a9b77fb326ab5f27a05bf2601e16af017 +Author: Guus Sliepen +Date: Mon Mar 15 19:09:52 2004 +0000 + + Even better svn-clean command. + +commit b05df3fcbfb8dbef4c87691d118c5b68aeb79e4a +Author: Guus Sliepen +Date: Mon Mar 15 18:36:14 2004 +0000 + + Updating dutch translation. + +commit a92c471a2bc0773a7473ef0361d1a51fafee50d4 +Author: Guus Sliepen +Date: Mon Mar 15 18:15:02 2004 +0000 + + Only read our public key if it wasn't already in the private key file. + +commit a67a21ef3c17d32af95373e921138429a7fc507e +Author: Guus Sliepen +Date: Mon Mar 15 18:05:41 2004 +0000 + + Eat trailing whitespace in config files. + +commit 4350704d6578656af98195b26006c6b6d6a798e3 +Author: Guus Sliepen +Date: Mon Mar 15 17:54:19 2004 +0000 + + Remove CVS related cruft. + +commit 538595f7350ba6c7d11aba7d9f481ea1641e1857 +Author: Guus Sliepen +Date: Mon Mar 15 17:53:17 2004 +0000 + + Replace cvs-clean with a much better svn-clean. + +commit 5ca64f89be71131e77a29661827dc8866a5f278c +Author: cvs2svn +Date: Sat Jan 10 23:21:36 2004 +0000 + + This commit was generated by cvs2svn to compensate for changes in r1352, + which included commits to RCS files with non-trunk default branches. + +commit fcd836c609568fab323f4af6dd525de957a6f4cc +Author: Guus Sliepen +Date: Sat Jan 10 23:21:36 2004 +0000 + + Remove autogen.sh, the autoreconf program does exactly that. + Update everything for the latest autoconf and automake versions. + +commit f2aa7466e6db9777090583ef26d923fc0a4fcea8 +Author: Guus Sliepen +Date: Sat Jan 10 23:19:20 2004 +0000 + + Small updates. + +commit 519d63bedbdcc533dd7839aae02b4d7bc2debfb0 +Author: Guus Sliepen +Date: Sat Dec 27 16:32:52 2003 +0000 + + Don't forget to update destination MAC address. + +commit aebc97a77f37ec63fbd36721f9b284c975e54270 +Author: Guus Sliepen +Date: Wed Dec 24 10:48:15 2003 +0000 + + Small fixes for PMTU discovery. + +commit 2c7ce7de12d16cb407fd40224b6cb802528ee942 +Author: Guus Sliepen +Date: Mon Dec 22 11:05:23 2003 +0000 + + Missing definitions. + +commit 35399784b695c9ac692beba7be7930ee9f24412f +Author: Guus Sliepen +Date: Mon Dec 22 11:04:17 2003 +0000 + + Improvements for PMTU discovery and IPv4 packet fragmentation. + +commit 6d41b429a26dd1acaa7c56b2124f2daf55b5b97c +Author: Guus Sliepen +Date: Sat Dec 20 21:25:17 2003 +0000 + + Better name, show probed MTU in dump. + +commit af490a745d4ddc8994ceca546b5f9139f6a6ebe2 +Author: Guus Sliepen +Date: Sat Dec 20 21:20:10 2003 +0000 + + Describe the TunnelServer and PMTUDiscovery options. + +commit 9bab08e972ae0ca4b904a659d9aed46aaa9b5dd5 +Author: Guus Sliepen +Date: Sat Dec 20 21:09:33 2003 +0000 + + More sensible name, and try to set PMTU discovery on IPv6 sockets as well. + +commit 6b12bea62fe2e4bd8b5b6bd0e5ca7f53318705db +Author: Guus Sliepen +Date: Sat Dec 20 19:47:53 2003 +0000 + + Let tinc figure out the exact MTU of the link. + +commit e8fbef5de653e4df35eee49aae6e1ac92d6466e6 +Author: Guus Sliepen +Date: Sat Dec 13 21:50:26 2003 +0000 + + Forget multicast. Always inline some function. + +commit 5a1406adefd8b51981af0da5ac0ebec830eb43b4 +Author: Guus Sliepen +Date: Fri Dec 12 19:52:25 2003 +0000 + + Code beautification, start of multicast support. + +commit 354b7ab20e04736b368985a9e9dfd54ff5b7584e +Author: Guus Sliepen +Date: Mon Dec 8 12:00:40 2003 +0000 + + Fix proxy-neighborsolicitation. + +commit 331cef948db4b3cca245ab62cb0fafb5b1e5ebb3 +Author: Guus Sliepen +Date: Sun Dec 7 14:31:09 2003 +0000 + + Don't retry if configuration is wrong from the beginning. + +commit a3cd273751fdcef90a43108a5d2e669877b0bccb +Author: Guus Sliepen +Date: Sun Dec 7 14:29:02 2003 +0000 + + Missing space between words. + +commit 25447b384173cc3c99660c784fd784c787917e80 +Author: Guus Sliepen +Date: Sun Dec 7 14:28:39 2003 +0000 + + Read MaxTimeout from tinc.conf like the manpage says. + +commit 0b5e6cf04ec0c7e3c54c74a54a32b30e6e3c1f83 +Author: Guus Sliepen +Date: Thu Nov 27 23:24:59 2003 +0000 + + Complain if pid file cannot be created. + +commit e3220cacb5bc79fc56167e61b7a342f88a33a479 +Author: Guus Sliepen +Date: Mon Nov 17 15:30:18 2003 +0000 + + Replace Opaque and Strict options with a TunnelServer option. + +commit 0e59fb022c6c015a5be7ed70e0378cb011be98b5 +Author: Guus Sliepen +Date: Mon Nov 10 22:31:53 2003 +0000 + + Add Opaque option which prevent information from being forwarded to certain nodes. + +commit a8f415e67fd316d929f9b9e6661e0d3d66fc197b +Author: Guus Sliepen +Date: Sat Nov 8 15:29:40 2003 +0000 + + Release notes for 1.0.2 + +commit 507a83c74635955f803bb26c450f3e83dd4809f9 +Author: Guus Sliepen +Date: Sat Nov 8 15:09:03 2003 +0000 + + Add missing definitions. + +commit 0271de0e80459bdebcac50d38c053d4aaf657e9a +Author: Guus Sliepen +Date: Sat Nov 8 12:56:24 2003 +0000 + + Update dutch translation. + +commit d35a510fff65a7a3318036f27c11b956526b26f6 +Author: Guus Sliepen +Date: Sun Oct 12 11:40:00 2003 +0000 + + Fix another bug in meta.c. + +commit e88ea7277a97d46fa2c3ba1896cf0d0c62bdf128 +Author: Guus Sliepen +Date: Sat Oct 11 14:42:30 2003 +0000 + + Small fixes in documentation. + +commit ffb7327c20952cefcb5578e40f9802295172c5c2 +Author: Guus Sliepen +Date: Sat Oct 11 14:18:52 2003 +0000 + + Fix bug that could lead to an assertion failure in libcrypto when multiple + requests arrive and TCP packets are heavily fragmented. + +commit 258b7ce220607bb3f2a24bb7cab5fcd19e82314a +Author: Guus Sliepen +Date: Sat Oct 11 12:28:48 2003 +0000 + + Parentheses in the wrong spots. + +commit a1ab57e2755df6c1a8fab95a0886fea368200b96 +Author: Guus Sliepen +Date: Sat Oct 11 12:16:13 2003 +0000 + + Check all EVP_ function calls. + +commit b0dd705a264f0f72a7afba6de85200598cbe083b +Author: Guus Sliepen +Date: Fri Oct 10 16:24:24 2003 +0000 + + Check return value of EVP_* functions, and check if length before en/decryption + matches that after in meta.c. + +commit 9d2bf718f233672c11a9740ed2a1539eaab1509b +Author: Guus Sliepen +Date: Fri Oct 10 16:23:30 2003 +0000 + + Fix ASCII art. + +commit e33307fc9f5354933554d26de618db1b08fc04c0 +Author: Guus Sliepen +Date: Thu Oct 9 21:33:15 2003 +0000 + + Update documentation. + +commit 98edfb14fcc7167d24d440ed2772d0755daac3b7 +Author: Guus Sliepen +Date: Wed Oct 8 12:09:37 2003 +0000 + + Some platforms don't know sa_family_t or define it other than uint16_t. + +commit f2ebdf75806d8c04138db0eb30727f846541ed75 +Author: Guus Sliepen +Date: Wed Oct 8 11:37:53 2003 +0000 + + Set media status for newer TAP-Win32 driver. + +commit acf5f9c968d17ad3e31129d2184309de06d72eed +Author: Guus Sliepen +Date: Wed Oct 8 11:37:20 2003 +0000 + + Missing declaration. + +commit 1d7706a8506d8073def0965da809960c6ad8bf9a +Author: Guus Sliepen +Date: Wed Oct 8 11:34:55 2003 +0000 + + Update missing definitions, structs describing headers get __packed__ attribute. + +commit 5b556c0971e847580b85268e57f0b29dbde5499c +Author: Guus Sliepen +Date: Wed Oct 8 11:33:54 2003 +0000 + + Forgot to #include "xalloc.h" + +commit ad39db95fecf760297b4e320ef2f6d6d9fdad605 +Author: Guus Sliepen +Date: Mon Oct 6 16:49:42 2003 +0000 + + Make sure type of AF_UNKNOWN is sa_family_t. + +commit 5900c07fab39d2833ea66429ad652ca49a91a508 +Author: Guus Sliepen +Date: Mon Oct 6 16:13:08 2003 +0000 + + PIDs are of type pid_t, and use %ld when reading/writing them to the pidfile. + +commit e898b930dcd0694a49dc8cdcf373e0fc125c9fde +Author: Guus Sliepen +Date: Mon Oct 6 16:05:30 2003 +0000 + + Use CPPFLAGS, LDFLAGS and LIBS as appropiate. + +commit 6350334aa44f85e737c1eb0b55e0392766aa1e84 +Author: Guus Sliepen +Date: Mon Oct 6 14:41:45 2003 +0000 + + Don't confuse users with "Address family not supported" warnings. + +commit 0842998c0bd46855d198923acc2c13cff7430ffe +Author: Guus Sliepen +Date: Mon Oct 6 14:33:04 2003 +0000 + + Unused variable in struct. + +commit 77cb10dac0abbfa4389a7588f51797152d91ac22 +Author: Guus Sliepen +Date: Mon Oct 6 14:16:51 2003 +0000 + + Ethernet protocol types. + +commit c97b8827ed34284535706e8017c962ff8f3a4383 +Author: Guus Sliepen +Date: Mon Oct 6 13:57:12 2003 +0000 + + const + +commit 60943122f7b3a5896ce64c9000e119931484c12c +Author: Guus Sliepen +Date: Mon Oct 6 13:49:57 2003 +0000 + + Copy structs from packets to the stack before using them, to prevent + alignment issues. + +commit 5713fb07b3e831b78d8841d56a53c2a2698fe738 +Author: Guus Sliepen +Date: Wed Oct 1 09:43:01 2003 +0000 + + Add description of new authentication scheme. + +commit acbb9d6692614539260749c7b763eca5a6f81f07 +Author: Guus Sliepen +Date: Wed Oct 1 09:14:01 2003 +0000 + + Better length checks. + +commit eeb97e3ef4eb9089851f7b71d5393df24313c993 +Author: Guus Sliepen +Date: Thu Sep 25 10:34:16 2003 +0000 + + Generate keys with 0x10001 as public exponent, which has less prime factors + than 0xFFFF. + +commit 288d956728ab4d4aabe9bc59b87991420dbda151 +Author: Guus Sliepen +Date: Tue Sep 23 20:59:01 2003 +0000 + + Check for short packets from the tun/tap device and from other tinc daemons. + +commit 4e80612ac0f38daa0f2280c293427c7f25dac278 +Author: Guus Sliepen +Date: Tue Sep 9 15:47:59 2003 +0000 + + Update translations. + +commit cbf5a741aa2af937b3db606f0894990703f77bcb +Author: Guus Sliepen +Date: Mon Sep 8 21:52:47 2003 +0000 + + Remove pidfile when exitting. + +commit 0dba26267c76982a422984b61a3196ed2cd2b04a +Author: Guus Sliepen +Date: Wed Sep 3 16:20:33 2003 +0000 + + Prevent multiple inclusions. + +commit 6c5f3d8b74ffea1522a727ef189a5ba65a939e07 +Author: Guus Sliepen +Date: Thu Aug 28 21:05:11 2003 +0000 + + We don't have to tell GCC how to cast. + +commit 762cc2d2797d62ab593ea64d8ceeb4fe96be2a0d +Author: Guus Sliepen +Date: Thu Aug 28 15:27:12 2003 +0000 + + Remove old edges from unreachable nodes to us. This prevents the hosts/NAME-up + script from being called twice in some situations. + +commit a6dc69e7f30522bf885714f6b663960b6fbfff6a +Author: Guus Sliepen +Date: Wed Aug 27 13:58:29 2003 +0000 + + Forgot to synchronise po/ directory... + +commit 62349da6f2617c7250a77af6610344ec0dbfc4f2 +Author: Guus Sliepen +Date: Wed Aug 27 13:57:04 2003 +0000 + + Makevars file was accidentily removed. + +commit dc3b7d47f3297e22161787a1d6e06205140cf0fb +Author: Guus Sliepen +Date: Wed Aug 27 13:47:52 2003 +0000 + + Some device.c files weren't synchronised. + +commit 9e81a6ab5f50df4f5ca36d5303b91a8d5a0e753e +Author: Guus Sliepen +Date: Sun Aug 24 20:50:30 2003 +0000 + + This will become 2.0. + +commit 013a2e159e42c46808ea8d0b6abd57525db30a50 +Author: Guus Sliepen +Date: Sun Aug 24 20:38:31 2003 +0000 + + Synchronise HEAD with CABAL branch. + +commit ffb55e6904426a31c03b56c3bd87bb60db0624c6 +Author: Guus Sliepen +Date: Fri Aug 22 21:32:45 2003 +0000 + + Add license exception from Markus Oberhumer. + +commit 3e0b28b0c4d874934dde7b487a56cfacc956e3b4 +Author: Guus Sliepen +Date: Fri Aug 22 15:07:57 2003 +0000 + + Remove debug message. + +commit 89c9f3ed8fddb316d0f9ef7de30bdc76fba39e41 +Author: Guus Sliepen +Date: Fri Aug 22 15:04:26 2003 +0000 + + When purging nodes, only delete them if nobody references them anymore. + +commit 22dd23b650eb9b760bc68ab3a9227caf3b449140 +Author: Guus Sliepen +Date: Fri Aug 22 15:03:59 2003 +0000 + + Add checkpoints. + +commit 570e7e9c615388cfba263c7a7c66cbc3d092d6e7 +Author: Guus Sliepen +Date: Fri Aug 22 15:05:01 2003 +0000 + + Don't overwrite the first " when installing a service. + +commit 72bdc05cb7e246e56ed21a25256d441c45fccca8 +Author: Guus Sliepen +Date: Fri Aug 22 11:18:42 2003 +0000 + + Allow tinc to handle unknown type addresses from other tinc daemons. + +commit 5ac4179df66747a7013a10d576c23531d2b4fc58 +Author: Guus Sliepen +Date: Sun Aug 17 12:05:08 2003 +0000 + + If we're not in main_loop() and the service is stopped, exit immediately. + +commit 46cfe6199449a86eb58abaeac45b4021ffa7e178 +Author: Guus Sliepen +Date: Sun Aug 17 12:04:35 2003 +0000 + + Do what the SDK documentation tells. + +commit 107448698fc078bbd4cdbacdfbf51298ddc9ea65 +Author: Guus Sliepen +Date: Sun Aug 17 12:03:40 2003 +0000 + + Compilation fix. + +commit 3112e6a863b4421eb1a0b32632b86c55e47f989e +Author: Guus Sliepen +Date: Sun Aug 17 09:04:00 2003 +0000 + + Use the event log under Windows. + +commit 5e7c52610f8c8b9c38e437ef166a08372d5b8a61 +Author: Guus Sliepen +Date: Sun Aug 17 09:03:30 2003 +0000 + + Fix --logfile under Windows. + +commit 2236e05e518c9e317d82c027596bea5228725214 +Author: Guus Sliepen +Date: Sun Aug 17 08:32:39 2003 +0000 + + Fix fake getnameinfo() and check more arguments. + +commit f4e80cc5e0d1689bcdd828ac7f158bd634b7dd20 +Author: Guus Sliepen +Date: Sat Aug 16 12:40:01 2003 +0000 + + Don't getsockopt() SO_ERROR. We get the error from send()/recv() anyway. + +commit fd40130eb6bbba34176d34936a01bb6a6f9121d4 +Author: Guus Sliepen +Date: Sat Aug 16 12:11:11 2003 +0000 + + stat() batch files under Windows. + +commit 03995ca52ee31ed505902a3c8c3d1119988c8497 +Author: Guus Sliepen +Date: Sat Aug 16 12:10:28 2003 +0000 + + Simplify fake getname/addrinfo() functions, possibly fixing freeing a NULL pointer. + +commit dbfd6f284e0ff0aa04e6d6e62b902966912da516 +Author: Guus Sliepen +Date: Thu Aug 14 14:32:34 2003 +0000 + + Update. + +commit 7ed25590257b6ed33dfa879d187a09b0d790794f +Author: Guus Sliepen +Date: Thu Aug 14 14:21:35 2003 +0000 + + Fix permissions check for rsa_key.priv. + +commit 1f2670aab295dfd09c8c655611d2a5b820cb00fc +Author: Guus Sliepen +Date: Tue Aug 12 14:48:13 2003 +0000 + + Small fixes. + +commit b038e8db376969e70f1315840428b8a14ec8420f +Author: Guus Sliepen +Date: Tue Aug 12 12:35:53 2003 +0000 + + Updated dutch translation. + +commit ae070b917066f612e9aba8611c7a5da88e19a51a +Author: Guus Sliepen +Date: Sun Aug 10 13:35:05 2003 +0000 + + Add a description for the Service control panel. + +commit 9b579eb9ffdc1fd4a3d0cacb0728ec0796526bc5 +Author: Guus Sliepen +Date: Sat Aug 9 00:53:22 2003 +0000 + + Update documentation. + +commit 7eed829d288d0fdec2f31709a18ec420e489c2e4 +Author: Guus Sliepen +Date: Fri Aug 8 22:45:46 2003 +0000 + + Only system() needs script name quoted. + +commit 91f65c277483b47343b1b64d0f4edd497a8045a3 +Author: Guus Sliepen +Date: Fri Aug 8 22:13:50 2003 +0000 + + Check for fchmod(). + +commit 9bde92ce97d5503ff2d31dcc6f0648902580ec14 +Author: Guus Sliepen +Date: Fri Aug 8 22:11:54 2003 +0000 + + Simpler checking of permissions on private RSA key and other fixes. + +commit 96f5d98fc299a53fcdad304a56eb3a77a2c229e7 +Author: Guus Sliepen +Date: Fri Aug 8 19:56:11 2003 +0000 + + Small things. + +commit ef65a64443f740e3b22d9e903f764d9a58ce0ff0 +Author: Guus Sliepen +Date: Fri Aug 8 19:49:47 2003 +0000 + + Better error checking and reporting. + +commit bb2f18a3fc8acb7802f30e06153def30eb97a994 +Author: Guus Sliepen +Date: Fri Aug 8 19:45:21 2003 +0000 + + Under Windows, the installation directory can be found in the registry. + +commit 7f05445047c6479b81b7d393543ff73a95ee0dc8 +Author: Guus Sliepen +Date: Fri Aug 8 19:43:47 2003 +0000 + + Quote when needed and don't try stuff that doesn't work under Windows. + +commit b4c913aaa926d80a72aeb97459f84f992b65d1ed +Author: Guus Sliepen +Date: Fri Aug 8 19:42:35 2003 +0000 + + Log error first, try to close later. + +commit b0825f36b7b5dade1693fdbddfec7eef3f5ed86f +Author: Guus Sliepen +Date: Fri Aug 8 19:39:41 2003 +0000 + + Better error messages under Windows. + +commit 6f3099595530280028f6ec3d0b310df523e75f98 +Author: Guus Sliepen +Date: Fri Aug 8 17:20:12 2003 +0000 + + Typo. + +commit 691907caaeb348dee3dbe8a85f3590241f2cc992 +Author: Guus Sliepen +Date: Fri Aug 8 17:17:13 2003 +0000 + + Readd quotes. + +commit f956a28147ec8596c9a51b0c1535bb4b8c87692c +Author: Guus Sliepen +Date: Fri Aug 8 16:49:29 2003 +0000 + + Make rule for sample-config.tar.gz. + +commit 7e74e00d167da659ba6c3db3e8822008d27c081b +Author: Guus Sliepen +Date: Fri Aug 8 14:59:27 2003 +0000 + + Allow empty lines in config files. + +commit 863349638beb1eaab09e2a3d537c20a7913aef30 +Author: Guus Sliepen +Date: Fri Aug 8 14:48:33 2003 +0000 + + Simplify execute_script(). It will probably work under Windows as well. + +commit deba3ed900eb4453d27412606cecfaf89b5a5643 +Author: Guus Sliepen +Date: Fri Aug 8 14:24:09 2003 +0000 + + Correct error message when remote host closed connection. + +commit 0c2256670fc0822cc5a86bca754186c50f943a1c +Author: Guus Sliepen +Date: Fri Aug 8 14:07:12 2003 +0000 + + Remove unused stuff from doc/. + Let configure update pathnames in documentation. + +commit 070aee3be16b8d8078b049c5bb43dce7b18123df +Author: Guus Sliepen +Date: Fri Aug 8 12:55:05 2003 +0000 + + Tell windows to be patient. + +commit adb68b9c2aa7ad72dd5c38b95c083c47599cb65a +Author: Guus Sliepen +Date: Fri Aug 8 12:24:52 2003 +0000 + + Windows uses backslashes... + +commit ef091d1ddb1f7ab5244db96841274dc769e85167 +Author: Guus Sliepen +Date: Fri Aug 8 11:45:37 2003 +0000 + + Sync CABAL branch with release-1_0 branch. + +commit 5193a14ddea4c20ffc708dc629a2f91f1e4ccea3 +Author: Guus Sliepen +Date: Sun Aug 3 21:45:41 2003 +0000 + + Use our own port when connecting to ourself. + +commit 62a7fa9a7bfd1cd1592fd7c381ea28aac0ed7936 +Author: Guus Sliepen +Date: Sun Aug 3 21:45:13 2003 +0000 + + Simplify translation + +commit 98f97da9d7d80b528d9a2b2f03f710cdd2b293d0 +Author: Guus Sliepen +Date: Sun Aug 3 21:43:19 2003 +0000 + + Update dutch translation + +commit e220187f484f3549df3ad3a04939b9a38051d1a0 +Author: Guus Sliepen +Date: Sun Aug 3 12:38:43 2003 +0000 + + Remove newlines from log messages. + +commit 3671ed806d7371fb6b14a5909451b20e54a1b14a +Author: Guus Sliepen +Date: Sun Aug 3 12:38:18 2003 +0000 + + Keep Windows happy. + +commit 7bed2a7099fc7359f6ec24e5f2d7050c7d63b6ac +Author: Guus Sliepen +Date: Sun Aug 3 12:37:55 2003 +0000 + + Cygwin needs windows.h. + +commit fa9c00733e4b793691bf5a068ff7f2f391854fb4 +Author: Guus Sliepen +Date: Sun Aug 3 09:55:20 2003 +0000 + + Old gcc compilers don't like declarations in the middle of a function. + +commit a65011b3c54cd4ddc66f20909ca0e495de0d6eb0 +Author: Guus Sliepen +Date: Sun Aug 3 09:08:52 2003 +0000 + + Clean up last part of main(). + +commit e20ac7b52da8e3f7da292836c6e2551fc9f64617 +Author: Guus Sliepen +Date: Sat Aug 2 22:01:50 2003 +0000 + + Typo and another thing to think about. + +commit 92938c07b17fdd30f4e7f9ae1b884b05c7aa312c +Author: Guus Sliepen +Date: Sat Aug 2 21:55:12 2003 +0000 + + Explain how tinc detaches and how it is "killed" under Windows. + +commit 8a1969bc8319761e3821fc76a7c2f7037ffb8850 +Author: Guus Sliepen +Date: Sat Aug 2 21:39:11 2003 +0000 + + Updated dutch translation. + +commit f605ec47bed26362e24ffacf71c7ae5aeed3c230 +Author: Guus Sliepen +Date: Sat Aug 2 21:34:10 2003 +0000 + + Oops. + +commit e6e32814584f82ee61f658a71cb435bbb491bd39 +Author: Guus Sliepen +Date: Sat Aug 2 21:33:52 2003 +0000 + + Missing include. + +commit c044d12dfd54c033bc5ad9fbf9f889724762f76c +Author: Guus Sliepen +Date: Sat Aug 2 21:33:19 2003 +0000 + + Cleanups and error messages. + +commit 3fd96ebec7e44a0a7288c60da1cdec2d4fe03e8c +Author: Guus Sliepen +Date: Sat Aug 2 21:01:50 2003 +0000 + + Error messages. + +commit f08fc359a0b7f638e73a8f866119b016b7dff8de +Author: Guus Sliepen +Date: Sat Aug 2 20:50:38 2003 +0000 + + Install tinc as a service under Windows (MinGW). Remove cleanup_and_exit(), + either exit() directly on errors or let main_loop() shutdown gracefully. + +commit 7c34122af7ed4667748ceae4966bd5b519ac8ad7 +Author: Guus Sliepen +Date: Sat Aug 2 16:05:33 2003 +0000 + + When compiling with MinGW, link with ws2_32. + +commit 9a491a10eee55b243dd1030ee9016ec510908a10 +Author: Guus Sliepen +Date: Sat Aug 2 15:32:57 2003 +0000 + + Windows has no symbolic links as we know it. + +commit 9c2d5d9f9212dee5ee988f4824e5e4afedb7a2dd +Author: Guus Sliepen +Date: Sat Aug 2 15:29:06 2003 +0000 + + Oops. + +commit c7bf64c7946ece3e1a6a7cdd7bce00045bddb9cd +Author: Guus Sliepen +Date: Sat Aug 2 15:27:24 2003 +0000 + + Allow whitespace in values. + +commit b79e55b183898911e2c2b7b151b281aef8d474e1 +Author: Guus Sliepen +Date: Sat Aug 2 15:13:08 2003 +0000 + + Prevent system headers from including our own headers. + +commit 998ac634d456567e7caf99fe879d4ef1602f36bf +Author: Guus Sliepen +Date: Fri Aug 1 08:18:22 2003 +0000 + + Wrong function... + +commit 2531ff59b73af3a6de85fdc33d744758a6ab9449 +Author: Guus Sliepen +Date: Thu Jul 31 14:24:19 2003 +0000 + + Woops! + +commit 1fe56637874a1e93882a2ca6ffb8c50a773f80e4 +Author: Guus Sliepen +Date: Thu Jul 31 13:18:34 2003 +0000 + + No easy way to properly detect header files... + +commit 8eca27e863d9cb139a1e4039f63aaac3c9afc3c6 +Author: Guus Sliepen +Date: Thu Jul 31 11:31:51 2003 +0000 + + Remove forgotten braces. + +commit 5c29d066688691dd1664597ba1c76195634f06c0 +Author: Guus Sliepen +Date: Thu Jul 31 11:20:32 2003 +0000 + + Wrong argument. + +commit da3078c63a3b658573f6e2f986f69ed4d7993b3a +Author: Guus Sliepen +Date: Thu Jul 31 11:17:39 2003 +0000 + + Check if the compiler knows about the __malloc__ attribute. + +commit d798b8b3d832f8c69769e08cfd64a4d8355faf0e +Author: Guus Sliepen +Date: Wed Jul 30 21:52:41 2003 +0000 + + Prevent definitions from messing up attributes. + +commit 2edc764a333764e7e5c4d3420131c13e9c81ecf7 +Author: Guus Sliepen +Date: Wed Jul 30 16:00:59 2003 +0000 + + Replacement for stdbool.h + +commit fcbe29bc4cc67530581a36cf1a3a1445c741b8e5 +Author: Guus Sliepen +Date: Wed Jul 30 11:50:45 2003 +0000 + + No C99 initialisers, gcc 2.95.3 doesn't like it. + Also make sure getopt.h is included. + +commit de223b51b94c58d1674f1ef56e9d485ff48d366d +Author: Guus Sliepen +Date: Wed Jul 30 09:45:21 2003 +0000 + + Remove doc/es/ and src/device.c from the distribution. + +commit 63568bb6bca20b4d2b2068a6367084a273eabac8 +Author: Guus Sliepen +Date: Wed Jul 30 09:22:29 2003 +0000 + + Update documentation and remove stuff that's too outdated. + +commit 2ed154e73192d5e162544bc570abbb3a1df3ec83 +Author: Guus Sliepen +Date: Tue Jul 29 23:21:01 2003 +0000 + + Cleanups. + +commit 721e4caee0f7c6e003c297c95fb6d93bd4102219 +Author: Guus Sliepen +Date: Tue Jul 29 22:59:01 2003 +0000 + + Native Windows support. + +commit 586f15ed20682413d1bddbb4518dd2714c96b255 +Author: Guus Sliepen +Date: Tue Jul 29 12:38:49 2003 +0000 + + Make sure (at least) the MinGW device driver works. + +commit 6f7cce69479f9b2796d81f458bf836287b74462e +Author: Guus Sliepen +Date: Tue Jul 29 12:18:35 2003 +0000 + + Make sure it works. + +commit 4370b98bb1dfa9eb1e400549cb6fcb6711aa1b29 +Author: Guus Sliepen +Date: Tue Jul 29 11:50:39 2003 +0000 + + Update configure scripts. + +commit ae50b0077e27c4c4d81a98da46c66865ffa069be +Author: Guus Sliepen +Date: Tue Jul 29 11:06:23 2003 +0000 + + Update dutch translation and make sure all device drivers are included in + the translation and distribution. + +commit 714fb32d0377ed9f5643ed8f0bd914843d12266b +Author: Guus Sliepen +Date: Tue Jul 29 10:50:15 2003 +0000 + + Fix compile errors and warnings. + +commit 0e945413315c9d15a3eb013fa3731dd978a8c7b8 +Author: Guus Sliepen +Date: Mon Jul 28 22:06:09 2003 +0000 + + More checks for missing functions. + +commit c15e8a96bf7e45adf750b7a36b0e8446ea049468 +Author: Guus Sliepen +Date: Mon Jul 28 21:54:03 2003 +0000 + + More generic handling of tap device under Windows. + +commit 83263b74460656ba557fd9bb84dc27258549e9cd +Author: Guus Sliepen +Date: Thu Jul 24 12:08:16 2003 +0000 + + Sprinkle around a lot of const and some C99 initialisers. + +commit 5cb147135184e3748c6f5e6e6203d22ab9f904f8 +Author: Guus Sliepen +Date: Wed Jul 23 22:17:31 2003 +0000 + + Don't initialise a CIPHER_CTX if cipher == NULL. + +commit 4aadb9500d9198f9c271deb048a2d36000bfae34 +Author: Guus Sliepen +Date: Tue Jul 22 21:13:23 2003 +0000 + + Run setup_device() after parsing configuration but before claiming we're ready. + +commit eefa28059ab989c915a7d95fb4ae728abd7ce713 +Author: Guus Sliepen +Date: Tue Jul 22 20:55:21 2003 +0000 + + Use bools and enums where appropriate. + +commit 471308e1636e7a06e1d9ebc98e82b1c0c5150dde +Author: Guus Sliepen +Date: Tue Jul 22 12:58:34 2003 +0000 + + Option to specify pidfile location. + +commit c96900f378966ca1be96ddb1c43f855c74083b70 +Author: Guus Sliepen +Date: Mon Jul 21 19:58:58 2003 +0000 + + Add section about configuring Cygwin and CIPE on Windows. + +commit bad82522ecfc1f3c72c600cbca6e8fa7e950c3bf +Author: Guus Sliepen +Date: Mon Jul 21 15:51:00 2003 +0000 + + Copy cygwin driver to mingw directory. It doesn't work (yet). + +commit e169244e4b10dbcc1910c0f7fd811304d5b1a5a5 +Author: Guus Sliepen +Date: Mon Jul 21 14:47:43 2003 +0000 + + Use functions from logger.c + +commit 2f2defc4525befd5b5cb69d03b7887db35e9e46c +Author: Guus Sliepen +Date: Mon Jul 21 13:18:44 2003 +0000 + + Check for sys/mman.h. + +commit 64fd25aa6b794bb1d957b50d48705f30ed47c878 +Author: Guus Sliepen +Date: Mon Jul 21 13:15:36 2003 +0000 + + Oops. + +commit c1e8152f4fe5e4557784d8411e50006d461b8786 +Author: Guus Sliepen +Date: Mon Jul 21 13:14:02 2003 +0000 + + Be consistent. + +commit b657f0519456d05bcea5742017165793f79e56df +Author: Guus Sliepen +Date: Fri Jul 18 14:10:27 2003 +0000 + + No UNIX style permissions under Windows. + +commit 38aa0319ef79124e59b587e6d55f37a79a9d847c +Author: Guus Sliepen +Date: Fri Jul 18 14:09:47 2003 +0000 + + Oops. + +commit 123bb765d10453fdccbe363a02e3042c588729cc +Author: Guus Sliepen +Date: Fri Jul 18 13:45:06 2003 +0000 + + Use iface instead of interface because it might already be declared in + system header files. + +commit 96ee04b678143defa1040f2defdd3424efedea11 +Author: Guus Sliepen +Date: Fri Jul 18 13:42:35 2003 +0000 + + Check for ethernet/ipv4/ipv6 related structures. + +commit 00ddbf5723511d80fbd2522fc503bd409dc6189a +Author: Guus Sliepen +Date: Fri Jul 18 13:41:37 2003 +0000 + + Update all device.c files. + +commit 271d3537fed28b3e76cf0e76082b44c8771ac5da +Author: Guus Sliepen +Date: Fri Jul 18 12:21:03 2003 +0000 + + Remove all #ifndefs from route.c + +commit b0a4f7b5551cae6fb5af2eb4bcb0dfb3443f7d89 +Author: Guus Sliepen +Date: Fri Jul 18 12:16:24 2003 +0000 + + Even more missing definitions. + +commit e449d94caef963809d417f16497f6f978e10d731 +Author: Guus Sliepen +Date: Thu Jul 17 15:06:27 2003 +0000 + + Big header file cleanup: everything that has to do with standard system + libraries is moved to system.h. + +commit 47721be760c495ec13d68181bc03b151ffc1399c +Author: Guus Sliepen +Date: Tue Jul 15 16:38:18 2003 +0000 + + Windows headers declare a struct interface somewhere. + +commit 4c52febc57f2e34f5a187f0e57782903fe1eb95e +Author: Guus Sliepen +Date: Tue Jul 15 16:27:39 2003 +0000 + + Make use of the CIPE driver. Woohoo, tinc for Windows! + +commit d26a4af4561ce4236b8224919cf4f3636f57b4c1 +Author: Guus Sliepen +Date: Tue Jul 15 16:26:18 2003 +0000 + + Export mymac. + +commit 784db4e70d2573468c82ff5dfee723b77a20322f +Author: Guus Sliepen +Date: Sat Jul 12 20:24:04 2003 +0000 + + Format string checking for logger(). + +commit a438ac911e7e60e54d7d1fc4f84373fab7e055af +Author: Guus Sliepen +Date: Sat Jul 12 20:19:22 2003 +0000 + + Removing distribution specific files from CVS. + +commit 085d33e6265e139bb08cdfda3d7498993190d187 +Author: Guus Sliepen +Date: Sat Jul 12 17:48:38 2003 +0000 + + Update copyrights. + +commit 5db596c6844169f1eb5f804b72abe99d067aaa5a +Author: Guus Sliepen +Date: Sat Jul 12 17:41:48 2003 +0000 + + Simplify logging, update copyrights and some minor cleanups. + +commit 2a7f11c0e90f5f0465bbc3c75de715454066ff72 +Author: Guus Sliepen +Date: Fri Jul 11 16:13:00 2003 +0000 + + More missing IPv6 definitions and autoconf checks to make sure it compiles + under Solaris 2.6. + +commit 71f8124ea49f2a0e00e0cedbb1b76e49e9f1425d +Author: Guus Sliepen +Date: Mon Jul 7 11:50:52 2003 +0000 + + More missing definitions. + +commit a88f1edf297152580a7729c6f3d274ba2bff7360 +Author: Guus Sliepen +Date: Mon Jul 7 11:13:31 2003 +0000 + + Actually add ipv6.h. + +commit 30c0381d71d333a99f6c83ff9d03ef4a0857f423 +Author: Guus Sliepen +Date: Mon Jul 7 11:11:33 2003 +0000 + + Provide all missing IPv6 definitions in lib/ipv6.h. + +commit 1401faf608e1c8af0d0754e545b0ec79d2bd5d93 +Author: Guus Sliepen +Date: Sun Jul 6 23:16:29 2003 +0000 + + Sprinkling the source with static and attributes. + +commit 0b9175e998c2180e5d73ef3d644a49d620c68cad +Author: Guus Sliepen +Date: Sun Jul 6 22:11:37 2003 +0000 + + Define logger(), cleans up source code and allows us to write log entries + to a separate file. + +commit 868104703003605711582c984b57f8933bf361ee +Author: Guus Sliepen +Date: Sun Jul 6 17:49:49 2003 +0000 + + Check for IPv6 header files. + +commit 81f5713ab71944d51703653eab7f364fba0c482e +Author: Guus Sliepen +Date: Sun Jul 6 17:15:25 2003 +0000 + + - simplify configure.in + - drop support for OpenSSL < 0.9.7 + - add some missing definitions/includes + +commit 6c7172d694dcb80e538518282b6c4bd51818f1d2 +Author: Guus Sliepen +Date: Wed Jun 25 20:55:05 2003 +0000 + + This subtle pointer arithmetic thingy is (I'm very sure of it) the cause + of the lingering connections problem. Hopefully it is fixed now... + +commit 9528a63c35da77ba5b825068aeffbc5587816dd5 +Author: Guus Sliepen +Date: Wed Jun 25 20:52:59 2003 +0000 + + Really make tinc default to any addressfamily. + +commit 8bfa554af97ee0694919b9f5b78ada89c6af62f5 +Author: Guus Sliepen +Date: Thu Jun 12 11:08:40 2003 +0000 + + There are two lzo compression levels. + +commit c3593491d44e8e8f239bb297f5d5f6541d581b78 +Author: Guus Sliepen +Date: Wed Jun 11 20:36:36 2003 +0000 + + Typo and conversion to UTF-8. + +commit 636e650261712e3687048fe19987fd50ce84b093 +Author: Guus Sliepen +Date: Wed Jun 11 20:19:46 2003 +0000 + + Update dutch translation. + +commit 9279b3c69982b066e2aaea4e444892b51332881a +Author: Guus Sliepen +Date: Wed Jun 11 20:18:48 2003 +0000 + + Update documentation. + +commit 0a9aef2da749f7b7d1ca183daad88f6433579b9f +Author: Guus Sliepen +Date: Wed Jun 11 19:40:43 2003 +0000 + + More braces to make gcc happy. + +commit cf63cbef2bcb6a1f21ded439cbb09842581b9020 +Author: Guus Sliepen +Date: Wed Jun 11 19:39:02 2003 +0000 + + Fixes from Wessel Danker's libavl. + +commit 12de5a8eedd985f4732e88de6185f77a8244612c +Author: Guus Sliepen +Date: Wed Jun 11 19:28:38 2003 +0000 + + Remove mymac stuff from device.c. + +commit 31f17d43346a9175aec7c29ce41c71b1d08f725e +Author: Guus Sliepen +Date: Wed Jun 11 19:27:35 2003 +0000 + + AddressFamily is "any" by default. + +commit 451800eda87e886021fabd1888e486c51e97902a +Author: Guus Sliepen +Date: Wed Jun 11 19:09:52 2003 +0000 + + If we have a Linux tun/tap device and we are in router mode, open the device + in tun mode. + +commit 9e02a3d5631b687833e4cdcde18cda66e38138fc +Author: Guus Sliepen +Date: Wed Jun 11 19:07:56 2003 +0000 + + Call make_names() before doing anything else. + +commit 4b0e5a03fe89529ebe5d471a82c29c153a12116b +Author: Guus Sliepen +Date: Sat Jun 7 13:18:32 2003 +0000 + + Fix warning and add missing checks for LZO library. + +commit f238c209f4a0ced889b8fb443753ed2cdb3548b3 +Author: Guus Sliepen +Date: Sat May 17 22:12:52 2003 +0000 + + Fix links. + +commit 249933350bda2c3fa09c7ce8eb36bf84ee30a1cb +Author: Guus Sliepen +Date: Wed May 7 11:21:58 2003 +0000 + + Small fixes. + +commit 6ba4e2da55001e17aec6a7ee71002130555ff439 +Author: Guus Sliepen +Date: Tue May 6 23:14:45 2003 +0000 + + Small fixes to make LZO compression work. + +commit c70f52087bf6f7514684bbc859b83aec2ca17ae4 +Author: Guus Sliepen +Date: Tue May 6 21:13:18 2003 +0000 + + - Per-node EVP_CIPHER_CTX to avoid initialisation overhead. + - LZO compression, thanks to Teemu Kiviniemi. + - Updated dutch translation. + +commit 1ad2394b8468593030653bbfd0dee879fb711432 +Author: Guus Sliepen +Date: Sat Apr 19 11:12:45 2003 +0000 + + Make sure outgoing_t is completely freed. + +commit bc9e78250ef6fb5169d03565b7d8d9caf309eb98 +Author: Guus Sliepen +Date: Fri Apr 18 21:18:36 2003 +0000 + + Better handling of late packets. + +commit 51a1bcf00143319c74ffb58a66a19c41be422c21 +Author: Guus Sliepen +Date: Thu Apr 3 11:43:17 2003 +0000 + + HUP signal now closes connections to hosts if their host config file is + gone or changed. The tinc.conf file is reread for changes in the ConnectTo + lines. + +commit 8285827da127e38728b60b5c5484e5cdabff2f21 +Author: Guus Sliepen +Date: Sat Mar 29 22:11:22 2003 +0000 + + Checksums must also work for uneven number of bytes. + +commit c3ad3731a8dfa34535a156a7cfdb4e18afaa8bce +Author: Guus Sliepen +Date: Sat Mar 29 21:58:35 2003 +0000 + + Don't copy more than necessary. + +commit 7d21a8d1c7fd8909fe02385dbb4717c074db4648 +Author: Guus Sliepen +Date: Sat Mar 29 21:51:21 2003 +0000 + + - Speed up checksumming + - If a destination is not found in the subnet list or the destination node + is unreachable, respond with an appropiate ICMP message. + +commit 9792ba2cac35cb50cc99b72dd4cb9d3ef350dbd4 +Author: Guus Sliepen +Date: Fri Mar 28 13:41:49 2003 +0000 + + - Avoid memory leak caused by OpenSSL 0.9.7a. + - Disable RSA_blinding_on() because it segfaults. + +commit 69158563e9f790777eb27aeb8484a86d12385af4 +Author: Guus Sliepen +Date: Wed Mar 19 11:45:05 2003 +0000 + + Typo. + +commit 88ae2e9e0c1eb62d9b74c4b38d9c0e93557fed9f +Author: Guus Sliepen +Date: Wed Mar 19 11:43:42 2003 +0000 + + Make sure send_meta() writes everything. + +commit 2fff0a91a7e3e5f44e97255b6dd5807656b255a8 +Author: Ivo Timmermans +Date: Fri Mar 14 09:43:10 2003 +0000 + + Call RSA_blinding_on(), as advised in the paper on + http://crypto.stanford.edu/~dabo/abstracts/ssl-timing.html + to offer some resistance against timing attacks. + +commit 1783a3aaa9b692ab64260a9c2adf588ed6083a1c +Author: Guus Sliepen +Date: Fri Jan 17 00:43:58 2003 +0000 + + Various fixes for autoconf and OpenSSL 0.9.7 and a missing header. + +commit c08858baa91a00e38c0f5482dbb0817dbd0361f1 +Author: Guus Sliepen +Date: Fri Jan 17 00:37:20 2003 +0000 + + - Fix indentation in some places. + - Optimise select loop. + - Remove unused function setup_outgoing_socket(). + - Clear EVP_CIPHER_CTX structures before using them. + +commit 38f562fdfcacb50d34b9a48bfaea7faa132f493a +Author: Guus Sliepen +Date: Tue Jan 14 12:53:59 2003 +0000 + + Add $NAME for tinc-up/down scripts. + +commit 44b87ddb7ac90be13ef3e3d5118acaa158184853 +Author: Guus Sliepen +Date: Sun Jan 12 17:02:23 2003 +0000 + + Run graph algorithm when replacing a second connection from the same host + replaces an older one. + +commit 4c88ff86bcd32735d4768ef3464812cd77c500be +Author: Guus Sliepen +Date: Fri Dec 27 19:32:33 2002 +0000 + + PrivateKeyFile instead of PrivateKey. + +commit 5b2a62ebb6317cd88e491ee958c54670f381aee8 +Author: Guus Sliepen +Date: Thu Nov 14 22:09:03 2002 +0000 + + Fix PriorityInheritance. + +commit 07db46a44feb283c1c17bcce918ab49274a3b11f +Author: Guus Sliepen +Date: Mon Oct 7 07:32:31 2002 +0000 + + Add documentation for BindToAddress. + +commit e310cc82d3f9c9bdb3b827daa149861a41e2e00a +Author: Ivo Timmermans +Date: Mon Sep 30 19:04:37 2002 +0000 + + Fix saving of debug level for startup level 0 + +commit 006591efe5b3e6c64040d267f8c0477468abf2bf +Author: Guus Sliepen +Date: Tue Sep 24 11:43:34 2002 +0000 + + Run graph() after edge_del() when updating an edge. + +commit 6904e0469ef52aa6100f0185d579bc205bd07be8 +Author: Wessel Dankers +Date: Mon Sep 16 14:08:04 2002 +0000 + + its: Engels voor "van het" - 3e persoon enkelvoud, genitief, onzijdig + it's: Engels voor "het is". Dus niet "van het". + +commit 4f3395ee4dad3cdd23706af180ebddfa5e576012 +Author: Guus Sliepen +Date: Sun Sep 15 22:37:59 2002 +0000 + + Thank some more people. + +commit b216297a004f083336c633aaccecb4ab175360b3 +Author: Guus Sliepen +Date: Sun Sep 15 22:34:25 2002 +0000 + + Remarks about 1.0pre8 release. + +commit 1dcbdf48eb4a642e4d70a9e67aaca78deacf352d +Author: Guus Sliepen +Date: Sun Sep 15 22:19:38 2002 +0000 + + Update documentation. + +commit bf3a11898898c0618cd1b2e7a792b7d7fe56aecb +Author: Guus Sliepen +Date: Sun Sep 15 22:19:19 2002 +0000 + + Use /dev/net/tun as default for tun/tap device under Linux. + +commit 7d76ceaebd5180f4ef37086980c799199eb7de16 +Author: Guus Sliepen +Date: Sun Sep 15 17:40:00 2002 +0000 + + Updated dutch translation. + +commit 5eca9520d93bced1275d45e5e2a933d69354cd6d +Author: Guus Sliepen +Date: Sun Sep 15 14:55:54 2002 +0000 + + Small fixes so tinc compiles out of the box on SunOS 5.8 + +commit 8d472a415e9c5fdb878386005d29cdfd97b8a404 +Author: Guus Sliepen +Date: Sun Sep 15 12:26:24 2002 +0000 + + port_t isn't used anymore and conflicts with MacOS/X headers. + +commit 38c80bdd46fab68c686a293e2820041291972f3a +Author: Guus Sliepen +Date: Sun Sep 15 12:26:04 2002 +0000 + + MacOS/X needs #define _P1003_1B_VISIBLE in order to use mlockall(). + +commit 3e3b4a3190cf950c265a8c62d577812a22b11dcc +Author: Guus Sliepen +Date: Wed Sep 11 22:25:58 2002 +0000 + + What was I thinking? + +commit f6905582d0e70ac5b44369780aaa921d9c721197 +Author: Guus Sliepen +Date: Tue Sep 10 22:13:22 2002 +0000 + + Make sure malloc() is declared. + +commit eaf1208e9d5c5a15e4b23de936830520bf3b5685 +Author: Guus Sliepen +Date: Tue Sep 10 22:13:01 2002 +0000 + + Fix placement of #include "config.h" + +commit dd888ca685176128bf41034208f3dbb220f9d832 +Author: Guus Sliepen +Date: Tue Sep 10 21:46:05 2002 +0000 + + Link with libintl if necessary. + +commit c01f78ed3603eecaec8e3649a3bfb3de9742fd24 +Author: Guus Sliepen +Date: Tue Sep 10 21:29:42 2002 +0000 + + Clean up after indent. + +commit 161f917dd03c174742fb8c6722f430a93b506cb1 +Author: Guus Sliepen +Date: Tue Sep 10 09:40:25 2002 +0000 + + Fix compiler warnings. + +commit 3bc554347560a9c24e68bb2c7c7749be07bbec3d +Author: Guus Sliepen +Date: Mon Sep 9 22:41:56 2002 +0000 + + Let GCC check format string and arguments of send_request(). + +commit 6f9f6779e6bd1dd7bb795b42dad550863a386ca8 +Author: Guus Sliepen +Date: Mon Sep 9 22:33:31 2002 +0000 + + Remove redundant spaces. + +commit 9f38e394636a177c00a4545de2a99c661de36386 +Author: Guus Sliepen +Date: Mon Sep 9 21:49:16 2002 +0000 + + Switch to K&R style indentation. + +commit f75dcef72a81a337e847adf0bae54198894f65b9 +Author: Guus Sliepen +Date: Mon Sep 9 21:25:28 2002 +0000 + + Switch to K&R style indentation. + +commit 5fc1ed17f41f0c535cf57a4b7e00cd6d45759503 +Author: Guus Sliepen +Date: Mon Sep 9 19:40:12 2002 +0000 + + Cleanups: + - Convert cp to cp(); so that automatic indenters work. + - Convert constructions like if(x == NULL) to if(!x). + - Move all assignments out of conditions. + +commit 5638b9830f9cfe43f545c37cfd7ccf1d4b4bfcc6 +Author: Guus Sliepen +Date: Fri Sep 6 21:22:35 2002 +0000 + + Why don't these connection_t's get cleaned up? + +commit a8ddba42b99d7694359f1387235596b84d297b9e +Author: Guus Sliepen +Date: Fri Sep 6 21:02:36 2002 +0000 + + Fix MST algorithm. + +commit 66741978e16cc407e5c760621c34d1aabb753cd2 +Author: Guus Sliepen +Date: Fri Sep 6 14:31:12 2002 +0000 + + Reset the *correct* seqnos. + +commit d5b61fc0cd249fd2b2751a1ff77b321323a17beb +Author: Guus Sliepen +Date: Fri Sep 6 12:19:16 2002 +0000 + + edge_weight_compare() shouldn't rely on edge_compare(). + +commit fc7116a32b798589e7731db9f9db66345c8c3e01 +Author: Ivo Timmermans +Date: Fri Sep 6 11:08:21 2002 +0000 + + Added AM_MAINTAINER_MODE + +commit fbf8a47879671541939cfdc6beb93b02b9eee303 +Author: Guus Sliepen +Date: Fri Sep 6 10:23:52 2002 +0000 + + Remove global edge_tree. + +commit 641705df90b4c41e7f5083f6cd601cbbfb1c2c85 +Author: Guus Sliepen +Date: Fri Sep 6 09:48:39 2002 +0000 + + Only reset seqno's when a key is sent or received. + +commit e4d85a6557ee45870bee0c5a16807e48b7a3c243 +Author: Guus Sliepen +Date: Wed Sep 4 23:11:58 2002 +0000 + + Typo. + +commit b4f87952bf2d37524c705b32864f802144f94d68 +Author: Guus Sliepen +Date: Wed Sep 4 23:05:49 2002 +0000 + + Add missing headers. + +commit b18bd211bec84a804f58da5f2d2908e54de3fe40 +Author: Guus Sliepen +Date: Wed Sep 4 23:04:52 2002 +0000 + + Run autopoint and libtoolize before creating initial makefiles. + +commit 6fdaa8e1caff4edb44a105b03c79403b743e9bd2 +Author: Guus Sliepen +Date: Wed Sep 4 19:57:53 2002 +0000 + + Small updates. + +commit d4277e9ee8affa59ac9b3475245360bd14af1fa8 +Author: Guus Sliepen +Date: Wed Sep 4 16:36:03 2002 +0000 + + Updated dutch translation. + +commit 8b2b67e26c5b971761f5015764d5e188f6343bc4 +Author: Guus Sliepen +Date: Wed Sep 4 16:26:45 2002 +0000 + + Generalized request broadcasting/forwarding. + +commit 431fa10b37e78172a03c952e28a0364cc0e438f0 +Author: Guus Sliepen +Date: Wed Sep 4 14:17:28 2002 +0000 + + Small fixes. + +commit 82ebfc923ddb050c88bdf5d65ac943a15ca8748a +Author: Guus Sliepen +Date: Wed Sep 4 13:48:52 2002 +0000 + + Revert to edge and graph stuff. This time, use a directed graph. + +commit 973530db628fb91106d6fb7a17151e1d036e40a2 +Author: Guus Sliepen +Date: Wed Sep 4 08:48:03 2002 +0000 + + Just ignore wrong ADD_NODEs instead of replying with a DEL_NODE, in the + hope other DEL_NODEs will catch up eventually. + +commit 2af0bcc8fd39ca34a7ff856d539cdf38728a8c25 +Author: Guus Sliepen +Date: Wed Sep 4 08:36:34 2002 +0000 + + Don't forget to set prevhop to myself for new connections. + +commit 698d6ddac6ab32d5a4b802941b02232793442684 +Author: Guus Sliepen +Date: Wed Sep 4 08:33:08 2002 +0000 + + Prevent looping DEL_NODE/ADD_NODE messages after a node disconnects. + +commit 4a7c2026aec6966f934b60d75bc472d28f8587d8 +Author: Guus Sliepen +Date: Wed Sep 4 08:02:33 2002 +0000 + + Reduce KEY_CHANGED traffic. + +commit ddb96301a39dd3dac8d3df4e2e189b13b75e0b6e +Author: Guus Sliepen +Date: Tue Sep 3 22:49:55 2002 +0000 + + Woops. + +commit b5bb06200eda170c9836e1b4474d6f5b920c2151 +Author: Guus Sliepen +Date: Tue Sep 3 22:37:49 2002 +0000 + + A reachable node is always more preferable to an unreachable one... + +commit d134c4542d4e890e1c1007f32b866742319853c5 +Author: Guus Sliepen +Date: Tue Sep 3 20:43:26 2002 +0000 + + Drop graph and edge stuff. Use new node stuff instead. + +commit 856de4c5fe8acd779aa9277d4554e34ff3625e97 +Author: Guus Sliepen +Date: Tue Sep 3 20:42:05 2002 +0000 + + Make sure setlocale() is available. + +commit 2cb21f8810a6e0241a80623e991c8308b603ae95 +Author: Guus Sliepen +Date: Mon Sep 2 22:40:42 2002 +0000 + + Replacement for the current routing algorithm. + +commit f2c2443bbcfd5e09518bd87f3fd8d4a727d73ae2 +Author: Guus Sliepen +Date: Sat Aug 24 12:54:55 2002 +0000 + + Check for ranlib. + +commit 912e7e968f4888d62b3c620893a70e825599973b +Author: Guus Sliepen +Date: Sat Aug 24 12:11:40 2002 +0000 + + Gettext 1.11.5 compatibility. + +commit 18948c5784bfedf0dd5a371e41bc2cceee76d92e +Author: Guus Sliepen +Date: Thu Jul 18 14:30:45 2002 +0000 + + Added support for raw sockets. This can be used instead of tun/tap devices. + +commit 9f370893fafaeacdd78f5488cfa8b76fdee0d224 +Author: Guus Sliepen +Date: Tue Jul 16 13:18:27 2002 +0000 + + Don't bother to chown, and correctly document ConnectTo. + +commit 227ccd3a8a5602e4c31add8da1bfd8b35c6a801f +Author: Guus Sliepen +Date: Tue Jul 16 13:12:49 2002 +0000 + + Allow tincd to be locked into main memory. + +commit c4cd19935763b379e730a6fdf53dc1ca98d0b938 +Author: Guus Sliepen +Date: Fri Jul 12 11:45:21 2002 +0000 + + Include complete fake-getname/addrinfo from OpenSSH. + +commit afabbd6b9020dd6555a7ecd320a7b3e96119d538 +Author: Guus Sliepen +Date: Thu Jul 11 12:57:06 2002 +0000 + + Added stub device.c for Cygwin. + +commit 8949404db08f4ab594e60778bb76a9061426d7cc +Author: Guus Sliepen +Date: Thu Jul 11 12:55:58 2002 +0000 + + Started port to Cygwin. + +commit c98db1b861d62430e23f26b0da18e7b3ec875767 +Author: Guus Sliepen +Date: Thu Jul 11 12:42:43 2002 +0000 + + Clear subnets before using them. + +commit 8dd09568f1604f1ac8cc0d8d5120d986f5654900 +Author: Guus Sliepen +Date: Wed Jul 10 11:32:33 2002 +0000 + + Allow identical subnets from different owners. + +commit 36cbaa32f480b481bf2ee99fd4835586a02ebc60 +Author: Guus Sliepen +Date: Wed Jul 10 11:27:06 2002 +0000 + + Allow list of environment variables to be passed to execute_script(). + When executing host-up/down scripts, include the address and port of the + remote host. + +commit a1bd878e11ae7e66e7e9a4040c3b19f9b7bc50f4 +Author: Guus Sliepen +Date: Fri Jun 21 17:49:48 2002 +0000 + + Fix for prefixlengths of 32 (IPv4) and 128 (IPv6) bits. + +commit 627f7c22b447bd464b536cd016278545674df93d +Author: Guus Sliepen +Date: Fri Jun 21 10:11:37 2002 +0000 + + s/sliepen.warande.net/sliepen.eu.org/g + s/itimmermans@bigfoot.com/ivo@o2w.nl/g + +commit faabd163adf89bd0580cd40b8735ef8d9028a942 +Author: Guus Sliepen +Date: Fri Jun 14 11:51:29 2002 +0000 + + Update comments about IPv6 autoconfiguration. + +commit 940fcb6701d055f49530f12c93371f0280efce80 +Author: Guus Sliepen +Date: Thu Jun 13 16:12:40 2002 +0000 + + Reset listen_sockets after SIGHUP. + +commit 3a3adf5b690e9be1390a5df3caee6af64b25838f +Author: Guus Sliepen +Date: Wed Jun 12 13:45:23 2002 +0000 + + Add configuration details for NetBSD and Darwin (MacOS/X). + +commit 8988b127e18435054e48cbcca8ac712ddda3d6d2 +Author: Guus Sliepen +Date: Tue Jun 11 11:03:17 2002 +0000 + + Autoconf cleanup. Works for both 2.13 and 2.53, although running autoconf + 2.53 still gives some errors. + +commit de6835a9dd1891b6435c128cc6c2293950a4d7a7 +Author: Guus Sliepen +Date: Mon Jun 10 15:08:23 2002 +0000 + + Include darwin/device.c in distribution. + +commit 40ac473cb10f9c6a59739ce70032b746d8e0bf68 +Author: Guus Sliepen +Date: Mon Jun 10 14:35:18 2002 +0000 + + Use darwin/device.c when compiling on MacOS/X. + +commit 69b758879ee6d322e89143141b98d52167845c26 +Author: Guus Sliepen +Date: Mon Jun 10 14:33:40 2002 +0000 + + Added Darwin (MacOS/X) tun device handling. + +commit bd72e14138185f342885c0ed1c0f2c5dbf571132 +Author: Ivo Timmermans +Date: Sun Jun 9 16:23:12 2002 +0000 + + Added Alessandro Gatti + +commit 944df3eeee50972fcac84cfc8eefb36033bf04ad +Author: Ivo Timmermans +Date: Sun Jun 9 16:19:20 2002 +0000 + + Include netbsd's device.c in make dist + +commit 7608136a8dae24f2df30eac8644efd0d7cd57dc9 +Author: Ivo Timmermans +Date: Sun Jun 9 16:12:04 2002 +0000 + + Include a few more header files + +commit cd3601c5df57c7544ece00bf79e82b36499a26ff +Author: Ivo Timmermans +Date: Sun Jun 9 15:58:05 2002 +0000 + + Add /sw/{include,lib} to search paths if they exist + +commit 548551fd05f58863dfbbaaf147febfab0a22889b +Author: Ivo Timmermans +Date: Sun Jun 9 15:50:12 2002 +0000 + + getnameinfo fixes + +commit 9d769e0bf2ce266e8533e5e7c16bf07e44a9be34 +Author: Ivo Timmermans +Date: Sun Jun 9 15:26:10 2002 +0000 + + OSX support + +commit 78e88521845ae3bdd963ae5a414cb9c251963fa2 +Author: Guus Sliepen +Date: Sat Jun 8 14:08:57 2002 +0000 + + - netinet/* include files depend on netinet/in_systm.h. + - Squash bashism in configure.in. + +commit e47e51e9d17416e2b614287d14a5518881decd44 +Author: Guus Sliepen +Date: Sat Jun 8 13:46:43 2002 +0000 + + Use inttypes.h instead of stdint.h. + +commit 116ba3b3da73fb857cf75b5c92c6aacd70d94dd9 +Author: Guus Sliepen +Date: Sat Jun 8 12:57:10 2002 +0000 + + Cleanup: + - Remove checks for specific OS's, instead check for #defines/#includes. + - Use uint??_t where appropriate. + - Mask handling functions use void pointers to get rid of silly casts. + +commit d333fca4d611b85dd922ddf35bd9eddcb8095c85 +Author: Wessel Dankers +Date: Fri Jun 7 11:14:05 2002 +0000 + + This should work much better. + +commit 14e570f5eeff631c1312b11fcc5d22230ec27aff +Author: Guus Sliepen +Date: Wed Jun 5 00:25:55 2002 +0000 + + Use correct includes on NetBSD. + +commit 5886b6a10d0d2edf20ff53c4926ec4e41a36b8c0 +Author: Guus Sliepen +Date: Wed Jun 5 00:20:40 2002 +0000 + + Make it work correctly with NetBSD tun device. + +commit 4856d8e1f8398780a49545f35ba9b5746c9fc060 +Author: Guus Sliepen +Date: Sun Jun 2 16:06:33 2002 +0000 + + Support RSA_PUBKEYs (as opposed to RSAPublicKeys) so tinc accepts + public keys generated by the OpenSSL command line tools. + +commit efa5148bc76effb440d807d653dda02de050fde0 +Author: Ivo Timmermans +Date: Tue May 7 14:48:41 2002 +0000 + + Hm. + +commit 151ab8c9708534e012447688ed44d711d5b5fa2d +Author: Ivo Timmermans +Date: Thu May 2 13:23:58 2002 +0000 + + test 2 + +commit be04387a0c868b22ee4427822573df8b3b479bbe +Author: Ivo Timmermans +Date: Thu May 2 13:22:44 2002 +0000 + + test + +commit a9bb66367df82d062175f2b9b4bf236d77ae3ff1 +Author: Ivo Timmermans +Date: Thu May 2 13:11:55 2002 +0000 + + Moved event.c/h + +commit 474aab6325bf94724874cb74a9b56d9da739e1b8 +Author: Ivo Timmermans +Date: Thu May 2 11:52:28 2002 +0000 + + Callbacks + +commit 4c1a4e8a790584e4c7d5c0f2485706f4c01e1911 +Author: Ivo Timmermans +Date: Thu May 2 11:50:07 2002 +0000 + + Another file moved; random interface stuff. + +commit 2be8e69ca16e1558463c39c48af76d3d4a4674b7 +Author: Guus Sliepen +Date: Wed May 1 09:15:58 2002 +0000 + + Only purge once when there are no more connections. + +commit a77b35e748b7cf4cf7ac31750cefab7b2b0325f5 +Author: Ivo Timmermans +Date: Mon Apr 29 20:19:42 2002 +0000 + + Commit diff test + +commit 7caa253df4a34e594438e3fbe80c2bddab9a2b4a +Author: Guus Sliepen +Date: Mon Apr 29 20:05:07 2002 +0000 + + Fix very stupid bug in node_del(), which might have caused corruption of + subnets. + +commit 04d33be4bd102de67bb6dba5c449e12fea0db4d2 +Author: Ivo Timmermans +Date: Sun Apr 28 12:46:26 2002 +0000 + + Moving files, first attempt at gcrypt compatibility, more interface + abstraction + +commit b0a676988a8da3120e64ef0e1a4ea4c28b1511e1 +Author: Ivo Timmermans +Date: Sun Apr 28 12:43:40 2002 +0000 + + *** empty log message *** + +commit 67a6d7bcc4891c627663c639c0e02315bd4cf437 +Author: Guus Sliepen +Date: Sat Apr 27 11:40:45 2002 +0000 + + Informative log message if execl() failed. + +commit e6a67fc439fc3b46157647bed1af59b7519adb80 +Author: Ivo Timmermans +Date: Fri Apr 26 18:13:00 2002 +0000 + + Typo + +commit 01747d73a217f7ddf2107b086476702a9d04d683 +Author: Guus Sliepen +Date: Thu Apr 25 19:17:24 2002 +0000 + + Added Nick Patavalis for his RedHat package. + +commit b6ad4ce35a4434c209ee26015f15a18180987bac +Author: Guus Sliepen +Date: Tue Apr 23 07:49:38 2002 +0000 + + Add BindToAddress variable, similar to the late BindToIP. + +commit 40c2e36a96a3f5c34d4851b30f3561123f3906b5 +Author: Guus Sliepen +Date: Fri Apr 19 14:06:40 2002 +0000 + + Support for MaxOS/X. + +commit 97d492d9e23f43fe4c8a5ca8c95747088cf32f98 +Author: Ivo Timmermans +Date: Thu Apr 18 20:09:05 2002 +0000 + + Put #ifndef checks for HAVE_RAND_PSEUDO_BYTES in the correct places. + +commit fa8faff84bbbeb818adaea80d7bf9e12e0074978 +Author: Ivo Timmermans +Date: Sat Apr 13 18:01:58 2002 +0000 + + Print newline when writing to stderr + +commit fbebc5b65606119c01e9e1e3fcc7b2cc4cfd1daf +Author: Ivo Timmermans +Date: Sat Apr 13 11:24:25 2002 +0000 + + ... + +commit 7c75090025a4b06290663e0033a62414f3368f7c +Author: Ivo Timmermans +Date: Sat Apr 13 11:23:46 2002 +0000 + + Rename libvpn to libtinc + +commit 55385cacbfb0c743fc518e54854e24b7b05a623c +Author: Ivo Timmermans +Date: Sat Apr 13 11:23:19 2002 +0000 + + Renamed libvpn to libtinc + +commit 2389dcd573d909f21c8ec2d349b079075af6c7d3 +Author: Ivo Timmermans +Date: Sat Apr 13 11:21:58 2002 +0000 + + Include logging.h + +commit 246ce12c92ccc7badbb8c8c9a88fa03a7de9811f +Author: Ivo Timmermans +Date: Sat Apr 13 11:21:01 2002 +0000 + + Use new logging system + +commit a5b3ec41214ac8aea9b82734f92b5953e04a0c09 +Author: Ivo Timmermans +Date: Sat Apr 13 11:15:43 2002 +0000 + + Things to ignore... + +commit e239504524589a0f1549ca174f927afd07d563ba +Author: Ivo Timmermans +Date: Sat Apr 13 11:14:50 2002 +0000 + + Compile in logging.c + +commit e26dd564163fca001ab1694a51e7412f9ac970de +Author: Ivo Timmermans +Date: Sat Apr 13 11:08:31 2002 +0000 + + Use logging.h instead of syslog.h + +commit 72cd8938e2c759905666ea7d2c90dc1f0b2e2cd5 +Author: Ivo Timmermans +Date: Sat Apr 13 11:00:41 2002 +0000 + + Added prototype for log_syslog + +commit 48b80c93d30d5fae4273b0b496252bbc884abe53 +Author: Ivo Timmermans +Date: Sat Apr 13 10:55:42 2002 +0000 + + log_default_hook was renamed to log_default + +commit b63c3a1f0002675b6bedbd0b235e0ad0a708d4e3 +Author: Ivo Timmermans +Date: Sat Apr 13 10:50:48 2002 +0000 + + Added priority definitions from syslog.h + +commit 490b13edcfcae0422b6bd77fdb2a7f0181b14307 +Author: Ivo Timmermans +Date: Sat Apr 13 10:45:56 2002 +0000 + + Some magic + +commit 738389581b1ba29a181f639f3d20e3e24ff546f5 +Author: Ivo Timmermans +Date: Sat Apr 13 10:43:10 2002 +0000 + + Add syslog wrapper + +commit efa59f7cf4d416c8416866baeaa72cba7e936568 +Author: Ivo Timmermans +Date: Sat Apr 13 10:40:09 2002 +0000 + + Add syslog() wrapper + +commit 8822481d7b11db72d5400717d6b491b5f36bcb1f +Author: Ivo Timmermans +Date: Sat Apr 13 10:29:07 2002 +0000 + + Rename log_message to log + +commit cc603e2765f17555ecdc2b74c27ebf96e6691bf6 +Author: Ivo Timmermans +Date: Sat Apr 13 10:25:38 2002 +0000 + + New logging system to replace syslog() calls with a generic function. + +commit 131327a729216de8ae86da0c3c4d65d409741b7b +Author: Ivo Timmermans +Date: Sat Apr 13 10:04:46 2002 +0000 + + Remove debug_lvl + +commit e3c51b61caabc1a55772f7a52e75aab642c200ed +Author: Ivo Timmermans +Date: Sat Apr 13 10:02:48 2002 +0000 + + Update copyright info + +commit 9e8468f54aa5ecdb8b63c60449791427b59a474d +Author: Ivo Timmermans +Date: Sat Apr 13 10:02:16 2002 +0000 + + Remove debug level declaration + +commit 9f2c50e159caea1884c6a7aaa33f8098539ae0f5 +Author: Guus Sliepen +Date: Fri Apr 12 08:25:01 2002 +0000 + + Adding even more stuff from the CABAL branch. + +commit 191dcd5add0afba8b5d3aaa1e188c562c621712e +Author: Ivo Timmermans +Date: Thu Apr 11 20:18:02 2002 +0000 + + Also compile in pokey/ + +commit 39e93f473d34d6cdf6f4a7f0390a3b50cbd7b564 +Author: Ivo Timmermans +Date: Thu Apr 11 20:17:33 2002 +0000 + + Write src/pokey/Makefile + +commit c351b9e25b9f7b168a47fd8e6b60c66377e1824c +Author: Ivo Timmermans +Date: Thu Apr 11 14:27:35 2002 +0000 + + Pokey interface definition + +commit 17b308f0f0879c01f6864265af2e63595e965993 +Author: Ivo Timmermans +Date: Thu Apr 11 14:23:56 2002 +0000 + + Main pokey interface files. + +commit b5b38381c643632aa88c677236cace8c60e8344e +Author: Ivo Timmermans +Date: Tue Apr 9 16:11:48 2002 +0000 + + Last bits (hopefully) + +commit 77dd7b55801a3c7c2c6221664204ffdd7b83836a +Author: Ivo Timmermans +Date: Tue Apr 9 15:51:26 2002 +0000 + + More... + +commit 58c1df4028429ed6de4dad9455e3c92928450ffe +Author: Ivo Timmermans +Date: Tue Apr 9 15:48:54 2002 +0000 + + More updates + +commit 86dc60b9808d3aac70eccda80607a91ffd2e5292 +Author: Ivo Timmermans +Date: Tue Apr 9 15:32:14 2002 +0000 + + Ok, I forgot these ;) + +commit af23dfa5efb82b35eb00b94bda56390c9e2aac6f +Author: Ivo Timmermans +Date: Tue Apr 9 15:28:45 2002 +0000 + + Updating HEAD branch #5; Last files from CABAL. + +commit 462ab530e546f5732dfd51134751da6f6910d679 +Author: Ivo Timmermans +Date: Tue Apr 9 15:26:01 2002 +0000 + + Updating HEAD branch #4; Merging CABAL -> HEAD. + +commit e64ef59df44d39c76c00dee22841bbcce7c24e47 +Author: Ivo Timmermans +Date: Tue Apr 9 15:07:27 2002 +0000 + + Updating HEAD branch #3; more obsolete files removed. + +commit db59cbfa47aa152bcfa807754189aa18f28cb569 +Author: Ivo Timmermans +Date: Tue Apr 9 14:58:14 2002 +0000 + + Updating HEAD branch #2; removing debian/ dir. + +commit 50f2afec7e6dab3d809fc1b82820d1069205b69b +Author: Ivo Timmermans +Date: Tue Apr 9 14:54:37 2002 +0000 + + Updating HEAD branch #1; removing obsolete files. + +commit e69d2258032362c85c5936a5c137c70227e59332 +Author: Guus Sliepen +Date: Tue Apr 9 11:44:47 2002 +0000 + + Remarks about 1.0pre7 release. + +commit f2a3fcbdda250e5982c3ef36808568f996f8fff1 +Author: Guus Sliepen +Date: Tue Apr 9 11:43:45 2002 +0000 + + Updated dutch translation. + +commit b1322d244ff24e900f2298b8aa775d825c8ab00b +Author: Guus Sliepen +Date: Tue Apr 9 11:43:29 2002 +0000 + + masklength is better known as prefixlength + +commit 5df8a8cb3f4a0d2290f6677b44bbcaaf27a60bbc +Author: Guus Sliepen +Date: Tue Apr 9 11:42:48 2002 +0000 + + masklength is better known as prefixlength. + +commit 630dd023b990e076fdab890ff90783dc1ac7c13f +Author: Guus Sliepen +Date: Mon Apr 8 13:27:09 2002 +0000 + + Automake forgets about depcomp, remind it. + +commit ad6b1203490699ecc708290b2af1a45e134a5e20 +Author: Guus Sliepen +Date: Fri Apr 5 09:11:38 2002 +0000 + + Fix maskcheck() and maskcmp(). + +commit d8c249008a0b2abd44e652ed70e69b3dbc05b9d8 +Author: Guus Sliepen +Date: Mon Apr 1 21:28:39 2002 +0000 + + check_rsa() is broken, I don't know why, just remove it for now. + +commit 438419734ebee38dc3f7390e5c8ae8e6ca2cb6cf +Author: Guus Sliepen +Date: Mon Apr 1 21:28:05 2002 +0000 + + Don't check_network_activity() if select() is interrupted by a signal. + +commit 3d8a373bb3a788efffc555122b9d0569b96c5944 +Author: Guus Sliepen +Date: Wed Mar 27 19:43:50 2002 +0000 + + Make configure --help output look nicer. + +commit 9a03e7fa3d52ea062b4a3ff88b5d87ee95d24772 +Author: Guus Sliepen +Date: Wed Mar 27 16:26:26 2002 +0000 + + Update with information about the pre6 release. + +commit 33d3bad87d5f3e00e3ed81b75bca2ef21fd6e983 +Author: Guus Sliepen +Date: Wed Mar 27 16:00:49 2002 +0000 + + Update dutch translation. + +commit 0fe3dc38ed0527a5cfda9218114c8ee10422086b +Author: Guus Sliepen +Date: Wed Mar 27 16:00:38 2002 +0000 + + Fix format strings. + +commit 420f46acb0551a290b3263e39347b694286b2fa4 +Author: Guus Sliepen +Date: Wed Mar 27 15:47:06 2002 +0000 + + Remove symlink to device.c when doing a make dist. + +commit a5d8be8b1a9978d58c251d1020bb730bb1dc8ea1 +Author: Guus Sliepen +Date: Wed Mar 27 15:35:07 2002 +0000 + + Recent automake uses $(AMTAR) instead of $(TAR) + +commit c6d2f6c620beae387e8f9fc995ed7c8e8a5bc3dc +Author: Guus Sliepen +Date: Wed Mar 27 15:26:44 2002 +0000 + + Remove cruft. + +commit efd29fde85481e080a676f2ba780a528a90a9925 +Author: Guus Sliepen +Date: Wed Mar 27 15:26:29 2002 +0000 + + Small updates. + +commit 5eba1e1f6feadb3f7efb1261bd65e1e9e40b7f2b +Author: Guus Sliepen +Date: Wed Mar 27 15:01:37 2002 +0000 + + Limit the amount of packets in a queue to 8. + +commit 61cb593e670107ca3041f582c5486c243d5eda9e +Author: Guus Sliepen +Date: Wed Mar 27 15:01:16 2002 +0000 + + Extend list_t with the number of elements in the list. + +commit 0e7136027ce05bfeca977f2f64f3b228ea4fda87 +Author: Guus Sliepen +Date: Wed Mar 27 14:02:36 2002 +0000 + + Merge do_prune() with build_fdset(). Probably fixes the invalid filedescriptor error. + +commit e2238047d39eacc69da5732937021c38171ec7b9 +Author: Guus Sliepen +Date: Tue Mar 26 13:19:56 2002 +0000 + + Small correction. + +commit 7d07df71f9b82afdcf23494867bb8899198a6223 +Author: Guus Sliepen +Date: Tue Mar 26 12:00:38 2002 +0000 + + Fix execute_script(). + +commit 2de5e0eef911b9ff723d562ef9c62d833f3cdc45 +Author: Guus Sliepen +Date: Mon Mar 25 15:51:58 2002 +0000 + + Send REQ_KEY only once until ANS_KEY has arrived. + +commit a0c1696515fabd2183da7d8d83fd68410d2ec834 +Author: Guus Sliepen +Date: Mon Mar 25 15:12:09 2002 +0000 + + Tell a little bit more about security. + +commit 89a2f761a6d8ae4912c2dd2e9178589001487ef5 +Author: Guus Sliepen +Date: Mon Mar 25 15:01:32 2002 +0000 + + Updated documentation. + +commit 33d8747021d57c5827c6a755739756f95c7527c8 +Author: Guus Sliepen +Date: Mon Mar 25 13:54:49 2002 +0000 + + Set myself->status.reachable. + +commit 2749b997df33749f13d05e294db0e1e327e81d12 +Author: Guus Sliepen +Date: Sun Mar 24 17:14:01 2002 +0000 + + Configuration variables were still handled case sensitively. + +commit c73bdd6bc8e213b7e27848b97307228c01570a1d +Author: Guus Sliepen +Date: Sun Mar 24 17:08:38 2002 +0000 + + OpenBSD tun device uses address family number instead of Ethernet type. + +commit 8379c14b7f7a9b1400dd3776fc21dc9ccddd991d +Author: Guus Sliepen +Date: Sun Mar 24 16:50:58 2002 +0000 + + Respect type field. + +commit ad4f5cbc5fbce23893b7d42669ba907f18cc8ff4 +Author: Guus Sliepen +Date: Sun Mar 24 16:40:14 2002 +0000 + + Updated dutch translation. + +commit 4252ae83a43ea81382ce71ba614e2d1655f2e189 +Author: Guus Sliepen +Date: Sun Mar 24 16:36:56 2002 +0000 + + Set $INTERFACE correctly when using ethertap while compiled with tun/tap support. + +commit d699f3079c658e05f928c358d110d1d27849ea71 +Author: Guus Sliepen +Date: Sun Mar 24 16:28:27 2002 +0000 + + Execute hosts/name-up when a node becomes reachable, and hosts/name-down + when it becomes unreachable. + +commit 6ad5dd1a9adb1c1322ceb44d6f0fd160229e72ff +Author: Guus Sliepen +Date: Sun Mar 24 16:22:59 2002 +0000 + + Don't try to execute scripts unless they exist. + +commit 594d5b5d15551bd802c43926c7cb8863b7531654 +Author: Guus Sliepen +Date: Sat Mar 23 20:21:10 2002 +0000 + + Reset retry timeout when receiving the first PONG, not right after receiving the ACK. + +commit cbd8133ab4a2ea8a0c46224a5f1ae79e92819e5f +Author: Guus Sliepen +Date: Sat Mar 23 20:13:56 2002 +0000 + + Don't run graph algorithms if no edge is deleted in terminate_connection(). + +commit 6aee1ad021092d37538e15da22367789a4d4a763 +Author: Guus Sliepen +Date: Sat Mar 23 20:12:29 2002 +0000 + + free() request strings when deleting past requests from the tree. + +commit ccea26e0044ea59a9722385c9d69b1bc703e884f +Author: Guus Sliepen +Date: Sat Mar 23 20:01:05 2002 +0000 + + send_ack() was broken. + +commit 3c5655f59e85d312d11fa04489123e604920f95b +Author: Guus Sliepen +Date: Fri Mar 22 13:31:18 2002 +0000 + + Fix compiler warnings, strictly use long int and %lx for options. + +commit d6b70ed6f8b7ed65f64193fcfcdb6c8f4625e03c +Author: Guus Sliepen +Date: Fri Mar 22 12:41:54 2002 +0000 + + Fix add_edge_h(). + +commit 52e7699273a3009fe4d91e608522401076922785 +Author: Guus Sliepen +Date: Fri Mar 22 11:43:48 2002 +0000 + + - Added support for jumbograms. + - Remove tcpaddress from edges, it is not used at all. + - Last bits of code to prevent looping requests. + +commit 9da5390666ad532825d820b3554da3f39d3bc511 +Author: Guus Sliepen +Date: Thu Mar 21 23:11:53 2002 +0000 + + Put a break on requests that run around in circles. + +commit f48f8f4fedba365ceea30e1133bf1c560e9a522a +Author: Guus Sliepen +Date: Tue Mar 19 22:48:25 2002 +0000 + + Updated SSSP algorithm to automatically detect indirect links (if a node uses + different addresses for connections to other nodes). + +commit 5a88a27742d305be48498a297b90ee3fbdd935bf +Author: Guus Sliepen +Date: Tue Mar 19 00:08:34 2002 +0000 + + Updated dutch translation. + +commit 5c2d74de86d1acb3774a20357ad815d000f8a7f6 +Author: Guus Sliepen +Date: Tue Mar 19 00:08:23 2002 +0000 + + Don't use s6_addr[16|32] anymore. + +commit 9d99a789c38e8a1694537e427e8d4313c948b02b +Author: Guus Sliepen +Date: Tue Mar 19 00:07:09 2002 +0000 + + Cleanup. + +commit 305505f5ec4bb738f175cd897fa409f08d2971a3 +Author: Guus Sliepen +Date: Mon Mar 18 22:47:20 2002 +0000 + + Remember sockaddrs of listening sockets, use appropriate one when sending + UDP packets. + +commit 106fc2b769a635142bf5f9233a2f03e3a0f26b7f +Author: Guus Sliepen +Date: Mon Mar 18 14:39:37 2002 +0000 + + Fix #define s6_addr32. + +commit 813c369a8faca94fc38bc66afafad063fa00f928 +Author: Guus Sliepen +Date: Mon Mar 18 14:19:02 2002 +0000 + + #define s6_addr32, needed for FreeBSD. + +commit b2579385de427c3c03d28520d3a93bd5f9bc9488 +Author: Guus Sliepen +Date: Sun Mar 17 16:08:39 2002 +0000 + + Only unmap IPv6 addresses. + +commit 8b84c44175fedb81ca38107e0067ddea750add00 +Author: Guus Sliepen +Date: Sun Mar 17 15:59:29 2002 +0000 + + Unmap v4mapped sockaddrs. + +commit 07e37f8da03fa315be39623e62d8acba617aa226 +Author: Guus Sliepen +Date: Fri Mar 15 15:50:14 2002 +0000 + + Typo. + +commit e0dee537705cdbd005f6ab1fbef5ac71dc8411c0 +Author: Guus Sliepen +Date: Fri Mar 15 15:40:40 2002 +0000 + + Different way of detecting neighbor solicitation requests. + +commit 0e93f0aa02274481c16fc9f30b795d4f063bd1c3 +Author: Guus Sliepen +Date: Fri Mar 15 15:08:21 2002 +0000 + + Oops, don't forget to actually put the checksum in the response packet. + +commit e1de9ca990ea638c7e297c5335be415e44c250c1 +Author: Guus Sliepen +Date: Fri Mar 15 14:41:57 2002 +0000 + + Neighbor solicitation requests now work (I think). + +commit 4b3aef9e6992ca78f1b17b179a3051d3fec0473d +Author: Guus Sliepen +Date: Tue Mar 12 16:30:15 2002 +0000 + + Revert changes to Kruskal's algo. + +commit f219f156cf13fd30369d7cd4632c406ffd6ff628 +Author: Guus Sliepen +Date: Tue Mar 12 14:25:04 2002 +0000 + + Put #ifdef NEIGHBORSOL around corresponding code. + +commit ecad9e9289162faec7b678be54178d22876b5d90 +Author: Guus Sliepen +Date: Tue Mar 12 14:20:44 2002 +0000 + + Remove silly cache thingy. + +commit d6c2c4f2b7a94ef6a4db0de134d015bc8d21ffb1 +Author: Guus Sliepen +Date: Tue Mar 12 14:19:51 2002 +0000 + + Packet sequence number/authentication warnings only if debug_lvl >= 5. + +commit 2e7db2a6936a77baa0a81eb566674bd76d204951 +Author: Guus Sliepen +Date: Tue Mar 12 13:42:23 2002 +0000 + + Simplified implementation of Kruskal's minimum spanning tree algorithm. + +commit d2e0ed533c8aa3c6ab538d87e004108c631cb0be +Author: Guus Sliepen +Date: Mon Mar 11 13:56:00 2002 +0000 + + New strategy: forward icmp6 neighbor solicitations to intended target. + +commit 46fa10cec7b6bf26773f5e86e7b8118d9075e807 +Author: Guus Sliepen +Date: Mon Mar 11 13:14:53 2002 +0000 + + Try to reply to neighbor solicitation requests. + +commit c2713ba7a5ff12e270d66a5d3188a3640873830e +Author: Guus Sliepen +Date: Mon Mar 11 11:45:12 2002 +0000 + + prune_connections() before build_fdset(). + +commit 4fda4560bbdd41e217ce0e1a90ba98c79e4f3519 +Author: Guus Sliepen +Date: Mon Mar 11 11:23:04 2002 +0000 + + Cleanups, spelling fixes, allow symbol names for signals (-k option), + don't remove pidfile if other tincd is still running. + +commit 5ffeb13d65313d5a191a605690a4f8fdf1604b48 +Author: Guus Sliepen +Date: Sun Mar 10 16:09:15 2002 +0000 + + Don't retry to make outgoing connections when exitting. + +commit 3cbe67a8de1da7bd042474de4d16cb4f7e9822ab +Author: Guus Sliepen +Date: Sun Mar 10 15:40:27 2002 +0000 + + Small fixes to improve portability. + +commit 9de7470bfdabacec5f3769bf5cfa97ef4e481ba0 +Author: Guus Sliepen +Date: Sun Mar 10 14:07:08 2002 +0000 + + Autodetect $MAKE/gmake/make. + +commit 0c34478cc03167208c84f3d6d2ed6e53172b4711 +Author: Guus Sliepen +Date: Sun Mar 10 14:05:35 2002 +0000 + + po/POTFILES and po/Makefile should not be generated by configure. + +commit 024ab44d98883d78cefe2c622cec9831c7f19c13 +Author: Guus Sliepen +Date: Sun Mar 10 14:04:48 2002 +0000 + + Fix forwarding of IPv6 packets. + +commit 0c16add71c6432c882c6d8f538a4b2db0026ec24 +Author: Guus Sliepen +Date: Fri Mar 1 15:14:29 2002 +0000 + + Check if BindToDevice and PriorityInheritance are supported. + +commit 7d5741859e681e6b0d0e32b978da6f309c456729 +Author: Guus Sliepen +Date: Fri Mar 1 14:33:48 2002 +0000 + + Woops. + +commit ab90fa9bd1a653a330be7ef11293000721a0e7b4 +Author: Guus Sliepen +Date: Fri Mar 1 14:25:10 2002 +0000 + + Document and clean up MAC address expiry. + +commit 14979f835df4214a7c2510852f7ffedc9e08c2c0 +Author: Guus Sliepen +Date: Fri Mar 1 14:09:31 2002 +0000 + + - Global time_t now, so that we don't have to call time() too often. + - MAC addresses expire after a time configurable by MACExpire (default 600 + seconds) + +commit 7496ecc45ab6205bcce4e576c23b9afb52004e39 +Author: Guus Sliepen +Date: Fri Mar 1 13:38:15 2002 +0000 + + Updated dutch translation. + +commit 0c879b8eeed3477b0f1cdd2f232e67e38bd9bce6 +Author: Guus Sliepen +Date: Fri Mar 1 13:38:02 2002 +0000 + + Updated documentation. + +commit f93b1334e087dd7af1b87f475b2d398fdd4d56ab +Author: Guus Sliepen +Date: Fri Mar 1 13:18:54 2002 +0000 + + Create/bind TCP and UDP listening sockets in pairs. + +commit c2b738e7b51fbec2b11fbbf030b9a5a36df55fc4 +Author: Guus Sliepen +Date: Fri Mar 1 12:26:56 2002 +0000 + + If "PriorityInheritance = yes" is specified in tinc.conf, the value of the + TOS field of the tunneled packets will be passed on to the UDP packets tinc + sends out. + +commit 80ea653e8d8050878380fbc1446571cbaf578297 +Author: Guus Sliepen +Date: Fri Mar 1 12:25:58 2002 +0000 + + Fix listening sockets. + +commit 7f58ed7685f9fcd5271359a8c896670a835e1f95 +Author: Guus Sliepen +Date: Fri Mar 1 11:18:34 2002 +0000 + + Make BindToInterface work. + +commit 17bc5220c332fdd083fd47fc600010f85171adc7 +Author: Guus Sliepen +Date: Wed Feb 27 22:37:55 2002 +0000 + + Fix send_request() bug. + +commit 50403909b6bf6536924d4693bb1f32c248f17fda +Author: Guus Sliepen +Date: Tue Feb 26 23:26:41 2002 +0000 + + Allow multiple listening sockets. + +commit 2ac7be0d51a112108dc6c2b1c6f46da022f72f40 +Author: Guus Sliepen +Date: Tue Feb 26 22:47:51 2002 +0000 + + Tweaking IPv6 support. + +commit 23fda5688e8a109f8a50511538b14e4fbe4f738c +Author: Guus Sliepen +Date: Wed Feb 20 22:37:38 2002 +0000 + + - Change SA_LEN to SALEN, former one is already defined on some platforms. + - Use SALEN everywhere appropriate. + +commit dbc5b5bb5eb3096ad930aa6b590deaba2a103dfc +Author: Guus Sliepen +Date: Wed Feb 20 22:15:32 2002 +0000 + + - Use gai_strerror() where appropriate + - Clear hints before using them with getaddrinfo() + - Use sa_len on platforms that support them + +commit 28cc9a6488f78c72152251f6fa2ee84d417223e8 +Author: Guus Sliepen +Date: Wed Feb 20 19:31:15 2002 +0000 + + Preserve inpkt->len, needed for broadcasts. + +commit c6d01588312bec7691e72b42cf20c59ffe2749c2 +Author: Guus Sliepen +Date: Wed Feb 20 19:25:09 2002 +0000 + + Protocol now also exchanges cipher/digest/maclength/compression for the + meta connection. + +commit 626d5956d2bb0660ba315fba77da6cec9776fd3b +Author: Guus Sliepen +Date: Wed Feb 20 17:16:15 2002 +0000 + + Cache results of lookup_subnet_...(). + +commit e8e69460a7090aaf6ecda8970d3060695de81b00 +Author: Guus Sliepen +Date: Wed Feb 20 17:15:33 2002 +0000 + + Fix maskcmp() and maskcpy(). + +commit ed509312906625acee4007da6262de3898846888 +Author: Guus Sliepen +Date: Wed Feb 20 16:04:59 2002 +0000 + + Forward packets in router mode. + +commit 8c91fac31570594b6249d632cefe768f33c54b19 +Author: Guus Sliepen +Date: Wed Feb 20 16:04:39 2002 +0000 + + Use AF_UNSPEC for listening sockets if AddressFamily = any. + +commit 76f01453dfa157b0070751b1025e55a1e36ebdca +Author: Guus Sliepen +Date: Wed Feb 20 16:04:07 2002 +0000 + + Fix segfault when receiving HUP signal. + +commit c2b9c06062d36bde859b630b99a08c7b7428e721 +Author: Guus Sliepen +Date: Mon Feb 18 16:25:19 2002 +0000 + + - Non-blocking connect()s. + - Socket handling revamped to use sockaddr_t. + - tinc can now tunnel over IPv6. + - Handle all addresses and subnets in network byte order. + Only convert them when they need to be printed. + - IPv6 subnets bigger than /128 now work. + - Use %s and strerror(errno) instead of %m. + +commit fc674eaae14ed2e07abc0df1285b1bd70e0d27cc +Author: Guus Sliepen +Date: Tue Feb 12 14:42:37 2002 +0000 + + Add check for NetBSD. + +commit 2fb8a62edef7cb0988e44f92c3948cde6f34875e +Author: Guus Sliepen +Date: Tue Feb 12 14:40:12 2002 +0000 + + Added device.c for NetBSD, actually a copy of the OpenBSD one. + +commit f64b41a73b3b432aae17ba990414e0be2f61ce62 +Author: Guus Sliepen +Date: Tue Feb 12 14:36:45 2002 +0000 + + Get rid of sys/signal.h. + +commit dd611fb4f91b9b17c20c458694d2765b22814c5f +Author: Guus Sliepen +Date: Tue Feb 12 14:29:00 2002 +0000 + + Don't use sa_sigaction (which NetBSD doesn't like) at all if we don't use siginfo. + +commit d9a62c6354d1e2ad78ee8c610518ae9f9ab012d1 +Author: Guus Sliepen +Date: Mon Feb 11 15:59:18 2002 +0000 + + Added support for packet compression, thanks to Mark Glines. + Add "Compression = " to the host config files, where level can be + 0 (off), or any integer between 1 (fast) and 9 (best). + +commit 94b171b3051b999e619ae19e1c9c29d356606788 +Author: Guus Sliepen +Date: Mon Feb 11 14:20:46 2002 +0000 + + Small fix. + +commit 1708997bc8ab55122f9de9cc8b81397d3a003ea9 +Author: Guus Sliepen +Date: Mon Feb 11 14:20:21 2002 +0000 + + - If no PrivateKeyFile is specified, /etc/tinc/netname/rsa_key.priv is assumed. + - Check RSA key before using it. + +commit 1c34ba7fb8580949f3bd3a0d804747bbaea28e36 +Author: Guus Sliepen +Date: Mon Feb 11 12:33:01 2002 +0000 + + Sensible defaults for $INTERFACE. + +commit 24cc2a9065a4e962fb05addac47322930099a4b5 +Author: Guus Sliepen +Date: Mon Feb 11 10:16:18 2002 +0000 + + Last bits of the merger. + +commit 5bf4b88666ecafe190e8ed71d6c14c9de8d16e1f +Author: Guus Sliepen +Date: Mon Feb 11 10:05:58 2002 +0000 + + Forgot to merge new files from pre5. + +commit f0aa9641e82fb6e09c1e485366d14dddaa7f7c36 +Author: Guus Sliepen +Date: Sun Feb 10 21:57:54 2002 +0000 + + Merging of the entire pre5 branch. + +commit c2752b961c9262386b940c2c053b9909bee22859 +Author: Ivo Timmermans +Date: Fri Nov 16 22:41:38 2001 +0000 + + Conversion to struct addrinfo is almost complete for this file. + +commit 4f47da5b87ef7da608c7e44026122f3d95deb2eb +Author: Ivo Timmermans +Date: Fri Nov 16 22:40:26 2001 +0000 + + Don't include netutl.h. + +commit a59bbc72317c9cd97243a9cbf49db01ff249eb1e +Author: Ivo Timmermans +Date: Fri Nov 16 22:31:41 2001 +0000 + + Fixed silly typo: "np" instead of "no" + +commit bf664c054fdabc30679367a752a27bb769655e4d +Author: Ivo Timmermans +Date: Fri Nov 16 22:31:15 2001 +0000 + + get_config_subnet needs to be fixed. + +commit 9b2b3747340173590b8f6f5fbdd060b42985f026 +Author: Ivo Timmermans +Date: Fri Nov 16 17:40:50 2001 +0000 + + route_ipv4 and route_ipv6 replaced by route_ip. + +commit a4938b22e7502579ce44cac42410111db11256eb +Author: Ivo Timmermans +Date: Fri Nov 16 17:39:59 2001 +0000 + + Don't include netutl.h. + +commit ccda709f8243949a3c0ffcc6133d8d8fc5125f2e +Author: Ivo Timmermans +Date: Fri Nov 16 17:39:38 2001 +0000 + + lookup_node_udp changed. + +commit 836766d4c5bc47682ab69c57337157c879517670 +Author: Ivo Timmermans +Date: Fri Nov 16 17:38:39 2001 +0000 + + First part of rewriting things to use struct addrinfo. + +commit 2ec5b5f8621d9fb91181ab155084daa1bb2d1a54 +Author: Ivo Timmermans +Date: Fri Nov 16 17:37:08 2001 +0000 + + Added dropin replacements for get*info and helper functions. + +commit aabe59f6305cdd46220e95d8927a1636d4b4819d +Author: Ivo Timmermans +Date: Fri Nov 16 16:16:33 2001 +0000 + + Added HAVE_STRUCT_ADDRINFO + +commit 251f87c842b62cf770129d8a953fb06ef5d0e466 +Author: Ivo Timmermans +Date: Fri Nov 16 15:56:44 2001 +0000 + + (re)added port to struct node_t + +commit 6cf744e4b29cfe3b135b6553851816802ba3d8a8 +Author: Ivo Timmermans +Date: Fri Nov 16 12:22:02 2001 +0000 + + Don't include netutl.h. + +commit a79252af4383b8cd71cf0d13f1ae040d518517bf +Author: Ivo Timmermans +Date: Fri Nov 16 12:21:22 2001 +0000 + + Obsoleted. + +commit 331d9402e892b4baa9cadbbb364073ae10b58d99 +Author: Ivo Timmermans +Date: Fri Nov 16 12:16:28 2001 +0000 + + Don't compile/link netutl.c. + +commit f95e6ca8f6976d7a15f4623e25c85e1c7f82c04b +Author: Ivo Timmermans +Date: Fri Nov 16 12:14:20 2001 +0000 + + get_config_{ip,port} removed. + +commit 31db57bb4a00f5ca3743b89f8bb2fbd39919bf28 +Author: Ivo Timmermans +Date: Fri Nov 16 12:13:34 2001 +0000 + + Changed to use struct addrinfo where needed. + +commit f1b20b3ded5b360e426e094cf79df3bf97f350b4 +Author: Ivo Timmermans +Date: Fri Nov 16 12:10:54 2001 +0000 + + Obsoleted all IP types in favor of struct addrinfo + +commit fb6dc0b0890ebae2471e00e7a3e1d86c1fc3d646 +Author: Ivo Timmermans +Date: Fri Nov 16 12:08:38 2001 +0000 + + Removed definitions of ipv4_t, ipv6_t, port_t + +commit 3ef15f2554d1819d6c7d2573dac6039f2e76b638 +Author: Ivo Timmermans +Date: Fri Nov 16 12:02:17 2001 +0000 + + Changed lookup_connection to use struct addrinfo + +commit 74e1299fb58025f7506c7e2608c353a76f98d8df +Author: Ivo Timmermans +Date: Fri Nov 16 12:01:48 2001 +0000 + + Changed prototype for lookup_connection to use struct addrinfo + +commit 51b72b75f254c956b62be9dfca642145b199415f +Author: Ivo Timmermans +Date: Fri Nov 16 00:23:28 2001 +0000 + + Use struct addrinfo in connection_t to hold all host data such as IP + address and port + +commit 72395f989cb44132d7c756c91b3a6d8ba63517e5 +Author: Ivo Timmermans +Date: Fri Nov 16 00:13:08 2001 +0000 + + Deprecated get_config_ip and get_config_port + +commit 93cd0e33defba46f8e51d9a98a94599ceb0d521c +Author: Ivo Timmermans +Date: Thu Nov 15 23:49:46 2001 +0000 + + Check for struct addrinfo + +commit b16bf68a6dc27b364cb76156a7be0208594f1e94 +Author: Ivo Timmermans +Date: Thu Nov 15 23:28:58 2001 +0000 + + Credit OpenSSH + +commit 18269cfbe831902b97a6171ba0346fd323583e48 +Author: Ivo Timmermans +Date: Thu Nov 15 23:26:27 2001 +0000 + + Check for getnameinfo, gai_strerror, freeaddrinfo + +commit ae11e7c3d71893c5200b12682839538a52df37b8 +Author: Ivo Timmermans +Date: Thu Nov 15 23:05:34 2001 +0000 + + Check for getaddrinfo + +commit e06415e3d9d08cd33c5983a2c49c4101377160c2 +Author: Guus Sliepen +Date: Mon Nov 5 19:09:08 2001 +0000 + + More fixes for Solaris. + +commit 25a804c94ef0dbc4e5582ea6d8459d5f9a3fe06c +Author: Guus Sliepen +Date: Mon Nov 5 19:06:07 2001 +0000 + + Various fixes needed for Solaris. + +commit b2d5002ff1ccd44fbf3a94e4c41909ab6141f3bb +Author: Guus Sliepen +Date: Sun Nov 4 23:48:27 2001 +0000 + + Correctly check if subnet owner exists. + +commit ede6671c1354eeab86936efda32f6cdb3b3fd8d5 +Author: Guus Sliepen +Date: Sun Nov 4 23:29:50 2001 +0000 + + Be liberal in what you accept: allow unknown edges to be deleted. + +commit cf0e133e191cb40954bf5b6ee0a579442fe4b60b +Author: Guus Sliepen +Date: Sat Nov 3 22:53:02 2001 +0000 + + *** empty log message *** + +commit e5047d2835f0828a9c334cc3d928c2322abfefb7 +Author: Guus Sliepen +Date: Sat Nov 3 21:22:02 2001 +0000 + + Several bugfixes. + +commit 8910cbd67e13450e93816ecafa0cc5be5e4c2378 +Author: Guus Sliepen +Date: Sat Nov 3 21:21:04 2001 +0000 + + Use PEM functions as suggested by OpenSSL docs. + +commit 8e74c5bee48f2ef363193044d5309a65e91c70d8 +Author: Guus Sliepen +Date: Wed Oct 31 20:37:54 2001 +0000 + + Some very small fixes + +commit ffb88ff6410f33de92db108bd1e0c3a915368214 +Author: Guus Sliepen +Date: Wed Oct 31 20:22:52 2001 +0000 + + Avoid connecting to another node twice, and check name of outgoing connections. + +commit 6d333ad680465c26953ad4c8ca9140e27da868c5 +Author: Guus Sliepen +Date: Wed Oct 31 20:07:17 2001 +0000 + + Show cfg->variable instead of cfg->value when complaining about wrong type. + +commit 54b756f7dfb71c5622b7738fd449e126da959864 +Author: Guus Sliepen +Date: Wed Oct 31 20:02:06 2001 +0000 + + Don't forget to read public RSA key when making an outgoing connection. + +commit c0a3f67a5d66088aaf526f1461986f9e86d5dd1f +Author: Guus Sliepen +Date: Wed Oct 31 12:50:24 2001 +0000 + + - Small fixes to graph algorithms + - More control over tap device, ability to set interface name to something + other than the netname. + - Export NETNAME, DEVICE and INTERFACE environment variables to scripts. + +commit 2165931c62f0433fd97bd3ac6aefea3627218946 +Author: Guus Sliepen +Date: Tue Oct 30 16:34:32 2001 +0000 + + More updates to protocol handlers and reimplemented terminate_connection(). + +commit 87ad5c97a9a73a65050ad7adce34503f856d8665 +Author: Guus Sliepen +Date: Tue Oct 30 12:59:12 2001 +0000 + + Various fixes, tinc is now somewhat capable of actually working again. + +commit cc9473d8c6467e9eaa82fe8a639d8edba232ee76 +Author: Guus Sliepen +Date: Mon Oct 29 13:14:57 2001 +0000 + + Working version of Kruskal's algorithm. The running time is very bad though. + +commit b6298e2c082035b8238ea08673ced15d0fb7b89a +Author: Guus Sliepen +Date: Sun Oct 28 22:42:49 2001 +0000 + + - More changes needed for Kruskal's algorithm + - Implemented a breadth-first search algorithm as a cheap substitution for a + single-source shortest path algorithm. + +commit 66067cc9c1347fb2de35660d531fdd4be8aede6a +Author: Guus Sliepen +Date: Sun Oct 28 10:16:18 2001 +0000 + + - More s/vertex/edge/g + - Implementation of Kruskal's minimum spanning tree algorithm. + +commit 94497336efc1cc60561575e74d420e9e8e8c657e +Author: Guus Sliepen +Date: Sun Oct 28 08:41:19 2001 +0000 + + What was I thinking? s/vertex/edge/g. + +commit b98d9787fdde54f33dcdb376e1e018cd418aff8d +Author: Guus Sliepen +Date: Sat Oct 27 15:19:13 2001 +0000 + + Various small fixes to make tinc runnable again. + +commit ac066bb057dcb187bf91670793ba5e6ca456e052 +Author: Guus Sliepen +Date: Sat Oct 27 13:13:35 2001 +0000 + + Make sure everything links. + +commit 82e383710980534d38bb9a8ef22f20677cd85861 +Author: Guus Sliepen +Date: Sat Oct 27 12:13:17 2001 +0000 + + Big bad commit: + - Transition to new node/vertex/connection structures + - Use new configuration handling everywhere + - Linux tun/tap device handling cleanup + - Start of IPv6 support in route.c + + It compiles, but it won't link. + +commit 1935c44a1e8ab7c31c836f90215e3c5b5f8dd776 +Author: Guus Sliepen +Date: Sat Oct 13 13:53:07 2001 +0000 + + Support new files (node/vertex/device.[ch]) and OpenBSD. + +commit 26e517dd37e995fe9db518f7ebeff023fc73ff1b +Author: Guus Sliepen +Date: Fri Oct 12 15:52:03 2001 +0000 + + Forgot the tun specific stuff. + +commit ad61c20f42d2bee5cc7976bec4370cf4747b42c3 +Author: Guus Sliepen +Date: Fri Oct 12 15:49:11 2001 +0000 + + Added OpenBSD tun device handling. Untested though. + +commit 0c6321a67f92981d3adbaf4f5c2b9867c7968964 +Author: Guus Sliepen +Date: Fri Oct 12 15:38:35 2001 +0000 + + Forgot to remove some old #ifdef stuff. + +commit 6014c7e6374089bfccea7467c2c7f4b23fefa265 +Author: Guus Sliepen +Date: Fri Oct 12 15:33:21 2001 +0000 + + Solaris tun device handling cleaned up a bit and added. + +commit 623c7ee0308aede8eada552d6ae33710ae24d176 +Author: Guus Sliepen +Date: Fri Oct 12 15:22:59 2001 +0000 + + Added FreeBSD tap device handling. + +commit ec34f25228d7a0007ce6bcb1e97f263868e9129d +Author: Guus Sliepen +Date: Fri Oct 12 15:16:03 2001 +0000 + + - Split tap device stuff out of net.[ch] + - Each OS gets it's own device.c to get rid of evil #ifdefs. + - Cleaned up Linux ethertap and tun/tap handling. + +commit 0bbace18e96cd6fc32dfa23ffd55f73ff96e8c6f +Author: Guus Sliepen +Date: Wed Oct 10 20:35:10 2001 +0000 + + More updates to new node/vertex/connection combo. + +commit ea607d2d9292d3969f9d164b432dc64a33c2dade +Author: Guus Sliepen +Date: Wed Oct 10 20:34:27 2001 +0000 + + Revamp configuration handling: + - Store everything in AVL trees (fast lookup) + - No need for hazahaza anymore + - Parse values when needed + - This simplifies a lot of config variable lookups. + +commit 5904806dc80830d4eddca857a41db2fc25598201 +Author: Guus Sliepen +Date: Wed Oct 10 09:42:29 2001 +0000 + + Removed everything from connection.c that has already been moved to node.c and + vertex.c. + +commit ec0c16b9b63f361b11a757ee1641d562e4811f93 +Author: Guus Sliepen +Date: Wed Oct 10 08:49:47 2001 +0000 + + Further implementation of doc/CONNECTIVITY. connection.[ch] is now split into a + node, vertex and connection part. + +commit 75e1ae3a287642ca4281792c94ecd07332f39c08 +Author: Wessel Dankers +Date: Tue Oct 9 19:41:56 2001 +0000 + + make is not always GNU make. + +commit f22b9417510cca258785f8958c8dfed90e26d81b +Author: Guus Sliepen +Date: Tue Oct 9 19:37:10 2001 +0000 + + Small corrections. + +commit 49a2cd806c73cff1ab6a712a996c7f7d4e1f32c0 +Author: Guus Sliepen +Date: Tue Oct 9 19:30:30 2001 +0000 + + Started implementing doc/CONNECTIVITY. + +commit 5926c82b9a29031a8c619432869d1549b51b62a0 +Author: Guus Sliepen +Date: Mon Oct 8 15:47:30 2001 +0000 + + Updated dutch translation. + +commit fcc3ded75fe9f831aeb8678ee5e3926bf4168906 +Author: Guus Sliepen +Date: Mon Oct 8 15:37:14 2001 +0000 + + Fix bug when dropping an old connection in favour of a new one from the + same host. + +commit 1ef90a87fd9fd53c25a43455ffaac5274a63dc08 +Author: Guus Sliepen +Date: Mon Oct 8 13:37:30 2001 +0000 + + - Use ping timeout mechanism to close connections that don't authenticate + in time. + - Fix potential segmentation fault in check_dead_connections(). + +commit ce9fd32c04adf83cbaf668ee42a29575ba256002 +Author: Guus Sliepen +Date: Mon Oct 8 11:59:08 2001 +0000 + + Fix bug where tinc would crash because of a portscan or a connection from a + tinc daemon with a different version. + +commit 21027b1d5702c331b1ebb262bb149c75be1f24b1 +Author: Guus Sliepen +Date: Mon Oct 8 11:47:55 2001 +0000 + + - Renamed lastbutonehop to prevhop. + - Added connection_t *via to connection_t, this keeps record of where + to send UDP packets to. + +commit 18d1233c40a5705e9123edd6f4c6764a5178003b +Author: Guus Sliepen +Date: Tue Sep 25 13:39:11 2001 +0000 + + Fill in next- and lastbutonehop for myself. + +commit ec100a58b44e412a3d2606e5213af9ec5f30235b +Author: Guus Sliepen +Date: Tue Sep 25 13:35:45 2001 +0000 + + Try next connectto instead of the same over and over. + +commit 4d3de3b6a9b55bc783c649ff33e5415b0c7b5f25 +Author: Guus Sliepen +Date: Mon Sep 24 14:16:29 2001 +0000 + + Show next- and lastbutonehop when dumping connectionlist to syslog. + +commit 24a2c7e51a0b080c4bdb55f697b3f0458ebc3fb1 +Author: Guus Sliepen +Date: Mon Sep 24 14:12:00 2001 +0000 + + Not only keep track of nexthop, but also of lastbutonehop. If destination cl + wants indirectdata, send it to the lastbutonehop instead, unless it too has + requested so, and so on. + +commit 154733927af0b27cdadb83f03b845301ce8bfbfd +Author: Guus Sliepen +Date: Mon Sep 24 13:31:15 2001 +0000 + + - Try old TUN/TAP ioctl() request if the one from if_tun.h fails. + - Be more verbose about the kind of tap device used. + +commit 950c934e0bda28e5952d699d6008ee783d81982b +Author: Ivo Timmermans +Date: Wed Sep 5 18:38:09 2001 +0000 + + Killing tincd with SIGINT causes it to toggle between the current + debug level and level 5. Useful to debug a running tincd. + +commit a54ec980e047d13ecff7f1f337aa2665072febfd +Author: Guus Sliepen +Date: Sat Sep 1 12:46:49 2001 +0000 + + config_t* is a const parameter in get_config_val(). + +commit 68e23b1c9e69b2a218b3be821ad1ba3b3b6a64f2 +Author: Guus Sliepen +Date: Sat Sep 1 12:36:53 2001 +0000 + + Optional signal number for -k option. + +commit 8ed27d40f358581d021319cc26313c9f6ddf9a71 +Author: Guus Sliepen +Date: Sat Sep 1 12:36:06 2001 +0000 + + Revised reconnection mechanism, always try out all ConnectTo lines. + +commit ef1facc60709e9474197aa3fde9d517dfd96dc87 +Author: Guus Sliepen +Date: Sat Sep 1 12:02:39 2001 +0000 + + Remove IndirectData support for now, new implementation will be added + later. + +commit 8b5e4211304aaa5d39bc95f04398bd5ecaa887d8 +Author: Guus Sliepen +Date: Tue Aug 28 20:52:39 2001 +0000 + + Fix signed comparison bug in lookup_subnet_ipv4(). + +commit e1184ad15d6b2e7d58bdcb4489026dd0a35b4e5f +Author: Guus Sliepen +Date: Fri Aug 17 18:14:04 2001 +0000 + + Don't send DEL_HOSTs when !status.meta + +commit 30d22474ccc8da9a5685a90e0b2304ec627475af +Author: Guus Sliepen +Date: Tue Jul 24 20:14:30 2001 +0000 + + Explicitly log which type of tunnel device is used. + +commit 7e86cf91e3399905e19882bcf2d5677d7986aca5 +Author: Guus Sliepen +Date: Tue Jul 24 20:13:42 2001 +0000 + + The val variable in a config_t is never used as a long. + +commit 43923d2b106bfbe9300cc8e364cf098444cd649e +Author: Guus Sliepen +Date: Tue Jul 24 20:04:22 2001 +0000 + + Write public key to rsa_key.pub instead of rsa_key.priv (if not host + configuration file is found). + +commit 44e9d6a2872fac55f7eb701ba576ed9f39a22e08 +Author: Guus Sliepen +Date: Tue Jul 24 20:03:40 2001 +0000 + + Don't use %m in fprintf(). + +commit cbd03caece25d45015a4526b94b04a34ab87b0f2 +Author: Guus Sliepen +Date: Tue Jul 24 08:51:36 2001 +0000 + + More on edges. + +commit 3cd238f4e338f257ff61d58a9979b54344ee462f +Author: Guus Sliepen +Date: Mon Jul 23 22:06:22 2001 +0000 + + Discuss how sending ADD_EDGEs would be better than sending ADD_HOSTs. + +commit 5333cada0dfc4dfc3be728e6c78d8d42dc2ace52 +Author: Guus Sliepen +Date: Sun Jul 22 17:41:52 2001 +0000 + + Written down a possible solution. + +commit 995ab86fce506e9fabcf5a9ead7d43b30f12ab09 +Author: Guus Sliepen +Date: Sun Jul 22 15:25:13 2001 +0000 + + Correctie. + +commit d7b4de0e73baf664964f6daaf63526606b6a890b +Author: Guus Sliepen +Date: Sun Jul 22 14:58:18 2001 +0000 + + Small update. + +commit 71b9041f484128219f81cbf4f22a4e11388f879d +Author: Guus Sliepen +Date: Sun Jul 22 14:46:11 2001 +0000 + + Described problem in more detail. + +commit c1a98cd37ea20f6020487b2a5586e6de432398e7 +Author: Guus Sliepen +Date: Sun Jul 22 14:04:38 2001 +0000 + + Started writing a document about how daemons connect to each other. + +commit fcbe215d64d7e2f3b159fff6422d750417877ac4 +Author: Guus Sliepen +Date: Sat Jul 21 20:21:25 2001 +0000 + + Woohoo! tinc now compiles, runs and actually *works* on Solaris! + Tested on a SparcStation 20MP running Solaris 7. (Thanks, jiggel!) + +commit 533ee1206fb6433a1f0e616db999b3655addfaf2 +Author: Guus Sliepen +Date: Sat Jul 21 15:46:34 2001 +0000 + + Always close all sockets in terminate_connection(). + +commit acb853205d6d582d919c59879393b301ad4f4fde +Author: Guus Sliepen +Date: Sat Jul 21 15:34:18 2001 +0000 + + Updated terminate_connection() so you can choose if DEL_HOSTs should be + sent or not. + +commit 12f6b80429bc05a828051d72cc46f173e4657180 +Author: Guus Sliepen +Date: Fri Jul 20 20:25:10 2001 +0000 + + Added purge_tree for connection_t's which are no longer in the connection, + active or id trees, but which may still be referenced. This tree is flushed + when it is safe, this replaces purge_connection_tree(). + + Also lots of bugfixes related to the new trees. + +commit 37ed4265fa73d4c06c74362514d78c92029b2f05 +Author: Guus Sliepen +Date: Fri Jul 20 13:54:19 2001 +0000 + + Remove all unnecessary status.meta and status.active checks. + +commit 5e2ded68bfc7b3a1bfa600c1ce46144eb50e57a2 +Author: Guus Sliepen +Date: Thu Jul 19 12:29:40 2001 +0000 + + Correctly use the active_tree. + +commit 319e0cb48eb00565a11c85b901f54141f8160334 +Author: Guus Sliepen +Date: Sun Jul 15 18:07:31 2001 +0000 + + Split connection list into two lists: + - one list to handle all incoming/outgoing TCP connections + - another list to handle all UDP connections + + This will prevent race conditions. + +commit b3074590b184c141419cf4926820dc0d78380535 +Author: Guus Sliepen +Date: Sun Jul 15 14:21:12 2001 +0000 + + Correct inclusion of standard if_tun.h header file. + +commit 5dc4ade0b9c127a3c144d9c59894bf13527fe060 +Author: Guus Sliepen +Date: Wed Jul 4 08:43:32 2001 +0000 + + Don't load table of verbose OpenSSL errormessages. + +commit 1e2bdc2b6d28c76c63fc9fd36169b90fa0994388 +Author: Guus Sliepen +Date: Wed Jul 4 08:41:36 2001 +0000 + + - Always use instead of just + - Check if RAND_pseudo_bytes() exists, otherwise just use RAND_bytes() + +commit 6bd93e4c064578b545cb6dcaa28fffb229c929ff +Author: Guus Sliepen +Date: Sun Jul 1 21:42:13 2001 +0000 + + Check for all potential duplicate entries in the id tree. + +commit 9645cabc8e8364ed4df187fab8065b0991afa6af +Author: Guus Sliepen +Date: Sun Jul 1 09:21:14 2001 +0000 + + Fix compiler warning. + +commit 6365d0627b9b1e9a31371ec891db0d2cfb4d6ed4 +Author: Guus Sliepen +Date: Sun Jul 1 09:21:01 2001 +0000 + + Fix printf format bug. + +commit 33d6de0cd5c05cbf37211924a45e4231fec3a416 +Author: Guus Sliepen +Date: Sun Jul 1 09:06:17 2001 +0000 + + More items marked as done. + +commit a111593a082ff1df26f54168ab00f83ab3a1ab49 +Author: Guus Sliepen +Date: Fri Jun 29 15:38:40 2001 +0000 + + Dutch translation updated. + +commit 748dabdbe93f7439ed7eddf491a556279250e7ac +Author: Guus Sliepen +Date: Fri Jun 29 15:33:18 2001 +0000 + + Update of RedHat build scripts. + +commit 343c8fb6388ffd4f5c41cebd666aa8a045b20bdd +Author: Guus Sliepen +Date: Fri Jun 29 15:32:26 2001 +0000 + + It appears that autogen.sh doesn't like es.po if it isn't mentioned in + the makefile/configure scripts. + +commit 9391efe4e88077723840a7c085388ba2765ca17c +Author: Guus Sliepen +Date: Fri Jun 29 14:15:46 2001 +0000 + + Check for dlopen in standard libraries first (needed for DEC OSF). + +commit c9591bd1de1abcfe10459bd8c8cdd81a7b441ec0 +Author: Guus Sliepen +Date: Fri Jun 29 13:09:55 2001 +0000 + + Fix gcc 3.0 warnings. + +commit 402b85c48284a06fbfc56aca102b33be3a4260b0 +Author: Guus Sliepen +Date: Fri Jun 29 13:09:32 2001 +0000 + + Log error if two hosts connect with same IP/port tuple. + +commit 0d3bd912acdb00dc0a8015e337f981c942aa21bc +Author: Guus Sliepen +Date: Fri Jun 29 11:09:13 2001 +0000 + + Also remove po/Makefile.in.in, which is generated by autogen.sh. + +commit 67c16924c10b25d37957843a69d993b934dd1776 +Author: Guus Sliepen +Date: Fri Jun 29 11:03:27 2001 +0000 + + es.po revived. + +commit 5d3450357482176ce92ed4832ec944519d197744 +Author: Guus Sliepen +Date: Fri Jun 29 10:30:18 2001 +0000 + + Execute tinc-down BEFORE tap device is closed. This is a. more symmetric + (tinc-up is started after tap device is opened) and b. is needed for + tun/tap device, where the interface does not exist anymore after the + device file is closed. + +commit 6666acd0012c82c0bb4d1abae87332cec3dda77a +Author: Guus Sliepen +Date: Fri Jun 29 10:27:57 2001 +0000 + + Don't build Spanish translation. + +commit 77f635e871060f63c3e62fcf879d184326c690a4 +Author: Guus Sliepen +Date: Fri Jun 29 10:27:33 2001 +0000 + + ABOUT-NLS is created by autogen.sh. + +commit 333be8fbb8790237577761e580126a6d757a46e4 +Author: Guus Sliepen +Date: Fri Jun 29 10:23:46 2001 +0000 + + Spanish translation removed. Nobody maintains it, and it is severely + outdated. + +commit 3503ba995012f658f087a196dad0cb9fd45eff3b +Author: Ivo Timmermans +Date: Tue Jun 26 22:00:57 2001 +0000 + + Small fix to make it compile again + +commit 7fc068fe5421f7ec556b0b7db6f814e18b3326a4 +Author: Guus Sliepen +Date: Thu Jun 21 18:28:52 2001 +0000 + + Reinstated search for if_tun.h in kernel source tree, because apparently + /usr/include/linux does not always have the same contents as the include + files from the currently running kernel. + +commit 9e96840da810437c45af1c4b139578f7d74d65db +Author: Guus Sliepen +Date: Thu Jun 21 16:37:47 2001 +0000 + + Remove #warnings I used for debugging stuff. + +commit b1e97ece9c495ac67e54b8c2675b1eacc645eb1c +Author: Guus Sliepen +Date: Thu Jun 21 16:37:05 2001 +0000 + + Check for and add -ldl. + +commit 04ec0b82ab9c6a2662300a9257a5aff1c4dd56e7 +Author: Guus Sliepen +Date: Thu Jun 21 16:16:32 2001 +0000 + + - Solaris compile fixes + - Set mymac to broadcast MAC so that ifconfig hw ether <...> is really not + needed anymore. + - Forwarding of indirect packets when in switch mode (because the kernel + will not do it for us then). + +commit 353a9230bb70b70028f2dc6c651a28e30b13dc63 +Author: Ivo Timmermans +Date: Wed Jun 20 21:32:40 2001 +0000 + + Don't include the debian/ dir in a release + +commit 9a0a50cd3cf2570b39e00edf1a92123acbac41b4 +Author: Guus Sliepen +Date: Sat Jun 9 10:00:34 2001 +0000 + + Woops - big bug in send_key_changed fixed. + +commit ba918dce287788aaf6a90b3c7a9f349b197068d6 +Author: Guus Sliepen +Date: Fri Jun 8 18:02:10 2001 +0000 + + Only reset seconds_till_retry when we activate the outgoing connection. + +commit c5c02a0861bf540e07fe64704cb97aae29c4cacf +Author: Guus Sliepen +Date: Thu Jun 7 07:51:04 2001 +0000 + + Changed drastically because it didn't work correctly: + - Don't cache the --with-openssl-* option arguments + - Only search for openssl/*.h, the openssl include files include other + files only from an openssl/ directory too + - Set CPPFLAGS before AC_CHECK_HEADERS + +commit 053e78654097cf353aa59b4d34e608726edd5dad +Author: Guus Sliepen +Date: Thu Jun 7 07:48:11 2001 +0000 + + Save configure cache more often. + +commit 96ef7becdd71fc63c3489e3696117c1f137eade5 +Author: Guus Sliepen +Date: Wed Jun 6 19:12:38 2001 +0000 + + Fixes to make switching work between hosts that have no meta-connection. + +commit ce6c8e6d089abac81520c517185c6ef81b09f051 +Author: Guus Sliepen +Date: Wed Jun 6 19:11:16 2001 +0000 + + Log and warn about duplicate subnet_add()'s for the same subnet. + +commit 9cd9b0392388e24ade19a43206221081b61806e7 +Author: Guus Sliepen +Date: Tue Jun 5 19:45:47 2001 +0000 + + Add missing? counting of total_socket_in. + +commit 7bd7f5b4363f222340e5c058c243d31c576fba88 +Author: Guus Sliepen +Date: Tue Jun 5 19:39:54 2001 +0000 + + You can now put an option "Mode" in tinc.conf, and choose from: + + - Mode = router (default, work like tinc has always worked) + - Mode = switch (work like a switch) + - Mode = hub (work like a hub, broadcasting everything) + +commit edd6734faa37d043b8a2cc75b125db3b1c2130fa +Author: Guus Sliepen +Date: Tue Jun 5 18:07:14 2001 +0000 + + Fix bug where lookup_subnet_ipv4() could go into an infinite loop. + +commit fa376fbd4e5151ae43e86441a1e99073eeaf46a5 +Author: Guus Sliepen +Date: Tue Jun 5 16:31:59 2001 +0000 + + - This oneliner removes the need for ifconfig tap? hw ether fe:fd:0:0:0:0 + +commit 7a736d47b264065371f35cd9da64485d798cbc80 +Author: Guus Sliepen +Date: Tue Jun 5 16:15:48 2001 +0000 + + Updated dutch translation. + +commit 92924e8482f000eb33130ce9feadc08450ff349d +Author: Guus Sliepen +Date: Tue Jun 5 16:13:41 2001 +0000 + + Changed some stuff to allow correct generation of po/Makefile after a + make cvs-clean. + +commit 4f9dad0972ac0f665a1b6050b059bd52f93e6221 +Author: Guus Sliepen +Date: Tue Jun 5 16:09:55 2001 +0000 + + - tinc can now act as a switch or a hub too (as opposed to a router only) + - cleaner initialisation of "UNKNOWN" and "MYSELF" names + +commit 428482d86f860d1fb09de722c1b6576ec2eef1ce +Author: Guus Sliepen +Date: Mon Jun 4 11:14:35 2001 +0000 + + Added proxy-arp support. No more ifconfig -arp needed. Works like a charm + under FreeBSD now :). + +commit 0a3c8cefd4a154948799baaaa246cf0eba050eff +Author: Guus Sliepen +Date: Fri Jun 1 08:02:09 2001 +0000 + + Fix subnet_lookup() for overlapping subnets. Needs rethinking. + +commit 7db1b999c82611d6c68a5d79b4754db19669d5c6 +Author: Guus Sliepen +Date: Mon May 28 08:56:57 2001 +0000 + + Make sure Solaris is happy too. + +commit 65247c063b36a76dd68156fe17b017c7460d982f +Author: Guus Sliepen +Date: Mon May 28 08:21:43 2001 +0000 + + Small fixes to allow correct compilation under FreeBSD (tested with 4.3) + +commit 4e959ee40542733e647c36831c1fc87ed8098233 +Author: Ivo Timmermans +Date: Sat May 26 09:35:28 2001 +0000 + + Don't distribute autogen.sh in a release + +commit 514f8f579d5c0608aee8ca4a43d7414ecee5c11c +Author: Ivo Timmermans +Date: Sat May 26 09:35:00 2001 +0000 + + Changed version number to 1.0-cvs + +commit 20c2b62b1802390c0f5a1757641a0a1cea8103a8 +Author: Ivo Timmermans +Date: Sat May 26 09:34:11 2001 +0000 + + New make target: `make release' + +commit 8d307c2fbf2c20eb53909f74c81e03db838fb55e +Author: Guus Sliepen +Date: Fri May 25 18:57:37 2001 +0000 + + Fix sample configuration to show keys in PEM format and correct tapdevice. + +commit e12d41f39d8dd1cd30058d08effd2e5b66cdd4fd +Author: Guus Sliepen +Date: Fri May 25 13:24:34 2001 +0000 + + Documents are merged. Now we only need to check the ports and the TCPonly + and IndirectData options. + +commit f0c64a3dac3b0469ea05fa5d44a1e7bdbfa64900 +Author: Guus Sliepen +Date: Fri May 25 12:45:37 2001 +0000 + + Merged PROTOCOL, NETWORK and SECURITY2 with the texinfo manual. + +commit fcf869cd4250a240ea8d443f70fa373e4fbacf07 +Author: Guus Sliepen +Date: Fri May 25 11:54:28 2001 +0000 + + TCPonly now works (in a relatively clean way too). + +commit a5e2ae6b2b2e1629cf05bb2a57df75f13c0f120a +Author: Guus Sliepen +Date: Fri May 25 10:08:11 2001 +0000 + + With recent kernels the tun device file is located in /dev/net. + +commit 6e09c2a99c8ac3c1391f4f2eee16d6c235c10e90 +Author: Guus Sliepen +Date: Fri May 25 10:06:13 2001 +0000 + + Small corrections to the manuals. + +commit 4dee76522e177dcb4af5d6d844a5f3b74070e4b7 +Author: Guus Sliepen +Date: Fri May 25 08:36:11 2001 +0000 + + Small fixes: + + - Fix compiler warnings (one was a real (but harmless) bug) + - Don't send PING packets if there is UDP traffic + - Correctly terminate strings containing salt for PING/PONG packets + +commit bfc5d6014e3c1563f7b6a2f10698e9ba23ba3e96 +Author: Guus Sliepen +Date: Thu May 24 21:52:26 2001 +0000 + + Only send key_changed if it was previously requested. + +commit 1a248fd5bd5aa24fa0f6a2c395f05dd569f0898d +Author: Guus Sliepen +Date: Thu May 24 21:32:30 2001 +0000 + + All features for 1.0 are implemented now, we just have to check the + FreeBSD and Solaris ports and merge some docs. + +commit 58893f0875369aafff8481825af271683c975a2a +Author: Guus Sliepen +Date: Thu May 24 21:30:36 2001 +0000 + + Since this is incompatible with some earlier versions, PROT_CURRENT is + increased. + +commit d1b597758eab68bb80d97855f25cb6dda55eeb0b +Author: Guus Sliepen +Date: Thu May 24 21:29:09 2001 +0000 + + Add randomness to PING/PONG packets to prevent crypto attacks on quiet + tunnels. + +commit 4493b0650bd487990ca9d2802496ad0ee7c06247 +Author: Guus Sliepen +Date: Thu May 24 20:40:13 2001 +0000 + + Changed URL from kernelnotes.org to linuxdoc.org. + +commit 3360c6270bcc19a8b3d81da185266fc33b5c5421 +Author: Guus Sliepen +Date: Thu May 24 20:24:12 2001 +0000 + + More revisions to the documentation: + + - Removed cruft + - Reordered some sections to make it more logical for the beginner + - Added small examples and hints about configuration files + +commit 6f7f8659a2048fd6d616f4286ccdd0e661084493 +Author: Guus Sliepen +Date: Sat May 19 15:50:51 2001 +0000 + + - Make sure correct information is supplied for both old kernels (with + ethertap) and for new kernels (with TUN/TAP driver). + - Revised example configuration and made it conform to latest (CVS) version of + tinc. + +commit e4f3d93ec62871d1ae11b460627aef0da1b23cd2 +Author: Guus Sliepen +Date: Mon May 7 19:08:46 2001 +0000 + + - s/ip_t/ipv4_t/g + - Add "salt" to the beginning of UDP packets. Replaces length field which + is not useful anyway. + +commit a26081467c197cc6b26a0c36c4508361b242fc85 +Author: Guus Sliepen +Date: Fri May 4 18:45:02 2001 +0000 + + Correctly cycle through ConnectTo variables. + +commit 80b4a851a6b62cbbf503c2225f93305966f058c0 +Author: Guus Sliepen +Date: Fri Apr 13 10:30:04 2001 +0000 + + Depend on new ssl package and install alias for universal TUN/TAP module. + +commit 156ec676525ed789364b7a77926dd0717d0cf5d7 +Author: Guus Sliepen +Date: Tue Mar 13 21:33:31 2001 +0000 + + Check indirectdata option before forwarding certain requests. + +commit c426e981eeaed3fa4801221720ee8f74d40e9223 +Author: Guus Sliepen +Date: Tue Mar 13 21:32:24 2001 +0000 + + Ignore alarm signals if we do not need to respond to them. + +commit b413257e10ae0645da43583dd8f84a1f74df5bd7 +Author: Guus Sliepen +Date: Tue Mar 13 09:55:14 2001 +0000 + + Fixed bug in setup_signals() that would make tinc die when unexpected + signals were caught. + +commit f1a082823c48d00171b814f7e14e07e6dd4632fb +Author: Guus Sliepen +Date: Mon Mar 12 23:58:19 2001 +0000 + + Fixed a race condition triggered by receive_meta() and the new + authentication scheme. + +commit f4887b981f109fc4264f50170b2d12c4033bf5e9 +Author: Guus Sliepen +Date: Sun Mar 4 14:00:24 2001 +0000 + + Added a description of what is going on in net.c and route.c, and how + packets flow through tinc. + +commit 9d5c9bf6ba74e4e8bbd12b97fdda6c665155fec6 +Author: Guus Sliepen +Date: Sun Mar 4 13:59:53 2001 +0000 + + Updated translation. + +commit 34f9e6cf2d6d2b81eb63f9f28963b447a2157740 +Author: Guus Sliepen +Date: Sun Mar 4 13:59:32 2001 +0000 + + - route.c is now used to determine destination + - flags are removed, since they were not used at all. Use options instead. + - indirectdata works now, tcponly almost... + - made functions that don't return useful information void + +commit d2a54597e029f9d4f7bd29837be1be33909d78b1 +Author: Guus Sliepen +Date: Fri Mar 2 11:25:56 2001 +0000 + + Added explaination of our key exchange using RSA encryption. + +commit 125c4978812cffa5154ce5378a276f43f78417d8 +Author: Guus Sliepen +Date: Thu Mar 1 21:32:04 2001 +0000 + + Various small fixes. + +commit 099cc867c1a0831add7f1b4046f22ad6bfa5a1ef +Author: Guus Sliepen +Date: Tue Feb 27 16:50:29 2001 +0000 + + Removed compiler warning. + +commit 4fa12eb85d72f039df5004abc201f01f5573c2e4 +Author: Guus Sliepen +Date: Tue Feb 27 16:37:31 2001 +0000 + + Removed lots of compiler warnings. + +commit 173d606514d82fc5ae7895a178238d0abcaf6606 +Author: Guus Sliepen +Date: Tue Feb 27 16:17:04 2001 +0000 + + - Fixed Interface option (untested) + - Removed error handling for non-critical socket options + - Added TCP_NODELAY and IPTOS_LOWDELAY options for meta sockets. + +commit fb4ba9b265666d9949b03209a3ff52ff1263226b +Author: Ivo Timmermans +Date: Tue Feb 27 16:15:14 2001 +0000 + + Authentication done + +commit 24fa68585923d2b52718390f3f38d1aaacef12f0 +Author: Guus Sliepen +Date: Tue Feb 27 15:33:39 2001 +0000 + + Don't forget to reconnect if outgoing connection fails during + authentication. + +commit 34b7a876c3583f7a34585cff6a694bc9e35cdc87 +Author: Guus Sliepen +Date: Mon Feb 26 11:37:20 2001 +0000 + + - Make sure METAKEY is smaller than the modulus of the RSA key + - Get symmetric key from the least significant bytes of the RSA message + +commit 4b0ad4d97abd3643c44f45841d52f3000a34ba60 +Author: Guus Sliepen +Date: Sun Feb 25 20:17:46 2001 +0000 + + Added process.c to the translated files. + +commit 82455be966027a087a2ac23e3464594c81d7b111 +Author: Guus Sliepen +Date: Sun Feb 25 19:09:45 2001 +0000 + + Implemented new authentication scheme from doc/SECURITY2. + +commit 54881faf6fdbf04fb5ee56b7809439fbc50c65cb +Author: Guus Sliepen +Date: Sun Feb 25 16:34:19 2001 +0000 + + Encrypt network packets in CBC mode instead of CFB mode. + (This breaks compatibility with all previous versions!) + +commit 9de5787574b21e94c80ddc60def2b3e514aff755 +Author: Guus Sliepen +Date: Sun Feb 25 16:04:00 2001 +0000 + + Copy packets before putting them in the queue. + +commit 38adc479a44b64afcb220cd757f77ab105cb9bcd +Author: Guus Sliepen +Date: Sun Feb 25 15:34:50 2001 +0000 + + Free node->data and node, not node->data twice. + +commit e250d64300cea2a83059866e7cbabcb33684160e +Author: Guus Sliepen +Date: Sun Feb 25 14:51:42 2001 +0000 + + Add missing \n. + +commit 153fc35e57c0104aa4ea9103bcdbca3665e4934c +Author: Guus Sliepen +Date: Sun Feb 25 11:09:29 2001 +0000 + + Corrected check for errors after read() calls. + +commit 0b0c2a372ff5d11f73af172e07a93b2656374a42 +Author: Wessel Dankers +Date: Tue Feb 20 21:53:18 2001 +0000 + + Important bugfix in avl_insert_before() and avl_insert_after() + +commit 11f8465dd9a4f81b43a31f1cb6a7fc2d76bb7838 +Author: Ivo Timmermans +Date: Sun Feb 18 02:13:26 2001 +0000 + + tinc_TUNTAP now substitutes the values outside the AC_CACHE_CHECK + block. configure should now correctly set HAVE_TUNTAP. + +commit bb0870498037565209e24fbb2ffa07b815350a0b +Author: Guus Sliepen +Date: Tue Feb 13 09:54:29 2001 +0000 + + Added description of the proposed new authentication scheme. + +commit cebb6efeb0f39bf05ca7836b7a393c8385b49335 +Author: Ivo Timmermans +Date: Sun Feb 11 11:55:28 2001 +0000 + + More files to ignore in CVS + +commit 603781831f251d2e8111e8282d8e624b8e40b175 +Author: Guus Sliepen +Date: Sun Feb 11 11:50:09 2001 +0000 + + - Updated CVS_CREATED to remove intl/ directory and some other + autogenerated files. + - Checked if all INCLUDES/LIBS/etc directives inherit the global variables. + +commit 88dfdc9dbac3f5d0aa70b77509b4a87513433987 +Author: Guus Sliepen +Date: Sun Feb 11 11:46:14 2001 +0000 + + Ignore file for src/ + +commit ef0fc4f687fc25e97551e589941d6a2a2d8ade42 +Author: Guus Sliepen +Date: Sun Feb 11 11:44:32 2001 +0000 + + Added .cvsignore files to get rid of warnings and prevent autogenerated + files from being added accidentaly. + +commit f1cb3d8fa5f69840f353ca5a62f363dad47eb46f +Author: Guus Sliepen +Date: Tue Feb 6 10:42:27 2001 +0000 + + Removed another local definition of the variable "errno" + +commit 0f715887c617723e4b450083f8b77641f8b62e80 +Author: Guus Sliepen +Date: Tue Feb 6 10:13:44 2001 +0000 + + Updated dutch translation. + +commit 4bc394a3e29f2f90434bbbfc9f23d5587398471b +Author: Guus Sliepen +Date: Tue Feb 6 10:13:22 2001 +0000 + + Fix memory leak in avl_insert() if item was already inserted. + +commit f777c1807d663eaef3e36c395094451214886898 +Author: Guus Sliepen +Date: Tue Feb 6 10:12:51 2001 +0000 + + FreeBSD compile fixes (thanks to XeF4) + +commit bb4457d6caf6e424aeaf9b09222d4e62cab939da +Author: Ivo Timmermans +Date: Thu Jan 18 13:02:34 2001 +0000 + + Unpack sample-config.tar.gz when installing + +commit fe61e1ffef186aa509a50be3be83955fe1cbb514 +Author: Ivo Timmermans +Date: Thu Jan 18 13:01:42 2001 +0000 + + Distribute the sample config as a .tar.gz + +commit a73ec9caa45bda7738376a610030c8ba9b934445 +Author: Ivo Timmermans +Date: Thu Jan 18 13:00:57 2001 +0000 + + Fixed some errors + +commit b33c5f6640e63cc4cd35285367bcb2827b732229 +Author: Ivo Timmermans +Date: Wed Jan 17 16:24:24 2001 +0000 + + First try to create a graphical frontend for tinc configuration + +commit 6bc77a7710adcbc33331c45e1b6adf7089a42075 +Author: Ivo Timmermans +Date: Wed Jan 17 01:48:44 2001 +0000 + + Get the PO files up to date with the current source + +commit 664f7e5c0b9056d88e2b63b3626ea33c4894387b +Author: Ivo Timmermans +Date: Wed Jan 17 01:47:39 2001 +0000 + + Get the Debian changelog up to date + +commit 1d898e00a964ef922617683a1d29ff24e56ed8ff +Author: Ivo Timmermans +Date: Wed Jan 17 01:40:46 2001 +0000 + + Merged documentation with various updates I had lying around + +commit 457c6fa7b63a7f2971314d8d63af71c880ec6f53 +Author: Ivo Timmermans +Date: Wed Jan 17 01:34:08 2001 +0000 + + Second draft of the release notes + +commit b236ddb1df16f8eb025d485b75153c4f25f4afc6 +Author: Ivo Timmermans +Date: Wed Jan 17 01:31:56 2001 +0000 + + Change version to 1.0pre4 + +commit a893b05cb017c04871c2faf4099f104985f4ad75 +Author: Ivo Timmermans +Date: Wed Jan 17 01:30:32 2001 +0000 + + Set Architecture to `any' + +commit 54e19d34663cfe4af05e9e1dac94f76e39858f18 +Author: Ivo Timmermans +Date: Wed Jan 17 01:30:05 2001 +0000 + + Fix error reporting of read_config + +commit a56df1e06be3f47a775919e564c147687e961b5d +Author: Guus Sliepen +Date: Sat Jan 13 16:36:23 2001 +0000 + + - Allow ASN1 style keys to be in the config files. + Note: tinc ignores private key in the main config file, tinc.conf, + because it should really be in a separate file. + - When generating new keys, check if name is known and by default append + the public key to the host configuration file (otherwise rsa_key.pub). + +commit 44c85ab07ed07165b80140da4e2910ca51fa8887 +Author: Guus Sliepen +Date: Sat Jan 13 14:56:46 2001 +0000 + + - Copy entire sample-config directory to /etc/tinc/example upon installing. + +commit b195e8815f0abb2c5527119221886b524d719019 +Author: Guus Sliepen +Date: Sat Jan 13 14:38:18 2001 +0000 + + Added sample configuration directory. + +commit d646f4e094b63720f97bfd37bb3489bd9d6231a0 +Author: Guus Sliepen +Date: Thu Jan 11 11:19:08 2001 +0000 + + - Only send out DEL_HOSTs for hosts with a meta connection + +commit c8beaf35ee923c209ee23bedcb3dc892d2c2dae3 +Author: Guus Sliepen +Date: Mon Jan 8 21:32:30 2001 +0000 + + - Cleaned up subnet_t + +commit e5e1c20a99b0d72792f28e9a075a9f4a7e8b2c95 +Author: Guus Sliepen +Date: Mon Jan 8 21:32:00 2001 +0000 + + - Sign was wrong in search_closest_smaller/greater + +commit 11f3e9d138daf6b726631cc124b14d66dfa4d1f7 +Author: Guus Sliepen +Date: Mon Jan 8 20:35:30 2001 +0000 + + - Squashed another nasty bug. + +commit 447a43d63960802a7a29201c512246be11eb9c94 +Author: Guus Sliepen +Date: Sun Jan 7 20:19:35 2001 +0000 + + - Added indirectdata and tcponly functionality. + +commit 7cd2baedc6027ef6a5b941342bc6d3931d7220ba +Author: Guus Sliepen +Date: Sun Jan 7 20:19:08 2001 +0000 + + - Fixed IPv6 subnet lookup routine. + +commit d3f889c8076dff9c00ebfe1459cb36425f8da41d +Author: Guus Sliepen +Date: Sun Jan 7 17:09:07 2001 +0000 + + - It's 2001, all copyright notices are updated. + +commit 96b6f958bc733c3963dd164caacd42513be47a86 +Author: Guus Sliepen +Date: Sun Jan 7 17:08:03 2001 +0000 + + - Description of protocol and authentication updated. + +commit 7109526c6789c73a18bbe6b228ca35f0374c8d36 +Author: Guus Sliepen +Date: Sun Jan 7 15:27:30 2001 +0000 + + - Added header file for route.c. The routing routines in it are not used + yet, but have a look at the source for the ideas behind it. + +commit 07a08f5539f441e66946d1db1711dc584f8621c4 +Author: Guus Sliepen +Date: Sun Jan 7 15:25:49 2001 +0000 + + - Reinstated a queue for outgoing packets. + +commit 049ff67817e0db5afbba30930531d8ea3f7f2d18 +Author: Guus Sliepen +Date: Sun Jan 7 15:24:52 2001 +0000 + + - Changed list routines to give it the same look'n'feel as the rbl and + avl tree library. + +commit 8b4bc5b3a7e31c198c001610c99c2993e1612376 +Author: Guus Sliepen +Date: Sat Jan 6 20:43:03 2001 +0000 + + - Typo. + +commit 3d7289cf743f89cab4c71815482a4837a21f6703 +Author: Guus Sliepen +Date: Sat Jan 6 20:02:21 2001 +0000 + + - Updated texinfo manual. + +commit 0d99ae59bd7c640d396ce978045f0911567fb9bf +Author: Guus Sliepen +Date: Sat Jan 6 18:44:55 2001 +0000 + + - Updated manual pages. + +commit 90bf1b21fa7e94d73719da0593e7c0356d05e18f +Author: Guus Sliepen +Date: Sat Jan 6 18:21:17 2001 +0000 + + - Changed license of AVL tree library to GPL. + +commit f7bb205022e02c02c02733cd43544c231373115d +Author: Guus Sliepen +Date: Sat Jan 6 18:03:41 2001 +0000 + + - Check and follow symlinks in is_safe_path + - By default write keys to tinc config directory + - Small fix in protocol.c + +commit 1398edec37336853bfca6ea3dcca7c402f102ea2 +Author: Guus Sliepen +Date: Sat Jan 6 16:51:14 2001 +0000 + + - Updated dutch translation. + +commit e924096f62655d711cd2d114a8d1ef0fecbb593b +Author: Guus Sliepen +Date: Fri Jan 5 23:53:53 2001 +0000 + + - Let user choose whether keys are in the config files or separate + - Use AVL trees instead of RBL trees + - Fixed a lot of annoying subtle bugs! Thanks to gdb... + +commit 052fbc0bdf36e0dbe2a0867ce770d426c9a44841 +Author: Guus Sliepen +Date: Fri Jan 5 23:51:41 2001 +0000 + + - Doubled size of trace buffer for easier debugging. + +commit 77509da76c61b881c9967bfb7cdafeaf6b56eb6d +Author: Guus Sliepen +Date: Fri Jan 5 23:50:56 2001 +0000 + + - AVL tree routines: faster than RBL, and also more stable. + +commit e1707f7739f450c729e26b921e459d5da07602f9 +Author: Guus Sliepen +Date: Fri Dec 22 21:34:24 2000 +0000 + + - Don't even think about using sscanf with %as anymore + - Allow keys to be inside the config files or in a seperate file + - Small fixes + +commit ecae72de94222302aa326888f70cfacdbd775b23 +Author: Ivo Timmermans +Date: Fri Dec 22 17:15:26 2000 +0000 + + Added lint target, requires lclint. + +commit c5fac35c6ce9b9fcc47508810d69aeab83d08c25 +Author: Ivo Timmermans +Date: Fri Dec 22 17:10:25 2000 +0000 + + Forget router.c + +commit 37544990e96fe5ea161e644f6417f505d666cd00 +Author: Ivo Timmermans +Date: Fri Dec 22 16:59:16 2000 +0000 + + Include autogen.sh (needed for the Debian package). + +commit 8a4daf4ea7758270a47a358f43ad97a64eb1c3ff +Author: Ivo Timmermans +Date: Fri Dec 22 16:54:56 2000 +0000 + + Various small changes. + +commit e469fca4d78e9d23698fe1e6b29b232198cc499e +Author: Ivo Timmermans +Date: Wed Dec 6 13:33:49 2000 +0000 + + Re-introduced MyVirtualIP and VpnMask, as dummy options. + +commit e50e4a54d6b40b988041a7e9bfdfbf708657f3a5 +Author: Ivo Timmermans +Date: Tue Dec 5 09:04:32 2000 +0000 + + Give a warning about having to re-create the keys + +commit 4610d98c04641fce65747e07d65cbdd03fb6fe30 +Author: Ivo Timmermans +Date: Tue Dec 5 09:03:41 2000 +0000 + + Ported it back to /bin/sh. + +commit 1e38dcc3fa6c0da2fdb21f83a588338fa8a41818 +Author: Ivo Timmermans +Date: Tue Dec 5 09:03:19 2000 +0000 + + Install a file in /etc/modutils/tinc, containing all necessary aliases + and options for kernel modules. + +commit 6327f32f43dc9109fad9952fd50a23876d0acaf0 +Author: Ivo Timmermans +Date: Tue Dec 5 08:59:30 2000 +0000 + + Tiny bits of code beautifying + +commit 9267bed9f516244b00d5c86c8dae44b7eb78a96c +Author: Ivo Timmermans +Date: Tue Dec 5 08:56:44 2000 +0000 + + Oops. I did some VERY wrong things with readline(). Fixed now. + +commit 6ddc9109d7313503895227c7876309b36681393d +Author: Ivo Timmermans +Date: Tue Dec 5 08:54:22 2000 +0000 + + Massive long awaited documentation update. It's not finished yet, + most notably the example configuration is still old. + +commit bc22ee16e6903d2caf9d22afa85020d1e3e10b56 +Author: Ivo Timmermans +Date: Sun Dec 3 12:23:06 2000 +0000 + + Option -d accepts an argument to set the debug level immediately. + +commit 01d23601a273d128ebfd13c2ffa10892e9b13094 +Author: Ivo Timmermans +Date: Sun Dec 3 12:22:19 2000 +0000 + + Sort configuration directives + +commit d6b77e18b58ad8f9bcd9b60864b95cd2a74482c5 +Author: Ivo Timmermans +Date: Sun Dec 3 12:21:20 2000 +0000 + + Added documentation merger + +commit e985f6d3cdbebdeb17333bbd3d3c20d4618128cf +Author: Ivo Timmermans +Date: Fri Dec 1 13:46:26 2000 +0000 + + Include COPYING.README in the distribution. + +commit 94192b3db10fe51ce45fa569ec068423a4491b0b +Author: Ivo Timmermans +Date: Fri Dec 1 13:45:46 2000 +0000 + + Stated that distributing executables linked with OpenSSL is permitted + provided that all other requirements of the GPL are complied with. + +commit 52575a573c1d87ee125a54a2e0b4044698904cae +Author: Ivo Timmermans +Date: Fri Dec 1 12:38:42 2000 +0000 + + Use buffer instead of line in read_config_file(), line may be assigned + NULL, so buffer always holds the pointer to the allocated space. + +commit ab33c1aa6081f07333bf1de00e4036dd2b4628a6 +Author: Ivo Timmermans +Date: Fri Dec 1 12:36:36 2000 +0000 + + readline() accepts two extra parameters, buf and buflen, to avoid + mallocing and freeing for every line that is read. + +commit 6c56a8416eded8f19076a619a27ad7b153dd91f3 +Author: Ivo Timmermans +Date: Thu Nov 30 23:44:07 2000 +0000 + + Tagged `Storing private key in separate file' as done. + +commit 8fe83e98da043e930a88ddd6b2de6c14aa791335 +Author: Ivo Timmermans +Date: Thu Nov 30 23:39:55 2000 +0000 + + All full stops have two spaces after them. (Silly commit, I know.) + +commit a0f7af3ed79c55d9680cbb0a569b3c8987581d43 +Author: Ivo Timmermans +Date: Thu Nov 30 23:18:21 2000 +0000 + + New function read_rsa_public_key(); + In net.c/setup_myself deleted old code to read the public key (which + is now implicitly read in together with the private key). + +commit 28deaeac14d619efb9830d03fd61dc7cca70a701 +Author: Ivo Timmermans +Date: Thu Nov 30 22:48:48 2000 +0000 + + Avoid printing duplicate messages from read_rsa_keys + +commit 2293304748f7e4e9a18ee848b8264bdecebae37f +Author: Ivo Timmermans +Date: Thu Nov 30 22:33:16 2000 +0000 + + Better error checking when reading the RSA private key. + +commit bf4e969899bb6cdeb05570d96a567c2833ac83bd +Author: Ivo Timmermans +Date: Thu Nov 30 22:32:14 2000 +0000 + + In readline(): initialise the line to zero length; + In read_config_file(): Test for EOF, and print the variable name that + caused an error. + +commit 113198d9c0b3be9904057673cfed165406803f86 +Author: Ivo Timmermans +Date: Thu Nov 30 21:11:03 2000 +0000 + + The file is safe if it doesn't exist. + +commit 09260b43d1ff037c22f86c82a6af830e9a6d6ae5 +Author: Ivo Timmermans +Date: Thu Nov 30 20:08:41 2000 +0000 + + Read the PEM file pointed to by the configuration directive + PrivateKey. This means thatt he meaning of this variable has changed, + it no longer should contain the private key directly. + + WARNING: This code is untested. + +commit 8ccb1ede92fbd55481fa2317c2450bb9dd94a180 +Author: Ivo Timmermans +Date: Thu Nov 30 00:24:13 2000 +0000 + + Implemented is_safe_path, and extended ask_and_safe_open. + + is_safe_path needs more work before it is useable. + +commit 75e3c296b4fa1eb02df2f5f84a1280e791f88603 +Author: Ivo Timmermans +Date: Wed Nov 29 15:22:04 2000 +0000 + + Updated Dutch translation + +commit d36da1948abdd27e9d0740c2baceb0bd155c18c6 +Author: Ivo Timmermans +Date: Wed Nov 29 14:30:07 2000 +0000 + + Also free the pointer returned by readline(). + +commit 9e55426d72fd77fda891edd0023dab2f9909639e +Author: Ivo Timmermans +Date: Wed Nov 29 14:27:24 2000 +0000 + + Use readline() in read_config_file() instead of fgets. + +commit 8ea23d9ec3f2fe0c113eac5caafb7c2bd03f3016 +Author: Ivo Timmermans +Date: Wed Nov 29 14:23:08 2000 +0000 + + xstrdup now takes a const pointer as an argument. + +commit 54ef13bf75a7a1e787716ce395ffe847fa74673f +Author: Ivo Timmermans +Date: Wed Nov 29 14:24:40 2000 +0000 + + Implemented a readline() function that will read an entire line into a + dynamically allocated buffer; + + Ask for a file name in ask_and_safe_open(). + +commit 9175d2048382c617a639fd3d437a9e06baa66d0f +Author: Ivo Timmermans +Date: Wed Nov 29 01:37:50 2000 +0000 + + Added a check for a scanf that knows about %as. + +commit 1ca04711aeab615161746c6bbb5d137388c73263 +Author: Ivo Timmermans +Date: Wed Nov 29 00:33:15 2000 +0000 + + Check for get_current_dir_name. There is a replacement function in + dropin.c. + +commit c94f7637427f4c89d56c41fe4c75f2970b664a63 +Author: Ivo Timmermans +Date: Tue Nov 28 23:23:41 2000 +0000 + + dropin.c/h contain a set of drop-in replacements for non-standard C + library functions (read: GNU extensions). + +commit 3ff76eb10acc55b6f269c1075de6bbaa5bc83516 +Author: Ivo Timmermans +Date: Tue Nov 28 23:12:57 2000 +0000 + + Save RSA public and private keys to a separate file, instead of + wanting to copy them into a configuration file. + +commit 4c502b005bfd24821e817c134e8a442a5f4606de +Author: Ivo Timmermans +Date: Tue Nov 28 08:59:27 2000 +0000 + + Use sigaction to set signal handlers, the previous commit (1.1.2.16) + already contained a large portion of what should have gone in this + one. + +commit e44dc004b3d1ce8f857971f479c917931eda7091 +Author: Ivo Timmermans +Date: Mon Nov 27 20:52:55 2000 +0000 + + Sort items to either 1.0 or future release goals. + +commit 699f3b4c93482055c0832c9a6b76dc0294967003 +Author: Ivo Timmermans +Date: Sun Nov 26 22:46:53 2000 +0000 + + Check for the function strsignal, and define it to "" if it is not + available. + +commit 67a4abda707b28b9c77cb35ff1e800e6a5b0991c +Author: Ivo Timmermans +Date: Sun Nov 26 22:42:34 2000 +0000 + + Give an error message if daemon() failed. + +commit 702e55306dfebe5c6f9a6587ed029c3bc3efbe8f +Author: Ivo Timmermans +Date: Sun Nov 26 22:32:52 2000 +0000 + + Updated Spanish translation, provided by Enrique Zanardi. + +commit 1eedf54681d4556c6874f7baee8e810cab867756 +Author: Guus Sliepen +Date: Sat Nov 25 13:33:33 2000 +0000 + + - Use only one socket for all UDP traffic (for compatibility) + - Write pidfile again after detaching + - Check OS (for handling FreeBSD/Solaris tun/tap stuff) + +commit 0806605ce383b7e89fa26eda56f8a5f3bbed9dd3 +Author: Guus Sliepen +Date: Fri Nov 24 23:30:50 2000 +0000 + + - Added daemon() replacement. + +commit cfb828784ebbcf4b3e40eb9bb351b6ed10a84b35 +Author: Guus Sliepen +Date: Fri Nov 24 23:14:52 2000 +0000 + + - Added Armijn to the list + +commit cf49b2c0647554613874cce495e4a7937a9f7863 +Author: Guus Sliepen +Date: Fri Nov 24 23:13:07 2000 +0000 + + Another big & bad commit: + - Added some extra search functions to rbl routines + - Fix subnet_lookup() + - Reorder some syslog messages to make more sense + - daemon() is back + - Don't let scripts execute in parallel (gives race conditions, and + anyway something MIGHT just be configured which is necessary for further + execution of tinc itself) + - Accidently merged check_child() with execute_script(). + - Small fixes + +commit 97c54ffb35312caf38034952b9ed2733f7e374f9 +Author: Ivo Timmermans +Date: Fri Nov 24 16:52:57 2000 +0000 + + Add default tinc-up and tinc-down scripts for a Debian system. These + do not yet work, it's just old code from init.d. + +commit b42c9abafdc102db0641f3d444bdb30fbc29140a +Author: Ivo Timmermans +Date: Fri Nov 24 14:15:20 2000 +0000 + + Call autogen.sh instead of configure alone; and make cvs-clean instead + of distclean. This way you can just cvs checkout && dpkg-buildpackage + in one go. + +commit edb9b4cad09855a9bb3c57c5d4b1b174fde1de6c +Author: Ivo Timmermans +Date: Fri Nov 24 14:13:51 2000 +0000 + + Explain how to tell configure where OpenSSL lives. + +commit 4cb4a7d298d560593f84d974bf77d0ee8a911a50 +Author: Ivo Timmermans +Date: Fri Nov 24 14:13:06 2000 +0000 + + Set errno to 0 before trying to kill the other process. + +commit ef88db63120503a8c9d34d86073795c99dedc3a9 +Author: Ivo Timmermans +Date: Fri Nov 24 14:12:31 2000 +0000 + + Alter CFLAGS, somehow INCLUDES doesn't propagate properly. Still + doesn't work exactly like it should, but getting there. + +commit b17822840150f5ba8cfb8e5a44fc10d66bd15a97 +Author: Ivo Timmermans +Date: Fri Nov 24 14:04:49 2000 +0000 + + Set CFLAGS to -O2 -Wall when running configure + +commit eb36b0c1ef7b5ed8ff59c3b41cbb361ed37d5f01 +Author: Ivo Timmermans +Date: Fri Nov 24 14:00:32 2000 +0000 + + Use cvs2cl instead of rcs2log to generate the ChangeLog. + +commit 2f37f2bd8ab6b89eb6b6c2b4bdd6ffe449b1aa98 +Author: Ivo Timmermans +Date: Fri Nov 24 14:03:13 2000 +0000 + + Set localstatedir to /var + +commit 31aa4298463498cbb755db747e901e4269cd1ef6 +Author: Ivo Timmermans +Date: Fri Nov 24 13:33:48 2000 +0000 + + Do not attempt to retreive ChangeLog information only from the CABAL + tag, it doesn't work anyway. + +commit f2dd7bb42c1f4bfa708f542e430f4a56fd43e74f +Author: Ivo Timmermans +Date: Fri Nov 24 13:32:26 2000 +0000 + + Do not check for the daemon() system call + +commit b0ff879e7c68edd447328f3d806c1ad9e336fece +Author: Ivo Timmermans +Date: Fri Nov 24 12:44:39 2000 +0000 + + Do not use the C library's daemon() call. + +commit cebcf78b9a24f70902009bea23514e55d84b096a +Author: Guus Sliepen +Date: Thu Nov 23 09:30:33 2000 +0000 + + - Don't link with -ldl anymore + - Let's not use bash' built-in pwd function anymore... it does not follow + symlinks. + +commit 7aa7895629d72391eccfcb23f3cb6290a9e3abc3 +Author: Guus Sliepen +Date: Wed Nov 22 23:09:38 2000 +0000 + + - #include instead of + +commit dac256505e1af78505c9f905bd55c11d4b87345c +Author: Guus Sliepen +Date: Wed Nov 22 22:18:03 2000 +0000 + + - Fixed all (except 2) compiler warnings gcc -Wall gave. + +commit 6f373e690236334d8f8333710b61f97ccad54bf1 +Author: Guus Sliepen +Date: Wed Nov 22 22:05:37 2000 +0000 + + - More porting to FreeBSD and Solaris. + +commit 5971e352dae2cf189f1cbdeacffa4ccdd1e98304 +Author: Guus Sliepen +Date: Wed Nov 22 20:25:27 2000 +0000 + + - Work with the correct key buffer in ans_key_h + +commit a07602c4fddfca9894f1d738959ae359695f5bf9 +Author: Guus Sliepen +Date: Wed Nov 22 19:55:53 2000 +0000 + + - No more %as. + +commit 394ed3fb174bb629bfb4b441fe58842562f955de +Author: Guus Sliepen +Date: Wed Nov 22 19:14:09 2000 +0000 + + - Write pidfile AFTER detaching... + - Minor cleanups + +commit f8b4a000d008082e5c7e511a49318b8dea8fd08d +Author: Guus Sliepen +Date: Wed Nov 22 18:54:08 2000 +0000 + + - Cleaned up and checked for some more NULL pointers in rbl.c + - Two connection lists: one for incoming connections, sorted on ip/port, + one for connections whose identity we know, sorted on id ofcourse... + +commit 785684f0ec5c9250788b4b32c0eab3f358c9db61 +Author: Ivo Timmermans +Date: Wed Nov 22 17:49:16 2000 +0000 + + Declare fd. + +commit e42255ae1374fe65e92de72de4508a84bdb91fa1 +Author: Ivo Timmermans +Date: Wed Nov 22 17:48:15 2000 +0000 + + Add more checks to ensure that filedescriptors are right in + _execute_script(). + +commit 2ed68134047a19e708c2a2af32c58968835a7043 +Author: Ivo Timmermans +Date: Wed Nov 22 16:19:07 2000 +0000 + + Honor the --localstatedir option to configure, instead of hardcoded /var. + +commit 9e9e1925b901dff87518f0e1534a33e48eab8303 +Author: Guus Sliepen +Date: Tue Nov 21 09:13:59 2000 +0000 + + - Check for NULL tree->delete callback + - Add xstrdup() function + +commit da9a1e8084a9b73306bdbc541ee8af938c3e7754 +Author: Guus Sliepen +Date: Mon Nov 20 23:29:47 2000 +0000 + + - More fixes. + +commit 3a6200c1e39b61b249db3d1f9bcffa77351863bd +Author: Guus Sliepen +Date: Mon Nov 20 22:13:14 2000 +0000 + + - Various small fixes. + +commit 06afd357b0cf4aab778b1ccabbd1be61a9500d10 +Author: Ivo Timmermans +Date: Mon Nov 20 19:56:01 2000 +0000 + + Get rid of all libtool references at once. libtool was only used by + libblowfish, which was superseded by openssl. + +commit 1857b3c97c261dda9978a67d07b315bb3ca68841 +Author: Guus Sliepen +Date: Mon Nov 20 19:41:13 2000 +0000 + + - Proper initialization of rbltree structures. + +commit 408ca91766088b6c2d38e198b0692bf394b41248 +Author: Guus Sliepen +Date: Mon Nov 20 19:12:17 2000 +0000 + + - Integrate rbl trees into tinc. + +commit 9024e01ce649b89d304a4aa5b1d6ef0b56b5a12c +Author: Ivo Timmermans +Date: Mon Nov 20 18:06:17 2000 +0000 + + Also include process.h + +commit 3cc063d23a6e3a23fd01f03b0bc99825c2b13e16 +Author: Ivo Timmermans +Date: Mon Nov 20 18:05:34 2000 +0000 + + More function and header checks + +commit 59aa15d3d1db4e948113f202dd2183f4bb23970d +Author: Ivo Timmermans +Date: Mon Nov 20 18:02:15 2000 +0000 + + Added this release + +commit 8f273f0ee265c75dd8eea65b2f1cd60a79691cd6 +Author: Guus Sliepen +Date: Sun Nov 19 22:12:46 2000 +0000 + + - Small fixes + +commit cc7c078774db955cece9b263022e6c1ca955fc10 +Author: Guus Sliepen +Date: Sun Nov 19 11:05:59 2000 +0000 + + - Deletion also works now. + +commit 3526f1e151b7a189f075d88c9d88cacaece31d02 +Author: Guus Sliepen +Date: Sun Nov 19 02:04:29 2000 +0000 + + - Fixed a lot of small things. Tested everything except deletions. + +commit 4f68e5b6133480478edba0959cb87d4eb149a8e7 +Author: Guus Sliepen +Date: Sat Nov 18 23:22:44 2000 +0000 + + - Fix tree head/tail upon insertion + +commit 880cd6f1a94ef76ebebc5bd96dd26d62e3d829f4 +Author: Guus Sliepen +Date: Sat Nov 18 23:21:01 2000 +0000 + + - Implemented deletions + - Added rbl_foreach() function + +commit 00e5d572621ad5f0263999dbfbfcb11e023bf48b +Author: Guus Sliepen +Date: Sat Nov 18 18:14:57 2000 +0000 + + - Fixed searching + - Insertion implemented + +commit 7fcc0c6415488ed6ce0089a67ab7cfdd5d0d83ca +Author: Guus Sliepen +Date: Fri Nov 17 10:03:02 2000 +0000 + + - Removed stray @INCLUDE@ (how did that get there?) + - Use 0 instead of FALSE + +commit 44cbd13e5248880b074b5068df14a4634204a1d3 +Author: Guus Sliepen +Date: Fri Nov 17 00:56:49 2000 +0000 + + - Simplified do_detach + +commit 2626c641aa714a8d776f1bb16340586d935aa6b1 +Author: Ivo Timmermans +Date: Thu Nov 16 22:13:09 2000 +0000 + + Use proper prototypes. + +commit 5d1145f2c4b3b8261ca0aa0e89a2daf321640f0b +Author: Ivo Timmermans +Date: Thu Nov 16 22:12:23 2000 +0000 + + Move more functions from tincd.c into process.c. + +commit 485f7a5043a4b3345bd02e5063502603550b4c76 +Author: Ivo Timmermans +Date: Thu Nov 16 22:11:40 2000 +0000 + + Delete struct ifr + +commit 30f34015ee11bbe1106c07e381288a702f12dac5 +Author: Ivo Timmermans +Date: Thu Nov 16 18:06:39 2000 +0000 + + New function: xmalloc_and_zero, which initialises the allocated memory + to all zeroes. + +commit 2764532ea72200d0a27ad2d79e6e299c00c62404 +Author: Ivo Timmermans +Date: Thu Nov 16 17:54:29 2000 +0000 + + Move all process-related functions into process.c. + +commit aa755206da4bcce3261ecd5dbfa41570a0155c73 +Author: Guus Sliepen +Date: Thu Nov 16 09:18:38 2000 +0000 + + - Added balanced tree management stuff as well. (It is not finished yet.) + +commit 7f87c3d9134612041d56180ea7fc3e6c37991f6b +Author: Ivo Timmermans +Date: Wed Nov 15 22:07:36 2000 +0000 + + Keep a list of running children, and in each loop in main_loop(), + check if one has exited. + +commit d9ce5a7f3f5eddb193b6a9b5974c7c49eac41ea1 +Author: Ivo Timmermans +Date: Wed Nov 15 22:04:48 2000 +0000 + + List management and manipulation routines. + +commit e118ba0a648000c48d6a401c9b9249a844d6dbcf +Author: Guus Sliepen +Date: Wed Nov 15 13:33:27 2000 +0000 + + Porting to FreeBSD: + - Reorganized and added some #includes + +commit 596e248bc588323cc7ee751286dbcaf677b5c653 +Author: Ivo Timmermans +Date: Wed Nov 15 01:28:21 2000 +0000 + + Let the output from an executed script in execute_script() go to + syslog, with proper error detection. + +commit bb2495e569fb161b42efd633eb1c471b8222b1fb +Author: Ivo Timmermans +Date: Wed Nov 15 01:06:13 2000 +0000 + + Use the HAVE_OPENSSL_xxx_H defined from m4/openssl.m4 during + configure. + +commit 6fb4a5b6be5628ece9b391b46e7858fdf5957a80 +Author: Ivo Timmermans +Date: Wed Nov 15 01:02:30 2000 +0000 + + Also check for sha.h. + +commit 8eb60d0ccde2f1de6fd917db7300e537f271783e +Author: Ivo Timmermans +Date: Wed Nov 15 00:57:26 2000 +0000 + + Also check for rand.h and err.h. If any of these files does not + exist, try the next alternative path. + +commit c5c8e99afd3fae3868f20b5c7a4f8754498b39ad +Author: Ivo Timmermans +Date: Tue Nov 14 23:18:19 2000 +0000 + + Get rid of the annoying empty line + +commit c467ee02d3ef8bed7ec2cc52cb1527ec60cdc93a +Author: Ivo Timmermans +Date: Tue Nov 14 23:02:08 2000 +0000 + + Oops, small error. + +commit 9ddb37cee0f754ef88a55f692a508010fe18c782 +Author: Ivo Timmermans +Date: Tue Nov 14 22:57:19 2000 +0000 + + Better checks for OpenSSL. I think it can now detect almost all conceivable installations. + +commit 72c3776d6ac103fa25d216c42847ecba3a4f58e5 +Author: Ivo Timmermans +Date: Mon Nov 13 22:29:22 2000 +0000 + + Identify version as 1.0pre4-cvs + +commit 5344832be1126967ff340cf6bd270a377bb8e487 +Author: Ivo Timmermans +Date: Mon Nov 13 22:01:27 2000 +0000 + + Add a check for openssl that accepts explicit file locations. + +commit 5b74909ea070fbd482340dc42193e33366a9dddb +Author: Ivo Timmermans +Date: Thu Nov 9 21:33:18 2000 +0000 + + Add prototype for destroy_queue + +commit 6e27618708233998db7e5886ed9afaa21bb9d938 +Author: Ivo Timmermans +Date: Thu Nov 9 21:29:58 2000 +0000 + + Updates, updates + +commit a91eae538d9cff8aed399a175c0bbc7d744cd22a +Author: Ivo Timmermans +Date: Thu Nov 9 20:59:35 2000 +0000 + + Bop version number to 1.0pre3-1 + +commit e65a93053cca3f8aebf63094cf160835c3108e25 +Author: Ivo Timmermans +Date: Thu Nov 9 20:42:16 2000 +0000 + + Wrapped text to 70 (72?) columns for easy reading + +commit 4310b17be9cefcc1814ddef471e4c5cd8f9f867e +Author: Ivo Timmermans +Date: Thu Nov 9 20:41:13 2000 +0000 + + Final release notes added, also edited release notes for 1.0pre2 to what the announcement on the mailing list looked like. + +commit 16847ea255fa8a7c0ed922af80a2f36b7bdf4b3b +Author: Guus Sliepen +Date: Wed Nov 8 20:52:37 2000 +0000 + + - Make checkpoint tracing a compile time option (off by default) + +commit 55d7b5a2bb1df6f55f0a93e9cfed77c1da337588 +Author: Guus Sliepen +Date: Wed Nov 8 18:05:06 2000 +0000 + + - Add Jamie :) + +commit 5055e1dedc9fe984c497448c1b2ffc4afdf18aa3 +Author: Guus Sliepen +Date: Wed Nov 8 17:56:34 2000 +0000 + + - Applied Jamie Brigg's patch (close sockets after error) + +commit 74326df7adc514798565df0a8719421adbb5fef3 +Author: Guus Sliepen +Date: Wed Nov 8 00:20:06 2000 +0000 + + - Fixed --config + - Show warning when both netname and config directory are given. + +commit f8f1007bf469d44480d95d0d78ddc156d00e059f +Author: Guus Sliepen +Date: Wed Nov 8 00:10:50 2000 +0000 + + Porting to SunOS 5.8: + - More #includes Linux doesn't seem to need + - Don't do unsetenv() on SunOS + - Use a replacement asprintf() in case the OS doesn't support it + It now compiles properly under SunOS. + +commit 56bd0864e4c5680fee59af48228b1ec3fb97b57b +Author: Guus Sliepen +Date: Tue Nov 7 22:33:33 2000 +0000 + + Porting to SunOS 5.8: + - Include all header files necessary + - Check for flock() function + +commit 7d0f82bd4b7044a5151835e25e830fd28dfaaebd +Author: Guus Sliepen +Date: Tue Nov 7 22:02:14 2000 +0000 + + - Open UDP connection for all known hosts. Comments please. + +commit f95cc86d0c14ca4c47e5459af4bb6d1170baa9f5 +Author: Guus Sliepen +Date: Tue Nov 7 21:43:28 2000 +0000 + + Changed execution of tinc-up: + - Do not free() strings that have been putenv()d, see man page of the + latter. + - Do not set IFNAME anymore, it appears that the ioctl to get the name of + the interface does not work at all. Since it is set to NETNAME in case + of tun/tap and it is known beforehand in case of ethertap, there is no + need for it anyway... (though it would've simplified things). + +commit efc3a2a466937da942afc84dde080ba8b1731140 +Author: Ivo Timmermans +Date: Sun Nov 5 02:19:58 2000 +0000 + + Build-Depends on gettext + +commit 698191fd2f512f3618e2d60592fcd57cd750b965 +Author: Guus Sliepen +Date: Sat Nov 4 22:57:33 2000 +0000 + + - Prepended config_ to all configuration option names, because it confused + everything (including myself). + - Use connection oriented UDP sockets for both incoming and outgoing + packets. + +commit afc05797077641baa33b024ffeaafd6cad3ff7a7 +Author: Guus Sliepen +Date: Sat Nov 4 20:44:28 2000 +0000 + + - Simplified ping mechanism. + +commit 2191d894bfd615e8fa7857d031ea630edc12a854 +Author: Ivo Timmermans +Date: Sat Nov 4 17:29:45 2000 +0000 + + Build-depends on libtool + +commit 5019dd879177b5ab9413e5c0aa72a15d0e585acf +Author: Guus Sliepen +Date: Sat Nov 4 17:09:10 2000 +0000 + + - Check for packets that are looping back. + +commit 20dd5aff4d2898d8b59f371671cc110b870fa09c +Author: Ivo Timmermans +Date: Sat Nov 4 17:04:17 2000 +0000 + + Updated Dutch translation + +commit 3f177e9bf02b6121055414a2cc7fd3f4cff01cba +Author: Ivo Timmermans +Date: Sat Nov 4 17:01:55 2000 +0000 + + Add route.c to the list of source files. + +commit ac47586552710425417ed80878f8f853c313b421 +Author: Guus Sliepen +Date: Sat Nov 4 16:54:21 2000 +0000 + + - Forward keys in hex notation, not as binary data. + +commit 3f8f067e8b559366b9b41dee6a4312702c82042f +Author: Guus Sliepen +Date: Sat Nov 4 16:39:19 2000 +0000 + + - Don't forget to set packet cipher for added hosts. + +commit 433858d410c1fedf8d2a5f2b4ecd7c980dd79dd2 +Author: Guus Sliepen +Date: Sat Nov 4 15:34:07 2000 +0000 + + - connlist.c added to translation + +commit 15246df85d6171c92478541a835effb96d6085c4 +Author: Ivo Timmermans +Date: Sat Nov 4 15:32:05 2000 +0000 + + In execute_script: + - add an environment variable NETNAME. + - chdir to the configuration directory before execing the script. + +commit 69618c01385eb7226cd6eab0918d1f30b0ed6c66 +Author: Ivo Timmermans +Date: Sat Nov 4 15:18:58 2000 +0000 + + Do not include the passphrases directory + +commit 417f36a07990ff9bc7de7d4e63e57146bef0dd75 +Author: Guus Sliepen +Date: Sat Nov 4 15:17:02 2000 +0000 + + - Removed manpage for no longer existing genauth. + +commit 3d7189a444fe3efed58dc93a071129007041aebf +Author: Guus Sliepen +Date: Sat Nov 4 14:52:40 2000 +0000 + + - Resolve scriptname after fork() + +commit d38772ebc42f5ad1d946ee89d955f5d43bb2fe8c +Author: Ivo Timmermans +Date: Sat Nov 4 14:16:46 2000 +0000 + + Use putenv() instead of clumsy do-it-yourself in execute_script. + +commit f83803c1bf6557d5af93982e7cd987e151eba401 +Author: Ivo Timmermans +Date: Sat Nov 4 13:25:15 2000 +0000 + + Small change to the way the environment is copied. + +commit ed0bf283e37642f9f7673f664713a16d916bd70f +Author: Guus Sliepen +Date: Sat Nov 4 11:49:58 2000 +0000 + + - Removed even more warnings. + +commit dc699f8b1265deb7606d553e36326527dbd29746 +Author: Guus Sliepen +Date: Sat Nov 4 10:37:27 2000 +0000 + + - Removed unused MAC strip/add functions. + +commit 5065ea32c32e27478d93c00a1bba0c812b7a2b8c +Author: Ivo Timmermans +Date: Fri Nov 3 22:35:12 2000 +0000 + + Warnings removal pass: always include config.h first; add a few + prototypes in the header files. + + This also fixes a few lint errors/warnings. + +commit 73aa7fbf7e1b623398d1bc1493f567ce4d846f22 +Author: Ivo Timmermans +Date: Fri Nov 3 22:33:16 2000 +0000 + + Run the scripts tinc-up and tinc-down from a separate function, which + sets the environment as it should be and checks for errors. + +commit 4ad1e382d6f10acf94ce59d85b80925cee7553a6 +Author: Ivo Timmermans +Date: Fri Nov 3 22:31:55 2000 +0000 + + Save the environment on startup. + +commit 7612c6da3890ce5a0730e4dfde9d5ba07bdbf5b3 +Author: Ivo Timmermans +Date: Thu Nov 2 23:02:49 2000 +0000 + + Minor cosmetic change. + +commit 6a10e42f734e8bec9848a11e73bc2a8211a9f401 +Author: Ivo Timmermans +Date: Thu Nov 2 22:51:16 2000 +0000 + + - If necessary, patch po/Makefile.in from po-Makefile.in.in.diff to + get DESTDIR installation (required to get locales installed + correctly). + - Use dh_perl to get accurate perl dependencies. + +commit ef12849c1a03b3aaf85dd46786d6631f66b104bd +Author: Ivo Timmermans +Date: Thu Nov 2 22:11:18 2000 +0000 + + Oops, and include doc-base.tinc (new file). + +commit 5672ddd6cb9116420a1904f7741fdbed89c2ec54 +Author: Ivo Timmermans +Date: Thu Nov 2 22:10:09 2000 +0000 + + Don't include shlibs, as it no longer exists. + +commit 013fcb0e9f9c0222f4f63ddf42a2f25bfc4a5546 +Author: Ivo Timmermans +Date: Thu Nov 2 22:05:36 2000 +0000 + + Changed a few messages wrt. system calls; updated and changed the Dutch translation a bit. + +commit c444305c0bb965aa515a503406844ceeb483c285 +Author: Ivo Timmermans +Date: Thu Nov 2 21:43:03 2000 +0000 + + Mention fileutils, add a pointer to THANKS for more details + +commit 84c842def74c5d0e9c4a69e4f584fe9eb66eb728 +Author: Ivo Timmermans +Date: Thu Nov 2 21:41:53 2000 +0000 + + Change wsl to Wessel's name and email address in the ChangeLog creation + +commit 5b6815751e581bedd64bfc63aea5b42c746bbceb +Author: Ivo Timmermans +Date: Thu Nov 2 21:40:33 2000 +0000 + + More exhaustive list of changes - perhaps it can be worded differently? + +commit e954fc8f0c731e7116fd27f38c176b83cca519f7 +Author: Ivo Timmermans +Date: Thu Nov 2 21:39:57 2000 +0000 + + Changed `I' to `We' - small change, lots of difference :) + +commit 3db3a41667f90ce74bfd0197fc867cc71a087e50 +Author: Ivo Timmermans +Date: Thu Nov 2 21:38:55 2000 +0000 + + Only check for linux/if_tun.h once + +commit 1b11bcb0128ca65580cbf28ffb16078c81e6d678 +Author: Ivo Timmermans +Date: Thu Nov 2 21:34:45 2000 +0000 + + Added a perl example to turn an IP address into a MAC address. + +commit cadf81fe67aed424504758865c2ea2bb263c76fb +Author: Ivo Timmermans +Date: Thu Nov 2 21:26:51 2000 +0000 + + Do not include $(top_srcdir)/cipher, it does no longer exist. + +commit fd32d771a84765281ea4ab8a5d9dbf5cebfa2911 +Author: Ivo Timmermans +Date: Thu Nov 2 20:29:03 2000 +0000 + + - Synchronized changelog with the package's changelog. + - Changed maintainer email address. + - New file doc-base.tinc. + - Better Build-Depends and Depends lines. + +commit a13d9c9da7434154b33e666c2236844011b87d46 +Author: Ivo Timmermans +Date: Thu Nov 2 20:25:35 2000 +0000 + + This file is no longer needed. + +commit 59528ec892e8b9a599f2b39bf432a3d842e963fe +Author: Guus Sliepen +Date: Tue Oct 31 16:22:49 2000 +0000 + + Removed config file parsing and interface setup. This will be handled by + the tinc-up and tinc-down scripts from now on. + +commit af565d00220b7536b9987c48e2a71459b45027b4 +Author: Guus Sliepen +Date: Tue Oct 31 16:10:17 2000 +0000 + + - Update. + +commit b4c1d4e2d3287acd7ca438455c64e50a2828ad24 +Author: Guus Sliepen +Date: Mon Oct 30 10:19:06 2000 +0000 + + - Fixed some spelling mistakes and terminology here and there. + +commit 4811afa073c871f2a52dfd5139bd0171046365eb +Author: Guus Sliepen +Date: Mon Oct 30 00:22:54 2000 +0000 + + - Small cleanups + - Updated dutch translation + - Updated man pages + +commit b7d4d4c17712e0bb9ee8bd497a2f525b79d5f40d +Author: Guus Sliepen +Date: Sun Oct 29 22:55:15 2000 +0000 + + - Finishing touch: encrypt the meta connections + +commit ec12269355f7979fdc0783dc15d109832f1e83cd +Author: Guus Sliepen +Date: Sun Oct 29 22:10:44 2000 +0000 + + - Use CFB mode for encrypting packets: it works and we don't need padding. + +commit cea3d8f3056d3c6aaaef473443240b8470c8ea2d +Author: Guus Sliepen +Date: Sun Oct 29 10:39:08 2000 +0000 + + - Small fixes + - Do proper key exchange + - Encrypt packets - it works, but there is something wrong with the MAC + header after decryption... + +commit 8fa9bc017d89b53798903df3fa98311067d4de90 +Author: Guus Sliepen +Date: Sun Oct 29 09:19:27 2000 +0000 + + - Removed old encr stuff + +commit a26d371d0df3bee1bdc6e9d7046e949ee29e6de7 +Author: Guus Sliepen +Date: Sun Oct 29 02:07:41 2000 +0000 + + - Updated dutch translation. + - Shutdown properly. + +commit e8391bd49975aa29fa62d6ae1d2d2ee398e0eb3e +Author: Guus Sliepen +Date: Sun Oct 29 01:27:23 2000 +0000 + + - Moved connlist stuff to the proper header file. + +commit 2689690dc37c384c4a022d03ab80f2cfb7fb9553 +Author: Guus Sliepen +Date: Sun Oct 29 01:08:09 2000 +0000 + + - Enforce correct order of authentication requests + +commit 3b9802a542f1fa439321d3386763ec33989194b5 +Author: Guus Sliepen +Date: Sun Oct 29 00:46:43 2000 +0000 + + - Hit people who can't figure out subnet address/mask pairs with a + (clue)bat. + +commit 7398002ade1397bd857953f009f4aed65ffc9218 +Author: Guus Sliepen +Date: Sun Oct 29 00:24:31 2000 +0000 + + - Fixed ans_key_h + - Removed tapsubnet configuration option. + +commit 35932fe6c8cb481eb687f98424776ce429570c21 +Author: Guus Sliepen +Date: Sun Oct 29 00:02:20 2000 +0000 + + - Very big cleanup. + +commit db21f015161aac244ec5600c4d0ff685549892c2 +Author: Guus Sliepen +Date: Sat Oct 28 21:52:22 2000 +0000 + + - Override destination ethernet address on incoming packets with + FE:FD:00:00:00:00 + +commit 8738c007b15eea024bc4ca6ee0f972b2f5bf259f +Author: Guus Sliepen +Date: Sat Oct 28 21:25:21 2000 +0000 + + - Fixed offsets when reading/writing from/to tap device + +commit f25868fd2b58bc0b350a5cfaf342480f28f804cf +Author: Guus Sliepen +Date: Sat Oct 28 21:05:20 2000 +0000 + + - Lots of small fixes + - Exchange subnets on acknowledgement of connection + - Do proper lookup when incoming packets from tap + - off-by-a small number-error when reading/sending tap packets + +commit ba6b8005ebe3a53877590c242ff581dc5dee5eae +Author: Ivo Timmermans +Date: Sat Oct 28 19:34:53 2000 +0000 + + Skip the check for Linux kernel sources + +commit d47d5932a3bbc4940aa6453ebfe617ef330783c8 +Author: Guus Sliepen +Date: Sat Oct 28 16:41:40 2000 +0000 + + - Updated subnet list handling. Subnets are added to two lists now, the + owner's list and a global list. It is all fucked up but it probably + works anyway, good enough for pre3 :). + +commit 9c2f805255fa36b05e8fe9391f639581d938b653 +Author: Guus Sliepen +Date: Tue Oct 24 15:46:18 2000 +0000 + + - Lots of little stuff modified + - Succesfully reads in subnets from host config file now and adds them to + the list. + +commit 60401d99b18ae01d91ca65faf8d2b32fac2b4474 +Author: Ivo Timmermans +Date: Mon Oct 23 21:56:56 2000 +0000 + + Oops, echelon change committed to cabal... :) + +commit c46e84837d1c84a8590e0e3507227670368884a7 +Author: Guus Sliepen +Date: Mon Oct 23 13:52:54 2000 +0000 + + - route.c will contain the routing logic. + +commit 76d794eaf7c1664a47f4d0080fcd80e4a551740b +Author: Ivo Timmermans +Date: Sun Oct 22 13:47:41 2000 +0000 + + read_server_config: Check for result of read_config_file. + +commit 56d8e862409ae91c63a27968b01a48a94aafb205 +Author: Ivo Timmermans +Date: Sun Oct 22 13:37:15 2000 +0000 + + Include linux/sockios.h and net/if.h anyway, regardless of the value of HAVE_TUNTAP. + +commit 52b842f8076d507d3a6ea07045d085ae21d1aa10 +Author: Guus Sliepen +Date: Sat Oct 21 11:52:08 2000 +0000 + + - Fixed all debug levels. + - Seed PRNG before generating a challenge + - Strange thing in challenge decryption: it fails if first bit is set!? + +commit 73f7efddd723b25c1477ec1139dc7211307ff660 +Author: Guus Sliepen +Date: Fri Oct 20 19:46:58 2000 +0000 + + - Removed last reference to genauth from Makefile.am + - Tinc spawns tinc-up and tinc-down scripts which can be used to configure + the network device. The environment variable IFNAME is set to the name + of the interface. + +commit fba19c30c92d39e74f5fd5594053793b036f30f4 +Author: Guus Sliepen +Date: Fri Oct 20 16:49:20 2000 +0000 + + - Made Makefile.am stub for doc/es/ + - Merged genauth into tincd + - Updated dutch translation + +commit 97ec5685b92ea727fe8f8b4bb8cf289a20f8580b +Author: Ivo Timmermans +Date: Fri Oct 20 16:44:32 2000 +0000 + + Generalized list and hash handling functions + +commit 699e159a7a1711034f1d16d68ad1974a82e12dfc +Author: Ivo Timmermans +Date: Fri Oct 20 16:43:13 2000 +0000 + + New function: xalloc_and_zero() + +commit 4059151732afb7d8fb52121d80e54f2ee325d30e +Author: Ivo Timmermans +Date: Fri Oct 20 16:42:22 2000 +0000 + + Add all the new files to the sources list for the utility library + +commit 9f64499e40a95a8c05c82924219517aa017fc411 +Author: Guus Sliepen +Date: Fri Oct 20 15:34:38 2000 +0000 + + - tinc now really does public/private key encryption! It even works, whee! + +commit 71f05ff8956cb2e62181fcef763709b0de8faa68 +Author: Ivo Timmermans +Date: Thu Oct 19 20:56:49 2000 +0000 + + Generalized error handling functions + +commit 95f4e8620ef8e2cdec1cc3b2ccb8cc8e3ce94e40 +Author: Ivo Timmermans +Date: Thu Oct 19 20:39:04 2000 +0000 + + Add check for the syslog function + +commit 430e14162918864f9f18aad0ec0badc1ccc3e01f +Author: Ivo Timmermans +Date: Thu Oct 19 17:29:22 2000 +0000 + + Changed changelog + +commit d5fd1344e668da0bc8536e798f347041d5377843 +Author: Guus Sliepen +Date: Thu Oct 19 14:42:00 2000 +0000 + + - Seed the PRNG using /dev/random before generating the keys. + +commit 30df5e95dbe585c6076d743d3771a42ad7c78590 +Author: Ivo Timmermans +Date: Wed Oct 18 20:12:10 2000 +0000 + + Bring head revision up to date with cabal (try #3) + +commit 571cfb5846c710a0a3cdbdddce8936f6b34f1cf1 +Author: Ivo Timmermans +Date: Wed Oct 18 19:44:11 2000 +0000 + + Get the head revision up to date with cabal + +commit e75315dae609f32041ca5ed939fd2a1b69d32d3e +Author: Ivo Timmermans +Date: Tue Oct 17 10:15:20 2000 +0000 + + Don't declare cp_file and cp_line in xmalloc() + +commit 31c543ad0fa1d19667a03a9bd183c668def23da0 +Author: Ivo Timmermans +Date: Tue Oct 17 10:14:25 2000 +0000 + + Process subdir es/ + +commit 20301888b7a0a206119d2cfc48ccf1a667bb4add +Author: Guus Sliepen +Date: Mon Oct 16 19:04:47 2000 +0000 + + - More fixing. Tinc daemons can now even create activated connections. + +commit bb3d18d56fa0dd2bc5146d0a0044b6ef0880bdb4 +Author: Guus Sliepen +Date: Mon Oct 16 16:33:30 2000 +0000 + + - Fixing little things + - Two tinc daemons can connect to eachother now (but they disconnect right + after the ACKs). + +commit 6e32b870ee127555888a115163922362c99009f9 +Author: Ivo Timmermans +Date: Mon Oct 16 11:35:10 2000 +0000 + + Output doc/es/Makefile + +commit baeac83bf465a47d46082e1de40ea14dcf1d39af +Author: Guus Sliepen +Date: Sun Oct 15 20:30:39 2000 +0000 + + Corrected #ifdefs for tun/tap support. + +commit 782171fd2c59b7cc5568d2d4b33ce041834710ec +Author: Ivo Timmermans +Date: Sun Oct 15 20:21:27 2000 +0000 + + Really #include the if_tun.h files now + +commit 8a54c51238672abd7a72c1dbdc7d17b9956a0d35 +Author: Ivo Timmermans +Date: Sun Oct 15 20:13:55 2000 +0000 + + Linearized checks for if_tun.h + +commit e5130495d7d4083d58ab76c26001aa27f5fc13db +Author: Ivo Timmermans +Date: Sun Oct 15 19:53:15 2000 +0000 + + Wrap the tun/tap code in #ifdef HAVE_TUNTAP + +commit 3b455b8f318528206b08121f5ce93d16e4ea01df +Author: Ivo Timmermans +Date: Sun Oct 15 17:26:31 2000 +0000 + + Add checks for the presence of the universal tun/tap device driver. + +commit 85adeef21275633b78a234b2660cbe3bc9dd2c33 +Author: Guus Sliepen +Date: Sun Oct 15 00:59:37 2000 +0000 + + - The daemon actually runs now (somewhat) + - Added support for tun/tap driver (autodetect!) + - More sophisticated checkpoint functionality + - Updated dutch translation + +commit 97ce045189e330e121873d1b4be1959c60062cbb +Author: Ivo Timmermans +Date: Sat Oct 14 22:22:06 2000 +0000 + + Add CVS id lines + +commit 2e159d0139e77041ad82e96bf0abef6aaf64a258 +Author: Ivo Timmermans +Date: Sat Oct 14 22:17:29 2000 +0000 + + Fix `Requirements'-section for GMP and OpenSSL libraries. + +commit 1d5bb49f261b4346b5a440ae6bbf58fe391ea46e +Author: Ivo Timmermans +Date: Sat Oct 14 22:00:09 2000 +0000 + + Update Depends lines to reflect the dependencies on OpenSSL + +commit e9635ae38e0e2e3eb92568a1e234f8348856dd69 +Author: Guus Sliepen +Date: Sat Oct 14 17:04:16 2000 +0000 + + - Second fixing-things pass: it even links now. + - Lots of FIXME comments added to the source code. + +commit 6a8c2e346e6125e58aab428e6730c18a949abe12 +Author: Ivo Timmermans +Date: Fri Oct 13 23:34:56 2000 +0000 + + Don't look for GMP header files + +commit f18e30dab3c208fd353af11e365791035534f444 +Author: Ivo Timmermans +Date: Fri Oct 13 23:30:11 2000 +0000 + + Updated new requirements, pointers to the manual + +commit a96f2f0fc8a02593d4cda5976df3c76fc5c99eae +Author: Ivo Timmermans +Date: Fri Oct 13 23:29:35 2000 +0000 + + Link with OpenSSL, forget libGMP + +commit 183a8edd22ba4bc682392c73ae02fc9e121eda68 +Author: Guus Sliepen +Date: Wed Oct 11 22:01:02 2000 +0000 + + - Fixing-things pass: every source file compiles into an object file now, + but linking tincd does not work yet (must link with openssl libs and + define some missing functions). + +commit 6e39481d8f2406e60b5e329ace08b5a005d5cc43 +Author: Guus Sliepen +Date: Wed Oct 11 13:42:52 2000 +0000 + + - Generalized config file parsing to support multiple configuration trees. + +commit 451e9e3e7a968151de541de68603a01f0922b415 +Author: Guus Sliepen +Date: Wed Oct 11 12:07:27 2000 +0000 + + - Changed genauth to produce rsa keypairs instead of random passphrases. + +commit 950fb8e916b0e248dcaa72c96859acd6046683aa +Author: Guus Sliepen +Date: Wed Oct 11 10:35:17 2000 +0000 + + Big and bad commit of my current tree... + - Added seperate file for connection list handling + - Updating everything to use connlist, meta and subnet files + - Removed dependency on libgmp + - Lots of other stuff... + +commit 73d0dcfcc1019ee745a422982b4e3ede9d59dd91 +Author: Guus Sliepen +Date: Wed Oct 4 15:09:57 2000 +0000 + + Removing cipher directory (all will be covered by OpenSSL). + +commit 2228b16159a7aff64e6559ee1635716154e67fe6 +Author: Guus Sliepen +Date: Sun Oct 1 03:21:49 2000 +0000 + + - Added subnet handling code + - Other small changes to header files + +commit 676b1c0ea111406eb94a74ae12878dfd5ad9f56d +Author: Ivo Timmermans +Date: Wed Sep 27 20:32:29 2000 +0000 + + Many updates, parts rewritten, added, shuffled around. + +commit c78a204f06182f50b0812c8e4fef6163e82097bf +Author: Guus Sliepen +Date: Tue Sep 26 14:06:11 2000 +0000 + + - Added meta.c which contains functions to send, receive and broadcast + metadata. It will also handle encryption and decryption, and possibly + compression and checksumming. + - Moved request dispatcher to protocol.c. + +commit 2c412009e5805f04c650889b19fcb38531f2aa50 +Author: Guus Sliepen +Date: Mon Sep 25 20:08:50 2000 +0000 + + - Very detailed example of the authentication phase. + +commit 361690b18c1f5464db7b9cef235c648784780dfb +Author: Guus Sliepen +Date: Fri Sep 22 16:20:07 2000 +0000 + + - Removed options "string" stuff. It was a bad idea... + - free() everything that is allocated. + +commit 5afc1e98f436c4a2ed5da4b64293275b09632c79 +Author: Guus Sliepen +Date: Fri Sep 22 15:06:28 2000 +0000 + + - Severe code reduction and simplification of challenge requests + - "Finished" [add|del]_subnet_h + - Added lots of sanity checks to [add|del]_host_h + +commit 5d0b3516d5e8a46ca2268bdb32657b72295501ec +Author: Guus Sliepen +Date: Sun Sep 17 21:42:05 2000 +0000 + + - Updated authentication scheme. + - Removed all trailing spaces from all lines. + - Added things to add_ and del_subnet_h. + +commit 84f210edd9e72a65ca8b034a0d3bbc12e506c580 +Author: Guus Sliepen +Date: Sun Sep 17 20:11:59 2000 +0000 + + - Included authentication scheme from protocol.c + - Added a few comments about the symmetric cipher. + +commit 2863134a4113b7805a662f45a21a1be0ae9606cb +Author: Guus Sliepen +Date: Sun Sep 17 19:57:39 2000 +0000 + + Added document about the used cryptographic algorithms and the reasons + behind them. Feel very free to comment on this! + +commit 33a5b4547141c11b5128d9f4863fcf6cf8e33452 +Author: Ivo Timmermans +Date: Sun Sep 17 10:28:57 2000 +0000 + + Added Spanish translation of the docs by Matias Carrasco + +commit 7f3ab38c222809b15da2fe8dd655d35432eaafe0 +Author: Ivo Timmermans +Date: Fri Sep 15 12:58:40 2000 +0000 + + Second round of fixes + +commit ed397b6ac676329b237e219c806143cccf456b3c +Author: Ivo Timmermans +Date: Thu Sep 14 21:51:21 2000 +0000 + + First round of needed fixes after the overhaul + +commit 296171d115614d61480d896cd77898f5393c191d +Author: Ivo Timmermans +Date: Thu Sep 14 14:34:38 2000 +0000 + + New directive: Name. + +commit d335c6d0d7328fd86154dc60b22deb7953ab0228 +Author: Ivo Timmermans +Date: Thu Sep 14 14:32:34 2000 +0000 + + Added some structures and types that are needed for the overhaul. + +commit c04c84c98055c6b9e9e7890d3992648a3b715a1a +Author: Guus Sliepen +Date: Thu Sep 14 11:54:51 2000 +0000 + + - Lots of small changes. + +commit cd6695df82c55454a3f5b644f5c20a8ed31e7c97 +Author: Ivo Timmermans +Date: Mon Sep 11 11:40:46 2000 +0000 + + Better checks for SunOS libraries + +commit 9c75350ac6c14886195b6d368af2f118fd5d60e0 +Author: Guus Sliepen +Date: Mon Sep 11 10:05:35 2000 +0000 + + - Fixed modulo in keylength check + - Updated header file to reflect new protocol code + +commit 76b5f255c6cb0c5dfb5a870c371ec6f7c7879bb2 +Author: Guus Sliepen +Date: Sun Sep 10 23:11:37 2000 +0000 + + - Some key exchange stuff. (Last commit before going to bed.) + +commit 675ed08a71ec28d8ae99e10e993d5c7cb717f017 +Author: Guus Sliepen +Date: Sun Sep 10 22:49:46 2000 +0000 + + - Lots of functions added for the new protocol. + +commit 9926dae4646a96ee647a2ca7d728e91600dd1cca +Author: Ivo Timmermans +Date: Sun Sep 10 21:57:11 2000 +0000 + + Add Guus' name and shift out old protocol requests + +commit 74157d3f4501f4d1ec913a986b7167d2b847e41e +Author: Ivo Timmermans +Date: Sun Sep 10 18:37:46 2000 +0000 + + Correct filenames for passphrases given in the example + +commit 6b9ec9ed1e818d5e50dda4418ffb4d02c898bcba +Author: Guus Sliepen +Date: Sun Sep 10 16:15:35 2000 +0000 + + - Added more function skeletons for the new protocol. + +commit 28cc30159565a7eda4f66215a5994d84b46b47ad +Author: Guus Sliepen +Date: Sun Sep 10 15:18:03 2000 +0000 + + - New protocol. Will break everything else for now. + +commit 7884d3ecaf78006b3f288d99f10ef541fc97087e +Author: Ivo Timmermans +Date: Sun Sep 10 15:16:07 2000 +0000 + + Support for -lsocket and -lnsl on SunOS + +commit 14554e6f421e881b01be20879e9279545f375154 +Author: Ivo Timmermans +Date: Sun Sep 10 15:15:38 2000 +0000 + + Include openssl/blowfish.h + +commit 45ea3ca432a031ff1b8072d934709aadaae12534 +Author: Ivo Timmermans +Date: Sun Sep 10 15:07:41 2000 +0000 + + Updated text, removed protocol flowchart + +commit ae17572e6b94c6e7a2123ddeb45bf66d389ac7a0 +Author: Ivo Timmermans +Date: Sun Sep 10 15:05:45 2000 +0000 + + Link with OpenSSL crypto libraries instead of own blowfish library + +commit 4dde583bc91985c3ff19ac1d1f1bc791b50658ff +Author: Guus Sliepen +Date: Wed Sep 6 11:49:05 2000 +0000 + + - Use strerror() instead of sys_errlist[] for increased portability + (Needed for SunOS) + +commit 66e535a729dd5a9e45600ab74dc19c2b4062ee96 +Author: Ivo Timmermans +Date: Sun Aug 27 11:05:47 2000 +0000 + + Changed CVSROOT path in `make ChangeLog' + +commit 39e159fbe6bbffb3229542258f956fc412bd871c +Author: Guus Sliepen +Date: Tue Aug 22 14:55:04 2000 +0000 + + Fix rules (thanks to Laurence) + +commit 47992fe59f4c1b4116e4872d59251b143edc6763 +Author: Ivo Timmermans +Date: Mon Aug 21 20:35:47 2000 +0000 + + Added a rule to create an rpm + +commit d9af4f32330a495789d8eecdabbbb49928f074a7 +Author: Guus Sliepen +Date: Mon Aug 21 12:50:15 2000 +0000 + + Updated tinc.conf manual. + +commit 94a32c4b2d2ff5d4bb1376fe5ec96c6dec55f630 +Author: Ivo Timmermans +Date: Sun Aug 20 23:08:17 2000 +0000 + + Also chomp $VPNMASK + +commit 861e808fef1f6796d837215f9ad135fb4cb50f5c +Author: Ivo Timmermans +Date: Sun Aug 20 23:07:18 2000 +0000 + + (Quoting Laurence Lane:) + + The prefix is correctly set for /usr, but is + overridden with the current make install. DESTDIR is the clean way to + relocate the installation into the debian/tmp build dir. + +commit d3f41b803bf3c38910f24f1f268f182466723149 +Author: Guus Sliepen +Date: Fri Aug 18 14:45:38 2000 +0000 + + Updated the manual: + - incorporated comments from Stefan Hartsuiker + - updated configuration variables section + - added some text about key types + +commit 5c78e158d414595ab32399645678a43bb4469be6 +Author: Guus Sliepen +Date: Fri Aug 18 11:17:09 2000 +0000 + + Commented on some size calculations. + +commit d2c062a0a440d2871939b4ffdc2dbb137a4d45e7 +Author: Guus Sliepen +Date: Thu Aug 17 17:22:01 2000 +0000 + + Ran update-po and updated dutch translation. + +commit 3831f51a53088bfcc1d148fd54b3083afe7fde32 +Author: Guus Sliepen +Date: Thu Aug 17 16:51:08 2000 +0000 + + Fixed all sprintf() spl01ts. + +commit 9acd4379f705edc8b736e21b9011434e63f7dd95 +Author: Guus Sliepen +Date: Wed Aug 9 14:02:16 2000 +0000 + + - Added two extra configuration options, Interface and InterfaceIP, to + bind the listen socket to a network device or a specific IP. + +commit f6d79366b3efaef0a458717aac5e6754630dd434 +Author: Guus Sliepen +Date: Wed Aug 9 09:34:21 2000 +0000 + + - Reinstated O_NONBLOCK for meta socket + - Set SO_KEEPALIVE on meta socket + +commit 3cfc9424f255c26f2a7775b6fa059f1e3e47a76e +Author: Guus Sliepen +Date: Tue Aug 8 17:07:48 2000 +0000 + + - Moved TCP packet reception to meta handler: less kludgy and less buggy! + +commit e092d15be17db1d69c37f2aba46c66e03631c099 +Author: Guus Sliepen +Date: Tue Aug 8 14:54:57 2000 +0000 + + - Added date/time of build and protocol number to --version output. + +commit ff87f385c3a81499eff6b848aed8548cf6e5132e +Author: Guus Sliepen +Date: Tue Aug 8 13:47:57 2000 +0000 + + Removed calling add_queue for tcponly packets. + +commit ac73c72488dd8b33464fac1f392e89df48f7a23b +Author: Guus Sliepen +Date: Tue Aug 8 08:48:50 2000 +0000 + + Fixed PACKET read loop. + +commit b6997b0050e78a2f2e517beba3ff01d9232b3d1f +Author: Guus Sliepen +Date: Mon Aug 7 16:27:29 2000 +0000 + + - Lots o' buglets fixed (-Wall helps) + - Made TCPonly work :) + +commit fdc6a2f106315cd9ed22943d8c0bd279631e66b4 +Author: Guus Sliepen +Date: Mon Aug 7 14:52:16 2000 +0000 + + - Added experimental hackish tunneling-over-TCP support. + Just use TCPonly = true in the configuration file. + +commit 42455e97a057fb4386f9d8fb2f8963b2ec6ddf24 +Author: Guus Sliepen +Date: Sun Jul 2 13:40:57 2000 +0000 + + - Fixed typo. + +commit b1ecbf977722ec473fc8007acd39eb0de581de1a +Author: Guus Sliepen +Date: Sun Jul 2 13:36:18 2000 +0000 + + - Delayed address resolving for ConnectTo lines in configuration file to + allow DynDNS to work without restarting tincd. + +commit 6642ec2ea4e97a2fb3e737653ab1b9351ac759e9 +Author: Guus Sliepen +Date: Sun Jul 2 12:48:04 2000 +0000 + + - Updated THANKS file + +commit e0de803c7e80621600409a0c760241a3d97617bd +Author: Ivo Timmermans +Date: Sun Jul 2 12:41:03 2000 +0000 + + Include the Spanish translation in the distribution/build process. + +commit 721d85f77277813345bdb63a610e984cec996613 +Author: Guus Sliepen +Date: Sun Jul 2 12:35:28 2000 +0000 + + - Added Spanish translation from Enrique Zanardi. + +commit e821a22876d15c921a4c1fbc0f792d83e90916f6 +Author: Guus Sliepen +Date: Sat Jul 1 14:40:56 2000 +0000 + + - Forgot to mention ourselves in the tincd manual page! :) + +commit 09f4ec190119298187cec09dd5049af8fd8bad94 +Author: Guus Sliepen +Date: Sat Jul 1 14:32:24 2000 +0000 + + - Updated PROTOCOL (a bit) + - Included a real tincd.8 describing the options, signals, debug levels + and files used by tincd. + +commit d3ea434b3684093d6d160b8077c1f51a50ac7f61 +Author: Ivo Timmermans +Date: Sat Jul 1 10:39:28 2000 +0000 + + Autogenerated by gettextize. + +commit 1b28f88808b9ac3193cf9a0db7a81a89eed8b4ef +Author: Guus Sliepen +Date: Sat Jul 1 07:49:21 2000 +0000 + + - Removed a single unused bit from status_bits_t. + +commit 7fdc881b86fe379216f09dd5703bb88d398c87a8 +Author: Wessel Dankers +Date: Sat Jul 1 07:29:32 2000 +0000 + + Added architecture section, made a start with the kernel section. + ToDo: install tinc myself to see if everything is as I say =) + +commit 8ec648abf438bb5fcfe84e3a1c6a31192dc32b2e +Author: Guus Sliepen +Date: Fri Jun 30 22:38:58 2000 +0000 + + - Added documentation for the protocols (most important the meta protocol) + used by tinc. + +commit ce72275a4342ff4e21d21bb740ee88dca1ddb5f1 +Author: Wessel Dankers +Date: Fri Jun 30 21:16:52 2000 +0000 + + Grrr, recommit + +commit bbbdda255d6e7a8730906a1b6c2bfdd2ce1b94cf +Author: Wessel Dankers +Date: Fri Jun 30 21:11:34 2000 +0000 + + This file is now only in the CABAL revision. + +commit 28a140668f892873b01afe104d21db4adb8fd8c7 +Author: Wessel Dankers +Date: Fri Jun 30 21:09:32 2000 +0000 + + More about keys + +commit 1a1ebefd572c18d6af187750847b024ce07551ae +Author: Guus Sliepen +Date: Fri Jun 30 21:03:51 2000 +0000 + + - Made tinc even more silent if no -d flag is given at all. + +commit 79ad21c392e56cad2556e7693b9639d8e2346a59 +Author: Wessel Dankers +Date: Fri Jun 30 20:57:30 2000 +0000 + + Added extra bit about keys. + +commit 8309e9b869c25677d674f5cecb8b7ac5469d1758 +Author: Wessel Dankers +Date: Fri Jun 30 20:50:47 2000 +0000 + + File added to CABAL (hopefully) + +commit 5cd0f940c7334959534d3ab4e1f3c7cac67ee38a +Author: Wessel Dankers +Date: Fri Jun 30 20:42:07 2000 +0000 + + added bit on config file, split up sections, added Id: tag + +commit 6f5aac4e39cd6fb2fb76c0121de3f3782f72f18e +Author: Wessel Dankers +Date: Fri Jun 30 20:16:15 2000 +0000 + + Initial revision. Lots of loose ends, not usable yet. + +commit c5737583c8a5d099a71174e1eb997e0972ae03e9 +Author: Guus Sliepen +Date: Fri Jun 30 12:41:06 2000 +0000 + + - Instead of logging an error when remote end closes the connection, + we print a nice message if appropiate debug level is set. + - If we get ADD_HOSTs or DEL_HOSTs for ourself, then connection lists + are really messed up. We restart, and hope our problems go away. + +commit 24874d0806bac5d75663ea9de67a71171bfc97b6 +Author: Guus Sliepen +Date: Fri Jun 30 11:45:16 2000 +0000 + + - Removed segfault bug in conf.c (must have been there for ages!) + - Made main_loop() signal proof + - #defined MAXTIMEOUT (15 minutes) + - If something really really bad happens, close all connections, wait + for MAXTIMEOUT seconds, and then restart tinc + +commit 0f9ad1f047efec53590dc43f07d225e5f20456cb +Author: Guus Sliepen +Date: Thu Jun 29 19:47:04 2000 +0000 + + - Fixed memory leak. + - Implemented SIGHUP configuration file reloading. + - Other small changes. + +commit 18c85caac36f7236454deef11b9eba74328dbd96 +Author: Guus Sliepen +Date: Thu Jun 29 17:09:08 2000 +0000 + + - New semantics for BASIC_INFO, ADD_HOST and DEL_HOST requests. This will + improve connection list consistency, ensures the tree property, and + allows for recovery from situations where track of connections is lost. + +commit e8e7379311ca3bf6e1fdd7d0f477a43e510e2317 +Author: Guus Sliepen +Date: Thu Jun 29 13:04:15 2000 +0000 + + - Removed all IP_ADDR_S macros, because gettext doesn't like them. Each + connection now has two hostnames: real_hostname (replacing the old), + and vpn_hostname. In those places where hostnames really aren't usefull + IP_ADDR_S has been replaced by %d.%d.%d.%d. + +commit e0ddb638d1fb7abf19969ac887f3b7a2bd8225c1 +Author: Guus Sliepen +Date: Thu Jun 29 07:11:23 2000 +0000 + + - Updated Dutch translation. + +commit 0a155580a3d55633bbc3a1e7dcbe8906f41913be +Author: Ivo Timmermans +Date: Wed Jun 28 21:06:40 2000 +0000 + + Oops, and mention Guus too. + +commit f2c9e7f3bbada3fbfe80f622ebc06540afb60c21 +Author: Ivo Timmermans +Date: Wed Jun 28 21:01:45 2000 +0000 + + Removed Free Software Foundation copyright, because Guus Sliepen contributed significantly. + +commit 3df9b89204626afdd514d5b7323801af76a5cd26 +Author: Guus Sliepen +Date: Wed Jun 28 14:34:40 2000 +0000 + + - Added log message when SIGCHLD is received ("thanks" to Ivo van Dong) + +commit 8c6c60adf3d5942c6368bafe9a4d4377ffad1abe +Author: Guus Sliepen +Date: Wed Jun 28 13:41:02 2000 +0000 + + - Fixed a message in nl.po + - Woops, we forgot to send our connection list to our uplink when we + connect to it... Fixed. + +commit 63c5192d570e2ba5952b4e5a807e4ab4d6fdad76 +Author: Guus Sliepen +Date: Wed Jun 28 11:39:40 2000 +0000 + + - Fixed missing " in nl.po + +commit ea40d3f1a05e9edf4ccfb77f4e9e0f8355e94a83 +Author: Guus Sliepen +Date: Wed Jun 28 11:38:01 2000 +0000 + + - Fixed some spelling errors. + - Paar zpelvautjes gerepareerd, en de Nederlandse vertaling weer bij de + tijd gebracht. + +commit dba2995db73313b1c0a56ce13395dac0bc7571a5 +Author: Guus Sliepen +Date: Wed Jun 28 10:11:10 2000 +0000 + + - Extra check op EINTR bij inlezen requests + +commit 4ee53e7dac93d1edad8664edffdfaf142438b85d +Author: Guus Sliepen +Date: Tue Jun 27 21:05:07 2000 +0000 + + - Fixes a silly little insignificant buglet. + +commit 070ad08118a33755835b31174e2b04e84f75556e +Author: Guus Sliepen +Date: Tue Jun 27 20:55:12 2000 +0000 + + - Purge old connections that are ADD_HOSTed. + +commit 4aeaea5e590fbd38aebbfacf2672304d04ba4ad1 +Author: Guus Sliepen +Date: Tue Jun 27 20:10:48 2000 +0000 + + - Improved handling of errors on connection attempts. + +commit 45a28b1e893d4da9d7977945a35ec6a8e4554830 +Author: Guus Sliepen +Date: Tue Jun 27 15:08:58 2000 +0000 + + - Fixed indirectdata=no problem + - Added support for multiple ConnectTo lines in tinc.conf. + +commit 4faed1b8546563def6a426c563cec2a26d927eda +Author: Guus Sliepen +Date: Tue Jun 27 12:58:04 2000 +0000 + + - Fixed KEY_CHANGED notification. A lot of notify_others() calls were + wrong (first two arguments swapped). Should probably be doublechecked. + - Don't retry to connect to hosts with different protocol versions. + +commit 04cb206298df033d254ca007205d13f9a670c402 +Author: Guus Sliepen +Date: Mon Jun 26 20:30:21 2000 +0000 + + - Moved all connection messages to debug level 1, without -d's only the + startup message will be logged. + - Fixed DEL_HOST rebound. + +commit 783c8298610d5670f6e118f49bd3d1fdfa61ae1d +Author: Guus Sliepen +Date: Mon Jun 26 19:39:34 2000 +0000 + + - Indirectdata finally REALLY REALLY works now! + - More precise debug messages + +commit b3681ebf6c255daf082ed254282cbf493af8fa93 +Author: Guus Sliepen +Date: Mon Jun 26 17:20:58 2000 +0000 + + Fixes some hostlookups. Fixes indirectdata for real now (hopefully). + +commit 03af6d8c8056d0b7006f7d8fb19bb33d303ac8f9 +Author: Ivo Timmermans +Date: Sun Jun 25 20:52:29 2000 +0000 + + Version 1.0pre3. + +commit a473ece8a0d83be5f7992888a6a3ff938dc4fb72 +Author: Guus Sliepen +Date: Sun Jun 25 16:39:17 2000 +0000 + + - More verbose connection list + - Added "myself" as hostname when logging indirect ADD_HOSTs + +commit f1f901112e44beaecd3037dae27407ea83edd86e +Author: Guus Sliepen +Date: Sun Jun 25 16:20:27 2000 +0000 + + Hostlookup() is actually being called now. + +commit 54079bdf03e74c686f556f86082b9d14b5be227c +Author: Guus Sliepen +Date: Sun Jun 25 16:01:12 2000 +0000 + + Hostnames are back! + +commit e4b586ed070908f866a450292f9759004e6affa8 +Author: Guus Sliepen +Date: Sun Jun 25 15:45:09 2000 +0000 + + - Log possible spoofing attacks. + - Don't broadcast DEL_HOSTs for hosts that haven't been activated yet. + - If a host sends a TERMREQ, deactivate them. + +commit 9a1103a7be86de3da5548fd6446e6e4fe554cc08 +Author: Ivo Timmermans +Date: Sun Jun 25 15:42:40 2000 +0000 + + Changed version number to 1.0pre3. + +commit d8d2b83350e890adae9c9cede6e21ea4169abe00 +Author: Ivo Timmermans +Date: Sun Jun 25 15:42:40 2000 +0000 + + Changed version number to 1.0pre3. + +commit 7648bc606596851942dd6437ddaa93f53ab20f09 +Author: Guus Sliepen +Date: Sun Jun 25 15:22:16 2000 +0000 + + Added CVS Id tags to header files. + +commit 7f7e158aae8df5c65211bcfa82516e7c243cdd2e +Author: Guus Sliepen +Date: Sun Jun 25 15:16:12 2000 +0000 + + Large cleanup: + - Removed hostname lookup (it blocks, and you can always do it yourself) + - Reorganized debug levels (after hints from Axel M�ller): + 0 Startup message and errors + 1 Connection logging + 2 Meta protocol information + 3 Verbose meta protocol (includes copy of transmitted requests) + 4 Packet information (logs transmission/errors of UDP packets) + 5 Verbose packet information (every single byte, not implemented yet + to protect ourselves from filling up /var/log directories) + - Made log messages more consistent + +commit 3c54a513b0c0a3acac60e03403ab4abfa0688c62 +Author: Guus Sliepen +Date: Sat Jun 24 12:35:42 2000 +0000 + + If we have "indirectdata" flag set, we only send data to our uplink. + +commit d8e2f7104c3203edbf23d2349656c765a4310dee +Author: Guus Sliepen +Date: Fri Jun 23 19:27:03 2000 +0000 + + First step for implementation of the "indirectdata" directive. This should + allow _leaf_ tincds to be behind firewalls. + The protocol has changed and is INCOMPATIBLE with previous versions. The + PROT_CURRENT value has been incremented. + +commit 33c3a25a66251606cbf20d3bd5b392d8837116e3 +Author: Ivo Timmermans +Date: Sat Jun 17 20:55:54 2000 +0000 + + Configuration directive `IndirectData'. + +commit 1c8adb5e1f12894fc9a478fbf29678fb662e03ab +Author: Ivo Timmermans +Date: Sat Jun 17 20:30:44 2000 +0000 + + Merge changes from 1.6-1.8. + +commit 0d167e1f5d8778674a9a77b2256050e3afe2896e +Author: Guus Sliepen +Date: Sat Jun 17 08:30:45 2000 +0000 + + Added another semicolon for bash2 compliance (thanks to Jamie Briggs) + +commit 00f316810aa808368cdff620b1a1efdd1fcade20 +Author: Guus Sliepen +Date: Fri Jun 16 05:44:26 2000 +0000 + + Applied patch from Jamie Briggs for bash2 conformance. + +commit ef294a69678bc7cba6d2ee0be96f683249672222 +Author: Ivo Timmermans +Date: Tue Jun 6 10:24:33 2000 +0000 + + Include ../intl in the include path, and add @INTLLIBS@ to the list of libraries. + +commit 66e98068051bc52fa064650710260f89c09f8cfd +Author: Ivo Timmermans +Date: Sun Jun 4 12:14:31 2000 +0000 + + These files are created by gettextize (run by autogen.sh) (should have known that). + +commit d1d4a524dee9d75b067ac8e25770557cf22f4afe +Author: Ivo Timmermans +Date: Sun Jun 4 11:50:46 2000 +0000 + + Check for __gmpz_powm for libgmp3. + +commit 377c4df245ceb8c19cabfe6d7a7c76841c07ba52 +Author: Ivo Timmermans +Date: Sat Jun 3 23:32:03 2000 +0000 + + Don't touch VPNMASK if it's defined, otherwise use $MSK. + +commit 9193aee8159ce53b349557ba1ad8ed23111042bb +Author: Guus Sliepen +Date: Sat Jun 3 08:27:16 2000 +0000 + + Removed items in TODO list that are already implemented. Only two items + left. + +commit 5796d2f5b7310fa8841f76bbc7bbcf2385d960c3 +Author: Ivo Timmermans +Date: Fri Jun 2 17:30:33 2000 +0000 + + Alphabetized the list, added Lubom�r Bulej, removed Sander Smeenk and Tijs van Bakel, put merits after all names. + +commit 18b3084d2525c59f62b75346fa657ccce6459712 +Author: Guus Sliepen +Date: Thu Jun 1 20:21:27 2000 +0000 + + Debian init.d script automatically sets tap device's MTU to 1448 now. + +commit 77be52422d8c28735f787b1c233b4cec73d4db56 +Author: Ivo Timmermans +Date: Wed May 31 18:23:06 2000 +0000 + + Miscellaneous copyright updates. + +commit 8cb4bb619d777022a55255c5fa17a1a55a270ff3 +Author: Ivo Timmermans +Date: Wed May 31 18:21:27 2000 +0000 + + Handle locale settings. + +commit f20df109a638ac3a86efa70fac39e1dae8e87208 +Author: Ivo Timmermans +Date: Wed May 31 18:19:33 2000 +0000 + + Version 1.0pre2-1. + +commit 4ae74c50b7faadf31086bc61af0f8158a465e521 +Author: Ivo Timmermans +Date: Wed May 31 18:18:21 2000 +0000 + + Updated Dutch translation. + +commit 7037286586151e28b7c5f1fe09dd6c5faca18cdc +Author: Ivo Timmermans +Date: Wed May 31 18:17:45 2000 +0000 + + Tell about /etc/tinc/nets.boot. + +commit 65a9eedb05387b8cf77dbbbc56347b44a28de624 +Author: Ivo Timmermans +Date: Wed May 31 18:17:27 2000 +0000 + + Include news for 1.0pre2. + +commit 17fa07510ad74d0f96f9700538d32eb8e7b2a0ce +Author: Ivo Timmermans +Date: Tue May 30 21:36:16 2000 +0000 + + Only accept an ADD_HOST request for a host that already exists in our conn_list if the nexthop field matches the sender. This is a workaround for older clients. + +commit e7f22d2f5f0a5fcd52da7512ab734b0ba52c623f +Author: Ivo Timmermans +Date: Tue May 30 12:38:15 2000 +0000 + + In terminate_connection, only send a notification to hosts that are directly connected to us. (DEL_HOST gets forwarded automatically.) + +commit 2fdda8e4fa6c6ace5f7e9421f0644a3ffec388c9 +Author: Ivo Timmermans +Date: Tue May 30 12:31:41 2000 +0000 + + When a connection is terminated, all hosts that are still connected get notified of the lost connections. + +commit f826301889e1fa1a22770919f0385c3ca04c740a +Author: Ivo Timmermans +Date: Tue May 30 11:18:12 2000 +0000 + + Added new configuration directive `Hostnames', which controls the resolving of IP addresses to hostnames. + +commit a7ad161d2b115b6a2a69c5dc8ddd33008d3562d0 +Author: Guus Sliepen +Date: Mon May 29 23:40:05 2000 +0000 + + Only activate a connection upon receiving it's public key if it's an + incoming connection. When it's outgoing, we need to receive an ack first. + +commit 5654e156a31d05ac3026790f7749d0401b2eaabc +Author: Ivo Timmermans +Date: Mon May 29 22:27:15 2000 +0000 + + Updated changes list for version 1.0pre2. + +commit a822c7466aa91a819c498336f91c63d224c3af11 +Author: Ivo Timmermans +Date: Mon May 29 22:20:04 2000 +0000 + + Bounds check for request id (between 0 and 255). + +commit 0f2cf48d304e20abb9b3cded2aaa693828c9d412 +Author: Ivo Timmermans +Date: Mon May 29 22:15:38 2000 +0000 + + Dutch translation of tinc. + +commit 386a62ff57f283b415fd757a8c4645b24c3bd3bb +Author: Ivo Timmermans +Date: Mon May 29 21:40:51 2000 +0000 + + Define LOCALEDIR in CFLAGS. + +commit 4cd009f774e4c50cdacc06d351cac19ca3247b6b +Author: Ivo Timmermans +Date: Mon May 29 21:40:20 2000 +0000 + + Include GNU gettext checks. + +commit 5814939c9d0e801bdbed6c96092fd90b6dcd859c +Author: Ivo Timmermans +Date: Mon May 29 21:38:02 2000 +0000 + + Update acconfig.h to include values for gettext inclusion. + +commit b200b0d812763563dbe09e5da116c55e45f89e4f +Author: Ivo Timmermans +Date: Mon May 29 21:36:28 2000 +0000 + + Include system.h and ABOUT-NLS. + +commit b9ea0633c7243de552d581f4486902c67aefd695 +Author: Ivo Timmermans +Date: Mon May 29 21:04:55 2000 +0000 + + Include intl/ directory in the list of subdirs. + +commit 9fd02ffcb0cacf3de26e876de5f30510bff137a3 +Author: Ivo Timmermans +Date: Mon May 29 21:01:26 2000 +0000 + + Internationalization of tinc. + +commit 61e71ab74ad9b5edb044b84ccf1111a33eb468cb +Author: Guus Sliepen +Date: Sat May 27 20:23:01 2000 +0000 + + Terminate a connection on any error. Furthermore, disallow del_host, + add_host and other important requests until remote host has properly + authenticated itself. + +commit cc01b18bc6d0bfb12e6770fc0a007c278f355d9e +Author: Guus Sliepen +Date: Sat May 27 19:44:04 2000 +0000 + + Made tinc persistent. If no outgoing connection can be established right + after the start of the daemon, it won't quit anymore but will retry in 5 + minutes. Also, 5 minutes is now the maximum time to wait for a retry. + +commit 028659bfbf164cb7a72831506896e291010b251f +Author: Guus Sliepen +Date: Sat May 27 19:23:20 2000 +0000 + + Fixed typos. When terminating a connection, it's status is not only set to + remove=1 but also active=0. + +commit e4ff969a9868ecc25a85daab620f97227de8d493 +Author: Guus Sliepen +Date: Sat May 27 19:04:12 2000 +0000 + + Fix for a DoS attack: + A remote user could telnet to the tinc daemon and type only this line: + 61 6 00000000/00000000:28f + This would deny any packets to be sent to other tinc networks (except + for to the hosts that run tincd's themselves). Solution is to skip + hosts in lookup_conn() that have not been activated yet. + Fixed potential conn_list table corruption: + If a new connection is accepted but a connection with the same subnet + would already exist in the connection list, the OLD connection is + terminated. + +commit 4d71de15e8abd137702a5dc04a743d246c3f1110 +Author: Guus Sliepen +Date: Sat May 27 13:21:20 2000 +0000 + + Documentation updates. Removed all references to configuration variable + "AllowConnect", since it is NOT used in tinc. Added information about + "VpnMask". Elaborated a bit about "private" and "virtual" networks. + +commit 85e3c1f2716c622ca8cada83d833703bf8a3ecc6 +Author: Ivo Timmermans +Date: Fri May 26 11:25:59 2000 +0000 + + Updated by Lubomir Bulej and Mads Kiilerich: it uses /etc/tinc/nets.boot and the VpnMask directive in the config files. + +commit 3a6ffe6895b681377a9553c01e3777f499b90d4a +Author: Ivo Timmermans +Date: Sun May 21 23:01:28 2000 +0000 + + Create an empty /etc/tinc/nets.boot. + +commit b9a86ec70ed4ffe5009c4979454f0d99c8559b45 +Author: Ivo Timmermans +Date: Sun May 21 22:40:41 2000 +0000 + + Use /etc/tinc/example as a base directory for an example. /etc/tinc/example/README points to /usr/share/doc/tinc/README.Debian. + +commit 63847abdfdad03a69bfd967929336e113cdeb09e +Author: Ivo Timmermans +Date: Sun May 21 22:38:01 2000 +0000 + + Add an example of using VpnMask. + +commit 2469acc0900edeb8f1e3263fbf58bf74639c1b12 +Author: Ivo Timmermans +Date: Sun May 21 22:27:31 2000 +0000 + + When VpnMask is not present in the config file, silently use $MSK as vpnmask. + +commit 73b3e7ce03cacb644a8101610933b221fdf432d6 +Author: Guus Sliepen +Date: Sun May 21 22:21:38 2000 +0000 + + Fixed last typo. Init.d now uses ifconfig command to set both the tap's IP + address as well as the correct route. Furthermore, if no VpnMask is given, + a default of 255.255.0.0 is chosen and a warning issued. + +commit 2ad4f1cc5b6013be2deee82b0cb3f731adb51616 +Author: Guus Sliepen +Date: Sun May 21 22:08:21 2000 +0000 + + Typo. + +commit e25fc3a3dc4bc407bd0645fb9891ac127a83f468 +Author: Guus Sliepen +Date: Sun May 21 22:04:56 2000 +0000 + + VpnMask truely works now. + +commit 9ec4decec17f95cc7d5be66cc18bb040cce84d47 +Author: Ivo Timmermans +Date: Fri May 19 01:17:32 2000 +0000 + + Mask the vpn net with the vpn netmask, route would give an error if the netmask didn't match the net. + +commit 20e404ab5716b06b53a4a5443f8098f227770907 +Author: Ivo Timmermans +Date: Fri May 19 00:58:01 2000 +0000 + + Fixed typo. + +commit 44af1094be90878bd6fc09c40882cf2463046908 +Author: Ivo Timmermans +Date: Fri May 19 00:33:44 2000 +0000 + + Updated copyright notice. + +commit 01352f4c525862f05988ed8687f26210c5ba10a2 +Author: Ivo Timmermans +Date: Fri May 19 00:15:37 2000 +0000 + + Errors will not terminate the script or result in a nonzero exit code. + +commit 4ef2a8cfdb13c7eb2d811fc8c9f04df8970293c5 +Author: Ivo Timmermans +Date: Fri May 19 00:14:34 2000 +0000 + + Include postinst in the distribution. + +commit 59ca017df4c9d0f7861693b4d2ec4b7dc8c98b1e +Author: Ivo Timmermans +Date: Fri May 19 00:09:20 2000 +0000 + + Find networks in instead of . + +commit 0354962c9885f04801d8469214c172cc012cdcec +Author: Ivo Timmermans +Date: Thu May 18 23:33:44 2000 +0000 + + Don't distribute the file files. + +commit b56705e18ceec9234578d7ac12939f7c59cff066 +Author: Ivo Timmermans +Date: Thu May 18 23:28:51 2000 +0000 + + Version 1.0pre2-0.3 + +commit cbf6efb617f45ffc608fe5f61d09abdd85f444ad +Author: Ivo Timmermans +Date: Thu May 18 23:18:54 2000 +0000 + + Create a default /etc/tinc/nets.boot after installation, containing all directories under /etc/tinc by default. + +commit e7d583adfaa50370d20f4cfe88ba5b6da399911d +Author: Ivo Timmermans +Date: Thu May 18 23:09:31 2000 +0000 + + Read /etc/tinc/nets.boot to find the networks that have to be started. + +commit 8d4ab991b8c35382c9cd46dd65af873d9d08f63f +Author: Ivo Timmermans +Date: Wed May 17 23:13:51 2000 +0000 + + This file is generated with dpkg-buildpackage. + +commit ffc79bcd20b2b8085c906a446318817808bc36ae +Author: Guus Sliepen +Date: Tue May 16 16:07:15 2000 +0000 + + TODO file reinstated: + - Append your name to items if you're working on them. + - Remove them if you fixed the problem/implemented that feature. + - Add any (suspected) bugs. + +commit cdab82d6fb7d7d32194cb2162a814fbc89b7db4c +Author: Ivo Timmermans +Date: Tue May 16 14:34:44 2000 +0000 + + Use the new VpnMask directive to add a route to the rest of the VPN. + +commit 85963f4c857abc2d9a4c5a3245cc11257140b9a6 +Author: Guus Sliepen +Date: Tue May 16 13:09:15 2000 +0000 + + Stub for VpnMask config directive. + +commit 30aff5ea2aebcfc0e97e60e73ed3edc2363634a0 +Author: Ivo Timmermans +Date: Tue May 16 13:03:32 2000 +0000 + + Look if the tap devices exist before bluntly remaking them. + +commit 0761eed64c4d6d2b8e9fa6a335ccdca8ea4b95db +Author: Ivo Timmermans +Date: Tue May 16 07:56:05 2000 +0000 + + *** empty log message *** + +commit 0a2e2b0c8d20baf22b550f735b1fe63b0a1d377a +Author: Ivo Timmermans +Date: Mon May 15 19:48:46 2000 +0000 + + Depend on perl5. + +commit 7e817fcf0fdd25aae58259930006c61048b017cd +Author: Ivo Timmermans +Date: Mon May 15 18:28:45 2000 +0000 + + Unlimited length in the config file, thanks to Cris van Pelt. + +commit b18af982af810ff4c050891ad2026960c43620a0 +Author: Ivo Timmermans +Date: Mon May 15 17:15:52 2000 +0000 + + Exit with zero status if is empty. + +commit 4711a87922c84241e9bb312755d7b943ea8ae4b6 +Author: Ivo Timmermans +Date: Mon May 15 15:54:37 2000 +0000 + + Updated to newer version. + +commit a0c4e7fe6d46988f3fb1100ef00db7b747c86f72 +Author: Guus Sliepen +Date: Mon May 15 09:41:34 2000 +0000 + + Test for existence of configured tinc networks. This will also make + first install of tinc possible without errors. + +commit 265bda08cd00feebb68243d4079854916b03638e +Author: Ivo Timmermans +Date: Sun May 14 23:03:37 2000 +0000 + + .deb version number 1.0pre2-0.4. + +commit 7a450d704b5a242f8bf9129af60593c90c63df5a +Author: Ivo Timmermans +Date: Sun May 14 23:00:44 2000 +0000 + + tincd->tinc + Delete libblowfish.y not be in the .deb. + +commit 7fbfa990fcd38b8241281ce6f1a4e2992239986f +Author: Ivo Timmermans +Date: Sun May 14 22:59:47 2000 +0000 + + Mention both upstream authors. + +commit f7b04ea142623a43413f74e19b1b6a9a247647ff +Author: Ivo Timmermans +Date: Sun May 14 22:59:19 2000 +0000 + + Add description, better dependancies. + +commit 9f07fe55dc4930920b9a5909d7057ca7bc16bad9 +Author: Ivo Timmermans +Date: Sun May 14 22:58:47 2000 +0000 + + Add initscript, tincd->tinc. + +commit df10baa50c3b421b03ac9eeaed4a4a19a47f611e +Author: Ivo Timmermans +Date: Sun May 14 21:18:10 2000 +0000 + + Inserted useful content. + +commit 6c722da77cc9185e48e22818ef88f2a88cf2efc7 +Author: Ivo Timmermans +Date: Sun May 14 21:14:23 2000 +0000 + + Add shlibs control file for the blowfish library. + +commit 803f908078e87f433727a3ddf2d61734e1ed9233 +Author: Ivo Timmermans +Date: Sun May 14 21:07:16 2000 +0000 + + Give IP address instead of hex number when connecting tcp socket failed. + +commit 4b1a1c2123626b50bd1a5382867986260440e9e7 +Author: Ivo Timmermans +Date: Sun May 14 21:04:53 2000 +0000 + + Changed version to 1.0pre2. + +commit ca900d388b996c629f0c87c7a62efb52bd219065 +Author: Ivo Timmermans +Date: Sun May 14 20:58:34 2000 +0000 + + Version 1.0pre1-0.1. + +commit 7d433ebd7610e0ff7e7b4c59979c446c0a1dfd03 +Author: Ivo Timmermans +Date: Sun May 14 20:56:41 2000 +0000 + + Add check for mpz_powm in libgmp3. + +commit de09916eadd4c558937d1a6367f5319ca26ed07c +Author: Ivo Timmermans +Date: Sun May 14 13:50:10 2000 +0000 + + Only print an error with send_termreq if debug_lvl is 2 or more. + +commit 9d023b1f2e7750f4a0e506c0f61498a44c0b95a8 +Author: Guus Sliepen +Date: Sun May 14 13:06:52 2000 +0000 + + Fixed typos. + +commit e20e143f1e99bdc0a7d92e97da1bd0dc40e8a83b +Author: Guus Sliepen +Date: Sun May 14 13:02:20 2000 +0000 + + Changed ping behaviour (backwards compatible). If we don't have any data + to send, we don't need to check if the connection is still alive. + Furthermore, if we receive any kind of data from the other end, we know + it's alive, so we don't need to check it either. So, PING requests are + only sent if we send packets but there is no response. + +commit ee96ccabbbf0180d5631d3c22838456f28ee9c15 +Author: Guus Sliepen +Date: Sun May 14 12:22:42 2000 +0000 + + Cleanups. + +commit 8caa1b9d750bb7467d1c3330780b05ac2bbf9883 +Author: Guus Sliepen +Date: Sun May 14 11:39:18 2000 +0000 + + Proxymode removed. + +commit 269067bb22e8f80deb43d3ac903f4e0d67af63d2 +Author: Ivo Timmermans +Date: Sat May 13 00:54:27 2000 +0000 + + Perl version of the system startup script. + +commit 12adf1af548b7d2f2baa4be16d2df956048b7855 +Author: Ivo Timmermans +Date: Fri May 12 13:31:00 2000 +0000 + + Deleted the protocol description. + +commit d0ba34ccae02d07051bc3f7012a6c116cfb3b653 +Author: Guus Sliepen +Date: Mon May 8 18:44:15 2000 +0000 + + Added new config variable "ProxyMode". If enabled, all outgoing packets + are sent to the uplink (ConnectTo), which will have to forward them for + us (kernel should do that). This is for people behind firewalls. + +commit 92387475ace9b06af39987c71ac563cf29427009 +Author: Ivo Timmermans +Date: Fri May 5 10:48:54 2000 +0000 + + Added semicolons required by bash2 (Mads Kiilerich). + +commit bce2179fe350bf34cde0caab97f72c0930539840 +Author: Ivo Timmermans +Date: Thu May 4 23:26:24 2000 +0000 + + Copied most of the code from the redhat script. + +commit 74b0cbecce5194dc5c594cc4e2aa3e97c14ea6c1 +Author: Ivo Timmermans +Date: Thu May 4 23:17:02 2000 +0000 + + Include sys/types.h. + +commit 2f7e532d703bbf6997ae04658379df0b0d844f62 +Author: Ivo Timmermans +Date: Thu May 4 23:16:43 2000 +0000 + + Don't link in libdl. + +commit d4ef7ea0e79ee0d2b7063893f7af5ece886d838b +Author: Ivo Timmermans +Date: Thu May 4 00:01:05 2000 +0000 + + Check for the existance of libdl. + +commit 87ccd613cab1947878ef60e3c927f717df089233 +Author: Ivo Timmermans +Date: Thu May 4 00:00:50 2000 +0000 + + More for getopt support. + +commit 6182664859383a86a47846cafdc1f6fcd73b5a76 +Author: Ivo Timmermans +Date: Thu May 4 00:00:06 2000 +0000 + + Include stdio.h for fprintf. + +commit 88a8826cf72297a784d597ba5a2b47058e1faf72 +Author: Ivo Timmermans +Date: Wed May 3 23:47:06 2000 +0000 + + getopt_long() support for platforms that don't have it. + +commit 3d218a31145cf6a4c625ed287cdf3f99e4fd9a03 +Author: Ivo Timmermans +Date: Wed May 3 23:00:38 2000 +0000 + + Don't use error.h or error(), put #error in front of cpp errors. + +commit a083b1cf305f3d241f2f4b36968a5b1ed9117612 +Author: Guus Sliepen +Date: Wed May 3 18:02:15 2000 +0000 + + Squashed gcc warning. + +commit 78532475238b23eb52ac88d905fbf966d97a79d2 +Author: Guus Sliepen +Date: Wed May 3 17:59:07 2000 +0000 + + Fixes typo and UDP network byte order. + +commit 505b5ec2cd9d6cf3dc655284a8c4041ce8527a07 +Author: Guus Sliepen +Date: Wed May 3 15:37:32 2000 +0000 + + Outgoing packets now use network byte order in header. + +commit 2bc7a0c92831802eec167ad193515962a63690dd +Author: Ivo Timmermans +Date: Wed May 3 15:01:54 2000 +0000 + + Fix a typo, better handling of the info document. (from Mads Kiilerich) + +commit 89610e3fbada1dee79769b8146a500c8357fd81d +Author: Guus Sliepen +Date: Tue May 2 10:16:50 2000 +0000 + + Replaced sprintf() by safer snprintf(), removed possible buffer overflow + by one byte. + +commit aeccaca829842910b4a5c8a5fa61e1738492bea6 +Author: Guus Sliepen +Date: Tue May 2 09:55:34 2000 +0000 + + Previous fix fixed. Meta protocol should be really flawless from now on! + +commit 989d7edc07fd407e7f7838b45986f4e37359ef97 +Author: Guus Sliepen +Date: Tue May 2 09:10:33 2000 +0000 + + Fixed small mistake that would prevent forwarding requests. + +commit 069c146656b8f952e465492c53ab5b514e959565 +Author: Ivo Timmermans +Date: Mon May 1 22:00:02 2000 +0000 + + Mentioned new metaprotocol. + +commit bd0325655867b1dff740d52d0505773bba0606a6 +Author: Ivo Timmermans +Date: Mon May 1 21:47:12 2000 +0000 + + More tincd->tinc updates. + +commit a9247e6f2c57bda9dc62ed050f41048847109e83 +Author: Ivo Timmermans +Date: Mon May 1 21:31:59 2000 +0000 + + Fixed meta protocol. + +commit 9ea27f76fab3663c9c83a7fe7de95f74cbfd59be +Author: Ivo Timmermans +Date: Mon May 1 21:31:17 2000 +0000 + + Committed by Mads Kiilerich. + +commit a92604fa5dffef589fc3042c5ae09ae8878e8cff +Author: Ivo Timmermans +Date: Mon May 1 19:17:09 2000 +0000 + + Updates by Mads Kiilerich. + +commit ca6abd41ea0cdf2ca6491c3945fb3c62fd40ab98 +Author: Guus Sliepen +Date: Mon May 1 18:07:12 2000 +0000 + + Meta protocol overhaul. Tinc is now incompatible with previous versions, + furthermore this version does NOT work yet because of a problem with + sending keys (these should be converted to base36 or something like that). + It is possible to telnet to the tinc daemon now and type some commands + by hand though :). + +commit 3219be5770716bdb0c8b6e9e4c674a447c5085f2 +Author: Ivo Timmermans +Date: Mon May 1 16:28:28 2000 +0000 + + Committed by Lubom�r Bulej. + +commit 33cfdf43f4309c17d6df811b3c5d0af3a1c8679f +Author: Ivo Timmermans +Date: Sun Apr 30 20:48:48 2000 +0000 + + Key forwarding, write one byte extra. + +commit 75d351eaf1264cfb7aa47166469e8ec722712a89 +Author: Ivo Timmermans +Date: Sun Apr 30 19:49:49 2000 +0000 + + Protocol fix (ANS_KEY). This breaks 0.3.3 protocol compatibility. + +commit b4290c3f4360f3cf01bb44957da0d8a20eac75f3 +Author: Ivo Timmermans +Date: Sun Apr 30 19:03:00 2000 +0000 + + Send one less byte from an ANS_KEY request. + +commit d878230ebef5f1a14a23c266dc425666d9e805eb +Author: Ivo Timmermans +Date: Sun Apr 30 18:57:16 2000 +0000 + + Read one less byte from an ANS_KEY request. + +commit 789a4c4f400de31d43b9c5f349f1de417443074a +Author: Ivo Timmermans +Date: Sun Apr 30 16:34:31 2000 +0000 + + Removed debug messages. + +commit eb1c9814e6b2a5206be1fadf19e0dc779690a69e +Author: Ivo Timmermans +Date: Sun Apr 30 16:31:23 2000 +0000 + + Read public keys the right way (tm). + +commit ca73b722cbad5a08ec9bb5026ed5129da9a24bd8 +Author: Ivo Timmermans +Date: Sun Apr 30 16:11:05 2000 +0000 + + New way of handling the meta protocol. + +commit cd12345032e8547a50a1f7450814364f39f0c4ec +Author: Ivo Timmermans +Date: Sun Apr 30 13:23:53 2000 +0000 + + Replaced check for status.active by status.dataopen in check_network_activity. + +commit 4b076ee87fcf8aaf1d9a2bd3c27524b4e3840167 +Author: Ivo Timmermans +Date: Sun Apr 30 01:16:51 2000 +0000 + + Initially, the vpn_mask of a connection is 255.255.255.255 to avoid confusion with lookup_conn. + +commit 1c007c0627ad5e71b8218fcb086240970e955c87 +Author: Ivo Timmermans +Date: Sun Apr 30 01:15:47 2000 +0000 + + Got rid of the nasty hacks... and replaced it by another one. + +commit c02745991422ac3d8097b126e8b256a9b33ad24b +Author: Ivo Timmermans +Date: Sat Apr 29 20:39:36 2000 +0000 + + Filled up the protocol structs with unused bytes. + +commit d3e8e8ca54928e48400584d8a70c42bbf4ae6aeb +Author: Ivo Timmermans +Date: Sat Apr 29 20:38:23 2000 +0000 + + Added `deb' target. + +commit 4dbf7022a25e678969856a38501318db4d420936 +Author: Ivo Timmermans +Date: Sat Apr 29 13:56:06 2000 +0000 + + More updates wrt. the change from tincd->tinc. + +commit 23715510149179089952eef0a2d6f87571ac0e7e +Author: Guus Sliepen +Date: Fri Apr 28 11:33:25 2000 +0000 + + Oops! Reference to write_n() removed and changed into neat write() call. + +commit bb8fff92e1bc594a085c2cbd12b215d334695feb +Author: Guus Sliepen +Date: Thu Apr 27 20:57:18 2000 +0000 + + Removed write_n() function. + +commit 4fec0cc45774ba313d1823cc64c3afdda3204a2e +Author: Ivo Timmermans +Date: Thu Apr 27 13:47:51 2000 +0000 + + Default config file name is tinc.conf, and pidfile is tinc.pid. + +commit eebb708cb29a121ea8d58bb6ca6caf41dea3c3b4 +Author: Ivo Timmermans +Date: Thu Apr 27 00:07:17 2000 +0000 + + Updated version number to 1.0. + +commit 5797d3fcb1ff56ad3ff577f7eb988b70f9d4d709 +Author: Ivo Timmermans +Date: Thu Apr 27 00:01:00 2000 +0000 + + Filled in the details, license from libblowfish copied. + +commit a3ccc15ac0979c4103f98e740b525634e8e17a0a +Author: Ivo Timmermans +Date: Wed Apr 26 23:56:22 2000 +0000 + + Version to 1.0pre1; + Create Makefile and build in debian/. + +commit d928703db1c4aa6caa6e4fbb0894037b10dce820 +Author: Ivo Timmermans +Date: Wed Apr 26 23:23:01 2000 +0000 + + Omit TODO. + +commit d0ea9c8ff287e879e531af9f1b52529421c0512f +Author: Ivo Timmermans +Date: Wed Apr 26 22:42:15 2000 +0000 + + Add an entry to dir. + +commit e5a7291543d41d435cc0fae56e52dc62a119a225 +Author: Ivo Timmermans +Date: Wed Apr 26 22:01:01 2000 +0000 + + The make command is in /usr/bin. + +commit 44f9449888344866406c75b178eff83b392b3530 +Author: Guus Sliepen +Date: Wed Apr 26 17:42:55 2000 +0000 + + Cleanups: + - Changed recv/send calls into read/write calls for streams + - Made all sizeof() functions use a variable name instead of type + +commit fca84d8a7d116c62423faf88e841daf1bee714e1 +Author: Ivo Timmermans +Date: Wed Apr 26 14:54:43 2000 +0000 + + From Mads Kiilerich. + +commit 8efe4874dabdfdf03a747ea98cf38b11cb591ef5 +Author: Guus Sliepen +Date: Tue Apr 25 22:15:28 2000 +0000 + + Converted every &variable[0] to variable. + +commit 643d8712eb2f82bde21f206306cdb6491eee7e08 +Author: Ivo Timmermans +Date: Tue Apr 25 22:00:49 2000 +0000 + + Debug level tweaking. + +commit 468f1d2efcce53937b7f5e0540269ae18f29ebac +Author: Guus Sliepen +Date: Tue Apr 25 20:50:59 2000 +0000 + + When trying to talk to a host that is in the netmask of a tinc server but + not the tinc server itself, and no keys have been exchanged yet, the key + request would be directed to the host instead of the server. Fixed. + +commit 6461a4b607f5e422b5809acb772e4bfe810b5570 +Author: Ivo Timmermans +Date: Tue Apr 25 20:42:54 2000 +0000 + + *** empty log message *** + +commit dad90e82d3c7af95820b1c04903bed7074e2b175 +Author: Guus Sliepen +Date: Tue Apr 25 20:17:44 2000 +0000 + + Fixed typo and removed some unnecessary variables. + +commit 5b7242285795f5143770b663055b87ebb5dd15b8 +Author: Guus Sliepen +Date: Tue Apr 25 20:10:37 2000 +0000 + + Packet queues fixed. They caused the trouble when resending keys. + +commit 04db888b1a94a7d63fdf9800cfd722aa9c16cd26 +Author: Ivo Timmermans +Date: Tue Apr 25 19:23:23 2000 +0000 + + Create a ChangeLog file, automake requires it. + +commit c78b76c53f516cf944ee738fad3e7d4607f282ab +Author: Ivo Timmermans +Date: Tue Apr 25 19:21:19 2000 +0000 + + *** empty log message *** + +commit 45b275e2542b4e8e7deac9e5e9eeddacfdbce90f +Author: Ivo Timmermans +Date: Tue Apr 25 19:11:02 2000 +0000 + + Initial CVS. + +commit 3a3356865267ff4c1e4f7d73f6d1486952d641b5 +Author: Guus Sliepen +Date: Tue Apr 25 18:57:23 2000 +0000 + + Added checkpoints to beginning and ending of every function. + +commit b6bdb9079a9e80b77443efe6c8b6da19e57e8505 +Author: Ivo Timmermans +Date: Tue Apr 25 17:38:54 2000 +0000 + + Remove ChangeLog with a `make cvs-clean'. + +commit ca373c61944a7bd2fe26faf081edea136104d326 +Author: Ivo Timmermans +Date: Tue Apr 25 17:35:45 2000 +0000 + + Don't include TODO in the dist. + +commit e1e590fe9a8c5c767933c68979418911f36d3a89 +Author: Ivo Timmermans +Date: Tue Apr 25 15:08:10 2000 +0000 + + Propagate CFLAGS from configure to gcc. + +commit 8a90de94a1b0e6cdaf51559d44f04a75d5f9ab0e +Author: Ivo Timmermans +Date: Tue Apr 25 15:07:21 2000 +0000 + + Delete all the files that are created by autogen.sh on a `make cvs-clean'. + +commit 24ee68b683de9937e917898075c62ff5f43ee46a +Author: Ivo Timmermans +Date: Tue Apr 25 10:40:08 2000 +0000 + + Spelling fixes. + +commit 4d85552c5bf134ada1d1083ec86dabbe41497c4a +Author: Ivo Timmermans +Date: Tue Apr 25 10:27:44 2000 +0000 + + Contributed by Mads Kiilerich. + +commit 94921d6e57e01b378ab8b1d8ea9cf3da9511fbef +Author: Ivo Timmermans +Date: Tue Apr 25 10:22:26 2000 +0000 + + Generate this Makefile.am from Makefile.am.in. + +commit 8c2b6537d32720b38554815181009c3098423414 +Author: Ivo Timmermans +Date: Tue Apr 25 09:43:50 2000 +0000 + + *** empty log message *** + +commit 03fa76dbf9965cc174eebe8a152307b8fbb63079 +Author: Ivo Timmermans +Date: Tue Apr 25 09:42:52 2000 +0000 + + Added Mads Kiilerich, removed Guus Sliepen. + +commit 7c665712d69d5a502d4c2f098ad85df3b17bfb92 +Author: Ivo Timmermans +Date: Tue Apr 25 01:45:34 2000 +0000 + + Changes largely from Mads Kiilerich. + Removed section about encryption. + +commit ce98ee1ed4121fbbf5d0e13e158511064ced6b16 +Author: Ivo Timmermans +Date: Tue Apr 25 01:26:35 2000 +0000 + + Remove test for GNOME. + +commit 6c99feb3e3cf6d69bcf52ae87b6c64ddbf3ffca5 +Author: Ivo Timmermans +Date: Tue Apr 25 01:25:18 2000 +0000 + + Use `make ChangeLog' to create this file from the CVS logs. + +commit f9eef5210dbc9c0fe54637cc4c3c0be134a51409 +Author: Ivo Timmermans +Date: Tue Apr 25 01:23:31 2000 +0000 + + Don't define HAVE_NAMESPACES and HAVE_STL. + +commit ea9d2f379a170077f93569a957c713452768d0a4 +Author: Ivo Timmermans +Date: Tue Apr 25 01:22:01 2000 +0000 + + Remove check for bigendianness. + +commit 18b204d17a054e991d90b7c4047ea106df64cdaf +Author: Ivo Timmermans +Date: Tue Apr 25 01:15:28 2000 +0000 + + This file is obsolete, most of the ideas are already in echelon. + +commit 62d5384ee01ae818906f2f8ba1456372a13a2420 +Author: Ivo Timmermans +Date: Tue Apr 25 01:10:38 2000 +0000 + + s/Gnome/tinc/g + +commit f0101589959496593db672c6a35704ea5fb33238 +Author: Ivo Timmermans +Date: Tue Apr 25 00:50:48 2000 +0000 + + The shell script autogen.sh can create all these removed files, but be + sure to have autoconf, automake, libtool and more installed. + +commit 6990a7455521665d3b67518e3f2297968108190b +Author: Ivo Timmermans +Date: Tue Apr 25 00:11:33 2000 +0000 + + Don't try to create cipher/idea/Makefile. + +commit cfecc82c9a3f5e8c4648eec058da2c6427cd76af +Author: Ivo Timmermans +Date: Mon Apr 24 21:12:32 2000 +0000 + + Don't include idea/idea.h. + +commit 63540ceff5c7bb7c76d96a4cef4ba803ce915ce1 +Author: Ivo Timmermans +Date: Mon Apr 24 21:10:33 2000 +0000 + + Don't compile in `idea'. + +commit 74315f4218ba50cc5ba32b6ecc8e8afa2b5cd704 +Author: Ivo Timmermans +Date: Mon Apr 24 20:57:22 2000 +0000 + + These files are not needed in release 1.0. + +commit 16d581be68bb52c08569e34e8a6b87f66b87e8ee +Author: Guus Sliepen +Date: Mon Apr 24 09:39:50 2000 +0000 + + Bug found! Wrong pointer was used for handling multiple ADD_HOST requests + at once. (See line 606.) + +commit f6802d349d946090bf9d1b6c761077c80065afa5 +Author: Guus Sliepen +Date: Mon Apr 24 08:32:57 2000 +0000 + + Added extra checks for desynchronized connection lists. Hopefully this will + fix those strange segmentation faults. + +commit 10749179127c681ce040fcf612038174b2bd474a +Author: Ivo Timmermans +Date: Thu Apr 20 22:50:48 2000 +0000 + + Added cvs-clean. + +commit c92701fcf007b67725d82a23ffaef3e6e5c2b0e1 +Author: Ivo Timmermans +Date: Thu Apr 20 19:14:09 2000 +0000 + + Keep make dist(dir) happy. + +commit 7db17968fc84127212ebba0fbccec1e75ced2bdc +Author: Ivo Timmermans +Date: Tue Apr 18 20:44:29 2000 +0000 + + A short notice from Mads Kiilerich. + +commit 2c5a555d7aefcf5699c68cb5d5f00f604b2542c7 +Author: Ivo Timmermans +Date: Tue Apr 18 20:43:24 2000 +0000 + + Submitted changes by Mads Kiilerich. + +commit 375b668dbc1e0268b49ea12901da72bbf5247ce5 +Author: Ivo Timmermans +Date: Tue Apr 18 20:30:20 2000 +0000 + + Include genauth.8 in the distribution. + +commit 57d8c30e4cbecea3b4216e4e650c4c0a3e160ed2 +Author: Ivo Timmermans +Date: Tue Apr 18 20:26:49 2000 +0000 + + Include the directory redhat in the build process. + +commit 0b02ebc4d98182cf79c670e7e556ac7f4f859b75 +Author: Ivo Timmermans +Date: Tue Apr 18 16:04:10 2000 +0000 + + Address for bugreports changed to tinc@nl.linux.org. + +commit 8770211c84cfb69f71bd204926593900d74ab579 +Author: Ivo Timmermans +Date: Tue Apr 18 15:59:42 2000 +0000 + + Updated manpages. + +commit 8cdb84951019feb6d4954cd11eb9663c5b9ce363 +Author: Ivo Timmermans +Date: Tue Apr 18 15:59:22 2000 +0000 + + New manpage for genauth. + +commit d11cfcec74e25ee2b88acea62ca5ef973ab7204b +Author: Ivo Timmermans +Date: Tue Apr 18 15:09:11 2000 +0000 + + Submitted by Mads Kiilerich. + +commit 93287d2b2c77d4b9e3f85f36ef4f9230fe3bf9b3 +Author: Ivo Timmermans +Date: Mon Apr 17 17:04:33 2000 +0000 + + Default passphrase length of 1024, added -h/--help options. + +commit 9c2ac77594d83a810c53faf6979e0b76006ecd0e +Author: Ivo Timmermans +Date: Mon Apr 17 16:59:42 2000 +0000 + + Check if stdout is a terminal, if so, print a verbose message. + +commit c9246896901ff1ebad91ac399a4ea79fad941f75 +Author: Ivo Timmermans +Date: Mon Apr 17 16:52:58 2000 +0000 + + Check for an illegal length of passphrase in read_passphrase(). + +commit baebae274913d912d76ba1d545f337dfb945fc5c +Author: Ivo Timmermans +Date: Mon Apr 17 16:23:29 2000 +0000 + + Pass the requested size from xmalloc() and xrealloc() on to xalloc_fail_func() + +commit 210a92cae90deb5b4a410b1b7d5c625c5c5f2ffb +Author: Ivo Timmermans +Date: Mon Apr 17 15:38:47 2000 +0000 + + Only one round of reading bits out of urandom; + Reading `bytes' bytes out of it; + Print a newline after completion. + +commit 5b44b91eb408d76af646b031da2364a769b44771 +Author: Ivo Timmermans +Date: Wed Apr 12 16:22:39 2000 +0000 + + Moved to version number 1.0. + +commit 18e044bde3b508c991910218989b4bacc3a4934e +Author: Ivo Timmermans +Date: Thu Apr 6 18:28:29 2000 +0000 + + New option -D, don't detach. + +commit 523c80c4e35b7ff8ad94b41a6071dbe2b8ff6ec7 +Author: Ivo Timmermans +Date: Tue Mar 28 19:16:27 2000 +0000 + + Ignore SIGCHLD. + +commit f2076e3e7031ac8ad87eb6aab0cea40f379dd0c6 +Author: Ivo Timmermans +Date: Tue Mar 28 19:09:52 2000 +0000 + + Kill the parent after any error conditions in detach(). + +commit 98de35c742498878a27fb29becd3b7154525a60f +Author: Ivo Timmermans +Date: Mon Mar 27 22:59:16 2000 +0000 + + Upon regeneration, free the old encryption key `securely\' by overwriting it. + +commit b50523dc44bbb32f03d24573e195c071cbff3fc4 +Author: Ivo Timmermans +Date: Mon Mar 27 22:30:27 2000 +0000 + + Get rid of the message `zxnrbl\'. + +commit 1243156a5e03a666b36bc4400f1402243a85c9a7 +Author: Ivo Timmermans +Date: Sun Mar 26 00:33:07 2000 +0000 + + Initial revision diff --git a/Makefile.am b/Makefile.am index 177f549..e69542e 100644 --- a/Makefile.am +++ b/Makefile.am @@ -2,12 +2,14 @@ AUTOMAKE_OPTIONS = gnu -SUBDIRS = src doc gui test systemd +SUBDIRS = src doc test systemd ACLOCAL_AMFLAGS = -I m4 EXTRA_DIST = COPYING.README README.android +@CODE_COVERAGE_RULES@ + # If git describe works, force autoconf to run in order to make sure we have the # current version number from git in the resulting configure script. configure-version: @@ -33,3 +35,6 @@ release: echo "Please edit the NEWS file now..." /usr/bin/editor $(srcdir)/NEWS $(MAKE) dist + +astyle: + astyle --options=.astylerc -nQ src/*.[ch] src/*/*.[ch] diff --git a/Makefile.in b/Makefile.in index f7099d2..e462e23 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15.1 from Makefile.am. +# Makefile.in generated by automake 1.16.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2017 Free Software Foundation, Inc. +# Copyright (C) 1994-2018 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -94,6 +94,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \ $(top_srcdir)/m4/ax_cflags_warn_all.m4 \ $(top_srcdir)/m4/ax_check_compile_flag.m4 \ $(top_srcdir)/m4/ax_check_link_flag.m4 \ + $(top_srcdir)/m4/ax_code_coverage.m4 \ $(top_srcdir)/m4/ax_require_defined.m4 \ $(top_srcdir)/m4/curses.m4 $(top_srcdir)/m4/libgcrypt.m4 \ $(top_srcdir)/m4/lzo.m4 $(top_srcdir)/m4/miniupnpc.m4 \ @@ -143,7 +144,7 @@ am__recursive_targets = \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ - cscope distdir dist dist-all distcheck + cscope distdir distdir-am dist dist-all distcheck am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \ $(LISP)config.h.in # Read a list of newline-separated strings from the standard input, @@ -221,6 +222,12 @@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ +CODE_COVERAGE_CFLAGS = @CODE_COVERAGE_CFLAGS@ +CODE_COVERAGE_CPPFLAGS = @CODE_COVERAGE_CPPFLAGS@ +CODE_COVERAGE_CXXFLAGS = @CODE_COVERAGE_CXXFLAGS@ +CODE_COVERAGE_ENABLED = @CODE_COVERAGE_ENABLED@ +CODE_COVERAGE_LDFLAGS = @CODE_COVERAGE_LDFLAGS@ +CODE_COVERAGE_LIBS = @CODE_COVERAGE_LIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CURSES_LIBS = @CURSES_LIBS@ @@ -232,16 +239,18 @@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ +GCOV = @GCOV@ +GENHTML = @GENHTML@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LCOV = @LCOV@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ -LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MINIUPNPC_LIBS = @MINIUPNPC_LIBS@ @@ -256,6 +265,7 @@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ READLINE_LIBS = @READLINE_LIBS@ +SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ @@ -313,7 +323,7 @@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ AUTOMAKE_OPTIONS = gnu -SUBDIRS = src doc gui test systemd +SUBDIRS = src doc test systemd ACLOCAL_AMFLAGS = -I m4 EXTRA_DIST = COPYING.README README.android all: config.h @@ -341,8 +351,8 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status echo ' $(SHELL) ./config.status'; \ $(SHELL) ./config.status;; \ *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) @@ -475,7 +485,10 @@ distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags -rm -f cscope.out cscope.in.out cscope.po.out cscope.files -distdir: $(DISTFILES) +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) $(am__remove_distdir) test -d "$(distdir)" || mkdir "$(distdir)" @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ @@ -788,6 +801,8 @@ uninstall-am: .PRECIOUS: Makefile +@CODE_COVERAGE_RULES@ + # If git describe works, force autoconf to run in order to make sure we have the # current version number from git in the resulting configure script. configure-version: @@ -814,6 +829,9 @@ release: /usr/bin/editor $(srcdir)/NEWS $(MAKE) dist +astyle: + astyle --options=.astylerc -nQ src/*.[ch] src/*/*.[ch] + # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: diff --git a/NEWS b/NEWS index ec6add6..a458dd9 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,35 @@ +# Version 1.1pre17 October 8 2018 + +* Prevent oracle attacks in the legacy protocol (CVE-2018-16737, + CVE-2018-16738). +* Prevent a MITM from forcing a NULL cipher for UDP in the legacy protocol + (CVE-2018-16758). +* AutoConnect is now enabled by default. +* Per-node network traffic statistics are now shown in the output of "info" and + "dump nodes" commands. + +Thanks to volth and Rafael Sadowski for their contributions to this version of +tinc. + +# Version 1.1pre16 June 12 2018 + +* Fixed building with support for UML sockets. +* Documentation updates and spelling fixes. +* Support for MSS clamping of IP-in-IP packets. +* Fixed parsing of the -b flag. +* Added the ability to set a firemall mark on sockets on Linux. +* Minor improvements to the build system. +* Added a cache of recently seen addresses of peers. +* Add support for --runstatedir to the configure script. +* Fixed linking with libncurses on some distributions. +* Automatically disable PMTUDiscovery when TCPOnly is enabled. +* Fixed removing the tinc service on Windows in some situations. +* Fixed the TAP-Win32 device locking up after waking up from suspend. + +Thanks to Todd C. Miller, Etienne Dechamps, Daniel Lublin, +Gjergji Ramku, Mike Sullivan and Oliver Freyermuth for their +contributions to this version of tinc. + # Version 1.1pre15 September 2 2017 * Detect when the machine is resuming from suspension or hibernation. @@ -12,7 +44,7 @@ * Support PriorityInheritance for IPv6 packets. * Fixes for Solaris tun/tap support. * Add a configurable expiration time for invitations. -* Store invitation data after a succesful join. +* Store invitation data after a successful join. * Exit gracefully when the tun/tap device is in a bad state. * Add the LogLevel option. * AutoConnect now actively tries to heal split networks. @@ -43,7 +75,7 @@ contributions to this version of tinc. * Allow tinc to be compiled without LibreSSL or OpenSSL (this drops compatibility with nodes running 1.0.x). * Added a "fsck" command to check the configuration files for problems. -* Tinc "start" now checks whether the daemon really started succesfully, and +* Tinc "start" now checks whether the daemon really started successfully, and displays error messages otherwise. * Added systemd service files. * Use the recvmmsg() function if available. @@ -378,7 +410,7 @@ their contributions to this version of tinc. * Improved default settings of tun and tap devices on BSD platforms. * Make IPv6 sockets bind only to IPv6 on Linux. * Enable path MTU discovery by default. -* Fixed a memory leak that occured when connections were closed. +* Fixed a memory leak that occurred when connections were closed. Thanks to Max Rijevski for his contributions to this version of tinc. @@ -552,7 +584,7 @@ Thanks to Scott Lamb for his contributions to this version of tinc. * Tinc will retry to connect upon startup, does not quit if it doesn't work the first time. * Hosts that are disconnected implicitly if we lose a connection get - deleted from the internal list, to prevent hogging eachother with + deleted from the internal list, to prevent hogging each other with add and delete requests when the connection is restored. # Version 1.0pre1 May 12 2000 diff --git a/README b/README index d3b8f16..873e2dd 100644 --- a/README +++ b/README @@ -1,7 +1,7 @@ -This is the README file for tinc version 1.1pre15. Installation +This is the README file for tinc version 1.1pre17. Installation instructions may be found in the INSTALL file. -tinc is Copyright © 1998-2017 Ivo Timmermans, Guus Sliepen , and others. +tinc is Copyright © 1998-2018 Ivo Timmermans, Guus Sliepen , and others. For a complete list of authors see the AUTHORS file. @@ -28,11 +28,25 @@ Security statement This version uses an experimental and unfinished cryptographic protocol. Use it at your own risk. +When connecting to nodes that use the legacy protocol used in tinc 1.0, be +aware that any security issues in tinc 1.0 will apply to tinc 1.1 as well. On +September 6th, 2018, Michael Yonly contacted us and provided proof-of-concept +code that allowed a remote attacker to create an authenticated, one-way +connection with a node using the legacy protocol, and also that there was a +possibility for a man-in-the-middle to force UDP packets from a node to be sent +in plaintext. The first issue was trivial to exploit on tinc versions prior to +1.0.30, but the changes in 1.0.30 to mitigate the Sweet32 attack made this +weakness much harder to exploit. These issues have been fixed in tinc 1.0.35 +and tinc 1.1pre17. The new protocol in the tinc 1.1 branch is not susceptible +to these issues. However, be aware that SPTPS is only used between nodes +running tinc 1.1pre* or later, and in a VPN with nodes running different +versions, the security might only be as good as that of the oldest version. + Compatibility ------------- -Version 1.1pre15 is compatible with 1.0pre8, 1.0 and later, but not with older +Version 1.1pre17 is compatible with 1.0pre8, 1.0 and later, but not with older versions of tinc. When the ExperimentalProtocol option is used, tinc is still compatible with @@ -50,9 +64,9 @@ ensure you have the latest stable versions of all the required libraries: The following libraries are used by default, but can be disabled if necessary: -- zlib (http://www.zlib.net/) +- zlib (https://zlib.net/) - LZO (https://www.oberhumer.com/opensource/lzo/) -- ncurses (http://invisible-island.net/ncurses/) +- ncurses (https://invisible-island.net/ncurses/) - readline (https://cnswww.cns.cwru.edu/php/chet/readline/rltop.html) @@ -68,8 +82,8 @@ be forwarded by intermediate nodes. Tinc 1.1 support two protocols. The first is a legacy protocol that provides backwards compatibility with tinc 1.0 nodes, and which by default uses 2048 bit -RSA keys for authentication, and encrypts traffic using Blowfish in CBC mode -and HMAC-SHA1. The second is a new protocol which uses Curve25519 keys for +RSA keys for authentication, and encrypts traffic using AES256 in CBC mode +and HMAC-SHA256. The second is a new protocol which uses Curve25519 keys for authentication, and encrypts traffic using Chacha20-Poly1305, and provides forward secrecy. @@ -82,7 +96,7 @@ Ethernet network switch or hub. Normally, when started tinc will detach and run in the background. In a native Windows environment this means tinc will install itself as a service, which will -restart after reboots. To prevent tinc from detaching or running as a service, +restart after reboots. To prevent tinc from detaching or running as a service, use the -D option. The status of the VPN can be queried using the "tinc" command, which connects diff --git a/THANKS b/THANKS index dfb0365..e814641 100644 --- a/THANKS +++ b/THANKS @@ -5,9 +5,12 @@ We would like to thank the following people for their contributions to tinc: * Alexis Hildebrandt * Allesandro Gatti * Andreas van Cranenburgh +* Andrew Hahn * Anthony G. Basile * Armijn Hemel * Armin Fisslthaler +* Aron Cowan +* Ashish Bajaj * Baptiste Jonglez * Borg * Brandon Black @@ -19,35 +22,41 @@ We would like to thank the following people for their contributions to tinc: * Delf Eldkraft * Dennis Joachimsthaler * dnk +* Élie Bouttier * Enrique Zanardi * Erik Tews * Etienne Dechamps * Florent Clairambault +* Florian Forster * Florian Klink * Florian Weik * Flynn Marquardt * Franz Pletz * Gary Kessler and Claudia Gonzalez * Grzegorz Dymarek +* Gusariev Oleksandr * Hans Bayle * Harvest +* Ivo Smits * Ivo van Dong * James Cook * James MacLean * Jamie Briggs * Jason Harper * Jason Livesay +* Jasper Krijgsman * Jelle de Jong * Jeroen Domburg * Jeroen Ubbink * Jerome Etienne -* Jo-Philipp Wich * Jochen Voss +* Jo-Philipp Wich * Julien Muchembled * Lavrans Laading * Loïc Dachary * Loïc Grenié * Lubomír Bulej +* luckyhacky * LunarShaddow * Mads Kiilerich * Marc A. Lehmann @@ -63,18 +72,22 @@ We would like to thank the following people for their contributions to tinc: * Menno Smits * Mesar Hameed * Michael Tokarev +* Michael Yonli * Miles Nordin -* Nathan Stratton Treadway * Murat Donmez +* Nathan Stratton Treadway * Nick Hibma * Nick Patavalis * Paul Littlefield * Philipp Babel * Pierre Emeriaud +* Pierre-Olivier Mercier +* Rafael Sadowski * Rafał Leśniak * Rhosyn Celyn * Robert van der Meulen * Rumko +* Ryan Miller * Sam Bryan * Samuel Thibault * Saverio Proto @@ -92,6 +105,7 @@ We would like to thank the following people for their contributions to tinc: * Ulrich Seifert * Vil Brekin * Vittorio Gambaletta +* Wendy Willard * Wessel Dankers * William A. Kennington III * William McArthur diff --git a/aclocal.m4 b/aclocal.m4 index d4738fd..4ba9316 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -1,6 +1,6 @@ -# generated automatically by aclocal 1.15.1 -*- Autoconf -*- +# generated automatically by aclocal 1.16.1 -*- Autoconf -*- -# Copyright (C) 1996-2017 Free Software Foundation, Inc. +# Copyright (C) 1996-2018 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -20,7 +20,7 @@ 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'.])]) -# Copyright (C) 2002-2017 Free Software Foundation, Inc. +# Copyright (C) 2002-2018 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -32,10 +32,10 @@ To do so, use the procedure documented by the package, typically 'autoreconf'.]) # generated from the m4 files accompanying Automake X.Y. # (This private macro should not be called outside this file.) AC_DEFUN([AM_AUTOMAKE_VERSION], -[am__api_version='1.15' +[am__api_version='1.16' 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.15.1], [], +m4_if([$1], [1.16.1], [], [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl ]) @@ -51,14 +51,14 @@ 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.15.1])dnl +[AM_AUTOMAKE_VERSION([1.16.1])dnl m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) # AM_AUX_DIR_EXPAND -*- Autoconf -*- -# Copyright (C) 2001-2017 Free Software Foundation, Inc. +# Copyright (C) 2001-2018 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -110,7 +110,7 @@ am_aux_dir=`cd "$ac_aux_dir" && pwd` # AM_CONDITIONAL -*- Autoconf -*- -# Copyright (C) 1997-2017 Free Software Foundation, Inc. +# Copyright (C) 1997-2018 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -141,7 +141,7 @@ AC_CONFIG_COMMANDS_PRE( Usually this means the macro was only invoked conditionally.]]) fi])]) -# Copyright (C) 1999-2017 Free Software Foundation, Inc. +# Copyright (C) 1999-2018 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -332,13 +332,12 @@ _AM_SUBST_NOTMAKE([am__nodep])dnl # Generate code to set up dependency tracking. -*- Autoconf -*- -# Copyright (C) 1999-2017 Free Software Foundation, Inc. +# Copyright (C) 1999-2018 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. - # _AM_OUTPUT_DEPENDENCY_COMMANDS # ------------------------------ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], @@ -346,49 +345,41 @@ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], # Older Autoconf quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. - case $CONFIG_FILES in - *\'*) eval set x "$CONFIG_FILES" ;; - *) set x $CONFIG_FILES ;; - esac + # TODO: see whether this extra hack can be removed once we start + # requiring Autoconf 2.70 or later. + AS_CASE([$CONFIG_FILES], + [*\'*], [eval set x "$CONFIG_FILES"], + [*], [set x $CONFIG_FILES]) shift - for mf + # Used to flag and report bootstrapping failures. + am_rc=0 + for am_mf do # Strip MF so we end up with the name of the file. - mf=`echo "$mf" | sed -e 's/:.*$//'` - # Check whether this is an Automake generated Makefile or not. - # We used to match only the files named 'Makefile.in', but - # some people rename them; so instead we look at the file content. - # Grep'ing the first line is not enough: some people post-process - # each Makefile.in and add a new line on top of each file to say so. - # Grep'ing the whole file is not good either: AIX grep has a line + am_mf=`AS_ECHO(["$am_mf"]) | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile which includes + # dependency-tracking related rules and includes. + # Grep'ing the whole file directly is not great: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. - if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then - dirpart=`AS_DIRNAME("$mf")` - else - continue - fi - # Extract the definition of DEPDIR, am__include, and am__quote - # from the Makefile without running 'make'. - DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` - test -z "$DEPDIR" && continue - am__include=`sed -n 's/^am__include = //p' < "$mf"` - test -z "$am__include" && continue - am__quote=`sed -n 's/^am__quote = //p' < "$mf"` - # Find all dependency output files, they are included files with - # $(DEPDIR) in their names. We invoke sed twice because it is the - # simplest approach to changing $(DEPDIR) to its actual value in the - # expansion. - for file in `sed -n " - s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ - sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do - # Make sure the directory exists. - test -f "$dirpart/$file" && continue - fdir=`AS_DIRNAME(["$file"])` - AS_MKDIR_P([$dirpart/$fdir]) - # echo "creating $dirpart/$file" - echo '# dummy' > "$dirpart/$file" - done + sed -n 's,^am--depfiles:.*,X,p' "$am_mf" | grep X >/dev/null 2>&1 \ + || continue + am_dirpart=`AS_DIRNAME(["$am_mf"])` + am_filepart=`AS_BASENAME(["$am_mf"])` + AM_RUN_LOG([cd "$am_dirpart" \ + && sed -e '/# am--include-marker/d' "$am_filepart" \ + | $MAKE -f - am--depfiles]) || am_rc=$? done + if test $am_rc -ne 0; then + AC_MSG_FAILURE([Something went wrong bootstrapping makefile fragments + for automatic dependency tracking. Try re-running configure with the + '--disable-dependency-tracking' option to at least be able to build + the package (albeit without support for automatic dependency tracking).]) + fi + AS_UNSET([am_dirpart]) + AS_UNSET([am_filepart]) + AS_UNSET([am_mf]) + AS_UNSET([am_rc]) + rm -f conftest-deps.mk } ])# _AM_OUTPUT_DEPENDENCY_COMMANDS @@ -397,18 +388,17 @@ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], # ----------------------------- # This macro should only be invoked once -- use via AC_REQUIRE. # -# This code is only required when automatic dependency tracking -# is enabled. FIXME. This creates each '.P' file that we will -# need in order to bootstrap the dependency handling code. +# This code is only required when automatic dependency tracking is enabled. +# This creates each '.Po' and '.Plo' makefile fragment that we'll need in +# order to bootstrap the dependency handling code. AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], [AC_CONFIG_COMMANDS([depfiles], [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], - [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) -]) + [AMDEP_TRUE="$AMDEP_TRUE" MAKE="${MAKE-make}"])]) # Do all the work for Automake. -*- Autoconf -*- -# Copyright (C) 1996-2017 Free Software Foundation, Inc. +# Copyright (C) 1996-2018 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -495,8 +485,8 @@ AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl AC_REQUIRE([AC_PROG_MKDIR_P])dnl # For better backward compatibility. To be removed once Automake 1.9.x # dies out for good. For more background, see: -# -# +# +# AC_SUBST([mkdir_p], ['$(MKDIR_P)']) # We need awk for the "check" target (and possibly the TAP driver). The # system "awk" is bad on some platforms. @@ -563,7 +553,7 @@ END Aborting the configuration process, to ensure you take notice of the issue. You can download and install GNU coreutils to get an 'rm' implementation -that behaves properly: . +that behaves properly: . If you want to complete the configuration process using your problematic 'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM @@ -605,7 +595,7 @@ for _am_header in $config_headers :; do done echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) -# Copyright (C) 2001-2017 Free Software Foundation, Inc. +# Copyright (C) 2001-2018 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -626,7 +616,7 @@ if test x"${install_sh+set}" != xset; then fi AC_SUBST([install_sh])]) -# Copyright (C) 2003-2017 Free Software Foundation, Inc. +# Copyright (C) 2003-2018 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -647,7 +637,7 @@ AC_SUBST([am__leading_dot])]) # Check to see how 'make' treats includes. -*- Autoconf -*- -# Copyright (C) 2001-2017 Free Software Foundation, Inc. +# Copyright (C) 2001-2018 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -655,49 +645,42 @@ AC_SUBST([am__leading_dot])]) # AM_MAKE_INCLUDE() # ----------------- -# Check to see how make treats includes. +# Check whether make has an 'include' directive that can support all +# the idioms we need for our automatic dependency tracking code. AC_DEFUN([AM_MAKE_INCLUDE], -[am_make=${MAKE-make} -cat > confinc << 'END' +[AC_MSG_CHECKING([whether ${MAKE-make} supports the include directive]) +cat > confinc.mk << 'END' am__doit: - @echo this is the am__doit target + @echo this is the am__doit target >confinc.out .PHONY: am__doit END -# If we don't find an include directive, just comment out the code. -AC_MSG_CHECKING([for style of include used by $am_make]) am__include="#" am__quote= -_am_result=none -# First try GNU make style include. -echo "include confinc" > confmf -# Ignore all kinds of additional output from 'make'. -case `$am_make -s -f confmf 2> /dev/null` in #( -*the\ am__doit\ target*) - am__include=include - am__quote= - _am_result=GNU - ;; -esac -# Now try BSD make style include. -if test "$am__include" = "#"; then - echo '.include "confinc"' > confmf - case `$am_make -s -f confmf 2> /dev/null` in #( - *the\ am__doit\ target*) - am__include=.include - am__quote="\"" - _am_result=BSD - ;; - esac -fi -AC_SUBST([am__include]) -AC_SUBST([am__quote]) -AC_MSG_RESULT([$_am_result]) -rm -f confinc confmf -]) +# BSD make does it like this. +echo '.include "confinc.mk" # ignored' > confmf.BSD +# Other make implementations (GNU, Solaris 10, AIX) do it like this. +echo 'include confinc.mk # ignored' > confmf.GNU +_am_result=no +for s in GNU BSD; do + AM_RUN_LOG([${MAKE-make} -f confmf.$s && cat confinc.out]) + AS_CASE([$?:`cat confinc.out 2>/dev/null`], + ['0:this is the am__doit target'], + [AS_CASE([$s], + [BSD], [am__include='.include' am__quote='"'], + [am__include='include' am__quote=''])]) + if test "$am__include" != "#"; then + _am_result="yes ($s style)" + break + fi +done +rm -f confinc.* confmf.* +AC_MSG_RESULT([${_am_result}]) +AC_SUBST([am__include])]) +AC_SUBST([am__quote])]) # Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- -# Copyright (C) 1997-2017 Free Software Foundation, Inc. +# Copyright (C) 1997-2018 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -736,7 +719,7 @@ fi # Helper functions for option handling. -*- Autoconf -*- -# Copyright (C) 2001-2017 Free Software Foundation, Inc. +# Copyright (C) 2001-2018 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -765,7 +748,7 @@ AC_DEFUN([_AM_SET_OPTIONS], AC_DEFUN([_AM_IF_OPTION], [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) -# Copyright (C) 1999-2017 Free Software Foundation, Inc. +# Copyright (C) 1999-2018 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -812,7 +795,7 @@ AC_LANG_POP([C])]) # For backward compatibility. AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])]) -# Copyright (C) 2001-2017 Free Software Foundation, Inc. +# Copyright (C) 2001-2018 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -831,7 +814,7 @@ AC_DEFUN([AM_RUN_LOG], # Check to make sure that the build environment is sane. -*- Autoconf -*- -# Copyright (C) 1996-2017 Free Software Foundation, Inc. +# Copyright (C) 1996-2018 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -912,7 +895,7 @@ AC_CONFIG_COMMANDS_PRE( rm -f conftest.file ]) -# Copyright (C) 2009-2017 Free Software Foundation, Inc. +# Copyright (C) 2009-2018 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -972,7 +955,7 @@ AC_SUBST([AM_BACKSLASH])dnl _AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl ]) -# Copyright (C) 2001-2017 Free Software Foundation, Inc. +# Copyright (C) 2001-2018 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -1000,7 +983,7 @@ fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" AC_SUBST([INSTALL_STRIP_PROGRAM])]) -# Copyright (C) 2006-2017 Free Software Foundation, Inc. +# Copyright (C) 2006-2018 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -1019,7 +1002,7 @@ AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) # Check how to create a tarball. -*- Autoconf -*- -# Copyright (C) 2004-2017 Free Software Foundation, Inc. +# Copyright (C) 2004-2018 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -1155,6 +1138,7 @@ m4_include([m4/ax_append_flag.m4]) m4_include([m4/ax_cflags_warn_all.m4]) m4_include([m4/ax_check_compile_flag.m4]) m4_include([m4/ax_check_link_flag.m4]) +m4_include([m4/ax_code_coverage.m4]) m4_include([m4/ax_require_defined.m4]) m4_include([m4/curses.m4]) m4_include([m4/libgcrypt.m4]) diff --git a/compile b/compile index a85b723..99e5052 100755 --- a/compile +++ b/compile @@ -1,9 +1,9 @@ #! /bin/sh # Wrapper for compilers which do not understand '-c -o'. -scriptversion=2012-10-14.11; # UTC +scriptversion=2018-03-07.03; # UTC -# Copyright (C) 1999-2014 Free Software Foundation, Inc. +# Copyright (C) 1999-2018 Free Software Foundation, Inc. # Written by Tom Tromey . # # This program is free software; you can redistribute it and/or modify @@ -17,7 +17,7 @@ scriptversion=2012-10-14.11; # UTC # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with this program. If not, see . +# along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a @@ -255,7 +255,8 @@ EOF echo "compile $scriptversion" exit $? ;; - cl | *[/\\]cl | cl.exe | *[/\\]cl.exe ) + cl | *[/\\]cl | cl.exe | *[/\\]cl.exe | \ + icl | *[/\\]icl | icl.exe | *[/\\]icl.exe ) func_cl_wrapper "$@" # Doesn't return... ;; esac @@ -339,9 +340,9 @@ exit $ret # Local Variables: # mode: shell-script # sh-indentation: 2 -# eval: (add-hook 'write-file-hooks 'time-stamp) +# eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" -# time-stamp-time-zone: "UTC" +# time-stamp-time-zone: "UTC0" # time-stamp-end: "; # UTC" # End: diff --git a/config.guess b/config.guess index 2e9ad7f..f50dcdb 100755 --- a/config.guess +++ b/config.guess @@ -1,8 +1,8 @@ #! /bin/sh # Attempt to guess a canonical system name. -# Copyright 1992-2016 Free Software Foundation, Inc. +# Copyright 1992-2018 Free Software Foundation, Inc. -timestamp='2016-10-02' +timestamp='2018-02-24' # 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 @@ -15,7 +15,7 @@ timestamp='2016-10-02' # General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with this program; if not, see . +# along with this program; if not, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a @@ -27,7 +27,7 @@ timestamp='2016-10-02' # Originally written by Per Bothner; maintained since 2000 by Ben Elliston. # # 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 +# https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess # # Please send patches to . @@ -39,7 +39,7 @@ Usage: $0 [OPTION] Output the configuration name of the system \`$me' is run on. -Operation modes: +Options: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit @@ -50,7 +50,7 @@ version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. -Copyright 1992-2016 Free Software Foundation, Inc. +Copyright 1992-2018 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." @@ -107,9 +107,9 @@ trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; dummy=$tmp/dummy ; tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; case $CC_FOR_BUILD,$HOST_CC,$CC in - ,,) echo "int x;" > $dummy.c ; + ,,) echo "int x;" > "$dummy.c" ; for c in cc gcc c89 c99 ; do - if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then + if ($c -c -o "$dummy.o" "$dummy.c") >/dev/null 2>&1 ; then CC_FOR_BUILD="$c"; break ; fi ; done ; @@ -132,14 +132,14 @@ UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown -case "${UNAME_SYSTEM}" in +case "$UNAME_SYSTEM" in Linux|GNU|GNU/*) # If the system lacks a compiler, then just pick glibc. # We could probably try harder. LIBC=gnu - eval $set_cc_for_build - cat <<-EOF > $dummy.c + eval "$set_cc_for_build" + cat <<-EOF > "$dummy.c" #include #if defined(__UCLIBC__) LIBC=uclibc @@ -149,13 +149,20 @@ Linux|GNU|GNU/*) LIBC=gnu #endif EOF - eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC' | sed 's, ,,g'` + eval "`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`" + + # If ldd exists, use it to detect musl libc. + if command -v ldd >/dev/null && \ + ldd --version 2>&1 | grep -q ^musl + then + LIBC=musl + fi ;; esac # Note: order is significant - the case branches are not exclusive. -case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in +case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in *:NetBSD:*:*) # NetBSD (nbsd) targets should (where applicable) match one or # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, @@ -169,30 +176,30 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in # portion of the name. We always set it to "unknown". sysctl="sysctl -n hw.machine_arch" UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \ - /sbin/$sysctl 2>/dev/null || \ - /usr/sbin/$sysctl 2>/dev/null || \ + "/sbin/$sysctl" 2>/dev/null || \ + "/usr/sbin/$sysctl" 2>/dev/null || \ echo unknown)` - case "${UNAME_MACHINE_ARCH}" in + case "$UNAME_MACHINE_ARCH" in armeb) machine=armeb-unknown ;; arm*) machine=arm-unknown ;; sh3el) machine=shl-unknown ;; sh3eb) machine=sh-unknown ;; sh5el) machine=sh5le-unknown ;; earmv*) - arch=`echo ${UNAME_MACHINE_ARCH} | sed -e 's,^e\(armv[0-9]\).*$,\1,'` - endian=`echo ${UNAME_MACHINE_ARCH} | sed -ne 's,^.*\(eb\)$,\1,p'` - machine=${arch}${endian}-unknown + arch=`echo "$UNAME_MACHINE_ARCH" | sed -e 's,^e\(armv[0-9]\).*$,\1,'` + endian=`echo "$UNAME_MACHINE_ARCH" | sed -ne 's,^.*\(eb\)$,\1,p'` + machine="${arch}${endian}"-unknown ;; - *) machine=${UNAME_MACHINE_ARCH}-unknown ;; + *) machine="$UNAME_MACHINE_ARCH"-unknown ;; esac # The Operating System including object format, if it has switched # to ELF recently (or will in the future) and ABI. - case "${UNAME_MACHINE_ARCH}" in + case "$UNAME_MACHINE_ARCH" in earm*) os=netbsdelf ;; arm*|i386|m68k|ns32k|sh3*|sparc|vax) - eval $set_cc_for_build + eval "$set_cc_for_build" if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ELF__ then @@ -208,10 +215,10 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in ;; esac # Determine ABI tags. - case "${UNAME_MACHINE_ARCH}" in + case "$UNAME_MACHINE_ARCH" in earm*) expr='s/^earmv[0-9]/-eabi/;s/eb$//' - abi=`echo ${UNAME_MACHINE_ARCH} | sed -e "$expr"` + abi=`echo "$UNAME_MACHINE_ARCH" | sed -e "$expr"` ;; esac # The OS release @@ -219,46 +226,55 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in # thus, need a distinct triplet. However, they do not need # kernel version information, so it can be replaced with a # suitable tag, in the style of linux-gnu. - case "${UNAME_VERSION}" in + case "$UNAME_VERSION" in Debian*) release='-gnu' ;; *) - release=`echo ${UNAME_RELEASE} | sed -e 's/[-_].*//' | cut -d. -f1,2` + release=`echo "$UNAME_RELEASE" | sed -e 's/[-_].*//' | cut -d. -f1,2` ;; esac # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: # contains redundant information, the shorter form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. - echo "${machine}-${os}${release}${abi}" + echo "$machine-${os}${release}${abi}" exit ;; *:Bitrig:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` - echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE} + echo "$UNAME_MACHINE_ARCH"-unknown-bitrig"$UNAME_RELEASE" exit ;; *:OpenBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` - echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} + echo "$UNAME_MACHINE_ARCH"-unknown-openbsd"$UNAME_RELEASE" exit ;; *:LibertyBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'` - echo ${UNAME_MACHINE_ARCH}-unknown-libertybsd${UNAME_RELEASE} + echo "$UNAME_MACHINE_ARCH"-unknown-libertybsd"$UNAME_RELEASE" + exit ;; + *:MidnightBSD:*:*) + echo "$UNAME_MACHINE"-unknown-midnightbsd"$UNAME_RELEASE" exit ;; *:ekkoBSD:*:*) - echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} + echo "$UNAME_MACHINE"-unknown-ekkobsd"$UNAME_RELEASE" exit ;; *:SolidBSD:*:*) - echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} + echo "$UNAME_MACHINE"-unknown-solidbsd"$UNAME_RELEASE" exit ;; macppc:MirBSD:*:*) - echo powerpc-unknown-mirbsd${UNAME_RELEASE} + echo powerpc-unknown-mirbsd"$UNAME_RELEASE" exit ;; *:MirBSD:*:*) - echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} + echo "$UNAME_MACHINE"-unknown-mirbsd"$UNAME_RELEASE" exit ;; *:Sortix:*:*) - echo ${UNAME_MACHINE}-unknown-sortix + echo "$UNAME_MACHINE"-unknown-sortix exit ;; + *:Redox:*:*) + echo "$UNAME_MACHINE"-unknown-redox + exit ;; + mips:OSF1:*.*) + echo mips-dec-osf1 + exit ;; alpha:OSF1:*:*) case $UNAME_RELEASE in *4.0) @@ -310,28 +326,19 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in # A Tn.n version is a released field test version. # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. - echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` + echo "$UNAME_MACHINE"-dec-osf"`echo "$UNAME_RELEASE" | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`" # Reset EXIT trap before exiting to avoid spurious non-zero exit code. exitcode=$? trap '' 0 exit $exitcode ;; - Alpha\ *:Windows_NT*:*) - # How do we know it's Interix rather than the generic POSIX subsystem? - # Should we change UNAME_MACHINE based on the output of uname instead - # of the specific Alpha model? - echo alpha-pc-interix - exit ;; - 21064:Windows_NT:50:3) - echo alpha-dec-winnt3.5 - exit ;; Amiga*:UNIX_System_V:4.0:*) echo m68k-unknown-sysv4 exit ;; *:[Aa]miga[Oo][Ss]:*:*) - echo ${UNAME_MACHINE}-unknown-amigaos + echo "$UNAME_MACHINE"-unknown-amigaos exit ;; *:[Mm]orph[Oo][Ss]:*:*) - echo ${UNAME_MACHINE}-unknown-morphos + echo "$UNAME_MACHINE"-unknown-morphos exit ;; *:OS/390:*:*) echo i370-ibm-openedition @@ -343,7 +350,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in echo powerpc-ibm-os400 exit ;; arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) - echo arm-acorn-riscix${UNAME_RELEASE} + echo arm-acorn-riscix"$UNAME_RELEASE" exit ;; arm*:riscos:*:*|arm*:RISCOS:*:*) echo arm-unknown-riscos @@ -370,19 +377,19 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in sparc) echo sparc-icl-nx7; exit ;; esac ;; s390x:SunOS:*:*) - echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + echo "$UNAME_MACHINE"-ibm-solaris2"`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`" exit ;; sun4H:SunOS:5.*:*) - echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + echo sparc-hal-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" exit ;; sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) - echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + echo sparc-sun-solaris2"`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`" exit ;; i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) - echo i386-pc-auroraux${UNAME_RELEASE} + echo i386-pc-auroraux"$UNAME_RELEASE" exit ;; i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) - eval $set_cc_for_build + eval "$set_cc_for_build" SUN_ARCH=i386 # If there is a compiler, see if it is configured for 64-bit objects. # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. @@ -395,13 +402,13 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in SUN_ARCH=x86_64 fi fi - echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + echo "$SUN_ARCH"-pc-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" exit ;; sun4*:SunOS:6*:*) # According to config.sub, this is the proper way to canonicalize # SunOS6. Hard to guess exactly what SunOS6 will be like, but # it's likely to be more like Solaris than SunOS4. - echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + echo sparc-sun-solaris3"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" exit ;; sun4*:SunOS:*:*) case "`/usr/bin/arch -k`" in @@ -410,25 +417,25 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in ;; esac # Japanese Language versions have a version number like `4.1.3-JL'. - echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` + echo sparc-sun-sunos"`echo "$UNAME_RELEASE"|sed -e 's/-/_/'`" exit ;; sun3*:SunOS:*:*) - echo m68k-sun-sunos${UNAME_RELEASE} + echo m68k-sun-sunos"$UNAME_RELEASE" exit ;; sun*:*:4.2BSD:*) UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` - test "x${UNAME_RELEASE}" = x && UNAME_RELEASE=3 + test "x$UNAME_RELEASE" = x && UNAME_RELEASE=3 case "`/bin/arch`" in sun3) - echo m68k-sun-sunos${UNAME_RELEASE} + echo m68k-sun-sunos"$UNAME_RELEASE" ;; sun4) - echo sparc-sun-sunos${UNAME_RELEASE} + echo sparc-sun-sunos"$UNAME_RELEASE" ;; esac exit ;; aushp:SunOS:*:*) - echo sparc-auspex-sunos${UNAME_RELEASE} + echo sparc-auspex-sunos"$UNAME_RELEASE" exit ;; # The situation for MiNT is a little confusing. The machine name # can be virtually everything (everything which is not @@ -439,44 +446,44 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in # MiNT. But MiNT is downward compatible to TOS, so this should # be no problem. atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} + echo m68k-atari-mint"$UNAME_RELEASE" exit ;; atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} + echo m68k-atari-mint"$UNAME_RELEASE" exit ;; *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} + echo m68k-atari-mint"$UNAME_RELEASE" exit ;; milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) - echo m68k-milan-mint${UNAME_RELEASE} + echo m68k-milan-mint"$UNAME_RELEASE" exit ;; hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) - echo m68k-hades-mint${UNAME_RELEASE} + echo m68k-hades-mint"$UNAME_RELEASE" exit ;; *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) - echo m68k-unknown-mint${UNAME_RELEASE} + echo m68k-unknown-mint"$UNAME_RELEASE" exit ;; m68k:machten:*:*) - echo m68k-apple-machten${UNAME_RELEASE} + echo m68k-apple-machten"$UNAME_RELEASE" exit ;; powerpc:machten:*:*) - echo powerpc-apple-machten${UNAME_RELEASE} + echo powerpc-apple-machten"$UNAME_RELEASE" exit ;; RISC*:Mach:*:*) echo mips-dec-mach_bsd4.3 exit ;; RISC*:ULTRIX:*:*) - echo mips-dec-ultrix${UNAME_RELEASE} + echo mips-dec-ultrix"$UNAME_RELEASE" exit ;; VAX*:ULTRIX*:*:*) - echo vax-dec-ultrix${UNAME_RELEASE} + echo vax-dec-ultrix"$UNAME_RELEASE" exit ;; 2020:CLIX:*:* | 2430:CLIX:*:*) - echo clipper-intergraph-clix${UNAME_RELEASE} + echo clipper-intergraph-clix"$UNAME_RELEASE" exit ;; mips:*:*:UMIPS | mips:*:*:RISCos) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c + eval "$set_cc_for_build" + sed 's/^ //' << EOF > "$dummy.c" #ifdef __cplusplus #include /* for printf() prototype */ int main (int argc, char *argv[]) { @@ -485,23 +492,23 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in #endif #if defined (host_mips) && defined (MIPSEB) #if defined (SYSTYPE_SYSV) - printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); + printf ("mips-mips-riscos%ssysv\\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_SVR4) - printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); + printf ("mips-mips-riscos%ssvr4\\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) - printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); + printf ("mips-mips-riscos%sbsd\\n", argv[1]); exit (0); #endif #endif exit (-1); } EOF - $CC_FOR_BUILD -o $dummy $dummy.c && - dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && - SYSTEM_NAME=`$dummy $dummyarg` && + $CC_FOR_BUILD -o "$dummy" "$dummy.c" && + dummyarg=`echo "$UNAME_RELEASE" | sed -n 's/\([0-9]*\).*/\1/p'` && + SYSTEM_NAME=`"$dummy" "$dummyarg"` && { echo "$SYSTEM_NAME"; exit; } - echo mips-mips-riscos${UNAME_RELEASE} + echo mips-mips-riscos"$UNAME_RELEASE" exit ;; Motorola:PowerMAX_OS:*:*) echo powerpc-motorola-powermax @@ -527,17 +534,17 @@ EOF AViiON:dgux:*:*) # DG/UX returns AViiON for all architectures UNAME_PROCESSOR=`/usr/bin/uname -p` - if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] + if [ "$UNAME_PROCESSOR" = mc88100 ] || [ "$UNAME_PROCESSOR" = mc88110 ] then - if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ - [ ${TARGET_BINARY_INTERFACE}x = x ] + if [ "$TARGET_BINARY_INTERFACE"x = m88kdguxelfx ] || \ + [ "$TARGET_BINARY_INTERFACE"x = x ] then - echo m88k-dg-dgux${UNAME_RELEASE} + echo m88k-dg-dgux"$UNAME_RELEASE" else - echo m88k-dg-dguxbcs${UNAME_RELEASE} + echo m88k-dg-dguxbcs"$UNAME_RELEASE" fi else - echo i586-dg-dgux${UNAME_RELEASE} + echo i586-dg-dgux"$UNAME_RELEASE" fi exit ;; M88*:DolphinOS:*:*) # DolphinOS (SVR3) @@ -554,7 +561,7 @@ EOF echo m68k-tektronix-bsd exit ;; *:IRIX*:*:*) - echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + echo mips-sgi-irix"`echo "$UNAME_RELEASE"|sed -e 's/-/_/g'`" exit ;; ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id @@ -566,14 +573,14 @@ EOF if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else - IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + IBM_REV="$UNAME_VERSION.$UNAME_RELEASE" fi - echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} + echo "$UNAME_MACHINE"-ibm-aix"$IBM_REV" exit ;; *:AIX:2:3) if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c + eval "$set_cc_for_build" + sed 's/^ //' << EOF > "$dummy.c" #include main() @@ -584,7 +591,7 @@ EOF exit(0); } EOF - if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` + if $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` then echo "$SYSTEM_NAME" else @@ -598,7 +605,7 @@ EOF exit ;; *:AIX:*:[4567]) IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` - if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then + if /usr/sbin/lsattr -El "$IBM_CPU_ID" | grep ' POWER' >/dev/null 2>&1; then IBM_ARCH=rs6000 else IBM_ARCH=powerpc @@ -607,18 +614,18 @@ EOF IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc | awk -F: '{ print $3 }' | sed s/[0-9]*$/0/` else - IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + IBM_REV="$UNAME_VERSION.$UNAME_RELEASE" fi - echo ${IBM_ARCH}-ibm-aix${IBM_REV} + echo "$IBM_ARCH"-ibm-aix"$IBM_REV" exit ;; *:AIX:*:*) echo rs6000-ibm-aix exit ;; - ibmrt:4.4BSD:*|romp-ibm:BSD:*) + ibmrt:4.4BSD:*|romp-ibm:4.4BSD:*) echo romp-ibm-bsd4.4 exit ;; ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and - echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + echo romp-ibm-bsd"$UNAME_RELEASE" # 4.3 with uname added to exit ;; # report: romp-ibm BSD 4.3 *:BOSX:*:*) echo rs6000-bull-bosx @@ -633,28 +640,28 @@ EOF echo m68k-hp-bsd4.4 exit ;; 9000/[34678]??:HP-UX:*:*) - HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` - case "${UNAME_MACHINE}" in - 9000/31? ) HP_ARCH=m68000 ;; - 9000/[34]?? ) HP_ARCH=m68k ;; + HPUX_REV=`echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//'` + case "$UNAME_MACHINE" in + 9000/31?) HP_ARCH=m68000 ;; + 9000/[34]??) HP_ARCH=m68k ;; 9000/[678][0-9][0-9]) if [ -x /usr/bin/getconf ]; then sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` - case "${sc_cpu_version}" in + case "$sc_cpu_version" in 523) HP_ARCH=hppa1.0 ;; # CPU_PA_RISC1_0 528) HP_ARCH=hppa1.1 ;; # CPU_PA_RISC1_1 532) # CPU_PA_RISC2_0 - case "${sc_kernel_bits}" in + case "$sc_kernel_bits" in 32) HP_ARCH=hppa2.0n ;; 64) HP_ARCH=hppa2.0w ;; '') HP_ARCH=hppa2.0 ;; # HP-UX 10.20 esac ;; esac fi - if [ "${HP_ARCH}" = "" ]; then - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c + if [ "$HP_ARCH" = "" ]; then + eval "$set_cc_for_build" + sed 's/^ //' << EOF > "$dummy.c" #define _HPUX_SOURCE #include @@ -687,13 +694,13 @@ EOF exit (0); } EOF - (CCOPTS="" $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` + (CCOPTS="" $CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null) && HP_ARCH=`"$dummy"` test -z "$HP_ARCH" && HP_ARCH=hppa fi ;; esac - if [ ${HP_ARCH} = hppa2.0w ] + if [ "$HP_ARCH" = hppa2.0w ] then - eval $set_cc_for_build + eval "$set_cc_for_build" # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler @@ -712,15 +719,15 @@ EOF HP_ARCH=hppa64 fi fi - echo ${HP_ARCH}-hp-hpux${HPUX_REV} + echo "$HP_ARCH"-hp-hpux"$HPUX_REV" exit ;; ia64:HP-UX:*:*) - HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` - echo ia64-hp-hpux${HPUX_REV} + HPUX_REV=`echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux"$HPUX_REV" exit ;; 3050*:HI-UX:*:*) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c + eval "$set_cc_for_build" + sed 's/^ //' << EOF > "$dummy.c" #include int main () @@ -745,11 +752,11 @@ EOF exit (0); } EOF - $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && + $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` && { echo "$SYSTEM_NAME"; exit; } echo unknown-hitachi-hiuxwe2 exit ;; - 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:*) echo hppa1.1-hp-bsd exit ;; 9000/8??:4.3bsd:*:*) @@ -758,7 +765,7 @@ EOF *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) echo hppa1.0-hp-mpeix exit ;; - hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:*) echo hppa1.1-hp-osf exit ;; hp8??:OSF1:*:*) @@ -766,9 +773,9 @@ EOF exit ;; i*86:OSF1:*:*) if [ -x /usr/sbin/sysversion ] ; then - echo ${UNAME_MACHINE}-unknown-osf1mk + echo "$UNAME_MACHINE"-unknown-osf1mk else - echo ${UNAME_MACHINE}-unknown-osf1 + echo "$UNAME_MACHINE"-unknown-osf1 fi exit ;; parisc*:Lites*:*:*) @@ -793,127 +800,109 @@ EOF echo c4-convex-bsd exit ;; CRAY*Y-MP:*:*:*) - echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + echo ymp-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*[A-Z]90:*:*:*) - echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + echo "$UNAME_MACHINE"-cray-unicos"$UNAME_RELEASE" \ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ -e 's/\.[^.]*$/.X/' exit ;; CRAY*TS:*:*:*) - echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + echo t90-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*T3E:*:*:*) - echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + echo alphaev5-cray-unicosmk"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*SV1:*:*:*) - echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + echo sv1-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' exit ;; *:UNICOS/mp:*:*) - echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + echo craynv-cray-unicosmp"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' exit ;; F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) FUJITSU_PROC=`uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` - FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + FUJITSU_REL=`echo "$UNAME_RELEASE" | sed -e 's/ /_/'` echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; 5000:UNIX_System_V:4.*:*) FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` - FUJITSU_REL=`echo ${UNAME_RELEASE} | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'` + FUJITSU_REL=`echo "$UNAME_RELEASE" | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'` echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) - echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + echo "$UNAME_MACHINE"-pc-bsdi"$UNAME_RELEASE" exit ;; sparc*:BSD/OS:*:*) - echo sparc-unknown-bsdi${UNAME_RELEASE} + echo sparc-unknown-bsdi"$UNAME_RELEASE" exit ;; *:BSD/OS:*:*) - echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + echo "$UNAME_MACHINE"-unknown-bsdi"$UNAME_RELEASE" exit ;; *:FreeBSD:*:*) UNAME_PROCESSOR=`/usr/bin/uname -p` - case ${UNAME_PROCESSOR} in + case "$UNAME_PROCESSOR" in amd64) - echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; - *) - echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + UNAME_PROCESSOR=x86_64 ;; + i386) + UNAME_PROCESSOR=i586 ;; esac + echo "$UNAME_PROCESSOR"-unknown-freebsd"`echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`" exit ;; i*:CYGWIN*:*) - echo ${UNAME_MACHINE}-pc-cygwin + echo "$UNAME_MACHINE"-pc-cygwin exit ;; *:MINGW64*:*) - echo ${UNAME_MACHINE}-pc-mingw64 + echo "$UNAME_MACHINE"-pc-mingw64 exit ;; *:MINGW*:*) - echo ${UNAME_MACHINE}-pc-mingw32 + echo "$UNAME_MACHINE"-pc-mingw32 exit ;; *:MSYS*:*) - echo ${UNAME_MACHINE}-pc-msys - exit ;; - i*:windows32*:*) - # uname -m includes "-pc" on this system. - echo ${UNAME_MACHINE}-mingw32 + echo "$UNAME_MACHINE"-pc-msys exit ;; i*:PW*:*) - echo ${UNAME_MACHINE}-pc-pw32 + echo "$UNAME_MACHINE"-pc-pw32 exit ;; *:Interix*:*) - case ${UNAME_MACHINE} in + case "$UNAME_MACHINE" in x86) - echo i586-pc-interix${UNAME_RELEASE} + echo i586-pc-interix"$UNAME_RELEASE" exit ;; authenticamd | genuineintel | EM64T) - echo x86_64-unknown-interix${UNAME_RELEASE} + echo x86_64-unknown-interix"$UNAME_RELEASE" exit ;; IA64) - echo ia64-unknown-interix${UNAME_RELEASE} + echo ia64-unknown-interix"$UNAME_RELEASE" exit ;; esac ;; - [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) - echo i${UNAME_MACHINE}-pc-mks - exit ;; - 8664:Windows_NT:*) - echo x86_64-pc-mks - exit ;; - i*:Windows_NT*:* | Pentium*:Windows_NT*:*) - # How do we know it's Interix rather than the generic POSIX subsystem? - # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we - # UNAME_MACHINE based on the output of uname instead of i386? - echo i586-pc-interix - exit ;; i*:UWIN*:*) - echo ${UNAME_MACHINE}-pc-uwin + echo "$UNAME_MACHINE"-pc-uwin exit ;; amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) echo x86_64-unknown-cygwin exit ;; - p*:CYGWIN*:*) - echo powerpcle-unknown-cygwin - exit ;; prep*:SunOS:5.*:*) - echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + echo powerpcle-unknown-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" exit ;; *:GNU:*:*) # the GNU system - echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + echo "`echo "$UNAME_MACHINE"|sed -e 's,[-/].*$,,'`-unknown-$LIBC`echo "$UNAME_RELEASE"|sed -e 's,/.*$,,'`" exit ;; *:GNU/*:*:*) # other systems with GNU libc and userland - echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC} + echo "$UNAME_MACHINE-unknown-`echo "$UNAME_SYSTEM" | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"``echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`-$LIBC" exit ;; i*86:Minix:*:*) - echo ${UNAME_MACHINE}-pc-minix + echo "$UNAME_MACHINE"-pc-minix exit ;; aarch64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; aarch64_be:Linux:*:*) UNAME_MACHINE=aarch64_be - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; alpha:Linux:*:*) case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in @@ -927,63 +916,63 @@ EOF esac objdump --private-headers /bin/sh | grep -q ld.so.1 if test "$?" = 0 ; then LIBC=gnulibc1 ; fi - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; arc:Linux:*:* | arceb:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; arm*:Linux:*:*) - eval $set_cc_for_build + eval "$set_cc_for_build" if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_EABI__ then - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" else if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_PCS_VFP then - echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"eabi else - echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"eabihf fi fi exit ;; avr32*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; cris:Linux:*:*) - echo ${UNAME_MACHINE}-axis-linux-${LIBC} + echo "$UNAME_MACHINE"-axis-linux-"$LIBC" exit ;; crisv32:Linux:*:*) - echo ${UNAME_MACHINE}-axis-linux-${LIBC} + echo "$UNAME_MACHINE"-axis-linux-"$LIBC" exit ;; e2k:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; frv:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; hexagon:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; i*86:Linux:*:*) - echo ${UNAME_MACHINE}-pc-linux-${LIBC} + echo "$UNAME_MACHINE"-pc-linux-"$LIBC" exit ;; ia64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; k1om:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; m32r*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; m68*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; mips:Linux:*:* | mips64:Linux:*:*) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c + eval "$set_cc_for_build" + sed 's/^ //' << EOF > "$dummy.c" #undef CPU #undef ${UNAME_MACHINE} #undef ${UNAME_MACHINE}el @@ -997,70 +986,74 @@ EOF #endif #endif EOF - eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` - test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; } + eval "`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^CPU'`" + test "x$CPU" != x && { echo "$CPU-unknown-linux-$LIBC"; exit; } ;; mips64el:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; openrisc*:Linux:*:*) - echo or1k-unknown-linux-${LIBC} + echo or1k-unknown-linux-"$LIBC" exit ;; or32:Linux:*:* | or1k*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; padre:Linux:*:*) - echo sparc-unknown-linux-${LIBC} + echo sparc-unknown-linux-"$LIBC" exit ;; parisc64:Linux:*:* | hppa64:Linux:*:*) - echo hppa64-unknown-linux-${LIBC} + echo hppa64-unknown-linux-"$LIBC" exit ;; parisc:Linux:*:* | hppa:Linux:*:*) # Look for CPU level case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in - PA7*) echo hppa1.1-unknown-linux-${LIBC} ;; - PA8*) echo hppa2.0-unknown-linux-${LIBC} ;; - *) echo hppa-unknown-linux-${LIBC} ;; + PA7*) echo hppa1.1-unknown-linux-"$LIBC" ;; + PA8*) echo hppa2.0-unknown-linux-"$LIBC" ;; + *) echo hppa-unknown-linux-"$LIBC" ;; esac exit ;; ppc64:Linux:*:*) - echo powerpc64-unknown-linux-${LIBC} + echo powerpc64-unknown-linux-"$LIBC" exit ;; ppc:Linux:*:*) - echo powerpc-unknown-linux-${LIBC} + echo powerpc-unknown-linux-"$LIBC" exit ;; ppc64le:Linux:*:*) - echo powerpc64le-unknown-linux-${LIBC} + echo powerpc64le-unknown-linux-"$LIBC" exit ;; ppcle:Linux:*:*) - echo powerpcle-unknown-linux-${LIBC} + echo powerpcle-unknown-linux-"$LIBC" exit ;; riscv32:Linux:*:* | riscv64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; s390:Linux:*:* | s390x:Linux:*:*) - echo ${UNAME_MACHINE}-ibm-linux-${LIBC} + echo "$UNAME_MACHINE"-ibm-linux-"$LIBC" exit ;; sh64*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; sh*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; sparc:Linux:*:* | sparc64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; tile*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; vax:Linux:*:*) - echo ${UNAME_MACHINE}-dec-linux-${LIBC} + echo "$UNAME_MACHINE"-dec-linux-"$LIBC" exit ;; x86_64:Linux:*:*) - echo ${UNAME_MACHINE}-pc-linux-${LIBC} + if objdump -f /bin/sh | grep -q elf32-x86-64; then + echo "$UNAME_MACHINE"-pc-linux-"$LIBC"x32 + else + echo "$UNAME_MACHINE"-pc-linux-"$LIBC" + fi exit ;; xtensa*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; i*86:DYNIX/ptx:4*:*) # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. @@ -1074,34 +1067,34 @@ EOF # I am not positive that other SVR4 systems won't match this, # I just have to hope. -- rms. # Use sysv4.2uw... so that sysv4* matches it. - echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} + echo "$UNAME_MACHINE"-pc-sysv4.2uw"$UNAME_VERSION" exit ;; i*86:OS/2:*:*) # If we were able to find `uname', then EMX Unix compatibility # is probably installed. - echo ${UNAME_MACHINE}-pc-os2-emx + echo "$UNAME_MACHINE"-pc-os2-emx exit ;; i*86:XTS-300:*:STOP) - echo ${UNAME_MACHINE}-unknown-stop + echo "$UNAME_MACHINE"-unknown-stop exit ;; i*86:atheos:*:*) - echo ${UNAME_MACHINE}-unknown-atheos + echo "$UNAME_MACHINE"-unknown-atheos exit ;; i*86:syllable:*:*) - echo ${UNAME_MACHINE}-pc-syllable + echo "$UNAME_MACHINE"-pc-syllable exit ;; i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) - echo i386-unknown-lynxos${UNAME_RELEASE} + echo i386-unknown-lynxos"$UNAME_RELEASE" exit ;; i*86:*DOS:*:*) - echo ${UNAME_MACHINE}-pc-msdosdjgpp + echo "$UNAME_MACHINE"-pc-msdosdjgpp exit ;; - i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) - UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` + i*86:*:4.*:*) + UNAME_REL=`echo "$UNAME_RELEASE" | sed 's/\/MP$//'` if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then - echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} + echo "$UNAME_MACHINE"-univel-sysv"$UNAME_REL" else - echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} + echo "$UNAME_MACHINE"-pc-sysv"$UNAME_REL" fi exit ;; i*86:*:5:[678]*) @@ -1111,12 +1104,12 @@ EOF *Pentium) UNAME_MACHINE=i586 ;; *Pent*|*Celeron) UNAME_MACHINE=i686 ;; esac - echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} + echo "$UNAME_MACHINE-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}{$UNAME_VERSION}" exit ;; i*86:*:3.2:*) if test -f /usr/options/cb.name; then UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 @@ -1126,9 +1119,9 @@ EOF && UNAME_MACHINE=i686 (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ && UNAME_MACHINE=i686 - echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + echo "$UNAME_MACHINE"-pc-sco"$UNAME_REL" else - echo ${UNAME_MACHINE}-pc-sysv32 + echo "$UNAME_MACHINE"-pc-sysv32 fi exit ;; pc:*:*:*) @@ -1148,9 +1141,9 @@ EOF exit ;; i860:*:4.*:*) # i860-SVR4 if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then - echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + echo i860-stardent-sysv"$UNAME_RELEASE" # Stardent Vistra i860-SVR4 else # Add other i860-SVR4 vendors below as they are discovered. - echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + echo i860-unknown-sysv"$UNAME_RELEASE" # Unknown i860-SVR4 fi exit ;; mini*:CTIX:SYS*5:*) @@ -1170,9 +1163,9 @@ EOF test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + && { echo i486-ncr-sysv4.3"$OS_REL"; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ - && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;; 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4; exit; } ;; @@ -1181,28 +1174,28 @@ EOF test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + && { echo i486-ncr-sysv4.3"$OS_REL"; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ - && { echo i586-ncr-sysv4.3${OS_REL}; exit; } + && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ - && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;; m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) - echo m68k-unknown-lynxos${UNAME_RELEASE} + echo m68k-unknown-lynxos"$UNAME_RELEASE" exit ;; mc68030:UNIX_System_V:4.*:*) echo m68k-atari-sysv4 exit ;; TSUNAMI:LynxOS:2.*:*) - echo sparc-unknown-lynxos${UNAME_RELEASE} + echo sparc-unknown-lynxos"$UNAME_RELEASE" exit ;; rs6000:LynxOS:2.*:*) - echo rs6000-unknown-lynxos${UNAME_RELEASE} + echo rs6000-unknown-lynxos"$UNAME_RELEASE" exit ;; PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) - echo powerpc-unknown-lynxos${UNAME_RELEASE} + echo powerpc-unknown-lynxos"$UNAME_RELEASE" exit ;; SM[BE]S:UNIX_SV:*:*) - echo mips-dde-sysv${UNAME_RELEASE} + echo mips-dde-sysv"$UNAME_RELEASE" exit ;; RM*:ReliantUNIX-*:*:*) echo mips-sni-sysv4 @@ -1213,7 +1206,7 @@ EOF *:SINIX-*:*:*) if uname -p 2>/dev/null >/dev/null ; then UNAME_MACHINE=`(uname -p) 2>/dev/null` - echo ${UNAME_MACHINE}-sni-sysv4 + echo "$UNAME_MACHINE"-sni-sysv4 else echo ns32k-sni-sysv fi @@ -1233,23 +1226,23 @@ EOF exit ;; i*86:VOS:*:*) # From Paul.Green@stratus.com. - echo ${UNAME_MACHINE}-stratus-vos + echo "$UNAME_MACHINE"-stratus-vos exit ;; *:VOS:*:*) # From Paul.Green@stratus.com. echo hppa1.1-stratus-vos exit ;; mc68*:A/UX:*:*) - echo m68k-apple-aux${UNAME_RELEASE} + echo m68k-apple-aux"$UNAME_RELEASE" exit ;; news*:NEWS-OS:6*:*) echo mips-sony-newsos6 exit ;; R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) if [ -d /usr/nec ]; then - echo mips-nec-sysv${UNAME_RELEASE} + echo mips-nec-sysv"$UNAME_RELEASE" else - echo mips-unknown-sysv${UNAME_RELEASE} + echo mips-unknown-sysv"$UNAME_RELEASE" fi exit ;; BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. @@ -1268,49 +1261,56 @@ EOF echo x86_64-unknown-haiku exit ;; SX-4:SUPER-UX:*:*) - echo sx4-nec-superux${UNAME_RELEASE} + echo sx4-nec-superux"$UNAME_RELEASE" exit ;; SX-5:SUPER-UX:*:*) - echo sx5-nec-superux${UNAME_RELEASE} + echo sx5-nec-superux"$UNAME_RELEASE" exit ;; SX-6:SUPER-UX:*:*) - echo sx6-nec-superux${UNAME_RELEASE} + echo sx6-nec-superux"$UNAME_RELEASE" exit ;; SX-7:SUPER-UX:*:*) - echo sx7-nec-superux${UNAME_RELEASE} + echo sx7-nec-superux"$UNAME_RELEASE" exit ;; SX-8:SUPER-UX:*:*) - echo sx8-nec-superux${UNAME_RELEASE} + echo sx8-nec-superux"$UNAME_RELEASE" exit ;; SX-8R:SUPER-UX:*:*) - echo sx8r-nec-superux${UNAME_RELEASE} + echo sx8r-nec-superux"$UNAME_RELEASE" exit ;; SX-ACE:SUPER-UX:*:*) - echo sxace-nec-superux${UNAME_RELEASE} + echo sxace-nec-superux"$UNAME_RELEASE" exit ;; Power*:Rhapsody:*:*) - echo powerpc-apple-rhapsody${UNAME_RELEASE} + echo powerpc-apple-rhapsody"$UNAME_RELEASE" exit ;; *:Rhapsody:*:*) - echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + echo "$UNAME_MACHINE"-apple-rhapsody"$UNAME_RELEASE" exit ;; *:Darwin:*:*) UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown - eval $set_cc_for_build + eval "$set_cc_for_build" if test "$UNAME_PROCESSOR" = unknown ; then UNAME_PROCESSOR=powerpc fi - if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then + if test "`echo "$UNAME_RELEASE" | sed -e 's/\..*//'`" -le 10 ; then 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 + (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null then case $UNAME_PROCESSOR in i386) UNAME_PROCESSOR=x86_64 ;; powerpc) UNAME_PROCESSOR=powerpc64 ;; esac fi + # On 10.4-10.6 one might compile for PowerPC via gcc -arch ppc + if (echo '#ifdef __POWERPC__'; echo IS_PPC; echo '#endif') | \ + (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_PPC >/dev/null + then + UNAME_PROCESSOR=powerpc + fi fi elif test "$UNAME_PROCESSOR" = i386 ; then # Avoid executing cc on OS X 10.9, as it ships with a stub @@ -1321,7 +1321,7 @@ EOF # that Apple uses in portable devices. UNAME_PROCESSOR=x86_64 fi - echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} + echo "$UNAME_PROCESSOR"-apple-darwin"$UNAME_RELEASE" exit ;; *:procnto*:*:* | *:QNX:[0123456789]*:*) UNAME_PROCESSOR=`uname -p` @@ -1329,19 +1329,25 @@ EOF UNAME_PROCESSOR=i386 UNAME_MACHINE=pc fi - echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} + echo "$UNAME_PROCESSOR"-"$UNAME_MACHINE"-nto-qnx"$UNAME_RELEASE" exit ;; *:QNX:*:4*) echo i386-pc-qnx exit ;; - NEO-?:NONSTOP_KERNEL:*:*) - echo neo-tandem-nsk${UNAME_RELEASE} + NEO-*:NONSTOP_KERNEL:*:*) + echo neo-tandem-nsk"$UNAME_RELEASE" exit ;; NSE-*:NONSTOP_KERNEL:*:*) - echo nse-tandem-nsk${UNAME_RELEASE} + echo nse-tandem-nsk"$UNAME_RELEASE" exit ;; - NSR-?:NONSTOP_KERNEL:*:*) - echo nsr-tandem-nsk${UNAME_RELEASE} + NSR-*:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk"$UNAME_RELEASE" + exit ;; + NSV-*:NONSTOP_KERNEL:*:*) + echo nsv-tandem-nsk"$UNAME_RELEASE" + exit ;; + NSX-*:NONSTOP_KERNEL:*:*) + echo nsx-tandem-nsk"$UNAME_RELEASE" exit ;; *:NonStop-UX:*:*) echo mips-compaq-nonstopux @@ -1350,7 +1356,7 @@ EOF echo bs2000-siemens-sysv exit ;; DS/*:UNIX_System_V:*:*) - echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} + echo "$UNAME_MACHINE"-"$UNAME_SYSTEM"-"$UNAME_RELEASE" exit ;; *:Plan9:*:*) # "uname -m" is not consistent, so use $cputype instead. 386 @@ -1361,7 +1367,7 @@ EOF else UNAME_MACHINE="$cputype" fi - echo ${UNAME_MACHINE}-unknown-plan9 + echo "$UNAME_MACHINE"-unknown-plan9 exit ;; *:TOPS-10:*:*) echo pdp10-unknown-tops10 @@ -1382,14 +1388,14 @@ EOF echo pdp10-unknown-its exit ;; SEI:*:*:SEIUX) - echo mips-sei-seiux${UNAME_RELEASE} + echo mips-sei-seiux"$UNAME_RELEASE" exit ;; *:DragonFly:*:*) - echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + echo "$UNAME_MACHINE"-unknown-dragonfly"`echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`" exit ;; *:*VMS:*:*) UNAME_MACHINE=`(uname -p) 2>/dev/null` - case "${UNAME_MACHINE}" in + case "$UNAME_MACHINE" in A*) echo alpha-dec-vms ; exit ;; I*) echo ia64-dec-vms ; exit ;; V*) echo vax-dec-vms ; exit ;; @@ -1398,32 +1404,44 @@ EOF echo i386-pc-xenix exit ;; i*86:skyos:*:*) - echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE} | sed -e 's/ .*$//'` + echo "$UNAME_MACHINE"-pc-skyos"`echo "$UNAME_RELEASE" | sed -e 's/ .*$//'`" exit ;; i*86:rdos:*:*) - echo ${UNAME_MACHINE}-pc-rdos + echo "$UNAME_MACHINE"-pc-rdos exit ;; i*86:AROS:*:*) - echo ${UNAME_MACHINE}-pc-aros + echo "$UNAME_MACHINE"-pc-aros exit ;; x86_64:VMkernel:*:*) - echo ${UNAME_MACHINE}-unknown-esx + echo "$UNAME_MACHINE"-unknown-esx exit ;; amd64:Isilon\ OneFS:*:*) echo x86_64-unknown-onefs exit ;; esac +echo "$0: unable to guess system type" >&2 + +case "$UNAME_MACHINE:$UNAME_SYSTEM" in + mips:Linux | mips64:Linux) + # If we got here on MIPS GNU/Linux, output extra information. + cat >&2 <&2 </dev/null` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` -UNAME_MACHINE = ${UNAME_MACHINE} -UNAME_RELEASE = ${UNAME_RELEASE} -UNAME_SYSTEM = ${UNAME_SYSTEM} -UNAME_VERSION = ${UNAME_VERSION} +UNAME_MACHINE = "$UNAME_MACHINE" +UNAME_RELEASE = "$UNAME_RELEASE" +UNAME_SYSTEM = "$UNAME_SYSTEM" +UNAME_VERSION = "$UNAME_VERSION" EOF exit 1 # Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) +# eval: (add-hook 'write-file-functions 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" diff --git a/config.h.in b/config.h.in index 4b6f381..9c494c8 100644 --- a/config.h.in +++ b/config.h.in @@ -42,9 +42,13 @@ /* Darwin (MacOS/X) */ #undef HAVE_DARWIN -/* Define to 1 if you have the declaration of `OpenSSL_add_all_algorithms - EVP_aes_256_cfb', and to 0 if you don't. */ -#undef HAVE_DECL_OPENSSL_ADD_ALL_ALGORITHMS_EVP_AES_256_CFB +/* Define to 1 if you have the declaration of `EVP_aes_256_cfb', and to 0 if + you don't. */ +#undef HAVE_DECL_EVP_AES_256_CFB + +/* Define to 1 if you have the declaration of `OpenSSL_add_all_algorithms', + and to 0 if you don't. */ +#undef HAVE_DECL_OPENSSL_ADD_ALL_ALGORITHMS /* Define to 1 if you have the declaration of `res_init', and to 0 if you don't. */ @@ -83,9 +87,6 @@ /* FreeBSD */ #undef HAVE_FREEBSD -/* Define to 1 if you have the `ftime' function. */ -#undef HAVE_FTIME - /* Define to 1 if you have the header file. */ #undef HAVE_GCRYPT_H @@ -98,6 +99,9 @@ /* Define to 1 if you have the `gettimeofday' function. */ #undef HAVE_GETTIMEOFDAY +/* Define to 1 if you have the `HMAC_CTX_new' function. */ +#undef HAVE_HMAC_CTX_NEW + /* Define to 1 if you have the header file. */ #undef HAVE_INTTYPES_H @@ -424,5 +428,8 @@ /* Defined if the __malloc__ attribute is not supported. */ #undef __malloc__ +/* Defined if the __nonnull__ attribute is not supported. */ +#undef __nonnull__ + /* Defined if the __warn_unused_result__ attribute is not supported. */ #undef __warn_unused_result__ diff --git a/config.sub b/config.sub index dd2ca93..1d8e98b 100755 --- a/config.sub +++ b/config.sub @@ -1,8 +1,8 @@ #! /bin/sh # Configuration validation subroutine script. -# Copyright 1992-2016 Free Software Foundation, Inc. +# Copyright 1992-2018 Free Software Foundation, Inc. -timestamp='2016-11-04' +timestamp='2018-02-22' # 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 @@ -15,7 +15,7 @@ timestamp='2016-11-04' # General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with this program; if not, see . +# along with this program; if not, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a @@ -33,7 +33,7 @@ timestamp='2016-11-04' # 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 +# https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub # This file is supposed to be the same for all GNU packages # and recognize all the CPU types, system types and aliases @@ -57,7 +57,7 @@ Usage: $0 [OPTION] CPU-MFR-OPSYS or ALIAS Canonicalize a configuration name. -Operation modes: +Options: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit @@ -67,7 +67,7 @@ Report bugs and patches to ." version="\ GNU config.sub ($timestamp) -Copyright 1992-2016 Free Software Foundation, Inc. +Copyright 1992-2018 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." @@ -94,7 +94,7 @@ while test $# -gt 0 ; do *local*) # First pass through any local machine types. - echo $1 + echo "$1" exit ;; * ) @@ -112,7 +112,7 @@ esac # Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). # Here we must recognize all the valid KERNEL-OS combinations. -maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` +maybe_os=`echo "$1" | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` case $maybe_os in nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ @@ -120,16 +120,16 @@ case $maybe_os in kopensolaris*-gnu* | cloudabi*-eabi* | \ storm-chaos* | os2-emx* | rtmk-nova*) os=-$maybe_os - basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + basic_machine=`echo "$1" | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` ;; android-linux) os=-linux-android - basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown + basic_machine=`echo "$1" | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown ;; *) - basic_machine=`echo $1 | sed 's/-[^-]*$//'` - if [ $basic_machine != $1 ] - then os=`echo $1 | sed 's/.*-/-/'` + basic_machine=`echo "$1" | sed 's/-[^-]*$//'` + if [ "$basic_machine" != "$1" ] + then os=`echo "$1" | sed 's/.*-/-/'` else os=; fi ;; esac @@ -178,44 +178,44 @@ case $os in ;; -sco6) os=-sco5v6 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` ;; -sco5) os=-sco3.2v5 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` ;; -sco4) os=-sco3.2v4 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` ;; -sco3.2.[4-9]*) os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` ;; -sco3.2v[4-9]*) # Don't forget version if it is 3.2v4 or newer. - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` ;; -sco5v6*) # Don't forget version if it is 3.2v4 or newer. - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` ;; -sco*) os=-sco3.2v2 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` ;; -udk*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` ;; -isc) os=-isc2.2 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` ;; -clix*) basic_machine=clipper-intergraph ;; -isc*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` ;; -lynx*178) os=-lynxos178 @@ -227,10 +227,7 @@ case $os in os=-lynxos ;; -ptx*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` - ;; - -windowsnt*) - os=`echo $os | sed -e 's/windowsnt/winnt/'` + basic_machine=`echo "$1" | sed -e 's/86-.*/86-sequent/'` ;; -psos*) os=-psos @@ -263,7 +260,7 @@ case $basic_machine in | fido | fr30 | frv | ft32 \ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ | hexagon \ - | i370 | i860 | i960 | ia64 \ + | i370 | i860 | i960 | ia16 | ia64 \ | ip2k | iq2000 \ | k1om \ | le32 | le64 \ @@ -299,7 +296,7 @@ case $basic_machine in | nios | nios2 | nios2eb | nios2el \ | ns16k | ns32k \ | open8 | or1k | or1knd | or32 \ - | pdp10 | pdp11 | pj | pjl \ + | pdp10 | pj | pjl \ | powerpc | powerpc64 | powerpc64le | powerpcle \ | pru \ | pyramid \ @@ -315,7 +312,7 @@ case $basic_machine in | ubicom32 \ | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ | visium \ - | we32k \ + | wasm32 \ | x86 | xc16x | xstormy16 | xtensa \ | z8k | z80) basic_machine=$basic_machine-unknown @@ -336,7 +333,7 @@ case $basic_machine in basic_machine=$basic_machine-unknown os=-none ;; - m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65) ;; ms1) basic_machine=mt-unknown @@ -365,7 +362,7 @@ case $basic_machine in ;; # Object if more than one company name word. *-*-*) - echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + echo Invalid configuration \`"$1"\': machine \`"$basic_machine"\' not recognized 1>&2 exit 1 ;; # Recognize the basic CPU types with company name. @@ -388,7 +385,7 @@ case $basic_machine in | h8300-* | h8500-* \ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ | hexagon-* \ - | i*86-* | i860-* | i960-* | ia64-* \ + | i*86-* | i860-* | i960-* | ia16-* | ia64-* \ | ip2k-* | iq2000-* \ | k1om-* \ | le32-* | le64-* \ @@ -446,6 +443,7 @@ case $basic_machine in | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ | vax-* \ | visium-* \ + | wasm32-* \ | we32k-* \ | x86-* | x86_64-* | xc16x-* | xps100-* \ | xstormy16-* | xtensa*-* \ @@ -459,7 +457,7 @@ case $basic_machine in # Recognize the various machine names and aliases which stand # for a CPU type and a company and sometimes even an OS. 386bsd) - basic_machine=i386-unknown + basic_machine=i386-pc os=-bsd ;; 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) @@ -493,7 +491,7 @@ case $basic_machine in basic_machine=x86_64-pc ;; amd64-*) - basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` + basic_machine=x86_64-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; amdahl) basic_machine=580-amdahl @@ -538,7 +536,7 @@ case $basic_machine in os=-linux ;; blackfin-*) - basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` + basic_machine=bfin-`echo "$basic_machine" | sed 's/^[^-]*-//'` os=-linux ;; bluegene*) @@ -546,13 +544,13 @@ case $basic_machine in os=-cnk ;; c54x-*) - basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'` + basic_machine=tic54x-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; c55x-*) - basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'` + basic_machine=tic55x-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; c6x-*) - basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'` + basic_machine=tic6x-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; c90) basic_machine=c90-cray @@ -641,7 +639,7 @@ case $basic_machine in basic_machine=rs6000-bull os=-bosx ;; - dpx2* | dpx2*-bull) + dpx2*) basic_machine=m68k-bull os=-sysv3 ;; @@ -650,7 +648,7 @@ case $basic_machine in os=$os"spe" ;; e500v[12]-*) - basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + basic_machine=powerpc-`echo "$basic_machine" | sed 's/^[^-]*-//'` os=$os"spe" ;; ebmon29k) @@ -742,9 +740,6 @@ case $basic_machine in hp9k8[0-9][0-9] | hp8[0-9][0-9]) basic_machine=hppa1.0-hp ;; - hppa-next) - os=-nextstep3 - ;; hppaosf) basic_machine=hppa1.1-hp os=-osf @@ -757,26 +752,26 @@ case $basic_machine in basic_machine=i370-ibm ;; i*86v32) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'` os=-sysv32 ;; i*86v4*) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'` os=-sysv4 ;; i*86v) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'` os=-sysv ;; i*86sol2) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'` os=-solaris2 ;; i386mach) basic_machine=i386-mach os=-mach ;; - i386-vsta | vsta) + vsta) basic_machine=i386-unknown os=-vsta ;; @@ -795,19 +790,16 @@ case $basic_machine in os=-sysv ;; leon-*|leon[3-9]-*) - basic_machine=sparc-`echo $basic_machine | sed 's/-.*//'` + basic_machine=sparc-`echo "$basic_machine" | sed 's/-.*//'` ;; m68knommu) basic_machine=m68k-unknown os=-linux ;; m68knommu-*) - basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` + basic_machine=m68k-`echo "$basic_machine" | sed 's/^[^-]*-//'` os=-linux ;; - m88k-omron*) - basic_machine=m88k-omron - ;; magnum | m3230) basic_machine=mips-mips os=-sysv @@ -839,10 +831,10 @@ case $basic_machine in os=-mint ;; mips3*-*) - basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + basic_machine=`echo "$basic_machine" | sed -e 's/mips3/mips64/'` ;; mips3*) - basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + basic_machine=`echo "$basic_machine" | sed -e 's/mips3/mips64/'`-unknown ;; monitor) basic_machine=m68k-rom68k @@ -861,7 +853,7 @@ case $basic_machine in os=-msdos ;; ms1-*) - basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` + basic_machine=`echo "$basic_machine" | sed -e 's/ms1-/mt-/'` ;; msys) basic_machine=i686-pc @@ -903,7 +895,7 @@ case $basic_machine in basic_machine=v70-nec os=-sysv ;; - next | m*-next ) + next | m*-next) basic_machine=m68k-next case $os in -nextstep* ) @@ -948,6 +940,12 @@ case $basic_machine in nsr-tandem) basic_machine=nsr-tandem ;; + nsv-tandem) + basic_machine=nsv-tandem + ;; + nsx-tandem) + basic_machine=nsx-tandem + ;; op50n-* | op60c-*) basic_machine=hppa1.1-oki os=-proelf @@ -980,7 +978,7 @@ case $basic_machine in os=-linux ;; parisc-*) - basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` + basic_machine=hppa-`echo "$basic_machine" | sed 's/^[^-]*-//'` os=-linux ;; pbd) @@ -996,7 +994,7 @@ case $basic_machine in basic_machine=i386-pc ;; pc98-*) - basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` + basic_machine=i386-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; pentium | p5 | k5 | k6 | nexgen | viac3) basic_machine=i586-pc @@ -1011,16 +1009,16 @@ case $basic_machine in basic_machine=i786-pc ;; pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) - basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` + basic_machine=i586-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; pentiumpro-* | p6-* | 6x86-* | athlon-*) - basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + basic_machine=i686-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) - basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + basic_machine=i686-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; pentium4-*) - basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` + basic_machine=i786-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; pn) basic_machine=pn-gould @@ -1030,23 +1028,23 @@ case $basic_machine in ppc | ppcbe) basic_machine=powerpc-unknown ;; ppc-* | ppcbe-*) - basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + basic_machine=powerpc-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; ppcle | powerpclittle) basic_machine=powerpcle-unknown ;; ppcle-* | powerpclittle-*) - basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` + basic_machine=powerpcle-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; ppc64) basic_machine=powerpc64-unknown ;; - ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` + ppc64-*) basic_machine=powerpc64-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; ppc64le | powerpc64little) basic_machine=powerpc64le-unknown ;; ppc64le-* | powerpc64little-*) - basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` + basic_machine=powerpc64le-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; ps2) basic_machine=i386-ibm @@ -1100,17 +1098,10 @@ case $basic_machine in sequent) basic_machine=i386-sequent ;; - sh) - basic_machine=sh-hitachi - os=-hms - ;; sh5el) basic_machine=sh5le-unknown ;; - sh64) - basic_machine=sh64-unknown - ;; - sparclite-wrs | simso-wrs) + simso-wrs) basic_machine=sparclite-wrs os=-vxworks ;; @@ -1129,7 +1120,7 @@ case $basic_machine in os=-sysv4 ;; strongarm-* | thumb-*) - basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'` + basic_machine=arm-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; sun2) basic_machine=m68000-sun @@ -1251,6 +1242,9 @@ case $basic_machine in basic_machine=hppa1.1-winbond os=-proelf ;; + x64) + basic_machine=x86_64-pc + ;; xbox) basic_machine=i686-pc os=-mingw32 @@ -1259,20 +1253,12 @@ case $basic_machine in basic_machine=xps100-honeywell ;; xscale-* | xscalee[bl]-*) - basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'` + basic_machine=`echo "$basic_machine" | sed 's/^xscale/arm/'` ;; ymp) basic_machine=ymp-cray os=-unicos ;; - z8k-*-coff) - basic_machine=z8k-unknown - os=-sim - ;; - z80-*-coff) - basic_machine=z80-unknown - os=-sim - ;; none) basic_machine=none-none os=-none @@ -1301,10 +1287,6 @@ case $basic_machine in vax) basic_machine=vax-dec ;; - pdp10) - # there are many clones, so DEC is not a safe bet - basic_machine=pdp10-unknown - ;; pdp11) basic_machine=pdp11-dec ;; @@ -1314,9 +1296,6 @@ case $basic_machine in sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) basic_machine=sh-unknown ;; - sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) - basic_machine=sparc-sun - ;; cydra) basic_machine=cydra-cydrome ;; @@ -1336,7 +1315,7 @@ case $basic_machine in # Make sure to match an already-canonicalized machine name. ;; *) - echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + echo Invalid configuration \`"$1"\': machine \`"$basic_machine"\' not recognized 1>&2 exit 1 ;; esac @@ -1344,10 +1323,10 @@ esac # Here we canonicalize certain aliases for manufacturers. case $basic_machine in *-digital*) - basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` + basic_machine=`echo "$basic_machine" | sed 's/digital.*/dec/'` ;; *-commodore*) - basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + basic_machine=`echo "$basic_machine" | sed 's/commodore.*/cbm/'` ;; *) ;; @@ -1358,8 +1337,8 @@ esac if [ x"$os" != x"" ] then case $os in - # First match some system type aliases - # that might get confused with valid system types. + # 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 @@ -1370,18 +1349,19 @@ case $os in -solaris) os=-solaris2 ;; - -svr4*) - os=-sysv4 - ;; -unixware*) os=-sysv4.2uw ;; -gnu/linux*) os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` ;; - # First accept the basic system types. + # es1800 is here to avoid being matched by es* (a different OS) + -es1800*) + os=-ose + ;; + # Now accept the basic system types. # The portable systems comes first. - # Each alternative MUST END IN A *, to match a version number. + # Each alternative MUST end in a * to match a version number. # -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]*\ @@ -1391,25 +1371,26 @@ case $os in | -aos* | -aros* | -cloudabi* | -sortix* \ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ - | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ + | -hiux* | -knetbsd* | -mirbsd* | -netbsd* \ | -bitrig* | -openbsd* | -solidbsd* | -libertybsd* \ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ - | -chorusos* | -chorusrdb* | -cegcc* \ + | -chorusos* | -chorusrdb* | -cegcc* | -glidix* \ | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ | -midipix* | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \ | -linux-newlib* | -linux-musl* | -linux-uclibc* \ | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \ - | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ + | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* \ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ - | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ + | -morphos* | -superux* | -rtmk* | -windiss* \ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* \ - | -onefs* | -tirtos* | -phoenix* | -fuchsia*) + | -onefs* | -tirtos* | -phoenix* | -fuchsia* | -redox* | -bme* \ + | -midnightbsd*) # Remember, each alternative MUST END IN *, to match a version number. ;; -qnx*) @@ -1426,12 +1407,12 @@ case $os in -nto*) os=`echo $os | sed -e 's|nto|nto-qnx|'` ;; - -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ - | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ + -sim | -xray | -os68k* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* \ | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) ;; -mac*) - os=`echo $os | sed -e 's|mac|macos|'` + os=`echo "$os" | sed -e 's|mac|macos|'` ;; -linux-dietlibc) os=-linux-dietlibc @@ -1440,10 +1421,10 @@ case $os in os=`echo $os | sed -e 's|linux|linux-gnu|'` ;; -sunos5*) - os=`echo $os | sed -e 's|sunos5|solaris2|'` + os=`echo "$os" | sed -e 's|sunos5|solaris2|'` ;; -sunos6*) - os=`echo $os | sed -e 's|sunos6|solaris3|'` + os=`echo "$os" | sed -e 's|sunos6|solaris3|'` ;; -opened*) os=-openedition @@ -1454,12 +1435,6 @@ case $os in -wince*) os=-wince ;; - -osfrose*) - os=-osfrose - ;; - -osf*) - os=-osf - ;; -utek*) os=-bsd ;; @@ -1484,7 +1459,7 @@ case $os in -nova*) os=-rtmk-nova ;; - -ns2 ) + -ns2) os=-nextstep2 ;; -nsk*) @@ -1506,7 +1481,7 @@ case $os in -oss*) os=-sysv3 ;; - -svr4) + -svr4*) os=-sysv4 ;; -svr3) @@ -1521,24 +1496,28 @@ case $os in -ose*) os=-ose ;; - -es1800*) - os=-ose - ;; - -xenix) - os=-xenix - ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) os=-mint ;; - -aros*) - os=-aros - ;; -zvmoe) os=-zvmoe ;; -dicos*) os=-dicos ;; + -pikeos*) + # Until real need of OS specific support for + # particular features comes up, bare metal + # configurations are quite functional. + case $basic_machine in + arm*) + os=-eabi + ;; + *) + os=-elf + ;; + esac + ;; -nacl*) ;; -ios) @@ -1548,7 +1527,7 @@ case $os in *) # Get rid of the `-' at the beginning of $os. os=`echo $os | sed 's/[^-]*-//'` - echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 + echo Invalid configuration \`"$1"\': system \`"$os"\' not recognized 1>&2 exit 1 ;; esac @@ -1638,12 +1617,12 @@ case $basic_machine in sparc-* | *-sun) os=-sunos4.1.1 ;; + pru-*) + os=-elf + ;; *-be) os=-beos ;; - *-haiku) - os=-haiku - ;; *-ibm) os=-aix ;; @@ -1683,7 +1662,7 @@ case $basic_machine in m88k-omron*) os=-luna ;; - *-next ) + *-next) os=-nextstep ;; *-sequent) @@ -1698,9 +1677,6 @@ case $basic_machine in i370-*) os=-mvs ;; - *-next) - os=-nextstep3 - ;; *-gould) os=-sysv ;; @@ -1810,15 +1786,15 @@ case $basic_machine in vendor=stratus ;; esac - basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + basic_machine=`echo "$basic_machine" | sed "s/unknown/$vendor/"` ;; esac -echo $basic_machine$os +echo "$basic_machine$os" exit # Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) +# eval: (add-hook 'write-file-functions 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" diff --git a/configure b/configure index 536bafc..ebad571 100755 --- a/configure +++ b/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for tinc 1.1pre15. +# Generated by GNU Autoconf 2.69 for tinc 1.1pre17. # # # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. @@ -577,8 +577,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='tinc' PACKAGE_TARNAME='tinc' -PACKAGE_VERSION='1.1pre15' -PACKAGE_STRING='tinc 1.1pre15' +PACKAGE_VERSION='1.1pre17' +PACKAGE_STRING='tinc 1.1pre17' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -661,11 +661,22 @@ build_os build_vendor build_cpu build -LN_S -AM_BACKSLASH -AM_DEFAULT_VERBOSITY -AM_DEFAULT_V -AM_V +CODE_COVERAGE_RULES +CODE_COVERAGE_LDFLAGS +CODE_COVERAGE_LIBS +CODE_COVERAGE_CXXFLAGS +CODE_COVERAGE_CFLAGS +CODE_COVERAGE_CPPFLAGS +GENHTML +LCOV +GCOV +CODE_COVERAGE_ENABLED +CODE_COVERAGE_ENABLED_FALSE +CODE_COVERAGE_ENABLED_TRUE +SED +EGREP +GREP +CPP am__fastdepCC_FALSE am__fastdepCC_TRUE CCDEPMODE @@ -673,9 +684,19 @@ am__nodep AMDEPBACKSLASH AMDEP_FALSE AMDEP_TRUE -am__quote am__include DEPDIR +OBJEXT +EXEEXT +ac_ct_CC +CPPFLAGS +LDFLAGS +CFLAGS +CC +AM_BACKSLASH +AM_DEFAULT_VERBOSITY +AM_DEFAULT_V +AM_V am__untar am__tar AMTAR @@ -699,16 +720,6 @@ am__isrc INSTALL_DATA INSTALL_SCRIPT INSTALL_PROGRAM -EGREP -GREP -CPP -OBJEXT -EXEEXT -ac_ct_CC -CPPFLAGS -LDFLAGS -CFLAGS -CC target_alias host_alias build_alias @@ -747,12 +758,15 @@ PACKAGE_VERSION PACKAGE_TARNAME PACKAGE_NAME PATH_SEPARATOR -SHELL' +SHELL +am__quote' ac_subst_files='' ac_user_opts=' enable_option_checking -enable_dependency_tracking enable_silent_rules +enable_dependency_tracking +with_gcov +enable_code_coverage enable_uml enable_vde enable_tunemu @@ -1346,7 +1360,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures tinc 1.1pre15 to adapt to many kinds of systems. +\`configure' configures tinc 1.1pre17 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1417,7 +1431,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of tinc 1.1pre15:";; + short | recursive ) echo "Configuration of tinc 1.1pre17:";; esac cat <<\_ACEOF @@ -1425,12 +1439,13 @@ Optional Features: --disable-option-checking ignore unrecognized --enable/--with options --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --enable-silent-rules less verbose build output (undo: "make V=1") + --disable-silent-rules verbose build output (undo: "make V=0") --enable-dependency-tracking do not reject slow dependency extractors --disable-dependency-tracking speeds up one-time build - --enable-silent-rules less verbose build output (undo: "make V=1") - --disable-silent-rules verbose build output (undo: "make V=0") + --enable-code-coverage Whether to enable code coverage support --enable-uml enable support for User Mode Linux --enable-vde enable support for Virtual Distributed Ethernet --enable-tunemu enable support for the tunemu driver @@ -1448,6 +1463,7 @@ Optional Features: Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --with-gcov=GCOV use given GCOV for coverage (GCOV=gcov). --with-systemd[=DIR] install systemd service files [to DIR if specified] --with-curses=DIR curses base directory, or: --with-curses-include=DIR @@ -1556,7 +1572,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -tinc configure 1.1pre15 +tinc configure 1.1pre17 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -2021,7 +2037,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by tinc $as_me 1.1pre15, which was +It was created by tinc $as_me 1.1pre17, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -2370,6 +2386,8 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu +am__api_version='1.16' + ac_aux_dir= for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do if test -f "$ac_dir/install-sh"; then @@ -2399,9 +2417,692 @@ ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AmigaOS /C/install, which installs bootblocks on floppy discs +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# OS/2's system install, which has a completely different semantic +# ./install, which can be erroneously created by make from ./install.sh. +# Reject install programs that cannot install multiple files. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 +$as_echo_n "checking for a BSD-compatible install... " >&6; } +if test -z "$INSTALL"; then +if ${ac_cv_path_install+:} false; then : + $as_echo_n "(cached) " >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + # Account for people who put trailing slashes in PATH elements. +case $as_dir/ in #(( + ./ | .// | /[cC]/* | \ + /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ + ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ + /usr/ucb/* ) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then + if test $ac_prog = install && + grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + rm -rf conftest.one conftest.two conftest.dir + echo one > conftest.one + echo two > conftest.two + mkdir conftest.dir + if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && + test -s conftest.one && test -s conftest.two && + test -s conftest.dir/conftest.one && + test -s conftest.dir/conftest.two + then + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + fi + done + done + ;; +esac + + done +IFS=$as_save_IFS + +rm -rf conftest.one conftest.two conftest.dir + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL=$ac_cv_path_install + else + # As a last resort, use the slow shell script. Don't cache a + # value for INSTALL 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. + INSTALL=$ac_install_sh + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 +$as_echo "$INSTALL" >&6; } + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 +$as_echo_n "checking whether build environment is sane... " >&6; } +# Reject unsafe characters in $srcdir or the absolute working directory +# name. Accept space and tab only in the latter. +am_lf=' +' +case `pwd` in + *[\\\"\#\$\&\'\`$am_lf]*) + as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;; +esac +case $srcdir in + *[\\\"\#\$\&\'\`$am_lf\ \ ]*) + as_fn_error $? "unsafe srcdir value: '$srcdir'" "$LINENO" 5;; +esac + +# Do 'set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + am_has_slept=no + for am_try in 1 2; do + echo "timestamp, slept: $am_has_slept" > conftest.file + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$*" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + if test "$*" != "X $srcdir/configure conftest.file" \ + && test "$*" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + as_fn_error $? "ls -t appears to fail. Make sure there is not a broken + alias in your environment" "$LINENO" 5 + fi + if test "$2" = conftest.file || test $am_try -eq 2; then + break + fi + # Just in case. + sleep 1 + am_has_slept=yes + done + test "$2" = conftest.file + ) +then + # Ok. + : +else + as_fn_error $? "newly created file is older than distributed files! +Check your system clock" "$LINENO" 5 +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +# If we didn't sleep, we still need to ensure time stamps of config.status and +# generated files are strictly newer. +am_sleep_pid= +if grep 'slept: no' conftest.file >/dev/null 2>&1; then + ( sleep 1 ) & + am_sleep_pid=$! +fi + +rm -f conftest.file + +test "$program_prefix" != NONE && + program_transform_name="s&^&$program_prefix&;$program_transform_name" +# Use a double $ so make ignores it. +test "$program_suffix" != NONE && + program_transform_name="s&\$&$program_suffix&;$program_transform_name" +# Double any \ or $. +# By default was `s,x,x', remove it if useless. +ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' +program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` + # Expand $ac_aux_dir to an absolute path. am_aux_dir=`cd "$ac_aux_dir" && pwd` +if test x"${MISSING+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; + *) + MISSING="\${SHELL} $am_aux_dir/missing" ;; + esac +fi +# Use eval to expand $SHELL +if eval "$MISSING --is-lightweight"; then + am_missing_run="$MISSING " +else + am_missing_run= + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5 +$as_echo "$as_me: WARNING: 'missing' script is too old or missing" >&2;} +fi + +if test x"${install_sh+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; + *) + install_sh="\${SHELL} $am_aux_dir/install-sh" + esac +fi + +# Installed binaries are usually stripped using 'strip' when the user +# run "make install-strip". However 'strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the 'STRIP' environment variable to overrule this program. +if test "$cross_compiling" != no; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 +$as_echo "$STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_STRIP="strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 +$as_echo "$ac_ct_STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_STRIP" = x; then + STRIP=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + STRIP=$ac_ct_STRIP + fi +else + STRIP="$ac_cv_prog_STRIP" +fi + +fi +INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5 +$as_echo_n "checking for a thread-safe mkdir -p... " >&6; } +if test -z "$MKDIR_P"; then + if ${ac_cv_path_mkdir+:} false; then : + $as_echo_n "(cached) " >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in mkdir gmkdir; do + for ac_exec_ext in '' $ac_executable_extensions; do + as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext" || continue + case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( + 'mkdir (GNU coreutils) '* | \ + 'mkdir (coreutils) '* | \ + 'mkdir (fileutils) '4.1*) + ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext + break 3;; + esac + done + done + done +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 + # As a last resort, use the slow shell script. Don't cache a + # 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. + MKDIR_P="$ac_install_sh -d" + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 +$as_echo "$MKDIR_P" >&6; } + +for ac_prog in gawk mawk nawk awk +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_AWK+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AWK"; then + ac_cv_prog_AWK="$AWK" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_AWK="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AWK=$ac_cv_prog_AWK +if test -n "$AWK"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 +$as_echo "$AWK" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$AWK" && break +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 +$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } +set x ${MAKE-make} +ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` +if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat >conftest.make <<\_ACEOF +SHELL = /bin/sh +all: + @echo '@@@%%%=$(MAKE)=@@@%%%' +_ACEOF +# GNU make sometimes prints "make[1]: Entering ...", which would confuse us. +case `${MAKE-make} -f conftest.make 2>/dev/null` in + *@@@%%%=?*=@@@%%%*) + eval ac_cv_prog_make_${ac_make}_set=yes;; + *) + eval ac_cv_prog_make_${ac_make}_set=no;; +esac +rm -f conftest.make +fi +if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + SET_MAKE= +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + SET_MAKE="MAKE=${MAKE-make}" +fi + +rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null + +# Check whether --enable-silent-rules was given. +if test "${enable_silent_rules+set}" = set; then : + enableval=$enable_silent_rules; +fi + +case $enable_silent_rules in # ((( + yes) AM_DEFAULT_VERBOSITY=0;; + no) AM_DEFAULT_VERBOSITY=1;; + *) AM_DEFAULT_VERBOSITY=1;; +esac +am_make=${MAKE-make} +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 +$as_echo_n "checking whether $am_make supports nested variables... " >&6; } +if ${am_cv_make_support_nested_variables+:} false; then : + $as_echo_n "(cached) " >&6 +else + if $as_echo 'TRUE=$(BAR$(V)) +BAR0=false +BAR1=true +V=1 +am__doit: + @$(TRUE) +.PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then + am_cv_make_support_nested_variables=yes +else + am_cv_make_support_nested_variables=no +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 +$as_echo "$am_cv_make_support_nested_variables" >&6; } +if test $am_cv_make_support_nested_variables = yes; then + AM_V='$(V)' + AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' +else + AM_V=$AM_DEFAULT_VERBOSITY + AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY +fi +AM_BACKSLASH='\' + +if test "`cd $srcdir && pwd`" != "`pwd`"; then + # Use -I$(srcdir) only when $(srcdir) != ., so that make's output + # is not polluted with repeated "-I." + am__isrc=' -I$(srcdir)' + # test to see if srcdir already configured + if test -f $srcdir/config.status; then + as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 + fi +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi + + +# Define the identity of the package. + PACKAGE='tinc' + VERSION='1.1pre17' + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE "$PACKAGE" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define VERSION "$VERSION" +_ACEOF + +# Some tools Automake needs. + +ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} + + +AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} + + +AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} + + +AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} + + +MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} + +# For better backward compatibility. To be removed once Automake 1.9.x +# dies out for good. For more background, see: +# +# +mkdir_p='$(MKDIR_P)' + +# We need awk for the "check" target (and possibly the TAP driver). The +# system "awk" is bad on some platforms. +# Always define AMTAR for backward compatibility. Yes, it's still used +# in the wild :-( We should find a proper way to deprecate it ... +AMTAR='$${TAR-tar}' + + +# We'll loop over all known methods to create a tar archive until one works. +_am_tools='gnutar pax cpio none' + +am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -' + + + + + + +# POSIX will say in a future version that running "rm -f" with no argument +# is OK; and we want to be able to make that assumption in our Makefile +# recipes. So use an aggressive probe to check that the usage we want is +# actually supported "in the wild" to an acceptable degree. +# See automake bug#10828. +# To make any issue more visible, cause the running configure to be aborted +# by default if the 'rm' program in use doesn't match our expectations; the +# user can still override this though. +if rm -f && rm -fr && rm -rf; then : OK; else + cat >&2 <<'END' +Oops! + +Your 'rm' program seems unable to run without file operands specified +on the command line, even when the '-f' option is present. This is contrary +to the behaviour of most rm programs out there, and not conforming with +the upcoming POSIX standard: + +Please tell bug-automake@gnu.org about your system, including the value +of your $PATH and any error possibly output before this message. This +can help us improve future automake versions. + +END + if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then + echo 'Configuration will proceed anyway, since you have set the' >&2 + echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 + echo >&2 + else + cat >&2 <<'END' +Aborting the configuration process, to ensure you take notice of the issue. + +You can download and install GNU coreutils to get an 'rm' implementation +that behaves properly: . + +If you want to complete the configuration process using your problematic +'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM +to "yes", and re-run configure. + +END + as_fn_error $? "Your 'rm' program is bad, sorry." "$LINENO" 5 + fi +fi + +ac_config_headers="$ac_config_headers config.h" + + +# Check whether --enable-silent-rules was given. +if test "${enable_silent_rules+set}" = set; then : + enableval=$enable_silent_rules; +fi + +case $enable_silent_rules in # ((( + yes) AM_DEFAULT_VERBOSITY=0;; + no) AM_DEFAULT_VERBOSITY=1;; + *) AM_DEFAULT_VERBOSITY=0;; +esac +am_make=${MAKE-make} +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 +$as_echo_n "checking whether $am_make supports nested variables... " >&6; } +if ${am_cv_make_support_nested_variables+:} false; then : + $as_echo_n "(cached) " >&6 +else + if $as_echo 'TRUE=$(BAR$(V)) +BAR0=false +BAR1=true +V=1 +am__doit: + @$(TRUE) +.PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then + am_cv_make_support_nested_variables=yes +else + am_cv_make_support_nested_variables=no +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 +$as_echo "$am_cv_make_support_nested_variables" >&6; } +if test $am_cv_make_support_nested_variables = yes; then + AM_V='$(V)' + AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' +else + AM_V=$AM_DEFAULT_VERBOSITY + AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY +fi +AM_BACKSLASH='\' + + +# Enable GNU extensions. +# Define this here, not in acconfig's @TOP@ section, since definitions +# in the latter don't make it into the configure-time tests. +DEPDIR="${am__leading_dot}deps" + +ac_config_commands="$ac_config_commands depfiles" + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} supports the include directive" >&5 +$as_echo_n "checking whether ${MAKE-make} supports the include directive... " >&6; } +cat > confinc.mk << 'END' +am__doit: + @echo this is the am__doit target >confinc.out +.PHONY: am__doit +END +am__include="#" +am__quote= +# BSD make does it like this. +echo '.include "confinc.mk" # ignored' > confmf.BSD +# Other make implementations (GNU, Solaris 10, AIX) do it like this. +echo 'include confinc.mk # ignored' > confmf.GNU +_am_result=no +for s in GNU BSD; do + { echo "$as_me:$LINENO: ${MAKE-make} -f confmf.$s && cat confinc.out" >&5 + (${MAKE-make} -f confmf.$s && cat confinc.out) >&5 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + case $?:`cat confinc.out 2>/dev/null` in #( + '0:this is the am__doit target') : + case $s in #( + BSD) : + am__include='.include' am__quote='"' ;; #( + *) : + am__include='include' am__quote='' ;; +esac ;; #( + *) : + ;; +esac + if test "$am__include" != "#"; then + _am_result="yes ($s style)" + break + fi +done +rm -f confinc.* confmf.* +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: ${_am_result}" >&5 +$as_echo "${_am_result}" >&6; } + +# Check whether --enable-dependency-tracking was given. +if test "${enable_dependency_tracking+set}" = set; then : + enableval=$enable_dependency_tracking; +fi + +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' + am__nodep='_no' +fi + if test "x$enable_dependency_tracking" != xno; then + AMDEP_TRUE= + AMDEP_FALSE='#' +else + AMDEP_TRUE='#' + AMDEP_FALSE= +fi + + ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' @@ -3250,6 +3951,134 @@ ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $ ac_compiler_gnu=$ac_cv_c_compiler_gnu +depcc="$CC" am_compiler_list= + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 +$as_echo_n "checking dependency style of $depcc... " >&6; } +if ${am_cv_CC_dependencies_compiler_type+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named 'D' -- because '-MD' means "put the output + # in D". + rm -rf conftest.dir + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CC_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + am__universal=false + case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with + # Solaris 10 /bin/sh. + echo '/* dummy */' > sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with '-c' and '-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle '-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs. + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # After this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested. + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvc7 | msvc7msys | msvisualcpp | msvcmsys) + # This compiler won't grok '-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CC_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CC_dependencies_compiler_type=none +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 +$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } +CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type + + if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then + am__fastdepCC_TRUE= + am__fastdepCC_FALSE='#' +else + am__fastdepCC_TRUE='#' + am__fastdepCC_FALSE= +fi + + ac_ext=c ac_cpp='$CPP $CPPFLAGS' @@ -3710,820 +4539,6 @@ $as_echo "$ac_cv_safe_to_define___extensions__" >&6; } -am__api_version='1.15' - -# Find a good install program. We prefer a C program (faster), -# so one script is as good as another. But avoid the broken or -# incompatible versions: -# SysV /etc/install, /usr/sbin/install -# SunOS /usr/etc/install -# IRIX /sbin/install -# AIX /bin/install -# AmigaOS /C/install, which installs bootblocks on floppy discs -# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag -# AFS /usr/afsws/bin/install, which mishandles nonexistent args -# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" -# OS/2's system install, which has a completely different semantic -# ./install, which can be erroneously created by make from ./install.sh. -# Reject install programs that cannot install multiple files. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 -$as_echo_n "checking for a BSD-compatible install... " >&6; } -if test -z "$INSTALL"; then -if ${ac_cv_path_install+:} false; then : - $as_echo_n "(cached) " >&6 -else - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - # Account for people who put trailing slashes in PATH elements. -case $as_dir/ in #(( - ./ | .// | /[cC]/* | \ - /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ - ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ - /usr/ucb/* ) ;; - *) - # OSF1 and SCO ODT 3.0 have their own names for install. - # Don't use installbsd from OSF since it installs stuff as root - # by default. - for ac_prog in ginstall scoinst install; do - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then - if test $ac_prog = install && - grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then - # AIX install. It has an incompatible calling convention. - : - elif test $ac_prog = install && - grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then - # program-specific install script used by HP pwplus--don't use. - : - else - rm -rf conftest.one conftest.two conftest.dir - echo one > conftest.one - echo two > conftest.two - mkdir conftest.dir - if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && - test -s conftest.one && test -s conftest.two && - test -s conftest.dir/conftest.one && - test -s conftest.dir/conftest.two - then - ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" - break 3 - fi - fi - fi - done - done - ;; -esac - - done -IFS=$as_save_IFS - -rm -rf conftest.one conftest.two conftest.dir - -fi - if test "${ac_cv_path_install+set}" = set; then - INSTALL=$ac_cv_path_install - else - # As a last resort, use the slow shell script. Don't cache a - # value for INSTALL 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. - INSTALL=$ac_install_sh - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 -$as_echo "$INSTALL" >&6; } - -# Use test -z because SunOS4 sh mishandles braces in ${var-val}. -# It thinks the first close brace ends the variable substitution. -test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' - -test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' - -test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 -$as_echo_n "checking whether build environment is sane... " >&6; } -# Reject unsafe characters in $srcdir or the absolute working directory -# name. Accept space and tab only in the latter. -am_lf=' -' -case `pwd` in - *[\\\"\#\$\&\'\`$am_lf]*) - as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;; -esac -case $srcdir in - *[\\\"\#\$\&\'\`$am_lf\ \ ]*) - as_fn_error $? "unsafe srcdir value: '$srcdir'" "$LINENO" 5;; -esac - -# Do 'set' in a subshell so we don't clobber the current shell's -# arguments. Must try -L first in case configure is actually a -# symlink; some systems play weird games with the mod time of symlinks -# (eg FreeBSD returns the mod time of the symlink's containing -# directory). -if ( - am_has_slept=no - for am_try in 1 2; do - echo "timestamp, slept: $am_has_slept" > conftest.file - set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` - if test "$*" = "X"; then - # -L didn't work. - set X `ls -t "$srcdir/configure" conftest.file` - fi - if test "$*" != "X $srcdir/configure conftest.file" \ - && test "$*" != "X conftest.file $srcdir/configure"; then - - # If neither matched, then we have a broken ls. This can happen - # if, for instance, CONFIG_SHELL is bash and it inherits a - # broken ls alias from the environment. This has actually - # happened. Such a system could not be considered "sane". - as_fn_error $? "ls -t appears to fail. Make sure there is not a broken - alias in your environment" "$LINENO" 5 - fi - if test "$2" = conftest.file || test $am_try -eq 2; then - break - fi - # Just in case. - sleep 1 - am_has_slept=yes - done - test "$2" = conftest.file - ) -then - # Ok. - : -else - as_fn_error $? "newly created file is older than distributed files! -Check your system clock" "$LINENO" 5 -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } -# If we didn't sleep, we still need to ensure time stamps of config.status and -# generated files are strictly newer. -am_sleep_pid= -if grep 'slept: no' conftest.file >/dev/null 2>&1; then - ( sleep 1 ) & - am_sleep_pid=$! -fi - -rm -f conftest.file - -test "$program_prefix" != NONE && - program_transform_name="s&^&$program_prefix&;$program_transform_name" -# Use a double $ so make ignores it. -test "$program_suffix" != NONE && - program_transform_name="s&\$&$program_suffix&;$program_transform_name" -# Double any \ or $. -# By default was `s,x,x', remove it if useless. -ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' -program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` - -if test x"${MISSING+set}" != xset; then - case $am_aux_dir in - *\ * | *\ *) - MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; - *) - MISSING="\${SHELL} $am_aux_dir/missing" ;; - esac -fi -# Use eval to expand $SHELL -if eval "$MISSING --is-lightweight"; then - am_missing_run="$MISSING " -else - am_missing_run= - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5 -$as_echo "$as_me: WARNING: 'missing' script is too old or missing" >&2;} -fi - -if test x"${install_sh+set}" != xset; then - case $am_aux_dir in - *\ * | *\ *) - install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; - *) - install_sh="\${SHELL} $am_aux_dir/install-sh" - esac -fi - -# Installed binaries are usually stripped using 'strip' when the user -# run "make install-strip". However 'strip' might not be the right -# tool to use in cross-compilation environments, therefore Automake -# will honor the 'STRIP' environment variable to overrule this program. -if test "$cross_compiling" != no; then - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. -set dummy ${ac_tool_prefix}strip; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_STRIP+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$STRIP"; then - ac_cv_prog_STRIP="$STRIP" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_STRIP="${ac_tool_prefix}strip" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -STRIP=$ac_cv_prog_STRIP -if test -n "$STRIP"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 -$as_echo "$STRIP" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_STRIP"; then - ac_ct_STRIP=$STRIP - # Extract the first word of "strip", so it can be a program name with args. -set dummy strip; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_STRIP+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_STRIP"; then - ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_STRIP="strip" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP -if test -n "$ac_ct_STRIP"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 -$as_echo "$ac_ct_STRIP" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_STRIP" = x; then - STRIP=":" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - STRIP=$ac_ct_STRIP - fi -else - STRIP="$ac_cv_prog_STRIP" -fi - -fi -INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5 -$as_echo_n "checking for a thread-safe mkdir -p... " >&6; } -if test -z "$MKDIR_P"; then - if ${ac_cv_path_mkdir+:} false; then : - $as_echo_n "(cached) " >&6 -else - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_prog in mkdir gmkdir; do - for ac_exec_ext in '' $ac_executable_extensions; do - as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext" || continue - case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( - 'mkdir (GNU coreutils) '* | \ - 'mkdir (coreutils) '* | \ - 'mkdir (fileutils) '4.1*) - ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext - break 3;; - esac - done - done - done -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 - # As a last resort, use the slow shell script. Don't cache a - # 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. - MKDIR_P="$ac_install_sh -d" - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 -$as_echo "$MKDIR_P" >&6; } - -for ac_prog in gawk mawk nawk awk -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_AWK+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$AWK"; then - ac_cv_prog_AWK="$AWK" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_AWK="$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -AWK=$ac_cv_prog_AWK -if test -n "$AWK"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 -$as_echo "$AWK" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$AWK" && break -done - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 -$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } -set x ${MAKE-make} -ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` -if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat >conftest.make <<\_ACEOF -SHELL = /bin/sh -all: - @echo '@@@%%%=$(MAKE)=@@@%%%' -_ACEOF -# GNU make sometimes prints "make[1]: Entering ...", which would confuse us. -case `${MAKE-make} -f conftest.make 2>/dev/null` in - *@@@%%%=?*=@@@%%%*) - eval ac_cv_prog_make_${ac_make}_set=yes;; - *) - eval ac_cv_prog_make_${ac_make}_set=no;; -esac -rm -f conftest.make -fi -if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - SET_MAKE= -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - SET_MAKE="MAKE=${MAKE-make}" -fi - -rm -rf .tst 2>/dev/null -mkdir .tst 2>/dev/null -if test -d .tst; then - am__leading_dot=. -else - am__leading_dot=_ -fi -rmdir .tst 2>/dev/null - -DEPDIR="${am__leading_dot}deps" - -ac_config_commands="$ac_config_commands depfiles" - - -am_make=${MAKE-make} -cat > confinc << 'END' -am__doit: - @echo this is the am__doit target -.PHONY: am__doit -END -# If we don't find an include directive, just comment out the code. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5 -$as_echo_n "checking for style of include used by $am_make... " >&6; } -am__include="#" -am__quote= -_am_result=none -# First try GNU make style include. -echo "include confinc" > confmf -# Ignore all kinds of additional output from 'make'. -case `$am_make -s -f confmf 2> /dev/null` in #( -*the\ am__doit\ target*) - am__include=include - am__quote= - _am_result=GNU - ;; -esac -# Now try BSD make style include. -if test "$am__include" = "#"; then - echo '.include "confinc"' > confmf - case `$am_make -s -f confmf 2> /dev/null` in #( - *the\ am__doit\ target*) - am__include=.include - am__quote="\"" - _am_result=BSD - ;; - esac -fi - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5 -$as_echo "$_am_result" >&6; } -rm -f confinc confmf - -# Check whether --enable-dependency-tracking was given. -if test "${enable_dependency_tracking+set}" = set; then : - enableval=$enable_dependency_tracking; -fi - -if test "x$enable_dependency_tracking" != xno; then - am_depcomp="$ac_aux_dir/depcomp" - AMDEPBACKSLASH='\' - am__nodep='_no' -fi - if test "x$enable_dependency_tracking" != xno; then - AMDEP_TRUE= - AMDEP_FALSE='#' -else - AMDEP_TRUE='#' - AMDEP_FALSE= -fi - - -# Check whether --enable-silent-rules was given. -if test "${enable_silent_rules+set}" = set; then : - enableval=$enable_silent_rules; -fi - -case $enable_silent_rules in # ((( - yes) AM_DEFAULT_VERBOSITY=0;; - no) AM_DEFAULT_VERBOSITY=1;; - *) AM_DEFAULT_VERBOSITY=1;; -esac -am_make=${MAKE-make} -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 -$as_echo_n "checking whether $am_make supports nested variables... " >&6; } -if ${am_cv_make_support_nested_variables+:} false; then : - $as_echo_n "(cached) " >&6 -else - if $as_echo 'TRUE=$(BAR$(V)) -BAR0=false -BAR1=true -V=1 -am__doit: - @$(TRUE) -.PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then - am_cv_make_support_nested_variables=yes -else - am_cv_make_support_nested_variables=no -fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 -$as_echo "$am_cv_make_support_nested_variables" >&6; } -if test $am_cv_make_support_nested_variables = yes; then - AM_V='$(V)' - AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' -else - AM_V=$AM_DEFAULT_VERBOSITY - AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY -fi -AM_BACKSLASH='\' - -if test "`cd $srcdir && pwd`" != "`pwd`"; then - # Use -I$(srcdir) only when $(srcdir) != ., so that make's output - # is not polluted with repeated "-I." - am__isrc=' -I$(srcdir)' - # test to see if srcdir already configured - if test -f $srcdir/config.status; then - as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 - fi -fi - -# test whether we have cygpath -if test -z "$CYGPATH_W"; then - if (cygpath --version) >/dev/null 2>/dev/null; then - CYGPATH_W='cygpath -w' - else - CYGPATH_W=echo - fi -fi - - -# Define the identity of the package. - PACKAGE='tinc' - VERSION='1.1pre15' - - -cat >>confdefs.h <<_ACEOF -#define PACKAGE "$PACKAGE" -_ACEOF - - -cat >>confdefs.h <<_ACEOF -#define VERSION "$VERSION" -_ACEOF - -# Some tools Automake needs. - -ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} - - -AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} - - -AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} - - -AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} - - -MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} - -# For better backward compatibility. To be removed once Automake 1.9.x -# dies out for good. For more background, see: -# -# -mkdir_p='$(MKDIR_P)' - -# We need awk for the "check" target (and possibly the TAP driver). The -# system "awk" is bad on some platforms. -# Always define AMTAR for backward compatibility. Yes, it's still used -# in the wild :-( We should find a proper way to deprecate it ... -AMTAR='$${TAR-tar}' - - -# We'll loop over all known methods to create a tar archive until one works. -_am_tools='gnutar pax cpio none' - -am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -' - - - - - -depcc="$CC" am_compiler_list= - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 -$as_echo_n "checking dependency style of $depcc... " >&6; } -if ${am_cv_CC_dependencies_compiler_type+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then - # We make a subdir and do the tests there. Otherwise we can end up - # making bogus files that we don't know about and never remove. For - # instance it was reported that on HP-UX the gcc test will end up - # making a dummy file named 'D' -- because '-MD' means "put the output - # in D". - rm -rf conftest.dir - mkdir conftest.dir - # Copy depcomp to subdir because otherwise we won't find it if we're - # using a relative directory. - cp "$am_depcomp" conftest.dir - cd conftest.dir - # We will build objects and dependencies in a subdirectory because - # it helps to detect inapplicable dependency modes. For instance - # both Tru64's cc and ICC support -MD to output dependencies as a - # side effect of compilation, but ICC will put the dependencies in - # the current directory while Tru64 will put them in the object - # directory. - mkdir sub - - am_cv_CC_dependencies_compiler_type=none - if test "$am_compiler_list" = ""; then - am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` - fi - am__universal=false - case " $depcc " in #( - *\ -arch\ *\ -arch\ *) am__universal=true ;; - esac - - for depmode in $am_compiler_list; do - # Setup a source with many dependencies, because some compilers - # like to wrap large dependency lists on column 80 (with \), and - # we should not choose a depcomp mode which is confused by this. - # - # We need to recreate these files for each test, as the compiler may - # overwrite some of them when testing with obscure command lines. - # This happens at least with the AIX C compiler. - : > sub/conftest.c - for i in 1 2 3 4 5 6; do - echo '#include "conftst'$i'.h"' >> sub/conftest.c - # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with - # Solaris 10 /bin/sh. - echo '/* dummy */' > sub/conftst$i.h - done - echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf - - # We check with '-c' and '-o' for the sake of the "dashmstdout" - # mode. It turns out that the SunPro C++ compiler does not properly - # handle '-M -o', and we need to detect this. Also, some Intel - # versions had trouble with output in subdirs. - am__obj=sub/conftest.${OBJEXT-o} - am__minus_obj="-o $am__obj" - case $depmode in - gcc) - # This depmode causes a compiler race in universal mode. - test "$am__universal" = false || continue - ;; - nosideeffect) - # After this tag, mechanisms are not by side-effect, so they'll - # only be used when explicitly requested. - if test "x$enable_dependency_tracking" = xyes; then - continue - else - break - fi - ;; - msvc7 | msvc7msys | msvisualcpp | msvcmsys) - # This compiler won't grok '-c -o', but also, the minuso test has - # not run yet. These depmodes are late enough in the game, and - # so weak that their functioning should not be impacted. - am__obj=conftest.${OBJEXT-o} - am__minus_obj= - ;; - none) break ;; - esac - if depmode=$depmode \ - source=sub/conftest.c object=$am__obj \ - depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ - $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ - >/dev/null 2>conftest.err && - grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && - grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && - grep $am__obj sub/conftest.Po > /dev/null 2>&1 && - ${MAKE-make} -s -f confmf > /dev/null 2>&1; then - # icc doesn't choke on unknown options, it will just issue warnings - # or remarks (even with -Werror). So we grep stderr for any message - # that says an option was ignored or not supported. - # When given -MP, icc 7.0 and 7.1 complain thusly: - # icc: Command line warning: ignoring option '-M'; no argument required - # The diagnosis changed in icc 8.0: - # icc: Command line remark: option '-MP' not supported - if (grep 'ignoring option' conftest.err || - grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else - am_cv_CC_dependencies_compiler_type=$depmode - break - fi - fi - done - - cd .. - rm -rf conftest.dir -else - am_cv_CC_dependencies_compiler_type=none -fi - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 -$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } -CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type - - if - test "x$enable_dependency_tracking" != xno \ - && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then - am__fastdepCC_TRUE= - am__fastdepCC_FALSE='#' -else - am__fastdepCC_TRUE='#' - am__fastdepCC_FALSE= -fi - - - -# POSIX will say in a future version that running "rm -f" with no argument -# is OK; and we want to be able to make that assumption in our Makefile -# recipes. So use an aggressive probe to check that the usage we want is -# actually supported "in the wild" to an acceptable degree. -# See automake bug#10828. -# To make any issue more visible, cause the running configure to be aborted -# by default if the 'rm' program in use doesn't match our expectations; the -# user can still override this though. -if rm -f && rm -fr && rm -rf; then : OK; else - cat >&2 <<'END' -Oops! - -Your 'rm' program seems unable to run without file operands specified -on the command line, even when the '-f' option is present. This is contrary -to the behaviour of most rm programs out there, and not conforming with -the upcoming POSIX standard: - -Please tell bug-automake@gnu.org about your system, including the value -of your $PATH and any error possibly output before this message. This -can help us improve future automake versions. - -END - if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then - echo 'Configuration will proceed anyway, since you have set the' >&2 - echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 - echo >&2 - else - cat >&2 <<'END' -Aborting the configuration process, to ensure you take notice of the issue. - -You can download and install GNU coreutils to get an 'rm' implementation -that behaves properly: . - -If you want to complete the configuration process using your problematic -'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM -to "yes", and re-run configure. - -END - as_fn_error $? "Your 'rm' program is bad, sorry." "$LINENO" 5 - fi -fi - -ac_config_headers="$ac_config_headers config.h" - - -# Check whether --enable-silent-rules was given. -if test "${enable_silent_rules+set}" = set; then : - enableval=$enable_silent_rules; -fi - -case $enable_silent_rules in # ((( - yes) AM_DEFAULT_VERBOSITY=0;; - no) AM_DEFAULT_VERBOSITY=1;; - *) AM_DEFAULT_VERBOSITY=0;; -esac -am_make=${MAKE-make} -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 -$as_echo_n "checking whether $am_make supports nested variables... " >&6; } -if ${am_cv_make_support_nested_variables+:} false; then : - $as_echo_n "(cached) " >&6 -else - if $as_echo 'TRUE=$(BAR$(V)) -BAR0=false -BAR1=true -V=1 -am__doit: - @$(TRUE) -.PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then - am_cv_make_support_nested_variables=yes -else - am_cv_make_support_nested_variables=no -fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 -$as_echo "$am_cv_make_support_nested_variables" >&6; } -if test $am_cv_make_support_nested_variables = yes; then - AM_V='$(V)' - AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' -else - AM_V=$AM_DEFAULT_VERBOSITY - AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY -fi -AM_BACKSLASH='\' - - -# Enable GNU extensions. -# Define this here, not in acconfig's @TOP@ section, since definitions -# in the latter don't make it into the configure-time tests. - $as_echo "#define __USE_BSD 1" >>confdefs.h @@ -4843,19 +4858,450 @@ ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $ ac_compiler_gnu=$ac_cv_c_compiler_gnu -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 -$as_echo_n "checking whether ln -s works... " >&6; } -LN_S=$as_ln_s -if test "$LN_S" = "ln -s"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 +$as_echo_n "checking for a sed that does not truncate output... " >&6; } +if ${ac_cv_path_SED+:} false; then : + $as_echo_n "(cached) " >&6 else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 -$as_echo "no, using $LN_S" >&6; } + ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ + for ac_i in 1 2 3 4 5 6 7; do + ac_script="$ac_script$as_nl$ac_script" + done + echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed + { ac_script=; unset ac_script;} + if test -z "$SED"; then + ac_path_SED_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in sed gsed; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_SED="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_SED" || continue +# Check for GNU ac_path_SED and select it if it is found. + # Check for GNU $ac_path_SED +case `"$ac_path_SED" --version 2>&1` in +*GNU*) + ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo '' >> "conftest.nl" + "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_SED_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_SED="$ac_path_SED" + ac_path_SED_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_SED_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_SED"; then + as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5 + fi +else + ac_cv_path_SED=$SED +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 +$as_echo "$ac_cv_path_SED" >&6; } + SED="$ac_cv_path_SED" + rm -f conftest.sed + + + + + # allow to override gcov location + +# Check whether --with-gcov was given. +if test "${with_gcov+set}" = set; then : + withval=$with_gcov; _AX_CODE_COVERAGE_GCOV_PROG_WITH=$with_gcov +else + _AX_CODE_COVERAGE_GCOV_PROG_WITH=gcov +fi + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build with code coverage support" >&5 +$as_echo_n "checking whether to build with code coverage support... " >&6; } + # Check whether --enable-code-coverage was given. +if test "${enable_code_coverage+set}" = set; then : + enableval=$enable_code_coverage; +else + enable_code_coverage=no +fi + + + if test x$enable_code_coverage = xyes; then + CODE_COVERAGE_ENABLED_TRUE= + CODE_COVERAGE_ENABLED_FALSE='#' +else + CODE_COVERAGE_ENABLED_TRUE='#' + CODE_COVERAGE_ENABLED_FALSE= +fi + + CODE_COVERAGE_ENABLED=$enable_code_coverage + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_code_coverage" >&5 +$as_echo "$enable_code_coverage" >&6; } + + if test "$enable_code_coverage" = "yes" ; then : + + # check for gcov + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}$_AX_CODE_COVERAGE_GCOV_PROG_WITH", so it can be a program name with args. +set dummy ${ac_tool_prefix}$_AX_CODE_COVERAGE_GCOV_PROG_WITH; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_GCOV+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$GCOV"; then + ac_cv_prog_GCOV="$GCOV" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_GCOV="${ac_tool_prefix}$_AX_CODE_COVERAGE_GCOV_PROG_WITH" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +GCOV=$ac_cv_prog_GCOV +if test -n "$GCOV"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GCOV" >&5 +$as_echo "$GCOV" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_GCOV"; then + ac_ct_GCOV=$GCOV + # Extract the first word of "$_AX_CODE_COVERAGE_GCOV_PROG_WITH", so it can be a program name with args. +set dummy $_AX_CODE_COVERAGE_GCOV_PROG_WITH; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_GCOV+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_GCOV"; then + ac_cv_prog_ac_ct_GCOV="$ac_ct_GCOV" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_GCOV="$_AX_CODE_COVERAGE_GCOV_PROG_WITH" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_GCOV=$ac_cv_prog_ac_ct_GCOV +if test -n "$ac_ct_GCOV"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_GCOV" >&5 +$as_echo "$ac_ct_GCOV" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_GCOV" = x; then + GCOV=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + GCOV=$ac_ct_GCOV + fi +else + GCOV="$ac_cv_prog_GCOV" +fi + + if test "X$GCOV" = "X:"; then : + as_fn_error $? "gcov is needed to do coverage" "$LINENO" 5 +fi + + + if test "$GCC" = "no" ; then : + + as_fn_error $? "not compiling with gcc, which is required for gcov code coverage" "$LINENO" 5 + +fi + + # Extract the first word of "lcov", so it can be a program name with args. +set dummy lcov; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_LCOV+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$LCOV"; then + ac_cv_prog_LCOV="$LCOV" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_LCOV="lcov" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +LCOV=$ac_cv_prog_LCOV +if test -n "$LCOV"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LCOV" >&5 +$as_echo "$LCOV" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + # Extract the first word of "genhtml", so it can be a program name with args. +set dummy genhtml; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_GENHTML+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$GENHTML"; then + ac_cv_prog_GENHTML="$GENHTML" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_GENHTML="genhtml" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +GENHTML=$ac_cv_prog_GENHTML +if test -n "$GENHTML"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GENHTML" >&5 +$as_echo "$GENHTML" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } fi + if test -z "$LCOV" ; then : + + as_fn_error $? "To enable code coverage reporting you must have lcov installed" "$LINENO" 5 + +fi + + if test -z "$GENHTML" ; then : + + as_fn_error $? "Could not find genhtml from the lcov package" "$LINENO" 5 + +fi + + CODE_COVERAGE_CPPFLAGS="-DNDEBUG" + CODE_COVERAGE_CFLAGS="-O0 -g -fprofile-arcs -ftest-coverage" + CODE_COVERAGE_CXXFLAGS="-O0 -g -fprofile-arcs -ftest-coverage" + CODE_COVERAGE_LIBS="-lgcov" + CODE_COVERAGE_LDFLAGS="$CODE_COVERAGE_LIBS" + + + + + + + + CODE_COVERAGE_RULES_CHECK=' + -$(A''M_V_at)$(MAKE) $(AM_MAKEFLAGS) -k check + $(A''M_V_at)$(MAKE) $(AM_MAKEFLAGS) code-coverage-capture +' + CODE_COVERAGE_RULES_CAPTURE=' + $(code_coverage_v_lcov_cap)$(LCOV) $(code_coverage_quiet) $(addprefix --directory ,$(CODE_COVERAGE_DIRECTORY)) --capture --output-file "$(CODE_COVERAGE_OUTPUT_FILE).tmp" --test-name "$(call code_coverage_sanitize,$(PACKAGE_NAME)-$(PACKAGE_VERSION))" --no-checksum --compat-libtool $(CODE_COVERAGE_LCOV_SHOPTS) $(CODE_COVERAGE_LCOV_OPTIONS) + $(code_coverage_v_lcov_ign)$(LCOV) $(code_coverage_quiet) $(addprefix --directory ,$(CODE_COVERAGE_DIRECTORY)) --remove "$(CODE_COVERAGE_OUTPUT_FILE).tmp" "/tmp/*" $(CODE_COVERAGE_IGNORE_PATTERN) --output-file "$(CODE_COVERAGE_OUTPUT_FILE)" $(CODE_COVERAGE_LCOV_SHOPTS) $(CODE_COVERAGE_LCOV_RMOPTS) + -@rm -f $(CODE_COVERAGE_OUTPUT_FILE).tmp + $(code_coverage_v_genhtml)LANG=C $(GENHTML) $(code_coverage_quiet) $(addprefix --prefix ,$(CODE_COVERAGE_DIRECTORY)) --output-directory "$(CODE_COVERAGE_OUTPUT_DIRECTORY)" --title "$(PACKAGE_NAME)-$(PACKAGE_VERSION) Code Coverage" --legend --show-details "$(CODE_COVERAGE_OUTPUT_FILE)" $(CODE_COVERAGE_GENHTML_OPTIONS) + @echo "file://$(abs_builddir)/$(CODE_COVERAGE_OUTPUT_DIRECTORY)/index.html" +' + CODE_COVERAGE_RULES_CLEAN=' +clean: code-coverage-clean +distclean: code-coverage-clean +code-coverage-clean: + -$(LCOV) --directory $(top_builddir) -z + -rm -rf $(CODE_COVERAGE_OUTPUT_FILE) $(CODE_COVERAGE_OUTPUT_FILE).tmp $(CODE_COVERAGE_OUTPUT_DIRECTORY) + -find . \( -name "*.gcda" -o -name "*.gcno" -o -name "*.gcov" \) -delete +' + +else + + CODE_COVERAGE_RULES_CHECK=' + @echo "Need to reconfigure with --enable-code-coverage" +' + CODE_COVERAGE_RULES_CAPTURE="$CODE_COVERAGE_RULES_CHECK" + CODE_COVERAGE_RULES_CLEAN='' + +fi + +CODE_COVERAGE_RULES=' +# Code coverage +# +# Optional: +# - CODE_COVERAGE_DIRECTORY: Top-level directory for code coverage reporting. +# Multiple directories may be specified, separated by whitespace. +# (Default: $(top_builddir)) +# - CODE_COVERAGE_OUTPUT_FILE: Filename and path for the .info file generated +# by lcov for code coverage. (Default: +# $(PACKAGE_NAME)-$(PACKAGE_VERSION)-coverage.info) +# - CODE_COVERAGE_OUTPUT_DIRECTORY: Directory for generated code coverage +# reports to be created. (Default: +# $(PACKAGE_NAME)-$(PACKAGE_VERSION)-coverage) +# - CODE_COVERAGE_BRANCH_COVERAGE: Set to 1 to enforce branch coverage, +# set to 0 to disable it and leave empty to stay with the default. +# (Default: empty) +# - CODE_COVERAGE_LCOV_SHOPTS_DEFAULT: Extra options shared between both lcov +# instances. (Default: based on $CODE_COVERAGE_BRANCH_COVERAGE) +# - CODE_COVERAGE_LCOV_SHOPTS: Extra options to shared between both lcov +# instances. (Default: $CODE_COVERAGE_LCOV_SHOPTS_DEFAULT) +# - CODE_COVERAGE_LCOV_OPTIONS_GCOVPATH: --gcov-tool pathtogcov +# - CODE_COVERAGE_LCOV_OPTIONS_DEFAULT: Extra options to pass to the +# collecting lcov instance. (Default: $CODE_COVERAGE_LCOV_OPTIONS_GCOVPATH) +# - CODE_COVERAGE_LCOV_OPTIONS: Extra options to pass to the collecting lcov +# instance. (Default: $CODE_COVERAGE_LCOV_OPTIONS_DEFAULT) +# - CODE_COVERAGE_LCOV_RMOPTS_DEFAULT: Extra options to pass to the filtering +# lcov instance. (Default: empty) +# - CODE_COVERAGE_LCOV_RMOPTS: Extra options to pass to the filtering lcov +# instance. (Default: $CODE_COVERAGE_LCOV_RMOPTS_DEFAULT) +# - CODE_COVERAGE_GENHTML_OPTIONS_DEFAULT: Extra options to pass to the +# genhtml instance. (Default: based on $CODE_COVERAGE_BRANCH_COVERAGE) +# - CODE_COVERAGE_GENHTML_OPTIONS: Extra options to pass to the genhtml +# instance. (Default: $CODE_COVERAGE_GENHTML_OPTIONS_DEFAULT) +# - CODE_COVERAGE_IGNORE_PATTERN: Extra glob pattern of files to ignore +# +# The generated report will be titled using the $(PACKAGE_NAME) and +# $(PACKAGE_VERSION). In order to add the current git hash to the title, +# use the git-version-gen script, available online. + +# Optional variables +CODE_COVERAGE_DIRECTORY ?= $(top_builddir) +CODE_COVERAGE_OUTPUT_FILE ?= $(PACKAGE_NAME)-$(PACKAGE_VERSION)-coverage.info +CODE_COVERAGE_OUTPUT_DIRECTORY ?= $(PACKAGE_NAME)-$(PACKAGE_VERSION)-coverage +CODE_COVERAGE_BRANCH_COVERAGE ?= +CODE_COVERAGE_LCOV_SHOPTS_DEFAULT ?= $(if $(CODE_COVERAGE_BRANCH_COVERAGE),\ +--rc lcov_branch_coverage=$(CODE_COVERAGE_BRANCH_COVERAGE)) +CODE_COVERAGE_LCOV_SHOPTS ?= $(CODE_COVERAGE_LCOV_SHOPTS_DEFAULT) +CODE_COVERAGE_LCOV_OPTIONS_GCOVPATH ?= --gcov-tool "$(GCOV)" +CODE_COVERAGE_LCOV_OPTIONS_DEFAULT ?= $(CODE_COVERAGE_LCOV_OPTIONS_GCOVPATH) +CODE_COVERAGE_LCOV_OPTIONS ?= $(CODE_COVERAGE_LCOV_OPTIONS_DEFAULT) +CODE_COVERAGE_LCOV_RMOPTS_DEFAULT ?= +CODE_COVERAGE_LCOV_RMOPTS ?= $(CODE_COVERAGE_LCOV_RMOPTS_DEFAULT) +CODE_COVERAGE_GENHTML_OPTIONS_DEFAULT ?=\ +$(if $(CODE_COVERAGE_BRANCH_COVERAGE),\ +--rc genhtml_branch_coverage=$(CODE_COVERAGE_BRANCH_COVERAGE)) +CODE_COVERAGE_GENHTML_OPTIONS ?= $(CODE_COVERAGE_GENHTML_OPTIONS_DEFAULTS) +CODE_COVERAGE_IGNORE_PATTERN ?= + +code_coverage_v_lcov_cap = $(code_coverage_v_lcov_cap_$(V)) +code_coverage_v_lcov_cap_ = $(code_coverage_v_lcov_cap_$(AM_DEFAULT_VERBOSITY)) +code_coverage_v_lcov_cap_0 = @echo " LCOV --capture"\ + $(CODE_COVERAGE_OUTPUT_FILE); +code_coverage_v_lcov_ign = $(code_coverage_v_lcov_ign_$(V)) +code_coverage_v_lcov_ign_ = $(code_coverage_v_lcov_ign_$(AM_DEFAULT_VERBOSITY)) +code_coverage_v_lcov_ign_0 = @echo " LCOV --remove /tmp/*"\ + $(CODE_COVERAGE_IGNORE_PATTERN); +code_coverage_v_genhtml = $(code_coverage_v_genhtml_$(V)) +code_coverage_v_genhtml_ = $(code_coverage_v_genhtml_$(AM_DEFAULT_VERBOSITY)) +code_coverage_v_genhtml_0 = @echo " GEN " $(CODE_COVERAGE_OUTPUT_DIRECTORY); +code_coverage_quiet = $(code_coverage_quiet_$(V)) +code_coverage_quiet_ = $(code_coverage_quiet_$(AM_DEFAULT_VERBOSITY)) +code_coverage_quiet_0 = --quiet + +# sanitizes the test-name: replaces with underscores: dashes and dots +code_coverage_sanitize = $(subst -,_,$(subst .,_,$(1))) + +# Use recursive makes in order to ignore errors during check +check-code-coverage:'"$CODE_COVERAGE_RULES_CHECK"' + +# Capture code coverage data +code-coverage-capture: code-coverage-capture-hook'"$CODE_COVERAGE_RULES_CAPTURE"' + +# Hook rule executed before code-coverage-capture, overridable by the user +code-coverage-capture-hook: + +'"$CODE_COVERAGE_RULES_CLEAN"' + +GITIGNOREFILES ?= +GITIGNOREFILES += $(CODE_COVERAGE_OUTPUT_FILE) $(CODE_COVERAGE_OUTPUT_DIRECTORY) + +A''M_DISTCHECK_CONFIGURE_FLAGS ?= +A''M_DISTCHECK_CONFIGURE_FLAGS += --disable-code-coverage + +.PHONY: check-code-coverage code-coverage-capture code-coverage-capture-hook code-coverage-clean +' + + + + +if test "x$enable_code_coverage" = "xyes" -a "x$origcflags" = "x"; then : + CFLAGS="" +fi # Make sure we can run config.sub. @@ -5080,7 +5526,7 @@ fi if test "x$with_systemd" = "xyes"; then : - systemd_path="/lib/systemd/system" + systemd_path="\${libdir}/systemd/system" else if test "x$with_systemd" = "xno"; then : systemd=false @@ -5770,6 +6216,40 @@ $as_echo "#define __malloc__ /**/" >>confdefs.h fi + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working __nonnull__ attribute" >&5 +$as_echo_n "checking for working __nonnull__ attribute... " >&6; } +if ${tinc_cv_attribute___nonnull__+:} false; then : + $as_echo_n "(cached) " >&6 +else + + tempcflags="$CFLAGS" + CFLAGS="$CFLAGS -Wall -Werror" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +void *test(void) __attribute__ ((__nonnull__)); + void *test(void) { return (void *)0; } + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + tinc_cv_attribute___nonnull__=yes +else + tinc_cv_attribute___nonnull__=no + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + CFLAGS="$tempcflags" + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tinc_cv_attribute___nonnull__" >&5 +$as_echo "$tinc_cv_attribute___nonnull__" >&6; } + + if test ${tinc_cv_attribute___nonnull__} = no; then + +$as_echo "#define __nonnull__ /**/" >>confdefs.h + + fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working __warn_unused_result__ attribute" >&5 $as_echo_n "checking for working __warn_unused_result__ attribute... " >&6; } if ${tinc_cv_attribute___warn_unused_result__+:} false; then : @@ -5938,7 +6418,7 @@ cat >>confdefs.h <<_ACEOF _ACEOF -for ac_func in asprintf daemon fchmod flock ftime fork gettimeofday mlockall putenv recvmmsg strsignal nanosleep unsetenv vsyslog devname fdevname +for ac_func in asprintf daemon fchmod flock fork gettimeofday mlockall putenv recvmmsg strsignal nanosleep unsetenv vsyslog devname fdevname do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" @@ -6318,7 +6798,46 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ncurses_initscr" >&5 $as_echo "$ac_cv_lib_ncurses_initscr" >&6; } if test "x$ac_cv_lib_ncurses_initscr" = xyes; then : - CURSES_LIBS="-lncurses" + CURSES_LIBS="-lncurses"; { $as_echo "$as_me:${as_lineno-$LINENO}: checking for wtimeout in -ltinfo" >&5 +$as_echo_n "checking for wtimeout in -ltinfo... " >&6; } +if ${ac_cv_lib_tinfo_wtimeout+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ltinfo $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char wtimeout (); +int +main () +{ +return wtimeout (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_tinfo_wtimeout=yes +else + ac_cv_lib_tinfo_wtimeout=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_tinfo_wtimeout" >&5 +$as_echo "$ac_cv_lib_tinfo_wtimeout" >&6; } +if test "x$ac_cv_lib_tinfo_wtimeout" = xyes; then : + CURSES_LIBS+=" -ltinfo" +fi + else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for initscr in -lcurses" >&5 $as_echo_n "checking for initscr in -lcurses... " >&6; } @@ -7009,17 +7528,34 @@ fi done - ac_fn_c_check_decl "$LINENO" "OpenSSL_add_all_algorithms EVP_aes_256_cfb" "ac_cv_have_decl_OpenSSL_add_all_algorithms_EVP_aes_256_cfb" "#include + ac_fn_c_check_decl "$LINENO" "OpenSSL_add_all_algorithms" "ac_cv_have_decl_OpenSSL_add_all_algorithms" "#include " -if test "x$ac_cv_have_decl_OpenSSL_add_all_algorithms_EVP_aes_256_cfb" = xyes; then : +if test "x$ac_cv_have_decl_OpenSSL_add_all_algorithms" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF -#define HAVE_DECL_OPENSSL_ADD_ALL_ALGORITHMS_EVP_AES_256_CFB $ac_have_decl +#define HAVE_DECL_OPENSSL_ADD_ALL_ALGORITHMS $ac_have_decl +_ACEOF +if test $ac_have_decl = 1; then : + +else + as_fn_error $? "Missing LibreSSL/OpenSSL functionality, make sure you have installed the latest version." "$LINENO" 5; break +fi +ac_fn_c_check_decl "$LINENO" "EVP_aes_256_cfb" "ac_cv_have_decl_EVP_aes_256_cfb" "#include + +" +if test "x$ac_cv_have_decl_EVP_aes_256_cfb" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_EVP_AES_256_CFB $ac_have_decl _ACEOF if test $ac_have_decl = 1; then : @@ -7037,6 +7573,17 @@ if eval test \"x\$"$as_ac_var"\" = x"yes"; then : #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF +fi +done + + for ac_func in HMAC_CTX_new +do : + ac_fn_c_check_func "$LINENO" "HMAC_CTX_new" "ac_cv_func_HMAC_CTX_new" +if test "x$ac_cv_func_HMAC_CTX_new" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_HMAC_CTX_NEW 1 +_ACEOF + fi done @@ -7187,7 +7734,12 @@ fi fi -ac_config_files="$ac_config_files Makefile src/Makefile doc/Makefile gui/Makefile test/Makefile systemd/Makefile" +if test "x$runstatedir" = "x"; then + runstatedir='${localstatedir}/run' + +fi + +ac_config_files="$ac_config_files Makefile src/Makefile doc/Makefile test/Makefile systemd/Makefile" cat >confcache <<\_ACEOF @@ -7307,14 +7859,6 @@ $as_echo_n "checking that generated files are newer than configure... " >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5 $as_echo "done" >&6; } -if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then - as_fn_error $? "conditional \"AMDEP\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then - as_fn_error $? "conditional \"am__fastdepCC\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi if test -n "$EXEEXT"; then am__EXEEXT_TRUE= am__EXEEXT_FALSE='#' @@ -7323,6 +7867,18 @@ else am__EXEEXT_FALSE= fi +if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then + as_fn_error $? "conditional \"AMDEP\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then + as_fn_error $? "conditional \"am__fastdepCC\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${CODE_COVERAGE_ENABLED_TRUE}" && test -z "${CODE_COVERAGE_ENABLED_FALSE}"; then + as_fn_error $? "conditional \"CODE_COVERAGE_ENABLED\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi if test -z "${LINUX_TRUE}" && test -z "${LINUX_FALSE}"; then as_fn_error $? "conditional \"LINUX\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 @@ -7772,7 +8328,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by tinc $as_me 1.1pre15, which was +This file was extended by tinc $as_me 1.1pre17, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -7838,7 +8394,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -tinc config.status 1.1pre15 +tinc config.status 1.1pre17 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" @@ -7957,7 +8513,7 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # # INIT-COMMANDS # -AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" +AMDEP_TRUE="$AMDEP_TRUE" MAKE="${MAKE-make}" _ACEOF @@ -7967,12 +8523,11 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 for ac_config_target in $ac_config_targets do case $ac_config_target in - "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; + "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; "src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;; "doc/Makefile") CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;; - "gui/Makefile") CONFIG_FILES="$CONFIG_FILES gui/Makefile" ;; "test/Makefile") CONFIG_FILES="$CONFIG_FILES test/Makefile" ;; "systemd/Makefile") CONFIG_FILES="$CONFIG_FILES systemd/Makefile" ;; @@ -8574,29 +9129,35 @@ $as_echo "$as_me: executing $ac_file commands" >&6;} # Older Autoconf quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. - case $CONFIG_FILES in - *\'*) eval set x "$CONFIG_FILES" ;; - *) set x $CONFIG_FILES ;; - esac + # TODO: see whether this extra hack can be removed once we start + # requiring Autoconf 2.70 or later. + case $CONFIG_FILES in #( + *\'*) : + eval set x "$CONFIG_FILES" ;; #( + *) : + set x $CONFIG_FILES ;; #( + *) : + ;; +esac shift - for mf + # Used to flag and report bootstrapping failures. + am_rc=0 + for am_mf do # Strip MF so we end up with the name of the file. - mf=`echo "$mf" | sed -e 's/:.*$//'` - # Check whether this is an Automake generated Makefile or not. - # We used to match only the files named 'Makefile.in', but - # some people rename them; so instead we look at the file content. - # Grep'ing the first line is not enough: some people post-process - # each Makefile.in and add a new line on top of each file to say so. - # Grep'ing the whole file is not good either: AIX grep has a line + am_mf=`$as_echo "$am_mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile which includes + # dependency-tracking related rules and includes. + # Grep'ing the whole file directly is not great: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. - if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then - dirpart=`$as_dirname -- "$mf" || -$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$mf" : 'X\(//\)[^/]' \| \ - X"$mf" : 'X\(//\)$' \| \ - X"$mf" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$mf" | + sed -n 's,^am--depfiles:.*,X,p' "$am_mf" | grep X >/dev/null 2>&1 \ + || continue + am_dirpart=`$as_dirname -- "$am_mf" || +$as_expr X"$am_mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$am_mf" : 'X\(//\)[^/]' \| \ + X"$am_mf" : 'X\(//\)$' \| \ + X"$am_mf" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$am_mf" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q @@ -8614,53 +9175,48 @@ $as_echo X"$mf" | q } s/.*/./; q'` - else - continue - fi - # Extract the definition of DEPDIR, am__include, and am__quote - # from the Makefile without running 'make'. - DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` - test -z "$DEPDIR" && continue - am__include=`sed -n 's/^am__include = //p' < "$mf"` - test -z "$am__include" && continue - am__quote=`sed -n 's/^am__quote = //p' < "$mf"` - # Find all dependency output files, they are included files with - # $(DEPDIR) in their names. We invoke sed twice because it is the - # simplest approach to changing $(DEPDIR) to its actual value in the - # expansion. - for file in `sed -n " - s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ - sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do - # Make sure the directory exists. - test -f "$dirpart/$file" && continue - fdir=`$as_dirname -- "$file" || -$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$file" : 'X\(//\)[^/]' \| \ - X"$file" : 'X\(//\)$' \| \ - X"$file" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$file" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + am_filepart=`$as_basename -- "$am_mf" || +$as_expr X/"$am_mf" : '.*/\([^/][^/]*\)/*$' \| \ + X"$am_mf" : 'X\(//\)$' \| \ + X"$am_mf" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$am_mf" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } - /^X\(\/\/\)[^/].*/{ + /^X\/\(\/\/\)$/{ s//\1/ q } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ + /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` - as_dir=$dirpart/$fdir; as_fn_mkdir_p - # echo "creating $dirpart/$file" - echo '# dummy' > "$dirpart/$file" - done + { echo "$as_me:$LINENO: cd "$am_dirpart" \ + && sed -e '/# am--include-marker/d' "$am_filepart" \ + | $MAKE -f - am--depfiles" >&5 + (cd "$am_dirpart" \ + && sed -e '/# am--include-marker/d' "$am_filepart" \ + | $MAKE -f - am--depfiles) >&5 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } || am_rc=$? done + if test $am_rc -ne 0; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "Something went wrong bootstrapping makefile fragments + for automatic dependency tracking. Try re-running configure with the + '--disable-dependency-tracking' option to at least be able to build + the package (albeit without support for automatic dependency tracking). +See \`config.log' for more details" "$LINENO" 5; } + fi + { am_dirpart=; unset am_dirpart;} + { am_filepart=; unset am_filepart;} + { am_mf=; unset am_mf;} + { am_rc=; unset am_rc;} + rm -f conftest-deps.mk } ;; diff --git a/configure.ac b/configure.ac index 1a032e6..241f172 100644 --- a/configure.ac +++ b/configure.ac @@ -1,9 +1,10 @@ dnl Process this file with autoconf to produce a configure script. +origcflags="$CFLAGS" + AC_PREREQ(2.61) AC_INIT([tinc], m4_esyscmd_s((git describe || echo UNKNOWN) | sed 's/release-//')) AC_CONFIG_SRCDIR([src/tincd.c]) -AC_GNU_SOURCE AM_INIT_AUTOMAKE([std-options subdir-objects nostdinc silent-rules -Wall]) AC_CONFIG_HEADERS([config.h]) AC_CONFIG_MACRO_DIR([m4]) @@ -19,10 +20,12 @@ dnl Checks for programs. AC_PROG_CC_C99 AC_PROG_CPP AC_PROG_INSTALL -AC_PROG_LN_S - AM_PROG_CC_C_O +dnl Check whether to enable code coverage testing, and if so, clear the default CFLAGS. +AX_CODE_COVERAGE +AS_IF([test "x$enable_code_coverage" = "xyes" -a "x$origcflags" = "x"], [CFLAGS=""]) + dnl Check and set OS AC_CANONICAL_HOST @@ -117,7 +120,7 @@ AC_ARG_WITH(systemd, [ systemd=false ] ) -AS_IF([test "x$with_systemd" = "xyes"], [systemd_path="/lib/systemd/system"], +AS_IF([test "x$with_systemd" = "xyes"], [systemd_path="\${libdir}/systemd/system"], [AS_IF([test "x$with_systemd" = "xno"], [systemd=false])]) AC_SUBST(systemd_path, $systemd_path) @@ -178,6 +181,7 @@ AC_CHECK_HEADERS([netinet/tcp.h netinet/ip_icmp.h netinet/icmp6.h], dnl Checks for typedefs, structures, and compiler characteristics. tinc_ATTRIBUTE(__malloc__) +tinc_ATTRIBUTE(__nonnull__) tinc_ATTRIBUTE(__warn_unused_result__) AC_CHECK_TYPES([struct ether_header, struct arphdr, struct ether_arp, struct ip, struct icmp, struct ip6_hdr, struct icmp6_hdr, struct nd_neighbor_solicit, struct nd_opt_hdr], , , @@ -186,7 +190,7 @@ AC_CHECK_TYPES([struct ether_header, struct arphdr, struct ether_arp, struct ip, dnl Checks for library functions. AC_TYPE_SIGNAL -AC_CHECK_FUNCS([asprintf daemon fchmod flock ftime fork gettimeofday mlockall putenv recvmmsg strsignal nanosleep unsetenv vsyslog devname fdevname], +AC_CHECK_FUNCS([asprintf daemon fchmod flock fork gettimeofday mlockall putenv recvmmsg strsignal nanosleep unsetenv vsyslog devname fdevname], [], [], [#include "$srcdir/src/have.h"] ) @@ -257,6 +261,11 @@ AC_ARG_ENABLE(jumbograms, ] ) -AC_CONFIG_FILES([Makefile src/Makefile doc/Makefile gui/Makefile test/Makefile systemd/Makefile]) +dnl Ensure runstatedir is set if we are using a version of autoconf that does not support it +if test "x$runstatedir" = "x"; then + AC_SUBST([runstatedir], ['${localstatedir}/run']) +fi + +AC_CONFIG_FILES([Makefile src/Makefile doc/Makefile test/Makefile systemd/Makefile]) AC_OUTPUT diff --git a/depcomp b/depcomp index b39f98f..65cbf70 100755 --- a/depcomp +++ b/depcomp @@ -1,9 +1,9 @@ #! /bin/sh # depcomp - compile a program generating dependencies as side-effects -scriptversion=2016-01-11.22; # UTC +scriptversion=2018-03-07.03; # UTC -# Copyright (C) 1999-2017 Free Software Foundation, Inc. +# Copyright (C) 1999-2018 Free Software Foundation, Inc. # 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 @@ -16,7 +16,7 @@ scriptversion=2016-01-11.22; # UTC # GNU General Public License for more details. # You should have received a copy of the GNU General Public License -# along with this program. If not, see . +# along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a @@ -783,7 +783,7 @@ exit 0 # Local Variables: # mode: shell-script # sh-indentation: 2 -# eval: (add-hook 'write-file-hooks 'time-stamp) +# eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC0" diff --git a/doc/Makefile.am b/doc/Makefile.am index aa15b24..e5f3a04 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -1,23 +1,13 @@ ## Process this file with automake to get Makefile.in info_TEXINFOS = tinc.texi +tinc_TEXINFOS = tincinclude.texi man_MANS = tincd.8 tinc.8 tinc.conf.5 tinc-gui.8 -EXTRA_DIST = tincinclude.texi.in tincd.8.in tinc.8.in tinc.conf.5.in tinc-gui.8.in sample-config.tar.gz +EXTRA_DIST = tincinclude.texi.in tincd.8.in tinc.8.in tinc.conf.5.in tinc-gui.8.in sample-config -CLEANFILES = *.html tincd.8 tinc.8 tinc.conf.5 tinc-gui.8 tincinclude.texi sample-config.tar.gz - -# Use `ginstall' in the definition of man_MANS to avoid -# confusion with the `install' target. The install rule transforms `ginstall' -# to install before applying any user-specified name transformations. -transform = s/ginstall/install/; @program_transform_name@ - -# For additional rules usually of interest only to the maintainer, -# see GNUmakefile and Makefile.maint. - -sample-config.tar.gz: sample-config - $(AM_V_GEN)GZIP=$(GZIP_ENV) $(AMTAR) chozf $@ --exclude .svn $< +CLEANFILES = *.html tincd.8 tinc.8 tinc.conf.5 tinc-gui.8 tincinclude.texi tincd.8.html: tincd.8 $(AM_V_GEN)w3mman2html $? > $@ @@ -35,21 +25,20 @@ substitute = sed \ -e s,'@PACKAGE\@',"$(PACKAGE)",g \ -e s,'@VERSION\@',"$(VERSION)",g \ -e s,'@sysconfdir\@',"$(sysconfdir)",g \ + -e s,'@runstatedir\@',"$(runstatedir)",g \ -e s,'@localstatedir\@',"$(localstatedir)",g -tincd.8: tincd.8.in - $(AM_V_GEN)$(substitute) $? > $@ +tincd.8: $(srcdir)/tincd.8.in + $(AM_V_GEN)$(substitute) $(srcdir)/tincd.8.in > $@ -tinc.8: tinc.8.in - $(AM_V_GEN)$(substitute) $? > $@ +tinc.8: $(srcdir)/tinc.8.in + $(AM_V_GEN)$(substitute) $(srcdir)/tinc.8.in > $@ -tinc-gui.8: tinc-gui.8.in - $(AM_V_GEN)$(substitute) $? > $@ +tinc-gui.8: $(srcdir)/tinc-gui.8.in + $(AM_V_GEN)$(substitute) $(srcdir)/tinc-gui.8.in > $@ -tinc.conf.5: tinc.conf.5.in - $(AM_V_GEN)$(substitute) $? > $@ +tinc.conf.5: $(srcdir)/tinc.conf.5.in + $(AM_V_GEN)$(substitute) $(srcdir)/tinc.conf.5.in > $@ -tincinclude.texi: tincinclude.texi.in - $(AM_V_GEN)$(substitute) $? > $@ - -tinc.texi: tincinclude.texi +tincinclude.texi: $(srcdir)/tincinclude.texi.in + $(AM_V_GEN)$(substitute) $(srcdir)/tincinclude.texi.in > $@ diff --git a/doc/Makefile.in b/doc/Makefile.in index 07a02a1..82bcd01 100644 --- a/doc/Makefile.in +++ b/doc/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15.1 from Makefile.am. +# Makefile.in generated by automake 1.16.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2017 Free Software Foundation, Inc. +# Copyright (C) 1994-2018 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -78,6 +78,7 @@ install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : @@ -93,6 +94,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \ $(top_srcdir)/m4/ax_cflags_warn_all.m4 \ $(top_srcdir)/m4/ax_check_compile_flag.m4 \ $(top_srcdir)/m4/ax_check_link_flag.m4 \ + $(top_srcdir)/m4/ax_code_coverage.m4 \ $(top_srcdir)/m4/ax_require_defined.m4 \ $(top_srcdir)/m4/curses.m4 $(top_srcdir)/m4/libgcrypt.m4 \ $(top_srcdir)/m4/lzo.m4 $(top_srcdir)/m4/miniupnpc.m4 \ @@ -198,13 +200,8 @@ man8dir = $(mandir)/man8 NROFF = nroff MANS = $(man_MANS) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) -am__DIST_COMMON = $(srcdir)/Makefile.in texinfo.tex +am__DIST_COMMON = $(srcdir)/Makefile.in $(tinc_TEXINFOS) texinfo.tex DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) - -# Use `ginstall' in the definition of man_MANS to avoid -# confusion with the `install' target. The install rule transforms `ginstall' -# to install before applying any user-specified name transformations. -transform = s/ginstall/install/; @program_transform_name@ ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ @@ -215,6 +212,12 @@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ +CODE_COVERAGE_CFLAGS = @CODE_COVERAGE_CFLAGS@ +CODE_COVERAGE_CPPFLAGS = @CODE_COVERAGE_CPPFLAGS@ +CODE_COVERAGE_CXXFLAGS = @CODE_COVERAGE_CXXFLAGS@ +CODE_COVERAGE_ENABLED = @CODE_COVERAGE_ENABLED@ +CODE_COVERAGE_LDFLAGS = @CODE_COVERAGE_LDFLAGS@ +CODE_COVERAGE_LIBS = @CODE_COVERAGE_LIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CURSES_LIBS = @CURSES_LIBS@ @@ -226,16 +229,18 @@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ +GCOV = @GCOV@ +GENHTML = @GENHTML@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LCOV = @LCOV@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ -LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MINIUPNPC_LIBS = @MINIUPNPC_LIBS@ @@ -250,6 +255,7 @@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ READLINE_LIBS = @READLINE_LIBS@ +SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ @@ -307,13 +313,15 @@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ info_TEXINFOS = tinc.texi +tinc_TEXINFOS = tincinclude.texi man_MANS = tincd.8 tinc.8 tinc.conf.5 tinc-gui.8 -EXTRA_DIST = tincinclude.texi.in tincd.8.in tinc.8.in tinc.conf.5.in tinc-gui.8.in sample-config.tar.gz -CLEANFILES = *.html tincd.8 tinc.8 tinc.conf.5 tinc-gui.8 tincinclude.texi sample-config.tar.gz +EXTRA_DIST = tincinclude.texi.in tincd.8.in tinc.8.in tinc.conf.5.in tinc-gui.8.in sample-config +CLEANFILES = *.html tincd.8 tinc.8 tinc.conf.5 tinc-gui.8 tincinclude.texi substitute = sed \ -e s,'@PACKAGE\@',"$(PACKAGE)",g \ -e s,'@VERSION\@',"$(VERSION)",g \ -e s,'@sysconfdir\@',"$(sysconfdir)",g \ + -e s,'@runstatedir\@',"$(runstatedir)",g \ -e s,'@localstatedir\@',"$(localstatedir)",g all: all-am @@ -337,8 +345,8 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) @@ -393,10 +401,10 @@ $(am__aclocal_m4_deps): else \ rm -rf $(@:.html=.htp); exit 1; \ fi -$(srcdir)/tinc.info: tinc.texi -tinc.dvi: tinc.texi -tinc.pdf: tinc.texi -tinc.html: tinc.texi +$(srcdir)/tinc.info: tinc.texi $(tinc_TEXINFOS) +tinc.dvi: tinc.texi $(tinc_TEXINFOS) +tinc.pdf: tinc.texi $(tinc_TEXINFOS) +tinc.html: tinc.texi $(tinc_TEXINFOS) .dvi.ps: $(AM_V_DVIPS)TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \ $(DVIPS) $(AM_V_texinfo) -o $@ $< @@ -583,7 +591,10 @@ ctags CTAGS: cscope cscopelist: -distdir: $(DISTFILES) +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ @@ -835,12 +846,6 @@ uninstall-man: uninstall-man5 uninstall-man8 .PRECIOUS: Makefile -# For additional rules usually of interest only to the maintainer, -# see GNUmakefile and Makefile.maint. - -sample-config.tar.gz: sample-config - $(AM_V_GEN)GZIP=$(GZIP_ENV) $(AMTAR) chozf $@ --exclude .svn $< - tincd.8.html: tincd.8 $(AM_V_GEN)w3mman2html $? > $@ @@ -853,22 +858,20 @@ tinc-gui.8.html: tinc-gui.8 tinc.conf.5.html: tinc.conf.5 $(AM_V_GEN)w3mman2html $? > $@ -tincd.8: tincd.8.in - $(AM_V_GEN)$(substitute) $? > $@ +tincd.8: $(srcdir)/tincd.8.in + $(AM_V_GEN)$(substitute) $(srcdir)/tincd.8.in > $@ -tinc.8: tinc.8.in - $(AM_V_GEN)$(substitute) $? > $@ +tinc.8: $(srcdir)/tinc.8.in + $(AM_V_GEN)$(substitute) $(srcdir)/tinc.8.in > $@ -tinc-gui.8: tinc-gui.8.in - $(AM_V_GEN)$(substitute) $? > $@ +tinc-gui.8: $(srcdir)/tinc-gui.8.in + $(AM_V_GEN)$(substitute) $(srcdir)/tinc-gui.8.in > $@ -tinc.conf.5: tinc.conf.5.in - $(AM_V_GEN)$(substitute) $? > $@ +tinc.conf.5: $(srcdir)/tinc.conf.5.in + $(AM_V_GEN)$(substitute) $(srcdir)/tinc.conf.5.in > $@ -tincinclude.texi: tincinclude.texi.in - $(AM_V_GEN)$(substitute) $? > $@ - -tinc.texi: tincinclude.texi +tincinclude.texi: $(srcdir)/tincinclude.texi.in + $(AM_V_GEN)$(substitute) $(srcdir)/tincinclude.texi.in > $@ # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. diff --git a/doc/sample-config.tar.gz b/doc/sample-config.tar.gz deleted file mode 100644 index 05b1e898092dd87c28ea91e16443fe1b45960de6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1242 zcmV<01SR_)iwFQ-4XarI1MOLDZ`(Kw?&tgp4n1HvpmA(BFWZ2A=-Y;3yI#?B2kg^L ziJ3&GE%_ulUH<(@DOuAryWnt1?h2S_YC9q+l9C?Mj1@(hV{@q0NRC?vJE54U7sq@} zdL4g_lXlx*=X8)HNvG59rb(I}#7W%gwhy4Q8*_F;3r7~$7ee;Q`a7wH&8pn;92}4C z->iSHm#(aT8YkTY*s>YBr5C#Xhp$=#sakf@IE1^2v@nu6f<iX{T_WkMkC6KXXCr`}sMvf;zC5dYVg|-gLTsWGb zutzYc9LNz_LS~{>ugNlP?!lQEYhXn*R0vgxJfB4kQu2ZPRs8RE;~M|>L5I-yJK$&7(wKv>LBgi18xUD$ z(Aof8guq-ec-aWf3DgMVDocPhn1Lq5GLPdnYMjnxPasK;qx85P9e1K`kEgiN#;J<2 z)F%WI(gmjxGDuOXAZu&{7dR4C?il#H1Y!*qB4u>XD*AKy4Nys`!!eweMoxu8M!&^vO3~mY;TWkI{!4da{iCwc2b}JeGt9o%y($m-{G9|JKMU=`gK=nsHXpjp7(zu zzTfH`8_s`{_S&oY|G4h|?1z5jf1iMVR{s+)(4V03g4;3N%;}e6h}QQ*oEXrJLBL#6 zHs)*>%`@Q%SUFZC%ncXoj2yarMmd&5tuQn07g2^)zr04?3Le3RC6YN^o$flX7;?Fq^iCFJ++qmju*kMlPCOjF4_XE>HlZ?L2Y%8P4!=r zJjegESL6RaXnp^Gm}^VW!8_sEZvbnX&CFS!$C_%YsivB0s;Q=$YWknkcU&{@uK*|j E0NBcJAOHXW diff --git a/doc/sample-config/hosts/alpha b/doc/sample-config/hosts/alpha new file mode 100644 index 0000000..0f5e56a --- /dev/null +++ b/doc/sample-config/hosts/alpha @@ -0,0 +1,15 @@ +# Sample host configuration file + +# The real IP address of this tinc host. Can be used by other tinc hosts. +Address = 123.234.35.67 + +# Portnumber for incoming connections. Default is 655. +Port = 655 + +# Subnet on the virtual private network that is local for this host. +Subnet = 192.168.1.0/24 + +# The public key generated by `tincd -n example -K' is stored here +-----BEGIN RSA PUBLIC KEY----- +... +-----END RSA PUBLIC KEY----- diff --git a/doc/sample-config/hosts/beta b/doc/sample-config/hosts/beta new file mode 100644 index 0000000..6f70d4f --- /dev/null +++ b/doc/sample-config/hosts/beta @@ -0,0 +1,16 @@ +# Sample host configuration file +# This file was generated by host beta. + +# The real IP address of this tinc host. Can be used by other tinc hosts. +Address = 123.45.67.189 + +# Portnumber for incoming connections. Default is 655. +Port = 6500 + +# Subnet on the virtual private network that is local for this host. +Subnet = 192.168.2.0/24 + +# The public key generated by `tincd -n example -K' is stored here +-----BEGIN RSA PUBLIC KEY----- +... +-----END RSA PUBLIC KEY----- diff --git a/doc/sample-config/rsa_key.priv b/doc/sample-config/rsa_key.priv new file mode 100644 index 0000000..ac13536 --- /dev/null +++ b/doc/sample-config/rsa_key.priv @@ -0,0 +1 @@ +# Generate this file with `tincd -n example -K` diff --git a/doc/sample-config/tinc-down b/doc/sample-config/tinc-down new file mode 100644 index 0000000..65b049e --- /dev/null +++ b/doc/sample-config/tinc-down @@ -0,0 +1,4 @@ +#!/bin/sh +# This file closes down the tap device. + +ifconfig $INTERFACE down diff --git a/doc/sample-config/tinc-up b/doc/sample-config/tinc-up new file mode 100644 index 0000000..2d8b4d6 --- /dev/null +++ b/doc/sample-config/tinc-up @@ -0,0 +1,11 @@ +#!/bin/sh +# This file sets up the tap device. +# It gives you the freedom to do anything you want with it. +# Use the correct name for the tap device: +# The environment variable $INTERFACE is set to the right name +# on most platforms, but if it doesn't work try to set it manually. + +# Give it the right ip and netmask. Remember, the subnet of the +# tap device must be larger than that of the individual Subnets +# as defined in the host configuration file! +ifconfig $INTERFACE 192.168.1.1 netmask 255.255.0.0 diff --git a/doc/sample-config/tinc.conf b/doc/sample-config/tinc.conf new file mode 100644 index 0000000..25a61a7 --- /dev/null +++ b/doc/sample-config/tinc.conf @@ -0,0 +1,22 @@ +# Sample tinc configuration file + +# This is a comment. +# Spaces and tabs are eliminated. +# The = sign isn't strictly necessary any longer, though you may want +# to leave it in as it improves readability :) +# Variable names are treated case insensitive. + +# The name of this tinc host. Required. +Name = alpha + +# The internet host to connect with. +# Comment these out to make yourself a listen-only connection +# You must use the name of another tinc host. +# May be used multiple times for redundance. +ConnectTo = beta + +# The tap device tinc will use. +# Default is /dev/tap0 for ethertap or FreeBSD, +# /dev/tun0 for Solaris and OpenBSD, +# and /dev/net/tun for Linux tun/tap device. +Device = /dev/net/tun diff --git a/doc/texinfo.tex b/doc/texinfo.tex index 85f184c..ac5c1d9 100644 --- a/doc/texinfo.tex +++ b/doc/texinfo.tex @@ -3,11 +3,12 @@ % Load plain if necessary, i.e., if running under initex. \expandafter\ifx\csname fmtname\endcsname\relax\input plain\fi % -\def\texinfoversion{2013-02-01.11} +\def\texinfoversion{2018-02-12.17} % % Copyright 1985, 1986, 1988, 1990, 1991, 1992, 1993, 1994, 1995, % 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, -% 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc. +% 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 +% Free Software Foundation, Inc. % % This texinfo.tex file is free software: you can redistribute it and/or % modify it under the terms of the GNU General Public License as @@ -20,7 +21,7 @@ % General Public License for more details. % % You should have received a copy of the GNU General Public License -% along with this program. If not, see . +% along with this program. If not, see . % % As a special exception, when this file is read by TeX when processing % a Texinfo source document, you may use the result without @@ -29,9 +30,9 @@ % % Please try the latest version of texinfo.tex before submitting bug % reports; you can get the latest version from: -% http://ftp.gnu.org/gnu/texinfo/ (the Texinfo release area), or -% http://ftpmirror.gnu.org/texinfo/ (same, via a mirror), or -% http://www.gnu.org/software/texinfo/ (the Texinfo home page) +% https://ftp.gnu.org/gnu/texinfo/ (the Texinfo release area), or +% https://ftpmirror.gnu.org/texinfo/ (same, via a mirror), or +% https://www.gnu.org/software/texinfo/ (the Texinfo home page) % The texinfo.tex in any given distribution could well be out % of date, so if that's what you're using, please check. % @@ -55,7 +56,7 @@ % extent. You can get the existing language-specific files from the % full Texinfo distribution. % -% The GNU Texinfo home page is http://www.gnu.org/software/texinfo. +% The GNU Texinfo home page is https://www.gnu.org/software/texinfo. \message{Loading texinfo [version \texinfoversion]:} @@ -66,6 +67,10 @@ \everyjob{\message{[Texinfo version \texinfoversion]}% \catcode`+=\active \catcode`\_=\active} +% LaTeX's \typeout. This ensures that the messages it is used for +% are identical in format to the corresponding ones from latex/pdflatex. +\def\typeout{\immediate\write17}% + \chardef\other=12 % We never want plain's \outer definition of \+ in Texinfo. @@ -96,7 +101,9 @@ \let\ptexraggedright=\raggedright \let\ptexrbrace=\} \let\ptexslash=\/ +\let\ptexsp=\sp \let\ptexstar=\* +\let\ptexsup=\sup \let\ptext=\t \let\ptextop=\top {\catcode`\'=\active \global\let\ptexquoteright'}% active in plain's math mode @@ -155,22 +162,13 @@ \ifx\putwordDefopt\undefined \gdef\putwordDefopt{User Option}\fi \ifx\putwordDeffunc\undefined \gdef\putwordDeffunc{Function}\fi -% Since the category of space is not known, we have to be careful. -\chardef\spacecat = 10 -\def\spaceisspace{\catcode`\ =\spacecat} +% Give the space character the catcode for a space. +\def\spaceisspace{\catcode`\ =10\relax} + +% Likewise for ^^M, the end of line character. +\def\endlineisspace{\catcode13=10\relax} -% sometimes characters are active, so we need control sequences. -\chardef\ampChar = `\& -\chardef\colonChar = `\: -\chardef\commaChar = `\, \chardef\dashChar = `\- -\chardef\dotChar = `\. -\chardef\exclamChar= `\! -\chardef\hashChar = `\# -\chardef\lquoteChar= `\` -\chardef\questChar = `\? -\chardef\rquoteChar= `\' -\chardef\semiChar = `\; \chardef\slashChar = `\/ \chardef\underChar = `\_ @@ -184,7 +182,7 @@ % Hyphenation fixes. \hyphenation{ Flor-i-da Ghost-script Ghost-view Mac-OS Post-Script - ap-pen-dix bit-map bit-maps + auto-ma-ti-cal-ly ap-pen-dix bit-map bit-maps data-base data-bases eshell fall-ing half-way long-est man-u-script man-u-scripts mini-buf-fer mini-buf-fers over-view par-a-digm par-a-digms rath-er rec-tan-gu-lar ro-bot-ics se-vere-ly set-up spa-ces @@ -193,17 +191,6 @@ wide-spread wrap-around } -% Margin to add to right of even pages, to left of odd pages. -\newdimen\bindingoffset -\newdimen\normaloffset -\newdimen\pagewidth \newdimen\pageheight - -% For a final copy, take out the rectangles -% that mark overfull boxes (in case you have decided -% that the text looks ok even though it passes the margin). -% -\def\finalout{\overfullrule=0pt } - % Sometimes it is convenient to have everything in the transcript file % and nothing on the terminal. We don't just call \tracingall here, % since that produces some useless output on the terminal. We also make @@ -248,6 +235,15 @@ \def\bigbreak{\ifnum\lastpenalty<10000\par\ifdim\lastskip<\bigskipamount \removelastskip\penalty-200\bigskip\fi\fi} +% Output routine +% + +% For a final copy, take out the rectangles +% that mark overfull boxes (in case you have decided +% that the text looks ok even though it passes the margin). +% +\def\finalout{\overfullrule=0pt } + % Do @cropmarks to get crop marks. % \newif\ifcropmarks @@ -270,10 +266,18 @@ % % Another complication is to let the user choose whether \thischapter % (\thissection) refers to the chapter (section) in effect at the top -% of a page, or that at the bottom of a page. The solution is -% described on page 260 of The TeXbook. It involves outputting two -% marks for the sectioning macros, one before the section break, and -% one after. I won't pretend I can describe this better than DEK... +% of a page, or that at the bottom of a page. + +% \domark is called twice inside \chapmacro, to add one +% mark before the section break, and one after. +% In the second call \prevchapterdefs is the same as \lastchapterdefs, +% and \prevsectiondefs is the same as \lastsectiondefs. +% Then if the page is not broken at the mark, some of the previous +% section appears on the page, and we can get the name of this section +% from \firstmark for @everyheadingmarks top. +% @everyheadingmarks bottom uses \botmark. +% +% See page 260 of The TeXbook. \def\domark{% \toks0=\expandafter{\lastchapterdefs}% \toks2=\expandafter{\lastsectiondefs}% @@ -281,11 +285,15 @@ \toks6=\expandafter{\prevsectiondefs}% \toks8=\expandafter{\lastcolordefs}% \mark{% - \the\toks0 \the\toks2 - \noexpand\or \the\toks4 \the\toks6 - \noexpand\else \the\toks8 + \the\toks0 \the\toks2 % 0: marks for @everyheadingmarks top + \noexpand\or \the\toks4 \the\toks6 % 1: for @everyheadingmarks bottom + \noexpand\else \the\toks8 % 2: color marks }% } + +% \gettopheadingmarks, \getbottomheadingmarks, +% \getcolormarks - extract needed part of mark. +% % \topmark doesn't work for the very first chapter (after the title % page or the contents), so we use \firstmark there -- this gets us % the mark with the chapter defs, unless the user sneaks in, e.g., @@ -301,33 +309,67 @@ % Avoid "undefined control sequence" errors. \def\lastchapterdefs{} \def\lastsectiondefs{} +\def\lastsection{} \def\prevchapterdefs{} \def\prevsectiondefs{} \def\lastcolordefs{} +% Margin to add to right of even pages, to left of odd pages. +\newdimen\bindingoffset +\newdimen\normaloffset +\newdimen\txipagewidth \newdimen\txipageheight + % Main output routine. +% \chardef\PAGE = 255 \output = {\onepageout{\pagecontents\PAGE}} \newbox\headlinebox \newbox\footlinebox -% \onepageout takes a vbox as an argument. Note that \pagecontents -% does insertions, but you have to call it yourself. +% \onepageout takes a vbox as an argument. +% \shipout a vbox for a single page, adding an optional header, footer, +% cropmarks, and footnote. This also causes index entries for this page +% to be written to the auxiliary files. +% \def\onepageout#1{% \ifcropmarks \hoffset=0pt \else \hoffset=\normaloffset \fi % \ifodd\pageno \advance\hoffset by \bindingoffset \else \advance\hoffset by -\bindingoffset\fi % + % Common context changes for both heading and footing. % Do this outside of the \shipout so @code etc. will be expanded in % the headline as they should be, not taken literally (outputting ''code). + \def\commmonheadfootline{\let\hsize=\txipagewidth \texinfochars} + % + % Retrieve the information for the headings from the marks in the page, + % and call Plain TeX's \makeheadline and \makefootline, which use the + % values in \headline and \footline. + % + % This is used to check if we are on the first page of a chapter. + \ifcase1\topmark\fi + \let\prevchaptername\thischaptername + \ifcase0\firstmark\fi + \let\curchaptername\thischaptername + % \ifodd\pageno \getoddheadingmarks \else \getevenheadingmarks \fi - \setbox\headlinebox = \vbox{\let\hsize=\pagewidth \makeheadline}% \ifodd\pageno \getoddfootingmarks \else \getevenfootingmarks \fi - \setbox\footlinebox = \vbox{\let\hsize=\pagewidth \makefootline}% + % + \ifx\curchaptername\prevchaptername + \let\thischapterheading\thischapter + \else + % \thischapterheading is the same as \thischapter except it is blank + % for the first page of a chapter. This is to prevent the chapter name + % being shown twice. + \def\thischapterheading{}% + \fi + % + \global\setbox\headlinebox = \vbox{\commmonheadfootline \makeheadline}% + \global\setbox\footlinebox = \vbox{\commmonheadfootline \makefootline}% % {% + % Set context for writing to auxiliary files like index files. % Have to do this stuff outside the \shipout because we want it to % take effect in \write's, yet the group defined by the \vbox ends % before the \shipout runs. @@ -336,10 +378,10 @@ \normalturnoffactive % \ in index entries must not stay \, e.g., if % the page break happens to be in the middle of an example. % We don't want .vr (or whatever) entries like this: - % \entry{{\tt \indexbackslash }acronym}{32}{\code {\acronym}} + % \entry{{\indexbackslash }acronym}{32}{\code {\acronym}} % "\acronym" won't work when it's read back in; % it needs to be - % {\code {{\tt \backslashcurfont }acronym} + % {\code {{\backslashcurfont }acronym} \shipout\vbox{% % Do this early so pdf references go to the beginning of the page. \ifpdfmakepagedest \pdfdest name{\the\pageno} xyz\fi @@ -397,7 +439,8 @@ \newinsert\margin \dimen\margin=\maxdimen -\def\pagebody#1{\vbox to\pageheight{\boxmaxdepth=\maxdepth #1}} +% Main part of page, including any footnotes +\def\pagebody#1{\vbox to\txipageheight{\boxmaxdepth=\maxdepth #1}} {\catcode`\@ =11 \gdef\pagecontents#1{\ifvoid\topins\else\unvbox\topins\fi % marginal hacks, juha@viisa.uucp (Juha Takala) @@ -419,9 +462,13 @@ \def\nsbot{\vbox {\hrule height\cornerlong depth\cornerthick width\cornerthick}} + +% Argument parsing + % Parse an argument, then pass it to #1. The argument is the rest of % the input line (except we remove a trailing comment). #1 should be a % macro which expects an ordinary undelimited TeX argument. +% For example, \def\foo{\parsearg\fooxxx}. % \def\parsearg{\parseargusing{}} \def\parseargusing#1#2{% @@ -440,9 +487,11 @@ }% } -% First remove any @comment, then any @c comment. +% First remove any @comment, then any @c comment. Also remove a @texinfoc +% comment (see \scanmacro for details). Pass the result on to \argcheckspaces. \def\argremovecomment#1\comment#2\ArgTerm{\argremovec #1\c\ArgTerm} -\def\argremovec#1\c#2\ArgTerm{\argcheckspaces#1\^^M\ArgTerm} +\def\argremovec#1\c#2\ArgTerm{\argremovetexinfoc #1\texinfoc\ArgTerm} +\def\argremovetexinfoc#1\texinfoc#2\ArgTerm{\argcheckspaces#1\^^M\ArgTerm} % Each occurrence of `\^^M' or `\^^M' is replaced by a single space. % @@ -477,14 +526,13 @@ % \def\finishparsearg#1 \ArgTerm{\expandafter\argtorun\expandafter{#1}} + +% \parseargdef - define a command taking an argument on the line +% % \parseargdef\foo{...} % is roughly equivalent to % \def\foo{\parsearg\Xfoo} % \def\Xfoo#1{...} -% -% Actually, I use \csname\string\foo\endcsname, ie. \\foo, as it is my -% favourite TeX trick. --kasal, 16nov03 - \def\parseargdef#1{% \expandafter \doparseargdef \csname\string#1\endcsname #1% } @@ -674,21 +722,26 @@ \endgraf % Not \par, as it may have been set to \lisppar. \global\dimen1 = \prevdepth \egroup % End the \vtop. + \addgroupbox + \prevdepth = \dimen1 + \checkinserts +} + +\def\addgroupbox{ % \dimen0 is the vertical size of the group's box. \dimen0 = \ht\groupbox \advance\dimen0 by \dp\groupbox % \dimen2 is how much space is left on the page (more or less). - \dimen2 = \pageheight \advance\dimen2 by -\pagetotal + \dimen2 = \txipageheight \advance\dimen2 by -\pagetotal % if the group doesn't fit on the current page, and it's a big big % group, force a page break. \ifdim \dimen0 > \dimen2 - \ifdim \pagetotal < \vfilllimit\pageheight + \ifdim \pagetotal < \vfilllimit\txipageheight \page \fi \fi \box\groupbox - \prevdepth = \dimen1 - \checkinserts } + % % TeX puts in an \escapechar (i.e., `@') at the beginning of the help % message, so this ends up printing `@group can only ...'. @@ -812,36 +865,6 @@ where each line of input produces a line of output.} \temp } -% @| inserts a changebar to the left of the current line. It should -% surround any changed text. This approach does *not* work if the -% change spans more than two lines of output. To handle that, we would -% have adopt a much more difficult approach (putting marks into the main -% vertical list for the beginning and end of each change). This command -% is not documented, not supported, and doesn't work. -% -\def\|{% - % \vadjust can only be used in horizontal mode. - \leavevmode - % - % Append this vertical mode material after the current line in the output. - \vadjust{% - % We want to insert a rule with the height and depth of the current - % leading; that is exactly what \strutbox is supposed to record. - \vskip-\baselineskip - % - % \vadjust-items are inserted at the left edge of the type. So - % the \llap here moves out into the left-hand margin. - \llap{% - % - % For a thicker or thinner bar, change the `1pt'. - \vrule height\baselineskip width1pt - % - % This is the space between the bar and the text. - \hskip 12pt - }% - }% -} - % @include FILE -- \input text of FILE. % \def\include{\parseargusing\filenamecatcodes\includezzz} @@ -930,13 +953,14 @@ where each line of input produces a line of output.} % @comment ...line which is ignored... % @c is the same as @comment % @ignore ... @end ignore is another way to write a comment -% -\def\comment{\begingroup \catcode`\^^M=\other% + + +\def\c{\begingroup \catcode`\^^M=\active% \catcode`\@=\other \catcode`\{=\other \catcode`\}=\other% -\commentxxx} -{\catcode`\^^M=\other \gdef\commentxxx#1^^M{\endgroup}} +\cxxx} +{\catcode`\^^M=\active \gdef\cxxx#1^^M{\endgroup}} % -\let\c=\comment +\let\comment\c % @paragraphindent NCHARS % We'll use ems for NCHARS, close enough. @@ -1007,69 +1031,23 @@ where each line of input produces a line of output.} % paragraph. % \gdef\dosuppressfirstparagraphindent{% - \gdef\indent{% - \restorefirstparagraphindent - \indent - }% - \gdef\noindent{% - \restorefirstparagraphindent - \noindent - }% - \global\everypar = {% - \kern -\parindent - \restorefirstparagraphindent - }% + \gdef\indent {\restorefirstparagraphindent \indent}% + \gdef\noindent{\restorefirstparagraphindent \noindent}% + \global\everypar = {\kern -\parindent \restorefirstparagraphindent}% } - +% \gdef\restorefirstparagraphindent{% - \global \let \indent = \ptexindent - \global \let \noindent = \ptexnoindent - \global \everypar = {}% + \global\let\indent = \ptexindent + \global\let\noindent = \ptexnoindent + \global\everypar = {}% } % @refill is a no-op. \let\refill=\relax -% If working on a large document in chapters, it is convenient to -% be able to disable indexing, cross-referencing, and contents, for test runs. -% This is done with @novalidate (before @setfilename). -% -\newif\iflinks \linkstrue % by default we want the aux files. -\let\novalidate = \linksfalse - -% @setfilename is done at the beginning of every texinfo file. -% So open here the files we need to have open while reading the input. -% This makes it possible to make a .fmt file for texinfo. -\def\setfilename{% - \fixbackslash % Turn off hack to swallow `\input texinfo'. - \iflinks - \tryauxfile - % Open the new aux file. TeX will close it automatically at exit. - \immediate\openout\auxfile=\jobname.aux - \fi % \openindices needs to do some work in any case. - \openindices - \let\setfilename=\comment % Ignore extra @setfilename cmds. - % - % If texinfo.cnf is present on the system, read it. - % Useful for site-wide @afourpaper, etc. - \openin 1 texinfo.cnf - \ifeof 1 \else \input texinfo.cnf \fi - \closein 1 - % - \comment % Ignore the actual filename. -} - -% Called from \setfilename. -% -\def\openindices{% - \newindex{cp}% - \newcodeindex{fn}% - \newcodeindex{vr}% - \newcodeindex{tp}% - \newcodeindex{ky}% - \newcodeindex{pg}% -} +% @setfilename INFO-FILENAME - ignored +\let\setfilename=\comment % @bye. \outer\def\bye{\pagealignmacro\tracingstats=1\ptexend} @@ -1087,10 +1065,91 @@ where each line of input produces a line of output.} \newtoks\toksC \newtoks\toksD \newbox\boxA +\newbox\boxB \newcount\countA \newif\ifpdf \newif\ifpdfmakepagedest +% +% For LuaTeX +% + +\newif\iftxiuseunicodedestname +\txiuseunicodedestnamefalse % For pdfTeX etc. + +\ifx\luatexversion\thisisundefined +\else + % Use Unicode destination names + \txiuseunicodedestnametrue + % Escape PDF strings with converting UTF-16 from UTF-8 + \begingroup + \catcode`\%=12 + \directlua{ + function UTF16oct(str) + tex.sprint(string.char(0x5c) .. '376' .. string.char(0x5c) .. '377') + for c in string.utfvalues(str) do + if c < 0x10000 then + tex.sprint( + string.format(string.char(0x5c) .. string.char(0x25) .. '03o' .. + string.char(0x5c) .. string.char(0x25) .. '03o', + (c / 256), (c % 256))) + else + c = c - 0x10000 + local c_hi = c / 1024 + 0xd800 + local c_lo = c % 1024 + 0xdc00 + tex.sprint( + string.format(string.char(0x5c) .. string.char(0x25) .. '03o' .. + string.char(0x5c) .. string.char(0x25) .. '03o' .. + string.char(0x5c) .. string.char(0x25) .. '03o' .. + string.char(0x5c) .. string.char(0x25) .. '03o', + (c_hi / 256), (c_hi % 256), + (c_lo / 256), (c_lo % 256))) + end + end + end + } + \endgroup + \def\pdfescapestrutfsixteen#1{\directlua{UTF16oct('\luaescapestring{#1}')}} + % Escape PDF strings without converting + \begingroup + \directlua{ + function PDFescstr(str) + for c in string.bytes(str) do + if c <= 0x20 or c >= 0x80 or c == 0x28 or c == 0x29 or c == 0x5c then + tex.sprint( + string.format(string.char(0x5c) .. string.char(0x25) .. '03o', + c)) + else + tex.sprint(string.char(c)) + end + end + end + } + \endgroup + \def\pdfescapestring#1{\directlua{PDFescstr('\luaescapestring{#1}')}} + \ifnum\luatexversion>84 + % For LuaTeX >= 0.85 + \def\pdfdest{\pdfextension dest} + \let\pdfoutput\outputmode + \def\pdfliteral{\pdfextension literal} + \def\pdfcatalog{\pdfextension catalog} + \def\pdftexversion{\numexpr\pdffeedback version\relax} + \let\pdfximage\saveimageresource + \let\pdfrefximage\useimageresource + \let\pdflastximage\lastsavedimageresourceindex + \def\pdfendlink{\pdfextension endlink\relax} + \def\pdfoutline{\pdfextension outline} + \def\pdfstartlink{\pdfextension startlink} + \def\pdffontattr{\pdfextension fontattr} + \def\pdfobj{\pdfextension obj} + \def\pdflastobj{\numexpr\pdffeedback lastobj\relax} + \let\pdfpagewidth\pagewidth + \let\pdfpageheight\pageheight + \edef\pdfhorigin{\pdfvariable horigin} + \edef\pdfvorigin{\pdfvariable vorigin} + \fi +\fi + % when pdftex is run in dvi mode, \pdfoutput is defined (so \pdfoutput=1 % can be set). So we test for \relax and 0 as well as being undefined. \ifx\pdfoutput\thisisundefined @@ -1121,12 +1180,21 @@ where each line of input produces a line of output.} \ifx\pdfescapestring\thisisundefined % No primitive available; should we give a warning or log? % Many times it won't matter. + \xdef#1{#1}% \else % The expandable \pdfescapestring primitive escapes parentheses, % backslashes, and other special chars. \xdef#1{\pdfescapestring{#1}}% \fi } +\def\txiescapepdfutfsixteen#1{% + \ifx\pdfescapestrutfsixteen\thisisundefined + % No UTF-16 converting macro available. + \txiescapepdf{#1}% + \else + \xdef#1{\pdfescapestrutfsixteen{#1}}% + \fi +} \newhelp\nopdfimagehelp{Texinfo supports .png, .jpg, .jpeg, and .pdf images with PDF output, and none of those formats could be found. (.eps cannot @@ -1135,15 +1203,17 @@ output) for that.)} \ifpdf % - % Color manipulation macros based on pdfcolor.tex, + % Color manipulation macros using ideas from 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. + % of actual black. The dark red here is dark enough to print on paper as + % nearly black, but still distinguishable for online viewing. We use + % black by default, though. \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). + % rg sets the color for filling (usual text, etc.); + % RG sets the color for stroking (thin rules, e.g., normal _'s). \def\pdfsetcolor#1{\pdfliteral{#1 rg #1 RG}} % % Set color, and create a mark which defines \thiscolor accordingly, @@ -1234,24 +1304,83 @@ output) for that.)} \pdfrefximage \pdflastximage \fi} % - \def\pdfmkdest#1{{% + \def\setpdfdestname#1{{% % We have to set dummies so commands such as @code, and characters % such as \, aren't expanded when present in a section title. \indexnofonts - \turnoffactive \makevalueexpandable + \turnoffactive + \iftxiuseunicodedestname + \ifx \declaredencoding \latone + % Pass through Latin-1 characters. + % LuaTeX with byte wise I/O converts Latin-1 characters to Unicode. + \else + \ifx \declaredencoding \utfeight + % Pass through Unicode characters. + \else + % Use ASCII approximations in destination names. + \passthroughcharsfalse + \fi + \fi + \else + % Use ASCII approximations in destination names. + \passthroughcharsfalse + \fi \def\pdfdestname{#1}% \txiescapepdf\pdfdestname - \safewhatsit{\pdfdest name{\pdfdestname} xyz}% }} % + \def\setpdfoutlinetext#1{{% + \indexnofonts + \makevalueexpandable + \turnoffactive + \ifx \declaredencoding \latone + % The PDF format can use an extended form of Latin-1 in bookmark + % strings. See Appendix D of the PDF Reference, Sixth Edition, for + % the "PDFDocEncoding". + \passthroughcharstrue + % Pass through Latin-1 characters. + % LuaTeX: Convert to Unicode + % pdfTeX: Use Latin-1 as PDFDocEncoding + \def\pdfoutlinetext{#1}% + \else + \ifx \declaredencoding \utfeight + \ifx\luatexversion\thisisundefined + % For pdfTeX with UTF-8. + % TODO: the PDF format can use UTF-16 in bookmark strings, + % but the code for this isn't done yet. + % Use ASCII approximations. + \passthroughcharsfalse + \def\pdfoutlinetext{#1}% + \else + % For LuaTeX with UTF-8. + % Pass through Unicode characters for title texts. + \passthroughcharstrue + \def\pdfoutlinetext{#1}% + \fi + \else + % For non-Latin-1 or non-UTF-8 encodings. + % Use ASCII approximations. + \passthroughcharsfalse + \def\pdfoutlinetext{#1}% + \fi + \fi + % LuaTeX: Convert to UTF-16 + % pdfTeX: Use Latin-1 as PDFDocEncoding + \txiescapepdfutfsixteen\pdfoutlinetext + }} + % + \def\pdfmkdest#1{% + \setpdfdestname{#1}% + \safewhatsit{\pdfdest name{\pdfdestname} xyz}% + } + % % used to mark target names; must be expandable. \def\pdfmkpgn#1{#1} % - % by default, use a color that is dark enough to print on paper as - % nearly black, but still distinguishable for online viewing. - \def\urlcolor{\rgbDarkRed} - \def\linkcolor{\rgbDarkRed} + % by default, use black for everything. + \def\urlcolor{\rgbBlack} + \def\linkcolor{\rgbBlack} \def\endlink{\setcolor{\maincolor}\pdfendlink} % % Adding outlines to PDF; macros for calculating structure of outlines @@ -1273,18 +1402,13 @@ output) for that.)} % page number. We could generate a destination for the section % text in the case where a section has no node, but it doesn't % seem worth the trouble, since most documents are normally structured. - \edef\pdfoutlinedest{#3}% - \ifx\pdfoutlinedest\empty - \def\pdfoutlinedest{#4}% - \else - \txiescapepdf\pdfoutlinedest + \setpdfoutlinetext{#1} + \setpdfdestname{#3} + \ifx\pdfdestname\empty + \def\pdfdestname{#4}% \fi % - % Also escape PDF chars in the display string. - \edef\pdfoutlinetext{#1}% - \txiescapepdf\pdfoutlinetext - % - \pdfoutline goto name{\pdfmkpgn{\pdfoutlinedest}}#2{\pdfoutlinetext}% + \pdfoutline goto name{\pdfmkpgn{\pdfdestname}}#2{\pdfoutlinetext}% } % \def\pdfmakeoutlines{% @@ -1439,42 +1563,298 @@ output) for that.)} \let\pdfmakeoutlines = \relax \fi % \ifx\pdfoutput +% +% For XeTeX +% +\ifx\XeTeXrevision\thisisundefined +\else + % + % XeTeX version check + % + \ifnum\strcmp{\the\XeTeXversion\XeTeXrevision}{0.99996}>-1 + % TeX Live 2016 contains XeTeX 0.99996 and xdvipdfmx 20160307. + % It can use the `dvipdfmx:config' special (from TeX Live SVN r40941). + % For avoiding PDF destination name replacement, we use this special + % instead of xdvipdfmx's command line option `-C 0x0010'. + \special{dvipdfmx:config C 0x0010} + % XeTeX 0.99995+ comes with xdvipdfmx 20160307+. + % It can handle Unicode destination names for PDF. + \txiuseunicodedestnametrue + \else + % XeTeX < 0.99996 (TeX Live < 2016) cannot use the + % `dvipdfmx:config' special. + % So for avoiding PDF destination name replacement, + % xdvipdfmx's command line option `-C 0x0010' is necessary. + % + % XeTeX < 0.99995 can not handle Unicode destination names for PDF + % because xdvipdfmx 20150315 has a UTF-16 conversion issue. + % It is fixed by xdvipdfmx 20160106 (TeX Live SVN r39753). + \txiuseunicodedestnamefalse + \fi + % + % Color support + % + \def\rgbDarkRed{0.50 0.09 0.12} + \def\rgbBlack{0 0 0} + % + \def\pdfsetcolor#1{\special{pdf:scolor [#1]}} + % + % Set color, and create a mark which defines \thiscolor accordingly, + % so that \makeheadline knows which color to restore. + \def\setcolor#1{% + \xdef\lastcolordefs{\gdef\noexpand\thiscolor{#1}}% + \domark + \pdfsetcolor{#1}% + } + % + \def\maincolor{\rgbBlack} + \pdfsetcolor{\maincolor} + \edef\thiscolor{\maincolor} + \def\lastcolordefs{} + % + \def\makefootline{% + \baselineskip24pt + \line{\pdfsetcolor{\maincolor}\the\footline}% + } + % + \def\makeheadline{% + \vbox to 0pt{% + \vskip-22.5pt + \line{% + \vbox to8.5pt{}% + % Extract \thiscolor definition from the marks. + \getcolormarks + % Typeset the headline with \maincolor, then restore the color. + \pdfsetcolor{\maincolor}\the\headline\pdfsetcolor{\thiscolor}% + }% + \vss + }% + \nointerlineskip + } + % + % PDF outline support + % + % Emulate pdfTeX primitive + \def\pdfdest name#1 xyz{% + \special{pdf:dest (#1) [@thispage /XYZ @xpos @ypos null]}% + } + % + \def\setpdfdestname#1{{% + % We have to set dummies so commands such as @code, and characters + % such as \, aren't expanded when present in a section title. + \indexnofonts + \makevalueexpandable + \turnoffactive + \iftxiuseunicodedestname + % Pass through Unicode characters. + \else + % Use ASCII approximations in destination names. + \passthroughcharsfalse + \fi + \def\pdfdestname{#1}% + \txiescapepdf\pdfdestname + }} + % + \def\setpdfoutlinetext#1{{% + \turnoffactive + % Always use Unicode characters in title texts. + \def\pdfoutlinetext{#1}% + % For XeTeX, xdvipdfmx converts to UTF-16. + % So we do not convert. + \txiescapepdf\pdfoutlinetext + }} + % + \def\pdfmkdest#1{% + \setpdfdestname{#1}% + \safewhatsit{\pdfdest name{\pdfdestname} xyz}% + } + % + % by default, use black for everything. + \def\urlcolor{\rgbBlack} + \def\linkcolor{\rgbBlack} + \def\endlink{\setcolor{\maincolor}\pdfendlink} + % + \def\dopdfoutline#1#2#3#4{% + \setpdfoutlinetext{#1} + \setpdfdestname{#3} + \ifx\pdfdestname\empty + \def\pdfdestname{#4}% + \fi + % + \special{pdf:out [-] #2 << /Title (\pdfoutlinetext) /A + << /S /GoTo /D (\pdfdestname) >> >> }% + } + % + \def\pdfmakeoutlines{% + \begingroup + % + % For XeTeX, counts of subentries are not necessary. + % Therefore, we read toc only once. + % + % We use node names as destinations. + \def\partentry##1##2##3##4{}% ignore parts in the outlines + \def\numchapentry##1##2##3##4{% + \dopdfoutline{##1}{1}{##3}{##4}}% + \def\numsecentry##1##2##3##4{% + \dopdfoutline{##1}{2}{##3}{##4}}% + \def\numsubsecentry##1##2##3##4{% + \dopdfoutline{##1}{3}{##3}{##4}}% + \def\numsubsubsecentry##1##2##3##4{% + \dopdfoutline{##1}{4}{##3}{##4}}% + % + \let\appentry\numchapentry% + \let\appsecentry\numsecentry% + \let\appsubsecentry\numsubsecentry% + \let\appsubsubsecentry\numsubsubsecentry% + \let\unnchapentry\numchapentry% + \let\unnsecentry\numsecentry% + \let\unnsubsecentry\numsubsecentry% + \let\unnsubsubsecentry\numsubsubsecentry% + % + % For XeTeX, xdvipdfmx converts strings to UTF-16. + % Therefore, the encoding and the language may not be considered. + % + \indexnofonts + \setupdatafile + % We can have normal brace characters in the PDF outlines, unlike + % Texinfo index files. So set that up. + \def\{{\lbracecharliteral}% + \def\}{\rbracecharliteral}% + \catcode`\\=\active \otherbackslash + \input \tocreadfilename + \endgroup + } + {\catcode`[=1 \catcode`]=2 + \catcode`{=\other \catcode`}=\other + \gdef\lbracecharliteral[{]% + \gdef\rbracecharliteral[}]% + ] + \special{pdf:docview << /PageMode /UseOutlines >> } + % ``\special{pdf:tounicode ...}'' is not necessary + % because xdvipdfmx converts strings from UTF-8 to UTF-16 without it. + % However, due to a UTF-16 conversion issue of xdvipdfmx 20150315, + % ``\special{pdf:dest ...}'' cannot handle non-ASCII strings. + % It is fixed by xdvipdfmx 20160106 (TeX Live SVN r39753). +% + \def\skipspaces#1{\def\PP{#1}\def\D{|}% + \ifx\PP\D\let\nextsp\relax + \else\let\nextsp\skipspaces + \addtokens{\filename}{\PP}% + \advance\filenamelength by 1 + \fi + \nextsp} + \def\getfilename#1{% + \filenamelength=0 + % If we don't expand the argument now, \skipspaces will get + % snagged on things like "@value{foo}". + \edef\temp{#1}% + \expandafter\skipspaces\temp|\relax + } + % make a live url in pdf output. + \def\pdfurl#1{% + \begingroup + % it seems we really need yet another set of dummies; have not + % tried to figure out what each command should do in the context + % of @url. for now, just make @/ a no-op, that's the only one + % people have actually reported a problem with. + % + \normalturnoffactive + \def\@{@}% + \let\/=\empty + \makevalueexpandable + % do we want to go so far as to use \indexnofonts instead of just + % special-casing \var here? + \def\var##1{##1}% + % + \leavevmode\setcolor{\urlcolor}% + \special{pdf:bann << /Border [0 0 0] + /Subtype /Link /A << /S /URI /URI (#1) >> >>}% + \endgroup} + \def\endlink{\setcolor{\maincolor}\special{pdf:eann}} + \def\pdfgettoks#1.{\setbox\boxA=\hbox{\toksA={#1.}\toksB={}\maketoks}} + \def\addtokens#1#2{\edef\addtoks{\noexpand#1={\the#1#2}}\addtoks} + \def\adn#1{\addtokens{\toksC}{#1}\global\countA=1\let\next=\maketoks} + \def\poptoks#1#2|ENDTOKS|{\let\first=#1\toksD={#1}\toksA={#2}} + \def\maketoks{% + \expandafter\poptoks\the\toksA|ENDTOKS|\relax + \ifx\first0\adn0 + \else\ifx\first1\adn1 \else\ifx\first2\adn2 \else\ifx\first3\adn3 + \else\ifx\first4\adn4 \else\ifx\first5\adn5 \else\ifx\first6\adn6 + \else\ifx\first7\adn7 \else\ifx\first8\adn8 \else\ifx\first9\adn9 + \else + \ifnum0=\countA\else\makelink\fi + \ifx\first.\let\next=\done\else + \let\next=\maketoks + \addtokens{\toksB}{\the\toksD} + \ifx\first,\addtokens{\toksB}{\space}\fi + \fi + \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi + \next} + \def\makelink{\addtokens{\toksB}% + {\noexpand\pdflink{\the\toksC}}\toksC={}\global\countA=0} + \def\pdflink#1{% + \special{pdf:bann << /Border [0 0 0] + /Type /Annot /Subtype /Link /A << /S /GoTo /D (#1) >> >>}% + \setcolor{\linkcolor}#1\endlink} + \def\done{\edef\st{\global\noexpand\toksA={\the\toksB}}\st} +% + % + % @image support + % + % #1 is image name, #2 width (might be empty/whitespace), #3 height (ditto). + \def\doxeteximage#1#2#3{% + \def\xeteximagewidth{#2}\setbox0 = \hbox{\ignorespaces #2}% + \def\xeteximageheight{#3}\setbox2 = \hbox{\ignorespaces #3}% + % + % XeTeX (and the PDF format) supports .pdf, .png, .jpg (among + % others). Let's try in that order, PDF first since if + % someone has a scalable image, presumably better to use that than a + % bitmap. + \let\xeteximgext=\empty + \begingroup + \openin 1 #1.pdf \ifeof 1 + \openin 1 #1.PDF \ifeof 1 + \openin 1 #1.png \ifeof 1 + \openin 1 #1.jpg \ifeof 1 + \openin 1 #1.jpeg \ifeof 1 + \openin 1 #1.JPG \ifeof 1 + \errmessage{Could not find image file #1 for XeTeX}% + \else \gdef\xeteximgext{JPG}% + \fi + \else \gdef\xeteximgext{jpeg}% + \fi + \else \gdef\xeteximgext{jpg}% + \fi + \else \gdef\xeteximgext{png}% + \fi + \else \gdef\xeteximgext{PDF}% + \fi + \else \gdef\xeteximgext{pdf}% + \fi + \closein 1 + \endgroup + % + \def\xetexpdfext{pdf}% + \ifx\xeteximgext\xetexpdfext + \XeTeXpdffile "#1".\xeteximgext "" + \else + \def\xetexpdfext{PDF}% + \ifx\xeteximgext\xetexpdfext + \XeTeXpdffile "#1".\xeteximgext "" + \else + \XeTeXpicfile "#1".\xeteximgext "" + \fi + \fi + \ifdim \wd0 >0pt width \xeteximagewidth \fi + \ifdim \wd2 >0pt height \xeteximageheight \fi \relax + } +\fi + + +% \message{fonts,} -% Change the current font style to #1, remembering it in \curfontstyle. -% For now, we do not accumulate font styles: @b{@i{foo}} prints foo in -% italics, not bold italics. -% -\def\setfontstyle#1{% - \def\curfontstyle{#1}% not as a control sequence, because we are \edef'd. - \csname ten#1\endcsname % change the current font -} - -% Select #1 fonts with the current style. -% -\def\selectfonts#1{\csname #1fonts\endcsname \csname\curfontstyle\endcsname} - -\def\rm{\fam=0 \setfontstyle{rm}} -\def\it{\fam=\itfam \setfontstyle{it}} -\def\sl{\fam=\slfam \setfontstyle{sl}} -\def\bf{\fam=\bffam \setfontstyle{bf}}\def\bfstylename{bf} -\def\tt{\fam=\ttfam \setfontstyle{tt}} - -% Unfortunately, we have to override this for titles and the like, since -% in those cases "rm" is bold. Sigh. -\def\rmisbold{\rm\def\curfontstyle{bf}} - -% Texinfo sort of supports the sans serif font style, which plain TeX does not. -% So we set up a \sf. -\newfam\sffam -\def\sf{\fam=\sffam \setfontstyle{sf}} -\let\li = \sf % Sometimes we call it \li, not \sf. - -% We don't need math for this font style. -\def\ttsl{\setfontstyle{ttsl}} - - % Set the baselineskip to #1, and the lineskip and strut size % correspondingly. There is no deep meaning behind these magic numbers % used as factors; they just match (closely enough) what Knuth defined. @@ -1822,8 +2202,10 @@ end % A few fonts for @defun names and args. \setfont\defbf\bfshape{10}{\magstep1}{OT1} \setfont\deftt\ttshape{10}{\magstep1}{OT1TT} +\setfont\defsl\slshape{10}{\magstep1}{OT1TT} \setfont\defttsl\ttslshape{10}{\magstep1}{OT1TT} -\def\df{\let\tentt=\deftt \let\tenbf = \defbf \let\tenttsl=\defttsl \bf} +\def\df{\let\ttfont=\deftt \let\bffont = \defbf +\let\ttslfont=\defttsl \let\slfont=\defsl \bf} % Fonts for indices, footnotes, small examples (9pt). \def\smallnominalsize{9pt} @@ -1853,6 +2235,20 @@ end \font\smallersy=cmsy8 \def\smallerecsize{0800} +% Fonts for math mode superscripts (7pt). +\def\sevennominalsize{7pt} +\setfont\sevenrm\rmshape{7}{1000}{OT1} +\setfont\seventt\ttshape{10}{700}{OT1TT} +\setfont\sevenbf\bfshape{10}{700}{OT1} +\setfont\sevenit\itshape{7}{1000}{OT1IT} +\setfont\sevensl\slshape{10}{700}{OT1} +\setfont\sevensf\sfshape{10}{700}{OT1} +\setfont\sevensc\scshape{10}{700}{OT1} +\setfont\seventtsl\ttslshape{10}{700}{OT1TT} +\font\seveni=cmmi7 +\font\sevensy=cmsy7 +\def\sevenecsize{0700} + % Fonts for title page (20.4pt): \def\titlenominalsize{20pt} \setfont\titlerm\rmbshape{12}{\magstep3}{OT1} @@ -1884,6 +2280,7 @@ end % Section fonts (14.4pt). \def\secnominalsize{14pt} \setfont\secrm\rmbshape{12}{\magstep1}{OT1} +\setfont\secrmnotbold\rmshape{12}{\magstep1}{OT1} \setfont\secit\itbshape{10}{\magstep2}{OT1IT} \setfont\secsl\slbshape{10}{\magstep2}{OT1} \setfont\sectt\ttbshape{12}{\magstep1}{OT1TT} @@ -1909,7 +2306,7 @@ end \font\ssecsy=cmsy10 scaled 1315 \def\ssececsize{1200} -% Reduced fonts for @acro in text (10pt). +% Reduced fonts for @acronym in text (10pt). \def\reducednominalsize{10pt} \setfont\reducedrm\rmshape{10}{1000}{OT1} \setfont\reducedtt\ttshape{10}{1000}{OT1TT} @@ -1953,8 +2350,10 @@ end % A few fonts for @defun names and args. \setfont\defbf\bfshape{10}{\magstephalf}{OT1} \setfont\deftt\ttshape{10}{\magstephalf}{OT1TT} +\setfont\defsl\slshape{10}{\magstephalf}{OT1TT} \setfont\defttsl\ttslshape{10}{\magstephalf}{OT1TT} -\def\df{\let\tentt=\deftt \let\tenbf = \defbf \let\tenttsl=\defttsl \bf} +\def\df{\let\ttfont=\deftt \let\bffont = \defbf +\let\slfont=\defsl \let\ttslfont=\defttsl \bf} % Fonts for indices, footnotes, small examples (9pt). \def\smallnominalsize{9pt} @@ -1984,6 +2383,20 @@ end \font\smallersy=cmsy8 \def\smallerecsize{0800} +% Fonts for math mode superscripts (7pt). +\def\sevennominalsize{7pt} +\setfont\sevenrm\rmshape{7}{1000}{OT1} +\setfont\seventt\ttshape{10}{700}{OT1TT} +\setfont\sevenbf\bfshape{10}{700}{OT1} +\setfont\sevenit\itshape{7}{1000}{OT1IT} +\setfont\sevensl\slshape{10}{700}{OT1} +\setfont\sevensf\sfshape{10}{700}{OT1} +\setfont\sevensc\scshape{10}{700}{OT1} +\setfont\seventtsl\ttslshape{10}{700}{OT1TT} +\font\seveni=cmmi7 +\font\sevensy=cmsy7 +\def\sevenecsize{0700} + % Fonts for title page (20.4pt): \def\titlenominalsize{20pt} \setfont\titlerm\rmbshape{12}{\magstep3}{OT1} @@ -2040,7 +2453,7 @@ end \font\ssecsy=cmsy10 \def\ssececsize{1000} -% Reduced fonts for @acro in text (9pt). +% Reduced fonts for @acronym in text (9pt). \def\reducednominalsize{9pt} \setfont\reducedrm\rmshape{9}{1000}{OT1} \setfont\reducedtt\ttshape{9}{1000}{OT1TT} @@ -2060,6 +2473,12 @@ end \rm } % end of 10pt text font size definitions, \definetextfontsizex +% Fonts for short table of contents. +\setfont\shortcontrm\rmshape{12}{1000}{OT1} +\setfont\shortcontbf\bfshape{10}{\magstep1}{OT1} % no cmb12 +\setfont\shortcontsl\slshape{12}{1000}{OT1} +\setfont\shortconttt\ttshape{12}{1000}{OT1TT} + % We provide the user-level command % @fonttextsize 10 @@ -2086,102 +2505,121 @@ end \endgroup } - -% In order for the font changes to affect most math symbols and letters, -% we have to define the \textfont of the standard families. Since -% texinfo doesn't allow for producing subscripts and superscripts except -% in the main text, we don't bother to reset \scriptfont and -% \scriptscriptfont (which would also require loading a lot more fonts). % -\def\resetmathfonts{% - \textfont0=\tenrm \textfont1=\teni \textfont2=\tensy - \textfont\itfam=\tenit \textfont\slfam=\tensl \textfont\bffam=\tenbf - \textfont\ttfam=\tentt \textfont\sffam=\tensf +% Change the current font style to #1, remembering it in \curfontstyle. +% For now, we do not accumulate font styles: @b{@i{foo}} prints foo in +% italics, not bold italics. +% +\def\setfontstyle#1{% + \def\curfontstyle{#1}% not as a control sequence, because we are \edef'd. + \csname #1font\endcsname % change the current font } -% The font-changing commands redefine the meanings of \tenSTYLE, instead -% of just \STYLE. We do this because \STYLE needs to also set the -% current \fam for math mode. Our \STYLE (e.g., \rm) commands hardwire -% \tenSTYLE to set the current font. +\def\rm{\fam=0 \setfontstyle{rm}} +\def\it{\fam=\itfam \setfontstyle{it}} +\def\sl{\fam=\slfam \setfontstyle{sl}} +\def\bf{\fam=\bffam \setfontstyle{bf}}\def\bfstylename{bf} +\def\tt{\fam=\ttfam \setfontstyle{tt}} + +% Texinfo sort of supports the sans serif font style, which plain TeX does not. +% So we set up a \sf. +\newfam\sffam +\def\sf{\fam=\sffam \setfontstyle{sf}} + +% We don't need math for this font style. +\def\ttsl{\setfontstyle{ttsl}} + + +% In order for the font changes to affect most math symbols and letters, +% we have to define the \textfont of the standard families. +% We don't bother to reset \scriptscriptfont; awaiting user need. +% +\def\resetmathfonts{% + \textfont0=\rmfont \textfont1=\ifont \textfont2=\syfont + \textfont\itfam=\itfont \textfont\slfam=\slfont \textfont\bffam=\bffont + \textfont\ttfam=\ttfont \textfont\sffam=\sffont + % + % Fonts for superscript. Note that the 7pt fonts are used regardless + % of the current font size. + \scriptfont0=\sevenrm \scriptfont1=\seveni \scriptfont2=\sevensy + \scriptfont\itfam=\sevenit \scriptfont\slfam=\sevensl + \scriptfont\bffam=\sevenbf \scriptfont\ttfam=\seventt + \scriptfont\sffam=\sevensf +} + +% + +% The font-changing commands (all called \...fonts) redefine the meanings +% of \STYLEfont, instead of just \STYLE. We do this because \STYLE needs +% to also set the current \fam for math mode. Our \STYLE (e.g., \rm) +% commands hardwire \STYLEfont to set the current font. +% +% The fonts used for \ifont are for "math italics" (\itfont is for italics +% in regular text). \syfont is also used in math mode only. % % Each font-changing command also sets the names \lsize (one size lower) -% and \lllsize (three sizes lower). These relative commands are used in -% the LaTeX logo and acronyms. +% and \lllsize (three sizes lower). These relative commands are used +% in, e.g., the LaTeX logo and acronyms. % % This all needs generalizing, badly. % -\def\textfonts{% - \let\tenrm=\textrm \let\tenit=\textit \let\tensl=\textsl - \let\tenbf=\textbf \let\tentt=\texttt \let\smallcaps=\textsc - \let\tensf=\textsf \let\teni=\texti \let\tensy=\textsy - \let\tenttsl=\textttsl - \def\curfontsize{text}% - \def\lsize{reduced}\def\lllsize{smaller}% - \resetmathfonts \setleading{\textleading}} -\def\titlefonts{% - \let\tenrm=\titlerm \let\tenit=\titleit \let\tensl=\titlesl - \let\tenbf=\titlebf \let\tentt=\titlett \let\smallcaps=\titlesc - \let\tensf=\titlesf \let\teni=\titlei \let\tensy=\titlesy - \let\tenttsl=\titlettsl - \def\curfontsize{title}% - \def\lsize{chap}\def\lllsize{subsec}% - \resetmathfonts \setleading{27pt}} -\def\titlefont#1{{\titlefonts\rmisbold #1}} -\def\chapfonts{% - \let\tenrm=\chaprm \let\tenit=\chapit \let\tensl=\chapsl - \let\tenbf=\chapbf \let\tentt=\chaptt \let\smallcaps=\chapsc - \let\tensf=\chapsf \let\teni=\chapi \let\tensy=\chapsy - \let\tenttsl=\chapttsl - \def\curfontsize{chap}% - \def\lsize{sec}\def\lllsize{text}% - \resetmathfonts \setleading{19pt}} -\def\secfonts{% - \let\tenrm=\secrm \let\tenit=\secit \let\tensl=\secsl - \let\tenbf=\secbf \let\tentt=\sectt \let\smallcaps=\secsc - \let\tensf=\secsf \let\teni=\seci \let\tensy=\secsy - \let\tenttsl=\secttsl - \def\curfontsize{sec}% - \def\lsize{subsec}\def\lllsize{reduced}% - \resetmathfonts \setleading{16pt}} -\def\subsecfonts{% - \let\tenrm=\ssecrm \let\tenit=\ssecit \let\tensl=\ssecsl - \let\tenbf=\ssecbf \let\tentt=\ssectt \let\smallcaps=\ssecsc - \let\tensf=\ssecsf \let\teni=\sseci \let\tensy=\ssecsy - \let\tenttsl=\ssecttsl - \def\curfontsize{ssec}% - \def\lsize{text}\def\lllsize{small}% - \resetmathfonts \setleading{15pt}} -\let\subsubsecfonts = \subsecfonts -\def\reducedfonts{% - \let\tenrm=\reducedrm \let\tenit=\reducedit \let\tensl=\reducedsl - \let\tenbf=\reducedbf \let\tentt=\reducedtt \let\reducedcaps=\reducedsc - \let\tensf=\reducedsf \let\teni=\reducedi \let\tensy=\reducedsy - \let\tenttsl=\reducedttsl - \def\curfontsize{reduced}% - \def\lsize{small}\def\lllsize{smaller}% - \resetmathfonts \setleading{10.5pt}} -\def\smallfonts{% - \let\tenrm=\smallrm \let\tenit=\smallit \let\tensl=\smallsl - \let\tenbf=\smallbf \let\tentt=\smalltt \let\smallcaps=\smallsc - \let\tensf=\smallsf \let\teni=\smalli \let\tensy=\smallsy - \let\tenttsl=\smallttsl - \def\curfontsize{small}% - \def\lsize{smaller}\def\lllsize{smaller}% - \resetmathfonts \setleading{10.5pt}} -\def\smallerfonts{% - \let\tenrm=\smallerrm \let\tenit=\smallerit \let\tensl=\smallersl - \let\tenbf=\smallerbf \let\tentt=\smallertt \let\smallcaps=\smallersc - \let\tensf=\smallersf \let\teni=\smalleri \let\tensy=\smallersy - \let\tenttsl=\smallerttsl - \def\curfontsize{smaller}% - \def\lsize{smaller}\def\lllsize{smaller}% - \resetmathfonts \setleading{9.5pt}} -% Fonts for short table of contents. -\setfont\shortcontrm\rmshape{12}{1000}{OT1} -\setfont\shortcontbf\bfshape{10}{\magstep1}{OT1} % no cmb12 -\setfont\shortcontsl\slshape{12}{1000}{OT1} -\setfont\shortconttt\ttshape{12}{1000}{OT1TT} +\def\assignfonts#1{% + \expandafter\let\expandafter\rmfont\csname #1rm\endcsname + \expandafter\let\expandafter\itfont\csname #1it\endcsname + \expandafter\let\expandafter\slfont\csname #1sl\endcsname + \expandafter\let\expandafter\bffont\csname #1bf\endcsname + \expandafter\let\expandafter\ttfont\csname #1tt\endcsname + \expandafter\let\expandafter\smallcaps\csname #1sc\endcsname + \expandafter\let\expandafter\sffont \csname #1sf\endcsname + \expandafter\let\expandafter\ifont \csname #1i\endcsname + \expandafter\let\expandafter\syfont \csname #1sy\endcsname + \expandafter\let\expandafter\ttslfont\csname #1ttsl\endcsname +} + +\newif\ifrmisbold + +% Select smaller font size with the current style. Used to change font size +% in, e.g., the LaTeX logo and acronyms. If we are using bold fonts for +% normal roman text, also use bold fonts for roman text in the smaller size. +\def\switchtolllsize{% + \expandafter\assignfonts\expandafter{\lllsize}% + \ifrmisbold + \let\rmfont\bffont + \fi + \csname\curfontstyle\endcsname +}% + +\def\switchtolsize{% + \expandafter\assignfonts\expandafter{\lsize}% + \ifrmisbold + \let\rmfont\bffont + \fi + \csname\curfontstyle\endcsname +}% + +\def\definefontsetatsize#1#2#3#4#5{% +\expandafter\def\csname #1fonts\endcsname{% + \def\curfontsize{#1}% + \def\lsize{#2}\def\lllsize{#3}% + \csname rmisbold#5\endcsname + \assignfonts{#1}% + \resetmathfonts + \setleading{#4}% +}} + +\definefontsetatsize{text} {reduced}{smaller}{\textleading}{false} +\definefontsetatsize{title} {chap} {subsec} {27pt} {true} +\definefontsetatsize{chap} {sec} {text} {19pt} {true} +\definefontsetatsize{sec} {subsec} {reduced}{17pt} {true} +\definefontsetatsize{ssec} {text} {small} {15pt} {true} +\definefontsetatsize{reduced}{small} {smaller}{10.5pt}{false} +\definefontsetatsize{small} {smaller}{smaller}{10.5pt}{false} +\definefontsetatsize{smaller}{smaller}{smaller}{9.5pt} {false} + +\def\titlefont#1{{\titlefonts\rm #1}} +\let\subsecfonts = \ssecfonts +\let\subsubsecfonts = \ssecfonts % Define these just so they can be easily changed for other fonts. \def\angleleft{$\langle$} @@ -2219,26 +2657,11 @@ end % Markup style infrastructure. \defmarkupstylesetup\INITMACRO will % define and register \INITMACRO to be called on markup style changes. % \INITMACRO can check \currentmarkupstyle for the innermost -% style and the set of \ifmarkupSTYLE switches for all styles -% currently in effect. -\newif\ifmarkupvar -\newif\ifmarkupsamp -\newif\ifmarkupkey -%\newif\ifmarkupfile % @file == @samp. -%\newif\ifmarkupoption % @option == @samp. -\newif\ifmarkupcode -\newif\ifmarkupkbd -%\newif\ifmarkupenv % @env == @code. -%\newif\ifmarkupcommand % @command == @code. -\newif\ifmarkuptex % @tex (and part of @math, for now). -\newif\ifmarkupexample -\newif\ifmarkupverb -\newif\ifmarkupverbatim +% style. \let\currentmarkupstyle\empty \def\setupmarkupstyle#1{% - \csname markup#1true\endcsname \def\currentmarkupstyle{#1}% \markupstylesetup } @@ -2300,11 +2723,15 @@ end % lilypond developers report. xpdf does work with the regular 0x27. % \def\codequoteright{% - \expandafter\ifx\csname SETtxicodequoteundirected\endcsname\relax - \expandafter\ifx\csname SETcodequoteundirected\endcsname\relax - '% + \ifmonospace + \expandafter\ifx\csname SETtxicodequoteundirected\endcsname\relax + \expandafter\ifx\csname SETcodequoteundirected\endcsname\relax + '% + \else \char'15 \fi \else \char'15 \fi - \else \char'15 \fi + \else + '% + \fi } % % and a similar option for the left quote char vs. a grave accent. @@ -2312,13 +2739,17 @@ end % the code environments to do likewise. % \def\codequoteleft{% - \expandafter\ifx\csname SETtxicodequotebacktick\endcsname\relax - \expandafter\ifx\csname SETcodequotebacktick\endcsname\relax - % [Knuth] pp. 380,381,391 - % \relax disables Spanish ligatures ?` and !` of \tt font. - \relax`% + \ifmonospace + \expandafter\ifx\csname SETtxicodequotebacktick\endcsname\relax + \expandafter\ifx\csname SETcodequotebacktick\endcsname\relax + % [Knuth] pp. 380,381,391 + % \relax disables Spanish ligatures ?` and !` of \tt font. + \relax`% + \else \char'22 \fi \else \char'22 \fi - \else \char'22 \fi + \else + \relax`% + \fi } % Commands to set the quote options. @@ -2377,8 +2808,10 @@ end \ifx\next,% \else\ifx\next-% \else\ifx\next.% + \else\ifx\next\.% + \else\ifx\next\comma% \else\ptexslash - \fi\fi\fi + \fi\fi\fi\fi\fi \aftersmartic } @@ -2426,8 +2859,8 @@ end % \catcode`@=11 \def\plainfrenchspacing{% - \sfcode\dotChar =\@m \sfcode\questChar=\@m \sfcode\exclamChar=\@m - \sfcode\colonChar=\@m \sfcode\semiChar =\@m \sfcode\commaChar =\@m + \sfcode`\.=\@m \sfcode`\?=\@m \sfcode`\!=\@m + \sfcode`\:=\@m \sfcode`\;=\@m \sfcode`\,=\@m \def\endofsentencespacefactor{1000}% for @. and friends } \def\plainnonfrenchspacing{% @@ -2475,14 +2908,14 @@ end } % We *must* turn on hyphenation at `-' and `_' in @code. +% (But see \codedashfinish below.) % Otherwise, it is too hard to avoid overfull hboxes % in the Emacs manual, the Library manual, etc. % % Unfortunately, TeX uses one parameter (\hyphenchar) to control % both hyphenation at - and hyphenation within words. % We must therefore turn them both off (\tclose does that) -% and arrange explicitly to hyphenate at a dash. -% -- rms. +% and arrange explicitly to hyphenate at a dash. -- rms. { \catcode`\-=\active \catcode`\_=\active \catcode`\'=\active \catcode`\`=\active @@ -2499,14 +2932,35 @@ end \let-\normaldash \let_\realunder \fi + % Given -foo (with a single dash), we do not want to allow a break + % after the hyphen. + \global\let\codedashprev=\codedash + % \codex } + % + \gdef\codedash{\futurelet\next\codedashfinish} + \gdef\codedashfinish{% + \normaldash % always output the dash character itself. + % + % Now, output a discretionary to allow a line break, unless + % (a) the next character is a -, or + % (b) the preceding character is a -. + % E.g., given --posix, we do not want to allow a break after either -. + % Given --foo-bar, we do want to allow a break between the - and the b. + \ifx\next\codedash \else + \ifx\codedashprev\codedash + \else \discretionary{}{}{}\fi + \fi + % we need the space after the = for the case when \next itself is a + % space token; it would get swallowed otherwise. As in @code{- a}. + \global\let\codedashprev= \next + } } - +\def\normaldash{-} +% \def\codex #1{\tclose{#1}\endgroup} -\def\normaldash{-} -\def\codedash{-\discretionary{}{}{}} \def\codeunder{% % this is all so @math{@code{var_name}+1} can work. In math mode, _ % is "active" (mathcode"8000) and \normalunderscore (or \char95, etc.) @@ -2548,37 +3002,21 @@ end \let\file=\code \let\option=\code -% @uref (abbreviation for `urlref') takes an optional (comma-separated) -% second argument specifying the text to display and an optional third -% arg as text to display instead of (rather than in addition to) the url -% itself. First (mandatory) arg is the url. -% (This \urefnobreak definition isn't used now, leaving it for a while -% for comparison.) -\def\urefnobreak#1{\dourefnobreak #1,,,\finish} -\def\dourefnobreak#1,#2,#3,#4\finish{\begingroup - \unsepspaces - \pdfurl{#1}% - \setbox0 = \hbox{\ignorespaces #3}% - \ifdim\wd0 > 0pt - \unhbox0 % third arg given, show only that - \else - \setbox0 = \hbox{\ignorespaces #2}% - \ifdim\wd0 > 0pt - \ifpdf - \unhbox0 % PDF: 2nd arg given, show only it - \else - \unhbox0\ (\code{#1})% DVI: 2nd arg given, show both it and url - \fi - \else - \code{#1}% only url given, so show it - \fi - \fi - \endlink -\endgroup} +% @uref (abbreviation for `urlref') aka @url takes an optional +% (comma-separated) second argument specifying the text to display and +% an optional third arg as text to display instead of (rather than in +% addition to) the url itself. First (mandatory) arg is the url. -% This \urefbreak definition is the active one. +% TeX-only option to allow changing PDF output to show only the second +% arg (if given), and not the url (which is then just the link target). +\newif\ifurefurlonlylink + +% The main macro is \urefbreak, which allows breaking at expected +% places within the url. (There used to be another version, which +% didn't support automatic breaking.) \def\urefbreak{\begingroup \urefcatcodes \dourefbreak} \let\uref=\urefbreak +% \def\dourefbreak#1{\urefbreakfinish #1,,,\finish} \def\urefbreakfinish#1,#2,#3,#4\finish{% doesn't work in @example \unsepspaces @@ -2587,12 +3025,32 @@ end \ifdim\wd0 > 0pt \unhbox0 % third arg given, show only that \else - \setbox0 = \hbox{\ignorespaces #2}% + \setbox0 = \hbox{\ignorespaces #2}% look for second arg \ifdim\wd0 > 0pt \ifpdf - \unhbox0 % PDF: 2nd arg given, show only it + % For pdfTeX and LuaTeX + \ifurefurlonlylink + % PDF plus option to not display url, show just arg + \unhbox0 + \else + % PDF, normally display both arg and url for consistency, + % visibility, if the pdf is eventually used to print, etc. + \unhbox0\ (\urefcode{#1})% + \fi \else - \unhbox0\ (\urefcode{#1})% DVI: 2nd arg given, show both it and url + \ifx\XeTeXrevision\thisisundefined + \unhbox0\ (\urefcode{#1})% DVI, always show arg and url + \else + % For XeTeX + \ifurefurlonlylink + % PDF plus option to not display url, show just arg + \unhbox0 + \else + % PDF, normally display both arg and url for consistency, + % visibility, if the pdf is eventually used to print, etc. + \unhbox0\ (\urefcode{#1})% + \fi + \fi \fi \else \urefcode{#1}% only url given, so show it @@ -2603,9 +3061,9 @@ end % Allow line breaks around only a few characters (only). \def\urefcatcodes{% - \catcode\ampChar=\active \catcode\dotChar=\active - \catcode\hashChar=\active \catcode\questChar=\active - \catcode\slashChar=\active + \catcode`\&=\active \catcode`\.=\active + \catcode`\#=\active \catcode`\?=\active + \catcode`\/=\active } { \urefcatcodes @@ -2632,8 +3090,10 @@ end % we put a little stretch before and after the breakable chars, to help % line breaking of long url's. The unequal skips make look better in % cmtt at least, especially for dots. -\def\urefprestretch{\urefprebreak \hskip0pt plus.13em } -\def\urefpoststretch{\urefpostbreak \hskip0pt plus.1em } +\def\urefprestretchamount{.13em} +\def\urefpoststretchamount{.1em} +\def\urefprestretch{\urefprebreak \hskip0pt plus\urefprestretchamount\relax} +\def\urefpoststretch{\urefpostbreak \hskip0pt plus\urefprestretchamount\relax} % \def\urefcodeamp{\urefprestretch \&\urefpoststretch} \def\urefcodedot{\urefprestretch .\urefpoststretch} @@ -2691,7 +3151,18 @@ end \endlink \endgroup} \else - \let\email=\uref + \ifx\XeTeXrevision\thisisundefined + \let\email=\uref + \else + \def\email#1{\doemail#1,,\finish} + \def\doemail#1,#2,#3\finish{\begingroup + \unsepspaces + \pdfurl{mailto:#1}% + \setbox0 = \hbox{\ignorespaces #2}% + \ifdim\wd0>0pt\unhbox0\else\code{#1}\fi + \endlink + \endgroup} + \fi \fi % @kbdinputstyle -- arg is `distinct' (@kbd uses slanted tty font always), @@ -2760,18 +3231,13 @@ end % \def\dmn#1{\thinspace #1} -% @l was never documented to mean ``switch to the Lisp font'', -% and it is not used as such in any manual I can find. We need it for -% Polish suppressed-l. --karl, 22sep96. -%\def\l#1{{\li #1}\null} - % @acronym for "FBI", "NATO", and the like. % We print this one point size smaller, since it's intended for % all-uppercase. % \def\acronym#1{\doacronym #1,,\finish} \def\doacronym#1,#2,#3\finish{% - {\selectfonts\lsize #1}% + {\switchtolsize #1}% \def\temp{#2}% \ifx\temp\empty \else \space ({\unsepspaces \ignorespaces \temp \unskip})% @@ -2817,21 +3283,24 @@ end \def\mathbackslash{\ifnum\fam=\ttfam \mathchar"075C \else\backslash \fi} % \def\math{% - \tex - \mathunderscore - \let\\ = \mathbackslash - \mathactive - % make the texinfo accent commands work in math mode - \let\"=\ddot - \let\'=\acute - \let\==\bar - \let\^=\hat - \let\`=\grave - \let\u=\breve - \let\v=\check - \let\~=\tilde - \let\dotaccent=\dot - $\finishmath + \ifmmode\else % only go into math if not in math mode already + \tex + \mathunderscore + \let\\ = \mathbackslash + \mathactive + % make the texinfo accent commands work in math mode + \let\"=\ddot + \let\'=\acute + \let\==\bar + \let\^=\hat + \let\`=\grave + \let\u=\breve + \let\v=\check + \let\~=\tilde + \let\dotaccent=\dot + % have to provide another name for sup operator + \let\mathopsup=\sup + $\expandafter\finishmath\fi } \def\finishmath#1{#1$\endgroup} % Close the group opened by \tex. @@ -2854,8 +3323,17 @@ end } } -% ctrl is no longer a Texinfo command, but leave this definition for fun. -\def\ctrl #1{{\tt \rawbackslash \hat}#1} +% for @sub and @sup, if in math mode, just do a normal sub/superscript. +% If in text, use math to place as sub/superscript, but switch +% into text mode, with smaller fonts. This is a different font than the +% one used for real math sub/superscripts (8pt vs. 7pt), but let's not +% fix it (significant additions to font machinery) until someone notices. +% +\def\sub{\ifmmode \expandafter\sb \else \expandafter\finishsub\fi} +\def\finishsub#1{$\sb{\hbox{\switchtolllsize #1}}$}% +% +\def\sup{\ifmmode \expandafter\ptexsp \else \expandafter\finishsup\fi} +\def\finishsup#1{$\ptexsp{\hbox{\switchtolllsize #1}}$}% % @inlinefmt{FMTNAME,PROCESSED-TEXT} and @inlineraw{FMTNAME,RAW-TEXT}. % Ignore unless FMTNAME == tex; then it is like @iftex and @tex, @@ -2868,6 +3346,15 @@ end \def\inlinefmtname{#1}% \ifx\inlinefmtname\outfmtnametex \ignorespaces #2\fi } +% +% @inlinefmtifelse{FMTNAME,THEN-TEXT,ELSE-TEXT} expands THEN-TEXT if +% FMTNAME is tex, else ELSE-TEXT. +\long\def\inlinefmtifelse#1{\doinlinefmtifelse #1,,,\finish} +\long\def\doinlinefmtifelse#1,#2,#3,#4,\finish{% + \def\inlinefmtname{#1}% + \ifx\inlinefmtname\outfmtnametex \ignorespaces #2\else \ignorespaces #3\fi +} +% % For raw, must switch into @tex before parsing the argument, to avoid % setting catcodes prematurely. Doing it this way means that, for % example, @inlineraw{html, foo{bar} gets a parse error instead of being @@ -2884,6 +3371,23 @@ end \endgroup % close group opened by \tex. } +% @inlineifset{VAR, TEXT} expands TEXT if VAR is @set. +% +\long\def\inlineifset#1{\doinlineifset #1,\finish} +\long\def\doinlineifset#1,#2,\finish{% + \def\inlinevarname{#1}% + \expandafter\ifx\csname SET\inlinevarname\endcsname\relax + \else\ignorespaces#2\fi +} + +% @inlineifclear{VAR, TEXT} expands TEXT if VAR is not @set. +% +\long\def\inlineifclear#1{\doinlineifclear #1,\finish} +\long\def\doinlineifclear#1,#2,\finish{% + \def\inlinevarname{#1}% + \expandafter\ifx\csname SET\inlinevarname\endcsname\relax \ignorespaces#2\fi +} + \message{glyphs,} % and logos. @@ -2893,23 +3397,10 @@ end \let\atchar=\@ % @{ @} @lbracechar{} @rbracechar{} all generate brace characters. -% Unless we're in typewriter, use \ecfont because the CM text fonts do -% not have braces, and we don't want to switch into math. -\def\mylbrace{{\ifmonospace\else\ecfont\fi \char123}} -\def\myrbrace{{\ifmonospace\else\ecfont\fi \char125}} -\let\{=\mylbrace \let\lbracechar=\{ -\let\}=\myrbrace \let\rbracechar=\} -\begingroup - % Definitions to produce \{ and \} commands for indices, - % and @{ and @} for the aux/toc files. - \catcode`\{ = \other \catcode`\} = \other - \catcode`\[ = 1 \catcode`\] = 2 - \catcode`\! = 0 \catcode`\\ = \other - !gdef!lbracecmd[\{]% - !gdef!rbracecmd[\}]% - !gdef!lbraceatcmd[@{]% - !gdef!rbraceatcmd[@}]% -!endgroup +\def\lbracechar{{\ifmonospace\char123\else\ensuremath\lbrace\fi}} +\def\rbracechar{{\ifmonospace\char125\else\ensuremath\rbrace\fi}} +\let\{=\lbracechar +\let\}=\rbracechar % @comma{} to avoid , parsing problems. \let\comma = , @@ -2927,8 +3418,8 @@ end % Plain TeX defines: @AA @AE @O @OE @L (plus lowercase versions) @ss. \def\questiondown{?`} \def\exclamdown{!`} -\def\ordf{\leavevmode\raise1ex\hbox{\selectfonts\lllsize \underbar{a}}} -\def\ordm{\leavevmode\raise1ex\hbox{\selectfonts\lllsize \underbar{o}}} +\def\ordf{\leavevmode\raise1ex\hbox{\switchtolllsize \underbar{a}}} +\def\ordm{\leavevmode\raise1ex\hbox{\switchtolllsize \underbar{o}}} % Dotless i and dotless j, used for accents. \def\imacro{i} @@ -2957,12 +3448,12 @@ end {\setbox0=\hbox{T}% \vbox to \ht0{\hbox{% \ifx\textnominalsize\xwordpt - % for 10pt running text, \lllsize (8pt) is too small for the A in LaTeX. + % for 10pt running text, lllsize (8pt) is too small for the A in LaTeX. % Revert to plain's \scriptsize, which is 7pt. \count255=\the\fam $\fam\count255 \scriptstyle A$% \else % For 11pt, we can use our lllsize. - \selectfonts\lllsize A% + \switchtolllsize A% \fi }% \vss @@ -2971,11 +3462,16 @@ end \TeX } -% Some math mode symbols. -\def\bullet{$\ptexbullet$} -\def\geq{\ifmmode \ge\else $\ge$\fi} -\def\leq{\ifmmode \le\else $\le$\fi} -\def\minus{\ifmmode -\else $-$\fi} +% Some math mode symbols. Define \ensuremath to switch into math mode +% unless we are already there. Expansion tricks may not be needed here, +% but safer, and can't hurt. +\def\ensuremath{\ifmmode \expandafter\asis \else\expandafter\ensuredmath \fi} +\def\ensuredmath#1{$\relax#1$} +% +\def\bullet{\ensuremath\ptexbullet} +\def\geq{\ensuremath\ge} +\def\leq{\ensuremath\le} +\def\minus{\ensuremath-} % @dots{} outputs an ellipsis using the current font. % We do .5em per period so that it has the same spacing in the cm @@ -3023,7 +3519,7 @@ end % \newbox\errorbox % -{\tentt \global\dimen0 = 3em}% Width of the box. +{\ttfont \global\dimen0 = 3em}% Width of the box. \dimen2 = .55pt % Thickness of rules % The text. (`r' is open on the right, `e' somewhat less so on the left.) \setbox0 = \hbox{\kern-.75pt \reducedsf \putworderror\kern-1.5pt} @@ -3139,8 +3635,15 @@ end \def\Eogonek{{\ecfont \char"86}}\def\macrocharE{E} \def\eogonek{{\ecfont \char"A6}}\def\macrochare{e} % -% Use the ec* fonts (cm-super in outline format) for non-CM glyphs. -\def\ecfont{% +% Use the European Computer Modern fonts (cm-super in outline format) +% for non-CM glyphs. That is ec* for regular text and tc* for the text +% companion symbols (LaTeX TS1 encoding). Both are part of the ec +% package and follow the same conventions. +% +\def\ecfont{\etcfont{e}} +\def\tcfont{\etcfont{t}} +% +\def\etcfont#1{% % We can't distinguish serif/sans and italic/slanted, but this % is used for crude hacks anyway (like adding French and German % quotes to documents typeset with CM, where we lose kerning), so @@ -3149,14 +3652,14 @@ end \edef\nominalsize{\csname\curfontsize nominalsize\endcsname}% \ifmonospace % typewriter: - \font\thisecfont = ectt\ecsize \space at \nominalsize + \font\thisecfont = #1ctt\ecsize \space at \nominalsize \else \ifx\curfontstyle\bfstylename % bold: - \font\thisecfont = ecb\ifusingit{i}{x}\ecsize \space at \nominalsize + \font\thisecfont = #1cb\ifusingit{i}{x}\ecsize \space at \nominalsize \else % regular: - \font\thisecfont = ec\ifusingit{ti}{rm}\ecsize \space at \nominalsize + \font\thisecfont = #1c\ifusingit{ti}{rm}\ecsize \space at \nominalsize \fi \fi \thisecfont @@ -3167,7 +3670,7 @@ end % Adapted from the plain.tex definition of \copyright. % \def\registeredsymbol{% - $^{{\ooalign{\hfil\raise.07ex\hbox{\selectfonts\lllsize R}% + $^{{\ooalign{\hfil\raise.07ex\hbox{\switchtolllsize R}% \hfil\crcr\Orb}}% }$% } @@ -3200,13 +3703,16 @@ end \newif\ifseenauthor \newif\iffinishedtitlepage -% Do an implicit @contents or @shortcontents after @end titlepage if the -% user says @setcontentsaftertitlepage or @setshortcontentsaftertitlepage. -% -\newif\ifsetcontentsaftertitlepage - \let\setcontentsaftertitlepage = \setcontentsaftertitlepagetrue -\newif\ifsetshortcontentsaftertitlepage - \let\setshortcontentsaftertitlepage = \setshortcontentsaftertitlepagetrue +% @setcontentsaftertitlepage used to do an implicit @contents or +% @shortcontents after @end titlepage, but it is now obsolete. +\def\setcontentsaftertitlepage{% + \errmessage{@setcontentsaftertitlepage has been removed as a Texinfo + command; move your @contents command if you want the contents + after the title page.}}% +\def\setshortcontentsaftertitlepage{% + \errmessage{@setshortcontentsaftertitlepage has been removed as a Texinfo + command; move your @shortcontents and @contents commands if you + want the contents after the title page.}}% \parseargdef\shorttitlepage{% \begingroup \hbox{}\vskip 1.5in \chaprm \centerline{#1}% @@ -3248,20 +3754,6 @@ end % Need this before the \...aftertitlepage checks so that if they are % in effect the toc pages will come out with page numbers. \HEADINGSon - % - % If they want short, they certainly want long too. - \ifsetshortcontentsaftertitlepage - \shortcontents - \contents - \global\let\shortcontents = \relax - \global\let\contents = \relax - \fi - % - \ifsetcontentsaftertitlepage - \contents - \global\let\contents = \relax - \global\let\shortcontents = \relax - \fi } \def\finishtitlepage{% @@ -3272,12 +3764,11 @@ end % Settings used for typesetting titles: no hyphenation, no indentation, % don't worry much about spacing, ragged right. This should be used -% inside a \vbox, and fonts need to be set appropriately first. Because -% it is always used for titles, nothing else, we call \rmisbold. \par -% should be specified before the end of the \vbox, since a vbox is a group. +% inside a \vbox, and fonts need to be set appropriately first. \par should +% be specified before the end of the \vbox, since a vbox is a group. % \def\raggedtitlesettings{% - \rmisbold + \rm \hyphenpenalty=10000 \parindent=0pt \tolerance=5000 @@ -3286,7 +3777,7 @@ end % Macros to be used within @titlepage: -\let\subtitlerm=\tenrm +\let\subtitlerm=\rmfont \def\subtitlefont{\subtitlerm \normalbaselineskip = 13pt \normalbaselines} \parseargdef\title{% @@ -3312,7 +3803,7 @@ end \else \checkenv\titlepage \ifseenauthor\else \vskip 0pt plus 1filll \seenauthortrue \fi - {\secfonts\rmisbold \leftline{#1}}% + {\secfonts\rm \leftline{#1}}% \fi } @@ -3326,7 +3817,7 @@ end \newtoks\evenfootline % footline on even pages \newtoks\oddfootline % footline on odd pages -% Now make TeX use those variables +% Now make \makeheadline and \makefootline in Plain TeX use those variables \headline={{\textfonts\rm \ifodd\pageno \the\oddheadline \else \the\evenheadline \fi}} \footline={{\textfonts\rm \ifodd\pageno \the\oddfootline @@ -3365,7 +3856,7 @@ end % % Leave some space for the footline. Hopefully ok to assume % @evenfooting will not be used by itself. - \global\advance\pageheight by -12pt + \global\advance\txipageheight by -12pt \global\advance\vsize by -12pt } @@ -3382,13 +3873,17 @@ end % @everyheadingmarks % @everyfootingmarks +% These define \getoddheadingmarks, \getevenheadingmarks, +% \getoddfootingmarks, and \getevenfootingmarks, each to one of +% \gettopheadingmarks, \getbottomheadingmarks. +% \def\evenheadingmarks{\headingmarks{even}{heading}} \def\oddheadingmarks{\headingmarks{odd}{heading}} \def\evenfootingmarks{\headingmarks{even}{footing}} \def\oddfootingmarks{\headingmarks{odd}{footing}} -\def\everyheadingmarks#1 {\headingmarks{even}{heading}{#1} +\parseargdef\everyheadingmarks{\headingmarks{even}{heading}{#1} \headingmarks{odd}{heading}{#1} } -\def\everyfootingmarks#1 {\headingmarks{even}{footing}{#1} +\parseargdef\everyfootingmarks{\headingmarks{even}{footing}{#1} \headingmarks{odd}{footing}{#1} } % #1 = even/odd, #2 = heading/footing, #3 = top/bottom. \def\headingmarks#1#2#3 {% @@ -3409,7 +3904,7 @@ end % By default, they are off at the start of a document, % and turned `on' after @end titlepage. -\def\headings #1 {\csname HEADINGS#1\endcsname} +\parseargdef\headings{\csname HEADINGS#1\endcsname} \def\headingsoff{% non-global headings elimination \evenheadline={\hfil}\evenfootline={\hfil}% @@ -3429,7 +3924,7 @@ end \global\evenfootline={\hfil} \global\oddfootline={\hfil} \global\evenheadline={\line{\folio\hfil\thistitle}} -\global\oddheadline={\line{\thischapter\hfil\folio}} +\global\oddheadline={\line{\thischapterheading\hfil\folio}} \global\let\contentsalignmacro = \chapoddpage } \let\contentsalignmacro = \chappager @@ -3440,8 +3935,8 @@ end \global\pageno=1 \global\evenfootline={\hfil} \global\oddfootline={\hfil} -\global\evenheadline={\line{\thischapter\hfil\folio}} -\global\oddheadline={\line{\thischapter\hfil\folio}} +\global\evenheadline={\line{\thischapterheading\hfil\folio}} +\global\oddheadline={\line{\thischapterheading\hfil\folio}} \global\let\contentsalignmacro = \chappager } \def\HEADINGSon{\HEADINGSdouble} @@ -3452,7 +3947,7 @@ end \global\evenfootline={\hfil} \global\oddfootline={\hfil} \global\evenheadline={\line{\folio\hfil\thistitle}} -\global\oddheadline={\line{\thischapter\hfil\folio}} +\global\oddheadline={\line{\thischapterheading\hfil\folio}} \global\let\contentsalignmacro = \chapoddpage } @@ -3460,8 +3955,8 @@ end \def\HEADINGSsinglex{% \global\evenfootline={\hfil} \global\oddfootline={\hfil} -\global\evenheadline={\line{\thischapter\hfil\folio}} -\global\oddheadline={\line{\thischapter\hfil\folio}} +\global\evenheadline={\line{\thischapterheading\hfil\folio}} +\global\oddheadline={\line{\thischapterheading\hfil\folio}} \global\let\contentsalignmacro = \chappager } @@ -3639,7 +4134,7 @@ end \parskip=\smallskipamount \ifdim\parskip=0pt \parskip=2pt \fi % - % Try typesetting the item mark that if the document erroneously says + % Try typesetting the item mark so that if the document erroneously says % something like @itemize @samp (intending @table), there's an error % right away at the @itemize. It's not the best error message in the % world, but it's better than leaving it to the @item. This means if @@ -3671,7 +4166,12 @@ end \noindent \hbox to 0pt{\hss \itemcontents \kern\itemmargin}% % - \vadjust{\penalty 1200}}% not good to break after first line of item. + \ifinner\else + \vadjust{\penalty 1200}% not good to break after first line of item. + \fi + % We can be in inner vertical mode in a footnote, although an + % @itemize looks awful there. + }% \flushcr } @@ -3889,19 +4389,23 @@ end } % multitable-only commands. -% -% @headitem starts a heading row, which we typeset in bold. -% Assignments have to be global since we are inside the implicit group -% of an alignment entry. \everycr resets \everytab so we don't have to +% +% @headitem starts a heading row, which we typeset in bold. Assignments +% have to be global since we are inside the implicit group of an +% alignment entry. \everycr below resets \everytab so we don't have to % undo it ourselves. \def\headitemfont{\b}% for people to use in the template row; not changeable \def\headitem{% \checkenv\multitable \crcr + \gdef\headitemcrhook{\nobreak}% attempt to avoid page break after headings \global\everytab={\bf}% can't use \headitemfont since the parsing differs \the\everytab % for the first item }% % +% default for tables with no headings. +\let\headitemcrhook=\relax +% % A \tab used to include \hskip1sp. But then the space in a template % line is not enough. That is bad. So let's go back to just `&' until % we again encounter the problem the 1sp was intended to solve. @@ -3932,15 +4436,15 @@ end % \everycr = {% \noalign{% - \global\everytab={}% + \global\everytab={}% Reset from possible headitem. \global\colcount=0 % Reset the column counter. - % Check for saved footnotes, etc. + % + % Check for saved footnotes, etc.: \checkinserts - % Keeps underfull box messages off when table breaks over pages. - %\filbreak - % Maybe so, but it also creates really weird page breaks when the - % table breaks over pages. Wouldn't \vfil be better? Wait until the - % problem manifests itself, so it can be fixed for real --karl. + % + % Perhaps a \nobreak, then reset: + \headitemcrhook + \global\let\headitemcrhook=\relax }% }% % @@ -4179,7 +4683,7 @@ end \def\value{\begingroup\makevalueexpandable\valuexxx} \def\valuexxx#1{\expandablevalue{#1}\endgroup} { - \catcode`\- = \active \catcode`\_ = \active + \catcode`\-=\active \catcode`\_=\active % \gdef\makevalueexpandable{% \let\value = \expandablevalue @@ -4199,7 +4703,12 @@ end % variable's value contains other Texinfo commands, it's almost certain % it will fail (although perhaps we could fix that with sufficient work % to do a one-level expansion on the result, instead of complete). -% +% +% Unfortunately, this has the consequence that when _ is in the *value* +% of an @set, it does not print properly in the roman fonts (get the cmr +% dot accent at position 126 instead). No fix comes to mind, and it's +% been this way since 2003 or earlier, so just ignore it. +% \def\expandablevalue#1{% \expandafter\ifx\csname SET#1\endcsname\relax {[No value for ``#1'']}% @@ -4209,10 +4718,36 @@ end \fi } +% Like \expandablevalue, but completely expandable (the \message in the +% definition above operates at the execution level of TeX). Used when +% writing to auxiliary files, due to the expansion that \write does. +% If flag is undefined, pass through an unexpanded @value command: maybe it +% will be set by the time it is read back in. +% +% NB flag names containing - or _ may not work here. +\def\dummyvalue#1{% + \expandafter\ifx\csname SET#1\endcsname\relax + \noexpand\value{#1}% + \else + \csname SET#1\endcsname + \fi +} + +% Used for @value's in index entries to form the sort key: expand the @value +% if possible, otherwise sort late. +\def\indexnofontsvalue#1{% + \expandafter\ifx\csname SET#1\endcsname\relax + ZZZZZZZ + \else + \csname SET#1\endcsname + \fi +} + % @ifset VAR ... @end ifset reads the `...' iff VAR has been defined % with @set. -% -% To get special treatment of `@end ifset,' call \makeond and the redefine. +% +% To get the special treatment we need for `@end ifset,' we call +% \makecond and then redefine. % \makecond{ifset} \def\ifset{\parsearg{\doifset{\let\next=\ifsetfail}}} @@ -4283,19 +4818,16 @@ end % except not \outer, so it can be used within macros and \if's. \edef\newwrite{\makecsname{ptexnewwrite}} -% \newindex {foo} defines an index named foo. -% It automatically defines \fooindex such that -% \fooindex ...rest of line... puts an entry in the index foo. -% It also defines \fooindfile to be the number of the output channel for -% the file that accumulates this index. The file's extension is foo. +% \newindex {foo} defines an index named IX. +% It automatically defines \IXindex such that +% \IXindex ...rest of line... puts an entry in the index IX. +% It also defines \IXindfile to be the number of the output channel for +% the file that accumulates this index. The file's extension is IX. % The name of an index should be no more than 2 characters long % for the sake of vms. % \def\newindex#1{% - \iflinks - \expandafter\newwrite \csname#1indfile\endcsname - \openout \csname#1indfile\endcsname \jobname.#1 % Open the file - \fi + \expandafter\chardef\csname#1indfile\endcsname=0 \expandafter\xdef\csname#1index\endcsname{% % Define @#1index \noexpand\doindex{#1}} } @@ -4309,14 +4841,19 @@ end \def\defcodeindex{\parsearg\newcodeindex} % \def\newcodeindex#1{% - \iflinks - \expandafter\newwrite \csname#1indfile\endcsname - \openout \csname#1indfile\endcsname \jobname.#1 - \fi + \expandafter\chardef\csname#1indfile\endcsname=0 \expandafter\xdef\csname#1index\endcsname{% \noexpand\docodeindex{#1}}% } +% The default indices: +\newindex{cp}% concepts, +\newcodeindex{fn}% functions, +\newcodeindex{vr}% variables, +\newcodeindex{tp}% types, +\newcodeindex{ky}% keys +\newcodeindex{pg}% and programs. + % @synindex foo bar makes index foo feed into index bar. % Do this instead of @defindex foo if you don't want it as a separate index. @@ -4330,14 +4867,7 @@ end % #1 is \doindex or \docodeindex, #2 the index getting redefined (foo), % #3 the target index (bar). \def\dosynindex#1#2#3{% - % Only do \closeout if we haven't already done it, else we'll end up - % closing the target index. - \expandafter \ifx\csname donesynindex#2\endcsname \relax - % The \closeout helps reduce unnecessary open files; the limit on the - % Acorn RISC OS is a mere 16 files. - \expandafter\closeout\csname#2indfile\endcsname - \expandafter\let\csname donesynindex#2\endcsname = 1 - \fi + \requireopenindexfile{#3}% % redefine \fooindfile: \expandafter\let\expandafter\temp\expandafter=\csname#3indfile\endcsname \expandafter\let\csname#2indfile\endcsname=\temp @@ -4345,108 +4875,72 @@ end \expandafter\xdef\csname#2index\endcsname{\noexpand#1{#3}}% } -% Define \doindex, the driver for all \fooindex macros. +% Define \doindex, the driver for all index macros. % Argument #1 is generated by the calling \fooindex macro, -% and it is "foo", the name of the index. +% and it is the two-letter name of the index. -% \doindex just uses \parsearg; it calls \doind for the actual work. -% This is because \doind is more useful to call from other macros. - -% There is also \dosubind {index}{topic}{subtopic} -% which makes an entry in a two-level index such as the operation index. - -\def\doindex#1{\edef\indexname{#1}\parsearg\singleindexer} -\def\singleindexer #1{\doind{\indexname}{#1}} +\def\doindex#1{\edef\indexname{#1}\parsearg\doindexxxx} +\def\doindexxxx #1{\doind{\indexname}{#1}} % like the previous two, but they put @code around the argument. -\def\docodeindex#1{\edef\indexname{#1}\parsearg\singlecodeindexer} -\def\singlecodeindexer #1{\doind{\indexname}{\code{#1}}} +\def\docodeindex#1{\edef\indexname{#1}\parsearg\docodeindexxxx} +\def\docodeindexxxx #1{\doind{\indexname}{\code{#1}}} -% Take care of Texinfo commands that can appear in an index entry. -% Since there are some commands we want to expand, and others we don't, -% we have to laboriously prevent expansion for those that we don't. + +% Used when writing an index entry out to an index file to prevent +% expansion of Texinfo commands that can appear in an index entry. % \def\indexdummies{% \escapechar = `\\ % use backslash in output files. - \def\@{@}% change to @@ when we switch to @ as escape char in index files. - \def\ {\realbackslash\space }% + \definedummyletter\@% + \definedummyletter\ % % - % Need these unexpandable (because we define \tt as a dummy) - % definitions when @{ or @} appear in index entry text. Also, more - % complicated, when \tex is in effect and \{ is a \delimiter again. - % We can't use \lbracecmd and \rbracecmd because texindex assumes - % braces and backslashes are used only as delimiters. Perhaps we - % should define @lbrace and @rbrace commands a la @comma. - \def\{{{\tt\char123}}% - \def\}{{\tt\char125}}% - % - % I don't entirely understand this, but when an index entry is - % generated from a macro call, the \endinput which \scanmacro inserts - % causes processing to be prematurely terminated. This is, - % apparently, because \indexsorttmp is fully expanded, and \endinput - % is an expandable command. The redefinition below makes \endinput - % disappear altogether for that purpose -- although logging shows that - % processing continues to some further point. On the other hand, it - % seems \endinput does not hurt in the printed index arg, since that - % is still getting written without apparent harm. - % - % Sample source (mac-idx3.tex, reported by Graham Percival to - % help-texinfo, 22may06): - % @macro funindex {WORD} - % @findex xyz - % @end macro - % ... - % @funindex commtest - % - % The above is not enough to reproduce the bug, but it gives the flavor. - % - % Sample whatsit resulting: - % .@write3{\entry{xyz}{@folio }{@code {xyz@endinput }}} - % - % So: - \let\endinput = \empty + % For texindex which always views { and } as separators. + \def\{{\lbracechar{}}% + \def\}{\rbracechar{}}% % % Do the redefinitions. - \commondummies + \definedummies } -% For the aux and toc files, @ is the escape character. So we want to -% redefine everything using @ as the escape character (instead of -% \realbackslash, still used for index files). When everything uses @, -% this will be simpler. +% Used for the aux and toc files, where @ is the escape character. % \def\atdummies{% - \def\@{@@}% - \def\ {@ }% - \let\{ = \lbraceatcmd - \let\} = \rbraceatcmd + \definedummyletter\@% + \definedummyletter\ % + \definedummyletter\{% + \definedummyletter\}% % % Do the redefinitions. - \commondummies + \definedummies \otherbackslash } -% Called from \indexdummies and \atdummies. +% \definedummyword defines \#1 as \string\#1\space, thus effectively +% preventing its expansion. This is used only for control words, +% not control letters, because the \space would be incorrect for +% control characters, but is needed to separate the control word +% from whatever follows. % -\def\commondummies{% - % - % \definedummyword defines \#1 as \string\#1\space, thus effectively - % preventing its expansion. This is used only for control words, - % not control letters, because the \space would be incorrect for - % control characters, but is needed to separate the control word - % from whatever follows. - % - % For control letters, we have \definedummyletter, which omits the - % space. - % - % These can be used both for control words that take an argument and - % those that do not. If it is followed by {arg} in the input, then - % that will dutifully get written to the index (or wherever). - % - \def\definedummyword ##1{\def##1{\string##1\space}}% - \def\definedummyletter##1{\def##1{\string##1}}% - \let\definedummyaccent\definedummyletter +% These can be used both for control words that take an argument and +% those that do not. If it is followed by {arg} in the input, then +% that will dutifully get written to the index (or wherever). +% +% For control letters, we have \definedummyletter, which omits the +% space. +% +\def\definedummyword #1{\def#1{\string#1\space}}% +\def\definedummyletter#1{\def#1{\string#1}}% +\let\definedummyaccent\definedummyletter + +% Called from \indexdummies and \atdummies, to effectively prevent +% the expansion of commands. +% +\def\definedummies{% % + \let\commondummyword\definedummyword + \let\commondummyletter\definedummyletter + \let\commondummyaccent\definedummyaccent \commondummiesnofonts % \definedummyletter\_% @@ -4487,6 +4981,7 @@ end \definedummyword\TeX % % Assorted special characters. + \definedummyword\atchar \definedummyword\arrow \definedummyword\bullet \definedummyword\comma @@ -4506,6 +5001,7 @@ end \definedummyword\guilsinglright \definedummyword\lbracechar \definedummyword\leq + \definedummyword\mathopsup \definedummyword\minus \definedummyword\ogonek \definedummyword\pounds @@ -4519,88 +5015,136 @@ end \definedummyword\quotesinglbase \definedummyword\rbracechar \definedummyword\result + \definedummyword\sub + \definedummyword\sup \definedummyword\textdegree % % We want to disable all macros so that they are not expanded by \write. \macrolist + \let\value\dummyvalue % \normalturnoffactive - % - % Handle some cases of @value -- where it does not contain any - % (non-fully-expandable) commands. - \makevalueexpandable } -% \commondummiesnofonts: common to \commondummies and \indexnofonts. +% \commondummiesnofonts: common to \definedummies and \indexnofonts. +% Define \commondummyletter, \commondummyaccent and \commondummyword before +% using. Used for accents, font commands, and various control letters. % \def\commondummiesnofonts{% % Control letters and accents. - \definedummyletter\!% - \definedummyaccent\"% - \definedummyaccent\'% - \definedummyletter\*% - \definedummyaccent\,% - \definedummyletter\.% - \definedummyletter\/% - \definedummyletter\:% - \definedummyaccent\=% - \definedummyletter\?% - \definedummyaccent\^% - \definedummyaccent\`% - \definedummyaccent\~% - \definedummyword\u - \definedummyword\v - \definedummyword\H - \definedummyword\dotaccent - \definedummyword\ogonek - \definedummyword\ringaccent - \definedummyword\tieaccent - \definedummyword\ubaraccent - \definedummyword\udotaccent - \definedummyword\dotless + \commondummyletter\!% + \commondummyaccent\"% + \commondummyaccent\'% + \commondummyletter\*% + \commondummyaccent\,% + \commondummyletter\.% + \commondummyletter\/% + \commondummyletter\:% + \commondummyaccent\=% + \commondummyletter\?% + \commondummyaccent\^% + \commondummyaccent\`% + \commondummyaccent\~% + \commondummyword\u + \commondummyword\v + \commondummyword\H + \commondummyword\dotaccent + \commondummyword\ogonek + \commondummyword\ringaccent + \commondummyword\tieaccent + \commondummyword\ubaraccent + \commondummyword\udotaccent + \commondummyword\dotless % % Texinfo font commands. - \definedummyword\b - \definedummyword\i - \definedummyword\r - \definedummyword\sansserif - \definedummyword\sc - \definedummyword\slanted - \definedummyword\t + \commondummyword\b + \commondummyword\i + \commondummyword\r + \commondummyword\sansserif + \commondummyword\sc + \commondummyword\slanted + \commondummyword\t % % Commands that take arguments. - \definedummyword\abbr - \definedummyword\acronym - \definedummyword\anchor - \definedummyword\cite - \definedummyword\code - \definedummyword\command - \definedummyword\dfn - \definedummyword\dmn - \definedummyword\email - \definedummyword\emph - \definedummyword\env - \definedummyword\file - \definedummyword\image - \definedummyword\indicateurl - \definedummyword\inforef - \definedummyword\kbd - \definedummyword\key - \definedummyword\math - \definedummyword\option - \definedummyword\pxref - \definedummyword\ref - \definedummyword\samp - \definedummyword\strong - \definedummyword\tie - \definedummyword\uref - \definedummyword\url - \definedummyword\var - \definedummyword\verb - \definedummyword\w - \definedummyword\xref + \commondummyword\abbr + \commondummyword\acronym + \commondummyword\anchor + \commondummyword\cite + \commondummyword\code + \commondummyword\command + \commondummyword\dfn + \commondummyword\dmn + \commondummyword\email + \commondummyword\emph + \commondummyword\env + \commondummyword\file + \commondummyword\image + \commondummyword\indicateurl + \commondummyword\inforef + \commondummyword\kbd + \commondummyword\key + \commondummyword\math + \commondummyword\option + \commondummyword\pxref + \commondummyword\ref + \commondummyword\samp + \commondummyword\strong + \commondummyword\tie + \commondummyword\U + \commondummyword\uref + \commondummyword\url + \commondummyword\var + \commondummyword\verb + \commondummyword\w + \commondummyword\xref } +% For testing: output @{ and @} in index sort strings as \{ and \}. +\newif\ifusebracesinindexes + +\let\indexlbrace\relax +\let\indexrbrace\relax + +{\catcode`\@=0 +\catcode`\\=13 + @gdef@backslashdisappear{@def\{}} +} + +{ +\catcode`\<=13 +\catcode`\-=13 +\catcode`\`=13 + \gdef\indexnonalnumdisappear{% + \expandafter\ifx\csname SETtxiindexlquoteignore\endcsname\relax\else + % @set txiindexlquoteignore makes us ignore left quotes in the sort term. + % (Introduced for FSFS 2nd ed.) + \let`=\empty + \fi + % + \expandafter\ifx\csname SETtxiindexbackslashignore\endcsname\relax\else + \backslashdisappear + \fi + % + \expandafter\ifx\csname SETtxiindexhyphenignore\endcsname\relax\else + \def-{}% + \fi + \expandafter\ifx\csname SETtxiindexlessthanignore\endcsname\relax\else + \def<{}% + \fi + \expandafter\ifx\csname SETtxiindexatsignignore\endcsname\relax\else + \def\@{}% + \fi + } + + \gdef\indexnonalnumreappear{% + \useindexbackslash + \let-\normaldash + \let<\normalless + \def\@{@}% + } +} + + % \indexnofonts is used when outputting the strings to sort the index % by, and when constructing control sequence names. It eliminates all % control sequences and just writes whatever the best ASCII sort string @@ -4608,12 +5152,11 @@ end % \def\indexnofonts{% % Accent commands should become @asis. - \def\definedummyaccent##1{\let##1\asis}% + \def\commondummyaccent##1{\let##1\asis}% % We can just ignore other control letters. - \def\definedummyletter##1{\let##1\empty}% + \def\commondummyletter##1{\let##1\empty}% % All control words become @asis by default; overrides below. - \let\definedummyword\definedummyaccent - % + \let\commondummyword\commondummyaccent \commondummiesnofonts % % Don't no-op \tt, since it isn't a user-level command @@ -4626,14 +5169,10 @@ end \def\_{\normalunderscore}% \def\-{}% @- shouldn't affect sorting % - % Unfortunately, texindex is not prepared to handle braces in the - % content at all. So for index sorting, we map @{ and @} to strings - % starting with |, since that ASCII character is between ASCII { and }. - \def\{{|a}% - \def\lbracechar{|a}% - % - \def\}{|b}% - \def\rbracechar{|b}% + \uccode`\1=`\{ \uppercase{\def\{{1}}% + \uccode`\1=`\} \uppercase{\def\}{1}}% + \let\lbracechar\{% + \let\rbracechar\}% % % Non-English letters. \def\AA{AA}% @@ -4642,7 +5181,7 @@ end \def\L{L}% \def\OE{OE}% \def\O{O}% - \def\TH{ZZZ}% + \def\TH{TH}% \def\aa{aa}% \def\ae{ae}% \def\dh{dzz}% @@ -4654,45 +5193,45 @@ end \def\o{o}% \def\questiondown{?}% \def\ss{ss}% - \def\th{zzz}% + \def\th{th}% % \def\LaTeX{LaTeX}% \def\TeX{TeX}% % - % Assorted special characters. - % (The following {} will end up in the sort string, but that's ok.) - \def\arrow{->}% - \def\bullet{bullet}% - \def\comma{,}% - \def\copyright{copyright}% - \def\dots{...}% - \def\enddots{...}% - \def\equiv{==}% - \def\error{error}% - \def\euro{euro}% - \def\expansion{==>}% - \def\geq{>=}% - \def\guillemetleft{<<}% - \def\guillemetright{>>}% - \def\guilsinglleft{<}% - \def\guilsinglright{>}% - \def\leq{<=}% - \def\minus{-}% - \def\point{.}% - \def\pounds{pounds}% - \def\print{-|}% - \def\quotedblbase{"}% - \def\quotedblleft{"}% - \def\quotedblright{"}% - \def\quoteleft{`}% - \def\quoteright{'}% - \def\quotesinglbase{,}% - \def\registeredsymbol{R}% - \def\result{=>}% - \def\textdegree{o}% - % - \expandafter\ifx\csname SETtxiindexlquoteignore\endcsname\relax - \else \indexlquoteignore \fi + % Assorted special characters. \defglyph gives the control sequence a + % definition that removes the {} that follows its use. + \defglyph\atchar{@}% + \defglyph\arrow{->}% + \defglyph\bullet{bullet}% + \defglyph\comma{,}% + \defglyph\copyright{copyright}% + \defglyph\dots{...}% + \defglyph\enddots{...}% + \defglyph\equiv{==}% + \defglyph\error{error}% + \defglyph\euro{euro}% + \defglyph\expansion{==>}% + \defglyph\geq{>=}% + \defglyph\guillemetleft{<<}% + \defglyph\guillemetright{>>}% + \defglyph\guilsinglleft{<}% + \defglyph\guilsinglright{>}% + \defglyph\leq{<=}% + \defglyph\lbracechar{\{}% + \defglyph\minus{-}% + \defglyph\point{.}% + \defglyph\pounds{pounds}% + \defglyph\print{-|}% + \defglyph\quotedblbase{"}% + \defglyph\quotedblleft{"}% + \defglyph\quotedblright{"}% + \defglyph\quoteleft{`}% + \defglyph\quoteright{'}% + \defglyph\quotesinglbase{,}% + \defglyph\rbracechar{\}}% + \defglyph\registeredsymbol{R}% + \defglyph\result{=>}% + \defglyph\textdegree{o}% % % We need to get rid of all macros, leaving only the arguments (if present). % Of course this is not nearly correct, but it is the best we can do for now. @@ -4705,21 +5244,24 @@ end % goes to end-of-line is not handled. % \macrolist + \let\value\indexnofontsvalue } +\def\defglyph#1#2{\def#1##1{#2}} % see above + + -% Undocumented (for FSFS 2nd ed.): @set txiindexlquoteignore makes us -% ignore left quotes in the sort term. -{\catcode`\`=\active - \gdef\indexlquoteignore{\let`=\empty}} -\let\indexbackslash=0 %overridden during \printindex. \let\SETmarginindex=\relax % put index entries in margin (undocumented)? % Most index entries go through here, but \dosubind is the general case. % #1 is the index name, #2 is the entry text. \def\doind#1#2{\dosubind{#1}{#2}{}} -% Workhorse for all \fooindexes. +% There is also \dosubind {index}{topic}{subtopic} +% which makes an entry in a two-level index such as the operation index. +% TODO: Two-level index? Operation index? + +% Workhorse for all indexes. % #1 is name of index, #2 is stuff to put there, #3 is subentry -- % empty if called from \doind, as we usually are (the main exception % is with most defuns, which call us directly). @@ -4727,6 +5269,7 @@ end \def\dosubind#1#2#3{% \iflinks {% + \requireopenindexfile{#1}% % Store the main index entry text (including the third arg). \toks0 = {#2}% % If third arg is present, precede it with a space. @@ -4742,7 +5285,50 @@ end \fi } -% Write the entry in \toks0 to the index file: +% Check if an index file has been opened, and if not, open it. +\def\requireopenindexfile#1{% +\ifnum\csname #1indfile\endcsname=0 + \expandafter\newwrite \csname#1indfile\endcsname + \edef\suffix{#1}% + % A .fls suffix would conflict with the file extension for the output + % of -recorder, so use .f1s instead. + \ifx\suffix\indexisfl\def\suffix{f1}\fi + % Open the file + \immediate\openout\csname#1indfile\endcsname \jobname.\suffix + % Using \immediate above here prevents an object entering into the current + % box, which could confound checks such as those in \safewhatsit for + % preceding skips. + \typeout{Writing index file \jobname.\suffix}% +\fi} +\def\indexisfl{fl} + +% Output \ as {\indexbackslash}, because \ is an escape character in +% the index files. +\let\indexbackslash=\relax +{\catcode`\@=0 \catcode`\\=\active + @gdef@useindexbackslash{@def\{{@indexbackslash}}} +} + +% Definition for writing index entry text. +\def\sortas#1{\ignorespaces}% + +% Definition for writing index entry sort key. Should occur at the at +% the beginning of the index entry, like +% @cindex @sortas{september} \september +% The \ignorespaces takes care of following space, but there's no way +% to remove space before it. +{ +\catcode`\-=13 +\gdef\indexwritesortas{% + \begingroup + \indexnonalnumreappear + \indexwritesortasxxx} +\gdef\indexwritesortasxxx#1{% + \xdef\indexsortkey{#1}\endgroup} +} + + +% Write the entry in \toks0 to the index file. % \def\dosubindwrite{% % Put the index entry in the margin if desired. @@ -4752,14 +5338,26 @@ end % % Remember, we are within a group. \indexdummies % Must do this here, since \bf, etc expand at this stage - \def\backslashcurfont{\indexbackslash}% \indexbackslash isn't defined now - % so it will be output as is; and it will print as backslash. + \useindexbackslash % \indexbackslash isn't defined now so it will be output + % as is; and it will print as backslash. + % The braces around \indexbrace are recognized by texindex. % - % Process the index entry with all font commands turned off, to - % get the string to sort by. + % Get the string to sort by, by processing the index entry with all + % font commands turned off. {\indexnofonts - \edef\temp{\the\toks0}% need full expansion - \xdef\indexsorttmp{\temp}% + \def\lbracechar{{\indexlbrace}}% + \def\rbracechar{{\indexrbrace}}% + \let\{=\lbracechar + \let\}=\rbracechar + \indexnonalnumdisappear + \xdef\indexsortkey{}% + \let\sortas=\indexwritesortas + \edef\temp{\the\toks0}% + \setbox\dummybox = \hbox{\temp}% Make sure to execute any \sortas + \ifx\indexsortkey\empty + \xdef\indexsortkey{\temp}% + \ifx\indexsortkey\empty\xdef\indexsortkey{ }\fi + \fi }% % % Set up the complete index entry, with both the sort key and @@ -4769,10 +5367,11 @@ end % sorted result. \edef\temp{% \write\writeto{% - \string\entry{\indexsorttmp}{\noexpand\folio}{\the\toks0}}% + \string\entry{\indexsortkey}{\noexpand\folio}{\the\toks0}}% }% \temp } +\newbox\dummybox % used above % Take care of unwanted page breaks/skips around a whatsit: % @@ -4897,52 +5496,113 @@ end % \initial {@} % as its first line, TeX doesn't complain about mismatched braces % (because it thinks @} is a control sequence). - \catcode`\@ = 11 - \openin 1 \jobname.#1s + \catcode`\@ = 12 + % See comment in \requireopenindexfile. + \def\indexname{#1}\ifx\indexname\indexisfl\def\indexname{f1}\fi + \openin 1 \jobname.\indexname s \ifeof 1 % \enddoublecolumns gets confused if there is no text in the index, % and it loses the chapter title and the aux file entries for the % index. The easiest way to prevent this problem is to make sure % there is some text. \putwordIndexNonexistent + \typeout{No file \jobname.\indexname s.}% \else + \catcode`\\ = 0 % % If the index file exists but is empty, then \openin leaves \ifeof % false. We have to make TeX try to read something from the file, so % it can discover if there is anything in it. - \read 1 to \temp + \read 1 to \thisline \ifeof 1 \putwordIndexIsEmpty \else % Index files are almost Texinfo source, but we use \ as the escape % character. It would be better to use @, but that's too big a change % to make right now. - \def\indexbackslash{\backslashcurfont}% - \catcode`\\ = 0 - \escapechar = `\\ + \def\indexbackslash{\ttbackslash}% + \let\indexlbrace\{ % Likewise, set these sequences for braces + \let\indexrbrace\} % used in the sort key. \begindoublecolumns - \input \jobname.#1s + \let\dotheinsertentrybox\dotheinsertentryboxwithpenalty + % + % Read input from the index file line by line. + \loopdo + \ifeof1 \else + \read 1 to \nextline + \fi + % + \indexinputprocessing + \thisline + % + \ifeof1\else + \let\thisline\nextline + \repeat + %% \enddoublecolumns \fi \fi \closein 1 \endgroup} +\def\loopdo#1\repeat{\def\body{#1}\loopdoxxx} +\def\loopdoxxx{\let\next=\relax\body\let\next=\loopdoxxx\fi\next} + +\def\indexinputprocessing{% + \ifeof1 + \let\firsttoken\relax + \else + \edef\act{\gdef\noexpand\firsttoken{\getfirsttoken\nextline}}% + \act + \fi +} +\def\getfirsttoken#1{\expandafter\getfirsttokenx#1\endfirsttoken} +\long\def\getfirsttokenx#1#2\endfirsttoken{\noexpand#1} + % These macros are used by the sorted index file itself. % Change them to control the appearance of the index. -\def\initial#1{{% - % Some minor font changes for the special characters. - \let\tentt=\sectt \let\tt=\sectt \let\sf=\sectt +{\catcode`\/=13 \catcode`\-=13 \catcode`\^=13 \catcode`\~=13 \catcode`\_=13 +\catcode`\|=13 \catcode`\<=13 \catcode`\>=13 \catcode`\+=13 \catcode`\"=13 +\catcode`\$=3 +\gdef\initialglyphs{% + % Some changes for non-alphabetic characters. Using the glyphs from the + % math fonts looks more consistent than the typewriter font used elsewhere + % for these characters. + \def\indexbackslash{\math{\backslash}}% + \let\\=\indexbackslash % + % Can't get bold backslash so don't use bold forward slash + \catcode`\/=13 + \def/{{\secrmnotbold \normalslash}}% + \def-{{\normaldash\normaldash}}% en dash `--' + \def^{{\chapbf \normalcaret}}% + \def~{{\chapbf \normaltilde}}% + \def\_{% + \leavevmode \kern.07em \vbox{\hrule width.3em height.1ex}\kern .07em }% + \def|{$\vert$}% + \def<{$\less$}% + \def>{$\gtr$}% + \def+{$\normalplus$}% +}} + +\def\initial{% + \bgroup + \initialglyphs + \initialx +} + +\def\initialx#1{% % Remove any glue we may have, we'll be inserting our own. \removelastskip % % We like breaks before the index initials, so insert a bonus. + % The glue before the bonus allows a little bit of space at the + % bottom of a column to reduce an increase in inter-line spacing. \nobreak - \vskip 0pt plus 3\baselineskip - \penalty 0 - \vskip 0pt plus -3\baselineskip + \vskip 0pt plus 5\baselineskip + \penalty -300 + \vskip 0pt plus -5\baselineskip % % Typeset the initial. Making this add up to a whole number of % baselineskips increases the chance of the dots lining up from column @@ -4950,63 +5610,45 @@ end % we need before each entry, but it's better. % % No shrink because it confuses \balancecolumns. - \vskip 1.67\baselineskip plus .5\baselineskip - \leftline{\secbf #1}% + \vskip 1.67\baselineskip plus 1\baselineskip + \leftline{\secfonts \kern-0.05em \secbf #1}% + % \secfonts is inside the argument of \leftline so that the change of + % \baselineskip will not affect any glue inserted before the vbox that + % \leftline creates. % Do our best not to break after the initial. \nobreak \vskip .33\baselineskip plus .1\baselineskip -}} + \egroup % \initialglyphs +} + +\newdimen\entryrightmargin +\entryrightmargin=0pt % \entry typesets a paragraph consisting of the text (#1), dot leaders, and % then page number (#2) flushed to the right margin. It is used for index % and table of contents entries. The paragraph is indented by \leftskip. % -% A straightforward implementation would start like this: -% \def\entry#1#2{... -% But this freezes the catcodes in the argument, and can cause problems to -% @code, which sets - active. This problem was fixed by a kludge--- -% ``-'' was active throughout whole index, but this isn't really right. -% The right solution is to prevent \entry from swallowing the whole text. -% --kasal, 21nov03 \def\entry{% \begingroup + % + % For pdfTeX and XeTeX. + % The redefinition of \domark stops marks being added in \pdflink to + % preserve coloured links across page boundaries. Otherwise the marks + % would get in the way of \lastbox in \insertentrybox. + \let\domark\relax % % Start a new paragraph if necessary, so our assignments below can't % affect previous text. \par % - % Do not fill out the last line with white space. - \parfillskip = 0in - % % No extra space above this paragraph. \parskip = 0in % - % Do not prefer a separate line ending with a hyphen to fewer lines. - \finalhyphendemerits = 0 - % - % \hangindent is only relevant when the entry text and page number - % don't both fit on one line. In that case, bob suggests starting the - % dots pretty far over on the line. Unfortunately, a large - % indentation looks wrong when the entry text itself is broken across - % lines. So we use a small indentation and put up with long leaders. - % - % \hangafter is reset to 1 (which is the value we want) at the start - % of each paragraph, so we need not do anything with that. - \hangindent = 2em - % - % When the entry text needs to be broken, just fill out the first line - % with blank space. - \rightskip = 0pt plus1fil - % - % A bit of stretch before each entry for the benefit of balancing - % columns. - \vskip 0pt plus1pt - % % When reading the text of entry, convert explicit line breaks % from @* into spaces. The user might give these in long section % titles, for instance. \def\*{\unskip\space\ignorespaces}% - \def\entrybreak{\hfil\break}% + \def\entrybreak{\hfil\break}% An undocumented command % % Swallow the left brace of the text (first parameter): \afterassignment\doentry @@ -5014,45 +5656,168 @@ end } \def\entrybreak{\unskip\space\ignorespaces}% \def\doentry{% + % Save the text of the entry + \global\setbox\boxA=\hbox\bgroup \bgroup % Instead of the swallowed brace. \noindent \aftergroup\finishentry % And now comes the text of the entry. + % Not absorbing as a macro argument reduces the chance of problems + % with catcodes occurring. } -\def\finishentry#1{% +{\catcode`\@=11 +\gdef\finishentry#1{% + \egroup % end box A + \dimen@ = \wd\boxA % Length of text of entry + \global\setbox\boxA=\hbox\bgroup\unhbox\boxA % #1 is the page number. % - % The following is kludged to not output a line of dots in the index if - % there are no page numbers. The next person who breaks this will be - % cursed by a Unix daemon. - \setbox\boxA = \hbox{#1}% - \ifdim\wd\boxA = 0pt - \ % + % Get the width of the page numbers, and only use + % leaders if they are present. + \global\setbox\boxB = \hbox{#1}% + \ifdim\wd\boxB = 0pt + \null\nobreak\hfill\ % \else % - % If we must, put the page number on a line of its own, and fill out - % this line with blank space. (The \hfil is overwhelmed with the - % fill leaders glue in \indexdotfill if the page number does fit.) - \hfil\penalty50 \null\nobreak\indexdotfill % Have leaders before the page number. % - % The `\ ' here is removed by the implicit \unskip that TeX does as - % part of (the primitive) \par. Without it, a spurious underfull - % \hbox ensues. \ifpdf - \pdfgettoks#1.% - \ \the\toksA + \pdfgettoks#1.% + \hskip\skip\thinshrinkable\the\toksA \else - \ #1% + \ifx\XeTeXrevision\thisisundefined + \hskip\skip\thinshrinkable #1% + \else + \pdfgettoks#1.% + \hskip\skip\thinshrinkable\the\toksA + \fi \fi \fi - \par + \egroup % end \boxA + \ifdim\wd\boxB = 0pt + \global\setbox\entrybox=\vbox{\unhbox\boxA}% + \else + \global\setbox\entrybox=\vbox\bgroup + % We want the text of the entries to be aligned to the left, and the + % page numbers to be aligned to the right. + % + \parindent = 0pt + \advance\leftskip by 0pt plus 1fil + \advance\leftskip by 0pt plus -1fill + \rightskip = 0pt plus -1fil + \advance\rightskip by 0pt plus 1fill + % Cause last line, which could consist of page numbers on their own + % if the list of page numbers is long, to be aligned to the right. + \parfillskip=0pt plus -1fill + % + \advance\rightskip by \entryrightmargin + % Determine how far we can stretch into the margin. + % This allows, e.g., "Appendix H GNU Free Documentation License" to + % fit on one line in @letterpaper format. + \ifdim\entryrightmargin>2.1em + \dimen@i=2.1em + \else + \dimen@i=0em + \fi + \advance \parfillskip by 0pt minus 1\dimen@i + % + \dimen@ii = \hsize + \advance\dimen@ii by -1\leftskip + \advance\dimen@ii by -1\entryrightmargin + \advance\dimen@ii by 1\dimen@i + \ifdim\wd\boxA > \dimen@ii % If the entry doesn't fit in one line + \ifdim\dimen@ > 0.8\dimen@ii % due to long index text + % Try to split the text roughly evenly. \dimen@ will be the length of + % the first line. + \dimen@ = 0.7\dimen@ + \dimen@ii = \hsize + \ifnum\dimen@>\dimen@ii + % If the entry is too long (for example, if it needs more than + % two lines), use all the space in the first line. + \dimen@ = \dimen@ii + \fi + \advance\leftskip by 0pt plus 1fill % ragged right + \advance \dimen@ by 1\rightskip + \parshape = 2 0pt \dimen@ 0em \dimen@ii + % Ideally we'd add a finite glue at the end of the first line only, + % instead of using \parshape with explicit line lengths, but TeX + % doesn't seem to provide a way to do such a thing. + % + % Indent all lines but the first one. + \advance\leftskip by 1em + \advance\parindent by -1em + \fi\fi + \indent % start paragraph + \unhbox\boxA + % + % Do not prefer a separate line ending with a hyphen to fewer lines. + \finalhyphendemerits = 0 + % + % Word spacing - no stretch + \spaceskip=\fontdimen2\font minus \fontdimen4\font + % + \linepenalty=1000 % Discourage line breaks. + \hyphenpenalty=5000 % Discourage hyphenation. + % + \par % format the paragraph + \egroup % The \vbox + \fi \endgroup + \dotheinsertentrybox +}} + +\newskip\thinshrinkable +\skip\thinshrinkable=.15em minus .15em + +\newbox\entrybox +\def\insertentrybox{% + \ourunvbox\entrybox } +% default definition +\let\dotheinsertentrybox\insertentrybox + +% Use \lastbox to take apart vbox box by box, and add each sub-box +% to the current vertical list. +\def\ourunvbox#1{% +\bgroup % for local binding of \delayedbox + % Remove the last box from box #1 + \global\setbox#1=\vbox{% + \unvbox#1% + \unskip % remove any glue + \unpenalty + \global\setbox\interbox=\lastbox + }% + \setbox\delayedbox=\box\interbox + \ifdim\ht#1=0pt\else + \ourunvbox#1 % Repeat on what's left of the box + \nobreak + \fi + \box\delayedbox +\egroup +} +\newbox\delayedbox +\newbox\interbox + +% Used from \printindex. \firsttoken should be the first token +% after the \entry. If it's not another \entry, we are at the last +% line of a group of index entries, so insert a penalty to discourage +% widowed index entries. +\def\dotheinsertentryboxwithpenalty{% + \ifx\firsttoken\isentry + \else + \penalty 9000 + \fi + \insertentrybox +} +\def\isentry{\entry}% + % Like plain.tex's \dotfill, except uses up at least 1 em. +% The filll stretch here overpowers both the fil and fill stretch to push +% the page number to the right. \def\indexdotfill{\cleaders - \hbox{$\mathsurround=0pt \mkern1.5mu.\mkern1.5mu$}\hskip 1em plus 1fill} + \hbox{$\mathsurround=0pt \mkern1.5mu.\mkern1.5mu$}\hskip 1em plus 1filll} + \def\primary #1{\line{#1\hfil}} @@ -5066,7 +5831,11 @@ end \ifpdf \pdfgettoks#2.\ \the\toksA % The page number ends the paragraph. \else - #2 + \ifx\XeTeXrevision\thisisundefined + #2 + \else + \pdfgettoks#2.\ \the\toksA % The page number ends the paragraph. + \fi \fi \par }} @@ -5074,12 +5843,37 @@ end % Define two-column mode, which we use to typeset indexes. % Adapted from the TeXbook, page 416, which is to say, % the manmac.tex format used to print the TeXbook itself. -\catcode`\@=11 +\catcode`\@=11 % private names \newbox\partialpage \newdimen\doublecolumnhsize +% Use inside an output routine to save \topmark and \firstmark +\def\savemarks{% + \global\savedtopmark=\expandafter{\topmark }% + \global\savedfirstmark=\expandafter{\firstmark }% +} +\newtoks\savedtopmark +\newtoks\savedfirstmark + +% Set \topmark and \firstmark for next time \output runs. +% Can't be run from withinside \output (because any material +% added while an output routine is active, including +% penalties, is saved for after it finishes). The page so far +% should be empty, otherwise what's on it will be thrown away. +\def\restoremarks{% + \mark{\the\savedtopmark}% + \bgroup\output = {% + \setbox\dummybox=\box\PAGE + }abc\eject\egroup + % "abc" because output routine doesn't fire for a completely empty page. + \mark{\the\savedfirstmark}% +} + \def\begindoublecolumns{\begingroup % ended by \enddoublecolumns + % If not much space left on page, start a new page. + \ifdim\pagetotal>0.8\vsize\vfill\eject\fi + % % Grab any single-column material above us. \output = {% % @@ -5099,8 +5893,15 @@ end \unvbox\PAGE \kern-\topskip \kern\baselineskip }% + \savemarks }% \eject % run that output routine to set \partialpage + \restoremarks + % + % We recover the two marks that the last output routine saved in order + % to propagate the information in marks added around a chapter heading, + % which could be otherwise be lost by the time the final page is output. + % % % Use the double-column output routine for subsequent pages. \output = {\doublecolumnout}% @@ -5126,27 +5927,31 @@ end \divide\doublecolumnhsize by 2 \hsize = \doublecolumnhsize % - % Double the \vsize as well. (We don't need a separate register here, - % since nobody clobbers \vsize.) + % Double the \vsize as well. + \advance\vsize by -\ht\partialpage \vsize = 2\vsize + % + % For the benefit of balancing columns + \advance\baselineskip by 0pt plus 0.5pt } % The double-column output routine for all double-column pages except -% the last. +% the last, which is done by \balancecolumns. % \def\doublecolumnout{% + % \splittopskip=\topskip \splitmaxdepth=\maxdepth % Get the available space for the double columns -- the normal % (undoubled) page height minus any material left over from the % previous page. \dimen@ = \vsize \divide\dimen@ by 2 - \advance\dimen@ by -\ht\partialpage % % box0 will be the left-hand column, box2 the right. - \setbox0=\vsplit255 to\dimen@ \setbox2=\vsplit255 to\dimen@ + \setbox0=\vsplit\PAGE to\dimen@ \setbox2=\vsplit\PAGE to\dimen@ + \global\advance\vsize by 2\ht\partialpage \onepageout\pagesofar - \unvbox255 + \unvbox\PAGE \penalty\outputpenalty } % @@ -5157,10 +5962,11 @@ end % \hsize = \doublecolumnhsize \wd0=\hsize \wd2=\hsize - \hbox to\pagewidth{\box0\hfil\box2}% + \hbox to\txipagewidth{\box0\hfil\box2}% } -% -% All done with double columns. + + +% Finished with with double columns. \def\enddoublecolumns{% % The following penalty ensures that the page builder is exercised % _before_ we change the output routine. This is necessary in the @@ -5183,7 +5989,7 @@ end % goal. When TeX sees \eject from below which follows the final % section, it invokes the new output routine that we've set after % \balancecolumns below; \onepageout will try to fit the two columns - % and the final section into the vbox of \pageheight (see + % and the final section into the vbox of \txipageheight (see % \pagebody), causing an overfull box. % % Note that glue won't work here, because glue does not exercise the @@ -5191,53 +5997,88 @@ end \penalty0 % \output = {% - % Split the last of the double-column material. Leave it on the - % current page, no automatic page break. + % Split the last of the double-column material. + \savemarks \balancecolumns - % - % If we end up splitting too much material for the current page, - % though, there will be another page break right after this \output - % invocation ends. Having called \balancecolumns once, we do not - % want to call it again. Therefore, reset \output to its normal - % definition right away. (We hope \balancecolumns will never be - % called on to balance too much material, but if it is, this makes - % the output somewhat more palatable.) - \global\output = {\onepageout{\pagecontents\PAGE}}% }% - \eject - \endgroup % started in \begindoublecolumns - % - % \pagegoal was set to the doubled \vsize above, since we restarted - % the current page. We're now back to normal single-column - % typesetting, so reset \pagegoal to the normal \vsize (after the - % \endgroup where \vsize got restored). - \pagegoal = \vsize + \eject % call the \output just set + \ifdim\pagetotal=0pt + % Having called \balancecolumns once, we do not + % want to call it again. Therefore, reset \output to its normal + % definition right away. + \global\output = {\onepageout{\pagecontents\PAGE}}% + % + \endgroup % started in \begindoublecolumns + \restoremarks + % Leave the double-column material on the current page, no automatic + % page break. + \box\balancedcolumns + % + % \pagegoal was set to the doubled \vsize above, since we restarted + % the current page. We're now back to normal single-column + % typesetting, so reset \pagegoal to the normal \vsize. + \global\vsize = \txipageheight % + \pagegoal = \txipageheight % + \else + % We had some left-over material. This might happen when \doublecolumnout + % is called in \balancecolumns. Try again. + \expandafter\enddoublecolumns + \fi } +\newbox\balancedcolumns +\setbox\balancedcolumns=\vbox{shouldnt see this}% % -% Called at the end of the double column material. +% Only called for the last of the double column material. \doublecolumnout +% does the others. \def\balancecolumns{% - \setbox0 = \vbox{\unvbox255}% like \box255 but more efficient, see p.120. + \setbox0 = \vbox{\unvbox\PAGE}% like \box255 but more efficient, see p.120. \dimen@ = \ht0 \advance\dimen@ by \topskip \advance\dimen@ by-\baselineskip - \divide\dimen@ by 2 % target to split to - %debug\message{final 2-column material height=\the\ht0, target=\the\dimen@.}% - \splittopskip = \topskip - % Loop until we get a decent breakpoint. - {% - \vbadness = 10000 - \loop - \global\setbox3 = \copy0 - \global\setbox1 = \vsplit3 to \dimen@ - \ifdim\ht3>\dimen@ - \global\advance\dimen@ by 1pt - \repeat - }% - %debug\message{split to \the\dimen@, column heights: \the\ht1, \the\ht3.}% - \setbox0=\vbox to\dimen@{\unvbox1}% - \setbox2=\vbox to\dimen@{\unvbox3}% + \ifdim\dimen@<5\baselineskip + % Don't split a short final column in two. + \setbox2=\vbox{}% + \global\setbox\balancedcolumns=\vbox{\pagesofar}% + \else + \divide\dimen@ by 2 % target to split to + \dimen@ii = \dimen@ + \splittopskip = \topskip + % Loop until left column is at least as high as the right column. + {% + \vbadness = 10000 + \loop + \global\setbox3 = \copy0 + \global\setbox1 = \vsplit3 to \dimen@ + \ifdim\ht1<\ht3 + \global\advance\dimen@ by 1pt + \repeat + }% + % Now the left column is in box 1, and the right column in box 3. + % + % Check whether the left column has come out higher than the page itself. + % (Note that we have doubled \vsize for the double columns, so + % the actual height of the page is 0.5\vsize). + \ifdim2\ht1>\vsize + % It appears that we have been called upon to balance too much material. + % Output some of it with \doublecolumnout, leaving the rest on the page. + \setbox\PAGE=\box0 + \doublecolumnout + \else + % Compare the heights of the two columns. + \ifdim4\ht1>5\ht3 + % Column heights are too different, so don't make their bottoms + % flush with each other. + \setbox2=\vbox to \ht1 {\unvbox3\vfill}% + \setbox0=\vbox to \ht1 {\unvbox1\vfill}% + \else + % Make column bottoms flush with each other. + \setbox2=\vbox to\ht1{\unvbox3\unskip}% + \setbox0=\vbox to\ht1{\unvbox1\unskip}% + \fi + \global\setbox\balancedcolumns=\vbox{\pagesofar}% + \fi + \fi % - \pagesofar } \catcode`\@ = \other @@ -5252,10 +6093,14 @@ end \null \vskip.3\vsize % move it down on the page a bit \begingroup - \noindent \titlefonts\rmisbold #1\par % the text + \noindent \titlefonts\rm #1\par % the text \let\lastnode=\empty % no node to associate with \writetocentry{part}{#1}{}% but put it in the toc \headingsoff % no headline or footline on the part page + % This outputs a mark at the end of the page that clears \thischapter + % and \thissection, as is done in \startcontents. + \let\pchapsepmacro\relax + \chapmacro{}{Yomitfromtoc}{}% \chapoddpage \endgroup } @@ -5500,9 +6345,6 @@ end % @centerchap is like @unnumbered, but the heading is centered. \outer\parseargdef\centerchap{% - % Well, we could do the following in a group, but that would break - % an assumption that \chapmacro is called at the outermost level. - % Thus we are safer this way: --kasal, 24feb04 \let\centerparametersmaybe = \centerparameters \unnmhead0{#1}% \let\centerparametersmaybe = \relax @@ -5626,7 +6468,11 @@ end % Define plain chapter starts, and page on/off switching for it. \def\chapbreak{\dobreak \chapheadingskip {-4000}} + +% Start a new page \def\chappager{\par\vfill\supereject} + +% \chapoddpage - start on an odd page for a new chapter % Because \domark is called before \chapoddpage, the filler page will % get the headings for the next chapter, which is wrong. But we don't % care -- we just disable all headings on the filler page. @@ -5641,7 +6487,7 @@ end \fi } -\def\setchapternewpage #1 {\csname CHAPPAG#1\endcsname} +\parseargdef\setchapternewpage{\csname CHAPPAG#1\endcsname} \def\CHAPPAGoff{% \global\let\contentsalignmacro = \chappager @@ -5662,17 +6508,26 @@ end \CHAPPAGon -% Chapter opening. +% \chapmacro - Chapter opening. % % #1 is the text, #2 is the section type (Ynumbered, Ynothing, % Yappendix, Yomitfromtoc), #3 the chapter number. +% Not used for @heading series. % % To test against our argument. \def\Ynothingkeyword{Ynothing} -\def\Yomitfromtockeyword{Yomitfromtoc} \def\Yappendixkeyword{Yappendix} +\def\Yomitfromtockeyword{Yomitfromtoc} % \def\chapmacro#1#2#3{% + \expandafter\ifx\thisenv\titlepage\else + \checkenv{}% chapters, etc., should not start inside an environment. + \fi + % FIXME: \chapmacro is currently called from inside \titlepage when + % \setcontentsaftertitlepage to print the "Table of Contents" heading, but + % this should probably be done by \sectionheading with an option to print + % in chapter size. + % % Insert the first mark before the heading break (see notes for \domark). \let\prevchapterdefs=\lastchapterdefs \let\prevsectiondefs=\lastsectiondefs @@ -5724,7 +6579,8 @@ end \domark % {% - \chapfonts \rmisbold + \chapfonts \rm + \let\footnote=\errfootnoteheading % give better error message % % Have to define \lastsection before calling \donoderef, because the % xref code eventually uses it. On the other hand, it has to be called @@ -5777,30 +6633,6 @@ end } -% I don't think this chapter style is supported any more, so I'm not -% updating it with the new noderef stuff. We'll see. --karl, 11aug03. -% -\def\setchapterstyle #1 {\csname CHAPF#1\endcsname} -% -\def\unnchfopen #1{% - \chapoddpage - \vbox{\chapfonts \raggedtitlesettings #1\par}% - \nobreak\bigskip\nobreak -} -\def\chfopen #1#2{\chapoddpage {\chapfonts -\vbox to 3in{\vfil \hbox to\hsize{\hfil #2} \hbox to\hsize{\hfil #1} \vfil}}% -\par\penalty 5000 % -} -\def\centerchfopen #1{% - \chapoddpage - \vbox{\chapfonts \raggedtitlesettings \hfill #1\hfill}% - \nobreak\bigskip \nobreak -} -\def\CHAPFopen{% - \global\let\chapmacro=\chfopen - \global\let\centerchapmacro=\centerchfopen} - - % Section titles. These macros combine the section number parts and % call the generic \sectionheading to do the printing. % @@ -5818,22 +6650,29 @@ end % Print any size, any type, section title. % -% #1 is the text, #2 is the section level (sec/subsec/subsubsec), #3 is -% the section type for xrefs (Ynumbered, Ynothing, Yappendix), #4 is the -% section number. +% #1 is the text of the title, +% #2 is the section level (sec/subsec/subsubsec), +% #3 is the section type (Ynumbered, Ynothing, Yappendix, Yomitfromtoc), +% #4 is the section number. % \def\seckeyword{sec} % \def\sectionheading#1#2#3#4{% {% - \checkenv{}% should not be in an environment. - % - % Switch to the right set of fonts. - \csname #2fonts\endcsname \rmisbold - % \def\sectionlevel{#2}% \def\temptype{#3}% % + % It is ok for the @heading series commands to appear inside an + % environment (it's been historically allowed, though the logic is + % dubious), but not the others. + \ifx\temptype\Yomitfromtockeyword\else + \checkenv{}% non-@*heading should not be in an environment. + \fi + \let\footnote=\errfootnoteheading + % + % Switch to the right set of fonts. + \csname #2fonts\endcsname \rm + % % Insert first mark before the heading break (see notes for \domark). \let\prevsectiondefs=\lastsectiondefs \ifx\temptype\Ynothingkeyword @@ -5885,7 +6724,7 @@ end % % Now the second mark, after the heading break. No break points % between here and the heading. - \let\prevsectiondefs=\lastsectiondefs + \global\let\prevsectiondefs=\lastsectiondefs \domark % % Only insert the space after the number if we have a section number. @@ -5996,7 +6835,14 @@ end % 1 and 2 (the page numbers aren't printed), and so are the first % two pages of the document. Thus, we'd have two destinations named % `1', and two named `2'. - \ifpdf \global\pdfmakepagedesttrue \fi + \ifpdf + \global\pdfmakepagedesttrue + \else + \ifx\XeTeXrevision\thisisundefined + \else + \global\pdfmakepagedesttrue + \fi + \fi } @@ -6045,7 +6891,7 @@ end \savepageno = \pageno \begingroup % Set up to handle contents files properly. \raggedbottom % Worry more about breakpoints than the bottom. - \advance\hsize by -\contentsrightmargin % Don't use the full line length. + \entryrightmargin=\contentsrightmargin % Don't use the full line length. % % Roman numerals for page numbers. \ifnum \pageno>0 \global\pageno = \lastnegativepageno \fi @@ -6139,7 +6985,15 @@ end % exist, with an empty box. Let's hope all the numbers have the same width. % Also ignore the page number, which is conventionally not printed. \def\numeralbox{\setbox0=\hbox{8}\hbox to \wd0{\hfil}} -\def\partentry#1#2#3#4{\dochapentry{\numeralbox\labelspace#1}{}} +\def\partentry#1#2#3#4{% + % Add stretch and a bonus for breaking the page before the part heading. + % This reduces the chance of the page being broken immediately after the + % part heading, before a following chapter heading. + \vskip 0pt plus 5\baselineskip + \penalty-300 + \vskip 0pt plus -5\baselineskip + \dochapentry{\numeralbox\labelspace#1}{}% +} % % Parts, in the short toc. \def\shortpartentry#1#2#3#4{% @@ -6150,7 +7004,7 @@ end % Chapters, in the main contents. \def\numchapentry#1#2#3#4{\dochapentry{#2\labelspace#1}{#4}} -% + % Chapters, in the short toc. % See comments in \dochapentry re vbox and related settings. \def\shortchapentry#1#2#3#4{% @@ -6165,7 +7019,7 @@ end \setbox0 = \hbox{\putwordAppendix{} M}% \hbox to \wd0{\putwordAppendix{} #1\hss}} % -\def\appentry#1#2#3#4{\dochapentry{\appendixbox{#2}\labelspace#1}{#4}} +\def\appentry#1#2#3#4{\dochapentry{\appendixbox{#2}\hskip.7em#1}{#4}} % Unnumbered chapters. \def\unnchapentry#1#2#3#4{\dochapentry{#1}{#4}} @@ -6198,6 +7052,8 @@ end \def\dochapentry#1#2{% \penalty-300 \vskip1\baselineskip plus.33\baselineskip minus.25\baselineskip \begingroup + % Move the page numbers slightly to the right + \advance\entryrightmargin by -0.05em \chapentryfonts \tocentry{#1}{\dopageno\bgroup#2\egroup}% \endgroup @@ -6252,14 +7108,14 @@ end \catcode `\|=\other \catcode `\<=\other \catcode `\>=\other - \catcode`\`=\other - \catcode`\'=\other - \escapechar=`\\ + \catcode `\`=\other + \catcode `\'=\other % % ' is active in math mode (mathcode"8000). So reset it, and all our % other math active characters (just in case), to plain's definitions. \mathactive % + % Inverse of the list at the beginning of the file. \let\b=\ptexb \let\bullet=\ptexbullet \let\c=\ptexc @@ -6275,9 +7131,11 @@ end \let\+=\tabalign \let\}=\ptexrbrace \let\/=\ptexslash + \let\sp=\ptexsp \let\*=\ptexstar + %\let\sup=\ptexsup % do not redefine, we want @sup to work in math mode \let\t=\ptext - \expandafter \let\csname top\endcsname=\ptextop % outer + \expandafter \let\csname top\endcsname=\ptextop % we've made it outer \let\frenchspacing=\plainfrenchspacing % \def\endldots{\mathinner{\ldots\ldots\ldots\ldots}}% @@ -6307,6 +7165,24 @@ end % start of the next paragraph will insert \parskip. % \def\aboveenvbreak{{% + % =10000 instead of <10000 because of a special case in \itemzzz and + % \sectionheading, q.v. + \ifnum \lastpenalty=10000 \else + \advance\envskipamount by \parskip + \endgraf + \ifdim\lastskip<\envskipamount + \removelastskip + \ifnum\lastpenalty<10000 + % Penalize breaking before the environment, because preceding text + % often leads into it. + \penalty100 + \fi + \vskip\envskipamount + \fi + \fi +}} + +\def\afterenvbreak{{% % =10000 instead of <10000 because of a special case in \itemzzz and % \sectionheading, q.v. \ifnum \lastpenalty=10000 \else @@ -6322,8 +7198,6 @@ end \fi }} -\let\afterenvbreak = \aboveenvbreak - % \nonarrowing is a flag. If "set", @lisp etc don't narrow margins; it will % also clear it, so that its embedded environments do the narrowing again. \let\nonarrowing=\relax @@ -6361,15 +7235,13 @@ end % side, and for 6pt waste from % each corner char, and rule thickness \normbskip=\baselineskip \normpskip=\parskip \normlskip=\lineskip - % Flag to tell @lisp, etc., not to narrow margin. - \let\nonarrowing = t% % % If this cartouche directly follows a sectioning command, we need the % \parskip glue (backspaced over by default) or the cartouche can % collide with the section heading. \ifnum\lastpenalty>10000 \vskip\parskip \penalty\lastpenalty \fi % - \vbox\bgroup + \setbox\groupbox=\vbox\bgroup \baselineskip=0pt\parskip=0pt\lineskip=0pt \carttop \hbox\bgroup @@ -6393,6 +7265,7 @@ end \egroup \cartbot \egroup + \addgroupbox \checkinserts } @@ -6402,7 +7275,7 @@ end \newdimen\nonfillparindent \def\nonfillstart{% \aboveenvbreak - \hfuzz = 12pt % Don't be fussy + \ifdim\hfuzz < 12pt \hfuzz = 12pt \fi % Don't be fussy \sepspaces % Make spaces be word-separators rather than space tokens. \let\par = \lisppar % don't ignore blank lines \obeylines % each line of input is a line of output @@ -6529,9 +7402,13 @@ end % @raggedright does more-or-less normal line breaking but no right -% justification. From plain.tex. +% justification. From plain.tex. Don't stretch around special +% characters in urls in this environment, since the stretch at the right +% should be enough. \envdef\raggedright{% - \rightskip0pt plus2em \spaceskip.3333em \xspaceskip.5em\relax + \rightskip0pt plus2.4em \spaceskip.3333em \xspaceskip.5em\relax + \def\urefprestretchamount{0pt}% + \def\urefpoststretchamount{0pt}% } \let\Eraggedright\par @@ -6771,7 +7648,7 @@ end % typesetting commands (@smallbook, font changes, etc.) have to be done % beforehand -- and a) we want @copying to be done first in the source % file; b) letting users define the frontmatter in as flexible order as -% possible is very desirable. +% possible is desirable. % \def\copying{\checkenv{}\begingroup\scanargctxt\docopying} \def\docopying#1@end copying{\endgroup\def\copyingtext{#1}} @@ -6866,7 +7743,7 @@ end \temp } -% \domakedefun \deffn \deffnx \deffnheader +% \domakedefun \deffn \deffnx \deffnheader { (defn. of \deffnheader) } % % Define \deffn and \deffnx, without parameters. % \deffnheader has to be defined explicitly. @@ -7075,7 +7952,7 @@ end \fi % no return type #3% output function name }% - {\rm\enskip}% hskip 0.5 em of \tenrm + {\rm\enskip}% hskip 0.5 em of \rmfont % \boldbrax % arguments will be output next, if any. @@ -7204,34 +8081,41 @@ end } \fi -\def\scanmacro#1{\begingroup - \newlinechar`\^^M - \let\xeatspaces\eatspaces - % - % Undo catcode changes of \startcontents and \doprintindex - % When called from @insertcopying or (short)caption, we need active - % backslash to get it printed correctly. Previously, we had - % \catcode`\\=\other instead. We'll see whether a problem appears - % with macro expansion. --kasal, 19aug04 - \catcode`\@=0 \catcode`\\=\active \escapechar=`\@ - % - % ... and for \example: - \spaceisspace - % - % The \empty here causes a following catcode 5 newline to be eaten as - % part of reading whitespace after a control sequence. It does not - % eat a catcode 13 newline. There's no good way to handle the two - % cases (untried: maybe e-TeX's \everyeof could help, though plain TeX - % would then have different behavior). See the Macro Details node in - % the manual for the workaround we recommend for macros and - % line-oriented commands. - % - \scantokens{#1\empty}% -\endgroup} +% alias because \c means cedilla in @tex or @math +\let\texinfoc=\c +\newcount\savedcatcodeone +\newcount\savedcatcodetwo + +% Used at the time of macro expansion. +% Argument is macro body with arguments substituted +\def\scanmacro#1{% + \newlinechar`\^^M + \def\xeatspaces{\eatspaces}% + % + % Temporarily undo catcode changes of \printindex. Set catcode of @ to + % 0 so that @-commands in macro expansions aren't printed literally when + % formatting an index file, where \ is used as the escape character. + \savedcatcodeone=\catcode`\@ + \savedcatcodetwo=\catcode`\\ + \catcode`\@=0 + \catcode`\\=\active + % + % Process the macro body under the current catcode regime. + \scantokens{#1@texinfoc}% + % + \catcode`\@=\savedcatcodeone + \catcode`\\=\savedcatcodetwo + % + % The \texinfoc is to remove the \newlinechar added by \scantokens, and + % can be noticed by \parsearg. + % We avoid surrounding the call to \scantokens with \bgroup and \egroup + % to allow macros to open or close groups themselves. +} + +% Used for copying and captions \def\scanexp#1{% - \edef\temp{\noexpand\scanmacro{#1}}% - \temp + \expandafter\scanmacro\expandafter{#1}% } \newcount\paramno % Count of parameters @@ -7239,7 +8123,7 @@ end \newif\ifrecursive % Is it recursive? % List of all defined macros in the form -% \definedummyword\macro1\definedummyword\macro2... +% \commondummyword\macro1\commondummyword\macro2... % Currently is also contains all @aliases; the list can be split % if there is a need. \def\macrolist{} @@ -7247,7 +8131,7 @@ end % Add the macro to \macrolist \def\addtomacrolist#1{\expandafter \addtomacrolistxxx \csname#1\endcsname} \def\addtomacrolistxxx#1{% - \toks0 = \expandafter{\macrolist\definedummyword#1}% + \toks0 = \expandafter{\macrolist\commondummyword#1}% \xdef\macrolist{\the\toks0}% } @@ -7297,48 +8181,45 @@ end \catcode`\+=\other \catcode`\<=\other \catcode`\>=\other - \catcode`\@=\other \catcode`\^=\other \catcode`\_=\other \catcode`\|=\other \catcode`\~=\other - \ifx\declaredencoding\ascii \else \setnonasciicharscatcodenonglobal\other \fi + \passthroughcharstrue } \def\scanargctxt{% used for copying and captions, not macros. \scanctxt + \catcode`\@=\other \catcode`\\=\other \catcode`\^^M=\other } \def\macrobodyctxt{% used for @macro definitions \scanctxt + \catcode`\ =\other + \catcode`\@=\other \catcode`\{=\other \catcode`\}=\other \catcode`\^^M=\other \usembodybackslash } -\def\macroargctxt{% used when scanning invocations +% Used when scanning braced macro arguments. Note, however, that catcode +% changes here are ineffectual if the macro invocation was nested inside +% an argument to another Texinfo command. +\def\macroargctxt{% \scanctxt - \catcode`\\=0 + \catcode`\ =\active + \catcode`\^^M=\other + \catcode`\\=\active } -% why catcode 0 for \ in the above? To recognize \\ \{ \} as "escapes" -% for the single characters \ { }. Thus, we end up with the "commands" -% that would be written @\ @{ @} in a Texinfo document. -% -% We already have @{ and @}. For @\, we define it here, and only for -% this purpose, to produce a typewriter backslash (so, the @\ that we -% define for @math can't be used with @macro calls): -% -\def\\{\normalbackslash}% -% -% We would like to do this for \, too, since that is what makeinfo does. -% But it is not possible, because Texinfo already has a command @, for a -% cedilla accent. Documents must use @comma{} instead. -% -% \anythingelse will almost certainly be an error of some kind. +\def\macrolineargctxt{% used for whole-line arguments without braces + \scanctxt + \catcode`\{=\other + \catcode`\}=\other +} % \mbodybackslash is the definition of \ in @macro bodies. % It maps \foo\ => \csname macarg.foo\endcsname => #N @@ -7391,7 +8272,7 @@ end % Remove the macro name from \macrolist: \begingroup \expandafter\let\csname#1\endcsname \relax - \let\definedummyword\unmacrodo + \let\commondummyword\unmacrodo \xdef\macrolist{\macrolist}% \endgroup \else @@ -7406,61 +8287,40 @@ end \ifx #1\relax % remove this \else - \noexpand\definedummyword \noexpand#1% + \noexpand\commondummyword \noexpand#1% \fi } -% This makes use of the obscure feature that if the last token of a -% is #, then the preceding argument is delimited by -% an opening brace, and that opening brace is not consumed. +% \getargs -- Parse the arguments to a @macro line. Set \macname to +% the name of the macro, and \argl to the braced argument list. \def\getargs#1{\getargsxxx#1{}} \def\getargsxxx#1#{\getmacname #1 \relax\getmacargs} \def\getmacname#1 #2\relax{\macname={#1}} \def\getmacargs#1{\def\argl{#1}} +% This made use of the feature that if the last token of a +% is #, then the preceding argument is delimited by +% an opening brace, and that opening brace is not consumed. -% For macro processing make @ a letter so that we can make Texinfo private macro names. -\edef\texiatcatcode{\the\catcode`\@} -\catcode `@=11\relax - -% Parse the optional {params} list. Set up \paramno and \paramlist -% so \defmacro knows what to do. Define \macarg.BLAH for each BLAH -% in the params list to some hook where the argument si to be expanded. If -% there are less than 10 arguments that hook is to be replaced by ##N where N +% Parse the optional {params} list to @macro or @rmacro. +% Set \paramno to the number of arguments, +% and \paramlist to a parameter text for the macro (e.g. #1,#2,#3 for a +% three-param macro.) Define \macarg.BLAH for each BLAH in the params +% list to some hook where the argument is to be expanded. If there are +% less than 10 arguments that hook is to be replaced by ##N where N % is the position in that list, that is to say the macro arguments are to be % defined `a la TeX in the macro body. % % That gets used by \mbodybackslash (above). % -% We need to get `macro parameter char #' into several definitions. -% The technique used is stolen from LaTeX: let \hash be something -% unexpandable, insert that wherever you need a #, and then redefine -% it to # just before using the token list produced. +% If there are 10 or more arguments, a different technique is used: see +% \parsemmanyargdef. % -% The same technique is used to protect \eatspaces till just before -% the macro is used. -% -% If there are 10 or more arguments, a different technique is used, where the -% hook remains in the body, and when macro is to be expanded the body is -% processed again to replace the arguments. -% -% In that case, the hook is \the\toks N-1, and we simply set \toks N-1 to the -% argument N value and then \edef the body (nothing else will expand because of -% the catcode regime underwhich the body was input). -% -% If you compile with TeX (not eTeX), and you have macros with 10 or more -% arguments, you need that no macro has more than 256 arguments, otherwise an -% error is produced. \def\parsemargdef#1;{% \paramno=0\def\paramlist{}% \let\hash\relax + % \hash is redefined to `#' later to get it into definitions \let\xeatspaces\relax \parsemargdefxxx#1,;,% - % In case that there are 10 or more arguments we parse again the arguments - % list to set new definitions for the \macarg.BLAH macros corresponding to - % each BLAH argument. It was anyhow needed to parse already once this list - % in order to count the arguments, and as macros with at most 9 arguments - % are by far more frequent than macro with 10 or more arguments, defining - % twice the \macarg.BLAH macros does not cost too much processing power. \ifnum\paramno<10\relax\else \paramno0\relax \parsemmanyargdef@@#1,;,% 10 or more arguments @@ -7475,6 +8335,43 @@ end \edef\paramlist{\paramlist\hash\the\paramno,}% \fi\next} +% \parsemacbody, \parsermacbody +% +% Read recursive and nonrecursive macro bodies. (They're different since +% rec and nonrec macros end differently.) +% +% We are in \macrobodyctxt, and the \xdef causes backslashshes in the macro +% body to be transformed. +% Set \macrobody to the body of the macro, and call \defmacro. +% +{\catcode`\ =\other\long\gdef\parsemacbody#1@end macro{% +\xdef\macrobody{\eatcr{#1}}\endgroup\defmacro}}% +{\catcode`\ =\other\long\gdef\parsermacbody#1@end rmacro{% +\xdef\macrobody{\eatcr{#1}}\endgroup\defmacro}}% + +% Make @ a letter, so that we can make private-to-Texinfo macro names. +\edef\texiatcatcode{\the\catcode`\@} +\catcode `@=11\relax + +%%%%%%%%%%%%%% Code for > 10 arguments only %%%%%%%%%%%%%%%%%% + +% If there are 10 or more arguments, a different technique is used, where the +% hook remains in the body, and when macro is to be expanded the body is +% processed again to replace the arguments. +% +% In that case, the hook is \the\toks N-1, and we simply set \toks N-1 to the +% argument N value and then \edef the body (nothing else will expand because of +% the catcode regime under which the body was input). +% +% If you compile with TeX (not eTeX), and you have macros with 10 or more +% arguments, no macro can have more than 256 arguments (else error). +% +% In case that there are 10 or more arguments we parse again the arguments +% list to set new definitions for the \macarg.BLAH macros corresponding to +% each BLAH argument. It was anyhow needed to parse already once this list +% in order to count the arguments, and as macros with at most 9 arguments +% are by far more frequent than macro with 10 or more arguments, defining +% twice the \macarg.BLAH macros does not cost too much processing power. \def\parsemmanyargdef@@#1,{% \if#1;\let\next=\relax \else @@ -7490,16 +8387,6 @@ end \advance\paramno by 1\relax \fi\next} -% These two commands read recursive and nonrecursive macro bodies. -% (They're different since rec and nonrec macros end differently.) -% - -\catcode `\@\texiatcatcode -\long\def\parsemacbody#1@end macro% -{\xdef\temp{\eatcr{#1}}\endgroup\defmacro}% -\long\def\parsermacbody#1@end rmacro% -{\xdef\temp{\eatcr{#1}}\endgroup\defmacro}% -\catcode `\@=11\relax \let\endargs@\relax \let\nil@\relax @@ -7507,7 +8394,7 @@ end \long\def\nillm@{\nil@}% % This macro is expanded during the Texinfo macro expansion, not during its -% definition. It gets all the arguments values and assigns them to macros +% definition. It gets all the arguments' values and assigns them to macros % macarg.ARGNAME % % #1 is the macro name @@ -7528,8 +8415,6 @@ end \getargvals@@ \fi } - -% \def\getargvals@@{% \ifx\paramlist\nilm@ % Some sanity check needed here that \argvaluelist is also empty. @@ -7573,7 +8458,8 @@ end } % Replace arguments by their values in the macro body, and place the result -% in macro \@tempa +% in macro \@tempa. +% \def\macvalstoargs@{% % To do this we use the property that token registers that are \the'ed % within an \edef expand only once. So we are going to place all argument @@ -7597,8 +8483,9 @@ end \expandafter\def\expandafter\@tempa\expandafter{\@tempc}% } +% Define the named-macro outside of this group and then close this group. +% \def\macargexpandinbody@{% - %% Define the named-macro outside of this group and then close this group. \expandafter \endgroup \macargdeflist@ @@ -7635,14 +8522,8 @@ end \next } -% Save the token stack pointer into macro #1 -\def\texisavetoksstackpoint#1{\edef#1{\the\@cclvi}} -% Restore the token stack pointer from number in macro #1 -\def\texirestoretoksstackpoint#1{\expandafter\mathchardef\expandafter\@cclvi#1\relax} -% newtoks that can be used non \outer . -\def\texinonouternewtoks{\alloc@ 5\toks \toksdef \@cclvi} - -% Tailing missing arguments are set to empty +% Trailing missing arguments are set to empty. +% \def\setemptyargvalues@{% \ifx\paramlist\nilm@ \let\next\macargexpandinbody@ @@ -7672,99 +8553,191 @@ end \long\def#2{#4}% } -% This defines a Texinfo @macro. There are eight cases: recursive and -% nonrecursive macros of zero, one, up to nine, and many arguments. -% Much magic with \expandafter here. + +%%%%%%%%%%%%%% End of code for > 10 arguments %%%%%%%%%%%%%%%%%% + + +% This defines a Texinfo @macro or @rmacro, called by \parsemacbody. +% \macrobody has the body of the macro in it, with placeholders for +% its parameters, looking like "\xeatspaces{\hash 1}". +% \paramno is the number of parameters +% \paramlist is a TeX parameter text, e.g. "#1,#2,#3," +% There are four cases: macros of zero, one, up to nine, and many arguments. % \xdef is used so that macro definitions will survive the file -% they're defined in; @include reads the file inside a group. +% they're defined in: @include reads the file inside a group. % \def\defmacro{% \let\hash=##% convert placeholders to macro parameter chars - \ifrecursive - \ifcase\paramno - % 0 - \expandafter\xdef\csname\the\macname\endcsname{% - \noexpand\scanmacro{\temp}}% - \or % 1 - \expandafter\xdef\csname\the\macname\endcsname{% - \bgroup\noexpand\macroargctxt - \noexpand\braceorline - \expandafter\noexpand\csname\the\macname xxx\endcsname}% - \expandafter\xdef\csname\the\macname xxx\endcsname##1{% - \egroup\noexpand\scanmacro{\temp}}% - \else - \ifnum\paramno<10\relax % at most 9 - \expandafter\xdef\csname\the\macname\endcsname{% - \bgroup\noexpand\macroargctxt - \noexpand\csname\the\macname xx\endcsname}% - \expandafter\xdef\csname\the\macname xx\endcsname##1{% - \expandafter\noexpand\csname\the\macname xxx\endcsname ##1,}% - \expandafter\expandafter - \expandafter\xdef - \expandafter\expandafter - \csname\the\macname xxx\endcsname - \paramlist{\egroup\noexpand\scanmacro{\temp}}% - \else % 10 or more - \expandafter\xdef\csname\the\macname\endcsname{% - \noexpand\getargvals@{\the\macname}{\argl}% - }% - \global\expandafter\let\csname mac.\the\macname .body\endcsname\temp - \global\expandafter\let\csname mac.\the\macname .recurse\endcsname\gobble - \fi - \fi + \ifnum\paramno=1 + \def\xeatspaces##1{##1}% + % This removes the pair of braces around the argument. We don't + % use \eatspaces, because this can cause ends of lines to be lost + % when the argument to \eatspaces is read, leading to line-based + % commands like "@itemize" not being read correctly. \else - \ifcase\paramno - % 0 + \let\xeatspaces\relax % suppress expansion + \fi + \ifcase\paramno + % 0 + \expandafter\xdef\csname\the\macname\endcsname{% + \bgroup + \noexpand\spaceisspace + \noexpand\endlineisspace + \noexpand\expandafter % skip any whitespace after the macro name. + \expandafter\noexpand\csname\the\macname @@@\endcsname}% + \expandafter\xdef\csname\the\macname @@@\endcsname{% + \egroup + \noexpand\scanmacro{\macrobody}}% + \or % 1 + \expandafter\xdef\csname\the\macname\endcsname{% + \bgroup + \noexpand\braceorline + \expandafter\noexpand\csname\the\macname @@@\endcsname}% + \expandafter\xdef\csname\the\macname @@@\endcsname##1{% + \egroup + \noexpand\scanmacro{\macrobody}% + }% + \else % at most 9 + \ifnum\paramno<10\relax + % @MACNAME sets the context for reading the macro argument + % @MACNAME@@ gets the argument, processes backslashes and appends a + % comma. + % @MACNAME@@@ removes braces surrounding the argument list. + % @MACNAME@@@@ scans the macro body with arguments substituted. \expandafter\xdef\csname\the\macname\endcsname{% - \noexpand\norecurse{\the\macname}% - \noexpand\scanmacro{\temp}\egroup}% - \or % 1 + \bgroup + \noexpand\expandafter % This \expandafter skip any spaces after the + \noexpand\macroargctxt % macro before we change the catcode of space. + \noexpand\expandafter + \expandafter\noexpand\csname\the\macname @@\endcsname}% + \expandafter\xdef\csname\the\macname @@\endcsname##1{% + \noexpand\passargtomacro + \expandafter\noexpand\csname\the\macname @@@\endcsname{##1,}}% + \expandafter\xdef\csname\the\macname @@@\endcsname##1{% + \expandafter\noexpand\csname\the\macname @@@@\endcsname ##1}% + \expandafter\expandafter + \expandafter\xdef + \expandafter\expandafter + \csname\the\macname @@@@\endcsname\paramlist{% + \egroup\noexpand\scanmacro{\macrobody}}% + \else % 10 or more: \expandafter\xdef\csname\the\macname\endcsname{% - \bgroup\noexpand\macroargctxt - \noexpand\braceorline - \expandafter\noexpand\csname\the\macname xxx\endcsname}% - \expandafter\xdef\csname\the\macname xxx\endcsname##1{% - \egroup - \noexpand\norecurse{\the\macname}% - \noexpand\scanmacro{\temp}\egroup}% - \else % at most 9 - \ifnum\paramno<10\relax - \expandafter\xdef\csname\the\macname\endcsname{% - \bgroup\noexpand\macroargctxt - \expandafter\noexpand\csname\the\macname xx\endcsname}% - \expandafter\xdef\csname\the\macname xx\endcsname##1{% - \expandafter\noexpand\csname\the\macname xxx\endcsname ##1,}% - \expandafter\expandafter - \expandafter\xdef - \expandafter\expandafter - \csname\the\macname xxx\endcsname - \paramlist{% - \egroup - \noexpand\norecurse{\the\macname}% - \noexpand\scanmacro{\temp}\egroup}% - \else % 10 or more: - \expandafter\xdef\csname\the\macname\endcsname{% - \noexpand\getargvals@{\the\macname}{\argl}% - }% - \global\expandafter\let\csname mac.\the\macname .body\endcsname\temp - \global\expandafter\let\csname mac.\the\macname .recurse\endcsname\norecurse - \fi + \noexpand\getargvals@{\the\macname}{\argl}% + }% + \global\expandafter\let\csname mac.\the\macname .body\endcsname\macrobody + \global\expandafter\let\csname mac.\the\macname .recurse\endcsname\gobble \fi \fi} -\catcode `\@\texiatcatcode\relax +\catcode `\@\texiatcatcode\relax % end private-to-Texinfo catcodes \def\norecurse#1{\bgroup\cslet{#1}{macsave.#1}} -% \braceorline decides whether the next nonwhitespace character is a -% {. If so it reads up to the closing }, if not, it reads the whole -% line. Whatever was read is then fed to the next control sequence -% as an argument (by \parsebrace or \parsearg). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +{\catcode`\@=0 \catcode`\\=13 % We need to manipulate \ so use @ as escape +@catcode`@_=11 % private names +@catcode`@!=11 % used as argument separator + +% \passargtomacro#1#2 - +% Call #1 with a list of tokens #2, with any doubled backslashes in #2 +% compressed to one. +% +% This implementation works by expansion, and not execution (so we cannot use +% \def or similar). This reduces the risk of this failing in contexts where +% complete expansion is done with no execution (for example, in writing out to +% an auxiliary file for an index entry). +% +% State is kept in the input stream: the argument passed to +% @look_ahead, @gobble_and_check_finish and @add_segment is +% +% THE_MACRO ARG_RESULT ! {PENDING_BS} NEXT_TOKEN (... rest of input) +% +% where: +% THE_MACRO - name of the macro we want to call +% ARG_RESULT - argument list we build to pass to that macro +% PENDING_BS - either a backslash or nothing +% NEXT_TOKEN - used to look ahead in the input stream to see what's coming next + +@gdef@passargtomacro#1#2{% + @add_segment #1!{}@relax#2\@_finish\% +} +@gdef@_finish{@_finishx} @global@let@_finishx@relax + +% #1 - THE_MACRO ARG_RESULT +% #2 - PENDING_BS +% #3 - NEXT_TOKEN +% #4 used to look ahead +% +% If the next token is not a backslash, process the rest of the argument; +% otherwise, remove the next token. +@gdef@look_ahead#1!#2#3#4{% + @ifx#4\% + @expandafter@gobble_and_check_finish + @else + @expandafter@add_segment + @fi#1!{#2}#4#4% +} + +% #1 - THE_MACRO ARG_RESULT +% #2 - PENDING_BS +% #3 - NEXT_TOKEN +% #4 should be a backslash, which is gobbled. +% #5 looks ahead +% +% Double backslash found. Add a single backslash, and look ahead. +@gdef@gobble_and_check_finish#1!#2#3#4#5{% + @add_segment#1\!{}#5#5% +} + +@gdef@is_fi{@fi} + +% #1 - THE_MACRO ARG_RESULT +% #2 - PENDING_BS +% #3 - NEXT_TOKEN +% #4 is input stream until next backslash +% +% Input stream is either at the start of the argument, or just after a +% backslash sequence, either a lone backslash, or a doubled backslash. +% NEXT_TOKEN contains the first token in the input stream: if it is \finish, +% finish; otherwise, append to ARG_RESULT the segment of the argument up until +% the next backslash. PENDING_BACKSLASH contains a backslash to represent +% a backslash just before the start of the input stream that has not been +% added to ARG_RESULT. +@gdef@add_segment#1!#2#3#4\{% +@ifx#3@_finish + @call_the_macro#1!% +@else + % append the pending backslash to the result, followed by the next segment + @expandafter@is_fi@look_ahead#1#2#4!{\}@fi + % this @fi is discarded by @look_ahead. + % we can't get rid of it with \expandafter because we don't know how + % long #4 is. +} + +% #1 - THE_MACRO +% #2 - ARG_RESULT +% #3 discards the res of the conditional in @add_segment, and @is_fi ends the +% conditional. +@gdef@call_the_macro#1#2!#3@fi{@is_fi #1{#2}} + +} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +% \braceorline MAC is used for a one-argument macro MAC. It checks +% whether the next non-whitespace character is a {. It sets the context +% for reading the argument (slightly different in the two cases). Then, +% to read the argument, in the whole-line case, it then calls the regular +% \parsearg MAC; in the lbrace case, it calls \passargtomacro MAC. % \def\braceorline#1{\let\macnamexxx=#1\futurelet\nchar\braceorlinexxx} \def\braceorlinexxx{% - \ifx\nchar\bgroup\else - \expandafter\parsearg + \ifx\nchar\bgroup + \macroargctxt + \expandafter\passargtomacro + \else + \macrolineargctxt\expandafter\parsearg \fi \macnamexxx} @@ -7846,7 +8819,10 @@ end \pdfmkdest{#1}% \iflinks {% + \requireauxfile \atdummies % preserve commands, but don't expand them + % match definition in \xrdef, \refx, \xrefX. + \def\value##1{##1}% \edef\writexrdef##1##2{% \write\auxfile{@xrdef{#1-% #1 of \setref, expanded by the \edef ##1}{##2}}% these are parameters of \writexrdef @@ -7885,9 +8861,12 @@ end % node name, #4 the name of the Info file, #5 the name of the printed % manual. All but the node name can be omitted. % -\def\pxref#1{\putwordsee{} \xrefX[#1,,,,,,,]} -\def\xref#1{\putwordSee{} \xrefX[#1,,,,,,,]} -\def\ref#1{\xrefX[#1,,,,,,,]} +\def\pxref{\putwordsee{} \xrefXX} +\def\xref{\putwordSee{} \xrefXX} +\def\ref{\xrefXX} + +\def\xrefXX#1{\def\xrefXXarg{#1}\futurelet\tokenafterxref\xrefXXX} +\def\xrefXXX{\expandafter\xrefX\expandafter[\xrefXXarg,,,,,,,]} % \newbox\toprefbox \newbox\printedrefnamebox @@ -7934,9 +8913,10 @@ end % % Make link in pdf output. \ifpdf + % For pdfTeX and LuaTeX {\indexnofonts - \turnoffactive \makevalueexpandable + \turnoffactive % This expands tokens, so do it after making catcode changes, so _ % etc. don't get their TeX definitions. This ignores all spaces in % #4, including (wrongly) those in the middle of the filename. @@ -7944,35 +8924,74 @@ end % % This (wrongly) does not take account of leading or trailing % spaces in #1, which should be ignored. - \edef\pdfxrefdest{#1}% - \ifx\pdfxrefdest\empty - \def\pdfxrefdest{Top}% no empty targets - \else - \txiescapepdf\pdfxrefdest % escape PDF special chars + \setpdfdestname{#1}% + % + \ifx\pdfdestname\empty + \def\pdfdestname{Top}% no empty targets \fi % \leavevmode \startlink attr{/Border [0 0 0]}% \ifnum\filenamelength>0 - goto file{\the\filename.pdf} name{\pdfxrefdest}% + goto file{\the\filename.pdf} name{\pdfdestname}% \else - goto name{\pdfmkpgn{\pdfxrefdest}}% + goto name{\pdfmkpgn{\pdfdestname}}% \fi }% \setcolor{\linkcolor}% + \else + \ifx\XeTeXrevision\thisisundefined + \else + % For XeTeX + {\indexnofonts + \makevalueexpandable + \turnoffactive + % This expands tokens, so do it after making catcode changes, so _ + % etc. don't get their TeX definitions. This ignores all spaces in + % #4, including (wrongly) those in the middle of the filename. + \getfilename{#4}% + % + % This (wrongly) does not take account of leading or trailing + % spaces in #1, which should be ignored. + \setpdfdestname{#1}% + % + \ifx\pdfdestname\empty + \def\pdfdestname{Top}% no empty targets + \fi + % + \leavevmode + \ifnum\filenamelength>0 + % With default settings, + % XeTeX (xdvipdfmx) replaces link destination names with integers. + % In this case, the replaced destination names of + % remote PDFs are no longer known. In order to avoid a replacement, + % you can use xdvipdfmx's command line option `-C 0x0010'. + % If you use XeTeX 0.99996+ (TeX Live 2016+), + % this command line option is no longer necessary + % because we can use the `dvipdfmx:config' special. + \special{pdf:bann << /Border [0 0 0] /Type /Annot /Subtype /Link /A + << /S /GoToR /F (\the\filename.pdf) /D (\pdfdestname) >> >>}% + \else + \special{pdf:bann << /Border [0 0 0] /Type /Annot /Subtype /Link /A + << /S /GoTo /D (\pdfdestname) >> >>}% + \fi + }% + \setcolor{\linkcolor}% + \fi \fi - % - % Float references are printed completely differently: "Figure 1.2" - % instead of "[somenode], p.3". We distinguish them by the - % LABEL-title being set to a magic string. {% % Have to otherify everything special to allow the \csname to % include an _ in the xref name, etc. \indexnofonts \turnoffactive + \def\value##1{##1}% \expandafter\global\expandafter\let\expandafter\Xthisreftitle \csname XR#1-title\endcsname }% + % + % Float references are printed completely differently: "Figure 1.2" + % instead of "[somenode], p.3". \iffloat distinguishes them by + % \Xthisreftitle being set to a magic string. \iffloat\Xthisreftitle % If the user specified the print name (third arg) to the ref, % print it instead of our usual "Figure 1.2". @@ -8031,6 +9050,15 @@ end % % output the `page 3'. \turnoffactive \putwordpage\tie\refx{#1-pg}{}% + % Add a , if xref followed by a space + \if\space\noexpand\tokenafterxref ,% + \else\ifx\ \tokenafterxref ,% @TAB + \else\ifx\*\tokenafterxref ,% @* + \else\ifx\ \tokenafterxref ,% @SPACE + \else\ifx\ + \tokenafterxref ,% @NL + \else\ifx\tie\tokenafterxref ,% @tie + \fi\fi\fi\fi\fi\fi \fi\fi \fi \endlink @@ -8097,13 +9125,14 @@ end \fi\fi\fi } -% Define \refx{NAME}{SUFFIX} to reference a cross-reference string named NAME. -% If its value is nonempty, SUFFIX is output afterward. -% +% \refx{NAME}{SUFFIX} - reference a cross-reference string named NAME. SUFFIX +% is output afterwards if non-empty. \def\refx#1#2{% + \requireauxfile {% \indexnofonts \otherbackslash + \def\value##1{##1}% \expandafter\global\expandafter\let\expandafter\thisrefX \csname XR#1\endcsname }% @@ -8128,20 +9157,28 @@ end #2% Output the suffix in any case. } -% This is the macro invoked by entries in the aux file. Usually it's -% just a \def (we prepend XR to the control sequence name to avoid -% collisions). But if this is a float type, we have more work to do. +% This is the macro invoked by entries in the aux file. Define a control +% sequence for a cross-reference target (we prepend XR to the control sequence +% name to avoid collisions). The value is the page number. If this is a float +% type, we have more work to do. % \def\xrdef#1#2{% - {% The node name might contain 8-bit characters, which in our current - % implementation are changed to commands like @'e. Don't let these - % mess up the control sequence name. + {% Expand the node or anchor name to remove control sequences. + % \turnoffactive stops 8-bit characters being changed to commands + % like @'e. \refx does the same to retrieve the value in the definition. \indexnofonts \turnoffactive + \def\value##1{##1}% \xdef\safexrefname{#1}% }% % - \expandafter\gdef\csname XR\safexrefname\endcsname{#2}% remember this xref + \bgroup + \expandafter\gdef\csname XR\safexrefname\endcsname{#2}% + \egroup + % We put the \gdef inside a group to avoid the definitions building up on + % TeX's save stack, which can cause it to run out of space for aux files with + % thousands of lines. \gdef doesn't use the save stack, but \csname does + % when it defines an unknown control sequence as \relax. % % Was that xref control sequence that we just defined for a float? \expandafter\iffloat\csname XR\safexrefname\endcsname @@ -8164,6 +9201,23 @@ end \fi } +% If working on a large document in chapters, it is convenient to +% be able to disable indexing, cross-referencing, and contents, for test runs. +% This is done with @novalidate at the beginning of the file. +% +\newif\iflinks \linkstrue % by default we want the aux files. +\let\novalidate = \linksfalse + +% Used when writing to the aux file, or when using data from it. +\def\requireauxfile{% + \iflinks + \tryauxfile + % Open the new aux file. TeX will close it automatically at exit. + \immediate\openout\auxfile=\jobname.aux + \fi + \global\let\requireauxfile=\relax % Only do this once. +} + % Read the last existing aux file, if any. No error if none exists. % \def\tryauxfile{% @@ -8242,16 +9296,6 @@ end % now. --karl, 15jan04. \catcode`\\=\other % - % Make the characters 128-255 be printing characters. - {% - \count1=128 - \def\loop{% - \catcode\count1=\other - \advance\count1 by 1 - \ifnum \count1<256 \loop \fi - }% - }% - % % @ is our escape character in .aux files, and we need braces. \catcode`\{=1 \catcode`\}=2 @@ -8284,8 +9328,6 @@ end % % Auto-number footnotes. Otherwise like plain. \gdef\footnote{% - \let\indent=\ptexindent - \let\noindent=\ptexnoindent \global\advance\footnoteno by \@ne \edef\thisfootno{$^{\the\footnoteno}$}% % @@ -8309,10 +9351,15 @@ end % \gdef\dofootnote{% \insert\footins\bgroup + % + % Nested footnotes are not supported in TeX, that would take a lot + % more work. (\startsavinginserts does not suffice.) + \let\footnote=\errfootnotenest + % % We want to typeset this text as a normal paragraph, even if the % footnote reference occurs in (for example) a display environment. % So reset some parameters. - \hsize=\pagewidth + \hsize=\txipagewidth \interlinepenalty\interfootnotelinepenalty \splittopskip\ht\strutbox % top baseline for broken footnotes \splitmaxdepth\dp\strutbox @@ -8346,13 +9393,24 @@ end } }%end \catcode `\@=11 +\def\errfootnotenest{% + \errhelp=\EMsimple + \errmessage{Nested footnotes not supported in texinfo.tex, + even though they work in makeinfo; sorry} +} + +\def\errfootnoteheading{% + \errhelp=\EMsimple + \errmessage{Footnotes in chapters, sections, etc., are not supported} +} + % In case a @footnote appears in a vbox, save the footnote text and create % the real \insert just after the vbox finished. Otherwise, the insertion % would be lost. % Similarly, if a @footnote appears inside an alignment, save the footnote % text to a box and make the \insert when a row of the table is finished. % And the same can be done for other insert classes. --kasal, 16nov03. - +% % Replace the \insert primitive by a cheating macro. % Deeper inside, just make sure that the saved insertions are not spilled % out prematurely. @@ -8426,7 +9484,7 @@ end \newif\ifwarnednoepsf \newhelp\noepsfhelp{epsf.tex must be installed for images to work. It is also included in the Texinfo distribution, or you can get - it from ftp://tug.org/tex/epsf.tex.} + it from https://ctan.org/texarchive/macros/texinfo/texinfo/doc/epsf.tex.} % \def\image#1{% \ifx\epsfbox\thisisundefined @@ -8450,6 +9508,7 @@ end \def\imagexxx#1,#2,#3,#4,#5,#6\finish{\begingroup \catcode`\^^M = 5 % in case we're inside an example \normalturnoffactive % allow _ et al. in names + \def\xprocessmacroarg{\eatspaces}% in case we are being used via a macro % If the image is by itself, center it. \ifvmode \imagevmodetrue @@ -8479,12 +9538,21 @@ end % % Output the image. \ifpdf + % For pdfTeX and LuaTeX <= 0.80 \dopdfimage{#1}{#2}{#3}% \else - % \epsfbox itself resets \epsf?size at each figure. - \setbox0 = \hbox{\ignorespaces #2}\ifdim\wd0 > 0pt \epsfxsize=#2\relax \fi - \setbox0 = \hbox{\ignorespaces #3}\ifdim\wd0 > 0pt \epsfysize=#3\relax \fi - \epsfbox{#1.eps}% + \ifx\XeTeXrevision\thisisundefined + % For epsf.tex + % \epsfbox itself resets \epsf?size at each figure. + \setbox0 = \hbox{\ignorespaces #2}% + \ifdim\wd0 > 0pt \epsfxsize=#2\relax \fi + \setbox0 = \hbox{\ignorespaces #3}% + \ifdim\wd0 > 0pt \epsfysize=#3\relax \fi + \epsfbox{#1.eps}% + \else + % For XeTeX + \doxeteximage{#1}{#2}{#3}% + \fi \fi % \ifimagevmode @@ -8606,7 +9674,7 @@ end % \ifx\thiscaption\empty \else \ifx\floatident\empty \else - \appendtomacro\captionline{: }% had ident, so need a colon between + \appendtomacro\captionline{: }% had ident, so need a colon between \fi % % caption text. @@ -8630,32 +9698,20 @@ end % \floatlabel-lof. Besides \floatident, we include the short % caption if specified, else the full caption if specified, else nothing. {% + \requireauxfile \atdummies % - % since we read the caption text in the macro world, where ^^M - % is turned into a normal character, we have to scan it back, so - % we don't write the literal three characters "^^M" into the aux file. - \scanexp{% - \xdef\noexpand\gtemp{% - \ifx\thisshortcaption\empty - \thiscaption - \else - \thisshortcaption - \fi - }% - }% + \ifx\thisshortcaption\empty + \def\gtemp{\thiscaption}% + \else + \def\gtemp{\thisshortcaption}% + \fi \immediate\write\auxfile{@xrdef{\floatlabel-lof}{\floatident - \ifx\gtemp\empty \else : \gtemp \fi}}% + \ifx\gtemp\empty \else : \gtemp \fi}}% }% \fi \egroup % end of \vtop % - % place the captured inserts - % - % BEWARE: when the floats start floating, we have to issue warning - % whenever an insert appears inside a float which could possibly - % float. --kasal, 26may04 - % \checkinserts } @@ -8769,20 +9825,20 @@ end { \catcode`\_ = \active \globaldefs=1 -\parseargdef\documentlanguage{\begingroup - \let_=\normalunderscore % normal _ character for filenames +\parseargdef\documentlanguage{% \tex % read txi-??.tex file in plain TeX. % Read the file by the name they passed if it exists. + \let_ = \normalunderscore % normal _ character for filename test \openin 1 txi-#1.tex \ifeof 1 - \documentlanguagetrywithoutunderscore{#1_\finish}% + \documentlanguagetrywithoutunderscore #1_\finish \else \globaldefs = 1 % everything in the txi-LL files needs to persist \input txi-#1.tex \fi \closein 1 \endgroup % end raw TeX -\endgroup} +} % % If they passed de_DE, and txi-de_DE.tex doesn't exist, % try txi-de.tex. @@ -8830,6 +9886,70 @@ directory should work if nowhere else does.} \global\righthyphenmin = #3\relax } +% XeTeX and LuaTeX can handle Unicode natively. +% Their default I/O uses UTF-8 sequences instead of a byte-wise operation. +% Other TeX engines' I/O (pdfTeX, etc.) is byte-wise. +% +\newif\iftxinativeunicodecapable +\newif\iftxiusebytewiseio + +\ifx\XeTeXrevision\thisisundefined + \ifx\luatexversion\thisisundefined + \txinativeunicodecapablefalse + \txiusebytewiseiotrue + \else + \txinativeunicodecapabletrue + \txiusebytewiseiofalse + \fi +\else + \txinativeunicodecapabletrue + \txiusebytewiseiofalse +\fi + +% Set I/O by bytes instead of UTF-8 sequence for XeTeX and LuaTex +% for non-UTF-8 (byte-wise) encodings. +% +\def\setbytewiseio{% + \ifx\XeTeXrevision\thisisundefined + \else + \XeTeXdefaultencoding "bytes" % For subsequent files to be read + \XeTeXinputencoding "bytes" % For document root file + % Unfortunately, there seems to be no corresponding XeTeX command for + % output encoding. This is a problem for auxiliary index and TOC files. + % The only solution would be perhaps to write out @U{...} sequences in + % place of non-ASCII characters. + \fi + + \ifx\luatexversion\thisisundefined + \else + \directlua{ + local utf8_char, byte, gsub = unicode.utf8.char, string.byte, string.gsub + local function convert_char (char) + return utf8_char(byte(char)) + end + + local function convert_line (line) + return gsub(line, ".", convert_char) + end + + callback.register("process_input_buffer", convert_line) + + local function convert_line_out (line) + local line_out = "" + for c in string.utfvalues(line) do + line_out = line_out .. string.char(c) + end + return line_out + end + + callback.register("process_output_buffer", convert_line_out) + } + \fi + + \txiusebytewiseiotrue +} + + % Helpers for encodings. % Set the catcode of characters 128 through 255 to the specified number. % @@ -8852,7 +9972,9 @@ directory should work if nowhere else does.} % @documentencoding sets the definition of non-ASCII characters % according to the specified encoding. % -\parseargdef\documentencoding{% +\def\documentencoding{\parseargusing\filenamecatcodes\documentencodingzzz} +\def\documentencodingzzz#1{% + % % Encoding being declared for the document. \def\declaredencoding{\csname #1.enc\endcsname}% % @@ -8868,35 +9990,66 @@ directory should work if nowhere else does.} \asciichardefs % \else \ifx \declaredencoding \lattwo + \iftxinativeunicodecapable + \setbytewiseio + \fi \setnonasciicharscatcode\active \lattwochardefs % \else \ifx \declaredencoding \latone + \iftxinativeunicodecapable + \setbytewiseio + \fi \setnonasciicharscatcode\active \latonechardefs % \else \ifx \declaredencoding \latnine + \iftxinativeunicodecapable + \setbytewiseio + \fi \setnonasciicharscatcode\active \latninechardefs % \else \ifx \declaredencoding \utfeight - \setnonasciicharscatcode\active - \utfeightchardefs + \iftxinativeunicodecapable + % For native Unicode handling (XeTeX and LuaTeX) + \nativeunicodechardefs + \else + % For treating UTF-8 as byte sequences (TeX, eTeX and pdfTeX) + \setnonasciicharscatcode\active + % since we already invoked \utfeightchardefs at the top level + % (below), do not re-invoke it, otherwise our check for duplicated + % definitions gets triggered. Making non-ascii chars active is + % sufficient. + \fi % \else - \message{Unknown document encoding #1, ignoring.}% + \message{Ignoring unknown document encoding: #1.}% % \fi % utfeight \fi % latnine \fi % latone \fi % lattwo \fi % ascii + % + \ifx\XeTeXrevision\thisisundefined + \else + \ifx \declaredencoding \utfeight + \else + \ifx \declaredencoding \ascii + \else + \message{Warning: XeTeX with non-UTF-8 encodings cannot handle % + non-ASCII characters in auxiliary files.}% + \fi + \fi + \fi } +% emacs-page % A message to be logged when using a character that isn't available % the default font encoding (OT1). % -\def\missingcharmsg#1{\message{Character missing in OT1 encoding: #1.}} +\def\missingcharmsg#1{\message{Character missing, sorry: #1.}} % Take account of \c (plain) vs. \, (Texinfo) difference. \def\cedilla#1{\ifx\c\ptexc\c{#1}\else\,{#1}\fi} @@ -8906,111 +10059,119 @@ directory should work if nowhere else does.} % macros containing the character definitions. \setnonasciicharscatcode\active % + +\def\gdefchar#1#2{% +\gdef#1{% + \ifpassthroughchars + \string#1% + \else + #2% + \fi +}} + % Latin1 (ISO-8859-1) character definitions. \def\latonechardefs{% - \gdef^^a0{\tie} - \gdef^^a1{\exclamdown} - \gdef^^a2{\missingcharmsg{CENT SIGN}} - \gdef^^a3{{\pounds}} - \gdef^^a4{\missingcharmsg{CURRENCY SIGN}} - \gdef^^a5{\missingcharmsg{YEN SIGN}} - \gdef^^a6{\missingcharmsg{BROKEN BAR}} - \gdef^^a7{\S} - \gdef^^a8{\"{}} - \gdef^^a9{\copyright} - \gdef^^aa{\ordf} - \gdef^^ab{\guillemetleft} - \gdef^^ac{$\lnot$} - \gdef^^ad{\-} - \gdef^^ae{\registeredsymbol} - \gdef^^af{\={}} + \gdefchar^^a0{\tie} + \gdefchar^^a1{\exclamdown} + \gdefchar^^a2{{\tcfont \char162}} % cent + \gdefchar^^a3{\pounds{}} + \gdefchar^^a4{{\tcfont \char164}} % currency + \gdefchar^^a5{{\tcfont \char165}} % yen + \gdefchar^^a6{{\tcfont \char166}} % broken bar + \gdefchar^^a7{\S} + \gdefchar^^a8{\"{}} + \gdefchar^^a9{\copyright{}} + \gdefchar^^aa{\ordf} + \gdefchar^^ab{\guillemetleft{}} + \gdefchar^^ac{\ensuremath\lnot} + \gdefchar^^ad{\-} + \gdefchar^^ae{\registeredsymbol{}} + \gdefchar^^af{\={}} % - \gdef^^b0{\textdegree} - \gdef^^b1{$\pm$} - \gdef^^b2{$^2$} - \gdef^^b3{$^3$} - \gdef^^b4{\'{}} - \gdef^^b5{$\mu$} - \gdef^^b6{\P} + \gdefchar^^b0{\textdegree} + \gdefchar^^b1{$\pm$} + \gdefchar^^b2{$^2$} + \gdefchar^^b3{$^3$} + \gdefchar^^b4{\'{}} + \gdefchar^^b5{$\mu$} + \gdefchar^^b6{\P} + \gdefchar^^b7{\ensuremath\cdot} + \gdefchar^^b8{\cedilla\ } + \gdefchar^^b9{$^1$} + \gdefchar^^ba{\ordm} + \gdefchar^^bb{\guillemetright{}} + \gdefchar^^bc{$1\over4$} + \gdefchar^^bd{$1\over2$} + \gdefchar^^be{$3\over4$} + \gdefchar^^bf{\questiondown} % - \gdef^^b7{$^.$} - \gdef^^b8{\cedilla\ } - \gdef^^b9{$^1$} - \gdef^^ba{\ordm} + \gdefchar^^c0{\`A} + \gdefchar^^c1{\'A} + \gdefchar^^c2{\^A} + \gdefchar^^c3{\~A} + \gdefchar^^c4{\"A} + \gdefchar^^c5{\ringaccent A} + \gdefchar^^c6{\AE} + \gdefchar^^c7{\cedilla C} + \gdefchar^^c8{\`E} + \gdefchar^^c9{\'E} + \gdefchar^^ca{\^E} + \gdefchar^^cb{\"E} + \gdefchar^^cc{\`I} + \gdefchar^^cd{\'I} + \gdefchar^^ce{\^I} + \gdefchar^^cf{\"I} % - \gdef^^bb{\guillemetright} - \gdef^^bc{$1\over4$} - \gdef^^bd{$1\over2$} - \gdef^^be{$3\over4$} - \gdef^^bf{\questiondown} + \gdefchar^^d0{\DH} + \gdefchar^^d1{\~N} + \gdefchar^^d2{\`O} + \gdefchar^^d3{\'O} + \gdefchar^^d4{\^O} + \gdefchar^^d5{\~O} + \gdefchar^^d6{\"O} + \gdefchar^^d7{$\times$} + \gdefchar^^d8{\O} + \gdefchar^^d9{\`U} + \gdefchar^^da{\'U} + \gdefchar^^db{\^U} + \gdefchar^^dc{\"U} + \gdefchar^^dd{\'Y} + \gdefchar^^de{\TH} + \gdefchar^^df{\ss} % - \gdef^^c0{\`A} - \gdef^^c1{\'A} - \gdef^^c2{\^A} - \gdef^^c3{\~A} - \gdef^^c4{\"A} - \gdef^^c5{\ringaccent A} - \gdef^^c6{\AE} - \gdef^^c7{\cedilla C} - \gdef^^c8{\`E} - \gdef^^c9{\'E} - \gdef^^ca{\^E} - \gdef^^cb{\"E} - \gdef^^cc{\`I} - \gdef^^cd{\'I} - \gdef^^ce{\^I} - \gdef^^cf{\"I} + \gdefchar^^e0{\`a} + \gdefchar^^e1{\'a} + \gdefchar^^e2{\^a} + \gdefchar^^e3{\~a} + \gdefchar^^e4{\"a} + \gdefchar^^e5{\ringaccent a} + \gdefchar^^e6{\ae} + \gdefchar^^e7{\cedilla c} + \gdefchar^^e8{\`e} + \gdefchar^^e9{\'e} + \gdefchar^^ea{\^e} + \gdefchar^^eb{\"e} + \gdefchar^^ec{\`{\dotless i}} + \gdefchar^^ed{\'{\dotless i}} + \gdefchar^^ee{\^{\dotless i}} + \gdefchar^^ef{\"{\dotless i}} % - \gdef^^d0{\DH} - \gdef^^d1{\~N} - \gdef^^d2{\`O} - \gdef^^d3{\'O} - \gdef^^d4{\^O} - \gdef^^d5{\~O} - \gdef^^d6{\"O} - \gdef^^d7{$\times$} - \gdef^^d8{\O} - \gdef^^d9{\`U} - \gdef^^da{\'U} - \gdef^^db{\^U} - \gdef^^dc{\"U} - \gdef^^dd{\'Y} - \gdef^^de{\TH} - \gdef^^df{\ss} - % - \gdef^^e0{\`a} - \gdef^^e1{\'a} - \gdef^^e2{\^a} - \gdef^^e3{\~a} - \gdef^^e4{\"a} - \gdef^^e5{\ringaccent a} - \gdef^^e6{\ae} - \gdef^^e7{\cedilla c} - \gdef^^e8{\`e} - \gdef^^e9{\'e} - \gdef^^ea{\^e} - \gdef^^eb{\"e} - \gdef^^ec{\`{\dotless i}} - \gdef^^ed{\'{\dotless i}} - \gdef^^ee{\^{\dotless i}} - \gdef^^ef{\"{\dotless i}} - % - \gdef^^f0{\dh} - \gdef^^f1{\~n} - \gdef^^f2{\`o} - \gdef^^f3{\'o} - \gdef^^f4{\^o} - \gdef^^f5{\~o} - \gdef^^f6{\"o} - \gdef^^f7{$\div$} - \gdef^^f8{\o} - \gdef^^f9{\`u} - \gdef^^fa{\'u} - \gdef^^fb{\^u} - \gdef^^fc{\"u} - \gdef^^fd{\'y} - \gdef^^fe{\th} - \gdef^^ff{\"y} + \gdefchar^^f0{\dh} + \gdefchar^^f1{\~n} + \gdefchar^^f2{\`o} + \gdefchar^^f3{\'o} + \gdefchar^^f4{\^o} + \gdefchar^^f5{\~o} + \gdefchar^^f6{\"o} + \gdefchar^^f7{$\div$} + \gdefchar^^f8{\o} + \gdefchar^^f9{\`u} + \gdefchar^^fa{\'u} + \gdefchar^^fb{\^u} + \gdefchar^^fc{\"u} + \gdefchar^^fd{\'y} + \gdefchar^^fe{\th} + \gdefchar^^ff{\"y} } % Latin9 (ISO-8859-15) encoding character definitions. @@ -9018,119 +10179,119 @@ directory should work if nowhere else does.} % Encoding is almost identical to Latin1. \latonechardefs % - \gdef^^a4{\euro} - \gdef^^a6{\v S} - \gdef^^a8{\v s} - \gdef^^b4{\v Z} - \gdef^^b8{\v z} - \gdef^^bc{\OE} - \gdef^^bd{\oe} - \gdef^^be{\"Y} + \gdefchar^^a4{\euro{}} + \gdefchar^^a6{\v S} + \gdefchar^^a8{\v s} + \gdefchar^^b4{\v Z} + \gdefchar^^b8{\v z} + \gdefchar^^bc{\OE} + \gdefchar^^bd{\oe} + \gdefchar^^be{\"Y} } % Latin2 (ISO-8859-2) character definitions. \def\lattwochardefs{% - \gdef^^a0{\tie} - \gdef^^a1{\ogonek{A}} - \gdef^^a2{\u{}} - \gdef^^a3{\L} - \gdef^^a4{\missingcharmsg{CURRENCY SIGN}} - \gdef^^a5{\v L} - \gdef^^a6{\'S} - \gdef^^a7{\S} - \gdef^^a8{\"{}} - \gdef^^a9{\v S} - \gdef^^aa{\cedilla S} - \gdef^^ab{\v T} - \gdef^^ac{\'Z} - \gdef^^ad{\-} - \gdef^^ae{\v Z} - \gdef^^af{\dotaccent Z} + \gdefchar^^a0{\tie} + \gdefchar^^a1{\ogonek{A}} + \gdefchar^^a2{\u{}} + \gdefchar^^a3{\L} + \gdefchar^^a4{\missingcharmsg{CURRENCY SIGN}} + \gdefchar^^a5{\v L} + \gdefchar^^a6{\'S} + \gdefchar^^a7{\S} + \gdefchar^^a8{\"{}} + \gdefchar^^a9{\v S} + \gdefchar^^aa{\cedilla S} + \gdefchar^^ab{\v T} + \gdefchar^^ac{\'Z} + \gdefchar^^ad{\-} + \gdefchar^^ae{\v Z} + \gdefchar^^af{\dotaccent Z} % - \gdef^^b0{\textdegree} - \gdef^^b1{\ogonek{a}} - \gdef^^b2{\ogonek{ }} - \gdef^^b3{\l} - \gdef^^b4{\'{}} - \gdef^^b5{\v l} - \gdef^^b6{\'s} - \gdef^^b7{\v{}} - \gdef^^b8{\cedilla\ } - \gdef^^b9{\v s} - \gdef^^ba{\cedilla s} - \gdef^^bb{\v t} - \gdef^^bc{\'z} - \gdef^^bd{\H{}} - \gdef^^be{\v z} - \gdef^^bf{\dotaccent z} + \gdefchar^^b0{\textdegree{}} + \gdefchar^^b1{\ogonek{a}} + \gdefchar^^b2{\ogonek{ }} + \gdefchar^^b3{\l} + \gdefchar^^b4{\'{}} + \gdefchar^^b5{\v l} + \gdefchar^^b6{\'s} + \gdefchar^^b7{\v{}} + \gdefchar^^b8{\cedilla\ } + \gdefchar^^b9{\v s} + \gdefchar^^ba{\cedilla s} + \gdefchar^^bb{\v t} + \gdefchar^^bc{\'z} + \gdefchar^^bd{\H{}} + \gdefchar^^be{\v z} + \gdefchar^^bf{\dotaccent z} % - \gdef^^c0{\'R} - \gdef^^c1{\'A} - \gdef^^c2{\^A} - \gdef^^c3{\u A} - \gdef^^c4{\"A} - \gdef^^c5{\'L} - \gdef^^c6{\'C} - \gdef^^c7{\cedilla C} - \gdef^^c8{\v C} - \gdef^^c9{\'E} - \gdef^^ca{\ogonek{E}} - \gdef^^cb{\"E} - \gdef^^cc{\v E} - \gdef^^cd{\'I} - \gdef^^ce{\^I} - \gdef^^cf{\v D} + \gdefchar^^c0{\'R} + \gdefchar^^c1{\'A} + \gdefchar^^c2{\^A} + \gdefchar^^c3{\u A} + \gdefchar^^c4{\"A} + \gdefchar^^c5{\'L} + \gdefchar^^c6{\'C} + \gdefchar^^c7{\cedilla C} + \gdefchar^^c8{\v C} + \gdefchar^^c9{\'E} + \gdefchar^^ca{\ogonek{E}} + \gdefchar^^cb{\"E} + \gdefchar^^cc{\v E} + \gdefchar^^cd{\'I} + \gdefchar^^ce{\^I} + \gdefchar^^cf{\v D} % - \gdef^^d0{\DH} - \gdef^^d1{\'N} - \gdef^^d2{\v N} - \gdef^^d3{\'O} - \gdef^^d4{\^O} - \gdef^^d5{\H O} - \gdef^^d6{\"O} - \gdef^^d7{$\times$} - \gdef^^d8{\v R} - \gdef^^d9{\ringaccent U} - \gdef^^da{\'U} - \gdef^^db{\H U} - \gdef^^dc{\"U} - \gdef^^dd{\'Y} - \gdef^^de{\cedilla T} - \gdef^^df{\ss} + \gdefchar^^d0{\DH} + \gdefchar^^d1{\'N} + \gdefchar^^d2{\v N} + \gdefchar^^d3{\'O} + \gdefchar^^d4{\^O} + \gdefchar^^d5{\H O} + \gdefchar^^d6{\"O} + \gdefchar^^d7{$\times$} + \gdefchar^^d8{\v R} + \gdefchar^^d9{\ringaccent U} + \gdefchar^^da{\'U} + \gdefchar^^db{\H U} + \gdefchar^^dc{\"U} + \gdefchar^^dd{\'Y} + \gdefchar^^de{\cedilla T} + \gdefchar^^df{\ss} % - \gdef^^e0{\'r} - \gdef^^e1{\'a} - \gdef^^e2{\^a} - \gdef^^e3{\u a} - \gdef^^e4{\"a} - \gdef^^e5{\'l} - \gdef^^e6{\'c} - \gdef^^e7{\cedilla c} - \gdef^^e8{\v c} - \gdef^^e9{\'e} - \gdef^^ea{\ogonek{e}} - \gdef^^eb{\"e} - \gdef^^ec{\v e} - \gdef^^ed{\'{\dotless{i}}} - \gdef^^ee{\^{\dotless{i}}} - \gdef^^ef{\v d} + \gdefchar^^e0{\'r} + \gdefchar^^e1{\'a} + \gdefchar^^e2{\^a} + \gdefchar^^e3{\u a} + \gdefchar^^e4{\"a} + \gdefchar^^e5{\'l} + \gdefchar^^e6{\'c} + \gdefchar^^e7{\cedilla c} + \gdefchar^^e8{\v c} + \gdefchar^^e9{\'e} + \gdefchar^^ea{\ogonek{e}} + \gdefchar^^eb{\"e} + \gdefchar^^ec{\v e} + \gdefchar^^ed{\'{\dotless{i}}} + \gdefchar^^ee{\^{\dotless{i}}} + \gdefchar^^ef{\v d} % - \gdef^^f0{\dh} - \gdef^^f1{\'n} - \gdef^^f2{\v n} - \gdef^^f3{\'o} - \gdef^^f4{\^o} - \gdef^^f5{\H o} - \gdef^^f6{\"o} - \gdef^^f7{$\div$} - \gdef^^f8{\v r} - \gdef^^f9{\ringaccent u} - \gdef^^fa{\'u} - \gdef^^fb{\H u} - \gdef^^fc{\"u} - \gdef^^fd{\'y} - \gdef^^fe{\cedilla t} - \gdef^^ff{\dotaccent{}} + \gdefchar^^f0{\dh} + \gdefchar^^f1{\'n} + \gdefchar^^f2{\v n} + \gdefchar^^f3{\'o} + \gdefchar^^f4{\^o} + \gdefchar^^f5{\H o} + \gdefchar^^f6{\"o} + \gdefchar^^f7{$\div$} + \gdefchar^^f8{\v r} + \gdefchar^^f9{\ringaccent u} + \gdefchar^^fa{\'u} + \gdefchar^^fb{\H u} + \gdefchar^^fc{\"u} + \gdefchar^^fd{\'y} + \gdefchar^^fe{\cedilla t} + \gdefchar^^ff{\dotaccent{}} } % UTF-8 character definitions. @@ -9160,38 +10321,94 @@ directory should work if nowhere else does.} \fi } +% Give non-ASCII bytes the active definitions for processing UTF-8 sequences \begingroup \catcode`\~13 + \catcode`\$12 \catcode`\"12 + % Loop from \countUTFx to \countUTFy, performing \UTFviiiTmp + % substituting ~ and $ with a character token of that value. \def\UTFviiiLoop{% \global\catcode\countUTFx\active \uccode`\~\countUTFx + \uccode`\$\countUTFx \uppercase\expandafter{\UTFviiiTmp}% \advance\countUTFx by 1 \ifnum\countUTFx < \countUTFy \expandafter\UTFviiiLoop \fi} + % For bytes other than the first in a UTF-8 sequence. Not expected to + % be expanded except when writing to auxiliary files. + \countUTFx = "80 + \countUTFy = "C2 + \def\UTFviiiTmp{% + \gdef~{% + \ifpassthroughchars $\fi}}% + \UTFviiiLoop + \countUTFx = "C2 \countUTFy = "E0 \def\UTFviiiTmp{% - \xdef~{\noexpand\UTFviiiTwoOctets\string~}} + \gdef~{% + \ifpassthroughchars $% + \else\expandafter\UTFviiiTwoOctets\expandafter$\fi}}% \UTFviiiLoop \countUTFx = "E0 \countUTFy = "F0 \def\UTFviiiTmp{% - \xdef~{\noexpand\UTFviiiThreeOctets\string~}} + \gdef~{% + \ifpassthroughchars $% + \else\expandafter\UTFviiiThreeOctets\expandafter$\fi}}% \UTFviiiLoop \countUTFx = "F0 \countUTFy = "F4 \def\UTFviiiTmp{% - \xdef~{\noexpand\UTFviiiFourOctets\string~}} + \gdef~{% + \ifpassthroughchars $% + \else\expandafter\UTFviiiFourOctets\expandafter$\fi + }}% \UTFviiiLoop \endgroup +\def\globallet{\global\let} % save some \expandafter's below + +% @U{xxxx} to produce U+xxxx, if we support it. +\def\U#1{% + \expandafter\ifx\csname uni:#1\endcsname \relax + \iftxinativeunicodecapable + % All Unicode characters can be used if native Unicode handling is + % active. However, if the font does not have the glyph, + % letters are missing. + \begingroup + \uccode`\.="#1\relax + \uppercase{.} + \endgroup + \else + \errhelp = \EMsimple + \errmessage{Unicode character U+#1 not supported, sorry}% + \fi + \else + \csname uni:#1\endcsname + \fi +} + +% These macros are used here to construct the name of a control +% sequence to be defined. +\def\UTFviiiTwoOctetsName#1#2{% + \csname u8:#1\string #2\endcsname}% +\def\UTFviiiThreeOctetsName#1#2#3{% + \csname u8:#1\string #2\string #3\endcsname}% +\def\UTFviiiFourOctetsName#1#2#3#4{% + \csname u8:#1\string #2\string #3\string #4\endcsname}% + +% For UTF-8 byte sequences (TeX, e-TeX and pdfTeX), +% provide a definition macro to replace a Unicode character; +% this gets used by the @U command +% \begingroup \catcode`\"=12 \catcode`\<=12 @@ -9200,459 +10417,839 @@ directory should work if nowhere else does.} \catcode`\;=12 \catcode`\!=12 \catcode`\~=13 - - \gdef\DeclareUnicodeCharacter#1#2{% + \gdef\DeclareUnicodeCharacterUTFviii#1#2{% \countUTFz = "#1\relax - %\wlog{\space\space defining Unicode char U+#1 (decimal \the\countUTFz)}% \begingroup \parseXMLCharref - \def\UTFviiiTwoOctets##1##2{% - \csname u8:##1\string ##2\endcsname}% - \def\UTFviiiThreeOctets##1##2##3{% - \csname u8:##1\string ##2\string ##3\endcsname}% - \def\UTFviiiFourOctets##1##2##3##4{% - \csname u8:##1\string ##2\string ##3\string ##4\endcsname}% - \expandafter\expandafter\expandafter\expandafter - \expandafter\expandafter\expandafter - \gdef\UTFviiiTmp{#2}% + + % Give \u8:... its definition. The sequence of seven \expandafter's + % expands after the \gdef three times, e.g. + % + % 1. \UTFviiTwoOctetsName B1 B2 + % 2. \csname u8:B1 \string B2 \endcsname + % 3. \u8: B1 B2 (a single control sequence token) + % + \expandafter\expandafter + \expandafter\expandafter + \expandafter\expandafter + \expandafter\gdef \UTFviiiTmp{#2}% + % + \expandafter\ifx\csname uni:#1\endcsname \relax \else + \message{Internal error, already defined: #1}% + \fi + % + % define an additional control sequence for this code point. + \expandafter\globallet\csname uni:#1\endcsname \UTFviiiTmp \endgroup} - + % + % Given the value in \countUTFz as a Unicode code point, set \UTFviiiTmp + % to the corresponding UTF-8 sequence. \gdef\parseXMLCharref{% \ifnum\countUTFz < "A0\relax \errhelp = \EMsimple \errmessage{Cannot define Unicode char value < 00A0}% \else\ifnum\countUTFz < "800\relax \parseUTFviiiA,% - \parseUTFviiiB C\UTFviiiTwoOctets.,% + \parseUTFviiiB C\UTFviiiTwoOctetsName.,% \else\ifnum\countUTFz < "10000\relax \parseUTFviiiA;% \parseUTFviiiA,% - \parseUTFviiiB E\UTFviiiThreeOctets.{,;}% + \parseUTFviiiB E\UTFviiiThreeOctetsName.{,;}% \else \parseUTFviiiA;% \parseUTFviiiA,% \parseUTFviiiA!% - \parseUTFviiiB F\UTFviiiFourOctets.{!,;}% + \parseUTFviiiB F\UTFviiiFourOctetsName.{!,;}% \fi\fi\fi } + % Extract a byte from the end of the UTF-8 representation of \countUTFx. + % It must be a non-initial byte in the sequence. + % Change \uccode of #1 for it to be used in \parseUTFviiiB as one + % of the bytes. \gdef\parseUTFviiiA#1{% \countUTFx = \countUTFz \divide\countUTFz by 64 - \countUTFy = \countUTFz + \countUTFy = \countUTFz % Save to be the future value of \countUTFz. \multiply\countUTFz by 64 + + % \countUTFz is now \countUTFx with the last 5 bits cleared. Subtract + % in order to get the last five bits. \advance\countUTFx by -\countUTFz + + % Convert this to the byte in the UTF-8 sequence. \advance\countUTFx by 128 \uccode `#1\countUTFx \countUTFz = \countUTFy} + % Used to put a UTF-8 byte sequence into \UTFviiiTmp + % #1 is the increment for \countUTFz to yield a the first byte of the UTF-8 + % sequence. + % #2 is one of the \UTFviii*OctetsName macros. + % #3 is always a full stop (.) + % #4 is a template for the other bytes in the sequence. The values for these + % bytes is substituted in here with \uppercase using the \uccode's. \gdef\parseUTFviiiB#1#2#3#4{% \advance\countUTFz by "#10\relax \uccode `#3\countUTFz \uppercase{\gdef\UTFviiiTmp{#2#3#4}}} \endgroup +% For native Unicode handling (XeTeX and LuaTeX), +% provide a definition macro that sets a catcode to `other' non-globally +% +\def\DeclareUnicodeCharacterNativeOther#1#2{% + \catcode"#1=\other +} + +% https://en.wikipedia.org/wiki/Plane_(Unicode)#Basic_M +% U+0000..U+007F = https://en.wikipedia.org/wiki/Basic_Latin_(Unicode_block) +% U+0080..U+00FF = https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block) +% U+0100..U+017F = https://en.wikipedia.org/wiki/Latin_Extended-A +% U+0180..U+024F = https://en.wikipedia.org/wiki/Latin_Extended-B +% +% Many of our renditions are less than wonderful, and all the missing +% characters are available somewhere. Loading the necessary fonts +% awaits user request. We can't truly support Unicode without +% reimplementing everything that's been done in LaTeX for many years, +% plus probably using luatex or xetex, and who knows what else. +% We won't be doing that here in this simple file. But we can try to at +% least make most of the characters not bomb out. +% +\def\unicodechardefs{% + \DeclareUnicodeCharacter{00A0}{\tie}% + \DeclareUnicodeCharacter{00A1}{\exclamdown}% + \DeclareUnicodeCharacter{00A2}{{\tcfont \char162}}% 0242=cent + \DeclareUnicodeCharacter{00A3}{\pounds{}}% + \DeclareUnicodeCharacter{00A4}{{\tcfont \char164}}% 0244=currency + \DeclareUnicodeCharacter{00A5}{{\tcfont \char165}}% 0245=yen + \DeclareUnicodeCharacter{00A6}{{\tcfont \char166}}% 0246=brokenbar + \DeclareUnicodeCharacter{00A7}{\S}% + \DeclareUnicodeCharacter{00A8}{\"{ }}% + \DeclareUnicodeCharacter{00A9}{\copyright{}}% + \DeclareUnicodeCharacter{00AA}{\ordf}% + \DeclareUnicodeCharacter{00AB}{\guillemetleft{}}% + \DeclareUnicodeCharacter{00AC}{\ensuremath\lnot}% + \DeclareUnicodeCharacter{00AD}{\-}% + \DeclareUnicodeCharacter{00AE}{\registeredsymbol{}}% + \DeclareUnicodeCharacter{00AF}{\={ }}% + % + \DeclareUnicodeCharacter{00B0}{\ringaccent{ }}% + \DeclareUnicodeCharacter{00B1}{\ensuremath\pm}% + \DeclareUnicodeCharacter{00B2}{$^2$}% + \DeclareUnicodeCharacter{00B3}{$^3$}% + \DeclareUnicodeCharacter{00B4}{\'{ }}% + \DeclareUnicodeCharacter{00B5}{$\mu$}% + \DeclareUnicodeCharacter{00B6}{\P}% + \DeclareUnicodeCharacter{00B7}{\ensuremath\cdot}% + \DeclareUnicodeCharacter{00B8}{\cedilla{ }}% + \DeclareUnicodeCharacter{00B9}{$^1$}% + \DeclareUnicodeCharacter{00BA}{\ordm}% + \DeclareUnicodeCharacter{00BB}{\guillemetright{}}% + \DeclareUnicodeCharacter{00BC}{$1\over4$}% + \DeclareUnicodeCharacter{00BD}{$1\over2$}% + \DeclareUnicodeCharacter{00BE}{$3\over4$}% + \DeclareUnicodeCharacter{00BF}{\questiondown}% + % + \DeclareUnicodeCharacter{00C0}{\`A}% + \DeclareUnicodeCharacter{00C1}{\'A}% + \DeclareUnicodeCharacter{00C2}{\^A}% + \DeclareUnicodeCharacter{00C3}{\~A}% + \DeclareUnicodeCharacter{00C4}{\"A}% + \DeclareUnicodeCharacter{00C5}{\AA}% + \DeclareUnicodeCharacter{00C6}{\AE}% + \DeclareUnicodeCharacter{00C7}{\cedilla{C}}% + \DeclareUnicodeCharacter{00C8}{\`E}% + \DeclareUnicodeCharacter{00C9}{\'E}% + \DeclareUnicodeCharacter{00CA}{\^E}% + \DeclareUnicodeCharacter{00CB}{\"E}% + \DeclareUnicodeCharacter{00CC}{\`I}% + \DeclareUnicodeCharacter{00CD}{\'I}% + \DeclareUnicodeCharacter{00CE}{\^I}% + \DeclareUnicodeCharacter{00CF}{\"I}% + % + \DeclareUnicodeCharacter{00D0}{\DH}% + \DeclareUnicodeCharacter{00D1}{\~N}% + \DeclareUnicodeCharacter{00D2}{\`O}% + \DeclareUnicodeCharacter{00D3}{\'O}% + \DeclareUnicodeCharacter{00D4}{\^O}% + \DeclareUnicodeCharacter{00D5}{\~O}% + \DeclareUnicodeCharacter{00D6}{\"O}% + \DeclareUnicodeCharacter{00D7}{\ensuremath\times}% + \DeclareUnicodeCharacter{00D8}{\O}% + \DeclareUnicodeCharacter{00D9}{\`U}% + \DeclareUnicodeCharacter{00DA}{\'U}% + \DeclareUnicodeCharacter{00DB}{\^U}% + \DeclareUnicodeCharacter{00DC}{\"U}% + \DeclareUnicodeCharacter{00DD}{\'Y}% + \DeclareUnicodeCharacter{00DE}{\TH}% + \DeclareUnicodeCharacter{00DF}{\ss}% + % + \DeclareUnicodeCharacter{00E0}{\`a}% + \DeclareUnicodeCharacter{00E1}{\'a}% + \DeclareUnicodeCharacter{00E2}{\^a}% + \DeclareUnicodeCharacter{00E3}{\~a}% + \DeclareUnicodeCharacter{00E4}{\"a}% + \DeclareUnicodeCharacter{00E5}{\aa}% + \DeclareUnicodeCharacter{00E6}{\ae}% + \DeclareUnicodeCharacter{00E7}{\cedilla{c}}% + \DeclareUnicodeCharacter{00E8}{\`e}% + \DeclareUnicodeCharacter{00E9}{\'e}% + \DeclareUnicodeCharacter{00EA}{\^e}% + \DeclareUnicodeCharacter{00EB}{\"e}% + \DeclareUnicodeCharacter{00EC}{\`{\dotless{i}}}% + \DeclareUnicodeCharacter{00ED}{\'{\dotless{i}}}% + \DeclareUnicodeCharacter{00EE}{\^{\dotless{i}}}% + \DeclareUnicodeCharacter{00EF}{\"{\dotless{i}}}% + % + \DeclareUnicodeCharacter{00F0}{\dh}% + \DeclareUnicodeCharacter{00F1}{\~n}% + \DeclareUnicodeCharacter{00F2}{\`o}% + \DeclareUnicodeCharacter{00F3}{\'o}% + \DeclareUnicodeCharacter{00F4}{\^o}% + \DeclareUnicodeCharacter{00F5}{\~o}% + \DeclareUnicodeCharacter{00F6}{\"o}% + \DeclareUnicodeCharacter{00F7}{\ensuremath\div}% + \DeclareUnicodeCharacter{00F8}{\o}% + \DeclareUnicodeCharacter{00F9}{\`u}% + \DeclareUnicodeCharacter{00FA}{\'u}% + \DeclareUnicodeCharacter{00FB}{\^u}% + \DeclareUnicodeCharacter{00FC}{\"u}% + \DeclareUnicodeCharacter{00FD}{\'y}% + \DeclareUnicodeCharacter{00FE}{\th}% + \DeclareUnicodeCharacter{00FF}{\"y}% + % + \DeclareUnicodeCharacter{0100}{\=A}% + \DeclareUnicodeCharacter{0101}{\=a}% + \DeclareUnicodeCharacter{0102}{\u{A}}% + \DeclareUnicodeCharacter{0103}{\u{a}}% + \DeclareUnicodeCharacter{0104}{\ogonek{A}}% + \DeclareUnicodeCharacter{0105}{\ogonek{a}}% + \DeclareUnicodeCharacter{0106}{\'C}% + \DeclareUnicodeCharacter{0107}{\'c}% + \DeclareUnicodeCharacter{0108}{\^C}% + \DeclareUnicodeCharacter{0109}{\^c}% + \DeclareUnicodeCharacter{010A}{\dotaccent{C}}% + \DeclareUnicodeCharacter{010B}{\dotaccent{c}}% + \DeclareUnicodeCharacter{010C}{\v{C}}% + \DeclareUnicodeCharacter{010D}{\v{c}}% + \DeclareUnicodeCharacter{010E}{\v{D}}% + \DeclareUnicodeCharacter{010F}{d'}% + % + \DeclareUnicodeCharacter{0110}{\DH}% + \DeclareUnicodeCharacter{0111}{\dh}% + \DeclareUnicodeCharacter{0112}{\=E}% + \DeclareUnicodeCharacter{0113}{\=e}% + \DeclareUnicodeCharacter{0114}{\u{E}}% + \DeclareUnicodeCharacter{0115}{\u{e}}% + \DeclareUnicodeCharacter{0116}{\dotaccent{E}}% + \DeclareUnicodeCharacter{0117}{\dotaccent{e}}% + \DeclareUnicodeCharacter{0118}{\ogonek{E}}% + \DeclareUnicodeCharacter{0119}{\ogonek{e}}% + \DeclareUnicodeCharacter{011A}{\v{E}}% + \DeclareUnicodeCharacter{011B}{\v{e}}% + \DeclareUnicodeCharacter{011C}{\^G}% + \DeclareUnicodeCharacter{011D}{\^g}% + \DeclareUnicodeCharacter{011E}{\u{G}}% + \DeclareUnicodeCharacter{011F}{\u{g}}% + % + \DeclareUnicodeCharacter{0120}{\dotaccent{G}}% + \DeclareUnicodeCharacter{0121}{\dotaccent{g}}% + \DeclareUnicodeCharacter{0122}{\cedilla{G}}% + \DeclareUnicodeCharacter{0123}{\cedilla{g}}% + \DeclareUnicodeCharacter{0124}{\^H}% + \DeclareUnicodeCharacter{0125}{\^h}% + \DeclareUnicodeCharacter{0126}{\missingcharmsg{H WITH STROKE}}% + \DeclareUnicodeCharacter{0127}{\missingcharmsg{h WITH STROKE}}% + \DeclareUnicodeCharacter{0128}{\~I}% + \DeclareUnicodeCharacter{0129}{\~{\dotless{i}}}% + \DeclareUnicodeCharacter{012A}{\=I}% + \DeclareUnicodeCharacter{012B}{\={\dotless{i}}}% + \DeclareUnicodeCharacter{012C}{\u{I}}% + \DeclareUnicodeCharacter{012D}{\u{\dotless{i}}}% + \DeclareUnicodeCharacter{012E}{\ogonek{I}}% + \DeclareUnicodeCharacter{012F}{\ogonek{i}}% + % + \DeclareUnicodeCharacter{0130}{\dotaccent{I}}% + \DeclareUnicodeCharacter{0131}{\dotless{i}}% + \DeclareUnicodeCharacter{0132}{IJ}% + \DeclareUnicodeCharacter{0133}{ij}% + \DeclareUnicodeCharacter{0134}{\^J}% + \DeclareUnicodeCharacter{0135}{\^{\dotless{j}}}% + \DeclareUnicodeCharacter{0136}{\cedilla{K}}% + \DeclareUnicodeCharacter{0137}{\cedilla{k}}% + \DeclareUnicodeCharacter{0138}{\ensuremath\kappa}% + \DeclareUnicodeCharacter{0139}{\'L}% + \DeclareUnicodeCharacter{013A}{\'l}% + \DeclareUnicodeCharacter{013B}{\cedilla{L}}% + \DeclareUnicodeCharacter{013C}{\cedilla{l}}% + \DeclareUnicodeCharacter{013D}{L'}% should kern + \DeclareUnicodeCharacter{013E}{l'}% should kern + \DeclareUnicodeCharacter{013F}{L\U{00B7}}% + % + \DeclareUnicodeCharacter{0140}{l\U{00B7}}% + \DeclareUnicodeCharacter{0141}{\L}% + \DeclareUnicodeCharacter{0142}{\l}% + \DeclareUnicodeCharacter{0143}{\'N}% + \DeclareUnicodeCharacter{0144}{\'n}% + \DeclareUnicodeCharacter{0145}{\cedilla{N}}% + \DeclareUnicodeCharacter{0146}{\cedilla{n}}% + \DeclareUnicodeCharacter{0147}{\v{N}}% + \DeclareUnicodeCharacter{0148}{\v{n}}% + \DeclareUnicodeCharacter{0149}{'n}% + \DeclareUnicodeCharacter{014A}{\missingcharmsg{ENG}}% + \DeclareUnicodeCharacter{014B}{\missingcharmsg{eng}}% + \DeclareUnicodeCharacter{014C}{\=O}% + \DeclareUnicodeCharacter{014D}{\=o}% + \DeclareUnicodeCharacter{014E}{\u{O}}% + \DeclareUnicodeCharacter{014F}{\u{o}}% + % + \DeclareUnicodeCharacter{0150}{\H{O}}% + \DeclareUnicodeCharacter{0151}{\H{o}}% + \DeclareUnicodeCharacter{0152}{\OE}% + \DeclareUnicodeCharacter{0153}{\oe}% + \DeclareUnicodeCharacter{0154}{\'R}% + \DeclareUnicodeCharacter{0155}{\'r}% + \DeclareUnicodeCharacter{0156}{\cedilla{R}}% + \DeclareUnicodeCharacter{0157}{\cedilla{r}}% + \DeclareUnicodeCharacter{0158}{\v{R}}% + \DeclareUnicodeCharacter{0159}{\v{r}}% + \DeclareUnicodeCharacter{015A}{\'S}% + \DeclareUnicodeCharacter{015B}{\'s}% + \DeclareUnicodeCharacter{015C}{\^S}% + \DeclareUnicodeCharacter{015D}{\^s}% + \DeclareUnicodeCharacter{015E}{\cedilla{S}}% + \DeclareUnicodeCharacter{015F}{\cedilla{s}}% + % + \DeclareUnicodeCharacter{0160}{\v{S}}% + \DeclareUnicodeCharacter{0161}{\v{s}}% + \DeclareUnicodeCharacter{0162}{\cedilla{T}}% + \DeclareUnicodeCharacter{0163}{\cedilla{t}}% + \DeclareUnicodeCharacter{0164}{\v{T}}% + \DeclareUnicodeCharacter{0165}{\v{t}}% + \DeclareUnicodeCharacter{0166}{\missingcharmsg{H WITH STROKE}}% + \DeclareUnicodeCharacter{0167}{\missingcharmsg{h WITH STROKE}}% + \DeclareUnicodeCharacter{0168}{\~U}% + \DeclareUnicodeCharacter{0169}{\~u}% + \DeclareUnicodeCharacter{016A}{\=U}% + \DeclareUnicodeCharacter{016B}{\=u}% + \DeclareUnicodeCharacter{016C}{\u{U}}% + \DeclareUnicodeCharacter{016D}{\u{u}}% + \DeclareUnicodeCharacter{016E}{\ringaccent{U}}% + \DeclareUnicodeCharacter{016F}{\ringaccent{u}}% + % + \DeclareUnicodeCharacter{0170}{\H{U}}% + \DeclareUnicodeCharacter{0171}{\H{u}}% + \DeclareUnicodeCharacter{0172}{\ogonek{U}}% + \DeclareUnicodeCharacter{0173}{\ogonek{u}}% + \DeclareUnicodeCharacter{0174}{\^W}% + \DeclareUnicodeCharacter{0175}{\^w}% + \DeclareUnicodeCharacter{0176}{\^Y}% + \DeclareUnicodeCharacter{0177}{\^y}% + \DeclareUnicodeCharacter{0178}{\"Y}% + \DeclareUnicodeCharacter{0179}{\'Z}% + \DeclareUnicodeCharacter{017A}{\'z}% + \DeclareUnicodeCharacter{017B}{\dotaccent{Z}}% + \DeclareUnicodeCharacter{017C}{\dotaccent{z}}% + \DeclareUnicodeCharacter{017D}{\v{Z}}% + \DeclareUnicodeCharacter{017E}{\v{z}}% + \DeclareUnicodeCharacter{017F}{\missingcharmsg{LONG S}}% + % + \DeclareUnicodeCharacter{01C4}{D\v{Z}}% + \DeclareUnicodeCharacter{01C5}{D\v{z}}% + \DeclareUnicodeCharacter{01C6}{d\v{z}}% + \DeclareUnicodeCharacter{01C7}{LJ}% + \DeclareUnicodeCharacter{01C8}{Lj}% + \DeclareUnicodeCharacter{01C9}{lj}% + \DeclareUnicodeCharacter{01CA}{NJ}% + \DeclareUnicodeCharacter{01CB}{Nj}% + \DeclareUnicodeCharacter{01CC}{nj}% + \DeclareUnicodeCharacter{01CD}{\v{A}}% + \DeclareUnicodeCharacter{01CE}{\v{a}}% + \DeclareUnicodeCharacter{01CF}{\v{I}}% + % + \DeclareUnicodeCharacter{01D0}{\v{\dotless{i}}}% + \DeclareUnicodeCharacter{01D1}{\v{O}}% + \DeclareUnicodeCharacter{01D2}{\v{o}}% + \DeclareUnicodeCharacter{01D3}{\v{U}}% + \DeclareUnicodeCharacter{01D4}{\v{u}}% + % + \DeclareUnicodeCharacter{01E2}{\={\AE}}% + \DeclareUnicodeCharacter{01E3}{\={\ae}}% + \DeclareUnicodeCharacter{01E6}{\v{G}}% + \DeclareUnicodeCharacter{01E7}{\v{g}}% + \DeclareUnicodeCharacter{01E8}{\v{K}}% + \DeclareUnicodeCharacter{01E9}{\v{k}}% + % + \DeclareUnicodeCharacter{01F0}{\v{\dotless{j}}}% + \DeclareUnicodeCharacter{01F1}{DZ}% + \DeclareUnicodeCharacter{01F2}{Dz}% + \DeclareUnicodeCharacter{01F3}{dz}% + \DeclareUnicodeCharacter{01F4}{\'G}% + \DeclareUnicodeCharacter{01F5}{\'g}% + \DeclareUnicodeCharacter{01F8}{\`N}% + \DeclareUnicodeCharacter{01F9}{\`n}% + \DeclareUnicodeCharacter{01FC}{\'{\AE}}% + \DeclareUnicodeCharacter{01FD}{\'{\ae}}% + \DeclareUnicodeCharacter{01FE}{\'{\O}}% + \DeclareUnicodeCharacter{01FF}{\'{\o}}% + % + \DeclareUnicodeCharacter{021E}{\v{H}}% + \DeclareUnicodeCharacter{021F}{\v{h}}% + % + \DeclareUnicodeCharacter{0226}{\dotaccent{A}}% + \DeclareUnicodeCharacter{0227}{\dotaccent{a}}% + \DeclareUnicodeCharacter{0228}{\cedilla{E}}% + \DeclareUnicodeCharacter{0229}{\cedilla{e}}% + \DeclareUnicodeCharacter{022E}{\dotaccent{O}}% + \DeclareUnicodeCharacter{022F}{\dotaccent{o}}% + % + \DeclareUnicodeCharacter{0232}{\=Y}% + \DeclareUnicodeCharacter{0233}{\=y}% + \DeclareUnicodeCharacter{0237}{\dotless{j}}% + % + \DeclareUnicodeCharacter{02DB}{\ogonek{ }}% + % + % Greek letters upper case + \DeclareUnicodeCharacter{0391}{{\it A}}% + \DeclareUnicodeCharacter{0392}{{\it B}}% + \DeclareUnicodeCharacter{0393}{\ensuremath{\mit\Gamma}}% + \DeclareUnicodeCharacter{0394}{\ensuremath{\mit\Delta}}% + \DeclareUnicodeCharacter{0395}{{\it E}}% + \DeclareUnicodeCharacter{0396}{{\it Z}}% + \DeclareUnicodeCharacter{0397}{{\it H}}% + \DeclareUnicodeCharacter{0398}{\ensuremath{\mit\Theta}}% + \DeclareUnicodeCharacter{0399}{{\it I}}% + \DeclareUnicodeCharacter{039A}{{\it K}}% + \DeclareUnicodeCharacter{039B}{\ensuremath{\mit\Lambda}}% + \DeclareUnicodeCharacter{039C}{{\it M}}% + \DeclareUnicodeCharacter{039D}{{\it N}}% + \DeclareUnicodeCharacter{039E}{\ensuremath{\mit\Xi}}% + \DeclareUnicodeCharacter{039F}{{\it O}}% + \DeclareUnicodeCharacter{03A0}{\ensuremath{\mit\Pi}}% + \DeclareUnicodeCharacter{03A1}{{\it P}}% + %\DeclareUnicodeCharacter{03A2}{} % none - corresponds to final sigma + \DeclareUnicodeCharacter{03A3}{\ensuremath{\mit\Sigma}}% + \DeclareUnicodeCharacter{03A4}{{\it T}}% + \DeclareUnicodeCharacter{03A5}{\ensuremath{\mit\Upsilon}}% + \DeclareUnicodeCharacter{03A6}{\ensuremath{\mit\Phi}}% + \DeclareUnicodeCharacter{03A7}{{\it X}}% + \DeclareUnicodeCharacter{03A8}{\ensuremath{\mit\Psi}}% + \DeclareUnicodeCharacter{03A9}{\ensuremath{\mit\Omega}}% + % + % Vowels with accents + \DeclareUnicodeCharacter{0390}{\ensuremath{\ddot{\acute\iota}}}% + \DeclareUnicodeCharacter{03AC}{\ensuremath{\acute\alpha}}% + \DeclareUnicodeCharacter{03AD}{\ensuremath{\acute\epsilon}}% + \DeclareUnicodeCharacter{03AE}{\ensuremath{\acute\eta}}% + \DeclareUnicodeCharacter{03AF}{\ensuremath{\acute\iota}}% + \DeclareUnicodeCharacter{03B0}{\ensuremath{\acute{\ddot\upsilon}}}% + % + % Standalone accent + \DeclareUnicodeCharacter{0384}{\ensuremath{\acute{\ }}}% + % + % Greek letters lower case + \DeclareUnicodeCharacter{03B1}{\ensuremath\alpha}% + \DeclareUnicodeCharacter{03B2}{\ensuremath\beta}% + \DeclareUnicodeCharacter{03B3}{\ensuremath\gamma}% + \DeclareUnicodeCharacter{03B4}{\ensuremath\delta}% + \DeclareUnicodeCharacter{03B5}{\ensuremath\epsilon}% + \DeclareUnicodeCharacter{03B6}{\ensuremath\zeta}% + \DeclareUnicodeCharacter{03B7}{\ensuremath\eta}% + \DeclareUnicodeCharacter{03B8}{\ensuremath\theta}% + \DeclareUnicodeCharacter{03B9}{\ensuremath\iota}% + \DeclareUnicodeCharacter{03BA}{\ensuremath\kappa}% + \DeclareUnicodeCharacter{03BB}{\ensuremath\lambda}% + \DeclareUnicodeCharacter{03BC}{\ensuremath\mu}% + \DeclareUnicodeCharacter{03BD}{\ensuremath\nu}% + \DeclareUnicodeCharacter{03BE}{\ensuremath\xi}% + \DeclareUnicodeCharacter{03BF}{{\it o}}% omicron + \DeclareUnicodeCharacter{03C0}{\ensuremath\pi}% + \DeclareUnicodeCharacter{03C1}{\ensuremath\rho}% + \DeclareUnicodeCharacter{03C2}{\ensuremath\varsigma}% + \DeclareUnicodeCharacter{03C3}{\ensuremath\sigma}% + \DeclareUnicodeCharacter{03C4}{\ensuremath\tau}% + \DeclareUnicodeCharacter{03C5}{\ensuremath\upsilon}% + \DeclareUnicodeCharacter{03C6}{\ensuremath\phi}% + \DeclareUnicodeCharacter{03C7}{\ensuremath\chi}% + \DeclareUnicodeCharacter{03C8}{\ensuremath\psi}% + \DeclareUnicodeCharacter{03C9}{\ensuremath\omega}% + % + % More Greek vowels with accents + \DeclareUnicodeCharacter{03CA}{\ensuremath{\ddot\iota}}% + \DeclareUnicodeCharacter{03CB}{\ensuremath{\ddot\upsilon}}% + \DeclareUnicodeCharacter{03CC}{\ensuremath{\acute o}}% + \DeclareUnicodeCharacter{03CD}{\ensuremath{\acute\upsilon}}% + \DeclareUnicodeCharacter{03CE}{\ensuremath{\acute\omega}}% + % + % Variant Greek letters + \DeclareUnicodeCharacter{03D1}{\ensuremath\vartheta}% + \DeclareUnicodeCharacter{03D6}{\ensuremath\varpi}% + \DeclareUnicodeCharacter{03F1}{\ensuremath\varrho}% + % + \DeclareUnicodeCharacter{1E02}{\dotaccent{B}}% + \DeclareUnicodeCharacter{1E03}{\dotaccent{b}}% + \DeclareUnicodeCharacter{1E04}{\udotaccent{B}}% + \DeclareUnicodeCharacter{1E05}{\udotaccent{b}}% + \DeclareUnicodeCharacter{1E06}{\ubaraccent{B}}% + \DeclareUnicodeCharacter{1E07}{\ubaraccent{b}}% + \DeclareUnicodeCharacter{1E0A}{\dotaccent{D}}% + \DeclareUnicodeCharacter{1E0B}{\dotaccent{d}}% + \DeclareUnicodeCharacter{1E0C}{\udotaccent{D}}% + \DeclareUnicodeCharacter{1E0D}{\udotaccent{d}}% + \DeclareUnicodeCharacter{1E0E}{\ubaraccent{D}}% + \DeclareUnicodeCharacter{1E0F}{\ubaraccent{d}}% + % + \DeclareUnicodeCharacter{1E1E}{\dotaccent{F}}% + \DeclareUnicodeCharacter{1E1F}{\dotaccent{f}}% + % + \DeclareUnicodeCharacter{1E20}{\=G}% + \DeclareUnicodeCharacter{1E21}{\=g}% + \DeclareUnicodeCharacter{1E22}{\dotaccent{H}}% + \DeclareUnicodeCharacter{1E23}{\dotaccent{h}}% + \DeclareUnicodeCharacter{1E24}{\udotaccent{H}}% + \DeclareUnicodeCharacter{1E25}{\udotaccent{h}}% + \DeclareUnicodeCharacter{1E26}{\"H}% + \DeclareUnicodeCharacter{1E27}{\"h}% + % + \DeclareUnicodeCharacter{1E30}{\'K}% + \DeclareUnicodeCharacter{1E31}{\'k}% + \DeclareUnicodeCharacter{1E32}{\udotaccent{K}}% + \DeclareUnicodeCharacter{1E33}{\udotaccent{k}}% + \DeclareUnicodeCharacter{1E34}{\ubaraccent{K}}% + \DeclareUnicodeCharacter{1E35}{\ubaraccent{k}}% + \DeclareUnicodeCharacter{1E36}{\udotaccent{L}}% + \DeclareUnicodeCharacter{1E37}{\udotaccent{l}}% + \DeclareUnicodeCharacter{1E3A}{\ubaraccent{L}}% + \DeclareUnicodeCharacter{1E3B}{\ubaraccent{l}}% + \DeclareUnicodeCharacter{1E3E}{\'M}% + \DeclareUnicodeCharacter{1E3F}{\'m}% + % + \DeclareUnicodeCharacter{1E40}{\dotaccent{M}}% + \DeclareUnicodeCharacter{1E41}{\dotaccent{m}}% + \DeclareUnicodeCharacter{1E42}{\udotaccent{M}}% + \DeclareUnicodeCharacter{1E43}{\udotaccent{m}}% + \DeclareUnicodeCharacter{1E44}{\dotaccent{N}}% + \DeclareUnicodeCharacter{1E45}{\dotaccent{n}}% + \DeclareUnicodeCharacter{1E46}{\udotaccent{N}}% + \DeclareUnicodeCharacter{1E47}{\udotaccent{n}}% + \DeclareUnicodeCharacter{1E48}{\ubaraccent{N}}% + \DeclareUnicodeCharacter{1E49}{\ubaraccent{n}}% + % + \DeclareUnicodeCharacter{1E54}{\'P}% + \DeclareUnicodeCharacter{1E55}{\'p}% + \DeclareUnicodeCharacter{1E56}{\dotaccent{P}}% + \DeclareUnicodeCharacter{1E57}{\dotaccent{p}}% + \DeclareUnicodeCharacter{1E58}{\dotaccent{R}}% + \DeclareUnicodeCharacter{1E59}{\dotaccent{r}}% + \DeclareUnicodeCharacter{1E5A}{\udotaccent{R}}% + \DeclareUnicodeCharacter{1E5B}{\udotaccent{r}}% + \DeclareUnicodeCharacter{1E5E}{\ubaraccent{R}}% + \DeclareUnicodeCharacter{1E5F}{\ubaraccent{r}}% + % + \DeclareUnicodeCharacter{1E60}{\dotaccent{S}}% + \DeclareUnicodeCharacter{1E61}{\dotaccent{s}}% + \DeclareUnicodeCharacter{1E62}{\udotaccent{S}}% + \DeclareUnicodeCharacter{1E63}{\udotaccent{s}}% + \DeclareUnicodeCharacter{1E6A}{\dotaccent{T}}% + \DeclareUnicodeCharacter{1E6B}{\dotaccent{t}}% + \DeclareUnicodeCharacter{1E6C}{\udotaccent{T}}% + \DeclareUnicodeCharacter{1E6D}{\udotaccent{t}}% + \DeclareUnicodeCharacter{1E6E}{\ubaraccent{T}}% + \DeclareUnicodeCharacter{1E6F}{\ubaraccent{t}}% + % + \DeclareUnicodeCharacter{1E7C}{\~V}% + \DeclareUnicodeCharacter{1E7D}{\~v}% + \DeclareUnicodeCharacter{1E7E}{\udotaccent{V}}% + \DeclareUnicodeCharacter{1E7F}{\udotaccent{v}}% + % + \DeclareUnicodeCharacter{1E80}{\`W}% + \DeclareUnicodeCharacter{1E81}{\`w}% + \DeclareUnicodeCharacter{1E82}{\'W}% + \DeclareUnicodeCharacter{1E83}{\'w}% + \DeclareUnicodeCharacter{1E84}{\"W}% + \DeclareUnicodeCharacter{1E85}{\"w}% + \DeclareUnicodeCharacter{1E86}{\dotaccent{W}}% + \DeclareUnicodeCharacter{1E87}{\dotaccent{w}}% + \DeclareUnicodeCharacter{1E88}{\udotaccent{W}}% + \DeclareUnicodeCharacter{1E89}{\udotaccent{w}}% + \DeclareUnicodeCharacter{1E8A}{\dotaccent{X}}% + \DeclareUnicodeCharacter{1E8B}{\dotaccent{x}}% + \DeclareUnicodeCharacter{1E8C}{\"X}% + \DeclareUnicodeCharacter{1E8D}{\"x}% + \DeclareUnicodeCharacter{1E8E}{\dotaccent{Y}}% + \DeclareUnicodeCharacter{1E8F}{\dotaccent{y}}% + % + \DeclareUnicodeCharacter{1E90}{\^Z}% + \DeclareUnicodeCharacter{1E91}{\^z}% + \DeclareUnicodeCharacter{1E92}{\udotaccent{Z}}% + \DeclareUnicodeCharacter{1E93}{\udotaccent{z}}% + \DeclareUnicodeCharacter{1E94}{\ubaraccent{Z}}% + \DeclareUnicodeCharacter{1E95}{\ubaraccent{z}}% + \DeclareUnicodeCharacter{1E96}{\ubaraccent{h}}% + \DeclareUnicodeCharacter{1E97}{\"t}% + \DeclareUnicodeCharacter{1E98}{\ringaccent{w}}% + \DeclareUnicodeCharacter{1E99}{\ringaccent{y}}% + % + \DeclareUnicodeCharacter{1EA0}{\udotaccent{A}}% + \DeclareUnicodeCharacter{1EA1}{\udotaccent{a}}% + % + \DeclareUnicodeCharacter{1EB8}{\udotaccent{E}}% + \DeclareUnicodeCharacter{1EB9}{\udotaccent{e}}% + \DeclareUnicodeCharacter{1EBC}{\~E}% + \DeclareUnicodeCharacter{1EBD}{\~e}% + % + \DeclareUnicodeCharacter{1ECA}{\udotaccent{I}}% + \DeclareUnicodeCharacter{1ECB}{\udotaccent{i}}% + \DeclareUnicodeCharacter{1ECC}{\udotaccent{O}}% + \DeclareUnicodeCharacter{1ECD}{\udotaccent{o}}% + % + \DeclareUnicodeCharacter{1EE4}{\udotaccent{U}}% + \DeclareUnicodeCharacter{1EE5}{\udotaccent{u}}% + % + \DeclareUnicodeCharacter{1EF2}{\`Y}% + \DeclareUnicodeCharacter{1EF3}{\`y}% + \DeclareUnicodeCharacter{1EF4}{\udotaccent{Y}}% + % + \DeclareUnicodeCharacter{1EF8}{\~Y}% + \DeclareUnicodeCharacter{1EF9}{\~y}% + % + % Punctuation + \DeclareUnicodeCharacter{2013}{--}% + \DeclareUnicodeCharacter{2014}{---}% + \DeclareUnicodeCharacter{2018}{\quoteleft{}}% + \DeclareUnicodeCharacter{2019}{\quoteright{}}% + \DeclareUnicodeCharacter{201A}{\quotesinglbase{}}% + \DeclareUnicodeCharacter{201C}{\quotedblleft{}}% + \DeclareUnicodeCharacter{201D}{\quotedblright{}}% + \DeclareUnicodeCharacter{201E}{\quotedblbase{}}% + \DeclareUnicodeCharacter{2020}{\ensuremath\dagger}% + \DeclareUnicodeCharacter{2021}{\ensuremath\ddagger}% + \DeclareUnicodeCharacter{2022}{\bullet{}}% + \DeclareUnicodeCharacter{202F}{\thinspace}% + \DeclareUnicodeCharacter{2026}{\dots{}}% + \DeclareUnicodeCharacter{2039}{\guilsinglleft{}}% + \DeclareUnicodeCharacter{203A}{\guilsinglright{}}% + % + \DeclareUnicodeCharacter{20AC}{\euro{}}% + % + \DeclareUnicodeCharacter{2192}{\expansion{}}% + \DeclareUnicodeCharacter{21D2}{\result{}}% + % + % Mathematical symbols + \DeclareUnicodeCharacter{2200}{\ensuremath\forall}% + \DeclareUnicodeCharacter{2203}{\ensuremath\exists}% + \DeclareUnicodeCharacter{2208}{\ensuremath\in}% + \DeclareUnicodeCharacter{2212}{\minus{}}% + \DeclareUnicodeCharacter{2217}{\ast}% + \DeclareUnicodeCharacter{221E}{\ensuremath\infty}% + \DeclareUnicodeCharacter{2225}{\ensuremath\parallel}% + \DeclareUnicodeCharacter{2227}{\ensuremath\wedge}% + \DeclareUnicodeCharacter{2229}{\ensuremath\cap}% + \DeclareUnicodeCharacter{2261}{\equiv{}}% + \DeclareUnicodeCharacter{2264}{\ensuremath\leq}% + \DeclareUnicodeCharacter{2265}{\ensuremath\geq}% + \DeclareUnicodeCharacter{2282}{\ensuremath\subset}% + \DeclareUnicodeCharacter{2287}{\ensuremath\supseteq}% + % + \DeclareUnicodeCharacter{2016}{\ensuremath\Vert}% + \DeclareUnicodeCharacter{2032}{\ensuremath\prime}% + \DeclareUnicodeCharacter{210F}{\ensuremath\hbar}% + \DeclareUnicodeCharacter{2111}{\ensuremath\Im}% + \DeclareUnicodeCharacter{2113}{\ensuremath\ell}% + \DeclareUnicodeCharacter{2118}{\ensuremath\wp}% + \DeclareUnicodeCharacter{211C}{\ensuremath\Re}% + \DeclareUnicodeCharacter{2135}{\ensuremath\aleph}% + \DeclareUnicodeCharacter{2190}{\ensuremath\leftarrow}% + \DeclareUnicodeCharacter{2191}{\ensuremath\uparrow}% + \DeclareUnicodeCharacter{2193}{\ensuremath\downarrow}% + \DeclareUnicodeCharacter{2194}{\ensuremath\leftrightarrow}% + \DeclareUnicodeCharacter{2195}{\ensuremath\updownarrow}% + \DeclareUnicodeCharacter{2196}{\ensuremath\nwarrow}% + \DeclareUnicodeCharacter{2197}{\ensuremath\nearrow}% + \DeclareUnicodeCharacter{2198}{\ensuremath\searrow}% + \DeclareUnicodeCharacter{2199}{\ensuremath\swarrow}% + \DeclareUnicodeCharacter{21A6}{\ensuremath\mapsto}% + \DeclareUnicodeCharacter{21A9}{\ensuremath\hookleftarrow}% + \DeclareUnicodeCharacter{21AA}{\ensuremath\hookrightarrow}% + \DeclareUnicodeCharacter{21BC}{\ensuremath\leftharpoonup}% + \DeclareUnicodeCharacter{21BD}{\ensuremath\leftharpoondown}% + \DeclareUnicodeCharacter{21C0}{\ensuremath\rightharpoonup}% + \DeclareUnicodeCharacter{21C1}{\ensuremath\rightharpoondown}% + \DeclareUnicodeCharacter{21CC}{\ensuremath\rightleftharpoons}% + \DeclareUnicodeCharacter{21D0}{\ensuremath\Leftarrow}% + \DeclareUnicodeCharacter{21D1}{\ensuremath\Uparrow}% + \DeclareUnicodeCharacter{21D3}{\ensuremath\Downarrow}% + \DeclareUnicodeCharacter{21D4}{\ensuremath\Leftrightarrow}% + \DeclareUnicodeCharacter{21D5}{\ensuremath\Updownarrow}% + \DeclareUnicodeCharacter{2202}{\ensuremath\partial}% + \DeclareUnicodeCharacter{2205}{\ensuremath\emptyset}% + \DeclareUnicodeCharacter{2207}{\ensuremath\nabla}% + \DeclareUnicodeCharacter{2209}{\ensuremath\notin}% + \DeclareUnicodeCharacter{220B}{\ensuremath\owns}% + \DeclareUnicodeCharacter{220F}{\ensuremath\prod}% + \DeclareUnicodeCharacter{2210}{\ensuremath\coprod}% + \DeclareUnicodeCharacter{2211}{\ensuremath\sum}% + \DeclareUnicodeCharacter{2213}{\ensuremath\mp}% + \DeclareUnicodeCharacter{2218}{\ensuremath\circ}% + \DeclareUnicodeCharacter{221A}{\ensuremath\surd}% + \DeclareUnicodeCharacter{221D}{\ensuremath\propto}% + \DeclareUnicodeCharacter{2220}{\ensuremath\angle}% + \DeclareUnicodeCharacter{2223}{\ensuremath\mid}% + \DeclareUnicodeCharacter{2228}{\ensuremath\vee}% + \DeclareUnicodeCharacter{222A}{\ensuremath\cup}% + \DeclareUnicodeCharacter{222B}{\ensuremath\smallint}% + \DeclareUnicodeCharacter{222E}{\ensuremath\oint}% + \DeclareUnicodeCharacter{223C}{\ensuremath\sim}% + \DeclareUnicodeCharacter{2240}{\ensuremath\wr}% + \DeclareUnicodeCharacter{2243}{\ensuremath\simeq}% + \DeclareUnicodeCharacter{2245}{\ensuremath\cong}% + \DeclareUnicodeCharacter{2248}{\ensuremath\approx}% + \DeclareUnicodeCharacter{224D}{\ensuremath\asymp}% + \DeclareUnicodeCharacter{2250}{\ensuremath\doteq}% + \DeclareUnicodeCharacter{2260}{\ensuremath\neq}% + \DeclareUnicodeCharacter{226A}{\ensuremath\ll}% + \DeclareUnicodeCharacter{226B}{\ensuremath\gg}% + \DeclareUnicodeCharacter{227A}{\ensuremath\prec}% + \DeclareUnicodeCharacter{227B}{\ensuremath\succ}% + \DeclareUnicodeCharacter{2283}{\ensuremath\supset}% + \DeclareUnicodeCharacter{2286}{\ensuremath\subseteq}% + \DeclareUnicodeCharacter{228E}{\ensuremath\uplus}% + \DeclareUnicodeCharacter{2291}{\ensuremath\sqsubseteq}% + \DeclareUnicodeCharacter{2292}{\ensuremath\sqsupseteq}% + \DeclareUnicodeCharacter{2293}{\ensuremath\sqcap}% + \DeclareUnicodeCharacter{2294}{\ensuremath\sqcup}% + \DeclareUnicodeCharacter{2295}{\ensuremath\oplus}% + \DeclareUnicodeCharacter{2296}{\ensuremath\ominus}% + \DeclareUnicodeCharacter{2297}{\ensuremath\otimes}% + \DeclareUnicodeCharacter{2298}{\ensuremath\oslash}% + \DeclareUnicodeCharacter{2299}{\ensuremath\odot}% + \DeclareUnicodeCharacter{22A2}{\ensuremath\vdash}% + \DeclareUnicodeCharacter{22A3}{\ensuremath\dashv}% + \DeclareUnicodeCharacter{22A4}{\ensuremath\ptextop}% + \DeclareUnicodeCharacter{22A5}{\ensuremath\bot}% + \DeclareUnicodeCharacter{22A8}{\ensuremath\models}% + \DeclareUnicodeCharacter{22C0}{\ensuremath\bigwedge}% + \DeclareUnicodeCharacter{22C1}{\ensuremath\bigvee}% + \DeclareUnicodeCharacter{22C2}{\ensuremath\bigcap}% + \DeclareUnicodeCharacter{22C3}{\ensuremath\bigcup}% + \DeclareUnicodeCharacter{22C4}{\ensuremath\diamond}% + \DeclareUnicodeCharacter{22C5}{\ensuremath\cdot}% + \DeclareUnicodeCharacter{22C6}{\ensuremath\star}% + \DeclareUnicodeCharacter{22C8}{\ensuremath\bowtie}% + \DeclareUnicodeCharacter{2308}{\ensuremath\lceil}% + \DeclareUnicodeCharacter{2309}{\ensuremath\rceil}% + \DeclareUnicodeCharacter{230A}{\ensuremath\lfloor}% + \DeclareUnicodeCharacter{230B}{\ensuremath\rfloor}% + \DeclareUnicodeCharacter{2322}{\ensuremath\frown}% + \DeclareUnicodeCharacter{2323}{\ensuremath\smile}% + % + \DeclareUnicodeCharacter{25B3}{\ensuremath\triangle}% + \DeclareUnicodeCharacter{25B7}{\ensuremath\triangleright}% + \DeclareUnicodeCharacter{25BD}{\ensuremath\bigtriangledown}% + \DeclareUnicodeCharacter{25C1}{\ensuremath\triangleleft}% + \DeclareUnicodeCharacter{25C7}{\ensuremath\diamond}% + \DeclareUnicodeCharacter{2660}{\ensuremath\spadesuit}% + \DeclareUnicodeCharacter{2661}{\ensuremath\heartsuit}% + \DeclareUnicodeCharacter{2662}{\ensuremath\diamondsuit}% + \DeclareUnicodeCharacter{2663}{\ensuremath\clubsuit}% + \DeclareUnicodeCharacter{266D}{\ensuremath\flat}% + \DeclareUnicodeCharacter{266E}{\ensuremath\natural}% + \DeclareUnicodeCharacter{266F}{\ensuremath\sharp}% + \DeclareUnicodeCharacter{26AA}{\ensuremath\bigcirc}% + \DeclareUnicodeCharacter{27B9}{\ensuremath\rangle}% + \DeclareUnicodeCharacter{27C2}{\ensuremath\perp}% + \DeclareUnicodeCharacter{27E8}{\ensuremath\langle}% + \DeclareUnicodeCharacter{27F5}{\ensuremath\longleftarrow}% + \DeclareUnicodeCharacter{27F6}{\ensuremath\longrightarrow}% + \DeclareUnicodeCharacter{27F7}{\ensuremath\longleftrightarrow}% + \DeclareUnicodeCharacter{27FC}{\ensuremath\longmapsto}% + \DeclareUnicodeCharacter{29F5}{\ensuremath\setminus}% + \DeclareUnicodeCharacter{2A00}{\ensuremath\bigodot}% + \DeclareUnicodeCharacter{2A01}{\ensuremath\bigoplus}% + \DeclareUnicodeCharacter{2A02}{\ensuremath\bigotimes}% + \DeclareUnicodeCharacter{2A04}{\ensuremath\biguplus}% + \DeclareUnicodeCharacter{2A06}{\ensuremath\bigsqcup}% + \DeclareUnicodeCharacter{2A3F}{\ensuremath\amalg}% + \DeclareUnicodeCharacter{2AAF}{\ensuremath\preceq}% + \DeclareUnicodeCharacter{2AB0}{\ensuremath\succeq}% + % + \global\mathchardef\checkmark="1370% actually the square root sign + \DeclareUnicodeCharacter{2713}{\ensuremath\checkmark}% +}% end of \unicodechardefs + +% UTF-8 byte sequence (pdfTeX) definitions (replacing and @U command) +% It makes the setting that replace UTF-8 byte sequence. \def\utfeightchardefs{% - \DeclareUnicodeCharacter{00A0}{\tie} - \DeclareUnicodeCharacter{00A1}{\exclamdown} - \DeclareUnicodeCharacter{00A3}{\pounds} - \DeclareUnicodeCharacter{00A8}{\"{ }} - \DeclareUnicodeCharacter{00A9}{\copyright} - \DeclareUnicodeCharacter{00AA}{\ordf} - \DeclareUnicodeCharacter{00AB}{\guillemetleft} - \DeclareUnicodeCharacter{00AD}{\-} - \DeclareUnicodeCharacter{00AE}{\registeredsymbol} - \DeclareUnicodeCharacter{00AF}{\={ }} + \let\DeclareUnicodeCharacter\DeclareUnicodeCharacterUTFviii + \unicodechardefs +} - \DeclareUnicodeCharacter{00B0}{\ringaccent{ }} - \DeclareUnicodeCharacter{00B4}{\'{ }} - \DeclareUnicodeCharacter{00B8}{\cedilla{ }} - \DeclareUnicodeCharacter{00BA}{\ordm} - \DeclareUnicodeCharacter{00BB}{\guillemetright} - \DeclareUnicodeCharacter{00BF}{\questiondown} +% Whether the active definitions of non-ASCII characters expand to +% non-active tokens with the same character code. This is used to +% write characters literally, instead of using active definitions for +% printing the correct glyphs. +\newif\ifpassthroughchars +\passthroughcharsfalse - \DeclareUnicodeCharacter{00C0}{\`A} - \DeclareUnicodeCharacter{00C1}{\'A} - \DeclareUnicodeCharacter{00C2}{\^A} - \DeclareUnicodeCharacter{00C3}{\~A} - \DeclareUnicodeCharacter{00C4}{\"A} - \DeclareUnicodeCharacter{00C5}{\AA} - \DeclareUnicodeCharacter{00C6}{\AE} - \DeclareUnicodeCharacter{00C7}{\cedilla{C}} - \DeclareUnicodeCharacter{00C8}{\`E} - \DeclareUnicodeCharacter{00C9}{\'E} - \DeclareUnicodeCharacter{00CA}{\^E} - \DeclareUnicodeCharacter{00CB}{\"E} - \DeclareUnicodeCharacter{00CC}{\`I} - \DeclareUnicodeCharacter{00CD}{\'I} - \DeclareUnicodeCharacter{00CE}{\^I} - \DeclareUnicodeCharacter{00CF}{\"I} +% For native Unicode handling (XeTeX and LuaTeX), +% provide a definition macro to replace/pass-through a Unicode character +% +\def\DeclareUnicodeCharacterNative#1#2{% + \catcode"#1=\active + \def\dodeclareunicodecharacternative##1##2##3{% + \begingroup + \uccode`\~="##2\relax + \uppercase{\gdef~}{% + \ifpassthroughchars + ##1% + \else + ##3% + \fi + } + \endgroup + } + \begingroup + \uccode`\.="#1\relax + \uppercase{\def\UTFNativeTmp{.}}% + \expandafter\dodeclareunicodecharacternative\UTFNativeTmp{#1}{#2}% + \endgroup +} - \DeclareUnicodeCharacter{00D0}{\DH} - \DeclareUnicodeCharacter{00D1}{\~N} - \DeclareUnicodeCharacter{00D2}{\`O} - \DeclareUnicodeCharacter{00D3}{\'O} - \DeclareUnicodeCharacter{00D4}{\^O} - \DeclareUnicodeCharacter{00D5}{\~O} - \DeclareUnicodeCharacter{00D6}{\"O} - \DeclareUnicodeCharacter{00D8}{\O} - \DeclareUnicodeCharacter{00D9}{\`U} - \DeclareUnicodeCharacter{00DA}{\'U} - \DeclareUnicodeCharacter{00DB}{\^U} - \DeclareUnicodeCharacter{00DC}{\"U} - \DeclareUnicodeCharacter{00DD}{\'Y} - \DeclareUnicodeCharacter{00DE}{\TH} - \DeclareUnicodeCharacter{00DF}{\ss} +% Native Unicode handling (XeTeX and LuaTeX) character replacing definition. +% It activates the setting that replaces Unicode characters. +\def\nativeunicodechardefs{% + \let\DeclareUnicodeCharacter\DeclareUnicodeCharacterNative + \unicodechardefs +} - \DeclareUnicodeCharacter{00E0}{\`a} - \DeclareUnicodeCharacter{00E1}{\'a} - \DeclareUnicodeCharacter{00E2}{\^a} - \DeclareUnicodeCharacter{00E3}{\~a} - \DeclareUnicodeCharacter{00E4}{\"a} - \DeclareUnicodeCharacter{00E5}{\aa} - \DeclareUnicodeCharacter{00E6}{\ae} - \DeclareUnicodeCharacter{00E7}{\cedilla{c}} - \DeclareUnicodeCharacter{00E8}{\`e} - \DeclareUnicodeCharacter{00E9}{\'e} - \DeclareUnicodeCharacter{00EA}{\^e} - \DeclareUnicodeCharacter{00EB}{\"e} - \DeclareUnicodeCharacter{00EC}{\`{\dotless{i}}} - \DeclareUnicodeCharacter{00ED}{\'{\dotless{i}}} - \DeclareUnicodeCharacter{00EE}{\^{\dotless{i}}} - \DeclareUnicodeCharacter{00EF}{\"{\dotless{i}}} - - \DeclareUnicodeCharacter{00F0}{\dh} - \DeclareUnicodeCharacter{00F1}{\~n} - \DeclareUnicodeCharacter{00F2}{\`o} - \DeclareUnicodeCharacter{00F3}{\'o} - \DeclareUnicodeCharacter{00F4}{\^o} - \DeclareUnicodeCharacter{00F5}{\~o} - \DeclareUnicodeCharacter{00F6}{\"o} - \DeclareUnicodeCharacter{00F8}{\o} - \DeclareUnicodeCharacter{00F9}{\`u} - \DeclareUnicodeCharacter{00FA}{\'u} - \DeclareUnicodeCharacter{00FB}{\^u} - \DeclareUnicodeCharacter{00FC}{\"u} - \DeclareUnicodeCharacter{00FD}{\'y} - \DeclareUnicodeCharacter{00FE}{\th} - \DeclareUnicodeCharacter{00FF}{\"y} - - \DeclareUnicodeCharacter{0100}{\=A} - \DeclareUnicodeCharacter{0101}{\=a} - \DeclareUnicodeCharacter{0102}{\u{A}} - \DeclareUnicodeCharacter{0103}{\u{a}} - \DeclareUnicodeCharacter{0104}{\ogonek{A}} - \DeclareUnicodeCharacter{0105}{\ogonek{a}} - \DeclareUnicodeCharacter{0106}{\'C} - \DeclareUnicodeCharacter{0107}{\'c} - \DeclareUnicodeCharacter{0108}{\^C} - \DeclareUnicodeCharacter{0109}{\^c} - \DeclareUnicodeCharacter{0118}{\ogonek{E}} - \DeclareUnicodeCharacter{0119}{\ogonek{e}} - \DeclareUnicodeCharacter{010A}{\dotaccent{C}} - \DeclareUnicodeCharacter{010B}{\dotaccent{c}} - \DeclareUnicodeCharacter{010C}{\v{C}} - \DeclareUnicodeCharacter{010D}{\v{c}} - \DeclareUnicodeCharacter{010E}{\v{D}} - - \DeclareUnicodeCharacter{0112}{\=E} - \DeclareUnicodeCharacter{0113}{\=e} - \DeclareUnicodeCharacter{0114}{\u{E}} - \DeclareUnicodeCharacter{0115}{\u{e}} - \DeclareUnicodeCharacter{0116}{\dotaccent{E}} - \DeclareUnicodeCharacter{0117}{\dotaccent{e}} - \DeclareUnicodeCharacter{011A}{\v{E}} - \DeclareUnicodeCharacter{011B}{\v{e}} - \DeclareUnicodeCharacter{011C}{\^G} - \DeclareUnicodeCharacter{011D}{\^g} - \DeclareUnicodeCharacter{011E}{\u{G}} - \DeclareUnicodeCharacter{011F}{\u{g}} - - \DeclareUnicodeCharacter{0120}{\dotaccent{G}} - \DeclareUnicodeCharacter{0121}{\dotaccent{g}} - \DeclareUnicodeCharacter{0124}{\^H} - \DeclareUnicodeCharacter{0125}{\^h} - \DeclareUnicodeCharacter{0128}{\~I} - \DeclareUnicodeCharacter{0129}{\~{\dotless{i}}} - \DeclareUnicodeCharacter{012A}{\=I} - \DeclareUnicodeCharacter{012B}{\={\dotless{i}}} - \DeclareUnicodeCharacter{012C}{\u{I}} - \DeclareUnicodeCharacter{012D}{\u{\dotless{i}}} - - \DeclareUnicodeCharacter{0130}{\dotaccent{I}} - \DeclareUnicodeCharacter{0131}{\dotless{i}} - \DeclareUnicodeCharacter{0132}{IJ} - \DeclareUnicodeCharacter{0133}{ij} - \DeclareUnicodeCharacter{0134}{\^J} - \DeclareUnicodeCharacter{0135}{\^{\dotless{j}}} - \DeclareUnicodeCharacter{0139}{\'L} - \DeclareUnicodeCharacter{013A}{\'l} - - \DeclareUnicodeCharacter{0141}{\L} - \DeclareUnicodeCharacter{0142}{\l} - \DeclareUnicodeCharacter{0143}{\'N} - \DeclareUnicodeCharacter{0144}{\'n} - \DeclareUnicodeCharacter{0147}{\v{N}} - \DeclareUnicodeCharacter{0148}{\v{n}} - \DeclareUnicodeCharacter{014C}{\=O} - \DeclareUnicodeCharacter{014D}{\=o} - \DeclareUnicodeCharacter{014E}{\u{O}} - \DeclareUnicodeCharacter{014F}{\u{o}} - - \DeclareUnicodeCharacter{0150}{\H{O}} - \DeclareUnicodeCharacter{0151}{\H{o}} - \DeclareUnicodeCharacter{0152}{\OE} - \DeclareUnicodeCharacter{0153}{\oe} - \DeclareUnicodeCharacter{0154}{\'R} - \DeclareUnicodeCharacter{0155}{\'r} - \DeclareUnicodeCharacter{0158}{\v{R}} - \DeclareUnicodeCharacter{0159}{\v{r}} - \DeclareUnicodeCharacter{015A}{\'S} - \DeclareUnicodeCharacter{015B}{\'s} - \DeclareUnicodeCharacter{015C}{\^S} - \DeclareUnicodeCharacter{015D}{\^s} - \DeclareUnicodeCharacter{015E}{\cedilla{S}} - \DeclareUnicodeCharacter{015F}{\cedilla{s}} - - \DeclareUnicodeCharacter{0160}{\v{S}} - \DeclareUnicodeCharacter{0161}{\v{s}} - \DeclareUnicodeCharacter{0162}{\cedilla{t}} - \DeclareUnicodeCharacter{0163}{\cedilla{T}} - \DeclareUnicodeCharacter{0164}{\v{T}} - - \DeclareUnicodeCharacter{0168}{\~U} - \DeclareUnicodeCharacter{0169}{\~u} - \DeclareUnicodeCharacter{016A}{\=U} - \DeclareUnicodeCharacter{016B}{\=u} - \DeclareUnicodeCharacter{016C}{\u{U}} - \DeclareUnicodeCharacter{016D}{\u{u}} - \DeclareUnicodeCharacter{016E}{\ringaccent{U}} - \DeclareUnicodeCharacter{016F}{\ringaccent{u}} - - \DeclareUnicodeCharacter{0170}{\H{U}} - \DeclareUnicodeCharacter{0171}{\H{u}} - \DeclareUnicodeCharacter{0174}{\^W} - \DeclareUnicodeCharacter{0175}{\^w} - \DeclareUnicodeCharacter{0176}{\^Y} - \DeclareUnicodeCharacter{0177}{\^y} - \DeclareUnicodeCharacter{0178}{\"Y} - \DeclareUnicodeCharacter{0179}{\'Z} - \DeclareUnicodeCharacter{017A}{\'z} - \DeclareUnicodeCharacter{017B}{\dotaccent{Z}} - \DeclareUnicodeCharacter{017C}{\dotaccent{z}} - \DeclareUnicodeCharacter{017D}{\v{Z}} - \DeclareUnicodeCharacter{017E}{\v{z}} - - \DeclareUnicodeCharacter{01C4}{D\v{Z}} - \DeclareUnicodeCharacter{01C5}{D\v{z}} - \DeclareUnicodeCharacter{01C6}{d\v{z}} - \DeclareUnicodeCharacter{01C7}{LJ} - \DeclareUnicodeCharacter{01C8}{Lj} - \DeclareUnicodeCharacter{01C9}{lj} - \DeclareUnicodeCharacter{01CA}{NJ} - \DeclareUnicodeCharacter{01CB}{Nj} - \DeclareUnicodeCharacter{01CC}{nj} - \DeclareUnicodeCharacter{01CD}{\v{A}} - \DeclareUnicodeCharacter{01CE}{\v{a}} - \DeclareUnicodeCharacter{01CF}{\v{I}} - - \DeclareUnicodeCharacter{01D0}{\v{\dotless{i}}} - \DeclareUnicodeCharacter{01D1}{\v{O}} - \DeclareUnicodeCharacter{01D2}{\v{o}} - \DeclareUnicodeCharacter{01D3}{\v{U}} - \DeclareUnicodeCharacter{01D4}{\v{u}} - - \DeclareUnicodeCharacter{01E2}{\={\AE}} - \DeclareUnicodeCharacter{01E3}{\={\ae}} - \DeclareUnicodeCharacter{01E6}{\v{G}} - \DeclareUnicodeCharacter{01E7}{\v{g}} - \DeclareUnicodeCharacter{01E8}{\v{K}} - \DeclareUnicodeCharacter{01E9}{\v{k}} - - \DeclareUnicodeCharacter{01F0}{\v{\dotless{j}}} - \DeclareUnicodeCharacter{01F1}{DZ} - \DeclareUnicodeCharacter{01F2}{Dz} - \DeclareUnicodeCharacter{01F3}{dz} - \DeclareUnicodeCharacter{01F4}{\'G} - \DeclareUnicodeCharacter{01F5}{\'g} - \DeclareUnicodeCharacter{01F8}{\`N} - \DeclareUnicodeCharacter{01F9}{\`n} - \DeclareUnicodeCharacter{01FC}{\'{\AE}} - \DeclareUnicodeCharacter{01FD}{\'{\ae}} - \DeclareUnicodeCharacter{01FE}{\'{\O}} - \DeclareUnicodeCharacter{01FF}{\'{\o}} - - \DeclareUnicodeCharacter{021E}{\v{H}} - \DeclareUnicodeCharacter{021F}{\v{h}} - - \DeclareUnicodeCharacter{0226}{\dotaccent{A}} - \DeclareUnicodeCharacter{0227}{\dotaccent{a}} - \DeclareUnicodeCharacter{0228}{\cedilla{E}} - \DeclareUnicodeCharacter{0229}{\cedilla{e}} - \DeclareUnicodeCharacter{022E}{\dotaccent{O}} - \DeclareUnicodeCharacter{022F}{\dotaccent{o}} - - \DeclareUnicodeCharacter{0232}{\=Y} - \DeclareUnicodeCharacter{0233}{\=y} - \DeclareUnicodeCharacter{0237}{\dotless{j}} - - \DeclareUnicodeCharacter{02DB}{\ogonek{ }} - - \DeclareUnicodeCharacter{1E02}{\dotaccent{B}} - \DeclareUnicodeCharacter{1E03}{\dotaccent{b}} - \DeclareUnicodeCharacter{1E04}{\udotaccent{B}} - \DeclareUnicodeCharacter{1E05}{\udotaccent{b}} - \DeclareUnicodeCharacter{1E06}{\ubaraccent{B}} - \DeclareUnicodeCharacter{1E07}{\ubaraccent{b}} - \DeclareUnicodeCharacter{1E0A}{\dotaccent{D}} - \DeclareUnicodeCharacter{1E0B}{\dotaccent{d}} - \DeclareUnicodeCharacter{1E0C}{\udotaccent{D}} - \DeclareUnicodeCharacter{1E0D}{\udotaccent{d}} - \DeclareUnicodeCharacter{1E0E}{\ubaraccent{D}} - \DeclareUnicodeCharacter{1E0F}{\ubaraccent{d}} - - \DeclareUnicodeCharacter{1E1E}{\dotaccent{F}} - \DeclareUnicodeCharacter{1E1F}{\dotaccent{f}} - - \DeclareUnicodeCharacter{1E20}{\=G} - \DeclareUnicodeCharacter{1E21}{\=g} - \DeclareUnicodeCharacter{1E22}{\dotaccent{H}} - \DeclareUnicodeCharacter{1E23}{\dotaccent{h}} - \DeclareUnicodeCharacter{1E24}{\udotaccent{H}} - \DeclareUnicodeCharacter{1E25}{\udotaccent{h}} - \DeclareUnicodeCharacter{1E26}{\"H} - \DeclareUnicodeCharacter{1E27}{\"h} - - \DeclareUnicodeCharacter{1E30}{\'K} - \DeclareUnicodeCharacter{1E31}{\'k} - \DeclareUnicodeCharacter{1E32}{\udotaccent{K}} - \DeclareUnicodeCharacter{1E33}{\udotaccent{k}} - \DeclareUnicodeCharacter{1E34}{\ubaraccent{K}} - \DeclareUnicodeCharacter{1E35}{\ubaraccent{k}} - \DeclareUnicodeCharacter{1E36}{\udotaccent{L}} - \DeclareUnicodeCharacter{1E37}{\udotaccent{l}} - \DeclareUnicodeCharacter{1E3A}{\ubaraccent{L}} - \DeclareUnicodeCharacter{1E3B}{\ubaraccent{l}} - \DeclareUnicodeCharacter{1E3E}{\'M} - \DeclareUnicodeCharacter{1E3F}{\'m} - - \DeclareUnicodeCharacter{1E40}{\dotaccent{M}} - \DeclareUnicodeCharacter{1E41}{\dotaccent{m}} - \DeclareUnicodeCharacter{1E42}{\udotaccent{M}} - \DeclareUnicodeCharacter{1E43}{\udotaccent{m}} - \DeclareUnicodeCharacter{1E44}{\dotaccent{N}} - \DeclareUnicodeCharacter{1E45}{\dotaccent{n}} - \DeclareUnicodeCharacter{1E46}{\udotaccent{N}} - \DeclareUnicodeCharacter{1E47}{\udotaccent{n}} - \DeclareUnicodeCharacter{1E48}{\ubaraccent{N}} - \DeclareUnicodeCharacter{1E49}{\ubaraccent{n}} - - \DeclareUnicodeCharacter{1E54}{\'P} - \DeclareUnicodeCharacter{1E55}{\'p} - \DeclareUnicodeCharacter{1E56}{\dotaccent{P}} - \DeclareUnicodeCharacter{1E57}{\dotaccent{p}} - \DeclareUnicodeCharacter{1E58}{\dotaccent{R}} - \DeclareUnicodeCharacter{1E59}{\dotaccent{r}} - \DeclareUnicodeCharacter{1E5A}{\udotaccent{R}} - \DeclareUnicodeCharacter{1E5B}{\udotaccent{r}} - \DeclareUnicodeCharacter{1E5E}{\ubaraccent{R}} - \DeclareUnicodeCharacter{1E5F}{\ubaraccent{r}} - - \DeclareUnicodeCharacter{1E60}{\dotaccent{S}} - \DeclareUnicodeCharacter{1E61}{\dotaccent{s}} - \DeclareUnicodeCharacter{1E62}{\udotaccent{S}} - \DeclareUnicodeCharacter{1E63}{\udotaccent{s}} - \DeclareUnicodeCharacter{1E6A}{\dotaccent{T}} - \DeclareUnicodeCharacter{1E6B}{\dotaccent{t}} - \DeclareUnicodeCharacter{1E6C}{\udotaccent{T}} - \DeclareUnicodeCharacter{1E6D}{\udotaccent{t}} - \DeclareUnicodeCharacter{1E6E}{\ubaraccent{T}} - \DeclareUnicodeCharacter{1E6F}{\ubaraccent{t}} - - \DeclareUnicodeCharacter{1E7C}{\~V} - \DeclareUnicodeCharacter{1E7D}{\~v} - \DeclareUnicodeCharacter{1E7E}{\udotaccent{V}} - \DeclareUnicodeCharacter{1E7F}{\udotaccent{v}} - - \DeclareUnicodeCharacter{1E80}{\`W} - \DeclareUnicodeCharacter{1E81}{\`w} - \DeclareUnicodeCharacter{1E82}{\'W} - \DeclareUnicodeCharacter{1E83}{\'w} - \DeclareUnicodeCharacter{1E84}{\"W} - \DeclareUnicodeCharacter{1E85}{\"w} - \DeclareUnicodeCharacter{1E86}{\dotaccent{W}} - \DeclareUnicodeCharacter{1E87}{\dotaccent{w}} - \DeclareUnicodeCharacter{1E88}{\udotaccent{W}} - \DeclareUnicodeCharacter{1E89}{\udotaccent{w}} - \DeclareUnicodeCharacter{1E8A}{\dotaccent{X}} - \DeclareUnicodeCharacter{1E8B}{\dotaccent{x}} - \DeclareUnicodeCharacter{1E8C}{\"X} - \DeclareUnicodeCharacter{1E8D}{\"x} - \DeclareUnicodeCharacter{1E8E}{\dotaccent{Y}} - \DeclareUnicodeCharacter{1E8F}{\dotaccent{y}} - - \DeclareUnicodeCharacter{1E90}{\^Z} - \DeclareUnicodeCharacter{1E91}{\^z} - \DeclareUnicodeCharacter{1E92}{\udotaccent{Z}} - \DeclareUnicodeCharacter{1E93}{\udotaccent{z}} - \DeclareUnicodeCharacter{1E94}{\ubaraccent{Z}} - \DeclareUnicodeCharacter{1E95}{\ubaraccent{z}} - \DeclareUnicodeCharacter{1E96}{\ubaraccent{h}} - \DeclareUnicodeCharacter{1E97}{\"t} - \DeclareUnicodeCharacter{1E98}{\ringaccent{w}} - \DeclareUnicodeCharacter{1E99}{\ringaccent{y}} - - \DeclareUnicodeCharacter{1EA0}{\udotaccent{A}} - \DeclareUnicodeCharacter{1EA1}{\udotaccent{a}} - - \DeclareUnicodeCharacter{1EB8}{\udotaccent{E}} - \DeclareUnicodeCharacter{1EB9}{\udotaccent{e}} - \DeclareUnicodeCharacter{1EBC}{\~E} - \DeclareUnicodeCharacter{1EBD}{\~e} - - \DeclareUnicodeCharacter{1ECA}{\udotaccent{I}} - \DeclareUnicodeCharacter{1ECB}{\udotaccent{i}} - \DeclareUnicodeCharacter{1ECC}{\udotaccent{O}} - \DeclareUnicodeCharacter{1ECD}{\udotaccent{o}} - - \DeclareUnicodeCharacter{1EE4}{\udotaccent{U}} - \DeclareUnicodeCharacter{1EE5}{\udotaccent{u}} - - \DeclareUnicodeCharacter{1EF2}{\`Y} - \DeclareUnicodeCharacter{1EF3}{\`y} - \DeclareUnicodeCharacter{1EF4}{\udotaccent{Y}} - - \DeclareUnicodeCharacter{1EF8}{\~Y} - \DeclareUnicodeCharacter{1EF9}{\~y} - - \DeclareUnicodeCharacter{2013}{--} - \DeclareUnicodeCharacter{2014}{---} - \DeclareUnicodeCharacter{2018}{\quoteleft} - \DeclareUnicodeCharacter{2019}{\quoteright} - \DeclareUnicodeCharacter{201A}{\quotesinglbase} - \DeclareUnicodeCharacter{201C}{\quotedblleft} - \DeclareUnicodeCharacter{201D}{\quotedblright} - \DeclareUnicodeCharacter{201E}{\quotedblbase} - \DeclareUnicodeCharacter{2022}{\bullet} - \DeclareUnicodeCharacter{2026}{\dots} - \DeclareUnicodeCharacter{2039}{\guilsinglleft} - \DeclareUnicodeCharacter{203A}{\guilsinglright} - \DeclareUnicodeCharacter{20AC}{\euro} - - \DeclareUnicodeCharacter{2192}{\expansion} - \DeclareUnicodeCharacter{21D2}{\result} - - \DeclareUnicodeCharacter{2212}{\minus} - \DeclareUnicodeCharacter{2217}{\point} - \DeclareUnicodeCharacter{2261}{\equiv} -}% end of \utfeightchardefs +% For native Unicode handling (XeTeX and LuaTeX), +% make the character token expand +% to the sequences given in \unicodechardefs for printing. +\def\DeclareUnicodeCharacterNativeAtU#1#2{% + \def\UTFAtUTmp{#2} + \expandafter\globallet\csname uni:#1\endcsname \UTFAtUTmp +} +% @U command definitions for native Unicode handling (XeTeX and LuaTeX). +\def\nativeunicodechardefsatu{% + \let\DeclareUnicodeCharacter\DeclareUnicodeCharacterNativeAtU + \unicodechardefs +} % US-ASCII character definitions. \def\asciichardefs{% nothing need be done \relax } +% define all Unicode characters we know about, for the sake of @U. +\iftxinativeunicodecapable + \nativeunicodechardefsatu +\else + \utfeightchardefs +\fi + + % Make non-ASCII characters printable again for compatibility with % existing Texinfo documents that may use them, even without declaring a % document encoding. @@ -9708,12 +11305,12 @@ directory should work if nowhere else does.} \advance\vsize by \topskip \outervsize = \vsize \advance\outervsize by 2\topandbottommargin - \pageheight = \vsize + \txipageheight = \vsize % \hsize = #2\relax \outerhsize = \hsize \advance\outerhsize by 0.5in - \pagewidth = \hsize + \txipagewidth = \hsize % \normaloffset = #4\relax \bindingoffset = #5\relax @@ -9725,6 +11322,14 @@ directory should work if nowhere else does.} % whatever layout pdftex was dumped with. \pdfhorigin = 1 true in \pdfvorigin = 1 true in + \else + \ifx\XeTeXrevision\thisisundefined + \special{papersize=#8,#7}% + \else + \pdfpageheight #7\relax + \pdfpagewidth #8\relax + % XeTeX does not have \pdfhorigin and \pdfvorigin. + \fi \fi % \setleading{\textleading} @@ -9757,7 +11362,6 @@ directory should work if nowhere else does.} % \lispnarrowing = 0.3in \tolerance = 700 - \hfuzz = 1pt \contentsrightmargin = 0pt \defbodyindent = .5cm }} @@ -9775,7 +11379,6 @@ directory should work if nowhere else does.} % \lispnarrowing = 0.25in \tolerance = 700 - \hfuzz = 1pt \contentsrightmargin = 0pt \defbodyindent = .4cm }} @@ -9801,7 +11404,6 @@ directory should work if nowhere else does.} {297mm}{210mm}% % \tolerance = 700 - \hfuzz = 1pt \contentsrightmargin = 0pt \defbodyindent = 5mm }} @@ -9820,7 +11422,6 @@ directory should work if nowhere else does.} % \lispnarrowing = 0.2in \tolerance = 800 - \hfuzz = 1.2pt \contentsrightmargin = 0pt \defbodyindent = 2mm \tableindent = 12mm @@ -9862,9 +11463,11 @@ directory should work if nowhere else does.} % \dimen0 = #1\relax \advance\dimen0 by \voffset + \advance\dimen0 by 1in % reference point for DVI is 1 inch from top of page % \dimen2 = \hsize \advance\dimen2 by \normaloffset + \advance\dimen2 by 1in % reference point is 1 inch from left edge of page % \internalpagesizes{#1}{\hsize}% {\voffset}{\normaloffset}% @@ -9876,6 +11479,9 @@ directory should work if nowhere else does.} % \letterpaper +% Default value of \hfuzz, for suppressing warnings about overfull hboxes. +\hfuzz = 1pt + \message{and turning on texinfo input format.} @@ -9912,44 +11518,47 @@ directory should work if nowhere else does.} % this is not a problem. \def\ifusingit#1#2{\ifdim \fontdimen1\font>0pt #1\else #2\fi} -% Turn off all special characters except @ -% (and those which the user can use as if they were ordinary). +% Set catcodes for Texinfo file + +% Active characters for printing the wanted glyph. % Most of these we simply print from the \tt font, but for some, we can % use math or other variants that look better in normal text. - +% \catcode`\"=\active \def\activedoublequote{{\tt\char34}} \let"=\activedoublequote -\catcode`\~=\active -\def~{{\tt\char126}} -\chardef\hat=`\^ -\catcode`\^=\active -\def^{{\tt \hat}} +\catcode`\~=\active \def\activetilde{{\tt\char126}} \let~ = \activetilde +\chardef\hatchar=`\^ +\catcode`\^=\active \def\activehat{{\tt \hatchar}} \let^ = \activehat \catcode`\_=\active \def_{\ifusingtt\normalunderscore\_} -\let\realunder=_ -% Subroutine for the previous macro. \def\_{\leavevmode \kern.07em \vbox{\hrule width.3em height.1ex}\kern .07em } +\let\realunder=_ + +\catcode`\|=\active \def|{{\tt\char124}} -\catcode`\|=\active -\def|{{\tt\char124}} \chardef \less=`\< -\catcode`\<=\active -\def<{{\tt \less}} +\catcode`\<=\active \def\activeless{{\tt \less}}\let< = \activeless \chardef \gtr=`\> -\catcode`\>=\active -\def>{{\tt \gtr}} -\catcode`\+=\active -\def+{{\tt \char 43}} -\catcode`\$=\active -\def${\ifusingit{{\sl\$}}\normaldollar}%$ font-lock fix +\catcode`\>=\active \def\activegtr{{\tt \gtr}}\let> = \activegtr +\catcode`\+=\active \def+{{\tt \char 43}} +\catcode`\$=\active \def${\ifusingit{{\sl\$}}\normaldollar}%$ font-lock fix +\catcode`\-=\active \let-=\normaldash -% If a .fmt file is being used, characters that might appear in a file -% name cannot be active until we have parsed the command line. -% So turn them off again, and have \everyjob (or @setfilename) turn them on. -% \otherifyactive is called near the end of this file. -\def\otherifyactive{\catcode`+=\other \catcode`\_=\other} + +% used for headline/footline in the output routine, in case the page +% breaks in the middle of an @tex block. +\def\texinfochars{% + \let< = \activeless + \let> = \activegtr + \let~ = \activetilde + \let^ = \activehat + \markupsetuplqdefault \markupsetuprqdefault + \let\b = \strong + \let\i = \smartitalic + % in principle, all other definitions in \tex have to be undone too. +} % Used sometimes to turn off (effectively) the active characters even after % parsing them. @@ -9969,23 +11578,22 @@ directory should work if nowhere else does.} % \doublebackslash is two of them (for the pdf outlines). {\catcode`\\=\other @gdef@realbackslash{\} @gdef@doublebackslash{\\}} -% In texinfo, backslash is an active character; it prints the backslash +% In Texinfo, backslash is an active character; it prints the backslash % in fixed width font. \catcode`\\=\active % @ for escape char from now on. -% The story here is that in math mode, the \char of \backslashcurfont -% ends up printing the roman \ from the math symbol font (because \char -% in math mode uses the \mathcode, and plain.tex sets -% \mathcode`\\="026E). It seems better for @backslashchar{} to always -% print a typewriter backslash, hence we use an explicit \mathchar, +% Print a typewriter backslash. For math mode, we can't simply use +% \backslashcurfont: the story here is that in math mode, the \char +% of \backslashcurfont ends up printing the roman \ from the math symbol +% font (because \char in math mode uses the \mathcode, and plain.tex +% sets \mathcode`\\="026E). Hence we use an explicit \mathchar, % which is the decimal equivalent of "715c (class 7, e.g., use \fam; % ignored family value; char position "5C). We can't use " for the % usual hex value because it has already been made active. -@def@normalbackslash{{@tt @ifmmode @mathchar29020 @else @backslashcurfont @fi}} -@let@backslashchar = @normalbackslash % @backslashchar{} is for user documents. -% On startup, @fixbackslash assigns: -% @let \ = @normalbackslash +@def@ttbackslash{{@tt @ifmmode @mathchar29020 @else @backslashcurfont @fi}} +@let@backslashchar = @ttbackslash % @backslashchar{} is for user documents. + % \rawbackslash defines an active \ to do \backslashcurfont. % \otherbackslash defines an active \ to be a literal `\' character with % catcode other. We switch back and forth between these. @@ -9993,51 +11601,93 @@ directory should work if nowhere else does.} @gdef@otherbackslash{@let\=@realbackslash} % Same as @turnoffactive except outputs \ as {\tt\char`\\} instead of -% the literal character `\'. Also revert - to its normal character, in -% case the active - from code has slipped in. +% the literal character `\'. % {@catcode`- = @active @gdef@normalturnoffactive{% + @passthroughcharstrue @let-=@normaldash @let"=@normaldoublequote @let$=@normaldollar %$ font-lock fix @let+=@normalplus @let<=@normalless @let>=@normalgreater - @let\=@normalbackslash @let^=@normalcaret @let_=@normalunderscore @let|=@normalverticalbar @let~=@normaltilde + @let\=@ttbackslash @markupsetuplqdefault @markupsetuprqdefault @unsepspaces } } -% Make _ and + \other characters, temporarily. -% This is canceled by @fixbackslash. -@otherifyactive +% If a .fmt file is being used, characters that might appear in a file +% name cannot be active until we have parsed the command line. +% So turn them off again, and have @fixbackslash turn them back on. +@catcode`+=@other @catcode`@_=@other +% \enablebackslashhack - allow file to begin `\input texinfo' +% % If a .fmt file is being used, we don't want the `\input texinfo' to show up. % That is what \eatinput is for; after that, the `\' should revert to printing % a backslash. -% -@gdef@eatinput input texinfo{@fixbackslash} -@global@let\ = @eatinput +% If the file did not have a `\input texinfo', then it is turned off after +% the first line; otherwise the first `\' in the file would cause an error. +% This is used on the very last line of this file, texinfo.tex. +% We also use @c to call @fixbackslash, in case ends of lines are hidden. +{ +@catcode`@^=7 +@catcode`@^^M=13@gdef@enablebackslashhack{% + @global@let\ = @eatinput% + @catcode`@^^M=13% + @def@c{@fixbackslash@c}% + % Definition for the newline at the end of this file. + @def ^^M{@let^^M@secondlinenl}% + % Definition for a newline in the main Texinfo file. + @gdef @secondlinenl{@fixbackslash}% + % In case the first line has a whole-line command on it + @let@originalparsearg@parsearg + @def@parsearg{@fixbackslash@originalparsearg} +}} + +{@catcode`@^=7 @catcode`@^^M=13% +@gdef@eatinput input texinfo#1^^M{@fixbackslash}} + +% Emergency active definition of newline, in case an active newline token +% appears by mistake. +{@catcode`@^=7 @catcode13=13% +@gdef@enableemergencynewline{% + @gdef^^M{% + @par% + %@par% +}}} + -% On the other hand, perhaps the file did not have a `\input texinfo'. Then -% the first `\' in the file would cause an error. This macro tries to fix -% that, assuming it is called before the first `\' could plausibly occur. -% Also turn back on active characters that might appear in the input -% file name, in case not using a pre-dumped format. -% @gdef@fixbackslash{% - @ifx\@eatinput @let\ = @normalbackslash @fi + @ifx\@eatinput @let\ = @ttbackslash @fi + @catcode13=5 % regular end of line + @enableemergencynewline + @let@c=@texinfoc + @let@parsearg@originalparsearg + % Also turn back on active characters that might appear in the input + % file name, in case not using a pre-dumped format. @catcode`+=@active @catcode`@_=@active + % + % If texinfo.cnf is present on the system, read it. + % Useful for site-wide @afourpaper, etc. This macro, @fixbackslash, gets + % called at the beginning of every Texinfo file. Not opening texinfo.cnf + % directly in this file, texinfo.tex, makes it possible to make a format + % file for Texinfo. + % + @openin 1 texinfo.cnf + @ifeof 1 @else @input texinfo.cnf @fi + @closein 1 } + % Say @foo, not \foo, in error messages. @escapechar = `@@ @@ -10066,7 +11716,7 @@ directory should work if nowhere else does.} @c Local variables: @c eval: (add-hook 'write-file-hooks 'time-stamp) -@c page-delimiter: "^\\\\message" +@c page-delimiter: "^\\\\message\\|emacs-page" @c time-stamp-start: "def\\\\texinfoversion{" @c time-stamp-format: "%:y-%02m-%02d.%02H" @c time-stamp-end: "}" @@ -10074,6 +11724,4 @@ directory should work if nowhere else does.} @c vim:sw=2: -@ignore - arch-tag: e1b36e32-c96e-4135-a41a-0b2efa2ea115 -@end ignore +@enablebackslashhack diff --git a/doc/tinc-gui.8.in b/doc/tinc-gui.8.in index f5ebadb..e554a85 100644 --- a/doc/tinc-gui.8.in +++ b/doc/tinc-gui.8.in @@ -30,7 +30,7 @@ Use the cookie from .Ar FILENAME to authenticate with a running tinc daemon. If unspecified, the default is -.Pa @localstatedir@/run/tinc. Ns Ar NETNAME Ns Pa .pid. +.Pa @runstatedir@/tinc. Ns Ar NETNAME Ns Pa .pid. .It Fl -help Display short list of options. .El diff --git a/doc/tinc.8.in b/doc/tinc.8.in index 6644add..aaa3547 100644 --- a/doc/tinc.8.in +++ b/doc/tinc.8.in @@ -7,10 +7,11 @@ .Nd tinc VPN control .Sh SYNOPSIS .Nm -.Op Fl cn +.Op Fl bcn .Op Fl -config Ns = Ns Ar DIR .Op Fl -net Ns = Ns Ar NETNAME .Op Fl -pidfile Ns = Ns Ar FILENAME +.Op Fl -batch .Op Fl -force .Op Fl -help .Op Fl -version @@ -54,7 +55,9 @@ Use the cookie from .Ar FILENAME to authenticate with a running tinc daemon. If unspecified, the default is -.Pa @localstatedir@/run/tinc. Ns Ar NETNAME Ns Pa .pid. +.Pa @runstatedir@/tinc. Ns Ar NETNAME Ns Pa .pid. +.It Fl b, -batch +Don't ask for anything (non-interactive mode). .It Fl -force Force some commands to work despite warnings. .It Fl -help @@ -249,7 +252,7 @@ to allow a signature from any node whose public key is known. If no .Ar filename is given, the file is read from standard input. -If the verification is succesful, +If the verification is successful, a copy of the input with the signature removed is written to standard output, and the exit code will be zero. If the verification failed, diff --git a/doc/tinc.conf.5.in b/doc/tinc.conf.5.in index cb7d1b1..6897ba6 100644 --- a/doc/tinc.conf.5.in +++ b/doc/tinc.conf.5.in @@ -114,7 +114,7 @@ If .Qq any is selected, then depending on the operating system both IPv4 and IPv6 or just IPv6 listening sockets will be created. -.It Va AutoConnect Li = yes | no Po no Pc Bq experimental +.It Va AutoConnect Li = yes | no Po yes If set to yes, .Nm tinc will automatically set up meta connections to other nodes, @@ -177,7 +177,7 @@ line). .Pp If you don't specify a host with .Va ConnectTo -and don't enable +and have disabled .Va AutoConnect , .Nm tinc won't try to connect to other daemons at all, @@ -242,7 +242,7 @@ Packets received for the local node are written to it. Create a UNIX socket with the filename specified by .Va Device , or -.Pa @localstatedir@/run/ Ns Ar NETNAME Ns Pa .umlsocket +.Pa @runstatedir@/ Ns Ar NETNAME Ns Pa .umlsocket if not specified. .Nm tinc will wait for a User Mode Linux instance to connect to this socket. @@ -251,7 +251,7 @@ Uses the libvdeplug library to connect to a Virtual Distributed Ethernet switch, using the UNIX socket specified by .Va Device , or -.Pa @localstatedir@/run/vde.ctl +.Pa @runstatedir@/vde.ctl if not specified. .El Also, in case tinc does not seem to correctly interpret packets received from the virtual network device, @@ -306,10 +306,16 @@ Incoming packets that are meant for another node are forwarded by tinc internall .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. +Incoming packets using the legacy protocol 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. +Incoming packets using the SPTPS protocol are dropped, since they are end-to-end encrypted. .El +.It Va FWMark Li = Ar value Po 0 Pc Bq experimental +When set to a non-zero value, all TCP and UDP sockets created by tinc will use the given value as the firewall mark. +This can be used for mark-based routing or for packet filtering. +This option is currently only supported on Linux. .It Va Hostnames Li = yes | no Pq no This option selects whether IP addresses (both real and on the VPN) should be resolved. Since DNS lookups are blocking, it might affect tinc's @@ -786,7 +792,7 @@ its connection to the virtual network device. .It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /invitations/ This directory contains outstanding invitations. .It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /invitation-data -After a succesful join, this file contains a copy of the invitation data received. +After a successful join, this file contains a copy of the invitation data received. .El .Sh SEE ALSO .Xr tincd 8 , diff --git a/doc/tinc.info b/doc/tinc.info index 419de73..86f8682 100644 --- a/doc/tinc.info +++ b/doc/tinc.info @@ -1,14 +1,14 @@ -This is tinc.info, produced by makeinfo version 6.4.90 from tinc.texi. +This is tinc.info, produced by makeinfo version 6.5 from tinc.texi. INFO-DIR-SECTION Networking tools START-INFO-DIR-ENTRY * tinc: (tinc). The tinc Manual. END-INFO-DIR-ENTRY -This is the info manual for tinc version 1.1pre14-62-g958a751e, a -Virtual Private Network daemon. +This is the info manual for tinc version 1.1pre17, a Virtual Private +Network daemon. - Copyright (C) 1998-2017 Ivo Timmermans, Guus Sliepen + Copyright (C) 1998-2018 Ivo Timmermans, Guus Sliepen and Wessel Dankers . Permission is granted to make and distribute verbatim copies of this @@ -119,7 +119,7 @@ both the receiving and sending end, it has become largely runtime-configurable--in short, it has become a full-fledged professional package. -Tinc also allows more than two sites to connect to eachother and form a +Tinc also allows more than two sites to connect to each other and form a single VPN. Traditionally VPNs are created by making tunnels, which only have two endpoints. Larger VPNs with more sites are created by adding more tunnels. Tinc takes another approach: only endpoints are @@ -285,7 +285,7 @@ File: tinc.info, Node: Libraries, Prev: Configuring the kernel, Up: Preparati ============= Before you can configure or build tinc, you need to have the LibreSSL or -OpenSSL, zlib, lzo, curses and readline libraries installed on your +OpenSSL, zlib, LZO, curses and readline libraries installed on your system. If you try to configure tinc without having them installed, configure will give you an error message, and stop. @@ -293,7 +293,7 @@ configure will give you an error message, and stop. * LibreSSL/OpenSSL:: * zlib:: -* lzo:: +* LZO:: * libcurses:: * libreadline:: @@ -306,7 +306,7 @@ File: tinc.info, Node: LibreSSL/OpenSSL, Next: zlib, Up: Libraries For all cryptography-related functions, tinc uses the functions provided by the LibreSSL or the OpenSSL library. -If this library is not installed, you wil get an error when configuring +If this library is not installed, you will get an error when configuring tinc for build. Support for running tinc with other cryptographic libraries installed _may_ be added in the future. @@ -316,7 +316,7 @@ of this package. If your operating system comes neither with LibreSSL or OpenSSL, you have to install one manually. It is recommended that you get the latest -version of LibreSSL from . Instructions on +version of LibreSSL from . Instructions on how to configure, build and install this package are included within the package. Please make sure you build development and runtime libraries (which is the default). @@ -357,7 +357,7 @@ present the following exemption: Markus F.X.J. Oberhumer  -File: tinc.info, Node: zlib, Next: lzo, Prev: LibreSSL/OpenSSL, Up: Libraries +File: tinc.info, Node: zlib, Next: LZO, Prev: LibreSSL/OpenSSL, Up: Libraries 2.2.2 zlib ---------- @@ -365,7 +365,7 @@ File: tinc.info, Node: zlib, Next: lzo, Prev: LibreSSL/OpenSSL, Up: Librarie For the optional compression of UDP packets, tinc uses the functions provided by the zlib library. -If this library is not installed, you wil get an error when running the +If this library is not installed, you will get an error when running the configure script. You can either install the zlib library, or disable support for zlib compression by using the "-disable-zlib" option when running the configure script. Note that if you disable support for @@ -377,19 +377,19 @@ available. Make sure you install the development AND runtime versions of this package. If you have to install zlib manually, you can get the source code from -. Instructions on how to configure, build and +. Instructions on how to configure, build and install this package are included within the package. Please make sure you build development and runtime libraries (which is the default).  -File: tinc.info, Node: lzo, Next: libcurses, Prev: zlib, Up: Libraries +File: tinc.info, Node: LZO, Next: libcurses, Prev: zlib, Up: Libraries -2.2.3 lzo +2.2.3 LZO --------- Another form of compression is offered using the LZO library. -If this library is not installed, you wil get an error when running the +If this library is not installed, you will get an error when running the configure script. You can either install the LZO library, or disable support for LZO compression by using the "-disable-lzo" option when running the configure script. Note that if you disable support for LZO, @@ -400,29 +400,29 @@ You can use your operating system's package manager to install this if available. Make sure you install the development AND runtime versions of this package. -If you have to install lzo manually, you can get the source code from +If you have to install LZO manually, you can get the source code from . Instructions on how to configure, build and install this package are included within the package. Please make sure you build development and runtime libraries (which is the default).  -File: tinc.info, Node: libcurses, Next: libreadline, Prev: lzo, Up: Libraries +File: tinc.info, Node: libcurses, Next: libreadline, Prev: LZO, Up: Libraries 2.2.4 libcurses --------------- For the "tinc top" command, tinc requires a curses library. -If this library is not installed, you wil get an error when running the +If this library is not installed, you will get an error when running the configure script. You can either install a suitable curses library, or disable all functionality that depends on a curses library by using the "-disable-curses" option when running the configure script. There are several curses libraries. It is recommended that you install -"ncurses" (), however other curses -libraries should also work. In particular, "PDCurses" -() is recommended if you want to +"ncurses" (), however other +curses libraries should also work. In particular, "PDCurses" +() is recommended if you want to compile tinc for Windows. You can use your operating system's package manager to install this if @@ -438,7 +438,7 @@ File: tinc.info, Node: libreadline, Prev: libcurses, Up: Libraries For the "tinc" command's shell functionality, tinc uses the readline library. -If this library is not installed, you wil get an error when running the +If this library is not installed, you will get an error when running the configure script. You can either install a suitable readline library, or disable all functionality that depends on a readline library by using the "-disable-readline" option when running the configure script. @@ -448,7 +448,7 @@ available. Make sure you install the development AND runtime versions of this package. If you have to install libreadline manually, you can get the source code -from . Instructions on how to +from . Instructions on how to configure, build and install this package are included within the package. Please make sure you build development and runtime libraries (which is the default). @@ -625,7 +625,7 @@ Do you want to run tinc in router mode or switch mode? These questions can only be answered by yourself, you will not find the answers in this documentation. Make sure you have an adequate understanding of networks in general. A good resource on networking is the Linux Network -Administrators Guide (http://www.tldp.org/LDP/nag2/). +Administrators Guide (https://www.tldp.org/LDP/nag2/). If you have everything clearly pictured in your mind, proceed in the following order: First, create the initial configuration files and @@ -651,7 +651,7 @@ assign a NETNAME to your VPN. It is not required if you only run one tinc daemon, it doesn't even have to be the same on all the nodes of your VPN, but it is recommended that you choose one anyway. -We will asume you use a netname throughout this document. This means +We will assume you use a netname throughout this document. This means that you call tinc with the -n argument, which will specify the netname. The effect of this option is that tinc will set its configuration root @@ -675,22 +675,17 @@ File: tinc.info, Node: How connections work, Next: Configuration files, Prev: ======================== When tinc starts up, it parses the command-line options and then reads -in the configuration file tinc.conf. If it sees one or more 'ConnectTo' -values pointing to other tinc daemons in that file, it will try to -connect to those other daemons. Whether this succeeds or not and -whether 'ConnectTo' is specified or not, tinc will listen for incoming -connection from other deamons. If you did specify a 'ConnectTo' value -and the other side is not responding, tinc will keep retrying. This -means that once started, tinc will stay running until you tell it to -stop, and failures to connect to other tinc daemons will not stop your -tinc daemon for trying again later. This means you don't have to -intervene if there are temporary network problems. +in the configuration file tinc.conf. It will then start listening for +incoming connection from other daemons, and will by default also +automatically try to connect to known peers. By default, tinc will try +to keep at least 3 working meta-connections alive at all times. There is no real distinction between a server and a client in tinc. If -you wish, you can view a tinc daemon without a 'ConnectTo' value as a -server, and one which does specify such a value as a client. It does -not matter if two tinc daemons have a 'ConnectTo' value pointing to each -other however. +you wish, you can view a tinc daemon without a 'ConnectTo' statement in +tinc.conf and 'AutoConnect = no' as a server, and one which does have +one or more 'ConnectTo' statements or 'Autoconnect = yes' (which is the +default) as a client. It does not matter if two tinc daemons have a +'ConnectTo' value pointing to each other however. Connections specified using 'ConnectTo' are so-called meta-connections. Tinc daemons exchange information about all other daemon they know about @@ -712,7 +707,7 @@ might also prevent direct communication. In that case, VPN packets between A and C will be forwarded by B. In effect, all nodes in the VPN will be able to talk to each other, as -long as their is a path of meta-connections between them, and whenever +long as there is a path of meta-connections between them, and whenever possible, two nodes will communicate with each other directly.  @@ -725,8 +720,8 @@ The actual configuration of the daemon is done in the file '/etc/tinc/NETNAME/tinc.conf' and at least one other file in the directory '/etc/tinc/NETNAME/hosts/'. -An optionnal directory '/etc/tinc/NETNAME/conf.d' can be added from -which any .conf file will be read. +An optional directory '/etc/tinc/NETNAME/conf.d' can be added from which +any .conf file will be read. These file consists of comments (lines started with a #) or assignments in the form of @@ -771,7 +766,7 @@ AddressFamily = (any) system both IPv4 and IPv6 or just IPv6 listening sockets will be created. -AutoConnect = (no) [experimental] +AutoConnect = (yes) If set to yes, tinc will automatically set up meta connections to other nodes, without requiring CONNECTTO variables. @@ -831,7 +826,7 @@ ConnectTo = names should be known to this tinc daemon (i.e., there should be a host configuration file for the name on the ConnectTo line). - If you don't specify a host with ConnectTo and don't enable + If you don't specify a host with ConnectTo and have disabled AutoConnect, tinc won't try to connect to other daemons at all, and will instead just listen for incoming connections. @@ -966,16 +961,24 @@ Forwarding = (internal) [experimental] 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. + Incoming packets using the legacy protocol 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. Incoming packets using the SPTPS protocol are + dropped, since they are end-to-end encrypted. + +FWMark = (0) [experimental] + When set to a non-zero value, all TCP and UDP sockets created by + tinc will use the given value as the firewall mark. This can be + used for mark-based routing or for packet filtering. This option + is currently only supported on Linux. Hostnames = (no) This option selects whether IP addresses (both real and on the VPN) should be resolved. Since DNS lookups are blocking, it might affect tinc's efficiency, even stopping the daemon for a few - seconds everytime it does a lookup if your DNS server is not + seconds every time it does a lookup if your DNS server is not responding. This does not affect resolving hostnames to IP addresses from the @@ -1093,7 +1096,7 @@ PriorityInheritance = (no) [experimental] PrivateKey = [obsolete] This is the RSA private key for tinc. However, for safety reasons it is advised to store private keys of any kind in separate files. - This prevents accidental eavesdropping if you are editting the + This prevents accidental eavesdropping if you are editing the configuration file. PrivateKeyFile = ('/etc/tinc/NETNAME/rsa_key.priv') @@ -1243,7 +1246,7 @@ ClampMSS = (yes) 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 - (best zlib), 10 (fast lzo) and 11 (best lzo). + (best zlib), 10 (fast LZO) and 11 (best LZO). Digest = (sha1) The digest algorithm used to authenticate UDP packets using the @@ -1299,9 +1302,9 @@ PublicKeyFile = [obsolete] Subnet = The subnet which this tinc daemon will serve. Tinc tries to look up which other daemon it should send a packet to by searching the - appropiate subnet. If the packet matches a subnet, it will be sent - to the daemon who has this subnet in his host configuration file. - Multiple subnet lines can be specified for each daemon. + appropriate subnet. If the packet matches a subnet, it will be + sent to the daemon who has this subnet in his host configuration + file. Multiple subnet lines can be specified for each daemon. Subnets can either be single MAC, IPv4 or IPv6 addresses, in which case a subnet consisting of only that single address is assumed, or @@ -1513,26 +1516,14 @@ run: tinc -n NETNAME add address foo.example.org -If you already know to which daemons your daemon should make -meta-connections, you should configure that now as well. Suppose you -want to connect to a daemon named "bar", run: - - tinc -n NETNAME add connectto bar - -Note that you specify the Name of the other daemon here, not an IP -address or hostname! When you start tinc, and it tries to make a -connection to "bar", it will look for a host configuration file named -'hosts/bar', and will read Address statements and public keys from that -file. - Step 2. Exchanging configuration files. ....................................... -If your daemon has a ConnectTo = bar statement in its 'tinc.conf' file, -or if bar has a ConnectTo your daemon, then you both need each other's -host configuration files. You should send 'hosts/NAME' to bar, and bar -should send you his file which you should move to 'hosts/bar'. If you -are on a UNIX platform, you can easily send an email containing the +In order for two tinc daemons to be able to connect to each other, they +each need the other's host configuration files. So if you want foo to +be able to connect with bar, You should send 'hosts/NAME' to bar, and +bar should send you his file which you should move to 'hosts/bar'. If +you are on a UNIX platform, you can easily send an email containing the necessary information using the following command (assuming the owner of bar has the email address bar@example.org): @@ -1552,10 +1543,9 @@ following command: | ssh bar.example.org tinc -n NETNAME exchange \ | tinc -n NETNAME import -You should repeat this for all nodes you ConnectTo, or which ConnectTo -you. However, remember that you do not need to ConnectTo all nodes in -the VPN; it is only necessary to create one or a few meta-connections, -after the connections are made tinc will learn about all the other nodes +You can repeat this for a few other nodes as well. It is not necessary +to manually exchange host config files between all nodes; after the +initial connections are made tinc will learn about all the other nodes in the VPN, and will automatically make other connections as necessary.  @@ -1692,11 +1682,9 @@ In '/etc/tinc/company/tinc-up': and in '/etc/tinc/company/tinc.conf': Name = BranchB - ConnectTo = BranchA Note here that the internal address (on eth0) doesn't have to be the -same as on the VPN interface. Also, ConnectTo is given so that this -node will always try to connect to BranchA. +same as on the VPN interface. On all hosts, in '/etc/tinc/company/hosts/BranchB': @@ -1722,7 +1710,6 @@ In '/etc/tinc/company/tinc-up': and in '/etc/tinc/company/tinc.conf': Name = BranchC - ConnectTo = BranchA C already has another daemon that runs on port 655, so they have to reserve another port for tinc. It knows the portnumber it has to listen @@ -1753,7 +1740,6 @@ In '/etc/tinc/company/tinc-up': and in '/etc/tinc/company/tinc.conf': Name = BranchD - ConnectTo = BranchC D will be connecting to C, which has a tincd running for this network on port 2000. It knows the port number from the host configuration file. @@ -1861,6 +1847,9 @@ command line options. facility. If FILE is omitted, the default is '/var/log/tinc.NETNAME.log'. +'--pidfile=FILE' + Write PID to FILE instead of '/var/run/tinc.NETNAME.pid'. + '--bypass-security' Disables encryption and authentication. Only useful for debugging. @@ -1871,12 +1860,16 @@ command line options. chroot is performed after all the initialization is done, after writing pid files and opening network sockets. - Note that this option alone does not do any good without -U/-user, - below. + This option is best used in combination with the -U/-user option + described below. - Note also that tinc can't run scripts anymore (such as tinc-down or - host-up), unless it's setup to be runnable inside chroot - environment. + You will need to ensure the chroot environment contains all the + files necessary for tinc to run correctly. Most importantly, for + tinc to be able to resolve hostnames inside the chroot environment, + you must copy '/etc/resolv.conf' into the chroot directory. If you + want to be able to run scripts other than 'tinc-up' in the chroot, + you must ensure the appropriate shell is also installed in the + chroot, along with all its dependencies. This option is not supported on all platforms. '-U, --user=USER' @@ -2150,6 +2143,9 @@ File: tinc.info, Node: tinc runtime options, Next: tinc environment variables, daemon. If unspecified, the default is '/var/run/tinc.NETNAME.pid'. +'-b, --batch' + Don't ask for anything (non-interactive mode). + '--force' Force some commands to work despite warnings. @@ -2353,8 +2349,8 @@ File: tinc.info, Node: tinc commands, Next: tinc examples, Prev: tinc environ NAME of the node must be given, or can be "." to check against the local node's public key, or "*" to allow a signature from any node whose public key is known. If no FILENAME is given, the file is - read from standard input. If the verification is succesful, a copy - of the input with the signature removed is written to standard + read from standard input. If the verification is successful, a + copy of the input with the signature removed is written to standard output, and the exit code will be zero. If the verification failed, nothing will be written to standard output, and the exit code will be non-zero. @@ -2376,7 +2372,7 @@ Examples of changing the configuration using tinc: tinc -n vpn init foo tinc -n vpn add Subnet 192.168.1.0/24 tinc -n vpn add bar.Address bar.example.com - tinc -n vpn add ConnectTo bar + tinc -n vpn set Mode switch tinc -n vpn export | gpg --clearsign | mail -s "My config" vpnmaster@example.com  @@ -2400,7 +2396,7 @@ can be changed using the following keys: Toggle between displaying current traffic rates (in packets and - bytes per second) and cummulative traffic (total packets and bytes + bytes per second) and cumulative traffic (total packets and bytes since the tinc daemon started). @@ -2528,7 +2524,8 @@ invite' command looks like this: The file is basically a concatenation of several host config blocks. Each host config block starts with 'Name = ...'. Lines that look like '#---#' are not important, it just makes it easier for humans to read -the file. +the file. However, the first line of an invitation file _must_ always +start with 'Name = ...'. The first host config block is always the one representing the invitee. So the first Name statement determines the name that the invitee will @@ -2582,7 +2579,7 @@ When an invitation is generated, the "invitation-created" script is called (if it exists) right after the invitation file is written, but before the URL has been written to stdout. This allows one to change the invitation file automatically before the invitation URL is passed to -the invitee. Here is an example shell script that aproximately +the invitee. Here is an example shell script that approximately recreates the default invitation file: #!/bin/sh @@ -2684,8 +2681,7 @@ correct destination MAC address. In those modes every interface should have a unique MAC address, so make sure they are not the same. Because switch and hub modes rely on MAC addresses to function correctly, these modes cannot be used on the following operating systems which don't have -a 'tap' style virtual network device: OpenBSD, NetBSD, Darwin and -Solaris. +a 'tap' style virtual network device: NetBSD, Darwin and Solaris.  File: tinc.info, Node: The meta-connection, Prev: The UDP tunnel, Up: The connection @@ -3189,14 +3185,29 @@ too short, and he doesn't like tinc's use of RSA during authentication. We do not know of a security hole in the legacy protocol of tinc, but it is not as strong as TLS or IPsec. +The Sweet32 attack affects versions of tinc prior to 1.0.30. + +On September 6th, 2018, Michael Yonly contacted us and provided +proof-of-concept code that allowed a remote attacker to create an +authenticated, one-way connection with a node, and also that there was a +possibility for a man-in-the-middle to force UDP packets from a node to +be sent in plaintext. The first issue was trivial to exploit on tinc +versions prior to 1.0.30, but the changes in 1.0.30 to mitigate the +Sweet32 attack made this weakness much harder to exploit. These issues +have been fixed in tinc 1.0.35. + This version of tinc comes with an improved protocol, called Simple -Peer-to-Peer Security, which aims to be as strong as TLS with one of the -strongest cipher suites. +Peer-to-Peer Security (SPTPS), which aims to be as strong as TLS with +one of the strongest cipher suites. None of the above security issues +affected SPTPS. However, be aware that SPTPS is only used between nodes +running tinc 1.1pre* or later, and in a VPN with nodes running different +versions, the security might only be as good as that of the oldest +version. Cryptography is a hard thing to get right. We cannot make any guarantees. Time, review and feedback are the only things that can prove the security of any cryptographic product. If you wish to review -tinc or give us feedback, you are stronly encouraged to do so. +tinc or give us feedback, you are strongly encouraged to do so.  File: tinc.info, Node: Platform specific information, Next: About us, Prev: Technical information, Up: Top @@ -3208,6 +3219,7 @@ File: tinc.info, Node: Platform specific information, Next: About us, Prev: T * Interface configuration:: * Routes:: +* Automatically starting tinc::  File: tinc.info, Node: Interface configuration, Next: Routes, Up: Platform specific information @@ -3246,11 +3258,6 @@ Solaris 'ifconfig' INTERFACE 'inet6 plumb up' Darwin (MacOS/X) 'ifconfig' INTERFACE 'inet6' ADDRESS 'prefixlen' PREFIXLENGTH Windows 'netsh interface ipv6 add address' INTERFACE 'static' ADDRESS/PREFIXLENGTH -On some platforms, when running tinc in switch mode, the VPN interface -must be set to tap mode with an ifconfig command: - -OpenBSD 'ifconfig' INTERFACE 'link0' - On Linux, it is possible to create a persistent tun/tap interface which will continue to exist even if tinc quit, although this is normally not required. It can be useful to set up a tun/tap interface owned by a @@ -3260,7 +3267,7 @@ privileges at all. Linux 'ip tuntap add dev' INTERFACE 'mode' TUN|TAP 'user' USERNAME  -File: tinc.info, Node: Routes, Prev: Interface configuration, Up: Platform specific information +File: tinc.info, Node: Routes, Next: Automatically starting tinc, Prev: Interface configuration, Up: Platform specific information 9.2 Routes ========== @@ -3295,6 +3302,72 @@ Solaris 'route add -inet6' NETWORK_ADDRESS'/'PREFIXLENGTH LOCAL_ADDRE Darwin (MacOS/X) ? Windows 'netsh interface ipv6 add route' NETWORK ADDRESS/PREFIXLENGTH INTERFACE + +File: tinc.info, Node: Automatically starting tinc, Prev: Routes, Up: Platform specific information + +9.3 Automatically starting tinc +=============================== + +* Menu: + +* Linux:: +* Windows:: +* Other platforms:: + + +File: tinc.info, Node: Linux, Next: Windows, Up: Automatically starting tinc + +9.3.1 Linux +----------- + +There are many Linux distributions, and historically, many of them had +their own way of starting programs at boot time. Today, a number of +major Linux distributions have chosen to use systemd as their init +system. Tinc ships with systemd service files that allow you to start +and stop tinc using systemd. There are two service files: +'tinc.service' is used to globally enable or disable all tinc daemons +managed by systemd, and 'tinc@NETNAME.service' is used to enable or +disable specific tinc daemons. So if one has created a tinc network +with netname 'foo', then you have to run the following two commands to +ensure it is started at boot time: + + systemctl enable tinc + systemctl enable tinc@foo + +To start the tinc daemon immediately if it wasn't already running, use +the following command: + + systemctl start tinc@foo + +You can also use 'systemctl start tinc', this will start all tinc +daemons that are enabled. You can stop and disable tinc networks in the +same way. + +If your system is not using systemd, then you have to look up your +distribution's way of starting tinc at boot time. + + +File: tinc.info, Node: Windows, Next: Other platforms, Prev: Linux, Up: Automatically starting tinc + +9.3.2 Windows +------------- + +On Windows, if tinc is started with the 'tinc start' command without +using the '-D' or '--no-detach' option, it will automatically register +itself as a service that is started at boot time. When tinc is stopped +using the 'tinc stop' command, it will also automatically unregister +itself. Once tinc is registered as a service, it is also possible to +stop and start tinc using the Windows Services Manager. + + +File: tinc.info, Node: Other platforms, Prev: Windows, Up: Automatically starting tinc + +9.3.3 Other platforms +--------------------- + +On platforms other than the ones mentioned in the earlier sections, you +have to look up your platform's way of starting programs at boot time. +  File: tinc.info, Node: About us, Next: Concept Index, Prev: Platform specific information, Up: Top @@ -3354,6 +3427,8 @@ Concept Index * ANS_KEY: The meta-protocol. (line 63) * AutoConnect: Main configuration variables. (line 12) +* batch: tinc runtime options. + (line 18) * binary package: Building and installing tinc. (line 9) * BindToAddress: Main configuration variables. @@ -3376,7 +3451,7 @@ Concept Index * ClampMSS: Host configuration variables. (line 22) * client: How connections work. - (line 18) + (line 12) * command line: Runtime options. (line 9) * command line interface: Controlling tinc. (line 6) * Compression: Host configuration variables. @@ -3422,7 +3497,7 @@ Concept Index * exchange: tinc commands. (line 48) * exchange-all: tinc commands. (line 51) * exec: Main configuration variables. - (line 365) + (line 373) * ExperimentalProtocol: Main configuration variables. (line 185) * export: tinc commands. (line 36) @@ -3433,38 +3508,40 @@ Concept Index (line 192) * frame type: The UDP tunnel. (line 6) * fsck: tinc commands. (line 160) +* FWMark: Main configuration variables. + (line 214) * generate-ed25519-keys: tinc commands. (line 86) * generate-keys: tinc commands. (line 81) * generate-rsa-keys: tinc commands. (line 89) * get: tinc commands. (line 11) * graph: tinc commands. (line 108) * Hostnames: Main configuration variables. - (line 212) + (line 220) * http: Main configuration variables. - (line 362) + (line 370) * hub: Main configuration variables. - (line 280) + (line 288) * ID: Legacy authentication protocol. (line 6) * Ifconfig: Invitation file format. - (line 35) + (line 36) * import: tinc commands. (line 43) * IndirectData: Host configuration variables. (line 40) * info: tinc commands. (line 120) * init: tinc commands. (line 6) * Interface: Main configuration variables. - (line 223) + (line 231) * INTERFACE: Scripts. (line 75) * InvitationExpire: Main configuration variables. - (line 285) + (line 293) * INVITATION_FILE: Scripts. (line 98) * INVITATION_URL: Scripts. (line 102) * invite: tinc commands. (line 54) * IRC: Contact information. (line 9) * join: tinc commands. (line 59) * KeyExpire: Main configuration variables. - (line 288) + (line 296) * KEY_CHANGED: The meta-protocol. (line 63) * legacy authentication protocol: Legacy authentication protocol. (line 6) @@ -3474,31 +3551,31 @@ Concept Index * LibreSSL: LibreSSL/OpenSSL. (line 6) * license: LibreSSL/OpenSSL. (line 38) * ListenAddress: Main configuration variables. - (line 231) + (line 239) * LocalDiscovery: Main configuration variables. - (line 243) + (line 251) * log: tinc commands. (line 130) * LogLevel: Main configuration variables. - (line 254) -* lzo: lzo. (line 6) + (line 262) +* LZO: LZO. (line 6) * MACExpire: Main configuration variables. - (line 294) + (line 302) * MACLength: Host configuration variables. (line 45) * MaxConnectionBurst: Main configuration variables. - (line 299) + (line 307) * meta-protocol: The meta-connection. (line 18) * META_KEY: Legacy authentication protocol. (line 6) * Mode: Main configuration variables. - (line 258) + (line 266) * MTUInfoInterval: Host configuration variables. (line 60) * multicast: Main configuration variables. (line 118) * multiple networks: Multiple networks. (line 6) * Name: Main configuration variables. - (line 305) + (line 313) * NAME: Scripts. (line 69) * netmask: Network interfaces. (line 39) * netname: Multiple networks. (line 6) @@ -3517,9 +3594,9 @@ Concept Index * pid: tinc commands. (line 78) * PING: The meta-protocol. (line 88) * PingInterval: Main configuration variables. - (line 316) + (line 324) * PingTimeout: Main configuration variables. - (line 320) + (line 328) * platforms: Supported platforms. (line 6) * PMTU: Host configuration variables. (line 52) @@ -3530,17 +3607,17 @@ Concept Index (line 65) * port numbers: Other files. (line 17) * PriorityInheritance: Main configuration variables. - (line 326) + (line 334) * private: Virtual Private Networks. (line 10) * PrivateKey: Main configuration variables. - (line 331) + (line 339) * PrivateKeyFile: Main configuration variables. - (line 337) + (line 345) * ProcessPriority: Main configuration variables. - (line 342) + (line 350) * Proxy: Main configuration variables. - (line 347) + (line 355) * PublicKey: Host configuration variables. (line 69) * PublicKeyFile: Host configuration variables. @@ -3553,40 +3630,41 @@ Concept Index * REMOTEADDRESS: Scripts. (line 84) * REMOTEPORT: Scripts. (line 87) * ReplayWindow: Main configuration variables. - (line 370) + (line 378) * requirements: Libraries. (line 6) * REQ_KEY: The meta-protocol. (line 63) * restart: tinc commands. (line 70) * retry: tinc commands. (line 135) * Route: Invitation file format. - (line 51) + (line 52) * router: Main configuration variables. - (line 261) + (line 269) * runtime options: Runtime options. (line 9) * scalability: tinc. (line 19) * scripts: Scripts. (line 6) * server: How connections work. - (line 18) + (line 12) * set: tinc commands. (line 16) * shell: Controlling tinc. (line 11) * sign: tinc commands. (line 172) * signals: Signals. (line 6) * socks4: Main configuration variables. - (line 351) + (line 359) * socks5: Main configuration variables. - (line 356) + (line 364) * SPTPS: Simple Peer-to-Peer Security. (line 6) * start: tinc commands. (line 64) * stop: tinc commands. (line 67) * StrictSubnets: Main configuration variables. - (line 381) + (line 389) * Subnet: Host configuration variables. (line 84) * SUBNET: Scripts. (line 91) * SVPN: Security. (line 11) * switch: Main configuration variables. - (line 269) + (line 277) +* systemd: Linux. (line 6) * TCP: The meta-connection. (line 10) * TCPonly: Host configuration variables. (line 113) @@ -3602,36 +3680,36 @@ Concept Index * tunifhead: Main configuration variables. (line 158) * TunnelServer: Main configuration variables. - (line 388) + (line 396) * tunnohead: Main configuration variables. (line 152) * UDP: The UDP tunnel. (line 30) * UDP <1>: Encryption of network packets. (line 11) * UDPDiscoveryInterval: Main configuration variables. - (line 408) + (line 416) * UDPDiscoveryKeepaliveInterval: Main configuration variables. - (line 402) + (line 410) * UDPDiscoveryTimeout: Main configuration variables. - (line 412) + (line 420) * UDPDiscovey: Main configuration variables. - (line 395) + (line 403) * UDPInfoInterval: Main configuration variables. - (line 417) + (line 425) * UDPRcvBuf: Main configuration variables. - (line 421) + (line 429) * UDPSndBuf: Main configuration variables. - (line 427) + (line 435) * UML: Main configuration variables. (line 134) * Universal tun/tap: Configuration of Linux kernels. (line 6) * UPnP: Main configuration variables. - (line 433) + (line 441) * UPnPDiscoverWait: Main configuration variables. - (line 444) + (line 452) * UPnPRefreshPeriod: Main configuration variables. - (line 448) + (line 456) * utun: Main configuration variables. (line 165) * VDE: Main configuration variables. @@ -3652,78 +3730,82 @@ Concept Index  Tag Table: -Node: Top824 -Node: Introduction1160 -Node: Virtual Private Networks1964 -Node: tinc3676 -Node: Supported platforms5188 -Node: Preparations5885 -Node: Configuring the kernel6141 -Node: Configuration of Linux kernels6550 -Node: Configuration of FreeBSD kernels7399 -Node: Configuration of OpenBSD kernels7864 -Node: Configuration of NetBSD kernels8221 -Node: Configuration of Solaris kernels8623 -Node: Configuration of Darwin (MacOS/X) kernels9285 -Node: Configuration of Windows10098 -Node: Libraries10637 -Node: LibreSSL/OpenSSL11094 -Node: zlib13620 -Node: lzo14642 -Node: libcurses15633 -Node: libreadline16543 -Node: Installation17480 -Node: Building and installing tinc18384 -Node: Darwin (MacOS/X) build environment19040 -Node: Cygwin (Windows) build environment19599 -Node: MinGW (Windows) build environment20184 -Node: System files20772 -Node: Device files21037 -Node: Other files21450 -Node: Configuration22063 -Node: Configuration introduction22350 -Node: Multiple networks23871 -Node: How connections work25238 -Node: Configuration files27799 -Node: Main configuration variables29431 -Node: Host configuration variables50412 -Node: Scripts56482 -Node: How to configure60382 -Node: Network interfaces64866 -Node: Example configuration67245 -Node: Running tinc72344 -Node: Runtime options72931 -Node: Signals75791 -Node: Debug levels76640 -Node: Solving problems77576 -Node: Error messages79002 -Node: Sending bug reports83319 -Node: Controlling tinc84266 -Node: tinc runtime options85002 -Node: tinc environment variables85751 -Node: tinc commands86080 -Node: tinc examples92938 -Node: tinc top93500 -Node: Invitations95085 -Node: How invitations work95748 -Node: Invitation file format98041 -Node: Writing an invitation-created script100966 -Node: Technical information102028 -Node: The connection102258 -Node: The UDP tunnel102570 -Node: The meta-connection105615 -Node: The meta-protocol107073 -Node: Security112056 -Node: Legacy authentication protocol113393 -Node: Simple Peer-to-Peer Security118010 -Node: Encryption of network packets123655 -Node: Security issues126293 -Node: Platform specific information128040 -Node: Interface configuration128268 -Node: Routes130709 -Node: About us132620 -Node: Contact information132797 -Node: Authors133200 -Node: Concept Index133604 +Node: Top808 +Node: Introduction1144 +Node: Virtual Private Networks1948 +Node: tinc3660 +Node: Supported platforms5173 +Node: Preparations5870 +Node: Configuring the kernel6126 +Node: Configuration of Linux kernels6535 +Node: Configuration of FreeBSD kernels7384 +Node: Configuration of OpenBSD kernels7849 +Node: Configuration of NetBSD kernels8206 +Node: Configuration of Solaris kernels8608 +Node: Configuration of Darwin (MacOS/X) kernels9270 +Node: Configuration of Windows10083 +Node: Libraries10622 +Node: LibreSSL/OpenSSL11079 +Node: zlib13607 +Node: LZO14627 +Node: libcurses15619 +Node: libreadline16531 +Node: Installation17470 +Node: Building and installing tinc18374 +Node: Darwin (MacOS/X) build environment19030 +Node: Cygwin (Windows) build environment19589 +Node: MinGW (Windows) build environment20174 +Node: System files20762 +Node: Device files21027 +Node: Other files21440 +Node: Configuration22053 +Node: Configuration introduction22340 +Node: Multiple networks23862 +Node: How connections work25230 +Node: Configuration files27494 +Node: Main configuration variables29125 +Node: Host configuration variables50523 +Node: Scripts56595 +Node: How to configure60495 +Node: Network interfaces64406 +Node: Example configuration66785 +Node: Running tinc71726 +Node: Runtime options72313 +Node: Signals75581 +Node: Debug levels76430 +Node: Solving problems77366 +Node: Error messages78792 +Node: Sending bug reports83109 +Node: Controlling tinc84056 +Node: tinc runtime options84792 +Node: tinc environment variables85608 +Node: tinc commands85937 +Node: tinc examples92796 +Node: tinc top93356 +Node: Invitations94940 +Node: How invitations work95603 +Node: Invitation file format97896 +Node: Writing an invitation-created script100907 +Node: Technical information101970 +Node: The connection102200 +Node: The UDP tunnel102512 +Node: The meta-connection105548 +Node: The meta-protocol107006 +Node: Security111989 +Node: Legacy authentication protocol113326 +Node: Simple Peer-to-Peer Security117943 +Node: Encryption of network packets123588 +Node: Security issues126226 +Node: Platform specific information128818 +Node: Interface configuration129078 +Node: Routes131348 +Node: Automatically starting tinc133295 +Node: Linux133518 +Node: Windows134730 +Node: Other platforms135274 +Node: About us135556 +Node: Contact information135733 +Node: Authors136136 +Node: Concept Index136540  End Tag Table diff --git a/doc/tinc.texi b/doc/tinc.texi index 83e42c6..c7021dd 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-2017 Ivo Timmermans, +Copyright @copyright{} 1998-2018 Ivo Timmermans, Guus Sliepen and Wessel Dankers . @@ -43,7 +43,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-2017 Ivo Timmermans, +Copyright @copyright{} 1998-2018 Ivo Timmermans, Guus Sliepen and Wessel Dankers . @@ -161,7 +161,7 @@ professional package. @cindex traditional VPNs @cindex scalability -Tinc also allows more than two sites to connect to eachother and form a single VPN. +Tinc also allows more than two sites to connect to each other and form a single VPN. Traditionally VPNs are created by making tunnels, which only have two endpoints. Larger VPNs with more sites are created by adding more tunnels. Tinc takes another approach: only endpoints are specified, @@ -331,14 +331,14 @@ as explained in the rest of the documentation. @cindex requirements @cindex libraries Before you can configure or build tinc, you need to have the LibreSSL or OpenSSL, zlib, -lzo, curses and readline libraries installed on your system. If you try to +LZO, curses and readline libraries installed on your system. If you try to configure tinc without having them installed, configure will give you an error message, and stop. @menu * LibreSSL/OpenSSL:: * zlib:: -* lzo:: +* LZO:: * libcurses:: * libreadline:: @end menu @@ -353,7 +353,7 @@ message, and stop. For all cryptography-related functions, tinc uses the functions provided by the LibreSSL or the OpenSSL library. -If this library is not installed, you wil get an error when configuring +If this library is not installed, you will get an error when configuring tinc for build. Support for running tinc with other cryptographic libraries installed @emph{may} be added in the future. @@ -363,7 +363,7 @@ of this package. If your operating system comes neither with LibreSSL or OpenSSL, you have to install one manually. It is recommended that you get the latest version of -LibreSSL from @url{http://www.libressl.org/}. Instructions on how to +LibreSSL from @url{https://www.libressl.org/}. Instructions on how to configure, build and install this package are included within the package. Please make sure you build development and runtime libraries (which is the default). @@ -419,7 +419,7 @@ Markus F.X.J. Oberhumer For the optional compression of UDP packets, tinc uses the functions provided by the zlib library. -If this library is not installed, you wil get an error when running the +If this library is not installed, you will get an error when running the configure script. You can either install the zlib library, or disable support for zlib compression by using the "--disable-zlib" option when running the configure script. Note that if you disable support for zlib, the resulting @@ -430,20 +430,20 @@ available. Make sure you install the development AND runtime versions of this package. If you have to install zlib manually, you can get the source code -from @url{http://www.zlib.net/}. Instructions on how to configure, +from @url{https://zlib.net/}. Instructions on how to configure, build and install this package are included within the package. Please make sure you build development and runtime libraries (which is the default). @c ================================================================== -@node lzo -@subsection lzo +@node LZO +@subsection LZO -@cindex lzo +@cindex LZO Another form of compression is offered using the LZO library. -If this library is not installed, you wil get an error when running the +If this library is not installed, you will get an error when running the configure script. You can either install the LZO library, or disable support for LZO compression by using the "--disable-lzo" option when running the configure script. Note that if you disable support for LZO, the resulting @@ -453,7 +453,7 @@ You can use your operating system's package manager to install this if available. Make sure you install the development AND runtime versions of this package. -If you have to install lzo manually, you can get the source code +If you have to install LZO manually, you can get the source code from @url{https://www.oberhumer.com/opensource/lzo/}. Instructions on how to configure, build and install this package are included within the package. Please make sure you build development and runtime libraries (which is the @@ -467,15 +467,15 @@ default). @cindex libcurses For the "tinc top" command, tinc requires a curses library. -If this library is not installed, you wil get an error when running the +If this library is not installed, you will get an error when running the configure script. You can either install a suitable curses library, or disable all functionality that depends on a curses library by using the "--disable-curses" option when running the configure script. There are several curses libraries. It is recommended that you install -"ncurses" (@url{http://invisible-island.net/ncurses/}), +"ncurses" (@url{https://invisible-island.net/ncurses/}), however other curses libraries should also work. -In particular, "PDCurses" (@url{http://pdcurses.sourceforge.net/}) +In particular, "PDCurses" (@url{https://pdcurses.sourceforge.io/}) is recommended if you want to compile tinc for Windows. You can use your operating system's package manager to install this if @@ -490,7 +490,7 @@ of this package. @cindex libreadline For the "tinc" command's shell functionality, tinc uses the readline library. -If this library is not installed, you wil get an error when running the +If this library is not installed, you will get an error when running the configure script. You can either install a suitable readline library, or disable all functionality that depends on a readline library by using the "--disable-readline" option when running the configure script. @@ -500,7 +500,7 @@ available. Make sure you install the development AND runtime versions of this package. If you have to install libreadline manually, you can get the source code from -@url{http://www.gnu.org/software/readline/}. Instructions on how to configure, +@url{https://www.gnu.org/software/readline/}. Instructions on how to configure, build and install this package are included within the package. Please make sure you build development and runtime libraries (which is the default). @@ -691,7 +691,7 @@ you will not find the answers in this documentation. Make sure you have an adequate understanding of networks in general. @cindex Network Administrators Guide A good resource on networking is the -@uref{http://www.tldp.org/LDP/nag2/, Linux Network Administrators Guide}. +@uref{https://www.tldp.org/LDP/nag2/, Linux Network Administrators Guide}. If you have everything clearly pictured in your mind, proceed in the following order: @@ -721,7 +721,7 @@ It is not required if you only run one tinc daemon, it doesn't even have to be the same on all the nodes of your VPN, but it is recommended that you choose one anyway. -We will asume you use a netname throughout this document. +We will assume you use a netname throughout this document. This means that you call tinc with the -n argument, which will specify the netname. @@ -744,22 +744,15 @@ and the host configuration files are expected to be in @file{@value{sysconfdir}/ When tinc starts up, it parses the command-line options and then reads in the configuration file tinc.conf. -If it sees one or more `ConnectTo' values pointing to other tinc daemons in that file, -it will try to connect to those other daemons. -Whether this succeeds or not and whether `ConnectTo' is specified or not, -tinc will listen for incoming connection from other deamons. -If you did specify a `ConnectTo' value and the other side is not responding, -tinc will keep retrying. -This means that once started, tinc will stay running until you tell it to stop, -and failures to connect to other tinc daemons will not stop your tinc daemon -for trying again later. -This means you don't have to intervene if there are temporary network problems. +It will then start listening for incoming connection from other daemons, +and will by default also automatically try to connect to known peers. +By default, tinc will try to keep at least 3 working meta-connections alive at all times. @cindex client @cindex server There is no real distinction between a server and a client in tinc. -If you wish, you can view a tinc daemon without a `ConnectTo' value as a server, -and one which does specify such a value as a client. +If you wish, you can view a tinc daemon without a `ConnectTo' statement in tinc.conf and `AutoConnect = no' as a server, +and one which does have one or more `ConnectTo' statements or `Autoconnect = yes' (which is the default) as a client. It does not matter if two tinc daemons have a `ConnectTo' value pointing to each other however. Connections specified using `ConnectTo' are so-called meta-connections. @@ -778,7 +771,7 @@ It is not always possible to do this however, and firewalls might also prevent d In that case, VPN packets between A and C will be forwarded by B. In effect, all nodes in the VPN will be able to talk to each other, as long as -their is a path of meta-connections between them, and whenever possible, two +there is a path of meta-connections between them, and whenever possible, two nodes will communicate with each other directly. @@ -790,7 +783,7 @@ The actual configuration of the daemon is done in the file @file{@value{sysconfdir}/tinc/@var{netname}/tinc.conf} and at least one other file in the directory @file{@value{sysconfdir}/tinc/@var{netname}/hosts/}. -An optionnal directory @file{@value{sysconfdir}/tinc/@var{netname}/conf.d} can be added from which +An optional directory @file{@value{sysconfdir}/tinc/@var{netname}/conf.d} can be added from which any .conf file will be read. These file consists of comments (lines started with a #) or assignments @@ -839,7 +832,7 @@ If any is selected, then depending on the operating system both IPv4 and IPv6 or just IPv6 listening sockets will be created. @cindex AutoConnect -@item AutoConnect = (no) [experimental] +@item AutoConnect = (yes) If set to yes, tinc will automatically set up meta connections to other nodes, without requiring @var{ConnectTo} variables. @@ -900,7 +893,7 @@ in which case outgoing connections to each specified tinc daemon are made. The names should be known to this tinc daemon (i.e., there should be a host configuration file for the name on the ConnectTo line). -If you don't specify a host with ConnectTo and don't enable AutoConnect, +If you don't specify a host with ConnectTo and have disabled AutoConnect, tinc won't try to connect to other daemons at all, and will instead just listen for incoming connections. @@ -967,7 +960,7 @@ Packets received for the local node are written to it. @cindex UML @item uml (not compiled in by default) Create a UNIX socket with the filename specified by -@var{Device}, or @file{@value{localstatedir}/run/@var{netname}.umlsocket} +@var{Device}, or @file{@value{runstatedir}/@var{netname}.umlsocket} if not specified. Tinc will wait for a User Mode Linux instance to connect to this socket. @@ -975,7 +968,7 @@ Tinc will wait for a User Mode Linux instance to connect to this socket. @item vde (not compiled in by default) Uses the libvdeplug library to connect to a Virtual Distributed Ethernet switch, using the UNIX socket specified by -@var{Device}, or @file{@value{localstatedir}/run/vde.ctl} +@var{Device}, or @file{@value{runstatedir}/vde.ctl} if not specified. @end table @@ -1048,16 +1041,24 @@ Incoming packets that are meant for another node are forwarded by tinc internall 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. +Incoming packets using the legacy protocol 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. +Incoming packets using the SPTPS protocol are dropped, since they are end-to-end encrypted. @end table +@cindex FWMark +@item FWMark = <@var{value}> (0) [experimental] +When set to a non-zero value, all TCP and UDP sockets created by tinc will use the given value as the firewall mark. +This can be used for mark-based routing or for packet filtering. +This option is currently only supported on Linux. + @cindex Hostnames @item Hostnames = (no) This option selects whether IP addresses (both real and on the VPN) should be resolved. Since DNS lookups are blocking, it might affect -tinc's efficiency, even stopping the daemon for a few seconds everytime +tinc's efficiency, even stopping the daemon for a few seconds every time it does a lookup if your DNS server is not responding. This does not affect resolving hostnames to IP addresses from the @@ -1179,7 +1180,7 @@ will be inherited by the UDP packets that are sent out. @item PrivateKey = <@var{key}> [obsolete] This is the RSA private key for tinc. However, for safety reasons it is advised to store private keys of any kind in separate files. This prevents -accidental eavesdropping if you are editting the configuration file. +accidental eavesdropping if you are editing the configuration file. @cindex PrivateKeyFile @item PrivateKeyFile = <@var{path}> (@file{@value{sysconfdir}/tinc/@var{netname}/rsa_key.priv}) @@ -1335,7 +1336,7 @@ Fragmentation Needed or Packet too Big messages are dropped by firewalls. @item Compression = <@var{level}> (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), -10 (fast lzo) and 11 (best lzo). +10 (fast LZO) and 11 (best LZO). @cindex Digest @item Digest = <@var{digest}> (sha1) @@ -1396,7 +1397,7 @@ connection with that host. @cindex Subnet @item Subnet = <@var{address}[/@var{prefixlength}[#@var{weight}]]> The subnet which this tinc daemon will serve. -Tinc tries to look up which other daemon it should send a packet to by searching the appropiate subnet. +Tinc tries to look up which other daemon it should send a packet to by searching the appropriate subnet. If the packet matches a subnet, it will be sent to the daemon who has this subnet in his host configuration file. Multiple subnet lines can be specified for each daemon. @@ -1626,23 +1627,11 @@ For example, if your hostname is foo.example.org, run: tinc -n @var{netname} add address foo.example.org @end example -If you already know to which daemons your daemon should make meta-connections, -you should configure that now as well. -Suppose you want to connect to a daemon named "bar", run: - -@example -tinc -n @var{netname} add connectto bar -@end example - -Note that you specify the Name of the other daemon here, not an IP address or hostname! -When you start tinc, and it tries to make a connection to "bar", -it will look for a host configuration file named @file{hosts/bar}, -and will read Address statements and public keys from that file. - @subsubheading Step 2. Exchanging configuration files. -If your daemon has a ConnectTo = bar statement in its @file{tinc.conf} file, -or if bar has a ConnectTo your daemon, then you both need each other's host configuration files. +In order for two tinc daemons to be able to connect to each other, +they each need the other's host configuration files. +So if you want foo to be able to connect with bar, You should send @file{hosts/@var{name}} to bar, and bar should send you his file which you should move to @file{hosts/bar}. If you are on a UNIX platform, you can easily send an email containing the necessary information using the following command (assuming the owner of bar has the email address bar@@example.org): @@ -1668,10 +1657,9 @@ tinc -n @var{netname} export \ | tinc -n @var{netname} import @end example -You should repeat this for all nodes you ConnectTo, or which ConnectTo you. -However, remember that you do not need to ConnectTo all nodes in the VPN; -it is only necessary to create one or a few meta-connections, -after the connections are made tinc will learn about all the other nodes in the VPN, +You can repeat this for a few other nodes as well. +It is not necessary to manually exchange host config files between all nodes; +after the initial connections are made tinc will learn about all the other nodes in the VPN, and will automatically make other connections as necessary. @@ -1817,12 +1805,10 @@ and in @file{@value{sysconfdir}/tinc/company/tinc.conf}: @example Name = BranchB -ConnectTo = BranchA @end example Note here that the internal address (on eth0) doesn't have to be the -same as on the VPN interface. Also, ConnectTo is given so that this node will -always try to connect to BranchA. +same as on the VPN interface. On all hosts, in @file{@value{sysconfdir}/tinc/company/hosts/BranchB}: @@ -1853,7 +1839,6 @@ and in @file{@value{sysconfdir}/tinc/company/tinc.conf}: @example Name = BranchC -ConnectTo = BranchA @end example C already has another daemon that runs on port 655, so they have to @@ -1890,7 +1875,6 @@ and in @file{@value{sysconfdir}/tinc/company/tinc.conf}: @example Name = BranchD -ConnectTo = BranchC @end example D will be connecting to C, which has a tincd running for this network on @@ -1983,7 +1967,7 @@ Specifying . for @var{netname} is the same as not specifying any @var{netname}. @item --pidfile=@var{filename} Store a cookie in @var{filename} which allows tinc to authenticate. If unspecified, the default is -@file{@value{localstatedir}/run/tinc.@var{netname}.pid}. +@file{@value{runstatedir}/tinc.@var{netname}.pid}. @item -o, --option=[@var{HOST}.]@var{KEY}=@var{VALUE} Without specifying a @var{HOST}, this will set server configuration variable @var{KEY} to @var{VALUE}. @@ -2001,6 +1985,9 @@ This option is not supported on all platforms. Write log entries to a file instead of to the system logging facility. If @var{file} is omitted, the default is @file{@value{localstatedir}/log/tinc.@var{netname}.log}. +@item --pidfile=@var{file} +Write PID to @var{file} instead of @file{@value{runstatedir}/tinc.@var{netname}.pid}. + @item --bypass-security Disables encryption and authentication. Only useful for debugging. @@ -2012,10 +1999,14 @@ located (@file{@value{sysconfdir}/tinc/@var{netname}/} as determined by The chroot is performed after all the initialization is done, after writing pid files and opening network sockets. -Note that this option alone does not do any good without -U/--user, below. +This option is best used in combination with the -U/--user option described below. -Note also that tinc can't run scripts anymore (such as tinc-down or host-up), -unless it's setup to be runnable inside chroot environment. +You will need to ensure the chroot environment contains all the files necessary +for tinc to run correctly. +Most importantly, for tinc to be able to resolve hostnames inside the chroot environment, +you must copy @file{/etc/resolv.conf} into the chroot directory. +If you want to be able to run scripts other than @file{tinc-up} in the chroot, +you must ensure the appropriate shell is also installed in the chroot, along with all its dependencies. This option is not supported on all platforms. @item -U, --user=@var{user} @@ -2295,7 +2286,11 @@ Use configuration for net @var{netname}. @xref{Multiple networks}. @item --pidfile=@var{filename} Use the cookie from @var{filename} to authenticate with a running tinc daemon. If unspecified, the default is -@file{@value{localstatedir}/run/tinc.@var{netname}.pid}. +@file{@value{runstatedir}/tinc.@var{netname}.pid}. + +@cindex batch +@item -b, --batch +Don't ask for anything (non-interactive mode). @item --force Force some commands to work despite warnings. @@ -2523,7 +2518,7 @@ The @var{name} of the node must be given, or can be "." to check against the local node's public key, or "*" to allow a signature from any node whose public key is known. If no @var{filename} is given, the file is read from standard input. -If the verification is succesful, a copy of the input with the signature removed is written to standard output, and the exit code will be zero. +If the verification is successful, a copy of the input with the signature removed is written to standard output, and the exit code will be zero. If the verification failed, nothing will be written to standard output, and the exit code will be non-zero. @end table @@ -2546,7 +2541,7 @@ Examples of changing the configuration using tinc: tinc -n vpn init foo tinc -n vpn add Subnet 192.168.1.0/24 tinc -n vpn add bar.Address bar.example.com -tinc -n vpn add ConnectTo bar +tinc -n vpn set Mode switch tinc -n vpn export | gpg --clearsign | mail -s "My config" vpnmaster@@example.com @end example @@ -2571,7 +2566,7 @@ Intervals lower than 0.1 seconds are not allowed. @item c Toggle between displaying current traffic rates (in packets and bytes per second) -and cummulative traffic (total packets and bytes since the tinc daemon started). +and cumulative traffic (total packets and bytes since the tinc daemon started). @item n Sort the list of nodes by name. @@ -2696,6 +2691,8 @@ Address = server.example.com The file is basically a concatenation of several host config blocks. Each host config block starts with @code{Name = ...}. Lines that look like @code{#---#} are not important, it just makes it easier for humans to read the file. +However, the first line of an invitation file @emph{must} always start with +@code{Name = ...}. The first host config block is always the one representing the invitee. So the first Name statement determines the name that the invitee will get. From the @@ -2744,7 +2741,7 @@ When an invitation is generated, the "invitation-created" script is called (if it exists) right after the invitation file is written, but before the URL has been written to stdout. This allows one to change the invitation file automatically before the invitation URL is passed to the invitee. Here is an -example shell script that aproximately recreates the default invitation file: +example shell script that approximately recreates the default invitation file: @example #!/bin/sh @@ -2846,7 +2843,7 @@ In switch or hub modes ARP does work so the sender already knows the correct des In those modes every interface should have a unique MAC address, so make sure they are not the same. Because switch and hub modes rely on MAC addresses to function correctly, these modes cannot be used on the following operating systems which don't have a `tap' style virtual network device: -OpenBSD, NetBSD, Darwin and Solaris. +NetBSD, Darwin and Solaris. @c ================================================================== @@ -3378,13 +3375,27 @@ that tinc's default length of 4 bytes for the MAC is too short, and he doesn't like tinc's use of RSA during authentication. We do not know of a security hole in the legacy protocol of tinc, but it is not as strong as TLS or IPsec. -This version of tinc comes with an improved protocol, called Simple Peer-to-Peer Security, -which aims to be as strong as TLS with one of the strongest cipher suites. +The Sweet32 attack affects versions of tinc prior to 1.0.30. + +On September 6th, 2018, Michael Yonly contacted us and provided +proof-of-concept code that allowed a remote attacker to create an +authenticated, one-way connection with a node, and also that there was a +possibility for a man-in-the-middle to force UDP packets from a node to be sent +in plaintext. The first issue was trivial to exploit on tinc versions prior to +1.0.30, but the changes in 1.0.30 to mitigate the Sweet32 attack made this +weakness much harder to exploit. These issues have been fixed in tinc 1.0.35. + +This version of tinc comes with an improved protocol, called Simple +Peer-to-Peer Security (SPTPS), which aims to be as strong as TLS with one of +the strongest cipher suites. None of the above security issues affected SPTPS. +However, be aware that SPTPS is only used between nodes running tinc 1.1pre* or +later, and in a VPN with nodes running different versions, the security might +only be as good as that of the oldest version. Cryptography is a hard thing to get right. We cannot make any guarantees. Time, review and feedback are the only things that can prove the security of any cryptographic product. If you wish to review -tinc or give us feedback, you are stronly encouraged to do so. +tinc or give us feedback, you are strongly encouraged to do so. @c ================================================================== @@ -3394,6 +3405,7 @@ tinc or give us feedback, you are stronly encouraged to do so. @menu * Interface configuration:: * Routes:: +* Automatically starting tinc:: @end menu @c ================================================================== @@ -3450,13 +3462,6 @@ For IPv6 addresses: @tab @code{netsh interface ipv6 add address} @var{interface} @code{static} @var{address}/@var{prefixlength} @end multitable -On some platforms, when running tinc in switch mode, the VPN interface must be set to tap mode with an ifconfig command: - -@multitable {Darwin (MacOS/X)} {ifconfig route add -bla network address netmask netmask prefixlength interface} -@item OpenBSD -@tab @code{ifconfig} @var{interface} @code{link0} -@end multitable - On Linux, it is possible to create a persistent tun/tap interface which will continue to exist even if tinc quit, although this is normally not required. It can be useful to set up a tun/tap interface owned by a non-root user, so @@ -3520,6 +3525,67 @@ Adding routes to IPv6 subnets: @tab @code{netsh interface ipv6 add route} @var{network address}/@var{prefixlength} @var{interface} @end multitable +@c ================================================================== +@node Automatically starting tinc +@section Automatically starting tinc + +@menu +* Linux:: +* Windows:: +* Other platforms:: +@end menu + +@c ================================================================== +@node Linux +@subsection Linux + +@cindex systemd +There are many Linux distributions, and historically, many of them had their +own way of starting programs at boot time. Today, a number of major Linux +distributions have chosen to use systemd as their init system. Tinc ships with +systemd service files that allow you to start and stop tinc using systemd. +There are two service files: @code{tinc.service} is used to globally enable or +disable all tinc daemons managed by systemd, and +@code{tinc@@@var{netname}.service} is used to enable or disable specific tinc +daemons. So if one has created a tinc network with netname @code{foo}, then +you have to run the following two commands to ensure it is started at boot +time: + +@example +systemctl enable tinc +systemctl enable tinc@@foo +@end example + +To start the tinc daemon immediately if it wasn't already running, use the +following command: + +@example +systemctl start tinc@@foo +@end example + +You can also use @samp{systemctl start tinc}, this will start all tinc daemons +that are enabled. You can stop and disable tinc networks in the same way. + +If your system is not using systemd, then you have to look up your +distribution's way of starting tinc at boot time. + +@c ================================================================== +@node Windows +@subsection Windows + +On Windows, if tinc is started with the @code{tinc start} command without using +the @code{-D} or @code{--no-detach} option, it will automatically register +itself as a service that is started at boot time. When tinc is stopped using +the @code{tinc stop} command, it will also automatically unregister itself. +Once tinc is registered as a service, it is also possible to stop and start +tinc using the Windows Services Manager. + +@c ================================================================== +@node Other platforms +@subsection Other platforms + +On platforms other than the ones mentioned in the earlier sections, you have to +look up your platform's way of starting programs at boot time. @c ================================================================== @node About us diff --git a/doc/tincd.8.in b/doc/tincd.8.in index 22c54a7..a14eb4e 100644 --- a/doc/tincd.8.in +++ b/doc/tincd.8.in @@ -100,7 +100,7 @@ to authenticate. If .Ar FILE is omitted, the default is -.Pa @localstatedir@/run/tinc. Ns Ar NETNAME Ns Pa .pid. +.Pa @runstatedir@/tinc. Ns Ar NETNAME Ns Pa .pid. .It Fl -bypass-security Disables encryption and authentication of the meta protocol. Only useful for debugging. @@ -173,7 +173,7 @@ This will log all network traffic over the virtual private network. Directory containing the configuration files tinc uses. For more information, see .Xr tinc.conf 5 . -.It Pa @localstatedir@/run/tinc. Ns Ar NETNAME Ns Pa .pid +.It Pa @runstatedir@/tinc. Ns Ar NETNAME Ns Pa .pid The PID of the currently running .Nm is stored in this file. diff --git a/doc/tincinclude.texi b/doc/tincinclude.texi new file mode 100644 index 0000000..6bb64ca --- /dev/null +++ b/doc/tincinclude.texi @@ -0,0 +1,5 @@ +@set VERSION 1.1pre17 +@set PACKAGE tinc +@set sysconfdir /etc +@set localstatedir /var +@set runstatedir /var/run diff --git a/doc/tincinclude.texi.in b/doc/tincinclude.texi.in index da4adc5..01fee35 100644 --- a/doc/tincinclude.texi.in +++ b/doc/tincinclude.texi.in @@ -2,3 +2,4 @@ @set PACKAGE @PACKAGE@ @set sysconfdir @sysconfdir@ @set localstatedir @localstatedir@ +@set runstatedir @runstatedir@ diff --git a/gui/Makefile.am b/gui/Makefile.am deleted file mode 100644 index 4f2c7fe..0000000 --- a/gui/Makefile.am +++ /dev/null @@ -1,3 +0,0 @@ -dist_bin_SCRIPTS = tinc-gui - -extra_DIST = README.gui diff --git a/gui/Makefile.in b/gui/Makefile.in deleted file mode 100644 index 178c672..0000000 --- a/gui/Makefile.in +++ /dev/null @@ -1,507 +0,0 @@ -# Makefile.in generated by automake 1.15.1 from Makefile.am. -# @configure_input@ - -# Copyright (C) 1994-2017 Free Software Foundation, Inc. - -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -@SET_MAKE@ - -VPATH = @srcdir@ -am__is_gnu_make = { \ - if test -z '$(MAKELEVEL)'; then \ - false; \ - elif test -n '$(MAKE_HOST)'; then \ - true; \ - elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ - true; \ - else \ - false; \ - fi; \ -} -am__make_running_with_option = \ - case $${target_option-} in \ - ?) ;; \ - *) echo "am__make_running_with_option: internal error: invalid" \ - "target option '$${target_option-}' specified" >&2; \ - exit 1;; \ - esac; \ - has_opt=no; \ - sane_makeflags=$$MAKEFLAGS; \ - if $(am__is_gnu_make); then \ - sane_makeflags=$$MFLAGS; \ - else \ - case $$MAKEFLAGS in \ - *\\[\ \ ]*) \ - bs=\\; \ - sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ - | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ - esac; \ - fi; \ - skip_next=no; \ - strip_trailopt () \ - { \ - flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ - }; \ - for flg in $$sane_makeflags; do \ - test $$skip_next = yes && { skip_next=no; continue; }; \ - case $$flg in \ - *=*|--*) continue;; \ - -*I) strip_trailopt 'I'; skip_next=yes;; \ - -*I?*) strip_trailopt 'I';; \ - -*O) strip_trailopt 'O'; skip_next=yes;; \ - -*O?*) strip_trailopt 'O';; \ - -*l) strip_trailopt 'l'; skip_next=yes;; \ - -*l?*) strip_trailopt 'l';; \ - -[dEDm]) skip_next=yes;; \ - -[JT]) skip_next=yes;; \ - esac; \ - case $$flg in \ - *$$target_option*) has_opt=yes; break;; \ - esac; \ - done; \ - test $$has_opt = yes -am__make_dryrun = (target_option=n; $(am__make_running_with_option)) -am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) -pkgdatadir = $(datadir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkglibexecdir = $(libexecdir)/@PACKAGE@ -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -install_sh_DATA = $(install_sh) -c -m 644 -install_sh_PROGRAM = $(install_sh) -c -install_sh_SCRIPT = $(install_sh) -c -INSTALL_HEADER = $(INSTALL_DATA) -transform = $(program_transform_name) -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -build_triplet = @build@ -host_triplet = @host@ -subdir = gui -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \ - $(top_srcdir)/m4/ax_append_flag.m4 \ - $(top_srcdir)/m4/ax_cflags_warn_all.m4 \ - $(top_srcdir)/m4/ax_check_compile_flag.m4 \ - $(top_srcdir)/m4/ax_check_link_flag.m4 \ - $(top_srcdir)/m4/ax_require_defined.m4 \ - $(top_srcdir)/m4/curses.m4 $(top_srcdir)/m4/libgcrypt.m4 \ - $(top_srcdir)/m4/lzo.m4 $(top_srcdir)/m4/miniupnpc.m4 \ - $(top_srcdir)/m4/openssl.m4 $(top_srcdir)/m4/readline.m4 \ - $(top_srcdir)/m4/zlib.m4 $(top_srcdir)/configure.ac -am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ - $(ACLOCAL_M4) -DIST_COMMON = $(srcdir)/Makefile.am $(dist_bin_SCRIPTS) \ - $(am__DIST_COMMON) -mkinstalldirs = $(install_sh) -d -CONFIG_HEADER = $(top_builddir)/config.h -CONFIG_CLEAN_FILES = -CONFIG_CLEAN_VPATH_FILES = -am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; -am__vpath_adj = case $$p in \ - $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ - *) f=$$p;; \ - esac; -am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; -am__install_max = 40 -am__nobase_strip_setup = \ - srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` -am__nobase_strip = \ - for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" -am__nobase_list = $(am__nobase_strip_setup); \ - for p in $$list; do echo "$$p $$p"; done | \ - sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ - $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ - if (++n[$$2] == $(am__install_max)) \ - { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ - END { for (dir in files) print dir, files[dir] }' -am__base_list = \ - sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ - sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' -am__uninstall_files_from_dir = { \ - test -z "$$files" \ - || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ - || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ - $(am__cd) "$$dir" && rm -f $$files; }; \ - } -am__installdirs = "$(DESTDIR)$(bindir)" -SCRIPTS = $(dist_bin_SCRIPTS) -AM_V_P = $(am__v_P_@AM_V@) -am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) -am__v_P_0 = false -am__v_P_1 = : -AM_V_GEN = $(am__v_GEN_@AM_V@) -am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) -am__v_GEN_0 = @echo " GEN " $@; -am__v_GEN_1 = -AM_V_at = $(am__v_at_@AM_V@) -am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) -am__v_at_0 = @ -am__v_at_1 = -SOURCES = -DIST_SOURCES = -am__can_run_installinfo = \ - case $$AM_UPDATE_INFO_DIR in \ - n|no|NO) false;; \ - *) (install-info --version) >/dev/null 2>&1;; \ - esac -am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) -am__DIST_COMMON = $(srcdir)/Makefile.in -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) -ACLOCAL = @ACLOCAL@ -AMTAR = @AMTAR@ -AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ -AUTOCONF = @AUTOCONF@ -AUTOHEADER = @AUTOHEADER@ -AUTOMAKE = @AUTOMAKE@ -AWK = @AWK@ -CC = @CC@ -CCDEPMODE = @CCDEPMODE@ -CFLAGS = @CFLAGS@ -CPP = @CPP@ -CPPFLAGS = @CPPFLAGS@ -CURSES_LIBS = @CURSES_LIBS@ -CYGPATH_W = @CYGPATH_W@ -DEFS = @DEFS@ -DEPDIR = @DEPDIR@ -ECHO_C = @ECHO_C@ -ECHO_N = @ECHO_N@ -ECHO_T = @ECHO_T@ -EGREP = @EGREP@ -EXEEXT = @EXEEXT@ -GREP = @GREP@ -INSTALL = @INSTALL@ -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -LDFLAGS = @LDFLAGS@ -LIBOBJS = @LIBOBJS@ -LIBS = @LIBS@ -LN_S = @LN_S@ -LTLIBOBJS = @LTLIBOBJS@ -MAKEINFO = @MAKEINFO@ -MINIUPNPC_LIBS = @MINIUPNPC_LIBS@ -MKDIR_P = @MKDIR_P@ -OBJEXT = @OBJEXT@ -PACKAGE = @PACKAGE@ -PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ -PACKAGE_NAME = @PACKAGE_NAME@ -PACKAGE_STRING = @PACKAGE_STRING@ -PACKAGE_TARNAME = @PACKAGE_TARNAME@ -PACKAGE_URL = @PACKAGE_URL@ -PACKAGE_VERSION = @PACKAGE_VERSION@ -PATH_SEPARATOR = @PATH_SEPARATOR@ -READLINE_LIBS = @READLINE_LIBS@ -SET_MAKE = @SET_MAKE@ -SHELL = @SHELL@ -STRIP = @STRIP@ -VERSION = @VERSION@ -abs_builddir = @abs_builddir@ -abs_srcdir = @abs_srcdir@ -abs_top_builddir = @abs_top_builddir@ -abs_top_srcdir = @abs_top_srcdir@ -ac_ct_CC = @ac_ct_CC@ -am__include = @am__include@ -am__leading_dot = @am__leading_dot@ -am__quote = @am__quote@ -am__tar = @am__tar@ -am__untar = @am__untar@ -bindir = @bindir@ -build = @build@ -build_alias = @build_alias@ -build_cpu = @build_cpu@ -build_os = @build_os@ -build_vendor = @build_vendor@ -builddir = @builddir@ -datadir = @datadir@ -datarootdir = @datarootdir@ -docdir = @docdir@ -dvidir = @dvidir@ -exec_prefix = @exec_prefix@ -host = @host@ -host_alias = @host_alias@ -host_cpu = @host_cpu@ -host_os = @host_os@ -host_vendor = @host_vendor@ -htmldir = @htmldir@ -includedir = @includedir@ -infodir = @infodir@ -install_sh = @install_sh@ -libdir = @libdir@ -libexecdir = @libexecdir@ -localedir = @localedir@ -localstatedir = @localstatedir@ -mandir = @mandir@ -mkdir_p = @mkdir_p@ -oldincludedir = @oldincludedir@ -pdfdir = @pdfdir@ -prefix = @prefix@ -program_transform_name = @program_transform_name@ -psdir = @psdir@ -runstatedir = @runstatedir@ -sbindir = @sbindir@ -sharedstatedir = @sharedstatedir@ -srcdir = @srcdir@ -sysconfdir = @sysconfdir@ -systemd_path = @systemd_path@ -target_alias = @target_alias@ -top_build_prefix = @top_build_prefix@ -top_builddir = @top_builddir@ -top_srcdir = @top_srcdir@ -dist_bin_SCRIPTS = tinc-gui -extra_DIST = README.gui -all: all-am - -.SUFFIXES: -$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) - @for dep in $?; do \ - case '$(am__configure_deps)' in \ - *$$dep*) \ - ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ - && { if test -f $@; then exit 0; else break; fi; }; \ - exit 1;; \ - esac; \ - done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu gui/Makefile'; \ - $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --gnu gui/Makefile -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - @case '$?' in \ - *config.status*) \ - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ - *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ - esac; - -$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh - -$(top_srcdir)/configure: $(am__configure_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(ACLOCAL_M4): $(am__aclocal_m4_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(am__aclocal_m4_deps): -install-dist_binSCRIPTS: $(dist_bin_SCRIPTS) - @$(NORMAL_INSTALL) - @list='$(dist_bin_SCRIPTS)'; test -n "$(bindir)" || list=; \ - if test -n "$$list"; then \ - echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ - fi; \ - for p in $$list; do \ - if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ - if test -f "$$d$$p"; then echo "$$d$$p"; echo "$$p"; else :; fi; \ - done | \ - sed -e 'p;s,.*/,,;n' \ - -e 'h;s|.*|.|' \ - -e 'p;x;s,.*/,,;$(transform)' | sed 'N;N;N;s,\n, ,g' | \ - $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1; } \ - { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ - if ($$2 == $$4) { files[d] = files[d] " " $$1; \ - if (++n[d] == $(am__install_max)) { \ - print "f", d, files[d]; n[d] = 0; files[d] = "" } } \ - else { print "f", d "/" $$4, $$1 } } \ - END { for (d in files) print "f", d, files[d] }' | \ - while read type dir files; do \ - if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ - test -z "$$files" || { \ - echo " $(INSTALL_SCRIPT) $$files '$(DESTDIR)$(bindir)$$dir'"; \ - $(INSTALL_SCRIPT) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ - } \ - ; done - -uninstall-dist_binSCRIPTS: - @$(NORMAL_UNINSTALL) - @list='$(dist_bin_SCRIPTS)'; test -n "$(bindir)" || exit 0; \ - files=`for p in $$list; do echo "$$p"; done | \ - sed -e 's,.*/,,;$(transform)'`; \ - dir='$(DESTDIR)$(bindir)'; $(am__uninstall_files_from_dir) - -installcheck-dist_binSCRIPTS: $(dist_bin_SCRIPTS) - bad=0; pid=$$$$; list="$(dist_bin_SCRIPTS)"; for p in $$list; do \ - case ' $(AM_INSTALLCHECK_STD_OPTIONS_EXEMPT) ' in \ - *" $$p "* | *" $(srcdir)/$$p "*) continue;; \ - esac; \ - f=`echo "$$p" | sed 's,^.*/,,;$(transform)'`; \ - for opt in --help --version; do \ - if "$(DESTDIR)$(bindir)/$$f" $$opt >c$${pid}_.out \ - 2>c$${pid}_.err &2; bad=1; fi; \ - done; \ - done; rm -f c$${pid}_.???; exit $$bad -tags TAGS: - -ctags CTAGS: - -cscope cscopelist: - - -distdir: $(DISTFILES) - @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - list='$(DISTFILES)'; \ - dist_files=`for file in $$list; do echo $$file; done | \ - sed -e "s|^$$srcdirstrip/||;t" \ - -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ - case $$dist_files in \ - */*) $(MKDIR_P) `echo "$$dist_files" | \ - sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ - sort -u` ;; \ - esac; \ - for file in $$dist_files; do \ - if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - if test -d $$d/$$file; then \ - dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test -d "$(distdir)/$$file"; then \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ - else \ - test -f "$(distdir)/$$file" \ - || cp -p $$d/$$file "$(distdir)/$$file" \ - || exit 1; \ - fi; \ - done -check-am: all-am -check: check-am -all-am: Makefile $(SCRIPTS) -installdirs: - for dir in "$(DESTDIR)$(bindir)"; do \ - test -z "$$dir" || $(MKDIR_P) "$$dir"; \ - done -install: install-am -install-exec: install-exec-am -install-data: install-data-am -uninstall: uninstall-am - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am - -installcheck: installcheck-am -install-strip: - if test -z '$(STRIP)'; then \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - install; \ - else \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ - fi -mostlyclean-generic: - -clean-generic: - -distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) - -maintainer-clean-generic: - @echo "This command is intended for maintainers to use" - @echo "it deletes files that may require special tools to rebuild." -clean: clean-am - -clean-am: clean-generic mostlyclean-am - -distclean: distclean-am - -rm -f Makefile -distclean-am: clean-am distclean-generic - -dvi: dvi-am - -dvi-am: - -html: html-am - -html-am: - -info: info-am - -info-am: - -install-data-am: - -install-dvi: install-dvi-am - -install-dvi-am: - -install-exec-am: install-dist_binSCRIPTS - -install-html: install-html-am - -install-html-am: - -install-info: install-info-am - -install-info-am: - -install-man: - -install-pdf: install-pdf-am - -install-pdf-am: - -install-ps: install-ps-am - -install-ps-am: - -installcheck-am: installcheck-dist_binSCRIPTS - -maintainer-clean: maintainer-clean-am - -rm -f Makefile -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-am - -mostlyclean-am: mostlyclean-generic - -pdf: pdf-am - -pdf-am: - -ps: ps-am - -ps-am: - -uninstall-am: uninstall-dist_binSCRIPTS - -.MAKE: install-am install-strip - -.PHONY: all all-am check check-am clean clean-generic cscopelist-am \ - ctags-am distclean distclean-generic distdir dvi dvi-am html \ - html-am info info-am install install-am install-data \ - install-data-am install-dist_binSCRIPTS install-dvi \ - install-dvi-am install-exec install-exec-am install-html \ - install-html-am install-info install-info-am install-man \ - install-pdf install-pdf-am install-ps install-ps-am \ - install-strip installcheck installcheck-am \ - installcheck-dist_binSCRIPTS installdirs maintainer-clean \ - maintainer-clean-generic mostlyclean mostlyclean-generic pdf \ - pdf-am ps ps-am tags-am uninstall uninstall-am \ - uninstall-dist_binSCRIPTS - -.PRECIOUS: Makefile - - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/gui/tinc-gui b/gui/tinc-gui deleted file mode 100755 index 65e8b14..0000000 --- a/gui/tinc-gui +++ /dev/null @@ -1,634 +0,0 @@ -#!/usr/bin/env python2 - -# tinc-gui -- GUI for controlling a running tincd -# Copyright (C) 2009-2014 Guus Sliepen -# 2014 Dennis Joachimsthaler -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License along -# with this program; if not, write to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - -import string -import socket -import os -import platform -import time -from argparse import ArgumentParser - -import wx -from wx.lib.mixins.listctrl import ColumnSorterMixin -from wx.lib.mixins.listctrl import ListCtrlAutoWidthMixin - -if platform.system() == 'Windows': - import _winreg - -# Classes to interface with a running tinc daemon -REQ_STOP = 0 -REQ_RELOAD = 1 -REQ_RESTART = 2 -REQ_DUMP_NODES = 3 -REQ_DUMP_EDGES = 4 -REQ_DUMP_SUBNETS = 5 -REQ_DUMP_CONNECTIONS = 6 -REQ_DUMP_GRAPH = 7 -REQ_PURGE = 8 -REQ_SET_DEBUG = 9 -REQ_RETRY = 10 -REQ_CONNECT = 11 -REQ_DISCONNECT = 12 - -ID = 0 -ACK = 4 -CONTROL = 18 - - -class Node(object): - def __init__(self, args): - self.name = args[0] - self.id = args[1] - - self.address = args[2] - self.port = args[4] - - self.cipher = int(args[5]) - self.digest = int(args[6]) - self.maclength = int(args[7]) - - self.compression = int(args[8]) - self.options = int(args[9], 0x10) - self.status = int(args[10], 0x10) - - self.nexthop = args[11] - self.via = args[12] - self.distance = int(args[13]) - self.pmtu = int(args[14]) - self.minmtu = int(args[15]) - self.maxmtu = int(args[16]) - - self.last_state_change = float(args[17]) - - self.subnets = {} - - -class Edge(object): - def __init__(self, args): - self.source = args[0] - self.sink = args[1] - - self.address = args[2] - self.port = args[4] - - self.options = int(args[-2], 16) - self.weight = int(args[-1]) - - -class Subnet(object): - def __init__(self, args): - if args[0].find('#') >= 0: - address, self.weight = args[0].split('#', 1) - else: - self.weight = 10 - address = args[0] - - if address.find('/') >= 0: - self.address, self.prefixlen = address.split('/', 1) - else: - self.address = address - self.prefixlen = '48' - - self.owner = args[1] - - -class Connection(object): - def __init__(self, args): - self.name = args[0] - - self.address = args[1] - self.port = args[3] - - self.options = int(args[4], 0x10) - self.socket = int(args[5]) - self.status = int(args[6], 0x10) - - self.weight = 'n/a' - - -class VPN(object): - def __init__(self, netname=None, pidfile=None, confdir='/etc/tinc', piddir='/run'): - if platform.system() == 'Windows': - sam = _winreg.KEY_READ - if platform.machine().endswith('64'): - sam = sam | _winreg.KEY_WOW64_64KEY - try: - reg = _winreg.ConnectRegistry(None, _winreg.HKEY_LOCAL_MACHINE) - try: - key = _winreg.OpenKey(reg, "SOFTWARE\\tinc", 0, sam) - except WindowsError: - key = _winreg.OpenKey(reg, "SOFTWARE\\Wow6432Node\\tinc", 0, sam) - confdir = _winreg.QueryValue(key, None) - except WindowsError: - pass - - if netname: - self.netname = netname - self.confbase = os.path.join(confdir, netname) - else: - self.confbase = confdir - - self.tincconf = os.path.join(self.confbase, 'tinc.conf') - - if pidfile is not None: - self.pidfile = pidfile - else: - if platform.system() == 'Windows': - self.pidfile = os.path.join(self.confbase, 'pid') - else: - if netname: - self.pidfile = os.path.join(piddir, 'tinc.' + netname + '.pid') - else: - self.pidfile = os.path.join(piddir, 'tinc.pid') - - self.sf = None - self.name = None - self.port = None - self.nodes = {} - self.edges = {} - self.subnets = {} - self.connections = {} - - def connect(self): - # read the pidfile - f = open(self.pidfile) - info = string.split(f.readline()) - f.close() - - # check if there is a UNIX socket as well - if self.pidfile.endswith('.pid'): - unixfile = self.pidfile.replace('.pid', '.socket'); - else: - unixfile = self.pidfile + '.socket'; - - if os.path.exists(unixfile): - # use it if it exists - print(unixfile + " exists!"); - s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) - s.connect(unixfile) - else: - # otherwise connect via TCP - print(unixfile + " does not exist."); - if ':' in info[2]: - af = socket.AF_INET6 - else: - af = socket.AF_INET - s = socket.socket(af, socket.SOCK_STREAM) - s.connect((info[2], int(info[4]))) - - self.sf = s.makefile() - s.close() - hello = string.split(self.sf.readline()) - self.name = hello[1] - self.sf.write('0 ^' + info[1] + ' 17\r\n') - self.sf.flush() - resp = string.split(self.sf.readline()) - self.port = info[4] - self.refresh() - - def refresh(self): - for request in (REQ_DUMP_NODES, REQ_DUMP_EDGES, REQ_DUMP_SUBNETS, REQ_DUMP_CONNECTIONS): - self.sf.write('{} {}\r\n'.format(CONTROL, request)) - self.sf.flush() - - for node in self.nodes.values(): - node.visited = False - for edge in self.edges.values(): - edge.visited = False - for subnet in self.subnets.values(): - subnet.visited = False - for connections in self.connections.values(): - connections.visited = False - - while True: - resp = string.split(self.sf.readline()) - if len(resp) < 2: - break - if resp[0] != '18': - break - if resp[1] == '3': - if len(resp) < 19: - continue - node = self.nodes.get(resp[2]) or Node(resp[2:]) - node.visited = True - self.nodes[resp[2]] = node - elif resp[1] == '4': - if len(resp) < 9: - continue - edge = self.nodes.get((resp[2], resp[3])) or Edge(resp[2:]) - edge.visited = True - self.edges[(resp[2], resp[3])] = edge - elif resp[1] == '5': - if len(resp) < 4: - continue - subnet = self.subnets.get((resp[2], resp[3])) or Subnet(resp[2:]) - subnet.visited = True - self.subnets[(resp[2], resp[3])] = subnet - if subnet.owner == "(broadcast)": - continue - self.nodes[subnet.owner].subnets[resp[2]] = subnet - elif resp[1] == '6': - if len(resp) < 9: - break - connection = self.connections.get((resp[2], resp[3], resp[5])) or Connection(resp[2:]) - connection.visited = True - self.connections[(resp[2], resp[3], resp[5])] = connection - else: - break - - for key, subnet in self.subnets.items(): - if not subnet.visited: - del self.subnets[key] - - for key, edge in self.edges.items(): - if not edge.visited: - del self.edges[key] - - for key, node in self.nodes.items(): - if not node.visited: - del self.nodes[key] - else: - for key, subnet in node.subnets.items(): - if not subnet.visited: - del node.subnets[key] - - for key, connection in self.connections.items(): - if not connection.visited: - del self.connections[key] - - def close(self): - self.sf.close() - - def disconnect(self, name): - self.sf.write('18 12 ' + name + '\r\n') - self.sf.flush() - resp = string.split(self.sf.readline()) - - def debug(self, level=-1): - self.sf.write('18 9 ' + str(level) + '\r\n') - self.sf.flush() - resp = string.split(self.sf.readline()) - return int(resp[2]) - - -class SuperListCtrl(wx.ListCtrl, ColumnSorterMixin, ListCtrlAutoWidthMixin): - def __init__(self, parent, style): - wx.ListCtrl.__init__(self, parent, -1, style=wx.LC_REPORT | wx.LC_HRULES | wx.LC_VRULES) - ListCtrlAutoWidthMixin.__init__(self) - ColumnSorterMixin.__init__(self, 16) - - def GetListCtrl(self): - return self - - -class SettingsPage(wx.Panel): - def on_debug_level(self, event): - vpn.debug(self.debug.GetValue()) - - def __init__(self, parent, id): - wx.Panel.__init__(self, parent, id) - grid = wx.FlexGridSizer(cols=2) - grid.AddGrowableCol(1, 1) - - namelabel = wx.StaticText(self, -1, 'Name:') - self.name = wx.TextCtrl(self, -1, vpn.name) - grid.Add(namelabel) - grid.Add(self.name, 1, wx.EXPAND) - - portlabel = wx.StaticText(self, -1, 'Port:') - self.port = wx.TextCtrl(self, -1, vpn.port) - grid.Add(portlabel) - grid.Add(self.port) - - debuglabel = wx.StaticText(self, -1, 'Debug level:') - self.debug = wx.SpinCtrl(self, min=0, max=5, initial=vpn.debug()) - self.debug.Bind(wx.EVT_SPINCTRL, self.on_debug_level) - grid.Add(debuglabel) - grid.Add(self.debug) - - modelabel = wx.StaticText(self, -1, 'Mode:') - self.mode = wx.ComboBox(self, -1, style=wx.CB_READONLY, value='Router', choices=['Router', 'Switch', 'Hub']) - grid.Add(modelabel) - grid.Add(self.mode) - - self.SetSizer(grid) - - -class ConnectionsPage(wx.Panel): - def __init__(self, parent, id): - wx.Panel.__init__(self, parent, id) - self.list = SuperListCtrl(self, id) - self.list.InsertColumn(0, 'Name') - self.list.InsertColumn(1, 'Address') - self.list.InsertColumn(2, 'Port') - self.list.InsertColumn(3, 'Options') - self.list.InsertColumn(4, 'Weight') - - hbox = wx.BoxSizer(wx.HORIZONTAL) - hbox.Add(self.list, 1, wx.EXPAND) - self.SetSizer(hbox) - self.refresh() - - class ContextMenu(wx.Menu): - def __init__(self, item): - wx.Menu.__init__(self) - - self.item = item - - disconnect = wx.MenuItem(self, -1, 'Disconnect') - self.AppendItem(disconnect) - self.Bind(wx.EVT_MENU, self.on_disconnect, id=disconnect.GetId()) - - def on_disconnect(self, event): - vpn.disconnect(self.item[0]) - - def on_context(self, event): - idx = event.GetIndex() - self.PopupMenu(self.ContextMenu(self.list.itemDataMap[event.GetIndex()]), event.GetPosition()) - - def refresh(self): - sortstate = self.list.GetSortState() - self.list.itemDataMap = {} - i = 0 - - for key, connection in vpn.connections.items(): - if self.list.GetItemCount() <= i: - self.list.InsertStringItem(i, connection.name) - else: - self.list.SetStringItem(i, 0, connection.name) - self.list.SetStringItem(i, 1, connection.address) - self.list.SetStringItem(i, 2, connection.port) - self.list.SetStringItem(i, 3, str(connection.options)) - self.list.SetStringItem(i, 4, str(connection.weight)) - self.list.itemDataMap[i] = (connection.name, connection.address, connection.port, connection.options, - connection.weight) - self.list.Bind(wx.EVT_LIST_ITEM_RIGHT_CLICK, self.on_context) - self.list.SetItemData(i, i) - i += 1 - - while self.list.GetItemCount() > i: - self.list.DeleteItem(self.list.GetItemCount() - 1) - - self.list.SortListItems(sortstate[0], sortstate[1]) - - -class NodesPage(wx.Panel): - def __init__(self, parent, id): - wx.Panel.__init__(self, parent, id) - self.list = SuperListCtrl(self, id) - self.list.InsertColumn(0, 'Name') - self.list.InsertColumn(1, 'Address') - self.list.InsertColumn(2, 'Port') - self.list.InsertColumn(3, 'Cipher') - self.list.InsertColumn(4, 'Digest') - self.list.InsertColumn(5, 'MACLength') - self.list.InsertColumn(6, 'Compression') - self.list.InsertColumn(7, 'Options') - self.list.InsertColumn(8, 'Status') - self.list.InsertColumn(9, 'Nexthop') - self.list.InsertColumn(10, 'Via') - self.list.InsertColumn(11, 'Distance') - self.list.InsertColumn(12, 'PMTU') - self.list.InsertColumn(13, 'Min MTU') - self.list.InsertColumn(14, 'Max MTU') - self.list.InsertColumn(15, 'Since') - - hbox = wx.BoxSizer(wx.HORIZONTAL) - hbox.Add(self.list, 1, wx.EXPAND) - self.SetSizer(hbox) - self.refresh() - - def refresh(self): - sortstate = self.list.GetSortState() - self.list.itemDataMap = {} - i = 0 - - for key, node in vpn.nodes.items(): - if self.list.GetItemCount() <= i: - self.list.InsertStringItem(i, node.name) - else: - self.list.SetStringItem(i, 0, node.name) - self.list.SetStringItem(i, 1, node.address) - self.list.SetStringItem(i, 2, node.port) - self.list.SetStringItem(i, 3, str(node.cipher)) - self.list.SetStringItem(i, 4, str(node.digest)) - self.list.SetStringItem(i, 5, str(node.maclength)) - self.list.SetStringItem(i, 6, str(node.compression)) - self.list.SetStringItem(i, 7, format(node.options, "x")) - self.list.SetStringItem(i, 8, format(node.status, "04x")) - self.list.SetStringItem(i, 9, node.nexthop) - self.list.SetStringItem(i, 10, node.via) - self.list.SetStringItem(i, 11, str(node.distance)) - self.list.SetStringItem(i, 12, str(node.pmtu)) - self.list.SetStringItem(i, 13, str(node.minmtu)) - self.list.SetStringItem(i, 14, str(node.maxmtu)) - if node.last_state_change: - since = time.strftime("%Y-%m-%d %H:%M", time.localtime(node.last_state_change)) - else: - since = "never" - self.list.SetStringItem(i, 15, since) - self.list.itemDataMap[i] = (node.name, node.address, node.port, node.cipher, node.digest, node.maclength, - node.compression, node.options, node.status, node.nexthop, node.via, - node.distance, node.pmtu, node.minmtu, node.maxmtu, since) - self.list.SetItemData(i, i) - i += 1 - - while self.list.GetItemCount() > i: - self.list.DeleteItem(self.list.GetItemCount() - 1) - - self.list.SortListItems(sortstate[0], sortstate[1]) - - -class EdgesPage(wx.Panel): - def __init__(self, parent, id): - wx.Panel.__init__(self, parent, id) - self.list = SuperListCtrl(self, id) - self.list.InsertColumn(0, 'From') - self.list.InsertColumn(1, 'To') - self.list.InsertColumn(2, 'Address') - self.list.InsertColumn(3, 'Port') - self.list.InsertColumn(4, 'Options') - self.list.InsertColumn(5, 'Weight') - - hbox = wx.BoxSizer(wx.HORIZONTAL) - hbox.Add(self.list, 1, wx.EXPAND) - self.SetSizer(hbox) - self.refresh() - - def refresh(self): - sortstate = self.list.GetSortState() - self.list.itemDataMap = {} - i = 0 - - for key, edge in vpn.edges.items(): - if self.list.GetItemCount() <= i: - self.list.InsertStringItem(i, edge.source) - else: - self.list.SetStringItem(i, 0, edge.source) - self.list.SetStringItem(i, 1, edge.sink) - self.list.SetStringItem(i, 2, edge.address) - self.list.SetStringItem(i, 3, edge.port) - self.list.SetStringItem(i, 4, format(edge.options, "x")) - self.list.SetStringItem(i, 5, str(edge.weight)) - self.list.itemDataMap[i] = (edge.source, edge.sink, edge.address, edge.port, edge.options, edge.weight) - self.list.SetItemData(i, i) - i += 1 - - while self.list.GetItemCount() > i: - self.list.DeleteItem(self.list.GetItemCount() - 1) - - self.list.SortListItems(sortstate[0], sortstate[1]) - - -class SubnetsPage(wx.Panel): - def __init__(self, parent, id): - wx.Panel.__init__(self, parent, id) - self.list = SuperListCtrl(self, id) - self.list.InsertColumn(0, 'Subnet', wx.LIST_FORMAT_RIGHT) - self.list.InsertColumn(1, 'Weight', wx.LIST_FORMAT_RIGHT) - self.list.InsertColumn(2, 'Owner') - hbox = wx.BoxSizer(wx.HORIZONTAL) - hbox.Add(self.list, 1, wx.EXPAND) - self.SetSizer(hbox) - self.refresh() - - def refresh(self): - sortstate = self.list.GetSortState() - self.list.itemDataMap = {} - i = 0 - - for key, subnet in vpn.subnets.items(): - if self.list.GetItemCount() <= i: - self.list.InsertStringItem(i, subnet.address + '/' + subnet.prefixlen) - else: - self.list.SetStringItem(i, 0, subnet.address + '/' + subnet.prefixlen) - self.list.SetStringItem(i, 1, str(subnet.weight)) - self.list.SetStringItem(i, 2, subnet.owner) - self.list.itemDataMap[i] = (subnet.address + '/' + subnet.prefixlen, subnet.weight, subnet.owner) - self.list.SetItemData(i, i) - i += 1 - - while self.list.GetItemCount() > i: - self.list.DeleteItem(self.list.GetItemCount() - 1) - - self.list.SortListItems(sortstate[0], sortstate[1]) - - -class StatusPage(wx.Panel): - def __init__(self, parent, id): - wx.Panel.__init__(self, parent, id) - - -class GraphPage(wx.Window): - def __init__(self, parent, id): - wx.Window.__init__(self, parent, id) - - -class NetPage(wx.Notebook): - def __init__(self, parent, id): - wx.Notebook.__init__(self, parent) - self.settings = SettingsPage(self, id) - self.connections = ConnectionsPage(self, id) - self.nodes = NodesPage(self, id) - self.edges = EdgesPage(self, id) - self.subnets = SubnetsPage(self, id) - self.graph = GraphPage(self, id) - self.status = StatusPage(self, id) - - self.AddPage(self.settings, 'Settings') - # self.AddPage(self.status, 'Status') - self.AddPage(self.connections, 'Connections') - self.AddPage(self.nodes, 'Nodes') - self.AddPage(self.edges, 'Edges') - self.AddPage(self.subnets, 'Subnets') - - # self.AddPage(self.graph, 'Graph') - - -class MainWindow(wx.Frame): - def __init__(self, parent, id, title): - wx.Frame.__init__(self, parent, id, title) - - menubar = wx.MenuBar() - - menu = wx.Menu() - menu.Append(1, '&Quit\tCtrl-X', 'Quit tinc GUI') - menubar.Append(menu, '&File') - - # nb = wx.Notebook(self, -1) - # nb.SetPadding((0, 0)) - self.np = NetPage(self, -1) - # nb.AddPage(np, 'VPN') - - self.timer = wx.Timer(self, -1) - self.Bind(wx.EVT_TIMER, self.on_timer, self.timer) - self.timer.Start(1000) - self.Bind(wx.EVT_MENU, self.on_quit, id=1) - self.SetMenuBar(menubar) - self.Show() - - def on_quit(self, event): - app.ExitMainLoop() - - def on_timer(self, event): - vpn.refresh() - self.np.nodes.refresh() - self.np.subnets.refresh() - self.np.edges.refresh() - self.np.connections.refresh() - - -def main(netname, pidfile): - global vpn, app - - if netname is None: - netname = os.getenv('NETNAME') - - vpn = VPN(netname, pidfile) - vpn.connect() - - app = wx.App() - mw = MainWindow(None, -1, 'Tinc GUI') - - """ - def OnTaskBarIcon(event): - mw.Raise() - """ - - """ - icon = wx.Icon("tincgui.ico", wx.BITMAP_TYPE_PNG) - taskbaricon = wx.TaskBarIcon() - taskbaricon.SetIcon(icon, 'Tinc GUI') - wx.EVT_TASKBAR_RIGHT_UP(taskbaricon, OnTaskBarIcon) - """ - - app.MainLoop() - vpn.close() - - -if __name__ == '__main__': - argparser = ArgumentParser(epilog='Report bugs to tinc@tinc-vpn.org.') - - argparser.add_argument('-n', '--net', metavar='NETNAME', dest='netname', help='Connect to net NETNAME') - argparser.add_argument('-p', '--pidfile', help='Path to the pid file (containing the controlcookie)') - - options = argparser.parse_args() - - main(options.netname, options.pidfile) diff --git a/install-sh b/install-sh index 59990a1..8175c64 100755 --- a/install-sh +++ b/install-sh @@ -1,7 +1,7 @@ #!/bin/sh # install - install a program, script, or datafile -scriptversion=2014-09-12.12; # UTC +scriptversion=2018-03-11.20; # UTC # This originates from X11R5 (mit/util/scripts/install.sh), which was # later released in X11R6 (xc/config/util/install.sh) with the @@ -271,15 +271,18 @@ do fi dst=$dst_arg - # If destination is a directory, append the input filename; won't work - # if double slashes aren't ignored. + # If destination is a directory, append the input filename. if test -d "$dst"; then if test "$is_target_a_directory" = never; then echo "$0: $dst_arg: Is a directory" >&2 exit 1 fi dstdir=$dst - dst=$dstdir/`basename "$src"` + dstbase=`basename "$src"` + case $dst in + */) dst=$dst$dstbase;; + *) dst=$dst/$dstbase;; + esac dstdir_status=0 else dstdir=`dirname "$dst"` @@ -288,6 +291,11 @@ do fi fi + case $dstdir in + */) dstdirslash=$dstdir;; + *) dstdirslash=$dstdir/;; + esac + obsolete_mkdir_used=false if test $dstdir_status != 0; then @@ -324,14 +332,16 @@ do # is incompatible with FreeBSD 'install' when (umask & 300) != 0. ;; *) - # $RANDOM is not portable (e.g. dash); use it when possible to - # lower collision chance + # Note that $RANDOM variable is not portable (e.g. dash); Use it + # here however when possible just to lower collision chance. tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ + trap 'ret=$?; rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null; exit $ret' 0 - # As "mkdir -p" follows symlinks and we work in /tmp possibly; so - # create the $tmpdir first (and fail if unsuccessful) to make sure - # that nobody tries to guess the $tmpdir name. + # Because "mkdir -p" follows existing symlinks and we likely work + # directly in world-writeable /tmp, make sure that the '$tmpdir' + # directory is successfully created first before we actually test + # 'mkdir -p' feature. if (umask $mkdir_umask && $mkdirprog $mkdir_mode "$tmpdir" && exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1 @@ -434,8 +444,8 @@ do else # Make a couple of temp file names in the proper directory. - dsttmp=$dstdir/_inst.$$_ - rmtmp=$dstdir/_rm.$$_ + dsttmp=${dstdirslash}_inst.$$_ + rmtmp=${dstdirslash}_rm.$$_ # Trap to clean up those temp files at exit. trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 @@ -500,9 +510,9 @@ do done # Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) +# eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" -# time-stamp-time-zone: "UTC" +# time-stamp-time-zone: "UTC0" # time-stamp-end: "; # UTC" # End: diff --git a/m4/ax_code_coverage.m4 b/m4/ax_code_coverage.m4 new file mode 100644 index 0000000..0934a44 --- /dev/null +++ b/m4/ax_code_coverage.m4 @@ -0,0 +1,264 @@ +# =========================================================================== +# https://www.gnu.org/software/autoconf-archive/ax_code_coverage.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_CODE_COVERAGE() +# +# DESCRIPTION +# +# Defines CODE_COVERAGE_CPPFLAGS, CODE_COVERAGE_CFLAGS, +# CODE_COVERAGE_CXXFLAGS and CODE_COVERAGE_LIBS which should be included +# in the CPPFLAGS, CFLAGS CXXFLAGS and LIBS/LIBADD variables of every +# build target (program or library) which should be built with code +# coverage support. Also defines CODE_COVERAGE_RULES which should be +# substituted in your Makefile; and $enable_code_coverage which can be +# used in subsequent configure output. CODE_COVERAGE_ENABLED is defined +# and substituted, and corresponds to the value of the +# --enable-code-coverage option, which defaults to being disabled. +# +# Test also for gcov program and create GCOV variable that could be +# substituted. +# +# Note that all optimisation flags in CFLAGS must be disabled when code +# coverage is enabled. +# +# Usage example: +# +# configure.ac: +# +# AX_CODE_COVERAGE +# +# Makefile.am: +# +# @CODE_COVERAGE_RULES@ +# my_program_LIBS = ... $(CODE_COVERAGE_LIBS) ... +# my_program_CPPFLAGS = ... $(CODE_COVERAGE_CPPFLAGS) ... +# my_program_CFLAGS = ... $(CODE_COVERAGE_CFLAGS) ... +# my_program_CXXFLAGS = ... $(CODE_COVERAGE_CXXFLAGS) ... +# +# This results in a "check-code-coverage" rule being added to any +# Makefile.am which includes "@CODE_COVERAGE_RULES@" (assuming the module +# has been configured with --enable-code-coverage). Running `make +# check-code-coverage` in that directory will run the module's test suite +# (`make check`) and build a code coverage report detailing the code which +# was touched, then print the URI for the report. +# +# In earlier versions of this macro, CODE_COVERAGE_LDFLAGS was defined +# instead of CODE_COVERAGE_LIBS. They are both still defined, but use of +# CODE_COVERAGE_LIBS is preferred for clarity; CODE_COVERAGE_LDFLAGS is +# deprecated. They have the same value. +# +# This code was derived from Makefile.decl in GLib, originally licenced +# under LGPLv2.1+. +# +# LICENSE +# +# Copyright (c) 2012, 2016 Philip Withnall +# Copyright (c) 2012 Xan Lopez +# Copyright (c) 2012 Christian Persch +# Copyright (c) 2012 Paolo Borelli +# Copyright (c) 2012 Dan Winship +# Copyright (c) 2015 Bastien ROUCARIES +# +# This library is free software; you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation; either version 2.1 of the License, or (at +# your option) any later version. +# +# This library is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser +# General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see . + +#serial 21 + +AC_DEFUN([AX_CODE_COVERAGE],[ + dnl Check for --enable-code-coverage + AC_REQUIRE([AC_PROG_SED]) + + # allow to override gcov location + AC_ARG_WITH([gcov], + [AS_HELP_STRING([--with-gcov[=GCOV]], [use given GCOV for coverage (GCOV=gcov).])], + [_AX_CODE_COVERAGE_GCOV_PROG_WITH=$with_gcov], + [_AX_CODE_COVERAGE_GCOV_PROG_WITH=gcov]) + + AC_MSG_CHECKING([whether to build with code coverage support]) + AC_ARG_ENABLE([code-coverage], + AS_HELP_STRING([--enable-code-coverage], + [Whether to enable code coverage support]),, + enable_code_coverage=no) + + AM_CONDITIONAL([CODE_COVERAGE_ENABLED], [test x$enable_code_coverage = xyes]) + AC_SUBST([CODE_COVERAGE_ENABLED], [$enable_code_coverage]) + AC_MSG_RESULT($enable_code_coverage) + + AS_IF([ test "$enable_code_coverage" = "yes" ], [ + # check for gcov + AC_CHECK_TOOL([GCOV], + [$_AX_CODE_COVERAGE_GCOV_PROG_WITH], + [:]) + AS_IF([test "X$GCOV" = "X:"], + [AC_MSG_ERROR([gcov is needed to do coverage])]) + AC_SUBST([GCOV]) + + dnl Check if gcc is being used + AS_IF([ test "$GCC" = "no" ], [ + AC_MSG_ERROR([not compiling with gcc, which is required for gcov code coverage]) + ]) + + AC_CHECK_PROG([LCOV], [lcov], [lcov]) + AC_CHECK_PROG([GENHTML], [genhtml], [genhtml]) + + AS_IF([ test -z "$LCOV" ], [ + AC_MSG_ERROR([To enable code coverage reporting you must have lcov installed]) + ]) + + AS_IF([ test -z "$GENHTML" ], [ + AC_MSG_ERROR([Could not find genhtml from the lcov package]) + ]) + + dnl Build the code coverage flags + dnl Define CODE_COVERAGE_LDFLAGS for backwards compatibility + CODE_COVERAGE_CPPFLAGS="-DNDEBUG" + CODE_COVERAGE_CFLAGS="-O0 -g -fprofile-arcs -ftest-coverage" + CODE_COVERAGE_CXXFLAGS="-O0 -g -fprofile-arcs -ftest-coverage" + CODE_COVERAGE_LIBS="-lgcov" + CODE_COVERAGE_LDFLAGS="$CODE_COVERAGE_LIBS" + + AC_SUBST([CODE_COVERAGE_CPPFLAGS]) + AC_SUBST([CODE_COVERAGE_CFLAGS]) + AC_SUBST([CODE_COVERAGE_CXXFLAGS]) + AC_SUBST([CODE_COVERAGE_LIBS]) + AC_SUBST([CODE_COVERAGE_LDFLAGS]) + + [CODE_COVERAGE_RULES_CHECK=' + -$(A''M_V_at)$(MAKE) $(AM_MAKEFLAGS) -k check + $(A''M_V_at)$(MAKE) $(AM_MAKEFLAGS) code-coverage-capture +'] + [CODE_COVERAGE_RULES_CAPTURE=' + $(code_coverage_v_lcov_cap)$(LCOV) $(code_coverage_quiet) $(addprefix --directory ,$(CODE_COVERAGE_DIRECTORY)) --capture --output-file "$(CODE_COVERAGE_OUTPUT_FILE).tmp" --test-name "$(call code_coverage_sanitize,$(PACKAGE_NAME)-$(PACKAGE_VERSION))" --no-checksum --compat-libtool $(CODE_COVERAGE_LCOV_SHOPTS) $(CODE_COVERAGE_LCOV_OPTIONS) + $(code_coverage_v_lcov_ign)$(LCOV) $(code_coverage_quiet) $(addprefix --directory ,$(CODE_COVERAGE_DIRECTORY)) --remove "$(CODE_COVERAGE_OUTPUT_FILE).tmp" "/tmp/*" $(CODE_COVERAGE_IGNORE_PATTERN) --output-file "$(CODE_COVERAGE_OUTPUT_FILE)" $(CODE_COVERAGE_LCOV_SHOPTS) $(CODE_COVERAGE_LCOV_RMOPTS) + -@rm -f $(CODE_COVERAGE_OUTPUT_FILE).tmp + $(code_coverage_v_genhtml)LANG=C $(GENHTML) $(code_coverage_quiet) $(addprefix --prefix ,$(CODE_COVERAGE_DIRECTORY)) --output-directory "$(CODE_COVERAGE_OUTPUT_DIRECTORY)" --title "$(PACKAGE_NAME)-$(PACKAGE_VERSION) Code Coverage" --legend --show-details "$(CODE_COVERAGE_OUTPUT_FILE)" $(CODE_COVERAGE_GENHTML_OPTIONS) + @echo "file://$(abs_builddir)/$(CODE_COVERAGE_OUTPUT_DIRECTORY)/index.html" +'] + [CODE_COVERAGE_RULES_CLEAN=' +clean: code-coverage-clean +distclean: code-coverage-clean +code-coverage-clean: + -$(LCOV) --directory $(top_builddir) -z + -rm -rf $(CODE_COVERAGE_OUTPUT_FILE) $(CODE_COVERAGE_OUTPUT_FILE).tmp $(CODE_COVERAGE_OUTPUT_DIRECTORY) + -find . \( -name "*.gcda" -o -name "*.gcno" -o -name "*.gcov" \) -delete +'] + ], [ + [CODE_COVERAGE_RULES_CHECK=' + @echo "Need to reconfigure with --enable-code-coverage" +'] + CODE_COVERAGE_RULES_CAPTURE="$CODE_COVERAGE_RULES_CHECK" + CODE_COVERAGE_RULES_CLEAN='' + ]) + +[CODE_COVERAGE_RULES=' +# Code coverage +# +# Optional: +# - CODE_COVERAGE_DIRECTORY: Top-level directory for code coverage reporting. +# Multiple directories may be specified, separated by whitespace. +# (Default: $(top_builddir)) +# - CODE_COVERAGE_OUTPUT_FILE: Filename and path for the .info file generated +# by lcov for code coverage. (Default: +# $(PACKAGE_NAME)-$(PACKAGE_VERSION)-coverage.info) +# - CODE_COVERAGE_OUTPUT_DIRECTORY: Directory for generated code coverage +# reports to be created. (Default: +# $(PACKAGE_NAME)-$(PACKAGE_VERSION)-coverage) +# - CODE_COVERAGE_BRANCH_COVERAGE: Set to 1 to enforce branch coverage, +# set to 0 to disable it and leave empty to stay with the default. +# (Default: empty) +# - CODE_COVERAGE_LCOV_SHOPTS_DEFAULT: Extra options shared between both lcov +# instances. (Default: based on $CODE_COVERAGE_BRANCH_COVERAGE) +# - CODE_COVERAGE_LCOV_SHOPTS: Extra options to shared between both lcov +# instances. (Default: $CODE_COVERAGE_LCOV_SHOPTS_DEFAULT) +# - CODE_COVERAGE_LCOV_OPTIONS_GCOVPATH: --gcov-tool pathtogcov +# - CODE_COVERAGE_LCOV_OPTIONS_DEFAULT: Extra options to pass to the +# collecting lcov instance. (Default: $CODE_COVERAGE_LCOV_OPTIONS_GCOVPATH) +# - CODE_COVERAGE_LCOV_OPTIONS: Extra options to pass to the collecting lcov +# instance. (Default: $CODE_COVERAGE_LCOV_OPTIONS_DEFAULT) +# - CODE_COVERAGE_LCOV_RMOPTS_DEFAULT: Extra options to pass to the filtering +# lcov instance. (Default: empty) +# - CODE_COVERAGE_LCOV_RMOPTS: Extra options to pass to the filtering lcov +# instance. (Default: $CODE_COVERAGE_LCOV_RMOPTS_DEFAULT) +# - CODE_COVERAGE_GENHTML_OPTIONS_DEFAULT: Extra options to pass to the +# genhtml instance. (Default: based on $CODE_COVERAGE_BRANCH_COVERAGE) +# - CODE_COVERAGE_GENHTML_OPTIONS: Extra options to pass to the genhtml +# instance. (Default: $CODE_COVERAGE_GENHTML_OPTIONS_DEFAULT) +# - CODE_COVERAGE_IGNORE_PATTERN: Extra glob pattern of files to ignore +# +# The generated report will be titled using the $(PACKAGE_NAME) and +# $(PACKAGE_VERSION). In order to add the current git hash to the title, +# use the git-version-gen script, available online. + +# Optional variables +CODE_COVERAGE_DIRECTORY ?= $(top_builddir) +CODE_COVERAGE_OUTPUT_FILE ?= $(PACKAGE_NAME)-$(PACKAGE_VERSION)-coverage.info +CODE_COVERAGE_OUTPUT_DIRECTORY ?= $(PACKAGE_NAME)-$(PACKAGE_VERSION)-coverage +CODE_COVERAGE_BRANCH_COVERAGE ?= +CODE_COVERAGE_LCOV_SHOPTS_DEFAULT ?= $(if $(CODE_COVERAGE_BRANCH_COVERAGE),\ +--rc lcov_branch_coverage=$(CODE_COVERAGE_BRANCH_COVERAGE)) +CODE_COVERAGE_LCOV_SHOPTS ?= $(CODE_COVERAGE_LCOV_SHOPTS_DEFAULT) +CODE_COVERAGE_LCOV_OPTIONS_GCOVPATH ?= --gcov-tool "$(GCOV)" +CODE_COVERAGE_LCOV_OPTIONS_DEFAULT ?= $(CODE_COVERAGE_LCOV_OPTIONS_GCOVPATH) +CODE_COVERAGE_LCOV_OPTIONS ?= $(CODE_COVERAGE_LCOV_OPTIONS_DEFAULT) +CODE_COVERAGE_LCOV_RMOPTS_DEFAULT ?= +CODE_COVERAGE_LCOV_RMOPTS ?= $(CODE_COVERAGE_LCOV_RMOPTS_DEFAULT) +CODE_COVERAGE_GENHTML_OPTIONS_DEFAULT ?=\ +$(if $(CODE_COVERAGE_BRANCH_COVERAGE),\ +--rc genhtml_branch_coverage=$(CODE_COVERAGE_BRANCH_COVERAGE)) +CODE_COVERAGE_GENHTML_OPTIONS ?= $(CODE_COVERAGE_GENHTML_OPTIONS_DEFAULTS) +CODE_COVERAGE_IGNORE_PATTERN ?= + +code_coverage_v_lcov_cap = $(code_coverage_v_lcov_cap_$(V)) +code_coverage_v_lcov_cap_ = $(code_coverage_v_lcov_cap_$(AM_DEFAULT_VERBOSITY)) +code_coverage_v_lcov_cap_0 = @echo " LCOV --capture"\ + $(CODE_COVERAGE_OUTPUT_FILE); +code_coverage_v_lcov_ign = $(code_coverage_v_lcov_ign_$(V)) +code_coverage_v_lcov_ign_ = $(code_coverage_v_lcov_ign_$(AM_DEFAULT_VERBOSITY)) +code_coverage_v_lcov_ign_0 = @echo " LCOV --remove /tmp/*"\ + $(CODE_COVERAGE_IGNORE_PATTERN); +code_coverage_v_genhtml = $(code_coverage_v_genhtml_$(V)) +code_coverage_v_genhtml_ = $(code_coverage_v_genhtml_$(AM_DEFAULT_VERBOSITY)) +code_coverage_v_genhtml_0 = @echo " GEN " $(CODE_COVERAGE_OUTPUT_DIRECTORY); +code_coverage_quiet = $(code_coverage_quiet_$(V)) +code_coverage_quiet_ = $(code_coverage_quiet_$(AM_DEFAULT_VERBOSITY)) +code_coverage_quiet_0 = --quiet + +# sanitizes the test-name: replaces with underscores: dashes and dots +code_coverage_sanitize = $(subst -,_,$(subst .,_,$(1))) + +# Use recursive makes in order to ignore errors during check +check-code-coverage:'"$CODE_COVERAGE_RULES_CHECK"' + +# Capture code coverage data +code-coverage-capture: code-coverage-capture-hook'"$CODE_COVERAGE_RULES_CAPTURE"' + +# Hook rule executed before code-coverage-capture, overridable by the user +code-coverage-capture-hook: + +'"$CODE_COVERAGE_RULES_CLEAN"' + +GITIGNOREFILES ?= +GITIGNOREFILES += $(CODE_COVERAGE_OUTPUT_FILE) $(CODE_COVERAGE_OUTPUT_DIRECTORY) + +A''M_DISTCHECK_CONFIGURE_FLAGS ?= +A''M_DISTCHECK_CONFIGURE_FLAGS += --disable-code-coverage + +.PHONY: check-code-coverage code-coverage-capture code-coverage-capture-hook code-coverage-clean +'] + + AC_SUBST([CODE_COVERAGE_RULES]) + m4_ifdef([_AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE([CODE_COVERAGE_RULES])]) +]) diff --git a/m4/curses.m4 b/m4/curses.m4 index 2e8d151..031e1ee 100644 --- a/m4/curses.m4 +++ b/m4/curses.m4 @@ -32,7 +32,7 @@ AC_DEFUN([tinc_CURSES], ) AC_CHECK_LIB(ncurses, initscr, - [CURSES_LIBS="-lncurses"], + [CURSES_LIBS="-lncurses"; AC_CHECK_LIB(tinfo, wtimeout, [CURSES_LIBS+=" -ltinfo"], [])], [AC_CHECK_LIB(curses, initscr, [CURSES_LIBS="-lcurses"], [AC_MSG_ERROR("curses libraries not found.")] diff --git a/m4/openssl.m4 b/m4/openssl.m4 index 4afcff2..0ff939b 100644 --- a/m4/openssl.m4 +++ b/m4/openssl.m4 @@ -49,10 +49,11 @@ AC_DEFUN([tinc_OPENSSL], [AC_MSG_ERROR([Missing LibreSSL/OpenSSL functionality, make sure you have installed the latest version.]); break], ) - AC_CHECK_DECLS([OpenSSL_add_all_algorithms EVP_aes_256_cfb], , + AC_CHECK_DECLS([OpenSSL_add_all_algorithms, EVP_aes_256_cfb], , [AC_MSG_ERROR([Missing LibreSSL/OpenSSL functionality, make sure you have installed the latest version.]); break], [#include ] ) AC_CHECK_FUNCS([BN_GENCB_new ERR_remove_state RSA_set0_key], , , [#include ]) + AC_CHECK_FUNCS([HMAC_CTX_new], , , [#include ]) ]) diff --git a/missing b/missing index f62bbae..625aeb1 100755 --- a/missing +++ b/missing @@ -1,9 +1,9 @@ #! /bin/sh # Common wrapper for a few potentially missing GNU programs. -scriptversion=2013-10-28.13; # UTC +scriptversion=2018-03-07.03; # UTC -# Copyright (C) 1996-2014 Free Software Foundation, Inc. +# Copyright (C) 1996-2018 Free Software Foundation, Inc. # Originally written by Fran,cois Pinard , 1996. # This program is free software; you can redistribute it and/or modify @@ -17,7 +17,7 @@ scriptversion=2013-10-28.13; # UTC # GNU General Public License for more details. # You should have received a copy of the GNU General Public License -# along with this program. If not, see . +# along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a @@ -101,9 +101,9 @@ else exit $st fi -perl_URL=http://www.perl.org/ -flex_URL=http://flex.sourceforge.net/ -gnu_software_URL=http://www.gnu.org/software +perl_URL=https://www.perl.org/ +flex_URL=https://github.com/westes/flex +gnu_software_URL=https://www.gnu.org/software program_details () { @@ -207,9 +207,9 @@ give_advice "$1" | sed -e '1s/^/WARNING: /' \ exit $st # Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) +# eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" -# time-stamp-time-zone: "UTC" +# time-stamp-time-zone: "UTC0" # time-stamp-end: "; # UTC" # End: diff --git a/src/Makefile.am b/src/Makefile.am index 7be46d9..cb188d2 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -42,6 +42,7 @@ chacha_poly1305_SOURCES = \ chacha-poly1305/poly1305.c chacha-poly1305/poly1305.h tincd_SOURCES = \ + address_cache.c address_cache.h \ autoconnect.c autoconnect.h \ buffer.c buffer.h \ cipher.h \ @@ -278,10 +279,11 @@ endif tinc_LDADD = $(READLINE_LIBS) $(CURSES_LIBS) sptps_speed_LDADD = -lrt -LIBS = @LIBS@ -lm +LIBS = @LIBS@ -lm $(CODE_COVERAGE_LIBS) if TUNEMU LIBS += -lpcap endif -AM_CFLAGS = -DCONFDIR=\"$(sysconfdir)\" -DLOCALSTATEDIR=\"$(localstatedir)\" -DSBINDIR=\"$(sbindir)\" -iquote. +AM_CFLAGS = -DCONFDIR=\"$(sysconfdir)\" -DRUNSTATEDIR=\"$(runstatedir)\" -DLOCALSTATEDIR=\"$(localstatedir)\" -DSBINDIR=\"$(sbindir)\" -iquote. $(CODE_COVERAGE_CFLAGS) +AM_CPPFLAGS = $(CODE_COVERAGE_CPPFLAGS) diff --git a/src/Makefile.in b/src/Makefile.in index a132cf1..6651ad9 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15.1 from Makefile.am. +# Makefile.in generated by automake 1.16.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2017 Free Software Foundation, Inc. +# Copyright (C) 1994-2018 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -202,6 +202,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \ $(top_srcdir)/m4/ax_cflags_warn_all.m4 \ $(top_srcdir)/m4/ax_check_compile_flag.m4 \ $(top_srcdir)/m4/ax_check_link_flag.m4 \ + $(top_srcdir)/m4/ax_code_coverage.m4 \ $(top_srcdir)/m4/ax_require_defined.m4 \ $(top_srcdir)/m4/curses.m4 $(top_srcdir)/m4/libgcrypt.m4 \ $(top_srcdir)/m4/lzo.m4 $(top_srcdir)/m4/miniupnpc.m4 \ @@ -336,22 +337,23 @@ am_tinc_OBJECTS = dropin.$(OBJEXT) fsck.$(OBJEXT) ifconfig.$(OBJEXT) \ tinc_OBJECTS = $(am_tinc_OBJECTS) am__DEPENDENCIES_1 = tinc_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) -am__tincd_SOURCES_DIST = autoconnect.c autoconnect.h buffer.c buffer.h \ - cipher.h conf.c conf.h connection.c connection.h control.c \ - control.h control_common.h crypto.h device.h digest.h dropin.c \ - dropin.h dummy_device.c ecdh.h ecdsa.h ecdsagen.h edge.c \ - edge.h ethernet.h event.c event.h fd_device.c graph.c graph.h \ - hash.c hash.h have.h ipv4.h ipv6.h list.c list.h logger.c \ - logger.h meta.c meta.h multicast_device.c names.c names.h \ - net.c net.h net_packet.c net_setup.c net_socket.c netutl.c \ - netutl.h node.c node.h prf.h process.c process.h protocol.c \ - protocol.h protocol_auth.c protocol_edge.c protocol_key.c \ - protocol_misc.c protocol_subnet.c raw_socket_device.c route.c \ - route.h rsa.h rsagen.h script.c script.h splay_tree.c \ - splay_tree.h sptps.c sptps.h subnet.c subnet.h subnet_parse.c \ - system.h tincd.c utils.c utils.h xalloc.h version.c version.h \ - ed25519/ecdh.c ed25519/ecdsa.c ed25519/ed25519.h ed25519/fe.c \ - ed25519/fe.h ed25519/fixedint.h ed25519/ge.c ed25519/ge.h \ +am__tincd_SOURCES_DIST = address_cache.c address_cache.h autoconnect.c \ + autoconnect.h buffer.c buffer.h cipher.h conf.c conf.h \ + connection.c connection.h control.c control.h control_common.h \ + crypto.h device.h digest.h dropin.c dropin.h dummy_device.c \ + ecdh.h ecdsa.h ecdsagen.h edge.c edge.h ethernet.h event.c \ + event.h fd_device.c graph.c graph.h hash.c hash.h have.h \ + ipv4.h ipv6.h list.c list.h logger.c logger.h meta.c meta.h \ + multicast_device.c names.c names.h net.c net.h net_packet.c \ + net_setup.c net_socket.c netutl.c netutl.h node.c node.h prf.h \ + process.c process.h protocol.c protocol.h protocol_auth.c \ + protocol_edge.c protocol_key.c protocol_misc.c \ + protocol_subnet.c raw_socket_device.c route.c route.h rsa.h \ + rsagen.h script.c script.h splay_tree.c splay_tree.h sptps.c \ + sptps.h subnet.c subnet.h subnet_parse.c system.h tincd.c \ + utils.c utils.h xalloc.h version.c version.h ed25519/ecdh.c \ + ed25519/ecdsa.c ed25519/ed25519.h ed25519/fe.c ed25519/fe.h \ + ed25519/fixedint.h ed25519/ge.c ed25519/ge.h \ ed25519/key_exchange.c ed25519/keypair.c \ ed25519/precomp_data.h ed25519/sc.c ed25519/sc.h \ ed25519/sha512.c ed25519/sha512.h ed25519/sign.c \ @@ -384,15 +386,15 @@ am__tincd_SOURCES_DIST = autoconnect.c autoconnect.h buffer.c buffer.h \ @GCRYPT_TRUE@@OPENSSL_FALSE@ gcrypt/prf.$(OBJEXT) \ @GCRYPT_TRUE@@OPENSSL_FALSE@ gcrypt/rsa.$(OBJEXT) @MINIUPNPC_TRUE@am__objects_23 = upnp.$(OBJEXT) -am_tincd_OBJECTS = autoconnect.$(OBJEXT) buffer.$(OBJEXT) \ - conf.$(OBJEXT) connection.$(OBJEXT) control.$(OBJEXT) \ - dropin.$(OBJEXT) dummy_device.$(OBJEXT) edge.$(OBJEXT) \ - event.$(OBJEXT) fd_device.$(OBJEXT) graph.$(OBJEXT) \ - hash.$(OBJEXT) list.$(OBJEXT) logger.$(OBJEXT) meta.$(OBJEXT) \ - multicast_device.$(OBJEXT) names.$(OBJEXT) net.$(OBJEXT) \ - net_packet.$(OBJEXT) net_setup.$(OBJEXT) net_socket.$(OBJEXT) \ - netutl.$(OBJEXT) node.$(OBJEXT) process.$(OBJEXT) \ - protocol.$(OBJEXT) protocol_auth.$(OBJEXT) \ +am_tincd_OBJECTS = address_cache.$(OBJEXT) autoconnect.$(OBJEXT) \ + buffer.$(OBJEXT) conf.$(OBJEXT) connection.$(OBJEXT) \ + control.$(OBJEXT) dropin.$(OBJEXT) dummy_device.$(OBJEXT) \ + edge.$(OBJEXT) event.$(OBJEXT) fd_device.$(OBJEXT) \ + graph.$(OBJEXT) hash.$(OBJEXT) list.$(OBJEXT) logger.$(OBJEXT) \ + meta.$(OBJEXT) multicast_device.$(OBJEXT) names.$(OBJEXT) \ + net.$(OBJEXT) net_packet.$(OBJEXT) net_setup.$(OBJEXT) \ + net_socket.$(OBJEXT) netutl.$(OBJEXT) node.$(OBJEXT) \ + process.$(OBJEXT) protocol.$(OBJEXT) protocol_auth.$(OBJEXT) \ protocol_edge.$(OBJEXT) protocol_key.$(OBJEXT) \ protocol_misc.$(OBJEXT) protocol_subnet.$(OBJEXT) \ raw_socket_device.$(OBJEXT) route.$(OBJEXT) script.$(OBJEXT) \ @@ -423,7 +425,54 @@ am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = depcomp = $(SHELL) $(top_srcdir)/depcomp -am__depfiles_maybe = depfiles +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/address_cache.Po \ + ./$(DEPDIR)/autoconnect.Po ./$(DEPDIR)/buffer.Po \ + ./$(DEPDIR)/conf.Po ./$(DEPDIR)/connection.Po \ + ./$(DEPDIR)/control.Po ./$(DEPDIR)/dropin.Po \ + ./$(DEPDIR)/dummy_device.Po ./$(DEPDIR)/edge.Po \ + ./$(DEPDIR)/event.Po ./$(DEPDIR)/fd_device.Po \ + ./$(DEPDIR)/fsck.Po ./$(DEPDIR)/getopt.Po \ + ./$(DEPDIR)/getopt1.Po ./$(DEPDIR)/graph.Po \ + ./$(DEPDIR)/hash.Po ./$(DEPDIR)/ifconfig.Po \ + ./$(DEPDIR)/info.Po ./$(DEPDIR)/invitation.Po \ + ./$(DEPDIR)/list.Po ./$(DEPDIR)/logger.Po ./$(DEPDIR)/meta.Po \ + ./$(DEPDIR)/multicast_device.Po ./$(DEPDIR)/names.Po \ + ./$(DEPDIR)/net.Po ./$(DEPDIR)/net_packet.Po \ + ./$(DEPDIR)/net_setup.Po ./$(DEPDIR)/net_socket.Po \ + ./$(DEPDIR)/netutl.Po ./$(DEPDIR)/node.Po \ + ./$(DEPDIR)/process.Po ./$(DEPDIR)/protocol.Po \ + ./$(DEPDIR)/protocol_auth.Po ./$(DEPDIR)/protocol_edge.Po \ + ./$(DEPDIR)/protocol_key.Po ./$(DEPDIR)/protocol_misc.Po \ + ./$(DEPDIR)/protocol_subnet.Po \ + ./$(DEPDIR)/raw_socket_device.Po ./$(DEPDIR)/route.Po \ + ./$(DEPDIR)/script.Po ./$(DEPDIR)/splay_tree.Po \ + ./$(DEPDIR)/sptps.Po ./$(DEPDIR)/sptps_keypair.Po \ + ./$(DEPDIR)/sptps_speed.Po ./$(DEPDIR)/sptps_test.Po \ + ./$(DEPDIR)/subnet.Po ./$(DEPDIR)/subnet_parse.Po \ + ./$(DEPDIR)/tincctl.Po ./$(DEPDIR)/tincd.Po ./$(DEPDIR)/top.Po \ + ./$(DEPDIR)/uml_device.Po ./$(DEPDIR)/upnp.Po \ + ./$(DEPDIR)/utils.Po ./$(DEPDIR)/vde_device.Po \ + ./$(DEPDIR)/version.Po bsd/$(DEPDIR)/device.Po \ + bsd/$(DEPDIR)/tunemu.Po \ + chacha-poly1305/$(DEPDIR)/chacha-poly1305.Po \ + chacha-poly1305/$(DEPDIR)/chacha.Po \ + chacha-poly1305/$(DEPDIR)/poly1305.Po \ + cygwin/$(DEPDIR)/device.Po ed25519/$(DEPDIR)/ecdh.Po \ + ed25519/$(DEPDIR)/ecdsa.Po ed25519/$(DEPDIR)/ecdsagen.Po \ + ed25519/$(DEPDIR)/fe.Po ed25519/$(DEPDIR)/ge.Po \ + ed25519/$(DEPDIR)/key_exchange.Po ed25519/$(DEPDIR)/keypair.Po \ + ed25519/$(DEPDIR)/sc.Po ed25519/$(DEPDIR)/sha512.Po \ + ed25519/$(DEPDIR)/sign.Po ed25519/$(DEPDIR)/verify.Po \ + gcrypt/$(DEPDIR)/cipher.Po gcrypt/$(DEPDIR)/crypto.Po \ + gcrypt/$(DEPDIR)/digest.Po gcrypt/$(DEPDIR)/prf.Po \ + gcrypt/$(DEPDIR)/rsa.Po gcrypt/$(DEPDIR)/rsagen.Po \ + linux/$(DEPDIR)/device.Po mingw/$(DEPDIR)/device.Po \ + nolegacy/$(DEPDIR)/crypto.Po nolegacy/$(DEPDIR)/prf.Po \ + openssl/$(DEPDIR)/cipher.Po openssl/$(DEPDIR)/crypto.Po \ + openssl/$(DEPDIR)/digest.Po openssl/$(DEPDIR)/prf.Po \ + openssl/$(DEPDIR)/rsa.Po openssl/$(DEPDIR)/rsagen.Po \ + solaris/$(DEPDIR)/device.Po am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) @@ -478,6 +527,12 @@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ +CODE_COVERAGE_CFLAGS = @CODE_COVERAGE_CFLAGS@ +CODE_COVERAGE_CPPFLAGS = @CODE_COVERAGE_CPPFLAGS@ +CODE_COVERAGE_CXXFLAGS = @CODE_COVERAGE_CXXFLAGS@ +CODE_COVERAGE_ENABLED = @CODE_COVERAGE_ENABLED@ +CODE_COVERAGE_LDFLAGS = @CODE_COVERAGE_LDFLAGS@ +CODE_COVERAGE_LIBS = @CODE_COVERAGE_LIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CURSES_LIBS = @CURSES_LIBS@ @@ -489,16 +544,18 @@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ +GCOV = @GCOV@ +GENHTML = @GENHTML@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LCOV = @LCOV@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ -LIBS = @LIBS@ -lm $(am__append_30) -LN_S = @LN_S@ +LIBS = @LIBS@ -lm $(CODE_COVERAGE_LIBS) $(am__append_30) LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MINIUPNPC_LIBS = @MINIUPNPC_LIBS@ @@ -513,6 +570,7 @@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ READLINE_LIBS = @READLINE_LIBS@ +SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ @@ -588,16 +646,17 @@ chacha_poly1305_SOURCES = \ chacha-poly1305/chacha-poly1305.c chacha-poly1305/chacha-poly1305.h \ chacha-poly1305/poly1305.c chacha-poly1305/poly1305.h -tincd_SOURCES = autoconnect.c autoconnect.h buffer.c buffer.h cipher.h \ - conf.c conf.h connection.c connection.h control.c control.h \ - control_common.h crypto.h device.h digest.h dropin.c dropin.h \ - dummy_device.c ecdh.h ecdsa.h ecdsagen.h edge.c edge.h \ - ethernet.h event.c event.h fd_device.c graph.c graph.h hash.c \ - hash.h have.h ipv4.h ipv6.h list.c list.h logger.c logger.h \ - meta.c meta.h multicast_device.c names.c names.h net.c net.h \ - net_packet.c net_setup.c net_socket.c netutl.c netutl.h node.c \ - node.h prf.h process.c process.h protocol.c protocol.h \ - protocol_auth.c protocol_edge.c protocol_key.c protocol_misc.c \ +tincd_SOURCES = address_cache.c address_cache.h autoconnect.c \ + autoconnect.h buffer.c buffer.h cipher.h conf.c conf.h \ + connection.c connection.h control.c control.h control_common.h \ + crypto.h device.h digest.h dropin.c dropin.h dummy_device.c \ + ecdh.h ecdsa.h ecdsagen.h edge.c edge.h ethernet.h event.c \ + event.h fd_device.c graph.c graph.h hash.c hash.h have.h \ + ipv4.h ipv6.h list.c list.h logger.c logger.h meta.c meta.h \ + multicast_device.c names.c names.h net.c net.h net_packet.c \ + net_setup.c net_socket.c netutl.c netutl.h node.c node.h prf.h \ + process.c process.h protocol.c protocol.h protocol_auth.c \ + protocol_edge.c protocol_key.c protocol_misc.c \ protocol_subnet.c raw_socket_device.c route.c route.h rsa.h \ rsagen.h script.c script.h splay_tree.c splay_tree.h sptps.c \ sptps.h subnet.c subnet.h subnet_parse.c system.h tincd.c \ @@ -632,7 +691,8 @@ sptps_speed_SOURCES = logger.c logger.h sptps.c sptps.h sptps_speed.c \ @MINIUPNPC_TRUE@tincd_LDFLAGS = -pthread tinc_LDADD = $(READLINE_LIBS) $(CURSES_LIBS) sptps_speed_LDADD = -lrt -AM_CFLAGS = -DCONFDIR=\"$(sysconfdir)\" -DLOCALSTATEDIR=\"$(localstatedir)\" -DSBINDIR=\"$(sbindir)\" -iquote. +AM_CFLAGS = -DCONFDIR=\"$(sysconfdir)\" -DRUNSTATEDIR=\"$(runstatedir)\" -DLOCALSTATEDIR=\"$(localstatedir)\" -DSBINDIR=\"$(sbindir)\" -iquote. $(CODE_COVERAGE_CFLAGS) +AM_CPPFLAGS = $(CODE_COVERAGE_CPPFLAGS) all: all-am .SUFFIXES: @@ -654,8 +714,8 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) @@ -893,94 +953,101 @@ mostlyclean-compile: distclean-compile: -rm -f *.tab.c -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/autoconnect.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/buffer.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/conf.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/connection.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/control.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dropin.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dummy_device.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/edge.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/event.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fd_device.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fsck.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getopt.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getopt1.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/graph.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hash.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ifconfig.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/info.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/invitation.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/list.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/logger.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/meta.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/multicast_device.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/names.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/net.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/net_packet.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/net_setup.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/net_socket.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/netutl.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/node.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/process.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protocol.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protocol_auth.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protocol_edge.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protocol_key.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protocol_misc.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protocol_subnet.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/raw_socket_device.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/route.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/script.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/splay_tree.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sptps.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sptps_keypair.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sptps_speed.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sptps_test.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/subnet.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/subnet_parse.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tincctl.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tincd.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/top.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uml_device.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/upnp.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/utils.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vde_device.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/version.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@bsd/$(DEPDIR)/device.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@bsd/$(DEPDIR)/tunemu.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@chacha-poly1305/$(DEPDIR)/chacha-poly1305.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@chacha-poly1305/$(DEPDIR)/chacha.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@chacha-poly1305/$(DEPDIR)/poly1305.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cygwin/$(DEPDIR)/device.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/ecdh.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/ecdsa.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/ecdsagen.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/fe.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/ge.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/key_exchange.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/keypair.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/sc.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/sha512.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/sign.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/verify.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@gcrypt/$(DEPDIR)/cipher.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@gcrypt/$(DEPDIR)/crypto.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@gcrypt/$(DEPDIR)/digest.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@gcrypt/$(DEPDIR)/prf.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@gcrypt/$(DEPDIR)/rsa.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@gcrypt/$(DEPDIR)/rsagen.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@linux/$(DEPDIR)/device.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@mingw/$(DEPDIR)/device.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@nolegacy/$(DEPDIR)/crypto.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@nolegacy/$(DEPDIR)/prf.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@openssl/$(DEPDIR)/cipher.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@openssl/$(DEPDIR)/crypto.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@openssl/$(DEPDIR)/digest.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@openssl/$(DEPDIR)/prf.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@openssl/$(DEPDIR)/rsa.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@openssl/$(DEPDIR)/rsagen.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@solaris/$(DEPDIR)/device.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/address_cache.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/autoconnect.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/buffer.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/conf.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/connection.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/control.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dropin.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dummy_device.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/edge.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/event.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fd_device.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fsck.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getopt.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getopt1.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/graph.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hash.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ifconfig.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/info.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/invitation.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/list.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/logger.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/meta.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/multicast_device.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/names.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/net.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/net_packet.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/net_setup.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/net_socket.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/netutl.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/node.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/process.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protocol.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protocol_auth.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protocol_edge.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protocol_key.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protocol_misc.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protocol_subnet.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/raw_socket_device.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/route.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/script.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/splay_tree.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sptps.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sptps_keypair.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sptps_speed.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sptps_test.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/subnet.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/subnet_parse.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tincctl.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tincd.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/top.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uml_device.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/upnp.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/utils.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vde_device.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/version.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@bsd/$(DEPDIR)/device.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@bsd/$(DEPDIR)/tunemu.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@chacha-poly1305/$(DEPDIR)/chacha-poly1305.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@chacha-poly1305/$(DEPDIR)/chacha.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@chacha-poly1305/$(DEPDIR)/poly1305.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@cygwin/$(DEPDIR)/device.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/ecdh.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/ecdsa.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/ecdsagen.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/fe.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/ge.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/key_exchange.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/keypair.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/sc.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/sha512.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/sign.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/verify.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@gcrypt/$(DEPDIR)/cipher.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@gcrypt/$(DEPDIR)/crypto.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@gcrypt/$(DEPDIR)/digest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@gcrypt/$(DEPDIR)/prf.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@gcrypt/$(DEPDIR)/rsa.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@gcrypt/$(DEPDIR)/rsagen.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@linux/$(DEPDIR)/device.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@mingw/$(DEPDIR)/device.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@nolegacy/$(DEPDIR)/crypto.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@nolegacy/$(DEPDIR)/prf.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@openssl/$(DEPDIR)/cipher.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@openssl/$(DEPDIR)/crypto.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@openssl/$(DEPDIR)/digest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@openssl/$(DEPDIR)/prf.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@openssl/$(DEPDIR)/rsa.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@openssl/$(DEPDIR)/rsagen.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@solaris/$(DEPDIR)/device.Po@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @@ -1050,7 +1117,10 @@ cscopelist-am: $(am__tagged_files) distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags -distdir: $(DISTFILES) +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ @@ -1145,7 +1215,95 @@ clean-am: clean-checkPROGRAMS clean-generic clean-sbinPROGRAMS \ mostlyclean-am distclean: distclean-am - -rm -rf ./$(DEPDIR) bsd/$(DEPDIR) chacha-poly1305/$(DEPDIR) cygwin/$(DEPDIR) ed25519/$(DEPDIR) gcrypt/$(DEPDIR) linux/$(DEPDIR) mingw/$(DEPDIR) nolegacy/$(DEPDIR) openssl/$(DEPDIR) solaris/$(DEPDIR) + -rm -f ./$(DEPDIR)/address_cache.Po + -rm -f ./$(DEPDIR)/autoconnect.Po + -rm -f ./$(DEPDIR)/buffer.Po + -rm -f ./$(DEPDIR)/conf.Po + -rm -f ./$(DEPDIR)/connection.Po + -rm -f ./$(DEPDIR)/control.Po + -rm -f ./$(DEPDIR)/dropin.Po + -rm -f ./$(DEPDIR)/dummy_device.Po + -rm -f ./$(DEPDIR)/edge.Po + -rm -f ./$(DEPDIR)/event.Po + -rm -f ./$(DEPDIR)/fd_device.Po + -rm -f ./$(DEPDIR)/fsck.Po + -rm -f ./$(DEPDIR)/getopt.Po + -rm -f ./$(DEPDIR)/getopt1.Po + -rm -f ./$(DEPDIR)/graph.Po + -rm -f ./$(DEPDIR)/hash.Po + -rm -f ./$(DEPDIR)/ifconfig.Po + -rm -f ./$(DEPDIR)/info.Po + -rm -f ./$(DEPDIR)/invitation.Po + -rm -f ./$(DEPDIR)/list.Po + -rm -f ./$(DEPDIR)/logger.Po + -rm -f ./$(DEPDIR)/meta.Po + -rm -f ./$(DEPDIR)/multicast_device.Po + -rm -f ./$(DEPDIR)/names.Po + -rm -f ./$(DEPDIR)/net.Po + -rm -f ./$(DEPDIR)/net_packet.Po + -rm -f ./$(DEPDIR)/net_setup.Po + -rm -f ./$(DEPDIR)/net_socket.Po + -rm -f ./$(DEPDIR)/netutl.Po + -rm -f ./$(DEPDIR)/node.Po + -rm -f ./$(DEPDIR)/process.Po + -rm -f ./$(DEPDIR)/protocol.Po + -rm -f ./$(DEPDIR)/protocol_auth.Po + -rm -f ./$(DEPDIR)/protocol_edge.Po + -rm -f ./$(DEPDIR)/protocol_key.Po + -rm -f ./$(DEPDIR)/protocol_misc.Po + -rm -f ./$(DEPDIR)/protocol_subnet.Po + -rm -f ./$(DEPDIR)/raw_socket_device.Po + -rm -f ./$(DEPDIR)/route.Po + -rm -f ./$(DEPDIR)/script.Po + -rm -f ./$(DEPDIR)/splay_tree.Po + -rm -f ./$(DEPDIR)/sptps.Po + -rm -f ./$(DEPDIR)/sptps_keypair.Po + -rm -f ./$(DEPDIR)/sptps_speed.Po + -rm -f ./$(DEPDIR)/sptps_test.Po + -rm -f ./$(DEPDIR)/subnet.Po + -rm -f ./$(DEPDIR)/subnet_parse.Po + -rm -f ./$(DEPDIR)/tincctl.Po + -rm -f ./$(DEPDIR)/tincd.Po + -rm -f ./$(DEPDIR)/top.Po + -rm -f ./$(DEPDIR)/uml_device.Po + -rm -f ./$(DEPDIR)/upnp.Po + -rm -f ./$(DEPDIR)/utils.Po + -rm -f ./$(DEPDIR)/vde_device.Po + -rm -f ./$(DEPDIR)/version.Po + -rm -f bsd/$(DEPDIR)/device.Po + -rm -f bsd/$(DEPDIR)/tunemu.Po + -rm -f chacha-poly1305/$(DEPDIR)/chacha-poly1305.Po + -rm -f chacha-poly1305/$(DEPDIR)/chacha.Po + -rm -f chacha-poly1305/$(DEPDIR)/poly1305.Po + -rm -f cygwin/$(DEPDIR)/device.Po + -rm -f ed25519/$(DEPDIR)/ecdh.Po + -rm -f ed25519/$(DEPDIR)/ecdsa.Po + -rm -f ed25519/$(DEPDIR)/ecdsagen.Po + -rm -f ed25519/$(DEPDIR)/fe.Po + -rm -f ed25519/$(DEPDIR)/ge.Po + -rm -f ed25519/$(DEPDIR)/key_exchange.Po + -rm -f ed25519/$(DEPDIR)/keypair.Po + -rm -f ed25519/$(DEPDIR)/sc.Po + -rm -f ed25519/$(DEPDIR)/sha512.Po + -rm -f ed25519/$(DEPDIR)/sign.Po + -rm -f ed25519/$(DEPDIR)/verify.Po + -rm -f gcrypt/$(DEPDIR)/cipher.Po + -rm -f gcrypt/$(DEPDIR)/crypto.Po + -rm -f gcrypt/$(DEPDIR)/digest.Po + -rm -f gcrypt/$(DEPDIR)/prf.Po + -rm -f gcrypt/$(DEPDIR)/rsa.Po + -rm -f gcrypt/$(DEPDIR)/rsagen.Po + -rm -f linux/$(DEPDIR)/device.Po + -rm -f mingw/$(DEPDIR)/device.Po + -rm -f nolegacy/$(DEPDIR)/crypto.Po + -rm -f nolegacy/$(DEPDIR)/prf.Po + -rm -f openssl/$(DEPDIR)/cipher.Po + -rm -f openssl/$(DEPDIR)/crypto.Po + -rm -f openssl/$(DEPDIR)/digest.Po + -rm -f openssl/$(DEPDIR)/prf.Po + -rm -f openssl/$(DEPDIR)/rsa.Po + -rm -f openssl/$(DEPDIR)/rsagen.Po + -rm -f solaris/$(DEPDIR)/device.Po -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags @@ -1191,7 +1349,95 @@ install-ps-am: installcheck-am: installcheck-sbinPROGRAMS maintainer-clean: maintainer-clean-am - -rm -rf ./$(DEPDIR) bsd/$(DEPDIR) chacha-poly1305/$(DEPDIR) cygwin/$(DEPDIR) ed25519/$(DEPDIR) gcrypt/$(DEPDIR) linux/$(DEPDIR) mingw/$(DEPDIR) nolegacy/$(DEPDIR) openssl/$(DEPDIR) solaris/$(DEPDIR) + -rm -f ./$(DEPDIR)/address_cache.Po + -rm -f ./$(DEPDIR)/autoconnect.Po + -rm -f ./$(DEPDIR)/buffer.Po + -rm -f ./$(DEPDIR)/conf.Po + -rm -f ./$(DEPDIR)/connection.Po + -rm -f ./$(DEPDIR)/control.Po + -rm -f ./$(DEPDIR)/dropin.Po + -rm -f ./$(DEPDIR)/dummy_device.Po + -rm -f ./$(DEPDIR)/edge.Po + -rm -f ./$(DEPDIR)/event.Po + -rm -f ./$(DEPDIR)/fd_device.Po + -rm -f ./$(DEPDIR)/fsck.Po + -rm -f ./$(DEPDIR)/getopt.Po + -rm -f ./$(DEPDIR)/getopt1.Po + -rm -f ./$(DEPDIR)/graph.Po + -rm -f ./$(DEPDIR)/hash.Po + -rm -f ./$(DEPDIR)/ifconfig.Po + -rm -f ./$(DEPDIR)/info.Po + -rm -f ./$(DEPDIR)/invitation.Po + -rm -f ./$(DEPDIR)/list.Po + -rm -f ./$(DEPDIR)/logger.Po + -rm -f ./$(DEPDIR)/meta.Po + -rm -f ./$(DEPDIR)/multicast_device.Po + -rm -f ./$(DEPDIR)/names.Po + -rm -f ./$(DEPDIR)/net.Po + -rm -f ./$(DEPDIR)/net_packet.Po + -rm -f ./$(DEPDIR)/net_setup.Po + -rm -f ./$(DEPDIR)/net_socket.Po + -rm -f ./$(DEPDIR)/netutl.Po + -rm -f ./$(DEPDIR)/node.Po + -rm -f ./$(DEPDIR)/process.Po + -rm -f ./$(DEPDIR)/protocol.Po + -rm -f ./$(DEPDIR)/protocol_auth.Po + -rm -f ./$(DEPDIR)/protocol_edge.Po + -rm -f ./$(DEPDIR)/protocol_key.Po + -rm -f ./$(DEPDIR)/protocol_misc.Po + -rm -f ./$(DEPDIR)/protocol_subnet.Po + -rm -f ./$(DEPDIR)/raw_socket_device.Po + -rm -f ./$(DEPDIR)/route.Po + -rm -f ./$(DEPDIR)/script.Po + -rm -f ./$(DEPDIR)/splay_tree.Po + -rm -f ./$(DEPDIR)/sptps.Po + -rm -f ./$(DEPDIR)/sptps_keypair.Po + -rm -f ./$(DEPDIR)/sptps_speed.Po + -rm -f ./$(DEPDIR)/sptps_test.Po + -rm -f ./$(DEPDIR)/subnet.Po + -rm -f ./$(DEPDIR)/subnet_parse.Po + -rm -f ./$(DEPDIR)/tincctl.Po + -rm -f ./$(DEPDIR)/tincd.Po + -rm -f ./$(DEPDIR)/top.Po + -rm -f ./$(DEPDIR)/uml_device.Po + -rm -f ./$(DEPDIR)/upnp.Po + -rm -f ./$(DEPDIR)/utils.Po + -rm -f ./$(DEPDIR)/vde_device.Po + -rm -f ./$(DEPDIR)/version.Po + -rm -f bsd/$(DEPDIR)/device.Po + -rm -f bsd/$(DEPDIR)/tunemu.Po + -rm -f chacha-poly1305/$(DEPDIR)/chacha-poly1305.Po + -rm -f chacha-poly1305/$(DEPDIR)/chacha.Po + -rm -f chacha-poly1305/$(DEPDIR)/poly1305.Po + -rm -f cygwin/$(DEPDIR)/device.Po + -rm -f ed25519/$(DEPDIR)/ecdh.Po + -rm -f ed25519/$(DEPDIR)/ecdsa.Po + -rm -f ed25519/$(DEPDIR)/ecdsagen.Po + -rm -f ed25519/$(DEPDIR)/fe.Po + -rm -f ed25519/$(DEPDIR)/ge.Po + -rm -f ed25519/$(DEPDIR)/key_exchange.Po + -rm -f ed25519/$(DEPDIR)/keypair.Po + -rm -f ed25519/$(DEPDIR)/sc.Po + -rm -f ed25519/$(DEPDIR)/sha512.Po + -rm -f ed25519/$(DEPDIR)/sign.Po + -rm -f ed25519/$(DEPDIR)/verify.Po + -rm -f gcrypt/$(DEPDIR)/cipher.Po + -rm -f gcrypt/$(DEPDIR)/crypto.Po + -rm -f gcrypt/$(DEPDIR)/digest.Po + -rm -f gcrypt/$(DEPDIR)/prf.Po + -rm -f gcrypt/$(DEPDIR)/rsa.Po + -rm -f gcrypt/$(DEPDIR)/rsagen.Po + -rm -f linux/$(DEPDIR)/device.Po + -rm -f mingw/$(DEPDIR)/device.Po + -rm -f nolegacy/$(DEPDIR)/crypto.Po + -rm -f nolegacy/$(DEPDIR)/prf.Po + -rm -f openssl/$(DEPDIR)/cipher.Po + -rm -f openssl/$(DEPDIR)/crypto.Po + -rm -f openssl/$(DEPDIR)/digest.Po + -rm -f openssl/$(DEPDIR)/prf.Po + -rm -f openssl/$(DEPDIR)/rsa.Po + -rm -f openssl/$(DEPDIR)/rsagen.Po + -rm -f solaris/$(DEPDIR)/device.Po -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic @@ -1211,7 +1457,7 @@ uninstall-am: uninstall-sbinPROGRAMS .MAKE: check-am install-am install-strip -.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean \ +.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-checkPROGRAMS clean-generic clean-sbinPROGRAMS \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-tags distdir dvi dvi-am html \ diff --git a/src/address_cache.c b/src/address_cache.c new file mode 100644 index 0000000..445cd1c --- /dev/null +++ b/src/address_cache.c @@ -0,0 +1,277 @@ +/* + address_cache.c -- Manage cache of recently seen addresses + Copyright (C) 2018 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "system.h" + +#include "address_cache.h" +#include "conf.h" +#include "names.h" +#include "netutl.h" +#include "xalloc.h" + +static const unsigned int NOT_CACHED = -1; + +// Find edges pointing to this node, and use them to build a list of unique, known addresses. +static struct addrinfo *get_known_addresses(node_t *n) { + struct addrinfo *ai = NULL; + struct addrinfo *oai = NULL; + + for splay_each(edge_t, e, n->edge_tree) { + if(!e->reverse) { + continue; + } + + bool found = false; + + for(struct addrinfo *aip = ai; aip; aip = aip->ai_next) { + if(!sockaddrcmp(&e->reverse->address, (sockaddr_t *)aip->ai_addr)) { + found = true; + break; + } + } + + if(found) { + continue; + } + + oai = ai; + ai = xzalloc(sizeof(*ai)); + ai->ai_family = e->reverse->address.sa.sa_family; + ai->ai_socktype = SOCK_STREAM; + ai->ai_protocol = IPPROTO_TCP; + ai->ai_addrlen = SALEN(e->reverse->address.sa); + ai->ai_addr = xmalloc(ai->ai_addrlen); + memcpy(ai->ai_addr, &e->reverse->address, ai->ai_addrlen); + ai->ai_next = oai; + } + + return ai; +} + +static void free_known_addresses(struct addrinfo *ai) { + for(struct addrinfo *aip = ai, *next; aip; aip = next) { + next = aip->ai_next; + free(aip); + } +} + +static unsigned int find_cached(address_cache_t *cache, const sockaddr_t *sa) { + for(unsigned int i = 0; i < cache->data.used; i++) + if(!sockaddrcmp(&cache->data.address[i], sa)) { + return i; + } + + return NOT_CACHED; +} + +void add_recent_address(address_cache_t *cache, const sockaddr_t *sa) { + // Check if it's already cached + unsigned int pos = find_cached(cache, sa); + + // It's in the first spot, so nothing to do + if(pos == 0) { + return; + } + + // Shift everything, move/add the address to the first slot + if(pos == NOT_CACHED) { + if(cache->data.used < MAX_CACHED_ADDRESSES) { + cache->data.used++; + } + + pos = cache->data.used - 1; + } + + memmove(&cache->data.address[1], &cache->data.address[0], pos * sizeof(cache->data.address[0])); + + cache->data.address[0] = *sa; + + // Write the cache + char fname[PATH_MAX]; + snprintf(fname, sizeof(fname), "%s" SLASH "cache" SLASH "%s", confbase, cache->node->name); + FILE *fp = fopen(fname, "wb"); + + if(fp) { + fwrite(&cache->data, sizeof(cache->data), 1, fp); + fclose(fp); + } +} + +const sockaddr_t *get_recent_address(address_cache_t *cache) { + // Check if there is an address in our cache of recently seen addresses + if(cache->tried < cache->data.used) { + return &cache->data.address[cache->tried++]; + } + + // Next, check any recently seen addresses not in our cache + while(cache->tried == cache->data.used) { + if(!cache->ai) { + cache->aip = cache->ai = get_known_addresses(cache->node); + } + + if(cache->ai) { + if(cache->aip) { + sockaddr_t *sa = (sockaddr_t *)cache->aip->ai_addr; + cache->aip = cache->aip->ai_next; + + if(find_cached(cache, sa) != NOT_CACHED) { + continue; + } + + return sa; + } else { + free_known_addresses(cache->ai); + cache->ai = NULL; + } + } + + cache->tried++; + } + + // Otherwise, check if there are any known Address statements + if(!cache->config_tree) { + init_configuration(&cache->config_tree); + read_host_config(cache->config_tree, cache->node->name, false); + cache->cfg = lookup_config(cache->config_tree, "Address"); + } + + while(cache->cfg && !cache->ai) { + char *address, *port; + + get_config_string(cache->cfg, &address); + + char *space = strchr(address, ' '); + + if(space) { + port = xstrdup(space + 1); + *space = 0; + } else { + if(!get_config_string(lookup_config(cache->config_tree, "Port"), &port)) { + port = xstrdup("655"); + } + } + + cache->aip = cache->ai = str2addrinfo(address, port, SOCK_STREAM); + + if(cache->ai) { + struct addrinfo *ai = NULL; + + for(; cache->aip; cache->aip = cache->aip->ai_next) { + struct addrinfo *oai = ai; + + ai = xzalloc(sizeof(*ai)); + ai->ai_family = cache->aip->ai_family; + ai->ai_socktype = cache->aip->ai_socktype; + ai->ai_protocol = cache->aip->ai_protocol; + ai->ai_addrlen = cache->aip->ai_addrlen; + ai->ai_addr = xmalloc(ai->ai_addrlen); + memcpy(ai->ai_addr, cache->aip->ai_addr, ai->ai_addrlen); + ai->ai_next = oai; + } + + freeaddrinfo(cache->ai); + cache->aip = cache->ai = ai; + } + + free(address); + free(port); + + cache->cfg = lookup_config_next(cache->config_tree, cache->cfg); + } + + if(cache->ai) { + if(cache->aip) { + sockaddr_t *sa = (sockaddr_t *)cache->aip->ai_addr; + + cache->aip = cache->aip->ai_next; + return sa; + } else { + free_known_addresses(cache->ai); + cache->ai = NULL; + } + } + + // We're all out of addresses. + exit_configuration(&cache->config_tree); + return false; +} + +address_cache_t *open_address_cache(node_t *node) { + address_cache_t *cache = xmalloc(sizeof(*cache)); + cache->node = node; + + // Try to open an existing address cache + char fname[PATH_MAX]; + snprintf(fname, sizeof(fname), "%s" SLASH "cache" SLASH "%s", confbase, node->name); + FILE *fp = fopen(fname, "rb"); + + if(!fp || fread(&cache->data, sizeof(cache->data), 1, fp) != 1 || cache->data.version != ADDRESS_CACHE_VERSION) { + memset(&cache->data, 0, sizeof(cache->data)); + } + + if(fp) { + fclose(fp); + } + + // Ensure we have a valid state + cache->config_tree = NULL; + cache->cfg = NULL; + cache->ai = NULL; + cache->aip = NULL; + cache->tried = 0; + cache->data.version = ADDRESS_CACHE_VERSION; + + if(cache->data.used > MAX_CACHED_ADDRESSES) { + cache->data.used = 0; + } + + return cache; +} + +void reset_address_cache(address_cache_t *cache, const sockaddr_t *sa) { + if(sa) { + add_recent_address(cache, sa); + } + + if(cache->config_tree) { + exit_configuration(&cache->config_tree); + } + + if(cache->ai) { + free_known_addresses(cache->ai); + } + + cache->config_tree = NULL; + cache->cfg = NULL; + cache->ai = NULL; + cache->aip = NULL; + cache->tried = 0; +} + +void close_address_cache(address_cache_t *cache) { + if(cache->config_tree) { + exit_configuration(&cache->config_tree); + } + + if(cache->ai) { + free_known_addresses(cache->ai); + } + + free(cache); +} diff --git a/src/address_cache.h b/src/address_cache.h new file mode 100644 index 0000000..4ce6ec5 --- /dev/null +++ b/src/address_cache.h @@ -0,0 +1,50 @@ +#ifndef TINC_ADDRESS_CACHE_H +#define TINC_ADDRESS_CACHE_H + +/* + address_cache.h -- header for address_cache.c + Copyright (C) 2018 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "net.h" + +#define MAX_CACHED_ADDRESSES 8 +#define ADDRESS_CACHE_VERSION 1 + +typedef struct address_cache_t { + struct node_t *node; + struct splay_tree_t *config_tree; + struct config_t *cfg; + struct addrinfo *ai; + struct addrinfo *aip; + unsigned int tried; + + struct { + unsigned int version; + unsigned int used; + sockaddr_t address[MAX_CACHED_ADDRESSES]; + } data; +} address_cache_t; + +void add_recent_address(address_cache_t *cache, const sockaddr_t *sa); +const sockaddr_t *get_recent_address(address_cache_t *cache); + +address_cache_t *open_address_cache(struct node_t *node); +void reset_address_cache(address_cache_t *cache, const sockaddr_t *sa); +void close_address_cache(address_cache_t *cache); + +#endif diff --git a/src/autoconnect.c b/src/autoconnect.c index 1ea51b5..0fa6f4e 100644 --- a/src/autoconnect.c +++ b/src/autoconnect.c @@ -27,28 +27,34 @@ static void make_new_connection() { /* Select a random node we haven't connected to yet. */ int count = 0; + for splay_each(node_t, n, node_tree) { - if(n == myself || n->connection || !(n->status.has_address || n->status.reachable)) + if(n == myself || n->connection || !(n->status.has_address || n->status.reachable)) { continue; + } + count++; } - if(!count) + if(!count) { return; + } int r = rand() % count; for splay_each(node_t, n, node_tree) { - if(n == myself || n->connection || !(n->status.has_address || n->status.reachable)) + if(n == myself || n->connection || !(n->status.has_address || n->status.reachable)) { continue; + } - if(r--) + if(r--) { continue; + } bool found = false; for list_each(outgoing_t, outgoing, outgoing_list) { - if(!strcmp(outgoing->name, n->name)) { + if(outgoing->node == n) { found = true; break; } @@ -56,10 +62,10 @@ static void make_new_connection() { if(!found) { logger(DEBUG_CONNECTIONS, LOG_INFO, "Autoconnecting to %s", n->name); - outgoing_t *outgoing = xzalloc(sizeof *outgoing); - outgoing->name = xstrdup(n->name); + outgoing_t *outgoing = xzalloc(sizeof(*outgoing)); + outgoing->node = n; list_insert_tail(outgoing_list, outgoing); - setup_outgoing_connection(outgoing); + setup_outgoing_connection(outgoing, false); } break; @@ -77,23 +83,27 @@ static void connect_to_unreachable() { int r = rand() % node_tree->count; for splay_each(node_t, n, node_tree) { - if(r--) + if(r--) { continue; + } /* Is it unreachable and do we know an address for it? If not, return. */ - if(n == myself || n->connection || n->status.reachable || !n->status.has_address) + if(n == myself || n->connection || n->status.reachable || !n->status.has_address) { return; + } - /* Are we already trying to make an outgoing connection to it? If not, return. */ - for list_each(outgoing_t, outgoing, outgoing_list) - if(!strcmp(outgoing->name, n->name)) + /* Are we already trying to make an outgoing connection to it? If so, return. */ + for list_each(outgoing_t, outgoing, outgoing_list) { + if(outgoing->node == n) { return; + } + } logger(DEBUG_CONNECTIONS, LOG_INFO, "Autoconnecting to %s", n->name); - outgoing_t *outgoing = xzalloc(sizeof *outgoing); - outgoing->name = xstrdup(n->name); + outgoing_t *outgoing = xzalloc(sizeof(*outgoing)); + outgoing->node = n; list_insert_tail(outgoing_list, outgoing); - setup_outgoing_connection(outgoing); + setup_outgoing_connection(outgoing, false); return; } @@ -102,23 +112,29 @@ static void connect_to_unreachable() { static void drop_superfluous_outgoing_connection() { /* Choose a random outgoing connection to a node that has at least one other connection. */ int count = 0; + for list_each(connection_t, c, connection_list) { - if(!c->edge || !c->outgoing || !c->node || c->node->edge_tree->count < 2) + if(!c->edge || !c->outgoing || !c->node || c->node->edge_tree->count < 2) { continue; + } + count++; } - if(!count) + if(!count) { return; + } int r = rand() % count; for list_each(connection_t, c, connection_list) { - if(!c->edge || !c->outgoing || !c->node || c->node->edge_tree->count < 2) + if(!c->edge || !c->outgoing || !c->node || c->node->edge_tree->count < 2) { continue; - - if(r--) + } + + if(r--) { continue; + } logger(DEBUG_CONNECTIONS, LOG_INFO, "Autodisconnecting from %s", c->name); list_delete(outgoing_list, c->outgoing); @@ -132,6 +148,7 @@ static void drop_superfluous_pending_connections() { for list_each(outgoing_t, o, outgoing_list) { /* Only look for connections that are waiting to be retried later. */ bool found = false; + for list_each(connection_t, c, connection_list) { if(c->outgoing == o) { found = true; @@ -139,10 +156,11 @@ static void drop_superfluous_pending_connections() { } } - if(found) + if(found) { continue; + } - logger(DEBUG_CONNECTIONS, LOG_INFO, "Cancelled outgoing connection to %s", o->name); + logger(DEBUG_CONNECTIONS, LOG_INFO, "Cancelled outgoing connection to %s", o->node->name); list_delete_node(outgoing_list, node); } } @@ -150,9 +168,11 @@ static void drop_superfluous_pending_connections() { void do_autoconnect() { /* Count number of active connections. */ int nc = 0; + for list_each(connection_t, c, connection_list) { - if(c->edge) + if(c->edge) { nc++; + } } /* Less than 3 connections? Eagerly try to make a new one. */ @@ -160,10 +180,11 @@ void do_autoconnect() { make_new_connection(); return; } - + /* More than 3 connections? See if we can get rid of a superfluous one. */ - if(nc > 3) + if(nc > 3) { drop_superfluous_outgoing_connection(); + } /* Check if there are unreachable nodes that we should try to connect to. */ diff --git a/src/autoconnect.h b/src/autoconnect.h index dc3ee1c..82a5043 100644 --- a/src/autoconnect.h +++ b/src/autoconnect.h @@ -1,3 +1,6 @@ +#ifndef TINC_AUTOCONNECT_H +#define TINC_AUTOCONNECT_H + /* autoconnect.h -- header for autoconnect.c Copyright (C) 2017 Guus Sliepen @@ -17,9 +20,6 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#ifndef __TINC_AUTOCONNECT_H__ -#define __TINC_AUTOCONNECT_H__ - extern void do_autoconnect(void); #endif diff --git a/src/bsd/device.c b/src/bsd/device.c index 4a63e84..0eeee6e 100644 --- a/src/bsd/device.c +++ b/src/bsd/device.c @@ -56,7 +56,7 @@ typedef enum device_type { int device_fd = -1; char *device = NULL; char *iface = NULL; -static char *device_info = NULL; +static const char *device_info = "OS X utun device"; #if defined(ENABLE_TUNEMU) static device_type_t device_type = DEVICE_TYPE_TUNEMU; #elif defined(HAVE_OPENBSD) || defined(HAVE_FREEBSD) || defined(HAVE_DRAGONFLY) @@ -68,13 +68,15 @@ static device_type_t device_type = DEVICE_TYPE_TUN; #ifdef HAVE_NET_IF_UTUN_H static bool setup_utun(void) { device_fd = socket(PF_SYSTEM, SOCK_DGRAM, SYSPROTO_CONTROL); + if(device_fd == -1) { logger(DEBUG_ALWAYS, LOG_ERR, "Could not open PF_SYSTEM socket: %s\n", strerror(errno)); return false; } struct ctl_info info = {}; - strlcpy(info.ctl_name, UTUN_CONTROL_NAME, sizeof info.ctl_name); + + strlcpy(info.ctl_name, UTUN_CONTROL_NAME, sizeof(info.ctl_name)); if(ioctl(device_fd, CTLIOCGINFO, &info) == -1) { logger(DEBUG_ALWAYS, LOG_ERR, "ioctl(CTLIOCGINFO) failed: %s", strerror(errno)); @@ -83,15 +85,18 @@ static bool setup_utun(void) { int unit = -1; char *p = strstr(device, "utun"), *e = NULL; + if(p) { unit = strtol(p + 4, &e, 10); - if(!e) + + if(!e) { unit = -1; + } } struct sockaddr_ctl sc = { .sc_id = info.ctl_id, - .sc_len = sizeof sc, + .sc_len = sizeof(sc), .sc_family = AF_SYSTEM, .ss_sysaddr = AF_SYS_CONTROL, .sc_unit = unit + 1, @@ -103,15 +108,14 @@ static bool setup_utun(void) { } char name[64] = ""; - socklen_t len = sizeof name; + socklen_t len = sizeof(name); + if(getsockopt(device_fd, SYSPROTO_CONTROL, UTUN_OPT_IFNAME, name, &len)) { iface = xstrdup(device); } else { iface = xstrdup(name); } - device_info = "OS X utun device"; - logger(DEBUG_ALWAYS, LOG_INFO, "%s is a %s", device, device_info); return true; @@ -124,35 +128,43 @@ static bool setup_device(void) { // Find out if it's supposed to be a tun or a tap device char *type; + if(get_config_string(lookup_config(config_tree, "DeviceType"), &type)) { if(!strcasecmp(type, "tun")) /* use default */; + #ifdef ENABLE_TUNEMU - else if(!strcasecmp(type, "tunemu")) + else if(!strcasecmp(type, "tunemu")) { device_type = DEVICE_TYPE_TUNEMU; + } + #endif #ifdef HAVE_NET_IF_UTUN_H - else if(!strcasecmp(type, "utun")) + else if(!strcasecmp(type, "utun")) { device_type = DEVICE_TYPE_UTUN; + } + #endif - else if(!strcasecmp(type, "tunnohead")) + else if(!strcasecmp(type, "tunnohead")) { device_type = DEVICE_TYPE_TUN; - else if(!strcasecmp(type, "tunifhead")) + } else if(!strcasecmp(type, "tunifhead")) { device_type = DEVICE_TYPE_TUNIFHEAD; - else if(!strcasecmp(type, "tap")) + } else if(!strcasecmp(type, "tap")) { device_type = DEVICE_TYPE_TAP; - else { + } else { logger(DEBUG_ALWAYS, LOG_ERR, "Unknown device type %s!", type); return false; } } else { #ifdef HAVE_NET_IF_UTUN_H - if(device && (strncmp(device, "utun", 4) == 0 || strncmp(device, "/dev/utun", 9) == 0)) + + if(device && (strncmp(device, "utun", 4) == 0 || strncmp(device, "/dev/utun", 9) == 0)) { device_type = DEVICE_TYPE_UTUN; - else + } else #endif - if((device && strstr(device, "tap")) || routing_mode != RMODE_ROUTER) - device_type = DEVICE_TYPE_TAP; + if((device && strstr(device, "tap")) || routing_mode != RMODE_ROUTER) { + device_type = DEVICE_TYPE_TAP; + } } if(routing_mode == RMODE_SWITCH && device_type != DEVICE_TYPE_TAP) { @@ -163,28 +175,32 @@ static bool setup_device(void) { // Find out which device file to open if(!device) { - if(device_type == DEVICE_TYPE_TAP) + if(device_type == DEVICE_TYPE_TAP) { device = xstrdup(DEFAULT_TAP_DEVICE); - else + } else { device = xstrdup(DEFAULT_TUN_DEVICE); + } } // Open the device switch(device_type) { #ifdef ENABLE_TUNEMU - case DEVICE_TYPE_TUNEMU: { - char dynamic_name[256] = ""; - device_fd = tunemu_open(dynamic_name); - } - break; + + case DEVICE_TYPE_TUNEMU: { + char dynamic_name[256] = ""; + device_fd = tunemu_open(dynamic_name); + } + break; #endif #ifdef HAVE_NET_IF_UTUN_H - case DEVICE_TYPE_UTUN: - return setup_utun(); + + case DEVICE_TYPE_UTUN: + return setup_utun(); #endif - default: - device_fd = open(device, O_RDWR | O_NONBLOCK); + + default: + device_fd = open(device, O_RDWR | O_NONBLOCK); } if(device_fd < 0) { @@ -204,87 +220,105 @@ static bool setup_device(void) { realname = fdevname(device_fd); #elif defined(HAVE_DEVNAME) struct stat buf; - if(!fstat(device_fd, &buf)) + + if(!fstat(device_fd, &buf)) { realname = devname(buf.st_rdev, S_IFCHR); + } + #endif - if(!realname) + if(!realname) { realname = device; + } - if(!get_config_string(lookup_config(config_tree, "Interface"), &iface)) + if(!get_config_string(lookup_config(config_tree, "Interface"), &iface)) { iface = xstrdup(strrchr(realname, '/') ? strrchr(realname, '/') + 1 : realname); - else if(strcmp(iface, strrchr(realname, '/') ? strrchr(realname, '/') + 1 : realname)) + } else if(strcmp(iface, strrchr(realname, '/') ? strrchr(realname, '/') + 1 : realname)) { logger(DEBUG_ALWAYS, LOG_WARNING, "Warning: Interface does not match Device. $INTERFACE might be set incorrectly."); + } // Configure the device as best as we can switch(device_type) { - default: - device_type = DEVICE_TYPE_TUN; - case DEVICE_TYPE_TUN: + default: + device_type = DEVICE_TYPE_TUN; + + case DEVICE_TYPE_TUN: #ifdef TUNSIFHEAD { const int zero = 0; - if(ioctl(device_fd, TUNSIFHEAD, &zero, sizeof zero) == -1) { + + if(ioctl(device_fd, TUNSIFHEAD, &zero, sizeof(zero)) == -1) { logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "ioctl", strerror(errno)); return false; } } + #endif #if defined(TUNSIFMODE) && defined(IFF_BROADCAST) && defined(IFF_MULTICAST) { const int mode = IFF_BROADCAST | IFF_MULTICAST; - ioctl(device_fd, TUNSIFMODE, &mode, sizeof mode); + ioctl(device_fd, TUNSIFMODE, &mode, sizeof(mode)); } #endif - device_info = "Generic BSD tun device"; - break; - case DEVICE_TYPE_TUNIFHEAD: + device_info = "Generic BSD tun device"; + break; + + case DEVICE_TYPE_TUNIFHEAD: #ifdef TUNSIFHEAD { const int one = 1; - if(ioctl(device_fd, TUNSIFHEAD, &one, sizeof one) == -1) { + + if(ioctl(device_fd, TUNSIFHEAD, &one, sizeof(one)) == -1) { logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "ioctl", strerror(errno)); return false; } } + #endif #if defined(TUNSIFMODE) && defined(IFF_BROADCAST) && defined(IFF_MULTICAST) { - const int mode = IFF_BROADCAST | IFF_MULTICAST; - ioctl(device_fd, TUNSIFMODE, &mode, sizeof mode); + const int mode = IFF_BROADCAST | IFF_MULTICAST; + ioctl(device_fd, TUNSIFMODE, &mode, sizeof(mode)); } #endif - device_info = "Generic BSD tun device"; - break; - case DEVICE_TYPE_TAP: - if(routing_mode == RMODE_ROUTER) - overwrite_mac = true; - device_info = "Generic BSD tap device"; + device_info = "Generic BSD tun device"; + break; + + case DEVICE_TYPE_TAP: + if(routing_mode == RMODE_ROUTER) { + overwrite_mac = true; + } + + device_info = "Generic BSD tap device"; #ifdef TAPGIFNAME - { - struct ifreq ifr; - if(ioctl(device_fd, TAPGIFNAME, (void*)&ifr) == 0) { - if(iface) - free(iface); - iface = xstrdup(ifr.ifr_name); - } + { + struct ifreq ifr; + + if(ioctl(device_fd, TAPGIFNAME, (void *)&ifr) == 0) { + free(iface); + iface = xstrdup(ifr.ifr_name); } + } #endif - break; + break; #ifdef ENABLE_TUNEMU - case DEVICE_TYPE_TUNEMU: - device_info = "BSD tunemu device"; - break; + + case DEVICE_TYPE_TUNEMU: + device_info = "BSD tunemu device"; + break; #endif } #ifdef SIOCGIFADDR - if(overwrite_mac) + + if(overwrite_mac) { ioctl(device_fd, SIOCGIFADDR, mymac.x); + } + #endif logger(DEBUG_ALWAYS, LOG_INFO, "%s is a %s", device, device_info); @@ -295,17 +329,22 @@ static bool setup_device(void) { static void close_device(void) { switch(device_type) { #ifdef ENABLE_TUNEMU - case DEVICE_TYPE_TUNEMU: - tunemu_close(device_fd); - break; + + case DEVICE_TYPE_TUNEMU: + tunemu_close(device_fd); + break; #endif - default: - close(device_fd); + + default: + close(device_fd); } + device_fd = -1; - free(device); device = NULL; - free(iface); iface = NULL; + free(device); + device = NULL; + free(iface); + iface = NULL; device_info = NULL; } @@ -313,154 +352,163 @@ static bool read_packet(vpn_packet_t *packet) { int inlen; switch(device_type) { - case DEVICE_TYPE_TUN: + case DEVICE_TYPE_TUN: #ifdef ENABLE_TUNEMU - case DEVICE_TYPE_TUNEMU: - if(device_type == DEVICE_TYPE_TUNEMU) - inlen = tunemu_read(device_fd, DATA(packet) + 14, MTU - 14); - else + case DEVICE_TYPE_TUNEMU: + if(device_type == DEVICE_TYPE_TUNEMU) { + inlen = tunemu_read(device_fd, DATA(packet) + 14, MTU - 14); + } else #endif - inlen = read(device_fd, DATA(packet) + 14, MTU - 14); + inlen = read(device_fd, DATA(packet) + 14, MTU - 14); - if(inlen <= 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info, - device, strerror(errno)); - return false; - } - - switch(DATA(packet)[14] >> 4) { - case 4: - DATA(packet)[12] = 0x08; - DATA(packet)[13] = 0x00; - break; - case 6: - DATA(packet)[12] = 0x86; - DATA(packet)[13] = 0xDD; - break; - default: - logger(DEBUG_TRAFFIC, LOG_ERR, - "Unknown IP version %d while reading packet from %s %s", - DATA(packet)[14] >> 4, device_info, device); - return false; - } - - memset(DATA(packet), 0, 12); - packet->len = inlen + 14; - break; - - case DEVICE_TYPE_UTUN: - case DEVICE_TYPE_TUNIFHEAD: { - if((inlen = read(device_fd, DATA(packet) + 10, MTU - 10)) <= 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info, - device, strerror(errno)); - return false; - } - - switch (DATA(packet)[14] >> 4) { - case 4: - DATA(packet)[12] = 0x08; - DATA(packet)[13] = 0x00; - break; - - case 6: - DATA(packet)[12] = 0x86; - DATA(packet)[13] = 0xDD; - break; - - default: - logger(DEBUG_TRAFFIC, LOG_ERR, - "Unknown IP version %d while reading packet from %s %s", - DATA(packet)[14] >> 4, device_info, device); - return false; - } - - memset(DATA(packet), 0, 12); - packet->len = inlen + 10; - break; + if(inlen <= 0) { + logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info, + device, strerror(errno)); + return false; } - case DEVICE_TYPE_TAP: - if((inlen = read(device_fd, DATA(packet), MTU)) <= 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info, - device, strerror(errno)); - return false; - } + switch(DATA(packet)[14] >> 4) { + case 4: + DATA(packet)[12] = 0x08; + DATA(packet)[13] = 0x00; + break; - packet->len = inlen; + case 6: + DATA(packet)[12] = 0x86; + DATA(packet)[13] = 0xDD; break; default: + logger(DEBUG_TRAFFIC, LOG_ERR, + "Unknown IP version %d while reading packet from %s %s", + DATA(packet)[14] >> 4, device_info, device); return false; + } + + memset(DATA(packet), 0, 12); + packet->len = inlen + 14; + break; + + case DEVICE_TYPE_UTUN: + case DEVICE_TYPE_TUNIFHEAD: { + if((inlen = read(device_fd, DATA(packet) + 10, MTU - 10)) <= 0) { + logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info, + device, strerror(errno)); + return false; + } + + switch(DATA(packet)[14] >> 4) { + case 4: + DATA(packet)[12] = 0x08; + DATA(packet)[13] = 0x00; + break; + + case 6: + DATA(packet)[12] = 0x86; + DATA(packet)[13] = 0xDD; + break; + + default: + logger(DEBUG_TRAFFIC, LOG_ERR, + "Unknown IP version %d while reading packet from %s %s", + DATA(packet)[14] >> 4, device_info, device); + return false; + } + + memset(DATA(packet), 0, 12); + packet->len = inlen + 10; + break; + } + + case DEVICE_TYPE_TAP: + if((inlen = read(device_fd, DATA(packet), MTU)) <= 0) { + logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info, + device, strerror(errno)); + return false; + } + + packet->len = inlen; + break; + + default: + return false; } logger(DEBUG_TRAFFIC, LOG_DEBUG, "Read packet of %d bytes from %s", - packet->len, device_info); + packet->len, device_info); return true; } static bool write_packet(vpn_packet_t *packet) { logger(DEBUG_TRAFFIC, LOG_DEBUG, "Writing packet of %d bytes to %s", - packet->len, device_info); + packet->len, device_info); switch(device_type) { - case DEVICE_TYPE_TUN: - if(write(device_fd, DATA(packet) + 14, packet->len - 14) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error while writing to %s %s: %s", device_info, - device, strerror(errno)); - return false; - } - break; - - case DEVICE_TYPE_UTUN: - case DEVICE_TYPE_TUNIFHEAD: { - int af = (DATA(packet)[12] << 8) + DATA(packet)[13]; - uint32_t type; - - switch (af) { - case 0x0800: - type = htonl(AF_INET); - break; - case 0x86DD: - type = htonl(AF_INET6); - break; - default: - logger(DEBUG_TRAFFIC, LOG_ERR, - "Unknown address family %x while writing packet to %s %s", - af, device_info, device); - return false; - } - - memcpy(DATA(packet) + 10, &type, sizeof type); - - if(write(device_fd, DATA(packet) + 10, packet->len - 10) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Can't write to %s %s: %s", device_info, device, - strerror(errno)); - return false; - } - break; + case DEVICE_TYPE_TUN: + if(write(device_fd, DATA(packet) + 14, packet->len - 14) < 0) { + logger(DEBUG_ALWAYS, LOG_ERR, "Error while writing to %s %s: %s", device_info, + device, strerror(errno)); + return false; } - case DEVICE_TYPE_TAP: - if(write(device_fd, DATA(packet), packet->len) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error while writing to %s %s: %s", device_info, - device, strerror(errno)); - return false; - } + break; + + case DEVICE_TYPE_UTUN: + case DEVICE_TYPE_TUNIFHEAD: { + int af = (DATA(packet)[12] << 8) + DATA(packet)[13]; + uint32_t type; + + switch(af) { + case 0x0800: + type = htonl(AF_INET); break; -#ifdef ENABLE_TUNEMU - case DEVICE_TYPE_TUNEMU: - if(tunemu_write(device_fd, DATA(packet) + 14, packet->len - 14) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error while writing to %s %s: %s", device_info, - device, strerror(errno)); - return false; - } + case 0x86DD: + type = htonl(AF_INET6); break; -#endif default: + logger(DEBUG_TRAFFIC, LOG_ERR, + "Unknown address family %x while writing packet to %s %s", + af, device_info, device); return false; + } + + memcpy(DATA(packet) + 10, &type, sizeof(type)); + + if(write(device_fd, DATA(packet) + 10, packet->len - 10) < 0) { + logger(DEBUG_ALWAYS, LOG_ERR, "Can't write to %s %s: %s", device_info, device, + strerror(errno)); + return false; + } + + break; + } + + case DEVICE_TYPE_TAP: + if(write(device_fd, DATA(packet), packet->len) < 0) { + logger(DEBUG_ALWAYS, LOG_ERR, "Error while writing to %s %s: %s", device_info, + device, strerror(errno)); + return false; + } + + break; + +#ifdef ENABLE_TUNEMU + + case DEVICE_TYPE_TUNEMU: + if(tunemu_write(device_fd, DATA(packet) + 14, packet->len - 14) < 0) { + logger(DEBUG_ALWAYS, LOG_ERR, "Error while writing to %s %s: %s", device_info, + device, strerror(errno)); + return false; + } + + break; +#endif + + default: + return false; } return true; diff --git a/src/bsd/tunemu.c b/src/bsd/tunemu.c index d2b9f3d..2248264 100644 --- a/src/bsd/tunemu.c +++ b/src/bsd/tunemu.c @@ -49,24 +49,21 @@ #define PPPIOCCONNECT _IOW('t', 58, int) #define PPPIOCGUNIT _IOR('t', 86, int) -struct sockaddr_ppp -{ +struct sockaddr_ppp { u_int8_t ppp_len; u_int8_t ppp_family; u_int16_t ppp_proto; u_int32_t ppp_cookie; }; -enum NPmode -{ +enum NPmode { NPMODE_PASS, - NPMODE_DROP, - NPMODE_ERROR, - NPMODE_QUEUE + NPMODE_DROP, + NPMODE_ERROR, + NPMODE_QUEUE }; -struct npioctl -{ +struct npioctl { int protocol; enum NPmode mode; }; @@ -83,58 +80,55 @@ static pcap_t *pcap = NULL; static int data_buffer_length = 0; static char *data_buffer = NULL; -static void tun_error(char *format, ...) -{ +static void tun_error(char *format, ...) { va_list vl; va_start(vl, format); - vsnprintf(tunemu_error, sizeof tunemu_error, format, vl); + vsnprintf(tunemu_error, sizeof(tunemu_error), format, vl); va_end(vl); } -static void tun_noerror() -{ +static void tun_noerror() { *tunemu_error = 0; } -static void closeall() -{ - int fd = getdtablesize(); - while (fd--) - close(fd); +static void closeall() { + int fd = getdtablesize(); - open("/dev/null", O_RDWR, 0); - dup(0); - dup(0); + while(fd--) { + close(fd); + } + + open("/dev/null", O_RDWR, 0); + dup(0); + dup(0); } -static int ppp_load_kext() -{ +static int ppp_load_kext() { int pid = fork(); - if (pid < 0) - { + + if(pid < 0) { tun_error("fork for ppp kext: %s", strerror(errno)); return -1; } - if (pid == 0) - { + if(pid == 0) { closeall(); execle("/sbin/kextload", "kextload", PPP_KEXT_PATH, NULL, NULL); exit(1); } int status; - while (waitpid(pid, &status, 0) < 0) - { - if (errno == EINTR) + + while(waitpid(pid, &status, 0) < 0) { + if(errno == EINTR) { continue; + } tun_error("waitpid for ppp kext: %s", strerror(errno)); return -1; } - if (WEXITSTATUS(status) != 0) - { + if(WEXITSTATUS(status) != 0) { tun_error("could not load ppp kext \"%s\"", PPP_KEXT_PATH); return -1; } @@ -143,74 +137,73 @@ static int ppp_load_kext() return 0; } -static int ppp_new_instance() -{ +static int ppp_new_instance() { // create ppp socket - int ppp_sockfd = socket(PF_PPP, SOCK_RAW, PPPPROTO_CTL); - if (ppp_sockfd < 0) - { - if (ppp_load_kext() < 0) + int ppp_sockfd = socket(PF_PPP, SOCK_RAW, PPPPROTO_CTL); + + if(ppp_sockfd < 0) { + if(ppp_load_kext() < 0) { return -1; + } ppp_sockfd = socket(PF_PPP, SOCK_RAW, PPPPROTO_CTL); - if (ppp_sockfd < 0) - { + + if(ppp_sockfd < 0) { tun_error("creating ppp socket: %s", strerror(errno)); return -1; } } // connect to ppp procotol - struct sockaddr_ppp pppaddr; - pppaddr.ppp_len = sizeof(struct sockaddr_ppp); - pppaddr.ppp_family = AF_PPP; - pppaddr.ppp_proto = PPPPROTO_CTL; - pppaddr.ppp_cookie = 0; - if (connect(ppp_sockfd, (struct sockaddr *)&pppaddr, sizeof(struct sockaddr_ppp)) < 0) - { + struct sockaddr_ppp pppaddr; + pppaddr.ppp_len = sizeof(struct sockaddr_ppp); + pppaddr.ppp_family = AF_PPP; + pppaddr.ppp_proto = PPPPROTO_CTL; + pppaddr.ppp_cookie = 0; + + if(connect(ppp_sockfd, (struct sockaddr *)&pppaddr, sizeof(struct sockaddr_ppp)) < 0) { tun_error("connecting ppp socket: %s", strerror(errno)); close(ppp_sockfd); return -1; - } + } tun_noerror(); return ppp_sockfd; } -static int ppp_new_unit(int *unit_number) -{ +static int ppp_new_unit(int *unit_number) { int fd = ppp_new_instance(); - if (fd < 0) + + if(fd < 0) { return -1; + } // create ppp unit - if (ioctl(fd, PPPIOCNEWUNIT, unit_number) < 0) - { + if(ioctl(fd, PPPIOCNEWUNIT, unit_number) < 0) { tun_error("creating ppp unit: %s", strerror(errno)); close(fd); return -1; - } + } tun_noerror(); return fd; } -static int ppp_setup_unit(int unit_fd) -{ +static int ppp_setup_unit(int unit_fd) { // send traffic to program int flags = SC_LOOP_TRAFFIC; - if (ioctl(unit_fd, PPPIOCSFLAGS, &flags) < 0) - { + + if(ioctl(unit_fd, PPPIOCSFLAGS, &flags) < 0) { tun_error("setting ppp loopback mode: %s", strerror(errno)); return -1; - } + } // allow packets struct npioctl npi; npi.protocol = PPP_IP; npi.mode = NPMODE_PASS; - if (ioctl(unit_fd, PPPIOCSNPMODE, &npi) < 0) - { + + if(ioctl(unit_fd, PPPIOCSNPMODE, &npi) < 0) { tun_error("starting ppp unit: %s", strerror(errno)); return -1; } @@ -219,10 +212,8 @@ static int ppp_setup_unit(int unit_fd) return 0; } -static int open_pcap() -{ - if (pcap != NULL) - { +static int open_pcap() { + if(pcap != NULL) { pcap_use_count++; return 0; } @@ -231,8 +222,7 @@ static int open_pcap() pcap = pcap_open_live("lo0", BUFSIZ, 0, 1, errbuf); pcap_use_count = 1; - if (pcap == NULL) - { + if(pcap == NULL) { tun_error("opening pcap: %s", errbuf); return -1; } @@ -241,59 +231,57 @@ static int open_pcap() return 0; } -static void close_pcap() -{ - if (pcap == NULL) +static void close_pcap() { + if(pcap == NULL) { return; + } pcap_use_count--; - if (pcap_use_count == 0) - { + + if(pcap_use_count == 0) { pcap_close(pcap); pcap = NULL; } } -static void allocate_data_buffer(int size) -{ - if (data_buffer_length < size) - { +static void allocate_data_buffer(int size) { + if(data_buffer_length < size) { free(data_buffer); data_buffer_length = size; data_buffer = malloc(data_buffer_length); } } -static void make_device_name(tunemu_device device, int unit_number) -{ +static void make_device_name(tunemu_device device, int unit_number) { snprintf(device, sizeof(tunemu_device), "ppp%d", unit_number); } -static int check_device_name(tunemu_device device) -{ - if (strlen(device) < 4) +static int check_device_name(tunemu_device device) { + if(strlen(device) < 4) { return -1; + } int unit_number = atoi(device + 3); - if (unit_number < 0 || unit_number > 999) + + if(unit_number < 0 || unit_number > 999) { return -1; + } tunemu_device compare; make_device_name(compare, unit_number); - if (strcmp(device, compare) != 0) + if(strcmp(device, compare) != 0) { return -1; + } return 0; } -int tunemu_open(tunemu_device device) -{ +int tunemu_open(tunemu_device device) { int ppp_unit_number = -1; - if (device[0] != 0) - { - if (check_device_name(device) < 0) - { + + if(device[0] != 0) { + if(check_device_name(device) < 0) { tun_error("invalid device name \"%s\"", device); return -1; } @@ -302,17 +290,17 @@ int tunemu_open(tunemu_device device) } int ppp_unit_fd = ppp_new_unit(&ppp_unit_number); - if (ppp_unit_fd < 0) - return -1; - if (ppp_setup_unit(ppp_unit_fd) < 0) - { + if(ppp_unit_fd < 0) { + return -1; + } + + if(ppp_setup_unit(ppp_unit_fd) < 0) { close(ppp_unit_fd); return -1; } - if (open_pcap() < 0) - { + if(open_pcap() < 0) { close(ppp_unit_fd); return -1; } @@ -322,39 +310,40 @@ int tunemu_open(tunemu_device device) return ppp_unit_fd; } -int tunemu_close(int ppp_sockfd) -{ +int tunemu_close(int ppp_sockfd) { int ret = close(ppp_sockfd); - if (ret == 0) + if(ret == 0) { close_pcap(); + } return ret; } -int tunemu_read(int ppp_sockfd, char *buffer, int length) -{ +int tunemu_read(int ppp_sockfd, char *buffer, int length) { allocate_data_buffer(length + 2); length = read(ppp_sockfd, data_buffer, length + 2); - if (length < 0) - { + + if(length < 0) { tun_error("reading packet: %s", strerror(errno)); return length; } + tun_noerror(); length -= 2; - if (length < 0) + + if(length < 0) { return 0; + } memcpy(buffer, data_buffer + 2, length); return length; } -int tunemu_write(int ppp_sockfd, char *buffer, int length) -{ +int tunemu_write(int ppp_sockfd, char *buffer, int length) { allocate_data_buffer(length + 4); data_buffer[0] = 0x02; @@ -364,23 +353,25 @@ int tunemu_write(int ppp_sockfd, char *buffer, int length) memcpy(data_buffer + 4, buffer, length); - if (pcap == NULL) - { + if(pcap == NULL) { tun_error("pcap not open"); return -1; } length = pcap_inject(pcap, data_buffer, length + 4); - if (length < 0) - { + + if(length < 0) { tun_error("injecting packet: %s", pcap_geterr(pcap)); return length; } + tun_noerror(); length -= 4; - if (length < 0) + + if(length < 0) { return 0; + } return length; } diff --git a/src/buffer.c b/src/buffer.c index ac57d1c..60adec8 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -22,7 +22,7 @@ #include "buffer.h" #include "xalloc.h" -void buffer_compact(buffer_t *buffer, int maxsize) { +void buffer_compact(buffer_t *buffer, uint32_t maxsize) { if(buffer->len >= maxsize || buffer->offset / 7 > buffer->len / 8) { memmove(buffer->data, buffer->data + buffer->offset, buffer->len - buffer->offset); buffer->len -= buffer->offset; @@ -32,7 +32,7 @@ void buffer_compact(buffer_t *buffer, int maxsize) { // Make sure we can add size bytes to the buffer, and return a pointer to the start of those bytes. -char *buffer_prepare(buffer_t *buffer, int size) { +char *buffer_prepare(buffer_t *buffer, uint32_t size) { if(!buffer->data) { buffer->maxlen = size; buffer->data = xmalloc(size); @@ -58,13 +58,13 @@ char *buffer_prepare(buffer_t *buffer, int size) { // Copy data into the buffer. -void buffer_add(buffer_t *buffer, const char *data, int size) { +void buffer_add(buffer_t *buffer, const char *data, uint32_t size) { memcpy(buffer_prepare(buffer, size), data, size); } // Remove given number of bytes from the buffer, return a pointer to the start of them. -static char *buffer_consume(buffer_t *buffer, int size) { +static char *buffer_consume(buffer_t *buffer, uint32_t size) { char *start = buffer->data + buffer->offset; buffer->offset += size; @@ -82,19 +82,21 @@ static char *buffer_consume(buffer_t *buffer, int size) { char *buffer_readline(buffer_t *buffer) { char *newline = memchr(buffer->data + buffer->offset, '\n', buffer->len - buffer->offset); - if(!newline) + if(!newline) { return NULL; + } - int len = newline + 1 - (buffer->data + buffer->offset); + uint32_t len = newline + 1 - (buffer->data + buffer->offset); *newline = 0; return buffer_consume(buffer, len); } // Check if we have enough bytes in the buffer, and if so, return a pointer to the start of them. -char *buffer_read(buffer_t *buffer, int size) { - if(buffer->len - buffer->offset < size) +char *buffer_read(buffer_t *buffer, uint32_t size) { + if(buffer->len - buffer->offset < size) { return NULL; + } return buffer_consume(buffer, size); } diff --git a/src/buffer.h b/src/buffer.h index a96c15a..b25c8ad 100644 --- a/src/buffer.h +++ b/src/buffer.h @@ -1,18 +1,18 @@ -#ifndef __TINC_BUFFER_H__ -#define __TINC_BUFFER_H__ +#ifndef TINC_BUFFER_H +#define TINC_BUFFER_H typedef struct buffer_t { char *data; - int maxlen; - int len; - int offset; + uint32_t maxlen; + uint32_t len; + uint32_t offset; } buffer_t; -extern void buffer_compact(buffer_t *buffer, int maxsize); -extern char *buffer_prepare(buffer_t *buffer, int size); -extern void buffer_add(buffer_t *buffer, const char *data, int size); +extern void buffer_compact(buffer_t *buffer, uint32_t maxsize); +extern char *buffer_prepare(buffer_t *buffer, uint32_t size); +extern void buffer_add(buffer_t *buffer, const char *data, uint32_t size); extern char *buffer_readline(buffer_t *buffer); -extern char *buffer_read(buffer_t *buffer, int size); +extern char *buffer_read(buffer_t *buffer, uint32_t size); extern void buffer_clear(buffer_t *buffer); #endif diff --git a/src/chacha-poly1305/chacha-poly1305.c b/src/chacha-poly1305/chacha-poly1305.c index bd5cb2c..a74c502 100644 --- a/src/chacha-poly1305/chacha-poly1305.c +++ b/src/chacha-poly1305/chacha-poly1305.c @@ -11,42 +11,40 @@ struct chacha_poly1305_ctx { struct chacha_ctx main_ctx, header_ctx; }; -chacha_poly1305_ctx_t *chacha_poly1305_init(void) -{ - chacha_poly1305_ctx_t *ctx = xzalloc(sizeof *ctx); +chacha_poly1305_ctx_t *chacha_poly1305_init(void) { + chacha_poly1305_ctx_t *ctx = xzalloc(sizeof(*ctx)); return ctx; } -void chacha_poly1305_exit(chacha_poly1305_ctx_t *ctx) -{ +void chacha_poly1305_exit(chacha_poly1305_ctx_t *ctx) { free(ctx); } -bool chacha_poly1305_set_key(chacha_poly1305_ctx_t *ctx, const void *key) -{ +bool chacha_poly1305_set_key(chacha_poly1305_ctx_t *ctx, const void *vkey) { + const uint8_t *key = vkey; chacha_keysetup(&ctx->main_ctx, key, 256); chacha_keysetup(&ctx->header_ctx, key + 32, 256); return true; } -static void put_u64(void *vp, uint64_t v) -{ +static void put_u64(void *vp, uint64_t v) { uint8_t *p = (uint8_t *) vp; - p[0] = (uint8_t) (v >> 56) & 0xff; - p[1] = (uint8_t) (v >> 48) & 0xff; - p[2] = (uint8_t) (v >> 40) & 0xff; - p[3] = (uint8_t) (v >> 32) & 0xff; - p[4] = (uint8_t) (v >> 24) & 0xff; - p[5] = (uint8_t) (v >> 16) & 0xff; - p[6] = (uint8_t) (v >> 8) & 0xff; + p[0] = (uint8_t)(v >> 56) & 0xff; + p[1] = (uint8_t)(v >> 48) & 0xff; + p[2] = (uint8_t)(v >> 40) & 0xff; + p[3] = (uint8_t)(v >> 32) & 0xff; + p[4] = (uint8_t)(v >> 24) & 0xff; + p[5] = (uint8_t)(v >> 16) & 0xff; + p[6] = (uint8_t)(v >> 8) & 0xff; p[7] = (uint8_t) v & 0xff; } -bool chacha_poly1305_encrypt(chacha_poly1305_ctx_t *ctx, uint64_t seqnr, const void *indata, size_t inlen, void *outdata, size_t *outlen) { +bool chacha_poly1305_encrypt(chacha_poly1305_ctx_t *ctx, uint64_t seqnr, const void *indata, size_t inlen, void *voutdata, size_t *outlen) { uint8_t seqbuf[8]; - const uint8_t one[8] = { 1, 0, 0, 0, 0, 0, 0, 0 }; /* NB little-endian */ + const uint8_t one[8] = { 1, 0, 0, 0, 0, 0, 0, 0 }; /* NB little-endian */ uint8_t poly_key[POLY1305_KEYLEN]; + uint8_t *outdata = voutdata; /* * Run ChaCha20 once to generate the Poly1305 key. The IV is the @@ -63,16 +61,18 @@ bool chacha_poly1305_encrypt(chacha_poly1305_ctx_t *ctx, uint64_t seqnr, const v chacha_encrypt_bytes(&ctx->main_ctx, indata, outdata, inlen); poly1305_auth(outdata + inlen, outdata, inlen, poly_key); - if (outlen) + if(outlen) { *outlen = inlen + POLY1305_TAGLEN; + } return true; } -bool chacha_poly1305_decrypt(chacha_poly1305_ctx_t *ctx, uint64_t seqnr, const void *indata, size_t inlen, void *outdata, size_t *outlen) { +bool chacha_poly1305_decrypt(chacha_poly1305_ctx_t *ctx, uint64_t seqnr, const void *vindata, size_t inlen, void *outdata, size_t *outlen) { uint8_t seqbuf[8]; - const uint8_t one[8] = { 1, 0, 0, 0, 0, 0, 0, 0 }; /* NB little-endian */ + const uint8_t one[8] = { 1, 0, 0, 0, 0, 0, 0, 0 }; /* NB little-endian */ uint8_t expected_tag[POLY1305_TAGLEN], poly_key[POLY1305_KEYLEN]; + const uint8_t *indata = vindata; /* * Run ChaCha20 once to generate the Poly1305 key. The IV is the @@ -91,13 +91,16 @@ bool chacha_poly1305_decrypt(chacha_poly1305_ctx_t *ctx, uint64_t seqnr, const v const uint8_t *tag = indata + inlen; poly1305_auth(expected_tag, indata, inlen, poly_key); - if (memcmp(expected_tag, tag, POLY1305_TAGLEN)) + + if(memcmp(expected_tag, tag, POLY1305_TAGLEN)) { return false; + } chacha_encrypt_bytes(&ctx->main_ctx, indata, outdata, inlen); - if (outlen) + if(outlen) { *outlen = inlen; + } return true; } diff --git a/src/chacha-poly1305/chacha.c b/src/chacha-poly1305/chacha.c index 2d0b918..696f44a 100644 --- a/src/chacha-poly1305/chacha.c +++ b/src/chacha-poly1305/chacha.c @@ -47,20 +47,21 @@ typedef struct chacha_ctx chacha_ctx; static const char sigma[16] = "expand 32-byte k"; static const char tau[16] = "expand 16-byte k"; -void chacha_keysetup(chacha_ctx *x, const uint8_t *k, uint32_t kbits) -{ +void chacha_keysetup(chacha_ctx *x, const uint8_t *k, uint32_t kbits) { const char *constants; x->input[4] = U8TO32_LITTLE(k + 0); x->input[5] = U8TO32_LITTLE(k + 4); x->input[6] = U8TO32_LITTLE(k + 8); x->input[7] = U8TO32_LITTLE(k + 12); - if (kbits == 256) { /* recommended */ + + if(kbits == 256) { /* recommended */ k += 16; constants = sigma; - } else { /* kbits == 128 */ + } else { /* kbits == 128 */ constants = tau; } + x->input[8] = U8TO32_LITTLE(k + 0); x->input[9] = U8TO32_LITTLE(k + 4); x->input[10] = U8TO32_LITTLE(k + 8); @@ -71,8 +72,7 @@ void chacha_keysetup(chacha_ctx *x, const uint8_t *k, uint32_t kbits) x->input[3] = U8TO32_LITTLE(constants + 12); } -void chacha_ivsetup(chacha_ctx *x, const uint8_t *iv, const uint8_t *counter) -{ +void chacha_ivsetup(chacha_ctx *x, const uint8_t *iv, const uint8_t *counter) { x->input[12] = counter == NULL ? 0 : U8TO32_LITTLE(counter + 0); x->input[13] = counter == NULL ? 0 : U8TO32_LITTLE(counter + 4); x->input[14] = U8TO32_LITTLE(iv + 0); @@ -80,16 +80,16 @@ void chacha_ivsetup(chacha_ctx *x, const uint8_t *iv, const uint8_t *counter) } void -chacha_encrypt_bytes(chacha_ctx *x, const uint8_t *m, uint8_t *c, uint32_t bytes) -{ +chacha_encrypt_bytes(chacha_ctx *x, const uint8_t *m, uint8_t *c, uint32_t bytes) { uint32_t x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15; uint32_t j0, j1, j2, j3, j4, j5, j6, j7, j8, j9, j10, j11, j12, j13, j14, j15; uint8_t *ctarget = NULL; uint8_t tmp[64]; uint32_t i; - if (!bytes) + if(!bytes) { return; + } j0 = x->input[0]; j1 = x->input[1]; @@ -108,14 +108,17 @@ chacha_encrypt_bytes(chacha_ctx *x, const uint8_t *m, uint8_t *c, uint32_t bytes j14 = x->input[14]; j15 = x->input[15]; - for (;;) { - if (bytes < 64) { - for (i = 0; i < bytes; ++i) + for(;;) { + if(bytes < 64) { + for(i = 0; i < bytes; ++i) { tmp[i] = m[i]; + } + m = tmp; ctarget = c; c = tmp; } + x0 = j0; x1 = j1; x2 = j2; @@ -132,7 +135,8 @@ chacha_encrypt_bytes(chacha_ctx *x, const uint8_t *m, uint8_t *c, uint32_t bytes x13 = j13; x14 = j14; x15 = j15; - for (i = 20; i > 0; i -= 2) { + + for(i = 20; i > 0; i -= 2) { QUARTERROUND(x0, x4, x8, x12) QUARTERROUND(x1, x5, x9, x13) QUARTERROUND(x2, x6, x10, x14) @@ -142,6 +146,7 @@ chacha_encrypt_bytes(chacha_ctx *x, const uint8_t *m, uint8_t *c, uint32_t bytes QUARTERROUND(x2, x7, x8, x13) QUARTERROUND(x3, x4, x9, x14) } + x0 = PLUS(x0, j0); x1 = PLUS(x1, j1); x2 = PLUS(x2, j2); @@ -177,7 +182,8 @@ chacha_encrypt_bytes(chacha_ctx *x, const uint8_t *m, uint8_t *c, uint32_t bytes x15 = XOR(x15, U8TO32_LITTLE(m + 60)); j12 = PLUSONE(j12); - if (!j12) { + + if(!j12) { j13 = PLUSONE(j13); /* stopping at 2^70 bytes per nonce is user's responsibility */ } @@ -199,15 +205,18 @@ chacha_encrypt_bytes(chacha_ctx *x, const uint8_t *m, uint8_t *c, uint32_t bytes U32TO8_LITTLE(c + 56, x14); U32TO8_LITTLE(c + 60, x15); - if (bytes <= 64) { - if (bytes < 64) { - for (i = 0; i < bytes; ++i) + if(bytes <= 64) { + if(bytes < 64) { + for(i = 0; i < bytes; ++i) { ctarget[i] = c[i]; + } } + x->input[12] = j12; x->input[13] = j13; return; } + bytes -= 64; c += 64; m += 64; diff --git a/src/chacha-poly1305/chacha.h b/src/chacha-poly1305/chacha.h index af1b9a4..103c3d8 100644 --- a/src/chacha-poly1305/chacha.h +++ b/src/chacha-poly1305/chacha.h @@ -11,14 +11,14 @@ struct chacha_ctx { uint32_t input[16]; }; -#define CHACHA_MINKEYLEN 16 -#define CHACHA_NONCELEN 8 -#define CHACHA_CTRLEN 8 -#define CHACHA_STATELEN (CHACHA_NONCELEN+CHACHA_CTRLEN) -#define CHACHA_BLOCKLEN 64 +#define CHACHA_MINKEYLEN 16 +#define CHACHA_NONCELEN 8 +#define CHACHA_CTRLEN 8 +#define CHACHA_STATELEN (CHACHA_NONCELEN+CHACHA_CTRLEN) +#define CHACHA_BLOCKLEN 64 void chacha_keysetup(struct chacha_ctx *x, const uint8_t *k, uint32_t kbits); void chacha_ivsetup(struct chacha_ctx *x, const uint8_t *iv, const uint8_t *ctr); -void chacha_encrypt_bytes(struct chacha_ctx *x, const uint8_t *m, uint8_t * c, uint32_t bytes); +void chacha_encrypt_bytes(struct chacha_ctx *x, const uint8_t *m, uint8_t *c, uint32_t bytes); #endif /* CHACHA_H */ diff --git a/src/chacha-poly1305/poly1305.c b/src/chacha-poly1305/poly1305.c index f1ddf2d..4d99b8c 100644 --- a/src/chacha-poly1305/poly1305.c +++ b/src/chacha-poly1305/poly1305.c @@ -1,4 +1,4 @@ -/* +/* * Public Domain poly1305 from Andrew Moon * poly1305-donna-unrolled.c from https://github.com/floodyberry/poly1305-donna */ @@ -24,8 +24,7 @@ } while (0) void -poly1305_auth(unsigned char out[POLY1305_TAGLEN], const unsigned char *m, size_t inlen, const unsigned char key[POLY1305_KEYLEN]) -{ +poly1305_auth(unsigned char out[POLY1305_TAGLEN], const unsigned char *m, size_t inlen, const unsigned char key[POLY1305_KEYLEN]) { uint32_t t0, t1, t2, t3; uint32_t h0, h1, h2, h3, h4; uint32_t r0, r1, r2, r3, r4; @@ -71,10 +70,11 @@ poly1305_auth(unsigned char out[POLY1305_TAGLEN], const unsigned char *m, size_t h4 = 0; /* full blocks */ - if (inlen < 16) + if(inlen < 16) { goto poly1305_donna_atmost15bytes; + } - poly1305_donna_16bytes: +poly1305_donna_16bytes: m += 16; inlen -= 16; @@ -89,7 +89,7 @@ poly1305_auth(unsigned char out[POLY1305_TAGLEN], const unsigned char *m, size_t h3 += ((((uint64_t) t3 << 32) | t2) >> 14) & 0x3ffffff; h4 += (t3 >> 8) | (1 << 24); - poly1305_donna_mul: +poly1305_donna_mul: t[0] = mul32x32_64(h0, r0) + mul32x32_64(h1, s4) + mul32x32_64(h2, s3) + mul32x32_64(h3, s2) + mul32x32_64(h4, s1); t[1] = mul32x32_64(h0, r1) + mul32x32_64(h1, r0) + mul32x32_64(h2, s4) + mul32x32_64(h3, s3) + mul32x32_64(h4, s2); t[2] = mul32x32_64(h0, r2) + mul32x32_64(h1, r1) + mul32x32_64(h2, r0) + mul32x32_64(h3, s4) + mul32x32_64(h4, s3); @@ -100,31 +100,39 @@ poly1305_auth(unsigned char out[POLY1305_TAGLEN], const unsigned char *m, size_t c = (t[0] >> 26); t[1] += c; h1 = (uint32_t) t[1] & 0x3ffffff; - b = (uint32_t) (t[1] >> 26); + b = (uint32_t)(t[1] >> 26); t[2] += b; h2 = (uint32_t) t[2] & 0x3ffffff; - b = (uint32_t) (t[2] >> 26); + b = (uint32_t)(t[2] >> 26); t[3] += b; h3 = (uint32_t) t[3] & 0x3ffffff; - b = (uint32_t) (t[3] >> 26); + b = (uint32_t)(t[3] >> 26); t[4] += b; h4 = (uint32_t) t[4] & 0x3ffffff; - b = (uint32_t) (t[4] >> 26); + b = (uint32_t)(t[4] >> 26); h0 += b * 5; - if (inlen >= 16) + if(inlen >= 16) { goto poly1305_donna_16bytes; + } /* final bytes */ - poly1305_donna_atmost15bytes: - if (!inlen) - goto poly1305_donna_finish; +poly1305_donna_atmost15bytes: - for (j = 0; j < inlen; j++) + if(!inlen) { + goto poly1305_donna_finish; + } + + for(j = 0; j < inlen; j++) { mp[j] = m[j]; + } + mp[j++] = 1; - for (; j < 16; j++) + + for(; j < 16; j++) { mp[j] = 0; + } + inlen = 0; t0 = U8TO32_LE(mp + 0); @@ -140,7 +148,7 @@ poly1305_auth(unsigned char out[POLY1305_TAGLEN], const unsigned char *m, size_t goto poly1305_donna_mul; - poly1305_donna_finish: +poly1305_donna_finish: b = h0 >> 26; h0 = h0 & 0x3ffffff; h1 += b; diff --git a/src/chacha-poly1305/poly1305.h b/src/chacha-poly1305/poly1305.h index 9a64015..4ece415 100644 --- a/src/chacha-poly1305/poly1305.h +++ b/src/chacha-poly1305/poly1305.h @@ -1,6 +1,6 @@ /* $OpenBSD: poly1305.h,v 1.2 2013/12/19 22:57:13 djm Exp $ */ -/* +/* * Public Domain poly1305 from Andrew Moon * poly1305-donna-unrolled.c from https://github.com/floodyberry/poly1305-donna */ @@ -8,9 +8,9 @@ #ifndef POLY1305_H #define POLY1305_H -#define POLY1305_KEYLEN 32 -#define POLY1305_TAGLEN 16 +#define POLY1305_KEYLEN 32 +#define POLY1305_TAGLEN 16 void poly1305_auth(uint8_t out[POLY1305_TAGLEN], const uint8_t *m, size_t inlen, const uint8_t key[POLY1305_KEYLEN]); -#endif /* POLY1305_H */ +#endif /* POLY1305_H */ diff --git a/src/cipher.h b/src/cipher.h index 44db40f..2845be8 100644 --- a/src/cipher.h +++ b/src/cipher.h @@ -1,3 +1,6 @@ +#ifndef TINC_CIPHER_H +#define TINC_CIPHER_H + /* cipher.h -- header file cipher.c Copyright (C) 2007-2016 Guus Sliepen @@ -17,9 +20,6 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#ifndef __TINC_CIPHER_H__ -#define __TINC_CIPHER_H__ - #define CIPHER_MAX_BLOCK_SIZE 32 #define CIPHER_MAX_IV_SIZE 16 #define CIPHER_MAX_KEY_SIZE 32 @@ -28,19 +28,18 @@ typedef struct cipher cipher_t; -extern cipher_t *cipher_open_by_name(const char *) __attribute__ ((__malloc__)); -extern cipher_t *cipher_open_by_nid(int) __attribute__ ((__malloc__)); -extern void cipher_close(cipher_t *); -extern size_t cipher_keylength(const cipher_t *); -extern size_t cipher_blocksize(const cipher_t *); -extern uint64_t cipher_budget(const cipher_t *); -extern void cipher_get_key(const cipher_t *, void *); -extern bool cipher_set_key(cipher_t *, void *, bool) __attribute__ ((__warn_unused_result__)); -extern bool cipher_set_key_from_rsa(cipher_t *, void *, size_t, bool) __attribute__ ((__warn_unused_result__)); -extern bool cipher_encrypt(cipher_t *, const void *indata, size_t inlen, void *outdata, size_t *outlen, bool oneshot) __attribute__ ((__warn_unused_result__)); -extern bool cipher_decrypt(cipher_t *, const void *indata, size_t inlen, void *outdata, size_t *outlen, bool oneshot) __attribute__ ((__warn_unused_result__)); -extern int cipher_get_nid(const cipher_t *); -extern bool cipher_active(const cipher_t *); +extern cipher_t *cipher_open_by_name(const char *name) __attribute__((__malloc__)); +extern cipher_t *cipher_open_by_nid(int nid) __attribute__((__malloc__)); +extern void cipher_close(cipher_t *cipher); +extern size_t cipher_keylength(const cipher_t *cipher); +extern size_t cipher_blocksize(const cipher_t *cipher); +extern uint64_t cipher_budget(const cipher_t *cipher); +extern bool cipher_set_key(cipher_t *cipher, void *key, bool encrypt) __attribute__((__warn_unused_result__)); +extern bool cipher_set_key_from_rsa(cipher_t *cipher, void *rsa, size_t len, bool encrypt) __attribute__((__warn_unused_result__)); +extern bool cipher_encrypt(cipher_t *cipher, const void *indata, size_t inlen, void *outdata, size_t *outlen, bool oneshot) __attribute__((__warn_unused_result__)); +extern bool cipher_decrypt(cipher_t *cipher, const void *indata, size_t inlen, void *outdata, size_t *outlen, bool oneshot) __attribute__((__warn_unused_result__)); +extern int cipher_get_nid(const cipher_t *cipher); +extern bool cipher_active(const cipher_t *cipher); #endif diff --git a/src/conf.c b/src/conf.c index 7756247..a33bdfe 100644 --- a/src/conf.c +++ b/src/conf.c @@ -46,27 +46,31 @@ static int config_compare(const config_t *a, const config_t *b) { result = strcasecmp(a->variable, b->variable); - if(result) + if(result) { return result; + } /* give priority to command line options */ result = !b->file - !a->file; - if (result) + + if(result) { return result; + } result = a->line - b->line; - if(result) + if(result) { return result; - else + } else { return a->file ? strcmp(a->file, b->file) : 0; + } } -void init_configuration(splay_tree_t ** config_tree) { +void init_configuration(splay_tree_t **config_tree) { *config_tree = splay_alloc_tree((splay_compare_t) config_compare, (splay_action_t) free_config); } -void exit_configuration(splay_tree_t ** config_tree) { +void exit_configuration(splay_tree_t **config_tree) { splay_delete_tree(*config_tree); *config_tree = NULL; } @@ -76,15 +80,9 @@ config_t *new_config(void) { } void free_config(config_t *cfg) { - if(cfg->variable) - free(cfg->variable); - - if(cfg->value) - free(cfg->value); - - if(cfg->file) - free(cfg->file); - + free(cfg->variable); + free(cfg->value); + free(cfg->file); free(cfg); } @@ -101,11 +99,13 @@ config_t *lookup_config(splay_tree_t *config_tree, char *variable) { found = splay_search_closest_greater(config_tree, &cfg); - if(!found) + if(!found) { return NULL; + } - if(strcasecmp(found->variable, variable)) + if(strcasecmp(found->variable, variable)) { return NULL; + } return found; } @@ -120,8 +120,9 @@ config_t *lookup_config_next(splay_tree_t *config_tree, const config_t *cfg) { if(node->next) { found = node->next->data; - if(!strcasecmp(found->variable, cfg->variable)) + if(!strcasecmp(found->variable, cfg->variable)) { return found; + } } } @@ -129,8 +130,9 @@ config_t *lookup_config_next(splay_tree_t *config_tree, const config_t *cfg) { } bool get_config_bool(const config_t *cfg, bool *result) { - if(!cfg) + if(!cfg) { return false; + } if(!strcasecmp(cfg->value, "yes")) { *result = true; @@ -141,27 +143,30 @@ bool get_config_bool(const config_t *cfg, bool *result) { } logger(DEBUG_ALWAYS, LOG_ERR, "\"yes\" or \"no\" expected for configuration variable %s in %s line %d", - cfg->variable, cfg->file, cfg->line); + cfg->variable, cfg->file, cfg->line); return false; } bool get_config_int(const config_t *cfg, int *result) { - if(!cfg) + if(!cfg) { return false; + } - if(sscanf(cfg->value, "%d", result) == 1) + if(sscanf(cfg->value, "%d", result) == 1) { return true; + } logger(DEBUG_ALWAYS, LOG_ERR, "Integer expected for configuration variable %s in %s line %d", - cfg->variable, cfg->file, cfg->line); + cfg->variable, cfg->file, cfg->line); return false; } bool get_config_string(const config_t *cfg, char **result) { - if(!cfg) + if(!cfg) { return false; + } *result = xstrdup(cfg->value); @@ -171,8 +176,9 @@ bool get_config_string(const config_t *cfg, char **result) { bool get_config_address(const config_t *cfg, struct addrinfo **result) { struct addrinfo *ai; - if(!cfg) + if(!cfg) { return false; + } ai = str2addrinfo(cfg->value, NULL, 0); @@ -182,31 +188,32 @@ bool get_config_address(const config_t *cfg, struct addrinfo **result) { } logger(DEBUG_ALWAYS, LOG_ERR, "Hostname or IP address expected for configuration variable %s in %s line %d", - cfg->variable, cfg->file, cfg->line); + cfg->variable, cfg->file, cfg->line); return false; } -bool get_config_subnet(const config_t *cfg, subnet_t ** result) { - subnet_t subnet = {NULL}; +bool get_config_subnet(const config_t *cfg, subnet_t **result) { + subnet_t subnet = {0}; - if(!cfg) + if(!cfg) { return false; + } if(!str2net(&subnet, cfg->value)) { logger(DEBUG_ALWAYS, LOG_ERR, "Subnet expected for configuration variable %s in %s line %d", - cfg->variable, cfg->file, cfg->line); + cfg->variable, cfg->file, cfg->line); return false; } /* Teach newbies what subnets are... */ if(((subnet.type == SUBNET_IPV4) - && !maskcheck(&subnet.net.ipv4.address, subnet.net.ipv4.prefixlength, sizeof subnet.net.ipv4.address)) - || ((subnet.type == SUBNET_IPV6) - && !maskcheck(&subnet.net.ipv6.address, subnet.net.ipv6.prefixlength, sizeof subnet.net.ipv6.address))) { + && !maskcheck(&subnet.net.ipv4.address, subnet.net.ipv4.prefixlength, sizeof(subnet.net.ipv4.address))) + || ((subnet.type == SUBNET_IPV6) + && !maskcheck(&subnet.net.ipv6.address, subnet.net.ipv6.prefixlength, sizeof(subnet.net.ipv6.address)))) { logger(DEBUG_ALWAYS, LOG_ERR, "Network address and prefix length do not match for configuration variable %s in %s line %d", - cfg->variable, cfg->file, cfg->line); + cfg->variable, cfg->file, cfg->line); return false; } @@ -218,27 +225,32 @@ bool get_config_subnet(const config_t *cfg, subnet_t ** result) { /* 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; - if(feof(fp)) + if(feof(fp)) { return NULL; + } p = fgets(buf, buflen, fp); - if(!p) + if(!p) { return NULL; + } newline = strchr(p, '\n'); - if(!newline) + if(!newline) { return buf; + } /* kill newline and carriage return if necessary */ *newline = '\0'; - if(newline > p && newline[-1] == '\r') + + if(newline > p && newline[-1] == '\r') { newline[-1] = '\0'; + } return buf; } @@ -250,26 +262,32 @@ config_t *parse_config_line(char *line, const char *fname, int lineno) { variable = value = line; eol = line + strlen(line); - while(strchr("\t ", *--eol)) + + while(strchr("\t ", *--eol)) { *eol = '\0'; + } len = strcspn(value, "\t ="); value += len; value += strspn(value, "\t "); + if(*value == '=') { value++; value += strspn(value, "\t "); } + variable[len] = '\0'; if(!*value) { const char err[] = "No value for variable"; - if (fname) + + if(fname) logger(DEBUG_ALWAYS, LOG_ERR, "%s `%s' on line %d while reading config file %s", - err, variable, lineno, fname); + err, variable, lineno, fname); else logger(DEBUG_ALWAYS, LOG_ERR, "%s `%s' in command line option %d", - err, variable, lineno); + err, variable, lineno); + return NULL; } @@ -286,7 +304,7 @@ config_t *parse_config_line(char *line, const char *fname, int lineno) { Parse a configuration file and put the results in the configuration tree starting at *base. */ -bool read_config_file(splay_tree_t *config_tree, const char *fname) { +bool read_config_file(splay_tree_t *config_tree, const char *fname, bool verbose) { FILE *fp; char buffer[MAX_STRING_SIZE]; char *line; @@ -298,27 +316,32 @@ bool read_config_file(splay_tree_t *config_tree, const char *fname) { fp = fopen(fname, "r"); if(!fp) { - logger(DEBUG_ALWAYS, LOG_DEBUG, "Cannot open config file %s: %s", fname, strerror(errno)); + logger(verbose ? DEBUG_ALWAYS : DEBUG_CONNECTIONS, LOG_ERR, "Cannot open config file %s: %s", fname, strerror(errno)); return false; } for(;;) { - line = readline(fp, buffer, sizeof buffer); + line = readline(fp, buffer, sizeof(buffer)); if(!line) { - if(feof(fp)) + if(feof(fp)) { result = true; + } + break; } lineno++; - if(!*line || *line == '#') + if(!*line || *line == '#') { continue; + } if(ignore) { - if(!strncmp(line, "-----END", 8)) + if(!strncmp(line, "-----END", 8)) { ignore = false; + } + continue; } @@ -328,8 +351,11 @@ bool read_config_file(splay_tree_t *config_tree, const char *fname) { } cfg = parse_config_line(line, fname, lineno); - if (!cfg) + + if(!cfg) { break; + } + config_add(config_tree, cfg); } @@ -346,19 +372,24 @@ void read_config_options(splay_tree_t *config_tree, const char *prefix) { config_t *new; if(!prefix) { - if(strchr(cfg->variable, '.')) + if(strchr(cfg->variable, '.')) { continue; + } } else { if(strncmp(prefix, cfg->variable, prefix_len) || - cfg->variable[prefix_len] != '.') + cfg->variable[prefix_len] != '.') { continue; + } } new = new_config(); - if(prefix) + + if(prefix) { new->variable = xstrdup(cfg->variable + prefix_len + 1); - else + } else { new->variable = xstrdup(cfg->variable); + } + new->value = xstrdup(cfg->value); new->file = NULL; new->line = cfg->line; @@ -373,52 +404,57 @@ bool read_server_config(void) { read_config_options(config_tree, NULL); - snprintf(fname, sizeof fname, "%s" SLASH "tinc.conf", confbase); + snprintf(fname, sizeof(fname), "%s" SLASH "tinc.conf", confbase); errno = 0; - x = read_config_file(config_tree, fname); + x = read_config_file(config_tree, fname, true); // We will try to read the conf files in the "conf.d" dir - if (x) { + if(x) { char dname[PATH_MAX]; - snprintf(dname, sizeof dname, "%s" SLASH "conf.d", confbase); - DIR *dir = opendir (dname); + snprintf(dname, sizeof(dname), "%s" SLASH "conf.d", confbase); + DIR *dir = opendir(dname); + // If we can find this dir - if (dir) { + if(dir) { struct dirent *ep; + // We list all the files in it - while (x && (ep = readdir (dir))) { + while(x && (ep = readdir(dir))) { size_t l = strlen(ep->d_name); + // And we try to read the ones that end with ".conf" - if (l > 5 && !strcmp(".conf", & ep->d_name[ l - 5 ])) { - snprintf(fname, sizeof fname, "%s" SLASH "%s", dname, ep->d_name); - x = read_config_file(config_tree, fname); + if(l > 5 && !strcmp(".conf", & ep->d_name[ l - 5 ])) { + if((size_t)snprintf(fname, sizeof(fname), "%s" SLASH "%s", dname, ep->d_name) >= sizeof(fname)) { + logger(DEBUG_ALWAYS, LOG_ERR, "Pathname too long: %s/%s", dname, ep->d_name); + return false; + } + + x = read_config_file(config_tree, fname, true); } } - closedir (dir); + + closedir(dir); } } - if(!x && errno) + if(!x && errno) { logger(DEBUG_ALWAYS, LOG_ERR, "Failed to read `%s': %s", fname, strerror(errno)); + } return x; } -bool read_host_config(splay_tree_t *config_tree, const char *name) { - char fname[PATH_MAX]; - bool x; - +bool read_host_config(splay_tree_t *config_tree, const char *name, bool verbose) { read_config_options(config_tree, name); - snprintf(fname, sizeof fname, "%s" SLASH "hosts" SLASH "%s", confbase, name); - x = read_config_file(config_tree, fname); - - return x; + char fname[PATH_MAX]; + snprintf(fname, sizeof(fname), "%s" SLASH "hosts" SLASH "%s", confbase, name); + return read_config_file(config_tree, fname, verbose); } bool append_config_file(const char *name, const char *key, const char *value) { char fname[PATH_MAX]; - snprintf(fname, sizeof fname, "%s" SLASH "hosts" SLASH "%s", confbase, name); + snprintf(fname, sizeof(fname), "%s" SLASH "hosts" SLASH "%s", confbase, name); FILE *fp = fopen(fname, "a"); diff --git a/src/conf.h b/src/conf.h index 2478c58..8457124 100644 --- a/src/conf.h +++ b/src/conf.h @@ -1,3 +1,6 @@ +#ifndef TINC_CONF_H +#define TINC_CONF_H + /* conf.h -- header for conf.c Copyright (C) 1998-2005 Ivo Timmermans @@ -18,9 +21,6 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#ifndef __TINC_CONF_H__ -#define __TINC_CONF_H__ - #include "list.h" #include "splay_tree.h" #include "subnet.h" @@ -41,24 +41,24 @@ extern int maxtimeout; extern bool bypass_security; extern list_t *cmdline_conf; -extern void init_configuration(splay_tree_t **); -extern void exit_configuration(splay_tree_t **); -extern config_t *new_config(void) __attribute__ ((__malloc__)); -extern void free_config(config_t *); -extern void config_add(splay_tree_t *, config_t *); -extern config_t *lookup_config(splay_tree_t *, char *); -extern config_t *lookup_config_next(splay_tree_t *, const config_t *); -extern bool get_config_bool(const config_t *, bool *); -extern bool get_config_int(const config_t *, int *); -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 void init_configuration(splay_tree_t **config_tree); +extern void exit_configuration(splay_tree_t **config_tree); +extern config_t *new_config(void) __attribute__((__malloc__)); +extern void free_config(config_t *config); +extern void config_add(splay_tree_t *config_tree, config_t *config); +extern config_t *lookup_config(splay_tree_t *config_tree, char *variable); +extern config_t *lookup_config_next(splay_tree_t *config_tree, const config_t *config); +extern bool get_config_bool(const config_t *config, bool *result); +extern bool get_config_int(const config_t *config, int *result); +extern bool get_config_string(const config_t *config, char **result); +extern bool get_config_address(const config_t *config, struct addrinfo **result); +extern bool get_config_subnet(const config_t *config, struct subnet_t **result); -extern config_t *parse_config_line(char *, const char *, int); -extern bool read_config_file(splay_tree_t *, const char *); -extern void read_config_options(splay_tree_t *, const char *); +extern config_t *parse_config_line(char *line, const char *fname, int lineno); +extern bool read_config_file(splay_tree_t *config_tree, const char *filename, bool verbose); +extern void read_config_options(splay_tree_t *config_tree, const char *prefix); extern bool read_server_config(void); -extern bool read_host_config(splay_tree_t *, const char *); -extern bool append_config_file(const char *, const char *, const char *); +extern bool read_host_config(splay_tree_t *config_tree, const char *name, bool verbose); +extern bool append_config_file(const char *name, const char *key, const char *value); -#endif /* __TINC_CONF_H__ */ +#endif diff --git a/src/connection.c b/src/connection.c index 0e61132..1c638a4 100644 --- a/src/connection.c +++ b/src/connection.c @@ -27,6 +27,7 @@ #include "control_common.h" #include "list.h" #include "logger.h" +#include "net.h" #include "rsa.h" #include "subnet.h" #include "utils.h" @@ -52,8 +53,9 @@ connection_t *new_connection(void) { } void free_connection(connection_t *c) { - if(!c) + if(!c) { return; + } #ifndef DISABLE_LEGACY cipher_close(c->incipher); @@ -67,20 +69,27 @@ void free_connection(connection_t *c) { ecdsa_free(c->ecdsa); free(c->hischallenge); + free(c->mychallenge); buffer_clear(&c->inbuf); buffer_clear(&c->outbuf); io_del(&c->io); - if(c->socket > 0) - closesocket(c->socket); + if(c->socket > 0) { + if(c->status.tarpit) { + tarpit(c->socket); + } else { + closesocket(c->socket); + } + } free(c->name); free(c->hostname); - if(c->config_tree) + if(c->config_tree) { exit_configuration(&c->config_tree); + } free(c); } @@ -96,9 +105,9 @@ void connection_del(connection_t *c) { bool dump_connections(connection_t *cdump) { for list_each(connection_t, c, connection_list) { send_request(cdump, "%d %d %s %s %x %d %x", - CONTROL, REQ_DUMP_CONNECTIONS, - c->name, c->hostname, c->options, c->socket, - bitfield_to_int(&c->status, sizeof c->status)); + CONTROL, REQ_DUMP_CONNECTIONS, + c->name, c->hostname, c->options, c->socket, + bitfield_to_int(&c->status, sizeof(c->status))); } return send_request(cdump, "%d %d", CONTROL, REQ_DUMP_CONNECTIONS); diff --git a/src/connection.h b/src/connection.h index acd77bc..206417b 100644 --- a/src/connection.h +++ b/src/connection.h @@ -1,3 +1,6 @@ +#ifndef TINC_CONNECTION_H +#define TINC_CONNECTION_H + /* connection.h -- header for connection.c Copyright (C) 2000-2013 Guus Sliepen , @@ -18,9 +21,6 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#ifndef __TINC_CONNECTION_H__ -#define __TINC_CONNECTION_H__ - #include "buffer.h" #include "cipher.h" #include "digest.h" @@ -35,21 +35,22 @@ #define OPTION_VERSION(x) ((x) >> 24) /* Top 8 bits are for protocol minor version */ typedef struct connection_status_t { - unsigned int pinged:1; /* sent ping */ - unsigned int unused_active:1; - unsigned int connecting:1; /* 1 if we are waiting for a non-blocking connect() to finish */ - unsigned int unused_termreq:1; /* the termination of this connection was requested */ - unsigned int remove_unused:1; /* Set to 1 if you want this connection removed */ - unsigned int timeout_unused:1; /* 1 if gotten timeout */ - unsigned int encryptout:1; /* 1 if we can encrypt outgoing traffic */ - unsigned int decryptin:1; /* 1 if we have to decrypt incoming traffic */ - unsigned int mst:1; /* 1 if this connection is part of a minimum spanning tree */ - unsigned int control:1; /* 1 if this is a control connection */ - unsigned int pcap:1; /* 1 if this is a control connection requesting packet capture */ - unsigned int log:1; /* 1 if this is a control connection requesting log dump */ - unsigned int invitation:1; /* 1 if this is an invitation */ - unsigned int invitation_used:1; /* 1 if the invitation has been consumed */ - unsigned int unused:18; + unsigned int pinged: 1; /* sent ping */ + unsigned int unused_active: 1; + unsigned int connecting: 1; /* 1 if we are waiting for a non-blocking connect() to finish */ + unsigned int unused_termreq: 1; /* the termination of this connection was requested */ + unsigned int remove_unused: 1; /* Set to 1 if you want this connection removed */ + unsigned int timeout_unused: 1; /* 1 if gotten timeout */ + unsigned int encryptout: 1; /* 1 if we can encrypt outgoing traffic */ + unsigned int decryptin: 1; /* 1 if we have to decrypt incoming traffic */ + unsigned int mst: 1; /* 1 if this connection is part of a minimum spanning tree */ + unsigned int control: 1; /* 1 if this is a control connection */ + unsigned int pcap: 1; /* 1 if this is a control connection requesting packet capture */ + unsigned int log: 1; /* 1 if this is a control connection requesting log dump */ + unsigned int invitation: 1; /* 1 if this is an invitation */ + unsigned int invitation_used: 1; /* 1 if the invitation has been consumed */ + unsigned int tarpit: 1; /* 1 if the connection should be added to the tarpit */ + unsigned int unused: 17; } connection_status_t; #include "ecdsa.h" @@ -94,12 +95,13 @@ typedef struct connection_t { int outcompression; char *hischallenge; /* The challenge we sent to him */ + char *mychallenge; /* The challenge we received */ struct buffer_t inbuf; struct buffer_t outbuf; io_t io; /* input/output event on this metadata connection */ int tcplen; /* length of incoming TCPpacket */ - int sptpslen; /* length of incoming SPTPS packet */ + int sptpslen; /* length of incoming SPTPS packet */ int allow_request; /* defined if there's only one request possible */ time_t last_ping_time; /* last time we saw some activity from the other end or pinged them */ @@ -112,10 +114,10 @@ extern connection_t *everyone; extern void init_connections(void); extern void exit_connections(void); -extern connection_t *new_connection(void) __attribute__ ((__malloc__)); -extern void free_connection(connection_t *); -extern void connection_add(connection_t *); -extern void connection_del(connection_t *); -extern bool dump_connections(struct connection_t *); +extern connection_t *new_connection(void) __attribute__((__malloc__)); +extern void free_connection(connection_t *c); +extern void connection_add(connection_t *c); +extern void connection_del(connection_t *c); +extern bool dump_connections(struct connection_t *c); -#endif /* __TINC_CONNECTION_H__ */ +#endif diff --git a/src/control.c b/src/control.c index 98eae80..71258b5 100644 --- a/src/control.c +++ b/src/control.c @@ -56,86 +56,95 @@ bool control_h(connection_t *c, const char *request) { return false; } - switch (type) { - case REQ_STOP: - event_exit(); - return control_ok(c, REQ_STOP); + switch(type) { + case REQ_STOP: + event_exit(); + return control_ok(c, REQ_STOP); - case REQ_DUMP_NODES: - return dump_nodes(c); + case REQ_DUMP_NODES: + return dump_nodes(c); - case REQ_DUMP_EDGES: - return dump_edges(c); + case REQ_DUMP_EDGES: + return dump_edges(c); - case REQ_DUMP_SUBNETS: - return dump_subnets(c); + case REQ_DUMP_SUBNETS: + return dump_subnets(c); - case REQ_DUMP_CONNECTIONS: - return dump_connections(c); + case REQ_DUMP_CONNECTIONS: + return dump_connections(c); - case REQ_PURGE: - purge(); - return control_ok(c, REQ_PURGE); + case REQ_PURGE: + purge(); + return control_ok(c, REQ_PURGE); - case REQ_SET_DEBUG: { - int new_level; - if(sscanf(request, "%*d %*d %d", &new_level) != 1) - return false; - send_request(c, "%d %d %d", CONTROL, REQ_SET_DEBUG, debug_level); - if(new_level >= 0) - debug_level = new_level; - return true; + case REQ_SET_DEBUG: { + int new_level; + + if(sscanf(request, "%*d %*d %d", &new_level) != 1) { + return false; } - case REQ_RETRY: - retry(); - return control_ok(c, REQ_RETRY); + send_request(c, "%d %d %d", CONTROL, REQ_SET_DEBUG, debug_level); - case REQ_RELOAD: - logger(DEBUG_ALWAYS, LOG_NOTICE, "Got '%s' command", "reload"); - int result = reload_configuration(); - return control_return(c, REQ_RELOAD, result); + if(new_level >= 0) { + debug_level = new_level; + } - case REQ_DISCONNECT: { - char name[MAX_STRING_SIZE]; - bool found = false; + return true; + } - if(sscanf(request, "%*d %*d " MAX_STRING, name) != 1) - return control_return(c, REQ_DISCONNECT, -1); + case REQ_RETRY: + retry(); + return control_ok(c, REQ_RETRY); - for list_each(connection_t, other, connection_list) { - if(strcmp(other->name, name)) - continue; - terminate_connection(other, other->edge); - found = true; + case REQ_RELOAD: + logger(DEBUG_ALWAYS, LOG_NOTICE, "Got '%s' command", "reload"); + int result = reload_configuration(); + return control_return(c, REQ_RELOAD, result); + + case REQ_DISCONNECT: { + char name[MAX_STRING_SIZE]; + bool found = false; + + if(sscanf(request, "%*d %*d " MAX_STRING, name) != 1) { + return control_return(c, REQ_DISCONNECT, -1); + } + + for list_each(connection_t, other, connection_list) { + if(strcmp(other->name, name)) { + continue; } - return control_return(c, REQ_DISCONNECT, found ? 0 : -2); + terminate_connection(other, other->edge); + found = true; } - case REQ_DUMP_TRAFFIC: - return dump_traffic(c); + return control_return(c, REQ_DISCONNECT, found ? 0 : -2); + } - case REQ_PCAP: - sscanf(request, "%*d %*d %d", &c->outmaclength); - c->status.pcap = true; - pcap = true; - return true; + case REQ_DUMP_TRAFFIC: + return dump_traffic(c); - case REQ_LOG: - sscanf(request, "%*d %*d %d", &c->outcompression); - c->status.log = true; - logcontrol = true; - return true; + case REQ_PCAP: + sscanf(request, "%*d %*d %d", &c->outmaclength); + c->status.pcap = true; + pcap = true; + return true; - default: - return send_request(c, "%d %d", CONTROL, REQ_INVALID); + case REQ_LOG: + sscanf(request, "%*d %*d %d", &c->outcompression); + c->status.log = true; + logcontrol = true; + return true; + + default: + return send_request(c, "%d %d", CONTROL, REQ_INVALID); } } bool init_control(void) { - randomize(controlcookie, sizeof controlcookie / 2); - bin2hex(controlcookie, controlcookie, sizeof controlcookie / 2); + randomize(controlcookie, sizeof(controlcookie) / 2); + bin2hex(controlcookie, controlcookie, sizeof(controlcookie) / 2); mode_t mask = umask(0); umask(mask | 077); @@ -150,21 +159,24 @@ bool init_control(void) { // Get the address and port of the first listening socket char *localhost = NULL; - sockaddr_t sa; - socklen_t len = sizeof sa; + sockaddr_t sa = {0}; + socklen_t len = sizeof(sa); // Make sure we have a valid address, and map 0.0.0.0 and :: to 127.0.0.1 and ::1. - if(getsockname(listen_socket[0].tcp.fd, (struct sockaddr *)&sa, &len)) { + if(getsockname(listen_socket[0].tcp.fd, &sa.sa, &len)) { xasprintf(&localhost, "127.0.0.1 port %s", myport); } else { if(sa.sa.sa_family == AF_INET) { - if(sa.in.sin_addr.s_addr == 0) + if(sa.in.sin_addr.s_addr == 0) { sa.in.sin_addr.s_addr = htonl(0x7f000001); + } } else if(sa.sa.sa_family == AF_INET6) { static const uint8_t zero[16] = {0}; - if(!memcmp(sa.in6.sin6_addr.s6_addr, zero, sizeof zero)) + + if(!memcmp(sa.in6.sin6_addr.s6_addr, zero, sizeof(zero))) { sa.in6.sin6_addr.s6_addr[15] = 1; + } } localhost = sockaddr2hostname(&sa); @@ -177,16 +189,21 @@ bool init_control(void) { #ifndef HAVE_MINGW int unix_fd = socket(AF_UNIX, SOCK_STREAM, 0); + if(unix_fd < 0) { logger(DEBUG_ALWAYS, LOG_ERR, "Could not create UNIX socket: %s", sockstrerror(sockerrno)); return false; } struct sockaddr_un sa_un; - sa_un.sun_family = AF_UNIX; - strncpy(sa_un.sun_path, unixsocketname, sizeof sa_un.sun_path); - if(connect(unix_fd, (struct sockaddr *)&sa_un, sizeof sa_un) >= 0) { + sa_un.sun_family = AF_UNIX; + + strncpy(sa_un.sun_path, unixsocketname, sizeof(sa_un.sun_path)); + + sa_un.sun_path[sizeof(sa_un.sun_path) - 1] = 0; + + if(connect(unix_fd, (struct sockaddr *)&sa_un, sizeof(sa_un)) >= 0) { logger(DEBUG_ALWAYS, LOG_ERR, "UNIX socket %s is still in use!", unixsocketname); return false; } @@ -194,7 +211,7 @@ bool init_control(void) { unlink(unixsocketname); umask(mask | 077); - int result = bind(unix_fd, (struct sockaddr *)&sa_un, sizeof sa_un); + int result = bind(unix_fd, (struct sockaddr *)&sa_un, sizeof(sa_un)); umask(mask); if(result < 0) { diff --git a/src/control.h b/src/control.h index ce8145a..9398410 100644 --- a/src/control.h +++ b/src/control.h @@ -1,3 +1,6 @@ +#ifndef TINC_CONTROL_H +#define TINC_CONTROL_H + /* control.h -- header for control.c. Copyright (C) 2007 Guus Sliepen @@ -17,11 +20,8 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#ifndef __TINC_CONTROL_H__ -#define __TINC_CONTROL_H__ - -extern bool init_control(); -extern void exit_control(); +extern bool init_control(void); +extern void exit_control(void); extern char controlcookie[]; #endif diff --git a/src/control_common.h b/src/control_common.h index cd54889..2be4abd 100644 --- a/src/control_common.h +++ b/src/control_common.h @@ -1,3 +1,6 @@ +#ifndef TINC_CONTROL_COMMON_H +#define TINC_CONTROL_COMMON_H + /* control_protocol.h -- control socket protocol. Copyright (C) 2007 Scott Lamb @@ -18,9 +21,6 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#ifndef __TINC_CONTROL_PROTOCOL_H__ -#define __TINC_CONTROL_PROTOCOL_H__ - #include "protocol.h" enum request_type { diff --git a/src/crypto.h b/src/crypto.h index cd3654f..74bab1b 100644 --- a/src/crypto.h +++ b/src/crypto.h @@ -1,3 +1,6 @@ +#ifndef TINC_CRYPTO_H +#define TINC_CRYPTO_H + /* crypto.h -- header for crypto.c Copyright (C) 2007-2013 Guus Sliepen @@ -17,11 +20,8 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#ifndef __TINC_CRYPTO_H__ -#define __TINC_CRYPTO_H__ - -extern void crypto_init(); -extern void crypto_exit(); -extern void randomize(void *, size_t); +extern void crypto_init(void); +extern void crypto_exit(void); +extern void randomize(void *buf, size_t buflen); #endif diff --git a/src/cygwin/device.c b/src/cygwin/device.c index d3a4303..6d94988 100644 --- a/src/cygwin/device.c +++ b/src/cygwin/device.c @@ -38,7 +38,7 @@ int device_fd = -1; static HANDLE device_handle = INVALID_HANDLE_VALUE; char *device = NULL; char *iface = NULL; -static char *device_info = NULL; +static const char *device_info = "Windows tap device"; static pid_t reader_pid; static int sp[2]; @@ -59,8 +59,9 @@ static bool setup_device(void) { get_config_string(lookup_config(config_tree, "Device"), &device); get_config_string(lookup_config(config_tree, "Interface"), &iface); - if(device && iface) + if(device && iface) { logger(LOG_WARNING, "Warning: both Device and Interface specified, results may not be as expected"); + } /* Open registry and look for network adapters */ @@ -69,44 +70,51 @@ static bool setup_device(void) { return false; } - for (i = 0; ; i++) { - len = sizeof adapterid; - if(RegEnumKeyEx(key, i, adapterid, &len, 0, 0, 0, NULL)) + for(i = 0; ; i++) { + len = sizeof(adapterid); + + if(RegEnumKeyEx(key, i, adapterid, &len, 0, 0, 0, NULL)) { break; + } /* Find out more about this adapter */ - snprintf(regpath, sizeof regpath, "%s\\%s\\Connection", NETWORK_CONNECTIONS_KEY, adapterid); + snprintf(regpath, sizeof(regpath), "%s\\%s\\Connection", NETWORK_CONNECTIONS_KEY, adapterid); - if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, regpath, 0, KEY_READ, &key2)) + if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, regpath, 0, KEY_READ, &key2)) { continue; + } - len = sizeof adaptername; + len = sizeof(adaptername); err = RegQueryValueEx(key2, "Name", 0, 0, adaptername, &len); RegCloseKey(key2); - if(err) + if(err) { continue; + } if(device) { if(!strcmp(device, adapterid)) { found = true; break; - } else + } else { continue; + } } if(iface) { if(!strcmp(iface, adaptername)) { found = true; break; - } else + } else { continue; + } } - snprintf(tapname, sizeof tapname, USERMODEDEVICEDIR "%s" TAPSUFFIX, adapterid); + snprintf(tapname, sizeof(tapname), USERMODEDEVICEDIR "%s" TAPSUFFIX, adapterid); device_handle = CreateFile(tapname, GENERIC_WRITE | GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM, 0); + if(device_handle != INVALID_HANDLE_VALUE) { CloseHandle(device_handle); found = true; @@ -121,13 +129,15 @@ static bool setup_device(void) { return false; } - if(!device) + if(!device) { device = xstrdup(adapterid); + } - if(!iface) + if(!iface) { iface = xstrdup(adaptername); + } - snprintf(tapname, sizeof tapname, USERMODEDEVICEDIR "%s" TAPSUFFIX, device); + snprintf(tapname, sizeof(tapname), USERMODEDEVICEDIR "%s" TAPSUFFIX, device); /* Now we are going to open this device twice: once for reading and once for writing. We do this because apparently it isn't possible to check for activity in the select() loop. @@ -140,7 +150,7 @@ static bool setup_device(void) { /* The parent opens the tap device for writing. */ - device_handle = CreateFile(tapname, GENERIC_WRITE, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM , 0); + device_handle = CreateFile(tapname, GENERIC_WRITE, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM, 0); if(device_handle == INVALID_HANDLE_VALUE) { logger(DEBUG_ALWAYS, LOG_ERR, "Could not open Windows tap device %s (%s) for writing: %s", device, iface, winerror(GetLastError())); @@ -151,7 +161,7 @@ static bool setup_device(void) { /* Get MAC address from tap device */ - if(!DeviceIoControl(device_handle, TAP_IOCTL_GET_MAC, mymac.x, sizeof mymac.x, mymac.x, sizeof mymac.x, &len, 0)) { + if(!DeviceIoControl(device_handle, TAP_IOCTL_GET_MAC, mymac.x, sizeof(mymac.x), mymac.x, sizeof(mymac.x), &len, 0)) { logger(DEBUG_ALWAYS, LOG_ERR, "Could not get MAC address from Windows tap device %s (%s): %s", device, iface, winerror(GetLastError())); return false; } @@ -203,13 +213,12 @@ static bool setup_device(void) { } read(device_fd, &gelukt, 1); + if(gelukt != 1) { logger(DEBUG_ALWAYS, LOG_DEBUG, "Tap reader failed!"); return false; } - device_info = "Windows tap device"; - logger(DEBUG_ALWAYS, LOG_INFO, "%s (%s) is a %s", device, iface, device_info); return true; @@ -218,12 +227,15 @@ static bool setup_device(void) { static void close_device(void) { close(sp[0]); close(sp[1]); - CloseHandle(device_handle); device_handle = INVALID_HANDLE_VALUE; + CloseHandle(device_handle); + device_handle = INVALID_HANDLE_VALUE; kill(reader_pid, SIGKILL); - free(device); device = NULL; - free(iface); iface = NULL; + free(device); + device = NULL; + free(iface); + iface = NULL; device_info = NULL; } @@ -232,14 +244,14 @@ static bool read_packet(vpn_packet_t *packet) { if((inlen = read(sp[0], DATA(packet), MTU)) <= 0) { logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info, - device, strerror(errno)); + device, strerror(errno)); return false; } packet->len = inlen; logger(DEBUG_TRAFFIC, LOG_DEBUG, "Read packet of %d bytes from %s", packet->len, - device_info); + device_info); return true; } @@ -248,9 +260,9 @@ static bool write_packet(vpn_packet_t *packet) { long outlen; logger(DEBUG_TRAFFIC, LOG_DEBUG, "Writing packet of %d bytes to %s", - packet->len, device_info); + packet->len, device_info); - if(!WriteFile (device_handle, DATA(packet), packet->len, &outlen, NULL)) { + if(!WriteFile(device_handle, DATA(packet), packet->len, &outlen, NULL)) { logger(DEBUG_ALWAYS, LOG_ERR, "Error while writing to %s %s: %s", device_info, device, winerror(GetLastError())); return false; } diff --git a/src/device.h b/src/device.h index fa27df3..c85671b 100644 --- a/src/device.h +++ b/src/device.h @@ -1,3 +1,6 @@ +#ifndef TINC_DEVICE_H +#define TINC_DEVICE_H + /* device.h -- generic header for device.c Copyright (C) 2001-2005 Ivo Timmermans @@ -18,9 +21,6 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#ifndef __TINC_DEVICE_H__ -#define __TINC_DEVICE_H__ - #include "net.h" extern int device_fd; @@ -45,4 +45,4 @@ extern const devops_t uml_devops; extern const devops_t vde_devops; extern devops_t devops; -#endif /* __TINC_DEVICE_H__ */ +#endif diff --git a/src/digest.h b/src/digest.h index a3691bf..6d7cb41 100644 --- a/src/digest.h +++ b/src/digest.h @@ -1,3 +1,6 @@ +#ifndef TINC_DIGEST_H +#define TINC_DIGEST_H + /* digest.h -- header file digest.c Copyright (C) 2007-2016 Guus Sliepen @@ -17,25 +20,22 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#ifndef __TINC_DIGEST_H__ -#define __TINC_DIGEST_H__ - #define DIGEST_MAX_SIZE 64 #ifndef DISABLE_LEGACY typedef struct digest digest_t; -extern digest_t *digest_open_by_name(const char *name, int maclength) __attribute__ ((__malloc__)); -extern digest_t *digest_open_by_nid(int nid, int maclength) __attribute__ ((__malloc__)); -extern void digest_close(digest_t *); -extern bool digest_create(digest_t *, const void *indata, size_t inlen, void *outdata) __attribute__ ((__warn_unused_result__)); -extern bool digest_verify(digest_t *, const void *indata, size_t inlen, const void *digestdata) __attribute__ ((__warn_unused_result__)); -extern bool digest_set_key(digest_t *, const void *key, size_t len) __attribute__ ((__warn_unused_result__)); -extern int digest_get_nid(const digest_t *); -extern size_t digest_keylength(const digest_t *); -extern size_t digest_length(const digest_t *); -extern bool digest_active(const digest_t *); +extern digest_t *digest_open_by_name(const char *name, int maclength) __attribute__((__malloc__)); +extern digest_t *digest_open_by_nid(int nid, int maclength) __attribute__((__malloc__)); +extern void digest_close(digest_t *digest); +extern bool digest_create(digest_t *digest, const void *indata, size_t inlen, void *outdata) __attribute__((__warn_unused_result__)); +extern bool digest_verify(digest_t *digest, const void *indata, size_t inlen, const void *digestdata) __attribute__((__warn_unused_result__)); +extern bool digest_set_key(digest_t *digest, const void *key, size_t len) __attribute__((__warn_unused_result__)); +extern int digest_get_nid(const digest_t *digest); +extern size_t digest_keylength(const digest_t *digest); +extern size_t digest_length(const digest_t *digest); +extern bool digest_active(const digest_t *digest); #endif diff --git a/src/dropin.c b/src/dropin.c index a4f7a65..74e5676 100644 --- a/src/dropin.c +++ b/src/dropin.c @@ -50,8 +50,9 @@ int daemon(int nochdir, int noclose) { } /* If we are the parent, terminate */ - if(pid) + if(pid) { exit(0); + } /* Detach by becoming the new process group leader */ if(setsid() < 0) { @@ -108,8 +109,9 @@ int vasprintf(char **buf, const char *fmt, va_list ap) { status = vsnprintf(*buf, len, fmt, aq); va_end(aq); - if(status >= 0) + if(status >= 0) { *buf = xrealloc(*buf, status + 1); + } if(status > len - 1) { len = status + 1; diff --git a/src/dropin.h b/src/dropin.h index 938f30d..5033f90 100644 --- a/src/dropin.h +++ b/src/dropin.h @@ -1,3 +1,6 @@ +#ifndef TINC_DROPIN_H +#define TINC_DROPIN_H + /* dropin.h -- header file for dropin.c Copyright (C) 2000-2005 Ivo Timmermans, @@ -18,9 +21,6 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#ifndef __DROPIN_H__ -#define __DROPIN_H__ - #ifndef HAVE_DAEMON extern int daemon(int, int); #endif @@ -40,20 +40,20 @@ extern int nanosleep(const struct timespec *req, struct timespec *rem); #ifndef timeradd #define timeradd(a, b, r) do {\ - (r)->tv_sec = (a)->tv_sec + (b)->tv_sec;\ - (r)->tv_usec = (a)->tv_usec + (b)->tv_usec;\ - if((r)->tv_usec >= 1000000)\ - (r)->tv_sec++, (r)->tv_usec -= 1000000;\ -} while (0) + (r)->tv_sec = (a)->tv_sec + (b)->tv_sec;\ + (r)->tv_usec = (a)->tv_usec + (b)->tv_usec;\ + if((r)->tv_usec >= 1000000)\ + (r)->tv_sec++, (r)->tv_usec -= 1000000;\ + } while (0) #endif #ifndef timersub #define timersub(a, b, r) do {\ - (r)->tv_sec = (a)->tv_sec - (b)->tv_sec;\ - (r)->tv_usec = (a)->tv_usec - (b)->tv_usec;\ - if((r)->tv_usec < 0)\ - (r)->tv_sec--, (r)->tv_usec += 1000000;\ -} while (0) + (r)->tv_sec = (a)->tv_sec - (b)->tv_sec;\ + (r)->tv_usec = (a)->tv_usec - (b)->tv_usec;\ + if((r)->tv_usec < 0)\ + (r)->tv_sec--, (r)->tv_usec += 1000000;\ + } while (0) #endif #ifdef HAVE_MINGW @@ -67,4 +67,4 @@ extern int nanosleep(const struct timespec *req, struct timespec *rem); #define EAI_SYSTEM 0 #endif -#endif /* __DROPIN_H__ */ +#endif diff --git a/src/dummy_device.c b/src/dummy_device.c index c43d586..15f0654 100644 --- a/src/dummy_device.c +++ b/src/dummy_device.c @@ -22,12 +22,13 @@ #include "device.h" #include "logger.h" #include "net.h" +#include "xalloc.h" -static char *device_info = "dummy device"; +static const char *device_info = "dummy device"; static bool setup_device(void) { - device = "dummy"; - iface = "dummy"; + device = xstrdup("dummy"); + iface = xstrdup("dummy"); logger(DEBUG_ALWAYS, LOG_INFO, "%s (%s) is a %s", device, iface, device_info); return true; } @@ -36,10 +37,12 @@ static void close_device(void) { } static bool read_packet(vpn_packet_t *packet) { + (void)packet; return false; } static bool write_packet(vpn_packet_t *packet) { + (void)packet; return true; } diff --git a/src/ecdh.h b/src/ecdh.h index c5ea3ef..0bfc271 100644 --- a/src/ecdh.h +++ b/src/ecdh.h @@ -1,3 +1,6 @@ +#ifndef TINC_ECDH_H +#define TINC_ECDH_H + /* ecdh.h -- header file for ecdh.c Copyright (C) 2011-2013 Guus Sliepen @@ -17,18 +20,15 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#ifndef __TINC_ECDH_H__ -#define __TINC_ECDH_H__ - #define ECDH_SIZE 32 #define ECDH_SHARED_SIZE 32 -#ifndef __TINC_ECDH_INTERNAL__ +#ifndef TINC_ECDH_INTERNAL typedef struct ecdh ecdh_t; #endif -extern ecdh_t *ecdh_generate_public(void *pubkey) __attribute__ ((__malloc__)); -extern bool ecdh_compute_shared(ecdh_t *ecdh, const void *pubkey, void *shared) __attribute__ ((__warn_unused_result__)); +extern ecdh_t *ecdh_generate_public(void *pubkey) __attribute__((__malloc__)); +extern bool ecdh_compute_shared(ecdh_t *ecdh, const void *pubkey, void *shared) __attribute__((__warn_unused_result__)); extern void ecdh_free(ecdh_t *ecdh); #endif diff --git a/src/ecdsa.h b/src/ecdsa.h index d03a58e..6cb5434 100644 --- a/src/ecdsa.h +++ b/src/ecdsa.h @@ -1,3 +1,6 @@ +#ifndef TINC_ECDSA_H +#define TINC_ECDSA_H + /* ecdsa.h -- ECDSA key handling Copyright (C) 2011-2013 Guus Sliepen @@ -17,20 +20,17 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#ifndef __TINC_ECDSA_H__ -#define __TINC_ECDSA_H__ - -#ifndef __TINC_ECDSA_INTERNAL__ +#ifndef TINC_ECDSA_INTERNAL typedef struct ecdsa ecdsa_t; #endif -extern ecdsa_t *ecdsa_set_base64_public_key(const char *p) __attribute__ ((__malloc__)); +extern ecdsa_t *ecdsa_set_base64_public_key(const char *p) __attribute__((__malloc__)); extern char *ecdsa_get_base64_public_key(ecdsa_t *ecdsa); -extern ecdsa_t *ecdsa_read_pem_public_key(FILE *fp) __attribute__ ((__malloc__)); -extern ecdsa_t *ecdsa_read_pem_private_key(FILE *fp) __attribute__ ((__malloc__)); +extern ecdsa_t *ecdsa_read_pem_public_key(FILE *fp) __attribute__((__malloc__)); +extern ecdsa_t *ecdsa_read_pem_private_key(FILE *fp) __attribute__((__malloc__)); extern size_t ecdsa_size(ecdsa_t *ecdsa); -extern bool ecdsa_sign(ecdsa_t *ecdsa, const void *in, size_t inlen, void *out) __attribute__ ((__warn_unused_result__)); -extern bool ecdsa_verify(ecdsa_t *ecdsa, const void *in, size_t inlen, const void *out) __attribute__ ((__warn_unused_result__)); +extern bool ecdsa_sign(ecdsa_t *ecdsa, const void *in, size_t inlen, void *out) __attribute__((__warn_unused_result__)); +extern bool ecdsa_verify(ecdsa_t *ecdsa, const void *in, size_t inlen, const void *out) __attribute__((__warn_unused_result__)); extern bool ecdsa_active(ecdsa_t *ecdsa); extern void ecdsa_free(ecdsa_t *ecdsa); diff --git a/src/ecdsagen.h b/src/ecdsagen.h index 12e5c00..48cd25b 100644 --- a/src/ecdsagen.h +++ b/src/ecdsagen.h @@ -1,3 +1,6 @@ +#ifndef TINC_ECDSAGEN_H +#define TINC_ECDSAGEN_H + /* ecdsagen.h -- ECDSA key generation and export Copyright (C) 2011-2013 Guus Sliepen @@ -17,13 +20,10 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#ifndef __TINC_ECDSAGEN_H__ -#define __TINC_ECDSAGEN_H__ - #include "ecdsa.h" -extern ecdsa_t *ecdsa_generate(void) __attribute__ ((__malloc__)); -extern bool ecdsa_write_pem_public_key(ecdsa_t *ecdsa, FILE *fp) __attribute__ ((__warn_unused_result__)); -extern bool ecdsa_write_pem_private_key(ecdsa_t *ecdsa, FILE *fp) __attribute__ ((__warn_unused_result__)); +extern ecdsa_t *ecdsa_generate(void) __attribute__((__malloc__)); +extern bool ecdsa_write_pem_public_key(ecdsa_t *ecdsa, FILE *fp) __attribute__((__warn_unused_result__)); +extern bool ecdsa_write_pem_private_key(ecdsa_t *ecdsa, FILE *fp) __attribute__((__warn_unused_result__)); #endif diff --git a/src/ed25519/ecdh.c b/src/ed25519/ecdh.c index d0cd7e0..302fafd 100644 --- a/src/ed25519/ecdh.c +++ b/src/ed25519/ecdh.c @@ -21,7 +21,7 @@ #include "ed25519.h" -#define __TINC_ECDH_INTERNAL__ +#define TINC_ECDH_INTERNAL typedef struct ecdh_t { uint8_t private[64]; } ecdh_t; @@ -31,10 +31,10 @@ typedef struct ecdh_t { #include "../xalloc.h" ecdh_t *ecdh_generate_public(void *pubkey) { - ecdh_t *ecdh = xzalloc(sizeof *ecdh); + ecdh_t *ecdh = xzalloc(sizeof(*ecdh)); uint8_t seed[32]; - randomize(seed, sizeof seed); + randomize(seed, sizeof(seed)); ed25519_create_keypair(pubkey, ecdh->private, seed); return ecdh; diff --git a/src/ed25519/ecdsa.c b/src/ed25519/ecdsa.c index f8aafe4..4bd7155 100644 --- a/src/ed25519/ecdsa.c +++ b/src/ed25519/ecdsa.c @@ -21,7 +21,7 @@ #include "ed25519.h" -#define __TINC_ECDSA_INTERNAL__ +#define TINC_ECDSA_INTERNAL typedef struct { uint8_t private[64]; uint8_t public[32]; @@ -42,8 +42,9 @@ ecdsa_t *ecdsa_set_base64_public_key(const char *p) { return 0; } - ecdsa_t *ecdsa = xzalloc(sizeof *ecdsa); + ecdsa_t *ecdsa = xzalloc(sizeof(*ecdsa)); len = b64decode(p, ecdsa->public, len); + if(len != 32) { logger(DEBUG_ALWAYS, LOG_ERR, "Invalid format of public key! len = %d", len); free(ecdsa); @@ -55,33 +56,40 @@ ecdsa_t *ecdsa_set_base64_public_key(const char *p) { char *ecdsa_get_base64_public_key(ecdsa_t *ecdsa) { char *base64 = xmalloc(44); - b64encode(ecdsa->public, base64, sizeof ecdsa->public); + b64encode(ecdsa->public, base64, sizeof(ecdsa->public)); return base64; } // Read PEM ECDSA keys -static bool read_pem(FILE *fp, const char *type, void *buf, size_t size) { +static bool read_pem(FILE *fp, const char *type, void *vbuf, size_t size) { char line[1024]; bool data = false; size_t typelen = strlen(type); + char *buf = vbuf; - while(fgets(line, sizeof line, fp)) { + while(fgets(line, sizeof(line), fp)) { if(!data) { - if(strncmp(line, "-----BEGIN ", 11)) + if(strncmp(line, "-----BEGIN ", 11)) { continue; - if(strncmp(line + 11, type, typelen)) + } + + if(strncmp(line + 11, type, typelen)) { continue; + } + data = true; continue; } - if(!strncmp(line, "-----END ", 9)) + if(!strncmp(line, "-----END ", 9)) { break; + } size_t linelen = strcspn(line, "\r\n"); size_t len = b64decode(line, line, linelen); + if(!len) { logger(DEBUG_ALWAYS, LOG_ERR, "Invalid base64 data in PEM file\n"); errno = EINVAL; @@ -106,6 +114,7 @@ static bool read_pem(FILE *fp, const char *type, void *buf, size_t size) { } else { errno = ENOENT; } + return false; } @@ -113,22 +122,29 @@ static bool read_pem(FILE *fp, const char *type, void *buf, size_t size) { } ecdsa_t *ecdsa_read_pem_public_key(FILE *fp) { - ecdsa_t *ecdsa = xzalloc(sizeof *ecdsa); - if(read_pem(fp, "ED25519 PUBLIC KEY", ecdsa->public, sizeof ecdsa->public)) + ecdsa_t *ecdsa = xzalloc(sizeof(*ecdsa)); + + if(read_pem(fp, "ED25519 PUBLIC KEY", ecdsa->public, sizeof(ecdsa->public))) { return ecdsa; + } + free(ecdsa); return 0; } ecdsa_t *ecdsa_read_pem_private_key(FILE *fp) { - ecdsa_t *ecdsa = xmalloc(sizeof *ecdsa); - if(read_pem(fp, "ED25519 PRIVATE KEY", ecdsa->private, sizeof *ecdsa)) + ecdsa_t *ecdsa = xmalloc(sizeof(*ecdsa)); + + if(read_pem(fp, "ED25519 PRIVATE KEY", ecdsa->private, sizeof(*ecdsa))) { return ecdsa; + } + free(ecdsa); return 0; } size_t ecdsa_size(ecdsa_t *ecdsa) { + (void)ecdsa; return 64; } diff --git a/src/ed25519/ecdsagen.c b/src/ed25519/ecdsagen.c index d2a1489..ede5136 100644 --- a/src/ed25519/ecdsagen.c +++ b/src/ed25519/ecdsagen.c @@ -21,7 +21,7 @@ #include "ed25519.h" -#define __TINC_ECDSA_INTERNAL__ +#define TINC_ECDSA_INTERNAL typedef struct { uint8_t private[64]; uint8_t public[32]; @@ -35,10 +35,10 @@ typedef struct { // Generate ECDSA key ecdsa_t *ecdsa_generate(void) { - ecdsa_t *ecdsa = xzalloc(sizeof *ecdsa); + ecdsa_t *ecdsa = xzalloc(sizeof(*ecdsa)); uint8_t seed[32]; - randomize(seed, sizeof seed); + randomize(seed, sizeof(seed)); ed25519_create_keypair(ecdsa->public, ecdsa->private, seed); return ecdsa; @@ -46,10 +46,12 @@ ecdsa_t *ecdsa_generate(void) { // Write PEM ECDSA keys -static bool write_pem(FILE *fp, const char *type, void *buf, size_t size) { +static bool write_pem(FILE *fp, const char *type, void *vbuf, size_t size) { fprintf(fp, "-----BEGIN %s-----\n", type); + char *buf = vbuf; char base64[65]; + while(size) { size_t todo = size > 48 ? 48 : size; b64encode(buf, base64, todo); @@ -63,9 +65,9 @@ static bool write_pem(FILE *fp, const char *type, void *buf, size_t size) { } bool ecdsa_write_pem_public_key(ecdsa_t *ecdsa, FILE *fp) { - return write_pem(fp, "ED25519 PUBLIC KEY", ecdsa->public, sizeof ecdsa->public); + return write_pem(fp, "ED25519 PUBLIC KEY", ecdsa->public, sizeof(ecdsa->public)); } bool ecdsa_write_pem_private_key(ecdsa_t *ecdsa, FILE *fp) { - return write_pem(fp, "ED25519 PRIVATE KEY", ecdsa->private, sizeof *ecdsa); + return write_pem(fp, "ED25519 PRIVATE KEY", ecdsa->private, sizeof(*ecdsa)); } diff --git a/src/ed25519/ed25519.h b/src/ed25519/ed25519.h index 5cb82d5..65b191e 100644 --- a/src/ed25519/ed25519.h +++ b/src/ed25519/ed25519.h @@ -4,15 +4,15 @@ #include #if defined(_WIN32) - #if defined(ED25519_BUILD_DLL) - #define ED25519_DECLSPEC __declspec(dllexport) - #elif defined(ED25519_DLL) - #define ED25519_DECLSPEC __declspec(dllimport) - #else - #define ED25519_DECLSPEC - #endif +#if defined(ED25519_BUILD_DLL) +#define ED25519_DECLSPEC __declspec(dllexport) +#elif defined(ED25519_DLL) +#define ED25519_DECLSPEC __declspec(dllimport) #else - #define ED25519_DECLSPEC +#define ED25519_DECLSPEC +#endif +#else +#define ED25519_DECLSPEC #endif diff --git a/src/ed25519/fe.c b/src/ed25519/fe.c index 1c459f4..df907a7 100644 --- a/src/ed25519/fe.c +++ b/src/ed25519/fe.c @@ -6,24 +6,24 @@ helper functions */ static uint64_t load_3(const unsigned char *in) { - uint64_t result; + uint64_t result; - result = in[0]; - result |= shlu64(in[1], 8); - result |= shlu64(in[2], 16); + result = in[0]; + result |= shlu64(in[1], 8); + result |= shlu64(in[2], 16); - return result; + return result; } static uint64_t load_4(const unsigned char *in) { - uint64_t result; + uint64_t result; - result = in[0]; - result |= shlu64(in[1], 8); - result |= shlu64(in[2], 16); - result |= shlu64(in[3], 24); - - return result; + result = in[0]; + result |= shlu64(in[1], 8); + result |= shlu64(in[2], 16); + result |= shlu64(in[3], 24); + + return result; } @@ -33,16 +33,16 @@ static uint64_t load_4(const unsigned char *in) { */ void fe_0(fe h) { - h[0] = 0; - h[1] = 0; - h[2] = 0; - h[3] = 0; - h[4] = 0; - h[5] = 0; - h[6] = 0; - h[7] = 0; - h[8] = 0; - h[9] = 0; + h[0] = 0; + h[1] = 0; + h[2] = 0; + h[3] = 0; + h[4] = 0; + h[5] = 0; + h[6] = 0; + h[7] = 0; + h[8] = 0; + h[9] = 0; } @@ -52,16 +52,16 @@ void fe_0(fe h) { */ void fe_1(fe h) { - h[0] = 1; - h[1] = 0; - h[2] = 0; - h[3] = 0; - h[4] = 0; - h[5] = 0; - h[6] = 0; - h[7] = 0; - h[8] = 0; - h[9] = 0; + h[0] = 1; + h[1] = 0; + h[2] = 0; + h[3] = 0; + h[4] = 0; + h[5] = 0; + h[6] = 0; + h[7] = 0; + h[8] = 0; + h[9] = 0; } @@ -79,47 +79,47 @@ void fe_1(fe h) { */ void fe_add(fe h, const fe f, const fe g) { - int32_t f0 = f[0]; - int32_t f1 = f[1]; - int32_t f2 = f[2]; - int32_t f3 = f[3]; - int32_t f4 = f[4]; - int32_t f5 = f[5]; - int32_t f6 = f[6]; - int32_t f7 = f[7]; - int32_t f8 = f[8]; - int32_t f9 = f[9]; - int32_t g0 = g[0]; - int32_t g1 = g[1]; - int32_t g2 = g[2]; - int32_t g3 = g[3]; - int32_t g4 = g[4]; - int32_t g5 = g[5]; - int32_t g6 = g[6]; - int32_t g7 = g[7]; - int32_t g8 = g[8]; - int32_t g9 = g[9]; - int32_t h0 = f0 + g0; - int32_t h1 = f1 + g1; - int32_t h2 = f2 + g2; - int32_t h3 = f3 + g3; - int32_t h4 = f4 + g4; - int32_t h5 = f5 + g5; - int32_t h6 = f6 + g6; - int32_t h7 = f7 + g7; - int32_t h8 = f8 + g8; - int32_t h9 = f9 + g9; - - h[0] = h0; - h[1] = h1; - h[2] = h2; - h[3] = h3; - h[4] = h4; - h[5] = h5; - h[6] = h6; - h[7] = h7; - h[8] = h8; - h[9] = h9; + int32_t f0 = f[0]; + int32_t f1 = f[1]; + int32_t f2 = f[2]; + int32_t f3 = f[3]; + int32_t f4 = f[4]; + int32_t f5 = f[5]; + int32_t f6 = f[6]; + int32_t f7 = f[7]; + int32_t f8 = f[8]; + int32_t f9 = f[9]; + int32_t g0 = g[0]; + int32_t g1 = g[1]; + int32_t g2 = g[2]; + int32_t g3 = g[3]; + int32_t g4 = g[4]; + int32_t g5 = g[5]; + int32_t g6 = g[6]; + int32_t g7 = g[7]; + int32_t g8 = g[8]; + int32_t g9 = g[9]; + int32_t h0 = f0 + g0; + int32_t h1 = f1 + g1; + int32_t h2 = f2 + g2; + int32_t h3 = f3 + g3; + int32_t h4 = f4 + g4; + int32_t h5 = f5 + g5; + int32_t h6 = f6 + g6; + int32_t h7 = f7 + g7; + int32_t h8 = f8 + g8; + int32_t h9 = f9 + g9; + + h[0] = h0; + h[1] = h1; + h[2] = h2; + h[3] = h3; + h[4] = h4; + h[5] = h5; + h[6] = h6; + h[7] = h7; + h[8] = h8; + h[9] = h9; } @@ -132,59 +132,59 @@ void fe_add(fe h, const fe f, const fe g) { */ void fe_cmov(fe f, const fe g, unsigned int b) { - int32_t f0 = f[0]; - int32_t f1 = f[1]; - int32_t f2 = f[2]; - int32_t f3 = f[3]; - int32_t f4 = f[4]; - int32_t f5 = f[5]; - int32_t f6 = f[6]; - int32_t f7 = f[7]; - int32_t f8 = f[8]; - int32_t f9 = f[9]; - int32_t g0 = g[0]; - int32_t g1 = g[1]; - int32_t g2 = g[2]; - int32_t g3 = g[3]; - int32_t g4 = g[4]; - int32_t g5 = g[5]; - int32_t g6 = g[6]; - int32_t g7 = g[7]; - int32_t g8 = g[8]; - int32_t g9 = g[9]; - int32_t x0 = f0 ^ g0; - int32_t x1 = f1 ^ g1; - int32_t x2 = f2 ^ g2; - int32_t x3 = f3 ^ g3; - int32_t x4 = f4 ^ g4; - int32_t x5 = f5 ^ g5; - int32_t x6 = f6 ^ g6; - int32_t x7 = f7 ^ g7; - int32_t x8 = f8 ^ g8; - int32_t x9 = f9 ^ g9; + int32_t f0 = f[0]; + int32_t f1 = f[1]; + int32_t f2 = f[2]; + int32_t f3 = f[3]; + int32_t f4 = f[4]; + int32_t f5 = f[5]; + int32_t f6 = f[6]; + int32_t f7 = f[7]; + int32_t f8 = f[8]; + int32_t f9 = f[9]; + int32_t g0 = g[0]; + int32_t g1 = g[1]; + int32_t g2 = g[2]; + int32_t g3 = g[3]; + int32_t g4 = g[4]; + int32_t g5 = g[5]; + int32_t g6 = g[6]; + int32_t g7 = g[7]; + int32_t g8 = g[8]; + int32_t g9 = g[9]; + int32_t x0 = f0 ^ g0; + int32_t x1 = f1 ^ g1; + int32_t x2 = f2 ^ g2; + int32_t x3 = f3 ^ g3; + int32_t x4 = f4 ^ g4; + int32_t x5 = f5 ^ g5; + int32_t x6 = f6 ^ g6; + int32_t x7 = f7 ^ g7; + int32_t x8 = f8 ^ g8; + int32_t x9 = f9 ^ g9; - b = (unsigned int) (- (int) b); /* silence warning */ - x0 &= b; - x1 &= b; - x2 &= b; - x3 &= b; - x4 &= b; - x5 &= b; - x6 &= b; - x7 &= b; - x8 &= b; - x9 &= b; - - f[0] = f0 ^ x0; - f[1] = f1 ^ x1; - f[2] = f2 ^ x2; - f[3] = f3 ^ x3; - f[4] = f4 ^ x4; - f[5] = f5 ^ x5; - f[6] = f6 ^ x6; - f[7] = f7 ^ x7; - f[8] = f8 ^ x8; - f[9] = f9 ^ x9; + b = (unsigned int)(- (int) b); /* silence warning */ + x0 &= b; + x1 &= b; + x2 &= b; + x3 &= b; + x4 &= b; + x5 &= b; + x6 &= b; + x7 &= b; + x8 &= b; + x9 &= b; + + f[0] = f0 ^ x0; + f[1] = f1 ^ x1; + f[2] = f2 ^ x2; + f[3] = f3 ^ x3; + f[4] = f4 ^ x4; + f[5] = f5 ^ x5; + f[6] = f6 ^ x6; + f[7] = f7 ^ x7; + f[8] = f8 ^ x8; + f[9] = f9 ^ x9; } /* @@ -194,68 +194,68 @@ void fe_cmov(fe f, const fe g, unsigned int b) { Preconditions: b in {0,1}. */ -void fe_cswap(fe f,fe g,unsigned int b) { - int32_t f0 = f[0]; - int32_t f1 = f[1]; - int32_t f2 = f[2]; - int32_t f3 = f[3]; - int32_t f4 = f[4]; - int32_t f5 = f[5]; - int32_t f6 = f[6]; - int32_t f7 = f[7]; - int32_t f8 = f[8]; - int32_t f9 = f[9]; - int32_t g0 = g[0]; - int32_t g1 = g[1]; - int32_t g2 = g[2]; - int32_t g3 = g[3]; - int32_t g4 = g[4]; - int32_t g5 = g[5]; - int32_t g6 = g[6]; - int32_t g7 = g[7]; - int32_t g8 = g[8]; - int32_t g9 = g[9]; - int32_t x0 = f0 ^ g0; - int32_t x1 = f1 ^ g1; - int32_t x2 = f2 ^ g2; - int32_t x3 = f3 ^ g3; - int32_t x4 = f4 ^ g4; - int32_t x5 = f5 ^ g5; - int32_t x6 = f6 ^ g6; - int32_t x7 = f7 ^ g7; - int32_t x8 = f8 ^ g8; - int32_t x9 = f9 ^ g9; - b = -b; - x0 &= b; - x1 &= b; - x2 &= b; - x3 &= b; - x4 &= b; - x5 &= b; - x6 &= b; - x7 &= b; - x8 &= b; - x9 &= b; - f[0] = f0 ^ x0; - f[1] = f1 ^ x1; - f[2] = f2 ^ x2; - f[3] = f3 ^ x3; - f[4] = f4 ^ x4; - f[5] = f5 ^ x5; - f[6] = f6 ^ x6; - f[7] = f7 ^ x7; - f[8] = f8 ^ x8; - f[9] = f9 ^ x9; - g[0] = g0 ^ x0; - g[1] = g1 ^ x1; - g[2] = g2 ^ x2; - g[3] = g3 ^ x3; - g[4] = g4 ^ x4; - g[5] = g5 ^ x5; - g[6] = g6 ^ x6; - g[7] = g7 ^ x7; - g[8] = g8 ^ x8; - g[9] = g9 ^ x9; +void fe_cswap(fe f, fe g, unsigned int b) { + int32_t f0 = f[0]; + int32_t f1 = f[1]; + int32_t f2 = f[2]; + int32_t f3 = f[3]; + int32_t f4 = f[4]; + int32_t f5 = f[5]; + int32_t f6 = f[6]; + int32_t f7 = f[7]; + int32_t f8 = f[8]; + int32_t f9 = f[9]; + int32_t g0 = g[0]; + int32_t g1 = g[1]; + int32_t g2 = g[2]; + int32_t g3 = g[3]; + int32_t g4 = g[4]; + int32_t g5 = g[5]; + int32_t g6 = g[6]; + int32_t g7 = g[7]; + int32_t g8 = g[8]; + int32_t g9 = g[9]; + int32_t x0 = f0 ^ g0; + int32_t x1 = f1 ^ g1; + int32_t x2 = f2 ^ g2; + int32_t x3 = f3 ^ g3; + int32_t x4 = f4 ^ g4; + int32_t x5 = f5 ^ g5; + int32_t x6 = f6 ^ g6; + int32_t x7 = f7 ^ g7; + int32_t x8 = f8 ^ g8; + int32_t x9 = f9 ^ g9; + b = -b; + x0 &= b; + x1 &= b; + x2 &= b; + x3 &= b; + x4 &= b; + x5 &= b; + x6 &= b; + x7 &= b; + x8 &= b; + x9 &= b; + f[0] = f0 ^ x0; + f[1] = f1 ^ x1; + f[2] = f2 ^ x2; + f[3] = f3 ^ x3; + f[4] = f4 ^ x4; + f[5] = f5 ^ x5; + f[6] = f6 ^ x6; + f[7] = f7 ^ x7; + f[8] = f8 ^ x8; + f[9] = f9 ^ x9; + g[0] = g0 ^ x0; + g[1] = g1 ^ x1; + g[2] = g2 ^ x2; + g[3] = g3 ^ x3; + g[4] = g4 ^ x4; + g[5] = g5 ^ x5; + g[6] = g6 ^ x6; + g[7] = g7 ^ x7; + g[8] = g8 ^ x8; + g[9] = g9 ^ x9; } @@ -265,27 +265,27 @@ void fe_cswap(fe f,fe g,unsigned int b) { */ void fe_copy(fe h, const fe f) { - int32_t f0 = f[0]; - int32_t f1 = f[1]; - int32_t f2 = f[2]; - int32_t f3 = f[3]; - int32_t f4 = f[4]; - int32_t f5 = f[5]; - int32_t f6 = f[6]; - int32_t f7 = f[7]; - int32_t f8 = f[8]; - int32_t f9 = f[9]; - - h[0] = f0; - h[1] = f1; - h[2] = f2; - h[3] = f3; - h[4] = f4; - h[5] = f5; - h[6] = f6; - h[7] = f7; - h[8] = f8; - h[9] = f9; + int32_t f0 = f[0]; + int32_t f1 = f[1]; + int32_t f2 = f[2]; + int32_t f3 = f[3]; + int32_t f4 = f[4]; + int32_t f5 = f[5]; + int32_t f6 = f[6]; + int32_t f7 = f[7]; + int32_t f8 = f[8]; + int32_t f9 = f[9]; + + h[0] = f0; + h[1] = f1; + h[2] = f2; + h[3] = f3; + h[4] = f4; + h[5] = f5; + h[6] = f6; + h[7] = f7; + h[8] = f8; + h[9] = f9; } @@ -295,156 +295,156 @@ void fe_copy(fe h, const fe f) { */ void fe_frombytes(fe h, const unsigned char *s) { - int64_t h0 = load_4(s); - int64_t h1 = load_3(s + 4) << 6; - int64_t h2 = load_3(s + 7) << 5; - int64_t h3 = load_3(s + 10) << 3; - int64_t h4 = load_3(s + 13) << 2; - int64_t h5 = load_4(s + 16); - int64_t h6 = load_3(s + 20) << 7; - int64_t h7 = load_3(s + 23) << 5; - int64_t h8 = load_3(s + 26) << 4; - int64_t h9 = (load_3(s + 29) & 8388607) << 2; - int64_t carry0; - int64_t carry1; - int64_t carry2; - int64_t carry3; - int64_t carry4; - int64_t carry5; - int64_t carry6; - int64_t carry7; - int64_t carry8; - int64_t carry9; + int64_t h0 = load_4(s); + int64_t h1 = load_3(s + 4) << 6; + int64_t h2 = load_3(s + 7) << 5; + int64_t h3 = load_3(s + 10) << 3; + int64_t h4 = load_3(s + 13) << 2; + int64_t h5 = load_4(s + 16); + int64_t h6 = load_3(s + 20) << 7; + int64_t h7 = load_3(s + 23) << 5; + int64_t h8 = load_3(s + 26) << 4; + int64_t h9 = (load_3(s + 29) & 8388607) << 2; + int64_t carry0; + int64_t carry1; + int64_t carry2; + int64_t carry3; + int64_t carry4; + int64_t carry5; + int64_t carry6; + int64_t carry7; + int64_t carry8; + int64_t carry9; - carry9 = (h9 + (1L << 24)) >> 25; - h0 += carry9 * 19; - h9 -= shl64(carry9, 25); - carry1 = (h1 + (1L << 24)) >> 25; - h2 += carry1; - h1 -= shl64(carry1, 25); - carry3 = (h3 + (1L << 24)) >> 25; - h4 += carry3; - h3 -= shl64(carry3, 25); - carry5 = (h5 + (1L << 24)) >> 25; - h6 += carry5; - h5 -= shl64(carry5, 25); - carry7 = (h7 + (1L << 24)) >> 25; - h8 += carry7; - h7 -= shl64(carry7, 25); - carry0 = (h0 + (1L << 25)) >> 26; - h1 += carry0; - h0 -= shl64(carry0, 26); - carry2 = (h2 + (1L << 25)) >> 26; - h3 += carry2; - h2 -= shl64(carry2, 26); - carry4 = (h4 + (1L << 25)) >> 26; - h5 += carry4; - h4 -= shl64(carry4, 26); - carry6 = (h6 + (1L << 25)) >> 26; - h7 += carry6; - h6 -= shl64(carry6, 26); - carry8 = (h8 + (1L << 25)) >> 26; - h9 += carry8; - h8 -= shl64(carry8, 26); + carry9 = (h9 + (1L << 24)) >> 25; + h0 += carry9 * 19; + h9 -= shl64(carry9, 25); + carry1 = (h1 + (1L << 24)) >> 25; + h2 += carry1; + h1 -= shl64(carry1, 25); + carry3 = (h3 + (1L << 24)) >> 25; + h4 += carry3; + h3 -= shl64(carry3, 25); + carry5 = (h5 + (1L << 24)) >> 25; + h6 += carry5; + h5 -= shl64(carry5, 25); + carry7 = (h7 + (1L << 24)) >> 25; + h8 += carry7; + h7 -= shl64(carry7, 25); + carry0 = (h0 + (1L << 25)) >> 26; + h1 += carry0; + h0 -= shl64(carry0, 26); + carry2 = (h2 + (1L << 25)) >> 26; + h3 += carry2; + h2 -= shl64(carry2, 26); + carry4 = (h4 + (1L << 25)) >> 26; + h5 += carry4; + h4 -= shl64(carry4, 26); + carry6 = (h6 + (1L << 25)) >> 26; + h7 += carry6; + h6 -= shl64(carry6, 26); + carry8 = (h8 + (1L << 25)) >> 26; + h9 += carry8; + h8 -= shl64(carry8, 26); - h[0] = h0; - h[1] = h1; - h[2] = h2; - h[3] = h3; - h[4] = h4; - h[5] = h5; - h[6] = h6; - h[7] = h7; - h[8] = h8; - h[9] = h9; + h[0] = h0; + h[1] = h1; + h[2] = h2; + h[3] = h3; + h[4] = h4; + h[5] = h5; + h[6] = h6; + h[7] = h7; + h[8] = h8; + h[9] = h9; } void fe_invert(fe out, const fe z) { - fe t0; - fe t1; - fe t2; - fe t3; - int i; + fe t0; + fe t1; + fe t2; + fe t3; + int i; - fe_sq(t0, z); + fe_sq(t0, z); - for (i = 1; i < 1; ++i) { - fe_sq(t0, t0); - } + for(i = 1; i < 1; ++i) { + fe_sq(t0, t0); + } - fe_sq(t1, t0); + fe_sq(t1, t0); - for (i = 1; i < 2; ++i) { - fe_sq(t1, t1); - } + for(i = 1; i < 2; ++i) { + fe_sq(t1, t1); + } - fe_mul(t1, z, t1); - fe_mul(t0, t0, t1); - fe_sq(t2, t0); + fe_mul(t1, z, t1); + fe_mul(t0, t0, t1); + fe_sq(t2, t0); - for (i = 1; i < 1; ++i) { - fe_sq(t2, t2); - } + for(i = 1; i < 1; ++i) { + fe_sq(t2, t2); + } - fe_mul(t1, t1, t2); - fe_sq(t2, t1); + fe_mul(t1, t1, t2); + fe_sq(t2, t1); - for (i = 1; i < 5; ++i) { - fe_sq(t2, t2); - } + for(i = 1; i < 5; ++i) { + fe_sq(t2, t2); + } - fe_mul(t1, t2, t1); - fe_sq(t2, t1); + fe_mul(t1, t2, t1); + fe_sq(t2, t1); - for (i = 1; i < 10; ++i) { - fe_sq(t2, t2); - } + for(i = 1; i < 10; ++i) { + fe_sq(t2, t2); + } - fe_mul(t2, t2, t1); - fe_sq(t3, t2); + fe_mul(t2, t2, t1); + fe_sq(t3, t2); - for (i = 1; i < 20; ++i) { - fe_sq(t3, t3); - } + for(i = 1; i < 20; ++i) { + fe_sq(t3, t3); + } - fe_mul(t2, t3, t2); - fe_sq(t2, t2); + fe_mul(t2, t3, t2); + fe_sq(t2, t2); - for (i = 1; i < 10; ++i) { - fe_sq(t2, t2); - } + for(i = 1; i < 10; ++i) { + fe_sq(t2, t2); + } - fe_mul(t1, t2, t1); - fe_sq(t2, t1); + fe_mul(t1, t2, t1); + fe_sq(t2, t1); - for (i = 1; i < 50; ++i) { - fe_sq(t2, t2); - } + for(i = 1; i < 50; ++i) { + fe_sq(t2, t2); + } - fe_mul(t2, t2, t1); - fe_sq(t3, t2); + fe_mul(t2, t2, t1); + fe_sq(t3, t2); - for (i = 1; i < 100; ++i) { - fe_sq(t3, t3); - } + for(i = 1; i < 100; ++i) { + fe_sq(t3, t3); + } - fe_mul(t2, t3, t2); - fe_sq(t2, t2); + fe_mul(t2, t3, t2); + fe_sq(t2, t2); - for (i = 1; i < 50; ++i) { - fe_sq(t2, t2); - } + for(i = 1; i < 50; ++i) { + fe_sq(t2, t2); + } - fe_mul(t1, t2, t1); - fe_sq(t1, t1); + fe_mul(t1, t2, t1); + fe_sq(t1, t1); - for (i = 1; i < 5; ++i) { - fe_sq(t1, t1); - } + for(i = 1; i < 5; ++i) { + fe_sq(t1, t1); + } - fe_mul(out, t1, t0); + fe_mul(out, t1, t0); } @@ -458,11 +458,11 @@ void fe_invert(fe out, const fe z) { */ int fe_isnegative(const fe f) { - unsigned char s[32]; + unsigned char s[32]; - fe_tobytes(s, f); - - return s[0] & 1; + fe_tobytes(s, f); + + return s[0] & 1; } @@ -476,47 +476,47 @@ int fe_isnegative(const fe f) { */ int fe_isnonzero(const fe f) { - unsigned char s[32]; - unsigned char r; + unsigned char s[32]; + unsigned char r; - fe_tobytes(s, f); + fe_tobytes(s, f); - r = s[0]; - #define F(i) r |= s[i] - F(1); - F(2); - F(3); - F(4); - F(5); - F(6); - F(7); - F(8); - F(9); - F(10); - F(11); - F(12); - F(13); - F(14); - F(15); - F(16); - F(17); - F(18); - F(19); - F(20); - F(21); - F(22); - F(23); - F(24); - F(25); - F(26); - F(27); - F(28); - F(29); - F(30); - F(31); - #undef F + r = s[0]; +#define F(i) r |= s[i] + F(1); + F(2); + F(3); + F(4); + F(5); + F(6); + F(7); + F(8); + F(9); + F(10); + F(11); + F(12); + F(13); + F(14); + F(15); + F(16); + F(17); + F(18); + F(19); + F(20); + F(21); + F(22); + F(23); + F(24); + F(25); + F(26); + F(27); + F(28); + F(29); + F(30); + F(31); +#undef F - return r != 0; + return r != 0; } @@ -533,235 +533,235 @@ int fe_isnonzero(const fe f) { |h| bounded by 1.01*2^25,1.01*2^24,1.01*2^25,1.01*2^24,etc. */ - /* - Notes on implementation strategy: +/* +Notes on implementation strategy: - Using schoolbook multiplication. - Karatsuba would save a little in some cost models. +Using schoolbook multiplication. +Karatsuba would save a little in some cost models. - Most multiplications by 2 and 19 are 32-bit precomputations; - cheaper than 64-bit postcomputations. +Most multiplications by 2 and 19 are 32-bit precomputations; +cheaper than 64-bit postcomputations. - There is one remaining multiplication by 19 in the carry chain; - one *19 precomputation can be merged into this, - but the resulting data flow is considerably less clean. +There is one remaining multiplication by 19 in the carry chain; +one *19 precomputation can be merged into this, +but the resulting data flow is considerably less clean. - There are 12 carries below. - 10 of them are 2-way parallelizable and vectorizable. - Can get away with 11 carries, but then data flow is much deeper. +There are 12 carries below. +10 of them are 2-way parallelizable and vectorizable. +Can get away with 11 carries, but then data flow is much deeper. - With tighter constraints on inputs can squeeze carries into int32. +With tighter constraints on inputs can squeeze carries into int32. */ void fe_mul(fe h, const fe f, const fe g) { - int32_t f0 = f[0]; - int32_t f1 = f[1]; - int32_t f2 = f[2]; - int32_t f3 = f[3]; - int32_t f4 = f[4]; - int32_t f5 = f[5]; - int32_t f6 = f[6]; - int32_t f7 = f[7]; - int32_t f8 = f[8]; - int32_t f9 = f[9]; - int32_t g0 = g[0]; - int32_t g1 = g[1]; - int32_t g2 = g[2]; - int32_t g3 = g[3]; - int32_t g4 = g[4]; - int32_t g5 = g[5]; - int32_t g6 = g[6]; - int32_t g7 = g[7]; - int32_t g8 = g[8]; - int32_t g9 = g[9]; - int32_t g1_19 = 19 * g1; /* 1.959375*2^29 */ - int32_t g2_19 = 19 * g2; /* 1.959375*2^30; still ok */ - int32_t g3_19 = 19 * g3; - int32_t g4_19 = 19 * g4; - int32_t g5_19 = 19 * g5; - int32_t g6_19 = 19 * g6; - int32_t g7_19 = 19 * g7; - int32_t g8_19 = 19 * g8; - int32_t g9_19 = 19 * g9; - int32_t f1_2 = 2 * f1; - int32_t f3_2 = 2 * f3; - int32_t f5_2 = 2 * f5; - int32_t f7_2 = 2 * f7; - int32_t f9_2 = 2 * f9; - int64_t f0g0 = f0 * (int64_t) g0; - int64_t f0g1 = f0 * (int64_t) g1; - int64_t f0g2 = f0 * (int64_t) g2; - int64_t f0g3 = f0 * (int64_t) g3; - int64_t f0g4 = f0 * (int64_t) g4; - int64_t f0g5 = f0 * (int64_t) g5; - int64_t f0g6 = f0 * (int64_t) g6; - int64_t f0g7 = f0 * (int64_t) g7; - int64_t f0g8 = f0 * (int64_t) g8; - int64_t f0g9 = f0 * (int64_t) g9; - int64_t f1g0 = f1 * (int64_t) g0; - int64_t f1g1_2 = f1_2 * (int64_t) g1; - int64_t f1g2 = f1 * (int64_t) g2; - int64_t f1g3_2 = f1_2 * (int64_t) g3; - int64_t f1g4 = f1 * (int64_t) g4; - int64_t f1g5_2 = f1_2 * (int64_t) g5; - int64_t f1g6 = f1 * (int64_t) g6; - int64_t f1g7_2 = f1_2 * (int64_t) g7; - int64_t f1g8 = f1 * (int64_t) g8; - int64_t f1g9_38 = f1_2 * (int64_t) g9_19; - int64_t f2g0 = f2 * (int64_t) g0; - int64_t f2g1 = f2 * (int64_t) g1; - int64_t f2g2 = f2 * (int64_t) g2; - int64_t f2g3 = f2 * (int64_t) g3; - int64_t f2g4 = f2 * (int64_t) g4; - int64_t f2g5 = f2 * (int64_t) g5; - int64_t f2g6 = f2 * (int64_t) g6; - int64_t f2g7 = f2 * (int64_t) g7; - int64_t f2g8_19 = f2 * (int64_t) g8_19; - int64_t f2g9_19 = f2 * (int64_t) g9_19; - int64_t f3g0 = f3 * (int64_t) g0; - int64_t f3g1_2 = f3_2 * (int64_t) g1; - int64_t f3g2 = f3 * (int64_t) g2; - int64_t f3g3_2 = f3_2 * (int64_t) g3; - int64_t f3g4 = f3 * (int64_t) g4; - int64_t f3g5_2 = f3_2 * (int64_t) g5; - int64_t f3g6 = f3 * (int64_t) g6; - int64_t f3g7_38 = f3_2 * (int64_t) g7_19; - int64_t f3g8_19 = f3 * (int64_t) g8_19; - int64_t f3g9_38 = f3_2 * (int64_t) g9_19; - int64_t f4g0 = f4 * (int64_t) g0; - int64_t f4g1 = f4 * (int64_t) g1; - int64_t f4g2 = f4 * (int64_t) g2; - int64_t f4g3 = f4 * (int64_t) g3; - int64_t f4g4 = f4 * (int64_t) g4; - int64_t f4g5 = f4 * (int64_t) g5; - int64_t f4g6_19 = f4 * (int64_t) g6_19; - int64_t f4g7_19 = f4 * (int64_t) g7_19; - int64_t f4g8_19 = f4 * (int64_t) g8_19; - int64_t f4g9_19 = f4 * (int64_t) g9_19; - int64_t f5g0 = f5 * (int64_t) g0; - int64_t f5g1_2 = f5_2 * (int64_t) g1; - int64_t f5g2 = f5 * (int64_t) g2; - int64_t f5g3_2 = f5_2 * (int64_t) g3; - int64_t f5g4 = f5 * (int64_t) g4; - int64_t f5g5_38 = f5_2 * (int64_t) g5_19; - int64_t f5g6_19 = f5 * (int64_t) g6_19; - int64_t f5g7_38 = f5_2 * (int64_t) g7_19; - int64_t f5g8_19 = f5 * (int64_t) g8_19; - int64_t f5g9_38 = f5_2 * (int64_t) g9_19; - int64_t f6g0 = f6 * (int64_t) g0; - int64_t f6g1 = f6 * (int64_t) g1; - int64_t f6g2 = f6 * (int64_t) g2; - int64_t f6g3 = f6 * (int64_t) g3; - int64_t f6g4_19 = f6 * (int64_t) g4_19; - int64_t f6g5_19 = f6 * (int64_t) g5_19; - int64_t f6g6_19 = f6 * (int64_t) g6_19; - int64_t f6g7_19 = f6 * (int64_t) g7_19; - int64_t f6g8_19 = f6 * (int64_t) g8_19; - int64_t f6g9_19 = f6 * (int64_t) g9_19; - int64_t f7g0 = f7 * (int64_t) g0; - int64_t f7g1_2 = f7_2 * (int64_t) g1; - int64_t f7g2 = f7 * (int64_t) g2; - int64_t f7g3_38 = f7_2 * (int64_t) g3_19; - int64_t f7g4_19 = f7 * (int64_t) g4_19; - int64_t f7g5_38 = f7_2 * (int64_t) g5_19; - int64_t f7g6_19 = f7 * (int64_t) g6_19; - int64_t f7g7_38 = f7_2 * (int64_t) g7_19; - int64_t f7g8_19 = f7 * (int64_t) g8_19; - int64_t f7g9_38 = f7_2 * (int64_t) g9_19; - int64_t f8g0 = f8 * (int64_t) g0; - int64_t f8g1 = f8 * (int64_t) g1; - int64_t f8g2_19 = f8 * (int64_t) g2_19; - int64_t f8g3_19 = f8 * (int64_t) g3_19; - int64_t f8g4_19 = f8 * (int64_t) g4_19; - int64_t f8g5_19 = f8 * (int64_t) g5_19; - int64_t f8g6_19 = f8 * (int64_t) g6_19; - int64_t f8g7_19 = f8 * (int64_t) g7_19; - int64_t f8g8_19 = f8 * (int64_t) g8_19; - int64_t f8g9_19 = f8 * (int64_t) g9_19; - int64_t f9g0 = f9 * (int64_t) g0; - int64_t f9g1_38 = f9_2 * (int64_t) g1_19; - int64_t f9g2_19 = f9 * (int64_t) g2_19; - int64_t f9g3_38 = f9_2 * (int64_t) g3_19; - int64_t f9g4_19 = f9 * (int64_t) g4_19; - int64_t f9g5_38 = f9_2 * (int64_t) g5_19; - int64_t f9g6_19 = f9 * (int64_t) g6_19; - int64_t f9g7_38 = f9_2 * (int64_t) g7_19; - int64_t f9g8_19 = f9 * (int64_t) g8_19; - int64_t f9g9_38 = f9_2 * (int64_t) g9_19; - int64_t h0 = f0g0 + f1g9_38 + f2g8_19 + f3g7_38 + f4g6_19 + f5g5_38 + f6g4_19 + f7g3_38 + f8g2_19 + f9g1_38; - int64_t h1 = f0g1 + f1g0 + f2g9_19 + f3g8_19 + f4g7_19 + f5g6_19 + f6g5_19 + f7g4_19 + f8g3_19 + f9g2_19; - int64_t h2 = f0g2 + f1g1_2 + f2g0 + f3g9_38 + f4g8_19 + f5g7_38 + f6g6_19 + f7g5_38 + f8g4_19 + f9g3_38; - int64_t h3 = f0g3 + f1g2 + f2g1 + f3g0 + f4g9_19 + f5g8_19 + f6g7_19 + f7g6_19 + f8g5_19 + f9g4_19; - int64_t h4 = f0g4 + f1g3_2 + f2g2 + f3g1_2 + f4g0 + f5g9_38 + f6g8_19 + f7g7_38 + f8g6_19 + f9g5_38; - int64_t h5 = f0g5 + f1g4 + f2g3 + f3g2 + f4g1 + f5g0 + f6g9_19 + f7g8_19 + f8g7_19 + f9g6_19; - int64_t h6 = f0g6 + f1g5_2 + f2g4 + f3g3_2 + f4g2 + f5g1_2 + f6g0 + f7g9_38 + f8g8_19 + f9g7_38; - int64_t h7 = f0g7 + f1g6 + f2g5 + f3g4 + f4g3 + f5g2 + f6g1 + f7g0 + f8g9_19 + f9g8_19; - int64_t h8 = f0g8 + f1g7_2 + f2g6 + f3g5_2 + f4g4 + f5g3_2 + f6g2 + f7g1_2 + f8g0 + f9g9_38; - int64_t h9 = f0g9 + f1g8 + f2g7 + f3g6 + f4g5 + f5g4 + f6g3 + f7g2 + f8g1 + f9g0 ; - int64_t carry0; - int64_t carry1; - int64_t carry2; - int64_t carry3; - int64_t carry4; - int64_t carry5; - int64_t carry6; - int64_t carry7; - int64_t carry8; - int64_t carry9; + int32_t f0 = f[0]; + int32_t f1 = f[1]; + int32_t f2 = f[2]; + int32_t f3 = f[3]; + int32_t f4 = f[4]; + int32_t f5 = f[5]; + int32_t f6 = f[6]; + int32_t f7 = f[7]; + int32_t f8 = f[8]; + int32_t f9 = f[9]; + int32_t g0 = g[0]; + int32_t g1 = g[1]; + int32_t g2 = g[2]; + int32_t g3 = g[3]; + int32_t g4 = g[4]; + int32_t g5 = g[5]; + int32_t g6 = g[6]; + int32_t g7 = g[7]; + int32_t g8 = g[8]; + int32_t g9 = g[9]; + int32_t g1_19 = 19 * g1; /* 1.959375*2^29 */ + int32_t g2_19 = 19 * g2; /* 1.959375*2^30; still ok */ + int32_t g3_19 = 19 * g3; + int32_t g4_19 = 19 * g4; + int32_t g5_19 = 19 * g5; + int32_t g6_19 = 19 * g6; + int32_t g7_19 = 19 * g7; + int32_t g8_19 = 19 * g8; + int32_t g9_19 = 19 * g9; + int32_t f1_2 = 2 * f1; + int32_t f3_2 = 2 * f3; + int32_t f5_2 = 2 * f5; + int32_t f7_2 = 2 * f7; + int32_t f9_2 = 2 * f9; + int64_t f0g0 = f0 * (int64_t) g0; + int64_t f0g1 = f0 * (int64_t) g1; + int64_t f0g2 = f0 * (int64_t) g2; + int64_t f0g3 = f0 * (int64_t) g3; + int64_t f0g4 = f0 * (int64_t) g4; + int64_t f0g5 = f0 * (int64_t) g5; + int64_t f0g6 = f0 * (int64_t) g6; + int64_t f0g7 = f0 * (int64_t) g7; + int64_t f0g8 = f0 * (int64_t) g8; + int64_t f0g9 = f0 * (int64_t) g9; + int64_t f1g0 = f1 * (int64_t) g0; + int64_t f1g1_2 = f1_2 * (int64_t) g1; + int64_t f1g2 = f1 * (int64_t) g2; + int64_t f1g3_2 = f1_2 * (int64_t) g3; + int64_t f1g4 = f1 * (int64_t) g4; + int64_t f1g5_2 = f1_2 * (int64_t) g5; + int64_t f1g6 = f1 * (int64_t) g6; + int64_t f1g7_2 = f1_2 * (int64_t) g7; + int64_t f1g8 = f1 * (int64_t) g8; + int64_t f1g9_38 = f1_2 * (int64_t) g9_19; + int64_t f2g0 = f2 * (int64_t) g0; + int64_t f2g1 = f2 * (int64_t) g1; + int64_t f2g2 = f2 * (int64_t) g2; + int64_t f2g3 = f2 * (int64_t) g3; + int64_t f2g4 = f2 * (int64_t) g4; + int64_t f2g5 = f2 * (int64_t) g5; + int64_t f2g6 = f2 * (int64_t) g6; + int64_t f2g7 = f2 * (int64_t) g7; + int64_t f2g8_19 = f2 * (int64_t) g8_19; + int64_t f2g9_19 = f2 * (int64_t) g9_19; + int64_t f3g0 = f3 * (int64_t) g0; + int64_t f3g1_2 = f3_2 * (int64_t) g1; + int64_t f3g2 = f3 * (int64_t) g2; + int64_t f3g3_2 = f3_2 * (int64_t) g3; + int64_t f3g4 = f3 * (int64_t) g4; + int64_t f3g5_2 = f3_2 * (int64_t) g5; + int64_t f3g6 = f3 * (int64_t) g6; + int64_t f3g7_38 = f3_2 * (int64_t) g7_19; + int64_t f3g8_19 = f3 * (int64_t) g8_19; + int64_t f3g9_38 = f3_2 * (int64_t) g9_19; + int64_t f4g0 = f4 * (int64_t) g0; + int64_t f4g1 = f4 * (int64_t) g1; + int64_t f4g2 = f4 * (int64_t) g2; + int64_t f4g3 = f4 * (int64_t) g3; + int64_t f4g4 = f4 * (int64_t) g4; + int64_t f4g5 = f4 * (int64_t) g5; + int64_t f4g6_19 = f4 * (int64_t) g6_19; + int64_t f4g7_19 = f4 * (int64_t) g7_19; + int64_t f4g8_19 = f4 * (int64_t) g8_19; + int64_t f4g9_19 = f4 * (int64_t) g9_19; + int64_t f5g0 = f5 * (int64_t) g0; + int64_t f5g1_2 = f5_2 * (int64_t) g1; + int64_t f5g2 = f5 * (int64_t) g2; + int64_t f5g3_2 = f5_2 * (int64_t) g3; + int64_t f5g4 = f5 * (int64_t) g4; + int64_t f5g5_38 = f5_2 * (int64_t) g5_19; + int64_t f5g6_19 = f5 * (int64_t) g6_19; + int64_t f5g7_38 = f5_2 * (int64_t) g7_19; + int64_t f5g8_19 = f5 * (int64_t) g8_19; + int64_t f5g9_38 = f5_2 * (int64_t) g9_19; + int64_t f6g0 = f6 * (int64_t) g0; + int64_t f6g1 = f6 * (int64_t) g1; + int64_t f6g2 = f6 * (int64_t) g2; + int64_t f6g3 = f6 * (int64_t) g3; + int64_t f6g4_19 = f6 * (int64_t) g4_19; + int64_t f6g5_19 = f6 * (int64_t) g5_19; + int64_t f6g6_19 = f6 * (int64_t) g6_19; + int64_t f6g7_19 = f6 * (int64_t) g7_19; + int64_t f6g8_19 = f6 * (int64_t) g8_19; + int64_t f6g9_19 = f6 * (int64_t) g9_19; + int64_t f7g0 = f7 * (int64_t) g0; + int64_t f7g1_2 = f7_2 * (int64_t) g1; + int64_t f7g2 = f7 * (int64_t) g2; + int64_t f7g3_38 = f7_2 * (int64_t) g3_19; + int64_t f7g4_19 = f7 * (int64_t) g4_19; + int64_t f7g5_38 = f7_2 * (int64_t) g5_19; + int64_t f7g6_19 = f7 * (int64_t) g6_19; + int64_t f7g7_38 = f7_2 * (int64_t) g7_19; + int64_t f7g8_19 = f7 * (int64_t) g8_19; + int64_t f7g9_38 = f7_2 * (int64_t) g9_19; + int64_t f8g0 = f8 * (int64_t) g0; + int64_t f8g1 = f8 * (int64_t) g1; + int64_t f8g2_19 = f8 * (int64_t) g2_19; + int64_t f8g3_19 = f8 * (int64_t) g3_19; + int64_t f8g4_19 = f8 * (int64_t) g4_19; + int64_t f8g5_19 = f8 * (int64_t) g5_19; + int64_t f8g6_19 = f8 * (int64_t) g6_19; + int64_t f8g7_19 = f8 * (int64_t) g7_19; + int64_t f8g8_19 = f8 * (int64_t) g8_19; + int64_t f8g9_19 = f8 * (int64_t) g9_19; + int64_t f9g0 = f9 * (int64_t) g0; + int64_t f9g1_38 = f9_2 * (int64_t) g1_19; + int64_t f9g2_19 = f9 * (int64_t) g2_19; + int64_t f9g3_38 = f9_2 * (int64_t) g3_19; + int64_t f9g4_19 = f9 * (int64_t) g4_19; + int64_t f9g5_38 = f9_2 * (int64_t) g5_19; + int64_t f9g6_19 = f9 * (int64_t) g6_19; + int64_t f9g7_38 = f9_2 * (int64_t) g7_19; + int64_t f9g8_19 = f9 * (int64_t) g8_19; + int64_t f9g9_38 = f9_2 * (int64_t) g9_19; + int64_t h0 = f0g0 + f1g9_38 + f2g8_19 + f3g7_38 + f4g6_19 + f5g5_38 + f6g4_19 + f7g3_38 + f8g2_19 + f9g1_38; + int64_t h1 = f0g1 + f1g0 + f2g9_19 + f3g8_19 + f4g7_19 + f5g6_19 + f6g5_19 + f7g4_19 + f8g3_19 + f9g2_19; + int64_t h2 = f0g2 + f1g1_2 + f2g0 + f3g9_38 + f4g8_19 + f5g7_38 + f6g6_19 + f7g5_38 + f8g4_19 + f9g3_38; + int64_t h3 = f0g3 + f1g2 + f2g1 + f3g0 + f4g9_19 + f5g8_19 + f6g7_19 + f7g6_19 + f8g5_19 + f9g4_19; + int64_t h4 = f0g4 + f1g3_2 + f2g2 + f3g1_2 + f4g0 + f5g9_38 + f6g8_19 + f7g7_38 + f8g6_19 + f9g5_38; + int64_t h5 = f0g5 + f1g4 + f2g3 + f3g2 + f4g1 + f5g0 + f6g9_19 + f7g8_19 + f8g7_19 + f9g6_19; + int64_t h6 = f0g6 + f1g5_2 + f2g4 + f3g3_2 + f4g2 + f5g1_2 + f6g0 + f7g9_38 + f8g8_19 + f9g7_38; + int64_t h7 = f0g7 + f1g6 + f2g5 + f3g4 + f4g3 + f5g2 + f6g1 + f7g0 + f8g9_19 + f9g8_19; + int64_t h8 = f0g8 + f1g7_2 + f2g6 + f3g5_2 + f4g4 + f5g3_2 + f6g2 + f7g1_2 + f8g0 + f9g9_38; + int64_t h9 = f0g9 + f1g8 + f2g7 + f3g6 + f4g5 + f5g4 + f6g3 + f7g2 + f8g1 + f9g0 ; + int64_t carry0; + int64_t carry1; + int64_t carry2; + int64_t carry3; + int64_t carry4; + int64_t carry5; + int64_t carry6; + int64_t carry7; + int64_t carry8; + int64_t carry9; - carry0 = (h0 + (1L << 25)) >> 26; - h1 += carry0; - h0 -= shl64(carry0, 26); - carry4 = (h4 + (1L << 25)) >> 26; - h5 += carry4; - h4 -= shl64(carry4, 26); + carry0 = (h0 + (1L << 25)) >> 26; + h1 += carry0; + h0 -= shl64(carry0, 26); + carry4 = (h4 + (1L << 25)) >> 26; + h5 += carry4; + h4 -= shl64(carry4, 26); - carry1 = (h1 + (1L << 24)) >> 25; - h2 += carry1; - h1 -= shl64(carry1, 25); - carry5 = (h5 + (1L << 24)) >> 25; - h6 += carry5; - h5 -= shl64(carry5, 25); + carry1 = (h1 + (1L << 24)) >> 25; + h2 += carry1; + h1 -= shl64(carry1, 25); + carry5 = (h5 + (1L << 24)) >> 25; + h6 += carry5; + h5 -= shl64(carry5, 25); - carry2 = (h2 + (1L << 25)) >> 26; - h3 += carry2; - h2 -= shl64(carry2, 26); - carry6 = (h6 + (1L << 25)) >> 26; - h7 += carry6; - h6 -= shl64(carry6, 26); + carry2 = (h2 + (1L << 25)) >> 26; + h3 += carry2; + h2 -= shl64(carry2, 26); + carry6 = (h6 + (1L << 25)) >> 26; + h7 += carry6; + h6 -= shl64(carry6, 26); - carry3 = (h3 + (1L << 24)) >> 25; - h4 += carry3; - h3 -= shl64(carry3, 25); - carry7 = (h7 + (1L << 24)) >> 25; - h8 += carry7; - h7 -= shl64(carry7, 25); + carry3 = (h3 + (1L << 24)) >> 25; + h4 += carry3; + h3 -= shl64(carry3, 25); + carry7 = (h7 + (1L << 24)) >> 25; + h8 += carry7; + h7 -= shl64(carry7, 25); - carry4 = (h4 + (1L << 25)) >> 26; - h5 += carry4; - h4 -= shl64(carry4, 26); - carry8 = (h8 + (1L << 25)) >> 26; - h9 += carry8; - h8 -= shl64(carry8, 26); + carry4 = (h4 + (1L << 25)) >> 26; + h5 += carry4; + h4 -= shl64(carry4, 26); + carry8 = (h8 + (1L << 25)) >> 26; + h9 += carry8; + h8 -= shl64(carry8, 26); - carry9 = (h9 + (1L << 24)) >> 25; - h0 += carry9 * 19; - h9 -= shl64(carry9, 25); + carry9 = (h9 + (1L << 24)) >> 25; + h0 += carry9 * 19; + h9 -= shl64(carry9, 25); - carry0 = (h0 + (1L << 25)) >> 26; - h1 += carry0; - h0 -= shl64(carry0, 26); + carry0 = (h0 + (1L << 25)) >> 26; + h1 += carry0; + h0 -= shl64(carry0, 26); - h[0] = (int32_t) h0; - h[1] = (int32_t) h1; - h[2] = (int32_t) h2; - h[3] = (int32_t) h3; - h[4] = (int32_t) h4; - h[5] = (int32_t) h5; - h[6] = (int32_t) h6; - h[7] = (int32_t) h7; - h[8] = (int32_t) h8; - h[9] = (int32_t) h9; + h[0] = (int32_t) h0; + h[1] = (int32_t) h1; + h[2] = (int32_t) h2; + h[3] = (int32_t) h3; + h[4] = (int32_t) h4; + h[5] = (int32_t) h5; + h[6] = (int32_t) h6; + h[7] = (int32_t) h7; + h[8] = (int32_t) h8; + h[9] = (int32_t) h9; } @@ -777,59 +777,79 @@ Postconditions: */ void fe_mul121666(fe h, fe f) { - int32_t f0 = f[0]; - int32_t f1 = f[1]; - int32_t f2 = f[2]; - int32_t f3 = f[3]; - int32_t f4 = f[4]; - int32_t f5 = f[5]; - int32_t f6 = f[6]; - int32_t f7 = f[7]; - int32_t f8 = f[8]; - int32_t f9 = f[9]; - int64_t h0 = f0 * (int64_t) 121666; - int64_t h1 = f1 * (int64_t) 121666; - int64_t h2 = f2 * (int64_t) 121666; - int64_t h3 = f3 * (int64_t) 121666; - int64_t h4 = f4 * (int64_t) 121666; - int64_t h5 = f5 * (int64_t) 121666; - int64_t h6 = f6 * (int64_t) 121666; - int64_t h7 = f7 * (int64_t) 121666; - int64_t h8 = f8 * (int64_t) 121666; - int64_t h9 = f9 * (int64_t) 121666; - int64_t carry0; - int64_t carry1; - int64_t carry2; - int64_t carry3; - int64_t carry4; - int64_t carry5; - int64_t carry6; - int64_t carry7; - int64_t carry8; - int64_t carry9; + int32_t f0 = f[0]; + int32_t f1 = f[1]; + int32_t f2 = f[2]; + int32_t f3 = f[3]; + int32_t f4 = f[4]; + int32_t f5 = f[5]; + int32_t f6 = f[6]; + int32_t f7 = f[7]; + int32_t f8 = f[8]; + int32_t f9 = f[9]; + int64_t h0 = f0 * (int64_t) 121666; + int64_t h1 = f1 * (int64_t) 121666; + int64_t h2 = f2 * (int64_t) 121666; + int64_t h3 = f3 * (int64_t) 121666; + int64_t h4 = f4 * (int64_t) 121666; + int64_t h5 = f5 * (int64_t) 121666; + int64_t h6 = f6 * (int64_t) 121666; + int64_t h7 = f7 * (int64_t) 121666; + int64_t h8 = f8 * (int64_t) 121666; + int64_t h9 = f9 * (int64_t) 121666; + int64_t carry0; + int64_t carry1; + int64_t carry2; + int64_t carry3; + int64_t carry4; + int64_t carry5; + int64_t carry6; + int64_t carry7; + int64_t carry8; + int64_t carry9; - carry9 = (h9 + (int64_t) (1<<24)) >> 25; h0 += carry9 * 19; h9 -= shl64(carry9, 25); - carry1 = (h1 + (int64_t) (1<<24)) >> 25; h2 += carry1; h1 -= shl64(carry1, 25); - carry3 = (h3 + (int64_t) (1<<24)) >> 25; h4 += carry3; h3 -= shl64(carry3, 25); - carry5 = (h5 + (int64_t) (1<<24)) >> 25; h6 += carry5; h5 -= shl64(carry5, 25); - carry7 = (h7 + (int64_t) (1<<24)) >> 25; h8 += carry7; h7 -= shl64(carry7, 25); + carry9 = (h9 + (int64_t)(1 << 24)) >> 25; + h0 += carry9 * 19; + h9 -= shl64(carry9, 25); + carry1 = (h1 + (int64_t)(1 << 24)) >> 25; + h2 += carry1; + h1 -= shl64(carry1, 25); + carry3 = (h3 + (int64_t)(1 << 24)) >> 25; + h4 += carry3; + h3 -= shl64(carry3, 25); + carry5 = (h5 + (int64_t)(1 << 24)) >> 25; + h6 += carry5; + h5 -= shl64(carry5, 25); + carry7 = (h7 + (int64_t)(1 << 24)) >> 25; + h8 += carry7; + h7 -= shl64(carry7, 25); - carry0 = (h0 + (int64_t) (1<<25)) >> 26; h1 += carry0; h0 -= shl64(carry0, 26); - carry2 = (h2 + (int64_t) (1<<25)) >> 26; h3 += carry2; h2 -= shl64(carry2, 26); - carry4 = (h4 + (int64_t) (1<<25)) >> 26; h5 += carry4; h4 -= shl64(carry4, 26); - carry6 = (h6 + (int64_t) (1<<25)) >> 26; h7 += carry6; h6 -= shl64(carry6, 26); - carry8 = (h8 + (int64_t) (1<<25)) >> 26; h9 += carry8; h8 -= shl64(carry8, 26); + carry0 = (h0 + (int64_t)(1 << 25)) >> 26; + h1 += carry0; + h0 -= shl64(carry0, 26); + carry2 = (h2 + (int64_t)(1 << 25)) >> 26; + h3 += carry2; + h2 -= shl64(carry2, 26); + carry4 = (h4 + (int64_t)(1 << 25)) >> 26; + h5 += carry4; + h4 -= shl64(carry4, 26); + carry6 = (h6 + (int64_t)(1 << 25)) >> 26; + h7 += carry6; + h6 -= shl64(carry6, 26); + carry8 = (h8 + (int64_t)(1 << 25)) >> 26; + h9 += carry8; + h8 -= shl64(carry8, 26); - h[0] = h0; - h[1] = h1; - h[2] = h2; - h[3] = h3; - h[4] = h4; - h[5] = h5; - h[6] = h6; - h[7] = h7; - h[8] = h8; - h[9] = h9; + h[0] = h0; + h[1] = h1; + h[2] = h2; + h[3] = h3; + h[4] = h4; + h[5] = h5; + h[6] = h6; + h[7] = h7; + h[8] = h8; + h[9] = h9; } @@ -844,123 +864,123 @@ Postconditions: */ void fe_neg(fe h, const fe f) { - int32_t f0 = f[0]; - int32_t f1 = f[1]; - int32_t f2 = f[2]; - int32_t f3 = f[3]; - int32_t f4 = f[4]; - int32_t f5 = f[5]; - int32_t f6 = f[6]; - int32_t f7 = f[7]; - int32_t f8 = f[8]; - int32_t f9 = f[9]; - int32_t h0 = -f0; - int32_t h1 = -f1; - int32_t h2 = -f2; - int32_t h3 = -f3; - int32_t h4 = -f4; - int32_t h5 = -f5; - int32_t h6 = -f6; - int32_t h7 = -f7; - int32_t h8 = -f8; - int32_t h9 = -f9; + int32_t f0 = f[0]; + int32_t f1 = f[1]; + int32_t f2 = f[2]; + int32_t f3 = f[3]; + int32_t f4 = f[4]; + int32_t f5 = f[5]; + int32_t f6 = f[6]; + int32_t f7 = f[7]; + int32_t f8 = f[8]; + int32_t f9 = f[9]; + int32_t h0 = -f0; + int32_t h1 = -f1; + int32_t h2 = -f2; + int32_t h3 = -f3; + int32_t h4 = -f4; + int32_t h5 = -f5; + int32_t h6 = -f6; + int32_t h7 = -f7; + int32_t h8 = -f8; + int32_t h9 = -f9; - h[0] = h0; - h[1] = h1; - h[2] = h2; - h[3] = h3; - h[4] = h4; - h[5] = h5; - h[6] = h6; - h[7] = h7; - h[8] = h8; - h[9] = h9; + h[0] = h0; + h[1] = h1; + h[2] = h2; + h[3] = h3; + h[4] = h4; + h[5] = h5; + h[6] = h6; + h[7] = h7; + h[8] = h8; + h[9] = h9; } void fe_pow22523(fe out, const fe z) { - fe t0; - fe t1; - fe t2; - int i; - fe_sq(t0, z); + fe t0; + fe t1; + fe t2; + int i; + fe_sq(t0, z); - for (i = 1; i < 1; ++i) { - fe_sq(t0, t0); - } + for(i = 1; i < 1; ++i) { + fe_sq(t0, t0); + } - fe_sq(t1, t0); + fe_sq(t1, t0); - for (i = 1; i < 2; ++i) { - fe_sq(t1, t1); - } + for(i = 1; i < 2; ++i) { + fe_sq(t1, t1); + } - fe_mul(t1, z, t1); - fe_mul(t0, t0, t1); - fe_sq(t0, t0); + fe_mul(t1, z, t1); + fe_mul(t0, t0, t1); + fe_sq(t0, t0); - for (i = 1; i < 1; ++i) { - fe_sq(t0, t0); - } + for(i = 1; i < 1; ++i) { + fe_sq(t0, t0); + } - fe_mul(t0, t1, t0); - fe_sq(t1, t0); + fe_mul(t0, t1, t0); + fe_sq(t1, t0); - for (i = 1; i < 5; ++i) { - fe_sq(t1, t1); - } + for(i = 1; i < 5; ++i) { + fe_sq(t1, t1); + } - fe_mul(t0, t1, t0); - fe_sq(t1, t0); + fe_mul(t0, t1, t0); + fe_sq(t1, t0); - for (i = 1; i < 10; ++i) { - fe_sq(t1, t1); - } + for(i = 1; i < 10; ++i) { + fe_sq(t1, t1); + } - fe_mul(t1, t1, t0); - fe_sq(t2, t1); + fe_mul(t1, t1, t0); + fe_sq(t2, t1); - for (i = 1; i < 20; ++i) { - fe_sq(t2, t2); - } + for(i = 1; i < 20; ++i) { + fe_sq(t2, t2); + } - fe_mul(t1, t2, t1); - fe_sq(t1, t1); + fe_mul(t1, t2, t1); + fe_sq(t1, t1); - for (i = 1; i < 10; ++i) { - fe_sq(t1, t1); - } + for(i = 1; i < 10; ++i) { + fe_sq(t1, t1); + } - fe_mul(t0, t1, t0); - fe_sq(t1, t0); + fe_mul(t0, t1, t0); + fe_sq(t1, t0); - for (i = 1; i < 50; ++i) { - fe_sq(t1, t1); - } + for(i = 1; i < 50; ++i) { + fe_sq(t1, t1); + } - fe_mul(t1, t1, t0); - fe_sq(t2, t1); + fe_mul(t1, t1, t0); + fe_sq(t2, t1); - for (i = 1; i < 100; ++i) { - fe_sq(t2, t2); - } + for(i = 1; i < 100; ++i) { + fe_sq(t2, t2); + } - fe_mul(t1, t2, t1); - fe_sq(t1, t1); + fe_mul(t1, t2, t1); + fe_sq(t1, t1); - for (i = 1; i < 50; ++i) { - fe_sq(t1, t1); - } + for(i = 1; i < 50; ++i) { + fe_sq(t1, t1); + } - fe_mul(t0, t1, t0); - fe_sq(t0, t0); + fe_mul(t0, t1, t0); + fe_sq(t0, t0); - for (i = 1; i < 2; ++i) { - fe_sq(t0, t0); - } + for(i = 1; i < 2; ++i) { + fe_sq(t0, t0); + } - fe_mul(out, t0, z); - return; + fe_mul(out, t0, z); + return; } @@ -980,150 +1000,150 @@ See fe_mul.c for discussion of implementation strategy. */ void fe_sq(fe h, const fe f) { - int32_t f0 = f[0]; - int32_t f1 = f[1]; - int32_t f2 = f[2]; - int32_t f3 = f[3]; - int32_t f4 = f[4]; - int32_t f5 = f[5]; - int32_t f6 = f[6]; - int32_t f7 = f[7]; - int32_t f8 = f[8]; - int32_t f9 = f[9]; - int32_t f0_2 = 2 * f0; - int32_t f1_2 = 2 * f1; - int32_t f2_2 = 2 * f2; - int32_t f3_2 = 2 * f3; - int32_t f4_2 = 2 * f4; - int32_t f5_2 = 2 * f5; - int32_t f6_2 = 2 * f6; - int32_t f7_2 = 2 * f7; - int32_t f5_38 = 38 * f5; /* 1.959375*2^30 */ - int32_t f6_19 = 19 * f6; /* 1.959375*2^30 */ - int32_t f7_38 = 38 * f7; /* 1.959375*2^30 */ - int32_t f8_19 = 19 * f8; /* 1.959375*2^30 */ - int32_t f9_38 = 38 * f9; /* 1.959375*2^30 */ - int64_t f0f0 = f0 * (int64_t) f0; - int64_t f0f1_2 = f0_2 * (int64_t) f1; - int64_t f0f2_2 = f0_2 * (int64_t) f2; - int64_t f0f3_2 = f0_2 * (int64_t) f3; - int64_t f0f4_2 = f0_2 * (int64_t) f4; - int64_t f0f5_2 = f0_2 * (int64_t) f5; - int64_t f0f6_2 = f0_2 * (int64_t) f6; - int64_t f0f7_2 = f0_2 * (int64_t) f7; - int64_t f0f8_2 = f0_2 * (int64_t) f8; - int64_t f0f9_2 = f0_2 * (int64_t) f9; - int64_t f1f1_2 = f1_2 * (int64_t) f1; - int64_t f1f2_2 = f1_2 * (int64_t) f2; - int64_t f1f3_4 = f1_2 * (int64_t) f3_2; - int64_t f1f4_2 = f1_2 * (int64_t) f4; - int64_t f1f5_4 = f1_2 * (int64_t) f5_2; - int64_t f1f6_2 = f1_2 * (int64_t) f6; - int64_t f1f7_4 = f1_2 * (int64_t) f7_2; - int64_t f1f8_2 = f1_2 * (int64_t) f8; - int64_t f1f9_76 = f1_2 * (int64_t) f9_38; - int64_t f2f2 = f2 * (int64_t) f2; - int64_t f2f3_2 = f2_2 * (int64_t) f3; - int64_t f2f4_2 = f2_2 * (int64_t) f4; - int64_t f2f5_2 = f2_2 * (int64_t) f5; - int64_t f2f6_2 = f2_2 * (int64_t) f6; - int64_t f2f7_2 = f2_2 * (int64_t) f7; - int64_t f2f8_38 = f2_2 * (int64_t) f8_19; - int64_t f2f9_38 = f2 * (int64_t) f9_38; - int64_t f3f3_2 = f3_2 * (int64_t) f3; - int64_t f3f4_2 = f3_2 * (int64_t) f4; - int64_t f3f5_4 = f3_2 * (int64_t) f5_2; - int64_t f3f6_2 = f3_2 * (int64_t) f6; - int64_t f3f7_76 = f3_2 * (int64_t) f7_38; - int64_t f3f8_38 = f3_2 * (int64_t) f8_19; - int64_t f3f9_76 = f3_2 * (int64_t) f9_38; - int64_t f4f4 = f4 * (int64_t) f4; - int64_t f4f5_2 = f4_2 * (int64_t) f5; - int64_t f4f6_38 = f4_2 * (int64_t) f6_19; - int64_t f4f7_38 = f4 * (int64_t) f7_38; - int64_t f4f8_38 = f4_2 * (int64_t) f8_19; - int64_t f4f9_38 = f4 * (int64_t) f9_38; - int64_t f5f5_38 = f5 * (int64_t) f5_38; - int64_t f5f6_38 = f5_2 * (int64_t) f6_19; - int64_t f5f7_76 = f5_2 * (int64_t) f7_38; - int64_t f5f8_38 = f5_2 * (int64_t) f8_19; - int64_t f5f9_76 = f5_2 * (int64_t) f9_38; - int64_t f6f6_19 = f6 * (int64_t) f6_19; - int64_t f6f7_38 = f6 * (int64_t) f7_38; - int64_t f6f8_38 = f6_2 * (int64_t) f8_19; - int64_t f6f9_38 = f6 * (int64_t) f9_38; - int64_t f7f7_38 = f7 * (int64_t) f7_38; - int64_t f7f8_38 = f7_2 * (int64_t) f8_19; - int64_t f7f9_76 = f7_2 * (int64_t) f9_38; - int64_t f8f8_19 = f8 * (int64_t) f8_19; - int64_t f8f9_38 = f8 * (int64_t) f9_38; - int64_t f9f9_38 = f9 * (int64_t) f9_38; - int64_t h0 = f0f0 + f1f9_76 + f2f8_38 + f3f7_76 + f4f6_38 + f5f5_38; - int64_t h1 = f0f1_2 + f2f9_38 + f3f8_38 + f4f7_38 + f5f6_38; - int64_t h2 = f0f2_2 + f1f1_2 + f3f9_76 + f4f8_38 + f5f7_76 + f6f6_19; - int64_t h3 = f0f3_2 + f1f2_2 + f4f9_38 + f5f8_38 + f6f7_38; - int64_t h4 = f0f4_2 + f1f3_4 + f2f2 + f5f9_76 + f6f8_38 + f7f7_38; - int64_t h5 = f0f5_2 + f1f4_2 + f2f3_2 + f6f9_38 + f7f8_38; - int64_t h6 = f0f6_2 + f1f5_4 + f2f4_2 + f3f3_2 + f7f9_76 + f8f8_19; - int64_t h7 = f0f7_2 + f1f6_2 + f2f5_2 + f3f4_2 + f8f9_38; - int64_t h8 = f0f8_2 + f1f7_4 + f2f6_2 + f3f5_4 + f4f4 + f9f9_38; - int64_t h9 = f0f9_2 + f1f8_2 + f2f7_2 + f3f6_2 + f4f5_2; - int64_t carry0; - int64_t carry1; - int64_t carry2; - int64_t carry3; - int64_t carry4; - int64_t carry5; - int64_t carry6; - int64_t carry7; - int64_t carry8; - int64_t carry9; - carry0 = (h0 + (1L << 25)) >> 26; - h1 += carry0; - h0 -= shl64(carry0, 26); - carry4 = (h4 + (1L << 25)) >> 26; - h5 += carry4; - h4 -= shl64(carry4, 26); - carry1 = (h1 + (1L << 24)) >> 25; - h2 += carry1; - h1 -= shl64(carry1, 25); - carry5 = (h5 + (1L << 24)) >> 25; - h6 += carry5; - h5 -= shl64(carry5, 25); - carry2 = (h2 + (1L << 25)) >> 26; - h3 += carry2; - h2 -= shl64(carry2, 26); - carry6 = (h6 + (1L << 25)) >> 26; - h7 += carry6; - h6 -= shl64(carry6, 26); - carry3 = (h3 + (1L << 24)) >> 25; - h4 += carry3; - h3 -= shl64(carry3, 25); - carry7 = (h7 + (1L << 24)) >> 25; - h8 += carry7; - h7 -= shl64(carry7, 25); - carry4 = (h4 + (1L << 25)) >> 26; - h5 += carry4; - h4 -= shl64(carry4, 26); - carry8 = (h8 + (1L << 25)) >> 26; - h9 += carry8; - h8 -= shl64(carry8, 26); - carry9 = (h9 + (1L << 24)) >> 25; - h0 += carry9 * 19; - h9 -= shl64(carry9, 25); - carry0 = (h0 + (1L << 25)) >> 26; - h1 += carry0; - h0 -= shl64(carry0, 26); - h[0] = (int32_t) h0; - h[1] = (int32_t) h1; - h[2] = (int32_t) h2; - h[3] = (int32_t) h3; - h[4] = (int32_t) h4; - h[5] = (int32_t) h5; - h[6] = (int32_t) h6; - h[7] = (int32_t) h7; - h[8] = (int32_t) h8; - h[9] = (int32_t) h9; + int32_t f0 = f[0]; + int32_t f1 = f[1]; + int32_t f2 = f[2]; + int32_t f3 = f[3]; + int32_t f4 = f[4]; + int32_t f5 = f[5]; + int32_t f6 = f[6]; + int32_t f7 = f[7]; + int32_t f8 = f[8]; + int32_t f9 = f[9]; + int32_t f0_2 = 2 * f0; + int32_t f1_2 = 2 * f1; + int32_t f2_2 = 2 * f2; + int32_t f3_2 = 2 * f3; + int32_t f4_2 = 2 * f4; + int32_t f5_2 = 2 * f5; + int32_t f6_2 = 2 * f6; + int32_t f7_2 = 2 * f7; + int32_t f5_38 = 38 * f5; /* 1.959375*2^30 */ + int32_t f6_19 = 19 * f6; /* 1.959375*2^30 */ + int32_t f7_38 = 38 * f7; /* 1.959375*2^30 */ + int32_t f8_19 = 19 * f8; /* 1.959375*2^30 */ + int32_t f9_38 = 38 * f9; /* 1.959375*2^30 */ + int64_t f0f0 = f0 * (int64_t) f0; + int64_t f0f1_2 = f0_2 * (int64_t) f1; + int64_t f0f2_2 = f0_2 * (int64_t) f2; + int64_t f0f3_2 = f0_2 * (int64_t) f3; + int64_t f0f4_2 = f0_2 * (int64_t) f4; + int64_t f0f5_2 = f0_2 * (int64_t) f5; + int64_t f0f6_2 = f0_2 * (int64_t) f6; + int64_t f0f7_2 = f0_2 * (int64_t) f7; + int64_t f0f8_2 = f0_2 * (int64_t) f8; + int64_t f0f9_2 = f0_2 * (int64_t) f9; + int64_t f1f1_2 = f1_2 * (int64_t) f1; + int64_t f1f2_2 = f1_2 * (int64_t) f2; + int64_t f1f3_4 = f1_2 * (int64_t) f3_2; + int64_t f1f4_2 = f1_2 * (int64_t) f4; + int64_t f1f5_4 = f1_2 * (int64_t) f5_2; + int64_t f1f6_2 = f1_2 * (int64_t) f6; + int64_t f1f7_4 = f1_2 * (int64_t) f7_2; + int64_t f1f8_2 = f1_2 * (int64_t) f8; + int64_t f1f9_76 = f1_2 * (int64_t) f9_38; + int64_t f2f2 = f2 * (int64_t) f2; + int64_t f2f3_2 = f2_2 * (int64_t) f3; + int64_t f2f4_2 = f2_2 * (int64_t) f4; + int64_t f2f5_2 = f2_2 * (int64_t) f5; + int64_t f2f6_2 = f2_2 * (int64_t) f6; + int64_t f2f7_2 = f2_2 * (int64_t) f7; + int64_t f2f8_38 = f2_2 * (int64_t) f8_19; + int64_t f2f9_38 = f2 * (int64_t) f9_38; + int64_t f3f3_2 = f3_2 * (int64_t) f3; + int64_t f3f4_2 = f3_2 * (int64_t) f4; + int64_t f3f5_4 = f3_2 * (int64_t) f5_2; + int64_t f3f6_2 = f3_2 * (int64_t) f6; + int64_t f3f7_76 = f3_2 * (int64_t) f7_38; + int64_t f3f8_38 = f3_2 * (int64_t) f8_19; + int64_t f3f9_76 = f3_2 * (int64_t) f9_38; + int64_t f4f4 = f4 * (int64_t) f4; + int64_t f4f5_2 = f4_2 * (int64_t) f5; + int64_t f4f6_38 = f4_2 * (int64_t) f6_19; + int64_t f4f7_38 = f4 * (int64_t) f7_38; + int64_t f4f8_38 = f4_2 * (int64_t) f8_19; + int64_t f4f9_38 = f4 * (int64_t) f9_38; + int64_t f5f5_38 = f5 * (int64_t) f5_38; + int64_t f5f6_38 = f5_2 * (int64_t) f6_19; + int64_t f5f7_76 = f5_2 * (int64_t) f7_38; + int64_t f5f8_38 = f5_2 * (int64_t) f8_19; + int64_t f5f9_76 = f5_2 * (int64_t) f9_38; + int64_t f6f6_19 = f6 * (int64_t) f6_19; + int64_t f6f7_38 = f6 * (int64_t) f7_38; + int64_t f6f8_38 = f6_2 * (int64_t) f8_19; + int64_t f6f9_38 = f6 * (int64_t) f9_38; + int64_t f7f7_38 = f7 * (int64_t) f7_38; + int64_t f7f8_38 = f7_2 * (int64_t) f8_19; + int64_t f7f9_76 = f7_2 * (int64_t) f9_38; + int64_t f8f8_19 = f8 * (int64_t) f8_19; + int64_t f8f9_38 = f8 * (int64_t) f9_38; + int64_t f9f9_38 = f9 * (int64_t) f9_38; + int64_t h0 = f0f0 + f1f9_76 + f2f8_38 + f3f7_76 + f4f6_38 + f5f5_38; + int64_t h1 = f0f1_2 + f2f9_38 + f3f8_38 + f4f7_38 + f5f6_38; + int64_t h2 = f0f2_2 + f1f1_2 + f3f9_76 + f4f8_38 + f5f7_76 + f6f6_19; + int64_t h3 = f0f3_2 + f1f2_2 + f4f9_38 + f5f8_38 + f6f7_38; + int64_t h4 = f0f4_2 + f1f3_4 + f2f2 + f5f9_76 + f6f8_38 + f7f7_38; + int64_t h5 = f0f5_2 + f1f4_2 + f2f3_2 + f6f9_38 + f7f8_38; + int64_t h6 = f0f6_2 + f1f5_4 + f2f4_2 + f3f3_2 + f7f9_76 + f8f8_19; + int64_t h7 = f0f7_2 + f1f6_2 + f2f5_2 + f3f4_2 + f8f9_38; + int64_t h8 = f0f8_2 + f1f7_4 + f2f6_2 + f3f5_4 + f4f4 + f9f9_38; + int64_t h9 = f0f9_2 + f1f8_2 + f2f7_2 + f3f6_2 + f4f5_2; + int64_t carry0; + int64_t carry1; + int64_t carry2; + int64_t carry3; + int64_t carry4; + int64_t carry5; + int64_t carry6; + int64_t carry7; + int64_t carry8; + int64_t carry9; + carry0 = (h0 + (1L << 25)) >> 26; + h1 += carry0; + h0 -= shl64(carry0, 26); + carry4 = (h4 + (1L << 25)) >> 26; + h5 += carry4; + h4 -= shl64(carry4, 26); + carry1 = (h1 + (1L << 24)) >> 25; + h2 += carry1; + h1 -= shl64(carry1, 25); + carry5 = (h5 + (1L << 24)) >> 25; + h6 += carry5; + h5 -= shl64(carry5, 25); + carry2 = (h2 + (1L << 25)) >> 26; + h3 += carry2; + h2 -= shl64(carry2, 26); + carry6 = (h6 + (1L << 25)) >> 26; + h7 += carry6; + h6 -= shl64(carry6, 26); + carry3 = (h3 + (1L << 24)) >> 25; + h4 += carry3; + h3 -= shl64(carry3, 25); + carry7 = (h7 + (1L << 24)) >> 25; + h8 += carry7; + h7 -= shl64(carry7, 25); + carry4 = (h4 + (1L << 25)) >> 26; + h5 += carry4; + h4 -= shl64(carry4, 26); + carry8 = (h8 + (1L << 25)) >> 26; + h9 += carry8; + h8 -= shl64(carry8, 26); + carry9 = (h9 + (1L << 24)) >> 25; + h0 += carry9 * 19; + h9 -= shl64(carry9, 25); + carry0 = (h0 + (1L << 25)) >> 26; + h1 += carry0; + h0 -= shl64(carry0, 26); + h[0] = (int32_t) h0; + h[1] = (int32_t) h1; + h[2] = (int32_t) h2; + h[3] = (int32_t) h3; + h[4] = (int32_t) h4; + h[5] = (int32_t) h5; + h[6] = (int32_t) h6; + h[7] = (int32_t) h7; + h[8] = (int32_t) h8; + h[9] = (int32_t) h9; } @@ -1143,160 +1163,160 @@ See fe_mul.c for discussion of implementation strategy. */ void fe_sq2(fe h, const fe f) { - int32_t f0 = f[0]; - int32_t f1 = f[1]; - int32_t f2 = f[2]; - int32_t f3 = f[3]; - int32_t f4 = f[4]; - int32_t f5 = f[5]; - int32_t f6 = f[6]; - int32_t f7 = f[7]; - int32_t f8 = f[8]; - int32_t f9 = f[9]; - int32_t f0_2 = 2 * f0; - int32_t f1_2 = 2 * f1; - int32_t f2_2 = 2 * f2; - int32_t f3_2 = 2 * f3; - int32_t f4_2 = 2 * f4; - int32_t f5_2 = 2 * f5; - int32_t f6_2 = 2 * f6; - int32_t f7_2 = 2 * f7; - int32_t f5_38 = 38 * f5; /* 1.959375*2^30 */ - int32_t f6_19 = 19 * f6; /* 1.959375*2^30 */ - int32_t f7_38 = 38 * f7; /* 1.959375*2^30 */ - int32_t f8_19 = 19 * f8; /* 1.959375*2^30 */ - int32_t f9_38 = 38 * f9; /* 1.959375*2^30 */ - int64_t f0f0 = f0 * (int64_t) f0; - int64_t f0f1_2 = f0_2 * (int64_t) f1; - int64_t f0f2_2 = f0_2 * (int64_t) f2; - int64_t f0f3_2 = f0_2 * (int64_t) f3; - int64_t f0f4_2 = f0_2 * (int64_t) f4; - int64_t f0f5_2 = f0_2 * (int64_t) f5; - int64_t f0f6_2 = f0_2 * (int64_t) f6; - int64_t f0f7_2 = f0_2 * (int64_t) f7; - int64_t f0f8_2 = f0_2 * (int64_t) f8; - int64_t f0f9_2 = f0_2 * (int64_t) f9; - int64_t f1f1_2 = f1_2 * (int64_t) f1; - int64_t f1f2_2 = f1_2 * (int64_t) f2; - int64_t f1f3_4 = f1_2 * (int64_t) f3_2; - int64_t f1f4_2 = f1_2 * (int64_t) f4; - int64_t f1f5_4 = f1_2 * (int64_t) f5_2; - int64_t f1f6_2 = f1_2 * (int64_t) f6; - int64_t f1f7_4 = f1_2 * (int64_t) f7_2; - int64_t f1f8_2 = f1_2 * (int64_t) f8; - int64_t f1f9_76 = f1_2 * (int64_t) f9_38; - int64_t f2f2 = f2 * (int64_t) f2; - int64_t f2f3_2 = f2_2 * (int64_t) f3; - int64_t f2f4_2 = f2_2 * (int64_t) f4; - int64_t f2f5_2 = f2_2 * (int64_t) f5; - int64_t f2f6_2 = f2_2 * (int64_t) f6; - int64_t f2f7_2 = f2_2 * (int64_t) f7; - int64_t f2f8_38 = f2_2 * (int64_t) f8_19; - int64_t f2f9_38 = f2 * (int64_t) f9_38; - int64_t f3f3_2 = f3_2 * (int64_t) f3; - int64_t f3f4_2 = f3_2 * (int64_t) f4; - int64_t f3f5_4 = f3_2 * (int64_t) f5_2; - int64_t f3f6_2 = f3_2 * (int64_t) f6; - int64_t f3f7_76 = f3_2 * (int64_t) f7_38; - int64_t f3f8_38 = f3_2 * (int64_t) f8_19; - int64_t f3f9_76 = f3_2 * (int64_t) f9_38; - int64_t f4f4 = f4 * (int64_t) f4; - int64_t f4f5_2 = f4_2 * (int64_t) f5; - int64_t f4f6_38 = f4_2 * (int64_t) f6_19; - int64_t f4f7_38 = f4 * (int64_t) f7_38; - int64_t f4f8_38 = f4_2 * (int64_t) f8_19; - int64_t f4f9_38 = f4 * (int64_t) f9_38; - int64_t f5f5_38 = f5 * (int64_t) f5_38; - int64_t f5f6_38 = f5_2 * (int64_t) f6_19; - int64_t f5f7_76 = f5_2 * (int64_t) f7_38; - int64_t f5f8_38 = f5_2 * (int64_t) f8_19; - int64_t f5f9_76 = f5_2 * (int64_t) f9_38; - int64_t f6f6_19 = f6 * (int64_t) f6_19; - int64_t f6f7_38 = f6 * (int64_t) f7_38; - int64_t f6f8_38 = f6_2 * (int64_t) f8_19; - int64_t f6f9_38 = f6 * (int64_t) f9_38; - int64_t f7f7_38 = f7 * (int64_t) f7_38; - int64_t f7f8_38 = f7_2 * (int64_t) f8_19; - int64_t f7f9_76 = f7_2 * (int64_t) f9_38; - int64_t f8f8_19 = f8 * (int64_t) f8_19; - int64_t f8f9_38 = f8 * (int64_t) f9_38; - int64_t f9f9_38 = f9 * (int64_t) f9_38; - int64_t h0 = f0f0 + f1f9_76 + f2f8_38 + f3f7_76 + f4f6_38 + f5f5_38; - int64_t h1 = f0f1_2 + f2f9_38 + f3f8_38 + f4f7_38 + f5f6_38; - int64_t h2 = f0f2_2 + f1f1_2 + f3f9_76 + f4f8_38 + f5f7_76 + f6f6_19; - int64_t h3 = f0f3_2 + f1f2_2 + f4f9_38 + f5f8_38 + f6f7_38; - int64_t h4 = f0f4_2 + f1f3_4 + f2f2 + f5f9_76 + f6f8_38 + f7f7_38; - int64_t h5 = f0f5_2 + f1f4_2 + f2f3_2 + f6f9_38 + f7f8_38; - int64_t h6 = f0f6_2 + f1f5_4 + f2f4_2 + f3f3_2 + f7f9_76 + f8f8_19; - int64_t h7 = f0f7_2 + f1f6_2 + f2f5_2 + f3f4_2 + f8f9_38; - int64_t h8 = f0f8_2 + f1f7_4 + f2f6_2 + f3f5_4 + f4f4 + f9f9_38; - int64_t h9 = f0f9_2 + f1f8_2 + f2f7_2 + f3f6_2 + f4f5_2; - int64_t carry0; - int64_t carry1; - int64_t carry2; - int64_t carry3; - int64_t carry4; - int64_t carry5; - int64_t carry6; - int64_t carry7; - int64_t carry8; - int64_t carry9; - h0 += h0; - h1 += h1; - h2 += h2; - h3 += h3; - h4 += h4; - h5 += h5; - h6 += h6; - h7 += h7; - h8 += h8; - h9 += h9; - carry0 = (h0 + (1L << 25)) >> 26; - h1 += carry0; - h0 -= shl64(carry0, 26); - carry4 = (h4 + (1L << 25)) >> 26; - h5 += carry4; - h4 -= shl64(carry4, 26); - carry1 = (h1 + (1L << 24)) >> 25; - h2 += carry1; - h1 -= shl64(carry1, 25); - carry5 = (h5 + (1L << 24)) >> 25; - h6 += carry5; - h5 -= shl64(carry5, 25); - carry2 = (h2 + (1L << 25)) >> 26; - h3 += carry2; - h2 -= shl64(carry2, 26); - carry6 = (h6 + (1L << 25)) >> 26; - h7 += carry6; - h6 -= shl64(carry6, 26); - carry3 = (h3 + (1L << 24)) >> 25; - h4 += carry3; - h3 -= shl64(carry3, 25); - carry7 = (h7 + (1L << 24)) >> 25; - h8 += carry7; - h7 -= shl64(carry7, 25); - carry4 = (h4 + (1L << 25)) >> 26; - h5 += carry4; - h4 -= shl64(carry4, 26); - carry8 = (h8 + (1L << 25)) >> 26; - h9 += carry8; - h8 -= shl64(carry8, 26); - carry9 = (h9 + (1L << 24)) >> 25; - h0 += carry9 * 19; - h9 -= shl64(carry9, 25); - carry0 = (h0 + (1L << 25)) >> 26; - h1 += carry0; - h0 -= shl64(carry0, 26); - h[0] = (int32_t) h0; - h[1] = (int32_t) h1; - h[2] = (int32_t) h2; - h[3] = (int32_t) h3; - h[4] = (int32_t) h4; - h[5] = (int32_t) h5; - h[6] = (int32_t) h6; - h[7] = (int32_t) h7; - h[8] = (int32_t) h8; - h[9] = (int32_t) h9; + int32_t f0 = f[0]; + int32_t f1 = f[1]; + int32_t f2 = f[2]; + int32_t f3 = f[3]; + int32_t f4 = f[4]; + int32_t f5 = f[5]; + int32_t f6 = f[6]; + int32_t f7 = f[7]; + int32_t f8 = f[8]; + int32_t f9 = f[9]; + int32_t f0_2 = 2 * f0; + int32_t f1_2 = 2 * f1; + int32_t f2_2 = 2 * f2; + int32_t f3_2 = 2 * f3; + int32_t f4_2 = 2 * f4; + int32_t f5_2 = 2 * f5; + int32_t f6_2 = 2 * f6; + int32_t f7_2 = 2 * f7; + int32_t f5_38 = 38 * f5; /* 1.959375*2^30 */ + int32_t f6_19 = 19 * f6; /* 1.959375*2^30 */ + int32_t f7_38 = 38 * f7; /* 1.959375*2^30 */ + int32_t f8_19 = 19 * f8; /* 1.959375*2^30 */ + int32_t f9_38 = 38 * f9; /* 1.959375*2^30 */ + int64_t f0f0 = f0 * (int64_t) f0; + int64_t f0f1_2 = f0_2 * (int64_t) f1; + int64_t f0f2_2 = f0_2 * (int64_t) f2; + int64_t f0f3_2 = f0_2 * (int64_t) f3; + int64_t f0f4_2 = f0_2 * (int64_t) f4; + int64_t f0f5_2 = f0_2 * (int64_t) f5; + int64_t f0f6_2 = f0_2 * (int64_t) f6; + int64_t f0f7_2 = f0_2 * (int64_t) f7; + int64_t f0f8_2 = f0_2 * (int64_t) f8; + int64_t f0f9_2 = f0_2 * (int64_t) f9; + int64_t f1f1_2 = f1_2 * (int64_t) f1; + int64_t f1f2_2 = f1_2 * (int64_t) f2; + int64_t f1f3_4 = f1_2 * (int64_t) f3_2; + int64_t f1f4_2 = f1_2 * (int64_t) f4; + int64_t f1f5_4 = f1_2 * (int64_t) f5_2; + int64_t f1f6_2 = f1_2 * (int64_t) f6; + int64_t f1f7_4 = f1_2 * (int64_t) f7_2; + int64_t f1f8_2 = f1_2 * (int64_t) f8; + int64_t f1f9_76 = f1_2 * (int64_t) f9_38; + int64_t f2f2 = f2 * (int64_t) f2; + int64_t f2f3_2 = f2_2 * (int64_t) f3; + int64_t f2f4_2 = f2_2 * (int64_t) f4; + int64_t f2f5_2 = f2_2 * (int64_t) f5; + int64_t f2f6_2 = f2_2 * (int64_t) f6; + int64_t f2f7_2 = f2_2 * (int64_t) f7; + int64_t f2f8_38 = f2_2 * (int64_t) f8_19; + int64_t f2f9_38 = f2 * (int64_t) f9_38; + int64_t f3f3_2 = f3_2 * (int64_t) f3; + int64_t f3f4_2 = f3_2 * (int64_t) f4; + int64_t f3f5_4 = f3_2 * (int64_t) f5_2; + int64_t f3f6_2 = f3_2 * (int64_t) f6; + int64_t f3f7_76 = f3_2 * (int64_t) f7_38; + int64_t f3f8_38 = f3_2 * (int64_t) f8_19; + int64_t f3f9_76 = f3_2 * (int64_t) f9_38; + int64_t f4f4 = f4 * (int64_t) f4; + int64_t f4f5_2 = f4_2 * (int64_t) f5; + int64_t f4f6_38 = f4_2 * (int64_t) f6_19; + int64_t f4f7_38 = f4 * (int64_t) f7_38; + int64_t f4f8_38 = f4_2 * (int64_t) f8_19; + int64_t f4f9_38 = f4 * (int64_t) f9_38; + int64_t f5f5_38 = f5 * (int64_t) f5_38; + int64_t f5f6_38 = f5_2 * (int64_t) f6_19; + int64_t f5f7_76 = f5_2 * (int64_t) f7_38; + int64_t f5f8_38 = f5_2 * (int64_t) f8_19; + int64_t f5f9_76 = f5_2 * (int64_t) f9_38; + int64_t f6f6_19 = f6 * (int64_t) f6_19; + int64_t f6f7_38 = f6 * (int64_t) f7_38; + int64_t f6f8_38 = f6_2 * (int64_t) f8_19; + int64_t f6f9_38 = f6 * (int64_t) f9_38; + int64_t f7f7_38 = f7 * (int64_t) f7_38; + int64_t f7f8_38 = f7_2 * (int64_t) f8_19; + int64_t f7f9_76 = f7_2 * (int64_t) f9_38; + int64_t f8f8_19 = f8 * (int64_t) f8_19; + int64_t f8f9_38 = f8 * (int64_t) f9_38; + int64_t f9f9_38 = f9 * (int64_t) f9_38; + int64_t h0 = f0f0 + f1f9_76 + f2f8_38 + f3f7_76 + f4f6_38 + f5f5_38; + int64_t h1 = f0f1_2 + f2f9_38 + f3f8_38 + f4f7_38 + f5f6_38; + int64_t h2 = f0f2_2 + f1f1_2 + f3f9_76 + f4f8_38 + f5f7_76 + f6f6_19; + int64_t h3 = f0f3_2 + f1f2_2 + f4f9_38 + f5f8_38 + f6f7_38; + int64_t h4 = f0f4_2 + f1f3_4 + f2f2 + f5f9_76 + f6f8_38 + f7f7_38; + int64_t h5 = f0f5_2 + f1f4_2 + f2f3_2 + f6f9_38 + f7f8_38; + int64_t h6 = f0f6_2 + f1f5_4 + f2f4_2 + f3f3_2 + f7f9_76 + f8f8_19; + int64_t h7 = f0f7_2 + f1f6_2 + f2f5_2 + f3f4_2 + f8f9_38; + int64_t h8 = f0f8_2 + f1f7_4 + f2f6_2 + f3f5_4 + f4f4 + f9f9_38; + int64_t h9 = f0f9_2 + f1f8_2 + f2f7_2 + f3f6_2 + f4f5_2; + int64_t carry0; + int64_t carry1; + int64_t carry2; + int64_t carry3; + int64_t carry4; + int64_t carry5; + int64_t carry6; + int64_t carry7; + int64_t carry8; + int64_t carry9; + h0 += h0; + h1 += h1; + h2 += h2; + h3 += h3; + h4 += h4; + h5 += h5; + h6 += h6; + h7 += h7; + h8 += h8; + h9 += h9; + carry0 = (h0 + (1L << 25)) >> 26; + h1 += carry0; + h0 -= shl64(carry0, 26); + carry4 = (h4 + (1L << 25)) >> 26; + h5 += carry4; + h4 -= shl64(carry4, 26); + carry1 = (h1 + (1L << 24)) >> 25; + h2 += carry1; + h1 -= shl64(carry1, 25); + carry5 = (h5 + (1L << 24)) >> 25; + h6 += carry5; + h5 -= shl64(carry5, 25); + carry2 = (h2 + (1L << 25)) >> 26; + h3 += carry2; + h2 -= shl64(carry2, 26); + carry6 = (h6 + (1L << 25)) >> 26; + h7 += carry6; + h6 -= shl64(carry6, 26); + carry3 = (h3 + (1L << 24)) >> 25; + h4 += carry3; + h3 -= shl64(carry3, 25); + carry7 = (h7 + (1L << 24)) >> 25; + h8 += carry7; + h7 -= shl64(carry7, 25); + carry4 = (h4 + (1L << 25)) >> 26; + h5 += carry4; + h4 -= shl64(carry4, 26); + carry8 = (h8 + (1L << 25)) >> 26; + h9 += carry8; + h8 -= shl64(carry8, 26); + carry9 = (h9 + (1L << 24)) >> 25; + h0 += carry9 * 19; + h9 -= shl64(carry9, 25); + carry0 = (h0 + (1L << 25)) >> 26; + h1 += carry0; + h0 -= shl64(carry0, 26); + h[0] = (int32_t) h0; + h[1] = (int32_t) h1; + h[2] = (int32_t) h2; + h[3] = (int32_t) h3; + h[4] = (int32_t) h4; + h[5] = (int32_t) h5; + h[6] = (int32_t) h6; + h[7] = (int32_t) h7; + h[8] = (int32_t) h8; + h[9] = (int32_t) h9; } @@ -1313,47 +1333,47 @@ Postconditions: */ void fe_sub(fe h, const fe f, const fe g) { - int32_t f0 = f[0]; - int32_t f1 = f[1]; - int32_t f2 = f[2]; - int32_t f3 = f[3]; - int32_t f4 = f[4]; - int32_t f5 = f[5]; - int32_t f6 = f[6]; - int32_t f7 = f[7]; - int32_t f8 = f[8]; - int32_t f9 = f[9]; - int32_t g0 = g[0]; - int32_t g1 = g[1]; - int32_t g2 = g[2]; - int32_t g3 = g[3]; - int32_t g4 = g[4]; - int32_t g5 = g[5]; - int32_t g6 = g[6]; - int32_t g7 = g[7]; - int32_t g8 = g[8]; - int32_t g9 = g[9]; - int32_t h0 = f0 - g0; - int32_t h1 = f1 - g1; - int32_t h2 = f2 - g2; - int32_t h3 = f3 - g3; - int32_t h4 = f4 - g4; - int32_t h5 = f5 - g5; - int32_t h6 = f6 - g6; - int32_t h7 = f7 - g7; - int32_t h8 = f8 - g8; - int32_t h9 = f9 - g9; + int32_t f0 = f[0]; + int32_t f1 = f[1]; + int32_t f2 = f[2]; + int32_t f3 = f[3]; + int32_t f4 = f[4]; + int32_t f5 = f[5]; + int32_t f6 = f[6]; + int32_t f7 = f[7]; + int32_t f8 = f[8]; + int32_t f9 = f[9]; + int32_t g0 = g[0]; + int32_t g1 = g[1]; + int32_t g2 = g[2]; + int32_t g3 = g[3]; + int32_t g4 = g[4]; + int32_t g5 = g[5]; + int32_t g6 = g[6]; + int32_t g7 = g[7]; + int32_t g8 = g[8]; + int32_t g9 = g[9]; + int32_t h0 = f0 - g0; + int32_t h1 = f1 - g1; + int32_t h2 = f2 - g2; + int32_t h3 = f3 - g3; + int32_t h4 = f4 - g4; + int32_t h5 = f5 - g5; + int32_t h6 = f6 - g6; + int32_t h7 = f7 - g7; + int32_t h8 = f8 - g8; + int32_t h9 = f9 - g9; - h[0] = h0; - h[1] = h1; - h[2] = h2; - h[3] = h3; - h[4] = h4; - h[5] = h5; - h[6] = h6; - h[7] = h7; - h[8] = h8; - h[9] = h9; + h[0] = h0; + h[1] = h1; + h[2] = h2; + h[3] = h3; + h[4] = h4; + h[5] = h5; + h[6] = h6; + h[7] = h7; + h[8] = h8; + h[9] = h9; } @@ -1384,108 +1404,108 @@ Proof: */ void fe_tobytes(unsigned char *s, const fe h) { - int32_t h0 = h[0]; - int32_t h1 = h[1]; - int32_t h2 = h[2]; - int32_t h3 = h[3]; - int32_t h4 = h[4]; - int32_t h5 = h[5]; - int32_t h6 = h[6]; - int32_t h7 = h[7]; - int32_t h8 = h[8]; - int32_t h9 = h[9]; - int32_t q; - int32_t carry0; - int32_t carry1; - int32_t carry2; - int32_t carry3; - int32_t carry4; - int32_t carry5; - int32_t carry6; - int32_t carry7; - int32_t carry8; - int32_t carry9; - q = (19 * h9 + (((int32_t) 1) << 24)) >> 25; - q = (h0 + q) >> 26; - q = (h1 + q) >> 25; - q = (h2 + q) >> 26; - q = (h3 + q) >> 25; - q = (h4 + q) >> 26; - q = (h5 + q) >> 25; - q = (h6 + q) >> 26; - q = (h7 + q) >> 25; - q = (h8 + q) >> 26; - q = (h9 + q) >> 25; - /* Goal: Output h-(2^255-19)q, which is between 0 and 2^255-20. */ - h0 += 19 * q; - /* Goal: Output h-2^255 q, which is between 0 and 2^255-20. */ - carry0 = h0 >> 26; - h1 += carry0; - h0 -= shl32(carry0, 26); - carry1 = h1 >> 25; - h2 += carry1; - h1 -= shl32(carry1, 25); - carry2 = h2 >> 26; - h3 += carry2; - h2 -= shl32(carry2, 26); - carry3 = h3 >> 25; - h4 += carry3; - h3 -= shl32(carry3, 25); - carry4 = h4 >> 26; - h5 += carry4; - h4 -= shl32(carry4, 26); - carry5 = h5 >> 25; - h6 += carry5; - h5 -= shl32(carry5, 25); - carry6 = h6 >> 26; - h7 += carry6; - h6 -= shl32(carry6, 26); - carry7 = h7 >> 25; - h8 += carry7; - h7 -= shl32(carry7, 25); - carry8 = h8 >> 26; - h9 += carry8; - h8 -= shl32(carry8, 26); - carry9 = h9 >> 25; - h9 -= shl32(carry9, 25); + int32_t h0 = h[0]; + int32_t h1 = h[1]; + int32_t h2 = h[2]; + int32_t h3 = h[3]; + int32_t h4 = h[4]; + int32_t h5 = h[5]; + int32_t h6 = h[6]; + int32_t h7 = h[7]; + int32_t h8 = h[8]; + int32_t h9 = h[9]; + int32_t q; + int32_t carry0; + int32_t carry1; + int32_t carry2; + int32_t carry3; + int32_t carry4; + int32_t carry5; + int32_t carry6; + int32_t carry7; + int32_t carry8; + int32_t carry9; + q = (19 * h9 + (((int32_t) 1) << 24)) >> 25; + q = (h0 + q) >> 26; + q = (h1 + q) >> 25; + q = (h2 + q) >> 26; + q = (h3 + q) >> 25; + q = (h4 + q) >> 26; + q = (h5 + q) >> 25; + q = (h6 + q) >> 26; + q = (h7 + q) >> 25; + q = (h8 + q) >> 26; + q = (h9 + q) >> 25; + /* Goal: Output h-(2^255-19)q, which is between 0 and 2^255-20. */ + h0 += 19 * q; + /* Goal: Output h-2^255 q, which is between 0 and 2^255-20. */ + carry0 = h0 >> 26; + h1 += carry0; + h0 -= shl32(carry0, 26); + carry1 = h1 >> 25; + h2 += carry1; + h1 -= shl32(carry1, 25); + carry2 = h2 >> 26; + h3 += carry2; + h2 -= shl32(carry2, 26); + carry3 = h3 >> 25; + h4 += carry3; + h3 -= shl32(carry3, 25); + carry4 = h4 >> 26; + h5 += carry4; + h4 -= shl32(carry4, 26); + carry5 = h5 >> 25; + h6 += carry5; + h5 -= shl32(carry5, 25); + carry6 = h6 >> 26; + h7 += carry6; + h6 -= shl32(carry6, 26); + carry7 = h7 >> 25; + h8 += carry7; + h7 -= shl32(carry7, 25); + carry8 = h8 >> 26; + h9 += carry8; + h8 -= shl32(carry8, 26); + carry9 = h9 >> 25; + h9 -= shl32(carry9, 25); - /* h10 = carry9 */ - /* - Goal: Output h0+...+2^255 h10-2^255 q, which is between 0 and 2^255-20. - Have h0+...+2^230 h9 between 0 and 2^255-1; - evidently 2^255 h10-2^255 q = 0. - Goal: Output h0+...+2^230 h9. - */ - s[0] = (unsigned char) (h0 >> 0); - s[1] = (unsigned char) (h0 >> 8); - s[2] = (unsigned char) (h0 >> 16); - s[3] = (unsigned char) ((h0 >> 24) | shl32(h1, 2)); - s[4] = (unsigned char) (h1 >> 6); - s[5] = (unsigned char) (h1 >> 14); - s[6] = (unsigned char) ((h1 >> 22) | shl32(h2, 3)); - s[7] = (unsigned char) (h2 >> 5); - s[8] = (unsigned char) (h2 >> 13); - s[9] = (unsigned char) ((h2 >> 21) | shl32(h3, 5)); - s[10] = (unsigned char) (h3 >> 3); - s[11] = (unsigned char) (h3 >> 11); - s[12] = (unsigned char) ((h3 >> 19) | shl32(h4, 6)); - s[13] = (unsigned char) (h4 >> 2); - s[14] = (unsigned char) (h4 >> 10); - s[15] = (unsigned char) (h4 >> 18); - s[16] = (unsigned char) (h5 >> 0); - s[17] = (unsigned char) (h5 >> 8); - s[18] = (unsigned char) (h5 >> 16); - s[19] = (unsigned char) ((h5 >> 24) | shl32(h6, 1)); - s[20] = (unsigned char) (h6 >> 7); - s[21] = (unsigned char) (h6 >> 15); - s[22] = (unsigned char) ((h6 >> 23) | shl32(h7, 3)); - s[23] = (unsigned char) (h7 >> 5); - s[24] = (unsigned char) (h7 >> 13); - s[25] = (unsigned char) ((h7 >> 21) | shl32(h8, 4)); - s[26] = (unsigned char) (h8 >> 4); - s[27] = (unsigned char) (h8 >> 12); - s[28] = (unsigned char) ((h8 >> 20) | shl32(h9, 6)); - s[29] = (unsigned char) (h9 >> 2); - s[30] = (unsigned char) (h9 >> 10); - s[31] = (unsigned char) (h9 >> 18); + /* h10 = carry9 */ + /* + Goal: Output h0+...+2^255 h10-2^255 q, which is between 0 and 2^255-20. + Have h0+...+2^230 h9 between 0 and 2^255-1; + evidently 2^255 h10-2^255 q = 0. + Goal: Output h0+...+2^230 h9. + */ + s[0] = (unsigned char)(h0 >> 0); + s[1] = (unsigned char)(h0 >> 8); + s[2] = (unsigned char)(h0 >> 16); + s[3] = (unsigned char)((h0 >> 24) | shl32(h1, 2)); + s[4] = (unsigned char)(h1 >> 6); + s[5] = (unsigned char)(h1 >> 14); + s[6] = (unsigned char)((h1 >> 22) | shl32(h2, 3)); + s[7] = (unsigned char)(h2 >> 5); + s[8] = (unsigned char)(h2 >> 13); + s[9] = (unsigned char)((h2 >> 21) | shl32(h3, 5)); + s[10] = (unsigned char)(h3 >> 3); + s[11] = (unsigned char)(h3 >> 11); + s[12] = (unsigned char)((h3 >> 19) | shl32(h4, 6)); + s[13] = (unsigned char)(h4 >> 2); + s[14] = (unsigned char)(h4 >> 10); + s[15] = (unsigned char)(h4 >> 18); + s[16] = (unsigned char)(h5 >> 0); + s[17] = (unsigned char)(h5 >> 8); + s[18] = (unsigned char)(h5 >> 16); + s[19] = (unsigned char)((h5 >> 24) | shl32(h6, 1)); + s[20] = (unsigned char)(h6 >> 7); + s[21] = (unsigned char)(h6 >> 15); + s[22] = (unsigned char)((h6 >> 23) | shl32(h7, 3)); + s[23] = (unsigned char)(h7 >> 5); + s[24] = (unsigned char)(h7 >> 13); + s[25] = (unsigned char)((h7 >> 21) | shl32(h8, 4)); + s[26] = (unsigned char)(h8 >> 4); + s[27] = (unsigned char)(h8 >> 12); + s[28] = (unsigned char)((h8 >> 20) | shl32(h9, 6)); + s[29] = (unsigned char)(h9 >> 2); + s[30] = (unsigned char)(h9 >> 10); + s[31] = (unsigned char)(h9 >> 18); } diff --git a/src/ed25519/fixedint.h b/src/ed25519/fixedint.h index 8abced0..af031e9 100644 --- a/src/ed25519/fixedint.h +++ b/src/ed25519/fixedint.h @@ -1,75 +1,75 @@ +#ifndef TINC_FIXEDINT_H +#define TINC_FIXEDINT_H + /* Portable header to provide the 32 and 64 bits type. Not a compatible replacement for , do not blindly use it as such. */ -#ifndef __TINC_FIXEDINT_H__ -#define __TINC_FIXEDINT_H__ - #if ((defined(__STDC__) && __STDC__ && __STDC_VERSION__ >= 199901L) || (defined(__WATCOMC__) && (defined(_STDINT_H_INCLUDED) || __WATCOMC__ >= 1250)) || (defined(__GNUC__) && (defined(_STDINT_H) || defined(_STDINT_H_) || defined(__UINT_FAST64_TYPE__)) )) && !defined(FIXEDINT_H_INCLUDED) - #include - #define FIXEDINT_H_INCLUDED +#include +#define FIXEDINT_H_INCLUDED - #if defined(__WATCOMC__) && __WATCOMC__ >= 1250 && !defined(UINT64_C) - #include - #define UINT64_C(x) (x + (UINT64_MAX - UINT64_MAX)) - #endif +#if defined(__WATCOMC__) && __WATCOMC__ >= 1250 && !defined(UINT64_C) +#include +#define UINT64_C(x) (x + (UINT64_MAX - UINT64_MAX)) +#endif #endif #ifndef FIXEDINT_H_INCLUDED - #define FIXEDINT_H_INCLUDED +#define FIXEDINT_H_INCLUDED - /* (u)int32_t */ - #ifndef uint32_t - #if (ULONG_MAX == 0xffffffffUL) - typedef unsigned long uint32_t; - #elif (UINT_MAX == 0xffffffffUL) - typedef unsigned int uint32_t; - #elif (USHRT_MAX == 0xffffffffUL) - typedef unsigned short uint32_t; - #endif - #endif +/* (u)int32_t */ +#ifndef uint32_t +#if (ULONG_MAX == 0xffffffffUL) +typedef unsigned long uint32_t; +#elif (UINT_MAX == 0xffffffffUL) +typedef unsigned int uint32_t; +#elif (USHRT_MAX == 0xffffffffUL) +typedef unsigned short uint32_t; +#endif +#endif - #ifndef int32_t - #if (LONG_MAX == 0x7fffffffL) - typedef signed long int32_t; - #elif (INT_MAX == 0x7fffffffL) - typedef signed int int32_t; - #elif (SHRT_MAX == 0x7fffffffL) - typedef signed short int32_t; - #endif - #endif +#ifndef int32_t +#if (LONG_MAX == 0x7fffffffL) +typedef signed long int32_t; +#elif (INT_MAX == 0x7fffffffL) +typedef signed int int32_t; +#elif (SHRT_MAX == 0x7fffffffL) +typedef signed short int32_t; +#endif +#endif - /* (u)int64_t */ - #if (defined(__STDC__) && defined(__STDC_VERSION__) && __STDC__ && __STDC_VERSION__ >= 199901L) - typedef long long int64_t; - typedef unsigned long long uint64_t; +/* (u)int64_t */ +#if (defined(__STDC__) && defined(__STDC_VERSION__) && __STDC__ && __STDC_VERSION__ >= 199901L) +typedef long long int64_t; +typedef unsigned long long uint64_t; - #define UINT64_C(v) v ##ULL - #define INT64_C(v) v ##LL - #elif defined(__GNUC__) - __extension__ typedef long long int64_t; - __extension__ typedef unsigned long long uint64_t; +#define UINT64_C(v) v ##ULL +#define INT64_C(v) v ##LL +#elif defined(__GNUC__) +__extension__ typedef long long int64_t; +__extension__ typedef unsigned long long uint64_t; - #define UINT64_C(v) v ##ULL - #define INT64_C(v) v ##LL - #elif defined(__MWERKS__) || defined(__SUNPRO_C) || defined(__SUNPRO_CC) || defined(__APPLE_CC__) || defined(_LONG_LONG) || defined(_CRAYC) - typedef long long int64_t; - typedef unsigned long long uint64_t; +#define UINT64_C(v) v ##ULL +#define INT64_C(v) v ##LL +#elif defined(__MWERKS__) || defined(__SUNPRO_C) || defined(__SUNPRO_CC) || defined(__APPLE_CC__) || defined(_LONG_LONG) || defined(_CRAYC) +typedef long long int64_t; +typedef unsigned long long uint64_t; - #define UINT64_C(v) v ##ULL - #define INT64_C(v) v ##LL - #elif (defined(__WATCOMC__) && defined(__WATCOM_INT64__)) || (defined(_MSC_VER) && _INTEGRAL_MAX_BITS >= 64) || (defined(__BORLANDC__) && __BORLANDC__ > 0x460) || defined(__alpha) || defined(__DECC) - typedef __int64 int64_t; - typedef unsigned __int64 uint64_t; +#define UINT64_C(v) v ##ULL +#define INT64_C(v) v ##LL +#elif (defined(__WATCOMC__) && defined(__WATCOM_INT64__)) || (defined(_MSC_VER) && _INTEGRAL_MAX_BITS >= 64) || (defined(__BORLANDC__) && __BORLANDC__ > 0x460) || defined(__alpha) || defined(__DECC) +typedef __int64 int64_t; +typedef unsigned __int64 uint64_t; - #define UINT64_C(v) v ##UI64 - #define INT64_C(v) v ##I64 - #endif +#define UINT64_C(v) v ##UI64 +#define INT64_C(v) v ##I64 +#endif #endif static inline unsigned char shlu8(unsigned char a, uint32_t b) { diff --git a/src/ed25519/ge.c b/src/ed25519/ge.c index 9488218..ca8c39b 100644 --- a/src/ed25519/ge.c +++ b/src/ed25519/ge.c @@ -7,54 +7,54 @@ r = p + q */ void ge_add(ge_p1p1 *r, const ge_p3 *p, const ge_cached *q) { - fe t0; - fe_add(r->X, p->Y, p->X); - fe_sub(r->Y, p->Y, p->X); - fe_mul(r->Z, r->X, q->YplusX); - fe_mul(r->Y, r->Y, q->YminusX); - fe_mul(r->T, q->T2d, p->T); - fe_mul(r->X, p->Z, q->Z); - fe_add(t0, r->X, r->X); - fe_sub(r->X, r->Z, r->Y); - fe_add(r->Y, r->Z, r->Y); - fe_add(r->Z, t0, r->T); - fe_sub(r->T, t0, r->T); + fe t0; + fe_add(r->X, p->Y, p->X); + fe_sub(r->Y, p->Y, p->X); + fe_mul(r->Z, r->X, q->YplusX); + fe_mul(r->Y, r->Y, q->YminusX); + fe_mul(r->T, q->T2d, p->T); + fe_mul(r->X, p->Z, q->Z); + fe_add(t0, r->X, r->X); + fe_sub(r->X, r->Z, r->Y); + fe_add(r->Y, r->Z, r->Y); + fe_add(r->Z, t0, r->T); + fe_sub(r->T, t0, r->T); } static void slide(signed char *r, const unsigned char *a) { - int i; - int b; - int k; + int i; + int b; + int k; - for (i = 0; i < 256; ++i) { - r[i] = 1 & (a[i >> 3] >> (i & 7)); - } + for(i = 0; i < 256; ++i) { + r[i] = 1 & (a[i >> 3] >> (i & 7)); + } - for (i = 0; i < 256; ++i) - if (r[i]) { - for (b = 1; b <= 6 && i + b < 256; ++b) { - if (r[i + b]) { - if (r[i] + (r[i + b] << b) <= 15) { - r[i] += r[i + b] << b; - r[i + b] = 0; - } else if (r[i] - (r[i + b] << b) >= -15) { - r[i] -= r[i + b] << b; + for(i = 0; i < 256; ++i) + if(r[i]) { + for(b = 1; b <= 6 && i + b < 256; ++b) { + if(r[i + b]) { + if(r[i] + (r[i + b] << b) <= 15) { + r[i] += r[i + b] << b; + r[i + b] = 0; + } else if(r[i] - (r[i + b] << b) >= -15) { + r[i] -= r[i + b] << b; - for (k = i + b; k < 256; ++k) { - if (!r[k]) { - r[k] = 1; - break; - } + for(k = i + b; k < 256; ++k) { + if(!r[k]) { + r[k] = 1; + break; + } - r[k] = 0; - } - } else { - break; - } - } - } - } + r[k] = 0; + } + } else { + break; + } + } + } + } } /* @@ -65,119 +65,119 @@ B is the Ed25519 base point (x,4/5) with x positive. */ void ge_double_scalarmult_vartime(ge_p2 *r, const unsigned char *a, const ge_p3 *A, const unsigned char *b) { - signed char aslide[256]; - signed char bslide[256]; - ge_cached Ai[8]; /* A,3A,5A,7A,9A,11A,13A,15A */ - ge_p1p1 t; - ge_p3 u; - ge_p3 A2; - int i; - slide(aslide, a); - slide(bslide, b); - ge_p3_to_cached(&Ai[0], A); - ge_p3_dbl(&t, A); - ge_p1p1_to_p3(&A2, &t); - ge_add(&t, &A2, &Ai[0]); - ge_p1p1_to_p3(&u, &t); - ge_p3_to_cached(&Ai[1], &u); - ge_add(&t, &A2, &Ai[1]); - ge_p1p1_to_p3(&u, &t); - ge_p3_to_cached(&Ai[2], &u); - ge_add(&t, &A2, &Ai[2]); - ge_p1p1_to_p3(&u, &t); - ge_p3_to_cached(&Ai[3], &u); - ge_add(&t, &A2, &Ai[3]); - ge_p1p1_to_p3(&u, &t); - ge_p3_to_cached(&Ai[4], &u); - ge_add(&t, &A2, &Ai[4]); - ge_p1p1_to_p3(&u, &t); - ge_p3_to_cached(&Ai[5], &u); - ge_add(&t, &A2, &Ai[5]); - ge_p1p1_to_p3(&u, &t); - ge_p3_to_cached(&Ai[6], &u); - ge_add(&t, &A2, &Ai[6]); - ge_p1p1_to_p3(&u, &t); - ge_p3_to_cached(&Ai[7], &u); - ge_p2_0(r); + signed char aslide[256]; + signed char bslide[256]; + ge_cached Ai[8]; /* A,3A,5A,7A,9A,11A,13A,15A */ + ge_p1p1 t; + ge_p3 u; + ge_p3 A2; + int i; + slide(aslide, a); + slide(bslide, b); + ge_p3_to_cached(&Ai[0], A); + ge_p3_dbl(&t, A); + ge_p1p1_to_p3(&A2, &t); + ge_add(&t, &A2, &Ai[0]); + ge_p1p1_to_p3(&u, &t); + ge_p3_to_cached(&Ai[1], &u); + ge_add(&t, &A2, &Ai[1]); + ge_p1p1_to_p3(&u, &t); + ge_p3_to_cached(&Ai[2], &u); + ge_add(&t, &A2, &Ai[2]); + ge_p1p1_to_p3(&u, &t); + ge_p3_to_cached(&Ai[3], &u); + ge_add(&t, &A2, &Ai[3]); + ge_p1p1_to_p3(&u, &t); + ge_p3_to_cached(&Ai[4], &u); + ge_add(&t, &A2, &Ai[4]); + ge_p1p1_to_p3(&u, &t); + ge_p3_to_cached(&Ai[5], &u); + ge_add(&t, &A2, &Ai[5]); + ge_p1p1_to_p3(&u, &t); + ge_p3_to_cached(&Ai[6], &u); + ge_add(&t, &A2, &Ai[6]); + ge_p1p1_to_p3(&u, &t); + ge_p3_to_cached(&Ai[7], &u); + ge_p2_0(r); - for (i = 255; i >= 0; --i) { - if (aslide[i] || bslide[i]) { - break; - } - } + for(i = 255; i >= 0; --i) { + if(aslide[i] || bslide[i]) { + break; + } + } - for (; i >= 0; --i) { - ge_p2_dbl(&t, r); + for(; i >= 0; --i) { + ge_p2_dbl(&t, r); - if (aslide[i] > 0) { - ge_p1p1_to_p3(&u, &t); - ge_add(&t, &u, &Ai[aslide[i] / 2]); - } else if (aslide[i] < 0) { - ge_p1p1_to_p3(&u, &t); - ge_sub(&t, &u, &Ai[(-aslide[i]) / 2]); - } + if(aslide[i] > 0) { + ge_p1p1_to_p3(&u, &t); + ge_add(&t, &u, &Ai[aslide[i] / 2]); + } else if(aslide[i] < 0) { + ge_p1p1_to_p3(&u, &t); + ge_sub(&t, &u, &Ai[(-aslide[i]) / 2]); + } - if (bslide[i] > 0) { - ge_p1p1_to_p3(&u, &t); - ge_madd(&t, &u, &Bi[bslide[i] / 2]); - } else if (bslide[i] < 0) { - ge_p1p1_to_p3(&u, &t); - ge_msub(&t, &u, &Bi[(-bslide[i]) / 2]); - } + if(bslide[i] > 0) { + ge_p1p1_to_p3(&u, &t); + ge_madd(&t, &u, &Bi[bslide[i] / 2]); + } else if(bslide[i] < 0) { + ge_p1p1_to_p3(&u, &t); + ge_msub(&t, &u, &Bi[(-bslide[i]) / 2]); + } - ge_p1p1_to_p2(r, &t); - } + ge_p1p1_to_p2(r, &t); + } } static const fe d = { - -10913610, 13857413, -15372611, 6949391, 114729, -8787816, -6275908, -3247719, -18696448, -12055116 -}; + -10913610, 13857413, -15372611, 6949391, 114729, -8787816, -6275908, -3247719, -18696448, -12055116 + }; static const fe sqrtm1 = { - -32595792, -7943725, 9377950, 3500415, 12389472, -272473, -25146209, -2005654, 326686, 11406482 -}; + -32595792, -7943725, 9377950, 3500415, 12389472, -272473, -25146209, -2005654, 326686, 11406482 + }; int ge_frombytes_negate_vartime(ge_p3 *h, const unsigned char *s) { - fe u; - fe v; - fe v3; - fe vxx; - fe check; - fe_frombytes(h->Y, s); - fe_1(h->Z); - fe_sq(u, h->Y); - fe_mul(v, u, d); - fe_sub(u, u, h->Z); /* u = y^2-1 */ - fe_add(v, v, h->Z); /* v = dy^2+1 */ - fe_sq(v3, v); - fe_mul(v3, v3, v); /* v3 = v^3 */ - fe_sq(h->X, v3); - fe_mul(h->X, h->X, v); - fe_mul(h->X, h->X, u); /* x = uv^7 */ - fe_pow22523(h->X, h->X); /* x = (uv^7)^((q-5)/8) */ - fe_mul(h->X, h->X, v3); - fe_mul(h->X, h->X, u); /* x = uv^3(uv^7)^((q-5)/8) */ - fe_sq(vxx, h->X); - fe_mul(vxx, vxx, v); - fe_sub(check, vxx, u); /* vx^2-u */ + fe u; + fe v; + fe v3; + fe vxx; + fe check; + fe_frombytes(h->Y, s); + fe_1(h->Z); + fe_sq(u, h->Y); + fe_mul(v, u, d); + fe_sub(u, u, h->Z); /* u = y^2-1 */ + fe_add(v, v, h->Z); /* v = dy^2+1 */ + fe_sq(v3, v); + fe_mul(v3, v3, v); /* v3 = v^3 */ + fe_sq(h->X, v3); + fe_mul(h->X, h->X, v); + fe_mul(h->X, h->X, u); /* x = uv^7 */ + fe_pow22523(h->X, h->X); /* x = (uv^7)^((q-5)/8) */ + fe_mul(h->X, h->X, v3); + fe_mul(h->X, h->X, u); /* x = uv^3(uv^7)^((q-5)/8) */ + fe_sq(vxx, h->X); + fe_mul(vxx, vxx, v); + fe_sub(check, vxx, u); /* vx^2-u */ - if (fe_isnonzero(check)) { - fe_add(check, vxx, u); /* vx^2+u */ + if(fe_isnonzero(check)) { + fe_add(check, vxx, u); /* vx^2+u */ - if (fe_isnonzero(check)) { - return -1; - } + if(fe_isnonzero(check)) { + return -1; + } - fe_mul(h->X, h->X, sqrtm1); - } + fe_mul(h->X, h->X, sqrtm1); + } - if (fe_isnegative(h->X) == (s[31] >> 7)) { - fe_neg(h->X, h->X); - } + if(fe_isnegative(h->X) == (s[31] >> 7)) { + fe_neg(h->X, h->X); + } - fe_mul(h->T, h->X, h->Y); - return 0; + fe_mul(h->T, h->X, h->Y); + return 0; } @@ -186,17 +186,17 @@ r = p + q */ void ge_madd(ge_p1p1 *r, const ge_p3 *p, const ge_precomp *q) { - fe t0; - fe_add(r->X, p->Y, p->X); - fe_sub(r->Y, p->Y, p->X); - fe_mul(r->Z, r->X, q->yplusx); - fe_mul(r->Y, r->Y, q->yminusx); - fe_mul(r->T, q->xy2d, p->T); - fe_add(t0, p->Z, p->Z); - fe_sub(r->X, r->Z, r->Y); - fe_add(r->Y, r->Z, r->Y); - fe_add(r->Z, t0, r->T); - fe_sub(r->T, t0, r->T); + fe t0; + fe_add(r->X, p->Y, p->X); + fe_sub(r->Y, p->Y, p->X); + fe_mul(r->Z, r->X, q->yplusx); + fe_mul(r->Y, r->Y, q->yminusx); + fe_mul(r->T, q->xy2d, p->T); + fe_add(t0, p->Z, p->Z); + fe_sub(r->X, r->Z, r->Y); + fe_add(r->Y, r->Z, r->Y); + fe_add(r->Z, t0, r->T); + fe_sub(r->T, t0, r->T); } @@ -205,18 +205,18 @@ r = p - q */ void ge_msub(ge_p1p1 *r, const ge_p3 *p, const ge_precomp *q) { - fe t0; + fe t0; - fe_add(r->X, p->Y, p->X); - fe_sub(r->Y, p->Y, p->X); - fe_mul(r->Z, r->X, q->yminusx); - fe_mul(r->Y, r->Y, q->yplusx); - fe_mul(r->T, q->xy2d, p->T); - fe_add(t0, p->Z, p->Z); - fe_sub(r->X, r->Z, r->Y); - fe_add(r->Y, r->Z, r->Y); - fe_sub(r->Z, t0, r->T); - fe_add(r->T, t0, r->T); + fe_add(r->X, p->Y, p->X); + fe_sub(r->Y, p->Y, p->X); + fe_mul(r->Z, r->X, q->yminusx); + fe_mul(r->Y, r->Y, q->yplusx); + fe_mul(r->T, q->xy2d, p->T); + fe_add(t0, p->Z, p->Z); + fe_sub(r->X, r->Z, r->Y); + fe_add(r->Y, r->Z, r->Y); + fe_sub(r->Z, t0, r->T); + fe_add(r->T, t0, r->T); } @@ -225,9 +225,9 @@ r = p */ void ge_p1p1_to_p2(ge_p2 *r, const ge_p1p1 *p) { - fe_mul(r->X, p->X, p->T); - fe_mul(r->Y, p->Y, p->Z); - fe_mul(r->Z, p->Z, p->T); + fe_mul(r->X, p->X, p->T); + fe_mul(r->Y, p->Y, p->Z); + fe_mul(r->Z, p->Z, p->T); } @@ -237,17 +237,17 @@ r = p */ void ge_p1p1_to_p3(ge_p3 *r, const ge_p1p1 *p) { - fe_mul(r->X, p->X, p->T); - fe_mul(r->Y, p->Y, p->Z); - fe_mul(r->Z, p->Z, p->T); - fe_mul(r->T, p->X, p->Y); + fe_mul(r->X, p->X, p->T); + fe_mul(r->Y, p->Y, p->Z); + fe_mul(r->Z, p->Z, p->T); + fe_mul(r->T, p->X, p->Y); } void ge_p2_0(ge_p2 *h) { - fe_0(h->X); - fe_1(h->Y); - fe_1(h->Z); + fe_0(h->X); + fe_1(h->Y); + fe_1(h->Z); } @@ -257,25 +257,25 @@ r = 2 * p */ void ge_p2_dbl(ge_p1p1 *r, const ge_p2 *p) { - fe t0; + fe t0; - fe_sq(r->X, p->X); - fe_sq(r->Z, p->Y); - fe_sq2(r->T, p->Z); - fe_add(r->Y, p->X, p->Y); - fe_sq(t0, r->Y); - fe_add(r->Y, r->Z, r->X); - fe_sub(r->Z, r->Z, r->X); - fe_sub(r->X, t0, r->Y); - fe_sub(r->T, r->T, r->Z); + fe_sq(r->X, p->X); + fe_sq(r->Z, p->Y); + fe_sq2(r->T, p->Z); + fe_add(r->Y, p->X, p->Y); + fe_sq(t0, r->Y); + fe_add(r->Y, r->Z, r->X); + fe_sub(r->Z, r->Z, r->X); + fe_sub(r->X, t0, r->Y); + fe_sub(r->T, r->T, r->Z); } void ge_p3_0(ge_p3 *h) { - fe_0(h->X); - fe_1(h->Y); - fe_1(h->Z); - fe_0(h->T); + fe_0(h->X); + fe_1(h->Y); + fe_1(h->Z); + fe_0(h->T); } @@ -284,9 +284,9 @@ r = 2 * p */ void ge_p3_dbl(ge_p1p1 *r, const ge_p3 *p) { - ge_p2 q; - ge_p3_to_p2(&q, p); - ge_p2_dbl(r, &q); + ge_p2 q; + ge_p3_to_p2(&q, p); + ge_p2_dbl(r, &q); } @@ -296,14 +296,14 @@ r = p */ static const fe d2 = { - -21827239, -5839606, -30745221, 13898782, 229458, 15978800, -12551817, -6495438, 29715968, 9444199 -}; + -21827239, -5839606, -30745221, 13898782, 229458, 15978800, -12551817, -6495438, 29715968, 9444199 + }; void ge_p3_to_cached(ge_cached *r, const ge_p3 *p) { - fe_add(r->YplusX, p->Y, p->X); - fe_sub(r->YminusX, p->Y, p->X); - fe_copy(r->Z, p->Z); - fe_mul(r->T2d, p->T, d2); + fe_add(r->YplusX, p->Y, p->X); + fe_sub(r->YminusX, p->Y, p->X); + fe_copy(r->Z, p->Z); + fe_mul(r->T2d, p->T, d2); } @@ -312,66 +312,66 @@ r = p */ void ge_p3_to_p2(ge_p2 *r, const ge_p3 *p) { - fe_copy(r->X, p->X); - fe_copy(r->Y, p->Y); - fe_copy(r->Z, p->Z); + fe_copy(r->X, p->X); + fe_copy(r->Y, p->Y); + fe_copy(r->Z, p->Z); } void ge_p3_tobytes(unsigned char *s, const ge_p3 *h) { - fe recip; - fe x; - fe y; - fe_invert(recip, h->Z); - fe_mul(x, h->X, recip); - fe_mul(y, h->Y, recip); - fe_tobytes(s, y); - s[31] ^= fe_isnegative(x) << 7; + fe recip; + fe x; + fe y; + fe_invert(recip, h->Z); + fe_mul(x, h->X, recip); + fe_mul(y, h->Y, recip); + fe_tobytes(s, y); + s[31] ^= fe_isnegative(x) << 7; } static unsigned char equal(signed char b, signed char c) { - unsigned char ub = b; - unsigned char uc = c; - unsigned char x = ub ^ uc; /* 0: yes; 1..255: no */ - uint64_t y = x; /* 0: yes; 1..255: no */ - y -= 1; /* large: yes; 0..254: no */ - y >>= 63; /* 1: yes; 0: no */ - return (unsigned char) y; + unsigned char ub = b; + unsigned char uc = c; + unsigned char x = ub ^ uc; /* 0: yes; 1..255: no */ + uint64_t y = x; /* 0: yes; 1..255: no */ + y -= 1; /* large: yes; 0..254: no */ + y >>= 63; /* 1: yes; 0: no */ + return (unsigned char) y; } static unsigned char negative(signed char b) { - uint64_t x = b; /* 18446744073709551361..18446744073709551615: yes; 0..255: no */ - x >>= 63; /* 1: yes; 0: no */ - return (unsigned char) x; + uint64_t x = b; /* 18446744073709551361..18446744073709551615: yes; 0..255: no */ + x >>= 63; /* 1: yes; 0: no */ + return (unsigned char) x; } static void cmov(ge_precomp *t, ge_precomp *u, unsigned char b) { - fe_cmov(t->yplusx, u->yplusx, b); - fe_cmov(t->yminusx, u->yminusx, b); - fe_cmov(t->xy2d, u->xy2d, b); + fe_cmov(t->yplusx, u->yplusx, b); + fe_cmov(t->yminusx, u->yminusx, b); + fe_cmov(t->xy2d, u->xy2d, b); } static void select(ge_precomp *t, int pos, signed char b) { - ge_precomp minust; - unsigned char bnegative = negative(b); - unsigned char babs = b - shlu8(((-bnegative) & b), 1); - fe_1(t->yplusx); - fe_1(t->yminusx); - fe_0(t->xy2d); - cmov(t, &base[pos][0], equal(babs, 1)); - cmov(t, &base[pos][1], equal(babs, 2)); - cmov(t, &base[pos][2], equal(babs, 3)); - cmov(t, &base[pos][3], equal(babs, 4)); - cmov(t, &base[pos][4], equal(babs, 5)); - cmov(t, &base[pos][5], equal(babs, 6)); - cmov(t, &base[pos][6], equal(babs, 7)); - cmov(t, &base[pos][7], equal(babs, 8)); - fe_copy(minust.yplusx, t->yminusx); - fe_copy(minust.yminusx, t->yplusx); - fe_neg(minust.xy2d, t->xy2d); - cmov(t, &minust, bnegative); + ge_precomp minust; + unsigned char bnegative = negative(b); + unsigned char babs = b - shlu8(((-bnegative) & b), 1); + fe_1(t->yplusx); + fe_1(t->yminusx); + fe_0(t->xy2d); + cmov(t, &base[pos][0], equal(babs, 1)); + cmov(t, &base[pos][1], equal(babs, 2)); + cmov(t, &base[pos][2], equal(babs, 3)); + cmov(t, &base[pos][3], equal(babs, 4)); + cmov(t, &base[pos][4], equal(babs, 5)); + cmov(t, &base[pos][5], equal(babs, 6)); + cmov(t, &base[pos][6], equal(babs, 7)); + cmov(t, &base[pos][7], equal(babs, 8)); + fe_copy(minust.yplusx, t->yminusx); + fe_copy(minust.yminusx, t->yplusx); + fe_neg(minust.xy2d, t->xy2d); + cmov(t, &minust, bnegative); } /* @@ -384,53 +384,53 @@ Preconditions: */ void ge_scalarmult_base(ge_p3 *h, const unsigned char *a) { - signed char e[64]; - signed char carry; - ge_p1p1 r; - ge_p2 s; - ge_precomp t; - int i; + signed char e[64]; + signed char carry; + ge_p1p1 r; + ge_p2 s; + ge_precomp t; + int i; - for (i = 0; i < 32; ++i) { - e[2 * i + 0] = (a[i] >> 0) & 15; - e[2 * i + 1] = (a[i] >> 4) & 15; - } + for(i = 0; i < 32; ++i) { + e[2 * i + 0] = (a[i] >> 0) & 15; + e[2 * i + 1] = (a[i] >> 4) & 15; + } - /* each e[i] is between 0 and 15 */ - /* e[63] is between 0 and 7 */ - carry = 0; + /* each e[i] is between 0 and 15 */ + /* e[63] is between 0 and 7 */ + carry = 0; - for (i = 0; i < 63; ++i) { - e[i] += carry; - carry = e[i] + 8; - carry >>= 4; - e[i] -= shl32(carry, 4); - } + for(i = 0; i < 63; ++i) { + e[i] += carry; + carry = e[i] + 8; + carry >>= 4; + e[i] -= shl32(carry, 4); + } - e[63] += carry; - /* each e[i] is between -8 and 8 */ - ge_p3_0(h); + e[63] += carry; + /* each e[i] is between -8 and 8 */ + ge_p3_0(h); - for (i = 1; i < 64; i += 2) { - select(&t, i / 2, e[i]); - ge_madd(&r, h, &t); - ge_p1p1_to_p3(h, &r); - } + for(i = 1; i < 64; i += 2) { + select(&t, i / 2, e[i]); + ge_madd(&r, h, &t); + ge_p1p1_to_p3(h, &r); + } - ge_p3_dbl(&r, h); - ge_p1p1_to_p2(&s, &r); - ge_p2_dbl(&r, &s); - ge_p1p1_to_p2(&s, &r); - ge_p2_dbl(&r, &s); - ge_p1p1_to_p2(&s, &r); - ge_p2_dbl(&r, &s); - ge_p1p1_to_p3(h, &r); + ge_p3_dbl(&r, h); + ge_p1p1_to_p2(&s, &r); + ge_p2_dbl(&r, &s); + ge_p1p1_to_p2(&s, &r); + ge_p2_dbl(&r, &s); + ge_p1p1_to_p2(&s, &r); + ge_p2_dbl(&r, &s); + ge_p1p1_to_p3(h, &r); - for (i = 0; i < 64; i += 2) { - select(&t, i / 2, e[i]); - ge_madd(&r, h, &t); - ge_p1p1_to_p3(h, &r); - } + for(i = 0; i < 64; i += 2) { + select(&t, i / 2, e[i]); + ge_madd(&r, h, &t); + ge_p1p1_to_p3(h, &r); + } } @@ -439,29 +439,29 @@ r = p - q */ void ge_sub(ge_p1p1 *r, const ge_p3 *p, const ge_cached *q) { - fe t0; - - fe_add(r->X, p->Y, p->X); - fe_sub(r->Y, p->Y, p->X); - fe_mul(r->Z, r->X, q->YminusX); - fe_mul(r->Y, r->Y, q->YplusX); - fe_mul(r->T, q->T2d, p->T); - fe_mul(r->X, p->Z, q->Z); - fe_add(t0, r->X, r->X); - fe_sub(r->X, r->Z, r->Y); - fe_add(r->Y, r->Z, r->Y); - fe_sub(r->Z, t0, r->T); - fe_add(r->T, t0, r->T); + fe t0; + + fe_add(r->X, p->Y, p->X); + fe_sub(r->Y, p->Y, p->X); + fe_mul(r->Z, r->X, q->YminusX); + fe_mul(r->Y, r->Y, q->YplusX); + fe_mul(r->T, q->T2d, p->T); + fe_mul(r->X, p->Z, q->Z); + fe_add(t0, r->X, r->X); + fe_sub(r->X, r->Z, r->Y); + fe_add(r->Y, r->Z, r->Y); + fe_sub(r->Z, t0, r->T); + fe_add(r->T, t0, r->T); } void ge_tobytes(unsigned char *s, const ge_p2 *h) { - fe recip; - fe x; - fe y; - fe_invert(recip, h->Z); - fe_mul(x, h->X, recip); - fe_mul(y, h->Y, recip); - fe_tobytes(s, y); - s[31] ^= fe_isnegative(x) << 7; + fe recip; + fe x; + fe y; + fe_invert(recip, h->Z); + fe_mul(x, h->X, recip); + fe_mul(y, h->Y, recip); + fe_tobytes(s, y); + s[31] ^= fe_isnegative(x) << 7; } diff --git a/src/ed25519/ge.h b/src/ed25519/ge.h index 17fde2d..9cc3b98 100644 --- a/src/ed25519/ge.h +++ b/src/ed25519/ge.h @@ -19,36 +19,36 @@ Representations: */ typedef struct { - fe X; - fe Y; - fe Z; + fe X; + fe Y; + fe Z; } ge_p2; typedef struct { - fe X; - fe Y; - fe Z; - fe T; + fe X; + fe Y; + fe Z; + fe T; } ge_p3; typedef struct { - fe X; - fe Y; - fe Z; - fe T; + fe X; + fe Y; + fe Z; + fe T; } ge_p1p1; typedef struct { - fe yplusx; - fe yminusx; - fe xy2d; + fe yplusx; + fe yminusx; + fe xy2d; } ge_precomp; typedef struct { - fe YplusX; - fe YminusX; - fe Z; - fe T2d; + fe YplusX; + fe YminusX; + fe Z; + fe T2d; } ge_cached; void ge_p3_tobytes(unsigned char *s, const ge_p3 *h); diff --git a/src/ed25519/key_exchange.c b/src/ed25519/key_exchange.c index abd75da..9ace86b 100644 --- a/src/ed25519/key_exchange.c +++ b/src/ed25519/key_exchange.c @@ -2,78 +2,79 @@ #include "fe.h" void ed25519_key_exchange(unsigned char *shared_secret, const unsigned char *public_key, const unsigned char *private_key) { - unsigned char e[32]; - unsigned int i; - - fe x1; - fe x2; - fe z2; - fe x3; - fe z3; - fe tmp0; - fe tmp1; + unsigned char e[32]; + unsigned int i; - int pos; - unsigned int swap; - unsigned int b; + fe x1; + fe x2; + fe z2; + fe x3; + fe z3; + fe tmp0; + fe tmp1; - /* copy the private key and make sure it's valid */ - for (i = 0; i < 32; ++i) { - e[i] = private_key[i]; - } + int pos; + unsigned int swap; + unsigned int b; - e[0] &= 248; - e[31] &= 63; - e[31] |= 64; + /* copy the private key and make sure it's valid */ + for(i = 0; i < 32; ++i) { + e[i] = private_key[i]; + } - /* unpack the public key and convert edwards to montgomery */ - /* due to CodesInChaos: montgomeryX = (edwardsY + 1)*inverse(1 - edwardsY) mod p */ - fe_frombytes(x1, public_key); - fe_1(tmp1); - fe_add(tmp0, x1, tmp1); - fe_sub(tmp1, tmp1, x1); - fe_invert(tmp1, tmp1); - fe_mul(x1, tmp0, tmp1); + e[0] &= 248; + e[31] &= 63; + e[31] |= 64; - fe_1(x2); - fe_0(z2); - fe_copy(x3, x1); - fe_1(z3); + /* unpack the public key and convert edwards to montgomery */ + /* due to CodesInChaos: montgomeryX = (edwardsY + 1)*inverse(1 - edwardsY) mod p */ + fe_frombytes(x1, public_key); + fe_1(tmp1); + fe_add(tmp0, x1, tmp1); + fe_sub(tmp1, tmp1, x1); + fe_invert(tmp1, tmp1); + fe_mul(x1, tmp0, tmp1); - swap = 0; - for (pos = 254; pos >= 0; --pos) { - b = e[pos / 8] >> (pos & 7); - b &= 1; - swap ^= b; - fe_cswap(x2, x3, swap); - fe_cswap(z2, z3, swap); - swap = b; + fe_1(x2); + fe_0(z2); + fe_copy(x3, x1); + fe_1(z3); - /* from montgomery.h */ - fe_sub(tmp0, x3, z3); - fe_sub(tmp1, x2, z2); - fe_add(x2, x2, z2); - fe_add(z2, x3, z3); - fe_mul(z3, tmp0, x2); - fe_mul(z2, z2, tmp1); - fe_sq(tmp0, tmp1); - fe_sq(tmp1, x2); - fe_add(x3, z3, z2); - fe_sub(z2, z3, z2); - fe_mul(x2, tmp1, tmp0); - fe_sub(tmp1, tmp1, tmp0); - fe_sq(z2, z2); - fe_mul121666(z3, tmp1); - fe_sq(x3, x3); - fe_add(tmp0, tmp0, z3); - fe_mul(z3, x1, z2); - fe_mul(z2, tmp1, tmp0); - } + swap = 0; - fe_cswap(x2, x3, swap); - fe_cswap(z2, z3, swap); + for(pos = 254; pos >= 0; --pos) { + b = e[pos / 8] >> (pos & 7); + b &= 1; + swap ^= b; + fe_cswap(x2, x3, swap); + fe_cswap(z2, z3, swap); + swap = b; - fe_invert(z2, z2); - fe_mul(x2, x2, z2); - fe_tobytes(shared_secret, x2); + /* from montgomery.h */ + fe_sub(tmp0, x3, z3); + fe_sub(tmp1, x2, z2); + fe_add(x2, x2, z2); + fe_add(z2, x3, z3); + fe_mul(z3, tmp0, x2); + fe_mul(z2, z2, tmp1); + fe_sq(tmp0, tmp1); + fe_sq(tmp1, x2); + fe_add(x3, z3, z2); + fe_sub(z2, z3, z2); + fe_mul(x2, tmp1, tmp0); + fe_sub(tmp1, tmp1, tmp0); + fe_sq(z2, z2); + fe_mul121666(z3, tmp1); + fe_sq(x3, x3); + fe_add(tmp0, tmp0, z3); + fe_mul(z3, x1, z2); + fe_mul(z2, tmp1, tmp0); + } + + fe_cswap(x2, x3, swap); + fe_cswap(z2, z3, swap); + + fe_invert(z2, z2); + fe_mul(x2, x2, z2); + fe_tobytes(shared_secret, x2); } diff --git a/src/ed25519/keypair.c b/src/ed25519/keypair.c index dc1b8ec..71ec4d7 100644 --- a/src/ed25519/keypair.c +++ b/src/ed25519/keypair.c @@ -4,13 +4,13 @@ void ed25519_create_keypair(unsigned char *public_key, unsigned char *private_key, const unsigned char *seed) { - ge_p3 A; + ge_p3 A; - sha512(seed, 32, private_key); - private_key[0] &= 248; - private_key[31] &= 63; - private_key[31] |= 64; + sha512(seed, 32, private_key); + private_key[0] &= 248; + private_key[31] &= 63; + private_key[31] |= 64; - ge_scalarmult_base(&A, private_key); - ge_p3_tobytes(public_key, &A); + ge_scalarmult_base(&A, private_key); + ge_p3_tobytes(public_key, &A); } diff --git a/src/ed25519/precomp_data.h b/src/ed25519/precomp_data.h index ce59788..7a29302 100644 --- a/src/ed25519/precomp_data.h +++ b/src/ed25519/precomp_data.h @@ -1,1391 +1,1391 @@ static ge_precomp Bi[8] = { - { - { 25967493, -14356035, 29566456, 3660896, -12694345, 4014787, 27544626, -11754271, -6079156, 2047605 }, - { -12545711, 934262, -2722910, 3049990, -727428, 9406986, 12720692, 5043384, 19500929, -15469378 }, - { -8738181, 4489570, 9688441, -14785194, 10184609, -12363380, 29287919, 11864899, -24514362, -4438546 }, - }, - { - { 15636291, -9688557, 24204773, -7912398, 616977, -16685262, 27787600, -14772189, 28944400, -1550024 }, - { 16568933, 4717097, -11556148, -1102322, 15682896, -11807043, 16354577, -11775962, 7689662, 11199574 }, - { 30464156, -5976125, -11779434, -15670865, 23220365, 15915852, 7512774, 10017326, -17749093, -9920357 }, - }, - { - { 10861363, 11473154, 27284546, 1981175, -30064349, 12577861, 32867885, 14515107, -15438304, 10819380 }, - { 4708026, 6336745, 20377586, 9066809, -11272109, 6594696, -25653668, 12483688, -12668491, 5581306 }, - { 19563160, 16186464, -29386857, 4097519, 10237984, -4348115, 28542350, 13850243, -23678021, -15815942 }, - }, - { - { 5153746, 9909285, 1723747, -2777874, 30523605, 5516873, 19480852, 5230134, -23952439, -15175766 }, - { -30269007, -3463509, 7665486, 10083793, 28475525, 1649722, 20654025, 16520125, 30598449, 7715701 }, - { 28881845, 14381568, 9657904, 3680757, -20181635, 7843316, -31400660, 1370708, 29794553, -1409300 }, - }, - { - { -22518993, -6692182, 14201702, -8745502, -23510406, 8844726, 18474211, -1361450, -13062696, 13821877 }, - { -6455177, -7839871, 3374702, -4740862, -27098617, -10571707, 31655028, -7212327, 18853322, -14220951 }, - { 4566830, -12963868, -28974889, -12240689, -7602672, -2830569, -8514358, -10431137, 2207753, -3209784 }, - }, - { - { -25154831, -4185821, 29681144, 7868801, -6854661, -9423865, -12437364, -663000, -31111463, -16132436 }, - { 25576264, -2703214, 7349804, -11814844, 16472782, 9300885, 3844789, 15725684, 171356, 6466918 }, - { 23103977, 13316479, 9739013, -16149481, 817875, -15038942, 8965339, -14088058, -30714912, 16193877 }, - }, - { - { -33521811, 3180713, -2394130, 14003687, -16903474, -16270840, 17238398, 4729455, -18074513, 9256800 }, - { -25182317, -4174131, 32336398, 5036987, -21236817, 11360617, 22616405, 9761698, -19827198, 630305 }, - { -13720693, 2639453, -24237460, -7406481, 9494427, -5774029, -6554551, -15960994, -2449256, -14291300 }, - }, - { - { -3151181, -5046075, 9282714, 6866145, -31907062, -863023, -18940575, 15033784, 25105118, -7894876 }, - { -24326370, 15950226, -31801215, -14592823, -11662737, -5090925, 1573892, -2625887, 2198790, -15804619 }, - { -3099351, 10324967, -2241613, 7453183, -5446979, -2735503, -13812022, -16236442, -32461234, -12290683 }, - }, + { + { 25967493, -14356035, 29566456, 3660896, -12694345, 4014787, 27544626, -11754271, -6079156, 2047605 }, + { -12545711, 934262, -2722910, 3049990, -727428, 9406986, 12720692, 5043384, 19500929, -15469378 }, + { -8738181, 4489570, 9688441, -14785194, 10184609, -12363380, 29287919, 11864899, -24514362, -4438546 }, + }, + { + { 15636291, -9688557, 24204773, -7912398, 616977, -16685262, 27787600, -14772189, 28944400, -1550024 }, + { 16568933, 4717097, -11556148, -1102322, 15682896, -11807043, 16354577, -11775962, 7689662, 11199574 }, + { 30464156, -5976125, -11779434, -15670865, 23220365, 15915852, 7512774, 10017326, -17749093, -9920357 }, + }, + { + { 10861363, 11473154, 27284546, 1981175, -30064349, 12577861, 32867885, 14515107, -15438304, 10819380 }, + { 4708026, 6336745, 20377586, 9066809, -11272109, 6594696, -25653668, 12483688, -12668491, 5581306 }, + { 19563160, 16186464, -29386857, 4097519, 10237984, -4348115, 28542350, 13850243, -23678021, -15815942 }, + }, + { + { 5153746, 9909285, 1723747, -2777874, 30523605, 5516873, 19480852, 5230134, -23952439, -15175766 }, + { -30269007, -3463509, 7665486, 10083793, 28475525, 1649722, 20654025, 16520125, 30598449, 7715701 }, + { 28881845, 14381568, 9657904, 3680757, -20181635, 7843316, -31400660, 1370708, 29794553, -1409300 }, + }, + { + { -22518993, -6692182, 14201702, -8745502, -23510406, 8844726, 18474211, -1361450, -13062696, 13821877 }, + { -6455177, -7839871, 3374702, -4740862, -27098617, -10571707, 31655028, -7212327, 18853322, -14220951 }, + { 4566830, -12963868, -28974889, -12240689, -7602672, -2830569, -8514358, -10431137, 2207753, -3209784 }, + }, + { + { -25154831, -4185821, 29681144, 7868801, -6854661, -9423865, -12437364, -663000, -31111463, -16132436 }, + { 25576264, -2703214, 7349804, -11814844, 16472782, 9300885, 3844789, 15725684, 171356, 6466918 }, + { 23103977, 13316479, 9739013, -16149481, 817875, -15038942, 8965339, -14088058, -30714912, 16193877 }, + }, + { + { -33521811, 3180713, -2394130, 14003687, -16903474, -16270840, 17238398, 4729455, -18074513, 9256800 }, + { -25182317, -4174131, 32336398, 5036987, -21236817, 11360617, 22616405, 9761698, -19827198, 630305 }, + { -13720693, 2639453, -24237460, -7406481, 9494427, -5774029, -6554551, -15960994, -2449256, -14291300 }, + }, + { + { -3151181, -5046075, 9282714, 6866145, -31907062, -863023, -18940575, 15033784, 25105118, -7894876 }, + { -24326370, 15950226, -31801215, -14592823, -11662737, -5090925, 1573892, -2625887, 2198790, -15804619 }, + { -3099351, 10324967, -2241613, 7453183, -5446979, -2735503, -13812022, -16236442, -32461234, -12290683 }, + }, }; /* base[i][j] = (j+1)*256^i*B */ static ge_precomp base[32][8] = { - { - { - { 25967493, -14356035, 29566456, 3660896, -12694345, 4014787, 27544626, -11754271, -6079156, 2047605 }, - { -12545711, 934262, -2722910, 3049990, -727428, 9406986, 12720692, 5043384, 19500929, -15469378 }, - { -8738181, 4489570, 9688441, -14785194, 10184609, -12363380, 29287919, 11864899, -24514362, -4438546 }, - }, - { - { -12815894, -12976347, -21581243, 11784320, -25355658, -2750717, -11717903, -3814571, -358445, -10211303 }, - { -21703237, 6903825, 27185491, 6451973, -29577724, -9554005, -15616551, 11189268, -26829678, -5319081 }, - { 26966642, 11152617, 32442495, 15396054, 14353839, -12752335, -3128826, -9541118, -15472047, -4166697 }, - }, - { - { 15636291, -9688557, 24204773, -7912398, 616977, -16685262, 27787600, -14772189, 28944400, -1550024 }, - { 16568933, 4717097, -11556148, -1102322, 15682896, -11807043, 16354577, -11775962, 7689662, 11199574 }, - { 30464156, -5976125, -11779434, -15670865, 23220365, 15915852, 7512774, 10017326, -17749093, -9920357 }, - }, - { - { -17036878, 13921892, 10945806, -6033431, 27105052, -16084379, -28926210, 15006023, 3284568, -6276540 }, - { 23599295, -8306047, -11193664, -7687416, 13236774, 10506355, 7464579, 9656445, 13059162, 10374397 }, - { 7798556, 16710257, 3033922, 2874086, 28997861, 2835604, 32406664, -3839045, -641708, -101325 }, - }, - { - { 10861363, 11473154, 27284546, 1981175, -30064349, 12577861, 32867885, 14515107, -15438304, 10819380 }, - { 4708026, 6336745, 20377586, 9066809, -11272109, 6594696, -25653668, 12483688, -12668491, 5581306 }, - { 19563160, 16186464, -29386857, 4097519, 10237984, -4348115, 28542350, 13850243, -23678021, -15815942 }, - }, - { - { -15371964, -12862754, 32573250, 4720197, -26436522, 5875511, -19188627, -15224819, -9818940, -12085777 }, - { -8549212, 109983, 15149363, 2178705, 22900618, 4543417, 3044240, -15689887, 1762328, 14866737 }, - { -18199695, -15951423, -10473290, 1707278, -17185920, 3916101, -28236412, 3959421, 27914454, 4383652 }, - }, - { - { 5153746, 9909285, 1723747, -2777874, 30523605, 5516873, 19480852, 5230134, -23952439, -15175766 }, - { -30269007, -3463509, 7665486, 10083793, 28475525, 1649722, 20654025, 16520125, 30598449, 7715701 }, - { 28881845, 14381568, 9657904, 3680757, -20181635, 7843316, -31400660, 1370708, 29794553, -1409300 }, - }, - { - { 14499471, -2729599, -33191113, -4254652, 28494862, 14271267, 30290735, 10876454, -33154098, 2381726 }, - { -7195431, -2655363, -14730155, 462251, -27724326, 3941372, -6236617, 3696005, -32300832, 15351955 }, - { 27431194, 8222322, 16448760, -3907995, -18707002, 11938355, -32961401, -2970515, 29551813, 10109425 }, - }, - }, - { - { - { -13657040, -13155431, -31283750, 11777098, 21447386, 6519384, -2378284, -1627556, 10092783, -4764171 }, - { 27939166, 14210322, 4677035, 16277044, -22964462, -12398139, -32508754, 12005538, -17810127, 12803510 }, - { 17228999, -15661624, -1233527, 300140, -1224870, -11714777, 30364213, -9038194, 18016357, 4397660 }, - }, - { - { -10958843, -7690207, 4776341, -14954238, 27850028, -15602212, -26619106, 14544525, -17477504, 982639 }, - { 29253598, 15796703, -2863982, -9908884, 10057023, 3163536, 7332899, -4120128, -21047696, 9934963 }, - { 5793303, 16271923, -24131614, -10116404, 29188560, 1206517, -14747930, 4559895, -30123922, -10897950 }, - }, - { - { -27643952, -11493006, 16282657, -11036493, 28414021, -15012264, 24191034, 4541697, -13338309, 5500568 }, - { 12650548, -1497113, 9052871, 11355358, -17680037, -8400164, -17430592, 12264343, 10874051, 13524335 }, - { 25556948, -3045990, 714651, 2510400, 23394682, -10415330, 33119038, 5080568, -22528059, 5376628 }, - }, - { - { -26088264, -4011052, -17013699, -3537628, -6726793, 1920897, -22321305, -9447443, 4535768, 1569007 }, - { -2255422, 14606630, -21692440, -8039818, 28430649, 8775819, -30494562, 3044290, 31848280, 12543772 }, - { -22028579, 2943893, -31857513, 6777306, 13784462, -4292203, -27377195, -2062731, 7718482, 14474653 }, - }, - { - { 2385315, 2454213, -22631320, 46603, -4437935, -15680415, 656965, -7236665, 24316168, -5253567 }, - { 13741529, 10911568, -33233417, -8603737, -20177830, -1033297, 33040651, -13424532, -20729456, 8321686 }, - { 21060490, -2212744, 15712757, -4336099, 1639040, 10656336, 23845965, -11874838, -9984458, 608372 }, - }, - { - { -13672732, -15087586, -10889693, -7557059, -6036909, 11305547, 1123968, -6780577, 27229399, 23887 }, - { -23244140, -294205, -11744728, 14712571, -29465699, -2029617, 12797024, -6440308, -1633405, 16678954 }, - { -29500620, 4770662, -16054387, 14001338, 7830047, 9564805, -1508144, -4795045, -17169265, 4904953 }, - }, - { - { 24059557, 14617003, 19037157, -15039908, 19766093, -14906429, 5169211, 16191880, 2128236, -4326833 }, - { -16981152, 4124966, -8540610, -10653797, 30336522, -14105247, -29806336, 916033, -6882542, -2986532 }, - { -22630907, 12419372, -7134229, -7473371, -16478904, 16739175, 285431, 2763829, 15736322, 4143876 }, - }, - { - { 2379352, 11839345, -4110402, -5988665, 11274298, 794957, 212801, -14594663, 23527084, -16458268 }, - { 33431127, -11130478, -17838966, -15626900, 8909499, 8376530, -32625340, 4087881, -15188911, -14416214 }, - { 1767683, 7197987, -13205226, -2022635, -13091350, 448826, 5799055, 4357868, -4774191, -16323038 }, - }, - }, - { - { - { 6721966, 13833823, -23523388, -1551314, 26354293, -11863321, 23365147, -3949732, 7390890, 2759800 }, - { 4409041, 2052381, 23373853, 10530217, 7676779, -12885954, 21302353, -4264057, 1244380, -12919645 }, - { -4421239, 7169619, 4982368, -2957590, 30256825, -2777540, 14086413, 9208236, 15886429, 16489664 }, - }, - { - { 1996075, 10375649, 14346367, 13311202, -6874135, -16438411, -13693198, 398369, -30606455, -712933 }, - { -25307465, 9795880, -2777414, 14878809, -33531835, 14780363, 13348553, 12076947, -30836462, 5113182 }, - { -17770784, 11797796, 31950843, 13929123, -25888302, 12288344, -30341101, -7336386, 13847711, 5387222 }, - }, - { - { -18582163, -3416217, 17824843, -2340966, 22744343, -10442611, 8763061, 3617786, -19600662, 10370991 }, - { 20246567, -14369378, 22358229, -543712, 18507283, -10413996, 14554437, -8746092, 32232924, 16763880 }, - { 9648505, 10094563, 26416693, 14745928, -30374318, -6472621, 11094161, 15689506, 3140038, -16510092 }, - }, - { - { -16160072, 5472695, 31895588, 4744994, 8823515, 10365685, -27224800, 9448613, -28774454, 366295 }, - { 19153450, 11523972, -11096490, -6503142, -24647631, 5420647, 28344573, 8041113, 719605, 11671788 }, - { 8678025, 2694440, -6808014, 2517372, 4964326, 11152271, -15432916, -15266516, 27000813, -10195553 }, - }, - { - { -15157904, 7134312, 8639287, -2814877, -7235688, 10421742, 564065, 5336097, 6750977, -14521026 }, - { 11836410, -3979488, 26297894, 16080799, 23455045, 15735944, 1695823, -8819122, 8169720, 16220347 }, - { -18115838, 8653647, 17578566, -6092619, -8025777, -16012763, -11144307, -2627664, -5990708, -14166033 }, - }, - { - { -23308498, -10968312, 15213228, -10081214, -30853605, -11050004, 27884329, 2847284, 2655861, 1738395 }, - { -27537433, -14253021, -25336301, -8002780, -9370762, 8129821, 21651608, -3239336, -19087449, -11005278 }, - { 1533110, 3437855, 23735889, 459276, 29970501, 11335377, 26030092, 5821408, 10478196, 8544890 }, - }, - { - { 32173121, -16129311, 24896207, 3921497, 22579056, -3410854, 19270449, 12217473, 17789017, -3395995 }, - { -30552961, -2228401, -15578829, -10147201, 13243889, 517024, 15479401, -3853233, 30460520, 1052596 }, - { -11614875, 13323618, 32618793, 8175907, -15230173, 12596687, 27491595, -4612359, 3179268, -9478891 }, - }, - { - { 31947069, -14366651, -4640583, -15339921, -15125977, -6039709, -14756777, -16411740, 19072640, -9511060 }, - { 11685058, 11822410, 3158003, -13952594, 33402194, -4165066, 5977896, -5215017, 473099, 5040608 }, - { -20290863, 8198642, -27410132, 11602123, 1290375, -2799760, 28326862, 1721092, -19558642, -3131606 }, - }, - }, - { - { - { 7881532, 10687937, 7578723, 7738378, -18951012, -2553952, 21820786, 8076149, -27868496, 11538389 }, - { -19935666, 3899861, 18283497, -6801568, -15728660, -11249211, 8754525, 7446702, -5676054, 5797016 }, - { -11295600, -3793569, -15782110, -7964573, 12708869, -8456199, 2014099, -9050574, -2369172, -5877341 }, - }, - { - { -22472376, -11568741, -27682020, 1146375, 18956691, 16640559, 1192730, -3714199, 15123619, 10811505 }, - { 14352098, -3419715, -18942044, 10822655, 32750596, 4699007, -70363, 15776356, -28886779, -11974553 }, - { -28241164, -8072475, -4978962, -5315317, 29416931, 1847569, -20654173, -16484855, 4714547, -9600655 }, - }, - { - { 15200332, 8368572, 19679101, 15970074, -31872674, 1959451, 24611599, -4543832, -11745876, 12340220 }, - { 12876937, -10480056, 33134381, 6590940, -6307776, 14872440, 9613953, 8241152, 15370987, 9608631 }, - { -4143277, -12014408, 8446281, -391603, 4407738, 13629032, -7724868, 15866074, -28210621, -8814099 }, - }, - { - { 26660628, -15677655, 8393734, 358047, -7401291, 992988, -23904233, 858697, 20571223, 8420556 }, - { 14620715, 13067227, -15447274, 8264467, 14106269, 15080814, 33531827, 12516406, -21574435, -12476749 }, - { 236881, 10476226, 57258, -14677024, 6472998, 2466984, 17258519, 7256740, 8791136, 15069930 }, - }, - { - { 1276410, -9371918, 22949635, -16322807, -23493039, -5702186, 14711875, 4874229, -30663140, -2331391 }, - { 5855666, 4990204, -13711848, 7294284, -7804282, 1924647, -1423175, -7912378, -33069337, 9234253 }, - { 20590503, -9018988, 31529744, -7352666, -2706834, 10650548, 31559055, -11609587, 18979186, 13396066 }, - }, - { - { 24474287, 4968103, 22267082, 4407354, 24063882, -8325180, -18816887, 13594782, 33514650, 7021958 }, - { -11566906, -6565505, -21365085, 15928892, -26158305, 4315421, -25948728, -3916677, -21480480, 12868082 }, - { -28635013, 13504661, 19988037, -2132761, 21078225, 6443208, -21446107, 2244500, -12455797, -8089383 }, - }, - { - { -30595528, 13793479, -5852820, 319136, -25723172, -6263899, 33086546, 8957937, -15233648, 5540521 }, - { -11630176, -11503902, -8119500, -7643073, 2620056, 1022908, -23710744, -1568984, -16128528, -14962807 }, - { 23152971, 775386, 27395463, 14006635, -9701118, 4649512, 1689819, 892185, -11513277, -15205948 }, - }, - { - { 9770129, 9586738, 26496094, 4324120, 1556511, -3550024, 27453819, 4763127, -19179614, 5867134 }, - { -32765025, 1927590, 31726409, -4753295, 23962434, -16019500, 27846559, 5931263, -29749703, -16108455 }, - { 27461885, -2977536, 22380810, 1815854, -23033753, -3031938, 7283490, -15148073, -19526700, 7734629 }, - }, - }, - { - { - { -8010264, -9590817, -11120403, 6196038, 29344158, -13430885, 7585295, -3176626, 18549497, 15302069 }, - { -32658337, -6171222, -7672793, -11051681, 6258878, 13504381, 10458790, -6418461, -8872242, 8424746 }, - { 24687205, 8613276, -30667046, -3233545, 1863892, -1830544, 19206234, 7134917, -11284482, -828919 }, - }, - { - { 11334899, -9218022, 8025293, 12707519, 17523892, -10476071, 10243738, -14685461, -5066034, 16498837 }, - { 8911542, 6887158, -9584260, -6958590, 11145641, -9543680, 17303925, -14124238, 6536641, 10543906 }, - { -28946384, 15479763, -17466835, 568876, -1497683, 11223454, -2669190, -16625574, -27235709, 8876771 }, - }, - { - { -25742899, -12566864, -15649966, -846607, -33026686, -796288, -33481822, 15824474, -604426, -9039817 }, - { 10330056, 70051, 7957388, -9002667, 9764902, 15609756, 27698697, -4890037, 1657394, 3084098 }, - { 10477963, -7470260, 12119566, -13250805, 29016247, -5365589, 31280319, 14396151, -30233575, 15272409 }, - }, - { - { -12288309, 3169463, 28813183, 16658753, 25116432, -5630466, -25173957, -12636138, -25014757, 1950504 }, - { -26180358, 9489187, 11053416, -14746161, -31053720, 5825630, -8384306, -8767532, 15341279, 8373727 }, - { 28685821, 7759505, -14378516, -12002860, -31971820, 4079242, 298136, -10232602, -2878207, 15190420 }, - }, - { - { -32932876, 13806336, -14337485, -15794431, -24004620, 10940928, 8669718, 2742393, -26033313, -6875003 }, - { -1580388, -11729417, -25979658, -11445023, -17411874, -10912854, 9291594, -16247779, -12154742, 6048605 }, - { -30305315, 14843444, 1539301, 11864366, 20201677, 1900163, 13934231, 5128323, 11213262, 9168384 }, - }, - { - { -26280513, 11007847, 19408960, -940758, -18592965, -4328580, -5088060, -11105150, 20470157, -16398701 }, - { -23136053, 9282192, 14855179, -15390078, -7362815, -14408560, -22783952, 14461608, 14042978, 5230683 }, - { 29969567, -2741594, -16711867, -8552442, 9175486, -2468974, 21556951, 3506042, -5933891, -12449708 }, - }, - { - { -3144746, 8744661, 19704003, 4581278, -20430686, 6830683, -21284170, 8971513, -28539189, 15326563 }, - { -19464629, 10110288, -17262528, -3503892, -23500387, 1355669, -15523050, 15300988, -20514118, 9168260 }, - { -5353335, 4488613, -23803248, 16314347, 7780487, -15638939, -28948358, 9601605, 33087103, -9011387 }, - }, - { - { -19443170, -15512900, -20797467, -12445323, -29824447, 10229461, -27444329, -15000531, -5996870, 15664672 }, - { 23294591, -16632613, -22650781, -8470978, 27844204, 11461195, 13099750, -2460356, 18151676, 13417686 }, - { -24722913, -4176517, -31150679, 5988919, -26858785, 6685065, 1661597, -12551441, 15271676, -15452665 }, - }, - }, - { - { - { 11433042, -13228665, 8239631, -5279517, -1985436, -725718, -18698764, 2167544, -6921301, -13440182 }, - { -31436171, 15575146, 30436815, 12192228, -22463353, 9395379, -9917708, -8638997, 12215110, 12028277 }, - { 14098400, 6555944, 23007258, 5757252, -15427832, -12950502, 30123440, 4617780, -16900089, -655628 }, - }, - { - { -4026201, -15240835, 11893168, 13718664, -14809462, 1847385, -15819999, 10154009, 23973261, -12684474 }, - { -26531820, -3695990, -1908898, 2534301, -31870557, -16550355, 18341390, -11419951, 32013174, -10103539 }, - { -25479301, 10876443, -11771086, -14625140, -12369567, 1838104, 21911214, 6354752, 4425632, -837822 }, - }, - { - { -10433389, -14612966, 22229858, -3091047, -13191166, 776729, -17415375, -12020462, 4725005, 14044970 }, - { 19268650, -7304421, 1555349, 8692754, -21474059, -9910664, 6347390, -1411784, -19522291, -16109756 }, - { -24864089, 12986008, -10898878, -5558584, -11312371, -148526, 19541418, 8180106, 9282262, 10282508 }, - }, - { - { -26205082, 4428547, -8661196, -13194263, 4098402, -14165257, 15522535, 8372215, 5542595, -10702683 }, - { -10562541, 14895633, 26814552, -16673850, -17480754, -2489360, -2781891, 6993761, -18093885, 10114655 }, - { -20107055, -929418, 31422704, 10427861, -7110749, 6150669, -29091755, -11529146, 25953725, -106158 }, - }, - { - { -4234397, -8039292, -9119125, 3046000, 2101609, -12607294, 19390020, 6094296, -3315279, 12831125 }, - { -15998678, 7578152, 5310217, 14408357, -33548620, -224739, 31575954, 6326196, 7381791, -2421839 }, - { -20902779, 3296811, 24736065, -16328389, 18374254, 7318640, 6295303, 8082724, -15362489, 12339664 }, - }, - { - { 27724736, 2291157, 6088201, -14184798, 1792727, 5857634, 13848414, 15768922, 25091167, 14856294 }, - { -18866652, 8331043, 24373479, 8541013, -701998, -9269457, 12927300, -12695493, -22182473, -9012899 }, - { -11423429, -5421590, 11632845, 3405020, 30536730, -11674039, -27260765, 13866390, 30146206, 9142070 }, - }, - { - { 3924129, -15307516, -13817122, -10054960, 12291820, -668366, -27702774, 9326384, -8237858, 4171294 }, - { -15921940, 16037937, 6713787, 16606682, -21612135, 2790944, 26396185, 3731949, 345228, -5462949 }, - { -21327538, 13448259, 25284571, 1143661, 20614966, -8849387, 2031539, -12391231, -16253183, -13582083 }, - }, - { - { 31016211, -16722429, 26371392, -14451233, -5027349, 14854137, 17477601, 3842657, 28012650, -16405420 }, - { -5075835, 9368966, -8562079, -4600902, -15249953, 6970560, -9189873, 16292057, -8867157, 3507940 }, - { 29439664, 3537914, 23333589, 6997794, -17555561, -11018068, -15209202, -15051267, -9164929, 6580396 }, - }, - }, - { - { - { -12185861, -7679788, 16438269, 10826160, -8696817, -6235611, 17860444, -9273846, -2095802, 9304567 }, - { 20714564, -4336911, 29088195, 7406487, 11426967, -5095705, 14792667, -14608617, 5289421, -477127 }, - { -16665533, -10650790, -6160345, -13305760, 9192020, -1802462, 17271490, 12349094, 26939669, -3752294 }, - }, - { - { -12889898, 9373458, 31595848, 16374215, 21471720, 13221525, -27283495, -12348559, -3698806, 117887 }, - { 22263325, -6560050, 3984570, -11174646, -15114008, -566785, 28311253, 5358056, -23319780, 541964 }, - { 16259219, 3261970, 2309254, -15534474, -16885711, -4581916, 24134070, -16705829, -13337066, -13552195 }, - }, - { - { 9378160, -13140186, -22845982, -12745264, 28198281, -7244098, -2399684, -717351, 690426, 14876244 }, - { 24977353, -314384, -8223969, -13465086, 28432343, -1176353, -13068804, -12297348, -22380984, 6618999 }, - { -1538174, 11685646, 12944378, 13682314, -24389511, -14413193, 8044829, -13817328, 32239829, -5652762 }, - }, - { - { -18603066, 4762990, -926250, 8885304, -28412480, -3187315, 9781647, -10350059, 32779359, 5095274 }, - { -33008130, -5214506, -32264887, -3685216, 9460461, -9327423, -24601656, 14506724, 21639561, -2630236 }, - { -16400943, -13112215, 25239338, 15531969, 3987758, -4499318, -1289502, -6863535, 17874574, 558605 }, - }, - { - { -13600129, 10240081, 9171883, 16131053, -20869254, 9599700, 33499487, 5080151, 2085892, 5119761 }, - { -22205145, -2519528, -16381601, 414691, -25019550, 2170430, 30634760, -8363614, -31999993, -5759884 }, - { -6845704, 15791202, 8550074, -1312654, 29928809, -12092256, 27534430, -7192145, -22351378, 12961482 }, - }, - { - { -24492060, -9570771, 10368194, 11582341, -23397293, -2245287, 16533930, 8206996, -30194652, -5159638 }, - { -11121496, -3382234, 2307366, 6362031, -135455, 8868177, -16835630, 7031275, 7589640, 8945490 }, - { -32152748, 8917967, 6661220, -11677616, -1192060, -15793393, 7251489, -11182180, 24099109, -14456170 }, - }, - { - { 5019558, -7907470, 4244127, -14714356, -26933272, 6453165, -19118182, -13289025, -6231896, -10280736 }, - { 10853594, 10721687, 26480089, 5861829, -22995819, 1972175, -1866647, -10557898, -3363451, -6441124 }, - { -17002408, 5906790, 221599, -6563147, 7828208, -13248918, 24362661, -2008168, -13866408, 7421392 }, - }, - { - { 8139927, -6546497, 32257646, -5890546, 30375719, 1886181, -21175108, 15441252, 28826358, -4123029 }, - { 6267086, 9695052, 7709135, -16603597, -32869068, -1886135, 14795160, -7840124, 13746021, -1742048 }, - { 28584902, 7787108, -6732942, -15050729, 22846041, -7571236, -3181936, -363524, 4771362, -8419958 }, - }, - }, - { - { - { 24949256, 6376279, -27466481, -8174608, -18646154, -9930606, 33543569, -12141695, 3569627, 11342593 }, - { 26514989, 4740088, 27912651, 3697550, 19331575, -11472339, 6809886, 4608608, 7325975, -14801071 }, - { -11618399, -14554430, -24321212, 7655128, -1369274, 5214312, -27400540, 10258390, -17646694, -8186692 }, - }, - { - { 11431204, 15823007, 26570245, 14329124, 18029990, 4796082, -31446179, 15580664, 9280358, -3973687 }, - { -160783, -10326257, -22855316, -4304997, -20861367, -13621002, -32810901, -11181622, -15545091, 4387441 }, - { -20799378, 12194512, 3937617, -5805892, -27154820, 9340370, -24513992, 8548137, 20617071, -7482001 }, - }, - { - { -938825, -3930586, -8714311, 16124718, 24603125, -6225393, -13775352, -11875822, 24345683, 10325460 }, - { -19855277, -1568885, -22202708, 8714034, 14007766, 6928528, 16318175, -1010689, 4766743, 3552007 }, - { -21751364, -16730916, 1351763, -803421, -4009670, 3950935, 3217514, 14481909, 10988822, -3994762 }, - }, - { - { 15564307, -14311570, 3101243, 5684148, 30446780, -8051356, 12677127, -6505343, -8295852, 13296005 }, - { -9442290, 6624296, -30298964, -11913677, -4670981, -2057379, 31521204, 9614054, -30000824, 12074674 }, - { 4771191, -135239, 14290749, -13089852, 27992298, 14998318, -1413936, -1556716, 29832613, -16391035 }, - }, - { - { 7064884, -7541174, -19161962, -5067537, -18891269, -2912736, 25825242, 5293297, -27122660, 13101590 }, - { -2298563, 2439670, -7466610, 1719965, -27267541, -16328445, 32512469, -5317593, -30356070, -4190957 }, - { -30006540, 10162316, -33180176, 3981723, -16482138, -13070044, 14413974, 9515896, 19568978, 9628812 }, - }, - { - { 33053803, 199357, 15894591, 1583059, 27380243, -4580435, -17838894, -6106839, -6291786, 3437740 }, - { -18978877, 3884493, 19469877, 12726490, 15913552, 13614290, -22961733, 70104, 7463304, 4176122 }, - { -27124001, 10659917, 11482427, -16070381, 12771467, -6635117, -32719404, -5322751, 24216882, 5944158 }, - }, - { - { 8894125, 7450974, -2664149, -9765752, -28080517, -12389115, 19345746, 14680796, 11632993, 5847885 }, - { 26942781, -2315317, 9129564, -4906607, 26024105, 11769399, -11518837, 6367194, -9727230, 4782140 }, - { 19916461, -4828410, -22910704, -11414391, 25606324, -5972441, 33253853, 8220911, 6358847, -1873857 }, - }, - { - { 801428, -2081702, 16569428, 11065167, 29875704, 96627, 7908388, -4480480, -13538503, 1387155 }, - { 19646058, 5720633, -11416706, 12814209, 11607948, 12749789, 14147075, 15156355, -21866831, 11835260 }, - { 19299512, 1155910, 28703737, 14890794, 2925026, 7269399, 26121523, 15467869, -26560550, 5052483 }, - }, - }, - { - { - { -3017432, 10058206, 1980837, 3964243, 22160966, 12322533, -6431123, -12618185, 12228557, -7003677 }, - { 32944382, 14922211, -22844894, 5188528, 21913450, -8719943, 4001465, 13238564, -6114803, 8653815 }, - { 22865569, -4652735, 27603668, -12545395, 14348958, 8234005, 24808405, 5719875, 28483275, 2841751 }, - }, - { - { -16420968, -1113305, -327719, -12107856, 21886282, -15552774, -1887966, -315658, 19932058, -12739203 }, - { -11656086, 10087521, -8864888, -5536143, -19278573, -3055912, 3999228, 13239134, -4777469, -13910208 }, - { 1382174, -11694719, 17266790, 9194690, -13324356, 9720081, 20403944, 11284705, -14013818, 3093230 }, - }, - { - { 16650921, -11037932, -1064178, 1570629, -8329746, 7352753, -302424, 16271225, -24049421, -6691850 }, - { -21911077, -5927941, -4611316, -5560156, -31744103, -10785293, 24123614, 15193618, -21652117, -16739389 }, - { -9935934, -4289447, -25279823, 4372842, 2087473, 10399484, 31870908, 14690798, 17361620, 11864968 }, - }, - { - { -11307610, 6210372, 13206574, 5806320, -29017692, -13967200, -12331205, -7486601, -25578460, -16240689 }, - { 14668462, -12270235, 26039039, 15305210, 25515617, 4542480, 10453892, 6577524, 9145645, -6443880 }, - { 5974874, 3053895, -9433049, -10385191, -31865124, 3225009, -7972642, 3936128, -5652273, -3050304 }, - }, - { - { 30625386, -4729400, -25555961, -12792866, -20484575, 7695099, 17097188, -16303496, -27999779, 1803632 }, - { -3553091, 9865099, -5228566, 4272701, -5673832, -16689700, 14911344, 12196514, -21405489, 7047412 }, - { 20093277, 9920966, -11138194, -5343857, 13161587, 12044805, -32856851, 4124601, -32343828, -10257566 }, - }, - { - { -20788824, 14084654, -13531713, 7842147, 19119038, -13822605, 4752377, -8714640, -21679658, 2288038 }, - { -26819236, -3283715, 29965059, 3039786, -14473765, 2540457, 29457502, 14625692, -24819617, 12570232 }, - { -1063558, -11551823, 16920318, 12494842, 1278292, -5869109, -21159943, -3498680, -11974704, 4724943 }, - }, - { - { 17960970, -11775534, -4140968, -9702530, -8876562, -1410617, -12907383, -8659932, -29576300, 1903856 }, - { 23134274, -14279132, -10681997, -1611936, 20684485, 15770816, -12989750, 3190296, 26955097, 14109738 }, - { 15308788, 5320727, -30113809, -14318877, 22902008, 7767164, 29425325, -11277562, 31960942, 11934971 }, - }, - { - { -27395711, 8435796, 4109644, 12222639, -24627868, 14818669, 20638173, 4875028, 10491392, 1379718 }, - { -13159415, 9197841, 3875503, -8936108, -1383712, -5879801, 33518459, 16176658, 21432314, 12180697 }, - { -11787308, 11500838, 13787581, -13832590, -22430679, 10140205, 1465425, 12689540, -10301319, -13872883 }, - }, - }, - { - { - { 5414091, -15386041, -21007664, 9643570, 12834970, 1186149, -2622916, -1342231, 26128231, 6032912 }, - { -26337395, -13766162, 32496025, -13653919, 17847801, -12669156, 3604025, 8316894, -25875034, -10437358 }, - { 3296484, 6223048, 24680646, -12246460, -23052020, 5903205, -8862297, -4639164, 12376617, 3188849 }, - }, - { - { 29190488, -14659046, 27549113, -1183516, 3520066, -10697301, 32049515, -7309113, -16109234, -9852307 }, - { -14744486, -9309156, 735818, -598978, -20407687, -5057904, 25246078, -15795669, 18640741, -960977 }, - { -6928835, -16430795, 10361374, 5642961, 4910474, 12345252, -31638386, -494430, 10530747, 1053335 }, - }, - { - { -29265967, -14186805, -13538216, -12117373, -19457059, -10655384, -31462369, -2948985, 24018831, 15026644 }, - { -22592535, -3145277, -2289276, 5953843, -13440189, 9425631, 25310643, 13003497, -2314791, -15145616 }, - { -27419985, -603321, -8043984, -1669117, -26092265, 13987819, -27297622, 187899, -23166419, -2531735 }, - }, - { - { -21744398, -13810475, 1844840, 5021428, -10434399, -15911473, 9716667, 16266922, -5070217, 726099 }, - { 29370922, -6053998, 7334071, -15342259, 9385287, 2247707, -13661962, -4839461, 30007388, -15823341 }, - { -936379, 16086691, 23751945, -543318, -1167538, -5189036, 9137109, 730663, 9835848, 4555336 }, - }, - { - { -23376435, 1410446, -22253753, -12899614, 30867635, 15826977, 17693930, 544696, -11985298, 12422646 }, - { 31117226, -12215734, -13502838, 6561947, -9876867, -12757670, -5118685, -4096706, 29120153, 13924425 }, - { -17400879, -14233209, 19675799, -2734756, -11006962, -5858820, -9383939, -11317700, 7240931, -237388 }, - }, - { - { -31361739, -11346780, -15007447, -5856218, -22453340, -12152771, 1222336, 4389483, 3293637, -15551743 }, - { -16684801, -14444245, 11038544, 11054958, -13801175, -3338533, -24319580, 7733547, 12796905, -6335822 }, - { -8759414, -10817836, -25418864, 10783769, -30615557, -9746811, -28253339, 3647836, 3222231, -11160462 }, - }, - { - { 18606113, 1693100, -25448386, -15170272, 4112353, 10045021, 23603893, -2048234, -7550776, 2484985 }, - { 9255317, -3131197, -12156162, -1004256, 13098013, -9214866, 16377220, -2102812, -19802075, -3034702 }, - { -22729289, 7496160, -5742199, 11329249, 19991973, -3347502, -31718148, 9936966, -30097688, -10618797 }, - }, - { - { 21878590, -5001297, 4338336, 13643897, -3036865, 13160960, 19708896, 5415497, -7360503, -4109293 }, - { 27736861, 10103576, 12500508, 8502413, -3413016, -9633558, 10436918, -1550276, -23659143, -8132100 }, - { 19492550, -12104365, -29681976, -852630, -3208171, 12403437, 30066266, 8367329, 13243957, 8709688 }, - }, - }, - { - { - { 12015105, 2801261, 28198131, 10151021, 24818120, -4743133, -11194191, -5645734, 5150968, 7274186 }, - { 2831366, -12492146, 1478975, 6122054, 23825128, -12733586, 31097299, 6083058, 31021603, -9793610 }, - { -2529932, -2229646, 445613, 10720828, -13849527, -11505937, -23507731, 16354465, 15067285, -14147707 }, - }, - { - { 7840942, 14037873, -33364863, 15934016, -728213, -3642706, 21403988, 1057586, -19379462, -12403220 }, - { 915865, -16469274, 15608285, -8789130, -24357026, 6060030, -17371319, 8410997, -7220461, 16527025 }, - { 32922597, -556987, 20336074, -16184568, 10903705, -5384487, 16957574, 52992, 23834301, 6588044 }, - }, - { - { 32752030, 11232950, 3381995, -8714866, 22652988, -10744103, 17159699, 16689107, -20314580, -1305992 }, - { -4689649, 9166776, -25710296, -10847306, 11576752, 12733943, 7924251, -2752281, 1976123, -7249027 }, - { 21251222, 16309901, -2983015, -6783122, 30810597, 12967303, 156041, -3371252, 12331345, -8237197 }, - }, - { - { 8651614, -4477032, -16085636, -4996994, 13002507, 2950805, 29054427, -5106970, 10008136, -4667901 }, - { 31486080, 15114593, -14261250, 12951354, 14369431, -7387845, 16347321, -13662089, 8684155, -10532952 }, - { 19443825, 11385320, 24468943, -9659068, -23919258, 2187569, -26263207, -6086921, 31316348, 14219878 }, - }, - { - { -28594490, 1193785, 32245219, 11392485, 31092169, 15722801, 27146014, 6992409, 29126555, 9207390 }, - { 32382935, 1110093, 18477781, 11028262, -27411763, -7548111, -4980517, 10843782, -7957600, -14435730 }, - { 2814918, 7836403, 27519878, -7868156, -20894015, -11553689, -21494559, 8550130, 28346258, 1994730 }, - }, - { - { -19578299, 8085545, -14000519, -3948622, 2785838, -16231307, -19516951, 7174894, 22628102, 8115180 }, - { -30405132, 955511, -11133838, -15078069, -32447087, -13278079, -25651578, 3317160, -9943017, 930272 }, - { -15303681, -6833769, 28856490, 1357446, 23421993, 1057177, 24091212, -1388970, -22765376, -10650715 }, - }, - { - { -22751231, -5303997, -12907607, -12768866, -15811511, -7797053, -14839018, -16554220, -1867018, 8398970 }, - { -31969310, 2106403, -4736360, 1362501, 12813763, 16200670, 22981545, -6291273, 18009408, -15772772 }, - { -17220923, -9545221, -27784654, 14166835, 29815394, 7444469, 29551787, -3727419, 19288549, 1325865 }, - }, - { - { 15100157, -15835752, -23923978, -1005098, -26450192, 15509408, 12376730, -3479146, 33166107, -8042750 }, - { 20909231, 13023121, -9209752, 16251778, -5778415, -8094914, 12412151, 10018715, 2213263, -13878373 }, - { 32529814, -11074689, 30361439, -16689753, -9135940, 1513226, 22922121, 6382134, -5766928, 8371348 }, - }, - }, - { - { - { 9923462, 11271500, 12616794, 3544722, -29998368, -1721626, 12891687, -8193132, -26442943, 10486144 }, - { -22597207, -7012665, 8587003, -8257861, 4084309, -12970062, 361726, 2610596, -23921530, -11455195 }, - { 5408411, -1136691, -4969122, 10561668, 24145918, 14240566, 31319731, -4235541, 19985175, -3436086 }, - }, - { - { -13994457, 16616821, 14549246, 3341099, 32155958, 13648976, -17577068, 8849297, 65030, 8370684 }, - { -8320926, -12049626, 31204563, 5839400, -20627288, -1057277, -19442942, 6922164, 12743482, -9800518 }, - { -2361371, 12678785, 28815050, 4759974, -23893047, 4884717, 23783145, 11038569, 18800704, 255233 }, - }, - { - { -5269658, -1773886, 13957886, 7990715, 23132995, 728773, 13393847, 9066957, 19258688, -14753793 }, - { -2936654, -10827535, -10432089, 14516793, -3640786, 4372541, -31934921, 2209390, -1524053, 2055794 }, - { 580882, 16705327, 5468415, -2683018, -30926419, -14696000, -7203346, -8994389, -30021019, 7394435 }, - }, - { - { 23838809, 1822728, -15738443, 15242727, 8318092, -3733104, -21672180, -3492205, -4821741, 14799921 }, - { 13345610, 9759151, 3371034, -16137791, 16353039, 8577942, 31129804, 13496856, -9056018, 7402518 }, - { 2286874, -4435931, -20042458, -2008336, -13696227, 5038122, 11006906, -15760352, 8205061, 1607563 }, - }, - { - { 14414086, -8002132, 3331830, -3208217, 22249151, -5594188, 18364661, -2906958, 30019587, -9029278 }, - { -27688051, 1585953, -10775053, 931069, -29120221, -11002319, -14410829, 12029093, 9944378, 8024 }, - { 4368715, -3709630, 29874200, -15022983, -20230386, -11410704, -16114594, -999085, -8142388, 5640030 }, - }, - { - { 10299610, 13746483, 11661824, 16234854, 7630238, 5998374, 9809887, -16694564, 15219798, -14327783 }, - { 27425505, -5719081, 3055006, 10660664, 23458024, 595578, -15398605, -1173195, -18342183, 9742717 }, - { 6744077, 2427284, 26042789, 2720740, -847906, 1118974, 32324614, 7406442, 12420155, 1994844 }, - }, - { - { 14012521, -5024720, -18384453, -9578469, -26485342, -3936439, -13033478, -10909803, 24319929, -6446333 }, - { 16412690, -4507367, 10772641, 15929391, -17068788, -4658621, 10555945, -10484049, -30102368, -4739048 }, - { 22397382, -7767684, -9293161, -12792868, 17166287, -9755136, -27333065, 6199366, 21880021, -12250760 }, - }, - { - { -4283307, 5368523, -31117018, 8163389, -30323063, 3209128, 16557151, 8890729, 8840445, 4957760 }, - { -15447727, 709327, -6919446, -10870178, -29777922, 6522332, -21720181, 12130072, -14796503, 5005757 }, - { -2114751, -14308128, 23019042, 15765735, -25269683, 6002752, 10183197, -13239326, -16395286, -2176112 }, - }, - }, - { - { - { -19025756, 1632005, 13466291, -7995100, -23640451, 16573537, -32013908, -3057104, 22208662, 2000468 }, - { 3065073, -1412761, -25598674, -361432, -17683065, -5703415, -8164212, 11248527, -3691214, -7414184 }, - { 10379208, -6045554, 8877319, 1473647, -29291284, -12507580, 16690915, 2553332, -3132688, 16400289 }, - }, - { - { 15716668, 1254266, -18472690, 7446274, -8448918, 6344164, -22097271, -7285580, 26894937, 9132066 }, - { 24158887, 12938817, 11085297, -8177598, -28063478, -4457083, -30576463, 64452, -6817084, -2692882 }, - { 13488534, 7794716, 22236231, 5989356, 25426474, -12578208, 2350710, -3418511, -4688006, 2364226 }, - }, - { - { 16335052, 9132434, 25640582, 6678888, 1725628, 8517937, -11807024, -11697457, 15445875, -7798101 }, - { 29004207, -7867081, 28661402, -640412, -12794003, -7943086, 31863255, -4135540, -278050, -15759279 }, - { -6122061, -14866665, -28614905, 14569919, -10857999, -3591829, 10343412, -6976290, -29828287, -10815811 }, - }, - { - { 27081650, 3463984, 14099042, -4517604, 1616303, -6205604, 29542636, 15372179, 17293797, 960709 }, - { 20263915, 11434237, -5765435, 11236810, 13505955, -10857102, -16111345, 6493122, -19384511, 7639714 }, - { -2830798, -14839232, 25403038, -8215196, -8317012, -16173699, 18006287, -16043750, 29994677, -15808121 }, - }, - { - { 9769828, 5202651, -24157398, -13631392, -28051003, -11561624, -24613141, -13860782, -31184575, 709464 }, - { 12286395, 13076066, -21775189, -1176622, -25003198, 4057652, -32018128, -8890874, 16102007, 13205847 }, - { 13733362, 5599946, 10557076, 3195751, -5557991, 8536970, -25540170, 8525972, 10151379, 10394400 }, - }, - { - { 4024660, -16137551, 22436262, 12276534, -9099015, -2686099, 19698229, 11743039, -33302334, 8934414 }, - { -15879800, -4525240, -8580747, -2934061, 14634845, -698278, -9449077, 3137094, -11536886, 11721158 }, - { 17555939, -5013938, 8268606, 2331751, -22738815, 9761013, 9319229, 8835153, -9205489, -1280045 }, - }, - { - { -461409, -7830014, 20614118, 16688288, -7514766, -4807119, 22300304, 505429, 6108462, -6183415 }, - { -5070281, 12367917, -30663534, 3234473, 32617080, -8422642, 29880583, -13483331, -26898490, -7867459 }, - { -31975283, 5726539, 26934134, 10237677, -3173717, -605053, 24199304, 3795095, 7592688, -14992079 }, - }, - { - { 21594432, -14964228, 17466408, -4077222, 32537084, 2739898, 6407723, 12018833, -28256052, 4298412 }, - { -20650503, -11961496, -27236275, 570498, 3767144, -1717540, 13891942, -1569194, 13717174, 10805743 }, - { -14676630, -15644296, 15287174, 11927123, 24177847, -8175568, -796431, 14860609, -26938930, -5863836 }, - }, - }, - { - { - { 12962541, 5311799, -10060768, 11658280, 18855286, -7954201, 13286263, -12808704, -4381056, 9882022 }, - { 18512079, 11319350, -20123124, 15090309, 18818594, 5271736, -22727904, 3666879, -23967430, -3299429 }, - { -6789020, -3146043, 16192429, 13241070, 15898607, -14206114, -10084880, -6661110, -2403099, 5276065 }, - }, - { - { 30169808, -5317648, 26306206, -11750859, 27814964, 7069267, 7152851, 3684982, 1449224, 13082861 }, - { 10342826, 3098505, 2119311, 193222, 25702612, 12233820, 23697382, 15056736, -21016438, -8202000 }, - { -33150110, 3261608, 22745853, 7948688, 19370557, -15177665, -26171976, 6482814, -10300080, -11060101 }, - }, - { - { 32869458, -5408545, 25609743, 15678670, -10687769, -15471071, 26112421, 2521008, -22664288, 6904815 }, - { 29506923, 4457497, 3377935, -9796444, -30510046, 12935080, 1561737, 3841096, -29003639, -6657642 }, - { 10340844, -6630377, -18656632, -2278430, 12621151, -13339055, 30878497, -11824370, -25584551, 5181966 }, - }, - { - { 25940115, -12658025, 17324188, -10307374, -8671468, 15029094, 24396252, -16450922, -2322852, -12388574 }, - { -21765684, 9916823, -1300409, 4079498, -1028346, 11909559, 1782390, 12641087, 20603771, -6561742 }, - { -18882287, -11673380, 24849422, 11501709, 13161720, -4768874, 1925523, 11914390, 4662781, 7820689 }, - }, - { - { 12241050, -425982, 8132691, 9393934, 32846760, -1599620, 29749456, 12172924, 16136752, 15264020 }, - { -10349955, -14680563, -8211979, 2330220, -17662549, -14545780, 10658213, 6671822, 19012087, 3772772 }, - { 3753511, -3421066, 10617074, 2028709, 14841030, -6721664, 28718732, -15762884, 20527771, 12988982 }, - }, - { - { -14822485, -5797269, -3707987, 12689773, -898983, -10914866, -24183046, -10564943, 3299665, -12424953 }, - { -16777703, -15253301, -9642417, 4978983, 3308785, 8755439, 6943197, 6461331, -25583147, 8991218 }, - { -17226263, 1816362, -1673288, -6086439, 31783888, -8175991, -32948145, 7417950, -30242287, 1507265 }, - }, - { - { 29692663, 6829891, -10498800, 4334896, 20945975, -11906496, -28887608, 8209391, 14606362, -10647073 }, - { -3481570, 8707081, 32188102, 5672294, 22096700, 1711240, -33020695, 9761487, 4170404, -2085325 }, - { -11587470, 14855945, -4127778, -1531857, -26649089, 15084046, 22186522, 16002000, -14276837, -8400798 }, - }, - { - { -4811456, 13761029, -31703877, -2483919, -3312471, 7869047, -7113572, -9620092, 13240845, 10965870 }, - { -7742563, -8256762, -14768334, -13656260, -23232383, 12387166, 4498947, 14147411, 29514390, 4302863 }, - { -13413405, -12407859, 20757302, -13801832, 14785143, 8976368, -5061276, -2144373, 17846988, -13971927 }, - }, - }, - { - { - { -2244452, -754728, -4597030, -1066309, -6247172, 1455299, -21647728, -9214789, -5222701, 12650267 }, - { -9906797, -16070310, 21134160, 12198166, -27064575, 708126, 387813, 13770293, -19134326, 10958663 }, - { 22470984, 12369526, 23446014, -5441109, -21520802, -9698723, -11772496, -11574455, -25083830, 4271862 }, - }, - { - { -25169565, -10053642, -19909332, 15361595, -5984358, 2159192, 75375, -4278529, -32526221, 8469673 }, - { 15854970, 4148314, -8893890, 7259002, 11666551, 13824734, -30531198, 2697372, 24154791, -9460943 }, - { 15446137, -15806644, 29759747, 14019369, 30811221, -9610191, -31582008, 12840104, 24913809, 9815020 }, - }, - { - { -4709286, -5614269, -31841498, -12288893, -14443537, 10799414, -9103676, 13438769, 18735128, 9466238 }, - { 11933045, 9281483, 5081055, -5183824, -2628162, -4905629, -7727821, -10896103, -22728655, 16199064 }, - { 14576810, 379472, -26786533, -8317236, -29426508, -10812974, -102766, 1876699, 30801119, 2164795 }, - }, - { - { 15995086, 3199873, 13672555, 13712240, -19378835, -4647646, -13081610, -15496269, -13492807, 1268052 }, - { -10290614, -3659039, -3286592, 10948818, 23037027, 3794475, -3470338, -12600221, -17055369, 3565904 }, - { 29210088, -9419337, -5919792, -4952785, 10834811, -13327726, -16512102, -10820713, -27162222, -14030531 }, - }, - { - { -13161890, 15508588, 16663704, -8156150, -28349942, 9019123, -29183421, -3769423, 2244111, -14001979 }, - { -5152875, -3800936, -9306475, -6071583, 16243069, 14684434, -25673088, -16180800, 13491506, 4641841 }, - { 10813417, 643330, -19188515, -728916, 30292062, -16600078, 27548447, -7721242, 14476989, -12767431 }, - }, - { - { 10292079, 9984945, 6481436, 8279905, -7251514, 7032743, 27282937, -1644259, -27912810, 12651324 }, - { -31185513, -813383, 22271204, 11835308, 10201545, 15351028, 17099662, 3988035, 21721536, -3148940 }, - { 10202177, -6545839, -31373232, -9574638, -32150642, -8119683, -12906320, 3852694, 13216206, 14842320 }, - }, - { - { -15815640, -10601066, -6538952, -7258995, -6984659, -6581778, -31500847, 13765824, -27434397, 9900184 }, - { 14465505, -13833331, -32133984, -14738873, -27443187, 12990492, 33046193, 15796406, -7051866, -8040114 }, - { 30924417, -8279620, 6359016, -12816335, 16508377, 9071735, -25488601, 15413635, 9524356, -7018878 }, - }, - { - { 12274201, -13175547, 32627641, -1785326, 6736625, 13267305, 5237659, -5109483, 15663516, 4035784 }, - { -2951309, 8903985, 17349946, 601635, -16432815, -4612556, -13732739, -15889334, -22258478, 4659091 }, - { -16916263, -4952973, -30393711, -15158821, 20774812, 15897498, 5736189, 15026997, -2178256, -13455585 }, - }, - }, - { - { - { -8858980, -2219056, 28571666, -10155518, -474467, -10105698, -3801496, 278095, 23440562, -290208 }, - { 10226241, -5928702, 15139956, 120818, -14867693, 5218603, 32937275, 11551483, -16571960, -7442864 }, - { 17932739, -12437276, -24039557, 10749060, 11316803, 7535897, 22503767, 5561594, -3646624, 3898661 }, - }, - { - { 7749907, -969567, -16339731, -16464, -25018111, 15122143, -1573531, 7152530, 21831162, 1245233 }, - { 26958459, -14658026, 4314586, 8346991, -5677764, 11960072, -32589295, -620035, -30402091, -16716212 }, - { -12165896, 9166947, 33491384, 13673479, 29787085, 13096535, 6280834, 14587357, -22338025, 13987525 }, - }, - { - { -24349909, 7778775, 21116000, 15572597, -4833266, -5357778, -4300898, -5124639, -7469781, -2858068 }, - { 9681908, -6737123, -31951644, 13591838, -6883821, 386950, 31622781, 6439245, -14581012, 4091397 }, - { -8426427, 1470727, -28109679, -1596990, 3978627, -5123623, -19622683, 12092163, 29077877, -14741988 }, - }, - { - { 5269168, -6859726, -13230211, -8020715, 25932563, 1763552, -5606110, -5505881, -20017847, 2357889 }, - { 32264008, -15407652, -5387735, -1160093, -2091322, -3946900, 23104804, -12869908, 5727338, 189038 }, - { 14609123, -8954470, -6000566, -16622781, -14577387, -7743898, -26745169, 10942115, -25888931, -14884697 }, - }, - { - { 20513500, 5557931, -15604613, 7829531, 26413943, -2019404, -21378968, 7471781, 13913677, -5137875 }, - { -25574376, 11967826, 29233242, 12948236, -6754465, 4713227, -8940970, 14059180, 12878652, 8511905 }, - { -25656801, 3393631, -2955415, -7075526, -2250709, 9366908, -30223418, 6812974, 5568676, -3127656 }, - }, - { - { 11630004, 12144454, 2116339, 13606037, 27378885, 15676917, -17408753, -13504373, -14395196, 8070818 }, - { 27117696, -10007378, -31282771, -5570088, 1127282, 12772488, -29845906, 10483306, -11552749, -1028714 }, - { 10637467, -5688064, 5674781, 1072708, -26343588, -6982302, -1683975, 9177853, -27493162, 15431203 }, - }, - { - { 20525145, 10892566, -12742472, 12779443, -29493034, 16150075, -28240519, 14943142, -15056790, -7935931 }, - { -30024462, 5626926, -551567, -9981087, 753598, 11981191, 25244767, -3239766, -3356550, 9594024 }, - { -23752644, 2636870, -5163910, -10103818, 585134, 7877383, 11345683, -6492290, 13352335, -10977084 }, - }, - { - { -1931799, -5407458, 3304649, -12884869, 17015806, -4877091, -29783850, -7752482, -13215537, -319204 }, - { 20239939, 6607058, 6203985, 3483793, -18386976, -779229, -20723742, 15077870, -22750759, 14523817 }, - { 27406042, -6041657, 27423596, -4497394, 4996214, 10002360, -28842031, -4545494, -30172742, -4805667 }, - }, - }, - { - { - { 11374242, 12660715, 17861383, -12540833, 10935568, 1099227, -13886076, -9091740, -27727044, 11358504 }, - { -12730809, 10311867, 1510375, 10778093, -2119455, -9145702, 32676003, 11149336, -26123651, 4985768 }, - { -19096303, 341147, -6197485, -239033, 15756973, -8796662, -983043, 13794114, -19414307, -15621255 }, - }, - { - { 6490081, 11940286, 25495923, -7726360, 8668373, -8751316, 3367603, 6970005, -1691065, -9004790 }, - { 1656497, 13457317, 15370807, 6364910, 13605745, 8362338, -19174622, -5475723, -16796596, -5031438 }, - { -22273315, -13524424, -64685, -4334223, -18605636, -10921968, -20571065, -7007978, -99853, -10237333 }, - }, - { - { 17747465, 10039260, 19368299, -4050591, -20630635, -16041286, 31992683, -15857976, -29260363, -5511971 }, - { 31932027, -4986141, -19612382, 16366580, 22023614, 88450, 11371999, -3744247, 4882242, -10626905 }, - { 29796507, 37186, 19818052, 10115756, -11829032, 3352736, 18551198, 3272828, -5190932, -4162409 }, - }, - { - { 12501286, 4044383, -8612957, -13392385, -32430052, 5136599, -19230378, -3529697, 330070, -3659409 }, - { 6384877, 2899513, 17807477, 7663917, -2358888, 12363165, 25366522, -8573892, -271295, 12071499 }, - { -8365515, -4042521, 25133448, -4517355, -6211027, 2265927, -32769618, 1936675, -5159697, 3829363 }, - }, - { - { 28425966, -5835433, -577090, -4697198, -14217555, 6870930, 7921550, -6567787, 26333140, 14267664 }, - { -11067219, 11871231, 27385719, -10559544, -4585914, -11189312, 10004786, -8709488, -21761224, 8930324 }, - { -21197785, -16396035, 25654216, -1725397, 12282012, 11008919, 1541940, 4757911, -26491501, -16408940 }, - }, - { - { 13537262, -7759490, -20604840, 10961927, -5922820, -13218065, -13156584, 6217254, -15943699, 13814990 }, - { -17422573, 15157790, 18705543, 29619, 24409717, -260476, 27361681, 9257833, -1956526, -1776914 }, - { -25045300, -10191966, 15366585, 15166509, -13105086, 8423556, -29171540, 12361135, -18685978, 4578290 }, - }, - { - { 24579768, 3711570, 1342322, -11180126, -27005135, 14124956, -22544529, 14074919, 21964432, 8235257 }, - { -6528613, -2411497, 9442966, -5925588, 12025640, -1487420, -2981514, -1669206, 13006806, 2355433 }, - { -16304899, -13605259, -6632427, -5142349, 16974359, -10911083, 27202044, 1719366, 1141648, -12796236 }, - }, - { - { -12863944, -13219986, -8318266, -11018091, -6810145, -4843894, 13475066, -3133972, 32674895, 13715045 }, - { 11423335, -5468059, 32344216, 8962751, 24989809, 9241752, -13265253, 16086212, -28740881, -15642093 }, - { -1409668, 12530728, -6368726, 10847387, 19531186, -14132160, -11709148, 7791794, -27245943, 4383347 }, - }, - }, - { - { - { -28970898, 5271447, -1266009, -9736989, -12455236, 16732599, -4862407, -4906449, 27193557, 6245191 }, - { -15193956, 5362278, -1783893, 2695834, 4960227, 12840725, 23061898, 3260492, 22510453, 8577507 }, - { -12632451, 11257346, -32692994, 13548177, -721004, 10879011, 31168030, 13952092, -29571492, -3635906 }, - }, - { - { 3877321, -9572739, 32416692, 5405324, -11004407, -13656635, 3759769, 11935320, 5611860, 8164018 }, - { -16275802, 14667797, 15906460, 12155291, -22111149, -9039718, 32003002, -8832289, 5773085, -8422109 }, - { -23788118, -8254300, 1950875, 8937633, 18686727, 16459170, -905725, 12376320, 31632953, 190926 }, - }, - { - { -24593607, -16138885, -8423991, 13378746, 14162407, 6901328, -8288749, 4508564, -25341555, -3627528 }, - { 8884438, -5884009, 6023974, 10104341, -6881569, -4941533, 18722941, -14786005, -1672488, 827625 }, - { -32720583, -16289296, -32503547, 7101210, 13354605, 2659080, -1800575, -14108036, -24878478, 1541286 }, - }, - { - { 2901347, -1117687, 3880376, -10059388, -17620940, -3612781, -21802117, -3567481, 20456845, -1885033 }, - { 27019610, 12299467, -13658288, -1603234, -12861660, -4861471, -19540150, -5016058, 29439641, 15138866 }, - { 21536104, -6626420, -32447818, -10690208, -22408077, 5175814, -5420040, -16361163, 7779328, 109896 }, - }, - { - { 30279744, 14648750, -8044871, 6425558, 13639621, -743509, 28698390, 12180118, 23177719, -554075 }, - { 26572847, 3405927, -31701700, 12890905, -19265668, 5335866, -6493768, 2378492, 4439158, -13279347 }, - { -22716706, 3489070, -9225266, -332753, 18875722, -1140095, 14819434, -12731527, -17717757, -5461437 }, - }, - { - { -5056483, 16566551, 15953661, 3767752, -10436499, 15627060, -820954, 2177225, 8550082, -15114165 }, - { -18473302, 16596775, -381660, 15663611, 22860960, 15585581, -27844109, -3582739, -23260460, -8428588 }, - { -32480551, 15707275, -8205912, -5652081, 29464558, 2713815, -22725137, 15860482, -21902570, 1494193 }, - }, - { - { -19562091, -14087393, -25583872, -9299552, 13127842, 759709, 21923482, 16529112, 8742704, 12967017 }, - { -28464899, 1553205, 32536856, -10473729, -24691605, -406174, -8914625, -2933896, -29903758, 15553883 }, - { 21877909, 3230008, 9881174, 10539357, -4797115, 2841332, 11543572, 14513274, 19375923, -12647961 }, - }, - { - { 8832269, -14495485, 13253511, 5137575, 5037871, 4078777, 24880818, -6222716, 2862653, 9455043 }, - { 29306751, 5123106, 20245049, -14149889, 9592566, 8447059, -2077124, -2990080, 15511449, 4789663 }, - { -20679756, 7004547, 8824831, -9434977, -4045704, -3750736, -5754762, 108893, 23513200, 16652362 }, - }, - }, - { - { - { -33256173, 4144782, -4476029, -6579123, 10770039, -7155542, -6650416, -12936300, -18319198, 10212860 }, - { 2756081, 8598110, 7383731, -6859892, 22312759, -1105012, 21179801, 2600940, -9988298, -12506466 }, - { -24645692, 13317462, -30449259, -15653928, 21365574, -10869657, 11344424, 864440, -2499677, -16710063 }, - }, - { - { -26432803, 6148329, -17184412, -14474154, 18782929, -275997, -22561534, 211300, 2719757, 4940997 }, - { -1323882, 3911313, -6948744, 14759765, -30027150, 7851207, 21690126, 8518463, 26699843, 5276295 }, - { -13149873, -6429067, 9396249, 365013, 24703301, -10488939, 1321586, 149635, -15452774, 7159369 }, - }, - { - { 9987780, -3404759, 17507962, 9505530, 9731535, -2165514, 22356009, 8312176, 22477218, -8403385 }, - { 18155857, -16504990, 19744716, 9006923, 15154154, -10538976, 24256460, -4864995, -22548173, 9334109 }, - { 2986088, -4911893, 10776628, -3473844, 10620590, -7083203, -21413845, 14253545, -22587149, 536906 }, - }, - { - { 4377756, 8115836, 24567078, 15495314, 11625074, 13064599, 7390551, 10589625, 10838060, -15420424 }, - { -19342404, 867880, 9277171, -3218459, -14431572, -1986443, 19295826, -15796950, 6378260, 699185 }, - { 7895026, 4057113, -7081772, -13077756, -17886831, -323126, -716039, 15693155, -5045064, -13373962 }, - }, - { - { -7737563, -5869402, -14566319, -7406919, 11385654, 13201616, 31730678, -10962840, -3918636, -9669325 }, - { 10188286, -15770834, -7336361, 13427543, 22223443, 14896287, 30743455, 7116568, -21786507, 5427593 }, - { 696102, 13206899, 27047647, -10632082, 15285305, -9853179, 10798490, -4578720, 19236243, 12477404 }, - }, - { - { -11229439, 11243796, -17054270, -8040865, -788228, -8167967, -3897669, 11180504, -23169516, 7733644 }, - { 17800790, -14036179, -27000429, -11766671, 23887827, 3149671, 23466177, -10538171, 10322027, 15313801 }, - { 26246234, 11968874, 32263343, -5468728, 6830755, -13323031, -15794704, -101982, -24449242, 10890804 }, - }, - { - { -31365647, 10271363, -12660625, -6267268, 16690207, -13062544, -14982212, 16484931, 25180797, -5334884 }, - { -586574, 10376444, -32586414, -11286356, 19801893, 10997610, 2276632, 9482883, 316878, 13820577 }, - { -9882808, -4510367, -2115506, 16457136, -11100081, 11674996, 30756178, -7515054, 30696930, -3712849 }, - }, - { - { 32988917, -9603412, 12499366, 7910787, -10617257, -11931514, -7342816, -9985397, -32349517, 7392473 }, - { -8855661, 15927861, 9866406, -3649411, -2396914, -16655781, -30409476, -9134995, 25112947, -2926644 }, - { -2504044, -436966, 25621774, -5678772, 15085042, -5479877, -24884878, -13526194, 5537438, -13914319 }, - }, - }, - { - { - { -11225584, 2320285, -9584280, 10149187, -33444663, 5808648, -14876251, -1729667, 31234590, 6090599 }, - { -9633316, 116426, 26083934, 2897444, -6364437, -2688086, 609721, 15878753, -6970405, -9034768 }, - { -27757857, 247744, -15194774, -9002551, 23288161, -10011936, -23869595, 6503646, 20650474, 1804084 }, - }, - { - { -27589786, 15456424, 8972517, 8469608, 15640622, 4439847, 3121995, -10329713, 27842616, -202328 }, - { -15306973, 2839644, 22530074, 10026331, 4602058, 5048462, 28248656, 5031932, -11375082, 12714369 }, - { 20807691, -7270825, 29286141, 11421711, -27876523, -13868230, -21227475, 1035546, -19733229, 12796920 }, - }, - { - { 12076899, -14301286, -8785001, -11848922, -25012791, 16400684, -17591495, -12899438, 3480665, -15182815 }, - { -32361549, 5457597, 28548107, 7833186, 7303070, -11953545, -24363064, -15921875, -33374054, 2771025 }, - { -21389266, 421932, 26597266, 6860826, 22486084, -6737172, -17137485, -4210226, -24552282, 15673397 }, - }, - { - { -20184622, 2338216, 19788685, -9620956, -4001265, -8740893, -20271184, 4733254, 3727144, -12934448 }, - { 6120119, 814863, -11794402, -622716, 6812205, -15747771, 2019594, 7975683, 31123697, -10958981 }, - { 30069250, -11435332, 30434654, 2958439, 18399564, -976289, 12296869, 9204260, -16432438, 9648165 }, - }, - { - { 32705432, -1550977, 30705658, 7451065, -11805606, 9631813, 3305266, 5248604, -26008332, -11377501 }, - { 17219865, 2375039, -31570947, -5575615, -19459679, 9219903, 294711, 15298639, 2662509, -16297073 }, - { -1172927, -7558695, -4366770, -4287744, -21346413, -8434326, 32087529, -1222777, 32247248, -14389861 }, - }, - { - { 14312628, 1221556, 17395390, -8700143, -4945741, -8684635, -28197744, -9637817, -16027623, -13378845 }, - { -1428825, -9678990, -9235681, 6549687, -7383069, -468664, 23046502, 9803137, 17597934, 2346211 }, - { 18510800, 15337574, 26171504, 981392, -22241552, 7827556, -23491134, -11323352, 3059833, -11782870 }, - }, - { - { 10141598, 6082907, 17829293, -1947643, 9830092, 13613136, -25556636, -5544586, -33502212, 3592096 }, - { 33114168, -15889352, -26525686, -13343397, 33076705, 8716171, 1151462, 1521897, -982665, -6837803 }, - { -32939165, -4255815, 23947181, -324178, -33072974, -12305637, -16637686, 3891704, 26353178, 693168 }, - }, - { - { 30374239, 1595580, -16884039, 13186931, 4600344, 406904, 9585294, -400668, 31375464, 14369965 }, - { -14370654, -7772529, 1510301, 6434173, -18784789, -6262728, 32732230, -13108839, 17901441, 16011505 }, - { 18171223, -11934626, -12500402, 15197122, -11038147, -15230035, -19172240, -16046376, 8764035, 12309598 }, - }, - }, - { - { - { 5975908, -5243188, -19459362, -9681747, -11541277, 14015782, -23665757, 1228319, 17544096, -10593782 }, - { 5811932, -1715293, 3442887, -2269310, -18367348, -8359541, -18044043, -15410127, -5565381, 12348900 }, - { -31399660, 11407555, 25755363, 6891399, -3256938, 14872274, -24849353, 8141295, -10632534, -585479 }, - }, - { - { -12675304, 694026, -5076145, 13300344, 14015258, -14451394, -9698672, -11329050, 30944593, 1130208 }, - { 8247766, -6710942, -26562381, -7709309, -14401939, -14648910, 4652152, 2488540, 23550156, -271232 }, - { 17294316, -3788438, 7026748, 15626851, 22990044, 113481, 2267737, -5908146, -408818, -137719 }, - }, - { - { 16091085, -16253926, 18599252, 7340678, 2137637, -1221657, -3364161, 14550936, 3260525, -7166271 }, - { -4910104, -13332887, 18550887, 10864893, -16459325, -7291596, -23028869, -13204905, -12748722, 2701326 }, - { -8574695, 16099415, 4629974, -16340524, -20786213, -6005432, -10018363, 9276971, 11329923, 1862132 }, - }, - { - { 14763076, -15903608, -30918270, 3689867, 3511892, 10313526, -21951088, 12219231, -9037963, -940300 }, - { 8894987, -3446094, 6150753, 3013931, 301220, 15693451, -31981216, -2909717, -15438168, 11595570 }, - { 15214962, 3537601, -26238722, -14058872, 4418657, -15230761, 13947276, 10730794, -13489462, -4363670 }, - }, - { - { -2538306, 7682793, 32759013, 263109, -29984731, -7955452, -22332124, -10188635, 977108, 699994 }, - { -12466472, 4195084, -9211532, 550904, -15565337, 12917920, 19118110, -439841, -30534533, -14337913 }, - { 31788461, -14507657, 4799989, 7372237, 8808585, -14747943, 9408237, -10051775, 12493932, -5409317 }, - }, - { - { -25680606, 5260744, -19235809, -6284470, -3695942, 16566087, 27218280, 2607121, 29375955, 6024730 }, - { 842132, -2794693, -4763381, -8722815, 26332018, -12405641, 11831880, 6985184, -9940361, 2854096 }, - { -4847262, -7969331, 2516242, -5847713, 9695691, -7221186, 16512645, 960770, 12121869, 16648078 }, - }, - { - { -15218652, 14667096, -13336229, 2013717, 30598287, -464137, -31504922, -7882064, 20237806, 2838411 }, - { -19288047, 4453152, 15298546, -16178388, 22115043, -15972604, 12544294, -13470457, 1068881, -12499905 }, - { -9558883, -16518835, 33238498, 13506958, 30505848, -1114596, -8486907, -2630053, 12521378, 4845654 }, - }, - { - { -28198521, 10744108, -2958380, 10199664, 7759311, -13088600, 3409348, -873400, -6482306, -12885870 }, - { -23561822, 6230156, -20382013, 10655314, -24040585, -11621172, 10477734, -1240216, -3113227, 13974498 }, - { 12966261, 15550616, -32038948, -1615346, 21025980, -629444, 5642325, 7188737, 18895762, 12629579 }, - }, - }, - { - { - { 14741879, -14946887, 22177208, -11721237, 1279741, 8058600, 11758140, 789443, 32195181, 3895677 }, - { 10758205, 15755439, -4509950, 9243698, -4879422, 6879879, -2204575, -3566119, -8982069, 4429647 }, - { -2453894, 15725973, -20436342, -10410672, -5803908, -11040220, -7135870, -11642895, 18047436, -15281743 }, - }, - { - { -25173001, -11307165, 29759956, 11776784, -22262383, -15820455, 10993114, -12850837, -17620701, -9408468 }, - { 21987233, 700364, -24505048, 14972008, -7774265, -5718395, 32155026, 2581431, -29958985, 8773375 }, - { -25568350, 454463, -13211935, 16126715, 25240068, 8594567, 20656846, 12017935, -7874389, -13920155 }, - }, - { - { 6028182, 6263078, -31011806, -11301710, -818919, 2461772, -31841174, -5468042, -1721788, -2776725 }, - { -12278994, 16624277, 987579, -5922598, 32908203, 1248608, 7719845, -4166698, 28408820, 6816612 }, - { -10358094, -8237829, 19549651, -12169222, 22082623, 16147817, 20613181, 13982702, -10339570, 5067943 }, - }, - { - { -30505967, -3821767, 12074681, 13582412, -19877972, 2443951, -19719286, 12746132, 5331210, -10105944 }, - { 30528811, 3601899, -1957090, 4619785, -27361822, -15436388, 24180793, -12570394, 27679908, -1648928 }, - { 9402404, -13957065, 32834043, 10838634, -26580150, -13237195, 26653274, -8685565, 22611444, -12715406 }, - }, - { - { 22190590, 1118029, 22736441, 15130463, -30460692, -5991321, 19189625, -4648942, 4854859, 6622139 }, - { -8310738, -2953450, -8262579, -3388049, -10401731, -271929, 13424426, -3567227, 26404409, 13001963 }, - { -31241838, -15415700, -2994250, 8939346, 11562230, -12840670, -26064365, -11621720, -15405155, 11020693 }, - }, - { - { 1866042, -7949489, -7898649, -10301010, 12483315, 13477547, 3175636, -12424163, 28761762, 1406734 }, - { -448555, -1777666, 13018551, 3194501, -9580420, -11161737, 24760585, -4347088, 25577411, -13378680 }, - { -24290378, 4759345, -690653, -1852816, 2066747, 10693769, -29595790, 9884936, -9368926, 4745410 }, - }, - { - { -9141284, 6049714, -19531061, -4341411, -31260798, 9944276, -15462008, -11311852, 10931924, -11931931 }, - { -16561513, 14112680, -8012645, 4817318, -8040464, -11414606, -22853429, 10856641, -20470770, 13434654 }, - { 22759489, -10073434, -16766264, -1871422, 13637442, -10168091, 1765144, -12654326, 28445307, -5364710 }, - }, - { - { 29875063, 12493613, 2795536, -3786330, 1710620, 15181182, -10195717, -8788675, 9074234, 1167180 }, - { -26205683, 11014233, -9842651, -2635485, -26908120, 7532294, -18716888, -9535498, 3843903, 9367684 }, - { -10969595, -6403711, 9591134, 9582310, 11349256, 108879, 16235123, 8601684, -139197, 4242895 }, - }, - }, - { - { - { 22092954, -13191123, -2042793, -11968512, 32186753, -11517388, -6574341, 2470660, -27417366, 16625501 }, - { -11057722, 3042016, 13770083, -9257922, 584236, -544855, -7770857, 2602725, -27351616, 14247413 }, - { 6314175, -10264892, -32772502, 15957557, -10157730, 168750, -8618807, 14290061, 27108877, -1180880 }, - }, - { - { -8586597, -7170966, 13241782, 10960156, -32991015, -13794596, 33547976, -11058889, -27148451, 981874 }, - { 22833440, 9293594, -32649448, -13618667, -9136966, 14756819, -22928859, -13970780, -10479804, -16197962 }, - { -7768587, 3326786, -28111797, 10783824, 19178761, 14905060, 22680049, 13906969, -15933690, 3797899 }, - }, - { - { 21721356, -4212746, -12206123, 9310182, -3882239, -13653110, 23740224, -2709232, 20491983, -8042152 }, - { 9209270, -15135055, -13256557, -6167798, -731016, 15289673, 25947805, 15286587, 30997318, -6703063 }, - { 7392032, 16618386, 23946583, -8039892, -13265164, -1533858, -14197445, -2321576, 17649998, -250080 }, - }, - { - { -9301088, -14193827, 30609526, -3049543, -25175069, -1283752, -15241566, -9525724, -2233253, 7662146 }, - { -17558673, 1763594, -33114336, 15908610, -30040870, -12174295, 7335080, -8472199, -3174674, 3440183 }, - { -19889700, -5977008, -24111293, -9688870, 10799743, -16571957, 40450, -4431835, 4862400, 1133 }, - }, - { - { -32856209, -7873957, -5422389, 14860950, -16319031, 7956142, 7258061, 311861, -30594991, -7379421 }, - { -3773428, -1565936, 28985340, 7499440, 24445838, 9325937, 29727763, 16527196, 18278453, 15405622 }, - { -4381906, 8508652, -19898366, -3674424, -5984453, 15149970, -13313598, 843523, -21875062, 13626197 }, - }, - { - { 2281448, -13487055, -10915418, -2609910, 1879358, 16164207, -10783882, 3953792, 13340839, 15928663 }, - { 31727126, -7179855, -18437503, -8283652, 2875793, -16390330, -25269894, -7014826, -23452306, 5964753 }, - { 4100420, -5959452, -17179337, 6017714, -18705837, 12227141, -26684835, 11344144, 2538215, -7570755 }, - }, - { - { -9433605, 6123113, 11159803, -2156608, 30016280, 14966241, -20474983, 1485421, -629256, -15958862 }, - { -26804558, 4260919, 11851389, 9658551, -32017107, 16367492, -20205425, -13191288, 11659922, -11115118 }, - { 26180396, 10015009, -30844224, -8581293, 5418197, 9480663, 2231568, -10170080, 33100372, -1306171 }, - }, - { - { 15121113, -5201871, -10389905, 15427821, -27509937, -15992507, 21670947, 4486675, -5931810, -14466380 }, - { 16166486, -9483733, -11104130, 6023908, -31926798, -1364923, 2340060, -16254968, -10735770, -10039824 }, - { 28042865, -3557089, -12126526, 12259706, -3717498, -6945899, 6766453, -8689599, 18036436, 5803270 }, - }, - }, - { - { - { -817581, 6763912, 11803561, 1585585, 10958447, -2671165, 23855391, 4598332, -6159431, -14117438 }, - { -31031306, -14256194, 17332029, -2383520, 31312682, -5967183, 696309, 50292, -20095739, 11763584 }, - { -594563, -2514283, -32234153, 12643980, 12650761, 14811489, 665117, -12613632, -19773211, -10713562 }, - }, - { - { 30464590, -11262872, -4127476, -12734478, 19835327, -7105613, -24396175, 2075773, -17020157, 992471 }, - { 18357185, -6994433, 7766382, 16342475, -29324918, 411174, 14578841, 8080033, -11574335, -10601610 }, - { 19598397, 10334610, 12555054, 2555664, 18821899, -10339780, 21873263, 16014234, 26224780, 16452269 }, - }, - { - { -30223925, 5145196, 5944548, 16385966, 3976735, 2009897, -11377804, -7618186, -20533829, 3698650 }, - { 14187449, 3448569, -10636236, -10810935, -22663880, -3433596, 7268410, -10890444, 27394301, 12015369 }, - { 19695761, 16087646, 28032085, 12999827, 6817792, 11427614, 20244189, -1312777, -13259127, -3402461 }, - }, - { - { 30860103, 12735208, -1888245, -4699734, -16974906, 2256940, -8166013, 12298312, -8550524, -10393462 }, - { -5719826, -11245325, -1910649, 15569035, 26642876, -7587760, -5789354, -15118654, -4976164, 12651793 }, - { -2848395, 9953421, 11531313, -5282879, 26895123, -12697089, -13118820, -16517902, 9768698, -2533218 }, - }, - { - { -24719459, 1894651, -287698, -4704085, 15348719, -8156530, 32767513, 12765450, 4940095, 10678226 }, - { 18860224, 15980149, -18987240, -1562570, -26233012, -11071856, -7843882, 13944024, -24372348, 16582019 }, - { -15504260, 4970268, -29893044, 4175593, -20993212, -2199756, -11704054, 15444560, -11003761, 7989037 }, - }, - { - { 31490452, 5568061, -2412803, 2182383, -32336847, 4531686, -32078269, 6200206, -19686113, -14800171 }, - { -17308668, -15879940, -31522777, -2831, -32887382, 16375549, 8680158, -16371713, 28550068, -6857132 }, - { -28126887, -5688091, 16837845, -1820458, -6850681, 12700016, -30039981, 4364038, 1155602, 5988841 }, - }, - { - { 21890435, -13272907, -12624011, 12154349, -7831873, 15300496, 23148983, -4470481, 24618407, 8283181 }, - { -33136107, -10512751, 9975416, 6841041, -31559793, 16356536, 3070187, -7025928, 1466169, 10740210 }, - { -1509399, -15488185, -13503385, -10655916, 32799044, 909394, -13938903, -5779719, -32164649, -15327040 }, - }, - { - { 3960823, -14267803, -28026090, -15918051, -19404858, 13146868, 15567327, 951507, -3260321, -573935 }, - { 24740841, 5052253, -30094131, 8961361, 25877428, 6165135, -24368180, 14397372, -7380369, -6144105 }, - { -28888365, 3510803, -28103278, -1158478, -11238128, -10631454, -15441463, -14453128, -1625486, -6494814 }, - }, - }, - { - { - { 793299, -9230478, 8836302, -6235707, -27360908, -2369593, 33152843, -4885251, -9906200, -621852 }, - { 5666233, 525582, 20782575, -8038419, -24538499, 14657740, 16099374, 1468826, -6171428, -15186581 }, - { -4859255, -3779343, -2917758, -6748019, 7778750, 11688288, -30404353, -9871238, -1558923, -9863646 }, - }, - { - { 10896332, -7719704, 824275, 472601, -19460308, 3009587, 25248958, 14783338, -30581476, -15757844 }, - { 10566929, 12612572, -31944212, 11118703, -12633376, 12362879, 21752402, 8822496, 24003793, 14264025 }, - { 27713862, -7355973, -11008240, 9227530, 27050101, 2504721, 23886875, -13117525, 13958495, -5732453 }, - }, - { - { -23481610, 4867226, -27247128, 3900521, 29838369, -8212291, -31889399, -10041781, 7340521, -15410068 }, - { 4646514, -8011124, -22766023, -11532654, 23184553, 8566613, 31366726, -1381061, -15066784, -10375192 }, - { -17270517, 12723032, -16993061, 14878794, 21619651, -6197576, 27584817, 3093888, -8843694, 3849921 }, - }, - { - { -9064912, 2103172, 25561640, -15125738, -5239824, 9582958, 32477045, -9017955, 5002294, -15550259 }, - { -12057553, -11177906, 21115585, -13365155, 8808712, -12030708, 16489530, 13378448, -25845716, 12741426 }, - { -5946367, 10645103, -30911586, 15390284, -3286982, -7118677, 24306472, 15852464, 28834118, -7646072 }, - }, - { - { -17335748, -9107057, -24531279, 9434953, -8472084, -583362, -13090771, 455841, 20461858, 5491305 }, - { 13669248, -16095482, -12481974, -10203039, -14569770, -11893198, -24995986, 11293807, -28588204, -9421832 }, - { 28497928, 6272777, -33022994, 14470570, 8906179, -1225630, 18504674, -14165166, 29867745, -8795943 }, - }, - { - { -16207023, 13517196, -27799630, -13697798, 24009064, -6373891, -6367600, -13175392, 22853429, -4012011 }, - { 24191378, 16712145, -13931797, 15217831, 14542237, 1646131, 18603514, -11037887, 12876623, -2112447 }, - { 17902668, 4518229, -411702, -2829247, 26878217, 5258055, -12860753, 608397, 16031844, 3723494 }, - }, - { - { -28632773, 12763728, -20446446, 7577504, 33001348, -13017745, 17558842, -7872890, 23896954, -4314245 }, - { -20005381, -12011952, 31520464, 605201, 2543521, 5991821, -2945064, 7229064, -9919646, -8826859 }, - { 28816045, 298879, -28165016, -15920938, 19000928, -1665890, -12680833, -2949325, -18051778, -2082915 }, - }, - { - { 16000882, -344896, 3493092, -11447198, -29504595, -13159789, 12577740, 16041268, -19715240, 7847707 }, - { 10151868, 10572098, 27312476, 7922682, 14825339, 4723128, -32855931, -6519018, -10020567, 3852848 }, - { -11430470, 15697596, -21121557, -4420647, 5386314, 15063598, 16514493, -15932110, 29330899, -15076224 }, - }, - }, - { - { - { -25499735, -4378794, -15222908, -6901211, 16615731, 2051784, 3303702, 15490, -27548796, 12314391 }, - { 15683520, -6003043, 18109120, -9980648, 15337968, -5997823, -16717435, 15921866, 16103996, -3731215 }, - { -23169824, -10781249, 13588192, -1628807, -3798557, -1074929, -19273607, 5402699, -29815713, -9841101 }, - }, - { - { 23190676, 2384583, -32714340, 3462154, -29903655, -1529132, -11266856, 8911517, -25205859, 2739713 }, - { 21374101, -3554250, -33524649, 9874411, 15377179, 11831242, -33529904, 6134907, 4931255, 11987849 }, - { -7732, -2978858, -16223486, 7277597, 105524, -322051, -31480539, 13861388, -30076310, 10117930 }, - }, - { - { -29501170, -10744872, -26163768, 13051539, -25625564, 5089643, -6325503, 6704079, 12890019, 15728940 }, - { -21972360, -11771379, -951059, -4418840, 14704840, 2695116, 903376, -10428139, 12885167, 8311031 }, - { -17516482, 5352194, 10384213, -13811658, 7506451, 13453191, 26423267, 4384730, 1888765, -5435404 }, - }, - { - { -25817338, -3107312, -13494599, -3182506, 30896459, -13921729, -32251644, -12707869, -19464434, -3340243 }, - { -23607977, -2665774, -526091, 4651136, 5765089, 4618330, 6092245, 14845197, 17151279, -9854116 }, - { -24830458, -12733720, -15165978, 10367250, -29530908, -265356, 22825805, -7087279, -16866484, 16176525 }, - }, - { - { -23583256, 6564961, 20063689, 3798228, -4740178, 7359225, 2006182, -10363426, -28746253, -10197509 }, - { -10626600, -4486402, -13320562, -5125317, 3432136, -6393229, 23632037, -1940610, 32808310, 1099883 }, - { 15030977, 5768825, -27451236, -2887299, -6427378, -15361371, -15277896, -6809350, 2051441, -15225865 }, - }, - { - { -3362323, -7239372, 7517890, 9824992, 23555850, 295369, 5148398, -14154188, -22686354, 16633660 }, - { 4577086, -16752288, 13249841, -15304328, 19958763, -14537274, 18559670, -10759549, 8402478, -9864273 }, - { -28406330, -1051581, -26790155, -907698, -17212414, -11030789, 9453451, -14980072, 17983010, 9967138 }, - }, - { - { -25762494, 6524722, 26585488, 9969270, 24709298, 1220360, -1677990, 7806337, 17507396, 3651560 }, - { -10420457, -4118111, 14584639, 15971087, -15768321, 8861010, 26556809, -5574557, -18553322, -11357135 }, - { 2839101, 14284142, 4029895, 3472686, 14402957, 12689363, -26642121, 8459447, -5605463, -7621941 }, - }, - { - { -4839289, -3535444, 9744961, 2871048, 25113978, 3187018, -25110813, -849066, 17258084, -7977739 }, - { 18164541, -10595176, -17154882, -1542417, 19237078, -9745295, 23357533, -15217008, 26908270, 12150756 }, - { -30264870, -7647865, 5112249, -7036672, -1499807, -6974257, 43168, -5537701, -32302074, 16215819 }, - }, - }, - { - { - { -6898905, 9824394, -12304779, -4401089, -31397141, -6276835, 32574489, 12532905, -7503072, -8675347 }, - { -27343522, -16515468, -27151524, -10722951, 946346, 16291093, 254968, 7168080, 21676107, -1943028 }, - { 21260961, -8424752, -16831886, -11920822, -23677961, 3968121, -3651949, -6215466, -3556191, -7913075 }, - }, - { - { 16544754, 13250366, -16804428, 15546242, -4583003, 12757258, -2462308, -8680336, -18907032, -9662799 }, - { -2415239, -15577728, 18312303, 4964443, -15272530, -12653564, 26820651, 16690659, 25459437, -4564609 }, - { -25144690, 11425020, 28423002, -11020557, -6144921, -15826224, 9142795, -2391602, -6432418, -1644817 }, - }, - { - { -23104652, 6253476, 16964147, -3768872, -25113972, -12296437, -27457225, -16344658, 6335692, 7249989 }, - { -30333227, 13979675, 7503222, -12368314, -11956721, -4621693, -30272269, 2682242, 25993170, -12478523 }, - { 4364628, 5930691, 32304656, -10044554, -8054781, 15091131, 22857016, -10598955, 31820368, 15075278 }, - }, - { - { 31879134, -8918693, 17258761, 90626, -8041836, -4917709, 24162788, -9650886, -17970238, 12833045 }, - { 19073683, 14851414, -24403169, -11860168, 7625278, 11091125, -19619190, 2074449, -9413939, 14905377 }, - { 24483667, -11935567, -2518866, -11547418, -1553130, 15355506, -25282080, 9253129, 27628530, -7555480 }, - }, - { - { 17597607, 8340603, 19355617, 552187, 26198470, -3176583, 4593324, -9157582, -14110875, 15297016 }, - { 510886, 14337390, -31785257, 16638632, 6328095, 2713355, -20217417, -11864220, 8683221, 2921426 }, - { 18606791, 11874196, 27155355, -5281482, -24031742, 6265446, -25178240, -1278924, 4674690, 13890525 }, - }, - { - { 13609624, 13069022, -27372361, -13055908, 24360586, 9592974, 14977157, 9835105, 4389687, 288396 }, - { 9922506, -519394, 13613107, 5883594, -18758345, -434263, -12304062, 8317628, 23388070, 16052080 }, - { 12720016, 11937594, -31970060, -5028689, 26900120, 8561328, -20155687, -11632979, -14754271, -10812892 }, - }, - { - { 15961858, 14150409, 26716931, -665832, -22794328, 13603569, 11829573, 7467844, -28822128, 929275 }, - { 11038231, -11582396, -27310482, -7316562, -10498527, -16307831, -23479533, -9371869, -21393143, 2465074 }, - { 20017163, -4323226, 27915242, 1529148, 12396362, 15675764, 13817261, -9658066, 2463391, -4622140 }, - }, - { - { -16358878, -12663911, -12065183, 4996454, -1256422, 1073572, 9583558, 12851107, 4003896, 12673717 }, - { -1731589, -15155870, -3262930, 16143082, 19294135, 13385325, 14741514, -9103726, 7903886, 2348101 }, - { 24536016, -16515207, 12715592, -3862155, 1511293, 10047386, -3842346, -7129159, -28377538, 10048127 }, - }, - }, - { - { - { -12622226, -6204820, 30718825, 2591312, -10617028, 12192840, 18873298, -7297090, -32297756, 15221632 }, - { -26478122, -11103864, 11546244, -1852483, 9180880, 7656409, -21343950, 2095755, 29769758, 6593415 }, - { -31994208, -2907461, 4176912, 3264766, 12538965, -868111, 26312345, -6118678, 30958054, 8292160 }, - }, - { - { 31429822, -13959116, 29173532, 15632448, 12174511, -2760094, 32808831, 3977186, 26143136, -3148876 }, - { 22648901, 1402143, -22799984, 13746059, 7936347, 365344, -8668633, -1674433, -3758243, -2304625 }, - { -15491917, 8012313, -2514730, -12702462, -23965846, -10254029, -1612713, -1535569, -16664475, 8194478 }, - }, - { - { 27338066, -7507420, -7414224, 10140405, -19026427, -6589889, 27277191, 8855376, 28572286, 3005164 }, - { 26287124, 4821776, 25476601, -4145903, -3764513, -15788984, -18008582, 1182479, -26094821, -13079595 }, - { -7171154, 3178080, 23970071, 6201893, -17195577, -4489192, -21876275, -13982627, 32208683, -1198248 }, - }, - { - { -16657702, 2817643, -10286362, 14811298, 6024667, 13349505, -27315504, -10497842, -27672585, -11539858 }, - { 15941029, -9405932, -21367050, 8062055, 31876073, -238629, -15278393, -1444429, 15397331, -4130193 }, - { 8934485, -13485467, -23286397, -13423241, -32446090, 14047986, 31170398, -1441021, -27505566, 15087184 }, - }, - { - { -18357243, -2156491, 24524913, -16677868, 15520427, -6360776, -15502406, 11461896, 16788528, -5868942 }, - { -1947386, 16013773, 21750665, 3714552, -17401782, -16055433, -3770287, -10323320, 31322514, -11615635 }, - { 21426655, -5650218, -13648287, -5347537, -28812189, -4920970, -18275391, -14621414, 13040862, -12112948 }, - }, - { - { 11293895, 12478086, -27136401, 15083750, -29307421, 14748872, 14555558, -13417103, 1613711, 4896935 }, - { -25894883, 15323294, -8489791, -8057900, 25967126, -13425460, 2825960, -4897045, -23971776, -11267415 }, - { -15924766, -5229880, -17443532, 6410664, 3622847, 10243618, 20615400, 12405433, -23753030, -8436416 }, - }, - { - { -7091295, 12556208, -20191352, 9025187, -17072479, 4333801, 4378436, 2432030, 23097949, -566018 }, - { 4565804, -16025654, 20084412, -7842817, 1724999, 189254, 24767264, 10103221, -18512313, 2424778 }, - { 366633, -11976806, 8173090, -6890119, 30788634, 5745705, -7168678, 1344109, -3642553, 12412659 }, - }, - { - { -24001791, 7690286, 14929416, -168257, -32210835, -13412986, 24162697, -15326504, -3141501, 11179385 }, - { 18289522, -14724954, 8056945, 16430056, -21729724, 7842514, -6001441, -1486897, -18684645, -11443503 }, - { 476239, 6601091, -6152790, -9723375, 17503545, -4863900, 27672959, 13403813, 11052904, 5219329 }, - }, - }, - { - { - { 20678546, -8375738, -32671898, 8849123, -5009758, 14574752, 31186971, -3973730, 9014762, -8579056 }, - { -13644050, -10350239, -15962508, 5075808, -1514661, -11534600, -33102500, 9160280, 8473550, -3256838 }, - { 24900749, 14435722, 17209120, -15292541, -22592275, 9878983, -7689309, -16335821, -24568481, 11788948 }, - }, - { - { -3118155, -11395194, -13802089, 14797441, 9652448, -6845904, -20037437, 10410733, -24568470, -1458691 }, - { -15659161, 16736706, -22467150, 10215878, -9097177, 7563911, 11871841, -12505194, -18513325, 8464118 }, - { -23400612, 8348507, -14585951, -861714, -3950205, -6373419, 14325289, 8628612, 33313881, -8370517 }, - }, - { - { -20186973, -4967935, 22367356, 5271547, -1097117, -4788838, -24805667, -10236854, -8940735, -5818269 }, - { -6948785, -1795212, -32625683, -16021179, 32635414, -7374245, 15989197, -12838188, 28358192, -4253904 }, - { -23561781, -2799059, -32351682, -1661963, -9147719, 10429267, -16637684, 4072016, -5351664, 5596589 }, - }, - { - { -28236598, -3390048, 12312896, 6213178, 3117142, 16078565, 29266239, 2557221, 1768301, 15373193 }, - { -7243358, -3246960, -4593467, -7553353, -127927, -912245, -1090902, -4504991, -24660491, 3442910 }, - { -30210571, 5124043, 14181784, 8197961, 18964734, -11939093, 22597931, 7176455, -18585478, 13365930 }, - }, - { - { -7877390, -1499958, 8324673, 4690079, 6261860, 890446, 24538107, -8570186, -9689599, -3031667 }, - { 25008904, -10771599, -4305031, -9638010, 16265036, 15721635, 683793, -11823784, 15723479, -15163481 }, - { -9660625, 12374379, -27006999, -7026148, -7724114, -12314514, 11879682, 5400171, 519526, -1235876 }, - }, - { - { 22258397, -16332233, -7869817, 14613016, -22520255, -2950923, -20353881, 7315967, 16648397, 7605640 }, - { -8081308, -8464597, -8223311, 9719710, 19259459, -15348212, 23994942, -5281555, -9468848, 4763278 }, - { -21699244, 9220969, -15730624, 1084137, -25476107, -2852390, 31088447, -7764523, -11356529, 728112 }, - }, - { - { 26047220, -11751471, -6900323, -16521798, 24092068, 9158119, -4273545, -12555558, -29365436, -5498272 }, - { 17510331, -322857, 5854289, 8403524, 17133918, -3112612, -28111007, 12327945, 10750447, 10014012 }, - { -10312768, 3936952, 9156313, -8897683, 16498692, -994647, -27481051, -666732, 3424691, 7540221 }, - }, - { - { 30322361, -6964110, 11361005, -4143317, 7433304, 4989748, -7071422, -16317219, -9244265, 15258046 }, - { 13054562, -2779497, 19155474, 469045, -12482797, 4566042, 5631406, 2711395, 1062915, -5136345 }, - { -19240248, -11254599, -29509029, -7499965, -5835763, 13005411, -6066489, 12194497, 32960380, 1459310 }, - }, - }, - { - { - { 19852034, 7027924, 23669353, 10020366, 8586503, -6657907, 394197, -6101885, 18638003, -11174937 }, - { 31395534, 15098109, 26581030, 8030562, -16527914, -5007134, 9012486, -7584354, -6643087, -5442636 }, - { -9192165, -2347377, -1997099, 4529534, 25766844, 607986, -13222, 9677543, -32294889, -6456008 }, - }, - { - { -2444496, -149937, 29348902, 8186665, 1873760, 12489863, -30934579, -7839692, -7852844, -8138429 }, - { -15236356, -15433509, 7766470, 746860, 26346930, -10221762, -27333451, 10754588, -9431476, 5203576 }, - { 31834314, 14135496, -770007, 5159118, 20917671, -16768096, -7467973, -7337524, 31809243, 7347066 }, - }, - { - { -9606723, -11874240, 20414459, 13033986, 13716524, -11691881, 19797970, -12211255, 15192876, -2087490 }, - { -12663563, -2181719, 1168162, -3804809, 26747877, -14138091, 10609330, 12694420, 33473243, -13382104 }, - { 33184999, 11180355, 15832085, -11385430, -1633671, 225884, 15089336, -11023903, -6135662, 14480053 }, - }, - { - { 31308717, -5619998, 31030840, -1897099, 15674547, -6582883, 5496208, 13685227, 27595050, 8737275 }, - { -20318852, -15150239, 10933843, -16178022, 8335352, -7546022, -31008351, -12610604, 26498114, 66511 }, - { 22644454, -8761729, -16671776, 4884562, -3105614, -13559366, 30540766, -4286747, -13327787, -7515095 }, - }, - { - { -28017847, 9834845, 18617207, -2681312, -3401956, -13307506, 8205540, 13585437, -17127465, 15115439 }, - { 23711543, -672915, 31206561, -8362711, 6164647, -9709987, -33535882, -1426096, 8236921, 16492939 }, - { -23910559, -13515526, -26299483, -4503841, 25005590, -7687270, 19574902, 10071562, 6708380, -6222424 }, - }, - { - { 2101391, -4930054, 19702731, 2367575, -15427167, 1047675, 5301017, 9328700, 29955601, -11678310 }, - { 3096359, 9271816, -21620864, -15521844, -14847996, -7592937, -25892142, -12635595, -9917575, 6216608 }, - { -32615849, 338663, -25195611, 2510422, -29213566, -13820213, 24822830, -6146567, -26767480, 7525079 }, - }, - { - { -23066649, -13985623, 16133487, -7896178, -3389565, 778788, -910336, -2782495, -19386633, 11994101 }, - { 21691500, -13624626, -641331, -14367021, 3285881, -3483596, -25064666, 9718258, -7477437, 13381418 }, - { 18445390, -4202236, 14979846, 11622458, -1727110, -3582980, 23111648, -6375247, 28535282, 15779576 }, - }, - { - { 30098053, 3089662, -9234387, 16662135, -21306940, 11308411, -14068454, 12021730, 9955285, -16303356 }, - { 9734894, -14576830, -7473633, -9138735, 2060392, 11313496, -18426029, 9924399, 20194861, 13380996 }, - { -26378102, -7965207, -22167821, 15789297, -18055342, -6168792, -1984914, 15707771, 26342023, 10146099 }, - }, - }, - { - { - { -26016874, -219943, 21339191, -41388, 19745256, -2878700, -29637280, 2227040, 21612326, -545728 }, - { -13077387, 1184228, 23562814, -5970442, -20351244, -6348714, 25764461, 12243797, -20856566, 11649658 }, - { -10031494, 11262626, 27384172, 2271902, 26947504, -15997771, 39944, 6114064, 33514190, 2333242 }, - }, - { - { -21433588, -12421821, 8119782, 7219913, -21830522, -9016134, -6679750, -12670638, 24350578, -13450001 }, - { -4116307, -11271533, -23886186, 4843615, -30088339, 690623, -31536088, -10406836, 8317860, 12352766 }, - { 18200138, -14475911, -33087759, -2696619, -23702521, -9102511, -23552096, -2287550, 20712163, 6719373 }, - }, - { - { 26656208, 6075253, -7858556, 1886072, -28344043, 4262326, 11117530, -3763210, 26224235, -3297458 }, - { -17168938, -14854097, -3395676, -16369877, -19954045, 14050420, 21728352, 9493610, 18620611, -16428628 }, - { -13323321, 13325349, 11432106, 5964811, 18609221, 6062965, -5269471, -9725556, -30701573, -16479657 }, - }, - { - { -23860538, -11233159, 26961357, 1640861, -32413112, -16737940, 12248509, -5240639, 13735342, 1934062 }, - { 25089769, 6742589, 17081145, -13406266, 21909293, -16067981, -15136294, -3765346, -21277997, 5473616 }, - { 31883677, -7961101, 1083432, -11572403, 22828471, 13290673, -7125085, 12469656, 29111212, -5451014 }, - }, - { - { 24244947, -15050407, -26262976, 2791540, -14997599, 16666678, 24367466, 6388839, -10295587, 452383 }, - { -25640782, -3417841, 5217916, 16224624, 19987036, -4082269, -24236251, -5915248, 15766062, 8407814 }, - { -20406999, 13990231, 15495425, 16395525, 5377168, 15166495, -8917023, -4388953, -8067909, 2276718 }, - }, - { - { 30157918, 12924066, -17712050, 9245753, 19895028, 3368142, -23827587, 5096219, 22740376, -7303417 }, - { 2041139, -14256350, 7783687, 13876377, -25946985, -13352459, 24051124, 13742383, -15637599, 13295222 }, - { 33338237, -8505733, 12532113, 7977527, 9106186, -1715251, -17720195, -4612972, -4451357, -14669444 }, - }, - { - { -20045281, 5454097, -14346548, 6447146, 28862071, 1883651, -2469266, -4141880, 7770569, 9620597 }, - { 23208068, 7979712, 33071466, 8149229, 1758231, -10834995, 30945528, -1694323, -33502340, -14767970 }, - { 1439958, -16270480, -1079989, -793782, 4625402, 10647766, -5043801, 1220118, 30494170, -11440799 }, - }, - { - { -5037580, -13028295, -2970559, -3061767, 15640974, -6701666, -26739026, 926050, -1684339, -13333647 }, - { 13908495, -3549272, 30919928, -6273825, -21521863, 7989039, 9021034, 9078865, 3353509, 4033511 }, - { -29663431, -15113610, 32259991, -344482, 24295849, -12912123, 23161163, 8839127, 27485041, 7356032 }, - }, - }, - { - { - { 9661027, 705443, 11980065, -5370154, -1628543, 14661173, -6346142, 2625015, 28431036, -16771834 }, - { -23839233, -8311415, -25945511, 7480958, -17681669, -8354183, -22545972, 14150565, 15970762, 4099461 }, - { 29262576, 16756590, 26350592, -8793563, 8529671, -11208050, 13617293, -9937143, 11465739, 8317062 }, - }, - { - { -25493081, -6962928, 32500200, -9419051, -23038724, -2302222, 14898637, 3848455, 20969334, -5157516 }, - { -20384450, -14347713, -18336405, 13884722, -33039454, 2842114, -21610826, -3649888, 11177095, 14989547 }, - { -24496721, -11716016, 16959896, 2278463, 12066309, 10137771, 13515641, 2581286, -28487508, 9930240 }, - }, - { - { -17751622, -2097826, 16544300, -13009300, -15914807, -14949081, 18345767, -13403753, 16291481, -5314038 }, - { -33229194, 2553288, 32678213, 9875984, 8534129, 6889387, -9676774, 6957617, 4368891, 9788741 }, - { 16660756, 7281060, -10830758, 12911820, 20108584, -8101676, -21722536, -8613148, 16250552, -11111103 }, - }, - { - { -19765507, 2390526, -16551031, 14161980, 1905286, 6414907, 4689584, 10604807, -30190403, 4782747 }, - { -1354539, 14736941, -7367442, -13292886, 7710542, -14155590, -9981571, 4383045, 22546403, 437323 }, - { 31665577, -12180464, -16186830, 1491339, -18368625, 3294682, 27343084, 2786261, -30633590, -14097016 }, - }, - { - { -14467279, -683715, -33374107, 7448552, 19294360, 14334329, -19690631, 2355319, -19284671, -6114373 }, - { 15121312, -15796162, 6377020, -6031361, -10798111, -12957845, 18952177, 15496498, -29380133, 11754228 }, - { -2637277, -13483075, 8488727, -14303896, 12728761, -1622493, 7141596, 11724556, 22761615, -10134141 }, - }, - { - { 16918416, 11729663, -18083579, 3022987, -31015732, -13339659, -28741185, -12227393, 32851222, 11717399 }, - { 11166634, 7338049, -6722523, 4531520, -29468672, -7302055, 31474879, 3483633, -1193175, -4030831 }, - { -185635, 9921305, 31456609, -13536438, -12013818, 13348923, 33142652, 6546660, -19985279, -3948376 }, - }, - { - { -32460596, 11266712, -11197107, -7899103, 31703694, 3855903, -8537131, -12833048, -30772034, -15486313 }, - { -18006477, 12709068, 3991746, -6479188, -21491523, -10550425, -31135347, -16049879, 10928917, 3011958 }, - { -6957757, -15594337, 31696059, 334240, 29576716, 14796075, -30831056, -12805180, 18008031, 10258577 }, - }, - { - { -22448644, 15655569, 7018479, -4410003, -30314266, -1201591, -1853465, 1367120, 25127874, 6671743 }, - { 29701166, -14373934, -10878120, 9279288, -17568, 13127210, 21382910, 11042292, 25838796, 4642684 }, - { -20430234, 14955537, -24126347, 8124619, -5369288, -5990470, 30468147, -13900640, 18423289, 4177476 }, - }, - }, + { + { + { 25967493, -14356035, 29566456, 3660896, -12694345, 4014787, 27544626, -11754271, -6079156, 2047605 }, + { -12545711, 934262, -2722910, 3049990, -727428, 9406986, 12720692, 5043384, 19500929, -15469378 }, + { -8738181, 4489570, 9688441, -14785194, 10184609, -12363380, 29287919, 11864899, -24514362, -4438546 }, + }, + { + { -12815894, -12976347, -21581243, 11784320, -25355658, -2750717, -11717903, -3814571, -358445, -10211303 }, + { -21703237, 6903825, 27185491, 6451973, -29577724, -9554005, -15616551, 11189268, -26829678, -5319081 }, + { 26966642, 11152617, 32442495, 15396054, 14353839, -12752335, -3128826, -9541118, -15472047, -4166697 }, + }, + { + { 15636291, -9688557, 24204773, -7912398, 616977, -16685262, 27787600, -14772189, 28944400, -1550024 }, + { 16568933, 4717097, -11556148, -1102322, 15682896, -11807043, 16354577, -11775962, 7689662, 11199574 }, + { 30464156, -5976125, -11779434, -15670865, 23220365, 15915852, 7512774, 10017326, -17749093, -9920357 }, + }, + { + { -17036878, 13921892, 10945806, -6033431, 27105052, -16084379, -28926210, 15006023, 3284568, -6276540 }, + { 23599295, -8306047, -11193664, -7687416, 13236774, 10506355, 7464579, 9656445, 13059162, 10374397 }, + { 7798556, 16710257, 3033922, 2874086, 28997861, 2835604, 32406664, -3839045, -641708, -101325 }, + }, + { + { 10861363, 11473154, 27284546, 1981175, -30064349, 12577861, 32867885, 14515107, -15438304, 10819380 }, + { 4708026, 6336745, 20377586, 9066809, -11272109, 6594696, -25653668, 12483688, -12668491, 5581306 }, + { 19563160, 16186464, -29386857, 4097519, 10237984, -4348115, 28542350, 13850243, -23678021, -15815942 }, + }, + { + { -15371964, -12862754, 32573250, 4720197, -26436522, 5875511, -19188627, -15224819, -9818940, -12085777 }, + { -8549212, 109983, 15149363, 2178705, 22900618, 4543417, 3044240, -15689887, 1762328, 14866737 }, + { -18199695, -15951423, -10473290, 1707278, -17185920, 3916101, -28236412, 3959421, 27914454, 4383652 }, + }, + { + { 5153746, 9909285, 1723747, -2777874, 30523605, 5516873, 19480852, 5230134, -23952439, -15175766 }, + { -30269007, -3463509, 7665486, 10083793, 28475525, 1649722, 20654025, 16520125, 30598449, 7715701 }, + { 28881845, 14381568, 9657904, 3680757, -20181635, 7843316, -31400660, 1370708, 29794553, -1409300 }, + }, + { + { 14499471, -2729599, -33191113, -4254652, 28494862, 14271267, 30290735, 10876454, -33154098, 2381726 }, + { -7195431, -2655363, -14730155, 462251, -27724326, 3941372, -6236617, 3696005, -32300832, 15351955 }, + { 27431194, 8222322, 16448760, -3907995, -18707002, 11938355, -32961401, -2970515, 29551813, 10109425 }, + }, + }, + { + { + { -13657040, -13155431, -31283750, 11777098, 21447386, 6519384, -2378284, -1627556, 10092783, -4764171 }, + { 27939166, 14210322, 4677035, 16277044, -22964462, -12398139, -32508754, 12005538, -17810127, 12803510 }, + { 17228999, -15661624, -1233527, 300140, -1224870, -11714777, 30364213, -9038194, 18016357, 4397660 }, + }, + { + { -10958843, -7690207, 4776341, -14954238, 27850028, -15602212, -26619106, 14544525, -17477504, 982639 }, + { 29253598, 15796703, -2863982, -9908884, 10057023, 3163536, 7332899, -4120128, -21047696, 9934963 }, + { 5793303, 16271923, -24131614, -10116404, 29188560, 1206517, -14747930, 4559895, -30123922, -10897950 }, + }, + { + { -27643952, -11493006, 16282657, -11036493, 28414021, -15012264, 24191034, 4541697, -13338309, 5500568 }, + { 12650548, -1497113, 9052871, 11355358, -17680037, -8400164, -17430592, 12264343, 10874051, 13524335 }, + { 25556948, -3045990, 714651, 2510400, 23394682, -10415330, 33119038, 5080568, -22528059, 5376628 }, + }, + { + { -26088264, -4011052, -17013699, -3537628, -6726793, 1920897, -22321305, -9447443, 4535768, 1569007 }, + { -2255422, 14606630, -21692440, -8039818, 28430649, 8775819, -30494562, 3044290, 31848280, 12543772 }, + { -22028579, 2943893, -31857513, 6777306, 13784462, -4292203, -27377195, -2062731, 7718482, 14474653 }, + }, + { + { 2385315, 2454213, -22631320, 46603, -4437935, -15680415, 656965, -7236665, 24316168, -5253567 }, + { 13741529, 10911568, -33233417, -8603737, -20177830, -1033297, 33040651, -13424532, -20729456, 8321686 }, + { 21060490, -2212744, 15712757, -4336099, 1639040, 10656336, 23845965, -11874838, -9984458, 608372 }, + }, + { + { -13672732, -15087586, -10889693, -7557059, -6036909, 11305547, 1123968, -6780577, 27229399, 23887 }, + { -23244140, -294205, -11744728, 14712571, -29465699, -2029617, 12797024, -6440308, -1633405, 16678954 }, + { -29500620, 4770662, -16054387, 14001338, 7830047, 9564805, -1508144, -4795045, -17169265, 4904953 }, + }, + { + { 24059557, 14617003, 19037157, -15039908, 19766093, -14906429, 5169211, 16191880, 2128236, -4326833 }, + { -16981152, 4124966, -8540610, -10653797, 30336522, -14105247, -29806336, 916033, -6882542, -2986532 }, + { -22630907, 12419372, -7134229, -7473371, -16478904, 16739175, 285431, 2763829, 15736322, 4143876 }, + }, + { + { 2379352, 11839345, -4110402, -5988665, 11274298, 794957, 212801, -14594663, 23527084, -16458268 }, + { 33431127, -11130478, -17838966, -15626900, 8909499, 8376530, -32625340, 4087881, -15188911, -14416214 }, + { 1767683, 7197987, -13205226, -2022635, -13091350, 448826, 5799055, 4357868, -4774191, -16323038 }, + }, + }, + { + { + { 6721966, 13833823, -23523388, -1551314, 26354293, -11863321, 23365147, -3949732, 7390890, 2759800 }, + { 4409041, 2052381, 23373853, 10530217, 7676779, -12885954, 21302353, -4264057, 1244380, -12919645 }, + { -4421239, 7169619, 4982368, -2957590, 30256825, -2777540, 14086413, 9208236, 15886429, 16489664 }, + }, + { + { 1996075, 10375649, 14346367, 13311202, -6874135, -16438411, -13693198, 398369, -30606455, -712933 }, + { -25307465, 9795880, -2777414, 14878809, -33531835, 14780363, 13348553, 12076947, -30836462, 5113182 }, + { -17770784, 11797796, 31950843, 13929123, -25888302, 12288344, -30341101, -7336386, 13847711, 5387222 }, + }, + { + { -18582163, -3416217, 17824843, -2340966, 22744343, -10442611, 8763061, 3617786, -19600662, 10370991 }, + { 20246567, -14369378, 22358229, -543712, 18507283, -10413996, 14554437, -8746092, 32232924, 16763880 }, + { 9648505, 10094563, 26416693, 14745928, -30374318, -6472621, 11094161, 15689506, 3140038, -16510092 }, + }, + { + { -16160072, 5472695, 31895588, 4744994, 8823515, 10365685, -27224800, 9448613, -28774454, 366295 }, + { 19153450, 11523972, -11096490, -6503142, -24647631, 5420647, 28344573, 8041113, 719605, 11671788 }, + { 8678025, 2694440, -6808014, 2517372, 4964326, 11152271, -15432916, -15266516, 27000813, -10195553 }, + }, + { + { -15157904, 7134312, 8639287, -2814877, -7235688, 10421742, 564065, 5336097, 6750977, -14521026 }, + { 11836410, -3979488, 26297894, 16080799, 23455045, 15735944, 1695823, -8819122, 8169720, 16220347 }, + { -18115838, 8653647, 17578566, -6092619, -8025777, -16012763, -11144307, -2627664, -5990708, -14166033 }, + }, + { + { -23308498, -10968312, 15213228, -10081214, -30853605, -11050004, 27884329, 2847284, 2655861, 1738395 }, + { -27537433, -14253021, -25336301, -8002780, -9370762, 8129821, 21651608, -3239336, -19087449, -11005278 }, + { 1533110, 3437855, 23735889, 459276, 29970501, 11335377, 26030092, 5821408, 10478196, 8544890 }, + }, + { + { 32173121, -16129311, 24896207, 3921497, 22579056, -3410854, 19270449, 12217473, 17789017, -3395995 }, + { -30552961, -2228401, -15578829, -10147201, 13243889, 517024, 15479401, -3853233, 30460520, 1052596 }, + { -11614875, 13323618, 32618793, 8175907, -15230173, 12596687, 27491595, -4612359, 3179268, -9478891 }, + }, + { + { 31947069, -14366651, -4640583, -15339921, -15125977, -6039709, -14756777, -16411740, 19072640, -9511060 }, + { 11685058, 11822410, 3158003, -13952594, 33402194, -4165066, 5977896, -5215017, 473099, 5040608 }, + { -20290863, 8198642, -27410132, 11602123, 1290375, -2799760, 28326862, 1721092, -19558642, -3131606 }, + }, + }, + { + { + { 7881532, 10687937, 7578723, 7738378, -18951012, -2553952, 21820786, 8076149, -27868496, 11538389 }, + { -19935666, 3899861, 18283497, -6801568, -15728660, -11249211, 8754525, 7446702, -5676054, 5797016 }, + { -11295600, -3793569, -15782110, -7964573, 12708869, -8456199, 2014099, -9050574, -2369172, -5877341 }, + }, + { + { -22472376, -11568741, -27682020, 1146375, 18956691, 16640559, 1192730, -3714199, 15123619, 10811505 }, + { 14352098, -3419715, -18942044, 10822655, 32750596, 4699007, -70363, 15776356, -28886779, -11974553 }, + { -28241164, -8072475, -4978962, -5315317, 29416931, 1847569, -20654173, -16484855, 4714547, -9600655 }, + }, + { + { 15200332, 8368572, 19679101, 15970074, -31872674, 1959451, 24611599, -4543832, -11745876, 12340220 }, + { 12876937, -10480056, 33134381, 6590940, -6307776, 14872440, 9613953, 8241152, 15370987, 9608631 }, + { -4143277, -12014408, 8446281, -391603, 4407738, 13629032, -7724868, 15866074, -28210621, -8814099 }, + }, + { + { 26660628, -15677655, 8393734, 358047, -7401291, 992988, -23904233, 858697, 20571223, 8420556 }, + { 14620715, 13067227, -15447274, 8264467, 14106269, 15080814, 33531827, 12516406, -21574435, -12476749 }, + { 236881, 10476226, 57258, -14677024, 6472998, 2466984, 17258519, 7256740, 8791136, 15069930 }, + }, + { + { 1276410, -9371918, 22949635, -16322807, -23493039, -5702186, 14711875, 4874229, -30663140, -2331391 }, + { 5855666, 4990204, -13711848, 7294284, -7804282, 1924647, -1423175, -7912378, -33069337, 9234253 }, + { 20590503, -9018988, 31529744, -7352666, -2706834, 10650548, 31559055, -11609587, 18979186, 13396066 }, + }, + { + { 24474287, 4968103, 22267082, 4407354, 24063882, -8325180, -18816887, 13594782, 33514650, 7021958 }, + { -11566906, -6565505, -21365085, 15928892, -26158305, 4315421, -25948728, -3916677, -21480480, 12868082 }, + { -28635013, 13504661, 19988037, -2132761, 21078225, 6443208, -21446107, 2244500, -12455797, -8089383 }, + }, + { + { -30595528, 13793479, -5852820, 319136, -25723172, -6263899, 33086546, 8957937, -15233648, 5540521 }, + { -11630176, -11503902, -8119500, -7643073, 2620056, 1022908, -23710744, -1568984, -16128528, -14962807 }, + { 23152971, 775386, 27395463, 14006635, -9701118, 4649512, 1689819, 892185, -11513277, -15205948 }, + }, + { + { 9770129, 9586738, 26496094, 4324120, 1556511, -3550024, 27453819, 4763127, -19179614, 5867134 }, + { -32765025, 1927590, 31726409, -4753295, 23962434, -16019500, 27846559, 5931263, -29749703, -16108455 }, + { 27461885, -2977536, 22380810, 1815854, -23033753, -3031938, 7283490, -15148073, -19526700, 7734629 }, + }, + }, + { + { + { -8010264, -9590817, -11120403, 6196038, 29344158, -13430885, 7585295, -3176626, 18549497, 15302069 }, + { -32658337, -6171222, -7672793, -11051681, 6258878, 13504381, 10458790, -6418461, -8872242, 8424746 }, + { 24687205, 8613276, -30667046, -3233545, 1863892, -1830544, 19206234, 7134917, -11284482, -828919 }, + }, + { + { 11334899, -9218022, 8025293, 12707519, 17523892, -10476071, 10243738, -14685461, -5066034, 16498837 }, + { 8911542, 6887158, -9584260, -6958590, 11145641, -9543680, 17303925, -14124238, 6536641, 10543906 }, + { -28946384, 15479763, -17466835, 568876, -1497683, 11223454, -2669190, -16625574, -27235709, 8876771 }, + }, + { + { -25742899, -12566864, -15649966, -846607, -33026686, -796288, -33481822, 15824474, -604426, -9039817 }, + { 10330056, 70051, 7957388, -9002667, 9764902, 15609756, 27698697, -4890037, 1657394, 3084098 }, + { 10477963, -7470260, 12119566, -13250805, 29016247, -5365589, 31280319, 14396151, -30233575, 15272409 }, + }, + { + { -12288309, 3169463, 28813183, 16658753, 25116432, -5630466, -25173957, -12636138, -25014757, 1950504 }, + { -26180358, 9489187, 11053416, -14746161, -31053720, 5825630, -8384306, -8767532, 15341279, 8373727 }, + { 28685821, 7759505, -14378516, -12002860, -31971820, 4079242, 298136, -10232602, -2878207, 15190420 }, + }, + { + { -32932876, 13806336, -14337485, -15794431, -24004620, 10940928, 8669718, 2742393, -26033313, -6875003 }, + { -1580388, -11729417, -25979658, -11445023, -17411874, -10912854, 9291594, -16247779, -12154742, 6048605 }, + { -30305315, 14843444, 1539301, 11864366, 20201677, 1900163, 13934231, 5128323, 11213262, 9168384 }, + }, + { + { -26280513, 11007847, 19408960, -940758, -18592965, -4328580, -5088060, -11105150, 20470157, -16398701 }, + { -23136053, 9282192, 14855179, -15390078, -7362815, -14408560, -22783952, 14461608, 14042978, 5230683 }, + { 29969567, -2741594, -16711867, -8552442, 9175486, -2468974, 21556951, 3506042, -5933891, -12449708 }, + }, + { + { -3144746, 8744661, 19704003, 4581278, -20430686, 6830683, -21284170, 8971513, -28539189, 15326563 }, + { -19464629, 10110288, -17262528, -3503892, -23500387, 1355669, -15523050, 15300988, -20514118, 9168260 }, + { -5353335, 4488613, -23803248, 16314347, 7780487, -15638939, -28948358, 9601605, 33087103, -9011387 }, + }, + { + { -19443170, -15512900, -20797467, -12445323, -29824447, 10229461, -27444329, -15000531, -5996870, 15664672 }, + { 23294591, -16632613, -22650781, -8470978, 27844204, 11461195, 13099750, -2460356, 18151676, 13417686 }, + { -24722913, -4176517, -31150679, 5988919, -26858785, 6685065, 1661597, -12551441, 15271676, -15452665 }, + }, + }, + { + { + { 11433042, -13228665, 8239631, -5279517, -1985436, -725718, -18698764, 2167544, -6921301, -13440182 }, + { -31436171, 15575146, 30436815, 12192228, -22463353, 9395379, -9917708, -8638997, 12215110, 12028277 }, + { 14098400, 6555944, 23007258, 5757252, -15427832, -12950502, 30123440, 4617780, -16900089, -655628 }, + }, + { + { -4026201, -15240835, 11893168, 13718664, -14809462, 1847385, -15819999, 10154009, 23973261, -12684474 }, + { -26531820, -3695990, -1908898, 2534301, -31870557, -16550355, 18341390, -11419951, 32013174, -10103539 }, + { -25479301, 10876443, -11771086, -14625140, -12369567, 1838104, 21911214, 6354752, 4425632, -837822 }, + }, + { + { -10433389, -14612966, 22229858, -3091047, -13191166, 776729, -17415375, -12020462, 4725005, 14044970 }, + { 19268650, -7304421, 1555349, 8692754, -21474059, -9910664, 6347390, -1411784, -19522291, -16109756 }, + { -24864089, 12986008, -10898878, -5558584, -11312371, -148526, 19541418, 8180106, 9282262, 10282508 }, + }, + { + { -26205082, 4428547, -8661196, -13194263, 4098402, -14165257, 15522535, 8372215, 5542595, -10702683 }, + { -10562541, 14895633, 26814552, -16673850, -17480754, -2489360, -2781891, 6993761, -18093885, 10114655 }, + { -20107055, -929418, 31422704, 10427861, -7110749, 6150669, -29091755, -11529146, 25953725, -106158 }, + }, + { + { -4234397, -8039292, -9119125, 3046000, 2101609, -12607294, 19390020, 6094296, -3315279, 12831125 }, + { -15998678, 7578152, 5310217, 14408357, -33548620, -224739, 31575954, 6326196, 7381791, -2421839 }, + { -20902779, 3296811, 24736065, -16328389, 18374254, 7318640, 6295303, 8082724, -15362489, 12339664 }, + }, + { + { 27724736, 2291157, 6088201, -14184798, 1792727, 5857634, 13848414, 15768922, 25091167, 14856294 }, + { -18866652, 8331043, 24373479, 8541013, -701998, -9269457, 12927300, -12695493, -22182473, -9012899 }, + { -11423429, -5421590, 11632845, 3405020, 30536730, -11674039, -27260765, 13866390, 30146206, 9142070 }, + }, + { + { 3924129, -15307516, -13817122, -10054960, 12291820, -668366, -27702774, 9326384, -8237858, 4171294 }, + { -15921940, 16037937, 6713787, 16606682, -21612135, 2790944, 26396185, 3731949, 345228, -5462949 }, + { -21327538, 13448259, 25284571, 1143661, 20614966, -8849387, 2031539, -12391231, -16253183, -13582083 }, + }, + { + { 31016211, -16722429, 26371392, -14451233, -5027349, 14854137, 17477601, 3842657, 28012650, -16405420 }, + { -5075835, 9368966, -8562079, -4600902, -15249953, 6970560, -9189873, 16292057, -8867157, 3507940 }, + { 29439664, 3537914, 23333589, 6997794, -17555561, -11018068, -15209202, -15051267, -9164929, 6580396 }, + }, + }, + { + { + { -12185861, -7679788, 16438269, 10826160, -8696817, -6235611, 17860444, -9273846, -2095802, 9304567 }, + { 20714564, -4336911, 29088195, 7406487, 11426967, -5095705, 14792667, -14608617, 5289421, -477127 }, + { -16665533, -10650790, -6160345, -13305760, 9192020, -1802462, 17271490, 12349094, 26939669, -3752294 }, + }, + { + { -12889898, 9373458, 31595848, 16374215, 21471720, 13221525, -27283495, -12348559, -3698806, 117887 }, + { 22263325, -6560050, 3984570, -11174646, -15114008, -566785, 28311253, 5358056, -23319780, 541964 }, + { 16259219, 3261970, 2309254, -15534474, -16885711, -4581916, 24134070, -16705829, -13337066, -13552195 }, + }, + { + { 9378160, -13140186, -22845982, -12745264, 28198281, -7244098, -2399684, -717351, 690426, 14876244 }, + { 24977353, -314384, -8223969, -13465086, 28432343, -1176353, -13068804, -12297348, -22380984, 6618999 }, + { -1538174, 11685646, 12944378, 13682314, -24389511, -14413193, 8044829, -13817328, 32239829, -5652762 }, + }, + { + { -18603066, 4762990, -926250, 8885304, -28412480, -3187315, 9781647, -10350059, 32779359, 5095274 }, + { -33008130, -5214506, -32264887, -3685216, 9460461, -9327423, -24601656, 14506724, 21639561, -2630236 }, + { -16400943, -13112215, 25239338, 15531969, 3987758, -4499318, -1289502, -6863535, 17874574, 558605 }, + }, + { + { -13600129, 10240081, 9171883, 16131053, -20869254, 9599700, 33499487, 5080151, 2085892, 5119761 }, + { -22205145, -2519528, -16381601, 414691, -25019550, 2170430, 30634760, -8363614, -31999993, -5759884 }, + { -6845704, 15791202, 8550074, -1312654, 29928809, -12092256, 27534430, -7192145, -22351378, 12961482 }, + }, + { + { -24492060, -9570771, 10368194, 11582341, -23397293, -2245287, 16533930, 8206996, -30194652, -5159638 }, + { -11121496, -3382234, 2307366, 6362031, -135455, 8868177, -16835630, 7031275, 7589640, 8945490 }, + { -32152748, 8917967, 6661220, -11677616, -1192060, -15793393, 7251489, -11182180, 24099109, -14456170 }, + }, + { + { 5019558, -7907470, 4244127, -14714356, -26933272, 6453165, -19118182, -13289025, -6231896, -10280736 }, + { 10853594, 10721687, 26480089, 5861829, -22995819, 1972175, -1866647, -10557898, -3363451, -6441124 }, + { -17002408, 5906790, 221599, -6563147, 7828208, -13248918, 24362661, -2008168, -13866408, 7421392 }, + }, + { + { 8139927, -6546497, 32257646, -5890546, 30375719, 1886181, -21175108, 15441252, 28826358, -4123029 }, + { 6267086, 9695052, 7709135, -16603597, -32869068, -1886135, 14795160, -7840124, 13746021, -1742048 }, + { 28584902, 7787108, -6732942, -15050729, 22846041, -7571236, -3181936, -363524, 4771362, -8419958 }, + }, + }, + { + { + { 24949256, 6376279, -27466481, -8174608, -18646154, -9930606, 33543569, -12141695, 3569627, 11342593 }, + { 26514989, 4740088, 27912651, 3697550, 19331575, -11472339, 6809886, 4608608, 7325975, -14801071 }, + { -11618399, -14554430, -24321212, 7655128, -1369274, 5214312, -27400540, 10258390, -17646694, -8186692 }, + }, + { + { 11431204, 15823007, 26570245, 14329124, 18029990, 4796082, -31446179, 15580664, 9280358, -3973687 }, + { -160783, -10326257, -22855316, -4304997, -20861367, -13621002, -32810901, -11181622, -15545091, 4387441 }, + { -20799378, 12194512, 3937617, -5805892, -27154820, 9340370, -24513992, 8548137, 20617071, -7482001 }, + }, + { + { -938825, -3930586, -8714311, 16124718, 24603125, -6225393, -13775352, -11875822, 24345683, 10325460 }, + { -19855277, -1568885, -22202708, 8714034, 14007766, 6928528, 16318175, -1010689, 4766743, 3552007 }, + { -21751364, -16730916, 1351763, -803421, -4009670, 3950935, 3217514, 14481909, 10988822, -3994762 }, + }, + { + { 15564307, -14311570, 3101243, 5684148, 30446780, -8051356, 12677127, -6505343, -8295852, 13296005 }, + { -9442290, 6624296, -30298964, -11913677, -4670981, -2057379, 31521204, 9614054, -30000824, 12074674 }, + { 4771191, -135239, 14290749, -13089852, 27992298, 14998318, -1413936, -1556716, 29832613, -16391035 }, + }, + { + { 7064884, -7541174, -19161962, -5067537, -18891269, -2912736, 25825242, 5293297, -27122660, 13101590 }, + { -2298563, 2439670, -7466610, 1719965, -27267541, -16328445, 32512469, -5317593, -30356070, -4190957 }, + { -30006540, 10162316, -33180176, 3981723, -16482138, -13070044, 14413974, 9515896, 19568978, 9628812 }, + }, + { + { 33053803, 199357, 15894591, 1583059, 27380243, -4580435, -17838894, -6106839, -6291786, 3437740 }, + { -18978877, 3884493, 19469877, 12726490, 15913552, 13614290, -22961733, 70104, 7463304, 4176122 }, + { -27124001, 10659917, 11482427, -16070381, 12771467, -6635117, -32719404, -5322751, 24216882, 5944158 }, + }, + { + { 8894125, 7450974, -2664149, -9765752, -28080517, -12389115, 19345746, 14680796, 11632993, 5847885 }, + { 26942781, -2315317, 9129564, -4906607, 26024105, 11769399, -11518837, 6367194, -9727230, 4782140 }, + { 19916461, -4828410, -22910704, -11414391, 25606324, -5972441, 33253853, 8220911, 6358847, -1873857 }, + }, + { + { 801428, -2081702, 16569428, 11065167, 29875704, 96627, 7908388, -4480480, -13538503, 1387155 }, + { 19646058, 5720633, -11416706, 12814209, 11607948, 12749789, 14147075, 15156355, -21866831, 11835260 }, + { 19299512, 1155910, 28703737, 14890794, 2925026, 7269399, 26121523, 15467869, -26560550, 5052483 }, + }, + }, + { + { + { -3017432, 10058206, 1980837, 3964243, 22160966, 12322533, -6431123, -12618185, 12228557, -7003677 }, + { 32944382, 14922211, -22844894, 5188528, 21913450, -8719943, 4001465, 13238564, -6114803, 8653815 }, + { 22865569, -4652735, 27603668, -12545395, 14348958, 8234005, 24808405, 5719875, 28483275, 2841751 }, + }, + { + { -16420968, -1113305, -327719, -12107856, 21886282, -15552774, -1887966, -315658, 19932058, -12739203 }, + { -11656086, 10087521, -8864888, -5536143, -19278573, -3055912, 3999228, 13239134, -4777469, -13910208 }, + { 1382174, -11694719, 17266790, 9194690, -13324356, 9720081, 20403944, 11284705, -14013818, 3093230 }, + }, + { + { 16650921, -11037932, -1064178, 1570629, -8329746, 7352753, -302424, 16271225, -24049421, -6691850 }, + { -21911077, -5927941, -4611316, -5560156, -31744103, -10785293, 24123614, 15193618, -21652117, -16739389 }, + { -9935934, -4289447, -25279823, 4372842, 2087473, 10399484, 31870908, 14690798, 17361620, 11864968 }, + }, + { + { -11307610, 6210372, 13206574, 5806320, -29017692, -13967200, -12331205, -7486601, -25578460, -16240689 }, + { 14668462, -12270235, 26039039, 15305210, 25515617, 4542480, 10453892, 6577524, 9145645, -6443880 }, + { 5974874, 3053895, -9433049, -10385191, -31865124, 3225009, -7972642, 3936128, -5652273, -3050304 }, + }, + { + { 30625386, -4729400, -25555961, -12792866, -20484575, 7695099, 17097188, -16303496, -27999779, 1803632 }, + { -3553091, 9865099, -5228566, 4272701, -5673832, -16689700, 14911344, 12196514, -21405489, 7047412 }, + { 20093277, 9920966, -11138194, -5343857, 13161587, 12044805, -32856851, 4124601, -32343828, -10257566 }, + }, + { + { -20788824, 14084654, -13531713, 7842147, 19119038, -13822605, 4752377, -8714640, -21679658, 2288038 }, + { -26819236, -3283715, 29965059, 3039786, -14473765, 2540457, 29457502, 14625692, -24819617, 12570232 }, + { -1063558, -11551823, 16920318, 12494842, 1278292, -5869109, -21159943, -3498680, -11974704, 4724943 }, + }, + { + { 17960970, -11775534, -4140968, -9702530, -8876562, -1410617, -12907383, -8659932, -29576300, 1903856 }, + { 23134274, -14279132, -10681997, -1611936, 20684485, 15770816, -12989750, 3190296, 26955097, 14109738 }, + { 15308788, 5320727, -30113809, -14318877, 22902008, 7767164, 29425325, -11277562, 31960942, 11934971 }, + }, + { + { -27395711, 8435796, 4109644, 12222639, -24627868, 14818669, 20638173, 4875028, 10491392, 1379718 }, + { -13159415, 9197841, 3875503, -8936108, -1383712, -5879801, 33518459, 16176658, 21432314, 12180697 }, + { -11787308, 11500838, 13787581, -13832590, -22430679, 10140205, 1465425, 12689540, -10301319, -13872883 }, + }, + }, + { + { + { 5414091, -15386041, -21007664, 9643570, 12834970, 1186149, -2622916, -1342231, 26128231, 6032912 }, + { -26337395, -13766162, 32496025, -13653919, 17847801, -12669156, 3604025, 8316894, -25875034, -10437358 }, + { 3296484, 6223048, 24680646, -12246460, -23052020, 5903205, -8862297, -4639164, 12376617, 3188849 }, + }, + { + { 29190488, -14659046, 27549113, -1183516, 3520066, -10697301, 32049515, -7309113, -16109234, -9852307 }, + { -14744486, -9309156, 735818, -598978, -20407687, -5057904, 25246078, -15795669, 18640741, -960977 }, + { -6928835, -16430795, 10361374, 5642961, 4910474, 12345252, -31638386, -494430, 10530747, 1053335 }, + }, + { + { -29265967, -14186805, -13538216, -12117373, -19457059, -10655384, -31462369, -2948985, 24018831, 15026644 }, + { -22592535, -3145277, -2289276, 5953843, -13440189, 9425631, 25310643, 13003497, -2314791, -15145616 }, + { -27419985, -603321, -8043984, -1669117, -26092265, 13987819, -27297622, 187899, -23166419, -2531735 }, + }, + { + { -21744398, -13810475, 1844840, 5021428, -10434399, -15911473, 9716667, 16266922, -5070217, 726099 }, + { 29370922, -6053998, 7334071, -15342259, 9385287, 2247707, -13661962, -4839461, 30007388, -15823341 }, + { -936379, 16086691, 23751945, -543318, -1167538, -5189036, 9137109, 730663, 9835848, 4555336 }, + }, + { + { -23376435, 1410446, -22253753, -12899614, 30867635, 15826977, 17693930, 544696, -11985298, 12422646 }, + { 31117226, -12215734, -13502838, 6561947, -9876867, -12757670, -5118685, -4096706, 29120153, 13924425 }, + { -17400879, -14233209, 19675799, -2734756, -11006962, -5858820, -9383939, -11317700, 7240931, -237388 }, + }, + { + { -31361739, -11346780, -15007447, -5856218, -22453340, -12152771, 1222336, 4389483, 3293637, -15551743 }, + { -16684801, -14444245, 11038544, 11054958, -13801175, -3338533, -24319580, 7733547, 12796905, -6335822 }, + { -8759414, -10817836, -25418864, 10783769, -30615557, -9746811, -28253339, 3647836, 3222231, -11160462 }, + }, + { + { 18606113, 1693100, -25448386, -15170272, 4112353, 10045021, 23603893, -2048234, -7550776, 2484985 }, + { 9255317, -3131197, -12156162, -1004256, 13098013, -9214866, 16377220, -2102812, -19802075, -3034702 }, + { -22729289, 7496160, -5742199, 11329249, 19991973, -3347502, -31718148, 9936966, -30097688, -10618797 }, + }, + { + { 21878590, -5001297, 4338336, 13643897, -3036865, 13160960, 19708896, 5415497, -7360503, -4109293 }, + { 27736861, 10103576, 12500508, 8502413, -3413016, -9633558, 10436918, -1550276, -23659143, -8132100 }, + { 19492550, -12104365, -29681976, -852630, -3208171, 12403437, 30066266, 8367329, 13243957, 8709688 }, + }, + }, + { + { + { 12015105, 2801261, 28198131, 10151021, 24818120, -4743133, -11194191, -5645734, 5150968, 7274186 }, + { 2831366, -12492146, 1478975, 6122054, 23825128, -12733586, 31097299, 6083058, 31021603, -9793610 }, + { -2529932, -2229646, 445613, 10720828, -13849527, -11505937, -23507731, 16354465, 15067285, -14147707 }, + }, + { + { 7840942, 14037873, -33364863, 15934016, -728213, -3642706, 21403988, 1057586, -19379462, -12403220 }, + { 915865, -16469274, 15608285, -8789130, -24357026, 6060030, -17371319, 8410997, -7220461, 16527025 }, + { 32922597, -556987, 20336074, -16184568, 10903705, -5384487, 16957574, 52992, 23834301, 6588044 }, + }, + { + { 32752030, 11232950, 3381995, -8714866, 22652988, -10744103, 17159699, 16689107, -20314580, -1305992 }, + { -4689649, 9166776, -25710296, -10847306, 11576752, 12733943, 7924251, -2752281, 1976123, -7249027 }, + { 21251222, 16309901, -2983015, -6783122, 30810597, 12967303, 156041, -3371252, 12331345, -8237197 }, + }, + { + { 8651614, -4477032, -16085636, -4996994, 13002507, 2950805, 29054427, -5106970, 10008136, -4667901 }, + { 31486080, 15114593, -14261250, 12951354, 14369431, -7387845, 16347321, -13662089, 8684155, -10532952 }, + { 19443825, 11385320, 24468943, -9659068, -23919258, 2187569, -26263207, -6086921, 31316348, 14219878 }, + }, + { + { -28594490, 1193785, 32245219, 11392485, 31092169, 15722801, 27146014, 6992409, 29126555, 9207390 }, + { 32382935, 1110093, 18477781, 11028262, -27411763, -7548111, -4980517, 10843782, -7957600, -14435730 }, + { 2814918, 7836403, 27519878, -7868156, -20894015, -11553689, -21494559, 8550130, 28346258, 1994730 }, + }, + { + { -19578299, 8085545, -14000519, -3948622, 2785838, -16231307, -19516951, 7174894, 22628102, 8115180 }, + { -30405132, 955511, -11133838, -15078069, -32447087, -13278079, -25651578, 3317160, -9943017, 930272 }, + { -15303681, -6833769, 28856490, 1357446, 23421993, 1057177, 24091212, -1388970, -22765376, -10650715 }, + }, + { + { -22751231, -5303997, -12907607, -12768866, -15811511, -7797053, -14839018, -16554220, -1867018, 8398970 }, + { -31969310, 2106403, -4736360, 1362501, 12813763, 16200670, 22981545, -6291273, 18009408, -15772772 }, + { -17220923, -9545221, -27784654, 14166835, 29815394, 7444469, 29551787, -3727419, 19288549, 1325865 }, + }, + { + { 15100157, -15835752, -23923978, -1005098, -26450192, 15509408, 12376730, -3479146, 33166107, -8042750 }, + { 20909231, 13023121, -9209752, 16251778, -5778415, -8094914, 12412151, 10018715, 2213263, -13878373 }, + { 32529814, -11074689, 30361439, -16689753, -9135940, 1513226, 22922121, 6382134, -5766928, 8371348 }, + }, + }, + { + { + { 9923462, 11271500, 12616794, 3544722, -29998368, -1721626, 12891687, -8193132, -26442943, 10486144 }, + { -22597207, -7012665, 8587003, -8257861, 4084309, -12970062, 361726, 2610596, -23921530, -11455195 }, + { 5408411, -1136691, -4969122, 10561668, 24145918, 14240566, 31319731, -4235541, 19985175, -3436086 }, + }, + { + { -13994457, 16616821, 14549246, 3341099, 32155958, 13648976, -17577068, 8849297, 65030, 8370684 }, + { -8320926, -12049626, 31204563, 5839400, -20627288, -1057277, -19442942, 6922164, 12743482, -9800518 }, + { -2361371, 12678785, 28815050, 4759974, -23893047, 4884717, 23783145, 11038569, 18800704, 255233 }, + }, + { + { -5269658, -1773886, 13957886, 7990715, 23132995, 728773, 13393847, 9066957, 19258688, -14753793 }, + { -2936654, -10827535, -10432089, 14516793, -3640786, 4372541, -31934921, 2209390, -1524053, 2055794 }, + { 580882, 16705327, 5468415, -2683018, -30926419, -14696000, -7203346, -8994389, -30021019, 7394435 }, + }, + { + { 23838809, 1822728, -15738443, 15242727, 8318092, -3733104, -21672180, -3492205, -4821741, 14799921 }, + { 13345610, 9759151, 3371034, -16137791, 16353039, 8577942, 31129804, 13496856, -9056018, 7402518 }, + { 2286874, -4435931, -20042458, -2008336, -13696227, 5038122, 11006906, -15760352, 8205061, 1607563 }, + }, + { + { 14414086, -8002132, 3331830, -3208217, 22249151, -5594188, 18364661, -2906958, 30019587, -9029278 }, + { -27688051, 1585953, -10775053, 931069, -29120221, -11002319, -14410829, 12029093, 9944378, 8024 }, + { 4368715, -3709630, 29874200, -15022983, -20230386, -11410704, -16114594, -999085, -8142388, 5640030 }, + }, + { + { 10299610, 13746483, 11661824, 16234854, 7630238, 5998374, 9809887, -16694564, 15219798, -14327783 }, + { 27425505, -5719081, 3055006, 10660664, 23458024, 595578, -15398605, -1173195, -18342183, 9742717 }, + { 6744077, 2427284, 26042789, 2720740, -847906, 1118974, 32324614, 7406442, 12420155, 1994844 }, + }, + { + { 14012521, -5024720, -18384453, -9578469, -26485342, -3936439, -13033478, -10909803, 24319929, -6446333 }, + { 16412690, -4507367, 10772641, 15929391, -17068788, -4658621, 10555945, -10484049, -30102368, -4739048 }, + { 22397382, -7767684, -9293161, -12792868, 17166287, -9755136, -27333065, 6199366, 21880021, -12250760 }, + }, + { + { -4283307, 5368523, -31117018, 8163389, -30323063, 3209128, 16557151, 8890729, 8840445, 4957760 }, + { -15447727, 709327, -6919446, -10870178, -29777922, 6522332, -21720181, 12130072, -14796503, 5005757 }, + { -2114751, -14308128, 23019042, 15765735, -25269683, 6002752, 10183197, -13239326, -16395286, -2176112 }, + }, + }, + { + { + { -19025756, 1632005, 13466291, -7995100, -23640451, 16573537, -32013908, -3057104, 22208662, 2000468 }, + { 3065073, -1412761, -25598674, -361432, -17683065, -5703415, -8164212, 11248527, -3691214, -7414184 }, + { 10379208, -6045554, 8877319, 1473647, -29291284, -12507580, 16690915, 2553332, -3132688, 16400289 }, + }, + { + { 15716668, 1254266, -18472690, 7446274, -8448918, 6344164, -22097271, -7285580, 26894937, 9132066 }, + { 24158887, 12938817, 11085297, -8177598, -28063478, -4457083, -30576463, 64452, -6817084, -2692882 }, + { 13488534, 7794716, 22236231, 5989356, 25426474, -12578208, 2350710, -3418511, -4688006, 2364226 }, + }, + { + { 16335052, 9132434, 25640582, 6678888, 1725628, 8517937, -11807024, -11697457, 15445875, -7798101 }, + { 29004207, -7867081, 28661402, -640412, -12794003, -7943086, 31863255, -4135540, -278050, -15759279 }, + { -6122061, -14866665, -28614905, 14569919, -10857999, -3591829, 10343412, -6976290, -29828287, -10815811 }, + }, + { + { 27081650, 3463984, 14099042, -4517604, 1616303, -6205604, 29542636, 15372179, 17293797, 960709 }, + { 20263915, 11434237, -5765435, 11236810, 13505955, -10857102, -16111345, 6493122, -19384511, 7639714 }, + { -2830798, -14839232, 25403038, -8215196, -8317012, -16173699, 18006287, -16043750, 29994677, -15808121 }, + }, + { + { 9769828, 5202651, -24157398, -13631392, -28051003, -11561624, -24613141, -13860782, -31184575, 709464 }, + { 12286395, 13076066, -21775189, -1176622, -25003198, 4057652, -32018128, -8890874, 16102007, 13205847 }, + { 13733362, 5599946, 10557076, 3195751, -5557991, 8536970, -25540170, 8525972, 10151379, 10394400 }, + }, + { + { 4024660, -16137551, 22436262, 12276534, -9099015, -2686099, 19698229, 11743039, -33302334, 8934414 }, + { -15879800, -4525240, -8580747, -2934061, 14634845, -698278, -9449077, 3137094, -11536886, 11721158 }, + { 17555939, -5013938, 8268606, 2331751, -22738815, 9761013, 9319229, 8835153, -9205489, -1280045 }, + }, + { + { -461409, -7830014, 20614118, 16688288, -7514766, -4807119, 22300304, 505429, 6108462, -6183415 }, + { -5070281, 12367917, -30663534, 3234473, 32617080, -8422642, 29880583, -13483331, -26898490, -7867459 }, + { -31975283, 5726539, 26934134, 10237677, -3173717, -605053, 24199304, 3795095, 7592688, -14992079 }, + }, + { + { 21594432, -14964228, 17466408, -4077222, 32537084, 2739898, 6407723, 12018833, -28256052, 4298412 }, + { -20650503, -11961496, -27236275, 570498, 3767144, -1717540, 13891942, -1569194, 13717174, 10805743 }, + { -14676630, -15644296, 15287174, 11927123, 24177847, -8175568, -796431, 14860609, -26938930, -5863836 }, + }, + }, + { + { + { 12962541, 5311799, -10060768, 11658280, 18855286, -7954201, 13286263, -12808704, -4381056, 9882022 }, + { 18512079, 11319350, -20123124, 15090309, 18818594, 5271736, -22727904, 3666879, -23967430, -3299429 }, + { -6789020, -3146043, 16192429, 13241070, 15898607, -14206114, -10084880, -6661110, -2403099, 5276065 }, + }, + { + { 30169808, -5317648, 26306206, -11750859, 27814964, 7069267, 7152851, 3684982, 1449224, 13082861 }, + { 10342826, 3098505, 2119311, 193222, 25702612, 12233820, 23697382, 15056736, -21016438, -8202000 }, + { -33150110, 3261608, 22745853, 7948688, 19370557, -15177665, -26171976, 6482814, -10300080, -11060101 }, + }, + { + { 32869458, -5408545, 25609743, 15678670, -10687769, -15471071, 26112421, 2521008, -22664288, 6904815 }, + { 29506923, 4457497, 3377935, -9796444, -30510046, 12935080, 1561737, 3841096, -29003639, -6657642 }, + { 10340844, -6630377, -18656632, -2278430, 12621151, -13339055, 30878497, -11824370, -25584551, 5181966 }, + }, + { + { 25940115, -12658025, 17324188, -10307374, -8671468, 15029094, 24396252, -16450922, -2322852, -12388574 }, + { -21765684, 9916823, -1300409, 4079498, -1028346, 11909559, 1782390, 12641087, 20603771, -6561742 }, + { -18882287, -11673380, 24849422, 11501709, 13161720, -4768874, 1925523, 11914390, 4662781, 7820689 }, + }, + { + { 12241050, -425982, 8132691, 9393934, 32846760, -1599620, 29749456, 12172924, 16136752, 15264020 }, + { -10349955, -14680563, -8211979, 2330220, -17662549, -14545780, 10658213, 6671822, 19012087, 3772772 }, + { 3753511, -3421066, 10617074, 2028709, 14841030, -6721664, 28718732, -15762884, 20527771, 12988982 }, + }, + { + { -14822485, -5797269, -3707987, 12689773, -898983, -10914866, -24183046, -10564943, 3299665, -12424953 }, + { -16777703, -15253301, -9642417, 4978983, 3308785, 8755439, 6943197, 6461331, -25583147, 8991218 }, + { -17226263, 1816362, -1673288, -6086439, 31783888, -8175991, -32948145, 7417950, -30242287, 1507265 }, + }, + { + { 29692663, 6829891, -10498800, 4334896, 20945975, -11906496, -28887608, 8209391, 14606362, -10647073 }, + { -3481570, 8707081, 32188102, 5672294, 22096700, 1711240, -33020695, 9761487, 4170404, -2085325 }, + { -11587470, 14855945, -4127778, -1531857, -26649089, 15084046, 22186522, 16002000, -14276837, -8400798 }, + }, + { + { -4811456, 13761029, -31703877, -2483919, -3312471, 7869047, -7113572, -9620092, 13240845, 10965870 }, + { -7742563, -8256762, -14768334, -13656260, -23232383, 12387166, 4498947, 14147411, 29514390, 4302863 }, + { -13413405, -12407859, 20757302, -13801832, 14785143, 8976368, -5061276, -2144373, 17846988, -13971927 }, + }, + }, + { + { + { -2244452, -754728, -4597030, -1066309, -6247172, 1455299, -21647728, -9214789, -5222701, 12650267 }, + { -9906797, -16070310, 21134160, 12198166, -27064575, 708126, 387813, 13770293, -19134326, 10958663 }, + { 22470984, 12369526, 23446014, -5441109, -21520802, -9698723, -11772496, -11574455, -25083830, 4271862 }, + }, + { + { -25169565, -10053642, -19909332, 15361595, -5984358, 2159192, 75375, -4278529, -32526221, 8469673 }, + { 15854970, 4148314, -8893890, 7259002, 11666551, 13824734, -30531198, 2697372, 24154791, -9460943 }, + { 15446137, -15806644, 29759747, 14019369, 30811221, -9610191, -31582008, 12840104, 24913809, 9815020 }, + }, + { + { -4709286, -5614269, -31841498, -12288893, -14443537, 10799414, -9103676, 13438769, 18735128, 9466238 }, + { 11933045, 9281483, 5081055, -5183824, -2628162, -4905629, -7727821, -10896103, -22728655, 16199064 }, + { 14576810, 379472, -26786533, -8317236, -29426508, -10812974, -102766, 1876699, 30801119, 2164795 }, + }, + { + { 15995086, 3199873, 13672555, 13712240, -19378835, -4647646, -13081610, -15496269, -13492807, 1268052 }, + { -10290614, -3659039, -3286592, 10948818, 23037027, 3794475, -3470338, -12600221, -17055369, 3565904 }, + { 29210088, -9419337, -5919792, -4952785, 10834811, -13327726, -16512102, -10820713, -27162222, -14030531 }, + }, + { + { -13161890, 15508588, 16663704, -8156150, -28349942, 9019123, -29183421, -3769423, 2244111, -14001979 }, + { -5152875, -3800936, -9306475, -6071583, 16243069, 14684434, -25673088, -16180800, 13491506, 4641841 }, + { 10813417, 643330, -19188515, -728916, 30292062, -16600078, 27548447, -7721242, 14476989, -12767431 }, + }, + { + { 10292079, 9984945, 6481436, 8279905, -7251514, 7032743, 27282937, -1644259, -27912810, 12651324 }, + { -31185513, -813383, 22271204, 11835308, 10201545, 15351028, 17099662, 3988035, 21721536, -3148940 }, + { 10202177, -6545839, -31373232, -9574638, -32150642, -8119683, -12906320, 3852694, 13216206, 14842320 }, + }, + { + { -15815640, -10601066, -6538952, -7258995, -6984659, -6581778, -31500847, 13765824, -27434397, 9900184 }, + { 14465505, -13833331, -32133984, -14738873, -27443187, 12990492, 33046193, 15796406, -7051866, -8040114 }, + { 30924417, -8279620, 6359016, -12816335, 16508377, 9071735, -25488601, 15413635, 9524356, -7018878 }, + }, + { + { 12274201, -13175547, 32627641, -1785326, 6736625, 13267305, 5237659, -5109483, 15663516, 4035784 }, + { -2951309, 8903985, 17349946, 601635, -16432815, -4612556, -13732739, -15889334, -22258478, 4659091 }, + { -16916263, -4952973, -30393711, -15158821, 20774812, 15897498, 5736189, 15026997, -2178256, -13455585 }, + }, + }, + { + { + { -8858980, -2219056, 28571666, -10155518, -474467, -10105698, -3801496, 278095, 23440562, -290208 }, + { 10226241, -5928702, 15139956, 120818, -14867693, 5218603, 32937275, 11551483, -16571960, -7442864 }, + { 17932739, -12437276, -24039557, 10749060, 11316803, 7535897, 22503767, 5561594, -3646624, 3898661 }, + }, + { + { 7749907, -969567, -16339731, -16464, -25018111, 15122143, -1573531, 7152530, 21831162, 1245233 }, + { 26958459, -14658026, 4314586, 8346991, -5677764, 11960072, -32589295, -620035, -30402091, -16716212 }, + { -12165896, 9166947, 33491384, 13673479, 29787085, 13096535, 6280834, 14587357, -22338025, 13987525 }, + }, + { + { -24349909, 7778775, 21116000, 15572597, -4833266, -5357778, -4300898, -5124639, -7469781, -2858068 }, + { 9681908, -6737123, -31951644, 13591838, -6883821, 386950, 31622781, 6439245, -14581012, 4091397 }, + { -8426427, 1470727, -28109679, -1596990, 3978627, -5123623, -19622683, 12092163, 29077877, -14741988 }, + }, + { + { 5269168, -6859726, -13230211, -8020715, 25932563, 1763552, -5606110, -5505881, -20017847, 2357889 }, + { 32264008, -15407652, -5387735, -1160093, -2091322, -3946900, 23104804, -12869908, 5727338, 189038 }, + { 14609123, -8954470, -6000566, -16622781, -14577387, -7743898, -26745169, 10942115, -25888931, -14884697 }, + }, + { + { 20513500, 5557931, -15604613, 7829531, 26413943, -2019404, -21378968, 7471781, 13913677, -5137875 }, + { -25574376, 11967826, 29233242, 12948236, -6754465, 4713227, -8940970, 14059180, 12878652, 8511905 }, + { -25656801, 3393631, -2955415, -7075526, -2250709, 9366908, -30223418, 6812974, 5568676, -3127656 }, + }, + { + { 11630004, 12144454, 2116339, 13606037, 27378885, 15676917, -17408753, -13504373, -14395196, 8070818 }, + { 27117696, -10007378, -31282771, -5570088, 1127282, 12772488, -29845906, 10483306, -11552749, -1028714 }, + { 10637467, -5688064, 5674781, 1072708, -26343588, -6982302, -1683975, 9177853, -27493162, 15431203 }, + }, + { + { 20525145, 10892566, -12742472, 12779443, -29493034, 16150075, -28240519, 14943142, -15056790, -7935931 }, + { -30024462, 5626926, -551567, -9981087, 753598, 11981191, 25244767, -3239766, -3356550, 9594024 }, + { -23752644, 2636870, -5163910, -10103818, 585134, 7877383, 11345683, -6492290, 13352335, -10977084 }, + }, + { + { -1931799, -5407458, 3304649, -12884869, 17015806, -4877091, -29783850, -7752482, -13215537, -319204 }, + { 20239939, 6607058, 6203985, 3483793, -18386976, -779229, -20723742, 15077870, -22750759, 14523817 }, + { 27406042, -6041657, 27423596, -4497394, 4996214, 10002360, -28842031, -4545494, -30172742, -4805667 }, + }, + }, + { + { + { 11374242, 12660715, 17861383, -12540833, 10935568, 1099227, -13886076, -9091740, -27727044, 11358504 }, + { -12730809, 10311867, 1510375, 10778093, -2119455, -9145702, 32676003, 11149336, -26123651, 4985768 }, + { -19096303, 341147, -6197485, -239033, 15756973, -8796662, -983043, 13794114, -19414307, -15621255 }, + }, + { + { 6490081, 11940286, 25495923, -7726360, 8668373, -8751316, 3367603, 6970005, -1691065, -9004790 }, + { 1656497, 13457317, 15370807, 6364910, 13605745, 8362338, -19174622, -5475723, -16796596, -5031438 }, + { -22273315, -13524424, -64685, -4334223, -18605636, -10921968, -20571065, -7007978, -99853, -10237333 }, + }, + { + { 17747465, 10039260, 19368299, -4050591, -20630635, -16041286, 31992683, -15857976, -29260363, -5511971 }, + { 31932027, -4986141, -19612382, 16366580, 22023614, 88450, 11371999, -3744247, 4882242, -10626905 }, + { 29796507, 37186, 19818052, 10115756, -11829032, 3352736, 18551198, 3272828, -5190932, -4162409 }, + }, + { + { 12501286, 4044383, -8612957, -13392385, -32430052, 5136599, -19230378, -3529697, 330070, -3659409 }, + { 6384877, 2899513, 17807477, 7663917, -2358888, 12363165, 25366522, -8573892, -271295, 12071499 }, + { -8365515, -4042521, 25133448, -4517355, -6211027, 2265927, -32769618, 1936675, -5159697, 3829363 }, + }, + { + { 28425966, -5835433, -577090, -4697198, -14217555, 6870930, 7921550, -6567787, 26333140, 14267664 }, + { -11067219, 11871231, 27385719, -10559544, -4585914, -11189312, 10004786, -8709488, -21761224, 8930324 }, + { -21197785, -16396035, 25654216, -1725397, 12282012, 11008919, 1541940, 4757911, -26491501, -16408940 }, + }, + { + { 13537262, -7759490, -20604840, 10961927, -5922820, -13218065, -13156584, 6217254, -15943699, 13814990 }, + { -17422573, 15157790, 18705543, 29619, 24409717, -260476, 27361681, 9257833, -1956526, -1776914 }, + { -25045300, -10191966, 15366585, 15166509, -13105086, 8423556, -29171540, 12361135, -18685978, 4578290 }, + }, + { + { 24579768, 3711570, 1342322, -11180126, -27005135, 14124956, -22544529, 14074919, 21964432, 8235257 }, + { -6528613, -2411497, 9442966, -5925588, 12025640, -1487420, -2981514, -1669206, 13006806, 2355433 }, + { -16304899, -13605259, -6632427, -5142349, 16974359, -10911083, 27202044, 1719366, 1141648, -12796236 }, + }, + { + { -12863944, -13219986, -8318266, -11018091, -6810145, -4843894, 13475066, -3133972, 32674895, 13715045 }, + { 11423335, -5468059, 32344216, 8962751, 24989809, 9241752, -13265253, 16086212, -28740881, -15642093 }, + { -1409668, 12530728, -6368726, 10847387, 19531186, -14132160, -11709148, 7791794, -27245943, 4383347 }, + }, + }, + { + { + { -28970898, 5271447, -1266009, -9736989, -12455236, 16732599, -4862407, -4906449, 27193557, 6245191 }, + { -15193956, 5362278, -1783893, 2695834, 4960227, 12840725, 23061898, 3260492, 22510453, 8577507 }, + { -12632451, 11257346, -32692994, 13548177, -721004, 10879011, 31168030, 13952092, -29571492, -3635906 }, + }, + { + { 3877321, -9572739, 32416692, 5405324, -11004407, -13656635, 3759769, 11935320, 5611860, 8164018 }, + { -16275802, 14667797, 15906460, 12155291, -22111149, -9039718, 32003002, -8832289, 5773085, -8422109 }, + { -23788118, -8254300, 1950875, 8937633, 18686727, 16459170, -905725, 12376320, 31632953, 190926 }, + }, + { + { -24593607, -16138885, -8423991, 13378746, 14162407, 6901328, -8288749, 4508564, -25341555, -3627528 }, + { 8884438, -5884009, 6023974, 10104341, -6881569, -4941533, 18722941, -14786005, -1672488, 827625 }, + { -32720583, -16289296, -32503547, 7101210, 13354605, 2659080, -1800575, -14108036, -24878478, 1541286 }, + }, + { + { 2901347, -1117687, 3880376, -10059388, -17620940, -3612781, -21802117, -3567481, 20456845, -1885033 }, + { 27019610, 12299467, -13658288, -1603234, -12861660, -4861471, -19540150, -5016058, 29439641, 15138866 }, + { 21536104, -6626420, -32447818, -10690208, -22408077, 5175814, -5420040, -16361163, 7779328, 109896 }, + }, + { + { 30279744, 14648750, -8044871, 6425558, 13639621, -743509, 28698390, 12180118, 23177719, -554075 }, + { 26572847, 3405927, -31701700, 12890905, -19265668, 5335866, -6493768, 2378492, 4439158, -13279347 }, + { -22716706, 3489070, -9225266, -332753, 18875722, -1140095, 14819434, -12731527, -17717757, -5461437 }, + }, + { + { -5056483, 16566551, 15953661, 3767752, -10436499, 15627060, -820954, 2177225, 8550082, -15114165 }, + { -18473302, 16596775, -381660, 15663611, 22860960, 15585581, -27844109, -3582739, -23260460, -8428588 }, + { -32480551, 15707275, -8205912, -5652081, 29464558, 2713815, -22725137, 15860482, -21902570, 1494193 }, + }, + { + { -19562091, -14087393, -25583872, -9299552, 13127842, 759709, 21923482, 16529112, 8742704, 12967017 }, + { -28464899, 1553205, 32536856, -10473729, -24691605, -406174, -8914625, -2933896, -29903758, 15553883 }, + { 21877909, 3230008, 9881174, 10539357, -4797115, 2841332, 11543572, 14513274, 19375923, -12647961 }, + }, + { + { 8832269, -14495485, 13253511, 5137575, 5037871, 4078777, 24880818, -6222716, 2862653, 9455043 }, + { 29306751, 5123106, 20245049, -14149889, 9592566, 8447059, -2077124, -2990080, 15511449, 4789663 }, + { -20679756, 7004547, 8824831, -9434977, -4045704, -3750736, -5754762, 108893, 23513200, 16652362 }, + }, + }, + { + { + { -33256173, 4144782, -4476029, -6579123, 10770039, -7155542, -6650416, -12936300, -18319198, 10212860 }, + { 2756081, 8598110, 7383731, -6859892, 22312759, -1105012, 21179801, 2600940, -9988298, -12506466 }, + { -24645692, 13317462, -30449259, -15653928, 21365574, -10869657, 11344424, 864440, -2499677, -16710063 }, + }, + { + { -26432803, 6148329, -17184412, -14474154, 18782929, -275997, -22561534, 211300, 2719757, 4940997 }, + { -1323882, 3911313, -6948744, 14759765, -30027150, 7851207, 21690126, 8518463, 26699843, 5276295 }, + { -13149873, -6429067, 9396249, 365013, 24703301, -10488939, 1321586, 149635, -15452774, 7159369 }, + }, + { + { 9987780, -3404759, 17507962, 9505530, 9731535, -2165514, 22356009, 8312176, 22477218, -8403385 }, + { 18155857, -16504990, 19744716, 9006923, 15154154, -10538976, 24256460, -4864995, -22548173, 9334109 }, + { 2986088, -4911893, 10776628, -3473844, 10620590, -7083203, -21413845, 14253545, -22587149, 536906 }, + }, + { + { 4377756, 8115836, 24567078, 15495314, 11625074, 13064599, 7390551, 10589625, 10838060, -15420424 }, + { -19342404, 867880, 9277171, -3218459, -14431572, -1986443, 19295826, -15796950, 6378260, 699185 }, + { 7895026, 4057113, -7081772, -13077756, -17886831, -323126, -716039, 15693155, -5045064, -13373962 }, + }, + { + { -7737563, -5869402, -14566319, -7406919, 11385654, 13201616, 31730678, -10962840, -3918636, -9669325 }, + { 10188286, -15770834, -7336361, 13427543, 22223443, 14896287, 30743455, 7116568, -21786507, 5427593 }, + { 696102, 13206899, 27047647, -10632082, 15285305, -9853179, 10798490, -4578720, 19236243, 12477404 }, + }, + { + { -11229439, 11243796, -17054270, -8040865, -788228, -8167967, -3897669, 11180504, -23169516, 7733644 }, + { 17800790, -14036179, -27000429, -11766671, 23887827, 3149671, 23466177, -10538171, 10322027, 15313801 }, + { 26246234, 11968874, 32263343, -5468728, 6830755, -13323031, -15794704, -101982, -24449242, 10890804 }, + }, + { + { -31365647, 10271363, -12660625, -6267268, 16690207, -13062544, -14982212, 16484931, 25180797, -5334884 }, + { -586574, 10376444, -32586414, -11286356, 19801893, 10997610, 2276632, 9482883, 316878, 13820577 }, + { -9882808, -4510367, -2115506, 16457136, -11100081, 11674996, 30756178, -7515054, 30696930, -3712849 }, + }, + { + { 32988917, -9603412, 12499366, 7910787, -10617257, -11931514, -7342816, -9985397, -32349517, 7392473 }, + { -8855661, 15927861, 9866406, -3649411, -2396914, -16655781, -30409476, -9134995, 25112947, -2926644 }, + { -2504044, -436966, 25621774, -5678772, 15085042, -5479877, -24884878, -13526194, 5537438, -13914319 }, + }, + }, + { + { + { -11225584, 2320285, -9584280, 10149187, -33444663, 5808648, -14876251, -1729667, 31234590, 6090599 }, + { -9633316, 116426, 26083934, 2897444, -6364437, -2688086, 609721, 15878753, -6970405, -9034768 }, + { -27757857, 247744, -15194774, -9002551, 23288161, -10011936, -23869595, 6503646, 20650474, 1804084 }, + }, + { + { -27589786, 15456424, 8972517, 8469608, 15640622, 4439847, 3121995, -10329713, 27842616, -202328 }, + { -15306973, 2839644, 22530074, 10026331, 4602058, 5048462, 28248656, 5031932, -11375082, 12714369 }, + { 20807691, -7270825, 29286141, 11421711, -27876523, -13868230, -21227475, 1035546, -19733229, 12796920 }, + }, + { + { 12076899, -14301286, -8785001, -11848922, -25012791, 16400684, -17591495, -12899438, 3480665, -15182815 }, + { -32361549, 5457597, 28548107, 7833186, 7303070, -11953545, -24363064, -15921875, -33374054, 2771025 }, + { -21389266, 421932, 26597266, 6860826, 22486084, -6737172, -17137485, -4210226, -24552282, 15673397 }, + }, + { + { -20184622, 2338216, 19788685, -9620956, -4001265, -8740893, -20271184, 4733254, 3727144, -12934448 }, + { 6120119, 814863, -11794402, -622716, 6812205, -15747771, 2019594, 7975683, 31123697, -10958981 }, + { 30069250, -11435332, 30434654, 2958439, 18399564, -976289, 12296869, 9204260, -16432438, 9648165 }, + }, + { + { 32705432, -1550977, 30705658, 7451065, -11805606, 9631813, 3305266, 5248604, -26008332, -11377501 }, + { 17219865, 2375039, -31570947, -5575615, -19459679, 9219903, 294711, 15298639, 2662509, -16297073 }, + { -1172927, -7558695, -4366770, -4287744, -21346413, -8434326, 32087529, -1222777, 32247248, -14389861 }, + }, + { + { 14312628, 1221556, 17395390, -8700143, -4945741, -8684635, -28197744, -9637817, -16027623, -13378845 }, + { -1428825, -9678990, -9235681, 6549687, -7383069, -468664, 23046502, 9803137, 17597934, 2346211 }, + { 18510800, 15337574, 26171504, 981392, -22241552, 7827556, -23491134, -11323352, 3059833, -11782870 }, + }, + { + { 10141598, 6082907, 17829293, -1947643, 9830092, 13613136, -25556636, -5544586, -33502212, 3592096 }, + { 33114168, -15889352, -26525686, -13343397, 33076705, 8716171, 1151462, 1521897, -982665, -6837803 }, + { -32939165, -4255815, 23947181, -324178, -33072974, -12305637, -16637686, 3891704, 26353178, 693168 }, + }, + { + { 30374239, 1595580, -16884039, 13186931, 4600344, 406904, 9585294, -400668, 31375464, 14369965 }, + { -14370654, -7772529, 1510301, 6434173, -18784789, -6262728, 32732230, -13108839, 17901441, 16011505 }, + { 18171223, -11934626, -12500402, 15197122, -11038147, -15230035, -19172240, -16046376, 8764035, 12309598 }, + }, + }, + { + { + { 5975908, -5243188, -19459362, -9681747, -11541277, 14015782, -23665757, 1228319, 17544096, -10593782 }, + { 5811932, -1715293, 3442887, -2269310, -18367348, -8359541, -18044043, -15410127, -5565381, 12348900 }, + { -31399660, 11407555, 25755363, 6891399, -3256938, 14872274, -24849353, 8141295, -10632534, -585479 }, + }, + { + { -12675304, 694026, -5076145, 13300344, 14015258, -14451394, -9698672, -11329050, 30944593, 1130208 }, + { 8247766, -6710942, -26562381, -7709309, -14401939, -14648910, 4652152, 2488540, 23550156, -271232 }, + { 17294316, -3788438, 7026748, 15626851, 22990044, 113481, 2267737, -5908146, -408818, -137719 }, + }, + { + { 16091085, -16253926, 18599252, 7340678, 2137637, -1221657, -3364161, 14550936, 3260525, -7166271 }, + { -4910104, -13332887, 18550887, 10864893, -16459325, -7291596, -23028869, -13204905, -12748722, 2701326 }, + { -8574695, 16099415, 4629974, -16340524, -20786213, -6005432, -10018363, 9276971, 11329923, 1862132 }, + }, + { + { 14763076, -15903608, -30918270, 3689867, 3511892, 10313526, -21951088, 12219231, -9037963, -940300 }, + { 8894987, -3446094, 6150753, 3013931, 301220, 15693451, -31981216, -2909717, -15438168, 11595570 }, + { 15214962, 3537601, -26238722, -14058872, 4418657, -15230761, 13947276, 10730794, -13489462, -4363670 }, + }, + { + { -2538306, 7682793, 32759013, 263109, -29984731, -7955452, -22332124, -10188635, 977108, 699994 }, + { -12466472, 4195084, -9211532, 550904, -15565337, 12917920, 19118110, -439841, -30534533, -14337913 }, + { 31788461, -14507657, 4799989, 7372237, 8808585, -14747943, 9408237, -10051775, 12493932, -5409317 }, + }, + { + { -25680606, 5260744, -19235809, -6284470, -3695942, 16566087, 27218280, 2607121, 29375955, 6024730 }, + { 842132, -2794693, -4763381, -8722815, 26332018, -12405641, 11831880, 6985184, -9940361, 2854096 }, + { -4847262, -7969331, 2516242, -5847713, 9695691, -7221186, 16512645, 960770, 12121869, 16648078 }, + }, + { + { -15218652, 14667096, -13336229, 2013717, 30598287, -464137, -31504922, -7882064, 20237806, 2838411 }, + { -19288047, 4453152, 15298546, -16178388, 22115043, -15972604, 12544294, -13470457, 1068881, -12499905 }, + { -9558883, -16518835, 33238498, 13506958, 30505848, -1114596, -8486907, -2630053, 12521378, 4845654 }, + }, + { + { -28198521, 10744108, -2958380, 10199664, 7759311, -13088600, 3409348, -873400, -6482306, -12885870 }, + { -23561822, 6230156, -20382013, 10655314, -24040585, -11621172, 10477734, -1240216, -3113227, 13974498 }, + { 12966261, 15550616, -32038948, -1615346, 21025980, -629444, 5642325, 7188737, 18895762, 12629579 }, + }, + }, + { + { + { 14741879, -14946887, 22177208, -11721237, 1279741, 8058600, 11758140, 789443, 32195181, 3895677 }, + { 10758205, 15755439, -4509950, 9243698, -4879422, 6879879, -2204575, -3566119, -8982069, 4429647 }, + { -2453894, 15725973, -20436342, -10410672, -5803908, -11040220, -7135870, -11642895, 18047436, -15281743 }, + }, + { + { -25173001, -11307165, 29759956, 11776784, -22262383, -15820455, 10993114, -12850837, -17620701, -9408468 }, + { 21987233, 700364, -24505048, 14972008, -7774265, -5718395, 32155026, 2581431, -29958985, 8773375 }, + { -25568350, 454463, -13211935, 16126715, 25240068, 8594567, 20656846, 12017935, -7874389, -13920155 }, + }, + { + { 6028182, 6263078, -31011806, -11301710, -818919, 2461772, -31841174, -5468042, -1721788, -2776725 }, + { -12278994, 16624277, 987579, -5922598, 32908203, 1248608, 7719845, -4166698, 28408820, 6816612 }, + { -10358094, -8237829, 19549651, -12169222, 22082623, 16147817, 20613181, 13982702, -10339570, 5067943 }, + }, + { + { -30505967, -3821767, 12074681, 13582412, -19877972, 2443951, -19719286, 12746132, 5331210, -10105944 }, + { 30528811, 3601899, -1957090, 4619785, -27361822, -15436388, 24180793, -12570394, 27679908, -1648928 }, + { 9402404, -13957065, 32834043, 10838634, -26580150, -13237195, 26653274, -8685565, 22611444, -12715406 }, + }, + { + { 22190590, 1118029, 22736441, 15130463, -30460692, -5991321, 19189625, -4648942, 4854859, 6622139 }, + { -8310738, -2953450, -8262579, -3388049, -10401731, -271929, 13424426, -3567227, 26404409, 13001963 }, + { -31241838, -15415700, -2994250, 8939346, 11562230, -12840670, -26064365, -11621720, -15405155, 11020693 }, + }, + { + { 1866042, -7949489, -7898649, -10301010, 12483315, 13477547, 3175636, -12424163, 28761762, 1406734 }, + { -448555, -1777666, 13018551, 3194501, -9580420, -11161737, 24760585, -4347088, 25577411, -13378680 }, + { -24290378, 4759345, -690653, -1852816, 2066747, 10693769, -29595790, 9884936, -9368926, 4745410 }, + }, + { + { -9141284, 6049714, -19531061, -4341411, -31260798, 9944276, -15462008, -11311852, 10931924, -11931931 }, + { -16561513, 14112680, -8012645, 4817318, -8040464, -11414606, -22853429, 10856641, -20470770, 13434654 }, + { 22759489, -10073434, -16766264, -1871422, 13637442, -10168091, 1765144, -12654326, 28445307, -5364710 }, + }, + { + { 29875063, 12493613, 2795536, -3786330, 1710620, 15181182, -10195717, -8788675, 9074234, 1167180 }, + { -26205683, 11014233, -9842651, -2635485, -26908120, 7532294, -18716888, -9535498, 3843903, 9367684 }, + { -10969595, -6403711, 9591134, 9582310, 11349256, 108879, 16235123, 8601684, -139197, 4242895 }, + }, + }, + { + { + { 22092954, -13191123, -2042793, -11968512, 32186753, -11517388, -6574341, 2470660, -27417366, 16625501 }, + { -11057722, 3042016, 13770083, -9257922, 584236, -544855, -7770857, 2602725, -27351616, 14247413 }, + { 6314175, -10264892, -32772502, 15957557, -10157730, 168750, -8618807, 14290061, 27108877, -1180880 }, + }, + { + { -8586597, -7170966, 13241782, 10960156, -32991015, -13794596, 33547976, -11058889, -27148451, 981874 }, + { 22833440, 9293594, -32649448, -13618667, -9136966, 14756819, -22928859, -13970780, -10479804, -16197962 }, + { -7768587, 3326786, -28111797, 10783824, 19178761, 14905060, 22680049, 13906969, -15933690, 3797899 }, + }, + { + { 21721356, -4212746, -12206123, 9310182, -3882239, -13653110, 23740224, -2709232, 20491983, -8042152 }, + { 9209270, -15135055, -13256557, -6167798, -731016, 15289673, 25947805, 15286587, 30997318, -6703063 }, + { 7392032, 16618386, 23946583, -8039892, -13265164, -1533858, -14197445, -2321576, 17649998, -250080 }, + }, + { + { -9301088, -14193827, 30609526, -3049543, -25175069, -1283752, -15241566, -9525724, -2233253, 7662146 }, + { -17558673, 1763594, -33114336, 15908610, -30040870, -12174295, 7335080, -8472199, -3174674, 3440183 }, + { -19889700, -5977008, -24111293, -9688870, 10799743, -16571957, 40450, -4431835, 4862400, 1133 }, + }, + { + { -32856209, -7873957, -5422389, 14860950, -16319031, 7956142, 7258061, 311861, -30594991, -7379421 }, + { -3773428, -1565936, 28985340, 7499440, 24445838, 9325937, 29727763, 16527196, 18278453, 15405622 }, + { -4381906, 8508652, -19898366, -3674424, -5984453, 15149970, -13313598, 843523, -21875062, 13626197 }, + }, + { + { 2281448, -13487055, -10915418, -2609910, 1879358, 16164207, -10783882, 3953792, 13340839, 15928663 }, + { 31727126, -7179855, -18437503, -8283652, 2875793, -16390330, -25269894, -7014826, -23452306, 5964753 }, + { 4100420, -5959452, -17179337, 6017714, -18705837, 12227141, -26684835, 11344144, 2538215, -7570755 }, + }, + { + { -9433605, 6123113, 11159803, -2156608, 30016280, 14966241, -20474983, 1485421, -629256, -15958862 }, + { -26804558, 4260919, 11851389, 9658551, -32017107, 16367492, -20205425, -13191288, 11659922, -11115118 }, + { 26180396, 10015009, -30844224, -8581293, 5418197, 9480663, 2231568, -10170080, 33100372, -1306171 }, + }, + { + { 15121113, -5201871, -10389905, 15427821, -27509937, -15992507, 21670947, 4486675, -5931810, -14466380 }, + { 16166486, -9483733, -11104130, 6023908, -31926798, -1364923, 2340060, -16254968, -10735770, -10039824 }, + { 28042865, -3557089, -12126526, 12259706, -3717498, -6945899, 6766453, -8689599, 18036436, 5803270 }, + }, + }, + { + { + { -817581, 6763912, 11803561, 1585585, 10958447, -2671165, 23855391, 4598332, -6159431, -14117438 }, + { -31031306, -14256194, 17332029, -2383520, 31312682, -5967183, 696309, 50292, -20095739, 11763584 }, + { -594563, -2514283, -32234153, 12643980, 12650761, 14811489, 665117, -12613632, -19773211, -10713562 }, + }, + { + { 30464590, -11262872, -4127476, -12734478, 19835327, -7105613, -24396175, 2075773, -17020157, 992471 }, + { 18357185, -6994433, 7766382, 16342475, -29324918, 411174, 14578841, 8080033, -11574335, -10601610 }, + { 19598397, 10334610, 12555054, 2555664, 18821899, -10339780, 21873263, 16014234, 26224780, 16452269 }, + }, + { + { -30223925, 5145196, 5944548, 16385966, 3976735, 2009897, -11377804, -7618186, -20533829, 3698650 }, + { 14187449, 3448569, -10636236, -10810935, -22663880, -3433596, 7268410, -10890444, 27394301, 12015369 }, + { 19695761, 16087646, 28032085, 12999827, 6817792, 11427614, 20244189, -1312777, -13259127, -3402461 }, + }, + { + { 30860103, 12735208, -1888245, -4699734, -16974906, 2256940, -8166013, 12298312, -8550524, -10393462 }, + { -5719826, -11245325, -1910649, 15569035, 26642876, -7587760, -5789354, -15118654, -4976164, 12651793 }, + { -2848395, 9953421, 11531313, -5282879, 26895123, -12697089, -13118820, -16517902, 9768698, -2533218 }, + }, + { + { -24719459, 1894651, -287698, -4704085, 15348719, -8156530, 32767513, 12765450, 4940095, 10678226 }, + { 18860224, 15980149, -18987240, -1562570, -26233012, -11071856, -7843882, 13944024, -24372348, 16582019 }, + { -15504260, 4970268, -29893044, 4175593, -20993212, -2199756, -11704054, 15444560, -11003761, 7989037 }, + }, + { + { 31490452, 5568061, -2412803, 2182383, -32336847, 4531686, -32078269, 6200206, -19686113, -14800171 }, + { -17308668, -15879940, -31522777, -2831, -32887382, 16375549, 8680158, -16371713, 28550068, -6857132 }, + { -28126887, -5688091, 16837845, -1820458, -6850681, 12700016, -30039981, 4364038, 1155602, 5988841 }, + }, + { + { 21890435, -13272907, -12624011, 12154349, -7831873, 15300496, 23148983, -4470481, 24618407, 8283181 }, + { -33136107, -10512751, 9975416, 6841041, -31559793, 16356536, 3070187, -7025928, 1466169, 10740210 }, + { -1509399, -15488185, -13503385, -10655916, 32799044, 909394, -13938903, -5779719, -32164649, -15327040 }, + }, + { + { 3960823, -14267803, -28026090, -15918051, -19404858, 13146868, 15567327, 951507, -3260321, -573935 }, + { 24740841, 5052253, -30094131, 8961361, 25877428, 6165135, -24368180, 14397372, -7380369, -6144105 }, + { -28888365, 3510803, -28103278, -1158478, -11238128, -10631454, -15441463, -14453128, -1625486, -6494814 }, + }, + }, + { + { + { 793299, -9230478, 8836302, -6235707, -27360908, -2369593, 33152843, -4885251, -9906200, -621852 }, + { 5666233, 525582, 20782575, -8038419, -24538499, 14657740, 16099374, 1468826, -6171428, -15186581 }, + { -4859255, -3779343, -2917758, -6748019, 7778750, 11688288, -30404353, -9871238, -1558923, -9863646 }, + }, + { + { 10896332, -7719704, 824275, 472601, -19460308, 3009587, 25248958, 14783338, -30581476, -15757844 }, + { 10566929, 12612572, -31944212, 11118703, -12633376, 12362879, 21752402, 8822496, 24003793, 14264025 }, + { 27713862, -7355973, -11008240, 9227530, 27050101, 2504721, 23886875, -13117525, 13958495, -5732453 }, + }, + { + { -23481610, 4867226, -27247128, 3900521, 29838369, -8212291, -31889399, -10041781, 7340521, -15410068 }, + { 4646514, -8011124, -22766023, -11532654, 23184553, 8566613, 31366726, -1381061, -15066784, -10375192 }, + { -17270517, 12723032, -16993061, 14878794, 21619651, -6197576, 27584817, 3093888, -8843694, 3849921 }, + }, + { + { -9064912, 2103172, 25561640, -15125738, -5239824, 9582958, 32477045, -9017955, 5002294, -15550259 }, + { -12057553, -11177906, 21115585, -13365155, 8808712, -12030708, 16489530, 13378448, -25845716, 12741426 }, + { -5946367, 10645103, -30911586, 15390284, -3286982, -7118677, 24306472, 15852464, 28834118, -7646072 }, + }, + { + { -17335748, -9107057, -24531279, 9434953, -8472084, -583362, -13090771, 455841, 20461858, 5491305 }, + { 13669248, -16095482, -12481974, -10203039, -14569770, -11893198, -24995986, 11293807, -28588204, -9421832 }, + { 28497928, 6272777, -33022994, 14470570, 8906179, -1225630, 18504674, -14165166, 29867745, -8795943 }, + }, + { + { -16207023, 13517196, -27799630, -13697798, 24009064, -6373891, -6367600, -13175392, 22853429, -4012011 }, + { 24191378, 16712145, -13931797, 15217831, 14542237, 1646131, 18603514, -11037887, 12876623, -2112447 }, + { 17902668, 4518229, -411702, -2829247, 26878217, 5258055, -12860753, 608397, 16031844, 3723494 }, + }, + { + { -28632773, 12763728, -20446446, 7577504, 33001348, -13017745, 17558842, -7872890, 23896954, -4314245 }, + { -20005381, -12011952, 31520464, 605201, 2543521, 5991821, -2945064, 7229064, -9919646, -8826859 }, + { 28816045, 298879, -28165016, -15920938, 19000928, -1665890, -12680833, -2949325, -18051778, -2082915 }, + }, + { + { 16000882, -344896, 3493092, -11447198, -29504595, -13159789, 12577740, 16041268, -19715240, 7847707 }, + { 10151868, 10572098, 27312476, 7922682, 14825339, 4723128, -32855931, -6519018, -10020567, 3852848 }, + { -11430470, 15697596, -21121557, -4420647, 5386314, 15063598, 16514493, -15932110, 29330899, -15076224 }, + }, + }, + { + { + { -25499735, -4378794, -15222908, -6901211, 16615731, 2051784, 3303702, 15490, -27548796, 12314391 }, + { 15683520, -6003043, 18109120, -9980648, 15337968, -5997823, -16717435, 15921866, 16103996, -3731215 }, + { -23169824, -10781249, 13588192, -1628807, -3798557, -1074929, -19273607, 5402699, -29815713, -9841101 }, + }, + { + { 23190676, 2384583, -32714340, 3462154, -29903655, -1529132, -11266856, 8911517, -25205859, 2739713 }, + { 21374101, -3554250, -33524649, 9874411, 15377179, 11831242, -33529904, 6134907, 4931255, 11987849 }, + { -7732, -2978858, -16223486, 7277597, 105524, -322051, -31480539, 13861388, -30076310, 10117930 }, + }, + { + { -29501170, -10744872, -26163768, 13051539, -25625564, 5089643, -6325503, 6704079, 12890019, 15728940 }, + { -21972360, -11771379, -951059, -4418840, 14704840, 2695116, 903376, -10428139, 12885167, 8311031 }, + { -17516482, 5352194, 10384213, -13811658, 7506451, 13453191, 26423267, 4384730, 1888765, -5435404 }, + }, + { + { -25817338, -3107312, -13494599, -3182506, 30896459, -13921729, -32251644, -12707869, -19464434, -3340243 }, + { -23607977, -2665774, -526091, 4651136, 5765089, 4618330, 6092245, 14845197, 17151279, -9854116 }, + { -24830458, -12733720, -15165978, 10367250, -29530908, -265356, 22825805, -7087279, -16866484, 16176525 }, + }, + { + { -23583256, 6564961, 20063689, 3798228, -4740178, 7359225, 2006182, -10363426, -28746253, -10197509 }, + { -10626600, -4486402, -13320562, -5125317, 3432136, -6393229, 23632037, -1940610, 32808310, 1099883 }, + { 15030977, 5768825, -27451236, -2887299, -6427378, -15361371, -15277896, -6809350, 2051441, -15225865 }, + }, + { + { -3362323, -7239372, 7517890, 9824992, 23555850, 295369, 5148398, -14154188, -22686354, 16633660 }, + { 4577086, -16752288, 13249841, -15304328, 19958763, -14537274, 18559670, -10759549, 8402478, -9864273 }, + { -28406330, -1051581, -26790155, -907698, -17212414, -11030789, 9453451, -14980072, 17983010, 9967138 }, + }, + { + { -25762494, 6524722, 26585488, 9969270, 24709298, 1220360, -1677990, 7806337, 17507396, 3651560 }, + { -10420457, -4118111, 14584639, 15971087, -15768321, 8861010, 26556809, -5574557, -18553322, -11357135 }, + { 2839101, 14284142, 4029895, 3472686, 14402957, 12689363, -26642121, 8459447, -5605463, -7621941 }, + }, + { + { -4839289, -3535444, 9744961, 2871048, 25113978, 3187018, -25110813, -849066, 17258084, -7977739 }, + { 18164541, -10595176, -17154882, -1542417, 19237078, -9745295, 23357533, -15217008, 26908270, 12150756 }, + { -30264870, -7647865, 5112249, -7036672, -1499807, -6974257, 43168, -5537701, -32302074, 16215819 }, + }, + }, + { + { + { -6898905, 9824394, -12304779, -4401089, -31397141, -6276835, 32574489, 12532905, -7503072, -8675347 }, + { -27343522, -16515468, -27151524, -10722951, 946346, 16291093, 254968, 7168080, 21676107, -1943028 }, + { 21260961, -8424752, -16831886, -11920822, -23677961, 3968121, -3651949, -6215466, -3556191, -7913075 }, + }, + { + { 16544754, 13250366, -16804428, 15546242, -4583003, 12757258, -2462308, -8680336, -18907032, -9662799 }, + { -2415239, -15577728, 18312303, 4964443, -15272530, -12653564, 26820651, 16690659, 25459437, -4564609 }, + { -25144690, 11425020, 28423002, -11020557, -6144921, -15826224, 9142795, -2391602, -6432418, -1644817 }, + }, + { + { -23104652, 6253476, 16964147, -3768872, -25113972, -12296437, -27457225, -16344658, 6335692, 7249989 }, + { -30333227, 13979675, 7503222, -12368314, -11956721, -4621693, -30272269, 2682242, 25993170, -12478523 }, + { 4364628, 5930691, 32304656, -10044554, -8054781, 15091131, 22857016, -10598955, 31820368, 15075278 }, + }, + { + { 31879134, -8918693, 17258761, 90626, -8041836, -4917709, 24162788, -9650886, -17970238, 12833045 }, + { 19073683, 14851414, -24403169, -11860168, 7625278, 11091125, -19619190, 2074449, -9413939, 14905377 }, + { 24483667, -11935567, -2518866, -11547418, -1553130, 15355506, -25282080, 9253129, 27628530, -7555480 }, + }, + { + { 17597607, 8340603, 19355617, 552187, 26198470, -3176583, 4593324, -9157582, -14110875, 15297016 }, + { 510886, 14337390, -31785257, 16638632, 6328095, 2713355, -20217417, -11864220, 8683221, 2921426 }, + { 18606791, 11874196, 27155355, -5281482, -24031742, 6265446, -25178240, -1278924, 4674690, 13890525 }, + }, + { + { 13609624, 13069022, -27372361, -13055908, 24360586, 9592974, 14977157, 9835105, 4389687, 288396 }, + { 9922506, -519394, 13613107, 5883594, -18758345, -434263, -12304062, 8317628, 23388070, 16052080 }, + { 12720016, 11937594, -31970060, -5028689, 26900120, 8561328, -20155687, -11632979, -14754271, -10812892 }, + }, + { + { 15961858, 14150409, 26716931, -665832, -22794328, 13603569, 11829573, 7467844, -28822128, 929275 }, + { 11038231, -11582396, -27310482, -7316562, -10498527, -16307831, -23479533, -9371869, -21393143, 2465074 }, + { 20017163, -4323226, 27915242, 1529148, 12396362, 15675764, 13817261, -9658066, 2463391, -4622140 }, + }, + { + { -16358878, -12663911, -12065183, 4996454, -1256422, 1073572, 9583558, 12851107, 4003896, 12673717 }, + { -1731589, -15155870, -3262930, 16143082, 19294135, 13385325, 14741514, -9103726, 7903886, 2348101 }, + { 24536016, -16515207, 12715592, -3862155, 1511293, 10047386, -3842346, -7129159, -28377538, 10048127 }, + }, + }, + { + { + { -12622226, -6204820, 30718825, 2591312, -10617028, 12192840, 18873298, -7297090, -32297756, 15221632 }, + { -26478122, -11103864, 11546244, -1852483, 9180880, 7656409, -21343950, 2095755, 29769758, 6593415 }, + { -31994208, -2907461, 4176912, 3264766, 12538965, -868111, 26312345, -6118678, 30958054, 8292160 }, + }, + { + { 31429822, -13959116, 29173532, 15632448, 12174511, -2760094, 32808831, 3977186, 26143136, -3148876 }, + { 22648901, 1402143, -22799984, 13746059, 7936347, 365344, -8668633, -1674433, -3758243, -2304625 }, + { -15491917, 8012313, -2514730, -12702462, -23965846, -10254029, -1612713, -1535569, -16664475, 8194478 }, + }, + { + { 27338066, -7507420, -7414224, 10140405, -19026427, -6589889, 27277191, 8855376, 28572286, 3005164 }, + { 26287124, 4821776, 25476601, -4145903, -3764513, -15788984, -18008582, 1182479, -26094821, -13079595 }, + { -7171154, 3178080, 23970071, 6201893, -17195577, -4489192, -21876275, -13982627, 32208683, -1198248 }, + }, + { + { -16657702, 2817643, -10286362, 14811298, 6024667, 13349505, -27315504, -10497842, -27672585, -11539858 }, + { 15941029, -9405932, -21367050, 8062055, 31876073, -238629, -15278393, -1444429, 15397331, -4130193 }, + { 8934485, -13485467, -23286397, -13423241, -32446090, 14047986, 31170398, -1441021, -27505566, 15087184 }, + }, + { + { -18357243, -2156491, 24524913, -16677868, 15520427, -6360776, -15502406, 11461896, 16788528, -5868942 }, + { -1947386, 16013773, 21750665, 3714552, -17401782, -16055433, -3770287, -10323320, 31322514, -11615635 }, + { 21426655, -5650218, -13648287, -5347537, -28812189, -4920970, -18275391, -14621414, 13040862, -12112948 }, + }, + { + { 11293895, 12478086, -27136401, 15083750, -29307421, 14748872, 14555558, -13417103, 1613711, 4896935 }, + { -25894883, 15323294, -8489791, -8057900, 25967126, -13425460, 2825960, -4897045, -23971776, -11267415 }, + { -15924766, -5229880, -17443532, 6410664, 3622847, 10243618, 20615400, 12405433, -23753030, -8436416 }, + }, + { + { -7091295, 12556208, -20191352, 9025187, -17072479, 4333801, 4378436, 2432030, 23097949, -566018 }, + { 4565804, -16025654, 20084412, -7842817, 1724999, 189254, 24767264, 10103221, -18512313, 2424778 }, + { 366633, -11976806, 8173090, -6890119, 30788634, 5745705, -7168678, 1344109, -3642553, 12412659 }, + }, + { + { -24001791, 7690286, 14929416, -168257, -32210835, -13412986, 24162697, -15326504, -3141501, 11179385 }, + { 18289522, -14724954, 8056945, 16430056, -21729724, 7842514, -6001441, -1486897, -18684645, -11443503 }, + { 476239, 6601091, -6152790, -9723375, 17503545, -4863900, 27672959, 13403813, 11052904, 5219329 }, + }, + }, + { + { + { 20678546, -8375738, -32671898, 8849123, -5009758, 14574752, 31186971, -3973730, 9014762, -8579056 }, + { -13644050, -10350239, -15962508, 5075808, -1514661, -11534600, -33102500, 9160280, 8473550, -3256838 }, + { 24900749, 14435722, 17209120, -15292541, -22592275, 9878983, -7689309, -16335821, -24568481, 11788948 }, + }, + { + { -3118155, -11395194, -13802089, 14797441, 9652448, -6845904, -20037437, 10410733, -24568470, -1458691 }, + { -15659161, 16736706, -22467150, 10215878, -9097177, 7563911, 11871841, -12505194, -18513325, 8464118 }, + { -23400612, 8348507, -14585951, -861714, -3950205, -6373419, 14325289, 8628612, 33313881, -8370517 }, + }, + { + { -20186973, -4967935, 22367356, 5271547, -1097117, -4788838, -24805667, -10236854, -8940735, -5818269 }, + { -6948785, -1795212, -32625683, -16021179, 32635414, -7374245, 15989197, -12838188, 28358192, -4253904 }, + { -23561781, -2799059, -32351682, -1661963, -9147719, 10429267, -16637684, 4072016, -5351664, 5596589 }, + }, + { + { -28236598, -3390048, 12312896, 6213178, 3117142, 16078565, 29266239, 2557221, 1768301, 15373193 }, + { -7243358, -3246960, -4593467, -7553353, -127927, -912245, -1090902, -4504991, -24660491, 3442910 }, + { -30210571, 5124043, 14181784, 8197961, 18964734, -11939093, 22597931, 7176455, -18585478, 13365930 }, + }, + { + { -7877390, -1499958, 8324673, 4690079, 6261860, 890446, 24538107, -8570186, -9689599, -3031667 }, + { 25008904, -10771599, -4305031, -9638010, 16265036, 15721635, 683793, -11823784, 15723479, -15163481 }, + { -9660625, 12374379, -27006999, -7026148, -7724114, -12314514, 11879682, 5400171, 519526, -1235876 }, + }, + { + { 22258397, -16332233, -7869817, 14613016, -22520255, -2950923, -20353881, 7315967, 16648397, 7605640 }, + { -8081308, -8464597, -8223311, 9719710, 19259459, -15348212, 23994942, -5281555, -9468848, 4763278 }, + { -21699244, 9220969, -15730624, 1084137, -25476107, -2852390, 31088447, -7764523, -11356529, 728112 }, + }, + { + { 26047220, -11751471, -6900323, -16521798, 24092068, 9158119, -4273545, -12555558, -29365436, -5498272 }, + { 17510331, -322857, 5854289, 8403524, 17133918, -3112612, -28111007, 12327945, 10750447, 10014012 }, + { -10312768, 3936952, 9156313, -8897683, 16498692, -994647, -27481051, -666732, 3424691, 7540221 }, + }, + { + { 30322361, -6964110, 11361005, -4143317, 7433304, 4989748, -7071422, -16317219, -9244265, 15258046 }, + { 13054562, -2779497, 19155474, 469045, -12482797, 4566042, 5631406, 2711395, 1062915, -5136345 }, + { -19240248, -11254599, -29509029, -7499965, -5835763, 13005411, -6066489, 12194497, 32960380, 1459310 }, + }, + }, + { + { + { 19852034, 7027924, 23669353, 10020366, 8586503, -6657907, 394197, -6101885, 18638003, -11174937 }, + { 31395534, 15098109, 26581030, 8030562, -16527914, -5007134, 9012486, -7584354, -6643087, -5442636 }, + { -9192165, -2347377, -1997099, 4529534, 25766844, 607986, -13222, 9677543, -32294889, -6456008 }, + }, + { + { -2444496, -149937, 29348902, 8186665, 1873760, 12489863, -30934579, -7839692, -7852844, -8138429 }, + { -15236356, -15433509, 7766470, 746860, 26346930, -10221762, -27333451, 10754588, -9431476, 5203576 }, + { 31834314, 14135496, -770007, 5159118, 20917671, -16768096, -7467973, -7337524, 31809243, 7347066 }, + }, + { + { -9606723, -11874240, 20414459, 13033986, 13716524, -11691881, 19797970, -12211255, 15192876, -2087490 }, + { -12663563, -2181719, 1168162, -3804809, 26747877, -14138091, 10609330, 12694420, 33473243, -13382104 }, + { 33184999, 11180355, 15832085, -11385430, -1633671, 225884, 15089336, -11023903, -6135662, 14480053 }, + }, + { + { 31308717, -5619998, 31030840, -1897099, 15674547, -6582883, 5496208, 13685227, 27595050, 8737275 }, + { -20318852, -15150239, 10933843, -16178022, 8335352, -7546022, -31008351, -12610604, 26498114, 66511 }, + { 22644454, -8761729, -16671776, 4884562, -3105614, -13559366, 30540766, -4286747, -13327787, -7515095 }, + }, + { + { -28017847, 9834845, 18617207, -2681312, -3401956, -13307506, 8205540, 13585437, -17127465, 15115439 }, + { 23711543, -672915, 31206561, -8362711, 6164647, -9709987, -33535882, -1426096, 8236921, 16492939 }, + { -23910559, -13515526, -26299483, -4503841, 25005590, -7687270, 19574902, 10071562, 6708380, -6222424 }, + }, + { + { 2101391, -4930054, 19702731, 2367575, -15427167, 1047675, 5301017, 9328700, 29955601, -11678310 }, + { 3096359, 9271816, -21620864, -15521844, -14847996, -7592937, -25892142, -12635595, -9917575, 6216608 }, + { -32615849, 338663, -25195611, 2510422, -29213566, -13820213, 24822830, -6146567, -26767480, 7525079 }, + }, + { + { -23066649, -13985623, 16133487, -7896178, -3389565, 778788, -910336, -2782495, -19386633, 11994101 }, + { 21691500, -13624626, -641331, -14367021, 3285881, -3483596, -25064666, 9718258, -7477437, 13381418 }, + { 18445390, -4202236, 14979846, 11622458, -1727110, -3582980, 23111648, -6375247, 28535282, 15779576 }, + }, + { + { 30098053, 3089662, -9234387, 16662135, -21306940, 11308411, -14068454, 12021730, 9955285, -16303356 }, + { 9734894, -14576830, -7473633, -9138735, 2060392, 11313496, -18426029, 9924399, 20194861, 13380996 }, + { -26378102, -7965207, -22167821, 15789297, -18055342, -6168792, -1984914, 15707771, 26342023, 10146099 }, + }, + }, + { + { + { -26016874, -219943, 21339191, -41388, 19745256, -2878700, -29637280, 2227040, 21612326, -545728 }, + { -13077387, 1184228, 23562814, -5970442, -20351244, -6348714, 25764461, 12243797, -20856566, 11649658 }, + { -10031494, 11262626, 27384172, 2271902, 26947504, -15997771, 39944, 6114064, 33514190, 2333242 }, + }, + { + { -21433588, -12421821, 8119782, 7219913, -21830522, -9016134, -6679750, -12670638, 24350578, -13450001 }, + { -4116307, -11271533, -23886186, 4843615, -30088339, 690623, -31536088, -10406836, 8317860, 12352766 }, + { 18200138, -14475911, -33087759, -2696619, -23702521, -9102511, -23552096, -2287550, 20712163, 6719373 }, + }, + { + { 26656208, 6075253, -7858556, 1886072, -28344043, 4262326, 11117530, -3763210, 26224235, -3297458 }, + { -17168938, -14854097, -3395676, -16369877, -19954045, 14050420, 21728352, 9493610, 18620611, -16428628 }, + { -13323321, 13325349, 11432106, 5964811, 18609221, 6062965, -5269471, -9725556, -30701573, -16479657 }, + }, + { + { -23860538, -11233159, 26961357, 1640861, -32413112, -16737940, 12248509, -5240639, 13735342, 1934062 }, + { 25089769, 6742589, 17081145, -13406266, 21909293, -16067981, -15136294, -3765346, -21277997, 5473616 }, + { 31883677, -7961101, 1083432, -11572403, 22828471, 13290673, -7125085, 12469656, 29111212, -5451014 }, + }, + { + { 24244947, -15050407, -26262976, 2791540, -14997599, 16666678, 24367466, 6388839, -10295587, 452383 }, + { -25640782, -3417841, 5217916, 16224624, 19987036, -4082269, -24236251, -5915248, 15766062, 8407814 }, + { -20406999, 13990231, 15495425, 16395525, 5377168, 15166495, -8917023, -4388953, -8067909, 2276718 }, + }, + { + { 30157918, 12924066, -17712050, 9245753, 19895028, 3368142, -23827587, 5096219, 22740376, -7303417 }, + { 2041139, -14256350, 7783687, 13876377, -25946985, -13352459, 24051124, 13742383, -15637599, 13295222 }, + { 33338237, -8505733, 12532113, 7977527, 9106186, -1715251, -17720195, -4612972, -4451357, -14669444 }, + }, + { + { -20045281, 5454097, -14346548, 6447146, 28862071, 1883651, -2469266, -4141880, 7770569, 9620597 }, + { 23208068, 7979712, 33071466, 8149229, 1758231, -10834995, 30945528, -1694323, -33502340, -14767970 }, + { 1439958, -16270480, -1079989, -793782, 4625402, 10647766, -5043801, 1220118, 30494170, -11440799 }, + }, + { + { -5037580, -13028295, -2970559, -3061767, 15640974, -6701666, -26739026, 926050, -1684339, -13333647 }, + { 13908495, -3549272, 30919928, -6273825, -21521863, 7989039, 9021034, 9078865, 3353509, 4033511 }, + { -29663431, -15113610, 32259991, -344482, 24295849, -12912123, 23161163, 8839127, 27485041, 7356032 }, + }, + }, + { + { + { 9661027, 705443, 11980065, -5370154, -1628543, 14661173, -6346142, 2625015, 28431036, -16771834 }, + { -23839233, -8311415, -25945511, 7480958, -17681669, -8354183, -22545972, 14150565, 15970762, 4099461 }, + { 29262576, 16756590, 26350592, -8793563, 8529671, -11208050, 13617293, -9937143, 11465739, 8317062 }, + }, + { + { -25493081, -6962928, 32500200, -9419051, -23038724, -2302222, 14898637, 3848455, 20969334, -5157516 }, + { -20384450, -14347713, -18336405, 13884722, -33039454, 2842114, -21610826, -3649888, 11177095, 14989547 }, + { -24496721, -11716016, 16959896, 2278463, 12066309, 10137771, 13515641, 2581286, -28487508, 9930240 }, + }, + { + { -17751622, -2097826, 16544300, -13009300, -15914807, -14949081, 18345767, -13403753, 16291481, -5314038 }, + { -33229194, 2553288, 32678213, 9875984, 8534129, 6889387, -9676774, 6957617, 4368891, 9788741 }, + { 16660756, 7281060, -10830758, 12911820, 20108584, -8101676, -21722536, -8613148, 16250552, -11111103 }, + }, + { + { -19765507, 2390526, -16551031, 14161980, 1905286, 6414907, 4689584, 10604807, -30190403, 4782747 }, + { -1354539, 14736941, -7367442, -13292886, 7710542, -14155590, -9981571, 4383045, 22546403, 437323 }, + { 31665577, -12180464, -16186830, 1491339, -18368625, 3294682, 27343084, 2786261, -30633590, -14097016 }, + }, + { + { -14467279, -683715, -33374107, 7448552, 19294360, 14334329, -19690631, 2355319, -19284671, -6114373 }, + { 15121312, -15796162, 6377020, -6031361, -10798111, -12957845, 18952177, 15496498, -29380133, 11754228 }, + { -2637277, -13483075, 8488727, -14303896, 12728761, -1622493, 7141596, 11724556, 22761615, -10134141 }, + }, + { + { 16918416, 11729663, -18083579, 3022987, -31015732, -13339659, -28741185, -12227393, 32851222, 11717399 }, + { 11166634, 7338049, -6722523, 4531520, -29468672, -7302055, 31474879, 3483633, -1193175, -4030831 }, + { -185635, 9921305, 31456609, -13536438, -12013818, 13348923, 33142652, 6546660, -19985279, -3948376 }, + }, + { + { -32460596, 11266712, -11197107, -7899103, 31703694, 3855903, -8537131, -12833048, -30772034, -15486313 }, + { -18006477, 12709068, 3991746, -6479188, -21491523, -10550425, -31135347, -16049879, 10928917, 3011958 }, + { -6957757, -15594337, 31696059, 334240, 29576716, 14796075, -30831056, -12805180, 18008031, 10258577 }, + }, + { + { -22448644, 15655569, 7018479, -4410003, -30314266, -1201591, -1853465, 1367120, 25127874, 6671743 }, + { 29701166, -14373934, -10878120, 9279288, -17568, 13127210, 21382910, 11042292, 25838796, 4642684 }, + { -20430234, 14955537, -24126347, 8124619, -5369288, -5990470, 30468147, -13900640, 18423289, 4177476 }, + }, + }, }; diff --git a/src/ed25519/sc.c b/src/ed25519/sc.c index 3364de4..ee54d99 100644 --- a/src/ed25519/sc.c +++ b/src/ed25519/sc.c @@ -2,24 +2,24 @@ #include "sc.h" static uint64_t load_3(const unsigned char *in) { - uint64_t result; + uint64_t result; - result = in[0]; - result |= shlu64(in[1], 8); - result |= shlu64(in[2], 16); + result = in[0]; + result |= shlu64(in[1], 8); + result |= shlu64(in[2], 16); - return result; + return result; } static uint64_t load_4(const unsigned char *in) { - uint64_t result; + uint64_t result; - result = in[0]; - result |= shlu64(in[1], 8); - result |= shlu64(in[2], 16); - result |= shlu64(in[3], 24); - - return result; + result = in[0]; + result |= shlu64(in[1], 8); + result |= shlu64(in[2], 16); + result |= shlu64(in[3], 24); + + return result; } /* @@ -33,305 +33,305 @@ Output: */ void sc_reduce(unsigned char *s) { - int64_t s0 = 2097151 & load_3(s); - int64_t s1 = 2097151 & (load_4(s + 2) >> 5); - int64_t s2 = 2097151 & (load_3(s + 5) >> 2); - int64_t s3 = 2097151 & (load_4(s + 7) >> 7); - int64_t s4 = 2097151 & (load_4(s + 10) >> 4); - int64_t s5 = 2097151 & (load_3(s + 13) >> 1); - int64_t s6 = 2097151 & (load_4(s + 15) >> 6); - int64_t s7 = 2097151 & (load_3(s + 18) >> 3); - int64_t s8 = 2097151 & load_3(s + 21); - int64_t s9 = 2097151 & (load_4(s + 23) >> 5); - int64_t s10 = 2097151 & (load_3(s + 26) >> 2); - int64_t s11 = 2097151 & (load_4(s + 28) >> 7); - int64_t s12 = 2097151 & (load_4(s + 31) >> 4); - int64_t s13 = 2097151 & (load_3(s + 34) >> 1); - int64_t s14 = 2097151 & (load_4(s + 36) >> 6); - int64_t s15 = 2097151 & (load_3(s + 39) >> 3); - int64_t s16 = 2097151 & load_3(s + 42); - int64_t s17 = 2097151 & (load_4(s + 44) >> 5); - int64_t s18 = 2097151 & (load_3(s + 47) >> 2); - int64_t s19 = 2097151 & (load_4(s + 49) >> 7); - int64_t s20 = 2097151 & (load_4(s + 52) >> 4); - int64_t s21 = 2097151 & (load_3(s + 55) >> 1); - int64_t s22 = 2097151 & (load_4(s + 57) >> 6); - int64_t s23 = (load_4(s + 60) >> 3); - int64_t carry0; - int64_t carry1; - int64_t carry2; - int64_t carry3; - int64_t carry4; - int64_t carry5; - int64_t carry6; - int64_t carry7; - int64_t carry8; - int64_t carry9; - int64_t carry10; - int64_t carry11; - int64_t carry12; - int64_t carry13; - int64_t carry14; - int64_t carry15; - int64_t carry16; + int64_t s0 = 2097151 & load_3(s); + int64_t s1 = 2097151 & (load_4(s + 2) >> 5); + int64_t s2 = 2097151 & (load_3(s + 5) >> 2); + int64_t s3 = 2097151 & (load_4(s + 7) >> 7); + int64_t s4 = 2097151 & (load_4(s + 10) >> 4); + int64_t s5 = 2097151 & (load_3(s + 13) >> 1); + int64_t s6 = 2097151 & (load_4(s + 15) >> 6); + int64_t s7 = 2097151 & (load_3(s + 18) >> 3); + int64_t s8 = 2097151 & load_3(s + 21); + int64_t s9 = 2097151 & (load_4(s + 23) >> 5); + int64_t s10 = 2097151 & (load_3(s + 26) >> 2); + int64_t s11 = 2097151 & (load_4(s + 28) >> 7); + int64_t s12 = 2097151 & (load_4(s + 31) >> 4); + int64_t s13 = 2097151 & (load_3(s + 34) >> 1); + int64_t s14 = 2097151 & (load_4(s + 36) >> 6); + int64_t s15 = 2097151 & (load_3(s + 39) >> 3); + int64_t s16 = 2097151 & load_3(s + 42); + int64_t s17 = 2097151 & (load_4(s + 44) >> 5); + int64_t s18 = 2097151 & (load_3(s + 47) >> 2); + int64_t s19 = 2097151 & (load_4(s + 49) >> 7); + int64_t s20 = 2097151 & (load_4(s + 52) >> 4); + int64_t s21 = 2097151 & (load_3(s + 55) >> 1); + int64_t s22 = 2097151 & (load_4(s + 57) >> 6); + int64_t s23 = (load_4(s + 60) >> 3); + int64_t carry0; + int64_t carry1; + int64_t carry2; + int64_t carry3; + int64_t carry4; + int64_t carry5; + int64_t carry6; + int64_t carry7; + int64_t carry8; + int64_t carry9; + int64_t carry10; + int64_t carry11; + int64_t carry12; + int64_t carry13; + int64_t carry14; + int64_t carry15; + int64_t carry16; - s11 += s23 * 666643; - s12 += s23 * 470296; - s13 += s23 * 654183; - s14 -= s23 * 997805; - s15 += s23 * 136657; - s16 -= s23 * 683901; - s10 += s22 * 666643; - s11 += s22 * 470296; - s12 += s22 * 654183; - s13 -= s22 * 997805; - s14 += s22 * 136657; - s15 -= s22 * 683901; - s9 += s21 * 666643; - s10 += s21 * 470296; - s11 += s21 * 654183; - s12 -= s21 * 997805; - s13 += s21 * 136657; - s14 -= s21 * 683901; - s8 += s20 * 666643; - s9 += s20 * 470296; - s10 += s20 * 654183; - s11 -= s20 * 997805; - s12 += s20 * 136657; - s13 -= s20 * 683901; - s7 += s19 * 666643; - s8 += s19 * 470296; - s9 += s19 * 654183; - s10 -= s19 * 997805; - s11 += s19 * 136657; - s12 -= s19 * 683901; - s6 += s18 * 666643; - s7 += s18 * 470296; - s8 += s18 * 654183; - s9 -= s18 * 997805; - s10 += s18 * 136657; - s11 -= s18 * 683901; - carry6 = (s6 + (1 << 20)) >> 21; - s7 += carry6; - s6 -= shl64(carry6, 21); - carry8 = (s8 + (1 << 20)) >> 21; - s9 += carry8; - s8 -= shl64(carry8, 21); - carry10 = (s10 + (1 << 20)) >> 21; - s11 += carry10; - s10 -= shl64(carry10, 21); - carry12 = (s12 + (1 << 20)) >> 21; - s13 += carry12; - s12 -= shl64(carry12, 21); - carry14 = (s14 + (1 << 20)) >> 21; - s15 += carry14; - s14 -= shl64(carry14, 21); - carry16 = (s16 + (1 << 20)) >> 21; - s17 += carry16; - s16 -= shl64(carry16, 21); - carry7 = (s7 + (1 << 20)) >> 21; - s8 += carry7; - s7 -= shl64(carry7, 21); - carry9 = (s9 + (1 << 20)) >> 21; - s10 += carry9; - s9 -= shl64(carry9, 21); - carry11 = (s11 + (1 << 20)) >> 21; - s12 += carry11; - s11 -= shl64(carry11, 21); - carry13 = (s13 + (1 << 20)) >> 21; - s14 += carry13; - s13 -= shl64(carry13, 21); - carry15 = (s15 + (1 << 20)) >> 21; - s16 += carry15; - s15 -= shl64(carry15, 21); - s5 += s17 * 666643; - s6 += s17 * 470296; - s7 += s17 * 654183; - s8 -= s17 * 997805; - s9 += s17 * 136657; - s10 -= s17 * 683901; - s4 += s16 * 666643; - s5 += s16 * 470296; - s6 += s16 * 654183; - s7 -= s16 * 997805; - s8 += s16 * 136657; - s9 -= s16 * 683901; - s3 += s15 * 666643; - s4 += s15 * 470296; - s5 += s15 * 654183; - s6 -= s15 * 997805; - s7 += s15 * 136657; - s8 -= s15 * 683901; - s2 += s14 * 666643; - s3 += s14 * 470296; - s4 += s14 * 654183; - s5 -= s14 * 997805; - s6 += s14 * 136657; - s7 -= s14 * 683901; - s1 += s13 * 666643; - s2 += s13 * 470296; - s3 += s13 * 654183; - s4 -= s13 * 997805; - s5 += s13 * 136657; - s6 -= s13 * 683901; - s0 += s12 * 666643; - s1 += s12 * 470296; - s2 += s12 * 654183; - s3 -= s12 * 997805; - s4 += s12 * 136657; - s5 -= s12 * 683901; - s12 = 0; - carry0 = (s0 + (1 << 20)) >> 21; - s1 += carry0; - s0 -= shl64(carry0, 21); - carry2 = (s2 + (1 << 20)) >> 21; - s3 += carry2; - s2 -= shl64(carry2, 21); - carry4 = (s4 + (1 << 20)) >> 21; - s5 += carry4; - s4 -= shl64(carry4, 21); - carry6 = (s6 + (1 << 20)) >> 21; - s7 += carry6; - s6 -= shl64(carry6, 21); - carry8 = (s8 + (1 << 20)) >> 21; - s9 += carry8; - s8 -= shl64(carry8, 21); - carry10 = (s10 + (1 << 20)) >> 21; - s11 += carry10; - s10 -= shl64(carry10, 21); - carry1 = (s1 + (1 << 20)) >> 21; - s2 += carry1; - s1 -= shl64(carry1, 21); - carry3 = (s3 + (1 << 20)) >> 21; - s4 += carry3; - s3 -= shl64(carry3, 21); - carry5 = (s5 + (1 << 20)) >> 21; - s6 += carry5; - s5 -= shl64(carry5, 21); - carry7 = (s7 + (1 << 20)) >> 21; - s8 += carry7; - s7 -= shl64(carry7, 21); - carry9 = (s9 + (1 << 20)) >> 21; - s10 += carry9; - s9 -= shl64(carry9, 21); - carry11 = (s11 + (1 << 20)) >> 21; - s12 += carry11; - s11 -= shl64(carry11, 21); - s0 += s12 * 666643; - s1 += s12 * 470296; - s2 += s12 * 654183; - s3 -= s12 * 997805; - s4 += s12 * 136657; - s5 -= s12 * 683901; - s12 = 0; - carry0 = s0 >> 21; - s1 += carry0; - s0 -= shl64(carry0, 21); - carry1 = s1 >> 21; - s2 += carry1; - s1 -= shl64(carry1, 21); - carry2 = s2 >> 21; - s3 += carry2; - s2 -= shl64(carry2, 21); - carry3 = s3 >> 21; - s4 += carry3; - s3 -= shl64(carry3, 21); - carry4 = s4 >> 21; - s5 += carry4; - s4 -= shl64(carry4, 21); - carry5 = s5 >> 21; - s6 += carry5; - s5 -= shl64(carry5, 21); - carry6 = s6 >> 21; - s7 += carry6; - s6 -= shl64(carry6, 21); - carry7 = s7 >> 21; - s8 += carry7; - s7 -= shl64(carry7, 21); - carry8 = s8 >> 21; - s9 += carry8; - s8 -= shl64(carry8, 21); - carry9 = s9 >> 21; - s10 += carry9; - s9 -= shl64(carry9, 21); - carry10 = s10 >> 21; - s11 += carry10; - s10 -= shl64(carry10, 21); - carry11 = s11 >> 21; - s12 += carry11; - s11 -= shl64(carry11, 21); - s0 += s12 * 666643; - s1 += s12 * 470296; - s2 += s12 * 654183; - s3 -= s12 * 997805; - s4 += s12 * 136657; - s5 -= s12 * 683901; - carry0 = s0 >> 21; - s1 += carry0; - s0 -= shl64(carry0, 21); - carry1 = s1 >> 21; - s2 += carry1; - s1 -= shl64(carry1, 21); - carry2 = s2 >> 21; - s3 += carry2; - s2 -= shl64(carry2, 21); - carry3 = s3 >> 21; - s4 += carry3; - s3 -= shl64(carry3, 21); - carry4 = s4 >> 21; - s5 += carry4; - s4 -= shl64(carry4, 21); - carry5 = s5 >> 21; - s6 += carry5; - s5 -= shl64(carry5, 21); - carry6 = s6 >> 21; - s7 += carry6; - s6 -= shl64(carry6, 21); - carry7 = s7 >> 21; - s8 += carry7; - s7 -= shl64(carry7, 21); - carry8 = s8 >> 21; - s9 += carry8; - s8 -= shl64(carry8, 21); - carry9 = s9 >> 21; - s10 += carry9; - s9 -= shl64(carry9, 21); - carry10 = s10 >> 21; - s11 += carry10; - s10 -= shl64(carry10, 21); + s11 += s23 * 666643; + s12 += s23 * 470296; + s13 += s23 * 654183; + s14 -= s23 * 997805; + s15 += s23 * 136657; + s16 -= s23 * 683901; + s10 += s22 * 666643; + s11 += s22 * 470296; + s12 += s22 * 654183; + s13 -= s22 * 997805; + s14 += s22 * 136657; + s15 -= s22 * 683901; + s9 += s21 * 666643; + s10 += s21 * 470296; + s11 += s21 * 654183; + s12 -= s21 * 997805; + s13 += s21 * 136657; + s14 -= s21 * 683901; + s8 += s20 * 666643; + s9 += s20 * 470296; + s10 += s20 * 654183; + s11 -= s20 * 997805; + s12 += s20 * 136657; + s13 -= s20 * 683901; + s7 += s19 * 666643; + s8 += s19 * 470296; + s9 += s19 * 654183; + s10 -= s19 * 997805; + s11 += s19 * 136657; + s12 -= s19 * 683901; + s6 += s18 * 666643; + s7 += s18 * 470296; + s8 += s18 * 654183; + s9 -= s18 * 997805; + s10 += s18 * 136657; + s11 -= s18 * 683901; + carry6 = (s6 + (1 << 20)) >> 21; + s7 += carry6; + s6 -= shl64(carry6, 21); + carry8 = (s8 + (1 << 20)) >> 21; + s9 += carry8; + s8 -= shl64(carry8, 21); + carry10 = (s10 + (1 << 20)) >> 21; + s11 += carry10; + s10 -= shl64(carry10, 21); + carry12 = (s12 + (1 << 20)) >> 21; + s13 += carry12; + s12 -= shl64(carry12, 21); + carry14 = (s14 + (1 << 20)) >> 21; + s15 += carry14; + s14 -= shl64(carry14, 21); + carry16 = (s16 + (1 << 20)) >> 21; + s17 += carry16; + s16 -= shl64(carry16, 21); + carry7 = (s7 + (1 << 20)) >> 21; + s8 += carry7; + s7 -= shl64(carry7, 21); + carry9 = (s9 + (1 << 20)) >> 21; + s10 += carry9; + s9 -= shl64(carry9, 21); + carry11 = (s11 + (1 << 20)) >> 21; + s12 += carry11; + s11 -= shl64(carry11, 21); + carry13 = (s13 + (1 << 20)) >> 21; + s14 += carry13; + s13 -= shl64(carry13, 21); + carry15 = (s15 + (1 << 20)) >> 21; + s16 += carry15; + s15 -= shl64(carry15, 21); + s5 += s17 * 666643; + s6 += s17 * 470296; + s7 += s17 * 654183; + s8 -= s17 * 997805; + s9 += s17 * 136657; + s10 -= s17 * 683901; + s4 += s16 * 666643; + s5 += s16 * 470296; + s6 += s16 * 654183; + s7 -= s16 * 997805; + s8 += s16 * 136657; + s9 -= s16 * 683901; + s3 += s15 * 666643; + s4 += s15 * 470296; + s5 += s15 * 654183; + s6 -= s15 * 997805; + s7 += s15 * 136657; + s8 -= s15 * 683901; + s2 += s14 * 666643; + s3 += s14 * 470296; + s4 += s14 * 654183; + s5 -= s14 * 997805; + s6 += s14 * 136657; + s7 -= s14 * 683901; + s1 += s13 * 666643; + s2 += s13 * 470296; + s3 += s13 * 654183; + s4 -= s13 * 997805; + s5 += s13 * 136657; + s6 -= s13 * 683901; + s0 += s12 * 666643; + s1 += s12 * 470296; + s2 += s12 * 654183; + s3 -= s12 * 997805; + s4 += s12 * 136657; + s5 -= s12 * 683901; + s12 = 0; + carry0 = (s0 + (1 << 20)) >> 21; + s1 += carry0; + s0 -= shl64(carry0, 21); + carry2 = (s2 + (1 << 20)) >> 21; + s3 += carry2; + s2 -= shl64(carry2, 21); + carry4 = (s4 + (1 << 20)) >> 21; + s5 += carry4; + s4 -= shl64(carry4, 21); + carry6 = (s6 + (1 << 20)) >> 21; + s7 += carry6; + s6 -= shl64(carry6, 21); + carry8 = (s8 + (1 << 20)) >> 21; + s9 += carry8; + s8 -= shl64(carry8, 21); + carry10 = (s10 + (1 << 20)) >> 21; + s11 += carry10; + s10 -= shl64(carry10, 21); + carry1 = (s1 + (1 << 20)) >> 21; + s2 += carry1; + s1 -= shl64(carry1, 21); + carry3 = (s3 + (1 << 20)) >> 21; + s4 += carry3; + s3 -= shl64(carry3, 21); + carry5 = (s5 + (1 << 20)) >> 21; + s6 += carry5; + s5 -= shl64(carry5, 21); + carry7 = (s7 + (1 << 20)) >> 21; + s8 += carry7; + s7 -= shl64(carry7, 21); + carry9 = (s9 + (1 << 20)) >> 21; + s10 += carry9; + s9 -= shl64(carry9, 21); + carry11 = (s11 + (1 << 20)) >> 21; + s12 += carry11; + s11 -= shl64(carry11, 21); + s0 += s12 * 666643; + s1 += s12 * 470296; + s2 += s12 * 654183; + s3 -= s12 * 997805; + s4 += s12 * 136657; + s5 -= s12 * 683901; + s12 = 0; + carry0 = s0 >> 21; + s1 += carry0; + s0 -= shl64(carry0, 21); + carry1 = s1 >> 21; + s2 += carry1; + s1 -= shl64(carry1, 21); + carry2 = s2 >> 21; + s3 += carry2; + s2 -= shl64(carry2, 21); + carry3 = s3 >> 21; + s4 += carry3; + s3 -= shl64(carry3, 21); + carry4 = s4 >> 21; + s5 += carry4; + s4 -= shl64(carry4, 21); + carry5 = s5 >> 21; + s6 += carry5; + s5 -= shl64(carry5, 21); + carry6 = s6 >> 21; + s7 += carry6; + s6 -= shl64(carry6, 21); + carry7 = s7 >> 21; + s8 += carry7; + s7 -= shl64(carry7, 21); + carry8 = s8 >> 21; + s9 += carry8; + s8 -= shl64(carry8, 21); + carry9 = s9 >> 21; + s10 += carry9; + s9 -= shl64(carry9, 21); + carry10 = s10 >> 21; + s11 += carry10; + s10 -= shl64(carry10, 21); + carry11 = s11 >> 21; + s12 += carry11; + s11 -= shl64(carry11, 21); + s0 += s12 * 666643; + s1 += s12 * 470296; + s2 += s12 * 654183; + s3 -= s12 * 997805; + s4 += s12 * 136657; + s5 -= s12 * 683901; + carry0 = s0 >> 21; + s1 += carry0; + s0 -= shl64(carry0, 21); + carry1 = s1 >> 21; + s2 += carry1; + s1 -= shl64(carry1, 21); + carry2 = s2 >> 21; + s3 += carry2; + s2 -= shl64(carry2, 21); + carry3 = s3 >> 21; + s4 += carry3; + s3 -= shl64(carry3, 21); + carry4 = s4 >> 21; + s5 += carry4; + s4 -= shl64(carry4, 21); + carry5 = s5 >> 21; + s6 += carry5; + s5 -= shl64(carry5, 21); + carry6 = s6 >> 21; + s7 += carry6; + s6 -= shl64(carry6, 21); + carry7 = s7 >> 21; + s8 += carry7; + s7 -= shl64(carry7, 21); + carry8 = s8 >> 21; + s9 += carry8; + s8 -= shl64(carry8, 21); + carry9 = s9 >> 21; + s10 += carry9; + s9 -= shl64(carry9, 21); + carry10 = s10 >> 21; + s11 += carry10; + s10 -= shl64(carry10, 21); - s[0] = (unsigned char) (s0 >> 0); - s[1] = (unsigned char) (s0 >> 8); - s[2] = (unsigned char) ((s0 >> 16) | shl64(s1, 5)); - s[3] = (unsigned char) (s1 >> 3); - s[4] = (unsigned char) (s1 >> 11); - s[5] = (unsigned char) ((s1 >> 19) | shl64(s2, 2)); - s[6] = (unsigned char) (s2 >> 6); - s[7] = (unsigned char) ((s2 >> 14) | shl64(s3, 7)); - s[8] = (unsigned char) (s3 >> 1); - s[9] = (unsigned char) (s3 >> 9); - s[10] = (unsigned char) ((s3 >> 17) | shl64(s4, 4)); - s[11] = (unsigned char) (s4 >> 4); - s[12] = (unsigned char) (s4 >> 12); - s[13] = (unsigned char) ((s4 >> 20) | shl64(s5, 1)); - s[14] = (unsigned char) (s5 >> 7); - s[15] = (unsigned char) ((s5 >> 15) | shl64(s6, 6)); - s[16] = (unsigned char) (s6 >> 2); - s[17] = (unsigned char) (s6 >> 10); - s[18] = (unsigned char) ((s6 >> 18) | shl64(s7, 3)); - s[19] = (unsigned char) (s7 >> 5); - s[20] = (unsigned char) (s7 >> 13); - s[21] = (unsigned char) (s8 >> 0); - s[22] = (unsigned char) (s8 >> 8); - s[23] = (unsigned char) ((s8 >> 16) | shl64(s9, 5)); - s[24] = (unsigned char) (s9 >> 3); - s[25] = (unsigned char) (s9 >> 11); - s[26] = (unsigned char) ((s9 >> 19) | shl64(s10, 2)); - s[27] = (unsigned char) (s10 >> 6); - s[28] = (unsigned char) ((s10 >> 14) | shl64(s11, 7)); - s[29] = (unsigned char) (s11 >> 1); - s[30] = (unsigned char) (s11 >> 9); - s[31] = (unsigned char) (s11 >> 17); + s[0] = (unsigned char)(s0 >> 0); + s[1] = (unsigned char)(s0 >> 8); + s[2] = (unsigned char)((s0 >> 16) | shl64(s1, 5)); + s[3] = (unsigned char)(s1 >> 3); + s[4] = (unsigned char)(s1 >> 11); + s[5] = (unsigned char)((s1 >> 19) | shl64(s2, 2)); + s[6] = (unsigned char)(s2 >> 6); + s[7] = (unsigned char)((s2 >> 14) | shl64(s3, 7)); + s[8] = (unsigned char)(s3 >> 1); + s[9] = (unsigned char)(s3 >> 9); + s[10] = (unsigned char)((s3 >> 17) | shl64(s4, 4)); + s[11] = (unsigned char)(s4 >> 4); + s[12] = (unsigned char)(s4 >> 12); + s[13] = (unsigned char)((s4 >> 20) | shl64(s5, 1)); + s[14] = (unsigned char)(s5 >> 7); + s[15] = (unsigned char)((s5 >> 15) | shl64(s6, 6)); + s[16] = (unsigned char)(s6 >> 2); + s[17] = (unsigned char)(s6 >> 10); + s[18] = (unsigned char)((s6 >> 18) | shl64(s7, 3)); + s[19] = (unsigned char)(s7 >> 5); + s[20] = (unsigned char)(s7 >> 13); + s[21] = (unsigned char)(s8 >> 0); + s[22] = (unsigned char)(s8 >> 8); + s[23] = (unsigned char)((s8 >> 16) | shl64(s9, 5)); + s[24] = (unsigned char)(s9 >> 3); + s[25] = (unsigned char)(s9 >> 11); + s[26] = (unsigned char)((s9 >> 19) | shl64(s10, 2)); + s[27] = (unsigned char)(s10 >> 6); + s[28] = (unsigned char)((s10 >> 14) | shl64(s11, 7)); + s[29] = (unsigned char)(s11 >> 1); + s[30] = (unsigned char)(s11 >> 9); + s[31] = (unsigned char)(s11 >> 17); } @@ -348,438 +348,438 @@ Output: */ void sc_muladd(unsigned char *s, const unsigned char *a, const unsigned char *b, const unsigned char *c) { - int64_t a0 = 2097151 & load_3(a); - int64_t a1 = 2097151 & (load_4(a + 2) >> 5); - int64_t a2 = 2097151 & (load_3(a + 5) >> 2); - int64_t a3 = 2097151 & (load_4(a + 7) >> 7); - int64_t a4 = 2097151 & (load_4(a + 10) >> 4); - int64_t a5 = 2097151 & (load_3(a + 13) >> 1); - int64_t a6 = 2097151 & (load_4(a + 15) >> 6); - int64_t a7 = 2097151 & (load_3(a + 18) >> 3); - int64_t a8 = 2097151 & load_3(a + 21); - int64_t a9 = 2097151 & (load_4(a + 23) >> 5); - int64_t a10 = 2097151 & (load_3(a + 26) >> 2); - int64_t a11 = (load_4(a + 28) >> 7); - int64_t b0 = 2097151 & load_3(b); - int64_t b1 = 2097151 & (load_4(b + 2) >> 5); - int64_t b2 = 2097151 & (load_3(b + 5) >> 2); - int64_t b3 = 2097151 & (load_4(b + 7) >> 7); - int64_t b4 = 2097151 & (load_4(b + 10) >> 4); - int64_t b5 = 2097151 & (load_3(b + 13) >> 1); - int64_t b6 = 2097151 & (load_4(b + 15) >> 6); - int64_t b7 = 2097151 & (load_3(b + 18) >> 3); - int64_t b8 = 2097151 & load_3(b + 21); - int64_t b9 = 2097151 & (load_4(b + 23) >> 5); - int64_t b10 = 2097151 & (load_3(b + 26) >> 2); - int64_t b11 = (load_4(b + 28) >> 7); - int64_t c0 = 2097151 & load_3(c); - int64_t c1 = 2097151 & (load_4(c + 2) >> 5); - int64_t c2 = 2097151 & (load_3(c + 5) >> 2); - int64_t c3 = 2097151 & (load_4(c + 7) >> 7); - int64_t c4 = 2097151 & (load_4(c + 10) >> 4); - int64_t c5 = 2097151 & (load_3(c + 13) >> 1); - int64_t c6 = 2097151 & (load_4(c + 15) >> 6); - int64_t c7 = 2097151 & (load_3(c + 18) >> 3); - int64_t c8 = 2097151 & load_3(c + 21); - int64_t c9 = 2097151 & (load_4(c + 23) >> 5); - int64_t c10 = 2097151 & (load_3(c + 26) >> 2); - int64_t c11 = (load_4(c + 28) >> 7); - int64_t s0; - int64_t s1; - int64_t s2; - int64_t s3; - int64_t s4; - int64_t s5; - int64_t s6; - int64_t s7; - int64_t s8; - int64_t s9; - int64_t s10; - int64_t s11; - int64_t s12; - int64_t s13; - int64_t s14; - int64_t s15; - int64_t s16; - int64_t s17; - int64_t s18; - int64_t s19; - int64_t s20; - int64_t s21; - int64_t s22; - int64_t s23; - int64_t carry0; - int64_t carry1; - int64_t carry2; - int64_t carry3; - int64_t carry4; - int64_t carry5; - int64_t carry6; - int64_t carry7; - int64_t carry8; - int64_t carry9; - int64_t carry10; - int64_t carry11; - int64_t carry12; - int64_t carry13; - int64_t carry14; - int64_t carry15; - int64_t carry16; - int64_t carry17; - int64_t carry18; - int64_t carry19; - int64_t carry20; - int64_t carry21; - int64_t carry22; + int64_t a0 = 2097151 & load_3(a); + int64_t a1 = 2097151 & (load_4(a + 2) >> 5); + int64_t a2 = 2097151 & (load_3(a + 5) >> 2); + int64_t a3 = 2097151 & (load_4(a + 7) >> 7); + int64_t a4 = 2097151 & (load_4(a + 10) >> 4); + int64_t a5 = 2097151 & (load_3(a + 13) >> 1); + int64_t a6 = 2097151 & (load_4(a + 15) >> 6); + int64_t a7 = 2097151 & (load_3(a + 18) >> 3); + int64_t a8 = 2097151 & load_3(a + 21); + int64_t a9 = 2097151 & (load_4(a + 23) >> 5); + int64_t a10 = 2097151 & (load_3(a + 26) >> 2); + int64_t a11 = (load_4(a + 28) >> 7); + int64_t b0 = 2097151 & load_3(b); + int64_t b1 = 2097151 & (load_4(b + 2) >> 5); + int64_t b2 = 2097151 & (load_3(b + 5) >> 2); + int64_t b3 = 2097151 & (load_4(b + 7) >> 7); + int64_t b4 = 2097151 & (load_4(b + 10) >> 4); + int64_t b5 = 2097151 & (load_3(b + 13) >> 1); + int64_t b6 = 2097151 & (load_4(b + 15) >> 6); + int64_t b7 = 2097151 & (load_3(b + 18) >> 3); + int64_t b8 = 2097151 & load_3(b + 21); + int64_t b9 = 2097151 & (load_4(b + 23) >> 5); + int64_t b10 = 2097151 & (load_3(b + 26) >> 2); + int64_t b11 = (load_4(b + 28) >> 7); + int64_t c0 = 2097151 & load_3(c); + int64_t c1 = 2097151 & (load_4(c + 2) >> 5); + int64_t c2 = 2097151 & (load_3(c + 5) >> 2); + int64_t c3 = 2097151 & (load_4(c + 7) >> 7); + int64_t c4 = 2097151 & (load_4(c + 10) >> 4); + int64_t c5 = 2097151 & (load_3(c + 13) >> 1); + int64_t c6 = 2097151 & (load_4(c + 15) >> 6); + int64_t c7 = 2097151 & (load_3(c + 18) >> 3); + int64_t c8 = 2097151 & load_3(c + 21); + int64_t c9 = 2097151 & (load_4(c + 23) >> 5); + int64_t c10 = 2097151 & (load_3(c + 26) >> 2); + int64_t c11 = (load_4(c + 28) >> 7); + int64_t s0; + int64_t s1; + int64_t s2; + int64_t s3; + int64_t s4; + int64_t s5; + int64_t s6; + int64_t s7; + int64_t s8; + int64_t s9; + int64_t s10; + int64_t s11; + int64_t s12; + int64_t s13; + int64_t s14; + int64_t s15; + int64_t s16; + int64_t s17; + int64_t s18; + int64_t s19; + int64_t s20; + int64_t s21; + int64_t s22; + int64_t s23; + int64_t carry0; + int64_t carry1; + int64_t carry2; + int64_t carry3; + int64_t carry4; + int64_t carry5; + int64_t carry6; + int64_t carry7; + int64_t carry8; + int64_t carry9; + int64_t carry10; + int64_t carry11; + int64_t carry12; + int64_t carry13; + int64_t carry14; + int64_t carry15; + int64_t carry16; + int64_t carry17; + int64_t carry18; + int64_t carry19; + int64_t carry20; + int64_t carry21; + int64_t carry22; - s0 = c0 + a0 * b0; - s1 = c1 + a0 * b1 + a1 * b0; - s2 = c2 + a0 * b2 + a1 * b1 + a2 * b0; - s3 = c3 + a0 * b3 + a1 * b2 + a2 * b1 + a3 * b0; - s4 = c4 + a0 * b4 + a1 * b3 + a2 * b2 + a3 * b1 + a4 * b0; - s5 = c5 + a0 * b5 + a1 * b4 + a2 * b3 + a3 * b2 + a4 * b1 + a5 * b0; - s6 = c6 + a0 * b6 + a1 * b5 + a2 * b4 + a3 * b3 + a4 * b2 + a5 * b1 + a6 * b0; - s7 = c7 + a0 * b7 + a1 * b6 + a2 * b5 + a3 * b4 + a4 * b3 + a5 * b2 + a6 * b1 + a7 * b0; - s8 = c8 + a0 * b8 + a1 * b7 + a2 * b6 + a3 * b5 + a4 * b4 + a5 * b3 + a6 * b2 + a7 * b1 + a8 * b0; - s9 = c9 + a0 * b9 + a1 * b8 + a2 * b7 + a3 * b6 + a4 * b5 + a5 * b4 + a6 * b3 + a7 * b2 + a8 * b1 + a9 * b0; - s10 = c10 + a0 * b10 + a1 * b9 + a2 * b8 + a3 * b7 + a4 * b6 + a5 * b5 + a6 * b4 + a7 * b3 + a8 * b2 + a9 * b1 + a10 * b0; - s11 = c11 + a0 * b11 + a1 * b10 + a2 * b9 + a3 * b8 + a4 * b7 + a5 * b6 + a6 * b5 + a7 * b4 + a8 * b3 + a9 * b2 + a10 * b1 + a11 * b0; - s12 = a1 * b11 + a2 * b10 + a3 * b9 + a4 * b8 + a5 * b7 + a6 * b6 + a7 * b5 + a8 * b4 + a9 * b3 + a10 * b2 + a11 * b1; - s13 = a2 * b11 + a3 * b10 + a4 * b9 + a5 * b8 + a6 * b7 + a7 * b6 + a8 * b5 + a9 * b4 + a10 * b3 + a11 * b2; - s14 = a3 * b11 + a4 * b10 + a5 * b9 + a6 * b8 + a7 * b7 + a8 * b6 + a9 * b5 + a10 * b4 + a11 * b3; - s15 = a4 * b11 + a5 * b10 + a6 * b9 + a7 * b8 + a8 * b7 + a9 * b6 + a10 * b5 + a11 * b4; - s16 = a5 * b11 + a6 * b10 + a7 * b9 + a8 * b8 + a9 * b7 + a10 * b6 + a11 * b5; - s17 = a6 * b11 + a7 * b10 + a8 * b9 + a9 * b8 + a10 * b7 + a11 * b6; - s18 = a7 * b11 + a8 * b10 + a9 * b9 + a10 * b8 + a11 * b7; - s19 = a8 * b11 + a9 * b10 + a10 * b9 + a11 * b8; - s20 = a9 * b11 + a10 * b10 + a11 * b9; - s21 = a10 * b11 + a11 * b10; - s22 = a11 * b11; - s23 = 0; - carry0 = (s0 + (1 << 20)) >> 21; - s1 += carry0; - s0 -= shl64(carry0, 21); - carry2 = (s2 + (1 << 20)) >> 21; - s3 += carry2; - s2 -= shl64(carry2, 21); - carry4 = (s4 + (1 << 20)) >> 21; - s5 += carry4; - s4 -= shl64(carry4, 21); - carry6 = (s6 + (1 << 20)) >> 21; - s7 += carry6; - s6 -= shl64(carry6, 21); - carry8 = (s8 + (1 << 20)) >> 21; - s9 += carry8; - s8 -= shl64(carry8, 21); - carry10 = (s10 + (1 << 20)) >> 21; - s11 += carry10; - s10 -= shl64(carry10, 21); - carry12 = (s12 + (1 << 20)) >> 21; - s13 += carry12; - s12 -= shl64(carry12, 21); - carry14 = (s14 + (1 << 20)) >> 21; - s15 += carry14; - s14 -= shl64(carry14, 21); - carry16 = (s16 + (1 << 20)) >> 21; - s17 += carry16; - s16 -= shl64(carry16, 21); - carry18 = (s18 + (1 << 20)) >> 21; - s19 += carry18; - s18 -= shl64(carry18, 21); - carry20 = (s20 + (1 << 20)) >> 21; - s21 += carry20; - s20 -= shl64(carry20, 21); - carry22 = (s22 + (1 << 20)) >> 21; - s23 += carry22; - s22 -= shl64(carry22, 21); - carry1 = (s1 + (1 << 20)) >> 21; - s2 += carry1; - s1 -= shl64(carry1, 21); - carry3 = (s3 + (1 << 20)) >> 21; - s4 += carry3; - s3 -= shl64(carry3, 21); - carry5 = (s5 + (1 << 20)) >> 21; - s6 += carry5; - s5 -= shl64(carry5, 21); - carry7 = (s7 + (1 << 20)) >> 21; - s8 += carry7; - s7 -= shl64(carry7, 21); - carry9 = (s9 + (1 << 20)) >> 21; - s10 += carry9; - s9 -= shl64(carry9, 21); - carry11 = (s11 + (1 << 20)) >> 21; - s12 += carry11; - s11 -= shl64(carry11, 21); - carry13 = (s13 + (1 << 20)) >> 21; - s14 += carry13; - s13 -= shl64(carry13, 21); - carry15 = (s15 + (1 << 20)) >> 21; - s16 += carry15; - s15 -= shl64(carry15, 21); - carry17 = (s17 + (1 << 20)) >> 21; - s18 += carry17; - s17 -= shl64(carry17, 21); - carry19 = (s19 + (1 << 20)) >> 21; - s20 += carry19; - s19 -= shl64(carry19, 21); - carry21 = (s21 + (1 << 20)) >> 21; - s22 += carry21; - s21 -= shl64(carry21, 21); - s11 += s23 * 666643; - s12 += s23 * 470296; - s13 += s23 * 654183; - s14 -= s23 * 997805; - s15 += s23 * 136657; - s16 -= s23 * 683901; - s10 += s22 * 666643; - s11 += s22 * 470296; - s12 += s22 * 654183; - s13 -= s22 * 997805; - s14 += s22 * 136657; - s15 -= s22 * 683901; - s9 += s21 * 666643; - s10 += s21 * 470296; - s11 += s21 * 654183; - s12 -= s21 * 997805; - s13 += s21 * 136657; - s14 -= s21 * 683901; - s8 += s20 * 666643; - s9 += s20 * 470296; - s10 += s20 * 654183; - s11 -= s20 * 997805; - s12 += s20 * 136657; - s13 -= s20 * 683901; - s7 += s19 * 666643; - s8 += s19 * 470296; - s9 += s19 * 654183; - s10 -= s19 * 997805; - s11 += s19 * 136657; - s12 -= s19 * 683901; - s6 += s18 * 666643; - s7 += s18 * 470296; - s8 += s18 * 654183; - s9 -= s18 * 997805; - s10 += s18 * 136657; - s11 -= s18 * 683901; - carry6 = (s6 + (1 << 20)) >> 21; - s7 += carry6; - s6 -= shl64(carry6, 21); - carry8 = (s8 + (1 << 20)) >> 21; - s9 += carry8; - s8 -= shl64(carry8, 21); - carry10 = (s10 + (1 << 20)) >> 21; - s11 += carry10; - s10 -= shl64(carry10, 21); - carry12 = (s12 + (1 << 20)) >> 21; - s13 += carry12; - s12 -= shl64(carry12, 21); - carry14 = (s14 + (1 << 20)) >> 21; - s15 += carry14; - s14 -= shl64(carry14, 21); - carry16 = (s16 + (1 << 20)) >> 21; - s17 += carry16; - s16 -= shl64(carry16, 21); - carry7 = (s7 + (1 << 20)) >> 21; - s8 += carry7; - s7 -= shl64(carry7, 21); - carry9 = (s9 + (1 << 20)) >> 21; - s10 += carry9; - s9 -= shl64(carry9, 21); - carry11 = (s11 + (1 << 20)) >> 21; - s12 += carry11; - s11 -= shl64(carry11, 21); - carry13 = (s13 + (1 << 20)) >> 21; - s14 += carry13; - s13 -= shl64(carry13, 21); - carry15 = (s15 + (1 << 20)) >> 21; - s16 += carry15; - s15 -= shl64(carry15, 21); - s5 += s17 * 666643; - s6 += s17 * 470296; - s7 += s17 * 654183; - s8 -= s17 * 997805; - s9 += s17 * 136657; - s10 -= s17 * 683901; - s4 += s16 * 666643; - s5 += s16 * 470296; - s6 += s16 * 654183; - s7 -= s16 * 997805; - s8 += s16 * 136657; - s9 -= s16 * 683901; - s3 += s15 * 666643; - s4 += s15 * 470296; - s5 += s15 * 654183; - s6 -= s15 * 997805; - s7 += s15 * 136657; - s8 -= s15 * 683901; - s2 += s14 * 666643; - s3 += s14 * 470296; - s4 += s14 * 654183; - s5 -= s14 * 997805; - s6 += s14 * 136657; - s7 -= s14 * 683901; - s1 += s13 * 666643; - s2 += s13 * 470296; - s3 += s13 * 654183; - s4 -= s13 * 997805; - s5 += s13 * 136657; - s6 -= s13 * 683901; - s0 += s12 * 666643; - s1 += s12 * 470296; - s2 += s12 * 654183; - s3 -= s12 * 997805; - s4 += s12 * 136657; - s5 -= s12 * 683901; - s12 = 0; - carry0 = (s0 + (1 << 20)) >> 21; - s1 += carry0; - s0 -= shl64(carry0, 21); - carry2 = (s2 + (1 << 20)) >> 21; - s3 += carry2; - s2 -= shl64(carry2, 21); - carry4 = (s4 + (1 << 20)) >> 21; - s5 += carry4; - s4 -= shl64(carry4, 21); - carry6 = (s6 + (1 << 20)) >> 21; - s7 += carry6; - s6 -= shl64(carry6, 21); - carry8 = (s8 + (1 << 20)) >> 21; - s9 += carry8; - s8 -= shl64(carry8, 21); - carry10 = (s10 + (1 << 20)) >> 21; - s11 += carry10; - s10 -= shl64(carry10, 21); - carry1 = (s1 + (1 << 20)) >> 21; - s2 += carry1; - s1 -= shl64(carry1, 21); - carry3 = (s3 + (1 << 20)) >> 21; - s4 += carry3; - s3 -= shl64(carry3, 21); - carry5 = (s5 + (1 << 20)) >> 21; - s6 += carry5; - s5 -= shl64(carry5, 21); - carry7 = (s7 + (1 << 20)) >> 21; - s8 += carry7; - s7 -= shl64(carry7, 21); - carry9 = (s9 + (1 << 20)) >> 21; - s10 += carry9; - s9 -= shl64(carry9, 21); - carry11 = (s11 + (1 << 20)) >> 21; - s12 += carry11; - s11 -= shl64(carry11, 21); - s0 += s12 * 666643; - s1 += s12 * 470296; - s2 += s12 * 654183; - s3 -= s12 * 997805; - s4 += s12 * 136657; - s5 -= s12 * 683901; - s12 = 0; - carry0 = s0 >> 21; - s1 += carry0; - s0 -= shl64(carry0, 21); - carry1 = s1 >> 21; - s2 += carry1; - s1 -= shl64(carry1, 21); - carry2 = s2 >> 21; - s3 += carry2; - s2 -= shl64(carry2, 21); - carry3 = s3 >> 21; - s4 += carry3; - s3 -= shl64(carry3, 21); - carry4 = s4 >> 21; - s5 += carry4; - s4 -= shl64(carry4, 21); - carry5 = s5 >> 21; - s6 += carry5; - s5 -= shl64(carry5, 21); - carry6 = s6 >> 21; - s7 += carry6; - s6 -= shl64(carry6, 21); - carry7 = s7 >> 21; - s8 += carry7; - s7 -= shl64(carry7, 21); - carry8 = s8 >> 21; - s9 += carry8; - s8 -= shl64(carry8, 21); - carry9 = s9 >> 21; - s10 += carry9; - s9 -= shl64(carry9, 21); - carry10 = s10 >> 21; - s11 += carry10; - s10 -= shl64(carry10, 21); - carry11 = s11 >> 21; - s12 += carry11; - s11 -= shl64(carry11, 21); - s0 += s12 * 666643; - s1 += s12 * 470296; - s2 += s12 * 654183; - s3 -= s12 * 997805; - s4 += s12 * 136657; - s5 -= s12 * 683901; - carry0 = s0 >> 21; - s1 += carry0; - s0 -= shl64(carry0, 21); - carry1 = s1 >> 21; - s2 += carry1; - s1 -= shl64(carry1, 21); - carry2 = s2 >> 21; - s3 += carry2; - s2 -= shl64(carry2, 21); - carry3 = s3 >> 21; - s4 += carry3; - s3 -= shl64(carry3, 21); - carry4 = s4 >> 21; - s5 += carry4; - s4 -= shl64(carry4, 21); - carry5 = s5 >> 21; - s6 += carry5; - s5 -= shl64(carry5, 21); - carry6 = s6 >> 21; - s7 += carry6; - s6 -= shl64(carry6, 21); - carry7 = s7 >> 21; - s8 += carry7; - s7 -= shl64(carry7, 21); - carry8 = s8 >> 21; - s9 += carry8; - s8 -= shl64(carry8, 21); - carry9 = s9 >> 21; - s10 += carry9; - s9 -= shl64(carry9, 21); - carry10 = s10 >> 21; - s11 += carry10; - s10 -= shl64(carry10, 21); - - s[0] = (unsigned char) (s0 >> 0); - s[1] = (unsigned char) (s0 >> 8); - s[2] = (unsigned char) ((s0 >> 16) | shl64(s1, 5)); - s[3] = (unsigned char) (s1 >> 3); - s[4] = (unsigned char) (s1 >> 11); - s[5] = (unsigned char) ((s1 >> 19) | shl64(s2, 2)); - s[6] = (unsigned char) (s2 >> 6); - s[7] = (unsigned char) ((s2 >> 14) | shl64(s3, 7)); - s[8] = (unsigned char) (s3 >> 1); - s[9] = (unsigned char) (s3 >> 9); - s[10] = (unsigned char) ((s3 >> 17) | shl64(s4, 4)); - s[11] = (unsigned char) (s4 >> 4); - s[12] = (unsigned char) (s4 >> 12); - s[13] = (unsigned char) ((s4 >> 20) | shl64(s5, 1)); - s[14] = (unsigned char) (s5 >> 7); - s[15] = (unsigned char) ((s5 >> 15) | shl64(s6, 6)); - s[16] = (unsigned char) (s6 >> 2); - s[17] = (unsigned char) (s6 >> 10); - s[18] = (unsigned char) ((s6 >> 18) | shl64(s7, 3)); - s[19] = (unsigned char) (s7 >> 5); - s[20] = (unsigned char) (s7 >> 13); - s[21] = (unsigned char) (s8 >> 0); - s[22] = (unsigned char) (s8 >> 8); - s[23] = (unsigned char) ((s8 >> 16) | shl64(s9, 5)); - s[24] = (unsigned char) (s9 >> 3); - s[25] = (unsigned char) (s9 >> 11); - s[26] = (unsigned char) ((s9 >> 19) | shl64(s10, 2)); - s[27] = (unsigned char) (s10 >> 6); - s[28] = (unsigned char) ((s10 >> 14) | shl64(s11, 7)); - s[29] = (unsigned char) (s11 >> 1); - s[30] = (unsigned char) (s11 >> 9); - s[31] = (unsigned char) (s11 >> 17); + s0 = c0 + a0 * b0; + s1 = c1 + a0 * b1 + a1 * b0; + s2 = c2 + a0 * b2 + a1 * b1 + a2 * b0; + s3 = c3 + a0 * b3 + a1 * b2 + a2 * b1 + a3 * b0; + s4 = c4 + a0 * b4 + a1 * b3 + a2 * b2 + a3 * b1 + a4 * b0; + s5 = c5 + a0 * b5 + a1 * b4 + a2 * b3 + a3 * b2 + a4 * b1 + a5 * b0; + s6 = c6 + a0 * b6 + a1 * b5 + a2 * b4 + a3 * b3 + a4 * b2 + a5 * b1 + a6 * b0; + s7 = c7 + a0 * b7 + a1 * b6 + a2 * b5 + a3 * b4 + a4 * b3 + a5 * b2 + a6 * b1 + a7 * b0; + s8 = c8 + a0 * b8 + a1 * b7 + a2 * b6 + a3 * b5 + a4 * b4 + a5 * b3 + a6 * b2 + a7 * b1 + a8 * b0; + s9 = c9 + a0 * b9 + a1 * b8 + a2 * b7 + a3 * b6 + a4 * b5 + a5 * b4 + a6 * b3 + a7 * b2 + a8 * b1 + a9 * b0; + s10 = c10 + a0 * b10 + a1 * b9 + a2 * b8 + a3 * b7 + a4 * b6 + a5 * b5 + a6 * b4 + a7 * b3 + a8 * b2 + a9 * b1 + a10 * b0; + s11 = c11 + a0 * b11 + a1 * b10 + a2 * b9 + a3 * b8 + a4 * b7 + a5 * b6 + a6 * b5 + a7 * b4 + a8 * b3 + a9 * b2 + a10 * b1 + a11 * b0; + s12 = a1 * b11 + a2 * b10 + a3 * b9 + a4 * b8 + a5 * b7 + a6 * b6 + a7 * b5 + a8 * b4 + a9 * b3 + a10 * b2 + a11 * b1; + s13 = a2 * b11 + a3 * b10 + a4 * b9 + a5 * b8 + a6 * b7 + a7 * b6 + a8 * b5 + a9 * b4 + a10 * b3 + a11 * b2; + s14 = a3 * b11 + a4 * b10 + a5 * b9 + a6 * b8 + a7 * b7 + a8 * b6 + a9 * b5 + a10 * b4 + a11 * b3; + s15 = a4 * b11 + a5 * b10 + a6 * b9 + a7 * b8 + a8 * b7 + a9 * b6 + a10 * b5 + a11 * b4; + s16 = a5 * b11 + a6 * b10 + a7 * b9 + a8 * b8 + a9 * b7 + a10 * b6 + a11 * b5; + s17 = a6 * b11 + a7 * b10 + a8 * b9 + a9 * b8 + a10 * b7 + a11 * b6; + s18 = a7 * b11 + a8 * b10 + a9 * b9 + a10 * b8 + a11 * b7; + s19 = a8 * b11 + a9 * b10 + a10 * b9 + a11 * b8; + s20 = a9 * b11 + a10 * b10 + a11 * b9; + s21 = a10 * b11 + a11 * b10; + s22 = a11 * b11; + s23 = 0; + carry0 = (s0 + (1 << 20)) >> 21; + s1 += carry0; + s0 -= shl64(carry0, 21); + carry2 = (s2 + (1 << 20)) >> 21; + s3 += carry2; + s2 -= shl64(carry2, 21); + carry4 = (s4 + (1 << 20)) >> 21; + s5 += carry4; + s4 -= shl64(carry4, 21); + carry6 = (s6 + (1 << 20)) >> 21; + s7 += carry6; + s6 -= shl64(carry6, 21); + carry8 = (s8 + (1 << 20)) >> 21; + s9 += carry8; + s8 -= shl64(carry8, 21); + carry10 = (s10 + (1 << 20)) >> 21; + s11 += carry10; + s10 -= shl64(carry10, 21); + carry12 = (s12 + (1 << 20)) >> 21; + s13 += carry12; + s12 -= shl64(carry12, 21); + carry14 = (s14 + (1 << 20)) >> 21; + s15 += carry14; + s14 -= shl64(carry14, 21); + carry16 = (s16 + (1 << 20)) >> 21; + s17 += carry16; + s16 -= shl64(carry16, 21); + carry18 = (s18 + (1 << 20)) >> 21; + s19 += carry18; + s18 -= shl64(carry18, 21); + carry20 = (s20 + (1 << 20)) >> 21; + s21 += carry20; + s20 -= shl64(carry20, 21); + carry22 = (s22 + (1 << 20)) >> 21; + s23 += carry22; + s22 -= shl64(carry22, 21); + carry1 = (s1 + (1 << 20)) >> 21; + s2 += carry1; + s1 -= shl64(carry1, 21); + carry3 = (s3 + (1 << 20)) >> 21; + s4 += carry3; + s3 -= shl64(carry3, 21); + carry5 = (s5 + (1 << 20)) >> 21; + s6 += carry5; + s5 -= shl64(carry5, 21); + carry7 = (s7 + (1 << 20)) >> 21; + s8 += carry7; + s7 -= shl64(carry7, 21); + carry9 = (s9 + (1 << 20)) >> 21; + s10 += carry9; + s9 -= shl64(carry9, 21); + carry11 = (s11 + (1 << 20)) >> 21; + s12 += carry11; + s11 -= shl64(carry11, 21); + carry13 = (s13 + (1 << 20)) >> 21; + s14 += carry13; + s13 -= shl64(carry13, 21); + carry15 = (s15 + (1 << 20)) >> 21; + s16 += carry15; + s15 -= shl64(carry15, 21); + carry17 = (s17 + (1 << 20)) >> 21; + s18 += carry17; + s17 -= shl64(carry17, 21); + carry19 = (s19 + (1 << 20)) >> 21; + s20 += carry19; + s19 -= shl64(carry19, 21); + carry21 = (s21 + (1 << 20)) >> 21; + s22 += carry21; + s21 -= shl64(carry21, 21); + s11 += s23 * 666643; + s12 += s23 * 470296; + s13 += s23 * 654183; + s14 -= s23 * 997805; + s15 += s23 * 136657; + s16 -= s23 * 683901; + s10 += s22 * 666643; + s11 += s22 * 470296; + s12 += s22 * 654183; + s13 -= s22 * 997805; + s14 += s22 * 136657; + s15 -= s22 * 683901; + s9 += s21 * 666643; + s10 += s21 * 470296; + s11 += s21 * 654183; + s12 -= s21 * 997805; + s13 += s21 * 136657; + s14 -= s21 * 683901; + s8 += s20 * 666643; + s9 += s20 * 470296; + s10 += s20 * 654183; + s11 -= s20 * 997805; + s12 += s20 * 136657; + s13 -= s20 * 683901; + s7 += s19 * 666643; + s8 += s19 * 470296; + s9 += s19 * 654183; + s10 -= s19 * 997805; + s11 += s19 * 136657; + s12 -= s19 * 683901; + s6 += s18 * 666643; + s7 += s18 * 470296; + s8 += s18 * 654183; + s9 -= s18 * 997805; + s10 += s18 * 136657; + s11 -= s18 * 683901; + carry6 = (s6 + (1 << 20)) >> 21; + s7 += carry6; + s6 -= shl64(carry6, 21); + carry8 = (s8 + (1 << 20)) >> 21; + s9 += carry8; + s8 -= shl64(carry8, 21); + carry10 = (s10 + (1 << 20)) >> 21; + s11 += carry10; + s10 -= shl64(carry10, 21); + carry12 = (s12 + (1 << 20)) >> 21; + s13 += carry12; + s12 -= shl64(carry12, 21); + carry14 = (s14 + (1 << 20)) >> 21; + s15 += carry14; + s14 -= shl64(carry14, 21); + carry16 = (s16 + (1 << 20)) >> 21; + s17 += carry16; + s16 -= shl64(carry16, 21); + carry7 = (s7 + (1 << 20)) >> 21; + s8 += carry7; + s7 -= shl64(carry7, 21); + carry9 = (s9 + (1 << 20)) >> 21; + s10 += carry9; + s9 -= shl64(carry9, 21); + carry11 = (s11 + (1 << 20)) >> 21; + s12 += carry11; + s11 -= shl64(carry11, 21); + carry13 = (s13 + (1 << 20)) >> 21; + s14 += carry13; + s13 -= shl64(carry13, 21); + carry15 = (s15 + (1 << 20)) >> 21; + s16 += carry15; + s15 -= shl64(carry15, 21); + s5 += s17 * 666643; + s6 += s17 * 470296; + s7 += s17 * 654183; + s8 -= s17 * 997805; + s9 += s17 * 136657; + s10 -= s17 * 683901; + s4 += s16 * 666643; + s5 += s16 * 470296; + s6 += s16 * 654183; + s7 -= s16 * 997805; + s8 += s16 * 136657; + s9 -= s16 * 683901; + s3 += s15 * 666643; + s4 += s15 * 470296; + s5 += s15 * 654183; + s6 -= s15 * 997805; + s7 += s15 * 136657; + s8 -= s15 * 683901; + s2 += s14 * 666643; + s3 += s14 * 470296; + s4 += s14 * 654183; + s5 -= s14 * 997805; + s6 += s14 * 136657; + s7 -= s14 * 683901; + s1 += s13 * 666643; + s2 += s13 * 470296; + s3 += s13 * 654183; + s4 -= s13 * 997805; + s5 += s13 * 136657; + s6 -= s13 * 683901; + s0 += s12 * 666643; + s1 += s12 * 470296; + s2 += s12 * 654183; + s3 -= s12 * 997805; + s4 += s12 * 136657; + s5 -= s12 * 683901; + s12 = 0; + carry0 = (s0 + (1 << 20)) >> 21; + s1 += carry0; + s0 -= shl64(carry0, 21); + carry2 = (s2 + (1 << 20)) >> 21; + s3 += carry2; + s2 -= shl64(carry2, 21); + carry4 = (s4 + (1 << 20)) >> 21; + s5 += carry4; + s4 -= shl64(carry4, 21); + carry6 = (s6 + (1 << 20)) >> 21; + s7 += carry6; + s6 -= shl64(carry6, 21); + carry8 = (s8 + (1 << 20)) >> 21; + s9 += carry8; + s8 -= shl64(carry8, 21); + carry10 = (s10 + (1 << 20)) >> 21; + s11 += carry10; + s10 -= shl64(carry10, 21); + carry1 = (s1 + (1 << 20)) >> 21; + s2 += carry1; + s1 -= shl64(carry1, 21); + carry3 = (s3 + (1 << 20)) >> 21; + s4 += carry3; + s3 -= shl64(carry3, 21); + carry5 = (s5 + (1 << 20)) >> 21; + s6 += carry5; + s5 -= shl64(carry5, 21); + carry7 = (s7 + (1 << 20)) >> 21; + s8 += carry7; + s7 -= shl64(carry7, 21); + carry9 = (s9 + (1 << 20)) >> 21; + s10 += carry9; + s9 -= shl64(carry9, 21); + carry11 = (s11 + (1 << 20)) >> 21; + s12 += carry11; + s11 -= shl64(carry11, 21); + s0 += s12 * 666643; + s1 += s12 * 470296; + s2 += s12 * 654183; + s3 -= s12 * 997805; + s4 += s12 * 136657; + s5 -= s12 * 683901; + s12 = 0; + carry0 = s0 >> 21; + s1 += carry0; + s0 -= shl64(carry0, 21); + carry1 = s1 >> 21; + s2 += carry1; + s1 -= shl64(carry1, 21); + carry2 = s2 >> 21; + s3 += carry2; + s2 -= shl64(carry2, 21); + carry3 = s3 >> 21; + s4 += carry3; + s3 -= shl64(carry3, 21); + carry4 = s4 >> 21; + s5 += carry4; + s4 -= shl64(carry4, 21); + carry5 = s5 >> 21; + s6 += carry5; + s5 -= shl64(carry5, 21); + carry6 = s6 >> 21; + s7 += carry6; + s6 -= shl64(carry6, 21); + carry7 = s7 >> 21; + s8 += carry7; + s7 -= shl64(carry7, 21); + carry8 = s8 >> 21; + s9 += carry8; + s8 -= shl64(carry8, 21); + carry9 = s9 >> 21; + s10 += carry9; + s9 -= shl64(carry9, 21); + carry10 = s10 >> 21; + s11 += carry10; + s10 -= shl64(carry10, 21); + carry11 = s11 >> 21; + s12 += carry11; + s11 -= shl64(carry11, 21); + s0 += s12 * 666643; + s1 += s12 * 470296; + s2 += s12 * 654183; + s3 -= s12 * 997805; + s4 += s12 * 136657; + s5 -= s12 * 683901; + carry0 = s0 >> 21; + s1 += carry0; + s0 -= shl64(carry0, 21); + carry1 = s1 >> 21; + s2 += carry1; + s1 -= shl64(carry1, 21); + carry2 = s2 >> 21; + s3 += carry2; + s2 -= shl64(carry2, 21); + carry3 = s3 >> 21; + s4 += carry3; + s3 -= shl64(carry3, 21); + carry4 = s4 >> 21; + s5 += carry4; + s4 -= shl64(carry4, 21); + carry5 = s5 >> 21; + s6 += carry5; + s5 -= shl64(carry5, 21); + carry6 = s6 >> 21; + s7 += carry6; + s6 -= shl64(carry6, 21); + carry7 = s7 >> 21; + s8 += carry7; + s7 -= shl64(carry7, 21); + carry8 = s8 >> 21; + s9 += carry8; + s8 -= shl64(carry8, 21); + carry9 = s9 >> 21; + s10 += carry9; + s9 -= shl64(carry9, 21); + carry10 = s10 >> 21; + s11 += carry10; + s10 -= shl64(carry10, 21); + + s[0] = (unsigned char)(s0 >> 0); + s[1] = (unsigned char)(s0 >> 8); + s[2] = (unsigned char)((s0 >> 16) | shl64(s1, 5)); + s[3] = (unsigned char)(s1 >> 3); + s[4] = (unsigned char)(s1 >> 11); + s[5] = (unsigned char)((s1 >> 19) | shl64(s2, 2)); + s[6] = (unsigned char)(s2 >> 6); + s[7] = (unsigned char)((s2 >> 14) | shl64(s3, 7)); + s[8] = (unsigned char)(s3 >> 1); + s[9] = (unsigned char)(s3 >> 9); + s[10] = (unsigned char)((s3 >> 17) | shl64(s4, 4)); + s[11] = (unsigned char)(s4 >> 4); + s[12] = (unsigned char)(s4 >> 12); + s[13] = (unsigned char)((s4 >> 20) | shl64(s5, 1)); + s[14] = (unsigned char)(s5 >> 7); + s[15] = (unsigned char)((s5 >> 15) | shl64(s6, 6)); + s[16] = (unsigned char)(s6 >> 2); + s[17] = (unsigned char)(s6 >> 10); + s[18] = (unsigned char)((s6 >> 18) | shl64(s7, 3)); + s[19] = (unsigned char)(s7 >> 5); + s[20] = (unsigned char)(s7 >> 13); + s[21] = (unsigned char)(s8 >> 0); + s[22] = (unsigned char)(s8 >> 8); + s[23] = (unsigned char)((s8 >> 16) | shl64(s9, 5)); + s[24] = (unsigned char)(s9 >> 3); + s[25] = (unsigned char)(s9 >> 11); + s[26] = (unsigned char)((s9 >> 19) | shl64(s10, 2)); + s[27] = (unsigned char)(s10 >> 6); + s[28] = (unsigned char)((s10 >> 14) | shl64(s11, 7)); + s[29] = (unsigned char)(s11 >> 1); + s[30] = (unsigned char)(s11 >> 9); + s[31] = (unsigned char)(s11 >> 17); } diff --git a/src/ed25519/sha512.c b/src/ed25519/sha512.c index e1db1e5..9cdf94d 100644 --- a/src/ed25519/sha512.c +++ b/src/ed25519/sha512.c @@ -14,65 +14,65 @@ /* the K array */ static const uint64_t K[80] = { - UINT64_C(0x428a2f98d728ae22), UINT64_C(0x7137449123ef65cd), - UINT64_C(0xb5c0fbcfec4d3b2f), UINT64_C(0xe9b5dba58189dbbc), - UINT64_C(0x3956c25bf348b538), UINT64_C(0x59f111f1b605d019), - UINT64_C(0x923f82a4af194f9b), UINT64_C(0xab1c5ed5da6d8118), - UINT64_C(0xd807aa98a3030242), UINT64_C(0x12835b0145706fbe), - UINT64_C(0x243185be4ee4b28c), UINT64_C(0x550c7dc3d5ffb4e2), - UINT64_C(0x72be5d74f27b896f), UINT64_C(0x80deb1fe3b1696b1), - UINT64_C(0x9bdc06a725c71235), UINT64_C(0xc19bf174cf692694), - UINT64_C(0xe49b69c19ef14ad2), UINT64_C(0xefbe4786384f25e3), - UINT64_C(0x0fc19dc68b8cd5b5), UINT64_C(0x240ca1cc77ac9c65), - UINT64_C(0x2de92c6f592b0275), UINT64_C(0x4a7484aa6ea6e483), - UINT64_C(0x5cb0a9dcbd41fbd4), UINT64_C(0x76f988da831153b5), - UINT64_C(0x983e5152ee66dfab), UINT64_C(0xa831c66d2db43210), - UINT64_C(0xb00327c898fb213f), UINT64_C(0xbf597fc7beef0ee4), - UINT64_C(0xc6e00bf33da88fc2), UINT64_C(0xd5a79147930aa725), - UINT64_C(0x06ca6351e003826f), UINT64_C(0x142929670a0e6e70), - UINT64_C(0x27b70a8546d22ffc), UINT64_C(0x2e1b21385c26c926), - UINT64_C(0x4d2c6dfc5ac42aed), UINT64_C(0x53380d139d95b3df), - UINT64_C(0x650a73548baf63de), UINT64_C(0x766a0abb3c77b2a8), - UINT64_C(0x81c2c92e47edaee6), UINT64_C(0x92722c851482353b), - UINT64_C(0xa2bfe8a14cf10364), UINT64_C(0xa81a664bbc423001), - UINT64_C(0xc24b8b70d0f89791), UINT64_C(0xc76c51a30654be30), - UINT64_C(0xd192e819d6ef5218), UINT64_C(0xd69906245565a910), - UINT64_C(0xf40e35855771202a), UINT64_C(0x106aa07032bbd1b8), - UINT64_C(0x19a4c116b8d2d0c8), UINT64_C(0x1e376c085141ab53), - UINT64_C(0x2748774cdf8eeb99), UINT64_C(0x34b0bcb5e19b48a8), - UINT64_C(0x391c0cb3c5c95a63), UINT64_C(0x4ed8aa4ae3418acb), - UINT64_C(0x5b9cca4f7763e373), UINT64_C(0x682e6ff3d6b2b8a3), - UINT64_C(0x748f82ee5defb2fc), UINT64_C(0x78a5636f43172f60), - UINT64_C(0x84c87814a1f0ab72), UINT64_C(0x8cc702081a6439ec), - UINT64_C(0x90befffa23631e28), UINT64_C(0xa4506cebde82bde9), - UINT64_C(0xbef9a3f7b2c67915), UINT64_C(0xc67178f2e372532b), - UINT64_C(0xca273eceea26619c), UINT64_C(0xd186b8c721c0c207), - UINT64_C(0xeada7dd6cde0eb1e), UINT64_C(0xf57d4f7fee6ed178), - UINT64_C(0x06f067aa72176fba), UINT64_C(0x0a637dc5a2c898a6), - UINT64_C(0x113f9804bef90dae), UINT64_C(0x1b710b35131c471b), - UINT64_C(0x28db77f523047d84), UINT64_C(0x32caab7b40c72493), - UINT64_C(0x3c9ebe0a15c9bebc), UINT64_C(0x431d67c49c100d4c), - UINT64_C(0x4cc5d4becb3e42b6), UINT64_C(0x597f299cfc657e2a), - UINT64_C(0x5fcb6fab3ad6faec), UINT64_C(0x6c44198c4a475817) + UINT64_C(0x428a2f98d728ae22), UINT64_C(0x7137449123ef65cd), + UINT64_C(0xb5c0fbcfec4d3b2f), UINT64_C(0xe9b5dba58189dbbc), + UINT64_C(0x3956c25bf348b538), UINT64_C(0x59f111f1b605d019), + UINT64_C(0x923f82a4af194f9b), UINT64_C(0xab1c5ed5da6d8118), + UINT64_C(0xd807aa98a3030242), UINT64_C(0x12835b0145706fbe), + UINT64_C(0x243185be4ee4b28c), UINT64_C(0x550c7dc3d5ffb4e2), + UINT64_C(0x72be5d74f27b896f), UINT64_C(0x80deb1fe3b1696b1), + UINT64_C(0x9bdc06a725c71235), UINT64_C(0xc19bf174cf692694), + UINT64_C(0xe49b69c19ef14ad2), UINT64_C(0xefbe4786384f25e3), + UINT64_C(0x0fc19dc68b8cd5b5), UINT64_C(0x240ca1cc77ac9c65), + UINT64_C(0x2de92c6f592b0275), UINT64_C(0x4a7484aa6ea6e483), + UINT64_C(0x5cb0a9dcbd41fbd4), UINT64_C(0x76f988da831153b5), + UINT64_C(0x983e5152ee66dfab), UINT64_C(0xa831c66d2db43210), + UINT64_C(0xb00327c898fb213f), UINT64_C(0xbf597fc7beef0ee4), + UINT64_C(0xc6e00bf33da88fc2), UINT64_C(0xd5a79147930aa725), + UINT64_C(0x06ca6351e003826f), UINT64_C(0x142929670a0e6e70), + UINT64_C(0x27b70a8546d22ffc), UINT64_C(0x2e1b21385c26c926), + UINT64_C(0x4d2c6dfc5ac42aed), UINT64_C(0x53380d139d95b3df), + UINT64_C(0x650a73548baf63de), UINT64_C(0x766a0abb3c77b2a8), + UINT64_C(0x81c2c92e47edaee6), UINT64_C(0x92722c851482353b), + UINT64_C(0xa2bfe8a14cf10364), UINT64_C(0xa81a664bbc423001), + UINT64_C(0xc24b8b70d0f89791), UINT64_C(0xc76c51a30654be30), + UINT64_C(0xd192e819d6ef5218), UINT64_C(0xd69906245565a910), + UINT64_C(0xf40e35855771202a), UINT64_C(0x106aa07032bbd1b8), + UINT64_C(0x19a4c116b8d2d0c8), UINT64_C(0x1e376c085141ab53), + UINT64_C(0x2748774cdf8eeb99), UINT64_C(0x34b0bcb5e19b48a8), + UINT64_C(0x391c0cb3c5c95a63), UINT64_C(0x4ed8aa4ae3418acb), + UINT64_C(0x5b9cca4f7763e373), UINT64_C(0x682e6ff3d6b2b8a3), + UINT64_C(0x748f82ee5defb2fc), UINT64_C(0x78a5636f43172f60), + UINT64_C(0x84c87814a1f0ab72), UINT64_C(0x8cc702081a6439ec), + UINT64_C(0x90befffa23631e28), UINT64_C(0xa4506cebde82bde9), + UINT64_C(0xbef9a3f7b2c67915), UINT64_C(0xc67178f2e372532b), + UINT64_C(0xca273eceea26619c), UINT64_C(0xd186b8c721c0c207), + UINT64_C(0xeada7dd6cde0eb1e), UINT64_C(0xf57d4f7fee6ed178), + UINT64_C(0x06f067aa72176fba), UINT64_C(0x0a637dc5a2c898a6), + UINT64_C(0x113f9804bef90dae), UINT64_C(0x1b710b35131c471b), + UINT64_C(0x28db77f523047d84), UINT64_C(0x32caab7b40c72493), + UINT64_C(0x3c9ebe0a15c9bebc), UINT64_C(0x431d67c49c100d4c), + UINT64_C(0x4cc5d4becb3e42b6), UINT64_C(0x597f299cfc657e2a), + UINT64_C(0x5fcb6fab3ad6faec), UINT64_C(0x6c44198c4a475817) }; /* Various logical functions */ #define ROR64c(x, y) \ - ( ((((x)&UINT64_C(0xFFFFFFFFFFFFFFFF))>>((uint64_t)(y)&UINT64_C(63))) | \ - ((x)<<((uint64_t)(64-((y)&UINT64_C(63)))))) & UINT64_C(0xFFFFFFFFFFFFFFFF)) + ( ((((x)&UINT64_C(0xFFFFFFFFFFFFFFFF))>>((uint64_t)(y)&UINT64_C(63))) | \ + ((x)<<((uint64_t)(64-((y)&UINT64_C(63)))))) & UINT64_C(0xFFFFFFFFFFFFFFFF)) #define STORE64H(x, y) \ - { (y)[0] = (unsigned char)(((x)>>56)&255); (y)[1] = (unsigned char)(((x)>>48)&255); \ - (y)[2] = (unsigned char)(((x)>>40)&255); (y)[3] = (unsigned char)(((x)>>32)&255); \ - (y)[4] = (unsigned char)(((x)>>24)&255); (y)[5] = (unsigned char)(((x)>>16)&255); \ - (y)[6] = (unsigned char)(((x)>>8)&255); (y)[7] = (unsigned char)((x)&255); } + { (y)[0] = (unsigned char)(((x)>>56)&255); (y)[1] = (unsigned char)(((x)>>48)&255); \ + (y)[2] = (unsigned char)(((x)>>40)&255); (y)[3] = (unsigned char)(((x)>>32)&255); \ + (y)[4] = (unsigned char)(((x)>>24)&255); (y)[5] = (unsigned char)(((x)>>16)&255); \ + (y)[6] = (unsigned char)(((x)>>8)&255); (y)[7] = (unsigned char)((x)&255); } #define LOAD64H(x, y) \ - { x = (((uint64_t)((y)[0] & 255))<<56)|(((uint64_t)((y)[1] & 255))<<48) | \ - (((uint64_t)((y)[2] & 255))<<40)|(((uint64_t)((y)[3] & 255))<<32) | \ - (((uint64_t)((y)[4] & 255))<<24)|(((uint64_t)((y)[5] & 255))<<16) | \ - (((uint64_t)((y)[6] & 255))<<8)|(((uint64_t)((y)[7] & 255))); } + { x = (((uint64_t)((y)[0] & 255))<<56)|(((uint64_t)((y)[1] & 255))<<48) | \ + (((uint64_t)((y)[2] & 255))<<40)|(((uint64_t)((y)[3] & 255))<<32) | \ + (((uint64_t)((y)[4] & 255))<<24)|(((uint64_t)((y)[5] & 255))<<16) | \ + (((uint64_t)((y)[6] & 255))<<8)|(((uint64_t)((y)[7] & 255))); } #define Ch(x,y,z) (z ^ (x & (y ^ z))) @@ -84,58 +84,57 @@ static const uint64_t K[80] = { #define Gamma0(x) (S(x, 1) ^ S(x, 8) ^ R(x, 7)) #define Gamma1(x) (S(x, 19) ^ S(x, 61) ^ R(x, 6)) #ifndef MIN - #define MIN(x, y) ( ((x)<(y))?(x):(y) ) +#define MIN(x, y) ( ((x)<(y))?(x):(y) ) #endif /* compress 1024-bits */ -static int sha512_compress(sha512_context *md, const unsigned char *buf) -{ - uint64_t S[8], W[80], t0, t1; - int i; +static int sha512_compress(sha512_context *md, const unsigned char *buf) { + uint64_t S[8], W[80], t0, t1; + int i; - /* copy state into S */ - for (i = 0; i < 8; i++) { - S[i] = md->state[i]; - } + /* copy state into S */ + for(i = 0; i < 8; i++) { + S[i] = md->state[i]; + } - /* copy the state into 1024-bits into W[0..15] */ - for (i = 0; i < 16; i++) { - LOAD64H(W[i], buf + (8*i)); - } + /* copy the state into 1024-bits into W[0..15] */ + for(i = 0; i < 16; i++) { + LOAD64H(W[i], buf + (8 * i)); + } - /* fill W[16..79] */ - for (i = 16; i < 80; i++) { - W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16]; - } + /* fill W[16..79] */ + for(i = 16; i < 80; i++) { + W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16]; + } -/* Compress */ - #define RND(a,b,c,d,e,f,g,h,i) \ - t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i]; \ - t1 = Sigma0(a) + Maj(a, b, c);\ - d += t0; \ - h = t0 + t1; + /* Compress */ +#define RND(a,b,c,d,e,f,g,h,i) \ + t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i]; \ + t1 = Sigma0(a) + Maj(a, b, c);\ + d += t0; \ + h = t0 + t1; - for (i = 0; i < 80; i += 8) { - RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],i+0); - RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],i+1); - RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],i+2); - RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],i+3); - RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],i+4); - RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],i+5); - RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],i+6); - RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],i+7); - } + for(i = 0; i < 80; i += 8) { + RND(S[0], S[1], S[2], S[3], S[4], S[5], S[6], S[7], i + 0); + RND(S[7], S[0], S[1], S[2], S[3], S[4], S[5], S[6], i + 1); + RND(S[6], S[7], S[0], S[1], S[2], S[3], S[4], S[5], i + 2); + RND(S[5], S[6], S[7], S[0], S[1], S[2], S[3], S[4], i + 3); + RND(S[4], S[5], S[6], S[7], S[0], S[1], S[2], S[3], i + 4); + RND(S[3], S[4], S[5], S[6], S[7], S[0], S[1], S[2], i + 5); + RND(S[2], S[3], S[4], S[5], S[6], S[7], S[0], S[1], i + 6); + RND(S[1], S[2], S[3], S[4], S[5], S[6], S[7], S[0], i + 7); + } - #undef RND +#undef RND - /* feedback */ - for (i = 0; i < 8; i++) { - md->state[i] = md->state[i] + S[i]; - } + /* feedback */ + for(i = 0; i < 8; i++) { + md->state[i] = md->state[i] + S[i]; + } - return 0; + return 0; } @@ -144,21 +143,23 @@ static int sha512_compress(sha512_context *md, const unsigned char *buf) @param md The hash state you wish to initialize @return 0 if successful */ -int sha512_init(sha512_context * md) { - if (md == NULL) return 1; +int sha512_init(sha512_context *md) { + if(md == NULL) { + return 1; + } - md->curlen = 0; - md->length = 0; - md->state[0] = UINT64_C(0x6a09e667f3bcc908); - md->state[1] = UINT64_C(0xbb67ae8584caa73b); - md->state[2] = UINT64_C(0x3c6ef372fe94f82b); - md->state[3] = UINT64_C(0xa54ff53a5f1d36f1); - md->state[4] = UINT64_C(0x510e527fade682d1); - md->state[5] = UINT64_C(0x9b05688c2b3e6c1f); - md->state[6] = UINT64_C(0x1f83d9abfb41bd6b); - md->state[7] = UINT64_C(0x5be0cd19137e2179); + md->curlen = 0; + md->length = 0; + md->state[0] = UINT64_C(0x6a09e667f3bcc908); + md->state[1] = UINT64_C(0xbb67ae8584caa73b); + md->state[2] = UINT64_C(0x3c6ef372fe94f82b); + md->state[3] = UINT64_C(0xa54ff53a5f1d36f1); + md->state[4] = UINT64_C(0x510e527fade682d1); + md->state[5] = UINT64_C(0x9b05688c2b3e6c1f); + md->state[6] = UINT64_C(0x1f83d9abfb41bd6b); + md->state[7] = UINT64_C(0x5be0cd19137e2179); - return 0; + return 0; } /** @@ -168,46 +169,57 @@ int sha512_init(sha512_context * md) { @param inlen The length of the data (octets) @return 0 if successful */ -int sha512_update(sha512_context *md, const void *vin, size_t inlen) -{ - const unsigned char *in = vin; - size_t n; - size_t i; - int err; - if (md == NULL) return 1; - if (in == NULL) return 1; - if (md->curlen > sizeof(md->buf)) { - return 1; - } - while (inlen > 0) { - if (md->curlen == 0 && inlen >= 128) { - if ((err = sha512_compress (md, in)) != 0) { - return err; - } - md->length += 128 * 8; - in += 128; - inlen -= 128; - } else { - n = MIN(inlen, (128 - md->curlen)); +int sha512_update(sha512_context *md, const void *vin, size_t inlen) { + const unsigned char *in = vin; + size_t n; + size_t i; + int err; - for (i = 0; i < n; i++) { - md->buf[i + md->curlen] = in[i]; - } + if(md == NULL) { + return 1; + } + + if(in == NULL) { + return 1; + } + + if(md->curlen > sizeof(md->buf)) { + return 1; + } + + while(inlen > 0) { + if(md->curlen == 0 && inlen >= 128) { + if((err = sha512_compress(md, in)) != 0) { + return err; + } + + md->length += 128 * 8; + in += 128; + inlen -= 128; + } else { + n = MIN(inlen, (128 - md->curlen)); + + for(i = 0; i < n; i++) { + md->buf[i + md->curlen] = in[i]; + } - md->curlen += n; - in += n; - inlen -= n; - if (md->curlen == 128) { - if ((err = sha512_compress (md, md->buf)) != 0) { - return err; - } - md->length += 8*128; - md->curlen = 0; - } - } - } - return 0; + md->curlen += n; + in += n; + inlen -= n; + + if(md->curlen == 128) { + if((err = sha512_compress(md, md->buf)) != 0) { + return err; + } + + md->length += 8 * 128; + md->curlen = 0; + } + } + } + + return 0; } /** @@ -216,62 +228,76 @@ int sha512_update(sha512_context *md, const void *vin, size_t inlen) @param out [out] The destination of the hash (64 bytes) @return 0 if successful */ -int sha512_final(sha512_context * md, void *vout) -{ - int i; - unsigned char *out = vout; +int sha512_final(sha512_context *md, void *vout) { + int i; + unsigned char *out = vout; - if (md == NULL) return 1; - if (out == NULL) return 1; + if(md == NULL) { + return 1; + } - if (md->curlen >= sizeof(md->buf)) { - return 1; - } + if(out == NULL) { + return 1; + } - /* increase the length of the message */ - md->length += md->curlen * UINT64_C(8); + if(md->curlen >= sizeof(md->buf)) { + return 1; + } - /* append the '1' bit */ - md->buf[md->curlen++] = (unsigned char)0x80; + /* increase the length of the message */ + md->length += md->curlen * UINT64_C(8); - /* if the length is currently above 112 bytes we append zeros - * then compress. Then we can fall back to padding zeros and length - * encoding like normal. - */ - if (md->curlen > 112) { - while (md->curlen < 128) { - md->buf[md->curlen++] = (unsigned char)0; - } - sha512_compress(md, md->buf); - md->curlen = 0; - } + /* append the '1' bit */ + md->buf[md->curlen++] = (unsigned char)0x80; - /* pad upto 120 bytes of zeroes - * note: that from 112 to 120 is the 64 MSB of the length. We assume that you won't hash - * > 2^64 bits of data... :-) - */ - while (md->curlen < 120) { - md->buf[md->curlen++] = (unsigned char)0; - } + /* if the length is currently above 112 bytes we append zeros + * then compress. Then we can fall back to padding zeros and length + * encoding like normal. + */ + if(md->curlen > 112) { + while(md->curlen < 128) { + md->buf[md->curlen++] = (unsigned char)0; + } - /* store length */ - STORE64H(md->length, md->buf+120); - sha512_compress(md, md->buf); + sha512_compress(md, md->buf); + md->curlen = 0; + } - /* copy output */ - for (i = 0; i < 8; i++) { - STORE64H(md->state[i], out+(8*i)); - } + /* pad up to 120 bytes of zeroes + * note: that from 112 to 120 is the 64 MSB of the length. We assume that you won't hash + * > 2^64 bits of data... :-) + */ + while(md->curlen < 120) { + md->buf[md->curlen++] = (unsigned char)0; + } - return 0; + /* store length */ + STORE64H(md->length, md->buf + 120); + sha512_compress(md, md->buf); + + /* copy output */ + for(i = 0; i < 8; i++) { + STORE64H(md->state[i], out + (8 * i)); + } + + return 0; } -int sha512(const void *message, size_t message_len, void *out) -{ - sha512_context ctx; - int ret; - if ((ret = sha512_init(&ctx))) return ret; - if ((ret = sha512_update(&ctx, message, message_len))) return ret; - if ((ret = sha512_final(&ctx, out))) return ret; - return 0; +int sha512(const void *message, size_t message_len, void *out) { + sha512_context ctx; + int ret; + + if((ret = sha512_init(&ctx))) { + return ret; + } + + if((ret = sha512_update(&ctx, message, message_len))) { + return ret; + } + + if((ret = sha512_final(&ctx, out))) { + return ret; + } + + return 0; } diff --git a/src/ed25519/sha512.h b/src/ed25519/sha512.h index e23f8db..95461ce 100644 --- a/src/ed25519/sha512.h +++ b/src/ed25519/sha512.h @@ -7,15 +7,15 @@ /* state */ typedef struct sha512_context_ { - uint64_t length, state[8]; - size_t curlen; - unsigned char buf[128]; + uint64_t length, state[8]; + size_t curlen; + unsigned char buf[128]; } sha512_context; -int sha512_init(sha512_context * md); -int sha512_final(sha512_context * md, void *out); -int sha512_update(sha512_context * md, const void *in, size_t inlen); +int sha512_init(sha512_context *md); +int sha512_final(sha512_context *md, void *out); +int sha512_update(sha512_context *md, const void *in, size_t inlen); int sha512(const void *message, size_t message_len, void *out); #endif diff --git a/src/ed25519/sign.c b/src/ed25519/sign.c index 199a839..0c4eea9 100644 --- a/src/ed25519/sign.c +++ b/src/ed25519/sign.c @@ -5,27 +5,27 @@ void ed25519_sign(unsigned char *signature, const unsigned char *message, size_t message_len, const unsigned char *public_key, const unsigned char *private_key) { - sha512_context hash; - unsigned char hram[64]; - unsigned char r[64]; - ge_p3 R; + sha512_context hash; + unsigned char hram[64]; + unsigned char r[64]; + ge_p3 R; - sha512_init(&hash); - sha512_update(&hash, private_key + 32, 32); - sha512_update(&hash, message, message_len); - sha512_final(&hash, r); + sha512_init(&hash); + sha512_update(&hash, private_key + 32, 32); + sha512_update(&hash, message, message_len); + sha512_final(&hash, r); - sc_reduce(r); - ge_scalarmult_base(&R, r); - ge_p3_tobytes(signature, &R); + sc_reduce(r); + ge_scalarmult_base(&R, r); + ge_p3_tobytes(signature, &R); - sha512_init(&hash); - sha512_update(&hash, signature, 32); - sha512_update(&hash, public_key, 32); - sha512_update(&hash, message, message_len); - sha512_final(&hash, hram); + sha512_init(&hash); + sha512_update(&hash, signature, 32); + sha512_update(&hash, public_key, 32); + sha512_update(&hash, message, message_len); + sha512_final(&hash, hram); - sc_reduce(hram); - sc_muladd(signature + 32, hram, private_key, r); + sc_reduce(hram); + sc_muladd(signature + 32, hram, private_key, r); } diff --git a/src/ed25519/verify.c b/src/ed25519/verify.c index 32f988e..415e94f 100644 --- a/src/ed25519/verify.c +++ b/src/ed25519/verify.c @@ -4,74 +4,74 @@ #include "sc.h" static int consttime_equal(const unsigned char *x, const unsigned char *y) { - unsigned char r = 0; + unsigned char r = 0; - r = x[0] ^ y[0]; - #define F(i) r |= x[i] ^ y[i] - F(1); - F(2); - F(3); - F(4); - F(5); - F(6); - F(7); - F(8); - F(9); - F(10); - F(11); - F(12); - F(13); - F(14); - F(15); - F(16); - F(17); - F(18); - F(19); - F(20); - F(21); - F(22); - F(23); - F(24); - F(25); - F(26); - F(27); - F(28); - F(29); - F(30); - F(31); - #undef F + r = x[0] ^ y[0]; +#define F(i) r |= x[i] ^ y[i] + F(1); + F(2); + F(3); + F(4); + F(5); + F(6); + F(7); + F(8); + F(9); + F(10); + F(11); + F(12); + F(13); + F(14); + F(15); + F(16); + F(17); + F(18); + F(19); + F(20); + F(21); + F(22); + F(23); + F(24); + F(25); + F(26); + F(27); + F(28); + F(29); + F(30); + F(31); +#undef F - return !r; + return !r; } int ed25519_verify(const unsigned char *signature, const unsigned char *message, size_t message_len, const unsigned char *public_key) { - unsigned char h[64]; - unsigned char checker[32]; - sha512_context hash; - ge_p3 A; - ge_p2 R; + unsigned char h[64]; + unsigned char checker[32]; + sha512_context hash; + ge_p3 A; + ge_p2 R; - if (signature[63] & 224) { - return 0; - } + if(signature[63] & 224) { + return 0; + } - if (ge_frombytes_negate_vartime(&A, public_key) != 0) { - return 0; - } + if(ge_frombytes_negate_vartime(&A, public_key) != 0) { + return 0; + } - sha512_init(&hash); - sha512_update(&hash, signature, 32); - sha512_update(&hash, public_key, 32); - sha512_update(&hash, message, message_len); - sha512_final(&hash, h); - - sc_reduce(h); - ge_double_scalarmult_vartime(&R, h, &A, signature + 32); - ge_tobytes(checker, &R); + sha512_init(&hash); + sha512_update(&hash, signature, 32); + sha512_update(&hash, public_key, 32); + sha512_update(&hash, message, message_len); + sha512_final(&hash, h); - if (!consttime_equal(checker, signature)) { - return 0; - } + sc_reduce(h); + ge_double_scalarmult_vartime(&R, h, &A, signature + 32); + ge_tobytes(checker, &R); - return 1; + if(!consttime_equal(checker, signature)) { + return 0; + } + + return 1; } diff --git a/src/edge.c b/src/edge.c index 0e35cd1..5491d8a 100644 --- a/src/edge.c +++ b/src/edge.c @@ -40,13 +40,15 @@ static int edge_weight_compare(const edge_t *a, const edge_t *b) { result = a->weight - b->weight; - if(result) + if(result) { return result; + } result = strcmp(a->from->name, b->from->name); - if(result) + if(result) { return result; + } return strcmp(a->to->name, b->to->name); } @@ -86,13 +88,15 @@ void edge_add(edge_t *e) { e->reverse = lookup_edge(e->to, e->from); - if(e->reverse) + if(e->reverse) { e->reverse->reverse = e; + } } void edge_del(edge_t *e) { - if(e->reverse) + if(e->reverse) { e->reverse->reverse = NULL; + } splay_delete(edge_weight_tree, e); splay_delete(e->from->edge_tree, e); @@ -111,11 +115,11 @@ bool dump_edges(connection_t *c) { for splay_each(node_t, n, node_tree) { for splay_each(edge_t, e, n->edge_tree) { char *address = sockaddr2hostname(&e->address); - char* local_address = sockaddr2hostname(&e->local_address); + char *local_address = sockaddr2hostname(&e->local_address); send_request(c, "%d %d %s %s %s %s %x %d", - CONTROL, REQ_DUMP_EDGES, - e->from->name, e->to->name, address, - local_address, e->options, e->weight); + CONTROL, REQ_DUMP_EDGES, + e->from->name, e->to->name, address, + local_address, e->options, e->weight); free(address); free(local_address); } diff --git a/src/edge.h b/src/edge.h index ed46b8a..032acbc 100644 --- a/src/edge.h +++ b/src/edge.h @@ -1,3 +1,6 @@ +#ifndef TINC_EDGE_H +#define TINC_EDGE_H + /* edge.h -- header for edge.c Copyright (C) 2001-2012 Guus Sliepen , @@ -18,9 +21,6 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#ifndef __TINC_EDGE_H__ -#define __TINC_EDGE_H__ - #include "splay_tree.h" #include "connection.h" #include "net.h" @@ -43,13 +43,13 @@ extern splay_tree_t *edge_weight_tree; /* Tree with all known edges sor extern void init_edges(void); extern void exit_edges(void); -extern edge_t *new_edge(void) __attribute__ ((__malloc__)); -extern void free_edge(edge_t *); -extern splay_tree_t *new_edge_tree(void) __attribute__ ((__malloc__)); -extern void free_edge_tree(splay_tree_t *); -extern void edge_add(edge_t *); -extern void edge_del(edge_t *); -extern edge_t *lookup_edge(struct node_t *, struct node_t *); -extern bool dump_edges(struct connection_t *); +extern edge_t *new_edge(void) __attribute__((__malloc__)); +extern void free_edge(edge_t *e); +extern splay_tree_t *new_edge_tree(void) __attribute__((__malloc__)); +extern void free_edge_tree(splay_tree_t *edge_tree); +extern void edge_add(edge_t *e); +extern void edge_del(edge_t *e); +extern edge_t *lookup_edge(struct node_t *from, struct node_t *to); +extern bool dump_edges(struct connection_t *c); -#endif /* __TINC_EDGE_H__ */ +#endif diff --git a/src/ethernet.h b/src/ethernet.h index 0b4a1db..8bfbd71 100644 --- a/src/ethernet.h +++ b/src/ethernet.h @@ -1,3 +1,6 @@ +#ifndef TINC_ETHERNET_H +#define TINC_ETHERNET_H + /* ethernet.h -- missing Ethernet related definitions Copyright (C) 2005 Ivo Timmermans @@ -18,9 +21,6 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#ifndef __TINC_ETHERNET_H__ -#define __TINC_ETHERNET_H__ - #ifndef ETH_ALEN #define ETH_ALEN 6 #endif @@ -63,7 +63,7 @@ struct ether_header { uint8_t ether_dhost[ETH_ALEN]; uint8_t ether_shost[ETH_ALEN]; uint16_t ether_type; -} __attribute__ ((__gcc_struct__, __packed__)); +} __attribute__((__gcc_struct__, __packed__)); #endif #ifndef HAVE_STRUCT_ARPHDR @@ -73,7 +73,7 @@ struct arphdr { uint8_t ar_hln; uint8_t ar_pln; uint16_t ar_op; -} __attribute__ ((__gcc_struct__, __packed__)); +} __attribute__((__gcc_struct__, __packed__)); #define ARPOP_REQUEST 1 #define ARPOP_REPLY 2 @@ -91,7 +91,7 @@ struct ether_arp { uint8_t arp_spa[4]; uint8_t arp_tha[ETH_ALEN]; uint8_t arp_tpa[4]; -} __attribute__ ((__gcc_struct__, __packed__)); +} __attribute__((__gcc_struct__, __packed__)); #define arp_hrd ea_hdr.ar_hrd #define arp_pro ea_hdr.ar_pro #define arp_hln ea_hdr.ar_hln @@ -99,4 +99,4 @@ struct ether_arp { #define arp_op ea_hdr.ar_op #endif -#endif /* __TINC_ETHERNET_H__ */ +#endif diff --git a/src/event.c b/src/event.c index 858e1d9..47adb18 100644 --- a/src/event.c +++ b/src/event.c @@ -41,25 +41,47 @@ static int io_compare(const io_t *a, const io_t *b) { #ifndef HAVE_MINGW return a->fd - b->fd; #else - return a->event - b->event; + + if(a->event < b->event) { + return -1; + } + + if(a->event > b->event) { + return 1; + } + + return 0; #endif } static int timeout_compare(const timeout_t *a, const timeout_t *b) { struct timeval diff; timersub(&a->tv, &b->tv, &diff); - if(diff.tv_sec < 0) + + if(diff.tv_sec < 0) { return -1; - if(diff.tv_sec > 0) + } + + if(diff.tv_sec > 0) { return 1; - if(diff.tv_usec < 0) + } + + if(diff.tv_usec < 0) { return -1; - if(diff.tv_usec > 0) + } + + if(diff.tv_usec > 0) { return 1; - if(a < b) + } + + if(a < b) { return -1; - if(a > b) + } + + if(a > b) { return 1; + } + return 0; } @@ -67,16 +89,21 @@ static splay_tree_t io_tree = {.compare = (splay_compare_t)io_compare}; static splay_tree_t timeout_tree = {.compare = (splay_compare_t)timeout_compare}; void io_add(io_t *io, io_cb_t cb, void *data, int fd, int flags) { - if(io->cb) + if(io->cb) { return; + } io->fd = fd; #ifdef HAVE_MINGW - if (io->fd != -1) { + + if(io->fd != -1) { io->event = WSACreateEvent(); - if (io->event == WSA_INVALID_EVENT) + + if(io->event == WSA_INVALID_EVENT) { abort(); + } } + event_count++; #endif io->cb = cb; @@ -85,8 +112,9 @@ void io_add(io_t *io, io_cb_t cb, void *data, int fd, int flags) { io_set(io, flags); - if(!splay_insert_node(&io_tree, &io->node)) + if(!splay_insert_node(&io_tree, &io->node)) { abort(); + } } #ifdef HAVE_MINGW @@ -97,41 +125,60 @@ void io_add_event(io_t *io, io_cb_t cb, void *data, WSAEVENT event) { #endif void io_set(io_t *io, int flags) { - if (flags == io->flags) + if(flags == io->flags) { return; + } + io->flags = flags; - if (io->fd == -1) + + if(io->fd == -1) { return; + } #ifndef HAVE_MINGW - if(flags & IO_READ) - FD_SET(io->fd, &readfds); - else - FD_CLR(io->fd, &readfds); - if(flags & IO_WRITE) + if(flags & IO_READ) { + FD_SET(io->fd, &readfds); + } else { + FD_CLR(io->fd, &readfds); + } + + if(flags & IO_WRITE) { FD_SET(io->fd, &writefds); - else + } else { FD_CLR(io->fd, &writefds); + } + #else long events = 0; - if (flags & IO_WRITE) + + if(flags & IO_WRITE) { events |= WRITE_EVENTS; - if (flags & IO_READ) + } + + if(flags & IO_READ) { events |= READ_EVENTS; - if (WSAEventSelect(io->fd, io->event, events) != 0) + } + + if(WSAEventSelect(io->fd, io->event, events) != 0) { abort(); + } + #endif } void io_del(io_t *io) { - if(!io->cb) + if(!io->cb) { return; + } io_set(io, 0); #ifdef HAVE_MINGW - if (io->fd != -1 && WSACloseEvent(io->event) == FALSE) + + if(io->fd != -1 && WSACloseEvent(io->event) == FALSE) { abort(); + } + event_count--; #endif @@ -148,25 +195,31 @@ void timeout_add(timeout_t *timeout, timeout_cb_t cb, void *data, struct timeval } void timeout_set(timeout_t *timeout, struct timeval *tv) { - if(timerisset(&timeout->tv)) + if(timerisset(&timeout->tv)) { splay_unlink_node(&timeout_tree, &timeout->node); + } - if(!now.tv_sec) + if(!now.tv_sec) { gettimeofday(&now, NULL); + } timeradd(&now, tv, &timeout->tv); - if(!splay_insert_node(&timeout_tree, &timeout->node)) + if(!splay_insert_node(&timeout_tree, &timeout->node)) { abort(); + } } void timeout_del(timeout_t *timeout) { - if(!timeout->cb) + if(!timeout->cb) { return; + } splay_unlink_node(&timeout_tree, &timeout->node); timeout->cb = 0; - timeout->tv = (struct timeval){0, 0}; + timeout->tv = (struct timeval) { + 0, 0 + }; } #ifndef HAVE_MINGW @@ -184,41 +237,54 @@ static void signal_handler(int signum) { } static void signalio_handler(void *data, int flags) { + (void)data; + (void)flags; unsigned char signum; - if(read(pipefd[0], &signum, 1) != 1) - return; - signal_t *sig = splay_search(&signal_tree, &((signal_t){.signum = signum})); - if(sig) + if(read(pipefd[0], &signum, 1) != 1) { + return; + } + + signal_t *sig = splay_search(&signal_tree, &((signal_t) { + .signum = signum + })); + + if(sig) { sig->cb(sig->data); + } } static void pipe_init(void) { - if(!pipe(pipefd)) + if(!pipe(pipefd)) { io_add(&signalio, signalio_handler, NULL, pipefd[0], IO_READ); + } } void signal_add(signal_t *sig, signal_cb_t cb, void *data, int signum) { - if(sig->cb) + if(sig->cb) { return; + } sig->cb = cb; sig->data = data; sig->signum = signum; sig->node.data = sig; - if(pipefd[0] == -1) + if(pipefd[0] == -1) { pipe_init(); + } signal(sig->signum, signal_handler); - if(!splay_insert_node(&signal_tree, &sig->node)) + if(!splay_insert_node(&signal_tree, &sig->node)) { abort(); + } } void signal_del(signal_t *sig) { - if(!sig->cb) + if(!sig->cb) { return; + } signal(sig->signum, SIG_DFL); @@ -227,7 +293,7 @@ void signal_del(signal_t *sig) { } #endif -static struct timeval * get_time_remaining(struct timeval *diff) { +static struct timeval *get_time_remaining(struct timeval *diff) { gettimeofday(&now, NULL); struct timeval *tv = NULL; @@ -237,8 +303,10 @@ static struct timeval * get_time_remaining(struct timeval *diff) { if(diff->tv_sec < 0) { timeout->cb(timeout->data); - if(timercmp(&timeout->tv, &now, <)) + + if(timercmp(&timeout->tv, &now, <)) { timeout_del(timeout); + } } else { tv = diff; break; @@ -258,8 +326,8 @@ bool event_loop(void) { while(running) { struct timeval diff; struct timeval *tv = get_time_remaining(&diff); - memcpy(&readable, &readfds, sizeof readable); - memcpy(&writable, &writefds, sizeof writable); + memcpy(&readable, &readfds, sizeof(readable)); + memcpy(&writable, &writefds, sizeof(writable)); int fds = 0; @@ -271,39 +339,48 @@ bool event_loop(void) { int n = select(fds, &readable, &writable, NULL, tv); if(n < 0) { - if(sockwouldblock(sockerrno)) + if(sockwouldblock(sockerrno)) { continue; - else + } else { return false; + } } - if(!n) + if(!n) { continue; + } + + unsigned int curgen = io_tree.generation; for splay_each(io_t, io, &io_tree) { - if(FD_ISSET(io->fd, &writable)) + if(FD_ISSET(io->fd, &writable)) { io->cb(io->data, IO_WRITE); - else if(FD_ISSET(io->fd, &readable)) + } else if(FD_ISSET(io->fd, &readable)) { io->cb(io->data, IO_READ); - else + } else { continue; + } /* There are scenarios in which the callback will remove another io_t from the tree (e.g. closing a double connection). Since splay_each does not support that, we - need to exit the loop now. That's okay, since any remaining events will get picked - up by the next select() call. + need to exit the loop if that happens. That's okay, since any remaining events will + get picked up by the next select() call. */ - break; + if(curgen != io_tree.generation) { + break; + } } } + #else - while (running) { + + while(running) { struct timeval diff; struct timeval *tv = get_time_remaining(&diff); DWORD timeout_ms = tv ? (tv->tv_sec * 1000 + tv->tv_usec / 1000 + 1) : WSA_INFINITE; - if (!event_count) { + if(!event_count) { Sleep(timeout_ms); continue; } @@ -318,54 +395,90 @@ bool event_loop(void) { Note that technically FD_CLOSE has the same problem, but it's okay because user code does not rely on this event being fired again if ignored. */ - io_t* writeable_io = NULL; - for splay_each(io_t, io, &io_tree) - if (io->flags & IO_WRITE && send(io->fd, NULL, 0, 0) == 0) { - writeable_io = io; - break; + unsigned int curgen = io_tree.generation; + + for splay_each(io_t, io, &io_tree) { + if(io->flags & IO_WRITE && send(io->fd, NULL, 0, 0) == 0) { + io->cb(io->data, IO_WRITE); + + if(curgen != io_tree.generation) { + break; + } } - if (writeable_io) { - writeable_io->cb(writeable_io->data, IO_WRITE); - continue; } - WSAEVENT* events = xmalloc(event_count * sizeof(*events)); + if(event_count > WSA_MAXIMUM_WAIT_EVENTS) { + WSASetLastError(WSA_INVALID_PARAMETER); + return(false); + } + + WSAEVENT events[WSA_MAXIMUM_WAIT_EVENTS]; + io_t *io_map[WSA_MAXIMUM_WAIT_EVENTS]; DWORD event_index = 0; + for splay_each(io_t, io, &io_tree) { events[event_index] = io->event; + io_map[event_index] = io; event_index++; } - DWORD result = WSAWaitForMultipleEvents(event_count, events, FALSE, timeout_ms, FALSE); + /* + * If the generation number changes due to event addition + * or removal by a callback we restart the loop. + */ + curgen = io_tree.generation; - WSAEVENT event; - if (result >= WSA_WAIT_EVENT_0 && result < WSA_WAIT_EVENT_0 + event_count) - event = events[result - WSA_WAIT_EVENT_0]; - free(events); - if (result == WSA_WAIT_TIMEOUT) - continue; - if (result < WSA_WAIT_EVENT_0 || result >= WSA_WAIT_EVENT_0 + event_count) - return false; + for(DWORD event_offset = 0; event_offset < event_count;) { + DWORD result = WSAWaitForMultipleEvents(event_count - event_offset, &events[event_offset], FALSE, timeout_ms, FALSE); - io_t *io = splay_search(&io_tree, &((io_t){.event = event})); - if (!io) - abort(); + if(result == WSA_WAIT_TIMEOUT) { + break; + } - if (io->fd == -1) { - io->cb(io->data, 0); - } else { - WSANETWORKEVENTS network_events; - if (WSAEnumNetworkEvents(io->fd, io->event, &network_events) != 0) - return false; - if (network_events.lNetworkEvents & READ_EVENTS) - io->cb(io->data, IO_READ); - /* - The fd might be available for write too. However, if we already fired the read callback, that - callback might have deleted the io (e.g. through terminate_connection()), so we can't fire the - write callback here. Instead, we loop back and let the writable io loop above handle it. - */ + if(result < WSA_WAIT_EVENT_0 || result >= WSA_WAIT_EVENT_0 + event_count - event_offset) { + return(false); + } + + /* Look up io in the map by index. */ + event_index = result - WSA_WAIT_EVENT_0 + event_offset; + io_t *io = io_map[event_index]; + + if(io->fd == -1) { + io->cb(io->data, 0); + + if(curgen != io_tree.generation) { + break; + } + } else { + WSANETWORKEVENTS network_events; + + if(WSAEnumNetworkEvents(io->fd, io->event, &network_events) != 0) { + return(false); + } + + if(network_events.lNetworkEvents & READ_EVENTS) { + io->cb(io->data, IO_READ); + + if(curgen != io_tree.generation) { + break; + } + } + + /* + The fd might be available for write too. However, if we already fired the read callback, that + callback might have deleted the io (e.g. through terminate_connection()), so we can't fire the + write callback here. Instead, we loop back and let the writable io loop above handle it. + */ + } + + /* Continue checking the rest of the events. */ + event_offset = event_index + 1; + + /* Just poll the next time through. */ + timeout_ms = 0; } } + #endif return true; diff --git a/src/event.h b/src/event.h index 0ff8e01..7adaf85 100644 --- a/src/event.h +++ b/src/event.h @@ -1,3 +1,6 @@ +#ifndef TINC_EVENT_H +#define TINC_EVENT_H + /* event.h -- I/O, timeout and signal event handling Copyright (C) 2012-2013 Guus Sliepen @@ -17,9 +20,6 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#ifndef __TINC_EVENT_H__ -#define __TINC_EVENT_H__ - #include "splay_tree.h" #define IO_READ 1 @@ -58,7 +58,7 @@ extern struct timeval now; extern void io_add(io_t *io, io_cb_t cb, void *data, int fd, int flags); #ifdef HAVE_MINGW -extern void io_add_event(io_t *io, io_cb_t cb, void* data, WSAEVENT event); +extern void io_add_event(io_t *io, io_cb_t cb, void *data, WSAEVENT event); #endif extern void io_del(io_t *io); extern void io_set(io_t *io, int flags); diff --git a/src/fd_device.c b/src/fd_device.c index 67e0cb7..afe59bc 100644 --- a/src/fd_device.c +++ b/src/fd_device.c @@ -64,7 +64,7 @@ static void close_device(void) { } static inline uint16_t get_ip_ethertype(vpn_packet_t *packet) { - switch (DATA(packet)[ETH_HLEN] >> 4) { + switch(DATA(packet)[ETH_HLEN] >> 4) { case 4: return ETH_P_IP; @@ -85,12 +85,14 @@ static inline void set_etherheader(vpn_packet_t *packet, uint16_t ethertype) { static bool read_packet(vpn_packet_t *packet) { int lenin = read(device_fd, DATA(packet) + ETH_HLEN, MTU - ETH_HLEN); + if(lenin <= 0) { logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from fd/%d: %s!", device_fd, strerror(errno)); return false; } uint16_t ethertype = get_ip_ethertype(packet); + if(ethertype == ETH_P_MAX) { logger(DEBUG_TRAFFIC, LOG_ERR, "Unknown IP version while reading packet from fd/%d!", device_fd); return false; diff --git a/src/fsck.c b/src/fsck.c index e5e7dd5..e19f03f 100644 --- a/src/fsck.c +++ b/src/fsck.c @@ -32,31 +32,43 @@ #include "utils.h" static bool ask_fix(void) { - if(force) + if(force) { return true; - if(!tty) + } + + if(!tty) { return false; + } + again: fprintf(stderr, "Fix y/n? "); char buf[1024]; - if(!fgets(buf, sizeof buf, stdin)) { + + if(!fgets(buf, sizeof(buf), stdin)) { tty = false; return false; } - if(buf[0] == 'y' || buf[0] == 'Y') + + if(buf[0] == 'y' || buf[0] == 'Y') { return true; - if(buf[0] == 'n' || buf[0] == 'N') + } + + if(buf[0] == 'n' || buf[0] == 'N') { return false; + } + goto again; } static void print_tinc_cmd(const char *argv0, const char *format, ...) { - if(confbasegiven) + if(confbasegiven) { fprintf(stderr, "%s -c %s ", argv0, confbase); - else if(netname) + } else if(netname) { fprintf(stderr, "%s -n %s ", argv0, netname); - else + } else { fprintf(stderr, "%s ", argv0); + } + va_list va; va_start(va, format); vfprintf(stderr, format, va); @@ -67,13 +79,19 @@ static void print_tinc_cmd(const char *argv0, const char *format, ...) { static int strtailcmp(const char *str, const char *tail) { size_t slen = strlen(str); size_t tlen = strlen(tail); - if(tlen > slen) + + if(tlen > slen) { return -1; + } + return memcmp(str + slen - tlen, tail, tlen); } static void check_conffile(const char *fname, bool server) { + (void)server; + FILE *f = fopen(fname, "r"); + if(!f) { fprintf(stderr, "ERROR: cannot read %s: %s\n", fname, strerror(errno)); return; @@ -84,12 +102,14 @@ static void check_conffile(const char *fname, bool server) { bool skip = false; const int maxvariables = 50; int count[maxvariables]; - memset(count, 0, sizeof count); + memset(count, 0, sizeof(count)); - while(fgets(line, sizeof line, f)) { + while(fgets(line, sizeof(line), f)) { if(skip) { - if(!strncmp(line, "-----END", 8)) + if(!strncmp(line, "-----END", 8)) { skip = false; + } + continue; } else { if(!strncmp(line, "-----BEGIN", 10)) { @@ -105,26 +125,32 @@ static void check_conffile(const char *fname, bool server) { lineno++; eol = line + strlen(line); - while(strchr("\t \r\n", *--eol)) - *eol = '\0'; - if(!line[0] || line[0] == '#') + while(strchr("\t \r\n", *--eol)) { + *eol = '\0'; + } + + if(!line[0] || line[0] == '#') { continue; + } len = strcspn(value, "\t ="); value += len; value += strspn(value, "\t "); + if(*value == '=') { value++; value += strspn(value, "\t "); } + variable[len] = '\0'; bool found = false; for(int i = 0; variables[i].name; i++) { - if(strcasecmp(variables[i].name, variable)) + if(strcasecmp(variables[i].name, variable)) { continue; + } found = true; @@ -132,24 +158,29 @@ static void check_conffile(const char *fname, bool server) { fprintf(stderr, "WARNING: obsolete variable %s in %s line %d\n", variable, fname, lineno); } - if(i < maxvariables) + if(i < maxvariables) { count[i]++; + } } - if(!found) + if(!found) { fprintf(stderr, "WARNING: unknown variable %s in %s line %d\n", variable, fname, lineno); + } - if(!*value) + if(!*value) { fprintf(stderr, "ERROR: no value for variable %s in %s line %d\n", variable, fname, lineno); + } } for(int i = 0; variables[i].name && i < maxvariables; i++) { - if(count[i] > 1 && !(variables[i].type & VAR_MULTIPLE)) + if(count[i] > 1 && !(variables[i].type & VAR_MULTIPLE)) { fprintf(stderr, "WARNING: multiple instances of variable %s in %s\n", variables[i].name, fname); + } } - if(ferror(f)) + if(ferror(f)) { fprintf(stderr, "ERROR: while reading %s: %s\n", fname, strerror(errno)); + } fclose(f); } @@ -165,19 +196,23 @@ int fsck(const char *argv0) { if(access(tinc_conf, R_OK)) { fprintf(stderr, "ERROR: cannot read %s: %s\n", tinc_conf, strerror(errno)); + if(errno == ENOENT) { fprintf(stderr, "No tinc configuration found. Create a new one with:\n\n"); print_tinc_cmd(argv0, "init"); } else if(errno == EACCES) { - if(uid != 0) + if(uid != 0) { fprintf(stderr, "You are currently not running tinc as root. Use sudo?\n"); - else + } else { fprintf(stderr, "Check the permissions of each component of the path %s.\n", tinc_conf); + } } + return 1; } char *name = get_my_name(true); + if(!name) { fprintf(stderr, "ERROR: tinc cannot run without a valid Name.\n"); return 1; @@ -192,7 +227,7 @@ int fsck(const char *argv0) { #ifndef DISABLE_LEGACY rsa_t *rsa_priv = NULL; - snprintf(fname, sizeof fname, "%s/rsa_key.priv", confbase); + snprintf(fname, sizeof(fname), "%s/rsa_key.priv", confbase); if(stat(fname, &st)) { if(errno != ENOENT) { @@ -203,12 +238,15 @@ int fsck(const char *argv0) { } } else { FILE *f = fopen(fname, "r"); + if(!f) { fprintf(stderr, "ERROR: could not open %s: %s\n", fname, strerror(errno)); return 1; } + rsa_priv = rsa_read_pem_private_key(f); fclose(f); + if(!rsa_priv) { fprintf(stderr, "ERROR: No key or unusable key found in %s.\n", fname); fprintf(stderr, "You can generate a new RSA key with:\n\n"); @@ -217,23 +255,28 @@ int fsck(const char *argv0) { } #if !defined(HAVE_MINGW) && !defined(HAVE_CYGWIN) + if(st.st_mode & 077) { fprintf(stderr, "WARNING: unsafe file permissions on %s.\n", fname); + if(st.st_uid != uid) { fprintf(stderr, "You are not running %s as the same uid as %s.\n", argv0, fname); } else if(ask_fix()) { - if(chmod(fname, st.st_mode & ~077)) + if(chmod(fname, st.st_mode & ~077)) { fprintf(stderr, "ERROR: could not change permissions of %s: %s\n", fname, strerror(errno)); - else + } else { fprintf(stderr, "Fixed permissions of %s.\n", fname); + } } } + #endif } + #endif ecdsa_t *ecdsa_priv = NULL; - snprintf(fname, sizeof fname, "%s/ed25519_key.priv", confbase); + snprintf(fname, sizeof(fname), "%s/ed25519_key.priv", confbase); if(stat(fname, &st)) { if(errno != ENOENT) { @@ -244,12 +287,15 @@ int fsck(const char *argv0) { } } else { FILE *f = fopen(fname, "r"); + if(!f) { fprintf(stderr, "ERROR: could not open %s: %s\n", fname, strerror(errno)); return 1; } + ecdsa_priv = ecdsa_read_pem_private_key(f); fclose(f); + if(!ecdsa_priv) { fprintf(stderr, "ERROR: No key or unusable key found in %s.\n", fname); fprintf(stderr, "You can generate a new Ed25519 key with:\n\n"); @@ -258,24 +304,30 @@ int fsck(const char *argv0) { } #if !defined(HAVE_MINGW) && !defined(HAVE_CYGWIN) + if(st.st_mode & 077) { fprintf(stderr, "WARNING: unsafe file permissions on %s.\n", fname); + if(st.st_uid != uid) { fprintf(stderr, "You are not running %s as the same uid as %s.\n", argv0, fname); } else if(ask_fix()) { - if(chmod(fname, st.st_mode & ~077)) + if(chmod(fname, st.st_mode & ~077)) { fprintf(stderr, "ERROR: could not change permissions of %s: %s\n", fname, strerror(errno)); - else + } else { fprintf(stderr, "Fixed permissions of %s.\n", fname); + } } } + #endif } #ifdef DISABLE_LEGACY + if(!ecdsa_priv) { fprintf(stderr, "ERROR: No Ed25519 private key found.\n"); #else + if(!rsa_priv && !ecdsa_priv) { fprintf(stderr, "ERROR: Neither RSA or Ed25519 private key found.\n"); #endif @@ -287,9 +339,11 @@ int fsck(const char *argv0) { // Check for public keys. // TODO: use RSAPublicKeyFile variable if present. - snprintf(fname, sizeof fname, "%s/hosts/%s", confbase, name); - if(access(fname, R_OK)) + snprintf(fname, sizeof(fname), "%s/hosts/%s", confbase, name); + + if(access(fname, R_OK)) { fprintf(stderr, "WARNING: cannot read %s\n", fname); + } FILE *f; @@ -297,6 +351,7 @@ int fsck(const char *argv0) { rsa_t *rsa_pub = NULL; f = fopen(fname, "r"); + if(f) { rsa_pub = rsa_read_pem_public_key(f); fclose(f); @@ -305,13 +360,17 @@ int fsck(const char *argv0) { if(rsa_priv) { if(!rsa_pub) { fprintf(stderr, "WARNING: No (usable) public RSA key found.\n"); + if(ask_fix()) { FILE *f = fopen(fname, "a"); + if(f) { - if(rsa_write_pem_public_key(rsa_priv, f)) + if(rsa_write_pem_public_key(rsa_priv, f)) { fprintf(stderr, "Wrote RSA public key to %s.\n", fname); - else + } else { fprintf(stderr, "ERROR: could not write RSA public key to %s.\n", fname); + } + fclose(f); } else { fprintf(stderr, "ERROR: could not append to %s: %s\n", fname, strerror(errno)); @@ -320,56 +379,70 @@ int fsck(const char *argv0) { } else { // TODO: suggest remedies size_t len = rsa_size(rsa_priv); + if(len != rsa_size(rsa_pub)) { fprintf(stderr, "ERROR: public and private RSA keys do not match.\n"); return 1; } + char buf1[len], buf2[len], buf3[len]; - randomize(buf1, sizeof buf1); + randomize(buf1, sizeof(buf1)); buf1[0] &= 0x7f; - memset(buf2, 0, sizeof buf2); - memset(buf3, 0, sizeof buf2); - if(!rsa_public_encrypt(rsa_pub, buf1, sizeof buf1, buf2)) { + memset(buf2, 0, sizeof(buf2)); + memset(buf3, 0, sizeof(buf2)); + + if(!rsa_public_encrypt(rsa_pub, buf1, sizeof(buf1), buf2)) { fprintf(stderr, "ERROR: public RSA key does not work.\n"); return 1; } - if(!rsa_private_decrypt(rsa_priv, buf2, sizeof buf2, buf3)) { + + if(!rsa_private_decrypt(rsa_priv, buf2, sizeof(buf2), buf3)) { fprintf(stderr, "ERROR: private RSA key does not work.\n"); return 1; } - if(memcmp(buf1, buf3, sizeof buf1)) { + + if(memcmp(buf1, buf3, sizeof(buf1))) { fprintf(stderr, "ERROR: public and private RSA keys do not match.\n"); return 1; } } } else { - if(rsa_pub) + if(rsa_pub) { fprintf(stderr, "WARNING: A public RSA key was found but no private key is known.\n"); + } } + #endif ecdsa_t *ecdsa_pub = NULL; f = fopen(fname, "r"); + if(f) { ecdsa_pub = get_pubkey(f); + if(!ecdsa_pub) { rewind(f); ecdsa_pub = ecdsa_read_pem_public_key(f); } + fclose(f); } if(ecdsa_priv) { if(!ecdsa_pub) { fprintf(stderr, "WARNING: No (usable) public Ed25519 key found.\n"); + if(ask_fix()) { FILE *f = fopen(fname, "a"); + if(f) { - if(ecdsa_write_pem_public_key(ecdsa_priv, f)) + if(ecdsa_write_pem_public_key(ecdsa_priv, f)) { fprintf(stderr, "Wrote Ed25519 public key to %s.\n", fname); - else + } else { fprintf(stderr, "ERROR: could not write Ed25519 public key to %s.\n", fname); + } + fclose(f); } else { fprintf(stderr, "ERROR: could not append to %s: %s\n", fname, strerror(errno)); @@ -378,119 +451,150 @@ int fsck(const char *argv0) { } else { // TODO: suggest remedies char *key1 = ecdsa_get_base64_public_key(ecdsa_pub); + if(!key1) { fprintf(stderr, "ERROR: public Ed25519 key does not work.\n"); return 1; } + char *key2 = ecdsa_get_base64_public_key(ecdsa_priv); + if(!key2) { free(key1); fprintf(stderr, "ERROR: private Ed25519 key does not work.\n"); return 1; } + int result = strcmp(key1, key2); free(key1); free(key2); + if(result) { fprintf(stderr, "ERROR: public and private Ed25519 keys do not match.\n"); return 1; } } } else { - if(ecdsa_pub) + if(ecdsa_pub) { fprintf(stderr, "WARNING: A public Ed25519 key was found but no private key is known.\n"); + } } // Check whether scripts are executable struct dirent *ent; DIR *dir = opendir(confbase); + if(!dir) { fprintf(stderr, "ERROR: cannot read directory %s: %s\n", confbase, strerror(errno)); return 1; } while((ent = readdir(dir))) { - if(strtailcmp(ent->d_name, "-up") && strtailcmp(ent->d_name, "-down")) + if(strtailcmp(ent->d_name, "-up") && strtailcmp(ent->d_name, "-down")) { continue; + } - strncpy(fname, ent->d_name, sizeof fname); + strncpy(fname, ent->d_name, sizeof(fname)); char *dash = strrchr(fname, '-'); - if(!dash) + + if(!dash) { continue; + } + *dash = 0; if(strcmp(fname, "tinc") && strcmp(fname, "host") && strcmp(fname, "subnet")) { static bool explained = false; fprintf(stderr, "WARNING: Unknown script %s" SLASH "%s found.\n", confbase, ent->d_name); + if(!explained) { fprintf(stderr, "The only scripts in %s executed by tinc are:\n", confbase); fprintf(stderr, "tinc-up, tinc-down, host-up, host-down, subnet-up and subnet-down.\n"); explained = true; } + continue; } - snprintf(fname, sizeof fname, "%s" SLASH "%s", confbase, ent->d_name); + snprintf(fname, sizeof(fname), "%s" SLASH "%s", confbase, ent->d_name); + if(access(fname, R_OK | X_OK)) { if(errno != EACCES) { fprintf(stderr, "ERROR: cannot access %s: %s\n", fname, strerror(errno)); continue; } + fprintf(stderr, "WARNING: cannot read and execute %s: %s\n", fname, strerror(errno)); + if(ask_fix()) { - if(chmod(fname, 0755)) + if(chmod(fname, 0755)) { fprintf(stderr, "ERROR: cannot change permissions on %s: %s\n", fname, strerror(errno)); + } } } } + closedir(dir); - snprintf(dname, sizeof dname, "%s" SLASH "hosts", confbase); + snprintf(dname, sizeof(dname), "%s" SLASH "hosts", confbase); dir = opendir(dname); + if(!dir) { fprintf(stderr, "ERROR: cannot read directory %s: %s\n", dname, strerror(errno)); return 1; } while((ent = readdir(dir))) { - if(strtailcmp(ent->d_name, "-up") && strtailcmp(ent->d_name, "-down")) + if(strtailcmp(ent->d_name, "-up") && strtailcmp(ent->d_name, "-down")) { continue; + } - strncpy(fname, ent->d_name, sizeof fname); + strncpy(fname, ent->d_name, sizeof(fname)); char *dash = strrchr(fname, '-'); - if(!dash) + + if(!dash) { continue; + } + *dash = 0; - snprintf(fname, sizeof fname, "%s" SLASH "hosts" SLASH "%s", confbase, ent->d_name); + snprintf(fname, sizeof(fname), "%s" SLASH "hosts" SLASH "%s", confbase, ent->d_name); + if(access(fname, R_OK | X_OK)) { if(errno != EACCES) { fprintf(stderr, "ERROR: cannot access %s: %s\n", fname, strerror(errno)); continue; } + fprintf(stderr, "WARNING: cannot read and execute %s: %s\n", fname, strerror(errno)); + if(ask_fix()) { - if(chmod(fname, 0755)) + if(chmod(fname, 0755)) { fprintf(stderr, "ERROR: cannot change permissions on %s: %s\n", fname, strerror(errno)); + } } } } + closedir(dir); - + // Check for obsolete / unsafe / unknown configuration variables. check_conffile(tinc_conf, true); dir = opendir(dname); + if(dir) { while((ent = readdir(dir))) { - if(!check_id(ent->d_name)) + if(!check_id(ent->d_name)) { continue; + } - snprintf(fname, sizeof fname, "%s" SLASH "hosts" SLASH "%s", confbase, ent->d_name); + snprintf(fname, sizeof(fname), "%s" SLASH "hosts" SLASH "%s", confbase, ent->d_name); check_conffile(fname, false); } + closedir(dir); } diff --git a/src/fsck.h b/src/fsck.h index 51e4f55..3e0b4ca 100644 --- a/src/fsck.h +++ b/src/fsck.h @@ -1,3 +1,6 @@ +#ifndef TINC_FSCK_H +#define TINC_FSCK_H + /* fsck.h -- header for fsck.c. Copyright (C) 2012 Guus Sliepen @@ -17,10 +20,6 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#ifndef __TINC_FSCK_H__ -#define __TINC_FSCK_H__ - extern int fsck(const char *argv0); #endif - diff --git a/src/gcrypt/cipher.c b/src/gcrypt/cipher.c index e9b32cf..3eed8e9 100644 --- a/src/gcrypt/cipher.c +++ b/src/gcrypt/cipher.c @@ -55,7 +55,7 @@ static struct { static bool nametocipher(const char *name, int *algo, int *mode) { size_t i; - for(i = 0; i < sizeof ciphertable / sizeof *ciphertable; i++) { + for(i = 0; i < sizeof(ciphertable) / sizeof(*ciphertable); i++) { if(ciphertable[i].name && !strcasecmp(name, ciphertable[i].name)) { *algo = ciphertable[i].algo; *mode = ciphertable[i].mode; @@ -69,7 +69,7 @@ static bool nametocipher(const char *name, int *algo, int *mode) { static bool nidtocipher(int nid, int *algo, int *mode) { size_t i; - for(i = 0; i < sizeof ciphertable / sizeof *ciphertable; i++) { + for(i = 0; i < sizeof(ciphertable) / sizeof(*ciphertable); i++) { if(nid == ciphertable[i].nid) { *algo = ciphertable[i].algo; *mode = ciphertable[i].mode; @@ -83,7 +83,7 @@ static bool nidtocipher(int nid, int *algo, int *mode) { static bool ciphertonid(int algo, int mode, int *nid) { size_t i; - for(i = 0; i < sizeof ciphertable / sizeof *ciphertable; i++) { + for(i = 0; i < sizeof(ciphertable) / sizeof(*ciphertable); i++) { if(algo == ciphertable[i].algo && mode == ciphertable[i].mode) { *nid = ciphertable[i].nid; return true; @@ -102,7 +102,7 @@ static bool cipher_open(cipher_t *cipher, int algo, int mode) { } if((err = gcry_cipher_open(&cipher->handle, algo, mode, 0))) { - logger(DEBUG_ALWAYS, LOG_DEBUG, "Unable to intialise cipher %d mode %d: %s", algo, mode, gcry_strerror(err)); + logger(DEBUG_ALWAYS, LOG_DEBUG, "Unable to initialise cipher %d mode %d: %s", algo, mode, gcry_strerror(err)); return false; } @@ -146,10 +146,8 @@ void cipher_close(cipher_t *cipher) { cipher->handle = NULL; } - if(cipher->key) { - free(cipher->key); - cipher->key = NULL; - } + free(cipher->key); + cipher->key = NULL; } size_t cipher_keylength(const cipher_t *cipher) { @@ -193,8 +191,9 @@ bool cipher_encrypt(cipher_t *cipher, const void *indata, size_t inlen, void *ou uint8_t pad[cipher->blklen]; if(cipher->padding) { - if(!oneshot) + if(!oneshot) { return false; + } size_t reqlen = ((inlen + cipher->blklen) / cipher->blklen) * cipher->blklen; @@ -207,14 +206,16 @@ bool cipher_encrypt(cipher_t *cipher, const void *indata, size_t inlen, void *ou inlen = reqlen - cipher->blklen; for(int i = 0; i < cipher->blklen; i++) - if(i < cipher->blklen - padbyte) + if(i < cipher->blklen - padbyte) { pad[i] = ((uint8_t *)indata)[inlen + i]; - else + } else { pad[i] = padbyte; + } } - if(oneshot) + if(oneshot) { gcry_cipher_setiv(cipher->handle, cipher->key + cipher->keylen, cipher->blklen); + } if((err = gcry_cipher_encrypt(cipher->handle, outdata, *outlen, indata, inlen))) { logger(DEBUG_ALWAYS, LOG_ERR, "Error while encrypting: %s", gcry_strerror(err)); @@ -237,8 +238,9 @@ bool cipher_encrypt(cipher_t *cipher, const void *indata, size_t inlen, void *ou bool cipher_decrypt(cipher_t *cipher, const void *indata, size_t inlen, void *outdata, size_t *outlen, bool oneshot) { gcry_error_t err; - if(oneshot) + if(oneshot) { gcry_cipher_setiv(cipher->handle, cipher->key + cipher->keylen, cipher->blklen); + } if((err = gcry_cipher_decrypt(cipher->handle, outdata, *outlen, indata, inlen))) { logger(DEBUG_ALWAYS, LOG_ERR, "Error while decrypting: %s", gcry_strerror(err)); @@ -246,8 +248,9 @@ bool cipher_decrypt(cipher_t *cipher, const void *indata, size_t inlen, void *ou } if(cipher->padding) { - if(!oneshot) + if(!oneshot) { return false; + } uint8_t padbyte = ((uint8_t *)outdata)[inlen - 1]; @@ -265,8 +268,9 @@ bool cipher_decrypt(cipher_t *cipher, const void *indata, size_t inlen, void *ou } *outlen = origlen; - } else + } else { *outlen = inlen; + } return true; } diff --git a/src/gcrypt/digest.c b/src/gcrypt/digest.c index 4229b0c..fce48ee 100644 --- a/src/gcrypt/digest.c +++ b/src/gcrypt/digest.c @@ -37,7 +37,7 @@ static struct { static bool nametodigest(const char *name, int *algo) { int i; - for(i = 0; i < sizeof digesttable / sizeof *digesttable; i++) { + for(i = 0; i < sizeof(digesttable) / sizeof(*digesttable); i++) { if(digesttable[i].name && !strcasecmp(name, digesttable[i].name)) { *algo = digesttable[i].algo; return true; @@ -50,7 +50,7 @@ static bool nametodigest(const char *name, int *algo) { static bool nidtodigest(int nid, int *algo) { int i; - for(i = 0; i < sizeof digesttable / sizeof *digesttable; i++) { + for(i = 0; i < sizeof(digesttable) / sizeof(*digesttable); i++) { if(nid == digesttable[i].nid) { *algo = digesttable[i].algo; return true; @@ -63,7 +63,7 @@ static bool nidtodigest(int nid, int *algo) { static bool digesttonid(int algo, int *nid) { int i; - for(i = 0; i < sizeof digesttable / sizeof *digesttable; i++) { + for(i = 0; i < sizeof(digesttable) / sizeof(*digesttable); i++) { if(algo == digesttable[i].algo) { *nid = digesttable[i].nid; return true; @@ -81,10 +81,11 @@ static bool digest_open(digest_t *digest, int algo, int maclength) { unsigned int len = gcry_md_get_algo_dlen(algo); - if(maclength > len || maclength < 0) + if(maclength > len || maclength < 0) { digest->maclength = len; - else + } else { digest->maclength = maclength; + } digest->algo = algo; digest->hmac = NULL; @@ -119,16 +120,21 @@ bool digest_open_sha1(digest_t *digest, int maclength) { } void digest_close(digest_t *digest) { - if(digest->hmac) + if(digest->hmac) { gcry_md_close(digest->hmac); + } + digest->hmac = NULL; } bool digest_set_key(digest_t *digest, const void *key, size_t len) { - if(!digest->hmac) + if(!digest->hmac) { gcry_md_open(&digest->hmac, digest->algo, GCRY_MD_FLAG_HMAC); - if(!digest->hmac) + } + + if(!digest->hmac) { return false; + } return !gcry_md_setkey(digest->hmac, key, len); } @@ -141,8 +147,11 @@ bool digest_create(digest_t *digest, const void *indata, size_t inlen, void *out gcry_md_reset(digest->hmac); gcry_md_write(digest->hmac, indata, inlen); tmpdata = gcry_md_read(digest->hmac, digest->algo); - if(!tmpdata) + + if(!tmpdata) { return false; + } + memcpy(outdata, tmpdata, digest->maclength); } else { char tmpdata[len]; diff --git a/src/gcrypt/digest.h b/src/gcrypt/digest.h index 9f0d7d8..42404fc 100644 --- a/src/gcrypt/digest.h +++ b/src/gcrypt/digest.h @@ -1,3 +1,6 @@ +#ifndef TINC_GCRYPT_DIGEST_H +#define TINC_GCRYPT_DIGEST_H + /* digest.h -- header file digest.c Copyright (C) 2007-2009 Guus Sliepen @@ -17,9 +20,6 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#ifndef __TINC_DIGEST_H__ -#define __TINC_DIGEST_H__ - #include #define DIGEST_MAX_SIZE 64 diff --git a/src/gcrypt/prf.c b/src/gcrypt/prf.c index 55c9923..ce80f8c 100644 --- a/src/gcrypt/prf.c +++ b/src/gcrypt/prf.c @@ -23,8 +23,9 @@ #include "../ed25519/sha512.h" static void memxor(char *buf, char c, size_t len) { - for(size_t i = 0; i < len; i++) + for(size_t i = 0; i < len; i++) { buf[i] ^= c; + } } static const size_t mdlen = 64; @@ -38,30 +39,39 @@ static bool hmac_sha512(const char *key, size_t keylen, const char *msg, size_t memcpy(tmp, key, keylen); memset(tmp + keylen, 0, blklen - keylen); } else { - if(sha512(key, keylen, tmp) != 0) + if(sha512(key, keylen, tmp) != 0) { return false; + } + memset(tmp + mdlen, 0, blklen - mdlen); } - if(sha512_init(&md) != 0) + if(sha512_init(&md) != 0) { return false; + } // ipad memxor(tmp, 0x36, blklen); - if(sha512_update(&md, tmp, blklen) != 0) + + if(sha512_update(&md, tmp, blklen) != 0) { return false; + } // message - if(sha512_update(&md, msg, msglen) != 0) + if(sha512_update(&md, msg, msglen) != 0) { return false; + } - if(sha512_final(&md, tmp + blklen) != 0) + if(sha512_final(&md, tmp + blklen) != 0) { return false; + } // opad memxor(tmp, 0x36 ^ 0x5c, blklen); - if(sha512(tmp, sizeof tmp, out) != 0) + + if(sha512(tmp, sizeof(tmp), out) != 0) { return false; + } return true; } @@ -84,18 +94,23 @@ bool prf(const char *secret, size_t secretlen, char *seed, size_t seedlen, char while(outlen > 0) { /* Inner HMAC */ - if(!hmac_sha512(secret, secretlen, data, sizeof data, data)) + if(!hmac_sha512(secret, secretlen, data, sizeof(data), data)) { return false; + } /* Outer HMAC */ if(outlen >= mdlen) { - if(!hmac_sha512(secret, secretlen, data, sizeof data, out)) + if(!hmac_sha512(secret, secretlen, data, sizeof(data), out)) { return false; + } + out += mdlen; outlen -= mdlen; } else { - if(!hmac_sha512(secret, secretlen, data, sizeof data, hash)) + if(!hmac_sha512(secret, secretlen, data, sizeof(data), hash)) { return false; + } + memcpy(out, hash, outlen); out += outlen; outlen = 0; diff --git a/src/gcrypt/rsa.c b/src/gcrypt/rsa.c index 751f7b6..eb9f58d 100644 --- a/src/gcrypt/rsa.c +++ b/src/gcrypt/rsa.c @@ -27,28 +27,28 @@ // Base64 decoding table static const uint8_t b64d[128] = { - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0x3e, 0xff, 0xff, 0xff, 0x3f, - 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, - 0x3a, 0x3b, 0x3c, 0x3d, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, - 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, - 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, - 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, - 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, - 0x19, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, - 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, - 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, - 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, - 0x31, 0x32, 0x33, 0xff, 0xff, 0xff, - 0xff, 0xff + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x3e, 0xff, 0xff, 0xff, 0x3f, + 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, + 0x3a, 0x3b, 0x3c, 0x3d, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, + 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, + 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, + 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, + 0x19, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, + 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, + 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, + 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, + 0x31, 0x32, 0x33, 0xff, 0xff, 0xff, + 0xff, 0xff }; // PEM encoding/decoding functions @@ -61,12 +61,15 @@ static bool pem_decode(FILE *fp, const char *header, uint8_t *buf, size_t size, size_t i, j = 0; while(!feof(fp)) { - if(!fgets(line, sizeof line, fp)) + if(!fgets(line, sizeof(line), fp)) { return false; + } if(!decode && !strncmp(line, "-----BEGIN ", 11)) { - if(!strncmp(line + 11, header, strlen(header))) + if(!strncmp(line + 11, header, strlen(header))) { decode = true; + } + continue; } @@ -74,14 +77,18 @@ static bool pem_decode(FILE *fp, const char *header, uint8_t *buf, size_t size, break; } - if(!decode) + if(!decode) { continue; + } for(i = 0; line[i] >= ' '; i++) { - if((signed char)line[i] < 0 || b64d[(int)line[i]] == 0xff) + if((signed char)line[i] < 0 || b64d[(int)line[i]] == 0xff) { break; + } + word |= b64d[(int)line[i]] << shift; shift -= 6; + if(shift <= 2) { if(j > size) { errno = ENOMEM; @@ -95,8 +102,10 @@ static bool pem_decode(FILE *fp, const char *header, uint8_t *buf, size_t size, } } - if(outsize) + if(outsize) { *outsize = j; + } + return true; } @@ -104,20 +113,25 @@ static bool pem_decode(FILE *fp, const char *header, uint8_t *buf, size_t size, // BER decoding functions static int ber_read_id(unsigned char **p, size_t *buflen) { - if(*buflen <= 0) + if(*buflen <= 0) { return -1; + } if((**p & 0x1f) == 0x1f) { int id = 0; bool more; + while(*buflen > 0) { id <<= 7; id |= **p & 0x7f; more = *(*p)++ & 0x80; (*buflen)--; - if(!more) + + if(!more) { break; + } } + return id; } else { (*buflen)--; @@ -126,15 +140,18 @@ static int ber_read_id(unsigned char **p, size_t *buflen) { } static size_t ber_read_len(unsigned char **p, size_t *buflen) { - if(*buflen <= 0) + if(*buflen <= 0) { return -1; + } if(**p & 0x80) { size_t result = 0; int len = *(*p)++ & 0x7f; (*buflen)--; - if(len > *buflen) + + if(len > *buflen) { return 0; + } while(len--) { result <<= 8; @@ -155,8 +172,10 @@ static bool ber_read_sequence(unsigned char **p, size_t *buflen, size_t *result) size_t len = ber_read_len(p, buflen); if(tag == 0x10) { - if(result) + if(result) { *result = len; + } + return true; } else { return false; @@ -168,11 +187,13 @@ static bool ber_read_mpi(unsigned char **p, size_t *buflen, gcry_mpi_t *mpi) { size_t len = ber_read_len(p, buflen); gcry_error_t err = 0; - if(tag != 0x02 || len > *buflen) + if(tag != 0x02 || len > *buflen) { return false; + } - if(mpi) + if(mpi) { err = gcry_mpi_scan(mpi, GCRYMPI_FMT_USG, *p, len, NULL); + } *p += len; *buflen -= len; @@ -184,7 +205,7 @@ bool rsa_set_hex_public_key(rsa_t *rsa, char *n, char *e) { gcry_error_t err = 0; err = gcry_mpi_scan(&rsa->n, GCRYMPI_FMT_HEX, n, 0, NULL) - ?: gcry_mpi_scan(&rsa->e, GCRYMPI_FMT_HEX, e, 0, NULL); + ? : gcry_mpi_scan(&rsa->e, GCRYMPI_FMT_HEX, e, 0, NULL); if(err) { logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading RSA public key: %s", gcry_strerror(errno)); @@ -198,8 +219,8 @@ bool rsa_set_hex_private_key(rsa_t *rsa, char *n, char *e, char *d) { gcry_error_t err = 0; err = gcry_mpi_scan(&rsa->n, GCRYMPI_FMT_HEX, n, 0, NULL) - ?: gcry_mpi_scan(&rsa->e, GCRYMPI_FMT_HEX, e, 0, NULL) - ?: gcry_mpi_scan(&rsa->d, GCRYMPI_FMT_HEX, d, 0, NULL); + ? : gcry_mpi_scan(&rsa->e, GCRYMPI_FMT_HEX, e, 0, NULL) + ? : gcry_mpi_scan(&rsa->d, GCRYMPI_FMT_HEX, d, 0, NULL); if(err) { logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading RSA public key: %s", gcry_strerror(errno)); @@ -215,15 +236,15 @@ bool rsa_read_pem_public_key(rsa_t *rsa, FILE *fp) { uint8_t derbuf[8096], *derp = derbuf; size_t derlen; - if(!pem_decode(fp, "RSA PUBLIC KEY", derbuf, sizeof derbuf, &derlen)) { + if(!pem_decode(fp, "RSA PUBLIC KEY", derbuf, sizeof(derbuf), &derlen)) { logger(DEBUG_ALWAYS, LOG_ERR, "Unable to read RSA public key: %s", strerror(errno)); return NULL; } if(!ber_read_sequence(&derp, &derlen, NULL) - || !ber_read_mpi(&derp, &derlen, &rsa->n) - || !ber_read_mpi(&derp, &derlen, &rsa->e) - || derlen) { + || !ber_read_mpi(&derp, &derlen, &rsa->n) + || !ber_read_mpi(&derp, &derlen, &rsa->e) + || derlen) { logger(DEBUG_ALWAYS, LOG_ERR, "Error while decoding RSA public key"); return NULL; } @@ -235,22 +256,22 @@ bool rsa_read_pem_private_key(rsa_t *rsa, FILE *fp) { uint8_t derbuf[8096], *derp = derbuf; size_t derlen; - if(!pem_decode(fp, "RSA PRIVATE KEY", derbuf, sizeof derbuf, &derlen)) { + if(!pem_decode(fp, "RSA PRIVATE KEY", derbuf, sizeof(derbuf), &derlen)) { logger(DEBUG_ALWAYS, LOG_ERR, "Unable to read RSA private key: %s", strerror(errno)); return NULL; } if(!ber_read_sequence(&derp, &derlen, NULL) - || !ber_read_mpi(&derp, &derlen, NULL) - || !ber_read_mpi(&derp, &derlen, &rsa->n) - || !ber_read_mpi(&derp, &derlen, &rsa->e) - || !ber_read_mpi(&derp, &derlen, &rsa->d) - || !ber_read_mpi(&derp, &derlen, NULL) // p - || !ber_read_mpi(&derp, &derlen, NULL) // q - || !ber_read_mpi(&derp, &derlen, NULL) - || !ber_read_mpi(&derp, &derlen, NULL) - || !ber_read_mpi(&derp, &derlen, NULL) // u - || derlen) { + || !ber_read_mpi(&derp, &derlen, NULL) + || !ber_read_mpi(&derp, &derlen, &rsa->n) + || !ber_read_mpi(&derp, &derlen, &rsa->e) + || !ber_read_mpi(&derp, &derlen, &rsa->d) + || !ber_read_mpi(&derp, &derlen, NULL) // p + || !ber_read_mpi(&derp, &derlen, NULL) // q + || !ber_read_mpi(&derp, &derlen, NULL) + || !ber_read_mpi(&derp, &derlen, NULL) + || !ber_read_mpi(&derp, &derlen, NULL) // u + || derlen) { logger(DEBUG_ALWAYS, LOG_ERR, "Error while decoding RSA private key"); return NULL; } @@ -277,10 +298,12 @@ bool rsa_public_encrypt(rsa_t *rsa, void *in, size_t len, void *out) { gcry_mpi_powm(outmpi, inmpi, rsa->e, rsa->n); int pad = len - (gcry_mpi_get_nbits(outmpi) + 7) / 8; - while(pad--) - *(char *)out++ = 0; - check(gcry_mpi_print(GCRYMPI_FMT_USG, out,len, NULL, outmpi)); + while(pad--) { + *(char *)out++ = 0; + } + + check(gcry_mpi_print(GCRYMPI_FMT_USG, out, len, NULL, outmpi)); return true; } @@ -293,10 +316,12 @@ bool rsa_private_decrypt(rsa_t *rsa, void *in, size_t len, void *out) { gcry_mpi_powm(outmpi, inmpi, rsa->d, rsa->n); int pad = len - (gcry_mpi_get_nbits(outmpi) + 7) / 8; - while(pad--) - *(char *)out++ = 0; - check(gcry_mpi_print(GCRYMPI_FMT_USG, out,len, NULL, outmpi)); + while(pad--) { + *(char *)out++ = 0; + } + + check(gcry_mpi_print(GCRYMPI_FMT_USG, out, len, NULL, outmpi)); return true; } diff --git a/src/gcrypt/rsagen.c b/src/gcrypt/rsagen.c index 36fb104..030f2bc 100644 --- a/src/gcrypt/rsagen.c +++ b/src/gcrypt/rsagen.c @@ -44,14 +44,16 @@ static bool pem_encode(FILE *fp, const char *header, uint8_t *buf, size_t size) word = buf[i] << 16 | buf[i + 1] << 8 | buf[i + 2]; } else { word = buf[i] << 16; - if(i == size - 2) + + if(i == size - 2) { word |= buf[i + 1] << 8; + } } line[j++] = b64e[(word >> 18) ]; line[j++] = b64e[(word >> 12) & 0x3f]; line[j++] = b64e[(word >> 6) & 0x3f]; - line[j++] = b64e[(word ) & 0x3f]; + line[j++] = b64e[(word) & 0x3f]; if(j >= 64) { line[j++] = '\n'; @@ -62,8 +64,10 @@ static bool pem_encode(FILE *fp, const char *header, uint8_t *buf, size_t size) } if(size % 3 > 0) { - if(size % 3 > 1) + if(size % 3 > 1) { line[j++] = '='; + } + line[j++] = '='; } @@ -82,19 +86,24 @@ static bool pem_encode(FILE *fp, const char *header, uint8_t *buf, size_t size) // BER encoding functions static bool ber_write_id(uint8_t **p, size_t *buflen, int id) { - if(*buflen <= 0) + if(*buflen <= 0) { return false; + } if(id >= 0x1f) { while(id) { - if(*buflen <= 0) + if(*buflen <= 0) { return false; + } (*buflen)--; **p = id & 0x7f; id >>= 7; - if(id) + + if(id) { **p |= 0x80; + } + (*p)++; } } else { @@ -107,14 +116,18 @@ static bool ber_write_id(uint8_t **p, size_t *buflen, int id) { static bool ber_write_len(uint8_t **p, size_t *buflen, size_t len) { do { - if(*buflen <= 0) + if(*buflen <= 0) { return false; + } (*buflen)--; **p = len & 0x7f; len >>= 7; - if(len) + + if(len) { **p |= 0x80; + } + (*p)++; } while(len); @@ -122,8 +135,9 @@ static bool ber_write_len(uint8_t **p, size_t *buflen, size_t len) { } static bool ber_write_sequence(uint8_t **p, size_t *buflen, uint8_t *seqbuf, size_t seqlen) { - if(!ber_write_id(p, buflen, 0x10) || !ber_write_len(p, buflen, seqlen) || *buflen < seqlen) + if(!ber_write_id(p, buflen, 0x10) || !ber_write_len(p, buflen, seqlen) || *buflen < seqlen) { return false; + } memcpy(*p, seqbuf, seqlen); *p += seqlen; @@ -134,15 +148,18 @@ static bool ber_write_sequence(uint8_t **p, size_t *buflen, uint8_t *seqbuf, siz static bool ber_write_mpi(uint8_t **p, size_t *buflen, gcry_mpi_t mpi) { uint8_t tmpbuf[1024]; - size_t tmplen = sizeof tmpbuf; + size_t tmplen = sizeof(tmpbuf); gcry_error_t err; err = gcry_mpi_aprint(GCRYMPI_FMT_USG, &tmpbuf, &tmplen, mpi); - if(err) - return false; - if(!ber_write_id(p, buflen, 0x02) || !ber_write_len(p, buflen, tmplen) || *buflen < tmplen) + if(err) { return false; + } + + if(!ber_write_id(p, buflen, 0x02) || !ber_write_len(p, buflen, tmplen) || *buflen < tmplen) { + return false; + } memcpy(*p, tmpbuf, tmplen); *p += tmplen; @@ -158,12 +175,12 @@ bool rsa_write_pem_public_key(rsa_t *rsa, FILE *fp) { uint8_t derbuf2[8096]; uint8_t *derp1 = derbuf1; uint8_t *derp2 = derbuf2; - size_t derlen1 = sizeof derbuf1; - size_t derlen2 = sizeof derbuf2; + size_t derlen1 = sizeof(derbuf1); + size_t derlen2 = sizeof(derbuf2); if(!ber_write_mpi(&derp1, &derlen1, &rsa->n) - || !ber_write_mpi(&derp1, &derlen1, &rsa->e) - || !ber_write_sequence(&derp2, &derlen2, derbuf1, derlen1)) { + || !ber_write_mpi(&derp1, &derlen1, &rsa->e) + || !ber_write_sequence(&derp2, &derlen2, derbuf1, derlen1)) { logger(DEBUG_ALWAYS, LOG_ERR, "Error while encoding RSA public key"); return false; } @@ -181,28 +198,30 @@ bool rsa_write_pem_private_key(rsa_t *rsa, FILE *fp) { uint8_t derbuf2[8096]; uint8_t *derp1 = derbuf1; uint8_t *derp2 = derbuf2; - size_t derlen1 = sizeof derbuf1; - size_t derlen2 = sizeof derbuf2; + size_t derlen1 = sizeof(derbuf1); + size_t derlen2 = sizeof(derbuf2); if(!ber_write_mpi(&derp1, &derlen1, &bits) - || ber_write_mpi(&derp1, &derlen1, &rsa->n) // modulus - || ber_write_mpi(&derp1, &derlen1, &rsa->e) // public exponent - || ber_write_mpi(&derp1, &derlen1, &rsa->d) // private exponent - || ber_write_mpi(&derp1, &derlen1, &p) - || ber_write_mpi(&derp1, &derlen1, &q) - || ber_write_mpi(&derp1, &derlen1, &exp1) - || ber_write_mpi(&derp1, &derlen1, &exp2) - || ber_write_mpi(&derp1, &derlen1, &coeff)) + || ber_write_mpi(&derp1, &derlen1, &rsa->n) // modulus + || ber_write_mpi(&derp1, &derlen1, &rsa->e) // public exponent + || ber_write_mpi(&derp1, &derlen1, &rsa->d) // private exponent + || ber_write_mpi(&derp1, &derlen1, &p) + || ber_write_mpi(&derp1, &derlen1, &q) + || ber_write_mpi(&derp1, &derlen1, &exp1) + || ber_write_mpi(&derp1, &derlen1, &exp2) + || ber_write_mpi(&derp1, &derlen1, &coeff)) { logger(DEBUG_ALWAYS, LOG_ERR, "Error while encoding RSA private key"); - return false; } - if(!pem_encode(fp, "RSA PRIVATE KEY", derbuf2, derlen2)) { - logger(DEBUG_ALWAYS, LOG_ERR, "Unable to write RSA private key: %s", strerror(errno)); - return false; - } + return false; +} - return true; +if(!pem_encode(fp, "RSA PRIVATE KEY", derbuf2, derlen2)) { + logger(DEBUG_ALWAYS, LOG_ERR, "Unable to write RSA private key: %s", strerror(errno)); + return false; +} + +return true; } #endif diff --git a/src/getopt.c b/src/getopt.c index d63887e..5d5fb59 100644 --- a/src/getopt.c +++ b/src/getopt.c @@ -4,7 +4,7 @@ before changing it! Copyright (C) 1987, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97 - Free Software Foundation, Inc. + Free Software Foundation, Inc. NOTE: The canonical source of this file is maintained with the GNU C Library. Bugs can be reported to bug-glibc@prep.ai.mit.edu. @@ -69,12 +69,12 @@ with this program; if not, write to the Free Software Foundation, Inc., /* This needs to come after some library #include to get __GNU_LIBRARY__ defined. */ -#ifdef __GNU_LIBRARY__ +#ifdef __GNU_LIBRARY__ /* Don't include stdlib.h for non-GNU C libraries because some of them contain conflicting prototypes for getopt. */ #include #include -#endif /* GNU C library. */ +#endif /* GNU C library. */ #ifdef VMS #include @@ -183,40 +183,41 @@ int optopt = '?'; of the value of `ordering'. In the case of RETURN_IN_ORDER, only `--' can cause `getopt' to return -1 with `optind' != ARGC. */ -static enum -{ - REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER +static enum { + REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER } ordering; /* Value of POSIXLY_CORRECT environment variable. */ static char *posixly_correct; -#ifdef __GNU_LIBRARY__ +#ifdef __GNU_LIBRARY__ /* We want to avoid inclusion of string.h with non-GNU libraries because there are many ways it can cause trouble. On some systems, it contains special magic macros that don't work in GCC. */ #include -#define my_index strchr +#define my_index strchr #else /* Avoid depending on library functions or files whose names are inconsistent. */ -char *getenv (); +char *getenv(); static char * -my_index (str, chr) - const char *str; - int chr; +my_index(str, chr) +const char *str; +int chr; { - while (*str) - { - if (*str == chr) - return (char *) str; - str++; - } - return 0; + while(*str) { + if(*str == chr) { + return (char *) str; + } + + str++; + } + + return 0; } /* If using GCC, we can safely declare strlen this way. @@ -227,7 +228,7 @@ my_index (str, chr) #if !defined (__STDC__) || !__STDC__ /* gcc with -traditional declares the built-in strlen to return int, and has done so at least since version 2.4.5. -- rms. */ -extern int strlen (const char *); +extern int strlen(const char *); #endif /* not __STDC__ */ #endif /* __GNUC__ */ @@ -261,26 +262,25 @@ extern pid_t __libc_pid; is valid for the getopt call we must make sure that the ARGV passed to getopt is that one passed to the process. */ static void -__attribute__ ((__unused__)) -store_args_and_env (int argc, char *const *argv) -{ - /* XXX This is no good solution. We should rather copy the args so - that we can compare them later. But we must not use malloc(3). */ - original_argc = argc; - original_argv = argv; +__attribute__((__unused__)) +store_args_and_env(int argc, char *const *argv) { + /* XXX This is no good solution. We should rather copy the args so + that we can compare them later. But we must not use malloc(3). */ + original_argc = argc; + original_argv = argv; } -text_set_element (__libc_subinit, store_args_and_env); +text_set_element(__libc_subinit, store_args_and_env); # define SWAP_FLAGS(ch1, ch2) \ - if (nonoption_flags_len > 0) \ - { \ - char __tmp = __getopt_nonoption_flags[ch1]; \ - __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2]; \ - __getopt_nonoption_flags[ch2] = __tmp; \ - } -#else /* !_LIBC */ + if (nonoption_flags_len > 0) \ + { \ + char __tmp = __getopt_nonoption_flags[ch1]; \ + __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2]; \ + __getopt_nonoption_flags[ch2] = __tmp; \ + } +#else /* !_LIBC */ # define SWAP_FLAGS(ch1, ch2) -#endif /* _LIBC */ +#endif /* _LIBC */ /* Exchange two adjacent subsequences of ARGV. One subsequence is elements [first_nonopt,last_nonopt) @@ -292,161 +292,158 @@ text_set_element (__libc_subinit, store_args_and_env); the new indices of the non-options in ARGV after they are moved. */ #if defined (__STDC__) && __STDC__ -static void exchange (char **); +static void exchange(char **); #endif static void -exchange (argv) - char **argv; +exchange(argv) +char **argv; { - int bottom = first_nonopt; - int middle = last_nonopt; - int top = optind; - char *tem; + int bottom = first_nonopt; + int middle = last_nonopt; + int top = optind; + char *tem; - /* Exchange the shorter segment with the far end of the longer segment. - That puts the shorter segment into the right place. - It leaves the longer segment in the right place overall, - but it consists of two parts that need to be swapped next. */ + /* Exchange the shorter segment with the far end of the longer segment. + That puts the shorter segment into the right place. + It leaves the longer segment in the right place overall, + but it consists of two parts that need to be swapped next. */ #ifdef _LIBC - /* First make sure the handling of the `__getopt_nonoption_flags' - string can work normally. Our top argument must be in the range - of the string. */ - if (nonoption_flags_len > 0 && top >= nonoption_flags_max_len) - { - /* We must extend the array. The user plays games with us and - presents new arguments. */ - char *new_str = malloc (top + 1); - if (new_str == NULL) - nonoption_flags_len = nonoption_flags_max_len = 0; - else - { - memcpy (new_str, __getopt_nonoption_flags, nonoption_flags_max_len); - memset (&new_str[nonoption_flags_max_len], '\0', - top + 1 - nonoption_flags_max_len); - nonoption_flags_max_len = top + 1; - __getopt_nonoption_flags = new_str; + + /* First make sure the handling of the `__getopt_nonoption_flags' + string can work normally. Our top argument must be in the range + of the string. */ + if(nonoption_flags_len > 0 && top >= nonoption_flags_max_len) { + /* We must extend the array. The user plays games with us and + presents new arguments. */ + char *new_str = malloc(top + 1); + + if(new_str == NULL) { + nonoption_flags_len = nonoption_flags_max_len = 0; + } else { + memcpy(new_str, __getopt_nonoption_flags, nonoption_flags_max_len); + memset(&new_str[nonoption_flags_max_len], '\0', + top + 1 - nonoption_flags_max_len); + nonoption_flags_max_len = top + 1; + __getopt_nonoption_flags = new_str; + } } - } + #endif - while (top > middle && middle > bottom) - { - if (top - middle > middle - bottom) - { - /* Bottom segment is the short one. */ - int len = middle - bottom; - register int i; + while(top > middle && middle > bottom) { + if(top - middle > middle - bottom) { + /* Bottom segment is the short one. */ + int len = middle - bottom; + register int i; - /* Swap it with the top part of the top segment. */ - for (i = 0; i < len; i++) - { - tem = argv[bottom + i]; - argv[bottom + i] = argv[top - (middle - bottom) + i]; - argv[top - (middle - bottom) + i] = tem; - SWAP_FLAGS (bottom + i, top - (middle - bottom) + i); - } - /* Exclude the moved bottom segment from further swapping. */ - top -= len; + /* Swap it with the top part of the top segment. */ + for(i = 0; i < len; i++) { + tem = argv[bottom + i]; + argv[bottom + i] = argv[top - (middle - bottom) + i]; + argv[top - (middle - bottom) + i] = tem; + SWAP_FLAGS(bottom + i, top - (middle - bottom) + i); + } + + /* Exclude the moved bottom segment from further swapping. */ + top -= len; + } else { + /* Top segment is the short one. */ + int len = top - middle; + register int i; + + /* Swap it with the bottom part of the bottom segment. */ + for(i = 0; i < len; i++) { + tem = argv[bottom + i]; + argv[bottom + i] = argv[middle + i]; + argv[middle + i] = tem; + SWAP_FLAGS(bottom + i, middle + i); + } + + /* Exclude the moved top segment from further swapping. */ + bottom += len; + } } - else - { - /* Top segment is the short one. */ - int len = top - middle; - register int i; - /* Swap it with the bottom part of the bottom segment. */ - for (i = 0; i < len; i++) - { - tem = argv[bottom + i]; - argv[bottom + i] = argv[middle + i]; - argv[middle + i] = tem; - SWAP_FLAGS (bottom + i, middle + i); - } - /* Exclude the moved top segment from further swapping. */ - bottom += len; - } - } + /* Update records for the slots the non-options now occupy. */ - /* Update records for the slots the non-options now occupy. */ - - first_nonopt += (optind - last_nonopt); - last_nonopt = optind; + first_nonopt += (optind - last_nonopt); + last_nonopt = optind; } /* Initialize the internal data when the first call is made. */ #if defined (__STDC__) && __STDC__ -static const char *_getopt_initialize (int, char *const *, const char *); +static const char *_getopt_initialize(int, char *const *, const char *); #endif static const char * -_getopt_initialize (argc, argv, optstring) - int argc; - char *const *argv; - const char *optstring; +_getopt_initialize(argc, argv, optstring) +int argc; +char *const *argv; +const char *optstring; { - /* Start processing options with ARGV-element 1 (since ARGV-element 0 - is the program name); the sequence of previously skipped - non-option ARGV-elements is empty. */ + /* Start processing options with ARGV-element 1 (since ARGV-element 0 + is the program name); the sequence of previously skipped + non-option ARGV-elements is empty. */ - first_nonopt = last_nonopt = optind; + first_nonopt = last_nonopt = optind; - nextchar = NULL; + nextchar = NULL; - posixly_correct = getenv ("POSIXLY_CORRECT"); + posixly_correct = getenv("POSIXLY_CORRECT"); - /* Determine how to handle the ordering of options and nonoptions. */ + /* Determine how to handle the ordering of options and nonoptions. */ - if (optstring[0] == '-') - { - ordering = RETURN_IN_ORDER; - ++optstring; - } - else if (optstring[0] == '+') - { - ordering = REQUIRE_ORDER; - ++optstring; - } - else if (posixly_correct != NULL) - ordering = REQUIRE_ORDER; - else - ordering = PERMUTE; + if(optstring[0] == '-') { + ordering = RETURN_IN_ORDER; + ++optstring; + } else if(optstring[0] == '+') { + ordering = REQUIRE_ORDER; + ++optstring; + } else if(posixly_correct != NULL) { + ordering = REQUIRE_ORDER; + } else { + ordering = PERMUTE; + } #ifdef _LIBC - if (posixly_correct == NULL - && argc == original_argc && argv == original_argv) - { - if (nonoption_flags_max_len == 0) - { - if (__getopt_nonoption_flags == NULL - || __getopt_nonoption_flags[0] == '\0') - nonoption_flags_max_len = -1; - else - { - const char *orig_str = __getopt_nonoption_flags; - int len = nonoption_flags_max_len = strlen (orig_str); - if (nonoption_flags_max_len < argc) - nonoption_flags_max_len = argc; - __getopt_nonoption_flags = - (char *) malloc (nonoption_flags_max_len); - if (__getopt_nonoption_flags == NULL) - nonoption_flags_max_len = -1; - else - { - memcpy (__getopt_nonoption_flags, orig_str, len); - memset (&__getopt_nonoption_flags[len], '\0', - nonoption_flags_max_len - len); + + if(posixly_correct == NULL + && argc == original_argc && argv == original_argv) { + if(nonoption_flags_max_len == 0) { + if(__getopt_nonoption_flags == NULL + || __getopt_nonoption_flags[0] == '\0') { + nonoption_flags_max_len = -1; + } else { + const char *orig_str = __getopt_nonoption_flags; + int len = nonoption_flags_max_len = strlen(orig_str); + + if(nonoption_flags_max_len < argc) { + nonoption_flags_max_len = argc; + } + + __getopt_nonoption_flags = + (char *) malloc(nonoption_flags_max_len); + + if(__getopt_nonoption_flags == NULL) { + nonoption_flags_max_len = -1; + } else { + memcpy(__getopt_nonoption_flags, orig_str, len); + memset(&__getopt_nonoption_flags[len], '\0', + nonoption_flags_max_len - len); + } + } } - } + + nonoption_flags_len = nonoption_flags_max_len; + } else { + nonoption_flags_len = 0; } - nonoption_flags_len = nonoption_flags_max_len; - } - else - nonoption_flags_len = 0; + #endif - return optstring; + return optstring; } /* Scan elements of ARGV (whose length is ARGC) for option characters @@ -506,474 +503,476 @@ _getopt_initialize (argc, argv, optstring) long-named options. */ int -_getopt_internal (argc, argv, optstring, longopts, longind, long_only) - int argc; - char *const *argv; - const char *optstring; - const struct option *longopts; - int *longind; - int long_only; +_getopt_internal(argc, argv, optstring, longopts, longind, long_only) +int argc; +char *const *argv; +const char *optstring; +const struct option *longopts; +int *longind; +int long_only; { - optarg = NULL; + optarg = NULL; - if (optind == 0 || !__getopt_initialized) - { - if (optind == 0) - optind = 1; /* Don't scan ARGV[0], the program name. */ - optstring = _getopt_initialize (argc, argv, optstring); - __getopt_initialized = 1; - } + if(optind == 0 || !__getopt_initialized) { + if(optind == 0) { + optind = 1; /* Don't scan ARGV[0], the program name. */ + } - /* Test whether ARGV[optind] points to a non-option argument. - Either it does not have option syntax, or there is an environment flag - from the shell indicating it is not an option. The later information - is only used when the used in the GNU libc. */ + optstring = _getopt_initialize(argc, argv, optstring); + __getopt_initialized = 1; + } + + /* Test whether ARGV[optind] points to a non-option argument. + Either it does not have option syntax, or there is an environment flag + from the shell indicating it is not an option. The later information + is only used when the used in the GNU libc. */ #ifdef _LIBC -#define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0' \ - || (optind < nonoption_flags_len \ - && __getopt_nonoption_flags[optind] == '1')) +#define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0' \ + || (optind < nonoption_flags_len \ + && __getopt_nonoption_flags[optind] == '1')) #else #define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0') #endif - if (nextchar == NULL || *nextchar == '\0') - { - /* Advance to the next ARGV-element. */ + if(nextchar == NULL || *nextchar == '\0') { + /* Advance to the next ARGV-element. */ - /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been - moved back by the user (who may also have changed the arguments). */ - if (last_nonopt > optind) - last_nonopt = optind; - if (first_nonopt > optind) - first_nonopt = optind; - - if (ordering == PERMUTE) - { - /* If we have just processed some options following some non-options, - exchange them so that the options come first. */ - - if (first_nonopt != last_nonopt && last_nonopt != optind) - exchange ((char **) argv); - else if (last_nonopt != optind) - first_nonopt = optind; - - /* Skip any additional non-options - and extend the range of non-options previously skipped. */ - - while (optind < argc && NONOPTION_P) - optind++; - last_nonopt = optind; - } - - /* The special ARGV-element `--' means premature end of options. - Skip it like a null option, - then exchange with previous non-options as if it were an option, - then skip everything else like a non-option. */ - - if (optind != argc && !strcmp (argv[optind], "--")) - { - optind++; - - if (first_nonopt != last_nonopt && last_nonopt != optind) - exchange ((char **) argv); - else if (first_nonopt == last_nonopt) - first_nonopt = optind; - last_nonopt = argc; - - optind = argc; - } - - /* If we have done all the ARGV-elements, stop the scan - and back over any non-options that we skipped and permuted. */ - - if (optind == argc) - { - /* Set the next-arg-index to point at the non-options - that we previously skipped, so the caller will digest them. */ - if (first_nonopt != last_nonopt) - optind = first_nonopt; - return -1; - } - - /* If we have come to a non-option and did not permute it, - either stop the scan or describe it to the caller and pass it by. */ - - if (NONOPTION_P) - { - if (ordering == REQUIRE_ORDER) - return -1; - optarg = argv[optind++]; - return 1; - } - - /* We have found another option-ARGV-element. - Skip the initial punctuation. */ - - nextchar = (argv[optind] + 1 - + (longopts != NULL && argv[optind][1] == '-')); - } - - /* Decode the current option-ARGV-element. */ - - /* Check whether the ARGV-element is a long option. - - If long_only and the ARGV-element has the form "-f", where f is - a valid short option, don't consider it an abbreviated form of - a long option that starts with f. Otherwise there would be no - way to give the -f short option. - - On the other hand, if there's a long option "fubar" and - the ARGV-element is "-fu", do consider that an abbreviation of - the long option, just like "--fu", and not "-f" with arg "u". - - This distinction seems to be the most useful approach. */ - - if (longopts != NULL - && (argv[optind][1] == '-' - || (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1]))))) - { - char *nameend; - const struct option *p; - const struct option *pfound = NULL; - int exact = 0; - int ambig = 0; - int indfound = -1; - int option_index; - - for (nameend = nextchar; *nameend && *nameend != '='; nameend++) - /* Do nothing. */ ; - - /* Test all long options for either exact match - or abbreviated matches. */ - for (p = longopts, option_index = 0; p->name; p++, option_index++) - if (!strncmp (p->name, nextchar, nameend - nextchar)) - { - if ((unsigned int) (nameend - nextchar) - == (unsigned int) strlen (p->name)) - { - /* Exact match found. */ - pfound = p; - indfound = option_index; - exact = 1; - break; - } - else if (pfound == NULL) - { - /* First nonexact match found. */ - pfound = p; - indfound = option_index; - } - else - /* Second or later nonexact match found. */ - ambig = 1; - } - - if (ambig && !exact) - { - if (opterr) - fprintf (stderr, "%s: option `%s' is ambiguous\n", - argv[0], argv[optind]); - nextchar += strlen (nextchar); - optind++; - optopt = 0; - return '?'; - } - - if (pfound != NULL) - { - option_index = indfound; - optind++; - if (*nameend) - { - /* Don't test has_arg with >, because some C compilers don't - allow it to be used on enums. */ - if (pfound->has_arg) - optarg = nameend + 1; - else - { - if (opterr) - { - if (argv[optind - 1][1] == '-') - /* --option */ - fprintf (stderr, - "%s: option `--%s' doesn't allow an argument\n", - argv[0], pfound->name); - else - /* +option or -option */ - fprintf (stderr, - "%s: option `%c%s' doesn't allow an argument\n", - argv[0], argv[optind - 1][0], pfound->name); - } - - nextchar += strlen (nextchar); - - optopt = pfound->val; - return '?'; + /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been + moved back by the user (who may also have changed the arguments). */ + if(last_nonopt > optind) { + last_nonopt = optind; } - } - else if (pfound->has_arg == 1) - { - if (optind < argc) - optarg = argv[optind++]; - else - { - if (opterr) - fprintf (stderr, - "%s: option `%s' requires an argument\n", - argv[0], argv[optind - 1]); - nextchar += strlen (nextchar); - optopt = pfound->val; - return optstring[0] == ':' ? ':' : '?'; + + if(first_nonopt > optind) { + first_nonopt = optind; } - } - nextchar += strlen (nextchar); - if (longind != NULL) - *longind = option_index; - if (pfound->flag) - { - *(pfound->flag) = pfound->val; - return 0; - } - return pfound->val; + + if(ordering == PERMUTE) { + /* If we have just processed some options following some non-options, + exchange them so that the options come first. */ + + if(first_nonopt != last_nonopt && last_nonopt != optind) { + exchange((char **) argv); + } else if(last_nonopt != optind) { + first_nonopt = optind; + } + + /* Skip any additional non-options + and extend the range of non-options previously skipped. */ + + while(optind < argc && NONOPTION_P) { + optind++; + } + + last_nonopt = optind; + } + + /* The special ARGV-element `--' means premature end of options. + Skip it like a null option, + then exchange with previous non-options as if it were an option, + then skip everything else like a non-option. */ + + if(optind != argc && !strcmp(argv[optind], "--")) { + optind++; + + if(first_nonopt != last_nonopt && last_nonopt != optind) { + exchange((char **) argv); + } else if(first_nonopt == last_nonopt) { + first_nonopt = optind; + } + + last_nonopt = argc; + + optind = argc; + } + + /* If we have done all the ARGV-elements, stop the scan + and back over any non-options that we skipped and permuted. */ + + if(optind == argc) { + /* Set the next-arg-index to point at the non-options + that we previously skipped, so the caller will digest them. */ + if(first_nonopt != last_nonopt) { + optind = first_nonopt; + } + + return -1; + } + + /* If we have come to a non-option and did not permute it, + either stop the scan or describe it to the caller and pass it by. */ + + if(NONOPTION_P) { + if(ordering == REQUIRE_ORDER) { + return -1; + } + + optarg = argv[optind++]; + return 1; + } + + /* We have found another option-ARGV-element. + Skip the initial punctuation. */ + + nextchar = (argv[optind] + 1 + + (longopts != NULL && argv[optind][1] == '-')); } - /* Can't find it as a long option. If this is not getopt_long_only, - or the option starts with '--' or is not a valid short - option, then it's an error. - Otherwise interpret it as a short option. */ - if (!long_only || argv[optind][1] == '-' - || my_index (optstring, *nextchar) == NULL) + /* Decode the current option-ARGV-element. */ + + /* Check whether the ARGV-element is a long option. + + If long_only and the ARGV-element has the form "-f", where f is + a valid short option, don't consider it an abbreviated form of + a long option that starts with f. Otherwise there would be no + way to give the -f short option. + + On the other hand, if there's a long option "fubar" and + the ARGV-element is "-fu", do consider that an abbreviation of + the long option, just like "--fu", and not "-f" with arg "u". + + This distinction seems to be the most useful approach. */ + + if(longopts != NULL + && (argv[optind][1] == '-' + || (long_only && (argv[optind][2] || !my_index(optstring, argv[optind][1]))))) { + char *nameend; + const struct option *p; + const struct option *pfound = NULL; + int exact = 0; + int ambig = 0; + int indfound = -1; + int option_index; + + for(nameend = nextchar; *nameend && *nameend != '='; nameend++) + /* Do nothing. */ ; + + /* Test all long options for either exact match + or abbreviated matches. */ + for(p = longopts, option_index = 0; p->name; p++, option_index++) + if(!strncmp(p->name, nextchar, nameend - nextchar)) { + if((unsigned int)(nameend - nextchar) + == (unsigned int) strlen(p->name)) { + /* Exact match found. */ + pfound = p; + indfound = option_index; + exact = 1; + break; + } else if(pfound == NULL) { + /* First nonexact match found. */ + pfound = p; + indfound = option_index; + } else + /* Second or later nonexact match found. */ + { + ambig = 1; + } + } + + if(ambig && !exact) { + if(opterr) + fprintf(stderr, "%s: option `%s' is ambiguous\n", + argv[0], argv[optind]); + + nextchar += strlen(nextchar); + optind++; + optopt = 0; + return '?'; + } + + if(pfound != NULL) { + option_index = indfound; + optind++; + + if(*nameend) { + /* Don't test has_arg with >, because some C compilers don't + allow it to be used on enums. */ + if(pfound->has_arg) { + optarg = nameend + 1; + } else { + if(opterr) { + if(argv[optind - 1][1] == '-') + /* --option */ + fprintf(stderr, + "%s: option `--%s' doesn't allow an argument\n", + argv[0], pfound->name); + else + /* +option or -option */ + fprintf(stderr, + "%s: option `%c%s' doesn't allow an argument\n", + argv[0], argv[optind - 1][0], pfound->name); + } + + nextchar += strlen(nextchar); + + optopt = pfound->val; + return '?'; + } + } else if(pfound->has_arg == 1) { + if(optind < argc) { + optarg = argv[optind++]; + } else { + if(opterr) + fprintf(stderr, + "%s: option `%s' requires an argument\n", + argv[0], argv[optind - 1]); + + nextchar += strlen(nextchar); + optopt = pfound->val; + return optstring[0] == ':' ? ':' : '?'; + } + } + + nextchar += strlen(nextchar); + + if(longind != NULL) { + *longind = option_index; + } + + if(pfound->flag) { + *(pfound->flag) = pfound->val; + return 0; + } + + return pfound->val; + } + + /* Can't find it as a long option. If this is not getopt_long_only, + or the option starts with '--' or is not a valid short + option, then it's an error. + Otherwise interpret it as a short option. */ + if(!long_only || argv[optind][1] == '-' + || my_index(optstring, *nextchar) == NULL) { + if(opterr) { + if(argv[optind][1] == '-') + /* --option */ + fprintf(stderr, "%s: unrecognized option `--%s'\n", + argv[0], nextchar); + else + /* +option or -option */ + fprintf(stderr, "%s: unrecognized option `%c%s'\n", + argv[0], argv[optind][0], nextchar); + } + + nextchar = (char *) ""; + optind++; + optopt = 0; + return '?'; + } + } + + /* Look at and handle the next short option-character. */ + { - if (opterr) - { - if (argv[optind][1] == '-') - /* --option */ - fprintf (stderr, "%s: unrecognized option `--%s'\n", - argv[0], nextchar); - else - /* +option or -option */ - fprintf (stderr, "%s: unrecognized option `%c%s'\n", - argv[0], argv[optind][0], nextchar); - } - nextchar = (char *) ""; - optind++; - optopt = 0; - return '?'; + char c = *nextchar++; + char *temp = my_index(optstring, c); + + /* Increment `optind' when we start to process its last character. */ + if(*nextchar == '\0') { + ++optind; + } + + if(temp == NULL || c == ':') { + if(opterr) { + if(posixly_correct) + /* 1003.2 specifies the format of this message. */ + fprintf(stderr, "%s: illegal option -- %c\n", + argv[0], c); + else + fprintf(stderr, "%s: invalid option -- %c\n", + argv[0], c); + } + + optopt = c; + return '?'; + } + + /* Convenience. Treat POSIX -W foo same as long option --foo */ + if(temp[0] == 'W' && temp[1] == ';') { + char *nameend; + const struct option *p; + const struct option *pfound = NULL; + int exact = 0; + int ambig = 0; + int indfound = 0; + int option_index; + + /* This is an option that requires an argument. */ + if(*nextchar != '\0') { + optarg = nextchar; + /* If we end this ARGV-element by taking the rest as an arg, + we must advance to the next element now. */ + optind++; + } else if(optind == argc) { + if(opterr) { + /* 1003.2 specifies the format of this message. */ + fprintf(stderr, "%s: option requires an argument -- %c\n", + argv[0], c); + } + + optopt = c; + + if(optstring[0] == ':') { + c = ':'; + } else { + c = '?'; + } + + return c; + } else + /* We already incremented `optind' once; + increment it again when taking next ARGV-elt as argument. */ + { + optarg = argv[optind++]; + } + + /* optarg is now the argument, see if it's in the + table of longopts. */ + + for(nextchar = nameend = optarg; *nameend && *nameend != '='; nameend++) + /* Do nothing. */ ; + + /* Test all long options for either exact match + or abbreviated matches. */ + for(p = longopts, option_index = 0; p->name; p++, option_index++) + if(!strncmp(p->name, nextchar, nameend - nextchar)) { + if((unsigned int)(nameend - nextchar) == strlen(p->name)) { + /* Exact match found. */ + pfound = p; + indfound = option_index; + exact = 1; + break; + } else if(pfound == NULL) { + /* First nonexact match found. */ + pfound = p; + indfound = option_index; + } else + /* Second or later nonexact match found. */ + { + ambig = 1; + } + } + + if(ambig && !exact) { + if(opterr) + fprintf(stderr, "%s: option `-W %s' is ambiguous\n", + argv[0], argv[optind]); + + nextchar += strlen(nextchar); + optind++; + return '?'; + } + + if(pfound != NULL) { + option_index = indfound; + + if(*nameend) { + /* Don't test has_arg with >, because some C compilers don't + allow it to be used on enums. */ + if(pfound->has_arg) { + optarg = nameend + 1; + } else { + if(opterr) + fprintf(stderr, + "%s: option `-W %s' doesn't allow an argument\n", + argv[0], pfound->name); + + nextchar += strlen(nextchar); + return '?'; + } + } else if(pfound->has_arg == 1) { + if(optind < argc) { + optarg = argv[optind++]; + } else { + if(opterr) + fprintf(stderr, + "%s: option `%s' requires an argument\n", + argv[0], argv[optind - 1]); + + nextchar += strlen(nextchar); + return optstring[0] == ':' ? ':' : '?'; + } + } + + nextchar += strlen(nextchar); + + if(longind != NULL) { + *longind = option_index; + } + + if(pfound->flag) { + *(pfound->flag) = pfound->val; + return 0; + } + + return pfound->val; + } + + nextchar = NULL; + return 'W'; /* Let the application handle it. */ + } + + if(temp[1] == ':') { + if(temp[2] == ':') { + /* This is an option that accepts an argument optionally. */ + if(*nextchar != '\0') { + optarg = nextchar; + optind++; + } else { + optarg = NULL; + } + + nextchar = NULL; + } else { + /* This is an option that requires an argument. */ + if(*nextchar != '\0') { + optarg = nextchar; + /* If we end this ARGV-element by taking the rest as an arg, + we must advance to the next element now. */ + optind++; + } else if(optind == argc) { + if(opterr) { + /* 1003.2 specifies the format of this message. */ + fprintf(stderr, + "%s: option requires an argument -- %c\n", + argv[0], c); + } + + optopt = c; + + if(optstring[0] == ':') { + c = ':'; + } else { + c = '?'; + } + } else + /* We already incremented `optind' once; + increment it again when taking next ARGV-elt as argument. */ + { + optarg = argv[optind++]; + } + + nextchar = NULL; + } + } + + return c; } - } - - /* Look at and handle the next short option-character. */ - - { - char c = *nextchar++; - char *temp = my_index (optstring, c); - - /* Increment `optind' when we start to process its last character. */ - if (*nextchar == '\0') - ++optind; - - if (temp == NULL || c == ':') - { - if (opterr) - { - if (posixly_correct) - /* 1003.2 specifies the format of this message. */ - fprintf (stderr, "%s: illegal option -- %c\n", - argv[0], c); - else - fprintf (stderr, "%s: invalid option -- %c\n", - argv[0], c); - } - optopt = c; - return '?'; - } - /* Convenience. Treat POSIX -W foo same as long option --foo */ - if (temp[0] == 'W' && temp[1] == ';') - { - char *nameend; - const struct option *p; - const struct option *pfound = NULL; - int exact = 0; - int ambig = 0; - int indfound = 0; - int option_index; - - /* This is an option that requires an argument. */ - if (*nextchar != '\0') - { - optarg = nextchar; - /* If we end this ARGV-element by taking the rest as an arg, - we must advance to the next element now. */ - optind++; - } - else if (optind == argc) - { - if (opterr) - { - /* 1003.2 specifies the format of this message. */ - fprintf (stderr, "%s: option requires an argument -- %c\n", - argv[0], c); - } - optopt = c; - if (optstring[0] == ':') - c = ':'; - else - c = '?'; - return c; - } - else - /* We already incremented `optind' once; - increment it again when taking next ARGV-elt as argument. */ - optarg = argv[optind++]; - - /* optarg is now the argument, see if it's in the - table of longopts. */ - - for (nextchar = nameend = optarg; *nameend && *nameend != '='; nameend++) - /* Do nothing. */ ; - - /* Test all long options for either exact match - or abbreviated matches. */ - for (p = longopts, option_index = 0; p->name; p++, option_index++) - if (!strncmp (p->name, nextchar, nameend - nextchar)) - { - if ((unsigned int) (nameend - nextchar) == strlen (p->name)) - { - /* Exact match found. */ - pfound = p; - indfound = option_index; - exact = 1; - break; - } - else if (pfound == NULL) - { - /* First nonexact match found. */ - pfound = p; - indfound = option_index; - } - else - /* Second or later nonexact match found. */ - ambig = 1; - } - if (ambig && !exact) - { - if (opterr) - fprintf (stderr, "%s: option `-W %s' is ambiguous\n", - argv[0], argv[optind]); - nextchar += strlen (nextchar); - optind++; - return '?'; - } - if (pfound != NULL) - { - option_index = indfound; - if (*nameend) - { - /* Don't test has_arg with >, because some C compilers don't - allow it to be used on enums. */ - if (pfound->has_arg) - optarg = nameend + 1; - else - { - if (opterr) - fprintf (stderr, - "%s: option `-W %s' doesn't allow an argument\n", - argv[0], pfound->name); - - nextchar += strlen (nextchar); - return '?'; - } - } - else if (pfound->has_arg == 1) - { - if (optind < argc) - optarg = argv[optind++]; - else - { - if (opterr) - fprintf (stderr, - "%s: option `%s' requires an argument\n", - argv[0], argv[optind - 1]); - nextchar += strlen (nextchar); - return optstring[0] == ':' ? ':' : '?'; - } - } - nextchar += strlen (nextchar); - if (longind != NULL) - *longind = option_index; - if (pfound->flag) - { - *(pfound->flag) = pfound->val; - return 0; - } - return pfound->val; - } - nextchar = NULL; - return 'W'; /* Let the application handle it. */ - } - if (temp[1] == ':') - { - if (temp[2] == ':') - { - /* This is an option that accepts an argument optionally. */ - if (*nextchar != '\0') - { - optarg = nextchar; - optind++; - } - else - optarg = NULL; - nextchar = NULL; - } - else - { - /* This is an option that requires an argument. */ - if (*nextchar != '\0') - { - optarg = nextchar; - /* If we end this ARGV-element by taking the rest as an arg, - we must advance to the next element now. */ - optind++; - } - else if (optind == argc) - { - if (opterr) - { - /* 1003.2 specifies the format of this message. */ - fprintf (stderr, - "%s: option requires an argument -- %c\n", - argv[0], c); - } - optopt = c; - if (optstring[0] == ':') - c = ':'; - else - c = '?'; - } - else - /* We already incremented `optind' once; - increment it again when taking next ARGV-elt as argument. */ - optarg = argv[optind++]; - nextchar = NULL; - } - } - return c; - } } int -getopt (argc, argv, optstring) - int argc; - char *const *argv; - const char *optstring; +getopt(argc, argv, optstring) +int argc; +char *const *argv; +const char *optstring; { - return _getopt_internal (argc, argv, optstring, - (const struct option *) 0, - (int *) 0, - 0); + return _getopt_internal(argc, argv, optstring, + (const struct option *) 0, + (int *) 0, + 0); } -#endif /* Not ELIDE_CODE. */ +#endif /* Not ELIDE_CODE. */ #ifdef TEST @@ -981,68 +980,72 @@ getopt (argc, argv, optstring) the above definition of `getopt'. */ int -main (argc, argv) - int argc; - char **argv; +main(argc, argv) +int argc; +char **argv; { - int c; - int digit_optind = 0; + int c; + int digit_optind = 0; - while (1) - { - int this_option_optind = optind ? optind : 1; + while(1) { + int this_option_optind = optind ? optind : 1; - c = getopt (argc, argv, "abc:d:0123456789"); - if (c == -1) - break; + c = getopt(argc, argv, "abc:d:0123456789"); - switch (c) - { - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - if (digit_optind != 0 && digit_optind != this_option_optind) - printf ("digits occur in two different argv-elements.\n"); - digit_optind = this_option_optind; - printf ("option %c\n", c); - break; + if(c == -1) { + break; + } - case 'a': - printf ("option a\n"); - break; + switch(c) { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + if(digit_optind != 0 && digit_optind != this_option_optind) { + printf("digits occur in two different argv-elements.\n"); + } - case 'b': - printf ("option b\n"); - break; + digit_optind = this_option_optind; + printf("option %c\n", c); + break; - case 'c': - printf ("option c with value `%s'\n", optarg); - break; + case 'a': + printf("option a\n"); + break; - case '?': - break; + case 'b': + printf("option b\n"); + break; - default: - printf ("?? getopt returned character code 0%o ??\n", c); + case 'c': + printf("option c with value `%s'\n", optarg); + break; + + case '?': + break; + + default: + printf("?? getopt returned character code 0%o ??\n", c); + } } - } - if (optind < argc) - { - printf ("non-option ARGV-elements: "); - while (optind < argc) - printf ("%s ", argv[optind++]); - printf ("\n"); - } + if(optind < argc) { + printf("non-option ARGV-elements: "); - exit (0); + while(optind < argc) { + printf("%s ", argv[optind++]); + } + + printf("\n"); + } + + exit(0); } #endif /* TEST */ diff --git a/src/getopt.h b/src/getopt.h index ddf6fdd..e9a7040 100644 --- a/src/getopt.h +++ b/src/getopt.h @@ -1,3 +1,6 @@ +#ifndef TINC_GETOPT_H +#define TINC_GETOPT_H + /* Declarations for getopt. Copyright (C) 1989,90,91,92,93,94,96,97 Free Software Foundation, Inc. @@ -22,7 +25,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #ifndef _GETOPT_H #define _GETOPT_H 1 -#ifdef __cplusplus +#ifdef __cplusplus extern "C" { #endif @@ -63,9 +66,9 @@ extern int optopt; zero. The field `has_arg' is: - no_argument (or 0) if the option does not take an argument, - required_argument (or 1) if the option requires an argument, - optional_argument (or 2) if the option takes an optional argument. + no_argument (or 0) if the option does not take an argument, + required_argument (or 1) if the option requires an argument, + optional_argument (or 2) if the option takes an optional argument. If the field `flag' is not NULL, it points to a variable that is set to the value given in the field `val' when the option is found, but @@ -78,56 +81,55 @@ extern int optopt; one). For long options that have a zero `flag' field, `getopt' returns the contents of the `val' field. */ -struct option -{ +struct option { #if defined (__STDC__) && __STDC__ - const char *name; + const char *name; #else - char *name; + char *name; #endif - /* has_arg can't be an enum because some compilers complain about - type mismatches in all the code that assumes it is an int. */ - int has_arg; - int *flag; - int val; + /* has_arg can't be an enum because some compilers complain about + type mismatches in all the code that assumes it is an int. */ + int has_arg; + int *flag; + int val; }; /* Names for the values of the `has_arg' field of `struct option'. */ -#define no_argument 0 -#define required_argument 1 -#define optional_argument 2 +#define no_argument 0 +#define required_argument 1 +#define optional_argument 2 #if defined (__STDC__) && __STDC__ #ifdef __GNU_LIBRARY__ /* Many other libraries have conflicting prototypes for getopt, with differences in the consts, in stdlib.h. To avoid compilation errors, only prototype getopt for the GNU C library. */ -extern int getopt (int argc, char *const *argv, const char *shortopts); +extern int getopt(int argc, char *const *argv, const char *shortopts); #else /* not __GNU_LIBRARY__ */ -extern int getopt (); +extern int getopt(); #endif /* __GNU_LIBRARY__ */ -extern int getopt_long (int argc, char *const *argv, const char *shortopts, - const struct option *longopts, int *longind); -extern int getopt_long_only (int argc, char *const *argv, - const char *shortopts, - const struct option *longopts, int *longind); +extern int getopt_long(int argc, char *const *argv, const char *shortopts, + const struct option *longopts, int *longind); +extern int getopt_long_only(int argc, char *const *argv, + const char *shortopts, + const struct option *longopts, int *longind); /* Internal only. Users should not call this directly. */ -extern int _getopt_internal (int argc, char *const *argv, - const char *shortopts, - const struct option *longopts, int *longind, - int long_only); +extern int _getopt_internal(int argc, char *const *argv, + const char *shortopts, + const struct option *longopts, int *longind, + int long_only); #else /* not __STDC__ */ -extern int getopt (); -extern int getopt_long (); -extern int getopt_long_only (); +extern int getopt(); +extern int getopt_long(); +extern int getopt_long_only(); -extern int _getopt_internal (); +extern int _getopt_internal(); #endif /* __STDC__ */ -#ifdef __cplusplus +#ifdef __cplusplus } #endif -#endif /* _GETOPT_H */ +#endif diff --git a/src/getopt1.c b/src/getopt1.c index 19605a5..3ccb150 100644 --- a/src/getopt1.c +++ b/src/getopt1.c @@ -60,19 +60,19 @@ with this program; if not, write to the Free Software Foundation, Inc., #include #endif -#ifndef NULL +#ifndef NULL #define NULL 0 #endif int -getopt_long (argc, argv, options, long_options, opt_index) - int argc; - char *const *argv; - const char *options; - const struct option *long_options; - int *opt_index; +getopt_long(argc, argv, options, long_options, opt_index) +int argc; +char *const *argv; +const char *options; +const struct option *long_options; +int *opt_index; { - return _getopt_internal (argc, argv, options, long_options, opt_index, 0); + return _getopt_internal(argc, argv, options, long_options, opt_index, 0); } /* Like getopt_long, but '-' as well as '--' can indicate a long option. @@ -81,109 +81,115 @@ getopt_long (argc, argv, options, long_options, opt_index) instead. */ int -getopt_long_only (argc, argv, options, long_options, opt_index) - int argc; - char *const *argv; - const char *options; - const struct option *long_options; - int *opt_index; +getopt_long_only(argc, argv, options, long_options, opt_index) +int argc; +char *const *argv; +const char *options; +const struct option *long_options; +int *opt_index; { - return _getopt_internal (argc, argv, options, long_options, opt_index, 1); + return _getopt_internal(argc, argv, options, long_options, opt_index, 1); } -#endif /* Not ELIDE_CODE. */ +#endif /* Not ELIDE_CODE. */ #ifdef TEST #include int -main (argc, argv) - int argc; - char **argv; +main(argc, argv) +int argc; +char **argv; { - int c; - int digit_optind = 0; + int c; + int digit_optind = 0; - while (1) - { - int this_option_optind = optind ? optind : 1; - int option_index = 0; - static struct option long_options[] = - { - {"add", 1, 0, 0}, - {"append", 0, 0, 0}, - {"delete", 1, 0, 0}, - {"verbose", 0, 0, 0}, - {"create", 0, 0, 0}, - {"file", 1, 0, 0}, - {0, 0, 0, 0} - }; + while(1) { + int this_option_optind = optind ? optind : 1; + int option_index = 0; + static struct option long_options[] = { + {"add", 1, 0, 0}, + {"append", 0, 0, 0}, + {"delete", 1, 0, 0}, + {"verbose", 0, 0, 0}, + {"create", 0, 0, 0}, + {"file", 1, 0, 0}, + {0, 0, 0, 0} + }; - c = getopt_long (argc, argv, "abc:d:0123456789", - long_options, &option_index); - if (c == -1) - break; + c = getopt_long(argc, argv, "abc:d:0123456789", + long_options, &option_index); - switch (c) - { - case 0: - printf ("option %s", long_options[option_index].name); - if (optarg) - printf (" with arg %s", optarg); - printf ("\n"); - break; + if(c == -1) { + break; + } - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - if (digit_optind != 0 && digit_optind != this_option_optind) - printf ("digits occur in two different argv-elements.\n"); - digit_optind = this_option_optind; - printf ("option %c\n", c); - break; + switch(c) { + case 0: + printf("option %s", long_options[option_index].name); - case 'a': - printf ("option a\n"); - break; + if(optarg) { + printf(" with arg %s", optarg); + } - case 'b': - printf ("option b\n"); - break; + printf("\n"); + break; - case 'c': - printf ("option c with value `%s'\n", optarg); - break; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + if(digit_optind != 0 && digit_optind != this_option_optind) { + printf("digits occur in two different argv-elements.\n"); + } - case 'd': - printf ("option d with value `%s'\n", optarg); - break; + digit_optind = this_option_optind; + printf("option %c\n", c); + break; - case '?': - break; + case 'a': + printf("option a\n"); + break; - default: - printf ("?? getopt returned character code 0%o ??\n", c); + case 'b': + printf("option b\n"); + break; + + case 'c': + printf("option c with value `%s'\n", optarg); + break; + + case 'd': + printf("option d with value `%s'\n", optarg); + break; + + case '?': + break; + + default: + printf("?? getopt returned character code 0%o ??\n", c); + } } - } - if (optind < argc) - { - printf ("non-option ARGV-elements: "); - while (optind < argc) - printf ("%s ", argv[optind++]); - printf ("\n"); - } + if(optind < argc) { + printf("non-option ARGV-elements: "); - exit (0); + while(optind < argc) { + printf("%s ", argv[optind++]); + } + + printf("\n"); + } + + exit(0); } #endif /* TEST */ diff --git a/src/graph.c b/src/graph.c index 1f1fdb3..a774eac 100644 --- a/src/graph.c +++ b/src/graph.c @@ -68,15 +68,17 @@ static void mst_kruskal(void) { /* Clear MST status on connections */ - for list_each(connection_t, c, connection_list) + for list_each(connection_t, c, connection_list) { c->status.mst = false; + } logger(DEBUG_SCARY_THINGS, LOG_DEBUG, "Running Kruskal's algorithm:"); /* Clear visited status on nodes */ - for splay_each(node_t, n, node_tree) + for splay_each(node_t, n, node_tree) { n->status.visited = false; + } /* Starting point */ @@ -100,11 +102,13 @@ static void mst_kruskal(void) { e->from->status.visited = true; e->to->status.visited = true; - if(e->connection) + if(e->connection) { e->connection->status.mst = true; + } - if(e->reverse->connection) + if(e->reverse->connection) { e->reverse->connection->status.mst = true; + } logger(DEBUG_SCARY_THINGS, LOG_DEBUG, " Adding edge %s - %s weight %d", e->from->name, e->to->name, e->weight); @@ -145,20 +149,22 @@ static void sssp_bfs(void) { for list_each(node_t, n, todo_list) { /* "n" is the node from which we start */ logger(DEBUG_SCARY_THINGS, LOG_DEBUG, " Examining edges from %s", n->name); - if(n->distance < 0) + if(n->distance < 0) { abort(); + } for splay_each(edge_t, e, n->edge_tree) { /* "e" is the edge connected to "from" */ - if(!e->reverse || e->to == myself) + if(!e->reverse || e->to == myself) { continue; + } /* Situation: - / - / + / + / ----->(n)---e-->(e->to) - \ - \ + \ + \ Where e is an edge, (n) and (e->to) are nodes. n->address is set to the e->address of the edge left of n to n. @@ -172,14 +178,16 @@ static void sssp_bfs(void) { bool indirect = n->status.indirect || e->options & OPTION_INDIRECT; if(e->to->status.visited - && (!e->to->status.indirect || indirect) - && (e->to->distance != n->distance + 1 || e->weight >= e->to->prevedge->weight)) + && (!e->to->status.indirect || indirect) + && (e->to->distance != n->distance + 1 || e->weight >= e->to->prevedge->weight)) { continue; + } // Only update nexthop if it doesn't increase the path length - if(!e->to->status.visited || (e->to->distance == n->distance + 1 && e->weight >= e->to->prevedge->weight)) + if(!e->to->status.visited || (e->to->distance == n->distance + 1 && e->weight >= e->to->prevedge->weight)) { e->to->nexthop = (n->nexthop == myself) ? e->to : n->nexthop; + } e->to->status.visited = true; e->to->status.indirect = indirect; @@ -188,8 +196,9 @@ static void sssp_bfs(void) { e->to->options = e->options; e->to->distance = n->distance + 1; - if(!e->to->status.reachable || (e->to->address.sa.sa_family == AF_UNSPEC && e->address.sa.sa_family != AF_UNKNOWN)) + if(!e->to->status.reachable || (e->to->address.sa.sa_family == AF_UNSPEC && e->address.sa.sa_family != AF_UNKNOWN)) { update_node_udp(e->to, &e->address); + } list_insert_tail(todo_list, e->to); } @@ -207,6 +216,7 @@ static void check_reachability(void) { int reachable_count = 0; int became_reachable_count = 0; int became_unreachable_count = 0; + for splay_each(node_t, n, node_tree) { if(n->status.visited != n->status.reachable) { n->status.reachable = !n->status.reachable; @@ -214,26 +224,33 @@ static void check_reachability(void) { if(n->status.reachable) { logger(DEBUG_TRAFFIC, LOG_DEBUG, "Node %s (%s) became reachable", - n->name, n->hostname); - if (n != myself) + n->name, n->hostname); + + if(n != myself) { became_reachable_count++; + } } else { logger(DEBUG_TRAFFIC, LOG_DEBUG, "Node %s (%s) became unreachable", - n->name, n->hostname); - if (n != myself) + n->name, n->hostname); + + if(n != myself) { became_unreachable_count++; + } } - if(experimental && OPTION_VERSION(n->options) >= 2) + if(experimental && OPTION_VERSION(n->options) >= 2) { n->status.sptps = true; + } /* TODO: only clear status.validkey if node is unreachable? */ n->status.validkey = false; + if(n->status.sptps) { sptps_stop(&n->sptps); n->status.waitingforkey = false; } + n->last_req_key = 0; n->status.udp_confirmed = false; @@ -269,24 +286,27 @@ static void check_reachability(void) { if(!n->status.reachable) { update_node_udp(n, NULL); - memset(&n->status, 0, sizeof n->status); + memset(&n->status, 0, sizeof(n->status)); n->options = 0; } else if(n->connection) { // Speed up UDP probing by sending our key. - if(!n->status.sptps) + if(!n->status.sptps) { send_ans_key(n); + } } } - if(n->status.reachable && n != myself) + if(n->status.reachable && n != myself) { reachable_count++; + } } - if (device_standby) { - if (reachable_count == 0 && became_unreachable_count > 0) + if(device_standby) { + if(reachable_count == 0 && became_unreachable_count > 0) { device_disable(); - else if (reachable_count > 0 && reachable_count == became_reachable_count) + } else if(reachable_count > 0 && reachable_count == became_reachable_count) { device_enable(); + } } } diff --git a/src/graph.h b/src/graph.h index fa521f5..fafffcb 100644 --- a/src/graph.h +++ b/src/graph.h @@ -1,3 +1,6 @@ +#ifndef TINC_GRAPH_H +#define TINC_GRAPH_H + /* graph.h -- header for graph.c Copyright (C) 2001-2012 Guus Sliepen , @@ -18,10 +21,7 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#ifndef __TINC_GRAPH_H__ -#define __TINC_GRAPH_H__ - extern void graph(void); extern void dump_graph(void); -#endif /* __TINC_GRAPH_H__ */ +#endif diff --git a/src/hash.c b/src/hash.c index 50934d9..63b8f54 100644 --- a/src/hash.c +++ b/src/hash.c @@ -27,36 +27,44 @@ static uint32_t hash_function(const void *p, size_t len) { const uint8_t *q = p; uint32_t hash = 0; + while(true) { - for(int i = len > 4 ? 4 : len; --i;) + for(int i = len > 4 ? 4 : len; --i;) { hash += (uint32_t)q[len - i] << (8 * i); + } + hash *= 0x9e370001UL; // Golden ratio prime. - if(len <= 4) + + if(len <= 4) { break; + } + len -= 4; } + return hash; } /* Map 32 bits int onto 0..n-1, without throwing away too many bits if n is 2^8 or 2^16 */ static uint32_t modulo(uint32_t hash, size_t n) { - if(n == 0x100) + if(n == 0x100) { return (hash >> 24) ^ ((hash >> 16) & 0xff) ^ ((hash >> 8) & 0xff) ^ (hash & 0xff); - else if(n == 0x10000) + } else if(n == 0x10000) { return (hash >> 16) ^ (hash & 0xffff); - else + } else { return hash % n; + } } /* (De)allocation */ hash_t *hash_alloc(size_t n, size_t size) { - hash_t *hash = xzalloc(sizeof *hash); + hash_t *hash = xzalloc(sizeof(*hash)); hash->n = n; hash->size = size; hash->keys = xzalloc(hash->n * hash->size); - hash->values = xzalloc(hash->n * sizeof *hash->values); + hash->values = xzalloc(hash->n * sizeof(*hash->values)); return hash; } @@ -76,16 +84,21 @@ void hash_insert(hash_t *hash, const void *key, const void *value) { void *hash_search(const hash_t *hash, const void *key) { uint32_t i = modulo(hash_function(key, hash->size), hash->n); + if(hash->values[i] && !memcmp(key, hash->keys + i * hash->size, hash->size)) { return (void *)hash->values[i]; } + return NULL; } void *hash_search_or_insert(hash_t *hash, const void *key, const void *value) { uint32_t i = modulo(hash_function(key, hash->size), hash->n); - if(hash->values[i] && !memcmp(key, hash->keys + i * hash->size, hash->size)) + + if(hash->values[i] && !memcmp(key, hash->keys + i * hash->size, hash->size)) { return (void *)hash->values[i]; + } + memcpy(hash->keys + i * hash->size, key, hash->size); hash->values[i] = value; return NULL; @@ -101,14 +114,15 @@ void hash_delete(hash_t *hash, const void *key) { /* Utility functions */ void hash_clear(hash_t *hash) { - memset(hash->values, 0, hash->n * sizeof *hash->values); + memset(hash->values, 0, hash->n * sizeof(*hash->values)); } void hash_resize(hash_t *hash, size_t n) { hash->keys = xrealloc(hash->keys, n * hash->size); - hash->values = xrealloc(hash->values, n * sizeof *hash->values); + hash->values = xrealloc(hash->values, n * sizeof(*hash->values)); + if(n > hash->n) { memset(hash->keys + hash->n * hash->size, 0, (n - hash->n) * hash->size); - memset(hash->values + hash->n, 0, (n - hash->n) * sizeof *hash->values); + memset(hash->values + hash->n, 0, (n - hash->n) * sizeof(*hash->values)); } } diff --git a/src/hash.h b/src/hash.h index 30a15fb..e4b1499 100644 --- a/src/hash.h +++ b/src/hash.h @@ -1,3 +1,6 @@ +#ifndef TINC_HASH_H +#define TINC_HASH_H + /* hash.h -- header file for hash.c Copyright (C) 2012 Guus Sliepen @@ -17,9 +20,6 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#ifndef __TINC_HASH_H__ -#define __TINC_HASH_H__ - typedef struct hash_t { size_t n; size_t size; @@ -27,7 +27,7 @@ typedef struct hash_t { const void **values; } hash_t; -extern hash_t *hash_alloc(size_t n, size_t size) __attribute__ ((__malloc__)); +extern hash_t *hash_alloc(size_t n, size_t size) __attribute__((__malloc__)); extern void hash_free(hash_t *); extern void hash_insert(hash_t *, const void *key, const void *value); @@ -39,4 +39,4 @@ extern void *hash_search_or_insert(hash_t *, const void *key, const void *value) extern void hash_clear(hash_t *); extern void hash_resize(hash_t *, size_t n); -#endif /* __TINC_HASH_H__ */ +#endif diff --git a/src/have.h b/src/have.h index faa4c9e..402f802 100644 --- a/src/have.h +++ b/src/have.h @@ -1,3 +1,6 @@ +#ifndef TINC_HAVE_H +#define TINC_HAVE_H + /* have.h -- include headers which are known to exist Copyright (C) 1998-2005 Ivo Timmermans @@ -18,9 +21,6 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#ifndef __TINC_HAVE_H__ -#define __TINC_HAVE_H__ - #ifdef HAVE_MINGW #define WINVER WindowsXP #define WIN32_LEAN_AND_MEAN @@ -213,4 +213,4 @@ #define SLASH "/" #endif -#endif /* __TINC_SYSTEM_H__ */ +#endif diff --git a/src/ifconfig.c b/src/ifconfig.c index 0b99402..4b47ad1 100644 --- a/src/ifconfig.c +++ b/src/ifconfig.c @@ -86,112 +86,219 @@ bool ifconfig_footer(FILE *out) { static subnet_t ipv4, ipv6; void ifconfig_address(FILE *out, const char *value) { - subnet_t address = {}; + subnet_t address = {0}; char address_str[MAXNETSTR]; - if(!str2net(&address, value) || !net2str(address_str, sizeof address_str, &address)) { + + if(!str2net(&address, value) || !net2str(address_str, sizeof(address_str), &address)) { fprintf(stderr, "Could not parse address in Ifconfig statement\n"); return; } + switch(address.type) { - case SUBNET_IPV4: ipv4 = address; break; - case SUBNET_IPV6: ipv6 = address; break; - default: return; + case SUBNET_IPV4: + ipv4 = address; + break; + + case SUBNET_IPV6: + ipv6 = address; + break; + + default: + return; } + #if defined(HAVE_LINUX) + switch(address.type) { - case SUBNET_MAC: fprintf(out, "ip link set \"$INTERFACE\" address %s\n", address_str); break; - case SUBNET_IPV4: fprintf(out, "ip addr replace %s dev \"$INTERFACE\"\n", address_str); break; - case SUBNET_IPV6: fprintf(out, "ip addr replace %s dev \"$INTERFACE\"\n", address_str); break; - default: return; + case SUBNET_MAC: + fprintf(out, "ip link set \"$INTERFACE\" address %s\n", address_str); + break; + + case SUBNET_IPV4: + fprintf(out, "ip addr replace %s dev \"$INTERFACE\"\n", address_str); + break; + + case SUBNET_IPV6: + fprintf(out, "ip addr replace %s dev \"$INTERFACE\"\n", address_str); + break; + + default: + return; } + #elif defined(HAVE_MINGW) || defined(HAVE_CYGWIN) + switch(address.type) { - case SUBNET_MAC: fprintf(out, "ip link set \"$INTERFACE\" address %s\n", address_str); break; - case SUBNET_IPV4: fprintf(out, "netsh inetface ipv4 set address \"$INTERFACE\" static %s\n", address_str); break; - case SUBNET_IPV6: fprintf(out, "netsh inetface ipv6 set address \"$INTERFACE\" static %s\n", address_str); break; - default: return; + case SUBNET_MAC: + fprintf(out, "ip link set \"$INTERFACE\" address %s\n", address_str); + break; + + case SUBNET_IPV4: + fprintf(out, "netsh inetface ipv4 set address \"$INTERFACE\" static %s\n", address_str); + break; + + case SUBNET_IPV6: + fprintf(out, "netsh inetface ipv6 set address \"$INTERFACE\" static %s\n", address_str); + break; + + default: + return; } + #else // assume BSD + switch(address.type) { - case SUBNET_MAC: fprintf(out, "ifconfig \"$INTERFACE\" link %s\n", address_str); break; - case SUBNET_IPV4: fprintf(out, "ifconfig \"$INTERFACE\" %s\n", address_str); break; - case SUBNET_IPV6: fprintf(out, "ifconfig \"$INTERFACE\" inet6 %s\n", address_str); break; - default: return; + case SUBNET_MAC: + fprintf(out, "ifconfig \"$INTERFACE\" link %s\n", address_str); + break; + + case SUBNET_IPV4: + fprintf(out, "ifconfig \"$INTERFACE\" %s\n", address_str); + break; + + case SUBNET_IPV6: + fprintf(out, "ifconfig \"$INTERFACE\" inet6 %s\n", address_str); + break; + + default: + return; } + #endif } void ifconfig_route(FILE *out, const char *value) { - subnet_t subnet = {}, gateway = {}; + subnet_t subnet = {0}, gateway = {0}; char subnet_str[MAXNETSTR] = "", gateway_str[MAXNETSTR] = ""; char *sep = strchr(value, ' '); - if(sep) + + if(sep) { *sep++ = 0; - if(!str2net(&subnet, value) || !net2str(subnet_str, sizeof subnet_str, &subnet) || subnet.type == SUBNET_MAC) { + } + + if(!str2net(&subnet, value) || !net2str(subnet_str, sizeof(subnet_str), &subnet) || subnet.type == SUBNET_MAC) { fprintf(stderr, "Could not parse subnet in Route statement\n"); return; } + if(sep) { - if(!str2net(&gateway, sep) || !net2str(gateway_str, sizeof gateway_str, &gateway) || gateway.type != subnet.type) { + if(!str2net(&gateway, sep) || !net2str(gateway_str, sizeof(gateway_str), &gateway) || gateway.type != subnet.type) { fprintf(stderr, "Could not parse gateway in Route statement\n"); return; } - char *slash = strchr(gateway_str, '/'); if(slash) *slash = 0; + + char *slash = strchr(gateway_str, '/'); + + if(slash) { + *slash = 0; + } } + #if defined(HAVE_LINUX) + if(*gateway_str) { switch(subnet.type) { - case SUBNET_IPV4: fprintf(out, "ip route add %s via %s dev \"$INTERFACE\"\n", subnet_str, gateway_str); break; - case SUBNET_IPV6: fprintf(out, "ip route add %s via %s dev \"$INTERFACE\"\n", subnet_str, gateway_str); break; - default: return; + case SUBNET_IPV4: + fprintf(out, "ip route add %s via %s dev \"$INTERFACE\"\n", subnet_str, gateway_str); + break; + + case SUBNET_IPV6: + fprintf(out, "ip route add %s via %s dev \"$INTERFACE\"\n", subnet_str, gateway_str); + break; + + default: + return; } } else { switch(subnet.type) { - case SUBNET_IPV4: fprintf(out, "ip route add %s dev \"$INTERFACE\"\n", subnet_str); break; - case SUBNET_IPV6: fprintf(out, "ip route add %s dev \"$INTERFACE\"\n", subnet_str); break; - default: return; + case SUBNET_IPV4: + fprintf(out, "ip route add %s dev \"$INTERFACE\"\n", subnet_str); + break; + + case SUBNET_IPV6: + fprintf(out, "ip route add %s dev \"$INTERFACE\"\n", subnet_str); + break; + + default: + return; } } + #elif defined(HAVE_MINGW) || defined(HAVE_CYGWIN) + if(*gateway_str) { switch(subnet.type) { - case SUBNET_IPV4: fprintf(out, "netsh inetface ipv4 add route %s \"%%INTERFACE%%\" %s\n", subnet_str, gateway_str); break; - case SUBNET_IPV6: fprintf(out, "netsh inetface ipv6 add route %s \"%%INTERFACE%%\" %s\n", subnet_str, gateway_str); break; - default: return; + case SUBNET_IPV4: + fprintf(out, "netsh inetface ipv4 add route %s \"%%INTERFACE%%\" %s\n", subnet_str, gateway_str); + break; + + case SUBNET_IPV6: + fprintf(out, "netsh inetface ipv6 add route %s \"%%INTERFACE%%\" %s\n", subnet_str, gateway_str); + break; + + default: + return; } } else { switch(subnet.type) { - case SUBNET_IPV4: fprintf(out, "netsh inetface ipv4 add route %s \"%%INTERFACE%%\"\n", subnet_str); break; - case SUBNET_IPV6: fprintf(out, "netsh inetface ipv6 add route %s \"%%INTERFACE%%\"\n", subnet_str); break; - default: return; + case SUBNET_IPV4: + fprintf(out, "netsh inetface ipv4 add route %s \"%%INTERFACE%%\"\n", subnet_str); + break; + + case SUBNET_IPV6: + fprintf(out, "netsh inetface ipv6 add route %s \"%%INTERFACE%%\"\n", subnet_str); + break; + + default: + return; } } + #else // assume BSD + if(!*gateway_str) { switch(subnet.type) { - case SUBNET_IPV4: - if(!ipv4.type) { - fprintf(stderr, "Route requested but no Ifconfig\n"); - return; - } - net2str(gateway_str, sizeof gateway_str, &ipv4); - break; - case SUBNET_IPV6: - if(!ipv6.type) { - fprintf(stderr, "Route requested but no Ifconfig\n"); - return; - } - net2str(gateway_str, sizeof gateway_str, &ipv6); - break; - default: return; + case SUBNET_IPV4: + if(!ipv4.type) { + fprintf(stderr, "Route requested but no Ifconfig\n"); + return; + } + + net2str(gateway_str, sizeof(gateway_str), &ipv4); + break; + + case SUBNET_IPV6: + if(!ipv6.type) { + fprintf(stderr, "Route requested but no Ifconfig\n"); + return; + } + + net2str(gateway_str, sizeof(gateway_str), &ipv6); + break; + + default: + return; + } + + char *slash = strchr(gateway_str, '/'); + + if(slash) { + *slash = 0; } - char *slash = strchr(gateway_str, '/'); if(slash) *slash = 0; } switch(subnet.type) { - case SUBNET_IPV4: fprintf(out, "route add %s %s\n", subnet_str, gateway_str); break; - case SUBNET_IPV6: fprintf(out, "route add -inet6 %s %s\n", subnet_str, gateway_str); break; - default: return; + case SUBNET_IPV4: + fprintf(out, "route add %s %s\n", subnet_str, gateway_str); + break; + + case SUBNET_IPV6: + fprintf(out, "route add -inet6 %s %s\n", subnet_str, gateway_str); + break; + + default: + return; } + #endif } diff --git a/src/ifconfig.h b/src/ifconfig.h index 3dbf9f6..854780b 100644 --- a/src/ifconfig.h +++ b/src/ifconfig.h @@ -1,3 +1,6 @@ +#ifndef TINC_IFCONFIG_H +#define TINC_IFCONFIG_H + /* ifconfig.h -- header for ifconfig.c. Copyright (C) 2016 Guus Sliepen @@ -17,9 +20,6 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#ifndef __TINC_IFCONFIG_H__ -#define __TINC_IFCONFIG_H__ - extern void ifconfig_dhcp(FILE *out); extern void ifconfig_dhcp6(FILE *out); extern void ifconfig_slaac(FILE *out); diff --git a/src/info.c b/src/info.c index 2a6934b..758c0d1 100644 --- a/src/info.c +++ b/src/info.c @@ -28,17 +28,24 @@ #include "xalloc.h" void logger(int level, int priority, const char *format, ...) { + (void)level; + (void)priority; va_list ap; + va_start(ap, format); vfprintf(stderr, format, ap); va_end(ap); + fputc('\n', stderr); } char *strip_weight(char *netstr) { int len = strlen(netstr); - if(len >= 3 && !strcmp(netstr + len - 3, "#10")) + + if(len >= 3 && !strcmp(netstr + len - 3, "#10")) { netstr[len - 3] = 0; + } + return netstr; } @@ -67,14 +74,17 @@ static int info_node(int fd, const char *item) { } status_union; node_status_t status; long int last_state_change; + int udp_ping_rtt; + uint64_t in_packets, in_bytes, out_packets, out_bytes; - while(recvline(fd, line, sizeof line)) { - int n = sscanf(line, "%d %d %4095s %4095s %4095s port %4095s %d %d %d %d %x %"PRIx32" %4095s %4095s %d %hd %hd %hd %ld", &code, &req, node, id, host, port, &cipher, &digest, &maclength, &compression, &options, &status_union.raw, nexthop, via, &distance, &pmtu, &minmtu, &maxmtu, &last_state_change); + while(recvline(fd, line, sizeof(line))) { + int n = sscanf(line, "%d %d %4095s %4095s %4095s port %4095s %d %d %d %d %x %"PRIx32" %4095s %4095s %d %hd %hd %hd %ld %d %"PRIu64" %"PRIu64" %"PRIu64" %"PRIu64, &code, &req, node, id, host, port, &cipher, &digest, &maclength, &compression, &options, &status_union.raw, nexthop, via, &distance, &pmtu, &minmtu, &maxmtu, &last_state_change, &udp_ping_rtt, &in_packets, &in_bytes, &out_packets, &out_bytes); - if(n == 2) + if(n == 2) { break; + } - if(n != 19) { + if(n != 24) { fprintf(stderr, "Unable to parse node dump from tincd.\n"); return 1; } @@ -90,9 +100,10 @@ static int info_node(int fd, const char *item) { return 1; } - while(recvline(fd, line, sizeof line)) { - if(sscanf(line, "%d %d %4095s", &code, &req, node) == 2) + while(recvline(fd, line, sizeof(line))) { + if(sscanf(line, "%d %d %4095s", &code, &req, node) == 2) { break; + } } printf("Node: %s\n", item); @@ -102,88 +113,135 @@ static int info_node(int fd, const char *item) { char timestr[32] = "never"; time_t lsc_time = last_state_change; - if(last_state_change) - strftime(timestr, sizeof timestr, "%Y-%m-%d %H:%M:%S", localtime(&lsc_time)); + if(last_state_change) { + strftime(timestr, sizeof(timestr), "%Y-%m-%d %H:%M:%S", localtime(&lsc_time)); + } status = status_union.bits; - if(status.reachable) + if(status.reachable) { printf("Online since: %s\n", timestr); - else + } else { printf("Last seen: %s\n", timestr); + } printf("Status: "); - if(status.validkey) + + if(status.validkey) { printf(" validkey"); - if(status.visited) + } + + if(status.visited) { printf(" visited"); - if(status.reachable) + } + + if(status.reachable) { printf(" reachable"); - if(status.indirect) + } + + if(status.indirect) { printf(" indirect"); - if(status.sptps) + } + + if(status.sptps) { printf(" sptps"); - if(status.udp_confirmed) + } + + if(status.udp_confirmed) { printf(" udp_confirmed"); + } + printf("\n"); printf("Options: "); - if(options & OPTION_INDIRECT) + + if(options & OPTION_INDIRECT) { printf(" indirect"); - if(options & OPTION_TCPONLY) + } + + if(options & OPTION_TCPONLY) { printf(" tcponly"); - if(options & OPTION_PMTU_DISCOVERY) + } + + if(options & OPTION_PMTU_DISCOVERY) { printf(" pmtu_discovery"); - if(options & OPTION_CLAMP_MSS) + } + + if(options & OPTION_CLAMP_MSS) { printf(" clamp_mss"); + } + printf("\n"); printf("Protocol: %d.%d\n", PROT_MAJOR, OPTION_VERSION(options)); printf("Reachability: "); - if(!strcmp(host, "MYSELF")) + + if(!strcmp(host, "MYSELF")) { printf("can reach itself\n"); - else if(!status.reachable) + } else if(!status.reachable) { printf("unreachable\n"); - else if(strcmp(via, item)) + } else if(strcmp(via, item)) { printf("indirectly via %s\n", via); - else if(!status.validkey) + } else if(!status.validkey) { printf("unknown\n"); - else if(minmtu > 0) + } else if(minmtu > 0) { printf("directly with UDP\nPMTU: %d\n", pmtu); - else if(!strcmp(nexthop, item)) + + if(udp_ping_rtt != -1) { + printf("RTT: %d.%03d\n", udp_ping_rtt / 1000, udp_ping_rtt % 1000); + } + } else if(!strcmp(nexthop, item)) { printf("directly with TCP\n"); - else + } else { printf("none, forwarded via %s\n", nexthop); + } + + printf("RX: %"PRIu64" packets %"PRIu64" bytes\n", in_packets, in_bytes); + printf("TX: %"PRIu64" packets %"PRIu64" bytes\n", out_packets, out_bytes); // List edges printf("Edges: "); sendline(fd, "%d %d %s", CONTROL, REQ_DUMP_EDGES, item); - while(recvline(fd, line, sizeof line)) { + + while(recvline(fd, line, sizeof(line))) { int n = sscanf(line, "%d %d %4095s %4095s", &code, &req, from, to); - if(n == 2) + + if(n == 2) { break; + } + if(n != 4) { fprintf(stderr, "Unable to parse edge dump from tincd.\n%s\n", line); return 1; } - if(!strcmp(from, item)) + + if(!strcmp(from, item)) { printf(" %s", to); + } } + printf("\n"); // List subnets printf("Subnets: "); sendline(fd, "%d %d %s", CONTROL, REQ_DUMP_SUBNETS, item); - while(recvline(fd, line, sizeof line)) { + + while(recvline(fd, line, sizeof(line))) { int n = sscanf(line, "%d %d %4095s %4095s", &code, &req, subnet, from); - if(n == 2) + + if(n == 2) { break; + } + if(n != 4) { fprintf(stderr, "Unable to parse subnet dump from tincd.\n"); return 1; } - if(!strcmp(from, item)) + + if(!strcmp(from, item)) { printf(" %s", strip_weight(subnet)); + } } + printf("\n"); return 0; @@ -208,47 +266,63 @@ static int info_subnet(int fd, const char *item) { int code, req; sendline(fd, "%d %d %s", CONTROL, REQ_DUMP_SUBNETS, item); - while(recvline(fd, line, sizeof line)) { + + while(recvline(fd, line, sizeof(line))) { int n = sscanf(line, "%d %d %4095s %4095s", &code, &req, netstr, owner); - if(n == 2) + + if(n == 2) { break; + } if(n != 4 || !str2net(&subnet, netstr)) { fprintf(stderr, "Unable to parse subnet dump from tincd.\n"); return 1; } - if(find.type != subnet.type) + if(find.type != subnet.type) { continue; + } if(weight) { - if(find.weight != subnet.weight) + if(find.weight != subnet.weight) { continue; + } } if(find.type == SUBNET_IPV4) { if(address) { - if(maskcmp(&find.net.ipv4.address, &subnet.net.ipv4.address, subnet.net.ipv4.prefixlength)) + if(maskcmp(&find.net.ipv4.address, &subnet.net.ipv4.address, subnet.net.ipv4.prefixlength)) { continue; + } } else { - if(find.net.ipv4.prefixlength != subnet.net.ipv4.prefixlength) + if(find.net.ipv4.prefixlength != subnet.net.ipv4.prefixlength) { continue; - if(memcmp(&find.net.ipv4.address, &subnet.net.ipv4.address, sizeof subnet.net.ipv4)) + } + + if(memcmp(&find.net.ipv4.address, &subnet.net.ipv4.address, sizeof(subnet.net.ipv4))) { continue; + } } } else if(find.type == SUBNET_IPV6) { if(address) { - if(maskcmp(&find.net.ipv6.address, &subnet.net.ipv6.address, subnet.net.ipv6.prefixlength)) + if(maskcmp(&find.net.ipv6.address, &subnet.net.ipv6.address, subnet.net.ipv6.prefixlength)) { continue; + } } else { - if(find.net.ipv6.prefixlength != subnet.net.ipv6.prefixlength) + if(find.net.ipv6.prefixlength != subnet.net.ipv6.prefixlength) { continue; - if(memcmp(&find.net.ipv6.address, &subnet.net.ipv6.address, sizeof subnet.net.ipv6)) + } + + if(memcmp(&find.net.ipv6.address, &subnet.net.ipv6.address, sizeof(subnet.net.ipv6))) { continue; + } } - } if(find.type == SUBNET_MAC) { - if(memcmp(&find.net.mac.address, &subnet.net.mac.address, sizeof subnet.net.mac)) + } + + if(find.type == SUBNET_MAC) { + if(memcmp(&find.net.mac.address, &subnet.net.mac.address, sizeof(subnet.net.mac))) { continue; + } } found = true; @@ -257,10 +331,12 @@ static int info_subnet(int fd, const char *item) { } if(!found) { - if(address) + if(address) { fprintf(stderr, "Unknown address %s.\n", item); - else + } else { fprintf(stderr, "Unknown subnet %s.\n", item); + } + return 1; } @@ -268,10 +344,13 @@ static int info_subnet(int fd, const char *item) { } int info(int fd, const char *item) { - if(check_id(item)) + if(check_id(item)) { return info_node(fd, item); - if(strchr(item, '.') || strchr(item, ':')) + } + + if(strchr(item, '.') || strchr(item, ':')) { return info_subnet(fd, item); + } fprintf(stderr, "Argument is not a node name, subnet or address.\n"); return 1; diff --git a/src/info.h b/src/info.h index a3f387f..1b323e0 100644 --- a/src/info.h +++ b/src/info.h @@ -1,3 +1,6 @@ +#ifndef TINC_INFO_H +#define TINC_INFO_H + /* info.h -- header for info.c. Copyright (C) 2012 Guus Sliepen @@ -17,11 +20,7 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#ifndef __TINC_INFO_H__ -#define __TINC_INFO_H__ - extern int info(int fd, const char *item); extern char *strip_weight(char *); #endif - diff --git a/src/invitation.c b/src/invitation.c index 0dfd9ea..500f243 100644 --- a/src/invitation.c +++ b/src/invitation.c @@ -40,27 +40,41 @@ int addressfamily = AF_UNSPEC; static void scan_for_hostname(const char *filename, char **hostname, char **port) { - if(!filename || (*hostname && *port)) + if(!filename || (*hostname && *port)) { return; + } FILE *f = fopen(filename, "r"); - if(!f) - return; - while(fgets(line, sizeof line, f)) { - if(!rstrip(line)) + if(!f) { + return; + } + + while(fgets(line, sizeof(line), f)) { + if(!rstrip(line)) { continue; + } + char *p = line, *q; p += strcspn(p, "\t ="); - if(!*p) + + if(!*p) { continue; + } + q = p + strspn(p, "\t "); - if(*q == '=') + + if(*q == '=') { q += 1 + strspn(q + 1, "\t "); + } + *p = 0; p = q + strcspn(q, "\t "); - if(*p) + + if(*p) { *p++ = 0; + } + p += strspn(p, "\t "); p[strcspn(p, "\t ")] = 0; @@ -68,14 +82,16 @@ static void scan_for_hostname(const char *filename, char **hostname, char **port *port = xstrdup(q); } else if(!*hostname && !strcasecmp(line, "Address")) { *hostname = xstrdup(q); + if(*p) { free(*port); *port = xstrdup(p); } } - if(*hostname && *port) + if(*hostname && *port) { break; + } } fclose(f); @@ -90,13 +106,14 @@ char *get_my_hostname() { // Use first Address statement in own host config file if(check_id(name)) { - snprintf(filename, sizeof filename, "%s" SLASH "hosts" SLASH "%s", confbase, name); + snprintf(filename, sizeof(filename), "%s" SLASH "hosts" SLASH "%s", confbase, name); scan_for_hostname(filename, &hostname, &port); scan_for_hostname(tinc_conf, &hostname, &port); } - if(hostname) + if(hostname) { goto done; + } // If that doesn't work, guess externally visible hostname fprintf(stderr, "Trying to discover externally visible hostname...\n"); @@ -106,39 +123,54 @@ char *get_my_hostname() { while(aip) { int s = socket(aip->ai_family, aip->ai_socktype, aip->ai_protocol); + if(s >= 0) { if(connect(s, aip->ai_addr, aip->ai_addrlen)) { closesocket(s); s = -1; } } + if(s >= 0) { - send(s, request, sizeof request - 1, 0); - int len = recv(s, line, sizeof line - 1, MSG_WAITALL); + send(s, request, sizeof(request) - 1, 0); + int len = recv(s, line, sizeof(line) - 1, MSG_WAITALL); + if(len > 0) { line[len] = 0; - if(line[len - 1] == '\n') + + if(line[len - 1] == '\n') { line[--len] = 0; + } + char *p = strrchr(line, '\n'); - if(p && p[1]) + + if(p && p[1]) { hostname = xstrdup(p + 1); + } } + closesocket(s); - if(hostname) + + if(hostname) { break; + } } + aip = aip->ai_next; continue; } - if(ai) + if(ai) { freeaddrinfo(ai); + } // Check that the hostname is reasonable if(hostname) { for(char *p = hostname; *p; p++) { - if(isalnum(*p) || *p == '-' || *p == '.' || *p == ':') + if(isalnum(*p) || *p == '-' || *p == '.' || *p == ':') { continue; + } + // If not, forget it. free(hostname); hostname = NULL; @@ -149,33 +181,42 @@ char *get_my_hostname() { if(!tty) { if(!hostname) { fprintf(stderr, "Could not determine the external address or hostname. Please set Address manually.\n"); + free(port); return NULL; } + goto save; } again: fprintf(stderr, "Please enter your host's external address or hostname"); - if(hostname) + + if(hostname) { fprintf(stderr, " [%s]", hostname); + } + fprintf(stderr, ": "); - if(!fgets(line, sizeof line, stdin)) { + if(!fgets(line, sizeof(line), stdin)) { fprintf(stderr, "Error while reading stdin: %s\n", strerror(errno)); free(hostname); + free(port); return NULL; } if(!rstrip(line)) { - if(hostname) + if(hostname) { goto save; - else + } else { goto again; + } } for(char *p = line; *p; p++) { - if(isalnum(*p) || *p == '-' || *p == '.') + if(isalnum(*p) || *p == '-' || *p == '.') { continue; + } + fprintf(stderr, "Invalid address or hostname.\n"); goto again; } @@ -184,8 +225,10 @@ again: hostname = xstrdup(line); save: + if(*filename) { FILE *f = fopen(filename, "a"); + if(f) { fprintf(f, "\nAddress = %s\n", hostname); fclose(f); @@ -195,16 +238,19 @@ save: } done: + if(port) { - if(strchr(hostname, ':')) + if(strchr(hostname, ':')) { xasprintf(&hostport, "[%s]:%s", hostname, port); - else + } else { xasprintf(&hostport, "%s:%s", hostname, port); + } } else { - if(strchr(hostname, ':')) + if(strchr(hostname, ':')) { xasprintf(&hostport, "[%s]", hostname); - else + } else { hostport = xstrdup(hostname); + } } free(hostname); @@ -214,6 +260,7 @@ done: static bool fcopy(FILE *out, const char *filename) { FILE *in = fopen(filename, "r"); + if(!in) { fprintf(stderr, "Could not open %s: %s\n", filename, strerror(errno)); return false; @@ -221,8 +268,11 @@ static bool fcopy(FILE *out, const char *filename) { char buf[1024]; size_t len; - while((len = fread(buf, 1, sizeof buf, in))) + + while((len = fread(buf, 1, sizeof(buf), in))) { fwrite(buf, len, 1, out); + } + fclose(in); return true; } @@ -240,12 +290,15 @@ int cmd_invite(int argc, char *argv[]) { } myname = get_my_name(true); - if(!myname) + + if(!myname) { return 1; + } // Ensure no host configuration file with that name exists char filename[PATH_MAX]; - snprintf(filename, sizeof filename, "%s" SLASH "hosts" SLASH "%s", confbase, argv[1]); + snprintf(filename, sizeof(filename), "%s" SLASH "hosts" SLASH "%s", confbase, argv[1]); + if(!access(filename, F_OK)) { fprintf(stderr, "A host config file for %s already exists!\n", argv[1]); return 1; @@ -256,13 +309,17 @@ int cmd_invite(int argc, char *argv[]) { bool found = false; sendline(fd, "%d %d", CONTROL, REQ_DUMP_NODES); - while(recvline(fd, line, sizeof line)) { + while(recvline(fd, line, sizeof(line))) { char node[4096]; int code, req; - if(sscanf(line, "%d %d %4095s", &code, &req, node) != 3) + + if(sscanf(line, "%d %d %4095s", &code, &req, node) != 3) { break; - if(!strcmp(node, argv[1])) + } + + if(!strcmp(node, argv[1])) { found = true; + } } if(found) { @@ -271,7 +328,8 @@ int cmd_invite(int argc, char *argv[]) { } } - snprintf(filename, sizeof filename, "%s" SLASH "invitations", confbase); + snprintf(filename, sizeof(filename), "%s" SLASH "invitations", confbase); + if(mkdir(filename, 0700) && errno != EEXIST) { fprintf(stderr, "Could not create directory %s: %s\n", filename, strerror(errno)); return 1; @@ -279,6 +337,7 @@ int cmd_invite(int argc, char *argv[]) { // Count the number of valid invitations, clean up old ones DIR *dir = opendir(filename); + if(!dir) { fprintf(stderr, "Could not read directory %s: %s\n", filename, strerror(errno)); return 1; @@ -290,16 +349,24 @@ int cmd_invite(int argc, char *argv[]) { time_t deadline = time(NULL) - 604800; // 1 week in the past while((ent = readdir(dir))) { - if(strlen(ent->d_name) != 24) + if(strlen(ent->d_name) != 24) { continue; + } + char invname[PATH_MAX]; struct stat st; - snprintf(invname, sizeof invname, "%s" SLASH "%s", filename, ent->d_name); + + if((size_t)snprintf(invname, sizeof(invname), "%s" SLASH "%s", filename, ent->d_name) >= sizeof(invname)) { + fprintf(stderr, "Filename too long: %s" SLASH "%s\n", filename, ent->d_name); + continue; + } + if(!stat(invname, &st)) { - if(deadline < st.st_mtime) + if(deadline < st.st_mtime) { count++; - else + } else { unlink(invname); + } } else { fprintf(stderr, "Could not stat %s: %s\n", invname, strerror(errno)); errno = 0; @@ -312,16 +379,18 @@ int cmd_invite(int argc, char *argv[]) { fprintf(stderr, "Error while reading directory %s: %s\n", filename, strerror(errno)); return 1; } - + ecdsa_t *key; - snprintf(filename, sizeof filename, "%s" SLASH "invitations" SLASH "ed25519_key.priv", confbase); + snprintf(filename, sizeof(filename), "%s" SLASH "invitations" SLASH "ed25519_key.priv", confbase); // Remove the key if there are no outstanding invitations. - if(!count) + if(!count) { unlink(filename); + } // Create a new key if necessary. FILE *f = fopen(filename, "r"); + if(!f) { if(errno != ENOENT) { fprintf(stderr, "Could not read %s: %s\n", filename, strerror(errno)); @@ -329,32 +398,45 @@ int cmd_invite(int argc, char *argv[]) { } key = ecdsa_generate(); - if(!key) + + if(!key) { return 1; + } + f = fopen(filename, "w"); + if(!f) { fprintf(stderr, "Could not write %s: %s\n", filename, strerror(errno)); return 1; } + chmod(filename, 0600); + if(!ecdsa_write_pem_private_key(key, f)) { fprintf(stderr, "Could not write ECDSA private key\n"); fclose(f); return 1; } + fclose(f); - if(connect_tincd(false)) + if(connect_tincd(true)) { sendline(fd, "%d %d", CONTROL, REQ_RELOAD); + } else { + fprintf(stderr, "Could not signal the tinc daemon. Please restart or reload it manually.\n"); + } } else { key = ecdsa_read_pem_private_key(f); fclose(f); - if(!key) + + if(!key) { fprintf(stderr, "Could not read private key from %s\n", filename); + } } - if(!key) + if(!key) { return 1; + } // Create a hash of the key. char hash[64]; @@ -370,45 +452,57 @@ int cmd_invite(int argc, char *argv[]) { char buf[18 + strlen(fingerprint)]; char cookiehash[64]; memcpy(buf, cookie, 18); - memcpy(buf + 18, fingerprint, sizeof buf - 18); - sha512(buf, sizeof buf, cookiehash); + memcpy(buf + 18, fingerprint, sizeof(buf) - 18); + sha512(buf, sizeof(buf), cookiehash); b64encode_urlsafe(cookiehash, cookiehash, 18); b64encode_urlsafe(cookie, cookie, 18); // Create a file containing the details of the invitation. - snprintf(filename, sizeof filename, "%s" SLASH "invitations" SLASH "%s", confbase, cookiehash); + snprintf(filename, sizeof(filename), "%s" SLASH "invitations" SLASH "%s", confbase, cookiehash); int ifd = open(filename, O_RDWR | O_CREAT | O_EXCL, 0600); + if(!ifd) { fprintf(stderr, "Could not create invitation file %s: %s\n", filename, strerror(errno)); return 1; } + f = fdopen(ifd, "w"); - if(!f) + + if(!f) { abort(); + } // Get the local address char *address = get_my_hostname(); // Fill in the details. fprintf(f, "Name = %s\n", argv[1]); - if(check_netname(netname, true)) + + if(check_netname(netname, true)) { fprintf(f, "NetName = %s\n", netname); + } + fprintf(f, "ConnectTo = %s\n", myname); // Copy Broadcast and Mode FILE *tc = fopen(tinc_conf, "r"); + if(tc) { char buf[1024]; - while(fgets(buf, sizeof buf, tc)) { + + while(fgets(buf, sizeof(buf), tc)) { if((!strncasecmp(buf, "Mode", 4) && strchr(" \t=", buf[4])) - || (!strncasecmp(buf, "Broadcast", 9) && strchr(" \t=", buf[9]))) { + || (!strncasecmp(buf, "Broadcast", 9) && strchr(" \t=", buf[9]))) { fputs(buf, f); + // Make sure there is a newline character. - if(!strchr(buf, '\n')) + if(!strchr(buf, '\n')) { fputc('\n', f); + } } } + fclose(tc); } @@ -416,7 +510,7 @@ int cmd_invite(int argc, char *argv[]) { fprintf(f, "Name = %s\n", myname); char filename2[PATH_MAX]; - snprintf(filename2, sizeof filename2, "%s" SLASH "hosts" SLASH "%s", confbase, myname); + snprintf(filename2, sizeof(filename2), "%s" SLASH "hosts" SLASH "%s", confbase, myname); fcopy(f, filename2); fclose(f); @@ -450,47 +544,60 @@ static bool success = false; static char cookie[18], hash[18]; static char *get_line(const char **data) { - if(!data || !*data) + if(!data || !*data) { return NULL; + } - if(!**data) { + if(! **data) { *data = NULL; return NULL; } static char line[1024]; const char *end = strchr(*data, '\n'); - size_t len = end ? end - *data : strlen(*data); - if(len >= sizeof line) { + size_t len = end ? (size_t)(end - *data) : strlen(*data); + + if(len >= sizeof(line)) { fprintf(stderr, "Maximum line length exceeded!\n"); return NULL; } - if(len && !isprint(**data)) + + if(len && !isprint(**data)) { abort(); + } memcpy(line, *data, len); line[len] = 0; - if(end) + if(end) { *data = end + 1; - else + } else { *data = NULL; + } return line; } static char *get_value(const char *data, const char *var) { char *line = get_line(&data); - if(!line) + + if(!line) { return NULL; + } char *sep = line + strcspn(line, " \t="); char *val = sep + strspn(sep, " \t"); - if(*val == '=') + + if(*val == '=') { val += 1 + strspn(val + 1, " \t"); + } + *sep = 0; - if(strcasecmp(line, var)) + + if(strcasecmp(line, var)) { return NULL; + } + return val; } @@ -503,25 +610,32 @@ static char *grep(const char *data, const char *var) { // Skip all lines not starting with var while(strncasecmp(p, var, varlen) || !strchr(" \t=", p[varlen])) { p = strchr(p, '\n'); - if(!p) + + if(!p) { break; - else + } else { p++; + } } - if(!p) + if(!p) { return NULL; + } p += varlen; p += strspn(p, " \t"); - if(*p == '=') + + if(*p == '=') { p += 1 + strspn(p + 1, " \t"); + } const char *e = strchr(p, '\n'); - if(!e) - return xstrdup(p); - if(e - p >= sizeof value) { + if(!e) { + return xstrdup(p); + } + + if((size_t)(e - p) >= sizeof(value)) { fprintf(stderr, "Maximum line length exceeded!\n"); return NULL; } @@ -532,12 +646,18 @@ static char *grep(const char *data, const char *var) { } static bool finalize_join(void) { - char *name = xstrdup(get_value(data, "Name")); - if(!name) { + const char *temp_name = get_value(data, "Name"); + + if(!temp_name) { fprintf(stderr, "No Name found in invitation!\n"); return false; } + size_t len = strlen(temp_name); + char name[len + 1]; + memcpy(name, temp_name, len); + name[len] = 0; + if(!check_id(name)) { fprintf(stderr, "Invalid Name found in invitation!\n"); return false; @@ -545,6 +665,7 @@ static bool finalize_join(void) { if(!netname) { netname = grep(data, "NetName"); + if(netname && !check_netname(netname, true)) { fprintf(stderr, "Unsafe NetName found in invitation!\n"); return false; @@ -555,6 +676,7 @@ static bool finalize_join(void) { char temp_netname[32]; make_names: + if(!confbasegiven) { free(confbase); confbase = NULL; @@ -570,15 +692,17 @@ make_names: if(!access(tinc_conf, F_OK)) { fprintf(stderr, "Configuration file %s already exists!\n", tinc_conf); - if(confbasegiven) + + if(confbasegiven) { return false; + } // Generate a random netname, ask for a better one later. ask_netname = true; - snprintf(temp_netname, sizeof temp_netname, "join_%x", rand()); + snprintf(temp_netname, sizeof(temp_netname), "join_%x", rand()); netname = temp_netname; goto make_names; - } + } if(mkdir(confbase, 0777) && errno != EEXIST) { fprintf(stderr, "Could not create directory %s: %s\n", confbase, strerror(errno)); @@ -591,6 +715,7 @@ make_names: } FILE *f = fopen(tinc_conf, "w"); + if(!f) { fprintf(stderr, "Could not create file %s: %s\n", tinc_conf, strerror(errno)); return false; @@ -599,16 +724,18 @@ make_names: fprintf(f, "Name = %s\n", name); char filename[PATH_MAX]; - snprintf(filename, sizeof filename, "%s" SLASH "%s", hosts_dir, name); + snprintf(filename, sizeof(filename), "%s" SLASH "%s", hosts_dir, name); FILE *fh = fopen(filename, "w"); + if(!fh) { fprintf(stderr, "Could not create file %s: %s\n", filename, strerror(errno)); fclose(f); return false; } - snprintf(filename, sizeof filename, "%s" SLASH "invitation-data", confbase); + snprintf(filename, sizeof(filename), "%s" SLASH "invitation-data", confbase); FILE *finv = fopen(filename, "w"); + if(!finv || fwrite(data, datalen, 1, finv) != 1) { fprintf(stderr, "Could not create file %s: %s\n", filename, strerror(errno)); fclose(fh); @@ -616,10 +743,12 @@ make_names: fclose(finv); return false; } + fclose(finv); - snprintf(filename, sizeof filename, "%s" SLASH "tinc-up.invitation", confbase); + snprintf(filename, sizeof(filename), "%s" SLASH "tinc-up.invitation", confbase); FILE *fup = fopen(filename, "w"); + if(!fup) { fprintf(stderr, "Could not create file %s: %s\n", filename, strerror(errno)); fclose(f); @@ -637,34 +766,47 @@ make_names: while((l = get_line(&p))) { // Ignore comments - if(*l == '#') + if(*l == '#') { continue; + } // Split line into variable and value int len = strcspn(l, "\t ="); value = l + len; value += strspn(value, "\t "); + if(*value == '=') { value++; value += strspn(value, "\t "); } + l[len] = 0; - // Is it a Name? - if(!strcasecmp(l, "Name")) - if(strcmp(value, name)) - break; - else - continue; - else if(!strcasecmp(l, "NetName")) + // Ignore lines with empty variable names + if(!*l) { continue; + } + + // Is it a Name? + if(!strcasecmp(l, "Name")) { + if(strcmp(value, name)) { + break; + } else { + continue; + } + } else if(!strcasecmp(l, "NetName")) { + continue; + } // Check the list of known variables bool found = false; int i; + for(i = 0; variables[i].name; i++) { - if(strcasecmp(l, variables[i].name)) + if(strcasecmp(l, variables[i].name)) { continue; + } + found = true; break; } @@ -672,14 +814,16 @@ make_names: // Handle Ifconfig and Route statements if(!found) { if(!strcasecmp(l, "Ifconfig")) { - if(!strcasecmp(value, "dhcp")) + if(!strcasecmp(value, "dhcp")) { ifconfig_dhcp(fup); - else if(!strcasecmp(value, "dhcp6")) + } else if(!strcasecmp(value, "dhcp6")) { ifconfig_dhcp6(fup); - else if(!strcasecmp(value, "slaac")) + } else if(!strcasecmp(value, "slaac")) { ifconfig_slaac(fup); - else + } else { ifconfig_address(fup, value); + } + continue; } else if(!strcasecmp(l, "Route")) { ifconfig_route(fup, value); @@ -715,7 +859,7 @@ make_names: return false; } - snprintf(filename, sizeof filename, "%s" SLASH "%s", hosts_dir, value); + snprintf(filename, sizeof(filename), "%s" SLASH "%s", hosts_dir, value); f = fopen(filename, "w"); if(!f) { @@ -724,16 +868,21 @@ make_names: } while((l = get_line(&p))) { - if(!strcmp(l, "#---------------------------------------------------------------#")) + if(!strcmp(l, "#---------------------------------------------------------------#")) { continue; + } + int len = strcspn(l, "\t ="); + if(len == 4 && !strncasecmp(l, "Name", 4)) { value = l + len; value += strspn(value, "\t "); + if(*value == '=') { value++; value += strspn(value, "\t "); } + l[len] = 0; break; } @@ -747,17 +896,23 @@ make_names: // Generate our key and send a copy to the server ecdsa_t *key = ecdsa_generate(); - if(!key) + + if(!key) { return false; + } char *b64key = ecdsa_get_base64_public_key(key); - if(!b64key) - return false; - snprintf(filename, sizeof filename, "%s" SLASH "ed25519_key.priv", confbase); - f = fopenmask(filename, "w", 0600); - if(!f) + if(!b64key) { return false; + } + + snprintf(filename, sizeof(filename), "%s" SLASH "ed25519_key.priv", confbase); + f = fopenmask(filename, "w", 0600); + + if(!f) { + return false; + } if(!ecdsa_write_pem_private_key(key, f)) { fprintf(stderr, "Error writing private key!\n"); @@ -776,7 +931,7 @@ make_names: #ifndef DISABLE_LEGACY rsa_t *rsa = rsa_generate(2048, 0x1001); - snprintf(filename, sizeof filename, "%s" SLASH "rsa_key.priv", confbase); + snprintf(filename, sizeof(filename), "%s" SLASH "rsa_key.priv", confbase); f = fopenmask(filename, "w", 0600); if(!f || !rsa_write_pem_private_key(rsa, f)) { @@ -795,19 +950,28 @@ make_names: check_port(name); ask_netname: + if(ask_netname && tty) { fprintf(stderr, "Enter a new netname: "); - if(!fgets(line, sizeof line, stdin)) { + + if(!fgets(line, sizeof(line), stdin)) { fprintf(stderr, "Error while reading stdin: %s\n", strerror(errno)); return false; } - if(!*line || *line == '\n') + + if(!*line || *line == '\n') { goto ask_netname; + } line[strlen(line) - 1] = 0; char newbase[PATH_MAX]; - snprintf(newbase, sizeof newbase, CONFDIR SLASH "tinc" SLASH "%s", line); + + if((size_t)snprintf(newbase, sizeof(newbase), CONFDIR SLASH "tinc" SLASH "%s", line) >= sizeof(newbase)) { + fprintf(stderr, "Filename too long: " CONFDIR SLASH "tinc" SLASH "%s\n", line); + goto ask_netname; + } + if(rename(confbase, newbase)) { fprintf(stderr, "Error trying to rename %s to %s: %s\n", confbase, newbase, strerror(errno)); goto ask_netname; @@ -818,21 +982,26 @@ ask_netname: } char filename2[PATH_MAX]; - snprintf(filename, sizeof filename, "%s" SLASH "tinc-up.invitation", confbase); - snprintf(filename2, sizeof filename2, "%s" SLASH "tinc-up", confbase); + snprintf(filename, sizeof(filename), "%s" SLASH "tinc-up.invitation", confbase); + snprintf(filename2, sizeof(filename2), "%s" SLASH "tinc-up", confbase); if(valid_tinc_up) { if(tty) { FILE *fup = fopen(filename, "r"); + if(fup) { fprintf(stderr, "\nPlease review the following tinc-up script:\n\n"); char buf[MAXSIZE]; - while(fgets(buf, sizeof buf, fup)) + + while(fgets(buf, sizeof(buf), fup)) { fputs(buf, stderr); + } + fclose(fup); int response = 0; + do { fprintf(stderr, "\nDo you want to use this script [y]es/[n]o/[e]dit? "); response = tolower(getchar()); @@ -843,14 +1012,23 @@ ask_netname: if(response == 'e') { char *command; #ifndef HAVE_MINGW - xasprintf(&command, "\"%s\" \"%s\"", getenv("VISUAL") ?: getenv("EDITOR") ?: "vi", filename); + const char *editor = getenv("VISUAL"); + if (!editor) + editor = getenv("EDITOR"); + if (!editor) + editor = "vi"; + + xasprintf(&command, "\"%s\" \"%s\"", editor, filename); #else xasprintf(&command, "edit \"%s\"", filename); #endif - if(system(command)) + + if(system(command)) { response = 'n'; - else + } else { response = 'y'; + } + free(command); } @@ -877,42 +1055,52 @@ ask_netname: } -static bool invitation_send(void *handle, uint8_t type, const void *data, size_t len) { +static bool invitation_send(void *handle, uint8_t type, const void *vdata, size_t len) { + (void)handle; + (void)type; + const char *data = vdata; + while(len) { int result = send(sock, data, len, 0); - if(result == -1 && errno == EINTR) + + if(result == -1 && errno == EINTR) { continue; - else if(result <= 0) + } else if(result <= 0) { return false; + } + data += result; len -= result; } + return true; } static bool invitation_receive(void *handle, uint8_t type, const void *msg, uint16_t len) { + (void)handle; + switch(type) { - case SPTPS_HANDSHAKE: - return sptps_send_record(&sptps, 0, cookie, sizeof cookie); + case SPTPS_HANDSHAKE: + return sptps_send_record(&sptps, 0, cookie, sizeof(cookie)); - case 0: - data = xrealloc(data, datalen + len + 1); - memcpy(data + datalen, msg, len); - datalen += len; - data[datalen] = 0; - break; + case 0: + data = xrealloc(data, datalen + len + 1); + memcpy(data + datalen, msg, len); + datalen += len; + data[datalen] = 0; + break; - case 1: - return finalize_join(); + case 1: + return finalize_join(); - case 2: - fprintf(stderr, "Invitation succesfully accepted.\n"); - shutdown(sock, SHUT_RDWR); - success = true; - break; + case 2: + fprintf(stderr, "Invitation successfully accepted.\n"); + shutdown(sock, SHUT_RDWR); + success = true; + break; - default: - return false; + default: + return false; } return true; @@ -956,13 +1144,17 @@ int cmd_join(int argc, char *argv[]) { if(argc > 1) { invitation = argv[1]; } else { - if(tty) + if(tty) { fprintf(stderr, "Enter invitation URL: "); + } + errno = EPIPE; - if(!fgets(line, sizeof line, stdin)) { + + if(!fgets(line, sizeof(line), stdin)) { fprintf(stderr, "Error while reading stdin: %s\n", strerror(errno)); return false; } + invitation = line; } @@ -970,60 +1162,81 @@ int cmd_join(int argc, char *argv[]) { rstrip(line); char *slash = strchr(invitation, '/'); - if(!slash) + + if(!slash) { goto invalid; + } *slash++ = 0; - if(strlen(slash) != 48) + if(strlen(slash) != 48) { goto invalid; + } char *address = invitation; char *port = NULL; + if(*address == '[') { address++; char *bracket = strchr(address, ']'); - if(!bracket) + + if(!bracket) { goto invalid; + } + *bracket = 0; - if(bracket[1] == ':') + + if(bracket[1] == ':') { port = bracket + 2; + } } else { port = strchr(address, ':'); - if(port) + + if(port) { *port++ = 0; + } } - if(!port || !*port) + if(!port || !*port) { port = "655"; + } - if(!b64decode(slash, hash, 24) || !b64decode(slash + 24, cookie, 24)) + if(!b64decode(slash, hash, 24) || !b64decode(slash + 24, cookie, 24)) { goto invalid; + } // Generate a throw-away key for the invitation. ecdsa_t *key = ecdsa_generate(); - if(!key) + + if(!key) { return 1; + } char *b64key = ecdsa_get_base64_public_key(key); // Connect to the tinc daemon mentioned in the URL. struct addrinfo *ai = str2addrinfo(address, port, SOCK_STREAM); - if(!ai) + + if(!ai) { return 1; + } struct addrinfo *aip = NULL; next: - if(!aip) + if(!aip) { aip = ai; - else { + } else { aip = aip->ai_next; - if(!aip) + + if(!aip) { + freeaddrinfo(ai); return 1; + } } sock = socket(aip->ai_family, aip->ai_socktype, aip->ai_protocol); + if(sock <= 0) { fprintf(stderr, "Could not open socket: %s\n", strerror(errno)); goto next; @@ -1042,9 +1255,11 @@ next: fprintf(stderr, "Connected to %s port %s...\n", address, port); // Tell him we have an invitation, and give him our throw-away key. - int len = snprintf(line, sizeof line, "0 ?%s %d.%d\n", b64key, PROT_MAJOR, PROT_MINOR); - if(len <= 0 || len >= sizeof line) + int len = snprintf(line, sizeof(line), "0 ?%s %d.%d\n", b64key, PROT_MAJOR, PROT_MINOR); + + if(len <= 0 || (size_t)len >= sizeof(line)) { abort(); + } if(!sendline(sock, "0 ?%s %d.%d", b64key, PROT_MAJOR, 1)) { fprintf(stderr, "Error sending request to %s port %s: %s\n", address, port, strerror(errno)); @@ -1055,55 +1270,69 @@ next: char hisname[4096] = ""; int code, hismajor, hisminor = 0; - if(!recvline(sock, line, sizeof line) || sscanf(line, "%d %4095s %d.%d", &code, hisname, &hismajor, &hisminor) < 3 || code != 0 || hismajor != PROT_MAJOR || !check_id(hisname) || !recvline(sock, line, sizeof line) || !rstrip(line) || sscanf(line, "%d ", &code) != 1 || code != ACK || strlen(line) < 3) { + if(!recvline(sock, line, sizeof(line)) || sscanf(line, "%d %4095s %d.%d", &code, hisname, &hismajor, &hisminor) < 3 || code != 0 || hismajor != PROT_MAJOR || !check_id(hisname) || !recvline(sock, line, sizeof(line)) || !rstrip(line) || sscanf(line, "%d ", &code) != 1 || code != ACK || strlen(line) < 3) { fprintf(stderr, "Cannot read greeting from peer\n"); closesocket(sock); goto next; } + freeaddrinfo(ai); + // Check if the hash of the key he gave us matches the hash in the URL. char *fingerprint = line + 2; char hishash[64]; + if(sha512(fingerprint, strlen(fingerprint), hishash)) { fprintf(stderr, "Could not create digest\n%s\n", line + 2); return 1; } + if(memcmp(hishash, hash, 18)) { fprintf(stderr, "Peer has an invalid key!\n%s\n", line + 2); return 1; } - + ecdsa_t *hiskey = ecdsa_set_base64_public_key(fingerprint); - if(!hiskey) + + if(!hiskey) { return 1; + } // Start an SPTPS session - if(!sptps_start(&sptps, NULL, true, false, key, hiskey, "tinc invitation", 15, invitation_send, invitation_receive)) + if(!sptps_start(&sptps, NULL, true, false, key, hiskey, "tinc invitation", 15, invitation_send, invitation_receive)) { return 1; + } // Feed rest of input buffer to SPTPS - if(!sptps_receive_data(&sptps, buffer, blen)) + if(!sptps_receive_data(&sptps, buffer, blen)) { return 1; + } - while((len = recv(sock, line, sizeof line, 0))) { + while((len = recv(sock, line, sizeof(line), 0))) { if(len < 0) { - if(errno == EINTR) + if(errno == EINTR) { continue; + } + fprintf(stderr, "Error reading data from %s port %s: %s\n", address, port, strerror(errno)); return 1; } char *p = line; + while(len) { int done = sptps_receive_data(&sptps, p, len); - if(!done) + + if(!done) { return 1; + } + len -= done; p += done; } } - + sptps_stop(&sptps); ecdsa_free(hiskey); ecdsa_free(key); diff --git a/src/invitation.h b/src/invitation.h index 3d017e9..6517fe8 100644 --- a/src/invitation.h +++ b/src/invitation.h @@ -1,3 +1,6 @@ +#ifndef TINC_INVITATION_H +#define TINC_INVITATION_H + /* invitation.h -- header for invitation.c. Copyright (C) 2013 Guus Sliepen @@ -17,10 +20,6 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#ifndef __TINC_INVITATION_H__ -#define __TINC_INVITATION_H__ - -bool recvdata(int fd, char *data, size_t len); int cmd_invite(int argc, char *argv[]); int cmd_join(int argc, char *argv[]); diff --git a/src/ipv4.h b/src/ipv4.h index 997b88d..1e34ccb 100644 --- a/src/ipv4.h +++ b/src/ipv4.h @@ -1,3 +1,6 @@ +#ifndef TINC_IPV4_H +#define TINC_IPV4_H + /* ipv4.h -- missing IPv4 related definitions Copyright (C) 2005 Ivo Timmermans @@ -18,9 +21,6 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#ifndef __TINC_IPV4_H__ -#define __TINC_IPV4_H__ - #ifndef AF_INET #define AF_INET 2 #endif @@ -64,11 +64,11 @@ #ifndef HAVE_STRUCT_IP struct ip { #if __BYTE_ORDER == __LITTLE_ENDIAN - unsigned int ip_hl:4; - unsigned int ip_v:4; + unsigned int ip_hl: 4; + unsigned int ip_v: 4; #else - unsigned int ip_v:4; - unsigned int ip_hl:4; + unsigned int ip_v: 4; + unsigned int ip_hl: 4; #endif uint8_t ip_tos; uint16_t ip_len; @@ -81,7 +81,7 @@ struct ip { uint8_t ip_p; uint16_t ip_sum; struct in_addr ip_src, ip_dst; -} __attribute__ ((__gcc_struct__, __packed__)); +} __attribute__((__gcc_struct__, __packed__)); #endif #ifndef IP_OFFMASK @@ -143,7 +143,7 @@ struct icmp { #define icmp_radv icmp_dun.id_radv #define icmp_mask icmp_dun.id_mask #define icmp_data icmp_dun.id_data -} __attribute__ ((__gcc_struct__, __packed__)); +} __attribute__((__gcc_struct__, __packed__)); #endif -#endif /* __TINC_IPV4_H__ */ +#endif diff --git a/src/ipv6.h b/src/ipv6.h index cc2c5b6..4d5173f 100644 --- a/src/ipv6.h +++ b/src/ipv6.h @@ -1,3 +1,6 @@ +#ifndef TINC_IPV6_H +#define TINC_IPV6_H + /* ipv6.h -- missing IPv6 related definitions Copyright (C) 2005 Ivo Timmermans @@ -18,9 +21,6 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#ifndef __TINC_IPV6_H__ -#define __TINC_IPV6_H__ - #ifndef AF_INET6 #define AF_INET6 10 #endif @@ -32,8 +32,8 @@ #ifndef IN6_IS_ADDR_V4MAPPED #define IN6_IS_ADDR_V4MAPPED(a) \ ((((__const uint32_t *) (a))[0] == 0) \ - && (((__const uint32_t *) (a))[1] == 0) \ - && (((__const uint32_t *) (a))[2] == htonl (0xffff))) + && (((__const uint32_t *) (a))[1] == 0) \ + && (((__const uint32_t *) (a))[2] == htonl (0xffff))) #endif #ifndef HAVE_STRUCT_IP6_HDR @@ -49,7 +49,7 @@ struct ip6_hdr { } ip6_ctlun; struct in6_addr ip6_src; struct in6_addr ip6_dst; -} __attribute__ ((__gcc_struct__, __packed__)); +} __attribute__((__gcc_struct__, __packed__)); #define ip6_vfc ip6_ctlun.ip6_un2_vfc #define ip6_flow ip6_ctlun.ip6_un1.ip6_un1_flow #define ip6_plen ip6_ctlun.ip6_un1.ip6_un1_plen @@ -68,7 +68,7 @@ struct icmp6_hdr { uint16_t icmp6_un_data16[2]; uint8_t icmp6_un_data8[4]; } icmp6_dataun; -} __attribute__ ((__gcc_struct__, __packed__)); +} __attribute__((__gcc_struct__, __packed__)); #define ICMP6_DST_UNREACH_NOROUTE 0 #define ICMP6_DST_UNREACH 1 #define ICMP6_PACKET_TOO_BIG 2 @@ -88,7 +88,7 @@ struct icmp6_hdr { struct nd_neighbor_solicit { struct icmp6_hdr nd_ns_hdr; struct in6_addr nd_ns_target; -} __attribute__ ((__gcc_struct__, __packed__)); +} __attribute__((__gcc_struct__, __packed__)); #define ND_OPT_SOURCE_LINKADDR 1 #define ND_OPT_TARGET_LINKADDR 2 #define nd_ns_type nd_ns_hdr.icmp6_type @@ -101,7 +101,7 @@ struct nd_neighbor_solicit { struct nd_opt_hdr { uint8_t nd_opt_type; uint8_t nd_opt_len; -} __attribute__ ((__gcc_struct__, __packed__)); +} __attribute__((__gcc_struct__, __packed__)); #endif -#endif /* __TINC_IPV6_H__ */ +#endif diff --git a/src/linux/device.c b/src/linux/device.c index e273bfa..94e223f 100644 --- a/src/linux/device.c +++ b/src/linux/device.c @@ -44,15 +44,17 @@ char *device = NULL; char *iface = NULL; static char *type = NULL; static char ifrname[IFNAMSIZ]; -static char *device_info; +static const char *device_info; static bool setup_device(void) { - if(!get_config_string(lookup_config(config_tree, "Device"), &device)) + if(!get_config_string(lookup_config(config_tree, "Device"), &device)) { device = xstrdup(DEFAULT_DEVICE); + } if(!get_config_string(lookup_config(config_tree, "Interface"), &iface)) - if(netname) + if(netname) { iface = xstrdup(netname); + } device_fd = open(device, O_RDWR | O_NONBLOCK); @@ -65,7 +67,7 @@ static bool setup_device(void) { fcntl(device_fd, F_SETFD, FD_CLOEXEC); #endif - struct ifreq ifr = {{{0}}}; + struct ifreq ifr = {0}; get_config_string(lookup_config(config_tree, "DeviceType"), &type); @@ -79,8 +81,10 @@ static bool setup_device(void) { device_type = DEVICE_TYPE_TUN; device_info = "Linux tun/tap device (tun mode)"; } else { - if (routing_mode == RMODE_ROUTER) + if(routing_mode == RMODE_ROUTER) { overwrite_mac = true; + } + ifr.ifr_flags = IFF_TAP | IFF_NO_PI; device_type = DEVICE_TYPE_TAP; device_info = "Linux tun/tap device (tap mode)"; @@ -90,15 +94,21 @@ static bool setup_device(void) { /* Set IFF_ONE_QUEUE flag... */ bool t1q = false; - if(get_config_bool(lookup_config(config_tree, "IffOneQueue"), &t1q) && t1q) + + if(get_config_bool(lookup_config(config_tree, "IffOneQueue"), &t1q) && t1q) { ifr.ifr_flags |= IFF_ONE_QUEUE; + } + #endif - if(iface) + if(iface) { strncpy(ifr.ifr_name, iface, IFNAMSIZ); + ifr.ifr_name[IFNAMSIZ - 1] = 0; + } if(!ioctl(device_fd, TUNSETIFF, &ifr)) { strncpy(ifrname, ifr.ifr_name, IFNAMSIZ); + ifrname[IFNAMSIZ - 1] = 0; free(iface); iface = xstrdup(ifrname); } else { @@ -109,11 +119,13 @@ static bool setup_device(void) { logger(DEBUG_ALWAYS, LOG_INFO, "%s is a %s", device, device_info); if(ifr.ifr_flags & IFF_TAP) { - struct ifreq ifr_mac = {}; - if(!ioctl(device_fd, SIOCGIFHWADDR, &ifr_mac)) + struct ifreq ifr_mac = {0}; + + if(!ioctl(device_fd, SIOCGIFHWADDR, &ifr_mac)) { memcpy(mymac.x, ifr_mac.ifr_hwaddr.sa_data, ETH_ALEN); - else + } else { logger(DEBUG_ALWAYS, LOG_WARNING, "Could not get MAC address of %s: %s", device, strerror(errno)); + } } return true; @@ -123,9 +135,12 @@ static void close_device(void) { close(device_fd); device_fd = -1; - free(type); type = NULL; - free(device); device = NULL; - free(iface); iface = NULL; + free(type); + type = NULL; + free(device); + device = NULL; + free(iface); + iface = NULL; device_info = NULL; } @@ -133,64 +148,73 @@ static bool read_packet(vpn_packet_t *packet) { int inlen; switch(device_type) { - case DEVICE_TYPE_TUN: - inlen = read(device_fd, DATA(packet) + 10, MTU - 10); + case DEVICE_TYPE_TUN: + inlen = read(device_fd, DATA(packet) + 10, MTU - 10); - if(inlen <= 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", - device_info, device, strerror(errno)); - if (errno == EBADFD) { /* File descriptor in bad state */ - event_exit(); - } - return false; + if(inlen <= 0) { + logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", + device_info, device, strerror(errno)); + + if(errno == EBADFD) { /* File descriptor in bad state */ + event_exit(); } - memset(DATA(packet), 0, 12); - packet->len = inlen + 10; - break; - case DEVICE_TYPE_TAP: - inlen = read(device_fd, DATA(packet), MTU); + return false; + } - if(inlen <= 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", - device_info, device, strerror(errno)); - return false; - } + memset(DATA(packet), 0, 12); + packet->len = inlen + 10; + break; - packet->len = inlen; - break; - default: - abort(); + case DEVICE_TYPE_TAP: + inlen = read(device_fd, DATA(packet), MTU); + + if(inlen <= 0) { + logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", + device_info, device, strerror(errno)); + return false; + } + + packet->len = inlen; + break; + + default: + abort(); } logger(DEBUG_TRAFFIC, LOG_DEBUG, "Read packet of %d bytes from %s", packet->len, - device_info); + device_info); return true; } static bool write_packet(vpn_packet_t *packet) { logger(DEBUG_TRAFFIC, LOG_DEBUG, "Writing packet of %d bytes to %s", - packet->len, device_info); + packet->len, device_info); switch(device_type) { - case DEVICE_TYPE_TUN: - DATA(packet)[10] = DATA(packet)[11] = 0; - if(write(device_fd, DATA(packet) + 10, packet->len - 10) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Can't write to %s %s: %s", device_info, device, - strerror(errno)); - return false; - } - break; - case DEVICE_TYPE_TAP: - if(write(device_fd, DATA(packet), packet->len) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Can't write to %s %s: %s", device_info, device, - strerror(errno)); - return false; - } - break; - default: - abort(); + case DEVICE_TYPE_TUN: + DATA(packet)[10] = DATA(packet)[11] = 0; + + if(write(device_fd, DATA(packet) + 10, packet->len - 10) < 0) { + logger(DEBUG_ALWAYS, LOG_ERR, "Can't write to %s %s: %s", device_info, device, + strerror(errno)); + return false; + } + + break; + + case DEVICE_TYPE_TAP: + if(write(device_fd, DATA(packet), packet->len) < 0) { + logger(DEBUG_ALWAYS, LOG_ERR, "Can't write to %s %s: %s", device_info, device, + strerror(errno)); + return false; + } + + break; + + default: + abort(); } return true; diff --git a/src/list.c b/src/list.c index 0bbc5d4..27494c8 100644 --- a/src/list.c +++ b/src/list.c @@ -41,8 +41,9 @@ list_node_t *list_alloc_node(void) { } void list_free_node(list_t *list, list_node_t *node) { - if(node->data && list->delete) + if(node->data && list->delete) { list->delete(node->data); + } free(node); } @@ -57,10 +58,11 @@ list_node_t *list_insert_head(list_t *list, void *data) { node->next = list->head; list->head = node; - if(node->next) + if(node->next) { node->next->prev = node; - else + } else { list->tail = node; + } list->count++; @@ -75,10 +77,11 @@ list_node_t *list_insert_tail(list_t *list, void *data) { node->prev = list->tail; list->tail = node; - if(node->prev) + if(node->prev) { node->prev->next = node; - else + } else { list->head = node; + } list->count++; @@ -93,10 +96,11 @@ list_node_t *list_insert_after(list_t *list, list_node_t *after, void *data) { node->prev = after; after->next = node; - if(node->next) + if(node->next) { node->next->prev = node; - else + } else { list->tail = node; + } list->count++; @@ -113,10 +117,11 @@ list_node_t *list_insert_before(list_t *list, list_node_t *before, void *data) { node->prev = before->prev; before->prev = node; - if(node->prev) + if(node->prev) { node->prev->next = node; - else + } else { list->head = node; + } list->count++; @@ -124,15 +129,17 @@ list_node_t *list_insert_before(list_t *list, list_node_t *before, void *data) { } void list_unlink_node(list_t *list, list_node_t *node) { - if(node->prev) + if(node->prev) { node->prev->next = node->next; - else + } else { list->head = node->next; + } - if(node->next) + if(node->next) { node->next->prev = node->prev; - else + } else { list->tail = node->prev; + } list->count--; } @@ -152,31 +159,35 @@ void list_delete_tail(list_t *list) { void list_delete(list_t *list, const void *data) { for(list_node_t *node = list->head, *next; next = node ? node->next : NULL, node; node = next) - if(node->data == data) + if(node->data == data) { list_delete_node(list, node); + } } /* Head/tail lookup */ void *list_get_head(list_t *list) { - if(list->head) + if(list->head) { return list->head->data; - else + } else { return NULL; + } } void *list_get_tail(list_t *list) { - if(list->tail) + if(list->tail) { return list->tail->data; - else + } else { return NULL; + } } /* Fast list deletion */ void list_delete_list(list_t *list) { - for(list_node_t *node = list->head, *next; next = node ? node->next : NULL, node; node = next) + for(list_node_t *node = list->head, *next; next = node ? node->next : NULL, node; node = next) { list_free_node(list, node); + } list_free(list); } @@ -184,12 +195,14 @@ void list_delete_list(list_t *list) { /* Traversing */ void list_foreach_node(list_t *list, list_action_node_t action) { - for(list_node_t *node = list->head, *next; next = node ? node->next : NULL, node; node = next) + for(list_node_t *node = list->head, *next; next = node ? node->next : NULL, node; node = next) { action(node); + } } void list_foreach(list_t *list, list_action_t action) { for(list_node_t *node = list->head, *next; next = node ? node->next : NULL, node; node = next) - if(node->data) + if(node->data) { action(node->data); + } } diff --git a/src/list.h b/src/list.h index b0e7a84..3806495 100644 --- a/src/list.h +++ b/src/list.h @@ -1,3 +1,6 @@ +#ifndef TINC_LIST_H +#define TINC_LIST_H + /* list.h -- header file for list.c Copyright (C) 2000-2005 Ivo Timmermans @@ -18,9 +21,6 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#ifndef __TINC_LIST_H__ -#define __TINC_LIST_H__ - typedef struct list_node_t { struct list_node_t *prev; struct list_node_t *next; @@ -30,8 +30,8 @@ typedef struct list_node_t { void *data; } list_node_t; -typedef void (*list_action_t)(const void *); -typedef void (*list_action_node_t)(const list_node_t *); +typedef void (*list_action_t)(const void *data); +typedef void (*list_action_node_t)(const list_node_t *node); typedef struct list_t { list_node_t *head; @@ -45,39 +45,39 @@ typedef struct list_t { /* (De)constructors */ -extern list_t *list_alloc(list_action_t) __attribute__ ((__malloc__)); -extern void list_free(list_t *); +extern list_t *list_alloc(list_action_t delete) __attribute__((__malloc__)); +extern void list_free(list_t *list); extern list_node_t *list_alloc_node(void); -extern void list_free_node(list_t *, list_node_t *); +extern void list_free_node(list_t *list, list_node_t *node); /* Insertion and deletion */ -extern list_node_t *list_insert_head(list_t *, void *); -extern list_node_t *list_insert_tail(list_t *, void *); -extern list_node_t *list_insert_after(list_t *, list_node_t *, void *); -extern list_node_t *list_insert_before(list_t *, list_node_t *, void *); +extern list_node_t *list_insert_head(list_t *list, void *data); +extern list_node_t *list_insert_tail(list_t *list, void *data); +extern list_node_t *list_insert_after(list_t *list, list_node_t *node, void *data); +extern list_node_t *list_insert_before(list_t *list, list_node_t *node, void *data); -extern void list_delete(list_t *, const void *); +extern void list_delete(list_t *list, const void *data); -extern void list_unlink_node(list_t *, list_node_t *); -extern void list_delete_node(list_t *, list_node_t *); +extern void list_unlink_node(list_t *list, list_node_t *node); +extern void list_delete_node(list_t *list, list_node_t *node); -extern void list_delete_head(list_t *); -extern void list_delete_tail(list_t *); +extern void list_delete_head(list_t *list); +extern void list_delete_tail(list_t *list); /* Head/tail lookup */ -extern void *list_get_head(list_t *); -extern void *list_get_tail(list_t *); +extern void *list_get_head(list_t *list); +extern void *list_get_tail(list_t *list); /* Fast list deletion */ -extern void list_delete_list(list_t *); +extern void list_delete_list(list_t *list); /* Traversing */ -extern void list_foreach(list_t *, list_action_t); -extern void list_foreach_node(list_t *, list_action_node_t); +extern void list_foreach(list_t *list, list_action_t action); +extern void list_foreach_node(list_t *list, list_action_node_t action); /* Iterates over a list. @@ -87,4 +87,4 @@ extern void list_foreach_node(list_t *, list_action_node_t); */ #define list_each(type, item, list) (type *item = (type *)1; item; item = NULL) for(list_node_t *node = (list)->head, *next; item = node ? node->data : NULL, next = node ? node->next : NULL, node; node = next) -#endif /* __TINC_LIST_H__ */ +#endif diff --git a/src/logger.c b/src/logger.c index 4075ea8..062f759 100644 --- a/src/logger.c +++ b/src/logger.c @@ -45,40 +45,48 @@ static void real_logger(int level, int priority, const char *message) { static bool suppress = false; // Bail out early if there is nothing to do. - if(suppress) + if(suppress) { return; + } - if(!logcontrol && (level > debug_level || logmode == LOGMODE_NULL)) + if(!logcontrol && (level > debug_level || logmode == LOGMODE_NULL)) { return; + } if(level <= debug_level) { switch(logmode) { - case LOGMODE_STDERR: - fprintf(stderr, "%s\n", message); - fflush(stderr); - break; - case LOGMODE_FILE: - if(!now.tv_sec) - gettimeofday(&now, NULL); - time_t now_sec = now.tv_sec; - strftime(timestr, sizeof timestr, "%Y-%m-%d %H:%M:%S", localtime(&now_sec)); - fprintf(logfile, "%s %s[%ld]: %s\n", timestr, logident, (long)logpid, message); - fflush(logfile); - break; - case LOGMODE_SYSLOG: + case LOGMODE_STDERR: + fprintf(stderr, "%s\n", message); + fflush(stderr); + break; + + case LOGMODE_FILE: + if(!now.tv_sec) { + gettimeofday(&now, NULL); + } + + time_t now_sec = now.tv_sec; + strftime(timestr, sizeof(timestr), "%Y-%m-%d %H:%M:%S", localtime(&now_sec)); + fprintf(logfile, "%s %s[%ld]: %s\n", timestr, logident, (long)logpid, message); + fflush(logfile); + break; + + case LOGMODE_SYSLOG: #ifdef HAVE_MINGW - { - const char *messages[] = {message}; - ReportEvent(loghandle, priority, 0, 0, NULL, 1, 0, messages, NULL); - } + { + const char *messages[] = {message}; + ReportEvent(loghandle, priority, 0, 0, NULL, 1, 0, messages, NULL); + } + #else #ifdef HAVE_SYSLOG_H - syslog(priority, "%s", message); + syslog(priority, "%s", message); #endif #endif - break; - case LOGMODE_NULL: - break; + break; + + case LOGMODE_NULL: + break; } if(umbilical && do_detach) { @@ -90,16 +98,25 @@ static void real_logger(int level, int priority, const char *message) { if(logcontrol) { suppress = true; logcontrol = false; + for list_each(connection_t, c, connection_list) { - if(!c->status.log) + if(!c->status.log) { continue; + } + logcontrol = true; - if(level > (c->outcompression >= 0 ? c->outcompression : debug_level)) + + if(level > (c->outcompression >= 0 ? c->outcompression : debug_level)) { continue; + } + int len = strlen(message); - if(send_request(c, "%d %d %d", CONTROL, REQ_LOG, len)) + + if(send_request(c, "%d %d %d", CONTROL, REQ_LOG, len)) { send_meta(c, message, len); + } } + suppress = false; } } @@ -109,31 +126,37 @@ void logger(int level, int priority, const char *format, ...) { char message[1024] = ""; va_start(ap, format); - int len = vsnprintf(message, sizeof message, format, ap); - message[sizeof message - 1] = 0; + int len = vsnprintf(message, sizeof(message), format, ap); + message[sizeof(message) - 1] = 0; va_end(ap); - if(len > 0 && len < sizeof message - 1 && message[len - 1] == '\n') + if(len > 0 && (size_t)len < sizeof(message) - 1 && message[len - 1] == '\n') { message[len - 1] = 0; + } real_logger(level, priority, message); } static void sptps_logger(sptps_t *s, int s_errno, const char *format, va_list ap) { + (void)s_errno; char message[1024]; - size_t msglen = sizeof message; + size_t msglen = sizeof(message); int len = vsnprintf(message, msglen, format, ap); - message[sizeof message - 1] = 0; - if(len > 0 && len < sizeof message - 1) { - if(message[len - 1] == '\n') + message[sizeof(message) - 1] = 0; + + if(len > 0 && (size_t)len < sizeof(message) - 1) { + if(message[len - 1] == '\n') { message[--len] = 0; + } // WARNING: s->handle can point to a connection_t or a node_t, // but both types have the name and hostname fields at the same offsets. connection_t *c = s->handle; - if(c) - snprintf(message + len, sizeof message - len, " from %s (%s)", c->name, c->hostname); + + if(c) { + snprintf(message + len, sizeof(message) - len, " from %s (%s)", c->name, c->hostname); + } } real_logger(DEBUG_ALWAYS, LOG_ERR, message); @@ -144,51 +167,62 @@ void openlogger(const char *ident, logmode_t mode) { logmode = mode; switch(mode) { - case LOGMODE_STDERR: - logpid = getpid(); - break; - case LOGMODE_FILE: - logpid = getpid(); - logfile = fopen(logfilename, "a"); - if(!logfile) { - fprintf(stderr, "Could not open log file %s: %s\n", logfilename, strerror(errno)); - logmode = LOGMODE_NULL; - } - break; - case LOGMODE_SYSLOG: + case LOGMODE_STDERR: + logpid = getpid(); + break; + + case LOGMODE_FILE: + logpid = getpid(); + logfile = fopen(logfilename, "a"); + + if(!logfile) { + fprintf(stderr, "Could not open log file %s: %s\n", logfilename, strerror(errno)); + logmode = LOGMODE_NULL; + } + + break; + + case LOGMODE_SYSLOG: #ifdef HAVE_MINGW - loghandle = RegisterEventSource(NULL, logident); - if(!loghandle) { - fprintf(stderr, "Could not open log handle!"); - logmode = LOGMODE_NULL; - } - break; + loghandle = RegisterEventSource(NULL, logident); + + if(!loghandle) { + fprintf(stderr, "Could not open log handle!\n"); + logmode = LOGMODE_NULL; + } + + break; #else #ifdef HAVE_SYSLOG_H - openlog(logident, LOG_CONS | LOG_PID, LOG_DAEMON); - break; + openlog(logident, LOG_CONS | LOG_PID, LOG_DAEMON); + break; #endif #endif - case LOGMODE_NULL: - break; + + case LOGMODE_NULL: + break; } - if(logmode != LOGMODE_NULL) + if(logmode != LOGMODE_NULL) { sptps_log = sptps_logger; - else + } else { sptps_log = sptps_log_quiet; + } } void reopenlogger() { - if(logmode != LOGMODE_FILE) + if(logmode != LOGMODE_FILE) { return; + } fflush(logfile); FILE *newfile = fopen(logfilename, "a"); + if(!newfile) { logger(DEBUG_ALWAYS, LOG_ERR, "Unable to reopen log file %s: %s", logfilename, strerror(errno)); return; } + fclose(logfile); logfile = newfile; } @@ -196,21 +230,23 @@ void reopenlogger() { void closelogger(void) { switch(logmode) { - case LOGMODE_FILE: - fclose(logfile); - break; - case LOGMODE_SYSLOG: + case LOGMODE_FILE: + fclose(logfile); + break; + + case LOGMODE_SYSLOG: #ifdef HAVE_MINGW - DeregisterEventSource(loghandle); - break; + DeregisterEventSource(loghandle); + break; #else #ifdef HAVE_SYSLOG_H - closelog(); - break; + closelog(); + break; #endif #endif - case LOGMODE_NULL: - case LOGMODE_STDERR: - break; + + case LOGMODE_NULL: + case LOGMODE_STDERR: + break; } } diff --git a/src/logger.h b/src/logger.h index f4f46f9..611fe38 100644 --- a/src/logger.h +++ b/src/logger.h @@ -1,3 +1,6 @@ +#ifndef TINC_LOGGER_H +#define TINC_LOGGER_H + /* logger.h -- header file for logger.c Copyright (C) 1998-2005 Ivo Timmermans @@ -18,9 +21,6 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#ifndef __TINC_LOGGER_H__ -#define __TINC_LOGGER_H__ - typedef enum debug_t { DEBUG_NOTHING = 0, /* Quiet mode, only show starting/stopping of the daemon */ DEBUG_ALWAYS = 0, @@ -70,9 +70,9 @@ enum { extern int debug_level; extern bool logcontrol; extern int umbilical; -extern void openlogger(const char *, logmode_t); +extern void openlogger(const char *ident, logmode_t mode); extern void reopenlogger(void); -extern void logger(int, int, const char *, ...) __attribute__ ((__format__(printf, 3, 4))); +extern void logger(int level, int priority, const char *format, ...) __attribute__((__format__(printf, 3, 4))); extern void closelogger(void); -#endif /* __TINC_LOGGER_H__ */ +#endif diff --git a/src/meta.c b/src/meta.c index 4b35798..0089ac8 100644 --- a/src/meta.c +++ b/src/meta.c @@ -35,6 +35,7 @@ #endif bool send_meta_sptps(void *handle, uint8_t type, const void *buffer, size_t length) { + (void)type; connection_t *c = handle; if(!c) { @@ -48,23 +49,25 @@ bool send_meta_sptps(void *handle, uint8_t type, const void *buffer, size_t leng return true; } -bool send_meta(connection_t *c, const char *buffer, int length) { +bool send_meta(connection_t *c, const char *buffer, size_t length) { if(!c) { logger(DEBUG_ALWAYS, LOG_ERR, "send_meta() called with NULL pointer!"); abort(); } - logger(DEBUG_META, LOG_DEBUG, "Sending %d bytes of metadata to %s (%s)", length, - c->name, c->hostname); + logger(DEBUG_META, LOG_DEBUG, "Sending %lu bytes of metadata to %s (%s)", (unsigned long)length, + c->name, c->hostname); - if(c->protocol_minor >= 2) + if(c->protocol_minor >= 2) { return sptps_send_record(&c->sptps, 0, buffer, length); + } /* Add our data to buffer */ if(c->status.encryptout) { #ifdef DISABLE_LEGACY return false; #else + if(length > c->outbudget) { logger(DEBUG_META, LOG_ERR, "Byte limit exceeded for encryption to %s (%s)", c->name, c->hostname); return false; @@ -76,9 +79,10 @@ bool send_meta(connection_t *c, const char *buffer, int length) { if(!cipher_encrypt(c->outcipher, buffer, length, buffer_prepare(&c->outbuf, length), &outlen, false) || outlen != length) { logger(DEBUG_ALWAYS, LOG_ERR, "Error while encrypting metadata to %s (%s)", - c->name, c->hostname); + c->name, c->hostname); return false; } + #endif } else { buffer_add(&c->outbuf, buffer, length); @@ -89,24 +93,25 @@ bool send_meta(connection_t *c, const char *buffer, int length) { return true; } -void send_meta_raw(connection_t *c, const char *buffer, int length) { +void send_meta_raw(connection_t *c, const char *buffer, size_t length) { if(!c) { logger(DEBUG_ALWAYS, LOG_ERR, "send_meta() called with NULL pointer!"); abort(); } - logger(DEBUG_META, LOG_DEBUG, "Sending %d bytes of raw metadata to %s (%s)", length, - c->name, c->hostname); + logger(DEBUG_META, LOG_DEBUG, "Sending %lu bytes of raw metadata to %s (%s)", (unsigned long)length, + c->name, c->hostname); buffer_add(&c->outbuf, buffer, length); io_set(&c->io, IO_READ | IO_WRITE); } -void broadcast_meta(connection_t *from, const char *buffer, int length) { +void broadcast_meta(connection_t *from, const char *buffer, size_t length) { for list_each(connection_t, c, connection_list) - if(c != from && c->edge) + if(c != from && c->edge) { send_meta(c, buffer, length); + } } bool receive_meta_sptps(void *handle, uint8_t type, const void *vdata, uint16_t length) { @@ -119,20 +124,24 @@ bool receive_meta_sptps(void *handle, uint8_t type, const void *vdata, uint16_t } if(type == SPTPS_HANDSHAKE) { - if(c->allow_request == ACK) + if(c->allow_request == ACK) { return send_ack(c); - else + } else { return true; + } } - if(!data) + if(!data) { return true; + } /* Are we receiving a TCPpacket? */ if(c->tcplen) { - if(length != c->tcplen) + if(length != c->tcplen) { return false; + } + receive_tcppacket(c, data, length); c->tcplen = 0; return true; @@ -140,8 +149,9 @@ bool receive_meta_sptps(void *handle, uint8_t type, const void *vdata, uint16_t /* Change newline to null byte, just like non-SPTPS requests */ - if(data[length - 1] == '\n') + if(data[length - 1] == '\n') { ((char *)data)[length - 1] = 0; + } /* Otherwise we are waiting for a request */ @@ -149,7 +159,7 @@ bool receive_meta_sptps(void *handle, uint8_t type, const void *vdata, uint16_t } bool receive_meta(connection_t *c) { - int inlen; + ssize_t inlen; char inbuf[MAXBUFSIZE]; char *bufp = inbuf, *endp; @@ -164,22 +174,23 @@ bool receive_meta(connection_t *c) { buffer_compact(&c->inbuf, MAXBUFSIZE); - if(sizeof inbuf <= c->inbuf.len) { + if(sizeof(inbuf) <= c->inbuf.len) { logger(DEBUG_ALWAYS, LOG_ERR, "Input buffer full for %s (%s)", c->name, c->hostname); return false; } - inlen = recv(c->socket, inbuf, sizeof inbuf - c->inbuf.len, 0); + inlen = recv(c->socket, inbuf, sizeof(inbuf) - c->inbuf.len, 0); if(inlen <= 0) { if(!inlen || !sockerrno) { logger(DEBUG_CONNECTIONS, LOG_NOTICE, "Connection closed by %s (%s)", - c->name, c->hostname); - } else if(sockwouldblock(sockerrno)) + c->name, c->hostname); + } else if(sockwouldblock(sockerrno)) { return true; - else + } else logger(DEBUG_ALWAYS, LOG_ERR, "Metadata socket read error for %s (%s): %s", - c->name, c->hostname, sockstrerror(sockerrno)); + c->name, c->hostname, sockstrerror(sockerrno)); + return false; } @@ -187,15 +198,19 @@ bool receive_meta(connection_t *c) { /* Are we receiving a SPTPS packet? */ if(c->sptpslen) { - int len = MIN(inlen, c->sptpslen - c->inbuf.len); + ssize_t len = MIN(inlen, c->sptpslen - c->inbuf.len); buffer_add(&c->inbuf, bufp, len); char *sptpspacket = buffer_read(&c->inbuf, c->sptpslen); - if(!sptpspacket) - return true; - if(!receive_tcppacket_sptps(c, sptpspacket, c->sptpslen)) + if(!sptpspacket) { + return true; + } + + if(!receive_tcppacket_sptps(c, sptpspacket, c->sptpslen)) { return false; + } + c->sptpslen = 0; bufp += len; @@ -204,9 +219,12 @@ bool receive_meta(connection_t *c) { } if(c->protocol_minor >= 2) { - int len = sptps_receive_data(&c->sptps, bufp, inlen); - if(!len) + size_t len = sptps_receive_data(&c->sptps, bufp, inlen); + + if(!len) { return false; + } + bufp += len; inlen -= len; continue; @@ -214,10 +232,12 @@ bool receive_meta(connection_t *c) { if(!c->status.decryptin) { endp = memchr(bufp, '\n', inlen); - if(endp) + + if(endp) { endp++; - else + } else { endp = bufp + inlen; + } buffer_add(&c->inbuf, bufp, endp - bufp); @@ -227,8 +247,9 @@ bool receive_meta(connection_t *c) { #ifdef DISABLE_LEGACY return false; #else - if(inlen > c->inbudget) { - logger(DEBUG_META, LOG_ERR, "yte limit exceeded for decryption from %s (%s)", c->name, c->hostname); + + if((size_t)inlen > c->inbudget) { + logger(DEBUG_META, LOG_ERR, "Byte limit exceeded for decryption from %s (%s)", c->name, c->hostname); return false; } else { c->inbudget -= inlen; @@ -236,9 +257,9 @@ bool receive_meta(connection_t *c) { size_t outlen = inlen; - if(!cipher_decrypt(c->incipher, bufp, inlen, buffer_prepare(&c->inbuf, inlen), &outlen, false) || inlen != outlen) { + if(!cipher_decrypt(c->incipher, bufp, inlen, buffer_prepare(&c->inbuf, inlen), &outlen, false) || (size_t)inlen != outlen) { logger(DEBUG_ALWAYS, LOG_ERR, "Error while decrypting metadata from %s (%s)", - c->name, c->hostname); + c->name, c->hostname); return false; } @@ -251,8 +272,10 @@ bool receive_meta(connection_t *c) { if(c->tcplen) { char *tcpbuffer = buffer_read(&c->inbuf, c->tcplen); - if(!tcpbuffer) + + if(!tcpbuffer) { break; + } if(!c->node) { if(c->outgoing && proxytype == PROXY_SOCKS4 && c->allow_request == ID) { @@ -267,14 +290,17 @@ bool receive_meta(connection_t *c) { logger(DEBUG_CONNECTIONS, LOG_ERR, "Invalid response from proxy server"); return false; } + if(tcpbuffer[1] == (char)0xff) { logger(DEBUG_CONNECTIONS, LOG_ERR, "Proxy request rejected: unsuitable authentication method"); return false; } + if(tcpbuffer[2] != 5) { logger(DEBUG_CONNECTIONS, LOG_ERR, "Invalid response from proxy server"); return false; } + if(tcpbuffer[3] == 0) { logger(DEBUG_CONNECTIONS, LOG_DEBUG, "Proxy request granted"); } else { @@ -300,10 +326,14 @@ bool receive_meta(connection_t *c) { /* Otherwise we are waiting for a request */ char *request = buffer_readline(&c->inbuf); + if(request) { bool result = receive_request(c, request); - if(!result) + + if(!result) { return false; + } + continue; } else { break; diff --git a/src/meta.h b/src/meta.h index 8b00a5a..dcf2419 100644 --- a/src/meta.h +++ b/src/meta.h @@ -1,3 +1,6 @@ +#ifndef TINC_META_H +#define TINC_META_H + /* meta.h -- header for meta.c Copyright (C) 2000-2014 Guus Sliepen , @@ -18,16 +21,13 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#ifndef __TINC_META_H__ -#define __TINC_META_H__ - #include "connection.h" -extern bool send_meta(struct connection_t *, const char *, int); -extern void send_meta_raw(struct connection_t *, const char *, int); -extern bool send_meta_sptps(void *, uint8_t, const void *, size_t); -extern bool receive_meta_sptps(void *, uint8_t, const void *, uint16_t); -extern void broadcast_meta(struct connection_t *, const char *, int); -extern bool receive_meta(struct connection_t *); +extern bool send_meta(struct connection_t *c, const char *buffer, size_t length); +extern void send_meta_raw(struct connection_t *c, const char *buffer, size_t length); +extern bool send_meta_sptps(void *handle, uint8_t type, const void *data, size_t length); +extern bool receive_meta_sptps(void *handle, uint8_t type, const void *data, uint16_t length); +extern void broadcast_meta(struct connection_t *from, const char *buffer, size_t length); +extern bool receive_meta(struct connection_t *c); -#endif /* __TINC_META_H__ */ +#endif diff --git a/src/mingw/common.h b/src/mingw/common.h index 6e5e75c..ff052c9 100644 --- a/src/mingw/common.h +++ b/src/mingw/common.h @@ -1,3 +1,6 @@ +#ifndef TINC_MINGW_COMMON_H +#define TINC_MINGW_COMMON_H + /* * TAP-Win32 -- A kernel driver to provide virtual tap device functionality * on Windows. Originally derived from the CIPE-Win32 @@ -37,7 +40,7 @@ //============= #define TAP_CONTROL_CODE(request,method) \ - CTL_CODE (FILE_DEVICE_UNKNOWN, request, method, FILE_ANY_ACCESS) + CTL_CODE (FILE_DEVICE_UNKNOWN, request, method, FILE_ANY_ACCESS) #define TAP_IOCTL_GET_MAC TAP_CONTROL_CODE (1, METHOD_BUFFERED) #define TAP_IOCTL_GET_VERSION TAP_CONTROL_CODE (2, METHOD_BUFFERED) @@ -73,3 +76,5 @@ //========================================================= #define TAP_COMPONENT_ID "tap0801" + +#endif diff --git a/src/mingw/device.c b/src/mingw/device.c index dfdb964..183641b 100644 --- a/src/mingw/device.c +++ b/src/mingw/device.c @@ -43,22 +43,24 @@ static vpn_packet_t device_read_packet; static vpn_packet_t device_write_packet; char *device = NULL; char *iface = NULL; -static char *device_info = NULL; +static const char *device_info = "Windows tap device"; extern char *myport; static void device_issue_read() { - device_read_overlapped.Offset = 0; - device_read_overlapped.OffsetHigh = 0; - int status; - for (;;) { + + for(;;) { + ResetEvent(device_read_overlapped.hEvent); + DWORD len; status = ReadFile(device_handle, (void *)device_read_packet.data, MTU, &len, &device_read_overlapped); - if (!status) { - if (GetLastError() != ERROR_IO_PENDING) + + if(!status) { + if(GetLastError() != ERROR_IO_PENDING) logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info, - device, strerror(errno)); + device, strerror(errno)); + break; } @@ -69,12 +71,17 @@ static void device_issue_read() { } static void device_handle_read(void *data, int flags) { - ResetEvent(device_read_overlapped.hEvent); - DWORD len; - if (!GetOverlappedResult(device_handle, &device_read_overlapped, &len, FALSE)) { + + if(!GetOverlappedResult(device_handle, &device_read_overlapped, &len, FALSE)) { logger(DEBUG_ALWAYS, LOG_ERR, "Error getting read result from %s %s: %s", device_info, - device, strerror(errno)); + device, strerror(errno)); + + if(GetLastError() != ERROR_IO_INCOMPLETE) { + /* Must reset event or it will keep firing. */ + ResetEvent(device_read_overlapped.hEvent); + } + return; } @@ -101,8 +108,9 @@ static bool setup_device(void) { get_config_string(lookup_config(config_tree, "Device"), &device); get_config_string(lookup_config(config_tree, "Interface"), &iface); - if(device && iface) + if(device && iface) { logger(DEBUG_ALWAYS, LOG_WARNING, "Warning: both Device and Interface specified, results may not be as expected"); + } /* Open registry and look for network adapters */ @@ -111,44 +119,51 @@ static bool setup_device(void) { return false; } - for (i = 0; ; i++) { - len = sizeof adapterid; - if(RegEnumKeyEx(key, i, adapterid, &len, 0, 0, 0, NULL)) + for(i = 0; ; i++) { + len = sizeof(adapterid); + + if(RegEnumKeyEx(key, i, adapterid, &len, 0, 0, 0, NULL)) { break; + } /* Find out more about this adapter */ - snprintf(regpath, sizeof regpath, "%s\\%s\\Connection", NETWORK_CONNECTIONS_KEY, adapterid); + snprintf(regpath, sizeof(regpath), "%s\\%s\\Connection", NETWORK_CONNECTIONS_KEY, adapterid); - if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, regpath, 0, KEY_READ, &key2)) + if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, regpath, 0, KEY_READ, &key2)) { continue; + } - len = sizeof adaptername; + len = sizeof(adaptername); err = RegQueryValueEx(key2, "Name", 0, 0, (LPBYTE)adaptername, &len); RegCloseKey(key2); - if(err) + if(err) { continue; + } if(device) { if(!strcmp(device, adapterid)) { found = true; break; - } else + } else { continue; + } } if(iface) { if(!strcmp(iface, adaptername)) { found = true; break; - } else + } else { continue; + } } - snprintf(tapname, sizeof tapname, USERMODEDEVICEDIR "%s" TAPSUFFIX, adapterid); + snprintf(tapname, sizeof(tapname), USERMODEDEVICEDIR "%s" TAPSUFFIX, adapterid); device_handle = CreateFile(tapname, GENERIC_WRITE | GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED, 0); + if(device_handle != INVALID_HANDLE_VALUE) { found = true; break; @@ -162,16 +177,18 @@ static bool setup_device(void) { return false; } - if(!device) + if(!device) { device = xstrdup(adapterid); + } - if(!iface) + if(!iface) { iface = xstrdup(adaptername); + } /* Try to open the corresponding tap device */ if(device_handle == INVALID_HANDLE_VALUE) { - snprintf(tapname, sizeof tapname, USERMODEDEVICEDIR "%s" TAPSUFFIX, device); + snprintf(tapname, sizeof(tapname), USERMODEDEVICEDIR "%s" TAPSUFFIX, device); device_handle = CreateFile(tapname, GENERIC_WRITE | GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED, 0); } @@ -185,23 +202,24 @@ static bool setup_device(void) { { ULONG info[3] = {0}; DWORD len; - if(!DeviceIoControl(device_handle, TAP_IOCTL_GET_VERSION, &info, sizeof info, &info, sizeof info, &len, NULL)) + + if(!DeviceIoControl(device_handle, TAP_IOCTL_GET_VERSION, &info, sizeof(info), &info, sizeof(info), &len, NULL)) { logger(DEBUG_ALWAYS, LOG_WARNING, "Could not get version information from Windows tap device %s (%s): %s", device, iface, winerror(GetLastError())); - else { + } else { logger(DEBUG_ALWAYS, LOG_INFO, "TAP-Windows driver version: %lu.%lu%s", info[0], info[1], info[2] ? " (DEBUG)" : ""); /* Warn if using >=9.21. This is because starting from 9.21, TAP-Win32 seems to use a different, less efficient write path. */ if(info[0] == 9 && info[1] >= 21) logger(DEBUG_ALWAYS, LOG_WARNING, - "You are using the newer (>= 9.0.0.21, NDIS6) series of TAP-Win32 drivers. " - "Using these drivers with tinc is not recommanded as it can result in poor performance. " - "You might want to revert back to 9.0.0.9 instead."); + "You are using the newer (>= 9.0.0.21, NDIS6) series of TAP-Win32 drivers. " + "Using these drivers with tinc is not recommended as it can result in poor performance. " + "You might want to revert back to 9.0.0.9 instead."); } } /* Get MAC address from tap device */ - if(!DeviceIoControl(device_handle, TAP_IOCTL_GET_MAC, mymac.x, sizeof mymac.x, mymac.x, sizeof mymac.x, &len, 0)) { + if(!DeviceIoControl(device_handle, TAP_IOCTL_GET_MAC, mymac.x, sizeof(mymac.x), mymac.x, sizeof(mymac.x), &len, 0)) { logger(DEBUG_ALWAYS, LOG_ERR, "Could not get MAC address from Windows tap device %s (%s): %s", device, iface, winerror(GetLastError())); return false; } @@ -225,7 +243,7 @@ static void enable_device(void) { ULONG status = 1; DWORD len; - DeviceIoControl(device_handle, TAP_IOCTL_SET_MEDIA_STATUS, &status, sizeof status, &status, sizeof status, &len, NULL); + DeviceIoControl(device_handle, TAP_IOCTL_SET_MEDIA_STATUS, &status, sizeof(status), &status, sizeof(status), &len, NULL); /* We don't use the write event directly, but GetOverlappedResult() does, internally. */ @@ -240,7 +258,7 @@ static void disable_device(void) { ULONG status = 0; DWORD len; - DeviceIoControl(device_handle, TAP_IOCTL_SET_MEDIA_STATUS, &status, sizeof status, &status, sizeof status, &len, NULL); + DeviceIoControl(device_handle, TAP_IOCTL_SET_MEDIA_STATUS, &status, sizeof(status), &status, sizeof(status), &len, NULL); /* Note that we don't try to cancel ongoing I/O here - we just stop listening. This is because some TAP-Win32 drivers don't seem to handle cancellation very well, @@ -257,19 +275,27 @@ static void close_device(void) { before we close the event it's referencing. */ DWORD len; - if(!GetOverlappedResult(device_handle, &device_read_overlapped, &len, TRUE) && GetLastError() != ERROR_OPERATION_ABORTED) + + if(!GetOverlappedResult(device_handle, &device_read_overlapped, &len, TRUE) && GetLastError() != ERROR_OPERATION_ABORTED) { logger(DEBUG_ALWAYS, LOG_ERR, "Could not wait for %s %s read to cancel: %s", device_info, device, winerror(GetLastError())); - if(device_write_packet.len > 0 && !GetOverlappedResult(device_handle, &device_write_overlapped, &len, TRUE) && GetLastError() != ERROR_OPERATION_ABORTED) + } + + if(device_write_packet.len > 0 && !GetOverlappedResult(device_handle, &device_write_overlapped, &len, TRUE) && GetLastError() != ERROR_OPERATION_ABORTED) { logger(DEBUG_ALWAYS, LOG_ERR, "Could not wait for %s %s write to cancel: %s", device_info, device, winerror(GetLastError())); + } + device_write_packet.len = 0; CloseHandle(device_read_overlapped.hEvent); CloseHandle(device_write_overlapped.hEvent); - CloseHandle(device_handle); device_handle = INVALID_HANDLE_VALUE; + CloseHandle(device_handle); + device_handle = INVALID_HANDLE_VALUE; - free(device); device = NULL; - free(iface); iface = NULL; + free(device); + device = NULL; + free(iface); + iface = NULL; device_info = NULL; } @@ -281,7 +307,7 @@ static bool write_packet(vpn_packet_t *packet) { DWORD outlen; logger(DEBUG_TRAFFIC, LOG_DEBUG, "Writing packet of %d bytes to %s", - packet->len, device_info); + packet->len, device_info); if(device_write_packet.len > 0) { /* Make sure the previous write operation is finished before we start the next one; @@ -289,20 +315,28 @@ static bool write_packet(vpn_packet_t *packet) { which according to MSDN is a no-no. */ if(!GetOverlappedResult(device_handle, &device_write_overlapped, &outlen, FALSE)) { - int log_level = (GetLastError() == ERROR_IO_INCOMPLETE) ? DEBUG_TRAFFIC : DEBUG_ALWAYS; - logger(log_level, LOG_ERR, "Error while checking previous write to %s %s: %s", device_info, device, winerror(GetLastError())); - return false; + if(GetLastError() != ERROR_IO_INCOMPLETE) { + logger(DEBUG_ALWAYS, LOG_ERR, "Error completing previously queued write to %s %s: %s", device_info, device, winerror(GetLastError())); + } else { + logger(DEBUG_TRAFFIC, LOG_ERR, "Previous overlapped write to %s %s still in progress", device_info, device); + // drop this packet + return true; + } } } /* Copy the packet, since the write operation might still be ongoing after we return. */ - memcpy(&device_write_packet, packet, sizeof *packet); + memcpy(&device_write_packet, packet, sizeof(*packet)); - if(WriteFile(device_handle, DATA(&device_write_packet), device_write_packet.len, &outlen, &device_write_overlapped)) + ResetEvent(device_write_overlapped.hEvent); + + if(WriteFile(device_handle, DATA(&device_write_packet), device_write_packet.len, &outlen, &device_write_overlapped)) { + // Write was completed immediately. device_write_packet.len = 0; - else if (GetLastError() != ERROR_IO_PENDING) { + } else if(GetLastError() != ERROR_IO_PENDING) { logger(DEBUG_ALWAYS, LOG_ERR, "Error while writing to %s %s: %s", device_info, device, winerror(GetLastError())); + device_write_packet.len = 0; return false; } diff --git a/src/multicast_device.c b/src/multicast_device.c index 8dab9e0..e9607f0 100644 --- a/src/multicast_device.c +++ b/src/multicast_device.c @@ -29,10 +29,10 @@ #include "route.h" #include "xalloc.h" -static char *device_info; +static const char *device_info = "multicast socket"; static struct addrinfo *ai = NULL; -static mac_t ignore_src = {{0}}; +static mac_t ignore_src = {0}; static bool setup_device(void) { char *host = NULL; @@ -40,8 +40,6 @@ static bool setup_device(void) { char *space; int ttl = 1; - device_info = "multicast socket"; - get_config_string(lookup_config(config_tree, "Interface"), &iface); if(!get_config_string(lookup_config(config_tree, "Device"), &device)) { @@ -51,6 +49,7 @@ static bool setup_device(void) { host = xstrdup(device); space = strchr(host, ' '); + if(!space) { logger(DEBUG_ALWAYS, LOG_ERR, "Port number required for %s", device_info); goto error; @@ -66,10 +65,13 @@ static bool setup_device(void) { } ai = str2addrinfo(host, port, SOCK_DGRAM); - if(!ai) + + if(!ai) { goto error; + } device_fd = socket(ai->ai_family, SOCK_DGRAM, IPPROTO_UDP); + if(device_fd < 0) { logger(DEBUG_ALWAYS, LOG_ERR, "Creating socket failed: %s", sockstrerror(sockerrno)); goto error; @@ -80,7 +82,7 @@ static bool setup_device(void) { #endif static const int one = 1; - setsockopt(device_fd, SOL_SOCKET, SO_REUSEADDR, (void *)&one, sizeof one); + setsockopt(device_fd, SOL_SOCKET, SO_REUSEADDR, (void *)&one, sizeof(one)); if(bind(device_fd, ai->ai_addr, ai->ai_addrlen)) { logger(DEBUG_ALWAYS, LOG_ERR, "Can't bind to %s %s: %s", host, port, sockstrerror(sockerrno)); @@ -89,48 +91,56 @@ static bool setup_device(void) { switch(ai->ai_family) { #ifdef IP_ADD_MEMBERSHIP - case AF_INET: { - struct ip_mreq mreq; - struct sockaddr_in in; - memcpy(&in, ai->ai_addr, sizeof in); - mreq.imr_multiaddr.s_addr = in.sin_addr.s_addr; - mreq.imr_interface.s_addr = htonl(INADDR_ANY); - if(setsockopt(device_fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (void *)&mreq, sizeof mreq)) { - logger(DEBUG_ALWAYS, LOG_ERR, "Cannot join multicast group %s %s: %s", host, port, sockstrerror(sockerrno)); - goto error; - } + + case AF_INET: { + struct ip_mreq mreq; + struct sockaddr_in in; + memcpy(&in, ai->ai_addr, sizeof(in)); + mreq.imr_multiaddr.s_addr = in.sin_addr.s_addr; + mreq.imr_interface.s_addr = htonl(INADDR_ANY); + + if(setsockopt(device_fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (void *)&mreq, sizeof(mreq))) { + logger(DEBUG_ALWAYS, LOG_ERR, "Cannot join multicast group %s %s: %s", host, port, sockstrerror(sockerrno)); + goto error; + } + #ifdef IP_MULTICAST_LOOP - setsockopt(device_fd, IPPROTO_IP, IP_MULTICAST_LOOP, (const void *)&one, sizeof one); + setsockopt(device_fd, IPPROTO_IP, IP_MULTICAST_LOOP, (const void *)&one, sizeof(one)); #endif #ifdef IP_MULTICAST_TTL - setsockopt(device_fd, IPPROTO_IP, IP_MULTICAST_TTL, (void *)&ttl, sizeof ttl); + setsockopt(device_fd, IPPROTO_IP, IP_MULTICAST_TTL, (void *)&ttl, sizeof(ttl)); #endif - } break; + } + break; #endif #ifdef IPV6_JOIN_GROUP - case AF_INET6: { - struct ipv6_mreq mreq; - struct sockaddr_in6 in6; - memcpy(&in6, ai->ai_addr, sizeof in6); - memcpy(&mreq.ipv6mr_multiaddr, &in6.sin6_addr, sizeof mreq.ipv6mr_multiaddr); - mreq.ipv6mr_interface = in6.sin6_scope_id; - if(setsockopt(device_fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, (void *)&mreq, sizeof mreq)) { - logger(DEBUG_ALWAYS, LOG_ERR, "Cannot join multicast group %s %s: %s", host, port, sockstrerror(sockerrno)); - goto error; - } + + case AF_INET6: { + struct ipv6_mreq mreq; + struct sockaddr_in6 in6; + memcpy(&in6, ai->ai_addr, sizeof(in6)); + memcpy(&mreq.ipv6mr_multiaddr, &in6.sin6_addr, sizeof(mreq.ipv6mr_multiaddr)); + mreq.ipv6mr_interface = in6.sin6_scope_id; + + if(setsockopt(device_fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, (void *)&mreq, sizeof(mreq))) { + logger(DEBUG_ALWAYS, LOG_ERR, "Cannot join multicast group %s %s: %s", host, port, sockstrerror(sockerrno)); + goto error; + } + #ifdef IPV6_MULTICAST_LOOP - setsockopt(device_fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, (const void *)&one, sizeof one); + setsockopt(device_fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, (const void *)&one, sizeof(one)); #endif #ifdef IPV6_MULTICAST_HOPS - setsockopt(device_fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, (void *)&ttl, sizeof ttl); + setsockopt(device_fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, (void *)&ttl, sizeof(ttl)); #endif - } break; + } + break; #endif - default: - logger(DEBUG_ALWAYS, LOG_ERR, "Multicast for address family %x unsupported", ai->ai_family); - goto error; + default: + logger(DEBUG_ALWAYS, LOG_ERR, "Multicast for address family %x unsupported", ai->ai_family); + goto error; } logger(DEBUG_ALWAYS, LOG_INFO, "%s is a %s", device, device_info); @@ -138,24 +148,34 @@ static bool setup_device(void) { return true; error: - if(device_fd >= 0) + + if(device_fd >= 0) { closesocket(device_fd); - if(ai) + } + + if(ai) { freeaddrinfo(ai); + } + free(host); return false; } static void close_device(void) { - close(device_fd); device_fd = -1; + close(device_fd); + device_fd = -1; - free(device); device = NULL; - free(iface); iface = NULL; + free(device); + device = NULL; + free(iface); + iface = NULL; if(ai) { - freeaddrinfo(ai); ai = NULL; + freeaddrinfo(ai); + ai = NULL; } + device_info = NULL; } @@ -164,11 +184,11 @@ static bool read_packet(vpn_packet_t *packet) { if((lenin = recv(device_fd, (void *)DATA(packet), MTU, 0)) <= 0) { logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info, - device, sockstrerror(sockerrno)); + device, sockstrerror(sockerrno)); return false; } - if(!memcmp(&ignore_src, DATA(packet) + 6, sizeof ignore_src)) { + if(!memcmp(&ignore_src, DATA(packet) + 6, sizeof(ignore_src))) { logger(DEBUG_SCARY_THINGS, LOG_DEBUG, "Ignoring loopback packet of %d bytes from %s", lenin, device_info); return false; } @@ -176,22 +196,22 @@ static bool read_packet(vpn_packet_t *packet) { packet->len = lenin; logger(DEBUG_TRAFFIC, LOG_DEBUG, "Read packet of %d bytes from %s", packet->len, - device_info); + device_info); return true; } static bool write_packet(vpn_packet_t *packet) { logger(DEBUG_TRAFFIC, LOG_DEBUG, "Writing packet of %d bytes to %s", - packet->len, device_info); + packet->len, device_info); if(sendto(device_fd, (void *)DATA(packet), packet->len, 0, ai->ai_addr, ai->ai_addrlen) < 0) { logger(DEBUG_ALWAYS, LOG_ERR, "Can't write to %s %s: %s", device_info, device, - sockstrerror(sockerrno)); + sockstrerror(sockerrno)); return false; } - memcpy(&ignore_src, DATA(packet) + 6, sizeof ignore_src); + memcpy(&ignore_src, DATA(packet) + 6, sizeof(ignore_src)); return true; } diff --git a/src/names.c b/src/names.c index 0cae28a..6db364e 100644 --- a/src/names.c +++ b/src/names.c @@ -42,91 +42,120 @@ void make_names(bool daemon) { #ifdef HAVE_MINGW HKEY key; char installdir[1024] = ""; - DWORD len = sizeof installdir; + DWORD len = sizeof(installdir); #endif confbase_given = confbase; - if(netname && confbase) + if(netname && confbase) { logger(DEBUG_ALWAYS, LOG_INFO, "Both netname and configuration directory given, using the latter..."); + } - if(netname) + if(netname) { xasprintf(&identname, "tinc.%s", netname); - else + } else { identname = xstrdup("tinc"); + } #ifdef HAVE_MINGW + if(!RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\tinc", 0, KEY_READ, &key)) { if(!RegQueryValueEx(key, NULL, 0, 0, (LPBYTE)installdir, &len)) { confdir = xstrdup(installdir); + if(!confbase) { - if(netname) + if(netname) { xasprintf(&confbase, "%s" SLASH "%s", installdir, netname); - else + } else { xasprintf(&confbase, "%s", installdir); + } } - if(!logfilename) + + if(!logfilename) { xasprintf(&logfilename, "%s" SLASH "tinc.log", confbase); + } } + RegCloseKey(key); } + #endif - if(!confdir) + + if(!confdir) { confdir = xstrdup(CONFDIR SLASH "tinc"); + } if(!confbase) { - if(netname) + if(netname) { xasprintf(&confbase, CONFDIR SLASH "tinc" SLASH "%s", netname); - else + } else { xasprintf(&confbase, CONFDIR SLASH "tinc"); + } } #ifdef HAVE_MINGW - if(!logfilename) - xasprintf(&logfilename, "%s" SLASH "log", confbase); - if(!pidfilename) + if(!logfilename) { + xasprintf(&logfilename, "%s" SLASH "log", confbase); + } + + if(!pidfilename) { xasprintf(&pidfilename, "%s" SLASH "pid", confbase); + } + #else bool fallback = false; + if(daemon) { - if(access(LOCALSTATEDIR, R_OK | W_OK | X_OK)) + if(access(LOCALSTATEDIR, R_OK | W_OK | X_OK)) { fallback = true; + } } else { char fname[PATH_MAX]; - snprintf(fname, sizeof fname, LOCALSTATEDIR SLASH "run" SLASH "%s.pid", identname); + snprintf(fname, sizeof(fname), LOCALSTATEDIR SLASH "run" SLASH "%s.pid", identname); + if(access(fname, R_OK)) { - snprintf(fname, sizeof fname, "%s" SLASH "pid", confbase); - if(!access(fname, R_OK)) + snprintf(fname, sizeof(fname), "%s" SLASH "pid", confbase); + + if(!access(fname, R_OK)) { fallback = true; + } } } if(!fallback) { - if(!logfilename) + if(!logfilename) { xasprintf(&logfilename, LOCALSTATEDIR SLASH "log" SLASH "%s.log", identname); - - if(!pidfilename) - xasprintf(&pidfilename, LOCALSTATEDIR SLASH "run" SLASH "%s.pid", identname); - } else { - if(!logfilename) - xasprintf(&logfilename, "%s" SLASH "log", confbase); + } if(!pidfilename) { - if(daemon) + xasprintf(&pidfilename, LOCALSTATEDIR SLASH "run" SLASH "%s.pid", identname); + } + } else { + if(!logfilename) { + xasprintf(&logfilename, "%s" SLASH "log", confbase); + } + + if(!pidfilename) { + if(daemon) { logger(DEBUG_ALWAYS, LOG_WARNING, "Could not access " LOCALSTATEDIR SLASH " (%s), storing pid and socket files in %s" SLASH, strerror(errno), confbase); + } + xasprintf(&pidfilename, "%s" SLASH "pid", confbase); } } + #endif if(!unixsocketname) { int len = strlen(pidfilename); unixsocketname = xmalloc(len + 8); memcpy(unixsocketname, pidfilename, len); - if(len > 4 && !strcmp(pidfilename + len - 4, ".pid")) + + if(len > 4 && !strcmp(pidfilename + len - 4, ".pid")) { strncpy(unixsocketname + len - 4, ".socket", 8); - else + } else { strncpy(unixsocketname + len, ".socket", 8); + } } } diff --git a/src/names.h b/src/names.h index e6b99c5..f109686 100644 --- a/src/names.h +++ b/src/names.h @@ -1,3 +1,6 @@ +#ifndef TINC_NAMES_H +#define TINC_NAMES_H + /* names.h -- header for names.c Copyright (C) 1998-2005 Ivo Timmermans @@ -18,9 +21,6 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#ifndef __TINC_NAMES_H__ -#define __TINC_NAMES_H__ - extern char *confdir; extern char *confbase; extern bool confbase_given; @@ -35,4 +35,4 @@ extern char *program_name; extern void make_names(bool daemon); extern void free_names(void); -#endif /* __TINC_NAMES_H__ */ +#endif diff --git a/src/net.c b/src/net.c index 1cb467d..75838e0 100644 --- a/src/net.c +++ b/src/net.c @@ -58,13 +58,17 @@ void purge(void) { for splay_each(subnet_t, s, n->subnet_tree) { send_del_subnet(everyone, s); - if(!strictsubnets) + + if(!strictsubnets) { subnet_del(n, s); + } } for splay_each(edge_t, e, n->edge_tree) { - if(!tunnelserver) + if(!tunnelserver) { send_del_edge(everyone, e); + } + edge_del(e); } } @@ -75,16 +79,35 @@ void purge(void) { for splay_each(node_t, n, node_tree) { if(!n->status.reachable) { for splay_each(edge_t, e, edge_weight_tree) - if(e->to == n) + if(e->to == n) { return; + } if(!autoconnect && (!strictsubnets || !n->subnet_tree->head)) /* in strictsubnets mode do not delete nodes with subnets */ + { node_del(n); + } } } } +/* Put a misbehaving connection in the tarpit */ +void tarpit(int fd) { + static int pits[10] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1}; + static unsigned int next_pit = 0; + + if(pits[next_pit] != -1) { + closesocket(pits[next_pit]); + } + + pits[next_pit++] = fd; + + if(next_pit >= sizeof pits / sizeof pits[0]) { + next_pit = 0; + } +} + /* Terminate a connection: - Mark it as inactive @@ -96,12 +119,14 @@ void terminate_connection(connection_t *c, bool report) { logger(DEBUG_CONNECTIONS, LOG_NOTICE, "Closing connection with %s (%s)", c->name, c->hostname); if(c->node) { - if(c->node->connection == c) + if(c->node->connection == c) { c->node->connection = NULL; + } if(c->edge) { - if(report && !tunnelserver) + if(report && !tunnelserver) { send_del_edge(everyone, c->edge); + } edge_del(c->edge); c->edge = NULL; @@ -115,9 +140,12 @@ void terminate_connection(connection_t *c, bool report) { if(report && !c->node->status.reachable) { edge_t *e; e = lookup_edge(c->node, myself); + if(e) { - if(!tunnelserver) + if(!tunnelserver) { send_del_edge(everyone, e); + } + edge_del(e); } } @@ -129,13 +157,15 @@ void terminate_connection(connection_t *c, bool report) { /* Check if this was our outgoing connection */ - if(outgoing) + if(outgoing) { do_outgoing_connection(outgoing); + } #ifndef HAVE_MINGW /* Clean up dead proxy processes */ while(waitpid(-1, NULL, WNOHANG) > 0); + #endif } @@ -152,37 +182,40 @@ static void timeout_handler(void *data) { bool close_all_connections = false; /* - timeout_handler will start after 30 seconds from start of tincd - hold information about the elapsed time since last time the handler - has been run + timeout_handler will start after 30 seconds from start of tincd + hold information about the elapsed time since last time the handler + has been run */ long sleep_time = now.tv_sec - last_periodic_run_time.tv_sec; + /* - It seems that finding sane default value is harder than expected - Since we send every second a UDP packet to make holepunching work - And default UDP state expire on firewalls is between 15-30 seconds - we drop all connections after 60 Seconds - UDPDiscoveryTimeout=30 - by default + It seems that finding sane default value is harder than expected + Since we send every second a UDP packet to make holepunching work + And default UDP state expire on firewalls is between 15-30 seconds + we drop all connections after 60 Seconds - UDPDiscoveryTimeout=30 + by default */ - if (sleep_time > 2 * udp_discovery_timeout) { + if(sleep_time > 2 * udp_discovery_timeout) { logger(DEBUG_ALWAYS, LOG_ERR, "Awaking from dead after %ld seconds of sleep", sleep_time); /* - Do not send any packets to tinc after we wake up. - The other node probably closed our connection but we still - are holding context information to them. This may happen on - laptops or any other hardware which can be suspended for some time. - Sending any data to node that wasn't expecting it will produce - annoying and misleading errors on the other side about failed signature - verification and or about missing sptps context + Do not send any packets to tinc after we wake up. + The other node probably closed our connection but we still + are holding context information to them. This may happen on + laptops or any other hardware which can be suspended for some time. + Sending any data to node that wasn't expecting it will produce + annoying and misleading errors on the other side about failed signature + verification and or about missing sptps context */ close_all_connections = true; } + last_periodic_run_time = now; for list_each(connection_t, c, connection_list) { // control connections (eg. tinc ctl) do not have any timeout - if(c->status.control) + if(c->status.control) { continue; + } if(close_all_connections) { logger(DEBUG_ALWAYS, LOG_ERR, "Forcing connection close after sleep time %s (%s)", c->name, c->hostname); @@ -191,15 +224,18 @@ static void timeout_handler(void *data) { } // Bail out early if we haven't reached the ping timeout for this node yet - if(c->last_ping_time + pingtimeout > now.tv_sec) + if(c->last_ping_time + pingtimeout > now.tv_sec) { continue; + } // timeout during connection establishing if(!c->edge) { - if(c->status.connecting) + if(c->status.connecting) { logger(DEBUG_CONNECTIONS, LOG_WARNING, "Timeout while connecting to %s (%s)", c->name, c->hostname); - else + } else { logger(DEBUG_CONNECTIONS, LOG_WARNING, "Timeout from %s (%s) during authentication", c->name, c->hostname); + c->status.tarpit = true; + } terminate_connection(c, c->edge); continue; @@ -216,11 +252,14 @@ static void timeout_handler(void *data) { } // check whether we need to send a new ping - if(c->last_ping_time + pinginterval <= now.tv_sec) + if(c->last_ping_time + pinginterval <= now.tv_sec) { send_ping(c); + } } - timeout_set(data, &(struct timeval){1, rand() % 100000}); + timeout_set(data, &(struct timeval) { + 1, rand() % 100000 + }); } static void periodic_handler(void *data) { @@ -231,14 +270,20 @@ static void periodic_handler(void *data) { if(contradicting_del_edge > 100 && contradicting_add_edge > 100) { logger(DEBUG_ALWAYS, LOG_WARNING, "Possible node with same Name as us! Sleeping %d seconds.", sleeptime); - nanosleep(&(struct timespec){sleeptime, 0}, NULL); + nanosleep(&(struct timespec) { + sleeptime, 0 + }, NULL); sleeptime *= 2; - if(sleeptime < 0) + + if(sleeptime < 0) { sleeptime = 3600; + } } else { sleeptime /= 2; - if(sleeptime < 10) + + if(sleeptime < 10) { sleeptime = 10; + } } contradicting_add_edge = 0; @@ -246,14 +291,21 @@ static void periodic_handler(void *data) { /* If AutoConnect is set, check if we need to make or break connections. */ - if(autoconnect && node_tree->count > 1) + if(autoconnect && node_tree->count > 1) { do_autoconnect(); + } - timeout_set(data, &(struct timeval){5, rand() % 100000}); + timeout_set(data, &(struct timeval) { + 5, rand() % 100000 + }); } void handle_meta_connection_data(connection_t *c) { - if (!receive_meta(c)) { + if(!receive_meta(c)) { + if(!c->status.control) { + c->status.tarpit = true; + } + terminate_connection(c, c->edge); return; } @@ -268,8 +320,10 @@ static void sigterm_handler(void *data) { static void sighup_handler(void *data) { logger(DEBUG_ALWAYS, LOG_NOTICE, "Got %s signal", strsignal(((signal_t *)data)->signum)); reopenlogger(); - if(reload_configuration()) + + if(reload_configuration()) { exit(1); + } } static void sigalrm_handler(void *data) { @@ -293,8 +347,8 @@ int reload_configuration(void) { read_config_options(config_tree, NULL); - snprintf(fname, sizeof fname, "%s" SLASH "hosts" SLASH "%s", confbase, myself->name); - read_config_file(config_tree, fname); + snprintf(fname, sizeof(fname), "%s" SLASH "hosts" SLASH "%s", confbase, myself->name); + read_config_file(config_tree, fname, true); /* Parse some options that are allowed to be changed while tinc is running */ @@ -304,48 +358,60 @@ int reload_configuration(void) { if(strictsubnets) { for splay_each(subnet_t, subnet, subnet_tree) - if (subnet->owner) + if(subnet->owner) { subnet->expires = 1; + } } - for splay_each(node_t, n, node_tree) + for splay_each(node_t, n, node_tree) { n->status.has_address = false; + } load_all_nodes(); if(strictsubnets) { for splay_each(subnet_t, subnet, subnet_tree) { - if (!subnet->owner) + if(!subnet->owner) { continue; + } + if(subnet->expires == 1) { send_del_subnet(everyone, subnet); - if(subnet->owner->status.reachable) + + 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(everyone, subnet); - if(subnet->owner->status.reachable) + + if(subnet->owner->status.reachable) { subnet_update(subnet->owner, subnet, true); + } } } } else { /* Only read our own subnets back in */ for splay_each(subnet_t, subnet, myself->subnet_tree) - if(!subnet->expires) + if(!subnet->expires) { subnet->expires = 1; + } config_t *cfg = lookup_config(config_tree, "Subnet"); while(cfg) { subnet_t *subnet, *s2; - if(!get_config_subnet(cfg, &subnet)) + if(!get_config_subnet(cfg, &subnet)) { continue; + } if((s2 = lookup_subnet(myself, subnet))) { - if(s2->expires == 1) + if(s2->expires == 1) { s2->expires = 0; + } free_subnet(subnet); } else { @@ -373,11 +439,13 @@ int reload_configuration(void) { /* Close connections to hosts that have a changed or deleted host config file */ for list_each(connection_t, c, connection_list) { - if(c->status.control) + if(c->status.control) { continue; + } - snprintf(fname, sizeof fname, "%s" SLASH "hosts" SLASH "%s", confbase, c->name); + snprintf(fname, sizeof(fname), "%s" SLASH "hosts" SLASH "%s", confbase, c->name); struct stat s; + if(stat(fname, &s) || s.st_mtime > last_config_check) { logger(DEBUG_CONNECTIONS, LOG_INFO, "Host config file of %s has been changed", c->name); terminate_connection(c, c->edge); @@ -393,18 +461,24 @@ void retry(void) { /* Reset the reconnection timers for all outgoing connections */ for list_each(outgoing_t, outgoing, outgoing_list) { outgoing->timeout = 0; + if(outgoing->ev.cb) - timeout_set(&outgoing->ev, &(struct timeval){0, 0}); + timeout_set(&outgoing->ev, &(struct timeval) { + 0, 0 + }); } /* Check for outgoing connections that are in progress, and reset their ping timers */ for list_each(connection_t, c, connection_list) { - if(c->outgoing && !c->node) + if(c->outgoing && !c->node) { c->last_ping_time = 0; + } } /* Kick the ping timeout handler */ - timeout_set(&pingtimer, &(struct timeval){0, 0}); + timeout_set(&pingtimer, &(struct timeval) { + 0, 0 + }); } /* @@ -412,8 +486,12 @@ void retry(void) { */ int main_loop(void) { last_periodic_run_time = now; - timeout_add(&pingtimer, timeout_handler, &pingtimer, &(struct timeval){pingtimeout, rand() % 100000}); - timeout_add(&periodictimer, periodic_handler, &periodictimer, &(struct timeval){0, 0}); + timeout_add(&pingtimer, timeout_handler, &pingtimer, &(struct timeval) { + pingtimeout, rand() % 100000 + }); + timeout_add(&periodictimer, periodic_handler, &periodictimer, &(struct timeval) { + 0, 0 + }); #ifndef HAVE_MINGW signal_t sighup = {0}; diff --git a/src/net.h b/src/net.h index 69ca488..8a74d85 100644 --- a/src/net.h +++ b/src/net.h @@ -1,3 +1,6 @@ +#ifndef TINC_NET_H +#define TINC_NET_H + /* net.h -- header for net.c Copyright (C) 1998-2005 Ivo Timmermans @@ -18,9 +21,6 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#ifndef __TINC_NET_H__ -#define __TINC_NET_H__ - #include "ipv6.h" #include "cipher.h" #include "digest.h" @@ -56,7 +56,7 @@ typedef struct node_id_t { uint8_t x[6]; } node_id_t; -typedef short length_t; +typedef uint16_t length_t; typedef uint32_t seqno_t; #define AF_UNKNOWN 255 @@ -74,9 +74,6 @@ typedef union sockaddr_t { struct sockaddr_in in; struct sockaddr_in6 in6; struct sockaddr_unknown unknown; -#ifdef HAVE_STRUCT_SOCKADDR_STORAGE - struct sockaddr_storage storage; -#endif } sockaddr_t; #ifdef SA_LEN @@ -122,13 +119,9 @@ typedef struct listen_socket_t { #include "list.h" typedef struct outgoing_t { - char *name; + struct node_t *node; int timeout; - splay_tree_t *config_tree; - struct config_t *cfg; - struct addrinfo *ai; // addresses from config files - struct addrinfo *aip; - struct addrinfo *kai; // addresses known via other online nodes (use free_known_addresses()) + struct address_cache_t *address_cache; timeout_t ev; } outgoing_t; @@ -155,6 +148,7 @@ extern int keylifetime; extern int udp_rcvbuf; extern int udp_sndbuf; extern int max_connection_burst; +extern int fwmark; extern bool do_prune; extern char *myport; extern bool device_standby; @@ -185,44 +179,45 @@ extern char *scriptextension; #include "connection.h" #include "node.h" -extern void retry_outgoing(outgoing_t *); -extern void handle_incoming_vpn_data(void *, int); -extern void finish_connecting(struct connection_t *); -extern bool do_outgoing_connection(struct outgoing_t *); -extern void handle_new_meta_connection(void *, int); -extern void handle_new_unix_connection(void *, int); -extern int setup_listen_socket(const sockaddr_t *); -extern int setup_vpn_in_socket(const sockaddr_t *); +extern void retry_outgoing(outgoing_t *outgoing); +extern void handle_incoming_vpn_data(void *data, int flags); +extern void finish_connecting(struct connection_t *c); +extern bool do_outgoing_connection(struct outgoing_t *outgoing); +extern void handle_new_meta_connection(void *data, int flags); +extern void handle_new_unix_connection(void *data, int flags); +extern int setup_listen_socket(const sockaddr_t *sa); +extern int setup_vpn_in_socket(const sockaddr_t *sa); extern bool send_sptps_data(node_t *to, node_t *from, int type, const void *data, size_t len); extern bool receive_sptps_record(void *handle, uint8_t type, const void *data, uint16_t len); -extern void send_packet(struct node_t *, vpn_packet_t *); -extern void receive_tcppacket(struct connection_t *, const char *, int); -extern bool receive_tcppacket_sptps(struct connection_t *, const char *, int); -extern void broadcast_packet(const struct node_t *, vpn_packet_t *); +extern void send_packet(struct node_t *n, vpn_packet_t *packet); +extern void receive_tcppacket(struct connection_t *c, const char *buffer, size_t length); +extern bool receive_tcppacket_sptps(struct connection_t *c, const char *buffer, size_t length); +extern void broadcast_packet(const struct node_t *n, vpn_packet_t *packet); extern char *get_name(void); extern void device_enable(void); extern void device_disable(void); extern bool setup_myself_reloadable(void); extern bool setup_network(void); -extern void setup_outgoing_connection(struct outgoing_t *); +extern void setup_outgoing_connection(struct outgoing_t *outgoing, bool verbose); extern void try_outgoing_connections(void); extern void close_network_connections(void); extern int main_loop(void); -extern void terminate_connection(struct connection_t *, bool); -extern bool node_read_ecdsa_public_key(struct node_t *); -extern bool read_ecdsa_public_key(struct connection_t *); -extern bool read_rsa_public_key(struct connection_t *); -extern void handle_device_data(void *, int); -extern void handle_meta_connection_data(struct connection_t *); +extern void terminate_connection(struct connection_t *c, bool report); +extern bool node_read_ecdsa_public_key(struct node_t *n); +extern bool read_ecdsa_public_key(struct connection_t *c); +extern bool read_rsa_public_key(struct connection_t *c); +extern void handle_device_data(void *data, int flags); +extern void handle_meta_connection_data(struct connection_t *c); extern void regenerate_key(void); extern void purge(void); extern void retry(void); extern int reload_configuration(void); extern void load_all_nodes(void); -extern void try_tx(struct node_t *n, bool); +extern void try_tx(struct node_t *n, bool mtu); +extern void tarpit(int fd); #ifndef HAVE_MINGW #define closesocket(s) close(s) #endif -#endif /* __TINC_NET_H__ */ +#endif diff --git a/src/net_packet.c b/src/net_packet.c index 5d559bd..6b40f2a 100644 --- a/src/net_packet.c +++ b/src/net_packet.c @@ -23,6 +23,7 @@ #include "system.h" #ifdef HAVE_ZLIB +#define ZLIB_CONST #include #endif @@ -30,6 +31,7 @@ #include LZO1X_H #endif +#include "address_cache.h" #include "cipher.h" #include "conf.h" #include "connection.h" @@ -74,14 +76,17 @@ int udp_discovery_timeout = 30; #define MAX_SEQNO 1073741824 static void try_fix_mtu(node_t *n) { - if(n->mtuprobes < 0) + if(n->mtuprobes < 0) { return; + } if(n->mtuprobes == 20 || n->minmtu >= n->maxmtu) { - if(n->minmtu > n->maxmtu) + if(n->minmtu > n->maxmtu) { n->minmtu = n->maxmtu; - else + } else { n->maxmtu = n->minmtu; + } + n->mtu = n->minmtu; logger(DEBUG_TRAFFIC, LOG_INFO, "Fixing MTU of %s (%s) to %d after %d probes", n->name, n->hostname, n->mtu, n->mtuprobes); n->mtuprobes = -1; @@ -90,11 +95,14 @@ static void try_fix_mtu(node_t *n) { static void udp_probe_timeout_handler(void *data) { node_t *n = data; - if(!n->status.udp_confirmed) + + if(!n->status.udp_confirmed) { return; + } logger(DEBUG_TRAFFIC, LOG_INFO, "Too much time has elapsed since last UDP ping response from %s (%s), stopping UDP communication", n->name, n->hostname); n->status.udp_confirmed = false; + n->udp_ping_rtt = -1; n->maxrecentlen = 0; n->mtuprobes = 0; n->minmtu = 0; @@ -108,7 +116,7 @@ static void send_udp_probe_reply(node_t *n, vpn_packet_t *packet, length_t len) } /* Type 2 probe replies were introduced in protocol 17.3 */ - if ((n->options >> 24) >= 3) { + if((n->options >> 24) >= 3) { DATA(packet)[0] = 2; uint16_t len16 = htons(len); memcpy(DATA(packet) + 1, &len16, 2); @@ -133,29 +141,48 @@ static void send_udp_probe_reply(node_t *n, vpn_packet_t *packet, length_t len) static void udp_probe_h(node_t *n, vpn_packet_t *packet, length_t len) { if(!DATA(packet)[0]) { logger(DEBUG_TRAFFIC, LOG_INFO, "Got UDP probe request %d from %s (%s)", packet->len, n->name, n->hostname); - return send_udp_probe_reply(n, packet, len); + send_udp_probe_reply(n, packet, len); + return; } - if (DATA(packet)[0] == 2) { + if(DATA(packet)[0] == 2) { // It's a type 2 probe reply, use the length field inside the packet uint16_t len16; memcpy(&len16, DATA(packet) + 1, 2); len = ntohs(len16); } - logger(DEBUG_TRAFFIC, LOG_INFO, "Got type %d UDP probe reply %d from %s (%s)", DATA(packet)[0], len, n->name, n->hostname); + if(n->udp_ping_sent.tv_sec != 0) { // a probe in flight + gettimeofday(&now, NULL); + struct timeval rtt; + timersub(&now, &n->udp_ping_sent, &rtt); + n->udp_ping_rtt = rtt.tv_sec * 1000000 + rtt.tv_usec; + logger(DEBUG_TRAFFIC, LOG_INFO, "Got type %d UDP probe reply %d from %s (%s) rtt=%d.%03d", DATA(packet)[0], len, n->name, n->hostname, n->udp_ping_rtt / 1000, n->udp_ping_rtt % 1000); + } else { + logger(DEBUG_TRAFFIC, LOG_INFO, "Got type %d UDP probe reply %d from %s (%s)", DATA(packet)[0], len, n->name, n->hostname); + } /* It's a valid reply: now we know bidirectional communication is possible using the address and socket that the reply packet used. */ - n->status.udp_confirmed = true; + if(!n->status.udp_confirmed) { + n->status.udp_confirmed = true; - // Reset the UDP ping timer. - n->udp_ping_sent = now; + if(!n->address_cache) { + n->address_cache = open_address_cache(n); + } + + reset_address_cache(n->address_cache, &n->address); + } + + // Reset the UDP ping timer. (no probe in flight) + n->udp_ping_sent.tv_sec = 0; if(udp_discovery) { timeout_del(&n->udp_ping_timeout); - timeout_add(&n->udp_ping_timeout, &udp_probe_timeout_handler, n, &(struct timeval){udp_discovery_timeout, 0}); + timeout_add(&n->udp_ping_timeout, &udp_probe_timeout_handler, n, &(struct timeval) { + udp_discovery_timeout, 0 + }); } if(len > n->maxmtu) { @@ -189,27 +216,28 @@ static length_t compress_packet(uint8_t *dest, const uint8_t *source, length_t l lzo1x_1_compress(source, len, dest, &lzolen, lzo_wrkmem); return lzolen; #else - return -1; + return 0; #endif } else if(level < 10) { #ifdef HAVE_ZLIB unsigned long destlen = MAXSIZE; - if(compress2(dest, &destlen, source, len, level) == Z_OK) + + if(compress2(dest, &destlen, source, len, level) == Z_OK) { return destlen; - else + } else #endif - return -1; + return 0; } else { #ifdef HAVE_LZO lzo_uint lzolen = MAXSIZE; lzo1x_999_compress(source, len, dest, &lzolen, lzo_wrkmem); return lzolen; #else - return -1; + return 0; #endif } - return -1; + return 0; } static length_t uncompress_packet(uint8_t *dest, const uint8_t *source, length_t len, int level) { @@ -219,30 +247,48 @@ static length_t uncompress_packet(uint8_t *dest, const uint8_t *source, length_t } else if(level > 9) { #ifdef HAVE_LZO lzo_uint lzolen = MAXSIZE; - if(lzo1x_decompress_safe(source, len, dest, &lzolen, NULL) == LZO_E_OK) + + if(lzo1x_decompress_safe(source, len, dest, &lzolen, NULL) == LZO_E_OK) { return lzolen; - else + } else #endif - return -1; + return 0; } + #ifdef HAVE_ZLIB else { unsigned long destlen = MAXSIZE; - if(uncompress(dest, &destlen, source, len) == Z_OK) - return destlen; - else - return -1; + static z_stream stream; + + if(stream.next_in) { + inflateReset(&stream); + } else { + inflateInit(&stream); + } + + stream.next_in = source; + stream.avail_in = len; + stream.next_out = dest; + stream.avail_out = destlen; + stream.total_out = 0; + + if(inflate(&stream, Z_FINISH) == Z_STREAM_END) { + return stream.total_out; + } else { + return 0; + } } + #endif - return -1; + return 0; } /* VPN packet I/O */ static void receive_packet(node_t *n, vpn_packet_t *packet) { logger(DEBUG_TRAFFIC, LOG_DEBUG, "Received packet of %d bytes from %s (%s)", - packet->len, n->name, n->hostname); + packet->len, n->name, n->hostname); n->in_packets++; n->in_bytes += packet->len; @@ -251,14 +297,17 @@ static void receive_packet(node_t *n, vpn_packet_t *packet) { } static bool try_mac(node_t *n, const vpn_packet_t *inpkt) { - if(n->status.sptps) + if(n->status.sptps) { return sptps_verify_datagram(&n->sptps, DATA(inpkt), inpkt->len); + } #ifdef DISABLE_LEGACY return false; #else - if(!n->status.validkey_in || !digest_active(n->indigest) || inpkt->len < sizeof(seqno_t) + digest_length(n->indigest)) + + if(!n->status.validkey_in || !digest_active(n->indigest) || (size_t)inpkt->len < sizeof(seqno_t) + digest_length(n->indigest)) { return false; + } return digest_verify(n->indigest, inpkt->data, inpkt->len - digest_length(n->indigest), inpkt->data + inpkt->len - digest_length(n->indigest)); #endif @@ -280,8 +329,10 @@ static bool receive_udppacket(node_t *n, vpn_packet_t *inpkt) { } else { logger(DEBUG_TRAFFIC, LOG_DEBUG, "Got packet from %s (%s) but he hasn't got our key yet", n->name, n->hostname); } + return false; } + n->status.udppacket = true; bool result = sptps_receive_data(&n->sptps, DATA(inpkt), inpkt->len); n->status.udppacket = false; @@ -295,14 +346,17 @@ static bool receive_udppacket(node_t *n, vpn_packet_t *inpkt) { logger(DEBUG_PROTOCOL, LOG_ERR, "Failed to decode raw TCP packet from %s (%s), restarting SPTPS", n->name, n->hostname); send_req_key(n); } + return false; } + return true; } #ifdef DISABLE_LEGACY return false; #else + if(!n->status.validkey_in) { logger(DEBUG_TRAFFIC, LOG_DEBUG, "Got packet from %s (%s) but he hasn't got our key yet", n->name, n->hostname); return false; @@ -310,9 +364,9 @@ static bool receive_udppacket(node_t *n, vpn_packet_t *inpkt) { /* Check packet length */ - if(inpkt->len < sizeof(seqno_t) + digest_length(n->indigest)) { + if((size_t)inpkt->len < sizeof(seqno_t) + digest_length(n->indigest)) { logger(DEBUG_TRAFFIC, LOG_DEBUG, "Got too short packet from %s (%s)", - n->name, n->hostname); + n->name, n->hostname); return false; } @@ -324,11 +378,13 @@ static bool receive_udppacket(node_t *n, vpn_packet_t *inpkt) { if(digest_active(n->indigest)) { inpkt->len -= digest_length(n->indigest); + if(!digest_verify(n->indigest, SEQNO(inpkt), inpkt->len, SEQNO(inpkt) + inpkt->len)) { logger(DEBUG_TRAFFIC, LOG_DEBUG, "Got unauthenticated packet from %s (%s)", n->name, n->hostname); return false; } } + /* Decrypt the packet */ if(cipher_active(n->incipher)) { @@ -347,30 +403,32 @@ static bool receive_udppacket(node_t *n, vpn_packet_t *inpkt) { /* Check the sequence number */ seqno_t seqno; - memcpy(&seqno, SEQNO(inpkt), sizeof seqno); + memcpy(&seqno, SEQNO(inpkt), sizeof(seqno)); seqno = ntohl(seqno); - inpkt->len -= sizeof seqno; + inpkt->len -= sizeof(seqno); if(replaywin) { if(seqno != n->received_seqno + 1) { if(seqno >= n->received_seqno + replaywin * 8) { if(n->farfuture++ < replaywin >> 2) { logger(DEBUG_TRAFFIC, LOG_WARNING, "Packet from %s (%s) is %d seqs in the future, dropped (%u)", - n->name, n->hostname, seqno - n->received_seqno - 1, n->farfuture); + n->name, n->hostname, seqno - n->received_seqno - 1, n->farfuture); return false; } + logger(DEBUG_TRAFFIC, LOG_WARNING, "Lost %d packets from %s (%s)", - seqno - n->received_seqno - 1, n->name, n->hostname); + seqno - n->received_seqno - 1, n->name, n->hostname); memset(n->late, 0, replaywin); - } else if (seqno <= n->received_seqno) { + } else if(seqno <= n->received_seqno) { if((n->received_seqno >= replaywin * 8 && seqno <= n->received_seqno - replaywin * 8) || !(n->late[(seqno / 8) % replaywin] & (1 << seqno % 8))) { logger(DEBUG_TRAFFIC, LOG_WARNING, "Got late or replayed packet from %s (%s), seqno %d, last received %d", - n->name, n->hostname, seqno, n->received_seqno); + n->name, n->hostname, seqno, n->received_seqno); return false; } } else { - for(int i = n->received_seqno + 1; i < seqno; i++) + for(seqno_t i = n->received_seqno + 1; i < seqno; i++) { n->late[(i / 8) % replaywin] |= 1 << i % 8; + } } } @@ -378,13 +436,15 @@ static bool receive_udppacket(node_t *n, vpn_packet_t *inpkt) { n->late[(seqno / 8) % replaywin] &= ~(1 << seqno % 8); } - if(seqno > n->received_seqno) + if(seqno > n->received_seqno) { n->received_seqno = seqno; + } n->received++; - if(n->received_seqno > MAX_SEQNO) + if(n->received_seqno > MAX_SEQNO) { regenerate_key(); + } /* Decompress the packet */ @@ -393,62 +453,77 @@ static bool receive_udppacket(node_t *n, vpn_packet_t *inpkt) { if(n->incompression) { vpn_packet_t *outpkt = pkt[nextpkt++]; - if((outpkt->len = uncompress_packet(DATA(outpkt), DATA(inpkt), inpkt->len, n->incompression)) < 0) { + if(!(outpkt->len = uncompress_packet(DATA(outpkt), DATA(inpkt), inpkt->len, n->incompression))) { logger(DEBUG_TRAFFIC, LOG_ERR, "Error while uncompressing packet from %s (%s)", - n->name, n->hostname); + n->name, n->hostname); return false; } inpkt = outpkt; - origlen -= MTU/64 + 20; + if(origlen > MTU / 64 + 20) { + origlen -= MTU / 64 + 20; + } else { + origlen = 0; + } } - if(inpkt->len > n->maxrecentlen) + if(inpkt->len > n->maxrecentlen) { n->maxrecentlen = inpkt->len; + } inpkt->priority = 0; - if(!DATA(inpkt)[12] && !DATA(inpkt)[13]) + if(!DATA(inpkt)[12] && !DATA(inpkt)[13]) { udp_probe_h(n, inpkt, origlen); - else + } else { receive_packet(n, inpkt); + } + return true; #endif } -void receive_tcppacket(connection_t *c, const char *buffer, int len) { +void receive_tcppacket(connection_t *c, const char *buffer, size_t len) { vpn_packet_t outpkt; outpkt.offset = DEFAULT_PACKET_OFFSET; - if(len > sizeof outpkt.data - outpkt.offset) + if(len > sizeof(outpkt.data) - outpkt.offset) { return; + } outpkt.len = len; - if(c->options & OPTION_TCPONLY) + + if(c->options & OPTION_TCPONLY) { outpkt.priority = 0; - else + } else { outpkt.priority = -1; + } + memcpy(DATA(&outpkt), buffer, len); receive_packet(c->node, &outpkt); } -bool receive_tcppacket_sptps(connection_t *c, const char *data, int len) { - if (len < sizeof(node_id_t) + sizeof(node_id_t)) { +bool receive_tcppacket_sptps(connection_t *c, const char *data, size_t len) { + if(len < sizeof(node_id_t) + sizeof(node_id_t)) { logger(DEBUG_PROTOCOL, LOG_ERR, "Got too short TCP SPTPS packet from %s (%s)", c->name, c->hostname); return false; } node_t *to = lookup_node_id((node_id_t *)data); - data += sizeof(node_id_t); len -= sizeof(node_id_t); + data += sizeof(node_id_t); + len -= sizeof(node_id_t); + if(!to) { logger(DEBUG_PROTOCOL, LOG_ERR, "Got TCP SPTPS packet from %s (%s) with unknown destination ID", c->name, c->hostname); return true; } node_t *from = lookup_node_id((node_id_t *)data); - data += sizeof(node_id_t); len -= sizeof(node_id_t); + data += sizeof(node_id_t); + len -= sizeof(node_id_t); + if(!from) { logger(DEBUG_PROTOCOL, LOG_ERR, "Got TCP SPTPS packet from %s (%s) with unknown source ID", c->name, c->hostname); return true; @@ -464,8 +539,9 @@ bool receive_tcppacket_sptps(connection_t *c, const char *data, int len) { /* Help the sender reach us over UDP. Note that we only do this if we're the destination or the static relay; otherwise every hop would initiate its own UDP info message, resulting in elevated chatter. */ - if(to->via == myself) + if(to->via == myself) { send_udp_info(myself, from); + } /* If we're not the final recipient, relay the packet. */ @@ -485,6 +561,7 @@ bool receive_tcppacket_sptps(connection_t *c, const char *data, int len) { logger(DEBUG_PROTOCOL, LOG_ERR, "Failed to decode raw TCP packet from %s (%s), restarting SPTPS", from->name, from->hostname); send_req_key(from); } + return true; } @@ -493,8 +570,9 @@ bool receive_tcppacket_sptps(connection_t *c, const char *data, int len) { } static void send_sptps_packet(node_t *n, vpn_packet_t *origpkt) { - if(!n->status.validkey && !n->connection) + if(!n->status.validkey && !n->connection) { return; + } uint8_t type = 0; int offset = 0; @@ -504,20 +582,23 @@ static void send_sptps_packet(node_t *n, vpn_packet_t *origpkt) { return; } - if(routing_mode == RMODE_ROUTER) + if(routing_mode == RMODE_ROUTER) { offset = 14; - else + } else { type = PKT_MAC; + } - if(origpkt->len < offset) + if(origpkt->len < offset) { return; + } vpn_packet_t outpkt; if(n->outcompression) { outpkt.offset = 0; - int len = compress_packet(DATA(&outpkt) + offset, DATA(origpkt) + offset, origpkt->len - offset, n->outcompression); - if(len < 0) { + length_t len = compress_packet(DATA(&outpkt) + offset, DATA(origpkt) + offset, origpkt->len - offset, n->outcompression); + + if(!len) { logger(DEBUG_TRAFFIC, LOG_ERR, "Error while compressing packet to %s (%s)", n->name, n->hostname); } else if(len < origpkt->len - offset) { outpkt.len = len + offset; @@ -530,10 +611,12 @@ static void send_sptps_packet(node_t *n, vpn_packet_t *origpkt) { don't bother with SPTPS and just use a "plaintext" PACKET message. We don't really care about end-to-end security since we're not sending the message through any intermediate nodes. */ - if(n->connection && origpkt->len > n->minmtu) + if(n->connection && origpkt->len > n->minmtu) { send_tcppacket(n->connection, origpkt); - else + } else { sptps_send_record(&n->sptps, type, DATA(origpkt) + offset, origpkt->len - offset); + } + return; } @@ -555,14 +638,16 @@ static void choose_udp_address(const node_t *n, const sockaddr_t **sa, int *sock *sock = n->sock; /* If the UDP address is confirmed, use it. */ - if(n->status.udp_confirmed) + if(n->status.udp_confirmed) { return; + } /* Send every third packet to n->address; that could be set to the node's reflexive UDP address discovered during key exchange. */ static int x = 0; + if(++x >= 3) { x = 0; return; @@ -606,7 +691,7 @@ static void choose_local_address(const node_t *n, const sockaddr_t **sa, int *so } } - if (candidate && candidate->local_address.sa.sa_family) { + if(candidate && candidate->local_address.sa.sa_family) { *sa = &candidate->local_address; *sock = rand() % listen_sockets; adapt_socket(*sa, sock); @@ -631,8 +716,10 @@ static void send_udppacket(node_t *n, vpn_packet_t *origpkt) { return; } - if(n->status.sptps) - return send_sptps_packet(n, origpkt); + if(n->status.sptps) { + send_sptps_packet(n, origpkt); + return; + } #ifdef DISABLE_LEGACY return; @@ -641,21 +728,22 @@ static void send_udppacket(node_t *n, vpn_packet_t *origpkt) { if(!n->status.validkey) { logger(DEBUG_TRAFFIC, LOG_INFO, - "No valid key known yet for %s (%s), forwarding via TCP", - n->name, n->hostname); + "No valid key known yet for %s (%s), forwarding via TCP", + n->name, n->hostname); send_tcppacket(n->nexthop->connection, origpkt); return; } if(n->options & OPTION_PMTU_DISCOVERY && inpkt->len > n->minmtu && (DATA(inpkt)[12] | DATA(inpkt)[13])) { logger(DEBUG_TRAFFIC, LOG_INFO, - "Packet for %s (%s) larger than minimum MTU, forwarding via %s", - n->name, n->hostname, n != n->nexthop ? n->nexthop->name : "TCP"); + "Packet for %s (%s) larger than minimum MTU, forwarding via %s", + n->name, n->hostname, n != n->nexthop ? n->nexthop->name : "TCP"); - if(n != n->nexthop) + if(n != n->nexthop) { send_packet(n->nexthop, origpkt); - else + } else { send_tcppacket(n->nexthop->connection, origpkt); + } return; } @@ -665,9 +753,9 @@ static void send_udppacket(node_t *n, vpn_packet_t *origpkt) { if(n->outcompression) { outpkt = pkt[nextpkt++]; - if((outpkt->len = compress_packet(DATA(outpkt), DATA(inpkt), inpkt->len, n->outcompression)) < 0) { + if(!(outpkt->len = compress_packet(DATA(outpkt), DATA(inpkt), inpkt->len, n->outcompression))) { logger(DEBUG_TRAFFIC, LOG_ERR, "Error while compressing packet to %s (%s)", - n->name, n->hostname); + n->name, n->hostname); return; } @@ -677,8 +765,8 @@ static void send_udppacket(node_t *n, vpn_packet_t *origpkt) { /* Add sequence number */ seqno_t seqno = htonl(++(n->sent_seqno)); - memcpy(SEQNO(inpkt), &seqno, sizeof seqno); - inpkt->len += sizeof seqno; + memcpy(SEQNO(inpkt), &seqno, sizeof(seqno)); + inpkt->len += sizeof(seqno); /* Encrypt the packet */ @@ -711,28 +799,41 @@ static void send_udppacket(node_t *n, vpn_packet_t *origpkt) { const sockaddr_t *sa = NULL; int sock; - if(n->status.send_locally) + if(n->status.send_locally) { choose_local_address(n, &sa, &sock); - if(!sa) + } + + if(!sa) { choose_udp_address(n, &sa, &sock); + } if(priorityinheritance && origpriority != listen_socket[sock].priority) { listen_socket[sock].priority = origpriority; + switch(sa->sa.sa_family) { -#if defined(IPPROTO_IP) && defined(IP_TOS) +#if defined(IP_TOS) + case AF_INET: logger(DEBUG_TRAFFIC, LOG_DEBUG, "Setting IPv4 outgoing packet priority to %d", origpriority); - if(setsockopt(listen_socket[sock].udp.fd, IPPROTO_IP, IP_TOS, (void *)&origpriority, sizeof origpriority)) /* SO_PRIORITY doesn't seem to work */ + + if(setsockopt(listen_socket[sock].udp.fd, IPPROTO_IP, IP_TOS, (void *)&origpriority, sizeof(origpriority))) { /* SO_PRIORITY doesn't seem to work */ logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "setsockopt", sockstrerror(sockerrno)); + } + break; #endif -#if defined(IPPROTO_IPV6) & defined(IPV6_TCLASS) +#if defined(IPV6_TCLASS) + case AF_INET6: logger(DEBUG_TRAFFIC, LOG_DEBUG, "Setting IPv6 outgoing packet priority to %d", origpriority); - if(setsockopt(listen_socket[sock].udp.fd, IPPROTO_IPV6, IPV6_TCLASS, (void *)&origpriority, sizeof origpriority)) /* SO_PRIORITY doesn't seem to work */ + + if(setsockopt(listen_socket[sock].udp.fd, IPPROTO_IPV6, IPV6_TCLASS, (void *)&origpriority, sizeof(origpriority))) { /* SO_PRIORITY doesn't seem to work */ logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "setsockopt", sockstrerror(sockerrno)); + } + break; #endif + default: break; } @@ -740,13 +841,18 @@ static void send_udppacket(node_t *n, vpn_packet_t *origpkt) { if(sendto(listen_socket[sock].udp.fd, (void *)SEQNO(inpkt), inpkt->len, 0, &sa->sa, SALEN(sa->sa)) < 0 && !sockwouldblock(sockerrno)) { if(sockmsgsize(sockerrno)) { - if(n->maxmtu >= origlen) + if(n->maxmtu >= origlen) { n->maxmtu = origlen - 1; - if(n->mtu >= origlen) + } + + if(n->mtu >= origlen) { n->mtu = origlen - 1; + } + try_fix_mtu(n); - } else + } else { logger(DEBUG_TRAFFIC, LOG_WARNING, "Error sending packet to %s (%s): %s", n->name, n->hostname, sockstrerror(sockerrno)); + } } end: @@ -764,16 +870,20 @@ bool send_sptps_data(node_t *to, node_t *from, int type, const void *data, size_ if(type == SPTPS_HANDSHAKE || tcponly || (!direct && !relay_supported) || (type != PKT_PROBE && (len - SPTPS_DATAGRAM_OVERHEAD) > relay->minmtu)) { if(type != SPTPS_HANDSHAKE && (to->nexthop->connection->options >> 24) >= 7) { - char buf[len + sizeof to->id + sizeof from->id]; char* buf_ptr = buf; - memcpy(buf_ptr, &to->id, sizeof to->id); buf_ptr += sizeof to->id; - memcpy(buf_ptr, &from->id, sizeof from->id); buf_ptr += sizeof from->id; + char buf[len + sizeof(to->id) + sizeof(from->id)]; + char *buf_ptr = buf; + memcpy(buf_ptr, &to->id, sizeof(to->id)); + buf_ptr += sizeof(to->id); + memcpy(buf_ptr, &from->id, sizeof(from->id)); + buf_ptr += sizeof(from->id); memcpy(buf_ptr, data, len); logger(DEBUG_TRAFFIC, LOG_INFO, "Sending packet from %s (%s) to %s (%s) via %s (%s) (TCP)", from->name, from->hostname, to->name, to->hostname, to->nexthop->name, to->nexthop->hostname); - return send_sptps_tcppacket(to->nexthop->connection, buf, sizeof buf); + return send_sptps_tcppacket(to->nexthop->connection, buf, sizeof(buf)); } char buf[len * 4 / 3 + 5]; b64encode(data, buf, len); + /* If this is a handshake packet, use ANS_KEY instead of REQ_KEY, for two reasons: - We don't want intermediate nodes to switch to UDP to relay these packets; - ANS_KEY allows us to learn the reflexive UDP address. */ @@ -786,37 +896,60 @@ bool send_sptps_data(node_t *to, node_t *from, int type, const void *data, size_ } size_t overhead = 0; - if(relay_supported) overhead += sizeof to->id + sizeof from->id; - char buf[len + overhead]; char* buf_ptr = buf; + + if(relay_supported) { + overhead += sizeof(to->id) + sizeof(from->id); + } + + char buf[len + overhead]; + char *buf_ptr = buf; + if(relay_supported) { if(direct) { /* Inform the recipient that this packet was sent directly. */ - node_id_t nullid = {}; - memcpy(buf_ptr, &nullid, sizeof nullid); buf_ptr += sizeof nullid; + node_id_t nullid = {0}; + memcpy(buf_ptr, &nullid, sizeof(nullid)); + buf_ptr += sizeof(nullid); } else { - memcpy(buf_ptr, &to->id, sizeof to->id); buf_ptr += sizeof to->id; + memcpy(buf_ptr, &to->id, sizeof(to->id)); + buf_ptr += sizeof(to->id); } - memcpy(buf_ptr, &from->id, sizeof from->id); buf_ptr += sizeof from->id; + + memcpy(buf_ptr, &from->id, sizeof(from->id)); + buf_ptr += sizeof(from->id); } + /* TODO: if this copy turns out to be a performance concern, change sptps_send_record() to add some "pre-padding" to the buffer and use that instead */ - memcpy(buf_ptr, data, len); buf_ptr += len; + memcpy(buf_ptr, data, len); + buf_ptr += len; const sockaddr_t *sa = NULL; int sock; - if(relay->status.send_locally) + + if(relay->status.send_locally) { choose_local_address(relay, &sa, &sock); - if(!sa) + } + + if(!sa) { choose_udp_address(relay, &sa, &sock); + } + logger(DEBUG_TRAFFIC, LOG_INFO, "Sending packet from %s (%s) to %s (%s) via %s (%s) (UDP)", from->name, from->hostname, to->name, to->hostname, relay->name, relay->hostname); + if(sendto(listen_socket[sock].udp.fd, buf, buf_ptr - buf, 0, &sa->sa, SALEN(sa->sa)) < 0 && !sockwouldblock(sockerrno)) { if(sockmsgsize(sockerrno)) { // Compensate for SPTPS overhead len -= SPTPS_DATAGRAM_OVERHEAD; - if(relay->maxmtu >= len) + + if(relay->maxmtu >= len) { relay->maxmtu = len - 1; - if(relay->mtu >= len) + } + + if(relay->mtu >= len) { relay->mtu = len - 1; + } + try_fix_mtu(relay); } else { logger(DEBUG_TRAFFIC, LOG_WARNING, "Error sending UDP SPTPS packet to %s (%s): %s", relay->name, relay->hostname, sockstrerror(sockerrno)); @@ -834,8 +967,9 @@ bool receive_sptps_record(void *handle, uint8_t type, const void *data, uint16_t if(!from->status.validkey) { from->status.validkey = true; from->status.waitingforkey = false; - logger(DEBUG_META, LOG_INFO, "SPTPS key exchange with %s (%s) succesful", from->name, from->hostname); + logger(DEBUG_META, LOG_INFO, "SPTPS key exchange with %s (%s) successful", from->name, from->hostname); } + return true; } @@ -853,10 +987,14 @@ bool receive_sptps_record(void *handle, uint8_t type, const void *data, uint16_t logger(DEBUG_ALWAYS, LOG_ERR, "Got SPTPS PROBE packet from %s (%s) via TCP", from->name, from->hostname); return false; } + inpkt.len = len; memcpy(DATA(&inpkt), data, len); - if(inpkt.len > from->maxrecentlen) + + if(inpkt.len > from->maxrecentlen) { from->maxrecentlen = inpkt.len; + } + udp_probe_h(from, &inpkt, len); return true; } @@ -875,15 +1013,19 @@ bool receive_sptps_record(void *handle, uint8_t type, const void *data, uint16_t } int offset = (type & PKT_MAC) ? 0 : 14; + if(type & PKT_COMPRESSED) { length_t ulen = uncompress_packet(DATA(&inpkt) + offset, (const uint8_t *)data, len, from->incompression); - if(ulen < 0) { + + if(!ulen) { return false; } else { inpkt.len = ulen + offset; } - if(inpkt.len > MAXSIZE) + + if(inpkt.len > MAXSIZE) { abort(); + } } else { memcpy(DATA(&inpkt) + offset, data, len); inpkt.len = len + offset; @@ -892,24 +1034,27 @@ bool receive_sptps_record(void *handle, uint8_t type, const void *data, uint16_t /* Generate the Ethernet packet type if necessary */ if(offset) { switch(DATA(&inpkt)[14] >> 4) { - case 4: - DATA(&inpkt)[12] = 0x08; - DATA(&inpkt)[13] = 0x00; - break; - case 6: - DATA(&inpkt)[12] = 0x86; - DATA(&inpkt)[13] = 0xDD; - break; - default: - logger(DEBUG_TRAFFIC, LOG_ERR, - "Unknown IP version %d while reading packet from %s (%s)", - DATA(&inpkt)[14] >> 4, from->name, from->hostname); - return false; + case 4: + DATA(&inpkt)[12] = 0x08; + DATA(&inpkt)[13] = 0x00; + break; + + case 6: + DATA(&inpkt)[12] = 0x86; + DATA(&inpkt)[13] = 0xDD; + break; + + default: + logger(DEBUG_TRAFFIC, LOG_ERR, + "Unknown IP version %d while reading packet from %s (%s)", + DATA(&inpkt)[14] >> 4, from->name, from->hostname); + return false; } } - if(from->status.udppacket && inpkt.len > from->maxrecentlen) + if(from->status.udppacket && inpkt.len > from->maxrecentlen) { from->maxrecentlen = inpkt.len; + } receive_packet(from, &inpkt); return true; @@ -918,14 +1063,15 @@ bool receive_sptps_record(void *handle, uint8_t type, const void *data, uint16_t // This function tries to get SPTPS keys, if they aren't already known. // This function makes no guarantees - it is up to the caller to check the node's state to figure out if the keys are available. static void try_sptps(node_t *n) { - if(n->status.validkey) + if(n->status.validkey) { return; + } logger(DEBUG_TRAFFIC, LOG_INFO, "No valid key known yet for %s (%s)", n->name, n->hostname); - if(!n->status.waitingforkey) + if(!n->status.waitingforkey) { send_req_key(n); - else if(n->last_req_key + 10 < now.tv_sec) { + } else if(n->last_req_key + 10 < now.tv_sec) { logger(DEBUG_ALWAYS, LOG_DEBUG, "No key from %s after 10 seconds, restarting SPTPS", n->name); sptps_stop(&n->sptps); n->status.waitingforkey = false; @@ -951,9 +1097,10 @@ static void send_udp_probe_packet(node_t *n, int len) { // This function tries to establish a UDP tunnel to a node so that packets can be sent. // If a tunnel is already established, it makes sure it stays up. // This function makes no guarantees - it is up to the caller to check the node's state to figure out if UDP is usable. -static void try_udp(node_t* n) { - if(!udp_discovery) +static void try_udp(node_t *n) { + if(!udp_discovery) { return; + } /* Send gratuitous probe replies to 1.1 nodes. */ @@ -963,6 +1110,7 @@ static void try_udp(node_t* n) { if(ping_tx_elapsed.tv_sec >= udp_discovery_keepalive_interval - 1) { n->udp_reply_sent = now; + if(n->maxrecentlen) { vpn_packet_t pkt; pkt.len = n->maxrecentlen; @@ -983,8 +1131,9 @@ static void try_udp(node_t* n) { int interval = n->status.udp_confirmed ? udp_discovery_keepalive_interval : udp_discovery_interval; if(ping_tx_elapsed.tv_sec >= interval) { + gettimeofday(&now, NULL); + n->udp_ping_sent = now; // a probe in flight send_udp_probe_packet(n, MIN_PROBE_SIZE); - n->udp_ping_sent = now; if(localdiscovery && !n->status.udp_confirmed && n->prevedge) { n->status.send_locally = true; @@ -1002,10 +1151,13 @@ static length_t choose_initial_maxmtu(node_t *n) { const sockaddr_t *sa = NULL; int sockindex; choose_udp_address(n, &sa, &sockindex); - if(!sa) + + if(!sa) { return MTU; + } sock = socket(sa->sa.sa_family, SOCK_DGRAM, IPPROTO_UDP); + if(sock < 0) { logger(DEBUG_TRAFFIC, LOG_ERR, "Creating MTU assessment socket for %s (%s) failed: %s", n->name, n->hostname, sockstrerror(sockerrno)); return MTU; @@ -1018,7 +1170,8 @@ static length_t choose_initial_maxmtu(node_t *n) { } int ip_mtu; - socklen_t ip_mtu_len = sizeof ip_mtu; + socklen_t ip_mtu_len = sizeof(ip_mtu); + if(getsockopt(sock, IPPROTO_IP, IP_MTU, &ip_mtu, &ip_mtu_len)) { logger(DEBUG_TRAFFIC, LOG_ERR, "getsockopt(IP_MTU) on %s (%s) failed: %s", n->name, n->hostname, sockstrerror(sockerrno)); close(sock); @@ -1032,10 +1185,14 @@ static length_t choose_initial_maxmtu(node_t *n) { length_t mtu = ip_mtu; mtu -= (sa->sa.sa_family == AF_INET6) ? sizeof(struct ip6_hdr) : sizeof(struct ip); mtu -= 8; /* UDP */ + if(n->status.sptps) { mtu -= SPTPS_DATAGRAM_OVERHEAD; - if((n->options >> 24) >= 4) + + if((n->options >> 24) >= 4) { mtu -= sizeof(node_id_t) + sizeof(node_id_t); + } + #ifndef DISABLE_LEGACY } else { mtu -= digest_length(n->outdigest); @@ -1059,12 +1216,14 @@ static length_t choose_initial_maxmtu(node_t *n) { #endif } - if (mtu < 512) { + if(mtu < 512) { logger(DEBUG_TRAFFIC, LOG_ERR, "getsockopt(IP_MTU) on %s (%s) returned absurdly small value: %d", n->name, n->hostname, ip_mtu); return MTU; } - if (mtu > MTU) + + if(mtu > MTU) { return MTU; + } logger(DEBUG_TRAFFIC, LOG_INFO, "Using system-provided maximum tinc MTU for %s (%s): %hd", n->name, n->hostname, mtu); return mtu; @@ -1083,8 +1242,9 @@ static length_t choose_initial_maxmtu(node_t *n) { */ static void try_mtu(node_t *n) { - if(!(n->options & OPTION_PMTU_DISCOVERY)) + if(!(n->options & OPTION_PMTU_DISCOVERY)) { return; + } if(udp_discovery && !n->status.udp_confirmed) { n->maxrecentlen = 0; @@ -1102,16 +1262,20 @@ static void try_mtu(node_t *n) { struct timeval elapsed; timersub(&now, &n->mtu_ping_sent, &elapsed); + if(n->mtuprobes >= 0) { - if(n->mtuprobes != 0 && elapsed.tv_sec == 0 && elapsed.tv_usec < 333333) + if(n->mtuprobes != 0 && elapsed.tv_sec == 0 && elapsed.tv_usec < 333333) { return; + } } else { if(n->mtuprobes < -1) { - if(elapsed.tv_sec < 1) + if(elapsed.tv_sec < 1) { return; + } } else { - if(elapsed.tv_sec < pinginterval) + if(elapsed.tv_sec < pinginterval) { return; + } } } @@ -1130,16 +1294,20 @@ static void try_mtu(node_t *n) { /* After the initial discovery, we only send one maxmtu and one maxmtu+1 probe to detect PMTU increases. */ send_udp_probe_packet(n, n->maxmtu); - if(n->mtuprobes == -1 && n->maxmtu + 1 < MTU) + + if(n->mtuprobes == -1 && n->maxmtu + 1 < MTU) { send_udp_probe_packet(n, n->maxmtu + 1); + } + n->mtuprobes--; } else { /* Before initial discovery begins, set maxmtu to the most likely value. If it's underestimated, we will correct it after initial discovery. */ - if(n->mtuprobes == 0) + if(n->mtuprobes == 0) { n->maxmtu = choose_initial_maxmtu(n); + } - for (;;) { + for(;;) { /* Decreasing the number of probes per cycle might make the algorithm react faster to lost packets, but it will typically increase convergence time in the no-loss case. */ const length_t probes_per_cycle = 8; @@ -1168,14 +1336,17 @@ static void try_mtu(node_t *n) { length_t maxmtu = n->maxmtu; send_udp_probe_packet(n, minmtu + offset); + /* If maxmtu changed, it means the probe was rejected by the system because it was too large. In that case, we recalculate with the new maxmtu and try again. */ - if(n->mtuprobes < 0 || maxmtu == n->maxmtu) + if(n->mtuprobes < 0 || maxmtu == n->maxmtu) { break; + } } - if(n->mtuprobes >= 0) + if(n->mtuprobes >= 0) { n->mtuprobes++; + } } } @@ -1196,8 +1367,9 @@ static void try_tx_sptps(node_t *n, bool mtu) { /* If n is a TCP-only neighbor, we'll only use "cleartext" PACKET messages anyway, so there's no need for SPTPS at all. */ - if(n->connection && ((myself->options | n->options) & OPTION_TCPONLY)) + if(n->connection && ((myself->options | n->options) & OPTION_TCPONLY)) { return; + } /* Otherwise, try to do SPTPS authentication with n if necessary. */ @@ -1210,29 +1382,36 @@ static void try_tx_sptps(node_t *n, bool mtu) { /* If we do have a static relay, try everything with that one instead, if it supports relaying. */ if(via != n) { - if((via->options >> 24) < 4) + if((via->options >> 24) < 4) { return; - return try_tx(via, mtu); + } + + try_tx(via, mtu); + return; } /* Otherwise, try to establish UDP connectivity. */ try_udp(n); - if(mtu) + + if(mtu) { try_mtu(n); + } /* If we don't have UDP connectivity (yet), we need to use a dynamic relay (nexthop) while we try to establish direct connectivity. */ - if(!n->status.udp_confirmed && n != n->nexthop && (n->nexthop->options >> 24) >= 4) + if(!n->status.udp_confirmed && n != n->nexthop && (n->nexthop->options >> 24) >= 4) { try_tx(n->nexthop, mtu); + } } static void try_tx_legacy(node_t *n, bool mtu) { /* Does he have our key? If not, send one. */ - if(!n->status.validkey_in) + if(!n->status.validkey_in) { send_ans_key(n); + } /* Check if we already have a key, or request one. */ @@ -1241,21 +1420,27 @@ static void try_tx_legacy(node_t *n, bool mtu) { send_req_key(n); n->last_req_key = now.tv_sec; } + return; } try_udp(n); - if(mtu) + + if(mtu) { try_mtu(n); + } } void try_tx(node_t *n, bool mtu) { - if(!n->status.reachable) + if(!n->status.reachable) { return; - if(n->status.sptps) + } + + if(n->status.sptps) { try_tx_sptps(n, mtu); - else + } else { try_tx_legacy(n, mtu); + } } void send_packet(node_t *n, vpn_packet_t *packet) { @@ -1263,11 +1448,12 @@ void send_packet(node_t *n, vpn_packet_t *packet) { if(n == myself) { if(overwrite_mac) { - memcpy(DATA(packet), mymac.x, ETH_ALEN); - // Use an arbitrary fake source address. - memcpy(DATA(packet) + ETH_ALEN, DATA(packet), ETH_ALEN); - DATA(packet)[ETH_ALEN * 2 - 1] ^= 0xFF; + memcpy(DATA(packet), mymac.x, ETH_ALEN); + // Use an arbitrary fake source address. + memcpy(DATA(packet) + ETH_ALEN, DATA(packet), ETH_ALEN); + DATA(packet)[ETH_ALEN * 2 - 1] ^= 0xFF; } + n->out_packets++; n->out_bytes += packet->len; devops.write(packet); @@ -1300,14 +1486,17 @@ void send_packet(node_t *n, vpn_packet_t *packet) { node_t *via = (packet->priority == -1 || n->via == myself) ? n->nexthop : n->via; - if(via != n) + if(via != n) { logger(DEBUG_TRAFFIC, LOG_INFO, "Sending packet to %s via %s (%s)", n->name, via->name, n->via->hostname); + } // Try to send via UDP, unless TCP is forced. if(packet->priority == -1 || ((myself->options | via->options) & OPTION_TCPONLY)) { - if(!send_tcppacket(via->connection, packet)) + if(!send_tcppacket(via->connection, packet)) { terminate_connection(via->connection, true); + } + return; } @@ -1317,41 +1506,48 @@ void send_packet(node_t *n, vpn_packet_t *packet) { void broadcast_packet(const node_t *from, vpn_packet_t *packet) { // Always give ourself a copy of the packet. - if(from != myself) + if(from != myself) { send_packet(myself, packet); + } // In TunnelServer mode, do not forward broadcast packets. // The MST might not be valid and create loops. - if(tunnelserver || broadcast_mode == BMODE_NONE) + if(tunnelserver || broadcast_mode == BMODE_NONE) { return; + } logger(DEBUG_TRAFFIC, LOG_INFO, "Broadcasting packet of %d bytes from %s (%s)", - packet->len, from->name, from->hostname); + packet->len, from->name, from->hostname); switch(broadcast_mode) { - // In MST mode, broadcast packets travel via the Minimum Spanning Tree. - // This guarantees all nodes receive the broadcast packet, and - // usually distributes the sending of broadcast packets over all nodes. - case BMODE_MST: - for list_each(connection_t, c, connection_list) - if(c->edge && c->status.mst && c != from->nexthop->connection) - send_packet(c->node, packet); - break; + // In MST mode, broadcast packets travel via the Minimum Spanning Tree. + // This guarantees all nodes receive the broadcast packet, and + // usually distributes the sending of broadcast packets over all nodes. + case BMODE_MST: + for list_each(connection_t, c, connection_list) + if(c->edge && c->status.mst && c != from->nexthop->connection) { + send_packet(c->node, packet); + } - // In direct mode, we send copies to each node we know of. - // However, this only reaches nodes that can be reached in a single hop. - // We don't have enough information to forward broadcast packets in this case. - case BMODE_DIRECT: - if(from != myself) - break; + break; - for splay_each(node_t, n, node_tree) - if(n->status.reachable && n != myself && ((n->via == myself && n->nexthop == n) || n->via == n)) - send_packet(n, packet); + // In direct mode, we send copies to each node we know of. + // However, this only reaches nodes that can be reached in a single hop. + // We don't have enough information to forward broadcast packets in this case. + case BMODE_DIRECT: + if(from != myself) { break; + } - default: - break; + for splay_each(node_t, n, node_tree) + if(n->status.reachable && n != myself && ((n->via == myself && n->nexthop == n) || n->via == n)) { + send_packet(n, packet); + } + + break; + + default: + break; } } @@ -1367,17 +1563,21 @@ static node_t *try_harder(const sockaddr_t *from, const vpn_packet_t *pkt) { static time_t last_hard_try = 0; for splay_each(node_t, n, node_tree) { - if(!n->status.reachable || n == myself) + if(!n->status.reachable || n == myself) { continue; + } - if(!n->status.validkey_in && !(n->status.sptps && n->sptps.instate)) + if(!n->status.validkey_in && !(n->status.sptps && n->sptps.instate)) { continue; + } bool soft = false; for splay_each(edge_t, e, n->edge_tree) { - if(!e->reverse) + if(!e->reverse) { continue; + } + if(!sockaddrcmp_noport(from, &e->reverse->address)) { soft = true; break; @@ -1385,27 +1585,31 @@ static node_t *try_harder(const sockaddr_t *from, const vpn_packet_t *pkt) { } if(!soft) { - if(last_hard_try == now.tv_sec) + if(last_hard_try == now.tv_sec) { continue; + } + hard = true; } - if(!try_mac(n, pkt)) + if(!try_mac(n, pkt)) { continue; + } match = n; break; } - if(hard) + if(hard) { last_hard_try = now.tv_sec; + } return match; } static void handle_incoming_vpn_packet(listen_socket_t *ls, vpn_packet_t *pkt, sockaddr_t *addr) { char *hostname; - node_id_t nullid = {}; + node_id_t nullid = {0}; node_t *from, *to; bool direct = false; @@ -1415,18 +1619,21 @@ static void handle_incoming_vpn_packet(listen_socket_t *ls, vpn_packet_t *pkt, s node_t *n = lookup_node_udp(addr); - if(n && !n->status.udp_confirmed) - n = NULL; // Don't believe it if we don't have confirmation yet. + if(n && !n->status.udp_confirmed) { + n = NULL; // Don't believe it if we don't have confirmation yet. + } if(!n) { // It might be from a 1.1 node, which might have a source ID in the packet. pkt->offset = 2 * sizeof(node_id_t); from = lookup_node_id(SRCID(pkt)); - if(from && !memcmp(DSTID(pkt), &nullid, sizeof nullid) && from->status.sptps) { - if(sptps_verify_datagram(&from->sptps, DATA(pkt), pkt->len - 2 * sizeof(node_id_t))) + + if(from && !memcmp(DSTID(pkt), &nullid, sizeof(nullid)) && from->status.sptps) { + if(sptps_verify_datagram(&from->sptps, DATA(pkt), pkt->len - 2 * sizeof(node_id_t))) { n = from; - else + } else { goto skip_harder; + } } } @@ -1436,12 +1643,14 @@ static void handle_incoming_vpn_packet(listen_socket_t *ls, vpn_packet_t *pkt, s } skip_harder: + if(!n) { if(debug_level >= DEBUG_PROTOCOL) { hostname = sockaddr2hostname(addr); logger(DEBUG_PROTOCOL, LOG_WARNING, "Received UDP packet from unknown source %s", hostname); free(hostname); } + return; } @@ -1449,12 +1658,13 @@ skip_harder: if(n->status.sptps) { bool relay_enabled = (n->options >> 24) >= 4; - if (relay_enabled) { + + if(relay_enabled) { pkt->offset = 2 * sizeof(node_id_t); pkt->len -= pkt->offset; } - if(!memcmp(DSTID(pkt), &nullid, sizeof nullid) || !relay_enabled) { + if(!memcmp(DSTID(pkt), &nullid, sizeof(nullid)) || !relay_enabled) { direct = true; from = n; to = myself; @@ -1462,6 +1672,7 @@ skip_harder: from = lookup_node_id(SRCID(pkt)); to = lookup_node_id(DSTID(pkt)); } + if(!from || !to) { logger(DEBUG_PROTOCOL, LOG_WARNING, "Received UDP packet from %s (%s) with unknown source and/or destination ID", n->name, n->hostname); return; @@ -1480,8 +1691,9 @@ skip_harder: Note that we only do this if we're the destination or the static relay; otherwise every hop would initiate its own UDP info message, resulting in elevated chatter. */ - if(n != from->via && to->via == myself) + if(n != from->via && to->via == myself) { send_udp_info(myself, from); + } /* If we're not the final recipient, relay the packet. */ @@ -1495,21 +1707,27 @@ skip_harder: from = n; } - if(!receive_udppacket(from, pkt)) + if(!receive_udppacket(from, pkt)) { return; + } n->sock = ls - listen_socket; - if(direct && sockaddrcmp(addr, &n->address)) + + if(direct && sockaddrcmp(addr, &n->address)) { update_node_udp(n, addr); + } /* If the packet went through a relay, help the sender find the appropriate MTU through the relay path. */ - if(!direct) + if(!direct) { send_mtu_info(myself, n, MTU); + } } void handle_incoming_vpn_data(void *data, int flags) { + (void)data; + (void)flags; listen_socket_t *ls = data; #ifdef HAVE_RECVMMSG @@ -1523,14 +1741,14 @@ void handle_incoming_vpn_data(void *data, int flags) { for(int i = 0; i < num; i++) { pkt[i].offset = 0; - iov[i] = (struct iovec){ + iov[i] = (struct iovec) { .iov_base = DATA(&pkt[i]), .iov_len = MAXSIZE, }; - msg[i].msg_hdr = (struct msghdr){ + msg[i].msg_hdr = (struct msghdr) { .msg_name = &addr[i].sa, - .msg_namelen = sizeof addr[i], + .msg_namelen = sizeof(addr)[i], .msg_iov = &iov[i], .msg_iovlen = 1, }; @@ -1539,28 +1757,36 @@ void handle_incoming_vpn_data(void *data, int flags) { num = recvmmsg(ls->udp.fd, msg, MAX_MSG, MSG_DONTWAIT, NULL); if(num < 0) { - if(!sockwouldblock(sockerrno)) + if(!sockwouldblock(sockerrno)) { logger(DEBUG_ALWAYS, LOG_ERR, "Receiving packet failed: %s", sockstrerror(sockerrno)); + } + return; } for(int i = 0; i < num; i++) { pkt[i].len = msg[i].msg_len; - if(pkt[i].len <= 0 || pkt[i].len > MAXSIZE) + + if(pkt[i].len <= 0 || pkt[i].len > MAXSIZE) { continue; + } + handle_incoming_vpn_packet(ls, &pkt[i], &addr[i]); } + #else vpn_packet_t pkt; sockaddr_t addr = {}; - socklen_t addrlen = sizeof addr; + socklen_t addrlen = sizeof(addr); pkt.offset = 0; int len = recvfrom(ls->udp.fd, (void *)DATA(&pkt), MAXSIZE, 0, &addr.sa, &addrlen); if(len <= 0 || len > MAXSIZE) { - if(!sockwouldblock(sockerrno)) + if(!sockwouldblock(sockerrno)) { logger(DEBUG_ALWAYS, LOG_ERR, "Receiving packet failed: %s", sockstrerror(sockerrno)); + } + return; } @@ -1571,6 +1797,8 @@ void handle_incoming_vpn_data(void *data, int flags) { } void handle_device_data(void *data, int flags) { + (void)data; + (void)flags; vpn_packet_t packet; packet.offset = DEFAULT_PACKET_OFFSET; packet.priority = 0; @@ -1584,6 +1812,7 @@ void handle_device_data(void *data, int flags) { } else { usleep(errors * 50000); errors++; + if(errors > 10) { logger(DEBUG_ALWAYS, LOG_ERR, "Too many errors from %s, exiting!", device); event_exit(); diff --git a/src/net_setup.c b/src/net_setup.c index e164214..ed69808 100644 --- a/src/net_setup.c +++ b/src/net_setup.c @@ -64,8 +64,9 @@ char *scriptinterpreter; char *scriptextension; bool node_read_ecdsa_public_key(node_t *n) { - if(ecdsa_active(n->ecdsa)) + if(ecdsa_active(n->ecdsa)) { return true; + } splay_tree_t *config_tree; FILE *fp; @@ -73,8 +74,10 @@ bool node_read_ecdsa_public_key(node_t *n) { char *p; init_configuration(&config_tree); - if(!read_host_config(config_tree, n->name)) + + if(!read_host_config(config_tree, n->name, true)) { goto exit; + } /* First, check for simple Ed25519PublicKey statement */ @@ -86,13 +89,15 @@ bool node_read_ecdsa_public_key(node_t *n) { /* Else, check for Ed25519PublicKeyFile statement and read it */ - if(!get_config_string(lookup_config(config_tree, "Ed25519PublicKeyFile"), &pubname)) + if(!get_config_string(lookup_config(config_tree, "Ed25519PublicKeyFile"), &pubname)) { xasprintf(&pubname, "%s" SLASH "hosts" SLASH "%s", confbase, n->name); + } fp = fopen(pubname, "r"); - if(!fp) + if(!fp) { goto exit; + } n->ecdsa = ecdsa_read_pem_public_key(fp); fclose(fp); @@ -104,8 +109,9 @@ exit: } bool read_ecdsa_public_key(connection_t *c) { - if(ecdsa_active(c->ecdsa)) + if(ecdsa_active(c->ecdsa)) { return true; + } FILE *fp; char *fname; @@ -113,8 +119,10 @@ bool read_ecdsa_public_key(connection_t *c) { if(!c->config_tree) { init_configuration(&c->config_tree); - if(!read_host_config(c->config_tree, c->name)) + + if(!read_host_config(c->config_tree, c->name, true)) { return false; + } } /* First, check for simple Ed25519PublicKey statement */ @@ -127,22 +135,24 @@ bool read_ecdsa_public_key(connection_t *c) { /* Else, check for Ed25519PublicKeyFile statement and read it */ - if(!get_config_string(lookup_config(c->config_tree, "Ed25519PublicKeyFile"), &fname)) + if(!get_config_string(lookup_config(c->config_tree, "Ed25519PublicKeyFile"), &fname)) { xasprintf(&fname, "%s" SLASH "hosts" SLASH "%s", confbase, c->name); + } fp = fopen(fname, "r"); if(!fp) { logger(DEBUG_ALWAYS, LOG_ERR, "Error reading Ed25519 public key file `%s': %s", - fname, strerror(errno)); + fname, strerror(errno)); free(fname); return false; } c->ecdsa = ecdsa_read_pem_public_key(fp); - if(!c->ecdsa && errno != ENOENT) + if(!c->ecdsa && errno != ENOENT) { logger(DEBUG_ALWAYS, LOG_ERR, "Parsing Ed25519 public key file `%s' failed.", fname); + } fclose(fp); free(fname); @@ -165,8 +175,9 @@ bool read_rsa_public_key(connection_t *c) { /* Else, check for PublicKeyFile statement and read it */ - if(!get_config_string(lookup_config(c->config_tree, "PublicKeyFile"), &fname)) + if(!get_config_string(lookup_config(c->config_tree, "PublicKeyFile"), &fname)) { xasprintf(&fname, "%s" SLASH "hosts" SLASH "%s", confbase, c->name); + } fp = fopen(fname, "r"); @@ -179,8 +190,10 @@ bool read_rsa_public_key(connection_t *c) { c->rsa = rsa_read_pem_public_key(fp); fclose(fp); - if(!c->rsa) + if(!c->rsa) { logger(DEBUG_ALWAYS, LOG_ERR, "Reading RSA public key file `%s' failed: %s", fname, strerror(errno)); + } + free(fname); return c->rsa; } @@ -192,15 +205,19 @@ static bool read_ecdsa_private_key(void) { /* Check for PrivateKeyFile statement and read it */ - if(!get_config_string(lookup_config(config_tree, "Ed25519PrivateKeyFile"), &fname)) + if(!get_config_string(lookup_config(config_tree, "Ed25519PrivateKeyFile"), &fname)) { xasprintf(&fname, "%s" SLASH "ed25519_key.priv", confbase); + } fp = fopen(fname, "r"); if(!fp) { logger(DEBUG_ALWAYS, LOG_ERR, "Error reading Ed25519 private key file `%s': %s", fname, strerror(errno)); - if(errno == ENOENT) - logger(DEBUG_ALWAYS, LOG_INFO, "Create an Ed25519 keypair with `tinc -n %s generate-ed25519-keys'.", netname ?: "."); + + if(errno == ENOENT) { + logger(DEBUG_ALWAYS, LOG_INFO, "Create an Ed25519 keypair with `tinc -n %s generate-ed25519-keys'.", netname ? netname : "."); + } + free(fname); return false; } @@ -214,15 +231,19 @@ static bool read_ecdsa_private_key(void) { return false; } - if(s.st_mode & ~0100700) + if(s.st_mode & ~0100700) { logger(DEBUG_ALWAYS, LOG_WARNING, "Warning: insecure file permissions for Ed25519 private key file `%s'!", fname); + } + #endif myself->connection->ecdsa = ecdsa_read_pem_private_key(fp); fclose(fp); - if(!myself->connection->ecdsa) + if(!myself->connection->ecdsa) { logger(DEBUG_ALWAYS, LOG_ERR, "Reading Ed25519 private key file `%s' failed", fname); + } + free(fname); return myself->connection->ecdsa; } @@ -236,15 +257,17 @@ static bool read_invitation_key(void) { invitation_key = NULL; } - snprintf(fname, sizeof fname, "%s" SLASH "invitations" SLASH "ed25519_key.priv", confbase); + snprintf(fname, sizeof(fname), "%s" SLASH "invitations" SLASH "ed25519_key.priv", confbase); fp = fopen(fname, "r"); if(fp) { invitation_key = ecdsa_read_pem_private_key(fp); fclose(fp); - if(!invitation_key) + + if(!invitation_key) { logger(DEBUG_ALWAYS, LOG_ERR, "Reading Ed25519 private key file `%s' failed", fname); + } } return invitation_key; @@ -264,6 +287,7 @@ static bool read_rsa_private_key(void) { free(d); return false; } + myself->connection->rsa = rsa_set_hex_private_key(n, "FFFF", d); free(n); free(d); @@ -272,16 +296,20 @@ static bool read_rsa_private_key(void) { /* Else, check for PrivateKeyFile statement and read it */ - if(!get_config_string(lookup_config(config_tree, "PrivateKeyFile"), &fname)) + if(!get_config_string(lookup_config(config_tree, "PrivateKeyFile"), &fname)) { xasprintf(&fname, "%s" SLASH "rsa_key.priv", confbase); + } fp = fopen(fname, "r"); if(!fp) { logger(DEBUG_ALWAYS, LOG_ERR, "Error reading RSA private key file `%s': %s", - fname, strerror(errno)); - if(errno == ENOENT) - logger(DEBUG_ALWAYS, LOG_INFO, "Create an RSA keypair with `tinc -n %s generate-rsa-keys'.", netname ?: "."); + fname, strerror(errno)); + + if(errno == ENOENT) { + logger(DEBUG_ALWAYS, LOG_INFO, "Create an RSA keypair with `tinc -n %s generate-rsa-keys'.", netname ? netname : "."); + } + free(fname); return false; } @@ -295,15 +323,19 @@ static bool read_rsa_private_key(void) { return false; } - if(s.st_mode & ~0100700) + if(s.st_mode & ~0100700) { logger(DEBUG_ALWAYS, LOG_WARNING, "Warning: insecure file permissions for RSA private key file `%s'!", fname); + } + #endif myself->connection->rsa = rsa_read_pem_private_key(fp); fclose(fp); - if(!myself->connection->rsa) + if(!myself->connection->rsa) { logger(DEBUG_ALWAYS, LOG_ERR, "Reading RSA private key file `%s' failed: %s", fname, strerror(errno)); + } + free(fname); return myself->connection->rsa; } @@ -313,14 +345,18 @@ static timeout_t keyexpire_timeout; static void keyexpire_handler(void *data) { regenerate_key(); - timeout_set(data, &(struct timeval){keylifetime, rand() % 100000}); + timeout_set(data, &(struct timeval) { + keylifetime, rand() % 100000 + }); } void regenerate_key(void) { logger(DEBUG_STATUS, LOG_INFO, "Expiring symmetric keys"); send_key_changed(); - for splay_each(node_t, n, node_tree) + + for splay_each(node_t, n, node_tree) { n->status.validkey_in = false; + } } void load_all_nodes(void) { @@ -328,23 +364,25 @@ void load_all_nodes(void) { struct dirent *ent; char dname[PATH_MAX]; - snprintf(dname, sizeof dname, "%s" SLASH "hosts", confbase); + snprintf(dname, sizeof(dname), "%s" SLASH "hosts", confbase); dir = opendir(dname); + if(!dir) { logger(DEBUG_ALWAYS, LOG_ERR, "Could not open %s: %s", dname, strerror(errno)); return; } while((ent = readdir(dir))) { - if(!check_id(ent->d_name)) + if(!check_id(ent->d_name)) { continue; + } node_t *n = lookup_node(ent->d_name); splay_tree_t *config_tree; init_configuration(&config_tree); read_config_options(config_tree, ent->d_name); - read_host_config(config_tree, ent->d_name); + read_host_config(config_tree, ent->d_name, true); if(!n) { n = new_node(); @@ -356,8 +394,9 @@ void load_all_nodes(void) { for(config_t *cfg = lookup_config(config_tree, "Subnet"); cfg; cfg = lookup_config_next(config_tree, cfg)) { subnet_t *s, *s2; - if(!get_config_subnet(cfg, &s)) + if(!get_config_subnet(cfg, &s)) { continue; + } if((s2 = lookup_subnet(n, s))) { s2->expires = -1; @@ -368,8 +407,9 @@ void load_all_nodes(void) { } } - if(lookup_config(config_tree, "Address")) + if(lookup_config(config_tree, "Address")) { n->status.has_address = true; + } exit_configuration(&config_tree); } @@ -383,8 +423,9 @@ char *get_name(void) { get_config_string(lookup_config(config_tree, "Name"), &name); - if(!name) + if(!name) { return NULL; + } returned_name = replace_name(name); free(name); @@ -406,13 +447,17 @@ bool setup_myself_reloadable(void) { free(scriptextension); - if(!get_config_string(lookup_config(config_tree, "ScriptsExtension"), &scriptextension)) + + if(!get_config_string(lookup_config(config_tree, "ScriptsExtension"), &scriptextension)) { scriptextension = xstrdup(""); + } get_config_string(lookup_config(config_tree, "Proxy"), &proxy); + if(proxy) { - if((space = strchr(proxy, ' '))) + if((space = strchr(proxy, ' '))) { *space++ = 0; + } if(!strcasecmp(proxy, "none")) { proxytype = PROXY_NONE; @@ -432,53 +477,70 @@ bool setup_myself_reloadable(void) { } switch(proxytype) { - case PROXY_NONE: - default: - break; + case PROXY_NONE: + default: + break; - case PROXY_EXEC: - if(!space || !*space) { - logger(DEBUG_ALWAYS, LOG_ERR, "Argument expected for proxy type exec!"); - return false; - } - proxyhost = xstrdup(space); - break; + case PROXY_EXEC: + if(!space || !*space) { + logger(DEBUG_ALWAYS, LOG_ERR, "Argument expected for proxy type exec!"); + return false; + } - case PROXY_SOCKS4: - case PROXY_SOCKS4A: - case PROXY_SOCKS5: - case PROXY_HTTP: - proxyhost = space; - if(space && (space = strchr(space, ' '))) - *space++ = 0, proxyport = space; - if(space && (space = strchr(space, ' '))) - *space++ = 0, proxyuser = space; - if(space && (space = strchr(space, ' '))) - *space++ = 0, proxypass = space; - if(!proxyhost || !*proxyhost || !proxyport || !*proxyport) { - logger(DEBUG_ALWAYS, LOG_ERR, "Host and port argument expected for proxy!"); - return false; - } - proxyhost = xstrdup(proxyhost); - proxyport = xstrdup(proxyport); - if(proxyuser && *proxyuser) - proxyuser = xstrdup(proxyuser); - if(proxypass && *proxypass) - proxypass = xstrdup(proxypass); - break; + proxyhost = xstrdup(space); + break; + + case PROXY_SOCKS4: + case PROXY_SOCKS4A: + case PROXY_SOCKS5: + case PROXY_HTTP: + proxyhost = space; + + if(space && (space = strchr(space, ' '))) { + *space++ = 0, proxyport = space; + } + + if(space && (space = strchr(space, ' '))) { + *space++ = 0, proxyuser = space; + } + + if(space && (space = strchr(space, ' '))) { + *space++ = 0, proxypass = space; + } + + if(!proxyhost || !*proxyhost || !proxyport || !*proxyport) { + logger(DEBUG_ALWAYS, LOG_ERR, "Host and port argument expected for proxy!"); + return false; + } + + proxyhost = xstrdup(proxyhost); + proxyport = xstrdup(proxyport); + + if(proxyuser && *proxyuser) { + proxyuser = xstrdup(proxyuser); + } + + if(proxypass && *proxypass) { + proxypass = xstrdup(proxypass); + } + + break; } free(proxy); } - if(get_config_bool(lookup_config(config_tree, "IndirectData"), &choice) && choice) + if(get_config_bool(lookup_config(config_tree, "IndirectData"), &choice) && choice) { myself->options |= OPTION_INDIRECT; + } - if(get_config_bool(lookup_config(config_tree, "TCPOnly"), &choice) && choice) + if(get_config_bool(lookup_config(config_tree, "TCPOnly"), &choice) && choice) { myself->options |= OPTION_TCPONLY; + } - if(myself->options & OPTION_TCPONLY) + if(myself->options & OPTION_TCPONLY) { myself->options |= OPTION_INDIRECT; + } get_config_bool(lookup_config(config_tree, "UDPDiscovery"), &udp_discovery); get_config_int(lookup_config(config_tree, "UDPDiscoveryKeepaliveInterval"), &udp_discovery_keepalive_interval); @@ -492,127 +554,148 @@ bool setup_myself_reloadable(void) { get_config_bool(lookup_config(config_tree, "LocalDiscovery"), &localdiscovery); if(get_config_string(lookup_config(config_tree, "Mode"), &rmode)) { - if(!strcasecmp(rmode, "router")) + if(!strcasecmp(rmode, "router")) { routing_mode = RMODE_ROUTER; - else if(!strcasecmp(rmode, "switch")) + } else if(!strcasecmp(rmode, "switch")) { routing_mode = RMODE_SWITCH; - else if(!strcasecmp(rmode, "hub")) + } else if(!strcasecmp(rmode, "hub")) { routing_mode = RMODE_HUB; - else { + } else { logger(DEBUG_ALWAYS, LOG_ERR, "Invalid routing mode!"); return false; } + free(rmode); } if(get_config_string(lookup_config(config_tree, "Forwarding"), &fmode)) { - if(!strcasecmp(fmode, "off")) + if(!strcasecmp(fmode, "off")) { forwarding_mode = FMODE_OFF; - else if(!strcasecmp(fmode, "internal")) + } else if(!strcasecmp(fmode, "internal")) { forwarding_mode = FMODE_INTERNAL; - else if(!strcasecmp(fmode, "kernel")) + } else if(!strcasecmp(fmode, "kernel")) { forwarding_mode = FMODE_KERNEL; - else { + } else { logger(DEBUG_ALWAYS, LOG_ERR, "Invalid forwarding mode!"); return false; } + free(fmode); } - choice = true; + choice = !(myself->options & OPTION_TCPONLY); get_config_bool(lookup_config(config_tree, "PMTUDiscovery"), &choice); - if(choice) + + if(choice) { myself->options |= OPTION_PMTU_DISCOVERY; + } choice = true; get_config_bool(lookup_config(config_tree, "ClampMSS"), &choice); - if(choice) + + if(choice) { myself->options |= OPTION_CLAMP_MSS; + } get_config_bool(lookup_config(config_tree, "PriorityInheritance"), &priorityinheritance); get_config_bool(lookup_config(config_tree, "DecrementTTL"), &decrement_ttl); + if(get_config_string(lookup_config(config_tree, "Broadcast"), &bmode)) { - if(!strcasecmp(bmode, "no")) + if(!strcasecmp(bmode, "no")) { broadcast_mode = BMODE_NONE; - else if(!strcasecmp(bmode, "yes") || !strcasecmp(bmode, "mst")) + } else if(!strcasecmp(bmode, "yes") || !strcasecmp(bmode, "mst")) { broadcast_mode = BMODE_MST; - else if(!strcasecmp(bmode, "direct")) + } else if(!strcasecmp(bmode, "direct")) { broadcast_mode = BMODE_DIRECT; - else { + } else { logger(DEBUG_ALWAYS, LOG_ERR, "Invalid broadcast mode!"); return false; } + free(bmode); } - const char* const DEFAULT_BROADCAST_SUBNETS[] = { "ff:ff:ff:ff:ff:ff", "255.255.255.255", "224.0.0.0/4", "ff00::/8" }; - for (size_t i = 0; i < sizeof(DEFAULT_BROADCAST_SUBNETS) / sizeof(*DEFAULT_BROADCAST_SUBNETS); i++) { + const char *const DEFAULT_BROADCAST_SUBNETS[] = { "ff:ff:ff:ff:ff:ff", "255.255.255.255", "224.0.0.0/4", "ff00::/8" }; + + for(size_t i = 0; i < sizeof(DEFAULT_BROADCAST_SUBNETS) / sizeof(*DEFAULT_BROADCAST_SUBNETS); i++) { subnet_t *s = new_subnet(); - if (!str2net(s, DEFAULT_BROADCAST_SUBNETS[i])) + + if(!str2net(s, DEFAULT_BROADCAST_SUBNETS[i])) { abort(); + } + subnet_add(NULL, s); } - for (config_t* cfg = lookup_config(config_tree, "BroadcastSubnet"); cfg; cfg = lookup_config_next(config_tree, cfg)) { + + for(config_t *cfg = lookup_config(config_tree, "BroadcastSubnet"); cfg; cfg = lookup_config_next(config_tree, cfg)) { subnet_t *s; - if (!get_config_subnet(cfg, &s)) + + if(!get_config_subnet(cfg, &s)) { continue; + } + subnet_add(NULL, s); } -#if !defined(IPPROTO_IP) || !defined(IP_TOS) - if(priorityinheritance) +#if !defined(IP_TOS) + + if(priorityinheritance) { logger(DEBUG_ALWAYS, LOG_WARNING, "%s not supported on this platform for IPv4 connections", "PriorityInheritance"); + } + #endif -#if !defined(IPPROTO_IPV6) || !defined(IPV6_TCLASS) - if(priorityinheritance) +#if !defined(IPV6_TCLASS) + + if(priorityinheritance) { logger(DEBUG_ALWAYS, LOG_WARNING, "%s not supported on this platform for IPv6 connections", "PriorityInheritance"); + } + #endif - if(!get_config_int(lookup_config(config_tree, "MACExpire"), &macexpire)) + if(!get_config_int(lookup_config(config_tree, "MACExpire"), &macexpire)) { macexpire = 600; + } if(get_config_int(lookup_config(config_tree, "MaxTimeout"), &maxtimeout)) { if(maxtimeout <= 0) { logger(DEBUG_ALWAYS, LOG_ERR, "Bogus maximum timeout!"); return false; } - } else + } else { maxtimeout = 900; + } if(get_config_string(lookup_config(config_tree, "AddressFamily"), &afname)) { - if(!strcasecmp(afname, "IPv4")) + if(!strcasecmp(afname, "IPv4")) { addressfamily = AF_INET; - else if(!strcasecmp(afname, "IPv6")) + } else if(!strcasecmp(afname, "IPv6")) { addressfamily = AF_INET6; - else if(!strcasecmp(afname, "any")) + } else if(!strcasecmp(afname, "any")) { addressfamily = AF_UNSPEC; - else { + } else { logger(DEBUG_ALWAYS, LOG_ERR, "Invalid address family!"); return false; } + free(afname); } get_config_bool(lookup_config(config_tree, "Hostnames"), &hostnames); - if(!get_config_int(lookup_config(config_tree, "KeyExpire"), &keylifetime)) + if(!get_config_int(lookup_config(config_tree, "KeyExpire"), &keylifetime)) { keylifetime = 3600; + } - config_t *cfg = lookup_config(config_tree, "AutoConnect"); - if(cfg) { - if(!get_config_bool(cfg, &autoconnect)) { - // Some backwards compatibility with when this option was an int - int val = 0; - get_config_int(cfg, &val); - autoconnect = val; - } + if(!get_config_bool(lookup_config(config_tree, "AutoConnect"), &autoconnect)) { + autoconnect = true; } get_config_bool(lookup_config(config_tree, "DisableBuggyPeers"), &disablebuggypeers); - if(!get_config_int(lookup_config(config_tree, "InvitationExpire"), &invitation_lifetime)) - invitation_lifetime = 604800; // 1 week + if(!get_config_int(lookup_config(config_tree, "InvitationExpire"), &invitation_lifetime)) { + invitation_lifetime = 604800; // 1 week + } read_invitation_key(); @@ -627,25 +710,33 @@ static bool add_listen_address(char *address, bool bindto) { if(address) { char *space = strchr(address, ' '); + if(space) { *space++ = 0; port = space; } - if(!strcmp(address, "*")) + if(!strcmp(address, "*")) { *address = 0; + } } struct addrinfo *ai, hint = {0}; + hint.ai_family = addressfamily; + hint.ai_socktype = SOCK_STREAM; + hint.ai_protocol = IPPROTO_TCP; + hint.ai_flags = AI_PASSIVE; #if HAVE_DECL_RES_INIT res_init(); + #endif int err = getaddrinfo(address && *address ? address : NULL, port, &hint, &ai); + free(address); if(err || !ai) { @@ -663,8 +754,9 @@ static bool add_listen_address(char *address, bool bindto) { break; } - if(found) + if(found) { continue; + } if(listen_sockets >= MAXSOCKETS) { logger(DEBUG_ALWAYS, LOG_ERR, "Too many listening sockets"); @@ -673,8 +765,9 @@ static bool add_listen_address(char *address, bool bindto) { int tcp_fd = setup_listen_socket((sockaddr_t *) aip->ai_addr); - if(tcp_fd < 0) + if(tcp_fd < 0) { continue; + } int udp_fd = setup_vpn_in_socket((sockaddr_t *) aip->ai_addr); @@ -702,8 +795,9 @@ static bool add_listen_address(char *address, bool bindto) { } void device_enable(void) { - if (devops.enable) + if(devops.enable) { devops.enable(); + } /* Run tinc-up script to further initialize the tap interface */ @@ -719,8 +813,9 @@ void device_disable(void) { execute_script("tinc-down", &env); environment_exit(&env); - if (devops.disable) + if(devops.disable) { devops.disable(); + } } /* @@ -741,12 +836,13 @@ static bool setup_myself(void) { myself->connection = new_connection(); myself->name = name; myself->connection->name = xstrdup(name); - read_host_config(config_tree, name); + read_host_config(config_tree, name, true); - if(!get_config_string(lookup_config(config_tree, "Port"), &myport)) + if(!get_config_string(lookup_config(config_tree, "Port"), &myport)) { myport = xstrdup("655"); - else + } else { port_specified = true; + } myself->connection->options = 0; myself->connection->protocol_major = PROT_MAJOR; @@ -756,18 +852,24 @@ static bool setup_myself(void) { #ifdef DISABLE_LEGACY experimental = read_ecdsa_private_key(); + if(!experimental) { logger(DEBUG_ALWAYS, LOG_ERR, "No private key available, cannot start tinc!"); return false; } + #else + if(!get_config_bool(lookup_config(config_tree, "ExperimentalProtocol"), &experimental)) { experimental = read_ecdsa_private_key(); - if(!experimental) + + if(!experimental) { logger(DEBUG_ALWAYS, LOG_WARNING, "Support for SPTPS disabled."); + } } else { - if(experimental && !read_ecdsa_private_key()) + if(experimental && !read_ecdsa_private_key()) { return false; + } } if(!read_rsa_private_key()) { @@ -778,6 +880,7 @@ static bool setup_myself(void) { return false; } } + #endif /* Ensure myport is numeric */ @@ -785,10 +888,14 @@ static bool setup_myself(void) { if(!atoi(myport)) { struct addrinfo *ai = str2addrinfo("localhost", myport, SOCK_DGRAM); sockaddr_t sa; - if(!ai || !ai->ai_addr) + + if(!ai || !ai->ai_addr) { return false; + } + free(myport); memcpy(&sa, ai->ai_addr, ai->ai_addrlen); + freeaddrinfo(ai); sockaddr2str(&sa, NULL, &myport); } @@ -797,16 +904,18 @@ static bool setup_myself(void) { for(config_t *cfg = lookup_config(config_tree, "Subnet"); cfg; cfg = lookup_config_next(config_tree, cfg)) { subnet_t *subnet; - if(!get_config_subnet(cfg, &subnet)) + if(!get_config_subnet(cfg, &subnet)) { return false; + } subnet_add(myself, subnet); } /* Check some options */ - if(!setup_myself_reloadable()) + if(!setup_myself_reloadable()) { return false; + } get_config_bool(lookup_config(config_tree, "StrictSubnets"), &strictsubnets); get_config_bool(lookup_config(config_tree, "TunnelServer"), &tunnelserver); @@ -833,12 +942,24 @@ static bool setup_myself(void) { } } + get_config_int(lookup_config(config_tree, "FWMark"), &fwmark); +#ifndef SO_MARK + + if(fwmark) { + logger(DEBUG_ALWAYS, LOG_ERR, "FWMark not supported on this platform!"); + return false; + } + +#endif + int replaywin_int; + if(get_config_int(lookup_config(config_tree, "ReplayWindow"), &replaywin_int)) { if(replaywin_int < 0) { logger(DEBUG_ALWAYS, LOG_ERR, "ReplayWindow cannot be negative!"); return false; } + replaywin = (unsigned)replaywin_int; sptps_replaywin = replaywin; } @@ -846,19 +967,23 @@ static bool setup_myself(void) { #ifndef DISABLE_LEGACY /* Generate packet encryption key */ - if(!get_config_string(lookup_config(config_tree, "Cipher"), &cipher)) + if(!get_config_string(lookup_config(config_tree, "Cipher"), &cipher)) { cipher = xstrdup("aes-256-cbc"); + } if(!strcasecmp(cipher, "none")) { myself->incipher = NULL; } else if(!(myself->incipher = cipher_open_by_name(cipher))) { logger(DEBUG_ALWAYS, LOG_ERR, "Unrecognized cipher type!"); + free(cipher); return false; } free(cipher); - timeout_add(&keyexpire_timeout, keyexpire_handler, &keyexpire_timeout, &(struct timeval){keylifetime, rand() % 100000}); + timeout_add(&keyexpire_timeout, keyexpire_handler, &keyexpire_timeout, &(struct timeval) { + keylifetime, rand() % 100000 + }); /* Check if we want to use message authentication codes... */ @@ -870,13 +995,15 @@ static bool setup_myself(void) { return false; } - if(!get_config_string(lookup_config(config_tree, "Digest"), &digest)) + if(!get_config_string(lookup_config(config_tree, "Digest"), &digest)) { digest = xstrdup("sha256"); + } if(!strcasecmp(digest, "none")) { myself->indigest = NULL; } else if(!(myself->indigest = digest_open_by_name(digest, maclength))) { logger(DEBUG_ALWAYS, LOG_ERR, "Unrecognized digest type!"); + free(digest); return false; } @@ -890,8 +1017,9 @@ static bool setup_myself(void) { logger(DEBUG_ALWAYS, LOG_ERR, "Bogus compression level!"); return false; } - } else + } else { myself->incompression = 0; + } myself->connection->outcompression = 0; @@ -913,32 +1041,40 @@ static bool setup_myself(void) { devops = os_devops; if(get_config_string(lookup_config(config_tree, "DeviceType"), &type)) { - if(!strcasecmp(type, "dummy")) + if(!strcasecmp(type, "dummy")) { devops = dummy_devops; - else if(!strcasecmp(type, "raw_socket")) + } else if(!strcasecmp(type, "raw_socket")) { devops = raw_socket_devops; - else if(!strcasecmp(type, "multicast")) + } else if(!strcasecmp(type, "multicast")) { devops = multicast_devops; - else if(!strcasecmp(type, "fd")) + } else if(!strcasecmp(type, "fd")) { devops = fd_devops; + } + #ifdef ENABLE_UML - else if(!strcasecmp(type, "uml")) + else if(!strcasecmp(type, "uml")) { devops = uml_devops; + } + #endif #ifdef ENABLE_VDE - else if(!strcasecmp(type, "vde")) + else if(!strcasecmp(type, "vde")) { devops = vde_devops; + } + #endif free(type); } get_config_bool(lookup_config(config_tree, "DeviceStandby"), &device_standby); - if(!devops.setup()) + if(!devops.setup()) { return false; + } - if(device_fd >= 0) + if(device_fd >= 0) { io_add(&device_io, handle_device_data, NULL, device_fd, IO_READ); + } /* Open sockets */ @@ -957,7 +1093,8 @@ static bool setup_myself(void) { } for(int i = 0; i < listen_sockets; i++) { - salen = sizeof sa; + salen = sizeof(sa); + if(getsockname(i + 3, &sa.sa, &salen) < 0) { logger(DEBUG_ALWAYS, LOG_ERR, "Could not get address of listen fd %d: %s", i + 3, sockstrerror(sockerrno)); return false; @@ -968,8 +1105,10 @@ static bool setup_myself(void) { #endif int udp_fd = setup_vpn_in_socket(&sa); - if(udp_fd < 0) + + if(udp_fd < 0) { return false; + } io_add(&listen_socket[i].tcp, (io_cb_t)handle_new_meta_connection, &listen_socket[i], i + 3, IO_READ); io_add(&listen_socket[i].udp, (io_cb_t)handle_incoming_vpn_data, &listen_socket[i], udp_fd, IO_READ); @@ -989,20 +1128,25 @@ static bool setup_myself(void) { for(config_t *cfg = lookup_config(config_tree, "BindToAddress"); cfg; cfg = lookup_config_next(config_tree, cfg)) { cfgs++; get_config_string(cfg, &address); - if(!add_listen_address(address, true)) + + if(!add_listen_address(address, true)) { return false; + } } for(config_t *cfg = lookup_config(config_tree, "ListenAddress"); cfg; cfg = lookup_config_next(config_tree, cfg)) { cfgs++; get_config_string(cfg, &address); - if(!add_listen_address(address, false)) + + if(!add_listen_address(address, false)) { return false; + } } if(!cfgs) - if(!add_listen_address(address, NULL)) + if(!add_listen_address(address, NULL)) { return false; + } } if(!listen_sockets) { @@ -1014,12 +1158,15 @@ static bool setup_myself(void) { if(!port_specified || atoi(myport) == 0) { sockaddr_t sa; - socklen_t salen = sizeof sa; + socklen_t salen = sizeof(sa); + if(!getsockname(listen_socket[0].udp.fd, &sa.sa, &salen)) { free(myport); sockaddr2str(&sa, NULL, &myport); - if(!myport) + + if(!myport) { myport = xstrdup("655"); + } } } @@ -1030,14 +1177,18 @@ static bool setup_myself(void) { get_config_string(lookup_config(config_tree, "UPnP"), &upnp); bool upnp_tcp = false; bool upnp_udp = false; - if (upnp) { - if (!strcasecmp(upnp, "yes")) + + if(upnp) { + if(!strcasecmp(upnp, "yes")) { upnp_tcp = upnp_udp = true; - else if (!strcasecmp(upnp, "udponly")) + } else if(!strcasecmp(upnp, "udponly")) { upnp_udp = true; + } + free(upnp); } - if (upnp_tcp || upnp_udp) { + + if(upnp_tcp || upnp_udp) { #ifdef HAVE_MINIUPNPC upnp_init(upnp_tcp, upnp_udp); #else @@ -1066,25 +1217,33 @@ bool setup_network(void) { if(pinginterval < 1) { pinginterval = 86400; } - } else + } else { pinginterval = 60; + } - if(!get_config_int(lookup_config(config_tree, "PingTimeout"), &pingtimeout)) + if(!get_config_int(lookup_config(config_tree, "PingTimeout"), &pingtimeout)) { pingtimeout = 5; - if(pingtimeout < 1 || pingtimeout > pinginterval) + } + + if(pingtimeout < 1 || pingtimeout > pinginterval) { pingtimeout = pinginterval; + } - if(!get_config_int(lookup_config(config_tree, "MaxOutputBufferSize"), &maxoutbufsize)) + if(!get_config_int(lookup_config(config_tree, "MaxOutputBufferSize"), &maxoutbufsize)) { maxoutbufsize = 10 * MTU; + } - if(!setup_myself()) + if(!setup_myself()) { return false; + } - if(!init_control()) + if(!init_control()) { return false; + } - if (!device_standby) + if(!device_standby) { device_enable(); + } /* Run subnet-up scripts for our own subnets */ @@ -1100,15 +1259,19 @@ void close_network_connections(void) { for(list_node_t *node = connection_list->head, *next; node; node = next) { next = node->next; connection_t *c = node->data; + /* Keep control connections open until the end, so they know when we really terminated */ - if(c->status.control) + if(c->status.control) { c->socket = -1; + } + c->outgoing = NULL; terminate_connection(c, false); } - if(outgoing_list) + if(outgoing_list) { list_delete_list(outgoing_list); + } if(myself && myself->connection) { subnet_update(myself, NULL, false); @@ -1128,15 +1291,19 @@ void close_network_connections(void) { exit_nodes(); exit_connections(); - if (!device_standby) + if(!device_standby) { device_disable(); + } free(myport); - if (device_fd >= 0) + if(device_fd >= 0) { io_del(&device_io); - if (devops.close) + } + + if(devops.close) { devops.close(); + } exit_control(); diff --git a/src/net_socket.c b/src/net_socket.c index ac6b840..dcf8372 100644 --- a/src/net_socket.c +++ b/src/net_socket.c @@ -22,6 +22,7 @@ #include "system.h" +#include "address_cache.h" #include "conf.h" #include "connection.h" #include "control_common.h" @@ -40,7 +41,8 @@ int maxtimeout = 900; int seconds_till_retry = 5; int udp_rcvbuf = 1024 * 1024; int udp_sndbuf = 1024 * 1024; -int max_connection_burst = 100; +int max_connection_burst = 10; +int fwmark; listen_socket_t listen_socket[MAXSOCKETS]; int listen_sockets; @@ -58,29 +60,39 @@ static void configure_tcp(connection_t *c) { int flags = fcntl(c->socket, F_GETFL); if(fcntl(c->socket, F_SETFL, flags | O_NONBLOCK) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "fcntl for %s: %s", c->hostname, strerror(errno)); + logger(DEBUG_ALWAYS, LOG_ERR, "fcntl for %s fd %d: %s", c->hostname, c->socket, strerror(errno)); } + #elif defined(WIN32) unsigned long arg = 1; if(ioctlsocket(c->socket, FIONBIO, &arg) != 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "ioctlsocket for %s: %s", c->hostname, sockstrerror(sockerrno)); + logger(DEBUG_ALWAYS, LOG_ERR, "ioctlsocket for %s fd %d: %s", c->hostname, c->socket, sockstrerror(sockerrno)); } + #endif -#if defined(IPPROTO_TCP) && defined(TCP_NODELAY) +#if defined(TCP_NODELAY) option = 1; - setsockopt(c->socket, IPPROTO_TCP, TCP_NODELAY, (void *)&option, sizeof option); + setsockopt(c->socket, IPPROTO_TCP, TCP_NODELAY, (void *)&option, sizeof(option)); #endif -#if defined(IPPROTO_IP) && defined(IP_TOS) && defined(IPTOS_LOWDELAY) +#if defined(IP_TOS) && defined(IPTOS_LOWDELAY) option = IPTOS_LOWDELAY; - setsockopt(c->socket, IPPROTO_IP, IP_TOS, (void *)&option, sizeof option); + setsockopt(c->socket, IPPROTO_IP, IP_TOS, (void *)&option, sizeof(option)); #endif -#if defined(IPPROTO_IPV6) && defined(IPV6_TCLASS) && defined(IPTOS_LOWDELAY) +#if defined(IPV6_TCLASS) && defined(IPTOS_LOWDELAY) option = IPTOS_LOWDELAY; - setsockopt(c->socket, IPPROTO_IPV6, IPV6_TCLASS, (void *)&option, sizeof option); + setsockopt(c->socket, IPPROTO_IPV6, IPV6_TCLASS, (void *)&option, sizeof(option)); +#endif + +#if defined(SO_MARK) + + if(fwmark) { + setsockopt(c->socket, SOL_SOCKET, SO_MARK, (void *)&fwmark, sizeof(fwmark)); + } + #endif } @@ -92,8 +104,9 @@ static bool bind_to_interface(int sd) { int status; #endif /* defined(SOL_SOCKET) && defined(SO_BINDTODEVICE) */ - if(!get_config_string (lookup_config (config_tree, "BindToInterface"), &iface)) + if(!get_config_string(lookup_config(config_tree, "BindToInterface"), &iface)) { return true; + } #if defined(SOL_SOCKET) && defined(SO_BINDTODEVICE) memset(&ifr, 0, sizeof(ifr)); @@ -101,11 +114,13 @@ static bool bind_to_interface(int sd) { ifr.ifr_ifrn.ifrn_name[IFNAMSIZ - 1] = 0; status = setsockopt(sd, SOL_SOCKET, SO_BINDTODEVICE, (void *)&ifr, sizeof(ifr)); + if(status) { logger(DEBUG_ALWAYS, LOG_ERR, "Can't bind to interface %s: %s", iface, - sockstrerror(sockerrno)); + sockstrerror(sockerrno)); return false; } + #else /* if !defined(SOL_SOCKET) || !defined(SO_BINDTODEVICE) */ logger(DEBUG_ALWAYS, LOG_WARNING, "%s not supported on this platform", "BindToInterface"); #endif @@ -117,21 +132,28 @@ static bool bind_to_address(connection_t *c) { int s = -1; for(int i = 0; i < listen_sockets && listen_socket[i].bindto; i++) { - if(listen_socket[i].sa.sa.sa_family != c->address.sa.sa_family) + if(listen_socket[i].sa.sa.sa_family != c->address.sa.sa_family) { continue; - if(s >= 0) + } + + if(s >= 0) { return false; + } + s = i; } - if(s < 0) + if(s < 0) { return false; + } sockaddr_t sa = listen_socket[s].sa; - if(sa.sa.sa_family == AF_INET) + + if(sa.sa.sa_family == AF_INET) { sa.in.sin_port = 0; - else if(sa.sa.sa_family == AF_INET6) + } else if(sa.sa.sa_family == AF_INET6) { sa.in6.sin6_port = 0; + } if(bind(c->socket, &sa.sa, SALEN(sa.sa))) { logger(DEBUG_CONNECTIONS, LOG_WARNING, "Can't bind outgoing socket: %s", sockstrerror(sockerrno)); @@ -161,27 +183,42 @@ int setup_listen_socket(const sockaddr_t *sa) { /* Optimize TCP settings */ option = 1; - setsockopt(nfd, SOL_SOCKET, SO_REUSEADDR, (void *)&option, sizeof option); + setsockopt(nfd, SOL_SOCKET, SO_REUSEADDR, (void *)&option, sizeof(option)); + +#if defined(IPV6_V6ONLY) + + if(sa->sa.sa_family == AF_INET6) { + setsockopt(nfd, IPPROTO_IPV6, IPV6_V6ONLY, (void *)&option, sizeof(option)); + } + +#else +#warning IPV6_V6ONLY not defined +#endif + +#if defined(SO_MARK) + + if(fwmark) { + setsockopt(nfd, SOL_SOCKET, SO_MARK, (void *)&fwmark, sizeof(fwmark)); + } -#if defined(IPPROTO_IPV6) && defined(IPV6_V6ONLY) - if(sa->sa.sa_family == AF_INET6) - setsockopt(nfd, IPPROTO_IPV6, IPV6_V6ONLY, (void *)&option, sizeof option); #endif if(get_config_string - (lookup_config(config_tree, "BindToInterface"), &iface)) { + (lookup_config(config_tree, "BindToInterface"), &iface)) { #if defined(SOL_SOCKET) && defined(SO_BINDTODEVICE) struct ifreq ifr; - memset(&ifr, 0, sizeof ifr); + memset(&ifr, 0, sizeof(ifr)); strncpy(ifr.ifr_ifrn.ifrn_name, iface, IFNAMSIZ); + ifr.ifr_ifrn.ifrn_name[IFNAMSIZ - 1] = 0; - if(setsockopt(nfd, SOL_SOCKET, SO_BINDTODEVICE, (void *)&ifr, sizeof ifr)) { + if(setsockopt(nfd, SOL_SOCKET, SO_BINDTODEVICE, (void *)&ifr, sizeof(ifr))) { closesocket(nfd); logger(DEBUG_ALWAYS, LOG_ERR, "Can't bind to interface %s: %s", iface, - sockstrerror(sockerrno)); + sockstrerror(sockerrno)); return -1; } + #else logger(DEBUG_ALWAYS, LOG_WARNING, "%s not supported on this platform", "BindToInterface"); #endif @@ -227,13 +264,14 @@ int setup_vpn_in_socket(const sockaddr_t *sa) { if(fcntl(nfd, F_SETFL, flags | O_NONBLOCK) < 0) { closesocket(nfd); logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "fcntl", - strerror(errno)); + strerror(errno)); return -1; } } #elif defined(WIN32) { unsigned long arg = 1; + if(ioctlsocket(nfd, FIONBIO, &arg) != 0) { closesocket(nfd); logger(DEBUG_ALWAYS, LOG_ERR, "Call to `%s' failed: %s", "ioctlsocket", sockstrerror(sockerrno)); @@ -243,49 +281,70 @@ int setup_vpn_in_socket(const sockaddr_t *sa) { #endif option = 1; - setsockopt(nfd, SOL_SOCKET, SO_REUSEADDR, (void *)&option, sizeof option); - setsockopt(nfd, SOL_SOCKET, SO_BROADCAST, (void *)&option, sizeof option); + setsockopt(nfd, SOL_SOCKET, SO_REUSEADDR, (void *)&option, sizeof(option)); + setsockopt(nfd, SOL_SOCKET, SO_BROADCAST, (void *)&option, sizeof(option)); - if(udp_rcvbuf && setsockopt(nfd, SOL_SOCKET, SO_RCVBUF, (void *)&udp_rcvbuf, sizeof(udp_rcvbuf))) + if(udp_rcvbuf && setsockopt(nfd, SOL_SOCKET, SO_RCVBUF, (void *)&udp_rcvbuf, sizeof(udp_rcvbuf))) { logger(DEBUG_ALWAYS, LOG_WARNING, "Can't set UDP SO_RCVBUF to %i: %s", udp_rcvbuf, sockstrerror(sockerrno)); + } - if(udp_sndbuf && setsockopt(nfd, SOL_SOCKET, SO_SNDBUF, (void *)&udp_sndbuf, sizeof(udp_sndbuf))) + if(udp_sndbuf && setsockopt(nfd, SOL_SOCKET, SO_SNDBUF, (void *)&udp_sndbuf, sizeof(udp_sndbuf))) { logger(DEBUG_ALWAYS, LOG_WARNING, "Can't set UDP SO_SNDBUF to %i: %s", udp_sndbuf, sockstrerror(sockerrno)); + } + +#if defined(IPV6_V6ONLY) + + if(sa->sa.sa_family == AF_INET6) { + setsockopt(nfd, IPPROTO_IPV6, IPV6_V6ONLY, (void *)&option, sizeof(option)); + } -#if defined(IPPROTO_IPV6) && defined(IPV6_V6ONLY) - if(sa->sa.sa_family == AF_INET6) - setsockopt(nfd, IPPROTO_IPV6, IPV6_V6ONLY, (void *)&option, sizeof option); #endif #if defined(IP_DONTFRAG) && !defined(IP_DONTFRAGMENT) #define IP_DONTFRAGMENT IP_DONTFRAG #endif -#if defined(IPPROTO_IP) && defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DO) +#if defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DO) + if(myself->options & OPTION_PMTU_DISCOVERY) { option = IP_PMTUDISC_DO; setsockopt(nfd, IPPROTO_IP, IP_MTU_DISCOVER, (void *)&option, sizeof(option)); } -#elif defined(IPPROTO_IP) && defined(IP_DONTFRAGMENT) + +#elif defined(IP_DONTFRAGMENT) + if(myself->options & OPTION_PMTU_DISCOVERY) { option = 1; setsockopt(nfd, IPPROTO_IP, IP_DONTFRAGMENT, (void *)&option, sizeof(option)); } + #endif -#if defined(IPPROTO_IPV6) && defined(IPV6_MTU_DISCOVER) && defined(IPV6_PMTUDISC_DO) +#if defined(IPV6_MTU_DISCOVER) && defined(IPV6_PMTUDISC_DO) + if(myself->options & OPTION_PMTU_DISCOVERY) { option = IPV6_PMTUDISC_DO; setsockopt(nfd, IPPROTO_IPV6, IPV6_MTU_DISCOVER, (void *)&option, sizeof(option)); } -#elif defined(IPPROTO_IPV6) && defined(IPV6_DONTFRAG) + +#elif defined(IPV6_DONTFRAG) + if(myself->options & OPTION_PMTU_DISCOVERY) { option = 1; setsockopt(nfd, IPPROTO_IPV6, IPV6_DONTFRAG, (void *)&option, sizeof(option)); } + #endif - if (!bind_to_interface(nfd)) { +#if defined(SO_MARK) + + if(fwmark) { + setsockopt(nfd, SOL_SOCKET, SO_MARK, (void *)&fwmark, sizeof(fwmark)); + } + +#endif + + if(!bind_to_interface(nfd)) { closesocket(nfd); return -1; } @@ -302,16 +361,19 @@ int setup_vpn_in_socket(const sockaddr_t *sa) { } /* int setup_vpn_in_socket */ static void retry_outgoing_handler(void *data) { - setup_outgoing_connection(data); + setup_outgoing_connection(data, true); } void retry_outgoing(outgoing_t *outgoing) { outgoing->timeout += 5; - if(outgoing->timeout > maxtimeout) + if(outgoing->timeout > maxtimeout) { outgoing->timeout = maxtimeout; + } - timeout_add(&outgoing->ev, retry_outgoing_handler, outgoing, &(struct timeval){outgoing->timeout, rand() % 100000}); + timeout_add(&outgoing->ev, retry_outgoing_handler, outgoing, &(struct timeval) { + outgoing->timeout, rand() % 100000 + }); logger(DEBUG_CONNECTIONS, LOG_NOTICE, "Trying to re-establish outgoing connection in %d seconds", outgoing->timeout); } @@ -358,14 +420,19 @@ static void do_outgoing_pipe(connection_t *c, char *command) { setenv("REMOTEPORT", port, true); setenv("NODE", c->name, true); setenv("NAME", myself->name, true); - if(netname) + + if(netname) { setenv("NETNAME", netname, true); + } int result = system(command); - if(result < 0) + + if(result < 0) { logger(DEBUG_ALWAYS, LOG_ERR, "Could not execute %s: %s", command, strerror(errno)); - else if(result) + } else if(result) { logger(DEBUG_ALWAYS, LOG_ERR, "%s exited with non-zero status %d", command, result); + } + exit(result); #else logger(DEBUG_ALWAYS, LOG_ERR, "Proxy type exec not supported on this platform!"); @@ -374,10 +441,12 @@ static void do_outgoing_pipe(connection_t *c, char *command) { } static void handle_meta_write(connection_t *c) { - if(c->outbuf.len <= c->outbuf.offset) + if(c->outbuf.len <= c->outbuf.offset) { return; + } ssize_t outlen = send(c->socket, c->outbuf.data + c->outbuf.offset, c->outbuf.len - c->outbuf.offset, 0); + if(outlen <= 0) { if(!sockerrno || sockerrno == EPIPE) { logger(DEBUG_CONNECTIONS, LOG_NOTICE, "Connection closed by %s (%s)", c->name, c->hostname); @@ -393,8 +462,10 @@ static void handle_meta_write(connection_t *c) { } buffer_read(&c->outbuf, outlen); - if(!c->outbuf.len) + + if(!c->outbuf.len) { io_set(&c->io, IO_READ); + } } static void handle_meta_io(void *data, int flags) { @@ -414,20 +485,25 @@ static void handle_meta_io(void *data, int flags) { | Successful | (success) | (success) | (success) | +------------+-----------+-------------+-----------+ */ - if (send(c->socket, NULL, 0, 0) != 0) { - if (sockwouldblock(sockerrno)) + if(send(c->socket, NULL, 0, 0) != 0) { + if(sockwouldblock(sockerrno)) { return; + } + int socket_error; - if (!socknotconn(sockerrno)) + + if(!socknotconn(sockerrno)) { socket_error = sockerrno; - else { - socklen_t len = sizeof socket_error; + } else { + socklen_t len = sizeof(socket_error); getsockopt(c->socket, SOL_SOCKET, SO_ERROR, (void *)&socket_error, &len); } - if (socket_error) { + + if(socket_error) { logger(DEBUG_CONNECTIONS, LOG_DEBUG, "Error while connecting to %s (%s): %s", c->name, c->hostname, sockstrerror(socket_error)); terminate_connection(c, false); } + return; } @@ -435,72 +511,33 @@ static void handle_meta_io(void *data, int flags) { finish_connecting(c); } - if(flags & IO_WRITE) + if(flags & IO_WRITE) { handle_meta_write(c); - else + } else { handle_meta_connection_data(c); -} - -static void free_known_addresses(struct addrinfo *ai) { - for(struct addrinfo *aip = ai, *next; aip; aip = next) { - next = aip->ai_next; - free(aip); } } bool do_outgoing_connection(outgoing_t *outgoing) { - char *address, *port, *space; + const sockaddr_t *sa; struct addrinfo *proxyai = NULL; int result; begin: - if(!outgoing->ai && !outgoing->kai) { - if(!outgoing->cfg) { - logger(DEBUG_CONNECTIONS, LOG_ERR, "Could not set up a meta connection to %s", outgoing->name); - retry_outgoing(outgoing); - return false; - } + sa = get_recent_address(outgoing->address_cache); - get_config_string(outgoing->cfg, &address); - - space = strchr(address, ' '); - if(space) { - port = xstrdup(space + 1); - *space = 0; - } else { - if(!get_config_string(lookup_config(outgoing->config_tree, "Port"), &port)) - port = xstrdup("655"); - } - - outgoing->ai = str2addrinfo(address, port, SOCK_STREAM); - free(address); - free(port); - - outgoing->aip = outgoing->ai; - outgoing->cfg = lookup_config_next(outgoing->config_tree, outgoing->cfg); - } - - if(!outgoing->aip) { - if(outgoing->ai) - freeaddrinfo(outgoing->ai); - outgoing->ai = NULL; - - if(outgoing->kai) - free_known_addresses(outgoing->kai); - outgoing->kai = NULL; - - goto begin; + if(!sa) { + logger(DEBUG_CONNECTIONS, LOG_ERR, "Could not set up a meta connection to %s", outgoing->node->name); + retry_outgoing(outgoing); + return false; } connection_t *c = new_connection(); c->outgoing = outgoing; - - memcpy(&c->address, outgoing->aip->ai_addr, outgoing->aip->ai_addrlen); - outgoing->aip = outgoing->aip->ai_next; - + memcpy(&c->address, sa, SALEN(sa->sa)); c->hostname = sockaddr2hostname(&c->address); - logger(DEBUG_CONNECTIONS, LOG_INFO, "Trying to connect to %s (%s)", outgoing->name, c->hostname); + logger(DEBUG_CONNECTIONS, LOG_INFO, "Trying to connect to %s (%s)", outgoing->node->name, c->hostname); if(!proxytype) { c->socket = socket(c->address.sa.sa_family, SOCK_STREAM, IPPROTO_TCP); @@ -509,10 +546,12 @@ begin: do_outgoing_pipe(c, proxyhost); } else { proxyai = str2addrinfo(proxyhost, proxyport, SOCK_STREAM); + if(!proxyai) { free_connection(c); goto begin; } + logger(DEBUG_CONNECTIONS, LOG_INFO, "Using proxy at %s port %s", proxyhost, proxyport); c->socket = socket(proxyai->ai_family, SOCK_STREAM, IPPROTO_TCP); configure_tcp(c); @@ -529,10 +568,13 @@ begin: #endif if(proxytype != PROXY_EXEC) { -#if defined(IPPROTO_IPV6) && defined(IPV6_V6ONLY) +#if defined(IPV6_V6ONLY) int option = 1; - if(c->address.sa.sa_family == AF_INET6) - setsockopt(c->socket, IPPROTO_IPV6, IPV6_V6ONLY, (void *)&option, sizeof option); + + if(c->address.sa.sa_family == AF_INET6) { + setsockopt(c->socket, IPPROTO_IPV6, IPV6_V6ONLY, (void *)&option, sizeof(option)); + } + #endif bind_to_interface(c->socket); @@ -546,14 +588,16 @@ begin: } else if(proxytype == PROXY_EXEC) { result = 0; } else { - if(!proxyai) + if(!proxyai) { abort(); + } + result = connect(c->socket, proxyai->ai_addr, proxyai->ai_addrlen); freeaddrinfo(proxyai); } if(result == -1 && !sockinprogress(sockerrno)) { - logger(DEBUG_CONNECTIONS, LOG_ERR, "Could not connect to %s (%s): %s", outgoing->name, c->hostname, sockstrerror(sockerrno)); + logger(DEBUG_CONNECTIONS, LOG_ERR, "Could not connect to %s (%s): %s", outgoing->node->name, c->hostname, sockstrerror(sockerrno)); free_connection(c); goto begin; @@ -563,7 +607,7 @@ begin: c->last_ping_time = time(NULL); c->status.connecting = true; - c->name = xstrdup(outgoing->name); + c->name = xstrdup(outgoing->node->name); #ifndef DISABLE_LEGACY c->outcipher = myself->connection->outcipher; c->outdigest = myself->connection->outdigest; @@ -574,51 +618,20 @@ begin: connection_add(c); - io_add(&c->io, handle_meta_io, c, c->socket, IO_READ|IO_WRITE); + io_add(&c->io, handle_meta_io, c, c->socket, IO_READ | IO_WRITE); return true; } -// Find edges pointing to this node, and use them to build a list of unique, known addresses. -static struct addrinfo *get_known_addresses(node_t *n) { - struct addrinfo *ai = NULL; - struct addrinfo *oai = NULL; - - for splay_each(edge_t, e, n->edge_tree) { - if(!e->reverse) - continue; - - bool found = false; - for(struct addrinfo *aip = ai; aip; aip = aip->ai_next) { - if(!sockaddrcmp(&e->reverse->address, (sockaddr_t *)aip->ai_addr)) { - found = true; - break; - } - } - if(found) - continue; - - oai = ai; - ai = xzalloc(sizeof *ai); - ai->ai_family = e->reverse->address.sa.sa_family; - ai->ai_socktype = SOCK_STREAM; - ai->ai_protocol = IPPROTO_TCP; - ai->ai_addrlen = SALEN(e->reverse->address.sa); - ai->ai_addr = xmalloc(ai->ai_addrlen); - memcpy(ai->ai_addr, &e->reverse->address, ai->ai_addrlen); - ai->ai_next = oai; - } - - return ai; -} - -void setup_outgoing_connection(outgoing_t *outgoing) { +void setup_outgoing_connection(outgoing_t *outgoing, bool verbose) { + (void)verbose; timeout_del(&outgoing->ev); - node_t *n = lookup_node(outgoing->name); + node_t *n = outgoing->node; + + if(n->connection) { + logger(DEBUG_CONNECTIONS, LOG_INFO, "Already connected to %s", n->name); - if(n && n->connection) { - logger(DEBUG_CONNECTIONS, LOG_INFO, "Already connected to %s", outgoing->name); if(!n->connection->outgoing) { n->connection->outgoing = outgoing; return; @@ -627,17 +640,8 @@ void setup_outgoing_connection(outgoing_t *outgoing) { } } - init_configuration(&outgoing->config_tree); - read_host_config(outgoing->config_tree, outgoing->name); - outgoing->cfg = lookup_config(outgoing->config_tree, "Address"); - - if(!outgoing->cfg) { - if(n) - outgoing->aip = outgoing->kai = get_known_addresses(n); - if(!outgoing->kai) { - logger(DEBUG_ALWAYS, LOG_DEBUG, "No address known for %s", outgoing->name); - goto remove; - } + if(!outgoing->address_cache) { + outgoing->address_cache = open_address_cache(n); } do_outgoing_connection(outgoing); @@ -652,11 +656,12 @@ remove: new connection */ void handle_new_meta_connection(void *data, int flags) { + (void)flags; listen_socket_t *l = data; connection_t *c; sockaddr_t sa; int fd; - socklen_t len = sizeof sa; + socklen_t len = sizeof(sa); fd = accept(l->tcp.fd, &sa.sa, &len); @@ -670,49 +675,45 @@ void handle_new_meta_connection(void *data, int flags) { // Check if we get many connections from the same host static sockaddr_t prev_sa; - static int tarpit = -1; - - if(tarpit >= 0) { - closesocket(tarpit); - tarpit = -1; - } if(!sockaddrcmp_noport(&sa, &prev_sa)) { static int samehost_burst; static int samehost_burst_time; - if(now.tv_sec - samehost_burst_time > samehost_burst) + if(now.tv_sec - samehost_burst_time > samehost_burst) { samehost_burst = 0; - else + } else { samehost_burst -= now.tv_sec - samehost_burst_time; + } samehost_burst_time = now.tv_sec; samehost_burst++; if(samehost_burst > max_connection_burst) { - tarpit = fd; + tarpit(fd); return; } } - memcpy(&prev_sa, &sa, sizeof sa); + memcpy(&prev_sa, &sa, sizeof(sa)); // Check if we get many connections from different hosts static int connection_burst; static int connection_burst_time; - if(now.tv_sec - connection_burst_time > connection_burst) + if(now.tv_sec - connection_burst_time > connection_burst) { connection_burst = 0; - else + } else { connection_burst -= now.tv_sec - connection_burst_time; + } connection_burst_time = now.tv_sec; connection_burst++; if(connection_burst >= max_connection_burst) { connection_burst = max_connection_burst; - tarpit = fd; + tarpit(fd); return; } @@ -741,7 +742,6 @@ void handle_new_meta_connection(void *data, int flags) { connection_add(c); c->allow_request = ID; - send_id(c); } #ifndef HAVE_MINGW @@ -749,11 +749,12 @@ void handle_new_meta_connection(void *data, int flags) { accept a new UNIX socket connection */ void handle_new_unix_connection(void *data, int flags) { + (void)flags; io_t *io = data; connection_t *c; sockaddr_t sa; int fd; - socklen_t len = sizeof sa; + socklen_t len = sizeof(sa); fd = accept(io->fd, &sa.sa, &len); @@ -778,25 +779,15 @@ void handle_new_unix_connection(void *data, int flags) { connection_add(c); c->allow_request = ID; - - send_id(c); } #endif static void free_outgoing(outgoing_t *outgoing) { timeout_del(&outgoing->ev); - if(outgoing->ai) - freeaddrinfo(outgoing->ai); - - if(outgoing->kai) - free_known_addresses(outgoing->kai); - - if(outgoing->config_tree) - exit_configuration(&outgoing->config_tree); - - if(outgoing->name) - free(outgoing->name); + if(outgoing->address_cache) { + close_address_cache(outgoing->address_cache); + } free(outgoing); } @@ -807,8 +798,9 @@ void try_outgoing_connections(void) { if(!outgoing_list) { outgoing_list = list_alloc((list_action_t)free_outgoing); } else { - for list_each(outgoing_t, outgoing, outgoing_list) + for list_each(outgoing_t, outgoing, outgoing_list) { outgoing->timeout = -1; + } } /* Make sure there is one outgoing_t in the list for each ConnectTo. */ @@ -819,8 +811,8 @@ void try_outgoing_connections(void) { if(!check_id(name)) { logger(DEBUG_ALWAYS, LOG_ERR, - "Invalid name for outgoing connection in %s line %d", - cfg->file, cfg->line); + "Invalid name for outgoing connection in %s line %d", + cfg->file, cfg->line); free(name); continue; } @@ -833,7 +825,7 @@ void try_outgoing_connections(void) { bool found = false; for list_each(outgoing_t, outgoing, outgoing_list) { - if(!strcmp(outgoing->name, name)) { + if(!strcmp(outgoing->node->name, name)) { found = true; outgoing->timeout = 0; break; @@ -841,10 +833,18 @@ void try_outgoing_connections(void) { } if(!found) { - outgoing_t *outgoing = xzalloc(sizeof *outgoing); - outgoing->name = name; + outgoing_t *outgoing = xzalloc(sizeof(*outgoing)); + node_t *n = lookup_node(name); + + if(!n) { + n = new_node(); + n->name = xstrdup(name); + node_add(n); + } + + outgoing->node = n; list_insert_tail(outgoing_list, outgoing); - setup_outgoing_connection(outgoing); + setup_outgoing_connection(outgoing, true); } } @@ -861,6 +861,7 @@ void try_outgoing_connections(void) { /* Delete outgoing_ts for which there is no ConnectTo. */ for list_each(outgoing_t, outgoing, outgoing_list) - if(outgoing->timeout == -1) + if(outgoing->timeout == -1) { list_delete_node(outgoing_list, node); + } } diff --git a/src/netutl.c b/src/netutl.c index a9ad17c..2916e9a 100644 --- a/src/netutl.c +++ b/src/netutl.c @@ -54,7 +54,7 @@ struct addrinfo *str2addrinfo(const char *address, const char *service, int sock sockaddr_t str2sockaddr(const char *address, const char *port) { struct addrinfo *ai, hint = {0}; - sockaddr_t result = {{0}}; + sockaddr_t result = {0}; int err; hint.ai_family = AF_UNSPEC; @@ -84,20 +84,28 @@ void sockaddr2str(const sockaddr_t *sa, char **addrstr, char **portstr) { int err; if(sa->sa.sa_family == AF_UNSPEC) { - if(addrstr) + if(addrstr) { *addrstr = xstrdup("unspec"); - if(portstr) + } + + if(portstr) { *portstr = xstrdup("unspec"); + } + return; } else if(sa->sa.sa_family == AF_UNKNOWN) { - if(addrstr) + if(addrstr) { *addrstr = xstrdup(sa->unknown.address); - if(portstr) + } + + if(portstr) { *portstr = xstrdup(sa->unknown.port); + } + return; } - err = getnameinfo(&sa->sa, SALEN(sa->sa), address, sizeof address, port, sizeof port, NI_NUMERICHOST | NI_NUMERICSERV); + err = getnameinfo(&sa->sa, SALEN(sa->sa), address, sizeof(address), port, sizeof(port), NI_NUMERICHOST | NI_NUMERICSERV); if(err) { logger(DEBUG_ALWAYS, LOG_ERR, "Error while translating addresses: %s", err == EAI_SYSTEM ? strerror(errno) : gai_strerror(err)); @@ -106,13 +114,17 @@ void sockaddr2str(const sockaddr_t *sa, char **addrstr, char **portstr) { scopeid = strchr(address, '%'); - if(scopeid) - *scopeid = '\0'; /* Descope. */ + if(scopeid) { + *scopeid = '\0'; /* Descope. */ + } - if(addrstr) + if(addrstr) { *addrstr = xstrdup(address); - if(portstr) + } + + if(portstr) { *portstr = xstrdup(port); + } } char *sockaddr2hostname(const sockaddr_t *sa) { @@ -129,8 +141,9 @@ char *sockaddr2hostname(const sockaddr_t *sa) { return str; } - err = getnameinfo(&sa->sa, SALEN(sa->sa), address, sizeof address, port, sizeof port, - hostnames ? 0 : (NI_NUMERICHOST | NI_NUMERICSERV)); + err = getnameinfo(&sa->sa, SALEN(sa->sa), address, sizeof(address), port, sizeof(port), + hostnames ? 0 : (NI_NUMERICHOST | NI_NUMERICSERV)); + if(err) { logger(DEBUG_ALWAYS, LOG_ERR, "Error while looking up hostname: %s", err == EAI_SYSTEM ? strerror(errno) : gai_strerror(err)); } @@ -145,26 +158,27 @@ int sockaddrcmp_noport(const sockaddr_t *a, const sockaddr_t *b) { result = a->sa.sa_family - b->sa.sa_family; - if(result) + if(result) { return result; + } - switch (a->sa.sa_family) { - case AF_UNSPEC: - return 0; + switch(a->sa.sa_family) { + case AF_UNSPEC: + return 0; - case AF_UNKNOWN: - return strcmp(a->unknown.address, b->unknown.address); + case AF_UNKNOWN: + return strcmp(a->unknown.address, b->unknown.address); - case AF_INET: - return memcmp(&a->in.sin_addr, &b->in.sin_addr, sizeof(a->in.sin_addr)); + case AF_INET: + return memcmp(&a->in.sin_addr, &b->in.sin_addr, sizeof(a->in.sin_addr)); - case AF_INET6: - return memcmp(&a->in6.sin6_addr, &b->in6.sin6_addr, sizeof(a->in6.sin6_addr)); + case AF_INET6: + return memcmp(&a->in6.sin6_addr, &b->in6.sin6_addr, sizeof(a->in6.sin6_addr)); - default: - logger(DEBUG_ALWAYS, LOG_ERR, "sockaddrcmp() was called with unknown address family %d, exitting!", - a->sa.sa_family); - abort(); + default: + logger(DEBUG_ALWAYS, LOG_ERR, "sockaddrcmp() was called with unknown address family %d, exitting!", + a->sa.sa_family); + abort(); } } @@ -173,41 +187,45 @@ int sockaddrcmp(const sockaddr_t *a, const sockaddr_t *b) { result = a->sa.sa_family - b->sa.sa_family; - if(result) + if(result) { return result; + } - switch (a->sa.sa_family) { - case AF_UNSPEC: - return 0; + switch(a->sa.sa_family) { + case AF_UNSPEC: + return 0; - case AF_UNKNOWN: - result = strcmp(a->unknown.address, b->unknown.address); + case AF_UNKNOWN: + result = strcmp(a->unknown.address, b->unknown.address); - if(result) - return result; + if(result) { + return result; + } - return strcmp(a->unknown.port, b->unknown.port); + return strcmp(a->unknown.port, b->unknown.port); - case AF_INET: - result = memcmp(&a->in.sin_addr, &b->in.sin_addr, sizeof a->in.sin_addr); + case AF_INET: + result = memcmp(&a->in.sin_addr, &b->in.sin_addr, sizeof(a->in.sin_addr)); - if(result) - return result; + if(result) { + return result; + } - return memcmp(&a->in.sin_port, &b->in.sin_port, sizeof a->in.sin_port); + return memcmp(&a->in.sin_port, &b->in.sin_port, sizeof(a->in.sin_port)); - case AF_INET6: - result = memcmp(&a->in6.sin6_addr, &b->in6.sin6_addr, sizeof a->in6.sin6_addr); + case AF_INET6: + result = memcmp(&a->in6.sin6_addr, &b->in6.sin6_addr, sizeof(a->in6.sin6_addr)); - if(result) - return result; + if(result) { + return result; + } - return memcmp(&a->in6.sin6_port, &b->in6.sin6_port, sizeof a->in6.sin6_port); + return memcmp(&a->in6.sin6_port, &b->in6.sin6_port, sizeof(a->in6.sin6_port)); - default: - logger(DEBUG_ALWAYS, LOG_ERR, "sockaddrcmp() was called with unknown address family %d, exitting!", - a->sa.sa_family); - abort(); + default: + logger(DEBUG_ALWAYS, LOG_ERR, "sockaddrcmp() was called with unknown address family %d, exitting!", + a->sa.sa_family); + abort(); } } @@ -237,19 +255,25 @@ void sockaddrunmap(sockaddr_t *sa) { void sockaddr_setport(sockaddr_t *sa, const char *port) { uint16_t portnum = htons(atoi(port)); - if(!portnum) + + if(!portnum) { return; + } + switch(sa->sa.sa_family) { - case AF_INET: - sa->in.sin_port = portnum; - break; - case AF_INET6: - sa->in6.sin6_port = portnum; - break; - case AF_UNKNOWN: - free(sa->unknown.port); - sa->unknown.port = xstrdup(port); - default: - return; + case AF_INET: + sa->in.sin_port = portnum; + break; + + case AF_INET6: + sa->in6.sin6_port = portnum; + break; + + case AF_UNKNOWN: + free(sa->unknown.port); + sa->unknown.port = xstrdup(port); + + default: + return; } } diff --git a/src/netutl.h b/src/netutl.h index 2e2f293..4aa1542 100644 --- a/src/netutl.h +++ b/src/netutl.h @@ -1,3 +1,6 @@ +#ifndef TINC_NETUTL_H +#define TINC_NETUTL_H + /* netutl.h -- header file for netutl.c Copyright (C) 1998-2005 Ivo Timmermans @@ -18,22 +21,19 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#ifndef __TINC_NETUTL_H__ -#define __TINC_NETUTL_H__ - #include "net.h" extern bool hostnames; -extern struct addrinfo *str2addrinfo(const char *, const char *, int) __attribute__ ((__malloc__)); -extern sockaddr_t str2sockaddr(const char *, const char *); -extern void sockaddr2str(const sockaddr_t *, char **, char **); -extern char *sockaddr2hostname(const sockaddr_t *) __attribute__ ((__malloc__)); -extern int sockaddrcmp(const sockaddr_t *, const sockaddr_t *); -extern int sockaddrcmp_noport(const sockaddr_t *, const sockaddr_t *); -extern void sockaddrunmap(sockaddr_t *); -extern void sockaddrfree(sockaddr_t *); -extern void sockaddrcpy(sockaddr_t *, const sockaddr_t *); -extern void sockaddr_setport(sockaddr_t *, const char *); +extern struct addrinfo *str2addrinfo(const char *address, const char *service, int socktype) __attribute__((__malloc__)); +extern sockaddr_t str2sockaddr(const char *address, const char *port); +extern void sockaddr2str(const sockaddr_t *sa, char **address, char **port); +extern char *sockaddr2hostname(const sockaddr_t *sa) __attribute__((__malloc__)); +extern int sockaddrcmp(const sockaddr_t *a, const sockaddr_t *b); +extern int sockaddrcmp_noport(const sockaddr_t *a, const sockaddr_t *b); +extern void sockaddrunmap(sockaddr_t *sa); +extern void sockaddrfree(sockaddr_t *sa); +extern void sockaddrcpy(sockaddr_t *dest, const sockaddr_t *src); +extern void sockaddr_setport(sockaddr_t *sa, const char *port); -#endif /* __TINC_NETUTL_H__ */ +#endif diff --git a/src/node.c b/src/node.c index b17e692..8f4b6ee 100644 --- a/src/node.c +++ b/src/node.c @@ -20,6 +20,7 @@ #include "system.h" +#include "address_cache.h" #include "control_common.h" #include "hash.h" #include "logger.h" @@ -48,8 +49,11 @@ static int node_id_compare(const node_t *a, const node_t *b) { static int node_udp_compare(const node_t *a, const node_t *b) { int result = sockaddrcmp(&a->address, &b->address); - if (result) + + if(result) { return result; + } + return (a->name && b->name) ? strcmp(a->name, b->name) : 0; } @@ -66,23 +70,29 @@ void exit_nodes(void) { } node_t *new_node(void) { - node_t *n = xzalloc(sizeof *n); + node_t *n = xzalloc(sizeof(*n)); + + if(replaywin) { + n->late = xzalloc(replaywin); + } - if(replaywin) n->late = xzalloc(replaywin); n->subnet_tree = new_subnet_tree(); n->edge_tree = new_edge_tree(); n->mtu = MTU; n->maxmtu = MTU; + n->udp_ping_rtt = -1; return n; } void free_node(node_t *n) { - if(n->subnet_tree) + if(n->subnet_tree) { free_subnet_tree(n->subnet_tree); + } - if(n->edge_tree) + if(n->edge_tree) { free_edge_tree(n->edge_tree); + } sockaddrfree(&n->address); @@ -98,22 +108,21 @@ void free_node(node_t *n) { timeout_del(&n->udp_ping_timeout); - if(n->hostname) - free(n->hostname); + free(n->hostname); + free(n->name); + free(n->late); - if(n->name) - free(n->name); - - if(n->late) - free(n->late); + if(n->address_cache) { + close_address_cache(n->address_cache); + } free(n); } void node_add(node_t *n) { unsigned char buf[64]; - sha512(n->name, strlen(n->name),buf); - memcpy(&n->id, buf, sizeof n->id); + sha512(n->name, strlen(n->name), buf); + memcpy(&n->id, buf, sizeof(n->id)); splay_insert(node_tree, n); splay_insert(node_id_tree, n); @@ -122,18 +131,20 @@ void node_add(node_t *n) { void node_del(node_t *n) { splay_delete(node_udp_tree, n); - for splay_each(subnet_t, s, n->subnet_tree) + for splay_each(subnet_t, s, n->subnet_tree) { subnet_del(n, s); + } - for splay_each(edge_t, e, n->edge_tree) + for splay_each(edge_t, e, n->edge_tree) { edge_del(e); + } splay_delete(node_id_tree, n); splay_delete(node_tree, n); } node_t *lookup_node(char *name) { - node_t n = {NULL}; + node_t n = {0}; n.name = name; @@ -161,12 +172,14 @@ void update_node_udp(node_t *n, const sockaddr_t *sa) { if(sa) { n->address = *sa; n->sock = 0; + for(int i = 0; i < listen_sockets; i++) { if(listen_socket[i].sa.sa.sa_family == sa->sa.sa_family) { n->sock = i; break; } } + splay_insert(node_udp_tree, n); free(n->hostname); n->hostname = sockaddr2hostname(&n->address); @@ -184,20 +197,24 @@ void update_node_udp(node_t *n, const sockaddr_t *sa) { bool dump_nodes(connection_t *c) { for splay_each(node_t, n, node_tree) { - char id[2 * sizeof n->id + 1]; - for (size_t c = 0; c < sizeof n->id; ++c) + char id[2 * sizeof(n->id) + 1]; + + for(size_t c = 0; c < sizeof(n->id); ++c) { snprintf(id + 2 * c, 3, "%02x", n->id.x[c]); - id[sizeof id - 1] = 0; - send_request(c, "%d %d %s %s %s %d %d %d %d %x %x %s %s %d %d %d %d %ld", CONTROL, REQ_DUMP_NODES, - n->name, id, n->hostname ?: "unknown port unknown", + } + + id[sizeof(id) - 1] = 0; + send_request(c, "%d %d %s %s %s %d %d %d %d %x %x %s %s %d %d %d %d %ld %d %"PRIu64" %"PRIu64" %"PRIu64" %"PRIu64, CONTROL, REQ_DUMP_NODES, + n->name, id, n->hostname ? n->hostname : "unknown port unknown", #ifdef DISABLE_LEGACY - 0, 0, 0, + 0, 0, 0, #else - cipher_get_nid(n->outcipher), digest_get_nid(n->outdigest), (int)digest_length(n->outdigest), + cipher_get_nid(n->outcipher), digest_get_nid(n->outdigest), (int)digest_length(n->outdigest), #endif - n->outcompression, n->options, bitfield_to_int(&n->status, sizeof n->status), - n->nexthop ? n->nexthop->name : "-", n->via ? n->via->name ?: "-" : "-", n->distance, - n->mtu, n->minmtu, n->maxmtu, (long)n->last_state_change); + n->outcompression, n->options, bitfield_to_int(&n->status, sizeof(n->status)), + n->nexthop ? n->nexthop->name : "-", n->via && n->via->name ? n->via->name : "-", n->distance, + n->mtu, n->minmtu, n->maxmtu, (long)n->last_state_change, n->udp_ping_rtt, + n->in_packets, n->in_bytes, n->out_packets, n->out_bytes); } return send_request(c, "%d %d", CONTROL, REQ_DUMP_NODES); @@ -206,7 +223,7 @@ bool dump_nodes(connection_t *c) { bool dump_traffic(connection_t *c) { for splay_each(node_t, n, node_tree) send_request(c, "%d %d %s %"PRIu64" %"PRIu64" %"PRIu64" %"PRIu64, CONTROL, REQ_DUMP_TRAFFIC, - n->name, n->in_packets, n->in_bytes, n->out_packets, n->out_bytes); + n->name, n->in_packets, n->in_bytes, n->out_packets, n->out_bytes); return send_request(c, "%d %d", CONTROL, REQ_DUMP_TRAFFIC); } diff --git a/src/node.h b/src/node.h index b48fe88..3daffd4 100644 --- a/src/node.h +++ b/src/node.h @@ -1,3 +1,6 @@ +#ifndef TINC_NODE_H +#define TINC_NODE_H + /* node.h -- header for node.c Copyright (C) 2001-2013 Guus Sliepen , @@ -18,9 +21,6 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#ifndef __TINC_NODE_H__ -#define __TINC_NODE_H__ - #include "splay_tree.h" #include "cipher.h" #include "connection.h" @@ -29,19 +29,19 @@ #include "subnet.h" typedef struct node_status_t { - unsigned int unused_active:1; /* 1 if active (not used for nodes) */ - unsigned int validkey:1; /* 1 if we currently have a valid key for him */ - unsigned int waitingforkey:1; /* 1 if we already sent out a request */ - unsigned int visited:1; /* 1 if this node has been visited by one of the graph algorithms */ - unsigned int reachable:1; /* 1 if this node is reachable in the graph */ - unsigned int indirect:1; /* 1 if this node is not directly reachable by us */ - unsigned int sptps:1; /* 1 if this node supports SPTPS */ - unsigned int udp_confirmed:1; /* 1 if the address is one that we received UDP traffic on */ - unsigned int send_locally:1; /* 1 if the next UDP packet should be sent on the local network */ - unsigned int udppacket:1; /* 1 if the most recently received packet was UDP */ - unsigned int validkey_in:1; /* 1 if we have sent a valid key to him */ - unsigned int has_address:1; /* 1 if we know an external address for this node */ - unsigned int unused:20; + unsigned int unused_active: 1; /* 1 if active (not used for nodes) */ + unsigned int validkey: 1; /* 1 if we currently have a valid key for him */ + unsigned int waitingforkey: 1; /* 1 if we already sent out a request */ + unsigned int visited: 1; /* 1 if this node has been visited by one of the graph algorithms */ + unsigned int reachable: 1; /* 1 if this node is reachable in the graph */ + unsigned int indirect: 1; /* 1 if this node is not directly reachable by us */ + unsigned int sptps: 1; /* 1 if this node supports SPTPS */ + unsigned int udp_confirmed: 1; /* 1 if the address is one that we received UDP traffic on */ + unsigned int send_locally: 1; /* 1 if the next UDP packet should be sent on the local network */ + unsigned int udppacket: 1; /* 1 if the most recently received packet was UDP */ + unsigned int validkey_in: 1; /* 1 if we have sent a valid key to him */ + unsigned int has_address: 1; /* 1 if we know an external address for this node */ + unsigned int unused: 20; } node_status_t; typedef struct node_t { @@ -88,10 +88,11 @@ typedef struct node_t { uint32_t prev_received_seqno; uint32_t prev_received; uint32_t farfuture; /* Packets in a row that have arrived from the far future */ - unsigned char* late; /* Bitfield marking late packets */ + unsigned char *late; /* Bitfield marking late packets */ struct timeval udp_reply_sent; /* Last time a (gratuitous) UDP probe reply was sent */ struct timeval udp_ping_sent; /* Last time a UDP probe was sent */ + int udp_ping_rtt; /* Round trip time of UDP ping (in microseconds; or -1 if !status.udp_confirmed) */ timeout_t udp_ping_timeout; /* Ping timeout event */ struct timeval mtu_ping_sent; /* Last time a MTU probe was sent */ @@ -99,7 +100,7 @@ typedef struct node_t { struct timeval mtu_info_sent; /* Last time a MTU_INFO message was sent */ struct timeval udp_info_sent; /* Last time a UDP_INFO message was sent */ - length_t maxrecentlen; /* Maximum size of recently received packets */ + length_t maxrecentlen; /* Maximum size of recently received packets */ length_t mtu; /* Maximum size of packets to send to this node */ length_t minmtu; /* Probed minimum MTU */ @@ -110,6 +111,8 @@ typedef struct node_t { uint64_t in_bytes; uint64_t out_packets; uint64_t out_bytes; + + struct address_cache_t *address_cache; } node_t; extern struct node_t *myself; @@ -117,15 +120,15 @@ extern splay_tree_t *node_tree; extern void init_nodes(void); extern void exit_nodes(void); -extern node_t *new_node(void) __attribute__ ((__malloc__)); -extern void free_node(node_t *); -extern void node_add(node_t *); -extern void node_del(node_t *); -extern node_t *lookup_node(char *); -extern node_t *lookup_node_id(const node_id_t *); -extern node_t *lookup_node_udp(const sockaddr_t *); -extern bool dump_nodes(struct connection_t *); -extern bool dump_traffic(struct connection_t *); -extern void update_node_udp(node_t *, const sockaddr_t *); +extern node_t *new_node(void) __attribute__((__malloc__)); +extern void free_node(node_t *n); +extern void node_add(node_t *n); +extern void node_del(node_t *n); +extern node_t *lookup_node(char *name); +extern node_t *lookup_node_id(const node_id_t *id); +extern node_t *lookup_node_udp(const sockaddr_t *sa); +extern bool dump_nodes(struct connection_t *c); +extern bool dump_traffic(struct connection_t *c); +extern void update_node_udp(node_t *n, const sockaddr_t *sa); -#endif /* __TINC_NODE_H__ */ +#endif diff --git a/src/nolegacy/crypto.c b/src/nolegacy/crypto.c index f1113b4..44692fd 100644 --- a/src/nolegacy/crypto.c +++ b/src/nolegacy/crypto.c @@ -27,8 +27,11 @@ static int random_fd = -1; static void random_init(void) { random_fd = open("/dev/urandom", O_RDONLY); - if(random_fd < 0) + + if(random_fd < 0) { random_fd = open("/dev/random", O_RDONLY); + } + if(random_fd < 0) { fprintf(stderr, "Could not open source of random numbers: %s\n", strerror(errno)); abort(); @@ -42,12 +45,16 @@ static void random_exit(void) { void randomize(void *out, size_t outlen) { while(outlen) { size_t len = read(random_fd, out, outlen); + if(len <= 0) { - if(errno == EAGAIN || errno == EINTR) + if(errno == EAGAIN || errno == EINTR) { continue; + } + fprintf(stderr, "Could not read random numbers: %s\n", strerror(errno)); abort(); } + out += len; outlen -= len; } diff --git a/src/nolegacy/prf.c b/src/nolegacy/prf.c index 55c9923..ce80f8c 100644 --- a/src/nolegacy/prf.c +++ b/src/nolegacy/prf.c @@ -23,8 +23,9 @@ #include "../ed25519/sha512.h" static void memxor(char *buf, char c, size_t len) { - for(size_t i = 0; i < len; i++) + for(size_t i = 0; i < len; i++) { buf[i] ^= c; + } } static const size_t mdlen = 64; @@ -38,30 +39,39 @@ static bool hmac_sha512(const char *key, size_t keylen, const char *msg, size_t memcpy(tmp, key, keylen); memset(tmp + keylen, 0, blklen - keylen); } else { - if(sha512(key, keylen, tmp) != 0) + if(sha512(key, keylen, tmp) != 0) { return false; + } + memset(tmp + mdlen, 0, blklen - mdlen); } - if(sha512_init(&md) != 0) + if(sha512_init(&md) != 0) { return false; + } // ipad memxor(tmp, 0x36, blklen); - if(sha512_update(&md, tmp, blklen) != 0) + + if(sha512_update(&md, tmp, blklen) != 0) { return false; + } // message - if(sha512_update(&md, msg, msglen) != 0) + if(sha512_update(&md, msg, msglen) != 0) { return false; + } - if(sha512_final(&md, tmp + blklen) != 0) + if(sha512_final(&md, tmp + blklen) != 0) { return false; + } // opad memxor(tmp, 0x36 ^ 0x5c, blklen); - if(sha512(tmp, sizeof tmp, out) != 0) + + if(sha512(tmp, sizeof(tmp), out) != 0) { return false; + } return true; } @@ -84,18 +94,23 @@ bool prf(const char *secret, size_t secretlen, char *seed, size_t seedlen, char while(outlen > 0) { /* Inner HMAC */ - if(!hmac_sha512(secret, secretlen, data, sizeof data, data)) + if(!hmac_sha512(secret, secretlen, data, sizeof(data), data)) { return false; + } /* Outer HMAC */ if(outlen >= mdlen) { - if(!hmac_sha512(secret, secretlen, data, sizeof data, out)) + if(!hmac_sha512(secret, secretlen, data, sizeof(data), out)) { return false; + } + out += mdlen; outlen -= mdlen; } else { - if(!hmac_sha512(secret, secretlen, data, sizeof data, hash)) + if(!hmac_sha512(secret, secretlen, data, sizeof(data), hash)) { return false; + } + memcpy(out, hash, outlen); out += outlen; outlen = 0; diff --git a/src/openssl/cipher.c b/src/openssl/cipher.c index 98033c5..d51ec0d 100644 --- a/src/openssl/cipher.c +++ b/src/openssl/cipher.c @@ -33,17 +33,20 @@ struct cipher { }; static cipher_t *cipher_open(const EVP_CIPHER *evp_cipher) { - cipher_t *cipher = xzalloc(sizeof *cipher); + cipher_t *cipher = xzalloc(sizeof(*cipher)); cipher->cipher = evp_cipher; cipher->ctx = EVP_CIPHER_CTX_new(); - if(!cipher->ctx) + + if(!cipher->ctx) { abort(); + } return cipher; } cipher_t *cipher_open_by_name(const char *name) { const EVP_CIPHER *evp_cipher = EVP_get_cipherbyname(name); + if(!evp_cipher) { logger(DEBUG_ALWAYS, LOG_ERR, "Unknown cipher name '%s'!", name); return NULL; @@ -54,6 +57,7 @@ cipher_t *cipher_open_by_name(const char *name) { cipher_t *cipher_open_by_nid(int nid) { const EVP_CIPHER *evp_cipher = EVP_get_cipherbynid(nid); + if(!evp_cipher) { logger(DEBUG_ALWAYS, LOG_ERR, "Unknown cipher nid %d!", nid); return NULL; @@ -63,16 +67,18 @@ cipher_t *cipher_open_by_nid(int nid) { } void cipher_close(cipher_t *cipher) { - if(!cipher) + if(!cipher) { return; + } EVP_CIPHER_CTX_free(cipher->ctx); free(cipher); } size_t cipher_keylength(const cipher_t *cipher) { - if(!cipher || !cipher->cipher) + if(!cipher || !cipher->cipher) { return 0; + } return EVP_CIPHER_key_length(cipher->cipher) + EVP_CIPHER_iv_length(cipher->cipher); } @@ -85,8 +91,9 @@ uint64_t cipher_budget(const cipher_t *cipher) { is limited to what can be represented with a 64 bits integer. */ - if(!cipher || !cipher->cipher) - return UINT64_MAX; // NULL cipher + if(!cipher || !cipher->cipher) { + return UINT64_MAX; // NULL cipher + } int ivlen = EVP_CIPHER_iv_length(cipher->cipher); int blklen = EVP_CIPHER_block_size(cipher->cipher); @@ -96,8 +103,9 @@ uint64_t cipher_budget(const cipher_t *cipher) { } size_t cipher_blocksize(const cipher_t *cipher) { - if(!cipher || !cipher->cipher) + if(!cipher || !cipher->cipher) { return 1; + } return EVP_CIPHER_block_size(cipher->cipher); } @@ -105,13 +113,15 @@ size_t cipher_blocksize(const cipher_t *cipher) { bool cipher_set_key(cipher_t *cipher, void *key, bool encrypt) { bool result; - if(encrypt) + if(encrypt) { result = EVP_EncryptInit_ex(cipher->ctx, cipher->cipher, NULL, (unsigned char *)key, (unsigned char *)key + EVP_CIPHER_key_length(cipher->cipher)); - else + } else { result = EVP_DecryptInit_ex(cipher->ctx, cipher->cipher, NULL, (unsigned char *)key, (unsigned char *)key + EVP_CIPHER_key_length(cipher->cipher)); + } - if(result) + if(result) { return true; + } logger(DEBUG_ALWAYS, LOG_ERR, "Error while setting key: %s", ERR_error_string(ERR_get_error(), NULL)); return false; @@ -120,13 +130,15 @@ bool cipher_set_key(cipher_t *cipher, void *key, bool encrypt) { bool cipher_set_key_from_rsa(cipher_t *cipher, void *key, size_t len, bool encrypt) { bool result; - if(encrypt) + if(encrypt) { result = EVP_EncryptInit_ex(cipher->ctx, cipher->cipher, NULL, (unsigned char *)key + len - EVP_CIPHER_key_length(cipher->cipher), (unsigned char *)key + len - EVP_CIPHER_iv_length(cipher->cipher) - EVP_CIPHER_key_length(cipher->cipher)); - else + } else { result = EVP_DecryptInit_ex(cipher->ctx, cipher->cipher, NULL, (unsigned char *)key + len - EVP_CIPHER_key_length(cipher->cipher), (unsigned char *)key + len - EVP_CIPHER_iv_length(cipher->cipher) - EVP_CIPHER_key_length(cipher->cipher)); + } - if(result) + if(result) { return true; + } logger(DEBUG_ALWAYS, LOG_ERR, "Error while setting key: %s", ERR_error_string(ERR_get_error(), NULL)); return false; @@ -135,16 +147,24 @@ bool cipher_set_key_from_rsa(cipher_t *cipher, void *key, size_t len, bool encry bool cipher_encrypt(cipher_t *cipher, const void *indata, size_t inlen, void *outdata, size_t *outlen, bool oneshot) { if(oneshot) { int len, pad; + if(EVP_EncryptInit_ex(cipher->ctx, NULL, NULL, NULL, NULL) - && EVP_EncryptUpdate(cipher->ctx, (unsigned char *)outdata, &len, indata, inlen) - && EVP_EncryptFinal_ex(cipher->ctx, (unsigned char *)outdata + len, &pad)) { - if(outlen) *outlen = len + pad; + && EVP_EncryptUpdate(cipher->ctx, (unsigned char *)outdata, &len, indata, inlen) + && EVP_EncryptFinal_ex(cipher->ctx, (unsigned char *)outdata + len, &pad)) { + if(outlen) { + *outlen = len + pad; + } + return true; } } else { int len; + if(EVP_EncryptUpdate(cipher->ctx, outdata, &len, indata, inlen)) { - if(outlen) *outlen = len; + if(outlen) { + *outlen = len; + } + return true; } } @@ -156,16 +176,24 @@ bool cipher_encrypt(cipher_t *cipher, const void *indata, size_t inlen, void *ou bool cipher_decrypt(cipher_t *cipher, const void *indata, size_t inlen, void *outdata, size_t *outlen, bool oneshot) { if(oneshot) { int len, pad; + if(EVP_DecryptInit_ex(cipher->ctx, NULL, NULL, NULL, NULL) - && EVP_DecryptUpdate(cipher->ctx, (unsigned char *)outdata, &len, indata, inlen) - && EVP_DecryptFinal_ex(cipher->ctx, (unsigned char *)outdata + len, &pad)) { - if(outlen) *outlen = len + pad; + && EVP_DecryptUpdate(cipher->ctx, (unsigned char *)outdata, &len, indata, inlen) + && EVP_DecryptFinal_ex(cipher->ctx, (unsigned char *)outdata + len, &pad)) { + if(outlen) { + *outlen = len + pad; + } + return true; } } else { int len; + if(EVP_EncryptUpdate(cipher->ctx, outdata, &len, indata, inlen)) { - if(outlen) *outlen = len; + if(outlen) { + *outlen = len; + } + return true; } } @@ -175,8 +203,9 @@ bool cipher_decrypt(cipher_t *cipher, const void *indata, size_t inlen, void *ou } int cipher_get_nid(const cipher_t *cipher) { - if(!cipher || !cipher->cipher) + if(!cipher || !cipher->cipher) { return 0; + } return EVP_CIPHER_nid(cipher->cipher); } diff --git a/src/openssl/crypto.c b/src/openssl/crypto.c index 5b866b0..e594e73 100644 --- a/src/openssl/crypto.c +++ b/src/openssl/crypto.c @@ -31,8 +31,11 @@ static int random_fd = -1; static void random_init(void) { random_fd = open("/dev/urandom", O_RDONLY); - if(random_fd < 0) + + if(random_fd < 0) { random_fd = open("/dev/random", O_RDONLY); + } + if(random_fd < 0) { fprintf(stderr, "Could not open source of random numbers: %s\n", strerror(errno)); abort(); @@ -43,15 +46,21 @@ static void random_exit(void) { close(random_fd); } -void randomize(void *out, size_t outlen) { +void randomize(void *vout, size_t outlen) { + char *out = vout; + while(outlen) { size_t len = read(random_fd, out, outlen); + if(len <= 0) { - if(errno == EAGAIN || errno == EINTR) + if(errno == EAGAIN || errno == EINTR) { continue; + } + fprintf(stderr, "Could not read random numbers: %s\n", strerror(errno)); abort(); } + out += len; outlen -= len; } diff --git a/src/openssl/digest.c b/src/openssl/digest.c index 58ca167..9569f3c 100644 --- a/src/openssl/digest.c +++ b/src/openssl/digest.c @@ -29,15 +29,16 @@ #include "../logger.h" static digest_t *digest_open(const EVP_MD *evp_md, int maclength) { - digest_t *digest = xzalloc(sizeof *digest); + digest_t *digest = xzalloc(sizeof(*digest)); digest->digest = evp_md; int digestlen = EVP_MD_size(digest->digest); - if(maclength > digestlen || maclength < 0) + if(maclength > digestlen || maclength < 0) { digest->maclength = digestlen; - else + } else { digest->maclength = maclength; + } return digest; } @@ -65,17 +66,40 @@ digest_t *digest_open_by_nid(int nid, int maclength) { } bool digest_set_key(digest_t *digest, const void *key, size_t len) { - digest->key = xrealloc(digest->key, len); - memcpy(digest->key, key, len); - digest->keylength = len; +#ifdef HAVE_HMAC_CTX_NEW + digest->hmac_ctx = HMAC_CTX_new(); + HMAC_Init_ex(digest->hmac_ctx, key, len, digest->digest, NULL); +#else + digest->hmac_ctx = xzalloc(sizeof(*digest->hmac_ctx)); + HMAC_Init(digest->hmac_ctx, key, len, digest->digest); +#endif + + if(!digest->hmac_ctx) { + abort(); + } + return true; } void digest_close(digest_t *digest) { - if(!digest) + if(!digest) { return; + } + + if(digest->md_ctx) { + EVP_MD_CTX_destroy(digest->md_ctx); + } + +#ifdef HAVE_HMAC_CTX_NEW + + if(digest->hmac_ctx) { + HMAC_CTX_free(digest->hmac_ctx); + } + +#else + free(digest->hmac_ctx); +#endif - free(digest->key); free(digest); } @@ -83,25 +107,28 @@ bool digest_create(digest_t *digest, const void *indata, size_t inlen, void *out size_t len = EVP_MD_size(digest->digest); unsigned char tmpdata[len]; - if(digest->key) { - if(!HMAC(digest->digest, digest->key, digest->keylength, indata, inlen, tmpdata, NULL)) { + if(digest->hmac_ctx) { + if(!HMAC_Init_ex(digest->hmac_ctx, NULL, 0, NULL, NULL) + || !HMAC_Update(digest->hmac_ctx, indata, inlen) + || !HMAC_Final(digest->hmac_ctx, tmpdata, NULL)) { logger(DEBUG_ALWAYS, LOG_DEBUG, "Error creating digest: %s", ERR_error_string(ERR_get_error(), NULL)); return false; } } else { - EVP_MD_CTX *ctx = EVP_MD_CTX_create(); - if(!ctx) - abort(); - - if(!EVP_DigestInit(ctx, digest->digest) - || !EVP_DigestUpdate(ctx, indata, inlen) - || !EVP_DigestFinal(ctx, tmpdata, NULL)) { - logger(DEBUG_ALWAYS, LOG_DEBUG, "Error creating digest: %s", ERR_error_string(ERR_get_error(), NULL)); - EVP_MD_CTX_destroy(ctx); - return false; + if(!digest->md_ctx) { + digest->md_ctx = EVP_MD_CTX_create(); } - EVP_MD_CTX_destroy(ctx); + if(!digest->md_ctx) { + abort(); + } + + if(!EVP_DigestInit(digest->md_ctx, digest->digest) + || !EVP_DigestUpdate(digest->md_ctx, indata, inlen) + || !EVP_DigestFinal(digest->md_ctx, tmpdata, NULL)) { + logger(DEBUG_ALWAYS, LOG_DEBUG, "Error creating digest: %s", ERR_error_string(ERR_get_error(), NULL)); + return false; + } } memcpy(outdata, tmpdata, digest->maclength); @@ -116,22 +143,25 @@ bool digest_verify(digest_t *digest, const void *indata, size_t inlen, const voi } int digest_get_nid(const digest_t *digest) { - if(!digest || !digest->digest) + if(!digest || !digest->digest) { return 0; + } return EVP_MD_type(digest->digest); } size_t digest_keylength(const digest_t *digest) { - if(!digest || !digest->digest) + if(!digest || !digest->digest) { return 0; + } return EVP_MD_size(digest->digest); } size_t digest_length(const digest_t *digest) { - if(!digest) + if(!digest) { return 0; + } return digest->maclength; } diff --git a/src/openssl/digest.h b/src/openssl/digest.h index 0a32707..420b11e 100644 --- a/src/openssl/digest.h +++ b/src/openssl/digest.h @@ -1,3 +1,6 @@ +#ifndef TINC_OPENSSL_DIGEST_H +#define TINC_OPENSSL_DIGEST_H + /* digest.h -- header file digest.c Copyright (C) 2013 Guus Sliepen @@ -17,16 +20,14 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#ifndef __TINC_OPENSSL_DIGEST_H__ -#define __TINC_OPENSSL_DIGEST_H__ - #include +#include struct digest { const EVP_MD *digest; + HMAC_CTX *hmac_ctx; + EVP_MD_CTX *md_ctx; int maclength; - int keylength; - char *key; }; #endif diff --git a/src/openssl/prf.c b/src/openssl/prf.c index 4f5a52b..37af2ef 100644 --- a/src/openssl/prf.c +++ b/src/openssl/prf.c @@ -29,11 +29,12 @@ We use SHA512 instead of MD5 and SHA1. */ -static bool prf_xor(int nid, const char *secret, size_t secretlen, char *seed, size_t seedlen, char *out, ssize_t outlen) { +static bool prf_xor(int nid, const char *secret, size_t secretlen, char *seed, size_t seedlen, char *out, size_t outlen) { digest_t *digest = digest_open_by_nid(nid, -1); - if(!digest) + if(!digest) { return false; + } if(!digest_set_key(digest, secret, secretlen)) { digest_close(digest); @@ -66,8 +67,9 @@ static bool prf_xor(int nid, const char *secret, size_t secretlen, char *seed, s } /* XOR the results of the outer HMAC into the out buffer */ - for(int i = 0; i < len && i < outlen; i++) + for(size_t i = 0; i < len && i < outlen; i++) { *out++ ^= hash[i]; + } outlen -= len; } diff --git a/src/openssl/rsa.c b/src/openssl/rsa.c index 3033bcd..0e81172 100644 --- a/src/openssl/rsa.c +++ b/src/openssl/rsa.c @@ -22,7 +22,7 @@ #include #include -#define __TINC_RSA_INTERNAL__ +#define TINC_RSA_INTERNAL typedef RSA rsa_t; #include "../logger.h" @@ -32,9 +32,12 @@ typedef RSA rsa_t; #ifndef HAVE_RSA_SET0_KEY int RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d) { - BN_free(r->n); r->n = n; - BN_free(r->e); r->e = e; - BN_free(r->d); r->d = d; + BN_free(r->n); + r->n = n; + BN_free(r->e); + r->e = e; + BN_free(r->d); + r->d = d; return 1; } #endif @@ -43,16 +46,18 @@ rsa_t *rsa_set_hex_public_key(char *n, char *e) { BIGNUM *bn_n = NULL; BIGNUM *bn_e = NULL; - if(BN_hex2bn(&bn_n, n) != strlen(n) || BN_hex2bn(&bn_e, e) != strlen(e)) { + if((size_t)BN_hex2bn(&bn_n, n) != strlen(n) || (size_t)BN_hex2bn(&bn_e, e) != strlen(e)) { BN_free(bn_e); BN_free(bn_n); return false; } rsa_t *rsa = RSA_new(); - if(!rsa) + + if(!rsa) { return NULL; - + } + RSA_set0_key(rsa, bn_n, bn_e, NULL); return rsa; @@ -63,7 +68,7 @@ rsa_t *rsa_set_hex_private_key(char *n, char *e, char *d) { BIGNUM *bn_e = NULL; BIGNUM *bn_d = NULL; - if(BN_hex2bn(&bn_n, n) != strlen(n) || BN_hex2bn(&bn_e, e) != strlen(e) || BN_hex2bn(&bn_d, d) != strlen(d)) { + if((size_t)BN_hex2bn(&bn_n, n) != strlen(n) || (size_t)BN_hex2bn(&bn_e, e) != strlen(e) || (size_t)BN_hex2bn(&bn_d, d) != strlen(d)) { BN_free(bn_d); BN_free(bn_e); BN_free(bn_n); @@ -71,8 +76,10 @@ rsa_t *rsa_set_hex_private_key(char *n, char *e, char *d) { } rsa_t *rsa = RSA_new(); - if(!rsa) + + if(!rsa) { return NULL; + } RSA_set0_key(rsa, bn_n, bn_e, bn_d); @@ -89,8 +96,9 @@ rsa_t *rsa_read_pem_public_key(FILE *fp) { rsa = PEM_read_RSA_PUBKEY(fp, NULL, NULL, NULL); } - if(!rsa) + if(!rsa) { logger(DEBUG_ALWAYS, LOG_ERR, "Unable to read RSA public key: %s", ERR_error_string(ERR_get_error(), NULL)); + } return rsa; } @@ -98,8 +106,9 @@ rsa_t *rsa_read_pem_public_key(FILE *fp) { rsa_t *rsa_read_pem_private_key(FILE *fp) { rsa_t *rsa = PEM_read_RSAPrivateKey(fp, NULL, NULL, NULL); - if(!rsa) + if(!rsa) { logger(DEBUG_ALWAYS, LOG_ERR, "Unable to read RSA private key: %s", ERR_error_string(ERR_get_error(), NULL)); + } return rsa; } @@ -109,16 +118,18 @@ size_t rsa_size(rsa_t *rsa) { } bool rsa_public_encrypt(rsa_t *rsa, void *in, size_t len, void *out) { - if(RSA_public_encrypt(len, in, out, rsa, RSA_NO_PADDING) == len) + if((size_t)RSA_public_encrypt(len, in, out, rsa, RSA_NO_PADDING) == len) { return true; + } logger(DEBUG_ALWAYS, LOG_ERR, "Unable to perform RSA encryption: %s", ERR_error_string(ERR_get_error(), NULL)); return false; } bool rsa_private_decrypt(rsa_t *rsa, void *in, size_t len, void *out) { - if(RSA_private_decrypt(len, in, out, rsa, RSA_NO_PADDING) == len) + if((size_t)RSA_private_decrypt(len, in, out, rsa, RSA_NO_PADDING) == len) { return true; + } logger(DEBUG_ALWAYS, LOG_ERR, "Unable to perform RSA decryption: %s", ERR_error_string(ERR_get_error(), NULL)); return false; @@ -129,6 +140,7 @@ bool rsa_active(rsa_t *rsa) { } void rsa_free(rsa_t *rsa) { - if(rsa) + if(rsa) { RSA_free(rsa); + } } diff --git a/src/openssl/rsagen.c b/src/openssl/rsagen.c index b7eb629..79127f6 100644 --- a/src/openssl/rsagen.c +++ b/src/openssl/rsagen.c @@ -22,7 +22,7 @@ #include #include -#define __TINC_RSA_INTERNAL__ +#define TINC_RSA_INTERNAL typedef RSA rsa_t; #include "../logger.h" @@ -32,36 +32,39 @@ typedef RSA rsa_t; /* This function prettyprints the key generation process */ static int indicator(int a, int b, BN_GENCB *cb) { - switch (a) { + (void)cb; + + switch(a) { + case 0: + fprintf(stderr, "."); + break; + + case 1: + fprintf(stderr, "+"); + break; + + case 2: + fprintf(stderr, "-"); + break; + + case 3: + switch(b) { case 0: - fprintf(stderr, "."); + fprintf(stderr, " p\n"); break; case 1: - fprintf(stderr, "+"); - break; - - case 2: - fprintf(stderr, "-"); - break; - - case 3: - switch (b) { - case 0: - fprintf(stderr, " p\n"); - break; - - case 1: - fprintf(stderr, " q\n"); - break; - - default: - fprintf(stderr, "?"); - } + fprintf(stderr, " q\n"); break; default: fprintf(stderr, "?"); + } + + break; + + default: + fprintf(stderr, "?"); } return 1; @@ -84,8 +87,9 @@ rsa_t *rsa_generate(size_t bits, unsigned long exponent) { rsa_t *rsa = RSA_new(); BN_GENCB *cb = BN_GENCB_new(); - if(!bn_e || !rsa || !cb) + if(!bn_e || !rsa || !cb) { abort(); + } BN_set_word(bn_e, exponent); BN_GENCB_set(cb, indicator, NULL); diff --git a/src/prf.h b/src/prf.h index ef4b99b..9e64989 100644 --- a/src/prf.h +++ b/src/prf.h @@ -1,3 +1,6 @@ +#ifndef TINC_PRF_H +#define TINC_PRF_H + /* prf.h -- header file for prf.c Copyright (C) 2011-2013 Guus Sliepen @@ -17,9 +20,6 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#ifndef __TINC_PRF_H__ -#define __TINC_PRF_H__ - -extern bool prf(const char *secret, size_t secretlen, char *seed, size_t seedlen, char *out, size_t outlen) __attribute__ ((__warn_unused_result__)); +extern bool prf(const char *secret, size_t secretlen, char *seed, size_t seedlen, char *out, size_t outlen) __attribute__((__warn_unused_result__)); #endif diff --git a/src/process.c b/src/process.c index 5bb7eb3..c6cb536 100644 --- a/src/process.c +++ b/src/process.c @@ -57,39 +57,44 @@ static bool install_service(void) { SERVICE_DESCRIPTION description = {"Virtual Private Network daemon"}; manager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); + if(!manager) { logger(DEBUG_ALWAYS, LOG_ERR, "Could not open service manager: %s", winerror(GetLastError())); return false; } HMODULE module = GetModuleHandle(NULL); - GetModuleFileName(module, command + 1, sizeof command - 1); - command[sizeof command - 1] = 0; + GetModuleFileName(module, command + 1, sizeof(command) - 1); + command[sizeof(command) - 1] = 0; - strncat(command, "\"", sizeof command - strlen(command)); + strncat(command, "\"", sizeof(command) - strlen(command)); for(char **argp = g_argv + 1; *argp; argp++) { char *space = strchr(*argp, ' '); - strncat(command, " ", sizeof command - strlen(command)); + strncat(command, " ", sizeof(command) - strlen(command)); - if(space) - strncat(command, "\"", sizeof command - strlen(command)); + if(space) { + strncat(command, "\"", sizeof(command) - strlen(command)); + } - strncat(command, *argp, sizeof command - strlen(command)); + strncat(command, *argp, sizeof(command) - strlen(command)); - if(space) - strncat(command, "\"", sizeof command - strlen(command)); + if(space) { + strncat(command, "\"", sizeof(command) - strlen(command)); + } } service = CreateService(manager, identname, identname, - SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START, SERVICE_ERROR_NORMAL, - command, NULL, NULL, NULL, NULL, NULL); + SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START, SERVICE_ERROR_NORMAL, + command, NULL, NULL, NULL, NULL, NULL); if(!service) { DWORD lasterror = GetLastError(); logger(DEBUG_ALWAYS, LOG_ERR, "Could not create %s service: %s", identname, winerror(lasterror)); - if(lasterror != ERROR_SERVICE_EXISTS) + + if(lasterror != ERROR_SERVICE_EXISTS) { return false; + } } if(service) { @@ -99,10 +104,11 @@ static bool install_service(void) { service = OpenService(manager, identname, SERVICE_ALL_ACCESS); } - if(!StartService(service, 0, NULL)) + if(!StartService(service, 0, NULL)) { logger(DEBUG_ALWAYS, LOG_WARNING, "Could not start %s service: %s", identname, winerror(GetLastError())); - else + } else { logger(DEBUG_ALWAYS, LOG_INFO, "%s service started", identname); + } return true; } @@ -111,29 +117,35 @@ io_t stop_io; DWORD WINAPI controlhandler(DWORD request, DWORD type, LPVOID boe, LPVOID bah) { switch(request) { - case SERVICE_CONTROL_INTERROGATE: - SetServiceStatus(statushandle, &status); - return NO_ERROR; - case SERVICE_CONTROL_STOP: - logger(DEBUG_ALWAYS, LOG_NOTICE, "Got %s request", "SERVICE_CONTROL_STOP"); - break; - case SERVICE_CONTROL_SHUTDOWN: - logger(DEBUG_ALWAYS, LOG_NOTICE, "Got %s request", "SERVICE_CONTROL_SHUTDOWN"); - break; - default: - logger(DEBUG_ALWAYS, LOG_WARNING, "Got unexpected request %d", (int)request); - return ERROR_CALL_NOT_IMPLEMENTED; + case SERVICE_CONTROL_INTERROGATE: + SetServiceStatus(statushandle, &status); + return NO_ERROR; + + case SERVICE_CONTROL_STOP: + logger(DEBUG_ALWAYS, LOG_NOTICE, "Got %s request", "SERVICE_CONTROL_STOP"); + break; + + case SERVICE_CONTROL_SHUTDOWN: + logger(DEBUG_ALWAYS, LOG_NOTICE, "Got %s request", "SERVICE_CONTROL_SHUTDOWN"); + break; + + default: + logger(DEBUG_ALWAYS, LOG_WARNING, "Got unexpected request %d", (int)request); + return ERROR_CALL_NOT_IMPLEMENTED; } status.dwWaitHint = 1000; status.dwCurrentState = SERVICE_STOP_PENDING; SetServiceStatus(statushandle, &status); - if (WSASetEvent(stop_io.event) == FALSE) + + if(WSASetEvent(stop_io.event) == FALSE) { abort(); + } + return NO_ERROR; } -VOID WINAPI run_service(DWORD argc, LPTSTR* argv) { +VOID WINAPI run_service(DWORD argc, LPTSTR *argv) { extern int main2(int argc, char **argv); status.dwServiceType = SERVICE_WIN32; @@ -144,7 +156,7 @@ VOID WINAPI run_service(DWORD argc, LPTSTR* argv) { statushandle = RegisterServiceCtrlHandlerEx(identname, controlhandler, NULL); - if (!statushandle) { + if(!statushandle) { logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "RegisterServiceCtrlHandlerEx", winerror(GetLastError())); } else { status.dwWaitHint = 30000; @@ -174,9 +186,9 @@ bool init_service(void) { if(!StartServiceCtrlDispatcher(services)) { if(GetLastError() == ERROR_FAILED_SERVICE_CONTROLLER_CONNECT) { return false; - } - else + } else { logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "StartServiceCtrlDispatcher", winerror(GetLastError())); + } } return true; @@ -200,27 +212,33 @@ bool detach(void) { if(do_detach) { #ifndef HAVE_MINGW + if(daemon(1, 0)) { logger(DEBUG_ALWAYS, LOG_ERR, "Couldn't detach from terminal: %s", strerror(errno)); return false; } + #else - if(!statushandle) + + if(!statushandle) { exit(!install_service()); + } + #endif } - if(use_logfile) + if(use_logfile) { logmode = LOGMODE_FILE; - else if(use_syslog || do_detach) + } else if(use_syslog || do_detach) { logmode = LOGMODE_SYSLOG; - else + } else { logmode = LOGMODE_STDERR; + } openlogger(identname, logmode); logger(DEBUG_ALWAYS, LOG_NOTICE, "tincd %s (%s %s) starting, debug level %d", - BUILD_VERSION, BUILD_DATE, BUILD_TIME, debug_level); + BUILD_VERSION, BUILD_DATE, BUILD_TIME, debug_level); return true; } diff --git a/src/process.h b/src/process.h index ce2daed..93ef5e9 100644 --- a/src/process.h +++ b/src/process.h @@ -1,3 +1,6 @@ +#ifndef TINC_PROCESS_H +#define TINC_PROCESS_H + /* process.h -- header file for process.c Copyright (C) 1999-2005 Ivo Timmermans, @@ -18,9 +21,6 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#ifndef __TINC_PROCESS_H__ -#define __TINC_PROCESS_H__ - extern bool do_detach; extern bool sigalrm; @@ -33,4 +33,4 @@ extern io_t stop_io; extern bool init_service(void); #endif -#endif /* __TINC_PROCESS_H__ */ +#endif diff --git a/src/protocol.c b/src/protocol.c index b9abccc..d8b8867 100644 --- a/src/protocol.c +++ b/src/protocol.c @@ -35,26 +35,26 @@ bool experimental = true; /* Jumptable for the request handlers */ static bool (*request_handlers[])(connection_t *, const char *) = { - id_h, metakey_h, challenge_h, chal_reply_h, ack_h, - status_h, error_h, termreq_h, - ping_h, pong_h, - add_subnet_h, del_subnet_h, - add_edge_h, del_edge_h, - key_changed_h, req_key_h, ans_key_h, tcppacket_h, control_h, - NULL, NULL, /* Not "real" requests (yet) */ - sptps_tcppacket_h, - udp_info_h, mtu_info_h, + id_h, metakey_h, challenge_h, chal_reply_h, ack_h, + NULL, NULL, termreq_h, + ping_h, pong_h, + add_subnet_h, del_subnet_h, + add_edge_h, del_edge_h, + key_changed_h, req_key_h, ans_key_h, tcppacket_h, control_h, + NULL, NULL, /* Not "real" requests (yet) */ + sptps_tcppacket_h, + udp_info_h, mtu_info_h, }; /* Request names */ static char (*request_name[]) = { - "ID", "METAKEY", "CHALLENGE", "CHAL_REPLY", "ACK", - "STATUS", "ERROR", "TERMREQ", - "PING", "PONG", - "ADD_SUBNET", "DEL_SUBNET", - "ADD_EDGE", "DEL_EDGE", "KEY_CHANGED", "REQ_KEY", "ANS_KEY", "PACKET", "CONTROL", - "REQ_PUBKEY", "ANS_PUBKEY", "SPTPS_PACKET", "UDP_INFO", "MTU_INFO", + "ID", "METAKEY", "CHALLENGE", "CHAL_REPLY", "ACK", + "STATUS", "ERROR", "TERMREQ", + "PING", "PONG", + "ADD_SUBNET", "DEL_SUBNET", + "ADD_EDGE", "DEL_EDGE", "KEY_CHANGED", "REQ_KEY", "ANS_KEY", "PACKET", "CONTROL", + "REQ_PUBKEY", "ANS_PUBKEY", "SPTPS_PACKET", "UDP_INFO", "MTU_INFO", }; static splay_tree_t *past_request_tree; @@ -72,25 +72,32 @@ bool send_request(connection_t *c, const char *format, ...) { input buffer anyway */ va_start(args, format); - len = vsnprintf(request, sizeof request, format, args); - request[sizeof request - 1] = 0; + len = vsnprintf(request, sizeof(request), format, args); + request[sizeof(request) - 1] = 0; va_end(args); - if(len < 0 || len > sizeof request - 1) { + if(len < 0 || (size_t)len > sizeof(request) - 1) { logger(DEBUG_ALWAYS, LOG_ERR, "Output buffer overflow while sending request to %s (%s)", - c->name, c->hostname); + c->name, c->hostname); return false; } - logger(DEBUG_META, LOG_DEBUG, "Sending %s to %s (%s): %s", request_name[atoi(request)], c->name, c->hostname, request); + int id = atoi(request); + logger(DEBUG_META, LOG_DEBUG, "Sending %s to %s (%s): %s", request_name[id], c->name, c->hostname, request); request[len++] = '\n'; if(c == everyone) { broadcast_meta(NULL, request, len); return true; - } else - return send_meta(c, request, len); + } else { + if(id) { + return send_meta(c, request, len); + } else { + send_meta_raw(c, request, len); + return true; + } + } } void forward_request(connection_t *from, const char *request) { @@ -101,13 +108,15 @@ void forward_request(connection_t *from, const char *request) { char tmp[len + 1]; memcpy(tmp, request, len); tmp[len] = '\n'; - broadcast_meta(from, tmp, sizeof tmp); + broadcast_meta(from, tmp, sizeof(tmp)); } bool receive_request(connection_t *c, const char *request) { if(c->outgoing && proxytype == PROXY_HTTP && c->allow_request == ID) { - if(!request[0] || request[0] == '\r') + if(!request[0] || request[0] == '\r') { return true; + } + if(!strncasecmp(request, "HTTP/1.1 ", 9)) { if(!strncmp(request + 9, "200", 3)) { logger(DEBUG_CONNECTIONS, LOG_DEBUG, "Proxy request granted"); @@ -137,8 +146,10 @@ bool receive_request(connection_t *c, const char *request) { if(!request_handlers[reqno](c, request)) { /* Something went wrong. Probably scriptkiddies. Terminate. */ - if(reqno != TERMREQ) + if(reqno != TERMREQ) { logger(DEBUG_ALWAYS, LOG_ERR, "Error while processing %s from %s (%s)", request_name[reqno], c->name, c->hostname); + } + return false; } } else { @@ -154,33 +165,36 @@ static int past_request_compare(const past_request_t *a, const past_request_t *b } static void free_past_request(past_request_t *r) { - if(r->request) - free((char *)r->request); - + free((char *)r->request); free(r); } static timeout_t past_request_timeout; static void age_past_requests(void *data) { + (void)data; int left = 0, deleted = 0; for splay_each(past_request_t, p, past_request_tree) { - if(p->firstseen + pinginterval <= now.tv_sec) + if(p->firstseen + pinginterval <= now.tv_sec) { splay_delete_node(past_request_tree, node), deleted++; - else + } else { left++; + } } - if(left || deleted) + if(left || deleted) { logger(DEBUG_SCARY_THINGS, LOG_DEBUG, "Aging past requests: deleted %d, left %d", deleted, left); + } if(left) - timeout_set(&past_request_timeout, &(struct timeval){10, rand() % 100000}); + timeout_set(&past_request_timeout, &(struct timeval) { + 10, rand() % 100000 + }); } bool seen_request(const char *request) { - past_request_t *new, p = {NULL}; + past_request_t *new, p = {0}; p.request = request; @@ -188,11 +202,13 @@ bool seen_request(const char *request) { logger(DEBUG_SCARY_THINGS, LOG_DEBUG, "Already seen request"); return true; } else { - new = xmalloc(sizeof *new); + new = xmalloc(sizeof(*new)); new->request = xstrdup(request); new->firstseen = now.tv_sec; splay_insert(past_request_tree, new); - timeout_add(&past_request_timeout, age_past_requests, NULL, &(struct timeval){10, rand() % 100000}); + timeout_add(&past_request_timeout, age_past_requests, NULL, &(struct timeval) { + 10, rand() % 100000 + }); return false; } } diff --git a/src/protocol.h b/src/protocol.h index 8ce4e0d..42981cc 100644 --- a/src/protocol.h +++ b/src/protocol.h @@ -1,3 +1,6 @@ +#ifndef TINC_PROTOCOL_H +#define TINC_PROTOCOL_H + /* protocol.h -- header for protocol.c Copyright (C) 1999-2005 Ivo Timmermans, @@ -18,9 +21,6 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#ifndef __TINC_PROTOCOL_H__ -#define __TINC_PROTOCOL_H__ - #include "ecdsa.h" /* Protocol version. Different major versions are incompatible. */ @@ -80,62 +80,60 @@ extern ecdsa_t *invitation_key; /* Basic functions */ -extern bool send_request(struct connection_t *, const char *, ...) __attribute__ ((__format__(printf, 2, 3))); -extern void forward_request(struct connection_t *, const char *); -extern bool receive_request(struct connection_t *, const char *); +extern bool send_request(struct connection_t *c, const char *format, ...) __attribute__((__format__(printf, 2, 3))); +extern void forward_request(struct connection_t *c, const char *request); +extern bool receive_request(struct connection_t *c, const char *request); extern void init_requests(void); extern void exit_requests(void); -extern bool seen_request(const char *); +extern bool seen_request(const char *request); /* Requests */ -extern bool send_id(struct connection_t *); -extern bool send_metakey(struct connection_t *); -extern bool send_metakey_ec(struct connection_t *); -extern bool send_challenge(struct connection_t *); -extern bool send_chal_reply(struct connection_t *); -extern bool send_ack(struct connection_t *); -extern bool send_status(struct connection_t *, int, const char *); -extern bool send_error(struct connection_t *, int, const char *); -extern bool send_termreq(struct connection_t *); -extern bool send_ping(struct connection_t *); -extern bool send_pong(struct connection_t *); -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_id(struct connection_t *c); +extern bool send_metakey(struct connection_t *c); +extern bool send_metakey_ec(struct connection_t *c); +extern bool send_challenge(struct connection_t *c); +extern bool send_chal_reply(struct connection_t *c); +extern bool send_ack(struct connection_t *c); +extern bool send_termreq(struct connection_t *c); +extern bool send_ping(struct connection_t *c); +extern bool send_pong(struct connection_t *c); +extern bool send_add_subnet(struct connection_t *c, const struct subnet_t *subnet); +extern bool send_del_subnet(struct connection_t *c, const struct subnet_t *subnet); +extern bool send_add_edge(struct connection_t *c, const struct edge_t *e); +extern bool send_del_edge(struct connection_t *c, const struct edge_t *e); extern void send_key_changed(void); -extern bool send_req_key(struct node_t *); -extern bool send_ans_key(struct node_t *); -extern bool send_tcppacket(struct connection_t *, const struct vpn_packet_t *); -extern bool send_sptps_tcppacket(struct connection_t *, const char*, int); -extern bool send_udp_info(struct node_t *, struct node_t *); -extern bool send_mtu_info(struct node_t *, struct node_t *, int); +extern bool send_req_key(struct node_t *to); +extern bool send_ans_key(struct node_t *to); +extern bool send_tcppacket(struct connection_t *c, const struct vpn_packet_t *packet); +extern bool send_sptps_tcppacket(struct connection_t *c, const char *packet, int len); +extern bool send_udp_info(struct node_t *from, struct node_t *to); +extern bool send_mtu_info(struct node_t *from, struct node_t *to, int mtu); /* Request handlers */ -extern bool id_h(struct connection_t *, const char *); -extern bool metakey_h(struct connection_t *, const char *); -extern bool challenge_h(struct connection_t *, const char *); -extern bool chal_reply_h(struct connection_t *, const char *); -extern bool ack_h(struct connection_t *, const char *); -extern bool status_h(struct connection_t *, const char *); -extern bool error_h(struct connection_t *, const char *); -extern bool termreq_h(struct connection_t *, const char *); -extern bool ping_h(struct connection_t *, const char *); -extern bool pong_h(struct connection_t *, const char *); -extern bool add_subnet_h(struct connection_t *, const char *); -extern bool del_subnet_h(struct connection_t *, const char *); -extern bool add_edge_h(struct connection_t *, const char *); -extern bool del_edge_h(struct connection_t *, const char *); -extern bool key_changed_h(struct connection_t *, const char *); -extern bool req_key_h(struct connection_t *, const char *); -extern bool ans_key_h(struct connection_t *, const char *); -extern bool tcppacket_h(struct connection_t *, const char *); -extern bool sptps_tcppacket_h(struct connection_t *, const char *); -extern bool control_h(struct connection_t *, const char *); -extern bool udp_info_h(struct connection_t *, const char *); -extern bool mtu_info_h(struct connection_t *, const char *); +extern bool id_h(struct connection_t *c, const char *request); +extern bool metakey_h(struct connection_t *c, const char *request); +extern bool challenge_h(struct connection_t *c, const char *request); +extern bool chal_reply_h(struct connection_t *c, const char *request); +extern bool ack_h(struct connection_t *c, const char *request); +extern bool status_h(struct connection_t *c, const char *request); +extern bool error_h(struct connection_t *c, const char *request); +extern bool termreq_h(struct connection_t *c, const char *request); +extern bool ping_h(struct connection_t *c, const char *request); +extern bool pong_h(struct connection_t *c, const char *request); +extern bool add_subnet_h(struct connection_t *c, const char *request); +extern bool del_subnet_h(struct connection_t *c, const char *request); +extern bool add_edge_h(struct connection_t *c, const char *request); +extern bool del_edge_h(struct connection_t *c, const char *request); +extern bool key_changed_h(struct connection_t *c, const char *request); +extern bool req_key_h(struct connection_t *c, const char *request); +extern bool ans_key_h(struct connection_t *c, const char *request); +extern bool tcppacket_h(struct connection_t *c, const char *request); +extern bool sptps_tcppacket_h(struct connection_t *c, const char *request); +extern bool control_h(struct connection_t *c, const char *request); +extern bool udp_info_h(struct connection_t *c, const char *request); +extern bool mtu_info_h(struct connection_t *c, const char *request); -#endif /* __TINC_PROTOCOL_H__ */ +#endif diff --git a/src/protocol_auth.c b/src/protocol_auth.c index a99e1d6..3a84c22 100644 --- a/src/protocol_auth.c +++ b/src/protocol_auth.c @@ -52,87 +52,105 @@ ecdsa_t *invitation_key = NULL; static bool send_proxyrequest(connection_t *c) { switch(proxytype) { - case PROXY_HTTP: { - char *host; - char *port; + case PROXY_HTTP: { + char *host; + char *port; - sockaddr2str(&c->address, &host, &port); - send_request(c, "CONNECT %s:%s HTTP/1.1\r\n\r", host, port); - free(host); - free(port); - return true; + sockaddr2str(&c->address, &host, &port); + send_request(c, "CONNECT %s:%s HTTP/1.1\r\n\r", host, port); + free(host); + free(port); + return true; + } + + case PROXY_SOCKS4: { + if(c->address.sa.sa_family != AF_INET) { + logger(DEBUG_ALWAYS, LOG_ERR, "Cannot connect to an IPv6 host through a SOCKS 4 proxy!"); + return false; } - case PROXY_SOCKS4: { - if(c->address.sa.sa_family != AF_INET) { - logger(DEBUG_ALWAYS, LOG_ERR, "Cannot connect to an IPv6 host through a SOCKS 4 proxy!"); - return false; - } - char s4req[9 + (proxyuser ? strlen(proxyuser) : 0)]; - s4req[0] = 4; - s4req[1] = 1; - memcpy(s4req + 2, &c->address.in.sin_port, 2); - memcpy(s4req + 4, &c->address.in.sin_addr, 4); - if(proxyuser) - memcpy(s4req + 8, proxyuser, strlen(proxyuser)); - s4req[sizeof s4req - 1] = 0; - c->tcplen = 8; - return send_meta(c, s4req, sizeof s4req); + + char s4req[9 + (proxyuser ? strlen(proxyuser) : 0)]; + s4req[0] = 4; + s4req[1] = 1; + memcpy(s4req + 2, &c->address.in.sin_port, 2); + memcpy(s4req + 4, &c->address.in.sin_addr, 4); + + if(proxyuser) { + memcpy(s4req + 8, proxyuser, strlen(proxyuser)); } - case PROXY_SOCKS5: { - int len = 3 + 6 + (c->address.sa.sa_family == AF_INET ? 4 : 16); - c->tcplen = 2; - if(proxypass) - len += 3 + strlen(proxyuser) + strlen(proxypass); - char s5req[len]; - int i = 0; - s5req[i++] = 5; - s5req[i++] = 1; - if(proxypass) { - s5req[i++] = 2; - s5req[i++] = 1; - s5req[i++] = strlen(proxyuser); - memcpy(s5req + i, proxyuser, strlen(proxyuser)); - i += strlen(proxyuser); - s5req[i++] = strlen(proxypass); - memcpy(s5req + i, proxypass, strlen(proxypass)); - i += strlen(proxypass); - c->tcplen += 2; - } else { - s5req[i++] = 0; - } - s5req[i++] = 5; + + s4req[sizeof(s4req) - 1] = 0; + c->tcplen = 8; + return send_meta(c, s4req, sizeof(s4req)); + } + + case PROXY_SOCKS5: { + int len = 3 + 6 + (c->address.sa.sa_family == AF_INET ? 4 : 16); + c->tcplen = 2; + + if(proxypass) { + len += 3 + strlen(proxyuser) + strlen(proxypass); + } + + char s5req[len]; + int i = 0; + s5req[i++] = 5; + s5req[i++] = 1; + + if(proxypass) { + s5req[i++] = 2; s5req[i++] = 1; + s5req[i++] = strlen(proxyuser); + memcpy(s5req + i, proxyuser, strlen(proxyuser)); + i += strlen(proxyuser); + s5req[i++] = strlen(proxypass); + memcpy(s5req + i, proxypass, strlen(proxypass)); + i += strlen(proxypass); + c->tcplen += 2; + } else { s5req[i++] = 0; - if(c->address.sa.sa_family == AF_INET) { - s5req[i++] = 1; - memcpy(s5req + i, &c->address.in.sin_addr, 4); - i += 4; - memcpy(s5req + i, &c->address.in.sin_port, 2); - i += 2; - c->tcplen += 10; - } else if(c->address.sa.sa_family == AF_INET6) { - s5req[i++] = 3; - memcpy(s5req + i, &c->address.in6.sin6_addr, 16); - i += 16; - memcpy(s5req + i, &c->address.in6.sin6_port, 2); - i += 2; - c->tcplen += 22; - } else { - logger(DEBUG_ALWAYS, LOG_ERR, "Address family %x not supported for SOCKS 5 proxies!", c->address.sa.sa_family); - return false; - } - if(i > len) - abort(); - return send_meta(c, s5req, sizeof s5req); } - case PROXY_SOCKS4A: - logger(DEBUG_ALWAYS, LOG_ERR, "Proxy type not implemented yet"); - return false; - case PROXY_EXEC: - return true; - default: - logger(DEBUG_ALWAYS, LOG_ERR, "Unknown proxy type"); + + s5req[i++] = 5; + s5req[i++] = 1; + s5req[i++] = 0; + + if(c->address.sa.sa_family == AF_INET) { + s5req[i++] = 1; + memcpy(s5req + i, &c->address.in.sin_addr, 4); + i += 4; + memcpy(s5req + i, &c->address.in.sin_port, 2); + i += 2; + c->tcplen += 10; + } else if(c->address.sa.sa_family == AF_INET6) { + s5req[i++] = 3; + memcpy(s5req + i, &c->address.in6.sin6_addr, 16); + i += 16; + memcpy(s5req + i, &c->address.in6.sin6_port, 2); + i += 2; + c->tcplen += 22; + } else { + logger(DEBUG_ALWAYS, LOG_ERR, "Address family %x not supported for SOCKS 5 proxies!", c->address.sa.sa_family); return false; + } + + if(i > len) { + abort(); + } + + return send_meta(c, s5req, sizeof(s5req)); + } + + case PROXY_SOCKS4A: + logger(DEBUG_ALWAYS, LOG_ERR, "Proxy type not implemented yet"); + return false; + + case PROXY_EXEC: + return true; + + default: + logger(DEBUG_ALWAYS, LOG_ERR, "Unknown proxy type"); + return false; } } @@ -142,20 +160,24 @@ bool send_id(connection_t *c) { int minor = 0; if(experimental) { - if(c->outgoing && !read_ecdsa_public_key(c)) + if(c->outgoing && !read_ecdsa_public_key(c)) { minor = 1; - else + } else { minor = myself->connection->protocol_minor; + } } if(proxytype && c->outgoing) - if(!send_proxyrequest(c)) + if(!send_proxyrequest(c)) { return false; + } return send_request(c, "%d %s %d.%d", ID, myself->connection->name, myself->connection->protocol_major, minor); } static bool finalize_invitation(connection_t *c, const char *data, uint16_t len) { + (void)len; + if(strchr(data, '\n')) { logger(DEBUG_ALWAYS, LOG_ERR, "Received invalid key from invited node %s (%s)!\n", c->name, c->hostname); return false; @@ -163,13 +185,15 @@ static bool finalize_invitation(connection_t *c, const char *data, uint16_t len) // Create a new host config file char filename[PATH_MAX]; - snprintf(filename, sizeof filename, "%s" SLASH "hosts" SLASH "%s", confbase, c->name); + snprintf(filename, sizeof(filename), "%s" SLASH "hosts" SLASH "%s", confbase, c->name); + if(!access(filename, F_OK)) { logger(DEBUG_ALWAYS, LOG_ERR, "Host config file for %s (%s) already exists!\n", c->name, c->hostname); return false; } FILE *f = fopen(filename, "w"); + if(!f) { logger(DEBUG_ALWAYS, LOG_ERR, "Error trying to create %s: %s\n", filename, strerror(errno)); return false; @@ -178,14 +202,14 @@ static bool finalize_invitation(connection_t *c, const char *data, uint16_t len) fprintf(f, "Ed25519PublicKey = %s\n", data); fclose(f); - logger(DEBUG_CONNECTIONS, LOG_INFO, "Key succesfully received from %s (%s)", c->name, c->hostname); + logger(DEBUG_CONNECTIONS, LOG_INFO, "Key successfully received from %s (%s)", c->name, c->hostname); // Call invitation-accepted script environment_t env; char *address, *port; environment_init(&env); - environment_add(&env, "NODE=%s", c->name); + environment_add(&env, "NODE=%s", c->name); sockaddr2str(&c->address, &address, &port); environment_add(&env, "REMOTEADDRESS=%s", address); environment_add(&env, "NAME=%s", myself->name); @@ -201,40 +225,46 @@ static bool finalize_invitation(connection_t *c, const char *data, uint16_t len) static bool receive_invitation_sptps(void *handle, uint8_t type, const void *data, uint16_t len) { connection_t *c = handle; - if(type == 128) + if(type == 128) { return true; + } - if(type == 1 && c->status.invitation_used) + if(type == 1 && c->status.invitation_used) { return finalize_invitation(c, data, len); + } - if(type != 0 || len != 18 || c->status.invitation_used) + if(type != 0 || len != 18 || c->status.invitation_used) { return false; + } // Recover the filename from the cookie and the key char *fingerprint = ecdsa_get_base64_public_key(invitation_key); char hashbuf[18 + strlen(fingerprint)]; char cookie[64]; memcpy(hashbuf, data, 18); - memcpy(hashbuf + 18, fingerprint, sizeof hashbuf - 18); - sha512(hashbuf, sizeof hashbuf, cookie); + memcpy(hashbuf + 18, fingerprint, sizeof(hashbuf) - 18); + sha512(hashbuf, sizeof(hashbuf), cookie); b64encode_urlsafe(cookie, cookie, 18); free(fingerprint); char filename[PATH_MAX], usedname[PATH_MAX]; - snprintf(filename, sizeof filename, "%s" SLASH "invitations" SLASH "%s", confbase, cookie); - snprintf(usedname, sizeof usedname, "%s" SLASH "invitations" SLASH "%s.used", confbase, cookie); + snprintf(filename, sizeof(filename), "%s" SLASH "invitations" SLASH "%s", confbase, cookie); + snprintf(usedname, sizeof(usedname), "%s" SLASH "invitations" SLASH "%s.used", confbase, cookie); // Atomically rename the invitation file if(rename(filename, usedname)) { - if(errno == ENOENT) + if(errno == ENOENT) { logger(DEBUG_ALWAYS, LOG_ERR, "Peer %s tried to use non-existing invitation %s\n", c->hostname, cookie); - else + } else { logger(DEBUG_ALWAYS, LOG_ERR, "Error trying to rename invitation %s\n", cookie); + } + return false; } // Check the timestamp of the invitation struct stat st; + if(stat(usedname, &st)) { logger(DEBUG_ALWAYS, LOG_ERR, "Could not stat %s", usedname); return false; @@ -247,6 +277,7 @@ static bool receive_invitation_sptps(void *handle, uint8_t type, const void *dat // Open the renamed file FILE *f = fopen(usedname, "r"); + if(!f) { logger(DEBUG_ALWAYS, LOG_ERR, "Error trying to open invitation %s\n", cookie); return false; @@ -254,20 +285,24 @@ static bool receive_invitation_sptps(void *handle, uint8_t type, const void *dat // Read the new node's Name from the file char buf[1024]; - fgets(buf, sizeof buf, f); - if(*buf) + fgets(buf, sizeof(buf), f); + + if(*buf) { buf[strlen(buf) - 1] = 0; + } len = strcspn(buf, " \t="); char *name = buf + len; name += strspn(name, " \t"); + if(*name == '=') { name++; name += strspn(name, " \t"); } + buf[len] = 0; - if(!*buf || !*name || strcasecmp(buf, "Name") || !check_id(name)) { + if(!*buf || !*name || strcasecmp(buf, "Name") || !check_id(name) || !strcmp(name, myself->name)) { logger(DEBUG_ALWAYS, LOG_ERR, "Invalid invitation file %s\n", cookie); fclose(f); return false; @@ -279,15 +314,18 @@ static bool receive_invitation_sptps(void *handle, uint8_t type, const void *dat // Send the node the contents of the invitation file rewind(f); size_t result; - while((result = fread(buf, 1, sizeof buf, f))) + + while((result = fread(buf, 1, sizeof(buf), f))) { sptps_send_record(&c->sptps, 0, buf, result); + } + sptps_send_record(&c->sptps, 1, buf, 0); fclose(f); unlink(usedname); c->status.invitation_used = true; - logger(DEBUG_CONNECTIONS, LOG_INFO, "Invitation %s succesfully sent to %s (%s)", cookie, c->name, c->hostname); + logger(DEBUG_CONNECTIONS, LOG_INFO, "Invitation %s successfully sent to %s (%s)", cookie, c->name, c->hostname); return true; } @@ -296,7 +334,7 @@ bool id_h(connection_t *c, const char *request) { if(sscanf(request, "%*d " MAX_STRING " %2d.%3d", name, &c->protocol_major, &c->protocol_minor) < 2) { logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "ID", c->name, - c->hostname); + c->hostname); return false; } @@ -310,6 +348,10 @@ bool id_h(connection_t *c, const char *request) { free(c->name); c->name = xstrdup(""); + if(!c->outgoing) { + send_id(c); + } + return send_request(c, "%d %d %d", ACK, TINC_CTL_VERSION_CURRENT, getpid()); } @@ -320,6 +362,7 @@ bool id_h(connection_t *c, const char *request) { } c->ecdsa = ecdsa_set_base64_public_key(name + 1); + if(!c->ecdsa) { logger(DEBUG_ALWAYS, LOG_ERR, "Got bad invitation from %s", c->hostname); return false; @@ -327,10 +370,19 @@ bool id_h(connection_t *c, const char *request) { c->status.invitation = true; char *mykey = ecdsa_get_base64_public_key(invitation_key); - if(!mykey) + + if(!mykey) { return false; - if(!send_request(c, "%d %s", ACK, mykey)) + } + + if(!c->outgoing) { + send_id(c); + } + + if(!send_request(c, "%d %s", ACK, mykey)) { return false; + } + free(mykey); c->protocol_minor = 2; @@ -340,9 +392,9 @@ bool id_h(connection_t *c, const char *request) { /* Check if identity is a valid name */ - if(!check_id(name)) { + if(!check_id(name) || !strcmp(name, myself->name)) { logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s): %s", "ID", c->name, - c->hostname, "invalid name"); + c->hostname, "invalid name"); return false; } @@ -351,12 +403,11 @@ bool id_h(connection_t *c, const char *request) { if(c->outgoing) { if(strcmp(c->name, name)) { logger(DEBUG_ALWAYS, LOG_ERR, "Peer %s is %s instead of %s", c->hostname, name, - c->name); + c->name); return false; } } else { - if(c->name) - free(c->name); + free(c->name); c->name = xstrdup(name); } @@ -364,56 +415,72 @@ bool id_h(connection_t *c, const char *request) { if(c->protocol_major != myself->connection->protocol_major) { logger(DEBUG_ALWAYS, LOG_ERR, "Peer %s (%s) uses incompatible version %d.%d", - c->name, c->hostname, c->protocol_major, c->protocol_minor); + c->name, c->hostname, c->protocol_major, c->protocol_minor); return false; } if(bypass_security) { - if(!c->config_tree) + if(!c->config_tree) { init_configuration(&c->config_tree); + } + c->allow_request = ACK; + + if(!c->outgoing) { + send_id(c); + } + return send_ack(c); } - if(!experimental) + if(!experimental) { c->protocol_minor = 0; + } if(!c->config_tree) { init_configuration(&c->config_tree); - if(!read_host_config(c->config_tree, c->name)) { + if(!read_host_config(c->config_tree, c->name, false)) { logger(DEBUG_ALWAYS, LOG_ERR, "Peer %s had unknown identity (%s)", c->hostname, c->name); return false; } - if(experimental) + if(experimental) { read_ecdsa_public_key(c); - /* Ignore failures if no key known yet */ + } + + /* Ignore failures if no key known yet */ } - if(c->protocol_minor && !ecdsa_active(c->ecdsa)) + if(c->protocol_minor && !ecdsa_active(c->ecdsa)) { c->protocol_minor = 1; + } /* Forbid version rollback for nodes whose Ed25519 key we know */ if(ecdsa_active(c->ecdsa) && c->protocol_minor < 1) { logger(DEBUG_ALWAYS, LOG_ERR, "Peer %s (%s) tries to roll back protocol version to %d.%d", - c->name, c->hostname, c->protocol_major, c->protocol_minor); + c->name, c->hostname, c->protocol_major, c->protocol_minor); return false; } c->allow_request = METAKEY; + if(!c->outgoing) { + send_id(c); + } + if(c->protocol_minor >= 2) { c->allow_request = ACK; char label[25 + strlen(myself->name) + strlen(c->name)]; - if(c->outgoing) - snprintf(label, sizeof label, "tinc TCP key expansion %s %s", myself->name, c->name); - else - snprintf(label, sizeof label, "tinc TCP key expansion %s %s", c->name, myself->name); + if(c->outgoing) { + snprintf(label, sizeof(label), "tinc TCP key expansion %s %s", myself->name, c->name); + } else { + snprintf(label, sizeof(label), "tinc TCP key expansion %s %s", c->name, myself->name); + } - return sptps_start(&c->sptps, c, c->outgoing, false, myself->connection->ecdsa, c->ecdsa, label, sizeof label, send_meta_sptps, receive_meta_sptps); + return sptps_start(&c->sptps, c, c->outgoing, false, myself->connection->ecdsa, c->ecdsa, label, sizeof(label), send_meta_sptps, receive_meta_sptps); } else { return send_metakey(c); } @@ -423,13 +490,15 @@ bool send_metakey(connection_t *c) { #ifdef DISABLE_LEGACY return false; #else + if(!myself->connection->rsa) { logger(DEBUG_CONNECTIONS, LOG_ERR, "Peer %s (%s) uses legacy protocol which we don't support", c->name, c->hostname); return false; } - if(!read_rsa_public_key(c)) + if(!read_rsa_public_key(c)) { return false; + } /* We need to use a stream mode for the meta protocol. Use AES for this, but try to match the key size with the one from the cipher selected @@ -437,19 +506,24 @@ bool send_metakey(connection_t *c) { */ int keylen = cipher_keylength(myself->incipher); - if(keylen <= 16) + + if(keylen <= 16) { c->outcipher = cipher_open_by_name("aes-128-cfb"); - else if(keylen <= 24) + } else if(keylen <= 24) { c->outcipher = cipher_open_by_name("aes-192-cfb"); - else + } else { c->outcipher = cipher_open_by_name("aes-256-cfb"); - if(!c) + } + + if(!c) { return false; + } c->outbudget = cipher_budget(c->outcipher); - if(!(c->outdigest = digest_open_by_name("sha256", -1))) + if(!(c->outdigest = digest_open_by_name("sha256", -1))) { return false; + } const size_t len = rsa_size(c->rsa); char key[len]; @@ -472,8 +546,9 @@ bool send_metakey(connection_t *c) { key[0] &= 0x7F; - if(!cipher_set_key_from_rsa(c->outcipher, key, len, true)) + if(!cipher_set_key_from_rsa(c->outcipher, key, len, true)) { return false; + } if(debug_level >= DEBUG_SCARY_THINGS) { bin2hex(key, hexkey, len); @@ -499,9 +574,9 @@ bool send_metakey(connection_t *c) { /* Send the meta key */ bool result = send_request(c, "%d %d %d %d %d %s", METAKEY, - cipher_get_nid(c->outcipher), - digest_get_nid(c->outdigest), c->outmaclength, - c->outcompression, hexkey); + cipher_get_nid(c->outcipher), + digest_get_nid(c->outdigest), c->outmaclength, + c->outcompression, hexkey); c->status.encryptout = true; return result; @@ -512,8 +587,10 @@ bool metakey_h(connection_t *c, const char *request) { #ifdef DISABLE_LEGACY return false; #else - if(!myself->connection->rsa) + + if(!myself->connection->rsa) { return false; + } char hexkey[MAX_STRING_SIZE]; int cipher, digest, maclength, compression; @@ -528,7 +605,7 @@ bool metakey_h(connection_t *c, const char *request) { /* Convert the challenge from hexadecimal back to binary */ - int inlen = hex2bin(hexkey, enckey, sizeof enckey); + size_t inlen = hex2bin(hexkey, enckey, sizeof(enckey)); /* Check if the length of the meta key is all right */ @@ -557,7 +634,8 @@ bool metakey_h(connection_t *c, const char *request) { return false; } } else { - c->incipher = NULL; + logger(DEBUG_ALWAYS, LOG_ERR, "Possible intruder %s (%s): %s", c->name, c->hostname, "null cipher"); + return false; } c->inbudget = cipher_budget(c->incipher); @@ -568,7 +646,8 @@ bool metakey_h(connection_t *c, const char *request) { return false; } } else { - c->indigest = NULL; + logger(DEBUG_ALWAYS, LOG_ERR, "Possible intruder %s (%s): %s", c->name, c->hostname, "null digest"); + return false; } c->status.decryptin = true; @@ -586,8 +665,7 @@ bool send_challenge(connection_t *c) { const size_t len = rsa_size(c->rsa); char buffer[len * 2 + 1]; - if(!c->hischallenge) - c->hischallenge = xrealloc(c->hischallenge, len); + c->hischallenge = xrealloc(c->hischallenge, len); /* Copy random data to the buffer */ @@ -607,47 +685,68 @@ bool challenge_h(connection_t *c, const char *request) { #ifdef DISABLE_LEGACY return false; #else - if(!myself->connection->rsa) + + if(!myself->connection->rsa) { return false; + } char buffer[MAX_STRING_SIZE]; const size_t len = rsa_size(myself->connection->rsa); - size_t digestlen = digest_length(c->indigest); - char digest[digestlen]; if(sscanf(request, "%*d " MAX_STRING, buffer) != 1) { logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "CHALLENGE", c->name, c->hostname); return false; } - /* Convert the challenge from hexadecimal back to binary */ - - int inlen = hex2bin(buffer, buffer, sizeof buffer); - /* Check if the length of the challenge is all right */ - if(inlen != len) { + if(strlen(buffer) != (size_t)len * 2) { logger(DEBUG_ALWAYS, LOG_ERR, "Possible intruder %s (%s): %s", c->name, c->hostname, "wrong challenge length"); return false; } - /* Calculate the hash from the challenge we received */ + c->mychallenge = xrealloc(c->mychallenge, len); - if(!digest_create(c->indigest, buffer, len, digest)) - return false; + /* Convert the challenge from hexadecimal back to binary */ - /* Convert the hash to a hexadecimal formatted string */ + hex2bin(buffer, c->mychallenge, len); - bin2hex(digest, buffer, digestlen); - - /* Send the reply */ + /* The rest is done by send_chal_reply() */ c->allow_request = CHAL_REPLY; - return send_request(c, "%d %s", CHAL_REPLY, buffer); + if(c->outgoing) { + return send_chal_reply(c); + } else { + return true; + } + #endif } +bool send_chal_reply(connection_t *c) { + const size_t len = rsa_size(myself->connection->rsa); + size_t digestlen = digest_length(c->indigest); + char digest[digestlen * 2 + 1]; + + /* Calculate the hash from the challenge we received */ + + if(!digest_create(c->indigest, c->mychallenge, len, digest)) { + return false; + } + + free(c->mychallenge); + c->mychallenge = NULL; + + /* Convert the hash to a hexadecimal formatted string */ + + bin2hex(digest, digest, digestlen); + + /* Send the reply */ + + return send_request(c, "%d %s", CHAL_REPLY, digest); +} + bool chal_reply_h(connection_t *c, const char *request) { #ifdef DISABLE_LEGACY return false; @@ -656,13 +755,13 @@ bool chal_reply_h(connection_t *c, const char *request) { if(sscanf(request, "%*d " MAX_STRING, hishash) != 1) { logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "CHAL_REPLY", c->name, - c->hostname); + c->hostname); return false; } /* Convert the hash to binary format */ - int inlen = hex2bin(hishash, hishash, sizeof hishash); + size_t inlen = hex2bin(hishash, hishash, sizeof(hishash)); /* Check if the length of the hash is all right */ @@ -687,6 +786,10 @@ bool chal_reply_h(connection_t *c, const char *request) { c->hischallenge = NULL; c->allow_request = ACK; + if(!c->outgoing) { + send_chal_reply(c); + } + return send_ack(c); #endif } @@ -700,8 +803,9 @@ static bool send_upgrade(connection_t *c) { char *pubkey = ecdsa_get_base64_public_key(myself->connection->ecdsa); - if(!pubkey) + if(!pubkey) { return false; + } bool result = send_request(c, "%d %s", ACK, pubkey); free(pubkey); @@ -710,8 +814,9 @@ static bool send_upgrade(connection_t *c) { } bool send_ack(connection_t *c) { - if(c->protocol_minor == 1) + if(c->protocol_minor == 1) { return send_upgrade(c); + } /* ACK message contains rest of the information the other end needs to create node_t and edge_t structures. */ @@ -726,22 +831,28 @@ bool send_ack(connection_t *c) { /* Check some options */ - if((get_config_bool(lookup_config(c->config_tree, "IndirectData"), &choice) && choice) || myself->options & OPTION_INDIRECT) + if((get_config_bool(lookup_config(c->config_tree, "IndirectData"), &choice) && choice) || myself->options & OPTION_INDIRECT) { c->options |= OPTION_INDIRECT; + } - if((get_config_bool(lookup_config(c->config_tree, "TCPOnly"), &choice) && choice) || myself->options & OPTION_TCPONLY) + if((get_config_bool(lookup_config(c->config_tree, "TCPOnly"), &choice) && choice) || myself->options & OPTION_TCPONLY) { c->options |= OPTION_TCPONLY | OPTION_INDIRECT; + } - if(myself->options & OPTION_PMTU_DISCOVERY) + if(myself->options & OPTION_PMTU_DISCOVERY && !(c->options & OPTION_TCPONLY)) { 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; - if(!get_config_int(lookup_config(c->config_tree, "Weight"), &c->estimated_weight)) + if(choice) { + c->options |= OPTION_CLAMP_MSS; + } + + if(!get_config_int(lookup_config(c->config_tree, "Weight"), &c->estimated_weight)) { get_config_int(lookup_config(config_tree, "Weight"), &c->estimated_weight); + } return send_request(c, "%d %s %d %x", ACK, myport, c->estimated_weight, (c->options & 0xffffff) | (experimental ? (PROT_MINOR << 24) : 0)); } @@ -755,24 +866,27 @@ static void send_everything(connection_t *c) { char pad[MAXBUFSIZE - MAXSIZE]; } zeropkt; - memset(&zeropkt, 0, sizeof zeropkt); + memset(&zeropkt, 0, sizeof(zeropkt)); zeropkt.pkt.len = MAXBUFSIZE; send_tcppacket(c, &zeropkt.pkt); } if(tunnelserver) { - for splay_each(subnet_t, s, myself->subnet_tree) + for splay_each(subnet_t, s, myself->subnet_tree) { send_add_subnet(c, s); + } return; } for splay_each(node_t, n, node_tree) { - for splay_each(subnet_t, s, n->subnet_tree) + for splay_each(subnet_t, s, n->subnet_tree) { send_add_subnet(c, s); + } - for splay_each(edge_t, e, n->edge_tree) + for splay_each(edge_t, e, n->edge_tree) { send_add_edge(c, e); + } } } @@ -788,16 +902,19 @@ static bool upgrade_h(connection_t *c, const char *request) { char *knownkey = ecdsa_get_base64_public_key(c->ecdsa); bool different = strcmp(knownkey, pubkey); free(knownkey); + if(different) { logger(DEBUG_ALWAYS, LOG_ERR, "Already have an Ed25519 public key from %s (%s) which is different from the one presented now!", c->name, c->hostname); return false; } + logger(DEBUG_ALWAYS, LOG_INFO, "Already have Ed25519 public key from %s (%s), ignoring.", c->name, c->hostname); c->allow_request = TERMREQ; return send_termreq(c); } c->ecdsa = ecdsa_set_base64_public_key(pubkey); + if(!c->ecdsa) { logger(DEBUG_ALWAYS, LOG_INFO, "Got bad Ed25519 public key from %s (%s), not upgrading.", c->name, c->hostname); return false; @@ -806,14 +923,18 @@ static bool upgrade_h(connection_t *c, const char *request) { logger(DEBUG_ALWAYS, LOG_INFO, "Got Ed25519 public key from %s (%s), upgrading!", c->name, c->hostname); append_config_file(c->name, "Ed25519PublicKey", pubkey); c->allow_request = TERMREQ; - if(c->outgoing) + + if(c->outgoing) { c->outgoing->timeout = 0; + } + return send_termreq(c); } bool ack_h(connection_t *c, const char *request) { - if(c->protocol_minor == 1) + if(c->protocol_minor == 1) { return upgrade_h(c, request); + } char hisport[MAX_STRING_SIZE]; int weight, mtu; @@ -823,7 +944,7 @@ bool ack_h(connection_t *c, const char *request) { if(sscanf(request, "%*d " MAX_STRING " %d %x", hisport, &weight, &options) != 3) { logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "ACK", c->name, - c->hostname); + c->hostname); return false; } @@ -841,10 +962,11 @@ bool ack_h(connection_t *c, const char *request) { logger(DEBUG_CONNECTIONS, LOG_DEBUG, "Established a second connection with %s (%s), closing old connection", n->connection->name, n->connection->hostname); if(n->connection->outgoing) { - if(c->outgoing) + if(c->outgoing) { logger(DEBUG_ALWAYS, LOG_WARNING, "Two outgoing connections to the same node!"); - else + } else { c->outgoing = n->connection->outgoing; + } n->connection->outgoing = NULL; } @@ -857,23 +979,28 @@ bool ack_h(connection_t *c, const char *request) { n->connection = c; c->node = n; + if(!(c->options & options & OPTION_PMTU_DISCOVERY)) { c->options &= ~OPTION_PMTU_DISCOVERY; options &= ~OPTION_PMTU_DISCOVERY; } + c->options |= options; - if(get_config_int(lookup_config(c->config_tree, "PMTU"), &mtu) && mtu < n->mtu) + if(get_config_int(lookup_config(c->config_tree, "PMTU"), &mtu) && mtu < n->mtu) { n->mtu = mtu; + } - if(get_config_int(lookup_config(config_tree, "PMTU"), &mtu) && mtu < n->mtu) + if(get_config_int(lookup_config(config_tree, "PMTU"), &mtu) && mtu < n->mtu) { n->mtu = mtu; + } if(get_config_bool(lookup_config(c->config_tree, "ClampMSS"), &choice)) { - if(choice) + if(choice) { c->options |= OPTION_CLAMP_MSS; - else + } else { c->options &= ~OPTION_CLAMP_MSS; + } } /* Activate this connection */ @@ -881,7 +1008,7 @@ bool ack_h(connection_t *c, const char *request) { c->allow_request = ALL; logger(DEBUG_CONNECTIONS, LOG_NOTICE, "Connection with %s (%s) activated", c->name, - c->hostname); + c->hostname); /* Send him everything we know */ @@ -895,13 +1022,15 @@ bool ack_h(connection_t *c, const char *request) { sockaddrcpy(&c->edge->address, &c->address); sockaddr_setport(&c->edge->address, hisport); sockaddr_t local_sa; - socklen_t local_salen = sizeof local_sa; - if (getsockname(c->socket, &local_sa.sa, &local_salen) < 0) + socklen_t local_salen = sizeof(local_sa); + + if(getsockname(c->socket, &local_sa.sa, &local_salen) < 0) { logger(DEBUG_ALWAYS, LOG_WARNING, "Could not get local socket address for connection with %s", c->name); - else { + } else { sockaddr_setport(&local_sa, myport); c->edge->local_address = local_sa; } + c->edge->weight = (weight + c->estimated_weight) / 2; c->edge->connection = c; c->edge->options = c->options; @@ -910,10 +1039,11 @@ bool ack_h(connection_t *c, const char *request) { /* Notify everyone of the new edge */ - if(tunnelserver) + if(tunnelserver) { send_add_edge(c, c->edge); - else + } else { send_add_edge(everyone, c->edge); + } /* Run MST and SSSP algorithms */ diff --git a/src/protocol_edge.c b/src/protocol_edge.c index 92089b1..d650c36 100644 --- a/src/protocol_edge.c +++ b/src/protocol_edge.c @@ -45,14 +45,14 @@ bool send_add_edge(connection_t *c, const edge_t *e) { sockaddr2str(&e->local_address, &local_address, &local_port); x = send_request(c, "%d %x %s %s %s %s %x %d %s %s", ADD_EDGE, rand(), - e->from->name, e->to->name, address, port, - e->options, e->weight, local_address, local_port); + e->from->name, e->to->name, address, port, + e->options, e->weight, local_address, local_port); free(local_address); free(local_port); } else { x = send_request(c, "%d %x %s %s %s %s %x %d", ADD_EDGE, rand(), - e->from->name, e->to->name, address, port, - e->options, e->weight); + e->from->name, e->to->name, address, port, + e->options, e->weight); } free(address); @@ -70,28 +70,30 @@ bool add_edge_h(connection_t *c, const char *request) { char to_port[MAX_STRING_SIZE]; char address_local[MAX_STRING_SIZE]; char port_local[MAX_STRING_SIZE]; - sockaddr_t address, local_address = {{0}}; + sockaddr_t address, local_address = {0}; uint32_t options; int weight; int parameter_count = sscanf(request, "%*d %*x "MAX_STRING" "MAX_STRING" "MAX_STRING" "MAX_STRING" %x %d "MAX_STRING" "MAX_STRING, - from_name, to_name, to_address, to_port, &options, &weight, address_local, port_local); - if (parameter_count != 6 && parameter_count != 8) { + from_name, to_name, to_address, to_port, &options, &weight, address_local, port_local); + + if(parameter_count != 6 && parameter_count != 8) { logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "ADD_EDGE", c->name, - c->hostname); + c->hostname); return false; } /* Check if names are valid */ - if(!check_id(from_name) || !check_id(to_name)) { + if(!check_id(from_name) || !check_id(to_name) || !strcmp(from_name, to_name)) { logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s): %s", "ADD_EDGE", c->name, - c->hostname, "invalid name"); + c->hostname, "invalid name"); return false; } - if(seen_request(request)) + if(seen_request(request)) { return true; + } /* Lookup nodes */ @@ -99,12 +101,12 @@ bool add_edge_h(connection_t *c, const char *request) { to = lookup_node(to_name); if(tunnelserver && - from != myself && from != c->node && - to != myself && to != c->node) { + from != myself && from != c->node && + to != myself && to != c->node) { /* ignore indirect edge registrations for tunnelserver */ logger(DEBUG_PROTOCOL, LOG_WARNING, - "Ignoring indirect %s from %s (%s)", - "ADD_EDGE", c->name, c->hostname); + "Ignoring indirect %s from %s (%s)", + "ADD_EDGE", c->name, c->hostname); return true; } @@ -124,8 +126,10 @@ bool add_edge_h(connection_t *c, const char *request) { /* Convert addresses */ address = str2sockaddr(to_address, to_port); - if(parameter_count >= 8) + + if(parameter_count >= 8) { local_address = str2sockaddr(address_local, port_local); + } /* Check if edge already exists */ @@ -137,7 +141,7 @@ bool add_edge_h(connection_t *c, const char *request) { // local_address.sa.sa_family will be 255 (AF_UNKNOWN) if we got it from newer versions // but for edge which does not have local_address bool new_local_address = local_address.sa.sa_family && local_address.sa.sa_family != AF_UNKNOWN && - sockaddrcmp(&e->local_address, &local_address); + sockaddrcmp(&e->local_address, &local_address); if(e->weight == weight && e->options == options && !new_address && !new_local_address) { sockaddrfree(&address); @@ -147,7 +151,7 @@ bool add_edge_h(connection_t *c, const char *request) { if(from == myself) { logger(DEBUG_PROTOCOL, LOG_WARNING, "Got %s from %s (%s) for ourself which does not match existing entry", - "ADD_EDGE", c->name, c->hostname); + "ADD_EDGE", c->name, c->hostname); send_add_edge(c, e); sockaddrfree(&address); sockaddrfree(&local_address); @@ -155,7 +159,7 @@ bool add_edge_h(connection_t *c, const char *request) { } logger(DEBUG_PROTOCOL, LOG_WARNING, "Got %s from %s (%s) which does not match existing entry", - "ADD_EDGE", c->name, c->hostname); + "ADD_EDGE", c->name, c->hostname); e->options = options; @@ -180,7 +184,7 @@ bool add_edge_h(connection_t *c, const char *request) { } } else if(from == myself) { logger(DEBUG_PROTOCOL, LOG_WARNING, "Got %s from %s (%s) for ourself which does not exist", - "ADD_EDGE", c->name, c->hostname); + "ADD_EDGE", c->name, c->hostname); contradicting_add_edge++; e = new_edge(); e->from = from; @@ -203,8 +207,9 @@ bool add_edge_h(connection_t *c, const char *request) { /* Tell the rest about the new edge */ - if(!tunnelserver) + if(!tunnelserver) { forward_request(c, request); + } /* Run MST before or after we tell the rest? */ @@ -215,7 +220,7 @@ bool add_edge_h(connection_t *c, const char *request) { bool send_del_edge(connection_t *c, const edge_t *e) { return send_request(c, "%d %x %s %s", DEL_EDGE, rand(), - e->from->name, e->to->name); + e->from->name, e->to->name); } bool del_edge_h(connection_t *c, const char *request) { @@ -226,20 +231,21 @@ bool del_edge_h(connection_t *c, const char *request) { if(sscanf(request, "%*d %*x "MAX_STRING" "MAX_STRING, from_name, to_name) != 2) { logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "DEL_EDGE", c->name, - c->hostname); + c->hostname); return false; } /* Check if names are valid */ - if(!check_id(from_name) || !check_id(to_name)) { + if(!check_id(from_name) || !check_id(to_name) || !strcmp(from_name, to_name)) { logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s): %s", "DEL_EDGE", c->name, - c->hostname, "invalid name"); + c->hostname, "invalid name"); return false; } - if(seen_request(request)) + if(seen_request(request)) { return true; + } /* Lookup nodes */ @@ -247,24 +253,24 @@ bool del_edge_h(connection_t *c, const char *request) { to = lookup_node(to_name); if(tunnelserver && - from != myself && from != c->node && - to != myself && to != c->node) { + from != myself && from != c->node && + to != myself && to != c->node) { /* ignore indirect edge registrations for tunnelserver */ logger(DEBUG_PROTOCOL, LOG_WARNING, - "Ignoring indirect %s from %s (%s)", - "DEL_EDGE", c->name, c->hostname); + "Ignoring indirect %s from %s (%s)", + "DEL_EDGE", c->name, c->hostname); return true; } if(!from) { logger(DEBUG_PROTOCOL, LOG_ERR, "Got %s from %s (%s) which does not appear in the edge tree", - "DEL_EDGE", c->name, c->hostname); + "DEL_EDGE", c->name, c->hostname); return true; } if(!to) { logger(DEBUG_PROTOCOL, LOG_ERR, "Got %s from %s (%s) which does not appear in the edge tree", - "DEL_EDGE", c->name, c->hostname); + "DEL_EDGE", c->name, c->hostname); return true; } @@ -274,13 +280,13 @@ bool del_edge_h(connection_t *c, const char *request) { if(!e) { logger(DEBUG_PROTOCOL, LOG_WARNING, "Got %s from %s (%s) which does not appear in the edge tree", - "DEL_EDGE", c->name, c->hostname); + "DEL_EDGE", c->name, c->hostname); return true; } if(e->from == myself) { logger(DEBUG_PROTOCOL, LOG_WARNING, "Got %s from %s (%s) for ourself", - "DEL_EDGE", c->name, c->hostname); + "DEL_EDGE", c->name, c->hostname); contradicting_del_edge++; send_add_edge(c, e); /* Send back a correction */ return true; @@ -288,8 +294,9 @@ bool del_edge_h(connection_t *c, const char *request) { /* Tell the rest about the deleted edge */ - if(!tunnelserver) + if(!tunnelserver) { forward_request(c, request); + } /* Delete the edge */ @@ -303,9 +310,12 @@ bool del_edge_h(connection_t *c, const char *request) { if(!to->status.reachable) { e = lookup_edge(to, myself); + if(e) { - if(!tunnelserver) + if(!tunnelserver) { send_del_edge(everyone, e); + } + edge_del(e); } } diff --git a/src/protocol_key.c b/src/protocol_key.c index a18cefc..58a3bd2 100644 --- a/src/protocol_key.c +++ b/src/protocol_key.c @@ -29,6 +29,7 @@ #include "node.h" #include "prf.h" #include "protocol.h" +#include "route.h" #include "sptps.h" #include "utils.h" #include "xalloc.h" @@ -42,16 +43,19 @@ void send_key_changed(void) { /* Immediately send new keys to directly connected nodes to keep UDP mappings alive */ for list_each(connection_t, c, connection_list) - if(c->edge && c->node && c->node->status.reachable && !c->node->status.sptps) + if(c->edge && c->node && c->node->status.reachable && !c->node->status.sptps) { send_ans_key(c->node); + } + #endif /* Force key exchange for connections using SPTPS */ if(experimental) { for splay_each(node_t, n, node_tree) - if(n->status.reachable && n->status.validkey && n->status.sptps) + if(n->status.reachable && n->status.validkey && n->status.sptps) { sptps_force_kex(&n->sptps); + } } } @@ -61,18 +65,19 @@ bool key_changed_h(connection_t *c, const char *request) { if(sscanf(request, "%*d %*x " MAX_STRING, name) != 1) { logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "KEY_CHANGED", - c->name, c->hostname); + c->name, c->hostname); return false; } - if(seen_request(request)) + if(seen_request(request)) { return true; + } n = lookup_node(name); if(!n) { logger(DEBUG_ALWAYS, LOG_ERR, "Got %s from %s (%s) origin %s which does not exist", - "KEY_CHANGED", c->name, c->hostname, name); + "KEY_CHANGED", c->name, c->hostname, name); return true; } @@ -83,8 +88,9 @@ bool key_changed_h(connection_t *c, const char *request) { /* Tell the others */ - if(!tunnelserver) + if(!tunnelserver) { forward_request(c, request); + } return true; } @@ -94,10 +100,13 @@ static bool send_sptps_data_myself(void *handle, uint8_t type, const void *data, } static bool send_initial_sptps_data(void *handle, uint8_t type, const void *data, size_t len) { + (void)type; node_t *to = handle; to->sptps.send_data = send_sptps_data_myself; char buf[len * 4 / 3 + 5]; + b64encode(data, buf, len); + return send_request(to->nexthop->connection, "%d %s %s %d %s", REQ_KEY, myself->name, to->name, REQ_KEY, buf); } @@ -110,13 +119,13 @@ bool send_req_key(node_t *to) { } char label[25 + strlen(myself->name) + strlen(to->name)]; - snprintf(label, sizeof label, "tinc UDP key expansion %s %s", myself->name, to->name); + snprintf(label, sizeof(label), "tinc UDP key expansion %s %s", myself->name, to->name); sptps_stop(&to->sptps); to->status.validkey = false; to->status.waitingforkey = true; to->last_req_key = now.tv_sec; to->incompression = myself->incompression; - return sptps_start(&to->sptps, to, true, true, myself->connection->ecdsa, to->ecdsa, label, sizeof label, send_initial_sptps_data, receive_sptps_record); + return sptps_start(&to->sptps, to, true, true, myself->connection->ecdsa, to->ecdsa, label, sizeof(label), send_initial_sptps_data, receive_sptps_record); } return send_request(to->nexthop->connection, "%d %s %s", REQ_KEY, myself->name, to->name); @@ -125,17 +134,21 @@ bool send_req_key(node_t *to) { /* REQ_KEY is overloaded to allow arbitrary requests to be routed between two nodes. */ static bool req_key_ext_h(connection_t *c, const char *request, node_t *from, node_t *to, int reqno) { + (void)c; + /* If this is a SPTPS packet, see if sending UDP info helps. Note that we only do this if we're the destination or the static relay; otherwise every hop would initiate its own UDP info message, resulting in elevated chatter. */ - if((reqno == REQ_KEY || reqno == SPTPS_PACKET) && to->via == myself) + if((reqno == REQ_KEY || reqno == SPTPS_PACKET) && to->via == myself) { send_udp_info(myself, from); + } if(reqno == SPTPS_PACKET) { /* This is a SPTPS data packet. */ char buf[MAX_STRING_SIZE]; int len; + if(sscanf(request, "%*d %*s %*s %*d " MAX_STRING, buf) != 1 || !(len = b64decode(buf, buf, strlen(buf)))) { logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s) to %s (%s): %s", "SPTPS_PACKET", from->name, from->hostname, to->name, to->hostname, "invalid SPTPS data"); return true; @@ -143,8 +156,10 @@ static bool req_key_ext_h(connection_t *c, const char *request, node_t *from, no if(to != myself) { /* We don't just forward the request, because we want to use UDP if it's available. */ - send_sptps_data(to, from, 0, buf, len); - try_tx(to, true); + if(forwarding_mode == FMODE_INTERNAL) { + send_sptps_data(to, from, 0, buf, len); + try_tx(to, true); + } } else { /* The packet is for us */ if(!sptps_receive_data(&from->sptps, buf, len)) { @@ -155,8 +170,10 @@ static bool req_key_ext_h(connection_t *c, const char *request, node_t *from, no logger(DEBUG_PROTOCOL, LOG_ERR, "Failed to decode TCP packet from %s (%s), restarting SPTPS", from->name, from->hostname); send_req_key(from); } + return true; } + send_mtu_info(myself, from, MTU); } @@ -165,74 +182,78 @@ static bool req_key_ext_h(connection_t *c, const char *request, node_t *from, no /* Requests that are not SPTPS data packets are forwarded as-is. */ - if (to != myself) + if(to != myself) { return send_request(to->nexthop->connection, "%s", request); + } /* The request is for us */ switch(reqno) { - case REQ_PUBKEY: { - if(!node_read_ecdsa_public_key(from)) { - /* Request their key *before* we send our key back. Otherwise the first SPTPS packet from them will get dropped. */ - logger(DEBUG_PROTOCOL, LOG_DEBUG, "Preemptively requesting Ed25519 key for %s (%s)", from->name, from->hostname); - send_request(from->nexthop->connection, "%d %s %s %d", REQ_KEY, myself->name, from->name, REQ_PUBKEY); - } - char *pubkey = ecdsa_get_base64_public_key(myself->connection->ecdsa); - send_request(from->nexthop->connection, "%d %s %s %d %s", REQ_KEY, myself->name, from->name, ANS_PUBKEY, pubkey); - free(pubkey); + case REQ_PUBKEY: { + if(!node_read_ecdsa_public_key(from)) { + /* Request their key *before* we send our key back. Otherwise the first SPTPS packet from them will get dropped. */ + logger(DEBUG_PROTOCOL, LOG_DEBUG, "Preemptively requesting Ed25519 key for %s (%s)", from->name, from->hostname); + send_request(from->nexthop->connection, "%d %s %s %d", REQ_KEY, myself->name, from->name, REQ_PUBKEY); + } + + char *pubkey = ecdsa_get_base64_public_key(myself->connection->ecdsa); + send_request(from->nexthop->connection, "%d %s %s %d %s", REQ_KEY, myself->name, from->name, ANS_PUBKEY, pubkey); + free(pubkey); + return true; + } + + case ANS_PUBKEY: { + if(node_read_ecdsa_public_key(from)) { + logger(DEBUG_PROTOCOL, LOG_WARNING, "Got ANS_PUBKEY from %s (%s) even though we already have his pubkey", from->name, from->hostname); return true; } - case ANS_PUBKEY: { - if(node_read_ecdsa_public_key(from)) { - logger(DEBUG_PROTOCOL, LOG_WARNING, "Got ANS_PUBKEY from %s (%s) even though we already have his pubkey", from->name, from->hostname); - return true; - } + char pubkey[MAX_STRING_SIZE]; - char pubkey[MAX_STRING_SIZE]; - if(sscanf(request, "%*d %*s %*s %*d " MAX_STRING, pubkey) != 1 || !(from->ecdsa = ecdsa_set_base64_public_key(pubkey))) { - logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s): %s", "ANS_PUBKEY", from->name, from->hostname, "invalid pubkey"); - return true; - } - - logger(DEBUG_PROTOCOL, LOG_INFO, "Learned Ed25519 public key from %s (%s)", from->name, from->hostname); - append_config_file(from->name, "Ed25519PublicKey", pubkey); + if(sscanf(request, "%*d %*s %*s %*d " MAX_STRING, pubkey) != 1 || !(from->ecdsa = ecdsa_set_base64_public_key(pubkey))) { + logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s): %s", "ANS_PUBKEY", from->name, from->hostname, "invalid pubkey"); return true; } - case REQ_KEY: { - if(!node_read_ecdsa_public_key(from)) { - logger(DEBUG_PROTOCOL, LOG_DEBUG, "No Ed25519 key known for %s (%s)", from->name, from->hostname); - send_request(from->nexthop->connection, "%d %s %s %d", REQ_KEY, myself->name, from->name, REQ_PUBKEY); - return true; - } + logger(DEBUG_PROTOCOL, LOG_INFO, "Learned Ed25519 public key from %s (%s)", from->name, from->hostname); + append_config_file(from->name, "Ed25519PublicKey", pubkey); + return true; + } - if(from->sptps.label) - logger(DEBUG_ALWAYS, LOG_DEBUG, "Got REQ_KEY from %s while we already started a SPTPS session!", from->name); - - char buf[MAX_STRING_SIZE]; - int len; - - if(sscanf(request, "%*d %*s %*s %*d " MAX_STRING, buf) != 1 || !(len = b64decode(buf, buf, strlen(buf)))) { - logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s): %s", "REQ_SPTPS_START", from->name, from->hostname, "invalid SPTPS data"); - return true; - } - - char label[25 + strlen(from->name) + strlen(myself->name)]; - snprintf(label, sizeof label, "tinc UDP key expansion %s %s", from->name, myself->name); - sptps_stop(&from->sptps); - from->status.validkey = false; - from->status.waitingforkey = true; - from->last_req_key = now.tv_sec; - sptps_start(&from->sptps, from, false, true, myself->connection->ecdsa, from->ecdsa, label, sizeof label, send_sptps_data_myself, receive_sptps_record); - sptps_receive_data(&from->sptps, buf, len); - send_mtu_info(myself, from, MTU); + case REQ_KEY: { + if(!node_read_ecdsa_public_key(from)) { + logger(DEBUG_PROTOCOL, LOG_DEBUG, "No Ed25519 key known for %s (%s)", from->name, from->hostname); + send_request(from->nexthop->connection, "%d %s %s %d", REQ_KEY, myself->name, from->name, REQ_PUBKEY); return true; } - default: - logger(DEBUG_ALWAYS, LOG_ERR, "Unknown extended REQ_KEY request from %s (%s): %s", from->name, from->hostname, request); + if(from->sptps.label) { + logger(DEBUG_ALWAYS, LOG_DEBUG, "Got REQ_KEY from %s while we already started a SPTPS session!", from->name); + } + + char buf[MAX_STRING_SIZE]; + size_t len; + + if(sscanf(request, "%*d %*s %*s %*d " MAX_STRING, buf) != 1 || !(len = b64decode(buf, buf, strlen(buf)))) { + logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s): %s", "REQ_SPTPS_START", from->name, from->hostname, "invalid SPTPS data"); return true; + } + + char label[25 + strlen(from->name) + strlen(myself->name)]; + snprintf(label, sizeof(label), "tinc UDP key expansion %s %s", from->name, myself->name); + sptps_stop(&from->sptps); + from->status.validkey = false; + from->status.waitingforkey = true; + from->last_req_key = now.tv_sec; + sptps_start(&from->sptps, from, false, true, myself->connection->ecdsa, from->ecdsa, label, sizeof(label), send_sptps_data_myself, receive_sptps_record); + sptps_receive_data(&from->sptps, buf, len); + send_mtu_info(myself, from, MTU); + return true; + } + + default: + logger(DEBUG_ALWAYS, LOG_ERR, "Unknown extended REQ_KEY request from %s (%s): %s", from->name, from->hostname, request); + return true; } } @@ -244,7 +265,7 @@ bool req_key_h(connection_t *c, const char *request) { if(sscanf(request, "%*d " MAX_STRING " " MAX_STRING " %d", from_name, to_name, &reqno) < 2) { logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "REQ_KEY", c->name, - c->hostname); + c->hostname); return false; } @@ -257,7 +278,7 @@ bool req_key_h(connection_t *c, const char *request) { if(!from) { logger(DEBUG_ALWAYS, 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); + "REQ_KEY", c->name, c->hostname, from_name); return true; } @@ -265,7 +286,7 @@ bool req_key_h(connection_t *c, const char *request) { if(!to) { logger(DEBUG_ALWAYS, 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); + "REQ_KEY", c->name, c->hostname, to_name); return true; } @@ -273,24 +294,27 @@ bool req_key_h(connection_t *c, const char *request) { if(to == myself) { /* Yes */ /* Is this an extended REQ_KEY message? */ - if(experimental && reqno) + if(experimental && reqno) { return req_key_ext_h(c, request, from, to, reqno); + } /* No, just send our key back */ send_ans_key(from); } else { - if(tunnelserver) + if(tunnelserver) { return true; + } if(!to->status.reachable) { logger(DEBUG_PROTOCOL, LOG_WARNING, "Got %s from %s (%s) destination %s which is not reachable", - "REQ_KEY", c->name, c->hostname, to_name); + "REQ_KEY", c->name, c->hostname, to_name); return true; } /* Is this an extended REQ_KEY message? */ - if(experimental && reqno) + if(experimental && reqno) { return req_key_ext_h(c, request, from, to, reqno); + } send_request(to->nexthop->connection, "%s", request); } @@ -299,8 +323,9 @@ bool req_key_h(connection_t *c, const char *request) { } bool send_ans_key(node_t *to) { - if(to->status.sptps) + if(to->status.sptps) { abort(); + } #ifdef DISABLE_LEGACY return false; @@ -315,18 +340,26 @@ bool send_ans_key(node_t *to) { if(myself->incipher) { to->incipher = cipher_open_by_nid(cipher_get_nid(myself->incipher)); - if(!to->incipher) + + if(!to->incipher) { abort(); - if(!cipher_set_key(to->incipher, key, false)) + } + + if(!cipher_set_key(to->incipher, key, false)) { abort(); + } } if(myself->indigest) { to->indigest = digest_open_by_nid(digest_get_nid(myself->indigest), digest_length(myself->indigest)); - if(!to->indigest) + + if(!to->indigest) { abort(); - if(!digest_set_key(to->indigest, key, keylen)) + } + + if(!digest_set_key(to->indigest, key, keylen)) { abort(); + } } to->incompression = myself->incompression; @@ -337,16 +370,19 @@ bool send_ans_key(node_t *to) { mykeyused = true; to->received_seqno = 0; to->received = 0; - if(replaywin) memset(to->late, 0, replaywin); + + if(replaywin) { + memset(to->late, 0, replaywin); + } to->status.validkey_in = true; return send_request(to->nexthop->connection, "%d %s %s %s %d %d %d %d", ANS_KEY, - myself->name, to->name, key, - cipher_get_nid(to->incipher), - digest_get_nid(to->indigest), - (int)digest_length(to->indigest), - to->incompression); + myself->name, to->name, key, + cipher_get_nid(to->incipher), + digest_get_nid(to->indigest), + (int)digest_length(to->indigest), + to->incompression); #endif } @@ -360,10 +396,10 @@ bool ans_key_h(connection_t *c, const char *request) { node_t *from, *to; if(sscanf(request, "%*d "MAX_STRING" "MAX_STRING" "MAX_STRING" %d %d %d %d "MAX_STRING" "MAX_STRING, - from_name, to_name, key, &cipher, &digest, &maclength, - &compression, address, port) < 7) { + from_name, to_name, key, &cipher, &digest, &maclength, + &compression, address, port) < 7) { logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "ANS_KEY", c->name, - c->hostname); + c->hostname); return false; } @@ -376,7 +412,7 @@ bool ans_key_h(connection_t *c, const char *request) { if(!from) { logger(DEBUG_ALWAYS, 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); + "ANS_KEY", c->name, c->hostname, from_name); return true; } @@ -384,19 +420,20 @@ bool ans_key_h(connection_t *c, const char *request) { if(!to) { logger(DEBUG_ALWAYS, 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); + "ANS_KEY", c->name, c->hostname, to_name); return true; } /* Forward it if necessary */ if(to != myself) { - if(tunnelserver) + if(tunnelserver) { return true; + } if(!to->status.reachable) { logger(DEBUG_ALWAYS, LOG_WARNING, "Got %s from %s (%s) destination %s which is not reachable", - "ANS_KEY", c->name, c->hostname, to_name); + "ANS_KEY", c->name, c->hostname, to_name); return true; } @@ -418,7 +455,10 @@ bool ans_key_h(connection_t *c, const char *request) { cipher_close(from->outcipher); digest_close(from->outdigest); #endif - if (!from->status.sptps) from->status.validkey = false; + + if(!from->status.sptps) { + from->status.validkey = false; + } if(compression < 0 || compression > 11) { logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses bogus compression level!", from->name, from->hostname); @@ -431,7 +471,8 @@ bool ans_key_h(connection_t *c, const char *request) { if(from->status.sptps) { char buf[strlen(key)]; - int len = b64decode(key, buf, strlen(key)); + size_t len = b64decode(key, buf, strlen(key)); + if(!len || !sptps_receive_data(&from->sptps, buf, len)) { /* Uh-oh. It might be that the tunnel is stuck in some corrupted state, so let's restart SPTPS in case that helps. But don't do that too often @@ -442,6 +483,7 @@ bool ans_key_h(connection_t *c, const char *request) { logger(DEBUG_PROTOCOL, LOG_ERR, "Failed to decode handshake TCP packet from %s (%s), restarting SPTPS", from->name, from->hostname); send_req_key(from); } + return true; } @@ -482,14 +524,14 @@ bool ans_key_h(connection_t *c, const char *request) { from->outdigest = NULL; } - if(maclength != digest_length(from->outdigest)) { + if((size_t)maclength != digest_length(from->outdigest)) { logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses bogus MAC length!", from->name, from->hostname); return false; } /* Process key */ - int keylen = hex2bin(key, key, sizeof key); + size_t keylen = hex2bin(key, key, sizeof(key)); if(keylen != (from->outcipher ? cipher_keylength(from->outcipher) : 1)) { logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses wrong keylength!", from->name, from->hostname); @@ -498,10 +540,13 @@ bool ans_key_h(connection_t *c, const char *request) { /* Update our copy of the origin's packet key */ - if(from->outcipher && !cipher_set_key(from->outcipher, key, true)) + if(from->outcipher && !cipher_set_key(from->outcipher, key, true)) { return false; - if(from->outdigest && !digest_set_key(from->outdigest, key, keylen)) + } + + if(from->outdigest && !digest_set_key(from->outdigest, key, keylen)) { return false; + } from->status.validkey = true; from->sent_seqno = 0; diff --git a/src/protocol_misc.c b/src/protocol_misc.c index 05a4ada..a4fcd6f 100644 --- a/src/protocol_misc.c +++ b/src/protocol_misc.c @@ -20,6 +20,7 @@ #include "system.h" +#include "address_cache.h" #include "conf.h" #include "connection.h" #include "logger.h" @@ -38,59 +39,13 @@ int maxoutbufsize = 0; int mtu_info_interval = 5; int udp_info_interval = 5; -/* Status and error notification routines */ - -bool send_status(connection_t *c, int statusno, const char *statusstring) { - if(!statusstring) - statusstring = "Status"; - - return send_request(c, "%d %d %s", STATUS, statusno, statusstring); -} - -bool status_h(connection_t *c, const char *request) { - int statusno; - char statusstring[MAX_STRING_SIZE]; - - if(sscanf(request, "%*d %d " MAX_STRING, &statusno, statusstring) != 2) { - logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "STATUS", - c->name, c->hostname); - return false; - } - - logger(DEBUG_STATUS, LOG_NOTICE, "Status message from %s (%s): %d: %s", - c->name, c->hostname, statusno, statusstring); - - return true; -} - -bool send_error(connection_t *c, int err, const char *errstring) { - if(!errstring) - errstring = "Error"; - - return send_request(c, "%d %d %s", ERROR, err, errstring); -} - -bool error_h(connection_t *c, const char *request) { - int err; - char errorstring[MAX_STRING_SIZE]; - - if(sscanf(request, "%*d %d " MAX_STRING, &err, errorstring) != 2) { - logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "ERROR", - c->name, c->hostname); - return false; - } - - logger(DEBUG_ERROR, LOG_NOTICE, "Error message from %s (%s): %d: %s", - c->name, c->hostname, err, errorstring); - - return false; -} - bool send_termreq(connection_t *c) { return send_request(c, "%d", TERMREQ); } bool termreq_h(connection_t *c, const char *request) { + (void)c; + (void)request; return false; } @@ -102,6 +57,7 @@ bool send_ping(connection_t *c) { } bool ping_h(connection_t *c, const char *request) { + (void)request; return send_pong(c); } @@ -110,17 +66,14 @@ bool send_pong(connection_t *c) { } bool pong_h(connection_t *c, const char *request) { + (void)request; c->status.pinged = false; - /* Succesful connection, reset timeout if this is an outgoing connection. */ + /* Successful connection, reset timeout if this is an outgoing connection. */ if(c->outgoing) { c->outgoing->timeout = 0; - c->outgoing->cfg = NULL; - if(c->outgoing->ai) - freeaddrinfo(c->outgoing->ai); - c->outgoing->ai = NULL; - c->outgoing->aip = NULL; + reset_address_cache(c->outgoing->address_cache, &c->address); } return true; @@ -132,11 +85,13 @@ bool send_tcppacket(connection_t *c, const vpn_packet_t *packet) { /* If there already is a lot of data in the outbuf buffer, discard this packet. We use a very simple Random Early Drop algorithm. */ - if(2.0 * c->outbuf.len / (float)maxoutbufsize - 1 > (float)rand()/(float)RAND_MAX) + if(2.0 * c->outbuf.len / (float)maxoutbufsize - 1 > (float)rand() / (float)RAND_MAX) { return true; + } - if(!send_request(c, "%d %d", PACKET, packet->len)) + if(!send_request(c, "%d %d", PACKET, packet->len)) { return false; + } return send_meta(c, (char *)DATA(packet), packet->len); } @@ -146,7 +101,7 @@ bool tcppacket_h(connection_t *c, const char *request) { if(sscanf(request, "%*d %hd", &len) != 1) { logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "PACKET", c->name, - c->hostname); + c->hostname); return false; } @@ -157,26 +112,28 @@ bool tcppacket_h(connection_t *c, const char *request) { return true; } -bool send_sptps_tcppacket(connection_t *c, const char* packet, int len) { +bool send_sptps_tcppacket(connection_t *c, const char *packet, int len) { /* If there already is a lot of data in the outbuf buffer, discard this packet. We use a very simple Random Early Drop algorithm. */ - if(2.0 * c->outbuf.len / (float)maxoutbufsize - 1 > (float)rand()/(float)RAND_MAX) + if(2.0 * c->outbuf.len / (float)maxoutbufsize - 1 > (float)rand() / (float)RAND_MAX) { return true; + } - if(!send_request(c, "%d %d", SPTPS_PACKET, len)) + if(!send_request(c, "%d %d", SPTPS_PACKET, len)) { return false; + } send_meta_raw(c, packet, len); return true; } -bool sptps_tcppacket_h(connection_t *c, const char* request) { +bool sptps_tcppacket_h(connection_t *c, const char *request) { short int len; if(sscanf(request, "%*d %hd", &len) != 1) { logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "SPTPS_PACKET", c->name, - c->hostname); + c->hostname); return false; } @@ -194,7 +151,7 @@ bool send_udp_info(node_t *from, node_t *to) { farther than the static relay. */ to = (to->via == myself) ? to->nexthop : to->via; - if (to == NULL) { + if(to == NULL) { logger(DEBUG_ALWAYS, LOG_ERR, "Something went wrong when selecting relay - possible fake UDP_INFO"); return false; } @@ -202,27 +159,35 @@ bool send_udp_info(node_t *from, node_t *to) { /* Skip cases where sending UDP info messages doesn't make sense. This is done here in order to avoid repeating the same logic in multiple callsites. */ - if(to == myself) + if(to == myself) { return true; - - if(!to->status.reachable) - return true; - - if(from == myself) { - if(to->connection) - return true; - - struct timeval elapsed; - timersub(&now, &to->udp_info_sent, &elapsed); - if(elapsed.tv_sec < udp_info_interval) - return true; } - if((myself->options | from->options | to->options) & OPTION_TCPONLY) + if(!to->status.reachable) { return true; + } - if((to->nexthop->options >> 24) < 5) + if(from == myself) { + if(to->connection) { + return true; + } + + struct timeval elapsed; + + timersub(&now, &to->udp_info_sent, &elapsed); + + if(elapsed.tv_sec < udp_info_interval) { + return true; + } + } + + if((myself->options | from->options | to->options) & OPTION_TCPONLY) { return true; + } + + if((to->nexthop->options >> 24) < 5) { + return true; + } char *from_address, *from_port; /* If we're the originator, the address we use is irrelevant @@ -236,13 +201,14 @@ bool send_udp_info(node_t *from, node_t *to) { free(from_address); free(from_port); - if(from == myself) + if(from == myself) { to->udp_info_sent = now; + } return x; } -bool udp_info_h(connection_t *c, const char* request) { +bool udp_info_h(connection_t *c, const char *request) { char from_name[MAX_STRING_SIZE]; char to_name[MAX_STRING_SIZE]; char from_address[MAX_STRING_SIZE]; @@ -259,6 +225,7 @@ bool udp_info_h(connection_t *c, const char* request) { } node_t *from = lookup_node(from_name); + if(!from) { logger(DEBUG_ALWAYS, LOG_ERR, "Got %s from %s (%s) origin %s which does not exist in our connection list", "UDP_INFO", c->name, c->hostname, from_name); return true; @@ -274,11 +241,14 @@ bool udp_info_h(connection_t *c, const char* request) { to guess its address than it is itself. */ if(!from->connection && !from->status.udp_confirmed) { sockaddr_t from_addr = str2sockaddr(from_address, from_port); - if(sockaddrcmp(&from_addr, &from->address)) + + if(sockaddrcmp(&from_addr, &from->address)) { update_node_udp(from, &from_addr); + } } node_t *to = lookup_node(to_name); + if(!to) { logger(DEBUG_ALWAYS, LOG_ERR, "Got %s from %s (%s) destination %s which does not exist in our connection list", "UDP_INFO", c->name, c->hostname, to_name); return true; @@ -295,28 +265,36 @@ bool send_mtu_info(node_t *from, node_t *to, int mtu) { /* Skip cases where sending MTU info messages doesn't make sense. This is done here in order to avoid repeating the same logic in multiple callsites. */ - if(to == myself) + if(to == myself) { return true; - - if(!to->status.reachable) - return true; - - if(from == myself) { - if(to->connection) - return true; - - struct timeval elapsed; - timersub(&now, &to->mtu_info_sent, &elapsed); - if(elapsed.tv_sec < mtu_info_interval) - return true; } - if((to->nexthop->options >> 24) < 6) + if(!to->status.reachable) { return true; + } + + if(from == myself) { + if(to->connection) { + return true; + } + + struct timeval elapsed; + + timersub(&now, &to->mtu_info_sent, &elapsed); + + if(elapsed.tv_sec < mtu_info_interval) { + return true; + } + } + + if((to->nexthop->options >> 24) < 6) { + return true; + } /* We will send the passed-in MTU value, unless we believe ours is better. */ node_t *via = (from->via == myself) ? from->nexthop : from->via; + if(from->minmtu == from->maxmtu && from->via == myself) { /* We have a direct measurement. Override the value entirely. Note that we only do that if we are sitting as a static relay in the path; @@ -331,8 +309,9 @@ bool send_mtu_info(node_t *from, node_t *to, int mtu) { mtu = MIN(mtu, via->nexthop->minmtu); } - if(from == myself) + if(from == myself) { to->mtu_info_sent = now; + } /* If none of the conditions above match in the steady state, it means we're using TCP, so the MTU is irrelevant. That said, it is still important to honor the MTU that was passed in, @@ -341,7 +320,7 @@ bool send_mtu_info(node_t *from, node_t *to, int mtu) { return send_request(to->nexthop->connection, "%d %s %s %d", MTU_INFO, from->name, to->name, mtu); } -bool mtu_info_h(connection_t *c, const char* request) { +bool mtu_info_h(connection_t *c, const char *request) { char from_name[MAX_STRING_SIZE]; char to_name[MAX_STRING_SIZE]; int mtu; @@ -364,6 +343,7 @@ bool mtu_info_h(connection_t *c, const char* request) { } node_t *from = lookup_node(from_name); + if(!from) { logger(DEBUG_ALWAYS, LOG_ERR, "Got %s from %s (%s) origin %s which does not exist in our connection list", "MTU_INFO", c->name, c->hostname, from_name); return true; @@ -378,6 +358,7 @@ bool mtu_info_h(connection_t *c, const char* request) { } node_t *to = lookup_node(to_name); + if(!to) { logger(DEBUG_ALWAYS, LOG_ERR, "Got %s from %s (%s) destination %s which does not exist in our connection list", "MTU_INFO", c->name, c->hostname, to_name); return true; diff --git a/src/protocol_subnet.c b/src/protocol_subnet.c index 06dafbc..53afb8a 100644 --- a/src/protocol_subnet.c +++ b/src/protocol_subnet.c @@ -35,8 +35,9 @@ bool send_add_subnet(connection_t *c, const subnet_t *subnet) { char netstr[MAXNETSTR]; - if(!net2str(netstr, sizeof netstr, subnet)) + if(!net2str(netstr, sizeof(netstr), subnet)) { return false; + } return send_request(c, "%d %x %s %s", ADD_SUBNET, rand(), subnet->owner->name, netstr); } @@ -45,11 +46,11 @@ bool add_subnet_h(connection_t *c, const char *request) { char subnetstr[MAX_STRING_SIZE]; char name[MAX_STRING_SIZE]; node_t *owner; - subnet_t s = {NULL}, *new, *old; + subnet_t s = {0}, *new, *old; if(sscanf(request, "%*d %*x " MAX_STRING " " MAX_STRING, name, subnetstr) != 2) { logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "ADD_SUBNET", c->name, - c->hostname); + c->hostname); return false; } @@ -57,7 +58,7 @@ bool add_subnet_h(connection_t *c, const char *request) { if(!check_id(name)) { logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s): %s", "ADD_SUBNET", c->name, - c->hostname, "invalid name"); + c->hostname, "invalid name"); return false; } @@ -65,12 +66,13 @@ bool add_subnet_h(connection_t *c, const char *request) { if(!str2net(&s, subnetstr)) { logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s): %s", "ADD_SUBNET", c->name, - c->hostname, "invalid subnet string"); + c->hostname, "invalid subnet string"); return false; } - if(seen_request(request)) + if(seen_request(request)) { return true; + } /* Check if the owner of the new subnet is in the connection list */ @@ -79,7 +81,7 @@ bool add_subnet_h(connection_t *c, const char *request) { if(tunnelserver && owner != myself && owner != c->node) { /* in case of tunnelserver, ignore indirect subnet registrations */ logger(DEBUG_PROTOCOL, LOG_WARNING, "Ignoring indirect %s from %s (%s) for %s", - "ADD_SUBNET", c->name, c->hostname, subnetstr); + "ADD_SUBNET", c->name, c->hostname, subnetstr); return true; } @@ -91,14 +93,15 @@ bool add_subnet_h(connection_t *c, const char *request) { /* Check if we already know this subnet */ - if(lookup_subnet(owner, &s)) + if(lookup_subnet(owner, &s)) { return true; + } /* If we don't know this subnet, but we are the owner, retaliate with a DEL_SUBNET */ if(owner == myself) { logger(DEBUG_PROTOCOL, LOG_WARNING, "Got %s from %s (%s) for ourself", - "ADD_SUBNET", c->name, c->hostname); + "ADD_SUBNET", c->name, c->hostname); s.owner = myself; send_del_subnet(c, &s); return true; @@ -108,7 +111,7 @@ bool add_subnet_h(connection_t *c, const char *request) { if(tunnelserver) { logger(DEBUG_ALWAYS, LOG_WARNING, "Ignoring unauthorized %s from %s (%s): %s", - "ADD_SUBNET", c->name, c->hostname, subnetstr); + "ADD_SUBNET", c->name, c->hostname, subnetstr); return true; } @@ -116,7 +119,7 @@ bool add_subnet_h(connection_t *c, const char *request) { if(strictsubnets) { logger(DEBUG_ALWAYS, LOG_WARNING, "Ignoring unauthorized %s from %s (%s): %s", - "ADD_SUBNET", c->name, c->hostname, subnetstr); + "ADD_SUBNET", c->name, c->hostname, subnetstr); forward_request(c, request); return true; } @@ -126,18 +129,21 @@ bool add_subnet_h(connection_t *c, const char *request) { *(new = new_subnet()) = s; subnet_add(owner, new); - if(owner->status.reachable) + if(owner->status.reachable) { subnet_update(owner, new, true); + } /* Tell the rest */ - if(!tunnelserver) + if(!tunnelserver) { forward_request(c, request); + } /* Fast handoff of roaming MAC addresses */ - if(s.type == SUBNET_MAC && owner != myself && (old = lookup_subnet(myself, &s)) && old->expires) + if(s.type == SUBNET_MAC && owner != myself && (old = lookup_subnet(myself, &s)) && old->expires) { old->expires = 1; + } return true; } @@ -145,8 +151,9 @@ bool add_subnet_h(connection_t *c, const char *request) { bool send_del_subnet(connection_t *c, const subnet_t *s) { char netstr[MAXNETSTR]; - if(!net2str(netstr, sizeof netstr, s)) + if(!net2str(netstr, sizeof(netstr), s)) { return false; + } return send_request(c, "%d %x %s %s", DEL_SUBNET, rand(), s->owner->name, netstr); } @@ -155,11 +162,11 @@ bool del_subnet_h(connection_t *c, const char *request) { char subnetstr[MAX_STRING_SIZE]; char name[MAX_STRING_SIZE]; node_t *owner; - subnet_t s = {NULL}, *find; + subnet_t s = {0}, *find; if(sscanf(request, "%*d %*x " MAX_STRING " " MAX_STRING, name, subnetstr) != 2) { logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "DEL_SUBNET", c->name, - c->hostname); + c->hostname); return false; } @@ -167,7 +174,7 @@ bool del_subnet_h(connection_t *c, const char *request) { if(!check_id(name)) { logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s): %s", "DEL_SUBNET", c->name, - c->hostname, "invalid name"); + c->hostname, "invalid name"); return false; } @@ -175,12 +182,13 @@ bool del_subnet_h(connection_t *c, const char *request) { if(!str2net(&s, subnetstr)) { logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s): %s", "DEL_SUBNET", c->name, - c->hostname, "invalid subnet string"); + c->hostname, "invalid subnet string"); return false; } - if(seen_request(request)) + if(seen_request(request)) { return true; + } /* Check if the owner of the subnet being deleted is in the connection list */ @@ -189,13 +197,13 @@ bool del_subnet_h(connection_t *c, const char *request) { if(tunnelserver && owner != myself && owner != c->node) { /* in case of tunnelserver, ignore indirect subnet deletion */ logger(DEBUG_PROTOCOL, LOG_WARNING, "Ignoring indirect %s from %s (%s) for %s", - "DEL_SUBNET", c->name, c->hostname, subnetstr); + "DEL_SUBNET", c->name, c->hostname, subnetstr); return true; } if(!owner) { logger(DEBUG_PROTOCOL, LOG_WARNING, "Got %s from %s (%s) for %s which is not in our node tree", - "DEL_SUBNET", c->name, c->hostname, name); + "DEL_SUBNET", c->name, c->hostname, name); return true; } @@ -207,9 +215,12 @@ bool del_subnet_h(connection_t *c, const char *request) { if(!find) { logger(DEBUG_PROTOCOL, 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) + "DEL_SUBNET", c->name, c->hostname, name); + + if(strictsubnets) { forward_request(c, request); + } + return true; } @@ -217,25 +228,30 @@ bool del_subnet_h(connection_t *c, const char *request) { if(owner == myself) { logger(DEBUG_PROTOCOL, LOG_WARNING, "Got %s from %s (%s) for ourself", - "DEL_SUBNET", c->name, c->hostname); + "DEL_SUBNET", c->name, c->hostname); send_add_subnet(c, find); return true; } - if(tunnelserver) + if(tunnelserver) { return true; + } /* Tell the rest */ - if(!tunnelserver) + if(!tunnelserver) { forward_request(c, request); - if(strictsubnets) + } + + if(strictsubnets) { return true; + } /* Finally, delete it. */ - if(owner->status.reachable) + if(owner->status.reachable) { subnet_update(owner, find, false); + } subnet_del(owner, find); diff --git a/src/raw_socket_device.c b/src/raw_socket_device.c index eb38be2..02f6afa 100644 --- a/src/raw_socket_device.c +++ b/src/raw_socket_device.c @@ -33,46 +33,48 @@ #include "xalloc.h" #if defined(PF_PACKET) && defined(ETH_P_ALL) && defined(AF_PACKET) && defined(SIOCGIFINDEX) -static char *device_info; +static const char *device_info = "raw_socket"; static bool setup_device(void) { struct ifreq ifr; struct sockaddr_ll sa; - if(!get_config_string(lookup_config(config_tree, "Interface"), &iface)) + if(!get_config_string(lookup_config(config_tree, "Interface"), &iface)) { iface = xstrdup("eth0"); + } - if(!get_config_string(lookup_config(config_tree, "Device"), &device)) + if(!get_config_string(lookup_config(config_tree, "Device"), &device)) { device = xstrdup(iface); - - device_info = "raw socket"; + } if((device_fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL))) < 0) { logger(DEBUG_ALWAYS, LOG_ERR, "Could not open %s: %s", device_info, - strerror(errno)); + strerror(errno)); return false; } - memset(&ifr, 0, sizeof ifr); + memset(&ifr, 0, sizeof(ifr)); #ifdef FD_CLOEXEC fcntl(device_fd, F_SETFD, FD_CLOEXEC); #endif strncpy(ifr.ifr_ifrn.ifrn_name, iface, IFNAMSIZ); + ifr.ifr_ifrn.ifrn_name[IFNAMSIZ - 1] = 0; + if(ioctl(device_fd, SIOCGIFINDEX, &ifr)) { close(device_fd); logger(DEBUG_ALWAYS, LOG_ERR, "Can't find interface %s: %s", iface, - strerror(errno)); + strerror(errno)); return false; } - memset(&sa, '0', sizeof sa); + memset(&sa, '0', sizeof(sa)); sa.sll_family = AF_PACKET; sa.sll_protocol = htons(ETH_P_ALL); sa.sll_ifindex = ifr.ifr_ifindex; - if(bind(device_fd, (struct sockaddr *) &sa, (socklen_t) sizeof sa)) { + if(bind(device_fd, (struct sockaddr *) &sa, (socklen_t) sizeof(sa))) { logger(DEBUG_ALWAYS, LOG_ERR, "Could not bind %s to %s: %s", device, iface, strerror(errno)); return false; } @@ -83,10 +85,13 @@ static bool setup_device(void) { } static void close_device(void) { - close(device_fd); device_fd = -1; + close(device_fd); + device_fd = -1; - free(device); device = NULL; - free(iface); iface = NULL; + free(device); + device = NULL; + free(iface); + iface = NULL; device_info = NULL; } @@ -95,25 +100,25 @@ static bool read_packet(vpn_packet_t *packet) { if((inlen = read(device_fd, DATA(packet), MTU)) <= 0) { logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info, - device, strerror(errno)); + device, strerror(errno)); return false; } packet->len = inlen; logger(DEBUG_TRAFFIC, LOG_DEBUG, "Read packet of %d bytes from %s", packet->len, - device_info); + device_info); return true; } static bool write_packet(vpn_packet_t *packet) { logger(DEBUG_TRAFFIC, LOG_DEBUG, "Writing packet of %d bytes to %s", - packet->len, device_info); + packet->len, device_info); if(write(device_fd, DATA(packet), packet->len) < 0) { logger(DEBUG_ALWAYS, LOG_ERR, "Can't write to %s %s: %s", device_info, device, - strerror(errno)); + strerror(errno)); return false; } diff --git a/src/route.c b/src/route.c index 7ae4960..dcc6f3c 100644 --- a/src/route.c +++ b/src/route.c @@ -59,6 +59,7 @@ static const size_t opt_size = sizeof(struct nd_opt_hdr); #define MAX(a, b) ((a) > (b) ? (a) : (b)) #endif +volatile int dummy; static timeout_t age_subnets_timeout; /* RFC 1071 */ @@ -72,11 +73,18 @@ static uint16_t inet_checksum(void *data, int len, uint16_t prevsum) { len -= 2; } - if(len) + if(len) { checksum += *(uint8_t *)p; + } - while(checksum >> 16) + while(checksum >> 16) { checksum = (checksum & 0xFFFF) + (checksum >> 16); + } + + // Work around a compiler optimization bug. + if(checksum) { + dummy = 1; + } return ~checksum; } @@ -86,8 +94,9 @@ static bool ratelimit(int frequency) { static int count = 0; if(lasttime == now.tv_sec) { - if(count >= frequency) + if(count >= frequency) { return true; + } } else { lasttime = now.tv_sec; count = 0; @@ -101,15 +110,16 @@ static bool checklength(node_t *source, vpn_packet_t *packet, length_t length) { if(packet->len < length) { logger(DEBUG_TRAFFIC, LOG_WARNING, "Got too short packet from %s (%s)", source->name, source->hostname); return false; - } else + } else { return true; + } } static void swap_mac_addresses(vpn_packet_t *packet) { mac_t tmp; - memcpy(&tmp, &DATA(packet)[0], sizeof tmp); - memcpy(&DATA(packet)[0], &DATA(packet)[6], sizeof tmp); - memcpy(&DATA(packet)[6], &tmp, sizeof tmp); + memcpy(&tmp, &DATA(packet)[0], sizeof(tmp)); + memcpy(&DATA(packet)[0], &DATA(packet)[6], sizeof(tmp)); + memcpy(&DATA(packet)[6], &tmp, sizeof(tmp)); } /* RFC 792 */ @@ -122,8 +132,9 @@ static void route_ipv4_unreachable(node_t *source, vpn_packet_t *packet, length_ struct in_addr ip_dst; uint32_t oldlen; - if(ratelimit(3)) + if(ratelimit(3)) { return; + } /* Swap Ethernet source and destination addresses */ @@ -140,32 +151,38 @@ static void route_ipv4_unreachable(node_t *source, vpn_packet_t *packet, length_ /* Try to reply with an IP address assigned to the local machine */ - if (type == ICMP_TIME_EXCEEDED && code == ICMP_EXC_TTL) { + if(type == ICMP_TIME_EXCEEDED && code == ICMP_EXC_TTL) { int sockfd = socket(AF_INET, SOCK_DGRAM, 0); - if (sockfd != -1) { + + if(sockfd != -1) { struct sockaddr_in addr; memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; addr.sin_addr = ip.ip_src; - if (!connect(sockfd, (const struct sockaddr*) &addr, sizeof(addr))) { + + if(!connect(sockfd, (const struct sockaddr *) &addr, sizeof(addr))) { memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; socklen_t addrlen = sizeof(addr); - if (!getsockname(sockfd, (struct sockaddr*) &addr, &addrlen) && addrlen <= sizeof(addr)) { + + if(!getsockname(sockfd, (struct sockaddr *) &addr, &addrlen) && addrlen <= sizeof(addr)) { ip_dst = addr.sin_addr; } } + close(sockfd); } } oldlen = packet->len - ether_size; - if(type == ICMP_DEST_UNREACH && code == ICMP_FRAG_NEEDED) + if(type == ICMP_DEST_UNREACH && code == ICMP_FRAG_NEEDED) { icmp.icmp_nextmtu = htons(packet->len - ether_size); + } - if(oldlen >= IP_MSS - ip_size - icmp_size) + if(oldlen >= IP_MSS - ip_size - icmp_size) { oldlen = IP_MSS - ip_size - icmp_size; + } /* Copy first part of original contents to ICMP message */ @@ -220,8 +237,9 @@ static void route_ipv6_unreachable(node_t *source, vpn_packet_t *packet, length_ uint32_t next; } pseudo; - if(ratelimit(3)) + if(ratelimit(3)) { return; + } /* Swap Ethernet source and destination addresses */ @@ -238,32 +256,38 @@ static void route_ipv6_unreachable(node_t *source, vpn_packet_t *packet, length_ /* Try to reply with an IP address assigned to the local machine */ - if (type == ICMP6_TIME_EXCEEDED && code == ICMP6_TIME_EXCEED_TRANSIT) { + if(type == ICMP6_TIME_EXCEEDED && code == ICMP6_TIME_EXCEED_TRANSIT) { int sockfd = socket(AF_INET6, SOCK_DGRAM, 0); - if (sockfd != -1) { + + if(sockfd != -1) { struct sockaddr_in6 addr; memset(&addr, 0, sizeof(addr)); addr.sin6_family = AF_INET6; addr.sin6_addr = ip6.ip6_src; - if (!connect(sockfd, (const struct sockaddr*) &addr, sizeof(addr))) { + + if(!connect(sockfd, (const struct sockaddr *) &addr, sizeof(addr))) { memset(&addr, 0, sizeof(addr)); addr.sin6_family = AF_INET6; socklen_t addrlen = sizeof(addr); - if (!getsockname(sockfd, (struct sockaddr*) &addr, &addrlen) && addrlen <= sizeof(addr)) { + + if(!getsockname(sockfd, (struct sockaddr *) &addr, &addrlen) && addrlen <= sizeof(addr)) { pseudo.ip6_src = addr.sin6_addr; } } + close(sockfd); } } pseudo.length = packet->len - ether_size; - if(type == ICMP6_PACKET_TOO_BIG) + if(type == ICMP6_PACKET_TOO_BIG) { icmp6.icmp6_mtu = htonl(pseudo.length); + } - if(pseudo.length >= IP_MSS - ip6_size - icmp6_size) + if(pseudo.length >= IP_MSS - ip6_size - icmp6_size) { pseudo.length = IP_MSS - ip6_size - icmp6_size; + } /* Copy first part of original contents to ICMP message */ @@ -291,7 +315,7 @@ static void route_ipv6_unreachable(node_t *source, vpn_packet_t *packet, length_ /* Generate checksum */ - checksum = inet_checksum(&pseudo, sizeof pseudo, ~0); + checksum = inet_checksum(&pseudo, sizeof(pseudo), ~0); checksum = inet_checksum(&icmp6, icmp6_size, checksum); checksum = inet_checksum(DATA(packet) + ether_size + ip6_size + icmp6_size, ntohl(pseudo.length) - icmp6_size, checksum); @@ -316,56 +340,68 @@ static bool do_decrement_ttl(node_t *source, vpn_packet_t *packet) { ethlen += 4; } - switch (type) { - case ETH_P_IP: - if(!checklength(source, packet, ethlen + ip_size)) - return false; + switch(type) { + case ETH_P_IP: + if(!checklength(source, packet, ethlen + ip_size)) { + return false; + } - if(DATA(packet)[ethlen + 8] <= 1) { - if(DATA(packet)[ethlen + 11] != IPPROTO_ICMP || DATA(packet)[ethlen + 32] != ICMP_TIME_EXCEEDED) - route_ipv4_unreachable(source, packet, ethlen, ICMP_TIME_EXCEEDED, ICMP_EXC_TTL); - return false; + if(DATA(packet)[ethlen + 8] <= 1) { + if(DATA(packet)[ethlen + 11] != IPPROTO_ICMP || DATA(packet)[ethlen + 32] != ICMP_TIME_EXCEEDED) { + route_ipv4_unreachable(source, packet, ethlen, ICMP_TIME_EXCEEDED, ICMP_EXC_TTL); } - uint16_t old = DATA(packet)[ethlen + 8] << 8 | DATA(packet)[ethlen + 9]; - DATA(packet)[ethlen + 8]--; - uint16_t new = DATA(packet)[ethlen + 8] << 8 | DATA(packet)[ethlen + 9]; + return false; + } - uint32_t checksum = DATA(packet)[ethlen + 10] << 8 | DATA(packet)[ethlen + 11]; - checksum += old + (~new & 0xFFFF); - while(checksum >> 16) - checksum = (checksum & 0xFFFF) + (checksum >> 16); - DATA(packet)[ethlen + 10] = checksum >> 8; - DATA(packet)[ethlen + 11] = checksum & 0xff; + uint16_t old = DATA(packet)[ethlen + 8] << 8 | DATA(packet)[ethlen + 9]; + DATA(packet)[ethlen + 8]--; + uint16_t new = DATA(packet)[ethlen + 8] << 8 | DATA(packet)[ethlen + 9]; - return true; + uint32_t checksum = DATA(packet)[ethlen + 10] << 8 | DATA(packet)[ethlen + 11]; + checksum += old + (~new & 0xFFFF); - case ETH_P_IPV6: - if(!checklength(source, packet, ethlen + ip6_size)) - return false; + while(checksum >> 16) { + checksum = (checksum & 0xFFFF) + (checksum >> 16); + } - if(DATA(packet)[ethlen + 7] <= 1) { - if(DATA(packet)[ethlen + 6] != IPPROTO_ICMPV6 || DATA(packet)[ethlen + 40] != ICMP6_TIME_EXCEEDED) - route_ipv6_unreachable(source, packet, ethlen, ICMP6_TIME_EXCEEDED, ICMP6_TIME_EXCEED_TRANSIT); - return false; + DATA(packet)[ethlen + 10] = checksum >> 8; + DATA(packet)[ethlen + 11] = checksum & 0xff; + + return true; + + case ETH_P_IPV6: + if(!checklength(source, packet, ethlen + ip6_size)) { + return false; + } + + if(DATA(packet)[ethlen + 7] <= 1) { + if(DATA(packet)[ethlen + 6] != IPPROTO_ICMPV6 || DATA(packet)[ethlen + 40] != ICMP6_TIME_EXCEEDED) { + route_ipv6_unreachable(source, packet, ethlen, ICMP6_TIME_EXCEEDED, ICMP6_TIME_EXCEED_TRANSIT); } - DATA(packet)[ethlen + 7]--; + return false; + } - return true; + DATA(packet)[ethlen + 7]--; - default: - return true; + return true; + + default: + return true; } } static void clamp_mss(const node_t *source, const node_t *via, vpn_packet_t *packet) { - if(!source || !via || !(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) + + if(via != myself && via->mtu < mtu) { mtu = via->mtu; + } /* Find TCP header */ int start = ether_size; @@ -376,52 +412,70 @@ static void clamp_mss(const node_t *source, const node_t *via, vpn_packet_t *pac type = DATA(packet)[16] << 8 | DATA(packet)[17]; } - if(type == ETH_P_IP && DATA(packet)[start + 9] == 6) - start += (DATA(packet)[start] & 0xf) * 4; - else if(type == ETH_P_IPV6 && DATA(packet)[start + 6] == 6) - start += 40; - else - return; + /* IP in IP (RFC 2003) packet */ + if(type == ETH_P_IP && DATA(packet)[start + 9] == 4) { + start += 20; + } - if(packet->len <= start + 20) + if(packet->len <= start + 20) { return; + } + + if(type == ETH_P_IP && DATA(packet)[start + 9] == 6) { + start += (DATA(packet)[start] & 0xf) * 4; + } else if(type == ETH_P_IPV6 && DATA(packet)[start + 6] == 6) { + start += 40; + } else { + return; + } + + if(packet->len <= start + 20) { + return; + } /* Use data offset field to calculate length of options field */ int len = ((DATA(packet)[start + 12] >> 4) - 5) * 4; - if(packet->len < start + 20 + len) + if(packet->len < start + 20 + len) { return; + } /* Search for MSS option header */ for(int i = 0; i < len;) { - if(DATA(packet)[start + 20 + i] == 0) + if(DATA(packet)[start + 20 + i] == 0) { break; + } if(DATA(packet)[start + 20 + i] == 1) { i++; continue; } - if(i > len - 2 || i > len - DATA(packet)[start + 21 + i]) + if(i > len - 2 || i > len - DATA(packet)[start + 21 + i]) { break; + } if(DATA(packet)[start + 20 + i] != 2) { - if(DATA(packet)[start + 21 + i] < 2) + if(DATA(packet)[start + 21 + i] < 2) { break; + } + i += DATA(packet)[start + 21 + i]; continue; } - if(DATA(packet)[start + 21] != 4) + if(DATA(packet)[start + 21] != 4) { break; + } /* Found it */ uint16_t oldmss = DATA(packet)[start + 22 + i] << 8 | DATA(packet)[start + 23 + i]; uint16_t newmss = mtu - start - 20; uint32_t csum = DATA(packet)[start + 16] << 8 | DATA(packet)[start + 17]; - if(oldmss <= newmss) + if(oldmss <= newmss) { break; + } logger(DEBUG_TRAFFIC, LOG_INFO, "Clamping MSS of packet from %s to %s to %d", source->name, via->name, newmss); @@ -441,29 +495,36 @@ static void clamp_mss(const node_t *source, const node_t *via, vpn_packet_t *pac } static void age_subnets(void *data) { + (void)data; bool left = false; for splay_each(subnet_t, s, myself->subnet_tree) { if(s->expires && s->expires < now.tv_sec) { if(debug_level >= DEBUG_TRAFFIC) { char netstr[MAXNETSTR]; - if(net2str(netstr, sizeof netstr, s)) + + if(net2str(netstr, sizeof(netstr), s)) { logger(DEBUG_TRAFFIC, LOG_INFO, "Subnet %s expired", netstr); + } } for list_each(connection_t, c, connection_list) - if(c->edge) + if(c->edge) { send_del_subnet(c, s); + } subnet_del(myself, s); } else { - if(s->expires) + if(s->expires) { left = true; + } } } if(left) - timeout_set(&age_subnets_timeout, &(struct timeval){10, rand() % 100000}); + timeout_set(&age_subnets_timeout, &(struct timeval) { + 10, rand() % 100000 + }); } static void learn_mac(mac_t *address) { @@ -473,8 +534,8 @@ static void learn_mac(mac_t *address) { if(!subnet) { logger(DEBUG_TRAFFIC, LOG_INFO, "Learned new MAC address %x:%x:%x:%x:%x:%x", - address->x[0], address->x[1], address->x[2], address->x[3], - address->x[4], address->x[5]); + address->x[0], address->x[1], address->x[2], address->x[3], + address->x[4], address->x[5]); subnet = new_subnet(); subnet->type = SUBNET_MAC; @@ -487,20 +548,25 @@ static void learn_mac(mac_t *address) { /* And tell all other tinc daemons it's our MAC */ for list_each(connection_t, c, connection_list) - if(c->edge) + if(c->edge) { send_add_subnet(c, subnet); + } - timeout_add(&age_subnets_timeout, age_subnets, NULL, &(struct timeval){10, rand() % 100000}); + timeout_add(&age_subnets_timeout, age_subnets, NULL, &(struct timeval) { + 10, rand() % 100000 + }); } else { - if(subnet->expires) + if(subnet->expires) { subnet->expires = now.tv_sec + macexpire; + } } } static void route_broadcast(node_t *source, vpn_packet_t *packet) { if(decrement_ttl && source != myself) - if(!do_decrement_ttl(source, packet)) + if(!do_decrement_ttl(source, packet)) { return; + } broadcast_packet(source, packet); } @@ -518,8 +584,9 @@ static void fragment_ipv4_packet(node_t *dest, vpn_packet_t *packet, length_t et fragment.priority = packet->priority; fragment.offset = DEFAULT_PACKET_OFFSET; - if(ip.ip_hl != ip_size / 4) + if(ip.ip_hl != ip_size / 4) { return; + } todo = ntohs(ip.ip_len) - ip_size; @@ -557,29 +624,30 @@ static void fragment_ipv4_packet(node_t *dest, vpn_packet_t *packet, length_t et } static void route_ipv4(node_t *source, vpn_packet_t *packet) { - if(!checklength(source, packet, ether_size + ip_size)) + if(!checklength(source, packet, ether_size + ip_size)) { return; + } subnet_t *subnet; node_t *via; ipv4_t dest; - memcpy(&dest, &DATA(packet)[30], sizeof dest); + memcpy(&dest, &DATA(packet)[30], sizeof(dest)); subnet = lookup_subnet_ipv4(&dest); if(!subnet) { logger(DEBUG_TRAFFIC, LOG_WARNING, "Cannot route packet from %s (%s): unknown IPv4 destination address %d.%d.%d.%d", - source->name, source->hostname, - dest.x[0], - dest.x[1], - dest.x[2], - dest.x[3]); + source->name, source->hostname, + dest.x[0], + dest.x[1], + dest.x[2], + dest.x[3]); route_ipv4_unreachable(source, packet, ether_size, ICMP_DEST_UNREACH, ICMP_NET_UNKNOWN); return; } - if (!subnet->owner) { + if(!subnet->owner) { route_broadcast(source, packet); return; } @@ -589,18 +657,24 @@ static void route_ipv4(node_t *source, vpn_packet_t *packet) { return; } - if(!subnet->owner->status.reachable) - return route_ipv4_unreachable(source, packet, ether_size, ICMP_DEST_UNREACH, ICMP_NET_UNREACH); + if(!subnet->owner->status.reachable) { + route_ipv4_unreachable(source, packet, ether_size, ICMP_DEST_UNREACH, ICMP_NET_UNREACH); + return; + } - if(forwarding_mode == FMODE_OFF && source != myself && subnet->owner != myself) - return route_ipv4_unreachable(source, packet, ether_size, ICMP_DEST_UNREACH, ICMP_NET_ANO); + if(forwarding_mode == FMODE_OFF && source != myself && subnet->owner != myself) { + route_ipv4_unreachable(source, packet, ether_size, ICMP_DEST_UNREACH, ICMP_NET_ANO); + return; + } if(decrement_ttl && source != myself && subnet->owner != myself) - if(!do_decrement_ttl(source, packet)) + if(!do_decrement_ttl(source, packet)) { return; + } - if(priorityinheritance) + if(priorityinheritance) { packet->priority = DATA(packet)[15]; + } via = (subnet->owner->via == myself) ? subnet->owner->nexthop : subnet->owner->via; @@ -609,11 +683,14 @@ static void route_ipv4(node_t *source, vpn_packet_t *packet) { return; } - if(directonly && subnet->owner != via) - return route_ipv4_unreachable(source, packet, ether_size, ICMP_DEST_UNREACH, ICMP_NET_ANO); + if(directonly && subnet->owner != via) { + route_ipv4_unreachable(source, packet, ether_size, ICMP_DEST_UNREACH, ICMP_NET_ANO); + return; + } if(via && packet->len > MAX(via->mtu, 590) && via != myself) { logger(DEBUG_TRAFFIC, LOG_INFO, "Packet for %s (%s) length %d larger than MTU %d", subnet->owner->name, subnet->owner->hostname, packet->len, via->mtu); + if(DATA(packet)[20] & 0x40) { packet->len = MAX(via->mtu, 590); route_ipv4_unreachable(source, packet, ether_size, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED); @@ -632,8 +709,9 @@ static void route_ipv4(node_t *source, vpn_packet_t *packet) { static void route_neighborsol(node_t *source, vpn_packet_t *packet); static void route_ipv6(node_t *source, vpn_packet_t *packet) { - if(!checklength(source, packet, ether_size + ip6_size)) + if(!checklength(source, packet, ether_size + ip6_size)) { return; + } if(DATA(packet)[20] == IPPROTO_ICMPV6 && checklength(source, packet, ether_size + ip6_size + icmp6_size) && DATA(packet)[54] == ND_NEIGHBOR_SOLICIT) { route_neighborsol(source, packet); @@ -644,26 +722,26 @@ static void route_ipv6(node_t *source, vpn_packet_t *packet) { node_t *via; ipv6_t dest; - memcpy(&dest, &DATA(packet)[38], sizeof dest); + memcpy(&dest, &DATA(packet)[38], sizeof(dest)); subnet = lookup_subnet_ipv6(&dest); if(!subnet) { logger(DEBUG_TRAFFIC, LOG_WARNING, "Cannot route packet from %s (%s): unknown IPv6 destination address %hx:%hx:%hx:%hx:%hx:%hx:%hx:%hx", - source->name, source->hostname, - ntohs(dest.x[0]), - ntohs(dest.x[1]), - ntohs(dest.x[2]), - ntohs(dest.x[3]), - ntohs(dest.x[4]), - ntohs(dest.x[5]), - ntohs(dest.x[6]), - ntohs(dest.x[7])); + source->name, source->hostname, + ntohs(dest.x[0]), + ntohs(dest.x[1]), + ntohs(dest.x[2]), + ntohs(dest.x[3]), + ntohs(dest.x[4]), + ntohs(dest.x[5]), + ntohs(dest.x[6]), + ntohs(dest.x[7])); route_ipv6_unreachable(source, packet, ether_size, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_ADDR); return; } - if (!subnet->owner) { + if(!subnet->owner) { route_broadcast(source, packet); return; } @@ -673,18 +751,24 @@ static void route_ipv6(node_t *source, vpn_packet_t *packet) { return; } - if(!subnet->owner->status.reachable) - return route_ipv6_unreachable(source, packet, ether_size, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_NOROUTE); + if(!subnet->owner->status.reachable) { + route_ipv6_unreachable(source, packet, ether_size, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_NOROUTE); + return; + } - if(forwarding_mode == FMODE_OFF && source != myself && subnet->owner != myself) - return route_ipv6_unreachable(source, packet, ether_size, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_ADMIN); + if(forwarding_mode == FMODE_OFF && source != myself && subnet->owner != myself) { + route_ipv6_unreachable(source, packet, ether_size, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_ADMIN); + return; + } if(decrement_ttl && source != myself && subnet->owner != myself) - if(!do_decrement_ttl(source, packet)) + if(!do_decrement_ttl(source, packet)) { return; + } - if(priorityinheritance) + if(priorityinheritance) { packet->priority = ((DATA(packet)[14] & 0x0f) << 4) | (DATA(packet)[15] >> 4); + } via = (subnet->owner->via == myself) ? subnet->owner->nexthop : subnet->owner->via; @@ -693,8 +777,10 @@ static void route_ipv6(node_t *source, vpn_packet_t *packet) { return; } - if(directonly && subnet->owner != via) - return route_ipv6_unreachable(source, packet, ether_size, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_ADMIN); + if(directonly && subnet->owner != via) { + route_ipv6_unreachable(source, packet, ether_size, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_ADMIN); + return; + } if(via && packet->len > MAX(via->mtu, 1294) && via != myself) { logger(DEBUG_TRAFFIC, LOG_INFO, "Packet for %s (%s) length %d larger than MTU %d", subnet->owner->name, subnet->owner->hostname, packet->len, via->mtu); @@ -725,8 +811,9 @@ static void route_neighborsol(node_t *source, vpn_packet_t *packet) { uint32_t next; } pseudo; - if(!checklength(source, packet, ether_size + ip6_size + ns_size)) + if(!checklength(source, packet, ether_size + ip6_size + ns_size)) { return; + } has_opt = packet->len >= ether_size + ip6_size + ns_size + opt_size + ETH_ALEN; @@ -739,18 +826,21 @@ static void route_neighborsol(node_t *source, vpn_packet_t *packet) { memcpy(&ip6, DATA(packet) + ether_size, ip6_size); memcpy(&ns, DATA(packet) + ether_size + ip6_size, ns_size); - if(has_opt) + + if(has_opt) { memcpy(&opt, DATA(packet) + ether_size + ip6_size + ns_size, opt_size); + } /* First, snatch the source address from the neighbor solicitation packet */ - if(overwrite_mac) + if(overwrite_mac) { memcpy(mymac.x, DATA(packet) + ETH_ALEN, ETH_ALEN); + } /* Check if this is a valid neighbor solicitation request */ if(ns.nd_ns_hdr.icmp6_type != ND_NEIGHBOR_SOLICIT || - (has_opt && opt.nd_opt_type != ND_OPT_SOURCE_LINKADDR)) { + (has_opt && opt.nd_opt_type != ND_OPT_SOURCE_LINKADDR)) { logger(DEBUG_TRAFFIC, LOG_WARNING, "Cannot route packet: received unknown type neighbor solicitation request"); return; } @@ -759,16 +849,20 @@ static void route_neighborsol(node_t *source, vpn_packet_t *packet) { pseudo.ip6_src = ip6.ip6_src; pseudo.ip6_dst = ip6.ip6_dst; - if(has_opt) + + if(has_opt) { pseudo.length = htonl(ns_size + opt_size + ETH_ALEN); - else + } else { pseudo.length = htonl(ns_size); + } + pseudo.next = htonl(IPPROTO_ICMPV6); /* Generate checksum */ - checksum = inet_checksum(&pseudo, sizeof pseudo, ~0); + checksum = inet_checksum(&pseudo, sizeof(pseudo), ~0); checksum = inet_checksum(&ns, ns_size, checksum); + if(has_opt) { checksum = inet_checksum(&opt, opt_size, checksum); checksum = inet_checksum(DATA(packet) + ether_size + ip6_size + ns_size + opt_size, ETH_ALEN, checksum); @@ -785,37 +879,40 @@ static void route_neighborsol(node_t *source, vpn_packet_t *packet) { if(!subnet) { logger(DEBUG_TRAFFIC, LOG_WARNING, "Cannot route packet: neighbor solicitation request for unknown address %hx:%hx:%hx:%hx:%hx:%hx:%hx:%hx", - ntohs(((uint16_t *) &ns.nd_ns_target)[0]), - ntohs(((uint16_t *) &ns.nd_ns_target)[1]), - ntohs(((uint16_t *) &ns.nd_ns_target)[2]), - ntohs(((uint16_t *) &ns.nd_ns_target)[3]), - ntohs(((uint16_t *) &ns.nd_ns_target)[4]), - ntohs(((uint16_t *) &ns.nd_ns_target)[5]), - ntohs(((uint16_t *) &ns.nd_ns_target)[6]), - ntohs(((uint16_t *) &ns.nd_ns_target)[7])); + ntohs(((uint16_t *) &ns.nd_ns_target)[0]), + ntohs(((uint16_t *) &ns.nd_ns_target)[1]), + ntohs(((uint16_t *) &ns.nd_ns_target)[2]), + ntohs(((uint16_t *) &ns.nd_ns_target)[3]), + ntohs(((uint16_t *) &ns.nd_ns_target)[4]), + ntohs(((uint16_t *) &ns.nd_ns_target)[5]), + ntohs(((uint16_t *) &ns.nd_ns_target)[6]), + ntohs(((uint16_t *) &ns.nd_ns_target)[7])); return; } /* Check if it is for our own subnet */ - if(subnet->owner == myself) - return; /* silently ignore */ + if(subnet->owner == myself) { + return; /* silently ignore */ + } if(decrement_ttl) - if(!do_decrement_ttl(source, packet)) + if(!do_decrement_ttl(source, packet)) { return; + } /* Create neighbor advertation reply */ memcpy(DATA(packet), DATA(packet) + ETH_ALEN, ETH_ALEN); /* copy destination address */ DATA(packet)[ETH_ALEN * 2 - 1] ^= 0xFF; /* mangle source address so it looks like it's not from us */ - ip6.ip6_dst = ip6.ip6_src; /* swap destination and source protocoll address */ + ip6.ip6_dst = ip6.ip6_src; /* swap destination and source protocol address */ ip6.ip6_src = ns.nd_ns_target; - if(has_opt) - memcpy(DATA(packet) + ether_size + ip6_size + ns_size + opt_size, DATA(packet) + ETH_ALEN, ETH_ALEN); /* add fake source hard addr */ + if(has_opt) { + memcpy(DATA(packet) + ether_size + ip6_size + ns_size + opt_size, DATA(packet) + ETH_ALEN, ETH_ALEN); /* add fake source hard addr */ + } ns.nd_ns_cksum = 0; ns.nd_ns_type = ND_NEIGHBOR_ADVERT; @@ -826,16 +923,20 @@ static void route_neighborsol(node_t *source, vpn_packet_t *packet) { pseudo.ip6_src = ip6.ip6_src; pseudo.ip6_dst = ip6.ip6_dst; - if(has_opt) + + if(has_opt) { pseudo.length = htonl(ns_size + opt_size + ETH_ALEN); - else + } else { pseudo.length = htonl(ns_size); + } + pseudo.next = htonl(IPPROTO_ICMPV6); /* Generate checksum */ - checksum = inet_checksum(&pseudo, sizeof pseudo, ~0); + checksum = inet_checksum(&pseudo, sizeof(pseudo), ~0); checksum = inet_checksum(&ns, ns_size, checksum); + if(has_opt) { checksum = inet_checksum(&opt, opt_size, checksum); checksum = inet_checksum(DATA(packet) + ether_size + ip6_size + ns_size + opt_size, ETH_ALEN, checksum); @@ -847,8 +948,10 @@ static void route_neighborsol(node_t *source, vpn_packet_t *packet) { memcpy(DATA(packet) + ether_size, &ip6, ip6_size); memcpy(DATA(packet) + ether_size + ip6_size, &ns, ns_size); - if(has_opt) + + if(has_opt) { memcpy(DATA(packet) + ether_size + ip6_size + ns_size, &opt, opt_size); + } send_packet(source, packet); } @@ -860,8 +963,9 @@ static void route_arp(node_t *source, vpn_packet_t *packet) { subnet_t *subnet; struct in_addr addr; - if(!checklength(source, packet, ether_size + arp_size)) + if(!checklength(source, packet, ether_size + arp_size)) { return; + } if(source != myself) { logger(DEBUG_TRAFFIC, LOG_WARNING, "Got ARP request from %s (%s) while in router mode!", source->name, source->hostname); @@ -870,8 +974,9 @@ static void route_arp(node_t *source, vpn_packet_t *packet) { /* First, snatch the source address from the ARP packet */ - if(overwrite_mac) + if(overwrite_mac) { memcpy(mymac.x, DATA(packet) + ETH_ALEN, ETH_ALEN); + } /* Copy headers from packet to structs on the stack */ @@ -880,7 +985,7 @@ static void route_arp(node_t *source, vpn_packet_t *packet) { /* Check if this is a valid ARP request */ if(ntohs(arp.arp_hrd) != ARPHRD_ETHER || ntohs(arp.arp_pro) != ETH_P_IP || - arp.arp_hln != ETH_ALEN || arp.arp_pln != sizeof addr || ntohs(arp.arp_op) != ARPOP_REQUEST) { + arp.arp_hln != ETH_ALEN || arp.arp_pln != sizeof(addr) || ntohs(arp.arp_op) != ARPOP_REQUEST) { logger(DEBUG_TRAFFIC, LOG_WARNING, "Cannot route packet: received unknown type ARP request"); return; } @@ -891,23 +996,25 @@ static void route_arp(node_t *source, vpn_packet_t *packet) { if(!subnet) { logger(DEBUG_TRAFFIC, LOG_WARNING, "Cannot route packet: ARP request for unknown address %d.%d.%d.%d", - arp.arp_tpa[0], arp.arp_tpa[1], arp.arp_tpa[2], - arp.arp_tpa[3]); + arp.arp_tpa[0], arp.arp_tpa[1], arp.arp_tpa[2], + arp.arp_tpa[3]); return; } /* Check if it is for our own subnet */ - if(subnet->owner == myself) - return; /* silently ignore */ + if(subnet->owner == myself) { + return; /* silently ignore */ + } if(decrement_ttl) - if(!do_decrement_ttl(source, packet)) + if(!do_decrement_ttl(source, packet)) { return; + } - memcpy(&addr, arp.arp_tpa, sizeof addr); /* save protocol addr */ - memcpy(arp.arp_tpa, arp.arp_spa, sizeof addr); /* swap destination and source protocol address */ - memcpy(arp.arp_spa, &addr, sizeof addr); /* ... */ + memcpy(&addr, arp.arp_tpa, sizeof(addr)); /* save protocol addr */ + memcpy(arp.arp_tpa, arp.arp_spa, sizeof(addr)); /* swap destination and source protocol address */ + memcpy(arp.arp_spa, &addr, sizeof(addr)); /* ... */ memcpy(arp.arp_tha, arp.arp_sha, ETH_ALEN); /* set target hard/proto addr */ memcpy(arp.arp_sha, DATA(packet) + ETH_ALEN, ETH_ALEN); /* set source hard/proto addr */ @@ -929,13 +1036,13 @@ static void route_mac(node_t *source, vpn_packet_t *packet) { if(source == myself) { mac_t src; - memcpy(&src, &DATA(packet)[6], sizeof src); + memcpy(&src, &DATA(packet)[6], sizeof(src)); learn_mac(&src); } /* Lookup destination address */ - memcpy(&dest, &DATA(packet)[0], sizeof dest); + memcpy(&dest, &DATA(packet)[0], sizeof(dest)); subnet = lookup_subnet_mac(NULL, &dest); if(!subnet || !subnet->owner) { @@ -948,28 +1055,32 @@ static void route_mac(node_t *source, vpn_packet_t *packet) { return; } - if(forwarding_mode == FMODE_OFF && source != myself && subnet->owner != myself) + if(forwarding_mode == FMODE_OFF && source != myself && subnet->owner != myself) { return; + } if(decrement_ttl && source != myself && subnet->owner != myself) - if(!do_decrement_ttl(source, packet)) + if(!do_decrement_ttl(source, packet)) { return; + } uint16_t type = DATA(packet)[12] << 8 | DATA(packet)[13]; if(priorityinheritance) { - if(type == ETH_P_IP && packet->len >= ether_size + ip_size) + if(type == ETH_P_IP && packet->len >= ether_size + ip_size) { packet->priority = DATA(packet)[15]; - else if(type == ETH_P_IPV6 && packet->len >= ether_size + ip6_size) + } else if(type == ETH_P_IPV6 && packet->len >= ether_size + ip6_size) { packet->priority = ((DATA(packet)[14] & 0x0f) << 4) | (DATA(packet)[15] >> 4); + } } // Handle packets larger than PMTU node_t *via = (subnet->owner->via == myself) ? subnet->owner->nexthop : subnet->owner->via; - if(directonly && subnet->owner != via) + if(directonly && subnet->owner != via) { return; + } if(via && packet->len > via->mtu && via != myself) { logger(DEBUG_TRAFFIC, LOG_INFO, "Packet for %s (%s) length %d larger than MTU %d", subnet->owner->name, subnet->owner->hostname, packet->len, via->mtu); @@ -987,6 +1098,7 @@ static void route_mac(node_t *source, vpn_packet_t *packet) { } else { fragment_ipv4_packet(via, packet, ethlen); } + return; } else if(type == ETH_P_IPV6 && packet->len > 1280 + ethlen) { packet->len = via->mtu; @@ -1004,60 +1116,67 @@ static void send_pcap(vpn_packet_t *packet) { pcap = false; for list_each(connection_t, c, connection_list) { - if(!c->status.pcap) + if(!c->status.pcap) { continue; + } pcap = true; int len = packet->len; - if(c->outmaclength && c->outmaclength < len) - len = c->outmaclength; - if(send_request(c, "%d %d %d", CONTROL, REQ_PCAP, len)) + if(c->outmaclength && c->outmaclength < len) { + len = c->outmaclength; + } + + if(send_request(c, "%d %d %d", CONTROL, REQ_PCAP, len)) { send_meta(c, (char *)DATA(packet), len); + } } } void route(node_t *source, vpn_packet_t *packet) { - if(pcap) + if(pcap) { send_pcap(packet); + } if(forwarding_mode == FMODE_KERNEL && source != myself) { send_packet(myself, packet); return; } - if(!checklength(source, packet, ether_size)) + if(!checklength(source, packet, ether_size)) { return; + } uint16_t type = DATA(packet)[12] << 8 | DATA(packet)[13]; - switch (routing_mode) { - case RMODE_ROUTER: - switch (type) { - case ETH_P_ARP: - route_arp(source, packet); - break; - - case ETH_P_IP: - route_ipv4(source, packet); - break; - - case ETH_P_IPV6: - route_ipv6(source, packet); - break; - - default: - logger(DEBUG_TRAFFIC, LOG_WARNING, "Cannot route packet from %s (%s): unknown type %hx", source->name, source->hostname, type); - break; - } + switch(routing_mode) { + case RMODE_ROUTER: + switch(type) { + case ETH_P_ARP: + route_arp(source, packet); break; - case RMODE_SWITCH: - route_mac(source, packet); + case ETH_P_IP: + route_ipv4(source, packet); break; - case RMODE_HUB: - route_broadcast(source, packet); + case ETH_P_IPV6: + route_ipv6(source, packet); break; + + default: + logger(DEBUG_TRAFFIC, LOG_WARNING, "Cannot route packet from %s (%s): unknown type %hx", source->name, source->hostname, type); + break; + } + + break; + + case RMODE_SWITCH: + route_mac(source, packet); + break; + + case RMODE_HUB: + route_broadcast(source, packet); + break; } } diff --git a/src/route.h b/src/route.h index a0121d7..095448a 100644 --- a/src/route.h +++ b/src/route.h @@ -1,3 +1,6 @@ +#ifndef TINC_ROUTE_H +#define TINC_ROUTE_H + /* route.h -- header file for route.c Copyright (C) 2000-2005 Ivo Timmermans @@ -18,9 +21,6 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#ifndef __TINC_ROUTE_H__ -#define __TINC_ROUTE_H__ - #include "net.h" #include "node.h" @@ -54,6 +54,6 @@ extern bool pcap; extern mac_t mymac; -extern void route(struct node_t *, struct vpn_packet_t *); +extern void route(struct node_t *source, struct vpn_packet_t *packet); -#endif /* __TINC_ROUTE_H__ */ +#endif diff --git a/src/rsa.h b/src/rsa.h index f4290d4..a31ec24 100644 --- a/src/rsa.h +++ b/src/rsa.h @@ -1,3 +1,6 @@ +#ifndef TINC_RSA_H +#define TINC_RSA_H + /* rsa.h -- RSA key handling Copyright (C) 2007-2013 Guus Sliepen @@ -17,20 +20,17 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#ifndef __TINC_RSA_H__ -#define __TINC_RSA_H__ - -#ifndef __TINC_RSA_INTERNAL__ +#ifndef TINC_RSA_INTERNAL typedef struct rsa rsa_t; #endif extern void rsa_free(rsa_t *rsa); -extern rsa_t *rsa_set_hex_public_key(char *n, char *e) __attribute__ ((__malloc__)); -extern rsa_t *rsa_set_hex_private_key(char *n, char *e, char *d) __attribute__ ((__malloc__)); -extern rsa_t *rsa_read_pem_public_key(FILE *fp) __attribute__ ((__malloc__)); -extern rsa_t *rsa_read_pem_private_key(FILE *fp) __attribute__ ((__malloc__)); +extern rsa_t *rsa_set_hex_public_key(char *n, char *e) __attribute__((__malloc__)); +extern rsa_t *rsa_set_hex_private_key(char *n, char *e, char *d) __attribute__((__malloc__)); +extern rsa_t *rsa_read_pem_public_key(FILE *fp) __attribute__((__malloc__)); +extern rsa_t *rsa_read_pem_private_key(FILE *fp) __attribute__((__malloc__)); extern size_t rsa_size(rsa_t *rsa); -extern bool rsa_public_encrypt(rsa_t *rsa, void *in, size_t len, void *out) __attribute__ ((__warn_unused_result__)); -extern bool rsa_private_decrypt(rsa_t *rsa, void *in, size_t len, void *out) __attribute__ ((__warn_unused_result__)); +extern bool rsa_public_encrypt(rsa_t *rsa, void *in, size_t len, void *out) __attribute__((__warn_unused_result__)); +extern bool rsa_private_decrypt(rsa_t *rsa, void *in, size_t len, void *out) __attribute__((__warn_unused_result__)); #endif diff --git a/src/rsagen.h b/src/rsagen.h index 58ce29f..a661607 100644 --- a/src/rsagen.h +++ b/src/rsagen.h @@ -1,3 +1,6 @@ +#ifndef TINC_RSAGEN_H +#define TINC_RSAGEN_H + /* rsagen.h -- RSA key generation and export Copyright (C) 2008-2013 Guus Sliepen @@ -17,13 +20,10 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#ifndef __TINC_RSAGEN_H__ -#define __TINC_RSAGEN_H__ - #include "rsa.h" -extern rsa_t *rsa_generate(size_t bits, unsigned long exponent) __attribute__ ((__malloc__)); -extern bool rsa_write_pem_public_key(rsa_t *rsa, FILE *fp) __attribute__ ((__warn_unused_result__)); -extern bool rsa_write_pem_private_key(rsa_t *rsa, FILE *fp) __attribute__ ((__warn_unused_result__)); +extern rsa_t *rsa_generate(size_t bits, unsigned long exponent) __attribute__((__malloc__)); +extern bool rsa_write_pem_public_key(rsa_t *rsa, FILE *fp) __attribute__((__warn_unused_result__)); +extern bool rsa_write_pem_private_key(rsa_t *rsa, FILE *fp) __attribute__((__warn_unused_result__)); #endif diff --git a/src/script.c b/src/script.c index d65551a..81216a3 100644 --- a/src/script.c +++ b/src/script.c @@ -30,8 +30,11 @@ #ifdef HAVE_PUTENV static void unputenv(const char *p) { const char *e = strchr(p, '='); - if(!e) + + if(!e) { return; + } + int len = e - p; #ifndef HAVE_UNSETENV #ifdef HAVE_MINGW @@ -48,12 +51,14 @@ static void unputenv(const char *p) { // We must keep what we putenv() around in memory. // To do this without memory leaks, keep things in a list and reuse if possible. static list_t list = {}; + for list_each(char, data, &list) { if(!strcmp(data, var)) { putenv(data); return; } } + char *data = xstrdup(var); list_insert_tail(&list, data); putenv(data); @@ -69,7 +74,7 @@ static const int min_env_size = 10; int environment_add(environment_t *env, const char *format, ...) { if(env->n >= env->size) { env->size = env->n ? env->n * 2 : min_env_size; - env->entries = xrealloc(env->entries, env->size * sizeof *env->entries); + env->entries = xrealloc(env->entries, env->size * sizeof(*env->entries)); } if(format) { @@ -95,23 +100,34 @@ void environment_update(environment_t *env, int pos, const char *format, ...) { void environment_init(environment_t *env) { env->n = 0; env->size = min_env_size; - env->entries = xzalloc(env->size * sizeof *env->entries); + env->entries = xzalloc(env->size * sizeof(*env->entries)); - if(netname) + if(netname) { environment_add(env, "NETNAME=%s", netname); - if(myname) + } + + if(myname) { environment_add(env, "NAME=%s", myname); - if(device) + } + + if(device) { environment_add(env, "DEVICE=%s", device); - if(iface) + } + + if(iface) { environment_add(env, "INTERFACE=%s", iface); - if(debug_level >= 0) + } + + if(debug_level >= 0) { environment_add(env, "DEBUG=%d", debug_level); + } } void environment_exit(environment_t *env) { - for(int i = 0; i < env->n; i++) + for(int i = 0; i < env->n; i++) { free(env->entries[i]); + } + free(env->entries); } @@ -119,23 +135,26 @@ bool execute_script(const char *name, environment_t *env) { char scriptname[PATH_MAX]; char *command; - snprintf(scriptname, sizeof scriptname, "%s" SLASH "%s%s", confbase, name, scriptextension); + snprintf(scriptname, sizeof(scriptname), "%s" SLASH "%s%s", confbase, name, scriptextension); /* First check if there is a script */ #ifdef HAVE_MINGW + if(!*scriptextension) { - const char *pathext = getenv("PATHEXT") ?: ".COM;.EXE;.BAT;.CMD"; + const char *pathext = getenv("PATHEXT") ? : ".COM;.EXE;.BAT;.CMD"; size_t pathlen = strlen(pathext); size_t scriptlen = strlen(scriptname); char fullname[scriptlen + pathlen + 1]; char *ext = fullname + scriptlen; - strncpy(fullname, scriptname, sizeof fullname); + strncpy(fullname, scriptname, sizeof(fullname)); const char *p = pathext; bool found = false; + while(p && *p) { const char *q = strchr(p, ';'); + if(q) { memcpy(ext, p, q - p); ext[q - p] = 0; @@ -143,29 +162,37 @@ bool execute_script(const char *name, environment_t *env) { } else { strncpy(ext, p, pathlen + 1); } - if((found = !access(fullname, F_OK))) + + if((found = !access(fullname, F_OK))) { break; + } + p = q; } - if(!found) + + if(!found) { return true; + } } else #endif - if(access(scriptname, F_OK)) - return true; + if(access(scriptname, F_OK)) { + return true; + } logger(DEBUG_STATUS, LOG_INFO, "Executing script %s", name); /* Set environment */ - for(int i = 0; i < env->n; i++) + for(int i = 0; i < env->n; i++) { putenv(env->entries[i]); + } - if(scriptinterpreter) + if(scriptinterpreter) { xasprintf(&command, "%s \"%s\"", scriptinterpreter, scriptname); - else + } else { xasprintf(&command, "\"%s\"", scriptname); + } int status = system(command); @@ -173,25 +200,28 @@ bool execute_script(const char *name, environment_t *env) { /* Unset environment */ - for(int i = 0; i < env->n; i++) + for(int i = 0; i < env->n; i++) { unputenv(env->entries[i]); + } if(status != -1) { #ifdef WEXITSTATUS + if(WIFEXITED(status)) { /* Child exited by itself */ if(WEXITSTATUS(status)) { logger(DEBUG_ALWAYS, LOG_ERR, "Script %s exited with non-zero status %d", - name, WEXITSTATUS(status)); + name, WEXITSTATUS(status)); return false; } } else if(WIFSIGNALED(status)) { /* Child was killed by a signal */ logger(DEBUG_ALWAYS, LOG_ERR, "Script %s was killed by signal %d (%s)", - name, WTERMSIG(status), strsignal(WTERMSIG(status))); + name, WTERMSIG(status), strsignal(WTERMSIG(status))); return false; } else { /* Something strange happened */ logger(DEBUG_ALWAYS, LOG_ERR, "Script %s terminated abnormally", name); return false; } + #endif } else { logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "system", strerror(errno)); diff --git a/src/script.h b/src/script.h index 2e26418..5172034 100644 --- a/src/script.h +++ b/src/script.h @@ -1,3 +1,6 @@ +#ifndef TINC_SCRIPT_H +#define TINC_SCRIPT_H + /* script.h -- header file for script.c Copyright (C) 1999-2005 Ivo Timmermans, @@ -18,9 +21,6 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#ifndef __TINC_SCRIPT_H__ -#define __TINC_SCRIPT_H__ - typedef struct environment { int n; int size; @@ -35,4 +35,4 @@ extern void environment_exit(environment_t *env); extern bool execute_script(const char *name, environment_t *env); -#endif /* __TINC_SCRIPT_H__ */ +#endif diff --git a/src/solaris/device.c b/src/solaris/device.c index 89481c7..f27954b 100644 --- a/src/solaris/device.c +++ b/src/solaris/device.c @@ -53,36 +53,39 @@ int device_fd = -1; static int ip_fd = -1; char *device = NULL; char *iface = NULL; -static char *device_info = NULL; +static const char *device_info = NULL; static bool setup_device(void) { char *type; if(!get_config_string(lookup_config(config_tree, "Device"), &device)) { - if(routing_mode == RMODE_ROUTER) + if(routing_mode == RMODE_ROUTER) { device = xstrdup(DEFAULT_TUN_DEVICE); - else + } else { device = xstrdup(DEFAULT_TAP_DEVICE); + } } if(get_config_string(lookup_config(config_tree, "DeviceType"), &type)) { if(!strcasecmp(type, "tun")) /* use default */; - else if(!strcasecmp(type, "tap")) + else if(!strcasecmp(type, "tap")) { device_type = DEVICE_TYPE_TAP; - else { + } else { logger(DEBUG_ALWAYS, LOG_ERR, "Unknown device type %s!", type); return false; } } else { - if(strstr(device, "tap") || routing_mode != RMODE_ROUTER) + if(strstr(device, "tap") || routing_mode != RMODE_ROUTER) { device_type = DEVICE_TYPE_TAP; + } } - if(device_type == DEVICE_TYPE_TUN) + if(device_type == DEVICE_TYPE_TUN) { device_info = "Solaris tun device"; - else + } else { device_info = "Solaris tap device"; + } /* The following is black magic copied from OpenVPN. */ @@ -101,29 +104,35 @@ static bool setup_device(void) { char *ptr = device; get_config_string(lookup_config(config_tree, "Interface"), &ptr); - while(*ptr && !isdigit(*ptr)) + while(*ptr && !isdigit(*ptr)) { ptr++; + } + int ppa = atoi(ptr); /* Assign a new PPA and get its unit number. */ struct strioctl strioc_ppa = { .ic_cmd = TUNNEWPPA, - .ic_len = sizeof ppa, - .ic_dp = (char *)&ppa, + .ic_len = sizeof(ppa), + .ic_dp = (char *) &ppa, }; if(!*ptr) { /* no number given, try dynamic */ bool found = false; + while(!found && ppa < 64) { int new_ppa = ioctl(device_fd, I_STR, &strioc_ppa); + if(new_ppa >= 0) { ppa = new_ppa; found = true; break; } + ppa++; } + if(!found) { logger(DEBUG_ALWAYS, LOG_ERR, "Could not find free PPA for %s %s!", device_info, device); return false; @@ -136,6 +145,7 @@ static bool setup_device(void) { } int if_fd; + if((if_fd = open(device, O_RDWR, 0)) < 0) { logger(DEBUG_ALWAYS, LOG_ERR, "Could not open %s: %s\n", device, strerror(errno)); return false; @@ -151,7 +161,8 @@ static bool setup_device(void) { { /* Remove muxes just in case they are left over from a crashed tincd */ struct lifreq ifr = {}; - strncpy(ifr.lifr_name, iface, sizeof ifr.lifr_name); + strncpy(ifr.lifr_name, iface, sizeof(ifr.lifr_name)); + if(ioctl(ip_fd, SIOCGLIFMUXID, &ifr) >= 0) { int muxid = ifr.lifr_arp_muxid; ioctl(ip_fd, I_PUNLINK, muxid); @@ -165,7 +176,7 @@ static bool setup_device(void) { if(ioctl(if_fd, IF_UNITSEL, (char *)&ppa) < 0) { logger(DEBUG_ALWAYS, LOG_ERR, "Could not set PPA %d on %s %s!", ppa, device_info, device); return false; - } + } } int arp_fd = -1; @@ -186,6 +197,7 @@ static bool setup_device(void) { logger(DEBUG_ALWAYS, LOG_ERR, "Could not set PPA %d on %s %s!", ppa, device_info, device); return false; } + if(ioctl(if_fd, SIOCGLIFFLAGS, &ifr) < 0) { logger(DEBUG_ALWAYS, LOG_ERR, "Could not set flags on %s %s!", device_info, device); return false; @@ -199,8 +211,9 @@ static bool setup_device(void) { /* Pop any modules on the stream */ while(true) { - if(ioctl(ip_fd, I_POP, NULL) < 0) + if(ioctl(ip_fd, I_POP, NULL) < 0) { break; + } } /* Push arp module to ip_fd */ @@ -224,8 +237,8 @@ static bool setup_device(void) { /* Set ifname to arp */ struct strioctl strioc_if = { .ic_cmd = SIOCSLIFNAME, - .ic_len = sizeof ifr, - .ic_dp = (char *)&ifr, + .ic_len = sizeof(ifr), + .ic_dp = (char *) &ifr, }; if(ioctl(arp_fd, I_STR, &strioc_if) < 0) { @@ -246,12 +259,16 @@ static bool setup_device(void) { logger(DEBUG_ALWAYS, LOG_ERR, "Could not link %s %s to ARP", device_info, device); return false; } + close(arp_fd); } struct lifreq ifr = {}; + strncpy(ifr.lifr_name, iface, sizeof(ifr.lifr_name)); + ifr.lifr_ip_muxid = ip_muxid; + if(device_type == DEVICE_TYPE_TAP) { ifr.lifr_arp_muxid = arp_muxid; } @@ -260,6 +277,7 @@ static bool setup_device(void) { if(device_type == DEVICE_TYPE_TAP) { ioctl(ip_fd, I_PUNLINK, arp_muxid); } + ioctl(ip_fd, I_PUNLINK, ip_muxid); logger(DEBUG_ALWAYS, LOG_ERR, "Could not set multiplexor id for %s %s", device_info, device); return false; @@ -280,7 +298,8 @@ static bool setup_device(void) { static void close_device(void) { if(iface) { struct lifreq ifr = {}; - strncpy(ifr.lifr_name, iface, sizeof ifr.lifr_name); + strncpy(ifr.lifr_name, iface, sizeof(ifr.lifr_name)); + if(ioctl(ip_fd, SIOCGLIFMUXID, &ifr) >= 0) { int muxid = ifr.lifr_arp_muxid; ioctl(ip_fd, I_PUNLINK, muxid); @@ -289,11 +308,15 @@ static void close_device(void) { } } - close(ip_fd); ip_fd = -1; - close(device_fd); device_fd = -1; + close(ip_fd); + ip_fd = -1; + close(device_fd); + device_fd = -1; - free(device); device = NULL; - free(iface); iface = NULL; + free(device); + device = NULL; + free(iface); + iface = NULL; } static bool read_packet(vpn_packet_t *packet) { @@ -302,47 +325,49 @@ static bool read_packet(vpn_packet_t *packet) { int f = 0; switch(device_type) { - case DEVICE_TYPE_TUN: - sbuf.maxlen = MTU - 14; - sbuf.buf = (char *)DATA(packet) + 14; + case DEVICE_TYPE_TUN: + sbuf.maxlen = MTU - 14; + sbuf.buf = (char *)DATA(packet) + 14; - if((result = getmsg(device_fd, NULL, &sbuf, &f)) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info, device, strerror(errno)); - return false; - } + if((result = getmsg(device_fd, NULL, &sbuf, &f)) < 0) { + logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info, device, strerror(errno)); + return false; + } - switch(DATA(packet)[14] >> 4) { - case 4: - DATA(packet)[12] = 0x08; - DATA(packet)[13] = 0x00; - break; - case 6: - DATA(packet)[12] = 0x86; - DATA(packet)[13] = 0xDD; - break; - default: - logger(DEBUG_TRAFFIC, LOG_ERR, "Unknown IP version %d while reading packet from %s %s", DATA(packet)[14] >> 4, device_info, device); - return false; - } - - memset(DATA(packet), 0, 12); - packet->len = sbuf.len + 14; + switch(DATA(packet)[14] >> 4) { + case 4: + DATA(packet)[12] = 0x08; + DATA(packet)[13] = 0x00; break; - case DEVICE_TYPE_TAP: - sbuf.maxlen = MTU; - sbuf.buf = (char *)DATA(packet); - - if((result = getmsg(device_fd, NULL, &sbuf, &f)) < 0) { - logger(LOG_ERR, "Error while reading from %s %s: %s", device_info, device, strerror(errno)); - return false; - } - - packet->len = sbuf.len; + case 6: + DATA(packet)[12] = 0x86; + DATA(packet)[13] = 0xDD; break; default: - abort(); + logger(DEBUG_TRAFFIC, LOG_ERR, "Unknown IP version %d while reading packet from %s %s", DATA(packet)[14] >> 4, device_info, device); + return false; + } + + memset(DATA(packet), 0, 12); + packet->len = sbuf.len + 14; + break; + + case DEVICE_TYPE_TAP: + sbuf.maxlen = MTU; + sbuf.buf = (char *)DATA(packet); + + if((result = getmsg(device_fd, NULL, &sbuf, &f)) < 0) { + logger(LOG_ERR, "Error while reading from %s %s: %s", device_info, device, strerror(errno)); + return false; + } + + packet->len = sbuf.len; + break; + + default: + abort(); } logger(DEBUG_TRAFFIC, LOG_DEBUG, "Read packet of %d bytes from %s", packet->len, device_info); @@ -356,28 +381,30 @@ static bool write_packet(vpn_packet_t *packet) { struct strbuf sbuf; switch(device_type) { - case DEVICE_TYPE_TUN: - sbuf.len = packet->len - 14; - sbuf.buf = (char *)DATA(packet) + 14; + case DEVICE_TYPE_TUN: + sbuf.len = packet->len - 14; + sbuf.buf = (char *)DATA(packet) + 14; - if(putmsg(device_fd, NULL, &sbuf, 0) < 0) { - logger(LOG_ERR, "Can't write to %s %s: %s", device_info, device, strerror(errno)); - return false; - } - break; + if(putmsg(device_fd, NULL, &sbuf, 0) < 0) { + logger(LOG_ERR, "Can't write to %s %s: %s", device_info, device, strerror(errno)); + return false; + } - case DEVICE_TYPE_TAP: - sbuf.len = packet->len; - sbuf.buf = (char *)DATA(packet); + break; - if(putmsg(device_fd, NULL, &sbuf, 0) < 0) { - logger(LOG_ERR, "Can't write to %s %s: %s", device_info, device, strerror(errno)); - return false; - } - break; + case DEVICE_TYPE_TAP: + sbuf.len = packet->len; + sbuf.buf = (char *)DATA(packet); - default: - abort(); + if(putmsg(device_fd, NULL, &sbuf, 0) < 0) { + logger(LOG_ERR, "Can't write to %s %s: %s", device_info, device, strerror(errno)); + return false; + } + + break; + + default: + abort(); } return true; diff --git a/src/splay_tree.c b/src/splay_tree.c index bd0f06b..4d97373 100644 --- a/src/splay_tree.c +++ b/src/splay_tree.c @@ -25,14 +25,16 @@ /* Splay operation */ static splay_node_t *splay_top_down(splay_tree_t *tree, const void *data, int *result) { - splay_node_t left = {NULL}, right = {NULL}; + splay_node_t left = {0}, right = {0}; splay_node_t *leftbottom = &left, *rightbottom = &right, *child, *grandchild; splay_node_t *root = tree->root; int c; if(!root) { - if(result) + if(result) { *result = 0; + } + return NULL; } @@ -45,8 +47,9 @@ static splay_node_t *splay_top_down(splay_tree_t *tree, const void *data, int *r child->parent = rightbottom; rightbottom = child; - if((root->left = child->right)) + if((root->left = child->right)) { child->right->parent = root; + } child->right = root; root->parent = child; @@ -55,7 +58,7 @@ static splay_node_t *splay_top_down(splay_tree_t *tree, const void *data, int *r grandchild->parent = NULL; root = grandchild; - } else if (c > 0 && (grandchild = child->right)) { + } else if(c > 0 && (grandchild = child->right)) { leftbottom->right = child; child->parent = leftbottom; leftbottom = child; @@ -89,8 +92,9 @@ static splay_node_t *splay_top_down(splay_tree_t *tree, const void *data, int *r child->parent = leftbottom; leftbottom = child; - if((root->right = child->left)) + if((root->right = child->left)) { child->left->parent = root; + } child->left = root; root->parent = child; @@ -99,7 +103,7 @@ static splay_node_t *splay_top_down(splay_tree_t *tree, const void *data, int *r grandchild->parent = NULL; root = grandchild; - } else if (c < 0 && (grandchild = child->left)) { + } else if(c < 0 && (grandchild = child->left)) { rightbottom->left = child; child->parent = rightbottom; rightbottom = child; @@ -137,6 +141,7 @@ static splay_node_t *splay_top_down(splay_tree_t *tree, const void *data, int *r leftbottom->right = root->left; root->left->parent = leftbottom; } + root->left = left.right; left.right->parent = root; } @@ -146,6 +151,7 @@ static splay_node_t *splay_top_down(splay_tree_t *tree, const void *data, int *r rightbottom->left = root->right; root->right->parent = rightbottom; } + root->right = right.left; right.left->parent = root; } @@ -153,8 +159,10 @@ static splay_node_t *splay_top_down(splay_tree_t *tree, const void *data, int *r /* Return result */ tree->root = root; - if(result) + + if(result) { *result = c; + } return tree->root; } @@ -165,12 +173,16 @@ static void splay_bottom_up(splay_tree_t *tree, splay_node_t *node) { while((parent = node->parent)) { if(!(grandparent = parent->parent)) { /* zig */ if(node == parent->left) { - if((parent->left = node->right)) + if((parent->left = node->right)) { parent->left->parent = parent; + } + node->right = parent; } else { - if((parent->right = node->left)) + if((parent->right = node->left)) { parent->right->parent = parent; + } + node->left = parent; } @@ -180,52 +192,69 @@ static void splay_bottom_up(splay_tree_t *tree, splay_node_t *node) { greatgrandparent = grandparent->parent; if(node == parent->left && parent == grandparent->left) { /* left zig-zig */ - if((grandparent->left = parent->right)) + if((grandparent->left = parent->right)) { grandparent->left->parent = grandparent; + } + parent->right = grandparent; grandparent->parent = parent; - if((parent->left = node->right)) + if((parent->left = node->right)) { parent->left->parent = parent; + } + node->right = parent; parent->parent = node; } else if(node == parent->right && parent == grandparent->right) { /* right zig-zig */ - if((grandparent->right = parent->left)) + if((grandparent->right = parent->left)) { grandparent->right->parent = grandparent; + } + parent->left = grandparent; grandparent->parent = parent; - if((parent->right = node->left)) + if((parent->right = node->left)) { parent->right->parent = parent; + } + node->left = parent; parent->parent = node; } else if(node == parent->right && parent == grandparent->left) { /* left-right zig-zag */ - if((parent->right = node->left)) + if((parent->right = node->left)) { parent->right->parent = parent; + } + node->left = parent; parent->parent = node; - if((grandparent->left = node->right)) + if((grandparent->left = node->right)) { grandparent->left->parent = grandparent; + } + node->right = grandparent; grandparent->parent = node; } else { /* right-left zig-zag */ - if((parent->left = node->right)) + if((parent->left = node->right)) { parent->left->parent = parent; + } + node->right = parent; parent->parent = node; - if((grandparent->right = node->left)) + if((grandparent->right = node->left)) { grandparent->right->parent = grandparent; + } + node->left = grandparent; grandparent->parent = node; } if((node->parent = greatgrandparent)) { - if(grandparent == greatgrandparent->left) + if(grandparent == greatgrandparent->left) { greatgrandparent->left = node; - else + } else { greatgrandparent->right = node; + } } } } @@ -254,8 +283,9 @@ splay_node_t *splay_alloc_node(void) { } void splay_free_node(splay_tree_t *tree, splay_node_t *node) { - if(node->data && tree->delete) + if(node->data && tree->delete) { tree->delete(node->data); + } free(node); } @@ -310,8 +340,10 @@ splay_node_t *splay_search_closest_node_nosplay(const splay_tree_t *tree, const node = tree->root; if(!node) { - if(result) + if(result) { *result = 0; + } + return NULL; } @@ -319,22 +351,26 @@ splay_node_t *splay_search_closest_node_nosplay(const splay_tree_t *tree, const c = tree->compare(data, node->data); if(c < 0) { - if(node->left) + if(node->left) { node = node->left; - else + } else { break; + } } else if(c > 0) { - if(node->right) + if(node->right) { node = node->right; - else + } else { break; + } } else { break; } } - if(result) + if(result) { *result = c; + } + return node; } @@ -348,8 +384,9 @@ splay_node_t *splay_search_closest_smaller_node(splay_tree_t *tree, const void * node = splay_search_closest_node(tree, data, &result); - if(result < 0) + if(result < 0) { node = node->prev; + } return node; } @@ -360,8 +397,9 @@ splay_node_t *splay_search_closest_greater_node(splay_tree_t *tree, const void * node = splay_search_closest_node(tree, data, &result); - if(result > 0) + if(result > 0) { node = node->next; + } return node; } @@ -379,16 +417,18 @@ splay_node_t *splay_insert(splay_tree_t *tree, void *data) { } else { closest = splay_search_closest_node(tree, data, &result); - if(!result) + if(!result) { return NULL; + } new = splay_alloc_node(); new->data = data; - if(result < 0) + if(result < 0) { splay_insert_before(tree, closest, new); - else + } else { splay_insert_after(tree, closest, new); + } } return new; @@ -400,18 +440,20 @@ splay_node_t *splay_insert_node(splay_tree_t *tree, splay_node_t *node) { node->left = node->right = node->parent = node->next = node->prev = NULL; - if(!tree->root) + if(!tree->root) { splay_insert_top(tree, node); - else { + } else { closest = splay_search_closest_node(tree, node->data, &result); - if(!result) + if(!result) { return NULL; + } - if(result < 0) + if(result < 0) { splay_insert_before(tree, closest, node); - else + } else { splay_insert_after(tree, closest, node); + } } return node; @@ -421,64 +463,83 @@ void splay_insert_top(splay_tree_t *tree, splay_node_t *node) { node->prev = node->next = node->left = node->right = node->parent = NULL; tree->head = tree->tail = tree->root = node; tree->count++; + tree->generation++; } void splay_insert_before(splay_tree_t *tree, splay_node_t *before, splay_node_t *node) { if(!before) { - if(tree->tail) + if(tree->tail) { splay_insert_after(tree, tree->tail, node); - else + } else { splay_insert_top(tree, node); + } + return; } node->next = before; - if((node->prev = before->prev)) + + if((node->prev = before->prev)) { before->prev->next = node; - else + } else { tree->head = node; + } + before->prev = node; splay_bottom_up(tree, before); node->right = before; before->parent = node; - if((node->left = before->left)) + + if((node->left = before->left)) { before->left->parent = node; + } + before->left = NULL; node->parent = NULL; tree->root = node; tree->count++; + tree->generation++; } void splay_insert_after(splay_tree_t *tree, splay_node_t *after, splay_node_t *node) { if(!after) { - if(tree->head) + if(tree->head) { splay_insert_before(tree, tree->head, node); - else + } else { splay_insert_top(tree, node); + } + return; } node->prev = after; - if((node->next = after->next)) + + if((node->next = after->next)) { after->next->prev = node; - else + } else { tree->tail = node; + } + after->next = node; splay_bottom_up(tree, after); node->left = after; after->parent = node; - if((node->right = after->right)) + + if((node->right = after->right)) { after->right->parent = node; + } + after->right = NULL; node->parent = NULL; tree->root = node; tree->count++; + tree->generation++; } splay_node_t *splay_unlink(splay_tree_t *tree, void *data) { @@ -486,30 +547,35 @@ splay_node_t *splay_unlink(splay_tree_t *tree, void *data) { node = splay_search_node(tree, data); - if(node) + if(node) { splay_unlink_node(tree, node); + } return node; } void splay_unlink_node(splay_tree_t *tree, splay_node_t *node) { - if(node->prev) + if(node->prev) { node->prev->next = node->next; - else + } else { tree->head = node->next; + } - if(node->next) + if(node->next) { node->next->prev = node->prev; - else + } else { tree->tail = node->prev; + } splay_bottom_up(tree, node); if(node->prev) { node->left->parent = NULL; tree->root = node->left; - if((node->prev->right = node->right)) + + if((node->prev->right = node->right)) { node->right->parent = node->prev; + } } else if(node->next) { tree->root = node->right; node->right->parent = NULL; @@ -518,6 +584,7 @@ void splay_unlink_node(splay_tree_t *tree, splay_node_t *node) { } tree->count--; + tree->generation++; } void splay_delete_node(splay_tree_t *tree, splay_node_t *node) { @@ -530,8 +597,9 @@ void splay_delete(splay_tree_t *tree, void *data) { node = splay_search_node(tree, data); - if(node) + if(node) { splay_delete_node(tree, node); + } } /* Fast tree cleanup */ diff --git a/src/splay_tree.h b/src/splay_tree.h index 3ddf217..d5ab742 100644 --- a/src/splay_tree.h +++ b/src/splay_tree.h @@ -1,3 +1,6 @@ +#ifndef TINC_SPLAY_TREE_H +#define TINC_SPLAY_TREE_H + /* splay_tree.h -- header file for splay_tree.c Copyright (C) 2004-2013 Guus Sliepen @@ -17,10 +20,6 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ - -#ifndef __SPLAY_TREE_H__ -#define __SPLAY_TREE_H__ - typedef struct splay_node_t { /* Linked list part */ @@ -40,9 +39,9 @@ typedef struct splay_node_t { } splay_node_t; -typedef int (*splay_compare_t)(const void *, const void *); -typedef void (*splay_action_t)(const void *); -typedef void (*splay_action_node_t)(const splay_node_t *); +typedef int (*splay_compare_t)(const void *data1, const void *data2); +typedef void (*splay_action_t)(const void *data); +typedef void (*splay_action_node_t)(const splay_node_t *node); typedef struct splay_tree_t { @@ -58,53 +57,54 @@ typedef struct splay_tree_t { splay_compare_t compare; splay_action_t delete; - int count; + unsigned int count; + unsigned int generation; } splay_tree_t; /* (De)constructors */ -extern splay_tree_t *splay_alloc_tree(splay_compare_t, splay_action_t) __attribute__ ((__malloc__)); -extern void splay_free_tree(splay_tree_t *); +extern splay_tree_t *splay_alloc_tree(splay_compare_t compare, splay_action_t delete) __attribute__((__malloc__)); +extern void splay_free_tree(splay_tree_t *tree); -extern splay_node_t *splay_alloc_node(void) __attribute__ ((__malloc__)); -extern void splay_free_node(splay_tree_t *tree, splay_node_t *); +extern splay_node_t *splay_alloc_node(void) __attribute__((__malloc__)); +extern void splay_free_node(splay_tree_t *tree, splay_node_t *node); /* Insertion and deletion */ -extern splay_node_t *splay_insert(splay_tree_t *, void *); -extern splay_node_t *splay_insert_node(splay_tree_t *, splay_node_t *); +extern splay_node_t *splay_insert(splay_tree_t *tree, void *data); +extern splay_node_t *splay_insert_node(splay_tree_t *tree, splay_node_t *node); -extern void splay_insert_top(splay_tree_t *, splay_node_t *); -extern void splay_insert_before(splay_tree_t *, splay_node_t *, splay_node_t *); -extern void splay_insert_after(splay_tree_t *, splay_node_t *, splay_node_t *); +extern void splay_insert_top(splay_tree_t *tree, splay_node_t *node); +extern void splay_insert_before(splay_tree_t *tree, splay_node_t *before, splay_node_t *node); +extern void splay_insert_after(splay_tree_t *tree, splay_node_t *after, splay_node_t *node); -extern splay_node_t *splay_unlink(splay_tree_t *, void *); -extern void splay_unlink_node(splay_tree_t *tree, splay_node_t *); -extern void splay_delete(splay_tree_t *, void *); -extern void splay_delete_node(splay_tree_t *, splay_node_t *); +extern splay_node_t *splay_unlink(splay_tree_t *tree, void *data); +extern void splay_unlink_node(splay_tree_t *tree, splay_node_t *node); +extern void splay_delete(splay_tree_t *tree, void *data); +extern void splay_delete_node(splay_tree_t *tree, splay_node_t *node); /* Fast tree cleanup */ -extern void splay_delete_tree(splay_tree_t *); +extern void splay_delete_tree(splay_tree_t *tree); /* Searching */ -extern void *splay_search(splay_tree_t *, const void *); -extern void *splay_search_closest(splay_tree_t *, const void *, int *); -extern void *splay_search_closest_smaller(splay_tree_t *, const void *); -extern void *splay_search_closest_greater(splay_tree_t *, const void *); +extern void *splay_search(splay_tree_t *tree, const void *data); +extern void *splay_search_closest(splay_tree_t *tree, const void *data, int *result); +extern void *splay_search_closest_smaller(splay_tree_t *tree, const void *data); +extern void *splay_search_closest_greater(splay_tree_t *tree, const void *data); -extern splay_node_t *splay_search_node(splay_tree_t *, const void *); -extern splay_node_t *splay_search_closest_node(splay_tree_t *, const void *, int *); -extern splay_node_t *splay_search_closest_node_nosplay(const splay_tree_t *, const void *, int *); -extern splay_node_t *splay_search_closest_smaller_node(splay_tree_t *, const void *); -extern splay_node_t *splay_search_closest_greater_node(splay_tree_t *, const void *); +extern splay_node_t *splay_search_node(splay_tree_t *tree, const void *data); +extern splay_node_t *splay_search_closest_node(splay_tree_t *tree, const void *data, int *result); +extern splay_node_t *splay_search_closest_node_nosplay(const splay_tree_t *tree, const void *data, int *result); +extern splay_node_t *splay_search_closest_smaller_node(splay_tree_t *tree, const void *data); +extern splay_node_t *splay_search_closest_greater_node(splay_tree_t *tree, const void *data); /* Tree walking */ -extern void splay_foreach(const splay_tree_t *, splay_action_t); -extern void splay_foreach_node(const splay_tree_t *, splay_action_t); +extern void splay_foreach(const splay_tree_t *tree, splay_action_t action); +extern void splay_foreach_node(const splay_tree_t *tree, splay_action_t action); /* Iterates over a tree. diff --git a/src/sptps.c b/src/sptps.c index a1fd5e7..eeaf833 100644 --- a/src/sptps.c +++ b/src/sptps.c @@ -51,9 +51,16 @@ unsigned int sptps_replaywin = 16; */ void sptps_log_quiet(sptps_t *s, int s_errno, const char *format, va_list ap) { + (void)s; + (void)s_errno; + (void)format; + (void)ap; } void sptps_log_stderr(sptps_t *s, int s_errno, const char *format, va_list ap) { + (void)s; + (void)s_errno; + vfprintf(stderr, format, ap); fputc('\n', stderr); } @@ -62,6 +69,9 @@ void (*sptps_log)(sptps_t *s, int s_errno, const char *format, va_list ap) = spt // Log an error message. static bool error(sptps_t *s, int s_errno, const char *format, ...) { + (void)s; + (void)s_errno; + if(format) { va_list ap; va_start(ap, format); @@ -103,8 +113,9 @@ static bool send_record_priv_datagram(sptps_t *s, uint8_t type, const void *data } // Send a record (private version, accepts all record types, handles encryption and authentication). static bool send_record_priv(sptps_t *s, uint8_t type, const void *data, uint16_t len) { - if(s->datagram) + if(s->datagram) { return send_record_priv_datagram(s, type, data, len); + } char buffer[len + 19UL]; @@ -130,11 +141,13 @@ static bool send_record_priv(sptps_t *s, uint8_t type, const void *data, uint16_ bool sptps_send_record(sptps_t *s, uint8_t type, const void *data, uint16_t len) { // Sanity checks: application cannot send data before handshake is finished, // and only record types 0..127 are allowed. - if(!s->outstate) + if(!s->outstate) { return error(s, EINVAL, "Handshake phase not finished yet"); + } - if(type >= SPTPS_HANDSHAKE) + if(type >= SPTPS_HANDSHAKE) { return error(s, EINVAL, "Invalid application record type"); + } return send_record_priv(s, type, data, len); } @@ -144,11 +157,15 @@ static bool send_kex(sptps_t *s) { size_t keylen = ECDH_SIZE; // Make room for our KEX message, which we will keep around since send_sig() needs it. - if(s->mykex) + if(s->mykex) { return false; + } + s->mykex = realloc(s->mykex, 1 + 32 + keylen); - if(!s->mykex) + + if(!s->mykex) { return error(s, errno, strerror(errno)); + } // Set version byte to zero. s->mykex[0] = SPTPS_VERSION; @@ -157,8 +174,9 @@ static bool send_kex(sptps_t *s) { randomize(s->mykex + 1, 32); // Create a new ECDH public key. - if(!(s->ecdh = ecdh_generate_public(s->mykex + 1 + 32))) + if(!(s->ecdh = ecdh_generate_public(s->mykex + 1 + 32))) { return error(s, EINVAL, "Failed to generate ECDH public key"); + } return send_record_priv(s, SPTPS_HANDSHAKE, s->mykex, 1 + 32 + keylen); } @@ -178,11 +196,12 @@ static bool send_sig(sptps_t *s) { memcpy(msg + 1 + 2 * (33 + keylen), s->label, s->labellen); // Sign the result. - if(!ecdsa_sign(s->mykey, msg, sizeof msg, sig)) + if(!ecdsa_sign(s->mykey, msg, sizeof(msg), sig)) { return error(s, EINVAL, "Failed to sign SIG record"); + } // Send the SIG exchange record. - return send_record_priv(s, SPTPS_HANDSHAKE, sig, sizeof sig); + return send_record_priv(s, SPTPS_HANDSHAKE, sig, sizeof(sig)); } // Generate key material from the shared secret created from the ECDHE key exchange. @@ -191,20 +210,25 @@ static bool generate_key_material(sptps_t *s, const char *shared, size_t len) { if(!s->outstate) { s->incipher = chacha_poly1305_init(); s->outcipher = chacha_poly1305_init(); - if(!s->incipher || !s->outcipher) + + if(!s->incipher || !s->outcipher) { return error(s, EINVAL, "Failed to open cipher"); + } } // Allocate memory for key material size_t keylen = 2 * CHACHA_POLY1305_KEYLEN; s->key = realloc(s->key, keylen); - if(!s->key) + + if(!s->key) { return error(s, errno, strerror(errno)); + } // Create the HMAC seed, which is "key expansion" + session label + server nonce + client nonce char seed[s->labellen + 64 + 13]; memcpy(seed, "key expansion", 13); + if(s->initiator) { memcpy(seed + 13, s->mykex + 1, 32); memcpy(seed + 45, s->hiskex + 1, 32); @@ -212,11 +236,13 @@ static bool generate_key_material(sptps_t *s, const char *shared, size_t len) { memcpy(seed + 13, s->hiskex + 1, 32); memcpy(seed + 45, s->mykex + 1, 32); } + memcpy(seed + 77, s->label, s->labellen); // Use PRF to generate the key material - if(!prf(shared, len, seed, s->labellen + 64 + 13, s->key, keylen)) + if(!prf(shared, len, seed, s->labellen + 64 + 13, s->key, keylen)) { return error(s, EINVAL, "Failed to generate key material"); + } return true; } @@ -228,15 +254,20 @@ static bool send_ack(sptps_t *s) { // Receive an ACKnowledgement record. static bool receive_ack(sptps_t *s, const char *data, uint16_t len) { - if(len) + (void)data; + + if(len) { return error(s, EIO, "Invalid ACK record length"); + } if(s->initiator) { - if(!chacha_poly1305_set_key(s->incipher, s->key)) + if(!chacha_poly1305_set_key(s->incipher, s->key)) { return error(s, EINVAL, "Failed to set counter"); + } } else { - if(!chacha_poly1305_set_key(s->incipher, s->key + CHACHA_POLY1305_KEYLEN)) + if(!chacha_poly1305_set_key(s->incipher, s->key + CHACHA_POLY1305_KEYLEN)) { return error(s, EINVAL, "Failed to set counter"); + } } free(s->key); @@ -249,21 +280,30 @@ static bool receive_ack(sptps_t *s, const char *data, uint16_t len) { // Receive a Key EXchange record, respond by sending a SIG record. static bool receive_kex(sptps_t *s, const char *data, uint16_t len) { // Verify length of the HELLO record - if(len != 1 + 32 + ECDH_SIZE) + if(len != 1 + 32 + ECDH_SIZE) { return error(s, EIO, "Invalid KEX record length"); + } // Ignore version number for now. // Make a copy of the KEX message, send_sig() and receive_sig() need it - if(s->hiskex) + if(s->hiskex) { return error(s, EINVAL, "Received a second KEX message before first has been processed"); + } + s->hiskex = realloc(s->hiskex, len); - if(!s->hiskex) + + if(!s->hiskex) { return error(s, errno, strerror(errno)); + } memcpy(s->hiskex, data, len); - return send_sig(s); + if(s->initiator) { + return send_sig(s); + } else { + return true; + } } // Receive a SIGnature record, verify it, if it passed, compute the shared secret and calculate the session keys. @@ -272,8 +312,9 @@ static bool receive_sig(sptps_t *s, const char *data, uint16_t len) { size_t siglen = ecdsa_size(s->hiskey); // Verify length of KEX record. - if(len != siglen) + if(len != siglen) { return error(s, EIO, "Invalid KEX record length"); + } // Concatenate both KEX messages, plus tag indicating if it is from the connection originator char msg[(1 + 32 + keylen) * 2 + 1 + s->labellen]; @@ -284,18 +325,27 @@ static bool receive_sig(sptps_t *s, const char *data, uint16_t len) { memcpy(msg + 1 + 2 * (33 + keylen), s->label, s->labellen); // Verify signature. - if(!ecdsa_verify(s->hiskey, msg, sizeof msg, data)) + if(!ecdsa_verify(s->hiskey, msg, sizeof(msg), data)) { return error(s, EIO, "Failed to verify SIG record"); + } // Compute shared secret. char shared[ECDH_SHARED_SIZE]; - if(!ecdh_compute_shared(s->ecdh, s->hiskex + 1 + 32, shared)) + + if(!ecdh_compute_shared(s->ecdh, s->hiskex + 1 + 32, shared)) { return error(s, EINVAL, "Failed to compute ECDH shared secret"); + } + s->ecdh = NULL; // Generate key material from shared secret. - if(!generate_key_material(s, shared, sizeof shared)) + if(!generate_key_material(s, shared, sizeof(shared))) { return false; + } + + if(!s->initiator && !send_sig(s)) { + return false; + } free(s->mykex); free(s->hiskex); @@ -304,16 +354,19 @@ static bool receive_sig(sptps_t *s, const char *data, uint16_t len) { s->hiskex = NULL; // Send cipher change record - if(s->outstate && !send_ack(s)) + if(s->outstate && !send_ack(s)) { return false; + } // TODO: only set new keys after ACK has been set/received if(s->initiator) { - if(!chacha_poly1305_set_key(s->outcipher, s->key + CHACHA_POLY1305_KEYLEN)) + if(!chacha_poly1305_set_key(s->outcipher, s->key + CHACHA_POLY1305_KEYLEN)) { return error(s, EINVAL, "Failed to set key"); + } } else { - if(!chacha_poly1305_set_key(s->outcipher, s->key)) + if(!chacha_poly1305_set_key(s->outcipher, s->key)) { return error(s, EINVAL, "Failed to set key"); + } } return true; @@ -321,8 +374,9 @@ static bool receive_sig(sptps_t *s, const char *data, uint16_t len) { // Force another Key EXchange (for testing purposes). bool sptps_force_kex(sptps_t *s) { - if(!s->outstate || s->state != SPTPS_SECONDARY_KEX) + if(!s->outstate || s->state != SPTPS_SECONDARY_KEX) { return error(s, EINVAL, "Cannot force KEX in current state"); + } s->state = SPTPS_KEX; return send_kex(s); @@ -332,41 +386,60 @@ bool sptps_force_kex(sptps_t *s) { static bool receive_handshake(sptps_t *s, const char *data, uint16_t len) { // Only a few states to deal with handshaking. switch(s->state) { - case SPTPS_SECONDARY_KEX: - // We receive a secondary KEX request, first respond by sending our own. - if(!send_kex(s)) + case SPTPS_SECONDARY_KEX: + + // We receive a secondary KEX request, first respond by sending our own. + if(!send_kex(s)) { + return false; + } + + // Fall through + case SPTPS_KEX: + + // We have sent our KEX request, we expect our peer to sent one as well. + if(!receive_kex(s, data, len)) { + return false; + } + + s->state = SPTPS_SIG; + return true; + + case SPTPS_SIG: + + // If we already sent our secondary public ECDH key, we expect the peer to send his. + if(!receive_sig(s, data, len)) { + return false; + } + + if(s->outstate) { + s->state = SPTPS_ACK; + } else { + s->outstate = true; + + if(!receive_ack(s, NULL, 0)) { return false; - case SPTPS_KEX: - // We have sent our KEX request, we expect our peer to sent one as well. - if(!receive_kex(s, data, len)) - return false; - s->state = SPTPS_SIG; - return true; - case SPTPS_SIG: - // If we already sent our secondary public ECDH key, we expect the peer to send his. - if(!receive_sig(s, data, len)) - return false; - if(s->outstate) - s->state = SPTPS_ACK; - else { - s->outstate = true; - if(!receive_ack(s, NULL, 0)) - return false; - s->receive_record(s->handle, SPTPS_HANDSHAKE, NULL, 0); - s->state = SPTPS_SECONDARY_KEX; } - return true; - case SPTPS_ACK: - // We expect a handshake message to indicate transition to the new keys. - if(!receive_ack(s, data, len)) - return false; s->receive_record(s->handle, SPTPS_HANDSHAKE, NULL, 0); s->state = SPTPS_SECONDARY_KEX; - return true; - // TODO: split ACK into a VERify and ACK? - default: - return error(s, EIO, "Invalid session state %d", s->state); + } + + return true; + + case SPTPS_ACK: + + // We expect a handshake message to indicate transition to the new keys. + if(!receive_ack(s, data, len)) { + return false; + } + + s->receive_record(s->handle, SPTPS_HANDSHAKE, NULL, 0); + s->state = SPTPS_SECONDARY_KEX; + return true; + + // TODO: split ACK into a VERify and ACK? + default: + return error(s, EIO, "Invalid session state %d", s->state); } } @@ -381,59 +454,73 @@ static bool sptps_check_seqno(sptps_t *s, uint32_t seqno, bool update_state) { if(seqno >= s->inseqno + s->replaywin * 8) { // Prevent packets that jump far ahead of the queue from causing many others to be dropped. bool farfuture = s->farfuture < s->replaywin >> 2; - if (update_state) + + if(update_state) { s->farfuture++; - if(farfuture) + } + + if(farfuture) { return update_state ? error(s, EIO, "Packet is %d seqs in the future, dropped (%u)\n", seqno - s->inseqno, s->farfuture) : false; + } // Unless we have seen lots of them, in which case we consider the others lost. - if(update_state) + if(update_state) { warning(s, "Lost %d packets\n", seqno - s->inseqno); - if (update_state) { + } + + if(update_state) { // Mark all packets in the replay window as being late. memset(s->late, 255, s->replaywin); } - } else if (seqno < s->inseqno) { + } else if(seqno < s->inseqno) { // If the sequence number is farther in the past than the bitmap goes, or if the packet was already received, drop it. - if((s->inseqno >= s->replaywin * 8 && seqno < s->inseqno - s->replaywin * 8) || !(s->late[(seqno / 8) % s->replaywin] & (1 << seqno % 8))) + if((s->inseqno >= s->replaywin * 8 && seqno < s->inseqno - s->replaywin * 8) || !(s->late[(seqno / 8) % s->replaywin] & (1 << seqno % 8))) { return update_state ? error(s, EIO, "Received late or replayed packet, seqno %d, last received %d\n", seqno, s->inseqno) : false; - } else if (update_state) { + } + } else if(update_state) { // We missed some packets. Mark them in the bitmap as being late. - for(int i = s->inseqno; i < seqno; i++) + for(uint32_t i = s->inseqno; i < seqno; i++) { s->late[(i / 8) % s->replaywin] |= 1 << i % 8; + } } } - if (update_state) { + if(update_state) { // Mark the current packet as not being late. s->late[(seqno / 8) % s->replaywin] &= ~(1 << seqno % 8); s->farfuture = 0; } } - if (update_state) { - if(seqno >= s->inseqno) + if(update_state) { + if(seqno >= s->inseqno) { s->inseqno = seqno + 1; + } - if(!s->inseqno) + if(!s->inseqno) { s->received = 0; - else + } else { s->received++; + } } return true; } // Check datagram for valid HMAC -bool sptps_verify_datagram(sptps_t *s, const void *data, size_t len) { - if(!s->instate || len < 21) +bool sptps_verify_datagram(sptps_t *s, const void *vdata, size_t len) { + if(!s->instate || len < 21) { return error(s, EIO, "Received short packet"); + } + const char *data = vdata; uint32_t seqno; memcpy(&seqno, data, 4); seqno = ntohl(seqno); - if (!sptps_check_seqno(s, seqno, false)) + + if(!sptps_check_seqno(s, seqno, false)) { return false; + } char buffer[len]; size_t outlen; @@ -442,24 +529,29 @@ bool sptps_verify_datagram(sptps_t *s, const void *data, size_t len) { // Receive incoming data, datagram version. static bool sptps_receive_data_datagram(sptps_t *s, const char *data, size_t len) { - if(len < (s->instate ? 21 : 5)) + if(len < (s->instate ? 21 : 5)) { return error(s, EIO, "Received short packet"); + } uint32_t seqno; memcpy(&seqno, data, 4); seqno = ntohl(seqno); - data += 4; len -= 4; + data += 4; + len -= 4; if(!s->instate) { - if(seqno != s->inseqno) + if(seqno != s->inseqno) { return error(s, EIO, "Invalid packet seqno: %d != %d", seqno, s->inseqno); + } s->inseqno = seqno + 1; - uint8_t type = *(data++); len--; + uint8_t type = *(data++); + len--; - if(type != SPTPS_HANDSHAKE) + if(type != SPTPS_HANDSHAKE) { return error(s, EIO, "Application record received before handshake finished"); + } return receive_handshake(s, data, len); } @@ -468,11 +560,14 @@ static bool sptps_receive_data_datagram(sptps_t *s, const char *data, size_t len char buffer[len]; size_t outlen; - if(!chacha_poly1305_decrypt(s->incipher, seqno, data, len, buffer, &outlen)) - return error(s, EIO, "Failed to decrypt and verify packet"); - if(!sptps_check_seqno(s, seqno, true)) + if(!chacha_poly1305_decrypt(s->incipher, seqno, data, len, buffer, &outlen)) { + return error(s, EIO, "Failed to decrypt and verify packet"); + } + + if(!sptps_check_seqno(s, seqno, true)) { return false; + } // Append a NULL byte for safety. buffer[outlen] = 0; @@ -480,16 +575,21 @@ static bool sptps_receive_data_datagram(sptps_t *s, const char *data, size_t len data = buffer; len = outlen; - uint8_t type = *(data++); len--; + uint8_t type = *(data++); + len--; if(type < SPTPS_HANDSHAKE) { - if(!s->instate) + if(!s->instate) { return error(s, EIO, "Application record received before handshake finished"); - if(!s->receive_record(s->handle, type, data, len)) + } + + if(!s->receive_record(s->handle, type, data, len)) { return false; + } } else if(type == SPTPS_HANDSHAKE) { - if(!receive_handshake(s, data, len)) + if(!receive_handshake(s, data, len)) { return false; + } } else { return error(s, EIO, "Invalid record type %d", type); } @@ -498,20 +598,25 @@ static bool sptps_receive_data_datagram(sptps_t *s, const char *data, size_t len } // Receive incoming data. Check if it contains a complete record, if so, handle it. -size_t sptps_receive_data(sptps_t *s, const void *data, size_t len) { +size_t sptps_receive_data(sptps_t *s, const void *vdata, size_t len) { + const char *data = vdata; size_t total_read = 0; - if(!s->state) + if(!s->state) { return error(s, EIO, "Invalid session state zero"); + } - if(s->datagram) + if(s->datagram) { return sptps_receive_data_datagram(s, data, len) ? len : false; + } // First read the 2 length bytes. if(s->buflen < 2) { size_t toread = 2 - s->buflen; - if(toread > len) + + if(toread > len) { toread = len; + } memcpy(s->inbuf + s->buflen, data, toread); @@ -521,8 +626,9 @@ size_t sptps_receive_data(sptps_t *s, const void *data, size_t len) { data += toread; // Exit early if we don't have the full length. - if(s->buflen < 2) + if(s->buflen < 2) { return total_read; + } // Get the length bytes @@ -531,26 +637,32 @@ size_t sptps_receive_data(sptps_t *s, const void *data, size_t len) { // If we have the length bytes, ensure our buffer can hold the whole request. s->inbuf = realloc(s->inbuf, s->reclen + 19UL); - if(!s->inbuf) + + if(!s->inbuf) { return error(s, errno, strerror(errno)); + } // Exit early if we have no more data to process. - if(!len) + if(!len) { return total_read; + } } // Read up to the end of the record. size_t toread = s->reclen + (s->instate ? 19UL : 3UL) - s->buflen; - if(toread > len) + + if(toread > len) { toread = len; + } memcpy(s->inbuf + s->buflen, data, toread); total_read += toread; s->buflen += toread; // If we don't have a whole record, exit. - if(s->buflen < s->reclen + (s->instate ? 19UL : 3UL)) + if(s->buflen < s->reclen + (s->instate ? 19UL : 3UL)) { return total_read; + } // Update sequence number. @@ -558,8 +670,9 @@ size_t sptps_receive_data(sptps_t *s, const void *data, size_t len) { // Check HMAC and decrypt. if(s->instate) { - if(!chacha_poly1305_decrypt(s->incipher, seqno, s->inbuf + 2UL, s->reclen + 17UL, s->inbuf + 2UL, NULL)) + if(!chacha_poly1305_decrypt(s->incipher, seqno, s->inbuf + 2UL, s->reclen + 17UL, s->inbuf + 2UL, NULL)) { return error(s, EINVAL, "Failed to decrypt and verify record"); + } } // Append a NULL byte for safety. @@ -568,13 +681,17 @@ size_t sptps_receive_data(sptps_t *s, const void *data, size_t len) { uint8_t type = s->inbuf[2]; if(type < SPTPS_HANDSHAKE) { - if(!s->instate) + if(!s->instate) { return error(s, EIO, "Application record received before handshake finished"); - if(!s->receive_record(s->handle, type, s->inbuf + 3, s->reclen)) + } + + if(!s->receive_record(s->handle, type, s->inbuf + 3, s->reclen)) { return false; + } } else if(type == SPTPS_HANDSHAKE) { - if(!receive_handshake(s, s->inbuf + 3, s->reclen)) + if(!receive_handshake(s, s->inbuf + 3, s->reclen)) { return false; + } } else { return error(s, EIO, "Invalid record type %d", type); } @@ -587,7 +704,7 @@ size_t sptps_receive_data(sptps_t *s, const void *data, size_t len) { // Start a SPTPS session. bool sptps_start(sptps_t *s, void *handle, bool initiator, bool datagram, ecdsa_t *mykey, ecdsa_t *hiskey, const void *label, size_t labellen, send_data_t send_data, receive_record_t receive_record) { // Initialise struct sptps - memset(s, 0, sizeof *s); + memset(s, 0, sizeof(*s)); s->handle = handle; s->initiator = initiator; @@ -595,21 +712,30 @@ bool sptps_start(sptps_t *s, void *handle, bool initiator, bool datagram, ecdsa_ s->mykey = mykey; s->hiskey = hiskey; s->replaywin = sptps_replaywin; + if(s->replaywin) { s->late = malloc(s->replaywin); - if(!s->late) + + if(!s->late) { return error(s, errno, strerror(errno)); + } + memset(s->late, 0, s->replaywin); } s->label = malloc(labellen); - if(!s->label) + + if(!s->label) { return error(s, errno, strerror(errno)); + } if(!datagram) { s->inbuf = malloc(7); - if(!s->inbuf) + + if(!s->inbuf) { return error(s, errno, strerror(errno)); + } + s->buflen = 0; } @@ -636,6 +762,6 @@ bool sptps_stop(sptps_t *s) { free(s->key); free(s->label); free(s->late); - memset(s, 0, sizeof *s); + memset(s, 0, sizeof(*s)); return true; } diff --git a/src/sptps.h b/src/sptps.h index 75a9565..f5686f4 100644 --- a/src/sptps.h +++ b/src/sptps.h @@ -1,3 +1,6 @@ +#ifndef TINC_SPTPS_H +#define TINC_SPTPS_H + /* sptps.h -- Simple Peer-to-Peer Security Copyright (C) 2011-2014 Guus Sliepen @@ -17,9 +20,6 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#ifndef __SPTPS_H__ -#define __SPTPS_H__ - #include "system.h" #include "chacha-poly1305/chacha-poly1305.h" diff --git a/src/sptps_keypair.c b/src/sptps_keypair.c index fde8622..51a94ee 100644 --- a/src/sptps_keypair.c +++ b/src/sptps_keypair.c @@ -28,18 +28,22 @@ static char *program_name; void logger(int level, int priority, const char *format, ...) { + (void)level; + (void)priority; va_list ap; + va_start(ap, format); vfprintf(stderr, format, ap); va_end(ap); + fputc('\n', stderr); } static void usage() { fprintf(stderr, "Usage: %s [options] private_key_file public_key_file\n\n", program_name); fprintf(stderr, "Valid options are:\n" - " --help Display this help and exit.\n" - "\n"); + " --help Display this help and exit.\n" + "\n"); fprintf(stderr, "Report bugs to tinc@tinc-vpn.org.\n"); } @@ -54,20 +58,20 @@ int main(int argc, char *argv[]) { int option_index = 0; while((r = getopt_long(argc, argv, "", long_options, &option_index)) != EOF) { - switch (r) { - case 0: /* long option */ - break; + switch(r) { + case 0: /* long option */ + break; - case '?': /* wrong options */ - usage(); - return 1; + case '?': /* wrong options */ + usage(); + return 1; - case 1: /* help */ - usage(); - return 0; + case 1: /* help */ + usage(); + return 0; - default: - break; + default: + break; } } @@ -83,15 +87,19 @@ int main(int argc, char *argv[]) { crypto_init(); ecdsa_t *key = ecdsa_generate(); - if(!key) + + if(!key) { return 1; - + } + FILE *fp = fopen(argv[1], "w"); + if(fp) { if(!ecdsa_write_pem_private_key(key, fp)) { fprintf(stderr, "Could not write ECDSA private key\n"); return 1; } + fclose(fp); } else { fprintf(stderr, "Could not open '%s' for writing: %s\n", argv[1], strerror(errno)); @@ -99,9 +107,12 @@ int main(int argc, char *argv[]) { } fp = fopen(argv[2], "w"); + if(fp) { - if(!ecdsa_write_pem_public_key(key, fp)) + if(!ecdsa_write_pem_public_key(key, fp)) { fprintf(stderr, "Could not write ECDSA public key\n"); + } + fclose(fp); } else { fprintf(stderr, "Could not open '%s' for writing: %s\n", argv[2], strerror(errno)); diff --git a/src/sptps_speed.c b/src/sptps_speed.c index bde3d69..db7314e 100644 --- a/src/sptps_speed.c +++ b/src/sptps_speed.c @@ -29,9 +29,13 @@ #include "sptps.h" // Symbols necessary to link with logger.o -bool send_request(void *c, const char *msg, ...) { return false; } +bool send_request(void *c, const char *msg, ...) { + return false; +} struct list_t *connection_list = NULL; -bool send_meta(void *c, const char *msg , int len) { return false; } +bool send_meta(void *c, const char *msg, int len) { + return false; +} char *logfilename = NULL; bool do_detach = false; struct timeval now; @@ -49,11 +53,15 @@ static bool receive_record(void *handle, uint8_t type, const void *data, uint16_ static void receive_data(sptps_t *sptps) { char buf[4096], *bufp = buf; int fd = *(int *)sptps->handle; - size_t len = recv(fd, buf, sizeof buf, 0); + size_t len = recv(fd, buf, sizeof(buf), 0); + while(len) { size_t done = sptps_receive_data(sptps, bufp, len); - if(!done) + + if(!done) { abort(); + } + bufp += done; len -= done; } @@ -73,8 +81,10 @@ static void clock_start() { static bool clock_countto(double seconds) { clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &end); elapsed = end.tv_sec + end.tv_nsec * 1e-9 - start.tv_sec - start.tv_nsec * 1e-9; - if(elapsed < seconds) + + if(elapsed < seconds) { return ++count; + } rate = count / elapsed; return false; @@ -89,15 +99,18 @@ int main(int argc, char *argv[]) { crypto_init(); - randomize(buf1, sizeof buf1); - randomize(buf2, sizeof buf2); - randomize(buf3, sizeof buf3); + randomize(buf1, sizeof(buf1)); + randomize(buf2, sizeof(buf2)); + randomize(buf3, sizeof(buf3)); // Key generation fprintf(stderr, "Generating keys for %lg seconds: ", duration); - for(clock_start(); clock_countto(duration);) + + for(clock_start(); clock_countto(duration);) { ecdsa_free(ecdsa_generate()); + } + fprintf(stderr, "%17.2lf op/s\n", rate); key1 = ecdsa_generate(); @@ -106,34 +119,46 @@ int main(int argc, char *argv[]) { // Ed25519 signatures fprintf(stderr, "Ed25519 sign for %lg seconds: ", duration); + for(clock_start(); clock_countto(duration);) - if(!ecdsa_sign(key1, buf1, 256, buf2)) + if(!ecdsa_sign(key1, buf1, 256, buf2)) { return 1; + } + fprintf(stderr, "%20.2lf op/s\n", rate); fprintf(stderr, "Ed25519 verify for %lg seconds: ", duration); + for(clock_start(); clock_countto(duration);) if(!ecdsa_verify(key1, buf1, 256, buf2)) { fprintf(stderr, "Signature verification failed\n"); return 1; } + fprintf(stderr, "%18.2lf op/s\n", rate); ecdh1 = ecdh_generate_public(buf1); fprintf(stderr, "ECDH for %lg seconds: ", duration); + for(clock_start(); clock_countto(duration);) { ecdh2 = ecdh_generate_public(buf2); - if(!ecdh2) + + if(!ecdh2) { return 1; - if(!ecdh_compute_shared(ecdh2, buf1, buf3)) + } + + if(!ecdh_compute_shared(ecdh2, buf1, buf3)) { return 1; + } } + fprintf(stderr, "%28.2lf op/s\n", rate); ecdh_free(ecdh1); // SPTPS authentication phase int fd[2]; + if(socketpair(AF_UNIX, SOCK_STREAM, 0, fd)) { fprintf(stderr, "Could not create a UNIX socket pair: %s\n", sockstrerror(sockerrno)); return 1; @@ -142,43 +167,62 @@ int main(int argc, char *argv[]) { struct pollfd pfd[2] = {{fd[0], POLLIN}, {fd[1], POLLIN}}; fprintf(stderr, "SPTPS/TCP authenticate for %lg seconds: ", duration); + for(clock_start(); clock_countto(duration);) { sptps_start(&sptps1, fd + 0, true, false, key1, key2, "sptps_speed", 11, send_data, receive_record); sptps_start(&sptps2, fd + 1, false, false, key2, key1, "sptps_speed", 11, send_data, receive_record); + while(poll(pfd, 2, 0)) { - if(pfd[0].revents) + if(pfd[0].revents) { receive_data(&sptps1); - if(pfd[1].revents) + } + + if(pfd[1].revents) { receive_data(&sptps2); + } } + sptps_stop(&sptps1); sptps_stop(&sptps2); } + fprintf(stderr, "%10.2lf op/s\n", rate * 2); // SPTPS data sptps_start(&sptps1, fd + 0, true, false, key1, key2, "sptps_speed", 11, send_data, receive_record); sptps_start(&sptps2, fd + 1, false, false, key2, key1, "sptps_speed", 11, send_data, receive_record); + while(poll(pfd, 2, 0)) { - if(pfd[0].revents) + if(pfd[0].revents) { receive_data(&sptps1); - if(pfd[1].revents) + } + + if(pfd[1].revents) { receive_data(&sptps2); + } } + fprintf(stderr, "SPTPS/TCP transmit for %lg seconds: ", duration); + for(clock_start(); clock_countto(duration);) { - if(!sptps_send_record(&sptps1, 0, buf1, 1451)) + if(!sptps_send_record(&sptps1, 0, buf1, 1451)) { abort(); + } + receive_data(&sptps2); } + rate *= 2 * 1451 * 8; - if(rate > 1e9) + + if(rate > 1e9) { fprintf(stderr, "%14.2lf Gbit/s\n", rate / 1e9); - else if(rate > 1e6) + } else if(rate > 1e6) { fprintf(stderr, "%14.2lf Mbit/s\n", rate / 1e6); - else if(rate > 1e3) + } else if(rate > 1e3) { fprintf(stderr, "%14.2lf kbit/s\n", rate / 1e3); + } + sptps_stop(&sptps1); sptps_stop(&sptps2); @@ -193,43 +237,62 @@ int main(int argc, char *argv[]) { } fprintf(stderr, "SPTPS/UDP authenticate for %lg seconds: ", duration); + for(clock_start(); clock_countto(duration);) { sptps_start(&sptps1, fd + 0, true, true, key1, key2, "sptps_speed", 11, send_data, receive_record); sptps_start(&sptps2, fd + 1, false, true, key2, key1, "sptps_speed", 11, send_data, receive_record); + while(poll(pfd, 2, 0)) { - if(pfd[0].revents) + if(pfd[0].revents) { receive_data(&sptps1); - if(pfd[1].revents) + } + + if(pfd[1].revents) { receive_data(&sptps2); + } } + sptps_stop(&sptps1); sptps_stop(&sptps2); } + fprintf(stderr, "%10.2lf op/s\n", rate * 2); // SPTPS datagram data sptps_start(&sptps1, fd + 0, true, true, key1, key2, "sptps_speed", 11, send_data, receive_record); sptps_start(&sptps2, fd + 1, false, true, key2, key1, "sptps_speed", 11, send_data, receive_record); + while(poll(pfd, 2, 0)) { - if(pfd[0].revents) + if(pfd[0].revents) { receive_data(&sptps1); - if(pfd[1].revents) + } + + if(pfd[1].revents) { receive_data(&sptps2); + } } + fprintf(stderr, "SPTPS/UDP transmit for %lg seconds: ", duration); + for(clock_start(); clock_countto(duration);) { - if(!sptps_send_record(&sptps1, 0, buf1, 1451)) + if(!sptps_send_record(&sptps1, 0, buf1, 1451)) { abort(); + } + receive_data(&sptps2); } + rate *= 2 * 1451 * 8; - if(rate > 1e9) + + if(rate > 1e9) { fprintf(stderr, "%14.2lf Gbit/s\n", rate / 1e9); - else if(rate > 1e6) + } else if(rate > 1e6) { fprintf(stderr, "%14.2lf Mbit/s\n", rate / 1e6); - else if(rate > 1e3) + } else if(rate > 1e3) { fprintf(stderr, "%14.2lf kbit/s\n", rate / 1e3); + } + sptps_stop(&sptps1); sptps_stop(&sptps2); diff --git a/src/sptps_test.c b/src/sptps_test.c index 8df1046..4ff701e 100644 --- a/src/sptps_test.c +++ b/src/sptps_test.c @@ -31,9 +31,21 @@ #include "utils.h" // Symbols necessary to link with logger.o -bool send_request(void *c, const char *msg, ...) { return false; } +bool send_request(void *c, const char *msg, ...) { + (void)c; + (void)msg; + return false; +} + struct list_t *connection_list = NULL; -bool send_meta(void *c, const char *msg , int len) { return false; } + +bool send_meta(void *c, const char *msg, int len) { + (void)c; + (void)msg; + (void)len; + return false; +} + char *logfilename = NULL; bool do_detach = false; struct timeval now; @@ -47,21 +59,33 @@ static int out = 1; static int addressfamily = AF_UNSPEC; static bool send_data(void *handle, uint8_t type, const void *data, size_t len) { + (void)type; char hex[len * 2 + 1]; bin2hex(data, hex, len); - if(verbose) + + if(verbose) { fprintf(stderr, "Sending %d bytes of data:\n%s\n", (int)len, hex); + } + const int *sock = handle; - if(send(*sock, data, len, 0) != len) + + if((size_t)send(*sock, data, len, 0) != len) { return false; + } + return true; } static bool receive_record(void *handle, uint8_t type, const void *data, uint16_t len) { - if(verbose) + (void)handle; + if(verbose) { fprintf(stderr, "Received type %d record of %u bytes:\n", type, len); - if(!writeonly) + } + + if(!writeonly) { write(out, data, len); + } + return true; } @@ -83,20 +107,20 @@ const char *program_name; static void usage() { fprintf(stderr, "Usage: %s [options] my_ed25519_key_file his_ed25519_key_file [host] port\n\n", program_name); fprintf(stderr, "Valid options are:\n" - " -d, --datagram Enable datagram mode.\n" - " -q, --quit Quit when EOF occurs on stdin.\n" - " -r, --readonly Only send data from the socket to stdout.\n" + " -d, --datagram Enable datagram mode.\n" + " -q, --quit Quit when EOF occurs on stdin.\n" + " -r, --readonly Only send data from the socket to stdout.\n" #ifdef HAVE_LINUX - " -t, --tun Use a tun device instead of stdio.\n" + " -t, --tun Use a tun device instead of stdio.\n" #endif - " -w, --writeonly Only send data from stdin to the socket.\n" - " -L, --packet-loss RATE Fake packet loss of RATE percent.\n" - " -R, --replay-window N Set replay window to N bytes.\n" - " -s, --special Enable special handling of lines starting with #, ^ and $.\n" - " -v, --verbose Display debug messages.\n" - " -4 Use IPv4.\n" - " -6 Use IPv6.\n" - "\n"); + " -w, --writeonly Only send data from stdin to the socket.\n" + " -L, --packet-loss RATE Fake packet loss of RATE percent.\n" + " -R, --replay-window N Set replay window to N bytes.\n" + " -s, --special Enable special handling of lines starting with #, ^ and $.\n" + " -v, --verbose Display debug messages.\n" + " -4 Use IPv4.\n" + " -6 Use IPv6.\n" + "\n"); fprintf(stderr, "Report bugs to tinc@tinc-vpn.org.\n"); } @@ -114,70 +138,70 @@ int main(int argc, char *argv[]) { bool quit = false; while((r = getopt_long(argc, argv, "dqrstwL:W:v46", long_options, &option_index)) != EOF) { - switch (r) { - case 0: /* long option */ - break; + switch(r) { + case 0: /* long option */ + break; - case 'd': /* datagram mode */ - datagram = true; - break; + case 'd': /* datagram mode */ + datagram = true; + break; - case 'q': /* close connection on EOF from stdin */ - quit = true; - break; + case 'q': /* close connection on EOF from stdin */ + quit = true; + break; - case 'r': /* read only */ - readonly = true; - break; + case 'r': /* read only */ + readonly = true; + break; - case 't': /* read only */ + case 't': /* read only */ #ifdef HAVE_LINUX - tun = true; + tun = true; #else - fprintf(stderr, "--tun is only supported on Linux.\n"); - usage(); - return 1; + fprintf(stderr, "--tun is only supported on Linux.\n"); + usage(); + return 1; #endif - break; + break; - case 'w': /* write only */ - writeonly = true; - break; + case 'w': /* write only */ + writeonly = true; + break; - case 'L': /* packet loss rate */ - packetloss = atoi(optarg); - break; + case 'L': /* packet loss rate */ + packetloss = atoi(optarg); + break; - case 'W': /* replay window size */ - sptps_replaywin = atoi(optarg); - break; + case 'W': /* replay window size */ + sptps_replaywin = atoi(optarg); + break; - case 'v': /* be verbose */ - verbose = true; - break; + case 'v': /* be verbose */ + verbose = true; + break; - case 's': /* special character handling */ - special = true; - break; + case 's': /* special character handling */ + special = true; + break; - case '?': /* wrong options */ - usage(); - return 1; + case '?': /* wrong options */ + usage(); + return 1; - case '4': /* IPv4 */ - addressfamily = AF_INET; - break; + case '4': /* IPv4 */ + addressfamily = AF_INET; + break; - case '6': /* IPv6 */ - addressfamily = AF_INET6; - break; + case '6': /* IPv6 */ + addressfamily = AF_INET6; + break; - case 1: /* help */ - usage(); - return 0; + case 1: /* help */ + usage(); + return 0; - default: - break; + default: + break; } } @@ -190,38 +214,48 @@ int main(int argc, char *argv[]) { return 1; } - if(argc > 4) + if(argc > 4) { initiator = true; + } srand(time(NULL)); #ifdef HAVE_LINUX + if(tun) { in = out = open("/dev/net/tun", O_RDWR | O_NONBLOCK); + if(in < 0) { fprintf(stderr, "Could not open tun device: %s\n", strerror(errno)); return 1; } + struct ifreq ifr = { .ifr_flags = IFF_TUN }; + if(ioctl(in, TUNSETIFF, &ifr)) { fprintf(stderr, "Could not configure tun interface: %s\n", strerror(errno)); return 1; } + ifr.ifr_name[IFNAMSIZ - 1] = 0; fprintf(stderr, "Using tun interface %s\n", ifr.ifr_name); } + #endif #ifdef HAVE_MINGW static struct WSAData wsa_state; - if(WSAStartup(MAKEWORD(2, 2), &wsa_state)) + + if(WSAStartup(MAKEWORD(2, 2), &wsa_state)) { return 1; + } + #endif struct addrinfo *ai, hint; - memset(&hint, 0, sizeof hint); + memset(&hint, 0, sizeof(hint)); hint.ai_family = addressfamily; hint.ai_socktype = datagram ? SOCK_DGRAM : SOCK_STREAM; @@ -234,19 +268,21 @@ int main(int argc, char *argv[]) { } int sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); + if(sock < 0) { fprintf(stderr, "Could not create socket: %s\n", sockstrerror(sockerrno)); return 1; } int one = 1; - setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void *)&one, sizeof one); + setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void *)&one, sizeof(one)); if(initiator) { if(connect(sock, ai->ai_addr, ai->ai_addrlen)) { fprintf(stderr, "Could not connect to peer: %s\n", sockstrerror(sockerrno)); return 1; } + fprintf(stderr, "Connected\n"); } else { if(bind(sock, ai->ai_addr, ai->ai_addrlen)) { @@ -259,9 +295,11 @@ int main(int argc, char *argv[]) { fprintf(stderr, "Could not listen on socket: %s\n", sockstrerror(sockerrno)); return 1; } + fprintf(stderr, "Listening...\n"); sock = accept(sock, NULL, NULL); + if(sock < 0) { fprintf(stderr, "Could not accept connection: %s\n", sockstrerror(sockerrno)); return 1; @@ -271,9 +309,9 @@ int main(int argc, char *argv[]) { char buf[65536]; struct sockaddr addr; - socklen_t addrlen = sizeof addr; + socklen_t addrlen = sizeof(addr); - if(recvfrom(sock, buf, sizeof buf, MSG_PEEK, &addr, &addrlen) <= 0) { + if(recvfrom(sock, buf, sizeof(buf), MSG_PEEK, &addr, &addrlen) <= 0) { fprintf(stderr, "Could not read from socket: %s\n", sockstrerror(sockerrno)); return 1; } @@ -290,99 +328,133 @@ int main(int argc, char *argv[]) { crypto_init(); FILE *fp = fopen(argv[1], "r"); + if(!fp) { fprintf(stderr, "Could not open %s: %s\n", argv[1], strerror(errno)); return 1; } - if(!(mykey = ecdsa_read_pem_private_key(fp))) + + if(!(mykey = ecdsa_read_pem_private_key(fp))) { return 1; + } + fclose(fp); fp = fopen(argv[2], "r"); + if(!fp) { fprintf(stderr, "Could not open %s: %s\n", argv[2], strerror(errno)); return 1; } - if(!(hiskey = ecdsa_read_pem_public_key(fp))) + + if(!(hiskey = ecdsa_read_pem_public_key(fp))) { return 1; + } + fclose(fp); - if(verbose) + if(verbose) { fprintf(stderr, "Keys loaded\n"); + } sptps_t s; - if(!sptps_start(&s, &sock, initiator, datagram, mykey, hiskey, "sptps_test", 10, send_data, receive_record)) + + if(!sptps_start(&s, &sock, initiator, datagram, mykey, hiskey, "sptps_test", 10, send_data, receive_record)) { return 1; + } while(true) { - if(writeonly && readonly) + if(writeonly && readonly) { break; + } char buf[65535] = ""; fd_set fds; FD_ZERO(&fds); #ifndef HAVE_MINGW - if(!readonly && s.instate) + + if(!readonly && s.instate) { FD_SET(in, &fds); + } + #endif FD_SET(sock, &fds); - if(select(sock + 1, &fds, NULL, NULL, NULL) <= 0) + + if(select(sock + 1, &fds, NULL, NULL, NULL) <= 0) { return 1; + } if(FD_ISSET(in, &fds)) { - ssize_t len = read(in, buf, sizeof buf); + ssize_t len = read(in, buf, sizeof(buf)); + if(len < 0) { fprintf(stderr, "Could not read from stdin: %s\n", strerror(errno)); return 1; } + if(len == 0) { - if(quit) + if(quit) { break; + } + readonly = true; continue; } - if(special && buf[0] == '#') + + if(special && buf[0] == '#') { s.outseqno = atoi(buf + 1); - if(special && buf[0] == '^') + } + + if(special && buf[0] == '^') { sptps_send_record(&s, SPTPS_HANDSHAKE, NULL, 0); - else if(special && buf[0] == '$') { + } else if(special && buf[0] == '$') { sptps_force_kex(&s); - if(len > 1) + + if(len > 1) { sptps_send_record(&s, 0, buf, len); - } else - if(!sptps_send_record(&s, buf[0] == '!' ? 1 : 0, buf, (len == 1 && buf[0] == '\n') ? 0 : buf[0] == '*' ? sizeof buf : len)) + } + } else if(!sptps_send_record(&s, buf[0] == '!' ? 1 : 0, buf, (len == 1 && buf[0] == '\n') ? 0 : buf[0] == '*' ? sizeof(buf) : (size_t)len)) { return 1; + } } if(FD_ISSET(sock, &fds)) { - ssize_t len = recv(sock, buf, sizeof buf, 0); + ssize_t len = recv(sock, buf, sizeof(buf), 0); + if(len < 0) { fprintf(stderr, "Could not read from socket: %s\n", sockstrerror(sockerrno)); return 1; } + if(len == 0) { fprintf(stderr, "Connection terminated by peer.\n"); break; } + if(verbose) { char hex[len * 2 + 1]; bin2hex(buf, hex, len); fprintf(stderr, "Received %d bytes of data:\n%s\n", (int)len, hex); } + if(packetloss && (rand() % 100) < packetloss) { - if(verbose) + if(verbose) { fprintf(stderr, "Dropped.\n"); + } + continue; } + char *bufp = buf; + while(len) { size_t done = sptps_receive_data(&s, bufp, len); + if(!done) { - if(!datagram) + if(!datagram) { return 1; - } else { - break; + } } bufp += done; @@ -391,8 +463,9 @@ int main(int argc, char *argv[]) { } } - if(!sptps_stop(&s)) + if(!sptps_stop(&s)) { return 1; + } return 0; } diff --git a/src/subnet.c b/src/subnet.c index 3d055b6..4fefda6 100644 --- a/src/subnet.c +++ b/src/subnet.c @@ -92,15 +92,19 @@ void subnet_add(node_t *n, subnet_t *subnet) { subnet->owner = n; splay_insert(subnet_tree, subnet); - if (n) + + if(n) { splay_insert(n->subnet_tree, subnet); + } subnet_cache_flush(); } void subnet_del(node_t *n, subnet_t *subnet) { - if (n) + if(n) { splay_delete(n->subnet_tree, subnet); + } + splay_delete(subnet_tree, subnet); subnet_cache_flush(); @@ -117,26 +121,31 @@ subnet_t *lookup_subnet_mac(const node_t *owner, const mac_t *address) { // Check if this address is cached - if((r = hash_search(mac_cache, address))) + if((r = hash_search(mac_cache, address))) { return r; + } // Search all subnets for a matching one for splay_each(subnet_t, p, owner ? owner->subnet_tree : subnet_tree) { - if(!p || p->type != SUBNET_MAC) + if(!p || p->type != SUBNET_MAC) { continue; + } - if(!memcmp(address, &p->net.mac.address, sizeof *address)) { + if(!memcmp(address, &p->net.mac.address, sizeof(*address))) { r = p; - if(!p->owner || p->owner->status.reachable) + + if(!p->owner || p->owner->status.reachable) { break; + } } } // Cache the result - if(r) + if(r) { hash_insert(mac_cache, address, r); + } return r; } @@ -146,26 +155,31 @@ subnet_t *lookup_subnet_ipv4(const ipv4_t *address) { // Check if this address is cached - if((r = hash_search(ipv4_cache, address))) + if((r = hash_search(ipv4_cache, address))) { return r; + } // Search all subnets for a matching one for splay_each(subnet_t, p, subnet_tree) { - if(!p || p->type != SUBNET_IPV4) + if(!p || p->type != SUBNET_IPV4) { continue; + } if(!maskcmp(address, &p->net.ipv4.address, p->net.ipv4.prefixlength)) { r = p; - if(!p->owner || p->owner->status.reachable) + + if(!p->owner || p->owner->status.reachable) { break; + } } } // Cache the result - if(r) + if(r) { hash_insert(ipv4_cache, address, r); + } return r; } @@ -175,26 +189,31 @@ subnet_t *lookup_subnet_ipv6(const ipv6_t *address) { // Check if this address is cached - if((r = hash_search(ipv6_cache, address))) + if((r = hash_search(ipv6_cache, address))) { return r; + } // Search all subnets for a matching one for splay_each(subnet_t, p, subnet_tree) { - if(!p || p->type != SUBNET_IPV6) + if(!p || p->type != SUBNET_IPV6) { continue; + } if(!maskcmp(address, &p->net.ipv6.address, p->net.ipv6.prefixlength)) { r = p; - if(!p->owner || p->owner->status.reachable) + + if(!p->owner || p->owner->status.reachable) { break; + } } } // Cache the result - if(r) + if(r) { hash_insert(ipv6_cache, address, r); + } return r; } @@ -225,15 +244,18 @@ void subnet_update(node_t *owner, subnet_t *subnet, bool up) { if(!subnet) { for splay_each(subnet_t, subnet, owner->subnet_tree) { - if(!net2str(netstr, sizeof netstr, subnet)) + 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, '#'); - if(weight) + + if(weight) { *weight++ = 0; - else + } else { weight = empty; + } // Prepare the SUBNET and WEIGHT variables environment_update(&env, env_subnet, "SUBNET=%s", netstr); @@ -242,13 +264,15 @@ void subnet_update(node_t *owner, subnet_t *subnet, bool up) { execute_script(name, &env); } } else { - if(net2str(netstr, sizeof netstr, 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, '#'); - if(weight) + + if(weight) { *weight++ = 0; - else + } else { weight = empty; + } // Prepare the SUBNET and WEIGHT variables environment_update(&env, env_subnet, "SUBNET=%s", netstr); @@ -265,12 +289,13 @@ bool dump_subnets(connection_t *c) { for splay_each(subnet_t, subnet, subnet_tree) { char netstr[MAXNETSTR]; - if(!net2str(netstr, sizeof netstr, subnet)) + if(!net2str(netstr, sizeof(netstr), subnet)) { continue; + } send_request(c, "%d %d %s %s", - CONTROL, REQ_DUMP_SUBNETS, - netstr, subnet->owner ? subnet->owner->name : "(broadcast)"); + CONTROL, REQ_DUMP_SUBNETS, + netstr, subnet->owner ? subnet->owner->name : "(broadcast)"); } return send_request(c, "%d %d", CONTROL, REQ_DUMP_SUBNETS); diff --git a/src/subnet.h b/src/subnet.h index 6184e6b..cfdf2d0 100644 --- a/src/subnet.h +++ b/src/subnet.h @@ -1,3 +1,6 @@ +#ifndef TINC_SUBNET_H +#define TINC_SUBNET_H + /* subnet.h -- header for subnet.c Copyright (C) 2000-2012 Guus Sliepen , @@ -18,9 +21,6 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#ifndef __TINC_SUBNET_H__ -#define __TINC_SUBNET_H__ - #include "net.h" #include "node.h" @@ -65,27 +65,27 @@ typedef struct subnet_t { extern splay_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 *); +extern int subnet_compare(const struct subnet_t *a, const struct subnet_t *b); +extern subnet_t *new_subnet(void) __attribute__((__malloc__)); +extern void free_subnet(subnet_t *subnet); extern void init_subnets(void); extern void exit_subnets(void); -extern splay_tree_t *new_subnet_tree(void) __attribute__ ((__malloc__)); +extern splay_tree_t *new_subnet_tree(void) __attribute__((__malloc__)); extern void free_subnet_tree(splay_tree_t *); -extern void subnet_add(struct node_t *, subnet_t *); -extern void subnet_del(struct node_t *, subnet_t *); -extern void subnet_update(struct node_t *, subnet_t *, bool); -extern int maskcmp(const void *, const void *, int); -extern void maskcpy(void *, const void *, int, int); -extern void mask(void *, int, int); -extern bool maskcheck(const void *, int, int); -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 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 bool dump_subnets(struct connection_t *); +extern void subnet_add(struct node_t *owner, subnet_t *subnet); +extern void subnet_del(struct node_t *owner, subnet_t *subnet); +extern void subnet_update(struct node_t *owner, subnet_t *subnet, bool up); +extern int maskcmp(const void *a, const void *b, int masklen); +extern void maskcpy(void *dest, const void *src, int masklen, int len); +extern void mask(void *mask, int masklen, int len); +extern bool maskcheck(const void *mask, int masklen, int len); +extern bool net2str(char *netstr, int len, const subnet_t *subnet); +extern bool str2net(subnet_t *subnet, const char *netstr); +extern subnet_t *lookup_subnet(const struct node_t *owner, const subnet_t *subnet); +extern subnet_t *lookup_subnet_mac(const struct node_t *owner, const mac_t *address); +extern subnet_t *lookup_subnet_ipv4(const ipv4_t *address); +extern subnet_t *lookup_subnet_ipv6(const ipv6_t *address); +extern bool dump_subnets(struct connection_t *c); extern void subnet_cache_flush(void); -#endif /* __TINC_SUBNET_H__ */ +#endif diff --git a/src/subnet_parse.c b/src/subnet_parse.c index c5f6976..d5b84eb 100644 --- a/src/subnet_parse.c +++ b/src/subnet_parse.c @@ -39,13 +39,15 @@ int maskcmp(const void *va, const void *vb, int masklen) { for(m = masklen, i = 0; m >= 8; m -= 8, i++) { result = a[i] - b[i]; - if(result) + + if(result) { return result; + } } if(m) return (a[i] & (0x100 - (1 << (8 - m)))) - - (b[i] & (0x100 - (1 << (8 - m)))); + (b[i] & (0x100 - (1 << (8 - m)))); return 0; } @@ -57,11 +59,13 @@ void mask(void *va, int masklen, int len) { i = masklen / 8; masklen %= 8; - if(masklen) + if(masklen) { a[i++] &= (0x100 - (1 << (8 - masklen))); + } - for(; i < len; i++) + for(; i < len; i++) { a[i] = 0; + } } void maskcpy(void *va, const void *vb, int masklen, int len) { @@ -69,16 +73,18 @@ void maskcpy(void *va, const void *vb, int masklen, int len) { char *a = va; const char *b = vb; - for(m = masklen, i = 0; m >= 8; m -= 8, i++) + for(m = masklen, i = 0; m >= 8; m -= 8, i++) { a[i] = b[i]; + } if(m) { a[i] = b[i] & (0x100 - (1 << (8 - m))); i++; } - for(; i < len; i++) + for(; i < len; i++) { a[i] = 0; + } } bool maskcheck(const void *va, int masklen, int len) { @@ -88,12 +94,14 @@ bool maskcheck(const void *va, int masklen, int len) { i = masklen / 8; masklen %= 8; - if(masklen && a[i++] & (0xff >> masklen)) + if(masklen && a[i++] & (0xff >> masklen)) { return false; + } for(; i < len; i++) - if(a[i] != 0) + if(a[i] != 0) { return false; + } return true; } @@ -103,15 +111,17 @@ bool maskcheck(const void *va, int masklen, int len) { static int subnet_compare_mac(const subnet_t *a, const subnet_t *b) { int result; - result = memcmp(&a->net.mac.address, &b->net.mac.address, sizeof a->net.mac.address); + result = memcmp(&a->net.mac.address, &b->net.mac.address, sizeof(a->net.mac.address)); - if(result) + if(result) { return result; + } result = a->weight - b->weight; - if(result || !a->owner || !b->owner) + if(result || !a->owner || !b->owner) { return result; + } return strcmp(a->owner->name, b->owner->name); } @@ -121,18 +131,21 @@ static int subnet_compare_ipv4(const subnet_t *a, const subnet_t *b) { result = b->net.ipv4.prefixlength - a->net.ipv4.prefixlength; - if(result) + if(result) { return result; + } result = memcmp(&a->net.ipv4.address, &b->net.ipv4.address, sizeof(ipv4_t)); - if(result) + if(result) { return result; + } result = a->weight - b->weight; - if(result || !a->owner || !b->owner) + if(result || !a->owner || !b->owner) { return result; + } return strcmp(a->owner->name, b->owner->name); } @@ -142,18 +155,21 @@ static int subnet_compare_ipv6(const subnet_t *a, const subnet_t *b) { result = b->net.ipv6.prefixlength - a->net.ipv6.prefixlength; - if(result) + if(result) { return result; + } result = memcmp(&a->net.ipv6.address, &b->net.ipv6.address, sizeof(ipv6_t)); - if(result) + if(result) { return result; + } result = a->weight - b->weight; - if(result || !a->owner || !b->owner) + if(result || !a->owner || !b->owner) { return result; + } return strcmp(a->owner->name, b->owner->name); } @@ -163,16 +179,20 @@ int subnet_compare(const subnet_t *a, const subnet_t *b) { result = a->type - b->type; - if(result) + if(result) { return result; + } - switch (a->type) { + switch(a->type) { case SUBNET_MAC: return subnet_compare_mac(a, b); + case SUBNET_IPV4: return subnet_compare_ipv4(a, b); + case SUBNET_IPV6: return subnet_compare_ipv6(a, b); + default: logger(DEBUG_ALWAYS, LOG_ERR, "subnet_compare() was called with unknown subnet type %d, exitting!", a->type); exit(1); @@ -186,119 +206,163 @@ int subnet_compare(const subnet_t *a, const subnet_t *b) { bool str2net(subnet_t *subnet, const char *subnetstr) { char str[1024]; strncpy(str, subnetstr, sizeof(str)); - str[sizeof str - 1] = 0; + str[sizeof(str) - 1] = 0; int consumed; int weight = DEFAULT_WEIGHT; char *weight_separator = strchr(str, '#'); - if (weight_separator) { + + if(weight_separator) { char *weight_str = weight_separator + 1; - if (sscanf(weight_str, "%d%n", &weight, &consumed) < 1) + + if(sscanf(weight_str, "%d%n", &weight, &consumed) < 1) { return false; - if (weight_str[consumed]) + } + + if(weight_str[consumed]) { return false; + } + *weight_separator = 0; } int prefixlength = -1; char *prefixlength_separator = strchr(str, '/'); - if (prefixlength_separator) { - char* prefixlength_str = prefixlength_separator + 1; - if (sscanf(prefixlength_str, "%d%n", &prefixlength, &consumed) < 1) + + if(prefixlength_separator) { + char *prefixlength_str = prefixlength_separator + 1; + + if(sscanf(prefixlength_str, "%d%n", &prefixlength, &consumed) < 1) { return false; - if (prefixlength_str[consumed]) + } + + if(prefixlength_str[consumed]) { return false; + } + *prefixlength_separator = 0; - if (prefixlength < 0) + if(prefixlength < 0) { return false; + } } uint16_t x[8]; - if (sscanf(str, "%hx:%hx:%hx:%hx:%hx:%hx%n", &x[0], &x[1], &x[2], &x[3], &x[4], &x[5], &consumed) >= 6 && !str[consumed]) { + + if(sscanf(str, "%hx:%hx:%hx:%hx:%hx:%hx%n", &x[0], &x[1], &x[2], &x[3], &x[4], &x[5], &consumed) >= 6 && !str[consumed]) { /* Normally we should check that each part has two digits to prevent ambiguities. - However, in old tinc versions net2str() will agressively return MAC addresses with one-digit parts, + However, in old tinc versions net2str() will aggressively return MAC addresses with one-digit parts, so we have to accept them otherwise we would be unable to parse ADD_SUBNET messages. */ - if (prefixlength >= 0) + if(prefixlength >= 0) { return false; + } subnet->type = SUBNET_MAC; subnet->weight = weight; - for(int i = 0; i < 6; i++) + + for(int i = 0; i < 6; i++) { subnet->net.mac.address.x[i] = x[i]; + } + return true; } - if (sscanf(str, "%hu.%hu.%hu.%hu%n", &x[0], &x[1], &x[2], &x[3], &consumed) >= 4 && !str[consumed]) { - if (prefixlength == -1) + if(sscanf(str, "%hu.%hu.%hu.%hu%n", &x[0], &x[1], &x[2], &x[3], &consumed) >= 4 && !str[consumed]) { + if(prefixlength == -1) { prefixlength = 32; - if (prefixlength > 32) + } + + if(prefixlength > 32) { return false; + } subnet->type = SUBNET_IPV4; subnet->net.ipv4.prefixlength = prefixlength; subnet->weight = weight; + for(int i = 0; i < 4; i++) { - if (x[i] > 255) + if(x[i] > 255) { return false; + } + subnet->net.ipv4.address.x[i] = x[i]; } + return true; } /* IPv6 */ - char* last_colon = strrchr(str, ':'); - if (last_colon && sscanf(last_colon, ":%hu.%hu.%hu.%hu%n", &x[0], &x[1], &x[2], &x[3], &consumed) >= 4 && !last_colon[consumed]) { + char *last_colon = strrchr(str, ':'); + + if(last_colon && sscanf(last_colon, ":%hu.%hu.%hu.%hu%n", &x[0], &x[1], &x[2], &x[3], &consumed) >= 4 && !last_colon[consumed]) { /* Dotted quad suffix notation, convert to standard IPv6 notation */ - for (int i = 0; i < 4; i++) - if (x[i] > 255) + for(int i = 0; i < 4; i++) + if(x[i] > 255) { return false; - snprintf(last_colon, sizeof str - (last_colon - str), ":%02x%02x:%02x%02x", x[0], x[1], x[2], x[3]); + } + + snprintf(last_colon, sizeof(str) - (last_colon - str), ":%02x%02x:%02x%02x", x[0], x[1], x[2], x[3]); } - char* double_colon = strstr(str, "::"); - if (double_colon) { + char *double_colon = strstr(str, "::"); + + if(double_colon) { /* Figure out how many zero groups we need to expand */ int zero_group_count = 8; - for (const char* cur = str; *cur; cur++) - if (*cur != ':') { + + for(const char *cur = str; *cur; cur++) + if(*cur != ':') { zero_group_count--; - while(cur[1] && cur[1] != ':') + + while(cur[1] && cur[1] != ':') { cur++; + } } - if (zero_group_count < 1) + + if(zero_group_count < 1) { return false; + } /* Split the double colon in the middle to make room for zero groups */ double_colon++; memmove(double_colon + (zero_group_count * 2 - 1), double_colon, strlen(double_colon) + 1); /* Write zero groups in the resulting gap, overwriting the second colon */ - for (int i = 0; i < zero_group_count; i++) + for(int i = 0; i < zero_group_count; i++) { memcpy(&double_colon[i * 2], "0:", 2); + } /* Remove any leading or trailing colons */ - if (str[0] == ':') + if(str[0] == ':') { memmove(&str[0], &str[1], strlen(&str[1]) + 1); - if (str[strlen(str) - 1] == ':') + } + + if(str[strlen(str) - 1] == ':') { str[strlen(str) - 1] = 0; + } } - if (sscanf(str, "%hx:%hx:%hx:%hx:%hx:%hx:%hx:%hx%n", - &x[0], &x[1], &x[2], &x[3], &x[4], &x[5], &x[6], &x[7], &consumed) >= 8 && !str[consumed]) { - if (prefixlength == -1) + if(sscanf(str, "%hx:%hx:%hx:%hx:%hx:%hx:%hx:%hx%n", + &x[0], &x[1], &x[2], &x[3], &x[4], &x[5], &x[6], &x[7], &consumed) >= 8 && !str[consumed]) { + if(prefixlength == -1) { prefixlength = 128; - if (prefixlength > 128) + } + + if(prefixlength > 128) { return false; + } subnet->type = SUBNET_IPV6; subnet->net.ipv6.prefixlength = prefixlength; subnet->weight = weight; - for(int i = 0; i < 8; i++) + + for(int i = 0; i < 8; i++) { subnet->net.ipv6.address.x[i] = htons(x[i]); + } + return true; } @@ -307,102 +371,120 @@ bool str2net(subnet_t *subnet, const char *subnetstr) { bool net2str(char *netstr, int len, const subnet_t *subnet) { if(!netstr || !subnet) { - logger(DEBUG_ALWAYS, LOG_ERR, "net2str() was called with netstr=%p, subnet=%p!", netstr, subnet); + logger(DEBUG_ALWAYS, LOG_ERR, "net2str() was called with netstr=%p, subnet=%p!", (void *)netstr, (void *)subnet); return false; } int result; int prefixlength = -1; - switch (subnet->type) { - case SUBNET_MAC: - result = snprintf(netstr, len, "%02x:%02x:%02x:%02x:%02x:%02x", - subnet->net.mac.address.x[0], - subnet->net.mac.address.x[1], - subnet->net.mac.address.x[2], - subnet->net.mac.address.x[3], - subnet->net.mac.address.x[4], - subnet->net.mac.address.x[5]); - netstr += result; - len -= result; - break; - case SUBNET_IPV4: - result = snprintf(netstr, len, "%u.%u.%u.%u", - subnet->net.ipv4.address.x[0], - subnet->net.ipv4.address.x[1], - subnet->net.ipv4.address.x[2], - subnet->net.ipv4.address.x[3]); - netstr += result; - len -= result; - prefixlength = subnet->net.ipv4.prefixlength; - if (prefixlength == 32) - prefixlength = -1; - break; + switch(subnet->type) { + case SUBNET_MAC: + result = snprintf(netstr, len, "%02x:%02x:%02x:%02x:%02x:%02x", + subnet->net.mac.address.x[0], + subnet->net.mac.address.x[1], + subnet->net.mac.address.x[2], + subnet->net.mac.address.x[3], + subnet->net.mac.address.x[4], + subnet->net.mac.address.x[5]); + netstr += result; + len -= result; + break; - case SUBNET_IPV6: { - /* Find the longest sequence of consecutive zeroes */ - int max_zero_length = 0; - int max_zero_length_index = 0; - int current_zero_length = 0; - int current_zero_length_index = 0; - for (int i = 0; i < 8; i++) { - if (subnet->net.ipv6.address.x[i] != 0) - current_zero_length = 0; - else { - if (current_zero_length == 0) - current_zero_length_index = i; - current_zero_length++; - if (current_zero_length > max_zero_length) { - max_zero_length = current_zero_length; - max_zero_length_index = current_zero_length_index; - } - } - } + case SUBNET_IPV4: + result = snprintf(netstr, len, "%u.%u.%u.%u", + subnet->net.ipv4.address.x[0], + subnet->net.ipv4.address.x[1], + subnet->net.ipv4.address.x[2], + subnet->net.ipv4.address.x[3]); + netstr += result; + len -= result; + prefixlength = subnet->net.ipv4.prefixlength; - /* Print the address */ - for (int i = 0; i < 8;) { - if (max_zero_length > 1 && max_zero_length_index == i) { - /* Shorten the representation as per RFC 5952 */ - const char* const FORMATS[] = { "%.1s", "%.2s", "%.3s" }; - const char* const* format = &FORMATS[0]; - if (i == 0) - format++; - if (i + max_zero_length == 8) - format++; - result = snprintf(netstr, len, *format, ":::"); - i += max_zero_length; - } else { - result = snprintf(netstr, len, "%x:", ntohs(subnet->net.ipv6.address.x[i])); - i++; - } - netstr += result; - len -= result; - } - - /* Remove the trailing colon */ - netstr--; - len++; - *netstr = 0; - - prefixlength = subnet->net.ipv6.prefixlength; - if (prefixlength == 128) - prefixlength = -1; - break; + if(prefixlength == 32) { + prefixlength = -1; } - default: - logger(DEBUG_ALWAYS, LOG_ERR, "net2str() was called with unknown subnet type %d, exiting!", subnet->type); - exit(1); + break; + + case SUBNET_IPV6: { + /* Find the longest sequence of consecutive zeroes */ + int max_zero_length = 0; + int max_zero_length_index = 0; + int current_zero_length = 0; + int current_zero_length_index = 0; + + for(int i = 0; i < 8; i++) { + if(subnet->net.ipv6.address.x[i] != 0) { + current_zero_length = 0; + } else { + if(current_zero_length == 0) { + current_zero_length_index = i; + } + + current_zero_length++; + + if(current_zero_length > max_zero_length) { + max_zero_length = current_zero_length; + max_zero_length_index = current_zero_length_index; + } + } + } + + /* Print the address */ + for(int i = 0; i < 8;) { + if(max_zero_length > 1 && max_zero_length_index == i) { + /* Shorten the representation as per RFC 5952 */ + const char *const FORMATS[] = { "%.1s", "%.2s", "%.3s" }; + const char *const *format = &FORMATS[0]; + + if(i == 0) { + format++; + } + + if(i + max_zero_length == 8) { + format++; + } + + result = snprintf(netstr, len, *format, ":::"); + i += max_zero_length; + } else { + result = snprintf(netstr, len, "%x:", ntohs(subnet->net.ipv6.address.x[i])); + i++; + } + + netstr += result; + len -= result; + } + + /* Remove the trailing colon */ + netstr--; + len++; + *netstr = 0; + + prefixlength = subnet->net.ipv6.prefixlength; + + if(prefixlength == 128) { + prefixlength = -1; + } + + break; } - if (prefixlength >= 0) { + default: + logger(DEBUG_ALWAYS, LOG_ERR, "net2str() was called with unknown subnet type %d, exiting!", subnet->type); + exit(1); + } + + if(prefixlength >= 0) { result = snprintf(netstr, len, "/%d", prefixlength); netstr += result; len -= result; } - if (subnet->weight != DEFAULT_WEIGHT) + if(subnet->weight != DEFAULT_WEIGHT) { snprintf(netstr, len, "#%d", subnet->weight); + } return true; } diff --git a/src/system.h b/src/system.h index 2201ff3..f9675f9 100644 --- a/src/system.h +++ b/src/system.h @@ -1,3 +1,6 @@ +#ifndef TINC_SYSTEM_H +#define TINC_SYSTEM_H + /* system.h -- system headers Copyright (C) 1998-2005 Ivo Timmermans @@ -18,9 +21,6 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#ifndef __TINC_SYSTEM_H__ -#define __TINC_SYSTEM_H__ - #include "../config.h" #include "have.h" @@ -33,4 +33,4 @@ #include "dropin.h" -#endif /* __TINC_SYSTEM_H__ */ +#endif diff --git a/src/tincctl.c b/src/tincctl.c index 9eb9a1b..dccd49d 100644 --- a/src/tincctl.c +++ b/src/tincctl.c @@ -1,6 +1,6 @@ /* tincctl.c -- Controlling a running tincd - Copyright (C) 2007-2017 Guus Sliepen + Copyright (C) 2007-2018 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 @@ -91,12 +91,12 @@ static struct option const long_options[] = { static void version(void) { printf("%s version %s (built %s %s, protocol %d.%d)\n", PACKAGE, - BUILD_VERSION, BUILD_DATE, BUILD_TIME, PROT_MAJOR, PROT_MINOR); - printf("Copyright (C) 1998-2017 Ivo Timmermans, Guus Sliepen and others.\n" - "See the AUTHORS file for a complete list.\n\n" - "tinc comes with ABSOLUTELY NO WARRANTY. This is free software,\n" - "and you are welcome to redistribute it under certain conditions;\n" - "see the file COPYING for details.\n"); + BUILD_VERSION, BUILD_DATE, BUILD_TIME, PROT_MAJOR, PROT_MINOR); + printf("Copyright (C) 1998-2018 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" + "see the file COPYING for details.\n"); } static void usage(bool status) { @@ -105,61 +105,61 @@ static void usage(bool status) { } else { printf("Usage: %s [options] command\n\n", program_name); printf("Valid options are:\n" - " -b, --batch Don't ask for anything (non-interactive mode).\n" - " -c, --config=DIR Read configuration options from DIR.\n" - " -n, --net=NETNAME Connect to net NETNAME.\n" - " --pidfile=FILENAME Read control cookie from FILENAME.\n" - " --force Force some commands to work despite warnings.\n" - " --help Display this help and exit.\n" - " --version Output version information and exit.\n" - "\n" - "Valid commands are:\n" - " init [name] Create initial configuration files.\n" - " get VARIABLE Print current value of VARIABLE\n" - " set VARIABLE VALUE Set VARIABLE to VALUE\n" - " add VARIABLE VALUE Add VARIABLE with the given VALUE\n" - " del VARIABLE [VALUE] Remove VARIABLE [only ones with watching VALUE]\n" - " start [tincd options] Start tincd.\n" - " stop Stop tincd.\n" - " restart [tincd options] Restart tincd.\n" - " reload Partially reload configuration of running tincd.\n" - " pid Show PID of currently running tincd.\n" + " -b, --batch Don't ask for anything (non-interactive mode).\n" + " -c, --config=DIR Read configuration options from DIR.\n" + " -n, --net=NETNAME Connect to net NETNAME.\n" + " --pidfile=FILENAME Read control cookie from FILENAME.\n" + " --force Force some commands to work despite warnings.\n" + " --help Display this help and exit.\n" + " --version Output version information and exit.\n" + "\n" + "Valid commands are:\n" + " init [name] Create initial configuration files.\n" + " get VARIABLE Print current value of VARIABLE\n" + " set VARIABLE VALUE Set VARIABLE to VALUE\n" + " add VARIABLE VALUE Add VARIABLE with the given VALUE\n" + " del VARIABLE [VALUE] Remove VARIABLE [only ones with watching VALUE]\n" + " start [tincd options] Start tincd.\n" + " stop Stop tincd.\n" + " restart [tincd options] Restart tincd.\n" + " reload Partially reload configuration of running tincd.\n" + " pid Show PID of currently running tincd.\n" #ifdef DISABLE_LEGACY - " generate-keys Generate a new Ed25519 public/private keypair.\n" + " generate-keys Generate a new Ed25519 public/private keypair.\n" #else - " generate-keys [bits] Generate new RSA and Ed25519 public/private keypairs.\n" - " generate-rsa-keys [bits] Generate a new RSA public/private keypair.\n" + " generate-keys [bits] Generate new RSA and Ed25519 public/private keypairs.\n" + " generate-rsa-keys [bits] Generate a new RSA public/private keypair.\n" #endif - " generate-ed25519-keys Generate a new Ed25519 public/private keypair.\n" - " dump Dump a list of one of the following things:\n" - " [reachable] nodes - all known nodes in the VPN\n" - " edges - all known connections in the VPN\n" - " subnets - all known subnets in the VPN\n" - " connections - all meta connections with ourself\n" - " [di]graph - graph of the VPN in dotty format\n" - " invitations - outstanding invitations\n" - " info NODE|SUBNET|ADDRESS Give information about a particular NODE, SUBNET or ADDRESS.\n" - " purge Purge unreachable nodes\n" - " debug N Set debug level\n" - " retry Retry all outgoing connections\n" - " disconnect NODE Close meta connection with NODE\n" + " generate-ed25519-keys Generate a new Ed25519 public/private keypair.\n" + " dump Dump a list of one of the following things:\n" + " [reachable] nodes - all known nodes in the VPN\n" + " edges - all known connections in the VPN\n" + " subnets - all known subnets in the VPN\n" + " connections - all meta connections with ourself\n" + " [di]graph - graph of the VPN in dotty format\n" + " invitations - outstanding invitations\n" + " info NODE|SUBNET|ADDRESS Give information about a particular NODE, SUBNET or ADDRESS.\n" + " purge Purge unreachable nodes\n" + " debug N Set debug level\n" + " retry Retry all outgoing connections\n" + " disconnect NODE Close meta connection with NODE\n" #ifdef HAVE_CURSES - " top Show real-time statistics\n" + " top Show real-time statistics\n" #endif - " pcap [snaplen] Dump traffic in pcap format [up to snaplen bytes per packet]\n" - " log [level] Dump log output [up to the specified level]\n" - " export Export host configuration of local node to standard output\n" - " export-all Export all host configuration files to standard output\n" - " import Import host configuration file(s) from standard input\n" - " exchange Same as export followed by import\n" - " exchange-all Same as export-all followed by import\n" - " invite NODE [...] Generate an invitation for NODE\n" - " join INVITATION Join a VPN using an INVITATION\n" - " network [NETNAME] List all known networks, or switch to the one named NETNAME.\n" - " fsck Check the configuration files for problems.\n" - " sign [FILE] Generate a signed version of a file.\n" - " verify NODE [FILE] Verify that a file was signed by the given NODE.\n" - "\n"); + " pcap [snaplen] Dump traffic in pcap format [up to snaplen bytes per packet]\n" + " log [level] Dump log output [up to the specified level]\n" + " export Export host configuration of local node to standard output\n" + " export-all Export all host configuration files to standard output\n" + " import Import host configuration file(s) from standard input\n" + " exchange Same as export followed by import\n" + " exchange-all Same as export-all followed by import\n" + " invite NODE [...] Generate an invitation for NODE\n" + " join INVITATION Join a VPN using an INVITATION\n" + " network [NETNAME] List all known networks, or switch to the one named NETNAME.\n" + " fsck Check the configuration files for problems.\n" + " sign [FILE] Generate a signed version of a file.\n" + " verify NODE [FILE] Verify that a file was signed by the given NODE.\n" + "\n"); printf("Report bugs to tinc@tinc-vpn.org.\n"); } } @@ -168,51 +168,52 @@ static bool parse_options(int argc, char **argv) { int r; int option_index = 0; - while((r = getopt_long(argc, argv, "+c:n:", long_options, &option_index)) != EOF) { - switch (r) { - case 0: /* long option */ - break; + while((r = getopt_long(argc, argv, "+bc:n:", long_options, &option_index)) != EOF) { + switch(r) { + case 0: /* long option */ + break; - case 'b': - tty = false; - break; + case 'b': + tty = false; + break; - case 'c': /* config file */ - confbase = xstrdup(optarg); - confbasegiven = true; - break; + case 'c': /* config file */ + confbase = xstrdup(optarg); + confbasegiven = true; + break; - case 'n': /* net name given */ - netname = xstrdup(optarg); - break; + case 'n': /* net name given */ + netname = xstrdup(optarg); + break; - case 1: /* show help */ - show_help = true; - break; + case 1: /* show help */ + show_help = true; + break; - case 2: /* show version */ - show_version = true; - break; + case 2: /* show version */ + show_version = true; + break; - case 3: /* open control socket here */ - pidfilename = xstrdup(optarg); - break; + case 3: /* open control socket here */ + pidfilename = xstrdup(optarg); + break; - case 4: /* force */ - force = true; - break; + case 4: /* force */ + force = true; + break; - case '?': /* wrong options */ - usage(true); - return false; + case '?': /* wrong options */ + usage(true); + return false; - default: - break; + default: + break; } } - if(!netname && (netname = getenv("NETNAME"))) + if(!netname && (netname = getenv("NETNAME"))) { netname = xstrdup(netname); + } /* netname "." is special: a "top-level name" */ @@ -245,8 +246,11 @@ FILE *fopenmask(const char *filename, const char *mode, mode_t perms) { } #ifdef HAVE_FCHMOD - if((perms & 0444) && f) + + if((perms & 0444) && f) { fchmod(fileno(f), perms); + } + #endif umask(mask); return f; @@ -261,16 +265,18 @@ static void disable_old_keys(const char *filename, const char *what) { FILE *r, *w; r = fopen(filename, "r"); - if(!r) - return; - snprintf(tmpfile, sizeof tmpfile, "%s.tmp", filename); + if(!r) { + return; + } + + snprintf(tmpfile, sizeof(tmpfile), "%s.tmp", filename); struct stat st = {.st_mode = 0600}; fstat(fileno(r), &st); w = fopenmask(tmpfile, "w", st.st_mode); - while(fgets(buf, sizeof buf, r)) { + while(fgets(buf, sizeof(buf), r)) { if(!block && !strncmp(buf, "-----BEGIN ", 11)) { if((strstr(buf, " ED25519 ") && strstr(what, "Ed25519")) || (strstr(buf, " RSA ") && strstr(what, "RSA"))) { disabled = true; @@ -280,43 +286,55 @@ static void disable_old_keys(const char *filename, const char *what) { bool ed25519pubkey = !strncasecmp(buf, "Ed25519PublicKey", 16) && strchr(" \t=", buf[16]) && strstr(what, "Ed25519"); - if(ed25519pubkey) + if(ed25519pubkey) { disabled = true; + } if(w) { - if(block || ed25519pubkey) + if(block || ed25519pubkey) { fputc('#', w); + } + if(fputs(buf, w) < 0) { error = true; break; } } - if(block && !strncmp(buf, "-----END ", 9)) + if(block && !strncmp(buf, "-----END ", 9)) { block = false; + } } if(w) - if(fclose(w) < 0) + if(fclose(w) < 0) { error = true; - if(ferror(r) || fclose(r) < 0) + } + + if(ferror(r) || fclose(r) < 0) { error = true; + } if(disabled) { if(!w || error) { fprintf(stderr, "Warning: old key(s) found, remove them by hand!\n"); - if(w) + + if(w) { unlink(tmpfile); + } + return; } #ifdef HAVE_MINGW // We cannot atomically replace files on Windows. char bakfile[PATH_MAX] = ""; - snprintf(bakfile, sizeof bakfile, "%s.bak", filename); + snprintf(bakfile, sizeof(bakfile), "%s.bak", filename); + if(rename(filename, bakfile) || rename(tmpfile, filename)) { rename(bakfile, filename); #else + if(rename(tmpfile, filename)) { #endif fprintf(stderr, "Warning: old key(s) found, remove them by hand!\n"); @@ -337,32 +355,49 @@ static FILE *ask_and_open(const char *filename, const char *what, const char *mo char buf[PATH_MAX]; char buf2[PATH_MAX]; +ask_filename: + /* Check stdin and stdout */ if(ask && tty) { /* Ask for a file and/or directory name. */ fprintf(stderr, "Please enter a file to save %s to [%s]: ", what, filename); - if(fgets(buf, sizeof buf, stdin) == NULL) { + if(fgets(buf, sizeof(buf), stdin) == NULL) { fprintf(stderr, "Error while reading stdin: %s\n", strerror(errno)); return NULL; } size_t len = strlen(buf); - if(len) - buf[--len] = 0; - if(len) + if(len) { + buf[--len] = 0; + } + + if(len) { filename = buf; + } } #ifdef HAVE_MINGW + if(filename[0] != '\\' && filename[0] != '/' && !strchr(filename, ':')) { #else + if(filename[0] != '/') { #endif /* The directory is a relative path or a filename. */ - getcwd(directory, sizeof directory); - snprintf(buf2, sizeof buf2, "%s" SLASH "%s", directory, filename); + getcwd(directory, sizeof(directory)); + + if((size_t)snprintf(buf2, sizeof(buf2), "%s" SLASH "%s", directory, filename) >= sizeof(buf2)) { + fprintf(stderr, "Filename too long: %s" SLASH "%s\n", directory, filename); + + if(ask && tty) { + goto ask_filename; + } else { + return NULL; + } + } + filename = buf2; } @@ -394,14 +429,16 @@ static bool ed25519_keygen(bool ask) { if(!(key = ecdsa_generate())) { fprintf(stderr, "Error during key generation!\n"); return false; - } else + } else { fprintf(stderr, "Done.\n"); + } - snprintf(fname, sizeof fname, "%s" SLASH "ed25519_key.priv", confbase); + snprintf(fname, sizeof(fname), "%s" SLASH "ed25519_key.priv", confbase); f = ask_and_open(fname, "private Ed25519 key", "a", ask, 0600); - if(!f) + if(!f) { goto error; + } if(!ecdsa_write_pem_private_key(key, f)) { fprintf(stderr, "Error writing private key!\n"); @@ -410,15 +447,17 @@ static bool ed25519_keygen(bool ask) { fclose(f); - if(name) - snprintf(fname, sizeof fname, "%s" SLASH "hosts" SLASH "%s", confbase, name); - else - snprintf(fname, sizeof fname, "%s" SLASH "ed25519_key.pub", confbase); + if(name) { + snprintf(fname, sizeof(fname), "%s" SLASH "hosts" SLASH "%s", confbase, name); + } else { + snprintf(fname, sizeof(fname), "%s" SLASH "ed25519_key.pub", confbase); + } f = ask_and_open(fname, "public Ed25519 key", "a", ask, 0666); - if(!f) + if(!f) { return false; + } char *pubkey = ecdsa_get_base64_public_key(key); fprintf(f, "Ed25519PublicKey = %s\n", pubkey); @@ -430,8 +469,11 @@ static bool ed25519_keygen(bool ask) { return true; error: - if(f) + + if(f) { fclose(f); + } + ecdsa_free(key); return false; } @@ -462,14 +504,16 @@ static bool rsa_keygen(int bits, bool ask) { if(!(key = rsa_generate(bits, 0x10001))) { fprintf(stderr, "Error during key generation!\n"); return false; - } else + } else { fprintf(stderr, "Done.\n"); + } - snprintf(fname, sizeof fname, "%s" SLASH "rsa_key.priv", confbase); + snprintf(fname, sizeof(fname), "%s" SLASH "rsa_key.priv", confbase); f = ask_and_open(fname, "private RSA key", "a", ask, 0600); - if(!f) + if(!f) { goto error; + } if(!rsa_write_pem_private_key(key, f)) { fprintf(stderr, "Error writing private key!\n"); @@ -478,15 +522,17 @@ static bool rsa_keygen(int bits, bool ask) { fclose(f); - if(name) - snprintf(fname, sizeof fname, "%s" SLASH "hosts" SLASH "%s", confbase, name); - else - snprintf(fname, sizeof fname, "%s" SLASH "rsa_key.pub", confbase); + if(name) { + snprintf(fname, sizeof(fname), "%s" SLASH "hosts" SLASH "%s", confbase, name); + } else { + snprintf(fname, sizeof(fname), "%s" SLASH "rsa_key.pub", confbase); + } f = ask_and_open(fname, "public RSA key", "a", ask, 0666); - if(!f) + if(!f) { goto error; + } if(!rsa_write_pem_public_key(key, f)) { fprintf(stderr, "Error writing public key!\n"); @@ -499,8 +545,11 @@ static bool rsa_keygen(int bits, bool ask) { return true; error: - if(f) + + if(f) { fclose(f); + } + rsa_free(key); return false; } @@ -512,20 +561,25 @@ size_t blen = 0; bool recvline(int fd, char *line, size_t len) { char *newline = NULL; - if(!fd) + if(!fd) { return false; + } while(!(newline = memchr(buffer, '\n', blen))) { - int result = recv(fd, buffer + blen, sizeof buffer - blen, 0); - if(result == -1 && sockerrno == EINTR) + int result = recv(fd, buffer + blen, sizeof(buffer) - blen, 0); + + if(result == -1 && sockerrno == EINTR) { continue; - else if(result <= 0) + } else if(result <= 0) { return false; + } + blen += result; } - if(newline - buffer >= len) + if((size_t)(newline - buffer) >= len) { return false; + } len = newline - buffer; @@ -537,16 +591,16 @@ bool recvline(int fd, char *line, size_t len) { return true; } -bool recvdata(int fd, char *data, size_t len) { - if(len == -1) - len = blen; - +static bool recvdata(int fd, char *data, size_t len) { while(blen < len) { - int result = recv(fd, buffer + blen, sizeof buffer - blen, 0); - if(result == -1 && sockerrno == EINTR) + int result = recv(fd, buffer + blen, sizeof(buffer) - blen, 0); + + if(result == -1 && sockerrno == EINTR) { continue; - else if(result <= 0) + } else if(result <= 0) { return false; + } + blen += result; } @@ -560,26 +614,30 @@ bool recvdata(int fd, char *data, size_t len) { bool sendline(int fd, char *format, ...) { static char buffer[4096]; char *p = buffer; - int blen = 0; + int blen; va_list ap; va_start(ap, format); - blen = vsnprintf(buffer, sizeof buffer, format, ap); - buffer[sizeof buffer - 1] = 0; + blen = vsnprintf(buffer, sizeof(buffer), format, ap); + buffer[sizeof(buffer) - 1] = 0; va_end(ap); - if(blen < 1 || blen >= sizeof buffer) + if(blen < 1 || (size_t)blen >= sizeof(buffer)) { return false; + } buffer[blen] = '\n'; blen++; while(blen) { int result = send(fd, p, blen, MSG_NOSIGNAL); - if(result == -1 && sockerrno == EINTR) + + if(result == -1 && sockerrno == EINTR) { continue; - else if(result <= 0) + } else if(result <= 0) { return false; + } + p += result; blen -= result; } @@ -587,7 +645,7 @@ bool sendline(int fd, char *format, ...) { return true; } -static void pcap(int fd, FILE *out, int snaplen) { +static void pcap(int fd, FILE *out, uint32_t snaplen) { sendline(fd, "%d %d %d", CONTROL, REQ_PCAP, snaplen); char data[9018]; @@ -603,7 +661,7 @@ static void pcap(int fd, FILE *out, int snaplen) { 0xa1b2c3d4, 2, 4, 0, 0, - snaplen ?: sizeof data, + snaplen ? snaplen : sizeof(data), 1, }; @@ -616,23 +674,29 @@ static void pcap(int fd, FILE *out, int snaplen) { struct timeval tv; - fwrite(&header, sizeof header, 1, out); + fwrite(&header, sizeof(header), 1, out); fflush(out); char line[32]; - while(recvline(fd, line, sizeof line)) { + + while(recvline(fd, line, sizeof(line))) { int code, req, len; int n = sscanf(line, "%d %d %d", &code, &req, &len); gettimeofday(&tv, NULL); - if(n != 3 || code != CONTROL || req != REQ_PCAP || len < 0 || len > sizeof data) + + if(n != 3 || code != CONTROL || req != REQ_PCAP || len < 0 || (size_t)len > sizeof(data)) { break; - if(!recvdata(fd, data, len)) + } + + if(!recvdata(fd, data, len)) { break; + } + packet.tv_sec = tv.tv_sec; packet.tv_usec = tv.tv_usec; packet.len = len; packet.origlen = len; - fwrite(&packet, sizeof packet, 1, out); + fwrite(&packet, sizeof(packet), 1, out); fwrite(data, len, 1, out); fflush(out); } @@ -643,13 +707,18 @@ static void logcontrol(int fd, FILE *out, int level) { char data[1024]; char line[32]; - while(recvline(fd, line, sizeof line)) { + while(recvline(fd, line, sizeof(line))) { int code, req, len; int n = sscanf(line, "%d %d %d", &code, &req, &len); - if(n != 3 || code != CONTROL || req != REQ_LOG || len < 0 || len > sizeof data) + + if(n != 3 || code != CONTROL || req != REQ_LOG || len < 0 || (size_t)len > sizeof(data)) { break; - if(!recvdata(fd, data, len)) + } + + if(!recvdata(fd, data, len)) { break; + } + fwrite(data, len, 1, out); fputc('\n', out); fflush(out); @@ -661,33 +730,50 @@ static bool remove_service(void) { SC_HANDLE manager = NULL; SC_HANDLE service = NULL; SERVICE_STATUS status = {0}; + bool success = false; manager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); + if(!manager) { fprintf(stderr, "Could not open service manager: %s\n", winerror(GetLastError())); - return false; + goto exit; } service = OpenService(manager, identname, SERVICE_ALL_ACCESS); if(!service) { fprintf(stderr, "Could not open %s service: %s\n", identname, winerror(GetLastError())); - return false; + goto exit; } - if(!ControlService(service, SERVICE_CONTROL_STOP, &status)) + if(!ControlService(service, SERVICE_CONTROL_STOP, &status)) { fprintf(stderr, "Could not stop %s service: %s\n", identname, winerror(GetLastError())); - else + } else { fprintf(stderr, "%s service stopped\n", identname); + } if(!DeleteService(service)) { fprintf(stderr, "Could not remove %s service: %s\n", identname, winerror(GetLastError())); - return false; + goto exit; } - fprintf(stderr, "%s service removed\n", identname); + success = true; - return true; +exit: + + if(service) { + CloseServiceHandle(service); + } + + if(manager) { + CloseServiceHandle(manager); + } + + if(success) { + fprintf(stderr, "%s service removed\n", identname); + } + + return success; } #endif @@ -697,6 +783,7 @@ bool connect_tincd(bool verbose) { FD_ZERO(&r); FD_SET(fd, &r); struct timeval tv = {0, 0}; + if(select(fd + 1, &r, NULL, NULL, &tv)) { fprintf(stderr, "Previous connection to tincd lost, reconnecting.\n"); close(fd); @@ -707,9 +794,12 @@ bool connect_tincd(bool verbose) { } FILE *f = fopen(pidfilename, "r"); + if(!f) { - if(verbose) + if(verbose) { fprintf(stderr, "Could not open pid file %s: %s\n", pidfilename, strerror(errno)); + } + return false; } @@ -717,8 +807,10 @@ bool connect_tincd(bool verbose) { char port[129]; if(fscanf(f, "%20d %1024s %128s port %128s", &pid, controlcookie, host, port) != 4) { - if(verbose) + if(verbose) { fprintf(stderr, "Could not parse pid file %s\n", pidfilename); + } + fclose(f); return false; } @@ -726,7 +818,8 @@ bool connect_tincd(bool verbose) { fclose(f); #ifndef HAVE_MINGW - if ((pid == 0) || (kill(pid, 0) && (errno == ESRCH))) { + + if((pid == 0) || (kill(pid, 0) && (errno == ESRCH))) { fprintf(stderr, "Could not find tincd running at pid %d\n", pid); /* clean up the stale socket and pid file */ unlink(pidfilename); @@ -735,23 +828,33 @@ bool connect_tincd(bool verbose) { } struct sockaddr_un sa; + sa.sun_family = AF_UNIX; - strncpy(sa.sun_path, unixsocketname, sizeof sa.sun_path); + + strncpy(sa.sun_path, unixsocketname, sizeof(sa.sun_path)); + + sa.sun_path[sizeof(sa.sun_path) - 1] = 0; fd = socket(AF_UNIX, SOCK_STREAM, 0); + if(fd < 0) { - if(verbose) + if(verbose) { fprintf(stderr, "Cannot create UNIX socket: %s\n", sockstrerror(sockerrno)); + } + return false; } - if(connect(fd, (struct sockaddr *)&sa, sizeof sa) < 0) { - if(verbose) + if(connect(fd, (struct sockaddr *)&sa, sizeof(sa)) < 0) { + if(verbose) { fprintf(stderr, "Cannot connect to UNIX socket %s: %s\n", unixsocketname, sockstrerror(sockerrno)); + } + close(fd); fd = -1; return false; } + #else struct addrinfo hints = { .ai_family = AF_UNSPEC, @@ -763,15 +866,20 @@ bool connect_tincd(bool verbose) { struct addrinfo *res = NULL; if(getaddrinfo(host, port, &hints, &res) || !res) { - if(verbose) - fprintf(stderr, "Cannot resolve %s port %s: %s", host, port, sockstrerror(sockerrno)); + if(verbose) { + fprintf(stderr, "Cannot resolve %s port %s: %s\n", host, port, sockstrerror(sockerrno)); + } + return false; } fd = socket(res->ai_family, SOCK_STREAM, IPPROTO_TCP); + if(fd < 0) { - if(verbose) + if(verbose) { fprintf(stderr, "Cannot create TCP socket: %s\n", sockstrerror(sockerrno)); + } + return false; } @@ -779,14 +887,18 @@ bool connect_tincd(bool verbose) { unsigned long arg = 0; if(ioctlsocket(fd, FIONBIO, &arg) != 0) { - if(verbose) - fprintf(stderr, "ioctlsocket failed: %s", sockstrerror(sockerrno)); + if(verbose) { + fprintf(stderr, "System call `%s' failed: %s\n", "ioctlsocket", sockstrerror(sockerrno)); + } } + #endif if(connect(fd, res->ai_addr, res->ai_addrlen) < 0) { - if(verbose) + if(verbose) { fprintf(stderr, "Cannot connect to %s port %s: %s\n", host, port, sockstrerror(sockerrno)); + } + close(fd); fd = -1; return false; @@ -797,25 +909,29 @@ bool connect_tincd(bool verbose) { #ifdef SO_NOSIGPIPE static const int one = 1; - setsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, (void *)&one, sizeof one); + setsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, (void *)&one, sizeof(one)); #endif + sendline(fd, "%d ^%s %d", ID, controlcookie, TINC_CTL_VERSION_CURRENT); + char data[4096]; int version; - if(!recvline(fd, line, sizeof line) || sscanf(line, "%d %4095s %d", &code, data, &version) != 3 || code != 0) { - if(verbose) + if(!recvline(fd, line, sizeof(line)) || sscanf(line, "%d %4095s %d", &code, data, &version) != 3 || code != 0) { + if(verbose) { fprintf(stderr, "Cannot read greeting from control socket: %s\n", sockstrerror(sockerrno)); + } + close(fd); fd = -1; return false; } - sendline(fd, "%d ^%s %d", ID, controlcookie, TINC_CTL_VERSION_CURRENT); - - if(!recvline(fd, line, sizeof line) || sscanf(line, "%d %d %d", &code, &version, &pid) != 3 || code != 4 || version != TINC_CTL_VERSION_CURRENT) { - if(verbose) + if(!recvline(fd, line, sizeof(line)) || sscanf(line, "%d %d %d", &code, &version, &pid) != 3 || code != 4 || version != TINC_CTL_VERSION_CURRENT) { + if(verbose) { fprintf(stderr, "Could not fully establish control socket connection\n"); + } + close(fd); fd = -1; return false; @@ -827,10 +943,12 @@ bool connect_tincd(bool verbose) { static int cmd_start(int argc, char *argv[]) { if(connect_tincd(false)) { - if(netname) + if(netname) { fprintf(stderr, "A tincd is already running for net `%s' with pid %d.\n", netname, pid); - else + } else { fprintf(stderr, "A tincd is already running with pid %d.\n", pid); + } + return 0; } @@ -838,17 +956,21 @@ static int cmd_start(int argc, char *argv[]) { char *slash = strrchr(program_name, '/'); #ifdef HAVE_MINGW - if ((c = strrchr(program_name, '\\')) > slash) + + if((c = strrchr(program_name, '\\')) > slash) { slash = c; + } + #endif - if (slash++) + if(slash++) { xasprintf(&c, "%.*stincd", (int)(slash - program_name), program_name); - else + } else { c = "tincd"; + } int nargc = 0; - char **nargv = xzalloc((optind + argc) * sizeof *nargv); + char **nargv = xzalloc((optind + argc) * sizeof(*nargv)); char *arg0 = c; #ifdef HAVE_MINGW @@ -863,20 +985,27 @@ static int cmd_start(int argc, char *argv[]) { xasprintf(&arg0, "\"%s\"", arg0); #endif nargv[nargc++] = arg0; - for(int i = 1; i < optind; i++) + + for(int i = 1; i < optind; i++) { nargv[nargc++] = orig_argv[i]; - for(int i = 1; i < argc; i++) + } + + for(int i = 1; i < argc; i++) { nargv[nargc++] = argv[i]; + } #ifdef HAVE_MINGW int status = spawnvp(_P_WAIT, c, nargv); - if (status == -1) { + + if(status == -1) { fprintf(stderr, "Error starting %s: %s\n", c, strerror(errno)); return 1; } + return status; #else int pfd[2] = {-1, -1}; + if(socketpair(AF_UNIX, SOCK_STREAM, 0, pfd)) { fprintf(stderr, "Could not create umbilical socket: %s\n", strerror(errno)); free(nargv); @@ -884,6 +1013,7 @@ static int cmd_start(int argc, char *argv[]) { } pid_t pid = fork(); + if(pid == -1) { fprintf(stderr, "Could not fork: %s\n", strerror(errno)); free(nargv); @@ -893,7 +1023,7 @@ static int cmd_start(int argc, char *argv[]) { if(!pid) { close(pfd[0]); char buf[100]; - snprintf(buf, sizeof buf, "%d", pfd[1]); + snprintf(buf, sizeof(buf), "%d", pfd[1]); setenv("TINC_UMBILICAL", buf, true); exit(execvp(c, nargv)); } else { @@ -908,20 +1038,24 @@ static int cmd_start(int argc, char *argv[]) { #endif // Pass all log messages from the umbilical to stderr. - // A nul-byte right before closure means tincd started succesfully. + // A nul-byte right before closure means tincd started successfully. bool failure = true; char buf[1024]; ssize_t len; - while((len = read(pfd[0], buf, sizeof buf)) > 0) { + while((len = read(pfd[0], buf, sizeof(buf))) > 0) { failure = buf[len - 1]; - if(!failure) + + if(!failure) { len--; + } + write(2, buf, len); } - if(len) + if(len) { failure = true; + } close(pfd[0]); @@ -942,12 +1076,15 @@ static int cmd_start(int argc, char *argv[]) { } static int cmd_stop(int argc, char *argv[]) { + (void)argv; + if(argc > 1) { fprintf(stderr, "Too many arguments!\n"); return 1; } #ifndef HAVE_MINGW + if(!connect_tincd(true)) { if(pid) { if(kill(pid, SIGTERM)) { @@ -965,12 +1102,16 @@ static int cmd_stop(int argc, char *argv[]) { sendline(fd, "%d %d", CONTROL, REQ_STOP); - while(recvline(fd, line, sizeof line)) { + while(recvline(fd, line, sizeof(line))) { // Wait for tincd to close the connection... } + #else - if(!remove_service()) + + if(!remove_service()) { return 1; + } + #endif close(fd); pid = 0; @@ -985,16 +1126,20 @@ static int cmd_restart(int argc, char *argv[]) { } static int cmd_reload(int argc, char *argv[]) { + (void)argv; + if(argc > 1) { fprintf(stderr, "Too many arguments!\n"); return 1; } - if(!connect_tincd(true)) + if(!connect_tincd(true)) { return 1; + } sendline(fd, "%d %d", CONTROL, REQ_RELOAD); - if(!recvline(fd, line, sizeof line) || sscanf(line, "%d %d %d", &code, &req, &result) != 3 || code != CONTROL || req != REQ_RELOAD || result) { + + if(!recvline(fd, line, sizeof(line)) || sscanf(line, "%d %d %d", &code, &req, &result) != 3 || code != CONTROL || req != REQ_RELOAD || result) { fprintf(stderr, "Could not reload configuration.\n"); return 1; } @@ -1005,8 +1150,9 @@ static int cmd_reload(int argc, char *argv[]) { static int dump_invitations(void) { char dname[PATH_MAX]; - snprintf(dname, sizeof dname, "%s" SLASH "invitations", confbase); + snprintf(dname, sizeof(dname), "%s" SLASH "invitations", confbase); DIR *dir = opendir(dname); + if(!dir) { if(errno == ENOENT) { fprintf(stderr, "No outstanding invitations.\n"); @@ -1018,34 +1164,48 @@ static int dump_invitations(void) { } struct dirent *ent; + bool found = false; while((ent = readdir(dir))) { char buf[MAX_STRING_SIZE]; - if(b64decode(ent->d_name, buf, 24) != 18) + + if(b64decode(ent->d_name, buf, 24) != 18) { continue; + } char fname[PATH_MAX]; - snprintf(fname, sizeof fname, "%s" SLASH "%s", dname, ent->d_name); + + if((size_t)snprintf(fname, sizeof(fname), "%s" SLASH "%s", dname, ent->d_name) >= sizeof(fname)) { + fprintf(stderr, "Filename too long: %s" SLASH "%s\n", dname, ent->d_name); + continue; + } + FILE *f = fopen(fname, "r"); + if(!f) { fprintf(stderr, "Cannot open %s: %s\n", fname, strerror(errno)); continue; } buf[0] = 0; - if(!fgets(buf, sizeof buf, f)) { - fprintf(stderr, "Invalid invitation file %s", fname); + + if(!fgets(buf, sizeof(buf), f)) { + fprintf(stderr, "Invalid invitation file %s\n", fname); fclose(f); continue; } + fclose(f); char *eol = buf + strlen(buf); - while(strchr("\t \r\n", *--eol)) + + while(strchr("\t \r\n", *--eol)) { *eol = 0; + } + if(strncmp(buf, "Name = ", 7) || !check_id(buf + 7)) { - fprintf(stderr, "Invalid invitation file %s", fname); + fprintf(stderr, "Invalid invitation file %s\n", fname); continue; } @@ -1055,8 +1215,9 @@ static int dump_invitations(void) { closedir(dir); - if(!found) + if(!found) { fprintf(stderr, "No outstanding invitations.\n"); + } return 0; } @@ -1070,6 +1231,7 @@ static int cmd_dump(int argc, char *argv[]) { usage(true); return 1; } + only_reachable = true; argv++; argc--; @@ -1081,23 +1243,25 @@ static int cmd_dump(int argc, char *argv[]) { return 1; } - if(!strcasecmp(argv[1], "invitations")) + if(!strcasecmp(argv[1], "invitations")) { return dump_invitations(); + } - if(!connect_tincd(true)) + if(!connect_tincd(true)) { return 1; + } int do_graph = 0; - if(!strcasecmp(argv[1], "nodes")) + if(!strcasecmp(argv[1], "nodes")) { sendline(fd, "%d %d", CONTROL, REQ_DUMP_NODES); - else if(!strcasecmp(argv[1], "edges")) + } else if(!strcasecmp(argv[1], "edges")) { sendline(fd, "%d %d", CONTROL, REQ_DUMP_EDGES); - else if(!strcasecmp(argv[1], "subnets")) + } else if(!strcasecmp(argv[1], "subnets")) { sendline(fd, "%d %d", CONTROL, REQ_DUMP_SUBNETS); - else if(!strcasecmp(argv[1], "connections")) + } else if(!strcasecmp(argv[1], "connections")) { sendline(fd, "%d %d", CONTROL, REQ_DUMP_CONNECTIONS); - else if(!strcasecmp(argv[1], "graph")) { + } else if(!strcasecmp(argv[1], "graph")) { sendline(fd, "%d %d", CONTROL, REQ_DUMP_NODES); sendline(fd, "%d %d", CONTROL, REQ_DUMP_EDGES); do_graph = 1; @@ -1111,25 +1275,31 @@ static int cmd_dump(int argc, char *argv[]) { return 1; } - if(do_graph == 1) + if(do_graph == 1) { printf("graph {\n"); - else if(do_graph == 2) + } else if(do_graph == 2) { printf("digraph {\n"); + } - while(recvline(fd, line, sizeof line)) { + while(recvline(fd, line, sizeof(line))) { char node1[4096], node2[4096]; int n = sscanf(line, "%d %d %4095s %4095s", &code, &req, node1, node2); + if(n == 2) { - if(do_graph && req == REQ_DUMP_NODES) + if(do_graph && req == REQ_DUMP_NODES) { continue; - else { - if(do_graph) + } else { + if(do_graph) { printf("}\n"); + } + return 0; } } - if(n < 2) + + if(n < 2) { break; + } char node[4096]; char id[4096]; @@ -1147,77 +1317,102 @@ static int cmd_dump(int argc, char *argv[]) { unsigned int options, status_int; node_status_t status; long int last_state_change; + int udp_ping_rtt; + uint64_t in_packets, in_bytes, out_packets, out_bytes; switch(req) { - case REQ_DUMP_NODES: { - int n = sscanf(line, "%*d %*d %4095s %4095s %4095s port %4095s %d %d %d %d %x %x %4095s %4095s %d %hd %hd %hd %ld", node, id, host, port, &cipher, &digest, &maclength, &compression, &options, &status_int, nexthop, via, &distance, &pmtu, &minmtu, &maxmtu, &last_state_change); - if(n != 17) { - fprintf(stderr, "Unable to parse node dump from tincd: %s\n", line); - return 1; - } + case REQ_DUMP_NODES: { + int n = sscanf(line, "%*d %*d %4095s %4095s %4095s port %4095s %d %d %d %d %x %x %4095s %4095s %d %hd %hd %hd %ld %d %"PRIu64" %"PRIu64" %"PRIu64" %"PRIu64, node, id, host, port, &cipher, &digest, &maclength, &compression, &options, &status_int, nexthop, via, &distance, &pmtu, &minmtu, &maxmtu, &last_state_change, &udp_ping_rtt, &in_packets, &in_bytes, &out_packets, &out_bytes); - memcpy(&status, &status_int, sizeof status); - - if(do_graph) { - const char *color = "black"; - if(!strcmp(host, "MYSELF")) - color = "green"; - else if(!status.reachable) - color = "red"; - else if(strcmp(via, node)) - color = "orange"; - else if(!status.validkey) - color = "black"; - else if(minmtu > 0) - color = "green"; - printf(" %s [label = \"%s\", color = \"%s\"%s];\n", node, node, color, strcmp(host, "MYSELF") ? "" : ", style = \"filled\""); - } else { - if(only_reachable && !status.reachable) - continue; - printf("%s id %s at %s port %s cipher %d digest %d maclength %d compression %d options %x status %04x nexthop %s via %s distance %d pmtu %d (min %d max %d)\n", - node, id, host, port, cipher, digest, maclength, compression, options, status_int, nexthop, via, distance, pmtu, minmtu, maxmtu); - } - } break; - - case REQ_DUMP_EDGES: { - int n = sscanf(line, "%*d %*d %4095s %4095s %4095s port %4095s %4095s port %4095s %x %d", from, to, host, port, local_host, local_port, &options, &weight); - if(n != 8) { - fprintf(stderr, "Unable to parse edge dump from tincd.\n"); - return 1; - } - - if(do_graph) { - float w = 1 + 65536.0 / weight; - if(do_graph == 1 && strcmp(node1, node2) > 0) - printf(" %s -- %s [w = %f, weight = %f];\n", node1, node2, w, w); - else if(do_graph == 2) - printf(" %s -> %s [w = %f, weight = %f];\n", node1, node2, w, w); - } else { - printf("%s to %s at %s port %s local %s port %s options %x weight %d\n", from, to, host, port, local_host, local_port, options, weight); - } - } break; - - case REQ_DUMP_SUBNETS: { - int n = sscanf(line, "%*d %*d %4095s %4095s", subnet, node); - if(n != 2) { - fprintf(stderr, "Unable to parse subnet dump from tincd.\n"); - return 1; - } - printf("%s owner %s\n", strip_weight(subnet), node); - } break; - - case REQ_DUMP_CONNECTIONS: { - int n = sscanf(line, "%*d %*d %4095s %4095s port %4095s %x %d %x", node, host, port, &options, &socket, &status_int); - if(n != 6) { - fprintf(stderr, "Unable to parse connection dump from tincd.\n"); - return 1; - } - printf("%s at %s port %s options %x socket %d status %x\n", node, host, port, options, socket, status_int); - } break; - - default: - fprintf(stderr, "Unable to parse dump from tincd.\n"); + if(n != 22) { + fprintf(stderr, "Unable to parse node dump from tincd: %s\n", line); return 1; + } + + memcpy(&status, &status_int, sizeof(status)); + + if(do_graph) { + const char *color = "black"; + + if(!strcmp(host, "MYSELF")) { + color = "green"; + } else if(!status.reachable) { + color = "red"; + } else if(strcmp(via, node)) { + color = "orange"; + } else if(!status.validkey) { + color = "black"; + } else if(minmtu > 0) { + color = "green"; + } + + printf(" %s [label = \"%s\", color = \"%s\"%s];\n", node, node, color, strcmp(host, "MYSELF") ? "" : ", style = \"filled\""); + } else { + if(only_reachable && !status.reachable) { + continue; + } + + printf("%s id %s at %s port %s cipher %d digest %d maclength %d compression %d options %x status %04x nexthop %s via %s distance %d pmtu %d (min %d max %d) rx %"PRIu64" %"PRIu64" tx %"PRIu64" %"PRIu64, + node, id, host, port, cipher, digest, maclength, compression, options, status_int, nexthop, via, distance, pmtu, minmtu, maxmtu, in_packets, in_bytes, out_packets, out_bytes); + + if(udp_ping_rtt != -1) { + printf(" rtt %d.%03d", udp_ping_rtt / 1000, udp_ping_rtt % 1000); + } + + printf("\n"); + } + } + break; + + case REQ_DUMP_EDGES: { + int n = sscanf(line, "%*d %*d %4095s %4095s %4095s port %4095s %4095s port %4095s %x %d", from, to, host, port, local_host, local_port, &options, &weight); + + if(n != 8) { + fprintf(stderr, "Unable to parse edge dump from tincd.\n"); + return 1; + } + + if(do_graph) { + float w = 1 + 65536.0 / weight; + + if(do_graph == 1 && strcmp(node1, node2) > 0) { + printf(" %s -- %s [w = %f, weight = %f];\n", node1, node2, w, w); + } else if(do_graph == 2) { + printf(" %s -> %s [w = %f, weight = %f];\n", node1, node2, w, w); + } + } else { + printf("%s to %s at %s port %s local %s port %s options %x weight %d\n", from, to, host, port, local_host, local_port, options, weight); + } + } + break; + + case REQ_DUMP_SUBNETS: { + int n = sscanf(line, "%*d %*d %4095s %4095s", subnet, node); + + if(n != 2) { + fprintf(stderr, "Unable to parse subnet dump from tincd.\n"); + return 1; + } + + printf("%s owner %s\n", strip_weight(subnet), node); + } + break; + + case REQ_DUMP_CONNECTIONS: { + int n = sscanf(line, "%*d %*d %4095s %4095s port %4095s %x %d %x", node, host, port, &options, &socket, &status_int); + + if(n != 6) { + fprintf(stderr, "Unable to parse connection dump from tincd.\n"); + return 1; + } + + printf("%s at %s port %s options %x socket %d status %x\n", node, host, port, options, socket, status_int); + } + break; + + default: + fprintf(stderr, "Unable to parse dump from tincd.\n"); + return 1; } } @@ -1226,16 +1421,20 @@ static int cmd_dump(int argc, char *argv[]) { } static int cmd_purge(int argc, char *argv[]) { + (void)argv; + if(argc > 1) { fprintf(stderr, "Too many arguments!\n"); return 1; } - if(!connect_tincd(true)) + if(!connect_tincd(true)) { return 1; + } sendline(fd, "%d %d", CONTROL, REQ_PURGE); - if(!recvline(fd, line, sizeof line) || sscanf(line, "%d %d %d", &code, &req, &result) != 3 || code != CONTROL || req != REQ_PURGE || result) { + + if(!recvline(fd, line, sizeof(line)) || sscanf(line, "%d %d %d", &code, &req, &result) != 3 || code != CONTROL || req != REQ_PURGE || result) { fprintf(stderr, "Could not purge old information.\n"); return 1; } @@ -1249,14 +1448,16 @@ static int cmd_debug(int argc, char *argv[]) { return 1; } - if(!connect_tincd(true)) + if(!connect_tincd(true)) { return 1; + } int debuglevel = atoi(argv[1]); int origlevel; sendline(fd, "%d %d %d", CONTROL, REQ_SET_DEBUG, debuglevel); - if(!recvline(fd, line, sizeof line) || sscanf(line, "%d %d %d", &code, &req, &origlevel) != 3 || code != CONTROL || req != REQ_SET_DEBUG) { + + if(!recvline(fd, line, sizeof(line)) || sscanf(line, "%d %d %d", &code, &req, &origlevel) != 3 || code != CONTROL || req != REQ_SET_DEBUG) { fprintf(stderr, "Could not set debug level.\n"); return 1; } @@ -1266,16 +1467,20 @@ static int cmd_debug(int argc, char *argv[]) { } static int cmd_retry(int argc, char *argv[]) { + (void)argv; + if(argc > 1) { fprintf(stderr, "Too many arguments!\n"); return 1; } - if(!connect_tincd(true)) + if(!connect_tincd(true)) { return 1; + } sendline(fd, "%d %d", CONTROL, REQ_RETRY); - if(!recvline(fd, line, sizeof line) || sscanf(line, "%d %d %d", &code, &req, &result) != 3 || code != CONTROL || req != REQ_RETRY || result) { + + if(!recvline(fd, line, sizeof(line)) || sscanf(line, "%d %d %d", &code, &req, &result) != 3 || code != CONTROL || req != REQ_RETRY || result) { fprintf(stderr, "Could not retry outgoing connections.\n"); return 1; } @@ -1294,11 +1499,13 @@ static int cmd_connect(int argc, char *argv[]) { return 1; } - if(!connect_tincd(true)) + if(!connect_tincd(true)) { return 1; + } sendline(fd, "%d %d %s", CONTROL, REQ_CONNECT, argv[1]); - if(!recvline(fd, line, sizeof line) || sscanf(line, "%d %d %d", &code, &req, &result) != 3 || code != CONTROL || req != REQ_CONNECT || result) { + + if(!recvline(fd, line, sizeof(line)) || sscanf(line, "%d %d %d", &code, &req, &result) != 3 || code != CONTROL || req != REQ_CONNECT || result) { fprintf(stderr, "Could not connect to %s.\n", argv[1]); return 1; } @@ -1317,11 +1524,13 @@ static int cmd_disconnect(int argc, char *argv[]) { return 1; } - if(!connect_tincd(true)) + if(!connect_tincd(true)) { return 1; + } sendline(fd, "%d %d %s", CONTROL, REQ_DISCONNECT, argv[1]); - if(!recvline(fd, line, sizeof line) || sscanf(line, "%d %d %d", &code, &req, &result) != 3 || code != CONTROL || req != REQ_DISCONNECT || result) { + + if(!recvline(fd, line, sizeof(line)) || sscanf(line, "%d %d %d", &code, &req, &result) != 3 || code != CONTROL || req != REQ_DISCONNECT || result) { fprintf(stderr, "Could not disconnect %s.\n", argv[1]); return 1; } @@ -1330,14 +1539,18 @@ static int cmd_disconnect(int argc, char *argv[]) { } static int cmd_top(int argc, char *argv[]) { + (void)argv; + if(argc > 1) { fprintf(stderr, "Too many arguments!\n"); return 1; } #ifdef HAVE_CURSES - if(!connect_tincd(true)) + + if(!connect_tincd(true)) { return 1; + } top(fd); return 0; @@ -1353,8 +1566,9 @@ static int cmd_pcap(int argc, char *argv[]) { return 1; } - if(!connect_tincd(true)) + if(!connect_tincd(true)) { return 1; + } pcap(fd, stdout, argc > 1 ? atoi(argv[1]) : 0); return 0; @@ -1362,6 +1576,8 @@ static int cmd_pcap(int argc, char *argv[]) { #ifdef SIGINT static void sigint_handler(int sig) { + (void)sig; + fprintf(stderr, "\n"); shutdown(fd, SHUT_RDWR); } @@ -1373,8 +1589,9 @@ static int cmd_log(int argc, char *argv[]) { return 1; } - if(!connect_tincd(true)) + if(!connect_tincd(true)) { return 1; + } #ifdef SIGINT signal(SIGINT, sigint_handler); @@ -1392,13 +1609,16 @@ static int cmd_log(int argc, char *argv[]) { } static int cmd_pid(int argc, char *argv[]) { + (void)argv; + if(argc > 1) { fprintf(stderr, "Too many arguments!\n"); return 1; } - if(!connect_tincd(true) || !pid) + if(!connect_tincd(true) || !pid) { return 1; + } printf("%d\n", pid); return 0; @@ -1406,34 +1626,48 @@ static int cmd_pid(int argc, char *argv[]) { int rstrip(char *value) { int len = strlen(value); - while(len && strchr("\t\r\n ", value[len - 1])) + + while(len && strchr("\t\r\n ", value[len - 1])) { value[--len] = 0; + } + return len; } char *get_my_name(bool verbose) { FILE *f = fopen(tinc_conf, "r"); + if(!f) { - if(verbose) + if(verbose) { fprintf(stderr, "Could not open %s: %s\n", tinc_conf, strerror(errno)); + } + return NULL; } char buf[4096]; char *value; - while(fgets(buf, sizeof buf, f)) { + + while(fgets(buf, sizeof(buf), f)) { int len = strcspn(buf, "\t ="); value = buf + len; value += strspn(value, "\t "); + if(*value == '=') { value++; value += strspn(value, "\t "); } - if(!rstrip(value)) + + if(!rstrip(value)) { continue; + } + buf[len] = 0; - if(strcasecmp(buf, "Name")) + + if(strcasecmp(buf, "Name")) { continue; + } + if(*value) { fclose(f); return replace_name(value); @@ -1441,29 +1675,41 @@ char *get_my_name(bool verbose) { } fclose(f); - if(verbose) + + if(verbose) { fprintf(stderr, "Could not find Name in %s.\n", tinc_conf); + } + return NULL; } ecdsa_t *get_pubkey(FILE *f) { char buf[4096]; char *value; - while(fgets(buf, sizeof buf, f)) { + + while(fgets(buf, sizeof(buf), f)) { int len = strcspn(buf, "\t ="); value = buf + len; value += strspn(value, "\t "); + if(*value == '=') { value++; value += strspn(value, "\t "); } - if(!rstrip(value)) + + if(!rstrip(value)) { continue; + } + buf[len] = 0; - if(strcasecmp(buf, "Ed25519PublicKey")) + + if(strcasecmp(buf, "Ed25519PublicKey")) { continue; - if(*value) + } + + if(*value) { return ecdsa_set_base64_public_key(value); + } } return NULL; @@ -1486,6 +1732,7 @@ const var_t variables[] = { {"Ed25519PrivateKeyFile", VAR_SERVER}, {"ExperimentalProtocol", VAR_SERVER}, {"Forwarding", VAR_SERVER}, + {"FWMark", VAR_SERVER}, {"GraphDumpFile", VAR_SERVER | VAR_OBSOLETE}, {"Hostnames", VAR_SERVER}, {"IffOneQueue", VAR_SERVER}, @@ -1553,10 +1800,12 @@ static int cmd_config(int argc, char *argv[]) { return 1; } - if(strcasecmp(argv[0], "config")) + if(strcasecmp(argv[0], "config")) { argv--, argc++; + } int action = -2; + if(!strcasecmp(argv[1], "get")) { argv++, argc--; } else if(!strcasecmp(argv[1], "add")) { @@ -1573,10 +1822,11 @@ static int cmd_config(int argc, char *argv[]) { } // Concatenate the rest of the command line - strncpy(line, argv[1], sizeof line - 1); + strncpy(line, argv[1], sizeof(line) - 1); + for(int i = 2; i < argc; i++) { - strncat(line, " ", sizeof line - 1 - strlen(line)); - strncat(line, argv[i], sizeof line - 1 - strlen(line)); + strncat(line, " ", sizeof(line) - 1 - strlen(line)); + strncat(line, argv[i], sizeof(line) - 1 - strlen(line)); } // Liberal parsing into node name, variable name and value. @@ -1588,12 +1838,15 @@ static int cmd_config(int argc, char *argv[]) { len = strcspn(line, "\t ="); value = line + len; value += strspn(value, "\t "); + if(*value == '=') { value++; value += strspn(value, "\t "); } + line[len] = '\0'; variable = strchr(line, '.'); + if(variable) { node = line; *variable++ = 0; @@ -1611,16 +1864,18 @@ static int cmd_config(int argc, char *argv[]) { return 1; } - if(action < -1 && *value) + if(action < -1 && *value) { action = 0; + } /* Some simple checks. */ bool found = false; bool warnonremove = false; for(int i = 0; variables[i].name; i++) { - if(strcasecmp(variables[i].name, variable)) + if(strcasecmp(variables[i].name, variable)) { continue; + } found = true; variable = (char *)variables[i].name; @@ -1651,11 +1906,13 @@ static int cmd_config(int argc, char *argv[]) { if(!node && !(variables[i].type & VAR_SERVER)) { node = get_my_name(true); - if(!node) + + if(!node) { return 1; + } } - /* Change "add" into "set" for variables that do not allow multiple occurences. + /* Change "add" into "set" for variables that do not allow multiple occurrences. Turn on warnings when it seems variables might be removed unintentionally. */ if(action == 1 && !(variables[i].type & VAR_MULTIPLE)) { @@ -1684,12 +1941,15 @@ static int cmd_config(int argc, char *argv[]) { // Open the right configuration file. char filename[PATH_MAX]; - if(node) - snprintf(filename, sizeof filename, "%s" SLASH "%s", hosts_dir, node); - else - snprintf(filename, sizeof filename, "%s", tinc_conf); + + if(node) { + snprintf(filename, sizeof(filename), "%s" SLASH "%s", hosts_dir, node); + } else { + snprintf(filename, sizeof(filename), "%s", tinc_conf); + } FILE *f = fopen(filename, "r"); + if(!f) { fprintf(stderr, "Could not open configuration file %s: %s\n", filename, strerror(errno)); return 1; @@ -1699,8 +1959,13 @@ static int cmd_config(int argc, char *argv[]) { FILE *tf = NULL; if(action >= -1) { - snprintf(tmpfile, sizeof tmpfile, "%s.config.tmp", filename); + if((size_t)snprintf(tmpfile, sizeof(tmpfile), "%s.config.tmp", filename) >= sizeof(tmpfile)) { + fprintf(stderr, "Filename too long: %s.config.tmp\n", filename); + return 1; + } + tf = fopen(tmpfile, "w"); + if(!tf) { fprintf(stderr, "Could not open temporary file %s: %s\n", tmpfile, strerror(errno)); fclose(f); @@ -1715,9 +1980,9 @@ static int cmd_config(int argc, char *argv[]) { bool removed = false; found = false; - while(fgets(buf1, sizeof buf1, f)) { - buf1[sizeof buf1 - 1] = 0; - strncpy(buf2, buf1, sizeof buf2); + while(fgets(buf1, sizeof(buf1), f)) { + buf1[sizeof(buf1) - 1] = 0; + strncpy(buf2, buf1, sizeof(buf2)); // Parse line in a simple way char *bvalue; @@ -1726,10 +1991,12 @@ static int cmd_config(int argc, char *argv[]) { len = strcspn(buf2, "\t ="); bvalue = buf2 + len; bvalue += strspn(bvalue, "\t "); + if(*bvalue == '=') { bvalue++; bvalue += strspn(bvalue, "\t "); } + rstrip(bvalue); buf2[len] = '\0'; @@ -1739,34 +2006,39 @@ static int cmd_config(int argc, char *argv[]) { if(action < -1) { found = true; printf("%s\n", bvalue); - // Del + // Del } else if(action == -1) { if(!*value || !strcasecmp(bvalue, value)) { removed = true; continue; } - // Set + + // Set } else if(action == 0) { // Warn if "set" was used for variables that can occur multiple times - if(warnonremove && strcasecmp(bvalue, value)) + if(warnonremove && strcasecmp(bvalue, value)) { fprintf(stderr, "Warning: removing %s = %s\n", variable, bvalue); + } // Already set? Delete the rest... - if(set) + if(set) { continue; + } // Otherwise, replace. if(fprintf(tf, "%s = %s\n", variable, value) < 0) { fprintf(stderr, "Error writing to temporary file %s: %s\n", tmpfile, strerror(errno)); return 1; } + set = true; continue; - // Add + // Add } else if(action > 0) { // Check if we've already seen this variable with the same value - if(!strcasecmp(bvalue, value)) + if(!strcasecmp(bvalue, value)) { found = true; + } } } @@ -1799,7 +2071,7 @@ static int cmd_config(int argc, char *argv[]) { } // Add new variable if necessary. - if((action > 0 && !found)|| (action == 0 && !set)) { + if((action > 0 && !found) || (action == 0 && !set)) { if(fprintf(tf, "%s = %s\n", variable, value) < 0) { fprintf(stderr, "Error writing to temporary file %s: %s\n", tmpfile, strerror(errno)); return 1; @@ -1830,19 +2102,23 @@ static int cmd_config(int argc, char *argv[]) { // Replace the configuration file with the new one #ifdef HAVE_MINGW + if(remove(filename)) { fprintf(stderr, "Error replacing file %s: %s\n", filename, strerror(errno)); return 1; } + #endif + if(rename(tmpfile, filename)) { fprintf(stderr, "Error renaming temporary file %s to configuration file %s: %s\n", tmpfile, filename, strerror(errno)); return 1; } // Silently try notifying a running tincd of changes. - if(connect_tincd(false)) + if(connect_tincd(false)) { sendline(fd, "%d %d", CONTROL, REQ_RELOAD); + } return 0; } @@ -1858,13 +2134,15 @@ static bool try_bind(int port) { bool success = true; char portstr[16]; - snprintf(portstr, sizeof portstr, "%d", port); + snprintf(portstr, sizeof(portstr), "%d", port); - if(getaddrinfo(NULL, portstr, &hint, &ai) || !ai) + if(getaddrinfo(NULL, portstr, &hint, &ai) || !ai) { return false; + } for(aip = ai; aip; aip = aip->ai_next) { int fd = socket(ai->ai_family, SOCK_STREAM, IPPROTO_TCP); + if(!fd) { success = false; break; @@ -1872,6 +2150,7 @@ static bool try_bind(int port) { int result = bind(fd, ai->ai_addr, ai->ai_addrlen); closesocket(fd); + if(result) { success = false; break; @@ -1882,18 +2161,21 @@ static bool try_bind(int port) { return success; } -int check_port(char *name) { - if(try_bind(655)) +int check_port(const char *name) { + if(try_bind(655)) { return 655; + } fprintf(stderr, "Warning: could not bind to port 655. "); for(int i = 0; i < 100; i++) { int port = 0x1000 + (rand() & 0x7fff); + if(try_bind(port)) { char filename[PATH_MAX]; - snprintf(filename, sizeof filename, "%s" SLASH "hosts" SLASH "%s", confbase, name); + snprintf(filename, sizeof(filename), "%s" SLASH "hosts" SLASH "%s", confbase, name); FILE *f = fopen(filename, "a"); + if(!f) { fprintf(stderr, "Could not open %s: %s\n", filename, strerror(errno)); fprintf(stderr, "Please change tinc's Port manually.\n"); @@ -1924,15 +2206,19 @@ static int cmd_init(int argc, char *argv[]) { if(tty) { char buf[1024]; fprintf(stderr, "Enter the Name you want your tinc node to have: "); - if(!fgets(buf, sizeof buf, stdin)) { + + if(!fgets(buf, sizeof(buf), stdin)) { fprintf(stderr, "Error while reading stdin: %s\n", strerror(errno)); return 1; } + int len = rstrip(buf); + if(!len) { fprintf(stderr, "No name given!\n"); return 1; } + name = strdup(buf); } else { fprintf(stderr, "No Name given!\n"); @@ -1940,6 +2226,7 @@ static int cmd_init(int argc, char *argv[]) { } } else { name = strdup(argv[1]); + if(!*name) { fprintf(stderr, "No Name given!\n"); return 1; @@ -1967,6 +2254,7 @@ static int cmd_init(int argc, char *argv[]) { } FILE *f = fopen(tinc_conf, "w"); + if(!f) { fprintf(stderr, "Could not create file %s: %s\n", tinc_conf, strerror(errno)); return 1; @@ -1976,27 +2264,35 @@ static int cmd_init(int argc, char *argv[]) { fclose(f); #ifndef DISABLE_LEGACY - if(!rsa_keygen(2048, false)) + + if(!rsa_keygen(2048, false)) { return 1; + } + #endif - if(!ed25519_keygen(false)) + if(!ed25519_keygen(false)) { return 1; + } check_port(name); #ifndef HAVE_MINGW char filename[PATH_MAX]; - snprintf(filename, sizeof filename, "%s" SLASH "tinc-up", confbase); + snprintf(filename, sizeof(filename), "%s" SLASH "tinc-up", confbase); + if(access(filename, F_OK)) { FILE *f = fopenmask(filename, "w", 0777); + if(!f) { fprintf(stderr, "Could not create file %s: %s\n", filename, strerror(errno)); return 1; } + fprintf(f, "#!/bin/sh\n\necho 'Unconfigured tinc-up script, please edit '$0'!'\n\n#ifconfig $INTERFACE netmask \n"); fclose(f); } + #endif return 0; @@ -2005,24 +2301,31 @@ static int cmd_init(int argc, char *argv[]) { static int cmd_generate_keys(int argc, char *argv[]) { #ifdef DISABLE_LEGACY + if(argc > 1) { #else + if(argc > 2) { #endif fprintf(stderr, "Too many arguments!\n"); return 1; } - if(!name) + if(!name) { name = get_my_name(false); + } #ifndef DISABLE_LEGACY - if(!rsa_keygen(argc > 1 ? atoi(argv[1]) : 2048, true)) + + if(!rsa_keygen(argc > 1 ? atoi(argv[1]) : 2048, true)) { return 1; + } + #endif - if(!ed25519_keygen(true)) + if(!ed25519_keygen(true)) { return 1; + } return 0; } @@ -2034,31 +2337,40 @@ static int cmd_generate_rsa_keys(int argc, char *argv[]) { return 1; } - if(!name) + if(!name) { name = get_my_name(false); + } return !rsa_keygen(argc > 1 ? atoi(argv[1]) : 2048, true); } #endif static int cmd_generate_ed25519_keys(int argc, char *argv[]) { + (void)argv; + if(argc > 1) { fprintf(stderr, "Too many arguments!\n"); return 1; } - if(!name) + if(!name) { name = get_my_name(false); + } return !ed25519_keygen(true); } static int cmd_help(int argc, char *argv[]) { + (void)argc; + (void)argv; + usage(false); return 0; } static int cmd_version(int argc, char *argv[]) { + (void)argv; + if(argc > 1) { fprintf(stderr, "Too many arguments!\n"); return 1; @@ -2074,8 +2386,9 @@ static int cmd_info(int argc, char *argv[]) { return 1; } - if(!connect_tincd(true)) + if(!connect_tincd(true)) { return 1; + } return info(fd, argv[1]); } @@ -2102,7 +2415,7 @@ static int cmd_edit(int argc, char *argv[]) { if(strncmp(argv[1], "hosts" SLASH, 6)) { for(int i = 0; conffiles[i]; i++) { if(!strcmp(argv[1], conffiles[i])) { - snprintf(filename, sizeof filename, "%s" SLASH "%s", confbase, argv[1]); + snprintf(filename, sizeof(filename), "%s" SLASH "%s", confbase, argv[1]); break; } } @@ -2111,10 +2424,12 @@ static int cmd_edit(int argc, char *argv[]) { } if(!*filename) { - snprintf(filename, sizeof filename, "%s" SLASH "%s", hosts_dir, argv[1]); + snprintf(filename, sizeof(filename), "%s" SLASH "%s", hosts_dir, argv[1]); char *dash = strchr(argv[1], '-'); + if(dash) { *dash++ = 0; + if((strcmp(dash, "up") && strcmp(dash, "down")) || !check_id(argv[1])) { fprintf(stderr, "Invalid configuration filename.\n"); return 1; @@ -2124,26 +2439,36 @@ static int cmd_edit(int argc, char *argv[]) { char *command; #ifndef HAVE_MINGW - xasprintf(&command, "\"%s\" \"%s\"", getenv("VISUAL") ?: getenv("EDITOR") ?: "vi", filename); + const char *editor = getenv("VISUAL"); + if (!editor) + editor = getenv("EDITOR"); + if (!editor) + editor = "vi"; + + xasprintf(&command, "\"%s\" \"%s\"", editor, filename); #else xasprintf(&command, "edit \"%s\"", filename); #endif int result = system(command); free(command); - if(result) + + if(result) { return result; + } // Silently try notifying a running tincd of changes. - if(connect_tincd(false)) + if(connect_tincd(false)) { sendline(fd, "%d %d", CONTROL, REQ_RELOAD); + } return 0; } static int export(const char *name, FILE *out) { char filename[PATH_MAX]; - snprintf(filename, sizeof filename, "%s" SLASH "%s", hosts_dir, name); + snprintf(filename, sizeof(filename), "%s" SLASH "%s", hosts_dir, name); FILE *in = fopen(filename, "r"); + if(!in) { fprintf(stderr, "Could not open configuration file %s: %s\n", filename, strerror(errno)); return 1; @@ -2151,9 +2476,11 @@ static int export(const char *name, FILE *out) { fprintf(out, "Name = %s\n", name); char buf[4096]; - while(fgets(buf, sizeof buf, in)) { - if(strcspn(buf, "\t =") != 4 || strncasecmp(buf, "Name", 4)) + + while(fgets(buf, sizeof(buf), in)) { + if(strcspn(buf, "\t =") != 4 || strncasecmp(buf, "Name", 4)) { fputs(buf, out); + } } if(ferror(in)) { @@ -2167,30 +2494,39 @@ static int export(const char *name, FILE *out) { } static int cmd_export(int argc, char *argv[]) { + (void)argv; + if(argc > 1) { fprintf(stderr, "Too many arguments!\n"); return 1; } char *name = get_my_name(true); - if(!name) + + if(!name) { return 1; + } int result = export(name, stdout); - if(!tty) + + if(!tty) { fclose(stdout); + } free(name); return result; } static int cmd_export_all(int argc, char *argv[]) { + (void)argv; + if(argc > 1) { fprintf(stderr, "Too many arguments!\n"); return 1; } DIR *dir = opendir(hosts_dir); + if(!dir) { fprintf(stderr, "Could not open host configuration directory %s: %s\n", hosts_dir, strerror(errno)); return 1; @@ -2201,24 +2537,31 @@ static int cmd_export_all(int argc, char *argv[]) { struct dirent *ent; while((ent = readdir(dir))) { - if(!check_id(ent->d_name)) + if(!check_id(ent->d_name)) { continue; + } - if(first) + if(first) { first = false; - else + } else { printf("#---------------------------------------------------------------#\n"); + } result |= export(ent->d_name, stdout); } closedir(dir); - if(!tty) + + if(!tty) { fclose(stdout); + } + return result; } static int cmd_import(int argc, char *argv[]) { + (void)argv; + if(argc > 1) { fprintf(stderr, "Too many arguments!\n"); return 1; @@ -2233,7 +2576,7 @@ static int cmd_import(int argc, char *argv[]) { int count = 0; bool firstline = true; - while(fgets(buf, sizeof buf, in)) { + while(fgets(buf, sizeof(buf), in)) { if(sscanf(buf, "Name = %4095s", name) == 1) { firstline = false; @@ -2242,10 +2585,14 @@ static int cmd_import(int argc, char *argv[]) { return 1; } - if(out) + if(out) { fclose(out); + } - snprintf(filename, sizeof filename, "%s" SLASH "%s", hosts_dir, name); + if((size_t)snprintf(filename, sizeof(filename), "%s" SLASH "%s", hosts_dir, name) >= sizeof(filename)) { + fprintf(stderr, "Filename too long: %s" SLASH "%s\n", hosts_dir, name); + return 1; + } if(!force && !access(filename, F_OK)) { fprintf(stderr, "Host configuration file %s already exists, skipping.\n", filename); @@ -2254,6 +2601,7 @@ static int cmd_import(int argc, char *argv[]) { } out = fopen(filename, "w"); + if(!out) { fprintf(stderr, "Error creating configuration file %s: %s\n", filename, strerror(errno)); return 1; @@ -2267,8 +2615,9 @@ static int cmd_import(int argc, char *argv[]) { } - if(!strcmp(buf, "#---------------------------------------------------------------#\n")) + if(!strcmp(buf, "#---------------------------------------------------------------#\n")) { continue; + } if(out) { if(fputs(buf, out) < 0) { @@ -2278,8 +2627,9 @@ static int cmd_import(int argc, char *argv[]) { } } - if(out) + if(out) { fclose(out); + } if(count) { fprintf(stderr, "Imported %d host configuration files.\n", count); @@ -2291,11 +2641,11 @@ static int cmd_import(int argc, char *argv[]) { } static int cmd_exchange(int argc, char *argv[]) { - return cmd_export(argc, argv) ?: cmd_import(argc, argv); + return cmd_export(argc, argv) ? 1 : cmd_import(argc, argv); } static int cmd_exchange_all(int argc, char *argv[]) { - return cmd_export_all(argc, argv) ?: cmd_import(argc, argv); + return cmd_export_all(argc, argv) ? 1 : cmd_import(argc, argv); } static int switch_network(char *name) { @@ -2305,8 +2655,9 @@ static int switch_network(char *name) { return 1; } - if(!check_netname(name, true)) + if(!check_netname(name, true)) { fprintf(stderr, "Warning: unsafe character in netname!\n"); + } } if(fd >= 0) { @@ -2322,8 +2673,8 @@ static int switch_network(char *name) { free(hosts_dir); free(prompt); - xasprintf(&tinc_conf, "%s" SLASH "tinc.conf", confbase); - xasprintf(&hosts_dir, "%s" SLASH "hosts", confbase); + xasprintf(&tinc_conf, "%s" SLASH "tinc.conf", confbase); + xasprintf(&hosts_dir, "%s" SLASH "hosts", confbase); xasprintf(&prompt, "%s> ", identname); return 0; @@ -2335,19 +2686,23 @@ static int cmd_network(int argc, char *argv[]) { return 1; } - if(argc == 2) + if(argc == 2) { return switch_network(argv[1]); + } DIR *dir = opendir(confdir); + if(!dir) { fprintf(stderr, "Could not read directory %s: %s\n", confdir, strerror(errno)); - return 1; - } + return 1; + } struct dirent *ent; + while((ent = readdir(dir))) { - if(*ent->d_name == '.') + if(*ent->d_name == '.') { continue; + } if(!strcmp(ent->d_name, "tinc.conf")) { printf(".\n"); @@ -2355,9 +2710,11 @@ static int cmd_network(int argc, char *argv[]) { } char fname[PATH_MAX]; - snprintf(fname, sizeof fname, "%s/%s/tinc.conf", confdir, ent->d_name); - if(!access(fname, R_OK)) + snprintf(fname, sizeof(fname), "%s/%s/tinc.conf", confdir, ent->d_name); + + if(!access(fname, R_OK)) { printf("%s\n", ent->d_name); + } } closedir(dir); @@ -2366,6 +2723,8 @@ static int cmd_network(int argc, char *argv[]) { } static int cmd_fsck(int argc, char *argv[]) { + (void)argv; + if(argc > 1) { fprintf(stderr, "Too many arguments!\n"); return 1; @@ -2376,22 +2735,27 @@ static int cmd_fsck(int argc, char *argv[]) { static void *readfile(FILE *in, size_t *len) { size_t count = 0; - size_t alloced = 4096; - char *buf = xmalloc(alloced); + size_t bufsize = 4096; + char *buf = xmalloc(bufsize); while(!feof(in)) { - size_t read = fread(buf + count, 1, alloced - count, in); - if(!read) + size_t read = fread(buf + count, 1, bufsize - count, in); + + if(!read) { break; + } + count += read; - if(count >= alloced) { - alloced *= 2; - buf = xrealloc(buf, alloced); + + if(count >= bufsize) { + bufsize *= 2; + buf = xrealloc(buf, bufsize); } } - if(len) + if(len) { *len = count; + } return buf; } @@ -2404,13 +2768,16 @@ static int cmd_sign(int argc, char *argv[]) { if(!name) { name = get_my_name(true); - if(!name) + + if(!name) { return 1; + } } char fname[PATH_MAX]; - snprintf(fname, sizeof fname, "%s" SLASH "ed25519_key.priv", confbase); + snprintf(fname, sizeof(fname), "%s" SLASH "ed25519_key.priv", confbase); FILE *fp = fopen(fname, "r"); + if(!fp) { fprintf(stderr, "Could not open %s: %s\n", fname, strerror(errno)); return 1; @@ -2430,6 +2797,7 @@ static int cmd_sign(int argc, char *argv[]) { if(argc == 2) { in = fopen(argv[1], "rb"); + if(!in) { fprintf(stderr, "Could not open %s: %s\n", argv[1], strerror(errno)); ecdsa_free(key); @@ -2441,8 +2809,11 @@ static int cmd_sign(int argc, char *argv[]) { size_t len; char *data = readfile(in, &len); - if(in != stdin) + + if(in != stdin) { fclose(in); + } + if(!data) { fprintf(stderr, "Error reading %s: %s\n", argv[1], strerror(errno)); ecdsa_free(key); @@ -2460,12 +2831,14 @@ static int cmd_sign(int argc, char *argv[]) { free(trailer); char sig[87]; + if(!ecdsa_sign(key, data, len + trailer_len, sig)) { fprintf(stderr, "Error generating signature\n"); free(data); ecdsa_free(key); return 1; } + b64encode(sig, sig, 64); ecdsa_free(key); @@ -2488,12 +2861,16 @@ static int cmd_verify(int argc, char *argv[]) { } char *node = argv[1]; + if(!strcmp(node, ".")) { if(!name) { name = get_my_name(true); - if(!name) + + if(!name) { return 1; + } } + node = name; } else if(!strcmp(node, "*")) { node = NULL; @@ -2508,6 +2885,7 @@ static int cmd_verify(int argc, char *argv[]) { if(argc == 3) { in = fopen(argv[2], "rb"); + if(!in) { fprintf(stderr, "Could not open %s: %s\n", argv[2], strerror(errno)); return 1; @@ -2518,14 +2896,18 @@ static int cmd_verify(int argc, char *argv[]) { size_t len; char *data = readfile(in, &len); - if(in != stdin) + + if(in != stdin) { fclose(in); + } + if(!data) { fprintf(stderr, "Error reading %s: %s\n", argv[1], strerror(errno)); return 1; } char *newline = memchr(data, '\n', len); + if(!newline || (newline - data > MAX_STRING_SIZE - 1)) { fprintf(stderr, "Invalid input\n"); free(data); @@ -2551,8 +2933,9 @@ static int cmd_verify(int argc, char *argv[]) { return 1; } - if(!node) + if(!node) { node = signer; + } char *trailer; xasprintf(&trailer, " %s %ld", signer, t); @@ -2565,8 +2948,9 @@ static int cmd_verify(int argc, char *argv[]) { newline = data + skip; char fname[PATH_MAX]; - snprintf(fname, sizeof fname, "%s" SLASH "hosts" SLASH "%s", confbase, node); + snprintf(fname, sizeof(fname), "%s" SLASH "hosts" SLASH "%s", confbase, node); FILE *fp = fopen(fname, "r"); + if(!fp) { fprintf(stderr, "Could not open %s: %s\n", fname, strerror(errno)); free(data); @@ -2574,10 +2958,12 @@ static int cmd_verify(int argc, char *argv[]) { } ecdsa_t *key = get_pubkey(fp); + if(!key) { rewind(fp); key = ecdsa_read_pem_public_key(fp); } + if(!key) { fprintf(stderr, "Could not read public key from %s\n", fname); fclose(fp); @@ -2607,62 +2993,65 @@ static const struct { int (*function)(int argc, char *argv[]); bool hidden; } commands[] = { - {"start", cmd_start}, - {"stop", cmd_stop}, - {"restart", cmd_restart}, - {"reload", cmd_reload}, - {"dump", cmd_dump}, - {"list", cmd_dump}, - {"purge", cmd_purge}, - {"debug", cmd_debug}, - {"retry", cmd_retry}, - {"connect", cmd_connect}, - {"disconnect", cmd_disconnect}, - {"top", cmd_top}, - {"pcap", cmd_pcap}, - {"log", cmd_log}, - {"pid", cmd_pid}, + {"start", cmd_start, false}, + {"stop", cmd_stop, false}, + {"restart", cmd_restart, false}, + {"reload", cmd_reload, false}, + {"dump", cmd_dump, false}, + {"list", cmd_dump, false}, + {"purge", cmd_purge, false}, + {"debug", cmd_debug, false}, + {"retry", cmd_retry, false}, + {"connect", cmd_connect, false}, + {"disconnect", cmd_disconnect, false}, + {"top", cmd_top, false}, + {"pcap", cmd_pcap, false}, + {"log", cmd_log, false}, + {"pid", cmd_pid, false}, {"config", cmd_config, true}, - {"add", cmd_config}, - {"del", cmd_config}, - {"get", cmd_config}, - {"set", cmd_config}, - {"init", cmd_init}, - {"generate-keys", cmd_generate_keys}, + {"add", cmd_config, false}, + {"del", cmd_config, false}, + {"get", cmd_config, false}, + {"set", cmd_config, false}, + {"init", cmd_init, false}, + {"generate-keys", cmd_generate_keys, false}, #ifndef DISABLE_LEGACY - {"generate-rsa-keys", cmd_generate_rsa_keys}, + {"generate-rsa-keys", cmd_generate_rsa_keys, false}, #endif - {"generate-ed25519-keys", cmd_generate_ed25519_keys}, - {"help", cmd_help}, - {"version", cmd_version}, - {"info", cmd_info}, - {"edit", cmd_edit}, - {"export", cmd_export}, - {"export-all", cmd_export_all}, - {"import", cmd_import}, - {"exchange", cmd_exchange}, - {"exchange-all", cmd_exchange_all}, - {"invite", cmd_invite}, - {"join", cmd_join}, - {"network", cmd_network}, - {"fsck", cmd_fsck}, - {"sign", cmd_sign}, - {"verify", cmd_verify}, - {NULL, NULL}, + {"generate-ed25519-keys", cmd_generate_ed25519_keys, false}, + {"help", cmd_help, false}, + {"version", cmd_version, false}, + {"info", cmd_info, false}, + {"edit", cmd_edit, false}, + {"export", cmd_export, false}, + {"export-all", cmd_export_all, false}, + {"import", cmd_import, false}, + {"exchange", cmd_exchange, false}, + {"exchange-all", cmd_exchange_all, false}, + {"invite", cmd_invite, false}, + {"join", cmd_join, false}, + {"network", cmd_network, false}, + {"fsck", cmd_fsck, false}, + {"sign", cmd_sign, false}, + {"verify", cmd_verify, false}, + {NULL, NULL, false}, }; #ifdef HAVE_READLINE static char *complete_command(const char *text, int state) { static int i; - if(!state) + if(!state) { i = 0; - else + } else { i++; + } while(commands[i].command) { - if(!commands[i].hidden && !strncasecmp(commands[i].command, text, strlen(text))) + if(!commands[i].hidden && !strncasecmp(commands[i].command, text, strlen(text))) { return xstrdup(commands[i].command); + } + i++; } @@ -2673,14 +3062,17 @@ static char *complete_dump(const char *text, int state) { const char *matches[] = {"reachable", "nodes", "edges", "subnets", "connections", "graph", NULL}; static int i; - if(!state) + if(!state) { i = 0; - else + } else { i++; + } while(matches[i]) { - if(!strncasecmp(matches[i], text, strlen(text))) + if(!strncasecmp(matches[i], text, strlen(text))) { return xstrdup(matches[i]); + } + i++; } @@ -2690,13 +3082,15 @@ static char *complete_dump(const char *text, int state) { static char *complete_config(const char *text, int state) { static int i; - if(!state) + if(!state) { i = 0; - else + } else { i++; + } while(variables[i].name) { char *dot = strchr(text, '.'); + if(dot) { if((variables[i].type & VAR_HOST) && !strncasecmp(variables[i].name, dot + 1, strlen(dot + 1))) { char *match; @@ -2704,9 +3098,11 @@ static char *complete_config(const char *text, int state) { return match; } } else { - if(!strncasecmp(variables[i].name, text, strlen(text))) + if(!strncasecmp(variables[i].name, text, strlen(text))) { return xstrdup(variables[i].name); + } } + i++; } @@ -2715,24 +3111,31 @@ static char *complete_config(const char *text, int state) { static char *complete_info(const char *text, int state) { static int i; + if(!state) { i = 0; - if(!connect_tincd(false)) + + if(!connect_tincd(false)) { return NULL; + } + // Check the list of nodes sendline(fd, "%d %d", CONTROL, REQ_DUMP_NODES); sendline(fd, "%d %d", CONTROL, REQ_DUMP_SUBNETS); } - while(recvline(fd, line, sizeof line)) { + while(recvline(fd, line, sizeof(line))) { char item[4096]; int n = sscanf(line, "%d %d %4095s", &code, &req, item); + if(n == 2) { i++; - if(i >= 2) + + if(i >= 2) { break; - else + } else { continue; + } } if(n != 3) { @@ -2740,34 +3143,39 @@ static char *complete_info(const char *text, int state) { break; } - if(!strncmp(item, text, strlen(text))) + if(!strncmp(item, text, strlen(text))) { return xstrdup(strip_weight(item)); + } } return NULL; } static char *complete_nothing(const char *text, int state) { + (void)text; + (void)state; return NULL; } -static char **completion (const char *text, int start, int end) { +static char **completion(const char *text, int start, int end) { + (void)end; char **matches = NULL; - if(!start) + if(!start) { matches = rl_completion_matches(text, complete_command); - else if(!strncasecmp(rl_line_buffer, "dump ", 5)) + } else if(!strncasecmp(rl_line_buffer, "dump ", 5)) { matches = rl_completion_matches(text, complete_dump); - else if(!strncasecmp(rl_line_buffer, "add ", 4)) + } else if(!strncasecmp(rl_line_buffer, "add ", 4)) { matches = rl_completion_matches(text, complete_config); - else if(!strncasecmp(rl_line_buffer, "del ", 4)) + } else if(!strncasecmp(rl_line_buffer, "del ", 4)) { matches = rl_completion_matches(text, complete_config); - else if(!strncasecmp(rl_line_buffer, "get ", 4)) + } else if(!strncasecmp(rl_line_buffer, "get ", 4)) { matches = rl_completion_matches(text, complete_config); - else if(!strncasecmp(rl_line_buffer, "set ", 4)) + } else if(!strncasecmp(rl_line_buffer, "set ", 4)) { matches = rl_completion_matches(text, complete_config); - else if(!strncasecmp(rl_line_buffer, "info ", 5)) + } else if(!strncasecmp(rl_line_buffer, "info ", 5)) { matches = rl_completion_matches(text, complete_info); + } return matches; } @@ -2779,10 +3187,11 @@ static int cmd_shell(int argc, char *argv[]) { char buf[4096]; char *line = NULL; int maxargs = argc + 16; - char **nargv = xmalloc(maxargs * sizeof *nargv); + char **nargv = xmalloc(maxargs * sizeof(*nargv)); - for(int i = 0; i < argc; i++) + for(int i = 0; i < argc; i++) { nargv[i] = argv[i]; + } #ifdef HAVE_READLINE rl_readline_name = "tinc"; @@ -2794,30 +3203,35 @@ static int cmd_shell(int argc, char *argv[]) { while(true) { #ifdef HAVE_READLINE + if(tty) { free(copy); free(line); rl_basic_word_break_characters = "\t\n "; line = readline(prompt); - if(line) - copy = xstrdup(line); + copy = line ? xstrdup(line) : NULL; } else { - line = fgets(buf, sizeof buf, stdin); + line = fgets(buf, sizeof(buf), stdin); } -#else - if(tty) - fputs(prompt, stdout); - line = fgets(buf, sizeof buf, stdin); +#else + + if(tty) { + fputs(prompt, stdout); + } + + line = fgets(buf, sizeof(buf), stdin); #endif - if(!line) + if(!line) { break; + } /* Ignore comments */ - if(*line == '#') + if(*line == '#') { continue; + } /* Split */ @@ -2828,7 +3242,7 @@ static int cmd_shell(int argc, char *argv[]) { while(p && *p) { if(nargc >= maxargs) { maxargs *= 2; - nargv = xrealloc(nargv, maxargs * sizeof *nargv); + nargv = xrealloc(nargv, maxargs * sizeof(*nargv)); } nargv[nargc++] = p; @@ -2836,10 +3250,14 @@ static int cmd_shell(int argc, char *argv[]) { next = strtok(NULL, " \t\n"); } - if(nargc == argc) + if(nargc == argc) { continue; + } if(!strcasecmp(nargv[argc], "exit") || !strcasecmp(nargv[argc], "quit")) { +#ifdef HAVE_READLINE + free(copy); +#endif free(nargv); return result; } @@ -2855,8 +3273,11 @@ static int cmd_shell(int argc, char *argv[]) { } #ifdef HAVE_READLINE - if(tty && found) + + if(tty && found) { add_history(copy); + } + #endif if(!found) { @@ -2865,10 +3286,15 @@ static int cmd_shell(int argc, char *argv[]) { } } +#ifdef HAVE_READLINE + free(copy); +#endif free(nargv); - if(tty) + if(tty) { printf("\n"); + } + return result; } @@ -2879,8 +3305,9 @@ int main(int argc, char *argv[]) { orig_argc = argc; tty = isatty(0) && isatty(1); - if(!parse_options(argc, argv)) + if(!parse_options(argc, argv)) { return 1; + } make_names(false); xasprintf(&tinc_conf, "%s" SLASH "tinc.conf", confbase); @@ -2900,20 +3327,23 @@ int main(int argc, char *argv[]) { static struct WSAData wsa_state; if(WSAStartup(MAKEWORD(2, 2), &wsa_state)) { - fprintf(stderr, "System call `%s' failed: %s", "WSAStartup", winerror(GetLastError())); + fprintf(stderr, "System call `%s' failed: %s\n", "WSAStartup", winerror(GetLastError())); return false; } + #endif srand(time(NULL)); crypto_init(); - if(optind >= argc) + if(optind >= argc) { return cmd_shell(argc, argv); + } for(int i = 0; commands[i].command; i++) { - if(!strcasecmp(argv[optind], commands[i].command)) + if(!strcasecmp(argv[optind], commands[i].command)) { return commands[i].function(argc - optind, argv + optind); + } } fprintf(stderr, "Unknown command `%s'.\n", argv[optind]); diff --git a/src/tincctl.h b/src/tincctl.h index 6628f2b..3f7d003 100644 --- a/src/tincctl.h +++ b/src/tincctl.h @@ -1,3 +1,6 @@ +#ifndef TINC_TINCCTL_H +#define TINC_TINCCTL_H + /* tincctl.h -- header for tincctl.c. Copyright (C) 2011-2016 Guus Sliepen @@ -17,9 +20,6 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#ifndef __TINC_TINCCTL_H__ -#define __TINC_TINCCTL_H__ - extern bool tty; extern bool force; extern char line[4096]; @@ -48,9 +48,8 @@ extern char *get_my_name(bool verbose); extern bool connect_tincd(bool verbose); extern bool sendline(int fd, char *format, ...); extern bool recvline(int fd, char *line, size_t len); -extern int check_port(char *name); +extern int check_port(const char *name); extern FILE *fopenmask(const char *filename, const char *mode, mode_t perms); extern ecdsa_t *get_pubkey(FILE *f); #endif - diff --git a/src/tincd.c b/src/tincd.c index 2ab9ba7..dbf6bc8 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-2016 Guus Sliepen + 2000-2018 Guus Sliepen 2008 Max Rijevski 2009 Michael Tokarev 2010 Julien Muchembled @@ -116,27 +116,27 @@ int main2(int argc, char **argv); static void usage(bool status) { if(status) fprintf(stderr, "Try `%s --help\' for more information.\n", - program_name); + program_name); else { printf("Usage: %s [option]...\n\n", program_name); - printf( " -c, --config=DIR Read configuration options from DIR.\n" - " -D, --no-detach Don't fork and detach.\n" - " -d, --debug[=LEVEL] Increase debug level or set it to LEVEL.\n" - " -n, --net=NETNAME Connect to net NETNAME.\n" + printf(" -c, --config=DIR Read configuration options from DIR.\n" + " -D, --no-detach Don't fork and detach.\n" + " -d, --debug[=LEVEL] Increase debug level or set it to LEVEL.\n" + " -n, --net=NETNAME Connect to net NETNAME.\n" #ifdef HAVE_MLOCKALL - " -L, --mlock Lock tinc into main memory.\n" + " -L, --mlock Lock tinc into main memory.\n" #endif - " --logfile[=FILENAME] Write log entries to a logfile.\n" - " -s --syslog Use syslog instead of stderr with --no-detach.\n" - " --pidfile=FILENAME Write PID and control socket cookie to FILENAME.\n" - " --bypass-security Disables meta protocol security, for debugging.\n" - " -o, --option[HOST.]KEY=VALUE Set global/host configuration value.\n" + " --logfile[=FILENAME] Write log entries to a logfile.\n" + " -s --syslog Use syslog instead of stderr with --no-detach.\n" + " --pidfile=FILENAME Write PID and control socket cookie to FILENAME.\n" + " --bypass-security Disables meta protocol security, for debugging.\n" + " -o, --option[HOST.]KEY=VALUE Set global/host configuration value.\n" #ifndef HAVE_MINGW - " -R, --chroot chroot to NET dir at startup.\n" - " -U, --user=USER setuid to given USER at startup.\n" + " -R, --chroot chroot to NET dir at startup.\n" + " -U, --user=USER setuid to given USER at startup.\n" #endif - " --help Display this help and exit.\n" - " --version Output version information and exit.\n\n"); + " --help Display this help and exit.\n" + " --version Output version information and exit.\n\n"); printf("Report bugs to tinc@tinc-vpn.org.\n"); } } @@ -150,98 +150,112 @@ static bool parse_options(int argc, char **argv) { cmdline_conf = list_alloc((list_action_t)free_config); while((r = getopt_long(argc, argv, "c:DLd::n:so:RU:", long_options, &option_index)) != EOF) { - switch (r) { - case 0: /* long option */ - break; + switch(r) { + case 0: /* long option */ + break; - case 'c': /* config file */ - confbase = xstrdup(optarg); - break; + case 'c': /* config file */ + confbase = xstrdup(optarg); + break; - case 'D': /* no detach */ - do_detach = false; - break; + case 'D': /* no detach */ + do_detach = false; + break; - case 'L': /* no detach */ + case 'L': /* no detach */ #ifndef HAVE_MLOCKALL - logger(DEBUG_ALWAYS, LOG_ERR, "The %s option is not supported on this platform.", argv[optind - 1]); - return false; + logger(DEBUG_ALWAYS, LOG_ERR, "The %s option is not supported on this platform.", argv[optind - 1]); + return false; #else - do_mlock = true; - break; + do_mlock = true; + break; #endif - case 'd': /* increase debug level */ - if(!optarg && optind < argc && *argv[optind] != '-') - optarg = argv[optind++]; - if(optarg) - debug_level = atoi(optarg); - else - debug_level++; - break; + case 'd': /* increase debug level */ + if(!optarg && optind < argc && *argv[optind] != '-') { + optarg = argv[optind++]; + } - case 'n': /* net name given */ - netname = xstrdup(optarg); - break; + if(optarg) { + debug_level = atoi(optarg); + } else { + debug_level++; + } - case 's': /* syslog */ - use_logfile = false; - use_syslog = true; - break; + break; - case 'o': /* option */ - cfg = parse_config_line(optarg, NULL, ++lineno); - if (!cfg) - return false; - list_insert_tail(cmdline_conf, cfg); - break; + case 'n': /* net name given */ + netname = xstrdup(optarg); + break; + + case 's': /* syslog */ + use_logfile = false; + use_syslog = true; + break; + + case 'o': /* option */ + cfg = parse_config_line(optarg, NULL, ++lineno); + + if(!cfg) { + return false; + } + + list_insert_tail(cmdline_conf, cfg); + break; #ifdef HAVE_MINGW - case 'R': - case 'U': - logger(DEBUG_ALWAYS, LOG_ERR, "The %s option is not supported on this platform.", argv[optind - 1]); - return false; -#else - case 'R': /* chroot to NETNAME dir */ - do_chroot = true; - break; - case 'U': /* setuid to USER */ - switchuser = optarg; - break; + case 'R': + case 'U': + logger(DEBUG_ALWAYS, LOG_ERR, "The %s option is not supported on this platform.", argv[optind - 1]); + return false; +#else + + case 'R': /* chroot to NETNAME dir */ + do_chroot = true; + break; + + case 'U': /* setuid to USER */ + switchuser = optarg; + break; #endif - case 1: /* show help */ - show_help = true; - break; + case 1: /* show help */ + show_help = true; + break; - case 2: /* show version */ - show_version = true; - break; + case 2: /* show version */ + show_version = true; + break; - case 3: /* bypass security */ - bypass_security = true; - break; + case 3: /* bypass security */ + bypass_security = true; + break; - case 4: /* write log entries to a file */ - use_syslog = false; - use_logfile = true; - if(!optarg && optind < argc && *argv[optind] != '-') - optarg = argv[optind++]; - if(optarg) - logfilename = xstrdup(optarg); - break; + case 4: /* write log entries to a file */ + use_syslog = false; + use_logfile = true; - case 5: /* open control socket here */ - pidfilename = xstrdup(optarg); - break; + if(!optarg && optind < argc && *argv[optind] != '-') { + optarg = argv[optind++]; + } - case '?': /* wrong options */ - usage(true); - return false; + if(optarg) { + logfilename = xstrdup(optarg); + } - default: - break; + break; + + case 5: /* open control socket here */ + pidfilename = xstrdup(optarg); + break; + + case '?': /* wrong options */ + usage(true); + return false; + + default: + break; } } @@ -251,8 +265,9 @@ static bool parse_options(int argc, char **argv) { return false; } - if(!netname && (netname = getenv("NETNAME"))) + if(!netname && (netname = getenv("NETNAME"))) { netname = xstrdup(netname); + } /* netname "." is special: a "top-level name" */ @@ -266,8 +281,9 @@ static bool parse_options(int argc, char **argv) { return false; } - if(netname && !check_netname(netname, true)) + if(netname && !check_netname(netname, true)) { fprintf(stderr, "Warning: unsafe character in netname!\n"); + } return true; } @@ -275,41 +291,51 @@ static bool parse_options(int argc, char **argv) { static bool drop_privs(void) { #ifndef HAVE_MINGW uid_t uid = 0; - if (switchuser) { + + if(switchuser) { struct passwd *pw = getpwnam(switchuser); - if (!pw) { + + if(!pw) { logger(DEBUG_ALWAYS, LOG_ERR, "unknown user `%s'", switchuser); return false; } + uid = pw->pw_uid; - if (initgroups(switchuser, pw->pw_gid) != 0 || - setgid(pw->pw_gid) != 0) { + + if(initgroups(switchuser, pw->pw_gid) != 0 || + setgid(pw->pw_gid) != 0) { logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "initgroups", strerror(errno)); return false; } + #ifndef __ANDROID__ // Not supported in android NDK endgrent(); endpwent(); #endif } - if (do_chroot) { + + if(do_chroot) { tzset(); /* for proper timestamps in logs */ - if (chroot(confbase) != 0 || chdir("/") != 0) { + + if(chroot(confbase) != 0 || chdir("/") != 0) { logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "chroot", strerror(errno)); return false; } + free(confbase); confbase = xstrdup(""); } - if (switchuser) - if (setuid(uid) != 0) { + + if(switchuser) + if(setuid(uid) != 0) { logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "setuid", strerror(errno)); return false; } + #endif return true; } @@ -323,8 +349,11 @@ static void stop_handler(void *data, int flags) { static BOOL WINAPI console_ctrl_handler(DWORD type) { logger(DEBUG_ALWAYS, LOG_NOTICE, "Got console shutdown request"); - if (WSASetEvent(stop_io.event) == FALSE) + + if(WSASetEvent(stop_io.event) == FALSE) { abort(); + } + return TRUE; } #else @@ -337,20 +366,18 @@ static BOOL WINAPI console_ctrl_handler(DWORD type) { int main(int argc, char **argv) { program_name = argv[0]; - if(!parse_options(argc, argv)) + if(!parse_options(argc, argv)) { return 1; - - make_names(true); - chdir(confbase); + } if(show_version) { printf("%s version %s (built %s %s, protocol %d.%d)\n", PACKAGE, - BUILD_VERSION, BUILD_DATE, BUILD_TIME, PROT_MAJOR, PROT_MINOR); - printf("Copyright (C) 1998-2016 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" - "see the file COPYING for details.\n"); + BUILD_VERSION, BUILD_DATE, BUILD_TIME, PROT_MAJOR, PROT_MINOR); + printf("Copyright (C) 1998-2018 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" + "see the file COPYING for details.\n"); return 0; } @@ -360,31 +387,46 @@ int main(int argc, char **argv) { return 0; } + make_names(true); + chdir(confbase); + #ifdef HAVE_MINGW + if(WSAStartup(MAKEWORD(2, 2), &wsa_state)) { logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "WSAStartup", winerror(GetLastError())); return 1; } + #else // Check if we got an umbilical fd from the process that started us char *umbstr = getenv("TINC_UMBILICAL"); + if(umbstr) { umbilical = atoi(umbstr); - if(fcntl(umbilical, F_GETFL) < 0) + + if(fcntl(umbilical, F_GETFL) < 0) { umbilical = 0; + } + #ifdef FD_CLOEXEC - if(umbilical) + + if(umbilical) { fcntl(umbilical, F_SETFD, FD_CLOEXEC); + } + #endif } + #endif - openlogger("tinc", use_logfile?LOGMODE_FILE:LOGMODE_STDERR); + openlogger("tinc", use_logfile ? LOGMODE_FILE : LOGMODE_STDERR); g_argv = argv; - if(getenv("LISTEN_PID") && atoi(getenv("LISTEN_PID")) == getpid()) + if(getenv("LISTEN_PID") && atoi(getenv("LISTEN_PID")) == getpid()) { do_detach = false; + } + #ifdef HAVE_UNSETENV unsetenv("LISTEN_PID"); #endif @@ -397,33 +439,43 @@ int main(int argc, char **argv) { srand(now.tv_sec + now.tv_usec); crypto_init(); - if(!read_server_config()) + if(!read_server_config()) { return 1; + } - if(!debug_level) + if(!debug_level) { get_config_int(lookup_config(config_tree, "LogLevel"), &debug_level); + } #ifdef HAVE_LZO + if(lzo_init() != LZO_E_OK) { logger(DEBUG_ALWAYS, LOG_ERR, "Error initializing LZO compressor!"); return 1; } + #endif #ifdef HAVE_MINGW io_add_event(&stop_io, stop_handler, NULL, WSACreateEvent()); - if (stop_io.event == FALSE) + + if(stop_io.event == FALSE) { abort(); + } int result; + if(!do_detach || !init_service()) { SetConsoleCtrlHandler(console_ctrl_handler, TRUE); result = main2(argc, argv); - } else + } else { result = 1; + } - if (WSACloseEvent(stop_io.event) == FALSE) + if(WSACloseEvent(stop_io.event) == FALSE) { abort(); + } + io_del(&stop_io); return result; } @@ -432,40 +484,44 @@ int main2(int argc, char **argv) { #endif char *priority = NULL; - if(!detach()) + if(!detach()) { return 1; + } #ifdef HAVE_MLOCKALL + /* Lock all pages into memory if requested. * This has to be done after daemon()/fork() so it works for child. * No need to do that in parent as it's very short-lived. */ if(do_mlock && mlockall(MCL_CURRENT | MCL_FUTURE) != 0) { logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "mlockall", - strerror(errno)); + strerror(errno)); return 1; } + #endif /* Setup sockets and open device. */ - if(!setup_network()) + if(!setup_network()) { goto end; + } /* Change process priority */ if(get_config_string(lookup_config(config_tree, "ProcessPriority"), &priority)) { if(!strcasecmp(priority, "Normal")) { - if (setpriority(NORMAL_PRIORITY_CLASS) != 0) { + if(setpriority(NORMAL_PRIORITY_CLASS) != 0) { logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "setpriority", strerror(errno)); goto end; } } else if(!strcasecmp(priority, "Low")) { - if (setpriority(BELOW_NORMAL_PRIORITY_CLASS) != 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "setpriority", strerror(errno)); + if(setpriority(BELOW_NORMAL_PRIORITY_CLASS) != 0) { + logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "setpriority", strerror(errno)); goto end; } } else if(!strcasecmp(priority, "High")) { - if (setpriority(HIGH_PRIORITY_CLASS) != 0) { + if(setpriority(HIGH_PRIORITY_CLASS) != 0) { logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "setpriority", strerror(errno)); goto end; } @@ -476,8 +532,9 @@ int main2(int argc, char **argv) { } /* drop privileges */ - if (!drop_privs()) + if(!drop_privs()) { goto end; + } /* Start main loop. It only exits when tinc is killed. */ diff --git a/src/top.c b/src/top.c index 8227d6c..ab14619 100644 --- a/src/top.c +++ b/src/top.c @@ -68,8 +68,9 @@ static const char *punit = "pkts"; static float pscale = 1; static bool update(int fd) { - if(!sendline(fd, "%d %d", CONTROL, REQ_DUMP_TRAFFIC)) + if(!sendline(fd, "%d %d", CONTROL, REQ_DUMP_TRAFFIC)) { return false; + } gettimeofday(&cur, NULL); @@ -86,29 +87,35 @@ static bool update(int fd) { uint64_t out_packets; uint64_t out_bytes; - for list_each(nodestats_t, ns, &node_list) + for list_each(nodestats_t, ns, &node_list) { ns->known = false; + } - while(recvline(fd, line, sizeof line)) { + while(recvline(fd, line, sizeof(line))) { int n = sscanf(line, "%d %d %4095s %"PRIu64" %"PRIu64" %"PRIu64" %"PRIu64, &code, &req, name, &in_packets, &in_bytes, &out_packets, &out_bytes); - if(n == 2) + if(n == 2) { return true; + } - if(n != 7) + if(n != 7) { return false; + } nodestats_t *found = NULL; for list_each(nodestats_t, ns, &node_list) { int result = strcmp(name, ns->name); + if(result > 0) { continue; - } if(result == 0) { + } + + if(result == 0) { found = ns; break; } else { - found = xzalloc(sizeof *found); + found = xzalloc(sizeof(*found)); found->name = xstrdup(name); list_insert_before(&node_list, node, found); changed = true; @@ -117,7 +124,7 @@ static bool update(int fd) { } if(!found) { - found = xzalloc(sizeof *found); + found = xzalloc(sizeof(*found)); found->name = xstrdup(name); list_insert_tail(&node_list, found); changed = true; @@ -138,21 +145,23 @@ static bool update(int fd) { } static int cmpfloat(float a, float b) { - if(a < b) + if(a < b) { return -1; - else if(a > b) + } else if(a > b) { return 1; - else + } else { return 0; + } } static int cmpu64(uint64_t a, uint64_t b) { - if(a < b) + if(a < b) { return -1; - else if(a > b) + } else if(a > b) { return 1; - else + } else { return 0; + } } static int sortfunc(const void *a, const void *b) { @@ -161,93 +170,120 @@ static int sortfunc(const void *a, const void *b) { int result; switch(sortmode) { - case 1: - if(cumulative) - result = -cmpu64(na->in_packets, nb->in_packets); - else - result = -cmpfloat(na->in_packets_rate, nb->in_packets_rate); - break; - case 2: - if(cumulative) - result = -cmpu64(na->in_bytes, nb->in_bytes); - else - result = -cmpfloat(na->in_bytes_rate, nb->in_bytes_rate); - break; - case 3: - if(cumulative) - result = -cmpu64(na->out_packets, nb->out_packets); - else - result = -cmpfloat(na->out_packets_rate, nb->out_packets_rate); - break; - case 4: - if(cumulative) - result = -cmpu64(na->out_bytes, nb->out_bytes); - else - result = -cmpfloat(na->out_bytes_rate, nb->out_bytes_rate); - break; - case 5: - if(cumulative) - result = -cmpu64(na->in_packets + na->out_packets, nb->in_packets + nb->out_packets); - else - result = -cmpfloat(na->in_packets_rate + na->out_packets_rate, nb->in_packets_rate + nb->out_packets_rate); - break; - case 6: - if(cumulative) - result = -cmpu64(na->in_bytes + na->out_bytes, nb->in_bytes + nb->out_bytes); - else - result = -cmpfloat(na->in_bytes_rate + na->out_bytes_rate, nb->in_bytes_rate + nb->out_bytes_rate); - break; - default: - result = strcmp(na->name, nb->name); - break; + case 1: + if(cumulative) { + result = -cmpu64(na->in_packets, nb->in_packets); + } else { + result = -cmpfloat(na->in_packets_rate, nb->in_packets_rate); + } + + break; + + case 2: + if(cumulative) { + result = -cmpu64(na->in_bytes, nb->in_bytes); + } else { + result = -cmpfloat(na->in_bytes_rate, nb->in_bytes_rate); + } + + break; + + case 3: + if(cumulative) { + result = -cmpu64(na->out_packets, nb->out_packets); + } else { + result = -cmpfloat(na->out_packets_rate, nb->out_packets_rate); + } + + break; + + case 4: + if(cumulative) { + result = -cmpu64(na->out_bytes, nb->out_bytes); + } else { + result = -cmpfloat(na->out_bytes_rate, nb->out_bytes_rate); + } + + break; + + case 5: + if(cumulative) { + result = -cmpu64(na->in_packets + na->out_packets, nb->in_packets + nb->out_packets); + } else { + result = -cmpfloat(na->in_packets_rate + na->out_packets_rate, nb->in_packets_rate + nb->out_packets_rate); + } + + break; + + case 6: + if(cumulative) { + result = -cmpu64(na->in_bytes + na->out_bytes, nb->in_bytes + nb->out_bytes); + } else { + result = -cmpfloat(na->in_bytes_rate + na->out_bytes_rate, nb->in_bytes_rate + nb->out_bytes_rate); + } + + break; + + default: + result = strcmp(na->name, nb->name); + break; } - if(result) + if(result) { return result; - else + } else { return na->i - nb->i; + } } static void redraw(void) { erase(); - mvprintw(0, 0, "Tinc %-16s Nodes: %4d Sort: %-10s %s", netname ?: "", node_list.count, sortname[sortmode], cumulative ? "Cumulative" : "Current"); + mvprintw(0, 0, "Tinc %-16s Nodes: %4d Sort: %-10s %s", netname ? netname : "", node_list.count, sortname[sortmode], cumulative ? "Cumulative" : "Current"); attrset(A_REVERSE); mvprintw(2, 0, "Node IN %s IN %s OUT %s OUT %s", punit, bunit, punit, bunit); chgat(-1, A_REVERSE, 0, NULL); static nodestats_t **sorted = 0; static int n = 0; + if(changed) { n = 0; - sorted = xrealloc(sorted, node_list.count * sizeof *sorted); - for list_each(nodestats_t, ns, &node_list) + sorted = xrealloc(sorted, node_list.count * sizeof(*sorted)); + + for list_each(nodestats_t, ns, &node_list) { sorted[n++] = ns; + } + changed = false; } - for(int i = 0; i < n; i++) + for(int i = 0; i < n; i++) { sorted[i]->i = i; + } - if(sorted) - qsort(sorted, n, sizeof *sorted, sortfunc); + if(sorted) { + qsort(sorted, n, sizeof(*sorted), sortfunc); + } for(int i = 0, row = 3; i < n; i++, row++) { nodestats_t *node = sorted[i]; + if(node->known) - if(node->in_packets_rate || node->out_packets_rate) + if(node->in_packets_rate || node->out_packets_rate) { attrset(A_BOLD); - else + } else { attrset(A_NORMAL); - else + } else { attrset(A_DIM); + } if(cumulative) mvprintw(row, 0, "%-16s %10.0f %10.0f %10.0f %10.0f", - node->name, node->in_packets * pscale, node->in_bytes * bscale, node->out_packets * pscale, node->out_bytes * bscale); + node->name, node->in_packets * pscale, node->in_bytes * bscale, node->out_packets * pscale, node->out_bytes * bscale); else mvprintw(row, 0, "%-16s %10.0f %10.0f %10.0f %10.0f", - node->name, node->in_packets_rate * pscale, node->in_bytes_rate * bscale, node->out_packets_rate * pscale, node->out_bytes_rate * bscale); + node->name, node->in_packets_rate * pscale, node->in_bytes_rate * bscale, node->out_packets_rate * pscale, node->out_bytes_rate * bscale); } attrset(A_NORMAL); @@ -262,77 +298,95 @@ void top(int fd) { bool running = true; while(running) { - if(!update(fd)) + if(!update(fd)) { break; + } redraw(); switch(getch()) { - case 's': { - timeout(-1); - float input = delay * 1e-3; - mvprintw(1, 0, "Change delay from %.1fs to: ", input); - scanw("%f", &input); - if(input < 0.1) - input = 0.1; - delay = input * 1e3; - timeout(delay); - break; + case 's': { + timeout(-1); + float input = delay * 1e-3; + mvprintw(1, 0, "Change delay from %.1fs to: ", input); + scanw("%f", &input); + + if(input < 0.1) { + input = 0.1; } - case 'c': - cumulative = !cumulative; - break; - case 'n': - sortmode = 0; - break; - case 'i': - sortmode = 2; - break; - case 'I': - sortmode = 1; - break; - case 'o': - sortmode = 4; - break; - case 'O': - sortmode = 3; - break; - case 't': - sortmode = 6; - break; - case 'T': - sortmode = 5; - break; - case 'b': - bunit = "bytes"; - bscale = 1; - punit = "pkts"; - pscale = 1; - break; - case 'k': - bunit = "kbyte"; - bscale = 1e-3; - punit = "pkts"; - pscale = 1; - break; - case 'M': - bunit = "Mbyte"; - bscale = 1e-6; - punit = "kpkt"; - pscale = 1e-3; - break; - case 'G': - bunit = "Gbyte"; - bscale = 1e-9; - punit = "Mpkt"; - pscale = 1e-6; - break; - case 'q': - case KEY_BREAK: - running = false; - break; - default: - break; + + delay = input * 1e3; + timeout(delay); + break; + } + + case 'c': + cumulative = !cumulative; + break; + + case 'n': + sortmode = 0; + break; + + case 'i': + sortmode = 2; + break; + + case 'I': + sortmode = 1; + break; + + case 'o': + sortmode = 4; + break; + + case 'O': + sortmode = 3; + break; + + case 't': + sortmode = 6; + break; + + case 'T': + sortmode = 5; + break; + + case 'b': + bunit = "bytes"; + bscale = 1; + punit = "pkts"; + pscale = 1; + break; + + case 'k': + bunit = "kbyte"; + bscale = 1e-3; + punit = "pkts"; + pscale = 1; + break; + + case 'M': + bunit = "Mbyte"; + bscale = 1e-6; + punit = "kpkt"; + pscale = 1e-3; + break; + + case 'G': + bunit = "Gbyte"; + bscale = 1e-9; + punit = "Mpkt"; + pscale = 1e-6; + break; + + case 'q': + case KEY_BREAK: + running = false; + break; + + default: + break; } } diff --git a/src/top.h b/src/top.h index b3a264d..612d0d8 100644 --- a/src/top.h +++ b/src/top.h @@ -1,3 +1,6 @@ +#ifndef TINC_TOP_H +#define TINC_TOP_H + /* top.h -- header for top.c. Copyright (C) 2011 Guus Sliepen @@ -17,10 +20,6 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#ifndef __TINC_TOP_H__ -#define __TINC_TOP_H__ - extern void top(int fd); #endif - diff --git a/src/uml_device.c b/src/uml_device.c index 68f4cd2..a675b62 100644 --- a/src/uml_device.c +++ b/src/uml_device.c @@ -36,15 +36,15 @@ static int request_fd = -1; static int data_fd = -1; static int write_fd = -1; static int state = 0; -static char *device_info; +static const char *device_info = "UML network socket"; enum request_type { REQ_NEW_CONTROL }; static struct request { - uint32_t magic; - uint32_t version; - enum request_type type; - struct sockaddr_un sock; + uint32_t magic; + uint32_t version; + enum request_type type; + struct sockaddr_un sock; } request; static struct sockaddr_un data_sun; @@ -59,13 +59,12 @@ static bool setup_device(void) { } name; struct timeval tv; - if(!get_config_string(lookup_config(config_tree, "Device"), &device)) - xasprintf(&device, LOCALSTATEDIR "/run/%s.umlsocket", identname); + if(!get_config_string(lookup_config(config_tree, "Device"), &device)) { + xasprintf(&device, RUNSTATEDIR "/%s.umlsocket", identname); + } get_config_string(lookup_config(config_tree, "Interface"), &iface); - device_info = "UML network socket"; - if((write_fd = socket(PF_UNIX, SOCK_DGRAM, 0)) < 0) { logger(DEBUG_ALWAYS, LOG_ERR, "Could not open write %s: %s", device_info, strerror(errno)); event_exit(); @@ -76,7 +75,7 @@ static bool setup_device(void) { fcntl(write_fd, F_SETFD, FD_CLOEXEC); #endif - setsockopt(write_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof one); + setsockopt(write_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)); if(fcntl(write_fd, F_SETFL, O_NONBLOCK) < 0) { logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "fcntl", strerror(errno)); @@ -94,7 +93,7 @@ static bool setup_device(void) { fcntl(data_fd, F_SETFD, FD_CLOEXEC); #endif - setsockopt(data_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof one); + setsockopt(data_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)); if(fcntl(data_fd, F_SETFL, O_NONBLOCK) < 0) { logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "fcntl", strerror(errno)); @@ -107,9 +106,9 @@ static bool setup_device(void) { gettimeofday(&tv, NULL); name.usecs = tv.tv_usec; data_sun.sun_family = AF_UNIX; - memcpy(&data_sun.sun_path, &name, sizeof name); + memcpy(&data_sun.sun_path, &name, sizeof(name)); - if(bind(data_fd, (struct sockaddr *)&data_sun, sizeof data_sun) < 0) { + if(bind(data_fd, (struct sockaddr *)&data_sun, sizeof(data_sun)) < 0) { logger(DEBUG_ALWAYS, LOG_ERR, "Could not bind data %s: %s", device_info, strerror(errno)); event_exit(); return false; @@ -117,7 +116,7 @@ static bool setup_device(void) { if((listen_fd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) { logger(DEBUG_ALWAYS, LOG_ERR, "Could not open %s: %s", device_info, - strerror(errno)); + strerror(errno)); return false; } @@ -125,7 +124,7 @@ static bool setup_device(void) { fcntl(device_fd, F_SETFD, FD_CLOEXEC); #endif - setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof one); + setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)); if(fcntl(listen_fd, F_SETFL, O_NONBLOCK) < 0) { logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "fcntl", strerror(errno)); @@ -133,8 +132,10 @@ static bool setup_device(void) { } listen_sun.sun_family = AF_UNIX; - strncpy(listen_sun.sun_path, device, sizeof listen_sun.sun_path); - if(bind(listen_fd, (struct sockaddr *)&listen_sun, sizeof listen_sun) < 0) { + strncpy(listen_sun.sun_path, device, sizeof(listen_sun.sun_path)); + listen_sun.sun_path[sizeof(listen_sun.sun_path) - 1] = 0; + + if(bind(listen_fd, (struct sockaddr *)&listen_sun, sizeof(listen_sun)) < 0) { logger(DEBUG_ALWAYS, LOG_ERR, "Could not bind %s to %s: %s", device_info, device, strerror(errno)); return false; } @@ -149,35 +150,42 @@ static bool setup_device(void) { logger(DEBUG_ALWAYS, LOG_INFO, "%s is a %s", device, device_info); - if(routing_mode == RMODE_ROUTER) + if(routing_mode == RMODE_ROUTER) { overwrite_mac = true; + } return true; } void close_device(void) { if(listen_fd >= 0) { - close(listen_fd); listen_fd = -1; + close(listen_fd); + listen_fd = -1; } if(request_fd >= 0) { - close(request_fd); request_fd = -1; + close(request_fd); + request_fd = -1; } if(data_fd >= 0) { - close(data_fd); data_fd = -1; + close(data_fd); + data_fd = -1; } if(write_fd >= 0) { - close(write_fd); write_fd = -1; + close(write_fd); + write_fd = -1; } unlink(device); - free(device); device = NULL; - if(iface) { - free(iface); iface = NULL; - } + free(device); + device = NULL; + + free(iface); + iface = NULL; + device_info = NULL; } @@ -185,95 +193,96 @@ static bool read_packet(vpn_packet_t *packet) { int inlen; switch(state) { - case 0: { - struct sockaddr sa; - socklen_t salen = sizeof sa; + case 0: { + struct sockaddr sa; + socklen_t salen = sizeof(sa); - request_fd = accept(listen_fd, &sa, &salen); - if(request_fd < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not accept connection to %s %s: %s", device_info, device, strerror(errno)); - return false; - } + request_fd = accept(listen_fd, &sa, &salen); + + if(request_fd < 0) { + logger(DEBUG_ALWAYS, LOG_ERR, "Could not accept connection to %s %s: %s", device_info, device, strerror(errno)); + return false; + } #ifdef FD_CLOEXEC - fcntl(request_fd, F_SETFD, FD_CLOEXEC); + fcntl(request_fd, F_SETFD, FD_CLOEXEC); #endif - if(fcntl(listen_fd, F_SETFL, O_NONBLOCK) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "fcntl", strerror(errno)); - event_exit(); - return false; - } - - close(listen_fd); - listen_fd = -1; - device_fd = request_fd; - state = 1; - + if(fcntl(listen_fd, F_SETFL, O_NONBLOCK) < 0) { + logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "fcntl", strerror(errno)); + event_exit(); return false; } - case 1: { - if((inlen = read(request_fd, &request, sizeof request)) != sizeof request) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading request from %s %s: %s", device_info, - device, strerror(errno)); - event_exit(); - return false; - } + close(listen_fd); + listen_fd = -1; + device_fd = request_fd; + state = 1; - if(request.magic != 0xfeedface || request.version != 3 || request.type != REQ_NEW_CONTROL) { - logger(DEBUG_ALWAYS, LOG_ERR, "Unknown magic %x, version %d, request type %d from %s %s", - request.magic, request.version, request.type, device_info, device); - event_exit(); - return false; - } + return false; + } - if(connect(write_fd, (struct sockkadr *)&request.sock, sizeof request.sock) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not bind write %s: %s", device_info, strerror(errno)); - event_exit(); - return false; - } - - write(request_fd, &data_sun, sizeof data_sun); - device_fd = data_fd; - - logger(DEBUG_ALWAYS, LOG_INFO, "Connection with UML established"); - - state = 2; + case 1: { + if((inlen = read(request_fd, &request, sizeof(request))) != sizeof(request)) { + logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading request from %s %s: %s", device_info, + device, strerror(errno)); + event_exit(); return false; } - case 2: { - if((inlen = read(data_fd, DATA(packet), MTU)) <= 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info, - device, strerror(errno)); - event_exit(); - return false; - } - - packet->len = inlen; - - logger(DEBUG_TRAFFIC, LOG_DEBUG, "Read packet of %d bytes from %s", packet->len, - device_info); - - return true; + if(request.magic != 0xfeedface || request.version != 3 || request.type != REQ_NEW_CONTROL) { + logger(DEBUG_ALWAYS, LOG_ERR, "Unknown magic %x, version %d, request type %d from %s %s", + request.magic, request.version, request.type, device_info, device); + event_exit(); + return false; } - default: - logger(DEBUG_ALWAYS, LOG_ERR, "Invalid value for state variable in " __FILE__); - abort(); + if(connect(write_fd, (const struct sockaddr *)&request.sock, sizeof(request.sock)) < 0) { + logger(DEBUG_ALWAYS, LOG_ERR, "Could not bind write %s: %s", device_info, strerror(errno)); + event_exit(); + return false; + } + + write(request_fd, &data_sun, sizeof(data_sun)); + device_fd = data_fd; + + logger(DEBUG_ALWAYS, LOG_INFO, "Connection with UML established"); + + state = 2; + return false; + } + + case 2: { + if((inlen = read(data_fd, DATA(packet), MTU)) <= 0) { + logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info, + device, strerror(errno)); + event_exit(); + return false; + } + + packet->len = inlen; + + logger(DEBUG_TRAFFIC, LOG_DEBUG, "Read packet of %d bytes from %s", packet->len, + device_info); + + return true; + } + + default: + logger(DEBUG_ALWAYS, LOG_ERR, "Invalid value for state variable in " __FILE__); + abort(); } } static bool write_packet(vpn_packet_t *packet) { if(state != 2) { logger(DEBUG_TRAFFIC, LOG_DEBUG, "Dropping packet of %d bytes to %s: not connected to UML yet", - packet->len, device_info); + packet->len, device_info); return false; } logger(DEBUG_TRAFFIC, LOG_DEBUG, "Writing packet of %d bytes to %s", - packet->len, device_info); + packet->len, device_info); if(write(write_fd, DATA(packet), packet->len) < 0) { if(errno != EINTR && errno != EAGAIN) { diff --git a/src/upnp.c b/src/upnp.c index 3bfc770..5e41d1b 100644 --- a/src/upnp.c +++ b/src/upnp.c @@ -61,7 +61,7 @@ static struct UPNPDev *upnp_discover(int delay, int *error) { #else -#if MINIUPNPC_API_VERSION > 15 +#if MINIUPNPC_API_VERSION > 17 #warning "The version of libminiupnpc you're building against seems to be too recent. Expect trouble." #endif @@ -75,24 +75,28 @@ static void upnp_add_mapping(struct UPNPUrls *urls, struct IGDdatas *data, const // Note that we can't simply use listen_socket[].sa because this won't have the port // if we're running with Port=0 (dynamically assigned port). sockaddr_t sa; - socklen_t salen = sizeof sa; - if (getsockname(socket, &sa.sa, &salen)) { + socklen_t salen = sizeof(sa); + + if(getsockname(socket, &sa.sa, &salen)) { logger(DEBUG_PROTOCOL, LOG_ERR, "[upnp] Unable to get socket address: [%d] %s", sockerrno, sockstrerror(sockerrno)); return; } + char *port; sockaddr2str(&sa, NULL, &port); - if (!port) { + + if(!port) { logger(DEBUG_PROTOCOL, LOG_ERR, "[upnp] Unable to get socket port"); return; } // Use a lease twice as long as the refresh period so that the mapping won't expire before we refresh. char lease_duration[16]; - snprintf(lease_duration, sizeof lease_duration, "%d", upnp_refresh_period * 2); + snprintf(lease_duration, sizeof(lease_duration), "%d", upnp_refresh_period * 2); int error = UPNP_AddPortMapping(urls->controlURL, data->first.servicetype, port, port, myaddr, identname, proto, NULL, lease_duration); - if (error == 0) { + + if(error == 0) { logger(DEBUG_PROTOCOL, LOG_INFO, "[upnp] Successfully set port mapping (%s:%s %s for %s seconds)", myaddr, port, proto, lease_duration); } else { logger(DEBUG_PROTOCOL, LOG_ERR, "[upnp] Failed to set port mapping (%s:%s %s for %s seconds): [%d] %s", myaddr, port, proto, lease_duration, error, strupnperror(error)); @@ -106,26 +110,37 @@ static void upnp_refresh() { int error; struct UPNPDev *devices = upnp_discover(upnp_discover_wait * 1000, &error); - if (!devices) { + + if(!devices) { logger(DEBUG_PROTOCOL, LOG_WARNING, "[upnp] Unable to find IGD devices: [%d] %s", error, strupnperror(error)); freeUPNPDevlist(devices); return; } struct UPNPUrls urls; + struct IGDdatas data; + char myaddr[64]; - int result = UPNP_GetValidIGD(devices, &urls, &data, myaddr, sizeof myaddr); - if (result <= 0) { + + int result = UPNP_GetValidIGD(devices, &urls, &data, myaddr, sizeof(myaddr)); + + if(result <= 0) { logger(DEBUG_PROTOCOL, LOG_WARNING, "[upnp] No IGD found"); freeUPNPDevlist(devices); return; } + logger(DEBUG_PROTOCOL, LOG_INFO, "[upnp] IGD found: [%d] %s (local address: %s, service type: %s)", result, urls.controlURL, myaddr, data.first.servicetype); - for (int i = 0; i < listen_sockets; i++) { - if (upnp_tcp) upnp_add_mapping(&urls, &data, myaddr, listen_socket[i].tcp.fd, "TCP"); - if (upnp_udp) upnp_add_mapping(&urls, &data, myaddr, listen_socket[i].udp.fd, "UDP"); + for(int i = 0; i < listen_sockets; i++) { + if(upnp_tcp) { + upnp_add_mapping(&urls, &data, myaddr, listen_socket[i].tcp.fd, "TCP"); + } + + if(upnp_udp) { + upnp_add_mapping(&urls, &data, myaddr, listen_socket[i].udp.fd, "UDP"); + } } FreeUPNPUrls(&urls); @@ -133,14 +148,19 @@ static void upnp_refresh() { } static void *upnp_thread(void *data) { - while (true) { + (void)data; + + while(true) { time_t start = time(NULL); upnp_refresh(); // Make sure we'll stick to the refresh period no matter how long upnp_refresh() takes. time_t refresh_time = start + upnp_refresh_period; time_t now = time(NULL); - if (now < refresh_time) sleep(refresh_time - now); + + if(now < refresh_time) { + sleep(refresh_time - now); + } } // TODO: we don't have a clean thread shutdown procedure, so we can't remove the mapping. @@ -158,7 +178,8 @@ void upnp_init(bool tcp, bool udp) { pthread_t thread; int error = pthread_create(&thread, NULL, upnp_thread, NULL); - if (error) { + + if(error) { logger(DEBUG_ALWAYS, LOG_ERR, "Unable to start UPnP-IGD client thread: [%d] %s", error, strerror(error)); } } diff --git a/src/upnp.h b/src/upnp.h index dd0531b..b611bc1 100644 --- a/src/upnp.h +++ b/src/upnp.h @@ -1,3 +1,6 @@ +#ifndef TINC_UPNP_H +#define TINC_UPNP_H + /* upnp.h -- UPnP-IGD client Copyright (C) 2015 Guus Sliepen @@ -17,11 +20,8 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#ifndef __UPNP_H__ -#define __UPNP_H__ - #include "system.h" -extern void upnp_init(bool, bool); +extern void upnp_init(bool tcp, bool udp); #endif diff --git a/src/utils.c b/src/utils.c index fadfd05..857d47e 100644 --- a/src/utils.c +++ b/src/utils.c @@ -28,69 +28,84 @@ static const char base64_original[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmno static const char base64_urlsafe[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"; static const char base64_decode[256] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, 62, -1, 63, - 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, - -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, 63, - -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, - 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -}; + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, 62, -1, 63, + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, + -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, 63, + -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + }; static int charhex2bin(char c) { - if(isdigit(c)) + if(isdigit(c)) { return c - '0'; - else + } else { return toupper(c) - 'A' + 10; + } } -int hex2bin(const char *src, void *vdst, int length) { +size_t hex2bin(const char *src, void *vdst, size_t length) { char *dst = vdst; - int i; - for(i = 0; i < length && isxdigit(src[i * 2]) && isxdigit(src[i * 2 + 1]); i++) + size_t i; + + for(i = 0; i < length && isxdigit(src[i * 2]) && isxdigit(src[i * 2 + 1]); i++) { dst[i] = charhex2bin(src[i * 2]) * 16 + charhex2bin(src[i * 2 + 1]); + } + return i; } -int bin2hex(const void *vsrc, char *dst, int length) { +size_t bin2hex(const void *vsrc, char *dst, size_t length) { const char *src = vsrc; - for(int i = length - 1; i >= 0; i--) { + + for(size_t i = length; i-- > 0;) { dst[i * 2 + 1] = hexadecimals[(unsigned char) src[i] & 15]; dst[i * 2] = hexadecimals[(unsigned char) src[i] >> 4]; } + dst[length * 2] = 0; return length * 2; } -int b64decode(const char *src, void *dst, int length) { - int i; +size_t b64decode(const char *src, void *dst, size_t length) { + size_t i; uint32_t triplet = 0; unsigned char *udst = (unsigned char *)dst; for(i = 0; i < length && src[i]; i++) { triplet |= base64_decode[src[i] & 0xff] << (6 * (i & 3)); + if((i & 3) == 3) { - if(triplet & 0xff000000U) + if(triplet & 0xff000000U) { return 0; - udst[0] = triplet & 0xff; triplet >>= 8; - udst[1] = triplet & 0xff; triplet >>= 8; + } + + udst[0] = triplet & 0xff; + triplet >>= 8; + udst[1] = triplet & 0xff; + triplet >>= 8; udst[2] = triplet; triplet = 0; udst += 3; } } - if(triplet & 0xff000000U) + + if(triplet & 0xff000000U) { return 0; + } + if((i & 3) == 3) { - udst[0] = triplet & 0xff; triplet >>= 8; + udst[0] = triplet & 0xff; + triplet >>= 8; udst[1] = triplet & 0xff; return i / 4 * 3 + 2; } else if((i & 3) == 2) { @@ -101,52 +116,60 @@ int b64decode(const char *src, void *dst, int length) { } } -static int b64encode_internal(const void *src, char *dst, int length, const char *alphabet) { +static size_t b64encode_internal(const void *src, char *dst, size_t length, const char *alphabet) { uint32_t triplet; const unsigned char *usrc = (unsigned char *)src; - int si = length / 3 * 3; - int di = length / 3 * 4; + size_t si = length / 3 * 3; + size_t di = length / 3 * 4; switch(length % 3) { - case 2: - triplet = usrc[si] | usrc[si + 1] << 8; - dst[di] = alphabet[triplet & 63]; triplet >>= 6; - dst[di + 1] = alphabet[triplet & 63]; triplet >>= 6; - dst[di + 2] = alphabet[triplet]; - dst[di + 3] = 0; - length = di + 3; - break; - case 1: - triplet = usrc[si]; - dst[di] = alphabet[triplet & 63]; triplet >>= 6; - dst[di + 1] = alphabet[triplet]; - dst[di + 2] = 0; - length = di + 2; - break; - default: - dst[di] = 0; - length = di; - break; + case 2: + triplet = usrc[si] | usrc[si + 1] << 8; + dst[di] = alphabet[triplet & 63]; + triplet >>= 6; + dst[di + 1] = alphabet[triplet & 63]; + triplet >>= 6; + dst[di + 2] = alphabet[triplet]; + dst[di + 3] = 0; + length = di + 3; + break; + + case 1: + triplet = usrc[si]; + dst[di] = alphabet[triplet & 63]; + triplet >>= 6; + dst[di + 1] = alphabet[triplet]; + dst[di + 2] = 0; + length = di + 2; + break; + + default: + dst[di] = 0; + length = di; + break; } while(si > 0) { di -= 4; si -= 3; triplet = usrc[si] | usrc[si + 1] << 8 | usrc[si + 2] << 16; - dst[di] = alphabet[triplet & 63]; triplet >>= 6; - dst[di + 1] = alphabet[triplet & 63]; triplet >>= 6; - dst[di + 2] = alphabet[triplet & 63]; triplet >>= 6; + dst[di] = alphabet[triplet & 63]; + triplet >>= 6; + dst[di + 1] = alphabet[triplet & 63]; + triplet >>= 6; + dst[di + 2] = alphabet[triplet & 63]; + triplet >>= 6; dst[di + 3] = alphabet[triplet]; } return length; } -int b64encode(const void *src, char *dst, int length) { +size_t b64encode(const void *src, char *dst, size_t length) { return b64encode_internal(src, dst, length, base64_original); } -int b64encode_urlsafe(const void *src, char *dst, int length) { +size_t b64encode_urlsafe(const void *src, char *dst, size_t length) { return b64encode_internal(src, dst, length, base64_urlsafe); } @@ -158,15 +181,16 @@ int b64encode_urlsafe(const void *src, char *dst, int length) { const char *winerror(int err) { static char buf[1024], *ptr; - ptr = buf + snprintf(buf, sizeof buf, "(%d) ", err); + ptr = buf + snprintf(buf, sizeof(buf), "(%d) ", err); - if (!FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), ptr, sizeof(buf) - (ptr - buf), NULL)) { + if(!FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), ptr, sizeof(buf) - (ptr - buf), NULL)) { strncpy(buf, "(unable to format errormessage)", sizeof(buf)); }; - if((ptr = strchr(buf, '\r'))) + if((ptr = strchr(buf, '\r'))) { *ptr = '\0'; + } return buf; } @@ -174,34 +198,45 @@ const char *winerror(int err) { unsigned int bitfield_to_int(const void *bitfield, size_t size) { unsigned int value = 0; - if(size > sizeof value) - size = sizeof value; + + if(size > sizeof(value)) { + size = sizeof(value); + } + memcpy(&value, bitfield, size); return value; } bool check_id(const char *id) { - if(!id || !*id) + if(!id || !*id) { return false; + } for(; *id; id++) - if(!isalnum(*id) && *id != '_') + if(!isalnum(*id) && *id != '_') { return false; + } return true; } bool check_netname(const char *netname, bool strict) { - if(!netname || !*netname || *netname == '.') + if(!netname || !*netname || *netname == '.') { return false; + } for(const char *c = netname; *c; c++) { - if(iscntrl(*c)) + if(iscntrl(*c)) { return false; - if(*c == '/' || *c == '\\') + } + + if(*c == '/' || *c == '\\') { return false; - if(strict && strchr(" $%<>:`\"|?*", *c)) + } + + if(strict && strchr(" $%<>:`\"|?*", *c)) { return false; + } } return true; @@ -215,30 +250,36 @@ bool check_netname(const char *netname, bool strict) { char *replace_name(const char *name) { char *ret_name; - if (name[0] == '$') { + if(name[0] == '$') { char *envname = getenv(name + 1); - char hostname[HOST_NAME_MAX+1]; - if (!envname) { - if (strcmp(name + 1, "HOST")) { + char hostname[HOST_NAME_MAX + 1]; + + if(!envname) { + if(strcmp(name + 1, "HOST")) { logger(DEBUG_ALWAYS, LOG_ERR, "Invalid Name: environment variable %s does not exist\n", name + 1); return NULL; } - if (gethostname(hostname, sizeof hostname) || !*hostname) { + + if(gethostname(hostname, sizeof(hostname)) || !*hostname) { logger(DEBUG_ALWAYS, LOG_ERR, "Could not get hostname: %s\n", sockstrerror(sockerrno)); return NULL; } + hostname[HOST_NAME_MAX] = 0; envname = hostname; } + ret_name = xstrdup(envname); - for (char *c = ret_name; *c; c++) - if (!isalnum(*c)) + + for(char *c = ret_name; *c; c++) + if(!isalnum(*c)) { *c = '_'; + } } else { ret_name = xstrdup(name); } - if (!check_id(ret_name)) { + if(!check_id(ret_name)) { logger(DEBUG_ALWAYS, LOG_ERR, "Invalid name for myself!"); free(ret_name); return NULL; diff --git a/src/utils.h b/src/utils.h index 5c387bd..4285150 100644 --- a/src/utils.h +++ b/src/utils.h @@ -1,3 +1,6 @@ +#ifndef TINC_UTILS_H +#define TINC_UTILS_H + /* utils.h -- header file for utils.c Copyright (C) 1999-2005 Ivo Timmermans @@ -18,15 +21,12 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#ifndef __TINC_UTILS_H__ -#define __TINC_UTILS_H__ +extern size_t hex2bin(const char *src, void *dst, size_t length); +extern size_t bin2hex(const void *src, char *dst, size_t length); -extern int hex2bin(const char *src, void *dst, int length); -extern int bin2hex(const void *src, char *dst, int length); - -extern int b64encode(const void *src, char *dst, int length); -extern int b64encode_urlsafe(const void *src, char *dst, int length); -extern int b64decode(const char *src, void *dst, int length); +extern size_t b64encode(const void *src, char *dst, size_t length); +extern size_t b64encode_urlsafe(const void *src, char *dst, size_t length); +extern size_t b64decode(const char *src, void *dst, size_t length); #ifdef HAVE_MINGW extern const char *winerror(int); @@ -50,8 +50,8 @@ extern const char *winerror(int); extern unsigned int bitfield_to_int(const void *bitfield, size_t size); -extern bool check_id(const char *); -extern bool check_netname(const char *, bool strict); +extern bool check_id(const char *id); +extern bool check_netname(const char *netname, bool strict); char *replace_name(const char *name); -#endif /* __TINC_UTILS_H__ */ +#endif diff --git a/src/vde_device.c b/src/vde_device.c index 73ad713..0170af3 100644 --- a/src/vde_device.c +++ b/src/vde_device.c @@ -34,7 +34,7 @@ static struct vdepluglib plug; static struct vdeconn *conn = NULL; static int port = 0; static char *group = NULL; -static char *device_info; +static const char *device_info = "VDE socket"; static bool setup_device(void) { libvdeplug_dynopen(plug); @@ -44,8 +44,9 @@ static bool setup_device(void) { return false; } - if(!get_config_string(lookup_config(config_tree, "Device"), &device)) - xasprintf(&device, LOCALSTATEDIR "/run/vde.ctl"); + if(!get_config_string(lookup_config(config_tree, "Device"), &device)) { + xasprintf(&device, RUNSTATEDIR "/vde.ctl"); + } get_config_string(lookup_config(config_tree, "Interface"), &iface); @@ -53,8 +54,6 @@ static bool setup_device(void) { get_config_string(lookup_config(config_tree, "VDEGroup"), &group); - device_info = "VDE socket"; - struct vde_open_args args = { .port = port, .group = group, @@ -62,6 +61,7 @@ static bool setup_device(void) { }; conn = plug.vde_open(device, identname, &args); + if(!conn) { logger(DEBUG_ALWAYS, LOG_ERR, "Could not open VDE socket %s", device); return false; @@ -75,29 +75,35 @@ static bool setup_device(void) { logger(DEBUG_ALWAYS, LOG_INFO, "%s is a %s", device, device_info); - if(routing_mode == RMODE_ROUTER) + if(routing_mode == RMODE_ROUTER) { overwrite_mac = true; + } return true; } static void close_device(void) { if(conn) { - plug.vde_close(conn); conn = NULL; + plug.vde_close(conn); + conn = NULL; } - if(plug.dl_handle) + if(plug.dl_handle) { libvdeplug_dynclose(plug); + } - free(device); device = NULL; + free(device); + device = NULL; - free(iface); iface = NULL; + free(iface); + iface = NULL; device_info = NULL; } static bool read_packet(vpn_packet_t *packet) { int lenin = (ssize_t)plug.vde_recv(conn, DATA(packet), MTU, 0); + if(lenin <= 0) { logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info, device, strerror(errno)); event_exit(); diff --git a/src/version.c b/src/version.c index 325a6f0..d0af1cc 100644 --- a/src/version.c +++ b/src/version.c @@ -1,5 +1,5 @@ /* - version.c -- version information + version.c -- version information Copyright (C) 2014 Etienne Dechamps This program is free software; you can redistribute it and/or modify @@ -22,10 +22,10 @@ #include "../config.h" /* This file is always rebuilt (even if there are no changes) so that the following is updated */ -const char* const BUILD_DATE = __DATE__; -const char* const BUILD_TIME = __TIME__; +const char *const BUILD_DATE = __DATE__; +const char *const BUILD_TIME = __TIME__; #ifdef GIT_DESCRIPTION -const char* const BUILD_VERSION = GIT_DESCRIPTION; +const char *const BUILD_VERSION = GIT_DESCRIPTION; #else -const char* const BUILD_VERSION = VERSION; +const char *const BUILD_VERSION = VERSION; #endif diff --git a/src/version.h b/src/version.h index 9cbecb6..a4cf0a7 100644 --- a/src/version.h +++ b/src/version.h @@ -1,3 +1,6 @@ +#ifndef TINC_VERSION_H +#define TINC_VERSION_H + /* version.h -- header for version.c Copyright (C) 2014 Etienne Dechamps @@ -17,11 +20,8 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#ifndef __TINC_VERSION_H__ -#define __TINC_VERSION_H__ +extern const char *const BUILD_DATE; +extern const char *const BUILD_TIME; +extern const char *const BUILD_VERSION; -extern const char* const BUILD_DATE; -extern const char* const BUILD_TIME; -extern const char* const BUILD_VERSION; - -#endif /* __TINC_VERSION_H__ */ +#endif diff --git a/src/xalloc.h b/src/xalloc.h index 28960fb..d9877a8 100644 --- a/src/xalloc.h +++ b/src/xalloc.h @@ -1,5 +1,8 @@ +#ifndef TINC_XALLOC_H +#define TINC_XALLOC_H + /* - xalloc.h -- malloc and related fuctions with out of memory checking + xalloc.h -- malloc and related functions with out of memory checking Copyright (C) 1990, 91, 92, 93, 94, 95, 96, 97 Free Software Foundation, Inc. Copyright (C) 2011-2013 Guus Sliepen @@ -15,58 +18,74 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., Foundation, - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ -#ifndef __TINC_XALLOC_H__ -#define __TINC_XALLOC_H__ - -static inline void *xmalloc(size_t n) __attribute__ ((__malloc__)); +static inline void *xmalloc(size_t n) __attribute__((__malloc__)); static inline void *xmalloc(size_t n) { void *p = malloc(n); - if(!p) + + if(!p) { abort(); + } + return p; } -static inline void *xzalloc(size_t n) __attribute__ ((__malloc__)); +static inline void *xzalloc(size_t n) __attribute__((__malloc__)); static inline void *xzalloc(size_t n) { void *p = calloc(1, n); - if(!p) + + if(!p) { abort(); + } + return p; } static inline void *xrealloc(void *p, size_t n) { p = realloc(p, n); - if(!p) + + if(!p) { abort(); + } + return p; } -static inline char *xstrdup(const char *s) __attribute__ ((__malloc__)); +static inline char *xstrdup(const char *s) __attribute__((__malloc__, __nonnull__)); static inline char *xstrdup(const char *s) { char *p = strdup(s); - if(!p) + + if(!p) { abort(); + } + return p; } static inline int xvasprintf(char **strp, const char *fmt, va_list ap) { #ifdef HAVE_MINGW char buf[1024]; - int result = vsnprintf(buf, sizeof buf, fmt, ap); - if(result < 0) + int result = vsnprintf(buf, sizeof(buf), fmt, ap); + + if(result < 0) { abort(); + } + *strp = xstrdup(buf); #else int result = vasprintf(strp, fmt, ap); - if(result < 0) + + if(result < 0) { abort(); + } + #endif return result; } -static inline int xasprintf(char **strp, const char *fmt, ...) __attribute__ ((__format__(printf, 2, 3))); +static inline int xasprintf(char **strp, const char *fmt, ...) __attribute__((__format__(printf, 2, 3))); static inline int xasprintf(char **strp, const char *fmt, ...) { va_list ap; va_start(ap, fmt); diff --git a/systemd/Makefile.am b/systemd/Makefile.am index a1bfe12..dac2b73 100644 --- a/systemd/Makefile.am +++ b/systemd/Makefile.am @@ -1,4 +1,18 @@ +EXTRA_DIST = tinc.service.in tinc@.service.in + +CLEANFILES = tinc.service tinc@.service + if WITH_SYSTEMD systemddir = @systemd_path@ -dist_systemd_DATA = tinc.service tinc@.service +nodist_systemd_DATA = tinc.service tinc@.service endif + +substitute = sed \ + -e s,'@sbindir\@',"$(sbindir)",g \ + -e s,'@sysconfdir\@',"$(sysconfdir)",g + +tinc.service: $(srcdir)/tinc.service.in + $(AM_V_GEN)$(substitute) $(srcdir)/tinc.service.in > $@ + +tinc@.service: $(srcdir)/tinc@.service.in + $(AM_V_GEN)$(substitute) $(srcdir)/tinc@.service.in > $@ diff --git a/systemd/Makefile.in b/systemd/Makefile.in index f66a54e..ef4ed4e 100644 --- a/systemd/Makefile.in +++ b/systemd/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15.1 from Makefile.am. +# Makefile.in generated by automake 1.16.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2017 Free Software Foundation, Inc. +# Copyright (C) 1994-2018 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -95,6 +95,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \ $(top_srcdir)/m4/ax_cflags_warn_all.m4 \ $(top_srcdir)/m4/ax_check_compile_flag.m4 \ $(top_srcdir)/m4/ax_check_link_flag.m4 \ + $(top_srcdir)/m4/ax_code_coverage.m4 \ $(top_srcdir)/m4/ax_require_defined.m4 \ $(top_srcdir)/m4/curses.m4 $(top_srcdir)/m4/libgcrypt.m4 \ $(top_srcdir)/m4/lzo.m4 $(top_srcdir)/m4/miniupnpc.m4 \ @@ -102,8 +103,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \ $(top_srcdir)/m4/zlib.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) -DIST_COMMON = $(srcdir)/Makefile.am $(am__dist_systemd_DATA_DIST) \ - $(am__DIST_COMMON) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = @@ -127,7 +127,6 @@ am__can_run_installinfo = \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac -am__dist_systemd_DATA_DIST = tinc.service tinc@.service am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ @@ -156,7 +155,7 @@ am__uninstall_files_from_dir = { \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(systemddir)" -DATA = $(dist_systemd_DATA) +DATA = $(nodist_systemd_DATA) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) @@ -170,6 +169,12 @@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ +CODE_COVERAGE_CFLAGS = @CODE_COVERAGE_CFLAGS@ +CODE_COVERAGE_CPPFLAGS = @CODE_COVERAGE_CPPFLAGS@ +CODE_COVERAGE_CXXFLAGS = @CODE_COVERAGE_CXXFLAGS@ +CODE_COVERAGE_ENABLED = @CODE_COVERAGE_ENABLED@ +CODE_COVERAGE_LDFLAGS = @CODE_COVERAGE_LDFLAGS@ +CODE_COVERAGE_LIBS = @CODE_COVERAGE_LIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CURSES_LIBS = @CURSES_LIBS@ @@ -181,16 +186,18 @@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ +GCOV = @GCOV@ +GENHTML = @GENHTML@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LCOV = @LCOV@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ -LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MINIUPNPC_LIBS = @MINIUPNPC_LIBS@ @@ -205,6 +212,7 @@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ READLINE_LIBS = @READLINE_LIBS@ +SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ @@ -261,8 +269,14 @@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ +EXTRA_DIST = tinc.service.in tinc@.service.in +CLEANFILES = tinc.service tinc@.service @WITH_SYSTEMD_TRUE@systemddir = @systemd_path@ -@WITH_SYSTEMD_TRUE@dist_systemd_DATA = tinc.service tinc@.service +@WITH_SYSTEMD_TRUE@nodist_systemd_DATA = tinc.service tinc@.service +substitute = sed \ + -e s,'@sbindir\@',"$(sbindir)",g \ + -e s,'@sysconfdir\@',"$(sysconfdir)",g + all: all-am .SUFFIXES: @@ -283,8 +297,8 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) @@ -295,9 +309,9 @@ $(top_srcdir)/configure: $(am__configure_deps) $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): -install-dist_systemdDATA: $(dist_systemd_DATA) +install-nodist_systemdDATA: $(nodist_systemd_DATA) @$(NORMAL_INSTALL) - @list='$(dist_systemd_DATA)'; test -n "$(systemddir)" || list=; \ + @list='$(nodist_systemd_DATA)'; test -n "$(systemddir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(systemddir)'"; \ $(MKDIR_P) "$(DESTDIR)$(systemddir)" || exit 1; \ @@ -311,9 +325,9 @@ install-dist_systemdDATA: $(dist_systemd_DATA) $(INSTALL_DATA) $$files "$(DESTDIR)$(systemddir)" || exit $$?; \ done -uninstall-dist_systemdDATA: +uninstall-nodist_systemdDATA: @$(NORMAL_UNINSTALL) - @list='$(dist_systemd_DATA)'; test -n "$(systemddir)" || list=; \ + @list='$(nodist_systemd_DATA)'; test -n "$(systemddir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(systemddir)'; $(am__uninstall_files_from_dir) tags TAGS: @@ -323,7 +337,10 @@ ctags CTAGS: cscope cscopelist: -distdir: $(DISTFILES) +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ @@ -382,6 +399,7 @@ install-strip: mostlyclean-generic: clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) @@ -410,7 +428,7 @@ info: info-am info-am: -install-data-am: install-dist_systemdDATA +install-data-am: install-nodist_systemdDATA install-dvi: install-dvi-am @@ -454,25 +472,31 @@ ps: ps-am ps-am: -uninstall-am: uninstall-dist_systemdDATA +uninstall-am: uninstall-nodist_systemdDATA .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic cscopelist-am \ ctags-am distclean distclean-generic distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ - install-data-am install-dist_systemdDATA install-dvi \ - install-dvi-am install-exec install-exec-am install-html \ - install-html-am install-info install-info-am install-man \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-nodist_systemdDATA \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic pdf pdf-am ps ps-am tags-am uninstall \ - uninstall-am uninstall-dist_systemdDATA + uninstall-am uninstall-nodist_systemdDATA .PRECIOUS: Makefile +tinc.service: $(srcdir)/tinc.service.in + $(AM_V_GEN)$(substitute) $(srcdir)/tinc.service.in > $@ + +tinc@.service: $(srcdir)/tinc@.service.in + $(AM_V_GEN)$(substitute) $(srcdir)/tinc@.service.in > $@ + # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: diff --git a/systemd/tinc.service b/systemd/tinc.service.in similarity index 92% rename from systemd/tinc.service rename to systemd/tinc.service.in index d911fa7..b671042 100644 --- a/systemd/tinc.service +++ b/systemd/tinc.service.in @@ -14,7 +14,7 @@ Type=oneshot RemainAfterExit=yes ExecStart=/bin/true ExecReload=/bin/true -WorkingDirectory=/etc/tinc +WorkingDirectory=@sysconfdir@/tinc [Install] WantedBy=multi-user.target diff --git a/systemd/tinc@.service b/systemd/tinc@.service.in similarity index 73% rename from systemd/tinc@.service rename to systemd/tinc@.service.in index d1f711d..2d695ca 100644 --- a/systemd/tinc@.service +++ b/systemd/tinc@.service.in @@ -8,9 +8,9 @@ ReloadPropagatedFrom=tinc.service [Service] Type=simple -WorkingDirectory=/etc/tinc/%i -ExecStart=/usr/sbin/tincd -n %i -D -ExecReload=/usr/sbin/tinc -n %i reload +WorkingDirectory=@sysconfdir@/tinc/%i +ExecStart=@sbindir@/tincd -n %i -D +ExecReload=@sbindir@/tinc -n %i reload KillMode=mixed Restart=on-failure RestartSec=5 diff --git a/test-driver b/test-driver index 8e575b0..b8521a4 100755 --- a/test-driver +++ b/test-driver @@ -1,9 +1,9 @@ #! /bin/sh # test-driver - basic testsuite driver script. -scriptversion=2013-07-13.22; # UTC +scriptversion=2018-03-07.03; # UTC -# Copyright (C) 2011-2014 Free Software Foundation, Inc. +# Copyright (C) 2011-2018 Free Software Foundation, Inc. # # 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 @@ -16,7 +16,7 @@ scriptversion=2013-07-13.22; # UTC # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with this program. If not, see . +# along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a @@ -140,9 +140,9 @@ echo ":copy-in-global-log: $gcopy" >> $trs_file # Local Variables: # mode: shell-script # sh-indentation: 2 -# eval: (add-hook 'write-file-hooks 'time-stamp) +# eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" -# time-stamp-time-zone: "UTC" +# time-stamp-time-zone: "UTC0" # time-stamp-end: "; # UTC" # End: diff --git a/test/Makefile.am b/test/Makefile.am index 98f4a3b..32b2e30 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -6,9 +6,10 @@ TESTS = \ invite-join.test \ invite-offline.test \ invite-tinc-up.test \ + legacy-protocol.test \ ns-ping.test \ - ping.test \ scripts.test \ + security.test \ sptps-basic.test \ variables.test @@ -16,12 +17,14 @@ dist_check_SCRIPTS = $(TESTS) EXTRA_DIST = testlib.sh -check_PROGRAMS = pong +AM_CFLAGS = -iquote. -pong_SOURCES = pong.c +check_PROGRAMS = \ + splice + +splice_SOURCES = splice.c clean-local: -for pid in *.test.?/pid; do ../src/tinc --pidfile="$$pid" stop; done -killall ../src/sptps_test - -killall pong -rm -rf *.test.? diff --git a/test/Makefile.in b/test/Makefile.in index e5aadf2..a5f0487 100644 --- a/test/Makefile.in +++ b/test/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15.1 from Makefile.am. +# Makefile.in generated by automake 1.16.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2017 Free Software Foundation, Inc. +# Copyright (C) 1994-2018 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -87,7 +87,7 @@ PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ -check_PROGRAMS = pong$(EXEEXT) +check_PROGRAMS = splice$(EXEEXT) subdir = test ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \ @@ -95,6 +95,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \ $(top_srcdir)/m4/ax_cflags_warn_all.m4 \ $(top_srcdir)/m4/ax_check_compile_flag.m4 \ $(top_srcdir)/m4/ax_check_link_flag.m4 \ + $(top_srcdir)/m4/ax_code_coverage.m4 \ $(top_srcdir)/m4/ax_require_defined.m4 \ $(top_srcdir)/m4/curses.m4 $(top_srcdir)/m4/libgcrypt.m4 \ $(top_srcdir)/m4/lzo.m4 $(top_srcdir)/m4/miniupnpc.m4 \ @@ -108,9 +109,9 @@ mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = -am_pong_OBJECTS = pong.$(OBJEXT) -pong_OBJECTS = $(am_pong_OBJECTS) -pong_LDADD = $(LDADD) +am_splice_OBJECTS = splice.$(OBJEXT) +splice_OBJECTS = $(am_splice_OBJECTS) +splice_LDADD = $(LDADD) AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false @@ -125,7 +126,8 @@ am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = depcomp = $(SHELL) $(top_srcdir)/depcomp -am__depfiles_maybe = depfiles +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/splice.Po am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) @@ -139,8 +141,8 @@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = -SOURCES = $(pong_SOURCES) -DIST_SOURCES = $(pong_SOURCES) +SOURCES = $(splice_SOURCES) +DIST_SOURCES = $(splice_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ @@ -380,6 +382,12 @@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ +CODE_COVERAGE_CFLAGS = @CODE_COVERAGE_CFLAGS@ +CODE_COVERAGE_CPPFLAGS = @CODE_COVERAGE_CPPFLAGS@ +CODE_COVERAGE_CXXFLAGS = @CODE_COVERAGE_CXXFLAGS@ +CODE_COVERAGE_ENABLED = @CODE_COVERAGE_ENABLED@ +CODE_COVERAGE_LDFLAGS = @CODE_COVERAGE_LDFLAGS@ +CODE_COVERAGE_LIBS = @CODE_COVERAGE_LIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CURSES_LIBS = @CURSES_LIBS@ @@ -391,16 +399,18 @@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ +GCOV = @GCOV@ +GENHTML = @GENHTML@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LCOV = @LCOV@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ -LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MINIUPNPC_LIBS = @MINIUPNPC_LIBS@ @@ -415,6 +425,7 @@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ READLINE_LIBS = @READLINE_LIBS@ +SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ @@ -479,15 +490,17 @@ TESTS = \ invite-join.test \ invite-offline.test \ invite-tinc-up.test \ + legacy-protocol.test \ ns-ping.test \ - ping.test \ scripts.test \ + security.test \ sptps-basic.test \ variables.test dist_check_SCRIPTS = $(TESTS) EXTRA_DIST = testlib.sh -pong_SOURCES = pong.c +AM_CFLAGS = -iquote. +splice_SOURCES = splice.c all: all-am .SUFFIXES: @@ -509,8 +522,8 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) @@ -525,9 +538,9 @@ $(am__aclocal_m4_deps): clean-checkPROGRAMS: -test -z "$(check_PROGRAMS)" || rm -f $(check_PROGRAMS) -pong$(EXEEXT): $(pong_OBJECTS) $(pong_DEPENDENCIES) $(EXTRA_pong_DEPENDENCIES) - @rm -f pong$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(pong_OBJECTS) $(pong_LDADD) $(LIBS) +splice$(EXEEXT): $(splice_OBJECTS) $(splice_DEPENDENCIES) $(EXTRA_splice_DEPENDENCIES) + @rm -f splice$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(splice_OBJECTS) $(splice_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) @@ -535,7 +548,13 @@ mostlyclean-compile: distclean-compile: -rm -f *.tab.c -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pong.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/splice.Po@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @@ -725,7 +744,7 @@ $(TEST_SUITE_LOG): $(TEST_LOGS) fi; \ $$success || exit 1 -check-TESTS: +check-TESTS: $(check_PROGRAMS) $(dist_check_SCRIPTS) @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) @@ -761,7 +780,10 @@ recheck: all $(check_PROGRAMS) $(dist_check_SCRIPTS) @am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ @am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT) -distdir: $(DISTFILES) +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ @@ -836,7 +858,7 @@ clean: clean-am clean-am: clean-checkPROGRAMS clean-generic clean-local mostlyclean-am distclean: distclean-am - -rm -rf ./$(DEPDIR) + -rm -f ./$(DEPDIR)/splice.Po -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags @@ -882,7 +904,7 @@ install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am - -rm -rf ./$(DEPDIR) + -rm -f ./$(DEPDIR)/splice.Po -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic @@ -902,18 +924,19 @@ uninstall-am: .MAKE: check-am install-am install-strip -.PHONY: CTAGS GTAGS TAGS all all-am check check-TESTS check-am clean \ - clean-checkPROGRAMS clean-generic clean-local cscopelist-am \ - ctags ctags-am distclean distclean-compile distclean-generic \ - distclean-tags distdir dvi dvi-am html html-am info info-am \ - install install-am install-data install-data-am install-dvi \ - install-dvi-am install-exec install-exec-am install-html \ - install-html-am install-info install-info-am install-man \ - install-pdf install-pdf-am install-ps install-ps-am \ - install-strip installcheck installcheck-am installdirs \ - maintainer-clean maintainer-clean-generic mostlyclean \ - mostlyclean-compile mostlyclean-generic pdf pdf-am ps ps-am \ - recheck tags tags-am uninstall uninstall-am +.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-TESTS \ + check-am clean clean-checkPROGRAMS clean-generic clean-local \ + cscopelist-am ctags ctags-am distclean distclean-compile \ + distclean-generic distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic pdf pdf-am ps ps-am recheck tags tags-am \ + uninstall uninstall-am .PRECIOUS: Makefile @@ -921,7 +944,6 @@ uninstall-am: clean-local: -for pid in *.test.?/pid; do ../src/tinc --pidfile="$$pid" stop; done -killall ../src/sptps_test - -killall pong -rm -rf *.test.? # Tell versions [3.59,3.63) of GNU make to not export all variables. diff --git a/test/basic.test b/test/basic.test index b181e75..c377202 100755 --- a/test/basic.test +++ b/test/basic.test @@ -1,6 +1,6 @@ #!/bin/sh -. ./testlib.sh +. "${0%/*}/testlib.sh" # Initialize and test one node diff --git a/test/commandline.test b/test/commandline.test index 157eb54..44d651a 100755 --- a/test/commandline.test +++ b/test/commandline.test @@ -1,6 +1,6 @@ #!/bin/sh -. ./testlib.sh +. "${0%/*}/testlib.sh" # Initialize one node diff --git a/test/executables.test b/test/executables.test index 801de58..0cf9723 100755 --- a/test/executables.test +++ b/test/executables.test @@ -1,6 +1,6 @@ #!/bin/sh -. ./testlib.sh +. "${0%/*}/testlib.sh" # Just test whether the executables work $tincd --help diff --git a/test/import-export.test b/test/import-export.test index 6b5641c..e7bca23 100755 --- a/test/import-export.test +++ b/test/import-export.test @@ -1,6 +1,6 @@ #!/bin/sh -. ./testlib.sh +. "${0%/*}/testlib.sh" # Initialize three nodes diff --git a/test/invite-join.test b/test/invite-join.test index 28de83c..5167320 100755 --- a/test/invite-join.test +++ b/test/invite-join.test @@ -1,6 +1,6 @@ #!/bin/sh -. ./testlib.sh +. "${0%/*}/testlib.sh" # Initialize one node @@ -9,7 +9,6 @@ init foo set DeviceType dummy set Mode switch set Broadcast no -del Port set Address localhost set Port 32751 start $r1 diff --git a/test/invite-offline.test b/test/invite-offline.test index b435493..62bfcb4 100755 --- a/test/invite-offline.test +++ b/test/invite-offline.test @@ -1,6 +1,6 @@ #!/bin/sh -. ./testlib.sh +. "${0%/*}/testlib.sh" # Initialize one node @@ -9,7 +9,6 @@ init foo set DeviceType dummy set Mode switch set Broadcast no -del Port set Address localhost set Port 32758 EOF diff --git a/test/invite-tinc-up.test b/test/invite-tinc-up.test index 8d637b9..26efddf 100755 --- a/test/invite-tinc-up.test +++ b/test/invite-tinc-up.test @@ -1,6 +1,6 @@ #!/bin/sh -. ./testlib.sh +. "${0%/*}/testlib.sh" # Initialize one node diff --git a/test/legacy-protocol.test b/test/legacy-protocol.test new file mode 100755 index 0000000..ce8e614 --- /dev/null +++ b/test/legacy-protocol.test @@ -0,0 +1,79 @@ +#!/bin/sh + +. "${0%/*}/testlib.sh" + +# Initialize two nodes + +$tinc $c1 <$d1/tinc-up < - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include "../src/system.h" - -#include "../src/ethernet.h" - -uint8_t mymac[6] = {6, 5, 5, 6, 5, 5}; - -static ssize_t do_arp(uint8_t *buf, ssize_t len, struct sockaddr_in *in) { - struct ether_arp arp; - memcpy(&arp, buf + 14, sizeof arp); - - // Is it a valid ARP request? - if(ntohs(arp.arp_hrd) != ARPHRD_ETHER || ntohs(arp.arp_pro) != ETH_P_IP || arp.arp_hln != ETH_ALEN || arp.arp_pln != sizeof in->sin_addr.s_addr || ntohs(arp.arp_op) != ARPOP_REQUEST) - return 0; - - // Does it match our address? - if(memcmp(&in->sin_addr.s_addr, arp.arp_tpa, 4)) - return 0; - - // Swap addresses - memcpy(buf, buf + 6, 6); - memcpy(buf + 6, mymac, 6); - - arp.arp_op = htons(ARPOP_REPLY); - memcpy(arp.arp_tpa, arp.arp_spa, sizeof arp.arp_tpa); - memcpy(arp.arp_tha, arp.arp_sha, sizeof arp.arp_tha); - memcpy(arp.arp_spa, &in->sin_addr.s_addr, sizeof in->sin_addr.s_addr); - memcpy(arp.arp_sha, mymac, 6); - - memcpy(buf + 14, &arp, sizeof arp); - - return len; -} - -static ssize_t do_ipv4(uint8_t *buf, ssize_t len, struct sockaddr_in *in) { - struct ip ip; - struct icmp icmp; - - // Does it match our address? - if(memcmp(buf, mymac, 6)) - return 0; - - memcpy(&ip, buf + 14, sizeof ip); - if(memcmp(&ip.ip_dst, &in->sin_addr.s_addr, 4)) - return 0; - - // Is it an ICMP echo request? - if(ip.ip_p != IPPROTO_ICMP) - return 0; - - memcpy(&icmp, buf + 14 + sizeof ip, sizeof icmp); - if(icmp.icmp_type != ICMP_ECHO) - return 0; - - // Return an echo reply - memcpy(buf, buf + 6, 6); - memcpy(buf + 6, mymac, 6); - - ip.ip_dst = ip.ip_src; - memcpy(&ip.ip_src, &in->sin_addr.s_addr, 4); - - icmp.icmp_type = ICMP_ECHOREPLY; - - memcpy(buf + 14, &ip, sizeof ip); - memcpy(buf + 14 + sizeof ip, &icmp, sizeof icmp); - - return len; -} - -static ssize_t do_ipv6(uint8_t *buf, ssize_t len, struct sockaddr_in6 *in) { - return 0; -} - -int main(int argc, char *argv[]) { - if(argc != 4) { - fprintf(stderr, "Usage: %s \n", argv[0]); - return 1; - } - - struct addrinfo hints = {}, *ai = NULL; - hints.ai_socktype = SOCK_DGRAM; - hints.ai_flags = AI_ADDRCONFIG; - - errno = ENOENT; - if(getaddrinfo(argv[1], argv[2], &hints, &ai) || !ai) { - fprintf(stderr, "Could not resolve %s port %s: %s\n", argv[1], argv[2], strerror(errno)); - return 1; - } - - int fd; - fd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); - if(!fd) { - fprintf(stderr, "Could not create socket: %s\n", strerror(errno)); - return 1; - } - - static const int one = 1; - setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void *)&one, sizeof one); - - if(bind(fd, ai->ai_addr, ai->ai_addrlen)) { - fprintf(stderr, "Could not bind socket: %s\n", strerror(errno)); - return 1; - } - - switch(ai->ai_family) { - case AF_INET: { - struct ip_mreq mreq; - struct sockaddr_in in; - memcpy(&in, ai->ai_addr, sizeof in); - mreq.imr_multiaddr.s_addr = in.sin_addr.s_addr; - mreq.imr_interface.s_addr = htonl(INADDR_ANY); - if(setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (void *)&mreq, sizeof mreq)) { - fprintf(stderr, "Cannot join multicast group: %s\n", strerror(errno)); - return 1; - } -#ifdef IP_MULTICAST_LOOP - setsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP, (const void *)&one, sizeof one); -#endif - } break; - -#ifdef IPV6_JOIN_GROUP - case AF_INET6: { - struct ipv6_mreq mreq; - struct sockaddr_in6 in6; - memcpy(&in6, ai->ai_addr, sizeof in6); - memcpy(&mreq.ipv6mr_multiaddr, &in6.sin6_addr, sizeof mreq.ipv6mr_multiaddr); - mreq.ipv6mr_interface = in6.sin6_scope_id; - if(setsockopt(fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, (void *)&mreq, sizeof mreq)) { - fprintf(stderr, "Cannot join multicast group: %s\n", strerror(errno)); - return 1; - } -#ifdef IPV6_MULTICAST_LOOP - setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, (const void *)&one, sizeof one); -#endif - } break; -#endif - - default: - fprintf(stderr, "Multicast for address family %x unsupported\n", ai->ai_family); - return 1; - } - - errno = ENOENT; - struct addrinfo *ai2 = NULL; - if(getaddrinfo(argv[3], NULL, &hints, &ai2) || !ai2) { - fprintf(stderr, "Could not resolve %s: %s\n", argv[3], strerror(errno)); - return 1; - } - - while(true) { - uint8_t buf[10000]; - struct sockaddr src; - socklen_t srclen; - ssize_t len = recvfrom(fd, buf, sizeof buf, 0, &src, &srclen); - if(len <= 0) - break; - - // Ignore short packets. - if(len < 14) - continue; - - uint16_t type = buf[12] << 8 | buf[13]; - - if(ai2->ai_family == AF_INET && type == ETH_P_IP) - len = do_ipv4(buf, len, (struct sockaddr_in *)ai2->ai_addr); - else if(ai2->ai_family == AF_INET && type == ETH_P_ARP) - len = do_arp(buf, len, (struct sockaddr_in *)ai2->ai_addr); - else if(ai2->ai_family == AF_INET6 && type == ETH_P_IPV6) - len = do_ipv6(buf, len, (struct sockaddr_in6 *)ai2->ai_addr); - else - continue; - - if(len > 0) - sendto(fd, buf, len, 0, ai->ai_addr, ai->ai_addrlen); - } - - return 0; -} diff --git a/test/scripts.test b/test/scripts.test index 3b3f274..2580ced 100755 --- a/test/scripts.test +++ b/test/scripts.test @@ -1,6 +1,6 @@ #!/bin/sh -. ./testlib.sh +. "${0%/*}/testlib.sh" # Initialize server node diff --git a/test/security.test b/test/security.test new file mode 100755 index 0000000..91d29e2 --- /dev/null +++ b/test/security.test @@ -0,0 +1,98 @@ +#!/bin/sh + +. "${0%/*}/testlib.sh" + +# Skip this test if tools are missing + +which socket >/dev/null || exit 77 +which timeout >/dev/null || exit 77 + +# Initialize two nodes + +$tinc $c1 < + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include +#include +#include +#include +#include +#include +#include + +#ifdef HAVE_MINGW +extern const char *winerror(int); +#define strerror(x) ((x)>0?strerror(x):winerror(GetLastError())) +#define sockerrno WSAGetLastError() +#define sockstrerror(x) winerror(x) +#else +#define sockerrno errno +#define sockstrerror(x) strerror(x) +#endif + +int main(int argc, char *argv[]) { + if(argc < 7) { + fprintf(stderr, "Usage: %s name1 host1 port1 name2 host2 port2 [protocol]\n", argv[0]); + return 1; + } + + const char *protocol; + + if(argc >= 8) { + protocol = argv[7]; + } else { + protocol = "17.7"; + } + +#ifdef HAVE_MINGW + static struct WSAData wsa_state; + + if(WSAStartup(MAKEWORD(2, 2), &wsa_state)) { + return 1; + } + +#endif + int sock[2]; + char buf[1024]; + + struct addrinfo *ai, hint; + memset(&hint, 0, sizeof(hint)); + + hint.ai_family = AF_UNSPEC; + hint.ai_socktype = SOCK_STREAM; + hint.ai_protocol = IPPROTO_TCP; + hint.ai_flags = 0; + + for (int i = 0; i < 2; i++) { + if(getaddrinfo(argv[2 + 3 * i], argv[3 + 3 * i], &hint, &ai) || !ai) { + fprintf(stderr, "getaddrinfo() failed: %s\n", sockstrerror(sockerrno)); + return 1; + } + + sock[i] = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); + + if(sock[i] == -1) { + fprintf(stderr, "Could not create socket: %s\n", sockstrerror(sockerrno)); + return 1; + } + + if(connect(sock[i], ai->ai_addr, ai->ai_addrlen)) { + fprintf(stderr, "Could not connect to %s: %s\n", argv[i + 3 * i], sockstrerror(sockerrno)); + return 1; + } + + fprintf(stderr, "Connected to %s\n", argv[1 + 3 * i]); + + /* Pretend to be the other one */ + int len = snprintf(buf, sizeof buf, "0 %s %s\n", argv[4 - 3 * i], protocol); + if (send(sock[i], buf, len, 0) != len) { + fprintf(stderr, "Error sending data to %s: %s\n", argv[1 + 3 * i], sockstrerror(sockerrno)); + return 1; + } + + /* Ignore the response */ + do { + if (recv(sock[i], buf, 1, 0) != 1) { + fprintf(stderr, "Error reading data from %s: %s\n", argv[1 + 3 * i], sockstrerror(sockerrno)); + return 1; + } + } while(*buf != '\n'); + } + + fprintf(stderr, "Splicing...\n"); + + int nfds = (sock[0] > sock[1] ? sock[0] : sock[1]) + 1; + + while(true) { + fd_set fds; + FD_ZERO(&fds); + FD_SET(sock[0], &fds); + FD_SET(sock[1], &fds); + + if(select(nfds, &fds, NULL, NULL, NULL) <= 0) { + return 1; + } + + for(int i = 0; i < 2; i++ ) { + if(FD_ISSET(sock[i], &fds)) { + ssize_t len = recv(sock[i], buf, sizeof buf, 0); + + if(len < 0) { + fprintf(stderr, "Error while reading from %s: %s\n", argv[1 + i * 3], sockstrerror(sockerrno)); + return 1; + } + + if(len == 0) { + fprintf(stderr, "Connection closed by %s\n", argv[1 + i * 3]); + return 0; + } + + if(send(sock[i ^ 1], buf, len, 0) != len) { + fprintf(stderr, "Error while writing to %s: %s\n", argv[4 - i * 3], sockstrerror(sockerrno)); + return 1; + } + } + } + } + + return 0; +} diff --git a/test/sptps-basic.test b/test/sptps-basic.test index 9f86c8c..b6d081f 100755 --- a/test/sptps-basic.test +++ b/test/sptps-basic.test @@ -1,10 +1,10 @@ #!/bin/sh -. ./testlib.sh +. "${0%/*}/testlib.sh" # Skip this test if we did not compile sptps_test -test -e $sptps_test || exit 77 +test -e $sptps_test -a -e $sptps_keypair || exit 77 # Generate keys @@ -15,18 +15,18 @@ $sptps_keypair $d1/client.priv $d1/client.pub # Test transfer of a simple file. -(sleep 1; $sptps_test -4 -q $d1/client.priv $d1/server.pub localhost 32750 <../README) & +(sleep 1; $sptps_test -4 -q $d1/client.priv $d1/server.pub localhost 32750 $d1/out1 -cmp $d1/out1 ../README +cmp $d1/out1 Makefile -$sptps_test -4 -q $d1/server.priv $d1/client.pub 32750 <../NEWS & +$sptps_test -4 -q $d1/server.priv $d1/client.pub 32750 $d1/out2 -cmp $d1/out2 ../NEWS +cmp $d1/out2 Makefile # Datagram mode -$sptps_test -4 -dq $d1/server.priv $d1/client.pub 32750 <../COPYING & +$sptps_test -4 -dq $d1/server.priv $d1/client.pub 32750 $d1/out3 -cmp $d1/out3 ../COPYING +cmp $d1/out3 Makefile diff --git a/test/variables.test b/test/variables.test index 5fe6046..f8656c9 100755 --- a/test/variables.test +++ b/test/variables.test @@ -1,6 +1,6 @@ #!/bin/sh -. ./testlib.sh +. "${0%/*}/testlib.sh" # Initialize one node From 10b8518c221ebc3c74fd849bc43ca452f4ee68e9 Mon Sep 17 00:00:00 2001 From: Guus Sliepen Date: Mon, 26 Aug 2019 13:52:00 +0200 Subject: [PATCH 13/13] New upstream version 1.0.36 --- AUTHORS | 20 +- COPYING | 2 +- COPYING.README | 20 +- ChangeLog | 24881 +++--------------------- Makefile.am | 31 +- Makefile.in | 59 +- NEWS | 1062 +- README | 149 +- README.android | 38 +- THANKS | 12 +- aclocal.m4 | 5 - config.h.in | 99 +- configure | 1532 +- configure.ac | 106 +- doc/Makefile.am | 25 +- doc/Makefile.in | 47 +- doc/sample-config/tinc.conf | 6 +- doc/tinc-gui.8.in | 57 - doc/tinc.8.in | 345 - doc/tinc.conf.5.in | 324 +- doc/tinc.info | 2582 +-- doc/tinc.texi | 1569 +- doc/tincd.8.in | 50 +- doc/tincinclude.texi | 2 +- m4/ax_append_flag.m4 | 30 +- m4/ax_code_coverage.m4 | 264 - m4/curses.m4 | 44 - m4/libgcrypt.m4 | 33 - m4/miniupnpc.m4 | 40 - m4/openssl.m4 | 5 +- m4/readline.m4 | 42 - src/Makefile.am | 222 +- src/Makefile.in | 836 +- src/address_cache.c | 277 - src/address_cache.h | 50 - src/autoconnect.c | 195 - src/autoconnect.h | 25 - src/avl_tree.c | 757 + src/avl_tree.h | 142 + src/bsd/device.c | 168 +- src/bsd/tunemu.c | 6 +- src/buffer.c | 110 - src/buffer.h | 18 - src/chacha-poly1305/chacha-poly1305.c | 106 - src/chacha-poly1305/chacha-poly1305.h | 15 - src/chacha-poly1305/chacha.c | 224 - src/chacha-poly1305/chacha.h | 24 - src/chacha-poly1305/poly1305.c | 205 - src/chacha-poly1305/poly1305.h | 16 - src/cipher.h | 46 - src/conf.c | 257 +- src/conf.h | 41 +- src/connection.c | 137 +- src/connection.h | 106 +- src/control.c | 241 - src/control.h | 27 - src/control_common.h | 48 - src/crypto.h | 27 - src/cygwin/device.c | 69 +- src/device.h | 9 +- src/digest.h | 42 - src/dropin.c | 22 +- src/dropin.h | 50 +- src/dummy_device.c | 18 +- src/ecdh.h | 34 - src/ecdsa.h | 37 - src/ecdsagen.h | 29 - src/ed25519/ecdh.c | 51 - src/ed25519/ecdsa.c | 168 - src/ed25519/ecdsagen.c | 73 - src/ed25519/ed25519.h | 37 - src/ed25519/fe.c | 1511 -- src/ed25519/fe.h | 41 - src/ed25519/fixedint.h | 91 - src/ed25519/ge.c | 467 - src/ed25519/ge.h | 74 - src/ed25519/key_exchange.c | 80 - src/ed25519/keypair.c | 16 - src/ed25519/precomp_data.h | 1391 -- src/ed25519/sc.c | 785 - src/ed25519/sc.h | 12 - src/ed25519/sha512.c | 303 - src/ed25519/sha512.h | 21 - src/ed25519/sign.c | 31 - src/ed25519/verify.c | 77 - src/edge.c | 60 +- src/edge.h | 21 +- src/ethernet.h | 19 +- src/event.c | 484 +- src/event.h | 69 +- src/fake-getaddrinfo.c | 108 + src/fake-getaddrinfo.h | 57 + src/fake-getnameinfo.c | 64 + src/fake-getnameinfo.h | 16 + src/fd_device.c | 125 - src/fsck.c | 603 - src/fsck.h | 25 - src/gcrypt/cipher.c | 284 - src/gcrypt/crypto.c | 34 - src/gcrypt/digest.c | 182 - src/gcrypt/digest.h | 45 - src/gcrypt/prf.c | 121 - src/gcrypt/rsa.c | 327 - src/gcrypt/rsagen.c | 239 - src/getopt.c | 40 +- src/getopt.h | 139 +- src/graph.c | 262 +- src/hash.c | 128 - src/hash.h | 42 - src/have.h | 52 +- src/ifconfig.c | 304 - src/ifconfig.h | 31 - src/info.c | 357 - src/info.h | 26 - src/invitation.c | 1351 -- src/invitation.h | 26 - src/ipv4.h | 4 +- src/ipv6.h | 39 +- src/linux/device.c | 153 +- src/list.c | 80 +- src/list.h | 20 +- src/logger.c | 199 +- src/logger.h | 31 +- src/meta.c | 367 +- src/meta.h | 10 +- src/mingw/common.h | 5 - src/mingw/device.c | 253 +- src/multicast_device.c | 127 +- src/names.c | 180 - src/names.h | 38 - src/net.c | 914 +- src/net.h | 130 +- src/net_packet.c | 1743 +- src/net_setup.c | 1430 +- src/net_socket.c | 672 +- src/netutl.c | 118 +- src/netutl.h | 12 +- src/node.c | 204 +- src/node.h | 76 +- src/nolegacy/crypto.c | 94 - src/nolegacy/prf.c | 121 - src/openssl/cipher.c | 215 - src/openssl/crypto.c | 114 - src/openssl/digest.c | 171 - src/openssl/digest.h | 33 - src/openssl/prf.c | 86 - src/openssl/rsa.c | 146 - src/openssl/rsagen.c | 119 - src/pidfile.c | 142 + src/pidfile.h | 57 + src/prf.h | 25 - src/process.c | 534 +- src/process.h | 7 +- src/protocol.c | 229 +- src/protocol.h | 77 +- src/protocol_auth.c | 919 +- src/protocol_edge.c | 172 +- src/protocol_key.c | 461 +- src/protocol_misc.c | 308 +- src/protocol_subnet.c | 68 +- src/proxy.c | 366 + src/{upnp.h => proxy.h} | 26 +- src/raw_socket_device.c | 57 +- src/route.c | 489 +- src/route.h | 2 +- src/rsa.h | 36 - src/rsagen.h | 29 - src/script.c | 232 - src/script.h | 38 - src/solaris/device.c | 96 +- src/splay_tree.c | 630 - src/splay_tree.h | 117 - src/sptps.c | 767 - src/sptps.h | 95 - src/sptps_keypair.c | 123 - src/sptps_speed.c | 308 - src/sptps_test.c | 471 - src/subnet.c | 533 +- src/subnet.h | 30 +- src/subnet_parse.c | 490 - src/system.h | 8 +- src/tincctl.c | 3352 ---- src/tincctl.h | 55 - src/tincd.c | 603 +- src/top.c | 396 - src/top.h | 25 - src/uml_device.c | 114 +- src/upnp.c | 185 - src/utils.c | 238 +- src/utils.h | 21 +- src/vde_device.c | 45 +- src/version.c | 31 - src/version.h | 27 - src/xalloc.h | 8 +- systemd/Makefile.in | 22 +- systemd/tinc@.service.in | 2 +- test-driver | 148 - test/Makefile.am | 30 - test/Makefile.in | 951 - test/basic.test | 20 - test/commandline.test | 50 - test/executables.test | 10 - test/import-export.test | 64 - test/invite-join.test | 46 - test/invite-offline.test | 49 - test/invite-tinc-up.test | 51 - test/legacy-protocol.test | 79 - test/ns-ping.test | 70 - test/scripts.test | 112 - test/security.test | 98 - test/splice.c | 144 - test/sptps-basic.test | 32 - test/testlib.sh | 41 - test/variables.test | 86 - 214 files changed, 12416 insertions(+), 59622 deletions(-) delete mode 100644 doc/tinc-gui.8.in delete mode 100644 doc/tinc.8.in delete mode 100644 m4/ax_code_coverage.m4 delete mode 100644 m4/curses.m4 delete mode 100644 m4/libgcrypt.m4 delete mode 100644 m4/miniupnpc.m4 delete mode 100644 m4/readline.m4 delete mode 100644 src/address_cache.c delete mode 100644 src/address_cache.h delete mode 100644 src/autoconnect.c delete mode 100644 src/autoconnect.h create mode 100644 src/avl_tree.c create mode 100644 src/avl_tree.h delete mode 100644 src/buffer.c delete mode 100644 src/buffer.h delete mode 100644 src/chacha-poly1305/chacha-poly1305.c delete mode 100644 src/chacha-poly1305/chacha-poly1305.h delete mode 100644 src/chacha-poly1305/chacha.c delete mode 100644 src/chacha-poly1305/chacha.h delete mode 100644 src/chacha-poly1305/poly1305.c delete mode 100644 src/chacha-poly1305/poly1305.h delete mode 100644 src/cipher.h delete mode 100644 src/control.c delete mode 100644 src/control.h delete mode 100644 src/control_common.h delete mode 100644 src/crypto.h delete mode 100644 src/digest.h delete mode 100644 src/ecdh.h delete mode 100644 src/ecdsa.h delete mode 100644 src/ecdsagen.h delete mode 100644 src/ed25519/ecdh.c delete mode 100644 src/ed25519/ecdsa.c delete mode 100644 src/ed25519/ecdsagen.c delete mode 100644 src/ed25519/ed25519.h delete mode 100644 src/ed25519/fe.c delete mode 100644 src/ed25519/fe.h delete mode 100644 src/ed25519/fixedint.h delete mode 100644 src/ed25519/ge.c delete mode 100644 src/ed25519/ge.h delete mode 100644 src/ed25519/key_exchange.c delete mode 100644 src/ed25519/keypair.c delete mode 100644 src/ed25519/precomp_data.h delete mode 100644 src/ed25519/sc.c delete mode 100644 src/ed25519/sc.h delete mode 100644 src/ed25519/sha512.c delete mode 100644 src/ed25519/sha512.h delete mode 100644 src/ed25519/sign.c delete mode 100644 src/ed25519/verify.c create mode 100644 src/fake-getaddrinfo.c create mode 100644 src/fake-getaddrinfo.h create mode 100644 src/fake-getnameinfo.c create mode 100644 src/fake-getnameinfo.h delete mode 100644 src/fd_device.c delete mode 100644 src/fsck.c delete mode 100644 src/fsck.h delete mode 100644 src/gcrypt/cipher.c delete mode 100644 src/gcrypt/crypto.c delete mode 100644 src/gcrypt/digest.c delete mode 100644 src/gcrypt/digest.h delete mode 100644 src/gcrypt/prf.c delete mode 100644 src/gcrypt/rsa.c delete mode 100644 src/gcrypt/rsagen.c delete mode 100644 src/hash.c delete mode 100644 src/hash.h delete mode 100644 src/ifconfig.c delete mode 100644 src/ifconfig.h delete mode 100644 src/info.c delete mode 100644 src/info.h delete mode 100644 src/invitation.c delete mode 100644 src/invitation.h delete mode 100644 src/names.c delete mode 100644 src/names.h delete mode 100644 src/nolegacy/crypto.c delete mode 100644 src/nolegacy/prf.c delete mode 100644 src/openssl/cipher.c delete mode 100644 src/openssl/crypto.c delete mode 100644 src/openssl/digest.c delete mode 100644 src/openssl/digest.h delete mode 100644 src/openssl/prf.c delete mode 100644 src/openssl/rsa.c delete mode 100644 src/openssl/rsagen.c create mode 100644 src/pidfile.c create mode 100644 src/pidfile.h delete mode 100644 src/prf.h create mode 100644 src/proxy.c rename src/{upnp.h => proxy.h} (62%) delete mode 100644 src/rsa.h delete mode 100644 src/rsagen.h delete mode 100644 src/script.c delete mode 100644 src/script.h delete mode 100644 src/splay_tree.c delete mode 100644 src/splay_tree.h delete mode 100644 src/sptps.c delete mode 100644 src/sptps.h delete mode 100644 src/sptps_keypair.c delete mode 100644 src/sptps_speed.c delete mode 100644 src/sptps_test.c delete mode 100644 src/subnet_parse.c delete mode 100644 src/tincctl.c delete mode 100644 src/tincctl.h delete mode 100644 src/top.c delete mode 100644 src/top.h delete mode 100644 src/upnp.c delete mode 100644 src/version.c delete mode 100644 src/version.h delete mode 100755 test-driver delete mode 100644 test/Makefile.am delete mode 100644 test/Makefile.in delete mode 100755 test/basic.test delete mode 100755 test/commandline.test delete mode 100755 test/executables.test delete mode 100755 test/import-export.test delete mode 100755 test/invite-join.test delete mode 100755 test/invite-offline.test delete mode 100755 test/invite-tinc-up.test delete mode 100755 test/legacy-protocol.test delete mode 100755 test/ns-ping.test delete mode 100755 test/scripts.test delete mode 100755 test/security.test delete mode 100644 test/splice.c delete mode 100755 test/sptps-basic.test delete mode 100644 test/testlib.sh delete mode 100755 test/variables.test diff --git a/AUTHORS b/AUTHORS index 07939e8..af11393 100644 --- a/AUTHORS +++ b/AUTHORS @@ -1,25 +1,20 @@ Main tinc authors: - - Guus Sliepen - Ivo Timmermans (inactive) -Significant code contributions from: - -- Brandon Black -- Etienne Dechamps +Significant contributions from: +- Michael Tokarev - Florian Forster - Grzegorz Dymarek -- Julien Muchembled -- Loïc Grenié - Max Rijevski -- Michael Tokarev - Scott Lamb -- Sven-Haegar Koch +- Julien Muchembled - Timothy Redaelli +- Brandon Black +- Loïc Grenié These files are from other sources: - -* lib/pidfile.h and lib/pidfile.c are by Martin Schulze, taken from + * lib/pidfile.h and lib/pidfile.c are by Martin Schulze, taken from the syslog 1.3 sources. * src/bsd/tunemu.c and tunemu.h are by Friedrich Schöller @@ -28,4 +23,5 @@ These files are from other sources: Also some of the macro files in the directory m4, and their accompanying files in lib, were taken from GNU fileutils. -Please see the file THANKS for a list of all contributors to tinc. +Please see the file THANKS for more information on contributions from +users. diff --git a/COPYING b/COPYING index 1a88dcf..1384f46 100644 --- a/COPYING +++ b/COPYING @@ -1,4 +1,4 @@ -Copyright (C) 1998-2018 Ivo Timmermans, Guus Sliepen and others. +Copyright (C) 1998-2019 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 166102b..2eb9c1f 100644 --- a/COPYING.README +++ b/COPYING.README @@ -1,17 +1,19 @@ The following applies to tinc: -> This program is released under the GPL with the additional exemption that -> compiling, linking, and/or using OpenSSL is allowed. You may provide binary -> packages linked to the OpenSSL libraries, provided that all other requirements -> of the GPL are met. +This program is released under the GPL with the additional exemption that +compiling, linking, and/or using OpenSSL is allowed. You may provide binary +packages linked to the OpenSSL libraries, provided that all other requirements +of the GPL are met. The following applies to the LZO library: -> Hereby I grant a special exception to the tinc VPN project -> (https://www.tinc-vpn.org/) to link the LZO library with the OpenSSL library -> (https://openssl.org). -> -> Markus F.X.J. Oberhumer + Hereby I grant a special exception to the tinc VPN project + (http://tinc.nl.linux.org/) to link the LZO library with the OpenSSL library + (http://www.openssl.org). + + Markus F.X.J. Oberhumer 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 e28cde2..041bf3f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,22659 +1,2224 @@ -commit 2b74e1b01af2d56d6e7ebc135143fbe81f6ca455 -Author: Guus Sliepen -Date: Mon Oct 8 11:00:01 2018 +0200 +Version 1.0.36 August 26 2019 +------------------------------------------------------------------------ + +Guus Sliepen (8): + Remove the call to RAND_load_file(). + Update THANKS. + Backport tinc 1.1's str2net() function. + Update THANKS. + Fix spelling errors found by codespell. + Reformat all code using astyle. + Add a missing check for a pathname being too long. + Releasing 1.0.36. + +Rosen Penev (2): + Fix compilation when OpenSSL has no ENGINE support + Fix compilation without deprecated OpenSSL APIs + +Quentin Rameau (1): + Double-quote nodes in graphviz network file + +Werner Schreiber (1): + Fix segfault when dest->mtu is 0. + +Version 1.0.35 October 05 2018 +------------------------------------------------------------------------ + +Guus Sliepen (12): + Prevent oracle attacks (CVE-2018-16737, CVE-2018-16738) + Prevent a MITM from forcing a NULL cipher for UDP (CVE-2018-16758) + Check the return value from snprintf(). + Check the return values from BN_hex2bn() and RAND_load_file(). + Fix all warnings when compiling with -Wall -W -pedantic. + Fix two small memory leaks. + Don't check for NULL-pointers before calling free(). + Update THANKS. + Fix checks for Cygwin-related macros. + Fix spelling errors. + Update README and links to required libraries. + Releasing 1.0.35. + +AMRI Amine (1): + Fixing typo + +Rafael Sadowski (1): + OpenBSD has a proper tap device. + +Version 1.0.34 June 12 2018 +------------------------------------------------------------------------ + +Guus Sliepen (10): + Add missing thanks to the NEWS message. + Fix building documentation when using OpenBSD's make. + Fix #ifdefs that were broken due to commit d178b58. + Don't use SOL_IP and SOL_IPV6. + Make systemd service file handling identical to tinc 1.1. + Rename distro/ to systemd/. + Document how to enable tinc at boot time using systemd. + Fix all spelling errors found by codespell. + Properly implement tinc.texi's dependency on tincinclude.texi. + Releasing 1.0.34. + +Maximilian Stein (1): + Fix SEGFAULT when trying to connect to IPv6 peer in non-IPv6 environment + +wangliushuai (1): + Remove redundant 'break'. + +Version 1.0.33 November 04 2017 +------------------------------------------------------------------------ + +Guus Sliepen (31): + Udpate THANKS. + Fix a potential memory leak. + Use AC_CONFIG_MACRO_DIR(). + Give absolute path for #include to AC_CHECK_HEADERS(). + Prepare for automatic code formatting using Artistic Style. + Never remove items from cmdline_conf. + Use stack-allocated strings for temporary filenames. + Fix a few minor memory leaks. + Remove unused/obsolete checks from configure.ac. + Use getcwd() instead of get_current_dir_name(). + Remove xmalloc.c, backport xalloc.h from tinc 1.1. + Update all header guards. + Convert sizeof foo to sizeof(foo). + Reformat all code using astyle. + Don't call ERR_remove_state(). + Unconditionally include stdbool.h and inttypes.h. + Remove more obsolete autoconf checks. + Remove obsolete m4/README. + Fix some "make distcheck" errors. + Add some information about the requirements of a chroot environment. + Handle tun/tap device returning EPERM or EBUSY. + Disable PMTU discovery when TCPOnly is used. + Fix all -Wall -W compiler warnings. + Realign comments. + Remove unused functions. + Ensure all parameters have names in header files. + Support autoconf's --runstatedir option. + Const correctness. + Fix compilation errors when --enable-uml is used. + Update THANKS. + Releasing 1.0.33. + +Rafael Sadowski (1): + fix tinc.conf for OpenBSD + +nemunaire (1): + Allow compilation from a build directory + +Version 1.0.32 September 02 2017 +------------------------------------------------------------------------ + +Guus Sliepen (13): + Don't dereference myself->incipher if it's NULL. + Merge remote-tracking branch 'VittGam/master' + Use /dev/udp instead of /dev/ip on Solaris. + Use getmsg()/putmsg() instead of read()/write() on Solaris. + Fix Solaris DeviceType = tap in router Mode. + Bind outgoing TCP sockets. + Move logging of "would block" messages to debug level 4. + Set KillMode=mixed in the systemd service file. + Don't forget about outgoing connections on host file read errors. + Fix Proxy = exec. + Set status.proxy_passed early for Proxy = exec. + Don't try to bind Proxy = exec sockets to an address. + Releasing 1.0.32. + +Vittorio Gambaletta (VittGam) (1): + route: Support ToS/DiffServ priority inheritance when routing IPv6 packets. + +Version 1.0.31 January 15 2017 +------------------------------------------------------------------------ + +Guus Sliepen (1): + Releasing 1.0.31. + +Élie Bouttier (1): + Remove ExecStop in tinc@.service + +Version 1.0.30 October 30 2016 +------------------------------------------------------------------------ + +Guus Sliepen (11): + Allow non-empty lines after status code from a HTTP proxy. + Fix proxy reply parsing broken by the previous commit. + Log only the first line of a proxy request rejection message. + Delay sending the real ID request until after a proxy request is granted. + Use AES256 and SHA256 by default, also for the meta-connections. + Enforce maximum amount of bytes sent/received on meta-connections. + Fix bit shifting arithmetic so the code actually does what the last commit message says. + Really fix byte budget calculation. + Use AES in CTR mode instead of OFB mode for meta-connections. + Use CFB mode for meta-connections to improve security. + Releasing 1.0.30. + +Version 1.0.29 October 09 2016 +------------------------------------------------------------------------ + +Guus Sliepen (11): + Preserve IPv6 scope_id in edges. + Ensure compatibility with OpenSSL 1.1.0. + Add -Wall to CFLAGS. + Check return value of RSA_generate_key_ex(). + Force nul-termination of strings after vsnprintf(). + Log warnings about dropped packets only with debug level 5 or higher. + Add a copy of ax_append_flag.m4. + Add ax_require_defined.m4. + Fix possibly unitialized variable. + Fix compiler warnings about format string errors on BSD. + Releasing 1.0.29. + +Version 1.0.28 April 10 2016 +------------------------------------------------------------------------ + +Guus Sliepen (8): + Fix compiling bsd/device.c on systems without utun. + Really remove use of __DATE__ and __TIME__ to facilitate reproducible builds. + Add systemd service files. + Update .gitignore. + Ensure the service files are in the tarball. + Explicitly mention that LibreSSL can be used as well. + Update links in the documentation. + Releasing 1.0.28. + +Version 1.0.27 April 10 2016 +------------------------------------------------------------------------ + +Guus Sliepen (26): + Add missing AM_PROG_CC_C_O to configure.ac. + Attribution for various contributors. + Update "now" after connect() when making outgoing connections. + Add ability to use proxies to connect to hostnames when there is no nameserver. + Only add a reflexive address when we're sure it's working. + Fix compatibility with TAP-Win32 9.0.0.21 and later. + Fix warnings from the Clang Static Analyzer. + Improve performance of edge updates. + Clarify that scripts are called synchronously. + Small fixes for the documentation. + Add warnings for bad combinations of Device and Interface. + Fix forwarding of edge updates. + Don't compile getopt*.c if the system provides getopt_long(). + Update .gitignore. + Update THANKS. + Use iface instead of interface. + Update copyright notices. + Remove use of __DATE__ and __TIME__ to facilitate reproducible builds. + Cast 0xff to char before comparing it to another char. + Get rid of a warning when compiling tinc using MinGW. + Every BSD flavor has a tap device nowadays. + Use devname() if available to support devfs cloning on BSD. + Use SIOCGIFADDR on BSDs that support it. + Enable silent builds by default. + Add support for OS X utun interfaces. + Releasing 1.0.27. + +Vittorio Gambaletta (VittGam) (6): + Fix DecrementTTL option. + Fix source IP address for ICMP unreachable packets generated by tinc. + Try to reply with node address only when decrementing the TTL. + Fix DecrementTTL option for packets destined to the local node. + s/broadcast_packet_helper/route_broadcast/ + Remove forward declaration for do_decrement_ttl. + +LunarShaddow (3): + fix typo + re-arrange include sequence to avoid a mingw introduced bug. + Proofing README. + +Florian Weik (1): + Fix NAME variable in subnet-* scripts for local subnets. + +Nathan Stratton Treadway (1): + Fix invalid checksum generation. + +Version 1.0.26 July 05 2015 +------------------------------------------------------------------------ + +Guus Sliepen (14): + Use VittGam's real name. + Attribution for Saverio Proto. + Always call res_init() before getaddrinfo(). + Fix --logfile without a filename on Windows. + Never call putenv() with data on the stack. + Return non-zero exit code when encountering configuration errors during startup. + Fix autoconf check for function attributes. + Fix spelling of FORTIFY_SOURCE. + Update copyright notices. + Attribution for various contributors. + Only check for -fno-strict-overflow if -fwrapv does not work. + Fix unputenv() on Windows. + Don't try to call res_init() if ./configure told us it doesn't exist. + Releasing 1.0.26. + +Jo-Philipp Wich (1): + fix musl compatibility + +Version 1.0.25 December 22 2014 +------------------------------------------------------------------------ + +Guus Sliepen (7): + Fix date of last NEWS entry. + Remember ToS/Diffserv priority for each socket individually. + Attribution for various contributors. + Automatically choose a tap device on Mac OS X when using switch Mode. + Update documentation for Mac OS X. + Check whether res_init() really lives in libresolv. + Releasing 1.0.25. + +Borg (3): + Fixed scripts calling under Win32. + Get MAC of TAP device. + Fixed tinc-up script calling on Win32. + +Alexis Hildebrandt (1): + Add support to link against libresolv Mac OS X + +Baptiste Jonglez (1): + Use the description from the 1.1 man page for the IndirectData option + +David Pflug (1): + Update README.android + +Jochen Voss (1): + Fix some typos in the manual. + +Tomislav Čohar (1): + Configure minimum reconnect timeouts. + +VittGam (1): + Support ToS/DiffServ priority handling for IPv6 meta and UDP connections. + +Version 1.0.24 May 11 2014 +------------------------------------------------------------------------ + +Guus Sliepen (13): + Remove useless variable 'hard' from try_harder(). + Merge pull request #14 from luckyhacky/master + Add an autoconf check for res_init(). + Nexthop calculation should always use the shortest path. + Fix issues found by Coverity. + Fix warnings found by GCC 4.9. + Fix a few more issues found by Coverity. + Fix a few more issues found by Coverity. + Drop h and hh length modifiers from printf format strings. + Fix a bug that could prevent tinc from starting correctly on Windows. + FIx the autoconf checks for res_init(). + Remove the warnings when IP_DONTFRAGMENT/IPV6-DONTFRAG is not supported. + Releasing 1.0.24. + +Steffan Karger (3): + Use constant time memcmp() when comparing packet HMACs. + Use cryptographically strong random when generating keys. + Check RAND_bytes() return value, fail when getting random fails. + +Armin Fisslthaler (1): + reload /etc/resolv.conf in SIGALRM handler + +Loic Dachary (1): + fix documentation typo + +luckyhacky (1): + update to openssl version 1.0.1g due to lack of heartbleed bug in prior version of openssl + +refs/tags/1.0.23-android-1 March 11 2014 +------------------------------------------------------------------------ + +Guus Sliepen (13): + Mention in the manual that multiple Address staments are allowed. + If no Port is specified, set myport to actual port of first listening socket. + Enable compiler hardening flags by default. + Update support for Solaris. + Include for PATH_MAX. + Stricter check for raw socket support. + Use hardcoded value for TUNNEWPPA if net/if_tun.h is missing on Solaris. + Fix incorrectly merged bits from 80cd2ff73071941a5356555b85a00ee90dfd0e16. + Don't enable -fstack-protector-all. + Remove or lower the priority of some debug messages. + Clarify StrictSubnets. + Attribution for various contributors. + Handle errors from TAP-Win32/64 adapter in a better way. + +Florent Clairambault (2): + Adding "conf.d" configuration dir support. + Adding some documentation around the /etc/tinc/$NET/conf.d directory. + +Vilbrekin (1): + Update android build instructions. Disable PIE as this is not supported on some devices. + +Version 1.0.23 October 19 2013 +------------------------------------------------------------------------ + +Guus Sliepen (9): + Check for writability when waiting for a socket to finish connecting. + Don't send PING requests on connections which are not active yet. + Fix segfault when Name = $HOST but $HOST is not set. + Fix typos in the documentation. + Modernize the build system. + Get rid of the splay tree implementation. + Add description of IffOneQueue and MaxTimeout to the info manual. + Clean up child processes from proxy type exec. + Releasing 1.0.23. + +Version 1.0.22 August 13 2013 +------------------------------------------------------------------------ + +Guus Sliepen (7): + Better optional argument handling. + Fix a typo. + Set $NAME when calling host-up/down and subnet-up/down scripts. + Don't use vasprintf() anymore on Windows. + Don't echo broadcast packets back when Broadcast = direct. + Update copyright notices. + Releasing 1.0.22. + +Etienne Dechamps (1): + Fix combination of Mode = router and DeviceType = tap on Linux. + +Version 1.0.21 April 22 2013 +------------------------------------------------------------------------ + +Guus Sliepen (2): + Drop packets forwarded via TCP if they are too big (CVE-2013-1428). + Releasing 1.0.21. + +Version 1.0.20 March 03 2013 +------------------------------------------------------------------------ + +Guus Sliepen (30): + Use /dev/tap0 by default on FreeBSD and NetBSD when using Mode = switch. + Document how to load the tap driver on FreeBSD. + Update THANKS file. + Also clarify hostnames=[yes|no] in tinc.conf(5). + Attribution for Vil Brekin and some code style cleanups. + Don't ignore Makefile.am. + Fix links in documenation. + Attribution for Martin Schürrer. + Add strict checks to hex to binary conversions. + Clear connection options and status fields in free_connection_partially(). + Fix warnings from cppcheck. + Clear Ethernet header when reading packets from a tun device. + Clear status and options fields of unreachable nodes. + Fix warnings from groff. + Using alloca() for a constant sized buffer is very silly. + Make sure PMTU discovery works in switch mode with VLAN tags. + Mention in the manual that support for LZO and zlib can be disabled. + Fix configure script help text for --enable options. + Don't take the address of a variable whose scope is about to disappear. + Send broadcast packets using a random socket, and properly support IPv6. + Remove text saying you must have one of PrivateKey or PrivateKeyFile in tinc.conf. + Fix support for tunemu on iOS devices. + Make sure PriorityInheritance also works in switch mode. + Detect increases in PMTU. + Fix a compiler warning. + Fix segmentation fault when trying to connect via a SOCKS5 proxy. + Don't send proxy requests for incoming connections. + Fix compiler warnings on Windows. + Fix detection of rejected SOCKS5 proxy requests. + Releasing 1.0.20. + +Vilbrekin (5): + Basic patch for android cross-compilation. + Replace hard-code with new ScriptsInterpreter configuration property. + Add basic .gitignore file, cleaning (most) files generated by autotools. + Use __ANDROID__ define rather than dirty hard-code to allow android NDK cross-compilation. + Android cross-compilation instructions. + +Martin Schürrer (1): + Output details of encryption errors + +Mesar Hameed (1): + Minor clarification, tinc.conf hostnames=[yes|no] variable only resolves names for logging purposes. + +Version 1.0.19 June 25 2012 +------------------------------------------------------------------------ + +Guus Sliepen (14): + Support :: in IPv6 Subnets. + Remove newline from log message. + Add support for systemd style socket activation. + Allow environment variables to be used for Name. + Allow broadcast packets to be sent directly instead of via the MST. + Add basic support for SOCKS 4 and HTTP CONNECT proxies. + Add support for SOCKS 5 proxies. + Add support for proxying through an external command. + Document new proxy types. + Small fixes in proxy code. + #include on Windows. + Fix compiler warnings. + Fix crash when using Broadcast = direct. + Releasing 1.0.19. + +Anthony G. Basile (1): + configure.in: fix AC_ARG_ENABLE and AC_ARG_WITH + +Michael Tokarev (1): + add (errnum) in front of windows error messages + +Version 1.0.18 March 25 2012 +------------------------------------------------------------------------ + +Guus Sliepen (13): + Always try next Address when an outgoing connection fails to authenticate. + Allow a port to be specified in BindToAddress statements. + Add support for multicast communication with UML/QEMU/KVM. + Set default value of DecrementTTL to "no". + Add #ifdefs in case not all platforms support IPv4 and IPv6 multicast. + Allow scoped addresses to be used for IPv6 multicast socket. + Fix compiler warnings. + Fix return value type of vde_send(). + Fix some more compiler warnings. + Document OpenBSD "ifconfig link0" and Linux "ip tuntap" commands. + Fix return type of vde_recv() as well. + Mark DecrementTTL option experimental. + Releasing 1.0.18. + +Version 1.0.17 March 10 2012 +------------------------------------------------------------------------ + +Guus Sliepen (32): + Prevent read_rsa_public_key() from returning an uninitialized RSA structure. + Return false instead of void when there is an error. + Fix compilation of VDE and UML interfaces. + Add vde/device.c to the tarball. + Fix a few small memory leaks. + Allow linking with multiple device drivers. + Set FD_CLOEXEC flag on all sockets. + Allow multiple BindToAddress statements. + Merge branch 'master' of black:tinc + Send packets back using the same socket as they were received on. + Allow setting DeviceType to tun or tap on Linux. + Merge branch 'master' of black:tinc + Only compile raw socket code when it is supported on that platform. + Decrement TTL of incoming packets. + Don't bind outgoing TCP sockets anymore. + Rename connection_t *broadcast to everyone. + Allow disabling of broadcast packets. + Move initialization of char *priority up to prevent freeing an uninitialized pointer. + Document the command line flag -o and provide --option as well. + Fix a bug that caused tinc to ignore all but the last listening socket. + Fix check for raw socket support. + Pass index into listen_socket[] to handle_incoming_vpn_data(). + Add LocalDiscovery option which tries to detect peers on the local network. + Don't send ICMP Time Exceeded messages for other Time Exceeded messages. + Stricter checks against routing loops. + Only use broadcast at the start of the PMTU discovery phase. + Only log errors sending UDP packets when debug level >= 5. + Accept Subnets passed with the -o option when StrictSubnets = yes. + Add missing ICMP6 message type definitions. + Make sure disabling old RSA keys works on Windows. + Update copyright notices. + Releasing 1.0.17. + +Nick Hibma (1): + Add missing ICMP message type definitions. + +Version 1.0.16 July 23 2011 +------------------------------------------------------------------------ + +Guus Sliepen (4): + Make code to detect two nodes with the same Name less triggerhappy. + Flush output buffer in send_tcppacket(). + Use usleep() instead of sleep(), MinGW complained. + Releasing 1.0.16. + +Version 1.0.15 June 24 2011 +------------------------------------------------------------------------ + +Guus Sliepen (9): + Reorder checks for libraries to allow ./configure LDFLAGS=-static. + Make return value of SetPriorityClass() behave the same as setpriority(). + Fix sparse warnings and add an extra sprinkling of const. + Remove newlines from log messages. + Remove a few unnecessary #includes. + Attribution for Loïc Grenié. + Improved --logfile option. + Remove redundant @CFLAGS@ from AM_CFLAGS. + Releasing 1.0.15. + +Loïc Grenié (1): + Nearly tickless tinc. + +Version 1.0.14 May 08 2011 +------------------------------------------------------------------------ + +Guus Sliepen (48): + Fix reading configuration files that do not end with a newline. Again. + Define WINVER before including any other header file on Windows. + Use intptr_t instead of long to store a pointer. + OpenSSL 1.0.0 compiled for 64 bit Windows requires linking with -lcrypt32. + Fix all warnings when compiling with mingw64. + Use strrchr() insteaad of rindex(). + Detect and prevent two nodes with the same Name being on the VPN simultaneously. + Use 64 bit counters to keep track of bytes sent/received from the virtual network interface. + Do not append an address to ANS_KEY messages if we don't know any address. + Merge local host configuration with server configuration. + Remove duplicate command-line option parsing. + Attribution for Julien Muchembled. + Attribution for Timothy Redaelli. + Ensure there is a newline character before a PEM key is written. + Abort disabling old PEM keys on I/O errors. + Remove unused variables. + Quit when there are too many consecutive errors on the tun/tap device. + Read error counter must be static. + Add short options -R and -U to the tincd(8) manpage. + Don't use strlen() on a NULL pointer. + Provide usleep() for Windows. + Use variable length arrays instead of alloca(). + Fix warning message when setting SO_RCVBUF or SO_SNDBUF fails. + Free replay window when freeing a node_t. + Fix variable length array declaration. + Attribution for Brandon Black. + Use setpriority() instead of nice() on UNIX-like systems. + Always send MTU probes at least once every PingInterval. + Close all filedescriptors in Solaris close_device(). + Limit field width when scanning PID file. + Replace bogus #else with #endif. + Remove unused variables. + Document the behavior of "-n." + Update the manual. + Update the NEWS. + Proper check and dropin replacement for usleep(). + Fix typo spotted by Andrew Scheller. + Add support for VDE through libvdeplug. + Fix spurious misidentification of incoming UDP packets. + Prevent anything from updating our own UDP address. + Do not set indirect flag on edges from nodes with multiple addresses. + Increase threshold for detecting two nodes with the same Name. + Always use the default signal handler for ABRT signals. + Check for EVP_EncryptInit_ex instead of SHA1_Version in OpenSSL. + Update THANKS and copyright information. + Ensure proper linking with OpenSSL with recent versions of MinGW. + Include when using intptr_t. + Releasing 1.0.14. + +Brandon L Black (4): + Experimental IFF_ONE_QUEUE support for Linux + Configurable SO_RCVBUF/SO_SNDBUF for the UDP socket + Configurable ReplayWindow size, zero disables + Improved handling of queue-jumping packets on receive + +Julien Muchembled (2): + New '-o' option to configure server or hosts from command line + Fix command-line '-o' option for host configuration + +Timothy Redaelli (2): + Fix warnings showed using -D_FORTIFY_SOURCE=2 + Fix warnings under BSD + +Michael Tokarev (1): + Treat netname="." in a special way. + +Rumko (1): + DragonFlyBSD support + +Version 1.0.13 April 11 2010 +------------------------------------------------------------------------ + +Guus Sliepen (20): + Clamp MSS to miminum MTU in both directions. + Simplify reading lines from configuration files. + Check for dirent.h. + Preload all Subnets in TunnelServer mode. + Add the StrictSubnets option. + Add the Forwarding option. + Add the DirectOnly option. + Fixes for the Forwarding option. + ConnectTo does not mean tinc does not listen for incoming connections anymore. + Log unauthorized Subnets when StrictSubnets is set. + Fix typo. + Convert Port to numeric form before sending it to other nodes. + Ensure ICMP_NET_ANO is defined. + Reload Subnets when getting a HUP signal and StrictSubnets is used. + Fix reloading Subnets when StrictSubnets is set. + Ensure subnet-up/down scripts are called after HUP when necessary. + Fixes for definitions under Windows. + Don't redefine MAX if it already exists. + Mark Forwarding and DirectOnly options as being experimental. + Releasing 1.0.13. + +Timothy Redaelli (2): + Add --disable-lzo configure option + Add --disable-zlib configure option + +Sven-Haegar Koch (1): + Never delete Subnets when StrictSubnets is set + +Version 1.0.12 February 03 2010 +------------------------------------------------------------------------ + +Guus Sliepen (21): + When learning MAC addresses, only check our own Subnets for previous entries. + Remove unused variable in lookup_subnet_*() functions. + Forget addresses of unreachable nodes. + Do not fragment packets smaller than RFC defined minimum MTUs. + Allow port to be specified in Address statements. + Use xstrdup() instead of xasprintf() to copy static strings. + Allow Port and PMTUDiscovery options in tinc.conf, always enable PMTUDiscovery by default. + Clamp MSS of IPv4 SYN packets. + Ping nodes immediately when receiving SIGALRM. + Optimise handling of select() returning <= 0. + Also clamp MSS of TCP over IPv6 packets. + Make MSS clamping configurable, but enabled by default. + Fix subnet-up/down scripts being called with an empty SUBNET. + Run subnet-up/down scripts for local MAC addresses as well. + Be liberal in accepting KEY_CHANGED/REQ_KEY/ANS_KEY requests. + Determine peer's reflexive address and port when exchanging keys. + Immediately exchange keys when establishing a meta connection. + Try to set DF bit on BSDs as well. + Update copyright notices. + Ensure peers with a meta connection always have our key. + Releasing 1.0.12. + +Version 1.0.11 November 01 2009 +------------------------------------------------------------------------ + +Guus Sliepen (16): + Fix a possible crash when sending the HUP signal. + Starting to work towards 1.0.11. + Handle weighted Subnets in switch and hub modes. + Clarify and increase level of log message about MTU probes to unreachable nodes. + Add dummy device. + Use uint32_t instead of long int for connection options. + Allow UDP packets with an address different from the corresponding TCP connection. + Always reply to MTU probes via UDP. + Make maxmtu equal to minmtu when fixing the path MTU to a node. + Forward packets to not directly reachable hosts via UDP if possible. + Use IP_DONTFRAGMENT instead of IP_MTU_DISCOVER on Windows. + Use WSAGetLastError() to determine cause of network errors on Windows. + Move socket error interpretation to utils.h. + Fast handoff of roaming MAC addresses. + Start a tinc service if it already exists. + Releasing 1.0.11. + +Michael Tokarev (1): + Remove localedir leftovers. + +Version 1.0.10 October 18 2009 +------------------------------------------------------------------------ + +Guus Sliepen (78): + Update documentation for git. + Consistently allocate device and iface variables on the heap. + Only send packets via UDP if UDP communication is possible. + Move free()s at the end om main() to the proper destructor functions. + Change flush_events() to expire_events(). + Add missing cleanup functions in close_network_connections(). + Use a global list to track outgoing connections. + Remove unused definitions from net.h. + Allow reading config files with CRLF endings on Unix systems. + Validate Name before using it in a filename when generating a keypair. + Disable old RSA keys when generating new ones. + Handle neighbor solicitation requests without link layer addresses. + Allow weight to be assigned to Subnets. + Update THANKS and copyright information. + Disable PMTUDiscovery in switch and hub modes. + Use a simple Random Early Drop algorithm in send_tcppacket(). + Handle UDP packets from different and ports than advertised. + If PMTUDiscovery is not set, do not forward packets via TCP unnecessarily. + Fix link to Mattias Nissler's tun/tap driver for MacOS/X. + Fix initialisation of packet decryption context broken by commit 3308d13e7e3bf20cfeaf6f2ab17228a9820cea66. + Use xrealloc instead of if(ptr) ptr = xmalloc(). + Add declaration for sockaddrcmp_noport(). + Use packet size before decompression to calculate path MTU. + Do not forward broadcast packets when TunnelServer is enabled. + Add ProcessPriority option. + Add some const where appropriate. + Properly set HMAC length for incoming packets. + Don't try to send MTU probes to unreachable nodes. + Remove pending MTU probe events when a node's reachability status changes. + Do not log errors when recvfrom() returns EAGAIN or EINTR. + Change level of some debug messages, zero pointer after freeing hostname. + Always remove a node from the UDP tree before freeing it. + Add xasprintf() and xvasprintf(). + Check the return value of fscanf() when reading a PID file. + Replace asprintf() by xasprintf(). + UNIX signal numbers start at 1. + Ensure tinc compiles with gcc -std=c99. + Convert bitfields to integers in a safe way. + Add the GPL license to the repository. + Another safe bitfield conversion. + Add support for iPhones and recent iPods. + Don't stat() on iPhone/iPod. + Put Subnet weight in a separate environment variable. + Allow PMTUDiscovery in switch and hub modes again. + Handle unicast packets larger than PMTU in switch mode. + Remove superfluous call to avl_delete(). + Apparently it's impolite to ask GCC to subtract two pointers. + Use only rand(), not random(). + Also do not use drand48(), it is not available on Windows. + Allow compiling for Windows XP and higher. + Remove dropin random() function, as it is not used anymore. + Use access() instead of stat() for checking whether scripts exist. + Raise default crypto algorithms to AES256 and SHA256. + Remove extra {. + Use a mutex to allow the TAP reader to process packets faster on Windows. + Raise default RSA key length to 2048 bits. + Send large packets we cannot handle properly via TCP. + Update copyright information. + Remove all occurences of $Id$. + Remove Ivo's old email addresses. + Update the address of the Free Software Foundation in all copyright headers. + K&R style braces. + Remove checkpoint tracing. + Drop support for localisation. + Add more authors to the copyright headers. + Update the NEWS. + Remove autogenerated files from EXTRA_DIST. + Don't disconnect clients in TunnelServer mode who send unauthorised ADD_SUBNETs. + Remove code duplication when checking ADD_EDGE/DEL_EDGE messages. + Revert "Raise default crypto algorithms to AES256 and SHA256." + Ensure that the texinfo manual can be converted to HTML. + Small updates to the documentation. + Use MTU probes to regularly ping other nodes over UDP. + Allow the cloning /dev/tap interface to be used on FreeBSD and NetBSD. + Remove debugging message when reading packets from a BSD device. + Include missing header. + Fix description of the WEIGHT environment variable. + Releasing 1.0.10. + +Michael Tokarev (17): + Allow tunnelserver to work with clients that have other peers. + Enable PMTUDiscovery only if BOTH sides wants it. + Rename setup_network_connections() and split out try_outgoing_connections() + Implement privilege dropping + bugfix: initialize pid (as read from pidfile) to zero + bugfix: move mlock to after detach() so it works for child, not parent + bugfix: chdir(/) after chroot + change error messages in droppriv code to match the rest + format 'not supported on this platform' error message + TunnelServer: Don't disconnect client on DEL_SUBNET too + ignore indirect edge registrations in tunnelserver mode + don't log every strange packet coming to the UDP port + Fix ans_key exchange in recent changes + tunnelserver: log which ADD_SUBNET was refused + cleanup setpriority thing to make it readable + try outgoing connections before chroot/drop_privs + Remove extra semicolon in my definition of setpriority() + +Florian Forster (2): + src/linux/device.c: Fix segfault when running without `--net'. + src/net_socket.c: Bind outgoing TCP sockets to `BindToAddress'. + +Borg (1): + Removed last gettext function. + +Version 1.0.9 December 26 2008 +------------------------------------------------------------------------ + +Guus Sliepen (18): + Handle SERVICE_CONTROL_INTERROGATE requests. Thanks to Carsten Ralle for noticing this. + Make sure the prefixlength of subnets is sane. + Fix reading configuration files that do not end with a newline. + Do not try to send REQ_KEY or ANS_KEY requests to unreachable nodes. + Prevent freeing a NULL pointer when a hostname is unresolvable. + Correct debug message. + Treat virtual network device as tap if Mode = switch or hub. + Use TUNIFHEAD by default on FreeBSD to make sure IPv6 works. + Make sure IPv6 sockets are IPv6 only. + Update Dutch translation. + Update copyright information. + Enable PMTU discovery by default. + Update documentation. + Update the manpage as well, and some whitespace to make its source more legible. + Handle broadcast and multicast packets in router mode. + Apply patch from Max Rijevski fixing a memory leak when closing connections. + Add missing parentheses in check for IPv4 multicast addresses. + Releasing 1.0.9. + +Version 1.0.8 May 16 2007 +------------------------------------------------------------------------ + +Guus Sliepen (8): + Apply patch from Scott Lamb preventing an infinite loop when sending SIGALRM. + Apply patch from Scott Lamb fixing some memory and resource leaks. + Close the proper filedescriptor (if it exists). + Apply patch from "dnk" making sockets non-blocking under Windows. + Make sure connection->name is never NULL. + Update dutch translation. + Don't free struct addrinfo too early. Spotted by Christian Cier-Zniewski. + Releasing 1.0.8. + +Version 1.0.7 January 05 2007 +------------------------------------------------------------------------ + +Guus Sliepen (7): + Use a ringbuffer in shared memory to transfer packets from the tapreader thread to the main thread. + Tapreader socket should be bound to localhost only. + Fix generic BSD tun device to write only the actual packet length. + rename() cannot replace existing files on Windows. + No things to do for the 1.0 branch except bugfixing. + Update copyright notices. + Releasing 1.0.7. + +Version 1.0.6 December 18 2006 +------------------------------------------------------------------------ + +Guus Sliepen (13): + Make sure resolved addressed for outgoing connections are freed, if there are any. + Search for lzo/lzo1x.h, lzo2/lzo1x.h and lzo1x.h. + When building the minimum spanning tree, make sure we start from a reachable node. + Use the correct next pointer. + Remove unnecessary stuff from configure.in. + Remove old Spanish translation. + Fix rule that creates html version of manpages. + Use standard autoconf macros instead of our own. + We do properly check for malloc and realloc. + Remove the test for linux/if_tun.h. + Do a simple test for linux/if_tun.h instead of no test at all. + Prevent compiler warnings about redefinition of EAI_FAMILY on FreeBSD 6.1. + Releasing 1.0.6. + +Version 1.0.5 November 14 2006 +------------------------------------------------------------------------ + +Guus Sliepen (32): + Prevent possible buffer overflows when using very large (>= 8192 bit) RSA keys. + Add alloca.h to the list of necessary header files. + Enable OpenSSL ENGINE, so crypto hardware gets used. Thanks to Andreas van Cranenburgh. + EVP_Cleanup() when quitting. + Apply patch from Scott Lamb unifying configuration of TCP socket options. + Apply patch from Scott Lamb adding an output buffer for the TCP sockets. + Make sure $NAME is set correctly when executing tinc-down script. + Missing #include. + Export flush_meta(). + Fix signedness compiler warnings. + Fix a bug in handling prefixlengths that are not a multiple of 4. + Update copyright notices, remove Ivo's email address. + Restore length of the original packet in send_udppacket(). + Use memcpy() to copy sockaddrs returned by getaddrinfo(). + Add generic host-up and host-down scripts. + Do not break strict aliasing of status_t structs. + Fix format string warnings. + Remove unused variables. + Remove unused parameter from maskcmp(). + Remove unused variable. + memcpy() addresses from packet headers before calling the lookup functions. + The "active" bit in node.status is not used. + Added graph dumping ability based on Markus Goetz's patch. + popen() requires pclose(). + Support and autodetect LZO version 2.0 and later. + Support and autodetect LZO version 2.0 and later. + Document GraphDumpFile option. + Update Dutch translation. + Nodes use events, so event system should be initialised first and destroyed last. + When deleting an entire tree, start at head, not at root. + EWOULDBLOCK does not exist on platforms without O_NONBLOCK + Releasing 1.0.5. + +Version 1.0.4 May 04 2005 +------------------------------------------------------------------------ + +Guus Sliepen (17): + Make sure broadcast packet reach the local network interface. + Fix splay tree code. + subnet-up/down hooks + subnet-up/down hooks, use list_t for the todo list. + Small fix. + Free memory used by connection_t after it is deleted from the connection tree. + Use the proper free function. + Correct size argument for strncat(). + Nodes should only be in the node_udp_tree if they are reachable. + Don't try to add a non-existing node back to the node_udp_tree. + Remove unused (and potentially segfaulting) net2str() call. + Be on the safe side with initialisation of c->name. + Searching through splay trees may change the tree variable. + Several splay tree fixes. + Describe subnet-up/down scripts in documentation. + Update copyright notices. + Releasing 1.0.4. + +Version 1.0.3 November 11 2004 +------------------------------------------------------------------------ + +Guus Sliepen (77): + Removed items in TODO list that are already implemented. Only two items + Applied patch from Jamie Briggs for bash2 conformance. + Added another semicolon for bash2 compliance (thanks to Jamie Briggs) + Adding even more stuff from the CABAL branch. + Synchronise HEAD with CABAL branch. + This will become 2.0. + Some device.c files weren't synchronised. + Makevars file was accidentily removed. + Forgot to synchronise po/ directory... + Add description of new authentication scheme. + Add Opaque option which prevent information from being forwarded to certain nodes. + Replace Opaque and Strict options with a TunnelServer option. + Complain if pid file cannot be created. + Read MaxTimeout from tinc.conf like the manpage says. + Missing space between words. + Don't retry if configuration is wrong from the beginning. + Fix proxy-neighborsolicitation. + Code beautification, start of multicast support. + Forget multicast. Always inline some function. + Let tinc figure out the exact MTU of the link. + More sensible name, and try to set PMTU discovery on IPv6 sockets as well. + Describe the TunnelServer and PMTUDiscovery options. + Better name, show probed MTU in dump. + Improvements for PMTU discovery and IPv4 packet fragmentation. + Missing definitions. + Small fixes for PMTU discovery. + Don't forget to update destination MAC address. + Small updates. + Remove autogen.sh, the autoreconf program does exactly that. + Replace cvs-clean with a much better svn-clean. + Remove CVS related cruft. + Eat trailing whitespace in config files. + Only read our public key if it wasn't already in the private key file. + Updating dutch translation. + Even better svn-clean command. + Applied Martin Kihlgren's IdentityGenerosity patch, + Fix declaration of update_node_address(). + Use Subversion to create ChangeLog, better svn-clean rule. + Revert Martin Kihlgren's patch, it doesn't work the way it should. + Move CABAL branch to its rightful place: the trunk. + Update copyrights, links, email addresses and let Subversion update $Id$ keywords. + Increase MTU by 4 bytes to allow VLAN tagged Ethernet frames in hub and switch mode. + Clean up environment after executing scripts. + Handle timeouts during connecting the same way as other errors. + Added UML network socket handling. + Don't set $INTERFACE automatically, don't quit on EINTR/EAGAIN. + Marking potential late packets was in the wrong place. + Remove duplicate #include "system.h" + Move all #ifdef HAVE_HEADER_H #include to have.h, + Fix several #includes. + strndupa() is too arcane for some environments. + Allow tinc to work with the latest TAP-Win32 driver. + Correct return value. + Don't let tinc service depend on NDIS component. + Support alternative tun/tap driver from http://www-user.rhrk.uni-kl.de/~nissler/tuntap/ + Generic device driver for *BSD and MacOS/X + static + Check for sys/uio.h, net/if_tun.h and net/if_tap.h + Don't include .svn directory in sample configuration. + Splay trees. + Hoopjumping to get the default directories in the manuals properly. + Update to make it compile again. + Fixed another bug in late packet handling. + Hopefully this really fixes late packet handling. + Missing check for NULL-pointer. + Use the generic BSD tun/tap code. + Fix order of arguments for tar. + Let compiler decide when to inline. + Support tunneling IPv6 on Solaris. + Add BlockingTCP option, useful when using TCPOnly on slow or congested links. + Update documentation. + Set BSD tuns to broadcast mode. On OpenBSD, this enables IPv6 on the tun device! + Remove duplication. + Updated dutch translation. + Short readme about how to compile tinc from a Subversion checkout. + Add more people who have contributed to tinc. + Releasing 1.0.3. + +Ivo Timmermans (52): + Check for __gmpz_powm for libgmp3. + Changed version number to 1.0pre3. + Autogenerated by gettextize. + Bring head revision up to date with cabal (try #3) + Add check for the syslog function + Generalized error handling functions + Add all the new files to the sources list for the utility library + New function: xalloc_and_zero() + Generalized list and hash handling functions + First try to create a graphical frontend for tinc configuration + Updating HEAD branch #1; removing obsolete files. + Updating HEAD branch #2; removing debian/ dir. + Updating HEAD branch #3; more obsolete files removed. + Updating HEAD branch #4; Merging CABAL -> HEAD. + Updating HEAD branch #5; Last files from CABAL. + Ok, I forgot these ;) + More updates + More... + Last bits (hopefully) + Main pokey interface files. + Pokey interface definition + Write src/pokey/Makefile + Also compile in pokey/ + Remove debug level declaration + Update copyright info + Remove debug_lvl + New logging system to replace syslog() calls with a generic function. + Rename log_message to log + Add syslog() wrapper + Add syslog wrapper + Some magic + Added priority definitions from syslog.h + log_default_hook was renamed to log_default + Added prototype for log_syslog + Use logging.h instead of syslog.h + Compile in logging.c + Things to ignore... + Use new logging system + Include logging.h + Renamed libvpn to libtinc + Rename libvpn to libtinc + ... + Print newline when writing to stderr + *** empty log message *** + Moving files, first attempt at gcrypt compatibility, more interface + Commit diff test + Another file moved; random interface stuff. + Callbacks + Moved event.c/h + test + test 2 + Hm. + +Wessel Dankers (5): + Initial revision. Lots of loose ends, not usable yet. + added bit on config file, split up sections, added Id: tag + Added extra bit about keys. + More about keys + This file is now only in the CABAL revision. + +cvs2svn (1): + This commit was generated by cvs2svn to compensate for changes in r1352, + +Version 1.0.2 November 08 2003 +------------------------------------------------------------------------ + +Guus Sliepen (47): + Simplify fake getname/addrinfo() functions, possibly fixing freeing a NULL pointer. + stat() batch files under Windows. + Don't getsockopt() SO_ERROR. We get the error from send()/recv() anyway. + Fix fake getnameinfo() and check more arguments. + Fix --logfile under Windows. + Use the event log under Windows. + Compilation fix. + Do what the SDK documentation tells. + If we're not in main_loop() and the service is stopped, exit immediately. + Allow tinc to handle unknown type addresses from other tinc daemons. + Don't overwrite the first " when installing a service. + Add checkpoints. + When purging nodes, only delete them if nobody references them anymore. + Remove debug message. + Add license exception from Markus Oberhumer. + Remove old edges from unreachable nodes to us. This prevents the hosts/NAME-up + We don't have to tell GCC how to cast. + Prevent multiple inclusions. + Remove pidfile when exitting. + Update translations. + Check for short packets from the tun/tap device and from other tinc daemons. + Generate keys with 0x10001 as public exponent, which has less prime factors + Better length checks. + Copy structs from packets to the stack before using them, to prevent + const + Ethernet protocol types. + Unused variable in struct. + Don't confuse users with "Address family not supported" warnings. + Use CPPFLAGS, LDFLAGS and LIBS as appropiate. + PIDs are of type pid_t, and use %ld when reading/writing them to the pidfile. + Make sure type of AF_UNKNOWN is sa_family_t. + Forgot to #include "xalloc.h" + Update missing definitions, structs describing headers get __packed__ attribute. + Missing declaration. + Set media status for newer TAP-Win32 driver. + Some platforms don't know sa_family_t or define it other than uint16_t. + Update documentation. + Fix ASCII art. + Check return value of EVP_* functions, and check if length before en/decryption + Check all EVP_ function calls. + Parentheses in the wrong spots. + Fix bug that could lead to an assertion failure in libcrypto when multiple + Small fixes in documentation. + Fix another bug in meta.c. + Update dutch translation. + Add missing definitions. + Release notes for 1.0.2 + +Version 1.0.1 August 14 2003 +------------------------------------------------------------------------ + +Guus Sliepen (24): + Windows uses backslashes... + Tell windows to be patient. + Remove unused stuff from doc/. + Correct error message when remote host closed connection. + Simplify execute_script(). It will probably work under Windows as well. + Allow empty lines in config files. + Make rule for sample-config.tar.gz. + Readd quotes. + Typo. + Better error messages under Windows. + Log error first, try to close later. + Quote when needed and don't try stuff that doesn't work under Windows. + Under Windows, the installation directory can be found in the registry. + Better error checking and reporting. + Small things. + Simpler checking of permissions on private RSA key and other fixes. + Check for fchmod(). + Only system() needs script name quoted. + Update documentation. + Add a description for the Service control panel. + Updated dutch translation. + Small fixes. + Fix permissions check for rsa_key.priv. + Update. + +Version 1.0 August 08 2003 +------------------------------------------------------------------------ + +Guus Sliepen (111): + Thank some more people. + Run graph() after edge_del() when updating an edge. + Add documentation for BindToAddress. + Fix PriorityInheritance. + PrivateKeyFile instead of PrivateKey. + Run graph algorithm when replacing a second connection from the same host + Add $NAME for tinc-up/down scripts. + - Fix indentation in some places. + Various fixes for autoconf and OpenSSL 0.9.7 and a missing header. + Make sure send_meta() writes everything. + Typo. + - Avoid memory leak caused by OpenSSL 0.9.7a. + - Speed up checksumming + Don't copy more than necessary. + Checksums must also work for uneven number of bytes. + HUP signal now closes connections to hosts if their host config file is + Better handling of late packets. + Make sure outgoing_t is completely freed. + - Per-node EVP_CIPHER_CTX to avoid initialisation overhead. + Small fixes to make LZO compression work. + Small fixes. + Fix links. + Fix warning and add missing checks for LZO library. + Call make_names() before doing anything else. + If we have a Linux tun/tap device and we are in router mode, open the device + AddressFamily is "any" by default. + Remove mymac stuff from device.c. + Fixes from Wessel Danker's libavl. + More braces to make gcc happy. + Update documentation. + Update dutch translation. + Typo and conversion to UTF-8. + There are two lzo compression levels. + Really make tinc default to any addressfamily. + This subtle pointer arithmetic thingy is (I'm very sure of it) the cause + - simplify configure.in + Check for IPv6 header files. + Define logger(), cleans up source code and allows us to write log entries + Sprinkling the source with static and attributes. + Provide all missing IPv6 definitions in lib/ipv6.h. + Actually add ipv6.h. + More missing definitions. + More missing IPv6 definitions and autoconf checks to make sure it compiles + Simplify logging, update copyrights and some minor cleanups. + Update copyrights. + Removing distribution specific files from CVS. + Format string checking for logger(). + Export mymac. + Make use of the CIPE driver. Woohoo, tinc for Windows! + Windows headers declare a struct interface somewhere. + Big header file cleanup: everything that has to do with standard system + Even more missing definitions. + Remove all #ifndefs from route.c + Update all device.c files. + Check for ethernet/ipv4/ipv6 related structures. + Use iface instead of interface because it might already be declared in + Oops. + No UNIX style permissions under Windows. + Be consistent. + Oops. + Check for sys/mman.h. + Use functions from logger.c + Copy cygwin driver to mingw directory. It doesn't work (yet). + Add section about configuring Cygwin and CIPE on Windows. + Option to specify pidfile location. + Use bools and enums where appropriate. + Run setup_device() after parsing configuration but before claiming we're ready. + Don't initialise a CIPHER_CTX if cipher == NULL. + Sprinkle around a lot of const and some C99 initialisers. + More generic handling of tap device under Windows. + More checks for missing functions. + Fix compile errors and warnings. + Update dutch translation and make sure all device drivers are included in + Update configure scripts. + Make sure it works. + Make sure (at least) the MinGW device driver works. + Native Windows support. + Cleanups. + Update documentation and remove stuff that's too outdated. + Remove doc/es/ and src/device.c from the distribution. + No C99 initialisers, gcc 2.95.3 doesn't like it. + Replacement for stdbool.h + Prevent definitions from messing up attributes. + Check if the compiler knows about the __malloc__ attribute. + Wrong argument. + Remove forgotten braces. + No easy way to properly detect header files... + Woops! + Wrong function... + Prevent system headers from including our own headers. + Allow whitespace in values. + Oops. + Windows has no symbolic links as we know it. + When compiling with MinGW, link with ws2_32. + Install tinc as a service under Windows (MinGW). Remove cleanup_and_exit(), + Error messages. + Cleanups and error messages. + Missing include. + Oops. + Updated dutch translation. + Explain how tinc detaches and how it is "killed" under Windows. + Typo and another thing to think about. + Clean up last part of main(). + Old gcc compilers don't like declarations in the middle of a function. + Cygwin needs windows.h. + Keep Windows happy. + Remove newlines from log messages. + Update dutch translation + Simplify translation + Use our own port when connecting to ourself. + Sync CABAL branch with release-1_0 branch. + +Ivo Timmermans (2): + Fix saving of debug level for startup level 0 + Call RSA_blinding_on(), as advised in the paper on + +Wessel Dankers (1): + its: Engels voor "van het" - 3e persoon enkelvoud, genitief, onzijdig + +Version 1.0pre8 September 16 2002 +------------------------------------------------------------------------ + +Guus Sliepen (73): + Support for MaxOS/X. + Add BindToAddress variable, similar to the late BindToIP. + Added Nick Patavalis for his RedHat package. + Informative log message if execl() failed. + Fix very stupid bug in node_del(), which might have caused corruption of + Only purge once when there are no more connections. + Support RSA_PUBKEYs (as opposed to RSAPublicKeys) so tinc accepts + Make it work correctly with NetBSD tun device. + Use correct includes on NetBSD. + Cleanup: + Use inttypes.h instead of stdint.h. + - netinet/* include files depend on netinet/in_systm.h. + Added Darwin (MacOS/X) tun device handling. + Use darwin/device.c when compiling on MacOS/X. + Include darwin/device.c in distribution. + Autoconf cleanup. Works for both 2.13 and 2.53, although running autoconf + Add configuration details for NetBSD and Darwin (MacOS/X). + Reset listen_sockets after SIGHUP. + Update comments about IPv6 autoconfiguration. + s/sliepen.warande.net/sliepen.eu.org/g + Fix for prefixlengths of 32 (IPv4) and 128 (IPv6) bits. + Allow list of environment variables to be passed to execute_script(). + Allow identical subnets from different owners. + Clear subnets before using them. + Started port to Cygwin. + Added stub device.c for Cygwin. + Include complete fake-getname/addrinfo from OpenSSH. + Allow tincd to be locked into main memory. + Don't bother to chown, and correctly document ConnectTo. + Added support for raw sockets. This can be used instead of tun/tap devices. + Gettext 1.11.5 compatibility. + Check for ranlib. + Replacement for the current routing algorithm. + Make sure setlocale() is available. + Drop graph and edge stuff. Use new node stuff instead. + A reachable node is always more preferable to an unreachable one... + Woops. + Reduce KEY_CHANGED traffic. + Prevent looping DEL_NODE/ADD_NODE messages after a node disconnects. + Don't forget to set prevhop to myself for new connections. + Just ignore wrong ADD_NODEs instead of replying with a DEL_NODE, in the + Revert to edge and graph stuff. This time, use a directed graph. + Small fixes. + Generalized request broadcasting/forwarding. + Updated dutch translation. + Small updates. + Run autopoint and libtoolize before creating initial makefiles. + Add missing headers. + Typo. + Only reset seqno's when a key is sent or received. + Remove global edge_tree. + edge_weight_compare() shouldn't rely on edge_compare(). + Reset the *correct* seqnos. + Fix MST algorithm. + Why don't these connection_t's get cleaned up? + Cleanups: + Switch to K&R style indentation. + Switch to K&R style indentation. + Remove redundant spaces. + Let GCC check format string and arguments of send_request(). + Fix compiler warnings. + Clean up after indent. + Link with libintl if necessary. + Fix placement of #include "config.h" + Make sure malloc() is declared. + What was I thinking? + MacOS/X needs #define _P1003_1B_VISIBLE in order to use mlockall(). + port_t isn't used anymore and conflicts with MacOS/X headers. + Small fixes so tinc compiles out of the box on SunOS 5.8 + Updated dutch translation. + Use /dev/net/tun as default for tun/tap device under Linux. + Update documentation. + Remarks about 1.0pre8 release. + +Ivo Timmermans (9): + Put #ifndef checks for HAVE_RAND_PSEUDO_BYTES in the correct places. + Typo + OSX support + getnameinfo fixes + Add /sw/{include,lib} to search paths if they exist + Include a few more header files + Include netbsd's device.c in make dist + Added Alessandro Gatti + Added AM_MAINTAINER_MODE + +Wessel Dankers (1): + This should work much better. + +Version 1.0pre7 April 09 2002 +------------------------------------------------------------------------ + +Guus Sliepen (9): + Make configure --help output look nicer. + Don't check_network_activity() if select() is interrupted by a signal. + check_rsa() is broken, I don't know why, just remove it for now. + Fix maskcheck() and maskcmp(). + Automake forgets about depcomp, remind it. + masklength is better known as prefixlength. + masklength is better known as prefixlength + Updated dutch translation. + Remarks about 1.0pre7 release. + +Version 1.0pre6 March 27 2002 +------------------------------------------------------------------------ + +Guus Sliepen (91): + Forgot to merge new files from pre5. + Last bits of the merger. + Sensible defaults for $INTERFACE. + - If no PrivateKeyFile is specified, /etc/tinc/netname/rsa_key.priv is assumed. + Small fix. + Added support for packet compression, thanks to Mark Glines. + Don't use sa_sigaction (which NetBSD doesn't like) at all if we don't use siginfo. + Get rid of sys/signal.h. + Added device.c for NetBSD, actually a copy of the OpenBSD one. + Add check for NetBSD. + - Non-blocking connect()s. + Fix segfault when receiving HUP signal. + Use AF_UNSPEC for listening sockets if AddressFamily = any. + Forward packets in router mode. + Fix maskcmp() and maskcpy(). + Cache results of lookup_subnet_...(). + Protocol now also exchanges cipher/digest/maclength/compression for the + Preserve inpkt->len, needed for broadcasts. + - Use gai_strerror() where appropriate + - Change SA_LEN to SALEN, former one is already defined on some platforms. + Tweaking IPv6 support. + Allow multiple listening sockets. + Fix send_request() bug. + Make BindToInterface work. + Fix listening sockets. + If "PriorityInheritance = yes" is specified in tinc.conf, the value of the + Create/bind TCP and UDP listening sockets in pairs. + Updated documentation. + Updated dutch translation. + - Global time_t now, so that we don't have to call time() too often. + Document and clean up MAC address expiry. + Woops. + Check if BindToDevice and PriorityInheritance are supported. + Fix forwarding of IPv6 packets. + po/POTFILES and po/Makefile should not be generated by configure. + Autodetect $MAKE/gmake/make. + Small fixes to improve portability. + Don't retry to make outgoing connections when exitting. + Cleanups, spelling fixes, allow symbol names for signals (-k option), + prune_connections() before build_fdset(). + Try to reply to neighbor solicitation requests. + New strategy: forward icmp6 neighbor solicitations to intended target. + Simplified implementation of Kruskal's minimum spanning tree algorithm. + Packet sequence number/authentication warnings only if debug_lvl >= 5. + Remove silly cache thingy. + Put #ifdef NEIGHBORSOL around corresponding code. + Revert changes to Kruskal's algo. + Neighbor solicitation requests now work (I think). + Oops, don't forget to actually put the checksum in the response packet. + Different way of detecting neighbor solicitation requests. + Typo. + Unmap v4mapped sockaddrs. + Only unmap IPv6 addresses. + #define s6_addr32, needed for FreeBSD. + Fix #define s6_addr32. + Remember sockaddrs of listening sockets, use appropriate one when sending + Cleanup. + Don't use s6_addr[16|32] anymore. + Updated dutch translation. + Updated SSSP algorithm to automatically detect indirect links (if a node uses + Put a break on requests that run around in circles. + - Added support for jumbograms. + Fix add_edge_h(). + Fix compiler warnings, strictly use long int and %lx for options. + send_ack() was broken. + free() request strings when deleting past requests from the tree. + Don't run graph algorithms if no edge is deleted in terminate_connection(). + Reset retry timeout when receiving the first PONG, not right after receiving the ACK. + Don't try to execute scripts unless they exist. + Execute hosts/name-up when a node becomes reachable, and hosts/name-down + Set $INTERFACE correctly when using ethertap while compiled with tun/tap support. + Updated dutch translation. + Respect type field. + OpenBSD tun device uses address family number instead of Ethernet type. + Configuration variables were still handled case sensitively. + Set myself->status.reachable. + Updated documentation. + Tell a little bit more about security. + Send REQ_KEY only once until ANS_KEY has arrived. + Fix execute_script(). + Small correction. + Merge do_prune() with build_fdset(). Probably fixes the invalid filedescriptor error. + Extend list_t with the number of elements in the list. + Limit the amount of packets in a queue to 8. + Small updates. + Remove cruft. + Recent automake uses $(AMTAR) instead of $(TAR) + Remove symlink to device.c when doing a make dist. + Fix format strings. + Update dutch translation. + Update with information about the pre6 release. + +Version 1.0pre5 February 10 2002 +------------------------------------------------------------------------ + +Guus Sliepen (109): + Small fixes to allow correct compilation under FreeBSD (tested with 4.3) + Make sure Solaris is happy too. + Fix subnet_lookup() for overlapping subnets. Needs rethinking. + Added proxy-arp support. No more ifconfig -arp needed. Works like a charm + - tinc can now act as a switch or a hub too (as opposed to a router only) + Changed some stuff to allow correct generation of po/Makefile after a + Updated dutch translation. + - This oneliner removes the need for ifconfig tap? hw ether fe:fd:0:0:0:0 + Fix bug where lookup_subnet_ipv4() could go into an infinite loop. + You can now put an option "Mode" in tinc.conf, and choose from: + Add missing? counting of total_socket_in. + Log and warn about duplicate subnet_add()'s for the same subnet. + Fixes to make switching work between hosts that have no meta-connection. + Save configure cache more often. + Changed drastically because it didn't work correctly: + Only reset seconds_till_retry when we activate the outgoing connection. + Woops - big bug in send_key_changed fixed. + - Solaris compile fixes + Check for and add -ldl. + Remove #warnings I used for debugging stuff. + Reinstated search for if_tun.h in kernel source tree, because apparently + Spanish translation removed. Nobody maintains it, and it is severely + ABOUT-NLS is created by autogen.sh. + Don't build Spanish translation. + Execute tinc-down BEFORE tap device is closed. This is a. more symmetric + es.po revived. + Also remove po/Makefile.in.in, which is generated by autogen.sh. + Log error if two hosts connect with same IP/port tuple. + Fix gcc 3.0 warnings. + Check for dlopen in standard libraries first (needed for DEC OSF). + It appears that autogen.sh doesn't like es.po if it isn't mentioned in + Update of RedHat build scripts. + Dutch translation updated. + More items marked as done. + Fix printf format bug. + Fix compiler warning. + Check for all potential duplicate entries in the id tree. + - Always use instead of just + Don't load table of verbose OpenSSL errormessages. + Correct inclusion of standard if_tun.h header file. + Split connection list into two lists: + Correctly use the active_tree. + Remove all unnecessary status.meta and status.active checks. + Added purge_tree for connection_t's which are no longer in the connection, + Updated terminate_connection() so you can choose if DEL_HOSTs should be + Always close all sockets in terminate_connection(). + Woohoo! tinc now compiles, runs and actually *works* on Solaris! + Started writing a document about how daemons connect to each other. + Described problem in more detail. + Small update. + Correctie. + Written down a possible solution. + Discuss how sending ADD_EDGEs would be better than sending ADD_HOSTs. + More on edges. + Don't use %m in fprintf(). + Write public key to rsa_key.pub instead of rsa_key.priv (if not host + The val variable in a config_t is never used as a long. + Explicitly log which type of tunnel device is used. + Don't send DEL_HOSTs when !status.meta + Fix signed comparison bug in lookup_subnet_ipv4(). + Remove IndirectData support for now, new implementation will be added + Revised reconnection mechanism, always try out all ConnectTo lines. + Optional signal number for -k option. + config_t* is a const parameter in get_config_val(). + - Try old TUN/TAP ioctl() request if the one from if_tun.h fails. + Not only keep track of nexthop, but also of lastbutonehop. If destination cl + Show next- and lastbutonehop when dumping connectionlist to syslog. + Try next connectto instead of the same over and over. + Fill in next- and lastbutonehop for myself. + - Renamed lastbutonehop to prevhop. + Fix bug where tinc would crash because of a portscan or a connection from a + - Use ping timeout mechanism to close connections that don't authenticate + Fix bug when dropping an old connection in favour of a new one from the + Updated dutch translation. + Started implementing doc/CONNECTIVITY. + Small corrections. + Further implementation of doc/CONNECTIVITY. connection.[ch] is now split into a + Removed everything from connection.c that has already been moved to node.c and + Revamp configuration handling: + More updates to new node/vertex/connection combo. + - Split tap device stuff out of net.[ch] + Added FreeBSD tap device handling. + Solaris tun device handling cleaned up a bit and added. + Forgot to remove some old #ifdef stuff. + Added OpenBSD tun device handling. Untested though. + Forgot the tun specific stuff. + Support new files (node/vertex/device.[ch]) and OpenBSD. + Big bad commit: + Make sure everything links. + Various small fixes to make tinc runnable again. + What was I thinking? s/vertex/edge/g. + - More s/vertex/edge/g + - More changes needed for Kruskal's algorithm + Working version of Kruskal's algorithm. The running time is very bad though. + Various fixes, tinc is now somewhat capable of actually working again. + More updates to protocol handlers and reimplemented terminate_connection(). + - Small fixes to graph algorithms + Don't forget to read public RSA key when making an outgoing connection. + Show cfg->variable instead of cfg->value when complaining about wrong type. + Avoid connecting to another node twice, and check name of outgoing connections. + Some very small fixes + Use PEM functions as suggested by OpenSSL docs. + Several bugfixes. + *** empty log message *** + Be liberal in what you accept: allow unknown edges to be deleted. + Correctly check if subnet owner exists. + Various fixes needed for Solaris. + More fixes for Solaris. + Merging of the entire pre5 branch. + +Ivo Timmermans (32): + New make target: `make release' + Changed version number to 1.0-cvs + Don't distribute autogen.sh in a release + Don't include the debian/ dir in a release + Small fix to make it compile again + Killing tincd with SIGINT causes it to toggle between the current + Check for getaddrinfo + Check for getnameinfo, gai_strerror, freeaddrinfo + Credit OpenSSH + Check for struct addrinfo + Deprecated get_config_ip and get_config_port + Use struct addrinfo in connection_t to hold all host data such as IP + Changed prototype for lookup_connection to use struct addrinfo + Changed lookup_connection to use struct addrinfo + Removed definitions of ipv4_t, ipv6_t, port_t + Obsoleted all IP types in favor of struct addrinfo + Changed to use struct addrinfo where needed. + get_config_{ip,port} removed. + Don't compile/link netutl.c. + Obsoleted. + Don't include netutl.h. + (re)added port to struct node_t + Added HAVE_STRUCT_ADDRINFO + Added dropin replacements for get*info and helper functions. + First part of rewriting things to use struct addrinfo. + lookup_node_udp changed. + Don't include netutl.h. + route_ipv4 and route_ipv6 replaced by route_ip. + get_config_subnet needs to be fixed. + Fixed silly typo: "np" instead of "no" + Don't include netutl.h. + Conversion to struct addrinfo is almost complete for this file. + +Wessel Dankers (1): + make is not always GNU make. + +Version 1.0pre4 May 25 2001 +------------------------------------------------------------------------ + +Guus Sliepen (97): + Porting to FreeBSD: + - Added balanced tree management stuff as well. (It is not finished yet.) + - Simplified do_detach + - Removed stray @INCLUDE@ (how did that get there?) + - Fixed searching + - Implemented deletions + - Fix tree head/tail upon insertion + - Fixed a lot of small things. Tested everything except deletions. + - Deletion also works now. + - Small fixes + - Integrate rbl trees into tinc. + - Proper initialization of rbltree structures. + - Various small fixes. + - More fixes. + - Check for NULL tree->delete callback + - Cleaned up and checked for some more NULL pointers in rbl.c + - Write pidfile AFTER detaching... + - No more %as. + - Work with the correct key buffer in ans_key_h + - More porting to FreeBSD and Solaris. + - Fixed all (except 2) compiler warnings gcc -Wall gave. + - #include instead of + - Don't link with -ldl anymore + Another big & bad commit: + - Added Armijn to the list + - Added daemon() replacement. + - Use only one socket for all UDP traffic (for compatibility) + - Don't even think about using sscanf with %as anymore + - AVL tree routines: faster than RBL, and also more stable. + - Doubled size of trace buffer for easier debugging. + - Let user choose whether keys are in the config files or separate + - Updated dutch translation. + - Check and follow symlinks in is_safe_path + - Changed license of AVL tree library to GPL. + - Updated manual pages. + - Updated texinfo manual. + - Typo. + - Changed list routines to give it the same look'n'feel as the rbl and + - Reinstated a queue for outgoing packets. + - Added header file for route.c. The routing routines in it are not used + - Description of protocol and authentication updated. + - It's 2001, all copyright notices are updated. + - Fixed IPv6 subnet lookup routine. + - Added indirectdata and tcponly functionality. + - Squashed another nasty bug. + - Sign was wrong in search_closest_smaller/greater + - Cleaned up subnet_t + - Only send out DEL_HOSTs for hosts with a meta connection + Added sample configuration directory. + - Copy entire sample-config directory to /etc/tinc/example upon installing. + - Allow ASN1 style keys to be in the config files. + FreeBSD compile fixes (thanks to XeF4) + Fix memory leak in avl_insert() if item was already inserted. + Updated dutch translation. + Removed another local definition of the variable "errno" + Added .cvsignore files to get rid of warnings and prevent autogenerated + Ignore file for src/ + - Updated CVS_CREATED to remove intl/ directory and some other + Added description of the proposed new authentication scheme. + Corrected check for errors after read() calls. + Add missing \n. + Free node->data and node, not node->data twice. + Copy packets before putting them in the queue. + Encrypt network packets in CBC mode instead of CFB mode. + Implemented new authentication scheme from doc/SECURITY2. + Added process.c to the translated files. + - Make sure METAKEY is smaller than the modulus of the RSA key + Don't forget to reconnect if outgoing connection fails during + - Fixed Interface option (untested) + Removed lots of compiler warnings. + Removed compiler warning. + Various small fixes. + Added explaination of our key exchange using RSA encryption. + - route.c is now used to determine destination + Updated translation. + Added a description of what is going on in net.c and route.c, and how + Fixed a race condition triggered by receive_meta() and the new + Fixed bug in setup_signals() that would make tinc die when unexpected + Ignore alarm signals if we do not need to respond to them. + Check indirectdata option before forwarding certain requests. + Depend on new ssl package and install alias for universal TUN/TAP module. + Correctly cycle through ConnectTo variables. + - s/ip_t/ipv4_t/g + - Make sure correct information is supplied for both old kernels (with + More revisions to the documentation: + Changed URL from kernelnotes.org to linuxdoc.org. + Add randomness to PING/PONG packets to prevent crypto attacks on quiet + Since this is incompatible with some earlier versions, PROT_CURRENT is + All features for 1.0 are implemented now, we just have to check the + Only send key_changed if it was previously requested. + Small fixes: + Small corrections to the manuals. + With recent kernels the tun device file is located in /dev/net. + TCPonly now works (in a relatively clean way too). + Merged PROTOCOL, NETWORK and SECURITY2 with the texinfo manual. + Documents are merged. Now we only need to check the ports and the TCPonly + Fix sample configuration to show keys in PEM format and correct tapdevice. + +Ivo Timmermans (88): + Add a check for openssl that accepts explicit file locations. + Identify version as 1.0pre4-cvs + Better checks for OpenSSL. I think it can now detect almost all conceivable installations. + Oops, small error. + Get rid of the annoying empty line + Also check for rand.h and err.h. If any of these files does not + Also check for sha.h. + Use the HAVE_OPENSSL_xxx_H defined from m4/openssl.m4 during + Let the output from an executed script in execute_script() go to + List management and manipulation routines. + Keep a list of running children, and in each loop in main_loop(), + Move all process-related functions into process.c. + New function: xmalloc_and_zero, which initialises the allocated memory + Delete struct ifr + Move more functions from tincd.c into process.c. + Use proper prototypes. + Added this release + More function and header checks + Also include process.h + Get rid of all libtool references at once. libtool was only used by + Honor the --localstatedir option to configure, instead of hardcoded /var. + Add more checks to ensure that filedescriptors are right in + Declare fd. + Do not use the C library's daemon() call. + Do not check for the daemon() system call + Do not attempt to retreive ChangeLog information only from the CABAL + Set localstatedir to /var + Use cvs2cl instead of rcs2log to generate the ChangeLog. + Set CFLAGS to -O2 -Wall when running configure + Alter CFLAGS, somehow INCLUDES doesn't propagate properly. Still + Set errno to 0 before trying to kill the other process. + Explain how to tell configure where OpenSSL lives. + Call autogen.sh instead of configure alone; and make cvs-clean instead + Add default tinc-up and tinc-down scripts for a Debian system. These + Updated Spanish translation, provided by Enrique Zanardi. + Give an error message if daemon() failed. + Check for the function strsignal, and define it to "" if it is not + Sort items to either 1.0 or future release goals. + Use sigaction to set signal handlers, the previous commit (1.1.2.16) + Save RSA public and private keys to a separate file, instead of + dropin.c/h contain a set of drop-in replacements for non-standard C + Check for get_current_dir_name. There is a replacement function in + Added a check for a scanf that knows about %as. + Implemented a readline() function that will read an entire line into a + xstrdup now takes a const pointer as an argument. + Use readline() in read_config_file() instead of fgets. + Also free the pointer returned by readline(). + Updated Dutch translation + Implemented is_safe_path, and extended ask_and_safe_open. + Read the PEM file pointed to by the configuration directive + The file is safe if it doesn't exist. + In readline(): initialise the line to zero length; + Better error checking when reading the RSA private key. + Avoid printing duplicate messages from read_rsa_keys + New function read_rsa_public_key(); + All full stops have two spaces after them. (Silly commit, I know.) + Tagged `Storing private key in separate file' as done. + readline() accepts two extra parameters, buf and buflen, to avoid + Use buffer instead of line in read_config_file(), line may be assigned + Stated that distributing executables linked with OpenSSL is permitted + Include COPYING.README in the distribution. + Added documentation merger + Sort configuration directives + Option -d accepts an argument to set the debug level immediately. + Massive long awaited documentation update. It's not finished yet, + Oops. I did some VERY wrong things with readline(). Fixed now. + Tiny bits of code beautifying + Install a file in /etc/modutils/tinc, containing all necessary aliases + Ported it back to /bin/sh. + Give a warning about having to re-create the keys + Re-introduced MyVirtualIP and VpnMask, as dummy options. + Various small changes. + Include autogen.sh (needed for the Debian package). + Forget router.c + Added lint target, requires lclint. + Fix error reporting of read_config + Set Architecture to `any' + Change version to 1.0pre4 + Second draft of the release notes + Merged documentation with various updates I had lying around + Get the Debian changelog up to date + Get the PO files up to date with the current source + Fixed some errors + Distribute the sample config as a .tar.gz + Unpack sample-config.tar.gz when installing + More files to ignore in CVS + tinc_TUNTAP now substitutes the values outside the AC_CACHE_CHECK + Authentication done + +Wessel Dankers (1): + Important bugfix in avl_insert_before() and avl_insert_after() + +Version 1.0pre3 November 09 2000 +------------------------------------------------------------------------ + +Guus Sliepen (119): + Debian init.d script automatically sets tap device's MTU to 1448 now. + First step for implementation of the "indirectdata" directive. This should + If we have "indirectdata" flag set, we only send data to our uplink. + Large cleanup: + Added CVS Id tags to header files. + - Log possible spoofing attacks. + Hostnames are back! + Hostlookup() is actually being called now. + - More verbose connection list + Fixes some hostlookups. Fixes indirectdata for real now (hopefully). + - Indirectdata finally REALLY REALLY works now! + - Moved all connection messages to debug level 1, without -d's only the + - Fixed KEY_CHANGED notification. A lot of notify_others() calls were + - Fixed indirectdata=no problem + - Improved handling of errors on connection attempts. + - Purge old connections that are ADD_HOSTed. + - Fixes a silly little insignificant buglet. + - Extra check op EINTR bij inlezen requests + - Fixed some spelling errors. + - Fixed missing " in nl.po + - Fixed a message in nl.po + - Added log message when SIGCHLD is received ("thanks" to Ivo van Dong) + - Updated Dutch translation. + - Removed all IP_ADDR_S macros, because gettext doesn't like them. Each + - New semantics for BASIC_INFO, ADD_HOST and DEL_HOST requests. This will + - Fixed memory leak. + - Removed segfault bug in conf.c (must have been there for ages!) + - Instead of logging an error when remote end closes the connection, + - Made tinc even more silent if no -d flag is given at all. + - Added documentation for the protocols (most important the meta protocol) + - Removed a single unused bit from status_bits_t. + - Updated PROTOCOL (a bit) + - Forgot to mention ourselves in the tincd manual page! :) + - Added Spanish translation from Enrique Zanardi. + - Updated THANKS file + - Delayed address resolving for ConnectTo lines in configuration file to + - Fixed typo. + - Added experimental hackish tunneling-over-TCP support. + - Lots o' buglets fixed (-Wall helps) + Fixed PACKET read loop. + Removed calling add_queue for tcponly packets. + - Added date/time of build and protocol number to --version output. + - Moved TCP packet reception to meta handler: less kludgy and less buggy! + - Reinstated O_NONBLOCK for meta socket + - Added two extra configuration options, Interface and InterfaceIP, to + Fixed all sprintf() spl01ts. + Ran update-po and updated dutch translation. + Commented on some size calculations. + Updated the manual: + Updated tinc.conf manual. + Fix rules (thanks to Laurence) + - Use strerror() instead of sys_errlist[] for increased portability + - New protocol. Will break everything else for now. + - Added more function skeletons for the new protocol. + - Lots of functions added for the new protocol. + - Some key exchange stuff. (Last commit before going to bed.) + - Fixed modulo in keylength check + - Lots of small changes. + Added document about the used cryptographic algorithms and the reasons + - Included authentication scheme from protocol.c + - Updated authentication scheme. + - Severe code reduction and simplification of challenge requests + - Removed options "string" stuff. It was a bad idea... + - Very detailed example of the authentication phase. + - Added meta.c which contains functions to send, receive and broadcast + - Added subnet handling code + Removing cipher directory (all will be covered by OpenSSL). + Big and bad commit of my current tree... + - Changed genauth to produce rsa keypairs instead of random passphrases. + - Generalized config file parsing to support multiple configuration trees. + - Fixing-things pass: every source file compiles into an object file now, + - Second fixing-things pass: it even links now. + - The daemon actually runs now (somewhat) + Corrected #ifdefs for tun/tap support. + - Fixing little things + - More fixing. Tinc daemons can now even create activated connections. + - Seed the PRNG using /dev/random before generating the keys. + - tinc now really does public/private key encryption! It even works, whee! + - Made Makefile.am stub for doc/es/ + - Removed last reference to genauth from Makefile.am + - Fixed all debug levels. + - route.c will contain the routing logic. + - Lots of little stuff modified + - Updated subnet list handling. Subnets are added to two lists now, the + - Lots of small fixes + - Fixed offsets when reading/writing from/to tap device + - Override destination ethernet address on incoming packets with + - Very big cleanup. + - Fixed ans_key_h + - Hit people who can't figure out subnet address/mask pairs with a + - Enforce correct order of authentication requests + - Moved connlist stuff to the proper header file. + - Updated dutch translation. + - Removed old encr stuff + - Small fixes + - Use CFB mode for encrypting packets: it works and we don't need padding. + - Finishing touch: encrypt the meta connections + - Small cleanups + - Fixed some spelling mistakes and terminology here and there. + - Update. + Removed config file parsing and interface setup. This will be handled by + - Removed unused MAC strip/add functions. + - Removed even more warnings. + - Resolve scriptname after fork() + - Removed manpage for no longer existing genauth. + - connlist.c added to translation + - Don't forget to set packet cipher for added hosts. + - Forward keys in hex notation, not as binary data. + - Check for packets that are looping back. + - Simplified ping mechanism. + - Prepended config_ to all configuration option names, because it confused + Changed execution of tinc-up: + - Open UDP connection for all known hosts. Comments please. + Porting to SunOS 5.8: + Porting to SunOS 5.8: + - Fixed --config + - Applied Jamie Brigg's patch (close sockets after error) + - Add Jamie :) + - Make checkpoint tracing a compile time option (off by default) + +Ivo Timmermans (77): + Alphabetized the list, added Lubom�r Bulej, removed Sander Smeenk and Tijs van Bakel, put merits after all names. + Don't touch VPNMASK if it's defined, otherwise use $MSK. + These files are created by gettextize (run by autogen.sh) (should have known that). + Include ../intl in the include path, and add @INTLLIBS@ to the list of libraries. + Merge changes from 1.6-1.8. + Configuration directive `IndirectData'. + Changed version number to 1.0pre3. + Version 1.0pre3. + Removed Free Software Foundation copyright, because Guus Sliepen contributed significantly. + Oops, and mention Guus too. + Include the Spanish translation in the distribution/build process. + (Quoting Laurence Lane:) + Also chomp $VPNMASK + Added a rule to create an rpm + Changed CVSROOT path in `make ChangeLog' + Link with OpenSSL crypto libraries instead of own blowfish library + Updated text, removed protocol flowchart + Include openssl/blowfish.h + Support for -lsocket and -lnsl on SunOS + Correct filenames for passphrases given in the example + Add Guus' name and shift out old protocol requests + Better checks for SunOS libraries + Added some structures and types that are needed for the overhaul. + New directive: Name. + First round of needed fixes after the overhaul + Second round of fixes + Added Spanish translation of the docs by Matias Carrasco + Many updates, parts rewritten, added, shuffled around. + Link with OpenSSL, forget libGMP + Updated new requirements, pointers to the manual + Don't look for GMP header files + Update Depends lines to reflect the dependencies on OpenSSL + Fix `Requirements'-section for GMP and OpenSSL libraries. + Add CVS id lines + Add checks for the presence of the universal tun/tap device driver. + Wrap the tun/tap code in #ifdef HAVE_TUNTAP + Linearized checks for if_tun.h + Really #include the if_tun.h files now + Output doc/es/Makefile + Process subdir es/ + Don't declare cp_file and cp_line in xmalloc() + Get the head revision up to date with cabal + Changed changelog + Include linux/sockios.h and net/if.h anyway, regardless of the value of HAVE_TUNTAP. + read_server_config: Check for result of read_config_file. + Oops, echelon change committed to cabal... :) + Skip the check for Linux kernel sources + This file is no longer needed. + - Synchronized changelog with the package's changelog. + Do not include $(top_srcdir)/cipher, it does no longer exist. + Added a perl example to turn an IP address into a MAC address. + Only check for linux/if_tun.h once + Changed `I' to `We' - small change, lots of difference :) + More exhaustive list of changes - perhaps it can be worded differently? + Change wsl to Wessel's name and email address in the ChangeLog creation + Mention fileutils, add a pointer to THANKS for more details + Changed a few messages wrt. system calls; updated and changed the Dutch translation a bit. + Don't include shlibs, as it no longer exists. + Oops, and include doc-base.tinc (new file). + - If necessary, patch po/Makefile.in from po-Makefile.in.in.diff to + Minor cosmetic change. + Save the environment on startup. + Run the scripts tinc-up and tinc-down from a separate function, which + Warnings removal pass: always include config.h first; add a few + Small change to the way the environment is copied. + Use putenv() instead of clumsy do-it-yourself in execute_script. + Do not include the passphrases directory + In execute_script: + Add route.c to the list of source files. + Updated Dutch translation + Build-depends on libtool + Build-Depends on gettext + Final release notes added, also edited release notes for 1.0pre2 to what the announcement on the mailing list looked like. + Wrapped text to 70 (72?) columns for easy reading + Bop version number to 1.0pre3-1 + Updates, updates + Add prototype for destroy_queue + +Wessel Dankers (3): + File added to CABAL (hopefully) + Grrr, recommit + Added architecture section, made a start with the kernel section. + +Version 1.0pre2 May 31 2000 +------------------------------------------------------------------------ + +Ivo Timmermans (56): + Deleted the protocol description. + Perl version of the system startup script. + Only print an error with send_termreq if debug_lvl is 2 or more. + Add check for mpz_powm in libgmp3. + Version 1.0pre1-0.1. + Changed version to 1.0pre2. + Give IP address instead of hex number when connecting tcp socket failed. + Add shlibs control file for the blowfish library. + Inserted useful content. + Add initscript, tincd->tinc. + Add description, better dependancies. + Mention both upstream authors. + tincd->tinc + .deb version number 1.0pre2-0.4. + Updated to newer version. + Exit with zero status if is empty. + Unlimited length in the config file, thanks to Cris van Pelt. + Depend on perl5. + *** empty log message *** + Look if the tap devices exist before bluntly remaking them. + Use the new VpnMask directive to add a route to the rest of the VPN. + This file is generated with dpkg-buildpackage. + Read /etc/tinc/nets.boot to find the networks that have to be started. + Create a default /etc/tinc/nets.boot after installation, containing all directories under /etc/tinc by default. + Version 1.0pre2-0.3 + Don't distribute the file files. + Find networks in instead of . + Include postinst in the distribution. + Errors will not terminate the script or result in a nonzero exit code. + Updated copyright notice. + Fixed typo. + Mask the vpn net with the vpn netmask, route would give an error if the netmask didn't match the net. + When VpnMask is not present in the config file, silently use $MSK as vpnmask. + Add an example of using VpnMask. + Use /etc/tinc/example as a base directory for an example. /etc/tinc/example/README points to /usr/share/doc/tinc/README.Debian. + Create an empty /etc/tinc/nets.boot. + Updated by Lubomir Bulej and Mads Kiilerich: it uses /etc/tinc/nets.boot and the VpnMask directive in the config files. + Internationalization of tinc. + Include intl/ directory in the list of subdirs. + Include system.h and ABOUT-NLS. + Update acconfig.h to include values for gettext inclusion. + Include GNU gettext checks. + Define LOCALEDIR in CFLAGS. + Dutch translation of tinc. + Bounds check for request id (between 0 and 255). + Updated changes list for version 1.0pre2. + Added new configuration directive `Hostnames', which controls the resolving of IP addresses to hostnames. + When a connection is terminated, all hosts that are still connected get notified of the lost connections. + In terminate_connection, only send a notification to hosts that are directly connected to us. (DEL_HOST gets forwarded automatically.) + Only accept an ADD_HOST request for a host that already exists in our conn_list if the nexthop field matches the sender. This is a workaround for older clients. + Include news for 1.0pre2. + Tell about /etc/tinc/nets.boot. + Updated Dutch translation. + Version 1.0pre2-1. + Handle locale settings. + Miscellaneous copyright updates. + +Guus Sliepen (16): + Proxymode removed. + Cleanups. + Changed ping behaviour (backwards compatible). If we don't have any data + Fixed typos. + Test for existence of configured tinc networks. This will also make + Stub for VpnMask config directive. + TODO file reinstated: + VpnMask truely works now. + Typo. + Fixed last typo. Init.d now uses ifconfig command to set both the tap's IP + Documentation updates. Removed all references to configuration variable + Fix for a DoS attack: + Fixed typos. When terminating a connection, it's status is not only set to + Made tinc persistent. If no outgoing connection can be established right + Terminate a connection on any error. Furthermore, disallow del_host, + Only activate a connection upon receiving it's public key if it's an + +Version 1.0pre1 May 08 2000 +------------------------------------------------------------------------ + +Ivo Timmermans (84): + Get rid of the message `zxnrbl\'. + Upon regeneration, free the old encryption key `securely\' by overwriting it. + Kill the parent after any error conditions in detach(). + Ignore SIGCHLD. + New option -D, don't detach. + Moved to version number 1.0. + Only one round of reading bits out of urandom; + Pass the requested size from xmalloc() and xrealloc() on to xalloc_fail_func() + Check for an illegal length of passphrase in read_passphrase(). + Check if stdout is a terminal, if so, print a verbose message. + Default passphrase length of 1024, added -h/--help options. + Submitted by Mads Kiilerich. + New manpage for genauth. + Updated manpages. + Address for bugreports changed to tinc@nl.linux.org. + Include the directory redhat in the build process. + Include genauth.8 in the distribution. + Submitted changes by Mads Kiilerich. + A short notice from Mads Kiilerich. + Keep make dist(dir) happy. + Added cvs-clean. + These files are not needed in release 1.0. + Don't compile in `idea'. + Don't include idea/idea.h. + Don't try to create cipher/idea/Makefile. + The shell script autogen.sh can create all these removed files, but be + s/Gnome/tinc/g + This file is obsolete, most of the ideas are already in echelon. + Remove check for bigendianness. + Don't define HAVE_NAMESPACES and HAVE_STL. + Use `make ChangeLog' to create this file from the CVS logs. + Remove test for GNOME. + Changes largely from Mads Kiilerich. + Added Mads Kiilerich, removed Guus Sliepen. + *** empty log message *** + Generate this Makefile.am from Makefile.am.in. + Contributed by Mads Kiilerich. + Spelling fixes. + Delete all the files that are created by autogen.sh on a `make cvs-clean'. + Propagate CFLAGS from configure to gcc. + Don't include TODO in the dist. + Remove ChangeLog with a `make cvs-clean'. + Initial CVS. + *** empty log message *** + Create a ChangeLog file, automake requires it. + *** empty log message *** + Debug level tweaking. + From Mads Kiilerich. + The make command is in /usr/bin. + Add an entry to dir. + Omit TODO. + Version to 1.0pre1; + Filled in the details, license from libblowfish copied. + Updated version number to 1.0. + Default config file name is tinc.conf, and pidfile is tinc.pid. + More updates wrt. the change from tincd->tinc. + Added `deb' target. + Filled up the protocol structs with unused bytes. + Got rid of the nasty hacks... and replaced it by another one. + Initially, the vpn_mask of a connection is 255.255.255.255 to avoid confusion with lookup_conn. + Replaced check for status.active by status.dataopen in check_network_activity. + New way of handling the meta protocol. + Read public keys the right way (tm). + Removed debug messages. + Read one less byte from an ANS_KEY request. + Send one less byte from an ANS_KEY request. + Protocol fix (ANS_KEY). This breaks 0.3.3 protocol compatibility. + Key forwarding, write one byte extra. + Committed by Lubom�r Bulej. + Updates by Mads Kiilerich. + Committed by Mads Kiilerich. + Fixed meta protocol. + More tincd->tinc updates. + Mentioned new metaprotocol. + Fix a typo, better handling of the info document. (from Mads Kiilerich) + Don't use error.h or error(), put #error in front of cpp errors. + getopt_long() support for platforms that don't have it. + Include stdio.h for fprintf. + More for getopt support. + Check for the existance of libdl. + Don't link in libdl. + Include sys/types.h. + Copied most of the code from the redhat script. + Added semicolons required by bash2 (Mads Kiilerich). + +Guus Sliepen (18): + Added extra checks for desynchronized connection lists. Hopefully this will + Bug found! Wrong pointer was used for handling multiple ADD_HOST requests + Added checkpoints to beginning and ending of every function. + Packet queues fixed. They caused the trouble when resending keys. + Fixed typo and removed some unnecessary variables. + When trying to talk to a host that is in the netmask of a tinc server but + Converted every &variable[0] to variable. + Cleanups: + Removed write_n() function. + Oops! Reference to write_n() removed and changed into neat write() call. + Meta protocol overhaul. Tinc is now incompatible with previous versions, + Fixed small mistake that would prevent forwarding requests. + Previous fix fixed. Meta protocol should be really flawless from now on! + Replaced sprintf() by safer snprintf(), removed possible buffer overflow + Outgoing packets now use network byte order in header. + Fixes typo and UDP network byte order. + Squashed gcc warning. + Added new config variable "ProxyMode". If enabled, all outgoing packets - Releasing 1.1pre17. - -commit 32ff5ab8a22ab80cd6c141625538dcc027458c0e -Author: Guus Sliepen -Date: Sun Oct 7 18:05:50 2018 +0200 - - Update THANKS. - -commit 5f3e9858952277ef3d6ac9d119826cbdda0746d7 -Author: Rafael Sadowski -Date: Mon Oct 1 15:14:24 2018 +0200 - - OpenBSD has a proper tap device. - -commit 5e1f7fb11138bc552facfb4b64eca9131f3f25b1 -Author: Guus Sliepen -Date: Sun Oct 7 13:41:23 2018 +0200 - - Update README and links to required libraries. - -commit a03991b7911a5f0afbf1269ac47143d09be76c52 -Author: Guus Sliepen -Date: Sun Oct 7 13:32:25 2018 +0200 - - Don't check for NULL-pointers before calling free(). - -commit b0ffeb7eeb21920842382c302ca15ec0d758e9b6 -Author: Guus Sliepen -Date: Sun Oct 7 13:05:49 2018 +0200 - - Fix spelling errors. - - Found by codespell. - -commit 1c475ecb575367a6b3f9328b0f643ad636155341 -Author: Guus Sliepen -Date: Sat Oct 6 23:31:05 2018 +0200 - - Fix all warnings when compiling with -Wall -W -pedantic. - -commit 953f5b4231bbbb8269bb0c55b96a1c8c4bb34a59 -Author: Guus Sliepen -Date: Sat Oct 6 18:18:45 2018 +0200 - - Fix warnings from the Clang static analyzer. - -commit a6448291834ca7419553a807ee367c719c2956d0 -Author: Guus Sliepen -Date: Sat Oct 6 17:51:41 2018 +0200 - - Fix compiler warnings. - -commit 69e550f5950e31fb97eb4558c3d6e564211ab03a -Author: Guus Sliepen -Date: Sun Sep 9 22:13:43 2018 +0200 - - Add a test for backwards compatibility with the legacy protocol. - -commit 46f3eba7755089ff68fdc137b0754cae2fa523eb -Author: Guus Sliepen -Date: Sun Sep 9 18:19:15 2018 +0200 - - Prevent oracle attacks in the legacy protocol (CVE-2018-16737, CVE-2018-16738) - - The legacy authentication protocol allows an oracle attack that could - potentially be exploited. This commit contains several mitigations: - - - Connections are no longer closed immediately on error, but put in - a "tarpit". - - The authentication protocol now requires a valid CHAL_REPLY from the - initiator of a connection before sending a CHAL_REPLY of its own. - - Reduce the amount of connections per second accepted. - - Null ciphers or digests are no longer allowed in METAKEYs. - - Connections that claim to have the same name as the local node are - rejected. - - Just to be on the safe side: - - - The new protocol now requires a valid SIG from the initiator of a - connection before sending a SIG of its own. - -commit 01cb1961eac33de9e9d9cecd0910850a2cb549c3 -Author: Guus Sliepen -Date: Sun Jun 24 16:19:10 2018 +0200 - - Enable AutoConnect by default. - -commit 291b8f864ea57dd68b894a3b1482ee822aad66ed -Author: Guus Sliepen -Date: Sat Jun 23 22:32:19 2018 +0200 - - Remove address cache debug messages printed to stderr. - -commit e5b9bd324cc24355956e9e59e5ec2df72cf9d469 -Author: Guus Sliepen -Date: Sat Jun 23 22:26:12 2018 +0200 - - Avoid treating compressed MTU probes as having a negative length. - - This was not harmful, but caused negative values being logged. - -commit 950bbc8f2f9c580ac85bef7bab9a3ae36ea99c4b -Author: Guus Sliepen -Date: Wed Jun 13 22:41:02 2018 +0200 - - Print UDP RTT on its own line. - -commit 22ae0c3549628739ca7c40e48ce1a276469ded92 -Merge: 15341e76 70e1e467 -Author: Guus Sliepen -Date: Wed Jun 13 22:23:27 2018 +0200 - - Merge remote-tracking branch 'volth/release-1.1pre16-rtt' into 1.1 - - Also, reformat the code and fix a compiler warning. - -commit 15341e7697fe88a9f3b4646a2cb784dc515609bd -Author: Guus Sliepen -Date: Tue Jun 12 20:50:58 2018 +0200 - - Add missing item and attribution to NEWS. - -commit e60405831565062c914fe5498cf3b17b0bd13e8b -Author: Guus Sliepen -Date: Tue Jun 12 20:50:37 2018 +0200 - - Remove the ping test. - - This was kind of a hack. The ns-ping test is a much better test, although - it only works on Linux. - -commit 70e1e467f93f885da3e49289e96757d5cd2ae5ba -Author: volth -Date: Wed Jun 13 18:10:47 2018 +0000 - - minor - -commit 72136f8418bc7e8a0a5bf3c11215aa49dc679659 -Author: volth -Date: Wed Jun 13 14:12:02 2018 +0000 - - expose traffic stats to 'tinc info ___' and 'tinc dump nodes' - -commit 0f0585d71b28428792e53258bc570dddc17b0b27 -Author: volth -Date: Tue Jun 12 21:17:30 2018 +0000 - - keep track of round trip times of UDP pings - -commit 6c0584c55b99dd9814fed5c13536d831b3e5317e -Author: Guus Sliepen -Date: Tue Jun 12 20:01:43 2018 +0200 - - Releasing 1.1pre16. - -commit 75271559a9dc2536b9da1c655a012eb837c58761 -Author: Guus Sliepen -Date: Tue Jun 12 19:47:02 2018 +0200 - - Remove the wxPython GUI. - - This GUI is missing a lot of functionality, and won't be part of an 1.1.0 - release. Therefore, it's being removed, and might be brought back after - 1.1.0. - -commit 809ee79b458b0c45d4d60761b1d71171648bdbd5 -Author: Oliver Freyermuth -Date: Wed Apr 4 22:01:52 2018 +0200 - - Fix compiling when support for UML sockets is enabled. - -commit f52e4d07706e6314bb11cf9b553f58210f5dd181 -Author: Guus Sliepen -Date: Mon Apr 2 16:49:06 2018 +0200 - - Reformat all code using astyle. - -commit 7ee885a1f6776be85e5397eda04f75d98ff0b631 -Author: Guus Sliepen -Date: Mon Apr 2 16:33:14 2018 +0200 - - Add the ability to set a firewall mark on sockets. - - The FWMark option is added, when set it will use setsockopt(SOL_SOCKET, SO_MARK) - to set the given value as the mark on all sockets created by tinc. - - Thanks to Olivier Tirat for submitting a similar patch in the past. - -commit d32226bc14428864df08beccb3cf4f8a472f2eef -Author: Guus Sliepen -Date: Mon Apr 2 12:29:46 2018 +0200 - - Fix invitation tests if port 655 is available. - - Running the "del Port" command when no Port is set returns an error. But - it is not necessary anyway since the later "set Port" command will - overwrite it. - -commit 63fbaf7b4a33d5657cd3338b7ea91a173b9973fb -Author: Guus Sliepen -Date: Fri Mar 30 11:50:40 2018 +0200 - - Prevent an infinite loop in get_recent_address(). - - When a node is offline, but we still have edges to it that have the same - address as we already have in our address cache, an infinite loop would - happen in get_recent_address(), because we forgot to advance the pointer - in the list of known addresses, and kept looking at the same one over - and over. - - Thanks to Sven-Haegar Koch for spotting the bug and providing - diagnostics. - -commit 04e498f8b79c1ebfd7080338ffa0399d01862424 -Author: Guus Sliepen -Date: Fri Mar 30 11:38:22 2018 +0200 - - Properly implement tinc.texi's dependency on tincinclude.texi. - - With this, make distcheck succeeds even without the info-in-builddir - option to AM_INIT_AUTOMAKE. - -commit 63a3369cbc41ba68e221da174c28f5f909c2ed8d -Author: Guus Sliepen -Date: Tue Mar 27 22:54:15 2018 +0200 - - Warn if we cannot reload the tincd when creating an invitation. - -commit 2d268fc06bc01419e7f7f32d4da1b560e72e4ad3 -Author: Mike Sullivan -Date: Mon Mar 26 14:19:04 2018 -0500 - - Fix handling partial SPTPS messages in sptps_test. - -commit 69a18395931d657b77641b68ca12473ad6b996da -Author: Guus Sliepen -Date: Tue Mar 6 19:31:17 2018 +0100 - - Ensure we call CloseServiceHandle() in case of errors. - -commit a3f04cf74463e783eeddd45e998c1d15db0f868a -Author: Guus Sliepen -Date: Tue Mar 6 19:24:14 2018 +0100 - - Reformat all code using astyle. - -commit fa305d9570bc7350d04c7de66cfec28b9a2f53d1 -Author: Gjergji -Date: Tue Mar 6 11:10:41 2018 +0100 - - fix service removal. - Windows service was not removed until tincctl exits - -commit 7761a6992025ef06bf8dbf88d39a3bf9e459346a -Author: Guus Sliepen -Date: Wed Feb 28 21:34:48 2018 +0100 - - Fix compatibility with LibreSSL and OpenSSL < 1.1. - - Closes #184 on GitHub. - -commit a742ea4d040ecfaabbc875c63f2625654ce68923 -Author: Guus Sliepen -Date: Wed Feb 28 21:28:16 2018 +0100 - - Try to process all pending events after select(). - - If we break out of the loop every time at the first filedescriptor that - is read/writeable, we risk starving the other filedescriptors. - -commit d6c8a1a3d3e945142b251b2897517e10ce0dfce4 -Author: Todd C. Miller -Date: Tue Feb 27 14:20:46 2018 -0700 - - Call WSAWaitForMultipleEvents() in a loop until we have checked all events. - WSAWaitForMultipleEvents() only returns the index of the first event that is read. We need to call WSAWaitForMultipleEvents() repeatedly to check if other events are also ready. Otherwise, a single busy event (such as the TAP device) can starve the other events. - -commit 7c73cb3ace6659df58ec2382b8d47bb521dad886 -Author: Guus Sliepen -Date: Tue Feb 27 21:08:57 2018 +0100 - - Work around a GCC bug that causes inet_checksum() to give wrong results. - - Valgrind reports the following bug: - - ==24877== Conditional jump or move depends on uninitialised value(s) - ==24877== at 0x12283E: inet_checksum (route.c:80) - ==24877== by 0x12283E: route_ipv6_unreachable (route.c:315) - ==24877== by 0x1236AC: route_ipv6 (route.c:751) - ==24877== by 0x1236AC: route (route.c:1160) - ==24877== by 0x113DE0: receive_tcppacket (net_packet.c:493) - ==24877== by 0x1119D4: receive_meta (meta.c:315) - ==24877== by 0x113288: handle_meta_connection_data (net.c:287) - ==24877== by 0x11A091: handle_meta_io (net_socket.c:491) - ==24877== by 0x10FB0C: event_loop (event.c:370) - ==24877== by 0x11362E: main_loop (net.c:489) - ==24877== by 0x10CACA: main (tincd.c:551) - - Clearing the variable pseudo in route_ipv6_unreachable removes this error, - but the resulting checksum is still bad. If one instead adds a dummy - write that depends on checksum, the error goes away and the checksum is - correct. - -commit d661c7c7353da90911e9f2d0195ac861d6837f5c -Author: Guus Sliepen -Date: Tue Feb 27 19:11:38 2018 +0100 - - Revert "Unconditionally remove timeouts from the queue before calling the callback." - - This reverts commit e8a60109fc91a42420ec626b63956771675f89b0. - -commit e8a60109fc91a42420ec626b63956771675f89b0 -Author: Guus Sliepen -Date: Mon Feb 26 22:19:43 2018 +0100 - - Unconditionally remove timeouts from the queue before calling the callback. - - We are going to unlink the timeout from the splay tree anyway, so do it - unconditionally before the callback, instead of waiting until after the - callback to check whether or not to remove it based on its expiration - time. - -commit 03a94cb3148544230bdd306e905d2ce88c551c12 -Author: Todd C. Miller -Date: Thu Feb 22 14:27:37 2018 -0700 - - In device_handle_read() we need to reset the read event on error or - it will keep firing. This is easy to reproduce by suspending the - machine while tinc is running. - -commit f10e98f5e5a3537b43fbc53f07ab691265de999a -Author: Guus Sliepen -Date: Wed Feb 21 20:34:42 2018 +0100 - - Update the documentation of the control protocol. - -commit 89102b02047d0220766f55ec041c8fc46234cf69 -Author: Todd C. Miller -Date: Tue Feb 20 20:18:38 2018 -0700 - - Fix heap corruption on Windows exposed by the use-after free fix. - reset_address_cache() could call free_known_addresses() on a struct - addrinfo * that was returned by getaddrinfo(). It seems safest to just - make a copy of the addresses returned by getaddrinfo() so we can always - use free_known_addresses() instead of trying to determine whether or - not we need to use freeaddrinfo(). - -commit 8f73169567fed6703acbad4f0f5fd5cff700d619 -Author: Guus Sliepen -Date: Mon Feb 19 20:41:21 2018 +0100 - - Document the control protocol. - -commit ecfef0eeb9b52f6d75b4aa936a1e11e6d8e678e3 -Author: Guus Sliepen -Date: Sun Feb 18 16:51:06 2018 +0100 - - Reduce memory allocations due to HMAC() and EVP_MD_*(). - - HMAC() allocates a temporary buffer on the heap each time it is called. - Similarly, we called EVP_MD_CTX_create() every time we wanted to - calculate a hash. Use HMAC_CTX and EVP_MD_CTX variables to store the - state so no (re)allocations are necessary. HMAC() was called for every - legacy packet sent and received. - - This issue was found thanks to heaptrack. - -commit 6be453fc63da9f87455b5e579cb686f95fa92102 -Author: Guus Sliepen -Date: Sun Feb 18 15:38:12 2018 +0100 - - Reduce memory allocations due to zlib's uncompress(). - - Everytime uncompress() is called, zlib allocates some buffer on the heap - and frees it again. When compression is enabled, this is the biggest source - of memory allocations in tinc. Instead of using this function, use - inflate(), which can store its state in a z_stream variable, which avoids - (re)allocating memory for every packet received. - - This issue was found thanks to heaptrack. - -commit 8f2ef1a174d18a9efdf9b0bd2417132fe7d84e9f -Author: Guus Sliepen -Date: Sun Feb 18 15:33:36 2018 +0100 - - Add code coverage testing support. - - Allows configure to be run with the --enable-code-coverage flag, allowing - one to run make check-code-coverage, which runs the test suite and produces - a code coverage report. - -commit d2b03f006f98d504e3e30f2d4b91ce02abd19c51 -Author: Guus Sliepen -Date: Sat Feb 17 14:39:29 2018 +0100 - - Reformat all code using astyle. - -commit 536fe3ffcdc4c894ed986dfb5fdc0d6f78d6fe25 -Author: Todd C. Miller -Date: Fri Feb 16 14:17:39 2018 -0700 - - Fix a use-after-free bug in get_recent_address() and two related issues. - 1) The sockaddr_t * returned may be part of memory freed by the call to - freeaddrinfo(). - 2) The sockaddr_t * returned from a recently seen address not in the - cache was cast from struct addrinfo *ai, not the struct sockaddr * - inside of it. - 3) In do_outgoing_connection(), when filling in the address in the - connection_t, there is a buffer overflow (read, not write) if - the sa returned by get_recent_address() didn't come from the - cache of recently seen addresses. That is, it was really a - struct sockaddr * and not a sockaddr_t *. This last was - found by building tinc with address sanitizer. - -commit 8145a3392bdcff4d7856ba72e66a90d73d887c00 -Author: Todd C. Miller -Date: Wed Jan 31 14:55:20 2018 -0700 - - In device_issue_read() there is no need to reset Offset and OffsetHigh - to 0; they are only used for seekable files (not sockets). - - Reset the write event before the call to WriteFile(). This is - consistent with how the read event is reset before ReadFile(). - - Clear device_write_packet.len() if WriteFile() fails with an error - other than ERROR_IO_PENDING; otherwise write_packet() will call - GetOverlappedResult() the next time it is run even though there is - no write in progress. - -commit 5ec513ec0ffc735e30c559a03378659ba4cc4515 -Author: Todd C. Miller -Date: Tue Jan 23 15:57:58 2018 -0700 - - WSAEVENT is a pointer, so we cannot simply return the different of two - events in io_compare(), which returns an int. This can return the wrong - result for 64-bit executables. - -commit 92d66492e0824674f68d26e787dd1ba4444a4601 -Author: Todd C. Miller -Date: Mon Jan 22 10:27:16 2018 -0700 - - Add some missing freeaddrinfo() calls to avoid leaking memory. - -commit e0f6d90e7fac4c567900e98c354af979c97f8d59 -Author: Guus Sliepen -Date: Mon Jan 22 18:05:09 2018 +0100 - - Fix calling freeaddrinfo() on the wrong pointer. - - Thanks to Todd C. Miller for finding this issue. - -commit 7bf4d225a994d8ce9fb45d42afd53793c4232e8e -Author: Etienne Dechamps -Date: Wed Jan 17 19:37:53 2018 +0000 - - Move ResetEvent() call before ReadFile(). - - Commit 313a752 changed the Windows device code such that ResetEvent() is - called on the read OVERLAPPED structure before GetOverlappedResult(), as - opposed to before ReadFile(). In [1] Guus pointed out that this doesn't - make a ton of sense, and I agree with him; it must have been an - oversight on my part when I wrote this code. - - Surprisingly, none of this makes any difference in my testing, at least - with the standard TAP 9.0.0.9 driver. Nevertheless, this code is - probably wrong and fixing it will make me sleep better at night. - - [1]: https://www.tinc-vpn.org/pipermail/tinc/2018-January/005091.html - -commit 43cf631bc10097448db041639ad07f84f647017e -Author: Etienne Dechamps -Date: Sun Jan 7 14:48:08 2018 +0000 - - Fix "use of GNU empty initializer extension" warning. - -commit 1b777010e7255cb354e31ca28c6442ee86383bac -Author: Etienne Dechamps -Date: Sun Jan 7 14:44:12 2018 +0000 - - Fix "void function should not return void expression" warning. - -commit ddf798a0ef7df21d682d2f6763d5417400c987ba -Author: Etienne Dechamps -Date: Sun Jan 7 14:26:00 2018 +0000 - - Fix AC_CHECK_DECLS usage in openssl.m4. - - See: - - https://www.gnu.org/software/autoconf/manual/autoconf-2.62/html_node/Generic-Declarations.html - - "For each of the symbols (comma-separated list)" - - When building with aggressive warning settings the current code results - in the following configure test code being generated: - - #ifndef OpenSSL_add_all_algorithms EVP_aes_256_cfb - #ifdef __cplusplus - (void) OpenSSL_add_all_algorithms EVP_aes_256_cfb; - #else - (void) OpenSSL_add_all_algorithms EVP_aes_256_cfb; - #endif - #endif - - Which is obviously wrong and makes the configure check fail. - -commit 04543a57e73e29c3e2a1968fd330f03c94dd6059 -Author: Guus Sliepen -Date: Fri Jan 5 22:49:30 2018 +0100 - - Add a cache of recently seen addresses. - - This maintains a cache file for each host we have communicated with, either - via TCP or UDP. The cache is used when trying to make outgoing connections, - and is updated whenever a successful TCP or UDP connection is established. - Up to 8 addresses are stored in the cache. - - Currently, the cache is stored in /etc/tinc/NETNAME/cache. The directory - has to be manually created to opt in to this feature for now. - -commit ca989c0c8b19901cbd7664a9d2b42aa85c9c176e -Author: Guus Sliepen -Date: Sat Jan 6 20:46:22 2018 +0100 - - Fix all spelling errors found by codespell. - -commit 6989a070c35b9672683ebb0764ab9051e0650469 -Author: Guus Sliepen -Date: Sat Jan 6 20:34:37 2018 +0100 - - Document how to enable tinc at boot time using systemd. - -commit fe9089337093c917d172aa26eedc9285c8bafb6a -Author: Guus Sliepen -Date: Sat Jan 6 16:59:21 2018 +0100 - - Don't include generated files into the tarball. - -commit e56589082f6198380d7f2246a776e41d388496f6 -Author: Guus Sliepen -Date: Sat Jan 6 16:21:19 2018 +0100 - - Update .gitignore. - -commit ee5e3404e49ef08437cd6b6e4c5b83d190efa053 -Author: Guus Sliepen -Date: Sat Jan 6 16:20:25 2018 +0100 - - Ensure the sptps-basic test doesn't fail during make distcheck. - -commit c2d8264dbe8478d27ba694062cebecee0a0342c4 -Author: Guus Sliepen -Date: Sat Jan 6 16:20:03 2018 +0100 - - Set default systemd unit path to ${libdir}/systemd/system. - - This installs systemd unit files into /usr/local, just like the binaries. - The systemd documentation claims to read this directory as well. - -commit c550c85d75ae38b9621147fdca4bf4380d54edda -Author: Guus Sliepen -Date: Sat Jan 6 16:17:35 2018 +0100 - - Remove hardcoded paths from systemd unit files. - - Closes #160 on GitHub. - -commit bdeba3f9c26f9225c17c097ca490dc651cd40b90 -Merge: 696dc2ad 9ca5a3c4 -Author: Guus Sliepen -Date: Fri Jan 5 19:58:28 2018 +0100 - - Merge remote-tracking branch 'dechamps/ipip' into 1.1 - -commit 9ca5a3c43854fba782d87be080d7a97a88ef3427 -Author: Etienne Dechamps -Date: Tue Jan 2 09:55:26 2018 +0000 - - Support MSS clamping for IP in IP (RFC 2003) packets. - - This change allows tinc MSS clamping to operate on TCP streams that are - inside an IP in IP tunnel. - -commit 696dc2ad9743c62e56a6d21addb8c4e8efbffec1 -Author: Guus Sliepen -Date: Fri Jan 5 17:13:57 2018 +0100 - - Add missing newlines to some error messages. - -commit 313b05b67c59c316c0eff631598e0700e0fd3c8d -Author: Guus Sliepen -Date: Fri Jan 5 17:13:25 2018 +0100 - - Document that invitation files MUST always start with Name = ... - -commit 356118324f7cde276f393162fca54040f8c67f04 -Author: Guus Sliepen -Date: Fri Jan 5 17:12:06 2018 +0100 - - Don't warn about empty lines in invitation files. - -commit 50afa82a8f14ead7d4d3eafd2a1347b3bb9a2879 -Author: Guus Sliepen -Date: Mon Dec 18 10:47:40 2017 +0100 - - Document the --batch option. - -commit 0b2361a9399944cd57def87226f2be7f92646aa5 -Author: Guus Sliepen -Date: Sat Dec 16 22:54:31 2017 +0100 - - Assume all IPPROTO_* macros exist. - -commit b8acb89add4e553d141a45392bc0126c331deee6 -Author: Guus Sliepen -Date: Mon Nov 6 22:52:17 2017 +0100 - - Fix building documentation when using OpenBSD's make. - -commit 4986917cb11be70a9103917d58e7aa47ab88f09d -Author: Guus Sliepen -Date: Mon Nov 6 22:49:41 2017 +0100 - - Update THANKS. - -commit 38489e37f50e807e51bfd28ebb8b20396eed1447 -Author: Guus Sliepen -Date: Mon Nov 6 22:44:12 2017 +0100 - - Const correctness. - -commit 61b441dc995c1e6dd21fd85e2014dd981e9c9350 -Author: Guus Sliepen -Date: Mon Nov 6 22:35:28 2017 +0100 - - Support autoconf's --runstatedir option. - - Put the PID file in @runstatedir@ instead of @localstatedir@/run. This - requires autoconf 2.70, which is not released yet, so add a fallback to - use @localstatedir@/run if @runstatedir@ is not set. - -commit 42d2dff33306beae8ddbd9cc991ad80f135950a6 -Author: Guus Sliepen -Date: Mon Nov 6 22:28:32 2017 +0100 - - Ensure all parameters have names in header files. - -commit b34eb5555d40b7e87c1e06988250e4977a793c09 -Author: Guus Sliepen -Date: Mon Nov 6 22:27:57 2017 +0100 - - Remove unused functions. - -commit 6123ed30992d671b94fc016660086be6a62a3871 -Author: Guus Sliepen -Date: Mon Nov 6 21:46:17 2017 +0100 - - Don't log errors when autoconnecting fails and debuglevel is 0. - -commit c84fce52d2191df06e24737449e8983174984ddc -Author: Guus Sliepen -Date: Thu Oct 26 21:33:46 2017 +0200 - - If we are using libncurses, also try to link with libtinfo. - - On some distributions, tinc might not be linked correctly if -ltinfo is - not explicitly specified. - -commit e88b3fb52fb375cd8ab233a671f38ed2240ed828 -Author: Guus Sliepen -Date: Wed Oct 25 21:08:29 2017 +0200 - - Only forward SPTPS packets if Forwarding = internal. - - This tries to match what is done for packets using the legacy protocol. - However, since SPTPS is end-to-end encrypted, Forwarding = kernel cannot - be implemented. In that case, we also drop the packets. - -commit 87f96aec8c48327d879c20ff2b789c88a675173d -Author: Todd C. Miller -Date: Wed Oct 25 10:05:06 2017 -0600 - - Replace remaining sizeof foo with sizeof(foo). - -commit 9e7c6d4dce8b87d40cea537fd0b035a2612580e3 -Author: Guus Sliepen -Date: Mon Oct 23 21:10:20 2017 +0200 - - Disable PMTU discovery when TCPOnly is used. - -commit 7c359313aca273319f94fe18121831ab4b62a4b4 -Author: Guus Sliepen -Date: Wed Oct 11 19:30:17 2017 +0200 - - Add some information about the requirements of a chroot environment. - -commit a0baeddb8aa745007d0302ed06247cabb8facb32 -Author: Guus Sliepen -Date: Sun Oct 8 21:32:12 2017 +0200 - - Ensure "make distcheck" really runs without errors. - -commit f6e87ab476a0faf8b124ecaaa27f967d825e6457 -Author: Guus Sliepen -Date: Sat Oct 7 17:50:22 2017 +0200 - - Reformat all code using astyle. - -commit 3a316823b971396a428f020f401b9fe41252d98d -Author: Guus Sliepen -Date: Sat Oct 7 17:47:19 2017 +0200 - - Convert sizeof foo to sizeof(foo). - - While technically sizeof is an operator and doesn't need the parentheses - around expressions it operates on, except if they are type names, code - formatters don't seem to handle this very well. - -commit 5822f817aa802c2c5a83e9d99a8ae78cb822799b -Author: Guus Sliepen -Date: Sat Oct 7 17:40:34 2017 +0200 - - Update all header guards. - - Don't start with underscores, as those are reserved for system - libraries. Make sure all start with TINC_, and that they appear at - the top of the file. - -commit 3465746b9bf75124b21eab21cdf390696b608405 -Author: Guus Sliepen -Date: Sat Oct 7 16:51:32 2017 +0200 - - Remove unused/obsolete checks from configure.ac. - -commit ced6c3151d6012df560f088d39d306370bb115b7 -Author: Daniel Lublin -Date: Thu Oct 5 09:23:20 2017 +0200 - - doc: there is, not their is - -commit d3cb2a7342218c1aadfacd92d640c426d725112f -Author: Guus Sliepen -Date: Tue Oct 3 21:23:28 2017 +0200 - - Prepare for automatic code formatting using Artistic Style. - -commit e3d914a4d5f5be1c263ec77b9b5c62afb5fc1b78 -Author: Guus Sliepen -Date: Sun Oct 1 22:04:40 2017 +0200 - - Update THANKS. - -commit 453e6070ddfab2157f52536bdd7a79fc16f851f4 -Author: Todd C. Miller -Date: Thu Sep 28 16:39:59 2017 -0600 - - Fix parsing of -b flag - - Only the short -b option is missing, --batch works as expected. - -commit af81c436d6e11a53803747af7cc8ecfd449ccd4c -Author: Guus Sliepen -Date: Sat Sep 2 21:56:17 2017 +0200 - - Releasing 1.1pre15. - -commit 4e5c2193a1fa1ed054956fc0b1df387b19c546a5 -Author: Guus Sliepen -Date: Sat Sep 2 21:55:47 2017 +0200 - - Drop h and hh length modifiers from printf format strings. - -commit 91d50f8b375503be6b6081985f5948773d64b9d3 -Author: Guus Sliepen -Date: Sat Sep 2 21:54:34 2017 +0200 - - Ensure packet priority is cleared when sending PMTU probe replies. - - Found by the Clang static analyzer. - -commit 00d81ee6236e76f80b84372ac5c635636ad48136 -Author: Guus Sliepen -Date: Sat Sep 2 21:52:44 2017 +0200 - - Fix a file descriptor leak when using an invitation. - - Found by cppcheck. - -commit a073b2cb0bca646685a83479db6b66d518240bc5 -Author: Guus Sliepen -Date: Sat Sep 2 21:06:25 2017 +0200 - - Fix a compiler warning. - -commit 843990d8df0c060db9b64e170996e9d49c8c921d -Author: Guus Sliepen -Date: Sat Sep 2 17:24:05 2017 +0200 - - Force IPv4 for sptps-basic.test. - - Allow forcing either IPv4 or IPv6 for sptps_test, and use IPv4 for the - sptps-basic test. Since sptps_test is only opening a single listening - socket, and you cannot control which address family it uses, this gets - around a problem where the listening side is using a different address - family than the one connecting to it. - -commit 5f89950f47a9cf73169e797d4e2d6ef8b7f74a5a -Author: Guus Sliepen -Date: Sat Sep 2 17:04:25 2017 +0200 - - Add missing break statements. - -commit 92fdabc439bdb5e16f64a4bf2ed1deda54f7c544 -Author: Guus Sliepen -Date: Tue Aug 22 20:51:44 2017 +0200 - - Make autoconnect try to heal network splits. - - When we have less than three connections, we greedily try to connect to any - viable node. However, once we have three connections, try to connect to - nodes that we know of but that aren't reachable. - - We also make sure that if there are 100 reachable nodes, and 1 unreachable - one, that not all 100 reachable nodes try to connect to the unreachable - at the same time. - -commit 7c223917cb3d478fc3f5b23ee5602925f083e4d4 -Author: pacien -Date: Tue Aug 15 19:56:06 2017 +0200 - - Add LogLevel config option - -commit e4544dbc6989e4a146c19519924e52c116bfc343 -Author: Guus Sliepen -Date: Thu Jul 27 10:06:13 2017 +0200 - - Forward-port tinc 1.0's handling of device errors. - -commit d73cdee5df3e6c7395270c69e944b3c853f013ae -Author: volth -Date: Thu Jul 27 06:32:28 2017 +0000 - - Avoid infinite loop on EBADFD - - On Linux network restart, Tinc can get into a loop writing millions of error messages "Error while reading from Linux tun/tap device (tun mode) /dev/net/tun: File descriptor in bad state" to the log. https://github.com/NixOS/nixpkgs/pull/27675 - - It should be somehow aborted. - Here is my quick hack. - -commit acefa66dbd97617d86dee270b2b95ecdb763434b -Author: Guus Sliepen -Date: Sun Jul 9 16:12:55 2017 +0200 - - Store the invitation data after a succesful join. - - This can be used by the invitee to examine the file after a join, and - process it in different ways than the tinc CLI does. - -commit cd854fa86a9dc177dcaa56fa774afb127b29651a -Author: Guus Sliepen -Date: Sun Jul 9 15:57:51 2017 +0200 - - Add configurable experation time for invitations. - -commit 93584bc1cad7c7cc9c95859a8cde548bc18b6fa8 -Author: Guus Sliepen -Date: Sun May 28 12:48:32 2017 +0200 - - Set KillMode=mixed in the systemd service file. - - This ensures only the main process is sent the SIGTERM, and not anything - else that might have started in the same control group, including the - tinc-down script. - - Closes #145 on GitHub. - -commit 970799aa3406c22a575f665d3964c15d7c9ab555 -Author: Guus Sliepen -Date: Sun May 28 12:26:44 2017 +0200 - - Move logging of "would block" messages to debug level 4. - -commit 3d8a8363544bfcf75a9124251eff0caae3a8f1a2 -Author: Guus Sliepen -Date: Sun May 7 15:29:22 2017 +0200 - - Remove unused add_scalar function. - -commit 958a751e20270da821fee651ff9ecda8a2afc5d0 -Author: thorkill -Date: Thu May 4 23:44:56 2017 +0200 - - Fix NULL pointer dereference in send_udp_info - -commit 9527f4f22cd71feeee8a49866e29cce98408f1e7 -Author: thorkill -Date: Mon May 1 12:40:22 2017 +0200 - - Sanitize input in id_h - prevent integer overflows - -commit 18646deca120f0ccc3bfad643dba83547ecc2f20 -Author: Guus Sliepen -Date: Tue Apr 18 20:09:38 2017 +0200 - - Fix some minor issues found by cppcheck. - -commit 060ab1cd7cdf750a0477f2a8b6193d28849877e8 -Author: Guus Sliepen -Date: Tue Apr 18 20:09:08 2017 +0200 - - Add field widths to sscanf() calls. - - Found by cppcheck. - -commit be8e5cbd1cfcd198f975542e52085abdd543ec80 -Author: Guus Sliepen -Date: Tue Apr 18 20:07:33 2017 +0200 - - Remove dead stores. - - Found by the Clang static analyzer. - -commit 70fed5f7ffdeb0416ee6b77881098faab9a7cd47 -Author: Guus Sliepen -Date: Mon Apr 17 16:05:30 2017 +0200 - - Add missing tinc stop command to the scripts test. - -commit a14414731925cd59e64b3a90309b5a9ec60ac690 -Author: Guus Sliepen -Date: Mon Apr 17 13:54:02 2017 +0200 - - Fix tests on *BSD. - -commit db80dbbac93ce3c714247e0af2147f5e1474a135 -Author: Guus Sliepen -Date: Mon Apr 17 13:53:48 2017 +0200 - - Fix segfault when adding environment variables. - -commit 1be0c284c7c8d34c2dd6c2160ce49aeae468e867 -Author: Guus Sliepen -Date: Mon Apr 17 13:07:15 2017 +0200 - - Fix compiler warnings on *BSD. - -commit 2b4c0c63628ff9b432ec5d4b4c7b7ab2d4b02fb2 -Author: Guus Sliepen -Date: Mon Apr 17 13:02:39 2017 +0200 - - Make sure realname is always initialized. - -commit c87a77b5fd2a0378f2b992a5d579a80ee4033cec -Author: Guus Sliepen -Date: Mon Apr 17 12:50:30 2017 +0200 - - Ensure tests compile on *BSD. - -commit 95f09569beb2e304e6a2112d20cee6fab88f3729 -Author: Guus Sliepen -Date: Sat Apr 8 13:34:40 2017 +0200 - - Use getmsg()/putmsg() instead of read()/write() on Solaris. - - This fixes a problem where read() returns packets from the IP layer before - fragmentation is done. - - # Conflicts: - # src/solaris/device.c - -commit 6011197be5cdb18aa79713990d6a1887b9261d12 -Author: Guus Sliepen -Date: Sat Apr 8 13:31:04 2017 +0200 - - Use /dev/udp instead of /dev/ip on Solaris. - - # Conflicts: - # src/solaris/device.c - -commit 9a113db0a61242a0273a7ac95dd536f3a4bdb581 -Author: Guus Sliepen -Date: Wed Mar 29 08:08:56 2017 +0200 - - Ensure sptps_keypair and sptps_test get build for make check. - -commit d9a7f2d1054a7155b5f23855ba28dd98e0df73be -Author: Guus Sliepen -Date: Wed Mar 29 08:08:19 2017 +0200 - - Use 127.0.0.1 instead of localhost to ensure tests are reproducible. - -commit 3ab1893a4b6c2895075ac889cf06c511e2001a9e -Author: Guus Sliepen -Date: Sun Mar 26 17:54:37 2017 +0200 - - Ensure proper logging in the invite-offline test. - -commit 0af3dcf7a838dede699194c02444f1607644bb28 -Author: Guus Sliepen -Date: Sun Mar 26 17:43:33 2017 +0200 - - Add the scripts test. - - This test whether all the scripts are run with the right information in - the right order. - -commit ebade1e8f80ebaa476f701089da7ae654837397c -Author: Guus Sliepen -Date: Sun Mar 26 16:48:02 2017 +0200 - - Update .gitignore. - -commit fd3ec60757a84b7551e03b3a48dd30f35015c448 -Author: Guus Sliepen -Date: Sun Mar 26 16:47:54 2017 +0200 - - Add the invite-offline test. - - This tests generating an invitation on the server while no tinc daemon is - running. - -commit 5fcf6e16acccdaac573eebae21a5a47294e346e4 -Author: Guus Sliepen -Date: Sun Mar 26 16:46:31 2017 +0200 - - Remove superfluous sleep command in invite-join test. - -commit ccb4fb6f7ac2efbb99d044aa072e75c035f504aa -Author: Guus Sliepen -Date: Sun Mar 26 16:46:03 2017 +0200 - - Use unique ports for all tests. - -commit add75303e918af5e94ff545d969872799fac5cef -Author: Guus Sliepen -Date: Tue Mar 21 21:25:27 2017 +0100 - - Add DEBUG environment variable for scripts. - - This contains the current debug level used by tinc. Scripts can use it - to decide whether to log debugging information of their own. - - Closes #138 on GitHub. - -commit 5cbef906209eb5005f821af8f55a6f5d7e7d060c -Author: Guus Sliepen -Date: Tue Mar 21 21:21:23 2017 +0100 - - Put script environment creation/deletion in functions. - - This makes environment handling safer, and also has a single place where - we can add new environment variables that should be present for all - scripts. - -commit 3e643d5d7e5c7db35eacb3703d497c584e93cf18 -Author: Vittorio Gambaletta (VittGam) -Date: Wed Oct 12 13:52:17 2016 +0200 - - route: Support ToS/DiffServ priority inheritance when routing IPv6 packets. - - Signed-off-by: Vittorio Gambaletta - -commit aebaaa8db80ec3931346af710f2182d129c74c41 -Merge: 2c333f0f d21d97ea -Author: Guus Sliepen -Date: Mon Mar 20 22:33:18 2017 +0100 - - Merge remote-tracking branch 'dechamps/sleep' into 1.1 - -commit 2c333f0f45f445d0811a364817d03df0c8cf2d2f -Author: Guus Sliepen -Date: Mon Mar 20 22:19:36 2017 +0100 - - Don't try to use kill() on Windows. - -commit 26dc50599d6e38be1e7304602ffea0ba282c1091 -Author: Guus Sliepen -Date: Mon Mar 20 22:15:20 2017 +0100 - - Add missing #defines used by fd_device.c. - -commit 3fc678a8df4d6c057ef9f2c602b86ed106651e68 -Author: Guus Sliepen -Date: Tue Mar 7 19:19:19 2017 +0100 - - Use free_known_addresses() to free memory allocated by get_known_addresses(). - - We know what struct addrinfo looks like, but the standard says nothing - about how it is allocated. So we cannot trust freeaddrinfo() to work - correctly on the struct addrinfo list we allocated ourselves in - get_known_addresses(). To make a distinction by allocations from the - latter and from str2addrinfo(), we keep two pointers (*ai and *kai) in - struct outgoing, and use the freeing function that is appropriate for - each. - -commit ef661316f163f2ecf6c75a3dd28e2cad51772c56 -Author: Roman Savelyev -Date: Tue Mar 7 19:07:19 2017 +0100 - - Fix lost pointer trails in get_known_addresses(). - -commit 7a54fe5e884e98ade91af527c67f9c5df1452a50 -Author: Pacien TRAN-GIRARD -Date: Mon Feb 27 20:56:55 2017 +0100 - - Add fd_device - -commit 4a45a65fe2555efc5b6763a293d30251755e78a8 -Author: Guus Sliepen -Date: Tue Feb 14 20:51:43 2017 +0100 - - Remove the description of the LocalDiscoveryAddress option from the manual. - - This option is no longer implemented. - -commit d3cc96b027a919e22bbf06d634edb0a2a069ac92 -Author: Guus Sliepen -Date: Tue Jan 31 12:05:03 2017 +0100 - - Don't build sptps_* binaries by default. - -commit 88d158e15b9e16b4227b374d8bb4640010670cef -Author: Guus Sliepen -Date: Tue Jan 31 12:03:27 2017 +0100 - - Fix potential segfault in the replacement vasprintf() function. - -commit 06b820133285f83f7e1a839cccbed13358b84081 -Author: Etienne Dechamps -Date: Sun Dec 18 14:53:33 2016 +0000 - - Fix address memory leaks in add_edge_h(). - - Note that this is not as bad as it looks, because in practice - sockaddrfree() is a no-op for typical address types. - -commit 02093b12b0133b51dd04613c94c762ad2761cd3c -Author: Etienne Dechamps -Date: Sun Dec 18 14:32:25 2016 +0000 - - Clarify the flow of add_edge_h(). - - This is an attempt at making the control flow through this function - easier to understand by rearranging branches and cutting back on - indentation levels. - - This is a pure refactoring; there is no change in behavior. - -commit 3bf3d7d3e7d51034bda873861c52578f3abe6b5d -Author: Etienne Dechamps -Date: Sun Dec 18 14:25:20 2016 +0000 - - Fix edge updates containing local address changes. - - This commit fixes a logic bug in the edge update code where local - address changes are not taken into account if they are bundled in with - other changes. This bug breaks local discovery in some scenarios. - - The regression was introduced by commit - e4670fc4a0576eb76f1807ce29fa9455dd247632. - -commit 0792a10a5a66bcbf56185e479feed78252122667 -Author: Etienne Dechamps -Date: Sun Dec 18 16:56:27 2016 +0000 - - Fix edge local addresses not being set when connections are established. - - This bug prevented nodes from advertising their local addresses, thus - breaking local discovery. - - The regression was introduced in - ab13c14a1480561bb9f59ccfbbd6045e0484ce9c. - -commit d21d97eaf5db9e848d8eee28784c4f54af85f43d -Author: Etienne Dechamps -Date: Sat Dec 3 23:13:46 2016 +0000 - - On Windows, don't cancel I/O when disabling the device. - - I have observed cases where disable_device() can get stuck on the - GetOverlappedResult() call, especially when the computer is waking up - from sleep. This is problematic when combined with DeviceStandby=yes: - - other_side (1.2.3.4 port 655) didn't respond to PING in 5 seconds - Closing connection with other_side (1.2.3.4 port 655) - Disabling Windows tap device - - - gdb reveals the following stack trace: - - #0 0x77c7dd3c in ?? () - #1 0x7482aad0 in KERNELBASE!GetOverlappedResult () from C:\WINDOWS\SysWoW64\KernelBase.dll - #2 0x0043c343 in disable_device () at mingw/device.c:244 - #3 0x0040fcee in device_disable () at net_setup.c:759 - #4 0x00405bb5 in check_reachability () at graph.c:292 - #5 0x00405be2 in graph () at graph.c:301 - #6 0x004088db in terminate_connection (c=0x4dea5c0, report=true) at net.c:108 - #7 0x00408aed in timeout_handler (data=0x5af0c0 ) at net.c:168 - #8 0x00403af8 in get_time_remaining (diff=0x2a8fd64) at event.c:239 - #9 0x00403b6c in event_loop () at event.c:303 - #10 0x00409904 in main_loop () at net.c:461 - #11 0x00424a95 in main2 (argc=6, argv=0x2b42a60) at tincd.c:489 - #12 0x00424788 in main (argc=6, argv=0x2b42a60) at tincd.c:416 - - This is with TAP-Win32 9.0.0.9. I suspect driver bugs related to sleep. - In any case, this commit fixes the issue by cancelling I/O only when the - entire tinc process is being gracefully shut down, as opposed to every - time the device is disabled. Thankfully, the driver seems to be - perfectly fine with this code issuing TAP_IOCTL_SET_MEDIA_STATUS ioctls - while there are I/O operations inflight. - -commit 1672dbd66b619f84cb86950298ad89df93e1dcba -Author: Etienne Dechamps -Date: Sat Dec 3 22:52:30 2016 +0000 - - Fix crash on Windows when a socket is available for both write and read. - - Currently, if both write and read events fire at the same time on a - socket, the Windows-specific event loop will call both the write and - read callbacks, in that order. Problem is, the write callback could have - deleted the io handle, which makes the next call to the write callback a - use-after-free typically resulting in a hard crash. - - In practice, this issue is triggered quite easily by putting the - computer to sleep, which basically freezes the tinc process. When the - computer wakes up and the process resumes, all TCP connections are - suddenly gone; as a result, the following sequence of events might - appear in the logs: - - Metadata socket read error for node1 (1.2.3.4 port 655): (10054) An existing connection was forcibly closed by the remote host. - Closing connection with node1 (1.2.3.4 port 655) - Sending DEL_EDGE to everyone (BROADCAST): 13 4bf6 mynode node1 - Sending 43 bytes of metadata to node2 (5.6.7.8 port 655) - Could not send 10891 bytes of data to node2 (5.6.7.8 port 655): (10054) An existing connection was forcibly closed by the remote host.a - Closing connection with node2 (5.6.7.8 port 655) - - - In this example the crash occurs because the socket to node2 was - signaled for reading *in addition* to writing, but since the connection - was terminated, the attempt to call the read callback crashed the - process. - - This commit fixes the problem by not even attempting to fire the write - callback when the write event on the socket is signaled - instead, we - just rely on the part of the event loop that simulates level-triggered - write events. Arguably that's even cleaner and faster, because the code - being removed was technically redundant - we have to go through that - write check loop anyway. - -commit 979acc48aded5bb04f1574128d174d56550be302 -Author: Guus Sliepen -Date: Sun Oct 30 15:19:12 2016 +0100 - - Enforce maximum amount of bytes sent/received on meta-connections. - - This is 2^{block_length_in_bits / 2 - 1}. - -commit edc1efed3c0cf5aebb1c765066c0413757229a31 -Author: Guus Sliepen -Date: Sun Oct 30 15:17:52 2016 +0100 - - Use AES256 and SHA256 by default for the legacy protocol. - - At the start of the decade, there were still distributions that shipped - with versions of OpenSSL that did not support these algorithms. By now - everyone should support them. The old defaults were Blowfish and SHA1, - both of which are not considered secure anymore. - - The meta-protocol now always uses AES in CFB mode, but the key length - will adapt to the one specified by the Cipher option. The digest for the - meta-protocol is hardcoded to SHA256. - -commit fcaf158494af7cb015d8658a3241c324518e8d7f -Author: Dennis Lan -Date: Wed Oct 12 13:35:39 2016 +0200 - - Fix typo in src/upnp.c. - -commit 9cbd3c2b5b03c29c116a14f196db8a32c7135391 -Author: Vittorio G (VittGam) -Date: Tue Oct 11 20:30:41 2016 +0200 - - tincctl: Avoid falling back to 1024 bits RSA key generation when an invalid key size is specified. - - Also warn the user if a key smaller than 2048 bits is being generated. - - Signed-off-by: Vittorio Gambaletta - -commit c7c5c74d4af7442b92d863fc9eb04395c456b0be -Author: Vittorio G (VittGam) -Date: Tue Oct 11 13:30:05 2016 +0200 - - fsck: Fix ed25519 public key reading, and fclose usage. - - Signed-off-by: Vittorio Gambaletta - -commit e6497a23f7689663aa2c19311a278e20661bddc1 -Author: Guus Sliepen -Date: Tue Jul 26 16:47:45 2016 +0200 - - Log warnings about dropped packets only with debug level 5 or higher. - -commit 2784a171ec39e2a34aabf8194a651de570e19e0e -Author: Etienne Dechamps -Date: Thu Jul 14 19:15:35 2016 +0100 - - Fix error handling when setting up the UDP socket. - - Due to this typo, if tinc managed to set up the TCP socket but not the - UDP socket, it would continue anyway. - - The regression was introduced in - 6bc5d626a8726fc23365ee705761a3c666a08ad4. - -commit b1c29464b68d756035acc4b4d1681f05d8831eaf -Author: Guus Sliepen -Date: Fri Jun 24 11:22:24 2016 +0200 - - Fix compiling with OpenSSL < 1.1.0. - -commit 9a9f6fac009caf31c3786e13231eb05b3bad0681 -Author: Guus Sliepen -Date: Fri Jun 24 11:22:11 2016 +0200 - - Add missing m4 files. - - ax_cflags_warn_all.m4 depends on them. - -commit b9b0defaf422bcc1272f87d791d9ac53c9539734 -Author: Guus Sliepen -Date: Thu Jun 23 15:59:43 2016 +0200 - - Fix potential memory leaks found by the Clang static analyzer. - -commit 49edf9c53a31714b740d0ee67c29aca503973d81 -Author: Guus Sliepen -Date: Thu Jun 23 15:59:16 2016 +0200 - - Fix warnings from the Clang static analyzer. - - These are all false positives or harmless dead stores. - -commit e16ab7b89948c24a2c47652e8eb1a817a4b1424c -Author: Guus Sliepen -Date: Thu Jun 23 15:26:58 2016 +0200 - - Force nul-termination of strings after vsnprintf(). - - Apparently, on Windows this function might not always be properly - terminated. - -commit 2de5d866b5e4d4e6b827dcfb985c24edbda71f4f -Author: Guus Sliepen -Date: Wed Jun 22 23:08:30 2016 +0200 - - Use EVP_MD_CTX_destroy() instead of _free(). - - Thanks to azrdev for pointing out the build failure on Fedora 23. - -commit 9b148fd844587fbf956e28f57e4bd39a11edc07f -Author: Guus Sliepen -Date: Wed Jun 22 17:42:25 2016 +0200 - - Check return value of RSA_generate_key_ex(). - -commit 172763f4af4340ac2c2549e8fbb7490f5f995d47 -Author: Guus Sliepen -Date: Wed Jun 22 17:35:12 2016 +0200 - - Add -Wall to CFLAGS. - -commit 323c17e232539f3f06e7cebc664ab48f60127e0e -Author: Guus Sliepen -Date: Wed Jun 22 16:32:05 2016 +0200 - - Ensure compatibility with OpenSSL 1.1.0. - -commit 74eb4cc974f6d24370f439a1761dc4412d7fa58d -Author: Guus Sliepen -Date: Sun Jun 5 15:20:57 2016 +0200 - - Fix the previous commit. - -commit ab13c14a1480561bb9f59ccfbbd6045e0484ce9c -Author: Guus Sliepen -Date: Sun Jun 5 14:47:21 2016 +0200 - - Preserve IPv6 scope_id in edges. - - When creating an edge after authenticating a peer, we copy the - address used for the TCP connection, but change the port to that used - for UDP. But the way we did it discarded the scope_id for IPv6 - addresses. This prevented UDP communication from working correctly when - connecting to a peer on the same LAN using an IPv6 link-local address. - - Thanks to Rafał Leśniak for pointing out this issue. - -commit e47fe48aed76bfd7d2cb957e402a8cdcb0c84759 -Author: Sean McVeigh -Date: Sat May 21 17:38:14 2016 -0400 - - fix check in cmd_pid() for failure to connect to tincd - -commit 4314df644e22778a554ca1760941a2bfae08bce2 -Author: Sean McVeigh -Date: Sat May 21 17:25:18 2016 -0400 - - check for daemon pid existence before trying to connect to the control socket, and clean up stale files otherwise. - -commit 9d0e86683cdb7d53263569ad2e49dd87bd217939 -Author: lemoer -Date: Thu May 19 17:24:31 2016 +0200 - - Added comments and unfold deep "if"-construct in timeout_handler - -commit 5baecfd11be67bb80aab6c482e0b0ac98b267cca -Author: thorkill -Date: Thu May 19 15:48:15 2016 +0200 - - Prevent tincd from sending packets to unexpecting nodes - - Make tincd recognize when it was asleep and close connections to it's - peers. This happens when e.g. RoadWarrior has been suspended for - "longer" time period. After resume, it will start to communicate - with it's peers using the contextes it had before suspend. - - On the other side, the nodes closed the connections since PingTimeout - and/or TCP connection went down. - - Sending data to such unaware (sptps mostly) nodes will cause - havoc in the logs. Misleading the developers to wrong assumptions - that something is wrong with sptps. - - # Conflicts: - # src/net.c - -commit 0cf943753ab16704c818bebe74b4e7ea96399b05 -Author: thorkill -Date: Wed May 11 19:27:05 2016 +0200 - - Send PKT_PROBE only when handshake has been done already. - -commit 0edef996a6d944e9143f87dd3c72390979c33630 -Author: Guus Sliepen -Date: Sun May 1 20:35:26 2016 +0200 - - Releasing 1.1pre14. - -commit 3f6c663a06aac728912c4e47cbc2dc4343a3798c -Author: Guus Sliepen -Date: Sun May 1 12:07:44 2016 +0200 - - Revert "Remove tinc.service, it is not necessary." - - This reverts commit 0b6f84f96eeed20a0d771fedb72c0e19941adb7e. Although - systemd does automatically provide a "tinc.slice" when there is only a - tinc@.service template, it doesn't quite work the same way as - tinc.service. - -commit 0a6d89acc6417399dcf95efd68553d21e1f744e3 -Author: Guus Sliepen -Date: Sat Apr 30 20:55:12 2016 +0200 - - Releasing 1.1pre13. - -commit 2055c3e21d5b3f4217883d52d5e5b0fbad504785 -Author: Guus Sliepen -Date: Sat Apr 30 20:05:22 2016 +0200 - - AutoConnect now only chooses from nodes for which we know an address. - - Based partially on work from Rafał Leśniak. - -commit 0b6f84f96eeed20a0d771fedb72c0e19941adb7e -Author: Guus Sliepen -Date: Sat Apr 30 18:08:31 2016 +0200 - - Remove tinc.service, it is not necessary. - - Thanks to Alexander Ried for pointing out that if you have - tinc@.service template, systemd will provide a default slice containing - all instances of that template. So "systemctl start tinc" will still do - what we want it to do. - -commit 8377d0b8569b8d5240ad88683ad527c67237617a -Author: Guus Sliepen -Date: Wed Apr 27 20:30:36 2016 +0200 - - Fix BSD tun device support. - - This was broken by a botched merge from the master branch in commit d7f6737. - -commit 390d25f0b80dd7418e147de3561c70461628574d -Author: Guus Sliepen -Date: Sun Apr 24 13:23:06 2016 +0200 - - Releasing 1.1pre12. - -commit 5a7c6546a46bdcc97cf73a9aef206d2a83bb1eb4 -Author: Guus Sliepen -Date: Sat Apr 23 21:39:53 2016 +0200 - - Don't check file permissions on Windows during fsck. - -commit 83fa44ce42c67837dad30ba1538bf1fa8c49a47d -Author: Guus Sliepen -Date: Sat Apr 23 21:32:42 2016 +0200 - - Fix starting tinc as a service on Windows. - - Don't assume tincd.exe is in the working directory, especially now that - chdir() is called very early. We use GetModuleFileName() instead. - -commit 9a66d7499ae2c838c25f9c6bfcc277c3fa231dea -Author: Guus Sliepen -Date: Sat Apr 23 21:32:29 2016 +0200 - - Fix a compiler warning on Windows. - -commit ab5f4cbdc65cbc55062b36a6c11482c217884fe8 -Author: Guus Sliepen -Date: Sat Apr 23 17:28:30 2016 +0200 - - Fix possible read of freed memory when verifying the signature of a file. - -commit 76955a6c8b7a76d00ed401853c9d283e32d9ce1c -Author: Guus Sliepen -Date: Sat Apr 23 17:20:08 2016 +0200 - - Have "tinc fsck" recognize Ed25519PublicKey statements. - -commit 6805b157312c1f9adeee0035f540f4cbd63a79fd -Author: Guus Sliepen -Date: Sat Apr 23 16:05:41 2016 +0200 - - Move documentation of invitations to the manual. - -commit 51a0dc51451897cc0290d5040e42616dda9bdc8a -Author: Guus Sliepen -Date: Sun Apr 17 18:11:04 2016 +0200 - - Fix the "network" command in tinc shell. - -commit b6b302cee9de92d157f73d7739cc259d269c0ca0 -Author: Guus Sliepen -Date: Sun Apr 17 17:06:11 2016 +0200 - - Speed up AutoConnect at startup. - - Call periodic_handler() immediately at startup. Also, don't try to - connect to ourself. - -commit f934417aa658367587dadc81bd5c466baef407ef -Author: Guus Sliepen -Date: Sun Apr 17 16:23:31 2016 +0200 - - Don't call terminate_connection(myself->connection). - - It doesn't do anything except give a confusing error message that we are - closing the connection to ourself. Replace it with connection_del(). - This also fixes a double free. - -commit 2213ecaea550ce81c595464ad4347414bcb5d786 -Author: Guus Sliepen -Date: Sun Apr 17 16:01:49 2016 +0200 - - Handle special characters in sptps_test only if the --special option is given. - - sptps_test treats lines starting with #, ^ and $ specially, in order to - test the SPTPS protocol. However, this should only be done if explicitly - requested, otherwise it can unexpectedly fail. - -commit c2dc3784f127ef6db6e9960a4abecc1aab6f4e31 -Author: Guus Sliepen -Date: Sun Apr 17 14:38:37 2016 +0200 - - Add stricter checks for netnames. - - When passing a NetName via an invitation, we don't allow any characters - that are unsafe (either because they could cause shells to expand things, - or because they are not allowed on some filesystems). - - Also, warn when tinc is started with unsafe netnames. - -commit 097c69fc6a223213302fe9ffbe00a4c05357e660 -Author: Guus Sliepen -Date: Sun Apr 17 14:36:29 2016 +0200 - - Use ifconfig_header(). - -commit af9ee7ff003fb448b783ccf39347907adc239cb2 -Author: Guus Sliepen -Date: Sun Apr 17 14:04:57 2016 +0200 - - Chdir() to the configuration directory instead of /. - -commit 9bd978cc8ebf2fd9075f2be646fafd90128d403f -Author: Guus Sliepen -Date: Sun Apr 17 13:56:37 2016 +0200 - - Add a test for tinc-up creation from invitations. - -commit 0b96b6967256803c739a6b0a89d54ab8d6f63335 -Author: Guus Sliepen -Date: Sun Apr 17 13:55:36 2016 +0200 - - Fix compiler warnings. - -commit a08860ff8c2ad859836ed51c5629d6a85343e802 -Author: Guus Sliepen -Date: Sun Apr 17 13:55:18 2016 +0200 - - Fix gateway parsing in invitation files. - -commit 6d0452896673c36226c24144d4bde824a49c3950 -Author: Guus Sliepen -Date: Sun Apr 17 13:23:01 2016 +0200 - - Allow gateways to be specified for routes. - - Also improve the variable names, and ensure the % symbols in - %INTERFACE% are properly quoted. - -commit 03878f12150cbdb1aeb43e207404a0929a35ff13 -Author: Guus Sliepen -Date: Sun Apr 17 01:13:56 2016 +0200 - - Move some stray #includes. - -commit 3273e3254107a4b89cd9963012d5fac8927c417c -Author: Guus Sliepen -Date: Sun Apr 17 01:13:27 2016 +0200 - - Generate a tinc-up script from an invitation. - - This adds the ability for an invitation to provision an invitee with a - tinc-up script. This is quite strictly controlled; only address configuration - and routes are supported by adding "Ifconfig" and "Route" statements to - the invitation file. The "tinc join" command will generate a tinc-up script - from those statements, and will ask before enabling the tinc-up script. - -commit b2200f216658e07ab4e45592fa7de012a2ed96df -Author: Guus Sliepen -Date: Sat Apr 16 22:06:47 2016 +0200 - - Document how invitation files work. - - This should eventually be merged in to tinc.texi. - -commit a31e1f03c4eff16403178695d971a0838996ba2e -Author: Guus Sliepen -Date: Fri Apr 15 16:56:56 2016 +0200 - - Stop using SOL_TCP, SOL_IP and SOL_IPV6. - - Instead, use IPPROTO_TCP, _IP and _IPv6. This fixes an issue on OS X where - it didn't create an UDP socket that listened on IPv4. - -commit a0a8f8f81fc8da068e93088c7c13f689a96fac66 -Author: Guus Sliepen -Date: Fri Apr 15 16:30:45 2016 +0200 - - Fix crash at startup when Device is not specified on OS X. - -commit 8afb52a39a72805cd24b6979248135e0d8b17c32 -Author: Guus Sliepen -Date: Fri Apr 15 14:27:52 2016 +0200 - - Fix conditional checking of tun/tap headers on DragonFly BSD. - -commit 039d6d48afe00a0fa9e11bcdbfea8e996cce4ad0 -Author: Guus Sliepen -Date: Fri Apr 15 12:42:30 2016 +0200 - - Fix some compiler warnings from MinGW. - -commit 1f5c26102e228420fd954af1d73d3a89fc700d9d -Author: Guus Sliepen -Date: Fri Apr 15 12:30:01 2016 +0200 - - Fix generation of version_git.h for some versions of BSD make. - - In order to support VPATH builds, we have to use ${srcdir}/version.c as - the target for the rule that depends on the generation of version_git.h. - When not doing a VPATH build, ${srcdir} expands to ".", so the target - will be "./version.c". However, on some BSDs, make does not understand - that "./version.c" is the same as "version.c", and therefore it doesn't - trigger generating version_git.h when trying to build version.o. (It - works fine if you do a VPATH build, and OpenBSD's make does the right - thing in all cases.) - - The trick is to have version.c depend on ${srcdir}/version.c. Of course, - Linux's make knows this is nonsense and will complain about a circular - dependency, so add this rule only on BSD platforms. - -commit 0037ec7cb38994dda6ab5e4fa85ce595b9a59f6b -Author: Guus Sliepen -Date: Fri Apr 15 12:29:31 2016 +0200 - - Fix a non-working cast to get rid of a compiler warning. - -commit 25bcdad878eb7349d19ea877fdcc058d4c6b2242 -Author: Guus Sliepen -Date: Fri Apr 15 11:38:56 2016 +0200 - - Don't use HAVE_SYSTEM, the autoconf check was removed. - -commit cd5f222cc4e769395a7c6c8646abefe1d657f844 -Author: Guus Sliepen -Date: Fri Apr 15 11:25:18 2016 +0200 - - Remove use of strcpy() and sprintf(). - - Even though they were safe, compilers like to warn about them nowadays. - -commit d4410d0cce40929db9a0ce7042ef962f1867234d -Author: Guus Sliepen -Date: Fri Apr 15 11:10:50 2016 +0200 - - Don't assume sa.sa_family is a short int. - - Because FreeBSD's compiler complained about it. - -commit d704a89ecc0811eb0cdac4e4be8ff3bdb0838976 -Author: Guus Sliepen -Date: Fri Apr 15 11:00:14 2016 +0200 - - Add version_git.h and sample-config.tar.gz to CLEANFILES. - -commit 3cceae93f61a44d4f9f38d729555b2f31e209beb -Author: Guus Sliepen -Date: Thu Apr 14 23:51:18 2016 +0200 - - Make some platform-specific header checks conditional. - - Don't check for linux/if_tun.h on BSD platforms for example. - -commit d10834e92015f1e0e5bf74e03b161b3a5dc363fb -Author: Guus Sliepen -Date: Thu Apr 14 23:24:22 2016 +0200 - - Remove support for Windows 2000 and anything that doesn't support getaddrinfo(). - -commit 615ecb7a8a6e0ffc8d37f08fe46d5c50cef8b3e0 -Author: Guus Sliepen -Date: Thu Apr 14 23:10:59 2016 +0200 - - Remove checks for non-C99 compliant compilers. - -commit ed09fa4e03c907736b2be0a831d10863ce4cae84 -Author: Guus Sliepen -Date: Thu Apr 14 23:01:18 2016 +0200 - - Fix version_get.h generation on BSD. - - It doesn't like .PHONY rules that are actually doing stuff. So make a really - phony rule that does nothing and depend in it in the version_git.h rule. - -commit 2802b3a49797a0f58d6a8f4d9945d54acc64d996 -Author: Guus Sliepen -Date: Thu Apr 14 22:59:42 2016 +0200 - - Fix typo in Makefile.am. - -commit 46ebfbb6eb9966239f7826e002d99554420bbbc8 -Author: Guus Sliepen -Date: Thu Apr 14 17:29:25 2016 +0200 - - Use getcwd() instead of get_current_dir_name(). - -commit b5b04910b928c63a31a0859f04bf067ca9bd1cc2 -Author: Guus Sliepen -Date: Thu Apr 14 17:20:36 2016 +0200 - - Replace usleep() with nanosleep(). - -commit 491839a81aba00d4af50b66563cedaac4fa7028c -Author: Guus Sliepen -Date: Thu Apr 14 17:05:10 2016 +0200 - - Fix compiling under MinGW. - -commit 34ea20af73a35cd918ce9dc25796bebf9493b49c -Author: Guus Sliepen -Date: Thu Apr 14 17:03:01 2016 +0200 - - Remove checks for headers and functions that are in C99. - -commit fd3800324f4e4c67b087eaf5e0a61a184a270812 -Author: Guus Sliepen -Date: Wed Apr 13 15:34:16 2016 +0200 - - Make text files Markdown-compatible. - -commit 7f749c7e75c08549d7ce43838622624a8093de85 -Author: Guus Sliepen -Date: Mon Apr 11 15:28:26 2016 +0200 - - Update .gitignore. - -commit 9ba3e95a9a559240d16de71ca1513c7bfa98a70c -Author: Guus Sliepen -Date: Mon Apr 11 15:27:08 2016 +0200 - - Remove elliptic curve stubs from gcrypt/, add PRF implementation. - -commit 20dd1c21dc6d238200e62a1111a7d0d145168548 -Author: Guus Sliepen -Date: Fri Apr 8 17:49:49 2016 +0200 - - Really don't compile getopt*.c if the system provides getopt_long(). - -commit 9527622abc75ef41498de70ed6ded6bf5b38cfac -Author: Guus Sliepen -Date: Sat Apr 9 22:17:47 2016 +0200 - - Enable silent builds by default. - - Cleaner build messages make it easier to spot compiler warnings and errors. - Use make V=1 to get the verbose output back. - - # Conflicts: - # configure.ac - # doc/Makefile.am - -commit 413faffca356b25cf69ddf0a718730d46f9941bc -Author: Guus Sliepen -Date: Sun Apr 10 15:04:59 2016 +0200 - - Update links in the documentation. - - # Conflicts: - # doc/tinc.conf.5.in - # doc/tinc.texi - # src/avl_tree.c - # src/avl_tree.h - -commit 5cbc12b3d482231fc7e71fbe176c91971993760e -Author: Guus Sliepen -Date: Sun Apr 10 14:47:21 2016 +0200 - - Explicitly mention that LibreSSL can be used as well. - - # Conflicts: - # doc/tinc.texi - # m4/openssl.m4 - -commit d7f6737cfcae75e8c2f522c68aaedee0519a6131 -Author: Guus Sliepen -Date: Mon Apr 11 14:49:51 2016 +0200 - - Update support for BSD tun/tap devices, add support for OS X utun interfaces. - -commit 2a7871990bc401921b8bb9accbc6a8206d564f72 -Author: Guus Sliepen -Date: Sun Nov 1 21:07:56 2015 +0100 - - Update "now" after connect() when making outgoing connections. - - It could be that address resolution takes a long time, don't let that - count against a connection. This is especially important when using a - nameserver from the VPN. - - # Conflicts: - # src/net_socket.c - -commit cadbf587a09bd4adde664cd635b962315228b3f5 -Author: Guus Sliepen -Date: Sun May 3 20:06:12 2015 +0200 - - Never call putenv() with data on the stack. - - Even though we are using putenv() here to remove items from the - environment, there is no guarantee that putenv() doesn't add the - argument to the environment anyway. In that case, we have to make sure - that it doesn't go away. We also don't want a memory leak, so keep a - list of things we unputenv()ed around, so we can reuse things. - - Thanks to Poul-Henning Kamp for pointing out this problem. - - # Conflicts: - # src/process.c - -commit 0e8e53b4cee8f1ea27bad501cbc18292ced54fa1 -Author: Guus Sliepen -Date: Tue Apr 14 11:20:24 2015 +0200 - - Fix --logfile without a filename on Windows. - - On Windows, the log filename now defaults to "tinc.log" in the same - directory as tinc.conf. - - # Conflicts: - # src/tincd.c - -commit c544e5e8fe22250b230a46f0340483db5403a6c1 -Author: Guus Sliepen -Date: Sun Apr 10 17:22:41 2016 +0200 - - Support ToS/DiffServ for IPv6 meta and UDP connections. - - Also remember ToS/DiffServ priority for each socket individually. This - is a port of commits c72e237 and 042a6c1. - -commit e355088535ee9ebb12a4db0043bf6a9743085b28 -Author: Guus Sliepen -Date: Fri Apr 8 18:09:30 2016 +0200 - - Use iface instead of interface. - - This was accidentally added in commit 2f03a5d. - -commit 6f97c0011572a1e12fa6267068b7f3fd46ceffd8 -Author: Guus Sliepen -Date: Sun Apr 10 17:01:04 2016 +0200 - - Update THANKS. - -commit 8be447ac0227a8ecb89facb2831c121a7ca81748 -Author: Guus Sliepen -Date: Sun Apr 10 16:51:03 2016 +0200 - - Update .gitignore. - -commit 9f0fb224a6c2eab93b6917ef6c034423c49126cd -Author: Guus Sliepen -Date: Fri Apr 8 17:49:49 2016 +0200 - - Don't compile getopt*.c if the system provides getopt_long(). - - # Conflicts: - # configure.ac - # src/Makefile.am - # src/tincd.c - -commit c2726dae62d632883f822741f9619265640e57b3 -Author: Guus Sliepen -Date: Sun Apr 10 16:38:45 2016 +0200 - - Fix typo. - - Found by LunarShaddow. - -commit e44c337eae674120745f7c7c56a1a70919ff40ca -Author: LunarShaddow -Date: Mon Mar 7 15:43:04 2016 +0800 - - re-arrange include sequence to avoid a mingw introduced bug. - refers: https://www.cygwin.com/ml/cygwin/2012-12/msg00194.html - - # Conflicts: - # src/cygwin/device.c - -commit af83d0b9e87fe795a3d01d0ee3fb35e0d8579b88 -Author: LunarShaddow -Date: Mon Mar 7 15:42:34 2016 +0800 - - fix typo - -commit bf50b3502a022b406424d0d03aaf7670133452b2 -Author: Guus Sliepen -Date: Sun Feb 28 16:38:49 2016 +0100 - - Fix for botched cherry-pick commit 60fb230. - -commit 1ceea259c3ba5efb9b8b12161e75256270ba4804 -Author: Guus Sliepen -Date: Sat Feb 27 14:46:01 2016 +0100 - - Add warnings for bad combinations of Device and Interface. - - On Linux, the name of the tun/tap interface can be set freely. However, - on most other operating systems, tinc cannot change the name of the - interface. In those situations, it is possible to specify a Device and - an Interface that conflict with each other. On BSD, this can cause - $INTERFACE to be set incorrectly, on Windows, this results in a - potentially unreliable way in which a TAP-Win32 interface is selected. - - # Conflicts: - # src/bsd/device.c - -commit e3f80e9167ecef8db8add9359b6660ecdcaeb7af -Author: Guus Sliepen -Date: Sat Feb 27 14:22:36 2016 +0100 - - Small fixes for the documentation. - - # Conflicts: - # doc/tinc.texi - -commit 72cfd4f047210cc7cab9014cbf48e007bfd704e6 -Author: Guus Sliepen -Date: Sat Feb 27 14:21:53 2016 +0100 - - Clarify that scripts are called synchronously. - - # Conflicts: - # doc/tinc.conf.5.in - # doc/tinc.texi - -commit 4d7469e0da6652bddc8acde499068db4b41b646d -Author: Guus Sliepen -Date: Sun Feb 28 16:28:28 2016 +0100 - - Fix forwarding of edge updates. - - Commit e4670fc accidentily prevented ADD_EDGE messages from propagating - in some cases. - -commit 60fb2308e5bf1fd9ce642f6c4bcde81997593504 -Author: Guus Sliepen -Date: Sat Feb 27 14:18:20 2016 +0100 - - Improve performance of edge updates. - -commit 994adadf2752fd7515ee30ed5fdb91178a615fe9 -Author: Vittorio Gambaletta (VittGam) -Date: Fri Sep 25 16:51:51 2015 +0200 - - Remove forward declaration for do_decrement_ttl. - - Signed-off-by: Vittorio Gambaletta - - # Conflicts: - # src/route.c - -commit 0f3ae1a9f29c845a69e44a4f691f43d6a6651583 -Author: Vittorio Gambaletta (VittGam) -Date: Fri Sep 25 15:35:28 2015 +0200 - - s/broadcast_packet_helper/route_broadcast/ - - Signed-off-by: Vittorio Gambaletta - - # Conflicts: - # src/route.c - -commit 496f775568873bb769e48ceb644b15ab9f150d62 -Author: Vittorio Gambaletta (VittGam) -Date: Fri Sep 25 04:52:25 2015 +0200 - - Fix DecrementTTL option for packets destined to the local node. - - Signed-off-by: Vittorio Gambaletta - - # Conflicts: - # src/route.c - -commit 17e54ea0bec4d3a3b9a760854dde6039c7a1c421 -Author: Vittorio Gambaletta (VittGam) -Date: Fri Sep 4 17:04:03 2015 +0200 - - Try to reply with node address only when decrementing the TTL. - - Signed-off-by: Vittorio Gambaletta - -commit 92203bdbcb1af4a52c7ca9d0e1a271168435c905 -Author: Vittorio Gambaletta (VittGam) -Date: Fri Sep 4 04:00:57 2015 +0200 - - Fix source IP address for ICMP unreachable packets generated by tinc. - - Try to send ICMP unreachable replies from an address assigned to the - local machine, instead of the destination address of the original - packet. - - The address is found by looking up the route towards the sender of - the packet that generated the error; in usual configurations, this - is the tinc interface. - - This also fixes the traceroute display in mtr when using the - DecrementTTL option. - - Signed-off-by: Vittorio Gambaletta - - # Conflicts: - # src/route.c - -commit a8a3a2c8ceb19bcb6c2c3ef0647c94d7d0624b7a -Author: Vittorio Gambaletta (VittGam) -Date: Thu Sep 3 16:02:50 2015 +0200 - - Fix DecrementTTL option. - - The option was not actually working, as it could be seen on traceroute or mtr. - - The problem is that it was checking if the TTL was < 1 (so equal to 0) before decrementing it. - - This meant that a packet with a TTL of 1 was being sent with a TTL of 0 on the VPN, instead of being discarded with the ICMP error message. - - Signed-off-by: Vittorio Gambaletta - - # Conflicts: - # src/route.c - -commit ac9e32ff91ee2318c49808522f0c7d458c79eb44 -Author: Guus Sliepen -Date: Sun Feb 28 15:48:19 2016 +0100 - - Use nostdinc instead of overriding DEFAULT_INCLUDES. - -commit 96dd6e5f6c6f3f7717102fb3b38759b6cc0c0555 -Author: Guus Sliepen -Date: Sun Jul 5 16:03:03 2015 +0200 - - Only check for -fno-strict-overflow if -fwrapv does not work. - -commit 92f0c4db77a5e2733442491227625d0233f94a97 -Author: Guus Sliepen -Date: Sun Feb 28 15:39:41 2016 +0100 - - Update .gitignore. - -commit d8ca00fe40ff4b6d87e7e64c273f536fab462356 -Author: Guus Sliepen -Date: Wed Jan 27 00:09:29 2016 +0100 - - Add the ability to sign and verify files. - -commit 7418e9077f84db10ef6bb082a375870a7130bd7d -Merge: 420989e4 b6ed5c13 -Author: Guus Sliepen -Date: Sun Jan 17 23:29:23 2016 +0100 - - Merge remote-tracking branch 'mweinelt/tinc-gui' into 1.1 - -commit 420989e4c3ff109c7d077b2f8c06506540f1c0bd -Author: Guus Sliepen -Date: Thu Jan 14 15:07:22 2016 +0100 - - Only add a reflexive address when we're sure it's working. - -commit cda5a477c8138226d184a176256d559971b4f7ed -Author: Guus Sliepen -Date: Thu Dec 10 16:45:05 2015 +0100 - - Use static buffers for recvmmsg(), initialize them only as needed. - - As suggested by Michael Tokarev. - -commit e4fd81ed2d66b8fe3c2857244fe3da85c803cf60 -Author: Guus Sliepen -Date: Thu Dec 10 16:30:32 2015 +0100 - - Add support for recvmmsg(). - - Based on a patch from Samuel Thibault and input from Michael Tokarev. - -commit cef40b8b978694fc0e7c02e292fcbb60806bf028 -Author: Guus Sliepen -Date: Thu Nov 26 11:29:54 2015 +0100 - - list_delete() already free()s the deleted element. - -commit 9fdf4278f8c8c1563d45205c9e9f1bc351bd814f -Author: Guus Sliepen -Date: Tue Nov 24 16:48:44 2015 +0100 - - Don't leave dead outgoing_t's in the outgoing_list. - - If an outgoing connection cannot be made because no address is known for - it, it should be removed from the outgoing_list, otherwise it will - prevent it from being re-added later when we do know addresses for it. - -commit c58eba587da3ac884c6c18b64c262aed8fd1c452 -Author: Etienne Dechamps -Date: Sun Nov 22 18:57:59 2015 +0000 - - Add upnp.h to tincd SOURCES. - - This was missing from 513bffe1fee07bcbcb50691e221874adc1507857. - -commit 613d586afd22159cee57c9524218c7200f4f1096 -Author: Etienne Dechamps -Date: Sun Nov 22 17:14:14 2015 +0000 - - Don't unset validkey when receiving SPTPS handshakes over ANS_KEY. - - This fixes a hairy race condition that was introduced in - 1e89a63f1638e43dee79afbb18d5f733b27d830b, which changed - the underlying transport of handshake packets from REQ_KEY to ANS_KEY. - Unfortunately, what I missed in that commit is, on the receiving side, - there is a slight difference between req_key_h() and ans_key_h(): - indeed, the latter resets validkey to false. - - The reason why this is not a problem during typical operation is - because the normal SPTPS key regeneration procedure looks like this: - - KEX -> - <- KEX - SIG -> - <- SIG - - All these messages are sent over ANS_KEY, therefore the receiving side - will unset validkey. However, that's typically not a problem in practice - because upon reception of the last message (SIG), SPTPS will call - sptps_receive_record(), which will set validkey to true again, and - everything works out fine in the end. - - However, that was the *typical* scenario. Now let's assume that the - SPTPS channel is in active use at the same time key regeneration - happens. Specifically, let's assume a normal VPN data packet sneaks in - during the key regeneration procedure: - - KEX -> - <- KEX - <- (SPTPS packet, over TCP or UDP) - <- KEX (wtf?) - SIG -> (refused with Invalid packet seqno: XXX != 0) - - At this point, both nodes are extremely confused and the SPTPS channel - becomes unusable with various errors being thrown on both sides. The - channel will stay down until automatic SPTPS channel restart kicks in - after 10 seconds. - - (Note: the above is just an example - the race can occur on either side - whenever a packet is sent during the period of time between KEX and SIG - messages are received by the node sending the packet.) - - I've seen this race occur in the wild - it is very likely to occur if - key regeneration occurs on a heavily loaded channel. It can be - reproduced fairly easily by setting KeyExpire to a short value (a few - seconds) and then running something like ping -f foobar -i 0.01. - - The reason why this occurs is because tinc's TX code path triggers the - following: - - - send_packet() - - try_tx() - - try_tx_sptps() - - validkey is false because we just received an ANS_KEY message - - waitingforkey is false because it's not used for key regeneration - - send_req_key() - - SPTPS channel restart (sptps_stop(), sptps_start()). - - Obviously, it all goes downhill from there and the two nodes get very - confused quickly (for example the seqno gets reset, hence the error - messages). - - This commit fixes the issue by keeping validkey set when SPTPS data is - received over ANS_KEY messages. - -commit 95935cecb6290fd13b1266a96be1b8f9c1c54d0f -Author: Guus Sliepen -Date: Sat Nov 21 19:41:14 2015 +0100 - - Update THANKS file. - -commit 0f6d34dc1b43edc6f5bea45c17ce2d6a417265f1 -Author: Etienne Dechamps -Date: Sun Nov 15 17:42:14 2015 +0000 - - Try to ensure we build correctly against various libminiupnpc versions. - - Unfortunately, libminiupnpc has a somewhat... "peculiar" approach to - backwards compatibility for their API, where they reserve the right to - make breaking changes when they feel like it, forcing users to resort - to #ifdefs to ensure they use the correct API. Sigh. - - Previously, tinc would only build against API versions <= 13, because I - was doing my initial development using miniupnpc-1.9.20140610 which is - the version that ships with Debian. The changes in this commit are - required for tinc to build against more recent versions, from - 1.9.20150730 to the latest one at the time of this commit, 1.9.20151026. - -commit 675e3b497bdc87f5a4dfdef7508cd2070850e69e -Author: Etienne Dechamps -Date: Sun Nov 15 15:30:01 2015 +0000 - - Allow tinc to be built with miniupnpc on Windows. - - Contrary to what I expected, it so happens that modern versions of MinGW - include an implementation of pthread natively by default, so there is no - need to introduce Win32-specific threading code. This means the only - changes required to make UPnP work on Windows are just build parameter - tuning. - - This commit forces MinGW to be built statically. This makes linking - against miniupnpc simpler (otherwise we would have to handle the mess - of dllimport & co.) and it also prevents libwinpthread from being linked - dynamically (which it is by default), as this would require additional - DLLs to be distributed. Since static linking is how tinc is - traditionally built on Windows, I don't expect this to be a big deal. - -commit 513bffe1fee07bcbcb50691e221874adc1507857 -Author: Etienne Dechamps -Date: Sun Nov 15 13:40:07 2015 +0000 - - Add UPnP support to tincd. - - This commit makes tincd capable of discovering UPnP-IGD devices on the - local network, and add mappings (port redirects) for its TCP and/or UDP - port. - - The goal is to improve reliability and performance of tinc with nodes - sitting behind home routers that support UPnP, by making it less reliant - on UDP Hole Punching, which is prone to failure when "hostile" NATs are - involved. - - The way this is implemented is by leveraging the libminiupnpc library, - which we have just added a new dependency on. We use pthread to run the - UPnP client code in a dedicated thread; we can't use the tinc event loop - because libminiupnpc doesn't have a non-blocking API. - -commit 2bb567c6a31e333ebdd16d6d076ba9976e6ed4fb -Author: Etienne Dechamps -Date: Sat Nov 14 14:47:42 2015 +0000 - - Add a new optional dependency on the miniupnpc library. - - The miniupnpc library is a lightweight UPnP-IGD client. - - http://miniupnp.free.fr/ - - Contrary to other libraries, this dependency is disabled by default. - This is because the library is somewhat obscure and is only tangentially - useful, so enabling it by default would probably annoy most users. - -commit bdd84660c756437cf3bc8f64adf612055acc84ea -Author: Etienne Dechamps -Date: Sat Nov 7 11:04:13 2015 +0000 - - Make sure the packet source MAC address is always set. - - When tinc is used in router mode with a TAP device, Ethernet (MAC) - headers are not present in packets flowing over the VPN; it is the - node's responsibility to fill out this header before handing the - packet over to the TAP interface (which expects such headers). - - Currently, tinc fills out the destination MAC address of the packet - (otherwise the host would not recognize the packets, and nothing would - work), but it does not fill out the source MAC address. In practice this - doesn't seem to cause any real issues (the host doesn't care about the - source address), but it does look weird when looking at the packets with - a sniffer, and it also result in the following valgrind warning: - - ==13651== Syscall param write(buf) points to uninitialised byte(s) - ==13651== at 0x5C4B620: __write_nocancel (syscall-template.S:81) - ==13651== by 0x1445AA: write_packet (device.c:183) - ==13651== by 0x118C7C: send_packet (net_packet.c:1259) - ==13651== by 0x12B70A: route_ipv4 (route.c:443) - ==13651== by 0x12D5F8: route (route.c:971) - ==13651== by 0x1152BC: receive_packet (net_packet.c:250) - ==13651== by 0x117E1B: receive_sptps_record (net_packet.c:904) - ==13651== by 0x1309A8: sptps_receive_data_datagram (sptps.c:488) - ==13651== by 0x130A90: sptps_receive_data (sptps.c:508) - ==13651== by 0x115569: receive_udppacket (net_packet.c:286) - ==13651== by 0x119856: handle_incoming_vpn_data (net_packet.c:1499) - ==13651== by 0x10F3DA: event_loop (event.c:287) - ==13651== Address 0xffeffea3a is on thread 1's stack - ==13651== in frame #6, created by receive_sptps_record (net_packet.c:821) - ==13651== - - This commit fixes the issue by filling out the source MAC address. It is - generated by negating the last byte of the device MAC address, which is - consistent with what route_arp() does. - - In addition, this commit stops route_arp() from filling out the Ethernet - header of the packet - this is the responsibility of send_packet(), not - route(). - -commit 684bd659ae0c6ca623422851c245188037658698 -Author: Etienne Dechamps -Date: Wed Nov 4 19:18:12 2015 +0000 - - Revert "Cache node IDs in a hash table for faster lookups." - - This reverts commit c2319e90b16962fe899bc60abc8af0e2542bb176. - - As a general principle, I do not believe it is worthwhile to cache - nodes. Sure, it brings lookup time down from O(log n) to O(1), but - considering that the scalability target of tinc is around 1000 nodes - and log2(1000) is 10, that looks like premature optimization; tree - lookups should already be very fast. Therefore, I believe it makes sense - to remove the cache as a code cleanup initiative. - -commit eeebff55c07c09c5bc5e62a7b2a21f68ecd1c802 -Author: Etienne Dechamps -Date: Wed Nov 4 19:07:14 2015 +0000 - - Use a splay tree for node UDP addresses in order to avoid collisions. - - This commit replaces the node UDP address hash table "cache" with a - full-blown splay tree, aligning it with node_tree (name-indexed) and - node_id_tree (ID-indexed). - - I'm doing this for two reasons. The first reason is to make sure we - don't suddenly degrade to O(n) performance when two "hot" nodes end up - in the same hash table bucket (collision). - - The second, and most important, reason, has to do with the fact that - the hash table that was being used overrides elements that collide. - Indeed, it turns out that there is one scenario in which the contents of - node_udp_cache has *correctness* implications, not just performance - implications. This has to do with the way handle_incoming_vpn_data() is - implemented. - - Assume the following topology: - - A <-> B <-> C - - Now let's consider the perspective of tincd running on B, and let's - assume the following is true: - - - All nodes are using the 1.1 protocol with node IDs and relaying - support. - - Nodes A and C have UDP addresses that hash to the same value. - - Node C "wins" in the node_udp_cache (i.e. it overwrites A in the - cache). - - Node A has a "dynamic" UDP address (i.e. an UDP address that has been - detected dynamically and cannot be deduced from edge addresses). - - Then, before this commit, A would be unable to relay packets through B. - - This is because handle_incoming_vpn_data() will fall back to - try_harder(), which won't be able to match any edge addresses, doesn't - check the dynamic UDP addresses, and won't be able to match any keys - because this is a relayed packet which is encrypted with C's key, not - B's. As a result, tinc will fail to match the source of the packet and - will drop the packet with a "Received UDP packet from unknown source" - message. - - I have seen this happen in the wild; it is actually quite likely to - occur when there are more than a handful of nodes because node_udp_cache - only has 256 buckets, making collisions quite likely. This problem is - quite severe because it can completely prevent all packet communication - between nodes - indeed, if node A tries to initiate some communication - with C, it will use relaying at first, until C responds and helps A - establish direct communication with it (e.g. hole punching). If relaying - is broken, C will not help establish direct communication, and as a - result no packets can make it through at all. - - The bug can be reproduced fairly easily by reproducing the topology - above while changing the (hardcoded) node_udp_cache size to 1 to force a - collision. One will quickly observe various issues when trying to make A - talk to C. Setting IndirectData on B will make the issue even more - severe and prevent all communication. - - Arguably, another way to fix this problem is to make try_harder() - compare the packet's source address to each node's dynamic UDP - addresses. However, I do not like this solution because if two "hot" - nodes are contending on the same hash bucket, try_harder() will be - called very often and packet routing performance will degrade closer to - O(N) (where N is the total number of nodes in the graph). Using a more - appropriate data structure fixes the bug without introducing this - performance problem. - -commit 7a8515112a4bf94da3cec157ada6e0794a03b946 -Author: Guus Sliepen -Date: Mon Oct 26 13:46:30 2015 +0100 - - Avoid undefined behavior. - - Left shifts of negative values is undefined in C. This happens a lot in - the Ed25519 code. Cast to unsigned first, then cast the result back to - signed where necessary. - -commit b6ed5c134fc43d438c622d24f949c240632f5e67 -Author: Martin Weinelt -Date: Mon Sep 28 06:34:15 2015 +0200 - - tinc-gui: Properly initialize class attributes for VPN in __init__ - -commit 927efeff6242e262b176976a1eb298891578f77d -Author: Martin Weinelt -Date: Mon Sep 28 05:54:17 2015 +0200 - - tinc-gui: Use ArgumentParser, default to python2 - -commit e92bb7d1dd7adc02503e3ee795e53b15634df570 -Author: Martin Weinelt -Date: Mon Sep 28 05:34:22 2015 +0200 - - tinc-gui: Fix GetListCtrl method name in SuperListCtrl - - wxPython wrongly expects camelcase method names, this however - is against PEP8 - -commit 53333d6d0d870de6801352bda106286255f14319 -Author: Martin Weinelt -Date: Mon Sep 28 05:31:59 2015 +0200 - - tinc-gui: Update Node object to correctly parse responses - - The application was expecting a different respoonse from tinc - and wouldn't properly it, and thus not start at all. - -commit 0c7e0210d900185d4c1a9ffd969dc2a26d9523a9 -Author: Martin Weinelt -Date: Mon Sep 28 05:20:03 2015 +0200 - - tinc-gui: Reformat codebase according to PEP8 - -commit 73068238436d8a22abb86e67b08f573b09fd04e1 -Author: Guus Sliepen -Date: Fri Sep 25 10:06:18 2015 +0200 - - Fix a few memory leaks in the CLI found by AddressSanitizer. - -commit 543c0abbd91a7b076670b8763548b8d5849860a0 -Author: Guus Sliepen -Date: Fri Sep 25 10:05:24 2015 +0200 - - Fix struct node_status_t. - - Although not a problem for tinc internally, the size of the struct was 12 - bytes instead of 4, causing some problems when interpreting the value - received from tincd by the CLI. - -commit 706d855e507980de3845556989d7de7a3b9c76e8 -Author: Guus Sliepen -Date: Thu Sep 24 22:20:00 2015 +0200 - - Replace bare if statements with AS_IF in configure.ac. - -commit f54a87b800d551bec4532a5d3bf124d02e167856 -Author: Guus Sliepen -Date: Thu Sep 24 21:53:49 2015 +0200 - - Optionally install systemd service files. - - If --with-systemd is given when running the configure script, two - systemd service files will be installed. There is a template - tinc@.service, which can be used to control individual instances of - tinc. For example: - - systemctl enable tinc@foo - - Will create an instance for tinc with netname foo. There is also a - tinc.service, which can be used to start and stop all instances at once. - -commit 5ad43673acf03f86643f1463f1ebfa6e9ca189cc -Author: Guus Sliepen -Date: Thu Sep 24 17:10:25 2015 +0200 - - Add -I m4 back to ACLOCAL_AMFLAGS. - - In commit b7b5d51, AC_CONFIG_MACRO_DIRS([m4]) was added to configure.ac, - which is the current proper way of including the m4 directory. However, - old versions of autoconf ignore it and need the -I m4 statement in - Makefile.am. Both the old and new way of indicating that the m4/ - directory should be included can coexist. - -commit ae89a25695411149a7499189c9771762ad1f1726 -Author: Nathan Stratton Treadway -Date: Sat Sep 12 16:33:52 2015 +0200 - - Fix invalid checksum generation. - - Use equation 3 given in RFC 1624 and the UpdateTTL() example function given - RFC 1141. - - # Conflicts: - # src/route.c - -commit 56a8b90d863171d62e0a337b5635fbfc53a67fb0 -Author: Guus Sliepen -Date: Wed Jul 22 14:33:56 2015 +0200 - - In sssp_bfs(), never try to update myself. - -commit f75e6f61f280b138082b87ce69bdbdee3e4ba56e -Author: thorkill -Date: Sun Jul 19 18:53:29 2015 +0200 - - Do not access e->to->prevedge if not defined - - In some cases - mostly when e->to == myself the prevedge is set to NULL, - causing invalid memory access. In rare cases this may lead to malformed mst - or segfaults. - -commit f92c3446f2052a59d1e6a28f1bc7cec278cb1e48 -Author: Guus Sliepen -Date: Wed Jul 15 15:12:53 2015 +0200 - - Use AC_CONFIG_MACRO_DIR() instead of _DIRS(). - - The former is guaranteed to work with autoconf 2.58 and later, and we - don't have multiple m4 directories anyway. - -commit 9ca1750245b28ed8306f150b6371139c656be111 -Author: Guus Sliepen -Date: Sun Jul 12 16:31:32 2015 +0200 - - Fix the PRF function when compiling without OpenSSL. - -commit 3c54765bcdf8bd6114da0cb31f45404950089e3a -Author: thorkill -Date: Tue Jul 7 23:14:08 2015 +0200 - - Prevent tinc from forgeting e->local_address - - If ADD_EDGE came from tinc version 1.0.x local_address.sa.sa_family is set to 0. - If it came from tinc version 1.1.x forwarded for older verion it will be 255 - AF_UNKNOWN. - -commit 1e7ef381980a5c4c84d699522265290dde5ac728 -Author: thorkill -Date: Tue Jul 7 21:19:26 2015 +0200 - - Make sure we do not allocate new edge when talking to old nodes and the same edge already exists - - When tinc gets ADD_EDGE from older versions it will allocate - new edge in protocol_edge.c:189 due to missed case in lines 149-171 where - local_address is not defined. - -commit 7b831804aafa370a6c8d9e86caee31cda1a3dd72 -Author: Guus Sliepen -Date: Sun Jul 12 13:08:34 2015 +0200 - - Make subnet caches static. - -commit 322ffadac43c7e357cc12340d7b8112a0aaad5af -Author: thorkill -Date: Tue Jun 30 19:11:45 2015 +0200 - - Included missing names.h - -commit b7b5d516137713c594990cd982a29f7e5718b45b -Author: Guus Sliepen -Date: Sun Jul 12 13:05:51 2015 +0200 - - Use AC_CONFIG_MACRO_DIRS([m4]). - -commit 97457716d7efc541d18d08263bbd338e94195bd9 -Author: Guus Sliepen -Date: Sun Jul 12 12:55:13 2015 +0200 - - Remove unused code that caused warnings about an uninitialized variable. - -commit b22b9d438970a0442559949da35be9cc0ffaec00 -Author: thorkill -Date: Mon Jun 29 00:23:13 2015 +0200 - - Removed double break; - -commit b396585383fe12c890ef7953efaa13a83963b5d7 -Author: Guus Sliepen -Date: Sun Jul 12 12:33:07 2015 +0200 - - Fix undefined behaviour when left-shifting signed integers. - - Found by -fsanitize=undefined. - -commit de7d9ee437bc0e5d72f8c6744e1df7ea7b64d2e9 -Author: Guus Sliepen -Date: Sat Jul 4 17:53:11 2015 +0200 - - Call sockaddrfree(&e->local_address) in free_edge() instead of exit_edges(). - - The proper place to clean up resources of objects is in their - destructor. This makes sure proper cleanup when edge_del() is called as - well. At exit, free_edge() is called on all edges by free_edge_tree(), - which is called by exit_nodes(). - -commit 36cec9af88909cb2cf012d609e5c4d8c444ddab9 -Author: Guus Sliepen -Date: Sat Jul 4 17:51:05 2015 +0200 - - Coalesce two if statements that check for the same thing. - -commit 14ccf509540e338502ad806f60bdc3f71ddce66f -Author: Jo-Philipp Wich -Date: Thu Jun 18 23:58:31 2015 +0200 - - fix musl compatibility - - Let configure include sys/if_tun.h when testing for netinet/if_ether.h - to detect the Kernel/libc header conflict on musl. - - After this patch, configure will correctly detect netinet/if_ether.h as - unusable and the subsequent compilation will not attempt to use it. - - Conflicts: - src/have.h - -commit 37588b8d5cface1bc72424a198b1cc1a6044adb0 -Author: Guus Sliepen -Date: Sat Jul 4 17:18:40 2015 +0200 - - Don't #include OpenSSL headers when compiling without OpenSSL. - -commit abb24e9d71b3edb9cacf4c04361cc0dfd4e6a061 -Author: thorkill -Date: Sat Jul 4 03:21:01 2015 +0200 - - Cleanup local_address in protocol_edge.c - - In line 131 local_address has been defined, - but the memory was never freed on return. - -commit 92df36a610421ed5fcae90e832f64e3acfb7d431 -Author: thorkill -Date: Sat Jul 4 02:39:12 2015 +0200 - - Cleanup edges stored in edge_weight_tree on exit - - protocol_edge.c: 131 defines local_address using str2sockaddr - - str2sockaddr() allocates memory which has to be freed on exit. - -commit 1140ca6d3004b228947bad8736f0b49d6b169267 -Author: thorkill -Date: Sat Jul 4 00:29:36 2015 +0200 - - Fixed 2 leaks in setup_myself() - -commit 0267aef826ba627aba3a525b36c0e7bfc0f9a221 -Author: Florian Klink -Date: Thu Jul 2 12:35:42 2015 +0200 - - setup_outgoing_connection: log to LOG_DEBUG on if no known address - - With AutoConnect = yes, tinc tries to establish connections to known hosts. - However, you could have set no Address for this host, which is perfectly fine - (as long as there is at least one bootstrap node with an address or a local - discovered node already part of the network) - - So log this to LOG_DEBUG - -commit 91355b9ac5a80d6d7da6951a72ea0c22651bdfa8 -Author: Florian Klink -Date: Thu Jul 2 12:35:41 2015 +0200 - - (read|append)_config_file: log open errors as LOG_DEBUG - - In a "decentrally managed vpn" it is very likely that host config - files for some reachable nodes do not exist. Currently, tinc - fills the logs with "Cannot open config file" messages. - - This commit changes the log level to LOG_DEBUG so - syslog doesn't get filled by default. - -commit ebffa40aa7832459f63801e3a91cc741e6b339a8 -Author: Etienne Dechamps -Date: Sat Jun 20 11:41:20 2015 +0100 - - Protect against callbacks removing items from the io tree. - - The definition of the splay_each() macro is somewhat complicated for - syntactic reasons. Here's what it does in a more readable way: - - for (splay_node_t* node = tree->head; node;) { - type* item = node->data; - splay_node_t* next = node->next; - - // RUN USER BLOCK with (item) - - node = next; - } - - list_each() works in the same way. Since node->next is saved before the - user block runs, this construct supports removing the current item from - within the user block. However, what it does *not* support is removing - *other items* from within the user block, especially the next item. - Indeed, that will invalide the next pointer in the above loop and - therefore result in an invalid pointer dereference. - - Unfortunately, there is at least one code path where that unsupported - operation happens. It is located in ack_h(), where the authentication - protocol code detects a double connection (i.e. being connected to - another node twice). Running in the context of a socket read event, this - code will happily terminate the *other* metaconnection, resulting in its - socket being removed from the io tree. If, by misfortune, this other - metaconnection happened to have the next socket FD number (which is - quite possible due to FD reuse - albeit unlikely), and was part of the - io tree (which is quite likely because if that connection is stuck, it - will most likely have pending writes) then this will result in the next - pending io item being destroyed. Invalid pointer dereference ensues. - - I did a quick audit of other uses of splay_each() and list_each() and - I believe this is the only scenario in which this "next pointer - invalidation" problem can occur in practice. While this bug has been - there since at least 6bc5d626a8726fc23365ee705761a3c666a08ad4 (November - 2012), if not sooner, it happens quite rarely due to the very specific - set of conditions required to trigger it. Nevertheless, it does manage - to crash my central production nodes every other week or so. - -commit 7f020cf456b327313f0cfa8d103fb14f06f71994 -Author: Dato Simó -Date: Tue Jun 16 20:44:45 2015 -0300 - - Fix typo in tinc.texi. - -commit 45a46f068cf8fbe6cc8c59673de2d8580d18f87f -Author: Guus Sliepen -Date: Wed Jun 10 23:42:17 2015 +0200 - - Fix crash is sptps_logger(). - - Unfortunately, sptps_logger() cannot know if s->handle is pointing to a - connection_t or a node_t. But it needs to print name and hostname in - both cases. So make sure both types have name and hostname fields at the - start with the same offset. - -commit bfe231b977284ba78a582db96a05b5854ddf0d91 -Author: Guus Sliepen -Date: Sun Jun 7 23:20:14 2015 +0200 - - Fix alignment of output of sptps_speed. - -commit a797b4a19235be740c51bcb3bb6ec5de01915f46 -Author: Guus Sliepen -Date: Sun Jun 7 23:14:48 2015 +0200 - - Fix receiving SPTPS data in sptps_speed and sptps_test. - - The sptps_receive_data() was changed in commit d237efd to only process - one SPTPS record from a stream input. So now we have to put a loop - around it to ensure we process everything. - -commit d8d1ab4ee1e92ec84fe9ea86eec2396275483a92 -Author: Guus Sliepen -Date: Sun Jun 7 22:50:05 2015 +0200 - - Fix warnings about missing return value checks. - - In some harmless places, checks for the return value of ECDSA and RSA - key generation and verification was omitted. Add them to keep the - compiler happy and to warn end users in case something is wrong. - -commit ab0576a2034b03f92943ac477e4e97731a899554 -Author: Guus Sliepen -Date: Sun Jun 7 22:25:22 2015 +0200 - - Fix autoconf check for function attributes. - - GCC warns when a function attribute has no effect. The autoconf check - turns warnings about attributes into errors, therefore thinking that - they did not work. The reason was that the test function returned void, - which is not suitable for checking both __malloc__ and - __warn_unused_result__. - -commit 84ecc972e5c11f683ac618c5a734a17c295d9b46 -Author: Guus Sliepen -Date: Sun May 31 23:51:39 2015 +0200 - - Fix missing return value caused by the previous commit. - -commit eca357ed916c9782a64a68a2f30b144d84027795 -Author: Etienne Dechamps -Date: Sun May 31 20:19:48 2015 +0100 - - Don't try to relay packets to unreachable nodes. - - It is not unusual for tinc to receive SPTPS packets to be relayed to - nodes that just became unreachable, due to state propagation delays in - the metagraph. - - Unfortunately, the current code doesn't handle that situation correctly, - and still tries to relay the packet to the unreachable node. This - typically ends up segfaulting. - - This commit fixes the issue by checking for reachability before relaying - the packet. - -commit 9e3adef5cb31cb73fbbbd25d3fce115aac107714 -Author: Etienne Dechamps -Date: Sun May 24 09:49:16 2015 +0100 - - Fix invalid pointer use in get_my_hostname(). - - clang-3.7 warnings surfaced an actual bug: - - invitation.c:185:5: error: address of array 'filename' will always evaluate to 'true' - [-Werror,-Wpointer-bool-conversion] - if(filename) { - ~~ ^~~~~~~~ - - The regression was introduced in 3ccdf50beb6b2d3f2730bdc66006b43190537cde. - -commit 7fcfbe2bd2d14d13e06e3e2addfe0ea12b67873f -Author: Etienne Dechamps -Date: Sun May 24 09:45:09 2015 +0100 - - Fix wrong format string type in send_sptps_tcppacket(). - - This issue was found through a clang-3.7 warning: - - protocol_misc.c:167:46: error: format specifies type 'short' but the argument has type 'int' - [-Werror,-Wformat] - if(!send_request(c, "%d %hd", SPTPS_PACKET, len)) - ~~~ ^~~ - %d - -commit 3e61c7233b087b8400c29ca7a8d079aad8b706d8 -Author: Etienne Dechamps -Date: Sat May 23 17:24:05 2015 +0100 - - Don't set up an ongoing connection to myself. - - It is entirely possible that the configuration file could contain a - ConnectTo statement refering to its own name; that's a reasonable - scenario when one deploys semi-automatically generated tinc.conf files. - - Amusingly, tinc does not like that at all, and actually sets up an - outgoing_t structure to myself (which obviously makes no sense). This is - mostly benign, though it does result in non-sensical "Already connected - to myself" messages every retry interval. - - However, that also makes things blow up in close_network_connections(), - because there we delete the entire outgoing list and *then* the myself - node, which still has a reference to the freshly deleted outgoing - structure. Boom. - -commit 8587e8c0d9ac997fcd2040470c1ccf5930bc18c3 -Author: Etienne Dechamps -Date: Sat May 23 10:24:00 2015 +0100 - - Fix crashes when trying unreachable nodes. - - timeout_handler() calls try_tx(c->node) when c->edge exists. - Unfortunately, the existence of c->edge is not enough to conclude that - the node is reachable. - - In fact, during connection establishment, there is a short period of - time where we create an edge for the node at the other end of the - metaconnection, but we don't have one from the other side yet. - Unfortunately, if timeout_handler() runs during that short time - window, it will call try_tx() on an unreachable node, which makes - things explode because that function is not prepared to handle that - case. - - A typical symptom of this race condition is a hard SEGFAULT while trying - to send packets using metaconnections that don't exist, due to - n->nexthop containing garbage. - - This patch fixes the issue by making try_tx() check for reachability, - and then making all code paths use try_tx() instead of the more - specialized methods so that they go through the check. - - This regression was introduced in - eb7a0db18ea71a44999d6a37b4b179dac0ed9bc7. - -commit 537a9366718b39278fd4eb33b2ac568011e374cc -Author: Guus Sliepen -Date: Thu May 21 11:09:01 2015 +0200 - - Update copyright notices. - -commit 0a786ffbb9d293d7704b8e264f3943a616ed25cc -Author: Guus Sliepen -Date: Thu May 21 11:06:38 2015 +0200 - - Set the CLOEXEC flag on the umbilical socket. - -commit 87e09527735632aae3f595f5a28667880ca4c8c1 -Author: Guus Sliepen -Date: Wed May 20 21:28:54 2015 +0200 - - Use socketpair() instead of pipe() for the umbilical. - - This prepares for a possible conversion of the umbilical socket to a - control socket. - -commit 19e0d449ebd06450c9d7f16f032c0806242c7515 -Author: Guus Sliepen -Date: Wed May 20 21:25:06 2015 +0200 - - Don't write log messages to the umbilical pipe if we don't detach. - - If we run in the foreground and are started by the CLI, this would - otherwise cause the first few log messages to appear twice. - -commit 11868b890d1a7f4cfbfb37099393b32019010f66 -Author: Guus Sliepen -Date: Wed May 20 16:59:43 2015 +0200 - - Ensure "tinc start" knows if the daemon really started succesfully. - - We do this by creating an umbilical between the CLI and the daemon. The - daemon pipes log messages to the CLI until it starts the main loop. The - daemon then cuts the umbilical. The CLI copies all the received log - messages to stderr, and the last byte indicates whether the daemon - started succesfully or not, so the CLI can exit with a useful exit code. - -commit 7f96ef081dc0dc41e3955e35c1a36a62fd47f72b -Author: Guus Sliepen -Date: Wed May 20 11:11:12 2015 +0200 - - Fix check for LOCALSTATEDIR accessibility for the CLI. - - The CLI does not need write access to the directory where the PID file - is stored, it just needs to be able to read the PID file. - -commit 3ccdf50beb6b2d3f2730bdc66006b43190537cde -Author: Guus Sliepen -Date: Wed May 20 00:55:00 2015 +0200 - - Allocate temporary filenames on the stack. - - This gets rid of xasprintf() in a number of places, and removes the need - to free() the temporary strings. A few potential memory leaks have been - fixed. - -commit 58e8f598f38dbb2f210d8a62c8fb4b46513dc39f -Author: Guus Sliepen -Date: Wed May 20 00:12:01 2015 +0200 - - Allow dumping a list of outstanding invitations. - - This dumps the name of the invitation file, as well as the name of the - node that is being invited. This can make it easier to find the - invitation file belonging to a given node. - -commit 7c8f54cdb2925ba787209f5358b62d3cee414d43 -Author: Guus Sliepen -Date: Wed May 20 00:02:53 2015 +0200 - - Add "list" as an alias for "dump" in the CLI. - -commit 69ba5f621e4931417f9f41061a7689e36c70e3d9 -Author: Guus Sliepen -Date: Tue May 19 22:26:32 2015 +0200 - - Quit with an error message if ioctl(TUNSETIFF) fails. - - It is possible that opening /dev/net/tun works but that interface - creation itself fails, for example if a non-root user tries to create a - new interface, or if the desired interface is already opened by another - process. In this case, the ioctl() fails, but we actually silently - ignored this condition. - -commit 60fbdb3f2cf0216afb2cfcc2c4128fb5765471ac -Author: Guus Sliepen -Date: Tue May 19 22:17:18 2015 +0200 - - If LOCALSTATEDIR is inaccessible, store the pid and socket files in the configuration directory. - - The compile time local state directory is usually /var or - /usr/local/var. If this is not accessible for some reason, for example - because someone ./configured tinc without --localstatedir and - /usr/local/var does not exist, or if tinc is started by a non-root user, - then tinc will fall back to the directory where tinc.conf is stored. - A warning is logged when this happens. - -commit dece2db78e2c4ccd6e617e69195754639b086170 -Author: Guus Sliepen -Date: Tue May 19 21:32:30 2015 +0200 - - Don't log seqno failures in sptps_verify_datagram(). - - This function is not used for normal traffic, only when a packet from an - unknown source is received and we need to check against candidates. No - failures should be logger in this case; if the packet is really not - valid this will be logged by handle_incoming_vpn_data(). - -commit a7522118018928e17fc53840b420df570cf1bec5 -Author: Guus Sliepen -Date: Tue May 19 21:23:35 2015 +0200 - - Add source of SPTPS errors to log messages. - -commit d89f37eb17196e38105a92d746ed7cb6b6f6ba45 -Author: Guus Sliepen -Date: Tue May 19 14:25:20 2015 +0200 - - Add newline at end of precomp_data.h and sc.h. - -commit d8a3a182de30d649ed6764dd5d64b57ad77a446e -Author: Guus Sliepen -Date: Tue May 19 14:09:53 2015 +0200 - - Fix src/Makefile.am for *BSD. - - Apparently the BSDs don't like $(srcdir) but want to see ${srcdir} in - their rules. - -commit 96a323e16a1f3e99d0b498aa90423b060c3d458f -Author: Guus Sliepen -Date: Tue May 19 13:31:26 2015 +0200 - - Remove info-in-builddir option from AM_INIT_AUTOMAKE(). - - This option is not supported by older, but still widely used versions of - automake. The drawback is that when doing multiple VPATH builds in a - row, the info manual may mention incorrect paths, but it doesn't affect - the executables at all. - -commit 51b5aab9b042dffc6ef0791358f097895a3234eb -Author: Sven-Haegar Koch -Date: Wed May 13 21:24:29 2015 +0200 - - Fix check for public key in invite-join.test. - - Small fix to test/invite-join.test, comparing no-longer-existing - ECDSAPublicKey does not make sense. - -commit a196e9b0fde1e8a67108eacd51ac663eac5a63ae -Author: Etienne Dechamps -Date: Mon May 18 21:06:16 2015 +0100 - - Fix direct UDP communciation with pre-relaying 1.1 nodes. - - try_tx_sptps() gives up on UDP communication if the recipient doesn't - support relaying. This is too restrictive - we only need the other node - to support relaying if we actually want to relay through them. If the - packet is sent directly, it's fine to send it to an old pre-node-IDs - tinc-1.1 node. - -commit fef29d0193afc7e0a9dc766ef75b79cd4dc6fa37 -Author: Etienne Dechamps -Date: Mon May 18 20:48:45 2015 +0100 - - Don't parse node IDs if the sending node doesn't support them. - - Currently, tinc tries to parse node IDs for all SPTPS packets, including - ones sent from older, pre-node-IDs tinc-1.1 nodes, and therefore doesn't - recognize packets from these nodes. This commit fixes that. - - It also makes code slightly clearer by reducing the amount of fiddling - around packet offset/length. - -commit 643149b44991121c618a2412c64072ad22955991 -Author: Etienne Dechamps -Date: Mon May 18 20:35:44 2015 +0100 - - Fix SPTPS condition in try_harder(). - - A condition in try_harder() is always evaluating to false when talking - to a SPTPS node because n->status.validkey_in is always false in that - case. Fix the condition so that the SPTPS status is correctly checked. - - This prevented recent tinc-1.1 nodes from talking to older, pre-node-ID - tinc-1.1 nodes. - - The regression was introduced in - 6056f1c13bb37bf711dff9c25a6eaea99f14d31f. - -commit 01d251986260faf306927aa91daff705ee0523d6 -Author: Etienne Dechamps -Date: Sun May 17 22:36:15 2015 +0100 - - Don't pollute the system header directory namespace. - - Since commit 13f9bc1ff199bea46d3dde391a848f119e2cc0f0, tinc passes the - -I. option to the preprocessor so that version_git.h can be found during - out-of-tree ("VPATH") builds. - - The problem is, this option also affects the directory search for files - included *from* system headers. For example, on MinGW, unistd.h contains - the following line: - - #include - - Which, due to -I. putting the tinc directory at the head of the search - order, results in tinc's process.h being included instead of the file - from MinGW. Hilarity ensues. - - This commit fixes the issue by using -iquote, which doesn't affect - system headers. - -commit c1154bf696b0b3ad22126a76750d610e32e2ffc1 -Author: Etienne Dechamps -Date: Sun May 17 22:21:11 2015 +0100 - - Make sure the MIN() macro is defined. - - On MinGW this is not automatically the case, thereby breaking the build. - -commit 5c32bd1578d59e005f634621d17ca96af32bb630 -Merge: aa52300b 1a7a9078 2cb216d8 -Author: Guus Sliepen -Date: Sun May 17 21:07:45 2015 +0200 - - Merge remote-tracking branches 'dechamps/sptpsrestart' and 'dechamps/keychanged' into 1.1 - -commit 2cb216d83d825fcca2fa2b66c756b253f8f0828b -Author: Etienne Dechamps -Date: Sun May 17 19:23:12 2015 +0100 - - Don't send KEY_CHANGED messages if we don't support the legacy protocol. - - KEY_CHANGED messages are only useful to invalidate keys for non-SPTPS nodes; - SPTPS nodes use a different internal mechanism (forced KEX) for that purpose. - Therefore, if we know we can't talk to legacy nodes, there's no point in - sending them these messages. - -commit 1a7a9078c093f77950192c32be009bbe463fe372 -Author: Etienne Dechamps -Date: Sun May 17 18:50:11 2015 +0100 - - Proactively restart the SPTPS tunnel if we get receive errors. - - There are a number of ways a SPTPS tunnel can get into a corrupt state. - For example, during key regeneration, the KEX and SIG messages from - other nodes might arrive out of order, which confuses the hell out of - the SPTPS code. Another possible scenario is not noticing another node - crashed and restarted because there was no point in time where the node - was seen completely disconnected from *all* nodes; this could result in - using the wrong (old) key. There are probably other scenarios which have - not even been considered yet. Distributed systems are hard. - - When SPTPS got confused by a packet, it used to crash the entire - process; fortunately that was fixed by commit - 2e7f68ad2b51648b89c4b5c61aeb4cec67c2fbbb. However, the error handling - (or lack thereof) leaves a lot to be desired. Currently, when SPTPS - encounters an error when receiving a packet, it just shrugs it off and - continues as if nothing happened. The problem is, sometimes getting - receive errors mean the tunnel is completely stuck and will not recover - on its own. In that case, the node will become unreachable - possibly - indefinitely. - - The goal of this commit is to improve SPTPS error handling by taking - proactive action when an incoming packet triggers a failure, which is - often an indicator that the tunnel is stuck in some way. When that - happens, we simply restart SPTPS entirely, which should make the tunnel - recover quickly. - - To prevent "storms" where two buggy nodes flood each other with invalid - packets and therefore spend all their time negotiating new tunnels, we - limit the frequency at which tunnel restarts happen to ten seconds. - - It is likely this commit will solve the "Invalid KEX record length - during key regeneration" issue that has been seen in the wild. It is - difficult to be sure though because we do not have a full understanding - of all the possible conditions that can trigger this problem. - -commit aa52300b2b6e9d923d6d5b8c95fa500f549620d0 -Author: Etienne Dechamps -Date: Sun May 17 17:51:05 2015 +0100 - - Trivial: make sptps_receive_data_datagram() a little more readable. - - The new code updates variables as stuff is being consumed, so that the - reader doesn't have to do that in his head. - -commit 30e839b0a1810b9cb0a2de2595cef2f8ebb06357 -Author: Guus Sliepen -Date: Sun May 17 18:44:09 2015 +0200 - - Don't send local_address in ADD_EDGE messages if it's AF_UNSPEC. - -commit 23fda4db6d1bb400a97f6d2a07d9b700f9546129 -Author: Sven-Haegar Koch -Date: Sun May 17 05:29:21 2015 +0200 - - Let sockaddr2hostname() handle AF_UNSPEC addresses. - -commit 1e89a63f1638e43dee79afbb18d5f733b27d830b -Author: Etienne Dechamps -Date: Sun May 17 17:09:56 2015 +0100 - - Prevent SPTPS key regeneration packets from entering an UDP relay path. - - Commit 10c1f60c643607d9dafd79271c3475cddf81e903 introduced a mechanism - by which a packet received by REQ_KEY could continue its journey over - UDP. This was based on the assumption that REQ_KEY messages would never - be used for handshake packets (which should never be sent over UDP, - because SPTPS currently doesn't handle lost handshake packets very - well). - - Unfortunately, there is one case where handshake packets are sent using - REQ_KEY: when regenerating the SPTPS key for a pre-established channel. - With the current code, such packets risk getting relayed over UDP. - - When processing a REQ_KEY message, it is impossible for the receiving - end to distinguish between a data SPTPS packet and a handshake packet, - because this information is stored in the type field which is encrypted - with the end-to-end key. - - This commit fixes the issue by making tinc use ANS_KEY for all SPTPS - handshake messages. This works because ANS_KEY messages are never - forwarded using the SPTPS relay mechanisms, therefore they are - guaranteed to stick to TCP. - -commit eecfeadeb4fc70ee002b81c20ba12ba3e3acb843 -Author: Guus Sliepen -Date: Sat May 16 02:01:54 2015 +0200 - - Let sockaddr2str() handle AF_UNSPEC addresses. - -commit 613c121cdceec0199dc4d056857be021ed1d21de -Author: Guus Sliepen -Date: Fri May 15 23:35:46 2015 +0200 - - Try all addresses for the hostname in an invitation URL. - -commit 54a8bd78e3fbe2de4d9daea748643f9c9b5b240e -Author: Guus Sliepen -Date: Fri May 15 23:08:53 2015 +0200 - - Be more liberal accepting ADD_EDGE messages with conflicting local address information. - - If the ADD_EDGE is for one of the edges we own, and if it is not the - same as we actually have, send a correcting ADD_EDGE back. Otherwise, if - the ADD_EDGE contains new information, update our idea of the local - address for that edge. - - If the ADD_EDGE does not contain local address information, then we - never make a correction nor log a warning. - -commit 8028e01100eb40f64da5e50ef33fbf9e3f8099de -Author: Guus Sliepen -Date: Fri May 15 23:01:06 2015 +0200 - - Use AF_UNSPEC instead of AF_UNKNOWN for unspecified local address in add_edge_h(). - - AF_UNKNOWN is reserved for valid addresses that the local node cannot - parse, but remote nodes possibly can. - -commit fd1cff6df23c3f16a46edaff8a52a7212914b2f0 -Author: Guus Sliepen -Date: Fri May 15 00:21:48 2015 +0200 - - Fix receiving UDP packets from tinc 1.0.x nodes. - - In try_mac(), the wrong offsets were used into the packet buffer, - causing the digest verification to always fail. - -commit 44e9f1e1d8d6dbd4625e5458cfffcf6b5168374a -Author: Guus Sliepen -Date: Wed May 13 14:28:28 2015 +0200 - - Fix invitations. - - These were broken due to a change in behaviour of sptps_receive_data() - introduced in commit d237efd325cd7bdd73f5eb111c769470238dce6e. - -commit 7e6b2dd1ea51057b7135139c200d97a9e8f9c9cb -Author: Etienne Dechamps -Date: Sun May 10 19:00:03 2015 +0100 - - Introduce raw TCP SPTPS packet transport. - - Currently, SPTPS packets are transported over TCP metaconnections using - extended REQ_KEY requests, in order for the packets to pass through - tinc-1.0 nodes unaltered. Unfortunately, this method presents two - significant downsides: - - - An already encrypted SPTPS packet is decrypted and then encrypted - again every time it passes through a node, since it is transported - over the SPTPS channels of the metaconnections. This - double-encryption is unnecessary and wastes CPU cycles. - - - More importantly, the only way to transport binary data over - standard metaconnection messages such as REQ_KEY is to encode it - in base64, which has a 33% encoding overhead. This wastes 25% of the - network bandwidth. - - This commit introduces a new protocol message, SPTPS_PACKET, which can - be used to transport SPTPS packets over a TCP metaconnection in an - efficient way. The new message is appropriately protected through a - minor protocol version increment, and extended REQ_KEY messages are - still used with nodes that do not support the new message, as well as - for the intial handshake packets, for which efficiency is not a concern. - - The way SPTPS_PACKET works is very similar to how the traditional PACKET - message works: after the SPTPS_PACKET message, the raw binary packet is - sent directly over the metaconnection. There is one important - difference, however: in the case of SPTPS_PACKET, the packet is sent - directly over the TCP stream completely bypassing the SPTPS channel of - the metaconnection itself for maximum efficiency. This is secure because - the SPTPS packet that is being sent is already encrypted with an - end-to-end key. - -commit d237efd325cd7bdd73f5eb111c769470238dce6e -Author: Etienne Dechamps -Date: Sun May 10 19:28:11 2015 +0100 - - Only read one record at a time in sptps_receive_data(). - - sptps_receive_data() always consumes the entire buffer passed to it, - which is somewhat inflexible. This commit improves the interface so that - sptps_receive_data() consumes at most one record. The goal is to allow - non-SPTPS stuff to be interleaved with SPTPS records in a single TCP - stream. - -commit de14308840a96060d700c93117789e83ec948c01 -Author: Etienne Dechamps -Date: Sun May 10 18:05:19 2015 +0100 - - Rename REQ_SPTPS to SPTPS_PACKET. - - REQ_SPTPS implies the message has an ANS_ counterpart (like REQ_KEY, - ANS_KEY), but it doesn't. Therefore dropping the REQ_ seems more - appropriate, and we add a _PACKET suffix to reduce the likelihood of - naming conflicts. - -commit 10c1f60c643607d9dafd79271c3475cddf81e903 -Author: Etienne Dechamps -Date: Sat May 9 18:09:23 2015 +0100 - - Try to use UDP to relay SPTPS packets received over TCP. - - Currently, when tinc receives a SPTPS packet over TCP via the REQ_KEY - encapsulation mechanism, it forwards it like any other TCP request. This - is inefficient, because even though we received the packet over TCP, - we might have an UDP link with the next hop, which means the packet - could be sent over UDP. - - This commit removes that limitation by making sure SPTPS data packets - received through REQ_KEY requests are not forwarded as-is but passed - to send_sptps_data() instead, thereby using the same code path as if - the packet was received over UDP. - -commit 1296f715b57c88c17299cacadaccdc0be898e0b1 -Author: Etienne Dechamps -Date: Sat May 9 17:54:34 2015 +0100 - - Expose the raw SPTPS send interface from net_packet. - - net_packet doesn't actually use send_sptps_data(); it only uses - send_sptps_data_priv(). In addition, the only user of send_sptps_data() - is protocol_key. Therefore it makes sense to expose - send_sptps_data_priv() directly, and move send_sptps_data() (which is - basically just boilerplate) as a local function in protocol_key. - -commit 8e43a2fc744559956640d3eb9a7a26a945d94fde -Author: Etienne Dechamps -Date: Sun May 10 18:46:47 2015 +0100 - - Use the correct originator node when relaying SPTPS UDP packets. - - Currently, when relaying SPTPS UDP packets, the code uses the direct - sender as the originator, instead of preserving the original source ID. - - This wouldn't cause any issues in most cases because the originator and - the sender are the same in simple one-hop relay chains, but this will - break as soon as there is more than one relay. - -commit 9d223cb7e7f337c6b9707f07e3e9796108a3b597 -Author: Etienne Dechamps -Date: Sun May 10 18:37:30 2015 +0100 - - When relaying, send probes to the destination, not the source. - - This seems to be a typo from c23e50385d9de538af676706596f6508b2ceb01a. - Achievement unlocked: got a one-line commit wrong. - -commit 13f9bc1ff199bea46d3dde391a848f119e2cc0f0 -Author: Etienne Dechamps -Date: Sat Jul 12 16:01:41 2014 +0100 - - Add support for out-of-tree ("VPATH") builds. - - This fixes some issues with the build system when building out of tree. - - With this commit, it is now possible to do the following: - - $ cd /tmp/build - $ /path/to/tinc/configure - $ make - -commit 462e9892ae2765d0c7036005fafe036fd2a9f4f2 -Author: Etienne Dechamps -Date: Sat Jul 12 16:21:32 2014 +0100 - - Remove explicit distribution rules for m4 scripts. - - It turns out Automake is smart enough to include these files in the - distribution by itself. - -commit 362b79176439a2eb643612633aa0ff210a6a4d81 -Author: Guus Sliepen -Date: Sat May 9 15:41:37 2015 +0200 - - Really remove "release-" from the git-derived version string. - -commit b109e8b16488f9bbfdc4aefe0e9b00c4f202e905 -Author: Etienne Dechamps -Date: Sun Jun 29 18:26:55 2014 +0100 - - Use git describe to populate autoconf's VERSION. - - This uses the output of "git describe" directly in configure.ac to - determine the version number to use, instead of hardcoding it. - - With this change, current version information is completely removed - from the codebase itself, and is always fetched on-the-fly from git as - the single source of truth. - - In order to ensure make dist always uses the current version number in - the contents of the packaged configure script as well as the package - name, a dependency is added to the dist target such that autoconf is - always run before dist to regenerate the version number. If this wasn't - the case, make dist would use the version number from when autoconf was - originally run, not the version number that make dist is running from. - That said, errors from that rule are ignored so that people can still - run make dist without a working autoconf. - - In addition, the NEWS check is dropped, as it would then become annoying - because it would force make dist users to always have a line for the - current commit in the NEWS file. - -commit 1c77069064e0cf0e0ddd81bab1b1354a8952fb33 -Author: Pierre Emeriaud -Date: Sat May 9 00:03:51 2015 +0200 - - Fix typo in tincctl help. - -commit 54554cc2765befc2e95fd7fe2fedfd75a94b5926 -Author: Guus Sliepen -Date: Tue May 5 23:05:22 2015 +0200 - - Don't include build-time generated version_git.h in the tarball. - -commit c46bdbde18629f0a0613c776c13a79fea0ec6093 -Author: Guus Sliepen -Date: Tue May 5 23:03:41 2015 +0200 - - Remove "release-" from displayed git version. - - Also make sure that version_git.h is only written to if the "git - describe" command succeeds. - -commit 120e0567cba17eeb57c12a34686fddbbb491b62f -Author: Etienne Dechamps -Date: Sun Jun 29 15:22:10 2014 +0100 - - Use git description as the tinc version. - - Instead of using the hardcoded version number in configure.ac, this - makes tinc use the live version reported by "git describe", - queried on-the-fly during the build process and regenerated for every - build. - - This makes tinc version output more useful, as tinc will now display the - number of commits since the last tag as well as the commit the binary is - built from, following the format described in git-describe(1). - - Here's an example of tincd --version output: - - tinc version release-1.1pre10-48-gc149315 (built Jun 29 2014 15:21:10, protocol 17.3) - - When building directly from a release tag, this will look like the following: - - tinc version release-1.1pre10 (built Jun 29 2014 15:21:10, protocol 17.3) - - (Note that the format is slightly different - because of the way the - tags are named, it says "release-1.1pre10" instead of just "1.1pre10") - - If git describe fails (for example when building from a release - tarball), the build automatically falls back to the autoconf-provided - VERSION macro (i.e. the old behavior). - -commit 95594f47384b60a6f994f0fca6fd9f79b2b283aa -Author: Guus Sliepen -Date: Fri Apr 24 23:51:29 2015 +0200 - - Fix typo 0fda572c88d02b0b200ef81d72cc4da594fa0e38 that prevented some errors from being logged. - -commit 0fda572c88d02b0b200ef81d72cc4da594fa0e38 -Author: Guus Sliepen -Date: Fri Apr 24 23:43:58 2015 +0200 - - Don't log an error message when receiving a TERMREQ. - -commit ea1e815223e99f3747f94cf0d10eb06e52f70b21 -Author: Guus Sliepen -Date: Fri Apr 24 23:43:19 2015 +0200 - - Fix a possible segmentation fault during key upgrades. - - read_rsa_public_key() was bailing out early if the given node already has an Ed25519 key, and - returned true even though c->rsa was NULL. The early bailout code isn't necessary anymore, so just - remove it. - -commit 2059814238320b761fb93608b7f8a114de861302 -Author: Guus Sliepen -Date: Fri Apr 24 23:40:20 2015 +0200 - - Allow one-sided upgrades to Ed25519. - - This deals with the case where one node knows the Ed25519 key of another node, but not the other - way around. This was blocked by an overly paranoid check in id_h(). The upgrade_h() function already - handled this case, and the node that already knows the other's Ed25519 key checks that it has not - been changed, otherwise the connection will be aborted. - -commit 3def9d2ad88a9015af4c42aac329e0e2a80679f7 -Merge: 95921696 0c010ff9 -Author: Guus Sliepen -Date: Sun Apr 12 15:43:05 2015 +0200 - - Merge remote-tracking branch 'dechamps/wintapver' into 1.1 - -commit 95921696a49d1eff058880c90a80efd208de959d -Merge: f500a3d4 7027bba5 -Author: Guus Sliepen -Date: Sun Apr 12 15:42:48 2015 +0200 - - Always call res_init() before getaddrinfo(). - - Unfortunately, glibc assumes that /etc/resolv.conf is a static file that - never changes. Even on servers, /etc/resolv.conf might be a dynamically - generated file, and we never know when it changes. So just call - res_init() every time, so glibc uses up-to-date nameserver information. - - Conflicts: - src/have.h - src/net.c - src/net_setup.c - -commit f500a3d4e6e51ea1d88235e89e494ecb8f71ba5b -Merge: 41798146 89715454 -Author: Guus Sliepen -Date: Sun Apr 12 15:36:50 2015 +0200 - - Merge remote-tracking branch 'dechamps/windevice' into 1.1 - -commit 417981462a2dde7800768eb58cf8f4e5238d4ad7 -Merge: 11effab8 176ee015 -Author: Guus Sliepen -Date: Sun Apr 12 15:35:50 2015 +0200 - - Merge remote-tracking branch 'dechamps/winmtu' into 1.1 - -commit 11effab85b6b278ccf0ac3ba52a12bbca3e3dcc5 -Merge: 9e71b74e 43b41e90 -Author: Guus Sliepen -Date: Sun Apr 12 15:35:37 2015 +0200 - - Merge remote-tracking branch 'dechamps/fsckwin' into 1.1 - -commit 9e71b74ed83c51e0b35114a4f153b62b54fd3702 -Merge: 76a9be5b fa432426 -Author: Guus Sliepen -Date: Sun Apr 12 15:34:50 2015 +0200 - - Merge remote-tracking branch 'dechamps/staticfix' into 1.1 - -commit 0c010ff9fe50b4046b5c7977bafac3e74037f075 -Author: Etienne Dechamps -Date: Sun Mar 15 18:30:39 2015 +0000 - - Warn about performance if using TAP-Windows >=9.21. - - Testing has revealed that the newer series of Windows TAP drivers (i.e. - 9.0.0.21 and later, also known as NDIS6, tap-windows6) suffer from - serious performance issues in the write path. Write operations seems to - take a very long time to complete, resulting in massive packet loss even - for throughputs as low as 10 Mbit/s. - - I've made some attempts to alleviate the problem using parellelism. By - using custom code that allows up to 256 write operations at the same - time the results are much better, but it's still about 2 times worse - than the traditional 9.0.0.9 driver. - - We need to investigate more and file a bug against tap-windows6, but in - the mean time, let's inform the user that he might not want to use the - latest drivers. - -commit 0f328d9d2853ca723ff3205f39bb22207d21a932 -Author: Etienne Dechamps -Date: Sun Mar 15 18:18:04 2015 +0000 - - Log TAP-Windows driver version on startup. - - This is generally useful. We've seen issues that are specific to some - version of these drivers (especially the newer 9.0.0.21 version), so - it's relevant to log it, especially since that means it will be - copy-pasted by people posting their logs asking for help. - -commit 7027bba541eca3e34f689bebd6f6e408ba4e7710 -Author: Etienne Dechamps -Date: Sun Mar 15 18:01:03 2015 +0000 - - Increase the ReplayWindow default from 16 to 32. - - As a rule, it seems reasonable to make sure that tinc operates correctly - on at least 1G links, since these are pretty common. However, I have - observed replay window issues when operating at speeds of 600 Mbit/s and - above, especially when the receiving end is a Windows system (not sure - why). This commit increases the default so that this won't occur on - fresh setups. - -commit 94f49a163aa570ea272bf3bbd7734187098d88b7 -Author: Etienne Dechamps -Date: Sun Mar 15 17:50:53 2015 +0000 - - Set the default for UDPRcvBuf and UDPSndBuf to 1M. - - It may not be obvious, but due to the way tinc operates (single-threaded - control loop with no intermediate packet buffer), UDP send and receive - buffers can have a massive impact on performance. It is therefore of - paramount importance that the buffers be large enough to prevent packet - drops that could occur while tinc is processing a packet. - - Leaving that value to the OS default could be reasonable if we weren't - relying on it so much. Instead, this makes performance somewhat - unpredictable. - - In practice, the worst case scenario occurs on Windows, where Microsoft - had the brillant idea of making the buffers 8K in size by default, no - matter what the link speed is. Considering that 8K flies past in a - matter of microseconds on >1G links, this is extremely inappropriate. On - these systems, changing the buffer size to 1M results in *obscene* - raw throughput improvements; I have observed a 10X jump from 40 Mbit/s - to 400 Mbit/s on my system. - - In this commit, we stop trusting the OS to get this right and we use a - fixed 1M value instead, which should be enough for <=1G links. - -commit 89715454c083aaeb4dc73340f2d0ab9a3d9503e0 -Author: Etienne Dechamps -Date: Sat Mar 14 18:19:22 2015 +0000 - - Fix Windows device asynchronous write behavior. - - Write operations to the Windows device do not necessarily complete - immediately; in fact, with the latest TAP-Win32 drivers, this never - seems to be the case. - - write_packet() does not handle that case correctly, because the - OVERLAPPED structure and the packet data go out of scope before the - write operation completes, resulting in race conditions. - - This commit fixes the issue by making sure these data structures are - kept in global scope, and by dropping any packets that may arrive while - the previous write operation is still pending. - -commit 675142c7d88c9d325c0ca0bc5761072a5d810c75 -Author: Etienne Dechamps -Date: Sat Mar 14 17:27:14 2015 +0000 - - When disabling the Windows device, wait for pending reads to complete. - - On Windows, when disabling the device, tinc uses the CancelIo() to - cancel the pending read operation, and then proceeds to delete the event - handle immediately. - - This assumes that CancelIo() blocks until the pending read request is - completely torn down and no references to it remain. While MSDN is not - completely clear on that subject, it does suggest that this is not the - case: - - http://msdn.microsoft.com/en-us/library/windows/desktop/aa363791.aspx - If the function succeeds [...] the cancel operation for all pending - I/O operations issued by the calling thread for the specified file - handle was successfully requested. - - This implies that cancellation was merely "requested", and that there - are no guarantees as to the state of the operation when CancelIo() - returns. Therefore, care must be taken not to close event handles - prematurely. - - While I'm no aware of this potential race condition causing any problems - in practice, I don't want to take any chances. - -commit 176ee015267d87ff4fd4d2615e9f5ac978116171 -Author: Etienne Dechamps -Date: Sun Mar 15 10:00:56 2015 +0000 - - Make sure packet header structures are correctly packed on Windows. - - Modern versions of GCC handle structure packing differently when - compiling for Windows, as reported in the following GCC bug report: - - http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52991 - - In practice, this affects tinc because it uses packed structs as a - convenient way to populate packet headers. "struct ip" is especially - affected - on Linux, sizeof(struct ip) returns 20 as expected, while on - Windows, it returns 24 because of the broken alignment. - - This in turn completely breaks code that has to populate an IP header. - Specifically, this breaks route_ipv4_unreachable() which is responsible, - among other things, for the generation of ICMP Fragmentation Needed - messages. On Windows, these messages are corrupted beyond hope because - of this alignment issue. For TCP connections that are established - before tinc obtains a fix on the MTU (and thus are not MSS clamped), - this can result in massive disruption. - - This commit fixes the issue by forcing GCC to use standard alignment - for all packed structures in the tinc codebase instead of the MSVC - alignment. - -commit 43b41e9095e6261c53da1ae46117d018296c3b68 -Author: Etienne Dechamps -Date: Sat Mar 14 16:17:32 2015 +0000 - - Fix HAVE_DECL_RES_INIT conditionals. - - HAVE_DECL_RES_INIT is generated using AC_CHECK_DECLS. tinc checks this - symbol using #ifdef, which is wrong because (according to autoconf docs) - the symbol is always defined, it's just set to zero if the check failed. - - This broke the Windows build starting from - 0b310bf406dbe58afe37fa31156b9ea47599d7be, because it introduced this - conditional in code that's not excluded from the Windows build. - -commit 4989362300f800a6f407508f1e0127867cf80cba -Author: Etienne Dechamps -Date: Sat Mar 14 16:07:54 2015 +0000 - - Fix invalid getuid() call on Windows. - - This is breaking the Windows build. Regression was introduced in - 268e3ffca7b45cfc736e1bc9bec7a113c6c45701. - -commit fa432426df7e2e364e310ab4bac28e60f732a3c9 -Author: Etienne Dechamps -Date: Sat Mar 14 14:04:50 2015 +0000 - - Don't send UDP probes past static relays. - - Ironically, commit 0f8e2cc78cafe47a087d3fc9b480551b841aeb30 introduced - a regression on its own, since it accidently removed a return statement - that prevented try_tx_sptps() from sending UDP/MTU probes to nodes that - are past static relays. - -commit 76a9be5bce43a1a7363c670882f5315c824c903c -Author: Etienne Dechamps -Date: Sun Mar 8 20:17:27 2015 +0000 - - Throttle the rate of MTU_INFO messages. - - This makes sure MTU_INFO messages are only sent at the maximum rate of - 5 per second (by default). As usual with these "probe" mechanisms, the - rate of these messages cannot be higher than the rate of data packets - themselves, since they are sent from the RX path. - -commit 467397f25d3a99ec1a97d4419502c37b64276f49 -Author: Etienne Dechamps -Date: Sun Mar 8 19:54:44 2015 +0000 - - Throttle the rate of UDP_INFO messages. - - This makes sure UDP_INFO messages are only sent at the maximum rate of - 5 per second (by default). As usual with these "probe" mechanisms, the - rate of these messages cannot be higher than the rate of data packets - themselves, since they are sent from the RX path. - -commit b1421b919090351e885ed3d06df67fb2eb69e765 -Author: Etienne Dechamps -Date: Sun Mar 8 18:54:50 2015 +0000 - - Add MTU_INFO protocol message. - - In this commit, nodes use MTU_INFO messages to provide MTU information. - - The issue this code is meant to address is the non-trivial problem of - finding the proper MTU when UDP SPTPS relays are involved. Currently, - tinc has no idea what the MTU looks like beyond the first relay, and - will arbitrarily use the first relay's MTU as the limit. This will fail - miserably if the MTU decreases after the first relay, forcing relays to - fall back to TCP. More generally, one should keep in mind that relay - paths can be arbitrarily complex, resulting in packets taking "epic - journeys" through the graph, switching back and forth between UDP (with - variable MTUs) and TCP multiple times along the path. - - A solution that was considered consists in sending standard MTU probes - through the relays. This is inefficient (if there are 3 nodes on one - side of relay and 3 nodes on the other side, we end up with 3*3=9 MTU - discoveries taking place at the same time, while technically only - 3+3=6 are needed) and would involve eyebrow-raising behaviors such as - probes being sent over TCP. - - This commit implements an alternative solution, which consists in - the packet receiver sending MTU_INFO messages to the packet sender. - The message contains an MTU value which is set to maximum when the - message is originally sent. The message gets altered as it travels - through the metagraph, such that when the message arrives to the - destination, the MTU value contained in the message can be used to - send packets while making sure no relays will be forced to fall back to - TCP to deliver them. - - The operating principles behind such a protocol message are similar to - how the UDP_INFO message works, but there is a key difference that - prevents us from simply reusing the same message: the UDP_INFO message - only cares about relay-to-relay links (i.e. it is sent between static - relays and the information it contains only makes sense between two - adjacent static relays), while the MTU_INFO cares about the end-to-end - MTU, including the entire relay path. Therefore, UDP_INFO messages stop - when they encounter static relays, while MTU_INFO messages don't stop - until they get to the original packet sender. - - Note that, technically, the MTU that is obtained through this mechanism - can be slightly pessimistic, because it can be lowered by an - intermediate node that is not being used as a relay. Since nodes have no - way of knowing whether they'll be used as dynamic relays or not (and - have no say in the matter), this is not a trivial problem. That said, - this is highly unlikely to result in noticeable issues in realistic - scenarios. - -commit 9bb230f30f665779eb89dcce077a15360ec50be1 -Author: Etienne Dechamps -Date: Sat Jan 3 17:46:33 2015 +0000 - - Add UDP_INFO protocol message. - - In this commit, nodes use UDP_INFO messages to provide UDP address - information. The basic principle is that the node that receives packets - sends UDP_INFO messages to the node that's sending the packets. The - message originally contains no address information, and is (hopefully) - updated with relevant address information as it gets relayed through the - metagraph - specifically, each intermediate node will update the message - with its best guess as to what the address is while forwarding it. - - When a node receives an UDP_INFO message, and it doesn't have a - confirmed UDP tunnel with the originator node, it will update its - records with the new address for that node, so that it always has the - best possible guess as to how to reach that node. This applies to the - destination node of course, but also to any intermediate nodes, because - there's no reason they should pass on the free intel, and because it - results in nice behavior in the presence of relay chains (multiple nodes - in a path all trying to reach the same destination). - - If, on the other hand, the node does have a confirmed UDP tunnel, it - will ignore the address information contained in the message. - - In all cases, if the node that receives the message is not the - destination node specified in the message, it will forward the message - but not before overriding the address information with the one from its - own records. If the node has a confirmed UDP tunnel, that means the - message is updated with the address of the confirmed tunnel; if not, - the message simply reflects the records of the intermediate node, which - just happen to be the contents of the UDP_INFO message it just got, so - it's simply forwarded with no modification. - - This is similar to the way ANS_KEY messages are currently - overloaded to provide UDP address information, with two differences: - - - UDP_INFO messages are sent way more often than ANS_KEY messages, - thereby keeping the address information fresh. Previously, if the UDP - situation were to change after the ANS_KEY message was sent, the - sender would virtually never get the updated information. - - - Once a node puts address information in an ANS_KEY message, it is - never changed again as the message travels through the metagraph; in - contrast, UDP_INFO messages behave the opposite way, as they get - rewritten every time they travel through a node with a confirmed UDP - tunnel. The latter behavior seems more appropriate because UDP tunnel - information becomes more relevant as it moves closer to the - destination node. The ANS_KEY behavior is not satisfactory in some - cases such as multi-layered graphs where the first hop is located - before a NAT. - - Ultimately, the rationale behind this whole process is to improve UDP - hole punching capabilities when port translation is in effect, and more - generally, to make tinc more reliable in (very) hostile network - conditions (such as multi-layered NAT). - -commit 6568cffd52d4803effaf52a9bb9c98d69cf7922a -Author: Guus Sliepen -Date: Sat Mar 14 12:02:29 2015 +0000 - - --syslog and --logfile are mutually exclusive. - -commit 15ad628f06895175d7e629ce0188805dc00159fd -Author: Guus Sliepen -Date: Sat Mar 14 12:02:06 2015 +0000 - - Fix the case where we detach and use --logfile. - -commit 04fc19112da5e7fcefefcf6e490987cdcfb6f620 -Merge: f9ecaa10 19d16e40 -Author: Guus Sliepen -Date: Sat Mar 14 11:45:55 2015 +0000 - - Merge remote-tracking branch 'seehuhn/1.1' into 1.1 - -commit f9ecaa10768926302f24a70975f36e360b51c8ce -Merge: c23e5038 2e7f68ad -Author: Guus Sliepen -Date: Sat Mar 14 11:44:38 2015 +0000 - - Merge remote-tracking branch 'dechamps/sptpsabort' into 1.1 - -commit 19d16e40ccfb39461eda5336f4e754e10a640aba -Author: Jochen Voss -Date: Fri Mar 13 11:05:22 2015 +0000 - - Add a new --syslog option for tincd. - - This commit adds a new command line option for tincd which allows to - use tincd in non-detached mode with log messages still going to - syslog. The motivation for this change is to ease use of tincd - in Docker containers. - -commit 2e7f68ad2b51648b89c4b5c61aeb4cec67c2fbbb -Author: Etienne Dechamps -Date: Sun Mar 8 17:32:39 2015 +0000 - - Don't abort() willy-nilly in SPTPS code. - - If receive_handshake() or the receive_record() user callback returns an - error, sptps_receive_data_datagram() crashes the entire process. This is - heavy-handed, makes tinc very brittle to certain failures (i.e. - unexpected packets), and is inconsistent with the rest of SPTPS code. - -commit c23e50385d9de538af676706596f6508b2ceb01a -Author: Etienne Dechamps -Date: Sun Mar 8 14:32:01 2015 +0000 - - Fix UDP/MTU discovery in intermediate SPTPS UDP relays. - - Refactoring commit 81578484dc74fd92f1b01f71f882016f120ab1de seems to - have introduced a regression as it moved discovery code away from - send_sptps_data_priv() and within send_packet(). The issue is, - send_packet() is not called when the node is simply relaying an UDP - SPTPS packet: indeed, send_sptps_data_priv() is called directly from - handle_incoming_vpn_data() in that case. - - As a result, try_tx_sptps() is not called in the relaying case, which in - practice means that a relay doesn't initiate UDP/MTU discovery with the - next relay (unless some other activity compels it to do so). This can - result in packets getting sent over TCP instead of UDP from the relay. - -commit 0f8e2cc78cafe47a087d3fc9b480551b841aeb30 -Author: Etienne Dechamps -Date: Sun Mar 8 14:20:15 2015 +0000 - - Fix dynamic UDP SPTPS relaying. - - Refactoring commit 0e653260478005eb7c824a9a1a3df04f39938cd6 broke UDP - SPTPS relaying by accidently removing try_tx_sptps() logic related to - establishing connectivity to so-called "dynamic" relays (i.e. relays - that are not specified by IndirectData configuration statements, but - are used on-the-fly to circumvent loss of direct UDP connectivity). - - Specifically, the TX path was not trying to establish a tunnel to - dynamic relays (nexthop) anymore. This meant that MTU was not being - discovered with dynamic relays, which basically meant that all packets - being sent to dynamic relays went over TCP, thereby defeating the whole - purpose of SPTPS UDP relaying. - - Note that this bug could easily go unnoticed if a tunnel was established - with the dynamic tunnel for some other reason (i.e. exchanging actual - data packets with the relay node). - -commit 537c3528863c4736e877c4d1b6c6579940e6df5d -Author: xentec -Date: Tue Feb 17 04:02:35 2015 +0100 - - Fix compile errors introduced in cfe9285adf391ab66faeb5def811fe08e47a221a - - Compiling with `--disable-legacy-protocol` resulted in failure caused by the missing exclusion of some symbols in net_packet.c. - -commit cffcaf966b65a61943a00120f1ec5c868c917c1f -Author: Guus Sliepen -Date: Mon Feb 16 08:42:30 2015 +0100 - - Suppress warnings about parsing Ed25519 keys when they are not present. - -commit 833a8a048b22612cd12d703d55a71448b7179b4a -Author: Guus Sliepen -Date: Mon Feb 16 08:26:49 2015 +0100 - - Document that --force should precede commands. - -commit 85000a30ca68d3c8e9a98eb9537f4d1505bd849e -Author: Sven-Haegar Koch -Date: Tue Feb 10 01:17:12 2015 +0100 - - Fixed variables.test testsuite after 'Make "tinc add" idempotent.' change. - -commit 4b2ddded2c8ae1a1a5930637552eeb48f30d6530 -Author: Guus Sliepen -Date: Mon Feb 9 15:23:59 2015 +0100 - - Make "tinc add" idempotent. - - When calling "tinc add" multiple times with the same variable and value, - make sure only one unique line is added to the configuration file. - -commit 0b310bf406dbe58afe37fa31156b9ea47599d7be -Author: Guus Sliepen -Date: Mon Feb 9 15:16:36 2015 +0100 - - Always call res_init() before getaddrinfo(). - - Unfortunately, glibc assumes that /etc/resolv.conf is a static file that - never changes. Even on servers, /etc/resolv.conf might be a dynamically - generated file, and we never know when it changes. So just call - res_init() every time, so glibc uses up-to-date nameserver information. - -commit 268e3ffca7b45cfc736e1bc9bec7a113c6c45701 -Author: Guus Sliepen -Date: Thu Jan 15 22:57:56 2015 +0100 - - Add the "fsck" command to the CLI. - - This will report possible problems in the configuration files, and in - some cases offers to fix them. - - The code is far from perfect yet. It expects keys to be in their default - locations, it doesn't check for Public/PrivateKey[File] statemetns yet. - It also does not correctly handle Ed25519 public keys yet. - -commit a95e182d9ca54960383bfe3950b2b798e1f24f9e -Author: Guus Sliepen -Date: Mon Jan 12 14:43:32 2015 +0100 - - Improve packet source detection. - - When no UDP communication has been done yet, tinc establishes a guess - for the UDP address+port of each node. However, when there are multiple nodes - behind a NAT, tinc will guess the exact same address+port combination - for them, because it doesn't know about the NAT mappings yet. So when - receiving a packet, don't trust that guess unless we have confirmed UDP - communication. - - This ensures try_harder() is called in such cases. However, this - function was actually very inefficient, trying to verify packets - multiple times for nodes with multiple edges. Only call try_mac() at - most once per node. - -commit ae5b56c03d1e1af7561d7f1d1d8a333c3a9691ff -Author: Guus Sliepen -Date: Sun Jan 11 17:44:50 2015 +0100 - - Send gratuitous type 2 probe replies. - - If we receive any traffic from another node, we periodically send back a - gratuitous type 2 probe reply with the maximum received packet length. - On the other node, this causes the udp and perhaps mtu probe timers to - be reset, so it does not need to send a probe request. Gratuitous probe - replies from another node also count as received traffic for this - purpose, so for nodes that also have a meta-connection, UDP keepalive - packets in principle can now solely be type 2 replies. This reduces the - amount of probe traffic even more. - - To work, gratuitous replies should be sent slightly more often than - udp_discovery_keepalive_interval, so probe requests won't be triggered. - This also means that the timer resolution must be smaller than the - difference between the two, and at the moment it's kind of a hack. - -commit 7b76b7ac35b49b8a94ad91c432886a0a54e144d1 -Author: Guus Sliepen -Date: Sun Jan 11 16:14:05 2015 +0100 - - Send the size of the largest recently received packets in type 2 probe replies. - -commit 79b6adb489dde4ae92207ae7b9146f4e141c946c -Author: Guus Sliepen -Date: Sun Jan 11 16:12:57 2015 +0100 - - Move UDP probe reply code into its own function. - - This reduces the level of indentation, and prepares for sending gratuitous type 2 probe replies. - -commit f0afde0467443969eb408090d6b8ee542768ee33 -Author: Guus Sliepen -Date: Sun Jan 11 16:10:58 2015 +0100 - - Keep track of the largest UDP packet size received from a node. - -commit d63941593736fbf268f2770d42e7f3f6a2132fae -Author: Guus Sliepen -Date: Sun Jan 11 15:38:56 2015 +0100 - - Move detection of PMTU decrease to try_mtu(). - - When we have fixed the PMTU, n->mtuprobes == -1. When we send MTU probes - when mtuprobes == -1, decrease mtuprobes, and reset it back to -1 in - mtu_probe_h(). If mtuprobes < -1, send MTU probes every second, until - mtuprobes <= -4, in which case we will restart MTU discovery. - -commit e97e9b22cb6061070611212a06756fb493846955 -Author: Guus Sliepen -Date: Sun Jan 11 14:44:27 2015 +0100 - - Send MTU probes only once every PingInterval. - -commit 088b5fd9ee6d5f566e8726eae861cbc7cd832b17 -Author: Guus Sliepen -Date: Sun Jan 11 14:44:15 2015 +0100 - - Remove RTT and packet loss estimation code. - - This is not working at all anymore. Just remove it, and we'll do another - attempt at RTT, bandwidth and packet loss estimation after the new - probing code stabilizes. - -commit ce7079f4af3157eaef514d6d160933a016b2ab62 -Author: Guus Sliepen -Date: Sun Jan 11 13:53:16 2015 +0100 - - Only send small packets during UDP probes. - - We are trying to decouple UDP probing from MTU probing, so only send - very small packets during UDP probing. This significantly reduces the - amount of traffic sent (54 to 67 bytes per probe instead of 1500 bytes). - - This means the MTU probing code takes over sending PMTU sized probes, - but this commit does not take care of detecting PMTU decreases. - -commit e4077c00c6fead63467d296c89d5afc2860e2935 -Author: Guus Sliepen -Date: Sun Jan 11 13:51:55 2015 +0100 - - Immediately send our key when a meta-connection is established. - - This is what 1.0 does, and speeds up the UDP probing. - -commit eb7a0db18ea71a44999d6a37b4b179dac0ed9bc7 -Author: Guus Sliepen -Date: Sun Jan 11 13:31:01 2015 +0100 - - Always keep UDP mappings alive for nodes that also have a meta-connection. - - This is necessary for assisting with UDP hole punching. But we don't - need to know the PMTU for this, so only send UDP probes. - -commit 545ecb339654573b3ee91bffb45c8282154885c6 -Author: Guus Sliepen -Date: Sun Jan 11 01:52:37 2015 +0100 - - Fix segfault when sptps_test cannot open the key files. - -commit 69d4ccc43781152dc90521b3f517b0d9588ae207 -Author: Etienne Dechamps -Date: Tue Dec 30 09:56:30 2014 +0000 - - Fix typo in logging statement. - - This was introduced in cfe9285adf391ab66faeb5def811fe08e47a221a. - -commit 6fcfe763aa54e0522e726dc088b23d24899794d8 -Author: Guus Sliepen -Date: Sat Jan 10 23:58:35 2015 +0100 - - Don't send probe replies if we don't have the other's key. - - This can happen with the legacy protocol. Don't try to send anything - back in this case, otherwise it will be sent via TCP, which is silly. - -commit f3801cb54311da2c30cbe27cd66559a2ea5daa91 -Author: Guus Sliepen -Date: Sat Jan 10 23:52:23 2015 +0100 - - Proactively send our own key when we request another node's key. - -commit c26bb47af130d48d003afd29af4d7ea6ad0538c5 -Author: Guus Sliepen -Date: Sat Jan 10 23:33:55 2015 +0100 - - Fix size of type 2 probe replies. - - Type 2 replies should be as small as possible. The minimum payload size - for probe packets is 14 bytes, otherwise they won't be recognized as - such. - -commit 0209f12d27d29f3aedc09b228bd289305851c75d -Author: Guus Sliepen -Date: Sat Jan 10 23:00:51 2015 +0100 - - Correctly estimate the initial MTU for legacy packets. - -commit 0e653260478005eb7c824a9a1a3df04f39938cd6 -Author: Guus Sliepen -Date: Sat Jan 10 22:28:47 2015 +0100 - - Try to clarify the new code in net_packet.c a bit. - - Mainly by trying to reduce complex if statements, by splitting try_tx() into try_tx_legacy() and - try_tx_sptps(), since they don't share a lot of code. - -commit 6056f1c13bb37bf711dff9c25a6eaea99f14d31f -Author: Guus Sliepen -Date: Sat Jan 10 22:26:33 2015 +0100 - - Remember whether we sent our key to another node. - - In tinc 1.0.x, this was tracked in node->inkey, however in tinc 1.1 we have an abstraction layer for - the legacy cipher and digest, and we don't keep an explicit copy of the key around. We cannot use - cipher_active() or digest_active(), since it is possible to set both to the null algorithm. So add a bit to - node_status_t. - -commit f1f2df07387bc48a3b165c85a0493ff2774de737 -Author: Guus Sliepen -Date: Sun Jan 4 16:00:02 2015 +0100 - - Use global "now" in try_udp() and try_mtu(). - -commit b737103a9187e0191dbc1995da3399ab3dbcdc66 -Author: Guus Sliepen -Date: Sun Jan 4 14:19:23 2015 +0100 - - Use void pointers for opaque data blobs in the SHA512 code. - -commit 4b42518813de7459a1fb264fe9ddfaf066ecc22b -Author: Guus Sliepen -Date: Sun Jan 4 14:15:35 2015 +0100 - - Fix indentation and some whitespace issues. - -commit 07108117ceddaff0654f9def703e717c002f3e2d -Author: Etienne Dechamps -Date: Sat Jan 3 10:05:57 2015 +0000 - - Use a different UDP discovery interval if the tunnel is established. - - This introduces a new configuration option, - UDPDiscoveryKeepaliveInterval, which is used as the UDP discovery - interval once the UDP tunnel is established. The pre-existing option, - UDPDiscoveryInterval, is therefore only used before UDP connectivity - is established. - - The defaults are set so that tinc sends UDP pings more aggressively - if the tunnel is not established yet. This is appropriate since the - size of probes in that scenario is very small (16 bytes). - -commit 06345f89b9a1e9acaf74cbbf896559b4286c102e -Author: Etienne Dechamps -Date: Thu Jan 1 16:59:45 2015 +0000 - - Recalculate and resend MTU probes if they are too large for the system. - - Currently, if a MTU probe is sent and gets rejected by the system - because it is too large (i.e. send() returns EMSGSIZE), the MTU - discovery algorithm is not aware of it and still behaves as if the probe - was actually sent. - - This patch makes the MTU discovery algorithm recalculate and send a new - probe when this happens, so that the probe "slot" does not go to waste. - -commit f89319f9815da5ece8e96f1a2a777fb6d2e31c33 -Author: Etienne Dechamps -Date: Wed Dec 31 16:21:08 2014 +0000 - - Fine-tune the MTU discovery multiplier for the maxmtu < MTU case. - - The original multiplier constant for the MTU discovery algorithm, 0.97, - assumes a somewhat pessmistic scenario where we don't get any help from - the OS - i.e. maxmtu never changes. This can happen if IP_MTU is not - usable and the OS doesn't reject overly large packets. - - However, in most systems the OS will, in fact, contribute to the MTU - discovery process. In these situations, an actual MTU equal to maxmtu - is quite likely (as opposed to the maxmtu = 1518 case where that is - highly unlikely, unless the physical network supports jumbo frames). - It therefore makes sense to use a multiplier of 1 - that will make the - first probe length equal to maxmtu. - - The best results are obtained if the OS supports the getsockopt(IP_MTU) - call, and its result is accurate. In that case, tinc will typically fix - the MTU after one single probe(!), like so: - - Using system-provided maximum tinc MTU for foobar (1.2.3.4 port 655): 1442 - Sending UDP probe length 1442 to foobar (1.2.3.4 port 655) - Got type 2 UDP probe reply 1442 from foobar (1.2.3.4 port 655) - Fixing MTU of foobar (1.2.3.4 port 655) to 1442 after 1 probes - -commit bce17c83e871cb8a8c9158045eaf13f1be4b3d13 -Author: Etienne Dechamps -Date: Wed Dec 31 16:12:11 2014 +0000 - - Add IP_MTU-based maxmtu estimation. - - Linux provides a getsockopt() option, IP_MTU, to get the kernel's best - guess at a connection MTU. In practice, it seems to return the MTU of - the physical interface the socket is using. - - This patch uses this option to initialize maxmtu to a better value when - MTU discovery starts. - - Unfortunately, this is not supported on Windows. Winsock has options - such as SO_MAX_MSG_SIZE, SO_MAXDG and SO_MAXPATHDG but they seem useless - as they always return absurdly large values (typically, 65507), as - confirmed by http://support.microsoft.com/kb/822061/ - -commit c1532035e2850dc4ec0eb22a6d51208e3128eb94 -Author: Etienne Dechamps -Date: Wed Dec 31 09:26:14 2014 +0000 - - Don't send MTU probes smaller than 512 bytes. - - If MTU discovery comes up with an MTU smaller than 512 bytes (e.g. due - to massive packet loss), it's pretty much guaranteed to be wrong. Even - if it's not, most Internet applications assume the MTU will be at least - 512, so fixing the MTU to a small value is likely to cause trouble - anyway. - - This also makes the discovery algorithm converge even faster, since the - interval it has to consider is smaller. - -commit 172cbe6771fd3b98233f71e42ac9c9407d534568 -Author: Etienne Dechamps -Date: Tue Dec 30 17:02:38 2014 +0000 - - Adjust MTU probe counts. - - The recently introduced new MTU discovery algorithm converges much - faster than the previous one, which allows us to reduce the number - of probes required before we can confidently fix the MTU. This commit - reduces the number of initial discovery probes from 90 to 20. With the - new algorithm this is more than enough to get to the precise (byte-level - accuracy) MTU value; in cases of packet loss or weird MTU values for - which the algorithm is not optimized, we should get close to the actual - value, and then we rely on MTU increase detection (steady state probes) - to fine-tune it later if the need arises. - - This patch also triggers MTU increase detection even if the MTU we have - is off by only one byte. Previously we only did that if it was off by at - least 8 bytes. Considering that (1) this should happen less often, - (2) restarting MTU discovery is cheaper than before and (3) having MTUs - that are subtly off from their intended values by just a few bytes - sounds like trouble, this sounds like a good idea. - -commit 24d28adf64934c8d726959e25dce8c10dbd10d1f -Author: Etienne Dechamps -Date: Tue Dec 30 16:34:48 2014 +0000 - - Use a smarter algorithm for choosing MTU discovery probe sizes. - - Currently, tinc uses a naive algorithm for choosing MTU discovery probe - sizes, picking a size at random between minmtu and maxmtu. - - This is of course suboptimal - since the behavior of probes is - deterministic (assuming no packet loss), it seems likely that using a - non-deterministic discovery algorithm will not yield the best results. - Furthermore, the randomness introduces a lot of variation in convergence - times. - - The random solution also suffers from pathological cases - since it's - using a uniform distribution, it doesn't take into account the fact that - it's often more interesting to send small probes rather than large ones, - because getting replies is the only way we can make progress (assuming - the worst case scenario in which the OS doesn't know anything, therefore - keeping maxmtu constant). This can lead to absurd situations where the - discovery algorithm is close to the real MTU, but can't get to it - because the random number generator keeps generating numbers that are - past it. - - The algorithm implemented in this patch aims to improve on the naive - random algorithm. It is organized around "cycles" of 8 probes; the sizes - of the probes decrease as we go through the cycle, thus making sure the - algorithm can cover lots of ground quickly (in case we're far from - actual MTU), but also examining the local area (in case we're close to - actual MTU). Using cycles ensures that the algorithm will "go back" to - large probes to better cover the new interval and to protect against - packet loss. - - For the probe size itself, various mathematical models were simulated in - an attempt to find the one that converges the fastest; it has been - determined that using an exponential based on the size of the remaining - interval was the most effective option. The exponential is adjusted with - a magic multiplier fine-tuned to make tinc jump to the "most - interesting" (i.e. 1400+) section as soon as discovery starts. - - Simulations indicate that assuming no packet loss and no help from the - OS (i.e. maxmtu stays constant), this algorithm will typically converge - to the *exact* MTU value in less than 10 probes, and will get within 8 - bytes in less than 5 probes, for actual MTUs between 1417 and ~1450 - (which is the range the algorithm is fine-tuned for). In contrast, the - previous algorithm gives results all over the place, sometimes taking - 30+ probes to get in the ballpark. Because of the issues with the - distribution, the previous algorithm sometimes never gets to the precise - MTU value within any reasonable amount of time - in contrast, the new - algorithm will always get to the precise value in less than 30 probes, - even if the actual MTU is completely outside the optimized range. - -commit c22560ae3283a8f5f12eee8ee4dcaa5e65ee8cf9 -Author: Etienne Dechamps -Date: Tue Dec 30 10:47:56 2014 +0000 - - Remove bandwidth estimation code. - - tinc bandwidth estimation has always been quite unreliable (at least in - my experience), but there's no chance of it working anymore since the - last changes to MTU discovery code, because packets are not sent in - batches of three anymore. - - This commit removes the dead code - fortunately, nothing depends on this - estimation (it's not even shown in node info). We probably need be - smarter about this if we do want this estimation back. - -commit 1b972f22733dc979568bc0ad8ebe0c711887e447 -Author: Etienne Dechamps -Date: Tue Dec 30 10:16:32 2014 +0000 - - Send one MTU probe at a time. - - Currently, tinc sends MTU probes in batches of three every second. This - commit changes that to send one packet every 333 milliseconds instead. - - This change brings two benefits: - - - It makes MTU probing faster, because MTU probe lengths are calculated - based on minmtu, and minmtu is adjusted based on the replies. When - sending batches of three packets, all three packets are based on the - same minmtu estimation; in contrast, by sending one packet more - frequently, each subsequent packet can benefit from the replies that - have been received since the last packet was sent. As a result, MTU - discovery converges much faster (2-3 times as fast, typically). - - - It reduces network spikiness - it's more network-friendly to send - one packet from time to time as opposed to sending bursts. - -commit 5bdc1f2b82869d379812879334dbf2b549ff48db -Author: Etienne Dechamps -Date: Thu Jan 1 16:04:08 2015 +0000 - - Use -1 to identify the post-initial MTU discovery state. - - This is a minor cosmetic nit to emphasise the distinction between the - initial MTU discovery phase, and the post-initial phase (i.e. maxmtu - checking). - - Furthermore, this is an improvement with regard to the DRY (Don't - Repeat Yourself) principle, as the maximum mtuprobes value is only - written once. - -commit df6f67895723dd0c4226fa0f94257245a81a273f -Author: Etienne Dechamps -Date: Thu Jan 1 10:32:14 2015 +0000 - - Fix MTU as soon as possible. - - If a probe reply is received that makes minmtu equal to maxmtu, we - have to wait until try_mtu() runs to realize that. Since try_mtu() - runs after a packet is sent, this means there is at least one packet - (possibly more, depending on timing) that won't benefit from the - fixed MTU. This also happens when maxmtu is updated from the send() - path. - - This commit fixes that by making sure we check whether the MTU can be - fixed every time minmtu or maxmtu is touched. - -commit 97cf4783188b8027d2309ce594fea5fc6daf31d1 -Author: Etienne Dechamps -Date: Mon Dec 29 17:05:19 2014 +0000 - - Move try_mtu() closer to try_tx(). - - This moves related functions together, and is a pure cut-and-paste - change. The reason it was not done in the previous commit is because it - would have made the diff harder to review. - -commit 98716a227ee39fdcdfafa7309adb73499311a2ce -Author: Etienne Dechamps -Date: Mon Dec 29 16:47:49 2014 +0000 - - Move PMTU discovery code into the TX path. - - Currently, the PMTU discovery code is run by a timeout callback, - independently of tunnel activity. This commit moves it into the TX - path, meaning that send_mtu_probe_handler() is only called if a - packet is about to be sent. Consequently, it has been renamed to - try_mtu() for consistency with try_tx(), try_udp() and try_sptps(). - - Running PMTU discovery code only as part of the TX path prevents - PMTU discovery from generating unreasonable amounts of traffic when - the "real" traffic is negligible. One extreme example is sending one - real packet and then going silent: in the current code this one little - packet will result in the entire PMTU discovery algorithm being run - from start to finish, resulting in absurd write traffic amplification. - With this patch, PMTU discovery stops as soon as "real" packets stop - flowing, and will be no more aggressive than the underlying traffic. - - Furthermore, try_mtu() only runs if there is confirmed UDP - connectivity as per the UDP discovery mechanism. This prevents - unnecessary network chatter - previously, the PMTU discovery code - would send bursts of (potentially large) probe packets every second - even if there was nothing on the other side. With this patch, the - PMTU code only does that if something replied to the lightweight UDP - discovery pings. - - These inefficiencies were made even worse when the node is not a - direct neighbour, as tinc will use PMTU discovery both on the - destination node *and* the relay. UDP discovery is more lightweight for - this purpose. - - As a bonus, this code simplifies overall code somewhat - state is - easier to manage when code is run in predictable contexts as opposed - to "surprise callbacks". In addition, there is no need to call PMTU - discovery code outside of net_packet.c anymore, thereby simplifying - module boundaries. - -commit eef792c01ed1704c03d55163de3f302a3c1d42fa -Author: Etienne Dechamps -Date: Mon Dec 29 16:11:04 2014 +0000 - - Remove PMTU discovery code redundant with UDP discovery. - - This is a rewrite of the send_mtu_probe_handler() function to make it - focus on the actual discovery of PMTU. In particular, the PMTU - discovery code doesn't care about tunnel state anymore - it only cares - about doing the initial PMTU discovery, and once that's done, making - sure PMTU did not increase by checking it from time to time. All other - duties have already been rewritten in the UDP discovery code. - - As a result, the send_mtu_probe_handler(), which previously implemented - a nightmarish state machine which was very difficult to follow and - understand, has been massively simplified. We moved from four persistent - states to only two - initial discovery and steady state. - - Furthermore, a side effect is that network chatter is reduced: instead - of sending bursts of three minmtu-sized packets in the steady state, - there is only one such packet that's sent from the UDP discovery code. - However, that introduces a slight regression in the bandwidth estimation - code, which relies on three-packet bursts in order to function. - Considering that this estimation is extremely unreliable (in my - experience) and isn't relied on by anything, this seems like an - acceptable regression. - -commit 88026f27715774a7647c109ba5594068f0ba56af -Author: Etienne Dechamps -Date: Mon Dec 29 15:40:55 2014 +0000 - - Move responsibility for local discovery to UDP discovery. - - Since UDP discovery is the place where UDP feasibility is checked, it - makes sense to test for local connectivity as well. This was previously - done as part of PMTU discovery. - -commit 7939ee12836bf2ef772f2a6a1e805ee0d64a8e70 -Author: Etienne Dechamps -Date: Mon Dec 29 10:34:39 2014 +0000 - - Add UDP discovery mechanism. - - This adds a new mechanism by which tinc can determine if a node is - reachable via UDP. The new mechanism is currently redundant with the - PMTU discovery mechanism - that will be fixed in a future commit. - - Conceptually, the UDP discovery mechanism works similarly to PMTU - discovery: it sends UDP probes (of minmtu size, to make sure the tunnel - is fully usable), and assumes UDP is usable if it gets replies. It - assumes UDP is broken if too much time has passed since the last reply. - - The big difference with the current PMTU discovery mechanism, however, - is that UDP discovery probes are only triggered as part of the - packet TX path (through try_tx()). This is quite interesting, because - it means tinc will never send UDP pings more often than normal packets, - and most importantly, it will automatically stop sending pings as soon - as packets stop flowing, thereby nicely reducing network chatter. - - Of course, there are small drawbacks in some edge cases: for example, - if a node only sends one packet every minute to another node, these - packets will only be sent over TCP, because the interval between packets - is too long for tinc to maintain the UDP tunnel. I consider this a - feature, not a bug: I believe it is appropriate to use TCP in scenarios - where traffic is negligible, so that we don't pollute the network with - pings just to maintain a UDP tunnel that's seeing negligible usage. - -commit 5d6478b9fbb7379fe6017b2b74c0f1ccb3d2501f -Author: Etienne Dechamps -Date: Sun Dec 28 17:29:03 2014 +0000 - - Move try_sptps() closer to try_tx(). - - This moves related functions together. try_tx() is at the right place - since its only caller is send_packet(). - - This is a pure cut-and-paste change. The reason it was not done in the - previous commit is because it would have made the diff harder to review. - -commit 81578484dc74fd92f1b01f71f882016f120ab1de -Author: Etienne Dechamps -Date: Sun Dec 28 17:16:27 2014 +0000 - - Add the try_tx() function. - - Currently, the TX path (starting from send_packet()) in tinc has three - responsabilities: - - - Making sure packets can be sent (e.g. fetching SPTPS keys); - - Making sure they can be sent optimally (e.g. fetching non-SPTPS keys - so that UDP can be used); - - Sending the actual packet, if feasible. - - The first two are closely related; the third one, however, can be - cleanly separated from the other two - meaning, we can loosen code - coupling between sending packets and "optimizing" the way packets are - sent. This will become increasingly important as future commits will - move more tunnel establishment and maintenance code into the TX path, - so we will benefit from a cleaner separation of concerns. - - This is especially relevant because of the dual nature of the TX path - (SPTPS versus non-SPTPS), which can make things really complicated when - trying to share low-level code between both. - - In this commit, code related to establishing or improving tunnels is - moved away from the core TX path by introducing the "try_*()" family of - function, of which try_sptps() already existed before this commit. - - This is a pure refactoring; this commit shouldn't introduce any change - in behavior. - -commit 950edc0744dfa04790ae274e8b7f55b1a990a43c -Author: Etienne Dechamps -Date: Sun Oct 12 19:44:33 2014 +0100 - - Clarify the send_mtu_probe() function. - - This cleans up the PMTU probing function a little bit. It moves the - low-level sending of packets to a separate function, so that the code - reads naturally instead of using a weird for loop with "special - indexes". In addition, comments are moved inside the body of the - function for additional context. - - This shouldn't introduce any change of behavior, except for local - discovery which has some minor logic fixes and which now always uses - small packets (16 bytes) because there's no need for a full-length - probe just to try the local network. - -commit d28f33228635e78dac8f9e9bcaec92690f2ca10a -Author: Guus Sliepen -Date: Thu Jan 1 00:52:39 2015 +0100 - - Fixes for bugs in src/Makefile.am and tincctl.c introduced by cfe9285adf391ab66faeb5def811fe08e47a221a. - -commit 4d50f9f3485503099f5cb6e8486e9b98b72cb9be -Author: Guus Sliepen -Date: Tue Dec 30 11:16:08 2014 +0100 - - Add missing nolegacy/crypto.c and prf.c. - -commit cfe9285adf391ab66faeb5def811fe08e47a221a -Author: Guus Sliepen -Date: Mon Dec 29 22:57:18 2014 +0100 - - Allow tinc to be compiled without OpenSSL. - - The option "--disable-legacy-protocol" was added to the configure - script. The new protocol does not depend on any external crypto - libraries, so when the option is used tinc is no longer linked to - OpenSSL's libcrypto. - -commit 8d32b283b016e205b051b0bacb49a1e86fd5e1bc -Author: Guus Sliepen -Date: Sat Dec 27 09:22:31 2014 +0100 - - Releasing 1.1pre11. - -commit db465434e2736f6e052e5c52d3613ad81b4bde10 -Author: Guus Sliepen -Date: Sat Dec 27 09:20:46 2014 +0100 - - Add BroadcastSubnet and DeviceStandby options to the manual and completion. - -commit 26d3ee0dd9b770a857615752b5c5588be0354a16 -Author: Guus Sliepen -Date: Sat Dec 27 09:08:34 2014 +0100 - - Better default paths for log and PID files on Windows. - -commit b78436ff1e9afd767c3da473d34b7553d8411b6a -Author: Guus Sliepen -Date: Fri Dec 26 18:22:13 2014 +0100 - - Remove AES-GCM support. - -commit 128a37397432e5e63099633e275c65a652c16673 -Author: Guus Sliepen -Date: Fri Dec 26 18:12:28 2014 +0100 - - Linux doesn't like .PHONY .o files. - - In order to please every OS, make version.c .PHONY again, and add an - empty rule to make version.c. - -commit 69689f908b0c9a14b7108b7ab8edd92facc53ddf -Author: Guus Sliepen -Date: Fri Dec 26 17:53:40 2014 +0100 - - We don't depend on ECDH functions from OpenSSL anymore. - -commit aa2d4f8dd9bab794dd197b92ba54e6428400555f -Author: Guus Sliepen -Date: Fri Dec 26 15:58:28 2014 +0100 - - BSD make doesn't like .PHONY .c files. - - It then thinks there should be a rule to make the .c file, which does - not exist of course. Luckily, we can tell it that version.o is .PHONY, - and this will still cause the .o file to be regenerated and linked into - the binaries everytime make is called. - -commit 8ee4004edfbc79b1a17bf03c262f063f2f4c128d -Author: Guus Sliepen -Date: Fri Dec 26 15:40:09 2014 +0100 - - Check whether res_init() really lives in libresolv. - - On some platforms (Mac OS X for example), the res_init() function requires - linking with libresolv. On others (Linux, OpenBSD for example), res_init() - lives in libc. - -commit 9f20922d62d258d7f5f1ef30dcd538c661062439 -Author: Guus Sliepen -Date: Fri Dec 26 14:59:15 2014 +0100 - - Update THANKS file. - -commit 880d74ad2d8a6d73c2e94ec54df542b88dc0c6f4 -Author: Guus Sliepen -Date: Fri Dec 26 14:38:01 2014 +0100 - - Allow running tinc without RSA keys. - - This allows one to run tinc with only Ed25519 keys, forcing tinc to - always use the SPTPS protocol. - -commit 266afc6c63d3d02584feb24b69063f97057daac8 -Merge: 7730d5f3 c269a17c -Author: Guus Sliepen -Date: Thu Dec 25 18:13:24 2014 +0100 - - Merge remote-tracking branch 'groxxda/gui-fixes' into 1.1 - -commit 7730d5f3ed9bd7c011dced5808130ffcbd74ea6b -Author: Etienne Dechamps -Date: Sun Oct 12 12:14:46 2014 +0100 - - Use plain old PACKET for TCP packets sent directly to a neighbor. - - Currently, when sending packets over TCP where the final recipient is - a node we have a direct metaconnection to, tinc first establishes a - SPTPS handshake between the two neighbors. - - It turns out this SPTPS tunnel is not actually useful, because the - packet is only being sent over one metaconnection with no intermediate - nodes, and the metaconnection itself is already secured using a separate - SPTPS handshake. - - Therefore it seems simpler and more efficient to simply send these - packets directly over the metaconnection itself without any additional - layer. This commits implements this solution without any changes to the - metaprotocol, since the appropriate message already exists: it's the - good old "plaintext" PACKET message. - - This change brings two significant benefits: - - - Packets to neighbors can be sent immediately - there is no initial - delay and packet loss previously caused by the SPTPS handshake; - - - Performance of sending packets to neighbors over TCP is greatly - improved since the data only goes through one round of encryption - instead of two. - - Conflicts: - src/net_packet.c - -commit 0356efecb6385b59a69bea220057396d6daa30bc -Author: Etienne Dechamps -Date: Sun Oct 12 11:41:08 2014 +0100 - - Don't spontaneously start SPTPS with neighbors. - - Currently, when tinc establishes a metaconnection, it automatically - starts a VPN SPTPS tunnel with the other side of the metaconnection. - - It is not clear what this is trying to accomplish. Having a - metaconnection with a node does not necessarily mean we're going to send - packets to that node. This patch removes this behavior, thereby - simplifying code paths and removing unnecessary network chatter. - - Naturally, this introduces a slight delay (as well as at least one - initial packet loss) between the moment a metaconnection is established - and the moment VPN packets can be exchanged between the two nodes. - However this is no different to the non-neighbor case, so it makes - things more consistent and therefore easier to reason about. - -commit 6b92ac505d2cd5c7e390d49bf1f0b399ef9f8327 -Author: Guus Sliepen -Date: Wed Dec 24 22:23:24 2014 +0100 - - Add a variable offset to vpn_packet_t, drop sptps_packet_t. - - The offset value indicates where the actual payload starts, so we can - process both legacy and SPTPS UDP packets without having to do casting - tricks and/or moving memory around. - -commit 107d9c7da5b206425a8e1643a6849ea990f725f8 -Author: Guus Sliepen -Date: Wed Dec 24 22:15:40 2014 +0100 - - Use void pointers for opaque data blobs in the SPTPS code. - -commit 3df86ef17bce9f24c3dad79ccc2b17aa6e93ea34 -Author: Guus Sliepen -Date: Wed Dec 24 17:31:33 2014 +0100 - - Fix memory leaks found by Valgrind. - -commit d00d8dbb9b122a17ef93090de10396ebdd2c4a84 -Author: Guus Sliepen -Date: Wed Dec 24 17:06:05 2014 +0100 - - Don't use myself->name in device_disable(), it's already freed. - -commit 313de46e70b249de2938b04e7fc9c3872d99474a -Author: Guus Sliepen -Date: Wed Dec 24 16:59:08 2014 +0100 - - Don't pass uninitialized bytes to ioctl(). - -commit a99ded7d987c3242f972162e02767c498257f2b8 -Author: Guus Sliepen -Date: Wed Dec 24 16:54:12 2014 +0100 - - Avoid using OpenSSL's random number functions. - -commit 199573f1e834290290a1c278072a153b90443b05 -Author: Guus Sliepen -Date: Sun Dec 14 13:05:30 2014 +0100 - - Fix reception of SPTPS UDP packets. - - Some bugs were introduced in 46fa12e666badb79e480c4b2399787551f8266d0. - -commit 558b19c2432d938afc4a659668bd461ace6ed744 -Author: Guus Sliepen -Date: Sun Dec 14 12:42:03 2014 +0100 - - Fix segfault when receiving UDP packets with an unknown source address. - -commit 5104001bae7d09040703ddbe18cf8781c7aaa94f -Author: Guus Sliepen -Date: Mon Dec 8 08:43:15 2014 +0100 - - Changes that should have been in commit 46fa12e666badb79e480c4b2399787551f8266d0. - -commit 46fa12e666badb79e480c4b2399787551f8266d0 -Author: Guus Sliepen -Date: Mon Dec 8 00:58:09 2014 +0100 - - Make UDP packet handling more efficient. - - Limit the amount of address/ID lookups to the minimum in all cases: - - 1) Legacy packets, need an address lookup. - 2) Indirect SPTPS packets, need an address lookup + two ID lookups. - 3) Direct SPTPS packets, need an ID or an address lookup. - - So we start with an address lookup. If the source is an 1.1 node, we know it's an SPTPS packet, - and then the check for direct packets is a simple check if dstid is zero. If not, do the srcid and dstid - lookup. If the source is an 1.0 node, we don't have to do anything else. - - If the address is unknown, we first check whether it's from a 1.1 node by assuming it has a valid srcid - and verifying the packet. If not, use the old try_harder(). - -commit 263d9903826ffb65aec89bdf5d46f72bd183d467 -Author: Guus Sliepen -Date: Mon Dec 8 00:44:38 2014 +0100 - - Avoid memmove() for legacy UDP packets. - -commit c2319e90b16962fe899bc60abc8af0e2542bb176 -Author: Guus Sliepen -Date: Sun Dec 7 22:11:37 2014 +0100 - - Cache node IDs in a hash table for faster lookups. - -commit 9d48d5b7d48ad23e23eae02feae69bdc5ae80c8e -Author: Guus Sliepen -Date: Sun Dec 7 22:10:16 2014 +0100 - - Add an explicit hash_delete() function. - -commit 6062df4a0fa6214d21ac83d885087e9dbdac3f39 -Author: Guus Sliepen -Date: Sun Dec 7 21:42:20 2014 +0100 - - Better log messages when we already know the peer's key during an upgrade. - - If the peer presents a different one from the one we already know, log - an error. Otherwise, log an informational message, and terminate in the - same way as we would if we didn't already have that key. - -commit 148a4c9161735a76b0a4ce73ffaaec21d76ca702 -Author: Sven-Haegar Koch -Date: Fri Dec 5 03:06:44 2014 +0100 - - Try handling the case when the first side knows the ecdsa key of - the second, but the second not the key of the first. - (And both have the experimental protocol enabled) - -commit b90c42a33b78f22b7046da5a5445c712020f30eb -Author: Guus Sliepen -Date: Sun Dec 7 17:25:30 2014 +0100 - - Log an error message with the node's name when receiving bad SPTPS packets. - - The SPTPS code doesn't know about nodes, so when it logs an error about - a bad packet, it doesn't log which node it came from. So add a log - message with the node's name and hostname in receive_udppacket(). - -commit 660a2c7d1bf7f5fba905b525bc7c3b9a5ac2ec99 -Author: Guus Sliepen -Date: Sun Dec 7 17:20:18 2014 +0100 - - Check validity of Ed25519 key during an upgrade. - -commit 5716c8877fd705d5af36d82e27632b123fa5dde0 -Author: Sven-Haegar Koch -Date: Fri Dec 5 02:41:55 2014 +0100 - - Do not disconnect when no ecdsa key is known yet. - - This is the normal case when we support the experimental protocol, - but the other side is a tinc 1.0 which does not. - -commit dd6b0e65b96280235893705a947eac4a1c71276e -Author: Guus Sliepen -Date: Wed Dec 3 14:51:45 2014 +0100 - - Fix compiler warnings. - -commit 790b107f668a886c3b335e68b9440ef5152a2844 -Author: Etienne Dechamps -Date: Sat Oct 4 16:33:33 2014 +0100 - - Query the Linux device for its MAC address. - - On Linux, tinc doesn't know the MAC address of the TAP device until the - first read. This means that if no packets are sent through the - interface, tinc won't be able to figure out which MAC address to tag - incoming packets with. As a result, it is impossible to receive any - packet until at least one packet has been sent. - - When IPv6 is disabled Linux does not spontanously send any packets - when the interface comes up. At first users wonder why the node is not - responding to ICMP pings, and then as soon as at least one packet is - sent through the interface, pings mysteriously start working, resulting - in user confusion. - - This change fixes that problem by making sure tinc is aware of the - device's MAC address even before the first packet is sent. - -commit c269a17ca4d4e4946a3f8ab05da8cdd338d97ffb -Author: groxxda -Date: Tue Oct 14 22:18:56 2014 +0200 - - tinc-gui: Don't assign broadcast subnets to any node, fix parsing of Edges, fix diplay of Subnet.weight. - -commit 9a366544c297d5c558800f9ffc301e2cb5a6a672 -Author: Etienne Dechamps -Date: Sat Oct 4 15:01:11 2014 +0100 - - Make sure to discover MTU with relays. - - Currently, when tinc sends UDP SPTPS datagrams through a relay, it - doesn't automatically start discovering PMTU with the relay. This means - that unless something else triggers PMTU discovery, tinc will keep using - TCP when sending packets through the relay. - - This patches fixes the issue by explicitly establishing UDP tunnels with - relays. - -commit 63daebcd1ec2975c0c2ad8e0ee0fced33b1fbbf0 -Author: Etienne Dechamps -Date: Sat Oct 4 14:25:16 2014 +0100 - - Don't send MTU probes to nodes we can't reach directly. - - Currently, we send MTU probes to each node we receive a key for, even if - we know we will never send UDP packets to that node because of - indirection. This commit disables MTU probing between nodes that have - direct communication disabled, otherwise MTU probes end up getting sent - through relays. - - With the legacy protocol this was never a problem because we would never - request the key of a node with indirection enabled; with SPTPS this was - not a problem until we introduced relaying because send_sptps_data() - would simply ignore indirections, but this is not the case anymore. - - Note that the fix is implemented in a quick and dirty way, by disabling - the call to send_mtu_probe() in ans_key_h(); this is not a clean fix - because there's no code to resume sending MTU probes in case the - indirection disappears because of a graph change. - -commit 111040d7d1993c67246c52cbfd073183818655f9 -Author: Etienne Dechamps -Date: Sun Sep 28 12:38:06 2014 +0100 - - Add UDP datagram relay support to SPTPS. - - This commit changes the layout of UDP datagrams to include a 6-byte - destination node ID at the very beginning of the datagram (i.e. before - the source node ID and the seqno). Note that this only applies to SPTPS. - - Thanks to this new field, it is now possible to send SPTPS datagrams to - nodes that are not the final recipient of the packets, thereby using - these nodes as relay nodes. Previously SPTPS was unable to relay packets - using UDP, and required a fallback to TCP if the final recipient could - not be contacted directly using UDP. In that sense it fixes a regression - that SPTPS introduced with regard to the legacy protocol. - - This change also updates tinc's low-level routing logic (i.e. - send_sptps_data()) to automatically use this relaying facility if at all - possible. Specifically, it will relay packets if we don't have a - confirmed UDP link to the final recipient (but we have one with the next - hop node), or if IndirectData is specified. This is similar to how the - legacy protocol forwards packets. - - When sending packets directly without any relaying, the sender node uses - a special value for the destination node ID: instead of setting the - field to the ID of the recipient node, it writes a zero ID instead. This - allows the recipient node to distinguish between a relayed packet and a - direct packet, which is important when determining the UDP address of - the sending node. - - On the relay side, relay nodes will happily relay packets that have a - destination ID which is non-zero *and* is different from their own, - provided that the source IP address of the packet is known. This is to - prevent abuse by random strangers, since a node can't authenticate the - packets that are being relayed through it. - - This change keeps the protocol number from the previous datagram format - change (source IDs), 17.4. Compatibility is still preserved with 1.0 and - with pre-1.1 releases. Note, however, that nodes running this code won't - understand datagrams sent from nodes that only use source IDs and - vice-versa (not that we really care). - - There is one caveat: in the current state, there is no way for the - original sender to know what the PMTU is beyond the first hop, and - contrary to the legacy protocol, relay nodes can't apply MSS clamping - because they can't decrypt the relayed packets. This leads to - inefficient scenarios where a reduced PMTU over some link that's part of - the relay path will result in relays falling back to TCP to send packets - to their final destinations. - - Another caveat is that once a packet gets sent over TCP, it will use - TCP over the entire path, even if it is technically possible to use UDP - beyond the TCP-only link(s). - - Arguably, these two caveats can be fixed by improving the - metaconnection protocol, but that's out of scope for this change. TODOs - are added instead. In any case, this is no worse than before. - - In addition, this change increases SPTPS datagram overhead by another - 6 bytes for the destination ID, on top of the existing 6-byte overhead - from the source ID. - -commit 8dd1c8a020e3babf5054179b0d30e2aa850d2e2b -Author: Etienne Dechamps -Date: Sat Sep 27 18:13:33 2014 +0100 - - Prepend source node ID information to UDP datagrams. - - This commit changes the layout of UDP datagrams to include the 6-byte ID - (i.e. node name hash) of the node that crafted the packet at the very - beginning of the datagram (i.e. before the seqno). Note that this only - applies to SPTPS. - - This is implemented at the lowest layer, i.e. in - handle_incoming_vpn_data() and send_sptps_data() functions. Source ID is - added and removed there, in such a way that the upper layers are unaware - of its presence. - - This is the first stepping stone towards supporting UDP relaying in - SPTPS, by providing information about the original sender in the packet - itself. Nevertheless, even without relaying this commit already provides - a few benefits such as being able to reliably determine the source node - of a packet in the presence of an unknown source IP address, without - having to painfully go through all node keys. This makes tinc's behavior - much more scalable in this regard. - - This change does not break anything with regard to the protocol: It - preserves compatibility with 1.0 and even with older pre-1.1 releases - thanks to a minor protocol version change (17.4). Source ID information - won't be included in packets sent to nodes with minor version < 4. - - One drawback, however, is that this change increases SPTPS datagram - overhead by 6 bytes (the size of the source ID itself). - -commit 092d620dbb3fdc8226ea0a4e1cfd5cd53d608420 -Author: Etienne Dechamps -Date: Sat Sep 27 13:34:56 2014 +0100 - - Change vpn_packet_t::seqno from uint32_t to uint8_t[4]. - - This is to make sure on-wire vpn_packet_t fields are always 1-byte - aligned, otherwise padding could get in the way. - -commit 55a78da4e0b496fc599704473f41d5ea52669737 -Author: Etienne Dechamps -Date: Sun Sep 21 18:17:02 2014 +0100 - - Introduce node IDs. - - This introduces a new type of identifier for nodes, which complements - node names: node IDs. Node IDs are defined as the first 6 bytes of the - SHA-256 hash of the node name. They will be used in future code in lieu - of node names as unique node identifiers in contexts where space is at - a premium (such as VPN packets). - - The semantics of node IDs is that they are supposed to be unique in a - tinc graph; i.e. two different nodes that are part of the same graph - should not have the same ID, otherwise things could break. This - solution provides this guarantee based on realistic probabilities: - indeed, according to the birthday problem, with a 48-bit hash, the - probability of at least one collision is 1e-13 with 10 nodes, 1e-11 - with 100 nodes, 1e-9 with 1000 nodes and 1e-7 with 10000 nodes. Things - only start getting hairy with more than 1 million nodes, as the - probability gets over 0.2%. - -commit ac77e3c1eb9d7503e30dd69e96e411e7baaa1dfd -Author: Etienne Dechamps -Date: Sun Sep 21 15:44:59 2014 +0100 - - Invalidate UDP information on address changes. - - Currently, when tinc receives an UDP packet from an unexpected address - (i.e. an address different from the node's current address), it just - updates its internal UDP address record and carries on like nothing - happened. - - This poses two problems: - - - It assumes that the PMTU for the new address is the same as the - old address, which is risky. Packets might get dropped if the PMTU - turns out to be smaller (or if UDP communication on the new address - turns out to be impossible). - - - Because the source address in the UDP packet itself is not - authenticated (i.e. it can be forged by an attacker), this - introduces a potential vulnerability by which an attacker with - control over one link can trick a tinc node into dumping its network - traffic to an arbitrary IP address. - - This commit fixes the issue by invalidating UDP/PMTU state for a node - when its UDP address changes. This will trigger a temporary fallback - to indirect communication until we get confirmation via PMTU discovery - that the node is indeed sitting at the other end of the new UDP address. - -commit f57d53c3ad9af89489e15a8cfd94b56937bf3179 -Author: Etienne Dechamps -Date: Sat Sep 27 17:51:33 2014 +0100 - - Fix protocol version check for type 2 MTU probe replies. - - Currently tinc only uses type 2 MTU probe replies if the recipient uses - protocol version 17.3. It should of course support any higher minor - protocol version as well. - -commit f6b008d7317cb1c3766419bdf6bd97d7b4d561f1 -Author: Franz Pletz -Date: Mon Sep 22 22:43:15 2014 +0200 - - tinc-gui: Use /usr/bin/env to resolve path to python - -commit daf65919d1ccc40f6c11f3f723f325de9021c422 -Author: Etienne Dechamps -Date: Sun Sep 21 11:38:41 2014 +0200 - - Preemptively mirror REQ_PUBKEY messages from nodes with unknown keys. - - In this commit, if a node receives a REQ_PUBKEY message from a node it - doesn't have the key for, it will send a REQ_PUBKEY message in return - *before* sending its own key. - - The rationale is to prevent delays when establishing communication - between two nodes that see each other for the first time. These delays - are caused by the first SPTPS packet being dropped on the floor, as - shown in the following typical exchange: - - node1: No Ed25519 key known for node2 - REQ_PUBKEY -> - <- ANS_PUBKEY - node1: Learned Ed25519 public key from node2 - REQ_SPTPS_START -> - node2: No Ed25519 key known for zyklos - <- REQ_PUBKEY - ANS_PUBKEY -> - node2: Learned Ed25519 public key from node1 - -- 10-second delay -- - node1: No key from node2 after 10 seconds, restarting SPTPS - REQ_SPTPS_START -> - <- SPTPS -> - node1: SPTPS key exchange with node2 succesful - node2: SPTPS key exchange with node1 succesful - - With this patch, the following happens instead: - - node1: No Ed25519 key known for node2 - REQ_PUBKEY -> - node2: Preemptively requesting Ed25519 key for node1 - <- REQ_PUBKEY - <- ANS_PUBKEY - ANS_PUBKEY -> - node2: Learned Ed25519 public key from node1 - node1: Learned Ed25519 public key from node2 - REQ_SPTPS_START -> - <- SPTPS -> - node1: SPTPS key exchange with node2 succesful - node2: SPTPS key exchange with node1 succesful - -commit c897f8c99e0b0827cff60f098bd3f9852a062233 -Author: Etienne Dechamps -Date: Sun Sep 21 12:58:23 2014 +0200 - - Fix default device path selection on BSD. - - Currently, if DeviceType = tap but Mode = router, the default - device path is /dev/tun0, which is wrong. This commit fixes that. - -commit a649aa51bf8e5b5fcc76061c9f660122a08245a8 -Author: Etienne Dechamps -Date: Sun Sep 21 11:25:49 2014 +0100 - - Ignore the Interface option if device rename is impossible. - - There are platforms on which it is impossible to rename the TUN/TAP - device. An example is Mac OS X (tuntapx). On these platforms, - specifying the Interface option will not rename the interface, but - the specified name will still be passed to tinc-up scripts and the - like, resulting in potential confusion for the user. - -commit 053925efebf466b5866de12434010c1e8127c172 -Author: Etienne Dechamps -Date: Sun Sep 21 11:14:19 2014 +0100 - - Fix default TAP device on Darwin. - - On Darwin (tuntapx), the first TAP device is /dev/tap0, not /dev/tun0. - -commit 1ac9a3fbd18f961d604c2c080374b8fc32f155d6 -Author: Etienne Dechamps -Date: Sat Sep 6 18:16:46 2014 +0100 - - Fix wrong identifier in SO_NOSIGPIPE call. - - f134bd0c9c2213fbbb3967f3d784759cb65e2c76 broke the Mac OS X build by - introducing a reference to an identifier, c, that doesn't exist. - -commit 7ac52637659b7f17ab5139010f0436aefcf9625c -Author: Etienne Dechamps -Date: Sat Sep 6 10:43:15 2014 +0100 - - Don't enable the device if the reachable count is zero. - - A logic bug was introduced in bd451cfe1512fa69eac35a60dbe6df17bfc39154 - in which running graph() several times with zero reachable nodes had - the effect of calling device_enable() (instead of keeping the device - disabled). - - This results in weird behavior when DeviceStandby is enabled, especially - on Windows where calling device_enable() several times in a row corrupts - I/O structures for the device, rendering it unusable. - -commit 9ad656b512582ed95a574b3fd74b948f876953ce -Author: Etienne Dechamps -Date: Sun Aug 31 13:59:30 2014 +0100 - - Fix undefined HOST_NAME_MAX on Windows. - - The Windows build was broken by commit - 826ad11e419db90b66b3f76a90b54df021bb39fc which introduced a dependency - on the HOST_NAME_MAX macro, which is not defined on Windows. According - to MSDN for gethostname(), the maximum length of the returned string - is 256 bytes (including the terminating null byte), so let's use that - as a fallback. - -commit 0f09260b1377f2d6f14bcdf5de7cbad415743c1e -Author: Etienne Dechamps -Date: Sat Aug 30 10:57:57 2014 +0100 - - Remove Google from the list of copyright owners. - - Google released copyright to me for my own contributions. - -commit 38d7e730e619a8b86dfbf68d77773564595f12a1 -Author: William A. Kennington III -Date: Sun Aug 24 22:35:25 2014 -0700 - - tincctl: Use replace_name to properly replace and validate input hostnames - -commit 511b51ffe60c20a9091829c03863197b76027716 -Author: William A. Kennington III -Date: Sun Aug 24 21:55:42 2014 -0700 - - utils: Refactor check_id out of protocol for global access - -commit 826ad11e419db90b66b3f76a90b54df021bb39fc -Author: William A. Kennington III -Date: Sun Aug 24 19:49:27 2014 -0700 - - utils: Refactor get_name's functionality into util for global access - -commit 78bf82cf332327889f0f61388b73053850d8e59b -Author: Etienne Dechamps -Date: Sun Aug 17 20:22:44 2014 +0100 - - Clarify copyright ownership for code authored by Etienne Dechamps. - -commit 73d8393bd6c54e0ec28d5f6c114a6eb3821a8ec1 -Author: Sven-Haegar Koch -Date: Thu Aug 7 22:14:20 2014 +0200 - - commandline.test: Adding test that fetching non-existing config setting really fails. - -commit 9fe5ab7ccb60537810b60b76a415507ef2cadfdd -Author: Sven-Haegar Koch -Date: Thu Aug 7 23:01:05 2014 +0200 - - Fix exit code of "tinc get". - - Successfully getting an existing variable ("tinc get name") should - not result in an error exitcode (1) from the tinc command. - - This changes the result of test/commandline.test from FAIL to PASS. - -commit 5ae1ec8d80393182b6ff235062b6816b64edfa9b -Author: Etienne Dechamps -Date: Sat Jul 19 18:11:42 2014 +0100 - - Handle TAP-Win32 immediate reads correctly. - - The handling of TAP-Win32 virtual network device reads that complete - immediately (ReadFile() returns TRUE) is incorrect - instead of - starting a new read, tinc will continue listening for the overlapped - read completion event which will never fire. As a result, tinc stops - receiving packets on the interface. - -commit 1d10afd3d33f5623494d9eeb2fa8237712f8aa2e -Author: Etienne Dechamps -Date: Sat Jul 19 16:05:23 2014 +0100 - - Only read from TAP-Win32 if the device is enabled. - - With newer TAP-Win32 versions (such as the experimental - tap-windows6 9.21.0), tinc is unable to read from the virtual network - device: - - Error while reading from (null) {23810A13-BCA9-44CE-94C6-9AEDFBF85736}: No such file or directory - - This is because these new drivers apparently don't accept reads when - the device is not in the connected state (media status). - - This commit fixes the issue by making sure we start reading no sooner - than when the device is enabled, and that we stop reading when the - device is disabled. This also makes the behavior somewhat cleaner, - because it doesn't make much sense to read from a disabled device - anyway. - -commit cc9203ee75c49360dd29710ac12bb67fe503f97b -Author: Etienne Dechamps -Date: Sun Jul 13 15:54:34 2014 +0100 - - Add a non-interactive mode to tinc commands. - - Some tinc commands, such as "tinc generate-keys", use the terminal to - ask the user for information. This can be bypassed by making sure - there is no terminal, which is trivial on *nix but might require - jumping through some hoops on Windows depending on how the command is - invoked. - - This commit adds a --batch option that ensures tinc will never ask the - user for input, even if it is attached to a terminal. - -commit afb175873e6aa10d2d4dca3572edf054968c538d -Author: Guus Sliepen -Date: Sat Jul 12 22:51:37 2014 +0200 - - Revert "Use git description as the tinc version." - - This reverts commit e024b7a2c50e23311834e6d180e5acc72783b339. Automatic version - number generation needs a little bit more work to get it working correctly in - all cases. - -commit 19e42b76f546dc3baee4a5d6a4f161155d279c74 -Merge: f7043048 b12f122f -Author: Guus Sliepen -Date: Sat Jul 12 22:25:55 2014 +0200 - - Merge branch 'keysegfault' of https://github.com/dechamps/tinc into 1.1 - -commit f704304823df0ac868786ac89355eda38592dc3f -Merge: 54fd228e ea12a0fb -Author: Guus Sliepen -Date: Sat Jul 12 22:22:31 2014 +0200 - - Merge branch 'tincstart' of https://github.com/dechamps/tinc into 1.1 - -commit 54fd228e696acc9d78a17845402640cc04e2c54c -Merge: 53036a58 14be1d30 -Author: Guus Sliepen -Date: Sat Jul 12 22:21:01 2014 +0200 - - Merge branch 'ctrl' of https://github.com/dechamps/tinc into 1.1 - -commit 53036a58790168e18f524bd923f9a7d34691ba2d -Merge: ddd0cd47 b2a6381a -Author: Guus Sliepen -Date: Sat Jul 12 22:19:45 2014 +0200 - - Merge branch 'winwarnings' of https://github.com/dechamps/tinc into 1.1 - -commit ddd0cd47bc0bb3478b7d250192248a1e3aa2a243 -Author: Etienne Dechamps -Date: Mon Jun 30 14:03:17 2014 +0100 - - Verify seqno early in sptps_verify_datagram(). - - This is a slight optimization for sptps_verify_datagram(), which might - come in handy since this function is called in a loop via try_harder(). - - It turns out that since sptps_verify_datagram() doesn't update any - state, it doesn't matter in which order verifications are done. However, - it does affect performance since it's much cheaper to check the seqno - than to try to decrypt the packet. - - Since this function is called with the wrong node most of the time, it - makes verification vastly faster for the majority of calls because the - seqno will be wrong in most cases. - -commit 7bf61575fe1009ecb93b3f6b8f5145525874e470 -Author: Etienne Dechamps -Date: Sun Jul 6 11:34:57 2014 +0100 - - Add documentation about using system-assigned ports. - - There are two caveats to be aware of which are documented in this - commit: - - - Because the system will likely assign different ports when binding - several times to different address families, it is recommended to - only use a single address family, otherwise other nodes will only - get one port among the several that were assigned, possibly breaking - communication. - - - AutoConnect won't work in this scenario, because it relies on the UDP - port being the same as the TCP port, which is not the case when using - system-assigned ports. - -commit ea12a0fb066793c316ccc9ef21444f092f74b4ba -Author: Etienne Dechamps -Date: Sat Jul 12 18:53:25 2014 +0100 - - Improve subprocess behavior in tinc start command. - - When invoking tincd, tinc start currently uses the execvp() function, - which doesn't behave well in a console as the console displays a new - prompt before the subprocess finishes (which makes me suspect the exit - value is not handled at all). This new code uses spawnvp() instead, - which seems like a better fit. - -commit b22499668a7aa63c619cb8fa8535282a38841ce9 -Author: Etienne Dechamps -Date: Sat Jul 12 18:37:56 2014 +0100 - - Fix "tinc start" on Windows when the path contains spaces. - - When invoking "tinc start" with spaces in the path, the following - happens: - - > "c:\Program Files (x86)\tinc\tinc.exe" start - c:\Program: unrecognized argument 'Files' - Try `c:\Program --help' for more information. - - This is caused by inconsistent handling of command line strings between - execvp() and the spawned process' CRT, as documented on MSDN: - http://msdn.microsoft.com/library/431x4c1w.aspx - -commit 14be1d30ec3727906907dad49d3bcb868c19d777 -Author: Etienne Dechamps -Date: Sat Jul 12 17:47:01 2014 +0100 - - Shutdown cleanly when receiving a Windows console shutdown request. - - This commit makes tinc exit cleanly on Windows when hitting CTRL+C at - the console or when the user logs off. This change has no effect when - running tinc as a service. - -commit b12f122f1be89b49d8a3e39fb1b10c6e4d3ada94 -Author: Etienne Dechamps -Date: Sat Jul 12 13:56:01 2014 +0100 - - Check if devops is valid before closing the device. - - This fixes a segfault that occurs on exit if tinc fails before the - device is initialized (for example, if it fails to read the private - key). - -commit 5ffdff685a0e7d25f7c016f3a6cd89bb82fed71c -Author: Guus Sliepen -Date: Sat Jul 12 14:35:29 2014 +0200 - - Fix unsafe use of strncpy() and sprintf(). - - The strncpy() problem was found by cppcheck. - -commit 31361075d36fd3f4a393eeb90b75ae2567992ef2 -Author: Guus Sliepen -Date: Sat Jul 12 14:34:39 2014 +0200 - - Fix a potential file descriptor leak. - - Found by cppcheck. - -commit b2a6381ab28dbae4bf976627afccbf6c2fcb0625 -Author: Etienne Dechamps -Date: Sat Jul 12 13:32:23 2014 +0100 - - Resolve KEY_EVENT conflict between Windows and ncurses. - - This fixes the following compiler warning when building for Windows: - - In file included from top.c:24:0: - /usr/local/mingw/ncurses/include/curses.h:1478:0: error: "KEY_EVENT" redefined [-Werror] - #define KEY_EVENT 0633 /* We were interrupted by an event */ - ^ - In file included from /usr/share/mingw-w64/include/windows.h:74:0, - from /usr/share/mingw-w64/include/winsock2.h:23, - from have.h:46, - from system.h:26, - from top.c:20: - /usr/share/mingw-w64/include/wincon.h:101:0: note: this is the location of the previous definition - #define KEY_EVENT 0x1 - ^ - -commit 5217c16db4babd64580c2fd7aa36180bb9bd838c -Author: Etienne Dechamps -Date: Sat Jul 12 13:27:05 2014 +0100 - - Remove unused device stats variables. - - This removes a bunch of variables that are never actually used anywhere. - - This fixes the following compiler warning when building for Windows: - - mingw/device.c:46:17: error: ‘device_total_in’ defined but not used [-Werror=unused-variable] - static uint64_t device_total_in = 0; - ^ - -commit 6e221a828f87a511aecee9d9263a1db0836701c4 -Author: Etienne Dechamps -Date: Sat Jul 12 12:57:11 2014 +0100 - - Remove unused variable in TAP-Win32 setup_device(). - - This fixes the following compiler warning when building for Windows: - - mingw/device.c: In function ‘setup_device’: - mingw/device.c:92:9: error: unused variable ‘thread’ [-Werror=unused-variable] - HANDLE thread; - ^ - -commit 2d2e94406c5f595eff67a01ee6bb1190f77c37ff -Author: Etienne Dechamps -Date: Sat Jul 12 12:54:45 2014 +0100 - - Fix callback signature for TAP-Win32 device_handle_read(). - - This fixes the following compiler warning when building for Windows: - - mingw/device.c: In function ‘setup_device’: - mingw/device.c:186:2: error: passing argument 2 of ‘io_add_event’ from incompatible pointer type [-Werror] - io_add_event(&device_read_io, device_handle_read, NULL, CreateEvent(NULL, TRUE, FALSE, NULL)); - ^ - In file included from mingw/../net.h:27:0, - from mingw/../subnet.h:24, - from mingw/../conf.h:34, - from mingw/device.c:26: - mingw/../event.h:61:13: note: expected ‘io_cb_t’ but argument is of type ‘void (*)(void *)’ - extern void io_add_event(io_t *io, io_cb_t cb, void* data, WSAEVENT event); - -commit f693cb7295298ecd6993a4feac1faf9129aa204d -Author: Etienne Dechamps -Date: Sat Jul 12 12:52:25 2014 +0100 - - Remove an unnecessary pointer dereference in execute_script(). - - This fixes the following compiler warning when building for Windows: - - script.c: In function ‘execute_script’: - script.c:52:5: error: value computed is not used [-Werror=unused-value] - *q++; - ^ - -commit d7f89a79448dd1633342ea5ee344d403c8e6890b -Author: Etienne Dechamps -Date: Sat Jul 12 12:49:59 2014 +0100 - - Only declare the origpriority variable if we support priority. - - This fixes the following compiler warning when building for Windows: - - net_packet.c: In function ‘send_udppacket’: - net_packet.c:633:6: error: unused variable ‘origpriority’ [-Werror=unused-variable] - int origpriority = origpkt->priority; - ^ - -commit 5aed916ef4fd75e6843f8fe739444dae91ea106a -Author: Guus Sliepen -Date: Sat Jul 12 14:24:16 2014 +0200 - - Reserve legacy active bit in connection_status_t. - - This is so the positions of the other bits don't change, making it easier to - debug problems with different versions of tinc. - - Also fix the padding so connection_status_t is exactly 32 bits. - -commit b23bf132838156d2fe5a18d50a2b5e068ae18ec3 -Author: Etienne Dechamps -Date: Sat Jul 12 11:57:03 2014 +0100 - - Remove redundant connection_t::status.active field. - - The only places where connection_t::status.active is modified is in - ack_h() and terminate_connection(). In both cases, connection_t::edge - is added and removed at the same time, and that's the only places - connection_t::edge is set. Therefore, the following is true at all - times: - - !c->status.active == !c->edge - - This commit removes the redundant state information by getting rid of - connection_t::status.active, and using connection_t::edge instead. - -commit 127f2f99f3d43e0565782750f26f1d3980c72711 -Author: Etienne Dechamps -Date: Sat Jul 12 11:13:04 2014 +0100 - - Don't initialize outpkt to an unused value. - - in receive_udppacket(), we initialize outpkt to a default value but the - value is never read anywhere, as every read is preceded by a write. - - This issue was found by the clang static analyzer tool: - http://clang-analyzer.llvm.org/ - -commit 77e96c07912c2a8b280d3e812c71fa1f12efb0ff -Author: Etienne Dechamps -Date: Sat Jul 12 11:06:36 2014 +0100 - - Handle the "no local address" case in send_sptps_data(). - - If choose_local_address() is unable to find a local address (e.g. - because of old nodes that don't send their local address information), - then send_sptps_data() ends up using uninitialized variables for the - socket and address. - - This regression was introduced in - 415910897122da0073a862784d148802ca390020. The commit took care of - handling that case in send_udppacket() but was missing the same fix - for send_sptps_data(). - - This bug was found by the clang static analyzer tool: - http://clang-analyzer.llvm.org/ - -commit 45a30f71572fab8e73c456737b7506b2cf12be25 -Author: Guus Sliepen -Date: Thu Jul 10 22:41:01 2014 +0200 - - Fix incorrect format qualifiers. - - Based on a patch from Etienne Dechamps. We avoid the use of %hhx, since even - though it is C99, not all compilers support it yet. We use %x instead, since - it's guaranteed that the minimum size of function arguments on the stack or in - registers is that of an int. - -commit d8ed5cf36d0c6d5a863497674248c8e8b63b9d98 -Author: Etienne Dechamps -Date: Thu Jul 10 20:29:12 2014 +0100 - - Fix a typo (FORTIFY_SOURCE). - -commit 2f4075f7da2c6ddf777c5bab93992a6c6ac5ec40 -Author: Baptiste Jonglez -Date: Sun Jul 6 20:55:26 2014 +0900 - - Fix typos in the manual page - -commit d8ea4c11dec5946c135ad2d2d05954473a0bfda9 -Author: Guus Sliepen -Date: Tue Jul 8 14:20:11 2014 +0200 - - Fix segmentation fault when dumping subnets. - -commit 23a22ea1ceb9d0a6b6c288142130f0e30c0fdec9 -Author: Guus Sliepen -Date: Tue Jul 8 14:20:01 2014 +0200 - - Fix compiler warnings. - -commit 163773d7107b7726bed24cb1c31b1cecc0d0c239 -Author: Etienne Dechamps -Date: Sun Jul 6 12:35:32 2014 +0100 - - Fix event loop io tree inconsistency on Windows. - - On Windows, the event loop io tree uses the Windows Event handle to - differentiate between io_t objects. Unfortunately, there is a bug in - the io_add_event() function (introduced in - 2f9a1d4ab5ff51b05a5e8cc41a1528fdeb36c723) as it sets the event after - inserting the object into the tree, resulting in objects appearing in - io_tree out of order. - - This can lead to crashes on Windows as the event loop is unable to - determine which events fired. - -commit fcf5b53e785fd191dd951b77ad831fe6ac78dce4 -Author: Etienne Dechamps -Date: Sun Jul 6 10:55:23 2014 +0100 - - Make sure myport is set correctly when running with Port = 0. - - Setting the Port configuration variable to zero can be used to make tinc - listen on a system-assigned port. Unfortunately, in this scenario myport - will be zero, which means that tinc won't transmit its actual UDP - listening port to other nodes. This breaks UDP hole punching and local - discovery. - -commit c786ed116805c0bc911f592c03dc0d5562287283 -Author: Etienne Dechamps -Date: Sat Jul 5 00:23:05 2014 +0100 - - Fix tinc event loop reentrancy from timeout handlers. - - Commit 611217c96ec684799882cf330f40a0936131b6b5 introduced a regression - because it accidentally reordered the timeout handler calls and the - fdset setup code. This means that any io_add(), io_del() or io_set() - calls in timeout handlers would be ignored in the current event loop - iteration, resulting in erratic behavior. - - The most visible symptom is when a metaconnection timeout occurs and the - connection is closed; the timeout handler closes the socket but it still - ends up in the select() call, typically resulting in the following - crash: - - Error while waiting for input: Bad file descriptor - -commit d0d01a44485ee04f60a8fccf9bdf8311e23ffa43 -Author: Etienne Dechamps -Date: Sat Jul 5 19:51:19 2014 +0100 - - Canonicalize IPv6 addresses as per RFC 5952 before printing them. - - Currently we don't do any shortening on IPv6 addresses (aside from - removing trailing zeroes) before printing them. This commit makes - textual addresses smaller by shortening them according to the rules - described in RFC 5952. This is also the canonical textual representation - for IPv6 addresses, thus making them easier to compare. - -commit dec0400714cc6b125f615c224ac37903f44addb9 -Author: Etienne Dechamps -Date: Sat Jul 5 19:02:02 2014 +0100 - - Don't print subnet prefix lengths and weights for one-host subnets. - - This commit suppresses subnet prefix length output (/xx) for subnets - that only contain one address (/32 for IPv4, /128 for IPv6). It also - suppresses weight information if the subnet is using the default - weight. This improves readability of net2str() output in the majority - of cases. - -commit dc55691ca7399bab28963f92e4c3dea9d6bf8eb1 -Author: Etienne Dechamps -Date: Sat Jul 5 18:52:03 2014 +0100 - - When printing MAC addresses, always use trailing zeroes. - - tinc currently prints MAC addresses without trailing zeroes, for example: - - 1:2:3:4:5:6 - - This looks weird and is inconsistent with how MAC addresses are - displayed everywhere else. This commit adds trailing zeroes, so the - above address will be printed as the following: - - 01:02:03:04:05:06 - -commit 3d730a40a42d9b238da8725438a612296dea3860 -Author: Etienne Dechamps -Date: Sat Jul 5 18:05:55 2014 +0100 - - Rewrite, fix and improve str2net(). - - This is a complete rewrite of the str2net() function. Besides - refactoring duplicate code, this new code brings the following fixes - and improvements: - - - Fixes handling of leading/trailing double colon in IPv6 addresses. - For example, with the previous code the address - 2001:0db8:85a3:0000:0000:8a2e:0370:: is interpreted as a MAC address, - and ::0db8:85a3:0000:0000:8a2e:0370:7334 is rejected. - - - Catches more invalid cases, such as garbage at the end of the string. - - - Adds support for dotted quad notation in IPv6 (e.g. ::1.2.3.4). - - See RFC 4291, section 2.2 for details on the textual format of IPv6 - addresses. - -commit e024b7a2c50e23311834e6d180e5acc72783b339 -Author: Etienne Dechamps -Date: Sun Jun 29 15:22:10 2014 +0100 - - Use git description as the tinc version. - - Instead of using a hardcoded version number in configure.ac, this makes - tinc use the live version reported by "git describe", queried on-the-fly - during the build process and regenerated for every build. - - This provides several advantages: - - Less redundancy: git is now the source of truth for version - information, no need to store it in the repository itself. - - Simpler release process: just creating a git tag automatically - updates the version. No need to change files. - - More useful version information: tinc will now display the number of - commits since the last tag as well as the commit the binary is built - from, following the format described in git-describe(1). - - Here's an example of tincd --version output: - - tinc version release-1.1pre10-48-gc149315 (built Jun 29 2014 15:21:10, protocol 17.3) - - When building directly from a release tag, this would like the following: - - tinc version release-1.1pre10 (built Jun 29 2014 15:21:10, protocol 17.3) - - (Note that the format is slightly different - because of the way the - tags are named, it says "release-1.1pre10" instead of just "1.1pre10") - -commit aec82bb1c94af6d3142cdef0c51f42f38e9be3e0 -Author: Etienne Dechamps -Date: Sun Jun 29 14:57:42 2014 +0100 - - Regenerate build date and time every time tinc is built. - - This prevents the date and time shown in version information from - getting stale because of partial builds. With these changes, date and - time information is written to a dedicated object file that gets rebuilt - every time make is run, even if there are no changes. - -commit 116f2ed27a74982e4d1a19b7a8fd08b0aaee1f8d -Author: Etienne Dechamps -Date: Sun Jun 29 14:15:58 2014 +0100 - - Make IPv4 multicast space 224.0.0.0/4 broadcast by default. - - We already do this for IPv6 multicast space (ff00::/8), so why not - extend it to IPv4. - -commit 46a5aa0d674914f4220d8583b1b2f87c7f05a804 -Author: Etienne Dechamps -Date: Sun Jun 29 13:18:25 2014 +0100 - - Make broadcast addresses configurable. - - This adds a new option, BroadcastSubnet, that allows the user to - declare broadcast subnets, i.e. subnets which are considered broadcast - addresses by the tinc routing layer. Previously only the global IPv4 - and IPv6 broadcast addresses were supported by virtue of being - hardcoded. - - This is useful when using tinc in router mode with Ethernet virtual - devices, as it can be used to provide broadcast support for a local - broadcast address (e.g. 10.42.255.255) instead of just the global - address (255.255.255.255). - - This is implemented by removing hardcoded broadcast addresses and - introducing "broadcast subnets", which are subnets with a NULL owner. - By default, behavior is unchanged; this is accomplished by adding - the global broadcast addresses for Ethernet, IPv4 and IPv6 at start - time. - -commit b54fde67474e7201e94fa4be34dae65d295b2936 -Author: Etienne Dechamps -Date: Sun Jun 29 09:57:11 2014 +0100 - - Implement sptps_verify_datagram(). - - Implementation of sptps_verify_datagram() was left as a TODO. This - causes problems when using SPTPS in tinc, because this function is - used in try_mac(), which itself is used in try_harder() to locate - nodes sending UDP packets from unexpected addresses. In the current - state this function always returns true, resulting in UDP addresses - of random nodes getting changed which makes UDP communication - fragile and unreliable. In addition, this makes UDP communication - impossible through port translation and local discovery. - - This commit adds the missing implementation, thus fixing the issue. - -commit 498f1b1d5835ab1ac21886cdf0d1471ac90f75b2 -Author: Etienne Dechamps -Date: Sun Jun 29 11:06:44 2014 +0100 - - Enable LocalDiscovery by default. - - Recent improvements to the local discovery mechanism makes it cheaper, - more network-friendly, and now it cannot make things worse (as opposed - to the old mechanism). Thus there is no reason not to enable it by - default. - -commit 415910897122da0073a862784d148802ca390020 -Author: Etienne Dechamps -Date: Sun Jun 29 11:01:24 2014 +0100 - - Remove broadcast-based local discovery mechanism. - - The new local address based local discovery mechanism is technically - superior to the old broadcast-based one. In fact, the old algorithm - can technically make things worse by e.g. sending broadcasts over the - VPN itself and then selecting the VPN address as the node's UDP - address. This cannot happen with the new mechanism. - - Note that this means old nodes that don't send their local addresses in - ADD_EDGE messages can't be discovered, because there is no address to - send discovery packets to. Old nodes can still discover new nodes by - sending them broadcasts, though. - -commit e16ade874d08f82481dca7302b98305bcfbe27cf -Author: Etienne Dechamps -Date: Sun Jun 22 17:27:55 2014 +0100 - - Use edge local addresses for local discovery. - - This introduces a new way of doing local discovery: when tinc has - local address information for the recipient node, it will send local - discovery packets directly to the local address of that node, instead - of using broadcast packets. - - This new way of doing local discovery provides numerous advantages compared to - using broadcasts: - - - No broadcast packets "polluting" the local network; - - - Reliable even if the sending host has multiple network interfaces (in - contrast, broadcasts will only be sent through one unpredictable - interface) - - - Works even if the two hosts are not on the same broadcast domain. One - example is a large LAN where the two hosts might be on different local - subnets. In fact, thanks to UDP hole punching this might even work if - there is a NAT sitting in the middle of the LAN between the two nodes! - - - Sometimes a node is reachable through its "normal" address, and via a - local subnet as well. One might think the local subnet is the best route - to the node in this case, but more often than not it's actually worse - - one example is where the local segment is a third party VPN running in - parallel, or ironically it can be the local segment formed by the tinc - VPN itself! Because this new algorithm only checks the addresses for - which an edge is already established, it is less likely to fall into - these traps. - -commit bfce56d473e1e01a8af0260262ca84f09154e71f -Author: Etienne Dechamps -Date: Sun Jun 22 16:29:30 2014 +0100 - - Add local address information to edges. - - In addition to the remote address, each edge now stores the local address from - the point of view of the "from" node. This information is then made available - to other nodes through a backwards-compatible extension to ADD_EDGE messages. - - This information can be used in future code to improve packet routing. - -commit 762db91ef7d3b2eab00c23250ca61c7f814899c7 -Author: Guus Sliepen -Date: Sat Jun 28 21:54:34 2014 +0200 - - Give getsockopt() a reference to a socklen_t. - -commit e57daac63b6f703af8e7c8209ef61a4d3b2180c3 -Merge: cc284e7c 313a752c -Author: Guus Sliepen -Date: Sat Jun 28 21:49:55 2014 +0200 - - Merge branch 'winevents-clean' of https://github.com/dechamps/tinc into 1.1 - -commit 313a752cb5fbf27450d34c15b0085d2d8a4147af -Author: Etienne Dechamps -Date: Sat Jun 28 18:39:00 2014 +0100 - - Remove the TAP-Win32 reader thread. - - tinc is using a separate thread to read from the TAP device on Windows. - The rationale was that the notification mechanism for packets arriving - on the virtual network device is based on Win32 events, and the event - loop did not support listening to these events. - - Thanks to recent improvements, this event loop limitation has been - lifted. Therefore we can get rid of the separate thread and simply add - the Win32 "incoming packet" event to the event loop, just like a socket. - The result is cleaner code that's easier to reason about. - -commit ffbc99558cae4dff876645fe205349d8c4cd7acb -Author: Etienne Dechamps -Date: Sat Jun 28 15:19:11 2014 +0100 - - Use a Windows event to stop tinc when running as a service. - - Currently, when the tinc service handler callback (which runs in a - separate thread) receives a service shutdown request, it calls - event_exit() to request the event loop to exit. - - This approach has a few issues: - - - The event loop will only notice the exit request when the next event - fires. This slows down tinc service shutdown. In some extreme cases - (DeviceStandby enabled, long PingTimeout and no connections), - shutdown can take ages. - - - Strictly speaking, because of the absence of memory barriers, there - is no guarantee that the event loop will even notice an exit request - coming from another thread. I suppose marking the "running" variable - as "volatile" is supposed to alleviate that, but it's unclear whether - that provides any guarantees with modern systems and compilers. - - This commit fixes the issue by leveraging the new event loop Windows - interface, using a custom Windows event that is manually set when - shutdown is requested. - -commit 2f9a1d4ab5ff51b05a5e8cc41a1528fdeb36c723 -Author: Etienne Dechamps -Date: Sat Jun 28 15:15:41 2014 +0100 - - Make the event loop expose a Windows event interface. - - This allows event loop users to specify Win32 events to wait on, - thus making the event loop more flexible. - -commit 611217c96ec684799882cf330f40a0936131b6b5 -Author: Etienne Dechamps -Date: Fri Jun 27 21:58:35 2014 +0100 - - Use native Windows events for the event loop. - - This commit changes the event loop to use WSAEventSelect() and - WSAWaitForMultipleEvents() on Windows. This paves the way for making the - event loop more flexible on Windows by introducing the required - infrastructure to make the event loop wait on any Win32 event. - - This commit only affects the internal implementation of the event - module. Externally visible behavior remains strictly unchanged (for - now). - -commit cc284e7c5d298ca887c07f918da35e376bf98720 -Author: Etienne Dechamps -Date: Sat Jun 28 11:13:29 2014 +0100 - - Fix connection event error handling. - - Commit 86a99c6b999671ed444711139db1937617e802a0 changed the way we - handle connection events to protect against spurious event loop - callbacks. Unfortunately, it turns out that calling connect() twice on - the same socket results in different behaviors depending on the platform - (even though it seems well defined in POSIX). On Windows this resulted - in the connection handling code being unable to react to connection - errors (such as connection refused), always hitting the timeout; on - Linux this resulted in spurious error messages about connect() returning - success. - - In POSIX and on Linux, using connect() on a socket where the previous - attempt failed will attempt to connect again, resulting in unnecessary - network activity. Using getsockopt(SO_ERROR) before connect() solves - that, but introduces a race condition if a connection failure happens - between the two calls. - - For this reason, this commit switches from connect() to a zero-sized - send() call, which is more consistent (though not completely, see the - truth table in the comments) and simpler to use for that purpose. Note - that Windows explictly support empty send() calls; POSIX says nothing - on the subject, but testing shows it works at least on Linux. - - (Surprisingly enough, Windows seems more POSIX-compliant than Linux on - this one!) - -commit 86a99c6b999671ed444711139db1937617e802a0 -Author: Etienne Dechamps -Date: Fri Jun 27 19:33:31 2014 +0100 - - Protect against spurious connection events. - - The event loop does not guarantee that spurious write I/O events do not - happen; in fact, they are guaranteed to happen on Windows when - event_flush_output() is called. Because handle_meta_io() does not check - for spurious events, a metaconnection socket might appear connected even - though it's not, and will fail immediately when sending the ID request. - - This commit fixes this issue by making handle_meta_io() check the - connection status before assuming the socket is connected. It seems that - the only reliable way to do that is to try to call connect() again and - look at the error code, which will be EISCONN if the socket is - connected, or EALREADY if it's not. - -commit 0c026f3c6dec784c3267ad7e2c4709d5393dc292 -Author: Etienne Dechamps -Date: Thu Jun 26 20:42:40 2014 +0100 - - Fix errno references when handling socket errors. - - When using socket functions, "sockerrno" is supposed to be used to - retrieve the error code as opposed to "errno", so that it is translated - to the correct call on Windows (WSAGetLastError() - Windows does not - update errno on socket errors). Unfortunately, the use of sockerrno is - inconsistent throughout the tinc codebase, as errno is often used - incorrectly on socket-related calls. - - This commit fixes these oversights, which improves socket error - handling on Windows. - -commit 058473dc8d4cf60f79aee18d473342b8a3c25fbe -Author: Etienne Dechamps -Date: Sun Jun 22 18:45:49 2014 +0100 - - Fix Windows includes. - - These Windows include lines are capitalized, which causes the build to fail - when cross-compiling from Linux to Windows using MinGW as the MinGW headers - are entirely lower case. - -commit b24faf3cbe07dd931911ec4d70f1a9e0d6a87519 -Author: Guus Sliepen -Date: Sun May 11 17:11:02 2014 +0200 - - Remove the warnings when IP_DONTFRAGMENT/IPV6-DONTFRAG is not supported. - - There is nothing we can do about it, and tinc will run fine anyway. - -commit b99e1a306c7fb8f43dd61e432f3c896f5142e4ac -Author: Alexis Hildebrandt -Date: Sun Jun 22 16:43:15 2014 +0200 - - Add support to link against libresolv Mac OS X - -commit e76df30cb2af7a22e9c1dc91bb47a76c2fcbc43d -Author: Armin Fisslthaler -Date: Fri Apr 25 14:44:06 2014 +0200 - - reload /etc/resolv.conf in SIGALRM handler - -commit 132bdb77a0792d85d03ad89f846cbd4024037393 -Author: Etienne Dechamps -Date: Sun Jun 22 10:48:34 2014 +0100 - - Make DeviceStandby control network interface link status on Windows. - - Besides controlling when tinc-up and tinc-down get called, this commit makes - DeviceStandby control when the virtual network interface "cable" is "plugged" - on Windows. This is more user-friendly as the status of the tinc network can - be seen just by looking at the state of the network interface, and it makes - Windows behave better when isolated. - -commit bd451cfe1512fa69eac35a60dbe6df17bfc39154 -Author: Etienne Dechamps -Date: Sun Jun 22 10:48:34 2014 +0100 - - Add DeviceStandby option to only enable the device when nodes are reachable. - - This adds a new DeviceStandby option; when it is disabled (the default), - behavior is unchanged. If it is enabled, tinc-up will not be called during - tinc initialization, but will instead be deferred until the first node is - reachable, and it will be closed as soon as no nodes are reachable. - - This is useful because it means the device won't be set up until we are fairly - sure there is something listening on the other side. This is more user-friendly, - as one can check on the status of the tinc network connection just by checking - the status of the network interface. Besides, it prevents the OS from thinking - it is connected to some network when it is in fact completely isolated. - -commit f0885b8d2fe69610e7e294735795d98db11157a5 -Author: Etienne Dechamps -Date: Sun Jun 22 14:06:44 2014 +0100 - - Cleanly remove the device FD from the event loop before closing it. - -commit ed1d0878afe53032a4b63e87afd4a435015cf5de -Author: Etienne Dechamps -Date: Sun Jun 22 09:53:26 2014 +0100 - - Make device close cleaner. - -commit 638260865399693c3ced9337ef2664c5ba968a2a -Author: Etienne Dechamps -Date: Sun Jun 22 09:54:45 2014 +0100 - - Move Solaris if_fd to local scope. - - This variable is never used outside of setup_device(), therefore there is no - reason to declare it in global scope. - -commit 9bfc228ef5fcd4166897e32fbe82f4cc4e252922 -Author: Baptiste Jonglez -Date: Fri Jun 20 15:56:13 2014 +0900 - - Clarify man page regarding the IndirectData option - -commit 31c68993989fbca3c88df1449ea2077baafce481 -Author: Guus Sliepen -Date: Sun Jun 15 12:19:10 2014 +0200 - - Unconditionally return non-zero exit code when "tinc del" does not find the requested variable. - -commit 1ce0f7613964c7441ef683f9d875dd09cbfd667c -Author: Guus Sliepen -Date: Sun Jun 15 12:14:01 2014 +0200 - - Return non-zero exit code when "tinc get" does not find the requested variable. - -commit ef5e8b6920d1dd3097f36bd0c50170100acf2f28 -Author: Guus Sliepen -Date: Tue Jun 3 11:02:58 2014 +0200 - - Fix base64 decoding of Ed25519 keys. - -commit b0d80c7f28528c2c8857c5662b4aca779b3184bb -Author: Guus Sliepen -Date: Sun May 18 21:51:42 2014 +0200 - - Allow Cipher and Digest "none". - - This is for backwards compatibility with tinc 1.0, it has no effect on - the SPTPS protocol. - -commit 666718998eaa044f6f25fe99810a78dca8471393 -Author: Guus Sliepen -Date: Sun May 18 20:49:35 2014 +0200 - - Implement a PEM-like format for Ed25519 keys. - - We don't require compatibility with any other software, but we do want Ed25519 keys to work - the same as RSA keys for now. - -commit f0e7e6b03e34e69cac5b01a2d943ad3b9b59d36c -Author: Guus Sliepen -Date: Sun May 18 20:47:04 2014 +0200 - - Rename ECDSA to Ed25519. - -commit 35437a50e2a46861742b6fb8e49d065aa52a04dc -Author: Guus Sliepen -Date: Tue May 13 20:29:09 2014 +0200 - - Add sanity checks when generating new RSA keys. - - The key size should be a multiple of 8 bits, and it should be between 1024 and - 8192 bits. - -commit 66f325f4674e70d83744626f3b8dda6760f8d613 -Author: Guus Sliepen -Date: Mon May 12 15:57:40 2014 +0200 - - Fix PMTU discovery via datagram SPTPS. - - In send_sptps_data(), the len variable contains the length of the whole - datagram that needs to be sent to the peer, including the overhead from SPTPS - itself. - -commit c35bfa18ec49439d4a028990fcf0ae6d8c4508a5 -Author: Guus Sliepen -Date: Mon May 12 15:56:29 2014 +0200 - - Fix a crash when we have a malformed public ECDSA key of another node. - -commit c32fcdfc1dde289c52bc359b7b6c5f8c30186e58 -Author: Guus Sliepen -Date: Mon May 12 14:35:56 2014 +0200 - - Add missing closedir(). - -commit 75e5b2e906bd8563bf0f53a76065618c88122e1c -Author: Guus Sliepen -Date: Mon May 12 14:35:12 2014 +0200 - - Use void pointers to opaque buffers. - -commit 332b55d4720fadea76c0a5d9b9d484af6a724006 -Author: Guus Sliepen -Date: Tue May 6 14:11:55 2014 +0200 - - Change AutoConnect from int to bool. - - The proper value is 3, not 2 or 4, and 5 is right out. So just hardcode this value, - and only have the option to turn AutoConnect on or off. - -commit 27acb5d04792f2da70e937543de9110e16aae21c -Author: Guus Sliepen -Date: Tue May 6 13:01:48 2014 +0200 - - Fix compiler warnings. - -commit bc33a073d82cd4b5e75d00e379ddfeeaa6ade962 -Author: Guus Sliepen -Date: Tue May 6 12:58:25 2014 +0200 - - Nexthop calculation should always use the shortest path. - - When tinc runs the graph algorithms and updates the nexthop and via pointers, - it uses a breadth-first search, but it can sometimes revisit nodes that have - already been visited if the previous path is marked as being indirect, and - there is a longer path that is "direct". The via pointer should be updated in - this case, because this points to the closest hop to the destination that can - be reached directly. However, the nexthop pointer should not be updated. - - This fixes a bug where there could potentially be a routing loop if a node in - the graph has an edge with the indirect flag set, and some other edge without - that flag, the indirect edge is part of the minimum spanning tree, and a - broadcast packet is being sent. - -commit b6e2b416bf9a5788c8847267b849efcd9e5bbf95 -Author: Saverio Proto -Date: Mon May 5 15:23:25 2014 +0200 - - Fix typo in comment - -commit 18698c4e123d1ed22f3a2fc5529fac62fbabaf19 -Author: Guus Sliepen -Date: Fri Apr 25 17:00:55 2014 +0200 - - Put brackets around IPv6 addresses in invitation URL, even if there is no port number. - -commit 475088ed77df925ce0680c9993305cd746742708 -Author: Guus Sliepen -Date: Tue Apr 15 17:26:08 2014 +0200 - - sptps_test: allow using a tun device instead of stdio. - -commit 2980173ee7f8142598fe5e1ab117e463751da310 -Author: Guus Sliepen -Date: Mon Apr 14 21:43:45 2014 +0200 - - Use the ChaCha-Poly1305 cipher for the SPTPS protocol. - - The main reason to switch from AES-256-GCM to ChaCha-Poly1305 is to remove a - dependency on OpenSSL, whose behaviour of the AES-256-GCM decryption function - changes between versions. The source code for ChaCha-Pol1305 is small and in - the public domain, and can therefore be easily included in tinc itself. - Moreover, it is very fast even without using any optimized assembler, easily - outperforming AES-256-GCM on platforms that don't have special AES instructions - in hardware. - -commit 49e3baec20ddad9cc297c3eeb1d13f0e421f69c8 -Merge: 37b729d7 2f01744f -Author: Guus Sliepen -Date: Mon Apr 14 20:49:43 2014 +0200 - - Merge branch '1.1-ed25519' into 1.1 - -commit 37b729d7fdd49da5466696f7995a96ebb54fbcbb -Author: Guus Sliepen -Date: Sun Apr 13 12:09:48 2014 +0200 - - Properly initialize buffers. - - Valgrind complained about use of uninitialized data. - -commit 2f01744f82be542894fe2ceecbfb9ead93c9ffa5 -Author: Guus Sliepen -Date: Sun Apr 6 22:47:26 2014 +0200 - - Use Ed25519 keys. - - This uses the portable Ed25519 library made by Orson Peters, which in turn uses - the reference implementation made by Daniel J. Bernstein. - - This implementation also allows Ed25519 keys to be used for key exchange, so - there is no need to add a separate implementation of Curve25519. - -commit d6734a2da483675f5bcc9cf7b15723a409b1019f -Author: Guus Sliepen -Date: Sun Apr 6 22:46:06 2014 +0200 - - Fix return value of b64encode(). - -commit f134bd0c9c2213fbbb3967f3d784759cb65e2c76 -Author: Guus Sliepen -Date: Sun Mar 9 15:32:10 2014 +0100 - - Handle a disconnecting tincd better. - - - Try to prevent SIGPIPE from being sent for errors sending to the control - socket. We don't outright block the SIGPIPE signal because we still want the - tinc CLI to exit when its output is actually sent to a real (broken) pipe. - - - Don't call exit() from top(), and properly detect when the control socket is - closed by the tincd. - -commit 09e000ba54fd4a4ffe3e5c15ee7aeadac35d6996 -Author: Guus Sliepen -Date: Wed Feb 26 17:27:57 2014 +0100 - - Rewind the file before trying to use PEM_read_RSA_PUBKEY(). - -commit 44c7f554c7a6eb411428cfd30ca2cb21a613830e -Author: Guus Sliepen -Date: Wed Feb 26 11:00:30 2014 +0100 - - Add "network" command to list or switch networks. - -commit 48ecff6ddb7e6f9d6b6df7f8952c4cfb318572fa -Author: Guus Sliepen -Date: Fri Feb 7 23:06:26 2014 +0100 - - Add missing attribution for 1.1pre10 to the NEWS file. - -commit 9f7e2dffb27297385c56698638386b264c9aff1a -Author: Guus Sliepen -Date: Fri Feb 7 23:05:33 2014 +0100 - - Really fix compiling under Windows. - -commit 173072ff078a8917b60c24dbe58aa7c258450de2 -Author: Guus Sliepen -Date: Fri Feb 7 21:40:42 2014 +0100 - - Releasing 1.1pre10. - -commit cb5c1b5986861361207fa244662bb2c7f3d6a3a4 -Author: Guus Sliepen -Date: Fri Feb 7 21:40:29 2014 +0100 - - Check whether OpenSSL has support for GCM. - -commit cdda0388a82eb44ff260e25c0902794c8db9643a -Author: Guus Sliepen -Date: Fri Feb 7 21:14:41 2014 +0100 - - Fix compiling for Windows. - -commit 06a4a8c153407b690a3ce3f0e7fdaa8568ccb1a3 -Author: Guus Sliepen -Date: Fri Feb 7 20:38:48 2014 +0100 - - Update copyright notices. - -commit bc9347042bf6586d23bf17efd9fdf64a2c4a4d27 -Author: Guus Sliepen -Date: Fri Feb 7 19:57:06 2014 +0100 - - Attribution for Dennis Joachimsthaler. - -commit ac7f82cb235008d1711781a87ffdce5d45465134 -Author: Guus Sliepen -Date: Fri Feb 7 16:34:08 2014 +0100 - - Handle errors from TAP-Win32/64 adapter in a better way. - - Before, the tapreader thread would just exit immediately after encountering the - first error, without notifying the main thread. Now, the tapreader thead never - exits itself, but tells the main thread to stop when more than ten errors are - encountered in a row. - -commit 2f41780023bffc81fa42b0e72f67be86a52b370c -Author: Guus Sliepen -Date: Fri Feb 7 19:48:11 2014 +0100 - - Attribution for various contributors. - - Conflicts: - THANKS - -commit e717e424c22233aa728b75c4c8bb047e13b0107a -Author: Guus Sliepen -Date: Thu Jan 30 17:10:30 2014 +0100 - - Use addresses learned from other nodes when making outgoing connections. - - Before, when making a meta-connection to a node (either because of a ConnectTo - or because AutoConnect is set), tinc required one or more Address statements - in the corresponding host config file. However, tinc learns addresses from - other nodes that it uses for UDP connections. We can use those just as well for - TCP connections. - -commit 995444c4f96bafecf7fb5d59510b3034459cf85c -Author: Guus Sliepen -Date: Wed Jan 29 17:32:18 2014 +0100 - - Document Weight and also allow it to be set from tinc.conf. - -commit 2e318f379992a730f592b4c5261d26d8e1a38cfd -Author: Guus Sliepen -Date: Wed Jan 29 17:17:59 2014 +0100 - - Don't ask questions if we are not running interactively. - - When creating invitations or using them to join a VPN, and the tinc command is - not run interactively (ie, when stdin and stdout are not connected or - redirected to/from a file), don't ask questions. If normally tinc would ask for - a confirmation, just assume the default answer instead. If tinc really needs - some input, just print an error message instead. - - In case an invitation is used for a VPN which uses a netname that is already in - use on the local host, tinc will store the configuration in a temporary - directory. Normally it asks for an alternative netname and then renames the - temporary directory, but when not run interactively, it now just prints the - location of the unchanged temporary directory. - -commit 00398a60ec317740bcec83c5a524c5a95ce7f1c2 -Author: Guus Sliepen -Date: Mon Jan 27 23:21:25 2014 +0100 - - Add missing newlines when copying variables from tinc.conf to an invitation file. - -commit fa1e9b046128db81c207c9ed920d068a144cd687 -Author: Guus Sliepen -Date: Fri Jan 24 16:09:32 2014 +0100 - - Test two tinc daemons using network namespaces. - - Testing multiple daemons connecting to each other on the same computer is - usually difficult, because connections to local IP addresses will bypass most - of the network stack. However, recent versions of Linux support network - namespaces, which can isolate network interfaces. We use this to isolate the - virtual interface of the daemons from each other, so we get the behaviour as if - the daemons were each running on their own machine. This can also be used for - more complicated tests (including those with firewall rules) without disturbing - the real network setup of the host computer. - -commit 38adc8bf548c2c465d5f4147866c3d3f9112d3a8 -Author: Guus Sliepen -Date: Mon Jan 20 21:19:13 2014 +0100 - - Add the ListenAddress option. - - ListenAddress works the same as BindToAddress, except that from now on, - explicitly binding outgoing packets to the address of a socket is only done for - sockets specified with BindToAddress. - -commit e187758a7e163cb2d2e57db8b093823f68f1491f -Author: Guus Sliepen -Date: Mon Jan 20 20:21:15 2014 +0100 - - Document that 1.1 uses AES-256 in GCM mode. - -commit 1a115d1d1c58db179df6568e9b33fab3e8f80486 -Author: Guus Sliepen -Date: Mon Jan 20 20:16:58 2014 +0100 - - Document clearly that tinc depends on curses and readline libraries. - -commit a3decd09513370fbb3aa22dae11435103d179c30 -Author: Guus Sliepen -Date: Sun Jan 19 21:15:23 2014 +0100 - - Let tinc-gui use correct address family when connecting to tincd via TCP. - -commit c10f3105b354c523d4d4d36b09dd46f890e94a30 -Author: Dennis Joachimsthaler -Date: Fri Jan 17 18:15:40 2014 +0100 - - Ensure tinc-gui running in 64 bits mode can find tinc's 32 bit registry key. - -commit ab583f7e8c550822c63a1a6b73a7a329f622d9e0 -Author: Dennis Joachimsthaler -Date: Fri Jan 17 16:10:10 2014 +0100 - - Fix tinc-gui on Windows. - -commit 11d562e9b2b3ce483b04bb8c8cadb22a0beb1ab6 -Author: Guus Sliepen -Date: Thu Jan 16 14:52:44 2014 +0100 - - Add index entries for the CLI commands. - -commit d8ea66ff1fc68ca9ea672727b0274663df6f4866 -Author: Guus Sliepen -Date: Thu Jan 16 14:46:44 2014 +0100 - - Update the documentation of the tinc command. - -commit 8af6d64fd9dfdd684a56534249e12d201628055c -Author: Guus Sliepen -Date: Thu Jan 16 14:02:56 2014 +0100 - - Clarify StrictSubnets. - -commit c8543bbe6b9ae2de318b0ed4f54cdebcbc3fe5a4 -Author: Florent Clairambault -Date: Sun Dec 29 23:11:54 2013 +0100 - - Adding "conf.d" configuration dir support. - - Any file matching the pattern /etc/tinc/$NETNAME/conf.d/*.conf will be - parsed after the tinc.conf file. - -commit e6b32936c569d9f2ceaea76af2f8f0551d163dd9 -Author: Guus Sliepen -Date: Tue Dec 10 17:13:15 2013 +0100 - - Fix handling of --with-libgcrypt. - -commit b7d59f035bfa2e546428cac2b72318d4f5c517fb -Author: Guus Sliepen -Date: Tue Dec 10 17:02:52 2013 +0100 - - Don't enable -fstack-protector-all. - - It is not supported on all architectures and is problematic on some - platforms. - -commit 53b00f8c1abda0d477c75e4d70a7341301fa1733 -Author: Guus Sliepen -Date: Tue Dec 10 11:18:04 2013 +0100 - - Add our own autoconf check for libgcrypt. - - This one doesn't require one to have libgcrypt installed while running - autoreconf, making life easier for people who compile tinc from git. - -commit 283c5d1cf07f77d29fc1fc2f09532508f5124679 -Author: Guus Sliepen -Date: Tue Dec 10 10:48:00 2013 +0100 - - Enable compiler hardening flags by default. - - Check whether the compiler supports hardening flags and enable them unless - --disable-hardening is specified. - - Conflicts: - configure.ac - -commit ef8efdfff1de2b18092f9d4f383e3f2898bf86cd -Author: Guus Sliepen -Date: Sun Dec 8 21:37:56 2013 +0100 - - Remove erroneous warning about SPTPS being disabled. - -commit be1446f5d0e8831b60ea473a5b7b9ba40f18986e -Author: Guus Sliepen -Date: Sun Dec 8 21:32:21 2013 +0100 - - Don't print an error when no ECDSA key is known for a node using the legacy protocol. - -commit c151cfa2e978e92c1e5394bfcc8b41c6155f8436 -Author: Guus Sliepen -Date: Sun Dec 8 21:31:50 2013 +0100 - - Give full path to unconfigured tinc-up script. - -commit 1b580b2a6beee9d32488a1d95c45de336dee9c2e -Author: Guus Sliepen -Date: Sun Dec 8 21:06:03 2013 +0100 - - Allow running without ECDSA keys If ExperimentalProtocol is not explicitly set. - - To make upgrading less painful, allow running tinc 1.1 without ECDSA keys - unless ExperimentalProtocol is explicitly set to yes. - -commit 41583d5dcfc1277b1a203478de4cce2cd0cda1b1 -Author: Guus Sliepen -Date: Sun Dec 8 20:23:44 2013 +0100 - - Don't print device statistics when exiting tinc. - - Much more detailed statistics are now kept per node, which can be queried at - any time, which makes the device statistics obsolete. - -commit 19b97e79aa63bcb6f81c2dbfd7ca91d89a230387 -Author: Guus Sliepen -Date: Sat Dec 7 22:59:37 2013 +0100 - - Prefer ncurses over curses. - -commit b115de21990ecb1a2f377a73d07ff26e35980aba -Author: Guus Sliepen -Date: Sat Dec 7 22:54:02 2013 +0100 - - Use hardcoded value for TUNNEWPPA if net/if_tun.h is missing on Solaris. - -commit cf9bea4e938f4eec531782e2e947d711cac16014 -Author: Guus Sliepen -Date: Sat Dec 7 22:39:24 2013 +0100 - - Avoid using a variable named "sun". Solaris doesn't like it. - -commit 221f559bcf13febc9a4135c5eb54c236c543ee19 -Author: Guus Sliepen -Date: Sat Dec 7 22:20:10 2013 +0100 - - Stricter check for raw socket support. - -commit c1f7357e7dca18f43f02541cff2684f737512686 -Author: Guus Sliepen -Date: Sat Dec 7 22:19:39 2013 +0100 - - Include for PATH_MAX. - -commit c9bdac68e1b56d34b8fd8bff03bddda1d2cca516 -Author: Guus Sliepen -Date: Sat Dec 7 21:52:41 2013 +0100 - - Update support for Solaris. - - Adds support for the latest TAP driver from - http://www.whiteboard.ne.jp/~admin2/tuntap/, so tinc now also works in switch - mode on Solaris 11. - -commit 06943e828c45d8f4f1da6dc51907499f92957a39 -Author: Guus Sliepen -Date: Thu Dec 5 15:01:30 2013 +0100 - - If no Port is specified, set myport to actual port of first listening socket. - - If the Port statement is not used, there are two other ways to let tinc listen - on a non-default port: either by specifying one or more BindToAddress - statements including port numbers, or by starting it from systemd with socket - activation. Tinc announces its own port to other nodes, but before it only - announced what was set using the Port statement. - -commit 3e924045ccaab1441b77ff43a2d7eb759b313f7b -Author: Guus Sliepen -Date: Thu Dec 5 14:30:00 2013 +0100 - - Mention in the manual that multiple Address staments are allowed. - -commit 51bddfd4dd95161afae2cac4aa5d31970fef5714 -Author: Guus Sliepen -Date: Thu Nov 28 14:19:55 2013 +0100 - - Allow "none" for Cipher and Digest again. - -commit 3d41e7d71247998b7c4a3dd4eacb93bd3529428d -Author: Guus Sliepen -Date: Thu Nov 21 22:13:14 2013 +0100 - - Make LocalDiscovery work for SPTPS packets. - -commit c1703ea9172be05f501d636510834e31d5d4f98c -Author: Guus Sliepen -Date: Wed Nov 20 23:02:20 2013 +0100 - - Remove an unused variable. - -commit 6168a9b6d51b19378af9ba9977227042cf6eafc6 -Author: Guus Sliepen -Date: Fri Nov 15 15:32:53 2013 +0100 - - Fix two warnings from Clang's static analyzer. - -commit 29b42aa17ede17bc67963292e86b186cc09039b1 -Author: Guus Sliepen -Date: Tue Oct 22 21:28:44 2013 +0200 - - Fix sending bulk data starting with a newline. - -commit a5bcb29fdffe9bb2a9dd59c2e315f13fda6d5b34 -Author: Guus Sliepen -Date: Tue Oct 22 21:19:41 2013 +0200 - - Make sptps_test less verbose by default. - -commit 7da999f4aee4e9c8b192769fddbe1c61cd31d7d0 -Author: Guus Sliepen -Date: Fri Oct 18 16:58:47 2013 +0200 - - Clean up child processes from proxy type exec. - -commit 9b2eaebdf6eb46321403bfc6af1145d051d3bbdc -Author: Guus Sliepen -Date: Tue Oct 15 14:09:42 2013 +0200 - - Fix sending empty SPTPS records. - -commit 0da07280882253b792ddf9c6bd8b6690ba585b7a -Author: Guus Sliepen -Date: Sun Oct 13 01:02:52 2013 +0200 - - Use AES-256-GCM for the SPTPS protocol. - - It is faster than AES-256-CTR + HMAC-SHA256, especially on Intel chips with AES - and PCLMULQDQ instructions. - -commit e42bd6009785263b545c1651840943c01461ffda -Author: Guus Sliepen -Date: Fri Sep 27 10:43:56 2013 +0200 - - Fix typos in the documentation. - - Thanks to Thomas Sattler for finding and reporting them. - -commit 68e3efe34980cc82ffc143fc33d3c11b69ec8e2b -Author: Guus Sliepen -Date: Fri Sep 27 11:36:46 2013 +0200 - - Fix segfault when Name = $HOST but $HOST is not set. - - Conflicts: - src/net_setup.c - -commit 22d804d4467cfe9f3926ab6d37b69c3760395b6c -Author: Guus Sliepen -Date: Sun Sep 15 22:03:00 2013 +0200 - - Link sptps_speed with -lrt. - - This is necessary for clock_gettime() on older versions of libc. - -commit c621dd62c74284bfc307a351bec875eb6918bf0f -Author: Guus Sliepen -Date: Sun Sep 15 22:02:33 2013 +0200 - - Don't leak memory during the key generation speed test. - -commit b7b68c3e979994a70f3adb9b40784f65cadf6a75 -Author: Guus Sliepen -Date: Sun Sep 15 17:35:55 2013 +0200 - - Add a benchmark for the SPTPS protocol. - -commit 87b017c71062bbc75ab5a98795abaf87f96ceba6 -Author: Guus Sliepen -Date: Sun Sep 15 16:21:25 2013 +0200 - - Avoid using BIOs. - -commit aaa7caad3d2a03d799264b0d62cddac6b4ee4092 -Author: Guus Sliepen -Date: Sun Sep 15 13:36:53 2013 +0200 - - Wrong date for the 1.1pre9 release in the NEWS. - -commit 85d33e563a0e4ce5910c9ba3b34eba8fbb1cbd30 -Author: Guus Sliepen -Date: Sun Sep 8 17:29:12 2013 +0200 - - Releasing 1.1pre9. - -commit e11daa264615f6eb5782f1f349b23f47518577dd -Author: Guus Sliepen -Date: Sun Sep 8 15:03:06 2013 +0200 - - Don't try to mkdir(CONFDIR) if --config is used. - -commit c25c684a847e11be80916e6de0608f11958d701d -Author: Guus Sliepen -Date: Sun Sep 8 14:47:59 2013 +0200 - - Make sure test scripts end up in the tarball. - -commit 6072759bcb6118923685ace08048c2917425680a -Author: Guus Sliepen -Date: Sun Sep 8 14:42:32 2013 +0200 - - Automake doesn't like info files being mentioned in CLEANFILES. - -commit b80cbaba040775ba20159b20d02c8c903c84e0e1 -Author: Guus Sliepen -Date: Thu Sep 5 17:42:31 2013 +0200 - - Test running ping through two tinc daemons. - - This is a more complicated test with one tinc daemon using a tap interface - (therefore requiring root), and a second one using a multicast interface. A - separate program "pong" is listening on the same multicast address, and waits - for ARP and ICMP packets, responding to ICMP echo packets with replies. - This test doesn't require any configuration of the tap interface. - -commit fe1d0043c81b26f337bdce63dd290d882b01cf21 -Author: Guus Sliepen -Date: Thu Sep 5 17:41:05 2013 +0200 - - Don't return zero-length packets when receiving multicast loopback packets. - -commit 2faf3e91af90716180bde27f54370fe4cbfc64c2 -Author: Guus Sliepen -Date: Thu Sep 5 14:59:56 2013 +0200 - - Add two more test scripts. - -commit 6242b68242646fa94bdacc94be93f0e894ae757e -Author: Guus Sliepen -Date: Thu Sep 5 14:51:13 2013 +0200 - - Fix multicast device. - -commit 09b5a3c02057fe9448c4e9494a99c93a61f98280 -Author: Guus Sliepen -Date: Thu Sep 5 14:50:10 2013 +0200 - - Exit value 1 instead of a random non-zero value. - -commit bdbb710060bef4b3ec63f5592e4def57a4817bd9 -Author: Guus Sliepen -Date: Mon Sep 2 00:15:50 2013 +0200 - - Add a test for invite and join commands. - -commit 566ef6bcbae2bb17c30d500c96331d0c7bdca070 -Author: Guus Sliepen -Date: Mon Sep 2 00:15:18 2013 +0200 - - Also test whether tinc daemons can connect to each other after import/export. - -commit 796c14b75c9e8066b4f68f6ce7cdaddd97c46a87 -Author: Guus Sliepen -Date: Mon Sep 2 00:11:04 2013 +0200 - - Slightly relax the connection rate limit for a single address. - - The restriction of accepting only 1 connection per second from a single address - is a bit too much, especially if one wants to join a VPN using an invitation, - which requires two connections. - -commit 933f7f7526d89a4ad41e2c2936c26cb41997ed78 -Author: Guus Sliepen -Date: Sun Sep 1 22:59:51 2013 +0200 - - Send a RELOAD to a running tincd when a new invitation key has been generated. - -commit 4e7e4818b771af47a10ce0b8f4046ab455ef14a9 -Author: Guus Sliepen -Date: Sun Sep 1 22:58:45 2013 +0200 - - Clean up leftover tincd and sptps_test processes. - -commit b00a6d0666f13b5206b6fcb21479281270169584 -Author: Guus Sliepen -Date: Sun Sep 1 21:55:16 2013 +0200 - - Fix tincd logfile location when running tests. - -commit c179dd0fc8ba0d20e8b29b0a5d2485a637e999e6 -Author: Etienne Dechamps -Date: Sun Sep 1 20:07:32 2013 +0100 - - Fix broken build with --with-openssl, --with-libgcrypt. - - When --with-openssl is used, $openssl is set to the specified path. - Unfortunately, that confuses the OPENSSL conditional which expects it to - be set to "true". The result is that the contents of the openssl/ - directory are not built when --with-openssl is used, resulting in - undefined references and a broken build. - - In addition, there is a typo in the GCRYPT conditional definition - ("grypt" instead of "gcrypt") which means GCRYPT never gets set, - (presumably) breaking builds using libgcrypt. - - These regressions were introduced in - 9b9230a0a79c670b86f54fadd2807b864ff9d91f. - -commit a4e49f45664cfc9414d6eaaa7bd45f1eb3012e37 -Author: Guus Sliepen -Date: Sun Sep 1 21:07:02 2013 +0200 - - Add test for import, export and exchange commands. - -commit 2cd8e2b8e8d60fdeb633afe54eaf38e18afb04dc -Author: Guus Sliepen -Date: Sun Sep 1 21:06:25 2013 +0200 - - Small fixes for tests. - -commit 09cd7ac62a40851a73f0bf7e8721848c10a7b1ff -Author: Guus Sliepen -Date: Sun Sep 1 16:02:49 2013 +0200 - - Make sptps_test more easy to work with. - - It now defers reading from stdin until after the authentication phase is - completed. Furthermore, it supports the -q, -r, -w options similar to those of - Jürgen Nickelsen's socket. - -commit 1cdb0c21d42d600d0e89857f4e9f33843f9372c8 -Author: Guus Sliepen -Date: Sun Sep 1 15:40:59 2013 +0200 - - Some shells set $_ to an absolute path. - -commit 05a7f0b2fb07f8ee7752604a2a87b85f2430aaa3 -Author: Guus Sliepen -Date: Sun Sep 1 00:39:14 2013 +0200 - - Start of a test suite. - -commit d01ab07f78f84d7d30c5788416c8d4ca0e1f74bf -Author: Guus Sliepen -Date: Fri Aug 30 14:23:02 2013 +0200 - - Allow testing the replay window with sptps_test. - -commit ccbf70b66f8e5ac18e672309a7bad899cfc0f400 -Author: Guus Sliepen -Date: Fri Aug 30 14:22:05 2013 +0200 - - Fix the replay window in SPTPS. - -commit c7752ca73e582d63412e7f40984cff2fca02c22f -Author: Guus Sliepen -Date: Fri Aug 30 13:43:23 2013 +0200 - - Fix CTR mode. - -commit d0aa0817d2387e89555ed090d900f61c56b19caa -Author: Guus Sliepen -Date: Fri Aug 30 13:04:14 2013 +0200 - - Add an option to test datagram SPTPS with packet loss. - -commit 5da0ebd421572230fbd213ca0749df6771f4cb10 -Author: Guus Sliepen -Date: Wed Aug 28 14:24:07 2013 +0200 - - When generating invitations, handle any order of Port and Adress statements. - -commit f0e11cd2c55a83662049646d2f6ffba3ac697989 -Author: Guus Sliepen -Date: Tue Aug 27 21:19:50 2013 +0200 - - Call WSAStartup() in main(). - - The tinc utility defered calling WSAStartup() until it tried to connect to a - running tinc daemon. However, socket functions are now also used for other - things (like joining another VPN using an invitation). Now we just - unconditionally call WSAStartup() early in main(). - -commit 82575bd44dc02bd1febd265c1db0f05b298329af -Author: Guus Sliepen -Date: Sat Aug 24 00:48:24 2013 +0200 - - Tell invited node about Mode and Broadcast settings. - - Since these settings really should be the same for all nodes in a VPN. - -commit 57991e264202ad83e2c1b663777b358bf5573652 -Author: Guus Sliepen -Date: Fri Aug 23 19:24:36 2013 +0200 - - Use PATHEXT when checking for the presence of scripts on Windows. - - It seems like a lot of overhead to call access() for every possible extension - defined in PATHEXT, but apparently this is what Windows does itself too. At - least this avoids calling system() when the script one is looking for does not - exist at all. - - Since the tinc utility also needs to call scripts, execute_script() is now - split off into its own source file. - -commit 21184674b38ea1da87588de97dab076c9b9e4a81 -Author: Guus Sliepen -Date: Wed Aug 21 00:24:55 2013 +0200 - - Execute scripts when invitations are created or accepted. - -commit 9699f08afc6420d2bdac1063ea6789b585aaf42e -Author: Guus Sliepen -Date: Tue Aug 20 23:09:36 2013 +0200 - - Ensure the invitation filenames do not reveal the secret cookie. - - Since filenames could potentially leak to unprivileged users (for example, - because of locatedb), it should not contain the cookie used for invitations. - Instead, tinc now uses the hash of the cookie and the invitation key as the - filename to store pending invitations in. - -commit 5dec1c25713a19c49fcbb885200184a9682ef175 -Author: Guus Sliepen -Date: Tue Aug 20 22:36:31 2013 +0200 - - Let a server explicitly send a notification when the invitation protocol succeeded. - -commit c798f7309337fc4c6dec7fd99d45cd76f809ab02 -Author: Guus Sliepen -Date: Tue Aug 20 16:49:03 2013 +0200 - - Use our own infrastructure for finding out the local node's externally visible host name. - -commit 160b7cb5e3e9b7869f6ca38e6a7ab2db39aba979 -Author: Guus Sliepen -Date: Tue Aug 20 16:47:07 2013 +0200 - - Resolve the local host name before generating the invitation file. - -commit 65f5e8fba45c6c51cfdfa2a41ab6db14663cdf73 -Author: Guus Sliepen -Date: Sun Aug 18 23:55:40 2013 +0200 - - Bind outgoing sockets again. - - Commit cff5a84 removed the feature of binding outgoing TCP sockets to a local - address. We now call bind() again, but only if there is exactly one listening - socket with the same address family as the destination address of the outgoing - socket. - -commit 0c54f365534fcb345e87961e71d452e269e170fe -Author: Guus Sliepen -Date: Sun Aug 18 22:43:55 2013 +0200 - - Remove broadcast of KEY_CHANGED message during tinc's initialization. - -commit 09b0b49b98cc16f6b281e4e635c2c70234e38865 -Author: Guus Sliepen -Date: Sun Aug 18 22:35:27 2013 +0200 - - Fix order of tincd's initialization. - - The order in which tinc initialized things was not completely correct. Now, it - is done as follows: - - - Load and parse configuration files. - - Create all TCP and UDP listening sockets. - - Create PID file and UNIX socket. - - Run the tinc-up script. - - Drop privileges. - - Start outgoing connections. - - Run the main loop. - - The PID file can only be created correctly if the listening sockets have been - set up ,as it includes the address and port of the first listening socket. The - tinc-up script has to be run after the PID file and UNIX socket have been - created so it can change their permissions if necessary. Outgoing connections - should only be started right before the main loop, because this is not really - part of the initialization. - -commit 8f8424445810aa7d5e9d4d537494e64811a8e29f -Author: Guus Sliepen -Date: Sun Aug 18 18:20:41 2013 +0200 - - Don't force a .bat extension for scripts under Windows. - -commit b180c1af99c559809d0e7b23fce3022817ec56a9 -Author: Guus Sliepen -Date: Sun Aug 18 17:02:49 2013 +0200 - - Create UNIX socket at the same time as the PID file is created. - - The PID file was created before tinc-up was called, but the UNIX socket was - created afterwards, which meant one could not change the UNIX socket's owner or - permissions from the tinc-up script. - -commit 707914e0e4b45183b1f687b44d97731127df3078 -Author: Guus Sliepen -Date: Wed Aug 14 16:20:32 2013 +0200 - - Remove texi2html rule in docs/Makefile. - - According to Debian, texi2html is deprecated and makeinfo --html should be used - instead. Automake already provides a html target that invokes makeinfo. - -commit 5e50a56dd9ebef71683b60856f904d352a3b89dc -Author: Guus Sliepen -Date: Wed Aug 14 16:17:12 2013 +0200 - - Stop using EXTRA_DIST in src/Makefile.am. - - Automake finds the files in the subdirectories of src/ now that they are - properly declared in the _SOURCES variables. Using EXTRA_DIST would now cause - .o files to be included in the tarball. - -commit 60e774942826cb28c53ac6fd23887162323696e9 -Author: Guus Sliepen -Date: Tue Aug 13 22:05:43 2013 +0200 - - Releasing 1.1pre8. - -commit 6aa864baa626b366f5bba1f1b349a870b68d7c01 -Author: Guus Sliepen -Date: Tue Aug 13 20:40:40 2013 +0200 - - Don't typedef the same struct in two header files. - - Some (older?) versions of GCC don't like this. - -commit 5e00a24e1f13fa70a6945831c409d873b7809d11 -Author: Guus Sliepen -Date: Tue Aug 13 20:38:57 2013 +0200 - - Update copyright notices. - -commit a61d3d1c0b6d0dc1b53040ae2e1a055fb34eb832 -Author: Guus Sliepen -Date: Tue Aug 13 20:37:55 2013 +0200 - - Build .tar.gz instead of .tar.xz. - - Only FreeBSD's tar supports xz compression, the other BSDs do not. NetBSD doesn't even - like bzip2. - -commit 2df534808d75c5898a819a7a4063c7a6f2445bd4 -Author: Guus Sliepen -Date: Tue Aug 13 20:35:48 2013 +0200 - - Move .h files from noinst_HEADERS to tincd_SOURCES. - - This is the recommended way according to the Automake manual. - -commit de8e6bf452227094a8aadd32dd5ea0d94d4b5db9 -Author: Guus Sliepen -Date: Thu Aug 8 17:40:15 2013 +0200 - - Don't echo broadcast packets back when Broadcast = direct. - -commit 81c71203201f6642a496f466660236efdd522ceb -Author: Guus Sliepen -Date: Fri Aug 2 23:51:55 2013 +0200 - - Fix a typo. - -commit 76c90e1639ee900fca4fc858260f0078ba32b9b1 -Author: Guus Sliepen -Date: Fri Aug 2 23:46:19 2013 +0200 - - Non-zero exit code when reloading config file fails after SIGHUP. - - When reloading the configuration file via the tinc command, the user will get - an error message if reloading has failed. However, no such warning exists when - sending a HUP signal. Previously, tincd would exit in both cases, but with a - zero exit code. Now it will exit with code 1 when reloading fails after a - SIGHUP, but tincd will keep running if it is signaled via the tinc command. - Instead, the tinc command will exit with a non-zero exit code. - -commit f3a2bed063d98961d0619ca318185740f8cf6f99 -Author: Guus Sliepen -Date: Fri Aug 2 20:53:54 2013 +0200 - - Really retry outgoing connections immediately if requested. - - The retry() function would only abort connections that were in progress of - being made, it wouldn't reschedule the outgoing connections that had been - sleeping. - -commit 1e7d1cd3c72cc478482fb75b15f9f50745b68504 -Author: Guus Sliepen -Date: Fri Aug 2 20:50:19 2013 +0200 - - Clean up the SIGINT handler. - -commit a38e0d621397d6d69c939ccc287d5a803b668195 -Author: Guus Sliepen -Date: Fri Aug 2 19:27:06 2013 +0200 - - Use umask() to set file and UNIX socket permissions without race conditions. - - As mentioned by Erik Tews, calling fchmod() after fopen() leaves a small window - for exploits. As long as tinc is single-threaded, we can use umask() instead to - reduce file permissions. This also works when creating the AF_UNIX control socket. - - The umask of the user running tinc(d) is used for most files, except for the - private keys, invitation files, PID file and control socket. - -commit a1f4f14c6c5e269c901e6e019418fb8f789cf96b -Author: Guus Sliepen -Date: Fri Jul 26 15:48:52 2013 +0200 - - Defer handling netname conflicts when accepting an invitation. - - In case no explicit netname of configuration directory is specified when - accepting an invitation, the netname specified in the invitation data is - used. However, this new netname is only known after making the connection - to the server. If the new netname conflicts with an existing one at the - client, we ask the user for a netname that doesn't conflict. However, we - should first finish accepting the invitation, so we don't run into the - problem that the server times out and cancels the invitation. So, we create - a random netname and store the files there, and only after we finish - accepting the invitation we ask the user for a better netname, and then - just rename the temporary directory to the final name. - -commit d47c79533f831a2714aff277aff31c46da1ec684 -Author: Guus Sliepen -Date: Fri Jul 26 15:44:05 2013 +0200 - - Make absolutely sure we can write config files before accepting an invitation. - -commit 37cca72e6c973b77b5d11dcf721ae050edc23586 -Author: Guus Sliepen -Date: Fri Jul 26 14:53:36 2013 +0200 - - Choose a different Port when 655 isn't available when doing "tinc join". - -commit 8f2db4afddf109e59c7ec0cdb7ad79db75d698e5 -Author: Guus Sliepen -Date: Fri Jul 26 14:17:15 2013 +0200 - - Choose a different Port when 655 isn't available when doing "tinc init". - - If port 655 cannot be bound to when using the init command, tinc will try to - find a random port number that can be bound to, and will add the appropriate - Port variable to its host config file. A warning will be printed as well. - -commit d6a67266c812a85f11c734503ae5560ab8983edb -Author: Guus Sliepen -Date: Thu Jul 25 17:17:33 2013 +0200 - - Don't forget the Port variable when creating an invitation URL. - -commit d1e01bc880a6970050e55f19bafe8eaf1f0b9be2 -Author: Guus Sliepen -Date: Thu Jul 25 17:14:07 2013 +0200 - - Allow control-C to stop tincd without stopping the tinc shell. - -commit d219fe2c09652fcdc6b457bb5fd72ad18a3a33c5 -Author: Guus Sliepen -Date: Thu Jul 25 16:21:11 2013 +0200 - - Warn when incorrect use of add or set causes variables to be removed. - -commit e6249695684dcddc5d7ae0269adc7764ecec925a -Author: Guus Sliepen -Date: Wed Jul 24 20:48:31 2013 +0200 - - Fix compression when using the SPTPS protocol. - -commit 5fca595b80f5d2a6629d74e89ca2ef46ba9ae292 -Author: Guus Sliepen -Date: Mon Jul 22 22:58:13 2013 +0200 - - Honour umask, let temporary key files inherit original's permissions. - - During the init command, tinc changed the umask to 077 when writing the public - and private key files, to prevent the temporary copies from being world - readable. However, subsequently created files would therefore also be - unreadable for others. Now we don't change the umask anymore, therefore - allowing the user to choose whether the files are world readable or not by - setting the umask as desired. The private key files are still made unreadable - for others of course. Temporary files now inherit the permissions of the - original, and the tinc-up script's permissions now also honour the umask. - -commit ae85a020303d523f24ddf45a816e6a2ceb4fc935 -Author: Etienne Dechamps -Date: Mon Jul 22 21:22:26 2013 +0100 - - Further improve bandwidth estimation for type 2 MTU probe replies. - - This patch adds timestamp information to type 2 MTU probe replies. This - timestamp can then be used by the recipient to estimate bandwidth more - accurately, as jitter in the RX direction won't affect the results. - -commit e3c763eae89df9a69bb2d611238ef18f78de311f -Author: Etienne Dechamps -Date: Sun Jul 21 13:05:42 2013 +0100 - - Introduce lightweight PMTU probe replies. - - When replying to a PMTU probe, tinc sends a packet with the same length - as the PMTU probe itself, which is usually large (~1450 bytes). This is - not necessary: the other node wants to know the size of the PMTU probes - that have been received, but encoding this information as the actual - reply length is probably the most inefficient way to do it. It doubles - the bandwidth usage of the PMTU discovery process, and makes it less - reliable since large packets are more likely to be dropped. - - This patch introduces a new PMTU probe reply type, encoded as type "2" - in the first byte of the packet, that indicates that the length of the - PMTU probe that is being replied to is encoded in the next two bytes of - the packet. Thus reply packets are only 3 bytes long. - - (This also protects against very broken networks that drop very small - packets - yes, I've seen it happen on a subnet of a national ISP - in - such a case the PMTU probe replies will be dropped, and tinc won't - enable UDP communication, which is a good thing.) - - Because legacy nodes won't understand type 2 probe replies, the minor - protocol number is bumped to 3. - - Note that this also improves bandwidth estimation, as it is able to - measure bandwidth in both directions independently (the node receiving - the replies is measuring in the TX direction) and the use of smaller - reply packets might decrease the influence of jitter. - -commit e3a4672afb8eb341b380e74b2bf6d098f61c08a3 -Author: Etienne Dechamps -Date: Sat Jul 20 22:59:57 2013 +0100 - - Disable PMTU discovery when TCPOnly is set. - - Obviously, PMTU discovery doesn't make much sense when we know we'll be - using TCP anyway. - -commit b03bbaa38561e790873de3adabc3d4405be17fb8 -Author: Guus Sliepen -Date: Sun Jul 21 00:20:54 2013 +0200 - - Allow extra options to be passed to "tinc restart" again. - -commit e82bec667059b370b0cfd5df2a34647b8f32829c -Author: Guus Sliepen -Date: Sun Jul 21 00:13:38 2013 +0200 - - Forbid protocol version rollback. - - When we know a node's ECDSA key, we only allow communication via the SPTPS - protocol. - -commit fab2965d381f2f71ea8d249d30294918e954d2db -Author: Guus Sliepen -Date: Sat Jul 20 23:41:01 2013 +0200 - - Attribution for Etienne Dechamps. - -commit 51c1639884b409a98a4581a7b661ef65b94e9d86 -Author: Etienne Dechamps -Date: Sat Jul 20 14:50:28 2013 +0100 - - Fix hash_function(). - - The hashing function that tinc uses is currently broken as it only looks - at the first 4 bytes of data. - - This leads to interesting bugs, like the node UDP address cache being - subtly broken because two addresses with the same protocol and port (but - not the same IP address) will override each other. This is because - the first four bytes of sockaddr_in contains the IP protocol and port, - while the IP address itself is contained in the four remaining bytes - that are never used when the hash is computed. - -commit 182890814881be90e28ac5183039e25709766992 -Author: Guus Sliepen -Date: Wed Jul 17 18:06:56 2013 +0200 - - Don't use vasprintf() anymore on Windows. - - Windows doesn't actually support it, but MinGW provides it. However, with some versions of - MinGW it doesn't work correctly. Instead, we vsnprintf() to a local buffer and xstrdup() the - results. - -commit 54127996ca4156668b6c7df3bb5d8f952dc598ad -Author: Guus Sliepen -Date: Wed Jul 17 18:02:07 2013 +0200 - - Don't search in local directories for include files. - - Tinc's source code doesn't rely on this anymore, and this gets rid of potential conflicts with - system headers. - -commit fb1e69072e9c1dda35033cc2785c27e324a2abda -Author: Guus Sliepen -Date: Wed Jul 17 18:00:40 2013 +0200 - - Add missing definitions on Windows. - -commit 918067f117d5b9983a8f2273fd81983362a2ff88 -Author: Guus Sliepen -Date: Mon Jul 15 14:48:43 2013 +0200 - - Fix warning "Both netname and configuration directory given" on Windows. - -commit 633b7cbb452ea19e515cadee9bc63e631f8183c2 -Author: Etienne Dechamps -Date: Sat Jul 13 23:34:42 2013 +0100 - - Fix combination of Mode = router and DeviceType = tap on Linux. - - I believe I have found a bug in tinc on Linux when it is used with - Mode = router and DeviceType = tap. This combination is useful because - it allows global broadcast packets to be used in router mode. However, - when tinc receives a packet in this situation, it needs to make sure its - destination MAC address matches the address of the TAP adapter, which is - typically not the case since the sending node doesn't know the MAC - address of the recipient. Unfortunately, this is not the case on Linux, - which breaks connectivity. - -commit 24e3ec863ec463186501f76961c6d4b1dfe122af -Author: Guus Sliepen -Date: Thu Jul 11 23:38:38 2013 +0200 - - Add connection rate limiting. - - Tinc now strictly limits incoming connections from the same host to 1 per - second. For incoming connections from multiple hosts short bursts of incoming - connections are allowed (by default 100), but on average also only 1 connection - per second is allowed. - - When an incoming connection exceeds the limit, tinc will keep the connection in - a tarpit; the connection will be kept open but it is ignored completely. Only - one connection is in a tarpit at a time to limit the number of useless open - connections. - -commit 2eba7933053d7d21bf82e647978ee90abe98dc3a -Author: Guus Sliepen -Date: Fri Jul 5 21:36:51 2013 +0200 - - Set $NAME when calling host-up/down and subnet-up/down scripts. - -commit b811e980e3a2a301c019459b91df2252468fd572 -Author: Guus Sliepen -Date: Fri May 31 18:50:34 2013 +0200 - - Add the LocalDiscoveryAddress option. - - When LocalDiscovery is enabled, tinc normally sends broadcast packets during - PMTU discovery to the broadcast address (255.255.255.255 or ff02::1). This - option lets tinc use a different address. - - At the moment only one LocalDiscoveryAddress can be specified. - -commit e92b2004e20e1c8e6bc56f97bf4a45c6da4a630c -Author: Guus Sliepen -Date: Fri May 31 17:23:00 2013 +0200 - - Use strerror() instead of gai_strerror() when err == EAI_SYSTEM. - -commit ce5e0f6557edba19f8077661c034f48cdfd64b9a -Author: Guus Sliepen -Date: Thu May 30 17:38:48 2013 +0200 - - Allow the log output to be stopped with control-C in tinc's shell. - -commit 6bf3595a915111770b7a167c54ccbca86cfbec78 -Author: Guus Sliepen -Date: Thu May 30 16:53:16 2013 +0200 - - Better optional argument handling. - - Some options can take an optional argument. However, in this case GNU getopt - requires that the optional argument is right next to the option without - whitespace inbetween. If there is whitespace, getopt will treat it as a - non-option argument, but tincd ignored those without a warning. Now tincd will - allow optional arguments with whitespace inbetween, and will give an error when - it encounters any other non-option arguments. - - The tinc binary now requires that all options for itself are given before the - command. - -commit ced4c1a327b321a6d73028a3a15b41b0be64d910 -Author: Guus Sliepen -Date: Wed May 29 18:31:10 2013 +0200 - - Add an invitation protocol. - - Using the tinc command, an administrator of an existing VPN can generate - invitations for new nodes. The invitation is a small URL that can easily - be copy&pasted into email or live chat. Another person can have tinc - automatically setup the necessary configuration files and exchange keys - with the server, by only using the invitation URL. - - The invitation protocol uses temporary ECDSA keys. The invitation URL - consists of the hostname and port of the server, a hash of the server's - temporary ECDSA key and a cookie. When the client wants to accept an - invitation, it also creates a temporary ECDSA key, connects to the server - and says it wants to accept an invitation. Both sides exchange their - temporary keys. The client verifies that the server's key matches the hash - in the invitation URL. After setting up an SPTPS connection using the - temporary keys, the client gives the cookie to the server. If the cookie - is valid, the server sends the client an invitation file containing the - client's new name and a copy of the server's host config file. If everything - is ok, the client will generate a long-term ECDSA key and send it to the - server, which will add it to a new host config file for the client. - - The invitation protocol currently allows multiple host config files to be - send from the server to the client. However, the client filters out - most configuration variables for its own host configuration file. In - particular, it only accepts Name, Mode, Broadcast, ConnectTo, Subnet and - AutoConnect. Also, at the moment no tinc-up script is generated. - - When an invitation has succesfully been accepted, the client needs to start - the tinc daemon manually. - -commit 12e68b95e6a84582a016492a467d0a16337a3c4b -Author: Guus Sliepen -Date: Tue May 28 13:41:53 2013 +0200 - - Fix port number in pidfile. - -commit cbe03b09324dcf930e9bec71a809c66e2d3d77d5 -Author: Guus Sliepen -Date: Tue May 28 13:40:32 2013 +0200 - - Add a newline when logging to stderr in the tinc binary. - -commit c3d357af6c73d538f7cbcaca293ebbca666d3a82 -Author: Guus Sliepen -Date: Tue May 28 13:39:15 2013 +0200 - - Improve base64 encoding/decoding, add URL-safe variant. - - b64decode() now returns length 0 when an invalid character was encountered. - -commit ad93dc3a4b89799e8d5c1154e1dacc5b9a31c83b -Author: Guus Sliepen -Date: Tue May 28 13:36:26 2013 +0200 - - Annotate the xalloc functions. - - Most important is the annotation of xasprintf() with the format attribute, - which allows the compiler to give warnings about the format string and - arguments. - -commit bc87b450034382858822b918f43bdf31ad8e6995 -Author: Guus Sliepen -Date: Sat May 18 16:11:30 2013 +0200 - - Send a new key when we receive packets from a node we don't have a valid key for. - -commit a9b80226e10b0a957604ad55edd945f49bc5f334 -Author: Guus Sliepen -Date: Wed May 15 13:55:06 2013 +0200 - - Enable and fix warnings from automake. - -commit a518f82af79036527cb8d1a592a6778ec1657e9c -Author: Sven-Haegar Koch -Date: Tue May 14 02:57:35 2013 +0200 - - Modified some error messages in src/sptps.c. - -commit fa20cfceecee1756ecb7882b6fe9167f4db92777 -Author: Guus Sliepen -Date: Sun May 12 13:39:22 2013 +0200 - - Don't try to handle incoming data if sptps_start() has not been called yet. - -commit 52f64cdf954a525bf7de1c5f9d3be60dfbe220b5 -Author: Guus Sliepen -Date: Sat May 11 16:54:50 2013 +0200 - - Fix potential NULL pointer dereferences. - -commit d03dc91e27b31851f87351c03cfc9a43c1b06458 -Author: Guus Sliepen -Date: Sat May 11 14:13:23 2013 +0200 - - Don't free ephemeral ECDH keys twice. - - ecdh_compute_shared() was changed to immediately delete the ephemeral key after - the shared secret was computed. Therefore, the pointer to the ecdh_t struct - should be zeroed so it won't be freed again when a struct sptps_t is freed. - -commit fc119fb0096a9221f2cff279b07c886bcd794d28 -Author: Guus Sliepen -Date: Sat May 11 14:05:28 2013 +0200 - - Use read_host_config() where appropriate. - -commit 3c163a3796c984deb874fb1cca1ed9a85fc1d087 -Author: Guus Sliepen -Date: Sat May 11 14:04:39 2013 +0200 - - Fix check for presence of ECDSA public key for outgoing connections. - - At this point, c->config_tree may or may not be NULL, but this does not tell us whether it is an - outgoing connection or not. For incoming connections, we do not know the peer's name yet, - so we always have to claim ECDSA support. For outgoing connections, we always need to check - whether we have the peer's ECDSA public key, so that if we don't, we correctly tell the peer that - we want to upgrade. - -commit c83c2d080f21b12db42ef664d7c3272b8b700656 -Author: Guus Sliepen -Date: Fri May 10 21:11:45 2013 +0200 - - Enable the SPTPS protocol by default. - -commit ee34ac3d6125b7d1f41afa82c7e30f0a7205546c -Author: Guus Sliepen -Date: Fri May 10 20:55:52 2013 +0200 - - Add a few more checks and warnings in the crypto functions. - -commit 214060ef20499332b0369030b664a8e239518661 -Author: Guus Sliepen -Date: Fri May 10 20:30:47 2013 +0200 - - Fix warnings for functions marked __attribute((warn_unused_result)). - -commit 7b949262c4c01fdeff30a612d43f4b64f1ad426f -Author: Guus Sliepen -Date: Fri May 10 20:23:01 2013 +0200 - - Add __attribute__((warn_unused_result)) to crypto functions. - -commit 45063953fd3f2c25c7f8cc65860b32a35b3ba80e -Author: Guus Sliepen -Date: Fri May 10 20:15:27 2013 +0200 - - Add more __attribute__((malloc)) where appropriate. - -commit 0acdce222ff21c84cafc82c137e3d1e107a66fd9 -Author: Guus Sliepen -Date: Wed May 1 17:45:38 2013 +0200 - - Add generic crypto headers. - - They should have been included in commit 9b9230a. - -commit 5b07039b0712bee0f19749d63116a10fb08a2d8b -Author: Guus Sliepen -Date: Wed May 1 17:31:33 2013 +0200 - - Rename xmalloc_and_zero() to xzalloc(). - - The former name is more or less only used by tinc, the latter is used by other - projects as well, and shorter as well. - -commit 9b9230a0a79c670b86f54fadd2807b864ff9d91f -Author: Guus Sliepen -Date: Wed May 1 17:17:22 2013 +0200 - - Use conditional compilation for cryptographic functions. - - This gets rid of the rest of the symbolic links. However, as a consequence, the - crypto header files have now moved to src/, and can no longer contain - library-specific declarations. Therefore, cipher_t, digest_t, ecdh_t, ecdsa_t - and rsa_t are now all opaque types, and only pointers to those types can be - used. - -commit e70b5b5bd77bb66e8dd324c17d86d9bff151aa82 -Author: Guus Sliepen -Date: Wed May 1 12:20:06 2013 +0200 - - Use conditional compilation for device.c. - - This requires the automake option "subdir-objects" to be enabled, and it - becomes more critical to specify the exact path to local header files. - -commit 9f8020a09ce08210a10a0c65cefd83d2646395ab -Author: Guus Sliepen -Date: Wed May 1 11:46:40 2013 +0200 - - Modernize the configure script a bit. - -commit 43c72093ade72f14cb2fc78bef55dade8cd38df7 -Author: Guus Sliepen -Date: Sun Apr 28 19:33:04 2013 +0200 - - Don't try to create tinc.conf when using set or add commands. - - It is almost certainly an error. If one really wants to create a new tinc.conf - file, one should use the init command. - -commit 8e732fcbbb5ac627ea302bf5c0ea17ec9b3cea7c -Author: Guus Sliepen -Date: Mon Apr 22 15:54:05 2013 +0200 - - Releasing 1.1pre7. - -commit 258bf7ea0fe69bae395a084843ba59b9770199f1 -Author: Guus Sliepen -Date: Fri Apr 12 17:15:05 2013 +0200 - - Drop packets forwarded via TCP if they are too big (CVE-2013-1428). - - Normally all requests sent via the meta connections are checked so that they - cannot be larger than the input buffer. However, when packets are forwarded via - meta connections, they are copied into a packet buffer without checking whether - it fits into it. Since the packet buffer is allocated on the stack, this in - effect allows an authenticated remote node to cause a stack overflow. - - This issue was found by Martin Schobert. - -commit 9e2ae03d1dc3b0d9a32a748320b9ed1565fa1374 -Author: Guus Sliepen -Date: Tue Mar 12 11:28:40 2013 +0100 - - Fix completion of add/del/get/set commands. - -commit f8f250ca1289990cb1fe69dfa252f0796aa38255 -Author: Guus Sliepen -Date: Tue Mar 12 10:49:45 2013 +0100 - - Describe the SPTPS protocol in the manual. - - Also mention that Cipher, Digest and MACLength have no influence on the SPTPS protocol, - since that uses a fixed ciphersuite. - -commit 40666a5f5b85aa0151c3ba60950267f3c2a3a6bc -Author: Guus Sliepen -Date: Fri Mar 8 16:26:21 2013 +0100 - - Remove references to the config keyword. - -commit 23a634becf09ac84c71250474fcb96e23b0ebdf1 -Author: Guus Sliepen -Date: Fri Mar 8 16:22:56 2013 +0100 - - Rename tincctl to tinc. - -commit 3793cf10da488b9f4f7a1ac71f60bc270bdf31c6 -Author: Guus Sliepen -Date: Fri Mar 8 14:12:48 2013 +0100 - - Include README.android in the tarballs. - -commit 4c30004cb6dc23616d7295b0ce631f066e7f1f82 -Author: Guus Sliepen -Date: Fri Mar 8 14:11:15 2013 +0100 - - Avoid calling time(NULL). - - In most cases we can use the cached time. - -commit af77e5d475d4d4ab7ad036e926a05f4f3b5c6589 -Author: Guus Sliepen -Date: Fri Mar 8 11:40:40 2013 +0100 - - Allow changing configuration with tincctl without the "config" keyword. - - This saves typing some characters, and forces one to be more explicit about the - desired command (get, set). - -commit 1d226977a43cc6c3e4ff32e1a41a06dde08356e0 -Author: Guus Sliepen -Date: Fri Mar 8 11:24:37 2013 +0100 - - Better default output file for generated public keys. - -commit f9ab8e266b93aa3be772374ef4a8fdb06e376568 -Author: Guus Sliepen -Date: Fri Mar 1 17:15:26 2013 +0100 - - Flush output buffers in the tap reader thread on Windows. - - This is basically a port of commit 50fcfea1 to 1.1. - -commit 4d05e695ab68a16cc5ed853b50482c443c6e12a9 -Author: Guus Sliepen -Date: Fri Feb 22 15:37:48 2013 +0100 - - Use UDP when using sptps_test in datagram mode. - -commit a93c0139c5734f89180483b5fe160b334f7ece4b -Author: Guus Sliepen -Date: Wed Feb 20 15:35:19 2013 +0100 - - Releasing 1.1pre6. - -commit d298ebe91c9209d139f38b6de2e42bf7c5bb5899 -Author: Guus Sliepen -Date: Wed Feb 20 15:35:08 2013 +0100 - - Fix compiler warnings on some BSD variants. - -commit 3847b78ba5900fe4311e9ef62474e32e1a6750e5 -Author: Guus Sliepen -Date: Wed Feb 20 14:39:24 2013 +0100 - - Fix compiler warnings on Windows. - -commit 1bb969c9306812d0d5c954fe8db32ed1a248bf20 -Author: Guus Sliepen -Date: Wed Feb 20 13:59:50 2013 +0100 - - Fix a tiny memory leak. - - Found by cppcheck. - -commit d21f63d5b39280b653ca72a272f3a70c7c3f03be -Author: Guus Sliepen -Date: Fri Feb 8 16:44:50 2013 +0100 - - Don't expect a response from tincd after sending REQ_STOP. - -commit 26eca516508829c3f9d8f2549335f613b569e8f5 -Author: Guus Sliepen -Date: Thu Feb 7 15:27:16 2013 +0100 - - Let the GUI use UNIX sockets if available. - -commit a8b52becbbd86a52dc50a6a1b725a80737f2c760 -Author: Guus Sliepen -Date: Thu Feb 7 15:26:56 2013 +0100 - - Derive UNIX socket filename from PID filename. - -commit 079dcd01794187d2857e1233f6c9930310812593 -Author: Guus Sliepen -Date: Thu Feb 7 14:22:28 2013 +0100 - - Don't send proxy requests for incoming connections. - -commit ee63f2a32be398c31301e9ce9154511b24089d8d -Author: Guus Sliepen -Date: Wed Feb 6 15:24:02 2013 +0100 - - Fix segmentation fault when trying to connect via a SOCKS5 proxy. - -commit 053af97c9e729ab485609e4202f5195fdc8aeeb5 -Author: Guus Sliepen -Date: Wed Feb 6 15:12:53 2013 +0100 - - Check for writability when waiting for a socket to finish connecting. - - We were checking only for readability, which is not a problem for normal - connections, since the server side of a connection will always send an ID - request. But when using a proxy, the proxy server doesn't send anything before - the client, so tinc would not see that its connection to the proxy had already - been established. - -commit 1135669b3c6820f5473ea451a58865f552ba768f -Author: Guus Sliepen -Date: Wed Feb 6 11:30:35 2013 +0100 - - Fix tincd terminating immediately on Windows. - -commit 9c878bf56f81049397a35d3a41aa69749c697fce -Author: Guus Sliepen -Date: Thu Jan 31 16:12:56 2013 +0100 - - Remove direct inclusion of OpenSSL headers in net_packet.c and tincd.c. - -commit 42b222ecb66b1957d7b439e5d8be8b287aef0054 -Author: Guus Sliepen -Date: Thu Jan 31 15:58:33 2013 +0100 - - Detect increases in PMTU. - - Tinc never restarts PMTU discovery unless a node becomes unreachable. However, - it can be that the PMTU was very low during the initial discovery, but has - increased later. To detect this, tinc now tries to send an extra packet every - PingInterval, with a size slightly higher than the currently known PMTU. If - this packet is succesfully received back, we partially restart PMTU discovery - to find out the new maximum. - - Conflicts: - src/net_packet.c - -commit 87416bcd8bd3e8816750150e2dbe90a970400a00 -Author: Guus Sliepen -Date: Mon Jan 21 16:12:18 2013 +0100 - - Get microsecond time resolution on Windows. - -commit 8aadbd4b37cddaf021949e93bceab98146f4c499 -Author: Guus Sliepen -Date: Mon Jan 21 13:59:52 2013 +0100 - - Fix a typo. - -commit 3a039ece25198c87e67950f0c4687587bf268075 -Author: Guus Sliepen -Date: Mon Jan 21 13:47:46 2013 +0100 - - Fix datagram SPTPS. - - Commit dd07c9fc1f37bed8d1f67ffe7b203f61e7914edf broke the reception of datagram - SPTPS packets, by undoing the conversion of the sequence number to host byte - order before comparison. This caused error messages like "Packet is 16777215 - seqs in the future, dropped (1)". - -commit cc3c69c892b0dad9a6ece0a0f4ccd429a22fcbff -Author: Guus Sliepen -Date: Sun Jan 20 21:03:22 2013 +0100 - - Releasing 1.1pre5. - -commit 76dbcf89895e87144e1bcb3b5cb98ffce03c383b -Author: Guus Sliepen -Date: Sun Jan 20 21:02:58 2013 +0100 - - Fix tincctl init when /etc/tinc does not yet exist. - -commit aa465969918ce3f3332f5829dbc482fc3b732012 -Author: Guus Sliepen -Date: Sun Jan 20 20:19:08 2013 +0100 - - Remove possible definition of timersub(), which is also in dropin.h. - -commit 1be7dc759a64d436fd7586aad43b545f2dc665b5 -Author: Guus Sliepen -Date: Sun Jan 20 15:16:13 2013 +0100 - - Make sure PriorityInheritance also works in switch mode. - - Conflicts: - src/route.c - -commit 94587264bda45cce0295aaa37b59905d4b9843a8 -Author: Guus Sliepen -Date: Thu Jan 17 18:12:55 2013 +0100 - - Allow connections via UNIX sockets. - - This is mainly useful for control connections. The client must still present - the control cookie from the PID file. - -commit 2c1412306242d26f7803829873e582b50adde922 -Author: Guus Sliepen -Date: Thu Jan 17 16:39:41 2013 +0100 - - Fix compilation of UML and VDE device support. - -commit f5bb64b36ae0807cdd3f241f81a8e933065437f6 -Author: Guus Sliepen -Date: Thu Jan 17 16:39:02 2013 +0100 - - Move make_names() and related variables to its own source file. - -commit a9eba276a4ccec1c67611e8496ac0a30137b7493 -Author: Guus Sliepen -Date: Thu Jan 17 14:14:17 2013 +0100 - - Handle SIGINT gracefully. - -commit 1ddd6111a40733929089316838020f89176cbda2 -Author: Guus Sliepen -Date: Thu Jan 17 11:21:18 2013 +0100 - - Fix the minimum spanning tree algorithm. - - Tinc uses Kruskal's algorithm to calculate a MST. However, this was broken in - commit 6e80da3370249caa1082c23c3ef55f338d1e9e74. Revert back to the working - algorithm from tinc 1.0. - - Thanks to Cheng LI for spotting the problem. - -commit 61275547cdf950e1c4499f19044ff171a9a74af7 -Author: Guus Sliepen -Date: Wed Jan 16 16:31:56 2013 +0100 - - Estimate RTT, bandwidth and packet loss between nodes. - - Without adding any extra traffic, we can measure round trip times, estimate the - bandwidth and packet loss between nodes. The RTT and bandwidth can be measured - by timing the MTU probe packets. The RTT is the difference between the time a - burst of MTU probes was sent and when the first reply is received. The - bandwidth can be estimated by multiplying the size of the probe packets by the - time between succesive received probe replies of the same burst. The packet - loss can be estimated for incoming traffic by comparing how many packets have - actually been received to the increase in the sequence numbers. - - The estimates are not perfect. Especially bandwidth is difficult to measure, - the only accurate way is to continuously send as much data as possible, but - that is obviously not desirable. The packet loss rate is also almost always - a few percent when sending a lot of data over the VPN via TCP, since TCP - *needs* packet loss to work properly. - -commit eef25266cb862b5e2c24450d158d99e3cb43e511 -Author: Guus Sliepen -Date: Tue Jan 15 13:33:16 2013 +0100 - - Count the number of correctly received UDP packets. - - Keep track of the number of correct, non-replayed UDP packets that have been - received, regardless of their content. This can be compared to the sequence - number to determine the real packet loss. - -commit b50a92d0c3d26edfeb7c8d6c1b8c3adc28edd6fe -Author: Guus Sliepen -Date: Tue Jan 15 13:31:51 2013 +0100 - - Add the tincctl exchange and exchange-all commands. - - These are identical to an export/export-all followed by an import, and make - it simpler to exchange host config files with other nodes. - -commit dd07c9fc1f37bed8d1f67ffe7b203f61e7914edf -Author: Guus Sliepen -Date: Mon Jan 14 13:08:35 2013 +0100 - - Check HMAC before sequence number. - -commit 83a94ab08fb36b88a473a56b164a9795637fe798 -Author: Guus Sliepen -Date: Mon Jan 14 13:02:39 2013 +0100 - - Always complain if too many arguments are given for tincctl commands. - -commit 50e1790101efa1d695ce27498e7d7dede7ed3f9b -Author: Guus Sliepen -Date: Mon Jan 14 13:01:47 2013 +0100 - - Better error messages when using -L, -R or -U on platforms that do not support it. - -commit cad86108f3a47e9bba885ccd8decf20057f909f7 -Author: Guus Sliepen -Date: Mon Jan 14 12:59:17 2013 +0100 - - Don't complain about garbage if we skipped importing a host file. - -commit c90c431bc93c1478836149a8724fdc68d1ec455c -Author: Guus Sliepen -Date: Mon Jan 14 12:58:24 2013 +0100 - - Mention that the -L, -R and -U options are not supported on all platforms. - -commit 5b88f5ba74fa9aa2cad82576308847e08cea88b1 -Author: Guus Sliepen -Date: Mon Jan 14 12:57:33 2013 +0100 - - Note that tincctl import is only meant to work with data from tincctl export. - -commit bb228e2f058c1274dca29ba255714e6fa2be494f -Author: Guus Sliepen -Date: Mon Jan 14 12:56:54 2013 +0100 - - Note that node Names are case sensitive. - -commit 2c7ecdcd0c50d4d3da6ff0b8fc2ea39573338d7f -Author: Guus Sliepen -Date: Mon Jan 14 12:56:14 2013 +0100 - - Fix a typo. - -commit 17a0b3a8907d7e618eb94ee2792d10c7cb8d3f30 -Author: Guus Sliepen -Date: Sun Dec 16 15:36:06 2012 +0100 - - Fix support for tunemu on iOS devices. - - The actual code was fine but the #ifdefs tested for the wrong preprocessor - variable. - - Conflicts: - src/bsd/device.c - src/process.c - -commit c26581e29f1f8f23217da266b57082e81dfc8320 -Author: Guus Sliepen -Date: Fri Dec 7 15:49:21 2012 +0100 - - Fix infinite loop in timeout handling on Windows. - -commit 58026f72a17b316f1b9756400f0ee9e9f519f877 -Author: Guus Sliepen -Date: Thu Dec 6 16:57:57 2012 +0100 - - Fix display of cumulative packet counters. - -commit b300f99dfbda5fc57a5366cdcb2a347e38723417 -Author: Guus Sliepen -Date: Thu Dec 6 16:55:28 2012 +0100 - - Clarify the description of IndirectData and Mode = router. - -commit 5b7f42bca4dbfee7a5fa2bc119f4739baaeb2f55 -Author: Guus Sliepen -Date: Wed Dec 5 22:32:10 2012 +0100 - - Releasing 1.1pre4. - -commit 4c16094e949e1f17461ac744118076a3cec437e8 -Author: Guus Sliepen -Date: Wed Dec 5 21:42:43 2012 +0100 - - Fix whitespace. - -commit 4f8abf1b29b117c5d593bfa7703966fd88e9eace -Author: Guus Sliepen -Date: Wed Dec 5 21:40:49 2012 +0100 - - Scale packet counters similar to byte counters. - -commit d5f0ff5df86d06825110527ddc252b1268e31479 -Author: Guus Sliepen -Date: Wed Dec 5 21:33:01 2012 +0100 - - Don't use nested functions. - - This allows tinc to be compiled with Clang. - -commit eb80105ea855f2c7ee0ea467574acf86cf455a77 -Author: Guus Sliepen -Date: Wed Dec 5 14:42:21 2012 +0100 - - Fix compiler warnings on OpenBSD. - -commit 5e3607b616538eac7bb70d78d4f20d847a1c3064 -Author: Guus Sliepen -Date: Mon Dec 3 13:09:40 2012 +0100 - - Remove GraphDumpFile from the manual and manpages. - - This option is not supported in tinc 1.1, "tincctl dump graph" can be used - instead. - -commit a717b9bcfbe811787fd6718fb3f8fb3f272bcfb9 -Author: Guus Sliepen -Date: Mon Dec 3 13:08:03 2012 +0100 - - Add option to dump only a list of reachable nodes. - -commit 75c619e372f02f8225d158fd514f01bd04857d3b -Author: Guus Sliepen -Date: Mon Dec 3 10:41:28 2012 +0100 - - More fixes for Windows. - - In particular, Windows does support many of the timer* macros, except timeradd - and timersub. - -commit d53384c2de6d2824b9adcec111301d86e6b25f8e -Author: Guus Sliepen -Date: Mon Dec 3 09:08:21 2012 +0100 - - Fix compiler error on Windows. - -commit 76816e119b7d38a14823d430aafeff362dfbfd41 -Author: Guus Sliepen -Date: Mon Dec 3 09:07:23 2012 +0100 - - Fix crash in timeout handling. - -commit d19b00606576d19ef206e363ac709daf3bd00f25 -Author: Guus Sliepen -Date: Mon Dec 3 09:02:08 2012 +0100 - - Set a node's pointers to zero before trying to insert it into a tree. - -commit d2b19be1a0dd3c4987aa926117f5bf281892c78b -Author: Guus Sliepen -Date: Thu Nov 29 14:35:08 2012 +0100 - - Fix use of unitialised values in hash tables. - - Not only was Valgrind unhappy about it, it could also result in cache misses. - -commit d9c70767aa6da8b62b4a1034d5f07892603beddd -Author: Guus Sliepen -Date: Thu Nov 29 14:32:12 2012 +0100 - - Fix check for expired events. - - This would trigger a infinite loop if a timeout expired and the next timeout - was not expired yet, but less than 1 second from being expired. - -commit 8825cddd0d8ed6dad00924ef382139da51ca3fc4 -Author: Guus Sliepen -Date: Thu Nov 29 12:37:04 2012 +0100 - - Allow multiple timeouts to expire at the exact same time. - -commit 6bc5d626a8726fc23365ee705761a3c666a08ad4 -Author: Guus Sliepen -Date: Thu Nov 29 12:28:23 2012 +0100 - - Drop libevent and use our own event handling again. - - There are several reasons for this: - - - MacOS/X doesn't support polling the tap device using kqueue, requiring a - workaround to fall back to select(). - - On Windows only sockets are properly handled, therefore tinc uses a second - thread that does a blocking ReadFile() on the TAP-Win32/64 device. However, - this does not mix well with libevent. - - Libevent, event just the core, is quite large, and although it is easy to get - and install on many platforms, it can be a burden. - - Libev is more lightweight and seems technically superior, but it doesn't - abstract away all the platform differences (for example, async events are not - supported on Windows). - -commit d30b9e1272fef18070d37d10b2b3e4bb2fc07f59 -Author: Guus Sliepen -Date: Mon Nov 19 14:20:50 2012 +0100 - - Ensure MTU probe replies are sent back the same way they came in. - - Also sprinkle some comments over mtu_probe_h(). - -commit 3c1b7047332f4b5e9d5ae7109e696b33712a5fb2 -Author: Guus Sliepen -Date: Mon Nov 19 13:50:17 2012 +0100 - - Improve UDP address selection. - - We don't need to search the whole edge tree, we can use the node's own edge - tree since each edge has a pointer to its reverse. Also, we do need to make - sure we try the reflexive address often. - -commit f57129ce3439f3826c12f15feb5df05e5ad8cab9 -Author: Guus Sliepen -Date: Sat Nov 17 22:48:06 2012 +0100 - - Try all known addresses of node during PMTU discovery, now also for SPTPS. - -commit 30404650b28bf72d0b05b55393f2dd492434f9f3 -Author: Guus Sliepen -Date: Sat Nov 17 22:14:52 2012 +0100 - - Choose a suitable socket when updating a node's UDP address. - -commit 8f9ee895224b39347783f3119343efc3bdaa3511 -Author: Guus Sliepen -Date: Thu Nov 15 11:24:18 2012 +0100 - - Also don't use poll() on MacOS/X. - -commit 8a77df9e28114cbfd83351070fdb266cf31fc310 -Author: Guus Sliepen -Date: Thu Nov 15 11:13:40 2012 +0100 - - Disable support for kqueue on MacOS/X. - - Apparently MacOS/X doesn't support kqueue events on character devices. - -commit 818c92e6583006bf2e38f1027044925df6cf0ca0 -Author: Guus Sliepen -Date: Wed Nov 14 10:44:35 2012 +0100 - - Remove text saying you must have one of PrivateKey or PrivateKeyFile in tinc.conf. - -commit e8bf81794f412b27261be0f2aa4eb287352041af -Author: Guus Sliepen -Date: Tue Nov 13 15:05:41 2012 +0100 - - Send broadcast packets using a random socket, and properly support IPv6. - - Before it would always use the first socket, and always send an IPv4 broadcast packet. That - works fine in a lot of situations, but it is better to try all sockets, and to send IPv6 packets - on IPv6 sockets. This is especially important for users that are on IPv6-only networks or that - have multiple physical network interfaces, although in the latter case it probably requires - them to use the ListenAddress variable to create a separate socket for each interface. - -commit 0870c7c32cf8a24f234fc066df867747ddb1ddc7 -Author: Guus Sliepen -Date: Tue Nov 13 15:01:43 2012 +0100 - - Don't take the address of a variable whose scope is about to disappear. - -commit bb3d7f3b31d4a429d1c31c6621d82f34dd552482 -Author: Guus Sliepen -Date: Sun Nov 11 19:01:28 2012 +0100 - - Fix configure script help text for --enable options. - -commit 5bfbb8f6c58307a8109f556caa30be122cc4d39f -Author: Guus Sliepen -Date: Sun Nov 11 19:01:02 2012 +0100 - - Fix index entry for section about readline library. - -commit 5766518589a5e6cc43ba77a4049059ead05fb300 -Author: Guus Sliepen -Date: Sun Nov 11 18:53:23 2012 +0100 - - Mention in the manual that support for LZO and zlib can be disabled. - -commit 6ec4596557d658f6c15c2cb9a96152c8c476118a -Author: Guus Sliepen -Date: Sun Nov 11 18:45:40 2012 +0100 - - Mention libcurses and libreadline in the manual. - -commit 0ee139e91431527015b7132e4c36f8d4ec09f66b -Author: Guus Sliepen -Date: Sat Nov 10 23:45:22 2012 +0100 - - Make sure PMTU discovery works in switch mode with VLAN tags. - - Before, when tinc saw a packet larger than the PMTU with a VLAN tag, it would - not know what to do with it, and would just forward it via TCP. Now, tinc - handles 802.1q packets correctly, as long as there is only one tag. - -commit ade4fccad6857f3d6d548e52bc94ab23751e4fef -Author: Guus Sliepen -Date: Sat Nov 10 23:13:05 2012 +0100 - - Using alloca() for a constant sized buffer is very silly. - - Cppcheck said using alloca() in the 21st century is silly anyway. - -commit b355476e917f377abb6434657933fcf4ffe6870a -Author: Guus Sliepen -Date: Sat Nov 10 23:09:31 2012 +0100 - - Fix potential buffer overflow reading the PID file. - - Found by cppcheck. - -commit edc08b73a9e353bde6db4c73866a6a730a1a7cb4 -Author: Guus Sliepen -Date: Sun Oct 21 17:45:16 2012 +0200 - - Slightly randomize all timeouts. - -commit 717ea66d7ba0c23f27d86b3d5c6992b751135455 -Author: Guus Sliepen -Date: Sun Oct 21 17:35:13 2012 +0200 - - Add the AutoConnect option. - - When set to a non-zero value, tinc will try to maintain exactly that number of - meta connections to other nodes. If there are not enough connections, it will - periodically try to set up an outgoing connection to a random node. If there - are too many connections, it will periodically try to remove an outgoing - connection. - -commit 1f8b70efa0dedbd3642e0ee82a640d125664af34 -Author: Guus Sliepen -Date: Sun Oct 21 17:34:53 2012 +0200 - - Keep track of the number of nodes in a tree. - -commit 0006c754f2e61e108aa2dd5a6ddd2e9b50d51bd6 -Author: Guus Sliepen -Date: Wed Oct 17 13:51:02 2012 +0200 - - Fix warnings from groff. - -commit 0db9e471ea53b48687ea247c855cd95ec453530c -Author: Guus Sliepen -Date: Sun Oct 14 19:22:30 2012 +0200 - - Releasing 1.1pre3. - -commit 3254e75afe0ff28fed68d8682f61c184f442161d -Author: Guus Sliepen -Date: Sun Oct 14 19:21:13 2012 +0200 - - Fix a few compiler errors/warnings. - -commit 70a1a5594af5d4e6a364186b42ba4e34c676009b -Author: Guus Sliepen -Date: Sun Oct 14 17:42:49 2012 +0200 - - Update copyright notices. - -commit 4200a378c4fedf64e89b9f8481d7cd09dac14965 -Author: Guus Sliepen -Date: Sun Oct 14 16:39:16 2012 +0200 - - Fix compile error on Windows. - -commit 368727c3dac4a1f8343e2e0eccf5bc62d9b197e2 -Author: Guus Sliepen -Date: Sun Oct 14 16:07:35 2012 +0200 - - tincctl: add node colors and edge weight to graph dump. - -commit 40ed0c07dd3d4667054b0f5952b89ee39686493b -Author: Guus Sliepen -Date: Sun Oct 14 15:37:24 2012 +0200 - - Log more messages using logger(). - -commit b234304b6628aeddce63d7f751da97c3344bbb78 -Author: Guus Sliepen -Date: Sun Oct 14 14:48:35 2012 +0200 - - Make sure the ReplayWindow option works for SPTPS as well. - -commit ee1d655f2f1ede6da66b6268974d6f9585c616b3 -Author: Guus Sliepen -Date: Sun Oct 14 14:45:27 2012 +0200 - - Only log success of initial datagram SPTPS handshake. - -commit 44a24f63acc70d19904e5540986b8301b3c9b882 -Author: Guus Sliepen -Date: Sun Oct 14 14:33:54 2012 +0200 - - Fix handling of initial datagram SPTPS packet. - - Only the very first packet of an SPTPS session should be send with REQ_KEY, - this signals the peer to abort any previous session and start a new one as - well. - -commit ec1f7e525d046bcaeb8e7040b8cec9a34a568371 -Author: Sven-Haegar Koch -Date: Fri Oct 12 17:08:01 2012 +0200 - - sptps.c: Add missing newline to log message. - -commit 94ec8d34db0ddef14b5446975663e5ff37e27b45 -Author: Guus Sliepen -Date: Thu Oct 11 22:47:13 2012 +0200 - - Strip newline from incoming SPTPS requests. - - Most of the code doesn't care whether requests are terminated with a newline or - not, except that when requests are forwarded, it is assumed they do not have - one and a newline is added. When a node using SPTPS receives a request from - another SPTPS-using node, and forwards it to a non-SPTPS-using node, this will - result in two consecutive newlines, which the latter node will see as an empty, - and thus invalid, request. - -commit 45944e4514a7765f858fa33cc1d9719a603099e0 -Author: Guus Sliepen -Date: Thu Oct 11 22:21:30 2012 +0200 - - Clear status and options fields of unreachable nodes. - -commit d917c8cb6b69475d568ccbe82389b9f2b3eb5e80 -Author: Guus Sliepen -Date: Wed Oct 10 17:17:49 2012 +0200 - - Fix whitespace. - -commit 58f4b845b9a7d83739af77337f2ce263d8df7838 -Author: Guus Sliepen -Date: Wed Oct 10 14:46:22 2012 +0200 - - Try all known addresses of node during the PMTU discovery phase. - - This helps in situations where some nodes have IPv6 and others have not. - -commit 0ed0cc6f9c30537bd74222fd99a41726d488dd37 -Author: Guus Sliepen -Date: Tue Oct 9 17:49:09 2012 +0200 - - Fix hash functions for keys whose size is not divisible by 4. - -commit d1ec010660905ae0b99d783737350ccc08b37b16 -Author: Guus Sliepen -Date: Tue Oct 9 16:27:28 2012 +0200 - - Fix memory leaks found by valgrind. - -commit 72642b40b3ad476101622da202b6f977a32b472f -Author: Guus Sliepen -Date: Tue Oct 9 15:52:58 2012 +0200 - - Clear Ethernet header when reading packets from a tun device. - - This fixes a warning from valgrind about uninitialized bytes, which were being - sent to other nodes. - -commit b346338f9c2de6f71d87cb4ad8e61b0af0052688 -Author: Guus Sliepen -Date: Tue Oct 9 13:28:09 2012 +0200 - - Remove unused variables, fix some #includes. - -commit f62b4a91344bd0de09e7fb4e4c8c1993ffc027c3 -Author: Guus Sliepen -Date: Tue Oct 9 13:23:12 2012 +0200 - - Fix deleting connections from the connection list. - -commit 0b8b23e0dd7219344543f135ca0aeba8a4a42d48 -Author: Guus Sliepen -Date: Mon Oct 8 00:35:38 2012 +0200 - - C99 extravaganza. - -commit ff306f0cdaedb50de1472e7c1fb55de922a6ca60 -Author: Guus Sliepen -Date: Sun Oct 7 21:59:53 2012 +0200 - - Replace the connection_tree with a connection_list. - - The tree functions were never used on the connection_tree, a list is more appropriate. - Also be more paranoid about connections disappearing while traversing the list. - -commit ce059e36fdb3d3049c278e8b2f36b03c93778996 -Author: Guus Sliepen -Date: Sun Oct 7 21:02:40 2012 +0200 - - Refactor outgoing connection handling. - - Struct outgoing_ts and connection_ts were depending too much on each other, - causing lots of problems, especially the reuse of a connection_t. Now, whenever - a connection is closed it is immediately removed from the list of connections - and destroyed. - -commit d93a37928b75b17ac5e1eae5c2d62fd0760a6608 -Author: Guus Sliepen -Date: Sun Oct 7 17:53:23 2012 +0200 - - Fix warnings from cppcheck. - -commit 5d0812d49275ec8bda2b5b0ac813239045463777 -Author: Guus Sliepen -Date: Sun Oct 7 14:06:47 2012 +0200 - - Remove a debug message. - -commit c2a9ed9e98e3dc4218c74fff774ddfe654adfd72 -Author: Guus Sliepen -Date: Sun Oct 7 14:03:50 2012 +0200 - - Handle packets encrypted via SPTPS that need to be forwarded via TCP. - -commit bb6b97ce3493d49b79f1bd57fdac420c312ef8d6 -Author: Guus Sliepen -Date: Sun Oct 7 13:31:19 2012 +0200 - - Make datagram SPTPS key exchange more robust. - - Similar to old style key exchange requests, keep track of whether a key - exchange is already in progress and how long it took. If no key is known yet - or if key exchange takes too long, (re)start a new key exchange. - -commit b99af2f813b897e1fd49c87a7cf44241cad3a017 -Author: Guus Sliepen -Date: Sun Oct 7 11:45:54 2012 +0200 - - Useful error messages when writing to a meta connection fails. - -commit e05371346548dee977d4ee45e12e3058e749afb6 -Author: Guus Sliepen -Date: Sat Oct 6 21:16:17 2012 +0200 - - When terminating, keep control connections open until the end. - - This ensures all device files and listening sockets have been closed before - tincctl gets notified of tincd's termination. - -commit 86116bb022f0b885638ff9ba21b359fc9f55286a -Author: Guus Sliepen -Date: Sat Oct 6 21:15:19 2012 +0200 - - Clear connection options and status fields in free_connection_partially(). - - Most fields should be zero when reusing a connection. In particular, when an - outgoing connection to a node which is reachable on more than one address is - made, the second connection to that node will have status.encryptout set but - outctx will be NULL, causing a NULL pointer dereference when - EVP_EncryptUpdate() is called in send_meta() when it shouldn't. - -commit ef9358c0d616c5ff3391c8ec3da5d357286a4457 -Author: Guus Sliepen -Date: Sat Oct 6 17:45:03 2012 +0200 - - Improve starting/stopping tincd using tincctl. - - When starting tincd, tincctl now strips non-options from the command line, and - sets argv[0] to the name of the tincd command instead of copying its own - command name. - - When stopping a running tincd, tincctl now waits for it to terminate. - -commit 47f33e07ff90b557cfa96999e921d35ea537ca80 -Author: Guus Sliepen -Date: Sat Oct 6 16:53:43 2012 +0200 - - Fix off-by-one error. - - Apart from writing 1 byte beyond an array allocated on the stack, this slipped - an unitialized byte in the seed used for key generation. - -commit 20b441a6de743b2149df59cfb94a7663e1924fa3 -Author: Guus Sliepen -Date: Mon Oct 1 10:42:13 2012 +0200 - - Libreadline might depend on libcurses. - -commit 3887e6dcb54494ee11798e721e274e06b0a5621a -Author: Guus Sliepen -Date: Mon Oct 1 10:39:15 2012 +0200 - - Remove abort() call that accidentily sneaked into commit dd1b69e. - -commit 0b0949e5bb63f9545feb4714812e2aa2112fb092 -Author: Guus Sliepen -Date: Mon Oct 1 10:36:23 2012 +0200 - - Make sure sptps_test compiles without -flto. - -commit b381acd60dbadbb4bc679d35a7d86bf425f21f86 -Author: Guus Sliepen -Date: Sun Sep 30 23:12:43 2012 +0200 - - Remove unused function declaration. - -commit dd1b69e31f83e2cc200ecc10e6d927373823332b -Author: Guus Sliepen -Date: Sun Sep 30 22:43:48 2012 +0200 - - Fix not reading Port statement from host config file. - -commit 6dfdb323612184529b4b83c1be914dda8262de47 -Merge: 9e76c464 c4940a5c -Author: Guus Sliepen -Date: Sun Sep 30 15:00:47 2012 +0200 - - Merge branch 'master' into 1.1 - - Conflicts: - lib/utils.c - src/net_setup.c - src/process.c - src/protocol_auth.c - src/protocol_key.c - src/utils.h - -commit c4940a5c888d85b4c477b6face5e9a618e64718d -Author: Guus Sliepen -Date: Sun Sep 30 13:45:47 2012 +0200 - - Add strict checks to hex to binary conversions. - - The main goal is to catch misuse of the obsolete PrivateKey and PublicKey - statements. - -commit 3bd810ea79d6933839ddac4a2cf1445c51947d38 -Author: Guus Sliepen -Date: Sun Sep 30 13:45:39 2012 +0200 - - Attribution for Martin Schürrer. - -commit 5a161e86cf35351f5274d7a8e17fef4630b40686 -Author: Martin Schürrer -Date: Sun Sep 30 02:04:55 2012 +0200 - - Output details of encryption errors - -commit 9e76c464b26b066e1eb3aa5232e573792e28020d -Author: Guus Sliepen -Date: Fri Sep 28 17:51:48 2012 +0200 - - Remove some debugging messages. - -commit e971130b601064090815c31c90b876e3d0d1d5b1 -Author: Guus Sliepen -Date: Fri Sep 28 17:36:25 2012 +0200 - - Make tincctl robust against dropped control connections. - -commit c5325ffdd1c6749beaf842c272eb28ecd5a070b6 -Author: Guus Sliepen -Date: Fri Sep 28 17:05:01 2012 +0200 - - Correctly add/remove outgoing connections when reloading configuration. - -commit f417271ea1447589ea05901f54fbb0377e7afaf9 -Author: Guus Sliepen -Date: Fri Sep 28 17:03:14 2012 +0200 - - Fix column sorting, make all lists sortable. - -commit aee86011ff2d389832fc9a23081ea23ab8484607 -Author: Guus Sliepen -Date: Thu Sep 27 22:12:15 2012 +0200 - - Let the GUI handle the new dump format. - -commit fac5593f44e47f3bd4f4b425ada38ab49fbe3b42 -Author: Guus Sliepen -Date: Thu Sep 27 17:19:02 2012 +0200 - - Fix links in documenation. - -commit 2e09986a1fd6dc5b6313f10e5d86aaaf4a531235 -Author: Guus Sliepen -Date: Thu Sep 27 17:18:49 2012 +0200 - - Fix links in documentation. - -commit f70cbc9d3ee3a88cf956592007e57f7a1dde2c17 -Author: Guus Sliepen -Date: Thu Sep 27 15:45:02 2012 +0200 - - Comment out old public/private keys when generating new ones. - -commit 38dbc63f118dbfdb955b56740b8c20a9379fb3ba -Author: Guus Sliepen -Date: Wed Sep 26 23:56:21 2012 +0200 - - Update documentation of the "dump graph" command. - -commit 1f312137d5ab12a2d996d5f7972f169aeb852040 -Author: Guus Sliepen -Date: Wed Sep 26 23:52:36 2012 +0200 - - Allow dumping either directed or undirected graphs. - - Internally, tinc maintains a directed graph of the meta connections between - nodes. However, this causes graphviz to draw two lines between nodes, which is - not always desirable. The "dump graph" command now defaults to dumping an - undirected graph, the "dump digraph" command will dump a directed graph. - -commit d6388d782ede1bbe49a5c2643362e2e0f383fa89 -Author: Guus Sliepen -Date: Wed Sep 26 23:18:32 2012 +0200 - - Let tincctl parse and format dumps. - - At the moment it just reproduces the old format. - -commit 9ade39b7d5564fb6f5a41946c9a23cfa7851a19f -Author: Guus Sliepen -Date: Wed Sep 26 22:20:43 2012 +0200 - - Keep last known address and time since reachability changed. - - This allows tincctl info to show since when a node is online or offline. - -commit 1e5deec973cd366b9d9cec6c1314a97e7051ce0f -Author: Guus Sliepen -Date: Tue Sep 25 22:28:08 2012 +0200 - - Remove remnants of Ethertap and old TUNSETIFF ioctl(). - -commit 125dd0dbcf4f46033ead3486044eb00b413fe537 -Author: Guus Sliepen -Date: Tue Sep 25 22:12:36 2012 +0200 - - Fix typo in manpage. - -commit 72f08932cf6f1ac0cfb837d377b423207e8c671a -Author: Guus Sliepen -Date: Mon Sep 24 14:56:00 2012 +0200 - - Don't ignore Makefile.am. - -commit 66e702d90d83977dc089736d7e4146330bc5df28 -Author: Guus Sliepen -Date: Mon Sep 24 14:02:07 2012 +0200 - - Attribution for Vil Brekin and some code style cleanups. - -commit f421a640777bd9484c59fa6feacadcf3e05d4b44 -Author: Vilbrekin -Date: Sat Aug 25 20:32:38 2012 +0200 - - Android cross-compilation instructions. - -commit afe4bf62eccab76c75e5a661fb2c16f1391a8417 -Author: Vilbrekin -Date: Sat Aug 25 20:01:11 2012 +0200 - - Use __ANDROID__ define rather than dirty hard-code to allow android NDK cross-compilation. - -commit c6720f1a608d19c722d8601fab1048773dbad59b -Author: Vilbrekin -Date: Sat Aug 25 19:59:26 2012 +0200 - - Add basic .gitignore file, cleaning (most) files generated by autotools. - -commit f2570c1b7f5813e087c867cf002f36f0c09b5cfa -Author: Vilbrekin -Date: Sat Aug 25 19:14:00 2012 +0200 - - Replace hard-code with new ScriptsInterpreter configuration property. - - This new setting allows choosing a custom script interpreter used for the various tinc callbacks. - If none is specified, the script itself is called as executable (as before). - This is particularly useful when storing tinc configuration and script on a mount point with no-exec attribute. - -commit 8a6f278fd2606c0a8f133f05df83b2649eacf6c3 -Author: Vilbrekin -Date: Wed Aug 22 10:46:24 2012 +0200 - - Basic patch for android cross-compilation. - - Commented non-existing functions in android NDK. - Prefix scripts execution with shell binary to allow execution on no-exec mount points. - Everyything is currently hard coded, while it should use pre-compiler variables... - -commit 2dc8deb1047a076d1c040f47bedf36ad4b41b17c -Author: Guus Sliepen -Date: Thu Sep 13 21:35:29 2012 +0200 - - Ensure sptps_test compiles with -flto. - -commit 90f1cba1fd9e748ec4b8274511d5a36ec1a24d9d -Author: Guus Sliepen -Date: Wed Sep 5 13:05:48 2012 +0200 - - Replace node_udp_tree with a hash table. - -commit 4c05afd19acada4781e1b8865cf702b197882e5d -Author: Guus Sliepen -Date: Wed Sep 5 12:45:36 2012 +0200 - - Use hash tables to lookup owners of addresses. - -commit 6b6a025488f289f749498a7e6cc1994be19f53e8 -Author: Guus Sliepen -Date: Wed Sep 5 12:44:41 2012 +0200 - - Add a simple hash table implementation. - -commit e9de08be0dab58a48f9a8ce3d250516cf05d6b8e -Author: Guus Sliepen -Date: Tue Sep 4 14:21:50 2012 +0200 - - Remove newlines at end of log messages. - -commit 05dac63dbc03dc5a64a7f4b50e24eb3766135916 -Author: Guus Sliepen -Date: Tue Sep 4 14:16:05 2012 +0200 - - Remove some debug messages. - -commit 742f7bb04e72d93f2c4a858534144a599b3fc14d -Author: Guus Sliepen -Date: Thu Aug 30 14:21:23 2012 +0200 - - Properly handle SPTPS packets with stripped Ethernet headers. - -commit d74b81b61e87c66d364a8590a48d87773ad2652c -Author: Guus Sliepen -Date: Thu Aug 30 14:00:34 2012 +0200 - - Fix node name check for "connect" and "disconnect" commands. - -commit 5567c0d4107e6ff6f4639d8664651841bd59ddad -Author: Guus Sliepen -Date: Sun Aug 5 17:25:31 2012 +0200 - - Quit when "exit" or "quit" commands are used in tincctl's shell. - -commit d18519ae21345fea68dd7f0f5525adba3a7639a9 -Author: Guus Sliepen -Date: Sun Aug 5 17:03:57 2012 +0200 - - Fix segfault when using tincctl's shell without readline. - -commit b332bd964663b7109a5fc4be596d36fbf1dbaa47 -Author: Guus Sliepen -Date: Sun Aug 5 13:50:51 2012 +0200 - - Add bash completion script. - -commit e29e0fee8812851473bcf24324a15cbf3cc854a0 -Author: Guus Sliepen -Date: Fri Aug 3 14:17:02 2012 +0200 - - Make sure the top command can be used more than once in tincctl's shell. - -commit a57db1dfe0736fd902a45ed5f695630faf3f0e1e -Author: Guus Sliepen -Date: Fri Aug 3 14:15:50 2012 +0200 - - Fork when using the "start" command in tincctl. - - This allows the command to be given in its shell without immediatly exiting tincctl. - -commit 36c6afede36b6956bd86df824f5616c1afee35ed -Author: Guus Sliepen -Date: Fri Aug 3 13:23:07 2012 +0200 - - Add readline completion for tincctl config and tincctl info. - -commit 8af2f3f5a4061a8dbfd4f7d259e0038df06a373e -Author: Guus Sliepen -Date: Thu Aug 2 17:44:59 2012 +0200 - - Optionally compress and/or strip Ethernet header from SPTPS packets. - -commit 73348be58ecb9c40cf435122a00e72ac4d1a4c9b -Author: Guus Sliepen -Date: Thu Aug 2 17:24:42 2012 +0200 - - Have tincctl act as a shell when no command is given. - - By default it uses readline to read commands. If the input and output are not a - tty, no prompt is shown. - -commit 91937812bdfe74699e4f7cdf86265d07423acbba -Author: Guus Sliepen -Date: Thu Aug 2 17:23:51 2012 +0200 - - Clear struct sptps before reusing it. - -commit 6bcd03c2027636f82ab7228566717d112df7bc6d -Author: Guus Sliepen -Date: Wed Aug 1 22:22:52 2012 +0200 - - Update the documentation to encourage using "tincctl init" and "tincctl config". - -commit 6396f42d74f22ab5f8e736dc5cb04c57917f9319 -Author: Guus Sliepen -Date: Wed Aug 1 16:51:59 2012 +0200 - - Stricter checks for netname and node names. - - - Node names should not be empty. - - Net names should not contain slashes or start with a dot, because they are - used in pathnames. - -commit 61006ced88e1bf62e8883216cabc636f2d4cb12a -Author: Guus Sliepen -Date: Wed Aug 1 16:13:23 2012 +0200 - - Add missing configuration variables. - -commit b0f3a76e9bf8ceeab75c1e6f4dce6763aecddc5e -Author: Guus Sliepen -Date: Wed Aug 1 15:50:45 2012 +0200 - - Add the ability to query configuration variables to tincctl. - -commit a9caa2a6ea3aa553c9d2140ad4f5b34b7ab7297b -Author: Guus Sliepen -Date: Wed Aug 1 15:15:37 2012 +0200 - - tincctl restart should work even if no tincd is running. - -commit 07980b056c5371f8b6fdd50172f501be07155bdf -Author: Guus Sliepen -Date: Wed Aug 1 15:14:48 2012 +0200 - - Try sending SIGTERM if we cannot connect to a tincd but we know its PID. - -commit 7a71d48009e03ff1143a6e1084803f456a27c849 -Author: Guus Sliepen -Date: Tue Jul 31 21:43:49 2012 +0200 - - Use a status bit to track which nodes use SPTPS. - -commit 6bc8df3e010509f69af95d2cc14ec893def6f644 -Author: Guus Sliepen -Date: Tue Jul 31 20:39:15 2012 +0200 - - Add Brandon Black's replay window code to SPTPS. - -commit 5ede437307cc3bbb20431f4b82f4a2ef79c9b746 -Author: Guus Sliepen -Date: Tue Jul 31 20:36:35 2012 +0200 - - Handle SPTPS datagrams in try_mac(). - -commit aaff0ed08916f936b0a7b8a3d0607b8111b7a185 -Author: Guus Sliepen -Date: Tue Jul 31 20:29:13 2012 +0200 - - Remove unused #include. - -commit 153abaa4d940bf2bc9bd7275d5efe5c01c354190 -Author: Guus Sliepen -Date: Mon Jul 30 18:36:59 2012 +0200 - - Use datagram SPTPS for packet exchange between nodes. - - When two nodes which support SPTPS want to send packets to each other, they now - always use SPTPS. The node initiating the SPTPS session send the first SPTPS - packet via an extended REQ_KEY messages. All other handshake messages are sent - using ANS_KEY messages. This ensures that intermediate nodes using an older - version of tinc can still help with NAT traversal. After the authentication - phase is over, SPTPS packets are sent via UDP, or are encapsulated in extended - REQ_KEY messages instead of PACKET messages. - -commit 248d300f1be0d5f2aae39202041699ab2b46c56b -Merge: e1355e24 3391018e -Author: Guus Sliepen -Date: Fri Jul 27 22:48:24 2012 +0200 - - Merge branch 'master' into 1.1 - -commit 3391018efbd41858d42ccae6ae919749ba94c8db -Author: Guus Sliepen -Date: Fri Jul 27 22:43:01 2012 +0200 - - Also clarify hostnames=[yes|no] in tinc.conf(5). - -commit e895b358db8863d19dfa3d77c861ae19b76bc750 -Author: Mesar Hameed -Date: Tue Jul 24 07:18:50 2012 +0100 - - Minor clarification, tinc.conf hostnames=[yes|no] variable only resolves names for logging purposes. - -commit e1355e24eb7fe36bdb5dd7c818815fa266046a51 -Author: Guus Sliepen -Date: Sun Jul 22 13:05:56 2012 +0200 - - Remove unused po/ directory. - -commit 6c9b33c8b67374d38525b88f292840034c559a45 -Author: Guus Sliepen -Date: Sun Jul 22 12:55:04 2012 +0200 - - Have tinc-gui use same way of locating pidfile as tincd and tincctl. - -commit 2b97a7d7cf6ca7f4d84d3df754062a55bdf55305 -Author: Guus Sliepen -Date: Sun Jul 22 12:52:31 2012 +0200 - - tincctl init now also creates a template tinc-up script. - -commit eb430005c74b6b5f717e7e264afa3bd35284740d -Author: Guus Sliepen -Date: Sat Jul 21 17:10:10 2012 +0200 - - Fix exit code when installing tincd as a service on Windows. - -commit e5e96882c3825cee81ff163490b2f39fad3192b8 -Author: Guus Sliepen -Date: Sat Jul 21 16:33:09 2012 +0200 - - Windows doesn't like quotes around "edit" when calling it through system(). - - Even though that works fine on the command line. - -commit 18237e1f2d9dd5eef4a4e0d746d016bf94a42ad4 -Author: Guus Sliepen -Date: Sat Jul 21 16:26:55 2012 +0200 - - Use backslashes on Windows. - - Although Windows itself supports the forward slash, some programs may not. - -commit 09a8ff649cc7aa51d291c89e1556526a6265cc81 -Author: Guus Sliepen -Date: Sat Jul 21 15:58:16 2012 +0200 - - Don't try to mkdir(CONFDIR) on Windows when there is a registry key for tinc. - -commit ed8ce60845dc0568840c64c692838136f342fa54 -Author: Guus Sliepen -Date: Sat Jul 21 15:51:15 2012 +0200 - - Fix crash when no netname is specified. - -commit 7303b512b0e4f0d9cbc3236e846b2618f527b830 -Author: Guus Sliepen -Date: Sat Jul 21 15:50:50 2012 +0200 - - Fix some compiler warnings. - -commit 33521eabd4501b4add35468618453ac4f76311f3 -Author: Guus Sliepen -Date: Sat Jul 21 15:15:04 2012 +0200 - - Have tincd and tincctl use the same method of determining netname. - -commit 1d322d2eda8223f21b0c00381af34b94054f251a -Author: Guus Sliepen -Date: Sat Jul 21 15:02:44 2012 +0200 - - Add a newline to a configuration file if it is missing. - -commit dea722c4aca9a8cfa463807d279aa10cc6a0fc64 -Author: Guus Sliepen -Date: Sat Jul 21 15:02:17 2012 +0200 - - Add some checks when changing configuration. - -commit cc0c35267f8fac4f82622ff73474ed1e2d3a1e36 -Author: Guus Sliepen -Date: Sat Jul 21 14:19:23 2012 +0200 - - Call event_init() after detaching. - - Otherwise, the call to daemon() could close filedescriptors in use by libevent - itself; for example if it uses kqueue or epoll instead of a select() or poll() - backend. - -commit 4e0fc52197546bbf8a0be7af946f4b569e13048c -Author: Guus Sliepen -Date: Sat Jul 21 13:53:22 2012 +0200 - - Fix various compiler warnings. - -commit b161088b35fad1d284855f6434a895a20e34a250 -Author: Guus Sliepen -Date: Sat Jul 21 13:38:14 2012 +0200 - - BSD make doesn't like $<. - -commit 98a72d686983178f71cd2bf336c1f3d5c647f1e7 -Author: Guus Sliepen -Date: Sat Jul 21 13:02:35 2012 +0200 - - Make sure sptps.h and info.h are in the tarball. - -commit 5eeed38b8eb15f4c0464675b7d8c7722bc8be168 -Author: Guus Sliepen -Date: Sat Jul 21 12:51:53 2012 +0200 - - Make sure tinc compiles on Windows. - -commit 1d4590ca5cae09ea3b7a7e80355639e20861d349 -Author: Guus Sliepen -Date: Fri Jul 20 20:35:07 2012 +0200 - - Prefer routes with lower weight as long as they do not increase the number of hops. - - This should improve traffic to nodes that are not directly reachable somewhat. - -commit 4c8ead98743254be97c830e942f0cc53539d780c -Author: Guus Sliepen -Date: Fri Jul 20 20:01:29 2012 +0200 - - Allow more configuration variables to be changed when reloading configuration. - - In particular, Subnets may be added or removed from the local node on the fly. - -commit c678e7c4fb52d93350eafaed0f666018ed469e10 -Author: Guus Sliepen -Date: Fri Jul 20 19:59:47 2012 +0200 - - Split setup_myself() into two functions, one for reloading configuration. - -commit 4591e96c76914795aaae317c067f16abc22fb2e0 -Author: Guus Sliepen -Date: Fri Jul 20 17:29:16 2012 +0200 - - Never remove items from cmdline_conf. - - We should treat cmdline_conf as const, so we can call read_config_options() - more than once with prefix = NULL. - -commit 68a20876d0c4a6c370064d78786dd9f2aa6273cb -Author: Guus Sliepen -Date: Fri Jul 20 01:02:51 2012 +0200 - - Use minor protocol version to determine whether to use ECDH key exchange between nodes. - -commit 76a3ada4eb4032172c3d780915a07680f9954d42 -Author: Guus Sliepen -Date: Tue Jul 17 18:05:55 2012 +0200 - - Put minor protocol version in connection options so other nodes can see it. - - This allows two nodes that do not have a meta-connection with each other see - which version they are. - -commit 68de7b481e54d6a7c573d9a2d61f76d4d3a6b2f9 -Author: Guus Sliepen -Date: Mon Jul 16 18:49:39 2012 +0200 - - When exporting configuration files, don't copy Name variables. - - These interfere with tincctl import. Besides, host configuration files should - not contain Name at all. - -commit c52c46f8717aac6904f32766d774fa3fdf9611d8 -Author: Guus Sliepen -Date: Mon Jul 16 16:48:24 2012 +0200 - - Add an easy way to export and import host configuration files. - -commit 6319dc9dde3b328ba800f25a6bb4cf303d27f664 -Author: Guus Sliepen -Date: Mon Jul 16 01:14:08 2012 +0200 - - Strip default subnet weight from output. - -commit 74646a4afa6557a0363cc85e0a95d578d4ab0ac2 -Author: Guus Sliepen -Date: Mon Jul 16 01:09:47 2012 +0200 - - Give an error message when tincctl info cannot parse the given subnet or address. - -commit 53735a9d964579829d089f4b7572aef50c4e1468 -Author: Guus Sliepen -Date: Mon Jul 16 01:05:25 2012 +0200 - - "tincctl info" gives more human readable information about nodes or subnets. - -commit 3c7003893fe2f82023d0d4f54b488bb7a16d0007 -Author: Guus Sliepen -Date: Mon Jul 16 00:52:50 2012 +0200 - - Move all functions related to subnet parsing to subnet_parse.c. - -commit e72e6febfeddbd4354560388c8e0e125a8017909 -Author: Guus Sliepen -Date: Sun Jul 15 22:53:03 2012 +0200 - - Fix tincctl dump. - -commit 9be8980a2bb6245da017270f85bd6da186fb433b -Author: Guus Sliepen -Date: Sun Jul 15 21:17:10 2012 +0200 - - Let tincctl ignore tincd options, so they will be passed on. - -commit 36dee4c539521578005eed5e58b4803b73f0c889 -Author: Guus Sliepen -Date: Sun Jul 15 21:15:35 2012 +0200 - - Fix tincctl start. - -commit 439069bda62b25baaabeb765ac0557efa57b6cfb -Author: Guus Sliepen -Date: Sun Jul 15 20:59:17 2012 +0200 - - Have tincctl notify a running tincd of configuration file changes. - -commit eb01fd96258e5f99be0e4930eac04e5487a108a0 -Author: Guus Sliepen -Date: Sun Jul 15 20:37:38 2012 +0200 - - Add an easy way to edit a configuration file. - -commit cedfeccb247abb00063316068d7d2ade880f9d09 -Author: Guus Sliepen -Date: Sun Jul 15 20:22:21 2012 +0200 - - Stricter checks for node names. - -commit 03f72c6173f27198e2e68227cb41e00f8ec4ddc9 -Author: Guus Sliepen -Date: Sun Jul 15 18:16:35 2012 +0200 - - Allow configuration variables to be added/removed using tincctl. - -commit dd102efd24d847c41890adfcc7ce6d9d2592dcdb -Author: Guus Sliepen -Date: Sun Jul 15 15:46:16 2012 +0200 - - Put every command in its own function. - -commit a444ec396456a25546a4ab3d185c7fb5e4bb7ae3 -Author: Guus Sliepen -Date: Sun Jul 15 14:49:36 2012 +0200 - - "tincctl init" creates initial directory structure, tinc.conf and keypairs. - -commit 268c8545aaf83b7433f43402f5c77e39e20006ef -Merge: bce17776 f13fd8c3 -Author: Guus Sliepen -Date: Sat Jul 14 15:13:21 2012 +0200 - - Merge branch 'master' into 1.1 - -commit f13fd8c35068cd1f776e33362dcac40be9499035 -Author: Guus Sliepen -Date: Thu Jul 12 11:32:08 2012 +0200 - - Update THANKS file. - -commit 2eb0043e1352944b1113c1f7e40f37dffac0021d -Author: Guus Sliepen -Date: Thu Jul 12 11:30:56 2012 +0200 - - Document how to load the tap driver on FreeBSD. - -commit ae8c0b65d8f97942d7eff5f96344f781b8dec35d -Author: Guus Sliepen -Date: Thu Jul 12 11:25:11 2012 +0200 - - Use /dev/tap0 by default on FreeBSD and NetBSD when using Mode = switch. - -commit bce177767d521b47efd458c5cd570959a98d940d -Author: Guus Sliepen -Date: Tue Jun 26 14:22:57 2012 +0200 - - Fix crash when handling the ALRM signal. - - In retry() the function do_outgoing_connection() is called, which can delete - items from the connection_tree, so when walking the tree we must first save the - pointer to the next item. - -commit 19be9cf7150858311f7898fa3fb525d692d02f64 -Merge: 62b61a1b 00e71ece -Author: Guus Sliepen -Date: Tue Jun 26 13:24:20 2012 +0200 - - Merge branch 'master' of git://tinc-vpn.org/tinc into 1.1 - - Conflicts: - NEWS - README - configure.in - lib/utils.c - src/linux/device.c - src/meta.c - src/net.h - src/net_setup.c - src/net_socket.c - src/protocol.c - src/protocol_auth.c - src/tincd.c - -commit 00e71ece25070dc919f9bc0696e4ff3a387360d0 -Author: Guus Sliepen -Date: Mon Jun 25 19:45:51 2012 +0200 - - Releasing 1.0.19. - -commit 236b0ba4ebba01e22e382e79897100338a039bbb -Author: Guus Sliepen -Date: Mon Jun 25 19:03:54 2012 +0200 - - Fix crash when using Broadcast = direct. - -commit 0a84f9cb8f52f2d2b4f03a5ad5ef9dfcd3509033 -Author: Guus Sliepen -Date: Mon Jun 25 19:01:51 2012 +0200 - - Fix compiler warnings. - -commit 62ee9b776d45af41c8b040ad86e50ba8f6f8e6c4 -Author: Guus Sliepen -Date: Mon Jun 25 15:01:42 2012 +0200 - - #include on Windows. - - MinGW complained about it not being included. - -commit c0af4c37d2046ffb3e07dd62f266a4fb99ea5614 -Author: Guus Sliepen -Date: Mon Jun 25 15:00:24 2012 +0200 - - Small fixes in proxy code. - -commit 62b61a1b7c2382b1bade142b3a41a9b27c1fd40d -Author: Guus Sliepen -Date: Sun May 13 22:16:42 2012 +0200 - - Don't forget to send a newline when forwarding requests. - -commit 42a8158b1dca6ee4ec1707176199cc36c26da7af -Author: Michael Tokarev -Date: Fri May 4 16:41:47 2012 +0400 - - add (errnum) in front of windows error messages - - On localized, non-English versions of windows, it is - common to have two active charsets -- for console applications - and for GUI applications, together with localized error messages - returned by windows. But two charsets are rarely compatible, - so sending the same byte sequence to console and to windows - event log makes one or another to be unreadable. So at least - include the error number, this way it will be possible to - lookup the actual error test using external ways. - - Signed-off-by: Michael Tokarev - -commit 58007d7efa3940c863c5a398f8b257a686ce37ba -Author: Guus Sliepen -Date: Tue May 8 16:44:15 2012 +0200 - - Always pass request strings to other functions as const char *. - -commit 291a59b5b732de084e392daea1433b1fdb9fbfd5 -Author: Sven-Haegar Koch -Date: Sun Apr 22 03:44:28 2012 +0200 - - free_connection_partially(): also reset remote protocol version infos - - The used remote protocol can change between two reconnects, aka if - the remote side has enabled/disabled for example their ExperimentalProtocols - setting. - -commit 32e5c5bb7c2c9127274247cb74cffa7345b04fad -Author: Sven-Haegar Koch -Date: Sun Apr 22 03:05:29 2012 +0200 - - Silence SPTPS log messages, reduce them from DEBUG_ALWAYS to DEBUG_META. - -commit c78bb143030162f0c820f08c87808e157c014a07 -Author: Sven-Haegar Koch -Date: Sun Apr 22 02:55:06 2012 +0200 - - terminate_connection(): delete non-outgoing (aka incoming) connections. - -commit 8b9e5af0d93069a81ce2ebed9899eedf3b7b184b -Author: Sven-Haegar Koch -Date: Sat Apr 21 03:44:24 2012 +0200 - - Label control connections for log output as "", not "". - -commit d3f4cf59ca917386e7c6358a98adbe3b8e9ce87a -Author: Sven-Haegar Koch -Date: Sat Apr 21 01:59:01 2012 +0200 - - free_connection_partially(): Avoid possible use-after-free for c->hischallenge - -commit 7a6ca7a993e5907497d97fef09e375698dde182f -Author: Sven-Haegar Koch -Date: Sat Apr 21 01:51:36 2012 +0200 - - terminate_connection(): only kill c->node->connection if it is pointing - to the same connection - -commit a96c4f016c9fff2392d85f762e16f5430c0b6463 -Author: Sven-Haegar Koch -Date: Fri Apr 20 00:24:38 2012 +0200 - - terminate_connection(): Avoid use-after-free and double-free for - already freed edge structure. - -commit 5c0dd104f94519c3cb50e9ca44227656c5adc7ae -Author: Guus Sliepen -Date: Thu Apr 19 15:56:08 2012 +0200 - - Document new proxy types. - -commit 5ae19cb0bb8dd6be1e9bcd560bb051f496a373ec -Author: Guus Sliepen -Date: Thu Apr 19 15:18:31 2012 +0200 - - Add support for proxying through an external command. - - Proxy type "exec" can be used to have an external script or binary set - up an outgoing connection. Standard input and output will be used to - exchange data with the external command. The variables REMOTEADDRESS and - REMOTEPORT are set to the intended destination address and port. - -commit fb5588856fa4dd6f140c72f7360302fe85b20c75 -Author: Guus Sliepen -Date: Thu Apr 19 14:10:54 2012 +0200 - - Add support for SOCKS 5 proxies. - - This only covers outgoing TCP connections, and supports only - username/password authentication or no authentication. - -commit b58d95eb29662bce4388f95dbc5762b9e2999806 -Author: Guus Sliepen -Date: Wed Apr 18 23:19:40 2012 +0200 - - Add basic support for SOCKS 4 and HTTP CONNECT proxies. - - When the Proxy option is used, outgoing connections will be made via the - specified proxy. There is no support for authentication methods or for having - the proxy forward incoming connections, and there is no attempt to proxy UDP. - -commit 84531fb6e621959e06519fdbb7f2a8f7578f66bd -Author: Guus Sliepen -Date: Mon Apr 16 01:57:25 2012 +0200 - - Allow broadcast packets to be sent directly instead of via the MST. - - When the "Broadcast = direct" option is used, broadcast packets are not sent - and forwarded via the Minimum Spanning Tree to all nodes, but are sent directly - to all nodes that can be reached in one hop. - - One use for this is to allow running ad-hoc routing protocols, such as OLSR, on - top of tinc. - -commit 9ebb34f907e8a15cb71dd20b111270d80bad1e96 -Author: Guus Sliepen -Date: Mon Apr 16 01:16:59 2012 +0200 - - Update README to reflect that only OpenSSL is currently supported. - -commit a851d8a9f6e3b69ab75695d84471ff4d525341b7 -Author: Guus Sliepen -Date: Mon Apr 16 01:14:59 2012 +0200 - - Add autoconf checks for OpenSSL's elliptic curve functions. - -commit f8e15dfe8d155b5bdb1e39bf6b9af486606145e8 -Author: Sven-Haegar Koch -Date: Sat Apr 14 02:28:43 2012 +0200 - - ecdh & ecdsa: avoid some possible memory leaks in error conditions. - -commit 8792b9a9f343e751dc3cfd789db9528da609ba9f -Author: Sven-Haegar Koch -Date: Sat Apr 14 02:02:11 2012 +0200 - - Remove confusing error message for failed reading in ECDSA keys. - - Most likeley the error is that there just is no valid key inside the used - host file, and in this case errno just contains a random value from the - last previously failed call. - -commit a5bb6d40fb517aa175510ec179091e4f9ffaf6f6 -Author: Sven-Haegar Koch -Date: Sat Apr 14 02:29:32 2012 +0200 - - sptps_stop(): clear pointers after free to avoid double free. - - sptps_stop() may get called twice on some failed connection setups. - -commit 535a55100bb77f107c85361e9f72a194e92bc8bc -Author: Guus Sliepen -Date: Thu Mar 29 16:45:25 2012 +0100 - - Allow environment variables to be used for Name. - - When the Name starts with a $, the rest will be interpreted as the name of an - environment variable containing the real Name. When Name is $HOST, but this - environment variable does not exist, gethostname() will be used to set the - Name. In both cases, illegal characters will be converted to underscores. - -commit 1d9dacb1f26971e19463b5501c2410c57f780ecb -Merge: 86c29903 89f4574e -Author: Guus Sliepen -Date: Mon Mar 26 19:06:39 2012 +0100 - - Merge branch 'master' of git://tinc-vpn.org/tinc into 1.1 - - Conflicts: - src/logger.c - src/net_setup.c - -commit 89f4574e0b1553c8e5dcbfc275e829a759b697f6 -Author: Guus Sliepen -Date: Mon Mar 26 14:46:09 2012 +0100 - - Add support for systemd style socket activation. - - If the LISTEN_FDS environment variable is set and tinc is run in the - foreground, tinc will use filedescriptors 3 to 3 + LISTEN_FDS for its listening - TCP sockets. For now, tinc will create matching listening UDP sockets itself. - - There is no dependency on systemd or on libsystemd-daemon. - -commit cc6aee784659bfbd21eb8d414e00a8f1a801cac4 -Author: Guus Sliepen -Date: Mon Mar 26 14:45:20 2012 +0100 - - Remove newline from log message. - -commit 16e6769feef21a5bf58f6022d990452987bb5efb -Author: Anthony G. Basile -Date: Mon Mar 26 06:29:40 2012 -0400 - - configure.in: fix AC_ARG_ENABLE and AC_ARG_WITH - - The current configure.in file does not correctly make use of these - macros. The resulting configure file will therefore enable an item - even if --disable-FEATURE is given. This patch restores the intended - behavior. - -commit 86c2990327fdf7ec1197aa73cb2b9a926a734db4 -Merge: d7bf63c6 b23681dd -Author: Guus Sliepen -Date: Sun Mar 25 23:35:31 2012 +0100 - - Merge branch 'master' of git://tinc-vpn.org/tinc into 1.1 - - Conflicts: - NEWS - README - configure.in - src/Makefile.am - src/conf.c - src/conf.h - src/connection.c - src/net.c - src/tincd.c - -commit b23681dddb8987571f04d46fc14f0ba012a7929c -Author: Guus Sliepen -Date: Sun Mar 25 22:54:36 2012 +0100 - - Support :: in IPv6 Subnets. - -commit 482c6119a7ae80f320e5b519ef2e785e04a77b8e -Author: Guus Sliepen -Date: Sun Mar 25 15:32:26 2012 +0100 - - Releasing 1.0.18. - -commit 64c657b32d1eb34eb669c6d5b0ec26c1a643b194 -Author: Guus Sliepen -Date: Sun Mar 25 15:30:58 2012 +0100 - - Mark DecrementTTL option experimental. - -commit f71ce341800739c7cdee01d7cf025e7492da22ac -Author: Guus Sliepen -Date: Sun Mar 25 15:17:50 2012 +0100 - - Fix return type of vde_recv() as well. - - In this case it is not really necessary as the conversion to int will already - take care of ensuring the return value is treated as signed. - -commit 6225b1884a25af4debc2d0821a4c377ddbaec696 -Author: Guus Sliepen -Date: Sun Mar 25 14:55:56 2012 +0100 - - Document OpenBSD "ifconfig link0" and Linux "ip tuntap" commands. - -commit 399835385380d485416d6d59a8f27ce71f1db644 -Author: Guus Sliepen -Date: Sun Mar 25 14:46:50 2012 +0100 - - Fix some more compiler warnings. - -commit cfe6558d4ba4f572311aeafd62737f6f2692ad86 -Author: Guus Sliepen -Date: Sun Mar 25 14:00:21 2012 +0100 - - Fix return value type of vde_send(). - - The libvdeplug_dyn.h header file incorrectly declares the return type of - vde_send() to size_t, while in reality it is ssize_t. - -commit 95968c67f9df9102ddbce5b7c8d34107989ad51a -Author: Guus Sliepen -Date: Sun Mar 25 13:58:14 2012 +0100 - - Fix compiler warnings. - -commit e2d1b0b899ef66cd7ff227549e58b96c292f784e -Author: Guus Sliepen -Date: Sun Mar 25 13:42:10 2012 +0100 - - Allow scoped addresses to be used for IPv6 multicast socket. - -commit 251204063255d95910f9a079015e2f9b428fd983 -Author: Guus Sliepen -Date: Sun Mar 25 13:40:55 2012 +0100 - - Add #ifdefs in case not all platforms support IPv4 and IPv6 multicast. - -commit b5e3bf1a85462f0c41638c11305d28f87af24395 -Author: Guus Sliepen -Date: Fri Mar 23 13:18:36 2012 +0100 - - Set default value of DecrementTTL to "no". - - Decrementing the TTL causes IPv6 to fail when Mode = switch, and there may be - other unforeseen side-effects. - -commit c373de2e9812700c0568640727ad917b6fc7d758 -Author: Guus Sliepen -Date: Wed Mar 21 17:00:53 2012 +0100 - - Add support for multicast communication with UML/QEMU/KVM. - - DeviceType = multicast allows one to specify a multicast address and port with - a Device statement. Tinc will then read/send packets to that multicast group - instead of to a tun/tap device. This allows interaction with UML, QEMU and KVM - instances that are listening on the same group. - -commit a7dbb50c23f447a23b543c92ec096ff178bc2de3 -Author: Guus Sliepen -Date: Wed Mar 21 13:20:15 2012 +0100 - - Allow a port to be specified in BindToAddress statements. - - This can be used to let tinc listen on multiple ports for incoming connections. - -commit 80e15d8b96e5313b33c91003b1f75d7f6db9924e -Author: Guus Sliepen -Date: Tue Mar 20 23:49:16 2012 +0100 - - Always try next Address when an outgoing connection fails to authenticate. - - When making outgoing connections, tinc goes through the list of Addresses and - tries all of them until one succeeds. However, before it would consider - establishing a TCP connection a success, even when the authentication failed. - This would be a problem if the first Address would point to a hostname and port - combination that belongs to the wrong tinc node, or perhaps even to a non-tinc - service, causing tinc to endlessly try this Address instead of moving to the - next one. - - Problem found by Delf Eldkraft. - -commit d7bf63c63ab397cf3e5ca4a065922364925788e7 -Author: Guus Sliepen -Date: Sun Mar 18 21:24:46 2012 +0100 - - Make sure the signature also covers the session label. - -commit 42a0b61076d5d0f6391f0dd5c2c400b8fb89c5c5 -Author: Guus Sliepen -Date: Sun Mar 18 20:38:48 2012 +0100 - - Start documenting the SPTPS protocol. - -commit d756bb92ed52d5b1ecdd42af32f11f733db64d91 -Author: Guus Sliepen -Date: Sun Mar 18 17:46:30 2012 +0100 - - Don't send an ACK message after the first key exchange in the SPTPS protocol. - -commit c970ecdd75d4e7b3203a788f28b6e40cd532759b -Author: Guus Sliepen -Date: Sun Mar 18 17:42:43 2012 +0100 - - Test SPTPS messages sent while key renegotation is in progress. - -commit 3a4fe104a06b73fd19c550546e7c65a59ff2afe3 -Author: Guus Sliepen -Date: Sun Mar 18 16:42:02 2012 +0100 - - Add datagram mode to the SPTPS protocol. - - * Everything is identical except the headers of the records. - * Instead of sending explicit message length and having an implicit sequence - number, datagram mode has an implicit message length and an explicit sequence - number. - * The sequence number is used to set the most significant bytes of the counter. - -commit 03e06fd43aff73b4a5c9d367968a1279371ae252 -Author: Guus Sliepen -Date: Sun Mar 18 16:41:13 2012 +0100 - - Allow CTR mode counter to be set to a specific value. - -commit 28a1501b9a8b4c730f7f965d6b2e8fc50feba261 -Author: Guus Sliepen -Date: Sat Mar 10 13:31:36 2012 +0100 - - Releasing 1.0.17. - -commit 4712d8f92e63e86e835ffb624d6399343ee568ea -Author: Guus Sliepen -Date: Sat Mar 10 13:23:08 2012 +0100 - - Update copyright notices. - -commit 5b0f5ad958d6db4e73aebc5ee6c608cdae81b7b5 -Author: Guus Sliepen -Date: Thu Mar 8 23:23:39 2012 +0100 - - Make sure disabling old RSA keys works on Windows. - - Seeking in files and rewriting parts of them does not seem to work properly on - Windows. Instead, when old RSA keys are found when generating new ones, the - file containing the old keys is copied to a temporary file where the changes - are made, and that file is renamed back to the original filename. On Windows, - we cannot atomically replace files with a rename(), so we need to move the - original file out of the way first. If anything fails, the new code will warn - that the user has to solve the problem by hand. - -commit 2f1c337c541fcb7e2c62aeeab245ff7a43eb51a5 -Author: Guus Sliepen -Date: Thu Mar 8 22:19:20 2012 +0100 - - Add missing ICMP6 message type definitions. - -commit 40c28589328a2aa96c2ce1419c5d90616c758b3d -Merge: 8ac096b5 9dea33f5 -Author: Guus Sliepen -Date: Thu Mar 8 21:15:08 2012 +0100 - - Merge branch 'master' of git://tinc-vpn.org/tinc into 1.1 - - Conflicts: - src/net_packet.c - -commit 9dea33f5301119dd4423eb962956cf2d246af3f3 -Author: Guus Sliepen -Date: Wed Mar 7 10:40:06 2012 +0100 - - Accept Subnets passed with the -o option when StrictSubnets = yes. - -commit 63f8303a5dc1758876451a580a8317dbc3d295d6 -Author: Guus Sliepen -Date: Fri Mar 2 16:09:58 2012 +0100 - - Only log errors sending UDP packets when debug level >= 5. - - Since tinc will fall back to TCP or route via another node, it is not necessary - to log such errors unconditionally. - -commit 8ac096b5bf9da1b3961a3ac4a03d083629222a63 -Author: Guus Sliepen -Date: Sun Feb 26 18:37:36 2012 +0100 - - Allow log messages to be captured by tincctl. - - This allows tincctl to receive log messages from a running tincd, - independent of what is logged to syslog or to file. Tincctl can receive - debug messages with an arbitrary level. - -commit a1bd3a291379492c8ffecd53792065dc20a28c79 -Author: Guus Sliepen -Date: Sun Feb 26 16:56:53 2012 +0100 - - Don't close control connections when handling a reload command. - - Because this would terminate the connection while the control message - handler was still running, it would lead to a segmentation fault later - on. - -commit 483c5dcfb43719e5fd50902641252e28a04fd74e -Merge: 344d6b9a ae524961 -Author: Guus Sliepen -Date: Sun Feb 26 16:27:13 2012 +0100 - - Merge branch 'master' of git://tinc-vpn.org/tinc into 1.1 - -commit ae5249610954af17c68c547bb1b45ad286ad647e -Author: Guus Sliepen -Date: Sun Feb 26 16:23:02 2012 +0100 - - Only use broadcast at the start of the PMTU discovery phase. - - For local peer discovery, only a handful of packets are necessary for - peers to detect each other. - -commit 344d6b9ac3c795f2942e457c1ab38b1dac5f7242 -Author: Guus Sliepen -Date: Sun Feb 26 12:39:46 2012 +0100 - - Let tincctl use the NETNAME environment variable if no -n option is given. - - This allows administrators who frequently want to work with one tinc - network to omit the -n option. Since the NETNAME variable is set by - tincd when executing scripts, this makes it slightly easier to use - tincctl from within scripts. - -commit 84570275acd84628586a6ca591a283d074ca10f0 -Author: Guus Sliepen -Date: Sun Feb 26 12:33:16 2012 +0100 - - Ensure all SPTPS functions are prefixed with sptps_. - -commit 8b1ad6f76f821648079818f6ff018bbc33b9d9e9 -Author: Guus Sliepen -Date: Sat Feb 25 23:03:09 2012 +0100 - - Go back to breadth first search for path finding. - - If 1.1.x nodes using Dijkstra's algorithm are mixed with 1.0.x nodes using BFS, - then routing loops can occur. - -commit 36623e15a1c8685e5d8730345c1a7f9c93710fef -Merge: 65d6f023 5140656d -Author: Guus Sliepen -Date: Sat Feb 25 22:52:57 2012 +0100 - - Merge branch 'master' of git://tinc-vpn.org/tinc into 1.1 - -commit 5140656de6bcfda72951a7827b05414ce306e3ca -Author: Guus Sliepen -Date: Sat Feb 25 22:11:30 2012 +0100 - - Stricter checks against routing loops. - - If a packet that had to be sent via an intermediate hop, and that intermediate - hop was the one that sent the packet, we drop it. - -commit f1d5eae643cdf537ef357f10f2da8ff83bdf32b4 -Author: Guus Sliepen -Date: Sat Feb 25 21:46:18 2012 +0100 - - Don't send ICMP Time Exceeded messages for other Time Exceeded messages. - - That would be silly. - -commit 65d6f023c46ac3a087f59b60762f87c869783f21 -Author: Guus Sliepen -Date: Sat Feb 25 18:25:21 2012 +0100 - - Use SPTPS when ExperimentalProtocol is enabled. - -commit efd21e232dced3225f119aeb7a585ebf55b7cf77 -Author: Guus Sliepen -Date: Sat Feb 25 15:18:15 2012 +0100 - - Apply HMAC after encryption. - -commit f5dc136cfd7a3a195b75f7174722734e25f30fd9 -Merge: 3fba8017 5a28aa7b -Author: Guus Sliepen -Date: Thu Feb 23 13:26:01 2012 +0100 - - Merge branch 'master' of git://tinc-vpn.org/tinc into 1.1 - - Conflicts: - src/net.c - src/net_packet.c - src/net_socket.c - -commit 5a28aa7b8b0ab6237c2eab5f8b11253ea3ec5a05 -Author: Guus Sliepen -Date: Wed Feb 22 23:17:43 2012 +0100 - - Add LocalDiscovery option which tries to detect peers on the local network. - - Currently, this is implemented by sending IPv4 broadcast packets to the - LAN during path MTU discovery. - -commit 8e717ddb602f01f656369106ec0398efbe9ca4a4 -Author: Guus Sliepen -Date: Wed Feb 22 14:37:56 2012 +0100 - - Pass index into listen_socket[] to handle_incoming_vpn_data(). - -commit 3fba80174dbe29bcfe0d121a2a1d2e61be5ee57b -Merge: fba1c85f 65e8e06c -Author: Guus Sliepen -Date: Wed Feb 22 14:23:59 2012 +0100 - - Merge branch 'master' of git://tinc-vpn.org/tinc into 1.1 - - Conflicts: - NEWS - README - configure.in - doc/tincd.8.in - src/Makefile.am - src/bsd/device.c - src/connection.c - src/connection.h - src/cygwin/device.c - src/device.h - src/dropin.h - src/linux/device.c - src/mingw/device.c - src/net.c - src/net_packet.c - src/net_setup.c - src/net_socket.c - src/process.c - src/protocol.c - src/protocol_key.c - src/raw_socket_device.c - src/route.c - src/solaris/device.c - src/tincd.c - src/uml_device.c - -commit fba1c85f44edfc56c19d35332b1eb825179a8bb6 -Author: Guus Sliepen -Date: Tue Feb 21 23:19:51 2012 +0100 - - Remove useless warning about signature length being shorter than expected. - -commit cb6cbf452f6183a00746afc5bff8f63f3f55235f -Author: Guus Sliepen -Date: Tue Feb 21 23:17:12 2012 +0100 - - Use only one hash algorithm (SHA512) in the PRF. - - On some platforms, OpenSSL by default does not support the Whirlpool algorithm. - -commit 65e8e06c6dc7349b11c3c1e8f4071b51e2994c65 -Author: Nick Hibma -Date: Tue Feb 21 15:26:58 2012 +0100 - - Add missing ICMP message type definitions. - -commit ac48c4ee8c09c8144f830cb66386b9dbe7298440 -Author: Guus Sliepen -Date: Tue Feb 21 14:06:55 2012 +0100 - - Fix check for raw socket support. - - Also, move some variables so there are no compiler warnings about unused - variables when there is no support for raw sockets. - -commit d9ad3d313d96d30ef45cd53367dff9a855a396d4 -Author: Guus Sliepen -Date: Tue Feb 21 13:31:21 2012 +0100 - - Fix a bug that caused tinc to ignore all but the last listening socket. - -commit 46506b7aaf6c6a8a85561c38fdb9c95eae21aa75 -Author: Guus Sliepen -Date: Tue Feb 21 13:13:40 2012 +0100 - - Document the command line flag -o and provide --option as well. - -commit 7d76e287598c8c18cadfb5818046d9dd1b0ad881 -Author: Guus Sliepen -Date: Tue Feb 21 11:39:21 2012 +0100 - - Move initialization of char *priority up to prevent freeing an uninitialized pointer. - -commit 8420a0c8bde1781db04dd2436eb9d5dca5a1732a -Author: Guus Sliepen -Date: Mon Feb 20 17:19:00 2012 +0100 - - Allow disabling of broadcast packets. - - The Broadcast option can be used to cause tinc to drop all broadcast and - multicast packets. This option might be expanded in the future to selectively - allow only some broadcast packet types. - -commit ea415ccc1690d6e5864a7500977b181e5c8faafe -Author: Guus Sliepen -Date: Mon Feb 20 17:12:48 2012 +0100 - - Rename connection_t *broadcast to everyone. - -commit cff5a844a3e6b494f4a4f6eb5b48a84780f2d0e5 -Author: Guus Sliepen -Date: Mon Feb 20 16:52:53 2012 +0100 - - Don't bind outgoing TCP sockets anymore. - - The code introduced in commit 41a05f59ba2c3eb5caab555f096ed1b9fbe69ee3 is not - needed anymore, since tinc has been able to handle UDP packets from a different - source address than those of the TCP packets since 1.0.10. When using multiple - BindToAddress statements, this code does not make sense anymore, we do want the - kernel to choose the source address on its own. - -commit 0233b1d710222cb09be0cbd08c1297e3ece38a9f -Author: Guus Sliepen -Date: Mon Feb 20 16:34:02 2012 +0100 - - Decrement TTL of incoming packets. - - Tinc will now, by default, decrement the TTL field of incoming IPv4 and IPv6 - packets, before forwarding them to the virtual network device or to another - node. Packets with a TTL value of zero will be dropped, and an ICMP Time - Exceeded message will be sent back. - - This behaviour can be disabled using the DecrementTTL option. - -commit 6289859ab365dc1c0d420323174418b316b14502 -Author: Guus Sliepen -Date: Mon Feb 20 15:44:52 2012 +0100 - - Only compile raw socket code when it is supported on that platform. - -commit d1dcdf8eb6f800704be426b1ce6f6c1a8e65ba0d -Merge: 1b2846d9 3b1fad04 -Author: Guus Sliepen -Date: Sat Feb 18 14:31:08 2012 +0100 - - Merge branch 'master' of black:tinc - -commit 3b1fad04de6bed2f284fdf3d5b27d4162aeebc8c -Author: Guus Sliepen -Date: Sat Feb 18 14:37:52 2012 +0100 - - Allow setting DeviceType to tun or tap on Linux. - -commit 6455654d26d204cea4bbc102e5bd6550b7fff7a7 -Author: Guus Sliepen -Date: Sat Feb 18 11:48:21 2012 +0100 - - Send packets back using the same socket as they were received on. - -commit 1b2846d907adfc8472fc9da0c951c3243c7ee143 -Merge: 9f6a96af 6455654d -Author: Guus Sliepen -Date: Sat Feb 18 11:43:00 2012 +0100 - - Merge branch 'master' of black:tinc - -commit 9f6a96af3939bd2de410ce346a8c8fbcf93e7c9b -Author: Guus Sliepen -Date: Fri Feb 17 16:25:00 2012 +0100 - - Allow multiple BindToAddress statements. - -commit 708314df2f61675d0f54e541c9fff62ac1f433b5 -Author: Guus Sliepen -Date: Fri Feb 17 16:13:38 2012 +0100 - - Set FD_CLOEXEC flag on all sockets. - - Scripts called by tinc would inherit its open filedescriptors. This could - be a problem if other long-running daemons are started from those scripts, - if those daemons would not close all filedescriptors before going into the - background. - - Problem found and solution suggested by Nick Hibma. - -commit 1f00111e94b2f9a4beb9608b1e03a5e73c9c5d21 -Author: Guus Sliepen -Date: Mon Dec 26 23:11:27 2011 +0100 - - Fix a few small memory leaks. - -commit b50d6a7f2ad98239018bc5ce7a5739e3bf4f50f7 -Author: Guus Sliepen -Date: Mon Dec 26 23:04:40 2011 +0100 - - Fix compiler warnings. - -commit 178e52f76ef4ba40748c13ea7e518837394d6dbc -Author: Guus Sliepen -Date: Sun Dec 4 01:20:59 2011 +0100 - - Allow linking with multiple device drivers. - - Apart from the platform specific tun/tap driver, link with the dummy and - raw_socket devices, and optionally with support for UML and VDE devices. - At runtime, the DeviceType option can be used to select which driver to - use. - -commit 5672863e59e6a114ac6b66de98254b14266c0e61 -Author: Guus Sliepen -Date: Sat Dec 3 21:59:47 2011 +0100 - - Fix a few small memory leaks. - -commit 52ded09d1713b83222b56db7d29ff061aefb95e3 -Author: Guus Sliepen -Date: Sun Nov 27 12:13:16 2011 +0100 - - Add vde/device.c to the tarball. - -commit 2c7c87ec75c94d0b3cca9f7a5aeba34384f77cc1 -Author: Guus Sliepen -Date: Sun Nov 27 12:12:34 2011 +0100 - - Fix compilation of VDE and UML interfaces. - -commit 2a9060bba62d78f73da9b09ca791fe80993520fc -Author: Guus Sliepen -Date: Thu Oct 6 15:32:12 2011 +0200 - - Exchange ACK records to indicate switch to new keys. - - This allow application records to be sent while key renegotiation is still - happening. - -commit 3b5898078af1ab86797b3e24f2381131e6e702f7 -Author: Guus Sliepen -Date: Thu Oct 6 09:34:34 2011 +0200 - - Use counter mode encryption. - -commit a0f795ff5bd671ca10a7203e4234b37a12d8d1cd -Author: Guus Sliepen -Date: Thu Oct 6 09:33:09 2011 +0200 - - Add counter mode encryption. - -commit 67ff81ec16b8ab5f15d16efbedfecfaf0be17c13 -Author: Guus Sliepen -Date: Wed Oct 5 22:05:13 2011 +0200 - - Test corner cases in the SPTPS protocol. - - * Test zero-byte messages. - * Test maximum size (65535 byte) messages. - * Test different message types. - * Test key renegotiation. - -commit 30013511504e925729ebc67772205a74c4b8aeea -Author: Guus Sliepen -Date: Wed Oct 5 22:00:51 2011 +0200 - - Update SPTPS protocol. - - * Exchange nonce and ECDH public key first, calculate the ECDSA signature - over the complete key exchange. - * Make an explicit distinction between client and server in the signatures. - * Add more comments and replace some magic numbers by #defines. - - Thanks to Erik Tews for very helpful hints and comments! - -commit 810847248ae90140ee6f3e568add80aef88c3def -Author: Guus Sliepen -Date: Wed Oct 5 21:59:33 2011 +0200 - - Fix compiler warning. - -commit ddea7a23a66b8fee4942f2ce237dcabe02e17270 -Author: Guus Sliepen -Date: Tue Aug 30 20:49:48 2011 +0200 - - Return false instead of void when there is an error. - -commit e838289683c0039fac0ae6172d40b4177c17911b -Author: Guus Sliepen -Date: Tue Aug 30 19:56:56 2011 +0200 - - Prevent read_rsa_public_key() from returning an uninitialized RSA structure. - - In case the config file could not be opened a new but unitialized RSA structure - would be returned, causing a segmentation fault later on. This would only - happen in the case that the config file could be opened before, but not when - read_rsa_public_key() was called. This situation could occur when the --user - option was used, and the config files were not readable by the specified user. - -commit 5d4336e5429b88dcc53e80c00412e76a5269b384 -Author: Guus Sliepen -Date: Wed Aug 10 17:04:17 2011 +0200 - - Handle UDP packets with unknown source addresses properly. - - Probably due to a merge, the try_harder() function had duplicated the - rate-limiting code for detecting the sender node based on the HMAC of the - packet. This prevented this detection from running at all. The function is now - identical again to that in the 1.0 branch. - -commit bbc0ba9e87f76111529d6dc9cb00c0b9435b5858 -Author: Michael Tokarev -Date: Sun Aug 7 12:18:20 2011 +0400 - - use execvp() not execve() in tincctl start - - sometimes argv[0] will have directory-less name (when the - command is started by shell searching in $PATH for example). - For tincctl start we want the same rules to run tincd as for - tincctl itself (having full path is better but if shell does - not provide one we've no other choice). Previous code tried - to run ./tincd in this case, which is obviously wrong. - - This is a fix for the previous commit. - - Signed-off-by: Michael Tokarev - -commit a7556a9d2c943a6317d2dab66d9f742997f0d47a -Author: Michael Tokarev -Date: Sun Aug 7 12:05:07 2011 +0400 - - run tincd from the same directory as tincctl and pass all options to it - - For tincctl start, run tincd from dirname($0) not SBINDIR - - this allows painless alternative directory installation and - running from build directory too. - - Also while at it, pass the rest of command line to tincd, not - only options before "start" argument. This way it's possible - to pass options to tincd like this: - tincctl -n net start -- -d 1 -R -U tincuser ... - - And also add missing newline at the end of error message there. - - Signed-Off-By: Michael Tokarev - -commit 2696ad2cca73aee13e38f740d5530dc33e4a92e6 -Author: Michael Tokarev -Date: Sun Aug 7 11:25:03 2011 +0400 - - don't mention reload twice in tincctl help - - Signed-Off-By: Michael Tokarev - -commit 3d75dbc0880484ff6d2f689a9b981def3cd75b5e -Author: Guus Sliepen -Date: Sun Jul 24 15:44:51 2011 +0200 - - Start of "Simple Peer-To-Peer Security" protocol. - - Encryption and authentication of the meta connection is spread out over - meta.c and protocol_auth.c. The new protocol was added there as well, - leading to spaghetti code. To improve things, the new protocol will now - be implemented in sptps.[ch]. - - The goal is to have a very simplified version of TLS. There is a record - layer, and there are only two record types: application data and - handshake messages. The handshake message contains a random nonce, an - ephemeral ECDH public key, and an ECDSA signature over the former. After - the ECDH public keys are exchanged, a shared secret is calculated, and a - TLS style PRF is used to generate the key material for the cipher and - HMAC algorithm, and further communication is encrypted and authenticated. - - A lot of the simplicity comes from the fact that both sides must have - each other's public keys in advance, and there are no options to choose. - There will be one fixed cipher suite, and both peers always authenticate - each other. (Inspiration taken from Ian Grigg's hypotheses[0].) - There might be some compromise in the future, to enable or disable - encryption, authentication and compression, but there will be no choice - of algorithms. This will allow SPTPS to be built with a few embedded - crypto algorithms instead of linking with huge crypto libraries. - - The API is also kept simple. There is a start and a stop function. All - data necessary to make the connection work is passed in the start - function. Instead having both send- and receive-record functions, there - is a send-record function and a receive-data function. The latter will - pass protocol data received from the peer to the SPTPS implementation, - which will in turn call a receive-record callback function when - necessary. This hides all the handshaking from the application, and is - completely independent from any event loop or socket characteristics. - - [0] http://iang.org/ssl/hn_hypotheses_in_secure_protocol_design.html - -commit 0f2aa4bd8b698608876bec141c5aef1aa619730b -Author: Guus Sliepen -Date: Sat Jul 23 14:12:23 2011 +0200 - - Releasing 1.0.16. - -commit e16ead8dd9d4600664058069f0695832dfe068b2 -Author: Guus Sliepen -Date: Sat Jul 23 14:11:44 2011 +0200 - - Use usleep() instead of sleep(), MinGW complained. - -commit ff751903aa82bd6dd66a099f9c05dcdae9fc57f2 -Author: Guus Sliepen -Date: Wed Jul 20 08:19:18 2011 +0200 - - Don't abort() on low-level crypto errors, just return false. - - The abort() calls were accidentily left in for debugging. - -commit 2f4ccfe2473948372f7c9f14d9ffce1d77f5fd8c -Author: Guus Sliepen -Date: Tue Jul 19 21:11:11 2011 +0200 - - Fix tinc 1.0.x daemons connecting when ExperimentalProtocol = yes. - -commit f8d94f34fc5d7fe9ed4a076a2fd77eacbd83adca -Author: Guus Sliepen -Date: Sun Jul 17 20:09:08 2011 +0200 - - Releasing 1.1pre2. - -commit c259d552fa89c3e4a962d9adf2b237f24bc077da -Author: Guus Sliepen -Date: Sun Jul 17 20:06:06 2011 +0200 - - Add missing newline. - -commit f6020a5224c9c4c17c11c5f9d2c8441638ac04fc -Author: Guus Sliepen -Date: Sun Jul 17 20:01:24 2011 +0200 - - Write loopback address instead of "any" address in pidfile. - -commit 50fcfea127c9d2fdf8894498a9fdcc6fb3bbb2ce -Author: Guus Sliepen -Date: Sun Jul 17 19:34:01 2011 +0200 - - Flush output buffer in send_tcppacket(). - - This is mainly important for Windows, where the select() call in the - main thread is not being woken up when the tapreader thread calls - route(), causing a delay of up to 1 second before the output buffer is - flushed. This would cause bad performance when UDP communication is not - possible. - -commit 25091454da21941dd92375ddbee7dd6151343058 -Author: Guus Sliepen -Date: Sun Jul 17 19:23:52 2011 +0200 - - "tincctl stop" now removes the tinc service on Windows. - -commit c6c989cfa175154f4cd3830c5a77fbd2071f52af -Author: Guus Sliepen -Date: Sun Jul 17 18:02:56 2011 +0200 - - Fix declaration of usleep(). - -commit 18e9839dc861c368141bbbc9a963f719a83eba3e -Author: Guus Sliepen -Date: Sun Jul 17 10:59:54 2011 +0200 - - Ensure symlinked files do not end up in the tarball. - -commit fa4a01e4a27dd4b3a57077acbd0e69f95d55944a -Author: Guus Sliepen -Date: Sat Jul 16 22:38:50 2011 +0200 - - Use const pointer to source in base64 and hex routines. - -commit 574b380dfc75ef13ee4accba1f2416165c58a5a2 -Author: Guus Sliepen -Date: Sat Jul 16 22:38:22 2011 +0200 - - Use usleep() instead of sleep(), MinGW complained. - -commit 8efc8dc961865ceddb74cb36f0b4a2ebde39cc55 -Author: Guus Sliepen -Date: Sat Jul 16 21:44:17 2011 +0200 - - Update info manual. - -commit cff27a258f3b3a97b5d2e309c264eceea41dff3a -Author: Guus Sliepen -Date: Sat Jul 16 20:21:44 2011 +0200 - - Use ECDSA to sign ECDH key exchange for UDP session keys. - - The ECDSA public keys will also be included in the ANS_KEY requests, - but are only used when no ECDSA public key is known yet. - -commit 03ac48ea19914e4162f17a2fb0f742b99ae32499 -Author: Guus Sliepen -Date: Sat Jul 16 15:21:37 2011 +0200 - - Use the same logic as tinc 1.0.x for detecting two nodes with the same Name. - -commit 2ba61742d4c2ab82525efb806dc654a6d95d335e -Author: Guus Sliepen -Date: Sat Jul 16 15:15:29 2011 +0200 - - Use the correct direction flag when setting cipher keys. - - The flag was set incorrectly, but for most ciphers this does not have - any effect. AES in any of the block modes is picky about it though. - -commit be2fc8b0458b1e2ced3b5de410356d8d8639acff -Author: Guus Sliepen -Date: Sat Jul 16 10:47:35 2011 +0200 - - Make code to detect two nodes with the same Name less triggerhappy. - - First of all, if there really are two nodes with the same name, much - more than 10 contradicting ADD_EDGE and DEL_EDGE messages will be sent. - Also, we forgot to reset the counters when nothing happened. - - In case there is a ADD_EDGE/DEL_EDGE storm, we do not shut down, but - sleep an increasing amount of time, allowing tinc to recover gracefully - from temporary failures. - -commit 303dd1e70219a7542921f6e63d9391ab326d434f -Author: Guus Sliepen -Date: Wed Jul 13 22:52:52 2011 +0200 - - Fix compiler warnings. - -commit 791c1898ea8f92b07f1d79e90540c257ac38298d -Author: Guus Sliepen -Date: Wed Jul 13 22:29:30 2011 +0200 - - Remove unnecessary variables and functions. - -commit fec279a9c54ec8a13bd1ba4c7bec0d2a15454992 -Author: Guus Sliepen -Date: Tue Jul 12 23:43:12 2011 +0200 - - Make use of the improved hex and base64 functions. - - Also, use base64 for all EC related data, it is shorter and easy to - distinguish from the legacy protocol. - -commit 06b8271ed5d56c9bd3de459d95907d0ef4f0ea3c -Author: Guus Sliepen -Date: Tue Jul 12 22:54:49 2011 +0200 - - Make hexadecimal and base64 routines behave the same. - - The length parameter for the encoding functions is the length of the - binary input, and for the decoding functions it is the maximum size of - the binary output. - - The return value is always the length of the resulting output, excluding - the terminating NULL character for the encoding routines. - - All functions can encode and decode in-place. The encoding functions - will always write a terminating NULL character, and the decoding - functions will stop at a NULL character. - -commit c108c79a22118ef7246a3d7b3bc20e205e11d179 -Author: Guus Sliepen -Date: Mon Jul 11 22:14:06 2011 +0200 - - Don't use wildcards in filenames in configure.in. - -commit bbeab00f46a6c856573fe0d2b9b85bce35728403 -Author: Guus Sliepen -Date: Mon Jul 11 21:54:01 2011 +0200 - - Require ExperimentalProtocol = yes for new features, update documentation. - -commit d1cd3c81455ecb32149cbaa424b7870075b2b2fc -Author: Guus Sliepen -Date: Sun Jul 10 22:46:43 2011 +0200 - - Close meta connection socket after cleaning up event structures. - - Epoll doesn't like it when an already closed filedescriptor is being - removed, so we defer closing the socket until after all else is cleaned - up. - -commit 30ef2a981e1d62692b3a2363e0b3a0e8711d9604 -Author: Guus Sliepen -Date: Sun Jul 10 22:34:17 2011 +0200 - - Automatically exchange ECDSA keys and upgrade to new authentication protocol. - - If we don't have ECDSA keys for the node we connect to, set protocol_minor - to 1, to indicate this to the other end. This will first complete the - old way of authentication with RSA keys, and will then exchange ECDSA keys. - The connection will be terminated right afterwards, and the next attempt - will use ECDSA keys. - -commit 027228debee2ea6f31cd176e456c13d626380066 -Author: Guus Sliepen -Date: Sun Jul 10 21:02:34 2011 +0200 - - Free ECDSA and RSA structures when freeing a connection_t. - -commit 73863fab8ae1ecd8307aaeef486919cc76b85d63 -Author: Guus Sliepen -Date: Fri Jul 8 18:17:34 2011 +0200 - - Hash input before signing it with ECDSA. - -commit 8132be8fbd6c45be309c63a117f418ad12ced094 -Author: Guus Sliepen -Date: Thu Jul 7 22:30:55 2011 +0200 - - Very primitive ECDSA signed ECDH key exchange for the meta protocol. - - Nonces and hash of the ID requests should be included in the seed for the PRF. - -commit 210b5ceeeebdf742a74dcf95a0a13d69623ee001 -Author: Guus Sliepen -Date: Thu Jul 7 22:28:25 2011 +0200 - - Read ECDSA keys. - -commit 03582eb669494cb778ebea7b0fe3b1b841335750 -Author: Guus Sliepen -Date: Thu Jul 7 22:27:17 2011 +0200 - - Implement ECDSA sign and verify operations. - - Very basic at the moment, doesn't hash the input first, - and uses OpenSSL's DER encoded signature as output. - -commit 86d83bd9bd69e2129f4e4e8397f1c7e223685e2f -Author: Guus Sliepen -Date: Tue Jul 5 21:29:31 2011 +0200 - - Bump minor protocol to indicate ECDH capability for UDP session keys. - -commit 9708bbfa8e3094de8932a30b1d24c661558d8a03 -Author: Guus Sliepen -Date: Tue Jul 5 21:19:48 2011 +0200 - - Add a minor number to the protocol version. - -commit b99656d84a88dad7935d5981fcdb43a5b2bfa417 -Author: Guus Sliepen -Date: Mon Jul 4 07:51:47 2011 +0200 - - Round up the size of the secret parts after splitting it in two. - -commit 95e1cc36d320b47408ac3ec6f89df54e55a010d4 -Author: Guus Sliepen -Date: Sun Jul 3 23:44:43 2011 +0200 - - Add ECDSA key import. - -commit 1e2d9b08991861c8770aa2c5a73d86dc02e3067d -Author: Guus Sliepen -Date: Sun Jul 3 23:33:56 2011 +0200 - - Finish base64 decoding routine. - -commit 80b81c00b129b006981b76bdb734df3296317d6f -Author: Guus Sliepen -Date: Sun Jul 3 22:25:29 2011 +0200 - - Have tincctl generate ECDSA keys. - - The generate-keys command now generates both an RSA and an ECDSA keypair, - but one can generate-rsa-keys or generate-ecdsa-keys to just generate one type. - -commit 8ace7f3e5771957fbdda8b817fa26951d9d62c28 -Author: Guus Sliepen -Date: Sun Jul 3 22:15:00 2011 +0200 - - Add ECDSA key generation. - -commit 1d92dd62a786ecabbc05dfba5195f3f08e0f9585 -Author: Guus Sliepen -Date: Sun Jul 3 22:13:58 2011 +0200 - - Base64 encoding and decoding functions. - -commit c385d115331845e8a844322e66571d74d833e822 -Author: Guus Sliepen -Date: Sun Jul 3 22:13:34 2011 +0200 - - Cleanups in ECDH code. - -commit 895f868714f9422a757a95650345e0c662d12b49 -Author: Guus Sliepen -Date: Sun Jul 3 21:21:37 2011 +0200 - - No need to keep around pointers to EC_GROUP. - -commit ac163120d7f0300c8d555f76ace3368ce2ffa655 -Author: Guus Sliepen -Date: Sun Jul 3 16:30:49 2011 +0200 - - Proper use of PRF. - -commit 82f00ea07bffc10985ccb1a15723e6daa0ab4969 -Author: Guus Sliepen -Date: Sun Jul 3 15:59:49 2011 +0200 - - Use PRF. - -commit feb3f22fffa2620b9b11a509ce51ff9fa3be9418 -Author: Guus Sliepen -Date: Sun Jul 3 15:26:58 2011 +0200 - - Add PRF to derive key material from the ECDH shared secret. - - It is modelled after the pseudorandom function from RFC4346 (TLS 1.1), the only - significant change is the use of SHA512 and Whirlpool instead of MD5 and SHA1. - -commit 8dfa072733feab737cabf69f000c70657719826a -Author: Guus Sliepen -Date: Sun Jul 3 13:17:28 2011 +0200 - - Support ECDH key exchange. - - REQ_KEY requests have an extra field indicating key exchange version. - If it is present and > 0, the sender supports ECDH. If the receiver also - does, then it will generate a new keypair and sends the public key in a - ANS_KEY request with "ECDH:" prefixed. The ans_key_h() function will - compute the shared secret, which, at the moment,is used as is to set the - cipher and HMAC keys. However, this must be changed to use a proper KDF. - In the future, the ECDH key exchange must also be signed. - -commit ee8a214318fd6dbe6bc5d6b510896f30d92d46c6 -Author: Guus Sliepen -Date: Mon Jun 27 21:52:23 2011 +0200 - - Preliminary implementation of Elliptic Curve Diffie-Hellman Ephemeral key exchange. - -commit 6c21b5716b8e9e5ff5def8070f92b76a0f353cb0 -Author: Guus Sliepen -Date: Sun Jun 26 13:15:44 2011 +0200 - - Add manpage for tinc-gui. - -commit 4c934d0903a32e71ae83ffdf344957bd06b7164d -Author: Guus Sliepen -Date: Sun Jun 26 13:14:48 2011 +0200 - - Remove debug messages that were printed to stdout. - -commit e73052b05444679d922dbdf3d0c507873110957e -Author: Guus Sliepen -Date: Sun Jun 26 12:59:11 2011 +0200 - - Update documentation to mention pidfiles instead of controlcookies. - -commit 8c953b1bfef3c6ebee7c537c2c2f144807d0311a -Author: Guus Sliepen -Date: Sun Jun 26 12:58:50 2011 +0200 - - Don't react to escape character in tincctl top. - - Not only the ESC key generates an escape character, but many other keys - do as well, such as arrow keys. - -commit 27e6a89b155b171b0b026d5e24ee0cc68f43d010 -Author: Guus Sliepen -Date: Sun Jun 26 12:51:25 2011 +0200 - - Use pidfile in tinc-gui as well. - -commit 660f530a6ff733f96f81eefa69b38e2ea685f890 -Author: Guus Sliepen -Date: Sat Jun 25 22:20:39 2011 +0200 - - Really stable sorting of tincctl top output. - -commit 810766e1394f18b8709e9f0c75a41a2c348e3fad -Author: Guus Sliepen -Date: Sat Jun 25 21:38:59 2011 +0200 - - Add +git to the version string. - -commit ab4d289fafd1d391583935ab4c306f1f508ea1d0 -Author: Guus Sliepen -Date: Sat Jun 25 21:35:27 2011 +0200 - - Make pid files backwards compatible and add address of listening socket. - - The pid is now written first, so that a version 1.0.x tincd can be used to stop - a running version 1.1 tincd. Getsockname() is used to determine the address of - the first listening socket, so that tincctl can connect to the local tincd even - if AddressFamily = ipv6, or if BindToAddress or BindToInterface is used. - -commit a05fa7f88264599a43f9e411287e018259dc22b1 -Author: Guus Sliepen -Date: Sat Jun 25 21:21:36 2011 +0200 - - Rename controlcookie file to pidfile. - -commit c64f64b875879591873d68faf2d3cd8e9d644101 -Author: Guus Sliepen -Date: Sat Jun 25 21:16:13 2011 +0200 - - Don't call exit_control() if we didn't do init_control(). - -commit 3b237afbda86bc95703ed25386cc9a26695d4602 -Author: Guus Sliepen -Date: Sat Jun 25 20:20:07 2011 +0200 - - Re-add support for SIGALRM. - -commit 386c1aff08a3ce6e295931e2fcf4bfc607053ff0 -Author: Guus Sliepen -Date: Sat Jun 25 17:39:02 2011 +0200 - - Merge Tinc.py into tinc-gui to simplify make install. - - Autoconf/automake's Python support is strange. - -commit c4c32f40599eb8e75b1160083020d924c5807ac8 -Author: Guus Sliepen -Date: Sat Jun 25 17:11:05 2011 +0200 - - Thank Scott Lamb, Sven-Haegar Koch and Loïc Grenié in the NEWS file. - -commit 8733110dec28967d67a3c00d00cdfa608dbeb9c4 -Author: Guus Sliepen -Date: Sat Jun 25 17:08:40 2011 +0200 - - Ensure the right files end up in the tarball after make dist. - -commit e4f65db89726ac06ba7e787d420db4422d9a6e98 -Author: Guus Sliepen -Date: Sat Jun 25 15:28:54 2011 +0200 - - Releasing 1.1pre1. - -commit 2c5ded652035bfaa204a7e1cc6766efb87135569 -Author: Guus Sliepen -Date: Sat Jun 25 15:28:13 2011 +0200 - - Ensure that the texinfo manual can be converted to HTML. - - Somehow commit 2c30af6c90926340a89748c63cc453b1c0b5a589 was not properly - merged. - -commit e8deda0b23463599a7533e82cf038a01062956a7 -Author: Guus Sliepen -Date: Sat Jun 25 14:52:47 2011 +0200 - - Update manpages and info manual. - -commit 47393b5de42120dfb7d01f8b77aff16ac68177ec -Author: Guus Sliepen -Date: Sat Jun 25 00:32:45 2011 +0200 - - Add Makefile.am in gui/. - - This ensures the gui source will be included in the tarball with make dist, - and will be installed with make install. - -commit 7944cce19e4de4207a4ef20569155118acebd406 -Author: Guus Sliepen -Date: Sat Jun 25 00:06:06 2011 +0200 - - Don't use AM_CONDITIONAL for CURSES. - - For some reason, this doesn't work when cross-compiling for Windows. - -commit 365f60f3f8a8ff85a616d5014d555b470740d395 -Author: Guus Sliepen -Date: Fri Jun 24 22:49:18 2011 +0200 - - Don't call event_del() from the mtuevent handler, always send_mtu_probe() in ans_key_h(). - -commit 1fe8ba2f06c39d7c8b81f0e451bdbac94ae9375f -Author: Guus Sliepen -Date: Fri Jun 24 22:10:03 2011 +0200 - - Delete mtuevent if it is not used. - - Keeping it around prevents ans_key_h() from restarting PMTU discovery. - -commit 79e9a4f743b7b59fed968575f6b36171cf4a0063 -Merge: fb5b2601 05260f94 -Author: Guus Sliepen -Date: Fri Jun 24 21:40:55 2011 +0200 - - Merge branch 'master' of git://tinc-vpn.org/tinc into 1.1 - - Conflicts: - NEWS - README - configure.in - src/Makefile.am - -commit 05260f941c2a24eb3f09070a2550cf15e431266a -Author: Guus Sliepen -Date: Fri Jun 24 14:50:20 2011 +0200 - - Releasing 1.0.15. - -commit 3c0511984f0041f79e64bcc55d58680f86e8e408 -Author: Guus Sliepen -Date: Fri Jun 24 12:27:04 2011 +0200 - - Remove redundant @CFLAGS@ from AM_CFLAGS. - -commit fb5b260190b1c6d07ec822154094aee7416f292e -Author: Guus Sliepen -Date: Tue Jun 21 23:08:05 2011 +0200 - - No need to check for pselect() in tinc 1.1. - -commit 532557beeaa60d96ac423248ff62d2cc03205c22 -Author: Guus Sliepen -Date: Tue Jun 21 23:06:53 2011 +0200 - - Only log UDP address changes at the appropriate debug levels. - -commit 60ed7fe598ccf3ac11fab616c9c85492c576b722 -Author: Guus Sliepen -Date: Mon Jun 6 21:19:30 2011 +0200 - - Reopen log file after SIGHUP. - - This was missed by the previous merge. - -commit 33f241d97852d7a171f1aaf1bda7f66356ff889e -Merge: 601f3b2d 4b3fd94b -Author: Guus Sliepen -Date: Mon Jun 6 20:42:15 2011 +0200 - - Merge branch 'master' of git://tinc-vpn.org/tinc into 1.1 - - Conflicts: - NEWS - configure.in - doc/tincd.8.in - lib/pidfile.c - lib/pidfile.h - lib/xalloc.h - lib/xmalloc.c - src/conf.c - src/conf.h - src/connection.c - src/connection.h - src/event.c - src/graph.c - src/graph.h - src/net.c - src/net.h - src/node.h - src/openssl/crypto.c - src/process.c - src/protocol.c - src/protocol_key.c - src/route.c - -commit 601f3b2dd746ff5726eca256861f2ecf662b3a55 -Author: Guus Sliepen -Date: Mon Jun 6 20:12:33 2011 +0200 - - Clean up digests when freeing a connection_t. - -commit 4b3fd94b1cc79c24c4092b6b10ed4627a2648d26 -Author: Guus Sliepen -Date: Mon Jun 6 16:26:11 2011 +0200 - - Improved --logfile option. - - Instead of UNIX time, the log messages now start with the time in RFC3339 - format, which human-readable and still easy for the computer to parse and sort. - The HUP signal will also cause the log file to be closed and reopened, which is - useful when log rotation is used. If there is an error while opening the log - file, this is logged to stderr. - -commit b3bbeab6e669795f6f5a6b98590da359178bfdce -Author: Guus Sliepen -Date: Sat Jun 4 11:27:54 2011 +0200 - - Attribution for Loïc Grenié. - -commit 50af33d01f425983dd2b1d7b61092a6325be3f41 -Author: Loïc Grenié -Date: Sat Jun 4 09:05:23 2011 +0200 - - Nearly tickless tinc. - - Use pselect instead of select in main_loop (if available). This lets - tincd sleeps as long as there is nothing to do. - -commit 8b3cc695b56d4ab5e51c7e194153894f920b307f -Author: Guus Sliepen -Date: Fri Jun 3 15:50:20 2011 +0200 - - Don't ignore SIGCHLD, system() needs it. - - But we do ignore SIGPIPE, and tinc 1.0.x signals that are no longer used - (SIGUSR1 and SIGUSR2), since the default handler of these signals is to - terminate tincd immediately. - -commit 5989a29d7b53b25e8ed2f60bc3a0e089e423c02c -Author: Guus Sliepen -Date: Fri Jun 3 00:46:56 2011 +0200 - - Fix format strings for Windows. - - Windows doesn't like %zd, so cast (s)size_t to int. Also, some shorts were - incorrectly printed with %d instead of %hd. - -commit 3ade33bfac11715190ed3e6cc3589d1a738ce257 -Author: Guus Sliepen -Date: Fri Jun 3 00:34:30 2011 +0200 - - Use send() when writing to sockets, and the return type is ssize_t. - -commit 5f4d57e846b566e80557c57a72e2bad562f66e7b -Author: Guus Sliepen -Date: Thu Jun 2 23:40:27 2011 +0200 - - Small fixes for Windows. - -commit 2adc789401153ffde847f76155e07665fbf909ac -Author: Guus Sliepen -Date: Thu Jun 2 22:14:53 2011 +0200 - - Even simpler signal handling. - -commit 2f42896789a1798e71374fa2ddf555fe2fa46c44 -Author: Guus Sliepen -Date: Thu Jun 2 21:29:11 2011 +0200 - - Remove debugging message that was accidentily left in. - -commit c6b0e102ad7caabae6876849c97f8acaecf5bc1a -Author: Guus Sliepen -Date: Thu Jun 2 21:16:57 2011 +0200 - - Don't treat packets coming in via TCP as having zero length. - -commit 80ca91769d48e546d3e4cde03c2eb2820c03acc4 -Author: Guus Sliepen -Date: Thu Jun 2 21:14:50 2011 +0200 - - Fix nodes joining the VPN after tincctl top started. - -commit 311f60f4f0bdf974d4890d7eb4a752299d1c9458 -Author: Guus Sliepen -Date: Thu Jun 2 20:48:18 2011 +0200 - - Make traffic statistics more readable with configurable scaling. - -commit a8f0d21330b40993d52421327b1aa33a6ea7acb7 -Author: Guus Sliepen -Date: Thu Jun 2 20:27:16 2011 +0200 - - More stable sorting in tincctl top. - - Although we use qsort(), which is not guaranteed to be stable, resorting the - previously sorted array is more stable than recreating and resorting the array - each time. - -commit 2bda2aa8855ff3ae42aba7aa86e1d7ff2b7a3b34 -Author: Guus Sliepen -Date: Thu Jun 2 18:22:26 2011 +0200 - - Fix some compiler and cppcheck warnings. - -commit 809dfd2f5b08ecbfe55d1a06d267abeef0044b0b -Author: Guus Sliepen -Date: Thu Jun 2 18:07:50 2011 +0200 - - Remove support for the Ethertap device. - -commit af2e0c9a32642065aedd2e67ca1f5791ca7a407d -Author: Guus Sliepen -Date: Thu Jun 2 17:57:53 2011 +0200 - - Remove unused functions and variables. - -commit 9eca49329db0c3b0a80114045cf214eaeaf3d5c2 -Author: Guus Sliepen -Date: Thu Jun 2 17:55:29 2011 +0200 - - Don't #include anymore. - -commit b7754e5aaa3cc453582d6c8c2e66483fdcd1ac0d -Author: Guus Sliepen -Date: Thu Jun 2 17:53:35 2011 +0200 - - Drop the GNU memcmp.c implementation. - -commit 25b467638a23ad03524719329027225ae1da75bc -Author: Guus Sliepen -Date: Thu Jun 2 17:45:06 2011 +0200 - - Drop the GNU malloc.c, realloc.c, and xmalloc.c. - - We live in the 21st century, and we require C99 semantics, so we do not need to - work around buggy libcs. The xmalloc() and related functions are now static - inline functions. - -commit e452a933f9c53fd58db9d932afd15319129dd988 -Author: Guus Sliepen -Date: Thu Jun 2 17:14:30 2011 +0200 - - Simplify signal handling. - - We don't override any signal handlers anymore except those for SIGPIPE and - SIGCHLD. Fatal signals (SIGSEGV, SIGBUS etc.) will terminate tincd and - optionally dump core. The previous behaviour was to terminate gracefully and - try to restart, but that usually failed and made any core dump useless. - -commit 4d440336c3ce68719e23b2fc51fac368e23352ad -Author: Guus Sliepen -Date: Sun May 29 22:34:19 2011 +0200 - - Remove outgoing event in free_connection(). - -commit d29bfc9a450b4758e44757a71675bac631dd3c55 -Author: Guus Sliepen -Date: Sun May 29 22:14:35 2011 +0200 - - Initialise priority field to zero for packets read from the VPN interface. - -commit 4c403840ffdeb2a2ff04c9b7780a407920b2b794 -Author: Guus Sliepen -Date: Sun May 29 22:12:37 2011 +0200 - - Cosmetic fix when pressing 's' in tincctl top. - -commit b3aeaf0f917a895332ff937c7ab64638eacc0eae -Author: Guus Sliepen -Date: Sun May 29 22:10:54 2011 +0200 - - Show hostname and port in error message when connecting to a running tincd. - -commit 04de15984f1479d0142bdfa5bd968274aea2209e -Author: Sven-Haegar Koch -Date: Sun May 29 21:53:21 2011 +0200 - - do_outgoing_connection() may delete a failed connection, and the structure - must not be accessed afterwards. - -commit 82109868b5acd55e452569c565ab6dc090ea1de0 -Author: Sven-Haegar Koch -Date: Sun May 29 21:35:31 2011 +0200 - - src/net_socket.c bind_to_address(): Use after free in error path. - -commit 5bc957074a35e58f49cbcf8d1fb5d6237d37363d -Author: Guus Sliepen -Date: Sun May 29 14:41:05 2011 +0200 - - Allow tincctl to connect to something besides localhost. - - This would allow tincctl to connect to a remote tincd, or to a local tincd that - isn't listening on localhost, for example if it is using the BindToInterface or - BindToAddress options. - -commit 64771f73ebbff04262defcde59263e98f89f0fa1 -Author: Guus Sliepen -Date: Sat May 28 23:46:56 2011 +0200 - - Remove a few unnecessary #includes. - - Some spotted by Michael Tokarev. - -commit 5cff8c47c1781a88123c128a4cec6cdd39925aa5 -Author: Guus Sliepen -Date: Sat May 28 23:42:18 2011 +0200 - - Remove newlines from log messages. - -commit 6d08eb1614b59d5f86a43edda9db06fca72b76cd -Author: Guus Sliepen -Date: Sat May 28 23:36:52 2011 +0200 - - Fix sparse warnings and add an extra sprinkling of const. - - This is more or less the equivalent of Sven-Haegar Koch's fixes in the 1.1 - branch. - -commit e6b21e1a510691a86dcc1ecdf71a80a7c62ff17f -Author: Sven-Haegar Koch -Date: Sat May 28 03:48:07 2011 +0200 - - fgets() returns NULL on error, not < 0 - -commit 434e57ae5ee79b3d990c4d75358047bad641998b -Author: Sven-Haegar Koch -Date: Sat May 28 03:46:39 2011 +0200 - - sparse fixup: warning: Using plain integer as NULL pointer - -commit f4010694b3b16453e5e6298c208910264e326978 -Author: Sven-Haegar Koch -Date: Sat May 28 03:57:20 2011 +0200 - - sparse fixup: warning: non-ANSI function declaration of function '...' - -commit d772289f6d6adfb8932658b533349d43f08ec326 -Author: Sven-Haegar Koch -Date: Sat May 28 03:56:06 2011 +0200 - - sparse fixup: warning: symbol '...' was not declared. Should it be static? - -commit 02e32cf61ee25d3d0e2fc1fef5cd98cbfa1c9a2f -Author: Sven-Haegar Koch -Date: Sat May 28 03:12:03 2011 +0200 - - sparse fixup: error: too many arguments for function send_key_changed - -commit b995243ac3d9605003996ba879808ddcbc77ae15 -Author: Sven-Haegar Koch -Date: Sat May 28 03:08:31 2011 +0200 - - sparse fixup: error: dubious one-bit signed bitfield - -commit bbd0025ae323e7141ba04a5371ec2f3f75f9b059 -Author: Sven-Haegar Koch -Date: Sat May 28 02:57:40 2011 +0200 - - Use same definition for xalloc_fail_func as is really used. - -commit 3fca2cad485ef70360bca085c5c4d052b6deb15b -Author: Sven-Haegar Koch -Date: Sat May 28 01:36:10 2011 +0200 - - Removed two newlines from the end of log messages which created empty lines. - -commit 9cce44dfe3401867f753778b73fd1e7ac1ee3122 -Author: Sven-Haegar Koch -Date: Sat May 28 01:33:45 2011 +0200 - - Fixed error logging on "Input buffer full" condition. - -commit 07ffb1a19859791d419b83a876ba552dadedbf46 -Author: Guus Sliepen -Date: Sun May 22 15:56:04 2011 +0200 - - Make return value of SetPriorityClass() behave the same as setpriority(). - -commit 453c44e7b27d4259461795ab4ec6ef264085dd28 -Author: Guus Sliepen -Date: Sun May 22 14:17:30 2011 +0200 - - Add the ability to dump all traffic going through route() over a control connection. - - One can get the packet stream in pcap format, which can be decoded using - tcpdump, for example: - - tincctl -n pcap | tcpdump -r - - -commit 54c900e961de6065f607f5661edeb7c84be29ea5 -Author: Guus Sliepen -Date: Sun May 22 14:02:27 2011 +0200 - - Reset tcplen after use. - -commit 8ddcad5fa1908727f68abb461b615c666616064f -Author: Guus Sliepen -Date: Sun May 22 13:15:27 2011 +0200 - - Check if an event is initialized before calling event_del(). - - Libevent prints a warning to stderr if we do that. - -commit 931e30f91a9241ab8aa705c911c92ba8943f80fd -Author: Guus Sliepen -Date: Sun May 22 13:15:05 2011 +0200 - - Always compact the buffer if it has reached MAXBUFSIZE. - -commit 90c7fafe594cf6d03c15a072a3d749f3e4d78482 -Author: Guus Sliepen -Date: Sun May 22 12:56:51 2011 +0200 - - Compact input buffer before trying to read instead of after. - - Also log an error when the input buffer contains more than MAXBUFSIZE bytes - already, instead of silently claiming the other side closed the connection. - -commit 8de8f1d9e2c2c02d4a14a5506e7d0d914dc328da -Author: Guus Sliepen -Date: Tue May 17 10:58:22 2011 +0200 - - Fix some compiler warnings. - -commit a80c18dd20e5303b26d5283e6cb5062a1812ddc3 -Author: Guus Sliepen -Date: Tue May 17 10:57:30 2011 +0200 - - Use GetItemCount() on ListCtrls instead of directly accessing ItemCount. - -commit f536504a7de90927b09d16f3bf0d3c6adead9955 -Author: Guus Sliepen -Date: Mon May 16 09:48:19 2011 +0200 - - Add top.h. - -commit e272fab858d5d3eeb43ff9f36268d25d3c6d32f1 -Author: Guus Sliepen -Date: Mon May 16 09:46:54 2011 +0200 - - Add tincctl.h. - -commit 6d97cb1e229c22d1d34aa9889aeaf17644ff06dc -Author: Guus Sliepen -Date: Sun May 15 16:30:13 2011 +0200 - - Nicer top command. - - - Configurable refresh interval. - - Switch between cumulative count or current rate. - - Configurable sorting. - -commit 4574b04f79d79d53492b7e0eb592d64ff9b2362b -Author: Guus Sliepen -Date: Sun May 15 16:29:54 2011 +0200 - - Allow inserting items in the middle of a list. - -commit 97355690b9cf8d8b56a316e01f73f8ff1fee68c8 -Author: Guus Sliepen -Date: Sun May 15 13:16:48 2011 +0200 - - Add a very primitive "top" command to tincctl. - -commit ec495b2f15fc5ae22136c226c7966caf51f643f8 -Author: Guus Sliepen -Date: Sun May 15 12:06:21 2011 +0200 - - Add an autoconf check for the curses library. - -commit 362d8a6358019cb97456c8133832f18798cea41f -Author: Guus Sliepen -Date: Sun May 15 11:59:13 2011 +0200 - - Dump traffic statistics over control sockets. - -commit f5843e7d649f4a7f72cb3fd356bc935457aa492f -Author: Guus Sliepen -Date: Sun May 15 00:42:29 2011 +0200 - - Add per-node traffic counters. - -commit ffa3a443b9f01d3ea0fcb3c4fc6928a5c695cf4a -Author: Guus Sliepen -Date: Sat May 14 22:30:23 2011 +0200 - - Several fixes for the buffer code. - -commit cdb793f687262b9f56823ca9046523a609a758af -Author: Guus Sliepen -Date: Sat May 14 19:20:56 2011 +0200 - - Remove use of bufferevent and eventbuffers, use our own buffering instead. - -commit f431fcb35f400be388a905ae0f7f50c1f5c4cd5d -Author: Guus Sliepen -Date: Sat May 14 19:15:04 2011 +0200 - - Add simple buffer management code. - - Libevent 2.0's buffer code is not completely backward compatible with 1.4's. - In order to not (mis)use it anymore, we implement it ourselves. The buffers - are automatically expanding when necessary. When consuming data from the - buffer, no memmove()s are performed. Only when adding to the buffer would - write past the end do we shift everything back to the start. - -commit 3794e551c7db9aa81405f65f7b04a9951c4120b2 -Author: Guus Sliepen -Date: Sat May 14 11:52:35 2011 +0200 - - Fix check for event initialization due to the merge. - -commit 03b7118139f57033659730afb740bf5cef7c961c -Author: Guus Sliepen -Date: Fri May 13 12:37:26 2011 +0200 - - Reorder checks for libraries to allow ./configure LDFLAGS=-static. - - OpenSSL depends on libdl and libz. When linking dynamically, libcrypto will - automatically link with the other two libraries. However, when linking - statically, these libraries need to be specified explicitly while linking. By - moving the autoconf checks for libdl and libz before those for libcrypto, we - ensure the latter test will be done with the proper libraries. - -commit ce8775000ab38229a78ecf3dc26bab008ca0f332 -Merge: 3f59a26d 5686ad80 -Author: Guus Sliepen -Date: Mon May 9 21:35:14 2011 +0200 - - Merge branch 'master' of git://tinc-vpn.org/tinc into 1.1 - - Conflicts: - NEWS - README - configure.in - doc/tincd.8.in - lib/pidfile.c - src/bsd/device.c - src/dropin.h - src/net.c - src/net_packet.c - src/node.c - src/process.c - src/tincd.c - -commit 5686ad80b545afa3de9ed2f4176a5346e289aaa8 -Author: Guus Sliepen -Date: Sun May 8 23:17:46 2011 +0200 - - Releasing 1.0.14. - -commit 0d906489f2ce9faf81dc230f7db6ab5378573554 -Author: Guus Sliepen -Date: Sun May 8 23:12:44 2011 +0200 - - Include when using intptr_t. - -commit dc887f5011834d5a9a6ec5deb8781c6bfd88c474 -Author: Guus Sliepen -Date: Sun May 8 23:12:06 2011 +0200 - - Ensure proper linking with OpenSSL with recent versions of MinGW. - -commit 67766d65f06854ee894d784f638c5c9cd2b50bca -Author: Guus Sliepen -Date: Sun May 8 21:22:20 2011 +0200 - - Update THANKS and copyright information. - -commit 6e6b037ef4fd9877aeb1d947da7364409fa8cbb7 -Author: Guus Sliepen -Date: Sun May 8 21:06:06 2011 +0200 - - Check for EVP_EncryptInit_ex instead of SHA1_Version in OpenSSL. - - The latter function disappeared, and wasn't actually used in tinc, so now we - check on a function that we do use. - -commit 257cb6ac60bb0924720de9e252cdf7f4759bf741 -Author: Guus Sliepen -Date: Sun May 8 12:40:44 2011 +0200 - - Always use the default signal handler for ABRT signals. - - This will allow coredumps to be generated when tinc is daemonized. - Also add the -kABRT option. - -commit eacb5a28fb4c1515633f2b8a206e7067bc7b8f0c -Author: Guus Sliepen -Date: Sun May 8 12:16:26 2011 +0200 - - Increase threshold for detecting two nodes with the same Name. - - In commit 4a21aabada23d1d2c8a10f54dd7248171c4ec82f, code was added to detect - contradicting ADD_EDGE and DEL_EDGE messages being sent, which is an indication - of two nodes with the same Name connected to the same VPN. However, these - contradictory messages can also happen when there is a network partitioning. In - the former case a loop happens which causes many contradictory message, while - in the latter case only a few of those messages will be sent. So, now we - increase the threshold to at least 10 of both ADD_EDGE and DEL_EDGE messages. - -commit f11c6101f30df645223920bef3eb7592de9bcb79 -Author: Julien Muchembled -Date: Thu Apr 28 13:21:55 2011 +0200 - - Fix command-line '-o' option for host configuration - - This fixes a regression introduced by commit 667b1ba while refactoring option - parsing code. - -commit 0aa86d4b8b3010522e6de8842f5bd29004ba3df6 -Author: Guus Sliepen -Date: Wed Mar 9 09:34:56 2011 +0100 - - Do not set indirect flag on edges from nodes with multiple addresses. - - Since tinc now handles UDP packets with a different source address and port - than used for TCP connections, the heuristic to treat edges as indirect when - tinc could detect that multiple addresses were used does not make sense - anymore, and can actually reduce performance. - -commit 7cf68b5e35c002511cc7468967de6a75934cc998 -Author: Guus Sliepen -Date: Fri Feb 18 23:11:43 2011 +0100 - - Prevent anything from updating our own UDP address. - - Because we don't want to keep track of that, and this will cause the node - structure from being relinked into the node tree, which results in myself - pointing to an invalid address. - -commit cdbbbfabea173894bd2fb5f28135a04ddc5e3fd7 -Author: Guus Sliepen -Date: Fri Feb 18 23:02:11 2011 +0100 - - Fix spurious misidentification of incoming UDP packets. - - When a UDP packet was received with an unknown source address/port, and if it - failed a HMAC check against known keys, it could still incorrectly assign that - UDP address to another node. This would temporarily cause outgoing UDP packets - to go to the wrong destination address, until packets from the correct address - were received again. - -commit 046d83bf91e01bc7a32e66a02758caf228bc4601 -Author: Rumko -Date: Sat Feb 12 18:22:14 2011 +0100 - - DragonFlyBSD support - - * added DragonFly BSD support - * added a check for sys/resource.h (needed on DragonFly) - -commit f017c7f98f8f68d6ca50ebe247f4115aadd93635 -Author: Guus Sliepen -Date: Mon Feb 7 18:34:55 2011 +0100 - - Add support for VDE through libvdeplug. - - When compiled with vde/device.c, tinc will connect to a vde_switch instance - instead of using a tun/tap device. - -commit 8d18cc6c4e625625a2437d26c587f9f382a0c589 -Author: Guus Sliepen -Date: Sat Jan 29 10:49:44 2011 +0100 - - Fix typo spotted by Andrew Scheller. - -commit b3731c04097e66a6b8908bb893c5da831d89c04d -Author: Guus Sliepen -Date: Wed Jan 12 20:57:14 2011 +0100 - - Proper check and dropin replacement for usleep(). - -commit 4b8a5993036fccc2108fcc2550649d9b78fb1ab7 -Author: Guus Sliepen -Date: Sun Jan 2 17:25:24 2011 +0100 - - Update the NEWS. - -commit c228da54d47657811dfb679e7f138cbba58a9f67 -Author: Guus Sliepen -Date: Sun Jan 2 17:25:03 2011 +0100 - - Update the manual. - -commit 4575c6c7dffe228ce302776022a2075b7ef37ab0 -Author: Guus Sliepen -Date: Sun Jan 2 17:24:23 2011 +0100 - - Document the behavior of "-n." - -commit 6c05bf082b1ce9acfc0ebb5c6f32c2ece41c7f80 -Author: Guus Sliepen -Date: Sun Jan 2 16:59:42 2011 +0100 - - Remove unused variables. - -commit 6a51d89cf706bcefce1861a1a66d40ef7d7db43b -Author: Guus Sliepen -Date: Sun Jan 2 16:55:42 2011 +0100 - - Replace bogus #else with #endif. - - Found by cppcheck, which complained about lenin not being initialized, but the - real problem is that reading packets would fail when using code compiled with - --tunemu on a normal tun device. - -commit d7636352ce359e807b392a6e5ac0a6aeff4a63d2 -Author: Guus Sliepen -Date: Sun Jan 2 16:52:36 2011 +0100 - - Limit field width when scanning PID file. - - Cppcheck warns that scanf() might otherwise crash when presented with a huge, - bogus PID file. - -commit 3ce5e292da8bab3a1316faf1ca18625f05074467 -Author: Guus Sliepen -Date: Sun Jan 2 16:50:24 2011 +0100 - - Close all filedescriptors in Solaris close_device(). - -commit f99661a4ca5bacff47239ce7978b9c9948917c54 -Author: Guus Sliepen -Date: Sun Jan 2 15:02:23 2011 +0100 - - Always send MTU probes at least once every PingInterval. - - Before, if MTU probes failed, tinc would stop sending probes until the next - time keys were regenerated (by default, once every hour). Now it continues to - send them every PingInterval, so it recovers faster from temporary failures. - -commit cac0a5c651535e8317839b0deff1ee98086a8184 -Author: Guus Sliepen -Date: Sat Nov 20 14:31:11 2010 +0000 - - Use setpriority() instead of nice() on UNIX-like systems. - - The return value of nice() can not reliably indicate errors. The return value - of the setpriority() call is well-defined. - -commit 3f59a26d8098b8b0902b8746715508360b347f47 -Author: Guus Sliepen -Date: Fri Nov 19 12:26:20 2010 +0000 - - Do not try to dereference myself->connection->config_tree. - - This was a bug introduced due to an incomplete merge (commit - ff71f289022ccb91abc2726f16522d55b5ccf0f6). - -commit 886a6f61a1f4cc48a77b42d10f34f9126377d904 -Merge: 23dddc25 d91903ef -Author: Guus Sliepen -Date: Fri Nov 19 12:22:48 2010 +0000 - - Merge branch 'master' into 1.1 - - Conflicts: - src/net_packet.c - src/openssl/rsagen.h - src/protocol_auth.c - src/protocol_key.c - -commit d91903ef3c2a1f4481ae8757bb2b14282f2b7e68 -Author: Guus Sliepen -Date: Tue Nov 16 17:28:41 2010 +0100 - - Attribution for Brandon Black. - -commit e764ff7be9949c91865aff72844357e76ae6dd78 -Author: Guus Sliepen -Date: Tue Nov 16 16:45:36 2010 +0100 - - Fix variable length array declaration. - -commit 5eb0440110f99f0a49838cc00a0686c7a7595663 -Author: Guus Sliepen -Date: Sat Nov 13 21:36:51 2010 +0100 - - Free replay window when freeing a node_t. - -commit a9445e38f25bd24eca289768fc46e44e36b842ac -Author: Guus Sliepen -Date: Sat Nov 13 21:34:59 2010 +0100 - - Fix warning message when setting SO_RCVBUF or SO_SNDBUF fails. - -commit 0d61d4ae1358553fc8dde350747542f137f5cb8b -Author: Brandon L Black -Date: Sat Nov 13 12:05:51 2010 -0600 - - Improved handling of queue-jumping packets on receive - -commit 23acc19bc090051156ad895caed61848f5afb144 -Author: Brandon L Black -Date: Sat Nov 13 12:05:50 2010 -0600 - - Configurable ReplayWindow size, zero disables - -commit 8dfe1b374e165ecba5d3ae324ee834d337476be8 -Author: Brandon L Black -Date: Sat Nov 13 12:05:49 2010 -0600 - - Configurable SO_RCVBUF/SO_SNDBUF for the UDP socket - -commit 3f410e2f8f7c365630f226adf4904935698f9e0d -Author: Brandon L Black -Date: Sat Nov 13 12:05:48 2010 -0600 - - Experimental IFF_ONE_QUEUE support for Linux - -commit 9e3ca397735077f85bbde48c36e1b3e0fa950988 -Author: Guus Sliepen -Date: Sat Nov 13 15:55:38 2010 +0100 - - Use variable length arrays instead of alloca(). - -commit e2e6ec8050274b0a8678d6fc263e7dc4ef66feae -Author: Guus Sliepen -Date: Sat Nov 13 15:50:39 2010 +0100 - - Provide usleep() for Windows. - -commit 23dddc25930bc9033e5a2ac659376032aff44d82 -Author: Guus Sliepen -Date: Sat Nov 13 15:46:19 2010 +0100 - - Link tincctl with dropin.o. - -commit a22041922f160667573e9a5ae3f4195e1668906a -Merge: 8b70c5be 930bf74f -Author: Guus Sliepen -Date: Fri Nov 12 16:15:29 2010 +0100 - - Merge branch 'master' into 1.1 - - Conflicts: - doc/tincd.8.in - lib/pidfile.c - src/graph.c - src/net.c - src/net.h - src/net_packet.c - src/net_setup.c - src/net_socket.c - src/netutl.c - src/node.c - src/node.h - src/protocol_auth.c - src/protocol_key.c - src/tincd.c - -commit 930bf74fbe5ce8363b6cc2ae3a3e960e910e0996 -Author: Guus Sliepen -Date: Fri Nov 12 11:38:05 2010 +0100 - - Don't use strlen() on a NULL pointer. - - A bug introduced in commit 667b1bac77b134cf32c98d5dc25619e8c3303f52 caused tinc - to crash on startup. - -commit a07aa92176571eb7f063708640d0d486280808ef -Author: Guus Sliepen -Date: Fri Nov 12 11:33:01 2010 +0100 - - Add short options -R and -U to the tincd(8) manpage. - -commit 66b7aea294896a99df289231143a506b422b994c -Author: Guus Sliepen -Date: Tue Nov 2 14:23:43 2010 +0100 - - Read error counter must be static. - -commit a91bf2dfcd0f5857905e59da7d944654e0875503 -Author: Guus Sliepen -Date: Tue Nov 2 14:18:35 2010 +0100 - - Quit when there are too many consecutive errors on the tun/tap device. - - Although transient errors sometimes happen on the tun/tap device (for example, - if the kernel is temporarily out of buffer space), there are situations where - the tun/tap device becomes permanently broken. Instead of endlessly spamming - the syslog, we now sleep an increasing amount of time between consecutive read - errors, and if reads still fail after 10 attempts (approximately 3 seconds), - tinc will quit. - -commit aca70cd3c3fe787e62c618849e43f67b3870ac20 -Author: Michael Tokarev -Date: Sun Oct 24 15:23:10 2010 +0400 - - Treat netname="." in a special way. - - Treat netname "." in a special way as if there was no netname - specified. Before, f.e. tincd -n. -k didn't work as it tried - to open /var/run/tinc-.pid. Now -n. works as if there was no - -n option is specified. - - Signed-Off-By: Michael Tokarev - -commit 5f729f76f5a63114df582fc29f4189140c1e5ead -Author: Guus Sliepen -Date: Fri Oct 22 22:46:44 2010 +0200 - - Remove unused variables. - - These were caused by commit 667b1bac77b134cf32c98d5dc25619e8c3303f52. - -commit 20ae7dd8c12390f7360eb28cc17e1b8a8a706b06 -Author: Guus Sliepen -Date: Fri Oct 22 22:43:50 2010 +0200 - - Abort disabling old PEM keys on I/O errors. - -commit a08462bf845973016e061b8ca1233142d80416f6 -Author: Guus Sliepen -Date: Fri Oct 22 22:42:21 2010 +0200 - - Ensure there is a newline character before a PEM key is written. - -commit c6ccbadfcf93a7bd4a88dee8ff146b4db7f85e71 -Author: Guus Sliepen -Date: Fri Oct 22 13:40:04 2010 +0200 - - Attribution for Timothy Redaelli. - -commit 1c2cd7ed273ee1538ff8a13d036c68aa9992c4aa -Author: Guus Sliepen -Date: Fri Oct 22 13:17:42 2010 +0200 - - Attribution for Julien Muchembled. - -commit 667b1bac77b134cf32c98d5dc25619e8c3303f52 -Author: Guus Sliepen -Date: Fri Oct 22 13:06:06 2010 +0200 - - Remove duplicate command-line option parsing. - - Also fix parsing of command-line host configuration options for the local node. - -commit ff71f289022ccb91abc2726f16522d55b5ccf0f6 -Author: Guus Sliepen -Date: Fri Oct 22 12:47:12 2010 +0200 - - Merge local host configuration with server configuration. - - With some exceptions, tinc only accepted host configuration options for the - local node from the corresponding host configuration file. Although this is - documented, many people expect that they can also put those options in - tinc.conf. Tinc now internally merges the contents of both tinc.conf and the - local host configuration file. - -commit 8c3105283ac53f8cc9cc4dde25957ec1cf6b53a0 -Author: Julien Muchembled -Date: Fri Sep 3 13:34:22 2010 +0200 - - New '-o' option to configure server or hosts from command line - - Options given on the command line have precedence over configuration from files. - - This can be useful, for example, for a roaming node, for which 'ConnectTo' and - .Address depends on its location. - -commit 4b6a9f1c1f645ce5989692655337d9e23ca28648 -Author: Guus Sliepen -Date: Fri Jun 4 16:03:19 2010 +0200 - - Do not append an address to ANS_KEY messages if we don't know any address. - - This would let tinc raise an exception when an ANS_KEY request crossed a - DEL_EDGE request for the node sending the key. - -commit 798fa2f04c52b0639713f74b1195847bec40c16a -Author: Guus Sliepen -Date: Fri Jun 4 15:04:08 2010 +0200 - - Use 64 bit counters to keep track of bytes sent/received from the virtual network interface. - -commit 4a21aabada23d1d2c8a10f54dd7248171c4ec82f -Author: Guus Sliepen -Date: Fri Jun 4 14:53:52 2010 +0200 - - Detect and prevent two nodes with the same Name being on the VPN simultaneously. - - In this situation, the two nodes will start fighting over the edges they announced. - When we have to contradict both ADD_EDGE and DEL_EDGE messages, we log a warning, - and with 25% chance per PingTimeout we quit. - -commit dbf3d168b720045328d476f3b9e5f5e45b4ab6de -Author: Guus Sliepen -Date: Fri May 7 12:24:49 2010 +0200 - - Use strrchr() insteaad of rindex(). - - The latter function is deprecated, some build environments do not support. - -commit eda71798749e8b0abf5e8b3cbc11da82aa607f00 -Author: Timothy Redaelli -Date: Tue May 4 15:43:48 2010 +0200 - - Fix warnings under BSD - -commit df985256a766ee90f2fa4269b95fa0565c969dda -Author: Timothy Redaelli -Date: Tue May 4 00:27:44 2010 +0200 - - Fix warnings showed using -D_FORTIFY_SOURCE=2 - -commit f5122ccecee095b9185b2324dea7bcd9655462ee -Author: Guus Sliepen -Date: Sat May 1 15:39:59 2010 +0200 - - Fix all warnings when compiling with mingw64. - -commit ef92a5725c47c6e8e801e07190dd7dd3f9cb3a17 -Author: Guus Sliepen -Date: Sat May 1 15:39:03 2010 +0200 - - OpenSSL 1.0.0 compiled for 64 bit Windows requires linking with -lcrypt32. - -commit 0fdd7da52077d77a11a3646eb3e7d5b6ffa178e8 -Author: Guus Sliepen -Date: Sat May 1 15:38:04 2010 +0200 - - Use intptr_t instead of long to store a pointer. - -commit c94ede3b8708cdf105a3fecfc119a558e1583f27 -Author: Guus Sliepen -Date: Sat May 1 15:37:11 2010 +0200 - - Define WINVER before including any other header file on Windows. - -commit 8b70c5be9bc762d81354f9cd77c3748a44a4956d -Author: Guus Sliepen -Date: Fri Apr 30 23:18:22 2010 +0200 - - Remove obsolete lib/ directory. - -commit ee427cac0d04c60d09cc235c04664eab8b0c6527 -Author: Guus Sliepen -Date: Fri Apr 30 23:13:02 2010 +0200 - - Do not try to free NULL pointers. - -commit 113458c2864ec8c046ab7d63ff1b417252c8e4df -Author: Guus Sliepen -Date: Fri Apr 30 23:11:48 2010 +0200 - - Use correct digest length when checking a received key. - -commit 76b41ba20dc9783ff0d21dd738739a81d62142e7 -Author: Guus Sliepen -Date: Sat Apr 17 12:33:36 2010 +0200 - - Add missing return statement. - -commit 2911af6e23d0dba6d771fcd590551a84bd9dc932 -Author: Guus Sliepen -Date: Sat Apr 17 12:33:15 2010 +0200 - - Fix merge of commit 4a0b9981513059755b9fd15b38fc198f46a0d6f2. - -commit 79e46d08a46f2fef2ee4e8eac7ba487007160564 -Merge: 4ce4af4c 4766359e -Author: Guus Sliepen -Date: Sat Apr 17 12:21:53 2010 +0200 - - Merge branch 'master' into 1.1 - - Conflicts: - NEWS - README - configure.in - src/net.c - src/net.h - -commit 4ce4af4c712c80d08630767ec34787253da1021b -Author: Guus Sliepen -Date: Sat Apr 17 12:03:08 2010 +0200 - - Fix experimental GUI when reading hexadecimal values. - -commit 4766359e1426bdf1383c898d6103d8760e5e296d -Author: Guus Sliepen -Date: Sat Apr 17 12:01:38 2010 +0200 - - Fix reading configuration files that do not end with a newline. Again. - -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 e49891e188f618a0e98f1d30bcbf240286e8ad5c -Author: Sven-Haegar Koch -Date: Wed Mar 31 03:56:53 2010 +0200 - - Fixed metadata protokoll corruption on forwarded requests - - When forwarding a metadata request through forward_request() we were - adding the required newline char to our buffer, but then sending the - data without it - this results in the forwarded request and the next one - to be garbled together. - - Additionally while at it add a warning comment that request string is - not zero terminated anymore after a call to the forward_request() - function - for now this is ok as it is not used by any caller after this. - -commit 0310deb225cad21c458fb32fd589027e3f844735 -Author: Sven-Haegar Koch -Date: Fri Mar 26 17:25:18 2010 +0100 - - Demote all LOG_EMERG to LOG_ERR, spamming all xterms is bad. - -commit d5654f568dcaf81341395b52b2711f68c0417ec6 -Author: Sven-Haegar Koch -Date: Fri Mar 26 16:54:13 2010 +0100 - - README.git: tinc 1.1 needs libevent - -commit 685509ffe10d1bf9c409e5ba90f46cd747f2d9cd -Author: Sven-Haegar Koch -Date: Sun Mar 28 17:51:26 2010 +0200 - - Function flush_meta() does not exist anymore. - -commit c6d2b9d734859ccbd9582b28351983a12b04abb0 -Author: Sven-Haegar Koch -Date: Fri Mar 26 17:07:30 2010 +0100 - - Add missing AC_CHECK_HEADERS([dirent.h]) to configure.in - -commit ffa1dc73dcd62a856325641972a13d398aa8121c -Author: Sven-Haegar Koch -Date: Fri Mar 26 17:18:04 2010 +0100 - - Fixed 1.0 miss-merges - -commit 103543aa2c15d9f1e2aa313a2e593a7524cce484 -Merge: 35b1c250 29235491 -Author: Sven-Haegar Koch -Date: Fri Mar 26 16:51:03 2010 +0100 - - Merge branch 'master' into 1.1 - - Conflicts: - NEWS - README - configure.in - have.h - src/conf.c - src/conf.h - src/net.c - src/net_packet.c - src/protocol_key.c - src/protocol_subnet.c - src/route.c - src/tincd.c - -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 - - 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 35b1c25093a478d20e01f0ff391c9cdc9c41c2b8 -Author: Guus Sliepen -Date: Thu Dec 31 13:19:13 2009 +0100 - - Move source from lib/ to src/. - - The utility functions in the lib/ directory do not really form a library. - Also, now that we build two binaries, tincctl does not need everything that was - in libvpn.a, so it is wasteful to link to it. - -commit 41497246eeccbcc417f93c2ae087e927751c6914 -Author: Guus Sliepen -Date: Thu Dec 31 13:09:14 2009 +0100 - - Remove unused AVL tree library. - -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 36261650024ba8e18f9c77396f1d7a4e51f20602 -Author: Guus Sliepen -Date: Sat Dec 19 23:23:25 2009 +0100 - - Do not use hardcoded cipher block length when padding. - -commit f542ef8f9e645bf30e11e196dd768fac4f957eac -Author: Guus Sliepen -Date: Sat Dec 19 22:17:39 2009 +0100 - - Fix alignment of results of RSA operations when using libgcrypt. - - If the result of an RSA encryption or decryption operation can be represented - in less bytes than given, gcry_mpi_print() will not add leading zero bytes. Fix - this by adding those ourself. - -commit 4c68a8cb60eb0a4c05d9ce98963b930a976b55ee -Author: Guus Sliepen -Date: Sat Dec 19 20:53:48 2009 +0100 - - Do not consider unreachable nodes when trying to determine packet origin. - -commit 74e50d52e0e23c9dd1e21fb447f1e1a59d02d0b2 -Author: Guus Sliepen -Date: Sat Dec 19 20:52:19 2009 +0100 - - recv() and recvfrom() return int, do not prematurely cast the return value. - -commit 0bfd69a2736cb98470b47c1f6cba617b58bb86ef -Author: Guus Sliepen -Date: Sat Dec 19 20:26:30 2009 +0100 - - Fix reading raw RSA keys with libgcrypt. - -commit 0ff44fc2417217d542bf0e9a7ecfd20020893bc7 -Author: Guus Sliepen -Date: Sat Dec 19 20:10:38 2009 +0100 - - Reinitialise block cipher IV each time we encrypt a packet when using libgcrypt. - -commit 3c90be7678566203d38624c4a6fe3affaffbe5e3 -Author: Guus Sliepen -Date: Sat Dec 19 18:57:54 2009 +0100 - - Fix block cipher padding when using libgcrypt. - -commit c845bc109c85e6fb350096c63e13ef8e617ee29b -Author: Guus Sliepen -Date: Fri Dec 18 01:15:25 2009 +0100 - - Fix packet authentication. - - This wasn't working at all, since we didn't do HMAC but just a plain hash. - Also, verification of packets failed because it was checking the whole packet, - not the packet minus the HMAC. - -commit 10d609b1f0dd9eeb024cd40359683d48542aecbf -Author: Guus Sliepen -Date: Wed Dec 16 21:18:21 2009 +0100 - - Start of a GUI for tinc. - -commit 55ef2f806f9840103bceb472564a711b22e73d58 -Author: Guus Sliepen -Date: Wed Dec 16 21:16:56 2009 +0100 - - Allow connections to be closed. - - This only closes existing meta connections, it may not affect node - reachability. - -commit f12c36afd5293ddbecccf13f36edb8d36e56f040 -Author: Guus Sliepen -Date: Mon Dec 14 21:25:06 2009 +0100 - - Include missing header files and source directories. - -commit 2a410cd26d25cc01b96d255644df3ad138eae776 -Author: Guus Sliepen -Date: Mon Dec 14 21:20:56 2009 +0100 - - Do not include OpenSSL headers directly. - -commit 5d78e497f1c352c8d490eed1d44d128523a34572 -Author: Guus Sliepen -Date: Fri Dec 11 22:38:06 2009 +0100 - - Fix compiler warnings. - -commit d6c50eb73ad49bd2eac67214995dff76b7a20661 -Merge: fec14791 369fe1ab -Author: Guus Sliepen -Date: Fri Dec 11 22:31:27 2009 +0100 - - Merge branch 'master' into 1.1 - - Conflicts: - src/subnet.c - -commit fec14791e869180bb7994ca38ca7006cc2e957fb -Author: Guus Sliepen -Date: Fri Dec 11 22:24:07 2009 +0100 - - Only call ioctlsocket() on Windows. - -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 edebf579f2ea29e6e84360cb13731f5858a1555b -Author: Guus Sliepen -Date: Sat Nov 7 23:43:25 2009 +0100 - - Use the TCP socket infrastructure for control sockets. - - The control socket code was completely different from how meta connections are - handled, resulting in lots of extra code to handle requests. Also, not every - operating system has UNIX sockets, so we have to resort to another type of - sockets or pipes for those anyway. To reduce code duplication and make control - sockets work the same on all platforms, we now just connect to the TCP port - where tincd is already listening on. - - To authenticate, the program that wants to control a running tinc daemon must - send the contents of a cookie file. The cookie is a random 256 bits number that - is regenerated every time tincd starts. The cookie file should only be readable - by the same user that can start a tincd. - - Instead of the binary-ish protocol previously used, we now use an ASCII - protocol similar to that of the meta connections, but this can still change. - -commit c388527e341658dc915dd67c90bbc9b52b8539c0 -Author: Guus Sliepen -Date: Sat Nov 7 16:09:56 2009 +0100 - - Small fixes to get really working control sockets on Windows. - -commit 5c5548fc7185cc1462602dadcd39a53cef481d29 -Author: Guus Sliepen -Date: Sat Nov 7 14:35:48 2009 +0100 - - Better integration of libevent in build system. - - Since event.h is not part of tinc, we include it in have.h were all other - system header files are included. We also ensure -levent comes before -lgdi32 - when compiling with MinGW, apparently it doesn't work when the order is - reversed. - -commit 075264a9e18f9fd58cad044c064a91557e9ed429 -Author: Guus Sliepen -Date: Thu Nov 5 23:29:28 2009 +0100 - - Make sure the 1.1 branch compiles in a MinGW environment. - - UNIX domain sockets, of course, don't exist on Windows. For now, when compiling - tinc in a MinGW environment, try to use a TCP socket bound to localhost as an - alternative. - -commit 08615e420b2dd5054dd978bf53c88b8dde6e4788 -Author: Guus Sliepen -Date: Thu Nov 5 00:02:42 2009 +0100 - - Handle PKCS#5 padding in the gcrypt backend. - -commit d9b2ac6767f85927a26e2b95bba69c052ac503ac -Author: Guus Sliepen -Date: Thu Nov 5 00:01:25 2009 +0100 - - Handle truncated message authentication codes with gcrypt. - - Commit 4124b9682f8f890acb25d0c92f2583eef670274a did not update the gcrypt - backend. - -commit c4afc481541bff4db7f57c81796b7a5f61cdb1b5 -Author: Guus Sliepen -Date: Wed Nov 4 16:19:08 2009 +0100 - - Use %x instead of %lx where appropriate. - - Some conversions were not properly merged from the master branch. - -commit 37ccb325af5c7865eb16716780121a8a6dce8abd -Author: Guus Sliepen -Date: Wed Nov 4 16:18:08 2009 +0100 - - Don't enable device events when there is no valid filedescriptor. - -commit 108b238915c5f58b3d94ab433dc5d04e064c2b11 -Merge: 761517c2 44834d03 -Author: Guus Sliepen -Date: Mon Nov 2 14:24:27 2009 +0100 - - Merge branch 'master' into 1.1 - - Conflicts: - NEWS - README - configure.in - doc/tinc.texi - doc/tincd.8.in - src/Makefile.am - src/connection.c - src/edge.c - src/meta.c - src/net.c - src/net.h - src/net_packet.c - src/net_setup.c - src/net_socket.c - src/node.c - src/openssl/rsagen.h - src/protocol_auth.c - src/protocol_edge.c - src/subnet.c - -commit 44834d030464bbe1f7733caba8d96c678f1d6cf2 -Author: Guus Sliepen -Date: Sun Nov 1 16:24:39 2009 +0100 - - Releasing 1.0.11. - -commit d331f04e4598824afc7de33ac1228cf441ae9872 -Author: Guus Sliepen -Date: Sun Nov 1 15:57:28 2009 +0100 - - Start a tinc service if it already exists. - -commit 6f6f426b353596edca77829c0477268fc2fc1925 -Author: Guus Sliepen -Date: Tue Oct 27 23:53:49 2009 +0100 - - Fast handoff of roaming MAC addresses. - - In switch mode, if a known MAC address is claimed by a second node before it - expired at the first node, it is likely that this is because a computer has - roamed from the LAN of the first node to that of the second node. To ensure - packets for that computer are routed to the second node, the first node should - delete its corresponding Subnet as soon as possible, without waiting for the - normal expiry timeout. - -commit e00b44cb98e4d50a0d426048ba01dbd80bcb5941 -Author: Guus Sliepen -Date: Sun Oct 25 01:40:07 2009 +0200 - - Move socket error interpretation to utils.h. - -commit c11dc8079b60d9f8c5b1c7e8fecd90d0fac5a20c -Author: Guus Sliepen -Date: Sun Oct 25 00:50:09 2009 +0200 - - Use WSAGetLastError() to determine cause of network errors on Windows. - - This reduces log spam and lets path MTU discovery work faster. - -commit 1bca167b7e24a9cb00ad6130c24f0bb60e208f1f -Author: Michael Tokarev -Date: Sun Oct 18 21:27:24 2009 +0400 - - Remove localedir leftovers. - -commit c3acae034c4da2d1c70f31b852b14ca098c0eeb9 -Author: Guus Sliepen -Date: Sat Oct 24 22:32:35 2009 +0200 - - Use IP_DONTFRAGMENT instead of IP_MTU_DISCOVER on Windows. - - This ensures the DF bit on outgoing UDP packets gets set on Windows when path - MTU discovery is enabled, reducing fragmentation. - -commit 242c4e2ca67d0b5c78dfe6e68a5ddcd27be1de99 -Author: Guus Sliepen -Date: Sat Oct 24 21:53:01 2009 +0200 - - Forward packets to not directly reachable hosts via UDP if possible. - - If MTU probing discovered a node was not reachable via UDP, packets for it were - forwarded to the next hop, but always via TCP, even if the next hop was - reachable via UDP. This is now fixed by retrying to send the packet using - send_packet() if the destination is not the same as the nexthop. - -commit d922db253cd098bc038449e5c591cc94c1019952 -Author: Guus Sliepen -Date: Sat Oct 24 21:35:40 2009 +0200 - - Make maxmtu equal to minmtu when fixing the path MTU to a node. - - This ensures MTU probes used to ping nodes are not too large, and prevents - restarting MTU probing unnecessarily. - -commit a8f7fccbc2b5f1c4c39fc2804abaa358b31a5080 -Author: Guus Sliepen -Date: Sat Oct 24 21:32:06 2009 +0200 - - Always reply to MTU probes via UDP. - - It could sometime happen that a node would return MTU probes via TCP, which - does not make a lot of sense. - -commit cddcdc9af34afb388a8e4bdfff6882f568b98313 -Author: Guus Sliepen -Date: Sat Oct 24 20:54:44 2009 +0200 - - Allow UDP packets with an address different from the corresponding TCP connection. - -commit 5cbddc68bade0d1f8ded1b784bb27bb44c5dc5dc -Author: Guus Sliepen -Date: Sat Oct 24 16:15:24 2009 +0200 - - Use uint32_t instead of long int for connection options. - - Options should have a fixed width anyway, but this also fixes a possible MinGW - compiler bug where %lx tries to print a 64 bit value, even though a long int is - only 32 bits. - -commit 468f393c4fabf9223a1bd15adfb3906cde90d547 -Author: Guus Sliepen -Date: Sat Oct 24 16:05:12 2009 +0200 - - Add dummy device. - -commit b6543af7626403516b5fc54c24b11d3a242a2992 -Author: Guus Sliepen -Date: Tue Oct 20 22:39:07 2009 +0200 - - Clarify and increase level of log message about MTU probes to unreachable nodes. - -commit 43a6e786648fb666a9b7be8f05c8a173031c9110 -Author: Guus Sliepen -Date: Tue Oct 20 22:33:16 2009 +0200 - - Handle weighted Subnets in switch and hub modes. - - We now handle MAC Subnets in exactly the same way as IPv4 and IPv6 Subnets. - This also fixes a problem that causes unncessary broadcasting of unicast - packets in VPNs where some daemons run 1.0.10 and some run other versions. - -commit 3a925479c2883a6a9711f7b6931863d7f2a2c09b -Author: Guus Sliepen -Date: Tue Oct 20 22:22:59 2009 +0200 - - Starting to work towards 1.0.11. - -commit 35af4051c3749cd2c2137a7eb57171a1fbb12af7 -Author: Guus Sliepen -Date: Tue Oct 20 22:14:47 2009 +0200 - - Fix a possible crash when sending the HUP signal. - - When the HUP signal is sent while some outgoing connections have not been made - yet, or are being retried, a NULL pointer could be dereferenced resulting in - tinc crashing. We fix this by more careful handling of outgoing_ts, and by - deleting all connections that have not been fully activated yet at the HUP - signal is received. - -commit 8c267d3d558ac97a4ce7381a37abb6cc4b46b133 -Author: Guus Sliepen -Date: Sun Oct 18 16:45:13 2009 +0200 - - Releasing 1.0.10. - -commit 3849de9a331ad132ed9d01c9f0cac47196624b3e -Author: Guus Sliepen -Date: Sun Oct 18 16:44:32 2009 +0200 - - Fix description of the WEIGHT environment variable. - -commit 87364c16564c897b1a2d306615804d68ea5a9ba1 -Author: Guus Sliepen -Date: Sun Oct 18 14:22:20 2009 +0200 - - Include missing header. - -commit c7fdc7d5b8d728c744b13a823e7eef9d2432c61e -Author: Guus Sliepen -Date: Mon Oct 12 23:51:57 2009 +0200 - - Remove debugging message when reading packets from a BSD device. - - This was inadvertently introduced by commit - 4a5d42178cc0954efba8b24058da9c70cc77c35a. - -commit ec4c8bcb18c1f463cf4544126e027fc8ec9b3a39 -Author: Guus Sliepen -Date: Mon Oct 12 22:14:47 2009 +0200 - - Allow the cloning /dev/tap interface to be used on FreeBSD and NetBSD. - - This device works like /dev/tun on Linux, automatically creating a new tap - interface when a program opens it. We now pass the actual name of the newly - created interface in $INTERFACE. - -commit 92b8abc921dd15b710f67335562210eb713fbb39 -Author: Guus Sliepen -Date: Sun Oct 11 18:57:58 2009 +0200 - - Use MTU probes to regularly ping other nodes over UDP. - - This keeps NAT mappings for UDP alive, and will also detect when a node is not - reachable via UDP anymore or if the path MTU is decreasing. Tinc will fall back - to TCP if the node has become unreachable. - - If UDP communication is impossible, we stop sending probes, but we retry if it - changes its keys. - - We also decouple the UDP and TCP ping mechanisms completely, to ensure tinc - properly detects failure of either method. - -commit 927064e5fd0ebf29a7ea768a7f9c4226da626a72 -Author: Guus Sliepen -Date: Sun Oct 11 15:46:52 2009 +0200 - - Small updates to the documentation. - - Mention that TCPOnly is not necessary anymore since tinc will autodetect - whether it can send via UDP or not. Also mention the WEIGHT environment - variable and the new default value (2048 bits) of RSA keys. - -commit 2c30af6c90926340a89748c63cc453b1c0b5a589 -Author: Guus Sliepen -Date: Sun Oct 11 14:20:14 2009 +0200 - - Ensure that the texinfo manual can be converted to HTML. - - The top node was made conditional with the @iftex command, since it should not - appear in PostScript and PDF output. However, it is still necessary for - texi2html, so we have to use @ifnottex instead. - - Texi2html also complains about the use of @cindex in the copyright statement, - so we remove that. - -commit a4f132770dc136d456c67b01d209e73f5f4d7a65 -Author: Guus Sliepen -Date: Sun Oct 11 13:56:04 2009 +0200 - - Revert "Raise default crypto algorithms to AES256 and SHA256." - - Although it would be better to have the new defaults, only the most recent - releases of most of the platforms supported by tinc come with a version of - OpenSSL that supports SHA256. To ensure people can compile tinc and that nodes - can interact with each other, we revert the default back to Blowfish and SHA1. - - This reverts commit 4bb3793e38b7c7f24dd308801e7f6dbb02cf02d2. - -commit 2762509be179dcb21d855f3d6f90d3ee686e3910 -Author: Guus Sliepen -Date: Sun Oct 11 13:54:05 2009 +0200 - - Remove code duplication when checking ADD_EDGE/DEL_EDGE messages. - -commit 5cddf5e52aeb20e50c887356ad23aec354e04151 -Author: Guus Sliepen -Date: Sun Oct 11 13:51:10 2009 +0200 - - Don't disconnect clients in TunnelServer mode who send unauthorised ADD_SUBNETs. - - So that we are liberal in what we accept. - -commit 430c90412c521c534113b3c4e5fc883e9b7ecff0 -Author: Borg -Date: Sat Oct 3 13:06:00 2009 +0200 - - Removed last gettext function. - -commit 3282375f4d64d9402141ac4bf142629ec2e1cd53 -Author: Guus Sliepen -Date: Tue Sep 29 16:25:20 2009 +0200 - - Remove autogenerated files from EXTRA_DIST. - - Apparently they were once necessary, but autoconf now includes them - automatically. Some of them are not used anymore, and this caused make dist to - fail. - -commit 761517c21c37a808a19b487aa116c3c19439feca -Author: Guus Sliepen -Date: Tue Sep 29 15:33:58 2009 +0200 - - Update FSF address in files not covered by the merge. - -commit 07a560eab66b575f382428a956550817697e25e2 -Author: Guus Sliepen -Date: Tue Sep 29 15:19:55 2009 +0200 - - Drop localisation and checkpoint tracing in files not covered by the merge. - -commit 7ea85043ac1fb2096baea44f6b0af27ac0d0b2cf -Merge: f1fec466 9a2b0f88 -Author: Guus Sliepen -Date: Tue Sep 29 14:55:29 2009 +0200 - - Merge branch 'master' into 1.1 - - Conflicts: - NEWS - configure.in - lib/Makefile.am - lib/pidfile.c - lib/pidfile.h - lib/utils.c - po/POTFILES.in - po/nl.po - src/Makefile.am - src/bsd/device.c - src/conf.c - src/connection.c - src/cygwin/device.c - src/edge.c - src/event.c - src/graph.c - src/linux/device.c - src/meta.c - src/mingw/device.c - src/net.c - src/net_packet.c - src/net_setup.c - src/net_socket.c - src/netutl.c - src/node.c - src/process.c - src/protocol.c - src/protocol_auth.c - src/protocol_edge.c - src/protocol_key.c - src/protocol_misc.c - src/protocol_subnet.c - src/raw_socket/device.c - src/route.c - src/solaris/device.c - src/subnet.c - src/tincd.c - src/uml_socket/device.c - -commit 9a2b0f88a9cae753ebc81c939d01403178b18a35 -Author: Guus Sliepen -Date: Sat Sep 26 12:51:52 2009 +0200 - - Update the NEWS. - -commit 46e481dc945c5572eb6091a3660f6bf258ee0cfa -Author: Guus Sliepen -Date: Fri Sep 25 21:14:56 2009 +0200 - - Add more authors to the copyright headers. - - Git's log and blame tools were used to find out which files had significant - contributions from authors who sent in patches that were applied before we used - git. - -commit 4c85542894f7fca823b119b05e07179deb24229a -Author: Guus Sliepen -Date: Fri Sep 25 00:54:07 2009 +0200 - - Drop support for localisation. - - Localised messages don't make much sense for a daemon, and there is only the - Dutch translation which costs time to maintain. - -commit a227843b739d279b63adcf3736ebb03d856080c4 -Author: Guus Sliepen -Date: Fri Sep 25 00:33:04 2009 +0200 - - Remove checkpoint tracing. - - This feature is not necessary anymore since we have tools like valgrind today - that can catch stack overflow errors before they make a backtrace in gdb - impossible. - -commit 5dde6461a321ee47b06e33f8203f2acf00a31a51 -Author: Guus Sliepen -Date: Fri Sep 25 00:14:03 2009 +0200 - - K&R style braces. - - This is essentially commit f02d3ed3e135b5326003e7f69f8331ff6a3cc219 from the - 1.1 branch, making it easier to merge between master and 1.1. - -commit ab7c61b06f6c6e991225f2fcc32d02b8e1084aee -Author: Guus Sliepen -Date: Fri Sep 25 00:01:00 2009 +0200 - - Update the address of the Free Software Foundation in all copyright headers. - -commit 0e6856b1379e278aa5ed116d0911851339a6064c -Author: Guus Sliepen -Date: Thu Sep 24 23:42:30 2009 +0200 - - Remove Ivo's old email addresses. - -commit c217d214f4f071c235bc7c463a1da6124e2570a6 -Author: Guus Sliepen -Date: Thu Sep 24 23:39:16 2009 +0200 - - Remove all occurences of $Id$. - -commit c23fcf555ee4b69f03b76a0ffb731c3a475a77e7 -Author: Guus Sliepen -Date: Thu Sep 24 23:29:46 2009 +0200 - - Update copyright information. - - - Update year numbers in copyright headers. - - Add copyright information for Michael Tokarev and Florian Forster to the - copyright headers of files to which they have contributed significantly. - - Mention Michael and Florian in AUTHORS. - - Mention that tinc is GPLv3 or later if compiled with the --enable-tunemu - flag. - -commit f1fec466e232c00c668422014029dce9114d3add -Author: Guus Sliepen -Date: Wed Sep 16 23:43:19 2009 +0200 - - Add a better autoconf check for libevent. - -commit 4bdf0e80ee4cd0d40eb6522dab05df9346a5b3d0 -Author: Guus Sliepen -Date: Wed Sep 16 20:28:30 2009 +0200 - - Replace asprintf()s not covered by the merge to xasprintf(). - -commit 1cbddbd573d786f6b2bf9812dda89d1ea5b7e021 -Author: Guus Sliepen -Date: Wed Sep 16 20:17:11 2009 +0200 - - Use correct format specifiers. - -commit 2f97bdb46b1ed0a669619e0b9acf76f43dfa648b -Author: Guus Sliepen -Date: Wed Sep 16 20:16:54 2009 +0200 - - Add missing #include. - -commit 075e6828a7533e7daa790225f17aa6bb39703278 -Merge: 9b129c07 b5ccce29 -Author: Guus Sliepen -Date: Wed Sep 16 19:55:47 2009 +0200 - - Merge branch 'master' into 1.1 - - Conflicts: - have.h - lib/dropin.c - lib/fake-getaddrinfo.c - lib/pidfile.c - src/Makefile.am - src/bsd/device.c - src/conf.c - src/connection.c - src/connection.h - src/graph.c - src/mingw/device.c - src/net.c - src/net_setup.c - src/node.c - src/protocol_key.c - src/protocol_misc.c - src/tincd.c - -commit b5ccce296848aab72d574ca3de14af5fdf3efa4d -Author: Guus Sliepen -Date: Tue Sep 15 23:22:13 2009 +0200 - - Send large packets we cannot handle properly via TCP. - - During the path MTU discovery phase, we might not know the maximum MTU yet, but - we do know a safe minimum. If we encounter a packet that is larger than that - the minimum, we now send it via TCP instead to ensure it arrives. We also - allow large packets that we cannot fragment or create ICMP replies for to be - sent via TCP. - -commit d273efb177738d429e3cef7d8db8ee5cc8dcada7 -Author: Guus Sliepen -Date: Tue Sep 15 23:04:52 2009 +0200 - - Raise default RSA key length to 2048 bits. - -commit b47c17bcdeb70b63ad9346dc97ba575597cbd803 -Author: Guus Sliepen -Date: Tue Sep 15 22:59:01 2009 +0200 - - Use a mutex to allow the TAP reader to process packets faster on Windows. - - The TAP-Win32 device is not a socket, and select() under Windows only works - with sockets. Tinc used a separate thread to read from the TAP-Win32 device, - and passed this via a local socket to the main thread which could then select() - from it. We now use a global mutex, which is only unlocked when the main thread - is waiting for select(), to allow the TAP reader thread to process packets - directly. - -commit 802a50ffcd5f39bfc6424ac841de4e41154092fc -Author: Guus Sliepen -Date: Tue Sep 15 22:58:16 2009 +0200 - - Remove extra {. - -commit 4bb3793e38b7c7f24dd308801e7f6dbb02cf02d2 -Author: Guus Sliepen -Date: Tue Sep 15 12:08:05 2009 +0200 - - Raise default crypto algorithms to AES256 and SHA256. - - In light of the recent improvements of attacks on SHA1, the default hash - algorithm in tinc is now SHA256. At the same time, the default symmetric - encryption algorithm has been changed to AES256. - -commit 633c0cf1b067d118d5453bc8522fab65ffc82d2c -Author: Guus Sliepen -Date: Tue Sep 15 00:36:07 2009 +0200 - - Use access() instead of stat() for checking whether scripts exist. - -commit 6f1e0ece4e61f30612ed84ca4640635a02892cc8 -Author: Guus Sliepen -Date: Tue Sep 15 00:28:20 2009 +0200 - - Remove dropin random() function, as it is not used anymore. - -commit fa9bedd47cf8c143e801889c78f0a0979ac4d2fc -Author: Guus Sliepen -Date: Tue Sep 15 00:24:31 2009 +0200 - - Allow compiling for Windows XP and higher. - - This allows us to use getaddrinfo(), getnameinfo() and related functions, which - allow tinc to make connections over existing IPv6 networks. These functions are - not available on Windows 2000 however. By default, support is enabled, but when - compiling for Windows 2000 the configure switch --with-windows2000 should be - used. - - Since getaddrinfo() et al. are not functions but macros on Windows, we have to - use AC_CHECK_DECLS() instead of AC_CHECK_FUNCS() in configure.in. - -commit f80bf14f28925df6eaa56f3ed77adaf418ab9890 -Author: Guus Sliepen -Date: Mon Sep 14 23:28:28 2009 +0200 - - Also do not use drand48(), it is not available on Windows. - -commit 35e87b903e08fc51975a8cc97f06251d5153a424 -Author: Guus Sliepen -Date: Mon Sep 14 23:06:00 2009 +0200 - - Use only rand(), not random(). - - We used both rand() and random() in our code. Since it returns an int, we have - to use %x in our format strings instead of %lx. This fixes a crash under - Windows when cross-compiling tinc with a recent version of MinGW. - -commit 75773efe2689d347a2f219c5f27e4a82eef1236b -Author: Guus Sliepen -Date: Sun Sep 13 14:08:59 2009 +0200 - - Apparently it's impolite to ask GCC to subtract two pointers. - - If two pointers do not belong to the same array, pointer subtraction gives - nonsensical results, depending on the level of optimisation and the - architecture one is compiling for. It is apparently not just subtracting the - pointer values and dividing by the size of the object, but uses some kind of - higher magic not intended for mere mortals. GCC will not warn about this at - all. Casting to void * is also a no-no, because then GCC does warn that strict - aliasing rules are being broken. The only safe way to query the ordering of two - pointers is to use the (in)equality operators. - - The unsafe implementation of connection_compare() has probably caused the "old - connection_t for ... still lingering" messages. Our implementation of AVL trees - is augmented with a doubly linked list, which is normally what is traversed. - Only when deleting an old connection the tree itself is traversed. - -commit 23e151aeed6b3ffe0fab10f51ffdb134deb7a852 -Author: Guus Sliepen -Date: Sun Sep 13 14:07:40 2009 +0200 - - Remove superfluous call to avl_delete(). - -commit 9915f2abbedb7f1aa2b9e2f81d52ddcfca60e82d -Author: Guus Sliepen -Date: Sat Sep 12 14:19:36 2009 +0200 - - Handle unicast packets larger than PMTU in switch mode. - - If PMTUDiscovery is enabled, and we see a unicast packet that is larger than - the path MTU in switch mode, treat it just like we would do in router mode. - -commit 7242868b64f9d6f62b6c5bbf1526eb632ed9a4d6 -Author: Guus Sliepen -Date: Sat Sep 12 13:40:32 2009 +0200 - - Allow PMTUDiscovery in switch and hub modes again. - - PMTUDiscovery was disabled in commit d5b56bbba56480b5565ffb38496175a7c1df60ac - because tinc did not handle packets larger than the path MTU in switch and hub - modes. We now allow it again in preparation of proper support, but default to - off. - -commit 052ff8b2c598358d1c5febaa9f9f5fc5d384cfd3 -Author: Guus Sliepen -Date: Sat Sep 12 13:34:11 2009 +0200 - - Put Subnet weight in a separate environment variable. - - Commit 5674bba5c54c1aee3a4ac5b3aba6b3ebded91bbc introduced weighted Subnets, - but the weight was included in the SUBNET variable passed to subnet-up/down - scripts. This makes it harder to use in those scripts. The weight is now - stripped from the SUBNET variable and put in the WEIGHT variabel. - -commit a60a0a1f1357508063ee565d672c39898a787e33 -Author: Guus Sliepen -Date: Thu Sep 10 19:51:08 2009 +0200 - - Don't stat() on iPhone/iPod. - - Grzegorz Dymarek noted that tinc segfaults at the stat() call in - execute_script() on the iPhone. We can omit the stat() call for the moment, - the subsequent call to system() will fail with just a warning. - -commit 4a5d42178cc0954efba8b24058da9c70cc77c35a -Author: Guus Sliepen -Date: Thu Sep 10 19:32:54 2009 +0200 - - Add support for iPhones and recent iPods. - - This is a slightly modified patch from Grzegorz Dymarek that allows tinc to use - the tunemu device, which allows tinc to be compiled for iPhones and recent - iPods. To enable support for tunemu, the --enable-tunemu option has to be used - when running the configure script. - -commit ff946d0423fe547ea42bb11acfb3035c3b8aee4e -Author: Guus Sliepen -Date: Wed Sep 9 14:51:36 2009 +0200 - - Another safe bitfield conversion. - -commit dd6226062c2356d2a3679e2c7972be71233cb9de -Author: Guus Sliepen -Date: Wed Sep 9 13:23:16 2009 +0200 - - Add the GPL license to the repository. - - Tinc is licensed under the GPL version 2 or later. To ensure autoconf does not - install the wrong license if COPYING is missing, we have to put the right one - in place. - -commit 81afa26e4ad53bea00da18a7666f63d33cf3f588 -Author: Guus Sliepen -Date: Wed Sep 9 12:04:08 2009 +0200 - - Convert bitfields to integers in a safe way. - - This is commit eb391c52eed46f3f03b404553df417851fc0cb90 redone, but without the - non-standard anonymous union. - -commit 9b394bc887695da6db74f4b9796b4823e553f8cc -Author: Guus Sliepen -Date: Tue Sep 8 21:45:24 2009 +0200 - - Ensure tinc compiles with gcc -std=c99. - - We use a lot of C99 features already, but also some extensions which are not in - the standard. - -commit f52ea0a7eb0383cc2a5f41db1bf24c39424fdb04 -Author: Guus Sliepen -Date: Tue Sep 8 18:21:52 2009 +0200 - - UNIX signal numbers start at 1. - -commit 73d77dd416b87b7c4e9b6aa450f64846235cd2b4 -Author: Guus Sliepen -Date: Tue Sep 8 18:18:36 2009 +0200 - - Replace asprintf() by xasprintf(). - -commit 3e55dc77f4ba19fd9e79f3d5ce9d28bb6b05019e -Author: Guus Sliepen -Date: Tue Sep 8 18:18:16 2009 +0200 - - Check the return value of fscanf() when reading a PID file. - -commit 5e0efd53e797a2b5468b91b41b6122f3b942efb2 -Author: Guus Sliepen -Date: Tue Sep 8 18:16:58 2009 +0200 - - Add xasprintf() and xvasprintf(). - - These functions wrap asprintf() and vasprintf(), and check the return value. If - the function failed, tinc will exit with an error message, similar to xmalloc() - and friends. - -commit 63fe89e9eb8ef9077bfe3cd416c86820715eb33b -Author: Michael Tokarev -Date: Sat Sep 5 17:24:41 2009 +0400 - - Remove extra semicolon in my definition of setpriority() - -commit 5a7fc58012da10b96073804994777255463d1b8d -Author: Guus Sliepen -Date: Tue Sep 8 16:35:28 2009 +0200 - - Always remove a node from the UDP tree before freeing it. - - Valgrind caught tinc reading free'd memory during a purge(). This was caused by - first removing it from the main node tree, which will already call free_node(), - and then removing it from the UDP tree. This might cause spurious segmentation - faults. - -commit de029ce46056e02908b5390da9b71a6a59133f26 -Author: Guus Sliepen -Date: Thu Jun 11 19:39:25 2009 +0200 - - Change level of some debug messages, zero pointer after freeing hostname. - -commit 66be914d35cb7e7ea4dd4aed68ae9e41addd9f70 -Author: Guus Sliepen -Date: Thu Jun 11 19:26:34 2009 +0200 - - Do not log errors when recvfrom() returns EAGAIN or EINTR. - - Although we select() before we call recvfrom(), it sometimes happens that - select() tells us we can read but a subsequent read fails anyway. This is - harmless. - -commit df4add94a4a6461758b218a9ad257efc735062fe -Author: Guus Sliepen -Date: Thu Jun 11 19:07:54 2009 +0200 - - Remove pending MTU probe events when a node's reachability status changes. - -commit 36f8e4da8b1708474505f5a1fa8cf1ba848921de -Author: Guus Sliepen -Date: Thu Jun 11 18:36:08 2009 +0200 - - Don't try to send MTU probes to unreachable nodes. - - If there is an outstanding MTU probe event for a node which is not reachable - anymore, a UDP packet would be sent to that node, which caused a key request to - be sent to that node, which triggered a NULL pointer dereference. Probes and - other UDP packets to unreachable nodes are now dropped. - -commit 9b129c07e273ae113f3c67a9feeee82e8146f3a1 -Author: Guus Sliepen -Date: Sat Jun 6 20:14:51 2009 +0200 - - Fix pointer arithmetic when creating and verifying message authentication codes. - -commit 4124b9682f8f890acb25d0c92f2583eef670274a -Author: Guus Sliepen -Date: Sat Jun 6 19:04:04 2009 +0200 - - Handle truncated message authentication codes. - -commit 5a132550deb58473285e5f91705d286aef47be71 -Merge: 08aabbf9 591c38eb -Author: Guus Sliepen -Date: Fri Jun 5 23:03:28 2009 +0200 - - Merge branch 'master' into 1.1 - - Conflicts: - doc/tincd.8.in - lib/pidfile.c - src/graph.c - src/net.c - src/net.h - src/net_packet.c - src/net_setup.c - src/net_socket.c - src/netutl.c - src/node.c - src/node.h - src/protocol_auth.c - src/protocol_key.c - src/tincd.c - -commit 261d1eac1c5bbe6c87aa707566f290e611169432 -Author: Guus Sliepen -Date: Fri Jun 5 16:14:31 2009 +0200 - - Properly set HMAC length for incoming packets. - -commit 591c38eb38dbf0851bdebdd50b08d1bcbf6d7b0f -Author: Michael Tokarev -Date: Fri Jun 5 13:33:58 2009 +0400 - - try outgoing connections before chroot/drop_privs - - When chrooted, we either need to force-initialize resolver - and/or nsswitch somehow (no clean way) or resolve all the - names we want before entering chroot jail. The latter - looks cleaner, easier and it is actually safe because - we still don't talk with the remote nodes there, only - initiating outgoing connections. - -commit a42a8dde45fe95aa3fd3f7f15a74c5166efe3633 -Author: Michael Tokarev -Date: Fri Jun 5 11:58:17 2009 +0400 - - cleanup setpriority thing to make it readable - -commit a5fb0d8c6c384b9ea1074fb469c0a3dd5b874e98 -Author: Guus Sliepen -Date: Thu May 28 23:18:22 2009 +0200 - - Add some const where appropriate. - -commit 41c10c5a966000531099c79d6006429253ff8fd6 -Author: Guus Sliepen -Date: Thu May 28 22:51:30 2009 +0200 - - Add ProcessPriority option. - - This option can be set to low, normal or high. On UNIX flavours, this changes - the nice value of the process by +10, 0 and -10 respectively. On Windows, it - sets the priority to BELOW_NORMAL_PRIORITY_CLASS, NORMAL_PRIORITY_CLASS and - HIGH_PRIORITY_CLASS respectively. - - A high priority might help to reduce latency and packet loss on the VPN. - -commit 41a05f59ba2c3eb5caab555f096ed1b9fbe69ee3 -Author: Florian Forster -Date: Wed May 27 14:20:24 2009 +0200 - - src/net_socket.c: Bind outgoing TCP sockets to `BindToAddress'. - - If a host has multiple addresses on an interface, the source address of the TCP - connection(s) was picked by the operating system while the UDP packets used a - bound socket, i. e. the source address was the address specified by the user. - This caused problems because the receiving code requires the TCP connection and - the UDP connection to originate from the same IP address. - - This patch adds support for the `BindToInterface' and `BindToAddress' options - to the setup of outgoing TCP connections. - - Tested with Debian Etch on x86 and Debian Lenny on x86_64. - - Signed-off-by: Florian Forster - -commit 6b415a1a7f5bad2fff7b133ef2a2febccb96d6e5 -Author: Florian Forster -Date: Wed May 27 09:27:44 2009 +0200 - - src/linux/device.c: Fix segfault when running without `--net'. - - If running without `--net', the (global) variable `netname' is NULL. This - creates a segmentation fault because this NULL-pointer is passed to strdup: - - Program terminated with signal 11, Segmentation fault. - #0 0xb7d30463 in strlen () from /lib/tls/i686/cmov/libc.so.6 - (gdb) bt - #0 0xb7d30463 in strlen () from /lib/tls/i686/cmov/libc.so.6 - #1 0xb7d30175 in strdup () from /lib/tls/i686/cmov/libc.so.6 - #2 0x0805bf47 in xstrdup (s=0x0) at xmalloc.c:118 <--- - #3 0x0805be33 in setup_device () at device.c:66 - #4 0x0805072e in setup_myself () at net_setup.c:432 - #5 0x08050db2 in setup_network () at net_setup.c:536 - #6 0x0805b27f in main (argc=Cannot access memory at address 0x0) at tincd.c:580 - - This patch fixes this by checking `netname' in `setup_device'. An alternative - would be to check for NULL-pointers in `xstrdup' and return NULL in this case. - - Signed-off-by: Florian Forster - -commit a8a65cee083a27afe42cab360596e1453e7141b9 -Author: Michael Tokarev -Date: Sun May 24 17:23:24 2009 +0400 - - tunnelserver: log which ADD_SUBNET was refused - - Add some logging about refused ADD_SUBNET - (it causes subsequent client disconnect so it's - important to know which subnet was at fault). - - Maybe we should just ignore it completely. - -commit 4e9e3ca89dba68cbacaaa15ddfb298b181a969da -Author: Guus Sliepen -Date: Mon May 25 15:04:33 2009 +0200 - - Do not forward broadcast packets when TunnelServer is enabled. - - First of all, the idea behind the TunnelServer option is to hide all other - nodes from each other, so we shouldn't forward broadcast packets from them - anyway. The other reason is that since edges from other nodes are ignored, the - calculated minimum spanning tree might not be correct, which can result in - routing loops. - -commit 7fc69bc73b15349dafc193a50464caeb2f978369 -Author: Guus Sliepen -Date: Mon May 25 12:19:37 2009 +0200 - - Use packet size before decompression to calculate path MTU. - - Since compression can either grow or shrink a packet, the size of an MTU probe - after decompression might not reflect the real path MTU. Now we use the size - before decompression, which is independent of the compression algorithm, and - substract a safety margin such that the calculated path MTU will be safe even - for packets which grow as much as possible after compression. - -commit 1b3add6c29f8eb424a62837e89fe7d384fc94a48 -Author: Guus Sliepen -Date: Mon May 25 12:19:08 2009 +0200 - - Add declaration for sockaddrcmp_noport(). - -commit ca5b67111e4d797d15623c2163f67fe489dc3bf2 -Author: Michael Tokarev -Date: Sun May 24 22:32:24 2009 +0400 - - Fix ans_key exchange in recent changes - - send_ans_key() was using the wrong in vs. outkeylength to - terminate the key being sent, so it was always empty. - -commit 7034338bc36d9ea96d152091b9d58c2afc3f0c20 -Author: Guus Sliepen -Date: Sun May 24 19:35:51 2009 +0200 - - Use xrealloc instead of if(ptr) ptr = xmalloc(). - -commit e012e752f4f1a2b06dfab4640bbbea8f084999ff -Author: Guus Sliepen -Date: Sun May 24 19:31:31 2009 +0200 - - Fix initialisation of packet decryption context broken by commit 3308d13e7e3bf20cfeaf6f2ab17228a9820cea66. - - Instead of a single, global decryption context, each node has its own context. - However, in send_ans_key(), the global context was initialised. This commit - fixes that and removes the global context completely. - - Also only set status.validkey after all checks have been evaluated. - -commit 0246939ce18e1af9660b782b6814be182a7af9da -Author: Michael Tokarev -Date: Fri May 22 01:10:16 2009 +0400 - - don't log every strange packet coming to the UDP port - - it's a sure way to fill up syslog. Only log those if - debug level is up to PROTOCOL - -commit 576899ef0dec3aaede9b8ac101d189798587a646 -Author: Guus Sliepen -Date: Sun May 24 17:13:00 2009 +0200 - - Fix link to Mattias Nissler's tun/tap driver for MacOS/X. - - Thanks to Martin Christof Kindsmüller for spotting. - -commit 2c67eafc6e6c5e210636c0d2bad15827bf2d7cf0 -Author: Guus Sliepen -Date: Sun May 24 15:58:47 2009 +0200 - - If PMTUDiscovery is not set, do not forward packets via TCP unnecessarily. - -commit 7e4d57adf54ce369e4111bde0ccd3ea4b9e853ee -Author: Michael Tokarev -Date: Fri May 22 01:01:35 2009 +0400 - - ignore indirect edge registrations in tunnelserver mode - - In tunnelserver mode we're not interested to hear about - our client edges, just like in case of subnets. Just - ignore all requests which are not about our node or the - client node. - - The fix is very similar to what was done for subnets. - - Note that we don't need to add the "unknown" nodes to - the list in tunnelserver mode too, so move allocation - of new nodes down the line. - -commit 3759aa5f7745709c43f81faa36510ff650b4bf99 -Author: Michael Tokarev -Date: Wed May 20 18:40:04 2009 +0400 - - TunnelServer: Don't disconnect client on DEL_SUBNET too - - Similar changes as was in 2327d3f6eb5982bcc922ff1ab1ec436ba6aeffdc - but for del_subnet_h(). - - Before, we vere returning false (and causing disconnect of the - client) in case of tunnelserver and the client sending DEL_SUBNET - for non-his subnet or for subnet which owner isn't in our connection - list. - - After the mentioned change to add_subnet_h() that routine does not - add such indirect owners to the connection list anymore, so that - was ok (owner == NULL and we return true). - - But if we too has a connection with the node about which the client - is sending DEL_SUBNET notification, say, because that client lost - connection with that other node, we'll disconnect this client from - us too, returning false for indirect DEL_SUBNET. - - Fix that by allowing and ignoring indirect DEL_SUBNET in tunnelserver - mode. - - Also rearranged the function a bit, to match add_subnet_h() (in - particular, syntax-check everything first, see if we've seen this - request before). - - And also fix some comments. - -commit 218adee785df7c79ac18395d056a2eb6d63c407f -Author: Michael Tokarev -Date: Mon May 18 17:34:30 2009 +0400 - - format 'not supported on this platform' error message - - Format it in a similar way in all places, to make translation happier. - No functional changes. - -commit 54cb6b1aecb06a1ca44a7a60c74dd0d65b0043dd -Author: Michael Tokarev -Date: Mon May 18 17:00:00 2009 +0400 - - change error messages in droppriv code to match the rest - - Change formatting of error messages about failed syscalls - to be the same as in other places in tincd. - - Also suggest a change in "$foo not supported on this platform" - message as it's now used more than once. - -commit d4f9863635d06665cfbd3c46dc482344de240e97 -Author: Michael Tokarev -Date: Mon May 18 16:53:08 2009 +0400 - - bugfix: chdir(/) after chroot - - Fix the famous chdir(".") vs chdir("/") after chroot(something). - -commit 6be5d4f5b67764115b37528d2fe01bd245b3cd3e -Author: Michael Tokarev -Date: Mon May 18 16:49:39 2009 +0400 - - bugfix: move mlock to after detach() so it works for child, not parent - - mlock()/mlockall() are not persistent across fork(), and it's - done in parent process before daemon() which does fork(). So - basically, current --mlock does nothing useful. - - Move mlock() to after detach() so it works for child process - instead of parent. - - Also, check if the platform supports mlock right when processing - options (since else we'll have to die after startup, not at - startup, the error message will be in log only). - -commit cdf7f13c31310da0c40819fd812e19519bf4318c -Author: Michael Tokarev -Date: Mon May 18 16:28:55 2009 +0400 - - bugfix: initialize pid (as read from pidfile) to zero - - If we didn't read any number from a pid file, we'll return - an unitialized variable to the caller, and it will treat - that garbage as a pid of a process (possible to kill). - - Fix that. - -commit ec316aa32e8567395a88c4583007f01ffae008ce -Author: Michael Tokarev -Date: Mon May 18 16:25:41 2009 +0400 - - Implement privilege dropping - - Add two options, -R/--chroot and -U/--user=user, to chroot to the - config directory (where tinc.conf is located) and to perform - setuid to the user specified, after all the initialization is done. - - What's left is handling of pid file since we can't remove it anymore. - -commit 6698f7c390a5ae2f262e30560d9df59f9d5c418d -Author: Michael Tokarev -Date: Mon May 18 16:25:10 2009 +0400 - - Rename setup_network_connections() and split out try_outgoing_connections() - - In preparation of chroot/setuid operations, split out call to - try_outgoing_connections() from setup_network_connections() - (which was the last call in setup_network_connections()). - This is because dropping privileges should be done in-between - setup_network_connections() and try_outgoing_connections(). - - This patch renames setup_network_connections() to setup_network() - and moves call to try_outgoing_connections() into main routine. - - No functional changes. - -commit 3308d13e7e3bf20cfeaf6f2ab17228a9820cea66 -Author: Guus Sliepen -Date: Fri Apr 3 01:05:23 2009 +0200 - - Handle UDP packets from different and ports than advertised. - - Previously, tinc used a fixed address and port for each node for UDP packet - exchange. The port was the one advertised by that node as its listening port. - However, due to NAT the port might be different. Now, tinc sends a different - session key to each node. This way, the sending node can be determined from - incoming packets by checking the MAC against all session keys. If a match is - found, the address and port for that node are updated. - -commit 08aabbf9317806bc50a9a6693ca866c8936ce26b -Merge: 551cd194 43fa7283 -Author: Guus Sliepen -Date: Mon Mar 9 19:02:24 2009 +0100 - - Merge branch 'master' into 1.1 - - Conflicts: - NEWS - README - doc/tinc.conf.5.in - doc/tinc.texi - po/nl.po - src/conf.c - src/connection.c - src/event.c - src/graph.c - src/net.c - src/net_packet.c - src/net_socket.c - src/node.c - src/node.h - src/openssl/rsagen.h - src/protocol_auth.c - src/protocol_key.c - src/protocol_misc.c - src/subnet.c - src/subnet.h - src/tincd.c - -commit 43fa7283ac01f2ecc95381b519ef6b3342546f35 -Author: Guus Sliepen -Date: Mon Mar 9 14:04:31 2009 +0100 - - Use a simple Random Early Drop algorithm in send_tcppacket(). - -commit d5b56bbba56480b5565ffb38496175a7c1df60ac -Author: Guus Sliepen -Date: Mon Mar 9 13:48:54 2009 +0100 - - Disable PMTUDiscovery in switch and hub modes. - - In switch and hub modes, tinc does not generate ICMP packets in response to - packets that are larger than the path MTU. However, if PMTUDiscovery is - enabled, the IP_MTU_DISCOVER and IPV6_MTU_DISCOVER option is set on the UDP - sockets, which causes all UDP packets to be sent with the DF bit set, causing - large packets to be dropped, even if they would otherwise be routed fine. - -commit 78fc59e994c764d072bf0045177f690a378d1308 -Author: Guus Sliepen -Date: Thu Mar 5 14:12:36 2009 +0100 - - Update THANKS and copyright information. - -commit 5674bba5c54c1aee3a4ac5b3aba6b3ebded91bbc -Author: Guus Sliepen -Date: Thu Mar 5 13:34:13 2009 +0100 - - Allow weight to be assigned to Subnets. - - Tinc allows multiple nodes to own the same Subnet, but did not have a sensible - way to decide which one to send packets to. Tinc also did not check the - reachability of nodes when deciding where to route packets to, so it would not - automatically fail over to a reachable node. - - Tinc now assigns a weight to each Subnet. The default weight is 10, with lower - weights having higher priority. The Subnets are now internally sorted in the - same way as the kernel's routing table, and the Subnets are search linearly, - skipping those of unreachable nodes. A small cache of recently used addresses - is used to speed up the lookup functions. - -commit 76a1bcaffcf1f1abf81fdda379b703a004640cb4 -Author: Michael Tokarev -Date: Sat Feb 28 16:37:51 2009 +0300 - - Enable PMTUDiscovery only if BOTH sides wants it. - - Don't enable PMTUDiscovery if at least one side does not support it. - Before it was enabled if at least one side supported it, now both are required. - -commit 1c1a67fd93530b9d16538ab2897c3911d3b16574 -Author: Guus Sliepen -Date: Tue Feb 17 14:43:05 2009 +0100 - - Handle neighbor solicitation requests without link layer addresses. - - Apparently FreeBSD likes to send out neighbor solicitation requests, even on a - tun interface where this is completely pointless. These requests do not have an - option header containing a link layer address, so the proxy-neighborsol code - was treating these requests as invalid. We now handle such requests, and send - back equally pointless replies, also without a link layer address. This seems - to satisfy FreeBSD. - -commit 2327d3f6eb5982bcc922ff1ab1ec436ba6aeffdc -Author: Michael Tokarev -Date: Mon Feb 9 23:51:10 2009 +0100 - - Allow tunnelserver to work with clients that have other peers. - - In TunnelServer mode, tinc server disconnects any client if it announces - indirect subnets -- subnets that are not theirs (e.g. subnets for nodes - the CLIENT has connections now, even if those nodes are known to the server - too). Fix that by ignoring such (indirect) announces instead. - - While we're at it, move check for such indirect subnet registration to - before allocating new node structure, as in TunnelServer mode we don't - really need to know that other node. - -commit 23730375f27c32e0fe1a59c7a761dd85296a7a4a -Author: Guus Sliepen -Date: Tue Feb 3 14:54:45 2009 +0100 - - Disable old RSA keys when generating new ones. - - When generating an RSA keypair, the new public and private keys are appended to - files. However, when OpenSSL reads keys it only reads the first in a file, not - the last. Instead of printing an easily ignored warning, tinc now disables old - keys when appending new ones. - -commit 0d0dfd0852e9b2c9a7660880966a3c84790d5ea2 -Author: Guus Sliepen -Date: Tue Jan 20 14:21:50 2009 +0100 - - Validate Name before using it in a filename when generating a keypair. - -commit 0966cca8ab6dcde2747c717f21d73fd332e04242 -Author: Guus Sliepen -Date: Tue Jan 20 14:20:44 2009 +0100 - - Allow reading config files with CRLF endings on Unix systems. - -commit d1910ac198232573c1b18d8238a27bc29bc73f8a -Author: Guus Sliepen -Date: Tue Jan 20 13:19:31 2009 +0100 - - Remove unused definitions from net.h. - -commit 503c32eb0ef9d6329e931559082f4ddf6d487dc6 -Author: Guus Sliepen -Date: Tue Jan 20 13:12:41 2009 +0100 - - Use a global list to track outgoing connections. - - Previously an outgoing_t was maintained for each outgoing connection, - but the pointer to it was either stored in a connection_t or in an event_t. - This made it very hard to keep track of and to clean up. - - Now a list is created when tinc starts and reads all the ConnectTo variables, - and which is recreated when tinc receives a HUP signal. - -commit a7e793c94ec414eb71ec2aa3debc9e2e5ed5cfef -Author: Guus Sliepen -Date: Mon Jan 19 23:17:28 2009 +0100 - - Add missing cleanup functions in close_network_connections(). - -commit 116065afe352221ac6c2c8e34c109252004d6a59 -Author: Guus Sliepen -Date: Mon Jan 19 22:50:05 2009 +0100 - - Change flush_events() to expire_events(). - - The former function made a totally bogus shallow copy of the event_tree, called - the handler of each event and then deleted the whole tree. This should've - caused tinc to crash when an ALARM signal was sent more than once, but for some - reason it didn't. It also behaved incorrectly when a handler added a new event. - - The new function just moves the expiration time of all events to the past. - -commit a39a9506cd041a7092a98498b362eaacfd2f33c3 -Author: Guus Sliepen -Date: Fri Jan 9 12:36:06 2009 +0100 - - Move free()s at the end om main() to the proper destructor functions. - -commit 67df7fb7e1c9eefe4bbc920fdc68b595ef28abd9 -Author: Guus Sliepen -Date: Sat Jan 3 22:33:55 2009 +0100 - - Only send packets via UDP if UDP communication is possible. - - When no session key is known for a node, or when it is doing PMTU discovery but - no MTU probes have returned yet, packets are sent via TCP. Some logic is added - to make sure intermediate nodes continue forwarding via TCP. The per-node - packet queue is now no longer necessary and has been removed. - -commit b069da90d67b49dce041f513a3855b8da3d82f80 -Author: Guus Sliepen -Date: Sat Jan 3 22:06:10 2009 +0100 - - Consistently allocate device and iface variables on the heap. - - This fixes a segfault when no Device has been specified and tinc exits, and it - would try to free() a static string. Thanks to Borg for spottin. - -commit f81cea3bdc8683b27188cd8f24a2de906a29eb81 -Author: Guus Sliepen -Date: Sat Dec 27 11:09:43 2008 +0100 - - Update documentation for git. - -commit c81f90b91a054eeafcc3c8c45abc52045e4a8146 -Author: Guus Sliepen -Date: Fri Dec 26 13:47:34 2008 +0000 - - Releasing 1.0.9. - -commit a4d99ebf5042dedb609359cbbfc3fa4630b5fc70 -Author: Guus Sliepen -Date: Fri Dec 26 12:46:45 2008 +0000 - - Add missing parentheses in check for IPv4 multicast addresses. - -commit 099bc56f53e7d3cb7b799d26ff9535673ff03e1c -Author: Guus Sliepen -Date: Tue Dec 23 23:14:37 2008 +0000 - - Apply patch from Max Rijevski fixing a memory leak when closing connections. - It also cleans up more when stopping tinc, helping tools like valgrind. - -commit de032054dee67bcc406b4a15fb9e957a766d016a -Author: Guus Sliepen -Date: Tue Dec 23 22:31:38 2008 +0000 - - Handle broadcast and multicast packets in router mode. - Multicast packets are treated as broadcast packets. - Based on a patch from Max Rijevski. - -commit a5f899a9794f215e8174455ead04862a2c14a5b1 -Author: Guus Sliepen -Date: Mon Dec 22 21:49:23 2008 +0000 - - Update the manpage as well, and some whitespace to make its source more legible. - -commit e8f08ced76bf1b9a94dd0dc874ad22761ad8900b -Author: Guus Sliepen -Date: Mon Dec 22 21:29:21 2008 +0000 - - Update documentation. - - TCPOnly is not experimental. - - Do not mention old Linux kernels and Ethertap anymore. - - Document the DeviceType, PMTU and PMTUDiscovery options. - -commit 0e4d419aae8a82f2ae4552f755894a9bc70c83d2 -Author: Guus Sliepen -Date: Mon Dec 22 20:35:45 2008 +0000 - - Enable PMTU discovery by default. - -commit e9576632dc4b780b867044269d06cc50f76d8c05 -Author: Guus Sliepen -Date: Mon Dec 22 20:27:52 2008 +0000 - - Update copyright information. - -commit f50dc972cde2644588eabf35a2422fe0e372a024 -Author: Guus Sliepen -Date: Mon Dec 22 19:43:49 2008 +0000 - - Update Dutch translation. - -commit 26b490e86bc305b150200c0b08cd8e9c3bd605fb -Author: Guus Sliepen -Date: Mon Dec 22 19:40:40 2008 +0000 - - Make sure IPv6 sockets are IPv6 only. - This will get rid of the "Can't bind to 0.0.0.0 port 655/tcp: Address already - in use" message on Linux. - -commit c6830ba821e6387be961ca68b32992382a74a0e9 -Author: Guus Sliepen -Date: Mon Dec 22 19:33:37 2008 +0000 - - Use TUNIFHEAD by default on FreeBSD to make sure IPv6 works. - -commit a269ec4193900feee01ac83f0e18a6e2b98e751f -Author: Guus Sliepen -Date: Sun Dec 21 16:19:31 2008 +0000 - - Treat virtual network device as tap if Mode = switch or hub. - On OpenBSD, the link0 flag should still be set in tinc-up or by other means. - -commit 551cd19406a560d0d206bff5b4e9da064ec222b6 -Author: Guus Sliepen -Date: Sun Dec 14 12:47:26 2008 +0000 - - Move RSA key generation into the wrappers. - -commit 911c05f873ad967c40d04aa7347b1067fe62c055 -Author: Guus Sliepen -Date: Thu Dec 11 20:49:14 2008 +0000 - - Make sure IPv6 sockets are IPv6 only. - -commit 6e80da3370249caa1082c23c3ef55f338d1e9e74 -Author: Guus Sliepen -Date: Thu Dec 11 18:07:26 2008 +0000 - - Use Dijkstra's algorithm. Based on patches from Max Rijevskiy. - -commit 26a228e3025c3970fd461af777013e3807b0fc58 -Author: Guus Sliepen -Date: Thu Dec 11 18:05:59 2008 +0000 - - Remove wrong checks. - -commit 636200d1a2024982fe5b3062153daa72a8253015 -Author: Guus Sliepen -Date: Thu Dec 11 15:56:18 2008 +0000 - - Remove unnecessary parentheses from sizeof, apply sizeof to variables instead of types whereever possible. - -commit a9bdfb424e7a469d15156aa44bbe2fd0b8e28531 -Author: Guus Sliepen -Date: Thu Dec 11 15:42:46 2008 +0000 - - Fix compiler warnings. - -commit 76165488f8201a59e649b4eec02ee31398b3fb92 -Author: Guus Sliepen -Date: Thu Dec 11 15:21:40 2008 +0000 - - Backport fixes from trunk since revision 1555. - -commit 046158a216e78a0412186ec8463157f6bce45d5d -Author: Guus Sliepen -Date: Thu Dec 11 14:44:44 2008 +0000 - - Use the crypto wrappers again instead of calling OpenSSL directly. - This theoretically allows other cryptographic libraries to be used, - and it improves the readability of the code. - -commit 8c69f42d7d9b4d9d5f6b6656cfc1bf1e1abee854 -Author: Guus Sliepen -Date: Thu Dec 11 14:43:13 2008 +0000 - - Move AC_GNU_SOURCE up to make autoconf happy. - Also bump libgcrypt dependency to 1.4.0, because that version supports the OFB cipher mode. - -commit 8e8fe805c81d3edc974c12c468f793ea0c1e5ee7 -Author: Guus Sliepen -Date: Thu Dec 11 14:03:52 2008 +0000 - - Only show meta connection related debug messages when debug level >= 4 - -commit 40bebbb19fd69fa094e2f6c3c1474adc0105b048 -Author: Guus Sliepen -Date: Thu Dec 11 13:59:46 2008 +0000 - - Look in the configured sbin directory for the tincd binary. - -commit 38c2d6c1dae3f09c68baa37fd24caa2e0ec6d8ad -Author: Guus Sliepen -Date: Fri Dec 5 14:17:39 2008 +0000 - - Correct debug message. - -commit a36259435c17f76cf12476234a56f40fcd8faf41 -Author: Guus Sliepen -Date: Tue Nov 18 15:11:27 2008 +0000 - - Prevent freeing a NULL pointer when a hostname is unresolvable. - -commit 4a1740ede7c1992f7f3da5e197db9975c0344ac3 -Author: Guus Sliepen -Date: Sat Oct 25 19:54:00 2008 +0000 - - Do not try to send REQ_KEY or ANS_KEY requests to unreachable nodes. - -commit cb52aa06833a69e57b5e26337e51a4d375b6d8fb -Author: Guus Sliepen -Date: Sat Oct 25 18:10:08 2008 +0000 - - Fix reading configuration files that do not end with a newline. - -commit b2cee41b187d79c095914d1097b8ff34a0609ec3 -Author: Guus Sliepen -Date: Fri Dec 14 21:17:08 2007 +0000 - - Make sure the prefixlength of subnets is sane. - Thanks to Sven-Haegar Koch for spotting the bug and providing a fix. - -commit fe2f1fceb546ca4326435cac26bcf3f513e82b43 -Author: Scott Lamb -Date: Thu Nov 8 19:18:44 2007 +0000 - - Use a control socket directory to restrict access - - This provides reasonable security even on Solaris. The sysadmin is - responsible for securing the control socket's ancestors from the - grandparent on. - - We could add a cryptographic handshake later if desired. - -commit b1f8c65a2cfa307d9b8ed8cc3c8d4819f605e4f6 -Author: Scott Lamb -Date: Wed Nov 7 06:45:28 2007 +0000 - - Coding style corrections - -commit d82fcc88f355e3c8144478a860dfae0b299004a9 -Author: Scott Lamb -Date: Wed Nov 7 02:51:24 2007 +0000 - - Reload configuration through control socket - - I also kept the SIGHUP handler, which many people will expect to see. - The control socket is better, though - it will tell you if there is a - problem. - -commit f0a57eab4cfd64d4f8261b1885a2072177f9e76b -Author: Scott Lamb -Date: Wed Nov 7 02:50:58 2007 +0000 - - Retry connections through control socket - -commit a62a6825a8a69e279ee0688a4cd9e51fbc52054b -Author: Scott Lamb -Date: Wed Nov 7 02:50:27 2007 +0000 - - Alter debugging levels through control socket - -commit 1065879c8c6e8cdf8d3755024241f31eaabd4138 -Author: Scott Lamb -Date: Wed Nov 7 02:49:57 2007 +0000 - - Purge through the control socket - -commit 6eaefb4dbce240334e35f67d9f3db5d4f44e49c9 -Author: Scott Lamb -Date: Wed Nov 7 02:49:25 2007 +0000 - - Dump through control socket - - Note this removes SIGUSR1, SIGUSR2, and the graph dumping config option. - It seems cleaner to do everything through the control socket. - -commit 50ad3f2a895c38f8d546f87490ca96ab7d9e011e -Author: Scott Lamb -Date: Wed Nov 7 02:48:33 2007 +0000 - - Fancier protocol for control socket - - * pass error status back - * pass message boundaries - -commit b0b52991849073de059a188800d1b2f03663a188 -Author: Scott Lamb -Date: Wed Nov 7 02:48:15 2007 +0000 - - Fix reload crash - - sighup_handler was expecting the connection_tree to stay the same across - terminate_connection(), which hasn't been true since r1539. - -commit da81da064a093f94e460fc1c359b5cfab26d6b5b -Author: Scott Lamb -Date: Wed Nov 7 02:48:00 2007 +0000 - - Update documentation to match tincctl changes - - (Most of this was done in r1559, but it looks like tincctl.8.in got missed.) - -commit 40731d030fef793c6b6405efd9b3e64c26c00045 -Author: Scott Lamb -Date: Wed Nov 7 02:47:05 2007 +0000 - - Temporarily revert to old crypto code - - (The new code is still segfaulting for me, and I'd like to proceed with other - work.) - - This largely rolls back to the revision 1545 state of the existing code - (new crypto layer is still there with no callers), though I reintroduced - the segfault fix of revision 1562. - -commit 269892f70bf357de6ad66ca89daa34b225ee9e37 -Author: Guus Sliepen -Date: Sat Oct 20 11:21:44 2007 +0000 - - Prevent double free() of a used challenge nonce. - -commit b0709d2649ebd7ad01d6e24851dcdfc2707d09c5 -Author: Guus Sliepen -Date: Fri Oct 19 19:07:30 2007 +0000 - - Fix meta data segfault when receiving a partial command. - -commit 67d9a72ea2f10f1a2d2eb7c04a41183359d5e1cc -Author: Guus Sliepen -Date: Fri Oct 19 18:54:43 2007 +0000 - - Use a dummy function as the read callback for connection bufferevents. Should not be triggered. - -commit 54892b2e3efcbbbd65b26a32f487829bbb8d787c -Author: Guus Sliepen -Date: Fri Oct 19 18:53:48 2007 +0000 - - Fix connection weight estimation. - -commit 6c453769fd16125ec18e8e6d102a3eaa09d370c7 -Author: Guus Sliepen -Date: Tue Sep 4 15:06:35 2007 +0000 - - Apply patch from Scott Lamb: Update documentation to match tincctl changes - -commit 86358fabfedca395b60310799a648b4875596efb -Author: Guus Sliepen -Date: Tue Sep 4 14:58:52 2007 +0000 - - Small fixes to make gcrypt routines compile. - -commit f8733d1935ed83399c4851a31f4be710eb8c825f -Author: Guus Sliepen -Date: Tue Sep 4 14:58:11 2007 +0000 - - Fix formatting of --help output. - -commit 65375289dff849f00b3429dfe4be7e66efe48444 -Author: Guus Sliepen -Date: Tue Sep 4 14:57:37 2007 +0000 - - Only check for libgcrypt if --with-gcrypt is used. - -commit d7ca0300a3f004e9dc7d97ffb6fa6bdeda890fda -Author: Guus Sliepen -Date: Fri Aug 17 22:09:00 2007 +0000 - - Handle SERVICE_CONTROL_INTERROGATE requests. Thanks to Carsten Ralle for noticing this. - -commit 1fd1d5bd9330e02ab5dc32ad027f654ff2620099 -Author: Scott Lamb -Date: Fri Jul 20 20:10:46 2007 +0000 - - const correctness - - cipher_encrypt and cipher_decrypt should take "const void *" data - -commit 35d865a6348cd62d2992bb3d353e37471d902889 -Author: Scott Lamb -Date: Wed Jul 18 16:44:05 2007 +0000 - - Updated svn:ignores list for new symlinked sources and tincctl. - -commit dd299c06dccceeb9b4db09eee17268cf5631fa41 -Author: Scott Lamb -Date: Wed Jul 18 16:40:41 2007 +0000 - - Refresh po/POTFILES.in. - - In particular, remove lib/pidfile.c which was causing failures. Also sort - for diffability with "find . -type f -name '*.c' | cut -c3- | sort" output. - -commit 46018a1a16579ce00b02eb6a991a70615ab9bc3e -Author: Scott Lamb -Date: Wed Jul 18 16:40:29 2007 +0000 - - Revert to only requiring autoconf 2.59. - - The new autoconf macros introduced at the same time (AC_GNU_SOURCE, - AC_FUNC_MALLOC, AC_FUNC_REALLOC) exist in the autoconf 2.59 documentation, - and autoconf 2.59 appears to still work. This is more convenient, as RHEL 5 - ships with autoconf 2.59. - -commit 1b8f8918360b40a2749d40355266ed7dedbe41b5 -Author: Guus Sliepen -Date: Wed May 23 13:45:49 2007 +0000 - - Finish crypto wrapping. Also provide wrappers for OpenSSL. - Disable libgcrypt by default. Since it doesn't support the OFB cipher mode, - we can't use it in a backwards compatible way. - -commit f42e57f663a2663c830c4fb4c01927c2d3c89c09 -Author: Guus Sliepen -Date: Tue May 22 23:41:22 2007 +0000 - - Some more crypto wrapper functions are needed. - -commit 19413a8048fd851866c551ab8035f008f0c7e806 -Author: Guus Sliepen -Date: Tue May 22 21:44:17 2007 +0000 - - Make sure the crypto wrapper functions can actually be compiled. - -commit e8689a4753ca2b1665e131cc40217da6c033ebd3 -Author: Guus Sliepen -Date: Tue May 22 21:32:48 2007 +0000 - - Create wrappers for the cryptographic operations used in tinc. - Implement them using libgcrypt. - -commit 465837dd7f7b727d489b354e4b75489dd49fd6e3 -Author: Guus Sliepen -Date: Sun May 20 22:28:49 2007 +0000 - - Parse PEM RSA keys ourself, and use libgcrypt to do RSA encryption and decryption. - -commit fbf305c09d91bf34b1504b58d50392df2e6bcfba -Author: Guus Sliepen -Date: Sat May 19 22:23:02 2007 +0000 - - Use libevent for meta socket input/output buffering. - -commit 59108e4e4f7aa4632c510d16961edd8c551a6542 -Author: Guus Sliepen -Date: Sat May 19 16:21:52 2007 +0000 - - Use bufferevents to handle control socket buffering. - -commit 8c6131deda546452386f3703af968ee664cadfbd -Author: Guus Sliepen -Date: Sat May 19 15:21:26 2007 +0000 - - Implement "stop" command, and allow tincctl to retrieve a running tincd's PID. - -commit e9043e17c76f92b787c9ecdaf1a2ae7916f690a6 -Author: Guus Sliepen -Date: Sat May 19 14:55:35 2007 +0000 - - Move key generation to tincctl. - -commit bf8e3ce13dba6109757c14dc0013a315a75d2ba3 -Author: Guus Sliepen -Date: Sat May 19 14:13:21 2007 +0000 - - Remove pidfile in favour of control socket. - -commit bc0a24ec810cb911610ae7aafa245e47d1268cd2 -Author: Guus Sliepen -Date: Sat May 19 13:34:32 2007 +0000 - - Fix retrying outgoing connections. - -commit ce976717ea9756aa985699547fdbf132b694748d -Author: Guus Sliepen -Date: Sat May 19 12:07:30 2007 +0000 - - We can safely delete a connection_t in terminate_connection() now. - -commit 01f47c46af514a9d7f39c143e4558a8426a0d3eb -Author: Guus Sliepen -Date: Fri May 18 16:52:34 2007 +0000 - - Start of control socket implementation. - -commit 6ded8a3f089a22c98d2a06b960d65b44e60188d6 -Author: Guus Sliepen -Date: Fri May 18 11:54:16 2007 +0000 - - Update documentation. - -commit 86586594334e951a99845d92baed1966e394aafa -Author: Guus Sliepen -Date: Fri May 18 11:35:21 2007 +0000 - - Show branch version number. - -commit e37ef57a956507cc29e80930201731562b4266e5 -Author: Guus Sliepen -Date: Fri May 18 11:19:31 2007 +0000 - - More consistent variable naming. - -commit 29fbce4497357580fc0aa00f087e8f1a538a2a50 -Author: Guus Sliepen -Date: Fri May 18 10:29:10 2007 +0000 - - Detect duplicate outgoing connections. - -commit fb0cfccf7dc2240b576011edcf74fd5b058916cb -Author: Guus Sliepen -Date: Fri May 18 10:05:26 2007 +0000 - - Use splay trees instead of AVL trees. - -commit f02d3ed3e135b5326003e7f69f8331ff6a3cc219 -Author: Guus Sliepen -Date: Fri May 18 10:00:00 2007 +0000 - - K&R style braces - -commit 760dd966efe7dbff316a8c638e40dee162848256 -Author: Guus Sliepen -Date: Fri May 18 09:51:54 2007 +0000 - - Remove last references to the global variable "running". - -commit 3909b8e51b27b11c6d54541220cb7767bf25569c -Author: Guus Sliepen -Date: Fri May 18 09:43:52 2007 +0000 - - Remove the last bits of the legacy main_loop(). - -commit ddc6a81a854023e38b563f213aa9a449ee91add8 -Author: Guus Sliepen -Date: Fri May 18 09:34:06 2007 +0000 - - Remove global variable "now". - -commit 7e1117197ca4fc62af93fda50e28e0ff06cb736c -Author: Guus Sliepen -Date: Thu May 17 23:57:48 2007 +0000 - - Move key regeneration handling to net_setup.c. - -commit 563577a1479549fa0c20dcda45831a0fff8c7513 -Author: Guus Sliepen -Date: Thu May 17 23:33:07 2007 +0000 - - Use libevent to handle key expiration. - -commit 8852d4407d87cf5dcf2c212d352279015aa050c0 -Author: Guus Sliepen -Date: Thu May 17 23:24:40 2007 +0000 - - Use libevent to age learned MAC addresses. - -commit a530f94e7c4acd94d1cd568b384931eec6f60563 -Author: Guus Sliepen -Date: Thu May 17 23:14:42 2007 +0000 - - Use libevent to age past requests. - -commit aaf1851315023c2f960c58a0d977085a485298e7 -Author: Guus Sliepen -Date: Thu May 17 23:04:02 2007 +0000 - - Redo SIGALRM handling. - -commit 6d19ebd612e6387ba34419cce5cd4d5d861b9a9e -Author: Guus Sliepen -Date: Thu May 17 22:41:34 2007 +0000 - - Use libevent to handle all non-fatal signals. - -commit 531d5a904a3a91bca8b7d373fb6ab2869b31e7fa -Author: Guus Sliepen -Date: Thu May 17 22:17:24 2007 +0000 - - Properly use the timeout_initialized() macro. - -commit bf6490825eabdf4eda6e64f2e5fcd690db7b72ce -Author: Guus Sliepen -Date: Thu May 17 22:13:12 2007 +0000 - - Remove legacy event system. - -commit a67ab277c9fdbcfc8c0550e9046df2a00b5fed81 -Author: Guus Sliepen -Date: Thu May 17 22:09:55 2007 +0000 - - Use libevent for retrying outgoing connections. - -commit 3321591d93d00326eee01fa7c78fb0d56b3d0fba -Author: Guus Sliepen -Date: Thu May 17 22:01:07 2007 +0000 - - Use libevent to send MTU probes. - -commit ee7844905f63872e12cd12f5a3d1a62220594831 -Author: Guus Sliepen -Date: Thu May 17 21:47:27 2007 +0000 - - Configure events after obtaining a socket. - -commit 294ce72441e44c0561556c2984f0e26a74230347 -Author: Guus Sliepen -Date: Thu May 17 21:34:58 2007 +0000 - - Use libevent to handle HUP signal. - -commit 4d0621b1f39537699b0ec4655b0c6e6b84581c9a -Author: Guus Sliepen -Date: Thu May 17 21:14:30 2007 +0000 - - Use libevent to dump graphs when necessary. - event_add() can be called repeatedly, the second and later calls are ignored if - the event hasn't been removed yet. - -commit 0f6f54ff8aa96d981f68b5b71c7126b8fdbead6c -Author: Guus Sliepen -Date: Thu May 17 20:20:10 2007 +0000 - - Use a separate event structure to handle meta data writes. - Make meta socket events persistent. - -commit 17c8033029d50ce4a30b6e3585c0ee28ef45bc97 -Author: Guus Sliepen -Date: Thu May 17 19:52:12 2007 +0000 - - 128 listener sockets is way too much. - -commit d8dea8091fa2260071f775db58ba277d4ce44ea7 -Author: Guus Sliepen -Date: Thu May 17 19:51:26 2007 +0000 - - Properly delete listener socket events on shutdown. - -commit 6ea1dfc995f386b3a9406c7935642524dc755c51 -Author: Guus Sliepen -Date: Thu May 17 19:15:48 2007 +0000 - - Port fixes from release 1.0.8. - -commit cf2be574948fdd02db0503d9639d3b6e268dd4ff -Author: Guus Sliepen -Date: Wed May 16 17:16:09 2007 +0000 - - Releasing 1.0.8. - -commit 6af8900f8e1c7f2fe6a50a991ae6cbd0fd7edd43 -Author: Guus Sliepen -Date: Wed May 16 14:46:25 2007 +0000 - - Don't free struct addrinfo too early. Spotted by Christian Cier-Zniewski. - -commit 31a190dc7db21aa9bb97792563dd83e7c41b831c -Author: Guus Sliepen -Date: Wed May 16 14:42:41 2007 +0000 - - Update dutch translation. - -commit 480dd127c8a539036ff82a3810a0ad83136944f8 -Author: Guus Sliepen -Date: Wed May 16 14:42:08 2007 +0000 - - Make sure connection->name is never NULL. - -commit f0cf4991e2bd0e618c7020511fb12cb0b5c59a40 -Author: Guus Sliepen -Date: Mon May 14 09:21:09 2007 +0000 - - Apply patch from "dnk" making sockets non-blocking under Windows. - -commit 3730156165fd1aa7c8810cd8e390aba6a8badcfa -Author: Guus Sliepen -Date: Mon Mar 12 17:55:43 2007 +0000 - - Only free members of connection_t that have been allocated. - -commit 39f6d59b4b81dc2d754329e6c9f885e8211c5e70 -Author: Scott Lamb -Date: Tue Feb 27 08:13:41 2007 +0000 - - Lots of svn:ignore entries - -commit 38c25d62c2bc76908bd95fb21c8f5e39ad269884 -Author: Scott Lamb -Date: Tue Feb 27 01:57:01 2007 +0000 - - Convert to libevent. - - This is a quick initial conversion that doesn't yet show much advantage: - - We roll our own timeouts. - - We roll our own signal handling. - - We build up the meta connection fd events on each loop rather than - on state changes. - -commit 834290b00f859412ee48bef454a07083cb727130 -Author: Scott Lamb -Date: Tue Feb 27 01:30:57 2007 +0000 - - A couple missed tevent things. - (Sorry; had a couple changes queued.) - -commit 6362b12df725044f3404faceff113e469d8ac860 -Author: Scott Lamb -Date: Tue Feb 27 01:26:11 2007 +0000 - - Rename "event_t" to "tevent_t", along with associated functions. - This relieves some confusion and problems during the libevent transition. - In particular, "event_add" was defined by both. - (The 't' stands for 'timeout', 'tinc', 'temporary', or some such.) - -commit 54431094d95f3989084755fdb91883b24cf5a9f4 -Author: Guus Sliepen -Date: Sat Feb 24 22:50:42 2007 +0000 - - Created the 1.1 branch where large code changes can take place, - at the same time keeping compatibility with 1.0. - -commit ab6f76f6a9fc8028fff96322a52b770710ffa1a9 -Author: Guus Sliepen -Date: Wed Feb 14 09:32:16 2007 +0000 - - Close the proper filedescriptor (if it exists). - -commit 45fca3c723302868de3225e7509d2292008948f7 -Author: Guus Sliepen -Date: Wed Feb 14 09:21:34 2007 +0000 - - Apply patch from Scott Lamb fixing some memory and resource leaks. - -commit 6c6535a4161d04accb3a22c51477e9f92ae34086 -Author: Guus Sliepen -Date: Wed Feb 14 09:20:20 2007 +0000 - - Apply patch from Scott Lamb preventing an infinite loop when sending SIGALRM. - -commit 16c8b0e5bb7c05a0559b2d799a32204bfa0a0e3f -Author: Guus Sliepen -Date: Fri Jan 5 15:03:07 2007 +0000 - - Releasing 1.0.7. - -commit a1e72f84d08b76784c11ff723666ceeaef2756eb -Author: Guus Sliepen -Date: Fri Jan 5 13:18:36 2007 +0000 - - Update copyright notices. - -commit a22ef25f9b81993226a74b193377c7d6baf910ca -Author: Guus Sliepen -Date: Fri Jan 5 13:17:33 2007 +0000 - - No things to do for the 1.0 branch except bugfixing. - -commit d80cc7a5cc918a1dbf8dd789d2125f55c4949d27 -Author: Guus Sliepen -Date: Fri Jan 5 05:44:01 2007 +0000 - - rename() cannot replace existing files on Windows. - -commit 5214ece03009a916159c710cf436af1e92909f41 -Author: Guus Sliepen -Date: Fri Jan 5 04:49:02 2007 +0000 - - Fix generic BSD tun device to write only the actual packet length. - Due to a copy&paste bug, it tried to write a packet with the maximum size. - This was not a problem until the maximum size was increased to support VLANs. - -commit 40f02ff8eee359dc0ccc898f8da319f56af161ad -Author: Guus Sliepen -Date: Thu Jan 4 15:28:36 2007 +0000 - - Tapreader socket should be bound to localhost only. - -commit 03f3fc01e8d9402c4a14904fded883ff8cc574f6 -Author: Guus Sliepen -Date: Wed Jan 3 18:18:54 2007 +0000 - - Use a ringbuffer in shared memory to transfer packets from the tapreader thread to the main thread. - It's a wonder it ever worked before. The socket that is created is not of a - datagram type, therefore packet boundaries were not preserved, which becomes - a problem as soon as the TAP-Win32 device receives packets in fast succession. - -commit 52787a73b0211bcb4cb3cdd308b1a4c53a60f8ce -Author: Guus Sliepen -Date: Mon Dec 18 17:38:05 2006 +0000 - - Releasing 1.0.6. - -commit b32c22cf54e47677726d15a5fca7eecc2fa42754 -Author: Guus Sliepen -Date: Mon Dec 18 11:41:53 2006 +0000 - - Prevent compiler warnings about redefinition of EAI_FAMILY on FreeBSD 6.1. - -commit 855806b2f75fc1c566cfaac01c788cdc625b4687 -Author: Guus Sliepen -Date: Sat Dec 16 16:53:58 2006 +0000 - - Do a simple test for linux/if_tun.h instead of no test at all. - -commit 0322c0883b76257c0893aa75a510e264056ac15b -Author: Guus Sliepen -Date: Sat Dec 16 16:40:09 2006 +0000 - - Remove the test for linux/if_tun.h. - It has been available for years on any decent Linux distribution. - Although linux/if_tun.h is now required to compile tinc, - you can still run it on systems which only support Ethertap. - -commit b55813dc0b4a6a1f70c0f8d5f0512c8cebb4a5ba -Author: Guus Sliepen -Date: Sat Dec 16 16:34:04 2006 +0000 - - We do properly check for malloc and realloc. - -commit 5219ee25a248fe26055e54215c5027cbf8483439 -Author: Guus Sliepen -Date: Sat Dec 16 16:26:57 2006 +0000 - - Use standard autoconf macros instead of our own. - -commit 9d469a19691f9749b5d729a1ae903d7aa224a6e8 -Author: Guus Sliepen -Date: Sat Dec 16 16:26:08 2006 +0000 - - Fix rule that creates html version of manpages. - -commit dd03a003962788eb21910c3faabbda0e84eff5eb -Author: Guus Sliepen -Date: Fri Dec 15 20:44:33 2006 +0000 - - Remove old Spanish translation. - -commit 031e09f865e2c634f30fb0ed4e0b6a1f6df57588 -Author: Guus Sliepen -Date: Fri Dec 15 20:43:39 2006 +0000 - - Remove unnecessary stuff from configure.in. - -commit b834d67d7cc7d7f5d8b729b340ec0c809c7d54b6 -Author: Guus Sliepen -Date: Tue Dec 12 14:54:39 2006 +0000 - - Use the correct next pointer. - -commit 8b55dfacb199d152391aa5f7adbbbe35bceea7d7 -Author: Guus Sliepen -Date: Tue Dec 12 14:49:09 2006 +0000 - - When building the minimum spanning tree, make sure we start from a reachable node. - -commit 47d916ec5eb61fa396c0ec6962afed7885141478 -Author: Guus Sliepen -Date: Wed Nov 29 17:18:39 2006 +0000 - - Search for lzo/lzo1x.h, lzo2/lzo1x.h and lzo1x.h. - -commit 1bb5a284fec8c538f8ba243d4f9b2e46f68cd7e8 -Author: Guus Sliepen -Date: Wed Nov 29 16:57:46 2006 +0000 - - Make sure resolved addressed for outgoing connections are freed, if there are any. - -commit 5c69c390a17fc2b37218881e7285b639b79cfc5a -Author: Guus Sliepen -Date: Tue Nov 14 15:43:28 2006 +0000 - - Releasing 1.0.5. - -commit e5b1b5cefb82531e8a700c2ee251da1bb0a06fbf -Author: Guus Sliepen -Date: Tue Nov 14 12:28:04 2006 +0000 - - EWOULDBLOCK does not exist on platforms without O_NONBLOCK - -commit 3353ab37c2d6fb3652fbf7a85d85997be1c0c1b5 -Author: Guus Sliepen -Date: Sat Nov 11 22:45:45 2006 +0000 - - When deleting an entire tree, start at head, not at root. - -commit 0714ac6c59099a398e67770ad9c72fcec615812b -Author: Guus Sliepen -Date: Sat Nov 11 22:44:15 2006 +0000 - - Nodes use events, so event system should be initialised first and destroyed last. - -commit 35e4096120236db8d64a767f1ccdd6bf03a091fc -Author: Guus Sliepen -Date: Sat Nov 11 21:37:22 2006 +0000 - - Update Dutch translation. - -commit 315ef3e42bf16e03cfbea763442a52389a16b832 -Author: Guus Sliepen -Date: Sat Nov 11 20:37:58 2006 +0000 - - Document GraphDumpFile option. - -commit 8d393b30a922110ec77d5b243347416b50cd2160 -Author: Guus Sliepen -Date: Sat Nov 11 20:10:46 2006 +0000 - - Support and autodetect LZO version 2.0 and later. - -commit bdb3c24cea06e9557738b42e3c37cd036613b58d -Author: Guus Sliepen -Date: Sat Nov 11 20:06:14 2006 +0000 - - Support and autodetect LZO version 2.0 and later. - -commit 0d1ac68c59db87141616f69bcd3d79c705b1ecd0 -Author: Guus Sliepen -Date: Sat Nov 11 14:37:03 2006 +0000 - - popen() requires pclose(). - -commit 0200d3cd5d773d9b101c33264532d2a301c2af32 -Author: Guus Sliepen -Date: Sat Nov 11 14:11:16 2006 +0000 - - Added graph dumping ability based on Markus Goetz's patch. - -commit 1728d5b2c43b33700a9997f97fe8503ad1cf3585 -Author: Guus Sliepen -Date: Sat Nov 11 13:43:00 2006 +0000 - - The "active" bit in node.status is not used. - -commit 134dc8995b296b0bd8b346617c705204b0f3125c -Author: Guus Sliepen -Date: Wed Aug 9 22:31:10 2006 +0000 - - memcpy() addresses from packet headers before calling the lookup functions. - This probably fixes a problem on the ARM architecture that causes tinc to fail to lookup IPv4 addresses. - -commit 64e0519cb5042b251e7345f07429e8b82e2ac09b -Author: Guus Sliepen -Date: Tue Aug 8 13:50:58 2006 +0000 - - Remove unused variable. - -commit ddcf079cad3351f0823fc07af15787d02e5f1901 -Author: Guus Sliepen -Date: Tue Aug 8 13:44:37 2006 +0000 - - Remove unused parameter from maskcmp(). - -commit c620df3c1511643aa533ca31afc17db75b7255b8 -Author: Guus Sliepen -Date: Tue Aug 8 13:44:19 2006 +0000 - - Remove unused variables. - -commit 9fa27097dd82e20299f5277ecb4efffb4a99669c -Author: Guus Sliepen -Date: Tue Aug 8 13:29:17 2006 +0000 - - Fix format string warnings. - -commit eb391c52eed46f3f03b404553df417851fc0cb90 -Author: Guus Sliepen -Date: Tue Aug 8 13:21:08 2006 +0000 - - Do not break strict aliasing of status_t structs. - -commit 2077451e07f93edc520cf5bc31815624a2b03fdd -Author: Guus Sliepen -Date: Mon Jun 12 21:45:39 2006 +0000 - - Add generic host-up and host-down scripts. - Thanks to Menno Smits for a patch. - -commit f88c9942e1e3d4d463ec71ba5a60d045381bda8f -Author: Guus Sliepen -Date: Sun Jun 11 18:53:27 2006 +0000 - - Use memcpy() to copy sockaddrs returned by getaddrinfo(). - Thanks to Miles Nordin for spotting this. - -commit 412f3fb5101514d9a7d4d9e5729ee9c665a07cb6 -Author: Guus Sliepen -Date: Wed Apr 26 16:29:47 2006 +0000 - - Restore length of the original packet in send_udppacket(). - -commit de78d79db84c486afcc353884ec1770866beb653 -Author: Guus Sliepen -Date: Wed Apr 26 13:52:58 2006 +0000 - - Update copyright notices, remove Ivo's email address. - -commit 8ebb017a10cd85406ddf5ab60d8ef1f56df526ff -Author: Guus Sliepen -Date: Wed Apr 12 08:38:35 2006 +0000 - - Fix a bug in handling prefixlengths that are not a multiple of 4. - Thanks to Sven-Haegar Koch for spotting the bug and providing the fix. - -commit af95368c0f30955f0e13b587d5d6d4989fd5a83e -Author: Guus Sliepen -Date: Sun Mar 19 13:06:21 2006 +0000 - - Fix signedness compiler warnings. - -commit fb1cda2ca4ca74a85e88c39c11b97340e6495a08 -Author: Guus Sliepen -Date: Sun Mar 19 12:43:45 2006 +0000 - - Export flush_meta(). - -commit 098090468a9e1e8c5cdb0aeefa277329ff5f3406 -Author: Guus Sliepen -Date: Sun Mar 19 12:43:28 2006 +0000 - - Missing #include. - -commit a90f1b652c0fb52950f3b0783a7e2b7f2e0cf2db -Author: Guus Sliepen -Date: Mon Feb 6 12:30:51 2006 +0000 - - Make sure $NAME is set correctly when executing tinc-down script. - -commit 228e7a5c8f0e517dcede50f886965a44fca39853 -Author: Guus Sliepen -Date: Thu Jan 19 17:13:18 2006 +0000 - - Apply patch from Scott Lamb adding an output buffer for the TCP sockets. - This helps coalescing multiple send_meta() commands into one TCP packet. - Also limit the size of the output buffer before dropping PACKETs. - -commit a5a4d2b865879b8694760c0a5b5909c9a3675027 -Author: Guus Sliepen -Date: Fri Jan 13 11:21:59 2006 +0000 - - Apply patch from Scott Lamb unifying configuration of TCP socket options. - -commit e02f13cdb3133c33ac84d9582e2f47ca5ebd35bf -Author: Guus Sliepen -Date: Fri Jan 13 11:09:19 2006 +0000 - - EVP_Cleanup() when quitting. - -commit 0912260755021b9b836830dd99ae128c5fd912d9 -Author: Guus Sliepen -Date: Wed Nov 16 10:45:11 2005 +0000 - - Enable OpenSSL ENGINE, so crypto hardware gets used. Thanks to Andreas van Cranenburgh. - -commit 64e4c12778697f71ad3fcf33ee6cf1066322caa5 -Author: Guus Sliepen -Date: Fri Jun 3 10:56:02 2005 +0000 - - Add alloca.h to the list of necessary header files. - -commit e810545dc2ae158745624c1575b76c55f883c892 -Author: Guus Sliepen -Date: Fri Jun 3 10:16:03 2005 +0000 - - Prevent possible buffer overflows when using very large (>= 8192 bit) RSA keys. - Thanks to Tonnerre Lombard for noticing! - -commit 02746165a21a4a495d0069526c9a2355110a5784 -Author: Guus Sliepen -Date: Wed May 4 19:38:28 2005 +0000 - - Releasing 1.0.4. - -commit df3220a1549f992cbf4a9b6e67c1e67b69896c7d -Author: Guus Sliepen -Date: Wed May 4 18:09:30 2005 +0000 - - Update copyright notices. - -commit 54a30e30ad41d7c0e73fcc4e6ff23c3e85af75c4 -Author: Guus Sliepen -Date: Wed May 4 16:53:11 2005 +0000 - - Describe subnet-up/down scripts in documentation. - -commit bded1b74cc23c60e7319ed9e7465413b94a7914e -Author: Guus Sliepen -Date: Wed May 4 15:56:25 2005 +0000 - - Several splay tree fixes. - -commit faaaa1ef38dcdf19d5d5d73ab66806b15467c043 -Author: Guus Sliepen -Date: Wed May 4 15:52:55 2005 +0000 - - Searching through splay trees may change the tree variable. - -commit dc09f6fe896f5e35fffe8cc2004781b2e1b6fd5a -Author: Guus Sliepen -Date: Wed May 4 15:51:45 2005 +0000 - - Be on the safe side with initialisation of c->name. - -commit 92c4a28d7d43b68a324cf2eca741298ed6b692d6 -Author: Guus Sliepen -Date: Wed Apr 6 20:43:37 2005 +0000 - - Remove unused (and potentially segfaulting) net2str() call. - -commit 6363ed4d9c675b8b9301b694c4e4dd9c892e04e2 -Author: Guus Sliepen -Date: Thu Jan 20 15:14:25 2005 +0000 - - Don't try to add a non-existing node back to the node_udp_tree. - -commit 39fe3b445c2f20b325ee492dd1845877777b25c8 -Author: Guus Sliepen -Date: Tue Jan 4 22:19:56 2005 +0000 - - Nodes should only be in the node_udp_tree if they are reachable. - -commit fe0bfa3e65049d6e7cd46cf6caea7eb91b478008 -Author: Guus Sliepen -Date: Tue Jan 4 22:18:58 2005 +0000 - - Correct size argument for strncat(). - -commit 56c36a14d87b58c14dbc48df4d3d977207e2c06e -Author: Guus Sliepen -Date: Fri Dec 3 13:27:33 2004 +0000 - - Use the proper free function. - -commit 18c617ecf29b9dfb95227e764c76fff0f9d7af96 -Author: Guus Sliepen -Date: Fri Dec 3 13:22:18 2004 +0000 - - Free memory used by connection_t after it is deleted from the connection tree. - -commit 672ad5634cbedfbd6345e887935eed3e806f1e2d -Author: Guus Sliepen -Date: Wed Dec 1 21:26:51 2004 +0000 - - Small fix. - -commit 40b1692940a8d588c08fb6b8f24ded7c33b041b1 -Author: Guus Sliepen -Date: Wed Dec 1 20:06:39 2004 +0000 - - subnet-up/down hooks, use list_t for the todo list. - -commit c46f56a8b8bb865dd8951441b5acf4701b5b5b09 -Author: Guus Sliepen -Date: Wed Dec 1 20:06:05 2004 +0000 - - subnet-up/down hooks - -commit f08baa3072e7cd6cee7a2a7cde35b46c85363baf -Author: Guus Sliepen -Date: Thu Nov 18 20:34:48 2004 +0000 - - Fix splay tree code. - -commit 0077cfaae112b63d6af6aa1e5d079cebdde84b74 -Author: Guus Sliepen -Date: Tue Nov 16 19:02:54 2004 +0000 - - Make sure broadcast packet reach the local network interface. - -commit 79c48cfafd75dfc86a382f6454a9f009d3c099b6 -Author: Guus Sliepen -Date: Thu Nov 11 19:42:25 2004 +0000 - - Releasing 1.0.3. - -commit 2771691bfc85b2544b30ccaee8a709bd26c7e1ab -Author: Guus Sliepen -Date: Thu Nov 11 19:39:28 2004 +0000 - - Add more people who have contributed to tinc. - Remove details and sort on name; - the details were not always equally accurate and are hard to maintain. - -commit 4f3f6f07b234b4abd32bf3bae1be0551bc7dd9dc -Author: Guus Sliepen -Date: Thu Nov 11 11:17:04 2004 +0000 - - Short readme about how to compile tinc from a Subversion checkout. - -commit 704c3707c2c400b7e35ef4ac2c1d21e0f2de0187 -Author: Guus Sliepen -Date: Wed Nov 10 23:28:32 2004 +0000 - - Updated dutch translation. - -commit a20eb05714f828be7dc0f78c1a07f218a3482dff -Author: Guus Sliepen -Date: Wed Nov 10 23:21:41 2004 +0000 - - Remove duplication. - -commit d8fe2ecdd8dc5caf6f8d6acf2923a0baed64735f -Author: Guus Sliepen -Date: Wed Nov 10 23:20:59 2004 +0000 - - Set BSD tuns to broadcast mode. On OpenBSD, this enables IPv6 on the tun device! - -commit 2369b0ab09a008c519cd4307b634fd294c66014e -Author: Guus Sliepen -Date: Wed Nov 10 21:57:04 2004 +0000 - - Update documentation. - -commit 4fe7aff4d1b8605d4997b842481cc78bd062fe2a -Author: Guus Sliepen -Date: Wed Nov 10 21:56:31 2004 +0000 - - Add BlockingTCP option, useful when using TCPOnly on slow or congested links. - -commit 5bba3124c8c23568def7a4804651a53f3a6b4fd2 -Author: Guus Sliepen -Date: Wed Nov 10 21:14:08 2004 +0000 - - Support tunneling IPv6 on Solaris. - -commit d02d81ff9dbb12253957065752c56785aedccee3 -Author: Guus Sliepen -Date: Wed Nov 10 19:36:02 2004 +0000 - - Let compiler decide when to inline. - -commit db68db4b0e0f8b776f2d3dc938fb81dac975fdd8 -Author: Guus Sliepen -Date: Wed Nov 10 19:34:38 2004 +0000 - - Fix order of arguments for tar. - -commit 923abcfa35c7282251d507af83d6163df76c943b -Author: Guus Sliepen -Date: Wed Nov 10 18:11:44 2004 +0000 - - Use the generic BSD tun/tap code. - -commit e8b11b1cca11f7f50542a7b34f4251f43447db0d -Author: Guus Sliepen -Date: Wed Nov 10 18:10:59 2004 +0000 - - Missing check for NULL-pointer. - -commit ca7948fc06fd0495dc8104d7f55948f702ac09e2 -Author: Guus Sliepen -Date: Tue Nov 9 09:51:35 2004 +0000 - - Hopefully this really fixes late packet handling. - -commit f7b9761000000063bd00460af4b57117db7361e4 -Author: Guus Sliepen -Date: Mon Nov 8 22:30:13 2004 +0000 - - Fixed another bug in late packet handling. - -commit 14eab178295768311d4518289533005991add8ba -Author: Guus Sliepen -Date: Mon Nov 8 22:11:33 2004 +0000 - - Update to make it compile again. - -commit 804b2892a5e26a2dc46d19397cc8b321b43b8add -Author: Guus Sliepen -Date: Mon Nov 8 22:03:28 2004 +0000 - - Hoopjumping to get the default directories in the manuals properly. - -commit 719cb95ea4fa7a2e6f4291aed607323f290c7a91 -Author: Guus Sliepen -Date: Tue Nov 2 20:50:53 2004 +0000 - - Splay trees. - -commit 2af1538976c9c85c40becfdd8601b421ad2ab057 -Author: Guus Sliepen -Date: Mon Nov 1 17:05:09 2004 +0000 - - Don't include .svn directory in sample configuration. - -commit dced64c5c3625f6d2f0674e9fed14455aabc635e -Author: Guus Sliepen -Date: Mon Nov 1 17:04:28 2004 +0000 - - Check for sys/uio.h, net/if_tun.h and net/if_tap.h - -commit 1f00810da336f3b7132df17b7fe4625748ff4b63 -Author: Guus Sliepen -Date: Mon Nov 1 17:02:19 2004 +0000 - - static - -commit 82b29e9a3b1dc6b2104ab92ed78bf431a4e55649 -Author: Guus Sliepen -Date: Mon Nov 1 17:01:56 2004 +0000 - - Generic device driver for *BSD and MacOS/X - -commit 922e5b7beaad5bb3fcbfa6b8dd13c05bda29e5fa -Author: Guus Sliepen -Date: Mon Nov 1 15:18:53 2004 +0000 - - Support alternative tun/tap driver from http://www-user.rhrk.uni-kl.de/~nissler/tuntap/ - -commit faff6498821555e6afb3dc5e4e3b61d448a4fef1 -Author: Guus Sliepen -Date: Mon Nov 1 15:18:22 2004 +0000 - - Don't let tinc service depend on NDIS component. - -commit 396ac4be802f8b75c5a2ab5925925427c61c1da3 -Author: Guus Sliepen -Date: Mon Nov 1 15:16:12 2004 +0000 - - Correct return value. - -commit 58153cca98fd43c37ae52d3cf69474c3d736c431 -Author: Guus Sliepen -Date: Fri Oct 1 18:26:15 2004 +0000 - - Allow tinc to work with the latest TAP-Win32 driver. - -commit 6411e0d8bda8abc2cef87ca852255502f9bb03d0 -Author: Guus Sliepen -Date: Fri Oct 1 18:24:41 2004 +0000 - - strndupa() is too arcane for some environments. - -commit b0a80007e8945a11d7ce25aab096c5ee58ce0ad5 -Author: Guus Sliepen -Date: Fri Oct 1 18:23:08 2004 +0000 - - Fix several #includes. - -commit 2c40495747945bc497dac65b734a4995ab3400a3 -Author: Guus Sliepen -Date: Fri Oct 1 18:22:06 2004 +0000 - - Move all #ifdef HAVE_HEADER_H #include to have.h, - this allows for simplification of configure.in. - -commit 7717cb0c54cc1b736b9f210b180c3cb3f4663ded -Author: Guus Sliepen -Date: Mon Sep 20 20:56:14 2004 +0000 - - Remove duplicate #include "system.h" - -commit 5373129344d349ff6aeb2b3d21f947f5ecbbcfaf -Author: Guus Sliepen -Date: Mon Sep 20 20:55:49 2004 +0000 - - Marking potential late packets was in the wrong place. - -commit c44f69a30243a94ab93bd15915dbfa71db698bde -Author: Guus Sliepen -Date: Sat Jul 17 12:04:30 2004 +0000 - - Don't set $INTERFACE automatically, don't quit on EINTR/EAGAIN. - -commit dcec713675b604f5ef82e64d0671727e3f5ea518 -Author: Guus Sliepen -Date: Sat Jul 17 00:09:14 2004 +0000 - - Added UML network socket handling. - Now you can use tinc instead of uml_switch. - -commit fe84fafcb684391739a1b3366705c58683210392 -Author: Guus Sliepen -Date: Mon Jun 21 14:37:52 2004 +0000 - - Handle timeouts during connecting the same way as other errors. - -commit e5e0dd7534be5fb96032fb733ca36a09cb067f17 -Author: Guus Sliepen -Date: Mon Jun 14 14:32:10 2004 +0000 - - Clean up environment after executing scripts. - -commit 9e44f116bf0f72d1dd4f099440a351dbe0a74573 -Author: Guus Sliepen -Date: Thu Apr 15 14:09:56 2004 +0000 - - Increase MTU by 4 bytes to allow VLAN tagged Ethernet frames in hub and switch mode. - -commit 7926a156e5b118d06295228e57de0cc9de0433b4 -Author: Guus Sliepen -Date: Sun Mar 21 14:21:22 2004 +0000 - - Update copyrights, links, email addresses and let Subversion update $Id$ keywords. - -commit 42e01abd54bd36ee84a45a2b646cfa27034de8d1 -Merge: 5ca64f89 af86a322 -Author: Guus Sliepen -Date: Sun Mar 21 13:22:24 2004 +0000 - - Move CABAL branch to its rightful place: the trunk. - -commit af86a3226ea42375644b3f99c182c778d327de1e -Author: Guus Sliepen -Date: Sat Mar 20 22:23:42 2004 +0000 - - Revert Martin Kihlgren's patch, it doesn't work the way it should. - -commit 27c304940a5dbe83fb0f655c5c43150bafed3b63 -Author: Guus Sliepen -Date: Sat Mar 20 15:40:26 2004 +0000 - - Use Subversion to create ChangeLog, better svn-clean rule. - -commit 8df22248293a8cd5e6056415b6e08740e40aa2bc -Author: Guus Sliepen -Date: Sat Mar 20 15:33:07 2004 +0000 - - Fix declaration of update_node_address(). - -commit 56aad1bb486675ff9aba31418708cc179eea0381 -Author: Guus Sliepen -Date: Sat Mar 20 15:28:55 2004 +0000 - - Applied Martin Kihlgren's IdentityGenerosity patch, - simplified and renamed to StrictSource. - -commit 8c189c2a9b77fb326ab5f27a05bf2601e16af017 -Author: Guus Sliepen -Date: Mon Mar 15 19:09:52 2004 +0000 - - Even better svn-clean command. - -commit b05df3fcbfb8dbef4c87691d118c5b68aeb79e4a -Author: Guus Sliepen -Date: Mon Mar 15 18:36:14 2004 +0000 - - Updating dutch translation. - -commit a92c471a2bc0773a7473ef0361d1a51fafee50d4 -Author: Guus Sliepen -Date: Mon Mar 15 18:15:02 2004 +0000 - - Only read our public key if it wasn't already in the private key file. - -commit a67a21ef3c17d32af95373e921138429a7fc507e -Author: Guus Sliepen -Date: Mon Mar 15 18:05:41 2004 +0000 - - Eat trailing whitespace in config files. - -commit 4350704d6578656af98195b26006c6b6d6a798e3 -Author: Guus Sliepen -Date: Mon Mar 15 17:54:19 2004 +0000 - - Remove CVS related cruft. - -commit 538595f7350ba6c7d11aba7d9f481ea1641e1857 -Author: Guus Sliepen -Date: Mon Mar 15 17:53:17 2004 +0000 - - Replace cvs-clean with a much better svn-clean. - -commit 5ca64f89be71131e77a29661827dc8866a5f278c -Author: cvs2svn -Date: Sat Jan 10 23:21:36 2004 +0000 - - This commit was generated by cvs2svn to compensate for changes in r1352, - which included commits to RCS files with non-trunk default branches. - -commit fcd836c609568fab323f4af6dd525de957a6f4cc -Author: Guus Sliepen -Date: Sat Jan 10 23:21:36 2004 +0000 - - Remove autogen.sh, the autoreconf program does exactly that. - Update everything for the latest autoconf and automake versions. - -commit f2aa7466e6db9777090583ef26d923fc0a4fcea8 -Author: Guus Sliepen -Date: Sat Jan 10 23:19:20 2004 +0000 - - Small updates. - -commit 519d63bedbdcc533dd7839aae02b4d7bc2debfb0 -Author: Guus Sliepen -Date: Sat Dec 27 16:32:52 2003 +0000 - - Don't forget to update destination MAC address. - -commit aebc97a77f37ec63fbd36721f9b284c975e54270 -Author: Guus Sliepen -Date: Wed Dec 24 10:48:15 2003 +0000 - - Small fixes for PMTU discovery. - -commit 2c7ce7de12d16cb407fd40224b6cb802528ee942 -Author: Guus Sliepen -Date: Mon Dec 22 11:05:23 2003 +0000 - - Missing definitions. - -commit 35399784b695c9ac692beba7be7930ee9f24412f -Author: Guus Sliepen -Date: Mon Dec 22 11:04:17 2003 +0000 - - Improvements for PMTU discovery and IPv4 packet fragmentation. - -commit 6d41b429a26dd1acaa7c56b2124f2daf55b5b97c -Author: Guus Sliepen -Date: Sat Dec 20 21:25:17 2003 +0000 - - Better name, show probed MTU in dump. - -commit af490a745d4ddc8994ceca546b5f9139f6a6ebe2 -Author: Guus Sliepen -Date: Sat Dec 20 21:20:10 2003 +0000 - - Describe the TunnelServer and PMTUDiscovery options. - -commit 9bab08e972ae0ca4b904a659d9aed46aaa9b5dd5 -Author: Guus Sliepen -Date: Sat Dec 20 21:09:33 2003 +0000 - - More sensible name, and try to set PMTU discovery on IPv6 sockets as well. - -commit 6b12bea62fe2e4bd8b5b6bd0e5ca7f53318705db -Author: Guus Sliepen -Date: Sat Dec 20 19:47:53 2003 +0000 - - Let tinc figure out the exact MTU of the link. - -commit e8fbef5de653e4df35eee49aae6e1ac92d6466e6 -Author: Guus Sliepen -Date: Sat Dec 13 21:50:26 2003 +0000 - - Forget multicast. Always inline some function. - -commit 5a1406adefd8b51981af0da5ac0ebec830eb43b4 -Author: Guus Sliepen -Date: Fri Dec 12 19:52:25 2003 +0000 - - Code beautification, start of multicast support. - -commit 354b7ab20e04736b368985a9e9dfd54ff5b7584e -Author: Guus Sliepen -Date: Mon Dec 8 12:00:40 2003 +0000 - - Fix proxy-neighborsolicitation. - -commit 331cef948db4b3cca245ab62cb0fafb5b1e5ebb3 -Author: Guus Sliepen -Date: Sun Dec 7 14:31:09 2003 +0000 - - Don't retry if configuration is wrong from the beginning. - -commit a3cd273751fdcef90a43108a5d2e669877b0bccb -Author: Guus Sliepen -Date: Sun Dec 7 14:29:02 2003 +0000 - - Missing space between words. - -commit 25447b384173cc3c99660c784fd784c787917e80 -Author: Guus Sliepen -Date: Sun Dec 7 14:28:39 2003 +0000 - - Read MaxTimeout from tinc.conf like the manpage says. - -commit 0b5e6cf04ec0c7e3c54c74a54a32b30e6e3c1f83 -Author: Guus Sliepen -Date: Thu Nov 27 23:24:59 2003 +0000 - - Complain if pid file cannot be created. - -commit e3220cacb5bc79fc56167e61b7a342f88a33a479 -Author: Guus Sliepen -Date: Mon Nov 17 15:30:18 2003 +0000 - - Replace Opaque and Strict options with a TunnelServer option. - -commit 0e59fb022c6c015a5be7ed70e0378cb011be98b5 -Author: Guus Sliepen -Date: Mon Nov 10 22:31:53 2003 +0000 - - Add Opaque option which prevent information from being forwarded to certain nodes. - -commit a8f415e67fd316d929f9b9e6661e0d3d66fc197b -Author: Guus Sliepen -Date: Sat Nov 8 15:29:40 2003 +0000 - - Release notes for 1.0.2 - -commit 507a83c74635955f803bb26c450f3e83dd4809f9 -Author: Guus Sliepen -Date: Sat Nov 8 15:09:03 2003 +0000 - - Add missing definitions. - -commit 0271de0e80459bdebcac50d38c053d4aaf657e9a -Author: Guus Sliepen -Date: Sat Nov 8 12:56:24 2003 +0000 - - Update dutch translation. - -commit d35a510fff65a7a3318036f27c11b956526b26f6 -Author: Guus Sliepen -Date: Sun Oct 12 11:40:00 2003 +0000 - - Fix another bug in meta.c. - -commit e88ea7277a97d46fa2c3ba1896cf0d0c62bdf128 -Author: Guus Sliepen -Date: Sat Oct 11 14:42:30 2003 +0000 - - Small fixes in documentation. - -commit ffb7327c20952cefcb5578e40f9802295172c5c2 -Author: Guus Sliepen -Date: Sat Oct 11 14:18:52 2003 +0000 - - Fix bug that could lead to an assertion failure in libcrypto when multiple - requests arrive and TCP packets are heavily fragmented. - -commit 258b7ce220607bb3f2a24bb7cab5fcd19e82314a -Author: Guus Sliepen -Date: Sat Oct 11 12:28:48 2003 +0000 - - Parentheses in the wrong spots. - -commit a1ab57e2755df6c1a8fab95a0886fea368200b96 -Author: Guus Sliepen -Date: Sat Oct 11 12:16:13 2003 +0000 - - Check all EVP_ function calls. - -commit b0dd705a264f0f72a7afba6de85200598cbe083b -Author: Guus Sliepen -Date: Fri Oct 10 16:24:24 2003 +0000 - - Check return value of EVP_* functions, and check if length before en/decryption - matches that after in meta.c. - -commit 9d2bf718f233672c11a9740ed2a1539eaab1509b -Author: Guus Sliepen -Date: Fri Oct 10 16:23:30 2003 +0000 - - Fix ASCII art. - -commit e33307fc9f5354933554d26de618db1b08fc04c0 -Author: Guus Sliepen -Date: Thu Oct 9 21:33:15 2003 +0000 - - Update documentation. - -commit 98edfb14fcc7167d24d440ed2772d0755daac3b7 -Author: Guus Sliepen -Date: Wed Oct 8 12:09:37 2003 +0000 - - Some platforms don't know sa_family_t or define it other than uint16_t. - -commit f2ebdf75806d8c04138db0eb30727f846541ed75 -Author: Guus Sliepen -Date: Wed Oct 8 11:37:53 2003 +0000 - - Set media status for newer TAP-Win32 driver. - -commit acf5f9c968d17ad3e31129d2184309de06d72eed -Author: Guus Sliepen -Date: Wed Oct 8 11:37:20 2003 +0000 - - Missing declaration. - -commit 1d7706a8506d8073def0965da809960c6ad8bf9a -Author: Guus Sliepen -Date: Wed Oct 8 11:34:55 2003 +0000 - - Update missing definitions, structs describing headers get __packed__ attribute. - -commit 5b556c0971e847580b85268e57f0b29dbde5499c -Author: Guus Sliepen -Date: Wed Oct 8 11:33:54 2003 +0000 - - Forgot to #include "xalloc.h" - -commit ad39db95fecf760297b4e320ef2f6d6d9fdad605 -Author: Guus Sliepen -Date: Mon Oct 6 16:49:42 2003 +0000 - - Make sure type of AF_UNKNOWN is sa_family_t. - -commit 5900c07fab39d2833ea66429ad652ca49a91a508 -Author: Guus Sliepen -Date: Mon Oct 6 16:13:08 2003 +0000 - - PIDs are of type pid_t, and use %ld when reading/writing them to the pidfile. - -commit e898b930dcd0694a49dc8cdcf373e0fc125c9fde -Author: Guus Sliepen -Date: Mon Oct 6 16:05:30 2003 +0000 - - Use CPPFLAGS, LDFLAGS and LIBS as appropiate. - -commit 6350334aa44f85e737c1eb0b55e0392766aa1e84 -Author: Guus Sliepen -Date: Mon Oct 6 14:41:45 2003 +0000 - - Don't confuse users with "Address family not supported" warnings. - -commit 0842998c0bd46855d198923acc2c13cff7430ffe -Author: Guus Sliepen -Date: Mon Oct 6 14:33:04 2003 +0000 - - Unused variable in struct. - -commit 77cb10dac0abbfa4389a7588f51797152d91ac22 -Author: Guus Sliepen -Date: Mon Oct 6 14:16:51 2003 +0000 - - Ethernet protocol types. - -commit c97b8827ed34284535706e8017c962ff8f3a4383 -Author: Guus Sliepen -Date: Mon Oct 6 13:57:12 2003 +0000 - - const - -commit 60943122f7b3a5896ce64c9000e119931484c12c -Author: Guus Sliepen -Date: Mon Oct 6 13:49:57 2003 +0000 - - Copy structs from packets to the stack before using them, to prevent - alignment issues. - -commit 5713fb07b3e831b78d8841d56a53c2a2698fe738 -Author: Guus Sliepen -Date: Wed Oct 1 09:43:01 2003 +0000 - - Add description of new authentication scheme. - -commit acbb9d6692614539260749c7b763eca5a6f81f07 -Author: Guus Sliepen -Date: Wed Oct 1 09:14:01 2003 +0000 - - Better length checks. - -commit eeb97e3ef4eb9089851f7b71d5393df24313c993 -Author: Guus Sliepen -Date: Thu Sep 25 10:34:16 2003 +0000 - - Generate keys with 0x10001 as public exponent, which has less prime factors - than 0xFFFF. - -commit 288d956728ab4d4aabe9bc59b87991420dbda151 -Author: Guus Sliepen -Date: Tue Sep 23 20:59:01 2003 +0000 - - Check for short packets from the tun/tap device and from other tinc daemons. - -commit 4e80612ac0f38daa0f2280c293427c7f25dac278 -Author: Guus Sliepen -Date: Tue Sep 9 15:47:59 2003 +0000 - - Update translations. - -commit cbf5a741aa2af937b3db606f0894990703f77bcb -Author: Guus Sliepen -Date: Mon Sep 8 21:52:47 2003 +0000 - - Remove pidfile when exitting. - -commit 0dba26267c76982a422984b61a3196ed2cd2b04a -Author: Guus Sliepen -Date: Wed Sep 3 16:20:33 2003 +0000 - - Prevent multiple inclusions. - -commit 6c5f3d8b74ffea1522a727ef189a5ba65a939e07 -Author: Guus Sliepen -Date: Thu Aug 28 21:05:11 2003 +0000 - - We don't have to tell GCC how to cast. - -commit 762cc2d2797d62ab593ea64d8ceeb4fe96be2a0d -Author: Guus Sliepen -Date: Thu Aug 28 15:27:12 2003 +0000 - - Remove old edges from unreachable nodes to us. This prevents the hosts/NAME-up - script from being called twice in some situations. - -commit a6dc69e7f30522bf885714f6b663960b6fbfff6a -Author: Guus Sliepen -Date: Wed Aug 27 13:58:29 2003 +0000 - - Forgot to synchronise po/ directory... - -commit 62349da6f2617c7250a77af6610344ec0dbfc4f2 -Author: Guus Sliepen -Date: Wed Aug 27 13:57:04 2003 +0000 - - Makevars file was accidentily removed. - -commit dc3b7d47f3297e22161787a1d6e06205140cf0fb -Author: Guus Sliepen -Date: Wed Aug 27 13:47:52 2003 +0000 - - Some device.c files weren't synchronised. - -commit 9e81a6ab5f50df4f5ca36d5303b91a8d5a0e753e -Author: Guus Sliepen -Date: Sun Aug 24 20:50:30 2003 +0000 - - This will become 2.0. - -commit 013a2e159e42c46808ea8d0b6abd57525db30a50 -Author: Guus Sliepen -Date: Sun Aug 24 20:38:31 2003 +0000 - - Synchronise HEAD with CABAL branch. - -commit ffb55e6904426a31c03b56c3bd87bb60db0624c6 -Author: Guus Sliepen -Date: Fri Aug 22 21:32:45 2003 +0000 - - Add license exception from Markus Oberhumer. - -commit 3e0b28b0c4d874934dde7b487a56cfacc956e3b4 -Author: Guus Sliepen -Date: Fri Aug 22 15:07:57 2003 +0000 - - Remove debug message. - -commit 89c9f3ed8fddb316d0f9ef7de30bdc76fba39e41 -Author: Guus Sliepen -Date: Fri Aug 22 15:04:26 2003 +0000 - - When purging nodes, only delete them if nobody references them anymore. - -commit 22dd23b650eb9b760bc68ab3a9227caf3b449140 -Author: Guus Sliepen -Date: Fri Aug 22 15:03:59 2003 +0000 - - Add checkpoints. - -commit 570e7e9c615388cfba263c7a7c66cbc3d092d6e7 -Author: Guus Sliepen -Date: Fri Aug 22 15:05:01 2003 +0000 - - Don't overwrite the first " when installing a service. - -commit 72bdc05cb7e246e56ed21a25256d441c45fccca8 -Author: Guus Sliepen -Date: Fri Aug 22 11:18:42 2003 +0000 - - Allow tinc to handle unknown type addresses from other tinc daemons. - -commit 5ac4179df66747a7013a10d576c23531d2b4fc58 -Author: Guus Sliepen -Date: Sun Aug 17 12:05:08 2003 +0000 - - If we're not in main_loop() and the service is stopped, exit immediately. - -commit 46cfe6199449a86eb58abaeac45b4021ffa7e178 -Author: Guus Sliepen -Date: Sun Aug 17 12:04:35 2003 +0000 - - Do what the SDK documentation tells. - -commit 107448698fc078bbd4cdbacdfbf51298ddc9ea65 -Author: Guus Sliepen -Date: Sun Aug 17 12:03:40 2003 +0000 - - Compilation fix. - -commit 3112e6a863b4421eb1a0b32632b86c55e47f989e -Author: Guus Sliepen -Date: Sun Aug 17 09:04:00 2003 +0000 - - Use the event log under Windows. - -commit 5e7c52610f8c8b9c38e437ef166a08372d5b8a61 -Author: Guus Sliepen -Date: Sun Aug 17 09:03:30 2003 +0000 - - Fix --logfile under Windows. - -commit 2236e05e518c9e317d82c027596bea5228725214 -Author: Guus Sliepen -Date: Sun Aug 17 08:32:39 2003 +0000 - - Fix fake getnameinfo() and check more arguments. - -commit f4e80cc5e0d1689bcdd828ac7f158bd634b7dd20 -Author: Guus Sliepen -Date: Sat Aug 16 12:40:01 2003 +0000 - - Don't getsockopt() SO_ERROR. We get the error from send()/recv() anyway. - -commit fd40130eb6bbba34176d34936a01bb6a6f9121d4 -Author: Guus Sliepen -Date: Sat Aug 16 12:11:11 2003 +0000 - - stat() batch files under Windows. - -commit 03995ca52ee31ed505902a3c8c3d1119988c8497 -Author: Guus Sliepen -Date: Sat Aug 16 12:10:28 2003 +0000 - - Simplify fake getname/addrinfo() functions, possibly fixing freeing a NULL pointer. - -commit dbfd6f284e0ff0aa04e6d6e62b902966912da516 -Author: Guus Sliepen -Date: Thu Aug 14 14:32:34 2003 +0000 - - Update. - -commit 7ed25590257b6ed33dfa879d187a09b0d790794f -Author: Guus Sliepen -Date: Thu Aug 14 14:21:35 2003 +0000 - - Fix permissions check for rsa_key.priv. - -commit 1f2670aab295dfd09c8c655611d2a5b820cb00fc -Author: Guus Sliepen -Date: Tue Aug 12 14:48:13 2003 +0000 - - Small fixes. - -commit b038e8db376969e70f1315840428b8a14ec8420f -Author: Guus Sliepen -Date: Tue Aug 12 12:35:53 2003 +0000 - - Updated dutch translation. - -commit ae070b917066f612e9aba8611c7a5da88e19a51a -Author: Guus Sliepen -Date: Sun Aug 10 13:35:05 2003 +0000 - - Add a description for the Service control panel. - -commit 9b579eb9ffdc1fd4a3d0cacb0728ec0796526bc5 -Author: Guus Sliepen -Date: Sat Aug 9 00:53:22 2003 +0000 - - Update documentation. - -commit 7eed829d288d0fdec2f31709a18ec420e489c2e4 -Author: Guus Sliepen -Date: Fri Aug 8 22:45:46 2003 +0000 - - Only system() needs script name quoted. - -commit 91f65c277483b47343b1b64d0f4edd497a8045a3 -Author: Guus Sliepen -Date: Fri Aug 8 22:13:50 2003 +0000 - - Check for fchmod(). - -commit 9bde92ce97d5503ff2d31dcc6f0648902580ec14 -Author: Guus Sliepen -Date: Fri Aug 8 22:11:54 2003 +0000 - - Simpler checking of permissions on private RSA key and other fixes. - -commit 96f5d98fc299a53fcdad304a56eb3a77a2c229e7 -Author: Guus Sliepen -Date: Fri Aug 8 19:56:11 2003 +0000 - - Small things. - -commit ef65a64443f740e3b22d9e903f764d9a58ce0ff0 -Author: Guus Sliepen -Date: Fri Aug 8 19:49:47 2003 +0000 - - Better error checking and reporting. - -commit bb2f18a3fc8acb7802f30e06153def30eb97a994 -Author: Guus Sliepen -Date: Fri Aug 8 19:45:21 2003 +0000 - - Under Windows, the installation directory can be found in the registry. - -commit 7f05445047c6479b81b7d393543ff73a95ee0dc8 -Author: Guus Sliepen -Date: Fri Aug 8 19:43:47 2003 +0000 - - Quote when needed and don't try stuff that doesn't work under Windows. - -commit b4c913aaa926d80a72aeb97459f84f992b65d1ed -Author: Guus Sliepen -Date: Fri Aug 8 19:42:35 2003 +0000 - - Log error first, try to close later. - -commit b0825f36b7b5dade1693fdbddfec7eef3f5ed86f -Author: Guus Sliepen -Date: Fri Aug 8 19:39:41 2003 +0000 - - Better error messages under Windows. - -commit 6f3099595530280028f6ec3d0b310df523e75f98 -Author: Guus Sliepen -Date: Fri Aug 8 17:20:12 2003 +0000 - - Typo. - -commit 691907caaeb348dee3dbe8a85f3590241f2cc992 -Author: Guus Sliepen -Date: Fri Aug 8 17:17:13 2003 +0000 - - Readd quotes. - -commit f956a28147ec8596c9a51b0c1535bb4b8c87692c -Author: Guus Sliepen -Date: Fri Aug 8 16:49:29 2003 +0000 - - Make rule for sample-config.tar.gz. - -commit 7e74e00d167da659ba6c3db3e8822008d27c081b -Author: Guus Sliepen -Date: Fri Aug 8 14:59:27 2003 +0000 - - Allow empty lines in config files. - -commit 863349638beb1eaab09e2a3d537c20a7913aef30 -Author: Guus Sliepen -Date: Fri Aug 8 14:48:33 2003 +0000 - - Simplify execute_script(). It will probably work under Windows as well. - -commit deba3ed900eb4453d27412606cecfaf89b5a5643 -Author: Guus Sliepen -Date: Fri Aug 8 14:24:09 2003 +0000 - - Correct error message when remote host closed connection. - -commit 0c2256670fc0822cc5a86bca754186c50f943a1c -Author: Guus Sliepen -Date: Fri Aug 8 14:07:12 2003 +0000 - - Remove unused stuff from doc/. - Let configure update pathnames in documentation. - -commit 070aee3be16b8d8078b049c5bb43dce7b18123df -Author: Guus Sliepen -Date: Fri Aug 8 12:55:05 2003 +0000 - - Tell windows to be patient. - -commit adb68b9c2aa7ad72dd5c38b95c083c47599cb65a -Author: Guus Sliepen -Date: Fri Aug 8 12:24:52 2003 +0000 - - Windows uses backslashes... - -commit ef091d1ddb1f7ab5244db96841274dc769e85167 -Author: Guus Sliepen -Date: Fri Aug 8 11:45:37 2003 +0000 - - Sync CABAL branch with release-1_0 branch. - -commit 5193a14ddea4c20ffc708dc629a2f91f1e4ccea3 -Author: Guus Sliepen -Date: Sun Aug 3 21:45:41 2003 +0000 - - Use our own port when connecting to ourself. - -commit 62a7fa9a7bfd1cd1592fd7c381ea28aac0ed7936 -Author: Guus Sliepen -Date: Sun Aug 3 21:45:13 2003 +0000 - - Simplify translation - -commit 98f97da9d7d80b528d9a2b2f03f710cdd2b293d0 -Author: Guus Sliepen -Date: Sun Aug 3 21:43:19 2003 +0000 - - Update dutch translation - -commit e220187f484f3549df3ad3a04939b9a38051d1a0 -Author: Guus Sliepen -Date: Sun Aug 3 12:38:43 2003 +0000 - - Remove newlines from log messages. - -commit 3671ed806d7371fb6b14a5909451b20e54a1b14a -Author: Guus Sliepen -Date: Sun Aug 3 12:38:18 2003 +0000 - - Keep Windows happy. - -commit 7bed2a7099fc7359f6ec24e5f2d7050c7d63b6ac -Author: Guus Sliepen -Date: Sun Aug 3 12:37:55 2003 +0000 - - Cygwin needs windows.h. - -commit fa9c00733e4b793691bf5a068ff7f2f391854fb4 -Author: Guus Sliepen -Date: Sun Aug 3 09:55:20 2003 +0000 - - Old gcc compilers don't like declarations in the middle of a function. - -commit a65011b3c54cd4ddc66f20909ca0e495de0d6eb0 -Author: Guus Sliepen -Date: Sun Aug 3 09:08:52 2003 +0000 - - Clean up last part of main(). - -commit e20ac7b52da8e3f7da292836c6e2551fc9f64617 -Author: Guus Sliepen -Date: Sat Aug 2 22:01:50 2003 +0000 - - Typo and another thing to think about. - -commit 92938c07b17fdd30f4e7f9ae1b884b05c7aa312c -Author: Guus Sliepen -Date: Sat Aug 2 21:55:12 2003 +0000 - - Explain how tinc detaches and how it is "killed" under Windows. - -commit 8a1969bc8319761e3821fc76a7c2f7037ffb8850 -Author: Guus Sliepen -Date: Sat Aug 2 21:39:11 2003 +0000 - - Updated dutch translation. - -commit f605ec47bed26362e24ffacf71c7ae5aeed3c230 -Author: Guus Sliepen -Date: Sat Aug 2 21:34:10 2003 +0000 - - Oops. - -commit e6e32814584f82ee61f658a71cb435bbb491bd39 -Author: Guus Sliepen -Date: Sat Aug 2 21:33:52 2003 +0000 - - Missing include. - -commit c044d12dfd54c033bc5ad9fbf9f889724762f76c -Author: Guus Sliepen -Date: Sat Aug 2 21:33:19 2003 +0000 - - Cleanups and error messages. - -commit 3fd96ebec7e44a0a7288c60da1cdec2d4fe03e8c -Author: Guus Sliepen -Date: Sat Aug 2 21:01:50 2003 +0000 - - Error messages. - -commit f08fc359a0b7f638e73a8f866119b016b7dff8de -Author: Guus Sliepen -Date: Sat Aug 2 20:50:38 2003 +0000 - - Install tinc as a service under Windows (MinGW). Remove cleanup_and_exit(), - either exit() directly on errors or let main_loop() shutdown gracefully. - -commit 7c34122af7ed4667748ceae4966bd5b519ac8ad7 -Author: Guus Sliepen -Date: Sat Aug 2 16:05:33 2003 +0000 - - When compiling with MinGW, link with ws2_32. - -commit 9a491a10eee55b243dd1030ee9016ec510908a10 -Author: Guus Sliepen -Date: Sat Aug 2 15:32:57 2003 +0000 - - Windows has no symbolic links as we know it. - -commit 9c2d5d9f9212dee5ee988f4824e5e4afedb7a2dd -Author: Guus Sliepen -Date: Sat Aug 2 15:29:06 2003 +0000 - - Oops. - -commit c7bf64c7946ece3e1a6a7cdd7bce00045bddb9cd -Author: Guus Sliepen -Date: Sat Aug 2 15:27:24 2003 +0000 - - Allow whitespace in values. - -commit b79e55b183898911e2c2b7b151b281aef8d474e1 -Author: Guus Sliepen -Date: Sat Aug 2 15:13:08 2003 +0000 - - Prevent system headers from including our own headers. - -commit 998ac634d456567e7caf99fe879d4ef1602f36bf -Author: Guus Sliepen -Date: Fri Aug 1 08:18:22 2003 +0000 - - Wrong function... - -commit 2531ff59b73af3a6de85fdc33d744758a6ab9449 -Author: Guus Sliepen -Date: Thu Jul 31 14:24:19 2003 +0000 - - Woops! - -commit 1fe56637874a1e93882a2ca6ffb8c50a773f80e4 -Author: Guus Sliepen -Date: Thu Jul 31 13:18:34 2003 +0000 - - No easy way to properly detect header files... - -commit 8eca27e863d9cb139a1e4039f63aaac3c9afc3c6 -Author: Guus Sliepen -Date: Thu Jul 31 11:31:51 2003 +0000 - - Remove forgotten braces. - -commit 5c29d066688691dd1664597ba1c76195634f06c0 -Author: Guus Sliepen -Date: Thu Jul 31 11:20:32 2003 +0000 - - Wrong argument. - -commit da3078c63a3b658573f6e2f986f69ed4d7993b3a -Author: Guus Sliepen -Date: Thu Jul 31 11:17:39 2003 +0000 - - Check if the compiler knows about the __malloc__ attribute. - -commit d798b8b3d832f8c69769e08cfd64a4d8355faf0e -Author: Guus Sliepen -Date: Wed Jul 30 21:52:41 2003 +0000 - - Prevent definitions from messing up attributes. - -commit 2edc764a333764e7e5c4d3420131c13e9c81ecf7 -Author: Guus Sliepen -Date: Wed Jul 30 16:00:59 2003 +0000 - - Replacement for stdbool.h - -commit fcbe29bc4cc67530581a36cf1a3a1445c741b8e5 -Author: Guus Sliepen -Date: Wed Jul 30 11:50:45 2003 +0000 - - No C99 initialisers, gcc 2.95.3 doesn't like it. - Also make sure getopt.h is included. - -commit de223b51b94c58d1674f1ef56e9d485ff48d366d -Author: Guus Sliepen -Date: Wed Jul 30 09:45:21 2003 +0000 - - Remove doc/es/ and src/device.c from the distribution. - -commit 63568bb6bca20b4d2b2068a6367084a273eabac8 -Author: Guus Sliepen -Date: Wed Jul 30 09:22:29 2003 +0000 - - Update documentation and remove stuff that's too outdated. - -commit 2ed154e73192d5e162544bc570abbb3a1df3ec83 -Author: Guus Sliepen -Date: Tue Jul 29 23:21:01 2003 +0000 - - Cleanups. - -commit 721e4caee0f7c6e003c297c95fb6d93bd4102219 -Author: Guus Sliepen -Date: Tue Jul 29 22:59:01 2003 +0000 - - Native Windows support. - -commit 586f15ed20682413d1bddbb4518dd2714c96b255 -Author: Guus Sliepen -Date: Tue Jul 29 12:38:49 2003 +0000 - - Make sure (at least) the MinGW device driver works. - -commit 6f7cce69479f9b2796d81f458bf836287b74462e -Author: Guus Sliepen -Date: Tue Jul 29 12:18:35 2003 +0000 - - Make sure it works. - -commit 4370b98bb1dfa9eb1e400549cb6fcb6711aa1b29 -Author: Guus Sliepen -Date: Tue Jul 29 11:50:39 2003 +0000 - - Update configure scripts. - -commit ae50b0077e27c4c4d81a98da46c66865ffa069be -Author: Guus Sliepen -Date: Tue Jul 29 11:06:23 2003 +0000 - - Update dutch translation and make sure all device drivers are included in - the translation and distribution. - -commit 714fb32d0377ed9f5643ed8f0bd914843d12266b -Author: Guus Sliepen -Date: Tue Jul 29 10:50:15 2003 +0000 - - Fix compile errors and warnings. - -commit 0e945413315c9d15a3eb013fa3731dd978a8c7b8 -Author: Guus Sliepen -Date: Mon Jul 28 22:06:09 2003 +0000 - - More checks for missing functions. - -commit c15e8a96bf7e45adf750b7a36b0e8446ea049468 -Author: Guus Sliepen -Date: Mon Jul 28 21:54:03 2003 +0000 - - More generic handling of tap device under Windows. - -commit 83263b74460656ba557fd9bb84dc27258549e9cd -Author: Guus Sliepen -Date: Thu Jul 24 12:08:16 2003 +0000 - - Sprinkle around a lot of const and some C99 initialisers. - -commit 5cb147135184e3748c6f5e6e6203d22ab9f904f8 -Author: Guus Sliepen -Date: Wed Jul 23 22:17:31 2003 +0000 - - Don't initialise a CIPHER_CTX if cipher == NULL. - -commit 4aadb9500d9198f9c271deb048a2d36000bfae34 -Author: Guus Sliepen -Date: Tue Jul 22 21:13:23 2003 +0000 - - Run setup_device() after parsing configuration but before claiming we're ready. - -commit eefa28059ab989c915a7d95fb4ae728abd7ce713 -Author: Guus Sliepen -Date: Tue Jul 22 20:55:21 2003 +0000 - - Use bools and enums where appropriate. - -commit 471308e1636e7a06e1d9ebc98e82b1c0c5150dde -Author: Guus Sliepen -Date: Tue Jul 22 12:58:34 2003 +0000 - - Option to specify pidfile location. - -commit c96900f378966ca1be96ddb1c43f855c74083b70 -Author: Guus Sliepen -Date: Mon Jul 21 19:58:58 2003 +0000 - - Add section about configuring Cygwin and CIPE on Windows. - -commit bad82522ecfc1f3c72c600cbca6e8fa7e950c3bf -Author: Guus Sliepen -Date: Mon Jul 21 15:51:00 2003 +0000 - - Copy cygwin driver to mingw directory. It doesn't work (yet). - -commit e169244e4b10dbcc1910c0f7fd811304d5b1a5a5 -Author: Guus Sliepen -Date: Mon Jul 21 14:47:43 2003 +0000 - - Use functions from logger.c - -commit 2f2defc4525befd5b5cb69d03b7887db35e9e46c -Author: Guus Sliepen -Date: Mon Jul 21 13:18:44 2003 +0000 - - Check for sys/mman.h. - -commit 64fd25aa6b794bb1d957b50d48705f30ed47c878 -Author: Guus Sliepen -Date: Mon Jul 21 13:15:36 2003 +0000 - - Oops. - -commit c1e8152f4fe5e4557784d8411e50006d461b8786 -Author: Guus Sliepen -Date: Mon Jul 21 13:14:02 2003 +0000 - - Be consistent. - -commit b657f0519456d05bcea5742017165793f79e56df -Author: Guus Sliepen -Date: Fri Jul 18 14:10:27 2003 +0000 - - No UNIX style permissions under Windows. - -commit 38aa0319ef79124e59b587e6d55f37a79a9d847c -Author: Guus Sliepen -Date: Fri Jul 18 14:09:47 2003 +0000 - - Oops. - -commit 123bb765d10453fdccbe363a02e3042c588729cc -Author: Guus Sliepen -Date: Fri Jul 18 13:45:06 2003 +0000 - - Use iface instead of interface because it might already be declared in - system header files. - -commit 96ee04b678143defa1040f2defdd3424efedea11 -Author: Guus Sliepen -Date: Fri Jul 18 13:42:35 2003 +0000 - - Check for ethernet/ipv4/ipv6 related structures. - -commit 00ddbf5723511d80fbd2522fc503bd409dc6189a -Author: Guus Sliepen -Date: Fri Jul 18 13:41:37 2003 +0000 - - Update all device.c files. - -commit 271d3537fed28b3e76cf0e76082b44c8771ac5da -Author: Guus Sliepen -Date: Fri Jul 18 12:21:03 2003 +0000 - - Remove all #ifndefs from route.c - -commit b0a4f7b5551cae6fb5af2eb4bcb0dfb3443f7d89 -Author: Guus Sliepen -Date: Fri Jul 18 12:16:24 2003 +0000 - - Even more missing definitions. - -commit e449d94caef963809d417f16497f6f978e10d731 -Author: Guus Sliepen -Date: Thu Jul 17 15:06:27 2003 +0000 - - Big header file cleanup: everything that has to do with standard system - libraries is moved to system.h. - -commit 47721be760c495ec13d68181bc03b151ffc1399c -Author: Guus Sliepen -Date: Tue Jul 15 16:38:18 2003 +0000 - - Windows headers declare a struct interface somewhere. - -commit 4c52febc57f2e34f5a187f0e57782903fe1eb95e -Author: Guus Sliepen -Date: Tue Jul 15 16:27:39 2003 +0000 - - Make use of the CIPE driver. Woohoo, tinc for Windows! - -commit d26a4af4561ce4236b8224919cf4f3636f57b4c1 -Author: Guus Sliepen -Date: Tue Jul 15 16:26:18 2003 +0000 - - Export mymac. - -commit 784db4e70d2573468c82ff5dfee723b77a20322f -Author: Guus Sliepen -Date: Sat Jul 12 20:24:04 2003 +0000 - - Format string checking for logger(). - -commit a438ac911e7e60e54d7d1fc4f84373fab7e055af -Author: Guus Sliepen -Date: Sat Jul 12 20:19:22 2003 +0000 - - Removing distribution specific files from CVS. - -commit 085d33e6265e139bb08cdfda3d7498993190d187 -Author: Guus Sliepen -Date: Sat Jul 12 17:48:38 2003 +0000 - - Update copyrights. - -commit 5db596c6844169f1eb5f804b72abe99d067aaa5a -Author: Guus Sliepen -Date: Sat Jul 12 17:41:48 2003 +0000 - - Simplify logging, update copyrights and some minor cleanups. - -commit 2a7f11c0e90f5f0465bbc3c75de715454066ff72 -Author: Guus Sliepen -Date: Fri Jul 11 16:13:00 2003 +0000 - - More missing IPv6 definitions and autoconf checks to make sure it compiles - under Solaris 2.6. - -commit 71f8124ea49f2a0e00e0cedbb1b76e49e9f1425d -Author: Guus Sliepen -Date: Mon Jul 7 11:50:52 2003 +0000 - - More missing definitions. - -commit a88f1edf297152580a7729c6f3d274ba2bff7360 -Author: Guus Sliepen -Date: Mon Jul 7 11:13:31 2003 +0000 - - Actually add ipv6.h. - -commit 30c0381d71d333a99f6c83ff9d03ef4a0857f423 -Author: Guus Sliepen -Date: Mon Jul 7 11:11:33 2003 +0000 - - Provide all missing IPv6 definitions in lib/ipv6.h. - -commit 1401faf608e1c8af0d0754e545b0ec79d2bd5d93 -Author: Guus Sliepen -Date: Sun Jul 6 23:16:29 2003 +0000 - - Sprinkling the source with static and attributes. - -commit 0b9175e998c2180e5d73ef3d644a49d620c68cad -Author: Guus Sliepen -Date: Sun Jul 6 22:11:37 2003 +0000 - - Define logger(), cleans up source code and allows us to write log entries - to a separate file. - -commit 868104703003605711582c984b57f8933bf361ee -Author: Guus Sliepen -Date: Sun Jul 6 17:49:49 2003 +0000 - - Check for IPv6 header files. - -commit 81f5713ab71944d51703653eab7f364fba0c482e -Author: Guus Sliepen -Date: Sun Jul 6 17:15:25 2003 +0000 - - - simplify configure.in - - drop support for OpenSSL < 0.9.7 - - add some missing definitions/includes - -commit 6c7172d694dcb80e538518282b6c4bd51818f1d2 -Author: Guus Sliepen -Date: Wed Jun 25 20:55:05 2003 +0000 - - This subtle pointer arithmetic thingy is (I'm very sure of it) the cause - of the lingering connections problem. Hopefully it is fixed now... - -commit 9528a63c35da77ba5b825068aeffbc5587816dd5 -Author: Guus Sliepen -Date: Wed Jun 25 20:52:59 2003 +0000 - - Really make tinc default to any addressfamily. - -commit 8bfa554af97ee0694919b9f5b78ada89c6af62f5 -Author: Guus Sliepen -Date: Thu Jun 12 11:08:40 2003 +0000 - - There are two lzo compression levels. - -commit c3593491d44e8e8f239bb297f5d5f6541d581b78 -Author: Guus Sliepen -Date: Wed Jun 11 20:36:36 2003 +0000 - - Typo and conversion to UTF-8. - -commit 636e650261712e3687048fe19987fd50ce84b093 -Author: Guus Sliepen -Date: Wed Jun 11 20:19:46 2003 +0000 - - Update dutch translation. - -commit 9279b3c69982b066e2aaea4e444892b51332881a -Author: Guus Sliepen -Date: Wed Jun 11 20:18:48 2003 +0000 - - Update documentation. - -commit 0a9aef2da749f7b7d1ca183daad88f6433579b9f -Author: Guus Sliepen -Date: Wed Jun 11 19:40:43 2003 +0000 - - More braces to make gcc happy. - -commit cf63cbef2bcb6a1f21ded439cbb09842581b9020 -Author: Guus Sliepen -Date: Wed Jun 11 19:39:02 2003 +0000 - - Fixes from Wessel Danker's libavl. - -commit 12de5a8eedd985f4732e88de6185f77a8244612c -Author: Guus Sliepen -Date: Wed Jun 11 19:28:38 2003 +0000 - - Remove mymac stuff from device.c. - -commit 31f17d43346a9175aec7c29ce41c71b1d08f725e -Author: Guus Sliepen -Date: Wed Jun 11 19:27:35 2003 +0000 - - AddressFamily is "any" by default. - -commit 451800eda87e886021fabd1888e486c51e97902a -Author: Guus Sliepen -Date: Wed Jun 11 19:09:52 2003 +0000 - - If we have a Linux tun/tap device and we are in router mode, open the device - in tun mode. - -commit 9e02a3d5631b687833e4cdcde18cda66e38138fc -Author: Guus Sliepen -Date: Wed Jun 11 19:07:56 2003 +0000 - - Call make_names() before doing anything else. - -commit 4b0e5a03fe89529ebe5d471a82c29c153a12116b -Author: Guus Sliepen -Date: Sat Jun 7 13:18:32 2003 +0000 - - Fix warning and add missing checks for LZO library. - -commit f238c209f4a0ced889b8fb443753ed2cdb3548b3 -Author: Guus Sliepen -Date: Sat May 17 22:12:52 2003 +0000 - - Fix links. - -commit 249933350bda2c3fa09c7ce8eb36bf84ee30a1cb -Author: Guus Sliepen -Date: Wed May 7 11:21:58 2003 +0000 - - Small fixes. - -commit 6ba4e2da55001e17aec6a7ee71002130555ff439 -Author: Guus Sliepen -Date: Tue May 6 23:14:45 2003 +0000 - - Small fixes to make LZO compression work. - -commit c70f52087bf6f7514684bbc859b83aec2ca17ae4 -Author: Guus Sliepen -Date: Tue May 6 21:13:18 2003 +0000 - - - Per-node EVP_CIPHER_CTX to avoid initialisation overhead. - - LZO compression, thanks to Teemu Kiviniemi. - - Updated dutch translation. - -commit 1ad2394b8468593030653bbfd0dee879fb711432 -Author: Guus Sliepen -Date: Sat Apr 19 11:12:45 2003 +0000 - - Make sure outgoing_t is completely freed. - -commit bc9e78250ef6fb5169d03565b7d8d9caf309eb98 -Author: Guus Sliepen -Date: Fri Apr 18 21:18:36 2003 +0000 - - Better handling of late packets. - -commit 51a1bcf00143319c74ffb58a66a19c41be422c21 -Author: Guus Sliepen -Date: Thu Apr 3 11:43:17 2003 +0000 - - HUP signal now closes connections to hosts if their host config file is - gone or changed. The tinc.conf file is reread for changes in the ConnectTo - lines. - -commit 8285827da127e38728b60b5c5484e5cdabff2f21 -Author: Guus Sliepen -Date: Sat Mar 29 22:11:22 2003 +0000 - - Checksums must also work for uneven number of bytes. - -commit c3ad3731a8dfa34535a156a7cfdb4e18afaa8bce -Author: Guus Sliepen -Date: Sat Mar 29 21:58:35 2003 +0000 - - Don't copy more than necessary. - -commit 7d21a8d1c7fd8909fe02385dbb4717c074db4648 -Author: Guus Sliepen -Date: Sat Mar 29 21:51:21 2003 +0000 - - - Speed up checksumming - - If a destination is not found in the subnet list or the destination node - is unreachable, respond with an appropiate ICMP message. - -commit 9792ba2cac35cb50cc99b72dd4cb9d3ef350dbd4 -Author: Guus Sliepen -Date: Fri Mar 28 13:41:49 2003 +0000 - - - Avoid memory leak caused by OpenSSL 0.9.7a. - - Disable RSA_blinding_on() because it segfaults. - -commit 69158563e9f790777eb27aeb8484a86d12385af4 -Author: Guus Sliepen -Date: Wed Mar 19 11:45:05 2003 +0000 - - Typo. - -commit 88ae2e9e0c1eb62d9b74c4b38d9c0e93557fed9f -Author: Guus Sliepen -Date: Wed Mar 19 11:43:42 2003 +0000 - - Make sure send_meta() writes everything. - -commit 2fff0a91a7e3e5f44e97255b6dd5807656b255a8 -Author: Ivo Timmermans -Date: Fri Mar 14 09:43:10 2003 +0000 - - Call RSA_blinding_on(), as advised in the paper on - http://crypto.stanford.edu/~dabo/abstracts/ssl-timing.html - to offer some resistance against timing attacks. - -commit 1783a3aaa9b692ab64260a9c2adf588ed6083a1c -Author: Guus Sliepen -Date: Fri Jan 17 00:43:58 2003 +0000 - - Various fixes for autoconf and OpenSSL 0.9.7 and a missing header. - -commit c08858baa91a00e38c0f5482dbb0817dbd0361f1 -Author: Guus Sliepen -Date: Fri Jan 17 00:37:20 2003 +0000 - - - Fix indentation in some places. - - Optimise select loop. - - Remove unused function setup_outgoing_socket(). - - Clear EVP_CIPHER_CTX structures before using them. - -commit 38f562fdfcacb50d34b9a48bfaea7faa132f493a -Author: Guus Sliepen -Date: Tue Jan 14 12:53:59 2003 +0000 - - Add $NAME for tinc-up/down scripts. - -commit 44b87ddb7ac90be13ef3e3d5118acaa158184853 -Author: Guus Sliepen -Date: Sun Jan 12 17:02:23 2003 +0000 - - Run graph algorithm when replacing a second connection from the same host - replaces an older one. - -commit 4c88ff86bcd32735d4768ef3464812cd77c500be -Author: Guus Sliepen -Date: Fri Dec 27 19:32:33 2002 +0000 - - PrivateKeyFile instead of PrivateKey. - -commit 5b2a62ebb6317cd88e491ee958c54670f381aee8 -Author: Guus Sliepen -Date: Thu Nov 14 22:09:03 2002 +0000 - - Fix PriorityInheritance. - -commit 07db46a44feb283c1c17bcce918ab49274a3b11f -Author: Guus Sliepen -Date: Mon Oct 7 07:32:31 2002 +0000 - - Add documentation for BindToAddress. - -commit e310cc82d3f9c9bdb3b827daa149861a41e2e00a -Author: Ivo Timmermans -Date: Mon Sep 30 19:04:37 2002 +0000 - - Fix saving of debug level for startup level 0 - -commit 006591efe5b3e6c64040d267f8c0477468abf2bf -Author: Guus Sliepen -Date: Tue Sep 24 11:43:34 2002 +0000 - - Run graph() after edge_del() when updating an edge. - -commit 6904e0469ef52aa6100f0185d579bc205bd07be8 -Author: Wessel Dankers -Date: Mon Sep 16 14:08:04 2002 +0000 - - its: Engels voor "van het" - 3e persoon enkelvoud, genitief, onzijdig - it's: Engels voor "het is". Dus niet "van het". - -commit 4f3395ee4dad3cdd23706af180ebddfa5e576012 -Author: Guus Sliepen -Date: Sun Sep 15 22:37:59 2002 +0000 - - Thank some more people. - -commit b216297a004f083336c633aaccecb4ab175360b3 -Author: Guus Sliepen -Date: Sun Sep 15 22:34:25 2002 +0000 - - Remarks about 1.0pre8 release. - -commit 1dcbdf48eb4a642e4d70a9e67aaca78deacf352d -Author: Guus Sliepen -Date: Sun Sep 15 22:19:38 2002 +0000 - - Update documentation. - -commit bf3a11898898c0618cd1b2e7a792b7d7fe56aecb -Author: Guus Sliepen -Date: Sun Sep 15 22:19:19 2002 +0000 - - Use /dev/net/tun as default for tun/tap device under Linux. - -commit 7d76ceaebd5180f4ef37086980c799199eb7de16 -Author: Guus Sliepen -Date: Sun Sep 15 17:40:00 2002 +0000 - - Updated dutch translation. - -commit 5eca9520d93bced1275d45e5e2a933d69354cd6d -Author: Guus Sliepen -Date: Sun Sep 15 14:55:54 2002 +0000 - - Small fixes so tinc compiles out of the box on SunOS 5.8 - -commit 8d472a415e9c5fdb878386005d29cdfd97b8a404 -Author: Guus Sliepen -Date: Sun Sep 15 12:26:24 2002 +0000 - - port_t isn't used anymore and conflicts with MacOS/X headers. - -commit 38c80bdd46fab68c686a293e2820041291972f3a -Author: Guus Sliepen -Date: Sun Sep 15 12:26:04 2002 +0000 - - MacOS/X needs #define _P1003_1B_VISIBLE in order to use mlockall(). - -commit 3e3b4a3190cf950c265a8c62d577812a22b11dcc -Author: Guus Sliepen -Date: Wed Sep 11 22:25:58 2002 +0000 - - What was I thinking? - -commit f6905582d0e70ac5b44369780aaa921d9c721197 -Author: Guus Sliepen -Date: Tue Sep 10 22:13:22 2002 +0000 - - Make sure malloc() is declared. - -commit eaf1208e9d5c5a15e4b23de936830520bf3b5685 -Author: Guus Sliepen -Date: Tue Sep 10 22:13:01 2002 +0000 - - Fix placement of #include "config.h" - -commit dd888ca685176128bf41034208f3dbb220f9d832 -Author: Guus Sliepen -Date: Tue Sep 10 21:46:05 2002 +0000 - - Link with libintl if necessary. - -commit c01f78ed3603eecaec8e3649a3bfb3de9742fd24 -Author: Guus Sliepen -Date: Tue Sep 10 21:29:42 2002 +0000 - - Clean up after indent. - -commit 161f917dd03c174742fb8c6722f430a93b506cb1 -Author: Guus Sliepen -Date: Tue Sep 10 09:40:25 2002 +0000 - - Fix compiler warnings. - -commit 3bc554347560a9c24e68bb2c7c7749be07bbec3d -Author: Guus Sliepen -Date: Mon Sep 9 22:41:56 2002 +0000 - - Let GCC check format string and arguments of send_request(). - -commit 6f9f6779e6bd1dd7bb795b42dad550863a386ca8 -Author: Guus Sliepen -Date: Mon Sep 9 22:33:31 2002 +0000 - - Remove redundant spaces. - -commit 9f38e394636a177c00a4545de2a99c661de36386 -Author: Guus Sliepen -Date: Mon Sep 9 21:49:16 2002 +0000 - - Switch to K&R style indentation. - -commit f75dcef72a81a337e847adf0bae54198894f65b9 -Author: Guus Sliepen -Date: Mon Sep 9 21:25:28 2002 +0000 - - Switch to K&R style indentation. - -commit 5fc1ed17f41f0c535cf57a4b7e00cd6d45759503 -Author: Guus Sliepen -Date: Mon Sep 9 19:40:12 2002 +0000 - - Cleanups: - - Convert cp to cp(); so that automatic indenters work. - - Convert constructions like if(x == NULL) to if(!x). - - Move all assignments out of conditions. - -commit 5638b9830f9cfe43f545c37cfd7ccf1d4b4bfcc6 -Author: Guus Sliepen -Date: Fri Sep 6 21:22:35 2002 +0000 - - Why don't these connection_t's get cleaned up? - -commit a8ddba42b99d7694359f1387235596b84d297b9e -Author: Guus Sliepen -Date: Fri Sep 6 21:02:36 2002 +0000 - - Fix MST algorithm. - -commit 66741978e16cc407e5c760621c34d1aabb753cd2 -Author: Guus Sliepen -Date: Fri Sep 6 14:31:12 2002 +0000 - - Reset the *correct* seqnos. - -commit d5b61fc0cd249fd2b2751a1ff77b321323a17beb -Author: Guus Sliepen -Date: Fri Sep 6 12:19:16 2002 +0000 - - edge_weight_compare() shouldn't rely on edge_compare(). - -commit fc7116a32b798589e7731db9f9db66345c8c3e01 -Author: Ivo Timmermans -Date: Fri Sep 6 11:08:21 2002 +0000 - - Added AM_MAINTAINER_MODE - -commit fbf8a47879671541939cfdc6beb93b02b9eee303 -Author: Guus Sliepen -Date: Fri Sep 6 10:23:52 2002 +0000 - - Remove global edge_tree. - -commit 641705df90b4c41e7f5083f6cd601cbbfb1c2c85 -Author: Guus Sliepen -Date: Fri Sep 6 09:48:39 2002 +0000 - - Only reset seqno's when a key is sent or received. - -commit e4d85a6557ee45870bee0c5a16807e48b7a3c243 -Author: Guus Sliepen -Date: Wed Sep 4 23:11:58 2002 +0000 - - Typo. - -commit b4f87952bf2d37524c705b32864f802144f94d68 -Author: Guus Sliepen -Date: Wed Sep 4 23:05:49 2002 +0000 - - Add missing headers. - -commit b18bd211bec84a804f58da5f2d2908e54de3fe40 -Author: Guus Sliepen -Date: Wed Sep 4 23:04:52 2002 +0000 - - Run autopoint and libtoolize before creating initial makefiles. - -commit 6fdaa8e1caff4edb44a105b03c79403b743e9bd2 -Author: Guus Sliepen -Date: Wed Sep 4 19:57:53 2002 +0000 - - Small updates. - -commit d4277e9ee8affa59ac9b3475245360bd14af1fa8 -Author: Guus Sliepen -Date: Wed Sep 4 16:36:03 2002 +0000 - - Updated dutch translation. - -commit 8b2b67e26c5b971761f5015764d5e188f6343bc4 -Author: Guus Sliepen -Date: Wed Sep 4 16:26:45 2002 +0000 - - Generalized request broadcasting/forwarding. - -commit 431fa10b37e78172a03c952e28a0364cc0e438f0 -Author: Guus Sliepen -Date: Wed Sep 4 14:17:28 2002 +0000 - - Small fixes. - -commit 82ebfc923ddb050c88bdf5d65ac943a15ca8748a -Author: Guus Sliepen -Date: Wed Sep 4 13:48:52 2002 +0000 - - Revert to edge and graph stuff. This time, use a directed graph. - -commit 973530db628fb91106d6fb7a17151e1d036e40a2 -Author: Guus Sliepen -Date: Wed Sep 4 08:48:03 2002 +0000 - - Just ignore wrong ADD_NODEs instead of replying with a DEL_NODE, in the - hope other DEL_NODEs will catch up eventually. - -commit 2af0bcc8fd39ca34a7ff856d539cdf38728a8c25 -Author: Guus Sliepen -Date: Wed Sep 4 08:36:34 2002 +0000 - - Don't forget to set prevhop to myself for new connections. - -commit 698d6ddac6ab32d5a4b802941b02232793442684 -Author: Guus Sliepen -Date: Wed Sep 4 08:33:08 2002 +0000 - - Prevent looping DEL_NODE/ADD_NODE messages after a node disconnects. - -commit 4a7c2026aec6966f934b60d75bc472d28f8587d8 -Author: Guus Sliepen -Date: Wed Sep 4 08:02:33 2002 +0000 - - Reduce KEY_CHANGED traffic. - -commit ddb96301a39dd3dac8d3df4e2e189b13b75e0b6e -Author: Guus Sliepen -Date: Tue Sep 3 22:49:55 2002 +0000 - - Woops. - -commit b5bb06200eda170c9836e1b4474d6f5b920c2151 -Author: Guus Sliepen -Date: Tue Sep 3 22:37:49 2002 +0000 - - A reachable node is always more preferable to an unreachable one... - -commit d134c4542d4e890e1c1007f32b866742319853c5 -Author: Guus Sliepen -Date: Tue Sep 3 20:43:26 2002 +0000 - - Drop graph and edge stuff. Use new node stuff instead. - -commit 856de4c5fe8acd779aa9277d4554e34ff3625e97 -Author: Guus Sliepen -Date: Tue Sep 3 20:42:05 2002 +0000 - - Make sure setlocale() is available. - -commit 2cb21f8810a6e0241a80623e991c8308b603ae95 -Author: Guus Sliepen -Date: Mon Sep 2 22:40:42 2002 +0000 - - Replacement for the current routing algorithm. - -commit f2c2443bbcfd5e09518bd87f3fd8d4a727d73ae2 -Author: Guus Sliepen -Date: Sat Aug 24 12:54:55 2002 +0000 - - Check for ranlib. - -commit 912e7e968f4888d62b3c620893a70e825599973b -Author: Guus Sliepen -Date: Sat Aug 24 12:11:40 2002 +0000 - - Gettext 1.11.5 compatibility. - -commit 18948c5784bfedf0dd5a371e41bc2cceee76d92e -Author: Guus Sliepen -Date: Thu Jul 18 14:30:45 2002 +0000 - - Added support for raw sockets. This can be used instead of tun/tap devices. - -commit 9f370893fafaeacdd78f5488cfa8b76fdee0d224 -Author: Guus Sliepen -Date: Tue Jul 16 13:18:27 2002 +0000 - - Don't bother to chown, and correctly document ConnectTo. - -commit 227ccd3a8a5602e4c31add8da1bfd8b35c6a801f -Author: Guus Sliepen -Date: Tue Jul 16 13:12:49 2002 +0000 - - Allow tincd to be locked into main memory. - -commit c4cd19935763b379e730a6fdf53dc1ca98d0b938 -Author: Guus Sliepen -Date: Fri Jul 12 11:45:21 2002 +0000 - - Include complete fake-getname/addrinfo from OpenSSH. - -commit afabbd6b9020dd6555a7ecd320a7b3e96119d538 -Author: Guus Sliepen -Date: Thu Jul 11 12:57:06 2002 +0000 - - Added stub device.c for Cygwin. - -commit 8949404db08f4ab594e60778bb76a9061426d7cc -Author: Guus Sliepen -Date: Thu Jul 11 12:55:58 2002 +0000 - - Started port to Cygwin. - -commit c98db1b861d62430e23f26b0da18e7b3ec875767 -Author: Guus Sliepen -Date: Thu Jul 11 12:42:43 2002 +0000 - - Clear subnets before using them. - -commit 8dd09568f1604f1ac8cc0d8d5120d986f5654900 -Author: Guus Sliepen -Date: Wed Jul 10 11:32:33 2002 +0000 - - Allow identical subnets from different owners. - -commit 36cbaa32f480b481bf2ee99fd4835586a02ebc60 -Author: Guus Sliepen -Date: Wed Jul 10 11:27:06 2002 +0000 - - Allow list of environment variables to be passed to execute_script(). - When executing host-up/down scripts, include the address and port of the - remote host. - -commit a1bd878e11ae7e66e7e9a4040c3b19f9b7bc50f4 -Author: Guus Sliepen -Date: Fri Jun 21 17:49:48 2002 +0000 - - Fix for prefixlengths of 32 (IPv4) and 128 (IPv6) bits. - -commit 627f7c22b447bd464b536cd016278545674df93d -Author: Guus Sliepen -Date: Fri Jun 21 10:11:37 2002 +0000 - - s/sliepen.warande.net/sliepen.eu.org/g - s/itimmermans@bigfoot.com/ivo@o2w.nl/g - -commit faabd163adf89bd0580cd40b8735ef8d9028a942 -Author: Guus Sliepen -Date: Fri Jun 14 11:51:29 2002 +0000 - - Update comments about IPv6 autoconfiguration. - -commit 940fcb6701d055f49530f12c93371f0280efce80 -Author: Guus Sliepen -Date: Thu Jun 13 16:12:40 2002 +0000 - - Reset listen_sockets after SIGHUP. - -commit 3a3adf5b690e9be1390a5df3caee6af64b25838f -Author: Guus Sliepen -Date: Wed Jun 12 13:45:23 2002 +0000 - - Add configuration details for NetBSD and Darwin (MacOS/X). - -commit 8988b127e18435054e48cbcca8ac712ddda3d6d2 -Author: Guus Sliepen -Date: Tue Jun 11 11:03:17 2002 +0000 - - Autoconf cleanup. Works for both 2.13 and 2.53, although running autoconf - 2.53 still gives some errors. - -commit de6835a9dd1891b6435c128cc6c2293950a4d7a7 -Author: Guus Sliepen -Date: Mon Jun 10 15:08:23 2002 +0000 - - Include darwin/device.c in distribution. - -commit 40ac473cb10f9c6a59739ce70032b746d8e0bf68 -Author: Guus Sliepen -Date: Mon Jun 10 14:35:18 2002 +0000 - - Use darwin/device.c when compiling on MacOS/X. - -commit 69b758879ee6d322e89143141b98d52167845c26 -Author: Guus Sliepen -Date: Mon Jun 10 14:33:40 2002 +0000 - - Added Darwin (MacOS/X) tun device handling. - -commit bd72e14138185f342885c0ed1c0f2c5dbf571132 -Author: Ivo Timmermans -Date: Sun Jun 9 16:23:12 2002 +0000 - - Added Alessandro Gatti - -commit 944df3eeee50972fcac84cfc8eefb36033bf04ad -Author: Ivo Timmermans -Date: Sun Jun 9 16:19:20 2002 +0000 - - Include netbsd's device.c in make dist - -commit 7608136a8dae24f2df30eac8644efd0d7cd57dc9 -Author: Ivo Timmermans -Date: Sun Jun 9 16:12:04 2002 +0000 - - Include a few more header files - -commit cd3601c5df57c7544ece00bf79e82b36499a26ff -Author: Ivo Timmermans -Date: Sun Jun 9 15:58:05 2002 +0000 - - Add /sw/{include,lib} to search paths if they exist - -commit 548551fd05f58863dfbbaaf147febfab0a22889b -Author: Ivo Timmermans -Date: Sun Jun 9 15:50:12 2002 +0000 - - getnameinfo fixes - -commit 9d769e0bf2ce266e8533e5e7c16bf07e44a9be34 -Author: Ivo Timmermans -Date: Sun Jun 9 15:26:10 2002 +0000 - - OSX support - -commit 78e88521845ae3bdd963ae5a414cb9c251963fa2 -Author: Guus Sliepen -Date: Sat Jun 8 14:08:57 2002 +0000 - - - netinet/* include files depend on netinet/in_systm.h. - - Squash bashism in configure.in. - -commit e47e51e9d17416e2b614287d14a5518881decd44 -Author: Guus Sliepen -Date: Sat Jun 8 13:46:43 2002 +0000 - - Use inttypes.h instead of stdint.h. - -commit 116ba3b3da73fb857cf75b5c92c6aacd70d94dd9 -Author: Guus Sliepen -Date: Sat Jun 8 12:57:10 2002 +0000 - - Cleanup: - - Remove checks for specific OS's, instead check for #defines/#includes. - - Use uint??_t where appropriate. - - Mask handling functions use void pointers to get rid of silly casts. - -commit d333fca4d611b85dd922ddf35bd9eddcb8095c85 -Author: Wessel Dankers -Date: Fri Jun 7 11:14:05 2002 +0000 - - This should work much better. - -commit 14e570f5eeff631c1312b11fcc5d22230ec27aff -Author: Guus Sliepen -Date: Wed Jun 5 00:25:55 2002 +0000 - - Use correct includes on NetBSD. - -commit 5886b6a10d0d2edf20ff53c4926ec4e41a36b8c0 -Author: Guus Sliepen -Date: Wed Jun 5 00:20:40 2002 +0000 - - Make it work correctly with NetBSD tun device. - -commit 4856d8e1f8398780a49545f35ba9b5746c9fc060 -Author: Guus Sliepen -Date: Sun Jun 2 16:06:33 2002 +0000 - - Support RSA_PUBKEYs (as opposed to RSAPublicKeys) so tinc accepts - public keys generated by the OpenSSL command line tools. - -commit efa5148bc76effb440d807d653dda02de050fde0 -Author: Ivo Timmermans -Date: Tue May 7 14:48:41 2002 +0000 - - Hm. - -commit 151ab8c9708534e012447688ed44d711d5b5fa2d -Author: Ivo Timmermans -Date: Thu May 2 13:23:58 2002 +0000 - - test 2 - -commit be04387a0c868b22ee4427822573df8b3b479bbe -Author: Ivo Timmermans -Date: Thu May 2 13:22:44 2002 +0000 - - test - -commit a9bb66367df82d062175f2b9b4bf236d77ae3ff1 -Author: Ivo Timmermans -Date: Thu May 2 13:11:55 2002 +0000 - - Moved event.c/h - -commit 474aab6325bf94724874cb74a9b56d9da739e1b8 -Author: Ivo Timmermans -Date: Thu May 2 11:52:28 2002 +0000 - - Callbacks - -commit 4c1a4e8a790584e4c7d5c0f2485706f4c01e1911 -Author: Ivo Timmermans -Date: Thu May 2 11:50:07 2002 +0000 - - Another file moved; random interface stuff. - -commit 2be8e69ca16e1558463c39c48af76d3d4a4674b7 -Author: Guus Sliepen -Date: Wed May 1 09:15:58 2002 +0000 - - Only purge once when there are no more connections. - -commit a77b35e748b7cf4cf7ac31750cefab7b2b0325f5 -Author: Ivo Timmermans -Date: Mon Apr 29 20:19:42 2002 +0000 - - Commit diff test - -commit 7caa253df4a34e594438e3fbe80c2bddab9a2b4a -Author: Guus Sliepen -Date: Mon Apr 29 20:05:07 2002 +0000 - - Fix very stupid bug in node_del(), which might have caused corruption of - subnets. - -commit 04d33be4bd102de67bb6dba5c449e12fea0db4d2 -Author: Ivo Timmermans -Date: Sun Apr 28 12:46:26 2002 +0000 - - Moving files, first attempt at gcrypt compatibility, more interface - abstraction - -commit b0a676988a8da3120e64ef0e1a4ea4c28b1511e1 -Author: Ivo Timmermans -Date: Sun Apr 28 12:43:40 2002 +0000 - - *** empty log message *** - -commit 67a6d7bcc4891c627663c639c0e02315bd4cf437 -Author: Guus Sliepen -Date: Sat Apr 27 11:40:45 2002 +0000 - - Informative log message if execl() failed. - -commit e6a67fc439fc3b46157647bed1af59b7519adb80 -Author: Ivo Timmermans -Date: Fri Apr 26 18:13:00 2002 +0000 - - Typo - -commit 01747d73a217f7ddf2107b086476702a9d04d683 -Author: Guus Sliepen -Date: Thu Apr 25 19:17:24 2002 +0000 - - Added Nick Patavalis for his RedHat package. - -commit b6ad4ce35a4434c209ee26015f15a18180987bac -Author: Guus Sliepen -Date: Tue Apr 23 07:49:38 2002 +0000 - - Add BindToAddress variable, similar to the late BindToIP. - -commit 40c2e36a96a3f5c34d4851b30f3561123f3906b5 -Author: Guus Sliepen -Date: Fri Apr 19 14:06:40 2002 +0000 - - Support for MaxOS/X. - -commit 97d492d9e23f43fe4c8a5ca8c95747088cf32f98 -Author: Ivo Timmermans -Date: Thu Apr 18 20:09:05 2002 +0000 - - Put #ifndef checks for HAVE_RAND_PSEUDO_BYTES in the correct places. - -commit fa8faff84bbbeb818adaea80d7bf9e12e0074978 -Author: Ivo Timmermans -Date: Sat Apr 13 18:01:58 2002 +0000 - - Print newline when writing to stderr - -commit fbebc5b65606119c01e9e1e3fcc7b2cc4cfd1daf -Author: Ivo Timmermans -Date: Sat Apr 13 11:24:25 2002 +0000 - - ... - -commit 7c75090025a4b06290663e0033a62414f3368f7c -Author: Ivo Timmermans -Date: Sat Apr 13 11:23:46 2002 +0000 - - Rename libvpn to libtinc - -commit 55385cacbfb0c743fc518e54854e24b7b05a623c -Author: Ivo Timmermans -Date: Sat Apr 13 11:23:19 2002 +0000 - - Renamed libvpn to libtinc - -commit 2389dcd573d909f21c8ec2d349b079075af6c7d3 -Author: Ivo Timmermans -Date: Sat Apr 13 11:21:58 2002 +0000 - - Include logging.h - -commit 246ce12c92ccc7badbb8c8c9a88fa03a7de9811f -Author: Ivo Timmermans -Date: Sat Apr 13 11:21:01 2002 +0000 - - Use new logging system - -commit a5b3ec41214ac8aea9b82734f92b5953e04a0c09 -Author: Ivo Timmermans -Date: Sat Apr 13 11:15:43 2002 +0000 - - Things to ignore... - -commit e239504524589a0f1549ca174f927afd07d563ba -Author: Ivo Timmermans -Date: Sat Apr 13 11:14:50 2002 +0000 - - Compile in logging.c - -commit e26dd564163fca001ab1694a51e7412f9ac970de -Author: Ivo Timmermans -Date: Sat Apr 13 11:08:31 2002 +0000 - - Use logging.h instead of syslog.h - -commit 72cd8938e2c759905666ea7d2c90dc1f0b2e2cd5 -Author: Ivo Timmermans -Date: Sat Apr 13 11:00:41 2002 +0000 - - Added prototype for log_syslog - -commit 48b80c93d30d5fae4273b0b496252bbc884abe53 -Author: Ivo Timmermans -Date: Sat Apr 13 10:55:42 2002 +0000 - - log_default_hook was renamed to log_default - -commit b63c3a1f0002675b6bedbd0b235e0ad0a708d4e3 -Author: Ivo Timmermans -Date: Sat Apr 13 10:50:48 2002 +0000 - - Added priority definitions from syslog.h - -commit 490b13edcfcae0422b6bd77fdb2a7f0181b14307 -Author: Ivo Timmermans -Date: Sat Apr 13 10:45:56 2002 +0000 - - Some magic - -commit 738389581b1ba29a181f639f3d20e3e24ff546f5 -Author: Ivo Timmermans -Date: Sat Apr 13 10:43:10 2002 +0000 - - Add syslog wrapper - -commit efa59f7cf4d416c8416866baeaa72cba7e936568 -Author: Ivo Timmermans -Date: Sat Apr 13 10:40:09 2002 +0000 - - Add syslog() wrapper - -commit 8822481d7b11db72d5400717d6b491b5f36bcb1f -Author: Ivo Timmermans -Date: Sat Apr 13 10:29:07 2002 +0000 - - Rename log_message to log - -commit cc603e2765f17555ecdc2b74c27ebf96e6691bf6 -Author: Ivo Timmermans -Date: Sat Apr 13 10:25:38 2002 +0000 - - New logging system to replace syslog() calls with a generic function. - -commit 131327a729216de8ae86da0c3c4d65d409741b7b -Author: Ivo Timmermans -Date: Sat Apr 13 10:04:46 2002 +0000 - - Remove debug_lvl - -commit e3c51b61caabc1a55772f7a52e75aab642c200ed -Author: Ivo Timmermans -Date: Sat Apr 13 10:02:48 2002 +0000 - - Update copyright info - -commit 9e8468f54aa5ecdb8b63c60449791427b59a474d -Author: Ivo Timmermans -Date: Sat Apr 13 10:02:16 2002 +0000 - - Remove debug level declaration - -commit 9f2c50e159caea1884c6a7aaa33f8098539ae0f5 -Author: Guus Sliepen -Date: Fri Apr 12 08:25:01 2002 +0000 - - Adding even more stuff from the CABAL branch. - -commit 191dcd5add0afba8b5d3aaa1e188c562c621712e -Author: Ivo Timmermans -Date: Thu Apr 11 20:18:02 2002 +0000 - - Also compile in pokey/ - -commit 39e93f473d34d6cdf6f4a7f0390a3b50cbd7b564 -Author: Ivo Timmermans -Date: Thu Apr 11 20:17:33 2002 +0000 - - Write src/pokey/Makefile - -commit c351b9e25b9f7b168a47fd8e6b60c66377e1824c -Author: Ivo Timmermans -Date: Thu Apr 11 14:27:35 2002 +0000 - - Pokey interface definition - -commit 17b308f0f0879c01f6864265af2e63595e965993 -Author: Ivo Timmermans -Date: Thu Apr 11 14:23:56 2002 +0000 - - Main pokey interface files. - -commit b5b38381c643632aa88c677236cace8c60e8344e -Author: Ivo Timmermans -Date: Tue Apr 9 16:11:48 2002 +0000 - - Last bits (hopefully) - -commit 77dd7b55801a3c7c2c6221664204ffdd7b83836a -Author: Ivo Timmermans -Date: Tue Apr 9 15:51:26 2002 +0000 - - More... - -commit 58c1df4028429ed6de4dad9455e3c92928450ffe -Author: Ivo Timmermans -Date: Tue Apr 9 15:48:54 2002 +0000 - - More updates - -commit 86dc60b9808d3aac70eccda80607a91ffd2e5292 -Author: Ivo Timmermans -Date: Tue Apr 9 15:32:14 2002 +0000 - - Ok, I forgot these ;) - -commit af23dfa5efb82b35eb00b94bda56390c9e2aac6f -Author: Ivo Timmermans -Date: Tue Apr 9 15:28:45 2002 +0000 - - Updating HEAD branch #5; Last files from CABAL. - -commit 462ab530e546f5732dfd51134751da6f6910d679 -Author: Ivo Timmermans -Date: Tue Apr 9 15:26:01 2002 +0000 - - Updating HEAD branch #4; Merging CABAL -> HEAD. - -commit e64ef59df44d39c76c00dee22841bbcce7c24e47 -Author: Ivo Timmermans -Date: Tue Apr 9 15:07:27 2002 +0000 - - Updating HEAD branch #3; more obsolete files removed. - -commit db59cbfa47aa152bcfa807754189aa18f28cb569 -Author: Ivo Timmermans -Date: Tue Apr 9 14:58:14 2002 +0000 - - Updating HEAD branch #2; removing debian/ dir. - -commit 50f2afec7e6dab3d809fc1b82820d1069205b69b -Author: Ivo Timmermans -Date: Tue Apr 9 14:54:37 2002 +0000 - - Updating HEAD branch #1; removing obsolete files. - -commit e69d2258032362c85c5936a5c137c70227e59332 -Author: Guus Sliepen -Date: Tue Apr 9 11:44:47 2002 +0000 - - Remarks about 1.0pre7 release. - -commit f2a3fcbdda250e5982c3ef36808568f996f8fff1 -Author: Guus Sliepen -Date: Tue Apr 9 11:43:45 2002 +0000 - - Updated dutch translation. - -commit b1322d244ff24e900f2298b8aa775d825c8ab00b -Author: Guus Sliepen -Date: Tue Apr 9 11:43:29 2002 +0000 - - masklength is better known as prefixlength - -commit 5df8a8cb3f4a0d2290f6677b44bbcaaf27a60bbc -Author: Guus Sliepen -Date: Tue Apr 9 11:42:48 2002 +0000 - - masklength is better known as prefixlength. - -commit 630dd023b990e076fdab890ff90783dc1ac7c13f -Author: Guus Sliepen -Date: Mon Apr 8 13:27:09 2002 +0000 - - Automake forgets about depcomp, remind it. - -commit ad6b1203490699ecc708290b2af1a45e134a5e20 -Author: Guus Sliepen -Date: Fri Apr 5 09:11:38 2002 +0000 - - Fix maskcheck() and maskcmp(). - -commit d8c249008a0b2abd44e652ed70e69b3dbc05b9d8 -Author: Guus Sliepen -Date: Mon Apr 1 21:28:39 2002 +0000 - - check_rsa() is broken, I don't know why, just remove it for now. - -commit 438419734ebee38dc3f7390e5c8ae8e6ca2cb6cf -Author: Guus Sliepen -Date: Mon Apr 1 21:28:05 2002 +0000 - - Don't check_network_activity() if select() is interrupted by a signal. - -commit 3d8a373bb3a788efffc555122b9d0569b96c5944 -Author: Guus Sliepen -Date: Wed Mar 27 19:43:50 2002 +0000 - - Make configure --help output look nicer. - -commit 9a03e7fa3d52ea062b4a3ff88b5d87ee95d24772 -Author: Guus Sliepen -Date: Wed Mar 27 16:26:26 2002 +0000 - - Update with information about the pre6 release. - -commit 33d3bad87d5f3e00e3ed81b75bca2ef21fd6e983 -Author: Guus Sliepen -Date: Wed Mar 27 16:00:49 2002 +0000 - - Update dutch translation. - -commit 0fe3dc38ed0527a5cfda9218114c8ee10422086b -Author: Guus Sliepen -Date: Wed Mar 27 16:00:38 2002 +0000 - - Fix format strings. - -commit 420f46acb0551a290b3263e39347b694286b2fa4 -Author: Guus Sliepen -Date: Wed Mar 27 15:47:06 2002 +0000 - - Remove symlink to device.c when doing a make dist. - -commit a5d8be8b1a9978d58c251d1020bb730bb1dc8ea1 -Author: Guus Sliepen -Date: Wed Mar 27 15:35:07 2002 +0000 - - Recent automake uses $(AMTAR) instead of $(TAR) - -commit c6d2f6c620beae387e8f9fc995ed7c8e8a5bc3dc -Author: Guus Sliepen -Date: Wed Mar 27 15:26:44 2002 +0000 - - Remove cruft. - -commit efd29fde85481e080a676f2ba780a528a90a9925 -Author: Guus Sliepen -Date: Wed Mar 27 15:26:29 2002 +0000 - - Small updates. - -commit 5eba1e1f6feadb3f7efb1261bd65e1e9e40b7f2b -Author: Guus Sliepen -Date: Wed Mar 27 15:01:37 2002 +0000 - - Limit the amount of packets in a queue to 8. - -commit 61cb593e670107ca3041f582c5486c243d5eda9e -Author: Guus Sliepen -Date: Wed Mar 27 15:01:16 2002 +0000 - - Extend list_t with the number of elements in the list. - -commit 0e7136027ce05bfeca977f2f64f3b228ea4fda87 -Author: Guus Sliepen -Date: Wed Mar 27 14:02:36 2002 +0000 - - Merge do_prune() with build_fdset(). Probably fixes the invalid filedescriptor error. - -commit e2238047d39eacc69da5732937021c38171ec7b9 -Author: Guus Sliepen -Date: Tue Mar 26 13:19:56 2002 +0000 - - Small correction. - -commit 7d07df71f9b82afdcf23494867bb8899198a6223 -Author: Guus Sliepen -Date: Tue Mar 26 12:00:38 2002 +0000 - - Fix execute_script(). - -commit 2de5e0eef911b9ff723d562ef9c62d833f3cdc45 -Author: Guus Sliepen -Date: Mon Mar 25 15:51:58 2002 +0000 - - Send REQ_KEY only once until ANS_KEY has arrived. - -commit a0c1696515fabd2183da7d8d83fd68410d2ec834 -Author: Guus Sliepen -Date: Mon Mar 25 15:12:09 2002 +0000 - - Tell a little bit more about security. - -commit 89a2f761a6d8ae4912c2dd2e9178589001487ef5 -Author: Guus Sliepen -Date: Mon Mar 25 15:01:32 2002 +0000 - - Updated documentation. - -commit 33d8747021d57c5827c6a755739756f95c7527c8 -Author: Guus Sliepen -Date: Mon Mar 25 13:54:49 2002 +0000 - - Set myself->status.reachable. - -commit 2749b997df33749f13d05e294db0e1e327e81d12 -Author: Guus Sliepen -Date: Sun Mar 24 17:14:01 2002 +0000 - - Configuration variables were still handled case sensitively. - -commit c73bdd6bc8e213b7e27848b97307228c01570a1d -Author: Guus Sliepen -Date: Sun Mar 24 17:08:38 2002 +0000 - - OpenBSD tun device uses address family number instead of Ethernet type. - -commit 8379c14b7f7a9b1400dd3776fc21dc9ccddd991d -Author: Guus Sliepen -Date: Sun Mar 24 16:50:58 2002 +0000 - - Respect type field. - -commit ad4f5cbc5fbce23893b7d42669ba907f18cc8ff4 -Author: Guus Sliepen -Date: Sun Mar 24 16:40:14 2002 +0000 - - Updated dutch translation. - -commit 4252ae83a43ea81382ce71ba614e2d1655f2e189 -Author: Guus Sliepen -Date: Sun Mar 24 16:36:56 2002 +0000 - - Set $INTERFACE correctly when using ethertap while compiled with tun/tap support. - -commit d699f3079c658e05f928c358d110d1d27849ea71 -Author: Guus Sliepen -Date: Sun Mar 24 16:28:27 2002 +0000 - - Execute hosts/name-up when a node becomes reachable, and hosts/name-down - when it becomes unreachable. - -commit 6ad5dd1a9adb1c1322ceb44d6f0fd160229e72ff -Author: Guus Sliepen -Date: Sun Mar 24 16:22:59 2002 +0000 - - Don't try to execute scripts unless they exist. - -commit 594d5b5d15551bd802c43926c7cb8863b7531654 -Author: Guus Sliepen -Date: Sat Mar 23 20:21:10 2002 +0000 - - Reset retry timeout when receiving the first PONG, not right after receiving the ACK. - -commit cbd8133ab4a2ea8a0c46224a5f1ae79e92819e5f -Author: Guus Sliepen -Date: Sat Mar 23 20:13:56 2002 +0000 - - Don't run graph algorithms if no edge is deleted in terminate_connection(). - -commit 6aee1ad021092d37538e15da22367789a4d4a763 -Author: Guus Sliepen -Date: Sat Mar 23 20:12:29 2002 +0000 - - free() request strings when deleting past requests from the tree. - -commit ccea26e0044ea59a9722385c9d69b1bc703e884f -Author: Guus Sliepen -Date: Sat Mar 23 20:01:05 2002 +0000 - - send_ack() was broken. - -commit 3c5655f59e85d312d11fa04489123e604920f95b -Author: Guus Sliepen -Date: Fri Mar 22 13:31:18 2002 +0000 - - Fix compiler warnings, strictly use long int and %lx for options. - -commit d6b70ed6f8b7ed65f64193fcfcdb6c8f4625e03c -Author: Guus Sliepen -Date: Fri Mar 22 12:41:54 2002 +0000 - - Fix add_edge_h(). - -commit 52e7699273a3009fe4d91e608522401076922785 -Author: Guus Sliepen -Date: Fri Mar 22 11:43:48 2002 +0000 - - - Added support for jumbograms. - - Remove tcpaddress from edges, it is not used at all. - - Last bits of code to prevent looping requests. - -commit 9da5390666ad532825d820b3554da3f39d3bc511 -Author: Guus Sliepen -Date: Thu Mar 21 23:11:53 2002 +0000 - - Put a break on requests that run around in circles. - -commit f48f8f4fedba365ceea30e1133bf1c560e9a522a -Author: Guus Sliepen -Date: Tue Mar 19 22:48:25 2002 +0000 - - Updated SSSP algorithm to automatically detect indirect links (if a node uses - different addresses for connections to other nodes). - -commit 5a88a27742d305be48498a297b90ee3fbdd935bf -Author: Guus Sliepen -Date: Tue Mar 19 00:08:34 2002 +0000 - - Updated dutch translation. - -commit 5c2d74de86d1acb3774a20357ad815d000f8a7f6 -Author: Guus Sliepen -Date: Tue Mar 19 00:08:23 2002 +0000 - - Don't use s6_addr[16|32] anymore. - -commit 9d99a789c38e8a1694537e427e8d4313c948b02b -Author: Guus Sliepen -Date: Tue Mar 19 00:07:09 2002 +0000 - - Cleanup. - -commit 305505f5ec4bb738f175cd897fa409f08d2971a3 -Author: Guus Sliepen -Date: Mon Mar 18 22:47:20 2002 +0000 - - Remember sockaddrs of listening sockets, use appropriate one when sending - UDP packets. - -commit 106fc2b769a635142bf5f9233a2f03e3a0f26b7f -Author: Guus Sliepen -Date: Mon Mar 18 14:39:37 2002 +0000 - - Fix #define s6_addr32. - -commit 813c369a8faca94fc38bc66afafad063fa00f928 -Author: Guus Sliepen -Date: Mon Mar 18 14:19:02 2002 +0000 - - #define s6_addr32, needed for FreeBSD. - -commit b2579385de427c3c03d28520d3a93bd5f9bc9488 -Author: Guus Sliepen -Date: Sun Mar 17 16:08:39 2002 +0000 - - Only unmap IPv6 addresses. - -commit 8b84c44175fedb81ca38107e0067ddea750add00 -Author: Guus Sliepen -Date: Sun Mar 17 15:59:29 2002 +0000 - - Unmap v4mapped sockaddrs. - -commit 07e37f8da03fa315be39623e62d8acba617aa226 -Author: Guus Sliepen -Date: Fri Mar 15 15:50:14 2002 +0000 - - Typo. - -commit e0dee537705cdbd005f6ab1fbef5ac71dc8411c0 -Author: Guus Sliepen -Date: Fri Mar 15 15:40:40 2002 +0000 - - Different way of detecting neighbor solicitation requests. - -commit 0e93f0aa02274481c16fc9f30b795d4f063bd1c3 -Author: Guus Sliepen -Date: Fri Mar 15 15:08:21 2002 +0000 - - Oops, don't forget to actually put the checksum in the response packet. - -commit e1de9ca990ea638c7e297c5335be415e44c250c1 -Author: Guus Sliepen -Date: Fri Mar 15 14:41:57 2002 +0000 - - Neighbor solicitation requests now work (I think). - -commit 4b3aef9e6992ca78f1b17b179a3051d3fec0473d -Author: Guus Sliepen -Date: Tue Mar 12 16:30:15 2002 +0000 - - Revert changes to Kruskal's algo. - -commit f219f156cf13fd30369d7cd4632c406ffd6ff628 -Author: Guus Sliepen -Date: Tue Mar 12 14:25:04 2002 +0000 - - Put #ifdef NEIGHBORSOL around corresponding code. - -commit ecad9e9289162faec7b678be54178d22876b5d90 -Author: Guus Sliepen -Date: Tue Mar 12 14:20:44 2002 +0000 - - Remove silly cache thingy. - -commit d6c2c4f2b7a94ef6a4db0de134d015bc8d21ffb1 -Author: Guus Sliepen -Date: Tue Mar 12 14:19:51 2002 +0000 - - Packet sequence number/authentication warnings only if debug_lvl >= 5. - -commit 2e7db2a6936a77baa0a81eb566674bd76d204951 -Author: Guus Sliepen -Date: Tue Mar 12 13:42:23 2002 +0000 - - Simplified implementation of Kruskal's minimum spanning tree algorithm. - -commit d2e0ed533c8aa3c6ab538d87e004108c631cb0be -Author: Guus Sliepen -Date: Mon Mar 11 13:56:00 2002 +0000 - - New strategy: forward icmp6 neighbor solicitations to intended target. - -commit 46fa10cec7b6bf26773f5e86e7b8118d9075e807 -Author: Guus Sliepen -Date: Mon Mar 11 13:14:53 2002 +0000 - - Try to reply to neighbor solicitation requests. - -commit c2713ba7a5ff12e270d66a5d3188a3640873830e -Author: Guus Sliepen -Date: Mon Mar 11 11:45:12 2002 +0000 - - prune_connections() before build_fdset(). - -commit 4fda4560bbdd41e217ce0e1a90ba98c79e4f3519 -Author: Guus Sliepen -Date: Mon Mar 11 11:23:04 2002 +0000 - - Cleanups, spelling fixes, allow symbol names for signals (-k option), - don't remove pidfile if other tincd is still running. - -commit 5ffeb13d65313d5a191a605690a4f8fdf1604b48 -Author: Guus Sliepen -Date: Sun Mar 10 16:09:15 2002 +0000 - - Don't retry to make outgoing connections when exitting. - -commit 3cbe67a8de1da7bd042474de4d16cb4f7e9822ab -Author: Guus Sliepen -Date: Sun Mar 10 15:40:27 2002 +0000 - - Small fixes to improve portability. - -commit 9de7470bfdabacec5f3769bf5cfa97ef4e481ba0 -Author: Guus Sliepen -Date: Sun Mar 10 14:07:08 2002 +0000 - - Autodetect $MAKE/gmake/make. - -commit 0c34478cc03167208c84f3d6d2ed6e53172b4711 -Author: Guus Sliepen -Date: Sun Mar 10 14:05:35 2002 +0000 - - po/POTFILES and po/Makefile should not be generated by configure. - -commit 024ab44d98883d78cefe2c622cec9831c7f19c13 -Author: Guus Sliepen -Date: Sun Mar 10 14:04:48 2002 +0000 - - Fix forwarding of IPv6 packets. - -commit 0c16add71c6432c882c6d8f538a4b2db0026ec24 -Author: Guus Sliepen -Date: Fri Mar 1 15:14:29 2002 +0000 - - Check if BindToDevice and PriorityInheritance are supported. - -commit 7d5741859e681e6b0d0e32b978da6f309c456729 -Author: Guus Sliepen -Date: Fri Mar 1 14:33:48 2002 +0000 - - Woops. - -commit ab90fa9bd1a653a330be7ef11293000721a0e7b4 -Author: Guus Sliepen -Date: Fri Mar 1 14:25:10 2002 +0000 - - Document and clean up MAC address expiry. - -commit 14979f835df4214a7c2510852f7ffedc9e08c2c0 -Author: Guus Sliepen -Date: Fri Mar 1 14:09:31 2002 +0000 - - - Global time_t now, so that we don't have to call time() too often. - - MAC addresses expire after a time configurable by MACExpire (default 600 - seconds) - -commit 7496ecc45ab6205bcce4e576c23b9afb52004e39 -Author: Guus Sliepen -Date: Fri Mar 1 13:38:15 2002 +0000 - - Updated dutch translation. - -commit 0c879b8eeed3477b0f1cdd2f232e67e38bd9bce6 -Author: Guus Sliepen -Date: Fri Mar 1 13:38:02 2002 +0000 - - Updated documentation. - -commit f93b1334e087dd7af1b87f475b2d398fdd4d56ab -Author: Guus Sliepen -Date: Fri Mar 1 13:18:54 2002 +0000 - - Create/bind TCP and UDP listening sockets in pairs. - -commit c2b738e7b51fbec2b11fbbf030b9a5a36df55fc4 -Author: Guus Sliepen -Date: Fri Mar 1 12:26:56 2002 +0000 - - If "PriorityInheritance = yes" is specified in tinc.conf, the value of the - TOS field of the tunneled packets will be passed on to the UDP packets tinc - sends out. - -commit 80ea653e8d8050878380fbc1446571cbaf578297 -Author: Guus Sliepen -Date: Fri Mar 1 12:25:58 2002 +0000 - - Fix listening sockets. - -commit 7f58ed7685f9fcd5271359a8c896670a835e1f95 -Author: Guus Sliepen -Date: Fri Mar 1 11:18:34 2002 +0000 - - Make BindToInterface work. - -commit 17bc5220c332fdd083fd47fc600010f85171adc7 -Author: Guus Sliepen -Date: Wed Feb 27 22:37:55 2002 +0000 - - Fix send_request() bug. - -commit 50403909b6bf6536924d4693bb1f32c248f17fda -Author: Guus Sliepen -Date: Tue Feb 26 23:26:41 2002 +0000 - - Allow multiple listening sockets. - -commit 2ac7be0d51a112108dc6c2b1c6f46da022f72f40 -Author: Guus Sliepen -Date: Tue Feb 26 22:47:51 2002 +0000 - - Tweaking IPv6 support. - -commit 23fda5688e8a109f8a50511538b14e4fbe4f738c -Author: Guus Sliepen -Date: Wed Feb 20 22:37:38 2002 +0000 - - - Change SA_LEN to SALEN, former one is already defined on some platforms. - - Use SALEN everywhere appropriate. - -commit dbc5b5bb5eb3096ad930aa6b590deaba2a103dfc -Author: Guus Sliepen -Date: Wed Feb 20 22:15:32 2002 +0000 - - - Use gai_strerror() where appropriate - - Clear hints before using them with getaddrinfo() - - Use sa_len on platforms that support them - -commit 28cc9a6488f78c72152251f6fa2ee84d417223e8 -Author: Guus Sliepen -Date: Wed Feb 20 19:31:15 2002 +0000 - - Preserve inpkt->len, needed for broadcasts. - -commit c6d01588312bec7691e72b42cf20c59ffe2749c2 -Author: Guus Sliepen -Date: Wed Feb 20 19:25:09 2002 +0000 - - Protocol now also exchanges cipher/digest/maclength/compression for the - meta connection. - -commit 626d5956d2bb0660ba315fba77da6cec9776fd3b -Author: Guus Sliepen -Date: Wed Feb 20 17:16:15 2002 +0000 - - Cache results of lookup_subnet_...(). - -commit e8e69460a7090aaf6ecda8970d3060695de81b00 -Author: Guus Sliepen -Date: Wed Feb 20 17:15:33 2002 +0000 - - Fix maskcmp() and maskcpy(). - -commit ed509312906625acee4007da6262de3898846888 -Author: Guus Sliepen -Date: Wed Feb 20 16:04:59 2002 +0000 - - Forward packets in router mode. - -commit 8c91fac31570594b6249d632cefe768f33c54b19 -Author: Guus Sliepen -Date: Wed Feb 20 16:04:39 2002 +0000 - - Use AF_UNSPEC for listening sockets if AddressFamily = any. - -commit 76f01453dfa157b0070751b1025e55a1e36ebdca -Author: Guus Sliepen -Date: Wed Feb 20 16:04:07 2002 +0000 - - Fix segfault when receiving HUP signal. - -commit c2b9c06062d36bde859b630b99a08c7b7428e721 -Author: Guus Sliepen -Date: Mon Feb 18 16:25:19 2002 +0000 - - - Non-blocking connect()s. - - Socket handling revamped to use sockaddr_t. - - tinc can now tunnel over IPv6. - - Handle all addresses and subnets in network byte order. - Only convert them when they need to be printed. - - IPv6 subnets bigger than /128 now work. - - Use %s and strerror(errno) instead of %m. - -commit fc674eaae14ed2e07abc0df1285b1bd70e0d27cc -Author: Guus Sliepen -Date: Tue Feb 12 14:42:37 2002 +0000 - - Add check for NetBSD. - -commit 2fb8a62edef7cb0988e44f92c3948cde6f34875e -Author: Guus Sliepen -Date: Tue Feb 12 14:40:12 2002 +0000 - - Added device.c for NetBSD, actually a copy of the OpenBSD one. - -commit f64b41a73b3b432aae17ba990414e0be2f61ce62 -Author: Guus Sliepen -Date: Tue Feb 12 14:36:45 2002 +0000 - - Get rid of sys/signal.h. - -commit dd611fb4f91b9b17c20c458694d2765b22814c5f -Author: Guus Sliepen -Date: Tue Feb 12 14:29:00 2002 +0000 - - Don't use sa_sigaction (which NetBSD doesn't like) at all if we don't use siginfo. - -commit d9a62c6354d1e2ad78ee8c610518ae9f9ab012d1 -Author: Guus Sliepen -Date: Mon Feb 11 15:59:18 2002 +0000 - - Added support for packet compression, thanks to Mark Glines. - Add "Compression = " to the host config files, where level can be - 0 (off), or any integer between 1 (fast) and 9 (best). - -commit 94b171b3051b999e619ae19e1c9c29d356606788 -Author: Guus Sliepen -Date: Mon Feb 11 14:20:46 2002 +0000 - - Small fix. - -commit 1708997bc8ab55122f9de9cc8b81397d3a003ea9 -Author: Guus Sliepen -Date: Mon Feb 11 14:20:21 2002 +0000 - - - If no PrivateKeyFile is specified, /etc/tinc/netname/rsa_key.priv is assumed. - - Check RSA key before using it. - -commit 1c34ba7fb8580949f3bd3a0d804747bbaea28e36 -Author: Guus Sliepen -Date: Mon Feb 11 12:33:01 2002 +0000 - - Sensible defaults for $INTERFACE. - -commit 24cc2a9065a4e962fb05addac47322930099a4b5 -Author: Guus Sliepen -Date: Mon Feb 11 10:16:18 2002 +0000 - - Last bits of the merger. - -commit 5bf4b88666ecafe190e8ed71d6c14c9de8d16e1f -Author: Guus Sliepen -Date: Mon Feb 11 10:05:58 2002 +0000 - - Forgot to merge new files from pre5. - -commit f0aa9641e82fb6e09c1e485366d14dddaa7f7c36 -Author: Guus Sliepen -Date: Sun Feb 10 21:57:54 2002 +0000 - - Merging of the entire pre5 branch. - -commit c2752b961c9262386b940c2c053b9909bee22859 -Author: Ivo Timmermans -Date: Fri Nov 16 22:41:38 2001 +0000 - - Conversion to struct addrinfo is almost complete for this file. - -commit 4f47da5b87ef7da608c7e44026122f3d95deb2eb -Author: Ivo Timmermans -Date: Fri Nov 16 22:40:26 2001 +0000 - - Don't include netutl.h. - -commit a59bbc72317c9cd97243a9cbf49db01ff249eb1e -Author: Ivo Timmermans -Date: Fri Nov 16 22:31:41 2001 +0000 - - Fixed silly typo: "np" instead of "no" - -commit bf664c054fdabc30679367a752a27bb769655e4d -Author: Ivo Timmermans -Date: Fri Nov 16 22:31:15 2001 +0000 - - get_config_subnet needs to be fixed. - -commit 9b2b3747340173590b8f6f5fbdd060b42985f026 -Author: Ivo Timmermans -Date: Fri Nov 16 17:40:50 2001 +0000 - - route_ipv4 and route_ipv6 replaced by route_ip. - -commit a4938b22e7502579ce44cac42410111db11256eb -Author: Ivo Timmermans -Date: Fri Nov 16 17:39:59 2001 +0000 - - Don't include netutl.h. - -commit ccda709f8243949a3c0ffcc6133d8d8fc5125f2e -Author: Ivo Timmermans -Date: Fri Nov 16 17:39:38 2001 +0000 - - lookup_node_udp changed. - -commit 836766d4c5bc47682ab69c57337157c879517670 -Author: Ivo Timmermans -Date: Fri Nov 16 17:38:39 2001 +0000 - - First part of rewriting things to use struct addrinfo. - -commit 2ec5b5f8621d9fb91181ab155084daa1bb2d1a54 -Author: Ivo Timmermans -Date: Fri Nov 16 17:37:08 2001 +0000 - - Added dropin replacements for get*info and helper functions. - -commit aabe59f6305cdd46220e95d8927a1636d4b4819d -Author: Ivo Timmermans -Date: Fri Nov 16 16:16:33 2001 +0000 - - Added HAVE_STRUCT_ADDRINFO - -commit 251f87c842b62cf770129d8a953fb06ef5d0e466 -Author: Ivo Timmermans -Date: Fri Nov 16 15:56:44 2001 +0000 - - (re)added port to struct node_t - -commit 6cf744e4b29cfe3b135b6553851816802ba3d8a8 -Author: Ivo Timmermans -Date: Fri Nov 16 12:22:02 2001 +0000 - - Don't include netutl.h. - -commit a79252af4383b8cd71cf0d13f1ae040d518517bf -Author: Ivo Timmermans -Date: Fri Nov 16 12:21:22 2001 +0000 - - Obsoleted. - -commit 331d9402e892b4baa9cadbbb364073ae10b58d99 -Author: Ivo Timmermans -Date: Fri Nov 16 12:16:28 2001 +0000 - - Don't compile/link netutl.c. - -commit f95e6ca8f6976d7a15f4623e25c85e1c7f82c04b -Author: Ivo Timmermans -Date: Fri Nov 16 12:14:20 2001 +0000 - - get_config_{ip,port} removed. - -commit 31db57bb4a00f5ca3743b89f8bb2fbd39919bf28 -Author: Ivo Timmermans -Date: Fri Nov 16 12:13:34 2001 +0000 - - Changed to use struct addrinfo where needed. - -commit f1b20b3ded5b360e426e094cf79df3bf97f350b4 -Author: Ivo Timmermans -Date: Fri Nov 16 12:10:54 2001 +0000 - - Obsoleted all IP types in favor of struct addrinfo - -commit fb6dc0b0890ebae2471e00e7a3e1d86c1fc3d646 -Author: Ivo Timmermans -Date: Fri Nov 16 12:08:38 2001 +0000 - - Removed definitions of ipv4_t, ipv6_t, port_t - -commit 3ef15f2554d1819d6c7d2573dac6039f2e76b638 -Author: Ivo Timmermans -Date: Fri Nov 16 12:02:17 2001 +0000 - - Changed lookup_connection to use struct addrinfo - -commit 74e1299fb58025f7506c7e2608c353a76f98d8df -Author: Ivo Timmermans -Date: Fri Nov 16 12:01:48 2001 +0000 - - Changed prototype for lookup_connection to use struct addrinfo - -commit 51b72b75f254c956b62be9dfca642145b199415f -Author: Ivo Timmermans -Date: Fri Nov 16 00:23:28 2001 +0000 - - Use struct addrinfo in connection_t to hold all host data such as IP - address and port - -commit 72395f989cb44132d7c756c91b3a6d8ba63517e5 -Author: Ivo Timmermans -Date: Fri Nov 16 00:13:08 2001 +0000 - - Deprecated get_config_ip and get_config_port - -commit 93cd0e33defba46f8e51d9a98a94599ceb0d521c -Author: Ivo Timmermans -Date: Thu Nov 15 23:49:46 2001 +0000 - - Check for struct addrinfo - -commit b16bf68a6dc27b364cb76156a7be0208594f1e94 -Author: Ivo Timmermans -Date: Thu Nov 15 23:28:58 2001 +0000 - - Credit OpenSSH - -commit 18269cfbe831902b97a6171ba0346fd323583e48 -Author: Ivo Timmermans -Date: Thu Nov 15 23:26:27 2001 +0000 - - Check for getnameinfo, gai_strerror, freeaddrinfo - -commit ae11e7c3d71893c5200b12682839538a52df37b8 -Author: Ivo Timmermans -Date: Thu Nov 15 23:05:34 2001 +0000 - - Check for getaddrinfo - -commit e06415e3d9d08cd33c5983a2c49c4101377160c2 -Author: Guus Sliepen -Date: Mon Nov 5 19:09:08 2001 +0000 - - More fixes for Solaris. - -commit 25a804c94ef0dbc4e5582ea6d8459d5f9a3fe06c -Author: Guus Sliepen -Date: Mon Nov 5 19:06:07 2001 +0000 - - Various fixes needed for Solaris. - -commit b2d5002ff1ccd44fbf3a94e4c41909ab6141f3bb -Author: Guus Sliepen -Date: Sun Nov 4 23:48:27 2001 +0000 - - Correctly check if subnet owner exists. - -commit ede6671c1354eeab86936efda32f6cdb3b3fd8d5 -Author: Guus Sliepen -Date: Sun Nov 4 23:29:50 2001 +0000 - - Be liberal in what you accept: allow unknown edges to be deleted. - -commit cf0e133e191cb40954bf5b6ee0a579442fe4b60b -Author: Guus Sliepen -Date: Sat Nov 3 22:53:02 2001 +0000 - - *** empty log message *** - -commit e5047d2835f0828a9c334cc3d928c2322abfefb7 -Author: Guus Sliepen -Date: Sat Nov 3 21:22:02 2001 +0000 - - Several bugfixes. - -commit 8910cbd67e13450e93816ecafa0cc5be5e4c2378 -Author: Guus Sliepen -Date: Sat Nov 3 21:21:04 2001 +0000 - - Use PEM functions as suggested by OpenSSL docs. - -commit 8e74c5bee48f2ef363193044d5309a65e91c70d8 -Author: Guus Sliepen -Date: Wed Oct 31 20:37:54 2001 +0000 - - Some very small fixes - -commit ffb88ff6410f33de92db108bd1e0c3a915368214 -Author: Guus Sliepen -Date: Wed Oct 31 20:22:52 2001 +0000 - - Avoid connecting to another node twice, and check name of outgoing connections. - -commit 6d333ad680465c26953ad4c8ca9140e27da868c5 -Author: Guus Sliepen -Date: Wed Oct 31 20:07:17 2001 +0000 - - Show cfg->variable instead of cfg->value when complaining about wrong type. - -commit 54b756f7dfb71c5622b7738fd449e126da959864 -Author: Guus Sliepen -Date: Wed Oct 31 20:02:06 2001 +0000 - - Don't forget to read public RSA key when making an outgoing connection. - -commit c0a3f67a5d66088aaf526f1461986f9e86d5dd1f -Author: Guus Sliepen -Date: Wed Oct 31 12:50:24 2001 +0000 - - - Small fixes to graph algorithms - - More control over tap device, ability to set interface name to something - other than the netname. - - Export NETNAME, DEVICE and INTERFACE environment variables to scripts. - -commit 2165931c62f0433fd97bd3ac6aefea3627218946 -Author: Guus Sliepen -Date: Tue Oct 30 16:34:32 2001 +0000 - - More updates to protocol handlers and reimplemented terminate_connection(). - -commit 87ad5c97a9a73a65050ad7adce34503f856d8665 -Author: Guus Sliepen -Date: Tue Oct 30 12:59:12 2001 +0000 - - Various fixes, tinc is now somewhat capable of actually working again. - -commit cc9473d8c6467e9eaa82fe8a639d8edba232ee76 -Author: Guus Sliepen -Date: Mon Oct 29 13:14:57 2001 +0000 - - Working version of Kruskal's algorithm. The running time is very bad though. - -commit b6298e2c082035b8238ea08673ced15d0fb7b89a -Author: Guus Sliepen -Date: Sun Oct 28 22:42:49 2001 +0000 - - - More changes needed for Kruskal's algorithm - - Implemented a breadth-first search algorithm as a cheap substitution for a - single-source shortest path algorithm. - -commit 66067cc9c1347fb2de35660d531fdd4be8aede6a -Author: Guus Sliepen -Date: Sun Oct 28 10:16:18 2001 +0000 - - - More s/vertex/edge/g - - Implementation of Kruskal's minimum spanning tree algorithm. - -commit 94497336efc1cc60561575e74d420e9e8e8c657e -Author: Guus Sliepen -Date: Sun Oct 28 08:41:19 2001 +0000 - - What was I thinking? s/vertex/edge/g. - -commit b98d9787fdde54f33dcdb376e1e018cd418aff8d -Author: Guus Sliepen -Date: Sat Oct 27 15:19:13 2001 +0000 - - Various small fixes to make tinc runnable again. - -commit ac066bb057dcb187bf91670793ba5e6ca456e052 -Author: Guus Sliepen -Date: Sat Oct 27 13:13:35 2001 +0000 - - Make sure everything links. - -commit 82e383710980534d38bb9a8ef22f20677cd85861 -Author: Guus Sliepen -Date: Sat Oct 27 12:13:17 2001 +0000 - - Big bad commit: - - Transition to new node/vertex/connection structures - - Use new configuration handling everywhere - - Linux tun/tap device handling cleanup - - Start of IPv6 support in route.c - - It compiles, but it won't link. - -commit 1935c44a1e8ab7c31c836f90215e3c5b5f8dd776 -Author: Guus Sliepen -Date: Sat Oct 13 13:53:07 2001 +0000 - - Support new files (node/vertex/device.[ch]) and OpenBSD. - -commit 26e517dd37e995fe9db518f7ebeff023fc73ff1b -Author: Guus Sliepen -Date: Fri Oct 12 15:52:03 2001 +0000 - - Forgot the tun specific stuff. - -commit ad61c20f42d2bee5cc7976bec4370cf4747b42c3 -Author: Guus Sliepen -Date: Fri Oct 12 15:49:11 2001 +0000 - - Added OpenBSD tun device handling. Untested though. - -commit 0c6321a67f92981d3adbaf4f5c2b9867c7968964 -Author: Guus Sliepen -Date: Fri Oct 12 15:38:35 2001 +0000 - - Forgot to remove some old #ifdef stuff. - -commit 6014c7e6374089bfccea7467c2c7f4b23fefa265 -Author: Guus Sliepen -Date: Fri Oct 12 15:33:21 2001 +0000 - - Solaris tun device handling cleaned up a bit and added. - -commit 623c7ee0308aede8eada552d6ae33710ae24d176 -Author: Guus Sliepen -Date: Fri Oct 12 15:22:59 2001 +0000 - - Added FreeBSD tap device handling. - -commit ec34f25228d7a0007ce6bcb1e97f263868e9129d -Author: Guus Sliepen -Date: Fri Oct 12 15:16:03 2001 +0000 - - - Split tap device stuff out of net.[ch] - - Each OS gets it's own device.c to get rid of evil #ifdefs. - - Cleaned up Linux ethertap and tun/tap handling. - -commit 0bbace18e96cd6fc32dfa23ffd55f73ff96e8c6f -Author: Guus Sliepen -Date: Wed Oct 10 20:35:10 2001 +0000 - - More updates to new node/vertex/connection combo. - -commit ea607d2d9292d3969f9d164b432dc64a33c2dade -Author: Guus Sliepen -Date: Wed Oct 10 20:34:27 2001 +0000 - - Revamp configuration handling: - - Store everything in AVL trees (fast lookup) - - No need for hazahaza anymore - - Parse values when needed - - This simplifies a lot of config variable lookups. - -commit 5904806dc80830d4eddca857a41db2fc25598201 -Author: Guus Sliepen -Date: Wed Oct 10 09:42:29 2001 +0000 - - Removed everything from connection.c that has already been moved to node.c and - vertex.c. - -commit ec0c16b9b63f361b11a757ee1641d562e4811f93 -Author: Guus Sliepen -Date: Wed Oct 10 08:49:47 2001 +0000 - - Further implementation of doc/CONNECTIVITY. connection.[ch] is now split into a - node, vertex and connection part. - -commit 75e1ae3a287642ca4281792c94ecd07332f39c08 -Author: Wessel Dankers -Date: Tue Oct 9 19:41:56 2001 +0000 - - make is not always GNU make. - -commit f22b9417510cca258785f8958c8dfed90e26d81b -Author: Guus Sliepen -Date: Tue Oct 9 19:37:10 2001 +0000 - - Small corrections. - -commit 49a2cd806c73cff1ab6a712a996c7f7d4e1f32c0 -Author: Guus Sliepen -Date: Tue Oct 9 19:30:30 2001 +0000 - - Started implementing doc/CONNECTIVITY. - -commit 5926c82b9a29031a8c619432869d1549b51b62a0 -Author: Guus Sliepen -Date: Mon Oct 8 15:47:30 2001 +0000 - - Updated dutch translation. - -commit fcc3ded75fe9f831aeb8678ee5e3926bf4168906 -Author: Guus Sliepen -Date: Mon Oct 8 15:37:14 2001 +0000 - - Fix bug when dropping an old connection in favour of a new one from the - same host. - -commit 1ef90a87fd9fd53c25a43455ffaac5274a63dc08 -Author: Guus Sliepen -Date: Mon Oct 8 13:37:30 2001 +0000 - - - Use ping timeout mechanism to close connections that don't authenticate - in time. - - Fix potential segmentation fault in check_dead_connections(). - -commit ce9fd32c04adf83cbaf668ee42a29575ba256002 -Author: Guus Sliepen -Date: Mon Oct 8 11:59:08 2001 +0000 - - Fix bug where tinc would crash because of a portscan or a connection from a - tinc daemon with a different version. - -commit 21027b1d5702c331b1ebb262bb149c75be1f24b1 -Author: Guus Sliepen -Date: Mon Oct 8 11:47:55 2001 +0000 - - - Renamed lastbutonehop to prevhop. - - Added connection_t *via to connection_t, this keeps record of where - to send UDP packets to. - -commit 18d1233c40a5705e9123edd6f4c6764a5178003b -Author: Guus Sliepen -Date: Tue Sep 25 13:39:11 2001 +0000 - - Fill in next- and lastbutonehop for myself. - -commit ec100a58b44e412a3d2606e5213af9ec5f30235b -Author: Guus Sliepen -Date: Tue Sep 25 13:35:45 2001 +0000 - - Try next connectto instead of the same over and over. - -commit 4d3de3b6a9b55bc783c649ff33e5415b0c7b5f25 -Author: Guus Sliepen -Date: Mon Sep 24 14:16:29 2001 +0000 - - Show next- and lastbutonehop when dumping connectionlist to syslog. - -commit 24a2c7e51a0b080c4bdb55f697b3f0458ebc3fb1 -Author: Guus Sliepen -Date: Mon Sep 24 14:12:00 2001 +0000 - - Not only keep track of nexthop, but also of lastbutonehop. If destination cl - wants indirectdata, send it to the lastbutonehop instead, unless it too has - requested so, and so on. - -commit 154733927af0b27cdadb83f03b845301ce8bfbfd -Author: Guus Sliepen -Date: Mon Sep 24 13:31:15 2001 +0000 - - - Try old TUN/TAP ioctl() request if the one from if_tun.h fails. - - Be more verbose about the kind of tap device used. - -commit 950c934e0bda28e5952d699d6008ee783d81982b -Author: Ivo Timmermans -Date: Wed Sep 5 18:38:09 2001 +0000 - - Killing tincd with SIGINT causes it to toggle between the current - debug level and level 5. Useful to debug a running tincd. - -commit a54ec980e047d13ecff7f1f337aa2665072febfd -Author: Guus Sliepen -Date: Sat Sep 1 12:46:49 2001 +0000 - - config_t* is a const parameter in get_config_val(). - -commit 68e23b1c9e69b2a218b3be821ad1ba3b3b6a64f2 -Author: Guus Sliepen -Date: Sat Sep 1 12:36:53 2001 +0000 - - Optional signal number for -k option. - -commit 8ed27d40f358581d021319cc26313c9f6ddf9a71 -Author: Guus Sliepen -Date: Sat Sep 1 12:36:06 2001 +0000 - - Revised reconnection mechanism, always try out all ConnectTo lines. - -commit ef1facc60709e9474197aa3fde9d517dfd96dc87 -Author: Guus Sliepen -Date: Sat Sep 1 12:02:39 2001 +0000 - - Remove IndirectData support for now, new implementation will be added - later. - -commit 8b5e4211304aaa5d39bc95f04398bd5ecaa887d8 -Author: Guus Sliepen -Date: Tue Aug 28 20:52:39 2001 +0000 - - Fix signed comparison bug in lookup_subnet_ipv4(). - -commit e1184ad15d6b2e7d58bdcb4489026dd0a35b4e5f -Author: Guus Sliepen -Date: Fri Aug 17 18:14:04 2001 +0000 - - Don't send DEL_HOSTs when !status.meta - -commit 30d22474ccc8da9a5685a90e0b2304ec627475af -Author: Guus Sliepen -Date: Tue Jul 24 20:14:30 2001 +0000 - - Explicitly log which type of tunnel device is used. - -commit 7e86cf91e3399905e19882bcf2d5677d7986aca5 -Author: Guus Sliepen -Date: Tue Jul 24 20:13:42 2001 +0000 - - The val variable in a config_t is never used as a long. - -commit 43923d2b106bfbe9300cc8e364cf098444cd649e -Author: Guus Sliepen -Date: Tue Jul 24 20:04:22 2001 +0000 - - Write public key to rsa_key.pub instead of rsa_key.priv (if not host - configuration file is found). - -commit 44e9d6a2872fac55f7eb701ba576ed9f39a22e08 -Author: Guus Sliepen -Date: Tue Jul 24 20:03:40 2001 +0000 - - Don't use %m in fprintf(). - -commit cbd03caece25d45015a4526b94b04a34ab87b0f2 -Author: Guus Sliepen -Date: Tue Jul 24 08:51:36 2001 +0000 - - More on edges. - -commit 3cd238f4e338f257ff61d58a9979b54344ee462f -Author: Guus Sliepen -Date: Mon Jul 23 22:06:22 2001 +0000 - - Discuss how sending ADD_EDGEs would be better than sending ADD_HOSTs. - -commit 5333cada0dfc4dfc3be728e6c78d8d42dc2ace52 -Author: Guus Sliepen -Date: Sun Jul 22 17:41:52 2001 +0000 - - Written down a possible solution. - -commit 995ab86fce506e9fabcf5a9ead7d43b30f12ab09 -Author: Guus Sliepen -Date: Sun Jul 22 15:25:13 2001 +0000 - - Correctie. - -commit d7b4de0e73baf664964f6daaf63526606b6a890b -Author: Guus Sliepen -Date: Sun Jul 22 14:58:18 2001 +0000 - - Small update. - -commit 71b9041f484128219f81cbf4f22a4e11388f879d -Author: Guus Sliepen -Date: Sun Jul 22 14:46:11 2001 +0000 - - Described problem in more detail. - -commit c1a98cd37ea20f6020487b2a5586e6de432398e7 -Author: Guus Sliepen -Date: Sun Jul 22 14:04:38 2001 +0000 - - Started writing a document about how daemons connect to each other. - -commit fcbe215d64d7e2f3b159fff6422d750417877ac4 -Author: Guus Sliepen -Date: Sat Jul 21 20:21:25 2001 +0000 - - Woohoo! tinc now compiles, runs and actually *works* on Solaris! - Tested on a SparcStation 20MP running Solaris 7. (Thanks, jiggel!) - -commit 533ee1206fb6433a1f0e616db999b3655addfaf2 -Author: Guus Sliepen -Date: Sat Jul 21 15:46:34 2001 +0000 - - Always close all sockets in terminate_connection(). - -commit acb853205d6d582d919c59879393b301ad4f4fde -Author: Guus Sliepen -Date: Sat Jul 21 15:34:18 2001 +0000 - - Updated terminate_connection() so you can choose if DEL_HOSTs should be - sent or not. - -commit 12f6b80429bc05a828051d72cc46f173e4657180 -Author: Guus Sliepen -Date: Fri Jul 20 20:25:10 2001 +0000 - - Added purge_tree for connection_t's which are no longer in the connection, - active or id trees, but which may still be referenced. This tree is flushed - when it is safe, this replaces purge_connection_tree(). - - Also lots of bugfixes related to the new trees. - -commit 37ed4265fa73d4c06c74362514d78c92029b2f05 -Author: Guus Sliepen -Date: Fri Jul 20 13:54:19 2001 +0000 - - Remove all unnecessary status.meta and status.active checks. - -commit 5e2ded68bfc7b3a1bfa600c1ce46144eb50e57a2 -Author: Guus Sliepen -Date: Thu Jul 19 12:29:40 2001 +0000 - - Correctly use the active_tree. - -commit 319e0cb48eb00565a11c85b901f54141f8160334 -Author: Guus Sliepen -Date: Sun Jul 15 18:07:31 2001 +0000 - - Split connection list into two lists: - - one list to handle all incoming/outgoing TCP connections - - another list to handle all UDP connections - - This will prevent race conditions. - -commit b3074590b184c141419cf4926820dc0d78380535 -Author: Guus Sliepen -Date: Sun Jul 15 14:21:12 2001 +0000 - - Correct inclusion of standard if_tun.h header file. - -commit 5dc4ade0b9c127a3c144d9c59894bf13527fe060 -Author: Guus Sliepen -Date: Wed Jul 4 08:43:32 2001 +0000 - - Don't load table of verbose OpenSSL errormessages. - -commit 1e2bdc2b6d28c76c63fc9fd36169b90fa0994388 -Author: Guus Sliepen -Date: Wed Jul 4 08:41:36 2001 +0000 - - - Always use instead of just - - Check if RAND_pseudo_bytes() exists, otherwise just use RAND_bytes() - -commit 6bd93e4c064578b545cb6dcaa28fffb229c929ff -Author: Guus Sliepen -Date: Sun Jul 1 21:42:13 2001 +0000 - - Check for all potential duplicate entries in the id tree. - -commit 9645cabc8e8364ed4df187fab8065b0991afa6af -Author: Guus Sliepen -Date: Sun Jul 1 09:21:14 2001 +0000 - - Fix compiler warning. - -commit 6365d0627b9b1e9a31371ec891db0d2cfb4d6ed4 -Author: Guus Sliepen -Date: Sun Jul 1 09:21:01 2001 +0000 - - Fix printf format bug. - -commit 33d6de0cd5c05cbf37211924a45e4231fec3a416 -Author: Guus Sliepen -Date: Sun Jul 1 09:06:17 2001 +0000 - - More items marked as done. - -commit a111593a082ff1df26f54168ab00f83ab3a1ab49 -Author: Guus Sliepen -Date: Fri Jun 29 15:38:40 2001 +0000 - - Dutch translation updated. - -commit 748dabdbe93f7439ed7eddf491a556279250e7ac -Author: Guus Sliepen -Date: Fri Jun 29 15:33:18 2001 +0000 - - Update of RedHat build scripts. - -commit 343c8fb6388ffd4f5c41cebd666aa8a045b20bdd -Author: Guus Sliepen -Date: Fri Jun 29 15:32:26 2001 +0000 - - It appears that autogen.sh doesn't like es.po if it isn't mentioned in - the makefile/configure scripts. - -commit 9391efe4e88077723840a7c085388ba2765ca17c -Author: Guus Sliepen -Date: Fri Jun 29 14:15:46 2001 +0000 - - Check for dlopen in standard libraries first (needed for DEC OSF). - -commit c9591bd1de1abcfe10459bd8c8cdd81a7b441ec0 -Author: Guus Sliepen -Date: Fri Jun 29 13:09:55 2001 +0000 - - Fix gcc 3.0 warnings. - -commit 402b85c48284a06fbfc56aca102b33be3a4260b0 -Author: Guus Sliepen -Date: Fri Jun 29 13:09:32 2001 +0000 - - Log error if two hosts connect with same IP/port tuple. - -commit 0d3bd912acdb00dc0a8015e337f981c942aa21bc -Author: Guus Sliepen -Date: Fri Jun 29 11:09:13 2001 +0000 - - Also remove po/Makefile.in.in, which is generated by autogen.sh. - -commit 67c16924c10b25d37957843a69d993b934dd1776 -Author: Guus Sliepen -Date: Fri Jun 29 11:03:27 2001 +0000 - - es.po revived. - -commit 5d3450357482176ce92ed4832ec944519d197744 -Author: Guus Sliepen -Date: Fri Jun 29 10:30:18 2001 +0000 - - Execute tinc-down BEFORE tap device is closed. This is a. more symmetric - (tinc-up is started after tap device is opened) and b. is needed for - tun/tap device, where the interface does not exist anymore after the - device file is closed. - -commit 6666acd0012c82c0bb4d1abae87332cec3dda77a -Author: Guus Sliepen -Date: Fri Jun 29 10:27:57 2001 +0000 - - Don't build Spanish translation. - -commit 77f635e871060f63c3e62fcf879d184326c690a4 -Author: Guus Sliepen -Date: Fri Jun 29 10:27:33 2001 +0000 - - ABOUT-NLS is created by autogen.sh. - -commit 333be8fbb8790237577761e580126a6d757a46e4 -Author: Guus Sliepen -Date: Fri Jun 29 10:23:46 2001 +0000 - - Spanish translation removed. Nobody maintains it, and it is severely - outdated. - -commit 3503ba995012f658f087a196dad0cb9fd45eff3b -Author: Ivo Timmermans -Date: Tue Jun 26 22:00:57 2001 +0000 - - Small fix to make it compile again - -commit 7fc068fe5421f7ec556b0b7db6f814e18b3326a4 -Author: Guus Sliepen -Date: Thu Jun 21 18:28:52 2001 +0000 - - Reinstated search for if_tun.h in kernel source tree, because apparently - /usr/include/linux does not always have the same contents as the include - files from the currently running kernel. - -commit 9e96840da810437c45af1c4b139578f7d74d65db -Author: Guus Sliepen -Date: Thu Jun 21 16:37:47 2001 +0000 - - Remove #warnings I used for debugging stuff. - -commit b1e97ece9c495ac67e54b8c2675b1eacc645eb1c -Author: Guus Sliepen -Date: Thu Jun 21 16:37:05 2001 +0000 - - Check for and add -ldl. - -commit 04ec0b82ab9c6a2662300a9257a5aff1c4dd56e7 -Author: Guus Sliepen -Date: Thu Jun 21 16:16:32 2001 +0000 - - - Solaris compile fixes - - Set mymac to broadcast MAC so that ifconfig hw ether <...> is really not - needed anymore. - - Forwarding of indirect packets when in switch mode (because the kernel - will not do it for us then). - -commit 353a9230bb70b70028f2dc6c651a28e30b13dc63 -Author: Ivo Timmermans -Date: Wed Jun 20 21:32:40 2001 +0000 - - Don't include the debian/ dir in a release - -commit 9a0a50cd3cf2570b39e00edf1a92123acbac41b4 -Author: Guus Sliepen -Date: Sat Jun 9 10:00:34 2001 +0000 - - Woops - big bug in send_key_changed fixed. - -commit ba918dce287788aaf6a90b3c7a9f349b197068d6 -Author: Guus Sliepen -Date: Fri Jun 8 18:02:10 2001 +0000 - - Only reset seconds_till_retry when we activate the outgoing connection. - -commit c5c02a0861bf540e07fe64704cb97aae29c4cacf -Author: Guus Sliepen -Date: Thu Jun 7 07:51:04 2001 +0000 - - Changed drastically because it didn't work correctly: - - Don't cache the --with-openssl-* option arguments - - Only search for openssl/*.h, the openssl include files include other - files only from an openssl/ directory too - - Set CPPFLAGS before AC_CHECK_HEADERS - -commit 053e78654097cf353aa59b4d34e608726edd5dad -Author: Guus Sliepen -Date: Thu Jun 7 07:48:11 2001 +0000 - - Save configure cache more often. - -commit 96ef7becdd71fc63c3489e3696117c1f137eade5 -Author: Guus Sliepen -Date: Wed Jun 6 19:12:38 2001 +0000 - - Fixes to make switching work between hosts that have no meta-connection. - -commit ce6c8e6d089abac81520c517185c6ef81b09f051 -Author: Guus Sliepen -Date: Wed Jun 6 19:11:16 2001 +0000 - - Log and warn about duplicate subnet_add()'s for the same subnet. - -commit 9cd9b0392388e24ade19a43206221081b61806e7 -Author: Guus Sliepen -Date: Tue Jun 5 19:45:47 2001 +0000 - - Add missing? counting of total_socket_in. - -commit 7bd7f5b4363f222340e5c058c243d31c576fba88 -Author: Guus Sliepen -Date: Tue Jun 5 19:39:54 2001 +0000 - - You can now put an option "Mode" in tinc.conf, and choose from: - - - Mode = router (default, work like tinc has always worked) - - Mode = switch (work like a switch) - - Mode = hub (work like a hub, broadcasting everything) - -commit edd6734faa37d043b8a2cc75b125db3b1c2130fa -Author: Guus Sliepen -Date: Tue Jun 5 18:07:14 2001 +0000 - - Fix bug where lookup_subnet_ipv4() could go into an infinite loop. - -commit fa376fbd4e5151ae43e86441a1e99073eeaf46a5 -Author: Guus Sliepen -Date: Tue Jun 5 16:31:59 2001 +0000 - - - This oneliner removes the need for ifconfig tap? hw ether fe:fd:0:0:0:0 - -commit 7a736d47b264065371f35cd9da64485d798cbc80 -Author: Guus Sliepen -Date: Tue Jun 5 16:15:48 2001 +0000 - - Updated dutch translation. - -commit 92924e8482f000eb33130ce9feadc08450ff349d -Author: Guus Sliepen -Date: Tue Jun 5 16:13:41 2001 +0000 - - Changed some stuff to allow correct generation of po/Makefile after a - make cvs-clean. - -commit 4f9dad0972ac0f665a1b6050b059bd52f93e6221 -Author: Guus Sliepen -Date: Tue Jun 5 16:09:55 2001 +0000 - - - tinc can now act as a switch or a hub too (as opposed to a router only) - - cleaner initialisation of "UNKNOWN" and "MYSELF" names - -commit 428482d86f860d1fb09de722c1b6576ec2eef1ce -Author: Guus Sliepen -Date: Mon Jun 4 11:14:35 2001 +0000 - - Added proxy-arp support. No more ifconfig -arp needed. Works like a charm - under FreeBSD now :). - -commit 0a3c8cefd4a154948799baaaa246cf0eba050eff -Author: Guus Sliepen -Date: Fri Jun 1 08:02:09 2001 +0000 - - Fix subnet_lookup() for overlapping subnets. Needs rethinking. - -commit 7db1b999c82611d6c68a5d79b4754db19669d5c6 -Author: Guus Sliepen -Date: Mon May 28 08:56:57 2001 +0000 - - Make sure Solaris is happy too. - -commit 65247c063b36a76dd68156fe17b017c7460d982f -Author: Guus Sliepen -Date: Mon May 28 08:21:43 2001 +0000 - - Small fixes to allow correct compilation under FreeBSD (tested with 4.3) - -commit 4e959ee40542733e647c36831c1fc87ed8098233 -Author: Ivo Timmermans -Date: Sat May 26 09:35:28 2001 +0000 - - Don't distribute autogen.sh in a release - -commit 514f8f579d5c0608aee8ca4a43d7414ecee5c11c -Author: Ivo Timmermans -Date: Sat May 26 09:35:00 2001 +0000 - - Changed version number to 1.0-cvs - -commit 20c2b62b1802390c0f5a1757641a0a1cea8103a8 -Author: Ivo Timmermans -Date: Sat May 26 09:34:11 2001 +0000 - - New make target: `make release' - -commit 8d307c2fbf2c20eb53909f74c81e03db838fb55e -Author: Guus Sliepen -Date: Fri May 25 18:57:37 2001 +0000 - - Fix sample configuration to show keys in PEM format and correct tapdevice. - -commit e12d41f39d8dd1cd30058d08effd2e5b66cdd4fd -Author: Guus Sliepen -Date: Fri May 25 13:24:34 2001 +0000 - - Documents are merged. Now we only need to check the ports and the TCPonly - and IndirectData options. - -commit f0c64a3dac3b0469ea05fa5d44a1e7bdbfa64900 -Author: Guus Sliepen -Date: Fri May 25 12:45:37 2001 +0000 - - Merged PROTOCOL, NETWORK and SECURITY2 with the texinfo manual. - -commit fcf869cd4250a240ea8d443f70fa373e4fbacf07 -Author: Guus Sliepen -Date: Fri May 25 11:54:28 2001 +0000 - - TCPonly now works (in a relatively clean way too). - -commit a5e2ae6b2b2e1629cf05bb2a57df75f13c0f120a -Author: Guus Sliepen -Date: Fri May 25 10:08:11 2001 +0000 - - With recent kernels the tun device file is located in /dev/net. - -commit 6e09c2a99c8ac3c1391f4f2eee16d6c235c10e90 -Author: Guus Sliepen -Date: Fri May 25 10:06:13 2001 +0000 - - Small corrections to the manuals. - -commit 4dee76522e177dcb4af5d6d844a5f3b74070e4b7 -Author: Guus Sliepen -Date: Fri May 25 08:36:11 2001 +0000 - - Small fixes: - - - Fix compiler warnings (one was a real (but harmless) bug) - - Don't send PING packets if there is UDP traffic - - Correctly terminate strings containing salt for PING/PONG packets - -commit bfc5d6014e3c1563f7b6a2f10698e9ba23ba3e96 -Author: Guus Sliepen -Date: Thu May 24 21:52:26 2001 +0000 - - Only send key_changed if it was previously requested. - -commit 1a248fd5bd5aa24fa0f6a2c395f05dd569f0898d -Author: Guus Sliepen -Date: Thu May 24 21:32:30 2001 +0000 - - All features for 1.0 are implemented now, we just have to check the - FreeBSD and Solaris ports and merge some docs. - -commit 58893f0875369aafff8481825af271683c975a2a -Author: Guus Sliepen -Date: Thu May 24 21:30:36 2001 +0000 - - Since this is incompatible with some earlier versions, PROT_CURRENT is - increased. - -commit d1b597758eab68bb80d97855f25cb6dda55eeb0b -Author: Guus Sliepen -Date: Thu May 24 21:29:09 2001 +0000 - - Add randomness to PING/PONG packets to prevent crypto attacks on quiet - tunnels. - -commit 4493b0650bd487990ca9d2802496ad0ee7c06247 -Author: Guus Sliepen -Date: Thu May 24 20:40:13 2001 +0000 - - Changed URL from kernelnotes.org to linuxdoc.org. - -commit 3360c6270bcc19a8b3d81da185266fc33b5c5421 -Author: Guus Sliepen -Date: Thu May 24 20:24:12 2001 +0000 - - More revisions to the documentation: - - - Removed cruft - - Reordered some sections to make it more logical for the beginner - - Added small examples and hints about configuration files - -commit 6f7f8659a2048fd6d616f4286ccdd0e661084493 -Author: Guus Sliepen -Date: Sat May 19 15:50:51 2001 +0000 - - - Make sure correct information is supplied for both old kernels (with - ethertap) and for new kernels (with TUN/TAP driver). - - Revised example configuration and made it conform to latest (CVS) version of - tinc. - -commit e4f3d93ec62871d1ae11b460627aef0da1b23cd2 -Author: Guus Sliepen -Date: Mon May 7 19:08:46 2001 +0000 - - - s/ip_t/ipv4_t/g - - Add "salt" to the beginning of UDP packets. Replaces length field which - is not useful anyway. - -commit a26081467c197cc6b26a0c36c4508361b242fc85 -Author: Guus Sliepen -Date: Fri May 4 18:45:02 2001 +0000 - - Correctly cycle through ConnectTo variables. - -commit 80b4a851a6b62cbbf503c2225f93305966f058c0 -Author: Guus Sliepen -Date: Fri Apr 13 10:30:04 2001 +0000 - - Depend on new ssl package and install alias for universal TUN/TAP module. - -commit 156ec676525ed789364b7a77926dd0717d0cf5d7 -Author: Guus Sliepen -Date: Tue Mar 13 21:33:31 2001 +0000 - - Check indirectdata option before forwarding certain requests. - -commit c426e981eeaed3fa4801221720ee8f74d40e9223 -Author: Guus Sliepen -Date: Tue Mar 13 21:32:24 2001 +0000 - - Ignore alarm signals if we do not need to respond to them. - -commit b413257e10ae0645da43583dd8f84a1f74df5bd7 -Author: Guus Sliepen -Date: Tue Mar 13 09:55:14 2001 +0000 - - Fixed bug in setup_signals() that would make tinc die when unexpected - signals were caught. - -commit f1a082823c48d00171b814f7e14e07e6dd4632fb -Author: Guus Sliepen -Date: Mon Mar 12 23:58:19 2001 +0000 - - Fixed a race condition triggered by receive_meta() and the new - authentication scheme. - -commit f4887b981f109fc4264f50170b2d12c4033bf5e9 -Author: Guus Sliepen -Date: Sun Mar 4 14:00:24 2001 +0000 - - Added a description of what is going on in net.c and route.c, and how - packets flow through tinc. - -commit 9d5c9bf6ba74e4e8bbd12b97fdda6c665155fec6 -Author: Guus Sliepen -Date: Sun Mar 4 13:59:53 2001 +0000 - - Updated translation. - -commit 34f9e6cf2d6d2b81eb63f9f28963b447a2157740 -Author: Guus Sliepen -Date: Sun Mar 4 13:59:32 2001 +0000 - - - route.c is now used to determine destination - - flags are removed, since they were not used at all. Use options instead. - - indirectdata works now, tcponly almost... - - made functions that don't return useful information void - -commit d2a54597e029f9d4f7bd29837be1be33909d78b1 -Author: Guus Sliepen -Date: Fri Mar 2 11:25:56 2001 +0000 - - Added explaination of our key exchange using RSA encryption. - -commit 125c4978812cffa5154ce5378a276f43f78417d8 -Author: Guus Sliepen -Date: Thu Mar 1 21:32:04 2001 +0000 - - Various small fixes. - -commit 099cc867c1a0831add7f1b4046f22ad6bfa5a1ef -Author: Guus Sliepen -Date: Tue Feb 27 16:50:29 2001 +0000 - - Removed compiler warning. - -commit 4fa12eb85d72f039df5004abc201f01f5573c2e4 -Author: Guus Sliepen -Date: Tue Feb 27 16:37:31 2001 +0000 - - Removed lots of compiler warnings. - -commit 173d606514d82fc5ae7895a178238d0abcaf6606 -Author: Guus Sliepen -Date: Tue Feb 27 16:17:04 2001 +0000 - - - Fixed Interface option (untested) - - Removed error handling for non-critical socket options - - Added TCP_NODELAY and IPTOS_LOWDELAY options for meta sockets. - -commit fb4ba9b265666d9949b03209a3ff52ff1263226b -Author: Ivo Timmermans -Date: Tue Feb 27 16:15:14 2001 +0000 - - Authentication done - -commit 24fa68585923d2b52718390f3f38d1aaacef12f0 -Author: Guus Sliepen -Date: Tue Feb 27 15:33:39 2001 +0000 - - Don't forget to reconnect if outgoing connection fails during - authentication. - -commit 34b7a876c3583f7a34585cff6a694bc9e35cdc87 -Author: Guus Sliepen -Date: Mon Feb 26 11:37:20 2001 +0000 - - - Make sure METAKEY is smaller than the modulus of the RSA key - - Get symmetric key from the least significant bytes of the RSA message - -commit 4b0ad4d97abd3643c44f45841d52f3000a34ba60 -Author: Guus Sliepen -Date: Sun Feb 25 20:17:46 2001 +0000 - - Added process.c to the translated files. - -commit 82455be966027a087a2ac23e3464594c81d7b111 -Author: Guus Sliepen -Date: Sun Feb 25 19:09:45 2001 +0000 - - Implemented new authentication scheme from doc/SECURITY2. - -commit 54881faf6fdbf04fb5ee56b7809439fbc50c65cb -Author: Guus Sliepen -Date: Sun Feb 25 16:34:19 2001 +0000 - - Encrypt network packets in CBC mode instead of CFB mode. - (This breaks compatibility with all previous versions!) - -commit 9de5787574b21e94c80ddc60def2b3e514aff755 -Author: Guus Sliepen -Date: Sun Feb 25 16:04:00 2001 +0000 - - Copy packets before putting them in the queue. - -commit 38adc479a44b64afcb220cd757f77ab105cb9bcd -Author: Guus Sliepen -Date: Sun Feb 25 15:34:50 2001 +0000 - - Free node->data and node, not node->data twice. - -commit e250d64300cea2a83059866e7cbabcb33684160e -Author: Guus Sliepen -Date: Sun Feb 25 14:51:42 2001 +0000 - - Add missing \n. - -commit 153fc35e57c0104aa4ea9103bcdbca3665e4934c -Author: Guus Sliepen -Date: Sun Feb 25 11:09:29 2001 +0000 - - Corrected check for errors after read() calls. - -commit 0b0c2a372ff5d11f73af172e07a93b2656374a42 -Author: Wessel Dankers -Date: Tue Feb 20 21:53:18 2001 +0000 - - Important bugfix in avl_insert_before() and avl_insert_after() - -commit 11f8465dd9a4f81b43a31f1cb6a7fc2d76bb7838 -Author: Ivo Timmermans -Date: Sun Feb 18 02:13:26 2001 +0000 - - tinc_TUNTAP now substitutes the values outside the AC_CACHE_CHECK - block. configure should now correctly set HAVE_TUNTAP. - -commit bb0870498037565209e24fbb2ffa07b815350a0b -Author: Guus Sliepen -Date: Tue Feb 13 09:54:29 2001 +0000 - - Added description of the proposed new authentication scheme. - -commit cebb6efeb0f39bf05ca7836b7a393c8385b49335 -Author: Ivo Timmermans -Date: Sun Feb 11 11:55:28 2001 +0000 - - More files to ignore in CVS - -commit 603781831f251d2e8111e8282d8e624b8e40b175 -Author: Guus Sliepen -Date: Sun Feb 11 11:50:09 2001 +0000 - - - Updated CVS_CREATED to remove intl/ directory and some other - autogenerated files. - - Checked if all INCLUDES/LIBS/etc directives inherit the global variables. - -commit 88dfdc9dbac3f5d0aa70b77509b4a87513433987 -Author: Guus Sliepen -Date: Sun Feb 11 11:46:14 2001 +0000 - - Ignore file for src/ - -commit ef0fc4f687fc25e97551e589941d6a2a2d8ade42 -Author: Guus Sliepen -Date: Sun Feb 11 11:44:32 2001 +0000 - - Added .cvsignore files to get rid of warnings and prevent autogenerated - files from being added accidentaly. - -commit f1cb3d8fa5f69840f353ca5a62f363dad47eb46f -Author: Guus Sliepen -Date: Tue Feb 6 10:42:27 2001 +0000 - - Removed another local definition of the variable "errno" - -commit 0f715887c617723e4b450083f8b77641f8b62e80 -Author: Guus Sliepen -Date: Tue Feb 6 10:13:44 2001 +0000 - - Updated dutch translation. - -commit 4bc394a3e29f2f90434bbbfc9f23d5587398471b -Author: Guus Sliepen -Date: Tue Feb 6 10:13:22 2001 +0000 - - Fix memory leak in avl_insert() if item was already inserted. - -commit f777c1807d663eaef3e36c395094451214886898 -Author: Guus Sliepen -Date: Tue Feb 6 10:12:51 2001 +0000 - - FreeBSD compile fixes (thanks to XeF4) - -commit bb4457d6caf6e424aeaf9b09222d4e62cab939da -Author: Ivo Timmermans -Date: Thu Jan 18 13:02:34 2001 +0000 - - Unpack sample-config.tar.gz when installing - -commit fe61e1ffef186aa509a50be3be83955fe1cbb514 -Author: Ivo Timmermans -Date: Thu Jan 18 13:01:42 2001 +0000 - - Distribute the sample config as a .tar.gz - -commit a73ec9caa45bda7738376a610030c8ba9b934445 -Author: Ivo Timmermans -Date: Thu Jan 18 13:00:57 2001 +0000 - - Fixed some errors - -commit b33c5f6640e63cc4cd35285367bcb2827b732229 -Author: Ivo Timmermans -Date: Wed Jan 17 16:24:24 2001 +0000 - - First try to create a graphical frontend for tinc configuration - -commit 6bc77a7710adcbc33331c45e1b6adf7089a42075 -Author: Ivo Timmermans -Date: Wed Jan 17 01:48:44 2001 +0000 - - Get the PO files up to date with the current source - -commit 664f7e5c0b9056d88e2b63b3626ea33c4894387b -Author: Ivo Timmermans -Date: Wed Jan 17 01:47:39 2001 +0000 - - Get the Debian changelog up to date - -commit 1d898e00a964ef922617683a1d29ff24e56ed8ff -Author: Ivo Timmermans -Date: Wed Jan 17 01:40:46 2001 +0000 - - Merged documentation with various updates I had lying around - -commit 457c6fa7b63a7f2971314d8d63af71c880ec6f53 -Author: Ivo Timmermans -Date: Wed Jan 17 01:34:08 2001 +0000 - - Second draft of the release notes - -commit b236ddb1df16f8eb025d485b75153c4f25f4afc6 -Author: Ivo Timmermans -Date: Wed Jan 17 01:31:56 2001 +0000 - - Change version to 1.0pre4 - -commit a893b05cb017c04871c2faf4099f104985f4ad75 -Author: Ivo Timmermans -Date: Wed Jan 17 01:30:32 2001 +0000 - - Set Architecture to `any' - -commit 54e19d34663cfe4af05e9e1dac94f76e39858f18 -Author: Ivo Timmermans -Date: Wed Jan 17 01:30:05 2001 +0000 - - Fix error reporting of read_config - -commit a56df1e06be3f47a775919e564c147687e961b5d -Author: Guus Sliepen -Date: Sat Jan 13 16:36:23 2001 +0000 - - - Allow ASN1 style keys to be in the config files. - Note: tinc ignores private key in the main config file, tinc.conf, - because it should really be in a separate file. - - When generating new keys, check if name is known and by default append - the public key to the host configuration file (otherwise rsa_key.pub). - -commit 44c85ab07ed07165b80140da4e2910ca51fa8887 -Author: Guus Sliepen -Date: Sat Jan 13 14:56:46 2001 +0000 - - - Copy entire sample-config directory to /etc/tinc/example upon installing. - -commit b195e8815f0abb2c5527119221886b524d719019 -Author: Guus Sliepen -Date: Sat Jan 13 14:38:18 2001 +0000 - - Added sample configuration directory. - -commit d646f4e094b63720f97bfd37bb3489bd9d6231a0 -Author: Guus Sliepen -Date: Thu Jan 11 11:19:08 2001 +0000 - - - Only send out DEL_HOSTs for hosts with a meta connection - -commit c8beaf35ee923c209ee23bedcb3dc892d2c2dae3 -Author: Guus Sliepen -Date: Mon Jan 8 21:32:30 2001 +0000 - - - Cleaned up subnet_t - -commit e5e1c20a99b0d72792f28e9a075a9f4a7e8b2c95 -Author: Guus Sliepen -Date: Mon Jan 8 21:32:00 2001 +0000 - - - Sign was wrong in search_closest_smaller/greater - -commit 11f3e9d138daf6b726631cc124b14d66dfa4d1f7 -Author: Guus Sliepen -Date: Mon Jan 8 20:35:30 2001 +0000 - - - Squashed another nasty bug. - -commit 447a43d63960802a7a29201c512246be11eb9c94 -Author: Guus Sliepen -Date: Sun Jan 7 20:19:35 2001 +0000 - - - Added indirectdata and tcponly functionality. - -commit 7cd2baedc6027ef6a5b941342bc6d3931d7220ba -Author: Guus Sliepen -Date: Sun Jan 7 20:19:08 2001 +0000 - - - Fixed IPv6 subnet lookup routine. - -commit d3f889c8076dff9c00ebfe1459cb36425f8da41d -Author: Guus Sliepen -Date: Sun Jan 7 17:09:07 2001 +0000 - - - It's 2001, all copyright notices are updated. - -commit 96b6f958bc733c3963dd164caacd42513be47a86 -Author: Guus Sliepen -Date: Sun Jan 7 17:08:03 2001 +0000 - - - Description of protocol and authentication updated. - -commit 7109526c6789c73a18bbe6b228ca35f0374c8d36 -Author: Guus Sliepen -Date: Sun Jan 7 15:27:30 2001 +0000 - - - Added header file for route.c. The routing routines in it are not used - yet, but have a look at the source for the ideas behind it. - -commit 07a08f5539f441e66946d1db1711dc584f8621c4 -Author: Guus Sliepen -Date: Sun Jan 7 15:25:49 2001 +0000 - - - Reinstated a queue for outgoing packets. - -commit 049ff67817e0db5afbba30930531d8ea3f7f2d18 -Author: Guus Sliepen -Date: Sun Jan 7 15:24:52 2001 +0000 - - - Changed list routines to give it the same look'n'feel as the rbl and - avl tree library. - -commit 8b4bc5b3a7e31c198c001610c99c2993e1612376 -Author: Guus Sliepen -Date: Sat Jan 6 20:43:03 2001 +0000 - - - Typo. - -commit 3d7289cf743f89cab4c71815482a4837a21f6703 -Author: Guus Sliepen -Date: Sat Jan 6 20:02:21 2001 +0000 - - - Updated texinfo manual. - -commit 0d99ae59bd7c640d396ce978045f0911567fb9bf -Author: Guus Sliepen -Date: Sat Jan 6 18:44:55 2001 +0000 - - - Updated manual pages. - -commit 90bf1b21fa7e94d73719da0593e7c0356d05e18f -Author: Guus Sliepen -Date: Sat Jan 6 18:21:17 2001 +0000 - - - Changed license of AVL tree library to GPL. - -commit f7bb205022e02c02c02733cd43544c231373115d -Author: Guus Sliepen -Date: Sat Jan 6 18:03:41 2001 +0000 - - - Check and follow symlinks in is_safe_path - - By default write keys to tinc config directory - - Small fix in protocol.c - -commit 1398edec37336853bfca6ea3dcca7c402f102ea2 -Author: Guus Sliepen -Date: Sat Jan 6 16:51:14 2001 +0000 - - - Updated dutch translation. - -commit e924096f62655d711cd2d114a8d1ef0fecbb593b -Author: Guus Sliepen -Date: Fri Jan 5 23:53:53 2001 +0000 - - - Let user choose whether keys are in the config files or separate - - Use AVL trees instead of RBL trees - - Fixed a lot of annoying subtle bugs! Thanks to gdb... - -commit 052fbc0bdf36e0dbe2a0867ce770d426c9a44841 -Author: Guus Sliepen -Date: Fri Jan 5 23:51:41 2001 +0000 - - - Doubled size of trace buffer for easier debugging. - -commit 77509da76c61b881c9967bfb7cdafeaf6b56eb6d -Author: Guus Sliepen -Date: Fri Jan 5 23:50:56 2001 +0000 - - - AVL tree routines: faster than RBL, and also more stable. - -commit e1707f7739f450c729e26b921e459d5da07602f9 -Author: Guus Sliepen -Date: Fri Dec 22 21:34:24 2000 +0000 - - - Don't even think about using sscanf with %as anymore - - Allow keys to be inside the config files or in a seperate file - - Small fixes - -commit ecae72de94222302aa326888f70cfacdbd775b23 -Author: Ivo Timmermans -Date: Fri Dec 22 17:15:26 2000 +0000 - - Added lint target, requires lclint. - -commit c5fac35c6ce9b9fcc47508810d69aeab83d08c25 -Author: Ivo Timmermans -Date: Fri Dec 22 17:10:25 2000 +0000 - - Forget router.c - -commit 37544990e96fe5ea161e644f6417f505d666cd00 -Author: Ivo Timmermans -Date: Fri Dec 22 16:59:16 2000 +0000 - - Include autogen.sh (needed for the Debian package). - -commit 8a4daf4ea7758270a47a358f43ad97a64eb1c3ff -Author: Ivo Timmermans -Date: Fri Dec 22 16:54:56 2000 +0000 - - Various small changes. - -commit e469fca4d78e9d23698fe1e6b29b232198cc499e -Author: Ivo Timmermans -Date: Wed Dec 6 13:33:49 2000 +0000 - - Re-introduced MyVirtualIP and VpnMask, as dummy options. - -commit e50e4a54d6b40b988041a7e9bfdfbf708657f3a5 -Author: Ivo Timmermans -Date: Tue Dec 5 09:04:32 2000 +0000 - - Give a warning about having to re-create the keys - -commit 4610d98c04641fce65747e07d65cbdd03fb6fe30 -Author: Ivo Timmermans -Date: Tue Dec 5 09:03:41 2000 +0000 - - Ported it back to /bin/sh. - -commit 1e38dcc3fa6c0da2fdb21f83a588338fa8a41818 -Author: Ivo Timmermans -Date: Tue Dec 5 09:03:19 2000 +0000 - - Install a file in /etc/modutils/tinc, containing all necessary aliases - and options for kernel modules. - -commit 6327f32f43dc9109fad9952fd50a23876d0acaf0 -Author: Ivo Timmermans -Date: Tue Dec 5 08:59:30 2000 +0000 - - Tiny bits of code beautifying - -commit 9267bed9f516244b00d5c86c8dae44b7eb78a96c -Author: Ivo Timmermans -Date: Tue Dec 5 08:56:44 2000 +0000 - - Oops. I did some VERY wrong things with readline(). Fixed now. - -commit 6ddc9109d7313503895227c7876309b36681393d -Author: Ivo Timmermans -Date: Tue Dec 5 08:54:22 2000 +0000 - - Massive long awaited documentation update. It's not finished yet, - most notably the example configuration is still old. - -commit bc22ee16e6903d2caf9d22afa85020d1e3e10b56 -Author: Ivo Timmermans -Date: Sun Dec 3 12:23:06 2000 +0000 - - Option -d accepts an argument to set the debug level immediately. - -commit 01d23601a273d128ebfd13c2ffa10892e9b13094 -Author: Ivo Timmermans -Date: Sun Dec 3 12:22:19 2000 +0000 - - Sort configuration directives - -commit d6b77e18b58ad8f9bcd9b60864b95cd2a74482c5 -Author: Ivo Timmermans -Date: Sun Dec 3 12:21:20 2000 +0000 - - Added documentation merger - -commit e985f6d3cdbebdeb17333bbd3d3c20d4618128cf -Author: Ivo Timmermans -Date: Fri Dec 1 13:46:26 2000 +0000 - - Include COPYING.README in the distribution. - -commit 94192b3db10fe51ce45fa569ec068423a4491b0b -Author: Ivo Timmermans -Date: Fri Dec 1 13:45:46 2000 +0000 - - Stated that distributing executables linked with OpenSSL is permitted - provided that all other requirements of the GPL are complied with. - -commit 52575a573c1d87ee125a54a2e0b4044698904cae -Author: Ivo Timmermans -Date: Fri Dec 1 12:38:42 2000 +0000 - - Use buffer instead of line in read_config_file(), line may be assigned - NULL, so buffer always holds the pointer to the allocated space. - -commit ab33c1aa6081f07333bf1de00e4036dd2b4628a6 -Author: Ivo Timmermans -Date: Fri Dec 1 12:36:36 2000 +0000 - - readline() accepts two extra parameters, buf and buflen, to avoid - mallocing and freeing for every line that is read. - -commit 6c56a8416eded8f19076a619a27ad7b153dd91f3 -Author: Ivo Timmermans -Date: Thu Nov 30 23:44:07 2000 +0000 - - Tagged `Storing private key in separate file' as done. - -commit 8fe83e98da043e930a88ddd6b2de6c14aa791335 -Author: Ivo Timmermans -Date: Thu Nov 30 23:39:55 2000 +0000 - - All full stops have two spaces after them. (Silly commit, I know.) - -commit a0f7af3ed79c55d9680cbb0a569b3c8987581d43 -Author: Ivo Timmermans -Date: Thu Nov 30 23:18:21 2000 +0000 - - New function read_rsa_public_key(); - In net.c/setup_myself deleted old code to read the public key (which - is now implicitly read in together with the private key). - -commit 28deaeac14d619efb9830d03fd61dc7cca70a701 -Author: Ivo Timmermans -Date: Thu Nov 30 22:48:48 2000 +0000 - - Avoid printing duplicate messages from read_rsa_keys - -commit 2293304748f7e4e9a18ee848b8264bdecebae37f -Author: Ivo Timmermans -Date: Thu Nov 30 22:33:16 2000 +0000 - - Better error checking when reading the RSA private key. - -commit bf4e969899bb6cdeb05570d96a567c2833ac83bd -Author: Ivo Timmermans -Date: Thu Nov 30 22:32:14 2000 +0000 - - In readline(): initialise the line to zero length; - In read_config_file(): Test for EOF, and print the variable name that - caused an error. - -commit 113198d9c0b3be9904057673cfed165406803f86 -Author: Ivo Timmermans -Date: Thu Nov 30 21:11:03 2000 +0000 - - The file is safe if it doesn't exist. - -commit 09260b43d1ff037c22f86c82a6af830e9a6d6ae5 -Author: Ivo Timmermans -Date: Thu Nov 30 20:08:41 2000 +0000 - - Read the PEM file pointed to by the configuration directive - PrivateKey. This means thatt he meaning of this variable has changed, - it no longer should contain the private key directly. - - WARNING: This code is untested. - -commit 8ccb1ede92fbd55481fa2317c2450bb9dd94a180 -Author: Ivo Timmermans -Date: Thu Nov 30 00:24:13 2000 +0000 - - Implemented is_safe_path, and extended ask_and_safe_open. - - is_safe_path needs more work before it is useable. - -commit 75e3c296b4fa1eb02df2f5f84a1280e791f88603 -Author: Ivo Timmermans -Date: Wed Nov 29 15:22:04 2000 +0000 - - Updated Dutch translation - -commit d36da1948abdd27e9d0740c2baceb0bd155c18c6 -Author: Ivo Timmermans -Date: Wed Nov 29 14:30:07 2000 +0000 - - Also free the pointer returned by readline(). - -commit 9e55426d72fd77fda891edd0023dab2f9909639e -Author: Ivo Timmermans -Date: Wed Nov 29 14:27:24 2000 +0000 - - Use readline() in read_config_file() instead of fgets. - -commit 8ea23d9ec3f2fe0c113eac5caafb7c2bd03f3016 -Author: Ivo Timmermans -Date: Wed Nov 29 14:23:08 2000 +0000 - - xstrdup now takes a const pointer as an argument. - -commit 54ef13bf75a7a1e787716ce395ffe847fa74673f -Author: Ivo Timmermans -Date: Wed Nov 29 14:24:40 2000 +0000 - - Implemented a readline() function that will read an entire line into a - dynamically allocated buffer; - - Ask for a file name in ask_and_safe_open(). - -commit 9175d2048382c617a639fd3d437a9e06baa66d0f -Author: Ivo Timmermans -Date: Wed Nov 29 01:37:50 2000 +0000 - - Added a check for a scanf that knows about %as. - -commit 1ca04711aeab615161746c6bbb5d137388c73263 -Author: Ivo Timmermans -Date: Wed Nov 29 00:33:15 2000 +0000 - - Check for get_current_dir_name. There is a replacement function in - dropin.c. - -commit c94f7637427f4c89d56c41fe4c75f2970b664a63 -Author: Ivo Timmermans -Date: Tue Nov 28 23:23:41 2000 +0000 - - dropin.c/h contain a set of drop-in replacements for non-standard C - library functions (read: GNU extensions). - -commit 3ff76eb10acc55b6f269c1075de6bbaa5bc83516 -Author: Ivo Timmermans -Date: Tue Nov 28 23:12:57 2000 +0000 - - Save RSA public and private keys to a separate file, instead of - wanting to copy them into a configuration file. - -commit 4c502b005bfd24821e817c134e8a442a5f4606de -Author: Ivo Timmermans -Date: Tue Nov 28 08:59:27 2000 +0000 - - Use sigaction to set signal handlers, the previous commit (1.1.2.16) - already contained a large portion of what should have gone in this - one. - -commit e44dc004b3d1ce8f857971f479c917931eda7091 -Author: Ivo Timmermans -Date: Mon Nov 27 20:52:55 2000 +0000 - - Sort items to either 1.0 or future release goals. - -commit 699f3b4c93482055c0832c9a6b76dc0294967003 -Author: Ivo Timmermans -Date: Sun Nov 26 22:46:53 2000 +0000 - - Check for the function strsignal, and define it to "" if it is not - available. - -commit 67a4abda707b28b9c77cb35ff1e800e6a5b0991c -Author: Ivo Timmermans -Date: Sun Nov 26 22:42:34 2000 +0000 - - Give an error message if daemon() failed. - -commit 702e55306dfebe5c6f9a6587ed029c3bc3efbe8f -Author: Ivo Timmermans -Date: Sun Nov 26 22:32:52 2000 +0000 - - Updated Spanish translation, provided by Enrique Zanardi. - -commit 1eedf54681d4556c6874f7baee8e810cab867756 -Author: Guus Sliepen -Date: Sat Nov 25 13:33:33 2000 +0000 - - - Use only one socket for all UDP traffic (for compatibility) - - Write pidfile again after detaching - - Check OS (for handling FreeBSD/Solaris tun/tap stuff) - -commit 0806605ce383b7e89fa26eda56f8a5f3bbed9dd3 -Author: Guus Sliepen -Date: Fri Nov 24 23:30:50 2000 +0000 - - - Added daemon() replacement. - -commit cfb828784ebbcf4b3e40eb9bb351b6ed10a84b35 -Author: Guus Sliepen -Date: Fri Nov 24 23:14:52 2000 +0000 - - - Added Armijn to the list - -commit cf49b2c0647554613874cce495e4a7937a9f7863 -Author: Guus Sliepen -Date: Fri Nov 24 23:13:07 2000 +0000 - - Another big & bad commit: - - Added some extra search functions to rbl routines - - Fix subnet_lookup() - - Reorder some syslog messages to make more sense - - daemon() is back - - Don't let scripts execute in parallel (gives race conditions, and - anyway something MIGHT just be configured which is necessary for further - execution of tinc itself) - - Accidently merged check_child() with execute_script(). - - Small fixes - -commit 97c54ffb35312caf38034952b9ed2733f7e374f9 -Author: Ivo Timmermans -Date: Fri Nov 24 16:52:57 2000 +0000 - - Add default tinc-up and tinc-down scripts for a Debian system. These - do not yet work, it's just old code from init.d. - -commit b42c9abafdc102db0641f3d444bdb30fbc29140a -Author: Ivo Timmermans -Date: Fri Nov 24 14:15:20 2000 +0000 - - Call autogen.sh instead of configure alone; and make cvs-clean instead - of distclean. This way you can just cvs checkout && dpkg-buildpackage - in one go. - -commit edb9b4cad09855a9bb3c57c5d4b1b174fde1de6c -Author: Ivo Timmermans -Date: Fri Nov 24 14:13:51 2000 +0000 - - Explain how to tell configure where OpenSSL lives. - -commit 4cb4a7d298d560593f84d974bf77d0ee8a911a50 -Author: Ivo Timmermans -Date: Fri Nov 24 14:13:06 2000 +0000 - - Set errno to 0 before trying to kill the other process. - -commit ef88db63120503a8c9d34d86073795c99dedc3a9 -Author: Ivo Timmermans -Date: Fri Nov 24 14:12:31 2000 +0000 - - Alter CFLAGS, somehow INCLUDES doesn't propagate properly. Still - doesn't work exactly like it should, but getting there. - -commit b17822840150f5ba8cfb8e5a44fc10d66bd15a97 -Author: Ivo Timmermans -Date: Fri Nov 24 14:04:49 2000 +0000 - - Set CFLAGS to -O2 -Wall when running configure - -commit eb36b0c1ef7b5ed8ff59c3b41cbb361ed37d5f01 -Author: Ivo Timmermans -Date: Fri Nov 24 14:00:32 2000 +0000 - - Use cvs2cl instead of rcs2log to generate the ChangeLog. - -commit 2f37f2bd8ab6b89eb6b6c2b4bdd6ffe449b1aa98 -Author: Ivo Timmermans -Date: Fri Nov 24 14:03:13 2000 +0000 - - Set localstatedir to /var - -commit 31aa4298463498cbb755db747e901e4269cd1ef6 -Author: Ivo Timmermans -Date: Fri Nov 24 13:33:48 2000 +0000 - - Do not attempt to retreive ChangeLog information only from the CABAL - tag, it doesn't work anyway. - -commit f2dd7bb42c1f4bfa708f542e430f4a56fd43e74f -Author: Ivo Timmermans -Date: Fri Nov 24 13:32:26 2000 +0000 - - Do not check for the daemon() system call - -commit b0ff879e7c68edd447328f3d806c1ad9e336fece -Author: Ivo Timmermans -Date: Fri Nov 24 12:44:39 2000 +0000 - - Do not use the C library's daemon() call. - -commit cebcf78b9a24f70902009bea23514e55d84b096a -Author: Guus Sliepen -Date: Thu Nov 23 09:30:33 2000 +0000 - - - Don't link with -ldl anymore - - Let's not use bash' built-in pwd function anymore... it does not follow - symlinks. - -commit 7aa7895629d72391eccfcb23f3cb6290a9e3abc3 -Author: Guus Sliepen -Date: Wed Nov 22 23:09:38 2000 +0000 - - - #include instead of - -commit dac256505e1af78505c9f905bd55c11d4b87345c -Author: Guus Sliepen -Date: Wed Nov 22 22:18:03 2000 +0000 - - - Fixed all (except 2) compiler warnings gcc -Wall gave. - -commit 6f373e690236334d8f8333710b61f97ccad54bf1 -Author: Guus Sliepen -Date: Wed Nov 22 22:05:37 2000 +0000 - - - More porting to FreeBSD and Solaris. - -commit 5971e352dae2cf189f1cbdeacffa4ccdd1e98304 -Author: Guus Sliepen -Date: Wed Nov 22 20:25:27 2000 +0000 - - - Work with the correct key buffer in ans_key_h - -commit a07602c4fddfca9894f1d738959ae359695f5bf9 -Author: Guus Sliepen -Date: Wed Nov 22 19:55:53 2000 +0000 - - - No more %as. - -commit 394ed3fb174bb629bfb4b441fe58842562f955de -Author: Guus Sliepen -Date: Wed Nov 22 19:14:09 2000 +0000 - - - Write pidfile AFTER detaching... - - Minor cleanups - -commit f8b4a000d008082e5c7e511a49318b8dea8fd08d -Author: Guus Sliepen -Date: Wed Nov 22 18:54:08 2000 +0000 - - - Cleaned up and checked for some more NULL pointers in rbl.c - - Two connection lists: one for incoming connections, sorted on ip/port, - one for connections whose identity we know, sorted on id ofcourse... - -commit 785684f0ec5c9250788b4b32c0eab3f358c9db61 -Author: Ivo Timmermans -Date: Wed Nov 22 17:49:16 2000 +0000 - - Declare fd. - -commit e42255ae1374fe65e92de72de4508a84bdb91fa1 -Author: Ivo Timmermans -Date: Wed Nov 22 17:48:15 2000 +0000 - - Add more checks to ensure that filedescriptors are right in - _execute_script(). - -commit 2ed68134047a19e708c2a2af32c58968835a7043 -Author: Ivo Timmermans -Date: Wed Nov 22 16:19:07 2000 +0000 - - Honor the --localstatedir option to configure, instead of hardcoded /var. - -commit 9e9e1925b901dff87518f0e1534a33e48eab8303 -Author: Guus Sliepen -Date: Tue Nov 21 09:13:59 2000 +0000 - - - Check for NULL tree->delete callback - - Add xstrdup() function - -commit da9a1e8084a9b73306bdbc541ee8af938c3e7754 -Author: Guus Sliepen -Date: Mon Nov 20 23:29:47 2000 +0000 - - - More fixes. - -commit 3a6200c1e39b61b249db3d1f9bcffa77351863bd -Author: Guus Sliepen -Date: Mon Nov 20 22:13:14 2000 +0000 - - - Various small fixes. - -commit 06afd357b0cf4aab778b1ccabbd1be61a9500d10 -Author: Ivo Timmermans -Date: Mon Nov 20 19:56:01 2000 +0000 - - Get rid of all libtool references at once. libtool was only used by - libblowfish, which was superseded by openssl. - -commit 1857b3c97c261dda9978a67d07b315bb3ca68841 -Author: Guus Sliepen -Date: Mon Nov 20 19:41:13 2000 +0000 - - - Proper initialization of rbltree structures. - -commit 408ca91766088b6c2d38e198b0692bf394b41248 -Author: Guus Sliepen -Date: Mon Nov 20 19:12:17 2000 +0000 - - - Integrate rbl trees into tinc. - -commit 9024e01ce649b89d304a4aa5b1d6ef0b56b5a12c -Author: Ivo Timmermans -Date: Mon Nov 20 18:06:17 2000 +0000 - - Also include process.h - -commit 3cc063d23a6e3a23fd01f03b0bc99825c2b13e16 -Author: Ivo Timmermans -Date: Mon Nov 20 18:05:34 2000 +0000 - - More function and header checks - -commit 59aa15d3d1db4e948113f202dd2183f4bb23970d -Author: Ivo Timmermans -Date: Mon Nov 20 18:02:15 2000 +0000 - - Added this release - -commit 8f273f0ee265c75dd8eea65b2f1cd60a79691cd6 -Author: Guus Sliepen -Date: Sun Nov 19 22:12:46 2000 +0000 - - - Small fixes - -commit cc7c078774db955cece9b263022e6c1ca955fc10 -Author: Guus Sliepen -Date: Sun Nov 19 11:05:59 2000 +0000 - - - Deletion also works now. - -commit 3526f1e151b7a189f075d88c9d88cacaece31d02 -Author: Guus Sliepen -Date: Sun Nov 19 02:04:29 2000 +0000 - - - Fixed a lot of small things. Tested everything except deletions. - -commit 4f68e5b6133480478edba0959cb87d4eb149a8e7 -Author: Guus Sliepen -Date: Sat Nov 18 23:22:44 2000 +0000 - - - Fix tree head/tail upon insertion - -commit 880cd6f1a94ef76ebebc5bd96dd26d62e3d829f4 -Author: Guus Sliepen -Date: Sat Nov 18 23:21:01 2000 +0000 - - - Implemented deletions - - Added rbl_foreach() function - -commit 00e5d572621ad5f0263999dbfbfcb11e023bf48b -Author: Guus Sliepen -Date: Sat Nov 18 18:14:57 2000 +0000 - - - Fixed searching - - Insertion implemented - -commit 7fcc0c6415488ed6ce0089a67ab7cfdd5d0d83ca -Author: Guus Sliepen -Date: Fri Nov 17 10:03:02 2000 +0000 - - - Removed stray @INCLUDE@ (how did that get there?) - - Use 0 instead of FALSE - -commit 44cbd13e5248880b074b5068df14a4634204a1d3 -Author: Guus Sliepen -Date: Fri Nov 17 00:56:49 2000 +0000 - - - Simplified do_detach - -commit 2626c641aa714a8d776f1bb16340586d935aa6b1 -Author: Ivo Timmermans -Date: Thu Nov 16 22:13:09 2000 +0000 - - Use proper prototypes. - -commit 5d1145f2c4b3b8261ca0aa0e89a2daf321640f0b -Author: Ivo Timmermans -Date: Thu Nov 16 22:12:23 2000 +0000 - - Move more functions from tincd.c into process.c. - -commit 485f7a5043a4b3345bd02e5063502603550b4c76 -Author: Ivo Timmermans -Date: Thu Nov 16 22:11:40 2000 +0000 - - Delete struct ifr - -commit 30f34015ee11bbe1106c07e381288a702f12dac5 -Author: Ivo Timmermans -Date: Thu Nov 16 18:06:39 2000 +0000 - - New function: xmalloc_and_zero, which initialises the allocated memory - to all zeroes. - -commit 2764532ea72200d0a27ad2d79e6e299c00c62404 -Author: Ivo Timmermans -Date: Thu Nov 16 17:54:29 2000 +0000 - - Move all process-related functions into process.c. - -commit aa755206da4bcce3261ecd5dbfa41570a0155c73 -Author: Guus Sliepen -Date: Thu Nov 16 09:18:38 2000 +0000 - - - Added balanced tree management stuff as well. (It is not finished yet.) - -commit 7f87c3d9134612041d56180ea7fc3e6c37991f6b -Author: Ivo Timmermans -Date: Wed Nov 15 22:07:36 2000 +0000 - - Keep a list of running children, and in each loop in main_loop(), - check if one has exited. - -commit d9ce5a7f3f5eddb193b6a9b5974c7c49eac41ea1 -Author: Ivo Timmermans -Date: Wed Nov 15 22:04:48 2000 +0000 - - List management and manipulation routines. - -commit e118ba0a648000c48d6a401c9b9249a844d6dbcf -Author: Guus Sliepen -Date: Wed Nov 15 13:33:27 2000 +0000 - - Porting to FreeBSD: - - Reorganized and added some #includes - -commit 596e248bc588323cc7ee751286dbcaf677b5c653 -Author: Ivo Timmermans -Date: Wed Nov 15 01:28:21 2000 +0000 - - Let the output from an executed script in execute_script() go to - syslog, with proper error detection. - -commit bb2495e569fb161b42efd633eb1c471b8222b1fb -Author: Ivo Timmermans -Date: Wed Nov 15 01:06:13 2000 +0000 - - Use the HAVE_OPENSSL_xxx_H defined from m4/openssl.m4 during - configure. - -commit 6fb4a5b6be5628ece9b391b46e7858fdf5957a80 -Author: Ivo Timmermans -Date: Wed Nov 15 01:02:30 2000 +0000 - - Also check for sha.h. - -commit 8eb60d0ccde2f1de6fd917db7300e537f271783e -Author: Ivo Timmermans -Date: Wed Nov 15 00:57:26 2000 +0000 - - Also check for rand.h and err.h. If any of these files does not - exist, try the next alternative path. - -commit c5c8e99afd3fae3868f20b5c7a4f8754498b39ad -Author: Ivo Timmermans -Date: Tue Nov 14 23:18:19 2000 +0000 - - Get rid of the annoying empty line - -commit c467ee02d3ef8bed7ec2cc52cb1527ec60cdc93a -Author: Ivo Timmermans -Date: Tue Nov 14 23:02:08 2000 +0000 - - Oops, small error. - -commit 9ddb37cee0f754ef88a55f692a508010fe18c782 -Author: Ivo Timmermans -Date: Tue Nov 14 22:57:19 2000 +0000 - - Better checks for OpenSSL. I think it can now detect almost all conceivable installations. - -commit 72c3776d6ac103fa25d216c42847ecba3a4f58e5 -Author: Ivo Timmermans -Date: Mon Nov 13 22:29:22 2000 +0000 - - Identify version as 1.0pre4-cvs - -commit 5344832be1126967ff340cf6bd270a377bb8e487 -Author: Ivo Timmermans -Date: Mon Nov 13 22:01:27 2000 +0000 - - Add a check for openssl that accepts explicit file locations. - -commit 5b74909ea070fbd482340dc42193e33366a9dddb -Author: Ivo Timmermans -Date: Thu Nov 9 21:33:18 2000 +0000 - - Add prototype for destroy_queue - -commit 6e27618708233998db7e5886ed9afaa21bb9d938 -Author: Ivo Timmermans -Date: Thu Nov 9 21:29:58 2000 +0000 - - Updates, updates - -commit a91eae538d9cff8aed399a175c0bbc7d744cd22a -Author: Ivo Timmermans -Date: Thu Nov 9 20:59:35 2000 +0000 - - Bop version number to 1.0pre3-1 - -commit e65a93053cca3f8aebf63094cf160835c3108e25 -Author: Ivo Timmermans -Date: Thu Nov 9 20:42:16 2000 +0000 - - Wrapped text to 70 (72?) columns for easy reading - -commit 4310b17be9cefcc1814ddef471e4c5cd8f9f867e -Author: Ivo Timmermans -Date: Thu Nov 9 20:41:13 2000 +0000 - - Final release notes added, also edited release notes for 1.0pre2 to what the announcement on the mailing list looked like. - -commit 16847ea255fa8a7c0ed922af80a2f36b7bdf4b3b -Author: Guus Sliepen -Date: Wed Nov 8 20:52:37 2000 +0000 - - - Make checkpoint tracing a compile time option (off by default) - -commit 55d7b5a2bb1df6f55f0a93e9cfed77c1da337588 -Author: Guus Sliepen -Date: Wed Nov 8 18:05:06 2000 +0000 - - - Add Jamie :) - -commit 5055e1dedc9fe984c497448c1b2ffc4afdf18aa3 -Author: Guus Sliepen -Date: Wed Nov 8 17:56:34 2000 +0000 - - - Applied Jamie Brigg's patch (close sockets after error) - -commit 74326df7adc514798565df0a8719421adbb5fef3 -Author: Guus Sliepen -Date: Wed Nov 8 00:20:06 2000 +0000 - - - Fixed --config - - Show warning when both netname and config directory are given. - -commit f8f1007bf469d44480d95d0d78ddc156d00e059f -Author: Guus Sliepen -Date: Wed Nov 8 00:10:50 2000 +0000 - - Porting to SunOS 5.8: - - More #includes Linux doesn't seem to need - - Don't do unsetenv() on SunOS - - Use a replacement asprintf() in case the OS doesn't support it - It now compiles properly under SunOS. - -commit 56bd0864e4c5680fee59af48228b1ec3fb97b57b -Author: Guus Sliepen -Date: Tue Nov 7 22:33:33 2000 +0000 - - Porting to SunOS 5.8: - - Include all header files necessary - - Check for flock() function - -commit 7d0f82bd4b7044a5151835e25e830fd28dfaaebd -Author: Guus Sliepen -Date: Tue Nov 7 22:02:14 2000 +0000 - - - Open UDP connection for all known hosts. Comments please. - -commit f95cc86d0c14ca4c47e5459af4bb6d1170baa9f5 -Author: Guus Sliepen -Date: Tue Nov 7 21:43:28 2000 +0000 - - Changed execution of tinc-up: - - Do not free() strings that have been putenv()d, see man page of the - latter. - - Do not set IFNAME anymore, it appears that the ioctl to get the name of - the interface does not work at all. Since it is set to NETNAME in case - of tun/tap and it is known beforehand in case of ethertap, there is no - need for it anyway... (though it would've simplified things). - -commit efc3a2a466937da942afc84dde080ba8b1731140 -Author: Ivo Timmermans -Date: Sun Nov 5 02:19:58 2000 +0000 - - Build-Depends on gettext - -commit 698191fd2f512f3618e2d60592fcd57cd750b965 -Author: Guus Sliepen -Date: Sat Nov 4 22:57:33 2000 +0000 - - - Prepended config_ to all configuration option names, because it confused - everything (including myself). - - Use connection oriented UDP sockets for both incoming and outgoing - packets. - -commit afc05797077641baa33b024ffeaafd6cad3ff7a7 -Author: Guus Sliepen -Date: Sat Nov 4 20:44:28 2000 +0000 - - - Simplified ping mechanism. - -commit 2191d894bfd615e8fa7857d031ea630edc12a854 -Author: Ivo Timmermans -Date: Sat Nov 4 17:29:45 2000 +0000 - - Build-depends on libtool - -commit 5019dd879177b5ab9413e5c0aa72a15d0e585acf -Author: Guus Sliepen -Date: Sat Nov 4 17:09:10 2000 +0000 - - - Check for packets that are looping back. - -commit 20dd5aff4d2898d8b59f371671cc110b870fa09c -Author: Ivo Timmermans -Date: Sat Nov 4 17:04:17 2000 +0000 - - Updated Dutch translation - -commit 3f177e9bf02b6121055414a2cc7fd3f4cff01cba -Author: Ivo Timmermans -Date: Sat Nov 4 17:01:55 2000 +0000 - - Add route.c to the list of source files. - -commit ac47586552710425417ed80878f8f853c313b421 -Author: Guus Sliepen -Date: Sat Nov 4 16:54:21 2000 +0000 - - - Forward keys in hex notation, not as binary data. - -commit 3f8f067e8b559366b9b41dee6a4312702c82042f -Author: Guus Sliepen -Date: Sat Nov 4 16:39:19 2000 +0000 - - - Don't forget to set packet cipher for added hosts. - -commit 433858d410c1fedf8d2a5f2b4ecd7c980dd79dd2 -Author: Guus Sliepen -Date: Sat Nov 4 15:34:07 2000 +0000 - - - connlist.c added to translation - -commit 15246df85d6171c92478541a835effb96d6085c4 -Author: Ivo Timmermans -Date: Sat Nov 4 15:32:05 2000 +0000 - - In execute_script: - - add an environment variable NETNAME. - - chdir to the configuration directory before execing the script. - -commit 69618c01385eb7226cd6eab0918d1f30b0ed6c66 -Author: Ivo Timmermans -Date: Sat Nov 4 15:18:58 2000 +0000 - - Do not include the passphrases directory - -commit 417f36a07990ff9bc7de7d4e63e57146bef0dd75 -Author: Guus Sliepen -Date: Sat Nov 4 15:17:02 2000 +0000 - - - Removed manpage for no longer existing genauth. - -commit 3d7189a444fe3efed58dc93a071129007041aebf -Author: Guus Sliepen -Date: Sat Nov 4 14:52:40 2000 +0000 - - - Resolve scriptname after fork() - -commit d38772ebc42f5ad1d946ee89d955f5d43bb2fe8c -Author: Ivo Timmermans -Date: Sat Nov 4 14:16:46 2000 +0000 - - Use putenv() instead of clumsy do-it-yourself in execute_script. - -commit f83803c1bf6557d5af93982e7cd987e151eba401 -Author: Ivo Timmermans -Date: Sat Nov 4 13:25:15 2000 +0000 - - Small change to the way the environment is copied. - -commit ed0bf283e37642f9f7673f664713a16d916bd70f -Author: Guus Sliepen -Date: Sat Nov 4 11:49:58 2000 +0000 - - - Removed even more warnings. - -commit dc699f8b1265deb7606d553e36326527dbd29746 -Author: Guus Sliepen -Date: Sat Nov 4 10:37:27 2000 +0000 - - - Removed unused MAC strip/add functions. - -commit 5065ea32c32e27478d93c00a1bba0c812b7a2b8c -Author: Ivo Timmermans -Date: Fri Nov 3 22:35:12 2000 +0000 - - Warnings removal pass: always include config.h first; add a few - prototypes in the header files. - - This also fixes a few lint errors/warnings. - -commit 73aa7fbf7e1b623398d1bc1493f567ce4d846f22 -Author: Ivo Timmermans -Date: Fri Nov 3 22:33:16 2000 +0000 - - Run the scripts tinc-up and tinc-down from a separate function, which - sets the environment as it should be and checks for errors. - -commit 4ad1e382d6f10acf94ce59d85b80925cee7553a6 -Author: Ivo Timmermans -Date: Fri Nov 3 22:31:55 2000 +0000 - - Save the environment on startup. - -commit 7612c6da3890ce5a0730e4dfde9d5ba07bdbf5b3 -Author: Ivo Timmermans -Date: Thu Nov 2 23:02:49 2000 +0000 - - Minor cosmetic change. - -commit 6a10e42f734e8bec9848a11e73bc2a8211a9f401 -Author: Ivo Timmermans -Date: Thu Nov 2 22:51:16 2000 +0000 - - - If necessary, patch po/Makefile.in from po-Makefile.in.in.diff to - get DESTDIR installation (required to get locales installed - correctly). - - Use dh_perl to get accurate perl dependencies. - -commit ef12849c1a03b3aaf85dd46786d6631f66b104bd -Author: Ivo Timmermans -Date: Thu Nov 2 22:11:18 2000 +0000 - - Oops, and include doc-base.tinc (new file). - -commit 5672ddd6cb9116420a1904f7741fdbed89c2ec54 -Author: Ivo Timmermans -Date: Thu Nov 2 22:10:09 2000 +0000 - - Don't include shlibs, as it no longer exists. - -commit 013fcb0e9f9c0222f4f63ddf42a2f25bfc4a5546 -Author: Ivo Timmermans -Date: Thu Nov 2 22:05:36 2000 +0000 - - Changed a few messages wrt. system calls; updated and changed the Dutch translation a bit. - -commit c444305c0bb965aa515a503406844ceeb483c285 -Author: Ivo Timmermans -Date: Thu Nov 2 21:43:03 2000 +0000 - - Mention fileutils, add a pointer to THANKS for more details - -commit 84c842def74c5d0e9c4a69e4f584fe9eb66eb728 -Author: Ivo Timmermans -Date: Thu Nov 2 21:41:53 2000 +0000 - - Change wsl to Wessel's name and email address in the ChangeLog creation - -commit 5b6815751e581bedd64bfc63aea5b42c746bbceb -Author: Ivo Timmermans -Date: Thu Nov 2 21:40:33 2000 +0000 - - More exhaustive list of changes - perhaps it can be worded differently? - -commit e954fc8f0c731e7116fd27f38c176b83cca519f7 -Author: Ivo Timmermans -Date: Thu Nov 2 21:39:57 2000 +0000 - - Changed `I' to `We' - small change, lots of difference :) - -commit 3db3a41667f90ce74bfd0197fc867cc71a087e50 -Author: Ivo Timmermans -Date: Thu Nov 2 21:38:55 2000 +0000 - - Only check for linux/if_tun.h once - -commit 1b11bcb0128ca65580cbf28ffb16078c81e6d678 -Author: Ivo Timmermans -Date: Thu Nov 2 21:34:45 2000 +0000 - - Added a perl example to turn an IP address into a MAC address. - -commit cadf81fe67aed424504758865c2ea2bb263c76fb -Author: Ivo Timmermans -Date: Thu Nov 2 21:26:51 2000 +0000 - - Do not include $(top_srcdir)/cipher, it does no longer exist. - -commit fd32d771a84765281ea4ab8a5d9dbf5cebfa2911 -Author: Ivo Timmermans -Date: Thu Nov 2 20:29:03 2000 +0000 - - - Synchronized changelog with the package's changelog. - - Changed maintainer email address. - - New file doc-base.tinc. - - Better Build-Depends and Depends lines. - -commit a13d9c9da7434154b33e666c2236844011b87d46 -Author: Ivo Timmermans -Date: Thu Nov 2 20:25:35 2000 +0000 - - This file is no longer needed. - -commit 59528ec892e8b9a599f2b39bf432a3d842e963fe -Author: Guus Sliepen -Date: Tue Oct 31 16:22:49 2000 +0000 - - Removed config file parsing and interface setup. This will be handled by - the tinc-up and tinc-down scripts from now on. - -commit af565d00220b7536b9987c48e2a71459b45027b4 -Author: Guus Sliepen -Date: Tue Oct 31 16:10:17 2000 +0000 - - - Update. - -commit b4c1d4e2d3287acd7ca438455c64e50a2828ad24 -Author: Guus Sliepen -Date: Mon Oct 30 10:19:06 2000 +0000 - - - Fixed some spelling mistakes and terminology here and there. - -commit 4811afa073c871f2a52dfd5139bd0171046365eb -Author: Guus Sliepen -Date: Mon Oct 30 00:22:54 2000 +0000 - - - Small cleanups - - Updated dutch translation - - Updated man pages - -commit b7d4d4c17712e0bb9ee8bd497a2f525b79d5f40d -Author: Guus Sliepen -Date: Sun Oct 29 22:55:15 2000 +0000 - - - Finishing touch: encrypt the meta connections - -commit ec12269355f7979fdc0783dc15d109832f1e83cd -Author: Guus Sliepen -Date: Sun Oct 29 22:10:44 2000 +0000 - - - Use CFB mode for encrypting packets: it works and we don't need padding. - -commit cea3d8f3056d3c6aaaef473443240b8470c8ea2d -Author: Guus Sliepen -Date: Sun Oct 29 10:39:08 2000 +0000 - - - Small fixes - - Do proper key exchange - - Encrypt packets - it works, but there is something wrong with the MAC - header after decryption... - -commit 8fa9bc017d89b53798903df3fa98311067d4de90 -Author: Guus Sliepen -Date: Sun Oct 29 09:19:27 2000 +0000 - - - Removed old encr stuff - -commit a26d371d0df3bee1bdc6e9d7046e949ee29e6de7 -Author: Guus Sliepen -Date: Sun Oct 29 02:07:41 2000 +0000 - - - Updated dutch translation. - - Shutdown properly. - -commit e8391bd49975aa29fa62d6ae1d2d2ee398e0eb3e -Author: Guus Sliepen -Date: Sun Oct 29 01:27:23 2000 +0000 - - - Moved connlist stuff to the proper header file. - -commit 2689690dc37c384c4a022d03ab80f2cfb7fb9553 -Author: Guus Sliepen -Date: Sun Oct 29 01:08:09 2000 +0000 - - - Enforce correct order of authentication requests - -commit 3b9802a542f1fa439321d3386763ec33989194b5 -Author: Guus Sliepen -Date: Sun Oct 29 00:46:43 2000 +0000 - - - Hit people who can't figure out subnet address/mask pairs with a - (clue)bat. - -commit 7398002ade1397bd857953f009f4aed65ffc9218 -Author: Guus Sliepen -Date: Sun Oct 29 00:24:31 2000 +0000 - - - Fixed ans_key_h - - Removed tapsubnet configuration option. - -commit 35932fe6c8cb481eb687f98424776ce429570c21 -Author: Guus Sliepen -Date: Sun Oct 29 00:02:20 2000 +0000 - - - Very big cleanup. - -commit db21f015161aac244ec5600c4d0ff685549892c2 -Author: Guus Sliepen -Date: Sat Oct 28 21:52:22 2000 +0000 - - - Override destination ethernet address on incoming packets with - FE:FD:00:00:00:00 - -commit 8738c007b15eea024bc4ca6ee0f972b2f5bf259f -Author: Guus Sliepen -Date: Sat Oct 28 21:25:21 2000 +0000 - - - Fixed offsets when reading/writing from/to tap device - -commit f25868fd2b58bc0b350a5cfaf342480f28f804cf -Author: Guus Sliepen -Date: Sat Oct 28 21:05:20 2000 +0000 - - - Lots of small fixes - - Exchange subnets on acknowledgement of connection - - Do proper lookup when incoming packets from tap - - off-by-a small number-error when reading/sending tap packets - -commit ba6b8005ebe3a53877590c242ff581dc5dee5eae -Author: Ivo Timmermans -Date: Sat Oct 28 19:34:53 2000 +0000 - - Skip the check for Linux kernel sources - -commit d47d5932a3bbc4940aa6453ebfe617ef330783c8 -Author: Guus Sliepen -Date: Sat Oct 28 16:41:40 2000 +0000 - - - Updated subnet list handling. Subnets are added to two lists now, the - owner's list and a global list. It is all fucked up but it probably - works anyway, good enough for pre3 :). - -commit 9c2f805255fa36b05e8fe9391f639581d938b653 -Author: Guus Sliepen -Date: Tue Oct 24 15:46:18 2000 +0000 - - - Lots of little stuff modified - - Succesfully reads in subnets from host config file now and adds them to - the list. - -commit 60401d99b18ae01d91ca65faf8d2b32fac2b4474 -Author: Ivo Timmermans -Date: Mon Oct 23 21:56:56 2000 +0000 - - Oops, echelon change committed to cabal... :) - -commit c46e84837d1c84a8590e0e3507227670368884a7 -Author: Guus Sliepen -Date: Mon Oct 23 13:52:54 2000 +0000 - - - route.c will contain the routing logic. - -commit 76d794eaf7c1664a47f4d0080fcd80e4a551740b -Author: Ivo Timmermans -Date: Sun Oct 22 13:47:41 2000 +0000 - - read_server_config: Check for result of read_config_file. - -commit 56d8e862409ae91c63a27968b01a48a94aafb205 -Author: Ivo Timmermans -Date: Sun Oct 22 13:37:15 2000 +0000 - - Include linux/sockios.h and net/if.h anyway, regardless of the value of HAVE_TUNTAP. - -commit 52b842f8076d507d3a6ea07045d085ae21d1aa10 -Author: Guus Sliepen -Date: Sat Oct 21 11:52:08 2000 +0000 - - - Fixed all debug levels. - - Seed PRNG before generating a challenge - - Strange thing in challenge decryption: it fails if first bit is set!? - -commit 73f7efddd723b25c1477ec1139dc7211307ff660 -Author: Guus Sliepen -Date: Fri Oct 20 19:46:58 2000 +0000 - - - Removed last reference to genauth from Makefile.am - - Tinc spawns tinc-up and tinc-down scripts which can be used to configure - the network device. The environment variable IFNAME is set to the name - of the interface. - -commit fba19c30c92d39e74f5fd5594053793b036f30f4 -Author: Guus Sliepen -Date: Fri Oct 20 16:49:20 2000 +0000 - - - Made Makefile.am stub for doc/es/ - - Merged genauth into tincd - - Updated dutch translation - -commit 97ec5685b92ea727fe8f8b4bb8cf289a20f8580b -Author: Ivo Timmermans -Date: Fri Oct 20 16:44:32 2000 +0000 - - Generalized list and hash handling functions - -commit 699e159a7a1711034f1d16d68ad1974a82e12dfc -Author: Ivo Timmermans -Date: Fri Oct 20 16:43:13 2000 +0000 - - New function: xalloc_and_zero() - -commit 4059151732afb7d8fb52121d80e54f2ee325d30e -Author: Ivo Timmermans -Date: Fri Oct 20 16:42:22 2000 +0000 - - Add all the new files to the sources list for the utility library - -commit 9f64499e40a95a8c05c82924219517aa017fc411 -Author: Guus Sliepen -Date: Fri Oct 20 15:34:38 2000 +0000 - - - tinc now really does public/private key encryption! It even works, whee! - -commit 71f05ff8956cb2e62181fcef763709b0de8faa68 -Author: Ivo Timmermans -Date: Thu Oct 19 20:56:49 2000 +0000 - - Generalized error handling functions - -commit 95f4e8620ef8e2cdec1cc3b2ccb8cc8e3ce94e40 -Author: Ivo Timmermans -Date: Thu Oct 19 20:39:04 2000 +0000 - - Add check for the syslog function - -commit 430e14162918864f9f18aad0ec0badc1ccc3e01f -Author: Ivo Timmermans -Date: Thu Oct 19 17:29:22 2000 +0000 - - Changed changelog - -commit d5fd1344e668da0bc8536e798f347041d5377843 -Author: Guus Sliepen -Date: Thu Oct 19 14:42:00 2000 +0000 - - - Seed the PRNG using /dev/random before generating the keys. - -commit 30df5e95dbe585c6076d743d3771a42ad7c78590 -Author: Ivo Timmermans -Date: Wed Oct 18 20:12:10 2000 +0000 - - Bring head revision up to date with cabal (try #3) - -commit 571cfb5846c710a0a3cdbdddce8936f6b34f1cf1 -Author: Ivo Timmermans -Date: Wed Oct 18 19:44:11 2000 +0000 - - Get the head revision up to date with cabal - -commit e75315dae609f32041ca5ed939fd2a1b69d32d3e -Author: Ivo Timmermans -Date: Tue Oct 17 10:15:20 2000 +0000 - - Don't declare cp_file and cp_line in xmalloc() - -commit 31c543ad0fa1d19667a03a9bd183c668def23da0 -Author: Ivo Timmermans -Date: Tue Oct 17 10:14:25 2000 +0000 - - Process subdir es/ - -commit 20301888b7a0a206119d2cfc48ccf1a667bb4add -Author: Guus Sliepen -Date: Mon Oct 16 19:04:47 2000 +0000 - - - More fixing. Tinc daemons can now even create activated connections. - -commit bb3d18d56fa0dd2bc5146d0a0044b6ef0880bdb4 -Author: Guus Sliepen -Date: Mon Oct 16 16:33:30 2000 +0000 - - - Fixing little things - - Two tinc daemons can connect to eachother now (but they disconnect right - after the ACKs). - -commit 6e32b870ee127555888a115163922362c99009f9 -Author: Ivo Timmermans -Date: Mon Oct 16 11:35:10 2000 +0000 - - Output doc/es/Makefile - -commit baeac83bf465a47d46082e1de40ea14dcf1d39af -Author: Guus Sliepen -Date: Sun Oct 15 20:30:39 2000 +0000 - - Corrected #ifdefs for tun/tap support. - -commit 782171fd2c59b7cc5568d2d4b33ce041834710ec -Author: Ivo Timmermans -Date: Sun Oct 15 20:21:27 2000 +0000 - - Really #include the if_tun.h files now - -commit 8a54c51238672abd7a72c1dbdc7d17b9956a0d35 -Author: Ivo Timmermans -Date: Sun Oct 15 20:13:55 2000 +0000 - - Linearized checks for if_tun.h - -commit e5130495d7d4083d58ab76c26001aa27f5fc13db -Author: Ivo Timmermans -Date: Sun Oct 15 19:53:15 2000 +0000 - - Wrap the tun/tap code in #ifdef HAVE_TUNTAP - -commit 3b455b8f318528206b08121f5ce93d16e4ea01df -Author: Ivo Timmermans -Date: Sun Oct 15 17:26:31 2000 +0000 - - Add checks for the presence of the universal tun/tap device driver. - -commit 85adeef21275633b78a234b2660cbe3bc9dd2c33 -Author: Guus Sliepen -Date: Sun Oct 15 00:59:37 2000 +0000 - - - The daemon actually runs now (somewhat) - - Added support for tun/tap driver (autodetect!) - - More sophisticated checkpoint functionality - - Updated dutch translation - -commit 97ce045189e330e121873d1b4be1959c60062cbb -Author: Ivo Timmermans -Date: Sat Oct 14 22:22:06 2000 +0000 - - Add CVS id lines - -commit 2e159d0139e77041ad82e96bf0abef6aaf64a258 -Author: Ivo Timmermans -Date: Sat Oct 14 22:17:29 2000 +0000 - - Fix `Requirements'-section for GMP and OpenSSL libraries. - -commit 1d5bb49f261b4346b5a440ae6bbf58fe391ea46e -Author: Ivo Timmermans -Date: Sat Oct 14 22:00:09 2000 +0000 - - Update Depends lines to reflect the dependencies on OpenSSL - -commit e9635ae38e0e2e3eb92568a1e234f8348856dd69 -Author: Guus Sliepen -Date: Sat Oct 14 17:04:16 2000 +0000 - - - Second fixing-things pass: it even links now. - - Lots of FIXME comments added to the source code. - -commit 6a8c2e346e6125e58aab428e6730c18a949abe12 -Author: Ivo Timmermans -Date: Fri Oct 13 23:34:56 2000 +0000 - - Don't look for GMP header files - -commit f18e30dab3c208fd353af11e365791035534f444 -Author: Ivo Timmermans -Date: Fri Oct 13 23:30:11 2000 +0000 - - Updated new requirements, pointers to the manual - -commit a96f2f0fc8a02593d4cda5976df3c76fc5c99eae -Author: Ivo Timmermans -Date: Fri Oct 13 23:29:35 2000 +0000 - - Link with OpenSSL, forget libGMP - -commit 183a8edd22ba4bc682392c73ae02fc9e121eda68 -Author: Guus Sliepen -Date: Wed Oct 11 22:01:02 2000 +0000 - - - Fixing-things pass: every source file compiles into an object file now, - but linking tincd does not work yet (must link with openssl libs and - define some missing functions). - -commit 6e39481d8f2406e60b5e329ace08b5a005d5cc43 -Author: Guus Sliepen -Date: Wed Oct 11 13:42:52 2000 +0000 - - - Generalized config file parsing to support multiple configuration trees. - -commit 451e9e3e7a968151de541de68603a01f0922b415 -Author: Guus Sliepen -Date: Wed Oct 11 12:07:27 2000 +0000 - - - Changed genauth to produce rsa keypairs instead of random passphrases. - -commit 950fb8e916b0e248dcaa72c96859acd6046683aa -Author: Guus Sliepen -Date: Wed Oct 11 10:35:17 2000 +0000 - - Big and bad commit of my current tree... - - Added seperate file for connection list handling - - Updating everything to use connlist, meta and subnet files - - Removed dependency on libgmp - - Lots of other stuff... - -commit 73d0dcfcc1019ee745a422982b4e3ede9d59dd91 -Author: Guus Sliepen -Date: Wed Oct 4 15:09:57 2000 +0000 - - Removing cipher directory (all will be covered by OpenSSL). - -commit 2228b16159a7aff64e6559ee1635716154e67fe6 -Author: Guus Sliepen -Date: Sun Oct 1 03:21:49 2000 +0000 - - - Added subnet handling code - - Other small changes to header files - -commit 676b1c0ea111406eb94a74ae12878dfd5ad9f56d -Author: Ivo Timmermans -Date: Wed Sep 27 20:32:29 2000 +0000 - - Many updates, parts rewritten, added, shuffled around. - -commit c78a204f06182f50b0812c8e4fef6163e82097bf -Author: Guus Sliepen -Date: Tue Sep 26 14:06:11 2000 +0000 - - - Added meta.c which contains functions to send, receive and broadcast - metadata. It will also handle encryption and decryption, and possibly - compression and checksumming. - - Moved request dispatcher to protocol.c. - -commit 2c412009e5805f04c650889b19fcb38531f2aa50 -Author: Guus Sliepen -Date: Mon Sep 25 20:08:50 2000 +0000 - - - Very detailed example of the authentication phase. - -commit 361690b18c1f5464db7b9cef235c648784780dfb -Author: Guus Sliepen -Date: Fri Sep 22 16:20:07 2000 +0000 - - - Removed options "string" stuff. It was a bad idea... - - free() everything that is allocated. - -commit 5afc1e98f436c4a2ed5da4b64293275b09632c79 -Author: Guus Sliepen -Date: Fri Sep 22 15:06:28 2000 +0000 - - - Severe code reduction and simplification of challenge requests - - "Finished" [add|del]_subnet_h - - Added lots of sanity checks to [add|del]_host_h - -commit 5d0b3516d5e8a46ca2268bdb32657b72295501ec -Author: Guus Sliepen -Date: Sun Sep 17 21:42:05 2000 +0000 - - - Updated authentication scheme. - - Removed all trailing spaces from all lines. - - Added things to add_ and del_subnet_h. - -commit 84f210edd9e72a65ca8b034a0d3bbc12e506c580 -Author: Guus Sliepen -Date: Sun Sep 17 20:11:59 2000 +0000 - - - Included authentication scheme from protocol.c - - Added a few comments about the symmetric cipher. - -commit 2863134a4113b7805a662f45a21a1be0ae9606cb -Author: Guus Sliepen -Date: Sun Sep 17 19:57:39 2000 +0000 - - Added document about the used cryptographic algorithms and the reasons - behind them. Feel very free to comment on this! - -commit 33a5b4547141c11b5128d9f4863fcf6cf8e33452 -Author: Ivo Timmermans -Date: Sun Sep 17 10:28:57 2000 +0000 - - Added Spanish translation of the docs by Matias Carrasco - -commit 7f3ab38c222809b15da2fe8dd655d35432eaafe0 -Author: Ivo Timmermans -Date: Fri Sep 15 12:58:40 2000 +0000 - - Second round of fixes - -commit ed397b6ac676329b237e219c806143cccf456b3c -Author: Ivo Timmermans -Date: Thu Sep 14 21:51:21 2000 +0000 - - First round of needed fixes after the overhaul - -commit 296171d115614d61480d896cd77898f5393c191d -Author: Ivo Timmermans -Date: Thu Sep 14 14:34:38 2000 +0000 - - New directive: Name. - -commit d335c6d0d7328fd86154dc60b22deb7953ab0228 -Author: Ivo Timmermans -Date: Thu Sep 14 14:32:34 2000 +0000 - - Added some structures and types that are needed for the overhaul. - -commit c04c84c98055c6b9e9e7890d3992648a3b715a1a -Author: Guus Sliepen -Date: Thu Sep 14 11:54:51 2000 +0000 - - - Lots of small changes. - -commit cd6695df82c55454a3f5b644f5c20a8ed31e7c97 -Author: Ivo Timmermans -Date: Mon Sep 11 11:40:46 2000 +0000 - - Better checks for SunOS libraries - -commit 9c75350ac6c14886195b6d368af2f118fd5d60e0 -Author: Guus Sliepen -Date: Mon Sep 11 10:05:35 2000 +0000 - - - Fixed modulo in keylength check - - Updated header file to reflect new protocol code - -commit 76b5f255c6cb0c5dfb5a870c371ec6f7c7879bb2 -Author: Guus Sliepen -Date: Sun Sep 10 23:11:37 2000 +0000 - - - Some key exchange stuff. (Last commit before going to bed.) - -commit 675ed08a71ec28d8ae99e10e993d5c7cb717f017 -Author: Guus Sliepen -Date: Sun Sep 10 22:49:46 2000 +0000 - - - Lots of functions added for the new protocol. - -commit 9926dae4646a96ee647a2ca7d728e91600dd1cca -Author: Ivo Timmermans -Date: Sun Sep 10 21:57:11 2000 +0000 - - Add Guus' name and shift out old protocol requests - -commit 74157d3f4501f4d1ec913a986b7167d2b847e41e -Author: Ivo Timmermans -Date: Sun Sep 10 18:37:46 2000 +0000 - - Correct filenames for passphrases given in the example - -commit 6b9ec9ed1e818d5e50dda4418ffb4d02c898bcba -Author: Guus Sliepen -Date: Sun Sep 10 16:15:35 2000 +0000 - - - Added more function skeletons for the new protocol. - -commit 28cc30159565a7eda4f66215a5994d84b46b47ad -Author: Guus Sliepen -Date: Sun Sep 10 15:18:03 2000 +0000 - - - New protocol. Will break everything else for now. - -commit 7884d3ecaf78006b3f288d99f10ef541fc97087e -Author: Ivo Timmermans -Date: Sun Sep 10 15:16:07 2000 +0000 - - Support for -lsocket and -lnsl on SunOS - -commit 14554e6f421e881b01be20879e9279545f375154 -Author: Ivo Timmermans -Date: Sun Sep 10 15:15:38 2000 +0000 - - Include openssl/blowfish.h - -commit 45ea3ca432a031ff1b8072d934709aadaae12534 -Author: Ivo Timmermans -Date: Sun Sep 10 15:07:41 2000 +0000 - - Updated text, removed protocol flowchart - -commit ae17572e6b94c6e7a2123ddeb45bf66d389ac7a0 -Author: Ivo Timmermans -Date: Sun Sep 10 15:05:45 2000 +0000 - - Link with OpenSSL crypto libraries instead of own blowfish library - -commit 4dde583bc91985c3ff19ac1d1f1bc791b50658ff -Author: Guus Sliepen -Date: Wed Sep 6 11:49:05 2000 +0000 - - - Use strerror() instead of sys_errlist[] for increased portability - (Needed for SunOS) - -commit 66e535a729dd5a9e45600ab74dc19c2b4062ee96 -Author: Ivo Timmermans -Date: Sun Aug 27 11:05:47 2000 +0000 - - Changed CVSROOT path in `make ChangeLog' - -commit 39e159fbe6bbffb3229542258f956fc412bd871c -Author: Guus Sliepen -Date: Tue Aug 22 14:55:04 2000 +0000 - - Fix rules (thanks to Laurence) - -commit 47992fe59f4c1b4116e4872d59251b143edc6763 -Author: Ivo Timmermans -Date: Mon Aug 21 20:35:47 2000 +0000 - - Added a rule to create an rpm - -commit d9af4f32330a495789d8eecdabbbb49928f074a7 -Author: Guus Sliepen -Date: Mon Aug 21 12:50:15 2000 +0000 - - Updated tinc.conf manual. - -commit 94a32c4b2d2ff5d4bb1376fe5ec96c6dec55f630 -Author: Ivo Timmermans -Date: Sun Aug 20 23:08:17 2000 +0000 - - Also chomp $VPNMASK - -commit 861e808fef1f6796d837215f9ad135fb4cb50f5c -Author: Ivo Timmermans -Date: Sun Aug 20 23:07:18 2000 +0000 - - (Quoting Laurence Lane:) - - The prefix is correctly set for /usr, but is - overridden with the current make install. DESTDIR is the clean way to - relocate the installation into the debian/tmp build dir. - -commit d3f41b803bf3c38910f24f1f268f182466723149 -Author: Guus Sliepen -Date: Fri Aug 18 14:45:38 2000 +0000 - - Updated the manual: - - incorporated comments from Stefan Hartsuiker - - updated configuration variables section - - added some text about key types - -commit 5c78e158d414595ab32399645678a43bb4469be6 -Author: Guus Sliepen -Date: Fri Aug 18 11:17:09 2000 +0000 - - Commented on some size calculations. - -commit d2c062a0a440d2871939b4ffdc2dbb137a4d45e7 -Author: Guus Sliepen -Date: Thu Aug 17 17:22:01 2000 +0000 - - Ran update-po and updated dutch translation. - -commit 3831f51a53088bfcc1d148fd54b3083afe7fde32 -Author: Guus Sliepen -Date: Thu Aug 17 16:51:08 2000 +0000 - - Fixed all sprintf() spl01ts. - -commit 9acd4379f705edc8b736e21b9011434e63f7dd95 -Author: Guus Sliepen -Date: Wed Aug 9 14:02:16 2000 +0000 - - - Added two extra configuration options, Interface and InterfaceIP, to - bind the listen socket to a network device or a specific IP. - -commit f6d79366b3efaef0a458717aac5e6754630dd434 -Author: Guus Sliepen -Date: Wed Aug 9 09:34:21 2000 +0000 - - - Reinstated O_NONBLOCK for meta socket - - Set SO_KEEPALIVE on meta socket - -commit 3cfc9424f255c26f2a7775b6fa059f1e3e47a76e -Author: Guus Sliepen -Date: Tue Aug 8 17:07:48 2000 +0000 - - - Moved TCP packet reception to meta handler: less kludgy and less buggy! - -commit e092d15be17db1d69c37f2aba46c66e03631c099 -Author: Guus Sliepen -Date: Tue Aug 8 14:54:57 2000 +0000 - - - Added date/time of build and protocol number to --version output. - -commit ff87f385c3a81499eff6b848aed8548cf6e5132e -Author: Guus Sliepen -Date: Tue Aug 8 13:47:57 2000 +0000 - - Removed calling add_queue for tcponly packets. - -commit ac73c72488dd8b33464fac1f392e89df48f7a23b -Author: Guus Sliepen -Date: Tue Aug 8 08:48:50 2000 +0000 - - Fixed PACKET read loop. - -commit b6997b0050e78a2f2e517beba3ff01d9232b3d1f -Author: Guus Sliepen -Date: Mon Aug 7 16:27:29 2000 +0000 - - - Lots o' buglets fixed (-Wall helps) - - Made TCPonly work :) - -commit fdc6a2f106315cd9ed22943d8c0bd279631e66b4 -Author: Guus Sliepen -Date: Mon Aug 7 14:52:16 2000 +0000 - - - Added experimental hackish tunneling-over-TCP support. - Just use TCPonly = true in the configuration file. - -commit 42455e97a057fb4386f9d8fb2f8963b2ec6ddf24 -Author: Guus Sliepen -Date: Sun Jul 2 13:40:57 2000 +0000 - - - Fixed typo. - -commit b1ecbf977722ec473fc8007acd39eb0de581de1a -Author: Guus Sliepen -Date: Sun Jul 2 13:36:18 2000 +0000 - - - Delayed address resolving for ConnectTo lines in configuration file to - allow DynDNS to work without restarting tincd. - -commit 6642ec2ea4e97a2fb3e737653ab1b9351ac759e9 -Author: Guus Sliepen -Date: Sun Jul 2 12:48:04 2000 +0000 - - - Updated THANKS file - -commit e0de803c7e80621600409a0c760241a3d97617bd -Author: Ivo Timmermans -Date: Sun Jul 2 12:41:03 2000 +0000 - - Include the Spanish translation in the distribution/build process. - -commit 721d85f77277813345bdb63a610e984cec996613 -Author: Guus Sliepen -Date: Sun Jul 2 12:35:28 2000 +0000 - - - Added Spanish translation from Enrique Zanardi. - -commit e821a22876d15c921a4c1fbc0f792d83e90916f6 -Author: Guus Sliepen -Date: Sat Jul 1 14:40:56 2000 +0000 - - - Forgot to mention ourselves in the tincd manual page! :) - -commit 09f4ec190119298187cec09dd5049af8fd8bad94 -Author: Guus Sliepen -Date: Sat Jul 1 14:32:24 2000 +0000 - - - Updated PROTOCOL (a bit) - - Included a real tincd.8 describing the options, signals, debug levels - and files used by tincd. - -commit d3ea434b3684093d6d160b8077c1f51a50ac7f61 -Author: Ivo Timmermans -Date: Sat Jul 1 10:39:28 2000 +0000 - - Autogenerated by gettextize. - -commit 1b28f88808b9ac3193cf9a0db7a81a89eed8b4ef -Author: Guus Sliepen -Date: Sat Jul 1 07:49:21 2000 +0000 - - - Removed a single unused bit from status_bits_t. - -commit 7fdc881b86fe379216f09dd5703bb88d398c87a8 -Author: Wessel Dankers -Date: Sat Jul 1 07:29:32 2000 +0000 - - Added architecture section, made a start with the kernel section. - ToDo: install tinc myself to see if everything is as I say =) - -commit 8ec648abf438bb5fcfe84e3a1c6a31192dc32b2e -Author: Guus Sliepen -Date: Fri Jun 30 22:38:58 2000 +0000 - - - Added documentation for the protocols (most important the meta protocol) - used by tinc. - -commit ce72275a4342ff4e21d21bb740ee88dca1ddb5f1 -Author: Wessel Dankers -Date: Fri Jun 30 21:16:52 2000 +0000 - - Grrr, recommit - -commit bbbdda255d6e7a8730906a1b6c2bfdd2ce1b94cf -Author: Wessel Dankers -Date: Fri Jun 30 21:11:34 2000 +0000 - - This file is now only in the CABAL revision. - -commit 28a140668f892873b01afe104d21db4adb8fd8c7 -Author: Wessel Dankers -Date: Fri Jun 30 21:09:32 2000 +0000 - - More about keys - -commit 1a1ebefd572c18d6af187750847b024ce07551ae -Author: Guus Sliepen -Date: Fri Jun 30 21:03:51 2000 +0000 - - - Made tinc even more silent if no -d flag is given at all. - -commit 79ad21c392e56cad2556e7693b9639d8e2346a59 -Author: Wessel Dankers -Date: Fri Jun 30 20:57:30 2000 +0000 - - Added extra bit about keys. - -commit 8309e9b869c25677d674f5cecb8b7ac5469d1758 -Author: Wessel Dankers -Date: Fri Jun 30 20:50:47 2000 +0000 - - File added to CABAL (hopefully) - -commit 5cd0f940c7334959534d3ab4e1f3c7cac67ee38a -Author: Wessel Dankers -Date: Fri Jun 30 20:42:07 2000 +0000 - - added bit on config file, split up sections, added Id: tag - -commit 6f5aac4e39cd6fb2fb76c0121de3f3782f72f18e -Author: Wessel Dankers -Date: Fri Jun 30 20:16:15 2000 +0000 - - Initial revision. Lots of loose ends, not usable yet. - -commit c5737583c8a5d099a71174e1eb997e0972ae03e9 -Author: Guus Sliepen -Date: Fri Jun 30 12:41:06 2000 +0000 - - - Instead of logging an error when remote end closes the connection, - we print a nice message if appropiate debug level is set. - - If we get ADD_HOSTs or DEL_HOSTs for ourself, then connection lists - are really messed up. We restart, and hope our problems go away. - -commit 24874d0806bac5d75663ea9de67a71171bfc97b6 -Author: Guus Sliepen -Date: Fri Jun 30 11:45:16 2000 +0000 - - - Removed segfault bug in conf.c (must have been there for ages!) - - Made main_loop() signal proof - - #defined MAXTIMEOUT (15 minutes) - - If something really really bad happens, close all connections, wait - for MAXTIMEOUT seconds, and then restart tinc - -commit 0f9ad1f047efec53590dc43f07d225e5f20456cb -Author: Guus Sliepen -Date: Thu Jun 29 19:47:04 2000 +0000 - - - Fixed memory leak. - - Implemented SIGHUP configuration file reloading. - - Other small changes. - -commit 18c85caac36f7236454deef11b9eba74328dbd96 -Author: Guus Sliepen -Date: Thu Jun 29 17:09:08 2000 +0000 - - - New semantics for BASIC_INFO, ADD_HOST and DEL_HOST requests. This will - improve connection list consistency, ensures the tree property, and - allows for recovery from situations where track of connections is lost. - -commit e8e7379311ca3bf6e1fdd7d0f477a43e510e2317 -Author: Guus Sliepen -Date: Thu Jun 29 13:04:15 2000 +0000 - - - Removed all IP_ADDR_S macros, because gettext doesn't like them. Each - connection now has two hostnames: real_hostname (replacing the old), - and vpn_hostname. In those places where hostnames really aren't usefull - IP_ADDR_S has been replaced by %d.%d.%d.%d. - -commit e0ddb638d1fb7abf19969ac887f3b7a2bd8225c1 -Author: Guus Sliepen -Date: Thu Jun 29 07:11:23 2000 +0000 - - - Updated Dutch translation. - -commit 0a155580a3d55633bbc3a1e7dcbe8906f41913be -Author: Ivo Timmermans -Date: Wed Jun 28 21:06:40 2000 +0000 - - Oops, and mention Guus too. - -commit f2c9e7f3bbada3fbfe80f622ebc06540afb60c21 -Author: Ivo Timmermans -Date: Wed Jun 28 21:01:45 2000 +0000 - - Removed Free Software Foundation copyright, because Guus Sliepen contributed significantly. - -commit 3df9b89204626afdd514d5b7323801af76a5cd26 -Author: Guus Sliepen -Date: Wed Jun 28 14:34:40 2000 +0000 - - - Added log message when SIGCHLD is received ("thanks" to Ivo van Dong) - -commit 8c6c60adf3d5942c6368bafe9a4d4377ffad1abe -Author: Guus Sliepen -Date: Wed Jun 28 13:41:02 2000 +0000 - - - Fixed a message in nl.po - - Woops, we forgot to send our connection list to our uplink when we - connect to it... Fixed. - -commit 63c5192d570e2ba5952b4e5a807e4ab4d6fdad76 -Author: Guus Sliepen -Date: Wed Jun 28 11:39:40 2000 +0000 - - - Fixed missing " in nl.po - -commit ea40d3f1a05e9edf4ccfb77f4e9e0f8355e94a83 -Author: Guus Sliepen -Date: Wed Jun 28 11:38:01 2000 +0000 - - - Fixed some spelling errors. - - Paar zpelvautjes gerepareerd, en de Nederlandse vertaling weer bij de - tijd gebracht. - -commit dba2995db73313b1c0a56ce13395dac0bc7571a5 -Author: Guus Sliepen -Date: Wed Jun 28 10:11:10 2000 +0000 - - - Extra check op EINTR bij inlezen requests - -commit 4ee53e7dac93d1edad8664edffdfaf142438b85d -Author: Guus Sliepen -Date: Tue Jun 27 21:05:07 2000 +0000 - - - Fixes a silly little insignificant buglet. - -commit 070ad08118a33755835b31174e2b04e84f75556e -Author: Guus Sliepen -Date: Tue Jun 27 20:55:12 2000 +0000 - - - Purge old connections that are ADD_HOSTed. - -commit 4aeaea5e590fbd38aebbfacf2672304d04ba4ad1 -Author: Guus Sliepen -Date: Tue Jun 27 20:10:48 2000 +0000 - - - Improved handling of errors on connection attempts. - -commit 45a28b1e893d4da9d7977945a35ec6a8e4554830 -Author: Guus Sliepen -Date: Tue Jun 27 15:08:58 2000 +0000 - - - Fixed indirectdata=no problem - - Added support for multiple ConnectTo lines in tinc.conf. - -commit 4faed1b8546563def6a426c563cec2a26d927eda -Author: Guus Sliepen -Date: Tue Jun 27 12:58:04 2000 +0000 - - - Fixed KEY_CHANGED notification. A lot of notify_others() calls were - wrong (first two arguments swapped). Should probably be doublechecked. - - Don't retry to connect to hosts with different protocol versions. - -commit 04cb206298df033d254ca007205d13f9a670c402 -Author: Guus Sliepen -Date: Mon Jun 26 20:30:21 2000 +0000 - - - Moved all connection messages to debug level 1, without -d's only the - startup message will be logged. - - Fixed DEL_HOST rebound. - -commit 783c8298610d5670f6e118f49bd3d1fdfa61ae1d -Author: Guus Sliepen -Date: Mon Jun 26 19:39:34 2000 +0000 - - - Indirectdata finally REALLY REALLY works now! - - More precise debug messages - -commit b3681ebf6c255daf082ed254282cbf493af8fa93 -Author: Guus Sliepen -Date: Mon Jun 26 17:20:58 2000 +0000 - - Fixes some hostlookups. Fixes indirectdata for real now (hopefully). - -commit 03af6d8c8056d0b7006f7d8fb19bb33d303ac8f9 -Author: Ivo Timmermans -Date: Sun Jun 25 20:52:29 2000 +0000 - - Version 1.0pre3. - -commit a473ece8a0d83be5f7992888a6a3ff938dc4fb72 -Author: Guus Sliepen -Date: Sun Jun 25 16:39:17 2000 +0000 - - - More verbose connection list - - Added "myself" as hostname when logging indirect ADD_HOSTs - -commit f1f901112e44beaecd3037dae27407ea83edd86e -Author: Guus Sliepen -Date: Sun Jun 25 16:20:27 2000 +0000 - - Hostlookup() is actually being called now. - -commit 54079bdf03e74c686f556f86082b9d14b5be227c -Author: Guus Sliepen -Date: Sun Jun 25 16:01:12 2000 +0000 - - Hostnames are back! - -commit e4b586ed070908f866a450292f9759004e6affa8 -Author: Guus Sliepen -Date: Sun Jun 25 15:45:09 2000 +0000 - - - Log possible spoofing attacks. - - Don't broadcast DEL_HOSTs for hosts that haven't been activated yet. - - If a host sends a TERMREQ, deactivate them. - -commit 9a1103a7be86de3da5548fd6446e6e4fe554cc08 -Author: Ivo Timmermans -Date: Sun Jun 25 15:42:40 2000 +0000 - - Changed version number to 1.0pre3. - -commit d8d2b83350e890adae9c9cede6e21ea4169abe00 -Author: Ivo Timmermans -Date: Sun Jun 25 15:42:40 2000 +0000 - - Changed version number to 1.0pre3. - -commit 7648bc606596851942dd6437ddaa93f53ab20f09 -Author: Guus Sliepen -Date: Sun Jun 25 15:22:16 2000 +0000 - - Added CVS Id tags to header files. - -commit 7f7e158aae8df5c65211bcfa82516e7c243cdd2e -Author: Guus Sliepen -Date: Sun Jun 25 15:16:12 2000 +0000 - - Large cleanup: - - Removed hostname lookup (it blocks, and you can always do it yourself) - - Reorganized debug levels (after hints from Axel M�ller): - 0 Startup message and errors - 1 Connection logging - 2 Meta protocol information - 3 Verbose meta protocol (includes copy of transmitted requests) - 4 Packet information (logs transmission/errors of UDP packets) - 5 Verbose packet information (every single byte, not implemented yet - to protect ourselves from filling up /var/log directories) - - Made log messages more consistent - -commit 3c54a513b0c0a3acac60e03403ab4abfa0688c62 -Author: Guus Sliepen -Date: Sat Jun 24 12:35:42 2000 +0000 - - If we have "indirectdata" flag set, we only send data to our uplink. - -commit d8e2f7104c3203edbf23d2349656c765a4310dee -Author: Guus Sliepen -Date: Fri Jun 23 19:27:03 2000 +0000 - - First step for implementation of the "indirectdata" directive. This should - allow _leaf_ tincds to be behind firewalls. - The protocol has changed and is INCOMPATIBLE with previous versions. The - PROT_CURRENT value has been incremented. - -commit 33c3a25a66251606cbf20d3bd5b392d8837116e3 -Author: Ivo Timmermans -Date: Sat Jun 17 20:55:54 2000 +0000 - - Configuration directive `IndirectData'. - -commit 1c8adb5e1f12894fc9a478fbf29678fb662e03ab -Author: Ivo Timmermans -Date: Sat Jun 17 20:30:44 2000 +0000 - - Merge changes from 1.6-1.8. - -commit 0d167e1f5d8778674a9a77b2256050e3afe2896e -Author: Guus Sliepen -Date: Sat Jun 17 08:30:45 2000 +0000 - - Added another semicolon for bash2 compliance (thanks to Jamie Briggs) - -commit 00f316810aa808368cdff620b1a1efdd1fcade20 -Author: Guus Sliepen -Date: Fri Jun 16 05:44:26 2000 +0000 - - Applied patch from Jamie Briggs for bash2 conformance. - -commit ef294a69678bc7cba6d2ee0be96f683249672222 -Author: Ivo Timmermans -Date: Tue Jun 6 10:24:33 2000 +0000 - - Include ../intl in the include path, and add @INTLLIBS@ to the list of libraries. - -commit 66e98068051bc52fa064650710260f89c09f8cfd -Author: Ivo Timmermans -Date: Sun Jun 4 12:14:31 2000 +0000 - - These files are created by gettextize (run by autogen.sh) (should have known that). - -commit d1d4a524dee9d75b067ac8e25770557cf22f4afe -Author: Ivo Timmermans -Date: Sun Jun 4 11:50:46 2000 +0000 - - Check for __gmpz_powm for libgmp3. - -commit 377c4df245ceb8c19cabfe6d7a7c76841c07ba52 -Author: Ivo Timmermans -Date: Sat Jun 3 23:32:03 2000 +0000 - - Don't touch VPNMASK if it's defined, otherwise use $MSK. - -commit 9193aee8159ce53b349557ba1ad8ed23111042bb -Author: Guus Sliepen -Date: Sat Jun 3 08:27:16 2000 +0000 - - Removed items in TODO list that are already implemented. Only two items - left. - -commit 5796d2f5b7310fa8841f76bbc7bbcf2385d960c3 -Author: Ivo Timmermans -Date: Fri Jun 2 17:30:33 2000 +0000 - - Alphabetized the list, added Lubom�r Bulej, removed Sander Smeenk and Tijs van Bakel, put merits after all names. - -commit 18b3084d2525c59f62b75346fa657ccce6459712 -Author: Guus Sliepen -Date: Thu Jun 1 20:21:27 2000 +0000 - - Debian init.d script automatically sets tap device's MTU to 1448 now. - -commit 77be52422d8c28735f787b1c233b4cec73d4db56 -Author: Ivo Timmermans -Date: Wed May 31 18:23:06 2000 +0000 - - Miscellaneous copyright updates. - -commit 8cb4bb619d777022a55255c5fa17a1a55a270ff3 -Author: Ivo Timmermans -Date: Wed May 31 18:21:27 2000 +0000 - - Handle locale settings. - -commit f20df109a638ac3a86efa70fac39e1dae8e87208 -Author: Ivo Timmermans -Date: Wed May 31 18:19:33 2000 +0000 - - Version 1.0pre2-1. - -commit 4ae74c50b7faadf31086bc61af0f8158a465e521 -Author: Ivo Timmermans -Date: Wed May 31 18:18:21 2000 +0000 - - Updated Dutch translation. - -commit 7037286586151e28b7c5f1fe09dd6c5faca18cdc -Author: Ivo Timmermans -Date: Wed May 31 18:17:45 2000 +0000 - - Tell about /etc/tinc/nets.boot. - -commit 65a9eedb05387b8cf77dbbbc56347b44a28de624 -Author: Ivo Timmermans -Date: Wed May 31 18:17:27 2000 +0000 - - Include news for 1.0pre2. - -commit 17fa07510ad74d0f96f9700538d32eb8e7b2a0ce -Author: Ivo Timmermans -Date: Tue May 30 21:36:16 2000 +0000 - - Only accept an ADD_HOST request for a host that already exists in our conn_list if the nexthop field matches the sender. This is a workaround for older clients. - -commit e7f22d2f5f0a5fcd52da7512ab734b0ba52c623f -Author: Ivo Timmermans -Date: Tue May 30 12:38:15 2000 +0000 - - In terminate_connection, only send a notification to hosts that are directly connected to us. (DEL_HOST gets forwarded automatically.) - -commit 2fdda8e4fa6c6ace5f7e9421f0644a3ffec388c9 -Author: Ivo Timmermans -Date: Tue May 30 12:31:41 2000 +0000 - - When a connection is terminated, all hosts that are still connected get notified of the lost connections. - -commit f826301889e1fa1a22770919f0385c3ca04c740a -Author: Ivo Timmermans -Date: Tue May 30 11:18:12 2000 +0000 - - Added new configuration directive `Hostnames', which controls the resolving of IP addresses to hostnames. - -commit a7ad161d2b115b6a2a69c5dc8ddd33008d3562d0 -Author: Guus Sliepen -Date: Mon May 29 23:40:05 2000 +0000 - - Only activate a connection upon receiving it's public key if it's an - incoming connection. When it's outgoing, we need to receive an ack first. - -commit 5654e156a31d05ac3026790f7749d0401b2eaabc -Author: Ivo Timmermans -Date: Mon May 29 22:27:15 2000 +0000 - - Updated changes list for version 1.0pre2. - -commit a822c7466aa91a819c498336f91c63d224c3af11 -Author: Ivo Timmermans -Date: Mon May 29 22:20:04 2000 +0000 - - Bounds check for request id (between 0 and 255). - -commit 0f2cf48d304e20abb9b3cded2aaa693828c9d412 -Author: Ivo Timmermans -Date: Mon May 29 22:15:38 2000 +0000 - - Dutch translation of tinc. - -commit 386a62ff57f283b415fd757a8c4645b24c3bd3bb -Author: Ivo Timmermans -Date: Mon May 29 21:40:51 2000 +0000 - - Define LOCALEDIR in CFLAGS. - -commit 4cd009f774e4c50cdacc06d351cac19ca3247b6b -Author: Ivo Timmermans -Date: Mon May 29 21:40:20 2000 +0000 - - Include GNU gettext checks. - -commit 5814939c9d0e801bdbed6c96092fd90b6dcd859c -Author: Ivo Timmermans -Date: Mon May 29 21:38:02 2000 +0000 - - Update acconfig.h to include values for gettext inclusion. - -commit b200b0d812763563dbe09e5da116c55e45f89e4f -Author: Ivo Timmermans -Date: Mon May 29 21:36:28 2000 +0000 - - Include system.h and ABOUT-NLS. - -commit b9ea0633c7243de552d581f4486902c67aefd695 -Author: Ivo Timmermans -Date: Mon May 29 21:04:55 2000 +0000 - - Include intl/ directory in the list of subdirs. - -commit 9fd02ffcb0cacf3de26e876de5f30510bff137a3 -Author: Ivo Timmermans -Date: Mon May 29 21:01:26 2000 +0000 - - Internationalization of tinc. - -commit 61e71ab74ad9b5edb044b84ccf1111a33eb468cb -Author: Guus Sliepen -Date: Sat May 27 20:23:01 2000 +0000 - - Terminate a connection on any error. Furthermore, disallow del_host, - add_host and other important requests until remote host has properly - authenticated itself. - -commit cc01b18bc6d0bfb12e6770fc0a007c278f355d9e -Author: Guus Sliepen -Date: Sat May 27 19:44:04 2000 +0000 - - Made tinc persistent. If no outgoing connection can be established right - after the start of the daemon, it won't quit anymore but will retry in 5 - minutes. Also, 5 minutes is now the maximum time to wait for a retry. - -commit 028659bfbf164cb7a72831506896e291010b251f -Author: Guus Sliepen -Date: Sat May 27 19:23:20 2000 +0000 - - Fixed typos. When terminating a connection, it's status is not only set to - remove=1 but also active=0. - -commit e4ff969a9868ecc25a85daab620f97227de8d493 -Author: Guus Sliepen -Date: Sat May 27 19:04:12 2000 +0000 - - Fix for a DoS attack: - A remote user could telnet to the tinc daemon and type only this line: - 61 6 00000000/00000000:28f - This would deny any packets to be sent to other tinc networks (except - for to the hosts that run tincd's themselves). Solution is to skip - hosts in lookup_conn() that have not been activated yet. - Fixed potential conn_list table corruption: - If a new connection is accepted but a connection with the same subnet - would already exist in the connection list, the OLD connection is - terminated. - -commit 4d71de15e8abd137702a5dc04a743d246c3f1110 -Author: Guus Sliepen -Date: Sat May 27 13:21:20 2000 +0000 - - Documentation updates. Removed all references to configuration variable - "AllowConnect", since it is NOT used in tinc. Added information about - "VpnMask". Elaborated a bit about "private" and "virtual" networks. - -commit 85e3c1f2716c622ca8cada83d833703bf8a3ecc6 -Author: Ivo Timmermans -Date: Fri May 26 11:25:59 2000 +0000 - - Updated by Lubomir Bulej and Mads Kiilerich: it uses /etc/tinc/nets.boot and the VpnMask directive in the config files. - -commit 3a6ffe6895b681377a9553c01e3777f499b90d4a -Author: Ivo Timmermans -Date: Sun May 21 23:01:28 2000 +0000 - - Create an empty /etc/tinc/nets.boot. - -commit b9a86ec70ed4ffe5009c4979454f0d99c8559b45 -Author: Ivo Timmermans -Date: Sun May 21 22:40:41 2000 +0000 - - Use /etc/tinc/example as a base directory for an example. /etc/tinc/example/README points to /usr/share/doc/tinc/README.Debian. - -commit 63847abdfdad03a69bfd967929336e113cdeb09e -Author: Ivo Timmermans -Date: Sun May 21 22:38:01 2000 +0000 - - Add an example of using VpnMask. - -commit 2469acc0900edeb8f1e3263fbf58bf74639c1b12 -Author: Ivo Timmermans -Date: Sun May 21 22:27:31 2000 +0000 - - When VpnMask is not present in the config file, silently use $MSK as vpnmask. - -commit 73b3e7ce03cacb644a8101610933b221fdf432d6 -Author: Guus Sliepen -Date: Sun May 21 22:21:38 2000 +0000 - - Fixed last typo. Init.d now uses ifconfig command to set both the tap's IP - address as well as the correct route. Furthermore, if no VpnMask is given, - a default of 255.255.0.0 is chosen and a warning issued. - -commit 2ad4f1cc5b6013be2deee82b0cb3f731adb51616 -Author: Guus Sliepen -Date: Sun May 21 22:08:21 2000 +0000 - - Typo. - -commit e25fc3a3dc4bc407bd0645fb9891ac127a83f468 -Author: Guus Sliepen -Date: Sun May 21 22:04:56 2000 +0000 - - VpnMask truely works now. - -commit 9ec4decec17f95cc7d5be66cc18bb040cce84d47 -Author: Ivo Timmermans -Date: Fri May 19 01:17:32 2000 +0000 - - Mask the vpn net with the vpn netmask, route would give an error if the netmask didn't match the net. - -commit 20e404ab5716b06b53a4a5443f8098f227770907 -Author: Ivo Timmermans -Date: Fri May 19 00:58:01 2000 +0000 - - Fixed typo. - -commit 44af1094be90878bd6fc09c40882cf2463046908 -Author: Ivo Timmermans -Date: Fri May 19 00:33:44 2000 +0000 - - Updated copyright notice. - -commit 01352f4c525862f05988ed8687f26210c5ba10a2 -Author: Ivo Timmermans -Date: Fri May 19 00:15:37 2000 +0000 - - Errors will not terminate the script or result in a nonzero exit code. - -commit 4ef2a8cfdb13c7eb2d811fc8c9f04df8970293c5 -Author: Ivo Timmermans -Date: Fri May 19 00:14:34 2000 +0000 - - Include postinst in the distribution. - -commit 59ca017df4c9d0f7861693b4d2ec4b7dc8c98b1e -Author: Ivo Timmermans -Date: Fri May 19 00:09:20 2000 +0000 - - Find networks in instead of . - -commit 0354962c9885f04801d8469214c172cc012cdcec -Author: Ivo Timmermans -Date: Thu May 18 23:33:44 2000 +0000 - - Don't distribute the file files. - -commit b56705e18ceec9234578d7ac12939f7c59cff066 -Author: Ivo Timmermans -Date: Thu May 18 23:28:51 2000 +0000 - - Version 1.0pre2-0.3 - -commit cbf6efb617f45ffc608fe5f61d09abdd85f444ad -Author: Ivo Timmermans -Date: Thu May 18 23:18:54 2000 +0000 - - Create a default /etc/tinc/nets.boot after installation, containing all directories under /etc/tinc by default. - -commit e7d583adfaa50370d20f4cfe88ba5b6da399911d -Author: Ivo Timmermans -Date: Thu May 18 23:09:31 2000 +0000 - - Read /etc/tinc/nets.boot to find the networks that have to be started. - -commit 8d4ab991b8c35382c9cd46dd65af873d9d08f63f -Author: Ivo Timmermans -Date: Wed May 17 23:13:51 2000 +0000 - - This file is generated with dpkg-buildpackage. - -commit ffc79bcd20b2b8085c906a446318817808bc36ae -Author: Guus Sliepen -Date: Tue May 16 16:07:15 2000 +0000 - - TODO file reinstated: - - Append your name to items if you're working on them. - - Remove them if you fixed the problem/implemented that feature. - - Add any (suspected) bugs. - -commit cdab82d6fb7d7d32194cb2162a814fbc89b7db4c -Author: Ivo Timmermans -Date: Tue May 16 14:34:44 2000 +0000 - - Use the new VpnMask directive to add a route to the rest of the VPN. - -commit 85963f4c857abc2d9a4c5a3245cc11257140b9a6 -Author: Guus Sliepen -Date: Tue May 16 13:09:15 2000 +0000 - - Stub for VpnMask config directive. - -commit 30aff5ea2aebcfc0e97e60e73ed3edc2363634a0 -Author: Ivo Timmermans -Date: Tue May 16 13:03:32 2000 +0000 - - Look if the tap devices exist before bluntly remaking them. - -commit 0761eed64c4d6d2b8e9fa6a335ccdca8ea4b95db -Author: Ivo Timmermans -Date: Tue May 16 07:56:05 2000 +0000 - - *** empty log message *** - -commit 0a2e2b0c8d20baf22b550f735b1fe63b0a1d377a -Author: Ivo Timmermans -Date: Mon May 15 19:48:46 2000 +0000 - - Depend on perl5. - -commit 7e817fcf0fdd25aae58259930006c61048b017cd -Author: Ivo Timmermans -Date: Mon May 15 18:28:45 2000 +0000 - - Unlimited length in the config file, thanks to Cris van Pelt. - -commit b18af982af810ff4c050891ad2026960c43620a0 -Author: Ivo Timmermans -Date: Mon May 15 17:15:52 2000 +0000 - - Exit with zero status if is empty. - -commit 4711a87922c84241e9bb312755d7b943ea8ae4b6 -Author: Ivo Timmermans -Date: Mon May 15 15:54:37 2000 +0000 - - Updated to newer version. - -commit a0c4e7fe6d46988f3fb1100ef00db7b747c86f72 -Author: Guus Sliepen -Date: Mon May 15 09:41:34 2000 +0000 - - Test for existence of configured tinc networks. This will also make - first install of tinc possible without errors. - -commit 265bda08cd00feebb68243d4079854916b03638e -Author: Ivo Timmermans -Date: Sun May 14 23:03:37 2000 +0000 - - .deb version number 1.0pre2-0.4. - -commit 7a450d704b5a242f8bf9129af60593c90c63df5a -Author: Ivo Timmermans -Date: Sun May 14 23:00:44 2000 +0000 - - tincd->tinc - Delete libblowfish.y not be in the .deb. - -commit 7fbfa990fcd38b8241281ce6f1a4e2992239986f -Author: Ivo Timmermans -Date: Sun May 14 22:59:47 2000 +0000 - - Mention both upstream authors. - -commit f7b04ea142623a43413f74e19b1b6a9a247647ff -Author: Ivo Timmermans -Date: Sun May 14 22:59:19 2000 +0000 - - Add description, better dependancies. - -commit 9f07fe55dc4930920b9a5909d7057ca7bc16bad9 -Author: Ivo Timmermans -Date: Sun May 14 22:58:47 2000 +0000 - - Add initscript, tincd->tinc. - -commit df10baa50c3b421b03ac9eeaed4a4a19a47f611e -Author: Ivo Timmermans -Date: Sun May 14 21:18:10 2000 +0000 - - Inserted useful content. - -commit 6c722da77cc9185e48e22818ef88f2a88cf2efc7 -Author: Ivo Timmermans -Date: Sun May 14 21:14:23 2000 +0000 - - Add shlibs control file for the blowfish library. - -commit 803f908078e87f433727a3ddf2d61734e1ed9233 -Author: Ivo Timmermans -Date: Sun May 14 21:07:16 2000 +0000 - - Give IP address instead of hex number when connecting tcp socket failed. - -commit 4b1a1c2123626b50bd1a5382867986260440e9e7 -Author: Ivo Timmermans -Date: Sun May 14 21:04:53 2000 +0000 - - Changed version to 1.0pre2. - -commit ca900d388b996c629f0c87c7a62efb52bd219065 -Author: Ivo Timmermans -Date: Sun May 14 20:58:34 2000 +0000 - - Version 1.0pre1-0.1. - -commit 7d433ebd7610e0ff7e7b4c59979c446c0a1dfd03 -Author: Ivo Timmermans -Date: Sun May 14 20:56:41 2000 +0000 - - Add check for mpz_powm in libgmp3. - -commit de09916eadd4c558937d1a6367f5319ca26ed07c -Author: Ivo Timmermans -Date: Sun May 14 13:50:10 2000 +0000 - - Only print an error with send_termreq if debug_lvl is 2 or more. - -commit 9d023b1f2e7750f4a0e506c0f61498a44c0b95a8 -Author: Guus Sliepen -Date: Sun May 14 13:06:52 2000 +0000 - - Fixed typos. - -commit e20e143f1e99bdc0a7d92e97da1bd0dc40e8a83b -Author: Guus Sliepen -Date: Sun May 14 13:02:20 2000 +0000 - - Changed ping behaviour (backwards compatible). If we don't have any data - to send, we don't need to check if the connection is still alive. - Furthermore, if we receive any kind of data from the other end, we know - it's alive, so we don't need to check it either. So, PING requests are - only sent if we send packets but there is no response. - -commit ee96ccabbbf0180d5631d3c22838456f28ee9c15 -Author: Guus Sliepen -Date: Sun May 14 12:22:42 2000 +0000 - - Cleanups. - -commit 8caa1b9d750bb7467d1c3330780b05ac2bbf9883 -Author: Guus Sliepen -Date: Sun May 14 11:39:18 2000 +0000 - - Proxymode removed. - -commit 269067bb22e8f80deb43d3ac903f4e0d67af63d2 -Author: Ivo Timmermans -Date: Sat May 13 00:54:27 2000 +0000 - - Perl version of the system startup script. - -commit 12adf1af548b7d2f2baa4be16d2df956048b7855 -Author: Ivo Timmermans -Date: Fri May 12 13:31:00 2000 +0000 - - Deleted the protocol description. - -commit d0ba34ccae02d07051bc3f7012a6c116cfb3b653 -Author: Guus Sliepen -Date: Mon May 8 18:44:15 2000 +0000 - - Added new config variable "ProxyMode". If enabled, all outgoing packets - are sent to the uplink (ConnectTo), which will have to forward them for - us (kernel should do that). This is for people behind firewalls. - -commit 92387475ace9b06af39987c71ac563cf29427009 -Author: Ivo Timmermans -Date: Fri May 5 10:48:54 2000 +0000 - - Added semicolons required by bash2 (Mads Kiilerich). - -commit bce2179fe350bf34cde0caab97f72c0930539840 -Author: Ivo Timmermans -Date: Thu May 4 23:26:24 2000 +0000 - - Copied most of the code from the redhat script. - -commit 74b0cbecce5194dc5c594cc4e2aa3e97c14ea6c1 -Author: Ivo Timmermans -Date: Thu May 4 23:17:02 2000 +0000 - - Include sys/types.h. - -commit 2f7e532d703bbf6997ae04658379df0b0d844f62 -Author: Ivo Timmermans -Date: Thu May 4 23:16:43 2000 +0000 - - Don't link in libdl. - -commit d4ef7ea0e79ee0d2b7063893f7af5ece886d838b -Author: Ivo Timmermans -Date: Thu May 4 00:01:05 2000 +0000 - - Check for the existance of libdl. - -commit 87ccd613cab1947878ef60e3c927f717df089233 -Author: Ivo Timmermans -Date: Thu May 4 00:00:50 2000 +0000 - - More for getopt support. - -commit 6182664859383a86a47846cafdc1f6fcd73b5a76 -Author: Ivo Timmermans -Date: Thu May 4 00:00:06 2000 +0000 - - Include stdio.h for fprintf. - -commit 88a8826cf72297a784d597ba5a2b47058e1faf72 -Author: Ivo Timmermans -Date: Wed May 3 23:47:06 2000 +0000 - - getopt_long() support for platforms that don't have it. - -commit 3d218a31145cf6a4c625ed287cdf3f99e4fd9a03 -Author: Ivo Timmermans -Date: Wed May 3 23:00:38 2000 +0000 - - Don't use error.h or error(), put #error in front of cpp errors. - -commit a083b1cf305f3d241f2f4b36968a5b1ed9117612 -Author: Guus Sliepen -Date: Wed May 3 18:02:15 2000 +0000 - - Squashed gcc warning. - -commit 78532475238b23eb52ac88d905fbf966d97a79d2 -Author: Guus Sliepen -Date: Wed May 3 17:59:07 2000 +0000 - - Fixes typo and UDP network byte order. - -commit 505b5ec2cd9d6cf3dc655284a8c4041ce8527a07 -Author: Guus Sliepen -Date: Wed May 3 15:37:32 2000 +0000 - - Outgoing packets now use network byte order in header. - -commit 2bc7a0c92831802eec167ad193515962a63690dd -Author: Ivo Timmermans -Date: Wed May 3 15:01:54 2000 +0000 - - Fix a typo, better handling of the info document. (from Mads Kiilerich) - -commit 89610e3fbada1dee79769b8146a500c8357fd81d -Author: Guus Sliepen -Date: Tue May 2 10:16:50 2000 +0000 - - Replaced sprintf() by safer snprintf(), removed possible buffer overflow - by one byte. - -commit aeccaca829842910b4a5c8a5fa61e1738492bea6 -Author: Guus Sliepen -Date: Tue May 2 09:55:34 2000 +0000 - - Previous fix fixed. Meta protocol should be really flawless from now on! - -commit 989d7edc07fd407e7f7838b45986f4e37359ef97 -Author: Guus Sliepen -Date: Tue May 2 09:10:33 2000 +0000 - - Fixed small mistake that would prevent forwarding requests. - -commit 069c146656b8f952e465492c53ab5b514e959565 -Author: Ivo Timmermans -Date: Mon May 1 22:00:02 2000 +0000 - - Mentioned new metaprotocol. - -commit bd0325655867b1dff740d52d0505773bba0606a6 -Author: Ivo Timmermans -Date: Mon May 1 21:47:12 2000 +0000 - - More tincd->tinc updates. - -commit a9247e6f2c57bda9dc62ed050f41048847109e83 -Author: Ivo Timmermans -Date: Mon May 1 21:31:59 2000 +0000 - - Fixed meta protocol. - -commit 9ea27f76fab3663c9c83a7fe7de95f74cbfd59be -Author: Ivo Timmermans -Date: Mon May 1 21:31:17 2000 +0000 - - Committed by Mads Kiilerich. - -commit a92604fa5dffef589fc3042c5ae09ae8878e8cff -Author: Ivo Timmermans -Date: Mon May 1 19:17:09 2000 +0000 - - Updates by Mads Kiilerich. - -commit ca6abd41ea0cdf2ca6491c3945fb3c62fd40ab98 -Author: Guus Sliepen -Date: Mon May 1 18:07:12 2000 +0000 - - Meta protocol overhaul. Tinc is now incompatible with previous versions, - furthermore this version does NOT work yet because of a problem with - sending keys (these should be converted to base36 or something like that). - It is possible to telnet to the tinc daemon now and type some commands - by hand though :). - -commit 3219be5770716bdb0c8b6e9e4c674a447c5085f2 -Author: Ivo Timmermans -Date: Mon May 1 16:28:28 2000 +0000 - - Committed by Lubom�r Bulej. - -commit 33cfdf43f4309c17d6df811b3c5d0af3a1c8679f -Author: Ivo Timmermans -Date: Sun Apr 30 20:48:48 2000 +0000 - - Key forwarding, write one byte extra. - -commit 75d351eaf1264cfb7aa47166469e8ec722712a89 -Author: Ivo Timmermans -Date: Sun Apr 30 19:49:49 2000 +0000 - - Protocol fix (ANS_KEY). This breaks 0.3.3 protocol compatibility. - -commit b4290c3f4360f3cf01bb44957da0d8a20eac75f3 -Author: Ivo Timmermans -Date: Sun Apr 30 19:03:00 2000 +0000 - - Send one less byte from an ANS_KEY request. - -commit d878230ebef5f1a14a23c266dc425666d9e805eb -Author: Ivo Timmermans -Date: Sun Apr 30 18:57:16 2000 +0000 - - Read one less byte from an ANS_KEY request. - -commit 789a4c4f400de31d43b9c5f349f1de417443074a -Author: Ivo Timmermans -Date: Sun Apr 30 16:34:31 2000 +0000 - - Removed debug messages. - -commit eb1c9814e6b2a5206be1fadf19e0dc779690a69e -Author: Ivo Timmermans -Date: Sun Apr 30 16:31:23 2000 +0000 - - Read public keys the right way (tm). - -commit ca73b722cbad5a08ec9bb5026ed5129da9a24bd8 -Author: Ivo Timmermans -Date: Sun Apr 30 16:11:05 2000 +0000 - - New way of handling the meta protocol. - -commit cd12345032e8547a50a1f7450814364f39f0c4ec -Author: Ivo Timmermans -Date: Sun Apr 30 13:23:53 2000 +0000 - - Replaced check for status.active by status.dataopen in check_network_activity. - -commit 4b076ee87fcf8aaf1d9a2bd3c27524b4e3840167 -Author: Ivo Timmermans -Date: Sun Apr 30 01:16:51 2000 +0000 - - Initially, the vpn_mask of a connection is 255.255.255.255 to avoid confusion with lookup_conn. - -commit 1c007c0627ad5e71b8218fcb086240970e955c87 -Author: Ivo Timmermans -Date: Sun Apr 30 01:15:47 2000 +0000 - - Got rid of the nasty hacks... and replaced it by another one. - -commit c02745991422ac3d8097b126e8b256a9b33ad24b -Author: Ivo Timmermans -Date: Sat Apr 29 20:39:36 2000 +0000 - - Filled up the protocol structs with unused bytes. - -commit d3e8e8ca54928e48400584d8a70c42bbf4ae6aeb -Author: Ivo Timmermans -Date: Sat Apr 29 20:38:23 2000 +0000 - - Added `deb' target. - -commit 4dbf7022a25e678969856a38501318db4d420936 -Author: Ivo Timmermans -Date: Sat Apr 29 13:56:06 2000 +0000 - - More updates wrt. the change from tincd->tinc. - -commit 23715510149179089952eef0a2d6f87571ac0e7e -Author: Guus Sliepen -Date: Fri Apr 28 11:33:25 2000 +0000 - - Oops! Reference to write_n() removed and changed into neat write() call. - -commit bb8fff92e1bc594a085c2cbd12b215d334695feb -Author: Guus Sliepen -Date: Thu Apr 27 20:57:18 2000 +0000 - - Removed write_n() function. - -commit 4fec0cc45774ba313d1823cc64c3afdda3204a2e -Author: Ivo Timmermans -Date: Thu Apr 27 13:47:51 2000 +0000 - - Default config file name is tinc.conf, and pidfile is tinc.pid. - -commit eebb708cb29a121ea8d58bb6ca6caf41dea3c3b4 -Author: Ivo Timmermans -Date: Thu Apr 27 00:07:17 2000 +0000 - - Updated version number to 1.0. - -commit 5797d3fcb1ff56ad3ff577f7eb988b70f9d4d709 -Author: Ivo Timmermans -Date: Thu Apr 27 00:01:00 2000 +0000 - - Filled in the details, license from libblowfish copied. - -commit a3ccc15ac0979c4103f98e740b525634e8e17a0a -Author: Ivo Timmermans -Date: Wed Apr 26 23:56:22 2000 +0000 - - Version to 1.0pre1; - Create Makefile and build in debian/. - -commit d928703db1c4aa6caa6e4fbb0894037b10dce820 -Author: Ivo Timmermans -Date: Wed Apr 26 23:23:01 2000 +0000 - - Omit TODO. - -commit d0ea9c8ff287e879e531af9f1b52529421c0512f -Author: Ivo Timmermans -Date: Wed Apr 26 22:42:15 2000 +0000 - - Add an entry to dir. - -commit e5a7291543d41d435cc0fae56e52dc62a119a225 -Author: Ivo Timmermans -Date: Wed Apr 26 22:01:01 2000 +0000 - - The make command is in /usr/bin. - -commit 44f9449888344866406c75b178eff83b392b3530 -Author: Guus Sliepen -Date: Wed Apr 26 17:42:55 2000 +0000 - - Cleanups: - - Changed recv/send calls into read/write calls for streams - - Made all sizeof() functions use a variable name instead of type - -commit fca84d8a7d116c62423faf88e841daf1bee714e1 -Author: Ivo Timmermans -Date: Wed Apr 26 14:54:43 2000 +0000 - - From Mads Kiilerich. - -commit 8efe4874dabdfdf03a747ea98cf38b11cb591ef5 -Author: Guus Sliepen -Date: Tue Apr 25 22:15:28 2000 +0000 - - Converted every &variable[0] to variable. - -commit 643d8712eb2f82bde21f206306cdb6491eee7e08 -Author: Ivo Timmermans -Date: Tue Apr 25 22:00:49 2000 +0000 - - Debug level tweaking. - -commit 468f1d2efcce53937b7f5e0540269ae18f29ebac -Author: Guus Sliepen -Date: Tue Apr 25 20:50:59 2000 +0000 - - When trying to talk to a host that is in the netmask of a tinc server but - not the tinc server itself, and no keys have been exchanged yet, the key - request would be directed to the host instead of the server. Fixed. - -commit 6461a4b607f5e422b5809acb772e4bfe810b5570 -Author: Ivo Timmermans -Date: Tue Apr 25 20:42:54 2000 +0000 - - *** empty log message *** - -commit dad90e82d3c7af95820b1c04903bed7074e2b175 -Author: Guus Sliepen -Date: Tue Apr 25 20:17:44 2000 +0000 - - Fixed typo and removed some unnecessary variables. - -commit 5b7242285795f5143770b663055b87ebb5dd15b8 -Author: Guus Sliepen -Date: Tue Apr 25 20:10:37 2000 +0000 - - Packet queues fixed. They caused the trouble when resending keys. - -commit 04db888b1a94a7d63fdf9800cfd722aa9c16cd26 -Author: Ivo Timmermans -Date: Tue Apr 25 19:23:23 2000 +0000 - - Create a ChangeLog file, automake requires it. - -commit c78b76c53f516cf944ee738fad3e7d4607f282ab -Author: Ivo Timmermans -Date: Tue Apr 25 19:21:19 2000 +0000 - - *** empty log message *** - -commit 45b275e2542b4e8e7deac9e5e9eeddacfdbce90f -Author: Ivo Timmermans -Date: Tue Apr 25 19:11:02 2000 +0000 - - Initial CVS. - -commit 3a3356865267ff4c1e4f7d73f6d1486952d641b5 -Author: Guus Sliepen -Date: Tue Apr 25 18:57:23 2000 +0000 - - Added checkpoints to beginning and ending of every function. - -commit b6bdb9079a9e80b77443efe6c8b6da19e57e8505 -Author: Ivo Timmermans -Date: Tue Apr 25 17:38:54 2000 +0000 - - Remove ChangeLog with a `make cvs-clean'. - -commit ca373c61944a7bd2fe26faf081edea136104d326 -Author: Ivo Timmermans -Date: Tue Apr 25 17:35:45 2000 +0000 - - Don't include TODO in the dist. - -commit e1e590fe9a8c5c767933c68979418911f36d3a89 -Author: Ivo Timmermans -Date: Tue Apr 25 15:08:10 2000 +0000 - - Propagate CFLAGS from configure to gcc. - -commit 8a90de94a1b0e6cdaf51559d44f04a75d5f9ab0e -Author: Ivo Timmermans -Date: Tue Apr 25 15:07:21 2000 +0000 - - Delete all the files that are created by autogen.sh on a `make cvs-clean'. - -commit 24ee68b683de9937e917898075c62ff5f43ee46a -Author: Ivo Timmermans -Date: Tue Apr 25 10:40:08 2000 +0000 - - Spelling fixes. - -commit 4d85552c5bf134ada1d1083ec86dabbe41497c4a -Author: Ivo Timmermans -Date: Tue Apr 25 10:27:44 2000 +0000 - - Contributed by Mads Kiilerich. - -commit 94921d6e57e01b378ab8b1d8ea9cf3da9511fbef -Author: Ivo Timmermans -Date: Tue Apr 25 10:22:26 2000 +0000 - - Generate this Makefile.am from Makefile.am.in. - -commit 8c2b6537d32720b38554815181009c3098423414 -Author: Ivo Timmermans -Date: Tue Apr 25 09:43:50 2000 +0000 - - *** empty log message *** - -commit 03fa76dbf9965cc174eebe8a152307b8fbb63079 -Author: Ivo Timmermans -Date: Tue Apr 25 09:42:52 2000 +0000 - - Added Mads Kiilerich, removed Guus Sliepen. - -commit 7c665712d69d5a502d4c2f098ad85df3b17bfb92 -Author: Ivo Timmermans -Date: Tue Apr 25 01:45:34 2000 +0000 - - Changes largely from Mads Kiilerich. - Removed section about encryption. - -commit ce98ee1ed4121fbbf5d0e13e158511064ced6b16 -Author: Ivo Timmermans -Date: Tue Apr 25 01:26:35 2000 +0000 - - Remove test for GNOME. - -commit 6c99feb3e3cf6d69bcf52ae87b6c64ddbf3ffca5 -Author: Ivo Timmermans -Date: Tue Apr 25 01:25:18 2000 +0000 - - Use `make ChangeLog' to create this file from the CVS logs. - -commit f9eef5210dbc9c0fe54637cc4c3c0be134a51409 -Author: Ivo Timmermans -Date: Tue Apr 25 01:23:31 2000 +0000 - - Don't define HAVE_NAMESPACES and HAVE_STL. - -commit ea9d2f379a170077f93569a957c713452768d0a4 -Author: Ivo Timmermans -Date: Tue Apr 25 01:22:01 2000 +0000 - - Remove check for bigendianness. - -commit 18b204d17a054e991d90b7c4047ea106df64cdaf -Author: Ivo Timmermans -Date: Tue Apr 25 01:15:28 2000 +0000 - - This file is obsolete, most of the ideas are already in echelon. - -commit 62d5384ee01ae818906f2f8ba1456372a13a2420 -Author: Ivo Timmermans -Date: Tue Apr 25 01:10:38 2000 +0000 - - s/Gnome/tinc/g - -commit f0101589959496593db672c6a35704ea5fb33238 -Author: Ivo Timmermans -Date: Tue Apr 25 00:50:48 2000 +0000 - - The shell script autogen.sh can create all these removed files, but be - sure to have autoconf, automake, libtool and more installed. - -commit 6990a7455521665d3b67518e3f2297968108190b -Author: Ivo Timmermans -Date: Tue Apr 25 00:11:33 2000 +0000 - - Don't try to create cipher/idea/Makefile. - -commit cfecc82c9a3f5e8c4648eec058da2c6427cd76af -Author: Ivo Timmermans -Date: Mon Apr 24 21:12:32 2000 +0000 - - Don't include idea/idea.h. - -commit 63540ceff5c7bb7c76d96a4cef4ba803ce915ce1 -Author: Ivo Timmermans -Date: Mon Apr 24 21:10:33 2000 +0000 - - Don't compile in `idea'. - -commit 74315f4218ba50cc5ba32b6ecc8e8afa2b5cd704 -Author: Ivo Timmermans -Date: Mon Apr 24 20:57:22 2000 +0000 - - These files are not needed in release 1.0. - -commit 16d581be68bb52c08569e34e8a6b87f66b87e8ee -Author: Guus Sliepen -Date: Mon Apr 24 09:39:50 2000 +0000 - - Bug found! Wrong pointer was used for handling multiple ADD_HOST requests - at once. (See line 606.) - -commit f6802d349d946090bf9d1b6c761077c80065afa5 -Author: Guus Sliepen -Date: Mon Apr 24 08:32:57 2000 +0000 - - Added extra checks for desynchronized connection lists. Hopefully this will - fix those strange segmentation faults. - -commit 10749179127c681ce040fcf612038174b2bd474a -Author: Ivo Timmermans -Date: Thu Apr 20 22:50:48 2000 +0000 - - Added cvs-clean. - -commit c92701fcf007b67725d82a23ffaef3e6e5c2b0e1 -Author: Ivo Timmermans -Date: Thu Apr 20 19:14:09 2000 +0000 - - Keep make dist(dir) happy. - -commit 7db17968fc84127212ebba0fbccec1e75ced2bdc -Author: Ivo Timmermans -Date: Tue Apr 18 20:44:29 2000 +0000 - - A short notice from Mads Kiilerich. - -commit 2c5a555d7aefcf5699c68cb5d5f00f604b2542c7 -Author: Ivo Timmermans -Date: Tue Apr 18 20:43:24 2000 +0000 - - Submitted changes by Mads Kiilerich. - -commit 375b668dbc1e0268b49ea12901da72bbf5247ce5 -Author: Ivo Timmermans -Date: Tue Apr 18 20:30:20 2000 +0000 - - Include genauth.8 in the distribution. - -commit 57d8c30e4cbecea3b4216e4e650c4c0a3e160ed2 -Author: Ivo Timmermans -Date: Tue Apr 18 20:26:49 2000 +0000 - - Include the directory redhat in the build process. - -commit 0b02ebc4d98182cf79c670e7e556ac7f4f859b75 -Author: Ivo Timmermans -Date: Tue Apr 18 16:04:10 2000 +0000 - - Address for bugreports changed to tinc@nl.linux.org. - -commit 8770211c84cfb69f71bd204926593900d74ab579 -Author: Ivo Timmermans -Date: Tue Apr 18 15:59:42 2000 +0000 - - Updated manpages. - -commit 8cdb84951019feb6d4954cd11eb9663c5b9ce363 -Author: Ivo Timmermans -Date: Tue Apr 18 15:59:22 2000 +0000 - - New manpage for genauth. - -commit d11cfcec74e25ee2b88acea62ca5ef973ab7204b -Author: Ivo Timmermans -Date: Tue Apr 18 15:09:11 2000 +0000 - - Submitted by Mads Kiilerich. - -commit 93287d2b2c77d4b9e3f85f36ef4f9230fe3bf9b3 -Author: Ivo Timmermans -Date: Mon Apr 17 17:04:33 2000 +0000 - - Default passphrase length of 1024, added -h/--help options. - -commit 9c2ac77594d83a810c53faf6979e0b76006ecd0e -Author: Ivo Timmermans -Date: Mon Apr 17 16:59:42 2000 +0000 - - Check if stdout is a terminal, if so, print a verbose message. - -commit c9246896901ff1ebad91ac399a4ea79fad941f75 -Author: Ivo Timmermans -Date: Mon Apr 17 16:52:58 2000 +0000 - - Check for an illegal length of passphrase in read_passphrase(). - -commit baebae274913d912d76ba1d545f337dfb945fc5c -Author: Ivo Timmermans -Date: Mon Apr 17 16:23:29 2000 +0000 - - Pass the requested size from xmalloc() and xrealloc() on to xalloc_fail_func() - -commit 210a92cae90deb5b4a410b1b7d5c625c5c5f2ffb -Author: Ivo Timmermans -Date: Mon Apr 17 15:38:47 2000 +0000 - - Only one round of reading bits out of urandom; - Reading `bytes' bytes out of it; - Print a newline after completion. - -commit 5b44b91eb408d76af646b031da2364a769b44771 -Author: Ivo Timmermans -Date: Wed Apr 12 16:22:39 2000 +0000 - - Moved to version number 1.0. - -commit 18e044bde3b508c991910218989b4bacc3a4934e -Author: Ivo Timmermans -Date: Thu Apr 6 18:28:29 2000 +0000 - - New option -D, don't detach. - -commit 523c80c4e35b7ff8ad94b41a6071dbe2b8ff6ec7 -Author: Ivo Timmermans -Date: Tue Mar 28 19:16:27 2000 +0000 - - Ignore SIGCHLD. - -commit f2076e3e7031ac8ad87eb6aab0cea40f379dd0c6 -Author: Ivo Timmermans -Date: Tue Mar 28 19:09:52 2000 +0000 - - Kill the parent after any error conditions in detach(). - -commit 98de35c742498878a27fb29becd3b7154525a60f -Author: Ivo Timmermans -Date: Mon Mar 27 22:59:16 2000 +0000 - - Upon regeneration, free the old encryption key `securely\' by overwriting it. - -commit b50523dc44bbb32f03d24573e195c071cbff3fc4 -Author: Ivo Timmermans -Date: Mon Mar 27 22:30:27 2000 +0000 - - Get rid of the message `zxnrbl\'. - -commit 1243156a5e03a666b36bc4400f1402243a85c9a7 -Author: Ivo Timmermans -Date: Sun Mar 26 00:33:07 2000 +0000 - - Initial revision diff --git a/Makefile.am b/Makefile.am index e69542e..8e43fe5 100644 --- a/Makefile.am +++ b/Makefile.am @@ -2,39 +2,14 @@ AUTOMAKE_OPTIONS = gnu -SUBDIRS = src doc test systemd +SUBDIRS = src doc systemd -ACLOCAL_AMFLAGS = -I m4 +ACLOCAL_AMFLAGS = -I m4 EXTRA_DIST = COPYING.README README.android -@CODE_COVERAGE_RULES@ - -# If git describe works, force autoconf to run in order to make sure we have the -# current version number from git in the resulting configure script. -configure-version: - -cd $(srcdir) && git describe && autoconf --force - -# Triggering the README target means we are building a distribution (make dist). -README: configure-version - ChangeLog: - (cd $(srcdir) && git log) > ChangeLog - -deb: - dpkg-buildpackage -rfakeroot - -rpm: dist - cp $(distdir).tar.gz /usr/src/redhat/SOURCES/ - cp redhat/tinc.spec /usr/src/redhat/SOURCES/ - cd /usr/src/redhat/SOURCES/ && rpm -bb tinc.spec - -release: - rm -f ChangeLog - $(MAKE) ChangeLog - echo "Please edit the NEWS file now..." - /usr/bin/editor $(srcdir)/NEWS - $(MAKE) dist + git log > ChangeLog astyle: astyle --options=.astylerc -nQ src/*.[ch] src/*/*.[ch] diff --git a/Makefile.in b/Makefile.in index e462e23..e1f2745 100644 --- a/Makefile.in +++ b/Makefile.in @@ -94,12 +94,9 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \ $(top_srcdir)/m4/ax_cflags_warn_all.m4 \ $(top_srcdir)/m4/ax_check_compile_flag.m4 \ $(top_srcdir)/m4/ax_check_link_flag.m4 \ - $(top_srcdir)/m4/ax_code_coverage.m4 \ - $(top_srcdir)/m4/ax_require_defined.m4 \ - $(top_srcdir)/m4/curses.m4 $(top_srcdir)/m4/libgcrypt.m4 \ - $(top_srcdir)/m4/lzo.m4 $(top_srcdir)/m4/miniupnpc.m4 \ - $(top_srcdir)/m4/openssl.m4 $(top_srcdir)/m4/readline.m4 \ - $(top_srcdir)/m4/zlib.m4 $(top_srcdir)/configure.ac + $(top_srcdir)/m4/ax_require_defined.m4 $(top_srcdir)/m4/lzo.m4 \ + $(top_srcdir)/m4/openssl.m4 $(top_srcdir)/m4/zlib.m4 \ + $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \ @@ -222,15 +219,8 @@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ -CODE_COVERAGE_CFLAGS = @CODE_COVERAGE_CFLAGS@ -CODE_COVERAGE_CPPFLAGS = @CODE_COVERAGE_CPPFLAGS@ -CODE_COVERAGE_CXXFLAGS = @CODE_COVERAGE_CXXFLAGS@ -CODE_COVERAGE_ENABLED = @CODE_COVERAGE_ENABLED@ -CODE_COVERAGE_LDFLAGS = @CODE_COVERAGE_LDFLAGS@ -CODE_COVERAGE_LIBS = @CODE_COVERAGE_LIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ -CURSES_LIBS = @CURSES_LIBS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ @@ -239,21 +229,17 @@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ -GCOV = @GCOV@ -GENHTML = @GENHTML@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -LCOV = @LCOV@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ -MINIUPNPC_LIBS = @MINIUPNPC_LIBS@ MKDIR_P = @MKDIR_P@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ @@ -264,8 +250,6 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ -READLINE_LIBS = @READLINE_LIBS@ -SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ @@ -323,8 +307,8 @@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ AUTOMAKE_OPTIONS = gnu -SUBDIRS = src doc test systemd -ACLOCAL_AMFLAGS = -I m4 +SUBDIRS = src doc systemd +ACLOCAL_AMFLAGS = -I m4 EXTRA_DIST = COPYING.README README.android all: config.h $(MAKE) $(AM_MAKEFLAGS) all-recursive @@ -489,6 +473,12 @@ distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) + @case `sed 15q $(srcdir)/NEWS` in \ + *"$(VERSION)"*) : ;; \ + *) \ + echo "NEWS not updated; not releasing" 1>&2; \ + exit 1;; \ + esac $(am__remove_distdir) test -d "$(distdir)" || mkdir "$(distdir)" @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ @@ -801,33 +791,8 @@ uninstall-am: .PRECIOUS: Makefile -@CODE_COVERAGE_RULES@ - -# If git describe works, force autoconf to run in order to make sure we have the -# current version number from git in the resulting configure script. -configure-version: - -cd $(srcdir) && git describe && autoconf --force - -# Triggering the README target means we are building a distribution (make dist). -README: configure-version - ChangeLog: - (cd $(srcdir) && git log) > ChangeLog - -deb: - dpkg-buildpackage -rfakeroot - -rpm: dist - cp $(distdir).tar.gz /usr/src/redhat/SOURCES/ - cp redhat/tinc.spec /usr/src/redhat/SOURCES/ - cd /usr/src/redhat/SOURCES/ && rpm -bb tinc.spec - -release: - rm -f ChangeLog - $(MAKE) ChangeLog - echo "Please edit the NEWS file now..." - /usr/bin/editor $(srcdir)/NEWS - $(MAKE) dist + git log > ChangeLog astyle: astyle --options=.astylerc -nQ src/*.[ch] src/*/*.[ch] diff --git a/NEWS b/NEWS index a458dd9..c587e87 100644 --- a/NEWS +++ b/NEWS @@ -1,732 +1,758 @@ -# Version 1.1pre17 October 8 2018 +Version 1.0.36 August 26 2019 -* Prevent oracle attacks in the legacy protocol (CVE-2018-16737, - CVE-2018-16738). -* Prevent a MITM from forcing a NULL cipher for UDP in the legacy protocol - (CVE-2018-16758). -* AutoConnect is now enabled by default. -* Per-node network traffic statistics are now shown in the output of "info" and - "dump nodes" commands. + * Fix compiling tinc with certain versions of the OpenSSL library. + * Fix parsing some IPv6 addresses with :: in them. + * Fix GraphDumpFile output to handle node names starting with a digit. + * Fix a potential segmentation fault when fragmenting packets. -Thanks to volth and Rafael Sadowski for their contributions to this version of -tinc. - -# Version 1.1pre16 June 12 2018 - -* Fixed building with support for UML sockets. -* Documentation updates and spelling fixes. -* Support for MSS clamping of IP-in-IP packets. -* Fixed parsing of the -b flag. -* Added the ability to set a firemall mark on sockets on Linux. -* Minor improvements to the build system. -* Added a cache of recently seen addresses of peers. -* Add support for --runstatedir to the configure script. -* Fixed linking with libncurses on some distributions. -* Automatically disable PMTUDiscovery when TCPOnly is enabled. -* Fixed removing the tinc service on Windows in some situations. -* Fixed the TAP-Win32 device locking up after waking up from suspend. - -Thanks to Todd C. Miller, Etienne Dechamps, Daniel Lublin, -Gjergji Ramku, Mike Sullivan and Oliver Freyermuth for their +Thanks to Rosen Penev, Quentin Rameau and Werner Schreiber for their contributions to this version of tinc. -# Version 1.1pre15 September 2 2017 +Version 1.0.35 October 5 2018 -* Detect when the machine is resuming from suspension or hibernation. -* When an old PID file is found, check whether the old daemon is still alive. -* Remember scope_id for IPv6 addresses when sending UDP packets to link-local - addresses. -* Ensure compatibility with OpenSSL 1.1. -* Only log about dropped packets with debug level 5. -* Warn when trying to generate RSA keys less than 2048 bits. -* Use AES256 and SHA256 as the default encryption and digest algorithms. -* Add DeviceType = fd to support tinc on Android without requiring root. -* Support PriorityInheritance for IPv6 packets. -* Fixes for Solaris tun/tap support. -* Add a configurable expiration time for invitations. -* Store invitation data after a successful join. -* Exit gracefully when the tun/tap device is in a bad state. -* Add the LogLevel option. -* AutoConnect now actively tries to heal split networks. + * Prevent oracle attacks (CVE-2018-16737, CVE-2018-16738). + * Prevent a MITM from forcing a NULL cipher for UDP (CVE-2018-16758). + * Minor fixes in the documentation. -Thanks to Etienne Dechamps, Rafał Leśniak, Sean McVeigh, Vittorio Gambaletta, -Dennis Lan, Pacien Tran-Girard, Roman Savelyev, lemoer and volth for their -contributions to this version of tinc. +Thanks to Amine Amri and Rafael Sadowski for their contributions to this +version of tinc. -# Version 1.1pre14 May 1 2016 +Version 1.0.34 June 12 2018 -* Add tinc.service back. + * Fix a potential segmentation fault when connecting to an IPv6 peer via a + proxy. + * Minor improvements to the build system. + * Make the systemd service file identical to the one from the 1.1 branch. + * Fix a potential problem causing IPv4 sockets to not work on macOS. -# Version 1.1pre13 April 30 2016 +Thanks to Maximilian Stein and Wang Liu Shuai for their contributions to this +version of tinc. -* Fix BSD tun device support that was broken in 1.1pre12. -* Speed up AutoConnect when there are many host config files present without - an Address. +Version 1.0.33 November 4 2017 -# Version 1.1pre12 April 24 2016 + * Allow compilation from a build directory. + * Source code cleanups. + * Fix some options specified on the command line not surviving a HUP signal. + * Handle tun/tap device returning EPERM or EBUSY. + * Disable PMTUDiscovery when TCPOnly is used. + * Support the --runstatedir option of the autoconf 2.70. -* Added a "--syslog" option to force logging to syslog even if running in the - foreground. -* Fixes and improvements to the DecrementTTL function. -* Improved PMTU discovery and UDP keepalive probes. -* More efficient relaying of UDP packets through intermediate nodes. -* Improved compatibility with newer TAP-Win32 drivers. -* Added support for UPnP. -* Allow tinc to be compiled without LibreSSL or OpenSSL (this drops - compatibility with nodes running 1.0.x). -* Added a "fsck" command to check the configuration files for problems. -* Tinc "start" now checks whether the daemon really started successfully, and - displays error messages otherwise. -* Added systemd service files. -* Use the recvmmsg() function if available. -* Support ToS/Diffserv on IPv6 connections. -* Updated support for BSD tun/tap devices. -* Added support for OS X utun interfaces. -* Dropped support for Windows 2000. -* Initial support for generating a tinc-up script from an invitation. -* Many small fixes, documentation updates. +Thanks to Rafael Sadowski and Pierre-Olivier Mercier for their contributions to +this version of tinc. -Thanks to Etienne Dechamps, Rafał Leśniak, Vittorio Gambaletta, Martin Weinelt, -Sven-Haegar Koch, Florian Klink, LunnarShadow, Dato Simó, Jo-Philipp Wich, -Jochen Voss, Nathan Stratton Treadway, Pierre Emeriaud, xentec, Samuel -Thibault and Michael Tokarev for their contributions to this version of tinc. +Version 1.0.32 September 2 2017 -# Version 1.1pre11 December 27 2014 + * Fix segmentation fault when using Cipher = none. + * Fix Proxy = exec. + * Support PriorityInheritance for IPv6 packets. + * Fixes for Solaris tun/tap support. + * Bind outgoing TCP sockets when ListenAddress is used. -* Added a "network" command to list or switch networks. -* Switched to Ed25519 keys and the ChaCha-Poly1305 cipher for the new protocol. -* AutoConnect is now a boolean option, when enabled tinc always tries to keep - at least three meta-connections open. -* The new protocol now uses UDP much more often. -* Tinc "del" and "get" commands now return a non-zero exit code when they - don't find the requested variable. -* Updated documentation. -* Added a "DeviceStandby" option to defer running tinc-up until a working - connection is made, and which on Windows will also change the network - interface link status accordingly. -* Tinc now tells the resolver to reload /etc/resolv.conf when it receives - SIGALRM. -* Improved error messages and event loop handling on Windows. -* LocalDiscovery now uses local address learned from other nodes, and is - enabled by default. -* Added a "BroadcastSubnet" option to change the behavior of broadcast packets - in router mode. -* Added support for dotted quad notation in IPv6 (e.g. ::1.2.3.4). -* Improved format of printed Subnets, MAC and IPv6 addresses. -* Added a "--batch" option to force the tinc CLI to run in non-interactive - mode. -* Improve default Device selection on *BSD and Mac OS X. -* Allow running tinc without RSA keys. +Thanks to Vittorio Gambaletta for his contribution to this version of tinc. -Thanks to Etienne Dechamps, Sven-Haegar Koch, William A. Kennington III, -Baptiste Jonglez, Alexis Hildebrandt, Armin Fisslthaler, Franz Pletz, Alexander -Ried and Saverio Proto for their contributions to this version of tinc. +Version 1.0.31 January 15 2017 -# Version 1.1pre10 February 7 2014 + * Remove ExecStop in tinc@.service. -* Added a benchmark tool (sptps_speed) for the new protocol. -* Fixed a crash when using Name = $HOST while $HOST is not set. -* Use AES-256-GCM for the new protocol. -* Updated support for Solaris. -* Allow running tincd without a private ECDSA key present when - ExperimentalProtocol is not explicitly set. -* Enable various compiler hardening flags by default. -* Added support for a "conf.d" configuration directory. -* Fix tinc-gui on Windows, also allowing it to connect to a 32-bits tincd when - tinc-gui is run in a 64-bits Python environment. -* Added a "ListenAddress" option, which like BindToAddress adds more listening - address/ports, but doesn't bind to them for outgoing sockets. -* Make invitations work better when the "invite" and "join" commands are not - run interactively. -* When creating meta-connections to a node for which no Address statement is - specified, try to use addresses learned from other nodes. +Thanks to Élie Bouttier for his contribution to this version of tinc. -Thanks to Dennis Joachimsthaler and Florent Clairambault for their contribution -to this version of tinc. +Version 1.0.30 October 30 2016 -# Version 1.1pre9 September 8 2013 + * Fix troubles connecting to some HTTP proxies. -* The UNIX socket is now created before tinc-up is called. -* Windows users can now use any extension that is in %PATHEXT% for scripts, - not only .bat. -* Outgoing sockets are bound to the address of the listening sockets again, - when there is no ambiguity. -* Added invitation-created and invitation-accepted scripts. -* Invited nodes now learn of the Mode and Broadcast settings of the VPN. -* Joining a VPN with an invitation now also works on Windows. -* The port number tincd is listening on is now always included in the - invitation URL. -* A running tincd is now correctly informed when a new invitation has been - generated. -* Several bug fixes for the new protocol. -* Added a test suite. + * Add mitigations for the Sweet32 attack when using a 64-bit block cipher. + + * Use AES256 and SHA256 as the default encryption and digest algorithms. + +Version 1.0.29 October 9 2016 + + * Fix UDP communication with peers with link-local IPv6 addresses. + + * Ensure compatibility with OpenSSL 1.1.0. + + * Ensure autoreconf can be run without requiring autoconf-archive. + + * Log warnings about dropped packets only at debug level 5. + +Version 1.0.28 April 10 2016 + + * Fix compilation on BSD platforms. + + * Add systemd service files. + +Version 1.0.27 April 10 2016 + + * When using Proxy, let the proxy resolve hostnames if tinc can't. + + * Fixes and improvements of the DecrementTTL option. + + * Fixed the $NAME variable in subnet-up/down scripts for the local Subnets. + + * Fixed potentially wrong checksum generation when clamping the MSS. + + * Properly choose between the system's or our own copy of getopt. + + * Fixed compiling tinc for Cygwin with MinGW installed. + + * Added support for OS X utun interfaces. + + * Documentation updates and minor fixes. + +Thanks to Vittorio Gambaletta, LunarShaddow, Florian Weik and Nathan Stratton +Treadway for their contributions to this version of tinc. + +Version 1.0.26 July 5 2015 + + * Tinc now forces glibc to reload /etc/resolv.conf for every hostname lookup. + + * Fixed --logfile without a filename on Windows. + + * Ensure tinc can be compiled when using musl libc. + +Thanks to Jo-Philipp Wich for his contribution to this version of tinc. + +Version 1.0.25 December 22 2014 + + * Documentation updates. + + * Support linking against -lresolv on Mac OS X. + + * Fix scripts on Windows when using the ScriptsInterpreter option. + + * Allow a minimum reconnect timeout to be specified. + + * Support PriorityInheritance on IPv6 sockets. + +Thanks to David Pflug, Baptiste Jonglez, Alexis Hildebrandt, Borg, Jochen Voss, +Tomislav Čohar and VittGam for their contributions to this version of tinc. + +Version 1.0.24 May 11 2014 + + * Various compiler hardening flags are enabled by default. + + * Updated support for Solaris, allowing switch mode on Solaris 11. + + * Configuration will now also be read from a conf.d directory. + + * Various updates to the documentation. + + * Tinc now forces glibc to reload /etc/resolv.conf after it receives SIGALRM. + + * Fixed a potential routing loop when IndirectData or TCPOnly is used and + broadcast packets are being sent. + + * Improved security with constant time memcmp and stricter use of OpenSSL's + RNG functions. + + * Fixed all issues found by Coverity. + +Thanks to Florent Clairambault, Vilbrekin, luckyhacky, Armin Fisslthaler, Loïc +Dachary and Steffan Karger for their contributions to this version of tinc. + +Version 1.0.23 October 19 2013 + + * Start authentication immediately on outgoing connections (useful for sslh). + + * Fixed segfault when Name = $HOST but $HOST is not set. + + * Updated the build system and the documentation. + + * Clean up child processes left over from Proxy = exec. + +Version 1.0.22 August 13 2013 + + * Fixed the combination of Mode = router and DeviceType = tap. + + * The $NAME variable is now set in subnet-up/down scripts. + + * Tinc now gives an error when unknown options are given on the command line. + + * Tinc now correctly handles a space between a short command line option and + an optional argument. Thanks to Etienne Dechamps for his contribution to this version of tinc. -# Version 1.1pre8 August 13 2013 +Version 1.0.21 April 22 2013 -* ExperimentalProtocol is now enabled by default. -* Added an invitation protocol that makes it easy to invite new nodes. -* Added the LocalDiscoveryAddress option to change the broadcast address used - to find local nodes. -* Limit the rate of incoming meta-connections. -* Many small bug fixes and code cleanups. - -Thanks to Etienne Dechamps and Sven-Haegar Koch for their contributions to this -version of tinc. - -# Version 1.1pre7 April 22 2013 - -* Fixed large latencies on Windows. -* Renamed the tincctl tool to tinc. -* Simplified changing the configuration using the tinc tool. -* Added a full description of the ExperimentalProtocol to the manual. -* Drop packets forwarded via TCP if they are too big (CVE-2013-1428). - -Thanks to Martin Schobert for auditing tinc and reporting the vulnerability. - -# Version 1.1pre6 February 20 2013 - -* Fixed tincd exitting immediately on Windows. -* Detect PMTU increases. -* Fixed crashes when using a SOCKS5 proxy. -* Fixed control connection when using a proxy. - -# Version 1.1pre5 January 20 2013 - -* Fixed long delays and possible hangs on Windows. -* Fixed support for the tunemu device on iOS, the UML and VDE devices. -* Small improvements to the documentation and error messages. -* Fixed broadcast packets not reaching the whole VPN. -* Tincctl now connects via a UNIX socket to the tincd on platforms that - support this. -* The PriorityInheritance option now also works in switch mode. - -# Version 1.1pre4 December 5 2012 - -* Added the "AutoConnect" option which will let tinc automatically select - which nodes to connect to. -* Improved performance of VLAN-tagged IP traffic inside the VPN. -* Ensured LocalDiscovery works with multiple BindToAddress statements and/or - IPv6-only LANs. -* Dropped dependency on libevent. -* Fixed Windows version not reading packets from the TAP adapter. - -# Version 1.1pre3 October 14 2012 - -* New experimental protocol: - * Uses 521 bit ECDSA keys for authentication. - * Uses AES-256-CTR and HMAC-SHA256. - * Always provides perfect forward secrecy. - * Used for both meta-connections and VPN packets. - * VPN packets are encrypted end-to-end. -* Many improvements to tincctl: - * "config" command shows/adds/changes configuration variables. - * "export" and "import" commands help exchange configuration files. - * "init" command sets up initial configuration files. - * "info" command shows details about a node, subnet or address. - * "log" command shows live log messages. - * Without a command it acts as a shell, with history and TAB completion. - * Improved starting/stopping tincd. - * Improved graph output. -* When trying to directly send UDP packets to a node for which multiple - addresses are known, all of them are tried. -* Many small fixes, code cleanups and documentation updates. - -# Version 1.1pre2 July 17 2011 - -* .cookie files are renamed to .pid files, which are compatible with 1.0.x. -* Experimental protocol enhancements that can be enabled with the option - ExperimentalProtocol = yes: - - * Ephemeral ECDH key exchange will be used for both the meta protocol and - UDP session keys. - * Key exchanges are signed with ECDSA. - * ECDSA public keys are automatically exchanged after RSA authentication if - nodes do not know each other's ECDSA public key yet. - -# Version 1.1pre1 June 25 2011 - -* Control interface allows control of a running tinc daemon. Used by: - * tincctl, a commandline utility - * tinc-gui, a preliminary GUI implemented in Python/wxWidgets -* Code cleanups and reorganization. -* Repleacable cryptography backend, currently supports OpenSSL and libgcrypt. -* Use libevent to handle I/O events and timeouts. -* Use splay trees instead of AVL trees to manage internal datastructures. - -Thanks to Scott Lamb and Sven-Haegar Koch for their contributions to this -version of tinc. - -# Version 1.0.22 August 13 2013 - -* Fixed the combination of Mode = router and DeviceType = tap. -* The $NAME variable is now set in subnet-up/down scripts. -* Tinc now gives an error when unknown options are given on the command line. -* Tinc now correctly handles a space between a short command line option and - an optional argument. - -Thanks to Etienne Dechamps for his contribution to this version of tinc. - -# Version 1.0.21 April 22 2013 - -* Drop packets forwarded via TCP if they are too big (CVE-2013-1428). + * Drop packets forwarded via TCP if they are too big (CVE-2013-1428). Thanks to Martin Schobert for auditing tinc and reporting this vulnerability. -# Version 1.0.20 March 03 2013 +Version 1.0.20 March 03 2013 -* Use /dev/tap0 by default on FreeBSD and NetBSD when using switch mode. -* Minor improvements and clarifications in the documentation. -* Allow tinc to be cross-compiled with Android's NDK. -* The discovered PMTU is now also applied to VLAN tagged traffic. -* The LocalDiscovery option now makes use of all addresses tinc is bound to. -* Fixed support for tunemu on iOS devices. -* The PriorityInheritance option now also works with switch mode. -* Fixed tinc crashing when using a SOCKS5 proxy. + * Use /dev/tap0 by default on FreeBSD and NetBSD when using switch mode. + + * Minor improvements and clarifications in the documentation. + + * Allow tinc to be cross-compiled with Android's NDK. + + * The discovered PMTU is now also applied to VLAN tagged traffic. + + * The LocalDiscovery option now makes use of all addresses tinc is bound to. + + * Fixed support for tunemu on iOS devices. + + * The PriorityInheritance option now also works with switch mode. + + * Fixed tinc crashing when using a SOCKS5 proxy. Thanks to Mesar Hameed, Vilbrekin and Martin Schürrer for their contributions to this version of tinc. -# Version 1.0.19 June 25 2012 +Version 1.0.19 June 25 2012 -* Allow :: notation in IPv6 Subnets. -* Add support for systemd style socket activation. -* Allow environment variables to be used for the Name option. -* Add basic support for SOCKS proxies, HTTP proxies, and proxying through an - external command. + * Allow :: notation in IPv6 Subnets. -# Version 1.0.18 March 25 2012 + * Add support for systemd style socket activation. -* Fixed IPv6 in switch mode by turning off DecrementTTL by default. -* Allow a port number to be specified in BindToAddress, which also allows tinc - to listen on multiple ports. -* Add support for multicast communication with UML/QEMU/KVM. + * Allow environment variables to be used for the Name option. -# Version 1.0.17 March 10 2012 + * Add basic support for SOCKS proxies, HTTP proxies, and proxying through an + external command. -* The DeviceType option can now be used to select dummy, raw socket, UML and - VDE devices without needing to recompile tinc. -* Allow multiple BindToAddress statements. -* Decrement TTL value of IPv4 and IPv6 packets. -* Add LocalDiscovery option allowing tinc to detect peers that are behind the - same NAT. -* Accept Subnets passed with the -o option when StrictSubnets = yes. -* Disabling old RSA keys when generating new ones now also works properly on - Windows. +Thanks to Anthony G. Basile and Michael Tokarev for their contributions to +this version of tinc. -# Version 1.0.16 July 23 2011 +Version 1.0.18 March 25 2012 -* Fixed a performance issue with TCP communication under Windows. -* Fixed code that, during network outages, would cause tinc to exit when it - thought two nodes with identical Names were on the VPN. + * Fixed IPv6 in switch mode by turning off DecrementTTL by default. -# Version 1.0.15 June 24 2011 + * Allow a port number to be specified in BindToAddress, which also allows tinc + to listen on multiple ports. -* Improved logging to file. -* Reduced amount of process wakeups on platforms which support pselect(). -* Fixed ProcessPriority option under Windows. + * Add support for multicast communication with UML/QEMU/KVM. - Thanks to Loïc Grenié for his contribution to this version of tinc. +Version 1.0.17 March 10 2012 -# Version 1.0.14 May 8 2011 + * The DeviceType option can now be used to select dummy, raw socket, UML and + VDE devices without needing to recompile tinc. -* Fixed reading configuration files that do not end with a newline. Again. -* Allow arbitrary configuration options being specified on the command line. -* Allow all options in both tinc.conf and the local host config file. -* Configurable replay window, UDP send and receive buffers for performance tuning. -* Try harder to get UDP communication back after falling back to TCP. -* Initial support for attaching tinc to a VDE switch. -* DragonFly BSD support. -* Allow linking with OpenSSL 1.0.0. + * Allow multiple BindToAddress statements. -Thanks to Brandon Black, Julien Muchembled, Michael Tokarev, Rumko and Timothy -Redaelli for their contributions to this version of tinc. + * Decrement TTL value of IPv4 and IPv6 packets. -# Version 1.0.13 Apr 11 2010 + * Add LocalDiscovery option allowing tinc to detect peers that are behind the + same NAT. -* 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. + * Accept Subnets passed with the -o option when StrictSubnets = yes. -# Version 1.0.12 Feb 3 2010 + * Disabling old RSA keys when generating new ones now also works properly on + Windows. -* 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. +Thanks to Nick Hibma for his contribution to this version of tinc. -# Version 1.0.11 Nov 1 2009 +Version 1.0.16 July 23 2011 -* Fixed potential crash when the HUP signal is sent. -* Fixes handling of weighted Subnets in switch and hub modes, preventing - unnecessary broadcasts. -* Works around a MinGW bug that caused packets to Windows nodes to always be - sent via TCP. -* Improvements to the PMTU discovery code, especially on Windows. -* Use UDP again in certain cases where 1.0.10 was too conservative and fell - back to TCP unnecessarily. -* Allow fast roaming of hosts to other nodes in a switched VPN. + * Fixed a performance issue with TCP communication under Windows. -# Version 1.0.10 Oct 18 2009 + * Fixed code that, during network outages, would cause tinc to exit when it + thought two nodes with identical Names were on the VPN. -* Fixed potential crashes during shutdown and (in rare conditions) when other - nodes disconnected from the VPN. -* Improved NAT handling: tinc now copes with mangled port numbers, and will - automatically fall back to TCP if direct UDP connection between nodes is not - possible. The TCPOnly option should not have to be used anymore. -* Allow configuration files with CRLF line endings to be read on UNIX. -* Disable old RSA keys when generating new ones, and raise the default size of - new RSA keys to 2048 bits. -* Many fixes in the path MTU discovery code, especially when Compression is - being used. -* Tinc can now drop privileges and/or chroot itself. -* The TunnelServer code now just ignores information from clients instead of - disconnecting them. -* Improved performance on Windows by using the new ProcessPriority option and - by making the handling of packets received from the TAP-Win32 adapter more - efficient. -* Code cleanups: tinc now follows the C99 standard, copyright headers have - been updated to include patch authors, checkpoint tracing and localisation - features have been removed. -* Support for (jailbroken) iPhone and iPod Touch has been added. +Version 1.0.15 June 24 2011 -Thanks to Florian Forster, Grzegorz Dymarek and especially Michael Tokarev for -their contributions to this version of tinc. + * Improved logging to file. -# Version 1.0.9 Dec 26 2008 + * Reduced amount of process wakeups on platforms which support pselect(). -* Fixed tinc as a service under Windows 2003. -* Fixed reading configuration files that do not end with a newline. -* Fixed crashes in situations where hostnames could not be resolved or hosts - would disconnect at the same time as session keys were exchanged. -* Improved default settings of tun and tap devices on BSD platforms. -* Make IPv6 sockets bind only to IPv6 on Linux. -* Enable path MTU discovery by default. -* Fixed a memory leak that occurred when connections were closed. + * Fixed ProcessPriority option under Windows. -Thanks to Max Rijevski for his contributions to this version of tinc. +Version 1.0.14 May 8 2011 -# Version 1.0.8 May 16 2007 + * Fixed reading configuration files that do not end with a newline. Again. -* Fixed some memory and resource leaks. -* Made network sockets non-blocking under Windows. + * Allow arbitrary configuration options being specified on the command line. -Thanks to Scott Lamb and "dnk" for their contributions to this version of tinc. + * Allow all options in both tinc.conf and the local host config file. -# Version 1.0.7 Jan 5 2007 + * Configurable replay window, UDP send and receive buffers for performance tuning. -* Fixed a bug that caused slow network speeds on Windows. -* Fixed a bug that caused tinc unable to write packets to the tun device on - OpenBSD. + * Try harder to get UDP communication back after falling back to TCP. -# Version 1.0.6 Dec 18 2006 + * Initial support for attaching tinc to a VDE switch. -* More flexible detection of the LZO libraries when compiling. -* Fixed a bug where broadcasts in switch and hub modes sometimes would not - work anymore when part of the VPN had become disconnected from the rest. + * DragonFly BSD support. -# Version 1.0.5 Nov 14 2006 + * Allow linking with OpenSSL 1.0.0. -* Lots of small fixes. -* Broadcast packets no longer grow in size with each hop. This should - fix switch mode (again). -* Generic host-up and host-down scripts. -* Optionally dump graph in graphviz format to a file or a script. -* Support LZO 2.0 and later. + Thanks to Brandon Black, Julien Muchembled, Michael Tokarev, Rumko and Timothy + Redaelli for their contributions to this version of tinc. -Thanks to Scott Lamb for his contributions to this version of tinc. +Version 1.0.13 Apr 11 2010 -# Version 1.0.4 May 4 2005 + * Allow building tinc without LZO and/or Zlib. -* Fix switch and hub modes. -* Optionally start scripts when a Subnet becomes (un)reachable. + * Clamp MSS of TCP packets in both directions. -# Version 1.0.3 Nov 11 2004 + * 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. + + * 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. + + * Fixes handling of weighted Subnets in switch and hub modes, preventing + unnecessary broadcasts. + + * Works around a MinGW bug that caused packets to Windows nodes to always be + sent via TCP. + + * Improvements to the PMTU discovery code, especially on Windows. + + * Use UDP again in certain cases where 1.0.10 was too conservative and fell + back to TCP unnecessarily. + + * Allow fast roaming of hosts to other nodes in a switched VPN. + +Version 1.0.10 Oct 18 2009 + + * Fixed potential crashes during shutdown and (in rare conditions) when other + nodes disconnected from the VPN. + + * Improved NAT handling: tinc now copes with mangled port numbers, and will + automatically fall back to TCP if direct UDP connection between nodes is not + possible. The TCPOnly option should not have to be used anymore. + + * Allow configuration files with CRLF line endings to be read on UNIX. + + * Disable old RSA keys when generating new ones, and raise the default size of + new RSA keys to 2048 bits. + + * Many fixes in the path MTU discovery code, especially when Compression is + being used. + + * Tinc can now drop privileges and/or chroot itself. + + * The TunnelServer code now just ignores information from clients instead of + disconnecting them. + + * Improved performance on Windows by using the new ProcessPriority option and + by making the handling of packets received from the TAP-Win32 adapter more + efficient. + + * Code cleanups: tinc now follows the C99 standard, copyright headers have + been updated to include patch authors, checkpoint tracing and localisation + features have been removed. + + * Support for (jailbroken) iPhone and iPod Touch has been added. + + Thanks to Florian Forster, Grzegorz Dymarek and especially Michael Tokarev for + their contributions to this version of tinc. + +Version 1.0.9 Dec 26 2008 + + * Fixed tinc as a service under Windows 2003. + + * Fixed reading configuration files that do not end with a newline. + + * Fixed crashes in situations where hostnames could not be resolved or hosts + would disconnect at the same time as session keys were exchanged. + + * Improved default settings of tun and tap devices on BSD platforms. + + * Make IPv6 sockets bind only to IPv6 on Linux. + + * Enable path MTU discovery by default. + + * Fixed a memory leak that occurred when connections were closed. + + Thanks to Max Rijevski for his contributions to this version of tinc. + +Version 1.0.8 May 16 2007 + + * Fixed some memory and resource leaks. + + * Made network sockets non-blocking under Windows. + + Thanks to Scott Lamb and "dnk" for their contributions to this version of tinc. + +Version 1.0.7 Jan 5 2007 + + * Fixed a bug that caused slow network speeds on Windows. + + * Fixed a bug that caused tinc unable to write packets to the tun device on + OpenBSD. + +Version 1.0.6 Dec 18 2006 + + * More flexible detection of the LZO libraries when compiling. + + * Fixed a bug where broadcasts in switch and hub modes sometimes would not + work anymore when part of the VPN had become disconnected from the rest. + +version 1.0.5 Nov 14 2006 + + * Lots of small fixes. + + * Broadcast packets no longer grow in size with each hop. This should + fix switch mode (again). + + * Generic host-up and host-down scripts. + + * Optionally dump graph in graphviz format to a file or a script. + + * Support LZO 2.0 and later. + + Thanks to Scott Lamb for his contributions to this version of tinc. + +version 1.0.4 May 4 2005 + + * Fix switch and hub modes. + + * Optionally start scripts when a Subnet becomes (un)reachable. + +version 1.0.3 Nov 11 2004 * Show error message when failing to write a PID file. + * Ignore spaces at end of lines in config files. + * Fix handling of late packets. + * Unify BSD tun/tap device handling. This allows IPv6 on tun devices and anything on tap devices as long as the underlying OS supports it. + * Handle IPv6 on Solaris tun devices. + * Allow tinc to work properly under Windows XP SP2. + * Allow VLAN tagged Ethernet frames in switch and hub mode. + * Experimental PMTUDiscovery, TunnelServer and BlockingTCP options. -# Version 1.0.2 Nov 8 2003 +version 1.0.2 Nov 8 2003 * Fix address and hostname resolving under Windows. + * Remove warnings about non-existing scripts and unsupported address families. + * Use the event logger under Windows. + * Fix quoting of filenames and command line arguments under Windows. + * Strict checks for length incoming network packets and return values of cryptographic functions, + * Fix a bug in metadata handling that made the tinc daemon abort. -# Version 1.0.1 Aug 14 2003 +version 1.0.1 Aug 14 2003 * Allow empty lines in config files. + * Fix handling of spaces and backslashes in filenames under native Windows. + * Allow scripts to be executed under native Windows. + * Update documentation, make it less Linux specific. -# Version 1.0 Aug 4 2003 +version 1.0 Aug 4 2003 * Lots of small bugfixes and code cleanups. + * Throughput doubled and latency reduced. + * Added support for LZO compression. + * No need to set MAC address or disable ARP anymore. + * Added support for Windows 2000 and XP, both natively and in a Cygwin environment. -# Version 1.0pre8 Sep 16 2002 +version 1.0pre8 Sep 16 2002 * More fixes for subnets with prefixlength undivisible by 8. + * Added support for NetBSD and MacOS/X. + * Switched from undirected graphs to directed graphs to avoid certain race conditions and improve scalability. + * Generalized broadcasting and forwarding of protocol messages. + * Cleanup of source code. -# Version 1.0pre7 Apr 7 2002 + +version 1.0pre7 Apr 7 2002 * Don't do blocking read()s when getting a signal. + * Remove RSA key checking code, since it sometimes thinks perfectly good RSA keys are bad. + * Fix handling of subnets when prefixlength isn't divisible by 8. -# Version 1.0pre6 Mar 27 2002 + +version 1.0pre6 Mar 27 2002 * Improvement of redundant links: + * Non-blocking connects. + * Protocol broadcast messages can no longer go into an infinite loop. + * Graph algorithm updated to look harder for direct connections. + * Good support for routing IPv6 packets over the VPN. Works on Linux, FreeBSD, possibly OpenBSD but not on Solaris. + * Support for tunnels over IPv6 networks. Works on all supported operating systems. + * Optional compression of UDP connections using zlib. + * Optionally let UDP connections inherit TOS field of tunneled packets. + * Optionally start scripts when certain hosts become (un)reachable. -# Version 1.0pre5 Feb 9 2002 + +version 1.0pre5 Feb 9 2002 * Security enhancements: + * Added sequence number and optional message authentication code to the packets. + * Configurable encryption cipher and digest algorithms. + * More robust handling of dis- and reconnects. + * Added a "switch" and a "hub" mode to allow bridging setups. + * Preliminary support for routing of IPv6 packets. + * Supports Linux, FreeBSD, OpenBSD and Solaris. -# Version 1.0pre4 Jan 17 2001 + +It looks like this might be the last release before 1.0. + + +version 1.0pre4 Jan 17 2001 * Updated documentation; the documentation now reflects the configuration as it is. + * Some internal changes to make tinc scale better for large networks, such as using AVL trees instead of linked lists for the - connection list. + connection list. + * RSA keys can be stored in separate files if needed. See the documentation for more information. -* Tinc has now been reported to run on Linux PowerPC and FreeBSD x86. -# Version 1.0pre3 Oct 31 2000 +* tinc has now been reported to run on Linux PowerPC and FreeBSD x86. + + + +version 1.0pre3 Oct 31 2000 * The protocol has been redesigned, and although some details are still under discussion, this is secure. Care has been taken to resist most, if not all, attacks. + * Unfortunately this protocol is not compatible with earlier versions, nor are earlier versions compatible with this version. Because the older protocol has huge security flaws, we feel that not implementing backwards compatibility is justified. + * Some data about the protocol: + * It uses public/private RSA keys for authentication (this is the actual fix for the security hole). + * All cryptographic functions have been taken out of tinc, instead it uses the OpenSSL library functions. + * Offers support for multiple subnets per tinc daemon. + * New is also the support for the universal tun/tap device. This means better portability to FreeBSD and Solaris. -* Tinc is tested to compile on Solaris, Linux x86, Linux alpha. -* Tinc now uses the OpenSSL library for cryptographic operations. + +* tinc is tested to compile on Solaris, Linux x86, Linux alpha. + +* tinc now uses the OpenSSL library for cryptographic operations. More information on getting and installing OpenSSL is in the manual. This also means that the GMP library is no longer required. + * Further, thanks to Enrique Zanardi, we have Spanish messages; Matias Carrasco provided us with a Spanish translation of the manual. -# Version 1.0pre2 May 31 2000 -* This version has been internationalized; and a Dutch translation has - been included. -* Two configuration variables have been added: - * VpnMask - the IP network mask for the entire VPN, not just our - subnet (as given by MyVirtualIP). The Redhat and Debian packages - use this variable in their system startup scripts, but it is - ignored by tinc. - * Hostnames - if set to `yes', look up the names of IP addresses - trying to connect to us. Default set to `no', to prevent lockups - during lookups. -* The system startup scripts for Debian and Redhat use - /etc/tinc/nets.boot to find out which networks need to be started - during system boot. -* Fixes to prevent denial of service attacks by sending random data - after connecting (and even when the connection has been established), - either random garbage or just nonsensical protocol fields. -* Tinc will retry to connect upon startup, does not quit if it doesn't - work the first time. -* Hosts that are disconnected implicitly if we lose a connection get - deleted from the internal list, to prevent hogging each other with - add and delete requests when the connection is restored. +What still needs to be done before 1.0: -# Version 1.0pre1 May 12 2000 +* Documentation. Especially since the protocol has changed, and a lot + of configuration directives have been added. -* New meta-protocol -* Various other bugfixes -* Documentation updates -# Version 0.3.3 Feb 9 2000 -* Fixed bug that made tinc stop working with latest kernels -* Updated the manual -# Version 0.3.2 Nov 12 1999 +version 1.0pre2 May 31 2000 -* No more `Invalid filedescriptor' when working with multiple - connections. -* Forward unknown packets to uplink. +* This version has been internationalized; and a Dutch translation has + been included. + +* Two configuration variables have been added: + * VpnMask - the IP network mask for the entire VPN, not just our + subnet (as given by MyVirtualIP). The Redhat and Debian packages + use this variable in their system startup scripts, but it is + ignored by tinc. + * Hostnames - if set to `yes', look up the names of IP addresses + trying to connect to us. Default set to `no', to prevent lockups + during lookups. + +* The system startup scripts for Debian and Redhat use + /etc/tinc/nets.boot to find out which networks need to be started + during system boot. + +* Fixes to prevent denial of service attacks by sending random data + after connecting (and even when the connection has been established), + either random garbage or just nonsensical protocol fields. + +* tinc will retry to connect upon startup, does not quit if it doesn't + work the first time. + +* Hosts that are disconnected implicitly if we lose a connection get + deleted from the internal list, to prevent hogging eachother with + add and delete requests when the connection is restored. + + +What still needs to be done before 1.0: + +* Documentation. +* Failover ConnectTo lines, try another one if the first doesn't work. -# Version 0.3.1 Oct 20 1999 -* Fixed a bug where tinc would exit without a trace. -# Version 0.3 Aug 20 1999 -* Pings now work immediately. -* All packet sizes get transmitted correctly. +version 1.0pre1 May 12 2000 + * New meta-protocol + * Various other bugfixes + * Documentation updates -# Version 0.2.26 Aug 15 1999 +version 0.3.3 Feb 9 2000 + * Fixed bug that made tinc stop working with latest kernels (Guus + Sliepen) + * Updated the manual -* Fixed some remaining bugs. -* --sysconfdir works with configure. -* Last version before 0.3. +version 0.3.2 Nov 12 1999 + * no more `Invalid filedescriptor' when working with multiple + connections + * forward unknown packets to uplink -# Version 0.2.25 Aug 8 1999 +version 0.3.1 Oct 20 1999 + * fixed a bug where tinc would exit without a trace -* Improved stability, going towards 0.3 now. +version 0.3 Aug 20 1999 + * pings now work immediately + * all packet sizes get transmitted correctly -# Version 0.2.24 Aug 7 1999 +version 0.2.26 Aug 15 1999 + * fixed some remaining bugs + * --sysconfdir works with configure + * last version before 0.3 -* Added key aging, there's a new config variable, KeyExpire. -* Updated man and info pages. +version 0.2.25 Aug 8 1999 + * improved stability, going towards 0.3 now. -# Version 0.2.23 Aug 5 1999 +version 0.2.24 Aug 7 1999 + * added key aging, there's a new config variable, KeyExpire. + * updated man and info pages -* All known bugs fixed, this is a candidate for 0.3. +version 0.2.23 Aug 5 1999 + * all known bugs fixed, this is a candidate for 0.3 -# Version 0.2.22 Apr 11 1999 +version 0.2.22 Apr 11 1999 + * multiconnection thing is now working nearly perfect :) -* Multiconnection thing is now working nearly perfect :) - -# Version 0.2.21 Apr 10 1999 - -* You shouldn't notice a thing, but a lot has changed wrt key +version 0.2.21 Apr 10 1999 + * You shouldn't notice a thing, but a lot has changed wrt key management - except that it refuses to talk to versions < 0.2.20 -# Version 0.2.19 Apr 3 1999 +version 0.2.20 -* Don't install a libcipher.so. +version 0.2.19 Apr 3 1999 + * don't install a libcipher.so -# Version 0.2.18 Apr 3 1999 +version 0.2.18 Apr 3 1999 + * blowfish library dynamically loaded upon execution + * included Eric Young's IDEA library -* Blowfish library dynamically loaded upon execution. -* Included Eric Young's IDEA library. +version 0.2.17 Apr 1 1999 + * tincd now re-executes itself in case of a segmentation fault. -# Version 0.2.17 Apr 1 1999 +version 0.2.16 Apr 1 1999 + * wrote tincd.conf(5) man page, which still needs a lot of work. + * config file now accepts and tolerates spaces, and any integer base +for integer variables, and better error reporting. See +doc/tincd.conf.sample for an example. -* Tincd now re-executes itself in case of a segmentation fault. +version 0.2.15 Mar 29 1999 + * fixed bugs -# Version 0.2.16 Apr 1 1999 +version 0.2.14 Feb 10 1999 + * added --timeout flag and PingTimeout configuration + * did some first syslog cleanup work -* Wrote tincd.conf(5) man page, which still needs a lot of work. -* Config file now accepts and tolerates spaces, and any integer base - for integer variables, and better error reporting. See - doc/tincd.conf.sample for an example. +version 0.2.13 Jan 23 1999 + * bugfixes -# Version 0.2.15 Mar 29 1999 +version 0.2.12 Jan 23 1999 + * fixed nauseating bug so that it would crash whenever a connection +got lost -* Fixed bugs. +version 0.2.11 Jan 22 1999 + * framework for multiple connections has been done + * simple manpage for tincd -# Version 0.2.14 Feb 10 1999 +version 0.2.10 Jan 18 1999 + * passphrase support added -* Added --timeout flag and PingTimeout configuration. -* Did some first syslog cleanup work. +version 0.2.9 Jan 13 1999 + * bugs fixed. -# Version 0.2.13 Jan 23 1999 +version 0.2.8 Jan 11 1999 + * a reworked protocol version + * a ping/pong system + * more reliable networking code + * automatic reconnection + * still does not work with more than one connection :) + * strips MAC addresses before sending, so there's less overhead, and +less redundancy -* Bugfixes. +version 0.2.7 Jan 3 1999 + * several updates to make extending more easy. -# Version 0.2.12 Jan 23 1999 +version 0.2.6 Dec 20 1998 + * Point-to-Point connections have been established, including +blowfish encryption and a secret key-exchange. -* Fixed nauseating bug so that it would crash whenever a connection - got lost. +version 0.2.5 Dec 16 1998 + * Project renamed to tinc, in honour of TINC. -# Version 0.2.11 Jan 22 1999 +version 0.2.4 Dec 16 1998 + * now it really does ;) -* Framework for multiple connections has been done. -* Simple manpage for tincd. +version 0.2.3 Nov 24 1998 + * it sort of works now -# Version 0.2.10 Jan 18 1999 +version 0.2.2 Nov 20 1998 + * uses GNU gmp. -* Passphrase support added. +version 0.2.1 Nov 14 1998 -# Version 0.2.9 Jan 13 1999 - -* Bugs fixed. - -# Version 0.2.8 Jan 11 1999 - -* A reworked protocol version. -* A ping/pong system. -* More reliable networking code. -* Automatic reconnection. -* Still does not work with more than one connection :) -* Strips MAC addresses before sending, so there's less overhead, and - less redundancy. - -# Version 0.2.7 Jan 3 1999 - -* Several updates to make extending more easy. - -# Version 0.2.6 Dec 20 1998 - -* Point-to-Point connections have been established, including - Blowfish encryption and a secret key-exchange. - -# Version 0.2.5 Dec 16 1998 - -* Project renamed to tinc, in honour of TINC. - -# Version 0.2.4 Dec 16 1998 - -* Now it really does ;) - -# Version 0.2.3 Nov 24 1998 - -* It sort of works now. - -# Version 0.2.2 Nov 20 1998 - -* Uses GNU gmp. - -# Version 0.2.1 Nov 14 1998 - -* Bare version. + * Bare version. diff --git a/README b/README index 873e2dd..127cde2 100644 --- a/README +++ b/README @@ -1,7 +1,11 @@ -This is the README file for tinc version 1.1pre17. Installation +This is the README file for tinc version 1.0.36. Installation instructions may be found in the INSTALL file. -tinc is Copyright © 1998-2018 Ivo Timmermans, Guus Sliepen , and others. +tinc is Copyright (C) 1998-2019 by: + +Ivo Timmermans, +Guus Sliepen , +and others. For a complete list of authors see the AUTHORS file. @@ -11,94 +15,119 @@ the Free Software Foundation; either version 2 of the License, or (at your option) any later version. See the file COPYING for more details. -This is a pre-release ---------------------- - -Please note that this is NOT a stable release. Until version 1.1.0 is released, -please use one of the 1.0.x versions if you need a stable version of tinc. - -Although tinc 1.1 will be protocol compatible with tinc 1.0.x, the -functionality of the tinc program may still change, and the control socket -protocol is not fixed yet. - - Security statement ------------------ -This version uses an experimental and unfinished cryptographic protocol. Use it -at your own risk. +In August 2000, we discovered the existence of a security hole in all versions +of tinc up to and including 1.0pre2. This had to do with the way we exchanged +keys. Since then, we have been working on a new authentication scheme to make +tinc as secure as possible. The current version uses the OpenSSL library and +uses strong authentication with RSA keys. -When connecting to nodes that use the legacy protocol used in tinc 1.0, be -aware that any security issues in tinc 1.0 will apply to tinc 1.1 as well. On -September 6th, 2018, Michael Yonly contacted us and provided proof-of-concept -code that allowed a remote attacker to create an authenticated, one-way -connection with a node using the legacy protocol, and also that there was a +On the 29th of December 2001, Jerome Etienne posted a security analysis of tinc +1.0pre4. Due to a lack of sequence numbers and a message authentication code +for each packet, an attacker could possibly disrupt certain network services or +launch a denial of service attack by replaying intercepted packets. The current +version adds sequence numbers and message authentication codes to prevent such +attacks. + +On September the 15th of 2003, Peter Gutmann contacted us and showed us a +writeup describing various security issues in several VPN daemons. He showed +that tinc lacks perfect forward security, the connection authentication could +be done more properly, that the sequence number we use as an IV is not the best +practice and that the default length of the HMAC for packets is too short in +his opinion. We do not know of a way to exploit these weaknesses, but these +issues are being addressed in the tinc 1.1 branch. + +The Sweet32 attack affects versions of tinc prior to 1.0.30. + +On September 6th, 2018, Michael Yonly contacted us and provided +proof-of-concept code that allowed a remote attacker to create an +authenticated, one-way connection with a node, and also that there was a possibility for a man-in-the-middle to force UDP packets from a node to be sent in plaintext. The first issue was trivial to exploit on tinc versions prior to 1.0.30, but the changes in 1.0.30 to mitigate the Sweet32 attack made this -weakness much harder to exploit. These issues have been fixed in tinc 1.0.35 -and tinc 1.1pre17. The new protocol in the tinc 1.1 branch is not susceptible -to these issues. However, be aware that SPTPS is only used between nodes -running tinc 1.1pre* or later, and in a VPN with nodes running different -versions, the security might only be as good as that of the oldest version. +weakness much harder to exploit. These issues have been fixed in tinc 1.0.35. +The new protocol in the tinc 1.1 branch is not susceptible to these issues. + +Cryptography is a hard thing to get right. We cannot make any +guarantees. Time, review and feedback are the only things that can +prove the security of any cryptographic product. If you wish to review +tinc or give us feedback, you are strongly encouraged to do so. Compatibility ------------- -Version 1.1pre17 is compatible with 1.0pre8, 1.0 and later, but not with older -versions of tinc. - -When the ExperimentalProtocol option is used, tinc is still compatible with -1.0.X, 1.1pre11 and later, but not with any version between 1.1pre1 and -1.1pre10. +Version 1.0.35 is compatible with 1.0pre8, 1.0 and later, but not with older +versions of tinc. Note that since version 1.0.30, tinc requires all nodes in +the VPN to be compiled with a version of LibreSSL or OpenSSL that supports the +AES256 and SHA256 algorithms. Requirements ------------ -In order to compile tinc, you will need a GNU C compiler environment. Please -ensure you have the latest stable versions of all the required libraries: +The OpenSSL library is used for all cryptographic functions. You can find it at +https://www.openssl.org/. You will need version 1.0.1 or later with support for +AES256 and SHA256 enabled. If this library is not installed on your system, the +configure script will fail. The manual in doc/tinc.texi contains more detailed +information on how to install this library. Alternatively, you may also use the +LibreSSL library. -- LibreSSL (http://www.libressl.org/) or OpenSSL (https://openssl.org/) version 1.0.0 or later. +The zlib library is used for optional compression. You can +find it at https://zlib.net/. Because of a possible exploit in +earlier versions we recommend that you download version 1.1.4 or later. -The following libraries are used by default, but can be disabled if necessary: +The LZO library is also used for optional compression. You can +find it at https://www.oberhumer.com/opensource/lzo/. -- zlib (https://zlib.net/) -- LZO (https://www.oberhumer.com/opensource/lzo/) -- ncurses (https://invisible-island.net/ncurses/) -- readline (https://cnswww.cns.cwru.edu/php/chet/readline/rltop.html) +In order to compile tinc, you will need a C99 compliant compiler. Features -------- -Tinc is a peer-to-peer VPN daemon that supports VPNs with an arbitrary number -of nodes. Instead of configuring tunnels, you give tinc the location and -public key of a few nodes in the VPN. After making the initial connections to -those nodes, tinc will learn about all other nodes on the VPN, and will make -connections automatically. When direct connections are not possible, data will -be forwarded by intermediate nodes. +This version of tinc supports multiple virtual networks at once. To +use this feature, you may supply a netname via the -n or --net +options. The standard locations for the config files will then be +/etc/tinc//. -Tinc 1.1 support two protocols. The first is a legacy protocol that provides -backwards compatibility with tinc 1.0 nodes, and which by default uses 2048 bit -RSA keys for authentication, and encrypts traffic using AES256 in CBC mode -and HMAC-SHA256. The second is a new protocol which uses Curve25519 keys for -authentication, and encrypts traffic using Chacha20-Poly1305, and provides -forward secrecy. +tincd regenerates its encryption key pairs. It does this on the first +activity after the keys have expired. This period is adjustable in the +configuration file, and the default time is 3600 seconds (one hour). -Tinc fully supports IPv6. +This version supports multiple subnets at once. They are also sorted +on subnet mask size. This means that it is possible to have +overlapping subnets on the VPN, as long as their subnet mask sizes +differ. -Tinc can operate in several routing modes. In the default mode, "router", every -node is associated with one or more IPv4 and/or IPv6 Subnets. The other two -modes, "switch" and "hub", let the tinc daemons work together to form a virtual -Ethernet network switch or hub. +Since pre5, tinc can operate in several routing modes. The default mode, +"router", works exactly like the older version, and uses Subnet lines to +determine the destination of packets. The other two modes, "switch" and "hub", +allow the tinc daemons to work together like a single network switch or hub. +This is useful for bridging networks. The latter modes only work properly on +Linux, FreeBSD and Windows. + +The algorithms used for encryption and generating message authentication codes +can now be changed in the configuration files. All cipher and digest algorithms +supported by OpenSSL can be used. Useful ciphers are "blowfish" (default), +"bf-ofb", "des", "des3", et cetera. Useful digests are "sha1" (default), "md5", +et cetera. + +Support for routing IPv6 packets has been added. Just add Subnet lines with +IPv6 addresses (without using :: abbreviations) and use ifconfig or ip (from +the iproute package) to give the virtual network interface corresponding IPv6 +addresses. tinc does not provide autoconfiguration for IPv6 hosts. Consider +using radvd or zebra if you need it. + +It is also possible to make tunnels to other tinc daemons over IPv6 networks, +if the operating system supports IPv6. tinc will automatically use both IPv6 +and IPv4 when available, but this can be changed by adding the option +"AddressFamily = ipv4" or "AddressFamily = ipv6" to the tinc.conf file. Normally, when started tinc will detach and run in the background. In a native Windows environment this means tinc will install itself as a service, which will -restart after reboots. To prevent tinc from detaching or running as a service, +restart after reboots. To prevent tinc from detaching or running as a service, use the -D option. -The status of the VPN can be queried using the "tinc" command, which connects -to a running tinc daemon via a control connection. The same tool also makes it -easy to start and stop tinc, and to change its configuration. diff --git a/README.android b/README.android index 7d8e853..7925bdb 100644 --- a/README.android +++ b/README.android @@ -1,23 +1,25 @@ -Quick how-to cross compile tinc for Android (done from $HOME/android/): +Quick how-to cross compile tinc for android (done from $HOME/android/): -- Download Android NDK and setup local ARM toolchain: +- Download android NDK and setup local ARM toolchain: +wget http://dl.google.com/android/ndk/android-ndk-r9d-linux-x86.tar.bz2 +tar xfj android-ndk-r9d-linux-x86.tar.bz2 +./android-ndk-r9d/build/tools/make-standalone-toolchain.sh --platform=android-5 --install-dir=/tmp/my-android-toolchain - wget http://dl.google.com/android/ndk/android-ndk-r8b-linux-x86.tar.bz2 - tar xfj android-ndk-r8b-linux-x86.tar.bz2 - ./android-ndk-r8b/build/tools/make-standalone-toolchain.sh --platform=android-5 --install-dir=/tmp/my-android-toolchain - -- Download and cross-compile OpenSSL for ARM: - - wget http://www.openssl.org/source/openssl-1.0.1c.tar.gz - tar xfz openssl-1.0.1c.tar.gz - cd openssl-1.0.1c - ./Configure dist - make CC=/tmp/my-android-toolchain/bin/arm-linux-androideabi-gcc AR="/tmp/my-android-toolchain/bin/arm-linux-androideabi-ar r" RANLIB=/tmp/my-android-toolchain/bin/arm-linux-androideabi-ranlib +- Download and cross-compile openSSL for ARM: +wget http://www.openssl.org/source/openssl-1.0.1h.tar.gz +tar xfz openssl-1.0.1h.tar.gz +cd openssl-1.0.1h +./Configure dist +make CC=/tmp/my-android-toolchain/bin/arm-linux-androideabi-gcc AR="/tmp/my-android-toolchain/bin/arm-linux-androideabi-ar r" RANLIB=/tmp/my-android-toolchain/bin/arm-linux-androideabi-ranlib +cd - - Clone and cross-compile tinc: +git clone git://tinc-vpn.org/tinc +cd tinc +autoreconf -fsi +CC=/tmp/my-android-toolchain/bin/arm-linux-androideabi-gcc ./configure --host=arm-linux --disable-lzo --with-openssl-lib=$HOME/android/openssl-1.0.1g --with-openssl-include=$HOME/android/openssl-1.0.1g/include/ --disable-hardening +make -j5 + +- Strip tincd binary to make it smaller +/tmp/my-android-toolchain/bin/arm-linux-androideabi-strip src/tincd - git clone git://tinc-vpn.org/tinc - cd tinc - autoreconf -fsi - CC=/tmp/my-android-toolchain/bin/arm-linux-androideabi-gcc ./configure --host=arm-linux --disable-lzo --with-openssl-lib=$HOME/android/openssl-1.0.1c --with-openssl-include=$HOME/android/openssl-1.0.1c/include/ - make -j5 diff --git a/THANKS b/THANKS index e814641..a0f7966 100644 --- a/THANKS +++ b/THANKS @@ -22,6 +22,7 @@ We would like to thank the following people for their contributions to tinc: * Delf Eldkraft * Dennis Joachimsthaler * dnk +* Егор Палкин * Élie Bouttier * Enrique Zanardi * Erik Tews @@ -37,11 +38,12 @@ We would like to thank the following people for their contributions to tinc: * Gusariev Oleksandr * Hans Bayle * Harvest -* Ivo Smits * Ivo van Dong +* Ivo Smits * James Cook * James MacLean * Jamie Briggs +* Jan Štembera * Jason Harper * Jason Livesay * Jasper Krijgsman @@ -49,8 +51,8 @@ We would like to thank the following people for their contributions to tinc: * Jeroen Domburg * Jeroen Ubbink * Jerome Etienne -* Jochen Voss * Jo-Philipp Wich +* Jochen Voss * Julien Muchembled * Lavrans Laading * Loïc Dachary @@ -71,21 +73,24 @@ We would like to thank the following people for their contributions to tinc: * Max Rijevski * Menno Smits * Mesar Hameed +* Michael Taylor * Michael Tokarev * Michael Yonli * Miles Nordin -* Murat Donmez * Nathan Stratton Treadway +* Murat Donmez * Nick Hibma * Nick Patavalis * Paul Littlefield * Philipp Babel * Pierre Emeriaud * Pierre-Olivier Mercier +* Rafael Wolf * Rafael Sadowski * Rafał Leśniak * Rhosyn Celyn * Robert van der Meulen +* Robert Waniek * Rumko * Ryan Miller * Sam Bryan @@ -104,6 +109,7 @@ We would like to thank the following people for their contributions to tinc: * Tonnerre Lombard * Ulrich Seifert * Vil Brekin +* Vincent Laurent * Vittorio Gambaletta * Wendy Willard * Wessel Dankers diff --git a/aclocal.m4 b/aclocal.m4 index 4ba9316..06685b5 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -1138,12 +1138,7 @@ m4_include([m4/ax_append_flag.m4]) m4_include([m4/ax_cflags_warn_all.m4]) m4_include([m4/ax_check_compile_flag.m4]) m4_include([m4/ax_check_link_flag.m4]) -m4_include([m4/ax_code_coverage.m4]) m4_include([m4/ax_require_defined.m4]) -m4_include([m4/curses.m4]) -m4_include([m4/libgcrypt.m4]) m4_include([m4/lzo.m4]) -m4_include([m4/miniupnpc.m4]) m4_include([m4/openssl.m4]) -m4_include([m4/readline.m4]) m4_include([m4/zlib.m4]) diff --git a/config.h.in b/config.h.in index 9c494c8..cc68348 100644 --- a/config.h.in +++ b/config.h.in @@ -1,8 +1,5 @@ /* config.h.in. Generated from configure.ac by autoheader. */ -/* Disable support for the legacy (tinc 1.0) protocol */ -#undef DISABLE_LEGACY - /* Support for jumbograms (packets up to 9000 bytes) */ #undef ENABLE_JUMBOGRAMS @@ -18,6 +15,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_ARPA_INET_H +/* Define to 1 if you have the header file. */ +#undef HAVE_ARPA_NAMESER_H + /* Define to 1 if you have the `asprintf' function. */ #undef HAVE_ASPRINTF @@ -27,12 +27,6 @@ /* Unknown BSD variant */ #undef HAVE_BSD -/* have curses support */ -#undef HAVE_CURSES - -/* Define to 1 if you have the header file. */ -#undef HAVE_CURSES_H - /* Cygwin */ #undef HAVE_CYGWIN @@ -46,6 +40,22 @@ you don't. */ #undef HAVE_DECL_EVP_AES_256_CFB +/* Define to 1 if you have the declaration of `freeaddrinfo', and to 0 if you + don't. */ +#undef HAVE_DECL_FREEADDRINFO + +/* Define to 1 if you have the declaration of `gai_strerror', and to 0 if you + don't. */ +#undef HAVE_DECL_GAI_STRERROR + +/* Define to 1 if you have the declaration of `getaddrinfo', and to 0 if you + don't. */ +#undef HAVE_DECL_GETADDRINFO + +/* Define to 1 if you have the declaration of `getnameinfo', and to 0 if you + don't. */ +#undef HAVE_DECL_GETNAMEINFO + /* Define to 1 if you have the declaration of `OpenSSL_add_all_algorithms', and to 0 if you don't. */ #undef HAVE_DECL_OPENSSL_ADD_ALL_ALGORITHMS @@ -63,9 +73,6 @@ /* DragonFly */ #undef HAVE_DRAGONFLY -/* Define to 1 if you have the `ERR_remove_state' function. */ -#undef HAVE_ERR_REMOVE_STATE - /* Define to 1 if you have the `EVP_CIPHER_CTX_new' function. */ #undef HAVE_EVP_CIPHER_CTX_NEW @@ -87,9 +94,6 @@ /* FreeBSD */ #undef HAVE_FREEBSD -/* Define to 1 if you have the header file. */ -#undef HAVE_GCRYPT_H - /* Define to 1 if you have the header file. */ #undef HAVE_GETOPT_H @@ -99,12 +103,12 @@ /* Define to 1 if you have the `gettimeofday' function. */ #undef HAVE_GETTIMEOFDAY -/* Define to 1 if you have the `HMAC_CTX_new' function. */ -#undef HAVE_HMAC_CTX_NEW - /* Define to 1 if you have the header file. */ #undef HAVE_INTTYPES_H +/* Define to 1 if you have the `nsl' library (-lnsl). */ +#undef HAVE_LIBNSL + /* Define to 1 if you have the `resolv' library (-lresolv). */ #undef HAVE_LIBRESOLV @@ -138,18 +142,9 @@ /* MinGW */ #undef HAVE_MINGW -/* have miniupnpc support */ -#undef HAVE_MINIUPNPC - -/* Define to 1 if you have the header file. */ -#undef HAVE_MINIUPNPC_MINIUPNPC_H - /* Define to 1 if you have the `mlockall' function. */ #undef HAVE_MLOCKALL -/* Define to 1 if you have the `nanosleep' function. */ -#undef HAVE_NANOSLEEP - /* NetBSD */ #undef HAVE_NETBSD @@ -237,30 +232,24 @@ /* Define to 1 if you have the header file. */ #undef HAVE_OPENSSL_SHA_H +/* Define to 1 if you have the `pselect' function. */ +#undef HAVE_PSELECT + /* Define to 1 if you have the `putenv' function. */ #undef HAVE_PUTENV /* Define to 1 if you have the `RAND_bytes' function. */ #undef HAVE_RAND_BYTES -/* have readline support */ -#undef HAVE_READLINE - -/* Define to 1 if you have the header file. */ -#undef HAVE_READLINE_HISTORY_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_READLINE_READLINE_H - -/* Define to 1 if you have the `recvmmsg' function. */ -#undef HAVE_RECVMMSG - /* Define to 1 if you have the header file. */ #undef HAVE_RESOLV_H /* Define to 1 if you have the `RSA_set0_key' function. */ #undef HAVE_RSA_SET0_KEY +/* Define to 1 if the system has the type `socklen_t'. */ +#undef HAVE_SOCKLEN_T + /* Solaris/SunOS */ #undef HAVE_SOLARIS @@ -279,6 +268,9 @@ /* Define to 1 if you have the `strsignal' function. */ #undef HAVE_STRSIGNAL +/* Define to 1 if the system has the type `struct addrinfo'. */ +#undef HAVE_STRUCT_ADDRINFO + /* Define to 1 if the system has the type `struct arphdr'. */ #undef HAVE_STRUCT_ARPHDR @@ -294,6 +286,12 @@ /* Define to 1 if the system has the type `struct icmp6_hdr'. */ #undef HAVE_STRUCT_ICMP6_HDR +/* Define to 1 if the system has the type `struct in6_addr'. */ +#undef HAVE_STRUCT_IN6_ADDR + +/* Define to 1 if the system has the type `struct in_addr'. */ +#undef HAVE_STRUCT_IN_ADDR + /* Define to 1 if the system has the type `struct ip'. */ #undef HAVE_STRUCT_IP @@ -306,9 +304,15 @@ /* Define to 1 if the system has the type `struct nd_opt_hdr'. */ #undef HAVE_STRUCT_ND_OPT_HDR +/* Define to 1 if the system has the type `struct sockaddr_in6'. */ +#undef HAVE_STRUCT_SOCKADDR_IN6 + /* Define to 1 if you have the header file. */ #undef HAVE_SYSLOG_H +/* Define to 1 if you have the `system' function. */ +#undef HAVE_SYSTEM + /* Define to 1 if you have the header file. */ #undef HAVE_SYS_FILE_H @@ -336,8 +340,8 @@ /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TYPES_H -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_UN_H +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_UIO_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_WAIT_H @@ -348,6 +352,9 @@ /* Define to 1 if you have the `unsetenv' function. */ #undef HAVE_UNSETENV +/* Define to 1 if you have the `usleep' function. */ +#undef HAVE_USLEEP + /* Define to 1 if you have the `vsyslog' function. */ #undef HAVE_VSYSLOG @@ -412,6 +419,9 @@ /* Version number of package */ #undef VERSION +/* Compile with support for Windows 2000 */ +#undef WITH_WINDOWS2000 + /* Define to 1 if on MINIX. */ #undef _MINIX @@ -428,8 +438,5 @@ /* Defined if the __malloc__ attribute is not supported. */ #undef __malloc__ -/* Defined if the __nonnull__ attribute is not supported. */ -#undef __nonnull__ - -/* Defined if the __warn_unused_result__ attribute is not supported. */ -#undef __warn_unused_result__ +/* Define to `int' if does not define. */ +#undef pid_t diff --git a/configure b/configure index ebad571..7828190 100755 --- a/configure +++ b/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for tinc 1.1pre17. +# Generated by GNU Autoconf 2.69 for tinc 1.0.36. # # # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. @@ -577,8 +577,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='tinc' PACKAGE_TARNAME='tinc' -PACKAGE_VERSION='1.1pre17' -PACKAGE_STRING='tinc 1.1pre17' +PACKAGE_VERSION='1.0.36' +PACKAGE_STRING='tinc 1.0.36' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -623,15 +623,6 @@ ac_subst_vars='am__EXEEXT_FALSE am__EXEEXT_TRUE LTLIBOBJS LIBOBJS -MINIUPNPC_FALSE -MINIUPNPC_TRUE -MINIUPNPC_LIBS -GCRYPT_FALSE -GCRYPT_TRUE -OPENSSL_FALSE -OPENSSL_TRUE -READLINE_LIBS -CURSES_LIBS GETOPT_FALSE GETOPT_TRUE WITH_SYSTEMD_FALSE @@ -661,19 +652,6 @@ build_os build_vendor build_cpu build -CODE_COVERAGE_RULES -CODE_COVERAGE_LDFLAGS -CODE_COVERAGE_LIBS -CODE_COVERAGE_CXXFLAGS -CODE_COVERAGE_CFLAGS -CODE_COVERAGE_CPPFLAGS -GENHTML -LCOV -GCOV -CODE_COVERAGE_ENABLED -CODE_COVERAGE_ENABLED_FALSE -CODE_COVERAGE_ENABLED_TRUE -SED EGREP GREP CPP @@ -765,22 +743,12 @@ ac_user_opts=' enable_option_checking enable_silent_rules enable_dependency_tracking -with_gcov -enable_code_coverage enable_uml enable_vde enable_tunemu +with_windows2000 with_systemd enable_hardening -enable_legacy_protocol -enable_curses -with_curses -with_curses_include -with_curses_lib -enable_readline -with_readline -with_readline_include -with_readline_lib enable_zlib with_zlib with_zlib_include @@ -789,16 +757,9 @@ enable_lzo with_lzo with_lzo_include with_lzo_lib -with_libgcrypt -with_libgcrypt_include -with_libgcrypt_lib with_openssl with_openssl_include with_openssl_lib -enable_miniupnpc -with_miniupnpc -with_miniupnpc_include -with_miniupnpc_lib enable_jumbograms ' ac_precious_vars='build_alias @@ -1360,7 +1321,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures tinc 1.1pre17 to adapt to many kinds of systems. +\`configure' configures tinc 1.0.36 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1431,7 +1392,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of tinc 1.1pre17:";; + short | recursive ) echo "Configuration of tinc 1.0.36:";; esac cat <<\_ACEOF @@ -1445,56 +1406,32 @@ Optional Features: do not reject slow dependency extractors --disable-dependency-tracking speeds up one-time build - --enable-code-coverage Whether to enable code coverage support --enable-uml enable support for User Mode Linux --enable-vde enable support for Virtual Distributed Ethernet --enable-tunemu enable support for the tunemu driver --disable-hardening disable compiler and linker hardening flags - --disable-legacy-protocol - disable support for the legacy (tinc 1.0) protocol - --disable-curses disable curses support - --disable-readline disable readline support --disable-zlib disable zlib compression support --disable-lzo disable lzo compression support - --enable-miniupnpc enable miniupnpc support --enable-jumbograms enable support for jumbograms (packets up to 9000 bytes) Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) - --with-gcov=GCOV use given GCOV for coverage (GCOV=gcov). + --with-windows2000 compile with support for Windows 2000. This disables + support for tunneling over existing IPv6 networks. --with-systemd[=DIR] install systemd service files [to DIR if specified] - --with-curses=DIR curses base directory, or: - --with-curses-include=DIR - curses headers directory - --with-curses-lib=DIR curses library directory - --with-readline=DIR readline base directory, or: - --with-readline-include=DIR - readline headers directory - --with-readline-lib=DIR readline library directory --with-zlib=DIR zlib base directory, or: --with-zlib-include=DIR zlib headers directory --with-zlib-lib=DIR zlib library directory --with-lzo=DIR lzo base directory, or: --with-lzo-include=DIR lzo headers directory --with-lzo-lib=DIR lzo library directory - --with-libgcrypt=DIR libgcrypt base directory, or: - --with-libgcrypt-include=DIR - libgcrypt headers directory (without trailing - /libgcrypt) - --with-libgcrypt-lib=DIR - libgcrypt library directory --with-openssl=DIR LibreSSL/OpenSSL base directory, or: --with-openssl-include=DIR LibreSSL/OpenSSL headers directory (without trailing /openssl) --with-openssl-lib=DIR LibreSSL/OpenSSL library directory - --with-miniupnpc=DIR miniupnpc base directory, or: - --with-miniupnpc-include=DIR - miniupnpc headers directory - --with-miniupnpc-lib=DIR - miniupnpc library directory Some influential environment variables: CC C compiler command @@ -1572,7 +1509,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -tinc configure 1.1pre17 +tinc configure 1.0.36 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -2037,7 +1974,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by tinc $as_me 1.1pre17, which was +It was created by tinc $as_me 1.0.36, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -2901,7 +2838,7 @@ fi # Define the identity of the package. PACKAGE='tinc' - VERSION='1.1pre17' + VERSION='1.0.36' cat >>confdefs.h <<_ACEOF @@ -4860,448 +4797,6 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 -$as_echo_n "checking for a sed that does not truncate output... " >&6; } -if ${ac_cv_path_SED+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ - for ac_i in 1 2 3 4 5 6 7; do - ac_script="$ac_script$as_nl$ac_script" - done - echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed - { ac_script=; unset ac_script;} - if test -z "$SED"; then - ac_path_SED_found=false - # Loop through the user's path and test for each of PROGNAME-LIST - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_prog in sed gsed; do - for ac_exec_ext in '' $ac_executable_extensions; do - ac_path_SED="$as_dir/$ac_prog$ac_exec_ext" - as_fn_executable_p "$ac_path_SED" || continue -# Check for GNU ac_path_SED and select it if it is found. - # Check for GNU $ac_path_SED -case `"$ac_path_SED" --version 2>&1` in -*GNU*) - ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;; -*) - ac_count=0 - $as_echo_n 0123456789 >"conftest.in" - while : - do - cat "conftest.in" "conftest.in" >"conftest.tmp" - mv "conftest.tmp" "conftest.in" - cp "conftest.in" "conftest.nl" - $as_echo '' >> "conftest.nl" - "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break - diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break - as_fn_arith $ac_count + 1 && ac_count=$as_val - if test $ac_count -gt ${ac_path_SED_max-0}; then - # Best one so far, save it but keep looking for a better one - ac_cv_path_SED="$ac_path_SED" - ac_path_SED_max=$ac_count - fi - # 10*(2^10) chars as input seems more than enough - test $ac_count -gt 10 && break - done - rm -f conftest.in conftest.tmp conftest.nl conftest.out;; -esac - - $ac_path_SED_found && break 3 - done - done - done -IFS=$as_save_IFS - if test -z "$ac_cv_path_SED"; then - as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5 - fi -else - ac_cv_path_SED=$SED -fi - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 -$as_echo "$ac_cv_path_SED" >&6; } - SED="$ac_cv_path_SED" - rm -f conftest.sed - - - - - # allow to override gcov location - -# Check whether --with-gcov was given. -if test "${with_gcov+set}" = set; then : - withval=$with_gcov; _AX_CODE_COVERAGE_GCOV_PROG_WITH=$with_gcov -else - _AX_CODE_COVERAGE_GCOV_PROG_WITH=gcov -fi - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build with code coverage support" >&5 -$as_echo_n "checking whether to build with code coverage support... " >&6; } - # Check whether --enable-code-coverage was given. -if test "${enable_code_coverage+set}" = set; then : - enableval=$enable_code_coverage; -else - enable_code_coverage=no -fi - - - if test x$enable_code_coverage = xyes; then - CODE_COVERAGE_ENABLED_TRUE= - CODE_COVERAGE_ENABLED_FALSE='#' -else - CODE_COVERAGE_ENABLED_TRUE='#' - CODE_COVERAGE_ENABLED_FALSE= -fi - - CODE_COVERAGE_ENABLED=$enable_code_coverage - - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_code_coverage" >&5 -$as_echo "$enable_code_coverage" >&6; } - - if test "$enable_code_coverage" = "yes" ; then : - - # check for gcov - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}$_AX_CODE_COVERAGE_GCOV_PROG_WITH", so it can be a program name with args. -set dummy ${ac_tool_prefix}$_AX_CODE_COVERAGE_GCOV_PROG_WITH; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_GCOV+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$GCOV"; then - ac_cv_prog_GCOV="$GCOV" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_GCOV="${ac_tool_prefix}$_AX_CODE_COVERAGE_GCOV_PROG_WITH" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -GCOV=$ac_cv_prog_GCOV -if test -n "$GCOV"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GCOV" >&5 -$as_echo "$GCOV" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_GCOV"; then - ac_ct_GCOV=$GCOV - # Extract the first word of "$_AX_CODE_COVERAGE_GCOV_PROG_WITH", so it can be a program name with args. -set dummy $_AX_CODE_COVERAGE_GCOV_PROG_WITH; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_GCOV+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_GCOV"; then - ac_cv_prog_ac_ct_GCOV="$ac_ct_GCOV" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_GCOV="$_AX_CODE_COVERAGE_GCOV_PROG_WITH" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_GCOV=$ac_cv_prog_ac_ct_GCOV -if test -n "$ac_ct_GCOV"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_GCOV" >&5 -$as_echo "$ac_ct_GCOV" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_GCOV" = x; then - GCOV=":" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - GCOV=$ac_ct_GCOV - fi -else - GCOV="$ac_cv_prog_GCOV" -fi - - if test "X$GCOV" = "X:"; then : - as_fn_error $? "gcov is needed to do coverage" "$LINENO" 5 -fi - - - if test "$GCC" = "no" ; then : - - as_fn_error $? "not compiling with gcc, which is required for gcov code coverage" "$LINENO" 5 - -fi - - # Extract the first word of "lcov", so it can be a program name with args. -set dummy lcov; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_LCOV+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$LCOV"; then - ac_cv_prog_LCOV="$LCOV" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_LCOV="lcov" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -LCOV=$ac_cv_prog_LCOV -if test -n "$LCOV"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LCOV" >&5 -$as_echo "$LCOV" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - # Extract the first word of "genhtml", so it can be a program name with args. -set dummy genhtml; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_GENHTML+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$GENHTML"; then - ac_cv_prog_GENHTML="$GENHTML" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_GENHTML="genhtml" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -GENHTML=$ac_cv_prog_GENHTML -if test -n "$GENHTML"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GENHTML" >&5 -$as_echo "$GENHTML" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - - if test -z "$LCOV" ; then : - - as_fn_error $? "To enable code coverage reporting you must have lcov installed" "$LINENO" 5 - -fi - - if test -z "$GENHTML" ; then : - - as_fn_error $? "Could not find genhtml from the lcov package" "$LINENO" 5 - -fi - - CODE_COVERAGE_CPPFLAGS="-DNDEBUG" - CODE_COVERAGE_CFLAGS="-O0 -g -fprofile-arcs -ftest-coverage" - CODE_COVERAGE_CXXFLAGS="-O0 -g -fprofile-arcs -ftest-coverage" - CODE_COVERAGE_LIBS="-lgcov" - CODE_COVERAGE_LDFLAGS="$CODE_COVERAGE_LIBS" - - - - - - - - CODE_COVERAGE_RULES_CHECK=' - -$(A''M_V_at)$(MAKE) $(AM_MAKEFLAGS) -k check - $(A''M_V_at)$(MAKE) $(AM_MAKEFLAGS) code-coverage-capture -' - CODE_COVERAGE_RULES_CAPTURE=' - $(code_coverage_v_lcov_cap)$(LCOV) $(code_coverage_quiet) $(addprefix --directory ,$(CODE_COVERAGE_DIRECTORY)) --capture --output-file "$(CODE_COVERAGE_OUTPUT_FILE).tmp" --test-name "$(call code_coverage_sanitize,$(PACKAGE_NAME)-$(PACKAGE_VERSION))" --no-checksum --compat-libtool $(CODE_COVERAGE_LCOV_SHOPTS) $(CODE_COVERAGE_LCOV_OPTIONS) - $(code_coverage_v_lcov_ign)$(LCOV) $(code_coverage_quiet) $(addprefix --directory ,$(CODE_COVERAGE_DIRECTORY)) --remove "$(CODE_COVERAGE_OUTPUT_FILE).tmp" "/tmp/*" $(CODE_COVERAGE_IGNORE_PATTERN) --output-file "$(CODE_COVERAGE_OUTPUT_FILE)" $(CODE_COVERAGE_LCOV_SHOPTS) $(CODE_COVERAGE_LCOV_RMOPTS) - -@rm -f $(CODE_COVERAGE_OUTPUT_FILE).tmp - $(code_coverage_v_genhtml)LANG=C $(GENHTML) $(code_coverage_quiet) $(addprefix --prefix ,$(CODE_COVERAGE_DIRECTORY)) --output-directory "$(CODE_COVERAGE_OUTPUT_DIRECTORY)" --title "$(PACKAGE_NAME)-$(PACKAGE_VERSION) Code Coverage" --legend --show-details "$(CODE_COVERAGE_OUTPUT_FILE)" $(CODE_COVERAGE_GENHTML_OPTIONS) - @echo "file://$(abs_builddir)/$(CODE_COVERAGE_OUTPUT_DIRECTORY)/index.html" -' - CODE_COVERAGE_RULES_CLEAN=' -clean: code-coverage-clean -distclean: code-coverage-clean -code-coverage-clean: - -$(LCOV) --directory $(top_builddir) -z - -rm -rf $(CODE_COVERAGE_OUTPUT_FILE) $(CODE_COVERAGE_OUTPUT_FILE).tmp $(CODE_COVERAGE_OUTPUT_DIRECTORY) - -find . \( -name "*.gcda" -o -name "*.gcno" -o -name "*.gcov" \) -delete -' - -else - - CODE_COVERAGE_RULES_CHECK=' - @echo "Need to reconfigure with --enable-code-coverage" -' - CODE_COVERAGE_RULES_CAPTURE="$CODE_COVERAGE_RULES_CHECK" - CODE_COVERAGE_RULES_CLEAN='' - -fi - -CODE_COVERAGE_RULES=' -# Code coverage -# -# Optional: -# - CODE_COVERAGE_DIRECTORY: Top-level directory for code coverage reporting. -# Multiple directories may be specified, separated by whitespace. -# (Default: $(top_builddir)) -# - CODE_COVERAGE_OUTPUT_FILE: Filename and path for the .info file generated -# by lcov for code coverage. (Default: -# $(PACKAGE_NAME)-$(PACKAGE_VERSION)-coverage.info) -# - CODE_COVERAGE_OUTPUT_DIRECTORY: Directory for generated code coverage -# reports to be created. (Default: -# $(PACKAGE_NAME)-$(PACKAGE_VERSION)-coverage) -# - CODE_COVERAGE_BRANCH_COVERAGE: Set to 1 to enforce branch coverage, -# set to 0 to disable it and leave empty to stay with the default. -# (Default: empty) -# - CODE_COVERAGE_LCOV_SHOPTS_DEFAULT: Extra options shared between both lcov -# instances. (Default: based on $CODE_COVERAGE_BRANCH_COVERAGE) -# - CODE_COVERAGE_LCOV_SHOPTS: Extra options to shared between both lcov -# instances. (Default: $CODE_COVERAGE_LCOV_SHOPTS_DEFAULT) -# - CODE_COVERAGE_LCOV_OPTIONS_GCOVPATH: --gcov-tool pathtogcov -# - CODE_COVERAGE_LCOV_OPTIONS_DEFAULT: Extra options to pass to the -# collecting lcov instance. (Default: $CODE_COVERAGE_LCOV_OPTIONS_GCOVPATH) -# - CODE_COVERAGE_LCOV_OPTIONS: Extra options to pass to the collecting lcov -# instance. (Default: $CODE_COVERAGE_LCOV_OPTIONS_DEFAULT) -# - CODE_COVERAGE_LCOV_RMOPTS_DEFAULT: Extra options to pass to the filtering -# lcov instance. (Default: empty) -# - CODE_COVERAGE_LCOV_RMOPTS: Extra options to pass to the filtering lcov -# instance. (Default: $CODE_COVERAGE_LCOV_RMOPTS_DEFAULT) -# - CODE_COVERAGE_GENHTML_OPTIONS_DEFAULT: Extra options to pass to the -# genhtml instance. (Default: based on $CODE_COVERAGE_BRANCH_COVERAGE) -# - CODE_COVERAGE_GENHTML_OPTIONS: Extra options to pass to the genhtml -# instance. (Default: $CODE_COVERAGE_GENHTML_OPTIONS_DEFAULT) -# - CODE_COVERAGE_IGNORE_PATTERN: Extra glob pattern of files to ignore -# -# The generated report will be titled using the $(PACKAGE_NAME) and -# $(PACKAGE_VERSION). In order to add the current git hash to the title, -# use the git-version-gen script, available online. - -# Optional variables -CODE_COVERAGE_DIRECTORY ?= $(top_builddir) -CODE_COVERAGE_OUTPUT_FILE ?= $(PACKAGE_NAME)-$(PACKAGE_VERSION)-coverage.info -CODE_COVERAGE_OUTPUT_DIRECTORY ?= $(PACKAGE_NAME)-$(PACKAGE_VERSION)-coverage -CODE_COVERAGE_BRANCH_COVERAGE ?= -CODE_COVERAGE_LCOV_SHOPTS_DEFAULT ?= $(if $(CODE_COVERAGE_BRANCH_COVERAGE),\ ---rc lcov_branch_coverage=$(CODE_COVERAGE_BRANCH_COVERAGE)) -CODE_COVERAGE_LCOV_SHOPTS ?= $(CODE_COVERAGE_LCOV_SHOPTS_DEFAULT) -CODE_COVERAGE_LCOV_OPTIONS_GCOVPATH ?= --gcov-tool "$(GCOV)" -CODE_COVERAGE_LCOV_OPTIONS_DEFAULT ?= $(CODE_COVERAGE_LCOV_OPTIONS_GCOVPATH) -CODE_COVERAGE_LCOV_OPTIONS ?= $(CODE_COVERAGE_LCOV_OPTIONS_DEFAULT) -CODE_COVERAGE_LCOV_RMOPTS_DEFAULT ?= -CODE_COVERAGE_LCOV_RMOPTS ?= $(CODE_COVERAGE_LCOV_RMOPTS_DEFAULT) -CODE_COVERAGE_GENHTML_OPTIONS_DEFAULT ?=\ -$(if $(CODE_COVERAGE_BRANCH_COVERAGE),\ ---rc genhtml_branch_coverage=$(CODE_COVERAGE_BRANCH_COVERAGE)) -CODE_COVERAGE_GENHTML_OPTIONS ?= $(CODE_COVERAGE_GENHTML_OPTIONS_DEFAULTS) -CODE_COVERAGE_IGNORE_PATTERN ?= - -code_coverage_v_lcov_cap = $(code_coverage_v_lcov_cap_$(V)) -code_coverage_v_lcov_cap_ = $(code_coverage_v_lcov_cap_$(AM_DEFAULT_VERBOSITY)) -code_coverage_v_lcov_cap_0 = @echo " LCOV --capture"\ - $(CODE_COVERAGE_OUTPUT_FILE); -code_coverage_v_lcov_ign = $(code_coverage_v_lcov_ign_$(V)) -code_coverage_v_lcov_ign_ = $(code_coverage_v_lcov_ign_$(AM_DEFAULT_VERBOSITY)) -code_coverage_v_lcov_ign_0 = @echo " LCOV --remove /tmp/*"\ - $(CODE_COVERAGE_IGNORE_PATTERN); -code_coverage_v_genhtml = $(code_coverage_v_genhtml_$(V)) -code_coverage_v_genhtml_ = $(code_coverage_v_genhtml_$(AM_DEFAULT_VERBOSITY)) -code_coverage_v_genhtml_0 = @echo " GEN " $(CODE_COVERAGE_OUTPUT_DIRECTORY); -code_coverage_quiet = $(code_coverage_quiet_$(V)) -code_coverage_quiet_ = $(code_coverage_quiet_$(AM_DEFAULT_VERBOSITY)) -code_coverage_quiet_0 = --quiet - -# sanitizes the test-name: replaces with underscores: dashes and dots -code_coverage_sanitize = $(subst -,_,$(subst .,_,$(1))) - -# Use recursive makes in order to ignore errors during check -check-code-coverage:'"$CODE_COVERAGE_RULES_CHECK"' - -# Capture code coverage data -code-coverage-capture: code-coverage-capture-hook'"$CODE_COVERAGE_RULES_CAPTURE"' - -# Hook rule executed before code-coverage-capture, overridable by the user -code-coverage-capture-hook: - -'"$CODE_COVERAGE_RULES_CLEAN"' - -GITIGNOREFILES ?= -GITIGNOREFILES += $(CODE_COVERAGE_OUTPUT_FILE) $(CODE_COVERAGE_OUTPUT_DIRECTORY) - -A''M_DISTCHECK_CONFIGURE_FLAGS ?= -A''M_DISTCHECK_CONFIGURE_FLAGS += --disable-code-coverage - -.PHONY: check-code-coverage code-coverage-capture code-coverage-capture-hook code-coverage-clean -' - - - - -if test "x$enable_code_coverage" = "xyes" -a "x$origcflags" = "x"; then : - CFLAGS="" -fi # Make sure we can run config.sub. @@ -5438,9 +4933,7 @@ $as_echo "#define HAVE_CYGWIN 1" >>confdefs.h $as_echo "#define HAVE_MINGW 1" >>confdefs.h - LIBS="$LIBS -lws2_32 -lgdi32 -lcrypt32 -liphlpapi" - LDFLAGS="$LDFLAGS -static" - CPPFLAGS="$CPPFLAGS -DMINIUPNP_STATICLIB" + LIBS="$LIBS -lws2_32 -lgdi32 -lcrypt32" ;; *) as_fn_error $? "\"Unknown operating system.\"" "$LINENO" 5 @@ -5516,6 +5009,19 @@ fi +# Check whether --with-windows2000 was given. +if test "${with_windows2000+set}" = set; then : + withval=$with_windows2000; if test "x$with_windows2000" = "xyes"; then : + +$as_echo "#define WITH_WINDOWS2000 1" >>confdefs.h + +fi + + +fi + + + # Check whether --with-systemd was given. if test "${with_systemd+set}" = set; then : withval=$with_systemd; systemd=true; systemd_path="$with_systemd" @@ -5695,10 +5201,10 @@ $as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} fi rm -f confcache -if test -d /sw/include; then : +if test -d /sw/include ; then CPPFLAGS="$CPPFLAGS -I/sw/include" fi -if test -d /sw/lib; then : +if test -d /sw/lib ; then LIBS="$LIBS -L/sw/lib" fi @@ -5744,36 +5250,26 @@ $as_echo "$ac_cv_cflags_warn_all" >&6; } case ".$ac_cv_cflags_warn_all" in .ok|.ok,*) ;; .|.no|.no,*) ;; - *) -if ${CFLAGS+:} false; then : - - case " $CFLAGS " in #( - *" $ac_cv_cflags_warn_all "*) : - { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS already contains \$ac_cv_cflags_warn_all"; } >&5 + *) if ${CFLAGS+:} false; then : + case " $CFLAGS " in + *" $ac_cv_cflags_warn_all "*) + { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS already contains \$ac_cv_cflags_warn_all"; } >&5 (: CFLAGS already contains $ac_cv_cflags_warn_all) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } ;; #( - *) : - - as_fn_append CFLAGS " $ac_cv_cflags_warn_all" - { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS=\"\$CFLAGS\""; } >&5 - (: CFLAGS="$CFLAGS") 2>&5 + test $ac_status = 0; } + ;; + *) + { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS=\"\$CFLAGS \$ac_cv_cflags_warn_all\""; } >&5 + (: CFLAGS="$CFLAGS $ac_cv_cflags_warn_all") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } - ;; -esac - + CFLAGS="$CFLAGS $ac_cv_cflags_warn_all" + ;; + esac else - - CFLAGS=$ac_cv_cflags_warn_all - { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS=\"\$CFLAGS\""; } >&5 - (: CFLAGS="$CFLAGS") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } - + CFLAGS="$ac_cv_cflags_warn_all" fi ;; esac @@ -6122,7 +5618,8 @@ fi fi; -for ac_header in syslog.h sys/file.h sys/ioctl.h sys/mman.h sys/param.h sys/resource.h sys/socket.h sys/time.h sys/un.h sys/wait.h netdb.h arpa/inet.h dirent.h getopt.h + +for ac_header in syslog.h sys/file.h sys/ioctl.h sys/mman.h sys/param.h sys/resource.h sys/socket.h sys/time.h sys/uio.h sys/wait.h netdb.h arpa/inet.h arpa/nameser.h dirent.h getopt.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" @@ -6135,7 +5632,7 @@ fi done -for ac_header in net/if.h net/if_types.h net/ethernet.h net/if_arp.h netinet/in_systm.h netinet/in.h netinet/in6.h netpacket/packet.h +for ac_header in net/if.h net/if_types.h linux/if_tun.h net/if_tun.h net/if_utun.h net/tun/if_tun.h net/if_tap.h net/tap/if_tap.h net/ethernet.h net/if_arp.h netinet/in_systm.h netinet/in.h netinet/in6.h netpacket/packet.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "#include \"$srcdir/src/have.h\" @@ -6181,6 +5678,18 @@ fi done +ac_fn_c_check_type "$LINENO" "pid_t" "ac_cv_type_pid_t" "$ac_includes_default" +if test "x$ac_cv_type_pid_t" = xyes; then : + +else + +cat >>confdefs.h <<_ACEOF +#define pid_t int +_ACEOF + +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working __malloc__ attribute" >&5 $as_echo_n "checking for working __malloc__ attribute... " >&6; } @@ -6216,74 +5725,17 @@ $as_echo "#define __malloc__ /**/" >>confdefs.h fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working __nonnull__ attribute" >&5 -$as_echo_n "checking for working __nonnull__ attribute... " >&6; } -if ${tinc_cv_attribute___nonnull__+:} false; then : - $as_echo_n "(cached) " >&6 -else +ac_fn_c_check_type "$LINENO" "socklen_t" "ac_cv_type_socklen_t" "#include \"$srcdir/src/have.h\" - tempcflags="$CFLAGS" - CFLAGS="$CFLAGS -Wall -Werror" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -void *test(void) __attribute__ ((__nonnull__)); - void *test(void) { return (void *)0; } +" +if test "x$ac_cv_type_socklen_t" = xyes; then : +cat >>confdefs.h <<_ACEOF +#define HAVE_SOCKLEN_T 1 _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - tinc_cv_attribute___nonnull__=yes -else - tinc_cv_attribute___nonnull__=no + fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - CFLAGS="$tempcflags" - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tinc_cv_attribute___nonnull__" >&5 -$as_echo "$tinc_cv_attribute___nonnull__" >&6; } - - if test ${tinc_cv_attribute___nonnull__} = no; then - -$as_echo "#define __nonnull__ /**/" >>confdefs.h - - fi - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working __warn_unused_result__ attribute" >&5 -$as_echo_n "checking for working __warn_unused_result__ attribute... " >&6; } -if ${tinc_cv_attribute___warn_unused_result__+:} false; then : - $as_echo_n "(cached) " >&6 -else - - tempcflags="$CFLAGS" - CFLAGS="$CFLAGS -Wall -Werror" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -void *test(void) __attribute__ ((__warn_unused_result__)); - void *test(void) { return (void *)0; } - -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - tinc_cv_attribute___warn_unused_result__=yes -else - tinc_cv_attribute___warn_unused_result__=no - -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - CFLAGS="$tempcflags" - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tinc_cv_attribute___warn_unused_result__" >&5 -$as_echo "$tinc_cv_attribute___warn_unused_result__" >&6; } - - if test ${tinc_cv_attribute___warn_unused_result__} = no; then - -$as_echo "#define __warn_unused_result__ /**/" >>confdefs.h - - fi - - ac_fn_c_check_type "$LINENO" "struct ether_header" "ac_cv_type_struct_ether_header" "#include \"$srcdir/src/have.h\" " @@ -6316,6 +5768,28 @@ cat >>confdefs.h <<_ACEOF _ACEOF +fi +ac_fn_c_check_type "$LINENO" "struct in_addr" "ac_cv_type_struct_in_addr" "#include \"$srcdir/src/have.h\" + +" +if test "x$ac_cv_type_struct_in_addr" = xyes; then : + +cat >>confdefs.h <<_ACEOF +#define HAVE_STRUCT_IN_ADDR 1 +_ACEOF + + +fi +ac_fn_c_check_type "$LINENO" "struct addrinfo" "ac_cv_type_struct_addrinfo" "#include \"$srcdir/src/have.h\" + +" +if test "x$ac_cv_type_struct_addrinfo" = xyes; then : + +cat >>confdefs.h <<_ACEOF +#define HAVE_STRUCT_ADDRINFO 1 +_ACEOF + + fi ac_fn_c_check_type "$LINENO" "struct ip" "ac_cv_type_struct_ip" "#include \"$srcdir/src/have.h\" @@ -6338,6 +5812,28 @@ cat >>confdefs.h <<_ACEOF _ACEOF +fi +ac_fn_c_check_type "$LINENO" "struct in6_addr" "ac_cv_type_struct_in6_addr" "#include \"$srcdir/src/have.h\" + +" +if test "x$ac_cv_type_struct_in6_addr" = xyes; then : + +cat >>confdefs.h <<_ACEOF +#define HAVE_STRUCT_IN6_ADDR 1 +_ACEOF + + +fi +ac_fn_c_check_type "$LINENO" "struct sockaddr_in6" "ac_cv_type_struct_sockaddr_in6" "#include \"$srcdir/src/have.h\" + +" +if test "x$ac_cv_type_struct_sockaddr_in6" = xyes; then : + +cat >>confdefs.h <<_ACEOF +#define HAVE_STRUCT_SOCKADDR_IN6 1 +_ACEOF + + fi ac_fn_c_check_type "$LINENO" "struct ip6_hdr" "ac_cv_type_struct_ip6_hdr" "#include \"$srcdir/src/have.h\" @@ -6418,7 +5914,7 @@ cat >>confdefs.h <<_ACEOF _ACEOF -for ac_func in asprintf daemon fchmod flock fork gettimeofday mlockall putenv recvmmsg strsignal nanosleep unsetenv vsyslog devname fdevname +for ac_func in asprintf daemon fchmod flock fork gettimeofday mlockall pselect putenv strsignal system unsetenv usleep vsyslog devname fdevname do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" @@ -6449,6 +5945,164 @@ else fi + +ac_fn_c_check_func "$LINENO" "socket" "ac_cv_func_socket" +if test "x$ac_cv_func_socket" = xyes; then : + +else + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for connect in -lsocket" >&5 +$as_echo_n "checking for connect in -lsocket... " >&6; } +if ${ac_cv_lib_socket_connect+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lsocket $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char connect (); +int +main () +{ +return connect (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_socket_connect=yes +else + ac_cv_lib_socket_connect=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_connect" >&5 +$as_echo "$ac_cv_lib_socket_connect" >&6; } +if test "x$ac_cv_lib_socket_connect" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBSOCKET 1 +_ACEOF + + LIBS="-lsocket $LIBS" + +fi + + +fi + +ac_fn_c_check_func "$LINENO" "gethostbyname" "ac_cv_func_gethostbyname" +if test "x$ac_cv_func_gethostbyname" = xyes; then : + +else + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gethostbyname in -lnsl" >&5 +$as_echo_n "checking for gethostbyname in -lnsl... " >&6; } +if ${ac_cv_lib_nsl_gethostbyname+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lnsl $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char gethostbyname (); +int +main () +{ +return gethostbyname (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_nsl_gethostbyname=yes +else + ac_cv_lib_nsl_gethostbyname=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nsl_gethostbyname" >&5 +$as_echo "$ac_cv_lib_nsl_gethostbyname" >&6; } +if test "x$ac_cv_lib_nsl_gethostbyname" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBNSL 1 +_ACEOF + + LIBS="-lnsl $LIBS" + +fi + + +fi + + +ac_fn_c_check_decl "$LINENO" "freeaddrinfo" "ac_cv_have_decl_freeaddrinfo" "#include \"$srcdir/src/have.h\" + +" +if test "x$ac_cv_have_decl_freeaddrinfo" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_FREEADDRINFO $ac_have_decl +_ACEOF +ac_fn_c_check_decl "$LINENO" "gai_strerror" "ac_cv_have_decl_gai_strerror" "#include \"$srcdir/src/have.h\" + +" +if test "x$ac_cv_have_decl_gai_strerror" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_GAI_STRERROR $ac_have_decl +_ACEOF +ac_fn_c_check_decl "$LINENO" "getaddrinfo" "ac_cv_have_decl_getaddrinfo" "#include \"$srcdir/src/have.h\" + +" +if test "x$ac_cv_have_decl_getaddrinfo" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_GETADDRINFO $ac_have_decl +_ACEOF +ac_fn_c_check_decl "$LINENO" "getnameinfo" "ac_cv_have_decl_getnameinfo" "#include \"$srcdir/src/have.h\" + +" +if test "x$ac_cv_have_decl_getnameinfo" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_GETNAMEINFO $ac_have_decl +_ACEOF + + ac_fn_c_check_decl "$LINENO" "res_init" "ac_cv_have_decl_res_init" " #include #include @@ -6512,99 +6166,6 @@ fi fi -case $host_os in - *linux*) - for ac_header in linux/if_tun.h -do : - ac_fn_c_check_header_compile "$LINENO" "linux/if_tun.h" "ac_cv_header_linux_if_tun_h" "#include \"$srcdir/src/have.h\" - -" -if test "x$ac_cv_header_linux_if_tun_h" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LINUX_IF_TUN_H 1 -_ACEOF - -else - as_fn_error $? "Required header file missng" "$LINENO" 5 -fi - -done - - ;; - *bsd*|*dragonfly*|*darwin*) - for ac_header in net/if_tun.h net/if_utun.h net/tun/if_tun.h net/if_tap.h net/tap/if_tap.h -do : - as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` -ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "#include \"$srcdir/src/have.h\" - -" -if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : - cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 -_ACEOF - -fi - -done - - ;; - *solaris*) - ac_fn_c_check_func "$LINENO" "socket" "ac_cv_func_socket" -if test "x$ac_cv_func_socket" = xyes; then : - -else - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for connect in -lsocket" >&5 -$as_echo_n "checking for connect in -lsocket... " >&6; } -if ${ac_cv_lib_socket_connect+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lsocket $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char connect (); -int -main () -{ -return connect (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_socket_connect=yes -else - ac_cv_lib_socket_connect=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_connect" >&5 -$as_echo "$ac_cv_lib_socket_connect" >&6; } -if test "x$ac_cv_lib_socket_connect" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBSOCKET 1 -_ACEOF - - LIBS="-lsocket $LIBS" - -fi - -fi - - ;; - *) - ;; -esac - cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure @@ -6691,309 +6252,6 @@ $as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} fi rm -f confcache -# Check whether --enable-legacy-protocol was given. -if test "${enable_legacy_protocol+set}" = set; then : - enableval=$enable_legacy_protocol; if test "x$enable_legacy_protocol" = "xno"; then : - -$as_echo "#define DISABLE_LEGACY 1" >>confdefs.h - -fi - - -fi - - - - - - # Check whether --enable-curses was given. -if test "${enable_curses+set}" = set; then : - enableval=$enable_curses; -fi - - if test "x$enable_curses" != "xno"; then : - - -$as_echo "#define HAVE_CURSES 1" >>confdefs.h - - curses=true - -# Check whether --with-curses was given. -if test "${with_curses+set}" = set; then : - withval=$with_curses; curses="$withval" - CPPFLAGS="$CPPFLAGS -I$withval/include" - LDFLAGS="$LDFLAGS -L$withval/lib" - -fi - - - -# Check whether --with-curses-include was given. -if test "${with_curses_include+set}" = set; then : - withval=$with_curses_include; curses_include="$withval" - CPPFLAGS="$CPPFLAGS -I$withval" - -fi - - - -# Check whether --with-curses-lib was given. -if test "${with_curses_lib+set}" = set; then : - withval=$with_curses_lib; curses_lib="$withval" - LDFLAGS="$LDFLAGS -L$withval" - -fi - - - for ac_header in curses.h -do : - ac_fn_c_check_header_mongrel "$LINENO" "curses.h" "ac_cv_header_curses_h" "$ac_includes_default" -if test "x$ac_cv_header_curses_h" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_CURSES_H 1 -_ACEOF - -else - as_fn_error $? "\"curses header files not found.\"" "$LINENO" 5; break - -fi - -done - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for initscr in -lncurses" >&5 -$as_echo_n "checking for initscr in -lncurses... " >&6; } -if ${ac_cv_lib_ncurses_initscr+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lncurses $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char initscr (); -int -main () -{ -return initscr (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_ncurses_initscr=yes -else - ac_cv_lib_ncurses_initscr=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ncurses_initscr" >&5 -$as_echo "$ac_cv_lib_ncurses_initscr" >&6; } -if test "x$ac_cv_lib_ncurses_initscr" = xyes; then : - CURSES_LIBS="-lncurses"; { $as_echo "$as_me:${as_lineno-$LINENO}: checking for wtimeout in -ltinfo" >&5 -$as_echo_n "checking for wtimeout in -ltinfo... " >&6; } -if ${ac_cv_lib_tinfo_wtimeout+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-ltinfo $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char wtimeout (); -int -main () -{ -return wtimeout (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_tinfo_wtimeout=yes -else - ac_cv_lib_tinfo_wtimeout=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_tinfo_wtimeout" >&5 -$as_echo "$ac_cv_lib_tinfo_wtimeout" >&6; } -if test "x$ac_cv_lib_tinfo_wtimeout" = xyes; then : - CURSES_LIBS+=" -ltinfo" -fi - -else - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for initscr in -lcurses" >&5 -$as_echo_n "checking for initscr in -lcurses... " >&6; } -if ${ac_cv_lib_curses_initscr+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lcurses $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char initscr (); -int -main () -{ -return initscr (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_curses_initscr=yes -else - ac_cv_lib_curses_initscr=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_curses_initscr" >&5 -$as_echo "$ac_cv_lib_curses_initscr" >&6; } -if test "x$ac_cv_lib_curses_initscr" = xyes; then : - CURSES_LIBS="-lcurses" -else - as_fn_error $? "\"curses libraries not found.\"" "$LINENO" 5 - -fi - - -fi - - -fi - - - - - # Check whether --enable-readline was given. -if test "${enable_readline+set}" = set; then : - enableval=$enable_readline; -fi - - if test "x$enable_readline" != "xno"; then : - - -$as_echo "#define HAVE_READLINE 1" >>confdefs.h - - readline=true - -# Check whether --with-readline was given. -if test "${with_readline+set}" = set; then : - withval=$with_readline; readline="$withval" - CPPFLAGS="$CPPFLAGS -I$withval/include" - LDFLAGS="$LDFLAGS -L$withval/lib" - -fi - - - -# Check whether --with-readline-include was given. -if test "${with_readline_include+set}" = set; then : - withval=$with_readline_include; readline_include="$withval" - CPPFLAGS="$CPPFLAGS -I$withval" - -fi - - - -# Check whether --with-readline-lib was given. -if test "${with_readline_lib+set}" = set; then : - withval=$with_readline_lib; readline_lib="$withval" - LDFLAGS="$LDFLAGS -L$withval" - -fi - - - for ac_header in readline/readline.h readline/history.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" -if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : - cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 -_ACEOF - -else - as_fn_error $? "\"readline header files not found.\"" "$LINENO" 5; break - -fi - -done - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for readline in -lreadline" >&5 -$as_echo_n "checking for readline in -lreadline... " >&6; } -if ${ac_cv_lib_readline_readline+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lreadline $CURSES_LIBS - $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char readline (); -int -main () -{ -return readline (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_readline_readline=yes -else - ac_cv_lib_readline_readline=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_readline_readline" >&5 -$as_echo "$ac_cv_lib_readline_readline" >&6; } -if test "x$ac_cv_lib_readline_readline" = xyes; then : - READLINE_LIBS="-lreadline" -else - as_fn_error $? "\"readline library not found.\"" "$LINENO" 5 -fi - - -fi - - # Check whether --enable-zlib was given. @@ -7274,99 +6532,6 @@ done fi -if test "x$enable_legacy_protocol" != "xno"; then : - if test -n "$with_libgcrypt"; then : - gcrypt=true; - -# Check whether --with-libgcrypt was given. -if test "${with_libgcrypt+set}" = set; then : - withval=$with_libgcrypt; libgcrypt="$withval" - CPPFLAGS="$CPPFLAGS -I$withval/include" - LDFLAGS="$LDFLAGS -L$withval/lib" - -fi - - - -# Check whether --with-libgcrypt-include was given. -if test "${with_libgcrypt_include+set}" = set; then : - withval=$with_libgcrypt_include; libgcrypt_include="$withval" - CPPFLAGS="$CPPFLAGS -I$withval" - -fi - - - -# Check whether --with-libgcrypt-lib was given. -if test "${with_libgcrypt_lib+set}" = set; then : - withval=$with_libgcrypt_lib; libgcrypt_lib="$withval" - LDFLAGS="$LDFLAGS -L$withval" - -fi - - - for ac_header in gcrypt.h -do : - ac_fn_c_check_header_mongrel "$LINENO" "gcrypt.h" "ac_cv_header_gcrypt_h" "$ac_includes_default" -if test "x$ac_cv_header_gcrypt_h" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_GCRYPT_H 1 -_ACEOF - -else - as_fn_error $? "libgcrypt header files not found." "$LINENO" 5; break - -fi - -done - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gcry_cipher_encrypt in -lgcrypt" >&5 -$as_echo_n "checking for gcry_cipher_encrypt in -lgcrypt... " >&6; } -if ${ac_cv_lib_gcrypt_gcry_cipher_encrypt+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lgcrypt $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char gcry_cipher_encrypt (); -int -main () -{ -return gcry_cipher_encrypt (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_gcrypt_gcry_cipher_encrypt=yes -else - ac_cv_lib_gcrypt_gcry_cipher_encrypt=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_gcrypt_gcry_cipher_encrypt" >&5 -$as_echo "$ac_cv_lib_gcrypt_gcry_cipher_encrypt" >&6; } -if test "x$ac_cv_lib_gcrypt_gcry_cipher_encrypt" = xyes; then : - LIBS="-lgcrypt $LIBS" -else - as_fn_error $? "libgcrypt libraries not found." "$LINENO" 5 - -fi - - -else - openssl=true; case $host_os in *mingw*) ;; @@ -7564,7 +6729,7 @@ else fi - for ac_func in BN_GENCB_new ERR_remove_state RSA_set0_key + for ac_func in BN_GENCB_new RSA_set0_key do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" @@ -7576,150 +6741,6 @@ _ACEOF fi done - for ac_func in HMAC_CTX_new -do : - ac_fn_c_check_func "$LINENO" "HMAC_CTX_new" "ac_cv_func_HMAC_CTX_new" -if test "x$ac_cv_func_HMAC_CTX_new" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_HMAC_CTX_NEW 1 -_ACEOF - -fi -done - - -fi - - -fi - - if test -n "$openssl"; then - OPENSSL_TRUE= - OPENSSL_FALSE='#' -else - OPENSSL_TRUE='#' - OPENSSL_FALSE= -fi - - if test -n "$gcrypt"; then - GCRYPT_TRUE= - GCRYPT_FALSE='#' -else - GCRYPT_TRUE='#' - GCRYPT_FALSE= -fi - - - - # Check whether --enable-miniupnpc was given. -if test "${enable_miniupnpc+set}" = set; then : - enableval=$enable_miniupnpc; -fi - - if test "x$enable_miniupnpc" = "xyes"; then : - - -$as_echo "#define HAVE_MINIUPNPC 1" >>confdefs.h - - -# Check whether --with-miniupnpc was given. -if test "${with_miniupnpc+set}" = set; then : - withval=$with_miniupnpc; miniupnpc="$withval" - CPPFLAGS="$CPPFLAGS -I$withval/include" - LDFLAGS="$LDFLAGS -L$withval/lib" - -fi - - - -# Check whether --with-miniupnpc-include was given. -if test "${with_miniupnpc_include+set}" = set; then : - withval=$with_miniupnpc_include; miniupnpc_include="$withval" - CPPFLAGS="$CPPFLAGS -I$withval" - -fi - - - -# Check whether --with-miniupnpc-lib was given. -if test "${with_miniupnpc_lib+set}" = set; then : - withval=$with_miniupnpc_lib; miniupnpc_lib="$withval" - LDFLAGS="$LDFLAGS -L$withval" - -fi - - - for ac_header in miniupnpc/miniupnpc.h -do : - ac_fn_c_check_header_mongrel "$LINENO" "miniupnpc/miniupnpc.h" "ac_cv_header_miniupnpc_miniupnpc_h" "$ac_includes_default" -if test "x$ac_cv_header_miniupnpc_miniupnpc_h" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_MINIUPNPC_MINIUPNPC_H 1 -_ACEOF - -else - as_fn_error $? "\"miniupnpc header files not found.\"" "$LINENO" 5; break - -fi - -done - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for upnpDiscover in -lminiupnpc" >&5 -$as_echo_n "checking for upnpDiscover in -lminiupnpc... " >&6; } -if ${ac_cv_lib_miniupnpc_upnpDiscover+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lminiupnpc $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char upnpDiscover (); -int -main () -{ -return upnpDiscover (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_miniupnpc_upnpDiscover=yes -else - ac_cv_lib_miniupnpc_upnpDiscover=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_miniupnpc_upnpDiscover" >&5 -$as_echo "$ac_cv_lib_miniupnpc_upnpDiscover" >&6; } -if test "x$ac_cv_lib_miniupnpc_upnpDiscover" = xyes; then : - MINIUPNPC_LIBS="$LIBS -lminiupnpc" -else - as_fn_error $? "\"miniupnpc libraries not found.\"" "$LINENO" 5 - -fi - - -fi - - - - if test "x$enable_miniupnpc" = "xyes"; then - MINIUPNPC_TRUE= - MINIUPNPC_FALSE='#' -else - MINIUPNPC_TRUE='#' - MINIUPNPC_FALSE= -fi # Check whether --enable-jumbograms was given. @@ -7739,7 +6760,7 @@ if test "x$runstatedir" = "x"; then fi -ac_config_files="$ac_config_files Makefile src/Makefile doc/Makefile test/Makefile systemd/Makefile" +ac_config_files="$ac_config_files Makefile src/Makefile doc/Makefile systemd/Makefile" cat >confcache <<\_ACEOF @@ -7875,10 +6896,6 @@ if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then as_fn_error $? "conditional \"am__fastdepCC\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi -if test -z "${CODE_COVERAGE_ENABLED_TRUE}" && test -z "${CODE_COVERAGE_ENABLED_FALSE}"; then - as_fn_error $? "conditional \"CODE_COVERAGE_ENABLED\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi if test -z "${LINUX_TRUE}" && test -z "${LINUX_FALSE}"; then as_fn_error $? "conditional \"LINUX\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 @@ -7919,18 +6936,6 @@ if test -z "${GETOPT_TRUE}" && test -z "${GETOPT_FALSE}"; then as_fn_error $? "conditional \"GETOPT\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi -if test -z "${OPENSSL_TRUE}" && test -z "${OPENSSL_FALSE}"; then - as_fn_error $? "conditional \"OPENSSL\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${GCRYPT_TRUE}" && test -z "${GCRYPT_FALSE}"; then - as_fn_error $? "conditional \"GCRYPT\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${MINIUPNPC_TRUE}" && test -z "${MINIUPNPC_FALSE}"; then - as_fn_error $? "conditional \"MINIUPNPC\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi : "${CONFIG_STATUS=./config.status}" ac_write_fail=0 @@ -8328,7 +7333,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by tinc $as_me 1.1pre17, which was +This file was extended by tinc $as_me 1.0.36, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -8394,7 +7399,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -tinc config.status 1.1pre17 +tinc config.status 1.0.36 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" @@ -8528,7 +7533,6 @@ do "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; "src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;; "doc/Makefile") CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;; - "test/Makefile") CONFIG_FILES="$CONFIG_FILES test/Makefile" ;; "systemd/Makefile") CONFIG_FILES="$CONFIG_FILES systemd/Makefile" ;; *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; diff --git a/configure.ac b/configure.ac index 241f172..ca2948a 100644 --- a/configure.ac +++ b/configure.ac @@ -1,11 +1,9 @@ dnl Process this file with autoconf to produce a configure script. -origcflags="$CFLAGS" - AC_PREREQ(2.61) -AC_INIT([tinc], m4_esyscmd_s((git describe || echo UNKNOWN) | sed 's/release-//')) +AC_INIT([tinc], [1.0.36]) AC_CONFIG_SRCDIR([src/tincd.c]) -AM_INIT_AUTOMAKE([std-options subdir-objects nostdinc silent-rules -Wall]) +AM_INIT_AUTOMAKE([1.11 check-news std-options subdir-objects nostdinc silent-rules -Wall]) AC_CONFIG_HEADERS([config.h]) AC_CONFIG_MACRO_DIR([m4]) AM_SILENT_RULES([yes]) @@ -20,11 +18,8 @@ dnl Checks for programs. AC_PROG_CC_C99 AC_PROG_CPP AC_PROG_INSTALL -AM_PROG_CC_C_O -dnl Check whether to enable code coverage testing, and if so, clear the default CFLAGS. -AX_CODE_COVERAGE -AS_IF([test "x$enable_code_coverage" = "xyes" -a "x$origcflags" = "x"], [CFLAGS=""]) +AM_PROG_CC_C_O dnl Check and set OS @@ -71,9 +66,7 @@ case $host_os in *mingw*) mingw=true AC_DEFINE(HAVE_MINGW, 1, [MinGW]) - LIBS="$LIBS -lws2_32 -lgdi32 -lcrypt32 -liphlpapi" - LDFLAGS="$LDFLAGS -static" - CPPFLAGS="$CPPFLAGS -DMINIUPNP_STATICLIB" + LIBS="$LIBS -lws2_32 -lgdi32 -lcrypt32" ;; *) AC_MSG_ERROR("Unknown operating system.") @@ -114,6 +107,13 @@ AC_ARG_ENABLE(tunemu, [tunemu=false] ) +AC_ARG_WITH(windows2000, + AS_HELP_STRING([--with-windows2000], [compile with support for Windows 2000. This disables support for tunneling over existing IPv6 networks.]), + [ AS_IF([test "x$with_windows2000" = "xyes"], + [AC_DEFINE(WITH_WINDOWS2000, 1, [Compile with support for Windows 2000])]) + ] +) + AC_ARG_WITH(systemd, AS_HELP_STRING([--with-systemd@<:@=DIR@:>@], [install systemd service files @<:@to DIR if specified@:>@]), [ systemd=true; systemd_path="$with_systemd" ], @@ -137,8 +137,12 @@ AM_CONDITIONAL(WITH_SYSTEMD, test "$systemd" = true) AC_CACHE_SAVE -AS_IF([test -d /sw/include], [CPPFLAGS="$CPPFLAGS -I/sw/include"]) -AS_IF([test -d /sw/lib], [LIBS="$LIBS -L/sw/lib"]) +if test -d /sw/include ; then + CPPFLAGS="$CPPFLAGS -I/sw/include" +fi +if test -d /sw/lib ; then + LIBS="$LIBS -L/sw/lib" +fi dnl Compiler hardening flags dnl No -fstack-protector-all because it doesn't work on all platforms or architectures. @@ -165,11 +169,13 @@ AS_IF([test "x$enable_hardening" != "xno"], ] ); +dnl Checks for libraries. + 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_CHECK_HEADERS([syslog.h sys/file.h sys/ioctl.h sys/mman.h sys/param.h sys/resource.h sys/socket.h sys/time.h sys/un.h sys/wait.h netdb.h arpa/inet.h dirent.h getopt.h]) -AC_CHECK_HEADERS([net/if.h net/if_types.h net/ethernet.h net/if_arp.h netinet/in_systm.h netinet/in.h netinet/in6.h netpacket/packet.h], +AC_CHECK_HEADERS([syslog.h sys/file.h sys/ioctl.h sys/mman.h sys/param.h sys/resource.h sys/socket.h sys/time.h sys/uio.h sys/wait.h netdb.h arpa/inet.h arpa/nameser.h dirent.h getopt.h]) +AC_CHECK_HEADERS([net/if.h net/if_types.h linux/if_tun.h net/if_tun.h net/if_utun.h net/tun/if_tun.h net/if_tap.h net/tap/if_tap.h net/ethernet.h net/if_arp.h netinet/in_systm.h netinet/in.h netinet/in6.h netpacket/packet.h], [], [], [#include "$srcdir/src/have.h"] ) AC_CHECK_HEADERS([netinet/if_ether.h netinet/ip.h netinet/ip6.h resolv.h], @@ -180,78 +186,48 @@ AC_CHECK_HEADERS([netinet/tcp.h netinet/ip_icmp.h netinet/icmp6.h], ) dnl Checks for typedefs, structures, and compiler characteristics. -tinc_ATTRIBUTE(__malloc__) -tinc_ATTRIBUTE(__nonnull__) -tinc_ATTRIBUTE(__warn_unused_result__) +AC_TYPE_PID_T -AC_CHECK_TYPES([struct ether_header, struct arphdr, struct ether_arp, struct ip, struct icmp, struct ip6_hdr, struct icmp6_hdr, struct nd_neighbor_solicit, struct nd_opt_hdr], , , +tinc_ATTRIBUTE(__malloc__) + +AC_CHECK_TYPES([socklen_t, struct ether_header, struct arphdr, struct ether_arp, struct in_addr, struct addrinfo, struct ip, struct icmp, struct in6_addr, struct sockaddr_in6, struct ip6_hdr, struct icmp6_hdr, struct nd_neighbor_solicit, struct nd_opt_hdr], , , [#include "$srcdir/src/have.h"] ) dnl Checks for library functions. AC_TYPE_SIGNAL -AC_CHECK_FUNCS([asprintf daemon fchmod flock fork gettimeofday mlockall putenv recvmmsg strsignal nanosleep unsetenv vsyslog devname fdevname], +AC_CHECK_FUNCS([asprintf daemon fchmod flock fork gettimeofday mlockall pselect putenv strsignal system unsetenv usleep vsyslog devname fdevname], [], [], [#include "$srcdir/src/have.h"] ) AC_CHECK_FUNC(getopt_long, [getopt=true; AC_DEFINE(HAVE_GETOPT_LONG, 1, [getopt_long()])], [getopt=false]) AM_CONDITIONAL(GETOPT, test "$getopt" = true) +dnl Support for SunOS + +AC_CHECK_FUNC(socket, [], [ + AC_CHECK_LIB(socket, connect) +]) +AC_CHECK_FUNC(gethostbyname, [], [ + AC_CHECK_LIB(nsl, gethostbyname) +]) + +AC_CHECK_DECLS([freeaddrinfo, gai_strerror, getaddrinfo, getnameinfo], + [], [], [#include "$srcdir/src/have.h"] +) + AC_CHECK_DECLS([res_init], [AC_CHECK_LIB(resolv, res_init)], [], [ #include #include ]) -dnl Operating system specific checks -case $host_os in - *linux*) - AC_CHECK_HEADERS([linux/if_tun.h], - [], [AC_MSG_ERROR([Required header file missng])], [#include "$srcdir/src/have.h"] - ) - ;; - *bsd*|*dragonfly*|*darwin*) - AC_CHECK_HEADERS([net/if_tun.h net/if_utun.h net/tun/if_tun.h net/if_tap.h net/tap/if_tap.h], - [], [], [#include "$srcdir/src/have.h"] - ) - ;; - *solaris*) - AC_CHECK_FUNC(socket, [], [AC_CHECK_LIB(socket, connect)]) - ;; - *) - ;; -esac - AC_CACHE_SAVE -AC_ARG_ENABLE(legacy-protocol, - AS_HELP_STRING([--disable-legacy-protocol], [disable support for the legacy (tinc 1.0) protocol]), - [ AS_IF([test "x$enable_legacy_protocol" = "xno"], - [ AC_DEFINE(DISABLE_LEGACY, 1, [Disable support for the legacy (tinc 1.0) protocol]) ]) - ] -) - dnl These are defined in files in m4/ -dnl AC_ARG_WITH(libgcrypt, AC_HELP_STRING([--with-libgcrypt], [enable use of libgcrypt instead of OpenSSL])], []) -dnl AC_ARG_WITH(openssl, AC_HELP_STRING([--without-openssl], [disable support for OpenSSL])], []) - -tinc_CURSES -tinc_READLINE tinc_ZLIB tinc_LZO - -AS_IF([test "x$enable_legacy_protocol" != "xno"], - [AS_IF([test -n "$with_libgcrypt"], - [gcrypt=true; tinc_LIBGCRYPT], - [openssl=true; tinc_OPENSSL]) - ] -) - -AM_CONDITIONAL(OPENSSL, test -n "$openssl") -AM_CONDITIONAL(GCRYPT, test -n "$gcrypt") - -tinc_MINIUPNPC -AM_CONDITIONAL(MINIUPNPC, test "x$enable_miniupnpc" = "xyes") +tinc_OPENSSL dnl Check if support for jumbograms is requested AC_ARG_ENABLE(jumbograms, @@ -266,6 +242,6 @@ if test "x$runstatedir" = "x"; then AC_SUBST([runstatedir], ['${localstatedir}/run']) fi -AC_CONFIG_FILES([Makefile src/Makefile doc/Makefile test/Makefile systemd/Makefile]) +AC_CONFIG_FILES([Makefile src/Makefile doc/Makefile systemd/Makefile]) AC_OUTPUT diff --git a/doc/Makefile.am b/doc/Makefile.am index e5f3a04..29d6ffd 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -3,23 +3,20 @@ info_TEXINFOS = tinc.texi tinc_TEXINFOS = tincinclude.texi -man_MANS = tincd.8 tinc.8 tinc.conf.5 tinc-gui.8 +man_MANS = tincd.8 tinc.conf.5 -EXTRA_DIST = tincinclude.texi.in tincd.8.in tinc.8.in tinc.conf.5.in tinc-gui.8.in sample-config +EXTRA_DIST = tincinclude.texi.in tincd.8.in tinc.conf.5.in sample-config -CLEANFILES = *.html tincd.8 tinc.8 tinc.conf.5 tinc-gui.8 tincinclude.texi +CLEANFILES = *.html tincd.8 tinc.conf.5 tincinclude.texi + +texi2html: tinc.texi + $(AM_V_GEN)texi2html -split=chapter $< tincd.8.html: tincd.8 - $(AM_V_GEN)w3mman2html $? > $@ - -tinc.8.html: tinc.8 - $(AM_V_GEN)w3mman2html $? > $@ - -tinc-gui.8.html: tinc-gui.8 - $(AM_V_GEN)w3mman2html $? > $@ + $(AM_V_GEN)w3mman2html $< > $@ tinc.conf.5.html: tinc.conf.5 - $(AM_V_GEN)w3mman2html $? > $@ + $(AM_V_GEN)w3mman2html $< > $@ substitute = sed \ -e s,'@PACKAGE\@',"$(PACKAGE)",g \ @@ -31,12 +28,6 @@ substitute = sed \ tincd.8: $(srcdir)/tincd.8.in $(AM_V_GEN)$(substitute) $(srcdir)/tincd.8.in > $@ -tinc.8: $(srcdir)/tinc.8.in - $(AM_V_GEN)$(substitute) $(srcdir)/tinc.8.in > $@ - -tinc-gui.8: $(srcdir)/tinc-gui.8.in - $(AM_V_GEN)$(substitute) $(srcdir)/tinc-gui.8.in > $@ - tinc.conf.5: $(srcdir)/tinc.conf.5.in $(AM_V_GEN)$(substitute) $(srcdir)/tinc.conf.5.in > $@ diff --git a/doc/Makefile.in b/doc/Makefile.in index 82bcd01..86497e4 100644 --- a/doc/Makefile.in +++ b/doc/Makefile.in @@ -94,12 +94,9 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \ $(top_srcdir)/m4/ax_cflags_warn_all.m4 \ $(top_srcdir)/m4/ax_check_compile_flag.m4 \ $(top_srcdir)/m4/ax_check_link_flag.m4 \ - $(top_srcdir)/m4/ax_code_coverage.m4 \ - $(top_srcdir)/m4/ax_require_defined.m4 \ - $(top_srcdir)/m4/curses.m4 $(top_srcdir)/m4/libgcrypt.m4 \ - $(top_srcdir)/m4/lzo.m4 $(top_srcdir)/m4/miniupnpc.m4 \ - $(top_srcdir)/m4/openssl.m4 $(top_srcdir)/m4/readline.m4 \ - $(top_srcdir)/m4/zlib.m4 $(top_srcdir)/configure.ac + $(top_srcdir)/m4/ax_require_defined.m4 $(top_srcdir)/m4/lzo.m4 \ + $(top_srcdir)/m4/openssl.m4 $(top_srcdir)/m4/zlib.m4 \ + $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) @@ -212,15 +209,8 @@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ -CODE_COVERAGE_CFLAGS = @CODE_COVERAGE_CFLAGS@ -CODE_COVERAGE_CPPFLAGS = @CODE_COVERAGE_CPPFLAGS@ -CODE_COVERAGE_CXXFLAGS = @CODE_COVERAGE_CXXFLAGS@ -CODE_COVERAGE_ENABLED = @CODE_COVERAGE_ENABLED@ -CODE_COVERAGE_LDFLAGS = @CODE_COVERAGE_LDFLAGS@ -CODE_COVERAGE_LIBS = @CODE_COVERAGE_LIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ -CURSES_LIBS = @CURSES_LIBS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ @@ -229,21 +219,17 @@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ -GCOV = @GCOV@ -GENHTML = @GENHTML@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -LCOV = @LCOV@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ -MINIUPNPC_LIBS = @MINIUPNPC_LIBS@ MKDIR_P = @MKDIR_P@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ @@ -254,8 +240,6 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ -READLINE_LIBS = @READLINE_LIBS@ -SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ @@ -314,9 +298,9 @@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ info_TEXINFOS = tinc.texi tinc_TEXINFOS = tincinclude.texi -man_MANS = tincd.8 tinc.8 tinc.conf.5 tinc-gui.8 -EXTRA_DIST = tincinclude.texi.in tincd.8.in tinc.8.in tinc.conf.5.in tinc-gui.8.in sample-config -CLEANFILES = *.html tincd.8 tinc.8 tinc.conf.5 tinc-gui.8 tincinclude.texi +man_MANS = tincd.8 tinc.conf.5 +EXTRA_DIST = tincinclude.texi.in tincd.8.in tinc.conf.5.in sample-config +CLEANFILES = *.html tincd.8 tinc.conf.5 tincinclude.texi substitute = sed \ -e s,'@PACKAGE\@',"$(PACKAGE)",g \ -e s,'@VERSION\@',"$(VERSION)",g \ @@ -846,27 +830,18 @@ uninstall-man: uninstall-man5 uninstall-man8 .PRECIOUS: Makefile +texi2html: tinc.texi + $(AM_V_GEN)texi2html -split=chapter $< + tincd.8.html: tincd.8 - $(AM_V_GEN)w3mman2html $? > $@ - -tinc.8.html: tinc.8 - $(AM_V_GEN)w3mman2html $? > $@ - -tinc-gui.8.html: tinc-gui.8 - $(AM_V_GEN)w3mman2html $? > $@ + $(AM_V_GEN)w3mman2html $< > $@ tinc.conf.5.html: tinc.conf.5 - $(AM_V_GEN)w3mman2html $? > $@ + $(AM_V_GEN)w3mman2html $< > $@ tincd.8: $(srcdir)/tincd.8.in $(AM_V_GEN)$(substitute) $(srcdir)/tincd.8.in > $@ -tinc.8: $(srcdir)/tinc.8.in - $(AM_V_GEN)$(substitute) $(srcdir)/tinc.8.in > $@ - -tinc-gui.8: $(srcdir)/tinc-gui.8.in - $(AM_V_GEN)$(substitute) $(srcdir)/tinc-gui.8.in > $@ - tinc.conf.5: $(srcdir)/tinc.conf.5.in $(AM_V_GEN)$(substitute) $(srcdir)/tinc.conf.5.in > $@ diff --git a/doc/sample-config/tinc.conf b/doc/sample-config/tinc.conf index 25a61a7..7081764 100644 --- a/doc/sample-config/tinc.conf +++ b/doc/sample-config/tinc.conf @@ -16,7 +16,7 @@ Name = alpha ConnectTo = beta # The tap device tinc will use. -# Default is /dev/tap0 for ethertap or FreeBSD, -# /dev/tun0 for Solaris and OpenBSD, -# and /dev/net/tun for Linux tun/tap device. +# /dev/tap0 for ethertap, FreeBSD or OpenBSD +# /dev/tun0 for Solaris +# /dev/net/tun for Linux tun/tap Device = /dev/net/tun diff --git a/doc/tinc-gui.8.in b/doc/tinc-gui.8.in deleted file mode 100644 index e554a85..0000000 --- a/doc/tinc-gui.8.in +++ /dev/null @@ -1,57 +0,0 @@ -.Dd 2011-06-26 -.Dt TINC-GUI 8 -.\" Manual page created by: -.\" Guus Sliepen -.Sh NAME -.Nm tinc-gui -.Nd tinc GUI -.Sh SYNOPSIS -.Nm -.Op Fl n -.Op Fl -net Ns = Ns Ar NETNAME -.Op Fl -pidfile Ns = Ns Ar FILENAME -.Op Fl -help -.Sh DESCRIPTION -This is a Python/wxWidgets based graphical user interface for tinc, a secure virtual private network (VPN) project. -.Nm -communicates with -.Xr tincd 8 -to alter and inspect the running VPN's state. -It can show the current settings, the list of connections, nodes, subnets, and edges. -For now, the debug level can be changed from the GUI, and by right-clicking on a node in the list of connections, -a pop-up menu will appear that allows one to disconnect that node. -.Sh OPTIONS -.Bl -tag -width indent -.It Fl n, -net Ns = Ns Ar NETNAME -Communicate with tincd(8) connected with -.Ar NETNAME . -.It Fl -pidfile Ns = Ns Ar FILENAME -Use the cookie from -.Ar FILENAME -to authenticate with a running tinc daemon. -If unspecified, the default is -.Pa @runstatedir@/tinc. Ns Ar NETNAME Ns Pa .pid. -.It Fl -help -Display short list of options. -.El -.Sh BUGS -The GUI is not finished yet, the final version will have much more functionality. -If you find any bugs, report them to tinc@tinc-vpn.org. -.Sh SEE ALSO -.Xr tincd 8 , -.Pa http://www.tinc-vpn.org/ . -.Pp -The full documentation for tinc is maintained as a Texinfo manual. -If the info and tinc programs are properly installed at your site, -the command -.Ic info tinc -should give you access to the complete manual. -.Pp -tinc comes with ABSOLUTELY NO WARRANTY. -This is free software, and you are welcome to redistribute it under certain conditions; -see the file COPYING for details. -.Sh AUTHORS -.An "Ivo Timmermans" -.An "Guus Sliepen" Aq guus@tinc-vpn.org -.Pp -And thanks to many others for their contributions to tinc! diff --git a/doc/tinc.8.in b/doc/tinc.8.in deleted file mode 100644 index aaa3547..0000000 --- a/doc/tinc.8.in +++ /dev/null @@ -1,345 +0,0 @@ -.Dd 2014-01-16 -.Dt TINCCTL 8 -.\" Manual page created by: -.\" Scott Lamb -.Sh NAME -.Nm tinc -.Nd tinc VPN control -.Sh SYNOPSIS -.Nm -.Op Fl bcn -.Op Fl -config Ns = Ns Ar DIR -.Op Fl -net Ns = Ns Ar NETNAME -.Op Fl -pidfile Ns = Ns Ar FILENAME -.Op Fl -batch -.Op Fl -force -.Op Fl -help -.Op Fl -version -.Op Ar COMMAND -.Sh DESCRIPTION -This is the control program of tinc, a secure virtual private network (VPN) -project. -.Nm -can start and stop -.Xr tincd 8 , -and can to alter and inspect the state of a running VPN. -It can also be used to change the configuration, -or to import or export host configuration files from other nodes. - -If -.Nm -is started with a -.Ar COMMAND , -this command is immediately executed, after which -.Nm -exits. -If no -.Ar COMMAND -is given, -.Nm -will act as a shell; -it will display a prompt, and commands can be entered on the prompt. -If -.Nm -is compiled with libreadline, history and command completion are available on the prompt. -One can also pipe a script containing commands through -.Nm . -In that case, lines starting with a # symbol will be ignored. -.Sh OPTIONS -.Bl -tag -width indent -.It Fl n, -net Ns = Ns Ar NETNAME -Communicate with tincd(8) connected with -.Ar NETNAME . -.It Fl -pidfile Ns = Ns Ar FILENAME -Use the cookie from -.Ar FILENAME -to authenticate with a running tinc daemon. -If unspecified, the default is -.Pa @runstatedir@/tinc. Ns Ar NETNAME Ns Pa .pid. -.It Fl b, -batch -Don't ask for anything (non-interactive mode). -.It Fl -force -Force some commands to work despite warnings. -.It Fl -help -Display short list of options. -.It Fl -version -Output version information and exit. -.El -.Sh ENVIRONMENT VARIABLES -.Bl -tag -width indent -.It Ev NETNAME -If no netname is specified on the command line with the -.Fl n -option, the value of this environment variable is used. -.El -.Sh COMMANDS -.Bl -tag -width indent -.It init Op Ar name -Create initial configuration files and RSA and Ed25519 keypairs with default length. -If no -.Ar name -for this node is given, it will be asked for. -.It get Ar variable -Print the current value of configuration variable -.Ar variable . -If more than one variable with the same name exists, -the value of each of them will be printed on a separate line. -.It set Ar variable Ar value -Set configuration variable -.Ar variable -to the given -.Ar value . -All previously existing configuration variables with the same name are removed. -To set a variable for a specific host, use the notation -.Ar host Ns Li . Ns Ar variable . -.It add Ar variable Ar value -As above, but without removing any previously existing configuration variables. -If the variable already exists with the given value, nothing happens. -.It del Ar variable Op Ar value -Remove configuration variables with the same name and -.Ar value . -If no -.Ar value -is given, all configuration variables with the same name will be removed. -.It edit Ar filename -Start an editor for the given configuration file. -You do not need to specify the full path to the file. -.It export -Export the host configuration file of the local node to standard output. -.It export-all -Export all host configuration files to standard output. -.It import -Import host configuration data generated by the -.Nm -export command from standard input. -Already existing host configuration files are not overwritten unless the option -.Fl -force -is used. -.It exchange -The same as export followed by import. -.It exchange-all -The same as export-all followed by import. -.It invite Ar name -Prepares an invitation for a new node with the given -.Ar name , -and prints a short invitation URL that can be used with the join command. -.It join Op Ar URL -Join an existing VPN using an invitation URL created using the invite command. -If no -.Ar URL -is given, it will be read from standard input. -.It start Op tincd options -Start -.Xr tincd 8 , -optionally with the given extra options. -.It stop -Stop -.Xr tincd 8 . -.It restart Op tincd options -Restart -.Xr tincd 8 , -optionally with the given extra options. -.It reload -Partially rereads configuration files. Connections to hosts whose host -config files are removed are closed. New outgoing connections specified -in -.Xr tinc.conf 5 -will be made. -.It pid -Shows the PID of the currently running -.Xr tincd 8 . -.It generate-keys Op bits -Generate both RSA and Ed25519 keypairs (see below) and exit. -.It generate-ed25519-keys -Generate public/private Ed25519 keypair and exit. -.It generate-rsa-keys Op bits -Generate public/private RSA keypair and exit. -If -.Ar bits -is omitted, the default length will be 2048 bits. -When saving keys to existing files, tinc will not delete the old keys; -you have to remove them manually. -.It dump [reachable] nodes -Dump a list of all known nodes in the VPN. -If the keyword reachable is used, only lists reachable nodes. -.It dump edges -Dump a list of all known connections in the VPN. -.It dump subnets -Dump a list of all known subnets in the VPN. -.It dump connections -Dump a list of all meta connections with ourself. -.It dump graph | digraph -Dump a graph of the VPN in -.Xr dotty 1 -format. -Nodes are colored according to their reachability: -red nodes are unreachable, orange nodes are indirectly reachable, green nodes are directly reachable. -Black nodes are either directly or indirectly reachable, but direct reachability has not been tried yet. -.It dump invitations -Dump a list of outstanding invitations. -The filename of the invitation, as well as the name of the node that is being invited is shown for each invitation. -.It info Ar node | subnet | address -Show information about a particular node, subnet or address. -If an address is given, any matching subnet will be shown. -.It purge -Purges all information remembered about unreachable nodes. -.It debug Ar N -Sets debug level to -.Ar N . -.It log Op Ar N -Capture log messages from a running tinc daemon. -An optional debug level can be given that will be applied only for log messages sent to -.Nm tinc . -.It retry -Forces -.Xr tincd 8 -to try to connect to all uplinks immediately. -Usually -.Xr tincd 8 -attempts to do this itself, -but increases the time it waits between the attempts each time it failed, -and if -.Xr tincd 8 -didn't succeed to connect to an uplink the first time after it started, -it defaults to the maximum time of 15 minutes. -.It disconnect Ar NODE -Closes the meta connection with the given -.Ar NODE . -.It top -If -.Nm -is compiled with libcurses support, this will display live traffic statistics -for all the known nodes, similar to the UNIX -.Xr top 1 -command. -See below for more information. -.It pcap -Dump VPN traffic going through the local tinc node in -.Xr pcap-savefile 5 -format to standard output, -from where it can be redirected to a file or piped through a program that can parse it directly, -such as -.Xr tcpdump 8 . -.It network Op Ar netname -If -.Ar netname -is given, switch to that network. -Otherwise, display a list of all networks for which configuration files exist. -.It fsck -This will check the configuration files for possible problems, -such as unsafe file permissions, missing executable bit on script, -unknown and obsolete configuration variables, wrong public and/or private keys, and so on. -.Pp -When problems are found, this will be printed on a line with WARNING or ERROR in front of it. -Most problems must be corrected by the user itself, however in some cases (like file permissions and missing public keys), -tinc will ask if it should fix the problem. -.It sign Op Ar filename -Sign a file with the local node's private key. -If no -.Ar filename -is given, the file is read from standard input. -The signed file is written to standard output. -.It verify Ar name Op Ar filename -Check the signature of a file against a node's public key. -The -.Ar name -of the node must be given, -or can be -.Li . -to check against the local node's public key, or -.Li * -to allow a signature from any node whose public key is known. -If no -.Ar filename -is given, the file is read from standard input. -If the verification is successful, -a copy of the input with the signature removed is written to standard output, -and the exit code will be zero. -If the verification failed, -nothing will be written to standard output, and the exit code will be non-zero. -.El -.Sh EXAMPLES -Examples of some commands: -.Bd -literal -offset indent -tinc -n vpn dump graph | circo -Txlib -tinc -n vpn pcap | tcpdump -r - -tinc -n vpn top -.Pp -.Ed -Examples of changing the configuration using -.Nm : -.Bd -literal -offset indent -tinc -n vpn init foo -tinc -n vpn add Subnet 192.168.1.0/24 -tinc -n vpn add bar.Address bar.example.com -tinc -n vpn add ConnectTo bar -tinc -n vpn export | gpg --clearsign | mail -s "My config" vpnmaster@example.com -.Ed -.Sh TOP -The top command connects to a running tinc daemon and repeatedly queries its per-node traffic counters. -It displays a list of all the known nodes in the left-most column, -and the amount of bytes and packets read from and sent to each node in the other columns. -By default, the information is updated every second. -The behaviour of the top command can be changed using the following keys: -.Bl -tag -.It Ic s -Change the interval between updates. -After pressing the -.Ic s -key, enter the desired interval in seconds, followed by enter. -Fractional seconds are honored. -Intervals lower than 0.1 seconds are not allowed. -.It Ic c -Toggle between displaying current traffic rates (in packets and bytes per second) -and cumulative traffic (total packets and bytes since the tinc daemon started). -.It Ic n -Sort the list of nodes by name. -.It Ic i -Sort the list of nodes by incoming amount of bytes. -.It Ic I -Sort the list of nodes by incoming amount of packets. -.It Ic o -Sort the list of nodes by outgoing amount of bytes. -.It Ic O -Sort the list of nodes by outgoing amount of packets. -.It Ic t -Sort the list of nodes by sum of incoming and outgoing amount of bytes. -.It Ic T -Sort the list of nodes by sum of incoming and outgoing amount of packets. -.It Ic b -Show amount of traffic in bytes. -.It Ic k -Show amount of traffic in kilobytes. -.It Ic M -Show amount of traffic in megabytes. -.It Ic G -Show amount of traffic in gigabytes. -.It Ic q -Quit. -.El -.Sh BUGS -If you find any bugs, report them to tinc@tinc-vpn.org. -.Sh SEE ALSO -.Xr tincd 8 , -.Xr tinc.conf 5 , -.Xr dotty 1 , -.Xr pcap-savefile 5 , -.Xr tcpdump 8 , -.Xr top 1 , -.Pa http://www.tinc-vpn.org/ , -.Pa http://www.cabal.org/ . -.Pp -The full documentation for tinc is maintained as a Texinfo manual. -If the info and tinc programs are properly installed at your site, -the command -.Ic info tinc -should give you access to the complete manual. -.Pp -tinc comes with ABSOLUTELY NO WARRANTY. -This is free software, and you are welcome to redistribute it under certain conditions; -see the file COPYING for details. -.Sh AUTHORS -.An "Ivo Timmermans" -.An "Guus Sliepen" Aq guus@tinc-vpn.org -.Pp -And thanks to many others for their contributions to tinc! diff --git a/doc/tinc.conf.5.in b/doc/tinc.conf.5.in index 6897ba6..cd7d1a0 100644 --- a/doc/tinc.conf.5.in +++ b/doc/tinc.conf.5.in @@ -1,4 +1,4 @@ -.Dd 2017-09-02 +.Dd 2016-10-29 .Dt TINC.CONF 5 .\" Manual page created by: .\" Ivo Timmermans @@ -11,12 +11,20 @@ The files in the .Pa @sysconfdir@/tinc/ directory contain runtime and security information for the tinc daemon. .Sh NETWORKS -To distinguish multiple instances of tinc running on one computer, -you can use the -.Fl n -option to assign a network name to each tinc daemon. +It is perfectly ok for you to run more than one tinc daemon. +However, in its default form, +you will soon notice that you can't use two different configuration files without the +.Fl c +option. .Pp -The effect of this option is that the daemon will set its configuration root to +We have thought of another way of dealing with this: network names. +This means that you call +.Nm +with the +.Fl n +option, which will assign a name to this daemon. +.Pp +The effect of this is that the daemon will set its configuration root to .Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa / , where .Ar NETNAME @@ -24,14 +32,13 @@ is your argument to the .Fl n option. You'll notice that messages appear in syslog as coming from -.Nm tincd. Ns Ar NETNAME , -and on Linux, unless specified otherwise, the name of the virtual network interface will be the same as the network name. +.Nm tincd. Ns Ar NETNAME . .Pp -It is recommended that you use network names even if you run only one instance of tinc. -However, you can choose not to use the +However, it is not strictly necessary that you call tinc with the .Fl n option. -In this case, the network name would just be empty, and +In this case, the network name would just be empty, +and it will be used as such. .Nm tinc now looks for files in .Pa @sysconfdir@/tinc/ , @@ -41,6 +48,11 @@ the configuration file should be .Pa @sysconfdir@/tinc/tinc.conf , and the host configuration files are now expected to be in .Pa @sysconfdir@/tinc/hosts/ . +.Pp +But it is highly recommended that you use this feature of +.Nm tinc , +because it will be so much clearer whom your daemon talks to. +Hence, we will assume that you use it. .Sh NAMES Each tinc daemon must have a name that is unique in the network which it will be part of. The name will be used by other tinc daemons for identification. @@ -51,34 +63,24 @@ file. To make things easy, choose something that will give unique and easy to remember names to your tinc daemon(s). You could try things like hostnames, owner surnames or location names. -However, you are only allowed to use alphanumerical characters (a-z, A-Z, and 0-9) and underscores (_) in the name. -.Sh INITIAL CONFIGURATION -If you have not configured tinc yet, you can easily create a basic configuration using the following command: -.Bd -literal -offset indent -.Nm tinc Fl n Ar NETNAME Li init Ar NAME -.Ed -.Pp -You can further change the configuration as needed either by manually editing the configuration files, -or by using -.Xr tinc 8 . .Sh PUBLIC/PRIVATE KEYS -The -.Nm tinc Li init -command will have generated both RSA and Ed25519 public/private keypairs. -The private keys should be stored in files named -.Pa rsa_key.priv -and -.Pa ed25519_key.priv -in the directory -.Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa / -The public keys should be stored in the host configuration file -.Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /hosts/ Ns Va NAME . -The RSA keys are used for backwards compatibility with tinc version 1.0. -If you are upgrading from version 1.0 to 1.1, you can keep the old configuration files, -but you will need to create Ed25519 keys using the following command: -.Bd -literal -offset indent -.Nm tinc Fl n Ar NETNAME Li generate-ed25519-keys -.Ed +You should use +.Ic tincd -K +to generate public/private keypairs. +It will generate two keys. +The private key should be stored in a separate file +.Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /rsa_key.priv +\-\- where +.Ar NETNAME +stands for the network (see +.Sx NETWORKS ) +above. +The public key should be stored in the host configuration file +.Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /hosts/ Ns Va NAME +\-\- where +.Va NAME +stands for the name of the local tinc daemon (see +.Sx NAMES ) . .Sh SERVER CONFIGURATION The server configuration of the daemon is done in the file .Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /tinc.conf . @@ -101,10 +103,6 @@ Although all configuration options for the local host listed in this document ca it is recommended to put host specific configuration options in the host configuration file, as this makes it easy to exchange with other nodes. .Pp -You can edit the config file manually, but it is recommended that you use -.Xr tinc 8 -to change configuration variables for you. -.Pp Here are all valid variables, listed in alphabetical order. The default value is given between parentheses. .Bl -tag -width indent @@ -114,24 +112,26 @@ If .Qq any is selected, then depending on the operating system both IPv4 and IPv6 or just IPv6 listening sockets will be created. -.It Va AutoConnect Li = yes | no Po yes -If set to yes, +.It Va BindToAddress Li = Ar address Oo Ar port Oc Bq experimental +If your computer has more than one IPv4 or IPv6 address, .Nm tinc -will automatically set up meta connections to other nodes, -without requiring -.Va ConnectTo -variables. -.Pp -Note: it is not possible to connect to nodes using zero (system-assigned) ports in this way. -.It Va BindToAddress Li = Ar address Op Ar port -This is the same as -.Va ListenAddress , -however the address given with the +will by default listen on all of them for incoming connections. +Multiple .Va BindToAddress -option will also be used for outgoing connections. This is useful if your -computer has more than one IPv4 or IPv6 address, and you want -.Nm tinc -to only use a specific one for outgoing packets. +variables may be specified, +in which case listening sockets for each specified address are made. +.Pp +If no +.Ar port +is specified, the socket will be bound to the port specified by the +.Va Port +option, or to port 655 if neither is given. +To only bind to a specific port but not to a specific address, use +.Li * +for the +.Ar address . +.Pp +This option may not work on all platforms. .It Va BindToInterface Li = Ar interface Bq experimental If your computer has more than one network interface, .Nm tinc @@ -157,13 +157,6 @@ Broadcast packets are sent directly to all nodes that can be reached directly. Broadcast packets received from other nodes are never forwarded. If the IndirectData option is also set, broadcast packets will only be sent to nodes which we have a meta connection to. .El -.It Va BroadcastSubnet Li = Ar address Ns Op Li / Ns Ar prefixlength -Declares a broadcast subnet. Any packet with a destination address falling into such a subnet will be routed as a broadcast (provided all nodes have it declared). -This is most useful to declare subnet broadcast addresses (e.g. 10.42.255.255), otherwise -.Nm tinc -won't know what to do with them. -.Pp -Note that global broadcast addresses (MAC ff:ff:ff:ff:ff:ff, IPv4 255.255.255.255), as well as multicast space (IPv4 224.0.0.0/4, IPv6 ff00::/8) are always considered broadcast addresses and don't need to be declared. .It Va ConnectTo Li = Ar name Specifies which other tinc daemon to connect to on startup. Multiple @@ -176,9 +169,7 @@ The names should be known to this tinc daemon line). .Pp If you don't specify a host with -.Va ConnectTo -and have disabled -.Va AutoConnect , +.Va ConnectTo , .Nm tinc won't try to connect to other daemons at all, and will instead just listen for incoming connections. @@ -202,13 +193,6 @@ instead of .Va Device . The info pages of the tinc package contain more information about configuring the virtual network device. -.It Va DeviceStandby Li = yes | no Po no Pc -When disabled, -.Nm tinc -calls tinc-up on startup, and tinc-down on shutdown. When enabled, -.Nm tinc -will only call tinc-up when at least one node is reachable, and will call tinc-down as soon as no nodes are reachable. -On Windows, this also determines when the virtual network interface "cable" is "plugged". .It Va DeviceType Li = Ar type Pq platform dependent The type of the virtual network device. Tinc will normally automatically select the right type of tun/tap interface, and this option should not be used. @@ -234,10 +218,6 @@ Do NOT connect multiple .Nm tinc daemons to the same multicast address, this will very likely cause routing loops. Also note that this can cause decrypted VPN packets to be sent out on a real network if misconfigured. -.It fd -Use a file descriptor. -All packets are read from this interface. -Packets received for the local node are written to it. .It uml Pq not compiled in by default Create a UNIX socket with the filename specified by .Va Device , @@ -284,17 +264,6 @@ When this option is enabled, packets that cannot be sent directly to the destina 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 Ed25519PrivateKeyFile Li = Ar filename Po Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /ed25519_key.priv Pc -The file in which the private Ed25519 key of this tinc daemon resides. -This is only used if -.Va ExperimentalProtocol -is enabled. -.It Va ExperimentalProtocol Li = yes | no Pq yes -When this option is enabled, the SPTPS protocol will be used when connecting to nodes that also support it. -Ephemeral ECDH will be used for key exchanges, -and Ed25519 will be used instead of RSA for authentication. -When enabled, an Ed25519 key must have been generated before with -.Nm tinc generate-ed25519-keys . .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 @@ -306,16 +275,22 @@ Incoming packets that are meant for another node are forwarded by tinc internall .Pp This is the default mode, and unless you really know you need another forwarding mode, don't change it. .It kernel -Incoming packets using the legacy protocol are always sent to the TUN/TAP device, -even if the packets are not for the local node. +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. -Incoming packets using the SPTPS protocol are dropped, since they are end-to-end encrypted. .El -.It Va FWMark Li = Ar value Po 0 Pc Bq experimental -When set to a non-zero value, all TCP and UDP sockets created by tinc will use the given value as the firewall mark. -This can be used for mark-based routing or for packet filtering. -This option is currently only supported on Linux. +.It Va GraphDumpFile Li = Ar filename Bq experimental +If this option is present, +.Nm tinc +will dump the current network graph to the file +.Ar filename +every minute, unless there were no changes to the graph. +The file is in a format that can be read by graphviz tools. +If +.Ar filename +starts with a pipe symbol |, +then the rest of the filename is interpreted as a shell command +that is executed, the graph is then sent to stdin. .It Va Hostnames Li = yes | no Pq no This option selects whether IP addresses (both real and on the VPN) should be resolved. Since DNS lookups are blocking, it might affect tinc's @@ -333,40 +308,11 @@ Under Windows, this variable is used to select which network interface will be u If you specified a .Va Device , this variable is almost always already correctly set. -.It Va InvitationExpire Li = Ar seconds Pq 604800 -This option controls the period invitations are valid. .It Va KeyExpire Li = Ar seconds Pq 3600 This option controls the period the encryption keys used to encrypt the data are valid. It is common practice to change keys at regular intervals to make it even harder for crackers, even though it is thought to be nearly impossible to crack a single key. -.It Va ListenAddress Li = Ar address Op Ar port -If your computer has more than one IPv4 or IPv6 address, -.Nm tinc -will by default listen on all of them for incoming connections. -This option can be used to restrict which addresses tinc listens on. -Multiple -.Va ListenAddress -variables may be specified, -in which case listening sockets for each specified address are made. -.Pp -If no -.Ar port -is specified, the socket will listen on the port specified by the -.Va Port -option, or to port 655 if neither is given. -To only listen on a specific port but not on a specific address, use -.Li * -for the -.Ar address . -.Pp -If -.Ar port -is set to zero, it will be randomly assigned by the system. This is useful to randomize source ports of UDP packets, which can improve UDP hole punching reliability. In this case it is recommended to set -.Va AddressFamily -as well, otherwise -.Nm tinc -will assign different ports to different address families but other nodes can only know of one. -.It Va LocalDiscovery Li = yes | no Pq yes +.It Va LocalDiscovery Li = yes | no Po no Pc Bq experimental When enabled, .Nm tinc will try to detect peers that are on the same local network. @@ -374,20 +320,14 @@ This will allow direct communication using LAN addresses, even if both peers are and they only ConnectTo a third node outside the NAT, which normally would prevent the peers from learning each other's LAN address. .Pp -Currently, local discovery is implemented by sending some packets to the local address of the node during UDP discovery. This will not work with old nodes that don't transmit their local address. -.It Va LogLevel Li = level Pq 0 -This option controls the verbosity of the logging. The higher the debug level, the more messages it will log. +Currently, local discovery is implemented by sending broadcast packets to the LAN during path MTU discovery. +This feature may not work in all possible situations. .It Va MACExpire Li = Ar seconds Pq 600 This option controls the amount of time MAC addresses are kept before they are removed. This only has effect when .Va Mode is set to .Qq switch . -.It Va MaxConnectionBurst Li = Ar count Pq 100 -This option controls how many connections tinc accepts in quick succession. -If there are more connections than the given number in a short time interval, -tinc will reduce the number of accepted connections to only one per second, -until the burst has passed. .It Va MaxTimeout Li = Ar seconds Pq 900 This is the maximum delay before trying to reconnect to other tinc daemons. .It Va Mode Li = router | switch | hub Pq router @@ -397,7 +337,7 @@ This option selects the way packets are routed to other daemons. In this mode .Va Subnet variables in the host configuration files will be used to form a routing table. -Only packets of routable protocols (IPv4 and IPv6) are supported in this mode. +Only unicast packets of routable protocols (IPv4 and IPv6) are supported in this mode. .Pp This is the default mode, and unless you really know you need another mode, don't change it. .It switch @@ -415,8 +355,7 @@ while no routing table is managed. .It Va Name Li = Ar name Bq required This is the name which identifies this tinc daemon. It must be unique for the virtual private network this daemon will connect to. -.Va Name -may only consist of alphanumeric and underscore characters (a-z, A-Z, 0-9 and _), and is case sensitive. +The Name may only consist of alphanumeric and underscore characters. If .Va Name starts with a @@ -446,9 +385,7 @@ It will allow this tinc daemon to authenticate itself to other daemons. .It Va PrivateKeyFile Li = Ar filename Po Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /rsa_key.priv Pc The file in which the private RSA key of this tinc daemon resides. .It Va ProcessPriority Li = low | normal | high -When this option is used the priority of the -.Nm tincd -process will be adjusted. +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 Proxy Li = socks4 | socks5 | http | exec Ar ... Bq experimental Use a proxy when making outgoing connections. @@ -482,13 +419,13 @@ and .Ev REMOTEPORT are available. .El -.It Va ReplayWindow Li = Ar bytes Pq 32 +.It Va ReplayWindow Li = Ar bytes Pq 16 This is the size of the replay tracking window for each remote node, in bytes. The window is a bitfield which tracks 1 packet per bit, so for example -the default setting of 32 will track up to 256 packets in the window. In high +the default setting of 16 will track up to 128 packets in the window. In high bandwidth scenarios, setting this to a higher value can reduce packet loss from the interaction of replay tracking with underlying real packet loss and/or -reordering. Setting this to zero will disable replay tracking completely and +reordering. Setting this to zero will disable replay tracking completely and pass all traffic, but leaves tinc vulnerable to replay-based attacks on your traffic. .It Va StrictSubnets Li = yes | no Po no Pc Bq experimental @@ -503,42 +440,12 @@ and will only allow connections with nodes for which host config files are prese .Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /hosts/ directory. Setting this options also implicitly sets StrictSubnets. -.It Va UDPDiscovery Li = yes | no Po yes Pc -When this option is enabled tinc will try to establish UDP connectivity to nodes, -using TCP while it determines if a node is reachable over UDP. If it is disabled, -tinc always assumes a node is reachable over UDP. -Note that tinc will never use UDP with nodes that have -.Va TCPOnly -enabled. -.It Va UDPDiscoveryKeepaliveInterval Li = Ar seconds Pq 9 -The minimum amount of time between sending UDP ping datagrams to check UDP connectivity once it has been established. -Note that these pings are large, since they are used to verify link MTU as well. -.It Va UDPDiscoveryInterval Li = Ar seconds Pq 2 -The minimum amount of time between sending UDP ping datagrams to try to establish UDP connectivity. -.It Va UDPDiscoveryTimeout Li = Ar seconds Pq 30 -If tinc doesn't receive any UDP ping replies over the specified interval, -it will assume UDP communication is broken and will fall back to TCP. -.It Va UDPInfoInterval Li = Ar seconds Pq 5 -The minimum amount of time between sending periodic updates about UDP addresses, which are mostly useful for UDP hole punching. -.It Va UDPRcvBuf Li = Ar bytes Pq 1048576 +.It Va UDPRcvBuf Li = Ar bytes Pq OS default Sets the socket receive buffer size for the UDP socket, in bytes. -If set to zero, the default buffer size will be used by the operating system. -Note: this setting can have a significant impact on performance, especially raw throughput. -.It Va UDPSndBuf Li = Ar bytes Pq 1048576 +If unset, the default buffer size will be used by the operating system. +.It Va UDPSndBuf Li = Ar bytes Pq OS default Sets the socket send buffer size for the UDP socket, in bytes. -If set to zero, the default buffer size will be used by the operating system. -Note: this setting can have a significant impact on performance, especially raw throughput. -.It Va UPnP Li = yes | udponly | no Po no Pc -If this option is enabled then tinc will search for UPnP-IGD devices on the local network. -It will then create and maintain port mappings for tinc's listening TCP and UDP ports. -If set to "udponly", tinc will only create a mapping for its UDP (data) port, not for its TCP (metaconnection) port. -Note that tinc must have been built with miniupnpc support for this feature to be available. -Furthermore, be advised that enabling this can have security implications, because the miniupnpc library that -tinc uses might not be well-hardened with regard to malicious UPnP replies. -.It Va UPnPDiscoverWait Li = Ar seconds Pq 5 -The amount of time to wait for replies when probing the local network for UPnP devices. -.It Va UPnPRefreshPeriod Li = Ar seconds Pq 60 -How often tinc will re-add the port mapping, in case it gets reset on the UPnP device. This also controls the duration of the port mapping itself, which will be set to twice that duration. +If unset, the default buffer size will be used by the operating system. .El .Sh HOST CONFIGURATION FILES The host configuration files contain all information needed @@ -561,15 +468,13 @@ Multiple .Va Address variables can be specified, in which case each address will be tried until a working connection has been established. -.It Va Cipher Li = Ar cipher Pq blowfish +.It Va Cipher Li = Ar cipher Pq aes-256-cbc The symmetric cipher algorithm used to encrypt UDP packets. Any cipher supported by LibreSSL or OpenSSL is recognised. Furthermore, specifying .Qq none will turn off packet encryption. It is best to use only those ciphers which support CBC mode. -This option has no effect for connections between nodes using -.Va ExperimentalProtocol . .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 @@ -578,14 +483,12 @@ Fragmentation Needed or Packet too Big messages are dropped by firewalls. 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), 10 (fast lzo) and 11 (best lzo). -.It Va Digest Li = Ar digest Pq sha1 +.It Va Digest Li = Ar digest Pq sha256 The digest algorithm used to authenticate UDP packets. Any digest supported by LibreSSL or OpenSSL is recognised. Furthermore, specifying .Qq none will turn off packet authentication. -This option has no effect for connections between nodes using -.Va ExperimentalProtocol . .It Va IndirectData Li = yes | no Pq no When set to yes, only nodes which already have a meta connection to you will try to establish direct communication with you. @@ -595,28 +498,16 @@ The length of the message authentication code used to authenticate UDP packets. Can be anything from .Qq 0 up to the length of the digest produced by the digest algorithm. -This option has no effect for connections between nodes using -.Va ExperimentalProtocol . .It Va PMTU Li = Ar mtu Po 1514 Pc This option controls the initial path MTU to this node. .It Va PMTUDiscovery Li = yes | no Po yes Pc 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 MTUInfoInterval Li = Ar seconds Pq 5 -The minimum amount of time between sending periodic updates about relay path MTU. Useful for quickly determining MTU to indirect nodes. .It Va Port Li = Ar port Pq 655 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. -.Pp -If this is set to zero, the port will be randomly assigned by the system. This is useful to randomize source ports of UDP packets, which can improve UDP hole punching reliability. When setting -.Va Port -to zero it is recommended to set -.Va AddressFamily -as well, otherwise -.Nm tinc -will assign different ports to different address families but other nodes can only know of one. .It Va PublicKey Li = Ar key Bq obsolete The public RSA key of this tinc daemon. It will be used to cryptographically verify it's identity and to set up a secure connection. @@ -651,7 +542,7 @@ IPv6 subnets are notated like fec0:0:0:1::/64. MAC addresses are notated like 0:1a:2b:3c:4d:5e. .Pp A Subnet can be given a weight to indicate its priority over identical Subnets -owned by different nodes. The default weight is 10. Lower values indicate +owned by different nodes. The default weight is 10. Lower values indicate higher priority. Packets will be sent to the node with the highest priority, unless that node is not reachable, in which case the node with the next highest priority will be tried, and so on. @@ -665,12 +556,6 @@ Setting this options also implicitly sets IndirectData. .Pp Since version 1.0.10, tinc will automatically detect whether communication via UDP is possible or not. -.It Va Weight Li = Ar weight -If this variable is set, it overrides the weight given to connections made with -another host. A higher -.Ar weight -means a lower priority is given to this connection when broadcasting or -forwarding packets. .El .Sh SCRIPTS Apart from reading the server and host configuration files, @@ -684,23 +569,17 @@ This guarantees that scripts will execute in the exact same order as the events If you need to run commands asynchronously, you have to ensure yourself that they are being run in the background. .Pp Under Windows (not Cygwin), the scripts must have the extension -.Pa .bat -or -.Pa .cmd . +.Pa .bat . .Bl -tag -width indent .It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /tinc-up This is the most important script. -If it is present it will be executed right after the tinc daemon has been started and has connected to the virtual network device (or when the first node becomes reachable if -.Va DeviceStandby -is used). +If it is present it will be executed right after the tinc daemon has been started and has connected to the virtual network device. It should be used to set up the corresponding network interface, but can also be used to start other things. .Pp Under Windows you can use the Network Connections control panel instead of creating this script. .It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /tinc-down -This script is started right before the tinc daemon quits (or when the last node becomes unreachable if -.Va DeviceStandby -is used). +This script is started right before the tinc daemon quits. .It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /hosts/ Ns Ar HOST Ns Pa -up This script is started when the tinc daemon with name .Ar HOST @@ -718,10 +597,6 @@ This script is started when a Subnet becomes reachable. The Subnet and the node it belongs to are passed in environment variables. .It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /subnet-down This script is started when a Subnet becomes unreachable. -.It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /invitation-created -This script is started when a new invitation has been created. -.It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /invitation-accepted -This script is started when an invitation has been used. .El .Pp The scripts are started without command line arguments, but can make use of certain environment variables. @@ -730,8 +605,6 @@ Under UNIX like operating systems the names of environment variables must be pre in scripts. Under Windows, in .Pa .bat -or -.Pa .cmd files, they have to be put between .Li % signs. @@ -757,14 +630,6 @@ When a host becomes (un)reachable, this is set to the port number it uses for co When a subnet becomes (un)reachable, this is set to the subnet. .It Ev WEIGHT When a subnet becomes (un)reachable, this is set to the subnet weight. -.It Ev INVITATION_FILE -When the -.Pa invitation-created -script is called, this is set to the file where the invitation details will be stored. -.It Ev INVITATION_URL -When the -.Pa invitation-created -script is called, this is set to the invitation URL that has been created. .El .Pp Do not forget that under UNIX operating systems, you have to make the scripts executable, using the command @@ -778,7 +643,7 @@ The top directory for configuration files. The default name of the server configuration file for net .Ar NETNAME . .It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /conf.d/ -Optional directory from which any .conf file will be loaded +Optional directory from which any *.conf file will be loaded .It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /hosts/ Host configuration files are kept in this directory. .It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /tinc-up @@ -789,14 +654,9 @@ It can be used to set up the corresponding network interface. If an executable file with this name exists, it will be executed right before the tinc daemon is going to close its connection to the virtual network device. -.It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /invitations/ -This directory contains outstanding invitations. -.It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /invitation-data -After a successful join, this file contains a copy of the invitation data received. .El .Sh SEE ALSO .Xr tincd 8 , -.Xr tinc 8 , .Pa https://www.tinc-vpn.org/ , .Pa http://www.tldp.org/LDP/nag2/ . .Pp diff --git a/doc/tinc.info b/doc/tinc.info index 86f8682..44720f3 100644 --- a/doc/tinc.info +++ b/doc/tinc.info @@ -1,14 +1,14 @@ -This is tinc.info, produced by makeinfo version 6.5 from tinc.texi. +This is tinc.info, produced by makeinfo version 6.6 from tinc.texi. INFO-DIR-SECTION Networking tools START-INFO-DIR-ENTRY * tinc: (tinc). The tinc Manual. END-INFO-DIR-ENTRY -This is the info manual for tinc version 1.1pre17, a Virtual Private +This is the info manual for tinc version 1.0.36, a Virtual Private Network daemon. - Copyright (C) 1998-2018 Ivo Timmermans, Guus Sliepen + Copyright (C) 1998-2019 Ivo Timmermans, Guus Sliepen and Wessel Dankers . Permission is granted to make and distribute verbatim copies of this @@ -33,8 +33,6 @@ Top * Installation:: * Configuration:: * Running tinc:: -* Controlling tinc:: -* Invitations:: * Technical information:: * Platform specific information:: * About us:: @@ -50,13 +48,13 @@ Tinc is a Virtual Private Network (VPN) daemon that uses tunneling and encryption to create a secure private network between hosts on the Internet. -Because the tunnel appears to the IP level network code as a normal + Because the tunnel appears to the IP level network code as a normal network device, there is no need to adapt any existing software. The encrypted tunnels allows VPN sites to share information with each other over the Internet without exposing any information to others. -This document is the manual for tinc. Included are chapters on how to -configure your computer to use tinc, as well as the configuration + This document is the manual for tinc. Included are chapters on how +to configure your computer to use tinc, as well as the configuration process of tinc itself. * Menu: @@ -75,7 +73,7 @@ A Virtual Private Network or VPN is a network that can only be accessed by a few elected computers that participate. This goal is achievable in more than just one way. -Private networks can consist of a single stand-alone Ethernet LAN. Or + Private networks can consist of a single stand-alone Ethernet LAN. Or even two computers hooked up using a null-modem cable. In these cases, it is obvious that the network is _private_, no one can access it from the outside. But if your computers are linked to the Internet, the @@ -83,7 +81,7 @@ network is not private anymore, unless one uses firewalls to block all private traffic. But then, there is no way to send private data to trusted computers on the other end of the Internet. -This problem can be solved by using _virtual_ networks. Virtual + This problem can be solved by using _virtual_ networks. Virtual networks can live on top of other networks, but they use encapsulation to keep using their private address space so they do not interfere with the Internet. Mostly, virtual networks appear like a single LAN, even @@ -91,14 +89,14 @@ though they can span the entire world. But virtual networks can't be secured by using firewalls, because the traffic that flows through it has to go through the Internet, where other people can look at it. -As is the case with either type of VPN, anybody could eavesdrop. Or + As is the case with either type of VPN, anybody could eavesdrop. Or worse, alter data. Hence it's probably advisable to encrypt the data that flows over the network. -When one introduces encryption, we can form a true VPN. Other people may -see encrypted traffic, but if they don't know how to decipher it (they -need to know the key for that), they cannot read the information that -flows through the VPN. This is what tinc was made for. + When one introduces encryption, we can form a true VPN. Other people +may see encrypted traffic, but if they don't know how to decipher it +(they need to know the key for that), they cannot read the information +that flows through the VPN. This is what tinc was made for.  File: tinc.info, Node: tinc, Next: Supported platforms, Prev: Virtual Private Networks, Up: Introduction @@ -112,26 +110,26 @@ used the ethertap device that Linux knows of since somewhere about kernel 2.1.60. It didn't work immediately and he improved it a bit. At this stage, the project was still simply called "vpnd". -Since then, a lot has changed--to say the least. + Since then, a lot has changed--to say the least. -Tinc now supports encryption, it consists of a single daemon (tincd) for -both the receiving and sending end, it has become largely + Tinc now supports encryption, it consists of a single daemon (tincd) +for both the receiving and sending end, it has become largely runtime-configurable--in short, it has become a full-fledged professional package. -Tinc also allows more than two sites to connect to each other and form a -single VPN. Traditionally VPNs are created by making tunnels, which only -have two endpoints. Larger VPNs with more sites are created by adding -more tunnels. Tinc takes another approach: only endpoints are + Tinc also allows more than two sites to connect to each other and +form a single VPN. Traditionally VPNs are created by making tunnels, +which only have two endpoints. Larger VPNs with more sites are created +by adding more tunnels. Tinc takes another approach: only endpoints are specified, the software itself will take care of creating the tunnels. This allows for easier configuration and improved scalability. -A lot can--and will be--changed. We have a number of things that we + A lot can--and will be--changed. We have a number of things that we would like to see in the future releases of tinc. Not everything will be available in the near future. Our first objective is to make tinc work perfectly as it stands, and then add more advanced features. -Meanwhile, we're always open-minded towards new ideas. And we're + Meanwhile, we're always open-minded towards new ideas. And we're available too.  @@ -141,15 +139,15 @@ File: tinc.info, Node: Supported platforms, Prev: tinc, Up: Introduction ======================= Tinc has been verified to work under Linux, FreeBSD, OpenBSD, NetBSD, -MacOS/X (Darwin), Solaris, and Windows (both natively and in a Cygwin +Mac OS X (Darwin), Solaris, and Windows (both natively and in a Cygwin environment), with various hardware architectures. These are some of the platforms that are supported by the universal tun/tap device driver or other virtual network device drivers. Without such a driver, tinc will most likely compile and run, but it will not be able to send or receive data packets. -For an up to date list of supported platforms, please check the list on -our website: . + For an up to date list of supported platforms, please check the list +on our website: .  File: tinc.info, Node: Preparations, Next: Installation, Prev: Introduction, Up: Top @@ -178,7 +176,7 @@ File: tinc.info, Node: Configuring the kernel, Next: Libraries, Up: Preparati * Configuration of OpenBSD kernels:: * Configuration of NetBSD kernels:: * Configuration of Solaris kernels:: -* Configuration of Darwin (MacOS/X) kernels:: +* Configuration of Darwin (Mac OS X) kernels:: * Configuration of Windows::  @@ -196,11 +194,11 @@ Here are the options you have to turn on when configuring a new kernel: Network device support Universal tun/tap device driver support -It's not necessary to compile this driver as a module, even if you are -going to run more than one instance of tinc. + It's not necessary to compile this driver as a module, even if you +are going to run more than one instance of tinc. -If you decide to build the tun/tap driver as a kernel module, add these -lines to '/etc/modules.conf': + If you decide to build the tun/tap driver as a kernel module, add +these lines to '/etc/modules.conf': alias char-major-10-200 tun @@ -233,10 +231,10 @@ File: tinc.info, Node: Configuration of NetBSD kernels, Next: Configuration of For NetBSD version 1.5.2 and higher, the tun driver is included in the default kernel configuration. -Tunneling IPv6 may not work on NetBSD's tun device. + Tunneling IPv6 may not work on NetBSD's tun device.  -File: tinc.info, Node: Configuration of Solaris kernels, Next: Configuration of Darwin (MacOS/X) kernels, Prev: Configuration of NetBSD kernels, Up: Configuring the kernel +File: tinc.info, Node: Configuration of Solaris kernels, Next: Configuration of Darwin (Mac OS X) kernels, Prev: Configuration of NetBSD kernels, Up: Configuring the kernel 2.1.5 Configuration of Solaris kernels -------------------------------------- @@ -249,24 +247,24 @@ sparc64 architectures, precompiled versions can be found at header file is missing, install it from the source package.  -File: tinc.info, Node: Configuration of Darwin (MacOS/X) kernels, Next: Configuration of Windows, Prev: Configuration of Solaris kernels, Up: Configuring the kernel +File: tinc.info, Node: Configuration of Darwin (Mac OS X) kernels, Next: Configuration of Windows, Prev: Configuration of Solaris kernels, Up: Configuring the kernel -2.1.6 Configuration of Darwin (MacOS/X) kernels ------------------------------------------------ +2.1.6 Configuration of Darwin (Mac OS X) kernels +------------------------------------------------ Tinc on Darwin relies on a tunnel driver for its data acquisition from the kernel. OS X version 10.6.8 and later have a built-in tun driver called "utun". Tinc also supports the driver from , which supports both tun and tap -style devices, +style devices. -By default, tinc expects the tuntaposx driver to be installed. To use -the utun driver, set add 'Device = utunX' to 'tinc.conf', where X is the -desired number for the utun interface. You can also omit the number, in -which case the first free number will be chosen. + By default, tinc expects the tuntaposx driver to be installed. To +use the utun driver, set add 'Device = utunX' to 'tinc.conf', where X is +the desired number for the utun interface. You can also omit the +number, in which case the first free number will be chosen.  -File: tinc.info, Node: Configuration of Windows, Prev: Configuration of Darwin (MacOS/X) kernels, Up: Configuring the kernel +File: tinc.info, Node: Configuration of Windows, Prev: Configuration of Darwin (Mac OS X) kernels, Up: Configuring the kernel 2.1.7 Configuration of Windows ------------------------------ @@ -285,17 +283,15 @@ File: tinc.info, Node: Libraries, Prev: Configuring the kernel, Up: Preparati ============= Before you can configure or build tinc, you need to have the LibreSSL or -OpenSSL, zlib, LZO, curses and readline libraries installed on your -system. If you try to configure tinc without having them installed, -configure will give you an error message, and stop. +OpenSSL, zlib and lzo libraries installed on your system. If you try to +configure tinc without having them installed, configure will give you an +error message, and stop. * Menu: * LibreSSL/OpenSSL:: * zlib:: -* LZO:: -* libcurses:: -* libreadline:: +* lzo::  File: tinc.info, Node: LibreSSL/OpenSSL, Next: zlib, Up: Libraries @@ -306,25 +302,25 @@ File: tinc.info, Node: LibreSSL/OpenSSL, Next: zlib, Up: Libraries For all cryptography-related functions, tinc uses the functions provided by the LibreSSL or the OpenSSL library. -If this library is not installed, you will get an error when configuring -tinc for build. Support for running tinc with other cryptographic -libraries installed _may_ be added in the future. + If this library is not installed, you will get an error when +configuring tinc for build. Support for running tinc with other +cryptographic libraries installed _may_ be added in the future. -You can use your operating system's package manager to install this if -available. Make sure you install the development AND runtime versions -of this package. + You can use your operating system's package manager to install this +if available. Make sure you install the development AND runtime +versions of this package. -If your operating system comes neither with LibreSSL or OpenSSL, you + If your operating system comes neither with LibreSSL or OpenSSL, you have to install one manually. It is recommended that you get the latest -version of LibreSSL from . Instructions on +version of LibreSSL from . Instructions on how to configure, build and install this package are included within the package. Please make sure you build development and runtime libraries (which is the default). -If you installed the LibreSSL or OpenSSL libraries from source, it may -be necessary to let configure know where they are, by passing configure -one of the -with-openssl-* parameters. Note that you even have to use --with-openssl-* if you are using LibreSSL. + If you installed the LibreSSL or OpenSSL libraries from source, it +may be necessary to let configure know where they are, by passing +configure one of the -with-openssl-* parameters. Note that you even +have to use -with-openssl-* if you are using LibreSSL. --with-openssl=DIR LibreSSL/OpenSSL library and headers prefix --with-openssl-include=DIR LibreSSL/OpenSSL headers directory @@ -347,8 +343,8 @@ everyone to create a statically or dynamically linked executable: You may provide binary packages linked to the OpenSSL libraries, provided that all other requirements of the GPL are met. -Since the LZO library used by tinc is also covered by the GPL, we also -present the following exemption: + Since the LZO library used by tinc is also covered by the GPL, we +also present the following exemption: Hereby I grant a special exception to the tinc VPN project (https://www.tinc-vpn.org/) to link the LZO library with the @@ -357,7 +353,7 @@ present the following exemption: Markus F.X.J. Oberhumer  -File: tinc.info, Node: zlib, Next: LZO, Prev: LibreSSL/OpenSSL, Up: Libraries +File: tinc.info, Node: zlib, Next: lzo, Prev: LibreSSL/OpenSSL, Up: Libraries 2.2.2 zlib ---------- @@ -365,94 +361,47 @@ File: tinc.info, Node: zlib, Next: LZO, Prev: LibreSSL/OpenSSL, Up: Librarie For the optional compression of UDP packets, tinc uses the functions provided by the zlib library. -If this library is not installed, you will get an error when running the -configure script. You can either install the zlib library, or disable -support for zlib compression by using the "-disable-zlib" option when -running the configure script. Note that if you disable support for + If this library is not installed, you will get an error when running +the configure script. You can either install the zlib library, or +disable support for zlib compression by using the "-disable-zlib" option +when running the configure script. Note that if you disable support for zlib, the resulting binary will not work correctly on VPNs where zlib compression is used. -You can use your operating system's package manager to install this if -available. Make sure you install the development AND runtime versions -of this package. + You can use your operating system's package manager to install this +if available. Make sure you install the development AND runtime +versions of this package. -If you have to install zlib manually, you can get the source code from -. Instructions on how to configure, build and + If you have to install zlib manually, you can get the source code +from . Instructions on how to configure, build and install this package are included within the package. Please make sure you build development and runtime libraries (which is the default).  -File: tinc.info, Node: LZO, Next: libcurses, Prev: zlib, Up: Libraries +File: tinc.info, Node: lzo, Prev: zlib, Up: Libraries -2.2.3 LZO +2.2.3 lzo --------- Another form of compression is offered using the LZO library. -If this library is not installed, you will get an error when running the -configure script. You can either install the LZO library, or disable -support for LZO compression by using the "-disable-lzo" option when -running the configure script. Note that if you disable support for LZO, -the resulting binary will not work correctly on VPNs where LZO + If this library is not installed, you will get an error when running +the configure script. You can either install the LZO library, or +disable support for LZO compression by using the "-disable-lzo" option +when running the configure script. Note that if you disable support for +LZO, the resulting binary will not work correctly on VPNs where LZO compression is used. -You can use your operating system's package manager to install this if -available. Make sure you install the development AND runtime versions -of this package. + You can use your operating system's package manager to install this +if available. Make sure you install the development AND runtime +versions of this package. -If you have to install LZO manually, you can get the source code from + If you have to install lzo manually, you can get the source code from . Instructions on how to configure, build and install this package are included within the package. Please make sure you build development and runtime libraries (which is the default). - -File: tinc.info, Node: libcurses, Next: libreadline, Prev: LZO, Up: Libraries - -2.2.4 libcurses ---------------- - -For the "tinc top" command, tinc requires a curses library. - -If this library is not installed, you will get an error when running the -configure script. You can either install a suitable curses library, or -disable all functionality that depends on a curses library by using the -"-disable-curses" option when running the configure script. - -There are several curses libraries. It is recommended that you install -"ncurses" (), however other -curses libraries should also work. In particular, "PDCurses" -() is recommended if you want to -compile tinc for Windows. - -You can use your operating system's package manager to install this if -available. Make sure you install the development AND runtime versions -of this package. - - -File: tinc.info, Node: libreadline, Prev: libcurses, Up: Libraries - -2.2.5 libreadline ------------------ - -For the "tinc" command's shell functionality, tinc uses the readline -library. - -If this library is not installed, you will get an error when running the -configure script. You can either install a suitable readline library, -or disable all functionality that depends on a readline library by using -the "-disable-readline" option when running the configure script. - -You can use your operating system's package manager to install this if -available. Make sure you install the development AND runtime versions -of this package. - -If you have to install libreadline manually, you can get the source code -from . Instructions on how to -configure, build and install this package are included within the -package. Please make sure you build development and runtime libraries -(which is the default). -  File: tinc.info, Node: Installation, Next: Configuration, Prev: Preparations, Up: Top @@ -463,13 +412,13 @@ If you use Debian, you may want to install one of the precompiled packages for your system. These packages are equipped with system startup scripts and sample configurations. -If you cannot use one of the precompiled packages, or you want to + If you cannot use one of the precompiled packages, or you want to compile tinc for yourself, you can use the source. The source is distributed under the GNU General Public License (GPL). Download the source from the download page (https://www.tinc-vpn.org/download/). -Tinc comes in a convenient autoconf/automake package, which you can just -treat the same as any other package. Which is just untar it, type + Tinc comes in a convenient autoconf/automake package, which you can +just treat the same as any other package. Which is just untar it, type './configure' and then 'make'. More detailed instructions are in the file 'INSTALL', which is included in the source distribution. @@ -487,32 +436,33 @@ File: tinc.info, Node: Building and installing tinc, Next: System files, Up: Detailed instructions on configuring the source, building tinc and installing tinc can be found in the file called 'INSTALL'. -If you happen to have a binary package for tinc for your distribution, -you can use the package management tools of that distribution to install -tinc. The documentation that comes along with your distribution will -tell you how to do that. + If you happen to have a binary package for tinc for your +distribution, you can use the package management tools of that +distribution to install tinc. The documentation that comes along with +your distribution will tell you how to do that. * Menu: -* Darwin (MacOS/X) build environment:: +* Darwin (Mac OS X) build environment:: * Cygwin (Windows) build environment:: * MinGW (Windows) build environment::  -File: tinc.info, Node: Darwin (MacOS/X) build environment, Next: Cygwin (Windows) build environment, Up: Building and installing tinc +File: tinc.info, Node: Darwin (Mac OS X) build environment, Next: Cygwin (Windows) build environment, Up: Building and installing tinc -3.1.1 Darwin (MacOS/X) build environment ----------------------------------------- +3.1.1 Darwin (Mac OS X) build environment +----------------------------------------- In order to build tinc on Darwin, you need to install Xcode from . It might also help to install a recent version of Fink from . -You need to download and install LibreSSL (or OpenSSL) and LZO, either -directly from their websites (see *note Libraries::) or using Fink. + You need to download and install LibreSSL (or OpenSSL) and LZO, +either directly from their websites (see *note Libraries::) or using +Fink.  -File: tinc.info, Node: Cygwin (Windows) build environment, Next: MinGW (Windows) build environment, Prev: Darwin (MacOS/X) build environment, Up: Building and installing tinc +File: tinc.info, Node: Cygwin (Windows) build environment, Next: MinGW (Windows) build environment, Prev: Darwin (Mac OS X) build environment, Up: Building and installing tinc 3.1.2 Cygwin (Windows) build environment ---------------------------------------- @@ -520,7 +470,7 @@ File: tinc.info, Node: Cygwin (Windows) build environment, Next: MinGW (Window If Cygwin hasn't already been installed, install it directly from . -When tinc is compiled in a Cygwin environment, it can only be run in + When tinc is compiled in a Cygwin environment, it can only be run in this environment, but all programs, including those started outside the Cygwin environment, will be able to use the VPN. It will also support all features. @@ -535,10 +485,10 @@ You will need to install the MinGW environment from . You also need to download and install LibreSSL (or OpenSSL) and LZO. -When tinc is compiled using MinGW it runs natively under Windows, it is -not necessary to keep MinGW installed. + When tinc is compiled using MinGW it runs natively under Windows, it +is not necessary to keep MinGW installed. -When detaching, tinc will install itself as a service, which will be + When detaching, tinc will install itself as a service, which will be restarted automatically after reboots.  @@ -564,8 +514,8 @@ File: tinc.info, Node: Device files, Next: Other files, Up: System files Most operating systems nowadays come with the necessary device files by default, or they have a mechanism to create them on demand. -If you use Linux and do not have udev installed, you may need to create -the following device file if it does not exist: + If you use Linux and do not have udev installed, you may need to +create the following device file if it does not exist: mknod -m 600 /dev/net/tun c 10 200 @@ -606,6 +556,7 @@ File: tinc.info, Node: Configuration, Next: Running tinc, Prev: Installation, * Multiple networks:: * How connections work:: * Configuration files:: +* Generating keypairs:: * Network interfaces:: * Example configuration:: @@ -625,19 +576,13 @@ Do you want to run tinc in router mode or switch mode? These questions can only be answered by yourself, you will not find the answers in this documentation. Make sure you have an adequate understanding of networks in general. A good resource on networking is the Linux Network -Administrators Guide (https://www.tldp.org/LDP/nag2/). +Administrators Guide (http://www.tldp.org/LDP/nag2/). -If you have everything clearly pictured in your mind, proceed in the -following order: First, create the initial configuration files and -public/private keypairs using the following command: - tinc -n NETNAME init NAME -Second, use 'tinc -n NETNAME add ...' to further configure tinc. -Finally, export your host configuration file using 'tinc -n NETNAME -export' and send it to those people or computers you want tinc to -connect to. They should send you their host configuration file back, -which you can import using 'tinc -n NETNAME import'. - -These steps are described in the subsections below. + If you have everything clearly pictured in your mind, proceed in the +following order: First, generate the configuration files ('tinc.conf', +your host configuration file, 'tinc-up' and perhaps 'tinc-down'). Then +generate the keypairs. Finally, distribute the host configuration +files. These steps are described in the subsections below.  File: tinc.info, Node: Multiple networks, Next: How connections work, Prev: Configuration introduction, Up: Configuration @@ -648,25 +593,27 @@ File: tinc.info, Node: Multiple networks, Next: How connections work, Prev: C In order to allow you to run more than one tinc daemon on one computer, for instance if your computer is part of more than one VPN, you can assign a NETNAME to your VPN. It is not required if you only run one -tinc daemon, it doesn't even have to be the same on all the nodes of +tinc daemon, it doesn't even have to be the same on all the sites of your VPN, but it is recommended that you choose one anyway. -We will assume you use a netname throughout this document. This means -that you call tinc with the -n argument, which will specify the netname. + We will assume you use a netname throughout this document. This +means that you call tincd with the -n argument, which will assign a +netname to this daemon. -The effect of this option is that tinc will set its configuration root + The effect of this is that the daemon will set its configuration root to '/etc/tinc/NETNAME/', where NETNAME is your argument to the -n -option. You will also notice that log messages it appears in syslog as -coming from 'tinc.NETNAME', and on Linux, unless specified otherwise, -the name of the virtual network interface will be the same as the -network name. +option. You'll notice that it appears in syslog as 'tinc.NETNAME'. -However, it is not strictly necessary that you call tinc with the -n -option. If you do not use it, the network name will just be empty, and -tinc will look for files in '/etc/tinc/' instead of -'/etc/tinc/NETNAME/'; the configuration file will then be -'/etc/tinc/tinc.conf', and the host configuration files are expected to -be in '/etc/tinc/hosts/'. + However, it is not strictly necessary that you call tinc with the -n +option. In this case, the network name would just be empty, and it will +be used as such. tinc now looks for files in '/etc/tinc/', instead of +'/etc/tinc/NETNAME/'; the configuration file should be +'/etc/tinc/tinc.conf', and the host configuration files are now expected +to be in '/etc/tinc/hosts/'. + + But it is highly recommended that you use this feature of tinc, +because it will be so much clearer whom your daemon talks to. Hence, we +will assume that you use it.  File: tinc.info, Node: How connections work, Next: Configuration files, Prev: Multiple networks, Up: Configuration @@ -675,43 +622,25 @@ File: tinc.info, Node: How connections work, Next: Configuration files, Prev: ======================== When tinc starts up, it parses the command-line options and then reads -in the configuration file tinc.conf. It will then start listening for -incoming connection from other daemons, and will by default also -automatically try to connect to known peers. By default, tinc will try -to keep at least 3 working meta-connections alive at all times. +in the configuration file tinc.conf. If it sees one or more 'ConnectTo' +values pointing to other tinc daemons in that file, it will try to +connect to those other daemons. Whether this succeeds or not and +whether 'ConnectTo' is specified or not, tinc will listen for incoming +connection from other daemons. If you did specify a 'ConnectTo' value +and the other side is not responding, tinc will keep retrying. This +means that once started, tinc will stay running until you tell it to +stop, and failures to connect to other tinc daemons will not stop your +tinc daemon for trying again later. This means you don't have to +intervene if there are temporary network problems. -There is no real distinction between a server and a client in tinc. If -you wish, you can view a tinc daemon without a 'ConnectTo' statement in -tinc.conf and 'AutoConnect = no' as a server, and one which does have -one or more 'ConnectTo' statements or 'Autoconnect = yes' (which is the -default) as a client. It does not matter if two tinc daemons have a -'ConnectTo' value pointing to each other however. - -Connections specified using 'ConnectTo' are so-called meta-connections. -Tinc daemons exchange information about all other daemon they know about -via these meta-connections. After learning about all the daemons in the -VPN, tinc will create other connections as necessary in order to -communicate with them. For example, if there are three daemons named A, -B and C, and A has 'ConnectTo = B' in its tinc.conf file, and C has -'ConnectTo = B' in its tinc.conf file, then A will learn about C from B, -and will be able to exchange VPN packets with C without the need to have -'ConnectTo = C' in its tinc.conf file. - -It could be that some daemons are located behind a Network Address -Translation (NAT) device, or behind a firewall. In the above scenario -with three daemons, if A and C are behind a NAT, B will automatically -help A and C punch holes through their NAT, in a way similar to the STUN -protocol, so that A and C can still communicate with each other -directly. It is not always possible to do this however, and firewalls -might also prevent direct communication. In that case, VPN packets -between A and C will be forwarded by B. - -In effect, all nodes in the VPN will be able to talk to each other, as -long as there is a path of meta-connections between them, and whenever -possible, two nodes will communicate with each other directly. + There is no real distinction between a server and a client in tinc. +If you wish, you can view a tinc daemon without a 'ConnectTo' value as a +server, and one which does specify such a value as a client. It does +not matter if two tinc daemons have a 'ConnectTo' value pointing to each +other however.  -File: tinc.info, Node: Configuration files, Next: Network interfaces, Prev: How connections work, Up: Configuration +File: tinc.info, Node: Configuration files, Next: Generating keypairs, Prev: How connections work, Up: Configuration 4.4 Configuration files ======================= @@ -720,32 +649,29 @@ The actual configuration of the daemon is done in the file '/etc/tinc/NETNAME/tinc.conf' and at least one other file in the directory '/etc/tinc/NETNAME/hosts/'. -An optional directory '/etc/tinc/NETNAME/conf.d' can be added from which -any .conf file will be read. + An optional directory '/etc/tinc/NETNAME/conf.d' can be added from +which any .conf file will be read. -These file consists of comments (lines started with a #) or assignments -in the form of + These file consists of comments (lines started with a #) or +assignments in the form of Variable = Value. -The variable names are case insensitive, and any spaces, tabs, newlines -and carriage returns are ignored. Note: it is not required that you put -in the '=' sign, but doing so improves readability. If you leave it -out, remember to replace it with at least one space character. + The variable names are case insensitive, and any spaces, tabs, +newlines and carriage returns are ignored. Note: it is not required +that you put in the '=' sign, but doing so improves readability. If you +leave it out, remember to replace it with at least one space character. -The server configuration is complemented with host specific + The server configuration is complemented with host specific configuration (see the next section). Although all host configuration options for the local node listed in this document can also be put in '/etc/tinc/NETNAME/tinc.conf', it is recommended to put host specific configuration options in the host configuration file, as this makes it easy to exchange with other nodes. -You can edit the config file manually, but it is recommended that you -use the tinc command to change configuration variables for you. - -In the following two subsections all valid variables are listed in -alphabetical order. The default value is given between parentheses, -other comments are between square brackets. + In this section all valid variables are listed in alphabetical order. +The default value is given between parentheses, other comments are +between square brackets. * Menu: @@ -766,16 +692,18 @@ AddressFamily = (any) system both IPv4 and IPv6 or just IPv6 listening sockets will be created. -AutoConnect = (yes) - If set to yes, tinc will automatically set up meta connections to - other nodes, without requiring CONNECTTO variables. +BindToAddress =
[] [experimental] + If your computer has more than one IPv4 or IPv6 address, tinc will + by default listen on all of them for incoming connections. + Multiple BindToAddress variables may be specified, in which case + listening sockets for each specified address are made. -BindToAddress =
[] - This is the same as ListenAddress, however the address given with - the BindToAddress option will also be used for outgoing - connections. This is useful if your computer has more than one - IPv4 or IPv6 address, and you want tinc to only use a specific one - for outgoing packets. + If no PORT is specified, the socket will be bound to the port + specified by the Port option, or to port 655 if neither is given. + To only bind to a specific port but not to a specific address, use + "*" for the ADDRESS. + + This option may not work on all platforms. BindToInterface = [experimental] If you have more than one network interface in your computer, tinc @@ -783,9 +711,7 @@ BindToInterface = [experimental] is possible to bind tinc to a single interface like eth0 or ppp0 with this variable. - This option may not work on all platforms. Also, on some platforms - it will not actually bind to an interface, but rather to the - address that the interface has at the moment a socket is created. + This option may not work on all platforms. Broadcast = (mst) [experimental] This option selects the way broadcast packets are sent to other @@ -807,18 +733,6 @@ Broadcast = (mst) [experimental] broadcast packets will only be sent to nodes which we have a meta connection to. -BroadcastSubnet = ADDRESS[/PREFIXLENGTH] - Declares a broadcast subnet. Any packet with a destination address - falling into such a subnet will be routed as a broadcast (provided - all nodes have it declared). This is most useful to declare subnet - broadcast addresses (e.g. 10.42.255.255), otherwise tinc won't - know what to do with them. - - Note that global broadcast addresses (MAC ff:ff:ff:ff:ff:ff, IPv4 - 255.255.255.255), as well as multicast space (IPv4 224.0.0.0/4, - IPv6 ff00::/8) are always considered broadcast addresses and don't - need to be declared. - ConnectTo = Specifies which other tinc daemon to connect to on startup. Multiple ConnectTo variables may be specified, in which case @@ -826,9 +740,9 @@ ConnectTo = names should be known to this tinc daemon (i.e., there should be a host configuration file for the name on the ConnectTo line). - If you don't specify a host with ConnectTo and have disabled - AutoConnect, tinc won't try to connect to other daemons at all, and - will instead just listen for incoming connections. + If you don't specify a host with ConnectTo, tinc won't try to + connect to other daemons at all, and will instead just listen for + incoming connections. DecrementTTL = (no) [experimental] When enabled, tinc will decrement the Time To Live field in IPv4 @@ -841,17 +755,9 @@ DecrementTTL = (no) [experimental] Device = ('/dev/tap0', '/dev/net/tun' or other depending on platform) The virtual network device to use. Tinc will automatically detect - what kind of device it is. Note that you can only use one device - per daemon. Under Windows, use INTERFACE instead of DEVICE. Note - that you can only use one device per daemon. See also *note Device - files::. - -DeviceStandby = (no) - When disabled, tinc calls 'tinc-up' on startup, and 'tinc-down' on - shutdown. When enabled, tinc will only call 'tinc-up' when at - least one node is reachable, and will call 'tinc-down' as soon as - no nodes are reachable. On Windows, this also determines when the - virtual network interface "cable" is "plugged". + what kind of device it is. Under Windows, use INTERFACE instead of + DEVICE. Note that you can only use one device per daemon. See + also *note Device files::. DeviceType = (platform dependent) The type of the virtual network device. Tinc will normally @@ -883,11 +789,6 @@ DeviceType = (platform dependent) that this can cause decrypted VPN packets to be sent out on a real network if misconfigured. - fd - Use a file descriptor. All packets are read from this - interface. Packets received for the local node are written to - it. - uml (not compiled in by default) Create a UNIX socket with the filename specified by DEVICE, or '/var/run/NETNAME.umlsocket' if not specified. Tinc will wait @@ -935,17 +836,6 @@ DirectOnly = (no) [experimental] IndirectData option, packets for nodes for which we do not have a meta connection with are also dropped. -Ed25519PrivateKeyFile = ('/etc/tinc/NETNAME/ed25519_key.priv') - The file in which the private Ed25519 key of this tinc daemon - resides. This is only used if ExperimentalProtocol is enabled. - -ExperimentalProtocol = (yes) - When this option is enabled, the SPTPS protocol will be used when - connecting to nodes that also support it. Ephemeral ECDH will be - used for key exchanges, and Ed25519 will be used instead of RSA for - authentication. When enabled, an Ed25519 key must have been - generated before with 'tinc generate-ed25519-keys'. - Forwarding = (internal) [experimental] This option selects the way indirect packets are forwarded. @@ -961,18 +851,18 @@ Forwarding = (internal) [experimental] another forwarding mode, don't change it. kernel - Incoming packets using the legacy protocol 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. Incoming packets using the SPTPS protocol are - dropped, since they are end-to-end encrypted. + 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. -FWMark = (0) [experimental] - When set to a non-zero value, all TCP and UDP sockets created by - tinc will use the given value as the firewall mark. This can be - used for mark-based routing or for packet filtering. This option - is currently only supported on Linux. +GraphDumpFile = [experimental] + If this option is present, tinc will dump the current network graph + to the file FILENAME every minute, unless there were no changes to + the graph. The file is in a format that can be read by graphviz + tools. If FILENAME starts with a pipe symbol |, then the rest of + the filename is interpreted as a shell command that is executed, + the graph is then sent to stdin. Hostnames = (no) This option selects whether IP addresses (both real and on the VPN) @@ -985,6 +875,9 @@ Hostnames = (no) configuration file, but whether hostnames should be resolved while logging. +IffOneQueue = (no) [experimental] + (Linux only) Set IFF_ONE_QUEUE flag on TUN/TAP devices. + Interface = Defines the name of the interface corresponding to the virtual network device. Depending on the operating system and the type of @@ -993,39 +886,38 @@ Interface = interface will be used. If you specified a Device, this variable is almost always already correctly set. -ListenAddress =
[] - If your computer has more than one IPv4 or IPv6 address, tinc will - by default listen on all of them for incoming connections. This - option can be used to restrict which addresses tinc listens on. - Multiple ListenAddress variables may be specified, in which case - listening sockets for each specified address are made. +KeyExpire = (3600) + This option controls the time the encryption keys used to encrypt + the data are valid. It is common practice to change keys at + regular intervals to make it even harder for crackers, even though + it is thought to be nearly impossible to crack a single key. - If no PORT is specified, the socket will listen on the port - specified by the Port option, or to port 655 if neither is given. - To only listen on a specific port but not to a specific address, - use "*" for the ADDRESS. - -LocalDiscovery = (no) +LocalDiscovery = (no) [experimental] When enabled, tinc will try to detect peers that are on the same local network. This will allow direct communication using LAN addresses, even if both peers are behind a NAT and they only ConnectTo a third node outside the NAT, which normally would prevent the peers from learning each other's LAN address. - Currently, local discovery is implemented by sending some packets - to the local address of the node during UDP discovery. This will - not work with old nodes that don't transmit their local address. + Currently, local discovery is implemented by sending broadcast + packets to the LAN during path MTU discovery. This feature may not + work in all possible situations. -LogLevel = (0) - This option controls the verbosity of the logging. See *note Debug - levels::. +MACExpire = (600) + This option controls the amount of time MAC addresses are kept + before they are removed. This only has effect when Mode is set to + "switch". + +MaxTimeout = (900) + This is the maximum delay before trying to reconnect to other tinc + daemons. Mode = (router) This option selects the way packets are routed to other daemons. router In this mode Subnet variables in the host configuration files - will be used to form a routing table. Only packets of + will be used to form a routing table. Only unicast packets of routable protocols (IPv4 and IPv6) are supported in this mode. This is the default mode, and unless you really know you need @@ -1047,30 +939,10 @@ Mode = (router) every packet will be broadcast to the other daemons while no routing table is managed. -InvitationExpire = (604800) - This option controls the time invitations are valid. - -KeyExpire = (3600) - This option controls the time the encryption keys used to encrypt - the data are valid. It is common practice to change keys at - regular intervals to make it even harder for crackers, even though - it is thought to be nearly impossible to crack a single key. - -MACExpire = (600) - This option controls the amount of time MAC addresses are kept - before they are removed. This only has effect when Mode is set to - "switch". - -MaxConnectionBurst = (100) - This option controls how many connections tinc accepts in quick - succession. If there are more connections than the given number in - a short time interval, tinc will reduce the number of accepted - connections to only one per second, until the burst has passed. - Name = [required] This is a symbolic name for this connection. The name must consist - only of alfanumeric and underscore characters (a-z, A-Z, 0-9 and - _), and is case sensitive. + only of alphanumeric and underscore characters (a-z, A-Z, 0-9 and + _). If Name starts with a $, then the contents of the environment variable that follows will be used. In that case, invalid @@ -1101,8 +973,8 @@ PrivateKey = [obsolete] PrivateKeyFile = ('/etc/tinc/NETNAME/rsa_key.priv') This is the full path name of the RSA private key file that was - generated by 'tinc generate-keys'. It must be a full path, not a - relative directory. + generated by 'tincd --generate-keys'. It must be a full path, not + a relative directory. ProcessPriority = When this option is used the priority of the tincd process will be @@ -1132,10 +1004,10 @@ Proxy = socks4 | socks5 | http | exec ... [experimental] connection. The environment variables 'NAME', 'NODE', 'REMOTEADDRES' and 'REMOTEPORT' are available. -ReplayWindow = (32) +ReplayWindow = (16) This is the size of the replay tracking window for each remote node, in bytes. The window is a bitfield which tracks 1 packet per - bit, so for example the default setting of 32 will track up to 256 + bit, so for example the default setting of 16 will track up to 128 packets in the window. In high bandwidth scenarios, setting this to a higher value can reduce packet loss from the interaction of replay tracking with underlying real packet loss and/or reordering. @@ -1157,63 +1029,15 @@ TunnelServer = (no) [experimental] '/etc/tinc/NETNAME/hosts/' directory. Setting this options also implicitly sets StrictSubnets. -UDPDiscovery = (yes) - When this option is enabled tinc will try to establish UDP - connectivity to nodes, using TCP while it determines if a node is - reachable over UDP. If it is disabled, tinc always assumes a node - is reachable over UDP. Note that tinc will never use UDP with nodes - that have TCPOnly enabled. - -UDPDiscoveryKeepaliveInterval = (9) - The minimum amount of time between sending UDP ping datagrams to - check UDP connectivity once it has been established. Note that - these pings are large, since they are used to verify link MTU as - well. - -UDPDiscoveryInterval = (2) - The minimum amount of time between sending UDP ping datagrams to - try to establish UDP connectivity. - -UDPDiscoveryTimeout = (30) - If tinc doesn't receive any UDP ping replies over the specified - interval, it will assume UDP communication is broken and will fall - back to TCP. - -UDPInfoInterval = (5) - The minimum amount of time between sending periodic updates about - UDP addresses, which are mostly useful for UDP hole punching. - -UDPRcvBuf = (1048576) +UDPRcvBuf = (OS default) Sets the socket receive buffer size for the UDP socket, in bytes. - If set to zero, the default buffer size will be used by the - operating system. Note: this setting can have a significant impact - on performance, especially raw throughput. + If unset, the default buffer size will be used by the operating + system. -UDPSndBuf = (1048576) +UDPSndBuf = Pq OS default Sets the socket send buffer size for the UDP socket, in bytes. If - set to zero, the default buffer size will be used by the operating - system. Note: this setting can have a significant impact on - performance, especially raw throughput. - -UPnP = (no) - If this option is enabled then tinc will search for UPnP-IGD - devices on the local network. It will then create and maintain - port mappings for tinc's listening TCP and UDP ports. If set to - "udponly", tinc will only create a mapping for its UDP (data) port, - not for its TCP (metaconnection) port. Note that tinc must have - been built with miniupnpc support for this feature to be available. - Furthermore, be advised that enabling this can have security - implications, because the miniupnpc library that tinc uses might - not be well-hardened with regard to malicious UPnP replies. - -UPnPDiscoverWait = (5) - The amount of time to wait for replies when probing the local - network for UPnP devices. - -UPnPRefreshPeriod = (5) - How often tinc will re-add the port mapping, in case it gets reset - on the UPnP device. This also controls the duration of the port - mapping itself, which will be set to twice that duration. + unset, the default buffer size will be used by the operating + system.  File: tinc.info, Node: Host configuration variables, Next: Scripts, Prev: Main configuration variables, Up: Configuration files @@ -1229,13 +1053,11 @@ Address = [] [recommended] can be specified, in which case each address will be tried until a working connection has been established. -Cipher = (blowfish) - The symmetric cipher algorithm used to encrypt UDP packets using - the legacy protocol. Any cipher supported by LibreSSL or OpenSSL - is recognized. Furthermore, specifying "none" will turn off packet - encryption. It is best to use only those ciphers which support CBC - mode. This option has no effect for connections using the SPTPS - protocol, which always use AES-256-CTR. +Cipher = (aes-256-cbc) + The symmetric cipher algorithm used to encrypt UDP packets. Any + cipher supported by LibreSSL or OpenSSL is recognized. + Furthermore, 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 @@ -1246,26 +1068,25 @@ ClampMSS = (yes) 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 - (best zlib), 10 (fast LZO) and 11 (best LZO). + (best zlib), 10 (fast lzo) and 11 (best lzo). -Digest = (sha1) - The digest algorithm used to authenticate UDP packets using the - legacy protocol. Any digest supported by LibreSSL or OpenSSL is - recognized. Furthermore, specifying "none" will turn off packet - authentication. This option has no effect for connections using - the SPTPS protocol, which always use HMAC-SHA-256. +Digest = (sha256) + The digest algorithm used to authenticate UDP packets. Any digest + supported by LibreSSL or OpenSSL is recognized. Furthermore, + specifying "none" will turn off packet authentication. IndirectData = (no) - When set to yes, other nodes which do not already have a meta - connection to you will not try to establish direct communication - with you. It is best to leave this option out or set it to no. + This option specifies whether other tinc daemons besides the one + you specified with ConnectTo can make a direct connection to you. + This is especially useful if you are behind a firewall and it is + impossible to make a connection from the outside to your tinc + daemon. Otherwise, it is best to leave this option out or set it + to no. MACLength = (4) The length of the message authentication code used to authenticate - UDP packets using the legacy protocol. Can be anything from 0 up - to the length of the digest produced by the digest algorithm. This - option has no effect for connections using the SPTPS protocol, - which never truncate MACs. + UDP packets. Can be anything from 0 up to the length of the digest + produced by the digest algorithm. PMTU = (1514) This option controls the initial path MTU to this node. @@ -1275,11 +1096,6 @@ PMTUDiscovery = (yes) to this node. After the path MTU has been discovered, it will be enforced on the VPN. -MTUInfoInterval = (5) - The minimum amount of time between sending periodic updates about - relay path MTU. Useful for quickly determining MTU to indirect - nodes. - Port = (655) This is the port this tinc daemon listens on. You can use decimal portnumbers or symbolic names (as listed in '/etc/services'). @@ -1289,8 +1105,8 @@ PublicKey = [obsolete] PublicKeyFile = [obsolete] This is the full path name of the RSA public key file that was - generated by 'tinc generate-keys'. It must be a full path, not a - relative directory. + generated by 'tincd --generate-keys'. It must be a full path, not + a relative directory. From version 1.0pre4 on tinc will store the public key directly into the host configuration file in PEM format, the above two @@ -1328,18 +1144,15 @@ Subnet = reachable, in which case the node with the next highest priority will be tried, and so on. -TCPonly = (no) +TCPonly = (no) [deprecated] If this variable is set to yes, then the packets are tunnelled over a TCP connection instead of a UDP connection. This is especially useful for those who want to run a tinc daemon from behind a masquerading firewall, or if UDP packet routing is disabled somehow. Setting this options also implicitly sets IndirectData. -Weight = - If this variable is set, it overrides the weight given to - connections made with another host. A higher weight means a lower - priority is given to this connection when broadcasting or - forwarding packets. + Since version 1.0.10, tinc will automatically detect whether + communication via UDP is possible or not.  File: tinc.info, Node: Scripts, Next: How to configure, Prev: Host configuration variables, Up: Configuration files @@ -1352,14 +1165,13 @@ also run scripts at certain moments. Below is a list of filenames of scripts and a description of when they are run. A script is only run if it exists and if it is executable. -Scripts are run synchronously; this means that tinc will temporarily + Scripts are run synchronously; this means that tinc will temporarily stop processing packets until the called script finishes executing. This guarantees that scripts will execute in the exact same order as the events that trigger them. If you need to run commands asynchronously, you have to ensure yourself that they are being run in the background. -Under Windows (not Cygwin), the scripts should have the extension '.bat' -or '.cmd'. + Under Windows (not Cygwin), the scripts must have the extension .bat. '/etc/tinc/NETNAME/tinc-up' This is the most important script. If it is present it will be @@ -1389,23 +1201,16 @@ or '.cmd'. This script is started when any host becomes unreachable. '/etc/tinc/NETNAME/subnet-up' - This script is started when a Subnet becomes reachable. The Subnet + This script is started when a subnet becomes reachable. The Subnet and the node it belongs to are passed in environment variables. '/etc/tinc/NETNAME/subnet-down' - This script is started when a Subnet becomes unreachable. + This script is started when a subnet becomes unreachable. -'/etc/tinc/NETNAME/invitation-created' - This script is started when a new invitation has been created. - -'/etc/tinc/NETNAME/invitation-accepted' - This script is started when an invitation has been used. - -The scripts are started without command line arguments, but can make use -of certain environment variables. Under UNIX like operating systems the -names of environment variables must be preceded by a $ in scripts. -Under Windows, in '.bat' or '.cmd' files, they have to be put between % -signs. + The scripts are started without command line arguments, but can make +use of certain environment variables. Under UNIX like operating systems +the names of environment variables must be preceded by a $ in scripts. +Under Windows, in '.bat' files, they have to be put between % signs. 'NETNAME' If a netname was specified, this environment variable contains it. @@ -1439,162 +1244,95 @@ signs. When a subnet becomes (un)reachable, this is set to the subnet weight. -'INVITATION_FILE' - When the 'invitation-created' script is called, this is set to the - file where the invitation details will be stored. - -'INVITATION_URL' - When the 'invitation-created' script is called, this is set to the - invitation URL that has been created. - -Do not forget that under UNIX operating systems, you have to make the -scripts executable, using the command 'chmod a+x script'. -  File: tinc.info, Node: How to configure, Prev: Scripts, Up: Configuration files 4.4.4 How to configure ---------------------- -Step 1. Creating initial configuration files. -............................................. - -The initial directory structure, configuration files and public/private -keypairs are created using the following command: - - tinc -n NETNAME init NAME - -(You will need to run this as root, or use "sudo".) This will create -the configuration directory '/etc/tinc/NETNAME.', and inside it will -create another directory named 'hosts/'. In the configuration -directory, it will create the file 'tinc.conf' with the following -contents: - - Name = NAME - -It will also create private RSA and Ed25519 keys, which will be stored -in the files 'rsa_key.priv' and 'ed25519_key.priv'. It will also create -a host configuration file 'hosts/NAME', which will contain the -corresponding public RSA and Ed25519 keys. - -Finally, on UNIX operating systems, it will create an executable script -'tinc-up', which will initially not do anything except warning that you -should edit it. - -Step 2. Modifying the initial configuration. +Step 1. Creating the main configuration file ............................................ -Unless you want to use tinc in switch mode, you should now configure -which range of addresses you will use on the VPN. Let's assume you will -be part of a VPN which uses the address range 192.168.0.0/16, and you -yourself have a smaller portion of that range: 192.168.2.0/24. Then you -should run the following command: +The main configuration file will be called +'/etc/tinc/NETNAME/tinc.conf'. Adapt the following example to create a +basic configuration file: - tinc -n NETNAME add subnet 192.168.2.0/24 + Name = YOURNAME + Device = /dev/tap0 -This will add a Subnet statement to your host configuration file. Try -opening the file '/etc/tinc/NETNAME/hosts/NAME' in an editor. You -should now see a file containing the public RSA and Ed25519 keys (which -looks like a bunch of random characters), and the following line at the -bottom: + Then, if you know to which other tinc daemon(s) yours is going to +connect, add 'ConnectTo' values. - Subnet = 192.168.2.0/24 +Step 2. Creating your host configuration file +............................................. -If you will use more than one address range, you can add more Subnets. -For example, if you also use the IPv6 subnet fec0:0:0:2::/64, you can -add it as well: +If you added a line containing 'Name = yourname' in the main +configuration file, you will need to create a host configuration file +'/etc/tinc/NETNAME/hosts/yourname'. Adapt the following example to +create a host configuration file: - tinc -n NETNAME add subnet fec0:0:0:2::/24 + Address = your.real.hostname.org + Subnet = 192.168.1.0/24 -This will add another line to the file 'hosts/NAME'. If you make a -mistake, you can undo it by simply using 'del' instead of 'add'. - -If you want other tinc daemons to create meta-connections to your -daemon, you should add your public IP address or hostname to your host -configuration file. For example, if your hostname is foo.example.org, -run: - - tinc -n NETNAME add address foo.example.org - -Step 2. Exchanging configuration files. -....................................... - -In order for two tinc daemons to be able to connect to each other, they -each need the other's host configuration files. So if you want foo to -be able to connect with bar, You should send 'hosts/NAME' to bar, and -bar should send you his file which you should move to 'hosts/bar'. If -you are on a UNIX platform, you can easily send an email containing the -necessary information using the following command (assuming the owner of -bar has the email address bar@example.org): - - tinc -n NETNAME export | mail -s "My config file" bar@example.org - -If the owner of bar does the same to send his host configuration file to -you, you can probably pipe his email through the following command, or -you can just start this command in a terminal and copy&paste the email: - - tinc -n NETNAME import - -If you are the owner of bar yourself, and you have SSH access to that -computer, you can also swap the host configuration files using the -following command: - - tinc -n NETNAME export \ - | ssh bar.example.org tinc -n NETNAME exchange \ - | tinc -n NETNAME import - -You can repeat this for a few other nodes as well. It is not necessary -to manually exchange host config files between all nodes; after the -initial connections are made tinc will learn about all the other nodes -in the VPN, and will automatically make other connections as necessary. + You can also use an IP address instead of a hostname. The 'Subnet' +specifies the address range that is local for _your part of the VPN +only_. If you have multiple address ranges you can specify more than +one 'Subnet'. You might also need to add a 'Port' if you want your tinc +daemon to run on a different port number than the default (655).  -File: tinc.info, Node: Network interfaces, Next: Example configuration, Prev: Configuration files, Up: Configuration +File: tinc.info, Node: Generating keypairs, Next: Network interfaces, Prev: Configuration files, Up: Configuration -4.5 Network interfaces +4.5 Generating keypairs +======================= + +Now that you have already created the main configuration file and your +host configuration file, you can easily create a public/private keypair +by entering the following command: + + tincd -n NETNAME -K + + Tinc will generate a public and a private key and ask you where to +put them. Just press enter to accept the defaults. + + +File: tinc.info, Node: Network interfaces, Next: Example configuration, Prev: Generating keypairs, Up: Configuration + +4.6 Network interfaces ====================== Before tinc can start transmitting data over the tunnel, it must set up the virtual network interface. -First, decide which IP addresses you want to have associated with these -devices, and what network mask they must have. + First, decide which IP addresses you want to have associated with +these devices, and what network mask they must have. -Tinc will open a virtual network device ('/dev/tun', '/dev/tap0' or + Tinc will open a virtual network device ('/dev/tun', '/dev/tap0' or similar), which will also create a network interface called something like 'tun0', 'tap0'. If you are using the Linux tun/tap driver, the network interface will by default have the same name as the NETNAME. Under Windows you can change the name of the network interface from the Network Connections control panel. -You can configure the network interface by putting ordinary ifconfig, + You can configure the network interface by putting ordinary ifconfig, route, and other commands to a script named '/etc/tinc/NETNAME/tinc-up'. When tinc starts, this script will be executed. When tinc exits, it will execute the script named '/etc/tinc/NETNAME/tinc-down', but -normally you don't need to create that script. You can manually open -the script in an editor, or use the following command: +normally you don't need to create that script. - tinc -n NETNAME edit tinc-up - -An example 'tinc-up' script, that would be appropriate for the scenario -in the previous section, is: + An example 'tinc-up' script: #!/bin/sh - ifconfig $INTERFACE 192.168.2.1 netmask 255.255.0.0 - ip addr add fec0:0:0:2::/48 dev $INTERFACE + ifconfig $INTERFACE 192.168.1.1 netmask 255.255.0.0 -The first command gives the interface an IPv4 address and a netmask. -The kernel will also automatically add an IPv4 route to this interface, -so normally you don't need to add route commands to the 'tinc-up' -script. The kernel will also bring the interface up after this command. -The netmask is the mask of the _entire_ VPN network, not just your own -subnet. The second command gives the interface an IPv6 address and -netmask, which will also automatically add an IPv6 route. If you only -want to use "ip addr" commands on Linux, don't forget that it doesn't -bring the interface up, unlike ifconfig, so you need to add 'ip link set -$INTERFACE up' in that case. + This script gives the interface an IP address and a netmask. The +kernel will also automatically add a route to this interface, so +normally you don't need to add route commands to the 'tinc-up' script. +The kernel will also bring the interface up after this command. The +netmask is the mask of the _entire_ VPN network, not just your own +subnet. -The exact syntax of the ifconfig and route commands differs from + The exact syntax of the ifconfig and route commands differs from platform to platform. You can look up the commands for setting addresses and adding routes in *note Platform specific information::, but it is best to consult the manpages of those utilities on your @@ -1603,56 +1341,52 @@ platform.  File: tinc.info, Node: Example configuration, Prev: Network interfaces, Up: Configuration -4.6 Example configuration +4.7 Example configuration ========================= Imagine the following situation. Branch A of our example 'company' wants to connect three branch offices in B, C and D using the Internet. All four offices have a 24/7 connection to the Internet. -A is going to serve as the center of the network. B and C will connect -to A, and D will connect to C. Each office will be assigned their own IP -network, 10.x.0.0. + A is going to serve as the center of the network. B and C will +connect to A, and D will connect to C. Each office will be assigned +their own IP network, 10.x.0.0. A: net 10.1.0.0 mask 255.255.0.0 gateway 10.1.54.1 internet IP 1.2.3.4 B: net 10.2.0.0 mask 255.255.0.0 gateway 10.2.1.12 internet IP 2.3.4.5 C: net 10.3.0.0 mask 255.255.0.0 gateway 10.3.69.254 internet IP 3.4.5.6 D: net 10.4.0.0 mask 255.255.0.0 gateway 10.4.3.32 internet IP 4.5.6.7 -Here, "gateway" is the VPN IP address of the machine that is running the -tincd, and "internet IP" is the IP address of the firewall, which does -not need to run tincd, but it must do a port forwarding of TCP and UDP -on port 655 (unless otherwise configured). + Here, "gateway" is the VPN IP address of the machine that is running +the tincd, and "internet IP" is the IP address of the firewall, which +does not need to run tincd, but it must do a port forwarding of TCP and +UDP on port 655 (unless otherwise configured). -In this example, it is assumed that eth0 is the interface that points to -the inner (physical) LAN of the office, although this could also be the -same as the interface that leads to the Internet. The configuration of -the real interface is also shown as a comment, to give you an idea of + In this example, it is assumed that eth0 is the interface that points +to the inner (physical) LAN of the office, although this could also be +the same as the interface that leads to the Internet. The configuration +of the real interface is also shown as a comment, to give you an idea of how these example host is set up. All branches use the netname 'company' for this particular VPN. -Each branch is set up using the 'tinc init' and 'tinc config' commands, -here we just show the end results: - For Branch A ............ _BranchA_ would be configured like this: -In '/etc/tinc/company/tinc-up': - - #!/bin/sh + In '/etc/tinc/company/tinc-up': # Real interface of internal network: # ifconfig eth0 10.1.54.1 netmask 255.255.0.0 ifconfig $INTERFACE 10.1.54.1 netmask 255.0.0.0 -and in '/etc/tinc/company/tinc.conf': + and in '/etc/tinc/company/tinc.conf': Name = BranchA + Device = /dev/tap0 -On all hosts, '/etc/tinc/company/hosts/BranchA' contains: + On all hosts, '/etc/tinc/company/hosts/BranchA' contains: Subnet = 10.1.0.0/16 Address = 1.2.3.4 @@ -1661,32 +1395,32 @@ On all hosts, '/etc/tinc/company/hosts/BranchA' contains: ... -----END RSA PUBLIC KEY----- -Note that the IP addresses of eth0 and the VPN interface 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 both real -internal network interfaces and VPN interfaces the same IP address, -since that will make things a lot easier to remember and set up. + 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 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 ............ In '/etc/tinc/company/tinc-up': - #!/bin/sh - # Real interface of internal network: # ifconfig eth0 10.2.43.8 netmask 255.255.0.0 ifconfig $INTERFACE 10.2.1.12 netmask 255.0.0.0 -and in '/etc/tinc/company/tinc.conf': + and in '/etc/tinc/company/tinc.conf': Name = BranchB + ConnectTo = BranchA -Note here that the internal address (on eth0) doesn't have to be the -same as on the VPN interface. + 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 this node +will always try to connect to BranchA. -On all hosts, in '/etc/tinc/company/hosts/BranchB': + On all hosts, in '/etc/tinc/company/hosts/BranchB': Subnet = 10.2.0.0/16 Address = 2.3.4.5 @@ -1700,22 +1434,22 @@ For Branch C In '/etc/tinc/company/tinc-up': - #!/bin/sh - # Real interface of internal network: # ifconfig eth0 10.3.69.254 netmask 255.255.0.0 ifconfig $INTERFACE 10.3.69.254 netmask 255.0.0.0 -and in '/etc/tinc/company/tinc.conf': + and in '/etc/tinc/company/tinc.conf': Name = BranchC + ConnectTo = BranchA + Device = /dev/tap1 -C already has another daemon that runs on port 655, so they have to + C already has another daemon that runs on port 655, so they have to reserve another port for tinc. It knows the portnumber it has to listen on from it's own host configuration file. -On all hosts, in '/etc/tinc/company/hosts/BranchC': + On all hosts, in '/etc/tinc/company/hosts/BranchC': Address = 3.4.5.6 Subnet = 10.3.0.0/16 @@ -1730,21 +1464,24 @@ For Branch D In '/etc/tinc/company/tinc-up': - #!/bin/sh - # Real interface of internal network: # ifconfig eth0 10.4.3.32 netmask 255.255.0.0 ifconfig $INTERFACE 10.4.3.32 netmask 255.0.0.0 -and in '/etc/tinc/company/tinc.conf': + and in '/etc/tinc/company/tinc.conf': Name = BranchD + ConnectTo = BranchC + Device = /dev/net/tun -D will be connecting to C, which has a tincd running for this network on -port 2000. It knows the port number from the host configuration file. + D will be connecting to C, which has a tincd running for this network +on port 2000. It knows the port number from the host configuration +file. Also note that since D uses the tun/tap driver, the network +interface will not be called 'tun' or 'tap0' or something like that, but +will have the same name as netname. -On all hosts, in '/etc/tinc/company/hosts/BranchD': + On all hosts, in '/etc/tinc/company/hosts/BranchD': Subnet = 10.4.0.0/16 Address = 4.5.6.7 @@ -1756,12 +1493,16 @@ On all hosts, in '/etc/tinc/company/hosts/BranchD': Key files ......... -A, B, C and D all have their own public/private keypairs: +A, B, C and D all have generated a public/private keypair with the +following command: -The private RSA key is stored in '/etc/tinc/company/rsa_key.priv', the -private Ed25519 key is stored in '/etc/tinc/company/ed25519_key.priv', -and the public RSA and Ed25519 keys are put into the host configuration -file in the '/etc/tinc/company/hosts/' directory. + tincd -n company -K + + The private key is stored in '/etc/tinc/company/rsa_key.priv', the +public key is put into the host configuration file in the +'/etc/tinc/company/hosts/' directory. During key generation, tinc +automatically guesses the right filenames based on the -n option and the +Name directive in the 'tinc.conf' file (if it is available). Starting ........ @@ -1773,7 +1514,7 @@ have started their daemons, tinc will try connecting until they are available.  -File: tinc.info, Node: Running tinc, Next: Controlling tinc, Prev: Configuration, Up: Top +File: tinc.info, Node: Running tinc, Next: Technical information, Prev: Configuration, Up: Top 5 Running tinc ************** @@ -1781,12 +1522,12 @@ File: tinc.info, Node: Running tinc, Next: Controlling tinc, Prev: Configurat If everything else is done, you can start tinc by typing the following command: - tinc -n NETNAME start + tincd -n NETNAME -Tinc will detach from the terminal and continue to run in the background -like a good daemon. If there are any problems however you can try to -increase the debug level and look in the syslog to find out what the -problems are. + Tinc will detach from the terminal and continue to run in the +background like a good daemon. If there are any problems however you +can try to increase the debug level and look in the syslog to find out +what the problems are. * Menu: @@ -1818,15 +1559,25 @@ command line options. Set debug level to LEVEL. The higher the debug level, the more gets logged. Everything goes via syslog. +'-k, --kill[=SIGNAL]' + Attempt to kill a running tincd (optionally with the specified + SIGNAL instead of SIGTERM) and exit. Use it in conjunction with + the -n option to make sure you kill the right tinc daemon. Under + native Windows the optional argument is ignored, the service will + always be stopped and removed. + '-n, --net=NETNAME' Use configuration for net NETNAME. This will let tinc read all configuration files from '/etc/tinc/NETNAME/'. Specifying . for NETNAME is the same as not specifying any NETNAME. *Note Multiple networks::. -'--pidfile=FILENAME' - Store a cookie in FILENAME which allows tinc to authenticate. If - unspecified, the default is '/var/run/tinc.NETNAME.pid'. +'-K, --generate-keys[=BITS]' + Generate public/private keypair of BITS length. If BITS is not + specified, 2048 is the default. tinc will ask where you want to + store the files, but will default to the configuration directory + (you can use the -c or -n option in combination with -K). After + that, tinc will quit. '-o, --option=[HOST.]KEY=VALUE' Without specifying a HOST, this will set server configuration @@ -1840,8 +1591,6 @@ command line options. shared private keys to be written to the system swap files/partitions. - This option is not supported on all platforms. - '--logfile[=FILE]' Write log entries to a file instead of to the system logging facility. If FILE is omitted, the default is @@ -1871,14 +1620,11 @@ command line options. you must ensure the appropriate shell is also installed in the chroot, along with all its dependencies. - This option is not supported on all platforms. '-U, --user=USER' Switch to the given USER after initialization, at the same time as chroot is performed (see -chroot above). With this option tinc drops privileges, for added security. - This option is not supported on all platforms. - '--help' Display a short reminder of these runtime options and terminate. @@ -1907,6 +1653,20 @@ You can also send the following signals to a running tincd process: used, this will also close and reopen the log file, useful when log rotation is used. +'INT' + Temporarily increases debug level to 5. Send this signal again to + revert to the original level. + +'USR1' + Dumps the connection list to syslog. + +'USR2' + Dumps virtual network device statistics, all known nodes, edges and + subnets to syslog. + +'WINCH' + Purges all information remembered about unreachable nodes. +  File: tinc.info, Node: Debug levels, Next: Solving problems, Prev: Signals, Up: Running tinc @@ -1953,7 +1713,7 @@ directly see everything tinc logs: tincd -n NETNAME -d5 -D -If tinc does not log any error messages, then you might want to check + If tinc does not log any error messages, then you might want to check the following things: * 'tinc-up' script Does this script contain the right commands? @@ -1972,7 +1732,9 @@ the following things: it, make sure that it forwards TCP and UDP traffic to port 655 to the host running tinc. You can add 'TCPOnly = yes' to your host config file to force tinc to only use a single TCP connection, this - works through most firewalls and NATs. + works through most firewalls and NATs. Since version 1.0.10, tinc + will automatically fall back to TCP if direct communication via UDP + is not possible.  File: tinc.info, Node: Error messages, Next: Sending bug reports, Prev: Solving problems, Up: Running tinc @@ -2063,11 +1825,6 @@ high enough. * If you see this only sporadically, it is harmless and caused by a node sending packets using an old key. - * If you see this often and another node is not reachable - anymore, then a NAT (masquerading firewall) is changing the - source address of UDP packets. You can add 'TCPOnly = yes' to - host configuration files to force all VPN traffic to go over a - TCP connection. 'Got bad/bogus/unauthorized REQUEST from foo (1.2.3.4 port 12345)' @@ -2101,508 +1858,9 @@ bugreport: ping or traceroute).  -File: tinc.info, Node: Controlling tinc, Next: Invitations, Prev: Running tinc, Up: Top +File: tinc.info, Node: Technical information, Next: Platform specific information, Prev: Running tinc, Up: Top -6 Controlling tinc -****************** - -You can start, stop, control and inspect a running tincd through the -tinc command. A quick example: - - tinc -n NETNAME reload - -If tinc is started without a command, it will act as a shell; it will -display a prompt, and commands can be entered on the prompt. If tinc is -compiled with libreadline, history and command completion are available -on the prompt. One can also pipe a script containing commands through -tinc. In that case, lines starting with a # symbol will be ignored. - -* Menu: - -* tinc runtime options:: -* tinc environment variables:: -* tinc commands:: -* tinc examples:: -* tinc top:: - - -File: tinc.info, Node: tinc runtime options, Next: tinc environment variables, Up: Controlling tinc - -6.1 tinc runtime options -======================== - -'-c, --config=PATH' - Read configuration options from the directory PATH. The default is - '/etc/tinc/NETNAME/'. - -'-n, --net=NETNAME' - Use configuration for net NETNAME. *Note Multiple networks::. - -'--pidfile=FILENAME' - Use the cookie from FILENAME to authenticate with a running tinc - daemon. If unspecified, the default is - '/var/run/tinc.NETNAME.pid'. - -'-b, --batch' - Don't ask for anything (non-interactive mode). - -'--force' - Force some commands to work despite warnings. - -'--help' - Display a short reminder of runtime options and commands, then - terminate. - -'--version' - Output version information and exit. - - -File: tinc.info, Node: tinc environment variables, Next: tinc commands, Prev: tinc runtime options, Up: Controlling tinc - -6.2 tinc environment variables -============================== - -'NETNAME' - If no netname is specified on the command line with the '-n' - option, the value of this environment variable is used. - - -File: tinc.info, Node: tinc commands, Next: tinc examples, Prev: tinc environment variables, Up: Controlling tinc - -6.3 tinc commands -================= - -'init [NAME]' - Create initial configuration files and RSA and Ed25519 keypairs - with default length. If no NAME for this node is given, it will be - asked for. - -'get VARIABLE' - Print the current value of configuration variable VARIABLE. If - more than one variable with the same name exists, the value of each - of them will be printed on a separate line. - -'set VARIABLE VALUE' - Set configuration variable VARIABLE to the given VALUE. All - previously existing configuration variables with the same name are - removed. To set a variable for a specific host, use the notation - HOST.VARIABLE. - -'add VARIABLE VALUE' - As above, but without removing any previously existing - configuration variables. If the variable already exists with the - given value, nothing happens. - -'del VARIABLE [VALUE]' - Remove configuration variables with the same name and VALUE. If no - VALUE is given, all configuration variables with the same name will - be removed. - -'edit FILENAME' - Start an editor for the given configuration file. You do not need - to specify the full path to the file. - -'export' - Export the host configuration file of the local node to standard - output. - -'export-all' - Export all host configuration files to standard output. - -'import' - Import host configuration file(s) generated by the tinc export - command from standard input. Already existing host configuration - files are not overwritten unless the option -force is used. - -'exchange' - The same as export followed by import. - -'exchange-all' - The same as export-all followed by import. - -'invite NAME' - Prepares an invitation for a new node with the given NAME, and - prints a short invitation URL that can be used with the join - command. - -'join [URL]' - Join an existing VPN using an invitation URL created using the - invite command. If no URL is given, it will be read from standard - input. - -'start [tincd options]' - Start 'tincd', optionally with the given extra options. - -'stop' - Stop 'tincd'. - -'restart [tincd options]' - Restart 'tincd', optionally with the given extra options. - -'reload' - Partially rereads configuration files. Connections to hosts whose - host config files are removed are closed. New outgoing connections - specified in 'tinc.conf' will be made. - -'pid' - Shows the PID of the currently running 'tincd'. - -'generate-keys [BITS]' - Generate both RSA and Ed25519 keypairs (see below) and exit. tinc - will ask where you want to store the files, but will default to the - configuration directory (you can use the -c or -n option). - -'generate-ed25519-keys' - Generate public/private Ed25519 keypair and exit. - -'generate-rsa-keys [BITS]' - Generate public/private RSA keypair and exit. If BITS is omitted, - the default length will be 2048 bits. When saving keys to existing - files, tinc will not delete the old keys; you have to remove them - manually. - -'dump [reachable] nodes' - Dump a list of all known nodes in the VPN. If the reachable keyword - is used, only lists reachable nodes. - -'dump edges' - Dump a list of all known connections in the VPN. - -'dump subnets' - Dump a list of all known subnets in the VPN. - -'dump connections' - Dump a list of all meta connections with ourself. - -'dump graph | digraph' - Dump a graph of the VPN in dotty format. Nodes are colored - according to their reachability: red nodes are unreachable, orange - nodes are indirectly reachable, green nodes are directly reachable. - Black nodes are either directly or indirectly reachable, but direct - reachability has not been tried yet. - -'dump invitations' - Dump a list of outstanding invitations. The filename of the - invitation, as well as the name of the node that is being invited - is shown for each invitation. - -'info NODE | SUBNET | ADDRESS' - Show information about a particular NODE, SUBNET or ADDRESS. If an - ADDRESS is given, any matching subnet will be shown. - -'purge' - Purges all information remembered about unreachable nodes. - -'debug LEVEL' - Sets debug level to LEVEL. - -'log [LEVEL]' - Capture log messages from a running tinc daemon. An optional debug - level can be given that will be applied only for log messages sent - to tinc. - -'retry' - Forces tinc to try to connect to all uplinks immediately. Usually - tinc attempts to do this itself, but increases the time it waits - between the attempts each time it failed, and if tinc didn't - succeed to connect to an uplink the first time after it started, it - defaults to the maximum time of 15 minutes. - -'disconnect NODE' - Closes the meta connection with the given NODE. - -'top' - If tinc is compiled with libcurses support, this will display live - traffic statistics for all the known nodes, similar to the UNIX top - command. See below for more information. - -'pcap' - Dump VPN traffic going through the local tinc node in pcap-savefile - format to standard output, from where it can be redirected to a - file or piped through a program that can parse it directly, such as - tcpdump. - -'network [NETNAME]' - If NETNAME is given, switch to that network. Otherwise, display a - list of all networks for which configuration files exist. - -'fsck' - This will check the configuration files for possible problems, such - as unsafe file permissions, missing executable bit on script, - unknown and obsolete configuration variables, wrong public and/or - private keys, and so on. - - When problems are found, this will be printed on a line with - WARNING or ERROR in front of it. Most problems must be corrected - by the user itself, however in some cases (like file permissions - and missing public keys), tinc will ask if it should fix the - problem. - -'sign [FILENAME]' - Sign a file with the local node's private key. If no FILENAME is - given, the file is read from standard input. The signed file is - written to standard output. - -'verify NAME [FILENAME]' - - Check the signature of a file against a node's public key. The - NAME of the node must be given, or can be "." to check against the - local node's public key, or "*" to allow a signature from any node - whose public key is known. If no FILENAME is given, the file is - read from standard input. If the verification is successful, a - copy of the input with the signature removed is written to standard - output, and the exit code will be zero. If the verification - failed, nothing will be written to standard output, and the exit - code will be non-zero. - - -File: tinc.info, Node: tinc examples, Next: tinc top, Prev: tinc commands, Up: Controlling tinc - -6.4 tinc examples -================= - -Examples of some commands: - - tinc -n vpn dump graph | circo -Txlib - tinc -n vpn pcap | tcpdump -r - - tinc -n vpn top - -Examples of changing the configuration using tinc: - - tinc -n vpn init foo - tinc -n vpn add Subnet 192.168.1.0/24 - tinc -n vpn add bar.Address bar.example.com - tinc -n vpn set Mode switch - tinc -n vpn export | gpg --clearsign | mail -s "My config" vpnmaster@example.com - - -File: tinc.info, Node: tinc top, Prev: tinc examples, Up: Controlling tinc - -6.5 tinc top -============ - -The top command connects to a running tinc daemon and repeatedly queries -its per-node traffic counters. It displays a list of all the known -nodes in the left-most column, and the amount of bytes and packets read -from and sent to each node in the other columns. By default, the -information is updated every second. The behaviour of the top command -can be changed using the following keys: - - - Change the interval between updates. After pressing the key, - enter the desired interval in seconds, followed by enter. - Fractional seconds are honored. Intervals lower than 0.1 seconds - are not allowed. - - - Toggle between displaying current traffic rates (in packets and - bytes per second) and cumulative traffic (total packets and bytes - since the tinc daemon started). - - - Sort the list of nodes by name. - - - Sort the list of nodes by incoming amount of bytes. - - - Sort the list of nodes by incoming amount of packets. - - - Sort the list of nodes by outgoing amount of bytes. - - - Sort the list of nodes by outgoing amount of packets. - - - Sort the list of nodes by sum of incoming and outgoing amount of - bytes. - - - Sort the list of nodes by sum of incoming and outgoing amount of - packets. - - - Show amount of traffic in bytes. - - - Show amount of traffic in kilobytes. - - - Show amount of traffic in megabytes. - - - Show amount of traffic in gigabytes. - - - Quit. - - -File: tinc.info, Node: Invitations, Next: Technical information, Prev: Controlling tinc, Up: Top - -7 Invitations -************* - -Invitations are an easy way to add new nodes to an existing VPN. -Invitations can be created on an existing node using the 'tinc invite' -command, which generates a relatively short URL which can be given to -someone else, who uses the 'tinc join' command to automatically set up -tinc so it can connect to the inviting node. The next sections describe -how invitations actually work, and how to further automate the -invitations. - -* Menu: - -* How invitations work:: -* Invitation file format:: -* Writing an invitation-created script:: - - -File: tinc.info, Node: How invitations work, Next: Invitation file format, Up: Invitations - -7.1 How invitations work -======================== - -When an invitation is created on a node (which from now on we will call -the server) using the 'tinc invite' command, an invitation file is -created that contains all the information necessary for the invitee -(which we will call the client) to create its configuration files. The -invitation file is stays on the server, but a URL is generated that has -enough information for the client to contact the server and to retrieve -the invitation file. The whole URL is around 80 characters long and -looks like this: - - server.example.org:12345/cW1NhLHS-1WPFlcFio8ztYHvewTTKYZp8BjEKg3vbMtDz7w4 - -It is composed of four parts: - - hostname : port / keyhash cookie - -The hostname and port tell the client how to reach the tinc daemon on -the server. The part after the slash looks like one blob, but is -composed of two parts. The keyhash is the hash of the public key of the -server. The cookie is a shared secret that identifies the client to the -server. - -When the client connects to the server in order to join the VPN, the -client and server will exchange temporary public keys. The client -verifies that the hash of the server's public key matches the keyhash -from the invitation URL. If not, it will immediately exit with an error. -Otherwise, an ECDH exchange will happen so the client and server can -communicate privately with each other. The client will then present the -cookie to the server. The server uses this to look up the corresponding -invitation file it generated earlier. If it exists, it will send the -invitation file to the client. The client will also create a permanent -public key, and send it to the server. After the exchange is completed, -the connection is broken. The server creates a host config file for the -client containing the client's permanent public key, and the client -creates tinc.conf, host config files and possibly a tinc-up script based -on the information in the invitation file. - -It is important that the invitation URL is kept secret until it is used; -if another person gets a copy of the invitation URL before the real -client runs the 'tinc join' command, then that other person can try to -join the VPN. - - -File: tinc.info, Node: Invitation file format, Next: Writing an invitation-created script, Prev: How invitations work, Up: Invitations - -7.2 Invitation file format -========================== - -The contents of an invitation file that is generated by the 'tinc -invite' command looks like this: - - Name = client - Netname = vpn - ConnectTo = server - #-------------------------------------# - Name = server - Ed25519PublicKey = augbnwegoij123587... - Address = server.example.com - -The file is basically a concatenation of several host config blocks. -Each host config block starts with 'Name = ...'. Lines that look like -'#---#' are not important, it just makes it easier for humans to read -the file. However, the first line of an invitation file _must_ always -start with 'Name = ...'. - -The first host config block is always the one representing the invitee. -So the first Name statement determines the name that the invitee will -get. From the first block, the 'tinc.conf' and 'hosts/client' files -will be generated; the 'tinc join' command on the client will -automatically separate statements based on whether they should be in -'tinc.conf' or in a host config file. Some statements are special and -are treated differently: - -Netname = - This is a hint to the invitee which netname to use for the VPN. It - is used if the invitee did not already specify a netname, and if - there is no pre-existing configuration with the same netname. - -Ifconfig = - This is a hint for generating a 'tinc-up' script. If an address is - specified, a command will be added to 'tinc-up' so the VPN - interface will be configured to have the given address. If it is - the word "dhcp", a command will be added to start a DHCP client on - the VPN interface. If it is the word dhcpv6, it will be a DHCPv6 - client. If it is "slaac", then it will add commands to enable IPv6 - stateless address autoconfiguration. It is also possible to - specify a MAC address, in which case a command will be added to set - the MAC address of the VPN interface. - - The exact commands added to the 'tinc-up' script depends on the - operating system the client is using. Multiple Ifconfig statements - can be specified, however one should only use one Ifconfig - statement per address family. - -Route = [] - This is a hint for generating a 'tinc-up' script. Route statements - are similar to Ifconfig statements, but add routes instead of - addresses. These only allow IPv4 and IPv6 routes. If no gateway - address is specified, the route is directed to the VPN interface. - In general, a gateway is only necessary when running tinc in switch - mode. - -Subsequent host config blocks are copied verbatim into their respective -files in 'hosts/'. The invitation file generated by 'tinc invite' will -normally only contain two blocks; one for the client and one for the -server. - - -File: tinc.info, Node: Writing an invitation-created script, Prev: Invitation file format, Up: Invitations - -7.3 Writing an invitation-created script -======================================== - -When an invitation is generated, the "invitation-created" script is -called (if it exists) right after the invitation file is written, but -before the URL has been written to stdout. This allows one to change -the invitation file automatically before the invitation URL is passed to -the invitee. Here is an example shell script that approximately -recreates the default invitation file: - - #!/bin/sh - - cat >$INVITATION_FILE <>$INVITATION_FILE - -You can add more ConnectTo statements, and change 'tinc export' to 'tinc -export-all' for example. But you can also use the script to -automatically hand out a Subnet to the invitee. Note that the script -doesn't have to be a shell script, you can use any language, it just has -to be executable. - - -File: tinc.info, Node: Technical information, Next: Platform specific information, Prev: Invitations, Up: Top - -8 Technical information +6 Technical information *********************** * Menu: @@ -2614,7 +1872,7 @@ File: tinc.info, Node: Technical information, Next: Platform specific informat  File: tinc.info, Node: The connection, Next: The meta-protocol, Up: Technical information -8.1 The connection +6.1 The connection ================== Tinc is a daemon that takes VPN data and transmit that to another host @@ -2628,7 +1886,7 @@ computer over the existing Internet infrastructure.  File: tinc.info, Node: The UDP tunnel, Next: The meta-connection, Up: The connection -8.1.1 The UDP tunnel +6.1.1 The UDP tunnel -------------------- The data itself is read from a character device file, the so-called @@ -2640,43 +1898,43 @@ are point-to-point devices which can only handle IPv4 and/or IPv6 packets, and 'tap' style, which are Ethernet devices and handle complete Ethernet frames. -So when tinc reads an Ethernet frame from the device, it determines its -type. When tinc is in it's default routing mode, it can handle IPv4 and -IPv6 packets. Depending on the Subnet lines, it will send the packets -off to their destination IP address. In the 'switch' and 'hub' mode, -tinc will use broadcasts and MAC address discovery to deduce the + So when tinc reads an Ethernet frame from the device, it determines +its type. When tinc is in its default routing mode, it can handle IPv4 +and IPv6 packets. Depending on the Subnet lines, it will send the +packets off to their destination IP address. In the 'switch' and 'hub' +mode, tinc will use broadcasts and MAC address discovery to deduce the destination of the packets. Since the latter modes only depend on the link layer information, any protocol that runs over Ethernet is supported (for instance IPX and Appletalk). However, only 'tap' style devices provide this information. -After the destination has been determined, the packet will be compressed -(optionally), a sequence number will be added to the packet, the packet -will then be encrypted and a message authentication code will be -appended. + After the destination has been determined, the packet will be +compressed (optionally), a sequence number will be added to the packet, +the packet will then be encrypted and a message authentication code will +be appended. -When that is done, time has come to actually transport the packet to the -destination computer. We do this by sending the packet over an UDP + When that is done, time has come to actually transport the packet to +the destination computer. We do this by sending the packet over an UDP connection to the destination host. This is called _encapsulating_, the VPN packet (though now encrypted) is encapsulated in another IP datagram. -When the destination receives this packet, the same thing happens, only -in reverse. So it checks the message authentication code, decrypts the -contents of the UDP datagram, checks the sequence number and writes the -decrypted information to its own virtual network device. + When the destination receives this packet, the same thing happens, +only in reverse. So it checks the message authentication code, decrypts +the contents of the UDP datagram, checks the sequence number and writes +the decrypted information to its own virtual network device. -If the virtual network device is a 'tun' device (a point-to-point + If the virtual network device is a 'tun' device (a point-to-point tunnel), there is no problem for the kernel to accept a packet. However, if it is a 'tap' device (this is the only available type on FreeBSD), the destination MAC address must match that of the virtual -network interface. If tinc is in it's default routing mode, ARP does -not work, so the correct destination MAC can not be known by the sending +network interface. If tinc is in its default routing mode, ARP does not +work, so the correct destination MAC can not be known by the sending host. Tinc solves this by letting the receiving end detect the MAC address of its own virtual network interface and overwriting the destination MAC address of the received packet. -In switch or hub modes ARP does work so the sender already knows the + In switch or hub modes ARP does work so the sender already knows the correct destination MAC address. In those modes every interface should have a unique MAC address, so make sure they are not the same. Because switch and hub modes rely on MAC addresses to function correctly, these @@ -2686,28 +1944,28 @@ a 'tap' style virtual network device: NetBSD, Darwin and Solaris.  File: tinc.info, Node: The meta-connection, Prev: The UDP tunnel, Up: The connection -8.1.2 The meta-connection +6.1.2 The meta-connection ------------------------- Having only a UDP connection available is not enough. Though suitable for transmitting data, we want to be able to reliably send other information, such as routing and session key information to somebody. -TCP is a better alternative, because it already contains protection + TCP is a better alternative, because it already contains protection against information being lost, unlike UDP. -So we establish two connections. One for the encrypted VPN data, and + So we establish two connections. One for the encrypted VPN data, and one for other information, the meta-data. Hence, we call the second connection the meta-connection. We can now be sure that the meta-information doesn't get lost on the way to another computer. -Like with any communication, we must have a protocol, so that everybody -knows what everything stands for, and how she should react. Because we -have two connections, we also have two protocols. The protocol used for -the UDP data is the "data-protocol," the other one is the -"meta-protocol." + Like with any communication, we must have a protocol, so that +everybody knows what everything stands for, and how she should react. +Because we have two connections, we also have two protocols. The +protocol used for the UDP data is the "data-protocol," the other one is +the "meta-protocol." -The reason we don't use TCP for both protocols is that UDP is much + The reason we don't use TCP for both protocols is that UDP is much better for encapsulation, even while it is less reliable. The real problem is that when TCP would be used to encapsulate a TCP stream that's on the private network, for every packet sent there would be @@ -2718,24 +1976,24 @@ re-sending packets.  File: tinc.info, Node: The meta-protocol, Next: Security, Prev: The connection, Up: Technical information -8.2 The meta-protocol +6.2 The meta-protocol ===================== The meta protocol is used to tie all tinc daemons together, and exchange information about which tinc daemon serves which virtual subnet. -The meta protocol consists of requests that can be sent to the other + The meta protocol consists of requests that can be sent to the other side. Each request has a unique number and several parameters. All requests are represented in the standard ASCII character set. It is possible to use tools such as telnet or netcat to connect to a tinc daemon started with the -bypass-security option and to read and write requests by hand, provided that one understands the numeric codes sent. -The authentication scheme is described in *note Security::. After a -successful authentication, the server and the client will exchange all -the information about other tinc daemons and subnets they know of, so -that both sides (and all the other tinc daemons behind them) have their -information synchronised. + The authentication scheme is described in *note Authentication +protocol::. After a successful authentication, the server and the +client will exchange all the information about other tinc daemons and +subnets they know of, so that both sides (and all the other tinc daemons +behind them) have their information synchronised. message ------------------------------------------------------------------ @@ -2753,13 +2011,13 @@ information synchronised. +------------------> owner of this subnet ------------------------------------------------------------------ -The ADD_EDGE messages are to inform other tinc daemons that a connection -between two nodes exist. The address of the destination node is -available so that VPN packets can be sent directly to that node. + The ADD_EDGE messages are to inform other tinc daemons that a +connection between two nodes exist. The address of the destination node +is available so that VPN packets can be sent directly to that node. -The ADD_SUBNET messages inform other tinc daemons that certain subnets -belong to certain nodes. tinc will use it to determine to which node a -VPN packet has to be sent. + The ADD_SUBNET messages inform other tinc daemons that certain +subnets belong to certain nodes. tinc will use it to determine to which +node a VPN packet has to be sent. message ------------------------------------------------------------------ @@ -2773,10 +2031,10 @@ VPN packet has to be sent. +------------------> owner of this subnet ------------------------------------------------------------------ -In case a connection between two daemons is closed or broken, DEL_EDGE -messages are sent to inform the other daemons of that fact. Each daemon -will calculate a new route to the the daemons, or mark them unreachable -if there isn't any. + In case a connection between two daemons is closed or broken, +DEL_EDGE messages are sent to inform the other daemons of that fact. +Each daemon will calculate a new route to the the daemons, or mark them +unreachable if there isn't any. message ------------------------------------------------------------------ @@ -2796,20 +2054,20 @@ if there isn't any. +--> daemon that has changed it's packet key ------------------------------------------------------------------ -The keys used to encrypt VPN packets are not sent out directly. This is -because it would generate a lot of traffic on VPNs with many daemons, + The keys used to encrypt VPN packets are not sent out directly. This +is because it would generate a lot of traffic on VPNs with many daemons, and chances are that not every tinc daemon will ever send a packet to every other daemon. Instead, if a daemon needs a key it sends a request for it via the meta connection of the nearest hop in the direction of the destination. - daemon message + daemon message ------------------------------------------------------------------ - origin PING - dest. PONG + origin PING + dest. PONG ------------------------------------------------------------------ -There is also a mechanism to check if hosts are still alive. Since + There is also a mechanism to check if hosts are still alive. Since network failures or a crash can cause a daemon to be killed without properly shutting down the TCP connection, this is necessary to keep an up to date connection list. PINGs are sent at regular intervals, except @@ -2818,12 +2076,12 @@ data) is added with each PING and PONG message, to make sure that long sequences of PING/PONG messages without any other traffic won't result in known plaintext. -This basically covers what is sent over the meta connection by tinc. + This basically covers what is sent over the meta connection by tinc.  File: tinc.info, Node: Security, Prev: The meta-protocol, Up: Technical information -8.3 Security +6.3 Security ============ Tinc got its name from "TINC," short for _There Is No Cabal_; the @@ -2831,33 +2089,33 @@ alleged Cabal was/is an organisation that was said to keep an eye on the entire Internet. As this is exactly what you _don't_ want, we named the tinc project after TINC. -But in order to be "immune" to eavesdropping, you'll have to encrypt + But in order to be "immune" to eavesdropping, you'll have to encrypt your data. Because tinc is a _Secure_ VPN (SVPN) daemon, it does -exactly that: encrypt. However, encryption in itself does not prevent -an attacker from modifying the encrypted data. Therefore, tinc also -authenticates the data. Finally, tinc uses sequence numbers (which -themselves are also authenticated) to prevent an attacker from replaying -valid packets. - -Since version 1.1pre3, tinc has two protocols used to protect your data; -the legacy protocol, and the new Simple Peer-to-Peer Security (SPTPS) -protocol. The SPTPS protocol is designed to address some weaknesses in -the legacy protocol. The new authentication protocol is used when two -nodes connect to each other that both have the ExperimentalProtocol -option set to yes, otherwise the legacy protocol will be used. +exactly that: encrypt. Tinc by default uses blowfish encryption with +128 bit keys in CBC mode, 32 bit sequence numbers and 4 byte long +message authentication codes to make sure eavesdroppers cannot get and +cannot change any information at all from the packets they can +intercept. The encryption algorithm and message authentication +algorithm can be changed in the configuration. The length of the +message authentication codes is also adjustable. The length of the key +for the encryption algorithm is always the default length used by +LibreSSL/OpenSSL. * Menu: -* Legacy authentication protocol:: -* Simple Peer-to-Peer Security:: +* Authentication protocol:: * Encryption of network packets:: * Security issues::  -File: tinc.info, Node: Legacy authentication protocol, Next: Simple Peer-to-Peer Security, Up: Security +File: tinc.info, Node: Authentication protocol, Next: Encryption of network packets, Up: Security -8.3.1 Legacy authentication protocol ------------------------------------- +6.3.1 Authentication protocol +----------------------------- + +A new scheme for authentication in tinc has been devised, which offers +some improvements over the protocol used in 1.0pre2 and 1.0pre3. +Explanation is below. daemon message -------------------------------------------------------------------------- @@ -2865,46 +2123,28 @@ File: tinc.info, Node: Legacy authentication protocol, Next: Simple Peer-to-Pe server - client ID client 17.2 - | | +-> minor protocol version - | +----> major protocol version - +--------> name of tinc daemon + client ID client 12 + | +---> version + +-------> name of tinc daemon - server ID server 17.2 - | | +-> minor protocol version - | +----> major protocol version - +--------> name of tinc daemon + server ID server 12 + | +---> version + +-------> name of tinc daemon - client META_KEY 94 64 0 0 5f0823a93e35b69e...7086ec7866ce582b - | | | | \_________________________________/ - | | | | +-> RSAKEYLEN bits totally random string S1, - | | | | encrypted with server's public RSA key - | | | +-> compression level - | | +---> MAC length - | +------> digest algorithm NID - +---------> cipher algorithm NID + client META_KEY 5f0823a93e35b69e...7086ec7866ce582b + \_________________________________/ + +-> RSAKEYLEN bits totally random string S1, + encrypted with server's public RSA key - server META_KEY 94 64 0 0 6ab9c1640388f8f0...45d1a07f8a672630 - | | | | \_________________________________/ - | | | | +-> RSAKEYLEN bits totally random string S2, - | | | | encrypted with client's public RSA key - | | | +-> compression level - | | +---> MAC length - | +------> digest algorithm NID - +---------> cipher algorithm NID - -------------------------------------------------------------------------- + server META_KEY 6ab9c1640388f8f0...45d1a07f8a672630 + \_________________________________/ + +-> RSAKEYLEN bits totally random string S2, + encrypted with client's public RSA key -The protocol allows each side to specify encryption algorithms and -parameters, but in practice they are always fixed, since older versions -of tinc did not allow them to be different from the default values. The -cipher is always Blowfish in OFB mode, the digest is SHA1, but the MAC -length is zero and no compression is used. + From now on: + - the client will symmetrically encrypt outgoing traffic using S1 + - the server will symmetrically encrypt outgoing traffic using S2 -From now on: - * the client will symmetrically encrypt outgoing traffic using S1 - * the server will symmetrically encrypt outgoing traffic using S2 - - -------------------------------------------------------------------------- client CHALLENGE da02add1817c1920989ba6ae2a49cecbda0 \_________________________________/ +-> CHALLEN bits totally random string H1 @@ -2924,204 +2164,74 @@ From now on: client ACK 655 123 0 | | +-> options - | +----> estimated weight - +--------> listening port of client + | +----> estimated weight + +--------> listening port of client server ACK 655 321 0 | | +-> options - | +----> estimated weight - +--------> listening port of server + | +----> estimated weight + +--------> listening port of server -------------------------------------------------------------------------- -This legacy authentication protocol has several weaknesses, pointed out -by security export Peter Gutmann. First, data is encrypted with RSA -without padding. Padding schemes are designed to prevent attacks when -the size of the plaintext is not equal to the size of the RSA key. Tinc -always encrypts random nonces that have the same size as the RSA key, so -we do not believe this leads to a break of the security. There might be -timing or other side-channel attacks against RSA encryption and -decryption, tinc does not employ any protection against those. -Furthermore, both sides send identical messages to each other, there is -no distinction between server and client, which could make a MITM attack -easier. However, no exploit is known in which a third party who is not -already trusted by other nodes in the VPN could gain access. Finally, -the RSA keys are used to directly encrypt the session keys, which means -that if the RSA keys are compromised, it is possible to decrypt all -previous VPN traffic. In other words, the legacy protocol does not -provide perfect forward secrecy. + This new scheme has several improvements, both in efficiency and +security. + + First of all, the server sends exactly the same kind of messages over +the wire as the client. The previous versions of tinc first +authenticated the client, and then the server. This scheme even allows +both sides to send their messages simultaneously, there is no need to +wait for the other to send something first. This means that any +calculations that need to be done upon sending or receiving a message +can also be done in parallel. This is especially important when doing +RSA encryption/decryption. Given that these calculations are the main +part of the CPU time spent for the authentication, speed is improved by +a factor 2. + + Second, only one RSA encrypted message is sent instead of two. This +reduces the amount of information attackers can see (and thus use for a +cryptographic attack). It also improves speed by a factor two, making +the total speedup a factor 4. + + Third, and most important: The symmetric cipher keys are exchanged +first, the challenge is done afterwards. In the previous authentication +scheme, because a man-in-the-middle could pass the challenge/chal_reply +phase (by just copying the messages between the two real tinc daemons), +but no information was exchanged that was really needed to read the rest +of the messages, the challenge/chal_reply phase was of no real use. The +man-in-the-middle was only stopped by the fact that only after the ACK +messages were encrypted with the symmetric cipher. Potentially, it +could even send it's own symmetric key to the server (if it knew the +server's public key) and read some of the metadata the server would send +it (it was impossible for the mitm to read actual network packets +though). The new scheme however prevents this. + + This new scheme makes sure that first of all, symmetric keys are +exchanged. The rest of the messages are then encrypted with the +symmetric cipher. Then, each side can only read received messages if +they have their private key. The challenge is there to let the other +side know that the private key is really known, because a challenge +reply can only be sent back if the challenge is decrypted correctly, and +that can only be done with knowledge of the private key. + + Fourth: the first thing that is sent via the symmetric cipher +encrypted connection is a totally random string, so that there is no +known plaintext (for an attacker) in the beginning of the encrypted +stream.  -File: tinc.info, Node: Simple Peer-to-Peer Security, Next: Encryption of network packets, Prev: Legacy authentication protocol, Up: Security +File: tinc.info, Node: Encryption of network packets, Next: Security issues, Prev: Authentication protocol, Up: Security -8.3.2 Simple Peer-to-Peer Security ----------------------------------- - -The SPTPS protocol is designed to address the weaknesses in the legacy -protocol. SPTPS is based on TLS 1.2, but has been simplified: there is -no support for exchanging public keys, and there is no cipher suite -negotiation. Instead, SPTPS always uses a very strong cipher suite: -peers authenticate each other using 521 bits ECC keys, Diffie-Hellman -using ephemeral 521 bits ECC keys is used to provide perfect forward -secrecy (PFS), AES-256-CTR is used for encryption, and HMAC-SHA-256 for -message authentication. - -Similar to TLS, messages are split up in records. A complete logical -record contains the following information: - - * uint32_t seqno (network byte order) - * uint16_t length (network byte order) - * uint8_t type - * opaque data[length] - * opaque hmac[HMAC_SIZE] (HMAC over all preceding fields) - -Depending on whether SPTPS records are sent via TCP or UDP, either the -seqno or the length field is omitted on the wire (but they are still -included in the calculation of the HMAC); for TCP packets are guaranteed -to arrive in-order so we can infer the seqno, but packets can be split -or merged, so we still need the length field to determine the boundaries -between records; for UDP packets we know that there is exactly one -record per packet, and we know the length of a packet, but packets can -be dropped, duplicated and/or reordered, so we need to include the -seqno. - -The type field is used to distinguish between application records or -handshake records. Types 0 to 127 are application records, type 128 is -a handshake record, and types 129 to 255 are reserved. - -Before the initial handshake, no fields are encrypted, and the HMAC -field is not present. After the authentication handshake, the length -(if present), type and data fields are encrypted, and the HMAC field is -present. For UDP packets, the seqno field is not encrypted, as it is -used to determine the value of the counter used for encryption. - -The authentication consists of an exchange of Key EXchange, SIGnature -and ACKnowledge messages, transmitted using type 128 records. - -Overview: - - Initiator Responder - --------------------- - KEX -> - <- KEX - SIG -> - <- SIG - - ...encrypt and HMAC using session keys from now on... - - App -> - <- App - ... - ... - - ...key renegotiation starts here... - - KEX -> - <- KEX - SIG -> - <- SIG - ACK -> - <- ACK - - ...encrypt and HMAC using new session keys from now on... - - App -> - <- App - ... - ... - --------------------- - -Note that the responder does not need to wait before it receives the -first KEX message, it can immediately send its own once it has accepted -an incoming connection. - -Key EXchange message: - - * uint8_t kex_version (always 0 in this version of SPTPS) - * opaque nonce[32] (random number) - * opaque ecdh_key[ECDH_SIZE] - -SIGnature message: - - * opaque ecdsa_signature[ECDSA_SIZE] - -ACKnowledge message: - - * empty (only sent after key renegotiation) - -Remarks: - - * At the start, both peers generate a random nonce and an Elliptic - Curve public key and send it to the other in the KEX message. - * After receiving the other's KEX message, both KEX messages are - concatenated (see below), and the result is signed using ECDSA. The - result is sent to the other. - * After receiving the other's SIG message, the signature is verified. - If it is correct, the shared secret is calculated from the public - keys exchanged in the KEX message using the Elliptic Curve - Diffie-Helman algorithm. - * The shared secret key is expanded using a PRF. Both nonces and the - application specific label are also used as input for the PRF. - * An ACK message is sent only when doing key renegotiation, and is - sent using the old encryption keys. - * The expanded key is used to key the encryption and HMAC algorithms. - -The signature is calculated over this string: - - * uint8_t initiator (0 = local peer, 1 = remote peer is initiator) - * opaque remote_kex_message[1 + 32 + ECDH_SIZE] - * opaque local_kex_message[1 + 32 + ECDH_SIZE] - * opaque label[label_length] - -The PRF is calculated as follows: - - * A HMAC using SHA512 is used, the shared secret is used as the key. - * For each block of 64 bytes, a HMAC is calculated. For block n: - hmac[n] = HMAC_SHA512(hmac[n - 1] + seed) - * For the first block (n = 1), hmac[0] is given by HMAC_SHA512(zeroes - + seed), where zeroes is a block of 64 zero bytes. - -The seed is as follows: - - * const char[13] "key expansion" - * opaque responder_nonce[32] - * opaque initiator_nonce[32] - * opaque label[label_length] - -The expanded key is used as follows: - - * opaque responder_cipher_key[CIPHER_KEYSIZE] - * opaque responder_digest_key[DIGEST_KEYSIZE] - * opaque initiator_cipher_key[CIPHER_KEYSIZE] - * opaque initiator_digest_key[DIGEST_KEYSIZE] - -Where initiator_cipher_key is the key used by session initiator to -encrypt messages sent to the responder. - -When using 256 bits Ed25519 keys, the AES-256-CTR cipher and -HMAC-SHA-256 digest algorithm, the sizes are as follows: - - ECDH_SIZE: 32 (= 256/8) - ECDSA_SIZE: 64 (= 2 * 256/8) - CIPHER_KEYSIZE: 48 (= 256/8 + 128/8) - DIGEST_KEYSIZE: 32 (= 256/8) - -Note that the cipher key also includes the initial value for the -counter. - - -File: tinc.info, Node: Encryption of network packets, Next: Security issues, Prev: Simple Peer-to-Peer Security, Up: Security - -8.3.3 Encryption of network packets +6.3.2 Encryption of network packets ----------------------------------- A data packet can only be sent if the encryption key is known to both parties, and the connection is activated. If the encryption key is not known, a request is sent to the destination using the meta connection to -retrieve it. +retrieve it. The packet is stored in a queue while waiting for the key +to arrive. -The UDP packets can be either encrypted with the legacy protocol or with -SPTPS. In case of the legacy protocol, the UDP packet containing the -network packet from the VPN has the following layout: + The UDP packet containing the network packet from the VPN has the +following layout: ... | IP header | UDP header | seqno | VPN packet | MAC | UDP trailer \___________________/\_____/ @@ -3129,39 +2239,18 @@ network packet from the VPN has the following layout: V +---> digest algorithm Encrypted with symmetric cipher -So, the entire VPN packet is encrypted using a symmetric cipher, + So, the entire VPN packet is encrypted using a symmetric cipher, including a 32 bits sequence number that is added in front of the actual VPN packet, to act as a unique IV for each packet and to prevent replay attacks. A message authentication code is added to the UDP packet to -prevent alteration of packets. Tinc by default encrypts network packets -using Blowfish with 128 bit keys in CBC mode and uses 4 byte long -message authentication codes to make sure eavesdroppers cannot get and -cannot change any information at all from the packets they can -intercept. The encryption algorithm and message authentication -algorithm can be changed in the configuration. The length of the -message authentication codes is also adjustable. The length of the key -for the encryption algorithm is always the default length used by -LibreSSL/OpenSSL. - -The SPTPS protocol is described in *note Simple Peer-to-Peer Security::. -For comparison, this is how SPTPS UDP packets look: - - ... | IP header | UDP header | seqno | type | VPN packet | MAC | UDP trailer - \__________________/\_____/ - | | - V +---> digest algorithm - Encrypted with symmetric cipher - -The difference is that the seqno is not encrypted, since the encryption -cipher is used in CTR mode, and therefore the seqno must be known before -the packet can be decrypted. Furthermore, the MAC is never truncated. -The SPTPS protocol always uses the AES-256-CTR cipher and HMAC-SHA-256 -digest, this cannot be changed. +prevent alteration of packets. By default the first 4 bytes of the +digest are used for this, but this can be changed using the MACLength +configuration variable.  File: tinc.info, Node: Security issues, Prev: Encryption of network packets, Up: Security -8.3.4 Security issues +6.3.3 Security issues --------------------- In August 2000, we discovered the existence of a security hole in all @@ -3171,40 +2260,22 @@ authentication scheme to make tinc as secure as possible. The current version uses the LibreSSL or OpenSSL library and uses strong authentication with RSA keys. -On the 29th of December 2001, Jerome Etienne posted a security analysis -of tinc 1.0pre4. Due to a lack of sequence numbers and a message -authentication code for each packet, an attacker could possibly disrupt -certain network services or launch a denial of service attack by + On the 29th of December 2001, Jerome Etienne posted a security +analysis of tinc 1.0pre4. Due to a lack of sequence numbers and a +message authentication code for each packet, an attacker could possibly +disrupt certain network services or launch a denial of service attack by replaying intercepted packets. The current version adds sequence numbers and message authentication codes to prevent such attacks. -On the 15th of September 2003, Peter Gutmann posted a security analysis -of tinc 1.0.1. He argues that the 32 bit sequence number used by tinc -is not a good IV, that tinc's default length of 4 bytes for the MAC is -too short, and he doesn't like tinc's use of RSA during authentication. -We do not know of a security hole in the legacy protocol of tinc, but it -is not as strong as TLS or IPsec. + On the 15th of September 2003, Peter Gutmann posted a security +analysis of tinc 1.0.1. He argues that the 32 bit sequence number used +by tinc is not a good IV, that tinc's default length of 4 bytes for the +MAC is too short, and he doesn't like tinc's use of RSA during +authentication. We do not know of a security hole in this version of +tinc, but tinc's security is not as strong as TLS or IPsec. We will +address these issues in tinc 2.0. -The Sweet32 attack affects versions of tinc prior to 1.0.30. - -On September 6th, 2018, Michael Yonly contacted us and provided -proof-of-concept code that allowed a remote attacker to create an -authenticated, one-way connection with a node, and also that there was a -possibility for a man-in-the-middle to force UDP packets from a node to -be sent in plaintext. The first issue was trivial to exploit on tinc -versions prior to 1.0.30, but the changes in 1.0.30 to mitigate the -Sweet32 attack made this weakness much harder to exploit. These issues -have been fixed in tinc 1.0.35. - -This version of tinc comes with an improved protocol, called Simple -Peer-to-Peer Security (SPTPS), which aims to be as strong as TLS with -one of the strongest cipher suites. None of the above security issues -affected SPTPS. However, be aware that SPTPS is only used between nodes -running tinc 1.1pre* or later, and in a VPN with nodes running different -versions, the security might only be as good as that of the oldest -version. - -Cryptography is a hard thing to get right. We cannot make any + Cryptography is a hard thing to get right. We cannot make any guarantees. Time, review and feedback are the only things that can prove the security of any cryptographic product. If you wish to review tinc or give us feedback, you are strongly encouraged to do so. @@ -3212,7 +2283,7 @@ tinc or give us feedback, you are strongly encouraged to do so.  File: tinc.info, Node: Platform specific information, Next: About us, Prev: Technical information, Up: Top -9 Platform specific information +7 Platform specific information ******************************* * Menu: @@ -3224,7 +2295,7 @@ File: tinc.info, Node: Platform specific information, Next: About us, Prev: T  File: tinc.info, Node: Interface configuration, Next: Routes, Up: Platform specific information -9.1 Interface configuration +7.1 Interface configuration =========================== When configuring an interface, one normally assigns it an address and a @@ -3236,40 +2307,40 @@ to that interface. Because all packets for the entire VPN should go to the virtual network interface used by tinc, the netmask should be such that it encompasses the entire VPN. -For IPv4 addresses: + For IPv4 addresses: -Linux 'ifconfig' INTERFACE ADDRESS 'netmask' NETMASK -Linux iproute2 'ip addr add' ADDRESS'/'PREFIXLENGTH 'dev' INTERFACE -FreeBSD 'ifconfig' INTERFACE ADDRESS 'netmask' NETMASK -OpenBSD 'ifconfig' INTERFACE ADDRESS 'netmask' NETMASK -NetBSD 'ifconfig' INTERFACE ADDRESS 'netmask' NETMASK -Solaris 'ifconfig' INTERFACE ADDRESS 'netmask' NETMASK -Darwin (MacOS/X) 'ifconfig' INTERFACE ADDRESS 'netmask' NETMASK -Windows 'netsh interface ip set address' INTERFACE 'static' ADDRESS NETMASK +Linux 'ifconfig' INTERFACE ADDRESS 'netmask' NETMASK +Linux iproute2 'ip addr add' ADDRESS'/'PREFIXLENGTH 'dev' INTERFACE +FreeBSD 'ifconfig' INTERFACE ADDRESS 'netmask' NETMASK +OpenBSD 'ifconfig' INTERFACE ADDRESS 'netmask' NETMASK +NetBSD 'ifconfig' INTERFACE ADDRESS 'netmask' NETMASK +Solaris 'ifconfig' INTERFACE ADDRESS 'netmask' NETMASK +Darwin (Mac OS X) 'ifconfig' INTERFACE ADDRESS 'netmask' NETMASK +Windows 'netsh interface ip set address' INTERFACE 'static' ADDRESS NETMASK -For IPv6 addresses: + For IPv6 addresses: -Linux 'ifconfig' INTERFACE 'add' ADDRESS'/'PREFIXLENGTH -FreeBSD 'ifconfig' INTERFACE 'inet6' ADDRESS 'prefixlen' PREFIXLENGTH -OpenBSD 'ifconfig' INTERFACE 'inet6' ADDRESS 'prefixlen' PREFIXLENGTH -NetBSD 'ifconfig' INTERFACE 'inet6' ADDRESS 'prefixlen' PREFIXLENGTH -Solaris 'ifconfig' INTERFACE 'inet6 plumb up' - 'ifconfig' INTERFACE 'inet6 addif' ADDRESS ADDRESS -Darwin (MacOS/X) 'ifconfig' INTERFACE 'inet6' ADDRESS 'prefixlen' PREFIXLENGTH -Windows 'netsh interface ipv6 add address' INTERFACE 'static' ADDRESS/PREFIXLENGTH +Linux 'ifconfig' INTERFACE 'add' ADDRESS'/'PREFIXLENGTH +FreeBSD 'ifconfig' INTERFACE 'inet6' ADDRESS 'prefixlen' PREFIXLENGTH +OpenBSD 'ifconfig' INTERFACE 'inet6' ADDRESS 'prefixlen' PREFIXLENGTH +NetBSD 'ifconfig' INTERFACE 'inet6' ADDRESS 'prefixlen' PREFIXLENGTH +Solaris 'ifconfig' INTERFACE 'inet6 plumb up' + 'ifconfig' INTERFACE 'inet6 addif' ADDRESS ADDRESS +Darwin (Mac OS X) 'ifconfig' INTERFACE 'inet6' ADDRESS 'prefixlen' PREFIXLENGTH +Windows 'netsh interface ipv6 add address' INTERFACE 'static' ADDRESS/PREFIXLENGTH -On Linux, it is possible to create a persistent tun/tap interface which -will continue to exist even if tinc quit, although this is normally not -required. It can be useful to set up a tun/tap interface owned by a -non-root user, so tinc can be started without needing any root -privileges at all. + On Linux, it is possible to create a persistent tun/tap interface +which will continue to exist even if tinc quit, although this is +normally not required. It can be useful to set up a tun/tap interface +owned by a non-root user, so tinc can be started without needing any +root privileges at all. -Linux 'ip tuntap add dev' INTERFACE 'mode' TUN|TAP 'user' USERNAME +Linux 'ip tuntap add dev' INTERFACE 'mode' TUN|TAP 'user' USERNAME  File: tinc.info, Node: Routes, Next: Automatically starting tinc, Prev: Interface configuration, Up: Platform specific information -9.2 Routes +7.2 Routes ========== In some cases it might be necessary to add more routes to the virtual @@ -3279,33 +2350,33 @@ another way is to specify the (local) address that is assigned to that interface (LOCAL_ADDRESS). The former way is unambiguous and therefore preferable, but not all platforms support this. -Adding routes to IPv4 subnets: + Adding routes to IPv4 subnets: -Linux 'route add -net' NETWORK_ADDRESS 'netmask' NETMASK INTERFACE -Linux iproute2 'ip route add' NETWORK_ADDRESS'/'PREFIXLENGTH 'dev' INTERFACE -FreeBSD 'route add' NETWORK_ADDRESS'/'PREFIXLENGTH LOCAL_ADDRESS -OpenBSD 'route add' NETWORK_ADDRESS'/'PREFIXLENGTH LOCAL_ADDRESS -NetBSD 'route add' NETWORK_ADDRESS'/'PREFIXLENGTH LOCAL_ADDRESS -Solaris 'route add' NETWORK_ADDRESS'/'PREFIXLENGTH LOCAL_ADDRESS '-interface' -Darwin (MacOS/X) 'route add' NETWORK_ADDRESS'/'PREFIXLENGTH LOCAL_ADDRESS -Windows 'netsh routing ip add persistentroute' NETWORK_ADDRESS NETMASK INTERFACE - LOCAL_ADDRESS +Linux 'route add -net' NETWORK_ADDRESS 'netmask' NETMASK INTERFACE +Linux iproute2 'ip route add' NETWORK_ADDRESS'/'PREFIXLENGTH 'dev' INTERFACE +FreeBSD 'route add' NETWORK_ADDRESS'/'PREFIXLENGTH LOCAL_ADDRESS +OpenBSD 'route add' NETWORK_ADDRESS'/'PREFIXLENGTH LOCAL_ADDRESS +NetBSD 'route add' NETWORK_ADDRESS'/'PREFIXLENGTH LOCAL_ADDRESS +Solaris 'route add' NETWORK_ADDRESS'/'PREFIXLENGTH LOCAL_ADDRESS '-interface' +Darwin (Mac OS X) 'route add' NETWORK_ADDRESS'/'PREFIXLENGTH '-interface' INTERFACE +Windows 'netsh routing ip add persistentroute' NETWORK_ADDRESS NETMASK INTERFACE + LOCAL_ADDRESS -Adding routes to IPv6 subnets: + Adding routes to IPv6 subnets: -Linux 'route add -A inet6' NETWORK_ADDRESS'/'PREFIXLENGTH INTERFACE -Linux iproute2 'ip route add' NETWORK_ADDRESS'/'PREFIXLENGTH 'dev' INTERFACE -FreeBSD 'route add -inet6' NETWORK_ADDRESS'/'PREFIXLENGTH LOCAL_ADDRESS -OpenBSD 'route add -inet6' NETWORK_ADDRESS LOCAL_ADDRESS '-prefixlen' PREFIXLENGTH -NetBSD 'route add -inet6' NETWORK_ADDRESS LOCAL_ADDRESS '-prefixlen' PREFIXLENGTH -Solaris 'route add -inet6' NETWORK_ADDRESS'/'PREFIXLENGTH LOCAL_ADDRESS '-interface' -Darwin (MacOS/X) ? -Windows 'netsh interface ipv6 add route' NETWORK ADDRESS/PREFIXLENGTH INTERFACE +Linux 'route add -A inet6' NETWORK_ADDRESS'/'PREFIXLENGTH INTERFACE +Linux iproute2 'ip route add' NETWORK_ADDRESS'/'PREFIXLENGTH 'dev' INTERFACE +FreeBSD 'route add -inet6' NETWORK_ADDRESS'/'PREFIXLENGTH LOCAL_ADDRESS +OpenBSD 'route add -inet6' NETWORK_ADDRESS LOCAL_ADDRESS '-prefixlen' PREFIXLENGTH +NetBSD 'route add -inet6' NETWORK_ADDRESS LOCAL_ADDRESS '-prefixlen' PREFIXLENGTH +Solaris 'route add -inet6' NETWORK_ADDRESS'/'PREFIXLENGTH LOCAL_ADDRESS '-interface' +Darwin (Mac OS X) 'route add -inet6' NETWORK_ADDRESS'/'PREFIXLENGTH '-interface' INTERFACE +Windows 'netsh interface ipv6 add route' NETWORK ADDRESS/PREFIXLENGTH INTERFACE  File: tinc.info, Node: Automatically starting tinc, Prev: Routes, Up: Platform specific information -9.3 Automatically starting tinc +7.3 Automatically starting tinc =============================== * Menu: @@ -3317,7 +2388,7 @@ File: tinc.info, Node: Automatically starting tinc, Prev: Routes, Up: Platfor  File: tinc.info, Node: Linux, Next: Windows, Up: Automatically starting tinc -9.3.1 Linux +7.3.1 Linux ----------- There are many Linux distributions, and historically, many of them had @@ -3334,35 +2405,35 @@ ensure it is started at boot time: systemctl enable tinc systemctl enable tinc@foo -To start the tinc daemon immediately if it wasn't already running, use -the following command: + To start the tinc daemon immediately if it wasn't already running, +use the following command: systemctl start tinc@foo -You can also use 'systemctl start tinc', this will start all tinc + You can also use 'systemctl start tinc', this will start all tinc daemons that are enabled. You can stop and disable tinc networks in the same way. -If your system is not using systemd, then you have to look up your + If your system is not using systemd, then you have to look up your distribution's way of starting tinc at boot time.  File: tinc.info, Node: Windows, Next: Other platforms, Prev: Linux, Up: Automatically starting tinc -9.3.2 Windows +7.3.2 Windows ------------- -On Windows, if tinc is started with the 'tinc start' command without -using the '-D' or '--no-detach' option, it will automatically register -itself as a service that is started at boot time. When tinc is stopped -using the 'tinc stop' command, it will also automatically unregister -itself. Once tinc is registered as a service, it is also possible to -stop and start tinc using the Windows Services Manager. +On Windows, if tinc is started without the '-D' or '--no-detach' option, +it will automatically register itself as a service that is started at +boot time. When tinc is stopped using the '-k' or '--kill', it will +also automatically unregister itself. Once tinc is registered as a +service, it is also possible to stop and start tinc using the Windows +Services Manager.  File: tinc.info, Node: Other platforms, Prev: Windows, Up: Automatically starting tinc -9.3.3 Other platforms +7.3.3 Other platforms --------------------- On platforms other than the ones mentioned in the earlier sections, you @@ -3371,8 +2442,8 @@ have to look up your platform's way of starting programs at boot time.  File: tinc.info, Node: About us, Next: Concept Index, Prev: Platform specific information, Up: Top -10 About us -*********** +8 About us +********** * Menu: @@ -3382,29 +2453,29 @@ File: tinc.info, Node: About us, Next: Concept Index, Prev: Platform specific  File: tinc.info, Node: Contact information, Next: Authors, Up: About us -10.1 Contact information -======================== +8.1 Contact information +======================= Tinc's website is at , this server is located in the Netherlands. -We have an IRC channel on the FreeNode and OFTC IRC networks. Connect -to irc.freenode.net (https://freenode.net/) or irc.oftc.net + We have an IRC channel on the FreeNode and OFTC IRC networks. +Connect to irc.freenode.net (https://freenode.net/) or irc.oftc.net (https://www.oftc.net/) and join channel #tinc.  File: tinc.info, Node: Authors, Prev: Contact information, Up: About us -10.2 Authors -============ +8.2 Authors +=========== Ivo Timmermans (zarq) Guus Sliepen (guus) () -We have received a lot of valuable input from users. With their help, -tinc has become the flexible and robust tool that it is today. We have -composed a list of contributions, in the file called 'THANKS' in the -source distribution. + We have received a lot of valuable input from users. With their +help, tinc has become the flexible and robust tool that it is today. We +have composed a list of contributions, in the file called 'THANKS' in +the source distribution.  File: tinc.info, Node: Concept Index, Prev: About us, Up: Top @@ -3415,9 +2486,8 @@ Concept Index [index] * Menu: -* ACK: Legacy authentication protocol. - (line 6) -* add: tinc commands. (line 22) +* ACK: Authentication protocol. + (line 10) * Address: Host configuration variables. (line 6) * AddressFamily: Main configuration variables. @@ -3425,296 +2495,214 @@ Concept Index * ADD_EDGE: The meta-protocol. (line 22) * ADD_SUBNET: The meta-protocol. (line 22) * ANS_KEY: The meta-protocol. (line 63) -* AutoConnect: Main configuration variables. - (line 12) -* batch: tinc runtime options. - (line 18) +* authentication: Authentication protocol. + (line 6) * binary package: Building and installing tinc. (line 9) * BindToAddress: Main configuration variables. - (line 16) + (line 12) * BindToInterface: Main configuration variables. - (line 23) + (line 25) * Broadcast: Main configuration variables. (line 33) -* BroadcastSubnet: Main configuration variables. - (line 53) * Cabal: Security. (line 6) -* CHALLENGE: Legacy authentication protocol. - (line 6) -* CHAL_REPLY: Legacy authentication protocol. - (line 6) +* CHALLENGE: Authentication protocol. + (line 10) +* CHAL_REPLY: Authentication protocol. + (line 10) * CIDR notation: Host configuration variables. - (line 101) + (line 93) * Cipher: Host configuration variables. (line 14) * ClampMSS: Host configuration variables. - (line 22) + (line 20) * client: How connections work. - (line 12) + (line 18) * command line: Runtime options. (line 9) -* command line interface: Controlling tinc. (line 6) * Compression: Host configuration variables. - (line 28) + (line 26) * connection: The connection. (line 6) * ConnectTo: Main configuration variables. - (line 65) + (line 53) * daemon: Running tinc. (line 11) * data-protocol: The meta-connection. (line 18) -* debug: tinc commands. (line 127) * debug level: Runtime options. (line 17) * debug levels: Debug levels. (line 6) * DecrementTTL: Main configuration variables. - (line 76) -* del: tinc commands. (line 27) + (line 64) * DEL_EDGE: The meta-protocol. (line 46) * DEL_SUBNET: The meta-protocol. (line 46) * Device: Main configuration variables. - (line 85) -* DEVICE: Scripts. (line 72) + (line 73) +* DEVICE: Scripts. (line 64) * device files: Device files. (line 6) -* DeviceStandby: Main configuration variables. - (line 92) * DeviceType: Main configuration variables. - (line 99) + (line 79) * Digest: Host configuration variables. - (line 33) + (line 31) * DirectOnly: Main configuration variables. - (line 174) -* disconnect: tinc commands. (line 142) + (line 149) * dummy: Main configuration variables. - (line 106) -* dump: tinc commands. (line 95) -* Ed25519PrivateKeyFile: Main configuration variables. - (line 181) -* edit: tinc commands. (line 32) + (line 86) * encapsulating: The UDP tunnel. (line 30) * encryption: Encryption of network packets. (line 6) -* environment variables: Scripts. (line 60) +* environment variables: Scripts. (line 53) * example: Example configuration. (line 6) -* exchange: tinc commands. (line 48) -* exchange-all: tinc commands. (line 51) * exec: Main configuration variables. - (line 373) -* ExperimentalProtocol: Main configuration variables. - (line 185) -* export: tinc commands. (line 36) -* export-all: tinc commands. (line 40) -* fd: Main configuration variables. - (line 129) + (line 319) * Forwarding: Main configuration variables. - (line 192) + (line 156) * frame type: The UDP tunnel. (line 6) -* fsck: tinc commands. (line 160) -* FWMark: Main configuration variables. - (line 214) -* generate-ed25519-keys: tinc commands. (line 86) -* generate-keys: tinc commands. (line 81) -* generate-rsa-keys: tinc commands. (line 89) -* get: tinc commands. (line 11) -* graph: tinc commands. (line 108) +* GraphDumpFile: Main configuration variables. + (line 176) * Hostnames: Main configuration variables. - (line 220) + (line 184) * http: Main configuration variables. - (line 370) + (line 316) * hub: Main configuration variables. - (line 288) -* ID: Legacy authentication protocol. - (line 6) -* Ifconfig: Invitation file format. - (line 36) -* import: tinc commands. (line 43) + (line 254) +* ID: Authentication protocol. + (line 10) +* IffOneQueue: Main configuration variables. + (line 195) * IndirectData: Host configuration variables. - (line 40) -* info: tinc commands. (line 120) -* init: tinc commands. (line 6) + (line 36) * Interface: Main configuration variables. - (line 231) -* INTERFACE: Scripts. (line 75) -* InvitationExpire: Main configuration variables. - (line 293) -* INVITATION_FILE: Scripts. (line 98) -* INVITATION_URL: Scripts. (line 102) -* invite: tinc commands. (line 54) + (line 198) +* INTERFACE: Scripts. (line 67) * IRC: Contact information. (line 9) -* join: tinc commands. (line 59) +* key generation: Generating keypairs. (line 6) * KeyExpire: Main configuration variables. - (line 296) + (line 206) * KEY_CHANGED: The meta-protocol. (line 63) -* legacy authentication protocol: Legacy authentication protocol. - (line 6) -* libcurses: libcurses. (line 6) * libraries: Libraries. (line 6) -* libreadline: libreadline. (line 6) * LibreSSL: LibreSSL/OpenSSL. (line 6) * license: LibreSSL/OpenSSL. (line 38) -* ListenAddress: Main configuration variables. - (line 239) * LocalDiscovery: Main configuration variables. - (line 251) -* log: tinc commands. (line 130) -* LogLevel: Main configuration variables. - (line 262) -* LZO: LZO. (line 6) + (line 212) +* lzo: lzo. (line 6) * MACExpire: Main configuration variables. - (line 302) + (line 223) * MACLength: Host configuration variables. - (line 45) -* MaxConnectionBurst: Main configuration variables. - (line 307) + (line 44) +* MaxTimeout: Main configuration variables. + (line 228) * meta-protocol: The meta-connection. (line 18) -* META_KEY: Legacy authentication protocol. - (line 6) +* META_KEY: Authentication protocol. + (line 10) * Mode: Main configuration variables. - (line 266) -* MTUInfoInterval: Host configuration variables. - (line 60) + (line 232) * multicast: Main configuration variables. - (line 118) + (line 98) * multiple networks: Multiple networks. (line 6) * Name: Main configuration variables. - (line 313) -* NAME: Scripts. (line 69) -* netmask: Network interfaces. (line 39) + (line 259) +* NAME: Scripts. (line 61) +* netmask: Network interfaces. (line 33) * netname: Multiple networks. (line 6) -* NETNAME: Scripts. (line 66) -* NETNAME <1>: tinc environment variables. - (line 6) -* network: tinc commands. (line 156) +* NETNAME: Scripts. (line 58) * Network Administrators Guide: Configuration introduction. (line 15) -* NODE: Scripts. (line 79) +* NODE: Scripts. (line 71) * OpenSSL: LibreSSL/OpenSSL. (line 6) * options: Runtime options. (line 9) -* pcap: tinc commands. (line 150) * PEM format: Host configuration variables. - (line 77) -* pid: tinc commands. (line 78) + (line 69) * PING: The meta-protocol. (line 88) * PingInterval: Main configuration variables. - (line 324) + (line 270) * PingTimeout: Main configuration variables. - (line 328) + (line 274) * platforms: Supported platforms. (line 6) * PMTU: Host configuration variables. - (line 52) + (line 49) * PMTUDiscovery: Host configuration variables. - (line 55) + (line 52) * PONG: The meta-protocol. (line 88) * Port: Host configuration variables. - (line 65) + (line 57) * port numbers: Other files. (line 17) * PriorityInheritance: Main configuration variables. - (line 334) + (line 280) * private: Virtual Private Networks. (line 10) * PrivateKey: Main configuration variables. - (line 339) + (line 285) * PrivateKeyFile: Main configuration variables. - (line 345) + (line 291) * ProcessPriority: Main configuration variables. - (line 350) + (line 296) * Proxy: Main configuration variables. - (line 355) + (line 301) * PublicKey: Host configuration variables. - (line 69) + (line 61) * PublicKeyFile: Host configuration variables. - (line 72) -* purge: tinc commands. (line 124) + (line 64) * raw_socket: Main configuration variables. - (line 111) + (line 91) * release: Supported platforms. (line 14) -* reload: tinc commands. (line 73) -* REMOTEADDRESS: Scripts. (line 84) -* REMOTEPORT: Scripts. (line 87) +* REMOTEADDRESS: Scripts. (line 76) +* REMOTEPORT: Scripts. (line 79) * ReplayWindow: Main configuration variables. - (line 378) + (line 324) * requirements: Libraries. (line 6) * REQ_KEY: The meta-protocol. (line 63) -* restart: tinc commands. (line 70) -* retry: tinc commands. (line 135) -* Route: Invitation file format. - (line 52) * router: Main configuration variables. - (line 269) + (line 235) * runtime options: Runtime options. (line 9) * scalability: tinc. (line 19) * scripts: Scripts. (line 6) * server: How connections work. - (line 12) -* set: tinc commands. (line 16) -* shell: Controlling tinc. (line 11) -* sign: tinc commands. (line 172) + (line 18) * signals: Signals. (line 6) * socks4: Main configuration variables. - (line 359) + (line 305) * socks5: Main configuration variables. - (line 364) -* SPTPS: Simple Peer-to-Peer Security. - (line 6) -* start: tinc commands. (line 64) -* stop: tinc commands. (line 67) + (line 310) * StrictSubnets: Main configuration variables. - (line 389) + (line 335) * Subnet: Host configuration variables. - (line 84) -* SUBNET: Scripts. (line 91) + (line 76) +* SUBNET: Scripts. (line 83) +* Subnet weight: Host configuration variables. + (line 98) * SVPN: Security. (line 11) * switch: Main configuration variables. - (line 277) + (line 243) * systemd: Linux. (line 6) * TCP: The meta-connection. (line 10) * TCPonly: Host configuration variables. - (line 113) + (line 105) * tinc: Introduction. (line 6) * TINC: Security. (line 6) -* tinc-down: Scripts. (line 30) -* tinc-up: Scripts. (line 20) +* tinc-down: Scripts. (line 29) +* tinc-up: Scripts. (line 19) * tinc-up <1>: Network interfaces. (line 19) * tincd: tinc. (line 14) -* top: tinc commands. (line 145) -* top <1>: tinc top. (line 6) * traditional VPNs: tinc. (line 19) * tunifhead: Main configuration variables. - (line 158) + (line 133) * TunnelServer: Main configuration variables. - (line 396) + (line 342) * tunnohead: Main configuration variables. - (line 152) + (line 127) * UDP: The UDP tunnel. (line 30) * UDP <1>: Encryption of network packets. - (line 11) -* UDPDiscoveryInterval: Main configuration variables. - (line 416) -* UDPDiscoveryKeepaliveInterval: Main configuration variables. - (line 410) -* UDPDiscoveryTimeout: Main configuration variables. - (line 420) -* UDPDiscovey: Main configuration variables. - (line 403) -* UDPInfoInterval: Main configuration variables. - (line 425) + (line 12) * UDPRcvBuf: Main configuration variables. - (line 429) + (line 349) * UDPSndBuf: Main configuration variables. - (line 435) + (line 354) * UML: Main configuration variables. - (line 134) + (line 109) * Universal tun/tap: Configuration of Linux kernels. (line 6) -* UPnP: Main configuration variables. - (line 441) -* UPnPDiscoverWait: Main configuration variables. - (line 452) -* UPnPRefreshPeriod: Main configuration variables. - (line 456) * utun: Main configuration variables. - (line 165) + (line 140) * VDE: Main configuration variables. - (line 139) -* verify: tinc commands. (line 177) + (line 114) * virtual: Virtual Private Networks. (line 18) * virtual network device: The UDP tunnel. (line 6) @@ -3722,90 +2710,76 @@ Concept Index (line 6) * vpnd: tinc. (line 6) * website: Contact information. (line 6) -* Weight: Host configuration variables. - (line 120) -* WEIGHT: Scripts. (line 94) +* WEIGHT: Scripts. (line 86) * zlib: zlib. (line 6)  Tag Table: -Node: Top808 -Node: Introduction1144 -Node: Virtual Private Networks1948 -Node: tinc3660 -Node: Supported platforms5173 -Node: Preparations5870 -Node: Configuring the kernel6126 -Node: Configuration of Linux kernels6535 -Node: Configuration of FreeBSD kernels7384 -Node: Configuration of OpenBSD kernels7849 -Node: Configuration of NetBSD kernels8206 -Node: Configuration of Solaris kernels8608 -Node: Configuration of Darwin (MacOS/X) kernels9270 -Node: Configuration of Windows10083 -Node: Libraries10622 -Node: LibreSSL/OpenSSL11079 -Node: zlib13607 -Node: LZO14627 -Node: libcurses15619 -Node: libreadline16531 -Node: Installation17470 -Node: Building and installing tinc18374 -Node: Darwin (MacOS/X) build environment19030 -Node: Cygwin (Windows) build environment19589 -Node: MinGW (Windows) build environment20174 -Node: System files20762 -Node: Device files21027 -Node: Other files21440 -Node: Configuration22053 -Node: Configuration introduction22340 -Node: Multiple networks23862 -Node: How connections work25230 -Node: Configuration files27494 -Node: Main configuration variables29125 -Node: Host configuration variables50523 -Node: Scripts56595 -Node: How to configure60495 -Node: Network interfaces64406 -Node: Example configuration66785 -Node: Running tinc71726 -Node: Runtime options72313 -Node: Signals75581 -Node: Debug levels76430 -Node: Solving problems77366 -Node: Error messages78792 -Node: Sending bug reports83109 -Node: Controlling tinc84056 -Node: tinc runtime options84792 -Node: tinc environment variables85608 -Node: tinc commands85937 -Node: tinc examples92796 -Node: tinc top93356 -Node: Invitations94940 -Node: How invitations work95603 -Node: Invitation file format97896 -Node: Writing an invitation-created script100907 -Node: Technical information101970 -Node: The connection102200 -Node: The UDP tunnel102512 -Node: The meta-connection105548 -Node: The meta-protocol107006 -Node: Security111989 -Node: Legacy authentication protocol113326 -Node: Simple Peer-to-Peer Security117943 -Node: Encryption of network packets123588 -Node: Security issues126226 -Node: Platform specific information128818 -Node: Interface configuration129078 -Node: Routes131348 -Node: Automatically starting tinc133295 -Node: Linux133518 -Node: Windows134730 -Node: Other platforms135274 -Node: About us135556 -Node: Contact information135733 -Node: Authors136136 -Node: Concept Index136540 +Node: Top806 +Node: Introduction1105 +Node: Virtual Private Networks1915 +Node: tinc3639 +Node: Supported platforms5167 +Node: Preparations5868 +Node: Configuring the kernel6124 +Node: Configuration of Linux kernels6534 +Node: Configuration of FreeBSD kernels7389 +Node: Configuration of OpenBSD kernels7854 +Node: Configuration of NetBSD kernels8211 +Node: Configuration of Solaris kernels8616 +Node: Configuration of Darwin (Mac OS X) kernels9279 +Node: Configuration of Windows10098 +Node: Libraries10638 +Node: LibreSSL/OpenSSL11047 +Node: zlib13589 +Node: lzo14618 +Node: Installation15601 +Node: Building and installing tinc16511 +Node: Darwin (Mac OS X) build environment17171 +Node: Cygwin (Windows) build environment17736 +Node: MinGW (Windows) build environment18325 +Node: System files18919 +Node: Device files19184 +Node: Other files19600 +Node: Configuration20213 +Node: Configuration introduction20524 +Node: Multiple networks21792 +Node: How connections work23218 +Node: Configuration files24440 +Node: Main configuration variables25934 +Node: Host configuration variables42190 +Node: Scripts47722 +Node: How to configure50988 +Node: Generating keypairs52246 +Node: Network interfaces52745 +Node: Example configuration54593 +Node: Running tinc59918 +Node: Runtime options60508 +Node: Signals64137 +Node: Debug levels65328 +Node: Solving problems66264 +Node: Error messages67816 +Node: Sending bug reports71825 +Node: Technical information72772 +Node: The connection73003 +Node: The UDP tunnel73315 +Node: The meta-connection76367 +Node: The meta-protocol77836 +Node: Security82853 +Node: Authentication protocol83995 +Node: Encryption of network packets89040 +Node: Security issues90416 +Node: Platform specific information92056 +Node: Interface configuration92316 +Node: Routes94612 +Node: Automatically starting tinc96662 +Node: Linux96885 +Node: Windows98106 +Node: Other platforms98611 +Node: About us98893 +Node: Contact information99068 +Node: Authors99471 +Node: Concept Index99876  End Tag Table diff --git a/doc/tinc.texi b/doc/tinc.texi index c7021dd..0420e6f 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-2018 Ivo Timmermans, +Copyright @copyright{} 1998-2019 Ivo Timmermans, Guus Sliepen and Wessel Dankers . @@ -30,10 +30,6 @@ permission notice identical to this one. @end ifinfo -@afourpaper -@paragraphindent none -@finalout - @titlepage @title tinc Manual @subtitle Setting up a Virtual Private Network with tinc @@ -43,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-2018 Ivo Timmermans, +Copyright @copyright{} 1998-2019 Ivo Timmermans, Guus Sliepen and Wessel Dankers . @@ -69,8 +65,6 @@ permission notice identical to this one. * Installation:: * Configuration:: * Running tinc:: -* Controlling tinc:: -* Invitations:: * Technical information:: * Platform specific information:: * About us:: @@ -182,7 +176,7 @@ available too. @section Supported platforms @cindex platforms -Tinc has been verified to work under Linux, FreeBSD, OpenBSD, NetBSD, MacOS/X (Darwin), Solaris, and Windows (both natively and in a Cygwin environment), +Tinc has been verified to work under Linux, FreeBSD, OpenBSD, NetBSD, Mac OS X (Darwin), Solaris, and Windows (both natively and in a Cygwin environment), with various hardware architectures. These are some of the platforms that are supported by the universal tun/tap device driver or other virtual network device drivers. Without such a driver, tinc will most @@ -230,7 +224,7 @@ support tinc. * Configuration of OpenBSD kernels:: * Configuration of NetBSD kernels:: * Configuration of Solaris kernels:: -* Configuration of Darwin (MacOS/X) kernels:: +* Configuration of Darwin (Mac OS X) kernels:: * Configuration of Windows:: @end menu @@ -299,13 +293,13 @@ If the @file{net/if_tun.h} header file is missing, install it from the source pa @c ================================================================== -@node Configuration of Darwin (MacOS/X) kernels -@subsection Configuration of Darwin (MacOS/X) kernels +@node Configuration of Darwin (Mac OS X) kernels +@subsection Configuration of Darwin (Mac OS X) kernels Tinc on Darwin relies on a tunnel driver for its data acquisition from the kernel. OS X version 10.6.8 and later have a built-in tun driver called "utun". Tinc also supports the driver from @uref{http://tuntaposx.sourceforge.net/}, -which supports both tun and tap style devices, +which supports both tun and tap style devices. By default, tinc expects the tuntaposx driver to be installed. To use the utun driver, set add @code{Device = utunX} to @file{tinc.conf}, @@ -330,17 +324,14 @@ as explained in the rest of the documentation. @cindex requirements @cindex libraries -Before you can configure or build tinc, you need to have the LibreSSL or OpenSSL, zlib, -LZO, curses and readline libraries installed on your system. If you try to -configure tinc without having them installed, configure will give you an error -message, and stop. +Before you can configure or build tinc, you need to have the LibreSSL or OpenSSL, +zlib and lzo libraries installed on your system. If you try to configure tinc without +having them installed, configure will give you an error message, and stop. @menu * LibreSSL/OpenSSL:: * zlib:: -* LZO:: -* libcurses:: -* libreadline:: +* lzo:: @end menu @@ -363,7 +354,7 @@ of this package. If your operating system comes neither with LibreSSL or OpenSSL, you have to install one manually. It is recommended that you get the latest version of -LibreSSL from @url{https://www.libressl.org/}. Instructions on how to +LibreSSL from @url{http://www.libressl.org/}. Instructions on how to configure, build and install this package are included within the package. Please make sure you build development and runtime libraries (which is the default). @@ -437,10 +428,10 @@ default). @c ================================================================== -@node LZO -@subsection LZO +@node lzo +@subsection lzo -@cindex LZO +@cindex lzo Another form of compression is offered using the LZO library. If this library is not installed, you will get an error when running the @@ -453,58 +444,13 @@ You can use your operating system's package manager to install this if available. Make sure you install the development AND runtime versions of this package. -If you have to install LZO manually, you can get the source code +If you have to install lzo manually, you can get the source code from @url{https://www.oberhumer.com/opensource/lzo/}. Instructions on how to configure, build and install this package are included within the package. Please make sure you build development and runtime libraries (which is the default). -@c ================================================================== -@node libcurses -@subsection libcurses - -@cindex libcurses -For the "tinc top" command, tinc requires a curses library. - -If this library is not installed, you will get an error when running the -configure script. You can either install a suitable curses library, or disable -all functionality that depends on a curses library by using the -"--disable-curses" option when running the configure script. - -There are several curses libraries. It is recommended that you install -"ncurses" (@url{https://invisible-island.net/ncurses/}), -however other curses libraries should also work. -In particular, "PDCurses" (@url{https://pdcurses.sourceforge.io/}) -is recommended if you want to compile tinc for Windows. - -You can use your operating system's package manager to install this if -available. Make sure you install the development AND runtime versions -of this package. - - -@c ================================================================== -@node libreadline -@subsection libreadline - -@cindex libreadline -For the "tinc" command's shell functionality, tinc uses the readline library. - -If this library is not installed, you will get an error when running the -configure script. You can either install a suitable readline library, or -disable all functionality that depends on a readline library by using the -"--disable-readline" option when running the configure script. - -You can use your operating system's package manager to install this if -available. Make sure you install the development AND runtime versions -of this package. - -If you have to install libreadline manually, you can get the source code from -@url{https://www.gnu.org/software/readline/}. Instructions on how to configure, -build and install this package are included within the package. Please make -sure you build development and runtime libraries (which is the default). - - @c @c @c @@ -552,15 +498,15 @@ you can use the package management tools of that distribution to install tinc. The documentation that comes along with your distribution will tell you how to do that. @menu -* Darwin (MacOS/X) build environment:: +* Darwin (Mac OS X) build environment:: * Cygwin (Windows) build environment:: * MinGW (Windows) build environment:: @end menu @c ================================================================== -@node Darwin (MacOS/X) build environment -@subsection Darwin (MacOS/X) build environment +@node Darwin (Mac OS X) build environment +@subsection Darwin (Mac OS X) build environment In order to build tinc on Darwin, you need to install Xcode from @uref{https://developer.apple.com/xcode/}. It might also help to install a recent version of Fink from @uref{http://www.finkproject.org/}. @@ -669,6 +615,7 @@ tinc 655/udp TINC * Multiple networks:: * How connections work:: * Configuration files:: +* Generating keypairs:: * Network interfaces:: * Example configuration:: @end menu @@ -691,19 +638,13 @@ you will not find the answers in this documentation. Make sure you have an adequate understanding of networks in general. @cindex Network Administrators Guide A good resource on networking is the -@uref{https://www.tldp.org/LDP/nag2/, Linux Network Administrators Guide}. +@uref{http://www.tldp.org/LDP/nag2/, Linux Network Administrators Guide}. If you have everything clearly pictured in your mind, proceed in the following order: -First, create the initial configuration files and public/private keypairs using the following command: -@example -tinc -n @var{NETNAME} init @var{NAME} -@end example -Second, use @samp{tinc -n @var{NETNAME} add ...} to further configure tinc. -Finally, export your host configuration file using @samp{tinc -n @var{NETNAME} export} and send it to those -people or computers you want tinc to connect to. -They should send you their host configuration file back, which you can import using @samp{tinc -n @var{NETNAME} import}. - +First, generate the configuration files (@file{tinc.conf}, your host configuration file, @file{tinc-up} and perhaps @file{tinc-down}). +Then generate the keypairs. +Finally, distribute the host configuration files. These steps are described in the subsections below. @@ -713,29 +654,30 @@ These steps are described in the subsections below. @cindex multiple networks @cindex netname - In order to allow you to run more than one tinc daemon on one computer, for instance if your computer is part of more than one VPN, you can assign a @var{netname} to your VPN. It is not required if you only run one tinc daemon, -it doesn't even have to be the same on all the nodes of your VPN, +it doesn't even have to be the same on all the sites of your VPN, but it is recommended that you choose one anyway. We will assume you use a netname throughout this document. -This means that you call tinc with the -n argument, -which will specify the netname. +This means that you call tincd with the -n argument, +which will assign a netname to this daemon. -The effect of this option is that tinc will set its configuration -root to @file{@value{sysconfdir}/tinc/@var{netname}/}, where @var{netname} is your argument to the -n option. -You will also notice that log messages it appears in syslog as coming from @file{tinc.@var{netname}}, -and on Linux, unless specified otherwise, the name of the virtual network interface will be the same as the network name. +The effect of this is that the daemon will set its configuration +root to @file{@value{sysconfdir}/tinc/@var{netname}/}, where @var{netname} is your argument to the -n +option. You'll notice that it appears in syslog as @file{tinc.@var{netname}}. However, it is not strictly necessary that you call tinc with the -n -option. If you do not use it, the network name will just be empty, and -tinc will look for files in @file{@value{sysconfdir}/tinc/} instead of -@file{@value{sysconfdir}/tinc/@var{netname}/}; -the configuration file will then be @file{@value{sysconfdir}/tinc/tinc.conf}, -and the host configuration files are expected to be in @file{@value{sysconfdir}/tinc/hosts/}. +option. In this case, the network name would just be empty, and it will +be used as such. tinc now looks for files in @file{@value{sysconfdir}/tinc/}, instead of +@file{@value{sysconfdir}/tinc/@var{netname}/}; the configuration file should be @file{@value{sysconfdir}/tinc/tinc.conf}, +and the host configuration files are now expected to be in @file{@value{sysconfdir}/tinc/hosts/}. + +But it is highly recommended that you use this feature of tinc, because +it will be so much clearer whom your daemon talks to. Hence, we will +assume that you use it. @c ================================================================== @@ -744,36 +686,24 @@ and the host configuration files are expected to be in @file{@value{sysconfdir}/ When tinc starts up, it parses the command-line options and then reads in the configuration file tinc.conf. -It will then start listening for incoming connection from other daemons, -and will by default also automatically try to connect to known peers. -By default, tinc will try to keep at least 3 working meta-connections alive at all times. +If it sees one or more `ConnectTo' values pointing to other tinc daemons in that file, +it will try to connect to those other daemons. +Whether this succeeds or not and whether `ConnectTo' is specified or not, +tinc will listen for incoming connection from other daemons. +If you did specify a `ConnectTo' value and the other side is not responding, +tinc will keep retrying. +This means that once started, tinc will stay running until you tell it to stop, +and failures to connect to other tinc daemons will not stop your tinc daemon +for trying again later. +This means you don't have to intervene if there are temporary network problems. @cindex client @cindex server There is no real distinction between a server and a client in tinc. -If you wish, you can view a tinc daemon without a `ConnectTo' statement in tinc.conf and `AutoConnect = no' as a server, -and one which does have one or more `ConnectTo' statements or `Autoconnect = yes' (which is the default) as a client. +If you wish, you can view a tinc daemon without a `ConnectTo' value as a server, +and one which does specify such a value as a client. It does not matter if two tinc daemons have a `ConnectTo' value pointing to each other however. -Connections specified using `ConnectTo' are so-called meta-connections. -Tinc daemons exchange information about all other daemon they know about via these meta-connections. -After learning about all the daemons in the VPN, -tinc will create other connections as necessary in order to communicate with them. -For example, if there are three daemons named A, B and C, and A has @samp{ConnectTo = B} in its tinc.conf file, -and C has @samp{ConnectTo = B} in its tinc.conf file, then A will learn about C from B, -and will be able to exchange VPN packets with C without the need to have @samp{ConnectTo = C} in its tinc.conf file. - -It could be that some daemons are located behind a Network Address Translation (NAT) device, or behind a firewall. -In the above scenario with three daemons, if A and C are behind a NAT, -B will automatically help A and C punch holes through their NAT, -in a way similar to the STUN protocol, so that A and C can still communicate with each other directly. -It is not always possible to do this however, and firewalls might also prevent direct communication. -In that case, VPN packets between A and C will be forwarded by B. - -In effect, all nodes in the VPN will be able to talk to each other, as long as -there is a path of meta-connections between them, and whenever possible, two -nodes will communicate with each other directly. - @c ================================================================== @node Configuration files @@ -805,10 +735,7 @@ listed in this document can also be put in put host specific configuration options in the host configuration file, as this makes it easy to exchange with other nodes. -You can edit the config file manually, but it is recommended that you use -the tinc command to change configuration variables for you. - -In the following two subsections all valid variables are listed in alphabetical order. +In this section all valid variables are listed in alphabetical order. The default value is given between parentheses, other comments are between square brackets. @@ -831,17 +758,18 @@ This option affects the address family of listening and outgoing sockets. If any is selected, then depending on the operating system both IPv4 and IPv6 or just IPv6 listening sockets will be created. -@cindex AutoConnect -@item AutoConnect = (yes) -If set to yes, tinc will automatically set up meta connections to other nodes, -without requiring @var{ConnectTo} variables. - @cindex BindToAddress -@item BindToAddress = <@var{address}> [<@var{port}>] -This is the same as ListenAddress, however the address given with the BindToAddress option -will also be used for outgoing connections. -This is useful if your computer has more than one IPv4 or IPv6 address, -and you want tinc to only use a specific one for outgoing packets. +@item BindToAddress = <@var{address}> [<@var{port}>] [experimental] +If your computer has more than one IPv4 or IPv6 address, tinc +will by default listen on all of them for incoming connections. +Multiple BindToAddress variables may be specified, +in which case listening sockets for each specified address are made. + +If no @var{port} is specified, the socket will be bound to the port specified by the Port option, +or to port 655 if neither is given. +To only bind to a specific port but not to a specific address, use "*" for the @var{address}. + +This option may not work on all platforms. @cindex BindToInterface @item BindToInterface = <@var{interface}> [experimental] @@ -851,8 +779,6 @@ possible to bind tinc to a single interface like eth0 or ppp0 with this variable. This option may not work on all platforms. -Also, on some platforms it will not actually bind to an interface, -but rather to the address that the interface has at the moment a socket is created. @cindex Broadcast @item Broadcast = (mst) [experimental] @@ -873,18 +799,6 @@ Broadcast packets received from other nodes are never forwarded. If the IndirectData option is also set, broadcast packets will only be sent to nodes which we have a meta connection to. @end table -@cindex BroadcastSubnet -@item BroadcastSubnet = @var{address}[/@var{prefixlength}] -Declares a broadcast subnet. -Any packet with a destination address falling into such a subnet will be routed as a broadcast -(provided all nodes have it declared). -This is most useful to declare subnet broadcast addresses (e.g. 10.42.255.255), -otherwise tinc won't know what to do with them. - -Note that global broadcast addresses (MAC ff:ff:ff:ff:ff:ff, IPv4 255.255.255.255), -as well as multicast space (IPv4 224.0.0.0/4, IPv6 ff00::/8) -are always considered broadcast addresses and don't need to be declared. - @cindex ConnectTo @item ConnectTo = <@var{name}> Specifies which other tinc daemon to connect to on startup. @@ -893,7 +807,7 @@ in which case outgoing connections to each specified tinc daemon are made. The names should be known to this tinc daemon (i.e., there should be a host configuration file for the name on the ConnectTo line). -If you don't specify a host with ConnectTo and have disabled AutoConnect, +If you don't specify a host with ConnectTo, tinc won't try to connect to other daemons at all, and will instead just listen for incoming connections. @@ -910,18 +824,10 @@ Do not use this option if you use switch mode and want to use IPv6. @item Device = <@var{device}> (@file{/dev/tap0}, @file{/dev/net/tun} or other depending on platform) The virtual network device to use. Tinc will automatically detect what kind of device it is. -Note that you can only use one device per daemon. Under Windows, use @var{Interface} instead of @var{Device}. Note that you can only use one device per daemon. See also @ref{Device files}. -@cindex DeviceStandby -@item DeviceStandby = (no) -When disabled, tinc calls @file{tinc-up} on startup, and @file{tinc-down} on shutdown. -When enabled, tinc will only call @file{tinc-up} when at least one node is reachable, -and will call @file{tinc-down} as soon as no nodes are reachable. -On Windows, this also determines when the virtual network interface "cable" is "plugged". - @cindex DeviceType @item DeviceType = <@var{type}> (platform dependent) The type of the virtual network device. @@ -951,12 +857,6 @@ This can be used to connect to UML, QEMU or KVM instances listening on the same Do NOT connect multiple tinc daemons to the same multicast address, this will very likely cause routing loops. Also note that this can cause decrypted VPN packets to be sent out on a real network if misconfigured. -@cindex fd -@item fd -Use a file descriptor. -All packets are read from this interface. -Packets received for the local node are written to it. - @cindex UML @item uml (not compiled in by default) Create a UNIX socket with the filename specified by @@ -1013,19 +913,6 @@ but which would have to be forwarded by an intermediate node, are dropped instea When combined with the IndirectData option, packets for nodes for which we do not have a meta connection with are also dropped. -@cindex Ed25519PrivateKeyFile -@item Ed25519PrivateKeyFile = <@var{path}> (@file{@value{sysconfdir}/tinc/@var{netname}/ed25519_key.priv}) -The file in which the private Ed25519 key of this tinc daemon resides. -This is only used if ExperimentalProtocol is enabled. - -@cindex ExperimentalProtocol -@item ExperimentalProtocol = (yes) -When this option is enabled, the SPTPS protocol will be used when connecting to nodes that also support it. -Ephemeral ECDH will be used for key exchanges, -and Ed25519 will be used instead of RSA for authentication. -When enabled, an Ed25519 key must have been generated before with -@samp{tinc generate-ed25519-keys}. - @cindex Forwarding @item Forwarding = (internal) [experimental] This option selects the way indirect packets are forwarded. @@ -1041,18 +928,20 @@ Incoming packets that are meant for another node are forwarded by tinc internall This is the default mode, and unless you really know you need another forwarding mode, don't change it. @item kernel -Incoming packets using the legacy protocol are always sent to the TUN/TAP device, -even if the packets are not for the local node. +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. -Incoming packets using the SPTPS protocol are dropped, since they are end-to-end encrypted. @end table -@cindex FWMark -@item FWMark = <@var{value}> (0) [experimental] -When set to a non-zero value, all TCP and UDP sockets created by tinc will use the given value as the firewall mark. -This can be used for mark-based routing or for packet filtering. -This option is currently only supported on Linux. +@cindex GraphDumpFile +@item GraphDumpFile = <@var{filename}> [experimental] +If this option is present, +tinc will dump the current network graph to the file @var{filename} +every minute, unless there were no changes to the graph. +The file is in a format that can be read by graphviz tools. +If @var{filename} starts with a pipe symbol |, +then the rest of the filename is interpreted as a shell command +that is executed, the graph is then sent to stdin. @cindex Hostnames @item Hostnames = (no) @@ -1064,6 +953,10 @@ it does a lookup if your DNS server is not responding. This does not affect resolving hostnames to IP addresses from the configuration file, but whether hostnames should be resolved while logging. +@cindex IffOneQueue +@item IffOneQueue = (no) [experimental] +(Linux only) Set IFF_ONE_QUEUE flag on TUN/TAP devices. + @cindex Interface @item Interface = <@var{interface}> Defines the name of the interface corresponding to the virtual network device. @@ -1071,32 +964,31 @@ Depending on the operating system and the type of device this may or may not act Under Windows, this variable is used to select which network interface will be used. If you specified a Device, this variable is almost always already correctly set. -@cindex ListenAddress -@item ListenAddress = <@var{address}> [<@var{port}>] -If your computer has more than one IPv4 or IPv6 address, tinc -will by default listen on all of them for incoming connections. -This option can be used to restrict which addresses tinc listens on. -Multiple ListenAddress variables may be specified, -in which case listening sockets for each specified address are made. - -If no @var{port} is specified, the socket will listen on the port specified by the Port option, -or to port 655 if neither is given. -To only listen on a specific port but not to a specific address, use "*" for the @var{address}. +@cindex KeyExpire +@item KeyExpire = <@var{seconds}> (3600) +This option controls the time the encryption keys used to encrypt the data +are valid. It is common practice to change keys at regular intervals to +make it even harder for crackers, even though it is thought to be nearly +impossible to crack a single key. @cindex LocalDiscovery -@item LocalDiscovery = (no) +@item LocalDiscovery = (no) [experimental] When enabled, tinc will try to detect peers that are on the same local network. This will allow direct communication using LAN addresses, even if both peers are behind a NAT and they only ConnectTo a third node outside the NAT, which normally would prevent the peers from learning each other's LAN address. -Currently, local discovery is implemented by sending some packets to the local address of the node during UDP discovery. -This will not work with old nodes that don't transmit their local address. +Currently, local discovery is implemented by sending broadcast packets to the LAN during path MTU discovery. +This feature may not work in all possible situations. -@cindex LogLevel -@item LogLevel = <@var{level}> (0) -This option controls the verbosity of the logging. -See @ref{Debug levels}. +@cindex MACExpire +@item MACExpire = <@var{seconds}> (600) +This option controls the amount of time MAC addresses are kept before they are removed. +This only has effect when Mode is set to "switch". + +@cindex MaxTimeout +@item MaxTimeout = <@var{seconds}> (900) +This is the maximum delay before trying to reconnect to other tinc daemons. @cindex Mode @item Mode = (router) @@ -1107,7 +999,7 @@ This option selects the way packets are routed to other daemons. @item router In this mode Subnet variables in the host configuration files will be used to form a routing table. -Only packets of routable protocols (IPv4 and IPv6) are supported in this mode. +Only unicast packets of routable protocols (IPv4 and IPv6) are supported in this mode. This is the default mode, and unless you really know you need another mode, don't change it. @@ -1127,33 +1019,10 @@ every packet will be broadcast to the other daemons while no routing table is managed. @end table -@cindex InvitationExpire -@item InvitationExpire = <@var{seconds}> (604800) -This option controls the time invitations are valid. - -@cindex KeyExpire -@item KeyExpire = <@var{seconds}> (3600) -This option controls the time the encryption keys used to encrypt the data -are valid. It is common practice to change keys at regular intervals to -make it even harder for crackers, even though it is thought to be nearly -impossible to crack a single key. - -@cindex MACExpire -@item MACExpire = <@var{seconds}> (600) -This option controls the amount of time MAC addresses are kept before they are removed. -This only has effect when Mode is set to "switch". - -@cindex MaxConnectionBurst -@item MaxConnectionBurst = <@var{count}> (100) -This option controls how many connections tinc accepts in quick succession. -If there are more connections than the given number in a short time interval, -tinc will reduce the number of accepted connections to only one per second, -until the burst has passed. - @cindex Name @item Name = <@var{name}> [required] This is a symbolic name for this connection. -The name must consist only of alfanumeric and underscore characters (a-z, A-Z, 0-9 and _), and is case sensitive. +The name must consist only of alphanumeric and underscore characters (a-z, A-Z, 0-9 and _). If Name starts with a $, then the contents of the environment variable that follows will be used. In that case, invalid characters will be converted to underscores. @@ -1185,7 +1054,7 @@ accidental eavesdropping if you are editing the configuration file. @cindex PrivateKeyFile @item PrivateKeyFile = <@var{path}> (@file{@value{sysconfdir}/tinc/@var{netname}/rsa_key.priv}) This is the full path name of the RSA private key file that was -generated by @samp{tinc generate-keys}. It must be a full path, not a +generated by @samp{tincd --generate-keys}. It must be a full path, not a relative directory. @cindex ProcessPriority @@ -1221,10 +1090,10 @@ The environment variables @env{NAME}, @env{NODE}, @env{REMOTEADDRES} and @env{RE @end table @cindex ReplayWindow -@item ReplayWindow = (32) +@item ReplayWindow = (16) This is the size of the replay tracking window for each remote node, in bytes. The window is a bitfield which tracks 1 packet per bit, so for example -the default setting of 32 will track up to 256 packets in the window. In high +the default setting of 16 will track up to 128 packets in the window. In high bandwidth scenarios, setting this to a higher value can reduce packet loss from the interaction of replay tracking with underlying real packet loss and/or reordering. Setting this to zero will disable replay tracking completely and @@ -1246,60 +1115,15 @@ and will only allow connections with nodes for which host config files are prese @file{@value{sysconfdir}/tinc/@var{netname}/hosts/} directory. Setting this options also implicitly sets StrictSubnets. -@cindex UDPDiscovey -@item UDPDiscovery = (yes) -When this option is enabled tinc will try to establish UDP connectivity to nodes, -using TCP while it determines if a node is reachable over UDP. If it is disabled, -tinc always assumes a node is reachable over UDP. -Note that tinc will never use UDP with nodes that have TCPOnly enabled. - -@cindex UDPDiscoveryKeepaliveInterval -@item UDPDiscoveryKeepaliveInterval = (9) -The minimum amount of time between sending UDP ping datagrams to check UDP connectivity once it has been established. -Note that these pings are large, since they are used to verify link MTU as well. - -@cindex UDPDiscoveryInterval -@item UDPDiscoveryInterval = (2) -The minimum amount of time between sending UDP ping datagrams to try to establish UDP connectivity. - -@cindex UDPDiscoveryTimeout -@item UDPDiscoveryTimeout = (30) -If tinc doesn't receive any UDP ping replies over the specified interval, -it will assume UDP communication is broken and will fall back to TCP. - -@cindex UDPInfoInterval -@item UDPInfoInterval = (5) -The minimum amount of time between sending periodic updates about UDP addresses, which are mostly useful for UDP hole punching. - @cindex UDPRcvBuf -@item UDPRcvBuf = (1048576) +@item UDPRcvBuf = (OS default) Sets the socket receive buffer size for the UDP socket, in bytes. -If set to zero, the default buffer size will be used by the operating system. -Note: this setting can have a significant impact on performance, especially raw throughput. +If unset, the default buffer size will be used by the operating system. @cindex UDPSndBuf -@item UDPSndBuf = (1048576) +@item UDPSndBuf = Pq OS default Sets the socket send buffer size for the UDP socket, in bytes. -If set to zero, the default buffer size will be used by the operating system. -Note: this setting can have a significant impact on performance, especially raw throughput. - -@cindex UPnP -@item UPnP = (no) -If this option is enabled then tinc will search for UPnP-IGD devices on the local network. -It will then create and maintain port mappings for tinc's listening TCP and UDP ports. -If set to "udponly", tinc will only create a mapping for its UDP (data) port, not for its TCP (metaconnection) port. -Note that tinc must have been built with miniupnpc support for this feature to be available. -Furthermore, be advised that enabling this can have security implications, because the miniupnpc library that -tinc uses might not be well-hardened with regard to malicious UPnP replies. - -@cindex UPnPDiscoverWait -@item UPnPDiscoverWait = (5) -The amount of time to wait for replies when probing the local network for UPnP devices. - -@cindex UPnPRefreshPeriod -@item UPnPRefreshPeriod = (5) -How often tinc will re-add the port mapping, in case it gets reset on the UPnP device. -This also controls the duration of the port mapping itself, which will be set to twice that duration. +If unset, the default buffer size will be used by the operating system. @end table @@ -1319,12 +1143,11 @@ Multiple Address variables can be specified, in which case each address will be tried until a working connection has been established. @cindex Cipher -@item Cipher = <@var{cipher}> (blowfish) -The symmetric cipher algorithm used to encrypt UDP packets using the legacy protocol. +@item Cipher = <@var{cipher}> (aes-256-cbc) +The symmetric cipher algorithm used to encrypt UDP packets. Any cipher supported by LibreSSL or OpenSSL is recognized. Furthermore, specifying "none" will turn off packet encryption. It is best to use only those ciphers which support CBC mode. -This option has no effect for connections using the SPTPS protocol, which always use AES-256-CTR. @cindex ClampMSS @item ClampMSS = (yes) @@ -1336,27 +1159,27 @@ Fragmentation Needed or Packet too Big messages are dropped by firewalls. @item Compression = <@var{level}> (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), -10 (fast LZO) and 11 (best LZO). +10 (fast lzo) and 11 (best lzo). @cindex Digest -@item Digest = <@var{digest}> (sha1) -The digest algorithm used to authenticate UDP packets using the legacy protocol. +@item Digest = <@var{digest}> (sha256) +The digest algorithm used to authenticate UDP packets. Any digest supported by LibreSSL or OpenSSL is recognized. Furthermore, specifying "none" will turn off packet authentication. -This option has no effect for connections using the SPTPS protocol, which always use HMAC-SHA-256. @cindex IndirectData @item IndirectData = (no) -When set to yes, other nodes which do not already have a meta connection to you -will not try to establish direct communication with you. -It is best to leave this option out or set it to no. +This option specifies whether other tinc daemons besides the one you +specified with ConnectTo can make a direct connection to you. This is +especially useful if you are behind a firewall and it is impossible to +make a connection from the outside to your tinc daemon. Otherwise, it +is best to leave this option out or set it to no. @cindex MACLength @item MACLength = <@var{bytes}> (4) -The length of the message authentication code used to authenticate UDP packets using the legacy protocol. +The length of the message authentication code used to authenticate UDP packets. Can be anything from 0 up to the length of the digest produced by the digest algorithm. -This option has no effect for connections using the SPTPS protocol, which never truncate MACs. @cindex PMTU @item PMTU = <@var{mtu}> (1514) @@ -1367,10 +1190,6 @@ This option controls the initial path MTU to this node. 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. -@cindex MTUInfoInterval -@item MTUInfoInterval = (5) -The minimum amount of time between sending periodic updates about relay path MTU. Useful for quickly determining MTU to indirect nodes. - @cindex Port @item Port = <@var{port}> (655) This is the port this tinc daemon listens on. @@ -1383,7 +1202,7 @@ This is the RSA public key for this host. @cindex PublicKeyFile @item PublicKeyFile = <@var{path}> [obsolete] This is the full path name of the RSA public key file that was generated -by @samp{tinc generate-keys}. It must be a full path, not a relative +by @samp{tincd --generate-keys}. It must be a full path, not a relative directory. @cindex PEM format @@ -1418,6 +1237,7 @@ example: netmask 255.255.255.0 would become /24, 255.255.252.0 becomes /22. This conforms to standard CIDR notation as described in @uref{https://www.ietf.org/rfc/rfc1519.txt, RFC1519} +@cindex Subnet weight A Subnet can be given a weight to indicate its priority over identical Subnets owned by different nodes. The default weight is 10. Lower values indicate higher priority. Packets will be sent to the node with the highest priority, @@ -1425,18 +1245,15 @@ unless that node is not reachable, in which case the node with the next highest priority will be tried, and so on. @cindex TCPonly -@item TCPonly = (no) +@item TCPonly = (no) [deprecated] If this variable is set to yes, then the packets are tunnelled over a TCP connection instead of a UDP connection. This is especially useful for those who want to run a tinc daemon from behind a masquerading firewall, or if UDP packet routing is disabled somehow. Setting this options also implicitly sets IndirectData. -@cindex Weight -@item Weight = -If this variable is set, it overrides the weight given to connections made with -another host. A higher weight means a lower priority is given to this -connection when broadcasting or forwarding packets. +Since version 1.0.10, tinc will automatically detect whether communication via +UDP is possible or not. @end table @@ -1455,7 +1272,7 @@ this means that tinc will temporarily stop processing packets until the called s This guarantees that scripts will execute in the exact same order as the events that trigger them. If you need to run commands asynchronously, you have to ensure yourself that they are being run in the background. -Under Windows (not Cygwin), the scripts should have the extension @file{.bat} or @file{.cmd}. +Under Windows (not Cygwin), the scripts must have the extension .bat. @table @file @cindex tinc-up @@ -1485,25 +1302,18 @@ This script is started when any host becomes reachable. This script is started when any host becomes unreachable. @item @value{sysconfdir}/tinc/@var{netname}/subnet-up -This script is started when a Subnet becomes reachable. +This script is started when a subnet becomes reachable. The Subnet and the node it belongs to are passed in environment variables. @item @value{sysconfdir}/tinc/@var{netname}/subnet-down -This script is started when a Subnet becomes unreachable. - -@item @value{sysconfdir}/tinc/@var{netname}/invitation-created -This script is started when a new invitation has been created. - -@item @value{sysconfdir}/tinc/@var{netname}/invitation-accepted -This script is started when an invitation has been used. - +This script is started when a subnet becomes unreachable. @end table @cindex environment variables The scripts are started without command line arguments, but can make use of certain environment variables. Under UNIX like operating systems the names of environment variables must be preceded by a $ in scripts. -Under Windows, in @file{.bat} or @file{.cmd} files, they have to be put between % signs. +Under Windows, in @file{.bat} files, they have to be put between % signs. @table @env @cindex NETNAME @@ -1545,122 +1355,57 @@ When a subnet becomes (un)reachable, this is set to the subnet. @item WEIGHT When a subnet becomes (un)reachable, this is set to the subnet weight. -@cindex INVITATION_FILE -@item INVITATION_FILE -When the @file{invitation-created} script is called, -this is set to the file where the invitation details will be stored. - -@cindex INVITATION_URL -@item INVITATION_URL -When the @file{invitation-created} script is called, -this is set to the invitation URL that has been created. @end table -Do not forget that under UNIX operating systems, -you have to make the scripts executable, using the command @samp{chmod a+x script}. - @c ================================================================== @node How to configure @subsection How to configure -@subsubheading Step 1. Creating initial configuration files. +@subsubheading Step 1. Creating the main configuration file -The initial directory structure, configuration files and public/private keypairs are created using the following command: +The main configuration file will be called @file{@value{sysconfdir}/tinc/@var{netname}/tinc.conf}. +Adapt the following example to create a basic configuration file: @example -tinc -n @var{netname} init @var{name} +Name = @var{yourname} +Device = @file{/dev/tap0} @end example -(You will need to run this as root, or use "sudo".) -This will create the configuration directory @file{@value{sysconfdir}/tinc/@var{netname}.}, -and inside it will create another directory named @file{hosts/}. -In the configuration directory, it will create the file @file{tinc.conf} with the following contents: +Then, if you know to which other tinc daemon(s) yours is going to connect, +add `ConnectTo' values. + +@subsubheading Step 2. Creating your host configuration file + +If you added a line containing `Name = yourname' in the main configuration file, +you will need to create a host configuration file @file{@value{sysconfdir}/tinc/@var{netname}/hosts/yourname}. +Adapt the following example to create a host configuration file: @example -Name = @var{name} +Address = your.real.hostname.org +Subnet = 192.168.1.0/24 @end example -It will also create private RSA and Ed25519 keys, which will be stored in the files @file{rsa_key.priv} and @file{ed25519_key.priv}. -It will also create a host configuration file @file{hosts/@var{name}}, -which will contain the corresponding public RSA and Ed25519 keys. +You can also use an IP address instead of a hostname. +The `Subnet' specifies the address range that is local for @emph{your part of the VPN only}. +If you have multiple address ranges you can specify more than one `Subnet'. +You might also need to add a `Port' if you want your tinc daemon to run on a different port number than the default (655). -Finally, on UNIX operating systems, it will create an executable script @file{tinc-up}, -which will initially not do anything except warning that you should edit it. -@subsubheading Step 2. Modifying the initial configuration. +@c ================================================================== +@node Generating keypairs +@section Generating keypairs -Unless you want to use tinc in switch mode, -you should now configure which range of addresses you will use on the VPN. -Let's assume you will be part of a VPN which uses the address range 192.168.0.0/16, -and you yourself have a smaller portion of that range: 192.168.2.0/24. -Then you should run the following command: +@cindex key generation +Now that you have already created the main configuration file and your host configuration file, +you can easily create a public/private keypair by entering the following command: @example -tinc -n @var{netname} add subnet 192.168.2.0/24 +tincd -n @var{netname} -K @end example -This will add a Subnet statement to your host configuration file. -Try opening the file @file{@value{sysconfdir}/tinc/@var{netname}/hosts/@var{name}} in an editor. -You should now see a file containing the public RSA and Ed25519 keys (which looks like a bunch of random characters), -and the following line at the bottom: - -@example -Subnet = 192.168.2.0/24 -@end example - -If you will use more than one address range, you can add more Subnets. -For example, if you also use the IPv6 subnet fec0:0:0:2::/64, you can add it as well: - -@example -tinc -n @var{netname} add subnet fec0:0:0:2::/24 -@end example - -This will add another line to the file @file{hosts/@var{name}}. -If you make a mistake, you can undo it by simply using @samp{del} instead of @samp{add}. - -If you want other tinc daemons to create meta-connections to your daemon, -you should add your public IP address or hostname to your host configuration file. -For example, if your hostname is foo.example.org, run: - -@example -tinc -n @var{netname} add address foo.example.org -@end example - -@subsubheading Step 2. Exchanging configuration files. - -In order for two tinc daemons to be able to connect to each other, -they each need the other's host configuration files. -So if you want foo to be able to connect with bar, -You should send @file{hosts/@var{name}} to bar, and bar should send you his file which you should move to @file{hosts/bar}. -If you are on a UNIX platform, you can easily send an email containing the necessary information using the following command -(assuming the owner of bar has the email address bar@@example.org): - -@example -tinc -n @var{netname} export | mail -s "My config file" bar@@example.org -@end example - -If the owner of bar does the same to send his host configuration file to you, -you can probably pipe his email through the following command, -or you can just start this command in a terminal and copy&paste the email: - -@example -tinc -n @var{netname} import -@end example - -If you are the owner of bar yourself, and you have SSH access to that computer, -you can also swap the host configuration files using the following command: - -@example -tinc -n @var{netname} export \ - | ssh bar.example.org tinc -n @var{netname} exchange \ - | tinc -n @var{netname} import -@end example - -You can repeat this for a few other nodes as well. -It is not necessary to manually exchange host config files between all nodes; -after the initial connections are made tinc will learn about all the other nodes in the VPN, -and will automatically make other connections as necessary. +Tinc will generate a public and a private key and ask you where to put them. +Just press enter to accept the defaults. @c ================================================================== @@ -1683,31 +1428,21 @@ You can configure the network interface by putting ordinary ifconfig, route, and to a script named @file{@value{sysconfdir}/tinc/@var{netname}/tinc-up}. When tinc starts, this script will be executed. When tinc exits, it will execute the script named @file{@value{sysconfdir}/tinc/@var{netname}/tinc-down}, but normally you don't need to create that script. -You can manually open the script in an editor, or use the following command: -@example -tinc -n @var{netname} edit tinc-up -@end example - -An example @file{tinc-up} script, that would be appropriate for the scenario in the previous section, is: +An example @file{tinc-up} script: @example #!/bin/sh -ifconfig $INTERFACE 192.168.2.1 netmask 255.255.0.0 -ip addr add fec0:0:0:2::/48 dev $INTERFACE +ifconfig $INTERFACE 192.168.1.1 netmask 255.255.0.0 @end example -The first command gives the interface an IPv4 address and a netmask. -The kernel will also automatically add an IPv4 route to this interface, so normally you don't need +This script gives the interface an IP address and a netmask. +The kernel will also automatically add a route to this interface, so normally you don't need to add route commands to the @file{tinc-up} script. The kernel will also bring the interface up after this command. @cindex netmask The netmask is the mask of the @emph{entire} VPN network, not just your own subnet. -The second command gives the interface an IPv6 address and netmask, -which will also automatically add an IPv6 route. -If you only want to use "ip addr" commands on Linux, don't forget that it doesn't bring the interface up, unlike ifconfig, -so you need to add @samp{ip link set $INTERFACE up} in that case. The exact syntax of the ifconfig and route commands differs from platform to platform. You can look up the commands for setting addresses and adding routes in @ref{Platform specific information}, @@ -1747,9 +1482,6 @@ the real interface is also shown as a comment, to give you an idea of how these example host is set up. All branches use the netname `company' for this particular VPN. -Each branch is set up using the @samp{tinc init} and @samp{tinc config} commands, -here we just show the end results: - @subsubheading For Branch A @emph{BranchA} would be configured like this: @@ -1757,8 +1489,6 @@ here we just show the end results: In @file{@value{sysconfdir}/tinc/company/tinc-up}: @example -#!/bin/sh - # Real interface of internal network: # ifconfig eth0 10.1.54.1 netmask 255.255.0.0 @@ -1769,6 +1499,7 @@ and in @file{@value{sysconfdir}/tinc/company/tinc.conf}: @example Name = BranchA +Device = /dev/tap0 @end example On all hosts, @file{@value{sysconfdir}/tinc/company/hosts/BranchA} contains: @@ -1782,9 +1513,9 @@ Address = 1.2.3.4 -----END RSA PUBLIC KEY----- @end example -Note that the IP addresses of eth0 and the VPN interface are the same. +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 both real internal network interfaces and VPN 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. @@ -1793,8 +1524,6 @@ since that will make things a lot easier to remember and set up. In @file{@value{sysconfdir}/tinc/company/tinc-up}: @example -#!/bin/sh - # Real interface of internal network: # ifconfig eth0 10.2.43.8 netmask 255.255.0.0 @@ -1805,10 +1534,12 @@ and in @file{@value{sysconfdir}/tinc/company/tinc.conf}: @example Name = BranchB +ConnectTo = BranchA @end example Note here that the internal address (on eth0) doesn't have to be the -same as on the VPN interface. +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}: @@ -1827,8 +1558,6 @@ Address = 2.3.4.5 In @file{@value{sysconfdir}/tinc/company/tinc-up}: @example -#!/bin/sh - # Real interface of internal network: # ifconfig eth0 10.3.69.254 netmask 255.255.0.0 @@ -1839,6 +1568,8 @@ and in @file{@value{sysconfdir}/tinc/company/tinc.conf}: @example Name = BranchC +ConnectTo = BranchA +Device = /dev/tap1 @end example C already has another daemon that runs on port 655, so they have to @@ -1863,8 +1594,6 @@ Port = 2000 In @file{@value{sysconfdir}/tinc/company/tinc-up}: @example -#!/bin/sh - # Real interface of internal network: # ifconfig eth0 10.4.3.32 netmask 255.255.0.0 @@ -1875,10 +1604,15 @@ and in @file{@value{sysconfdir}/tinc/company/tinc.conf}: @example Name = BranchD +ConnectTo = BranchC +Device = /dev/net/tun @end example D will be connecting to C, which has a tincd running for this network on port 2000. It knows the port number from the host configuration file. +Also note that since D uses the tun/tap driver, the network interface +will not be called `tun' or `tap0' or something like that, but will +have the same name as netname. On all hosts, in @file{@value{sysconfdir}/tinc/company/hosts/BranchD}: @@ -1893,11 +1627,16 @@ Address = 4.5.6.7 @subsubheading Key files -A, B, C and D all have their own public/private keypairs: +A, B, C and D all have generated a public/private keypair with the following command: -The private RSA key is stored in @file{@value{sysconfdir}/tinc/company/rsa_key.priv}, -the private Ed25519 key is stored in @file{@value{sysconfdir}/tinc/company/ed25519_key.priv}, -and the public RSA and Ed25519 keys are put into the host configuration file in the @file{@value{sysconfdir}/tinc/company/hosts/} directory. +@example +tincd -n company -K +@end example + +The private key is stored in @file{@value{sysconfdir}/tinc/company/rsa_key.priv}, +the public key is put into the host configuration file in the @file{@value{sysconfdir}/tinc/company/hosts/} directory. +During key generation, tinc automatically guesses the right filenames based on the -n option and +the Name directive in the @file{tinc.conf} file (if it is available). @subsubheading Starting @@ -1914,7 +1653,7 @@ their daemons, tinc will try connecting until they are available. If everything else is done, you can start tinc by typing the following command: @example -tinc -n @var{netname} start +tincd -n @var{netname} @end example @cindex daemon @@ -1957,6 +1696,12 @@ This will also disable the automatic restart mechanism for fatal errors. Set debug level to @var{level}. The higher the debug level, the more gets logged. Everything goes via syslog. +@item -k, --kill[=@var{signal}] +Attempt to kill a running tincd (optionally with the specified @var{signal} instead of SIGTERM) and exit. +Use it in conjunction with the -n option to make sure you kill the right tinc daemon. +Under native Windows the optional argument is ignored, +the service will always be stopped and removed. + @item -n, --net=@var{netname} Use configuration for net @var{netname}. This will let tinc read all configuration files from @@ -1964,10 +1709,11 @@ This will let tinc read all configuration files from Specifying . for @var{netname} is the same as not specifying any @var{netname}. @xref{Multiple networks}. -@item --pidfile=@var{filename} -Store a cookie in @var{filename} which allows tinc to authenticate. -If unspecified, the default is -@file{@value{runstatedir}/tinc.@var{netname}.pid}. +@item -K, --generate-keys[=@var{bits}] +Generate public/private keypair of @var{bits} length. If @var{bits} is not specified, +2048 is the default. tinc will ask where you want to store the files, +but will default to the configuration directory (you can use the -c or -n option +in combination with -K). After that, tinc will quit. @item -o, --option=[@var{HOST}.]@var{KEY}=@var{VALUE} Without specifying a @var{HOST}, this will set server configuration variable @var{KEY} to @var{VALUE}. @@ -1979,8 +1725,6 @@ This option can be used more than once to specify multiple configuration variabl Lock tinc into main memory. This will prevent sensitive data like shared private keys to be written to the system swap files/partitions. -This option is not supported on all platforms. - @item --logfile[=@var{file}] Write log entries to a file instead of to the system logging facility. If @var{file} is omitted, the default is @file{@value{localstatedir}/log/tinc.@var{netname}.log}. @@ -2008,14 +1752,11 @@ you must copy @file{/etc/resolv.conf} into the chroot directory. If you want to be able to run scripts other than @file{tinc-up} in the chroot, you must ensure the appropriate shell is also installed in the chroot, along with all its dependencies. -This option is not supported on all platforms. @item -U, --user=@var{user} Switch to the given @var{user} after initialization, at the same time as chroot is performed (see --chroot above). With this option tinc drops privileges, for added security. -This option is not supported on all platforms. - @item --help Display a short reminder of these runtime options and terminate. @@ -2048,6 +1789,19 @@ New outgoing connections specified in @file{tinc.conf} will be made. If the --logfile option is used, this will also close and reopen the log file, useful when log rotation is used. +@item INT +Temporarily increases debug level to 5. +Send this signal again to revert to the original level. + +@item USR1 +Dumps the connection list to syslog. + +@item USR2 +Dumps virtual network device statistics, all known nodes, edges and subnets to syslog. + +@item WINCH +Purges all information remembered about unreachable nodes. + @end table @c ================================================================== @@ -2111,7 +1865,7 @@ Do you have a firewall or a NAT device (a masquerading firewall or perhaps an AD If so, check that it allows TCP and UDP traffic on port 655. If it masquerades and the host running tinc is behind it, make sure that it forwards TCP and UDP traffic to port 655 to the host running tinc. You can add @samp{TCPOnly = yes} to your host config file to force tinc to only use a single TCP connection, -this works through most firewalls and NATs. +this works through most firewalls and NATs. Since version 1.0.10, tinc will automatically fall back to TCP if direct communication via UDP is not possible. @end itemize @@ -2210,8 +1964,6 @@ or if that is not the case, try changing the prefix length into /32. @itemize @item If you see this only sporadically, it is harmless and caused by a node sending packets using an old key. -@item If you see this often and another node is not reachable anymore, then a NAT (masquerading firewall) is changing the source address of UDP packets. -You can add @samp{TCPOnly = yes} to host configuration files to force all VPN traffic to go over a TCP connection. @end itemize @item Got bad/bogus/unauthorized REQUEST from foo (1.2.3.4 port 12345) @@ -2242,526 +1994,6 @@ Be sure to include the following information in your bugreport: @item The output of any command that fails to work as it should (like ping or traceroute). @end itemize -@c ================================================================== -@node Controlling tinc -@chapter Controlling tinc - -@cindex command line interface -You can start, stop, control and inspect a running tincd through the tinc -command. A quick example: - -@example -tinc -n @var{netname} reload -@end example - -@cindex shell -If tinc is started without a command, it will act as a shell; it will display a -prompt, and commands can be entered on the prompt. If tinc is compiled with -libreadline, history and command completion are available on the prompt. One -can also pipe a script containing commands through tinc. In that case, lines -starting with a # symbol will be ignored. - -@menu -* tinc runtime options:: -* tinc environment variables:: -* tinc commands:: -* tinc examples:: -* tinc top:: -@end menu - - -@c ================================================================== -@node tinc runtime options -@section tinc runtime options - -@c from the manpage -@table @option -@item -c, --config=@var{path} -Read configuration options from the directory @var{path}. The default is -@file{@value{sysconfdir}/tinc/@var{netname}/}. - -@item -n, --net=@var{netname} -Use configuration for net @var{netname}. @xref{Multiple networks}. - -@item --pidfile=@var{filename} -Use the cookie from @var{filename} to authenticate with a running tinc daemon. -If unspecified, the default is -@file{@value{runstatedir}/tinc.@var{netname}.pid}. - -@cindex batch -@item -b, --batch -Don't ask for anything (non-interactive mode). - -@item --force -Force some commands to work despite warnings. - -@item --help -Display a short reminder of runtime options and commands, then terminate. - -@item --version -Output version information and exit. - -@end table - -@c ================================================================== -@node tinc environment variables -@section tinc environment variables - -@table @env -@cindex NETNAME -@item NETNAME -If no netname is specified on the command line with the @option{-n} option, -the value of this environment variable is used. -@end table - -@c ================================================================== -@node tinc commands -@section tinc commands - -@c from the manpage -@table @code - -@cindex init -@item init [@var{name}] -Create initial configuration files and RSA and Ed25519 keypairs with default length. -If no @var{name} for this node is given, it will be asked for. - -@cindex get -@item get @var{variable} -Print the current value of configuration variable @var{variable}. -If more than one variable with the same name exists, -the value of each of them will be printed on a separate line. - -@cindex set -@item set @var{variable} @var{value} -Set configuration variable @var{variable} to the given @var{value}. -All previously existing configuration variables with the same name are removed. -To set a variable for a specific host, use the notation @var{host}.@var{variable}. - -@cindex add -@item add @var{variable} @var{value} -As above, but without removing any previously existing configuration variables. -If the variable already exists with the given value, nothing happens. - -@cindex del -@item del @var{variable} [@var{value}] -Remove configuration variables with the same name and @var{value}. -If no @var{value} is given, all configuration variables with the same name will be removed. - -@cindex edit -@item edit @var{filename} -Start an editor for the given configuration file. -You do not need to specify the full path to the file. - -@cindex export -@item export -Export the host configuration file of the local node to standard output. - -@cindex export-all -@item export-all -Export all host configuration files to standard output. - -@cindex import -@item import -Import host configuration file(s) generated by the tinc export command from standard input. -Already existing host configuration files are not overwritten unless the option --force is used. - -@cindex exchange -@item exchange -The same as export followed by import. - -@cindex exchange-all -@item exchange-all -The same as export-all followed by import. - -@cindex invite -@item invite @var{name} -Prepares an invitation for a new node with the given @var{name}, -and prints a short invitation URL that can be used with the join command. - -@cindex join -@item join [@var{URL}] -Join an existing VPN using an invitation URL created using the invite command. -If no @var{URL} is given, it will be read from standard input. - -@cindex start -@item start [tincd options] -Start @samp{tincd}, optionally with the given extra options. - -@cindex stop -@item stop -Stop @samp{tincd}. - -@cindex restart -@item restart [tincd options] -Restart @samp{tincd}, optionally with the given extra options. - -@cindex reload -@item reload -Partially rereads configuration files. Connections to hosts whose host -config files are removed are closed. New outgoing connections specified -in @file{tinc.conf} will be made. - -@cindex pid -@item pid -Shows the PID of the currently running @samp{tincd}. - -@cindex generate-keys -@item generate-keys [@var{bits}] -Generate both RSA and Ed25519 keypairs (see below) and exit. -tinc will ask where you want to store the files, but will default to the -configuration directory (you can use the -c or -n option). - -@cindex generate-ed25519-keys -@item generate-ed25519-keys -Generate public/private Ed25519 keypair and exit. - -@cindex generate-rsa-keys -@item generate-rsa-keys [@var{bits}] -Generate public/private RSA keypair and exit. If @var{bits} is omitted, the -default length will be 2048 bits. When saving keys to existing files, tinc -will not delete the old keys; you have to remove them manually. - -@cindex dump -@item dump [reachable] nodes -Dump a list of all known nodes in the VPN. -If the reachable keyword is used, only lists reachable nodes. - -@item dump edges -Dump a list of all known connections in the VPN. - -@item dump subnets -Dump a list of all known subnets in the VPN. - -@item dump connections -Dump a list of all meta connections with ourself. - -@cindex graph -@item dump graph | digraph -Dump a graph of the VPN in dotty format. -Nodes are colored according to their reachability: -red nodes are unreachable, orange nodes are indirectly reachable, green nodes are directly reachable. -Black nodes are either directly or indirectly reachable, but direct reachability has not been tried yet. - -@item dump invitations -Dump a list of outstanding invitations. -The filename of the invitation, as well as the name of the node that is being invited is shown for each invitation. - -@cindex info -@item info @var{node} | @var{subnet} | @var{address} -Show information about a particular @var{node}, @var{subnet} or @var{address}. -If an @var{address} is given, any matching subnet will be shown. - -@cindex purge -@item purge -Purges all information remembered about unreachable nodes. - -@cindex debug -@item debug @var{level} -Sets debug level to @var{level}. - -@cindex log -@item log [@var{level}] -Capture log messages from a running tinc daemon. -An optional debug level can be given that will be applied only for log messages sent to tinc. - -@cindex retry -@item retry -Forces tinc to try to connect to all uplinks immediately. -Usually tinc attempts to do this itself, -but increases the time it waits between the attempts each time it failed, -and if tinc didn't succeed to connect to an uplink the first time after it started, -it defaults to the maximum time of 15 minutes. - -@cindex disconnect -@item disconnect @var{node} -Closes the meta connection with the given @var{node}. - -@cindex top -@item top -If tinc is compiled with libcurses support, this will display live traffic statistics for all the known nodes, -similar to the UNIX top command. -See below for more information. - -@cindex pcap -@item pcap -Dump VPN traffic going through the local tinc node in pcap-savefile format to standard output, -from where it can be redirected to a file or piped through a program that can parse it directly, -such as tcpdump. - -@cindex network -@item network [@var{netname}] -If @var{netname} is given, switch to that network. -Otherwise, display a list of all networks for which configuration files exist. - -@cindex fsck -@item fsck -This will check the configuration files for possible problems, -such as unsafe file permissions, missing executable bit on script, -unknown and obsolete configuration variables, wrong public and/or private keys, and so on. - -When problems are found, this will be printed on a line with WARNING or ERROR in front of it. -Most problems must be corrected by the user itself, however in some cases (like file permissions and missing public keys), -tinc will ask if it should fix the problem. - -@cindex sign -@item sign [@var{filename}] -Sign a file with the local node's private key. -If no @var{filename} is given, the file is read from standard input. -The signed file is written to standard output. - -@cindex verify -@item verify @var{name} [@var{filename}] - -Check the signature of a file against a node's public key. -The @var{name} of the node must be given, -or can be "." to check against the local node's public key, -or "*" to allow a signature from any node whose public key is known. -If no @var{filename} is given, the file is read from standard input. -If the verification is successful, a copy of the input with the signature removed is written to standard output, and the exit code will be zero. -If the verification failed, nothing will be written to standard output, and the exit code will be non-zero. - -@end table - -@c ================================================================== -@node tinc examples -@section tinc examples - -Examples of some commands: - -@example -tinc -n vpn dump graph | circo -Txlib -tinc -n vpn pcap | tcpdump -r - -tinc -n vpn top -@end example - -Examples of changing the configuration using tinc: - -@example -tinc -n vpn init foo -tinc -n vpn add Subnet 192.168.1.0/24 -tinc -n vpn add bar.Address bar.example.com -tinc -n vpn set Mode switch -tinc -n vpn export | gpg --clearsign | mail -s "My config" vpnmaster@@example.com -@end example - -@c ================================================================== -@node tinc top -@section tinc top - -@cindex top -The top command connects to a running tinc daemon and repeatedly queries its per-node traffic counters. -It displays a list of all the known nodes in the left-most column, -and the amount of bytes and packets read from and sent to each node in the other columns. -By default, the information is updated every second. -The behaviour of the top command can be changed using the following keys: - -@table @key - -@item s -Change the interval between updates. -After pressing the @key{s} key, enter the desired interval in seconds, followed by enter. -Fractional seconds are honored. -Intervals lower than 0.1 seconds are not allowed. - -@item c -Toggle between displaying current traffic rates (in packets and bytes per second) -and cumulative traffic (total packets and bytes since the tinc daemon started). - -@item n -Sort the list of nodes by name. - -@item i -Sort the list of nodes by incoming amount of bytes. - -@item I -Sort the list of nodes by incoming amount of packets. - -@item o -Sort the list of nodes by outgoing amount of bytes. - -@item O -Sort the list of nodes by outgoing amount of packets. - -@item t -Sort the list of nodes by sum of incoming and outgoing amount of bytes. - -@item T -Sort the list of nodes by sum of incoming and outgoing amount of packets. - -@item b -Show amount of traffic in bytes. - -@item k -Show amount of traffic in kilobytes. - -@item M -Show amount of traffic in megabytes. - -@item G -Show amount of traffic in gigabytes. - -@item q -Quit. - -@end table - - -@c ================================================================== -@node Invitations -@chapter Invitations - -Invitations are an easy way to add new nodes to an existing VPN. Invitations -can be created on an existing node using the @code{tinc invite} command, which -generates a relatively short URL which can be given to someone else, who uses -the @code{tinc join} command to automatically set up tinc so it can connect to -the inviting node. The next sections describe how invitations actually work, -and how to further automate the invitations. - -@menu -* How invitations work:: -* Invitation file format:: -* Writing an invitation-created script:: -@end menu - - -@c ================================================================== -@node How invitations work -@section How invitations work - -When an invitation is created on a node (which from now on we will call the -server) using the @code{tinc invite} command, an invitation file is created -that contains all the information necessary for the invitee (which we will call -the client) to create its configuration files. The invitation file is stays on -the server, but a URL is generated that has enough information for the client -to contact the server and to retrieve the invitation file. The whole URL is -around 80 characters long and looks like this: - -@example -server.example.org:12345/cW1NhLHS-1WPFlcFio8ztYHvewTTKYZp8BjEKg3vbMtDz7w4 -@end example - -It is composed of four parts: - -@example -hostname : port / keyhash cookie -@end example - -The hostname and port tell the client how to reach the tinc daemon on the server. -The part after the slash looks like one blob, but is composed of two parts. -The keyhash is the hash of the public key of the server. -The cookie is a shared secret that identifies the client to the server. - -When the client connects to the server in order to join the VPN, the client and -server will exchange temporary public keys. The client verifies that the hash -of the server's public key matches the keyhash from the invitation URL. If -not, it will immediately exit with an error. Otherwise, an ECDH exchange will -happen so the client and server can communicate privately with each other. The -client will then present the cookie to the server. The server uses this to -look up the corresponding invitation file it generated earlier. If it exists, -it will send the invitation file to the client. The client will also create a -permanent public key, and send it to the server. After the exchange is -completed, the connection is broken. The server creates a host config file for -the client containing the client's permanent public key, and the client creates -tinc.conf, host config files and possibly a tinc-up script based on the -information in the invitation file. - -It is important that the invitation URL is kept secret until it is used; if -another person gets a copy of the invitation URL before the real client runs -the @code{tinc join} command, then that other person can try to join the VPN. - - -@c ================================================================== -@node Invitation file format -@section Invitation file format - -The contents of an invitation file that is generated by the @code{tinc invite} -command looks like this: - -@example -Name = client -Netname = vpn -ConnectTo = server -#-------------------------------------# -Name = server -Ed25519PublicKey = augbnwegoij123587... -Address = server.example.com -@end example - -The file is basically a concatenation of several host config blocks. Each host -config block starts with @code{Name = ...}. Lines that look like @code{#---#} -are not important, it just makes it easier for humans to read the file. -However, the first line of an invitation file @emph{must} always start with -@code{Name = ...}. - -The first host config block is always the one representing the invitee. So the -first Name statement determines the name that the invitee will get. From the -first block, the @file{tinc.conf} and @file{hosts/client} files will be -generated; the @code{tinc join} command on the client will automatically -separate statements based on whether they should be in @file{tinc.conf} or in a -host config file. Some statements are special and are treated differently: - -@table @asis -@item Netname = <@var{netname}> -This is a hint to the invitee which netname to use for the VPN. It is used if -the invitee did not already specify a netname, and if there is no pre-existing -configuration with the same netname. - -@cindex Ifconfig -@item Ifconfig = <@var{address}[/@var{netmask}] | dhcp | dhcp6 | slaac> -This is a hint for generating a @file{tinc-up} script. -If an address is specified, a command will be added to @file{tinc-up} so the VPN interface will be configured to have the given address. -If it is the word "dhcp", a command will be added to start a DHCP client on the VPN interface. -If it is the word dhcpv6, it will be a DHCPv6 client. -If it is "slaac", then it will add commands to enable IPv6 stateless address autoconfiguration. -It is also possible to specify a MAC address, in which case a command will be added to set the MAC address of the VPN interface. - -The exact commands added to the @file{tinc-up} script depends on the operating system the client is using. -Multiple Ifconfig statements can be specified, however one should only use one Ifconfig statement per address family. - -@cindex Route -@item Route = <@var{address}[/@var{netmask}]> [<@var{gateway}>] -This is a hint for generating a @file{tinc-up} script. -Route statements are similar to Ifconfig statements, but add routes instead of addresses. -These only allow IPv4 and IPv6 routes. -If no gateway address is specified, the route is directed to the VPN interface. -In general, a gateway is only necessary when running tinc in switch mode. -@end table - -Subsequent host config blocks are copied verbatim into their respective files -in @file{hosts/}. The invitation file generated by @code{tinc invite} will -normally only contain two blocks; one for the client and one for the server. - - -@c ================================================================== -@node Writing an invitation-created script -@section Writing an invitation-created script - -When an invitation is generated, the "invitation-created" script is called (if -it exists) right after the invitation file is written, but before the URL has -been written to stdout. This allows one to change the invitation file -automatically before the invitation URL is passed to the invitee. Here is an -example shell script that approximately recreates the default invitation file: - -@example -#!/bin/sh - -cat >$INVITATION_FILE <>$INVITATION_FILE -@end example - -You can add more ConnectTo statements, and change `tinc export` to `tinc -export-all` for example. But you can also use the script to automatically hand -out a Subnet to the invitee. Note that the script doesn't have to be a shell script, -you can use any language, it just has to be executable. - - @c ================================================================== @node Technical information @chapter Technical information @@ -2803,7 +2035,7 @@ There are two possible types of virtual network devices: and `tap' style, which are Ethernet devices and handle complete Ethernet frames. So when tinc reads an Ethernet frame from the device, it determines its -type. When tinc is in it's default routing mode, it can handle IPv4 and IPv6 +type. When tinc is in its default routing mode, it can handle IPv4 and IPv6 packets. Depending on the Subnet lines, it will send the packets off to their destination IP address. In the `switch' and `hub' mode, tinc will use broadcasts and MAC address discovery to deduce the destination of the packets. @@ -2834,7 +2066,7 @@ If the virtual network device is a `tun' device (a point-to-point tunnel), there is no problem for the kernel to accept a packet. However, if it is a `tap' device (this is the only available type on FreeBSD), the destination MAC address must match that of the virtual network interface. -If tinc is in it's default routing mode, ARP does not work, so the correct destination MAC +If tinc is in its default routing mode, ARP does not work, so the correct destination MAC can not be known by the sending host. Tinc solves this by letting the receiving end detect the MAC address of its own virtual network interface and overwriting the destination MAC address of the received packet. @@ -2896,7 +2128,7 @@ daemon started with the --bypass-security option and to read and write requests by hand, provided that one understands the numeric codes sent. -The authentication scheme is described in @ref{Security}. After a +The authentication scheme is described in @ref{Authentication protocol}. After a successful authentication, the server and the client will exchange all the information about other tinc daemons and subnets they know of, so that both sides (and all the other tinc daemons behind them) have their information @@ -2983,10 +2215,10 @@ destination. @cindex PING @cindex PONG @example -daemon message +daemon message ------------------------------------------------------------------ -origin PING -dest. PONG +origin PING +dest. PONG ------------------------------------------------------------------ @end example @@ -3014,30 +2246,31 @@ the tinc project after TINC. @cindex SVPN But in order to be ``immune'' to eavesdropping, you'll have to encrypt -your data. Because tinc is a @emph{Secure} VPN (SVPN) daemon, it does +your data. Because tinc is a @emph{Secure} VPN (SVPN) daemon, it does exactly that: encrypt. -However, encryption in itself does not prevent an attacker from modifying the encrypted data. -Therefore, tinc also authenticates the data. -Finally, tinc uses sequence numbers (which themselves are also authenticated) to prevent an attacker from replaying valid packets. - -Since version 1.1pre3, tinc has two protocols used to protect your data; the legacy protocol, and the new Simple Peer-to-Peer Security (SPTPS) protocol. -The SPTPS protocol is designed to address some weaknesses in the legacy protocol. -The new authentication protocol is used when two nodes connect to each other that both have the ExperimentalProtocol option set to yes, -otherwise the legacy protocol will be used. +Tinc by default uses blowfish encryption with 128 bit keys in CBC mode, 32 bit +sequence numbers and 4 byte long message authentication codes to make sure +eavesdroppers cannot get and cannot change any information at all from the +packets they can intercept. The encryption algorithm and message authentication +algorithm can be changed in the configuration. The length of the message +authentication codes is also adjustable. The length of the key for the +encryption algorithm is always the default length used by LibreSSL/OpenSSL. @menu -* Legacy authentication protocol:: -* Simple Peer-to-Peer Security:: +* Authentication protocol:: * Encryption of network packets:: * Security issues:: @end menu @c ================================================================== -@node Legacy authentication protocol -@subsection Legacy authentication protocol +@node Authentication protocol +@subsection Authentication protocol -@cindex legacy authentication protocol +@cindex authentication +A new scheme for authentication in tinc has been devised, which offers some +improvements over the protocol used in 1.0pre2 and 1.0pre3. Explanation is +below. @cindex ID @cindex META_KEY @@ -3051,50 +2284,28 @@ client server -client ID client 17.2 - | | +-> minor protocol version - | +----> major protocol version - +--------> name of tinc daemon +client ID client 12 + | +---> version + +-------> name of tinc daemon -server ID server 17.2 - | | +-> minor protocol version - | +----> major protocol version - +--------> name of tinc daemon +server ID server 12 + | +---> version + +-------> name of tinc daemon -client META_KEY 94 64 0 0 5f0823a93e35b69e...7086ec7866ce582b - | | | | \_________________________________/ - | | | | +-> RSAKEYLEN bits totally random string S1, - | | | | encrypted with server's public RSA key - | | | +-> compression level - | | +---> MAC length - | +------> digest algorithm NID - +---------> cipher algorithm NID +client META_KEY 5f0823a93e35b69e...7086ec7866ce582b + \_________________________________/ + +-> RSAKEYLEN bits totally random string S1, + encrypted with server's public RSA key -server META_KEY 94 64 0 0 6ab9c1640388f8f0...45d1a07f8a672630 - | | | | \_________________________________/ - | | | | +-> RSAKEYLEN bits totally random string S2, - | | | | encrypted with client's public RSA key - | | | +-> compression level - | | +---> MAC length - | +------> digest algorithm NID - +---------> cipher algorithm NID --------------------------------------------------------------------------- -@end example - -The protocol allows each side to specify encryption algorithms and parameters, -but in practice they are always fixed, since older versions of tinc did not -allow them to be different from the default values. The cipher is always -Blowfish in OFB mode, the digest is SHA1, but the MAC length is zero and no -compression is used. +server META_KEY 6ab9c1640388f8f0...45d1a07f8a672630 + \_________________________________/ + +-> RSAKEYLEN bits totally random string S2, + encrypted with client's public RSA key From now on: -@itemize -@item the client will symmetrically encrypt outgoing traffic using S1 -@item the server will symmetrically encrypt outgoing traffic using S2 -@end itemize + - the client will symmetrically encrypt outgoing traffic using S1 + - the server will symmetrically encrypt outgoing traffic using S2 -@example --------------------------------------------------------------------------- client CHALLENGE da02add1817c1920989ba6ae2a49cecbda0 \_________________________________/ +-> CHALLEN bits totally random string H1 @@ -3114,188 +2325,57 @@ their identity. Further information is exchanged. client ACK 655 123 0 | | +-> options - | +----> estimated weight - +--------> listening port of client + | +----> estimated weight + +--------> listening port of client server ACK 655 321 0 | | +-> options - | +----> estimated weight - +--------> listening port of server + | +----> estimated weight + +--------> listening port of server -------------------------------------------------------------------------- @end example -This legacy authentication protocol has several weaknesses, pointed out by security export Peter Gutmann. -First, data is encrypted with RSA without padding. -Padding schemes are designed to prevent attacks when the size of the plaintext is not equal to the size of the RSA key. -Tinc always encrypts random nonces that have the same size as the RSA key, so we do not believe this leads to a break of the security. -There might be timing or other side-channel attacks against RSA encryption and decryption, tinc does not employ any protection against those. -Furthermore, both sides send identical messages to each other, there is no distinction between server and client, -which could make a MITM attack easier. -However, no exploit is known in which a third party who is not already trusted by other nodes in the VPN could gain access. -Finally, the RSA keys are used to directly encrypt the session keys, which means that if the RSA keys are compromised, it is possible to decrypt all previous VPN traffic. -In other words, the legacy protocol does not provide perfect forward secrecy. +This new scheme has several improvements, both in efficiency and security. -@c ================================================================== -@node Simple Peer-to-Peer Security -@subsection Simple Peer-to-Peer Security -@cindex SPTPS +First of all, the server sends exactly the same kind of messages over the wire +as the client. The previous versions of tinc first authenticated the client, +and then the server. This scheme even allows both sides to send their messages +simultaneously, there is no need to wait for the other to send something first. +This means that any calculations that need to be done upon sending or receiving +a message can also be done in parallel. This is especially important when doing +RSA encryption/decryption. Given that these calculations are the main part of +the CPU time spent for the authentication, speed is improved by a factor 2. -The SPTPS protocol is designed to address the weaknesses in the legacy protocol. -SPTPS is based on TLS 1.2, but has been simplified: there is no support for exchanging public keys, and there is no cipher suite negotiation. -Instead, SPTPS always uses a very strong cipher suite: -peers authenticate each other using 521 bits ECC keys, -Diffie-Hellman using ephemeral 521 bits ECC keys is used to provide perfect forward secrecy (PFS), -AES-256-CTR is used for encryption, and HMAC-SHA-256 for message authentication. +Second, only one RSA encrypted message is sent instead of two. This reduces the +amount of information attackers can see (and thus use for a cryptographic +attack). It also improves speed by a factor two, making the total speedup a +factor 4. -Similar to TLS, messages are split up in records. -A complete logical record contains the following information: +Third, and most important: +The symmetric cipher keys are exchanged first, the challenge is done +afterwards. In the previous authentication scheme, because a man-in-the-middle +could pass the challenge/chal_reply phase (by just copying the messages between +the two real tinc daemons), but no information was exchanged that was really +needed to read the rest of the messages, the challenge/chal_reply phase was of +no real use. The man-in-the-middle was only stopped by the fact that only after +the ACK messages were encrypted with the symmetric cipher. Potentially, it +could even send it's own symmetric key to the server (if it knew the server's +public key) and read some of the metadata the server would send it (it was +impossible for the mitm to read actual network packets though). The new scheme +however prevents this. -@itemize -@item uint32_t seqno (network byte order) -@item uint16_t length (network byte order) -@item uint8_t type -@item opaque data[length] -@item opaque hmac[HMAC_SIZE] (HMAC over all preceding fields) -@end itemize +This new scheme makes sure that first of all, symmetric keys are exchanged. The +rest of the messages are then encrypted with the symmetric cipher. Then, each +side can only read received messages if they have their private key. The +challenge is there to let the other side know that the private key is really +known, because a challenge reply can only be sent back if the challenge is +decrypted correctly, and that can only be done with knowledge of the private +key. -Depending on whether SPTPS records are sent via TCP or UDP, either the seqno or the length field is omitted on the wire -(but they are still included in the calculation of the HMAC); -for TCP packets are guaranteed to arrive in-order so we can infer the seqno, but packets can be split or merged, so we still need the length field to determine the boundaries between records; -for UDP packets we know that there is exactly one record per packet, and we know the length of a packet, but packets can be dropped, duplicated and/or reordered, so we need to include the seqno. +Fourth: the first thing that is sent via the symmetric cipher encrypted +connection is a totally random string, so that there is no known plaintext (for +an attacker) in the beginning of the encrypted stream. -The type field is used to distinguish between application records or handshake records. -Types 0 to 127 are application records, type 128 is a handshake record, and types 129 to 255 are reserved. - -Before the initial handshake, no fields are encrypted, and the HMAC field is not present. -After the authentication handshake, the length (if present), type and data fields are encrypted, and the HMAC field is present. -For UDP packets, the seqno field is not encrypted, as it is used to determine the value of the counter used for encryption. - -The authentication consists of an exchange of Key EXchange, SIGnature and ACKnowledge messages, transmitted using type 128 records. - -Overview: - -@example -Initiator Responder ---------------------- -KEX -> - <- KEX -SIG -> - <- SIG - -...encrypt and HMAC using session keys from now on... - -App -> - <- App -... - ... - -...key renegotiation starts here... - -KEX -> - <- KEX -SIG -> - <- SIG -ACK -> - <- ACK - -...encrypt and HMAC using new session keys from now on... - -App -> - <- App -... - ... ---------------------- -@end example - -Note that the responder does not need to wait before it receives the first KEX message, -it can immediately send its own once it has accepted an incoming connection. - -Key EXchange message: - -@itemize -@item uint8_t kex_version (always 0 in this version of SPTPS) -@item opaque nonce[32] (random number) -@item opaque ecdh_key[ECDH_SIZE] -@end itemize - -SIGnature message: - -@itemize -@item opaque ecdsa_signature[ECDSA_SIZE] -@end itemize - -ACKnowledge message: - -@itemize -@item empty (only sent after key renegotiation) -@end itemize - -Remarks: - -@itemize -@item At the start, both peers generate a random nonce and an Elliptic Curve public key and send it to the other in the KEX message. -@item After receiving the other's KEX message, both KEX messages are concatenated (see below), - and the result is signed using ECDSA. - The result is sent to the other. -@item After receiving the other's SIG message, the signature is verified. - If it is correct, the shared secret is calculated from the public keys exchanged in the KEX message using the Elliptic Curve Diffie-Helman algorithm. -@item The shared secret key is expanded using a PRF. - Both nonces and the application specific label are also used as input for the PRF. -@item An ACK message is sent only when doing key renegotiation, and is sent using the old encryption keys. -@item The expanded key is used to key the encryption and HMAC algorithms. -@end itemize - -The signature is calculated over this string: - -@itemize -@item uint8_t initiator (0 = local peer, 1 = remote peer is initiator) -@item opaque remote_kex_message[1 + 32 + ECDH_SIZE] -@item opaque local_kex_message[1 + 32 + ECDH_SIZE] -@item opaque label[label_length] -@end itemize - -The PRF is calculated as follows: - -@itemize -@item A HMAC using SHA512 is used, the shared secret is used as the key. -@item For each block of 64 bytes, a HMAC is calculated. For block n: hmac[n] = - HMAC_SHA512(hmac[n - 1] + seed) -@item For the first block (n = 1), hmac[0] is given by HMAC_SHA512(zeroes + seed), - where zeroes is a block of 64 zero bytes. -@end itemize - -The seed is as follows: - -@itemize -@item const char[13] "key expansion" -@item opaque responder_nonce[32] -@item opaque initiator_nonce[32] -@item opaque label[label_length] -@end itemize - -The expanded key is used as follows: - -@itemize -@item opaque responder_cipher_key[CIPHER_KEYSIZE] -@item opaque responder_digest_key[DIGEST_KEYSIZE] -@item opaque initiator_cipher_key[CIPHER_KEYSIZE] -@item opaque initiator_digest_key[DIGEST_KEYSIZE] -@end itemize - -Where initiator_cipher_key is the key used by session initiator to encrypt -messages sent to the responder. - -When using 256 bits Ed25519 keys, the AES-256-CTR cipher and HMAC-SHA-256 digest algorithm, -the sizes are as follows: - -@example -ECDH_SIZE: 32 (= 256/8) -ECDSA_SIZE: 64 (= 2 * 256/8) -CIPHER_KEYSIZE: 48 (= 256/8 + 128/8) -DIGEST_KEYSIZE: 32 (= 256/8) -@end example - -Note that the cipher key also includes the initial value for the counter. @c ================================================================== @node Encryption of network packets @@ -3305,11 +2385,11 @@ Note that the cipher key also includes the initial value for the counter. A data packet can only be sent if the encryption key is known to both parties, and the connection is activated. If the encryption key is not known, a request is sent to the destination using the meta connection -to retrieve it. +to retrieve it. The packet is stored in a queue while waiting for the +key to arrive. @cindex UDP -The UDP packets can be either encrypted with the legacy protocol or with SPTPS. -In case of the legacy protocol, the UDP packet containing the network packet from the VPN has the following layout: +The UDP packet containing the network packet from the VPN has the following layout: @example ... | IP header | UDP header | seqno | VPN packet | MAC | UDP trailer @@ -3319,38 +2399,12 @@ In case of the legacy protocol, the UDP packet containing the network packet fro Encrypted with symmetric cipher @end example - - - So, the entire VPN packet is encrypted using a symmetric cipher, including a 32 bits sequence number that is added in front of the actual VPN packet, to act as a unique IV for each packet and to prevent replay attacks. A message authentication code -is added to the UDP packet to prevent alteration of packets. -Tinc by default encrypts network packets using Blowfish with 128 bit keys in CBC mode -and uses 4 byte long message authentication codes to make sure -eavesdroppers cannot get and cannot change any information at all from the -packets they can intercept. The encryption algorithm and message authentication -algorithm can be changed in the configuration. The length of the message -authentication codes is also adjustable. The length of the key for the -encryption algorithm is always the default length used by LibreSSL/OpenSSL. - -The SPTPS protocol is described in @ref{Simple Peer-to-Peer Security}. -For comparison, this is how SPTPS UDP packets look: - -@example -... | IP header | UDP header | seqno | type | VPN packet | MAC | UDP trailer - \__________________/\_____/ - | | - V +---> digest algorithm - Encrypted with symmetric cipher -@end example - -The difference is that the seqno is not encrypted, since the encryption cipher is used in CTR mode, -and therefore the seqno must be known before the packet can be decrypted. -Furthermore, the MAC is never truncated. -The SPTPS protocol always uses the AES-256-CTR cipher and HMAC-SHA-256 digest, -this cannot be changed. - +is added to the UDP packet to prevent alteration of packets. By default the +first 4 bytes of the digest are used for this, but this can be changed using +the MACLength configuration variable. @c ================================================================== @node Security issues @@ -3373,24 +2427,8 @@ On the 15th of September 2003, Peter Gutmann posted a security analysis of tinc 1.0.1. He argues that the 32 bit sequence number used by tinc is not a good IV, that tinc's default length of 4 bytes for the MAC is too short, and he doesn't like tinc's use of RSA during authentication. We do not know of a security hole -in the legacy protocol of tinc, but it is not as strong as TLS or IPsec. - -The Sweet32 attack affects versions of tinc prior to 1.0.30. - -On September 6th, 2018, Michael Yonly contacted us and provided -proof-of-concept code that allowed a remote attacker to create an -authenticated, one-way connection with a node, and also that there was a -possibility for a man-in-the-middle to force UDP packets from a node to be sent -in plaintext. The first issue was trivial to exploit on tinc versions prior to -1.0.30, but the changes in 1.0.30 to mitigate the Sweet32 attack made this -weakness much harder to exploit. These issues have been fixed in tinc 1.0.35. - -This version of tinc comes with an improved protocol, called Simple -Peer-to-Peer Security (SPTPS), which aims to be as strong as TLS with one of -the strongest cipher suites. None of the above security issues affected SPTPS. -However, be aware that SPTPS is only used between nodes running tinc 1.1pre* or -later, and in a VPN with nodes running different versions, the security might -only be as good as that of the oldest version. +in this version of tinc, but tinc's security is not as strong as TLS or IPsec. +We will address these issues in tinc 2.0. Cryptography is a hard thing to get right. We cannot make any guarantees. Time, review and feedback are the only things that can @@ -3422,7 +2460,7 @@ netmask should be such that it encompasses the entire VPN. For IPv4 addresses: -@multitable {Darwin (MacOS/X)} {ifconfig route add -bla network address netmask netmask prefixlength interface} +@multitable {Darwin (Mac OS X)} {ifconfig route add -bla network address netmask netmask prefixlength interface} @item Linux @tab @code{ifconfig} @var{interface} @var{address} @code{netmask} @var{netmask} @item Linux iproute2 @@ -3435,7 +2473,7 @@ For IPv4 addresses: @tab @code{ifconfig} @var{interface} @var{address} @code{netmask} @var{netmask} @item Solaris @tab @code{ifconfig} @var{interface} @var{address} @code{netmask} @var{netmask} -@item Darwin (MacOS/X) +@item Darwin (Mac OS X) @tab @code{ifconfig} @var{interface} @var{address} @code{netmask} @var{netmask} @item Windows @tab @code{netsh interface ip set address} @var{interface} @code{static} @var{address} @var{netmask} @@ -3443,7 +2481,7 @@ For IPv4 addresses: For IPv6 addresses: -@multitable {Darwin (MacOS/X)} {ifconfig route add -bla network address netmask netmask prefixlength interface} +@multitable {Darwin (Mac OS X)} {ifconfig route add -bla network address netmask netmask prefixlength interface} @item Linux @tab @code{ifconfig} @var{interface} @code{add} @var{address}@code{/}@var{prefixlength} @item FreeBSD @@ -3456,7 +2494,7 @@ For IPv6 addresses: @tab @code{ifconfig} @var{interface} @code{inet6 plumb up} @item @tab @code{ifconfig} @var{interface} @code{inet6 addif} @var{address} @var{address} -@item Darwin (MacOS/X) +@item Darwin (Mac OS X) @tab @code{ifconfig} @var{interface} @code{inet6} @var{address} @code{prefixlen} @var{prefixlength} @item Windows @tab @code{netsh interface ipv6 add address} @var{interface} @code{static} @var{address}/@var{prefixlength} @@ -3467,7 +2505,7 @@ continue to exist even if tinc quit, although this is normally not required. It can be useful to set up a tun/tap interface owned by a non-root user, so tinc can be started without needing any root privileges at all. -@multitable {Darwin (MacOS/X)} {ifconfig route add -bla network address netmask netmask prefixlength interface} +@multitable {Darwin (Mac OS X)} {ifconfig route add -bla network address netmask netmask prefixlength interface} @item Linux @tab @code{ip tuntap add dev} @var{interface} @code{mode} @var{tun|tap} @code{user} @var{username} @end multitable @@ -3485,7 +2523,7 @@ support this. Adding routes to IPv4 subnets: -@multitable {Darwin (MacOS/X)} {ifconfig route add -bla network address netmask netmask prefixlength interface} +@multitable {Darwin (Mac OS X)} {ifconfig route add -bla network address netmask netmask prefixlength interface} @item Linux @tab @code{route add -net} @var{network_address} @code{netmask} @var{netmask} @var{interface} @item Linux iproute2 @@ -3498,15 +2536,15 @@ Adding routes to IPv4 subnets: @tab @code{route add} @var{network_address}@code{/}@var{prefixlength} @var{local_address} @item Solaris @tab @code{route add} @var{network_address}@code{/}@var{prefixlength} @var{local_address} @code{-interface} -@item Darwin (MacOS/X) -@tab @code{route add} @var{network_address}@code{/}@var{prefixlength} @var{local_address} +@item Darwin (Mac OS X) +@tab @code{route add} @var{network_address}@code{/}@var{prefixlength} @code{-interface} @var{interface} @item Windows @tab @code{netsh routing ip add persistentroute} @var{network_address} @var{netmask} @var{interface} @var{local_address} @end multitable Adding routes to IPv6 subnets: -@multitable {Darwin (MacOS/X)} {ifconfig route add -bla network address netmask netmask prefixlength interface} +@multitable {Darwin (Mac OS X)} {ifconfig route add -bla network address netmask netmask prefixlength interface} @item Linux @tab @code{route add -A inet6} @var{network_address}@code{/}@var{prefixlength} @var{interface} @item Linux iproute2 @@ -3519,8 +2557,8 @@ Adding routes to IPv6 subnets: @tab @code{route add -inet6} @var{network_address} @var{local_address} @code{-prefixlen} @var{prefixlength} @item Solaris @tab @code{route add -inet6} @var{network_address}@code{/}@var{prefixlength} @var{local_address} @code{-interface} -@item Darwin (MacOS/X) -@tab ? +@item Darwin (Mac OS X) +@tab @code{route add -inet6} @var{network_address}@code{/}@var{prefixlength} @code{-interface} @var{interface} @item Windows @tab @code{netsh interface ipv6 add route} @var{network address}/@var{prefixlength} @var{interface} @end multitable @@ -3573,12 +2611,11 @@ distribution's way of starting tinc at boot time. @node Windows @subsection Windows -On Windows, if tinc is started with the @code{tinc start} command without using -the @code{-D} or @code{--no-detach} option, it will automatically register -itself as a service that is started at boot time. When tinc is stopped using -the @code{tinc stop} command, it will also automatically unregister itself. -Once tinc is registered as a service, it is also possible to stop and start -tinc using the Windows Services Manager. +On Windows, if tinc is started without the @code{-D} or @code{--no-detach} +option, it will automatically register itself as a service that is started at +boot time. When tinc is stopped using the @code{-k} or @code{--kill}, it will +also automatically unregister itself. Once tinc is registered as a service, it +is also possible to stop and start tinc using the Windows Services Manager. @c ================================================================== @node Other platforms diff --git a/doc/tincd.8.in b/doc/tincd.8.in index a14eb4e..bdccf9d 100644 --- a/doc/tincd.8.in +++ b/doc/tincd.8.in @@ -1,4 +1,4 @@ -.Dd 2013-01-14 +.Dd 2014-05-11 .Dt TINCD 8 .\" Manual page created by: .\" Ivo Timmermans @@ -8,15 +8,17 @@ .Nd tinc VPN daemon .Sh SYNOPSIS .Nm -.Op Fl cdDKnsoLRU +.Op Fl cdDkKnoLRU .Op Fl -config Ns = Ns Ar DIR .Op Fl -no-detach .Op Fl -debug Ns Op = Ns Ar LEVEL +.Op Fl -kill Ns Op = Ns Ar SIGNAL .Op Fl -net Ns = Ns Ar NETNAME +.Op Fl -generate-keys Ns Op = Ns Ar BITS .Op Fl -option Ns = Ns Ar [HOST.]KEY=VALUE .Op Fl -mlock .Op Fl -logfile Ns Op = Ns Ar FILE -.Op Fl -syslog +.Op Fl -pidfile Ns = Ns Ar FILE .Op Fl -bypass-security .Op Fl -chroot .Op Fl -user Ns = Ns Ar USER @@ -52,6 +54,14 @@ If not mentioned otherwise, this will show log messages on the standard error ou Increase debug level or set it to .Ar LEVEL (see below). +.It Fl k, -kill Ns Op = Ns Ar SIGNAL +Attempt to kill a running +.Nm +(optionally with the specified +.Ar SIGNAL +instead of SIGTERM) and exit. +Under Windows (not Cygwin) the optional argument is ignored, +the service will always be stopped and removed. .It Fl n, -net Ns = Ns Ar NETNAME Connect to net .Ar NETNAME . @@ -63,6 +73,13 @@ for .Ar NETNAME is the same as not specifying any .Ar NETNAME . +.It Fl K, -generate-keys Ns Op = Ns Ar BITS +Generate public/private RSA keypair and exit. +If +.Ar BITS +is omitted, the default length will be 2048 bits. +When saving keys to existing files, tinc will not delete the old keys, +you have to remove them manually. .It Fl o, -option Ns = Ns Ar [HOST.]KEY=VALUE Without specifying a .Ar HOST , @@ -82,25 +99,18 @@ This option can be used more than once to specify multiple configuration variabl .It Fl L, -mlock Lock tinc into main memory. This will prevent sensitive data like shared private keys to be written to the system swap files/partitions. -This option is not supported on all platforms. .It Fl -logfile Ns Op = Ns Ar FILE Write log entries to a file instead of to the system logging facility. If .Ar FILE is omitted, the default is .Pa @localstatedir@/log/tinc. Ns Ar NETNAME Ns Pa .log. -.It Fl s, -syslog -When this option is is set, tinc uses syslog instead of stderr in --no-detach mode. -.It Fl -pidfile Ns = Ns Ar FILENAME -Store a cookie in -.Ar FILENAME -which allows -.Xr tinc 8 -to authenticate. -If +.It Fl -pidfile Ns = Ns Ar FILE +Write PID to .Ar FILE -is omitted, the default is +instead of .Pa @runstatedir@/tinc. Ns Ar NETNAME Ns Pa .pid. +Under Windows this option will be ignored. .It Fl -bypass-security Disables encryption and authentication of the meta protocol. Only useful for debugging. @@ -108,12 +118,10 @@ Only useful for debugging. With this option tinc chroots into the directory where network config is located (@sysconfdir@/tinc/NETNAME if -n option is used, or to the directory specified with -c option) after initialization. -This option is not supported on all platforms. .It Fl U, -user Ns = Ns Ar USER setuid to the specified .Ar USER after initialization. -This option is not supported on all platforms. .It Fl -help Display short list of options. .It Fl -version @@ -143,6 +151,15 @@ If the .Fl -logfile option is used, this will also close and reopen the log file, useful when log rotation is used. +.It INT +Temporarily increases debug level to 5. +Send this signal again to revert to the original level. +.It USR1 +Dumps the connection list to syslog. +.It USR2 +Dumps virtual network device statistics, all known nodes, edges and subnets to syslog. +.It WINCH +Purges all information remembered about unreachable nodes. .El .Sh DEBUG LEVELS The tinc daemon can send a lot of messages to the syslog. @@ -189,7 +206,6 @@ If you find any bugs, report them to tinc@tinc-vpn.org. .Sh TODO A lot, especially security auditing. .Sh SEE ALSO -.Xr tinc 8 , .Xr tinc.conf 5 , .Pa https://www.tinc-vpn.org/ , .Pa http://www.cabal.org/ . diff --git a/doc/tincinclude.texi b/doc/tincinclude.texi index 6bb64ca..b784882 100644 --- a/doc/tincinclude.texi +++ b/doc/tincinclude.texi @@ -1,4 +1,4 @@ -@set VERSION 1.1pre17 +@set VERSION 1.0.36 @set PACKAGE tinc @set sysconfdir /etc @set localstatedir /var diff --git a/m4/ax_append_flag.m4 b/m4/ax_append_flag.m4 index 08f2e07..1d38b76 100644 --- a/m4/ax_append_flag.m4 +++ b/m4/ax_append_flag.m4 @@ -49,23 +49,21 @@ # modified version of the Autoconf Macro, you may extend this special # exception to the GPL to apply to your modified version as well. -#serial 6 +#serial 2 AC_DEFUN([AX_APPEND_FLAG], -[dnl -AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_SET_IF -AS_VAR_PUSHDEF([FLAGS], [m4_default($2,_AC_LANG_PREFIX[FLAGS])]) -AS_VAR_SET_IF(FLAGS,[ - AS_CASE([" AS_VAR_GET(FLAGS) "], - [*" $1 "*], [AC_RUN_LOG([: FLAGS already contains $1])], - [ - AS_VAR_APPEND(FLAGS,[" $1"]) - AC_RUN_LOG([: FLAGS="$FLAGS"]) - ]) - ], - [ - AS_VAR_SET(FLAGS,[$1]) - AC_RUN_LOG([: FLAGS="$FLAGS"]) - ]) +[AC_PREREQ(2.59)dnl for _AC_LANG_PREFIX +AS_VAR_PUSHDEF([FLAGS], [m4_default($2,_AC_LANG_PREFIX[FLAGS])])dnl +AS_VAR_SET_IF(FLAGS, + [case " AS_VAR_GET(FLAGS) " in + *" $1 "*) + AC_RUN_LOG([: FLAGS already contains $1]) + ;; + *) + AC_RUN_LOG([: FLAGS="$FLAGS $1"]) + AS_VAR_SET(FLAGS, ["AS_VAR_GET(FLAGS) $1"]) + ;; + esac], + [AS_VAR_SET(FLAGS,["$1"])]) AS_VAR_POPDEF([FLAGS])dnl ])dnl AX_APPEND_FLAG diff --git a/m4/ax_code_coverage.m4 b/m4/ax_code_coverage.m4 deleted file mode 100644 index 0934a44..0000000 --- a/m4/ax_code_coverage.m4 +++ /dev/null @@ -1,264 +0,0 @@ -# =========================================================================== -# https://www.gnu.org/software/autoconf-archive/ax_code_coverage.html -# =========================================================================== -# -# SYNOPSIS -# -# AX_CODE_COVERAGE() -# -# DESCRIPTION -# -# Defines CODE_COVERAGE_CPPFLAGS, CODE_COVERAGE_CFLAGS, -# CODE_COVERAGE_CXXFLAGS and CODE_COVERAGE_LIBS which should be included -# in the CPPFLAGS, CFLAGS CXXFLAGS and LIBS/LIBADD variables of every -# build target (program or library) which should be built with code -# coverage support. Also defines CODE_COVERAGE_RULES which should be -# substituted in your Makefile; and $enable_code_coverage which can be -# used in subsequent configure output. CODE_COVERAGE_ENABLED is defined -# and substituted, and corresponds to the value of the -# --enable-code-coverage option, which defaults to being disabled. -# -# Test also for gcov program and create GCOV variable that could be -# substituted. -# -# Note that all optimisation flags in CFLAGS must be disabled when code -# coverage is enabled. -# -# Usage example: -# -# configure.ac: -# -# AX_CODE_COVERAGE -# -# Makefile.am: -# -# @CODE_COVERAGE_RULES@ -# my_program_LIBS = ... $(CODE_COVERAGE_LIBS) ... -# my_program_CPPFLAGS = ... $(CODE_COVERAGE_CPPFLAGS) ... -# my_program_CFLAGS = ... $(CODE_COVERAGE_CFLAGS) ... -# my_program_CXXFLAGS = ... $(CODE_COVERAGE_CXXFLAGS) ... -# -# This results in a "check-code-coverage" rule being added to any -# Makefile.am which includes "@CODE_COVERAGE_RULES@" (assuming the module -# has been configured with --enable-code-coverage). Running `make -# check-code-coverage` in that directory will run the module's test suite -# (`make check`) and build a code coverage report detailing the code which -# was touched, then print the URI for the report. -# -# In earlier versions of this macro, CODE_COVERAGE_LDFLAGS was defined -# instead of CODE_COVERAGE_LIBS. They are both still defined, but use of -# CODE_COVERAGE_LIBS is preferred for clarity; CODE_COVERAGE_LDFLAGS is -# deprecated. They have the same value. -# -# This code was derived from Makefile.decl in GLib, originally licenced -# under LGPLv2.1+. -# -# LICENSE -# -# Copyright (c) 2012, 2016 Philip Withnall -# Copyright (c) 2012 Xan Lopez -# Copyright (c) 2012 Christian Persch -# Copyright (c) 2012 Paolo Borelli -# Copyright (c) 2012 Dan Winship -# Copyright (c) 2015 Bastien ROUCARIES -# -# This library is free software; you can redistribute it and/or modify it -# under the terms of the GNU Lesser General Public License as published by -# the Free Software Foundation; either version 2.1 of the License, or (at -# your option) any later version. -# -# This library is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser -# General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public License -# along with this program. If not, see . - -#serial 21 - -AC_DEFUN([AX_CODE_COVERAGE],[ - dnl Check for --enable-code-coverage - AC_REQUIRE([AC_PROG_SED]) - - # allow to override gcov location - AC_ARG_WITH([gcov], - [AS_HELP_STRING([--with-gcov[=GCOV]], [use given GCOV for coverage (GCOV=gcov).])], - [_AX_CODE_COVERAGE_GCOV_PROG_WITH=$with_gcov], - [_AX_CODE_COVERAGE_GCOV_PROG_WITH=gcov]) - - AC_MSG_CHECKING([whether to build with code coverage support]) - AC_ARG_ENABLE([code-coverage], - AS_HELP_STRING([--enable-code-coverage], - [Whether to enable code coverage support]),, - enable_code_coverage=no) - - AM_CONDITIONAL([CODE_COVERAGE_ENABLED], [test x$enable_code_coverage = xyes]) - AC_SUBST([CODE_COVERAGE_ENABLED], [$enable_code_coverage]) - AC_MSG_RESULT($enable_code_coverage) - - AS_IF([ test "$enable_code_coverage" = "yes" ], [ - # check for gcov - AC_CHECK_TOOL([GCOV], - [$_AX_CODE_COVERAGE_GCOV_PROG_WITH], - [:]) - AS_IF([test "X$GCOV" = "X:"], - [AC_MSG_ERROR([gcov is needed to do coverage])]) - AC_SUBST([GCOV]) - - dnl Check if gcc is being used - AS_IF([ test "$GCC" = "no" ], [ - AC_MSG_ERROR([not compiling with gcc, which is required for gcov code coverage]) - ]) - - AC_CHECK_PROG([LCOV], [lcov], [lcov]) - AC_CHECK_PROG([GENHTML], [genhtml], [genhtml]) - - AS_IF([ test -z "$LCOV" ], [ - AC_MSG_ERROR([To enable code coverage reporting you must have lcov installed]) - ]) - - AS_IF([ test -z "$GENHTML" ], [ - AC_MSG_ERROR([Could not find genhtml from the lcov package]) - ]) - - dnl Build the code coverage flags - dnl Define CODE_COVERAGE_LDFLAGS for backwards compatibility - CODE_COVERAGE_CPPFLAGS="-DNDEBUG" - CODE_COVERAGE_CFLAGS="-O0 -g -fprofile-arcs -ftest-coverage" - CODE_COVERAGE_CXXFLAGS="-O0 -g -fprofile-arcs -ftest-coverage" - CODE_COVERAGE_LIBS="-lgcov" - CODE_COVERAGE_LDFLAGS="$CODE_COVERAGE_LIBS" - - AC_SUBST([CODE_COVERAGE_CPPFLAGS]) - AC_SUBST([CODE_COVERAGE_CFLAGS]) - AC_SUBST([CODE_COVERAGE_CXXFLAGS]) - AC_SUBST([CODE_COVERAGE_LIBS]) - AC_SUBST([CODE_COVERAGE_LDFLAGS]) - - [CODE_COVERAGE_RULES_CHECK=' - -$(A''M_V_at)$(MAKE) $(AM_MAKEFLAGS) -k check - $(A''M_V_at)$(MAKE) $(AM_MAKEFLAGS) code-coverage-capture -'] - [CODE_COVERAGE_RULES_CAPTURE=' - $(code_coverage_v_lcov_cap)$(LCOV) $(code_coverage_quiet) $(addprefix --directory ,$(CODE_COVERAGE_DIRECTORY)) --capture --output-file "$(CODE_COVERAGE_OUTPUT_FILE).tmp" --test-name "$(call code_coverage_sanitize,$(PACKAGE_NAME)-$(PACKAGE_VERSION))" --no-checksum --compat-libtool $(CODE_COVERAGE_LCOV_SHOPTS) $(CODE_COVERAGE_LCOV_OPTIONS) - $(code_coverage_v_lcov_ign)$(LCOV) $(code_coverage_quiet) $(addprefix --directory ,$(CODE_COVERAGE_DIRECTORY)) --remove "$(CODE_COVERAGE_OUTPUT_FILE).tmp" "/tmp/*" $(CODE_COVERAGE_IGNORE_PATTERN) --output-file "$(CODE_COVERAGE_OUTPUT_FILE)" $(CODE_COVERAGE_LCOV_SHOPTS) $(CODE_COVERAGE_LCOV_RMOPTS) - -@rm -f $(CODE_COVERAGE_OUTPUT_FILE).tmp - $(code_coverage_v_genhtml)LANG=C $(GENHTML) $(code_coverage_quiet) $(addprefix --prefix ,$(CODE_COVERAGE_DIRECTORY)) --output-directory "$(CODE_COVERAGE_OUTPUT_DIRECTORY)" --title "$(PACKAGE_NAME)-$(PACKAGE_VERSION) Code Coverage" --legend --show-details "$(CODE_COVERAGE_OUTPUT_FILE)" $(CODE_COVERAGE_GENHTML_OPTIONS) - @echo "file://$(abs_builddir)/$(CODE_COVERAGE_OUTPUT_DIRECTORY)/index.html" -'] - [CODE_COVERAGE_RULES_CLEAN=' -clean: code-coverage-clean -distclean: code-coverage-clean -code-coverage-clean: - -$(LCOV) --directory $(top_builddir) -z - -rm -rf $(CODE_COVERAGE_OUTPUT_FILE) $(CODE_COVERAGE_OUTPUT_FILE).tmp $(CODE_COVERAGE_OUTPUT_DIRECTORY) - -find . \( -name "*.gcda" -o -name "*.gcno" -o -name "*.gcov" \) -delete -'] - ], [ - [CODE_COVERAGE_RULES_CHECK=' - @echo "Need to reconfigure with --enable-code-coverage" -'] - CODE_COVERAGE_RULES_CAPTURE="$CODE_COVERAGE_RULES_CHECK" - CODE_COVERAGE_RULES_CLEAN='' - ]) - -[CODE_COVERAGE_RULES=' -# Code coverage -# -# Optional: -# - CODE_COVERAGE_DIRECTORY: Top-level directory for code coverage reporting. -# Multiple directories may be specified, separated by whitespace. -# (Default: $(top_builddir)) -# - CODE_COVERAGE_OUTPUT_FILE: Filename and path for the .info file generated -# by lcov for code coverage. (Default: -# $(PACKAGE_NAME)-$(PACKAGE_VERSION)-coverage.info) -# - CODE_COVERAGE_OUTPUT_DIRECTORY: Directory for generated code coverage -# reports to be created. (Default: -# $(PACKAGE_NAME)-$(PACKAGE_VERSION)-coverage) -# - CODE_COVERAGE_BRANCH_COVERAGE: Set to 1 to enforce branch coverage, -# set to 0 to disable it and leave empty to stay with the default. -# (Default: empty) -# - CODE_COVERAGE_LCOV_SHOPTS_DEFAULT: Extra options shared between both lcov -# instances. (Default: based on $CODE_COVERAGE_BRANCH_COVERAGE) -# - CODE_COVERAGE_LCOV_SHOPTS: Extra options to shared between both lcov -# instances. (Default: $CODE_COVERAGE_LCOV_SHOPTS_DEFAULT) -# - CODE_COVERAGE_LCOV_OPTIONS_GCOVPATH: --gcov-tool pathtogcov -# - CODE_COVERAGE_LCOV_OPTIONS_DEFAULT: Extra options to pass to the -# collecting lcov instance. (Default: $CODE_COVERAGE_LCOV_OPTIONS_GCOVPATH) -# - CODE_COVERAGE_LCOV_OPTIONS: Extra options to pass to the collecting lcov -# instance. (Default: $CODE_COVERAGE_LCOV_OPTIONS_DEFAULT) -# - CODE_COVERAGE_LCOV_RMOPTS_DEFAULT: Extra options to pass to the filtering -# lcov instance. (Default: empty) -# - CODE_COVERAGE_LCOV_RMOPTS: Extra options to pass to the filtering lcov -# instance. (Default: $CODE_COVERAGE_LCOV_RMOPTS_DEFAULT) -# - CODE_COVERAGE_GENHTML_OPTIONS_DEFAULT: Extra options to pass to the -# genhtml instance. (Default: based on $CODE_COVERAGE_BRANCH_COVERAGE) -# - CODE_COVERAGE_GENHTML_OPTIONS: Extra options to pass to the genhtml -# instance. (Default: $CODE_COVERAGE_GENHTML_OPTIONS_DEFAULT) -# - CODE_COVERAGE_IGNORE_PATTERN: Extra glob pattern of files to ignore -# -# The generated report will be titled using the $(PACKAGE_NAME) and -# $(PACKAGE_VERSION). In order to add the current git hash to the title, -# use the git-version-gen script, available online. - -# Optional variables -CODE_COVERAGE_DIRECTORY ?= $(top_builddir) -CODE_COVERAGE_OUTPUT_FILE ?= $(PACKAGE_NAME)-$(PACKAGE_VERSION)-coverage.info -CODE_COVERAGE_OUTPUT_DIRECTORY ?= $(PACKAGE_NAME)-$(PACKAGE_VERSION)-coverage -CODE_COVERAGE_BRANCH_COVERAGE ?= -CODE_COVERAGE_LCOV_SHOPTS_DEFAULT ?= $(if $(CODE_COVERAGE_BRANCH_COVERAGE),\ ---rc lcov_branch_coverage=$(CODE_COVERAGE_BRANCH_COVERAGE)) -CODE_COVERAGE_LCOV_SHOPTS ?= $(CODE_COVERAGE_LCOV_SHOPTS_DEFAULT) -CODE_COVERAGE_LCOV_OPTIONS_GCOVPATH ?= --gcov-tool "$(GCOV)" -CODE_COVERAGE_LCOV_OPTIONS_DEFAULT ?= $(CODE_COVERAGE_LCOV_OPTIONS_GCOVPATH) -CODE_COVERAGE_LCOV_OPTIONS ?= $(CODE_COVERAGE_LCOV_OPTIONS_DEFAULT) -CODE_COVERAGE_LCOV_RMOPTS_DEFAULT ?= -CODE_COVERAGE_LCOV_RMOPTS ?= $(CODE_COVERAGE_LCOV_RMOPTS_DEFAULT) -CODE_COVERAGE_GENHTML_OPTIONS_DEFAULT ?=\ -$(if $(CODE_COVERAGE_BRANCH_COVERAGE),\ ---rc genhtml_branch_coverage=$(CODE_COVERAGE_BRANCH_COVERAGE)) -CODE_COVERAGE_GENHTML_OPTIONS ?= $(CODE_COVERAGE_GENHTML_OPTIONS_DEFAULTS) -CODE_COVERAGE_IGNORE_PATTERN ?= - -code_coverage_v_lcov_cap = $(code_coverage_v_lcov_cap_$(V)) -code_coverage_v_lcov_cap_ = $(code_coverage_v_lcov_cap_$(AM_DEFAULT_VERBOSITY)) -code_coverage_v_lcov_cap_0 = @echo " LCOV --capture"\ - $(CODE_COVERAGE_OUTPUT_FILE); -code_coverage_v_lcov_ign = $(code_coverage_v_lcov_ign_$(V)) -code_coverage_v_lcov_ign_ = $(code_coverage_v_lcov_ign_$(AM_DEFAULT_VERBOSITY)) -code_coverage_v_lcov_ign_0 = @echo " LCOV --remove /tmp/*"\ - $(CODE_COVERAGE_IGNORE_PATTERN); -code_coverage_v_genhtml = $(code_coverage_v_genhtml_$(V)) -code_coverage_v_genhtml_ = $(code_coverage_v_genhtml_$(AM_DEFAULT_VERBOSITY)) -code_coverage_v_genhtml_0 = @echo " GEN " $(CODE_COVERAGE_OUTPUT_DIRECTORY); -code_coverage_quiet = $(code_coverage_quiet_$(V)) -code_coverage_quiet_ = $(code_coverage_quiet_$(AM_DEFAULT_VERBOSITY)) -code_coverage_quiet_0 = --quiet - -# sanitizes the test-name: replaces with underscores: dashes and dots -code_coverage_sanitize = $(subst -,_,$(subst .,_,$(1))) - -# Use recursive makes in order to ignore errors during check -check-code-coverage:'"$CODE_COVERAGE_RULES_CHECK"' - -# Capture code coverage data -code-coverage-capture: code-coverage-capture-hook'"$CODE_COVERAGE_RULES_CAPTURE"' - -# Hook rule executed before code-coverage-capture, overridable by the user -code-coverage-capture-hook: - -'"$CODE_COVERAGE_RULES_CLEAN"' - -GITIGNOREFILES ?= -GITIGNOREFILES += $(CODE_COVERAGE_OUTPUT_FILE) $(CODE_COVERAGE_OUTPUT_DIRECTORY) - -A''M_DISTCHECK_CONFIGURE_FLAGS ?= -A''M_DISTCHECK_CONFIGURE_FLAGS += --disable-code-coverage - -.PHONY: check-code-coverage code-coverage-capture code-coverage-capture-hook code-coverage-clean -'] - - AC_SUBST([CODE_COVERAGE_RULES]) - m4_ifdef([_AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE([CODE_COVERAGE_RULES])]) -]) diff --git a/m4/curses.m4 b/m4/curses.m4 deleted file mode 100644 index 031e1ee..0000000 --- a/m4/curses.m4 +++ /dev/null @@ -1,44 +0,0 @@ -dnl Check to find the curses headers/libraries - -AC_DEFUN([tinc_CURSES], -[ - AC_ARG_ENABLE([curses], - AS_HELP_STRING([--disable-curses], [disable curses support])) - AS_IF([test "x$enable_curses" != "xno"], [ - AC_DEFINE(HAVE_CURSES, 1, [have curses support]) - curses=true - AC_ARG_WITH(curses, - AS_HELP_STRING([--with-curses=DIR], [curses base directory, or:]), - [curses="$withval" - CPPFLAGS="$CPPFLAGS -I$withval/include" - LDFLAGS="$LDFLAGS -L$withval/lib"] - ) - - AC_ARG_WITH(curses-include, - AS_HELP_STRING([--with-curses-include=DIR], [curses headers directory]), - [curses_include="$withval" - CPPFLAGS="$CPPFLAGS -I$withval"] - ) - - AC_ARG_WITH(curses-lib, - AS_HELP_STRING([--with-curses-lib=DIR], [curses library directory]), - [curses_lib="$withval" - LDFLAGS="$LDFLAGS -L$withval"] - ) - - AC_CHECK_HEADERS(curses.h, - [], - [AC_MSG_ERROR("curses header files not found."); break] - ) - - AC_CHECK_LIB(ncurses, initscr, - [CURSES_LIBS="-lncurses"; AC_CHECK_LIB(tinfo, wtimeout, [CURSES_LIBS+=" -ltinfo"], [])], - [AC_CHECK_LIB(curses, initscr, - [CURSES_LIBS="-lcurses"], - [AC_MSG_ERROR("curses libraries not found.")] - )] - ) - ]) - - AC_SUBST(CURSES_LIBS) -]) diff --git a/m4/libgcrypt.m4 b/m4/libgcrypt.m4 deleted file mode 100644 index 01c7478..0000000 --- a/m4/libgcrypt.m4 +++ /dev/null @@ -1,33 +0,0 @@ -dnl Check to find the libgcrypt headers/libraries - -AC_DEFUN([tinc_LIBGCRYPT], -[ - AC_ARG_WITH(libgcrypt, - AS_HELP_STRING([--with-libgcrypt=DIR], [libgcrypt base directory, or:]), - [libgcrypt="$withval" - CPPFLAGS="$CPPFLAGS -I$withval/include" - LDFLAGS="$LDFLAGS -L$withval/lib"] - ) - - AC_ARG_WITH(libgcrypt-include, - AS_HELP_STRING([--with-libgcrypt-include=DIR], [libgcrypt headers directory (without trailing /libgcrypt)]), - [libgcrypt_include="$withval" - CPPFLAGS="$CPPFLAGS -I$withval"] - ) - - AC_ARG_WITH(libgcrypt-lib, - AS_HELP_STRING([--with-libgcrypt-lib=DIR], [libgcrypt library directory]), - [libgcrypt_lib="$withval" - LDFLAGS="$LDFLAGS -L$withval"] - ) - - AC_CHECK_HEADERS([gcrypt.h], - [], - [AC_MSG_ERROR([libgcrypt header files not found.]); break] - ) - - AC_CHECK_LIB(gcrypt, gcry_cipher_encrypt, - [LIBS="-lgcrypt $LIBS"], - [AC_MSG_ERROR([libgcrypt libraries not found.])] - ) -]) diff --git a/m4/miniupnpc.m4 b/m4/miniupnpc.m4 deleted file mode 100644 index c2aca29..0000000 --- a/m4/miniupnpc.m4 +++ /dev/null @@ -1,40 +0,0 @@ -dnl Check to find the miniupnpc headers/libraries - -AC_DEFUN([tinc_MINIUPNPC], -[ - AC_ARG_ENABLE([miniupnpc], - AS_HELP_STRING([--enable-miniupnpc], [enable miniupnpc support])) - AS_IF([test "x$enable_miniupnpc" = "xyes"], [ - AC_DEFINE(HAVE_MINIUPNPC, 1, [have miniupnpc support]) - AC_ARG_WITH(miniupnpc, - AS_HELP_STRING([--with-miniupnpc=DIR], [miniupnpc base directory, or:]), - [miniupnpc="$withval" - CPPFLAGS="$CPPFLAGS -I$withval/include" - LDFLAGS="$LDFLAGS -L$withval/lib"] - ) - - AC_ARG_WITH(miniupnpc-include, - AS_HELP_STRING([--with-miniupnpc-include=DIR], [miniupnpc headers directory]), - [miniupnpc_include="$withval" - CPPFLAGS="$CPPFLAGS -I$withval"] - ) - - AC_ARG_WITH(miniupnpc-lib, - AS_HELP_STRING([--with-miniupnpc-lib=DIR], [miniupnpc library directory]), - [miniupnpc_lib="$withval" - LDFLAGS="$LDFLAGS -L$withval"] - ) - - AC_CHECK_HEADERS(miniupnpc/miniupnpc.h, - [], - [AC_MSG_ERROR("miniupnpc header files not found."); break] - ) - - AC_CHECK_LIB(miniupnpc, upnpDiscover, - [MINIUPNPC_LIBS="$LIBS -lminiupnpc"], - [AC_MSG_ERROR("miniupnpc libraries not found.")] - ) - ]) - - AC_SUBST(MINIUPNPC_LIBS) -]) diff --git a/m4/openssl.m4 b/m4/openssl.m4 index 0ff939b..895c31a 100644 --- a/m4/openssl.m4 +++ b/m4/openssl.m4 @@ -35,7 +35,7 @@ AC_DEFUN([tinc_OPENSSL], LDFLAGS="$LDFLAGS -L$withval"] ) - AC_CHECK_HEADERS([openssl/evp.h openssl/rsa.h openssl/rand.h openssl/err.h openssl/sha.h openssl/pem.h openssl/engine.h], + AC_CHECK_HEADERS(openssl/evp.h openssl/rsa.h openssl/rand.h openssl/err.h openssl/sha.h openssl/pem.h openssl/engine.h, [], [AC_MSG_ERROR([LibreSSL/OpenSSL header files not found.]); break] ) @@ -54,6 +54,5 @@ AC_DEFUN([tinc_OPENSSL], [#include ] ) - AC_CHECK_FUNCS([BN_GENCB_new ERR_remove_state RSA_set0_key], , , [#include ]) - AC_CHECK_FUNCS([HMAC_CTX_new], , , [#include ]) + AC_CHECK_FUNCS([BN_GENCB_new RSA_set0_key], , , [#include ]) ]) diff --git a/m4/readline.m4 b/m4/readline.m4 deleted file mode 100644 index f29e692..0000000 --- a/m4/readline.m4 +++ /dev/null @@ -1,42 +0,0 @@ -dnl Check to find the readline headers/libraries - -AC_DEFUN([tinc_READLINE], -[ - AC_ARG_ENABLE([readline], - AS_HELP_STRING([--disable-readline], [disable readline support])) - AS_IF([test "x$enable_readline" != "xno"], [ - AC_DEFINE(HAVE_READLINE, 1, [have readline support]) - readline=true - AC_ARG_WITH(readline, - AS_HELP_STRING([--with-readline=DIR], [readline base directory, or:]), - [readline="$withval" - CPPFLAGS="$CPPFLAGS -I$withval/include" - LDFLAGS="$LDFLAGS -L$withval/lib"] - ) - - AC_ARG_WITH(readline-include, - AS_HELP_STRING([--with-readline-include=DIR], [readline headers directory]), - [readline_include="$withval" - CPPFLAGS="$CPPFLAGS -I$withval"] - ) - - AC_ARG_WITH(readline-lib, - AS_HELP_STRING([--with-readline-lib=DIR], [readline library directory]), - [readline_lib="$withval" - LDFLAGS="$LDFLAGS -L$withval"] - ) - - AC_CHECK_HEADERS([readline/readline.h readline/history.h], - [], - [AC_MSG_ERROR("readline header files not found."); break] - ) - - AC_CHECK_LIB(readline, readline, - [READLINE_LIBS="-lreadline"], - [AC_MSG_ERROR("readline library not found.")], - [$CURSES_LIBS] - ) - ]) - - AC_SUBST(READLINE_LIBS) -]) diff --git a/src/Makefile.am b/src/Makefile.am index cb188d2..7b3dd97 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,174 +1,54 @@ ## Produce this file with automake to get Makefile.in -sbin_PROGRAMS = tincd tinc -check_PROGRAMS = sptps_test sptps_keypair -EXTRA_PROGRAMS = sptps_test sptps_keypair - -CLEANFILES = version_git.h - -.PHONY: version-stamp -version-stamp: - -version_git.h: version-stamp - $(AM_V_GEN)echo >$@ - @-(cd $(srcdir) && git describe 2>/dev/null >/dev/null) && echo '#define GIT_DESCRIPTION "'`(cd $(srcdir) && git describe) | sed 's/release-//'`'"' >$@ ||: -${srcdir}/version.c: version_git.h - -## Now a hack to appease some versions of BSD make that don't understand that "./foo" is the same as "foo". -if BSD -version.c: ${srcdir}/version.c -endif - -if LINUX -EXTRA_PROGRAMS += sptps_speed -endif - -ed25519_SOURCES = \ - ed25519/ed25519.h \ - ed25519/fe.c ed25519/fe.h \ - ed25519/fixedint.h \ - ed25519/ge.c ed25519/ge.h \ - ed25519/key_exchange.c \ - ed25519/keypair.c \ - ed25519/precomp_data.h \ - ed25519/sc.c ed25519/sc.h \ - ed25519/sha512.c ed25519/sha512.h \ - ed25519/sign.c \ - ed25519/verify.c - -chacha_poly1305_SOURCES = \ - chacha-poly1305/chacha.c chacha-poly1305/chacha.h \ - chacha-poly1305/chacha-poly1305.c chacha-poly1305/chacha-poly1305.h \ - chacha-poly1305/poly1305.c chacha-poly1305/poly1305.h +sbin_PROGRAMS = tincd tincd_SOURCES = \ - address_cache.c address_cache.h \ - autoconnect.c autoconnect.h \ - buffer.c buffer.h \ - cipher.h \ + have.h \ + system.h \ + avl_tree.c avl_tree.h \ conf.c conf.h \ connection.c connection.h \ - control.c control.h \ - control_common.h \ - crypto.h \ device.h \ - digest.h \ dropin.c dropin.h \ dummy_device.c \ - ecdh.h \ - ecdsa.h \ - ecdsagen.h \ edge.c edge.h \ ethernet.h \ event.c event.h \ - fd_device.c \ + fake-getaddrinfo.c fake-getaddrinfo.h \ + fake-getnameinfo.c fake-getnameinfo.h \ graph.c graph.h \ - hash.c hash.h \ - have.h \ ipv4.h \ ipv6.h \ list.c list.h \ logger.c logger.h \ meta.c meta.h \ multicast_device.c \ - names.c names.h \ net.c net.h \ net_packet.c \ net_setup.c \ net_socket.c \ netutl.c netutl.h \ node.c node.h \ - prf.h \ + pidfile.c pidfile.h \ process.c process.h \ protocol.c protocol.h \ protocol_auth.c \ protocol_edge.c \ - protocol_key.c \ protocol_misc.c \ + protocol_key.c \ protocol_subnet.c \ + proxy.c proxy.h \ raw_socket_device.c \ route.c route.h \ - rsa.h \ - rsagen.h \ - script.c script.h \ - splay_tree.c splay_tree.h \ - sptps.c sptps.h \ subnet.c subnet.h \ - subnet_parse.c \ - system.h \ tincd.c \ utils.c utils.h \ - xalloc.h \ - version.c version.h \ - ed25519/ecdh.c \ - ed25519/ecdsa.c \ - $(ed25519_SOURCES) \ - $(chacha_poly1305_SOURCES) - -tinc_SOURCES = \ - dropin.c dropin.h \ - fsck.c fsck.h \ - ifconfig.c ifconfig.h \ - info.c info.h \ - invitation.c invitation.h \ - list.c list.h \ - names.c names.h \ - netutl.c netutl.h \ - script.c script.h \ - sptps.c sptps.h \ - subnet_parse.c subnet.h \ - tincctl.c tincctl.h \ - top.c top.h \ - utils.c utils.h \ - version.c version.h \ - ed25519/ecdh.c \ - ed25519/ecdsa.c \ - ed25519/ecdsagen.c \ - $(ed25519_SOURCES) \ - $(chacha_poly1305_SOURCES) - -sptps_test_SOURCES = \ - logger.c logger.h \ - sptps.c sptps.h \ - sptps_test.c \ - utils.c utils.h \ - ed25519/ecdh.c \ - ed25519/ecdsa.c \ - $(ed25519_SOURCES) \ - $(chacha_poly1305_SOURCES) - -sptps_keypair_SOURCES = \ - sptps_keypair.c \ - utils.c utils.h \ - ed25519/ecdsagen.c \ - $(ed25519_SOURCES) - -sptps_speed_SOURCES = \ - logger.c logger.h \ - sptps.c sptps.h \ - sptps_speed.c \ - utils.c utils.h \ - ed25519/ecdh.c \ - ed25519/ecdsa.c \ - ed25519/ecdsagen.c \ - $(ed25519_SOURCES) \ - $(chacha_poly1305_SOURCES) - -## Conditionally compile device drivers + xalloc.h if !GETOPT tincd_SOURCES += \ getopt.c getopt.h \ getopt1.c -tinc_SOURCES += \ - getopt.c getopt.h \ - getopt1.c -sptps_test_SOURCES += \ - getopt.c getopt.h \ - getopt1.c -sptps_keypair_SOURCES += \ - getopt.c getopt.h \ - getopt1.c endif if LINUX @@ -202,88 +82,8 @@ if VDE tincd_SOURCES += vde_device.c endif -if OPENSSL -tincd_SOURCES += \ - openssl/cipher.c \ - openssl/crypto.c \ - openssl/digest.c openssl/digest.h \ - openssl/prf.c \ - openssl/rsa.c -tinc_SOURCES += \ - openssl/cipher.c \ - openssl/crypto.c \ - openssl/digest.c openssl/digest.h \ - openssl/prf.c \ - openssl/rsa.c \ - openssl/rsagen.c -sptps_test_SOURCES += \ - openssl/crypto.c \ - openssl/digest.c openssl/digest.h \ - openssl/prf.c -sptps_keypair_SOURCES += \ - openssl/crypto.c -sptps_speed_SOURCES += \ - openssl/crypto.c \ - openssl/digest.c openssl/digest.h \ - openssl/prf.c -else -if GCRYPT -tincd_SOURCES += \ - gcrypt/cipher.c \ - gcrypt/crypto.c \ - gcrypt/digest.c gcrypt/digest.h \ - gcrypt/prf.c \ - gcrypt/rsa.c -tinc_SOURCES += \ - gcrypt/cipher.c \ - gcrypt/crypto.c \ - gcrypt/digest.c gcrypt/digest.h \ - gcrypt/prf.c \ - gcrypt/rsa.c \ - gcrypt/rsagen.c -sptps_test_SOURCES += \ - gcrypt/cipher.c \ - gcrypt/crypto.c \ - gcrypt/digest.c gcrypt/digest.h \ - gcrypt/prf.c -sptps_keypair_SOURCES += \ - openssl/crypto.c -sptps_speed_SOURCES += \ - openssl/crypto.c \ - openssl/digest.c openssl/digest.h \ - openssl/prf.c -else -tincd_SOURCES += \ - nolegacy/crypto.c \ - nolegacy/prf.c -tinc_SOURCES += \ - nolegacy/crypto.c \ - nolegacy/prf.c -sptps_test_SOURCES += \ - nolegacy/crypto.c \ - nolegacy/prf.c -sptps_keypair_SOURCES += \ - nolegacy/crypto.c -sptps_speed_SOURCES += \ - nolegacy/crypto.c \ - nolegacy/prf.c -endif -endif - -if MINIUPNPC -tincd_SOURCES += upnp.h upnp.c -tincd_LDADD = $(MINIUPNPC_LIBS) -tincd_LDFLAGS = -pthread -endif - -tinc_LDADD = $(READLINE_LIBS) $(CURSES_LIBS) -sptps_speed_LDADD = -lrt - -LIBS = @LIBS@ -lm $(CODE_COVERAGE_LIBS) - if TUNEMU LIBS += -lpcap endif -AM_CFLAGS = -DCONFDIR=\"$(sysconfdir)\" -DRUNSTATEDIR=\"$(runstatedir)\" -DLOCALSTATEDIR=\"$(localstatedir)\" -DSBINDIR=\"$(sbindir)\" -iquote. $(CODE_COVERAGE_CFLAGS) -AM_CPPFLAGS = $(CODE_COVERAGE_CPPFLAGS) +AM_CPPFLAGS = -DCONFDIR=\"$(sysconfdir)\" -DRUNSTATEDIR=\"$(runstatedir)\" -DLOCALSTATEDIR=\"$(localstatedir)\" -I $(abs_top_builddir)/ diff --git a/src/Makefile.in b/src/Makefile.in index 6651ad9..93039a2 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -88,113 +88,20 @@ PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ -sbin_PROGRAMS = tincd$(EXEEXT) tinc$(EXEEXT) -check_PROGRAMS = sptps_test$(EXEEXT) sptps_keypair$(EXEEXT) -EXTRA_PROGRAMS = sptps_test$(EXEEXT) sptps_keypair$(EXEEXT) \ - $(am__EXEEXT_1) -@LINUX_TRUE@am__append_1 = sptps_speed -@GETOPT_FALSE@am__append_2 = \ +sbin_PROGRAMS = tincd$(EXEEXT) +@GETOPT_FALSE@am__append_1 = \ @GETOPT_FALSE@ getopt.c getopt.h \ @GETOPT_FALSE@ getopt1.c -@GETOPT_FALSE@am__append_3 = \ -@GETOPT_FALSE@ getopt.c getopt.h \ -@GETOPT_FALSE@ getopt1.c - -@GETOPT_FALSE@am__append_4 = \ -@GETOPT_FALSE@ getopt.c getopt.h \ -@GETOPT_FALSE@ getopt1.c - -@GETOPT_FALSE@am__append_5 = \ -@GETOPT_FALSE@ getopt.c getopt.h \ -@GETOPT_FALSE@ getopt1.c - -@LINUX_TRUE@am__append_6 = linux/device.c -@BSD_TRUE@am__append_7 = bsd/device.c -@BSD_TRUE@@TUNEMU_TRUE@am__append_8 = bsd/tunemu.c bsd/tunemu.h -@SOLARIS_TRUE@am__append_9 = solaris/device.c -@MINGW_TRUE@am__append_10 = mingw/device.c mingw/common.h -@CYGWIN_TRUE@am__append_11 = cygwin/device.c -@UML_TRUE@am__append_12 = uml_device.c -@VDE_TRUE@am__append_13 = vde_device.c -@OPENSSL_TRUE@am__append_14 = \ -@OPENSSL_TRUE@ openssl/cipher.c \ -@OPENSSL_TRUE@ openssl/crypto.c \ -@OPENSSL_TRUE@ openssl/digest.c openssl/digest.h \ -@OPENSSL_TRUE@ openssl/prf.c \ -@OPENSSL_TRUE@ openssl/rsa.c - -@OPENSSL_TRUE@am__append_15 = \ -@OPENSSL_TRUE@ openssl/cipher.c \ -@OPENSSL_TRUE@ openssl/crypto.c \ -@OPENSSL_TRUE@ openssl/digest.c openssl/digest.h \ -@OPENSSL_TRUE@ openssl/prf.c \ -@OPENSSL_TRUE@ openssl/rsa.c \ -@OPENSSL_TRUE@ openssl/rsagen.c - -@OPENSSL_TRUE@am__append_16 = \ -@OPENSSL_TRUE@ openssl/crypto.c \ -@OPENSSL_TRUE@ openssl/digest.c openssl/digest.h \ -@OPENSSL_TRUE@ openssl/prf.c - -@OPENSSL_TRUE@am__append_17 = \ -@OPENSSL_TRUE@ openssl/crypto.c - -@OPENSSL_TRUE@am__append_18 = \ -@OPENSSL_TRUE@ openssl/crypto.c \ -@OPENSSL_TRUE@ openssl/digest.c openssl/digest.h \ -@OPENSSL_TRUE@ openssl/prf.c - -@GCRYPT_TRUE@@OPENSSL_FALSE@am__append_19 = \ -@GCRYPT_TRUE@@OPENSSL_FALSE@ gcrypt/cipher.c \ -@GCRYPT_TRUE@@OPENSSL_FALSE@ gcrypt/crypto.c \ -@GCRYPT_TRUE@@OPENSSL_FALSE@ gcrypt/digest.c gcrypt/digest.h \ -@GCRYPT_TRUE@@OPENSSL_FALSE@ gcrypt/prf.c \ -@GCRYPT_TRUE@@OPENSSL_FALSE@ gcrypt/rsa.c - -@GCRYPT_TRUE@@OPENSSL_FALSE@am__append_20 = \ -@GCRYPT_TRUE@@OPENSSL_FALSE@ gcrypt/cipher.c \ -@GCRYPT_TRUE@@OPENSSL_FALSE@ gcrypt/crypto.c \ -@GCRYPT_TRUE@@OPENSSL_FALSE@ gcrypt/digest.c gcrypt/digest.h \ -@GCRYPT_TRUE@@OPENSSL_FALSE@ gcrypt/prf.c \ -@GCRYPT_TRUE@@OPENSSL_FALSE@ gcrypt/rsa.c \ -@GCRYPT_TRUE@@OPENSSL_FALSE@ gcrypt/rsagen.c - -@GCRYPT_TRUE@@OPENSSL_FALSE@am__append_21 = \ -@GCRYPT_TRUE@@OPENSSL_FALSE@ gcrypt/cipher.c \ -@GCRYPT_TRUE@@OPENSSL_FALSE@ gcrypt/crypto.c \ -@GCRYPT_TRUE@@OPENSSL_FALSE@ gcrypt/digest.c gcrypt/digest.h \ -@GCRYPT_TRUE@@OPENSSL_FALSE@ gcrypt/prf.c - -@GCRYPT_TRUE@@OPENSSL_FALSE@am__append_22 = \ -@GCRYPT_TRUE@@OPENSSL_FALSE@ openssl/crypto.c - -@GCRYPT_TRUE@@OPENSSL_FALSE@am__append_23 = \ -@GCRYPT_TRUE@@OPENSSL_FALSE@ openssl/crypto.c \ -@GCRYPT_TRUE@@OPENSSL_FALSE@ openssl/digest.c openssl/digest.h \ -@GCRYPT_TRUE@@OPENSSL_FALSE@ openssl/prf.c - -@GCRYPT_FALSE@@OPENSSL_FALSE@am__append_24 = \ -@GCRYPT_FALSE@@OPENSSL_FALSE@ nolegacy/crypto.c \ -@GCRYPT_FALSE@@OPENSSL_FALSE@ nolegacy/prf.c - -@GCRYPT_FALSE@@OPENSSL_FALSE@am__append_25 = \ -@GCRYPT_FALSE@@OPENSSL_FALSE@ nolegacy/crypto.c \ -@GCRYPT_FALSE@@OPENSSL_FALSE@ nolegacy/prf.c - -@GCRYPT_FALSE@@OPENSSL_FALSE@am__append_26 = \ -@GCRYPT_FALSE@@OPENSSL_FALSE@ nolegacy/crypto.c \ -@GCRYPT_FALSE@@OPENSSL_FALSE@ nolegacy/prf.c - -@GCRYPT_FALSE@@OPENSSL_FALSE@am__append_27 = \ -@GCRYPT_FALSE@@OPENSSL_FALSE@ nolegacy/crypto.c - -@GCRYPT_FALSE@@OPENSSL_FALSE@am__append_28 = \ -@GCRYPT_FALSE@@OPENSSL_FALSE@ nolegacy/crypto.c \ -@GCRYPT_FALSE@@OPENSSL_FALSE@ nolegacy/prf.c - -@MINIUPNPC_TRUE@am__append_29 = upnp.h upnp.c -@TUNEMU_TRUE@am__append_30 = -lpcap +@LINUX_TRUE@am__append_2 = linux/device.c +@BSD_TRUE@am__append_3 = bsd/device.c +@BSD_TRUE@@TUNEMU_TRUE@am__append_4 = bsd/tunemu.c bsd/tunemu.h +@SOLARIS_TRUE@am__append_5 = solaris/device.c +@MINGW_TRUE@am__append_6 = mingw/device.c mingw/common.h +@CYGWIN_TRUE@am__append_7 = cygwin/device.c +@UML_TRUE@am__append_8 = uml_device.c +@VDE_TRUE@am__append_9 = vde_device.c +@TUNEMU_TRUE@am__append_10 = -lpcap subdir = src ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \ @@ -202,12 +109,9 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \ $(top_srcdir)/m4/ax_cflags_warn_all.m4 \ $(top_srcdir)/m4/ax_check_compile_flag.m4 \ $(top_srcdir)/m4/ax_check_link_flag.m4 \ - $(top_srcdir)/m4/ax_code_coverage.m4 \ - $(top_srcdir)/m4/ax_require_defined.m4 \ - $(top_srcdir)/m4/curses.m4 $(top_srcdir)/m4/libgcrypt.m4 \ - $(top_srcdir)/m4/lzo.m4 $(top_srcdir)/m4/miniupnpc.m4 \ - $(top_srcdir)/m4/openssl.m4 $(top_srcdir)/m4/readline.m4 \ - $(top_srcdir)/m4/zlib.m4 $(top_srcdir)/configure.ac + $(top_srcdir)/m4/ax_require_defined.m4 $(top_srcdir)/m4/lzo.m4 \ + $(top_srcdir)/m4/openssl.m4 $(top_srcdir)/m4/zlib.m4 \ + $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) @@ -215,202 +119,51 @@ mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = -@LINUX_TRUE@am__EXEEXT_1 = sptps_speed$(EXEEXT) am__installdirs = "$(DESTDIR)$(sbindir)" PROGRAMS = $(sbin_PROGRAMS) -am__sptps_keypair_SOURCES_DIST = sptps_keypair.c utils.c utils.h \ - ed25519/ecdsagen.c ed25519/ed25519.h ed25519/fe.c ed25519/fe.h \ - ed25519/fixedint.h ed25519/ge.c ed25519/ge.h \ - ed25519/key_exchange.c ed25519/keypair.c \ - ed25519/precomp_data.h ed25519/sc.c ed25519/sc.h \ - ed25519/sha512.c ed25519/sha512.h ed25519/sign.c \ - ed25519/verify.c getopt.c getopt.h getopt1.c openssl/crypto.c \ - nolegacy/crypto.c -am__dirstamp = $(am__leading_dot)dirstamp -am__objects_1 = ed25519/fe.$(OBJEXT) ed25519/ge.$(OBJEXT) \ - ed25519/key_exchange.$(OBJEXT) ed25519/keypair.$(OBJEXT) \ - ed25519/sc.$(OBJEXT) ed25519/sha512.$(OBJEXT) \ - ed25519/sign.$(OBJEXT) ed25519/verify.$(OBJEXT) -@GETOPT_FALSE@am__objects_2 = getopt.$(OBJEXT) getopt1.$(OBJEXT) -@OPENSSL_TRUE@am__objects_3 = openssl/crypto.$(OBJEXT) -@GCRYPT_TRUE@@OPENSSL_FALSE@am__objects_4 = openssl/crypto.$(OBJEXT) -@GCRYPT_FALSE@@OPENSSL_FALSE@am__objects_5 = \ -@GCRYPT_FALSE@@OPENSSL_FALSE@ nolegacy/crypto.$(OBJEXT) -am_sptps_keypair_OBJECTS = sptps_keypair.$(OBJEXT) utils.$(OBJEXT) \ - ed25519/ecdsagen.$(OBJEXT) $(am__objects_1) $(am__objects_2) \ - $(am__objects_3) $(am__objects_4) $(am__objects_5) -sptps_keypair_OBJECTS = $(am_sptps_keypair_OBJECTS) -sptps_keypair_LDADD = $(LDADD) -am__sptps_speed_SOURCES_DIST = logger.c logger.h sptps.c sptps.h \ - sptps_speed.c utils.c utils.h ed25519/ecdh.c ed25519/ecdsa.c \ - ed25519/ecdsagen.c ed25519/ed25519.h ed25519/fe.c ed25519/fe.h \ - ed25519/fixedint.h ed25519/ge.c ed25519/ge.h \ - ed25519/key_exchange.c ed25519/keypair.c \ - ed25519/precomp_data.h ed25519/sc.c ed25519/sc.h \ - ed25519/sha512.c ed25519/sha512.h ed25519/sign.c \ - ed25519/verify.c chacha-poly1305/chacha.c \ - chacha-poly1305/chacha.h chacha-poly1305/chacha-poly1305.c \ - chacha-poly1305/chacha-poly1305.h chacha-poly1305/poly1305.c \ - chacha-poly1305/poly1305.h openssl/crypto.c openssl/digest.c \ - openssl/digest.h openssl/prf.c nolegacy/crypto.c \ - nolegacy/prf.c -am__objects_6 = chacha-poly1305/chacha.$(OBJEXT) \ - chacha-poly1305/chacha-poly1305.$(OBJEXT) \ - chacha-poly1305/poly1305.$(OBJEXT) -@OPENSSL_TRUE@am__objects_7 = openssl/crypto.$(OBJEXT) \ -@OPENSSL_TRUE@ openssl/digest.$(OBJEXT) openssl/prf.$(OBJEXT) -@GCRYPT_TRUE@@OPENSSL_FALSE@am__objects_8 = openssl/crypto.$(OBJEXT) \ -@GCRYPT_TRUE@@OPENSSL_FALSE@ openssl/digest.$(OBJEXT) \ -@GCRYPT_TRUE@@OPENSSL_FALSE@ openssl/prf.$(OBJEXT) -@GCRYPT_FALSE@@OPENSSL_FALSE@am__objects_9 = \ -@GCRYPT_FALSE@@OPENSSL_FALSE@ nolegacy/crypto.$(OBJEXT) \ -@GCRYPT_FALSE@@OPENSSL_FALSE@ nolegacy/prf.$(OBJEXT) -am_sptps_speed_OBJECTS = logger.$(OBJEXT) sptps.$(OBJEXT) \ - sptps_speed.$(OBJEXT) utils.$(OBJEXT) ed25519/ecdh.$(OBJEXT) \ - ed25519/ecdsa.$(OBJEXT) ed25519/ecdsagen.$(OBJEXT) \ - $(am__objects_1) $(am__objects_6) $(am__objects_7) \ - $(am__objects_8) $(am__objects_9) -sptps_speed_OBJECTS = $(am_sptps_speed_OBJECTS) -sptps_speed_DEPENDENCIES = -am__sptps_test_SOURCES_DIST = logger.c logger.h sptps.c sptps.h \ - sptps_test.c utils.c utils.h ed25519/ecdh.c ed25519/ecdsa.c \ - ed25519/ed25519.h ed25519/fe.c ed25519/fe.h ed25519/fixedint.h \ - ed25519/ge.c ed25519/ge.h ed25519/key_exchange.c \ - ed25519/keypair.c ed25519/precomp_data.h ed25519/sc.c \ - ed25519/sc.h ed25519/sha512.c ed25519/sha512.h ed25519/sign.c \ - ed25519/verify.c chacha-poly1305/chacha.c \ - chacha-poly1305/chacha.h chacha-poly1305/chacha-poly1305.c \ - chacha-poly1305/chacha-poly1305.h chacha-poly1305/poly1305.c \ - chacha-poly1305/poly1305.h getopt.c getopt.h getopt1.c \ - openssl/crypto.c openssl/digest.c openssl/digest.h \ - openssl/prf.c gcrypt/cipher.c gcrypt/crypto.c gcrypt/digest.c \ - gcrypt/digest.h gcrypt/prf.c nolegacy/crypto.c nolegacy/prf.c -@GCRYPT_TRUE@@OPENSSL_FALSE@am__objects_10 = gcrypt/cipher.$(OBJEXT) \ -@GCRYPT_TRUE@@OPENSSL_FALSE@ gcrypt/crypto.$(OBJEXT) \ -@GCRYPT_TRUE@@OPENSSL_FALSE@ gcrypt/digest.$(OBJEXT) \ -@GCRYPT_TRUE@@OPENSSL_FALSE@ gcrypt/prf.$(OBJEXT) -am_sptps_test_OBJECTS = logger.$(OBJEXT) sptps.$(OBJEXT) \ - sptps_test.$(OBJEXT) utils.$(OBJEXT) ed25519/ecdh.$(OBJEXT) \ - ed25519/ecdsa.$(OBJEXT) $(am__objects_1) $(am__objects_6) \ - $(am__objects_2) $(am__objects_7) $(am__objects_10) \ - $(am__objects_9) -sptps_test_OBJECTS = $(am_sptps_test_OBJECTS) -sptps_test_LDADD = $(LDADD) -am__tinc_SOURCES_DIST = dropin.c dropin.h fsck.c fsck.h ifconfig.c \ - ifconfig.h info.c info.h invitation.c invitation.h list.c \ - list.h names.c names.h netutl.c netutl.h script.c script.h \ - sptps.c sptps.h subnet_parse.c subnet.h tincctl.c tincctl.h \ - top.c top.h utils.c utils.h version.c version.h ed25519/ecdh.c \ - ed25519/ecdsa.c ed25519/ecdsagen.c ed25519/ed25519.h \ - ed25519/fe.c ed25519/fe.h ed25519/fixedint.h ed25519/ge.c \ - ed25519/ge.h ed25519/key_exchange.c ed25519/keypair.c \ - ed25519/precomp_data.h ed25519/sc.c ed25519/sc.h \ - ed25519/sha512.c ed25519/sha512.h ed25519/sign.c \ - ed25519/verify.c chacha-poly1305/chacha.c \ - chacha-poly1305/chacha.h chacha-poly1305/chacha-poly1305.c \ - chacha-poly1305/chacha-poly1305.h chacha-poly1305/poly1305.c \ - chacha-poly1305/poly1305.h getopt.c getopt.h getopt1.c \ - openssl/cipher.c openssl/crypto.c openssl/digest.c \ - openssl/digest.h openssl/prf.c openssl/rsa.c openssl/rsagen.c \ - gcrypt/cipher.c gcrypt/crypto.c gcrypt/digest.c \ - gcrypt/digest.h gcrypt/prf.c gcrypt/rsa.c gcrypt/rsagen.c \ - nolegacy/crypto.c nolegacy/prf.c -@OPENSSL_TRUE@am__objects_11 = openssl/cipher.$(OBJEXT) \ -@OPENSSL_TRUE@ openssl/crypto.$(OBJEXT) \ -@OPENSSL_TRUE@ openssl/digest.$(OBJEXT) openssl/prf.$(OBJEXT) \ -@OPENSSL_TRUE@ openssl/rsa.$(OBJEXT) openssl/rsagen.$(OBJEXT) -@GCRYPT_TRUE@@OPENSSL_FALSE@am__objects_12 = gcrypt/cipher.$(OBJEXT) \ -@GCRYPT_TRUE@@OPENSSL_FALSE@ gcrypt/crypto.$(OBJEXT) \ -@GCRYPT_TRUE@@OPENSSL_FALSE@ gcrypt/digest.$(OBJEXT) \ -@GCRYPT_TRUE@@OPENSSL_FALSE@ gcrypt/prf.$(OBJEXT) \ -@GCRYPT_TRUE@@OPENSSL_FALSE@ gcrypt/rsa.$(OBJEXT) \ -@GCRYPT_TRUE@@OPENSSL_FALSE@ gcrypt/rsagen.$(OBJEXT) -am_tinc_OBJECTS = dropin.$(OBJEXT) fsck.$(OBJEXT) ifconfig.$(OBJEXT) \ - info.$(OBJEXT) invitation.$(OBJEXT) list.$(OBJEXT) \ - names.$(OBJEXT) netutl.$(OBJEXT) script.$(OBJEXT) \ - sptps.$(OBJEXT) subnet_parse.$(OBJEXT) tincctl.$(OBJEXT) \ - top.$(OBJEXT) utils.$(OBJEXT) version.$(OBJEXT) \ - ed25519/ecdh.$(OBJEXT) ed25519/ecdsa.$(OBJEXT) \ - ed25519/ecdsagen.$(OBJEXT) $(am__objects_1) $(am__objects_6) \ - $(am__objects_2) $(am__objects_11) $(am__objects_12) \ - $(am__objects_9) -tinc_OBJECTS = $(am_tinc_OBJECTS) -am__DEPENDENCIES_1 = -tinc_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) -am__tincd_SOURCES_DIST = address_cache.c address_cache.h autoconnect.c \ - autoconnect.h buffer.c buffer.h cipher.h conf.c conf.h \ - connection.c connection.h control.c control.h control_common.h \ - crypto.h device.h digest.h dropin.c dropin.h dummy_device.c \ - ecdh.h ecdsa.h ecdsagen.h edge.c edge.h ethernet.h event.c \ - event.h fd_device.c graph.c graph.h hash.c hash.h have.h \ - ipv4.h ipv6.h list.c list.h logger.c logger.h meta.c meta.h \ - multicast_device.c names.c names.h net.c net.h net_packet.c \ - net_setup.c net_socket.c netutl.c netutl.h node.c node.h prf.h \ - process.c process.h protocol.c protocol.h protocol_auth.c \ - protocol_edge.c protocol_key.c protocol_misc.c \ - protocol_subnet.c raw_socket_device.c route.c route.h rsa.h \ - rsagen.h script.c script.h splay_tree.c splay_tree.h sptps.c \ - sptps.h subnet.c subnet.h subnet_parse.c system.h tincd.c \ - utils.c utils.h xalloc.h version.c version.h ed25519/ecdh.c \ - ed25519/ecdsa.c ed25519/ed25519.h ed25519/fe.c ed25519/fe.h \ - ed25519/fixedint.h ed25519/ge.c ed25519/ge.h \ - ed25519/key_exchange.c ed25519/keypair.c \ - ed25519/precomp_data.h ed25519/sc.c ed25519/sc.h \ - ed25519/sha512.c ed25519/sha512.h ed25519/sign.c \ - ed25519/verify.c chacha-poly1305/chacha.c \ - chacha-poly1305/chacha.h chacha-poly1305/chacha-poly1305.c \ - chacha-poly1305/chacha-poly1305.h chacha-poly1305/poly1305.c \ - chacha-poly1305/poly1305.h getopt.c getopt.h getopt1.c \ +am__tincd_SOURCES_DIST = have.h system.h avl_tree.c avl_tree.h conf.c \ + conf.h connection.c connection.h device.h dropin.c dropin.h \ + dummy_device.c edge.c edge.h ethernet.h event.c event.h \ + fake-getaddrinfo.c fake-getaddrinfo.h fake-getnameinfo.c \ + fake-getnameinfo.h graph.c graph.h ipv4.h ipv6.h list.c list.h \ + logger.c logger.h meta.c meta.h multicast_device.c net.c net.h \ + net_packet.c net_setup.c net_socket.c netutl.c netutl.h node.c \ + node.h pidfile.c pidfile.h process.c process.h protocol.c \ + protocol.h protocol_auth.c protocol_edge.c protocol_misc.c \ + protocol_key.c protocol_subnet.c proxy.c proxy.h \ + raw_socket_device.c route.c route.h subnet.c subnet.h tincd.c \ + utils.c utils.h xalloc.h getopt.c getopt.h getopt1.c \ linux/device.c bsd/device.c bsd/tunemu.c bsd/tunemu.h \ solaris/device.c mingw/device.c mingw/common.h cygwin/device.c \ - uml_device.c vde_device.c openssl/cipher.c openssl/crypto.c \ - openssl/digest.c openssl/digest.h openssl/prf.c openssl/rsa.c \ - gcrypt/cipher.c gcrypt/crypto.c gcrypt/digest.c \ - gcrypt/digest.h gcrypt/prf.c gcrypt/rsa.c nolegacy/crypto.c \ - nolegacy/prf.c upnp.h upnp.c -@LINUX_TRUE@am__objects_13 = linux/device.$(OBJEXT) -@BSD_TRUE@am__objects_14 = bsd/device.$(OBJEXT) -@BSD_TRUE@@TUNEMU_TRUE@am__objects_15 = bsd/tunemu.$(OBJEXT) -@SOLARIS_TRUE@am__objects_16 = solaris/device.$(OBJEXT) -@MINGW_TRUE@am__objects_17 = mingw/device.$(OBJEXT) -@CYGWIN_TRUE@am__objects_18 = cygwin/device.$(OBJEXT) -@UML_TRUE@am__objects_19 = uml_device.$(OBJEXT) -@VDE_TRUE@am__objects_20 = vde_device.$(OBJEXT) -@OPENSSL_TRUE@am__objects_21 = openssl/cipher.$(OBJEXT) \ -@OPENSSL_TRUE@ openssl/crypto.$(OBJEXT) \ -@OPENSSL_TRUE@ openssl/digest.$(OBJEXT) openssl/prf.$(OBJEXT) \ -@OPENSSL_TRUE@ openssl/rsa.$(OBJEXT) -@GCRYPT_TRUE@@OPENSSL_FALSE@am__objects_22 = gcrypt/cipher.$(OBJEXT) \ -@GCRYPT_TRUE@@OPENSSL_FALSE@ gcrypt/crypto.$(OBJEXT) \ -@GCRYPT_TRUE@@OPENSSL_FALSE@ gcrypt/digest.$(OBJEXT) \ -@GCRYPT_TRUE@@OPENSSL_FALSE@ gcrypt/prf.$(OBJEXT) \ -@GCRYPT_TRUE@@OPENSSL_FALSE@ gcrypt/rsa.$(OBJEXT) -@MINIUPNPC_TRUE@am__objects_23 = upnp.$(OBJEXT) -am_tincd_OBJECTS = address_cache.$(OBJEXT) autoconnect.$(OBJEXT) \ - buffer.$(OBJEXT) conf.$(OBJEXT) connection.$(OBJEXT) \ - control.$(OBJEXT) dropin.$(OBJEXT) dummy_device.$(OBJEXT) \ - edge.$(OBJEXT) event.$(OBJEXT) fd_device.$(OBJEXT) \ - graph.$(OBJEXT) hash.$(OBJEXT) list.$(OBJEXT) logger.$(OBJEXT) \ - meta.$(OBJEXT) multicast_device.$(OBJEXT) names.$(OBJEXT) \ + uml_device.c vde_device.c +@GETOPT_FALSE@am__objects_1 = getopt.$(OBJEXT) getopt1.$(OBJEXT) +am__dirstamp = $(am__leading_dot)dirstamp +@LINUX_TRUE@am__objects_2 = linux/device.$(OBJEXT) +@BSD_TRUE@am__objects_3 = bsd/device.$(OBJEXT) +@BSD_TRUE@@TUNEMU_TRUE@am__objects_4 = bsd/tunemu.$(OBJEXT) +@SOLARIS_TRUE@am__objects_5 = solaris/device.$(OBJEXT) +@MINGW_TRUE@am__objects_6 = mingw/device.$(OBJEXT) +@CYGWIN_TRUE@am__objects_7 = cygwin/device.$(OBJEXT) +@UML_TRUE@am__objects_8 = uml_device.$(OBJEXT) +@VDE_TRUE@am__objects_9 = vde_device.$(OBJEXT) +am_tincd_OBJECTS = avl_tree.$(OBJEXT) conf.$(OBJEXT) \ + connection.$(OBJEXT) dropin.$(OBJEXT) dummy_device.$(OBJEXT) \ + edge.$(OBJEXT) event.$(OBJEXT) fake-getaddrinfo.$(OBJEXT) \ + fake-getnameinfo.$(OBJEXT) graph.$(OBJEXT) list.$(OBJEXT) \ + logger.$(OBJEXT) meta.$(OBJEXT) multicast_device.$(OBJEXT) \ net.$(OBJEXT) net_packet.$(OBJEXT) net_setup.$(OBJEXT) \ net_socket.$(OBJEXT) netutl.$(OBJEXT) node.$(OBJEXT) \ - process.$(OBJEXT) protocol.$(OBJEXT) protocol_auth.$(OBJEXT) \ - protocol_edge.$(OBJEXT) protocol_key.$(OBJEXT) \ - protocol_misc.$(OBJEXT) protocol_subnet.$(OBJEXT) \ - raw_socket_device.$(OBJEXT) route.$(OBJEXT) script.$(OBJEXT) \ - splay_tree.$(OBJEXT) sptps.$(OBJEXT) subnet.$(OBJEXT) \ - subnet_parse.$(OBJEXT) tincd.$(OBJEXT) utils.$(OBJEXT) \ - version.$(OBJEXT) ed25519/ecdh.$(OBJEXT) \ - ed25519/ecdsa.$(OBJEXT) $(am__objects_1) $(am__objects_6) \ - $(am__objects_2) $(am__objects_13) $(am__objects_14) \ - $(am__objects_15) $(am__objects_16) $(am__objects_17) \ - $(am__objects_18) $(am__objects_19) $(am__objects_20) \ - $(am__objects_21) $(am__objects_22) $(am__objects_9) \ - $(am__objects_23) + pidfile.$(OBJEXT) process.$(OBJEXT) protocol.$(OBJEXT) \ + protocol_auth.$(OBJEXT) protocol_edge.$(OBJEXT) \ + protocol_misc.$(OBJEXT) protocol_key.$(OBJEXT) \ + protocol_subnet.$(OBJEXT) proxy.$(OBJEXT) \ + raw_socket_device.$(OBJEXT) route.$(OBJEXT) subnet.$(OBJEXT) \ + tincd.$(OBJEXT) utils.$(OBJEXT) $(am__objects_1) \ + $(am__objects_2) $(am__objects_3) $(am__objects_4) \ + $(am__objects_5) $(am__objects_6) $(am__objects_7) \ + $(am__objects_8) $(am__objects_9) tincd_OBJECTS = $(am_tincd_OBJECTS) -@MINIUPNPC_TRUE@tincd_DEPENDENCIES = $(am__DEPENDENCIES_1) -tincd_LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(tincd_LDFLAGS) \ - $(LDFLAGS) -o $@ +tincd_LDADD = $(LDADD) AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false @@ -426,52 +179,27 @@ am__v_at_1 = DEFAULT_INCLUDES = depcomp = $(SHELL) $(top_srcdir)/depcomp am__maybe_remake_depfiles = depfiles -am__depfiles_remade = ./$(DEPDIR)/address_cache.Po \ - ./$(DEPDIR)/autoconnect.Po ./$(DEPDIR)/buffer.Po \ - ./$(DEPDIR)/conf.Po ./$(DEPDIR)/connection.Po \ - ./$(DEPDIR)/control.Po ./$(DEPDIR)/dropin.Po \ +am__depfiles_remade = ./$(DEPDIR)/avl_tree.Po ./$(DEPDIR)/conf.Po \ + ./$(DEPDIR)/connection.Po ./$(DEPDIR)/dropin.Po \ ./$(DEPDIR)/dummy_device.Po ./$(DEPDIR)/edge.Po \ - ./$(DEPDIR)/event.Po ./$(DEPDIR)/fd_device.Po \ - ./$(DEPDIR)/fsck.Po ./$(DEPDIR)/getopt.Po \ + ./$(DEPDIR)/event.Po ./$(DEPDIR)/fake-getaddrinfo.Po \ + ./$(DEPDIR)/fake-getnameinfo.Po ./$(DEPDIR)/getopt.Po \ ./$(DEPDIR)/getopt1.Po ./$(DEPDIR)/graph.Po \ - ./$(DEPDIR)/hash.Po ./$(DEPDIR)/ifconfig.Po \ - ./$(DEPDIR)/info.Po ./$(DEPDIR)/invitation.Po \ ./$(DEPDIR)/list.Po ./$(DEPDIR)/logger.Po ./$(DEPDIR)/meta.Po \ - ./$(DEPDIR)/multicast_device.Po ./$(DEPDIR)/names.Po \ - ./$(DEPDIR)/net.Po ./$(DEPDIR)/net_packet.Po \ - ./$(DEPDIR)/net_setup.Po ./$(DEPDIR)/net_socket.Po \ - ./$(DEPDIR)/netutl.Po ./$(DEPDIR)/node.Po \ + ./$(DEPDIR)/multicast_device.Po ./$(DEPDIR)/net.Po \ + ./$(DEPDIR)/net_packet.Po ./$(DEPDIR)/net_setup.Po \ + ./$(DEPDIR)/net_socket.Po ./$(DEPDIR)/netutl.Po \ + ./$(DEPDIR)/node.Po ./$(DEPDIR)/pidfile.Po \ ./$(DEPDIR)/process.Po ./$(DEPDIR)/protocol.Po \ ./$(DEPDIR)/protocol_auth.Po ./$(DEPDIR)/protocol_edge.Po \ ./$(DEPDIR)/protocol_key.Po ./$(DEPDIR)/protocol_misc.Po \ - ./$(DEPDIR)/protocol_subnet.Po \ + ./$(DEPDIR)/protocol_subnet.Po ./$(DEPDIR)/proxy.Po \ ./$(DEPDIR)/raw_socket_device.Po ./$(DEPDIR)/route.Po \ - ./$(DEPDIR)/script.Po ./$(DEPDIR)/splay_tree.Po \ - ./$(DEPDIR)/sptps.Po ./$(DEPDIR)/sptps_keypair.Po \ - ./$(DEPDIR)/sptps_speed.Po ./$(DEPDIR)/sptps_test.Po \ - ./$(DEPDIR)/subnet.Po ./$(DEPDIR)/subnet_parse.Po \ - ./$(DEPDIR)/tincctl.Po ./$(DEPDIR)/tincd.Po ./$(DEPDIR)/top.Po \ - ./$(DEPDIR)/uml_device.Po ./$(DEPDIR)/upnp.Po \ - ./$(DEPDIR)/utils.Po ./$(DEPDIR)/vde_device.Po \ - ./$(DEPDIR)/version.Po bsd/$(DEPDIR)/device.Po \ - bsd/$(DEPDIR)/tunemu.Po \ - chacha-poly1305/$(DEPDIR)/chacha-poly1305.Po \ - chacha-poly1305/$(DEPDIR)/chacha.Po \ - chacha-poly1305/$(DEPDIR)/poly1305.Po \ - cygwin/$(DEPDIR)/device.Po ed25519/$(DEPDIR)/ecdh.Po \ - ed25519/$(DEPDIR)/ecdsa.Po ed25519/$(DEPDIR)/ecdsagen.Po \ - ed25519/$(DEPDIR)/fe.Po ed25519/$(DEPDIR)/ge.Po \ - ed25519/$(DEPDIR)/key_exchange.Po ed25519/$(DEPDIR)/keypair.Po \ - ed25519/$(DEPDIR)/sc.Po ed25519/$(DEPDIR)/sha512.Po \ - ed25519/$(DEPDIR)/sign.Po ed25519/$(DEPDIR)/verify.Po \ - gcrypt/$(DEPDIR)/cipher.Po gcrypt/$(DEPDIR)/crypto.Po \ - gcrypt/$(DEPDIR)/digest.Po gcrypt/$(DEPDIR)/prf.Po \ - gcrypt/$(DEPDIR)/rsa.Po gcrypt/$(DEPDIR)/rsagen.Po \ + ./$(DEPDIR)/subnet.Po ./$(DEPDIR)/tincd.Po \ + ./$(DEPDIR)/uml_device.Po ./$(DEPDIR)/utils.Po \ + ./$(DEPDIR)/vde_device.Po bsd/$(DEPDIR)/device.Po \ + bsd/$(DEPDIR)/tunemu.Po cygwin/$(DEPDIR)/device.Po \ linux/$(DEPDIR)/device.Po mingw/$(DEPDIR)/device.Po \ - nolegacy/$(DEPDIR)/crypto.Po nolegacy/$(DEPDIR)/prf.Po \ - openssl/$(DEPDIR)/cipher.Po openssl/$(DEPDIR)/crypto.Po \ - openssl/$(DEPDIR)/digest.Po openssl/$(DEPDIR)/prf.Po \ - openssl/$(DEPDIR)/rsa.Po openssl/$(DEPDIR)/rsagen.Po \ solaris/$(DEPDIR)/device.Po am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ @@ -486,11 +214,8 @@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = -SOURCES = $(sptps_keypair_SOURCES) $(sptps_speed_SOURCES) \ - $(sptps_test_SOURCES) $(tinc_SOURCES) $(tincd_SOURCES) -DIST_SOURCES = $(am__sptps_keypair_SOURCES_DIST) \ - $(am__sptps_speed_SOURCES_DIST) $(am__sptps_test_SOURCES_DIST) \ - $(am__tinc_SOURCES_DIST) $(am__tincd_SOURCES_DIST) +SOURCES = $(tincd_SOURCES) +DIST_SOURCES = $(am__tincd_SOURCES_DIST) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ @@ -527,15 +252,8 @@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ -CODE_COVERAGE_CFLAGS = @CODE_COVERAGE_CFLAGS@ -CODE_COVERAGE_CPPFLAGS = @CODE_COVERAGE_CPPFLAGS@ -CODE_COVERAGE_CXXFLAGS = @CODE_COVERAGE_CXXFLAGS@ -CODE_COVERAGE_ENABLED = @CODE_COVERAGE_ENABLED@ -CODE_COVERAGE_LDFLAGS = @CODE_COVERAGE_LDFLAGS@ -CODE_COVERAGE_LIBS = @CODE_COVERAGE_LIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ -CURSES_LIBS = @CURSES_LIBS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ @@ -544,21 +262,17 @@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ -GCOV = @GCOV@ -GENHTML = @GENHTML@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -LCOV = @LCOV@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ -LIBS = @LIBS@ -lm $(CODE_COVERAGE_LIBS) $(am__append_30) +LIBS = @LIBS@ $(am__append_10) LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ -MINIUPNPC_LIBS = @MINIUPNPC_LIBS@ MKDIR_P = @MKDIR_P@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ @@ -569,8 +283,6 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ -READLINE_LIBS = @READLINE_LIBS@ -SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ @@ -627,72 +339,22 @@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ -CLEANFILES = version_git.h -ed25519_SOURCES = \ - ed25519/ed25519.h \ - ed25519/fe.c ed25519/fe.h \ - ed25519/fixedint.h \ - ed25519/ge.c ed25519/ge.h \ - ed25519/key_exchange.c \ - ed25519/keypair.c \ - ed25519/precomp_data.h \ - ed25519/sc.c ed25519/sc.h \ - ed25519/sha512.c ed25519/sha512.h \ - ed25519/sign.c \ - ed25519/verify.c - -chacha_poly1305_SOURCES = \ - chacha-poly1305/chacha.c chacha-poly1305/chacha.h \ - chacha-poly1305/chacha-poly1305.c chacha-poly1305/chacha-poly1305.h \ - chacha-poly1305/poly1305.c chacha-poly1305/poly1305.h - -tincd_SOURCES = address_cache.c address_cache.h autoconnect.c \ - autoconnect.h buffer.c buffer.h cipher.h conf.c conf.h \ - connection.c connection.h control.c control.h control_common.h \ - crypto.h device.h digest.h dropin.c dropin.h dummy_device.c \ - ecdh.h ecdsa.h ecdsagen.h edge.c edge.h ethernet.h event.c \ - event.h fd_device.c graph.c graph.h hash.c hash.h have.h \ - ipv4.h ipv6.h list.c list.h logger.c logger.h meta.c meta.h \ - multicast_device.c names.c names.h net.c net.h net_packet.c \ - net_setup.c net_socket.c netutl.c netutl.h node.c node.h prf.h \ - process.c process.h protocol.c protocol.h protocol_auth.c \ - protocol_edge.c protocol_key.c protocol_misc.c \ - protocol_subnet.c raw_socket_device.c route.c route.h rsa.h \ - rsagen.h script.c script.h splay_tree.c splay_tree.h sptps.c \ - sptps.h subnet.c subnet.h subnet_parse.c system.h tincd.c \ - utils.c utils.h xalloc.h version.c version.h ed25519/ecdh.c \ - ed25519/ecdsa.c $(ed25519_SOURCES) $(chacha_poly1305_SOURCES) \ - $(am__append_2) $(am__append_6) $(am__append_7) \ - $(am__append_8) $(am__append_9) $(am__append_10) \ - $(am__append_11) $(am__append_12) $(am__append_13) \ - $(am__append_14) $(am__append_19) $(am__append_24) \ - $(am__append_29) -tinc_SOURCES = dropin.c dropin.h fsck.c fsck.h ifconfig.c ifconfig.h \ - info.c info.h invitation.c invitation.h list.c list.h names.c \ - names.h netutl.c netutl.h script.c script.h sptps.c sptps.h \ - subnet_parse.c subnet.h tincctl.c tincctl.h top.c top.h \ - utils.c utils.h version.c version.h ed25519/ecdh.c \ - ed25519/ecdsa.c ed25519/ecdsagen.c $(ed25519_SOURCES) \ - $(chacha_poly1305_SOURCES) $(am__append_3) $(am__append_15) \ - $(am__append_20) $(am__append_25) -sptps_test_SOURCES = logger.c logger.h sptps.c sptps.h sptps_test.c \ - utils.c utils.h ed25519/ecdh.c ed25519/ecdsa.c \ - $(ed25519_SOURCES) $(chacha_poly1305_SOURCES) $(am__append_4) \ - $(am__append_16) $(am__append_21) $(am__append_26) -sptps_keypair_SOURCES = sptps_keypair.c utils.c utils.h \ - ed25519/ecdsagen.c $(ed25519_SOURCES) $(am__append_5) \ - $(am__append_17) $(am__append_22) $(am__append_27) -sptps_speed_SOURCES = logger.c logger.h sptps.c sptps.h sptps_speed.c \ - utils.c utils.h ed25519/ecdh.c ed25519/ecdsa.c \ - ed25519/ecdsagen.c $(ed25519_SOURCES) \ - $(chacha_poly1305_SOURCES) $(am__append_18) $(am__append_23) \ - $(am__append_28) -@MINIUPNPC_TRUE@tincd_LDADD = $(MINIUPNPC_LIBS) -@MINIUPNPC_TRUE@tincd_LDFLAGS = -pthread -tinc_LDADD = $(READLINE_LIBS) $(CURSES_LIBS) -sptps_speed_LDADD = -lrt -AM_CFLAGS = -DCONFDIR=\"$(sysconfdir)\" -DRUNSTATEDIR=\"$(runstatedir)\" -DLOCALSTATEDIR=\"$(localstatedir)\" -DSBINDIR=\"$(sbindir)\" -iquote. $(CODE_COVERAGE_CFLAGS) -AM_CPPFLAGS = $(CODE_COVERAGE_CPPFLAGS) +tincd_SOURCES = have.h system.h avl_tree.c avl_tree.h conf.c conf.h \ + connection.c connection.h device.h dropin.c dropin.h \ + dummy_device.c edge.c edge.h ethernet.h event.c event.h \ + fake-getaddrinfo.c fake-getaddrinfo.h fake-getnameinfo.c \ + fake-getnameinfo.h graph.c graph.h ipv4.h ipv6.h list.c list.h \ + logger.c logger.h meta.c meta.h multicast_device.c net.c net.h \ + net_packet.c net_setup.c net_socket.c netutl.c netutl.h node.c \ + node.h pidfile.c pidfile.h process.c process.h protocol.c \ + protocol.h protocol_auth.c protocol_edge.c protocol_misc.c \ + protocol_key.c protocol_subnet.c proxy.c proxy.h \ + raw_socket_device.c route.c route.h subnet.c subnet.h tincd.c \ + utils.c utils.h xalloc.h $(am__append_1) $(am__append_2) \ + $(am__append_3) $(am__append_4) $(am__append_5) \ + $(am__append_6) $(am__append_7) $(am__append_8) \ + $(am__append_9) +AM_CPPFLAGS = -DCONFDIR=\"$(sysconfdir)\" -DRUNSTATEDIR=\"$(runstatedir)\" -DLOCALSTATEDIR=\"$(localstatedir)\" -I $(abs_top_builddir)/ all: all-am .SUFFIXES: @@ -726,9 +388,6 @@ $(top_srcdir)/configure: $(am__configure_deps) $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): - -clean-checkPROGRAMS: - -test -z "$(check_PROGRAMS)" || rm -f $(check_PROGRAMS) install-sbinPROGRAMS: $(sbin_PROGRAMS) @$(NORMAL_INSTALL) @list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \ @@ -787,109 +446,6 @@ installcheck-sbinPROGRAMS: $(sbin_PROGRAMS) else echo "$$f does not support $$opt" 1>&2; bad=1; fi; \ done; \ done; rm -f c$${pid}_.???; exit $$bad -ed25519/$(am__dirstamp): - @$(MKDIR_P) ed25519 - @: > ed25519/$(am__dirstamp) -ed25519/$(DEPDIR)/$(am__dirstamp): - @$(MKDIR_P) ed25519/$(DEPDIR) - @: > ed25519/$(DEPDIR)/$(am__dirstamp) -ed25519/ecdsagen.$(OBJEXT): ed25519/$(am__dirstamp) \ - ed25519/$(DEPDIR)/$(am__dirstamp) -ed25519/fe.$(OBJEXT): ed25519/$(am__dirstamp) \ - ed25519/$(DEPDIR)/$(am__dirstamp) -ed25519/ge.$(OBJEXT): ed25519/$(am__dirstamp) \ - ed25519/$(DEPDIR)/$(am__dirstamp) -ed25519/key_exchange.$(OBJEXT): ed25519/$(am__dirstamp) \ - ed25519/$(DEPDIR)/$(am__dirstamp) -ed25519/keypair.$(OBJEXT): ed25519/$(am__dirstamp) \ - ed25519/$(DEPDIR)/$(am__dirstamp) -ed25519/sc.$(OBJEXT): ed25519/$(am__dirstamp) \ - ed25519/$(DEPDIR)/$(am__dirstamp) -ed25519/sha512.$(OBJEXT): ed25519/$(am__dirstamp) \ - ed25519/$(DEPDIR)/$(am__dirstamp) -ed25519/sign.$(OBJEXT): ed25519/$(am__dirstamp) \ - ed25519/$(DEPDIR)/$(am__dirstamp) -ed25519/verify.$(OBJEXT): ed25519/$(am__dirstamp) \ - ed25519/$(DEPDIR)/$(am__dirstamp) -openssl/$(am__dirstamp): - @$(MKDIR_P) openssl - @: > openssl/$(am__dirstamp) -openssl/$(DEPDIR)/$(am__dirstamp): - @$(MKDIR_P) openssl/$(DEPDIR) - @: > openssl/$(DEPDIR)/$(am__dirstamp) -openssl/crypto.$(OBJEXT): openssl/$(am__dirstamp) \ - openssl/$(DEPDIR)/$(am__dirstamp) -nolegacy/$(am__dirstamp): - @$(MKDIR_P) nolegacy - @: > nolegacy/$(am__dirstamp) -nolegacy/$(DEPDIR)/$(am__dirstamp): - @$(MKDIR_P) nolegacy/$(DEPDIR) - @: > nolegacy/$(DEPDIR)/$(am__dirstamp) -nolegacy/crypto.$(OBJEXT): nolegacy/$(am__dirstamp) \ - nolegacy/$(DEPDIR)/$(am__dirstamp) - -sptps_keypair$(EXEEXT): $(sptps_keypair_OBJECTS) $(sptps_keypair_DEPENDENCIES) $(EXTRA_sptps_keypair_DEPENDENCIES) - @rm -f sptps_keypair$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(sptps_keypair_OBJECTS) $(sptps_keypair_LDADD) $(LIBS) -ed25519/ecdh.$(OBJEXT): ed25519/$(am__dirstamp) \ - ed25519/$(DEPDIR)/$(am__dirstamp) -ed25519/ecdsa.$(OBJEXT): ed25519/$(am__dirstamp) \ - ed25519/$(DEPDIR)/$(am__dirstamp) -chacha-poly1305/$(am__dirstamp): - @$(MKDIR_P) chacha-poly1305 - @: > chacha-poly1305/$(am__dirstamp) -chacha-poly1305/$(DEPDIR)/$(am__dirstamp): - @$(MKDIR_P) chacha-poly1305/$(DEPDIR) - @: > chacha-poly1305/$(DEPDIR)/$(am__dirstamp) -chacha-poly1305/chacha.$(OBJEXT): chacha-poly1305/$(am__dirstamp) \ - chacha-poly1305/$(DEPDIR)/$(am__dirstamp) -chacha-poly1305/chacha-poly1305.$(OBJEXT): \ - chacha-poly1305/$(am__dirstamp) \ - chacha-poly1305/$(DEPDIR)/$(am__dirstamp) -chacha-poly1305/poly1305.$(OBJEXT): chacha-poly1305/$(am__dirstamp) \ - chacha-poly1305/$(DEPDIR)/$(am__dirstamp) -openssl/digest.$(OBJEXT): openssl/$(am__dirstamp) \ - openssl/$(DEPDIR)/$(am__dirstamp) -openssl/prf.$(OBJEXT): openssl/$(am__dirstamp) \ - openssl/$(DEPDIR)/$(am__dirstamp) -nolegacy/prf.$(OBJEXT): nolegacy/$(am__dirstamp) \ - nolegacy/$(DEPDIR)/$(am__dirstamp) - -sptps_speed$(EXEEXT): $(sptps_speed_OBJECTS) $(sptps_speed_DEPENDENCIES) $(EXTRA_sptps_speed_DEPENDENCIES) - @rm -f sptps_speed$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(sptps_speed_OBJECTS) $(sptps_speed_LDADD) $(LIBS) -gcrypt/$(am__dirstamp): - @$(MKDIR_P) gcrypt - @: > gcrypt/$(am__dirstamp) -gcrypt/$(DEPDIR)/$(am__dirstamp): - @$(MKDIR_P) gcrypt/$(DEPDIR) - @: > gcrypt/$(DEPDIR)/$(am__dirstamp) -gcrypt/cipher.$(OBJEXT): gcrypt/$(am__dirstamp) \ - gcrypt/$(DEPDIR)/$(am__dirstamp) -gcrypt/crypto.$(OBJEXT): gcrypt/$(am__dirstamp) \ - gcrypt/$(DEPDIR)/$(am__dirstamp) -gcrypt/digest.$(OBJEXT): gcrypt/$(am__dirstamp) \ - gcrypt/$(DEPDIR)/$(am__dirstamp) -gcrypt/prf.$(OBJEXT): gcrypt/$(am__dirstamp) \ - gcrypt/$(DEPDIR)/$(am__dirstamp) - -sptps_test$(EXEEXT): $(sptps_test_OBJECTS) $(sptps_test_DEPENDENCIES) $(EXTRA_sptps_test_DEPENDENCIES) - @rm -f sptps_test$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(sptps_test_OBJECTS) $(sptps_test_LDADD) $(LIBS) -openssl/cipher.$(OBJEXT): openssl/$(am__dirstamp) \ - openssl/$(DEPDIR)/$(am__dirstamp) -openssl/rsa.$(OBJEXT): openssl/$(am__dirstamp) \ - openssl/$(DEPDIR)/$(am__dirstamp) -openssl/rsagen.$(OBJEXT): openssl/$(am__dirstamp) \ - openssl/$(DEPDIR)/$(am__dirstamp) -gcrypt/rsa.$(OBJEXT): gcrypt/$(am__dirstamp) \ - gcrypt/$(DEPDIR)/$(am__dirstamp) -gcrypt/rsagen.$(OBJEXT): gcrypt/$(am__dirstamp) \ - gcrypt/$(DEPDIR)/$(am__dirstamp) - -tinc$(EXEEXT): $(tinc_OBJECTS) $(tinc_DEPENDENCIES) $(EXTRA_tinc_DEPENDENCIES) - @rm -f tinc$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(tinc_OBJECTS) $(tinc_LDADD) $(LIBS) linux/$(am__dirstamp): @$(MKDIR_P) linux @: > linux/$(am__dirstamp) @@ -935,54 +491,42 @@ cygwin/device.$(OBJEXT): cygwin/$(am__dirstamp) \ tincd$(EXEEXT): $(tincd_OBJECTS) $(tincd_DEPENDENCIES) $(EXTRA_tincd_DEPENDENCIES) @rm -f tincd$(EXEEXT) - $(AM_V_CCLD)$(tincd_LINK) $(tincd_OBJECTS) $(tincd_LDADD) $(LIBS) + $(AM_V_CCLD)$(LINK) $(tincd_OBJECTS) $(tincd_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) -rm -f bsd/*.$(OBJEXT) - -rm -f chacha-poly1305/*.$(OBJEXT) -rm -f cygwin/*.$(OBJEXT) - -rm -f ed25519/*.$(OBJEXT) - -rm -f gcrypt/*.$(OBJEXT) -rm -f linux/*.$(OBJEXT) -rm -f mingw/*.$(OBJEXT) - -rm -f nolegacy/*.$(OBJEXT) - -rm -f openssl/*.$(OBJEXT) -rm -f solaris/*.$(OBJEXT) distclean-compile: -rm -f *.tab.c -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/address_cache.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/autoconnect.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/buffer.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/avl_tree.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/conf.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/connection.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/control.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dropin.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dummy_device.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/edge.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/event.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fd_device.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fsck.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fake-getaddrinfo.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fake-getnameinfo.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getopt.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getopt1.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/graph.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hash.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ifconfig.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/info.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/invitation.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/list.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/logger.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/meta.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/multicast_device.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/names.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/net.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/net_packet.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/net_setup.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/net_socket.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/netutl.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/node.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pidfile.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/process.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protocol.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protocol_auth.Po@am__quote@ # am--include-marker @@ -990,57 +534,19 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protocol_key.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protocol_misc.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protocol_subnet.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/proxy.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/raw_socket_device.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/route.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/script.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/splay_tree.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sptps.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sptps_keypair.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sptps_speed.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sptps_test.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/subnet.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/subnet_parse.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tincctl.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tincd.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/top.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uml_device.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/upnp.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/utils.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vde_device.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/version.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@bsd/$(DEPDIR)/device.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@bsd/$(DEPDIR)/tunemu.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@chacha-poly1305/$(DEPDIR)/chacha-poly1305.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@chacha-poly1305/$(DEPDIR)/chacha.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@chacha-poly1305/$(DEPDIR)/poly1305.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@cygwin/$(DEPDIR)/device.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/ecdh.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/ecdsa.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/ecdsagen.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/fe.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/ge.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/key_exchange.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/keypair.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/sc.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/sha512.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/sign.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/verify.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@gcrypt/$(DEPDIR)/cipher.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@gcrypt/$(DEPDIR)/crypto.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@gcrypt/$(DEPDIR)/digest.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@gcrypt/$(DEPDIR)/prf.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@gcrypt/$(DEPDIR)/rsa.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@gcrypt/$(DEPDIR)/rsagen.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@linux/$(DEPDIR)/device.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@mingw/$(DEPDIR)/device.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@nolegacy/$(DEPDIR)/crypto.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@nolegacy/$(DEPDIR)/prf.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@openssl/$(DEPDIR)/cipher.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@openssl/$(DEPDIR)/crypto.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@openssl/$(DEPDIR)/digest.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@openssl/$(DEPDIR)/prf.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@openssl/$(DEPDIR)/rsa.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@openssl/$(DEPDIR)/rsagen.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@solaris/$(DEPDIR)/device.Po@am__quote@ # am--include-marker $(am__depfiles_remade): @@ -1151,7 +657,6 @@ distdir-am: $(DISTFILES) fi; \ done check-am: all-am - $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) check: check-am all-am: Makefile $(PROGRAMS) installdirs: @@ -1180,29 +685,18 @@ install-strip: mostlyclean-generic: clean-generic: - -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) -rm -f bsd/$(DEPDIR)/$(am__dirstamp) -rm -f bsd/$(am__dirstamp) - -rm -f chacha-poly1305/$(DEPDIR)/$(am__dirstamp) - -rm -f chacha-poly1305/$(am__dirstamp) -rm -f cygwin/$(DEPDIR)/$(am__dirstamp) -rm -f cygwin/$(am__dirstamp) - -rm -f ed25519/$(DEPDIR)/$(am__dirstamp) - -rm -f ed25519/$(am__dirstamp) - -rm -f gcrypt/$(DEPDIR)/$(am__dirstamp) - -rm -f gcrypt/$(am__dirstamp) -rm -f linux/$(DEPDIR)/$(am__dirstamp) -rm -f linux/$(am__dirstamp) -rm -f mingw/$(DEPDIR)/$(am__dirstamp) -rm -f mingw/$(am__dirstamp) - -rm -f nolegacy/$(DEPDIR)/$(am__dirstamp) - -rm -f nolegacy/$(am__dirstamp) - -rm -f openssl/$(DEPDIR)/$(am__dirstamp) - -rm -f openssl/$(am__dirstamp) -rm -f solaris/$(DEPDIR)/$(am__dirstamp) -rm -f solaris/$(am__dirstamp) @@ -1211,40 +705,32 @@ maintainer-clean-generic: @echo "it deletes files that may require special tools to rebuild." clean: clean-am -clean-am: clean-checkPROGRAMS clean-generic clean-sbinPROGRAMS \ - mostlyclean-am +clean-am: clean-generic clean-sbinPROGRAMS mostlyclean-am distclean: distclean-am - -rm -f ./$(DEPDIR)/address_cache.Po - -rm -f ./$(DEPDIR)/autoconnect.Po - -rm -f ./$(DEPDIR)/buffer.Po + -rm -f ./$(DEPDIR)/avl_tree.Po -rm -f ./$(DEPDIR)/conf.Po -rm -f ./$(DEPDIR)/connection.Po - -rm -f ./$(DEPDIR)/control.Po -rm -f ./$(DEPDIR)/dropin.Po -rm -f ./$(DEPDIR)/dummy_device.Po -rm -f ./$(DEPDIR)/edge.Po -rm -f ./$(DEPDIR)/event.Po - -rm -f ./$(DEPDIR)/fd_device.Po - -rm -f ./$(DEPDIR)/fsck.Po + -rm -f ./$(DEPDIR)/fake-getaddrinfo.Po + -rm -f ./$(DEPDIR)/fake-getnameinfo.Po -rm -f ./$(DEPDIR)/getopt.Po -rm -f ./$(DEPDIR)/getopt1.Po -rm -f ./$(DEPDIR)/graph.Po - -rm -f ./$(DEPDIR)/hash.Po - -rm -f ./$(DEPDIR)/ifconfig.Po - -rm -f ./$(DEPDIR)/info.Po - -rm -f ./$(DEPDIR)/invitation.Po -rm -f ./$(DEPDIR)/list.Po -rm -f ./$(DEPDIR)/logger.Po -rm -f ./$(DEPDIR)/meta.Po -rm -f ./$(DEPDIR)/multicast_device.Po - -rm -f ./$(DEPDIR)/names.Po -rm -f ./$(DEPDIR)/net.Po -rm -f ./$(DEPDIR)/net_packet.Po -rm -f ./$(DEPDIR)/net_setup.Po -rm -f ./$(DEPDIR)/net_socket.Po -rm -f ./$(DEPDIR)/netutl.Po -rm -f ./$(DEPDIR)/node.Po + -rm -f ./$(DEPDIR)/pidfile.Po -rm -f ./$(DEPDIR)/process.Po -rm -f ./$(DEPDIR)/protocol.Po -rm -f ./$(DEPDIR)/protocol_auth.Po @@ -1252,57 +738,19 @@ distclean: distclean-am -rm -f ./$(DEPDIR)/protocol_key.Po -rm -f ./$(DEPDIR)/protocol_misc.Po -rm -f ./$(DEPDIR)/protocol_subnet.Po + -rm -f ./$(DEPDIR)/proxy.Po -rm -f ./$(DEPDIR)/raw_socket_device.Po -rm -f ./$(DEPDIR)/route.Po - -rm -f ./$(DEPDIR)/script.Po - -rm -f ./$(DEPDIR)/splay_tree.Po - -rm -f ./$(DEPDIR)/sptps.Po - -rm -f ./$(DEPDIR)/sptps_keypair.Po - -rm -f ./$(DEPDIR)/sptps_speed.Po - -rm -f ./$(DEPDIR)/sptps_test.Po -rm -f ./$(DEPDIR)/subnet.Po - -rm -f ./$(DEPDIR)/subnet_parse.Po - -rm -f ./$(DEPDIR)/tincctl.Po -rm -f ./$(DEPDIR)/tincd.Po - -rm -f ./$(DEPDIR)/top.Po -rm -f ./$(DEPDIR)/uml_device.Po - -rm -f ./$(DEPDIR)/upnp.Po -rm -f ./$(DEPDIR)/utils.Po -rm -f ./$(DEPDIR)/vde_device.Po - -rm -f ./$(DEPDIR)/version.Po -rm -f bsd/$(DEPDIR)/device.Po -rm -f bsd/$(DEPDIR)/tunemu.Po - -rm -f chacha-poly1305/$(DEPDIR)/chacha-poly1305.Po - -rm -f chacha-poly1305/$(DEPDIR)/chacha.Po - -rm -f chacha-poly1305/$(DEPDIR)/poly1305.Po -rm -f cygwin/$(DEPDIR)/device.Po - -rm -f ed25519/$(DEPDIR)/ecdh.Po - -rm -f ed25519/$(DEPDIR)/ecdsa.Po - -rm -f ed25519/$(DEPDIR)/ecdsagen.Po - -rm -f ed25519/$(DEPDIR)/fe.Po - -rm -f ed25519/$(DEPDIR)/ge.Po - -rm -f ed25519/$(DEPDIR)/key_exchange.Po - -rm -f ed25519/$(DEPDIR)/keypair.Po - -rm -f ed25519/$(DEPDIR)/sc.Po - -rm -f ed25519/$(DEPDIR)/sha512.Po - -rm -f ed25519/$(DEPDIR)/sign.Po - -rm -f ed25519/$(DEPDIR)/verify.Po - -rm -f gcrypt/$(DEPDIR)/cipher.Po - -rm -f gcrypt/$(DEPDIR)/crypto.Po - -rm -f gcrypt/$(DEPDIR)/digest.Po - -rm -f gcrypt/$(DEPDIR)/prf.Po - -rm -f gcrypt/$(DEPDIR)/rsa.Po - -rm -f gcrypt/$(DEPDIR)/rsagen.Po -rm -f linux/$(DEPDIR)/device.Po -rm -f mingw/$(DEPDIR)/device.Po - -rm -f nolegacy/$(DEPDIR)/crypto.Po - -rm -f nolegacy/$(DEPDIR)/prf.Po - -rm -f openssl/$(DEPDIR)/cipher.Po - -rm -f openssl/$(DEPDIR)/crypto.Po - -rm -f openssl/$(DEPDIR)/digest.Po - -rm -f openssl/$(DEPDIR)/prf.Po - -rm -f openssl/$(DEPDIR)/rsa.Po - -rm -f openssl/$(DEPDIR)/rsagen.Po -rm -f solaris/$(DEPDIR)/device.Po -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ @@ -1349,36 +797,29 @@ install-ps-am: installcheck-am: installcheck-sbinPROGRAMS maintainer-clean: maintainer-clean-am - -rm -f ./$(DEPDIR)/address_cache.Po - -rm -f ./$(DEPDIR)/autoconnect.Po - -rm -f ./$(DEPDIR)/buffer.Po + -rm -f ./$(DEPDIR)/avl_tree.Po -rm -f ./$(DEPDIR)/conf.Po -rm -f ./$(DEPDIR)/connection.Po - -rm -f ./$(DEPDIR)/control.Po -rm -f ./$(DEPDIR)/dropin.Po -rm -f ./$(DEPDIR)/dummy_device.Po -rm -f ./$(DEPDIR)/edge.Po -rm -f ./$(DEPDIR)/event.Po - -rm -f ./$(DEPDIR)/fd_device.Po - -rm -f ./$(DEPDIR)/fsck.Po + -rm -f ./$(DEPDIR)/fake-getaddrinfo.Po + -rm -f ./$(DEPDIR)/fake-getnameinfo.Po -rm -f ./$(DEPDIR)/getopt.Po -rm -f ./$(DEPDIR)/getopt1.Po -rm -f ./$(DEPDIR)/graph.Po - -rm -f ./$(DEPDIR)/hash.Po - -rm -f ./$(DEPDIR)/ifconfig.Po - -rm -f ./$(DEPDIR)/info.Po - -rm -f ./$(DEPDIR)/invitation.Po -rm -f ./$(DEPDIR)/list.Po -rm -f ./$(DEPDIR)/logger.Po -rm -f ./$(DEPDIR)/meta.Po -rm -f ./$(DEPDIR)/multicast_device.Po - -rm -f ./$(DEPDIR)/names.Po -rm -f ./$(DEPDIR)/net.Po -rm -f ./$(DEPDIR)/net_packet.Po -rm -f ./$(DEPDIR)/net_setup.Po -rm -f ./$(DEPDIR)/net_socket.Po -rm -f ./$(DEPDIR)/netutl.Po -rm -f ./$(DEPDIR)/node.Po + -rm -f ./$(DEPDIR)/pidfile.Po -rm -f ./$(DEPDIR)/process.Po -rm -f ./$(DEPDIR)/protocol.Po -rm -f ./$(DEPDIR)/protocol_auth.Po @@ -1386,57 +827,19 @@ maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/protocol_key.Po -rm -f ./$(DEPDIR)/protocol_misc.Po -rm -f ./$(DEPDIR)/protocol_subnet.Po + -rm -f ./$(DEPDIR)/proxy.Po -rm -f ./$(DEPDIR)/raw_socket_device.Po -rm -f ./$(DEPDIR)/route.Po - -rm -f ./$(DEPDIR)/script.Po - -rm -f ./$(DEPDIR)/splay_tree.Po - -rm -f ./$(DEPDIR)/sptps.Po - -rm -f ./$(DEPDIR)/sptps_keypair.Po - -rm -f ./$(DEPDIR)/sptps_speed.Po - -rm -f ./$(DEPDIR)/sptps_test.Po -rm -f ./$(DEPDIR)/subnet.Po - -rm -f ./$(DEPDIR)/subnet_parse.Po - -rm -f ./$(DEPDIR)/tincctl.Po -rm -f ./$(DEPDIR)/tincd.Po - -rm -f ./$(DEPDIR)/top.Po -rm -f ./$(DEPDIR)/uml_device.Po - -rm -f ./$(DEPDIR)/upnp.Po -rm -f ./$(DEPDIR)/utils.Po -rm -f ./$(DEPDIR)/vde_device.Po - -rm -f ./$(DEPDIR)/version.Po -rm -f bsd/$(DEPDIR)/device.Po -rm -f bsd/$(DEPDIR)/tunemu.Po - -rm -f chacha-poly1305/$(DEPDIR)/chacha-poly1305.Po - -rm -f chacha-poly1305/$(DEPDIR)/chacha.Po - -rm -f chacha-poly1305/$(DEPDIR)/poly1305.Po -rm -f cygwin/$(DEPDIR)/device.Po - -rm -f ed25519/$(DEPDIR)/ecdh.Po - -rm -f ed25519/$(DEPDIR)/ecdsa.Po - -rm -f ed25519/$(DEPDIR)/ecdsagen.Po - -rm -f ed25519/$(DEPDIR)/fe.Po - -rm -f ed25519/$(DEPDIR)/ge.Po - -rm -f ed25519/$(DEPDIR)/key_exchange.Po - -rm -f ed25519/$(DEPDIR)/keypair.Po - -rm -f ed25519/$(DEPDIR)/sc.Po - -rm -f ed25519/$(DEPDIR)/sha512.Po - -rm -f ed25519/$(DEPDIR)/sign.Po - -rm -f ed25519/$(DEPDIR)/verify.Po - -rm -f gcrypt/$(DEPDIR)/cipher.Po - -rm -f gcrypt/$(DEPDIR)/crypto.Po - -rm -f gcrypt/$(DEPDIR)/digest.Po - -rm -f gcrypt/$(DEPDIR)/prf.Po - -rm -f gcrypt/$(DEPDIR)/rsa.Po - -rm -f gcrypt/$(DEPDIR)/rsagen.Po -rm -f linux/$(DEPDIR)/device.Po -rm -f mingw/$(DEPDIR)/device.Po - -rm -f nolegacy/$(DEPDIR)/crypto.Po - -rm -f nolegacy/$(DEPDIR)/prf.Po - -rm -f openssl/$(DEPDIR)/cipher.Po - -rm -f openssl/$(DEPDIR)/crypto.Po - -rm -f openssl/$(DEPDIR)/digest.Po - -rm -f openssl/$(DEPDIR)/prf.Po - -rm -f openssl/$(DEPDIR)/rsa.Po - -rm -f openssl/$(DEPDIR)/rsagen.Po -rm -f solaris/$(DEPDIR)/device.Po -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic @@ -1455,36 +858,25 @@ ps-am: uninstall-am: uninstall-sbinPROGRAMS -.MAKE: check-am install-am install-strip +.MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ - clean-checkPROGRAMS clean-generic clean-sbinPROGRAMS \ - cscopelist-am ctags ctags-am distclean distclean-compile \ - distclean-generic distclean-tags distdir dvi dvi-am html \ - html-am info info-am install install-am install-data \ - install-data-am install-dvi install-dvi-am install-exec \ - install-exec-am install-html install-html-am install-info \ - install-info-am install-man install-pdf install-pdf-am \ - install-ps install-ps-am install-sbinPROGRAMS install-strip \ - installcheck installcheck-am installcheck-sbinPROGRAMS \ - installdirs maintainer-clean maintainer-clean-generic \ - mostlyclean mostlyclean-compile mostlyclean-generic pdf pdf-am \ - ps ps-am tags tags-am uninstall uninstall-am \ - uninstall-sbinPROGRAMS + clean-generic clean-sbinPROGRAMS cscopelist-am ctags ctags-am \ + distclean distclean-compile distclean-generic distclean-tags \ + distdir dvi dvi-am html html-am info info-am install \ + install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-sbinPROGRAMS install-strip installcheck \ + installcheck-am installcheck-sbinPROGRAMS installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic pdf pdf-am ps ps-am \ + tags tags-am uninstall uninstall-am uninstall-sbinPROGRAMS .PRECIOUS: Makefile -.PHONY: version-stamp -version-stamp: - -version_git.h: version-stamp - $(AM_V_GEN)echo >$@ - @-(cd $(srcdir) && git describe 2>/dev/null >/dev/null) && echo '#define GIT_DESCRIPTION "'`(cd $(srcdir) && git describe) | sed 's/release-//'`'"' >$@ ||: -${srcdir}/version.c: version_git.h - -@BSD_TRUE@version.c: ${srcdir}/version.c - # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: diff --git a/src/address_cache.c b/src/address_cache.c deleted file mode 100644 index 445cd1c..0000000 --- a/src/address_cache.c +++ /dev/null @@ -1,277 +0,0 @@ -/* - address_cache.c -- Manage cache of recently seen addresses - Copyright (C) 2018 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 - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include "system.h" - -#include "address_cache.h" -#include "conf.h" -#include "names.h" -#include "netutl.h" -#include "xalloc.h" - -static const unsigned int NOT_CACHED = -1; - -// Find edges pointing to this node, and use them to build a list of unique, known addresses. -static struct addrinfo *get_known_addresses(node_t *n) { - struct addrinfo *ai = NULL; - struct addrinfo *oai = NULL; - - for splay_each(edge_t, e, n->edge_tree) { - if(!e->reverse) { - continue; - } - - bool found = false; - - for(struct addrinfo *aip = ai; aip; aip = aip->ai_next) { - if(!sockaddrcmp(&e->reverse->address, (sockaddr_t *)aip->ai_addr)) { - found = true; - break; - } - } - - if(found) { - continue; - } - - oai = ai; - ai = xzalloc(sizeof(*ai)); - ai->ai_family = e->reverse->address.sa.sa_family; - ai->ai_socktype = SOCK_STREAM; - ai->ai_protocol = IPPROTO_TCP; - ai->ai_addrlen = SALEN(e->reverse->address.sa); - ai->ai_addr = xmalloc(ai->ai_addrlen); - memcpy(ai->ai_addr, &e->reverse->address, ai->ai_addrlen); - ai->ai_next = oai; - } - - return ai; -} - -static void free_known_addresses(struct addrinfo *ai) { - for(struct addrinfo *aip = ai, *next; aip; aip = next) { - next = aip->ai_next; - free(aip); - } -} - -static unsigned int find_cached(address_cache_t *cache, const sockaddr_t *sa) { - for(unsigned int i = 0; i < cache->data.used; i++) - if(!sockaddrcmp(&cache->data.address[i], sa)) { - return i; - } - - return NOT_CACHED; -} - -void add_recent_address(address_cache_t *cache, const sockaddr_t *sa) { - // Check if it's already cached - unsigned int pos = find_cached(cache, sa); - - // It's in the first spot, so nothing to do - if(pos == 0) { - return; - } - - // Shift everything, move/add the address to the first slot - if(pos == NOT_CACHED) { - if(cache->data.used < MAX_CACHED_ADDRESSES) { - cache->data.used++; - } - - pos = cache->data.used - 1; - } - - memmove(&cache->data.address[1], &cache->data.address[0], pos * sizeof(cache->data.address[0])); - - cache->data.address[0] = *sa; - - // Write the cache - char fname[PATH_MAX]; - snprintf(fname, sizeof(fname), "%s" SLASH "cache" SLASH "%s", confbase, cache->node->name); - FILE *fp = fopen(fname, "wb"); - - if(fp) { - fwrite(&cache->data, sizeof(cache->data), 1, fp); - fclose(fp); - } -} - -const sockaddr_t *get_recent_address(address_cache_t *cache) { - // Check if there is an address in our cache of recently seen addresses - if(cache->tried < cache->data.used) { - return &cache->data.address[cache->tried++]; - } - - // Next, check any recently seen addresses not in our cache - while(cache->tried == cache->data.used) { - if(!cache->ai) { - cache->aip = cache->ai = get_known_addresses(cache->node); - } - - if(cache->ai) { - if(cache->aip) { - sockaddr_t *sa = (sockaddr_t *)cache->aip->ai_addr; - cache->aip = cache->aip->ai_next; - - if(find_cached(cache, sa) != NOT_CACHED) { - continue; - } - - return sa; - } else { - free_known_addresses(cache->ai); - cache->ai = NULL; - } - } - - cache->tried++; - } - - // Otherwise, check if there are any known Address statements - if(!cache->config_tree) { - init_configuration(&cache->config_tree); - read_host_config(cache->config_tree, cache->node->name, false); - cache->cfg = lookup_config(cache->config_tree, "Address"); - } - - while(cache->cfg && !cache->ai) { - char *address, *port; - - get_config_string(cache->cfg, &address); - - char *space = strchr(address, ' '); - - if(space) { - port = xstrdup(space + 1); - *space = 0; - } else { - if(!get_config_string(lookup_config(cache->config_tree, "Port"), &port)) { - port = xstrdup("655"); - } - } - - cache->aip = cache->ai = str2addrinfo(address, port, SOCK_STREAM); - - if(cache->ai) { - struct addrinfo *ai = NULL; - - for(; cache->aip; cache->aip = cache->aip->ai_next) { - struct addrinfo *oai = ai; - - ai = xzalloc(sizeof(*ai)); - ai->ai_family = cache->aip->ai_family; - ai->ai_socktype = cache->aip->ai_socktype; - ai->ai_protocol = cache->aip->ai_protocol; - ai->ai_addrlen = cache->aip->ai_addrlen; - ai->ai_addr = xmalloc(ai->ai_addrlen); - memcpy(ai->ai_addr, cache->aip->ai_addr, ai->ai_addrlen); - ai->ai_next = oai; - } - - freeaddrinfo(cache->ai); - cache->aip = cache->ai = ai; - } - - free(address); - free(port); - - cache->cfg = lookup_config_next(cache->config_tree, cache->cfg); - } - - if(cache->ai) { - if(cache->aip) { - sockaddr_t *sa = (sockaddr_t *)cache->aip->ai_addr; - - cache->aip = cache->aip->ai_next; - return sa; - } else { - free_known_addresses(cache->ai); - cache->ai = NULL; - } - } - - // We're all out of addresses. - exit_configuration(&cache->config_tree); - return false; -} - -address_cache_t *open_address_cache(node_t *node) { - address_cache_t *cache = xmalloc(sizeof(*cache)); - cache->node = node; - - // Try to open an existing address cache - char fname[PATH_MAX]; - snprintf(fname, sizeof(fname), "%s" SLASH "cache" SLASH "%s", confbase, node->name); - FILE *fp = fopen(fname, "rb"); - - if(!fp || fread(&cache->data, sizeof(cache->data), 1, fp) != 1 || cache->data.version != ADDRESS_CACHE_VERSION) { - memset(&cache->data, 0, sizeof(cache->data)); - } - - if(fp) { - fclose(fp); - } - - // Ensure we have a valid state - cache->config_tree = NULL; - cache->cfg = NULL; - cache->ai = NULL; - cache->aip = NULL; - cache->tried = 0; - cache->data.version = ADDRESS_CACHE_VERSION; - - if(cache->data.used > MAX_CACHED_ADDRESSES) { - cache->data.used = 0; - } - - return cache; -} - -void reset_address_cache(address_cache_t *cache, const sockaddr_t *sa) { - if(sa) { - add_recent_address(cache, sa); - } - - if(cache->config_tree) { - exit_configuration(&cache->config_tree); - } - - if(cache->ai) { - free_known_addresses(cache->ai); - } - - cache->config_tree = NULL; - cache->cfg = NULL; - cache->ai = NULL; - cache->aip = NULL; - cache->tried = 0; -} - -void close_address_cache(address_cache_t *cache) { - if(cache->config_tree) { - exit_configuration(&cache->config_tree); - } - - if(cache->ai) { - free_known_addresses(cache->ai); - } - - free(cache); -} diff --git a/src/address_cache.h b/src/address_cache.h deleted file mode 100644 index 4ce6ec5..0000000 --- a/src/address_cache.h +++ /dev/null @@ -1,50 +0,0 @@ -#ifndef TINC_ADDRESS_CACHE_H -#define TINC_ADDRESS_CACHE_H - -/* - address_cache.h -- header for address_cache.c - Copyright (C) 2018 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 - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include "net.h" - -#define MAX_CACHED_ADDRESSES 8 -#define ADDRESS_CACHE_VERSION 1 - -typedef struct address_cache_t { - struct node_t *node; - struct splay_tree_t *config_tree; - struct config_t *cfg; - struct addrinfo *ai; - struct addrinfo *aip; - unsigned int tried; - - struct { - unsigned int version; - unsigned int used; - sockaddr_t address[MAX_CACHED_ADDRESSES]; - } data; -} address_cache_t; - -void add_recent_address(address_cache_t *cache, const sockaddr_t *sa); -const sockaddr_t *get_recent_address(address_cache_t *cache); - -address_cache_t *open_address_cache(struct node_t *node); -void reset_address_cache(address_cache_t *cache, const sockaddr_t *sa); -void close_address_cache(address_cache_t *cache); - -#endif diff --git a/src/autoconnect.c b/src/autoconnect.c deleted file mode 100644 index 0fa6f4e..0000000 --- a/src/autoconnect.c +++ /dev/null @@ -1,195 +0,0 @@ -/* - autoconnect.c -- automatic connection establishment - Copyright (C) 2017 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 - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include "system.h" - -#include "connection.h" -#include "logger.h" -#include "node.h" -#include "xalloc.h" - -static void make_new_connection() { - /* Select a random node we haven't connected to yet. */ - int count = 0; - - for splay_each(node_t, n, node_tree) { - if(n == myself || n->connection || !(n->status.has_address || n->status.reachable)) { - continue; - } - - count++; - } - - if(!count) { - return; - } - - int r = rand() % count; - - for splay_each(node_t, n, node_tree) { - if(n == myself || n->connection || !(n->status.has_address || n->status.reachable)) { - continue; - } - - if(r--) { - continue; - } - - bool found = false; - - for list_each(outgoing_t, outgoing, outgoing_list) { - if(outgoing->node == n) { - found = true; - break; - } - } - - if(!found) { - logger(DEBUG_CONNECTIONS, LOG_INFO, "Autoconnecting to %s", n->name); - outgoing_t *outgoing = xzalloc(sizeof(*outgoing)); - outgoing->node = n; - list_insert_tail(outgoing_list, outgoing); - setup_outgoing_connection(outgoing, false); - } - - break; - } -} - -static void connect_to_unreachable() { - /* Select a random known node. The rationale is that if there are many - * reachable nodes, and only a few unreachable nodes, we don't want all - * reachable nodes to try to connect to the unreachable ones at the - * same time. This way, we back off automatically. Conversely, if there - * are only a few reachable nodes, and many unreachable ones, we're - * going to try harder to connect to them. */ - - int r = rand() % node_tree->count; - - for splay_each(node_t, n, node_tree) { - if(r--) { - continue; - } - - /* Is it unreachable and do we know an address for it? If not, return. */ - if(n == myself || n->connection || n->status.reachable || !n->status.has_address) { - return; - } - - /* Are we already trying to make an outgoing connection to it? If so, return. */ - for list_each(outgoing_t, outgoing, outgoing_list) { - if(outgoing->node == n) { - return; - } - } - - logger(DEBUG_CONNECTIONS, LOG_INFO, "Autoconnecting to %s", n->name); - outgoing_t *outgoing = xzalloc(sizeof(*outgoing)); - outgoing->node = n; - list_insert_tail(outgoing_list, outgoing); - setup_outgoing_connection(outgoing, false); - - return; - } -} - -static void drop_superfluous_outgoing_connection() { - /* Choose a random outgoing connection to a node that has at least one other connection. */ - int count = 0; - - for list_each(connection_t, c, connection_list) { - if(!c->edge || !c->outgoing || !c->node || c->node->edge_tree->count < 2) { - continue; - } - - count++; - } - - if(!count) { - return; - } - - int r = rand() % count; - - for list_each(connection_t, c, connection_list) { - if(!c->edge || !c->outgoing || !c->node || c->node->edge_tree->count < 2) { - continue; - } - - if(r--) { - continue; - } - - logger(DEBUG_CONNECTIONS, LOG_INFO, "Autodisconnecting from %s", c->name); - list_delete(outgoing_list, c->outgoing); - c->outgoing = NULL; - terminate_connection(c, c->edge); - break; - } -} - -static void drop_superfluous_pending_connections() { - for list_each(outgoing_t, o, outgoing_list) { - /* Only look for connections that are waiting to be retried later. */ - bool found = false; - - for list_each(connection_t, c, connection_list) { - if(c->outgoing == o) { - found = true; - break; - } - } - - if(found) { - continue; - } - - logger(DEBUG_CONNECTIONS, LOG_INFO, "Cancelled outgoing connection to %s", o->node->name); - list_delete_node(outgoing_list, node); - } -} - -void do_autoconnect() { - /* Count number of active connections. */ - int nc = 0; - - for list_each(connection_t, c, connection_list) { - if(c->edge) { - nc++; - } - } - - /* Less than 3 connections? Eagerly try to make a new one. */ - if(nc < 3) { - make_new_connection(); - return; - } - - /* More than 3 connections? See if we can get rid of a superfluous one. */ - if(nc > 3) { - drop_superfluous_outgoing_connection(); - } - - - /* Check if there are unreachable nodes that we should try to connect to. */ - connect_to_unreachable(); - - /* Drop pending outgoing connections from the outgoing list. */ - drop_superfluous_pending_connections(); -} diff --git a/src/autoconnect.h b/src/autoconnect.h deleted file mode 100644 index 82a5043..0000000 --- a/src/autoconnect.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef TINC_AUTOCONNECT_H -#define TINC_AUTOCONNECT_H - -/* - autoconnect.h -- header for autoconnect.c - Copyright (C) 2017 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 - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -extern void do_autoconnect(void); - -#endif diff --git a/src/avl_tree.c b/src/avl_tree.c new file mode 100644 index 0000000..96d3d43 --- /dev/null +++ b/src/avl_tree.c @@ -0,0 +1,757 @@ +/* + avl_tree.c -- avl_ tree and linked list convenience + Copyright (C) 1998 Michael H. Buselli + 2000-2005 Ivo Timmermans, + 2000-2015 Guus Sliepen + 2000-2005 Wessel Dankers + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + Original AVL tree library by Michael H. Buselli . + + Modified 2000-11-28 by Wessel Dankers to use counts + instead of depths, to add the ->next and ->prev and to generally obfuscate + the code. Mail me if you found a bug. + + Cleaned up and incorporated some of the ideas from the red-black tree + library for inclusion into tinc (https://www.tinc-vpn.org/) by + Guus Sliepen . +*/ + +#include "system.h" + +#include "avl_tree.h" +#include "xalloc.h" + +#ifdef AVL_COUNT +#define AVL_NODE_COUNT(n) ((n) ? (n)->count : 0) +#define AVL_L_COUNT(n) (AVL_NODE_COUNT((n)->left)) +#define AVL_R_COUNT(n) (AVL_NODE_COUNT((n)->right)) +#define AVL_CALC_COUNT(n) (AVL_L_COUNT(n) + AVL_R_COUNT(n) + 1) +#endif + +#ifdef AVL_DEPTH +#define AVL_NODE_DEPTH(n) ((n) ? (n)->depth : 0) +#define L_AVL_DEPTH(n) (AVL_NODE_DEPTH((n)->left)) +#define R_AVL_DEPTH(n) (AVL_NODE_DEPTH((n)->right)) +#define AVL_CALC_DEPTH(n) ((L_AVL_DEPTH(n)>R_AVL_DEPTH(n)?L_AVL_DEPTH(n):R_AVL_DEPTH(n)) + 1) +#endif + +#ifndef AVL_DEPTH +static int lg(unsigned int u) __attribute__((__const__)); + +static int lg(unsigned int u) { + int r = 1; + + if(!u) { + return 0; + } + + if(u & 0xffff0000) { + u >>= 16; + r += 16; + } + + if(u & 0x0000ff00) { + u >>= 8; + r += 8; + } + + if(u & 0x000000f0) { + u >>= 4; + r += 4; + } + + if(u & 0x0000000c) { + u >>= 2; + r += 2; + } + + if(u & 0x00000002) { + r++; + } + + return r; +} +#endif + +/* Internal helper functions */ + +static int avl_check_balance(const avl_node_t *node) { +#ifdef AVL_DEPTH + int d; + + d = R_AVL_DEPTH(node) - L_AVL_DEPTH(node); + + return d < -1 ? -1 : d > 1 ? 1 : 0; +#else + /* int d; + * d = lg(AVL_R_COUNT(node)) - lg(AVL_L_COUNT(node)); + * d = d<-1?-1:d>1?1:0; + */ + int pl, r; + + pl = lg(AVL_L_COUNT(node)); + r = AVL_R_COUNT(node); + + if(r >> pl + 1) { + return 1; + } + + if(pl < 2 || r >> pl - 2) { + return 0; + } + + return -1; +#endif +} + +static void avl_rebalance(avl_tree_t *tree, avl_node_t *node) { + avl_node_t *child; + avl_node_t *gchild; + avl_node_t *parent; + avl_node_t **superparent; + + while(node) { + parent = node->parent; + + superparent = + parent ? node == + parent->left ? &parent->left : &parent->right : &tree->root; + + switch(avl_check_balance(node)) { + case -1: + child = node->left; +#ifdef AVL_DEPTH + + if(L_AVL_DEPTH(child) >= R_AVL_DEPTH(child)) { +#else + + if(AVL_L_COUNT(child) >= AVL_R_COUNT(child)) { +#endif + node->left = child->right; + + if(node->left) { + node->left->parent = node; + } + + child->right = node; + node->parent = child; + *superparent = child; + child->parent = parent; +#ifdef AVL_COUNT + node->count = AVL_CALC_COUNT(node); + child->count = AVL_CALC_COUNT(child); +#endif +#ifdef AVL_DEPTH + node->depth = AVL_CALC_DEPTH(node); + child->depth = AVL_CALC_DEPTH(child); +#endif + } else { + gchild = child->right; + node->left = gchild->right; + + if(node->left) { + node->left->parent = node; + } + + child->right = gchild->left; + + if(child->right) { + child->right->parent = child; + } + + gchild->right = node; + + gchild->right->parent = gchild; + gchild->left = child; + + gchild->left->parent = gchild; + + *superparent = gchild; + gchild->parent = parent; +#ifdef AVL_COUNT + node->count = AVL_CALC_COUNT(node); + child->count = AVL_CALC_COUNT(child); + gchild->count = AVL_CALC_COUNT(gchild); +#endif +#ifdef AVL_DEPTH + node->depth = AVL_CALC_DEPTH(node); + child->depth = AVL_CALC_DEPTH(child); + gchild->depth = AVL_CALC_DEPTH(gchild); +#endif + } + + break; + + case 1: + child = node->right; +#ifdef AVL_DEPTH + + if(R_AVL_DEPTH(child) >= L_AVL_DEPTH(child)) { +#else + + if(AVL_R_COUNT(child) >= AVL_L_COUNT(child)) { +#endif + node->right = child->left; + + if(node->right) { + node->right->parent = node; + } + + child->left = node; + node->parent = child; + *superparent = child; + child->parent = parent; +#ifdef AVL_COUNT + node->count = AVL_CALC_COUNT(node); + child->count = AVL_CALC_COUNT(child); +#endif +#ifdef AVL_DEPTH + node->depth = AVL_CALC_DEPTH(node); + child->depth = AVL_CALC_DEPTH(child); +#endif + } else { + gchild = child->left; + node->right = gchild->left; + + if(node->right) { + node->right->parent = node; + } + + child->left = gchild->right; + + if(child->left) { + child->left->parent = child; + } + + gchild->left = node; + + gchild->left->parent = gchild; + gchild->right = child; + + gchild->right->parent = gchild; + + *superparent = gchild; + gchild->parent = parent; +#ifdef AVL_COUNT + node->count = AVL_CALC_COUNT(node); + child->count = AVL_CALC_COUNT(child); + gchild->count = AVL_CALC_COUNT(gchild); +#endif +#ifdef AVL_DEPTH + node->depth = AVL_CALC_DEPTH(node); + child->depth = AVL_CALC_DEPTH(child); + gchild->depth = AVL_CALC_DEPTH(gchild); +#endif + } + + break; + + default: +#ifdef AVL_COUNT + node->count = AVL_CALC_COUNT(node); +#endif +#ifdef AVL_DEPTH + node->depth = AVL_CALC_DEPTH(node); +#endif + } + + node = parent; + } +} + +/* (De)constructors */ + +avl_tree_t *avl_alloc_tree(avl_compare_t compare, avl_action_t delete) { + avl_tree_t *tree; + + tree = xmalloc_and_zero(sizeof(avl_tree_t)); + tree->compare = compare; + tree->delete = delete; + + return tree; +} + +void avl_free_tree(avl_tree_t *tree) { + free(tree); +} + +avl_node_t *avl_alloc_node(void) { + return xmalloc_and_zero(sizeof(avl_node_t)); +} + +void avl_free_node(avl_tree_t *tree, avl_node_t *node) { + if(node->data && tree->delete) { + tree->delete(node->data); + } + + free(node); +} + +/* Searching */ + +void *avl_search(const avl_tree_t *tree, const void *data) { + avl_node_t *node; + + node = avl_search_node(tree, data); + + return node ? node->data : NULL; +} + +void *avl_search_closest(const avl_tree_t *tree, const void *data, int *result) { + avl_node_t *node; + + node = avl_search_closest_node(tree, data, result); + + return node ? node->data : NULL; +} + +void *avl_search_closest_smaller(const avl_tree_t *tree, const void *data) { + avl_node_t *node; + + node = avl_search_closest_smaller_node(tree, data); + + return node ? node->data : NULL; +} + +void *avl_search_closest_greater(const avl_tree_t *tree, const void *data) { + avl_node_t *node; + + node = avl_search_closest_greater_node(tree, data); + + return node ? node->data : NULL; +} + +avl_node_t *avl_search_node(const avl_tree_t *tree, const void *data) { + avl_node_t *node; + int result; + + node = avl_search_closest_node(tree, data, &result); + + return result ? NULL : node; +} + +avl_node_t *avl_search_closest_node(const avl_tree_t *tree, const void *data, + int *result) { + avl_node_t *node; + int c; + + node = tree->root; + + if(!node) { + if(result) { + *result = 0; + } + + return NULL; + } + + for(;;) { + c = tree->compare(data, node->data); + + if(c < 0) { + if(node->left) { + node = node->left; + } else { + if(result) { + *result = -1; + } + + break; + } + } else if(c > 0) { + if(node->right) { + node = node->right; + } else { + if(result) { + *result = 1; + } + + break; + } + } else { + if(result) { + *result = 0; + } + + break; + } + } + + return node; +} + +avl_node_t *avl_search_closest_smaller_node(const avl_tree_t *tree, + const void *data) { + avl_node_t *node; + int result; + + node = avl_search_closest_node(tree, data, &result); + + if(result < 0) { + node = node->prev; + } + + return node; +} + +avl_node_t *avl_search_closest_greater_node(const avl_tree_t *tree, + const void *data) { + avl_node_t *node; + int result; + + node = avl_search_closest_node(tree, data, &result); + + if(result > 0) { + node = node->next; + } + + return node; +} + +/* Insertion and deletion */ + +avl_node_t *avl_insert(avl_tree_t *tree, void *data) { + avl_node_t *closest, *new; + int result; + + if(!tree->root) { + new = avl_alloc_node(); + new->data = data; + avl_insert_top(tree, new); + } else { + closest = avl_search_closest_node(tree, data, &result); + + switch(result) { + case -1: + new = avl_alloc_node(); + new->data = data; + avl_insert_before(tree, closest, new); + break; + + case 1: + new = avl_alloc_node(); + new->data = data; + avl_insert_after(tree, closest, new); + break; + + default: + return NULL; + } + } + +#ifdef AVL_COUNT + new->count = 1; +#endif +#ifdef AVL_DEPTH + new->depth = 1; +#endif + + return new; +} + +avl_node_t *avl_insert_node(avl_tree_t *tree, avl_node_t *node) { + avl_node_t *closest; + int result; + + if(!tree->root) { + avl_insert_top(tree, node); + } else { + closest = avl_search_closest_node(tree, node->data, &result); + + switch(result) { + case -1: + avl_insert_before(tree, closest, node); + break; + + case 1: + avl_insert_after(tree, closest, node); + break; + + case 0: + return NULL; + } + } + +#ifdef AVL_COUNT + node->count = 1; +#endif +#ifdef AVL_DEPTH + node->depth = 1; +#endif + + return node; +} + +void avl_insert_top(avl_tree_t *tree, avl_node_t *node) { + node->prev = node->next = node->parent = NULL; + tree->head = tree->tail = tree->root = node; +} + +void avl_insert_before(avl_tree_t *tree, avl_node_t *before, + avl_node_t *node) { + if(!before) { + if(tree->tail) { + avl_insert_after(tree, tree->tail, node); + } else { + avl_insert_top(tree, node); + } + + return; + } + + node->next = before; + node->parent = before; + node->prev = before->prev; + + if(before->left) { + avl_insert_after(tree, before->prev, node); + return; + } + + if(before->prev) { + before->prev->next = node; + } else { + tree->head = node; + } + + before->prev = node; + before->left = node; + + avl_rebalance(tree, before); +} + +void avl_insert_after(avl_tree_t *tree, avl_node_t *after, avl_node_t *node) { + if(!after) { + if(tree->head) { + avl_insert_before(tree, tree->head, node); + } else { + avl_insert_top(tree, node); + } + + return; + } + + if(after->right) { + avl_insert_before(tree, after->next, node); + return; + } + + node->prev = after; + node->parent = after; + node->next = after->next; + + if(after->next) { + after->next->prev = node; + } else { + tree->tail = node; + } + + after->next = node; + after->right = node; + + avl_rebalance(tree, after); +} + +avl_node_t *avl_unlink(avl_tree_t *tree, void *data) { + avl_node_t *node; + + node = avl_search_node(tree, data); + + if(node) { + avl_unlink_node(tree, node); + } + + return node; +} + +void avl_unlink_node(avl_tree_t *tree, avl_node_t *node) { + avl_node_t *parent; + avl_node_t **superparent; + avl_node_t *subst, *left, *right; + avl_node_t *balnode; + + if(node->prev) { + node->prev->next = node->next; + } else { + tree->head = node->next; + } + + if(node->next) { + node->next->prev = node->prev; + } else { + tree->tail = node->prev; + } + + parent = node->parent; + + superparent = + parent ? node == + parent->left ? &parent->left : &parent->right : &tree->root; + + left = node->left; + right = node->right; + + if(!left) { + *superparent = right; + + if(right) { + right->parent = parent; + } + + balnode = parent; + } else if(!right) { + *superparent = left; + left->parent = parent; + balnode = parent; + } else { + subst = node->prev; + + if(!subst) { // This only happens if node is not actually in a tree at all. + abort(); + } + + if(subst == left) { + balnode = subst; + } else { + balnode = subst->parent; + balnode->right = subst->left; + + if(balnode->right) { + balnode->right->parent = balnode; + } + + subst->left = left; + left->parent = subst; + } + + subst->right = right; + subst->parent = parent; + right->parent = subst; + *superparent = subst; + } + + avl_rebalance(tree, balnode); + + node->next = node->prev = node->parent = node->left = node->right = NULL; + +#ifdef AVL_COUNT + node->count = 0; +#endif +#ifdef AVL_DEPTH + node->depth = 0; +#endif +} + +void avl_delete_node(avl_tree_t *tree, avl_node_t *node) { + avl_unlink_node(tree, node); + avl_free_node(tree, node); +} + +void avl_delete(avl_tree_t *tree, void *data) { + avl_node_t *node; + + node = avl_search_node(tree, data); + + if(node) { + avl_delete_node(tree, node); + } +} + +/* Fast tree cleanup */ + +void avl_delete_tree(avl_tree_t *tree) { + avl_node_t *node, *next; + + for(node = tree->head; node; node = next) { + next = node->next; + avl_free_node(tree, node); + } + + avl_free_tree(tree); +} + +/* Tree walking */ + +void avl_foreach(const avl_tree_t *tree, avl_action_t action) { + avl_node_t *node, *next; + + for(node = tree->head; node; node = next) { + next = node->next; + action(node->data); + } +} + +void avl_foreach_node(const avl_tree_t *tree, avl_action_t action) { + avl_node_t *node, *next; + + for(node = tree->head; node; node = next) { + next = node->next; + action(node); + } +} + +/* Indexing */ + +#ifdef AVL_COUNT +unsigned int avl_count(const avl_tree_t *tree) { + return AVL_NODE_COUNT(tree->root); +} + +avl_node_t *avl_get_node(const avl_tree_t *tree, unsigned int index) { + avl_node_t *node; + unsigned int c; + + node = tree->root; + + while(node) { + c = AVL_L_COUNT(node); + + if(index < c) { + node = node->left; + } else if(index > c) { + node = node->right; + index -= c + 1; + } else { + return node; + } + } + + return NULL; +} + +unsigned int avl_index(const avl_node_t *node) { + avl_node_t *next; + unsigned int index; + + index = AVL_L_COUNT(node); + + while((next = node->parent)) { + if(node == next->right) { + index += AVL_L_COUNT(next) + 1; + } + + node = next; + } + + return index; +} +#endif +#ifdef AVL_DEPTH +unsigned int avl_depth(const avl_tree_t *tree) { + return AVL_NODE_DEPTH(tree->root); +} +#endif diff --git a/src/avl_tree.h b/src/avl_tree.h new file mode 100644 index 0000000..e8cefcf --- /dev/null +++ b/src/avl_tree.h @@ -0,0 +1,142 @@ +#ifndef TINC_AVL_TREE_H +#define TINC_AVL_TREE_H + +/* + avl_tree.h -- header file for avl_tree.c + Copyright (C) 1998 Michael H. Buselli + 2000-2005 Ivo Timmermans, + 2000-2006 Guus Sliepen + 2000-2005 Wessel Dankers + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + Original AVL tree library by Michael H. Buselli . + + Modified 2000-11-28 by Wessel Dankers to use counts + instead of depths, to add the ->next and ->prev and to generally obfuscate + the code. Mail me if you found a bug. + + Cleaned up and incorporated some of the ideas from the red-black tree + library for inclusion into tinc (https://www.tinc-vpn.org/) by + Guus Sliepen . +*/ + +#ifndef AVL_DEPTH +#ifndef AVL_COUNT +#define AVL_DEPTH +#endif +#endif + +typedef struct avl_node_t { + + /* Linked list part */ + + struct avl_node_t *next; + struct avl_node_t *prev; + + /* Tree part */ + + struct avl_node_t *parent; + struct avl_node_t *left; + struct avl_node_t *right; + +#ifdef AVL_COUNT + unsigned int count; +#endif +#ifdef AVL_DEPTH + unsigned char depth; +#endif + + /* Payload */ + + void *data; + +} avl_node_t; + +typedef int (*avl_compare_t)(const void *data1, const void *data2); +typedef void (*avl_action_t)(const void *data); +typedef void (*avl_action_node_t)(const avl_node_t *node); + +typedef struct avl_tree_t { + + /* Linked list part */ + + avl_node_t *head; + avl_node_t *tail; + + /* Tree part */ + + avl_node_t *root; + + avl_compare_t compare; + avl_action_t delete; + +} avl_tree_t; + +/* (De)constructors */ + +extern avl_tree_t *avl_alloc_tree(avl_compare_t compare, avl_action_t delete); +extern void avl_free_tree(avl_tree_t *tree); + +extern avl_node_t *avl_alloc_node(void); +extern void avl_free_node(avl_tree_t *tree, avl_node_t *node); + +/* Insertion and deletion */ + +extern avl_node_t *avl_insert(avl_tree_t *tree, void *data); +extern avl_node_t *avl_insert_node(avl_tree_t *tree, avl_node_t *node); + +extern void avl_insert_top(avl_tree_t *tree, avl_node_t *node); +extern void avl_insert_before(avl_tree_t *tree, avl_node_t *before, avl_node_t *node); +extern void avl_insert_after(avl_tree_t *tree, avl_node_t *after, avl_node_t *node); + +extern avl_node_t *avl_unlink(avl_tree_t *tree, void *data); +extern void avl_unlink_node(avl_tree_t *tree, avl_node_t *node); +extern void avl_delete(avl_tree_t *tree, void *data); +extern void avl_delete_node(avl_tree_t *tree, avl_node_t *node); + +/* Fast tree cleanup */ + +extern void avl_delete_tree(avl_tree_t *tree); + +/* Searching */ + +extern void *avl_search(const avl_tree_t *tree, const void *data); +extern void *avl_search_closest(const avl_tree_t *tree, const void *data, int *result); +extern void *avl_search_closest_smaller(const avl_tree_t *tree, const void *data); +extern void *avl_search_closest_greater(const avl_tree_t *tree, const void *data); + +extern avl_node_t *avl_search_node(const avl_tree_t *tree, const void *data); +extern avl_node_t *avl_search_closest_node(const avl_tree_t *tree, const void *data, int *result); +extern avl_node_t *avl_search_closest_smaller_node(const avl_tree_t *tree, const void *data); +extern avl_node_t *avl_search_closest_greater_node(const avl_tree_t *tree, const void *data); + +/* Tree walking */ + +extern void avl_foreach(const avl_tree_t *tree, avl_action_t action); +extern void avl_foreach_node(const avl_tree_t *tree, avl_action_t action); + +/* Indexing */ + +#ifdef AVL_COUNT +extern unsigned int avl_count(const avl_tree_t *tree); +extern avl_node_t *avl_get_node(const avl_tree_t *tree, unsigned int index); +extern unsigned int avl_index(const avl_node_t *node); +#endif +#ifdef AVL_DEPTH +extern unsigned int avl_depth(const avl_tree_t *tree); +#endif + +#endif diff --git a/src/bsd/device.c b/src/bsd/device.c index 0eeee6e..23d6d69 100644 --- a/src/bsd/device.c +++ b/src/bsd/device.c @@ -1,7 +1,7 @@ /* device.c -- Interaction BSD tun/tap device Copyright (C) 2001-2005 Ivo Timmermans, - 2001-2017 Guus Sliepen + 2001-2016 Guus Sliepen 2009 Grzegorz Dymarek This program is free software; you can redistribute it and/or modify @@ -24,14 +24,13 @@ #include "../conf.h" #include "../device.h" #include "../logger.h" -#include "../names.h" #include "../net.h" #include "../route.h" #include "../utils.h" #include "../xalloc.h" #ifdef ENABLE_TUNEMU -#include "bsd/tunemu.h" +#include "tunemu.h" #endif #ifdef HAVE_NET_IF_UTUN_H @@ -57,6 +56,8 @@ int device_fd = -1; char *device = NULL; char *iface = NULL; static const char *device_info = "OS X utun device"; +static uint64_t device_total_in = 0; +static uint64_t device_total_out = 0; #if defined(ENABLE_TUNEMU) static device_type_t device_type = DEVICE_TYPE_TUNEMU; #elif defined(HAVE_OPENBSD) || defined(HAVE_FREEBSD) || defined(HAVE_DRAGONFLY) @@ -70,7 +71,7 @@ static bool setup_utun(void) { device_fd = socket(PF_SYSTEM, SOCK_DGRAM, SYSPROTO_CONTROL); if(device_fd == -1) { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not open PF_SYSTEM socket: %s\n", strerror(errno)); + logger(LOG_ERR, "Could not open PF_SYSTEM socket: %s\n", strerror(errno)); return false; } @@ -79,7 +80,7 @@ static bool setup_utun(void) { strlcpy(info.ctl_name, UTUN_CONTROL_NAME, sizeof(info.ctl_name)); if(ioctl(device_fd, CTLIOCGINFO, &info) == -1) { - logger(DEBUG_ALWAYS, LOG_ERR, "ioctl(CTLIOCGINFO) failed: %s", strerror(errno)); + logger(LOG_ERR, "ioctl(CTLIOCGINFO) failed: %s", strerror(errno)); return false; } @@ -103,7 +104,7 @@ static bool setup_utun(void) { }; if(connect(device_fd, (struct sockaddr *)&sc, sizeof(sc)) == -1) { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not connect utun socket: %s\n", strerror(errno)); + logger(LOG_ERR, "Could not connect utun socket: %s\n", strerror(errno)); return false; } @@ -116,14 +117,22 @@ static bool setup_utun(void) { iface = xstrdup(name); } - logger(DEBUG_ALWAYS, LOG_INFO, "%s is a %s", device, device_info); + logger(LOG_INFO, "%s is a %s", device, device_info); return true; } #endif static bool setup_device(void) { - get_config_string(lookup_config(config_tree, "Device"), &device); + // Find out which device file to open + + if(!get_config_string(lookup_config(config_tree, "Device"), &device)) { + if(routing_mode == RMODE_ROUTER) { + device = xstrdup(DEFAULT_TUN_DEVICE); + } else { + device = xstrdup(DEFAULT_TAP_DEVICE); + } + } // Find out if it's supposed to be a tun or a tap device @@ -152,36 +161,26 @@ static bool setup_device(void) { } else if(!strcasecmp(type, "tap")) { device_type = DEVICE_TYPE_TAP; } else { - logger(DEBUG_ALWAYS, LOG_ERR, "Unknown device type %s!", type); + logger(LOG_ERR, "Unknown device type %s!", type); return false; } } else { #ifdef HAVE_NET_IF_UTUN_H - if(device && (strncmp(device, "utun", 4) == 0 || strncmp(device, "/dev/utun", 9) == 0)) { + if(strncmp(device, "utun", 4) == 0 || strncmp(device, "/dev/utun", 9) == 0) { device_type = DEVICE_TYPE_UTUN; } else #endif - if((device && strstr(device, "tap")) || routing_mode != RMODE_ROUTER) { + if(strstr(device, "tap") || routing_mode != RMODE_ROUTER) { device_type = DEVICE_TYPE_TAP; } } if(routing_mode == RMODE_SWITCH && device_type != DEVICE_TYPE_TAP) { - logger(DEBUG_ALWAYS, LOG_ERR, "Only tap devices support switch mode!"); + logger(LOG_ERR, "Only tap devices support switch mode!"); return false; } - // Find out which device file to open - - if(!device) { - if(device_type == DEVICE_TYPE_TAP) { - device = xstrdup(DEFAULT_TAP_DEVICE); - } else { - device = xstrdup(DEFAULT_TUN_DEVICE); - } - } - // Open the device switch(device_type) { @@ -204,7 +203,7 @@ static bool setup_device(void) { } if(device_fd < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not open %s: %s", device, strerror(errno)); + logger(LOG_ERR, "Could not open %s: %s", device, strerror(errno)); return false; } @@ -234,7 +233,7 @@ static bool setup_device(void) { if(!get_config_string(lookup_config(config_tree, "Interface"), &iface)) { iface = xstrdup(strrchr(realname, '/') ? strrchr(realname, '/') + 1 : realname); } else if(strcmp(iface, strrchr(realname, '/') ? strrchr(realname, '/') + 1 : realname)) { - logger(DEBUG_ALWAYS, LOG_WARNING, "Warning: Interface does not match Device. $INTERFACE might be set incorrectly."); + logger(LOG_WARNING, "Warning: Interface does not match Device. $INTERFACE might be set incorrectly."); } // Configure the device as best as we can @@ -249,7 +248,7 @@ static bool setup_device(void) { const int zero = 0; if(ioctl(device_fd, TUNSIFHEAD, &zero, sizeof(zero)) == -1) { - logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "ioctl", strerror(errno)); + logger(LOG_ERR, "System call `%s' failed: %s", "ioctl", strerror(errno)); return false; } } @@ -271,7 +270,7 @@ static bool setup_device(void) { const int one = 1; if(ioctl(device_fd, TUNSIFHEAD, &one, sizeof(one)) == -1) { - logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "ioctl", strerror(errno)); + logger(LOG_ERR, "System call `%s' failed: %s", "ioctl", strerror(errno)); return false; } } @@ -298,7 +297,10 @@ static bool setup_device(void) { struct ifreq ifr; if(ioctl(device_fd, TAPGIFNAME, (void *)&ifr) == 0) { - free(iface); + if(iface) { + free(iface); + } + iface = xstrdup(ifr.ifr_name); } } @@ -321,7 +323,7 @@ static bool setup_device(void) { #endif - logger(DEBUG_ALWAYS, LOG_INFO, "%s is a %s", device, device_info); + logger(LOG_INFO, "%s is a %s", device, device_info); return true; } @@ -339,115 +341,112 @@ static void close_device(void) { close(device_fd); } - device_fd = -1; - free(device); - device = NULL; free(iface); - iface = NULL; - device_info = NULL; } static bool read_packet(vpn_packet_t *packet) { - int inlen; + int lenin; switch(device_type) { case DEVICE_TYPE_TUN: #ifdef ENABLE_TUNEMU case DEVICE_TYPE_TUNEMU: if(device_type == DEVICE_TYPE_TUNEMU) { - inlen = tunemu_read(device_fd, DATA(packet) + 14, MTU - 14); + lenin = tunemu_read(device_fd, packet->data + 14, MTU - 14); } else #endif - inlen = read(device_fd, DATA(packet) + 14, MTU - 14); + lenin = read(device_fd, packet->data + 14, MTU - 14); - if(inlen <= 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info, + if(lenin <= 0) { + logger(LOG_ERR, "Error while reading from %s %s: %s", device_info, device, strerror(errno)); return false; } - switch(DATA(packet)[14] >> 4) { + switch(packet->data[14] >> 4) { case 4: - DATA(packet)[12] = 0x08; - DATA(packet)[13] = 0x00; + packet->data[12] = 0x08; + packet->data[13] = 0x00; break; case 6: - DATA(packet)[12] = 0x86; - DATA(packet)[13] = 0xDD; + packet->data[12] = 0x86; + packet->data[13] = 0xDD; break; default: - logger(DEBUG_TRAFFIC, LOG_ERR, - "Unknown IP version %d while reading packet from %s %s", - DATA(packet)[14] >> 4, device_info, device); + ifdebug(TRAFFIC) logger(LOG_ERR, + "Unknown IP version %d while reading packet from %s %s", + packet->data[14] >> 4, device_info, device); return false; } - memset(DATA(packet), 0, 12); - packet->len = inlen + 14; + memset(packet->data, 0, 12); + packet->len = lenin + 14; break; case DEVICE_TYPE_UTUN: case DEVICE_TYPE_TUNIFHEAD: { - if((inlen = read(device_fd, DATA(packet) + 10, MTU - 10)) <= 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info, + if((lenin = read(device_fd, packet->data + 10, MTU - 10)) <= 0) { + logger(LOG_ERR, "Error while reading from %s %s: %s", device_info, device, strerror(errno)); return false; } - switch(DATA(packet)[14] >> 4) { + switch(packet->data[14] >> 4) { case 4: - DATA(packet)[12] = 0x08; - DATA(packet)[13] = 0x00; + packet->data[12] = 0x08; + packet->data[13] = 0x00; break; case 6: - DATA(packet)[12] = 0x86; - DATA(packet)[13] = 0xDD; + packet->data[12] = 0x86; + packet->data[13] = 0xDD; break; default: - logger(DEBUG_TRAFFIC, LOG_ERR, - "Unknown IP version %d while reading packet from %s %s", - DATA(packet)[14] >> 4, device_info, device); + ifdebug(TRAFFIC) logger(LOG_ERR, + "Unknown IP version %d while reading packet from %s %s", + packet->data[14] >> 4, device_info, device); return false; } - memset(DATA(packet), 0, 12); - packet->len = inlen + 10; + memset(packet->data, 0, 12); + packet->len = lenin + 10; break; } case DEVICE_TYPE_TAP: - if((inlen = read(device_fd, DATA(packet), MTU)) <= 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info, + if((lenin = read(device_fd, packet->data, MTU)) <= 0) { + logger(LOG_ERR, "Error while reading from %s %s: %s", device_info, device, strerror(errno)); return false; } - packet->len = inlen; + packet->len = lenin; break; default: return false; } - logger(DEBUG_TRAFFIC, LOG_DEBUG, "Read packet of %d bytes from %s", - packet->len, device_info); + device_total_in += packet->len; + + ifdebug(TRAFFIC) logger(LOG_DEBUG, "Read packet of %d bytes from %s", + packet->len, device_info); return true; } static bool write_packet(vpn_packet_t *packet) { - logger(DEBUG_TRAFFIC, LOG_DEBUG, "Writing packet of %d bytes to %s", - packet->len, device_info); + ifdebug(TRAFFIC) logger(LOG_DEBUG, "Writing packet of %d bytes to %s", + packet->len, device_info); switch(device_type) { case DEVICE_TYPE_TUN: - if(write(device_fd, DATA(packet) + 14, packet->len - 14) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error while writing to %s %s: %s", device_info, + if(write(device_fd, packet->data + 14, packet->len - 14) < 0) { + logger(LOG_ERR, "Error while writing to %s %s: %s", device_info, device, strerror(errno)); return false; } @@ -456,7 +455,7 @@ static bool write_packet(vpn_packet_t *packet) { case DEVICE_TYPE_UTUN: case DEVICE_TYPE_TUNIFHEAD: { - int af = (DATA(packet)[12] << 8) + DATA(packet)[13]; + int af = (packet->data[12] << 8) + packet->data[13]; uint32_t type; switch(af) { @@ -469,16 +468,16 @@ static bool write_packet(vpn_packet_t *packet) { break; default: - logger(DEBUG_TRAFFIC, LOG_ERR, - "Unknown address family %x while writing packet to %s %s", - af, device_info, device); + ifdebug(TRAFFIC) logger(LOG_ERR, + "Unknown address family %x while writing packet to %s %s", + af, device_info, device); return false; } - memcpy(DATA(packet) + 10, &type, sizeof(type)); + memcpy(packet->data + 10, &type, sizeof(type)); - if(write(device_fd, DATA(packet) + 10, packet->len - 10) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Can't write to %s %s: %s", device_info, device, + if(write(device_fd, packet->data + 10, packet->len - 10) < 0) { + logger(LOG_ERR, "Can't write to %s %s: %s", device_info, device, strerror(errno)); return false; } @@ -487,8 +486,8 @@ static bool write_packet(vpn_packet_t *packet) { } case DEVICE_TYPE_TAP: - if(write(device_fd, DATA(packet), packet->len) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error while writing to %s %s: %s", device_info, + if(write(device_fd, packet->data, packet->len) < 0) { + logger(LOG_ERR, "Error while writing to %s %s: %s", device_info, device, strerror(errno)); return false; } @@ -498,8 +497,8 @@ static bool write_packet(vpn_packet_t *packet) { #ifdef ENABLE_TUNEMU case DEVICE_TYPE_TUNEMU: - if(tunemu_write(device_fd, DATA(packet) + 14, packet->len - 14) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error while writing to %s %s: %s", device_info, + if(tunemu_write(device_fd, packet->data + 14, packet->len - 14) < 0) { + logger(LOG_ERR, "Error while writing to %s %s: %s", device_info, device, strerror(errno)); return false; } @@ -511,12 +510,21 @@ static bool write_packet(vpn_packet_t *packet) { return false; } + device_total_out += packet->len; + return true; } +static void dump_device_stats(void) { + logger(LOG_DEBUG, "Statistics for %s %s:", device_info, device); + logger(LOG_DEBUG, " total bytes in: %10"PRIu64, device_total_in); + logger(LOG_DEBUG, " total bytes out: %10"PRIu64, device_total_out); +} + const devops_t os_devops = { .setup = setup_device, .close = close_device, .read = read_packet, .write = write_packet, + .dump_stats = dump_device_stats, }; diff --git a/src/bsd/tunemu.c b/src/bsd/tunemu.c index 2248264..7ff6f72 100644 --- a/src/bsd/tunemu.c +++ b/src/bsd/tunemu.c @@ -45,9 +45,9 @@ #define PPPIOCSFLAGS _IOW('t', 89, int) #define PPPIOCSNPMODE _IOW('t', 75, struct npioctl) #define PPPIOCATTCHAN _IOW('t', 56, int) -#define PPPIOCGCHAN _IOR('t', 55, int) +#define PPPIOCGCHAN _IOR('t', 55, int) #define PPPIOCCONNECT _IOW('t', 58, int) -#define PPPIOCGUNIT _IOR('t', 86, int) +#define PPPIOCGUNIT _IOR('t', 86, int) struct sockaddr_ppp { u_int8_t ppp_len; @@ -83,7 +83,7 @@ static char *data_buffer = NULL; static void tun_error(char *format, ...) { va_list vl; va_start(vl, format); - vsnprintf(tunemu_error, sizeof(tunemu_error), format, vl); + vsnprintf(tunemu_error, ERROR_BUFFER_SIZE, format, vl); va_end(vl); } diff --git a/src/buffer.c b/src/buffer.c deleted file mode 100644 index 60adec8..0000000 --- a/src/buffer.c +++ /dev/null @@ -1,110 +0,0 @@ -/* - buffer.c -- buffer management - Copyright (C) 2011 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 - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include "system.h" - -#include "buffer.h" -#include "xalloc.h" - -void buffer_compact(buffer_t *buffer, uint32_t maxsize) { - if(buffer->len >= maxsize || buffer->offset / 7 > buffer->len / 8) { - memmove(buffer->data, buffer->data + buffer->offset, buffer->len - buffer->offset); - buffer->len -= buffer->offset; - buffer->offset = 0; - } -} - -// Make sure we can add size bytes to the buffer, and return a pointer to the start of those bytes. - -char *buffer_prepare(buffer_t *buffer, uint32_t size) { - if(!buffer->data) { - buffer->maxlen = size; - buffer->data = xmalloc(size); - } else { - if(buffer->offset && buffer->len + size > buffer->maxlen) { - memmove(buffer->data, buffer->data + buffer->offset, buffer->len - buffer->offset); - buffer->len -= buffer->offset; - buffer->offset = 0; - } - - if(buffer->len + size > buffer->maxlen) { - buffer->maxlen = buffer->len + size; - buffer->data = xrealloc(buffer->data, buffer->maxlen); - } - } - - char *start = buffer->data + buffer->len; - - buffer->len += size; - - return start; -} - -// Copy data into the buffer. - -void buffer_add(buffer_t *buffer, const char *data, uint32_t size) { - memcpy(buffer_prepare(buffer, size), data, size); -} - -// Remove given number of bytes from the buffer, return a pointer to the start of them. - -static char *buffer_consume(buffer_t *buffer, uint32_t size) { - char *start = buffer->data + buffer->offset; - - buffer->offset += size; - - if(buffer->offset >= buffer->len) { - buffer->offset = 0; - buffer->len = 0; - } - - return start; -} - -// Check if there is a complete line in the buffer, and if so, return it NULL-terminated. - -char *buffer_readline(buffer_t *buffer) { - char *newline = memchr(buffer->data + buffer->offset, '\n', buffer->len - buffer->offset); - - if(!newline) { - return NULL; - } - - uint32_t len = newline + 1 - (buffer->data + buffer->offset); - *newline = 0; - return buffer_consume(buffer, len); -} - -// Check if we have enough bytes in the buffer, and if so, return a pointer to the start of them. - -char *buffer_read(buffer_t *buffer, uint32_t size) { - if(buffer->len - buffer->offset < size) { - return NULL; - } - - return buffer_consume(buffer, size); -} - -void buffer_clear(buffer_t *buffer) { - free(buffer->data); - buffer->data = NULL; - buffer->maxlen = 0; - buffer->len = 0; - buffer->offset = 0; -} diff --git a/src/buffer.h b/src/buffer.h deleted file mode 100644 index b25c8ad..0000000 --- a/src/buffer.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef TINC_BUFFER_H -#define TINC_BUFFER_H - -typedef struct buffer_t { - char *data; - uint32_t maxlen; - uint32_t len; - uint32_t offset; -} buffer_t; - -extern void buffer_compact(buffer_t *buffer, uint32_t maxsize); -extern char *buffer_prepare(buffer_t *buffer, uint32_t size); -extern void buffer_add(buffer_t *buffer, const char *data, uint32_t size); -extern char *buffer_readline(buffer_t *buffer); -extern char *buffer_read(buffer_t *buffer, uint32_t size); -extern void buffer_clear(buffer_t *buffer); - -#endif diff --git a/src/chacha-poly1305/chacha-poly1305.c b/src/chacha-poly1305/chacha-poly1305.c deleted file mode 100644 index a74c502..0000000 --- a/src/chacha-poly1305/chacha-poly1305.c +++ /dev/null @@ -1,106 +0,0 @@ -#include "../system.h" - -#include "../cipher.h" -#include "../xalloc.h" - -#include "chacha.h" -#include "chacha-poly1305.h" -#include "poly1305.h" - -struct chacha_poly1305_ctx { - struct chacha_ctx main_ctx, header_ctx; -}; - -chacha_poly1305_ctx_t *chacha_poly1305_init(void) { - chacha_poly1305_ctx_t *ctx = xzalloc(sizeof(*ctx)); - return ctx; -} - -void chacha_poly1305_exit(chacha_poly1305_ctx_t *ctx) { - free(ctx); -} - -bool chacha_poly1305_set_key(chacha_poly1305_ctx_t *ctx, const void *vkey) { - const uint8_t *key = vkey; - chacha_keysetup(&ctx->main_ctx, key, 256); - chacha_keysetup(&ctx->header_ctx, key + 32, 256); - return true; -} - -static void put_u64(void *vp, uint64_t v) { - uint8_t *p = (uint8_t *) vp; - - p[0] = (uint8_t)(v >> 56) & 0xff; - p[1] = (uint8_t)(v >> 48) & 0xff; - p[2] = (uint8_t)(v >> 40) & 0xff; - p[3] = (uint8_t)(v >> 32) & 0xff; - p[4] = (uint8_t)(v >> 24) & 0xff; - p[5] = (uint8_t)(v >> 16) & 0xff; - p[6] = (uint8_t)(v >> 8) & 0xff; - p[7] = (uint8_t) v & 0xff; -} - -bool chacha_poly1305_encrypt(chacha_poly1305_ctx_t *ctx, uint64_t seqnr, const void *indata, size_t inlen, void *voutdata, size_t *outlen) { - uint8_t seqbuf[8]; - const uint8_t one[8] = { 1, 0, 0, 0, 0, 0, 0, 0 }; /* NB little-endian */ - uint8_t poly_key[POLY1305_KEYLEN]; - uint8_t *outdata = voutdata; - - /* - * Run ChaCha20 once to generate the Poly1305 key. The IV is the - * packet sequence number. - */ - memset(poly_key, 0, sizeof(poly_key)); - put_u64(seqbuf, seqnr); - chacha_ivsetup(&ctx->main_ctx, seqbuf, NULL); - chacha_encrypt_bytes(&ctx->main_ctx, poly_key, poly_key, sizeof(poly_key)); - - /* Set Chacha's block counter to 1 */ - chacha_ivsetup(&ctx->main_ctx, seqbuf, one); - - chacha_encrypt_bytes(&ctx->main_ctx, indata, outdata, inlen); - poly1305_auth(outdata + inlen, outdata, inlen, poly_key); - - if(outlen) { - *outlen = inlen + POLY1305_TAGLEN; - } - - return true; -} - -bool chacha_poly1305_decrypt(chacha_poly1305_ctx_t *ctx, uint64_t seqnr, const void *vindata, size_t inlen, void *outdata, size_t *outlen) { - uint8_t seqbuf[8]; - const uint8_t one[8] = { 1, 0, 0, 0, 0, 0, 0, 0 }; /* NB little-endian */ - uint8_t expected_tag[POLY1305_TAGLEN], poly_key[POLY1305_KEYLEN]; - const uint8_t *indata = vindata; - - /* - * Run ChaCha20 once to generate the Poly1305 key. The IV is the - * packet sequence number. - */ - memset(poly_key, 0, sizeof(poly_key)); - put_u64(seqbuf, seqnr); - chacha_ivsetup(&ctx->main_ctx, seqbuf, NULL); - chacha_encrypt_bytes(&ctx->main_ctx, poly_key, poly_key, sizeof(poly_key)); - - /* Set Chacha's block counter to 1 */ - chacha_ivsetup(&ctx->main_ctx, seqbuf, one); - - /* Check tag before anything else */ - inlen -= POLY1305_TAGLEN; - const uint8_t *tag = indata + inlen; - - poly1305_auth(expected_tag, indata, inlen, poly_key); - - if(memcmp(expected_tag, tag, POLY1305_TAGLEN)) { - return false; - } - - chacha_encrypt_bytes(&ctx->main_ctx, indata, outdata, inlen); - - if(outlen) { - *outlen = inlen; - } - - return true; -} diff --git a/src/chacha-poly1305/chacha-poly1305.h b/src/chacha-poly1305/chacha-poly1305.h deleted file mode 100644 index af7eaf5..0000000 --- a/src/chacha-poly1305/chacha-poly1305.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef CHACHA_POLY1305_H -#define CHACHA_POLY1305_H - -#define CHACHA_POLY1305_KEYLEN 64 - -typedef struct chacha_poly1305_ctx chacha_poly1305_ctx_t; - -extern chacha_poly1305_ctx_t *chacha_poly1305_init(void); -extern void chacha_poly1305_exit(chacha_poly1305_ctx_t *); -extern bool chacha_poly1305_set_key(chacha_poly1305_ctx_t *ctx, const void *key); - -extern bool chacha_poly1305_encrypt(chacha_poly1305_ctx_t *ctx, uint64_t seqnr, const void *indata, size_t inlen, void *outdata, size_t *outlen); -extern bool chacha_poly1305_decrypt(chacha_poly1305_ctx_t *ctx, uint64_t seqnr, const void *indata, size_t inlen, void *outdata, size_t *outlen); - -#endif //CHACHA_POLY1305_H diff --git a/src/chacha-poly1305/chacha.c b/src/chacha-poly1305/chacha.c deleted file mode 100644 index 696f44a..0000000 --- a/src/chacha-poly1305/chacha.c +++ /dev/null @@ -1,224 +0,0 @@ -/* -chacha-merged.c version 20080118 -D. J. Bernstein -Public domain. -*/ - -#include "../system.h" - -#include "chacha.h" - -typedef struct chacha_ctx chacha_ctx; - -#define U8C(v) (v##U) -#define U32C(v) (v##U) - -#define U8V(v) ((uint8_t)(v) & U8C(0xFF)) -#define U32V(v) ((uint32_t)(v) & U32C(0xFFFFFFFF)) - -#define ROTL32(v, n) \ - (U32V((v) << (n)) | ((v) >> (32 - (n)))) - -#define U8TO32_LITTLE(p) \ - (((uint32_t)((p)[0]) ) | \ - ((uint32_t)((p)[1]) << 8) | \ - ((uint32_t)((p)[2]) << 16) | \ - ((uint32_t)((p)[3]) << 24)) - -#define U32TO8_LITTLE(p, v) \ - do { \ - (p)[0] = U8V((v) ); \ - (p)[1] = U8V((v) >> 8); \ - (p)[2] = U8V((v) >> 16); \ - (p)[3] = U8V((v) >> 24); \ - } while (0) - -#define ROTATE(v,c) (ROTL32(v,c)) -#define XOR(v,w) ((v) ^ (w)) -#define PLUS(v,w) (U32V((v) + (w))) -#define PLUSONE(v) (PLUS((v),1)) - -#define QUARTERROUND(a,b,c,d) \ - a = PLUS(a,b); d = ROTATE(XOR(d,a),16); \ - c = PLUS(c,d); b = ROTATE(XOR(b,c),12); \ - a = PLUS(a,b); d = ROTATE(XOR(d,a), 8); \ - c = PLUS(c,d); b = ROTATE(XOR(b,c), 7); - -static const char sigma[16] = "expand 32-byte k"; -static const char tau[16] = "expand 16-byte k"; - -void chacha_keysetup(chacha_ctx *x, const uint8_t *k, uint32_t kbits) { - const char *constants; - - x->input[4] = U8TO32_LITTLE(k + 0); - x->input[5] = U8TO32_LITTLE(k + 4); - x->input[6] = U8TO32_LITTLE(k + 8); - x->input[7] = U8TO32_LITTLE(k + 12); - - if(kbits == 256) { /* recommended */ - k += 16; - constants = sigma; - } else { /* kbits == 128 */ - constants = tau; - } - - x->input[8] = U8TO32_LITTLE(k + 0); - x->input[9] = U8TO32_LITTLE(k + 4); - x->input[10] = U8TO32_LITTLE(k + 8); - x->input[11] = U8TO32_LITTLE(k + 12); - x->input[0] = U8TO32_LITTLE(constants + 0); - x->input[1] = U8TO32_LITTLE(constants + 4); - x->input[2] = U8TO32_LITTLE(constants + 8); - x->input[3] = U8TO32_LITTLE(constants + 12); -} - -void chacha_ivsetup(chacha_ctx *x, const uint8_t *iv, const uint8_t *counter) { - x->input[12] = counter == NULL ? 0 : U8TO32_LITTLE(counter + 0); - x->input[13] = counter == NULL ? 0 : U8TO32_LITTLE(counter + 4); - x->input[14] = U8TO32_LITTLE(iv + 0); - x->input[15] = U8TO32_LITTLE(iv + 4); -} - -void -chacha_encrypt_bytes(chacha_ctx *x, const uint8_t *m, uint8_t *c, uint32_t bytes) { - uint32_t x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15; - uint32_t j0, j1, j2, j3, j4, j5, j6, j7, j8, j9, j10, j11, j12, j13, j14, j15; - uint8_t *ctarget = NULL; - uint8_t tmp[64]; - uint32_t i; - - if(!bytes) { - return; - } - - j0 = x->input[0]; - j1 = x->input[1]; - j2 = x->input[2]; - j3 = x->input[3]; - j4 = x->input[4]; - j5 = x->input[5]; - j6 = x->input[6]; - j7 = x->input[7]; - j8 = x->input[8]; - j9 = x->input[9]; - j10 = x->input[10]; - j11 = x->input[11]; - j12 = x->input[12]; - j13 = x->input[13]; - j14 = x->input[14]; - j15 = x->input[15]; - - for(;;) { - if(bytes < 64) { - for(i = 0; i < bytes; ++i) { - tmp[i] = m[i]; - } - - m = tmp; - ctarget = c; - c = tmp; - } - - x0 = j0; - x1 = j1; - x2 = j2; - x3 = j3; - x4 = j4; - x5 = j5; - x6 = j6; - x7 = j7; - x8 = j8; - x9 = j9; - x10 = j10; - x11 = j11; - x12 = j12; - x13 = j13; - x14 = j14; - x15 = j15; - - for(i = 20; i > 0; i -= 2) { - QUARTERROUND(x0, x4, x8, x12) - QUARTERROUND(x1, x5, x9, x13) - QUARTERROUND(x2, x6, x10, x14) - QUARTERROUND(x3, x7, x11, x15) - QUARTERROUND(x0, x5, x10, x15) - QUARTERROUND(x1, x6, x11, x12) - QUARTERROUND(x2, x7, x8, x13) - QUARTERROUND(x3, x4, x9, x14) - } - - x0 = PLUS(x0, j0); - x1 = PLUS(x1, j1); - x2 = PLUS(x2, j2); - x3 = PLUS(x3, j3); - x4 = PLUS(x4, j4); - x5 = PLUS(x5, j5); - x6 = PLUS(x6, j6); - x7 = PLUS(x7, j7); - x8 = PLUS(x8, j8); - x9 = PLUS(x9, j9); - x10 = PLUS(x10, j10); - x11 = PLUS(x11, j11); - x12 = PLUS(x12, j12); - x13 = PLUS(x13, j13); - x14 = PLUS(x14, j14); - x15 = PLUS(x15, j15); - - x0 = XOR(x0, U8TO32_LITTLE(m + 0)); - x1 = XOR(x1, U8TO32_LITTLE(m + 4)); - x2 = XOR(x2, U8TO32_LITTLE(m + 8)); - x3 = XOR(x3, U8TO32_LITTLE(m + 12)); - x4 = XOR(x4, U8TO32_LITTLE(m + 16)); - x5 = XOR(x5, U8TO32_LITTLE(m + 20)); - x6 = XOR(x6, U8TO32_LITTLE(m + 24)); - x7 = XOR(x7, U8TO32_LITTLE(m + 28)); - x8 = XOR(x8, U8TO32_LITTLE(m + 32)); - x9 = XOR(x9, U8TO32_LITTLE(m + 36)); - x10 = XOR(x10, U8TO32_LITTLE(m + 40)); - x11 = XOR(x11, U8TO32_LITTLE(m + 44)); - x12 = XOR(x12, U8TO32_LITTLE(m + 48)); - x13 = XOR(x13, U8TO32_LITTLE(m + 52)); - x14 = XOR(x14, U8TO32_LITTLE(m + 56)); - x15 = XOR(x15, U8TO32_LITTLE(m + 60)); - - j12 = PLUSONE(j12); - - if(!j12) { - j13 = PLUSONE(j13); - /* stopping at 2^70 bytes per nonce is user's responsibility */ - } - - U32TO8_LITTLE(c + 0, x0); - U32TO8_LITTLE(c + 4, x1); - U32TO8_LITTLE(c + 8, x2); - U32TO8_LITTLE(c + 12, x3); - U32TO8_LITTLE(c + 16, x4); - U32TO8_LITTLE(c + 20, x5); - U32TO8_LITTLE(c + 24, x6); - U32TO8_LITTLE(c + 28, x7); - U32TO8_LITTLE(c + 32, x8); - U32TO8_LITTLE(c + 36, x9); - U32TO8_LITTLE(c + 40, x10); - U32TO8_LITTLE(c + 44, x11); - U32TO8_LITTLE(c + 48, x12); - U32TO8_LITTLE(c + 52, x13); - U32TO8_LITTLE(c + 56, x14); - U32TO8_LITTLE(c + 60, x15); - - if(bytes <= 64) { - if(bytes < 64) { - for(i = 0; i < bytes; ++i) { - ctarget[i] = c[i]; - } - } - - x->input[12] = j12; - x->input[13] = j13; - return; - } - - bytes -= 64; - c += 64; - m += 64; - } -} diff --git a/src/chacha-poly1305/chacha.h b/src/chacha-poly1305/chacha.h deleted file mode 100644 index 103c3d8..0000000 --- a/src/chacha-poly1305/chacha.h +++ /dev/null @@ -1,24 +0,0 @@ -/* -chacha-merged.c version 20080118 -D. J. Bernstein -Public domain. -*/ - -#ifndef CHACHA_H -#define CHACHA_H - -struct chacha_ctx { - uint32_t input[16]; -}; - -#define CHACHA_MINKEYLEN 16 -#define CHACHA_NONCELEN 8 -#define CHACHA_CTRLEN 8 -#define CHACHA_STATELEN (CHACHA_NONCELEN+CHACHA_CTRLEN) -#define CHACHA_BLOCKLEN 64 - -void chacha_keysetup(struct chacha_ctx *x, const uint8_t *k, uint32_t kbits); -void chacha_ivsetup(struct chacha_ctx *x, const uint8_t *iv, const uint8_t *ctr); -void chacha_encrypt_bytes(struct chacha_ctx *x, const uint8_t *m, uint8_t *c, uint32_t bytes); - -#endif /* CHACHA_H */ diff --git a/src/chacha-poly1305/poly1305.c b/src/chacha-poly1305/poly1305.c deleted file mode 100644 index 4d99b8c..0000000 --- a/src/chacha-poly1305/poly1305.c +++ /dev/null @@ -1,205 +0,0 @@ -/* - * Public Domain poly1305 from Andrew Moon - * poly1305-donna-unrolled.c from https://github.com/floodyberry/poly1305-donna - */ - -#include "../system.h" - -#include "poly1305.h" - -#define mul32x32_64(a,b) ((uint64_t)(a) * (b)) - -#define U8TO32_LE(p) \ - (((uint32_t)((p)[0])) | \ - ((uint32_t)((p)[1]) << 8) | \ - ((uint32_t)((p)[2]) << 16) | \ - ((uint32_t)((p)[3]) << 24)) - -#define U32TO8_LE(p, v) \ - do { \ - (p)[0] = (uint8_t)((v)); \ - (p)[1] = (uint8_t)((v) >> 8); \ - (p)[2] = (uint8_t)((v) >> 16); \ - (p)[3] = (uint8_t)((v) >> 24); \ - } while (0) - -void -poly1305_auth(unsigned char out[POLY1305_TAGLEN], const unsigned char *m, size_t inlen, const unsigned char key[POLY1305_KEYLEN]) { - uint32_t t0, t1, t2, t3; - uint32_t h0, h1, h2, h3, h4; - uint32_t r0, r1, r2, r3, r4; - uint32_t s1, s2, s3, s4; - uint32_t b, nb; - size_t j; - uint64_t t[5]; - uint64_t f0, f1, f2, f3; - uint32_t g0, g1, g2, g3, g4; - uint64_t c; - unsigned char mp[16]; - - /* clamp key */ - t0 = U8TO32_LE(key + 0); - t1 = U8TO32_LE(key + 4); - t2 = U8TO32_LE(key + 8); - t3 = U8TO32_LE(key + 12); - - /* precompute multipliers */ - r0 = t0 & 0x3ffffff; - t0 >>= 26; - t0 |= t1 << 6; - r1 = t0 & 0x3ffff03; - t1 >>= 20; - t1 |= t2 << 12; - r2 = t1 & 0x3ffc0ff; - t2 >>= 14; - t2 |= t3 << 18; - r3 = t2 & 0x3f03fff; - t3 >>= 8; - r4 = t3 & 0x00fffff; - - s1 = r1 * 5; - s2 = r2 * 5; - s3 = r3 * 5; - s4 = r4 * 5; - - /* init state */ - h0 = 0; - h1 = 0; - h2 = 0; - h3 = 0; - h4 = 0; - - /* full blocks */ - if(inlen < 16) { - goto poly1305_donna_atmost15bytes; - } - -poly1305_donna_16bytes: - m += 16; - inlen -= 16; - - t0 = U8TO32_LE(m - 16); - t1 = U8TO32_LE(m - 12); - t2 = U8TO32_LE(m - 8); - t3 = U8TO32_LE(m - 4); - - h0 += t0 & 0x3ffffff; - h1 += ((((uint64_t) t1 << 32) | t0) >> 26) & 0x3ffffff; - h2 += ((((uint64_t) t2 << 32) | t1) >> 20) & 0x3ffffff; - h3 += ((((uint64_t) t3 << 32) | t2) >> 14) & 0x3ffffff; - h4 += (t3 >> 8) | (1 << 24); - -poly1305_donna_mul: - t[0] = mul32x32_64(h0, r0) + mul32x32_64(h1, s4) + mul32x32_64(h2, s3) + mul32x32_64(h3, s2) + mul32x32_64(h4, s1); - t[1] = mul32x32_64(h0, r1) + mul32x32_64(h1, r0) + mul32x32_64(h2, s4) + mul32x32_64(h3, s3) + mul32x32_64(h4, s2); - t[2] = mul32x32_64(h0, r2) + mul32x32_64(h1, r1) + mul32x32_64(h2, r0) + mul32x32_64(h3, s4) + mul32x32_64(h4, s3); - t[3] = mul32x32_64(h0, r3) + mul32x32_64(h1, r2) + mul32x32_64(h2, r1) + mul32x32_64(h3, r0) + mul32x32_64(h4, s4); - t[4] = mul32x32_64(h0, r4) + mul32x32_64(h1, r3) + mul32x32_64(h2, r2) + mul32x32_64(h3, r1) + mul32x32_64(h4, r0); - - h0 = (uint32_t) t[0] & 0x3ffffff; - c = (t[0] >> 26); - t[1] += c; - h1 = (uint32_t) t[1] & 0x3ffffff; - b = (uint32_t)(t[1] >> 26); - t[2] += b; - h2 = (uint32_t) t[2] & 0x3ffffff; - b = (uint32_t)(t[2] >> 26); - t[3] += b; - h3 = (uint32_t) t[3] & 0x3ffffff; - b = (uint32_t)(t[3] >> 26); - t[4] += b; - h4 = (uint32_t) t[4] & 0x3ffffff; - b = (uint32_t)(t[4] >> 26); - h0 += b * 5; - - if(inlen >= 16) { - goto poly1305_donna_16bytes; - } - - /* final bytes */ -poly1305_donna_atmost15bytes: - - if(!inlen) { - goto poly1305_donna_finish; - } - - for(j = 0; j < inlen; j++) { - mp[j] = m[j]; - } - - mp[j++] = 1; - - for(; j < 16; j++) { - mp[j] = 0; - } - - inlen = 0; - - t0 = U8TO32_LE(mp + 0); - t1 = U8TO32_LE(mp + 4); - t2 = U8TO32_LE(mp + 8); - t3 = U8TO32_LE(mp + 12); - - h0 += t0 & 0x3ffffff; - h1 += ((((uint64_t) t1 << 32) | t0) >> 26) & 0x3ffffff; - h2 += ((((uint64_t) t2 << 32) | t1) >> 20) & 0x3ffffff; - h3 += ((((uint64_t) t3 << 32) | t2) >> 14) & 0x3ffffff; - h4 += (t3 >> 8); - - goto poly1305_donna_mul; - -poly1305_donna_finish: - b = h0 >> 26; - h0 = h0 & 0x3ffffff; - h1 += b; - b = h1 >> 26; - h1 = h1 & 0x3ffffff; - h2 += b; - b = h2 >> 26; - h2 = h2 & 0x3ffffff; - h3 += b; - b = h3 >> 26; - h3 = h3 & 0x3ffffff; - h4 += b; - b = h4 >> 26; - h4 = h4 & 0x3ffffff; - h0 += b * 5; - b = h0 >> 26; - h0 = h0 & 0x3ffffff; - h1 += b; - - g0 = h0 + 5; - b = g0 >> 26; - g0 &= 0x3ffffff; - g1 = h1 + b; - b = g1 >> 26; - g1 &= 0x3ffffff; - g2 = h2 + b; - b = g2 >> 26; - g2 &= 0x3ffffff; - g3 = h3 + b; - b = g3 >> 26; - g3 &= 0x3ffffff; - g4 = h4 + b - (1 << 26); - - b = (g4 >> 31) - 1; - nb = ~b; - h0 = (h0 & nb) | (g0 & b); - h1 = (h1 & nb) | (g1 & b); - h2 = (h2 & nb) | (g2 & b); - h3 = (h3 & nb) | (g3 & b); - h4 = (h4 & nb) | (g4 & b); - - f0 = ((h0) | (h1 << 26)) + (uint64_t) U8TO32_LE(&key[16]); - f1 = ((h1 >> 6) | (h2 << 20)) + (uint64_t) U8TO32_LE(&key[20]); - f2 = ((h2 >> 12) | (h3 << 14)) + (uint64_t) U8TO32_LE(&key[24]); - f3 = ((h3 >> 18) | (h4 << 8)) + (uint64_t) U8TO32_LE(&key[28]); - - U32TO8_LE(&out[0], f0); - f1 += (f0 >> 32); - U32TO8_LE(&out[4], f1); - f2 += (f1 >> 32); - U32TO8_LE(&out[8], f2); - f3 += (f2 >> 32); - U32TO8_LE(&out[12], f3); -} diff --git a/src/chacha-poly1305/poly1305.h b/src/chacha-poly1305/poly1305.h deleted file mode 100644 index 4ece415..0000000 --- a/src/chacha-poly1305/poly1305.h +++ /dev/null @@ -1,16 +0,0 @@ -/* $OpenBSD: poly1305.h,v 1.2 2013/12/19 22:57:13 djm Exp $ */ - -/* - * Public Domain poly1305 from Andrew Moon - * poly1305-donna-unrolled.c from https://github.com/floodyberry/poly1305-donna - */ - -#ifndef POLY1305_H -#define POLY1305_H - -#define POLY1305_KEYLEN 32 -#define POLY1305_TAGLEN 16 - -void poly1305_auth(uint8_t out[POLY1305_TAGLEN], const uint8_t *m, size_t inlen, const uint8_t key[POLY1305_KEYLEN]); - -#endif /* POLY1305_H */ diff --git a/src/cipher.h b/src/cipher.h deleted file mode 100644 index 2845be8..0000000 --- a/src/cipher.h +++ /dev/null @@ -1,46 +0,0 @@ -#ifndef TINC_CIPHER_H -#define TINC_CIPHER_H - -/* - cipher.h -- header file cipher.c - Copyright (C) 2007-2016 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 - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#define CIPHER_MAX_BLOCK_SIZE 32 -#define CIPHER_MAX_IV_SIZE 16 -#define CIPHER_MAX_KEY_SIZE 32 - -#ifndef DISABLE_LEGACY - -typedef struct cipher cipher_t; - -extern cipher_t *cipher_open_by_name(const char *name) __attribute__((__malloc__)); -extern cipher_t *cipher_open_by_nid(int nid) __attribute__((__malloc__)); -extern void cipher_close(cipher_t *cipher); -extern size_t cipher_keylength(const cipher_t *cipher); -extern size_t cipher_blocksize(const cipher_t *cipher); -extern uint64_t cipher_budget(const cipher_t *cipher); -extern bool cipher_set_key(cipher_t *cipher, void *key, bool encrypt) __attribute__((__warn_unused_result__)); -extern bool cipher_set_key_from_rsa(cipher_t *cipher, void *rsa, size_t len, bool encrypt) __attribute__((__warn_unused_result__)); -extern bool cipher_encrypt(cipher_t *cipher, const void *indata, size_t inlen, void *outdata, size_t *outlen, bool oneshot) __attribute__((__warn_unused_result__)); -extern bool cipher_decrypt(cipher_t *cipher, const void *indata, size_t inlen, void *outdata, size_t *outlen, bool oneshot) __attribute__((__warn_unused_result__)); -extern int cipher_get_nid(const cipher_t *cipher); -extern bool cipher_active(const cipher_t *cipher); - -#endif - -#endif diff --git a/src/conf.c b/src/conf.c index a33bdfe..3f81877 100644 --- a/src/conf.c +++ b/src/conf.c @@ -1,11 +1,10 @@ /* conf.c -- configuration code - Copyright (C) 1998 Robert van der Meulen + Copyright (C) 1998 Robert van der Meulen 1998-2005 Ivo Timmermans - 2000 Cris van Pelt + 2000-2014 Guus Sliepen 2010-2011 Julien Muchembled - 2000-2015 Guus Sliepen - 2013 Florent Clairambault + 2000 Cris van Pelt 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 @@ -24,23 +23,25 @@ #include "system.h" -#include "splay_tree.h" +#include "avl_tree.h" #include "connection.h" #include "conf.h" #include "list.h" #include "logger.h" -#include "names.h" -#include "netutl.h" /* for str2address */ +#include "netutl.h" /* for str2address */ #include "protocol.h" -#include "utils.h" /* for cp */ +#include "utils.h" /* for cp */ #include "xalloc.h" -splay_tree_t *config_tree; +avl_tree_t *config_tree; -int pinginterval = 0; /* seconds between pings */ -int pingtimeout = 0; /* seconds to wait for response */ +int pinginterval = 0; /* seconds between pings */ +int pingtimeout = 0; /* seconds to wait for response */ +char *confbase = NULL; /* directory in which all config files are */ +char *netname = NULL; /* name of the vpn network */ list_t *cmdline_conf = NULL; /* global/host configuration values given at the command line */ + static int config_compare(const config_t *a, const config_t *b) { int result; @@ -66,17 +67,17 @@ static int config_compare(const config_t *a, const config_t *b) { } } -void init_configuration(splay_tree_t **config_tree) { - *config_tree = splay_alloc_tree((splay_compare_t) config_compare, (splay_action_t) free_config); +void init_configuration(avl_tree_t **config_tree) { + *config_tree = avl_alloc_tree((avl_compare_t) config_compare, (avl_action_t) free_config); } -void exit_configuration(splay_tree_t **config_tree) { - splay_delete_tree(*config_tree); +void exit_configuration(avl_tree_t **config_tree) { + avl_delete_tree(*config_tree); *config_tree = NULL; } config_t *new_config(void) { - return xzalloc(sizeof(config_t)); + return xmalloc_and_zero(sizeof(config_t)); } void free_config(config_t *cfg) { @@ -86,18 +87,18 @@ void free_config(config_t *cfg) { free(cfg); } -void config_add(splay_tree_t *config_tree, config_t *cfg) { - splay_insert(config_tree, cfg); +void config_add(avl_tree_t *config_tree, config_t *cfg) { + avl_insert(config_tree, cfg); } -config_t *lookup_config(splay_tree_t *config_tree, char *variable) { +config_t *lookup_config(const avl_tree_t *config_tree, char *variable) { config_t cfg, *found; cfg.variable = variable; cfg.file = NULL; cfg.line = 0; - found = splay_search_closest_greater(config_tree, &cfg); + found = avl_search_closest_greater(config_tree, &cfg); if(!found) { return NULL; @@ -110,11 +111,11 @@ config_t *lookup_config(splay_tree_t *config_tree, char *variable) { return found; } -config_t *lookup_config_next(splay_tree_t *config_tree, const config_t *cfg) { - splay_node_t *node; +config_t *lookup_config_next(const avl_tree_t *config_tree, const config_t *cfg) { + avl_node_t *node; config_t *found; - node = splay_search_node(config_tree, cfg); + node = avl_search_node(config_tree, cfg); if(node) { if(node->next) { @@ -142,7 +143,7 @@ bool get_config_bool(const config_t *cfg, bool *result) { return true; } - logger(DEBUG_ALWAYS, LOG_ERR, "\"yes\" or \"no\" expected for configuration variable %s in %s line %d", + logger(LOG_ERR, "\"yes\" or \"no\" expected for configuration variable %s in %s line %d", cfg->variable, cfg->file, cfg->line); return false; @@ -157,7 +158,7 @@ bool get_config_int(const config_t *cfg, int *result) { return true; } - logger(DEBUG_ALWAYS, LOG_ERR, "Integer expected for configuration variable %s in %s line %d", + logger(LOG_ERR, "Integer expected for configuration variable %s in %s line %d", cfg->variable, cfg->file, cfg->line); return false; @@ -187,7 +188,7 @@ bool get_config_address(const config_t *cfg, struct addrinfo **result) { return true; } - logger(DEBUG_ALWAYS, LOG_ERR, "Hostname or IP address expected for configuration variable %s in %s line %d", + logger(LOG_ERR, "Hostname or IP address expected for configuration variable %s in %s line %d", cfg->variable, cfg->file, cfg->line); return false; @@ -201,7 +202,7 @@ bool get_config_subnet(const config_t *cfg, subnet_t **result) { } if(!str2net(&subnet, cfg->value)) { - logger(DEBUG_ALWAYS, LOG_ERR, "Subnet expected for configuration variable %s in %s line %d", + logger(LOG_ERR, "Subnet expected for configuration variable %s in %s line %d", cfg->variable, cfg->file, cfg->line); return false; } @@ -209,10 +210,10 @@ bool get_config_subnet(const config_t *cfg, subnet_t **result) { /* Teach newbies what subnets are... */ if(((subnet.type == SUBNET_IPV4) - && !maskcheck(&subnet.net.ipv4.address, subnet.net.ipv4.prefixlength, sizeof(subnet.net.ipv4.address))) + && !maskcheck(&subnet.net.ipv4.address, subnet.net.ipv4.prefixlength, sizeof(ipv4_t))) || ((subnet.type == SUBNET_IPV6) - && !maskcheck(&subnet.net.ipv6.address, subnet.net.ipv6.prefixlength, sizeof(subnet.net.ipv6.address)))) { - logger(DEBUG_ALWAYS, LOG_ERR, "Network address and prefix length do not match for configuration variable %s in %s line %d", + && !maskcheck(&subnet.net.ipv6.address, subnet.net.ipv6.prefixlength, sizeof(ipv6_t)))) { + logger(LOG_ERR, "Network address and prefix length do not match for configuration variable %s in %s line %d", cfg->variable, cfg->file, cfg->line); return false; } @@ -245,10 +246,9 @@ static char *readline(FILE *fp, char *buf, size_t buflen) { return buf; } - /* kill newline and carriage return if necessary */ - *newline = '\0'; + *newline = '\0'; /* kill newline */ - if(newline > p && newline[-1] == '\r') { + if(newline > p && newline[-1] == '\r') { /* and carriage return if necessary */ newline[-1] = '\0'; } @@ -282,10 +282,10 @@ config_t *parse_config_line(char *line, const char *fname, int lineno) { const char err[] = "No value for variable"; if(fname) - logger(DEBUG_ALWAYS, LOG_ERR, "%s `%s' on line %d while reading config file %s", + logger(LOG_ERR, "%s `%s' on line %d while reading config file %s", err, variable, lineno, fname); else - logger(DEBUG_ALWAYS, LOG_ERR, "%s `%s' in command line option %d", + logger(LOG_ERR, "%s `%s' in command line option %d", err, variable, lineno); return NULL; @@ -304,7 +304,7 @@ config_t *parse_config_line(char *line, const char *fname, int lineno) { Parse a configuration file and put the results in the configuration tree starting at *base. */ -bool read_config_file(splay_tree_t *config_tree, const char *fname, bool verbose) { +bool read_config_file(avl_tree_t *config_tree, const char *fname) { FILE *fp; char buffer[MAX_STRING_SIZE]; char *line; @@ -316,7 +316,7 @@ bool read_config_file(splay_tree_t *config_tree, const char *fname, bool verbose fp = fopen(fname, "r"); if(!fp) { - logger(verbose ? DEBUG_ALWAYS : DEBUG_CONNECTIONS, LOG_ERR, "Cannot open config file %s: %s", fname, strerror(errno)); + logger(LOG_ERR, "Cannot open config file %s: %s", fname, strerror(errno)); return false; } @@ -364,12 +364,11 @@ bool read_config_file(splay_tree_t *config_tree, const char *fname, bool verbose return result; } -void read_config_options(splay_tree_t *config_tree, const char *prefix) { +void read_config_options(avl_tree_t *config_tree, const char *prefix) { size_t prefix_len = prefix ? strlen(prefix) : 0; for(const list_node_t *node = cmdline_conf->tail; node; node = node->prev) { const config_t *cfg = node->data; - config_t *new; if(!prefix) { if(strchr(cfg->variable, '.')) { @@ -382,7 +381,7 @@ void read_config_options(splay_tree_t *config_tree, const char *prefix) { } } - new = new_config(); + config_t *new = new_config(); if(prefix) { new->variable = xstrdup(cfg->variable + prefix_len + 1); @@ -404,14 +403,14 @@ bool read_server_config(void) { read_config_options(config_tree, NULL); - snprintf(fname, sizeof(fname), "%s" SLASH "tinc.conf", confbase); + snprintf(fname, sizeof(fname), "%s/tinc.conf", confbase); errno = 0; - x = read_config_file(config_tree, fname, true); + x = read_config_file(config_tree, fname); // We will try to read the conf files in the "conf.d" dir if(x) { char dname[PATH_MAX]; - snprintf(dname, sizeof(dname), "%s" SLASH "conf.d", confbase); + snprintf(dname, sizeof(dname), "%s/conf.d", confbase); DIR *dir = opendir(dname); // If we can find this dir @@ -424,12 +423,12 @@ bool read_server_config(void) { // And we try to read the ones that end with ".conf" if(l > 5 && !strcmp(".conf", & ep->d_name[ l - 5 ])) { - if((size_t)snprintf(fname, sizeof(fname), "%s" SLASH "%s", dname, ep->d_name) >= sizeof(fname)) { - logger(DEBUG_ALWAYS, LOG_ERR, "Pathname too long: %s/%s", dname, ep->d_name); + if((size_t)snprintf(fname, sizeof(fname), "%s/%s", dname, ep->d_name) >= sizeof(fname)) { + logger(LOG_ERR, "Pathname too long: %s/%s", dname, ep->d_name); return false; } - x = read_config_file(config_tree, fname, true); + x = read_config_file(config_tree, fname); } } @@ -438,32 +437,166 @@ bool read_server_config(void) { } if(!x && errno) { - logger(DEBUG_ALWAYS, LOG_ERR, "Failed to read `%s': %s", fname, strerror(errno)); + logger(LOG_ERR, "Failed to read `%s': %s", fname, strerror(errno)); } return x; } -bool read_host_config(splay_tree_t *config_tree, const char *name, bool verbose) { - read_config_options(config_tree, name); - +bool read_connection_config(connection_t *c) { char fname[PATH_MAX]; - snprintf(fname, sizeof(fname), "%s" SLASH "hosts" SLASH "%s", confbase, name); - return read_config_file(config_tree, fname, verbose); + bool x; + + read_config_options(c->config_tree, c->name); + + snprintf(fname, sizeof(fname), "%s/hosts/%s", confbase, c->name); + x = read_config_file(c->config_tree, fname); + + return x; } -bool append_config_file(const char *name, const char *key, const char *value) { - char fname[PATH_MAX]; - snprintf(fname, sizeof(fname), "%s" SLASH "hosts" SLASH "%s", confbase, name); +static void disable_old_keys(const char *filename) { + char tmpfile[PATH_MAX] = ""; + char buf[1024]; + bool disabled = false; + FILE *r, *w; - FILE *fp = fopen(fname, "a"); + r = fopen(filename, "r"); - if(!fp) { - logger(DEBUG_ALWAYS, LOG_DEBUG, "Cannot open config file %s: %s", fname, strerror(errno)); - return false; + if(!r) { + return; } - fprintf(fp, "\n# The following line was automatically added by tinc\n%s = %s\n", key, value); - fclose(fp); - return true; + int len = snprintf(tmpfile, sizeof(tmpfile), "%s.tmp", filename); + + if(len < 0 || len >= PATH_MAX) { + fprintf(stderr, "Pathname too long: %s.tmp\n", filename); + w = NULL; + } else { + w = fopen(tmpfile, "w"); + } + + while(fgets(buf, sizeof(buf), r)) { + if(!strncmp(buf, "-----BEGIN RSA", 14)) { + buf[11] = 'O'; + buf[12] = 'L'; + buf[13] = 'D'; + disabled = true; + } else if(!strncmp(buf, "-----END RSA", 12)) { + buf[ 9] = 'O'; + buf[10] = 'L'; + buf[11] = 'D'; + disabled = true; + } + + if(w && fputs(buf, w) < 0) { + disabled = false; + break; + } + } + + if(w) { + fclose(w); + } + + fclose(r); + + if(!w && disabled) { + fprintf(stderr, "Warning: old key(s) found, remove them by hand!\n"); + return; + } + + if(disabled) { +#ifdef HAVE_MINGW + // We cannot atomically replace files on Windows. + char bakfile[PATH_MAX] = ""; + snprintf(bakfile, sizeof(bakfile), "%s.bak", filename); + + if(rename(filename, bakfile) || rename(tmpfile, filename)) { + rename(bakfile, filename); +#else + + if(rename(tmpfile, filename)) { +#endif + fprintf(stderr, "Warning: old key(s) found, remove them by hand!\n"); + } else { +#ifdef HAVE_MINGW + unlink(bakfile); +#endif + fprintf(stderr, "Warning: old key(s) found and disabled.\n"); + } + } + + unlink(tmpfile); } + +FILE *ask_and_open(const char *filename, const char *what) { + FILE *r; + char directory[PATH_MAX]; + char line[PATH_MAX]; + char abspath[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 = 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, line, sizeof(line)); + + if(!fn) { + fprintf(stderr, "Error while reading stdin: %s\n", + strerror(errno)); + return NULL; + } + + if(!strlen(fn)) + /* User just pressed enter. */ + { + fn = filename; + } + } + +#ifdef HAVE_MINGW + + if(fn[0] != '\\' && fn[0] != '/' && !strchr(fn, ':')) { +#else + + if(fn[0] != '/') { +#endif + /* The directory is a relative path or a filename. */ + getcwd(directory, sizeof(directory)); + + if((size_t)snprintf(abspath, sizeof(abspath), "%s/%s", directory, fn) >= sizeof(abspath)) { + fprintf(stderr, "Pathname too long: %s/%s\n", directory, fn); + return NULL; + } + + fn = abspath; + } + + umask(0077); /* Disallow everything for group and other */ + + disable_old_keys(fn); + + /* Open it first to keep the inode busy */ + + r = fopen(fn, "a"); + + if(!r) { + fprintf(stderr, "Error opening file `%s': %s\n", + fn, strerror(errno)); + return NULL; + } + + return r; +} + + diff --git a/src/conf.h b/src/conf.h index 8457124..770ada7 100644 --- a/src/conf.h +++ b/src/conf.h @@ -4,7 +4,7 @@ /* conf.h -- header for conf.c Copyright (C) 1998-2005 Ivo Timmermans - 2000-2013 Guus Sliepen + 2000-2012 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 @@ -21,9 +21,8 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +#include "avl_tree.h" #include "list.h" -#include "splay_tree.h" -#include "subnet.h" typedef struct config_t { char *variable; @@ -32,33 +31,37 @@ typedef struct config_t { int line; } config_t; +#include "subnet.h" -extern splay_tree_t *config_tree; +extern avl_tree_t *config_tree; extern int pinginterval; extern int pingtimeout; extern int maxtimeout; +extern int mintimeout; extern bool bypass_security; +extern char *confbase; +extern char *netname; extern list_t *cmdline_conf; -extern void init_configuration(splay_tree_t **config_tree); -extern void exit_configuration(splay_tree_t **config_tree); +extern void init_configuration(avl_tree_t **config_tree); +extern void exit_configuration(avl_tree_t **config_tree); extern config_t *new_config(void) __attribute__((__malloc__)); -extern void free_config(config_t *config); -extern void config_add(splay_tree_t *config_tree, config_t *config); -extern config_t *lookup_config(splay_tree_t *config_tree, char *variable); -extern config_t *lookup_config_next(splay_tree_t *config_tree, const config_t *config); -extern bool get_config_bool(const config_t *config, bool *result); -extern bool get_config_int(const config_t *config, int *result); -extern bool get_config_string(const config_t *config, char **result); -extern bool get_config_address(const config_t *config, struct addrinfo **result); -extern bool get_config_subnet(const config_t *config, struct subnet_t **result); +extern void free_config(config_t *cfg); +extern void config_add(avl_tree_t *config_tree, config_t *cfg); +extern config_t *lookup_config(const avl_tree_t *config_tree, char *variable); +extern config_t *lookup_config_next(const avl_tree_t *config_tree, const config_t *cfg); +extern bool get_config_bool(const config_t *cfg, bool *result); +extern bool get_config_int(const config_t *cfg, int *result); +extern bool get_config_string(const config_t *cfg, char **result); +extern bool get_config_address(const config_t *cfg, struct addrinfo **result); +extern bool get_config_subnet(const config_t *cfg, struct subnet_t **result); extern config_t *parse_config_line(char *line, const char *fname, int lineno); -extern bool read_config_file(splay_tree_t *config_tree, const char *filename, bool verbose); -extern void read_config_options(splay_tree_t *config_tree, const char *prefix); +extern bool read_config_file(avl_tree_t *config_tree, const char *fname); +extern void read_config_options(avl_tree_t *config_tree, const char *prefix); extern bool read_server_config(void); -extern bool read_host_config(splay_tree_t *config_tree, const char *name, bool verbose); -extern bool append_config_file(const char *name, const char *key, const char *value); +extern bool read_connection_config(struct connection_t *c); +extern FILE *ask_and_open(const char *fname, const char *what); #endif diff --git a/src/connection.c b/src/connection.c index 1c638a4..d137af1 100644 --- a/src/connection.c +++ b/src/connection.c @@ -1,6 +1,6 @@ /* connection.c -- connection list management - Copyright (C) 2000-2013 Guus Sliepen , + Copyright (C) 2000-2016 Guus Sliepen , 2000-2005 Ivo Timmermans 2008 Max Rijevski @@ -21,68 +21,100 @@ #include "system.h" -#include "list.h" -#include "cipher.h" +#include "avl_tree.h" #include "conf.h" -#include "control_common.h" -#include "list.h" #include "logger.h" -#include "net.h" -#include "rsa.h" #include "subnet.h" #include "utils.h" #include "xalloc.h" -list_t *connection_list; +avl_tree_t *connection_tree; /* Meta connections */ connection_t *everyone; +static int connection_compare(const connection_t *a, const connection_t *b) { + return a < b ? -1 : a == b ? 0 : 1; +} + void init_connections(void) { - connection_list = list_alloc((list_action_t) free_connection); + connection_tree = avl_alloc_tree((avl_compare_t) connection_compare, (avl_action_t) free_connection); everyone = new_connection(); everyone->name = xstrdup("everyone"); everyone->hostname = xstrdup("BROADCAST"); } void exit_connections(void) { - list_delete_list(connection_list); + avl_delete_tree(connection_tree); free_connection(everyone); } connection_t *new_connection(void) { - return xzalloc(sizeof(connection_t)); + connection_t *c; + + c = xmalloc_and_zero(sizeof(connection_t)); + + if(!c) { + return NULL; + } + + gettimeofday(&c->start, NULL); + + return c; +} + +void free_connection_partially(connection_t *c) { + free(c->inkey); + free(c->outkey); + free(c->mychallenge); + free(c->hischallenge); + free(c->outbuf); + + c->inkey = NULL; + c->outkey = NULL; + c->mychallenge = NULL; + c->hischallenge = NULL; + c->outbuf = NULL; + + c->status.pinged = false; + c->status.active = false; + c->status.connecting = false; + c->status.timeout = false; + c->status.encryptout = false; + c->status.decryptin = false; + c->status.mst = false; + + c->options = 0; + c->buflen = 0; + c->reqlen = 0; + c->tcplen = 0; + c->allow_request = 0; + c->outbuflen = 0; + c->outbufsize = 0; + c->outbufstart = 0; + c->last_ping_time = 0; + c->last_flushed_time = 0; + c->inbudget = 0; + c->outbudget = 0; + + if(c->inctx) { + EVP_CIPHER_CTX_reset(c->inctx); + free(c->inctx); + c->inctx = NULL; + } + + if(c->outctx) { + EVP_CIPHER_CTX_reset(c->outctx); + free(c->outctx); + c->outctx = NULL; + } + + if(c->rsa_key) { + RSA_free(c->rsa_key); + c->rsa_key = NULL; + } } void free_connection(connection_t *c) { - if(!c) { - return; - } - -#ifndef DISABLE_LEGACY - cipher_close(c->incipher); - digest_close(c->indigest); - cipher_close(c->outcipher); - digest_close(c->outdigest); - rsa_free(c->rsa); -#endif - - sptps_stop(&c->sptps); - ecdsa_free(c->ecdsa); - - free(c->hischallenge); - free(c->mychallenge); - - buffer_clear(&c->inbuf); - buffer_clear(&c->outbuf); - - io_del(&c->io); - - if(c->socket > 0) { - if(c->status.tarpit) { - tarpit(c->socket); - } else { - closesocket(c->socket); - } - } + free_connection_partially(c); free(c->name); free(c->hostname); @@ -95,20 +127,25 @@ void free_connection(connection_t *c) { } void connection_add(connection_t *c) { - list_insert_tail(connection_list, c); + avl_insert(connection_tree, c); } void connection_del(connection_t *c) { - list_delete(connection_list, c); + avl_delete(connection_tree, c); } -bool dump_connections(connection_t *cdump) { - for list_each(connection_t, c, connection_list) { - send_request(cdump, "%d %d %s %s %x %d %x", - CONTROL, REQ_DUMP_CONNECTIONS, - c->name, c->hostname, c->options, c->socket, - bitfield_to_int(&c->status, sizeof(c->status))); +void dump_connections(void) { + avl_node_t *node; + connection_t *c; + + logger(LOG_DEBUG, "Connections:"); + + for(node = connection_tree->head; node; node = node->next) { + c = node->data; + logger(LOG_DEBUG, " %s at %s options %x socket %d status %04x outbuf %d/%d/%d", + c->name, c->hostname, c->options, c->socket, bitfield_to_int(&c->status, sizeof(c->status)), + c->outbufsize, c->outbufstart, c->outbuflen); } - return send_request(cdump, "%d %d", CONTROL, REQ_DUMP_CONNECTIONS); + logger(LOG_DEBUG, "End of connections."); } diff --git a/src/connection.h b/src/connection.h index 206417b..d619e85 100644 --- a/src/connection.h +++ b/src/connection.h @@ -3,7 +3,7 @@ /* connection.h -- header for connection.c - Copyright (C) 2000-2013 Guus Sliepen , + Copyright (C) 2000-2016 Guus Sliepen , 2000-2005 Ivo Timmermans This program is free software; you can redistribute it and/or modify @@ -21,50 +21,45 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#include "buffer.h" -#include "cipher.h" -#include "digest.h" -#include "rsa.h" -#include "list.h" -#include "sptps.h" +#include +#include + +#if OPENSSL_VERSION_NUMBER < 0x10100000L +#define EVP_CIPHER_CTX_reset(c) EVP_CIPHER_CTX_cleanup(c) +#endif + +#include "avl_tree.h" #define OPTION_INDIRECT 0x0001 #define OPTION_TCPONLY 0x0002 #define OPTION_PMTU_DISCOVERY 0x0004 #define OPTION_CLAMP_MSS 0x0008 -#define OPTION_VERSION(x) ((x) >> 24) /* Top 8 bits are for protocol minor version */ typedef struct connection_status_t { - unsigned int pinged: 1; /* sent ping */ - unsigned int unused_active: 1; - unsigned int connecting: 1; /* 1 if we are waiting for a non-blocking connect() to finish */ - unsigned int unused_termreq: 1; /* the termination of this connection was requested */ - unsigned int remove_unused: 1; /* Set to 1 if you want this connection removed */ - unsigned int timeout_unused: 1; /* 1 if gotten timeout */ - unsigned int encryptout: 1; /* 1 if we can encrypt outgoing traffic */ - unsigned int decryptin: 1; /* 1 if we have to decrypt incoming traffic */ - unsigned int mst: 1; /* 1 if this connection is part of a minimum spanning tree */ - unsigned int control: 1; /* 1 if this is a control connection */ - unsigned int pcap: 1; /* 1 if this is a control connection requesting packet capture */ - unsigned int log: 1; /* 1 if this is a control connection requesting log dump */ - unsigned int invitation: 1; /* 1 if this is an invitation */ - unsigned int invitation_used: 1; /* 1 if the invitation has been consumed */ - unsigned int tarpit: 1; /* 1 if the connection should be added to the tarpit */ - unsigned int unused: 17; + unsigned int pinged: 1; /* sent ping */ + unsigned int active: 1; /* 1 if active.. */ + unsigned int connecting: 1; /* 1 if we are waiting for a non-blocking connect() to finish */ + unsigned int unused_termreq: 1; /* the termination of this connection was requested */ + unsigned int remove: 1; /* Set to 1 if you want this connection removed */ + unsigned int timeout: 1; /* 1 if gotten timeout */ + unsigned int encryptout: 1; /* 1 if we can encrypt outgoing traffic */ + unsigned int decryptin: 1; /* 1 if we have to decrypt incoming traffic */ + unsigned int mst: 1; /* 1 if this connection is part of a minimum spanning tree */ + unsigned int proxy_passed: 1; /* 1 if we are connecting via a proxy and we have finished talking with it */ + unsigned int tarpit: 1; /* 1 if the connection should be added to the tarpit */ + unsigned int unused: 21; } connection_status_t; -#include "ecdsa.h" #include "edge.h" #include "net.h" #include "node.h" typedef struct connection_t { char *name; /* name he claims to have */ - char *hostname; /* the hostname of its real ip */ union sockaddr_t address; /* his real (internet) ip */ - int protocol_major; /* used protocol */ - int protocol_minor; /* used protocol */ + char *hostname; /* the hostname of its real ip */ + int protocol_version; /* used protocol */ int socket; /* socket used for this connection */ uint32_t options; /* options for this connection */ @@ -76,48 +71,53 @@ typedef struct connection_t { struct node_t *node; /* node associated with the other end */ struct edge_t *edge; /* edge associated with this connection */ -#ifndef DISABLE_LEGACY - rsa_t *rsa; /* his public RSA key */ - cipher_t *incipher; /* Cipher he will use to send data to us */ - cipher_t *outcipher; /* Cipher we will use to send data to him */ - digest_t *indigest; - digest_t *outdigest; - uint64_t inbudget; - uint64_t outbudget; -#endif - - ecdsa_t *ecdsa; /* his public ECDSA key */ - sptps_t sptps; - + RSA *rsa_key; /* his public/private key */ + const EVP_CIPHER *incipher; /* Cipher he will use to send data to us */ + const EVP_CIPHER *outcipher; /* Cipher we will use to send data to him */ + EVP_CIPHER_CTX *inctx; /* Context of encrypted meta data that will come from him to us */ + EVP_CIPHER_CTX *outctx; /* Context of encrypted meta data that will be sent from us to him */ + uint64_t inbudget; /* Encrypted bytes send budget */ + uint64_t outbudget; /* Encrypted bytes receive budget */ + char *inkey; /* His symmetric meta key + iv */ + char *outkey; /* Our symmetric meta key + iv */ + int inkeylength; /* Length of his key + iv */ + int outkeylength; /* Length of our key + iv */ + const EVP_MD *indigest; + const EVP_MD *outdigest; int inmaclength; int outmaclength; int incompression; int outcompression; + char *mychallenge; /* challenge we received from him */ + char *hischallenge; /* challenge we sent to him */ - char *hischallenge; /* The challenge we sent to him */ - char *mychallenge; /* The challenge we received */ - - struct buffer_t inbuf; - struct buffer_t outbuf; - io_t io; /* input/output event on this metadata connection */ - int tcplen; /* length of incoming TCPpacket */ - int sptpslen; /* length of incoming SPTPS packet */ + char buffer[MAXBUFSIZE]; /* metadata input buffer */ + int buflen; /* bytes read into buffer */ + int reqlen; /* length of incoming request */ + length_t tcplen; /* length of incoming TCPpacket */ int allow_request; /* defined if there's only one request possible */ - time_t last_ping_time; /* last time we saw some activity from the other end or pinged them */ + char *outbuf; /* metadata output buffer */ + int outbufstart; /* index of first meaningful byte in output buffer */ + int outbuflen; /* number of meaningful bytes in output buffer */ + int outbufsize; /* number of bytes allocated to output buffer */ - splay_tree_t *config_tree; /* Pointer to configuration tree belonging to him */ + time_t last_ping_time; /* last time we saw some activity from the other end or pinged them */ + time_t last_flushed_time; /* last time buffer was empty. Only meaningful if outbuflen > 0 */ + + avl_tree_t *config_tree; /* Pointer to configuration tree belonging to him */ } connection_t; -extern list_t *connection_list; +extern avl_tree_t *connection_tree; extern connection_t *everyone; extern void init_connections(void); extern void exit_connections(void); extern connection_t *new_connection(void) __attribute__((__malloc__)); extern void free_connection(connection_t *c); +extern void free_connection_partially(connection_t *c); extern void connection_add(connection_t *c); extern void connection_del(connection_t *c); -extern bool dump_connections(struct connection_t *c); +extern void dump_connections(void); #endif diff --git a/src/control.c b/src/control.c deleted file mode 100644 index 71258b5..0000000 --- a/src/control.c +++ /dev/null @@ -1,241 +0,0 @@ -/* - control.c -- Control socket handling. - Copyright (C) 2013 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 - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include "system.h" -#include "crypto.h" -#include "conf.h" -#include "control.h" -#include "control_common.h" -#include "graph.h" -#include "logger.h" -#include "meta.h" -#include "names.h" -#include "net.h" -#include "netutl.h" -#include "protocol.h" -#include "route.h" -#include "utils.h" -#include "xalloc.h" - -char controlcookie[65]; - -static bool control_return(connection_t *c, int type, int error) { - return send_request(c, "%d %d %d", CONTROL, type, error); -} - -static bool control_ok(connection_t *c, int type) { - return control_return(c, type, 0); -} - -bool control_h(connection_t *c, const char *request) { - int type; - - if(!c->status.control || c->allow_request != CONTROL) { - logger(DEBUG_ALWAYS, LOG_ERR, "Unauthorized control request from %s (%s)", c->name, c->hostname); - return false; - } - - if(sscanf(request, "%*d %d", &type) != 1) { - logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "CONTROL", c->name, c->hostname); - return false; - } - - switch(type) { - case REQ_STOP: - event_exit(); - return control_ok(c, REQ_STOP); - - case REQ_DUMP_NODES: - return dump_nodes(c); - - case REQ_DUMP_EDGES: - return dump_edges(c); - - case REQ_DUMP_SUBNETS: - return dump_subnets(c); - - case REQ_DUMP_CONNECTIONS: - return dump_connections(c); - - case REQ_PURGE: - purge(); - return control_ok(c, REQ_PURGE); - - case REQ_SET_DEBUG: { - int new_level; - - if(sscanf(request, "%*d %*d %d", &new_level) != 1) { - return false; - } - - send_request(c, "%d %d %d", CONTROL, REQ_SET_DEBUG, debug_level); - - if(new_level >= 0) { - debug_level = new_level; - } - - return true; - } - - case REQ_RETRY: - retry(); - return control_ok(c, REQ_RETRY); - - case REQ_RELOAD: - logger(DEBUG_ALWAYS, LOG_NOTICE, "Got '%s' command", "reload"); - int result = reload_configuration(); - return control_return(c, REQ_RELOAD, result); - - case REQ_DISCONNECT: { - char name[MAX_STRING_SIZE]; - bool found = false; - - if(sscanf(request, "%*d %*d " MAX_STRING, name) != 1) { - return control_return(c, REQ_DISCONNECT, -1); - } - - for list_each(connection_t, other, connection_list) { - if(strcmp(other->name, name)) { - continue; - } - - terminate_connection(other, other->edge); - found = true; - } - - return control_return(c, REQ_DISCONNECT, found ? 0 : -2); - } - - case REQ_DUMP_TRAFFIC: - return dump_traffic(c); - - case REQ_PCAP: - sscanf(request, "%*d %*d %d", &c->outmaclength); - c->status.pcap = true; - pcap = true; - return true; - - case REQ_LOG: - sscanf(request, "%*d %*d %d", &c->outcompression); - c->status.log = true; - logcontrol = true; - return true; - - default: - return send_request(c, "%d %d", CONTROL, REQ_INVALID); - } -} - -bool init_control(void) { - randomize(controlcookie, sizeof(controlcookie) / 2); - bin2hex(controlcookie, controlcookie, sizeof(controlcookie) / 2); - - mode_t mask = umask(0); - umask(mask | 077); - FILE *f = fopen(pidfilename, "w"); - umask(mask); - - if(!f) { - logger(DEBUG_ALWAYS, LOG_ERR, "Cannot write control socket cookie file %s: %s", pidfilename, strerror(errno)); - return false; - } - - // Get the address and port of the first listening socket - - char *localhost = NULL; - sockaddr_t sa = {0}; - socklen_t len = sizeof(sa); - - // Make sure we have a valid address, and map 0.0.0.0 and :: to 127.0.0.1 and ::1. - - if(getsockname(listen_socket[0].tcp.fd, &sa.sa, &len)) { - xasprintf(&localhost, "127.0.0.1 port %s", myport); - } else { - if(sa.sa.sa_family == AF_INET) { - if(sa.in.sin_addr.s_addr == 0) { - sa.in.sin_addr.s_addr = htonl(0x7f000001); - } - } else if(sa.sa.sa_family == AF_INET6) { - static const uint8_t zero[16] = {0}; - - if(!memcmp(sa.in6.sin6_addr.s6_addr, zero, sizeof(zero))) { - sa.in6.sin6_addr.s6_addr[15] = 1; - } - } - - localhost = sockaddr2hostname(&sa); - } - - fprintf(f, "%d %s %s\n", (int)getpid(), controlcookie, localhost); - - free(localhost); - fclose(f); - -#ifndef HAVE_MINGW - int unix_fd = socket(AF_UNIX, SOCK_STREAM, 0); - - if(unix_fd < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not create UNIX socket: %s", sockstrerror(sockerrno)); - return false; - } - - struct sockaddr_un sa_un; - - sa_un.sun_family = AF_UNIX; - - strncpy(sa_un.sun_path, unixsocketname, sizeof(sa_un.sun_path)); - - sa_un.sun_path[sizeof(sa_un.sun_path) - 1] = 0; - - if(connect(unix_fd, (struct sockaddr *)&sa_un, sizeof(sa_un)) >= 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "UNIX socket %s is still in use!", unixsocketname); - return false; - } - - unlink(unixsocketname); - - umask(mask | 077); - int result = bind(unix_fd, (struct sockaddr *)&sa_un, sizeof(sa_un)); - umask(mask); - - if(result < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not bind UNIX socket to %s: %s", unixsocketname, sockstrerror(sockerrno)); - return false; - } - - if(listen(unix_fd, 3) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not listen on UNIX socket %s: %s", unixsocketname, sockstrerror(sockerrno)); - return false; - } - - io_add(&unix_socket, handle_new_unix_connection, &unix_socket, unix_fd, IO_READ); -#endif - - return true; -} - -void exit_control(void) { -#ifndef HAVE_MINGW - unlink(unixsocketname); - io_del(&unix_socket); - close(unix_socket.fd); -#endif - - unlink(pidfilename); -} diff --git a/src/control.h b/src/control.h deleted file mode 100644 index 9398410..0000000 --- a/src/control.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef TINC_CONTROL_H -#define TINC_CONTROL_H - -/* - control.h -- header for control.c. - Copyright (C) 2007 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 - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -extern bool init_control(void); -extern void exit_control(void); -extern char controlcookie[]; - -#endif diff --git a/src/control_common.h b/src/control_common.h deleted file mode 100644 index 2be4abd..0000000 --- a/src/control_common.h +++ /dev/null @@ -1,48 +0,0 @@ -#ifndef TINC_CONTROL_COMMON_H -#define TINC_CONTROL_COMMON_H - -/* - control_protocol.h -- control socket protocol. - Copyright (C) 2007 Scott Lamb - 2009-2012 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 - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include "protocol.h" - -enum request_type { - REQ_INVALID = -1, - REQ_STOP = 0, - REQ_RELOAD, - REQ_RESTART, - REQ_DUMP_NODES, - REQ_DUMP_EDGES, - REQ_DUMP_SUBNETS, - REQ_DUMP_CONNECTIONS, - REQ_DUMP_GRAPH, - REQ_PURGE, - REQ_SET_DEBUG, - REQ_RETRY, - REQ_CONNECT, - REQ_DISCONNECT, - REQ_DUMP_TRAFFIC, - REQ_PCAP, - REQ_LOG, -}; - -#define TINC_CTL_VERSION_CURRENT 0 - -#endif diff --git a/src/crypto.h b/src/crypto.h deleted file mode 100644 index 74bab1b..0000000 --- a/src/crypto.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef TINC_CRYPTO_H -#define TINC_CRYPTO_H - -/* - crypto.h -- header for crypto.c - Copyright (C) 2007-2013 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 - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -extern void crypto_init(void); -extern void crypto_exit(void); -extern void randomize(void *buf, size_t buflen); - -#endif diff --git a/src/cygwin/device.c b/src/cygwin/device.c index 6d94988..1165d67 100644 --- a/src/cygwin/device.c +++ b/src/cygwin/device.c @@ -1,7 +1,7 @@ /* device.c -- Interaction with Windows tap driver in a Cygwin environment Copyright (C) 2002-2005 Ivo Timmermans, - 2002-2014 Guus Sliepen + 2002-2016 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 @@ -27,7 +27,6 @@ #include "../conf.h" #include "../device.h" #include "../logger.h" -#include "../names.h" #include "../route.h" #include "../utils.h" #include "../xalloc.h" @@ -40,6 +39,9 @@ char *device = NULL; char *iface = NULL; static const char *device_info = "Windows tap device"; +static uint64_t device_total_in = 0; +static uint64_t device_total_out = 0; + static pid_t reader_pid; static int sp[2]; @@ -66,7 +68,7 @@ static bool setup_device(void) { /* Open registry and look for network adapters */ if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, NETWORK_CONNECTIONS_KEY, 0, KEY_READ, &key)) { - logger(DEBUG_ALWAYS, LOG_ERR, "Unable to read registry: %s", winerror(GetLastError())); + logger(LOG_ERR, "Unable to read registry: %s", winerror(GetLastError())); return false; } @@ -125,7 +127,7 @@ static bool setup_device(void) { RegCloseKey(key); if(!found) { - logger(DEBUG_ALWAYS, LOG_ERR, "No Windows tap device found!"); + logger(LOG_ERR, "No Windows tap device found!"); return false; } @@ -144,7 +146,7 @@ static bool setup_device(void) { Furthermore I don't really know how to do it the "Windows" way. */ if(socketpair(AF_UNIX, SOCK_DGRAM, PF_UNIX, sp)) { - logger(DEBUG_ALWAYS, LOG_DEBUG, "System call `%s' failed: %s", "socketpair", strerror(errno)); + logger(LOG_DEBUG, "System call `%s' failed: %s", "socketpair", strerror(errno)); return false; } @@ -153,7 +155,7 @@ static bool setup_device(void) { device_handle = CreateFile(tapname, GENERIC_WRITE, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM, 0); if(device_handle == INVALID_HANDLE_VALUE) { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not open Windows tap device %s (%s) for writing: %s", device, iface, winerror(GetLastError())); + logger(LOG_ERR, "Could not open Windows tap device %s (%s) for writing: %s", device, iface, winerror(GetLastError())); return false; } @@ -162,7 +164,7 @@ static bool setup_device(void) { /* Get MAC address from tap device */ if(!DeviceIoControl(device_handle, TAP_IOCTL_GET_MAC, mymac.x, sizeof(mymac.x), mymac.x, sizeof(mymac.x), &len, 0)) { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not get MAC address from Windows tap device %s (%s): %s", device, iface, winerror(GetLastError())); + logger(LOG_ERR, "Could not get MAC address from Windows tap device %s (%s): %s", device, iface, winerror(GetLastError())); return false; } @@ -175,7 +177,7 @@ static bool setup_device(void) { reader_pid = fork(); if(reader_pid == -1) { - logger(DEBUG_ALWAYS, LOG_DEBUG, "System call `%s' failed: %s", "fork", strerror(errno)); + logger(LOG_DEBUG, "System call `%s' failed: %s", "fork", strerror(errno)); return false; } @@ -184,20 +186,20 @@ static bool setup_device(void) { It passes everything it reads to the socket. */ char buf[MTU]; - long inlen; + long lenin; CloseHandle(device_handle); device_handle = CreateFile(tapname, GENERIC_READ, FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM, 0); if(device_handle == INVALID_HANDLE_VALUE) { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not open Windows tap device %s (%s) for reading: %s", device, iface, winerror(GetLastError())); + logger(LOG_ERR, "Could not open Windows tap device %s (%s) for reading: %s", device, iface, winerror(GetLastError())); buf[0] = 0; write(sp[1], buf, 1); exit(1); } - logger(DEBUG_ALWAYS, LOG_DEBUG, "Tap reader forked and running."); + logger(LOG_DEBUG, "Tap reader forked and running."); /* Notify success */ @@ -207,19 +209,19 @@ static bool setup_device(void) { /* Pass packets */ for(;;) { - ReadFile(device_handle, buf, MTU, &inlen, NULL); - write(sp[1], buf, inlen); + ReadFile(device_handle, buf, MTU, &lenin, NULL); + write(sp[1], buf, lenin); } } read(device_fd, &gelukt, 1); if(gelukt != 1) { - logger(DEBUG_ALWAYS, LOG_DEBUG, "Tap reader failed!"); + logger(LOG_DEBUG, "Tap reader failed!"); return false; } - logger(DEBUG_ALWAYS, LOG_INFO, "%s (%s) is a %s", device, iface, device_info); + logger(LOG_INFO, "%s (%s) is a %s", device, iface, device_info); return true; } @@ -228,51 +230,58 @@ static void close_device(void) { close(sp[0]); close(sp[1]); CloseHandle(device_handle); - device_handle = INVALID_HANDLE_VALUE; kill(reader_pid, SIGKILL); free(device); - device = NULL; free(iface); - iface = NULL; - device_info = NULL; } static bool read_packet(vpn_packet_t *packet) { - int inlen; + int lenin; - if((inlen = read(sp[0], DATA(packet), MTU)) <= 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info, + if((lenin = read(sp[0], packet->data, MTU)) <= 0) { + logger(LOG_ERR, "Error while reading from %s %s: %s", device_info, device, strerror(errno)); return false; } - packet->len = inlen; + packet->len = lenin; - logger(DEBUG_TRAFFIC, LOG_DEBUG, "Read packet of %d bytes from %s", packet->len, - device_info); + device_total_in += packet->len; + + ifdebug(TRAFFIC) logger(LOG_DEBUG, "Read packet of %d bytes from %s", packet->len, + device_info); return true; } static bool write_packet(vpn_packet_t *packet) { - long outlen; + long lenout; - logger(DEBUG_TRAFFIC, LOG_DEBUG, "Writing packet of %d bytes to %s", - packet->len, device_info); + ifdebug(TRAFFIC) logger(LOG_DEBUG, "Writing packet of %d bytes to %s", + packet->len, device_info); - if(!WriteFile(device_handle, DATA(packet), packet->len, &outlen, NULL)) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error while writing to %s %s: %s", device_info, device, winerror(GetLastError())); + if(!WriteFile(device_handle, packet->data, packet->len, &lenout, NULL)) { + logger(LOG_ERR, "Error while writing to %s %s: %s", device_info, device, winerror(GetLastError())); return false; } + device_total_out += packet->len; + return true; } +static void dump_device_stats(void) { + logger(LOG_DEBUG, "Statistics for %s %s:", device_info, device); + logger(LOG_DEBUG, " total bytes in: %10"PRIu64, device_total_in); + logger(LOG_DEBUG, " total bytes out: %10"PRIu64, device_total_out); +} + const devops_t os_devops = { .setup = setup_device, .close = close_device, .read = read_packet, .write = write_packet, + .dump_stats = dump_device_stats, }; diff --git a/src/device.h b/src/device.h index c85671b..6bfc44d 100644 --- a/src/device.h +++ b/src/device.h @@ -25,22 +25,21 @@ extern int device_fd; extern char *device; + extern char *iface; typedef struct devops_t { bool (*setup)(void); void (*close)(void); - bool (*read)(struct vpn_packet_t *); - bool (*write)(struct vpn_packet_t *); - void (*enable)(void); /* optional */ - void (*disable)(void); /* optional */ + bool (*read)(struct vpn_packet_t *packet); + bool (*write)(struct vpn_packet_t *packet); + void (*dump_stats)(void); } devops_t; extern const devops_t os_devops; extern const devops_t dummy_devops; extern const devops_t raw_socket_devops; extern const devops_t multicast_devops; -extern const devops_t fd_devops; extern const devops_t uml_devops; extern const devops_t vde_devops; extern devops_t devops; diff --git a/src/digest.h b/src/digest.h deleted file mode 100644 index 6d7cb41..0000000 --- a/src/digest.h +++ /dev/null @@ -1,42 +0,0 @@ -#ifndef TINC_DIGEST_H -#define TINC_DIGEST_H - -/* - digest.h -- header file digest.c - Copyright (C) 2007-2016 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 - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#define DIGEST_MAX_SIZE 64 - -#ifndef DISABLE_LEGACY - -typedef struct digest digest_t; - -extern digest_t *digest_open_by_name(const char *name, int maclength) __attribute__((__malloc__)); -extern digest_t *digest_open_by_nid(int nid, int maclength) __attribute__((__malloc__)); -extern void digest_close(digest_t *digest); -extern bool digest_create(digest_t *digest, const void *indata, size_t inlen, void *outdata) __attribute__((__warn_unused_result__)); -extern bool digest_verify(digest_t *digest, const void *indata, size_t inlen, const void *digestdata) __attribute__((__warn_unused_result__)); -extern bool digest_set_key(digest_t *digest, const void *key, size_t len) __attribute__((__warn_unused_result__)); -extern int digest_get_nid(const digest_t *digest); -extern size_t digest_keylength(const digest_t *digest); -extern size_t digest_length(const digest_t *digest); -extern bool digest_active(const digest_t *digest); - -#endif - -#endif diff --git a/src/dropin.c b/src/dropin.c index 74e5676..93511f1 100644 --- a/src/dropin.c +++ b/src/dropin.c @@ -107,6 +107,7 @@ int vasprintf(char **buf, const char *fmt, va_list ap) { va_copy(aq, ap); status = vsnprintf(*buf, len, fmt, aq); + buf[len - 1] = 0; va_end(aq); if(status >= 0) { @@ -114,7 +115,7 @@ int vasprintf(char **buf, const char *fmt, va_list ap) { } if(status > len - 1) { - len = status + 1; + len = status; va_copy(aq, ap); status = vsnprintf(*buf, len, fmt, aq); va_end(aq); @@ -126,25 +127,16 @@ int vasprintf(char **buf, const char *fmt, va_list ap) { #ifndef HAVE_GETTIMEOFDAY int gettimeofday(struct timeval *tv, void *tz) { -#ifdef HAVE_MINGW - FILETIME ft; - GetSystemTimeAsFileTime(&ft); - uint64_t lt = (uint64_t)ft.dwLowDateTime | ((uint64_t)ft.dwHighDateTime << 32); - lt -= 116444736000000000ULL; - tv->tv_sec = lt / 10000000; - tv->tv_usec = (lt / 10) % 1000000; -#else -#warning No high resolution time source! tv->tv_sec = time(NULL); tv->tv_usec = 0; -#endif return 0; } #endif -#ifndef HAVE_NANOSLEEP -int nanosleep(const struct timespec *req, struct timespec *rem) { - struct timeval tv = {req->tv_sec, req->tv_nsec / 1000}; - return select(0, NULL, NULL, NULL, &tv); +#ifndef HAVE_USLEEP +int usleep(long long usec) { + struct timeval tv = {usec / 1000000, (usec / 1000) % 1000}; + select(0, NULL, NULL, NULL, &tv); + return 0; } #endif diff --git a/src/dropin.h b/src/dropin.h index 5033f90..012099b 100644 --- a/src/dropin.h +++ b/src/dropin.h @@ -4,7 +4,7 @@ /* dropin.h -- header file for dropin.c Copyright (C) 2000-2005 Ivo Timmermans, - 2000-2016 Guus Sliepen + 2000-2011 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 @@ -21,50 +21,28 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +#include "fake-getaddrinfo.h" +#include "fake-getnameinfo.h" + #ifndef HAVE_DAEMON -extern int daemon(int, int); +extern int daemon(int nochdir, int noclose); +#endif + +#ifndef HAVE_GET_CURRENT_DIR_NAME +extern char *get_current_dir_name(void); #endif #ifndef HAVE_ASPRINTF -extern int asprintf(char **, const char *, ...); -extern int vasprintf(char **, const char *, va_list ap); +extern int asprintf(char **buf, const char *fmt, ...); +extern int vasprintf(char **buf, const char *fmt, va_list ap); #endif #ifndef HAVE_GETTIMEOFDAY -extern int gettimeofday(struct timeval *, void *); +extern int gettimeofday(struct timeval *tv, void *tz); #endif -#ifndef HAVE_NANOSLEEP -extern int nanosleep(const struct timespec *req, struct timespec *rem); -#endif - -#ifndef timeradd -#define timeradd(a, b, r) do {\ - (r)->tv_sec = (a)->tv_sec + (b)->tv_sec;\ - (r)->tv_usec = (a)->tv_usec + (b)->tv_usec;\ - if((r)->tv_usec >= 1000000)\ - (r)->tv_sec++, (r)->tv_usec -= 1000000;\ - } while (0) -#endif - -#ifndef timersub -#define timersub(a, b, r) do {\ - (r)->tv_sec = (a)->tv_sec - (b)->tv_sec;\ - (r)->tv_usec = (a)->tv_usec - (b)->tv_usec;\ - if((r)->tv_usec < 0)\ - (r)->tv_sec--, (r)->tv_usec += 1000000;\ - } while (0) -#endif - -#ifdef HAVE_MINGW -#define mkdir(a, b) mkdir(a) -#ifndef SHUT_RDWR -#define SHUT_RDWR SD_BOTH -#endif -#endif - -#ifndef EAI_SYSTEM -#define EAI_SYSTEM 0 +#ifndef HAVE_USLEEP +extern int usleep(long long usec); #endif #endif diff --git a/src/dummy_device.c b/src/dummy_device.c index 15f0654..d1d751b 100644 --- a/src/dummy_device.c +++ b/src/dummy_device.c @@ -1,6 +1,6 @@ /* device.c -- Dummy device - Copyright (C) 2011-2012 Guus Sliepen + Copyright (C) 2011 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 @@ -26,14 +26,19 @@ static const char *device_info = "dummy device"; +static uint64_t device_total_in = 0; +static uint64_t device_total_out = 0; + static bool setup_device(void) { device = xstrdup("dummy"); iface = xstrdup("dummy"); - logger(DEBUG_ALWAYS, LOG_INFO, "%s (%s) is a %s", device, iface, device_info); + logger(LOG_INFO, "%s (%s) is a %s", device, iface, device_info); return true; } static void close_device(void) { + free(device); + free(iface); } static bool read_packet(vpn_packet_t *packet) { @@ -42,13 +47,20 @@ static bool read_packet(vpn_packet_t *packet) { } static bool write_packet(vpn_packet_t *packet) { - (void)packet; + device_total_out += packet->len; return true; } +static void dump_device_stats(void) { + logger(LOG_DEBUG, "Statistics for %s %s:", device_info, device); + logger(LOG_DEBUG, " total bytes in: %10"PRIu64, device_total_in); + logger(LOG_DEBUG, " total bytes out: %10"PRIu64, device_total_out); +} + const devops_t dummy_devops = { .setup = setup_device, .close = close_device, .read = read_packet, .write = write_packet, + .dump_stats = dump_device_stats, }; diff --git a/src/ecdh.h b/src/ecdh.h deleted file mode 100644 index 0bfc271..0000000 --- a/src/ecdh.h +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef TINC_ECDH_H -#define TINC_ECDH_H - -/* - ecdh.h -- header file for ecdh.c - Copyright (C) 2011-2013 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 - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#define ECDH_SIZE 32 -#define ECDH_SHARED_SIZE 32 - -#ifndef TINC_ECDH_INTERNAL -typedef struct ecdh ecdh_t; -#endif - -extern ecdh_t *ecdh_generate_public(void *pubkey) __attribute__((__malloc__)); -extern bool ecdh_compute_shared(ecdh_t *ecdh, const void *pubkey, void *shared) __attribute__((__warn_unused_result__)); -extern void ecdh_free(ecdh_t *ecdh); - -#endif diff --git a/src/ecdsa.h b/src/ecdsa.h deleted file mode 100644 index 6cb5434..0000000 --- a/src/ecdsa.h +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef TINC_ECDSA_H -#define TINC_ECDSA_H - -/* - ecdsa.h -- ECDSA key handling - Copyright (C) 2011-2013 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 - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#ifndef TINC_ECDSA_INTERNAL -typedef struct ecdsa ecdsa_t; -#endif - -extern ecdsa_t *ecdsa_set_base64_public_key(const char *p) __attribute__((__malloc__)); -extern char *ecdsa_get_base64_public_key(ecdsa_t *ecdsa); -extern ecdsa_t *ecdsa_read_pem_public_key(FILE *fp) __attribute__((__malloc__)); -extern ecdsa_t *ecdsa_read_pem_private_key(FILE *fp) __attribute__((__malloc__)); -extern size_t ecdsa_size(ecdsa_t *ecdsa); -extern bool ecdsa_sign(ecdsa_t *ecdsa, const void *in, size_t inlen, void *out) __attribute__((__warn_unused_result__)); -extern bool ecdsa_verify(ecdsa_t *ecdsa, const void *in, size_t inlen, const void *out) __attribute__((__warn_unused_result__)); -extern bool ecdsa_active(ecdsa_t *ecdsa); -extern void ecdsa_free(ecdsa_t *ecdsa); - -#endif diff --git a/src/ecdsagen.h b/src/ecdsagen.h deleted file mode 100644 index 48cd25b..0000000 --- a/src/ecdsagen.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef TINC_ECDSAGEN_H -#define TINC_ECDSAGEN_H - -/* - ecdsagen.h -- ECDSA key generation and export - Copyright (C) 2011-2013 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 - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include "ecdsa.h" - -extern ecdsa_t *ecdsa_generate(void) __attribute__((__malloc__)); -extern bool ecdsa_write_pem_public_key(ecdsa_t *ecdsa, FILE *fp) __attribute__((__warn_unused_result__)); -extern bool ecdsa_write_pem_private_key(ecdsa_t *ecdsa, FILE *fp) __attribute__((__warn_unused_result__)); - -#endif diff --git a/src/ed25519/ecdh.c b/src/ed25519/ecdh.c deleted file mode 100644 index 302fafd..0000000 --- a/src/ed25519/ecdh.c +++ /dev/null @@ -1,51 +0,0 @@ -/* - ecdh.c -- Diffie-Hellman key exchange handling - Copyright (C) 2011-2013 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 - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include "../system.h" - -#include "ed25519.h" - -#define TINC_ECDH_INTERNAL -typedef struct ecdh_t { - uint8_t private[64]; -} ecdh_t; - -#include "../crypto.h" -#include "../ecdh.h" -#include "../xalloc.h" - -ecdh_t *ecdh_generate_public(void *pubkey) { - ecdh_t *ecdh = xzalloc(sizeof(*ecdh)); - - uint8_t seed[32]; - randomize(seed, sizeof(seed)); - ed25519_create_keypair(pubkey, ecdh->private, seed); - - return ecdh; -} - -bool ecdh_compute_shared(ecdh_t *ecdh, const void *pubkey, void *shared) { - ed25519_key_exchange(shared, pubkey, ecdh->private); - free(ecdh); - return true; -} - -void ecdh_free(ecdh_t *ecdh) { - free(ecdh); -} diff --git a/src/ed25519/ecdsa.c b/src/ed25519/ecdsa.c deleted file mode 100644 index 4bd7155..0000000 --- a/src/ed25519/ecdsa.c +++ /dev/null @@ -1,168 +0,0 @@ -/* - ecdsa.c -- ECDSA key handling - Copyright (C) 2011-2013 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 - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include "../system.h" - -#include "ed25519.h" - -#define TINC_ECDSA_INTERNAL -typedef struct { - uint8_t private[64]; - uint8_t public[32]; -} ecdsa_t; - -#include "../logger.h" -#include "../ecdsa.h" -#include "../utils.h" -#include "../xalloc.h" - -// Get and set ECDSA keys -// -ecdsa_t *ecdsa_set_base64_public_key(const char *p) { - int len = strlen(p); - - if(len != 43) { - logger(DEBUG_ALWAYS, LOG_ERR, "Invalid size %d for public key!", len); - return 0; - } - - ecdsa_t *ecdsa = xzalloc(sizeof(*ecdsa)); - len = b64decode(p, ecdsa->public, len); - - if(len != 32) { - logger(DEBUG_ALWAYS, LOG_ERR, "Invalid format of public key! len = %d", len); - free(ecdsa); - return 0; - } - - return ecdsa; -} - -char *ecdsa_get_base64_public_key(ecdsa_t *ecdsa) { - char *base64 = xmalloc(44); - b64encode(ecdsa->public, base64, sizeof(ecdsa->public)); - - return base64; -} - -// Read PEM ECDSA keys - -static bool read_pem(FILE *fp, const char *type, void *vbuf, size_t size) { - char line[1024]; - bool data = false; - size_t typelen = strlen(type); - char *buf = vbuf; - - while(fgets(line, sizeof(line), fp)) { - if(!data) { - if(strncmp(line, "-----BEGIN ", 11)) { - continue; - } - - if(strncmp(line + 11, type, typelen)) { - continue; - } - - data = true; - continue; - } - - if(!strncmp(line, "-----END ", 9)) { - break; - } - - size_t linelen = strcspn(line, "\r\n"); - size_t len = b64decode(line, line, linelen); - - if(!len) { - logger(DEBUG_ALWAYS, LOG_ERR, "Invalid base64 data in PEM file\n"); - errno = EINVAL; - return false; - } - - if(len > size) { - logger(DEBUG_ALWAYS, LOG_ERR, "Too much base64 data in PEM file\n"); - errno = EINVAL; - return false; - } - - memcpy(buf, line, len); - buf += len; - size -= len; - } - - if(size) { - if(data) { - errno = EINVAL; - logger(DEBUG_ALWAYS, LOG_ERR, "Too little base64 data in PEM file\n"); - } else { - errno = ENOENT; - } - - return false; - } - - return true; -} - -ecdsa_t *ecdsa_read_pem_public_key(FILE *fp) { - ecdsa_t *ecdsa = xzalloc(sizeof(*ecdsa)); - - if(read_pem(fp, "ED25519 PUBLIC KEY", ecdsa->public, sizeof(ecdsa->public))) { - return ecdsa; - } - - free(ecdsa); - return 0; -} - -ecdsa_t *ecdsa_read_pem_private_key(FILE *fp) { - ecdsa_t *ecdsa = xmalloc(sizeof(*ecdsa)); - - if(read_pem(fp, "ED25519 PRIVATE KEY", ecdsa->private, sizeof(*ecdsa))) { - return ecdsa; - } - - free(ecdsa); - return 0; -} - -size_t ecdsa_size(ecdsa_t *ecdsa) { - (void)ecdsa; - return 64; -} - -// TODO: standardise output format? - -bool ecdsa_sign(ecdsa_t *ecdsa, const void *in, size_t len, void *sig) { - ed25519_sign(sig, in, len, ecdsa->public, ecdsa->private); - return true; -} - -bool ecdsa_verify(ecdsa_t *ecdsa, const void *in, size_t len, const void *sig) { - return ed25519_verify(sig, in, len, ecdsa->public); -} - -bool ecdsa_active(ecdsa_t *ecdsa) { - return ecdsa; -} - -void ecdsa_free(ecdsa_t *ecdsa) { - free(ecdsa); -} diff --git a/src/ed25519/ecdsagen.c b/src/ed25519/ecdsagen.c deleted file mode 100644 index ede5136..0000000 --- a/src/ed25519/ecdsagen.c +++ /dev/null @@ -1,73 +0,0 @@ -/* - ecdsagen.c -- ECDSA key generation and export - Copyright (C) 2011-2013 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 - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include "../system.h" - -#include "ed25519.h" - -#define TINC_ECDSA_INTERNAL -typedef struct { - uint8_t private[64]; - uint8_t public[32]; -} ecdsa_t; - -#include "../crypto.h" -#include "../ecdsagen.h" -#include "../utils.h" -#include "../xalloc.h" - -// Generate ECDSA key - -ecdsa_t *ecdsa_generate(void) { - ecdsa_t *ecdsa = xzalloc(sizeof(*ecdsa)); - - uint8_t seed[32]; - randomize(seed, sizeof(seed)); - ed25519_create_keypair(ecdsa->public, ecdsa->private, seed); - - return ecdsa; -} - -// Write PEM ECDSA keys - -static bool write_pem(FILE *fp, const char *type, void *vbuf, size_t size) { - fprintf(fp, "-----BEGIN %s-----\n", type); - - char *buf = vbuf; - char base64[65]; - - while(size) { - size_t todo = size > 48 ? 48 : size; - b64encode(buf, base64, todo); - fprintf(fp, "%s\n", base64); - buf += todo; - size -= todo; - } - - fprintf(fp, "-----END %s-----\n", type); - return !ferror(fp); -} - -bool ecdsa_write_pem_public_key(ecdsa_t *ecdsa, FILE *fp) { - return write_pem(fp, "ED25519 PUBLIC KEY", ecdsa->public, sizeof(ecdsa->public)); -} - -bool ecdsa_write_pem_private_key(ecdsa_t *ecdsa, FILE *fp) { - return write_pem(fp, "ED25519 PRIVATE KEY", ecdsa->private, sizeof(*ecdsa)); -} diff --git a/src/ed25519/ed25519.h b/src/ed25519/ed25519.h deleted file mode 100644 index 65b191e..0000000 --- a/src/ed25519/ed25519.h +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef ED25519_H -#define ED25519_H - -#include - -#if defined(_WIN32) -#if defined(ED25519_BUILD_DLL) -#define ED25519_DECLSPEC __declspec(dllexport) -#elif defined(ED25519_DLL) -#define ED25519_DECLSPEC __declspec(dllimport) -#else -#define ED25519_DECLSPEC -#endif -#else -#define ED25519_DECLSPEC -#endif - - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef ED25519_NO_SEED -int ED25519_DECLSPEC ed25519_create_seed(unsigned char *seed); -#endif - -void ED25519_DECLSPEC ed25519_create_keypair(unsigned char *public_key, unsigned char *private_key, const unsigned char *seed); -void ED25519_DECLSPEC ed25519_sign(unsigned char *signature, const unsigned char *message, size_t message_len, const unsigned char *public_key, const unsigned char *private_key); -int ED25519_DECLSPEC ed25519_verify(const unsigned char *signature, const unsigned char *message, size_t message_len, const unsigned char *private_key); -void ED25519_DECLSPEC ed25519_key_exchange(unsigned char *shared_secret, const unsigned char *public_key, const unsigned char *private_key); - - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/ed25519/fe.c b/src/ed25519/fe.c deleted file mode 100644 index df907a7..0000000 --- a/src/ed25519/fe.c +++ /dev/null @@ -1,1511 +0,0 @@ -#include "fixedint.h" -#include "fe.h" - - -/* - helper functions -*/ -static uint64_t load_3(const unsigned char *in) { - uint64_t result; - - result = in[0]; - result |= shlu64(in[1], 8); - result |= shlu64(in[2], 16); - - return result; -} - -static uint64_t load_4(const unsigned char *in) { - uint64_t result; - - result = in[0]; - result |= shlu64(in[1], 8); - result |= shlu64(in[2], 16); - result |= shlu64(in[3], 24); - - return result; -} - - - -/* - h = 0 -*/ - -void fe_0(fe h) { - h[0] = 0; - h[1] = 0; - h[2] = 0; - h[3] = 0; - h[4] = 0; - h[5] = 0; - h[6] = 0; - h[7] = 0; - h[8] = 0; - h[9] = 0; -} - - - -/* - h = 1 -*/ - -void fe_1(fe h) { - h[0] = 1; - h[1] = 0; - h[2] = 0; - h[3] = 0; - h[4] = 0; - h[5] = 0; - h[6] = 0; - h[7] = 0; - h[8] = 0; - h[9] = 0; -} - - - -/* - h = f + g - Can overlap h with f or g. - - Preconditions: - |f| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. - |g| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. - - Postconditions: - |h| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. -*/ - -void fe_add(fe h, const fe f, const fe g) { - int32_t f0 = f[0]; - int32_t f1 = f[1]; - int32_t f2 = f[2]; - int32_t f3 = f[3]; - int32_t f4 = f[4]; - int32_t f5 = f[5]; - int32_t f6 = f[6]; - int32_t f7 = f[7]; - int32_t f8 = f[8]; - int32_t f9 = f[9]; - int32_t g0 = g[0]; - int32_t g1 = g[1]; - int32_t g2 = g[2]; - int32_t g3 = g[3]; - int32_t g4 = g[4]; - int32_t g5 = g[5]; - int32_t g6 = g[6]; - int32_t g7 = g[7]; - int32_t g8 = g[8]; - int32_t g9 = g[9]; - int32_t h0 = f0 + g0; - int32_t h1 = f1 + g1; - int32_t h2 = f2 + g2; - int32_t h3 = f3 + g3; - int32_t h4 = f4 + g4; - int32_t h5 = f5 + g5; - int32_t h6 = f6 + g6; - int32_t h7 = f7 + g7; - int32_t h8 = f8 + g8; - int32_t h9 = f9 + g9; - - h[0] = h0; - h[1] = h1; - h[2] = h2; - h[3] = h3; - h[4] = h4; - h[5] = h5; - h[6] = h6; - h[7] = h7; - h[8] = h8; - h[9] = h9; -} - - - -/* - Replace (f,g) with (g,g) if b == 1; - replace (f,g) with (f,g) if b == 0. - - Preconditions: b in {0,1}. -*/ - -void fe_cmov(fe f, const fe g, unsigned int b) { - int32_t f0 = f[0]; - int32_t f1 = f[1]; - int32_t f2 = f[2]; - int32_t f3 = f[3]; - int32_t f4 = f[4]; - int32_t f5 = f[5]; - int32_t f6 = f[6]; - int32_t f7 = f[7]; - int32_t f8 = f[8]; - int32_t f9 = f[9]; - int32_t g0 = g[0]; - int32_t g1 = g[1]; - int32_t g2 = g[2]; - int32_t g3 = g[3]; - int32_t g4 = g[4]; - int32_t g5 = g[5]; - int32_t g6 = g[6]; - int32_t g7 = g[7]; - int32_t g8 = g[8]; - int32_t g9 = g[9]; - int32_t x0 = f0 ^ g0; - int32_t x1 = f1 ^ g1; - int32_t x2 = f2 ^ g2; - int32_t x3 = f3 ^ g3; - int32_t x4 = f4 ^ g4; - int32_t x5 = f5 ^ g5; - int32_t x6 = f6 ^ g6; - int32_t x7 = f7 ^ g7; - int32_t x8 = f8 ^ g8; - int32_t x9 = f9 ^ g9; - - b = (unsigned int)(- (int) b); /* silence warning */ - x0 &= b; - x1 &= b; - x2 &= b; - x3 &= b; - x4 &= b; - x5 &= b; - x6 &= b; - x7 &= b; - x8 &= b; - x9 &= b; - - f[0] = f0 ^ x0; - f[1] = f1 ^ x1; - f[2] = f2 ^ x2; - f[3] = f3 ^ x3; - f[4] = f4 ^ x4; - f[5] = f5 ^ x5; - f[6] = f6 ^ x6; - f[7] = f7 ^ x7; - f[8] = f8 ^ x8; - f[9] = f9 ^ x9; -} - -/* - Replace (f,g) with (g,f) if b == 1; - replace (f,g) with (f,g) if b == 0. - - Preconditions: b in {0,1}. -*/ - -void fe_cswap(fe f, fe g, unsigned int b) { - int32_t f0 = f[0]; - int32_t f1 = f[1]; - int32_t f2 = f[2]; - int32_t f3 = f[3]; - int32_t f4 = f[4]; - int32_t f5 = f[5]; - int32_t f6 = f[6]; - int32_t f7 = f[7]; - int32_t f8 = f[8]; - int32_t f9 = f[9]; - int32_t g0 = g[0]; - int32_t g1 = g[1]; - int32_t g2 = g[2]; - int32_t g3 = g[3]; - int32_t g4 = g[4]; - int32_t g5 = g[5]; - int32_t g6 = g[6]; - int32_t g7 = g[7]; - int32_t g8 = g[8]; - int32_t g9 = g[9]; - int32_t x0 = f0 ^ g0; - int32_t x1 = f1 ^ g1; - int32_t x2 = f2 ^ g2; - int32_t x3 = f3 ^ g3; - int32_t x4 = f4 ^ g4; - int32_t x5 = f5 ^ g5; - int32_t x6 = f6 ^ g6; - int32_t x7 = f7 ^ g7; - int32_t x8 = f8 ^ g8; - int32_t x9 = f9 ^ g9; - b = -b; - x0 &= b; - x1 &= b; - x2 &= b; - x3 &= b; - x4 &= b; - x5 &= b; - x6 &= b; - x7 &= b; - x8 &= b; - x9 &= b; - f[0] = f0 ^ x0; - f[1] = f1 ^ x1; - f[2] = f2 ^ x2; - f[3] = f3 ^ x3; - f[4] = f4 ^ x4; - f[5] = f5 ^ x5; - f[6] = f6 ^ x6; - f[7] = f7 ^ x7; - f[8] = f8 ^ x8; - f[9] = f9 ^ x9; - g[0] = g0 ^ x0; - g[1] = g1 ^ x1; - g[2] = g2 ^ x2; - g[3] = g3 ^ x3; - g[4] = g4 ^ x4; - g[5] = g5 ^ x5; - g[6] = g6 ^ x6; - g[7] = g7 ^ x7; - g[8] = g8 ^ x8; - g[9] = g9 ^ x9; -} - - - -/* - h = f -*/ - -void fe_copy(fe h, const fe f) { - int32_t f0 = f[0]; - int32_t f1 = f[1]; - int32_t f2 = f[2]; - int32_t f3 = f[3]; - int32_t f4 = f[4]; - int32_t f5 = f[5]; - int32_t f6 = f[6]; - int32_t f7 = f[7]; - int32_t f8 = f[8]; - int32_t f9 = f[9]; - - h[0] = f0; - h[1] = f1; - h[2] = f2; - h[3] = f3; - h[4] = f4; - h[5] = f5; - h[6] = f6; - h[7] = f7; - h[8] = f8; - h[9] = f9; -} - - - -/* - Ignores top bit of h. -*/ - -void fe_frombytes(fe h, const unsigned char *s) { - int64_t h0 = load_4(s); - int64_t h1 = load_3(s + 4) << 6; - int64_t h2 = load_3(s + 7) << 5; - int64_t h3 = load_3(s + 10) << 3; - int64_t h4 = load_3(s + 13) << 2; - int64_t h5 = load_4(s + 16); - int64_t h6 = load_3(s + 20) << 7; - int64_t h7 = load_3(s + 23) << 5; - int64_t h8 = load_3(s + 26) << 4; - int64_t h9 = (load_3(s + 29) & 8388607) << 2; - int64_t carry0; - int64_t carry1; - int64_t carry2; - int64_t carry3; - int64_t carry4; - int64_t carry5; - int64_t carry6; - int64_t carry7; - int64_t carry8; - int64_t carry9; - - carry9 = (h9 + (1L << 24)) >> 25; - h0 += carry9 * 19; - h9 -= shl64(carry9, 25); - carry1 = (h1 + (1L << 24)) >> 25; - h2 += carry1; - h1 -= shl64(carry1, 25); - carry3 = (h3 + (1L << 24)) >> 25; - h4 += carry3; - h3 -= shl64(carry3, 25); - carry5 = (h5 + (1L << 24)) >> 25; - h6 += carry5; - h5 -= shl64(carry5, 25); - carry7 = (h7 + (1L << 24)) >> 25; - h8 += carry7; - h7 -= shl64(carry7, 25); - carry0 = (h0 + (1L << 25)) >> 26; - h1 += carry0; - h0 -= shl64(carry0, 26); - carry2 = (h2 + (1L << 25)) >> 26; - h3 += carry2; - h2 -= shl64(carry2, 26); - carry4 = (h4 + (1L << 25)) >> 26; - h5 += carry4; - h4 -= shl64(carry4, 26); - carry6 = (h6 + (1L << 25)) >> 26; - h7 += carry6; - h6 -= shl64(carry6, 26); - carry8 = (h8 + (1L << 25)) >> 26; - h9 += carry8; - h8 -= shl64(carry8, 26); - - h[0] = h0; - h[1] = h1; - h[2] = h2; - h[3] = h3; - h[4] = h4; - h[5] = h5; - h[6] = h6; - h[7] = h7; - h[8] = h8; - h[9] = h9; -} - - - -void fe_invert(fe out, const fe z) { - fe t0; - fe t1; - fe t2; - fe t3; - int i; - - fe_sq(t0, z); - - for(i = 1; i < 1; ++i) { - fe_sq(t0, t0); - } - - fe_sq(t1, t0); - - for(i = 1; i < 2; ++i) { - fe_sq(t1, t1); - } - - fe_mul(t1, z, t1); - fe_mul(t0, t0, t1); - fe_sq(t2, t0); - - for(i = 1; i < 1; ++i) { - fe_sq(t2, t2); - } - - fe_mul(t1, t1, t2); - fe_sq(t2, t1); - - for(i = 1; i < 5; ++i) { - fe_sq(t2, t2); - } - - fe_mul(t1, t2, t1); - fe_sq(t2, t1); - - for(i = 1; i < 10; ++i) { - fe_sq(t2, t2); - } - - fe_mul(t2, t2, t1); - fe_sq(t3, t2); - - for(i = 1; i < 20; ++i) { - fe_sq(t3, t3); - } - - fe_mul(t2, t3, t2); - fe_sq(t2, t2); - - for(i = 1; i < 10; ++i) { - fe_sq(t2, t2); - } - - fe_mul(t1, t2, t1); - fe_sq(t2, t1); - - for(i = 1; i < 50; ++i) { - fe_sq(t2, t2); - } - - fe_mul(t2, t2, t1); - fe_sq(t3, t2); - - for(i = 1; i < 100; ++i) { - fe_sq(t3, t3); - } - - fe_mul(t2, t3, t2); - fe_sq(t2, t2); - - for(i = 1; i < 50; ++i) { - fe_sq(t2, t2); - } - - fe_mul(t1, t2, t1); - fe_sq(t1, t1); - - for(i = 1; i < 5; ++i) { - fe_sq(t1, t1); - } - - fe_mul(out, t1, t0); -} - - - -/* - return 1 if f is in {1,3,5,...,q-2} - return 0 if f is in {0,2,4,...,q-1} - - Preconditions: - |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. -*/ - -int fe_isnegative(const fe f) { - unsigned char s[32]; - - fe_tobytes(s, f); - - return s[0] & 1; -} - - - -/* - return 1 if f == 0 - return 0 if f != 0 - - Preconditions: - |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. -*/ - -int fe_isnonzero(const fe f) { - unsigned char s[32]; - unsigned char r; - - fe_tobytes(s, f); - - r = s[0]; -#define F(i) r |= s[i] - F(1); - F(2); - F(3); - F(4); - F(5); - F(6); - F(7); - F(8); - F(9); - F(10); - F(11); - F(12); - F(13); - F(14); - F(15); - F(16); - F(17); - F(18); - F(19); - F(20); - F(21); - F(22); - F(23); - F(24); - F(25); - F(26); - F(27); - F(28); - F(29); - F(30); - F(31); -#undef F - - return r != 0; -} - - - -/* - h = f * g - Can overlap h with f or g. - - Preconditions: - |f| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc. - |g| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc. - - Postconditions: - |h| bounded by 1.01*2^25,1.01*2^24,1.01*2^25,1.01*2^24,etc. - */ - -/* -Notes on implementation strategy: - -Using schoolbook multiplication. -Karatsuba would save a little in some cost models. - -Most multiplications by 2 and 19 are 32-bit precomputations; -cheaper than 64-bit postcomputations. - -There is one remaining multiplication by 19 in the carry chain; -one *19 precomputation can be merged into this, -but the resulting data flow is considerably less clean. - -There are 12 carries below. -10 of them are 2-way parallelizable and vectorizable. -Can get away with 11 carries, but then data flow is much deeper. - -With tighter constraints on inputs can squeeze carries into int32. -*/ - -void fe_mul(fe h, const fe f, const fe g) { - int32_t f0 = f[0]; - int32_t f1 = f[1]; - int32_t f2 = f[2]; - int32_t f3 = f[3]; - int32_t f4 = f[4]; - int32_t f5 = f[5]; - int32_t f6 = f[6]; - int32_t f7 = f[7]; - int32_t f8 = f[8]; - int32_t f9 = f[9]; - int32_t g0 = g[0]; - int32_t g1 = g[1]; - int32_t g2 = g[2]; - int32_t g3 = g[3]; - int32_t g4 = g[4]; - int32_t g5 = g[5]; - int32_t g6 = g[6]; - int32_t g7 = g[7]; - int32_t g8 = g[8]; - int32_t g9 = g[9]; - int32_t g1_19 = 19 * g1; /* 1.959375*2^29 */ - int32_t g2_19 = 19 * g2; /* 1.959375*2^30; still ok */ - int32_t g3_19 = 19 * g3; - int32_t g4_19 = 19 * g4; - int32_t g5_19 = 19 * g5; - int32_t g6_19 = 19 * g6; - int32_t g7_19 = 19 * g7; - int32_t g8_19 = 19 * g8; - int32_t g9_19 = 19 * g9; - int32_t f1_2 = 2 * f1; - int32_t f3_2 = 2 * f3; - int32_t f5_2 = 2 * f5; - int32_t f7_2 = 2 * f7; - int32_t f9_2 = 2 * f9; - int64_t f0g0 = f0 * (int64_t) g0; - int64_t f0g1 = f0 * (int64_t) g1; - int64_t f0g2 = f0 * (int64_t) g2; - int64_t f0g3 = f0 * (int64_t) g3; - int64_t f0g4 = f0 * (int64_t) g4; - int64_t f0g5 = f0 * (int64_t) g5; - int64_t f0g6 = f0 * (int64_t) g6; - int64_t f0g7 = f0 * (int64_t) g7; - int64_t f0g8 = f0 * (int64_t) g8; - int64_t f0g9 = f0 * (int64_t) g9; - int64_t f1g0 = f1 * (int64_t) g0; - int64_t f1g1_2 = f1_2 * (int64_t) g1; - int64_t f1g2 = f1 * (int64_t) g2; - int64_t f1g3_2 = f1_2 * (int64_t) g3; - int64_t f1g4 = f1 * (int64_t) g4; - int64_t f1g5_2 = f1_2 * (int64_t) g5; - int64_t f1g6 = f1 * (int64_t) g6; - int64_t f1g7_2 = f1_2 * (int64_t) g7; - int64_t f1g8 = f1 * (int64_t) g8; - int64_t f1g9_38 = f1_2 * (int64_t) g9_19; - int64_t f2g0 = f2 * (int64_t) g0; - int64_t f2g1 = f2 * (int64_t) g1; - int64_t f2g2 = f2 * (int64_t) g2; - int64_t f2g3 = f2 * (int64_t) g3; - int64_t f2g4 = f2 * (int64_t) g4; - int64_t f2g5 = f2 * (int64_t) g5; - int64_t f2g6 = f2 * (int64_t) g6; - int64_t f2g7 = f2 * (int64_t) g7; - int64_t f2g8_19 = f2 * (int64_t) g8_19; - int64_t f2g9_19 = f2 * (int64_t) g9_19; - int64_t f3g0 = f3 * (int64_t) g0; - int64_t f3g1_2 = f3_2 * (int64_t) g1; - int64_t f3g2 = f3 * (int64_t) g2; - int64_t f3g3_2 = f3_2 * (int64_t) g3; - int64_t f3g4 = f3 * (int64_t) g4; - int64_t f3g5_2 = f3_2 * (int64_t) g5; - int64_t f3g6 = f3 * (int64_t) g6; - int64_t f3g7_38 = f3_2 * (int64_t) g7_19; - int64_t f3g8_19 = f3 * (int64_t) g8_19; - int64_t f3g9_38 = f3_2 * (int64_t) g9_19; - int64_t f4g0 = f4 * (int64_t) g0; - int64_t f4g1 = f4 * (int64_t) g1; - int64_t f4g2 = f4 * (int64_t) g2; - int64_t f4g3 = f4 * (int64_t) g3; - int64_t f4g4 = f4 * (int64_t) g4; - int64_t f4g5 = f4 * (int64_t) g5; - int64_t f4g6_19 = f4 * (int64_t) g6_19; - int64_t f4g7_19 = f4 * (int64_t) g7_19; - int64_t f4g8_19 = f4 * (int64_t) g8_19; - int64_t f4g9_19 = f4 * (int64_t) g9_19; - int64_t f5g0 = f5 * (int64_t) g0; - int64_t f5g1_2 = f5_2 * (int64_t) g1; - int64_t f5g2 = f5 * (int64_t) g2; - int64_t f5g3_2 = f5_2 * (int64_t) g3; - int64_t f5g4 = f5 * (int64_t) g4; - int64_t f5g5_38 = f5_2 * (int64_t) g5_19; - int64_t f5g6_19 = f5 * (int64_t) g6_19; - int64_t f5g7_38 = f5_2 * (int64_t) g7_19; - int64_t f5g8_19 = f5 * (int64_t) g8_19; - int64_t f5g9_38 = f5_2 * (int64_t) g9_19; - int64_t f6g0 = f6 * (int64_t) g0; - int64_t f6g1 = f6 * (int64_t) g1; - int64_t f6g2 = f6 * (int64_t) g2; - int64_t f6g3 = f6 * (int64_t) g3; - int64_t f6g4_19 = f6 * (int64_t) g4_19; - int64_t f6g5_19 = f6 * (int64_t) g5_19; - int64_t f6g6_19 = f6 * (int64_t) g6_19; - int64_t f6g7_19 = f6 * (int64_t) g7_19; - int64_t f6g8_19 = f6 * (int64_t) g8_19; - int64_t f6g9_19 = f6 * (int64_t) g9_19; - int64_t f7g0 = f7 * (int64_t) g0; - int64_t f7g1_2 = f7_2 * (int64_t) g1; - int64_t f7g2 = f7 * (int64_t) g2; - int64_t f7g3_38 = f7_2 * (int64_t) g3_19; - int64_t f7g4_19 = f7 * (int64_t) g4_19; - int64_t f7g5_38 = f7_2 * (int64_t) g5_19; - int64_t f7g6_19 = f7 * (int64_t) g6_19; - int64_t f7g7_38 = f7_2 * (int64_t) g7_19; - int64_t f7g8_19 = f7 * (int64_t) g8_19; - int64_t f7g9_38 = f7_2 * (int64_t) g9_19; - int64_t f8g0 = f8 * (int64_t) g0; - int64_t f8g1 = f8 * (int64_t) g1; - int64_t f8g2_19 = f8 * (int64_t) g2_19; - int64_t f8g3_19 = f8 * (int64_t) g3_19; - int64_t f8g4_19 = f8 * (int64_t) g4_19; - int64_t f8g5_19 = f8 * (int64_t) g5_19; - int64_t f8g6_19 = f8 * (int64_t) g6_19; - int64_t f8g7_19 = f8 * (int64_t) g7_19; - int64_t f8g8_19 = f8 * (int64_t) g8_19; - int64_t f8g9_19 = f8 * (int64_t) g9_19; - int64_t f9g0 = f9 * (int64_t) g0; - int64_t f9g1_38 = f9_2 * (int64_t) g1_19; - int64_t f9g2_19 = f9 * (int64_t) g2_19; - int64_t f9g3_38 = f9_2 * (int64_t) g3_19; - int64_t f9g4_19 = f9 * (int64_t) g4_19; - int64_t f9g5_38 = f9_2 * (int64_t) g5_19; - int64_t f9g6_19 = f9 * (int64_t) g6_19; - int64_t f9g7_38 = f9_2 * (int64_t) g7_19; - int64_t f9g8_19 = f9 * (int64_t) g8_19; - int64_t f9g9_38 = f9_2 * (int64_t) g9_19; - int64_t h0 = f0g0 + f1g9_38 + f2g8_19 + f3g7_38 + f4g6_19 + f5g5_38 + f6g4_19 + f7g3_38 + f8g2_19 + f9g1_38; - int64_t h1 = f0g1 + f1g0 + f2g9_19 + f3g8_19 + f4g7_19 + f5g6_19 + f6g5_19 + f7g4_19 + f8g3_19 + f9g2_19; - int64_t h2 = f0g2 + f1g1_2 + f2g0 + f3g9_38 + f4g8_19 + f5g7_38 + f6g6_19 + f7g5_38 + f8g4_19 + f9g3_38; - int64_t h3 = f0g3 + f1g2 + f2g1 + f3g0 + f4g9_19 + f5g8_19 + f6g7_19 + f7g6_19 + f8g5_19 + f9g4_19; - int64_t h4 = f0g4 + f1g3_2 + f2g2 + f3g1_2 + f4g0 + f5g9_38 + f6g8_19 + f7g7_38 + f8g6_19 + f9g5_38; - int64_t h5 = f0g5 + f1g4 + f2g3 + f3g2 + f4g1 + f5g0 + f6g9_19 + f7g8_19 + f8g7_19 + f9g6_19; - int64_t h6 = f0g6 + f1g5_2 + f2g4 + f3g3_2 + f4g2 + f5g1_2 + f6g0 + f7g9_38 + f8g8_19 + f9g7_38; - int64_t h7 = f0g7 + f1g6 + f2g5 + f3g4 + f4g3 + f5g2 + f6g1 + f7g0 + f8g9_19 + f9g8_19; - int64_t h8 = f0g8 + f1g7_2 + f2g6 + f3g5_2 + f4g4 + f5g3_2 + f6g2 + f7g1_2 + f8g0 + f9g9_38; - int64_t h9 = f0g9 + f1g8 + f2g7 + f3g6 + f4g5 + f5g4 + f6g3 + f7g2 + f8g1 + f9g0 ; - int64_t carry0; - int64_t carry1; - int64_t carry2; - int64_t carry3; - int64_t carry4; - int64_t carry5; - int64_t carry6; - int64_t carry7; - int64_t carry8; - int64_t carry9; - - carry0 = (h0 + (1L << 25)) >> 26; - h1 += carry0; - h0 -= shl64(carry0, 26); - carry4 = (h4 + (1L << 25)) >> 26; - h5 += carry4; - h4 -= shl64(carry4, 26); - - carry1 = (h1 + (1L << 24)) >> 25; - h2 += carry1; - h1 -= shl64(carry1, 25); - carry5 = (h5 + (1L << 24)) >> 25; - h6 += carry5; - h5 -= shl64(carry5, 25); - - carry2 = (h2 + (1L << 25)) >> 26; - h3 += carry2; - h2 -= shl64(carry2, 26); - carry6 = (h6 + (1L << 25)) >> 26; - h7 += carry6; - h6 -= shl64(carry6, 26); - - carry3 = (h3 + (1L << 24)) >> 25; - h4 += carry3; - h3 -= shl64(carry3, 25); - carry7 = (h7 + (1L << 24)) >> 25; - h8 += carry7; - h7 -= shl64(carry7, 25); - - carry4 = (h4 + (1L << 25)) >> 26; - h5 += carry4; - h4 -= shl64(carry4, 26); - carry8 = (h8 + (1L << 25)) >> 26; - h9 += carry8; - h8 -= shl64(carry8, 26); - - carry9 = (h9 + (1L << 24)) >> 25; - h0 += carry9 * 19; - h9 -= shl64(carry9, 25); - - carry0 = (h0 + (1L << 25)) >> 26; - h1 += carry0; - h0 -= shl64(carry0, 26); - - h[0] = (int32_t) h0; - h[1] = (int32_t) h1; - h[2] = (int32_t) h2; - h[3] = (int32_t) h3; - h[4] = (int32_t) h4; - h[5] = (int32_t) h5; - h[6] = (int32_t) h6; - h[7] = (int32_t) h7; - h[8] = (int32_t) h8; - h[9] = (int32_t) h9; -} - - -/* -h = f * 121666 -Can overlap h with f. - -Preconditions: - |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. - -Postconditions: - |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. -*/ - -void fe_mul121666(fe h, fe f) { - int32_t f0 = f[0]; - int32_t f1 = f[1]; - int32_t f2 = f[2]; - int32_t f3 = f[3]; - int32_t f4 = f[4]; - int32_t f5 = f[5]; - int32_t f6 = f[6]; - int32_t f7 = f[7]; - int32_t f8 = f[8]; - int32_t f9 = f[9]; - int64_t h0 = f0 * (int64_t) 121666; - int64_t h1 = f1 * (int64_t) 121666; - int64_t h2 = f2 * (int64_t) 121666; - int64_t h3 = f3 * (int64_t) 121666; - int64_t h4 = f4 * (int64_t) 121666; - int64_t h5 = f5 * (int64_t) 121666; - int64_t h6 = f6 * (int64_t) 121666; - int64_t h7 = f7 * (int64_t) 121666; - int64_t h8 = f8 * (int64_t) 121666; - int64_t h9 = f9 * (int64_t) 121666; - int64_t carry0; - int64_t carry1; - int64_t carry2; - int64_t carry3; - int64_t carry4; - int64_t carry5; - int64_t carry6; - int64_t carry7; - int64_t carry8; - int64_t carry9; - - carry9 = (h9 + (int64_t)(1 << 24)) >> 25; - h0 += carry9 * 19; - h9 -= shl64(carry9, 25); - carry1 = (h1 + (int64_t)(1 << 24)) >> 25; - h2 += carry1; - h1 -= shl64(carry1, 25); - carry3 = (h3 + (int64_t)(1 << 24)) >> 25; - h4 += carry3; - h3 -= shl64(carry3, 25); - carry5 = (h5 + (int64_t)(1 << 24)) >> 25; - h6 += carry5; - h5 -= shl64(carry5, 25); - carry7 = (h7 + (int64_t)(1 << 24)) >> 25; - h8 += carry7; - h7 -= shl64(carry7, 25); - - carry0 = (h0 + (int64_t)(1 << 25)) >> 26; - h1 += carry0; - h0 -= shl64(carry0, 26); - carry2 = (h2 + (int64_t)(1 << 25)) >> 26; - h3 += carry2; - h2 -= shl64(carry2, 26); - carry4 = (h4 + (int64_t)(1 << 25)) >> 26; - h5 += carry4; - h4 -= shl64(carry4, 26); - carry6 = (h6 + (int64_t)(1 << 25)) >> 26; - h7 += carry6; - h6 -= shl64(carry6, 26); - carry8 = (h8 + (int64_t)(1 << 25)) >> 26; - h9 += carry8; - h8 -= shl64(carry8, 26); - - h[0] = h0; - h[1] = h1; - h[2] = h2; - h[3] = h3; - h[4] = h4; - h[5] = h5; - h[6] = h6; - h[7] = h7; - h[8] = h8; - h[9] = h9; -} - - -/* -h = -f - -Preconditions: - |f| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. - -Postconditions: - |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. -*/ - -void fe_neg(fe h, const fe f) { - int32_t f0 = f[0]; - int32_t f1 = f[1]; - int32_t f2 = f[2]; - int32_t f3 = f[3]; - int32_t f4 = f[4]; - int32_t f5 = f[5]; - int32_t f6 = f[6]; - int32_t f7 = f[7]; - int32_t f8 = f[8]; - int32_t f9 = f[9]; - int32_t h0 = -f0; - int32_t h1 = -f1; - int32_t h2 = -f2; - int32_t h3 = -f3; - int32_t h4 = -f4; - int32_t h5 = -f5; - int32_t h6 = -f6; - int32_t h7 = -f7; - int32_t h8 = -f8; - int32_t h9 = -f9; - - h[0] = h0; - h[1] = h1; - h[2] = h2; - h[3] = h3; - h[4] = h4; - h[5] = h5; - h[6] = h6; - h[7] = h7; - h[8] = h8; - h[9] = h9; -} - - -void fe_pow22523(fe out, const fe z) { - fe t0; - fe t1; - fe t2; - int i; - fe_sq(t0, z); - - for(i = 1; i < 1; ++i) { - fe_sq(t0, t0); - } - - fe_sq(t1, t0); - - for(i = 1; i < 2; ++i) { - fe_sq(t1, t1); - } - - fe_mul(t1, z, t1); - fe_mul(t0, t0, t1); - fe_sq(t0, t0); - - for(i = 1; i < 1; ++i) { - fe_sq(t0, t0); - } - - fe_mul(t0, t1, t0); - fe_sq(t1, t0); - - for(i = 1; i < 5; ++i) { - fe_sq(t1, t1); - } - - fe_mul(t0, t1, t0); - fe_sq(t1, t0); - - for(i = 1; i < 10; ++i) { - fe_sq(t1, t1); - } - - fe_mul(t1, t1, t0); - fe_sq(t2, t1); - - for(i = 1; i < 20; ++i) { - fe_sq(t2, t2); - } - - fe_mul(t1, t2, t1); - fe_sq(t1, t1); - - for(i = 1; i < 10; ++i) { - fe_sq(t1, t1); - } - - fe_mul(t0, t1, t0); - fe_sq(t1, t0); - - for(i = 1; i < 50; ++i) { - fe_sq(t1, t1); - } - - fe_mul(t1, t1, t0); - fe_sq(t2, t1); - - for(i = 1; i < 100; ++i) { - fe_sq(t2, t2); - } - - fe_mul(t1, t2, t1); - fe_sq(t1, t1); - - for(i = 1; i < 50; ++i) { - fe_sq(t1, t1); - } - - fe_mul(t0, t1, t0); - fe_sq(t0, t0); - - for(i = 1; i < 2; ++i) { - fe_sq(t0, t0); - } - - fe_mul(out, t0, z); - return; -} - - -/* -h = f * f -Can overlap h with f. - -Preconditions: - |f| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc. - -Postconditions: - |h| bounded by 1.01*2^25,1.01*2^24,1.01*2^25,1.01*2^24,etc. -*/ - -/* -See fe_mul.c for discussion of implementation strategy. -*/ - -void fe_sq(fe h, const fe f) { - int32_t f0 = f[0]; - int32_t f1 = f[1]; - int32_t f2 = f[2]; - int32_t f3 = f[3]; - int32_t f4 = f[4]; - int32_t f5 = f[5]; - int32_t f6 = f[6]; - int32_t f7 = f[7]; - int32_t f8 = f[8]; - int32_t f9 = f[9]; - int32_t f0_2 = 2 * f0; - int32_t f1_2 = 2 * f1; - int32_t f2_2 = 2 * f2; - int32_t f3_2 = 2 * f3; - int32_t f4_2 = 2 * f4; - int32_t f5_2 = 2 * f5; - int32_t f6_2 = 2 * f6; - int32_t f7_2 = 2 * f7; - int32_t f5_38 = 38 * f5; /* 1.959375*2^30 */ - int32_t f6_19 = 19 * f6; /* 1.959375*2^30 */ - int32_t f7_38 = 38 * f7; /* 1.959375*2^30 */ - int32_t f8_19 = 19 * f8; /* 1.959375*2^30 */ - int32_t f9_38 = 38 * f9; /* 1.959375*2^30 */ - int64_t f0f0 = f0 * (int64_t) f0; - int64_t f0f1_2 = f0_2 * (int64_t) f1; - int64_t f0f2_2 = f0_2 * (int64_t) f2; - int64_t f0f3_2 = f0_2 * (int64_t) f3; - int64_t f0f4_2 = f0_2 * (int64_t) f4; - int64_t f0f5_2 = f0_2 * (int64_t) f5; - int64_t f0f6_2 = f0_2 * (int64_t) f6; - int64_t f0f7_2 = f0_2 * (int64_t) f7; - int64_t f0f8_2 = f0_2 * (int64_t) f8; - int64_t f0f9_2 = f0_2 * (int64_t) f9; - int64_t f1f1_2 = f1_2 * (int64_t) f1; - int64_t f1f2_2 = f1_2 * (int64_t) f2; - int64_t f1f3_4 = f1_2 * (int64_t) f3_2; - int64_t f1f4_2 = f1_2 * (int64_t) f4; - int64_t f1f5_4 = f1_2 * (int64_t) f5_2; - int64_t f1f6_2 = f1_2 * (int64_t) f6; - int64_t f1f7_4 = f1_2 * (int64_t) f7_2; - int64_t f1f8_2 = f1_2 * (int64_t) f8; - int64_t f1f9_76 = f1_2 * (int64_t) f9_38; - int64_t f2f2 = f2 * (int64_t) f2; - int64_t f2f3_2 = f2_2 * (int64_t) f3; - int64_t f2f4_2 = f2_2 * (int64_t) f4; - int64_t f2f5_2 = f2_2 * (int64_t) f5; - int64_t f2f6_2 = f2_2 * (int64_t) f6; - int64_t f2f7_2 = f2_2 * (int64_t) f7; - int64_t f2f8_38 = f2_2 * (int64_t) f8_19; - int64_t f2f9_38 = f2 * (int64_t) f9_38; - int64_t f3f3_2 = f3_2 * (int64_t) f3; - int64_t f3f4_2 = f3_2 * (int64_t) f4; - int64_t f3f5_4 = f3_2 * (int64_t) f5_2; - int64_t f3f6_2 = f3_2 * (int64_t) f6; - int64_t f3f7_76 = f3_2 * (int64_t) f7_38; - int64_t f3f8_38 = f3_2 * (int64_t) f8_19; - int64_t f3f9_76 = f3_2 * (int64_t) f9_38; - int64_t f4f4 = f4 * (int64_t) f4; - int64_t f4f5_2 = f4_2 * (int64_t) f5; - int64_t f4f6_38 = f4_2 * (int64_t) f6_19; - int64_t f4f7_38 = f4 * (int64_t) f7_38; - int64_t f4f8_38 = f4_2 * (int64_t) f8_19; - int64_t f4f9_38 = f4 * (int64_t) f9_38; - int64_t f5f5_38 = f5 * (int64_t) f5_38; - int64_t f5f6_38 = f5_2 * (int64_t) f6_19; - int64_t f5f7_76 = f5_2 * (int64_t) f7_38; - int64_t f5f8_38 = f5_2 * (int64_t) f8_19; - int64_t f5f9_76 = f5_2 * (int64_t) f9_38; - int64_t f6f6_19 = f6 * (int64_t) f6_19; - int64_t f6f7_38 = f6 * (int64_t) f7_38; - int64_t f6f8_38 = f6_2 * (int64_t) f8_19; - int64_t f6f9_38 = f6 * (int64_t) f9_38; - int64_t f7f7_38 = f7 * (int64_t) f7_38; - int64_t f7f8_38 = f7_2 * (int64_t) f8_19; - int64_t f7f9_76 = f7_2 * (int64_t) f9_38; - int64_t f8f8_19 = f8 * (int64_t) f8_19; - int64_t f8f9_38 = f8 * (int64_t) f9_38; - int64_t f9f9_38 = f9 * (int64_t) f9_38; - int64_t h0 = f0f0 + f1f9_76 + f2f8_38 + f3f7_76 + f4f6_38 + f5f5_38; - int64_t h1 = f0f1_2 + f2f9_38 + f3f8_38 + f4f7_38 + f5f6_38; - int64_t h2 = f0f2_2 + f1f1_2 + f3f9_76 + f4f8_38 + f5f7_76 + f6f6_19; - int64_t h3 = f0f3_2 + f1f2_2 + f4f9_38 + f5f8_38 + f6f7_38; - int64_t h4 = f0f4_2 + f1f3_4 + f2f2 + f5f9_76 + f6f8_38 + f7f7_38; - int64_t h5 = f0f5_2 + f1f4_2 + f2f3_2 + f6f9_38 + f7f8_38; - int64_t h6 = f0f6_2 + f1f5_4 + f2f4_2 + f3f3_2 + f7f9_76 + f8f8_19; - int64_t h7 = f0f7_2 + f1f6_2 + f2f5_2 + f3f4_2 + f8f9_38; - int64_t h8 = f0f8_2 + f1f7_4 + f2f6_2 + f3f5_4 + f4f4 + f9f9_38; - int64_t h9 = f0f9_2 + f1f8_2 + f2f7_2 + f3f6_2 + f4f5_2; - int64_t carry0; - int64_t carry1; - int64_t carry2; - int64_t carry3; - int64_t carry4; - int64_t carry5; - int64_t carry6; - int64_t carry7; - int64_t carry8; - int64_t carry9; - carry0 = (h0 + (1L << 25)) >> 26; - h1 += carry0; - h0 -= shl64(carry0, 26); - carry4 = (h4 + (1L << 25)) >> 26; - h5 += carry4; - h4 -= shl64(carry4, 26); - carry1 = (h1 + (1L << 24)) >> 25; - h2 += carry1; - h1 -= shl64(carry1, 25); - carry5 = (h5 + (1L << 24)) >> 25; - h6 += carry5; - h5 -= shl64(carry5, 25); - carry2 = (h2 + (1L << 25)) >> 26; - h3 += carry2; - h2 -= shl64(carry2, 26); - carry6 = (h6 + (1L << 25)) >> 26; - h7 += carry6; - h6 -= shl64(carry6, 26); - carry3 = (h3 + (1L << 24)) >> 25; - h4 += carry3; - h3 -= shl64(carry3, 25); - carry7 = (h7 + (1L << 24)) >> 25; - h8 += carry7; - h7 -= shl64(carry7, 25); - carry4 = (h4 + (1L << 25)) >> 26; - h5 += carry4; - h4 -= shl64(carry4, 26); - carry8 = (h8 + (1L << 25)) >> 26; - h9 += carry8; - h8 -= shl64(carry8, 26); - carry9 = (h9 + (1L << 24)) >> 25; - h0 += carry9 * 19; - h9 -= shl64(carry9, 25); - carry0 = (h0 + (1L << 25)) >> 26; - h1 += carry0; - h0 -= shl64(carry0, 26); - h[0] = (int32_t) h0; - h[1] = (int32_t) h1; - h[2] = (int32_t) h2; - h[3] = (int32_t) h3; - h[4] = (int32_t) h4; - h[5] = (int32_t) h5; - h[6] = (int32_t) h6; - h[7] = (int32_t) h7; - h[8] = (int32_t) h8; - h[9] = (int32_t) h9; -} - - -/* -h = 2 * f * f -Can overlap h with f. - -Preconditions: - |f| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc. - -Postconditions: - |h| bounded by 1.01*2^25,1.01*2^24,1.01*2^25,1.01*2^24,etc. -*/ - -/* -See fe_mul.c for discussion of implementation strategy. -*/ - -void fe_sq2(fe h, const fe f) { - int32_t f0 = f[0]; - int32_t f1 = f[1]; - int32_t f2 = f[2]; - int32_t f3 = f[3]; - int32_t f4 = f[4]; - int32_t f5 = f[5]; - int32_t f6 = f[6]; - int32_t f7 = f[7]; - int32_t f8 = f[8]; - int32_t f9 = f[9]; - int32_t f0_2 = 2 * f0; - int32_t f1_2 = 2 * f1; - int32_t f2_2 = 2 * f2; - int32_t f3_2 = 2 * f3; - int32_t f4_2 = 2 * f4; - int32_t f5_2 = 2 * f5; - int32_t f6_2 = 2 * f6; - int32_t f7_2 = 2 * f7; - int32_t f5_38 = 38 * f5; /* 1.959375*2^30 */ - int32_t f6_19 = 19 * f6; /* 1.959375*2^30 */ - int32_t f7_38 = 38 * f7; /* 1.959375*2^30 */ - int32_t f8_19 = 19 * f8; /* 1.959375*2^30 */ - int32_t f9_38 = 38 * f9; /* 1.959375*2^30 */ - int64_t f0f0 = f0 * (int64_t) f0; - int64_t f0f1_2 = f0_2 * (int64_t) f1; - int64_t f0f2_2 = f0_2 * (int64_t) f2; - int64_t f0f3_2 = f0_2 * (int64_t) f3; - int64_t f0f4_2 = f0_2 * (int64_t) f4; - int64_t f0f5_2 = f0_2 * (int64_t) f5; - int64_t f0f6_2 = f0_2 * (int64_t) f6; - int64_t f0f7_2 = f0_2 * (int64_t) f7; - int64_t f0f8_2 = f0_2 * (int64_t) f8; - int64_t f0f9_2 = f0_2 * (int64_t) f9; - int64_t f1f1_2 = f1_2 * (int64_t) f1; - int64_t f1f2_2 = f1_2 * (int64_t) f2; - int64_t f1f3_4 = f1_2 * (int64_t) f3_2; - int64_t f1f4_2 = f1_2 * (int64_t) f4; - int64_t f1f5_4 = f1_2 * (int64_t) f5_2; - int64_t f1f6_2 = f1_2 * (int64_t) f6; - int64_t f1f7_4 = f1_2 * (int64_t) f7_2; - int64_t f1f8_2 = f1_2 * (int64_t) f8; - int64_t f1f9_76 = f1_2 * (int64_t) f9_38; - int64_t f2f2 = f2 * (int64_t) f2; - int64_t f2f3_2 = f2_2 * (int64_t) f3; - int64_t f2f4_2 = f2_2 * (int64_t) f4; - int64_t f2f5_2 = f2_2 * (int64_t) f5; - int64_t f2f6_2 = f2_2 * (int64_t) f6; - int64_t f2f7_2 = f2_2 * (int64_t) f7; - int64_t f2f8_38 = f2_2 * (int64_t) f8_19; - int64_t f2f9_38 = f2 * (int64_t) f9_38; - int64_t f3f3_2 = f3_2 * (int64_t) f3; - int64_t f3f4_2 = f3_2 * (int64_t) f4; - int64_t f3f5_4 = f3_2 * (int64_t) f5_2; - int64_t f3f6_2 = f3_2 * (int64_t) f6; - int64_t f3f7_76 = f3_2 * (int64_t) f7_38; - int64_t f3f8_38 = f3_2 * (int64_t) f8_19; - int64_t f3f9_76 = f3_2 * (int64_t) f9_38; - int64_t f4f4 = f4 * (int64_t) f4; - int64_t f4f5_2 = f4_2 * (int64_t) f5; - int64_t f4f6_38 = f4_2 * (int64_t) f6_19; - int64_t f4f7_38 = f4 * (int64_t) f7_38; - int64_t f4f8_38 = f4_2 * (int64_t) f8_19; - int64_t f4f9_38 = f4 * (int64_t) f9_38; - int64_t f5f5_38 = f5 * (int64_t) f5_38; - int64_t f5f6_38 = f5_2 * (int64_t) f6_19; - int64_t f5f7_76 = f5_2 * (int64_t) f7_38; - int64_t f5f8_38 = f5_2 * (int64_t) f8_19; - int64_t f5f9_76 = f5_2 * (int64_t) f9_38; - int64_t f6f6_19 = f6 * (int64_t) f6_19; - int64_t f6f7_38 = f6 * (int64_t) f7_38; - int64_t f6f8_38 = f6_2 * (int64_t) f8_19; - int64_t f6f9_38 = f6 * (int64_t) f9_38; - int64_t f7f7_38 = f7 * (int64_t) f7_38; - int64_t f7f8_38 = f7_2 * (int64_t) f8_19; - int64_t f7f9_76 = f7_2 * (int64_t) f9_38; - int64_t f8f8_19 = f8 * (int64_t) f8_19; - int64_t f8f9_38 = f8 * (int64_t) f9_38; - int64_t f9f9_38 = f9 * (int64_t) f9_38; - int64_t h0 = f0f0 + f1f9_76 + f2f8_38 + f3f7_76 + f4f6_38 + f5f5_38; - int64_t h1 = f0f1_2 + f2f9_38 + f3f8_38 + f4f7_38 + f5f6_38; - int64_t h2 = f0f2_2 + f1f1_2 + f3f9_76 + f4f8_38 + f5f7_76 + f6f6_19; - int64_t h3 = f0f3_2 + f1f2_2 + f4f9_38 + f5f8_38 + f6f7_38; - int64_t h4 = f0f4_2 + f1f3_4 + f2f2 + f5f9_76 + f6f8_38 + f7f7_38; - int64_t h5 = f0f5_2 + f1f4_2 + f2f3_2 + f6f9_38 + f7f8_38; - int64_t h6 = f0f6_2 + f1f5_4 + f2f4_2 + f3f3_2 + f7f9_76 + f8f8_19; - int64_t h7 = f0f7_2 + f1f6_2 + f2f5_2 + f3f4_2 + f8f9_38; - int64_t h8 = f0f8_2 + f1f7_4 + f2f6_2 + f3f5_4 + f4f4 + f9f9_38; - int64_t h9 = f0f9_2 + f1f8_2 + f2f7_2 + f3f6_2 + f4f5_2; - int64_t carry0; - int64_t carry1; - int64_t carry2; - int64_t carry3; - int64_t carry4; - int64_t carry5; - int64_t carry6; - int64_t carry7; - int64_t carry8; - int64_t carry9; - h0 += h0; - h1 += h1; - h2 += h2; - h3 += h3; - h4 += h4; - h5 += h5; - h6 += h6; - h7 += h7; - h8 += h8; - h9 += h9; - carry0 = (h0 + (1L << 25)) >> 26; - h1 += carry0; - h0 -= shl64(carry0, 26); - carry4 = (h4 + (1L << 25)) >> 26; - h5 += carry4; - h4 -= shl64(carry4, 26); - carry1 = (h1 + (1L << 24)) >> 25; - h2 += carry1; - h1 -= shl64(carry1, 25); - carry5 = (h5 + (1L << 24)) >> 25; - h6 += carry5; - h5 -= shl64(carry5, 25); - carry2 = (h2 + (1L << 25)) >> 26; - h3 += carry2; - h2 -= shl64(carry2, 26); - carry6 = (h6 + (1L << 25)) >> 26; - h7 += carry6; - h6 -= shl64(carry6, 26); - carry3 = (h3 + (1L << 24)) >> 25; - h4 += carry3; - h3 -= shl64(carry3, 25); - carry7 = (h7 + (1L << 24)) >> 25; - h8 += carry7; - h7 -= shl64(carry7, 25); - carry4 = (h4 + (1L << 25)) >> 26; - h5 += carry4; - h4 -= shl64(carry4, 26); - carry8 = (h8 + (1L << 25)) >> 26; - h9 += carry8; - h8 -= shl64(carry8, 26); - carry9 = (h9 + (1L << 24)) >> 25; - h0 += carry9 * 19; - h9 -= shl64(carry9, 25); - carry0 = (h0 + (1L << 25)) >> 26; - h1 += carry0; - h0 -= shl64(carry0, 26); - h[0] = (int32_t) h0; - h[1] = (int32_t) h1; - h[2] = (int32_t) h2; - h[3] = (int32_t) h3; - h[4] = (int32_t) h4; - h[5] = (int32_t) h5; - h[6] = (int32_t) h6; - h[7] = (int32_t) h7; - h[8] = (int32_t) h8; - h[9] = (int32_t) h9; -} - - -/* -h = f - g -Can overlap h with f or g. - -Preconditions: - |f| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. - |g| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. - -Postconditions: - |h| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. -*/ - -void fe_sub(fe h, const fe f, const fe g) { - int32_t f0 = f[0]; - int32_t f1 = f[1]; - int32_t f2 = f[2]; - int32_t f3 = f[3]; - int32_t f4 = f[4]; - int32_t f5 = f[5]; - int32_t f6 = f[6]; - int32_t f7 = f[7]; - int32_t f8 = f[8]; - int32_t f9 = f[9]; - int32_t g0 = g[0]; - int32_t g1 = g[1]; - int32_t g2 = g[2]; - int32_t g3 = g[3]; - int32_t g4 = g[4]; - int32_t g5 = g[5]; - int32_t g6 = g[6]; - int32_t g7 = g[7]; - int32_t g8 = g[8]; - int32_t g9 = g[9]; - int32_t h0 = f0 - g0; - int32_t h1 = f1 - g1; - int32_t h2 = f2 - g2; - int32_t h3 = f3 - g3; - int32_t h4 = f4 - g4; - int32_t h5 = f5 - g5; - int32_t h6 = f6 - g6; - int32_t h7 = f7 - g7; - int32_t h8 = f8 - g8; - int32_t h9 = f9 - g9; - - h[0] = h0; - h[1] = h1; - h[2] = h2; - h[3] = h3; - h[4] = h4; - h[5] = h5; - h[6] = h6; - h[7] = h7; - h[8] = h8; - h[9] = h9; -} - - - -/* -Preconditions: - |h| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. - -Write p=2^255-19; q=floor(h/p). -Basic claim: q = floor(2^(-255)(h + 19 2^(-25)h9 + 2^(-1))). - -Proof: - Have |h|<=p so |q|<=1 so |19^2 2^(-255) q|<1/4. - Also have |h-2^230 h9|<2^231 so |19 2^(-255)(h-2^230 h9)|<1/4. - - Write y=2^(-1)-19^2 2^(-255)q-19 2^(-255)(h-2^230 h9). - Then 0> 25; - q = (h0 + q) >> 26; - q = (h1 + q) >> 25; - q = (h2 + q) >> 26; - q = (h3 + q) >> 25; - q = (h4 + q) >> 26; - q = (h5 + q) >> 25; - q = (h6 + q) >> 26; - q = (h7 + q) >> 25; - q = (h8 + q) >> 26; - q = (h9 + q) >> 25; - /* Goal: Output h-(2^255-19)q, which is between 0 and 2^255-20. */ - h0 += 19 * q; - /* Goal: Output h-2^255 q, which is between 0 and 2^255-20. */ - carry0 = h0 >> 26; - h1 += carry0; - h0 -= shl32(carry0, 26); - carry1 = h1 >> 25; - h2 += carry1; - h1 -= shl32(carry1, 25); - carry2 = h2 >> 26; - h3 += carry2; - h2 -= shl32(carry2, 26); - carry3 = h3 >> 25; - h4 += carry3; - h3 -= shl32(carry3, 25); - carry4 = h4 >> 26; - h5 += carry4; - h4 -= shl32(carry4, 26); - carry5 = h5 >> 25; - h6 += carry5; - h5 -= shl32(carry5, 25); - carry6 = h6 >> 26; - h7 += carry6; - h6 -= shl32(carry6, 26); - carry7 = h7 >> 25; - h8 += carry7; - h7 -= shl32(carry7, 25); - carry8 = h8 >> 26; - h9 += carry8; - h8 -= shl32(carry8, 26); - carry9 = h9 >> 25; - h9 -= shl32(carry9, 25); - - /* h10 = carry9 */ - /* - Goal: Output h0+...+2^255 h10-2^255 q, which is between 0 and 2^255-20. - Have h0+...+2^230 h9 between 0 and 2^255-1; - evidently 2^255 h10-2^255 q = 0. - Goal: Output h0+...+2^230 h9. - */ - s[0] = (unsigned char)(h0 >> 0); - s[1] = (unsigned char)(h0 >> 8); - s[2] = (unsigned char)(h0 >> 16); - s[3] = (unsigned char)((h0 >> 24) | shl32(h1, 2)); - s[4] = (unsigned char)(h1 >> 6); - s[5] = (unsigned char)(h1 >> 14); - s[6] = (unsigned char)((h1 >> 22) | shl32(h2, 3)); - s[7] = (unsigned char)(h2 >> 5); - s[8] = (unsigned char)(h2 >> 13); - s[9] = (unsigned char)((h2 >> 21) | shl32(h3, 5)); - s[10] = (unsigned char)(h3 >> 3); - s[11] = (unsigned char)(h3 >> 11); - s[12] = (unsigned char)((h3 >> 19) | shl32(h4, 6)); - s[13] = (unsigned char)(h4 >> 2); - s[14] = (unsigned char)(h4 >> 10); - s[15] = (unsigned char)(h4 >> 18); - s[16] = (unsigned char)(h5 >> 0); - s[17] = (unsigned char)(h5 >> 8); - s[18] = (unsigned char)(h5 >> 16); - s[19] = (unsigned char)((h5 >> 24) | shl32(h6, 1)); - s[20] = (unsigned char)(h6 >> 7); - s[21] = (unsigned char)(h6 >> 15); - s[22] = (unsigned char)((h6 >> 23) | shl32(h7, 3)); - s[23] = (unsigned char)(h7 >> 5); - s[24] = (unsigned char)(h7 >> 13); - s[25] = (unsigned char)((h7 >> 21) | shl32(h8, 4)); - s[26] = (unsigned char)(h8 >> 4); - s[27] = (unsigned char)(h8 >> 12); - s[28] = (unsigned char)((h8 >> 20) | shl32(h9, 6)); - s[29] = (unsigned char)(h9 >> 2); - s[30] = (unsigned char)(h9 >> 10); - s[31] = (unsigned char)(h9 >> 18); -} diff --git a/src/ed25519/fe.h b/src/ed25519/fe.h deleted file mode 100644 index b4b62d2..0000000 --- a/src/ed25519/fe.h +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef FE_H -#define FE_H - -#include "fixedint.h" - - -/* - fe means field element. - Here the field is \Z/(2^255-19). - An element t, entries t[0]...t[9], represents the integer - t[0]+2^26 t[1]+2^51 t[2]+2^77 t[3]+2^102 t[4]+...+2^230 t[9]. - Bounds on each t[i] vary depending on context. -*/ - - -typedef int32_t fe[10]; - - -void fe_0(fe h); -void fe_1(fe h); - -void fe_frombytes(fe h, const unsigned char *s); -void fe_tobytes(unsigned char *s, const fe h); - -void fe_copy(fe h, const fe f); -int fe_isnegative(const fe f); -int fe_isnonzero(const fe f); -void fe_cmov(fe f, const fe g, unsigned int b); -void fe_cswap(fe f, fe g, unsigned int b); - -void fe_neg(fe h, const fe f); -void fe_add(fe h, const fe f, const fe g); -void fe_invert(fe out, const fe z); -void fe_sq(fe h, const fe f); -void fe_sq2(fe h, const fe f); -void fe_mul(fe h, const fe f, const fe g); -void fe_mul121666(fe h, fe f); -void fe_pow22523(fe out, const fe z); -void fe_sub(fe h, const fe f, const fe g); - -#endif diff --git a/src/ed25519/fixedint.h b/src/ed25519/fixedint.h deleted file mode 100644 index af031e9..0000000 --- a/src/ed25519/fixedint.h +++ /dev/null @@ -1,91 +0,0 @@ -#ifndef TINC_FIXEDINT_H -#define TINC_FIXEDINT_H - -/* - Portable header to provide the 32 and 64 bits type. - - Not a compatible replacement for , do not blindly use it as such. -*/ - -#if ((defined(__STDC__) && __STDC__ && __STDC_VERSION__ >= 199901L) || (defined(__WATCOMC__) && (defined(_STDINT_H_INCLUDED) || __WATCOMC__ >= 1250)) || (defined(__GNUC__) && (defined(_STDINT_H) || defined(_STDINT_H_) || defined(__UINT_FAST64_TYPE__)) )) && !defined(FIXEDINT_H_INCLUDED) -#include -#define FIXEDINT_H_INCLUDED - -#if defined(__WATCOMC__) && __WATCOMC__ >= 1250 && !defined(UINT64_C) -#include -#define UINT64_C(x) (x + (UINT64_MAX - UINT64_MAX)) -#endif -#endif - - -#ifndef FIXEDINT_H_INCLUDED -#define FIXEDINT_H_INCLUDED - -/* (u)int32_t */ -#ifndef uint32_t -#if (ULONG_MAX == 0xffffffffUL) -typedef unsigned long uint32_t; -#elif (UINT_MAX == 0xffffffffUL) -typedef unsigned int uint32_t; -#elif (USHRT_MAX == 0xffffffffUL) -typedef unsigned short uint32_t; -#endif -#endif - - -#ifndef int32_t -#if (LONG_MAX == 0x7fffffffL) -typedef signed long int32_t; -#elif (INT_MAX == 0x7fffffffL) -typedef signed int int32_t; -#elif (SHRT_MAX == 0x7fffffffL) -typedef signed short int32_t; -#endif -#endif - - -/* (u)int64_t */ -#if (defined(__STDC__) && defined(__STDC_VERSION__) && __STDC__ && __STDC_VERSION__ >= 199901L) -typedef long long int64_t; -typedef unsigned long long uint64_t; - -#define UINT64_C(v) v ##ULL -#define INT64_C(v) v ##LL -#elif defined(__GNUC__) -__extension__ typedef long long int64_t; -__extension__ typedef unsigned long long uint64_t; - -#define UINT64_C(v) v ##ULL -#define INT64_C(v) v ##LL -#elif defined(__MWERKS__) || defined(__SUNPRO_C) || defined(__SUNPRO_CC) || defined(__APPLE_CC__) || defined(_LONG_LONG) || defined(_CRAYC) -typedef long long int64_t; -typedef unsigned long long uint64_t; - -#define UINT64_C(v) v ##ULL -#define INT64_C(v) v ##LL -#elif (defined(__WATCOMC__) && defined(__WATCOM_INT64__)) || (defined(_MSC_VER) && _INTEGRAL_MAX_BITS >= 64) || (defined(__BORLANDC__) && __BORLANDC__ > 0x460) || defined(__alpha) || defined(__DECC) -typedef __int64 int64_t; -typedef unsigned __int64 uint64_t; - -#define UINT64_C(v) v ##UI64 -#define INT64_C(v) v ##I64 -#endif -#endif - -static inline unsigned char shlu8(unsigned char a, uint32_t b) { - return a << b; -} - -static inline int32_t shl32(uint32_t a, uint32_t b) { - return a << b; -} - -static inline int64_t shl64(uint64_t a, uint32_t b) { - return a << b; -} - -static inline uint64_t shlu64(uint64_t a, uint32_t b) { - return a << b; -} - -#endif diff --git a/src/ed25519/ge.c b/src/ed25519/ge.c deleted file mode 100644 index ca8c39b..0000000 --- a/src/ed25519/ge.c +++ /dev/null @@ -1,467 +0,0 @@ -#include "ge.h" -#include "precomp_data.h" - - -/* -r = p + q -*/ - -void ge_add(ge_p1p1 *r, const ge_p3 *p, const ge_cached *q) { - fe t0; - fe_add(r->X, p->Y, p->X); - fe_sub(r->Y, p->Y, p->X); - fe_mul(r->Z, r->X, q->YplusX); - fe_mul(r->Y, r->Y, q->YminusX); - fe_mul(r->T, q->T2d, p->T); - fe_mul(r->X, p->Z, q->Z); - fe_add(t0, r->X, r->X); - fe_sub(r->X, r->Z, r->Y); - fe_add(r->Y, r->Z, r->Y); - fe_add(r->Z, t0, r->T); - fe_sub(r->T, t0, r->T); -} - - -static void slide(signed char *r, const unsigned char *a) { - int i; - int b; - int k; - - for(i = 0; i < 256; ++i) { - r[i] = 1 & (a[i >> 3] >> (i & 7)); - } - - for(i = 0; i < 256; ++i) - if(r[i]) { - for(b = 1; b <= 6 && i + b < 256; ++b) { - if(r[i + b]) { - if(r[i] + (r[i + b] << b) <= 15) { - r[i] += r[i + b] << b; - r[i + b] = 0; - } else if(r[i] - (r[i + b] << b) >= -15) { - r[i] -= r[i + b] << b; - - for(k = i + b; k < 256; ++k) { - if(!r[k]) { - r[k] = 1; - break; - } - - r[k] = 0; - } - } else { - break; - } - } - } - } -} - -/* -r = a * A + b * B -where a = a[0]+256*a[1]+...+256^31 a[31]. -and b = b[0]+256*b[1]+...+256^31 b[31]. -B is the Ed25519 base point (x,4/5) with x positive. -*/ - -void ge_double_scalarmult_vartime(ge_p2 *r, const unsigned char *a, const ge_p3 *A, const unsigned char *b) { - signed char aslide[256]; - signed char bslide[256]; - ge_cached Ai[8]; /* A,3A,5A,7A,9A,11A,13A,15A */ - ge_p1p1 t; - ge_p3 u; - ge_p3 A2; - int i; - slide(aslide, a); - slide(bslide, b); - ge_p3_to_cached(&Ai[0], A); - ge_p3_dbl(&t, A); - ge_p1p1_to_p3(&A2, &t); - ge_add(&t, &A2, &Ai[0]); - ge_p1p1_to_p3(&u, &t); - ge_p3_to_cached(&Ai[1], &u); - ge_add(&t, &A2, &Ai[1]); - ge_p1p1_to_p3(&u, &t); - ge_p3_to_cached(&Ai[2], &u); - ge_add(&t, &A2, &Ai[2]); - ge_p1p1_to_p3(&u, &t); - ge_p3_to_cached(&Ai[3], &u); - ge_add(&t, &A2, &Ai[3]); - ge_p1p1_to_p3(&u, &t); - ge_p3_to_cached(&Ai[4], &u); - ge_add(&t, &A2, &Ai[4]); - ge_p1p1_to_p3(&u, &t); - ge_p3_to_cached(&Ai[5], &u); - ge_add(&t, &A2, &Ai[5]); - ge_p1p1_to_p3(&u, &t); - ge_p3_to_cached(&Ai[6], &u); - ge_add(&t, &A2, &Ai[6]); - ge_p1p1_to_p3(&u, &t); - ge_p3_to_cached(&Ai[7], &u); - ge_p2_0(r); - - for(i = 255; i >= 0; --i) { - if(aslide[i] || bslide[i]) { - break; - } - } - - for(; i >= 0; --i) { - ge_p2_dbl(&t, r); - - if(aslide[i] > 0) { - ge_p1p1_to_p3(&u, &t); - ge_add(&t, &u, &Ai[aslide[i] / 2]); - } else if(aslide[i] < 0) { - ge_p1p1_to_p3(&u, &t); - ge_sub(&t, &u, &Ai[(-aslide[i]) / 2]); - } - - if(bslide[i] > 0) { - ge_p1p1_to_p3(&u, &t); - ge_madd(&t, &u, &Bi[bslide[i] / 2]); - } else if(bslide[i] < 0) { - ge_p1p1_to_p3(&u, &t); - ge_msub(&t, &u, &Bi[(-bslide[i]) / 2]); - } - - ge_p1p1_to_p2(r, &t); - } -} - - -static const fe d = { - -10913610, 13857413, -15372611, 6949391, 114729, -8787816, -6275908, -3247719, -18696448, -12055116 - }; - -static const fe sqrtm1 = { - -32595792, -7943725, 9377950, 3500415, 12389472, -272473, -25146209, -2005654, 326686, 11406482 - }; - -int ge_frombytes_negate_vartime(ge_p3 *h, const unsigned char *s) { - fe u; - fe v; - fe v3; - fe vxx; - fe check; - fe_frombytes(h->Y, s); - fe_1(h->Z); - fe_sq(u, h->Y); - fe_mul(v, u, d); - fe_sub(u, u, h->Z); /* u = y^2-1 */ - fe_add(v, v, h->Z); /* v = dy^2+1 */ - fe_sq(v3, v); - fe_mul(v3, v3, v); /* v3 = v^3 */ - fe_sq(h->X, v3); - fe_mul(h->X, h->X, v); - fe_mul(h->X, h->X, u); /* x = uv^7 */ - fe_pow22523(h->X, h->X); /* x = (uv^7)^((q-5)/8) */ - fe_mul(h->X, h->X, v3); - fe_mul(h->X, h->X, u); /* x = uv^3(uv^7)^((q-5)/8) */ - fe_sq(vxx, h->X); - fe_mul(vxx, vxx, v); - fe_sub(check, vxx, u); /* vx^2-u */ - - if(fe_isnonzero(check)) { - fe_add(check, vxx, u); /* vx^2+u */ - - if(fe_isnonzero(check)) { - return -1; - } - - fe_mul(h->X, h->X, sqrtm1); - } - - if(fe_isnegative(h->X) == (s[31] >> 7)) { - fe_neg(h->X, h->X); - } - - fe_mul(h->T, h->X, h->Y); - return 0; -} - - -/* -r = p + q -*/ - -void ge_madd(ge_p1p1 *r, const ge_p3 *p, const ge_precomp *q) { - fe t0; - fe_add(r->X, p->Y, p->X); - fe_sub(r->Y, p->Y, p->X); - fe_mul(r->Z, r->X, q->yplusx); - fe_mul(r->Y, r->Y, q->yminusx); - fe_mul(r->T, q->xy2d, p->T); - fe_add(t0, p->Z, p->Z); - fe_sub(r->X, r->Z, r->Y); - fe_add(r->Y, r->Z, r->Y); - fe_add(r->Z, t0, r->T); - fe_sub(r->T, t0, r->T); -} - - -/* -r = p - q -*/ - -void ge_msub(ge_p1p1 *r, const ge_p3 *p, const ge_precomp *q) { - fe t0; - - fe_add(r->X, p->Y, p->X); - fe_sub(r->Y, p->Y, p->X); - fe_mul(r->Z, r->X, q->yminusx); - fe_mul(r->Y, r->Y, q->yplusx); - fe_mul(r->T, q->xy2d, p->T); - fe_add(t0, p->Z, p->Z); - fe_sub(r->X, r->Z, r->Y); - fe_add(r->Y, r->Z, r->Y); - fe_sub(r->Z, t0, r->T); - fe_add(r->T, t0, r->T); -} - - -/* -r = p -*/ - -void ge_p1p1_to_p2(ge_p2 *r, const ge_p1p1 *p) { - fe_mul(r->X, p->X, p->T); - fe_mul(r->Y, p->Y, p->Z); - fe_mul(r->Z, p->Z, p->T); -} - - - -/* -r = p -*/ - -void ge_p1p1_to_p3(ge_p3 *r, const ge_p1p1 *p) { - fe_mul(r->X, p->X, p->T); - fe_mul(r->Y, p->Y, p->Z); - fe_mul(r->Z, p->Z, p->T); - fe_mul(r->T, p->X, p->Y); -} - - -void ge_p2_0(ge_p2 *h) { - fe_0(h->X); - fe_1(h->Y); - fe_1(h->Z); -} - - - -/* -r = 2 * p -*/ - -void ge_p2_dbl(ge_p1p1 *r, const ge_p2 *p) { - fe t0; - - fe_sq(r->X, p->X); - fe_sq(r->Z, p->Y); - fe_sq2(r->T, p->Z); - fe_add(r->Y, p->X, p->Y); - fe_sq(t0, r->Y); - fe_add(r->Y, r->Z, r->X); - fe_sub(r->Z, r->Z, r->X); - fe_sub(r->X, t0, r->Y); - fe_sub(r->T, r->T, r->Z); -} - - -void ge_p3_0(ge_p3 *h) { - fe_0(h->X); - fe_1(h->Y); - fe_1(h->Z); - fe_0(h->T); -} - - -/* -r = 2 * p -*/ - -void ge_p3_dbl(ge_p1p1 *r, const ge_p3 *p) { - ge_p2 q; - ge_p3_to_p2(&q, p); - ge_p2_dbl(r, &q); -} - - - -/* -r = p -*/ - -static const fe d2 = { - -21827239, -5839606, -30745221, 13898782, 229458, 15978800, -12551817, -6495438, 29715968, 9444199 - }; - -void ge_p3_to_cached(ge_cached *r, const ge_p3 *p) { - fe_add(r->YplusX, p->Y, p->X); - fe_sub(r->YminusX, p->Y, p->X); - fe_copy(r->Z, p->Z); - fe_mul(r->T2d, p->T, d2); -} - - -/* -r = p -*/ - -void ge_p3_to_p2(ge_p2 *r, const ge_p3 *p) { - fe_copy(r->X, p->X); - fe_copy(r->Y, p->Y); - fe_copy(r->Z, p->Z); -} - - -void ge_p3_tobytes(unsigned char *s, const ge_p3 *h) { - fe recip; - fe x; - fe y; - fe_invert(recip, h->Z); - fe_mul(x, h->X, recip); - fe_mul(y, h->Y, recip); - fe_tobytes(s, y); - s[31] ^= fe_isnegative(x) << 7; -} - - -static unsigned char equal(signed char b, signed char c) { - unsigned char ub = b; - unsigned char uc = c; - unsigned char x = ub ^ uc; /* 0: yes; 1..255: no */ - uint64_t y = x; /* 0: yes; 1..255: no */ - y -= 1; /* large: yes; 0..254: no */ - y >>= 63; /* 1: yes; 0: no */ - return (unsigned char) y; -} - -static unsigned char negative(signed char b) { - uint64_t x = b; /* 18446744073709551361..18446744073709551615: yes; 0..255: no */ - x >>= 63; /* 1: yes; 0: no */ - return (unsigned char) x; -} - -static void cmov(ge_precomp *t, ge_precomp *u, unsigned char b) { - fe_cmov(t->yplusx, u->yplusx, b); - fe_cmov(t->yminusx, u->yminusx, b); - fe_cmov(t->xy2d, u->xy2d, b); -} - - -static void select(ge_precomp *t, int pos, signed char b) { - ge_precomp minust; - unsigned char bnegative = negative(b); - unsigned char babs = b - shlu8(((-bnegative) & b), 1); - fe_1(t->yplusx); - fe_1(t->yminusx); - fe_0(t->xy2d); - cmov(t, &base[pos][0], equal(babs, 1)); - cmov(t, &base[pos][1], equal(babs, 2)); - cmov(t, &base[pos][2], equal(babs, 3)); - cmov(t, &base[pos][3], equal(babs, 4)); - cmov(t, &base[pos][4], equal(babs, 5)); - cmov(t, &base[pos][5], equal(babs, 6)); - cmov(t, &base[pos][6], equal(babs, 7)); - cmov(t, &base[pos][7], equal(babs, 8)); - fe_copy(minust.yplusx, t->yminusx); - fe_copy(minust.yminusx, t->yplusx); - fe_neg(minust.xy2d, t->xy2d); - cmov(t, &minust, bnegative); -} - -/* -h = a * B -where a = a[0]+256*a[1]+...+256^31 a[31] -B is the Ed25519 base point (x,4/5) with x positive. - -Preconditions: - a[31] <= 127 -*/ - -void ge_scalarmult_base(ge_p3 *h, const unsigned char *a) { - signed char e[64]; - signed char carry; - ge_p1p1 r; - ge_p2 s; - ge_precomp t; - int i; - - for(i = 0; i < 32; ++i) { - e[2 * i + 0] = (a[i] >> 0) & 15; - e[2 * i + 1] = (a[i] >> 4) & 15; - } - - /* each e[i] is between 0 and 15 */ - /* e[63] is between 0 and 7 */ - carry = 0; - - for(i = 0; i < 63; ++i) { - e[i] += carry; - carry = e[i] + 8; - carry >>= 4; - e[i] -= shl32(carry, 4); - } - - e[63] += carry; - /* each e[i] is between -8 and 8 */ - ge_p3_0(h); - - for(i = 1; i < 64; i += 2) { - select(&t, i / 2, e[i]); - ge_madd(&r, h, &t); - ge_p1p1_to_p3(h, &r); - } - - ge_p3_dbl(&r, h); - ge_p1p1_to_p2(&s, &r); - ge_p2_dbl(&r, &s); - ge_p1p1_to_p2(&s, &r); - ge_p2_dbl(&r, &s); - ge_p1p1_to_p2(&s, &r); - ge_p2_dbl(&r, &s); - ge_p1p1_to_p3(h, &r); - - for(i = 0; i < 64; i += 2) { - select(&t, i / 2, e[i]); - ge_madd(&r, h, &t); - ge_p1p1_to_p3(h, &r); - } -} - - -/* -r = p - q -*/ - -void ge_sub(ge_p1p1 *r, const ge_p3 *p, const ge_cached *q) { - fe t0; - - fe_add(r->X, p->Y, p->X); - fe_sub(r->Y, p->Y, p->X); - fe_mul(r->Z, r->X, q->YminusX); - fe_mul(r->Y, r->Y, q->YplusX); - fe_mul(r->T, q->T2d, p->T); - fe_mul(r->X, p->Z, q->Z); - fe_add(t0, r->X, r->X); - fe_sub(r->X, r->Z, r->Y); - fe_add(r->Y, r->Z, r->Y); - fe_sub(r->Z, t0, r->T); - fe_add(r->T, t0, r->T); -} - - -void ge_tobytes(unsigned char *s, const ge_p2 *h) { - fe recip; - fe x; - fe y; - fe_invert(recip, h->Z); - fe_mul(x, h->X, recip); - fe_mul(y, h->Y, recip); - fe_tobytes(s, y); - s[31] ^= fe_isnegative(x) << 7; -} diff --git a/src/ed25519/ge.h b/src/ed25519/ge.h deleted file mode 100644 index 9cc3b98..0000000 --- a/src/ed25519/ge.h +++ /dev/null @@ -1,74 +0,0 @@ -#ifndef GE_H -#define GE_H - -#include "fe.h" - - -/* -ge means group element. - -Here the group is the set of pairs (x,y) of field elements (see fe.h) -satisfying -x^2 + y^2 = 1 + d x^2y^2 -where d = -121665/121666. - -Representations: - ge_p2 (projective): (X:Y:Z) satisfying x=X/Z, y=Y/Z - ge_p3 (extended): (X:Y:Z:T) satisfying x=X/Z, y=Y/Z, XY=ZT - ge_p1p1 (completed): ((X:Z),(Y:T)) satisfying x=X/Z, y=Y/T - ge_precomp (Duif): (y+x,y-x,2dxy) -*/ - -typedef struct { - fe X; - fe Y; - fe Z; -} ge_p2; - -typedef struct { - fe X; - fe Y; - fe Z; - fe T; -} ge_p3; - -typedef struct { - fe X; - fe Y; - fe Z; - fe T; -} ge_p1p1; - -typedef struct { - fe yplusx; - fe yminusx; - fe xy2d; -} ge_precomp; - -typedef struct { - fe YplusX; - fe YminusX; - fe Z; - fe T2d; -} ge_cached; - -void ge_p3_tobytes(unsigned char *s, const ge_p3 *h); -void ge_tobytes(unsigned char *s, const ge_p2 *h); -int ge_frombytes_negate_vartime(ge_p3 *h, const unsigned char *s); - -void ge_add(ge_p1p1 *r, const ge_p3 *p, const ge_cached *q); -void ge_sub(ge_p1p1 *r, const ge_p3 *p, const ge_cached *q); -void ge_double_scalarmult_vartime(ge_p2 *r, const unsigned char *a, const ge_p3 *A, const unsigned char *b); -void ge_madd(ge_p1p1 *r, const ge_p3 *p, const ge_precomp *q); -void ge_msub(ge_p1p1 *r, const ge_p3 *p, const ge_precomp *q); -void ge_scalarmult_base(ge_p3 *h, const unsigned char *a); - -void ge_p1p1_to_p2(ge_p2 *r, const ge_p1p1 *p); -void ge_p1p1_to_p3(ge_p3 *r, const ge_p1p1 *p); -void ge_p2_0(ge_p2 *h); -void ge_p2_dbl(ge_p1p1 *r, const ge_p2 *p); -void ge_p3_0(ge_p3 *h); -void ge_p3_dbl(ge_p1p1 *r, const ge_p3 *p); -void ge_p3_to_cached(ge_cached *r, const ge_p3 *p); -void ge_p3_to_p2(ge_p2 *r, const ge_p3 *p); - -#endif diff --git a/src/ed25519/key_exchange.c b/src/ed25519/key_exchange.c deleted file mode 100644 index 9ace86b..0000000 --- a/src/ed25519/key_exchange.c +++ /dev/null @@ -1,80 +0,0 @@ -#include "ed25519.h" -#include "fe.h" - -void ed25519_key_exchange(unsigned char *shared_secret, const unsigned char *public_key, const unsigned char *private_key) { - unsigned char e[32]; - unsigned int i; - - fe x1; - fe x2; - fe z2; - fe x3; - fe z3; - fe tmp0; - fe tmp1; - - int pos; - unsigned int swap; - unsigned int b; - - /* copy the private key and make sure it's valid */ - for(i = 0; i < 32; ++i) { - e[i] = private_key[i]; - } - - e[0] &= 248; - e[31] &= 63; - e[31] |= 64; - - /* unpack the public key and convert edwards to montgomery */ - /* due to CodesInChaos: montgomeryX = (edwardsY + 1)*inverse(1 - edwardsY) mod p */ - fe_frombytes(x1, public_key); - fe_1(tmp1); - fe_add(tmp0, x1, tmp1); - fe_sub(tmp1, tmp1, x1); - fe_invert(tmp1, tmp1); - fe_mul(x1, tmp0, tmp1); - - fe_1(x2); - fe_0(z2); - fe_copy(x3, x1); - fe_1(z3); - - swap = 0; - - for(pos = 254; pos >= 0; --pos) { - b = e[pos / 8] >> (pos & 7); - b &= 1; - swap ^= b; - fe_cswap(x2, x3, swap); - fe_cswap(z2, z3, swap); - swap = b; - - /* from montgomery.h */ - fe_sub(tmp0, x3, z3); - fe_sub(tmp1, x2, z2); - fe_add(x2, x2, z2); - fe_add(z2, x3, z3); - fe_mul(z3, tmp0, x2); - fe_mul(z2, z2, tmp1); - fe_sq(tmp0, tmp1); - fe_sq(tmp1, x2); - fe_add(x3, z3, z2); - fe_sub(z2, z3, z2); - fe_mul(x2, tmp1, tmp0); - fe_sub(tmp1, tmp1, tmp0); - fe_sq(z2, z2); - fe_mul121666(z3, tmp1); - fe_sq(x3, x3); - fe_add(tmp0, tmp0, z3); - fe_mul(z3, x1, z2); - fe_mul(z2, tmp1, tmp0); - } - - fe_cswap(x2, x3, swap); - fe_cswap(z2, z3, swap); - - fe_invert(z2, z2); - fe_mul(x2, x2, z2); - fe_tobytes(shared_secret, x2); -} diff --git a/src/ed25519/keypair.c b/src/ed25519/keypair.c deleted file mode 100644 index 71ec4d7..0000000 --- a/src/ed25519/keypair.c +++ /dev/null @@ -1,16 +0,0 @@ -#include "ed25519.h" -#include "sha512.h" -#include "ge.h" - - -void ed25519_create_keypair(unsigned char *public_key, unsigned char *private_key, const unsigned char *seed) { - ge_p3 A; - - sha512(seed, 32, private_key); - private_key[0] &= 248; - private_key[31] &= 63; - private_key[31] |= 64; - - ge_scalarmult_base(&A, private_key); - ge_p3_tobytes(public_key, &A); -} diff --git a/src/ed25519/precomp_data.h b/src/ed25519/precomp_data.h deleted file mode 100644 index 7a29302..0000000 --- a/src/ed25519/precomp_data.h +++ /dev/null @@ -1,1391 +0,0 @@ -static ge_precomp Bi[8] = { - { - { 25967493, -14356035, 29566456, 3660896, -12694345, 4014787, 27544626, -11754271, -6079156, 2047605 }, - { -12545711, 934262, -2722910, 3049990, -727428, 9406986, 12720692, 5043384, 19500929, -15469378 }, - { -8738181, 4489570, 9688441, -14785194, 10184609, -12363380, 29287919, 11864899, -24514362, -4438546 }, - }, - { - { 15636291, -9688557, 24204773, -7912398, 616977, -16685262, 27787600, -14772189, 28944400, -1550024 }, - { 16568933, 4717097, -11556148, -1102322, 15682896, -11807043, 16354577, -11775962, 7689662, 11199574 }, - { 30464156, -5976125, -11779434, -15670865, 23220365, 15915852, 7512774, 10017326, -17749093, -9920357 }, - }, - { - { 10861363, 11473154, 27284546, 1981175, -30064349, 12577861, 32867885, 14515107, -15438304, 10819380 }, - { 4708026, 6336745, 20377586, 9066809, -11272109, 6594696, -25653668, 12483688, -12668491, 5581306 }, - { 19563160, 16186464, -29386857, 4097519, 10237984, -4348115, 28542350, 13850243, -23678021, -15815942 }, - }, - { - { 5153746, 9909285, 1723747, -2777874, 30523605, 5516873, 19480852, 5230134, -23952439, -15175766 }, - { -30269007, -3463509, 7665486, 10083793, 28475525, 1649722, 20654025, 16520125, 30598449, 7715701 }, - { 28881845, 14381568, 9657904, 3680757, -20181635, 7843316, -31400660, 1370708, 29794553, -1409300 }, - }, - { - { -22518993, -6692182, 14201702, -8745502, -23510406, 8844726, 18474211, -1361450, -13062696, 13821877 }, - { -6455177, -7839871, 3374702, -4740862, -27098617, -10571707, 31655028, -7212327, 18853322, -14220951 }, - { 4566830, -12963868, -28974889, -12240689, -7602672, -2830569, -8514358, -10431137, 2207753, -3209784 }, - }, - { - { -25154831, -4185821, 29681144, 7868801, -6854661, -9423865, -12437364, -663000, -31111463, -16132436 }, - { 25576264, -2703214, 7349804, -11814844, 16472782, 9300885, 3844789, 15725684, 171356, 6466918 }, - { 23103977, 13316479, 9739013, -16149481, 817875, -15038942, 8965339, -14088058, -30714912, 16193877 }, - }, - { - { -33521811, 3180713, -2394130, 14003687, -16903474, -16270840, 17238398, 4729455, -18074513, 9256800 }, - { -25182317, -4174131, 32336398, 5036987, -21236817, 11360617, 22616405, 9761698, -19827198, 630305 }, - { -13720693, 2639453, -24237460, -7406481, 9494427, -5774029, -6554551, -15960994, -2449256, -14291300 }, - }, - { - { -3151181, -5046075, 9282714, 6866145, -31907062, -863023, -18940575, 15033784, 25105118, -7894876 }, - { -24326370, 15950226, -31801215, -14592823, -11662737, -5090925, 1573892, -2625887, 2198790, -15804619 }, - { -3099351, 10324967, -2241613, 7453183, -5446979, -2735503, -13812022, -16236442, -32461234, -12290683 }, - }, -}; - - -/* base[i][j] = (j+1)*256^i*B */ -static ge_precomp base[32][8] = { - { - { - { 25967493, -14356035, 29566456, 3660896, -12694345, 4014787, 27544626, -11754271, -6079156, 2047605 }, - { -12545711, 934262, -2722910, 3049990, -727428, 9406986, 12720692, 5043384, 19500929, -15469378 }, - { -8738181, 4489570, 9688441, -14785194, 10184609, -12363380, 29287919, 11864899, -24514362, -4438546 }, - }, - { - { -12815894, -12976347, -21581243, 11784320, -25355658, -2750717, -11717903, -3814571, -358445, -10211303 }, - { -21703237, 6903825, 27185491, 6451973, -29577724, -9554005, -15616551, 11189268, -26829678, -5319081 }, - { 26966642, 11152617, 32442495, 15396054, 14353839, -12752335, -3128826, -9541118, -15472047, -4166697 }, - }, - { - { 15636291, -9688557, 24204773, -7912398, 616977, -16685262, 27787600, -14772189, 28944400, -1550024 }, - { 16568933, 4717097, -11556148, -1102322, 15682896, -11807043, 16354577, -11775962, 7689662, 11199574 }, - { 30464156, -5976125, -11779434, -15670865, 23220365, 15915852, 7512774, 10017326, -17749093, -9920357 }, - }, - { - { -17036878, 13921892, 10945806, -6033431, 27105052, -16084379, -28926210, 15006023, 3284568, -6276540 }, - { 23599295, -8306047, -11193664, -7687416, 13236774, 10506355, 7464579, 9656445, 13059162, 10374397 }, - { 7798556, 16710257, 3033922, 2874086, 28997861, 2835604, 32406664, -3839045, -641708, -101325 }, - }, - { - { 10861363, 11473154, 27284546, 1981175, -30064349, 12577861, 32867885, 14515107, -15438304, 10819380 }, - { 4708026, 6336745, 20377586, 9066809, -11272109, 6594696, -25653668, 12483688, -12668491, 5581306 }, - { 19563160, 16186464, -29386857, 4097519, 10237984, -4348115, 28542350, 13850243, -23678021, -15815942 }, - }, - { - { -15371964, -12862754, 32573250, 4720197, -26436522, 5875511, -19188627, -15224819, -9818940, -12085777 }, - { -8549212, 109983, 15149363, 2178705, 22900618, 4543417, 3044240, -15689887, 1762328, 14866737 }, - { -18199695, -15951423, -10473290, 1707278, -17185920, 3916101, -28236412, 3959421, 27914454, 4383652 }, - }, - { - { 5153746, 9909285, 1723747, -2777874, 30523605, 5516873, 19480852, 5230134, -23952439, -15175766 }, - { -30269007, -3463509, 7665486, 10083793, 28475525, 1649722, 20654025, 16520125, 30598449, 7715701 }, - { 28881845, 14381568, 9657904, 3680757, -20181635, 7843316, -31400660, 1370708, 29794553, -1409300 }, - }, - { - { 14499471, -2729599, -33191113, -4254652, 28494862, 14271267, 30290735, 10876454, -33154098, 2381726 }, - { -7195431, -2655363, -14730155, 462251, -27724326, 3941372, -6236617, 3696005, -32300832, 15351955 }, - { 27431194, 8222322, 16448760, -3907995, -18707002, 11938355, -32961401, -2970515, 29551813, 10109425 }, - }, - }, - { - { - { -13657040, -13155431, -31283750, 11777098, 21447386, 6519384, -2378284, -1627556, 10092783, -4764171 }, - { 27939166, 14210322, 4677035, 16277044, -22964462, -12398139, -32508754, 12005538, -17810127, 12803510 }, - { 17228999, -15661624, -1233527, 300140, -1224870, -11714777, 30364213, -9038194, 18016357, 4397660 }, - }, - { - { -10958843, -7690207, 4776341, -14954238, 27850028, -15602212, -26619106, 14544525, -17477504, 982639 }, - { 29253598, 15796703, -2863982, -9908884, 10057023, 3163536, 7332899, -4120128, -21047696, 9934963 }, - { 5793303, 16271923, -24131614, -10116404, 29188560, 1206517, -14747930, 4559895, -30123922, -10897950 }, - }, - { - { -27643952, -11493006, 16282657, -11036493, 28414021, -15012264, 24191034, 4541697, -13338309, 5500568 }, - { 12650548, -1497113, 9052871, 11355358, -17680037, -8400164, -17430592, 12264343, 10874051, 13524335 }, - { 25556948, -3045990, 714651, 2510400, 23394682, -10415330, 33119038, 5080568, -22528059, 5376628 }, - }, - { - { -26088264, -4011052, -17013699, -3537628, -6726793, 1920897, -22321305, -9447443, 4535768, 1569007 }, - { -2255422, 14606630, -21692440, -8039818, 28430649, 8775819, -30494562, 3044290, 31848280, 12543772 }, - { -22028579, 2943893, -31857513, 6777306, 13784462, -4292203, -27377195, -2062731, 7718482, 14474653 }, - }, - { - { 2385315, 2454213, -22631320, 46603, -4437935, -15680415, 656965, -7236665, 24316168, -5253567 }, - { 13741529, 10911568, -33233417, -8603737, -20177830, -1033297, 33040651, -13424532, -20729456, 8321686 }, - { 21060490, -2212744, 15712757, -4336099, 1639040, 10656336, 23845965, -11874838, -9984458, 608372 }, - }, - { - { -13672732, -15087586, -10889693, -7557059, -6036909, 11305547, 1123968, -6780577, 27229399, 23887 }, - { -23244140, -294205, -11744728, 14712571, -29465699, -2029617, 12797024, -6440308, -1633405, 16678954 }, - { -29500620, 4770662, -16054387, 14001338, 7830047, 9564805, -1508144, -4795045, -17169265, 4904953 }, - }, - { - { 24059557, 14617003, 19037157, -15039908, 19766093, -14906429, 5169211, 16191880, 2128236, -4326833 }, - { -16981152, 4124966, -8540610, -10653797, 30336522, -14105247, -29806336, 916033, -6882542, -2986532 }, - { -22630907, 12419372, -7134229, -7473371, -16478904, 16739175, 285431, 2763829, 15736322, 4143876 }, - }, - { - { 2379352, 11839345, -4110402, -5988665, 11274298, 794957, 212801, -14594663, 23527084, -16458268 }, - { 33431127, -11130478, -17838966, -15626900, 8909499, 8376530, -32625340, 4087881, -15188911, -14416214 }, - { 1767683, 7197987, -13205226, -2022635, -13091350, 448826, 5799055, 4357868, -4774191, -16323038 }, - }, - }, - { - { - { 6721966, 13833823, -23523388, -1551314, 26354293, -11863321, 23365147, -3949732, 7390890, 2759800 }, - { 4409041, 2052381, 23373853, 10530217, 7676779, -12885954, 21302353, -4264057, 1244380, -12919645 }, - { -4421239, 7169619, 4982368, -2957590, 30256825, -2777540, 14086413, 9208236, 15886429, 16489664 }, - }, - { - { 1996075, 10375649, 14346367, 13311202, -6874135, -16438411, -13693198, 398369, -30606455, -712933 }, - { -25307465, 9795880, -2777414, 14878809, -33531835, 14780363, 13348553, 12076947, -30836462, 5113182 }, - { -17770784, 11797796, 31950843, 13929123, -25888302, 12288344, -30341101, -7336386, 13847711, 5387222 }, - }, - { - { -18582163, -3416217, 17824843, -2340966, 22744343, -10442611, 8763061, 3617786, -19600662, 10370991 }, - { 20246567, -14369378, 22358229, -543712, 18507283, -10413996, 14554437, -8746092, 32232924, 16763880 }, - { 9648505, 10094563, 26416693, 14745928, -30374318, -6472621, 11094161, 15689506, 3140038, -16510092 }, - }, - { - { -16160072, 5472695, 31895588, 4744994, 8823515, 10365685, -27224800, 9448613, -28774454, 366295 }, - { 19153450, 11523972, -11096490, -6503142, -24647631, 5420647, 28344573, 8041113, 719605, 11671788 }, - { 8678025, 2694440, -6808014, 2517372, 4964326, 11152271, -15432916, -15266516, 27000813, -10195553 }, - }, - { - { -15157904, 7134312, 8639287, -2814877, -7235688, 10421742, 564065, 5336097, 6750977, -14521026 }, - { 11836410, -3979488, 26297894, 16080799, 23455045, 15735944, 1695823, -8819122, 8169720, 16220347 }, - { -18115838, 8653647, 17578566, -6092619, -8025777, -16012763, -11144307, -2627664, -5990708, -14166033 }, - }, - { - { -23308498, -10968312, 15213228, -10081214, -30853605, -11050004, 27884329, 2847284, 2655861, 1738395 }, - { -27537433, -14253021, -25336301, -8002780, -9370762, 8129821, 21651608, -3239336, -19087449, -11005278 }, - { 1533110, 3437855, 23735889, 459276, 29970501, 11335377, 26030092, 5821408, 10478196, 8544890 }, - }, - { - { 32173121, -16129311, 24896207, 3921497, 22579056, -3410854, 19270449, 12217473, 17789017, -3395995 }, - { -30552961, -2228401, -15578829, -10147201, 13243889, 517024, 15479401, -3853233, 30460520, 1052596 }, - { -11614875, 13323618, 32618793, 8175907, -15230173, 12596687, 27491595, -4612359, 3179268, -9478891 }, - }, - { - { 31947069, -14366651, -4640583, -15339921, -15125977, -6039709, -14756777, -16411740, 19072640, -9511060 }, - { 11685058, 11822410, 3158003, -13952594, 33402194, -4165066, 5977896, -5215017, 473099, 5040608 }, - { -20290863, 8198642, -27410132, 11602123, 1290375, -2799760, 28326862, 1721092, -19558642, -3131606 }, - }, - }, - { - { - { 7881532, 10687937, 7578723, 7738378, -18951012, -2553952, 21820786, 8076149, -27868496, 11538389 }, - { -19935666, 3899861, 18283497, -6801568, -15728660, -11249211, 8754525, 7446702, -5676054, 5797016 }, - { -11295600, -3793569, -15782110, -7964573, 12708869, -8456199, 2014099, -9050574, -2369172, -5877341 }, - }, - { - { -22472376, -11568741, -27682020, 1146375, 18956691, 16640559, 1192730, -3714199, 15123619, 10811505 }, - { 14352098, -3419715, -18942044, 10822655, 32750596, 4699007, -70363, 15776356, -28886779, -11974553 }, - { -28241164, -8072475, -4978962, -5315317, 29416931, 1847569, -20654173, -16484855, 4714547, -9600655 }, - }, - { - { 15200332, 8368572, 19679101, 15970074, -31872674, 1959451, 24611599, -4543832, -11745876, 12340220 }, - { 12876937, -10480056, 33134381, 6590940, -6307776, 14872440, 9613953, 8241152, 15370987, 9608631 }, - { -4143277, -12014408, 8446281, -391603, 4407738, 13629032, -7724868, 15866074, -28210621, -8814099 }, - }, - { - { 26660628, -15677655, 8393734, 358047, -7401291, 992988, -23904233, 858697, 20571223, 8420556 }, - { 14620715, 13067227, -15447274, 8264467, 14106269, 15080814, 33531827, 12516406, -21574435, -12476749 }, - { 236881, 10476226, 57258, -14677024, 6472998, 2466984, 17258519, 7256740, 8791136, 15069930 }, - }, - { - { 1276410, -9371918, 22949635, -16322807, -23493039, -5702186, 14711875, 4874229, -30663140, -2331391 }, - { 5855666, 4990204, -13711848, 7294284, -7804282, 1924647, -1423175, -7912378, -33069337, 9234253 }, - { 20590503, -9018988, 31529744, -7352666, -2706834, 10650548, 31559055, -11609587, 18979186, 13396066 }, - }, - { - { 24474287, 4968103, 22267082, 4407354, 24063882, -8325180, -18816887, 13594782, 33514650, 7021958 }, - { -11566906, -6565505, -21365085, 15928892, -26158305, 4315421, -25948728, -3916677, -21480480, 12868082 }, - { -28635013, 13504661, 19988037, -2132761, 21078225, 6443208, -21446107, 2244500, -12455797, -8089383 }, - }, - { - { -30595528, 13793479, -5852820, 319136, -25723172, -6263899, 33086546, 8957937, -15233648, 5540521 }, - { -11630176, -11503902, -8119500, -7643073, 2620056, 1022908, -23710744, -1568984, -16128528, -14962807 }, - { 23152971, 775386, 27395463, 14006635, -9701118, 4649512, 1689819, 892185, -11513277, -15205948 }, - }, - { - { 9770129, 9586738, 26496094, 4324120, 1556511, -3550024, 27453819, 4763127, -19179614, 5867134 }, - { -32765025, 1927590, 31726409, -4753295, 23962434, -16019500, 27846559, 5931263, -29749703, -16108455 }, - { 27461885, -2977536, 22380810, 1815854, -23033753, -3031938, 7283490, -15148073, -19526700, 7734629 }, - }, - }, - { - { - { -8010264, -9590817, -11120403, 6196038, 29344158, -13430885, 7585295, -3176626, 18549497, 15302069 }, - { -32658337, -6171222, -7672793, -11051681, 6258878, 13504381, 10458790, -6418461, -8872242, 8424746 }, - { 24687205, 8613276, -30667046, -3233545, 1863892, -1830544, 19206234, 7134917, -11284482, -828919 }, - }, - { - { 11334899, -9218022, 8025293, 12707519, 17523892, -10476071, 10243738, -14685461, -5066034, 16498837 }, - { 8911542, 6887158, -9584260, -6958590, 11145641, -9543680, 17303925, -14124238, 6536641, 10543906 }, - { -28946384, 15479763, -17466835, 568876, -1497683, 11223454, -2669190, -16625574, -27235709, 8876771 }, - }, - { - { -25742899, -12566864, -15649966, -846607, -33026686, -796288, -33481822, 15824474, -604426, -9039817 }, - { 10330056, 70051, 7957388, -9002667, 9764902, 15609756, 27698697, -4890037, 1657394, 3084098 }, - { 10477963, -7470260, 12119566, -13250805, 29016247, -5365589, 31280319, 14396151, -30233575, 15272409 }, - }, - { - { -12288309, 3169463, 28813183, 16658753, 25116432, -5630466, -25173957, -12636138, -25014757, 1950504 }, - { -26180358, 9489187, 11053416, -14746161, -31053720, 5825630, -8384306, -8767532, 15341279, 8373727 }, - { 28685821, 7759505, -14378516, -12002860, -31971820, 4079242, 298136, -10232602, -2878207, 15190420 }, - }, - { - { -32932876, 13806336, -14337485, -15794431, -24004620, 10940928, 8669718, 2742393, -26033313, -6875003 }, - { -1580388, -11729417, -25979658, -11445023, -17411874, -10912854, 9291594, -16247779, -12154742, 6048605 }, - { -30305315, 14843444, 1539301, 11864366, 20201677, 1900163, 13934231, 5128323, 11213262, 9168384 }, - }, - { - { -26280513, 11007847, 19408960, -940758, -18592965, -4328580, -5088060, -11105150, 20470157, -16398701 }, - { -23136053, 9282192, 14855179, -15390078, -7362815, -14408560, -22783952, 14461608, 14042978, 5230683 }, - { 29969567, -2741594, -16711867, -8552442, 9175486, -2468974, 21556951, 3506042, -5933891, -12449708 }, - }, - { - { -3144746, 8744661, 19704003, 4581278, -20430686, 6830683, -21284170, 8971513, -28539189, 15326563 }, - { -19464629, 10110288, -17262528, -3503892, -23500387, 1355669, -15523050, 15300988, -20514118, 9168260 }, - { -5353335, 4488613, -23803248, 16314347, 7780487, -15638939, -28948358, 9601605, 33087103, -9011387 }, - }, - { - { -19443170, -15512900, -20797467, -12445323, -29824447, 10229461, -27444329, -15000531, -5996870, 15664672 }, - { 23294591, -16632613, -22650781, -8470978, 27844204, 11461195, 13099750, -2460356, 18151676, 13417686 }, - { -24722913, -4176517, -31150679, 5988919, -26858785, 6685065, 1661597, -12551441, 15271676, -15452665 }, - }, - }, - { - { - { 11433042, -13228665, 8239631, -5279517, -1985436, -725718, -18698764, 2167544, -6921301, -13440182 }, - { -31436171, 15575146, 30436815, 12192228, -22463353, 9395379, -9917708, -8638997, 12215110, 12028277 }, - { 14098400, 6555944, 23007258, 5757252, -15427832, -12950502, 30123440, 4617780, -16900089, -655628 }, - }, - { - { -4026201, -15240835, 11893168, 13718664, -14809462, 1847385, -15819999, 10154009, 23973261, -12684474 }, - { -26531820, -3695990, -1908898, 2534301, -31870557, -16550355, 18341390, -11419951, 32013174, -10103539 }, - { -25479301, 10876443, -11771086, -14625140, -12369567, 1838104, 21911214, 6354752, 4425632, -837822 }, - }, - { - { -10433389, -14612966, 22229858, -3091047, -13191166, 776729, -17415375, -12020462, 4725005, 14044970 }, - { 19268650, -7304421, 1555349, 8692754, -21474059, -9910664, 6347390, -1411784, -19522291, -16109756 }, - { -24864089, 12986008, -10898878, -5558584, -11312371, -148526, 19541418, 8180106, 9282262, 10282508 }, - }, - { - { -26205082, 4428547, -8661196, -13194263, 4098402, -14165257, 15522535, 8372215, 5542595, -10702683 }, - { -10562541, 14895633, 26814552, -16673850, -17480754, -2489360, -2781891, 6993761, -18093885, 10114655 }, - { -20107055, -929418, 31422704, 10427861, -7110749, 6150669, -29091755, -11529146, 25953725, -106158 }, - }, - { - { -4234397, -8039292, -9119125, 3046000, 2101609, -12607294, 19390020, 6094296, -3315279, 12831125 }, - { -15998678, 7578152, 5310217, 14408357, -33548620, -224739, 31575954, 6326196, 7381791, -2421839 }, - { -20902779, 3296811, 24736065, -16328389, 18374254, 7318640, 6295303, 8082724, -15362489, 12339664 }, - }, - { - { 27724736, 2291157, 6088201, -14184798, 1792727, 5857634, 13848414, 15768922, 25091167, 14856294 }, - { -18866652, 8331043, 24373479, 8541013, -701998, -9269457, 12927300, -12695493, -22182473, -9012899 }, - { -11423429, -5421590, 11632845, 3405020, 30536730, -11674039, -27260765, 13866390, 30146206, 9142070 }, - }, - { - { 3924129, -15307516, -13817122, -10054960, 12291820, -668366, -27702774, 9326384, -8237858, 4171294 }, - { -15921940, 16037937, 6713787, 16606682, -21612135, 2790944, 26396185, 3731949, 345228, -5462949 }, - { -21327538, 13448259, 25284571, 1143661, 20614966, -8849387, 2031539, -12391231, -16253183, -13582083 }, - }, - { - { 31016211, -16722429, 26371392, -14451233, -5027349, 14854137, 17477601, 3842657, 28012650, -16405420 }, - { -5075835, 9368966, -8562079, -4600902, -15249953, 6970560, -9189873, 16292057, -8867157, 3507940 }, - { 29439664, 3537914, 23333589, 6997794, -17555561, -11018068, -15209202, -15051267, -9164929, 6580396 }, - }, - }, - { - { - { -12185861, -7679788, 16438269, 10826160, -8696817, -6235611, 17860444, -9273846, -2095802, 9304567 }, - { 20714564, -4336911, 29088195, 7406487, 11426967, -5095705, 14792667, -14608617, 5289421, -477127 }, - { -16665533, -10650790, -6160345, -13305760, 9192020, -1802462, 17271490, 12349094, 26939669, -3752294 }, - }, - { - { -12889898, 9373458, 31595848, 16374215, 21471720, 13221525, -27283495, -12348559, -3698806, 117887 }, - { 22263325, -6560050, 3984570, -11174646, -15114008, -566785, 28311253, 5358056, -23319780, 541964 }, - { 16259219, 3261970, 2309254, -15534474, -16885711, -4581916, 24134070, -16705829, -13337066, -13552195 }, - }, - { - { 9378160, -13140186, -22845982, -12745264, 28198281, -7244098, -2399684, -717351, 690426, 14876244 }, - { 24977353, -314384, -8223969, -13465086, 28432343, -1176353, -13068804, -12297348, -22380984, 6618999 }, - { -1538174, 11685646, 12944378, 13682314, -24389511, -14413193, 8044829, -13817328, 32239829, -5652762 }, - }, - { - { -18603066, 4762990, -926250, 8885304, -28412480, -3187315, 9781647, -10350059, 32779359, 5095274 }, - { -33008130, -5214506, -32264887, -3685216, 9460461, -9327423, -24601656, 14506724, 21639561, -2630236 }, - { -16400943, -13112215, 25239338, 15531969, 3987758, -4499318, -1289502, -6863535, 17874574, 558605 }, - }, - { - { -13600129, 10240081, 9171883, 16131053, -20869254, 9599700, 33499487, 5080151, 2085892, 5119761 }, - { -22205145, -2519528, -16381601, 414691, -25019550, 2170430, 30634760, -8363614, -31999993, -5759884 }, - { -6845704, 15791202, 8550074, -1312654, 29928809, -12092256, 27534430, -7192145, -22351378, 12961482 }, - }, - { - { -24492060, -9570771, 10368194, 11582341, -23397293, -2245287, 16533930, 8206996, -30194652, -5159638 }, - { -11121496, -3382234, 2307366, 6362031, -135455, 8868177, -16835630, 7031275, 7589640, 8945490 }, - { -32152748, 8917967, 6661220, -11677616, -1192060, -15793393, 7251489, -11182180, 24099109, -14456170 }, - }, - { - { 5019558, -7907470, 4244127, -14714356, -26933272, 6453165, -19118182, -13289025, -6231896, -10280736 }, - { 10853594, 10721687, 26480089, 5861829, -22995819, 1972175, -1866647, -10557898, -3363451, -6441124 }, - { -17002408, 5906790, 221599, -6563147, 7828208, -13248918, 24362661, -2008168, -13866408, 7421392 }, - }, - { - { 8139927, -6546497, 32257646, -5890546, 30375719, 1886181, -21175108, 15441252, 28826358, -4123029 }, - { 6267086, 9695052, 7709135, -16603597, -32869068, -1886135, 14795160, -7840124, 13746021, -1742048 }, - { 28584902, 7787108, -6732942, -15050729, 22846041, -7571236, -3181936, -363524, 4771362, -8419958 }, - }, - }, - { - { - { 24949256, 6376279, -27466481, -8174608, -18646154, -9930606, 33543569, -12141695, 3569627, 11342593 }, - { 26514989, 4740088, 27912651, 3697550, 19331575, -11472339, 6809886, 4608608, 7325975, -14801071 }, - { -11618399, -14554430, -24321212, 7655128, -1369274, 5214312, -27400540, 10258390, -17646694, -8186692 }, - }, - { - { 11431204, 15823007, 26570245, 14329124, 18029990, 4796082, -31446179, 15580664, 9280358, -3973687 }, - { -160783, -10326257, -22855316, -4304997, -20861367, -13621002, -32810901, -11181622, -15545091, 4387441 }, - { -20799378, 12194512, 3937617, -5805892, -27154820, 9340370, -24513992, 8548137, 20617071, -7482001 }, - }, - { - { -938825, -3930586, -8714311, 16124718, 24603125, -6225393, -13775352, -11875822, 24345683, 10325460 }, - { -19855277, -1568885, -22202708, 8714034, 14007766, 6928528, 16318175, -1010689, 4766743, 3552007 }, - { -21751364, -16730916, 1351763, -803421, -4009670, 3950935, 3217514, 14481909, 10988822, -3994762 }, - }, - { - { 15564307, -14311570, 3101243, 5684148, 30446780, -8051356, 12677127, -6505343, -8295852, 13296005 }, - { -9442290, 6624296, -30298964, -11913677, -4670981, -2057379, 31521204, 9614054, -30000824, 12074674 }, - { 4771191, -135239, 14290749, -13089852, 27992298, 14998318, -1413936, -1556716, 29832613, -16391035 }, - }, - { - { 7064884, -7541174, -19161962, -5067537, -18891269, -2912736, 25825242, 5293297, -27122660, 13101590 }, - { -2298563, 2439670, -7466610, 1719965, -27267541, -16328445, 32512469, -5317593, -30356070, -4190957 }, - { -30006540, 10162316, -33180176, 3981723, -16482138, -13070044, 14413974, 9515896, 19568978, 9628812 }, - }, - { - { 33053803, 199357, 15894591, 1583059, 27380243, -4580435, -17838894, -6106839, -6291786, 3437740 }, - { -18978877, 3884493, 19469877, 12726490, 15913552, 13614290, -22961733, 70104, 7463304, 4176122 }, - { -27124001, 10659917, 11482427, -16070381, 12771467, -6635117, -32719404, -5322751, 24216882, 5944158 }, - }, - { - { 8894125, 7450974, -2664149, -9765752, -28080517, -12389115, 19345746, 14680796, 11632993, 5847885 }, - { 26942781, -2315317, 9129564, -4906607, 26024105, 11769399, -11518837, 6367194, -9727230, 4782140 }, - { 19916461, -4828410, -22910704, -11414391, 25606324, -5972441, 33253853, 8220911, 6358847, -1873857 }, - }, - { - { 801428, -2081702, 16569428, 11065167, 29875704, 96627, 7908388, -4480480, -13538503, 1387155 }, - { 19646058, 5720633, -11416706, 12814209, 11607948, 12749789, 14147075, 15156355, -21866831, 11835260 }, - { 19299512, 1155910, 28703737, 14890794, 2925026, 7269399, 26121523, 15467869, -26560550, 5052483 }, - }, - }, - { - { - { -3017432, 10058206, 1980837, 3964243, 22160966, 12322533, -6431123, -12618185, 12228557, -7003677 }, - { 32944382, 14922211, -22844894, 5188528, 21913450, -8719943, 4001465, 13238564, -6114803, 8653815 }, - { 22865569, -4652735, 27603668, -12545395, 14348958, 8234005, 24808405, 5719875, 28483275, 2841751 }, - }, - { - { -16420968, -1113305, -327719, -12107856, 21886282, -15552774, -1887966, -315658, 19932058, -12739203 }, - { -11656086, 10087521, -8864888, -5536143, -19278573, -3055912, 3999228, 13239134, -4777469, -13910208 }, - { 1382174, -11694719, 17266790, 9194690, -13324356, 9720081, 20403944, 11284705, -14013818, 3093230 }, - }, - { - { 16650921, -11037932, -1064178, 1570629, -8329746, 7352753, -302424, 16271225, -24049421, -6691850 }, - { -21911077, -5927941, -4611316, -5560156, -31744103, -10785293, 24123614, 15193618, -21652117, -16739389 }, - { -9935934, -4289447, -25279823, 4372842, 2087473, 10399484, 31870908, 14690798, 17361620, 11864968 }, - }, - { - { -11307610, 6210372, 13206574, 5806320, -29017692, -13967200, -12331205, -7486601, -25578460, -16240689 }, - { 14668462, -12270235, 26039039, 15305210, 25515617, 4542480, 10453892, 6577524, 9145645, -6443880 }, - { 5974874, 3053895, -9433049, -10385191, -31865124, 3225009, -7972642, 3936128, -5652273, -3050304 }, - }, - { - { 30625386, -4729400, -25555961, -12792866, -20484575, 7695099, 17097188, -16303496, -27999779, 1803632 }, - { -3553091, 9865099, -5228566, 4272701, -5673832, -16689700, 14911344, 12196514, -21405489, 7047412 }, - { 20093277, 9920966, -11138194, -5343857, 13161587, 12044805, -32856851, 4124601, -32343828, -10257566 }, - }, - { - { -20788824, 14084654, -13531713, 7842147, 19119038, -13822605, 4752377, -8714640, -21679658, 2288038 }, - { -26819236, -3283715, 29965059, 3039786, -14473765, 2540457, 29457502, 14625692, -24819617, 12570232 }, - { -1063558, -11551823, 16920318, 12494842, 1278292, -5869109, -21159943, -3498680, -11974704, 4724943 }, - }, - { - { 17960970, -11775534, -4140968, -9702530, -8876562, -1410617, -12907383, -8659932, -29576300, 1903856 }, - { 23134274, -14279132, -10681997, -1611936, 20684485, 15770816, -12989750, 3190296, 26955097, 14109738 }, - { 15308788, 5320727, -30113809, -14318877, 22902008, 7767164, 29425325, -11277562, 31960942, 11934971 }, - }, - { - { -27395711, 8435796, 4109644, 12222639, -24627868, 14818669, 20638173, 4875028, 10491392, 1379718 }, - { -13159415, 9197841, 3875503, -8936108, -1383712, -5879801, 33518459, 16176658, 21432314, 12180697 }, - { -11787308, 11500838, 13787581, -13832590, -22430679, 10140205, 1465425, 12689540, -10301319, -13872883 }, - }, - }, - { - { - { 5414091, -15386041, -21007664, 9643570, 12834970, 1186149, -2622916, -1342231, 26128231, 6032912 }, - { -26337395, -13766162, 32496025, -13653919, 17847801, -12669156, 3604025, 8316894, -25875034, -10437358 }, - { 3296484, 6223048, 24680646, -12246460, -23052020, 5903205, -8862297, -4639164, 12376617, 3188849 }, - }, - { - { 29190488, -14659046, 27549113, -1183516, 3520066, -10697301, 32049515, -7309113, -16109234, -9852307 }, - { -14744486, -9309156, 735818, -598978, -20407687, -5057904, 25246078, -15795669, 18640741, -960977 }, - { -6928835, -16430795, 10361374, 5642961, 4910474, 12345252, -31638386, -494430, 10530747, 1053335 }, - }, - { - { -29265967, -14186805, -13538216, -12117373, -19457059, -10655384, -31462369, -2948985, 24018831, 15026644 }, - { -22592535, -3145277, -2289276, 5953843, -13440189, 9425631, 25310643, 13003497, -2314791, -15145616 }, - { -27419985, -603321, -8043984, -1669117, -26092265, 13987819, -27297622, 187899, -23166419, -2531735 }, - }, - { - { -21744398, -13810475, 1844840, 5021428, -10434399, -15911473, 9716667, 16266922, -5070217, 726099 }, - { 29370922, -6053998, 7334071, -15342259, 9385287, 2247707, -13661962, -4839461, 30007388, -15823341 }, - { -936379, 16086691, 23751945, -543318, -1167538, -5189036, 9137109, 730663, 9835848, 4555336 }, - }, - { - { -23376435, 1410446, -22253753, -12899614, 30867635, 15826977, 17693930, 544696, -11985298, 12422646 }, - { 31117226, -12215734, -13502838, 6561947, -9876867, -12757670, -5118685, -4096706, 29120153, 13924425 }, - { -17400879, -14233209, 19675799, -2734756, -11006962, -5858820, -9383939, -11317700, 7240931, -237388 }, - }, - { - { -31361739, -11346780, -15007447, -5856218, -22453340, -12152771, 1222336, 4389483, 3293637, -15551743 }, - { -16684801, -14444245, 11038544, 11054958, -13801175, -3338533, -24319580, 7733547, 12796905, -6335822 }, - { -8759414, -10817836, -25418864, 10783769, -30615557, -9746811, -28253339, 3647836, 3222231, -11160462 }, - }, - { - { 18606113, 1693100, -25448386, -15170272, 4112353, 10045021, 23603893, -2048234, -7550776, 2484985 }, - { 9255317, -3131197, -12156162, -1004256, 13098013, -9214866, 16377220, -2102812, -19802075, -3034702 }, - { -22729289, 7496160, -5742199, 11329249, 19991973, -3347502, -31718148, 9936966, -30097688, -10618797 }, - }, - { - { 21878590, -5001297, 4338336, 13643897, -3036865, 13160960, 19708896, 5415497, -7360503, -4109293 }, - { 27736861, 10103576, 12500508, 8502413, -3413016, -9633558, 10436918, -1550276, -23659143, -8132100 }, - { 19492550, -12104365, -29681976, -852630, -3208171, 12403437, 30066266, 8367329, 13243957, 8709688 }, - }, - }, - { - { - { 12015105, 2801261, 28198131, 10151021, 24818120, -4743133, -11194191, -5645734, 5150968, 7274186 }, - { 2831366, -12492146, 1478975, 6122054, 23825128, -12733586, 31097299, 6083058, 31021603, -9793610 }, - { -2529932, -2229646, 445613, 10720828, -13849527, -11505937, -23507731, 16354465, 15067285, -14147707 }, - }, - { - { 7840942, 14037873, -33364863, 15934016, -728213, -3642706, 21403988, 1057586, -19379462, -12403220 }, - { 915865, -16469274, 15608285, -8789130, -24357026, 6060030, -17371319, 8410997, -7220461, 16527025 }, - { 32922597, -556987, 20336074, -16184568, 10903705, -5384487, 16957574, 52992, 23834301, 6588044 }, - }, - { - { 32752030, 11232950, 3381995, -8714866, 22652988, -10744103, 17159699, 16689107, -20314580, -1305992 }, - { -4689649, 9166776, -25710296, -10847306, 11576752, 12733943, 7924251, -2752281, 1976123, -7249027 }, - { 21251222, 16309901, -2983015, -6783122, 30810597, 12967303, 156041, -3371252, 12331345, -8237197 }, - }, - { - { 8651614, -4477032, -16085636, -4996994, 13002507, 2950805, 29054427, -5106970, 10008136, -4667901 }, - { 31486080, 15114593, -14261250, 12951354, 14369431, -7387845, 16347321, -13662089, 8684155, -10532952 }, - { 19443825, 11385320, 24468943, -9659068, -23919258, 2187569, -26263207, -6086921, 31316348, 14219878 }, - }, - { - { -28594490, 1193785, 32245219, 11392485, 31092169, 15722801, 27146014, 6992409, 29126555, 9207390 }, - { 32382935, 1110093, 18477781, 11028262, -27411763, -7548111, -4980517, 10843782, -7957600, -14435730 }, - { 2814918, 7836403, 27519878, -7868156, -20894015, -11553689, -21494559, 8550130, 28346258, 1994730 }, - }, - { - { -19578299, 8085545, -14000519, -3948622, 2785838, -16231307, -19516951, 7174894, 22628102, 8115180 }, - { -30405132, 955511, -11133838, -15078069, -32447087, -13278079, -25651578, 3317160, -9943017, 930272 }, - { -15303681, -6833769, 28856490, 1357446, 23421993, 1057177, 24091212, -1388970, -22765376, -10650715 }, - }, - { - { -22751231, -5303997, -12907607, -12768866, -15811511, -7797053, -14839018, -16554220, -1867018, 8398970 }, - { -31969310, 2106403, -4736360, 1362501, 12813763, 16200670, 22981545, -6291273, 18009408, -15772772 }, - { -17220923, -9545221, -27784654, 14166835, 29815394, 7444469, 29551787, -3727419, 19288549, 1325865 }, - }, - { - { 15100157, -15835752, -23923978, -1005098, -26450192, 15509408, 12376730, -3479146, 33166107, -8042750 }, - { 20909231, 13023121, -9209752, 16251778, -5778415, -8094914, 12412151, 10018715, 2213263, -13878373 }, - { 32529814, -11074689, 30361439, -16689753, -9135940, 1513226, 22922121, 6382134, -5766928, 8371348 }, - }, - }, - { - { - { 9923462, 11271500, 12616794, 3544722, -29998368, -1721626, 12891687, -8193132, -26442943, 10486144 }, - { -22597207, -7012665, 8587003, -8257861, 4084309, -12970062, 361726, 2610596, -23921530, -11455195 }, - { 5408411, -1136691, -4969122, 10561668, 24145918, 14240566, 31319731, -4235541, 19985175, -3436086 }, - }, - { - { -13994457, 16616821, 14549246, 3341099, 32155958, 13648976, -17577068, 8849297, 65030, 8370684 }, - { -8320926, -12049626, 31204563, 5839400, -20627288, -1057277, -19442942, 6922164, 12743482, -9800518 }, - { -2361371, 12678785, 28815050, 4759974, -23893047, 4884717, 23783145, 11038569, 18800704, 255233 }, - }, - { - { -5269658, -1773886, 13957886, 7990715, 23132995, 728773, 13393847, 9066957, 19258688, -14753793 }, - { -2936654, -10827535, -10432089, 14516793, -3640786, 4372541, -31934921, 2209390, -1524053, 2055794 }, - { 580882, 16705327, 5468415, -2683018, -30926419, -14696000, -7203346, -8994389, -30021019, 7394435 }, - }, - { - { 23838809, 1822728, -15738443, 15242727, 8318092, -3733104, -21672180, -3492205, -4821741, 14799921 }, - { 13345610, 9759151, 3371034, -16137791, 16353039, 8577942, 31129804, 13496856, -9056018, 7402518 }, - { 2286874, -4435931, -20042458, -2008336, -13696227, 5038122, 11006906, -15760352, 8205061, 1607563 }, - }, - { - { 14414086, -8002132, 3331830, -3208217, 22249151, -5594188, 18364661, -2906958, 30019587, -9029278 }, - { -27688051, 1585953, -10775053, 931069, -29120221, -11002319, -14410829, 12029093, 9944378, 8024 }, - { 4368715, -3709630, 29874200, -15022983, -20230386, -11410704, -16114594, -999085, -8142388, 5640030 }, - }, - { - { 10299610, 13746483, 11661824, 16234854, 7630238, 5998374, 9809887, -16694564, 15219798, -14327783 }, - { 27425505, -5719081, 3055006, 10660664, 23458024, 595578, -15398605, -1173195, -18342183, 9742717 }, - { 6744077, 2427284, 26042789, 2720740, -847906, 1118974, 32324614, 7406442, 12420155, 1994844 }, - }, - { - { 14012521, -5024720, -18384453, -9578469, -26485342, -3936439, -13033478, -10909803, 24319929, -6446333 }, - { 16412690, -4507367, 10772641, 15929391, -17068788, -4658621, 10555945, -10484049, -30102368, -4739048 }, - { 22397382, -7767684, -9293161, -12792868, 17166287, -9755136, -27333065, 6199366, 21880021, -12250760 }, - }, - { - { -4283307, 5368523, -31117018, 8163389, -30323063, 3209128, 16557151, 8890729, 8840445, 4957760 }, - { -15447727, 709327, -6919446, -10870178, -29777922, 6522332, -21720181, 12130072, -14796503, 5005757 }, - { -2114751, -14308128, 23019042, 15765735, -25269683, 6002752, 10183197, -13239326, -16395286, -2176112 }, - }, - }, - { - { - { -19025756, 1632005, 13466291, -7995100, -23640451, 16573537, -32013908, -3057104, 22208662, 2000468 }, - { 3065073, -1412761, -25598674, -361432, -17683065, -5703415, -8164212, 11248527, -3691214, -7414184 }, - { 10379208, -6045554, 8877319, 1473647, -29291284, -12507580, 16690915, 2553332, -3132688, 16400289 }, - }, - { - { 15716668, 1254266, -18472690, 7446274, -8448918, 6344164, -22097271, -7285580, 26894937, 9132066 }, - { 24158887, 12938817, 11085297, -8177598, -28063478, -4457083, -30576463, 64452, -6817084, -2692882 }, - { 13488534, 7794716, 22236231, 5989356, 25426474, -12578208, 2350710, -3418511, -4688006, 2364226 }, - }, - { - { 16335052, 9132434, 25640582, 6678888, 1725628, 8517937, -11807024, -11697457, 15445875, -7798101 }, - { 29004207, -7867081, 28661402, -640412, -12794003, -7943086, 31863255, -4135540, -278050, -15759279 }, - { -6122061, -14866665, -28614905, 14569919, -10857999, -3591829, 10343412, -6976290, -29828287, -10815811 }, - }, - { - { 27081650, 3463984, 14099042, -4517604, 1616303, -6205604, 29542636, 15372179, 17293797, 960709 }, - { 20263915, 11434237, -5765435, 11236810, 13505955, -10857102, -16111345, 6493122, -19384511, 7639714 }, - { -2830798, -14839232, 25403038, -8215196, -8317012, -16173699, 18006287, -16043750, 29994677, -15808121 }, - }, - { - { 9769828, 5202651, -24157398, -13631392, -28051003, -11561624, -24613141, -13860782, -31184575, 709464 }, - { 12286395, 13076066, -21775189, -1176622, -25003198, 4057652, -32018128, -8890874, 16102007, 13205847 }, - { 13733362, 5599946, 10557076, 3195751, -5557991, 8536970, -25540170, 8525972, 10151379, 10394400 }, - }, - { - { 4024660, -16137551, 22436262, 12276534, -9099015, -2686099, 19698229, 11743039, -33302334, 8934414 }, - { -15879800, -4525240, -8580747, -2934061, 14634845, -698278, -9449077, 3137094, -11536886, 11721158 }, - { 17555939, -5013938, 8268606, 2331751, -22738815, 9761013, 9319229, 8835153, -9205489, -1280045 }, - }, - { - { -461409, -7830014, 20614118, 16688288, -7514766, -4807119, 22300304, 505429, 6108462, -6183415 }, - { -5070281, 12367917, -30663534, 3234473, 32617080, -8422642, 29880583, -13483331, -26898490, -7867459 }, - { -31975283, 5726539, 26934134, 10237677, -3173717, -605053, 24199304, 3795095, 7592688, -14992079 }, - }, - { - { 21594432, -14964228, 17466408, -4077222, 32537084, 2739898, 6407723, 12018833, -28256052, 4298412 }, - { -20650503, -11961496, -27236275, 570498, 3767144, -1717540, 13891942, -1569194, 13717174, 10805743 }, - { -14676630, -15644296, 15287174, 11927123, 24177847, -8175568, -796431, 14860609, -26938930, -5863836 }, - }, - }, - { - { - { 12962541, 5311799, -10060768, 11658280, 18855286, -7954201, 13286263, -12808704, -4381056, 9882022 }, - { 18512079, 11319350, -20123124, 15090309, 18818594, 5271736, -22727904, 3666879, -23967430, -3299429 }, - { -6789020, -3146043, 16192429, 13241070, 15898607, -14206114, -10084880, -6661110, -2403099, 5276065 }, - }, - { - { 30169808, -5317648, 26306206, -11750859, 27814964, 7069267, 7152851, 3684982, 1449224, 13082861 }, - { 10342826, 3098505, 2119311, 193222, 25702612, 12233820, 23697382, 15056736, -21016438, -8202000 }, - { -33150110, 3261608, 22745853, 7948688, 19370557, -15177665, -26171976, 6482814, -10300080, -11060101 }, - }, - { - { 32869458, -5408545, 25609743, 15678670, -10687769, -15471071, 26112421, 2521008, -22664288, 6904815 }, - { 29506923, 4457497, 3377935, -9796444, -30510046, 12935080, 1561737, 3841096, -29003639, -6657642 }, - { 10340844, -6630377, -18656632, -2278430, 12621151, -13339055, 30878497, -11824370, -25584551, 5181966 }, - }, - { - { 25940115, -12658025, 17324188, -10307374, -8671468, 15029094, 24396252, -16450922, -2322852, -12388574 }, - { -21765684, 9916823, -1300409, 4079498, -1028346, 11909559, 1782390, 12641087, 20603771, -6561742 }, - { -18882287, -11673380, 24849422, 11501709, 13161720, -4768874, 1925523, 11914390, 4662781, 7820689 }, - }, - { - { 12241050, -425982, 8132691, 9393934, 32846760, -1599620, 29749456, 12172924, 16136752, 15264020 }, - { -10349955, -14680563, -8211979, 2330220, -17662549, -14545780, 10658213, 6671822, 19012087, 3772772 }, - { 3753511, -3421066, 10617074, 2028709, 14841030, -6721664, 28718732, -15762884, 20527771, 12988982 }, - }, - { - { -14822485, -5797269, -3707987, 12689773, -898983, -10914866, -24183046, -10564943, 3299665, -12424953 }, - { -16777703, -15253301, -9642417, 4978983, 3308785, 8755439, 6943197, 6461331, -25583147, 8991218 }, - { -17226263, 1816362, -1673288, -6086439, 31783888, -8175991, -32948145, 7417950, -30242287, 1507265 }, - }, - { - { 29692663, 6829891, -10498800, 4334896, 20945975, -11906496, -28887608, 8209391, 14606362, -10647073 }, - { -3481570, 8707081, 32188102, 5672294, 22096700, 1711240, -33020695, 9761487, 4170404, -2085325 }, - { -11587470, 14855945, -4127778, -1531857, -26649089, 15084046, 22186522, 16002000, -14276837, -8400798 }, - }, - { - { -4811456, 13761029, -31703877, -2483919, -3312471, 7869047, -7113572, -9620092, 13240845, 10965870 }, - { -7742563, -8256762, -14768334, -13656260, -23232383, 12387166, 4498947, 14147411, 29514390, 4302863 }, - { -13413405, -12407859, 20757302, -13801832, 14785143, 8976368, -5061276, -2144373, 17846988, -13971927 }, - }, - }, - { - { - { -2244452, -754728, -4597030, -1066309, -6247172, 1455299, -21647728, -9214789, -5222701, 12650267 }, - { -9906797, -16070310, 21134160, 12198166, -27064575, 708126, 387813, 13770293, -19134326, 10958663 }, - { 22470984, 12369526, 23446014, -5441109, -21520802, -9698723, -11772496, -11574455, -25083830, 4271862 }, - }, - { - { -25169565, -10053642, -19909332, 15361595, -5984358, 2159192, 75375, -4278529, -32526221, 8469673 }, - { 15854970, 4148314, -8893890, 7259002, 11666551, 13824734, -30531198, 2697372, 24154791, -9460943 }, - { 15446137, -15806644, 29759747, 14019369, 30811221, -9610191, -31582008, 12840104, 24913809, 9815020 }, - }, - { - { -4709286, -5614269, -31841498, -12288893, -14443537, 10799414, -9103676, 13438769, 18735128, 9466238 }, - { 11933045, 9281483, 5081055, -5183824, -2628162, -4905629, -7727821, -10896103, -22728655, 16199064 }, - { 14576810, 379472, -26786533, -8317236, -29426508, -10812974, -102766, 1876699, 30801119, 2164795 }, - }, - { - { 15995086, 3199873, 13672555, 13712240, -19378835, -4647646, -13081610, -15496269, -13492807, 1268052 }, - { -10290614, -3659039, -3286592, 10948818, 23037027, 3794475, -3470338, -12600221, -17055369, 3565904 }, - { 29210088, -9419337, -5919792, -4952785, 10834811, -13327726, -16512102, -10820713, -27162222, -14030531 }, - }, - { - { -13161890, 15508588, 16663704, -8156150, -28349942, 9019123, -29183421, -3769423, 2244111, -14001979 }, - { -5152875, -3800936, -9306475, -6071583, 16243069, 14684434, -25673088, -16180800, 13491506, 4641841 }, - { 10813417, 643330, -19188515, -728916, 30292062, -16600078, 27548447, -7721242, 14476989, -12767431 }, - }, - { - { 10292079, 9984945, 6481436, 8279905, -7251514, 7032743, 27282937, -1644259, -27912810, 12651324 }, - { -31185513, -813383, 22271204, 11835308, 10201545, 15351028, 17099662, 3988035, 21721536, -3148940 }, - { 10202177, -6545839, -31373232, -9574638, -32150642, -8119683, -12906320, 3852694, 13216206, 14842320 }, - }, - { - { -15815640, -10601066, -6538952, -7258995, -6984659, -6581778, -31500847, 13765824, -27434397, 9900184 }, - { 14465505, -13833331, -32133984, -14738873, -27443187, 12990492, 33046193, 15796406, -7051866, -8040114 }, - { 30924417, -8279620, 6359016, -12816335, 16508377, 9071735, -25488601, 15413635, 9524356, -7018878 }, - }, - { - { 12274201, -13175547, 32627641, -1785326, 6736625, 13267305, 5237659, -5109483, 15663516, 4035784 }, - { -2951309, 8903985, 17349946, 601635, -16432815, -4612556, -13732739, -15889334, -22258478, 4659091 }, - { -16916263, -4952973, -30393711, -15158821, 20774812, 15897498, 5736189, 15026997, -2178256, -13455585 }, - }, - }, - { - { - { -8858980, -2219056, 28571666, -10155518, -474467, -10105698, -3801496, 278095, 23440562, -290208 }, - { 10226241, -5928702, 15139956, 120818, -14867693, 5218603, 32937275, 11551483, -16571960, -7442864 }, - { 17932739, -12437276, -24039557, 10749060, 11316803, 7535897, 22503767, 5561594, -3646624, 3898661 }, - }, - { - { 7749907, -969567, -16339731, -16464, -25018111, 15122143, -1573531, 7152530, 21831162, 1245233 }, - { 26958459, -14658026, 4314586, 8346991, -5677764, 11960072, -32589295, -620035, -30402091, -16716212 }, - { -12165896, 9166947, 33491384, 13673479, 29787085, 13096535, 6280834, 14587357, -22338025, 13987525 }, - }, - { - { -24349909, 7778775, 21116000, 15572597, -4833266, -5357778, -4300898, -5124639, -7469781, -2858068 }, - { 9681908, -6737123, -31951644, 13591838, -6883821, 386950, 31622781, 6439245, -14581012, 4091397 }, - { -8426427, 1470727, -28109679, -1596990, 3978627, -5123623, -19622683, 12092163, 29077877, -14741988 }, - }, - { - { 5269168, -6859726, -13230211, -8020715, 25932563, 1763552, -5606110, -5505881, -20017847, 2357889 }, - { 32264008, -15407652, -5387735, -1160093, -2091322, -3946900, 23104804, -12869908, 5727338, 189038 }, - { 14609123, -8954470, -6000566, -16622781, -14577387, -7743898, -26745169, 10942115, -25888931, -14884697 }, - }, - { - { 20513500, 5557931, -15604613, 7829531, 26413943, -2019404, -21378968, 7471781, 13913677, -5137875 }, - { -25574376, 11967826, 29233242, 12948236, -6754465, 4713227, -8940970, 14059180, 12878652, 8511905 }, - { -25656801, 3393631, -2955415, -7075526, -2250709, 9366908, -30223418, 6812974, 5568676, -3127656 }, - }, - { - { 11630004, 12144454, 2116339, 13606037, 27378885, 15676917, -17408753, -13504373, -14395196, 8070818 }, - { 27117696, -10007378, -31282771, -5570088, 1127282, 12772488, -29845906, 10483306, -11552749, -1028714 }, - { 10637467, -5688064, 5674781, 1072708, -26343588, -6982302, -1683975, 9177853, -27493162, 15431203 }, - }, - { - { 20525145, 10892566, -12742472, 12779443, -29493034, 16150075, -28240519, 14943142, -15056790, -7935931 }, - { -30024462, 5626926, -551567, -9981087, 753598, 11981191, 25244767, -3239766, -3356550, 9594024 }, - { -23752644, 2636870, -5163910, -10103818, 585134, 7877383, 11345683, -6492290, 13352335, -10977084 }, - }, - { - { -1931799, -5407458, 3304649, -12884869, 17015806, -4877091, -29783850, -7752482, -13215537, -319204 }, - { 20239939, 6607058, 6203985, 3483793, -18386976, -779229, -20723742, 15077870, -22750759, 14523817 }, - { 27406042, -6041657, 27423596, -4497394, 4996214, 10002360, -28842031, -4545494, -30172742, -4805667 }, - }, - }, - { - { - { 11374242, 12660715, 17861383, -12540833, 10935568, 1099227, -13886076, -9091740, -27727044, 11358504 }, - { -12730809, 10311867, 1510375, 10778093, -2119455, -9145702, 32676003, 11149336, -26123651, 4985768 }, - { -19096303, 341147, -6197485, -239033, 15756973, -8796662, -983043, 13794114, -19414307, -15621255 }, - }, - { - { 6490081, 11940286, 25495923, -7726360, 8668373, -8751316, 3367603, 6970005, -1691065, -9004790 }, - { 1656497, 13457317, 15370807, 6364910, 13605745, 8362338, -19174622, -5475723, -16796596, -5031438 }, - { -22273315, -13524424, -64685, -4334223, -18605636, -10921968, -20571065, -7007978, -99853, -10237333 }, - }, - { - { 17747465, 10039260, 19368299, -4050591, -20630635, -16041286, 31992683, -15857976, -29260363, -5511971 }, - { 31932027, -4986141, -19612382, 16366580, 22023614, 88450, 11371999, -3744247, 4882242, -10626905 }, - { 29796507, 37186, 19818052, 10115756, -11829032, 3352736, 18551198, 3272828, -5190932, -4162409 }, - }, - { - { 12501286, 4044383, -8612957, -13392385, -32430052, 5136599, -19230378, -3529697, 330070, -3659409 }, - { 6384877, 2899513, 17807477, 7663917, -2358888, 12363165, 25366522, -8573892, -271295, 12071499 }, - { -8365515, -4042521, 25133448, -4517355, -6211027, 2265927, -32769618, 1936675, -5159697, 3829363 }, - }, - { - { 28425966, -5835433, -577090, -4697198, -14217555, 6870930, 7921550, -6567787, 26333140, 14267664 }, - { -11067219, 11871231, 27385719, -10559544, -4585914, -11189312, 10004786, -8709488, -21761224, 8930324 }, - { -21197785, -16396035, 25654216, -1725397, 12282012, 11008919, 1541940, 4757911, -26491501, -16408940 }, - }, - { - { 13537262, -7759490, -20604840, 10961927, -5922820, -13218065, -13156584, 6217254, -15943699, 13814990 }, - { -17422573, 15157790, 18705543, 29619, 24409717, -260476, 27361681, 9257833, -1956526, -1776914 }, - { -25045300, -10191966, 15366585, 15166509, -13105086, 8423556, -29171540, 12361135, -18685978, 4578290 }, - }, - { - { 24579768, 3711570, 1342322, -11180126, -27005135, 14124956, -22544529, 14074919, 21964432, 8235257 }, - { -6528613, -2411497, 9442966, -5925588, 12025640, -1487420, -2981514, -1669206, 13006806, 2355433 }, - { -16304899, -13605259, -6632427, -5142349, 16974359, -10911083, 27202044, 1719366, 1141648, -12796236 }, - }, - { - { -12863944, -13219986, -8318266, -11018091, -6810145, -4843894, 13475066, -3133972, 32674895, 13715045 }, - { 11423335, -5468059, 32344216, 8962751, 24989809, 9241752, -13265253, 16086212, -28740881, -15642093 }, - { -1409668, 12530728, -6368726, 10847387, 19531186, -14132160, -11709148, 7791794, -27245943, 4383347 }, - }, - }, - { - { - { -28970898, 5271447, -1266009, -9736989, -12455236, 16732599, -4862407, -4906449, 27193557, 6245191 }, - { -15193956, 5362278, -1783893, 2695834, 4960227, 12840725, 23061898, 3260492, 22510453, 8577507 }, - { -12632451, 11257346, -32692994, 13548177, -721004, 10879011, 31168030, 13952092, -29571492, -3635906 }, - }, - { - { 3877321, -9572739, 32416692, 5405324, -11004407, -13656635, 3759769, 11935320, 5611860, 8164018 }, - { -16275802, 14667797, 15906460, 12155291, -22111149, -9039718, 32003002, -8832289, 5773085, -8422109 }, - { -23788118, -8254300, 1950875, 8937633, 18686727, 16459170, -905725, 12376320, 31632953, 190926 }, - }, - { - { -24593607, -16138885, -8423991, 13378746, 14162407, 6901328, -8288749, 4508564, -25341555, -3627528 }, - { 8884438, -5884009, 6023974, 10104341, -6881569, -4941533, 18722941, -14786005, -1672488, 827625 }, - { -32720583, -16289296, -32503547, 7101210, 13354605, 2659080, -1800575, -14108036, -24878478, 1541286 }, - }, - { - { 2901347, -1117687, 3880376, -10059388, -17620940, -3612781, -21802117, -3567481, 20456845, -1885033 }, - { 27019610, 12299467, -13658288, -1603234, -12861660, -4861471, -19540150, -5016058, 29439641, 15138866 }, - { 21536104, -6626420, -32447818, -10690208, -22408077, 5175814, -5420040, -16361163, 7779328, 109896 }, - }, - { - { 30279744, 14648750, -8044871, 6425558, 13639621, -743509, 28698390, 12180118, 23177719, -554075 }, - { 26572847, 3405927, -31701700, 12890905, -19265668, 5335866, -6493768, 2378492, 4439158, -13279347 }, - { -22716706, 3489070, -9225266, -332753, 18875722, -1140095, 14819434, -12731527, -17717757, -5461437 }, - }, - { - { -5056483, 16566551, 15953661, 3767752, -10436499, 15627060, -820954, 2177225, 8550082, -15114165 }, - { -18473302, 16596775, -381660, 15663611, 22860960, 15585581, -27844109, -3582739, -23260460, -8428588 }, - { -32480551, 15707275, -8205912, -5652081, 29464558, 2713815, -22725137, 15860482, -21902570, 1494193 }, - }, - { - { -19562091, -14087393, -25583872, -9299552, 13127842, 759709, 21923482, 16529112, 8742704, 12967017 }, - { -28464899, 1553205, 32536856, -10473729, -24691605, -406174, -8914625, -2933896, -29903758, 15553883 }, - { 21877909, 3230008, 9881174, 10539357, -4797115, 2841332, 11543572, 14513274, 19375923, -12647961 }, - }, - { - { 8832269, -14495485, 13253511, 5137575, 5037871, 4078777, 24880818, -6222716, 2862653, 9455043 }, - { 29306751, 5123106, 20245049, -14149889, 9592566, 8447059, -2077124, -2990080, 15511449, 4789663 }, - { -20679756, 7004547, 8824831, -9434977, -4045704, -3750736, -5754762, 108893, 23513200, 16652362 }, - }, - }, - { - { - { -33256173, 4144782, -4476029, -6579123, 10770039, -7155542, -6650416, -12936300, -18319198, 10212860 }, - { 2756081, 8598110, 7383731, -6859892, 22312759, -1105012, 21179801, 2600940, -9988298, -12506466 }, - { -24645692, 13317462, -30449259, -15653928, 21365574, -10869657, 11344424, 864440, -2499677, -16710063 }, - }, - { - { -26432803, 6148329, -17184412, -14474154, 18782929, -275997, -22561534, 211300, 2719757, 4940997 }, - { -1323882, 3911313, -6948744, 14759765, -30027150, 7851207, 21690126, 8518463, 26699843, 5276295 }, - { -13149873, -6429067, 9396249, 365013, 24703301, -10488939, 1321586, 149635, -15452774, 7159369 }, - }, - { - { 9987780, -3404759, 17507962, 9505530, 9731535, -2165514, 22356009, 8312176, 22477218, -8403385 }, - { 18155857, -16504990, 19744716, 9006923, 15154154, -10538976, 24256460, -4864995, -22548173, 9334109 }, - { 2986088, -4911893, 10776628, -3473844, 10620590, -7083203, -21413845, 14253545, -22587149, 536906 }, - }, - { - { 4377756, 8115836, 24567078, 15495314, 11625074, 13064599, 7390551, 10589625, 10838060, -15420424 }, - { -19342404, 867880, 9277171, -3218459, -14431572, -1986443, 19295826, -15796950, 6378260, 699185 }, - { 7895026, 4057113, -7081772, -13077756, -17886831, -323126, -716039, 15693155, -5045064, -13373962 }, - }, - { - { -7737563, -5869402, -14566319, -7406919, 11385654, 13201616, 31730678, -10962840, -3918636, -9669325 }, - { 10188286, -15770834, -7336361, 13427543, 22223443, 14896287, 30743455, 7116568, -21786507, 5427593 }, - { 696102, 13206899, 27047647, -10632082, 15285305, -9853179, 10798490, -4578720, 19236243, 12477404 }, - }, - { - { -11229439, 11243796, -17054270, -8040865, -788228, -8167967, -3897669, 11180504, -23169516, 7733644 }, - { 17800790, -14036179, -27000429, -11766671, 23887827, 3149671, 23466177, -10538171, 10322027, 15313801 }, - { 26246234, 11968874, 32263343, -5468728, 6830755, -13323031, -15794704, -101982, -24449242, 10890804 }, - }, - { - { -31365647, 10271363, -12660625, -6267268, 16690207, -13062544, -14982212, 16484931, 25180797, -5334884 }, - { -586574, 10376444, -32586414, -11286356, 19801893, 10997610, 2276632, 9482883, 316878, 13820577 }, - { -9882808, -4510367, -2115506, 16457136, -11100081, 11674996, 30756178, -7515054, 30696930, -3712849 }, - }, - { - { 32988917, -9603412, 12499366, 7910787, -10617257, -11931514, -7342816, -9985397, -32349517, 7392473 }, - { -8855661, 15927861, 9866406, -3649411, -2396914, -16655781, -30409476, -9134995, 25112947, -2926644 }, - { -2504044, -436966, 25621774, -5678772, 15085042, -5479877, -24884878, -13526194, 5537438, -13914319 }, - }, - }, - { - { - { -11225584, 2320285, -9584280, 10149187, -33444663, 5808648, -14876251, -1729667, 31234590, 6090599 }, - { -9633316, 116426, 26083934, 2897444, -6364437, -2688086, 609721, 15878753, -6970405, -9034768 }, - { -27757857, 247744, -15194774, -9002551, 23288161, -10011936, -23869595, 6503646, 20650474, 1804084 }, - }, - { - { -27589786, 15456424, 8972517, 8469608, 15640622, 4439847, 3121995, -10329713, 27842616, -202328 }, - { -15306973, 2839644, 22530074, 10026331, 4602058, 5048462, 28248656, 5031932, -11375082, 12714369 }, - { 20807691, -7270825, 29286141, 11421711, -27876523, -13868230, -21227475, 1035546, -19733229, 12796920 }, - }, - { - { 12076899, -14301286, -8785001, -11848922, -25012791, 16400684, -17591495, -12899438, 3480665, -15182815 }, - { -32361549, 5457597, 28548107, 7833186, 7303070, -11953545, -24363064, -15921875, -33374054, 2771025 }, - { -21389266, 421932, 26597266, 6860826, 22486084, -6737172, -17137485, -4210226, -24552282, 15673397 }, - }, - { - { -20184622, 2338216, 19788685, -9620956, -4001265, -8740893, -20271184, 4733254, 3727144, -12934448 }, - { 6120119, 814863, -11794402, -622716, 6812205, -15747771, 2019594, 7975683, 31123697, -10958981 }, - { 30069250, -11435332, 30434654, 2958439, 18399564, -976289, 12296869, 9204260, -16432438, 9648165 }, - }, - { - { 32705432, -1550977, 30705658, 7451065, -11805606, 9631813, 3305266, 5248604, -26008332, -11377501 }, - { 17219865, 2375039, -31570947, -5575615, -19459679, 9219903, 294711, 15298639, 2662509, -16297073 }, - { -1172927, -7558695, -4366770, -4287744, -21346413, -8434326, 32087529, -1222777, 32247248, -14389861 }, - }, - { - { 14312628, 1221556, 17395390, -8700143, -4945741, -8684635, -28197744, -9637817, -16027623, -13378845 }, - { -1428825, -9678990, -9235681, 6549687, -7383069, -468664, 23046502, 9803137, 17597934, 2346211 }, - { 18510800, 15337574, 26171504, 981392, -22241552, 7827556, -23491134, -11323352, 3059833, -11782870 }, - }, - { - { 10141598, 6082907, 17829293, -1947643, 9830092, 13613136, -25556636, -5544586, -33502212, 3592096 }, - { 33114168, -15889352, -26525686, -13343397, 33076705, 8716171, 1151462, 1521897, -982665, -6837803 }, - { -32939165, -4255815, 23947181, -324178, -33072974, -12305637, -16637686, 3891704, 26353178, 693168 }, - }, - { - { 30374239, 1595580, -16884039, 13186931, 4600344, 406904, 9585294, -400668, 31375464, 14369965 }, - { -14370654, -7772529, 1510301, 6434173, -18784789, -6262728, 32732230, -13108839, 17901441, 16011505 }, - { 18171223, -11934626, -12500402, 15197122, -11038147, -15230035, -19172240, -16046376, 8764035, 12309598 }, - }, - }, - { - { - { 5975908, -5243188, -19459362, -9681747, -11541277, 14015782, -23665757, 1228319, 17544096, -10593782 }, - { 5811932, -1715293, 3442887, -2269310, -18367348, -8359541, -18044043, -15410127, -5565381, 12348900 }, - { -31399660, 11407555, 25755363, 6891399, -3256938, 14872274, -24849353, 8141295, -10632534, -585479 }, - }, - { - { -12675304, 694026, -5076145, 13300344, 14015258, -14451394, -9698672, -11329050, 30944593, 1130208 }, - { 8247766, -6710942, -26562381, -7709309, -14401939, -14648910, 4652152, 2488540, 23550156, -271232 }, - { 17294316, -3788438, 7026748, 15626851, 22990044, 113481, 2267737, -5908146, -408818, -137719 }, - }, - { - { 16091085, -16253926, 18599252, 7340678, 2137637, -1221657, -3364161, 14550936, 3260525, -7166271 }, - { -4910104, -13332887, 18550887, 10864893, -16459325, -7291596, -23028869, -13204905, -12748722, 2701326 }, - { -8574695, 16099415, 4629974, -16340524, -20786213, -6005432, -10018363, 9276971, 11329923, 1862132 }, - }, - { - { 14763076, -15903608, -30918270, 3689867, 3511892, 10313526, -21951088, 12219231, -9037963, -940300 }, - { 8894987, -3446094, 6150753, 3013931, 301220, 15693451, -31981216, -2909717, -15438168, 11595570 }, - { 15214962, 3537601, -26238722, -14058872, 4418657, -15230761, 13947276, 10730794, -13489462, -4363670 }, - }, - { - { -2538306, 7682793, 32759013, 263109, -29984731, -7955452, -22332124, -10188635, 977108, 699994 }, - { -12466472, 4195084, -9211532, 550904, -15565337, 12917920, 19118110, -439841, -30534533, -14337913 }, - { 31788461, -14507657, 4799989, 7372237, 8808585, -14747943, 9408237, -10051775, 12493932, -5409317 }, - }, - { - { -25680606, 5260744, -19235809, -6284470, -3695942, 16566087, 27218280, 2607121, 29375955, 6024730 }, - { 842132, -2794693, -4763381, -8722815, 26332018, -12405641, 11831880, 6985184, -9940361, 2854096 }, - { -4847262, -7969331, 2516242, -5847713, 9695691, -7221186, 16512645, 960770, 12121869, 16648078 }, - }, - { - { -15218652, 14667096, -13336229, 2013717, 30598287, -464137, -31504922, -7882064, 20237806, 2838411 }, - { -19288047, 4453152, 15298546, -16178388, 22115043, -15972604, 12544294, -13470457, 1068881, -12499905 }, - { -9558883, -16518835, 33238498, 13506958, 30505848, -1114596, -8486907, -2630053, 12521378, 4845654 }, - }, - { - { -28198521, 10744108, -2958380, 10199664, 7759311, -13088600, 3409348, -873400, -6482306, -12885870 }, - { -23561822, 6230156, -20382013, 10655314, -24040585, -11621172, 10477734, -1240216, -3113227, 13974498 }, - { 12966261, 15550616, -32038948, -1615346, 21025980, -629444, 5642325, 7188737, 18895762, 12629579 }, - }, - }, - { - { - { 14741879, -14946887, 22177208, -11721237, 1279741, 8058600, 11758140, 789443, 32195181, 3895677 }, - { 10758205, 15755439, -4509950, 9243698, -4879422, 6879879, -2204575, -3566119, -8982069, 4429647 }, - { -2453894, 15725973, -20436342, -10410672, -5803908, -11040220, -7135870, -11642895, 18047436, -15281743 }, - }, - { - { -25173001, -11307165, 29759956, 11776784, -22262383, -15820455, 10993114, -12850837, -17620701, -9408468 }, - { 21987233, 700364, -24505048, 14972008, -7774265, -5718395, 32155026, 2581431, -29958985, 8773375 }, - { -25568350, 454463, -13211935, 16126715, 25240068, 8594567, 20656846, 12017935, -7874389, -13920155 }, - }, - { - { 6028182, 6263078, -31011806, -11301710, -818919, 2461772, -31841174, -5468042, -1721788, -2776725 }, - { -12278994, 16624277, 987579, -5922598, 32908203, 1248608, 7719845, -4166698, 28408820, 6816612 }, - { -10358094, -8237829, 19549651, -12169222, 22082623, 16147817, 20613181, 13982702, -10339570, 5067943 }, - }, - { - { -30505967, -3821767, 12074681, 13582412, -19877972, 2443951, -19719286, 12746132, 5331210, -10105944 }, - { 30528811, 3601899, -1957090, 4619785, -27361822, -15436388, 24180793, -12570394, 27679908, -1648928 }, - { 9402404, -13957065, 32834043, 10838634, -26580150, -13237195, 26653274, -8685565, 22611444, -12715406 }, - }, - { - { 22190590, 1118029, 22736441, 15130463, -30460692, -5991321, 19189625, -4648942, 4854859, 6622139 }, - { -8310738, -2953450, -8262579, -3388049, -10401731, -271929, 13424426, -3567227, 26404409, 13001963 }, - { -31241838, -15415700, -2994250, 8939346, 11562230, -12840670, -26064365, -11621720, -15405155, 11020693 }, - }, - { - { 1866042, -7949489, -7898649, -10301010, 12483315, 13477547, 3175636, -12424163, 28761762, 1406734 }, - { -448555, -1777666, 13018551, 3194501, -9580420, -11161737, 24760585, -4347088, 25577411, -13378680 }, - { -24290378, 4759345, -690653, -1852816, 2066747, 10693769, -29595790, 9884936, -9368926, 4745410 }, - }, - { - { -9141284, 6049714, -19531061, -4341411, -31260798, 9944276, -15462008, -11311852, 10931924, -11931931 }, - { -16561513, 14112680, -8012645, 4817318, -8040464, -11414606, -22853429, 10856641, -20470770, 13434654 }, - { 22759489, -10073434, -16766264, -1871422, 13637442, -10168091, 1765144, -12654326, 28445307, -5364710 }, - }, - { - { 29875063, 12493613, 2795536, -3786330, 1710620, 15181182, -10195717, -8788675, 9074234, 1167180 }, - { -26205683, 11014233, -9842651, -2635485, -26908120, 7532294, -18716888, -9535498, 3843903, 9367684 }, - { -10969595, -6403711, 9591134, 9582310, 11349256, 108879, 16235123, 8601684, -139197, 4242895 }, - }, - }, - { - { - { 22092954, -13191123, -2042793, -11968512, 32186753, -11517388, -6574341, 2470660, -27417366, 16625501 }, - { -11057722, 3042016, 13770083, -9257922, 584236, -544855, -7770857, 2602725, -27351616, 14247413 }, - { 6314175, -10264892, -32772502, 15957557, -10157730, 168750, -8618807, 14290061, 27108877, -1180880 }, - }, - { - { -8586597, -7170966, 13241782, 10960156, -32991015, -13794596, 33547976, -11058889, -27148451, 981874 }, - { 22833440, 9293594, -32649448, -13618667, -9136966, 14756819, -22928859, -13970780, -10479804, -16197962 }, - { -7768587, 3326786, -28111797, 10783824, 19178761, 14905060, 22680049, 13906969, -15933690, 3797899 }, - }, - { - { 21721356, -4212746, -12206123, 9310182, -3882239, -13653110, 23740224, -2709232, 20491983, -8042152 }, - { 9209270, -15135055, -13256557, -6167798, -731016, 15289673, 25947805, 15286587, 30997318, -6703063 }, - { 7392032, 16618386, 23946583, -8039892, -13265164, -1533858, -14197445, -2321576, 17649998, -250080 }, - }, - { - { -9301088, -14193827, 30609526, -3049543, -25175069, -1283752, -15241566, -9525724, -2233253, 7662146 }, - { -17558673, 1763594, -33114336, 15908610, -30040870, -12174295, 7335080, -8472199, -3174674, 3440183 }, - { -19889700, -5977008, -24111293, -9688870, 10799743, -16571957, 40450, -4431835, 4862400, 1133 }, - }, - { - { -32856209, -7873957, -5422389, 14860950, -16319031, 7956142, 7258061, 311861, -30594991, -7379421 }, - { -3773428, -1565936, 28985340, 7499440, 24445838, 9325937, 29727763, 16527196, 18278453, 15405622 }, - { -4381906, 8508652, -19898366, -3674424, -5984453, 15149970, -13313598, 843523, -21875062, 13626197 }, - }, - { - { 2281448, -13487055, -10915418, -2609910, 1879358, 16164207, -10783882, 3953792, 13340839, 15928663 }, - { 31727126, -7179855, -18437503, -8283652, 2875793, -16390330, -25269894, -7014826, -23452306, 5964753 }, - { 4100420, -5959452, -17179337, 6017714, -18705837, 12227141, -26684835, 11344144, 2538215, -7570755 }, - }, - { - { -9433605, 6123113, 11159803, -2156608, 30016280, 14966241, -20474983, 1485421, -629256, -15958862 }, - { -26804558, 4260919, 11851389, 9658551, -32017107, 16367492, -20205425, -13191288, 11659922, -11115118 }, - { 26180396, 10015009, -30844224, -8581293, 5418197, 9480663, 2231568, -10170080, 33100372, -1306171 }, - }, - { - { 15121113, -5201871, -10389905, 15427821, -27509937, -15992507, 21670947, 4486675, -5931810, -14466380 }, - { 16166486, -9483733, -11104130, 6023908, -31926798, -1364923, 2340060, -16254968, -10735770, -10039824 }, - { 28042865, -3557089, -12126526, 12259706, -3717498, -6945899, 6766453, -8689599, 18036436, 5803270 }, - }, - }, - { - { - { -817581, 6763912, 11803561, 1585585, 10958447, -2671165, 23855391, 4598332, -6159431, -14117438 }, - { -31031306, -14256194, 17332029, -2383520, 31312682, -5967183, 696309, 50292, -20095739, 11763584 }, - { -594563, -2514283, -32234153, 12643980, 12650761, 14811489, 665117, -12613632, -19773211, -10713562 }, - }, - { - { 30464590, -11262872, -4127476, -12734478, 19835327, -7105613, -24396175, 2075773, -17020157, 992471 }, - { 18357185, -6994433, 7766382, 16342475, -29324918, 411174, 14578841, 8080033, -11574335, -10601610 }, - { 19598397, 10334610, 12555054, 2555664, 18821899, -10339780, 21873263, 16014234, 26224780, 16452269 }, - }, - { - { -30223925, 5145196, 5944548, 16385966, 3976735, 2009897, -11377804, -7618186, -20533829, 3698650 }, - { 14187449, 3448569, -10636236, -10810935, -22663880, -3433596, 7268410, -10890444, 27394301, 12015369 }, - { 19695761, 16087646, 28032085, 12999827, 6817792, 11427614, 20244189, -1312777, -13259127, -3402461 }, - }, - { - { 30860103, 12735208, -1888245, -4699734, -16974906, 2256940, -8166013, 12298312, -8550524, -10393462 }, - { -5719826, -11245325, -1910649, 15569035, 26642876, -7587760, -5789354, -15118654, -4976164, 12651793 }, - { -2848395, 9953421, 11531313, -5282879, 26895123, -12697089, -13118820, -16517902, 9768698, -2533218 }, - }, - { - { -24719459, 1894651, -287698, -4704085, 15348719, -8156530, 32767513, 12765450, 4940095, 10678226 }, - { 18860224, 15980149, -18987240, -1562570, -26233012, -11071856, -7843882, 13944024, -24372348, 16582019 }, - { -15504260, 4970268, -29893044, 4175593, -20993212, -2199756, -11704054, 15444560, -11003761, 7989037 }, - }, - { - { 31490452, 5568061, -2412803, 2182383, -32336847, 4531686, -32078269, 6200206, -19686113, -14800171 }, - { -17308668, -15879940, -31522777, -2831, -32887382, 16375549, 8680158, -16371713, 28550068, -6857132 }, - { -28126887, -5688091, 16837845, -1820458, -6850681, 12700016, -30039981, 4364038, 1155602, 5988841 }, - }, - { - { 21890435, -13272907, -12624011, 12154349, -7831873, 15300496, 23148983, -4470481, 24618407, 8283181 }, - { -33136107, -10512751, 9975416, 6841041, -31559793, 16356536, 3070187, -7025928, 1466169, 10740210 }, - { -1509399, -15488185, -13503385, -10655916, 32799044, 909394, -13938903, -5779719, -32164649, -15327040 }, - }, - { - { 3960823, -14267803, -28026090, -15918051, -19404858, 13146868, 15567327, 951507, -3260321, -573935 }, - { 24740841, 5052253, -30094131, 8961361, 25877428, 6165135, -24368180, 14397372, -7380369, -6144105 }, - { -28888365, 3510803, -28103278, -1158478, -11238128, -10631454, -15441463, -14453128, -1625486, -6494814 }, - }, - }, - { - { - { 793299, -9230478, 8836302, -6235707, -27360908, -2369593, 33152843, -4885251, -9906200, -621852 }, - { 5666233, 525582, 20782575, -8038419, -24538499, 14657740, 16099374, 1468826, -6171428, -15186581 }, - { -4859255, -3779343, -2917758, -6748019, 7778750, 11688288, -30404353, -9871238, -1558923, -9863646 }, - }, - { - { 10896332, -7719704, 824275, 472601, -19460308, 3009587, 25248958, 14783338, -30581476, -15757844 }, - { 10566929, 12612572, -31944212, 11118703, -12633376, 12362879, 21752402, 8822496, 24003793, 14264025 }, - { 27713862, -7355973, -11008240, 9227530, 27050101, 2504721, 23886875, -13117525, 13958495, -5732453 }, - }, - { - { -23481610, 4867226, -27247128, 3900521, 29838369, -8212291, -31889399, -10041781, 7340521, -15410068 }, - { 4646514, -8011124, -22766023, -11532654, 23184553, 8566613, 31366726, -1381061, -15066784, -10375192 }, - { -17270517, 12723032, -16993061, 14878794, 21619651, -6197576, 27584817, 3093888, -8843694, 3849921 }, - }, - { - { -9064912, 2103172, 25561640, -15125738, -5239824, 9582958, 32477045, -9017955, 5002294, -15550259 }, - { -12057553, -11177906, 21115585, -13365155, 8808712, -12030708, 16489530, 13378448, -25845716, 12741426 }, - { -5946367, 10645103, -30911586, 15390284, -3286982, -7118677, 24306472, 15852464, 28834118, -7646072 }, - }, - { - { -17335748, -9107057, -24531279, 9434953, -8472084, -583362, -13090771, 455841, 20461858, 5491305 }, - { 13669248, -16095482, -12481974, -10203039, -14569770, -11893198, -24995986, 11293807, -28588204, -9421832 }, - { 28497928, 6272777, -33022994, 14470570, 8906179, -1225630, 18504674, -14165166, 29867745, -8795943 }, - }, - { - { -16207023, 13517196, -27799630, -13697798, 24009064, -6373891, -6367600, -13175392, 22853429, -4012011 }, - { 24191378, 16712145, -13931797, 15217831, 14542237, 1646131, 18603514, -11037887, 12876623, -2112447 }, - { 17902668, 4518229, -411702, -2829247, 26878217, 5258055, -12860753, 608397, 16031844, 3723494 }, - }, - { - { -28632773, 12763728, -20446446, 7577504, 33001348, -13017745, 17558842, -7872890, 23896954, -4314245 }, - { -20005381, -12011952, 31520464, 605201, 2543521, 5991821, -2945064, 7229064, -9919646, -8826859 }, - { 28816045, 298879, -28165016, -15920938, 19000928, -1665890, -12680833, -2949325, -18051778, -2082915 }, - }, - { - { 16000882, -344896, 3493092, -11447198, -29504595, -13159789, 12577740, 16041268, -19715240, 7847707 }, - { 10151868, 10572098, 27312476, 7922682, 14825339, 4723128, -32855931, -6519018, -10020567, 3852848 }, - { -11430470, 15697596, -21121557, -4420647, 5386314, 15063598, 16514493, -15932110, 29330899, -15076224 }, - }, - }, - { - { - { -25499735, -4378794, -15222908, -6901211, 16615731, 2051784, 3303702, 15490, -27548796, 12314391 }, - { 15683520, -6003043, 18109120, -9980648, 15337968, -5997823, -16717435, 15921866, 16103996, -3731215 }, - { -23169824, -10781249, 13588192, -1628807, -3798557, -1074929, -19273607, 5402699, -29815713, -9841101 }, - }, - { - { 23190676, 2384583, -32714340, 3462154, -29903655, -1529132, -11266856, 8911517, -25205859, 2739713 }, - { 21374101, -3554250, -33524649, 9874411, 15377179, 11831242, -33529904, 6134907, 4931255, 11987849 }, - { -7732, -2978858, -16223486, 7277597, 105524, -322051, -31480539, 13861388, -30076310, 10117930 }, - }, - { - { -29501170, -10744872, -26163768, 13051539, -25625564, 5089643, -6325503, 6704079, 12890019, 15728940 }, - { -21972360, -11771379, -951059, -4418840, 14704840, 2695116, 903376, -10428139, 12885167, 8311031 }, - { -17516482, 5352194, 10384213, -13811658, 7506451, 13453191, 26423267, 4384730, 1888765, -5435404 }, - }, - { - { -25817338, -3107312, -13494599, -3182506, 30896459, -13921729, -32251644, -12707869, -19464434, -3340243 }, - { -23607977, -2665774, -526091, 4651136, 5765089, 4618330, 6092245, 14845197, 17151279, -9854116 }, - { -24830458, -12733720, -15165978, 10367250, -29530908, -265356, 22825805, -7087279, -16866484, 16176525 }, - }, - { - { -23583256, 6564961, 20063689, 3798228, -4740178, 7359225, 2006182, -10363426, -28746253, -10197509 }, - { -10626600, -4486402, -13320562, -5125317, 3432136, -6393229, 23632037, -1940610, 32808310, 1099883 }, - { 15030977, 5768825, -27451236, -2887299, -6427378, -15361371, -15277896, -6809350, 2051441, -15225865 }, - }, - { - { -3362323, -7239372, 7517890, 9824992, 23555850, 295369, 5148398, -14154188, -22686354, 16633660 }, - { 4577086, -16752288, 13249841, -15304328, 19958763, -14537274, 18559670, -10759549, 8402478, -9864273 }, - { -28406330, -1051581, -26790155, -907698, -17212414, -11030789, 9453451, -14980072, 17983010, 9967138 }, - }, - { - { -25762494, 6524722, 26585488, 9969270, 24709298, 1220360, -1677990, 7806337, 17507396, 3651560 }, - { -10420457, -4118111, 14584639, 15971087, -15768321, 8861010, 26556809, -5574557, -18553322, -11357135 }, - { 2839101, 14284142, 4029895, 3472686, 14402957, 12689363, -26642121, 8459447, -5605463, -7621941 }, - }, - { - { -4839289, -3535444, 9744961, 2871048, 25113978, 3187018, -25110813, -849066, 17258084, -7977739 }, - { 18164541, -10595176, -17154882, -1542417, 19237078, -9745295, 23357533, -15217008, 26908270, 12150756 }, - { -30264870, -7647865, 5112249, -7036672, -1499807, -6974257, 43168, -5537701, -32302074, 16215819 }, - }, - }, - { - { - { -6898905, 9824394, -12304779, -4401089, -31397141, -6276835, 32574489, 12532905, -7503072, -8675347 }, - { -27343522, -16515468, -27151524, -10722951, 946346, 16291093, 254968, 7168080, 21676107, -1943028 }, - { 21260961, -8424752, -16831886, -11920822, -23677961, 3968121, -3651949, -6215466, -3556191, -7913075 }, - }, - { - { 16544754, 13250366, -16804428, 15546242, -4583003, 12757258, -2462308, -8680336, -18907032, -9662799 }, - { -2415239, -15577728, 18312303, 4964443, -15272530, -12653564, 26820651, 16690659, 25459437, -4564609 }, - { -25144690, 11425020, 28423002, -11020557, -6144921, -15826224, 9142795, -2391602, -6432418, -1644817 }, - }, - { - { -23104652, 6253476, 16964147, -3768872, -25113972, -12296437, -27457225, -16344658, 6335692, 7249989 }, - { -30333227, 13979675, 7503222, -12368314, -11956721, -4621693, -30272269, 2682242, 25993170, -12478523 }, - { 4364628, 5930691, 32304656, -10044554, -8054781, 15091131, 22857016, -10598955, 31820368, 15075278 }, - }, - { - { 31879134, -8918693, 17258761, 90626, -8041836, -4917709, 24162788, -9650886, -17970238, 12833045 }, - { 19073683, 14851414, -24403169, -11860168, 7625278, 11091125, -19619190, 2074449, -9413939, 14905377 }, - { 24483667, -11935567, -2518866, -11547418, -1553130, 15355506, -25282080, 9253129, 27628530, -7555480 }, - }, - { - { 17597607, 8340603, 19355617, 552187, 26198470, -3176583, 4593324, -9157582, -14110875, 15297016 }, - { 510886, 14337390, -31785257, 16638632, 6328095, 2713355, -20217417, -11864220, 8683221, 2921426 }, - { 18606791, 11874196, 27155355, -5281482, -24031742, 6265446, -25178240, -1278924, 4674690, 13890525 }, - }, - { - { 13609624, 13069022, -27372361, -13055908, 24360586, 9592974, 14977157, 9835105, 4389687, 288396 }, - { 9922506, -519394, 13613107, 5883594, -18758345, -434263, -12304062, 8317628, 23388070, 16052080 }, - { 12720016, 11937594, -31970060, -5028689, 26900120, 8561328, -20155687, -11632979, -14754271, -10812892 }, - }, - { - { 15961858, 14150409, 26716931, -665832, -22794328, 13603569, 11829573, 7467844, -28822128, 929275 }, - { 11038231, -11582396, -27310482, -7316562, -10498527, -16307831, -23479533, -9371869, -21393143, 2465074 }, - { 20017163, -4323226, 27915242, 1529148, 12396362, 15675764, 13817261, -9658066, 2463391, -4622140 }, - }, - { - { -16358878, -12663911, -12065183, 4996454, -1256422, 1073572, 9583558, 12851107, 4003896, 12673717 }, - { -1731589, -15155870, -3262930, 16143082, 19294135, 13385325, 14741514, -9103726, 7903886, 2348101 }, - { 24536016, -16515207, 12715592, -3862155, 1511293, 10047386, -3842346, -7129159, -28377538, 10048127 }, - }, - }, - { - { - { -12622226, -6204820, 30718825, 2591312, -10617028, 12192840, 18873298, -7297090, -32297756, 15221632 }, - { -26478122, -11103864, 11546244, -1852483, 9180880, 7656409, -21343950, 2095755, 29769758, 6593415 }, - { -31994208, -2907461, 4176912, 3264766, 12538965, -868111, 26312345, -6118678, 30958054, 8292160 }, - }, - { - { 31429822, -13959116, 29173532, 15632448, 12174511, -2760094, 32808831, 3977186, 26143136, -3148876 }, - { 22648901, 1402143, -22799984, 13746059, 7936347, 365344, -8668633, -1674433, -3758243, -2304625 }, - { -15491917, 8012313, -2514730, -12702462, -23965846, -10254029, -1612713, -1535569, -16664475, 8194478 }, - }, - { - { 27338066, -7507420, -7414224, 10140405, -19026427, -6589889, 27277191, 8855376, 28572286, 3005164 }, - { 26287124, 4821776, 25476601, -4145903, -3764513, -15788984, -18008582, 1182479, -26094821, -13079595 }, - { -7171154, 3178080, 23970071, 6201893, -17195577, -4489192, -21876275, -13982627, 32208683, -1198248 }, - }, - { - { -16657702, 2817643, -10286362, 14811298, 6024667, 13349505, -27315504, -10497842, -27672585, -11539858 }, - { 15941029, -9405932, -21367050, 8062055, 31876073, -238629, -15278393, -1444429, 15397331, -4130193 }, - { 8934485, -13485467, -23286397, -13423241, -32446090, 14047986, 31170398, -1441021, -27505566, 15087184 }, - }, - { - { -18357243, -2156491, 24524913, -16677868, 15520427, -6360776, -15502406, 11461896, 16788528, -5868942 }, - { -1947386, 16013773, 21750665, 3714552, -17401782, -16055433, -3770287, -10323320, 31322514, -11615635 }, - { 21426655, -5650218, -13648287, -5347537, -28812189, -4920970, -18275391, -14621414, 13040862, -12112948 }, - }, - { - { 11293895, 12478086, -27136401, 15083750, -29307421, 14748872, 14555558, -13417103, 1613711, 4896935 }, - { -25894883, 15323294, -8489791, -8057900, 25967126, -13425460, 2825960, -4897045, -23971776, -11267415 }, - { -15924766, -5229880, -17443532, 6410664, 3622847, 10243618, 20615400, 12405433, -23753030, -8436416 }, - }, - { - { -7091295, 12556208, -20191352, 9025187, -17072479, 4333801, 4378436, 2432030, 23097949, -566018 }, - { 4565804, -16025654, 20084412, -7842817, 1724999, 189254, 24767264, 10103221, -18512313, 2424778 }, - { 366633, -11976806, 8173090, -6890119, 30788634, 5745705, -7168678, 1344109, -3642553, 12412659 }, - }, - { - { -24001791, 7690286, 14929416, -168257, -32210835, -13412986, 24162697, -15326504, -3141501, 11179385 }, - { 18289522, -14724954, 8056945, 16430056, -21729724, 7842514, -6001441, -1486897, -18684645, -11443503 }, - { 476239, 6601091, -6152790, -9723375, 17503545, -4863900, 27672959, 13403813, 11052904, 5219329 }, - }, - }, - { - { - { 20678546, -8375738, -32671898, 8849123, -5009758, 14574752, 31186971, -3973730, 9014762, -8579056 }, - { -13644050, -10350239, -15962508, 5075808, -1514661, -11534600, -33102500, 9160280, 8473550, -3256838 }, - { 24900749, 14435722, 17209120, -15292541, -22592275, 9878983, -7689309, -16335821, -24568481, 11788948 }, - }, - { - { -3118155, -11395194, -13802089, 14797441, 9652448, -6845904, -20037437, 10410733, -24568470, -1458691 }, - { -15659161, 16736706, -22467150, 10215878, -9097177, 7563911, 11871841, -12505194, -18513325, 8464118 }, - { -23400612, 8348507, -14585951, -861714, -3950205, -6373419, 14325289, 8628612, 33313881, -8370517 }, - }, - { - { -20186973, -4967935, 22367356, 5271547, -1097117, -4788838, -24805667, -10236854, -8940735, -5818269 }, - { -6948785, -1795212, -32625683, -16021179, 32635414, -7374245, 15989197, -12838188, 28358192, -4253904 }, - { -23561781, -2799059, -32351682, -1661963, -9147719, 10429267, -16637684, 4072016, -5351664, 5596589 }, - }, - { - { -28236598, -3390048, 12312896, 6213178, 3117142, 16078565, 29266239, 2557221, 1768301, 15373193 }, - { -7243358, -3246960, -4593467, -7553353, -127927, -912245, -1090902, -4504991, -24660491, 3442910 }, - { -30210571, 5124043, 14181784, 8197961, 18964734, -11939093, 22597931, 7176455, -18585478, 13365930 }, - }, - { - { -7877390, -1499958, 8324673, 4690079, 6261860, 890446, 24538107, -8570186, -9689599, -3031667 }, - { 25008904, -10771599, -4305031, -9638010, 16265036, 15721635, 683793, -11823784, 15723479, -15163481 }, - { -9660625, 12374379, -27006999, -7026148, -7724114, -12314514, 11879682, 5400171, 519526, -1235876 }, - }, - { - { 22258397, -16332233, -7869817, 14613016, -22520255, -2950923, -20353881, 7315967, 16648397, 7605640 }, - { -8081308, -8464597, -8223311, 9719710, 19259459, -15348212, 23994942, -5281555, -9468848, 4763278 }, - { -21699244, 9220969, -15730624, 1084137, -25476107, -2852390, 31088447, -7764523, -11356529, 728112 }, - }, - { - { 26047220, -11751471, -6900323, -16521798, 24092068, 9158119, -4273545, -12555558, -29365436, -5498272 }, - { 17510331, -322857, 5854289, 8403524, 17133918, -3112612, -28111007, 12327945, 10750447, 10014012 }, - { -10312768, 3936952, 9156313, -8897683, 16498692, -994647, -27481051, -666732, 3424691, 7540221 }, - }, - { - { 30322361, -6964110, 11361005, -4143317, 7433304, 4989748, -7071422, -16317219, -9244265, 15258046 }, - { 13054562, -2779497, 19155474, 469045, -12482797, 4566042, 5631406, 2711395, 1062915, -5136345 }, - { -19240248, -11254599, -29509029, -7499965, -5835763, 13005411, -6066489, 12194497, 32960380, 1459310 }, - }, - }, - { - { - { 19852034, 7027924, 23669353, 10020366, 8586503, -6657907, 394197, -6101885, 18638003, -11174937 }, - { 31395534, 15098109, 26581030, 8030562, -16527914, -5007134, 9012486, -7584354, -6643087, -5442636 }, - { -9192165, -2347377, -1997099, 4529534, 25766844, 607986, -13222, 9677543, -32294889, -6456008 }, - }, - { - { -2444496, -149937, 29348902, 8186665, 1873760, 12489863, -30934579, -7839692, -7852844, -8138429 }, - { -15236356, -15433509, 7766470, 746860, 26346930, -10221762, -27333451, 10754588, -9431476, 5203576 }, - { 31834314, 14135496, -770007, 5159118, 20917671, -16768096, -7467973, -7337524, 31809243, 7347066 }, - }, - { - { -9606723, -11874240, 20414459, 13033986, 13716524, -11691881, 19797970, -12211255, 15192876, -2087490 }, - { -12663563, -2181719, 1168162, -3804809, 26747877, -14138091, 10609330, 12694420, 33473243, -13382104 }, - { 33184999, 11180355, 15832085, -11385430, -1633671, 225884, 15089336, -11023903, -6135662, 14480053 }, - }, - { - { 31308717, -5619998, 31030840, -1897099, 15674547, -6582883, 5496208, 13685227, 27595050, 8737275 }, - { -20318852, -15150239, 10933843, -16178022, 8335352, -7546022, -31008351, -12610604, 26498114, 66511 }, - { 22644454, -8761729, -16671776, 4884562, -3105614, -13559366, 30540766, -4286747, -13327787, -7515095 }, - }, - { - { -28017847, 9834845, 18617207, -2681312, -3401956, -13307506, 8205540, 13585437, -17127465, 15115439 }, - { 23711543, -672915, 31206561, -8362711, 6164647, -9709987, -33535882, -1426096, 8236921, 16492939 }, - { -23910559, -13515526, -26299483, -4503841, 25005590, -7687270, 19574902, 10071562, 6708380, -6222424 }, - }, - { - { 2101391, -4930054, 19702731, 2367575, -15427167, 1047675, 5301017, 9328700, 29955601, -11678310 }, - { 3096359, 9271816, -21620864, -15521844, -14847996, -7592937, -25892142, -12635595, -9917575, 6216608 }, - { -32615849, 338663, -25195611, 2510422, -29213566, -13820213, 24822830, -6146567, -26767480, 7525079 }, - }, - { - { -23066649, -13985623, 16133487, -7896178, -3389565, 778788, -910336, -2782495, -19386633, 11994101 }, - { 21691500, -13624626, -641331, -14367021, 3285881, -3483596, -25064666, 9718258, -7477437, 13381418 }, - { 18445390, -4202236, 14979846, 11622458, -1727110, -3582980, 23111648, -6375247, 28535282, 15779576 }, - }, - { - { 30098053, 3089662, -9234387, 16662135, -21306940, 11308411, -14068454, 12021730, 9955285, -16303356 }, - { 9734894, -14576830, -7473633, -9138735, 2060392, 11313496, -18426029, 9924399, 20194861, 13380996 }, - { -26378102, -7965207, -22167821, 15789297, -18055342, -6168792, -1984914, 15707771, 26342023, 10146099 }, - }, - }, - { - { - { -26016874, -219943, 21339191, -41388, 19745256, -2878700, -29637280, 2227040, 21612326, -545728 }, - { -13077387, 1184228, 23562814, -5970442, -20351244, -6348714, 25764461, 12243797, -20856566, 11649658 }, - { -10031494, 11262626, 27384172, 2271902, 26947504, -15997771, 39944, 6114064, 33514190, 2333242 }, - }, - { - { -21433588, -12421821, 8119782, 7219913, -21830522, -9016134, -6679750, -12670638, 24350578, -13450001 }, - { -4116307, -11271533, -23886186, 4843615, -30088339, 690623, -31536088, -10406836, 8317860, 12352766 }, - { 18200138, -14475911, -33087759, -2696619, -23702521, -9102511, -23552096, -2287550, 20712163, 6719373 }, - }, - { - { 26656208, 6075253, -7858556, 1886072, -28344043, 4262326, 11117530, -3763210, 26224235, -3297458 }, - { -17168938, -14854097, -3395676, -16369877, -19954045, 14050420, 21728352, 9493610, 18620611, -16428628 }, - { -13323321, 13325349, 11432106, 5964811, 18609221, 6062965, -5269471, -9725556, -30701573, -16479657 }, - }, - { - { -23860538, -11233159, 26961357, 1640861, -32413112, -16737940, 12248509, -5240639, 13735342, 1934062 }, - { 25089769, 6742589, 17081145, -13406266, 21909293, -16067981, -15136294, -3765346, -21277997, 5473616 }, - { 31883677, -7961101, 1083432, -11572403, 22828471, 13290673, -7125085, 12469656, 29111212, -5451014 }, - }, - { - { 24244947, -15050407, -26262976, 2791540, -14997599, 16666678, 24367466, 6388839, -10295587, 452383 }, - { -25640782, -3417841, 5217916, 16224624, 19987036, -4082269, -24236251, -5915248, 15766062, 8407814 }, - { -20406999, 13990231, 15495425, 16395525, 5377168, 15166495, -8917023, -4388953, -8067909, 2276718 }, - }, - { - { 30157918, 12924066, -17712050, 9245753, 19895028, 3368142, -23827587, 5096219, 22740376, -7303417 }, - { 2041139, -14256350, 7783687, 13876377, -25946985, -13352459, 24051124, 13742383, -15637599, 13295222 }, - { 33338237, -8505733, 12532113, 7977527, 9106186, -1715251, -17720195, -4612972, -4451357, -14669444 }, - }, - { - { -20045281, 5454097, -14346548, 6447146, 28862071, 1883651, -2469266, -4141880, 7770569, 9620597 }, - { 23208068, 7979712, 33071466, 8149229, 1758231, -10834995, 30945528, -1694323, -33502340, -14767970 }, - { 1439958, -16270480, -1079989, -793782, 4625402, 10647766, -5043801, 1220118, 30494170, -11440799 }, - }, - { - { -5037580, -13028295, -2970559, -3061767, 15640974, -6701666, -26739026, 926050, -1684339, -13333647 }, - { 13908495, -3549272, 30919928, -6273825, -21521863, 7989039, 9021034, 9078865, 3353509, 4033511 }, - { -29663431, -15113610, 32259991, -344482, 24295849, -12912123, 23161163, 8839127, 27485041, 7356032 }, - }, - }, - { - { - { 9661027, 705443, 11980065, -5370154, -1628543, 14661173, -6346142, 2625015, 28431036, -16771834 }, - { -23839233, -8311415, -25945511, 7480958, -17681669, -8354183, -22545972, 14150565, 15970762, 4099461 }, - { 29262576, 16756590, 26350592, -8793563, 8529671, -11208050, 13617293, -9937143, 11465739, 8317062 }, - }, - { - { -25493081, -6962928, 32500200, -9419051, -23038724, -2302222, 14898637, 3848455, 20969334, -5157516 }, - { -20384450, -14347713, -18336405, 13884722, -33039454, 2842114, -21610826, -3649888, 11177095, 14989547 }, - { -24496721, -11716016, 16959896, 2278463, 12066309, 10137771, 13515641, 2581286, -28487508, 9930240 }, - }, - { - { -17751622, -2097826, 16544300, -13009300, -15914807, -14949081, 18345767, -13403753, 16291481, -5314038 }, - { -33229194, 2553288, 32678213, 9875984, 8534129, 6889387, -9676774, 6957617, 4368891, 9788741 }, - { 16660756, 7281060, -10830758, 12911820, 20108584, -8101676, -21722536, -8613148, 16250552, -11111103 }, - }, - { - { -19765507, 2390526, -16551031, 14161980, 1905286, 6414907, 4689584, 10604807, -30190403, 4782747 }, - { -1354539, 14736941, -7367442, -13292886, 7710542, -14155590, -9981571, 4383045, 22546403, 437323 }, - { 31665577, -12180464, -16186830, 1491339, -18368625, 3294682, 27343084, 2786261, -30633590, -14097016 }, - }, - { - { -14467279, -683715, -33374107, 7448552, 19294360, 14334329, -19690631, 2355319, -19284671, -6114373 }, - { 15121312, -15796162, 6377020, -6031361, -10798111, -12957845, 18952177, 15496498, -29380133, 11754228 }, - { -2637277, -13483075, 8488727, -14303896, 12728761, -1622493, 7141596, 11724556, 22761615, -10134141 }, - }, - { - { 16918416, 11729663, -18083579, 3022987, -31015732, -13339659, -28741185, -12227393, 32851222, 11717399 }, - { 11166634, 7338049, -6722523, 4531520, -29468672, -7302055, 31474879, 3483633, -1193175, -4030831 }, - { -185635, 9921305, 31456609, -13536438, -12013818, 13348923, 33142652, 6546660, -19985279, -3948376 }, - }, - { - { -32460596, 11266712, -11197107, -7899103, 31703694, 3855903, -8537131, -12833048, -30772034, -15486313 }, - { -18006477, 12709068, 3991746, -6479188, -21491523, -10550425, -31135347, -16049879, 10928917, 3011958 }, - { -6957757, -15594337, 31696059, 334240, 29576716, 14796075, -30831056, -12805180, 18008031, 10258577 }, - }, - { - { -22448644, 15655569, 7018479, -4410003, -30314266, -1201591, -1853465, 1367120, 25127874, 6671743 }, - { 29701166, -14373934, -10878120, 9279288, -17568, 13127210, 21382910, 11042292, 25838796, 4642684 }, - { -20430234, 14955537, -24126347, 8124619, -5369288, -5990470, 30468147, -13900640, 18423289, 4177476 }, - }, - }, -}; diff --git a/src/ed25519/sc.c b/src/ed25519/sc.c deleted file mode 100644 index ee54d99..0000000 --- a/src/ed25519/sc.c +++ /dev/null @@ -1,785 +0,0 @@ -#include "fixedint.h" -#include "sc.h" - -static uint64_t load_3(const unsigned char *in) { - uint64_t result; - - result = in[0]; - result |= shlu64(in[1], 8); - result |= shlu64(in[2], 16); - - return result; -} - -static uint64_t load_4(const unsigned char *in) { - uint64_t result; - - result = in[0]; - result |= shlu64(in[1], 8); - result |= shlu64(in[2], 16); - result |= shlu64(in[3], 24); - - return result; -} - -/* -Input: - s[0]+256*s[1]+...+256^63*s[63] = s - -Output: - s[0]+256*s[1]+...+256^31*s[31] = s mod l - where l = 2^252 + 27742317777372353535851937790883648493. - Overwrites s in place. -*/ - -void sc_reduce(unsigned char *s) { - int64_t s0 = 2097151 & load_3(s); - int64_t s1 = 2097151 & (load_4(s + 2) >> 5); - int64_t s2 = 2097151 & (load_3(s + 5) >> 2); - int64_t s3 = 2097151 & (load_4(s + 7) >> 7); - int64_t s4 = 2097151 & (load_4(s + 10) >> 4); - int64_t s5 = 2097151 & (load_3(s + 13) >> 1); - int64_t s6 = 2097151 & (load_4(s + 15) >> 6); - int64_t s7 = 2097151 & (load_3(s + 18) >> 3); - int64_t s8 = 2097151 & load_3(s + 21); - int64_t s9 = 2097151 & (load_4(s + 23) >> 5); - int64_t s10 = 2097151 & (load_3(s + 26) >> 2); - int64_t s11 = 2097151 & (load_4(s + 28) >> 7); - int64_t s12 = 2097151 & (load_4(s + 31) >> 4); - int64_t s13 = 2097151 & (load_3(s + 34) >> 1); - int64_t s14 = 2097151 & (load_4(s + 36) >> 6); - int64_t s15 = 2097151 & (load_3(s + 39) >> 3); - int64_t s16 = 2097151 & load_3(s + 42); - int64_t s17 = 2097151 & (load_4(s + 44) >> 5); - int64_t s18 = 2097151 & (load_3(s + 47) >> 2); - int64_t s19 = 2097151 & (load_4(s + 49) >> 7); - int64_t s20 = 2097151 & (load_4(s + 52) >> 4); - int64_t s21 = 2097151 & (load_3(s + 55) >> 1); - int64_t s22 = 2097151 & (load_4(s + 57) >> 6); - int64_t s23 = (load_4(s + 60) >> 3); - int64_t carry0; - int64_t carry1; - int64_t carry2; - int64_t carry3; - int64_t carry4; - int64_t carry5; - int64_t carry6; - int64_t carry7; - int64_t carry8; - int64_t carry9; - int64_t carry10; - int64_t carry11; - int64_t carry12; - int64_t carry13; - int64_t carry14; - int64_t carry15; - int64_t carry16; - - s11 += s23 * 666643; - s12 += s23 * 470296; - s13 += s23 * 654183; - s14 -= s23 * 997805; - s15 += s23 * 136657; - s16 -= s23 * 683901; - s10 += s22 * 666643; - s11 += s22 * 470296; - s12 += s22 * 654183; - s13 -= s22 * 997805; - s14 += s22 * 136657; - s15 -= s22 * 683901; - s9 += s21 * 666643; - s10 += s21 * 470296; - s11 += s21 * 654183; - s12 -= s21 * 997805; - s13 += s21 * 136657; - s14 -= s21 * 683901; - s8 += s20 * 666643; - s9 += s20 * 470296; - s10 += s20 * 654183; - s11 -= s20 * 997805; - s12 += s20 * 136657; - s13 -= s20 * 683901; - s7 += s19 * 666643; - s8 += s19 * 470296; - s9 += s19 * 654183; - s10 -= s19 * 997805; - s11 += s19 * 136657; - s12 -= s19 * 683901; - s6 += s18 * 666643; - s7 += s18 * 470296; - s8 += s18 * 654183; - s9 -= s18 * 997805; - s10 += s18 * 136657; - s11 -= s18 * 683901; - carry6 = (s6 + (1 << 20)) >> 21; - s7 += carry6; - s6 -= shl64(carry6, 21); - carry8 = (s8 + (1 << 20)) >> 21; - s9 += carry8; - s8 -= shl64(carry8, 21); - carry10 = (s10 + (1 << 20)) >> 21; - s11 += carry10; - s10 -= shl64(carry10, 21); - carry12 = (s12 + (1 << 20)) >> 21; - s13 += carry12; - s12 -= shl64(carry12, 21); - carry14 = (s14 + (1 << 20)) >> 21; - s15 += carry14; - s14 -= shl64(carry14, 21); - carry16 = (s16 + (1 << 20)) >> 21; - s17 += carry16; - s16 -= shl64(carry16, 21); - carry7 = (s7 + (1 << 20)) >> 21; - s8 += carry7; - s7 -= shl64(carry7, 21); - carry9 = (s9 + (1 << 20)) >> 21; - s10 += carry9; - s9 -= shl64(carry9, 21); - carry11 = (s11 + (1 << 20)) >> 21; - s12 += carry11; - s11 -= shl64(carry11, 21); - carry13 = (s13 + (1 << 20)) >> 21; - s14 += carry13; - s13 -= shl64(carry13, 21); - carry15 = (s15 + (1 << 20)) >> 21; - s16 += carry15; - s15 -= shl64(carry15, 21); - s5 += s17 * 666643; - s6 += s17 * 470296; - s7 += s17 * 654183; - s8 -= s17 * 997805; - s9 += s17 * 136657; - s10 -= s17 * 683901; - s4 += s16 * 666643; - s5 += s16 * 470296; - s6 += s16 * 654183; - s7 -= s16 * 997805; - s8 += s16 * 136657; - s9 -= s16 * 683901; - s3 += s15 * 666643; - s4 += s15 * 470296; - s5 += s15 * 654183; - s6 -= s15 * 997805; - s7 += s15 * 136657; - s8 -= s15 * 683901; - s2 += s14 * 666643; - s3 += s14 * 470296; - s4 += s14 * 654183; - s5 -= s14 * 997805; - s6 += s14 * 136657; - s7 -= s14 * 683901; - s1 += s13 * 666643; - s2 += s13 * 470296; - s3 += s13 * 654183; - s4 -= s13 * 997805; - s5 += s13 * 136657; - s6 -= s13 * 683901; - s0 += s12 * 666643; - s1 += s12 * 470296; - s2 += s12 * 654183; - s3 -= s12 * 997805; - s4 += s12 * 136657; - s5 -= s12 * 683901; - s12 = 0; - carry0 = (s0 + (1 << 20)) >> 21; - s1 += carry0; - s0 -= shl64(carry0, 21); - carry2 = (s2 + (1 << 20)) >> 21; - s3 += carry2; - s2 -= shl64(carry2, 21); - carry4 = (s4 + (1 << 20)) >> 21; - s5 += carry4; - s4 -= shl64(carry4, 21); - carry6 = (s6 + (1 << 20)) >> 21; - s7 += carry6; - s6 -= shl64(carry6, 21); - carry8 = (s8 + (1 << 20)) >> 21; - s9 += carry8; - s8 -= shl64(carry8, 21); - carry10 = (s10 + (1 << 20)) >> 21; - s11 += carry10; - s10 -= shl64(carry10, 21); - carry1 = (s1 + (1 << 20)) >> 21; - s2 += carry1; - s1 -= shl64(carry1, 21); - carry3 = (s3 + (1 << 20)) >> 21; - s4 += carry3; - s3 -= shl64(carry3, 21); - carry5 = (s5 + (1 << 20)) >> 21; - s6 += carry5; - s5 -= shl64(carry5, 21); - carry7 = (s7 + (1 << 20)) >> 21; - s8 += carry7; - s7 -= shl64(carry7, 21); - carry9 = (s9 + (1 << 20)) >> 21; - s10 += carry9; - s9 -= shl64(carry9, 21); - carry11 = (s11 + (1 << 20)) >> 21; - s12 += carry11; - s11 -= shl64(carry11, 21); - s0 += s12 * 666643; - s1 += s12 * 470296; - s2 += s12 * 654183; - s3 -= s12 * 997805; - s4 += s12 * 136657; - s5 -= s12 * 683901; - s12 = 0; - carry0 = s0 >> 21; - s1 += carry0; - s0 -= shl64(carry0, 21); - carry1 = s1 >> 21; - s2 += carry1; - s1 -= shl64(carry1, 21); - carry2 = s2 >> 21; - s3 += carry2; - s2 -= shl64(carry2, 21); - carry3 = s3 >> 21; - s4 += carry3; - s3 -= shl64(carry3, 21); - carry4 = s4 >> 21; - s5 += carry4; - s4 -= shl64(carry4, 21); - carry5 = s5 >> 21; - s6 += carry5; - s5 -= shl64(carry5, 21); - carry6 = s6 >> 21; - s7 += carry6; - s6 -= shl64(carry6, 21); - carry7 = s7 >> 21; - s8 += carry7; - s7 -= shl64(carry7, 21); - carry8 = s8 >> 21; - s9 += carry8; - s8 -= shl64(carry8, 21); - carry9 = s9 >> 21; - s10 += carry9; - s9 -= shl64(carry9, 21); - carry10 = s10 >> 21; - s11 += carry10; - s10 -= shl64(carry10, 21); - carry11 = s11 >> 21; - s12 += carry11; - s11 -= shl64(carry11, 21); - s0 += s12 * 666643; - s1 += s12 * 470296; - s2 += s12 * 654183; - s3 -= s12 * 997805; - s4 += s12 * 136657; - s5 -= s12 * 683901; - carry0 = s0 >> 21; - s1 += carry0; - s0 -= shl64(carry0, 21); - carry1 = s1 >> 21; - s2 += carry1; - s1 -= shl64(carry1, 21); - carry2 = s2 >> 21; - s3 += carry2; - s2 -= shl64(carry2, 21); - carry3 = s3 >> 21; - s4 += carry3; - s3 -= shl64(carry3, 21); - carry4 = s4 >> 21; - s5 += carry4; - s4 -= shl64(carry4, 21); - carry5 = s5 >> 21; - s6 += carry5; - s5 -= shl64(carry5, 21); - carry6 = s6 >> 21; - s7 += carry6; - s6 -= shl64(carry6, 21); - carry7 = s7 >> 21; - s8 += carry7; - s7 -= shl64(carry7, 21); - carry8 = s8 >> 21; - s9 += carry8; - s8 -= shl64(carry8, 21); - carry9 = s9 >> 21; - s10 += carry9; - s9 -= shl64(carry9, 21); - carry10 = s10 >> 21; - s11 += carry10; - s10 -= shl64(carry10, 21); - - s[0] = (unsigned char)(s0 >> 0); - s[1] = (unsigned char)(s0 >> 8); - s[2] = (unsigned char)((s0 >> 16) | shl64(s1, 5)); - s[3] = (unsigned char)(s1 >> 3); - s[4] = (unsigned char)(s1 >> 11); - s[5] = (unsigned char)((s1 >> 19) | shl64(s2, 2)); - s[6] = (unsigned char)(s2 >> 6); - s[7] = (unsigned char)((s2 >> 14) | shl64(s3, 7)); - s[8] = (unsigned char)(s3 >> 1); - s[9] = (unsigned char)(s3 >> 9); - s[10] = (unsigned char)((s3 >> 17) | shl64(s4, 4)); - s[11] = (unsigned char)(s4 >> 4); - s[12] = (unsigned char)(s4 >> 12); - s[13] = (unsigned char)((s4 >> 20) | shl64(s5, 1)); - s[14] = (unsigned char)(s5 >> 7); - s[15] = (unsigned char)((s5 >> 15) | shl64(s6, 6)); - s[16] = (unsigned char)(s6 >> 2); - s[17] = (unsigned char)(s6 >> 10); - s[18] = (unsigned char)((s6 >> 18) | shl64(s7, 3)); - s[19] = (unsigned char)(s7 >> 5); - s[20] = (unsigned char)(s7 >> 13); - s[21] = (unsigned char)(s8 >> 0); - s[22] = (unsigned char)(s8 >> 8); - s[23] = (unsigned char)((s8 >> 16) | shl64(s9, 5)); - s[24] = (unsigned char)(s9 >> 3); - s[25] = (unsigned char)(s9 >> 11); - s[26] = (unsigned char)((s9 >> 19) | shl64(s10, 2)); - s[27] = (unsigned char)(s10 >> 6); - s[28] = (unsigned char)((s10 >> 14) | shl64(s11, 7)); - s[29] = (unsigned char)(s11 >> 1); - s[30] = (unsigned char)(s11 >> 9); - s[31] = (unsigned char)(s11 >> 17); -} - - - -/* -Input: - a[0]+256*a[1]+...+256^31*a[31] = a - b[0]+256*b[1]+...+256^31*b[31] = b - c[0]+256*c[1]+...+256^31*c[31] = c - -Output: - s[0]+256*s[1]+...+256^31*s[31] = (ab+c) mod l - where l = 2^252 + 27742317777372353535851937790883648493. -*/ - -void sc_muladd(unsigned char *s, const unsigned char *a, const unsigned char *b, const unsigned char *c) { - int64_t a0 = 2097151 & load_3(a); - int64_t a1 = 2097151 & (load_4(a + 2) >> 5); - int64_t a2 = 2097151 & (load_3(a + 5) >> 2); - int64_t a3 = 2097151 & (load_4(a + 7) >> 7); - int64_t a4 = 2097151 & (load_4(a + 10) >> 4); - int64_t a5 = 2097151 & (load_3(a + 13) >> 1); - int64_t a6 = 2097151 & (load_4(a + 15) >> 6); - int64_t a7 = 2097151 & (load_3(a + 18) >> 3); - int64_t a8 = 2097151 & load_3(a + 21); - int64_t a9 = 2097151 & (load_4(a + 23) >> 5); - int64_t a10 = 2097151 & (load_3(a + 26) >> 2); - int64_t a11 = (load_4(a + 28) >> 7); - int64_t b0 = 2097151 & load_3(b); - int64_t b1 = 2097151 & (load_4(b + 2) >> 5); - int64_t b2 = 2097151 & (load_3(b + 5) >> 2); - int64_t b3 = 2097151 & (load_4(b + 7) >> 7); - int64_t b4 = 2097151 & (load_4(b + 10) >> 4); - int64_t b5 = 2097151 & (load_3(b + 13) >> 1); - int64_t b6 = 2097151 & (load_4(b + 15) >> 6); - int64_t b7 = 2097151 & (load_3(b + 18) >> 3); - int64_t b8 = 2097151 & load_3(b + 21); - int64_t b9 = 2097151 & (load_4(b + 23) >> 5); - int64_t b10 = 2097151 & (load_3(b + 26) >> 2); - int64_t b11 = (load_4(b + 28) >> 7); - int64_t c0 = 2097151 & load_3(c); - int64_t c1 = 2097151 & (load_4(c + 2) >> 5); - int64_t c2 = 2097151 & (load_3(c + 5) >> 2); - int64_t c3 = 2097151 & (load_4(c + 7) >> 7); - int64_t c4 = 2097151 & (load_4(c + 10) >> 4); - int64_t c5 = 2097151 & (load_3(c + 13) >> 1); - int64_t c6 = 2097151 & (load_4(c + 15) >> 6); - int64_t c7 = 2097151 & (load_3(c + 18) >> 3); - int64_t c8 = 2097151 & load_3(c + 21); - int64_t c9 = 2097151 & (load_4(c + 23) >> 5); - int64_t c10 = 2097151 & (load_3(c + 26) >> 2); - int64_t c11 = (load_4(c + 28) >> 7); - int64_t s0; - int64_t s1; - int64_t s2; - int64_t s3; - int64_t s4; - int64_t s5; - int64_t s6; - int64_t s7; - int64_t s8; - int64_t s9; - int64_t s10; - int64_t s11; - int64_t s12; - int64_t s13; - int64_t s14; - int64_t s15; - int64_t s16; - int64_t s17; - int64_t s18; - int64_t s19; - int64_t s20; - int64_t s21; - int64_t s22; - int64_t s23; - int64_t carry0; - int64_t carry1; - int64_t carry2; - int64_t carry3; - int64_t carry4; - int64_t carry5; - int64_t carry6; - int64_t carry7; - int64_t carry8; - int64_t carry9; - int64_t carry10; - int64_t carry11; - int64_t carry12; - int64_t carry13; - int64_t carry14; - int64_t carry15; - int64_t carry16; - int64_t carry17; - int64_t carry18; - int64_t carry19; - int64_t carry20; - int64_t carry21; - int64_t carry22; - - s0 = c0 + a0 * b0; - s1 = c1 + a0 * b1 + a1 * b0; - s2 = c2 + a0 * b2 + a1 * b1 + a2 * b0; - s3 = c3 + a0 * b3 + a1 * b2 + a2 * b1 + a3 * b0; - s4 = c4 + a0 * b4 + a1 * b3 + a2 * b2 + a3 * b1 + a4 * b0; - s5 = c5 + a0 * b5 + a1 * b4 + a2 * b3 + a3 * b2 + a4 * b1 + a5 * b0; - s6 = c6 + a0 * b6 + a1 * b5 + a2 * b4 + a3 * b3 + a4 * b2 + a5 * b1 + a6 * b0; - s7 = c7 + a0 * b7 + a1 * b6 + a2 * b5 + a3 * b4 + a4 * b3 + a5 * b2 + a6 * b1 + a7 * b0; - s8 = c8 + a0 * b8 + a1 * b7 + a2 * b6 + a3 * b5 + a4 * b4 + a5 * b3 + a6 * b2 + a7 * b1 + a8 * b0; - s9 = c9 + a0 * b9 + a1 * b8 + a2 * b7 + a3 * b6 + a4 * b5 + a5 * b4 + a6 * b3 + a7 * b2 + a8 * b1 + a9 * b0; - s10 = c10 + a0 * b10 + a1 * b9 + a2 * b8 + a3 * b7 + a4 * b6 + a5 * b5 + a6 * b4 + a7 * b3 + a8 * b2 + a9 * b1 + a10 * b0; - s11 = c11 + a0 * b11 + a1 * b10 + a2 * b9 + a3 * b8 + a4 * b7 + a5 * b6 + a6 * b5 + a7 * b4 + a8 * b3 + a9 * b2 + a10 * b1 + a11 * b0; - s12 = a1 * b11 + a2 * b10 + a3 * b9 + a4 * b8 + a5 * b7 + a6 * b6 + a7 * b5 + a8 * b4 + a9 * b3 + a10 * b2 + a11 * b1; - s13 = a2 * b11 + a3 * b10 + a4 * b9 + a5 * b8 + a6 * b7 + a7 * b6 + a8 * b5 + a9 * b4 + a10 * b3 + a11 * b2; - s14 = a3 * b11 + a4 * b10 + a5 * b9 + a6 * b8 + a7 * b7 + a8 * b6 + a9 * b5 + a10 * b4 + a11 * b3; - s15 = a4 * b11 + a5 * b10 + a6 * b9 + a7 * b8 + a8 * b7 + a9 * b6 + a10 * b5 + a11 * b4; - s16 = a5 * b11 + a6 * b10 + a7 * b9 + a8 * b8 + a9 * b7 + a10 * b6 + a11 * b5; - s17 = a6 * b11 + a7 * b10 + a8 * b9 + a9 * b8 + a10 * b7 + a11 * b6; - s18 = a7 * b11 + a8 * b10 + a9 * b9 + a10 * b8 + a11 * b7; - s19 = a8 * b11 + a9 * b10 + a10 * b9 + a11 * b8; - s20 = a9 * b11 + a10 * b10 + a11 * b9; - s21 = a10 * b11 + a11 * b10; - s22 = a11 * b11; - s23 = 0; - carry0 = (s0 + (1 << 20)) >> 21; - s1 += carry0; - s0 -= shl64(carry0, 21); - carry2 = (s2 + (1 << 20)) >> 21; - s3 += carry2; - s2 -= shl64(carry2, 21); - carry4 = (s4 + (1 << 20)) >> 21; - s5 += carry4; - s4 -= shl64(carry4, 21); - carry6 = (s6 + (1 << 20)) >> 21; - s7 += carry6; - s6 -= shl64(carry6, 21); - carry8 = (s8 + (1 << 20)) >> 21; - s9 += carry8; - s8 -= shl64(carry8, 21); - carry10 = (s10 + (1 << 20)) >> 21; - s11 += carry10; - s10 -= shl64(carry10, 21); - carry12 = (s12 + (1 << 20)) >> 21; - s13 += carry12; - s12 -= shl64(carry12, 21); - carry14 = (s14 + (1 << 20)) >> 21; - s15 += carry14; - s14 -= shl64(carry14, 21); - carry16 = (s16 + (1 << 20)) >> 21; - s17 += carry16; - s16 -= shl64(carry16, 21); - carry18 = (s18 + (1 << 20)) >> 21; - s19 += carry18; - s18 -= shl64(carry18, 21); - carry20 = (s20 + (1 << 20)) >> 21; - s21 += carry20; - s20 -= shl64(carry20, 21); - carry22 = (s22 + (1 << 20)) >> 21; - s23 += carry22; - s22 -= shl64(carry22, 21); - carry1 = (s1 + (1 << 20)) >> 21; - s2 += carry1; - s1 -= shl64(carry1, 21); - carry3 = (s3 + (1 << 20)) >> 21; - s4 += carry3; - s3 -= shl64(carry3, 21); - carry5 = (s5 + (1 << 20)) >> 21; - s6 += carry5; - s5 -= shl64(carry5, 21); - carry7 = (s7 + (1 << 20)) >> 21; - s8 += carry7; - s7 -= shl64(carry7, 21); - carry9 = (s9 + (1 << 20)) >> 21; - s10 += carry9; - s9 -= shl64(carry9, 21); - carry11 = (s11 + (1 << 20)) >> 21; - s12 += carry11; - s11 -= shl64(carry11, 21); - carry13 = (s13 + (1 << 20)) >> 21; - s14 += carry13; - s13 -= shl64(carry13, 21); - carry15 = (s15 + (1 << 20)) >> 21; - s16 += carry15; - s15 -= shl64(carry15, 21); - carry17 = (s17 + (1 << 20)) >> 21; - s18 += carry17; - s17 -= shl64(carry17, 21); - carry19 = (s19 + (1 << 20)) >> 21; - s20 += carry19; - s19 -= shl64(carry19, 21); - carry21 = (s21 + (1 << 20)) >> 21; - s22 += carry21; - s21 -= shl64(carry21, 21); - s11 += s23 * 666643; - s12 += s23 * 470296; - s13 += s23 * 654183; - s14 -= s23 * 997805; - s15 += s23 * 136657; - s16 -= s23 * 683901; - s10 += s22 * 666643; - s11 += s22 * 470296; - s12 += s22 * 654183; - s13 -= s22 * 997805; - s14 += s22 * 136657; - s15 -= s22 * 683901; - s9 += s21 * 666643; - s10 += s21 * 470296; - s11 += s21 * 654183; - s12 -= s21 * 997805; - s13 += s21 * 136657; - s14 -= s21 * 683901; - s8 += s20 * 666643; - s9 += s20 * 470296; - s10 += s20 * 654183; - s11 -= s20 * 997805; - s12 += s20 * 136657; - s13 -= s20 * 683901; - s7 += s19 * 666643; - s8 += s19 * 470296; - s9 += s19 * 654183; - s10 -= s19 * 997805; - s11 += s19 * 136657; - s12 -= s19 * 683901; - s6 += s18 * 666643; - s7 += s18 * 470296; - s8 += s18 * 654183; - s9 -= s18 * 997805; - s10 += s18 * 136657; - s11 -= s18 * 683901; - carry6 = (s6 + (1 << 20)) >> 21; - s7 += carry6; - s6 -= shl64(carry6, 21); - carry8 = (s8 + (1 << 20)) >> 21; - s9 += carry8; - s8 -= shl64(carry8, 21); - carry10 = (s10 + (1 << 20)) >> 21; - s11 += carry10; - s10 -= shl64(carry10, 21); - carry12 = (s12 + (1 << 20)) >> 21; - s13 += carry12; - s12 -= shl64(carry12, 21); - carry14 = (s14 + (1 << 20)) >> 21; - s15 += carry14; - s14 -= shl64(carry14, 21); - carry16 = (s16 + (1 << 20)) >> 21; - s17 += carry16; - s16 -= shl64(carry16, 21); - carry7 = (s7 + (1 << 20)) >> 21; - s8 += carry7; - s7 -= shl64(carry7, 21); - carry9 = (s9 + (1 << 20)) >> 21; - s10 += carry9; - s9 -= shl64(carry9, 21); - carry11 = (s11 + (1 << 20)) >> 21; - s12 += carry11; - s11 -= shl64(carry11, 21); - carry13 = (s13 + (1 << 20)) >> 21; - s14 += carry13; - s13 -= shl64(carry13, 21); - carry15 = (s15 + (1 << 20)) >> 21; - s16 += carry15; - s15 -= shl64(carry15, 21); - s5 += s17 * 666643; - s6 += s17 * 470296; - s7 += s17 * 654183; - s8 -= s17 * 997805; - s9 += s17 * 136657; - s10 -= s17 * 683901; - s4 += s16 * 666643; - s5 += s16 * 470296; - s6 += s16 * 654183; - s7 -= s16 * 997805; - s8 += s16 * 136657; - s9 -= s16 * 683901; - s3 += s15 * 666643; - s4 += s15 * 470296; - s5 += s15 * 654183; - s6 -= s15 * 997805; - s7 += s15 * 136657; - s8 -= s15 * 683901; - s2 += s14 * 666643; - s3 += s14 * 470296; - s4 += s14 * 654183; - s5 -= s14 * 997805; - s6 += s14 * 136657; - s7 -= s14 * 683901; - s1 += s13 * 666643; - s2 += s13 * 470296; - s3 += s13 * 654183; - s4 -= s13 * 997805; - s5 += s13 * 136657; - s6 -= s13 * 683901; - s0 += s12 * 666643; - s1 += s12 * 470296; - s2 += s12 * 654183; - s3 -= s12 * 997805; - s4 += s12 * 136657; - s5 -= s12 * 683901; - s12 = 0; - carry0 = (s0 + (1 << 20)) >> 21; - s1 += carry0; - s0 -= shl64(carry0, 21); - carry2 = (s2 + (1 << 20)) >> 21; - s3 += carry2; - s2 -= shl64(carry2, 21); - carry4 = (s4 + (1 << 20)) >> 21; - s5 += carry4; - s4 -= shl64(carry4, 21); - carry6 = (s6 + (1 << 20)) >> 21; - s7 += carry6; - s6 -= shl64(carry6, 21); - carry8 = (s8 + (1 << 20)) >> 21; - s9 += carry8; - s8 -= shl64(carry8, 21); - carry10 = (s10 + (1 << 20)) >> 21; - s11 += carry10; - s10 -= shl64(carry10, 21); - carry1 = (s1 + (1 << 20)) >> 21; - s2 += carry1; - s1 -= shl64(carry1, 21); - carry3 = (s3 + (1 << 20)) >> 21; - s4 += carry3; - s3 -= shl64(carry3, 21); - carry5 = (s5 + (1 << 20)) >> 21; - s6 += carry5; - s5 -= shl64(carry5, 21); - carry7 = (s7 + (1 << 20)) >> 21; - s8 += carry7; - s7 -= shl64(carry7, 21); - carry9 = (s9 + (1 << 20)) >> 21; - s10 += carry9; - s9 -= shl64(carry9, 21); - carry11 = (s11 + (1 << 20)) >> 21; - s12 += carry11; - s11 -= shl64(carry11, 21); - s0 += s12 * 666643; - s1 += s12 * 470296; - s2 += s12 * 654183; - s3 -= s12 * 997805; - s4 += s12 * 136657; - s5 -= s12 * 683901; - s12 = 0; - carry0 = s0 >> 21; - s1 += carry0; - s0 -= shl64(carry0, 21); - carry1 = s1 >> 21; - s2 += carry1; - s1 -= shl64(carry1, 21); - carry2 = s2 >> 21; - s3 += carry2; - s2 -= shl64(carry2, 21); - carry3 = s3 >> 21; - s4 += carry3; - s3 -= shl64(carry3, 21); - carry4 = s4 >> 21; - s5 += carry4; - s4 -= shl64(carry4, 21); - carry5 = s5 >> 21; - s6 += carry5; - s5 -= shl64(carry5, 21); - carry6 = s6 >> 21; - s7 += carry6; - s6 -= shl64(carry6, 21); - carry7 = s7 >> 21; - s8 += carry7; - s7 -= shl64(carry7, 21); - carry8 = s8 >> 21; - s9 += carry8; - s8 -= shl64(carry8, 21); - carry9 = s9 >> 21; - s10 += carry9; - s9 -= shl64(carry9, 21); - carry10 = s10 >> 21; - s11 += carry10; - s10 -= shl64(carry10, 21); - carry11 = s11 >> 21; - s12 += carry11; - s11 -= shl64(carry11, 21); - s0 += s12 * 666643; - s1 += s12 * 470296; - s2 += s12 * 654183; - s3 -= s12 * 997805; - s4 += s12 * 136657; - s5 -= s12 * 683901; - carry0 = s0 >> 21; - s1 += carry0; - s0 -= shl64(carry0, 21); - carry1 = s1 >> 21; - s2 += carry1; - s1 -= shl64(carry1, 21); - carry2 = s2 >> 21; - s3 += carry2; - s2 -= shl64(carry2, 21); - carry3 = s3 >> 21; - s4 += carry3; - s3 -= shl64(carry3, 21); - carry4 = s4 >> 21; - s5 += carry4; - s4 -= shl64(carry4, 21); - carry5 = s5 >> 21; - s6 += carry5; - s5 -= shl64(carry5, 21); - carry6 = s6 >> 21; - s7 += carry6; - s6 -= shl64(carry6, 21); - carry7 = s7 >> 21; - s8 += carry7; - s7 -= shl64(carry7, 21); - carry8 = s8 >> 21; - s9 += carry8; - s8 -= shl64(carry8, 21); - carry9 = s9 >> 21; - s10 += carry9; - s9 -= shl64(carry9, 21); - carry10 = s10 >> 21; - s11 += carry10; - s10 -= shl64(carry10, 21); - - s[0] = (unsigned char)(s0 >> 0); - s[1] = (unsigned char)(s0 >> 8); - s[2] = (unsigned char)((s0 >> 16) | shl64(s1, 5)); - s[3] = (unsigned char)(s1 >> 3); - s[4] = (unsigned char)(s1 >> 11); - s[5] = (unsigned char)((s1 >> 19) | shl64(s2, 2)); - s[6] = (unsigned char)(s2 >> 6); - s[7] = (unsigned char)((s2 >> 14) | shl64(s3, 7)); - s[8] = (unsigned char)(s3 >> 1); - s[9] = (unsigned char)(s3 >> 9); - s[10] = (unsigned char)((s3 >> 17) | shl64(s4, 4)); - s[11] = (unsigned char)(s4 >> 4); - s[12] = (unsigned char)(s4 >> 12); - s[13] = (unsigned char)((s4 >> 20) | shl64(s5, 1)); - s[14] = (unsigned char)(s5 >> 7); - s[15] = (unsigned char)((s5 >> 15) | shl64(s6, 6)); - s[16] = (unsigned char)(s6 >> 2); - s[17] = (unsigned char)(s6 >> 10); - s[18] = (unsigned char)((s6 >> 18) | shl64(s7, 3)); - s[19] = (unsigned char)(s7 >> 5); - s[20] = (unsigned char)(s7 >> 13); - s[21] = (unsigned char)(s8 >> 0); - s[22] = (unsigned char)(s8 >> 8); - s[23] = (unsigned char)((s8 >> 16) | shl64(s9, 5)); - s[24] = (unsigned char)(s9 >> 3); - s[25] = (unsigned char)(s9 >> 11); - s[26] = (unsigned char)((s9 >> 19) | shl64(s10, 2)); - s[27] = (unsigned char)(s10 >> 6); - s[28] = (unsigned char)((s10 >> 14) | shl64(s11, 7)); - s[29] = (unsigned char)(s11 >> 1); - s[30] = (unsigned char)(s11 >> 9); - s[31] = (unsigned char)(s11 >> 17); -} diff --git a/src/ed25519/sc.h b/src/ed25519/sc.h deleted file mode 100644 index e29e7fa..0000000 --- a/src/ed25519/sc.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef SC_H -#define SC_H - -/* -The set of scalars is \Z/l -where l = 2^252 + 27742317777372353535851937790883648493. -*/ - -void sc_reduce(unsigned char *s); -void sc_muladd(unsigned char *s, const unsigned char *a, const unsigned char *b, const unsigned char *c); - -#endif diff --git a/src/ed25519/sha512.c b/src/ed25519/sha512.c deleted file mode 100644 index 9cdf94d..0000000 --- a/src/ed25519/sha512.c +++ /dev/null @@ -1,303 +0,0 @@ -/* LibTomCrypt, modular cryptographic library -- Tom St Denis - * - * LibTomCrypt is a library that provides various cryptographic - * algorithms in a highly modular and flexible manner. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -#include "fixedint.h" -#include "sha512.h" - -/* the K array */ -static const uint64_t K[80] = { - UINT64_C(0x428a2f98d728ae22), UINT64_C(0x7137449123ef65cd), - UINT64_C(0xb5c0fbcfec4d3b2f), UINT64_C(0xe9b5dba58189dbbc), - UINT64_C(0x3956c25bf348b538), UINT64_C(0x59f111f1b605d019), - UINT64_C(0x923f82a4af194f9b), UINT64_C(0xab1c5ed5da6d8118), - UINT64_C(0xd807aa98a3030242), UINT64_C(0x12835b0145706fbe), - UINT64_C(0x243185be4ee4b28c), UINT64_C(0x550c7dc3d5ffb4e2), - UINT64_C(0x72be5d74f27b896f), UINT64_C(0x80deb1fe3b1696b1), - UINT64_C(0x9bdc06a725c71235), UINT64_C(0xc19bf174cf692694), - UINT64_C(0xe49b69c19ef14ad2), UINT64_C(0xefbe4786384f25e3), - UINT64_C(0x0fc19dc68b8cd5b5), UINT64_C(0x240ca1cc77ac9c65), - UINT64_C(0x2de92c6f592b0275), UINT64_C(0x4a7484aa6ea6e483), - UINT64_C(0x5cb0a9dcbd41fbd4), UINT64_C(0x76f988da831153b5), - UINT64_C(0x983e5152ee66dfab), UINT64_C(0xa831c66d2db43210), - UINT64_C(0xb00327c898fb213f), UINT64_C(0xbf597fc7beef0ee4), - UINT64_C(0xc6e00bf33da88fc2), UINT64_C(0xd5a79147930aa725), - UINT64_C(0x06ca6351e003826f), UINT64_C(0x142929670a0e6e70), - UINT64_C(0x27b70a8546d22ffc), UINT64_C(0x2e1b21385c26c926), - UINT64_C(0x4d2c6dfc5ac42aed), UINT64_C(0x53380d139d95b3df), - UINT64_C(0x650a73548baf63de), UINT64_C(0x766a0abb3c77b2a8), - UINT64_C(0x81c2c92e47edaee6), UINT64_C(0x92722c851482353b), - UINT64_C(0xa2bfe8a14cf10364), UINT64_C(0xa81a664bbc423001), - UINT64_C(0xc24b8b70d0f89791), UINT64_C(0xc76c51a30654be30), - UINT64_C(0xd192e819d6ef5218), UINT64_C(0xd69906245565a910), - UINT64_C(0xf40e35855771202a), UINT64_C(0x106aa07032bbd1b8), - UINT64_C(0x19a4c116b8d2d0c8), UINT64_C(0x1e376c085141ab53), - UINT64_C(0x2748774cdf8eeb99), UINT64_C(0x34b0bcb5e19b48a8), - UINT64_C(0x391c0cb3c5c95a63), UINT64_C(0x4ed8aa4ae3418acb), - UINT64_C(0x5b9cca4f7763e373), UINT64_C(0x682e6ff3d6b2b8a3), - UINT64_C(0x748f82ee5defb2fc), UINT64_C(0x78a5636f43172f60), - UINT64_C(0x84c87814a1f0ab72), UINT64_C(0x8cc702081a6439ec), - UINT64_C(0x90befffa23631e28), UINT64_C(0xa4506cebde82bde9), - UINT64_C(0xbef9a3f7b2c67915), UINT64_C(0xc67178f2e372532b), - UINT64_C(0xca273eceea26619c), UINT64_C(0xd186b8c721c0c207), - UINT64_C(0xeada7dd6cde0eb1e), UINT64_C(0xf57d4f7fee6ed178), - UINT64_C(0x06f067aa72176fba), UINT64_C(0x0a637dc5a2c898a6), - UINT64_C(0x113f9804bef90dae), UINT64_C(0x1b710b35131c471b), - UINT64_C(0x28db77f523047d84), UINT64_C(0x32caab7b40c72493), - UINT64_C(0x3c9ebe0a15c9bebc), UINT64_C(0x431d67c49c100d4c), - UINT64_C(0x4cc5d4becb3e42b6), UINT64_C(0x597f299cfc657e2a), - UINT64_C(0x5fcb6fab3ad6faec), UINT64_C(0x6c44198c4a475817) -}; - -/* Various logical functions */ - -#define ROR64c(x, y) \ - ( ((((x)&UINT64_C(0xFFFFFFFFFFFFFFFF))>>((uint64_t)(y)&UINT64_C(63))) | \ - ((x)<<((uint64_t)(64-((y)&UINT64_C(63)))))) & UINT64_C(0xFFFFFFFFFFFFFFFF)) - -#define STORE64H(x, y) \ - { (y)[0] = (unsigned char)(((x)>>56)&255); (y)[1] = (unsigned char)(((x)>>48)&255); \ - (y)[2] = (unsigned char)(((x)>>40)&255); (y)[3] = (unsigned char)(((x)>>32)&255); \ - (y)[4] = (unsigned char)(((x)>>24)&255); (y)[5] = (unsigned char)(((x)>>16)&255); \ - (y)[6] = (unsigned char)(((x)>>8)&255); (y)[7] = (unsigned char)((x)&255); } - -#define LOAD64H(x, y) \ - { x = (((uint64_t)((y)[0] & 255))<<56)|(((uint64_t)((y)[1] & 255))<<48) | \ - (((uint64_t)((y)[2] & 255))<<40)|(((uint64_t)((y)[3] & 255))<<32) | \ - (((uint64_t)((y)[4] & 255))<<24)|(((uint64_t)((y)[5] & 255))<<16) | \ - (((uint64_t)((y)[6] & 255))<<8)|(((uint64_t)((y)[7] & 255))); } - - -#define Ch(x,y,z) (z ^ (x & (y ^ z))) -#define Maj(x,y,z) (((x | y) & z) | (x & y)) -#define S(x, n) ROR64c(x, n) -#define R(x, n) (((x) &UINT64_C(0xFFFFFFFFFFFFFFFF))>>((uint64_t)n)) -#define Sigma0(x) (S(x, 28) ^ S(x, 34) ^ S(x, 39)) -#define Sigma1(x) (S(x, 14) ^ S(x, 18) ^ S(x, 41)) -#define Gamma0(x) (S(x, 1) ^ S(x, 8) ^ R(x, 7)) -#define Gamma1(x) (S(x, 19) ^ S(x, 61) ^ R(x, 6)) -#ifndef MIN -#define MIN(x, y) ( ((x)<(y))?(x):(y) ) -#endif - -/* compress 1024-bits */ -static int sha512_compress(sha512_context *md, const unsigned char *buf) { - uint64_t S[8], W[80], t0, t1; - int i; - - /* copy state into S */ - for(i = 0; i < 8; i++) { - S[i] = md->state[i]; - } - - /* copy the state into 1024-bits into W[0..15] */ - for(i = 0; i < 16; i++) { - LOAD64H(W[i], buf + (8 * i)); - } - - /* fill W[16..79] */ - for(i = 16; i < 80; i++) { - W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16]; - } - - /* Compress */ -#define RND(a,b,c,d,e,f,g,h,i) \ - t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i]; \ - t1 = Sigma0(a) + Maj(a, b, c);\ - d += t0; \ - h = t0 + t1; - - for(i = 0; i < 80; i += 8) { - RND(S[0], S[1], S[2], S[3], S[4], S[5], S[6], S[7], i + 0); - RND(S[7], S[0], S[1], S[2], S[3], S[4], S[5], S[6], i + 1); - RND(S[6], S[7], S[0], S[1], S[2], S[3], S[4], S[5], i + 2); - RND(S[5], S[6], S[7], S[0], S[1], S[2], S[3], S[4], i + 3); - RND(S[4], S[5], S[6], S[7], S[0], S[1], S[2], S[3], i + 4); - RND(S[3], S[4], S[5], S[6], S[7], S[0], S[1], S[2], i + 5); - RND(S[2], S[3], S[4], S[5], S[6], S[7], S[0], S[1], i + 6); - RND(S[1], S[2], S[3], S[4], S[5], S[6], S[7], S[0], i + 7); - } - -#undef RND - - - - /* feedback */ - for(i = 0; i < 8; i++) { - md->state[i] = md->state[i] + S[i]; - } - - return 0; -} - - -/** - Initialize the hash state - @param md The hash state you wish to initialize - @return 0 if successful -*/ -int sha512_init(sha512_context *md) { - if(md == NULL) { - return 1; - } - - md->curlen = 0; - md->length = 0; - md->state[0] = UINT64_C(0x6a09e667f3bcc908); - md->state[1] = UINT64_C(0xbb67ae8584caa73b); - md->state[2] = UINT64_C(0x3c6ef372fe94f82b); - md->state[3] = UINT64_C(0xa54ff53a5f1d36f1); - md->state[4] = UINT64_C(0x510e527fade682d1); - md->state[5] = UINT64_C(0x9b05688c2b3e6c1f); - md->state[6] = UINT64_C(0x1f83d9abfb41bd6b); - md->state[7] = UINT64_C(0x5be0cd19137e2179); - - return 0; -} - -/** - Process a block of memory though the hash - @param md The hash state - @param in The data to hash - @param inlen The length of the data (octets) - @return 0 if successful -*/ -int sha512_update(sha512_context *md, const void *vin, size_t inlen) { - const unsigned char *in = vin; - size_t n; - size_t i; - int err; - - if(md == NULL) { - return 1; - } - - if(in == NULL) { - return 1; - } - - if(md->curlen > sizeof(md->buf)) { - return 1; - } - - while(inlen > 0) { - if(md->curlen == 0 && inlen >= 128) { - if((err = sha512_compress(md, in)) != 0) { - return err; - } - - md->length += 128 * 8; - in += 128; - inlen -= 128; - } else { - n = MIN(inlen, (128 - md->curlen)); - - for(i = 0; i < n; i++) { - md->buf[i + md->curlen] = in[i]; - } - - - md->curlen += n; - in += n; - inlen -= n; - - if(md->curlen == 128) { - if((err = sha512_compress(md, md->buf)) != 0) { - return err; - } - - md->length += 8 * 128; - md->curlen = 0; - } - } - } - - return 0; -} - -/** - Terminate the hash to get the digest - @param md The hash state - @param out [out] The destination of the hash (64 bytes) - @return 0 if successful -*/ -int sha512_final(sha512_context *md, void *vout) { - int i; - unsigned char *out = vout; - - if(md == NULL) { - return 1; - } - - if(out == NULL) { - return 1; - } - - if(md->curlen >= sizeof(md->buf)) { - return 1; - } - - /* increase the length of the message */ - md->length += md->curlen * UINT64_C(8); - - /* append the '1' bit */ - md->buf[md->curlen++] = (unsigned char)0x80; - - /* if the length is currently above 112 bytes we append zeros - * then compress. Then we can fall back to padding zeros and length - * encoding like normal. - */ - if(md->curlen > 112) { - while(md->curlen < 128) { - md->buf[md->curlen++] = (unsigned char)0; - } - - sha512_compress(md, md->buf); - md->curlen = 0; - } - - /* pad up to 120 bytes of zeroes - * note: that from 112 to 120 is the 64 MSB of the length. We assume that you won't hash - * > 2^64 bits of data... :-) - */ - while(md->curlen < 120) { - md->buf[md->curlen++] = (unsigned char)0; - } - - /* store length */ - STORE64H(md->length, md->buf + 120); - sha512_compress(md, md->buf); - - /* copy output */ - for(i = 0; i < 8; i++) { - STORE64H(md->state[i], out + (8 * i)); - } - - return 0; -} - -int sha512(const void *message, size_t message_len, void *out) { - sha512_context ctx; - int ret; - - if((ret = sha512_init(&ctx))) { - return ret; - } - - if((ret = sha512_update(&ctx, message, message_len))) { - return ret; - } - - if((ret = sha512_final(&ctx, out))) { - return ret; - } - - return 0; -} diff --git a/src/ed25519/sha512.h b/src/ed25519/sha512.h deleted file mode 100644 index 95461ce..0000000 --- a/src/ed25519/sha512.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef SHA512_H -#define SHA512_H - -#include - -#include "fixedint.h" - -/* state */ -typedef struct sha512_context_ { - uint64_t length, state[8]; - size_t curlen; - unsigned char buf[128]; -} sha512_context; - - -int sha512_init(sha512_context *md); -int sha512_final(sha512_context *md, void *out); -int sha512_update(sha512_context *md, const void *in, size_t inlen); -int sha512(const void *message, size_t message_len, void *out); - -#endif diff --git a/src/ed25519/sign.c b/src/ed25519/sign.c deleted file mode 100644 index 0c4eea9..0000000 --- a/src/ed25519/sign.c +++ /dev/null @@ -1,31 +0,0 @@ -#include "ed25519.h" -#include "sha512.h" -#include "ge.h" -#include "sc.h" - - -void ed25519_sign(unsigned char *signature, const unsigned char *message, size_t message_len, const unsigned char *public_key, const unsigned char *private_key) { - sha512_context hash; - unsigned char hram[64]; - unsigned char r[64]; - ge_p3 R; - - - sha512_init(&hash); - sha512_update(&hash, private_key + 32, 32); - sha512_update(&hash, message, message_len); - sha512_final(&hash, r); - - sc_reduce(r); - ge_scalarmult_base(&R, r); - ge_p3_tobytes(signature, &R); - - sha512_init(&hash); - sha512_update(&hash, signature, 32); - sha512_update(&hash, public_key, 32); - sha512_update(&hash, message, message_len); - sha512_final(&hash, hram); - - sc_reduce(hram); - sc_muladd(signature + 32, hram, private_key, r); -} diff --git a/src/ed25519/verify.c b/src/ed25519/verify.c deleted file mode 100644 index 415e94f..0000000 --- a/src/ed25519/verify.c +++ /dev/null @@ -1,77 +0,0 @@ -#include "ed25519.h" -#include "sha512.h" -#include "ge.h" -#include "sc.h" - -static int consttime_equal(const unsigned char *x, const unsigned char *y) { - unsigned char r = 0; - - r = x[0] ^ y[0]; -#define F(i) r |= x[i] ^ y[i] - F(1); - F(2); - F(3); - F(4); - F(5); - F(6); - F(7); - F(8); - F(9); - F(10); - F(11); - F(12); - F(13); - F(14); - F(15); - F(16); - F(17); - F(18); - F(19); - F(20); - F(21); - F(22); - F(23); - F(24); - F(25); - F(26); - F(27); - F(28); - F(29); - F(30); - F(31); -#undef F - - return !r; -} - -int ed25519_verify(const unsigned char *signature, const unsigned char *message, size_t message_len, const unsigned char *public_key) { - unsigned char h[64]; - unsigned char checker[32]; - sha512_context hash; - ge_p3 A; - ge_p2 R; - - if(signature[63] & 224) { - return 0; - } - - if(ge_frombytes_negate_vartime(&A, public_key) != 0) { - return 0; - } - - sha512_init(&hash); - sha512_update(&hash, signature, 32); - sha512_update(&hash, public_key, 32); - sha512_update(&hash, message, message_len); - sha512_final(&hash, h); - - sc_reduce(h); - ge_double_scalarmult_vartime(&R, h, &A, signature + 32); - ge_tobytes(checker, &R); - - if(!consttime_equal(checker, signature)) { - return 0; - } - - return 1; -} diff --git a/src/edge.c b/src/edge.c index 5491d8a..c30d6cc 100644 --- a/src/edge.c +++ b/src/edge.c @@ -1,6 +1,6 @@ /* edge.c -- edge tree management - Copyright (C) 2000-2013 Guus Sliepen , + Copyright (C) 2000-2006 Guus Sliepen , 2000-2005 Ivo Timmermans This program is free software; you can redistribute it and/or modify @@ -20,8 +20,7 @@ #include "system.h" -#include "splay_tree.h" -#include "control_common.h" +#include "avl_tree.h" #include "edge.h" #include "logger.h" #include "netutl.h" @@ -29,7 +28,7 @@ #include "utils.h" #include "xalloc.h" -splay_tree_t *edge_weight_tree; +avl_tree_t *edge_weight_tree; /* Tree with all edges, sorted on weight */ static int edge_compare(const edge_t *a, const edge_t *b) { return strcmp(a->to->name, b->to->name); @@ -54,37 +53,36 @@ static int edge_weight_compare(const edge_t *a, const edge_t *b) { } void init_edges(void) { - edge_weight_tree = splay_alloc_tree((splay_compare_t) edge_weight_compare, NULL); + edge_weight_tree = avl_alloc_tree((avl_compare_t) edge_weight_compare, NULL); } -splay_tree_t *new_edge_tree(void) { - return splay_alloc_tree((splay_compare_t) edge_compare, (splay_action_t) free_edge); +avl_tree_t *new_edge_tree(void) { + return avl_alloc_tree((avl_compare_t) edge_compare, (avl_action_t) free_edge); } -void free_edge_tree(splay_tree_t *edge_tree) { - splay_delete_tree(edge_tree); +void free_edge_tree(avl_tree_t *edge_tree) { + avl_delete_tree(edge_tree); } void exit_edges(void) { - splay_delete_tree(edge_weight_tree); + avl_delete_tree(edge_weight_tree); } /* Creation and deletion of connection elements */ edge_t *new_edge(void) { - return xzalloc(sizeof(edge_t)); + return xmalloc_and_zero(sizeof(edge_t)); } void free_edge(edge_t *e) { sockaddrfree(&e->address); - sockaddrfree(&e->local_address); free(e); } void edge_add(edge_t *e) { - splay_insert(edge_weight_tree, e); - splay_insert(e->from->edge_tree, e); + avl_insert(edge_weight_tree, e); + avl_insert(e->from->edge_tree, e); e->reverse = lookup_edge(e->to, e->from); @@ -98,8 +96,8 @@ void edge_del(edge_t *e) { e->reverse->reverse = NULL; } - splay_delete(edge_weight_tree, e); - splay_delete(e->from->edge_tree, e); + avl_delete(edge_weight_tree, e); + avl_delete(e->from->edge_tree, e); } edge_t *lookup_edge(node_t *from, node_t *to) { @@ -108,22 +106,28 @@ edge_t *lookup_edge(node_t *from, node_t *to) { v.from = from; v.to = to; - return splay_search(from->edge_tree, &v); + return avl_search(from->edge_tree, &v); } -bool dump_edges(connection_t *c) { - for splay_each(node_t, n, node_tree) { - for splay_each(edge_t, e, n->edge_tree) { - char *address = sockaddr2hostname(&e->address); - char *local_address = sockaddr2hostname(&e->local_address); - send_request(c, "%d %d %s %s %s %s %x %d", - CONTROL, REQ_DUMP_EDGES, - e->from->name, e->to->name, address, - local_address, e->options, e->weight); +void dump_edges(void) { + avl_node_t *node, *node2; + node_t *n; + edge_t *e; + char *address; + + logger(LOG_DEBUG, "Edges:"); + + for(node = node_tree->head; node; node = node->next) { + n = node->data; + + for(node2 = n->edge_tree->head; node2; node2 = node2->next) { + e = node2->data; + address = sockaddr2hostname(&e->address); + logger(LOG_DEBUG, " %s to %s at %s options %x weight %d", + e->from->name, e->to->name, address, e->options, e->weight); free(address); - free(local_address); } } - return send_request(c, "%d %d", CONTROL, REQ_DUMP_EDGES); + logger(LOG_DEBUG, "End of edges."); } diff --git a/src/edge.h b/src/edge.h index 032acbc..a7a6302 100644 --- a/src/edge.h +++ b/src/edge.h @@ -3,7 +3,7 @@ /* edge.h -- header for edge.c - Copyright (C) 2001-2012 Guus Sliepen , + Copyright (C) 2001-2006 Guus Sliepen , 2001-2005 Ivo Timmermans This program is free software; you can redistribute it and/or modify @@ -21,7 +21,7 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#include "splay_tree.h" +#include "avl_tree.h" #include "connection.h" #include "net.h" #include "node.h" @@ -30,26 +30,25 @@ typedef struct edge_t { struct node_t *from; struct node_t *to; sockaddr_t address; - sockaddr_t local_address; - uint32_t options; /* options turned on for this edge */ - int weight; /* weight of this edge */ + uint32_t options; /* options turned on for this edge */ + int weight; /* weight of this edge */ - struct connection_t *connection; /* connection associated with this edge, if available */ - struct edge_t *reverse; /* edge in the opposite direction, if available */ + struct connection_t *connection; /* connection associated with this edge, if available */ + struct edge_t *reverse; /* edge in the opposite direction, if available */ } edge_t; -extern splay_tree_t *edge_weight_tree; /* Tree with all known edges sorted on weight */ +extern avl_tree_t *edge_weight_tree; /* Tree with all known edges sorted on weight */ extern void init_edges(void); extern void exit_edges(void); extern edge_t *new_edge(void) __attribute__((__malloc__)); extern void free_edge(edge_t *e); -extern splay_tree_t *new_edge_tree(void) __attribute__((__malloc__)); -extern void free_edge_tree(splay_tree_t *edge_tree); +extern avl_tree_t *new_edge_tree(void) __attribute__((__malloc__)); +extern void free_edge_tree(avl_tree_t *edge_tree); extern void edge_add(edge_t *e); extern void edge_del(edge_t *e); extern edge_t *lookup_edge(struct node_t *from, struct node_t *to); -extern bool dump_edges(struct connection_t *c); +extern void dump_edges(void); #endif diff --git a/src/ethernet.h b/src/ethernet.h index 8bfbd71..32f5553 100644 --- a/src/ethernet.h +++ b/src/ethernet.h @@ -25,15 +25,6 @@ #define ETH_ALEN 6 #endif -#ifndef ETH_HLEN -#define ETH_HLEN 14 -#endif - -#ifndef ETHER_TYPE_LEN -#define ETHER_TYPE_LEN 2 -#endif - - #ifndef ARPHRD_ETHER #define ARPHRD_ETHER 1 #endif @@ -54,16 +45,12 @@ #define ETH_P_8021Q 0x8100 #endif -#ifndef ETH_P_MAX -#define ETH_P_MAX 0xFFFF -#endif - #ifndef HAVE_STRUCT_ETHER_HEADER struct ether_header { uint8_t ether_dhost[ETH_ALEN]; uint8_t ether_shost[ETH_ALEN]; uint16_t ether_type; -} __attribute__((__gcc_struct__, __packed__)); +} __attribute__((__packed__)); #endif #ifndef HAVE_STRUCT_ARPHDR @@ -73,7 +60,7 @@ struct arphdr { uint8_t ar_hln; uint8_t ar_pln; uint16_t ar_op; -} __attribute__((__gcc_struct__, __packed__)); +} __attribute__((__packed__)); #define ARPOP_REQUEST 1 #define ARPOP_REPLY 2 @@ -91,7 +78,7 @@ struct ether_arp { uint8_t arp_spa[4]; uint8_t arp_tha[ETH_ALEN]; uint8_t arp_tpa[4]; -} __attribute__((__gcc_struct__, __packed__)); +} __attribute__((__packed__)); #define arp_hrd ea_hdr.ar_hrd #define arp_pro ea_hdr.ar_pro #define arp_hln ea_hdr.ar_hln diff --git a/src/event.c b/src/event.c index 47adb18..1223222 100644 --- a/src/event.c +++ b/src/event.c @@ -1,6 +1,7 @@ /* - event.c -- I/O, timeout and signal event handling - Copyright (C) 2012-2013 Guus Sliepen + event.c -- event queue + Copyright (C) 2002-2009 Guus Sliepen , + 2002-2005 Ivo Timmermans This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -19,471 +20,102 @@ #include "system.h" -#include "dropin.h" +#include "avl_tree.h" #include "event.h" -#include "net.h" #include "utils.h" #include "xalloc.h" -struct timeval now; +avl_tree_t *event_tree; +extern time_t now; -#ifndef HAVE_MINGW -static fd_set readfds; -static fd_set writefds; -#else -static const long READ_EVENTS = FD_READ | FD_ACCEPT | FD_CLOSE; -static const long WRITE_EVENTS = FD_WRITE | FD_CONNECT; -static DWORD event_count = 0; -#endif -static bool running; +static int id; -static int io_compare(const io_t *a, const io_t *b) { -#ifndef HAVE_MINGW - return a->fd - b->fd; -#else - - if(a->event < b->event) { - return -1; - } - - if(a->event > b->event) { +static int event_compare(const event_t *a, const event_t *b) { + if(a->time > b->time) { return 1; } - return 0; -#endif -} - -static int timeout_compare(const timeout_t *a, const timeout_t *b) { - struct timeval diff; - timersub(&a->tv, &b->tv, &diff); - - if(diff.tv_sec < 0) { + if(a->time < b->time) { return -1; } - if(diff.tv_sec > 0) { - return 1; - } - - if(diff.tv_usec < 0) { - return -1; - } - - if(diff.tv_usec > 0) { - return 1; - } - - if(a < b) { - return -1; - } - - if(a > b) { - return 1; - } - - return 0; + return a->id - b->id; } -static splay_tree_t io_tree = {.compare = (splay_compare_t)io_compare}; -static splay_tree_t timeout_tree = {.compare = (splay_compare_t)timeout_compare}; +void init_events(void) { + event_tree = avl_alloc_tree((avl_compare_t) event_compare, (avl_action_t) free_event); +} -void io_add(io_t *io, io_cb_t cb, void *data, int fd, int flags) { - if(io->cb) { +void exit_events(void) { + avl_delete_tree(event_tree); +} + +void expire_events(void) { + avl_node_t *node; + event_t *event; + time_t diff; + + /* + * Make all events appear expired by subtracting the difference between + * the expiration time of the last event and the current time. + */ + + if(!event_tree->tail) { return; } - io->fd = fd; -#ifdef HAVE_MINGW + event = event_tree->tail->data; - if(io->fd != -1) { - io->event = WSACreateEvent(); - - if(io->event == WSA_INVALID_EVENT) { - abort(); - } - } - - event_count++; -#endif - io->cb = cb; - io->data = data; - io->node.data = io; - - io_set(io, flags); - - if(!splay_insert_node(&io_tree, &io->node)) { - abort(); - } -} - -#ifdef HAVE_MINGW -void io_add_event(io_t *io, io_cb_t cb, void *data, WSAEVENT event) { - io->event = event; - io_add(io, cb, data, -1, 0); -} -#endif - -void io_set(io_t *io, int flags) { - if(flags == io->flags) { + if(event->time <= now) { return; } - io->flags = flags; + diff = event->time - now; - if(io->fd == -1) { - return; - } - -#ifndef HAVE_MINGW - - if(flags & IO_READ) { - FD_SET(io->fd, &readfds); - } else { - FD_CLR(io->fd, &readfds); - } - - if(flags & IO_WRITE) { - FD_SET(io->fd, &writefds); - } else { - FD_CLR(io->fd, &writefds); - } - -#else - long events = 0; - - if(flags & IO_WRITE) { - events |= WRITE_EVENTS; - } - - if(flags & IO_READ) { - events |= READ_EVENTS; - } - - if(WSAEventSelect(io->fd, io->event, events) != 0) { - abort(); - } - -#endif -} - -void io_del(io_t *io) { - if(!io->cb) { - return; - } - - io_set(io, 0); -#ifdef HAVE_MINGW - - if(io->fd != -1 && WSACloseEvent(io->event) == FALSE) { - abort(); - } - - event_count--; -#endif - - splay_unlink_node(&io_tree, &io->node); - io->cb = NULL; -} - -void timeout_add(timeout_t *timeout, timeout_cb_t cb, void *data, struct timeval *tv) { - timeout->cb = cb; - timeout->data = data; - timeout->node.data = timeout; - - timeout_set(timeout, tv); -} - -void timeout_set(timeout_t *timeout, struct timeval *tv) { - if(timerisset(&timeout->tv)) { - splay_unlink_node(&timeout_tree, &timeout->node); - } - - if(!now.tv_sec) { - gettimeofday(&now, NULL); - } - - timeradd(&now, tv, &timeout->tv); - - if(!splay_insert_node(&timeout_tree, &timeout->node)) { - abort(); + for(node = event_tree->head; node; node = node->next) { + event = node->data; + event->time -= diff; } } -void timeout_del(timeout_t *timeout) { - if(!timeout->cb) { - return; - } - - splay_unlink_node(&timeout_tree, &timeout->node); - timeout->cb = 0; - timeout->tv = (struct timeval) { - 0, 0 - }; +event_t *new_event(void) { + return xmalloc_and_zero(sizeof(event_t)); } -#ifndef HAVE_MINGW -static int signal_compare(const signal_t *a, const signal_t *b) { - return a->signum - b->signum; +void free_event(event_t *event) { + free(event); } -static io_t signalio; -static int pipefd[2] = {-1, -1}; -static splay_tree_t signal_tree = {.compare = (splay_compare_t)signal_compare}; - -static void signal_handler(int signum) { - unsigned char num = signum; - write(pipefd[1], &num, 1); +void event_add(event_t *event) { + event->id = ++id; + avl_insert(event_tree, event); } -static void signalio_handler(void *data, int flags) { - (void)data; - (void)flags; - unsigned char signum; - - if(read(pipefd[0], &signum, 1) != 1) { - return; - } - - signal_t *sig = splay_search(&signal_tree, &((signal_t) { - .signum = signum - })); - - if(sig) { - sig->cb(sig->data); - } +void event_del(event_t *event) { + avl_delete(event_tree, event); } -static void pipe_init(void) { - if(!pipe(pipefd)) { - io_add(&signalio, signalio_handler, NULL, pipefd[0], IO_READ); - } -} +event_t *get_expired_event(void) { + event_t *event; -void signal_add(signal_t *sig, signal_cb_t cb, void *data, int signum) { - if(sig->cb) { - return; - } + if(event_tree->head) { + event = event_tree->head->data; - sig->cb = cb; - sig->data = data; - sig->signum = signum; - sig->node.data = sig; - - if(pipefd[0] == -1) { - pipe_init(); - } - - signal(sig->signum, signal_handler); - - if(!splay_insert_node(&signal_tree, &sig->node)) { - abort(); - } -} - -void signal_del(signal_t *sig) { - if(!sig->cb) { - return; - } - - signal(sig->signum, SIG_DFL); - - splay_unlink_node(&signal_tree, &sig->node); - sig->cb = NULL; -} -#endif - -static struct timeval *get_time_remaining(struct timeval *diff) { - gettimeofday(&now, NULL); - struct timeval *tv = NULL; - - while(timeout_tree.head) { - timeout_t *timeout = timeout_tree.head->data; - timersub(&timeout->tv, &now, diff); - - if(diff->tv_sec < 0) { - timeout->cb(timeout->data); - - if(timercmp(&timeout->tv, &now, <)) { - timeout_del(timeout); - } - } else { - tv = diff; - break; + if(event->time <= now) { + avl_node_t *node = event_tree->head; + avl_unlink_node(event_tree, node); + free(node); + return event; } } - return tv; + return NULL; } -bool event_loop(void) { - running = true; - -#ifndef HAVE_MINGW - fd_set readable; - fd_set writable; - - while(running) { - struct timeval diff; - struct timeval *tv = get_time_remaining(&diff); - memcpy(&readable, &readfds, sizeof(readable)); - memcpy(&writable, &writefds, sizeof(writable)); - - int fds = 0; - - if(io_tree.tail) { - io_t *last = io_tree.tail->data; - fds = last->fd + 1; - } - - int n = select(fds, &readable, &writable, NULL, tv); - - if(n < 0) { - if(sockwouldblock(sockerrno)) { - continue; - } else { - return false; - } - } - - if(!n) { - continue; - } - - unsigned int curgen = io_tree.generation; - - for splay_each(io_t, io, &io_tree) { - if(FD_ISSET(io->fd, &writable)) { - io->cb(io->data, IO_WRITE); - } else if(FD_ISSET(io->fd, &readable)) { - io->cb(io->data, IO_READ); - } else { - continue; - } - - /* - There are scenarios in which the callback will remove another io_t from the tree - (e.g. closing a double connection). Since splay_each does not support that, we - need to exit the loop if that happens. That's okay, since any remaining events will - get picked up by the next select() call. - */ - if(curgen != io_tree.generation) { - break; - } - } +event_t *peek_next_event(void) { + if(event_tree->head) { + return event_tree->head->data; } -#else - - while(running) { - struct timeval diff; - struct timeval *tv = get_time_remaining(&diff); - DWORD timeout_ms = tv ? (tv->tv_sec * 1000 + tv->tv_usec / 1000 + 1) : WSA_INFINITE; - - if(!event_count) { - Sleep(timeout_ms); - continue; - } - - /* - For some reason, Microsoft decided to make the FD_WRITE event edge-triggered instead of level-triggered, - which is the opposite of what select() does. In practice, that means that if a FD_WRITE event triggers, - it will never trigger again until a send() returns EWOULDBLOCK. Since the semantics of this event loop - is that write events are level-triggered (i.e. they continue firing until the socket is full), we need - to emulate these semantics by making sure we fire each IO_WRITE that is still writeable. - - Note that technically FD_CLOSE has the same problem, but it's okay because user code does not rely on - this event being fired again if ignored. - */ - unsigned int curgen = io_tree.generation; - - for splay_each(io_t, io, &io_tree) { - if(io->flags & IO_WRITE && send(io->fd, NULL, 0, 0) == 0) { - io->cb(io->data, IO_WRITE); - - if(curgen != io_tree.generation) { - break; - } - } - } - - if(event_count > WSA_MAXIMUM_WAIT_EVENTS) { - WSASetLastError(WSA_INVALID_PARAMETER); - return(false); - } - - WSAEVENT events[WSA_MAXIMUM_WAIT_EVENTS]; - io_t *io_map[WSA_MAXIMUM_WAIT_EVENTS]; - DWORD event_index = 0; - - for splay_each(io_t, io, &io_tree) { - events[event_index] = io->event; - io_map[event_index] = io; - event_index++; - } - - /* - * If the generation number changes due to event addition - * or removal by a callback we restart the loop. - */ - curgen = io_tree.generation; - - for(DWORD event_offset = 0; event_offset < event_count;) { - DWORD result = WSAWaitForMultipleEvents(event_count - event_offset, &events[event_offset], FALSE, timeout_ms, FALSE); - - if(result == WSA_WAIT_TIMEOUT) { - break; - } - - if(result < WSA_WAIT_EVENT_0 || result >= WSA_WAIT_EVENT_0 + event_count - event_offset) { - return(false); - } - - /* Look up io in the map by index. */ - event_index = result - WSA_WAIT_EVENT_0 + event_offset; - io_t *io = io_map[event_index]; - - if(io->fd == -1) { - io->cb(io->data, 0); - - if(curgen != io_tree.generation) { - break; - } - } else { - WSANETWORKEVENTS network_events; - - if(WSAEnumNetworkEvents(io->fd, io->event, &network_events) != 0) { - return(false); - } - - if(network_events.lNetworkEvents & READ_EVENTS) { - io->cb(io->data, IO_READ); - - if(curgen != io_tree.generation) { - break; - } - } - - /* - The fd might be available for write too. However, if we already fired the read callback, that - callback might have deleted the io (e.g. through terminate_connection()), so we can't fire the - write callback here. Instead, we loop back and let the writable io loop above handle it. - */ - } - - /* Continue checking the rest of the events. */ - event_offset = event_index + 1; - - /* Just poll the next time through. */ - timeout_ms = 0; - } - } - -#endif - - return true; -} - -void event_exit(void) { - running = false; + return NULL; } diff --git a/src/event.h b/src/event.h index 7adaf85..6d521bb 100644 --- a/src/event.h +++ b/src/event.h @@ -2,8 +2,9 @@ #define TINC_EVENT_H /* - event.h -- I/O, timeout and signal event handling - Copyright (C) 2012-2013 Guus Sliepen + event.h -- header for event.c + Copyright (C) 2002-2009 Guus Sliepen , + 2002-2005 Ivo Timmermans 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 @@ -20,57 +21,27 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#include "splay_tree.h" +#include "avl_tree.h" -#define IO_READ 1 -#define IO_WRITE 2 +extern avl_tree_t *event_tree; -typedef void (*io_cb_t)(void *data, int flags); -typedef void (*timeout_cb_t)(void *data); -typedef void (*signal_cb_t)(void *data); +typedef void (*event_handler_t)(void *); -typedef struct io_t { - int fd; - int flags; -#ifdef HAVE_MINGW - WSAEVENT event; -#endif - io_cb_t cb; +typedef struct event { + time_t time; + int id; + event_handler_t handler; void *data; - splay_node_t node; -} io_t; +} event_t; -typedef struct timeout_t { - struct timeval tv; - timeout_cb_t cb; - void *data; - splay_node_t node; -} timeout_t; - -typedef struct signal_t { - int signum; - signal_cb_t cb; - void *data; - splay_node_t node; -} signal_t; - -extern struct timeval now; - -extern void io_add(io_t *io, io_cb_t cb, void *data, int fd, int flags); -#ifdef HAVE_MINGW -extern void io_add_event(io_t *io, io_cb_t cb, void *data, WSAEVENT event); -#endif -extern void io_del(io_t *io); -extern void io_set(io_t *io, int flags); - -extern void timeout_add(timeout_t *timeout, timeout_cb_t cb, void *data, struct timeval *tv); -extern void timeout_del(timeout_t *timeout); -extern void timeout_set(timeout_t *timeout, struct timeval *tv); - -extern void signal_add(signal_t *sig, signal_cb_t cb, void *data, int signum); -extern void signal_del(signal_t *sig); - -extern bool event_loop(void); -extern void event_exit(void); +extern void init_events(void); +extern void exit_events(void); +extern void expire_events(void); +extern event_t *new_event(void) __attribute__((__malloc__)); +extern void free_event(event_t *event); +extern void event_add(event_t *event); +extern void event_del(event_t *event); +extern event_t *get_expired_event(void); +extern event_t *peek_next_event(void); #endif diff --git a/src/fake-getaddrinfo.c b/src/fake-getaddrinfo.c new file mode 100644 index 0000000..1ee11c5 --- /dev/null +++ b/src/fake-getaddrinfo.c @@ -0,0 +1,108 @@ +/* + * fake library for ssh + * + * This file includes getaddrinfo(), freeaddrinfo() and gai_strerror(). + * These functions are defined in rfc2133. + * + * But these functions are not implemented correctly. The minimum subset + * is implemented for ssh use only. For example, this routine assumes + * that ai_family is AF_INET. Don't use it for another purpose. + */ + +#include "system.h" + +#include "ipv4.h" +#include "ipv6.h" +#include "fake-getaddrinfo.h" +#include "xalloc.h" + +#if !HAVE_DECL_GAI_STRERROR +char *gai_strerror(int ecode) { + switch(ecode) { + case EAI_NODATA: + return "No address associated with hostname"; + + case EAI_MEMORY: + return "Memory allocation failure"; + + case EAI_FAMILY: + return "Address family not supported"; + + default: + return "Unknown error"; + } +} +#endif /* !HAVE_GAI_STRERROR */ + +#if !HAVE_DECL_FREEADDRINFO +void freeaddrinfo(struct addrinfo *ai) { + struct addrinfo *next; + + while(ai) { + next = ai->ai_next; + free(ai); + ai = next; + } +} +#endif /* !HAVE_FREEADDRINFO */ + +#if !HAVE_DECL_GETADDRINFO +static struct addrinfo *malloc_ai(uint16_t port, uint32_t addr) { + struct addrinfo *ai; + + ai = xmalloc_and_zero(sizeof(struct addrinfo) + sizeof(struct sockaddr_in)); + + ai->ai_addr = (struct sockaddr *)(ai + 1); + ai->ai_addrlen = sizeof(struct sockaddr_in); + ai->ai_addr->sa_family = ai->ai_family = AF_INET; + + ((struct sockaddr_in *)(ai)->ai_addr)->sin_port = port; + ((struct sockaddr_in *)(ai)->ai_addr)->sin_addr.s_addr = addr; + + return ai; +} + +int getaddrinfo(const char *hostname, const char *servname, const struct addrinfo *hints, struct addrinfo **res) { + struct addrinfo *prev = NULL; + struct hostent *hp; + struct in_addr in = {0}; + int i; + uint16_t port = 0; + + if(hints && hints->ai_family != AF_INET && hints->ai_family != AF_UNSPEC) { + return EAI_FAMILY; + } + + if(servname) { + port = htons(atoi(servname)); + } + + if(hints && hints->ai_flags & AI_PASSIVE) { + *res = malloc_ai(port, htonl(0x00000000)); + return 0; + } + + if(!hostname) { + *res = malloc_ai(port, htonl(0x7f000001)); + return 0; + } + + hp = gethostbyname(hostname); + + if(!hp || !hp->h_addr_list || !hp->h_addr_list[0]) { + return EAI_NODATA; + } + + for(i = 0; hp->h_addr_list[i]; i++) { + *res = malloc_ai(port, ((struct in_addr *)hp->h_addr_list[i])->s_addr); + + if(prev) { + prev->ai_next = *res; + } + + prev = *res; + } + + return 0; +} +#endif /* !HAVE_GETADDRINFO */ diff --git a/src/fake-getaddrinfo.h b/src/fake-getaddrinfo.h new file mode 100644 index 0000000..f10cb83 --- /dev/null +++ b/src/fake-getaddrinfo.h @@ -0,0 +1,57 @@ +#ifndef TINC_FAKE_GETADDRINFO_H +#define TINC_FAKE_GETADDRINFO_H + +#ifndef EAI_NODATA +#define EAI_NODATA 1 +#endif + +#ifndef EAI_MEMORY +#define EAI_MEMORY 2 +#endif + +#ifndef EAI_FAMILY +#define EAI_FAMILY 3 +#endif + +#ifndef AI_PASSIVE +# define AI_PASSIVE 1 +# define AI_CANONNAME 2 +#endif + +#ifndef NI_NUMERICHOST +# define NI_NUMERICHOST 2 +# define NI_NAMEREQD 4 +# define NI_NUMERICSERV 8 +#endif + +#ifndef AI_NUMERICHOST +#define AI_NUMERICHOST 4 +#endif + +#ifndef HAVE_STRUCT_ADDRINFO +struct addrinfo { + int ai_flags; /* AI_PASSIVE, AI_CANONNAME */ + int ai_family; /* PF_xxx */ + int ai_socktype; /* SOCK_xxx */ + int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */ + size_t ai_addrlen; /* length of ai_addr */ + char *ai_canonname; /* canonical name for hostname */ + struct sockaddr *ai_addr; /* binary address */ + struct addrinfo *ai_next; /* next structure in linked list */ +}; +#endif /* !HAVE_STRUCT_ADDRINFO */ + +#if !HAVE_DECL_GETADDRINFO +int getaddrinfo(const char *hostname, const char *servname, + const struct addrinfo *hints, struct addrinfo **res); +#endif /* !HAVE_GETADDRINFO */ + +#if !HAVE_DECL_GAI_STRERROR +char *gai_strerror(int ecode); +#endif /* !HAVE_GAI_STRERROR */ + +#if !HAVE_DECL_FREEADDRINFO +void freeaddrinfo(struct addrinfo *ai); +#endif /* !HAVE_FREEADDRINFO */ + +#endif diff --git a/src/fake-getnameinfo.c b/src/fake-getnameinfo.c new file mode 100644 index 0000000..e51bce2 --- /dev/null +++ b/src/fake-getnameinfo.c @@ -0,0 +1,64 @@ +/* + * fake library for ssh + * + * This file includes getnameinfo(). + * These functions are defined in rfc2133. + * + * But these functions are not implemented correctly. The minimum subset + * is implemented for ssh use only. For example, this routine assumes + * that ai_family is AF_INET. Don't use it for another purpose. + */ + +#include "system.h" + +#include "fake-getnameinfo.h" +#include "fake-getaddrinfo.h" + +#if !HAVE_DECL_GETNAMEINFO + +int getnameinfo(const struct sockaddr *sa, size_t salen, char *host, size_t hostlen, char *serv, size_t servlen, int flags) { + struct sockaddr_in *sin = (struct sockaddr_in *)sa; + struct hostent *hp; + int len; + + if(sa->sa_family != AF_INET) { + return EAI_FAMILY; + } + + if(serv && servlen) { + len = snprintf(serv, servlen, "%d", ntohs(sin->sin_port)); + + if(len < 0 || len >= servlen) { + return EAI_MEMORY; + } + } + + if(!host || !hostlen) { + return 0; + } + + if(flags & NI_NUMERICHOST) { + len = snprintf(host, hostlen, "%s", inet_ntoa(sin->sin_addr)); + + if(len < 0 || len >= hostlen) { + return EAI_MEMORY; + } + + return 0; + } + + hp = gethostbyaddr((char *)&sin->sin_addr, sizeof(struct in_addr), AF_INET); + + if(!hp || !hp->h_name || !hp->h_name[0]) { + return EAI_NODATA; + } + + len = snprintf(host, hostlen, "%s", hp->h_name); + + if(len < 0 || len >= hostlen) { + return EAI_MEMORY; + } + + return 0; +} +#endif /* !HAVE_GETNAMEINFO */ diff --git a/src/fake-getnameinfo.h b/src/fake-getnameinfo.h new file mode 100644 index 0000000..4f24ad1 --- /dev/null +++ b/src/fake-getnameinfo.h @@ -0,0 +1,16 @@ +#ifndef TINC_FAKE_GETNAMEINFO_H +#define TINC_FAKE_GETNAMEINFO_H + +#if !HAVE_DECL_GETNAMEINFO +int getnameinfo(const struct sockaddr *sa, size_t salen, char *host, + size_t hostlen, char *serv, size_t servlen, int flags); +#endif /* !HAVE_GETNAMEINFO */ + +#ifndef NI_MAXSERV +# define NI_MAXSERV 32 +#endif /* !NI_MAXSERV */ +#ifndef NI_MAXHOST +# define NI_MAXHOST 1025 +#endif /* !NI_MAXHOST */ + +#endif diff --git a/src/fd_device.c b/src/fd_device.c deleted file mode 100644 index afe59bc..0000000 --- a/src/fd_device.c +++ /dev/null @@ -1,125 +0,0 @@ -/* - fd_device.c -- Interaction with Android tun fd - Copyright (C) 2001-2005 Ivo Timmermans, - 2001-2016 Guus Sliepen - 2009 Grzegorz Dymarek - 2016 Pacien TRAN-GIRARD - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include "system.h" -#include "conf.h" -#include "device.h" -#include "ethernet.h" -#include "logger.h" -#include "net.h" -#include "route.h" -#include "utils.h" - -static inline bool check_config(void) { - if(routing_mode == RMODE_SWITCH) { - logger(DEBUG_ALWAYS, LOG_ERR, "Switch mode not supported (requires unsupported TAP device)!"); - return false; - } - - if(!get_config_int(lookup_config(config_tree, "Device"), &device_fd)) { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not read fd from configuration!"); - return false; - } - - return true; -} - -static bool setup_device(void) { - if(!check_config()) { - return false; - } - - if(device_fd < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not open %s: %s!", device, strerror(errno)); - return false; - } - - logger(DEBUG_ALWAYS, LOG_INFO, "fd/%d adapter set up.", device_fd); - - return true; -} - -static void close_device(void) { - close(device_fd); - device_fd = -1; -} - -static inline uint16_t get_ip_ethertype(vpn_packet_t *packet) { - switch(DATA(packet)[ETH_HLEN] >> 4) { - case 4: - return ETH_P_IP; - - case 6: - return ETH_P_IPV6; - - default: - return ETH_P_MAX; - } -} - -static inline void set_etherheader(vpn_packet_t *packet, uint16_t ethertype) { - memset(DATA(packet), 0, ETH_HLEN - ETHER_TYPE_LEN); - - DATA(packet)[ETH_HLEN - ETHER_TYPE_LEN] = (ethertype >> 8) & 0xFF; - DATA(packet)[ETH_HLEN - ETHER_TYPE_LEN + 1] = ethertype & 0xFF; -} - -static bool read_packet(vpn_packet_t *packet) { - int lenin = read(device_fd, DATA(packet) + ETH_HLEN, MTU - ETH_HLEN); - - if(lenin <= 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from fd/%d: %s!", device_fd, strerror(errno)); - return false; - } - - uint16_t ethertype = get_ip_ethertype(packet); - - if(ethertype == ETH_P_MAX) { - logger(DEBUG_TRAFFIC, LOG_ERR, "Unknown IP version while reading packet from fd/%d!", device_fd); - return false; - } - - set_etherheader(packet, ethertype); - packet->len = lenin + ETH_HLEN; - - logger(DEBUG_TRAFFIC, LOG_DEBUG, "Read packet of %d bytes from fd/%d.", packet->len, device_fd); - - return true; -} - -static bool write_packet(vpn_packet_t *packet) { - logger(DEBUG_TRAFFIC, LOG_DEBUG, "Writing packet of %d bytes to fd/%d.", packet->len, device_fd); - - if(write(device_fd, DATA(packet) + ETH_HLEN, packet->len - ETH_HLEN) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error while writing to fd/%d: %s!", device_fd, strerror(errno)); - return false; - } - - return true; -} - -const devops_t fd_devops = { - .setup = setup_device, - .close = close_device, - .read = read_packet, - .write = write_packet, -}; diff --git a/src/fsck.c b/src/fsck.c deleted file mode 100644 index e19f03f..0000000 --- a/src/fsck.c +++ /dev/null @@ -1,603 +0,0 @@ -/* - fsck.c -- Check the configuration files for problems - Copyright (C) 2014 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 - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include "system.h" - -#include "crypto.h" -#include "ecdsa.h" -#include "ecdsagen.h" -#include "fsck.h" -#include "names.h" -#ifndef DISABLE_LEGACY -#include "rsa.h" -#include "rsagen.h" -#endif -#include "tincctl.h" -#include "utils.h" - -static bool ask_fix(void) { - if(force) { - return true; - } - - if(!tty) { - return false; - } - -again: - fprintf(stderr, "Fix y/n? "); - char buf[1024]; - - if(!fgets(buf, sizeof(buf), stdin)) { - tty = false; - return false; - } - - if(buf[0] == 'y' || buf[0] == 'Y') { - return true; - } - - if(buf[0] == 'n' || buf[0] == 'N') { - return false; - } - - goto again; -} - -static void print_tinc_cmd(const char *argv0, const char *format, ...) { - if(confbasegiven) { - fprintf(stderr, "%s -c %s ", argv0, confbase); - } else if(netname) { - fprintf(stderr, "%s -n %s ", argv0, netname); - } else { - fprintf(stderr, "%s ", argv0); - } - - va_list va; - va_start(va, format); - vfprintf(stderr, format, va); - va_end(va); - fputc('\n', stderr); -} - -static int strtailcmp(const char *str, const char *tail) { - size_t slen = strlen(str); - size_t tlen = strlen(tail); - - if(tlen > slen) { - return -1; - } - - return memcmp(str + slen - tlen, tail, tlen); -} - -static void check_conffile(const char *fname, bool server) { - (void)server; - - FILE *f = fopen(fname, "r"); - - if(!f) { - fprintf(stderr, "ERROR: cannot read %s: %s\n", fname, strerror(errno)); - return; - } - - char line[2048]; - int lineno = 0; - bool skip = false; - const int maxvariables = 50; - int count[maxvariables]; - memset(count, 0, sizeof(count)); - - while(fgets(line, sizeof(line), f)) { - if(skip) { - if(!strncmp(line, "-----END", 8)) { - skip = false; - } - - continue; - } else { - if(!strncmp(line, "-----BEGIN", 10)) { - skip = true; - continue; - } - } - - int len; - char *variable, *value, *eol; - variable = value = line; - - lineno++; - - eol = line + strlen(line); - - while(strchr("\t \r\n", *--eol)) { - *eol = '\0'; - } - - if(!line[0] || line[0] == '#') { - continue; - } - - len = strcspn(value, "\t ="); - value += len; - value += strspn(value, "\t "); - - if(*value == '=') { - value++; - value += strspn(value, "\t "); - } - - variable[len] = '\0'; - - bool found = false; - - for(int i = 0; variables[i].name; i++) { - if(strcasecmp(variables[i].name, variable)) { - continue; - } - - found = true; - - if(variables[i].type & VAR_OBSOLETE) { - fprintf(stderr, "WARNING: obsolete variable %s in %s line %d\n", variable, fname, lineno); - } - - if(i < maxvariables) { - count[i]++; - } - } - - if(!found) { - fprintf(stderr, "WARNING: unknown variable %s in %s line %d\n", variable, fname, lineno); - } - - if(!*value) { - fprintf(stderr, "ERROR: no value for variable %s in %s line %d\n", variable, fname, lineno); - } - } - - for(int i = 0; variables[i].name && i < maxvariables; i++) { - if(count[i] > 1 && !(variables[i].type & VAR_MULTIPLE)) { - fprintf(stderr, "WARNING: multiple instances of variable %s in %s\n", variables[i].name, fname); - } - } - - if(ferror(f)) { - fprintf(stderr, "ERROR: while reading %s: %s\n", fname, strerror(errno)); - } - - fclose(f); -} - -int fsck(const char *argv0) { -#ifdef HAVE_MINGW - int uid = 0; -#else - uid_t uid = getuid(); -#endif - - // Check that tinc.conf is readable. - - if(access(tinc_conf, R_OK)) { - fprintf(stderr, "ERROR: cannot read %s: %s\n", tinc_conf, strerror(errno)); - - if(errno == ENOENT) { - fprintf(stderr, "No tinc configuration found. Create a new one with:\n\n"); - print_tinc_cmd(argv0, "init"); - } else if(errno == EACCES) { - if(uid != 0) { - fprintf(stderr, "You are currently not running tinc as root. Use sudo?\n"); - } else { - fprintf(stderr, "Check the permissions of each component of the path %s.\n", tinc_conf); - } - } - - return 1; - } - - char *name = get_my_name(true); - - if(!name) { - fprintf(stderr, "ERROR: tinc cannot run without a valid Name.\n"); - return 1; - } - - // Check for private keys. - // TODO: use RSAPrivateKeyFile and Ed25519PrivateKeyFile variables if present. - - struct stat st; - char fname[PATH_MAX]; - char dname[PATH_MAX]; - -#ifndef DISABLE_LEGACY - rsa_t *rsa_priv = NULL; - snprintf(fname, sizeof(fname), "%s/rsa_key.priv", confbase); - - if(stat(fname, &st)) { - if(errno != ENOENT) { - // Something is seriously wrong here. If we can access the directory with tinc.conf in it, we should certainly be able to stat() an existing file. - fprintf(stderr, "ERROR: cannot read %s: %s\n", fname, strerror(errno)); - fprintf(stderr, "Please correct this error.\n"); - return 1; - } - } else { - FILE *f = fopen(fname, "r"); - - if(!f) { - fprintf(stderr, "ERROR: could not open %s: %s\n", fname, strerror(errno)); - return 1; - } - - rsa_priv = rsa_read_pem_private_key(f); - fclose(f); - - if(!rsa_priv) { - fprintf(stderr, "ERROR: No key or unusable key found in %s.\n", fname); - fprintf(stderr, "You can generate a new RSA key with:\n\n"); - print_tinc_cmd(argv0, "generate-rsa-keys"); - return 1; - } - -#if !defined(HAVE_MINGW) && !defined(HAVE_CYGWIN) - - if(st.st_mode & 077) { - fprintf(stderr, "WARNING: unsafe file permissions on %s.\n", fname); - - if(st.st_uid != uid) { - fprintf(stderr, "You are not running %s as the same uid as %s.\n", argv0, fname); - } else if(ask_fix()) { - if(chmod(fname, st.st_mode & ~077)) { - fprintf(stderr, "ERROR: could not change permissions of %s: %s\n", fname, strerror(errno)); - } else { - fprintf(stderr, "Fixed permissions of %s.\n", fname); - } - } - } - -#endif - } - -#endif - - ecdsa_t *ecdsa_priv = NULL; - snprintf(fname, sizeof(fname), "%s/ed25519_key.priv", confbase); - - if(stat(fname, &st)) { - if(errno != ENOENT) { - // Something is seriously wrong here. If we can access the directory with tinc.conf in it, we should certainly be able to stat() an existing file. - fprintf(stderr, "ERROR: cannot read %s: %s\n", fname, strerror(errno)); - fprintf(stderr, "Please correct this error.\n"); - return 1; - } - } else { - FILE *f = fopen(fname, "r"); - - if(!f) { - fprintf(stderr, "ERROR: could not open %s: %s\n", fname, strerror(errno)); - return 1; - } - - ecdsa_priv = ecdsa_read_pem_private_key(f); - fclose(f); - - if(!ecdsa_priv) { - fprintf(stderr, "ERROR: No key or unusable key found in %s.\n", fname); - fprintf(stderr, "You can generate a new Ed25519 key with:\n\n"); - print_tinc_cmd(argv0, "generate-ed25519-keys"); - return 1; - } - -#if !defined(HAVE_MINGW) && !defined(HAVE_CYGWIN) - - if(st.st_mode & 077) { - fprintf(stderr, "WARNING: unsafe file permissions on %s.\n", fname); - - if(st.st_uid != uid) { - fprintf(stderr, "You are not running %s as the same uid as %s.\n", argv0, fname); - } else if(ask_fix()) { - if(chmod(fname, st.st_mode & ~077)) { - fprintf(stderr, "ERROR: could not change permissions of %s: %s\n", fname, strerror(errno)); - } else { - fprintf(stderr, "Fixed permissions of %s.\n", fname); - } - } - } - -#endif - } - -#ifdef DISABLE_LEGACY - - if(!ecdsa_priv) { - fprintf(stderr, "ERROR: No Ed25519 private key found.\n"); -#else - - if(!rsa_priv && !ecdsa_priv) { - fprintf(stderr, "ERROR: Neither RSA or Ed25519 private key found.\n"); -#endif - fprintf(stderr, "You can generate new keys with:\n\n"); - print_tinc_cmd(argv0, "generate-keys"); - return 1; - } - - // Check for public keys. - // TODO: use RSAPublicKeyFile variable if present. - - snprintf(fname, sizeof(fname), "%s/hosts/%s", confbase, name); - - if(access(fname, R_OK)) { - fprintf(stderr, "WARNING: cannot read %s\n", fname); - } - - FILE *f; - -#ifndef DISABLE_LEGACY - rsa_t *rsa_pub = NULL; - - f = fopen(fname, "r"); - - if(f) { - rsa_pub = rsa_read_pem_public_key(f); - fclose(f); - } - - if(rsa_priv) { - if(!rsa_pub) { - fprintf(stderr, "WARNING: No (usable) public RSA key found.\n"); - - if(ask_fix()) { - FILE *f = fopen(fname, "a"); - - if(f) { - if(rsa_write_pem_public_key(rsa_priv, f)) { - fprintf(stderr, "Wrote RSA public key to %s.\n", fname); - } else { - fprintf(stderr, "ERROR: could not write RSA public key to %s.\n", fname); - } - - fclose(f); - } else { - fprintf(stderr, "ERROR: could not append to %s: %s\n", fname, strerror(errno)); - } - } - } else { - // TODO: suggest remedies - size_t len = rsa_size(rsa_priv); - - if(len != rsa_size(rsa_pub)) { - fprintf(stderr, "ERROR: public and private RSA keys do not match.\n"); - return 1; - } - - char buf1[len], buf2[len], buf3[len]; - randomize(buf1, sizeof(buf1)); - buf1[0] &= 0x7f; - memset(buf2, 0, sizeof(buf2)); - memset(buf3, 0, sizeof(buf2)); - - if(!rsa_public_encrypt(rsa_pub, buf1, sizeof(buf1), buf2)) { - fprintf(stderr, "ERROR: public RSA key does not work.\n"); - return 1; - } - - if(!rsa_private_decrypt(rsa_priv, buf2, sizeof(buf2), buf3)) { - fprintf(stderr, "ERROR: private RSA key does not work.\n"); - return 1; - } - - if(memcmp(buf1, buf3, sizeof(buf1))) { - fprintf(stderr, "ERROR: public and private RSA keys do not match.\n"); - return 1; - } - } - } else { - if(rsa_pub) { - fprintf(stderr, "WARNING: A public RSA key was found but no private key is known.\n"); - } - } - -#endif - - ecdsa_t *ecdsa_pub = NULL; - - f = fopen(fname, "r"); - - if(f) { - ecdsa_pub = get_pubkey(f); - - if(!ecdsa_pub) { - rewind(f); - ecdsa_pub = ecdsa_read_pem_public_key(f); - } - - fclose(f); - } - - if(ecdsa_priv) { - if(!ecdsa_pub) { - fprintf(stderr, "WARNING: No (usable) public Ed25519 key found.\n"); - - if(ask_fix()) { - FILE *f = fopen(fname, "a"); - - if(f) { - if(ecdsa_write_pem_public_key(ecdsa_priv, f)) { - fprintf(stderr, "Wrote Ed25519 public key to %s.\n", fname); - } else { - fprintf(stderr, "ERROR: could not write Ed25519 public key to %s.\n", fname); - } - - fclose(f); - } else { - fprintf(stderr, "ERROR: could not append to %s: %s\n", fname, strerror(errno)); - } - } - } else { - // TODO: suggest remedies - char *key1 = ecdsa_get_base64_public_key(ecdsa_pub); - - if(!key1) { - fprintf(stderr, "ERROR: public Ed25519 key does not work.\n"); - return 1; - } - - char *key2 = ecdsa_get_base64_public_key(ecdsa_priv); - - if(!key2) { - free(key1); - fprintf(stderr, "ERROR: private Ed25519 key does not work.\n"); - return 1; - } - - int result = strcmp(key1, key2); - free(key1); - free(key2); - - if(result) { - fprintf(stderr, "ERROR: public and private Ed25519 keys do not match.\n"); - return 1; - } - } - } else { - if(ecdsa_pub) { - fprintf(stderr, "WARNING: A public Ed25519 key was found but no private key is known.\n"); - } - } - - // Check whether scripts are executable - - struct dirent *ent; - DIR *dir = opendir(confbase); - - if(!dir) { - fprintf(stderr, "ERROR: cannot read directory %s: %s\n", confbase, strerror(errno)); - return 1; - } - - while((ent = readdir(dir))) { - if(strtailcmp(ent->d_name, "-up") && strtailcmp(ent->d_name, "-down")) { - continue; - } - - strncpy(fname, ent->d_name, sizeof(fname)); - char *dash = strrchr(fname, '-'); - - if(!dash) { - continue; - } - - *dash = 0; - - if(strcmp(fname, "tinc") && strcmp(fname, "host") && strcmp(fname, "subnet")) { - static bool explained = false; - fprintf(stderr, "WARNING: Unknown script %s" SLASH "%s found.\n", confbase, ent->d_name); - - if(!explained) { - fprintf(stderr, "The only scripts in %s executed by tinc are:\n", confbase); - fprintf(stderr, "tinc-up, tinc-down, host-up, host-down, subnet-up and subnet-down.\n"); - explained = true; - } - - continue; - } - - snprintf(fname, sizeof(fname), "%s" SLASH "%s", confbase, ent->d_name); - - if(access(fname, R_OK | X_OK)) { - if(errno != EACCES) { - fprintf(stderr, "ERROR: cannot access %s: %s\n", fname, strerror(errno)); - continue; - } - - fprintf(stderr, "WARNING: cannot read and execute %s: %s\n", fname, strerror(errno)); - - if(ask_fix()) { - if(chmod(fname, 0755)) { - fprintf(stderr, "ERROR: cannot change permissions on %s: %s\n", fname, strerror(errno)); - } - } - } - } - - closedir(dir); - - snprintf(dname, sizeof(dname), "%s" SLASH "hosts", confbase); - dir = opendir(dname); - - if(!dir) { - fprintf(stderr, "ERROR: cannot read directory %s: %s\n", dname, strerror(errno)); - return 1; - } - - while((ent = readdir(dir))) { - if(strtailcmp(ent->d_name, "-up") && strtailcmp(ent->d_name, "-down")) { - continue; - } - - strncpy(fname, ent->d_name, sizeof(fname)); - char *dash = strrchr(fname, '-'); - - if(!dash) { - continue; - } - - *dash = 0; - - snprintf(fname, sizeof(fname), "%s" SLASH "hosts" SLASH "%s", confbase, ent->d_name); - - if(access(fname, R_OK | X_OK)) { - if(errno != EACCES) { - fprintf(stderr, "ERROR: cannot access %s: %s\n", fname, strerror(errno)); - continue; - } - - fprintf(stderr, "WARNING: cannot read and execute %s: %s\n", fname, strerror(errno)); - - if(ask_fix()) { - if(chmod(fname, 0755)) { - fprintf(stderr, "ERROR: cannot change permissions on %s: %s\n", fname, strerror(errno)); - } - } - } - } - - closedir(dir); - - // Check for obsolete / unsafe / unknown configuration variables. - - check_conffile(tinc_conf, true); - - dir = opendir(dname); - - if(dir) { - while((ent = readdir(dir))) { - if(!check_id(ent->d_name)) { - continue; - } - - snprintf(fname, sizeof(fname), "%s" SLASH "hosts" SLASH "%s", confbase, ent->d_name); - check_conffile(fname, false); - } - - closedir(dir); - } - - return 0; -} - diff --git a/src/fsck.h b/src/fsck.h deleted file mode 100644 index 3e0b4ca..0000000 --- a/src/fsck.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef TINC_FSCK_H -#define TINC_FSCK_H - -/* - fsck.h -- header for fsck.c. - Copyright (C) 2012 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 - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -extern int fsck(const char *argv0); - -#endif diff --git a/src/gcrypt/cipher.c b/src/gcrypt/cipher.c deleted file mode 100644 index 3eed8e9..0000000 --- a/src/gcrypt/cipher.c +++ /dev/null @@ -1,284 +0,0 @@ -/* - cipher.c -- Symmetric block cipher handling - Copyright (C) 2007-2012 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 - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include "system.h" - -#include "cipher.h" -#include "logger.h" -#include "xalloc.h" - -static struct { - const char *name; - int algo; - int mode; - int nid; -} ciphertable[] = { - {"none", GCRY_CIPHER_NONE, GCRY_CIPHER_MODE_NONE, 0}, - - {NULL, GCRY_CIPHER_BLOWFISH, GCRY_CIPHER_MODE_ECB, 92}, - {"blowfish", GCRY_CIPHER_BLOWFISH, GCRY_CIPHER_MODE_CBC, 91}, - {NULL, GCRY_CIPHER_BLOWFISH, GCRY_CIPHER_MODE_CFB, 93}, - {NULL, GCRY_CIPHER_BLOWFISH, GCRY_CIPHER_MODE_OFB, 94}, - - {NULL, GCRY_CIPHER_AES, GCRY_CIPHER_MODE_ECB, 418}, - {"aes", GCRY_CIPHER_AES, GCRY_CIPHER_MODE_CBC, 419}, - {NULL, GCRY_CIPHER_AES, GCRY_CIPHER_MODE_CFB, 421}, - {NULL, GCRY_CIPHER_AES, GCRY_CIPHER_MODE_OFB, 420}, - - {NULL, GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_ECB, 422}, - {"aes192", GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_CBC, 423}, - {NULL, GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_CFB, 425}, - {NULL, GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_OFB, 424}, - - {NULL, GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_ECB, 426}, - {"aes256", GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CBC, 427}, - {NULL, GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CFB, 429}, - {NULL, GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_OFB, 428}, -}; - -static bool nametocipher(const char *name, int *algo, int *mode) { - size_t i; - - for(i = 0; i < sizeof(ciphertable) / sizeof(*ciphertable); i++) { - if(ciphertable[i].name && !strcasecmp(name, ciphertable[i].name)) { - *algo = ciphertable[i].algo; - *mode = ciphertable[i].mode; - return true; - } - } - - return false; -} - -static bool nidtocipher(int nid, int *algo, int *mode) { - size_t i; - - for(i = 0; i < sizeof(ciphertable) / sizeof(*ciphertable); i++) { - if(nid == ciphertable[i].nid) { - *algo = ciphertable[i].algo; - *mode = ciphertable[i].mode; - return true; - } - } - - return false; -} - -static bool ciphertonid(int algo, int mode, int *nid) { - size_t i; - - for(i = 0; i < sizeof(ciphertable) / sizeof(*ciphertable); i++) { - if(algo == ciphertable[i].algo && mode == ciphertable[i].mode) { - *nid = ciphertable[i].nid; - return true; - } - } - - return false; -} - -static bool cipher_open(cipher_t *cipher, int algo, int mode) { - gcry_error_t err; - - if(!ciphertonid(algo, mode, &cipher->nid)) { - logger(DEBUG_ALWAYS, LOG_DEBUG, "Cipher %d mode %d has no corresponding nid!", algo, mode); - return false; - } - - if((err = gcry_cipher_open(&cipher->handle, algo, mode, 0))) { - logger(DEBUG_ALWAYS, LOG_DEBUG, "Unable to initialise cipher %d mode %d: %s", algo, mode, gcry_strerror(err)); - return false; - } - - cipher->keylen = gcry_cipher_get_algo_keylen(algo); - cipher->blklen = gcry_cipher_get_algo_blklen(algo); - cipher->key = xmalloc(cipher->keylen + cipher->blklen); - cipher->padding = mode == GCRY_CIPHER_MODE_ECB || mode == GCRY_CIPHER_MODE_CBC; - - return true; -} - -bool cipher_open_by_name(cipher_t *cipher, const char *name) { - int algo, mode; - - if(!nametocipher(name, &algo, &mode)) { - logger(DEBUG_ALWAYS, LOG_DEBUG, "Unknown cipher name '%s'!", name); - return false; - } - - return cipher_open(cipher, algo, mode); -} - -bool cipher_open_by_nid(cipher_t *cipher, int nid) { - int algo, mode; - - if(!nidtocipher(nid, &algo, &mode)) { - logger(DEBUG_ALWAYS, LOG_DEBUG, "Unknown cipher ID %d!", nid); - return false; - } - - return cipher_open(cipher, algo, mode); -} - -bool cipher_open_blowfish_ofb(cipher_t *cipher) { - return cipher_open(cipher, GCRY_CIPHER_BLOWFISH, GCRY_CIPHER_MODE_OFB); -} - -void cipher_close(cipher_t *cipher) { - if(cipher->handle) { - gcry_cipher_close(cipher->handle); - cipher->handle = NULL; - } - - free(cipher->key); - cipher->key = NULL; -} - -size_t cipher_keylength(const cipher_t *cipher) { - return cipher->keylen + cipher->blklen; -} - -void cipher_get_key(const cipher_t *cipher, void *key) { - memcpy(key, cipher->key, cipher->keylen + cipher->blklen); -} - -bool cipher_set_key(cipher_t *cipher, void *key, bool encrypt) { - memcpy(cipher->key, key, cipher->keylen + cipher->blklen); - - gcry_cipher_setkey(cipher->handle, cipher->key, cipher->keylen); - gcry_cipher_setiv(cipher->handle, cipher->key + cipher->keylen, cipher->blklen); - - return true; -} - -bool cipher_set_key_from_rsa(cipher_t *cipher, void *key, size_t len, bool encrypt) { - memcpy(cipher->key, key + len - cipher->keylen, cipher->keylen + cipher->blklen); - memcpy(cipher->key + cipher->keylen, key + len - cipher->keylen - cipher->blklen, cipher->blklen); - - gcry_cipher_setkey(cipher->handle, cipher->key, cipher->keylen); - gcry_cipher_setiv(cipher->handle, cipher->key + cipher->keylen, cipher->blklen); - - return true; -} - -bool cipher_regenerate_key(cipher_t *cipher, bool encrypt) { - gcry_create_nonce(cipher->key, cipher->keylen + cipher->blklen); - - gcry_cipher_setkey(cipher->handle, cipher->key, cipher->keylen); - gcry_cipher_setiv(cipher->handle, cipher->key + cipher->keylen, cipher->blklen); - - return true; -} - -bool cipher_encrypt(cipher_t *cipher, const void *indata, size_t inlen, void *outdata, size_t *outlen, bool oneshot) { - gcry_error_t err; - uint8_t pad[cipher->blklen]; - - if(cipher->padding) { - if(!oneshot) { - return false; - } - - size_t reqlen = ((inlen + cipher->blklen) / cipher->blklen) * cipher->blklen; - - if(*outlen < reqlen) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error while encrypting: not enough room for padding"); - return false; - } - - uint8_t padbyte = reqlen - inlen; - inlen = reqlen - cipher->blklen; - - for(int i = 0; i < cipher->blklen; i++) - if(i < cipher->blklen - padbyte) { - pad[i] = ((uint8_t *)indata)[inlen + i]; - } else { - pad[i] = padbyte; - } - } - - if(oneshot) { - gcry_cipher_setiv(cipher->handle, cipher->key + cipher->keylen, cipher->blklen); - } - - if((err = gcry_cipher_encrypt(cipher->handle, outdata, *outlen, indata, inlen))) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error while encrypting: %s", gcry_strerror(err)); - return false; - } - - if(cipher->padding) { - if((err = gcry_cipher_encrypt(cipher->handle, outdata + inlen, cipher->blklen, pad, cipher->blklen))) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error while encrypting: %s", gcry_strerror(err)); - return false; - } - - inlen += cipher->blklen; - } - - *outlen = inlen; - return true; -} - -bool cipher_decrypt(cipher_t *cipher, const void *indata, size_t inlen, void *outdata, size_t *outlen, bool oneshot) { - gcry_error_t err; - - if(oneshot) { - gcry_cipher_setiv(cipher->handle, cipher->key + cipher->keylen, cipher->blklen); - } - - if((err = gcry_cipher_decrypt(cipher->handle, outdata, *outlen, indata, inlen))) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error while decrypting: %s", gcry_strerror(err)); - return false; - } - - if(cipher->padding) { - if(!oneshot) { - return false; - } - - uint8_t padbyte = ((uint8_t *)outdata)[inlen - 1]; - - if(padbyte == 0 || padbyte > cipher->blklen || padbyte > inlen) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error while decrypting: invalid padding"); - return false; - } - - size_t origlen = inlen - padbyte; - - for(int i = inlen - 1; i >= origlen; i--) - if(((uint8_t *)outdata)[i] != padbyte) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error while decrypting: invalid padding"); - return false; - } - - *outlen = origlen; - } else { - *outlen = inlen; - } - - return true; -} - -int cipher_get_nid(const cipher_t *cipher) { - return cipher->nid; -} - -bool cipher_active(const cipher_t *cipher) { - return cipher->nid != 0; -} diff --git a/src/gcrypt/crypto.c b/src/gcrypt/crypto.c deleted file mode 100644 index dc92b3e..0000000 --- a/src/gcrypt/crypto.c +++ /dev/null @@ -1,34 +0,0 @@ -/* - crypto.c -- Cryptographic miscellaneous functions and initialisation - Copyright (C) 2007 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 - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include "system.h" - -#include - -#include "crypto.h" - -void crypto_init() { -} - -void crypto_exit() { -} - -void randomize(void *out, size_t outlen) { - gcry_create_nonce(out, outlen); -} diff --git a/src/gcrypt/digest.c b/src/gcrypt/digest.c deleted file mode 100644 index fce48ee..0000000 --- a/src/gcrypt/digest.c +++ /dev/null @@ -1,182 +0,0 @@ -/* - digest.c -- Digest handling - Copyright (C) 2007-2012 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 - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include "system.h" - -#include "digest.h" -#include "logger.h" - -static struct { - const char *name; - int algo; - int nid; -} digesttable[] = { - {"none", GCRY_MD_NONE, 0}, - {"sha1", GCRY_MD_SHA1, 64}, - {"sha256", GCRY_MD_SHA256, 672}, - {"sha384", GCRY_MD_SHA384, 673}, - {"sha512", GCRY_MD_SHA512, 674}, -}; - -static bool nametodigest(const char *name, int *algo) { - int i; - - for(i = 0; i < sizeof(digesttable) / sizeof(*digesttable); i++) { - if(digesttable[i].name && !strcasecmp(name, digesttable[i].name)) { - *algo = digesttable[i].algo; - return true; - } - } - - return false; -} - -static bool nidtodigest(int nid, int *algo) { - int i; - - for(i = 0; i < sizeof(digesttable) / sizeof(*digesttable); i++) { - if(nid == digesttable[i].nid) { - *algo = digesttable[i].algo; - return true; - } - } - - return false; -} - -static bool digesttonid(int algo, int *nid) { - int i; - - for(i = 0; i < sizeof(digesttable) / sizeof(*digesttable); i++) { - if(algo == digesttable[i].algo) { - *nid = digesttable[i].nid; - return true; - } - } - - return false; -} - -static bool digest_open(digest_t *digest, int algo, int maclength) { - if(!digesttonid(algo, &digest->nid)) { - logger(DEBUG_ALWAYS, LOG_DEBUG, "Digest %d has no corresponding nid!", algo); - return false; - } - - unsigned int len = gcry_md_get_algo_dlen(algo); - - if(maclength > len || maclength < 0) { - digest->maclength = len; - } else { - digest->maclength = maclength; - } - - digest->algo = algo; - digest->hmac = NULL; - - return true; -} - -bool digest_open_by_name(digest_t *digest, const char *name, int maclength) { - int algo; - - if(!nametodigest(name, &algo)) { - logger(DEBUG_ALWAYS, LOG_DEBUG, "Unknown digest name '%s'!", name); - return false; - } - - return digest_open(digest, algo, maclength); -} - -bool digest_open_by_nid(digest_t *digest, int nid, int maclength) { - int algo; - - if(!nidtodigest(nid, &algo)) { - logger(DEBUG_ALWAYS, LOG_DEBUG, "Unknown digest ID %d!", nid); - return false; - } - - return digest_open(digest, algo, maclength); -} - -bool digest_open_sha1(digest_t *digest, int maclength) { - return digest_open(digest, GCRY_MD_SHA1, maclength); -} - -void digest_close(digest_t *digest) { - if(digest->hmac) { - gcry_md_close(digest->hmac); - } - - digest->hmac = NULL; -} - -bool digest_set_key(digest_t *digest, const void *key, size_t len) { - if(!digest->hmac) { - gcry_md_open(&digest->hmac, digest->algo, GCRY_MD_FLAG_HMAC); - } - - if(!digest->hmac) { - return false; - } - - return !gcry_md_setkey(digest->hmac, key, len); -} - -bool digest_create(digest_t *digest, const void *indata, size_t inlen, void *outdata) { - unsigned int len = gcry_md_get_algo_dlen(digest->algo); - - if(digest->hmac) { - char *tmpdata; - gcry_md_reset(digest->hmac); - gcry_md_write(digest->hmac, indata, inlen); - tmpdata = gcry_md_read(digest->hmac, digest->algo); - - if(!tmpdata) { - return false; - } - - memcpy(outdata, tmpdata, digest->maclength); - } else { - char tmpdata[len]; - gcry_md_hash_buffer(digest->algo, tmpdata, indata, inlen); - memcpy(outdata, tmpdata, digest->maclength); - } - - return true; -} - -bool digest_verify(digest_t *digest, const void *indata, size_t inlen, const void *cmpdata) { - unsigned int len = digest->maclength; - char outdata[len]; - - return digest_create(digest, indata, inlen, outdata) && !memcmp(cmpdata, outdata, len); -} - -int digest_get_nid(const digest_t *digest) { - return digest->nid; -} - -size_t digest_length(const digest_t *digest) { - return digest->maclength; -} - -bool digest_active(const digest_t *digest) { - return digest->algo != GCRY_MD_NONE; -} diff --git a/src/gcrypt/digest.h b/src/gcrypt/digest.h deleted file mode 100644 index 42404fc..0000000 --- a/src/gcrypt/digest.h +++ /dev/null @@ -1,45 +0,0 @@ -#ifndef TINC_GCRYPT_DIGEST_H -#define TINC_GCRYPT_DIGEST_H - -/* - digest.h -- header file digest.c - Copyright (C) 2007-2009 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 - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include - -#define DIGEST_MAX_SIZE 64 - -typedef struct digest { - int algo; - int nid; - int maclength; - gcry_md_hd_t hmac; -} digest_t; - -extern bool digest_open_by_name(struct digest *, const char *name, int maclength); -extern bool digest_open_by_nid(struct digest *, int nid, int maclength); -extern bool digest_open_sha1(struct digest *, int maclength); -extern void digest_close(struct digest *); -extern bool digest_create(struct digest *, const void *indata, size_t inlen, void *outdata); -extern bool digest_verify(struct digest *, const void *indata, size_t inlen, const void *digestdata); -extern bool digest_set_key(struct digest *, const void *key, size_t len); -extern int digest_get_nid(const struct digest *); -extern size_t digest_length(const struct digest *); -extern bool digest_active(const struct digest *); - -#endif diff --git a/src/gcrypt/prf.c b/src/gcrypt/prf.c deleted file mode 100644 index ce80f8c..0000000 --- a/src/gcrypt/prf.c +++ /dev/null @@ -1,121 +0,0 @@ -/* - prf.c -- Pseudo-Random Function for key material generation - Copyright (C) 2011-2013 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 - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include "../system.h" - -#include "../prf.h" -#include "../ed25519/sha512.h" - -static void memxor(char *buf, char c, size_t len) { - for(size_t i = 0; i < len; i++) { - buf[i] ^= c; - } -} - -static const size_t mdlen = 64; -static const size_t blklen = 128; - -static bool hmac_sha512(const char *key, size_t keylen, const char *msg, size_t msglen, char *out) { - char tmp[blklen + mdlen]; - sha512_context md; - - if(keylen <= blklen) { - memcpy(tmp, key, keylen); - memset(tmp + keylen, 0, blklen - keylen); - } else { - if(sha512(key, keylen, tmp) != 0) { - return false; - } - - memset(tmp + mdlen, 0, blklen - mdlen); - } - - if(sha512_init(&md) != 0) { - return false; - } - - // ipad - memxor(tmp, 0x36, blklen); - - if(sha512_update(&md, tmp, blklen) != 0) { - return false; - } - - // message - if(sha512_update(&md, msg, msglen) != 0) { - return false; - } - - if(sha512_final(&md, tmp + blklen) != 0) { - return false; - } - - // opad - memxor(tmp, 0x36 ^ 0x5c, blklen); - - if(sha512(tmp, sizeof(tmp), out) != 0) { - return false; - } - - return true; -} - - -/* Generate key material from a master secret and a seed, based on RFC 4346 section 5. - We use SHA512 instead of MD5 and SHA1. - */ - -bool prf(const char *secret, size_t secretlen, char *seed, size_t seedlen, char *out, size_t outlen) { - /* Data is what the "inner" HMAC function processes. - It consists of the previous HMAC result plus the seed. - */ - - char data[mdlen + seedlen]; - memset(data, 0, mdlen); - memcpy(data + mdlen, seed, seedlen); - - char hash[mdlen]; - - while(outlen > 0) { - /* Inner HMAC */ - if(!hmac_sha512(secret, secretlen, data, sizeof(data), data)) { - return false; - } - - /* Outer HMAC */ - if(outlen >= mdlen) { - if(!hmac_sha512(secret, secretlen, data, sizeof(data), out)) { - return false; - } - - out += mdlen; - outlen -= mdlen; - } else { - if(!hmac_sha512(secret, secretlen, data, sizeof(data), hash)) { - return false; - } - - memcpy(out, hash, outlen); - out += outlen; - outlen = 0; - } - } - - return true; -} diff --git a/src/gcrypt/rsa.c b/src/gcrypt/rsa.c deleted file mode 100644 index eb9f58d..0000000 --- a/src/gcrypt/rsa.c +++ /dev/null @@ -1,327 +0,0 @@ -/* - rsa.c -- RSA key handling - Copyright (C) 2007-2012 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 - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include "system.h" - -#include - -#include "logger.h" -#include "rsa.h" - -// Base64 decoding table - -static const uint8_t b64d[128] = { - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0x3e, 0xff, 0xff, 0xff, 0x3f, - 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, - 0x3a, 0x3b, 0x3c, 0x3d, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, - 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, - 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, - 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, - 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, - 0x19, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, - 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, - 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, - 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, - 0x31, 0x32, 0x33, 0xff, 0xff, 0xff, - 0xff, 0xff -}; - -// PEM encoding/decoding functions - -static bool pem_decode(FILE *fp, const char *header, uint8_t *buf, size_t size, size_t *outsize) { - bool decode = false; - char line[1024]; - uint16_t word = 0; - int shift = 10; - size_t i, j = 0; - - while(!feof(fp)) { - if(!fgets(line, sizeof(line), fp)) { - return false; - } - - if(!decode && !strncmp(line, "-----BEGIN ", 11)) { - if(!strncmp(line + 11, header, strlen(header))) { - decode = true; - } - - continue; - } - - if(decode && !strncmp(line, "-----END", 8)) { - break; - } - - if(!decode) { - continue; - } - - for(i = 0; line[i] >= ' '; i++) { - if((signed char)line[i] < 0 || b64d[(int)line[i]] == 0xff) { - break; - } - - word |= b64d[(int)line[i]] << shift; - shift -= 6; - - if(shift <= 2) { - if(j > size) { - errno = ENOMEM; - return false; - } - - buf[j++] = word >> 8; - word <<= 8; - shift += 8; - } - } - } - - if(outsize) { - *outsize = j; - } - - return true; -} - - -// BER decoding functions - -static int ber_read_id(unsigned char **p, size_t *buflen) { - if(*buflen <= 0) { - return -1; - } - - if((**p & 0x1f) == 0x1f) { - int id = 0; - bool more; - - while(*buflen > 0) { - id <<= 7; - id |= **p & 0x7f; - more = *(*p)++ & 0x80; - (*buflen)--; - - if(!more) { - break; - } - } - - return id; - } else { - (*buflen)--; - return *(*p)++ & 0x1f; - } -} - -static size_t ber_read_len(unsigned char **p, size_t *buflen) { - if(*buflen <= 0) { - return -1; - } - - if(**p & 0x80) { - size_t result = 0; - int len = *(*p)++ & 0x7f; - (*buflen)--; - - if(len > *buflen) { - return 0; - } - - while(len--) { - result <<= 8; - result |= *(*p)++; - (*buflen)--; - } - - return result; - } else { - (*buflen)--; - return *(*p)++; - } -} - - -static bool ber_read_sequence(unsigned char **p, size_t *buflen, size_t *result) { - int tag = ber_read_id(p, buflen); - size_t len = ber_read_len(p, buflen); - - if(tag == 0x10) { - if(result) { - *result = len; - } - - return true; - } else { - return false; - } -} - -static bool ber_read_mpi(unsigned char **p, size_t *buflen, gcry_mpi_t *mpi) { - int tag = ber_read_id(p, buflen); - size_t len = ber_read_len(p, buflen); - gcry_error_t err = 0; - - if(tag != 0x02 || len > *buflen) { - return false; - } - - if(mpi) { - err = gcry_mpi_scan(mpi, GCRYMPI_FMT_USG, *p, len, NULL); - } - - *p += len; - *buflen -= len; - - return mpi ? !err : true; -} - -bool rsa_set_hex_public_key(rsa_t *rsa, char *n, char *e) { - gcry_error_t err = 0; - - err = gcry_mpi_scan(&rsa->n, GCRYMPI_FMT_HEX, n, 0, NULL) - ? : gcry_mpi_scan(&rsa->e, GCRYMPI_FMT_HEX, e, 0, NULL); - - if(err) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading RSA public key: %s", gcry_strerror(errno)); - return false; - } - - return true; -} - -bool rsa_set_hex_private_key(rsa_t *rsa, char *n, char *e, char *d) { - gcry_error_t err = 0; - - err = gcry_mpi_scan(&rsa->n, GCRYMPI_FMT_HEX, n, 0, NULL) - ? : gcry_mpi_scan(&rsa->e, GCRYMPI_FMT_HEX, e, 0, NULL) - ? : gcry_mpi_scan(&rsa->d, GCRYMPI_FMT_HEX, d, 0, NULL); - - if(err) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading RSA public key: %s", gcry_strerror(errno)); - return false; - } - - return true; -} - -// Read PEM RSA keys - -bool rsa_read_pem_public_key(rsa_t *rsa, FILE *fp) { - uint8_t derbuf[8096], *derp = derbuf; - size_t derlen; - - if(!pem_decode(fp, "RSA PUBLIC KEY", derbuf, sizeof(derbuf), &derlen)) { - logger(DEBUG_ALWAYS, LOG_ERR, "Unable to read RSA public key: %s", strerror(errno)); - return NULL; - } - - if(!ber_read_sequence(&derp, &derlen, NULL) - || !ber_read_mpi(&derp, &derlen, &rsa->n) - || !ber_read_mpi(&derp, &derlen, &rsa->e) - || derlen) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error while decoding RSA public key"); - return NULL; - } - - return true; -} - -bool rsa_read_pem_private_key(rsa_t *rsa, FILE *fp) { - uint8_t derbuf[8096], *derp = derbuf; - size_t derlen; - - if(!pem_decode(fp, "RSA PRIVATE KEY", derbuf, sizeof(derbuf), &derlen)) { - logger(DEBUG_ALWAYS, LOG_ERR, "Unable to read RSA private key: %s", strerror(errno)); - return NULL; - } - - if(!ber_read_sequence(&derp, &derlen, NULL) - || !ber_read_mpi(&derp, &derlen, NULL) - || !ber_read_mpi(&derp, &derlen, &rsa->n) - || !ber_read_mpi(&derp, &derlen, &rsa->e) - || !ber_read_mpi(&derp, &derlen, &rsa->d) - || !ber_read_mpi(&derp, &derlen, NULL) // p - || !ber_read_mpi(&derp, &derlen, NULL) // q - || !ber_read_mpi(&derp, &derlen, NULL) - || !ber_read_mpi(&derp, &derlen, NULL) - || !ber_read_mpi(&derp, &derlen, NULL) // u - || derlen) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error while decoding RSA private key"); - return NULL; - } - - return true; -} - -size_t rsa_size(rsa_t *rsa) { - return (gcry_mpi_get_nbits(rsa->n) + 7) / 8; -} - -/* Well, libgcrypt has functions to handle RSA keys, but they suck. - * So we just use libgcrypt's mpi functions, and do the math ourselves. - */ - -// TODO: get rid of this macro, properly clean up gcry_ structures after use -#define check(foo) { gcry_error_t err = (foo); if(err) {logger(DEBUG_ALWAYS, LOG_ERR, "gcrypt error %s/%s at %s:%d", gcry_strsource(err), gcry_strerror(err), __FILE__, __LINE__); return false; }} - -bool rsa_public_encrypt(rsa_t *rsa, void *in, size_t len, void *out) { - gcry_mpi_t inmpi; - check(gcry_mpi_scan(&inmpi, GCRYMPI_FMT_USG, in, len, NULL)); - - gcry_mpi_t outmpi = gcry_mpi_new(len * 8); - gcry_mpi_powm(outmpi, inmpi, rsa->e, rsa->n); - - int pad = len - (gcry_mpi_get_nbits(outmpi) + 7) / 8; - - while(pad--) { - *(char *)out++ = 0; - } - - check(gcry_mpi_print(GCRYMPI_FMT_USG, out, len, NULL, outmpi)); - - return true; -} - -bool rsa_private_decrypt(rsa_t *rsa, void *in, size_t len, void *out) { - gcry_mpi_t inmpi; - check(gcry_mpi_scan(&inmpi, GCRYMPI_FMT_USG, in, len, NULL)); - - gcry_mpi_t outmpi = gcry_mpi_new(len * 8); - gcry_mpi_powm(outmpi, inmpi, rsa->d, rsa->n); - - int pad = len - (gcry_mpi_get_nbits(outmpi) + 7) / 8; - - while(pad--) { - *(char *)out++ = 0; - } - - check(gcry_mpi_print(GCRYMPI_FMT_USG, out, len, NULL, outmpi)); - - return true; -} diff --git a/src/gcrypt/rsagen.c b/src/gcrypt/rsagen.c deleted file mode 100644 index 030f2bc..0000000 --- a/src/gcrypt/rsagen.c +++ /dev/null @@ -1,239 +0,0 @@ -/* - rsagen.c -- RSA key generation and export - Copyright (C) 2008-2012 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 - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include "system.h" - -#include - -#include "rsagen.h" - -#if 0 -// Base64 encoding table - -static const char b64e[64] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - -// PEM encoding - -static bool pem_encode(FILE *fp, const char *header, uint8_t *buf, size_t size) { - bool decode = false; - char line[1024]; - uint32_t word = 0; - int shift = 0; - size_t i, j = 0; - - fprintf(fp, "-----BEGIN %s-----\n", header); - - for(i = 0; i < size; i += 3) { - if(i <= size - 3) { - word = buf[i] << 16 | buf[i + 1] << 8 | buf[i + 2]; - } else { - word = buf[i] << 16; - - if(i == size - 2) { - word |= buf[i + 1] << 8; - } - } - - line[j++] = b64e[(word >> 18) ]; - line[j++] = b64e[(word >> 12) & 0x3f]; - line[j++] = b64e[(word >> 6) & 0x3f]; - line[j++] = b64e[(word) & 0x3f]; - - if(j >= 64) { - line[j++] = '\n'; - line[j] = 0; - fputs(line, fp); - j = 0; - } - } - - if(size % 3 > 0) { - if(size % 3 > 1) { - line[j++] = '='; - } - - line[j++] = '='; - } - - if(j) { - line[j++] = '\n'; - line[j] = 0; - fputs(line, fp); - } - - fprintf(fp, "-----END %s-----\n", header); - - return true; -} - - -// BER encoding functions - -static bool ber_write_id(uint8_t **p, size_t *buflen, int id) { - if(*buflen <= 0) { - return false; - } - - if(id >= 0x1f) { - while(id) { - if(*buflen <= 0) { - return false; - } - - (*buflen)--; - **p = id & 0x7f; - id >>= 7; - - if(id) { - **p |= 0x80; - } - - (*p)++; - } - } else { - (*buflen)--; - *(*p)++ = id; - } - - return true; -} - -static bool ber_write_len(uint8_t **p, size_t *buflen, size_t len) { - do { - if(*buflen <= 0) { - return false; - } - - (*buflen)--; - **p = len & 0x7f; - len >>= 7; - - if(len) { - **p |= 0x80; - } - - (*p)++; - } while(len); - - return true; -} - -static bool ber_write_sequence(uint8_t **p, size_t *buflen, uint8_t *seqbuf, size_t seqlen) { - if(!ber_write_id(p, buflen, 0x10) || !ber_write_len(p, buflen, seqlen) || *buflen < seqlen) { - return false; - } - - memcpy(*p, seqbuf, seqlen); - *p += seqlen; - *buflen -= seqlen; - - return true; -} - -static bool ber_write_mpi(uint8_t **p, size_t *buflen, gcry_mpi_t mpi) { - uint8_t tmpbuf[1024]; - size_t tmplen = sizeof(tmpbuf); - gcry_error_t err; - - err = gcry_mpi_aprint(GCRYMPI_FMT_USG, &tmpbuf, &tmplen, mpi); - - if(err) { - return false; - } - - if(!ber_write_id(p, buflen, 0x02) || !ber_write_len(p, buflen, tmplen) || *buflen < tmplen) { - return false; - } - - memcpy(*p, tmpbuf, tmplen); - *p += tmplen; - *buflen -= tmplen; - - return true; -} - -// Write PEM RSA keys - -bool rsa_write_pem_public_key(rsa_t *rsa, FILE *fp) { - uint8_t derbuf1[8096]; - uint8_t derbuf2[8096]; - uint8_t *derp1 = derbuf1; - uint8_t *derp2 = derbuf2; - size_t derlen1 = sizeof(derbuf1); - size_t derlen2 = sizeof(derbuf2); - - if(!ber_write_mpi(&derp1, &derlen1, &rsa->n) - || !ber_write_mpi(&derp1, &derlen1, &rsa->e) - || !ber_write_sequence(&derp2, &derlen2, derbuf1, derlen1)) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error while encoding RSA public key"); - return false; - } - - if(!pem_encode(fp, "RSA PUBLIC KEY", derbuf2, derlen2)) { - logger(DEBUG_ALWAYS, LOG_ERR, "Unable to write RSA public key: %s", strerror(errno)); - return false; - } - - return true; -} - -bool rsa_write_pem_private_key(rsa_t *rsa, FILE *fp) { - uint8_t derbuf1[8096]; - uint8_t derbuf2[8096]; - uint8_t *derp1 = derbuf1; - uint8_t *derp2 = derbuf2; - size_t derlen1 = sizeof(derbuf1); - size_t derlen2 = sizeof(derbuf2); - - if(!ber_write_mpi(&derp1, &derlen1, &bits) - || ber_write_mpi(&derp1, &derlen1, &rsa->n) // modulus - || ber_write_mpi(&derp1, &derlen1, &rsa->e) // public exponent - || ber_write_mpi(&derp1, &derlen1, &rsa->d) // private exponent - || ber_write_mpi(&derp1, &derlen1, &p) - || ber_write_mpi(&derp1, &derlen1, &q) - || ber_write_mpi(&derp1, &derlen1, &exp1) - || ber_write_mpi(&derp1, &derlen1, &exp2) - || ber_write_mpi(&derp1, &derlen1, &coeff)) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error while encoding RSA private key"); - } - - return false; -} - -if(!pem_encode(fp, "RSA PRIVATE KEY", derbuf2, derlen2)) { - logger(DEBUG_ALWAYS, LOG_ERR, "Unable to write RSA private key: %s", strerror(errno)); - return false; -} - -return true; -} -#endif - -bool rsa_write_pem_public_key(rsa_t *rsa, FILE *fp) { - return false; -} - -bool rsa_write_pem_private_key(rsa_t *rsa, FILE *fp) { - return false; -} - -bool rsa_generate(rsa_t *rsa, size_t bits, unsigned long exponent) { - fprintf(stderr, "Generating RSA keys with libgcrypt not implemented yet\n"); - return false; -} diff --git a/src/getopt.c b/src/getopt.c index 5d5fb59..741c7f2 100644 --- a/src/getopt.c +++ b/src/getopt.c @@ -132,7 +132,7 @@ int optind = 1; causes problems with re-calling getopt as programs generally don't know that. */ -int __getopt_initialized = 0; +int getopt_initialized = 0; /* The next char to be scanned in the option-element in which the last option character we returned was found. @@ -248,7 +248,7 @@ static int last_nonopt; indicating ARGV elements that should not be considered arguments. */ /* Defined in getopt_init.c */ -extern char *__getopt_nonoption_flags; +extern char *getopt_nonoption_flags; static int nonoption_flags_max_len; static int nonoption_flags_len; @@ -256,7 +256,7 @@ static int nonoption_flags_len; static int original_argc; static char *const *original_argv; -extern pid_t __libc_pid; +extern pid_t libc_pid; /* Make sure the environment variable bash 2.0 puts in the environment is valid for the getopt call we must make sure that the ARGV passed @@ -269,14 +269,14 @@ store_args_and_env(int argc, char *const *argv) { original_argc = argc; original_argv = argv; } -text_set_element(__libc_subinit, store_args_and_env); +text_set_element(libc_subinit, store_args_and_env); # define SWAP_FLAGS(ch1, ch2) \ if (nonoption_flags_len > 0) \ { \ - char __tmp = __getopt_nonoption_flags[ch1]; \ - __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2]; \ - __getopt_nonoption_flags[ch2] = __tmp; \ + char tmp = getopt_nonoption_flags[ch1]; \ + getopt_nonoption_flags[ch1] = getopt_nonoption_flags[ch2]; \ + getopt_nonoption_flags[ch2] = tmp; \ } #else /* !_LIBC */ # define SWAP_FLAGS(ch1, ch2) @@ -311,7 +311,7 @@ char **argv; #ifdef _LIBC - /* First make sure the handling of the `__getopt_nonoption_flags' + /* First make sure the handling of the `getopt_nonoption_flags' string can work normally. Our top argument must be in the range of the string. */ if(nonoption_flags_len > 0 && top >= nonoption_flags_max_len) { @@ -322,11 +322,11 @@ char **argv; if(new_str == NULL) { nonoption_flags_len = nonoption_flags_max_len = 0; } else { - memcpy(new_str, __getopt_nonoption_flags, nonoption_flags_max_len); + memcpy(new_str, getopt_nonoption_flags, nonoption_flags_max_len); memset(&new_str[nonoption_flags_max_len], '\0', top + 1 - nonoption_flags_max_len); nonoption_flags_max_len = top + 1; - __getopt_nonoption_flags = new_str; + getopt_nonoption_flags = new_str; } } @@ -412,25 +412,25 @@ const char *optstring; if(posixly_correct == NULL && argc == original_argc && argv == original_argv) { if(nonoption_flags_max_len == 0) { - if(__getopt_nonoption_flags == NULL - || __getopt_nonoption_flags[0] == '\0') { + if(getopt_nonoption_flags == NULL + || getopt_nonoption_flags[0] == '\0') { nonoption_flags_max_len = -1; } else { - const char *orig_str = __getopt_nonoption_flags; + const char *orig_str = getopt_nonoption_flags; int len = nonoption_flags_max_len = strlen(orig_str); if(nonoption_flags_max_len < argc) { nonoption_flags_max_len = argc; } - __getopt_nonoption_flags = + getopt_nonoption_flags = (char *) malloc(nonoption_flags_max_len); - if(__getopt_nonoption_flags == NULL) { + if(getopt_nonoption_flags == NULL) { nonoption_flags_max_len = -1; } else { - memcpy(__getopt_nonoption_flags, orig_str, len); - memset(&__getopt_nonoption_flags[len], '\0', + memcpy(getopt_nonoption_flags, orig_str, len); + memset(&getopt_nonoption_flags[len], '\0', nonoption_flags_max_len - len); } } @@ -513,13 +513,13 @@ int long_only; { optarg = NULL; - if(optind == 0 || !__getopt_initialized) { + if(optind == 0 || !getopt_initialized) { if(optind == 0) { optind = 1; /* Don't scan ARGV[0], the program name. */ } optstring = _getopt_initialize(argc, argv, optstring); - __getopt_initialized = 1; + getopt_initialized = 1; } /* Test whether ARGV[optind] points to a non-option argument. @@ -529,7 +529,7 @@ int long_only; #ifdef _LIBC #define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0' \ || (optind < nonoption_flags_len \ - && __getopt_nonoption_flags[optind] == '1')) + && getopt_nonoption_flags[optind] == '1')) #else #define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0') #endif diff --git a/src/getopt.h b/src/getopt.h index e9a7040..ab1d40b 100644 --- a/src/getopt.h +++ b/src/getopt.h @@ -22,79 +22,76 @@ with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#ifndef _GETOPT_H -#define _GETOPT_H 1 - -#ifdef __cplusplus +#ifdef cplusplus extern "C" { #endif -/* For communication from `getopt' to the caller. - When `getopt' finds an option that takes an argument, - the argument value is returned here. - Also, when `ordering' is RETURN_IN_ORDER, - each non-option ARGV-element is returned here. */ + /* For communication from `getopt' to the caller. + When `getopt' finds an option that takes an argument, + the argument value is returned here. + Also, when `ordering' is RETURN_IN_ORDER, + each non-option ARGV-element is returned here. */ -extern char *optarg; + extern char *optarg; -/* Index in ARGV of the next element to be scanned. - This is used for communication to and from the caller - and for communication between successive calls to `getopt'. + /* Index in ARGV of the next element to be scanned. + This is used for communication to and from the caller + and for communication between successive calls to `getopt'. - On entry to `getopt', zero means this is the first call; initialize. + On entry to `getopt', zero means this is the first call; initialize. - When `getopt' returns -1, this is the index of the first of the - non-option elements that the caller should itself scan. + When `getopt' returns -1, this is the index of the first of the + non-option elements that the caller should itself scan. - Otherwise, `optind' communicates from one call to the next - how much of ARGV has been scanned so far. */ + Otherwise, `optind' communicates from one call to the next + how much of ARGV has been scanned so far. */ -extern int optind; + extern int optind; -/* Callers store zero here to inhibit the error message `getopt' prints - for unrecognized options. */ + /* Callers store zero here to inhibit the error message `getopt' prints + for unrecognized options. */ -extern int opterr; + extern int opterr; -/* Set to an option character which was unrecognized. */ + /* Set to an option character which was unrecognized. */ -extern int optopt; + extern int optopt; -/* Describe the long-named options requested by the application. - The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector - of `struct option' terminated by an element containing a name which is - zero. + /* Describe the long-named options requested by the application. + The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector + of `struct option' terminated by an element containing a name which is + zero. - The field `has_arg' is: - no_argument (or 0) if the option does not take an argument, - required_argument (or 1) if the option requires an argument, - optional_argument (or 2) if the option takes an optional argument. + The field `has_arg' is: + no_argument (or 0) if the option does not take an argument, + required_argument (or 1) if the option requires an argument, + optional_argument (or 2) if the option takes an optional argument. - If the field `flag' is not NULL, it points to a variable that is set - to the value given in the field `val' when the option is found, but - left unchanged if the option is not found. + If the field `flag' is not NULL, it points to a variable that is set + to the value given in the field `val' when the option is found, but + left unchanged if the option is not found. - To have a long-named option do something other than set an `int' to - a compiled-in constant, such as set a value from `optarg', set the - option's `flag' field to zero and its `val' field to a nonzero - value (the equivalent single-letter option character, if there is - one). For long options that have a zero `flag' field, `getopt' - returns the contents of the `val' field. */ + To have a long-named option do something other than set an `int' to + a compiled-in constant, such as set a value from `optarg', set the + option's `flag' field to zero and its `val' field to a nonzero + value (the equivalent single-letter option character, if there is + one). For long options that have a zero `flag' field, `getopt' + returns the contents of the `val' field. */ -struct option { + struct option { #if defined (__STDC__) && __STDC__ - const char *name; + const char *name; #else - char *name; + char *name; #endif - /* has_arg can't be an enum because some compilers complain about - type mismatches in all the code that assumes it is an int. */ - int has_arg; - int *flag; - int val; -}; + /* has_arg can't be an enum because some compilers complain about + type mismatches in all the code that assumes it is an int. */ + int has_arg; + int *flag; + int val; + }; -/* Names for the values of the `has_arg' field of `struct option'. */ + /* Names for the values of the `has_arg' field of `struct option'. */ #define no_argument 0 #define required_argument 1 @@ -102,33 +99,33 @@ struct option { #if defined (__STDC__) && __STDC__ #ifdef __GNU_LIBRARY__ -/* Many other libraries have conflicting prototypes for getopt, with - differences in the consts, in stdlib.h. To avoid compilation - errors, only prototype getopt for the GNU C library. */ -extern int getopt(int argc, char *const *argv, const char *shortopts); + /* Many other libraries have conflicting prototypes for getopt, with + differences in the consts, in stdlib.h. To avoid compilation + errors, only prototype getopt for the GNU C library. */ + extern int getopt(int argc, char *const *argv, const char *shortopts); #else /* not __GNU_LIBRARY__ */ -extern int getopt(); + extern int getopt(); #endif /* __GNU_LIBRARY__ */ -extern int getopt_long(int argc, char *const *argv, const char *shortopts, - const struct option *longopts, int *longind); -extern int getopt_long_only(int argc, char *const *argv, - const char *shortopts, - const struct option *longopts, int *longind); + extern int getopt_long(int argc, char *const *argv, const char *shortopts, + const struct option *longopts, int *longind); + extern int getopt_long_only(int argc, char *const *argv, + const char *shortopts, + const struct option *longopts, int *longind); -/* Internal only. Users should not call this directly. */ -extern int _getopt_internal(int argc, char *const *argv, - const char *shortopts, - const struct option *longopts, int *longind, - int long_only); + /* Internal only. Users should not call this directly. */ + extern int _getopt_internal(int argc, char *const *argv, + const char *shortopts, + const struct option *longopts, int *longind, + int long_only); #else /* not __STDC__ */ -extern int getopt(); -extern int getopt_long(); -extern int getopt_long_only(); + extern int getopt(); + extern int getopt_long(); + extern int getopt_long_only(); -extern int _getopt_internal(); + extern int _getopt_internal(); #endif /* __STDC__ */ -#ifdef __cplusplus +#ifdef cplusplus } #endif diff --git a/src/graph.c b/src/graph.c index a774eac..c63fdf9 100644 --- a/src/graph.c +++ b/src/graph.c @@ -1,6 +1,6 @@ /* graph.c -- graph algorithms - Copyright (C) 2001-2017 Guus Sliepen , + Copyright (C) 2001-2014 Guus Sliepen , 2001-2005 Ivo Timmermans This program is free software; you can redistribute it and/or modify @@ -44,21 +44,22 @@ #include "system.h" +#include "avl_tree.h" +#include "conf.h" #include "connection.h" #include "device.h" #include "edge.h" #include "graph.h" -#include "list.h" #include "logger.h" -#include "names.h" #include "netutl.h" #include "node.h" +#include "process.h" #include "protocol.h" -#include "script.h" #include "subnet.h" #include "utils.h" #include "xalloc.h" -#include "graph.h" + +static bool graph_changed = true; /* Implementation of Kruskal's algorithm. Running time: O(EN) @@ -66,23 +67,42 @@ */ static void mst_kruskal(void) { + avl_node_t *node, *next; + edge_t *e; + node_t *n; + connection_t *c; + int nodes = 0; + int safe_edges = 0; + bool skipped; + /* Clear MST status on connections */ - for list_each(connection_t, c, connection_list) { + for(node = connection_tree->head; node; node = node->next) { + c = node->data; c->status.mst = false; } - logger(DEBUG_SCARY_THINGS, LOG_DEBUG, "Running Kruskal's algorithm:"); + /* Do we have something to do at all? */ + + if(!edge_weight_tree->head) { + return; + } + + ifdebug(SCARY_THINGS) logger(LOG_DEBUG, "Running Kruskal's algorithm:"); /* Clear visited status on nodes */ - for splay_each(node_t, n, node_tree) { + for(node = node_tree->head; node; node = node->next) { + n = node->data; n->status.visited = false; + nodes++; } /* Starting point */ - for splay_each(edge_t, e, edge_weight_tree) { + for(node = edge_weight_tree->head; node; node = node->next) { + e = node->data; + if(e->from->status.reachable) { e->from->status.visited = true; break; @@ -91,10 +111,11 @@ static void mst_kruskal(void) { /* Add safe edges */ - bool skipped = false; + for(skipped = false, node = edge_weight_tree->head; node; node = next) { + next = node->next; + e = node->data; - for splay_each(edge_t, e, edge_weight_tree) { - if(!e->reverse || (e->from->status.visited == e->to->status.visited)) { + if(!e->reverse || e->from->status.visited == e->to->status.visited) { skipped = true; continue; } @@ -110,13 +131,20 @@ static void mst_kruskal(void) { e->reverse->connection->status.mst = true; } - logger(DEBUG_SCARY_THINGS, LOG_DEBUG, " Adding edge %s - %s weight %d", e->from->name, e->to->name, e->weight); + safe_edges++; + + ifdebug(SCARY_THINGS) logger(LOG_DEBUG, " Adding edge %s - %s weight %d", e->from->name, + e->to->name, e->weight); if(skipped) { skipped = false; next = edge_weight_tree->head; + continue; } } + + ifdebug(SCARY_THINGS) logger(LOG_DEBUG, "Done, counted %d nodes and %d safe edges.", nodes, + safe_edges); } /* Implementation of a simple breadth-first search algorithm. @@ -124,14 +152,25 @@ static void mst_kruskal(void) { */ static void sssp_bfs(void) { - list_t *todo_list = list_alloc(NULL); + avl_node_t *node, *next, *to; + edge_t *e; + node_t *n; + list_t *todo_list; + list_node_t *from, *todonext; + bool indirect; + char *name; + char *address, *port; + char *envp[8] = {NULL}; + int i; + + todo_list = list_alloc(NULL); /* Clear visited status on nodes */ - for splay_each(node_t, n, node_tree) { + for(node = node_tree->head; node; node = node->next) { + n = node->data; n->status.visited = false; n->status.indirect = true; - n->distance = -1; } /* Begin with myself */ @@ -141,20 +180,17 @@ static void sssp_bfs(void) { myself->nexthop = myself; myself->prevedge = NULL; myself->via = myself; - myself->distance = 0; list_insert_head(todo_list, myself); /* Loop while todo_list is filled */ - for list_each(node_t, n, todo_list) { /* "n" is the node from which we start */ - logger(DEBUG_SCARY_THINGS, LOG_DEBUG, " Examining edges from %s", n->name); + for(from = todo_list->head; from; from = todonext) { /* "from" is the node from which we start */ + n = from->data; - if(n->distance < 0) { - abort(); - } + for(to = n->edge_tree->head; to; to = to->next) { /* "to" is the edge connected to "from" */ + e = to->data; - for splay_each(edge_t, e, n->edge_tree) { /* "e" is the edge connected to "from" */ - if(!e->reverse || e->to == myself) { + if(!e->reverse) { continue; } @@ -175,17 +211,16 @@ static void sssp_bfs(void) { of nodes behind it. */ - bool indirect = n->status.indirect || e->options & OPTION_INDIRECT; + indirect = n->status.indirect || e->options & OPTION_INDIRECT; if(e->to->status.visited - && (!e->to->status.indirect || indirect) - && (e->to->distance != n->distance + 1 || e->weight >= e->to->prevedge->weight)) { + && (!e->to->status.indirect || indirect)) { continue; } - // Only update nexthop if it doesn't increase the path length + // Only update nexthop the first time we visit this node. - if(!e->to->status.visited || (e->to->distance == n->distance + 1 && e->weight >= e->to->prevedge->weight)) { + if(!e->to->status.visited) { e->to->nexthop = (n->nexthop == myself) ? e->to : n->nexthop; } @@ -194,93 +229,74 @@ static void sssp_bfs(void) { e->to->prevedge = e; e->to->via = indirect ? n->via : e->to; e->to->options = e->options; - e->to->distance = n->distance + 1; - if(!e->to->status.reachable || (e->to->address.sa.sa_family == AF_UNSPEC && e->address.sa.sa_family != AF_UNKNOWN)) { + if(e->to->address.sa.sa_family == AF_UNSPEC && e->address.sa.sa_family != AF_UNKNOWN) { update_node_udp(e->to, &e->address); } list_insert_tail(todo_list, e->to); } - next = node->next; /* Because the list_insert_tail() above could have added something extra for us! */ - list_delete_node(todo_list, node); + todonext = from->next; + list_delete_node(todo_list, from); } list_free(todo_list); -} -static void check_reachability(void) { /* Check reachability status. */ - int reachable_count = 0; - int became_reachable_count = 0; - int became_unreachable_count = 0; + for(node = node_tree->head; node; node = next) { + next = node->next; + n = node->data; - for splay_each(node_t, n, node_tree) { if(n->status.visited != n->status.reachable) { n->status.reachable = !n->status.reachable; - n->last_state_change = now.tv_sec; if(n->status.reachable) { - logger(DEBUG_TRAFFIC, LOG_DEBUG, "Node %s (%s) became reachable", - n->name, n->hostname); - - if(n != myself) { - became_reachable_count++; - } + ifdebug(TRAFFIC) logger(LOG_DEBUG, "Node %s (%s) became reachable", + n->name, n->hostname); } else { - logger(DEBUG_TRAFFIC, LOG_DEBUG, "Node %s (%s) became unreachable", - n->name, n->hostname); - - if(n != myself) { - became_unreachable_count++; - } - } - - if(experimental && OPTION_VERSION(n->options) >= 2) { - n->status.sptps = true; + ifdebug(TRAFFIC) logger(LOG_DEBUG, "Node %s (%s) became unreachable", + n->name, n->hostname); } /* TODO: only clear status.validkey if node is unreachable? */ n->status.validkey = false; - - if(n->status.sptps) { - sptps_stop(&n->sptps); - n->status.waitingforkey = false; - } - n->last_req_key = 0; - n->status.udp_confirmed = false; n->maxmtu = MTU; - n->maxrecentlen = 0; n->minmtu = 0; n->mtuprobes = 0; - timeout_del(&n->udp_ping_timeout); + if(n->mtuevent) { + event_del(n->mtuevent); + n->mtuevent = NULL; + } - char *name; - char *address; - char *port; - - environment_t env; - environment_init(&env); - environment_add(&env, "NODE=%s", n->name); + xasprintf(&envp[0], "NETNAME=%s", netname ? netname : ""); + xasprintf(&envp[1], "DEVICE=%s", device ? device : ""); + xasprintf(&envp[2], "INTERFACE=%s", iface ? iface : ""); + xasprintf(&envp[3], "NODE=%s", n->name); sockaddr2str(&n->address, &address, &port); - environment_add(&env, "REMOTEADDRESS=%s", address); - environment_add(&env, "REMOTEPORT=%s", port); + xasprintf(&envp[4], "REMOTEADDRESS=%s", address); + xasprintf(&envp[5], "REMOTEPORT=%s", port); + xasprintf(&envp[6], "NAME=%s", myself->name); - execute_script(n->status.reachable ? "host-up" : "host-down", &env); + execute_script(n->status.reachable ? "host-up" : "host-down", envp); - xasprintf(&name, n->status.reachable ? "hosts/%s-up" : "hosts/%s-down", n->name); - execute_script(name, &env); + xasprintf(&name, + n->status.reachable ? "hosts/%s-up" : "hosts/%s-down", + n->name); + execute_script(name, envp); free(name); free(address); free(port); - environment_exit(&env); + + for(i = 0; i < 7; i++) { + free(envp[i]); + } subnet_update(n, NULL, n->status.reachable); @@ -289,30 +305,86 @@ static void check_reachability(void) { memset(&n->status, 0, sizeof(n->status)); n->options = 0; } else if(n->connection) { - // Speed up UDP probing by sending our key. - if(!n->status.sptps) { - send_ans_key(n); - } + send_ans_key(n); } } - - if(n->status.reachable && n != myself) { - reachable_count++; - } - } - - if(device_standby) { - if(reachable_count == 0 && became_unreachable_count > 0) { - device_disable(); - } else if(reachable_count > 0 && reachable_count == became_reachable_count) { - device_enable(); - } } } void graph(void) { subnet_cache_flush(); sssp_bfs(); - check_reachability(); mst_kruskal(); + graph_changed = true; +} + + + +/* Dump nodes and edges to a graphviz file. + + The file can be converted to an image with + dot -Tpng graph_filename -o image_filename.png -Gconcentrate=true +*/ + +void dump_graph(void) { + avl_node_t *node; + node_t *n; + edge_t *e; + char *filename = NULL, *tmpname = NULL; + FILE *file, *pipe = NULL; + + if(!graph_changed || !get_config_string(lookup_config(config_tree, "GraphDumpFile"), &filename)) { + return; + } + + graph_changed = false; + + ifdebug(PROTOCOL) logger(LOG_NOTICE, "Dumping graph"); + + if(filename[0] == '|') { + file = pipe = popen(filename + 1, "w"); + } else { + xasprintf(&tmpname, "%s.new", filename); + file = fopen(tmpname, "w"); + } + + if(!file) { + logger(LOG_ERR, "Unable to open graph dump file %s: %s", filename, strerror(errno)); + free(filename); + free(tmpname); + return; + } + + fprintf(file, "digraph {\n"); + + /* dump all nodes first */ + for(node = node_tree->head; node; node = node->next) { + n = node->data; + fprintf(file, " \"%s\" [label = \"%s\"];\n", n->name, n->name); + } + + /* now dump all edges */ + for(node = edge_weight_tree->head; node; node = node->next) { + e = node->data; + fprintf(file, " \"%s\" -> \"%s\";\n", e->from->name, e->to->name); + } + + fprintf(file, "}\n"); + + if(pipe) { + pclose(pipe); + } else { + fclose(file); +#ifdef HAVE_MINGW + unlink(filename); +#endif + + if(rename(tmpname, filename)) { + logger(LOG_ERR, "Could not rename %s to %s: %s\n", tmpname, filename, strerror(errno)); + } + + free(tmpname); + } + + free(filename); } diff --git a/src/hash.c b/src/hash.c deleted file mode 100644 index 63b8f54..0000000 --- a/src/hash.c +++ /dev/null @@ -1,128 +0,0 @@ -/* - hash.c -- hash table management - Copyright (C) 2012-2013 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 - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include "system.h" - -#include "hash.h" -#include "xalloc.h" - -/* Generic hash function */ - -static uint32_t hash_function(const void *p, size_t len) { - const uint8_t *q = p; - uint32_t hash = 0; - - while(true) { - for(int i = len > 4 ? 4 : len; --i;) { - hash += (uint32_t)q[len - i] << (8 * i); - } - - hash *= 0x9e370001UL; // Golden ratio prime. - - if(len <= 4) { - break; - } - - len -= 4; - } - - return hash; -} - -/* Map 32 bits int onto 0..n-1, without throwing away too many bits if n is 2^8 or 2^16 */ - -static uint32_t modulo(uint32_t hash, size_t n) { - if(n == 0x100) { - return (hash >> 24) ^ ((hash >> 16) & 0xff) ^ ((hash >> 8) & 0xff) ^ (hash & 0xff); - } else if(n == 0x10000) { - return (hash >> 16) ^ (hash & 0xffff); - } else { - return hash % n; - } -} - -/* (De)allocation */ - -hash_t *hash_alloc(size_t n, size_t size) { - hash_t *hash = xzalloc(sizeof(*hash)); - hash->n = n; - hash->size = size; - hash->keys = xzalloc(hash->n * hash->size); - hash->values = xzalloc(hash->n * sizeof(*hash->values)); - return hash; -} - -void hash_free(hash_t *hash) { - free(hash->keys); - free(hash->values); - free(hash); -} - -/* Searching and inserting */ - -void hash_insert(hash_t *hash, const void *key, const void *value) { - uint32_t i = modulo(hash_function(key, hash->size), hash->n); - memcpy(hash->keys + i * hash->size, key, hash->size); - hash->values[i] = value; -} - -void *hash_search(const hash_t *hash, const void *key) { - uint32_t i = modulo(hash_function(key, hash->size), hash->n); - - if(hash->values[i] && !memcmp(key, hash->keys + i * hash->size, hash->size)) { - return (void *)hash->values[i]; - } - - return NULL; -} - -void *hash_search_or_insert(hash_t *hash, const void *key, const void *value) { - uint32_t i = modulo(hash_function(key, hash->size), hash->n); - - if(hash->values[i] && !memcmp(key, hash->keys + i * hash->size, hash->size)) { - return (void *)hash->values[i]; - } - - memcpy(hash->keys + i * hash->size, key, hash->size); - hash->values[i] = value; - return NULL; -} - -/* Deleting */ - -void hash_delete(hash_t *hash, const void *key) { - uint32_t i = modulo(hash_function(key, hash->size), hash->n); - hash->values[i] = NULL; -} - -/* Utility functions */ - -void hash_clear(hash_t *hash) { - memset(hash->values, 0, hash->n * sizeof(*hash->values)); -} - -void hash_resize(hash_t *hash, size_t n) { - hash->keys = xrealloc(hash->keys, n * hash->size); - hash->values = xrealloc(hash->values, n * sizeof(*hash->values)); - - if(n > hash->n) { - memset(hash->keys + hash->n * hash->size, 0, (n - hash->n) * hash->size); - memset(hash->values + hash->n, 0, (n - hash->n) * sizeof(*hash->values)); - } -} diff --git a/src/hash.h b/src/hash.h deleted file mode 100644 index e4b1499..0000000 --- a/src/hash.h +++ /dev/null @@ -1,42 +0,0 @@ -#ifndef TINC_HASH_H -#define TINC_HASH_H - -/* - hash.h -- header file for hash.c - Copyright (C) 2012 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 - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -typedef struct hash_t { - size_t n; - size_t size; - char *keys; - const void **values; -} hash_t; - -extern hash_t *hash_alloc(size_t n, size_t size) __attribute__((__malloc__)); -extern void hash_free(hash_t *); - -extern void hash_insert(hash_t *, const void *key, const void *value); -extern void hash_delete(hash_t *, const void *key); - -extern void *hash_search(const hash_t *, const void *key); -extern void *hash_search_or_insert(hash_t *, const void *key, const void *value); - -extern void hash_clear(hash_t *); -extern void hash_resize(hash_t *, size_t n); - -#endif diff --git a/src/have.h b/src/have.h index 402f802..11fa56a 100644 --- a/src/have.h +++ b/src/have.h @@ -4,7 +4,7 @@ /* have.h -- include headers which are known to exist Copyright (C) 1998-2005 Ivo Timmermans - 2003-2016 Guus Sliepen + 2003-2015 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 @@ -22,23 +22,27 @@ */ #ifdef HAVE_MINGW +#ifdef WITH_WINDOWS2000 +#define WINVER Windows2000 +#else #define WINVER WindowsXP -#define WIN32_LEAN_AND_MEAN +#endif #endif #include +#include +#include +#include #include #include -#include #include #include -#include #include +#include + #include #include -#include -#include -#include +#include #ifdef HAVE_MINGW #include @@ -47,12 +51,16 @@ #include #endif +#ifdef HAVE_STDBOOL_H +#include +#endif + #ifdef HAVE_TERMIOS_H #include #endif -#ifdef HAVE_INTTYPES_H -#include +#ifdef HAVE_ALLOCA_H +#include #endif /* Include system specific headers */ @@ -65,6 +73,9 @@ #include #endif +#ifdef HAVE_TIME_H +#include +#endif #ifdef HAVE_SYS_TYPES_H #include @@ -94,8 +105,8 @@ #include #endif -#ifdef HAVE_SYS_UN_H -#include +#ifdef HAVE_SYS_UIO_H +#include #endif #ifdef HAVE_DIRENT_H @@ -187,6 +198,9 @@ #ifdef HAVE_ARPA_NAMESER_H #include +#ifdef STATUS +#undef STATUS +#endif #endif #ifdef HAVE_RESOLV_H @@ -197,20 +211,4 @@ #include #endif -#ifdef HAVE_GETOPT_H -#include -#else -#include "getopt.h" -#endif - -#ifdef STATUS -#undef STATUS -#endif - -#ifdef HAVE_MINGW -#define SLASH "\\" -#else -#define SLASH "/" -#endif - #endif diff --git a/src/ifconfig.c b/src/ifconfig.c deleted file mode 100644 index 4b47ad1..0000000 --- a/src/ifconfig.c +++ /dev/null @@ -1,304 +0,0 @@ -/* - ifconfig.c -- Generate platform specific interface configuration commands - Copyright (C) 2016-2017 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 - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include "system.h" - -#include "conf.h" -#include "ifconfig.h" -#include "subnet.h" - -static long start; - -#ifndef HAVE_MINGW -void ifconfig_header(FILE *out) { - fprintf(out, "#!/bin/sh\n"); - start = ftell(out); -} - -void ifconfig_dhcp(FILE *out) { - fprintf(out, "dhclient -nw \"$INTERFACE\"\n"); -} - -void ifconfig_dhcp6(FILE *out) { - fprintf(out, "dhclient -6 -nw \"$INTERFACE\"\n"); -} - -void ifconfig_slaac(FILE *out) { -#ifdef HAVE_LINUX - fprintf(out, "echo 1 >\"/proc/sys/net/ipv6/conf/$INTERFACE/accept_ra\"\n"); - fprintf(out, "echo 1 >\"/proc/sys/net/ipv6/conf/$INTERFACE/autoconf\"\n"); -#else - fprintf(out, "rtsol \"$INTERFACE\" &\n"); -#endif -} - -bool ifconfig_footer(FILE *out) { - if(ftell(out) == start) { - fprintf(out, "echo 'Unconfigured tinc-up script, please edit '$0'!'\n\n#ifconfig $INTERFACE netmask \n"); - return false; - } else { -#ifdef HAVE_LINUX - fprintf(out, "ip link set \"$INTERFACE\" up\n"); -#else - fprintf(out, "ifconfig \"$INTERFACE\" up\n"); -#endif - return true; - } -} -#else -void ifconfig_header(FILE *out) { - start = ftell(out); -} - -void ifconfig_dhcp(FILE *out) { - fprintf(out, "netsh interface ipv4 set address \"%%INTERFACE%%\" dhcp\n"); -} - -void ifconfig_dhcp6(FILE *out) { - fprintf(stderr, "DHCPv6 requested, but not supported by tinc on this platform\n"); -} - -void ifconfig_slaac(FILE *out) { - // It's the default? -} - -bool ifconfig_footer(FILE *out) { - return ftell(out) != start; -} -#endif - -static subnet_t ipv4, ipv6; - -void ifconfig_address(FILE *out, const char *value) { - subnet_t address = {0}; - char address_str[MAXNETSTR]; - - if(!str2net(&address, value) || !net2str(address_str, sizeof(address_str), &address)) { - fprintf(stderr, "Could not parse address in Ifconfig statement\n"); - return; - } - - switch(address.type) { - case SUBNET_IPV4: - ipv4 = address; - break; - - case SUBNET_IPV6: - ipv6 = address; - break; - - default: - return; - } - -#if defined(HAVE_LINUX) - - switch(address.type) { - case SUBNET_MAC: - fprintf(out, "ip link set \"$INTERFACE\" address %s\n", address_str); - break; - - case SUBNET_IPV4: - fprintf(out, "ip addr replace %s dev \"$INTERFACE\"\n", address_str); - break; - - case SUBNET_IPV6: - fprintf(out, "ip addr replace %s dev \"$INTERFACE\"\n", address_str); - break; - - default: - return; - } - -#elif defined(HAVE_MINGW) || defined(HAVE_CYGWIN) - - switch(address.type) { - case SUBNET_MAC: - fprintf(out, "ip link set \"$INTERFACE\" address %s\n", address_str); - break; - - case SUBNET_IPV4: - fprintf(out, "netsh inetface ipv4 set address \"$INTERFACE\" static %s\n", address_str); - break; - - case SUBNET_IPV6: - fprintf(out, "netsh inetface ipv6 set address \"$INTERFACE\" static %s\n", address_str); - break; - - default: - return; - } - -#else // assume BSD - - switch(address.type) { - case SUBNET_MAC: - fprintf(out, "ifconfig \"$INTERFACE\" link %s\n", address_str); - break; - - case SUBNET_IPV4: - fprintf(out, "ifconfig \"$INTERFACE\" %s\n", address_str); - break; - - case SUBNET_IPV6: - fprintf(out, "ifconfig \"$INTERFACE\" inet6 %s\n", address_str); - break; - - default: - return; - } - -#endif -} - -void ifconfig_route(FILE *out, const char *value) { - subnet_t subnet = {0}, gateway = {0}; - char subnet_str[MAXNETSTR] = "", gateway_str[MAXNETSTR] = ""; - char *sep = strchr(value, ' '); - - if(sep) { - *sep++ = 0; - } - - if(!str2net(&subnet, value) || !net2str(subnet_str, sizeof(subnet_str), &subnet) || subnet.type == SUBNET_MAC) { - fprintf(stderr, "Could not parse subnet in Route statement\n"); - return; - } - - if(sep) { - if(!str2net(&gateway, sep) || !net2str(gateway_str, sizeof(gateway_str), &gateway) || gateway.type != subnet.type) { - fprintf(stderr, "Could not parse gateway in Route statement\n"); - return; - } - - char *slash = strchr(gateway_str, '/'); - - if(slash) { - *slash = 0; - } - } - -#if defined(HAVE_LINUX) - - if(*gateway_str) { - switch(subnet.type) { - case SUBNET_IPV4: - fprintf(out, "ip route add %s via %s dev \"$INTERFACE\"\n", subnet_str, gateway_str); - break; - - case SUBNET_IPV6: - fprintf(out, "ip route add %s via %s dev \"$INTERFACE\"\n", subnet_str, gateway_str); - break; - - default: - return; - } - } else { - switch(subnet.type) { - case SUBNET_IPV4: - fprintf(out, "ip route add %s dev \"$INTERFACE\"\n", subnet_str); - break; - - case SUBNET_IPV6: - fprintf(out, "ip route add %s dev \"$INTERFACE\"\n", subnet_str); - break; - - default: - return; - } - } - -#elif defined(HAVE_MINGW) || defined(HAVE_CYGWIN) - - if(*gateway_str) { - switch(subnet.type) { - case SUBNET_IPV4: - fprintf(out, "netsh inetface ipv4 add route %s \"%%INTERFACE%%\" %s\n", subnet_str, gateway_str); - break; - - case SUBNET_IPV6: - fprintf(out, "netsh inetface ipv6 add route %s \"%%INTERFACE%%\" %s\n", subnet_str, gateway_str); - break; - - default: - return; - } - } else { - switch(subnet.type) { - case SUBNET_IPV4: - fprintf(out, "netsh inetface ipv4 add route %s \"%%INTERFACE%%\"\n", subnet_str); - break; - - case SUBNET_IPV6: - fprintf(out, "netsh inetface ipv6 add route %s \"%%INTERFACE%%\"\n", subnet_str); - break; - - default: - return; - } - } - -#else // assume BSD - - if(!*gateway_str) { - switch(subnet.type) { - case SUBNET_IPV4: - if(!ipv4.type) { - fprintf(stderr, "Route requested but no Ifconfig\n"); - return; - } - - net2str(gateway_str, sizeof(gateway_str), &ipv4); - break; - - case SUBNET_IPV6: - if(!ipv6.type) { - fprintf(stderr, "Route requested but no Ifconfig\n"); - return; - } - - net2str(gateway_str, sizeof(gateway_str), &ipv6); - break; - - default: - return; - } - - char *slash = strchr(gateway_str, '/'); - - if(slash) { - *slash = 0; - } - } - - switch(subnet.type) { - case SUBNET_IPV4: - fprintf(out, "route add %s %s\n", subnet_str, gateway_str); - break; - - case SUBNET_IPV6: - fprintf(out, "route add -inet6 %s %s\n", subnet_str, gateway_str); - break; - - default: - return; - } - -#endif -} diff --git a/src/ifconfig.h b/src/ifconfig.h deleted file mode 100644 index 854780b..0000000 --- a/src/ifconfig.h +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef TINC_IFCONFIG_H -#define TINC_IFCONFIG_H - -/* - ifconfig.h -- header for ifconfig.c. - Copyright (C) 2016 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 - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -extern void ifconfig_dhcp(FILE *out); -extern void ifconfig_dhcp6(FILE *out); -extern void ifconfig_slaac(FILE *out); -extern void ifconfig_address(FILE *out, const char *value); -extern void ifconfig_route(FILE *out, const char *value); -extern void ifconfig_header(FILE *out); -extern bool ifconfig_footer(FILE *out); - -#endif diff --git a/src/info.c b/src/info.c deleted file mode 100644 index 758c0d1..0000000 --- a/src/info.c +++ /dev/null @@ -1,357 +0,0 @@ -/* - info.c -- Show information about a node, subnet or address - Copyright (C) 2012-2017 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 - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include "system.h" - -#include "control_common.h" -#include "list.h" -#include "subnet.h" -#include "tincctl.h" -#include "info.h" -#include "utils.h" -#include "xalloc.h" - -void logger(int level, int priority, const char *format, ...) { - (void)level; - (void)priority; - va_list ap; - - va_start(ap, format); - vfprintf(stderr, format, ap); - va_end(ap); - - fputc('\n', stderr); -} - -char *strip_weight(char *netstr) { - int len = strlen(netstr); - - if(len >= 3 && !strcmp(netstr + len - 3, "#10")) { - netstr[len - 3] = 0; - } - - return netstr; -} - -static int info_node(int fd, const char *item) { - // Check the list of nodes - sendline(fd, "%d %d %s", CONTROL, REQ_DUMP_NODES, item); - - bool found = false; - char line[4096]; - - char node[4096]; - char id[4096]; - char from[4096]; - char to[4096]; - char subnet[4096]; - char host[4096]; - char port[4096]; - char via[4096]; - char nexthop[4096]; - int code, req, cipher, digest, maclength, compression, distance; - short int pmtu, minmtu, maxmtu; - unsigned int options; - union { - node_status_t bits; - uint32_t raw; - } status_union; - node_status_t status; - long int last_state_change; - int udp_ping_rtt; - uint64_t in_packets, in_bytes, out_packets, out_bytes; - - while(recvline(fd, line, sizeof(line))) { - int n = sscanf(line, "%d %d %4095s %4095s %4095s port %4095s %d %d %d %d %x %"PRIx32" %4095s %4095s %d %hd %hd %hd %ld %d %"PRIu64" %"PRIu64" %"PRIu64" %"PRIu64, &code, &req, node, id, host, port, &cipher, &digest, &maclength, &compression, &options, &status_union.raw, nexthop, via, &distance, &pmtu, &minmtu, &maxmtu, &last_state_change, &udp_ping_rtt, &in_packets, &in_bytes, &out_packets, &out_bytes); - - if(n == 2) { - break; - } - - if(n != 24) { - fprintf(stderr, "Unable to parse node dump from tincd.\n"); - return 1; - } - - if(!strcmp(node, item)) { - found = true; - break; - } - } - - if(!found) { - fprintf(stderr, "Unknown node %s.\n", item); - return 1; - } - - while(recvline(fd, line, sizeof(line))) { - if(sscanf(line, "%d %d %4095s", &code, &req, node) == 2) { - break; - } - } - - printf("Node: %s\n", item); - printf("Node ID: %s\n", id); - printf("Address: %s port %s\n", host, port); - - char timestr[32] = "never"; - time_t lsc_time = last_state_change; - - if(last_state_change) { - strftime(timestr, sizeof(timestr), "%Y-%m-%d %H:%M:%S", localtime(&lsc_time)); - } - - status = status_union.bits; - - if(status.reachable) { - printf("Online since: %s\n", timestr); - } else { - printf("Last seen: %s\n", timestr); - } - - printf("Status: "); - - if(status.validkey) { - printf(" validkey"); - } - - if(status.visited) { - printf(" visited"); - } - - if(status.reachable) { - printf(" reachable"); - } - - if(status.indirect) { - printf(" indirect"); - } - - if(status.sptps) { - printf(" sptps"); - } - - if(status.udp_confirmed) { - printf(" udp_confirmed"); - } - - printf("\n"); - - printf("Options: "); - - if(options & OPTION_INDIRECT) { - printf(" indirect"); - } - - if(options & OPTION_TCPONLY) { - printf(" tcponly"); - } - - if(options & OPTION_PMTU_DISCOVERY) { - printf(" pmtu_discovery"); - } - - if(options & OPTION_CLAMP_MSS) { - printf(" clamp_mss"); - } - - printf("\n"); - printf("Protocol: %d.%d\n", PROT_MAJOR, OPTION_VERSION(options)); - printf("Reachability: "); - - if(!strcmp(host, "MYSELF")) { - printf("can reach itself\n"); - } else if(!status.reachable) { - printf("unreachable\n"); - } else if(strcmp(via, item)) { - printf("indirectly via %s\n", via); - } else if(!status.validkey) { - printf("unknown\n"); - } else if(minmtu > 0) { - printf("directly with UDP\nPMTU: %d\n", pmtu); - - if(udp_ping_rtt != -1) { - printf("RTT: %d.%03d\n", udp_ping_rtt / 1000, udp_ping_rtt % 1000); - } - } else if(!strcmp(nexthop, item)) { - printf("directly with TCP\n"); - } else { - printf("none, forwarded via %s\n", nexthop); - } - - printf("RX: %"PRIu64" packets %"PRIu64" bytes\n", in_packets, in_bytes); - printf("TX: %"PRIu64" packets %"PRIu64" bytes\n", out_packets, out_bytes); - - // List edges - printf("Edges: "); - sendline(fd, "%d %d %s", CONTROL, REQ_DUMP_EDGES, item); - - while(recvline(fd, line, sizeof(line))) { - int n = sscanf(line, "%d %d %4095s %4095s", &code, &req, from, to); - - if(n == 2) { - break; - } - - if(n != 4) { - fprintf(stderr, "Unable to parse edge dump from tincd.\n%s\n", line); - return 1; - } - - if(!strcmp(from, item)) { - printf(" %s", to); - } - } - - printf("\n"); - - // List subnets - printf("Subnets: "); - sendline(fd, "%d %d %s", CONTROL, REQ_DUMP_SUBNETS, item); - - while(recvline(fd, line, sizeof(line))) { - int n = sscanf(line, "%d %d %4095s %4095s", &code, &req, subnet, from); - - if(n == 2) { - break; - } - - if(n != 4) { - fprintf(stderr, "Unable to parse subnet dump from tincd.\n"); - return 1; - } - - if(!strcmp(from, item)) { - printf(" %s", strip_weight(subnet)); - } - } - - printf("\n"); - - return 0; -} - -static int info_subnet(int fd, const char *item) { - subnet_t subnet, find; - - if(!str2net(&find, item)) { - fprintf(stderr, "Could not parse subnet or address '%s'.\n", item); - return 1; - } - - bool address = !strchr(item, '/'); - bool weight = strchr(item, '#'); - bool found = false; - - char line[4096]; - char netstr[4096]; - char owner[4096]; - - int code, req; - - sendline(fd, "%d %d %s", CONTROL, REQ_DUMP_SUBNETS, item); - - while(recvline(fd, line, sizeof(line))) { - int n = sscanf(line, "%d %d %4095s %4095s", &code, &req, netstr, owner); - - if(n == 2) { - break; - } - - if(n != 4 || !str2net(&subnet, netstr)) { - fprintf(stderr, "Unable to parse subnet dump from tincd.\n"); - return 1; - } - - if(find.type != subnet.type) { - continue; - } - - if(weight) { - if(find.weight != subnet.weight) { - continue; - } - } - - if(find.type == SUBNET_IPV4) { - if(address) { - if(maskcmp(&find.net.ipv4.address, &subnet.net.ipv4.address, subnet.net.ipv4.prefixlength)) { - continue; - } - } else { - if(find.net.ipv4.prefixlength != subnet.net.ipv4.prefixlength) { - continue; - } - - if(memcmp(&find.net.ipv4.address, &subnet.net.ipv4.address, sizeof(subnet.net.ipv4))) { - continue; - } - } - } else if(find.type == SUBNET_IPV6) { - if(address) { - if(maskcmp(&find.net.ipv6.address, &subnet.net.ipv6.address, subnet.net.ipv6.prefixlength)) { - continue; - } - } else { - if(find.net.ipv6.prefixlength != subnet.net.ipv6.prefixlength) { - continue; - } - - if(memcmp(&find.net.ipv6.address, &subnet.net.ipv6.address, sizeof(subnet.net.ipv6))) { - continue; - } - } - } - - if(find.type == SUBNET_MAC) { - if(memcmp(&find.net.mac.address, &subnet.net.mac.address, sizeof(subnet.net.mac))) { - continue; - } - } - - found = true; - printf("Subnet: %s\n", strip_weight(netstr)); - printf("Owner: %s\n", owner); - } - - if(!found) { - if(address) { - fprintf(stderr, "Unknown address %s.\n", item); - } else { - fprintf(stderr, "Unknown subnet %s.\n", item); - } - - return 1; - } - - return 0; -} - -int info(int fd, const char *item) { - if(check_id(item)) { - return info_node(fd, item); - } - - if(strchr(item, '.') || strchr(item, ':')) { - return info_subnet(fd, item); - } - - fprintf(stderr, "Argument is not a node name, subnet or address.\n"); - return 1; -} diff --git a/src/info.h b/src/info.h deleted file mode 100644 index 1b323e0..0000000 --- a/src/info.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef TINC_INFO_H -#define TINC_INFO_H - -/* - info.h -- header for info.c. - Copyright (C) 2012 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 - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -extern int info(int fd, const char *item); -extern char *strip_weight(char *); - -#endif diff --git a/src/invitation.c b/src/invitation.c deleted file mode 100644 index 500f243..0000000 --- a/src/invitation.c +++ /dev/null @@ -1,1351 +0,0 @@ -/* - invitation.c -- Create and accept invitations - Copyright (C) 2013-2017 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 - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include "system.h" - -#include "control_common.h" -#include "crypto.h" -#include "ecdsa.h" -#include "ecdsagen.h" -#include "ifconfig.h" -#include "invitation.h" -#include "names.h" -#include "netutl.h" -#include "rsagen.h" -#include "script.h" -#include "sptps.h" -#include "subnet.h" -#include "tincctl.h" -#include "utils.h" -#include "xalloc.h" - -#include "ed25519/sha512.h" - -int addressfamily = AF_UNSPEC; - -static void scan_for_hostname(const char *filename, char **hostname, char **port) { - if(!filename || (*hostname && *port)) { - return; - } - - FILE *f = fopen(filename, "r"); - - if(!f) { - return; - } - - while(fgets(line, sizeof(line), f)) { - if(!rstrip(line)) { - continue; - } - - char *p = line, *q; - p += strcspn(p, "\t ="); - - if(!*p) { - continue; - } - - q = p + strspn(p, "\t "); - - if(*q == '=') { - q += 1 + strspn(q + 1, "\t "); - } - - *p = 0; - p = q + strcspn(q, "\t "); - - if(*p) { - *p++ = 0; - } - - p += strspn(p, "\t "); - p[strcspn(p, "\t ")] = 0; - - if(!*port && !strcasecmp(line, "Port")) { - *port = xstrdup(q); - } else if(!*hostname && !strcasecmp(line, "Address")) { - *hostname = xstrdup(q); - - if(*p) { - free(*port); - *port = xstrdup(p); - } - } - - if(*hostname && *port) { - break; - } - } - - fclose(f); -} - -char *get_my_hostname() { - char *hostname = NULL; - char *port = NULL; - char *hostport = NULL; - char *name = get_my_name(false); - char filename[PATH_MAX] = {0}; - - // Use first Address statement in own host config file - if(check_id(name)) { - snprintf(filename, sizeof(filename), "%s" SLASH "hosts" SLASH "%s", confbase, name); - scan_for_hostname(filename, &hostname, &port); - scan_for_hostname(tinc_conf, &hostname, &port); - } - - if(hostname) { - goto done; - } - - // If that doesn't work, guess externally visible hostname - fprintf(stderr, "Trying to discover externally visible hostname...\n"); - struct addrinfo *ai = str2addrinfo("tinc-vpn.org", "80", SOCK_STREAM); - struct addrinfo *aip = ai; - static const char request[] = "GET http://tinc-vpn.org/host.cgi HTTP/1.0\r\n\r\n"; - - while(aip) { - int s = socket(aip->ai_family, aip->ai_socktype, aip->ai_protocol); - - if(s >= 0) { - if(connect(s, aip->ai_addr, aip->ai_addrlen)) { - closesocket(s); - s = -1; - } - } - - if(s >= 0) { - send(s, request, sizeof(request) - 1, 0); - int len = recv(s, line, sizeof(line) - 1, MSG_WAITALL); - - if(len > 0) { - line[len] = 0; - - if(line[len - 1] == '\n') { - line[--len] = 0; - } - - char *p = strrchr(line, '\n'); - - if(p && p[1]) { - hostname = xstrdup(p + 1); - } - } - - closesocket(s); - - if(hostname) { - break; - } - } - - aip = aip->ai_next; - continue; - } - - if(ai) { - freeaddrinfo(ai); - } - - // Check that the hostname is reasonable - if(hostname) { - for(char *p = hostname; *p; p++) { - if(isalnum(*p) || *p == '-' || *p == '.' || *p == ':') { - continue; - } - - // If not, forget it. - free(hostname); - hostname = NULL; - break; - } - } - - if(!tty) { - if(!hostname) { - fprintf(stderr, "Could not determine the external address or hostname. Please set Address manually.\n"); - free(port); - return NULL; - } - - goto save; - } - -again: - fprintf(stderr, "Please enter your host's external address or hostname"); - - if(hostname) { - fprintf(stderr, " [%s]", hostname); - } - - fprintf(stderr, ": "); - - if(!fgets(line, sizeof(line), stdin)) { - fprintf(stderr, "Error while reading stdin: %s\n", strerror(errno)); - free(hostname); - free(port); - return NULL; - } - - if(!rstrip(line)) { - if(hostname) { - goto save; - } else { - goto again; - } - } - - for(char *p = line; *p; p++) { - if(isalnum(*p) || *p == '-' || *p == '.') { - continue; - } - - fprintf(stderr, "Invalid address or hostname.\n"); - goto again; - } - - free(hostname); - hostname = xstrdup(line); - -save: - - if(*filename) { - FILE *f = fopen(filename, "a"); - - if(f) { - fprintf(f, "\nAddress = %s\n", hostname); - fclose(f); - } else { - fprintf(stderr, "Could not append Address to %s: %s\n", filename, strerror(errno)); - } - } - -done: - - if(port) { - if(strchr(hostname, ':')) { - xasprintf(&hostport, "[%s]:%s", hostname, port); - } else { - xasprintf(&hostport, "%s:%s", hostname, port); - } - } else { - if(strchr(hostname, ':')) { - xasprintf(&hostport, "[%s]", hostname); - } else { - hostport = xstrdup(hostname); - } - } - - free(hostname); - free(port); - return hostport; -} - -static bool fcopy(FILE *out, const char *filename) { - FILE *in = fopen(filename, "r"); - - if(!in) { - fprintf(stderr, "Could not open %s: %s\n", filename, strerror(errno)); - return false; - } - - char buf[1024]; - size_t len; - - while((len = fread(buf, 1, sizeof(buf), in))) { - fwrite(buf, len, 1, out); - } - - fclose(in); - return true; -} - -int cmd_invite(int argc, char *argv[]) { - if(argc < 2) { - fprintf(stderr, "Not enough arguments!\n"); - return 1; - } - - // Check validity of the new node's name - if(!check_id(argv[1])) { - fprintf(stderr, "Invalid name for node.\n"); - return 1; - } - - myname = get_my_name(true); - - if(!myname) { - return 1; - } - - // Ensure no host configuration file with that name exists - char filename[PATH_MAX]; - snprintf(filename, sizeof(filename), "%s" SLASH "hosts" SLASH "%s", confbase, argv[1]); - - if(!access(filename, F_OK)) { - fprintf(stderr, "A host config file for %s already exists!\n", argv[1]); - return 1; - } - - // If a daemon is running, ensure no other nodes know about this name - if(connect_tincd(false)) { - bool found = false; - sendline(fd, "%d %d", CONTROL, REQ_DUMP_NODES); - - while(recvline(fd, line, sizeof(line))) { - char node[4096]; - int code, req; - - if(sscanf(line, "%d %d %4095s", &code, &req, node) != 3) { - break; - } - - if(!strcmp(node, argv[1])) { - found = true; - } - } - - if(found) { - fprintf(stderr, "A node with name %s is already known!\n", argv[1]); - return 1; - } - } - - snprintf(filename, sizeof(filename), "%s" SLASH "invitations", confbase); - - if(mkdir(filename, 0700) && errno != EEXIST) { - fprintf(stderr, "Could not create directory %s: %s\n", filename, strerror(errno)); - return 1; - } - - // Count the number of valid invitations, clean up old ones - DIR *dir = opendir(filename); - - if(!dir) { - fprintf(stderr, "Could not read directory %s: %s\n", filename, strerror(errno)); - return 1; - } - - errno = 0; - int count = 0; - struct dirent *ent; - time_t deadline = time(NULL) - 604800; // 1 week in the past - - while((ent = readdir(dir))) { - if(strlen(ent->d_name) != 24) { - continue; - } - - char invname[PATH_MAX]; - struct stat st; - - if((size_t)snprintf(invname, sizeof(invname), "%s" SLASH "%s", filename, ent->d_name) >= sizeof(invname)) { - fprintf(stderr, "Filename too long: %s" SLASH "%s\n", filename, ent->d_name); - continue; - } - - if(!stat(invname, &st)) { - if(deadline < st.st_mtime) { - count++; - } else { - unlink(invname); - } - } else { - fprintf(stderr, "Could not stat %s: %s\n", invname, strerror(errno)); - errno = 0; - } - } - - closedir(dir); - - if(errno) { - fprintf(stderr, "Error while reading directory %s: %s\n", filename, strerror(errno)); - return 1; - } - - ecdsa_t *key; - snprintf(filename, sizeof(filename), "%s" SLASH "invitations" SLASH "ed25519_key.priv", confbase); - - // Remove the key if there are no outstanding invitations. - if(!count) { - unlink(filename); - } - - // Create a new key if necessary. - FILE *f = fopen(filename, "r"); - - if(!f) { - if(errno != ENOENT) { - fprintf(stderr, "Could not read %s: %s\n", filename, strerror(errno)); - return 1; - } - - key = ecdsa_generate(); - - if(!key) { - return 1; - } - - f = fopen(filename, "w"); - - if(!f) { - fprintf(stderr, "Could not write %s: %s\n", filename, strerror(errno)); - return 1; - } - - chmod(filename, 0600); - - if(!ecdsa_write_pem_private_key(key, f)) { - fprintf(stderr, "Could not write ECDSA private key\n"); - fclose(f); - return 1; - } - - fclose(f); - - if(connect_tincd(true)) { - sendline(fd, "%d %d", CONTROL, REQ_RELOAD); - } else { - fprintf(stderr, "Could not signal the tinc daemon. Please restart or reload it manually.\n"); - } - } else { - key = ecdsa_read_pem_private_key(f); - fclose(f); - - if(!key) { - fprintf(stderr, "Could not read private key from %s\n", filename); - } - } - - if(!key) { - return 1; - } - - // Create a hash of the key. - char hash[64]; - char *fingerprint = ecdsa_get_base64_public_key(key); - sha512(fingerprint, strlen(fingerprint), hash); - b64encode_urlsafe(hash, hash, 18); - - // Create a random cookie for this invitation. - char cookie[25]; - randomize(cookie, 18); - - // Create a filename that doesn't reveal the cookie itself - char buf[18 + strlen(fingerprint)]; - char cookiehash[64]; - memcpy(buf, cookie, 18); - memcpy(buf + 18, fingerprint, sizeof(buf) - 18); - sha512(buf, sizeof(buf), cookiehash); - b64encode_urlsafe(cookiehash, cookiehash, 18); - - b64encode_urlsafe(cookie, cookie, 18); - - // Create a file containing the details of the invitation. - snprintf(filename, sizeof(filename), "%s" SLASH "invitations" SLASH "%s", confbase, cookiehash); - int ifd = open(filename, O_RDWR | O_CREAT | O_EXCL, 0600); - - if(!ifd) { - fprintf(stderr, "Could not create invitation file %s: %s\n", filename, strerror(errno)); - return 1; - } - - f = fdopen(ifd, "w"); - - if(!f) { - abort(); - } - - // Get the local address - char *address = get_my_hostname(); - - // Fill in the details. - fprintf(f, "Name = %s\n", argv[1]); - - if(check_netname(netname, true)) { - fprintf(f, "NetName = %s\n", netname); - } - - fprintf(f, "ConnectTo = %s\n", myname); - - // Copy Broadcast and Mode - FILE *tc = fopen(tinc_conf, "r"); - - if(tc) { - char buf[1024]; - - while(fgets(buf, sizeof(buf), tc)) { - if((!strncasecmp(buf, "Mode", 4) && strchr(" \t=", buf[4])) - || (!strncasecmp(buf, "Broadcast", 9) && strchr(" \t=", buf[9]))) { - fputs(buf, f); - - // Make sure there is a newline character. - if(!strchr(buf, '\n')) { - fputc('\n', f); - } - } - } - - fclose(tc); - } - - fprintf(f, "#---------------------------------------------------------------#\n"); - fprintf(f, "Name = %s\n", myname); - - char filename2[PATH_MAX]; - snprintf(filename2, sizeof(filename2), "%s" SLASH "hosts" SLASH "%s", confbase, myname); - fcopy(f, filename2); - fclose(f); - - // Create an URL from the local address, key hash and cookie - char *url; - xasprintf(&url, "%s/%s%s", address, hash, cookie); - - // Call the inviation-created script - environment_t env; - environment_init(&env); - environment_add(&env, "NODE=%s", argv[1]); - environment_add(&env, "INVITATION_FILE=%s", filename); - environment_add(&env, "INVITATION_URL=%s", url); - execute_script("invitation-created", &env); - environment_exit(&env); - - puts(url); - free(url); - free(address); - - return 0; -} - -static int sock; -static char cookie[18]; -static sptps_t sptps; -static char *data; -static size_t datalen; -static bool success = false; - -static char cookie[18], hash[18]; - -static char *get_line(const char **data) { - if(!data || !*data) { - return NULL; - } - - if(! **data) { - *data = NULL; - return NULL; - } - - static char line[1024]; - const char *end = strchr(*data, '\n'); - size_t len = end ? (size_t)(end - *data) : strlen(*data); - - if(len >= sizeof(line)) { - fprintf(stderr, "Maximum line length exceeded!\n"); - return NULL; - } - - if(len && !isprint(**data)) { - abort(); - } - - memcpy(line, *data, len); - line[len] = 0; - - if(end) { - *data = end + 1; - } else { - *data = NULL; - } - - return line; -} - -static char *get_value(const char *data, const char *var) { - char *line = get_line(&data); - - if(!line) { - return NULL; - } - - char *sep = line + strcspn(line, " \t="); - char *val = sep + strspn(sep, " \t"); - - if(*val == '=') { - val += 1 + strspn(val + 1, " \t"); - } - - *sep = 0; - - if(strcasecmp(line, var)) { - return NULL; - } - - return val; -} - -static char *grep(const char *data, const char *var) { - static char value[1024]; - - const char *p = data; - int varlen = strlen(var); - - // Skip all lines not starting with var - while(strncasecmp(p, var, varlen) || !strchr(" \t=", p[varlen])) { - p = strchr(p, '\n'); - - if(!p) { - break; - } else { - p++; - } - } - - if(!p) { - return NULL; - } - - p += varlen; - p += strspn(p, " \t"); - - if(*p == '=') { - p += 1 + strspn(p + 1, " \t"); - } - - const char *e = strchr(p, '\n'); - - if(!e) { - return xstrdup(p); - } - - if((size_t)(e - p) >= sizeof(value)) { - fprintf(stderr, "Maximum line length exceeded!\n"); - return NULL; - } - - memcpy(value, p, e - p); - value[e - p] = 0; - return value; -} - -static bool finalize_join(void) { - const char *temp_name = get_value(data, "Name"); - - if(!temp_name) { - fprintf(stderr, "No Name found in invitation!\n"); - return false; - } - - size_t len = strlen(temp_name); - char name[len + 1]; - memcpy(name, temp_name, len); - name[len] = 0; - - if(!check_id(name)) { - fprintf(stderr, "Invalid Name found in invitation!\n"); - return false; - } - - if(!netname) { - netname = grep(data, "NetName"); - - if(netname && !check_netname(netname, true)) { - fprintf(stderr, "Unsafe NetName found in invitation!\n"); - return false; - } - } - - bool ask_netname = false; - char temp_netname[32]; - -make_names: - - if(!confbasegiven) { - free(confbase); - confbase = NULL; - } - - make_names(false); - - free(tinc_conf); - free(hosts_dir); - - xasprintf(&tinc_conf, "%s" SLASH "tinc.conf", confbase); - xasprintf(&hosts_dir, "%s" SLASH "hosts", confbase); - - if(!access(tinc_conf, F_OK)) { - fprintf(stderr, "Configuration file %s already exists!\n", tinc_conf); - - if(confbasegiven) { - return false; - } - - // Generate a random netname, ask for a better one later. - ask_netname = true; - snprintf(temp_netname, sizeof(temp_netname), "join_%x", rand()); - netname = temp_netname; - goto make_names; - } - - if(mkdir(confbase, 0777) && errno != EEXIST) { - fprintf(stderr, "Could not create directory %s: %s\n", confbase, strerror(errno)); - return false; - } - - if(mkdir(hosts_dir, 0777) && errno != EEXIST) { - fprintf(stderr, "Could not create directory %s: %s\n", hosts_dir, strerror(errno)); - return false; - } - - FILE *f = fopen(tinc_conf, "w"); - - if(!f) { - fprintf(stderr, "Could not create file %s: %s\n", tinc_conf, strerror(errno)); - return false; - } - - fprintf(f, "Name = %s\n", name); - - char filename[PATH_MAX]; - snprintf(filename, sizeof(filename), "%s" SLASH "%s", hosts_dir, name); - FILE *fh = fopen(filename, "w"); - - if(!fh) { - fprintf(stderr, "Could not create file %s: %s\n", filename, strerror(errno)); - fclose(f); - return false; - } - - snprintf(filename, sizeof(filename), "%s" SLASH "invitation-data", confbase); - FILE *finv = fopen(filename, "w"); - - if(!finv || fwrite(data, datalen, 1, finv) != 1) { - fprintf(stderr, "Could not create file %s: %s\n", filename, strerror(errno)); - fclose(fh); - fclose(f); - fclose(finv); - return false; - } - - fclose(finv); - - snprintf(filename, sizeof(filename), "%s" SLASH "tinc-up.invitation", confbase); - FILE *fup = fopen(filename, "w"); - - if(!fup) { - fprintf(stderr, "Could not create file %s: %s\n", filename, strerror(errno)); - fclose(f); - fclose(fh); - return false; - } - - ifconfig_header(fup); - - // Filter first chunk on approved keywords, split between tinc.conf and hosts/Name - // Generate a tinc-up script from Ifconfig and Route keywords. - // Other chunks go unfiltered to their respective host config files - const char *p = data; - char *l, *value; - - while((l = get_line(&p))) { - // Ignore comments - if(*l == '#') { - continue; - } - - // Split line into variable and value - int len = strcspn(l, "\t ="); - value = l + len; - value += strspn(value, "\t "); - - if(*value == '=') { - value++; - value += strspn(value, "\t "); - } - - l[len] = 0; - - // Ignore lines with empty variable names - if(!*l) { - continue; - } - - // Is it a Name? - if(!strcasecmp(l, "Name")) { - if(strcmp(value, name)) { - break; - } else { - continue; - } - } else if(!strcasecmp(l, "NetName")) { - continue; - } - - // Check the list of known variables - bool found = false; - int i; - - for(i = 0; variables[i].name; i++) { - if(strcasecmp(l, variables[i].name)) { - continue; - } - - found = true; - break; - } - - // Handle Ifconfig and Route statements - if(!found) { - if(!strcasecmp(l, "Ifconfig")) { - if(!strcasecmp(value, "dhcp")) { - ifconfig_dhcp(fup); - } else if(!strcasecmp(value, "dhcp6")) { - ifconfig_dhcp6(fup); - } else if(!strcasecmp(value, "slaac")) { - ifconfig_slaac(fup); - } else { - ifconfig_address(fup, value); - } - - continue; - } else if(!strcasecmp(l, "Route")) { - ifconfig_route(fup, value); - continue; - } - } - - // Ignore unknown and unsafe variables - if(!found) { - fprintf(stderr, "Ignoring unknown variable '%s' in invitation.\n", l); - continue; - } else if(!(variables[i].type & VAR_SAFE)) { - fprintf(stderr, "Ignoring unsafe variable '%s' in invitation.\n", l); - continue; - } - - // Copy the safe variable to the right config file - fprintf((variables[i].type & VAR_HOST) ? fh : f, "%s = %s\n", l, value); - } - - fclose(f); - bool valid_tinc_up = ifconfig_footer(fup); - fclose(fup); - - while(l && !strcasecmp(l, "Name")) { - if(!check_id(value)) { - fprintf(stderr, "Invalid Name found in invitation.\n"); - return false; - } - - if(!strcmp(value, name)) { - fprintf(stderr, "Secondary chunk would overwrite our own host config file.\n"); - return false; - } - - snprintf(filename, sizeof(filename), "%s" SLASH "%s", hosts_dir, value); - f = fopen(filename, "w"); - - if(!f) { - fprintf(stderr, "Could not create file %s: %s\n", filename, strerror(errno)); - return false; - } - - while((l = get_line(&p))) { - if(!strcmp(l, "#---------------------------------------------------------------#")) { - continue; - } - - int len = strcspn(l, "\t ="); - - if(len == 4 && !strncasecmp(l, "Name", 4)) { - value = l + len; - value += strspn(value, "\t "); - - if(*value == '=') { - value++; - value += strspn(value, "\t "); - } - - l[len] = 0; - break; - } - - fputs(l, f); - fputc('\n', f); - } - - fclose(f); - } - - // Generate our key and send a copy to the server - ecdsa_t *key = ecdsa_generate(); - - if(!key) { - return false; - } - - char *b64key = ecdsa_get_base64_public_key(key); - - if(!b64key) { - return false; - } - - snprintf(filename, sizeof(filename), "%s" SLASH "ed25519_key.priv", confbase); - f = fopenmask(filename, "w", 0600); - - if(!f) { - return false; - } - - if(!ecdsa_write_pem_private_key(key, f)) { - fprintf(stderr, "Error writing private key!\n"); - ecdsa_free(key); - fclose(f); - return false; - } - - fclose(f); - - fprintf(fh, "Ed25519PublicKey = %s\n", b64key); - - sptps_send_record(&sptps, 1, b64key, strlen(b64key)); - free(b64key); - ecdsa_free(key); - -#ifndef DISABLE_LEGACY - rsa_t *rsa = rsa_generate(2048, 0x1001); - snprintf(filename, sizeof(filename), "%s" SLASH "rsa_key.priv", confbase); - f = fopenmask(filename, "w", 0600); - - if(!f || !rsa_write_pem_private_key(rsa, f)) { - fprintf(stderr, "Could not write private RSA key\n"); - } else if(!rsa_write_pem_public_key(rsa, fh)) { - fprintf(stderr, "Could not write public RSA key\n"); - } - - fclose(f); - - fclose(fh); - - rsa_free(rsa); -#endif - - check_port(name); - -ask_netname: - - if(ask_netname && tty) { - fprintf(stderr, "Enter a new netname: "); - - if(!fgets(line, sizeof(line), stdin)) { - fprintf(stderr, "Error while reading stdin: %s\n", strerror(errno)); - return false; - } - - if(!*line || *line == '\n') { - goto ask_netname; - } - - line[strlen(line) - 1] = 0; - - char newbase[PATH_MAX]; - - if((size_t)snprintf(newbase, sizeof(newbase), CONFDIR SLASH "tinc" SLASH "%s", line) >= sizeof(newbase)) { - fprintf(stderr, "Filename too long: " CONFDIR SLASH "tinc" SLASH "%s\n", line); - goto ask_netname; - } - - if(rename(confbase, newbase)) { - fprintf(stderr, "Error trying to rename %s to %s: %s\n", confbase, newbase, strerror(errno)); - goto ask_netname; - } - - netname = line; - make_names(false); - } - - char filename2[PATH_MAX]; - snprintf(filename, sizeof(filename), "%s" SLASH "tinc-up.invitation", confbase); - snprintf(filename2, sizeof(filename2), "%s" SLASH "tinc-up", confbase); - - if(valid_tinc_up) { - if(tty) { - FILE *fup = fopen(filename, "r"); - - if(fup) { - fprintf(stderr, "\nPlease review the following tinc-up script:\n\n"); - - char buf[MAXSIZE]; - - while(fgets(buf, sizeof(buf), fup)) { - fputs(buf, stderr); - } - - fclose(fup); - - int response = 0; - - do { - fprintf(stderr, "\nDo you want to use this script [y]es/[n]o/[e]dit? "); - response = tolower(getchar()); - } while(!strchr("yne", response)); - - fprintf(stderr, "\n"); - - if(response == 'e') { - char *command; -#ifndef HAVE_MINGW - const char *editor = getenv("VISUAL"); - if (!editor) - editor = getenv("EDITOR"); - if (!editor) - editor = "vi"; - - xasprintf(&command, "\"%s\" \"%s\"", editor, filename); -#else - xasprintf(&command, "edit \"%s\"", filename); -#endif - - if(system(command)) { - response = 'n'; - } else { - response = 'y'; - } - - free(command); - } - - if(response == 'y') { - rename(filename, filename2); - chmod(filename2, 0755); - fprintf(stderr, "tinc-up enabled.\n"); - } else { - fprintf(stderr, "tinc-up has been left disabled.\n"); - } - } - } else { - fprintf(stderr, "A tinc-up script was generated, but has been left disabled.\n"); - } - } else { - // A placeholder was generated. - rename(filename, filename2); - chmod(filename2, 0755); - } - - fprintf(stderr, "Configuration stored in: %s\n", confbase); - - return true; -} - - -static bool invitation_send(void *handle, uint8_t type, const void *vdata, size_t len) { - (void)handle; - (void)type; - const char *data = vdata; - - while(len) { - int result = send(sock, data, len, 0); - - if(result == -1 && errno == EINTR) { - continue; - } else if(result <= 0) { - return false; - } - - data += result; - len -= result; - } - - return true; -} - -static bool invitation_receive(void *handle, uint8_t type, const void *msg, uint16_t len) { - (void)handle; - - switch(type) { - case SPTPS_HANDSHAKE: - return sptps_send_record(&sptps, 0, cookie, sizeof(cookie)); - - case 0: - data = xrealloc(data, datalen + len + 1); - memcpy(data + datalen, msg, len); - datalen += len; - data[datalen] = 0; - break; - - case 1: - return finalize_join(); - - case 2: - fprintf(stderr, "Invitation successfully accepted.\n"); - shutdown(sock, SHUT_RDWR); - success = true; - break; - - default: - return false; - } - - return true; -} - -int cmd_join(int argc, char *argv[]) { - free(data); - data = NULL; - datalen = 0; - - if(argc > 2) { - fprintf(stderr, "Too many arguments!\n"); - return 1; - } - - // Make sure confbase exists and is accessible. - if(!confbase_given && mkdir(confdir, 0755) && errno != EEXIST) { - fprintf(stderr, "Could not create directory %s: %s\n", confdir, strerror(errno)); - return 1; - } - - if(mkdir(confbase, 0777) && errno != EEXIST) { - fprintf(stderr, "Could not create directory %s: %s\n", confbase, strerror(errno)); - return 1; - } - - if(access(confbase, R_OK | W_OK | X_OK)) { - fprintf(stderr, "No permission to write in directory %s: %s\n", confbase, strerror(errno)); - return 1; - } - - // If a netname or explicit configuration directory is specified, check for an existing tinc.conf. - if((netname || confbasegiven) && !access(tinc_conf, F_OK)) { - fprintf(stderr, "Configuration file %s already exists!\n", tinc_conf); - return 1; - } - - // Either read the invitation from the command line or from stdin. - char *invitation; - - if(argc > 1) { - invitation = argv[1]; - } else { - if(tty) { - fprintf(stderr, "Enter invitation URL: "); - } - - errno = EPIPE; - - if(!fgets(line, sizeof(line), stdin)) { - fprintf(stderr, "Error while reading stdin: %s\n", strerror(errno)); - return false; - } - - invitation = line; - } - - // Parse the invitation URL. - rstrip(line); - - char *slash = strchr(invitation, '/'); - - if(!slash) { - goto invalid; - } - - *slash++ = 0; - - if(strlen(slash) != 48) { - goto invalid; - } - - char *address = invitation; - char *port = NULL; - - if(*address == '[') { - address++; - char *bracket = strchr(address, ']'); - - if(!bracket) { - goto invalid; - } - - *bracket = 0; - - if(bracket[1] == ':') { - port = bracket + 2; - } - } else { - port = strchr(address, ':'); - - if(port) { - *port++ = 0; - } - } - - if(!port || !*port) { - port = "655"; - } - - if(!b64decode(slash, hash, 24) || !b64decode(slash + 24, cookie, 24)) { - goto invalid; - } - - // Generate a throw-away key for the invitation. - ecdsa_t *key = ecdsa_generate(); - - if(!key) { - return 1; - } - - char *b64key = ecdsa_get_base64_public_key(key); - - // Connect to the tinc daemon mentioned in the URL. - struct addrinfo *ai = str2addrinfo(address, port, SOCK_STREAM); - - if(!ai) { - return 1; - } - - struct addrinfo *aip = NULL; - -next: - if(!aip) { - aip = ai; - } else { - aip = aip->ai_next; - - if(!aip) { - freeaddrinfo(ai); - return 1; - } - } - - sock = socket(aip->ai_family, aip->ai_socktype, aip->ai_protocol); - - if(sock <= 0) { - fprintf(stderr, "Could not open socket: %s\n", strerror(errno)); - goto next; - } - - if(connect(sock, aip->ai_addr, aip->ai_addrlen)) { - char *addrstr, *portstr; - sockaddr2str((sockaddr_t *)aip->ai_addr, &addrstr, &portstr); - fprintf(stderr, "Could not connect to %s port %s: %s\n", addrstr, portstr, strerror(errno)); - free(addrstr); - free(portstr); - closesocket(sock); - goto next; - } - - fprintf(stderr, "Connected to %s port %s...\n", address, port); - - // Tell him we have an invitation, and give him our throw-away key. - int len = snprintf(line, sizeof(line), "0 ?%s %d.%d\n", b64key, PROT_MAJOR, PROT_MINOR); - - if(len <= 0 || (size_t)len >= sizeof(line)) { - abort(); - } - - if(!sendline(sock, "0 ?%s %d.%d", b64key, PROT_MAJOR, 1)) { - fprintf(stderr, "Error sending request to %s port %s: %s\n", address, port, strerror(errno)); - closesocket(sock); - goto next; - } - - char hisname[4096] = ""; - int code, hismajor, hisminor = 0; - - if(!recvline(sock, line, sizeof(line)) || sscanf(line, "%d %4095s %d.%d", &code, hisname, &hismajor, &hisminor) < 3 || code != 0 || hismajor != PROT_MAJOR || !check_id(hisname) || !recvline(sock, line, sizeof(line)) || !rstrip(line) || sscanf(line, "%d ", &code) != 1 || code != ACK || strlen(line) < 3) { - fprintf(stderr, "Cannot read greeting from peer\n"); - closesocket(sock); - goto next; - } - - freeaddrinfo(ai); - - // Check if the hash of the key he gave us matches the hash in the URL. - char *fingerprint = line + 2; - char hishash[64]; - - if(sha512(fingerprint, strlen(fingerprint), hishash)) { - fprintf(stderr, "Could not create digest\n%s\n", line + 2); - return 1; - } - - if(memcmp(hishash, hash, 18)) { - fprintf(stderr, "Peer has an invalid key!\n%s\n", line + 2); - return 1; - - } - - ecdsa_t *hiskey = ecdsa_set_base64_public_key(fingerprint); - - if(!hiskey) { - return 1; - } - - // Start an SPTPS session - if(!sptps_start(&sptps, NULL, true, false, key, hiskey, "tinc invitation", 15, invitation_send, invitation_receive)) { - return 1; - } - - // Feed rest of input buffer to SPTPS - if(!sptps_receive_data(&sptps, buffer, blen)) { - return 1; - } - - while((len = recv(sock, line, sizeof(line), 0))) { - if(len < 0) { - if(errno == EINTR) { - continue; - } - - fprintf(stderr, "Error reading data from %s port %s: %s\n", address, port, strerror(errno)); - return 1; - } - - char *p = line; - - while(len) { - int done = sptps_receive_data(&sptps, p, len); - - if(!done) { - return 1; - } - - len -= done; - p += done; - } - } - - sptps_stop(&sptps); - ecdsa_free(hiskey); - ecdsa_free(key); - closesocket(sock); - - if(!success) { - fprintf(stderr, "Connection closed by peer, invitation cancelled.\n"); - return 1; - } - - return 0; - -invalid: - fprintf(stderr, "Invalid invitation URL.\n"); - return 1; -} diff --git a/src/invitation.h b/src/invitation.h deleted file mode 100644 index 6517fe8..0000000 --- a/src/invitation.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef TINC_INVITATION_H -#define TINC_INVITATION_H - -/* - invitation.h -- header for invitation.c. - Copyright (C) 2013 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 - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -int cmd_invite(int argc, char *argv[]); -int cmd_join(int argc, char *argv[]); - -#endif diff --git a/src/ipv4.h b/src/ipv4.h index 1e34ccb..7979f7d 100644 --- a/src/ipv4.h +++ b/src/ipv4.h @@ -81,7 +81,7 @@ struct ip { uint8_t ip_p; uint16_t ip_sum; struct in_addr ip_src, ip_dst; -} __attribute__((__gcc_struct__, __packed__)); +} __attribute__((__packed__)); #endif #ifndef IP_OFFMASK @@ -143,7 +143,7 @@ struct icmp { #define icmp_radv icmp_dun.id_radv #define icmp_mask icmp_dun.id_mask #define icmp_data icmp_dun.id_data -} __attribute__((__gcc_struct__, __packed__)); +} __attribute__((__packed__)); #endif #endif diff --git a/src/ipv6.h b/src/ipv6.h index 4d5173f..1642278 100644 --- a/src/ipv6.h +++ b/src/ipv6.h @@ -4,7 +4,7 @@ /* ipv6.h -- missing IPv6 related definitions Copyright (C) 2005 Ivo Timmermans - 2006-2016 Guus Sliepen + 2006-2012 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 @@ -29,11 +29,34 @@ #define IPPROTO_ICMPV6 58 #endif +#ifndef HAVE_STRUCT_IN6_ADDR +struct in6_addr { + union { + uint8_t u6_addr8[16]; + uint16_t u6_addr16[8]; + uint32_t u6_addr32[4]; + } in6_u; +} __attribute__((__packed__)); +#define s6_addr in6_u.u6_addr8 +#define s6_addr16 in6_u.u6_addr16 +#define s6_addr32 in6_u.u6_addr32 +#endif + +#ifndef HAVE_STRUCT_SOCKADDR_IN6 +struct sockaddr_in6 { + uint16_t sin6_family; + uint16_t sin6_port; + uint32_t sin6_flowinfo; + struct in6_addr sin6_addr; + uint32_t sin6_scope_id; +} __attribute__((__packed__)); +#endif + #ifndef IN6_IS_ADDR_V4MAPPED #define IN6_IS_ADDR_V4MAPPED(a) \ - ((((__const uint32_t *) (a))[0] == 0) \ - && (((__const uint32_t *) (a))[1] == 0) \ - && (((__const uint32_t *) (a))[2] == htonl (0xffff))) + ((((const uint32_t *) (a))[0] == 0) \ + && (((const uint32_t *) (a))[1] == 0) \ + && (((const uint32_t *) (a))[2] == htonl (0xffff))) #endif #ifndef HAVE_STRUCT_IP6_HDR @@ -49,7 +72,7 @@ struct ip6_hdr { } ip6_ctlun; struct in6_addr ip6_src; struct in6_addr ip6_dst; -} __attribute__((__gcc_struct__, __packed__)); +} __attribute__((__packed__)); #define ip6_vfc ip6_ctlun.ip6_un2_vfc #define ip6_flow ip6_ctlun.ip6_un1.ip6_un1_flow #define ip6_plen ip6_ctlun.ip6_un1.ip6_un1_plen @@ -68,7 +91,7 @@ struct icmp6_hdr { uint16_t icmp6_un_data16[2]; uint8_t icmp6_un_data8[4]; } icmp6_dataun; -} __attribute__((__gcc_struct__, __packed__)); +} __attribute__((__packed__)); #define ICMP6_DST_UNREACH_NOROUTE 0 #define ICMP6_DST_UNREACH 1 #define ICMP6_PACKET_TOO_BIG 2 @@ -88,7 +111,7 @@ struct icmp6_hdr { struct nd_neighbor_solicit { struct icmp6_hdr nd_ns_hdr; struct in6_addr nd_ns_target; -} __attribute__((__gcc_struct__, __packed__)); +} __attribute__((__packed__)); #define ND_OPT_SOURCE_LINKADDR 1 #define ND_OPT_TARGET_LINKADDR 2 #define nd_ns_type nd_ns_hdr.icmp6_type @@ -101,7 +124,7 @@ struct nd_neighbor_solicit { struct nd_opt_hdr { uint8_t nd_opt_type; uint8_t nd_opt_len; -} __attribute__((__gcc_struct__, __packed__)); +} __attribute__((__packed__)); #endif #endif diff --git a/src/linux/device.c b/src/linux/device.c index 94e223f..38debe8 100644 --- a/src/linux/device.c +++ b/src/linux/device.c @@ -20,20 +20,23 @@ #include "../system.h" +#ifdef HAVE_LINUX_IF_TUN_H #include #define DEFAULT_DEVICE "/dev/net/tun" +#else +#define DEFAULT_DEVICE "/dev/tap0" +#endif #include "../conf.h" #include "../device.h" #include "../logger.h" -#include "../names.h" #include "../net.h" #include "../route.h" #include "../utils.h" #include "../xalloc.h" -#include "../device.h" typedef enum device_type_t { + DEVICE_TYPE_ETHERTAP, DEVICE_TYPE_TUN, DEVICE_TYPE_TAP, } device_type_t; @@ -46,20 +49,30 @@ static char *type = NULL; static char ifrname[IFNAMSIZ]; static const char *device_info; +static uint64_t device_total_in = 0; +static uint64_t device_total_out = 0; + static bool setup_device(void) { + struct ifreq ifr; + bool t1q = false; + if(!get_config_string(lookup_config(config_tree, "Device"), &device)) { device = xstrdup(DEFAULT_DEVICE); } if(!get_config_string(lookup_config(config_tree, "Interface"), &iface)) - if(netname) { +#ifdef HAVE_LINUX_IF_TUN_H + if(netname != NULL) { iface = xstrdup(netname); } +#else + iface = xstrdup(strrchr(device, '/') ? strrchr(device, '/') + 1 : device); +#endif device_fd = open(device, O_RDWR | O_NONBLOCK); if(device_fd < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not open %s: %s", device, strerror(errno)); + logger(LOG_ERR, "Could not open %s: %s", device, strerror(errno)); return false; } @@ -67,12 +80,15 @@ static bool setup_device(void) { fcntl(device_fd, F_SETFD, FD_CLOEXEC); #endif - struct ifreq ifr = {0}; +#ifdef HAVE_LINUX_IF_TUN_H + /* Ok now check if this is an old ethertap or a new tun/tap thingie */ + + memset(&ifr, 0, sizeof(ifr)); get_config_string(lookup_config(config_tree, "DeviceType"), &type); if(type && strcasecmp(type, "tun") && strcasecmp(type, "tap")) { - logger(DEBUG_ALWAYS, LOG_ERR, "Unknown device type %s!", type); + logger(LOG_ERR, "Unknown device type %s!", type); return false; } @@ -91,10 +107,8 @@ static bool setup_device(void) { } #ifdef IFF_ONE_QUEUE + /* Set IFF_ONE_QUEUE flag... */ - - bool t1q = false; - if(get_config_bool(lookup_config(config_tree, "IffOneQueue"), &t1q) && t1q) { ifr.ifr_flags |= IFF_ONE_QUEUE; } @@ -111,93 +125,105 @@ static bool setup_device(void) { ifrname[IFNAMSIZ - 1] = 0; free(iface); iface = xstrdup(ifrname); - } else { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not create a tun/tap interface from %s: %s", device, strerror(errno)); + } else if(errno == EPERM || errno == EBUSY) { + logger(LOG_ERR, "Error while trying to configure %s: %s", device, strerror(errno)); return false; - } - - logger(DEBUG_ALWAYS, LOG_INFO, "%s is a %s", device, device_info); - - if(ifr.ifr_flags & IFF_TAP) { - struct ifreq ifr_mac = {0}; - - if(!ioctl(device_fd, SIOCGIFHWADDR, &ifr_mac)) { - memcpy(mymac.x, ifr_mac.ifr_hwaddr.sa_data, ETH_ALEN); - } else { - logger(DEBUG_ALWAYS, LOG_WARNING, "Could not get MAC address of %s: %s", device, strerror(errno)); + } else if(!ioctl(device_fd, (('T' << 8) | 202), &ifr)) { + logger(LOG_WARNING, "Old ioctl() request was needed for %s", device); + strncpy(ifrname, ifr.ifr_name, IFNAMSIZ); + ifrname[IFNAMSIZ - 1] = 0; + free(iface); + iface = xstrdup(ifrname); + } else +#endif + { + if(routing_mode == RMODE_ROUTER) { + overwrite_mac = true; } + + device_info = "Linux ethertap device"; + device_type = DEVICE_TYPE_ETHERTAP; + free(iface); + iface = xstrdup(strrchr(device, '/') ? strrchr(device, '/') + 1 : device); } + if(overwrite_mac && !ioctl(device_fd, SIOCGIFHWADDR, &ifr)) { + memcpy(mymac.x, ifr.ifr_hwaddr.sa_data, ETH_ALEN); + } + + logger(LOG_INFO, "%s is a %s", device, device_info); + return true; } static void close_device(void) { close(device_fd); - device_fd = -1; free(type); - type = NULL; free(device); - device = NULL; free(iface); - iface = NULL; - device_info = NULL; } static bool read_packet(vpn_packet_t *packet) { - int inlen; + int lenin; switch(device_type) { case DEVICE_TYPE_TUN: - inlen = read(device_fd, DATA(packet) + 10, MTU - 10); + lenin = read(device_fd, packet->data + 10, MTU - 10); - if(inlen <= 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", + if(lenin <= 0) { + logger(LOG_ERR, "Error while reading from %s %s: %s", device_info, device, strerror(errno)); - - if(errno == EBADFD) { /* File descriptor in bad state */ - event_exit(); - } - return false; } - memset(DATA(packet), 0, 12); - packet->len = inlen + 10; + memset(packet->data, 0, 12); + packet->len = lenin + 10; break; case DEVICE_TYPE_TAP: - inlen = read(device_fd, DATA(packet), MTU); + lenin = read(device_fd, packet->data, MTU); - if(inlen <= 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", + if(lenin <= 0) { + logger(LOG_ERR, "Error while reading from %s %s: %s", device_info, device, strerror(errno)); return false; } - packet->len = inlen; + packet->len = lenin; break; - default: - abort(); + case DEVICE_TYPE_ETHERTAP: + lenin = read(device_fd, packet->data - 2, MTU + 2); + + if(lenin <= 0) { + logger(LOG_ERR, "Error while reading from %s %s: %s", + device_info, device, strerror(errno)); + return false; + } + + packet->len = lenin - 2; + break; } - logger(DEBUG_TRAFFIC, LOG_DEBUG, "Read packet of %d bytes from %s", packet->len, - device_info); + device_total_in += packet->len; + + ifdebug(TRAFFIC) logger(LOG_DEBUG, "Read packet of %d bytes from %s", packet->len, + device_info); return true; } static bool write_packet(vpn_packet_t *packet) { - logger(DEBUG_TRAFFIC, LOG_DEBUG, "Writing packet of %d bytes to %s", - packet->len, device_info); + ifdebug(TRAFFIC) logger(LOG_DEBUG, "Writing packet of %d bytes to %s", + packet->len, device_info); switch(device_type) { case DEVICE_TYPE_TUN: - DATA(packet)[10] = DATA(packet)[11] = 0; + packet->data[10] = packet->data[11] = 0; - if(write(device_fd, DATA(packet) + 10, packet->len - 10) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Can't write to %s %s: %s", device_info, device, + if(write(device_fd, packet->data + 10, packet->len - 10) < 0) { + logger(LOG_ERR, "Can't write to %s %s: %s", device_info, device, strerror(errno)); return false; } @@ -205,24 +231,41 @@ static bool write_packet(vpn_packet_t *packet) { break; case DEVICE_TYPE_TAP: - if(write(device_fd, DATA(packet), packet->len) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Can't write to %s %s: %s", device_info, device, + if(write(device_fd, packet->data, packet->len) < 0) { + logger(LOG_ERR, "Can't write to %s %s: %s", device_info, device, strerror(errno)); return false; } break; - default: - abort(); + case DEVICE_TYPE_ETHERTAP: + memcpy(packet->data - 2, &packet->len, 2); + + if(write(device_fd, packet->data - 2, packet->len + 2) < 0) { + logger(LOG_ERR, "Can't write to %s %s: %s", device_info, device, + strerror(errno)); + return false; + } + + break; } + device_total_out += packet->len; + return true; } +static void dump_device_stats(void) { + logger(LOG_DEBUG, "Statistics for %s %s:", device_info, device); + logger(LOG_DEBUG, " total bytes in: %10"PRIu64, device_total_in); + logger(LOG_DEBUG, " total bytes out: %10"PRIu64, device_total_out); +} + const devops_t os_devops = { .setup = setup_device, .close = close_device, .read = read_packet, .write = write_packet, + .dump_stats = dump_device_stats, }; diff --git a/src/list.c b/src/list.c index 27494c8..a807c6d 100644 --- a/src/list.c +++ b/src/list.c @@ -1,7 +1,7 @@ /* list.c -- functions to deal with double linked lists Copyright (C) 2000-2005 Ivo Timmermans - 2000-2013 Guus Sliepen + 2000-2006 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 @@ -26,7 +26,9 @@ /* (De)constructors */ list_t *list_alloc(list_action_t delete) { - list_t *list = xzalloc(sizeof(list_t)); + list_t *list; + + list = xmalloc_and_zero(sizeof(list_t)); list->delete = delete; return list; @@ -37,7 +39,7 @@ void list_free(list_t *list) { } list_node_t *list_alloc_node(void) { - return xzalloc(sizeof(list_node_t)); + return xmalloc_and_zero(sizeof(list_node_t)); } void list_free_node(list_t *list, list_node_t *node) { @@ -51,7 +53,9 @@ void list_free_node(list_t *list, list_node_t *node) { /* Insertion and deletion */ list_node_t *list_insert_head(list_t *list, void *data) { - list_node_t *node = list_alloc_node(); + list_node_t *node; + + node = list_alloc_node(); node->data = data; node->prev = NULL; @@ -70,52 +74,14 @@ list_node_t *list_insert_head(list_t *list, void *data) { } list_node_t *list_insert_tail(list_t *list, void *data) { - list_node_t *node = list_alloc_node(); - - node->data = data; - node->next = NULL; - node->prev = list->tail; - list->tail = node; - - if(node->prev) { - node->prev->next = node; - } else { - list->head = node; - } - - list->count++; - - return node; -} - -list_node_t *list_insert_after(list_t *list, list_node_t *after, void *data) { - list_node_t *node = list_alloc_node(); - - node->data = data; - node->next = after->next; - node->prev = after; - after->next = node; - - if(node->next) { - node->next->prev = node; - } else { - list->tail = node; - } - - list->count++; - - return node; -} - -list_node_t *list_insert_before(list_t *list, list_node_t *before, void *data) { list_node_t *node; node = list_alloc_node(); node->data = data; - node->next = before; - node->prev = before->prev; - before->prev = node; + node->next = NULL; + node->prev = list->tail; + list->tail = node; if(node->prev) { node->prev->next = node; @@ -157,13 +123,6 @@ void list_delete_tail(list_t *list) { list_delete_node(list, list->tail); } -void list_delete(list_t *list, const void *data) { - for(list_node_t *node = list->head, *next; next = node ? node->next : NULL, node; node = next) - if(node->data == data) { - list_delete_node(list, node); - } -} - /* Head/tail lookup */ void *list_get_head(list_t *list) { @@ -185,7 +144,10 @@ void *list_get_tail(list_t *list) { /* Fast list deletion */ void list_delete_list(list_t *list) { - for(list_node_t *node = list->head, *next; next = node ? node->next : NULL, node; node = next) { + list_node_t *node, *next; + + for(node = list->head; node; node = next) { + next = node->next; list_free_node(list, node); } @@ -195,14 +157,22 @@ void list_delete_list(list_t *list) { /* Traversing */ void list_foreach_node(list_t *list, list_action_node_t action) { - for(list_node_t *node = list->head, *next; next = node ? node->next : NULL, node; node = next) { + list_node_t *node, *next; + + for(node = list->head; node; node = next) { + next = node->next; action(node); } } void list_foreach(list_t *list, list_action_t action) { - for(list_node_t *node = list->head, *next; next = node ? node->next : NULL, node; node = next) + list_node_t *node, *next; + + for(node = list->head; node; node = next) { + next = node->next; + if(node->data) { action(node->data); } + } } diff --git a/src/list.h b/src/list.h index 3806495..b2a9b3d 100644 --- a/src/list.h +++ b/src/list.h @@ -4,7 +4,7 @@ /* list.h -- header file for list.c Copyright (C) 2000-2005 Ivo Timmermans - 2000-2012 Guus Sliepen + 2000-2006 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 @@ -30,8 +30,8 @@ typedef struct list_node_t { void *data; } list_node_t; -typedef void (*list_action_t)(const void *data); -typedef void (*list_action_node_t)(const list_node_t *node); +typedef void (*list_action_t)(const void *); +typedef void (*list_action_node_t)(const list_node_t *); typedef struct list_t { list_node_t *head; @@ -45,7 +45,7 @@ typedef struct list_t { /* (De)constructors */ -extern list_t *list_alloc(list_action_t delete) __attribute__((__malloc__)); +extern list_t *list_alloc(list_action_t) __attribute__((__malloc__)); extern void list_free(list_t *list); extern list_node_t *list_alloc_node(void); extern void list_free_node(list_t *list, list_node_t *node); @@ -54,10 +54,6 @@ extern void list_free_node(list_t *list, list_node_t *node); extern list_node_t *list_insert_head(list_t *list, void *data); extern list_node_t *list_insert_tail(list_t *list, void *data); -extern list_node_t *list_insert_after(list_t *list, list_node_t *node, void *data); -extern list_node_t *list_insert_before(list_t *list, list_node_t *node, void *data); - -extern void list_delete(list_t *list, const void *data); extern void list_unlink_node(list_t *list, list_node_t *node); extern void list_delete_node(list_t *list, list_node_t *node); @@ -79,12 +75,4 @@ extern void list_delete_list(list_t *list); extern void list_foreach(list_t *list, list_action_t action); extern void list_foreach_node(list_t *list, list_action_node_t action); -/* - Iterates over a list. - - CAUTION: while this construct supports deleting the current item, - it does *not* support deleting *other* nodes while iterating on the list. - */ -#define list_each(type, item, list) (type *item = (type *)1; item; item = NULL) for(list_node_t *node = (list)->head, *next; item = node ? node->data : NULL, next = node ? node->next : NULL, node; node = next) - #endif diff --git a/src/logger.c b/src/logger.c index 062f759..8d4aea1 100644 --- a/src/logger.c +++ b/src/logger.c @@ -1,6 +1,6 @@ /* logger.c -- logging code - Copyright (C) 2004-2017 Guus Sliepen + Copyright (C) 2004-2016 Guus Sliepen 2004-2005 Ivo Timmermans This program is free software; you can redistribute it and/or modify @@ -21,146 +21,17 @@ #include "system.h" #include "conf.h" -#include "meta.h" -#include "names.h" #include "logger.h" -#include "connection.h" -#include "control_common.h" -#include "process.h" -#include "sptps.h" -int debug_level = DEBUG_NOTHING; +debug_t debug_level = DEBUG_NOTHING; static logmode_t logmode = LOGMODE_STDERR; static pid_t logpid; +extern char *logfilename; static FILE *logfile = NULL; #ifdef HAVE_MINGW static HANDLE loghandle = NULL; #endif static const char *logident = NULL; -bool logcontrol = false; -int umbilical = 0; - -static void real_logger(int level, int priority, const char *message) { - char timestr[32] = ""; - static bool suppress = false; - - // Bail out early if there is nothing to do. - if(suppress) { - return; - } - - if(!logcontrol && (level > debug_level || logmode == LOGMODE_NULL)) { - return; - } - - if(level <= debug_level) { - switch(logmode) { - case LOGMODE_STDERR: - fprintf(stderr, "%s\n", message); - fflush(stderr); - break; - - case LOGMODE_FILE: - if(!now.tv_sec) { - gettimeofday(&now, NULL); - } - - time_t now_sec = now.tv_sec; - strftime(timestr, sizeof(timestr), "%Y-%m-%d %H:%M:%S", localtime(&now_sec)); - fprintf(logfile, "%s %s[%ld]: %s\n", timestr, logident, (long)logpid, message); - fflush(logfile); - break; - - case LOGMODE_SYSLOG: -#ifdef HAVE_MINGW - { - const char *messages[] = {message}; - ReportEvent(loghandle, priority, 0, 0, NULL, 1, 0, messages, NULL); - } - -#else -#ifdef HAVE_SYSLOG_H - syslog(priority, "%s", message); -#endif -#endif - break; - - case LOGMODE_NULL: - break; - } - - if(umbilical && do_detach) { - write(umbilical, message, strlen(message)); - write(umbilical, "\n", 1); - } - } - - if(logcontrol) { - suppress = true; - logcontrol = false; - - for list_each(connection_t, c, connection_list) { - if(!c->status.log) { - continue; - } - - logcontrol = true; - - if(level > (c->outcompression >= 0 ? c->outcompression : debug_level)) { - continue; - } - - int len = strlen(message); - - if(send_request(c, "%d %d %d", CONTROL, REQ_LOG, len)) { - send_meta(c, message, len); - } - } - - suppress = false; - } -} - -void logger(int level, int priority, const char *format, ...) { - va_list ap; - char message[1024] = ""; - - va_start(ap, format); - int len = vsnprintf(message, sizeof(message), format, ap); - message[sizeof(message) - 1] = 0; - va_end(ap); - - if(len > 0 && (size_t)len < sizeof(message) - 1 && message[len - 1] == '\n') { - message[len - 1] = 0; - } - - real_logger(level, priority, message); -} - -static void sptps_logger(sptps_t *s, int s_errno, const char *format, va_list ap) { - (void)s_errno; - char message[1024]; - size_t msglen = sizeof(message); - - int len = vsnprintf(message, msglen, format, ap); - message[sizeof(message) - 1] = 0; - - if(len > 0 && (size_t)len < sizeof(message) - 1) { - if(message[len - 1] == '\n') { - message[--len] = 0; - } - - // WARNING: s->handle can point to a connection_t or a node_t, - // but both types have the name and hostname fields at the same offsets. - connection_t *c = s->handle; - - if(c) { - snprintf(message + len, sizeof(message) - len, " from %s (%s)", c->name, c->hostname); - } - } - - real_logger(DEBUG_ALWAYS, LOG_ERR, message); -} void openlogger(const char *ident, logmode_t mode) { logident = ident; @@ -187,7 +58,7 @@ void openlogger(const char *ident, logmode_t mode) { loghandle = RegisterEventSource(NULL, logident); if(!loghandle) { - fprintf(stderr, "Could not open log handle!\n"); + fprintf(stderr, "Could not open log handle!"); logmode = LOGMODE_NULL; } @@ -202,12 +73,6 @@ void openlogger(const char *ident, logmode_t mode) { case LOGMODE_NULL: break; } - - if(logmode != LOGMODE_NULL) { - sptps_log = sptps_logger; - } else { - sptps_log = sptps_log_quiet; - } } void reopenlogger() { @@ -219,7 +84,7 @@ void reopenlogger() { FILE *newfile = fopen(logfilename, "a"); if(!newfile) { - logger(DEBUG_ALWAYS, LOG_ERR, "Unable to reopen log file %s: %s", logfilename, strerror(errno)); + logger(LOG_ERR, "Unable to reopen log file %s: %s", logfilename, strerror(errno)); return; } @@ -227,6 +92,60 @@ void reopenlogger() { logfile = newfile; } +void logger(int priority, const char *format, ...) { + va_list ap; + char timestr[32] = ""; + time_t now; + + va_start(ap, format); + + switch(logmode) { + case LOGMODE_STDERR: + vfprintf(stderr, format, ap); + fprintf(stderr, "\n"); + fflush(stderr); + break; + + case LOGMODE_FILE: + now = time(NULL); + strftime(timestr, sizeof(timestr), "%Y-%m-%d %H:%M:%S", localtime(&now)); + fprintf(logfile, "%s %s[%ld]: ", timestr, logident, (long)logpid); + vfprintf(logfile, format, ap); + fprintf(logfile, "\n"); + fflush(logfile); + break; + + case LOGMODE_SYSLOG: +#ifdef HAVE_MINGW + { + char message[4096]; + const char *messages[] = {message}; + vsnprintf(message, sizeof(message), format, ap); + message[sizeof(message) - 1] = 0; + ReportEvent(loghandle, priority, 0, 0, NULL, 1, 0, messages, NULL); + } + +#else +#ifdef HAVE_SYSLOG_H +#ifdef HAVE_VSYSLOG + vsyslog(priority, format, ap); +#else + { + char message[4096]; + vsnprintf(message, sizeof(message), format, ap); + syslog(priority, "%s", message); + } +#endif + break; +#endif +#endif + + case LOGMODE_NULL: + break; + } + + va_end(ap); +} void closelogger(void) { switch(logmode) { diff --git a/src/logger.h b/src/logger.h index 611fe38..5a17ffb 100644 --- a/src/logger.h +++ b/src/logger.h @@ -3,8 +3,7 @@ /* logger.h -- header file for logger.c - Copyright (C) 1998-2005 Ivo Timmermans - 2000-2017 Guus Sliepen + Copyright (C) 2003-2016 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 @@ -22,16 +21,16 @@ */ typedef enum debug_t { - DEBUG_NOTHING = 0, /* Quiet mode, only show starting/stopping of the daemon */ + DEBUG_NOTHING = 0, /* Quiet mode, only show starting/stopping of the daemon */ DEBUG_ALWAYS = 0, - DEBUG_CONNECTIONS = 1, /* Show (dis)connects of other tinc daemons via TCP */ - DEBUG_ERROR = 2, /* Show error messages received from other hosts */ - DEBUG_STATUS = 2, /* Show status messages received from other hosts */ - DEBUG_PROTOCOL = 3, /* Show the requests that are sent/received */ - DEBUG_META = 4, /* Show contents of every request that is sent/received */ - DEBUG_TRAFFIC = 5, /* Show network traffic information */ - DEBUG_PACKET = 6, /* Show contents of each packet that is being sent/received */ - DEBUG_SCARY_THINGS = 10 /* You have been warned */ + DEBUG_CONNECTIONS = 1, /* Show (dis)connects of other tinc daemons via TCP */ + DEBUG_ERROR = 2, /* Show error messages received from other hosts */ + DEBUG_STATUS = 2, /* Show status messages received from other hosts */ + DEBUG_PROTOCOL = 3, /* Show the requests that are sent/received */ + DEBUG_META = 4, /* Show contents of every request that is sent/received */ + DEBUG_TRAFFIC = 5, /* Show network traffic information */ + DEBUG_PACKET = 6, /* Show contents of each packet that is being sent/received */ + DEBUG_SCARY_THINGS = 10, /* You have been warned */ } debug_t; typedef enum logmode_t { @@ -65,14 +64,12 @@ enum { #endif #endif -#include - -extern int debug_level; -extern bool logcontrol; -extern int umbilical; +extern debug_t debug_level; extern void openlogger(const char *ident, logmode_t mode); extern void reopenlogger(void); -extern void logger(int level, int priority, const char *format, ...) __attribute__((__format__(printf, 3, 4))); +extern void logger(int priority, const char *format, ...) __attribute__((__format__(printf, 2, 3))); extern void closelogger(void); +#define ifdebug(l) if(debug_level >= DEBUG_##l) + #endif diff --git a/src/meta.c b/src/meta.c index 0089ac8..ee55ecd 100644 --- a/src/meta.c +++ b/src/meta.c @@ -1,6 +1,6 @@ /* meta.c -- handle the meta communication - Copyright (C) 2000-2014 Guus Sliepen , + Copyright (C) 2000-2017 Guus Sliepen , 2000-2005 Ivo Timmermans 2006 Scott Lamb @@ -21,147 +21,125 @@ #include "system.h" -#include "cipher.h" +#include +#include + +#include "avl_tree.h" #include "connection.h" #include "logger.h" #include "meta.h" #include "net.h" #include "protocol.h" +#include "proxy.h" #include "utils.h" #include "xalloc.h" -#ifndef MIN -#define MIN(x, y) (((x)<(y))?(x):(y)) -#endif +bool send_meta(connection_t *c, const char *buffer, int length) { + int outlen; + int result; -bool send_meta_sptps(void *handle, uint8_t type, const void *buffer, size_t length) { - (void)type; - connection_t *c = handle; + ifdebug(META) logger(LOG_DEBUG, "Sending %d bytes of metadata to %s (%s)", length, + c->name, c->hostname); - if(!c) { - logger(DEBUG_ALWAYS, LOG_ERR, "send_meta_sptps() called with NULL pointer!"); - abort(); + if(!c->outbuflen) { + c->last_flushed_time = now; } - buffer_add(&c->outbuf, buffer, length); - io_set(&c->io, IO_READ | IO_WRITE); - - return true; -} - -bool send_meta(connection_t *c, const char *buffer, size_t length) { - if(!c) { - logger(DEBUG_ALWAYS, LOG_ERR, "send_meta() called with NULL pointer!"); - abort(); + /* Find room in connection's buffer */ + if(length + c->outbuflen > c->outbufsize) { + c->outbufsize = length + c->outbuflen; + c->outbuf = xrealloc(c->outbuf, c->outbufsize); } - logger(DEBUG_META, LOG_DEBUG, "Sending %lu bytes of metadata to %s (%s)", (unsigned long)length, - c->name, c->hostname); - - if(c->protocol_minor >= 2) { - return sptps_send_record(&c->sptps, 0, buffer, length); + if(length + c->outbuflen + c->outbufstart > c->outbufsize) { + memmove(c->outbuf, c->outbuf + c->outbufstart, c->outbuflen); + c->outbufstart = 0; } /* Add our data to buffer */ if(c->status.encryptout) { -#ifdef DISABLE_LEGACY - return false; -#else - - if(length > c->outbudget) { - logger(DEBUG_META, LOG_ERR, "Byte limit exceeded for encryption to %s (%s)", c->name, c->hostname); + /* Check encryption limits */ + if((uint64_t)length > c->outbudget) { + ifdebug(META) logger(LOG_ERR, "Byte limit exceeded for encryption to %s (%s)", c->name, c->hostname); return false; } else { c->outbudget -= length; } - size_t outlen = length; + result = EVP_EncryptUpdate(c->outctx, (unsigned char *)c->outbuf + c->outbufstart + c->outbuflen, + &outlen, (unsigned char *)buffer, length); - if(!cipher_encrypt(c->outcipher, buffer, length, buffer_prepare(&c->outbuf, length), &outlen, false) || outlen != length) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error while encrypting metadata to %s (%s)", - c->name, c->hostname); + if(!result || outlen < length) { + logger(LOG_ERR, "Error while encrypting metadata to %s (%s): %s", + c->name, c->hostname, ERR_error_string(ERR_get_error(), NULL)); return false; + } else if(outlen > length) { + logger(LOG_EMERG, "Encrypted data too long! Heap corrupted!"); + abort(); } -#endif + c->outbuflen += outlen; } else { - buffer_add(&c->outbuf, buffer, length); + memcpy(c->outbuf + c->outbufstart + c->outbuflen, buffer, length); + c->outbuflen += length; } - io_set(&c->io, IO_READ | IO_WRITE); - return true; } -void send_meta_raw(connection_t *c, const char *buffer, size_t length) { - if(!c) { - logger(DEBUG_ALWAYS, LOG_ERR, "send_meta() called with NULL pointer!"); - abort(); - } +bool flush_meta(connection_t *c) { + int result; - logger(DEBUG_META, LOG_DEBUG, "Sending %lu bytes of raw metadata to %s (%s)", (unsigned long)length, - c->name, c->hostname); + ifdebug(META) logger(LOG_DEBUG, "Flushing %d bytes to %s (%s)", + c->outbuflen, c->name, c->hostname); - buffer_add(&c->outbuf, buffer, length); + while(c->outbuflen) { + result = send(c->socket, c->outbuf + c->outbufstart, c->outbuflen, 0); - io_set(&c->io, IO_READ | IO_WRITE); -} + if(result <= 0) { + if(!errno || errno == EPIPE) { + ifdebug(CONNECTIONS) logger(LOG_NOTICE, "Connection closed by %s (%s)", + c->name, c->hostname); + } else if(errno == EINTR) { + continue; + } else if(sockwouldblock(sockerrno)) { + ifdebug(META) logger(LOG_DEBUG, "Flushing %d bytes to %s (%s) would block", + c->outbuflen, c->name, c->hostname); + return true; + } else { + logger(LOG_ERR, "Flushing meta data to %s (%s) failed: %s", c->name, + c->hostname, sockstrerror(sockerrno)); + } -void broadcast_meta(connection_t *from, const char *buffer, size_t length) { - for list_each(connection_t, c, connection_list) - if(c != from && c->edge) { - send_meta(c, buffer, length); - } -} - -bool receive_meta_sptps(void *handle, uint8_t type, const void *vdata, uint16_t length) { - const char *data = vdata; - connection_t *c = handle; - - if(!c) { - logger(DEBUG_ALWAYS, LOG_ERR, "receive_meta_sptps() called with NULL pointer!"); - abort(); - } - - if(type == SPTPS_HANDSHAKE) { - if(c->allow_request == ACK) { - return send_ack(c); - } else { - return true; - } - } - - if(!data) { - return true; - } - - /* Are we receiving a TCPpacket? */ - - if(c->tcplen) { - if(length != c->tcplen) { return false; } - receive_tcppacket(c, data, length); - c->tcplen = 0; - return true; + c->outbufstart += result; + c->outbuflen -= result; } - /* Change newline to null byte, just like non-SPTPS requests */ + c->outbufstart = 0; /* avoid unnecessary memmoves */ + return true; +} - if(data[length - 1] == '\n') { - ((char *)data)[length - 1] = 0; +void broadcast_meta(connection_t *from, const char *buffer, int length) { + avl_node_t *node; + connection_t *c; + + for(node = connection_tree->head; node; node = node->next) { + c = node->data; + + if(c != from && c->status.active) { + send_meta(c, buffer, length); + } } - - /* Otherwise we are waiting for a request */ - - return receive_request(c, data); } bool receive_meta(connection_t *c) { - ssize_t inlen; + int oldlen, i, result; + int lenin, lenout, reqlen; + bool decrypted = false; char inbuf[MAXBUFSIZE]; - char *bufp = inbuf, *endp; /* Strategy: - Read as much as possible from the TCP socket in one go. @@ -172,174 +150,109 @@ bool receive_meta(connection_t *c) { - If not, keep stuff in buffer and exit. */ - buffer_compact(&c->inbuf, MAXBUFSIZE); + lenin = recv(c->socket, c->buffer + c->buflen, MAXBUFSIZE - c->buflen, 0); - if(sizeof(inbuf) <= c->inbuf.len) { - logger(DEBUG_ALWAYS, LOG_ERR, "Input buffer full for %s (%s)", c->name, c->hostname); - return false; - } - - inlen = recv(c->socket, inbuf, sizeof(inbuf) - c->inbuf.len, 0); - - if(inlen <= 0) { - if(!inlen || !sockerrno) { - logger(DEBUG_CONNECTIONS, LOG_NOTICE, "Connection closed by %s (%s)", - c->name, c->hostname); + if(lenin <= 0) { + if(!lenin || !errno) { + ifdebug(CONNECTIONS) logger(LOG_NOTICE, "Connection closed by %s (%s)", + c->name, c->hostname); } else if(sockwouldblock(sockerrno)) { return true; } else - logger(DEBUG_ALWAYS, LOG_ERR, "Metadata socket read error for %s (%s): %s", + logger(LOG_ERR, "Metadata socket read error for %s (%s): %s", c->name, c->hostname, sockstrerror(sockerrno)); return false; } - do { - /* Are we receiving a SPTPS packet? */ + oldlen = c->buflen; + c->buflen += lenin; - if(c->sptpslen) { - ssize_t len = MIN(inlen, c->sptpslen - c->inbuf.len); - buffer_add(&c->inbuf, bufp, len); + while(lenin > 0) { + reqlen = 0; - char *sptpspacket = buffer_read(&c->inbuf, c->sptpslen); + /* Is it proxy metadata? */ - if(!sptpspacket) { - return true; - } + if(c->allow_request == PROXY) { + reqlen = receive_proxy_meta(c); - if(!receive_tcppacket_sptps(c, sptpspacket, c->sptpslen)) { + if(reqlen < 0) { return false; } - c->sptpslen = 0; - - bufp += len; - inlen -= len; - continue; + goto consume; } - if(c->protocol_minor >= 2) { - size_t len = sptps_receive_data(&c->sptps, bufp, inlen); + /* Decrypt */ - if(!len) { - return false; - } - - bufp += len; - inlen -= len; - continue; - } - - if(!c->status.decryptin) { - endp = memchr(bufp, '\n', inlen); - - if(endp) { - endp++; - } else { - endp = bufp + inlen; - } - - buffer_add(&c->inbuf, bufp, endp - bufp); - - inlen -= endp - bufp; - bufp = endp; - } else { -#ifdef DISABLE_LEGACY - return false; -#else - - if((size_t)inlen > c->inbudget) { - logger(DEBUG_META, LOG_ERR, "Byte limit exceeded for decryption from %s (%s)", c->name, c->hostname); + if(c->status.decryptin && !decrypted) { + /* Check decryption limits */ + if((uint64_t)lenin > c->inbudget) { + ifdebug(META) logger(LOG_ERR, "Byte limit exceeded for decryption from %s (%s)", c->name, c->hostname); return false; } else { - c->inbudget -= inlen; + c->inbudget -= lenin; } - size_t outlen = inlen; + result = EVP_DecryptUpdate(c->inctx, (unsigned char *)inbuf, &lenout, (unsigned char *)c->buffer + oldlen, lenin); - if(!cipher_decrypt(c->incipher, bufp, inlen, buffer_prepare(&c->inbuf, inlen), &outlen, false) || (size_t)inlen != outlen) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error while decrypting metadata from %s (%s)", - c->name, c->hostname); + if(!result || lenout != lenin) { + logger(LOG_ERR, "Error while decrypting metadata from %s (%s): %s", + c->name, c->hostname, ERR_error_string(ERR_get_error(), NULL)); return false; } - inlen = 0; -#endif + memcpy(c->buffer + oldlen, inbuf, lenin); + decrypted = true; } - while(c->inbuf.len) { - /* Are we receiving a TCPpacket? */ + /* Are we receiving a TCPpacket? */ - if(c->tcplen) { - char *tcpbuffer = buffer_read(&c->inbuf, c->tcplen); - - if(!tcpbuffer) { - break; - } - - if(!c->node) { - if(c->outgoing && proxytype == PROXY_SOCKS4 && c->allow_request == ID) { - if(tcpbuffer[0] == 0 && tcpbuffer[1] == 0x5a) { - logger(DEBUG_CONNECTIONS, LOG_DEBUG, "Proxy request granted"); - } else { - logger(DEBUG_CONNECTIONS, LOG_ERR, "Proxy request rejected"); - return false; - } - } else if(c->outgoing && proxytype == PROXY_SOCKS5 && c->allow_request == ID) { - if(tcpbuffer[0] != 5) { - logger(DEBUG_CONNECTIONS, LOG_ERR, "Invalid response from proxy server"); - return false; - } - - if(tcpbuffer[1] == (char)0xff) { - logger(DEBUG_CONNECTIONS, LOG_ERR, "Proxy request rejected: unsuitable authentication method"); - return false; - } - - if(tcpbuffer[2] != 5) { - logger(DEBUG_CONNECTIONS, LOG_ERR, "Invalid response from proxy server"); - return false; - } - - if(tcpbuffer[3] == 0) { - logger(DEBUG_CONNECTIONS, LOG_DEBUG, "Proxy request granted"); - } else { - logger(DEBUG_CONNECTIONS, LOG_DEBUG, "Proxy request rejected"); - return false; - } - } else { - logger(DEBUG_CONNECTIONS, LOG_ERR, "c->tcplen set but c->node is NULL!"); - abort(); - } - } else { - if(c->allow_request == ALL) { - receive_tcppacket(c, tcpbuffer, c->tcplen); - } else { - logger(DEBUG_CONNECTIONS, LOG_ERR, "Got unauthorized TCP packet from %s (%s)", c->name, c->hostname); - return false; - } - } - - c->tcplen = 0; - } - - /* Otherwise we are waiting for a request */ - - char *request = buffer_readline(&c->inbuf); - - if(request) { - bool result = receive_request(c, request); - - if(!result) { + if(c->tcplen) { + if(c->tcplen <= c->buflen) { + if(c->allow_request != ALL) { + logger(LOG_ERR, "Got unauthorized TCP packet from %s (%s)", c->name, c->hostname); return false; } - continue; - } else { - break; + receive_tcppacket(c, c->buffer, c->tcplen); + reqlen = c->tcplen; + c->tcplen = 0; + } + } else { + /* Otherwise we are waiting for a request */ + + for(i = oldlen; i < c->buflen; i++) { + if(c->buffer[i] == '\n') { + c->buffer[i] = '\0'; /* replace end-of-line by end-of-string so we can use sscanf */ + c->reqlen = reqlen = i + 1; + break; + } + } + + if(reqlen && !receive_request(c)) { + return false; } } - } while(inlen); + +consume: + + if(reqlen) { + c->buflen -= reqlen; + lenin -= reqlen - oldlen; + memmove(c->buffer, c->buffer + reqlen, c->buflen); + oldlen = 0; + continue; + } else { + break; + } + } + + if(c->buflen >= MAXBUFSIZE) { + logger(LOG_ERR, "Metadata read buffer overflow for %s (%s)", + c->name, c->hostname); + return false; + } return true; } diff --git a/src/meta.h b/src/meta.h index dcf2419..36914f1 100644 --- a/src/meta.h +++ b/src/meta.h @@ -3,7 +3,7 @@ /* meta.h -- header for meta.c - Copyright (C) 2000-2014 Guus Sliepen , + Copyright (C) 2000-2006 Guus Sliepen , 2000-2005 Ivo Timmermans This program is free software; you can redistribute it and/or modify @@ -23,11 +23,9 @@ #include "connection.h" -extern bool send_meta(struct connection_t *c, const char *buffer, size_t length); -extern void send_meta_raw(struct connection_t *c, const char *buffer, size_t length); -extern bool send_meta_sptps(void *handle, uint8_t type, const void *data, size_t length); -extern bool receive_meta_sptps(void *handle, uint8_t type, const void *data, uint16_t length); -extern void broadcast_meta(struct connection_t *from, const char *buffer, size_t length); +extern bool send_meta(struct connection_t *c, const char *buffer, int length); +extern void broadcast_meta(struct connection_t *c, const char *buffer, int length); +extern bool flush_meta(struct connection_t *c); extern bool receive_meta(struct connection_t *c); #endif diff --git a/src/mingw/common.h b/src/mingw/common.h index ff052c9..41b9dc5 100644 --- a/src/mingw/common.h +++ b/src/mingw/common.h @@ -1,6 +1,3 @@ -#ifndef TINC_MINGW_COMMON_H -#define TINC_MINGW_COMMON_H - /* * TAP-Win32 -- A kernel driver to provide virtual tap device functionality * on Windows. Originally derived from the CIPE-Win32 @@ -76,5 +73,3 @@ //========================================================= #define TAP_COMPONENT_ID "tap0801" - -#endif diff --git a/src/mingw/device.c b/src/mingw/device.c index 183641b..321c515 100644 --- a/src/mingw/device.c +++ b/src/mingw/device.c @@ -1,7 +1,7 @@ /* device.c -- Interaction with Windows tap driver in a MinGW environment Copyright (C) 2002-2005 Ivo Timmermans, - 2002-2014 Guus Sliepen + 2002-2016 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 @@ -26,7 +26,6 @@ #include "../conf.h" #include "../device.h" #include "../logger.h" -#include "../names.h" #include "../net.h" #include "../route.h" #include "../utils.h" @@ -36,59 +35,67 @@ int device_fd = -1; static HANDLE device_handle = INVALID_HANDLE_VALUE; -static io_t device_read_io; -static OVERLAPPED device_read_overlapped; -static OVERLAPPED device_write_overlapped; -static vpn_packet_t device_read_packet; -static vpn_packet_t device_write_packet; char *device = NULL; char *iface = NULL; static const char *device_info = "Windows tap device"; -extern char *myport; +static uint64_t device_total_in = 0; +static uint64_t device_total_out = 0; -static void device_issue_read() { +extern char *myport; +OVERLAPPED r_overlapped; +OVERLAPPED w_overlapped; + +static DWORD WINAPI tapreader(void *bla) { int status; + DWORD len; + vpn_packet_t packet; + int errors = 0; + + logger(LOG_DEBUG, "Tap reader running"); + + /* Read from tap device and send to parent */ + + r_overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); for(;;) { - ResetEvent(device_read_overlapped.hEvent); + ResetEvent(r_overlapped.hEvent); - DWORD len; - status = ReadFile(device_handle, (void *)device_read_packet.data, MTU, &len, &device_read_overlapped); + status = ReadFile(device_handle, packet.data, MTU, &len, &r_overlapped); if(!status) { - if(GetLastError() != ERROR_IO_PENDING) - logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info, + if(GetLastError() == ERROR_IO_PENDING) { + WaitForSingleObject(r_overlapped.hEvent, INFINITE); + + if(!GetOverlappedResult(device_handle, &r_overlapped, &len, FALSE)) { + continue; + } + } else { + logger(LOG_ERR, "Error while reading from %s %s: %s", device_info, device, strerror(errno)); + errors++; - break; + if(errors >= 10) { + EnterCriticalSection(&mutex); + running = false; + LeaveCriticalSection(&mutex); + } + + usleep(1000000); + continue; + } } - device_read_packet.len = len; - device_read_packet.priority = 0; - route(myself, &device_read_packet); - } -} + errors = 0; + packet.len = len; + packet.priority = 0; -static void device_handle_read(void *data, int flags) { - DWORD len; - - if(!GetOverlappedResult(device_handle, &device_read_overlapped, &len, FALSE)) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error getting read result from %s %s: %s", device_info, - device, strerror(errno)); - - if(GetLastError() != ERROR_IO_INCOMPLETE) { - /* Must reset event or it will keep firing. */ - ResetEvent(device_read_overlapped.hEvent); - } - - return; + EnterCriticalSection(&mutex); + route(myself, &packet); + LeaveCriticalSection(&mutex); } - device_read_packet.len = len; - device_read_packet.priority = 0; - route(myself, &device_read_packet); - device_issue_read(); + return 0; } static bool setup_device(void) { @@ -100,22 +107,24 @@ static bool setup_device(void) { char adaptername[1024]; char tapname[1024]; DWORD len; + unsigned long status; bool found = false; int err; + HANDLE thread; get_config_string(lookup_config(config_tree, "Device"), &device); get_config_string(lookup_config(config_tree, "Interface"), &iface); if(device && iface) { - logger(DEBUG_ALWAYS, LOG_WARNING, "Warning: both Device and Interface specified, results may not be as expected"); + logger(LOG_WARNING, "Warning: both Device and Interface specified, results may not be as expected"); } /* Open registry and look for network adapters */ if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, NETWORK_CONNECTIONS_KEY, 0, KEY_READ, &key)) { - logger(DEBUG_ALWAYS, LOG_ERR, "Unable to read registry: %s", winerror(GetLastError())); + logger(LOG_ERR, "Unable to read registry: %s", winerror(GetLastError())); return false; } @@ -173,7 +182,7 @@ static bool setup_device(void) { RegCloseKey(key); if(!found) { - logger(DEBUG_ALWAYS, LOG_ERR, "No Windows tap device found!"); + logger(LOG_ERR, "No Windows tap device found!"); return false; } @@ -193,34 +202,14 @@ static bool setup_device(void) { } if(device_handle == INVALID_HANDLE_VALUE) { - logger(DEBUG_ALWAYS, LOG_ERR, "%s (%s) is not a usable Windows tap device: %s", device, iface, winerror(GetLastError())); + logger(LOG_ERR, "%s (%s) is not a usable Windows tap device: %s", device, iface, winerror(GetLastError())); return false; } - /* Get version information from tap device */ - - { - ULONG info[3] = {0}; - DWORD len; - - if(!DeviceIoControl(device_handle, TAP_IOCTL_GET_VERSION, &info, sizeof(info), &info, sizeof(info), &len, NULL)) { - logger(DEBUG_ALWAYS, LOG_WARNING, "Could not get version information from Windows tap device %s (%s): %s", device, iface, winerror(GetLastError())); - } else { - logger(DEBUG_ALWAYS, LOG_INFO, "TAP-Windows driver version: %lu.%lu%s", info[0], info[1], info[2] ? " (DEBUG)" : ""); - - /* Warn if using >=9.21. This is because starting from 9.21, TAP-Win32 seems to use a different, less efficient write path. */ - if(info[0] == 9 && info[1] >= 21) - logger(DEBUG_ALWAYS, LOG_WARNING, - "You are using the newer (>= 9.0.0.21, NDIS6) series of TAP-Win32 drivers. " - "Using these drivers with tinc is not recommended as it can result in poor performance. " - "You might want to revert back to 9.0.0.9 instead."); - } - } - /* Get MAC address from tap device */ if(!DeviceIoControl(device_handle, TAP_IOCTL_GET_MAC, mymac.x, sizeof(mymac.x), mymac.x, sizeof(mymac.x), &len, 0)) { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not get MAC address from Windows tap device %s (%s): %s", device, iface, winerror(GetLastError())); + logger(LOG_ERR, "Could not get MAC address from Windows tap device %s (%s): %s", device, iface, winerror(GetLastError())); return false; } @@ -228,75 +217,35 @@ static bool setup_device(void) { overwrite_mac = 1; } - device_info = "Windows tap device"; + /* Create overlapped events for tap I/O */ - logger(DEBUG_ALWAYS, LOG_INFO, "%s (%s) is a %s", device, iface, device_info); + r_overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + w_overlapped.hEvent = CreateEvent(NULL, TRUE, TRUE, NULL); - device_read_overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); - device_write_overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + /* Start the tap reader */ + + thread = CreateThread(NULL, 0, tapreader, NULL, 0, NULL); + + if(!thread) { + logger(LOG_ERR, "System call `%s' failed: %s", "CreateThread", winerror(GetLastError())); + return false; + } + + /* Set media status for newer TAP-Win32 devices */ + + status = true; + DeviceIoControl(device_handle, TAP_IOCTL_SET_MEDIA_STATUS, &status, sizeof(status), &status, sizeof(status), &len, NULL); + + logger(LOG_INFO, "%s (%s) is a %s", device, iface, device_info); return true; } -static void enable_device(void) { - logger(DEBUG_ALWAYS, LOG_INFO, "Enabling %s", device_info); - - ULONG status = 1; - DWORD len; - DeviceIoControl(device_handle, TAP_IOCTL_SET_MEDIA_STATUS, &status, sizeof(status), &status, sizeof(status), &len, NULL); - - /* We don't use the write event directly, but GetOverlappedResult() does, internally. */ - - io_add_event(&device_read_io, device_handle_read, NULL, device_read_overlapped.hEvent); - device_issue_read(); -} - -static void disable_device(void) { - logger(DEBUG_ALWAYS, LOG_INFO, "Disabling %s", device_info); - - io_del(&device_read_io); - - ULONG status = 0; - DWORD len; - DeviceIoControl(device_handle, TAP_IOCTL_SET_MEDIA_STATUS, &status, sizeof(status), &status, sizeof(status), &len, NULL); - - /* Note that we don't try to cancel ongoing I/O here - we just stop listening. - This is because some TAP-Win32 drivers don't seem to handle cancellation very well, - especially when combined with other events such as the computer going to sleep - cases - were observed where the GetOverlappedResult() would just block indefinitely and never - return in that case. */ -} - static void close_device(void) { - CancelIo(device_handle); - - /* According to MSDN, CancelIo() does not necessarily wait for the operation to complete. - To prevent race conditions, make sure the operation is complete - before we close the event it's referencing. */ - - DWORD len; - - if(!GetOverlappedResult(device_handle, &device_read_overlapped, &len, TRUE) && GetLastError() != ERROR_OPERATION_ABORTED) { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not wait for %s %s read to cancel: %s", device_info, device, winerror(GetLastError())); - } - - if(device_write_packet.len > 0 && !GetOverlappedResult(device_handle, &device_write_overlapped, &len, TRUE) && GetLastError() != ERROR_OPERATION_ABORTED) { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not wait for %s %s write to cancel: %s", device_info, device, winerror(GetLastError())); - } - - device_write_packet.len = 0; - - CloseHandle(device_read_overlapped.hEvent); - CloseHandle(device_write_overlapped.hEvent); - CloseHandle(device_handle); - device_handle = INVALID_HANDLE_VALUE; free(device); - device = NULL; free(iface); - iface = NULL; - device_info = NULL; } static bool read_packet(vpn_packet_t *packet) { @@ -304,50 +253,70 @@ static bool read_packet(vpn_packet_t *packet) { } static bool write_packet(vpn_packet_t *packet) { - DWORD outlen; + DWORD lenout; + static vpn_packet_t queue; - logger(DEBUG_TRAFFIC, LOG_DEBUG, "Writing packet of %d bytes to %s", - packet->len, device_info); + ifdebug(TRAFFIC) logger(LOG_DEBUG, "Writing packet of %d bytes to %s", + packet->len, device_info); - if(device_write_packet.len > 0) { - /* Make sure the previous write operation is finished before we start the next one; - otherwise we end up with multiple write ops referencing the same OVERLAPPED structure, - which according to MSDN is a no-no. */ + /* Check if there is something in progress */ - if(!GetOverlappedResult(device_handle, &device_write_overlapped, &outlen, FALSE)) { - if(GetLastError() != ERROR_IO_INCOMPLETE) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error completing previously queued write to %s %s: %s", device_info, device, winerror(GetLastError())); + if(queue.len) { + DWORD size; + BOOL success = GetOverlappedResult(device_handle, &w_overlapped, &size, FALSE); + + if(success) { + ResetEvent(&w_overlapped); + queue.len = 0; + } else { + int err = GetLastError(); + + if(err != ERROR_IO_INCOMPLETE) { + ifdebug(TRAFFIC) logger(LOG_DEBUG, "Error completing previously queued write: %s", winerror(err)); + ResetEvent(&w_overlapped); + queue.len = 0; } else { - logger(DEBUG_TRAFFIC, LOG_ERR, "Previous overlapped write to %s %s still in progress", device_info, device); + ifdebug(TRAFFIC) logger(LOG_DEBUG, "Previous overlapped write still in progress"); // drop this packet return true; } } } - /* Copy the packet, since the write operation might still be ongoing after we return. */ + /* Otherwise, try to write. */ - memcpy(&device_write_packet, packet, sizeof(*packet)); + memcpy(queue.data, packet->data, packet->len); - ResetEvent(device_write_overlapped.hEvent); + if(!WriteFile(device_handle, queue.data, packet->len, &lenout, &w_overlapped)) { + int err = GetLastError(); - if(WriteFile(device_handle, DATA(&device_write_packet), device_write_packet.len, &outlen, &device_write_overlapped)) { + if(err != ERROR_IO_PENDING) { + logger(LOG_ERR, "Error while writing to %s %s: %s", device_info, device, winerror(err)); + return false; + } + + // Write is being done asynchronously. + queue.len = packet->len; + } else { // Write was completed immediately. - device_write_packet.len = 0; - } else if(GetLastError() != ERROR_IO_PENDING) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error while writing to %s %s: %s", device_info, device, winerror(GetLastError())); - device_write_packet.len = 0; - return false; + ResetEvent(&w_overlapped); } + device_total_out += packet->len; + return true; } +static void dump_device_stats(void) { + logger(LOG_DEBUG, "Statistics for %s %s:", device_info, device); + logger(LOG_DEBUG, " total bytes in: %10"PRIu64, device_total_in); + logger(LOG_DEBUG, " total bytes out: %10"PRIu64, device_total_out); +} + const devops_t os_devops = { .setup = setup_device, .close = close_device, .read = read_packet, .write = write_packet, - .enable = enable_device, - .disable = disable_device, + .dump_stats = dump_device_stats, }; diff --git a/src/multicast_device.c b/src/multicast_device.c index e9607f0..93a40c4 100644 --- a/src/multicast_device.c +++ b/src/multicast_device.c @@ -1,7 +1,7 @@ /* device.c -- multicast socket Copyright (C) 2002-2005 Ivo Timmermans, - 2002-2013 Guus Sliepen + 2002-2014 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 @@ -31,11 +31,14 @@ static const char *device_info = "multicast socket"; +static uint64_t device_total_in = 0; +static uint64_t device_total_out = 0; + static struct addrinfo *ai = NULL; -static mac_t ignore_src = {0}; +static mac_t ignore_src = {{0}}; static bool setup_device(void) { - char *host = NULL; + char *host; char *port; char *space; int ttl = 1; @@ -43,16 +46,17 @@ static bool setup_device(void) { get_config_string(lookup_config(config_tree, "Interface"), &iface); if(!get_config_string(lookup_config(config_tree, "Device"), &device)) { - logger(DEBUG_ALWAYS, LOG_ERR, "Device variable required for %s", device_info); - goto error; + logger(LOG_ERR, "Device variable required for %s", device_info); + return false; } host = xstrdup(device); space = strchr(host, ' '); if(!space) { - logger(DEBUG_ALWAYS, LOG_ERR, "Port number required for %s", device_info); - goto error; + logger(LOG_ERR, "Port number required for %s", device_info); + free(host); + return false; } *space++ = 0; @@ -67,14 +71,16 @@ static bool setup_device(void) { ai = str2addrinfo(host, port, SOCK_DGRAM); if(!ai) { - goto error; + free(host); + return false; } device_fd = socket(ai->ai_family, SOCK_DGRAM, IPPROTO_UDP); if(device_fd < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Creating socket failed: %s", sockstrerror(sockerrno)); - goto error; + logger(LOG_ERR, "Creating socket failed: %s", sockstrerror(sockerrno)); + free(host); + return false; } #ifdef FD_CLOEXEC @@ -85,8 +91,10 @@ static bool setup_device(void) { setsockopt(device_fd, SOL_SOCKET, SO_REUSEADDR, (void *)&one, sizeof(one)); if(bind(device_fd, ai->ai_addr, ai->ai_addrlen)) { - logger(DEBUG_ALWAYS, LOG_ERR, "Can't bind to %s %s: %s", host, port, sockstrerror(sockerrno)); - goto error; + closesocket(device_fd); + logger(LOG_ERR, "Can't bind to %s %s: %s", host, port, sockstrerror(sockerrno)); + free(host); + return false; } switch(ai->ai_family) { @@ -100,8 +108,10 @@ static bool setup_device(void) { mreq.imr_interface.s_addr = htonl(INADDR_ANY); if(setsockopt(device_fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (void *)&mreq, sizeof(mreq))) { - logger(DEBUG_ALWAYS, LOG_ERR, "Cannot join multicast group %s %s: %s", host, port, sockstrerror(sockerrno)); - goto error; + logger(LOG_ERR, "Cannot join multicast group %s %s: %s", host, port, sockstrerror(sockerrno)); + closesocket(device_fd); + free(host); + return false; } #ifdef IP_MULTICAST_LOOP @@ -124,8 +134,10 @@ static bool setup_device(void) { mreq.ipv6mr_interface = in6.sin6_scope_id; if(setsockopt(device_fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, (void *)&mreq, sizeof(mreq))) { - logger(DEBUG_ALWAYS, LOG_ERR, "Cannot join multicast group %s %s: %s", host, port, sockstrerror(sockerrno)); - goto error; + logger(LOG_ERR, "Cannot join multicast group %s %s: %s", host, port, sockstrerror(sockerrno)); + closesocket(device_fd); + free(host); + return false; } #ifdef IPV6_MULTICAST_LOOP @@ -139,86 +151,97 @@ static bool setup_device(void) { #endif default: - logger(DEBUG_ALWAYS, LOG_ERR, "Multicast for address family %x unsupported", ai->ai_family); - goto error; - } - - logger(DEBUG_ALWAYS, LOG_INFO, "%s is a %s", device, device_info); - - return true; - -error: - - if(device_fd >= 0) { + logger(LOG_ERR, "Multicast for address family %x unsupported", ai->ai_family); closesocket(device_fd); - } - - if(ai) { - freeaddrinfo(ai); + free(host); + return false; } free(host); + logger(LOG_INFO, "%s is a %s", device, device_info); - return false; + return true; } static void close_device(void) { close(device_fd); - device_fd = -1; free(device); - device = NULL; free(iface); - iface = NULL; if(ai) { freeaddrinfo(ai); - ai = NULL; } - - device_info = NULL; } static bool read_packet(vpn_packet_t *packet) { int lenin; - if((lenin = recv(device_fd, (void *)DATA(packet), MTU, 0)) <= 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info, - device, sockstrerror(sockerrno)); + if((lenin = recv(device_fd, (void *)packet->data, MTU, 0)) <= 0) { + logger(LOG_ERR, "Error while reading from %s %s: %s", device_info, + device, strerror(errno)); return false; } - if(!memcmp(&ignore_src, DATA(packet) + 6, sizeof(ignore_src))) { - logger(DEBUG_SCARY_THINGS, LOG_DEBUG, "Ignoring loopback packet of %d bytes from %s", lenin, device_info); - return false; + if(!memcmp(&ignore_src, packet->data + 6, sizeof(ignore_src))) { + ifdebug(SCARY_THINGS) logger(LOG_DEBUG, "Ignoring loopback packet of %d bytes from %s", lenin, device_info); + packet->len = 0; + return true; } packet->len = lenin; - logger(DEBUG_TRAFFIC, LOG_DEBUG, "Read packet of %d bytes from %s", packet->len, - device_info); + device_total_in += packet->len; + + ifdebug(TRAFFIC) logger(LOG_DEBUG, "Read packet of %d bytes from %s", packet->len, + device_info); return true; } static bool write_packet(vpn_packet_t *packet) { - logger(DEBUG_TRAFFIC, LOG_DEBUG, "Writing packet of %d bytes to %s", - packet->len, device_info); + ifdebug(TRAFFIC) logger(LOG_DEBUG, "Writing packet of %d bytes to %s", + packet->len, device_info); - if(sendto(device_fd, (void *)DATA(packet), packet->len, 0, ai->ai_addr, ai->ai_addrlen) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Can't write to %s %s: %s", device_info, device, - sockstrerror(sockerrno)); + if(sendto(device_fd, (void *)packet->data, packet->len, 0, ai->ai_addr, ai->ai_addrlen) < 0) { + logger(LOG_ERR, "Can't write to %s %s: %s", device_info, device, + strerror(errno)); return false; } - memcpy(&ignore_src, DATA(packet) + 6, sizeof(ignore_src)); + device_total_out += packet->len; + + memcpy(&ignore_src, packet->data + 6, sizeof(ignore_src)); return true; } +static void dump_device_stats(void) { + logger(LOG_DEBUG, "Statistics for %s %s:", device_info, device); + logger(LOG_DEBUG, " total bytes in: %10"PRIu64, device_total_in); + logger(LOG_DEBUG, " total bytes out: %10"PRIu64, device_total_out); +} + const devops_t multicast_devops = { .setup = setup_device, .close = close_device, .read = read_packet, .write = write_packet, + .dump_stats = dump_device_stats, }; + +#if 0 + +static bool not_supported(void) { + logger(LOG_ERR, "Raw socket device not supported on this platform"); + return false; +} + +const devops_t multicast_devops = { + .setup = not_supported, + .close = NULL, + .read = NULL, + .write = NULL, + .dump_stats = NULL, +}; +#endif diff --git a/src/names.c b/src/names.c deleted file mode 100644 index 6db364e..0000000 --- a/src/names.c +++ /dev/null @@ -1,180 +0,0 @@ -/* - names.c -- generate commonly used (file)names - Copyright (C) 1998-2005 Ivo Timmermans - 2000-2017 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 - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include "system.h" - -#include "logger.h" -#include "names.h" -#include "xalloc.h" - -char *netname = NULL; -char *myname = NULL; -char *confdir = NULL; /* base configuration directory */ -char *confbase = NULL; /* base configuration directory for this instance of tinc */ -bool confbase_given; -char *identname = NULL; /* program name for syslog */ -char *unixsocketname = NULL; /* UNIX socket location */ -char *logfilename = NULL; /* log file location */ -char *pidfilename = NULL; -char *program_name = NULL; - -/* - Set all files and paths according to netname -*/ -void make_names(bool daemon) { -#ifdef HAVE_MINGW - HKEY key; - char installdir[1024] = ""; - DWORD len = sizeof(installdir); -#endif - confbase_given = confbase; - - if(netname && confbase) { - logger(DEBUG_ALWAYS, LOG_INFO, "Both netname and configuration directory given, using the latter..."); - } - - if(netname) { - xasprintf(&identname, "tinc.%s", netname); - } else { - identname = xstrdup("tinc"); - } - -#ifdef HAVE_MINGW - - if(!RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\tinc", 0, KEY_READ, &key)) { - if(!RegQueryValueEx(key, NULL, 0, 0, (LPBYTE)installdir, &len)) { - confdir = xstrdup(installdir); - - if(!confbase) { - if(netname) { - xasprintf(&confbase, "%s" SLASH "%s", installdir, netname); - } else { - xasprintf(&confbase, "%s", installdir); - } - } - - if(!logfilename) { - xasprintf(&logfilename, "%s" SLASH "tinc.log", confbase); - } - } - - RegCloseKey(key); - } - -#endif - - if(!confdir) { - confdir = xstrdup(CONFDIR SLASH "tinc"); - } - - if(!confbase) { - if(netname) { - xasprintf(&confbase, CONFDIR SLASH "tinc" SLASH "%s", netname); - } else { - xasprintf(&confbase, CONFDIR SLASH "tinc"); - } - } - -#ifdef HAVE_MINGW - - if(!logfilename) { - xasprintf(&logfilename, "%s" SLASH "log", confbase); - } - - if(!pidfilename) { - xasprintf(&pidfilename, "%s" SLASH "pid", confbase); - } - -#else - bool fallback = false; - - if(daemon) { - if(access(LOCALSTATEDIR, R_OK | W_OK | X_OK)) { - fallback = true; - } - } else { - char fname[PATH_MAX]; - snprintf(fname, sizeof(fname), LOCALSTATEDIR SLASH "run" SLASH "%s.pid", identname); - - if(access(fname, R_OK)) { - snprintf(fname, sizeof(fname), "%s" SLASH "pid", confbase); - - if(!access(fname, R_OK)) { - fallback = true; - } - } - } - - if(!fallback) { - if(!logfilename) { - xasprintf(&logfilename, LOCALSTATEDIR SLASH "log" SLASH "%s.log", identname); - } - - if(!pidfilename) { - xasprintf(&pidfilename, LOCALSTATEDIR SLASH "run" SLASH "%s.pid", identname); - } - } else { - if(!logfilename) { - xasprintf(&logfilename, "%s" SLASH "log", confbase); - } - - if(!pidfilename) { - if(daemon) { - logger(DEBUG_ALWAYS, LOG_WARNING, "Could not access " LOCALSTATEDIR SLASH " (%s), storing pid and socket files in %s" SLASH, strerror(errno), confbase); - } - - xasprintf(&pidfilename, "%s" SLASH "pid", confbase); - } - } - -#endif - - if(!unixsocketname) { - int len = strlen(pidfilename); - unixsocketname = xmalloc(len + 8); - memcpy(unixsocketname, pidfilename, len); - - if(len > 4 && !strcmp(pidfilename + len - 4, ".pid")) { - strncpy(unixsocketname + len - 4, ".socket", 8); - } else { - strncpy(unixsocketname + len, ".socket", 8); - } - } -} - -void free_names(void) { - free(identname); - free(netname); - free(unixsocketname); - free(pidfilename); - free(logfilename); - free(confbase); - free(confdir); - free(myname); - - identname = NULL; - netname = NULL; - unixsocketname = NULL; - pidfilename = NULL; - logfilename = NULL; - confbase = NULL; - confdir = NULL; - myname = NULL; -} diff --git a/src/names.h b/src/names.h deleted file mode 100644 index f109686..0000000 --- a/src/names.h +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef TINC_NAMES_H -#define TINC_NAMES_H - -/* - names.h -- header for names.c - Copyright (C) 1998-2005 Ivo Timmermans - 2000-2017 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 - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -extern char *confdir; -extern char *confbase; -extern bool confbase_given; -extern char *netname; -extern char *myname; -extern char *identname; -extern char *unixsocketname; -extern char *logfilename; -extern char *pidfilename; -extern char *program_name; - -extern void make_names(bool daemon); -extern void free_names(void); - -#endif diff --git a/src/net.c b/src/net.c index 75838e0..37ae116 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-2017 Guus Sliepen + 2000-2015 Guus Sliepen 2006 Scott Lamb 2011 Loïc Grenié @@ -22,41 +22,59 @@ #include "system.h" -#include "autoconnect.h" +#include + +#include "utils.h" +#include "avl_tree.h" #include "conf.h" #include "connection.h" #include "device.h" +#include "event.h" #include "graph.h" #include "logger.h" #include "meta.h" -#include "names.h" #include "net.h" #include "netutl.h" +#include "process.h" #include "protocol.h" +#include "route.h" #include "subnet.h" -#include "utils.h" #include "xalloc.h" +bool do_purge = false; +volatile bool running = false; +#ifdef HAVE_PSELECT +bool graph_dump = false; +#endif + +time_t now = 0; int contradicting_add_edge = 0; int contradicting_del_edge = 0; static int sleeptime = 10; -time_t last_config_check = 0; -static timeout_t pingtimer; -static timeout_t periodictimer; -static struct timeval last_periodic_run_time; /* Purge edges and subnets of unreachable nodes. Use carefully. */ -void purge(void) { - logger(DEBUG_PROTOCOL, LOG_DEBUG, "Purging unreachable nodes"); +static void purge(void) { + avl_node_t *nnode, *nnext, *enode, *enext, *snode, *snext; + node_t *n; + edge_t *e; + subnet_t *s; + + ifdebug(PROTOCOL) logger(LOG_DEBUG, "Purging unreachable nodes"); /* Remove all edges and subnets owned by unreachable nodes. */ - for splay_each(node_t, n, node_tree) { - if(!n->status.reachable) { - logger(DEBUG_SCARY_THINGS, LOG_DEBUG, "Purging node %s (%s)", n->name, n->hostname); + for(nnode = node_tree->head; nnode; nnode = nnext) { + nnext = nnode->next; + n = nnode->data; - for splay_each(subnet_t, s, n->subnet_tree) { + if(!n->status.reachable) { + ifdebug(SCARY_THINGS) logger(LOG_DEBUG, "Purging node %s (%s)", n->name, + n->hostname); + + for(snode = n->subnet_tree->head; snode; snode = snext) { + snext = snode->next; + s = snode->data; send_del_subnet(everyone, s); if(!strictsubnets) { @@ -64,7 +82,10 @@ void purge(void) { } } - for splay_each(edge_t, e, n->edge_tree) { + for(enode = n->edge_tree->head; enode; enode = enext) { + enext = enode->next; + e = enode->data; + if(!tunnelserver) { send_del_edge(everyone, e); } @@ -76,14 +97,21 @@ void purge(void) { /* Check if anyone else claims to have an edge to an unreachable node. If not, delete node. */ - for splay_each(node_t, n, node_tree) { - if(!n->status.reachable) { - for splay_each(edge_t, e, edge_weight_tree) - if(e->to == n) { - return; - } + for(nnode = node_tree->head; nnode; nnode = nnext) { + nnext = nnode->next; + n = nnode->data; - if(!autoconnect && (!strictsubnets || !n->subnet_tree->head)) + if(!n->status.reachable) { + for(enode = edge_weight_tree->head; enode; enode = enext) { + enext = enode->next; + e = enode->data; + + if(e->to == n) { + break; + } + } + + if(!enode && (!strictsubnets || !n->subnet_tree->head)) /* in strictsubnets mode do not delete nodes with subnets */ { node_del(n); @@ -92,10 +120,70 @@ void purge(void) { } } +/* + put all file descriptors in an fd_set array + While we're at it, purge stuff that needs to be removed. +*/ +static int build_fdset(fd_set *readset, fd_set *writeset) { + avl_node_t *node, *next; + connection_t *c; + int i, max = 0; + + FD_ZERO(readset); + FD_ZERO(writeset); + + for(node = connection_tree->head; node; node = next) { + next = node->next; + c = node->data; + + if(c->status.remove) { + connection_del(c); + + if(!connection_tree->head) { + purge(); + } + } else { + FD_SET(c->socket, readset); + + if(c->outbuflen > 0 || c->status.connecting) { + FD_SET(c->socket, writeset); + } + + if(c->socket > max) { + max = c->socket; + } + } + } + + for(i = 0; i < listen_sockets; i++) { + FD_SET(listen_socket[i].tcp, readset); + + if(listen_socket[i].tcp > max) { + max = listen_socket[i].tcp; + } + + FD_SET(listen_socket[i].udp, readset); + + if(listen_socket[i].udp > max) { + max = listen_socket[i].udp; + } + } + + if(device_fd >= 0) { + FD_SET(device_fd, readset); + } + + if(device_fd > max) { + max = device_fd; + } + + return max; +} + /* Put a misbehaving connection in the tarpit */ void tarpit(int fd) { static int pits[10] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1}; - static unsigned int next_pit = 0; + static int next_pit = 0; if(pits[next_pit] != -1) { closesocket(pits[next_pit]); @@ -103,62 +191,82 @@ void tarpit(int fd) { pits[next_pit++] = fd; - if(next_pit >= sizeof pits / sizeof pits[0]) { + if(next_pit >= (int)(sizeof pits / sizeof pits[0])) { next_pit = 0; } } /* Terminate a connection: - - Mark it as inactive - - Remove the edge representing this connection - - Kill it with fire + - Close the socket + - Remove associated edge and tell other connections about it if report = true - Check if we need to retry making an outgoing connection + - Deactivate the host */ void terminate_connection(connection_t *c, bool report) { - logger(DEBUG_CONNECTIONS, LOG_NOTICE, "Closing connection with %s (%s)", c->name, c->hostname); + if(c->status.remove) { + return; + } + + ifdebug(CONNECTIONS) logger(LOG_NOTICE, "Closing connection with %s (%s)", + c->name, c->hostname); + + c->status.remove = true; + c->status.active = false; if(c->node) { - if(c->node->connection == c) { - c->node->connection = NULL; + c->node->connection = NULL; + } + + if(c->socket) { + if(c->status.tarpit) { + tarpit(c->socket); + } else { + closesocket(c->socket); + } + } + + if(c->edge) { + if(!c->node) { + logger(LOG_ERR, "Connection to %s (%s) has an edge but node is NULL!", c->name, c->hostname); + // And that should never happen. + abort(); } - if(c->edge) { - if(report && !tunnelserver) { - send_del_edge(everyone, c->edge); - } + if(report && !tunnelserver) { + send_del_edge(everyone, c->edge); + } - edge_del(c->edge); - c->edge = NULL; + edge_del(c->edge); + c->edge = NULL; - /* Run MST and SSSP algorithms */ + /* Run MST and SSSP algorithms */ - graph(); + graph(); - /* If the node is not reachable anymore but we remember it had an edge to us, clean it up */ + /* If the node is not reachable anymore but we remember it had an edge to us, clean it up */ - if(report && !c->node->status.reachable) { - edge_t *e; - e = lookup_edge(c->node, myself); + if(report && !c->node->status.reachable) { + edge_t *e; + e = lookup_edge(c->node, myself); - if(e) { - if(!tunnelserver) { - send_del_edge(everyone, e); - } - - edge_del(e); + if(e) { + if(!tunnelserver) { + send_del_edge(everyone, e); } + + edge_del(e); } } } - outgoing_t *outgoing = c->outgoing; - connection_del(c); + free_connection_partially(c); /* Check if this was our outgoing connection */ - if(outgoing) { - do_outgoing_connection(outgoing); + if(c->outgoing) { + c->status.remove = false; + do_outgoing_connection(c); } #ifndef HAVE_MINGW @@ -177,351 +285,427 @@ void terminate_connection(connection_t *c, bool report) { end does not reply in time, we consider them dead and close the connection. */ -static void timeout_handler(void *data) { +static void check_dead_connections(void) { + avl_node_t *node, *next; + connection_t *c; - bool close_all_connections = false; + for(node = connection_tree->head; node; node = next) { + next = node->next; + c = node->data; - /* - timeout_handler will start after 30 seconds from start of tincd - hold information about the elapsed time since last time the handler - has been run - */ - long sleep_time = now.tv_sec - last_periodic_run_time.tv_sec; + if(c->last_ping_time + pingtimeout <= now) { + if(c->status.active) { + if(c->status.pinged) { + ifdebug(CONNECTIONS) logger(LOG_INFO, "%s (%s) didn't respond to PING in %ld seconds", + c->name, c->hostname, (long)(now - c->last_ping_time)); + c->status.timeout = true; + terminate_connection(c, true); + } else if(c->last_ping_time + pinginterval <= now) { + send_ping(c); + } + } else { + if(c->status.remove) { + logger(LOG_WARNING, "Old connection_t for %s (%s) status %04x still lingering, deleting...", + c->name, c->hostname, bitfield_to_int(&c->status, sizeof(c->status))); + connection_del(c); + continue; + } - /* - It seems that finding sane default value is harder than expected - Since we send every second a UDP packet to make holepunching work - And default UDP state expire on firewalls is between 15-30 seconds - we drop all connections after 60 Seconds - UDPDiscoveryTimeout=30 - by default - */ - if(sleep_time > 2 * udp_discovery_timeout) { - logger(DEBUG_ALWAYS, LOG_ERR, "Awaking from dead after %ld seconds of sleep", sleep_time); - /* - Do not send any packets to tinc after we wake up. - The other node probably closed our connection but we still - are holding context information to them. This may happen on - laptops or any other hardware which can be suspended for some time. - Sending any data to node that wasn't expecting it will produce - annoying and misleading errors on the other side about failed signature - verification and or about missing sptps context - */ - close_all_connections = true; + ifdebug(CONNECTIONS) logger(LOG_WARNING, "Timeout from %s (%s) during authentication", + c->name, c->hostname); + + if(c->status.connecting) { + c->status.connecting = false; + closesocket(c->socket); + do_outgoing_connection(c); + } else { + c->status.tarpit = true; + terminate_connection(c, false); + } + } + } + + if(c->outbuflen > 0 && c->last_flushed_time + pingtimeout <= now) { + if(c->status.active) { + ifdebug(CONNECTIONS) logger(LOG_INFO, + "%s (%s) could not flush for %ld seconds (%d bytes remaining)", + c->name, c->hostname, (long)(now - c->last_flushed_time), c->outbuflen); + c->status.timeout = true; + terminate_connection(c, true); + } + } + } +} + +/* + check all connections to see if anything + happened on their sockets +*/ +static void check_network_activity(fd_set *readset, fd_set *writeset) { + connection_t *c; + avl_node_t *node; + int result, i; + socklen_t len = sizeof(result); + vpn_packet_t packet; + static int errors = 0; + + /* check input from kernel */ + if(device_fd >= 0 && FD_ISSET(device_fd, readset)) { + if(devops.read(&packet)) { + if(packet.len) { + errors = 0; + packet.priority = 0; + route(myself, &packet); + } + } else { + usleep(errors * 50000); + errors++; + + if(errors > 10) { + logger(LOG_ERR, "Too many errors from %s, exiting!", device); + running = false; + } + } } - last_periodic_run_time = now; + /* check meta connections */ + for(node = connection_tree->head; node; node = node->next) { + c = node->data; - for list_each(connection_t, c, connection_list) { - // control connections (eg. tinc ctl) do not have any timeout - if(c->status.control) { + if(c->status.remove) { continue; } - if(close_all_connections) { - logger(DEBUG_ALWAYS, LOG_ERR, "Forcing connection close after sleep time %s (%s)", c->name, c->hostname); - terminate_connection(c, c->edge); - continue; - } - - // Bail out early if we haven't reached the ping timeout for this node yet - if(c->last_ping_time + pingtimeout > now.tv_sec) { - continue; - } - - // timeout during connection establishing - if(!c->edge) { + if(FD_ISSET(c->socket, writeset)) { if(c->status.connecting) { - logger(DEBUG_CONNECTIONS, LOG_WARNING, "Timeout while connecting to %s (%s)", c->name, c->hostname); - } else { - logger(DEBUG_CONNECTIONS, LOG_WARNING, "Timeout from %s (%s) during authentication", c->name, c->hostname); + c->status.connecting = false; + getsockopt(c->socket, SOL_SOCKET, SO_ERROR, (void *)&result, &len); + + if(!result) { + finish_connecting(c); + } else { + ifdebug(CONNECTIONS) logger(LOG_DEBUG, + "Error while connecting to %s (%s): %s", + c->name, c->hostname, sockstrerror(result)); + closesocket(c->socket); + do_outgoing_connection(c); + continue; + } + } + + if(!flush_meta(c)) { + terminate_connection(c, c->status.active); + continue; + } + } + + if(FD_ISSET(c->socket, readset)) { + if(!receive_meta(c)) { c->status.tarpit = true; - } - - terminate_connection(c, c->edge); - continue; - } - - // helps in UDP holepunching - try_tx(c->node, false); - - // timeout during ping - if(c->status.pinged) { - logger(DEBUG_CONNECTIONS, LOG_INFO, "%s (%s) didn't respond to PING in %ld seconds", c->name, c->hostname, (long)(now.tv_sec - c->last_ping_time)); - terminate_connection(c, c->edge); - continue; - } - - // check whether we need to send a new ping - if(c->last_ping_time + pinginterval <= now.tv_sec) { - send_ping(c); - } - } - - timeout_set(data, &(struct timeval) { - 1, rand() % 100000 - }); -} - -static void periodic_handler(void *data) { - /* Check if there are too many contradicting ADD_EDGE and DEL_EDGE messages. - This usually only happens when another node has the same Name as this node. - If so, sleep for a short while to prevent a storm of contradicting messages. - */ - - if(contradicting_del_edge > 100 && contradicting_add_edge > 100) { - logger(DEBUG_ALWAYS, LOG_WARNING, "Possible node with same Name as us! Sleeping %d seconds.", sleeptime); - nanosleep(&(struct timespec) { - sleeptime, 0 - }, NULL); - sleeptime *= 2; - - if(sleeptime < 0) { - sleeptime = 3600; - } - } else { - sleeptime /= 2; - - if(sleeptime < 10) { - sleeptime = 10; - } - } - - contradicting_add_edge = 0; - contradicting_del_edge = 0; - - /* If AutoConnect is set, check if we need to make or break connections. */ - - if(autoconnect && node_tree->count > 1) { - do_autoconnect(); - } - - timeout_set(data, &(struct timeval) { - 5, rand() % 100000 - }); -} - -void handle_meta_connection_data(connection_t *c) { - if(!receive_meta(c)) { - if(!c->status.control) { - c->status.tarpit = true; - } - - terminate_connection(c, c->edge); - return; - } -} - -#ifndef HAVE_MINGW -static void sigterm_handler(void *data) { - logger(DEBUG_ALWAYS, LOG_NOTICE, "Got %s signal", strsignal(((signal_t *)data)->signum)); - event_exit(); -} - -static void sighup_handler(void *data) { - logger(DEBUG_ALWAYS, LOG_NOTICE, "Got %s signal", strsignal(((signal_t *)data)->signum)); - reopenlogger(); - - if(reload_configuration()) { - exit(1); - } -} - -static void sigalrm_handler(void *data) { - logger(DEBUG_ALWAYS, LOG_NOTICE, "Got %s signal", strsignal(((signal_t *)data)->signum)); - retry(); -} -#endif - -int reload_configuration(void) { - char fname[PATH_MAX]; - - /* Reread our own configuration file */ - - exit_configuration(&config_tree); - init_configuration(&config_tree); - - if(!read_server_config()) { - logger(DEBUG_ALWAYS, LOG_ERR, "Unable to reread configuration file."); - return EINVAL; - } - - read_config_options(config_tree, NULL); - - snprintf(fname, sizeof(fname), "%s" SLASH "hosts" SLASH "%s", confbase, myself->name); - read_config_file(config_tree, fname, true); - - /* Parse some options that are allowed to be changed while tinc is running */ - - setup_myself_reloadable(); - - /* If StrictSubnet is set, expire deleted Subnets and read new ones in */ - - if(strictsubnets) { - for splay_each(subnet_t, subnet, subnet_tree) - if(subnet->owner) { - subnet->expires = 1; - } - } - - for splay_each(node_t, n, node_tree) { - n->status.has_address = false; - } - - load_all_nodes(); - - if(strictsubnets) { - for splay_each(subnet_t, subnet, subnet_tree) { - if(!subnet->owner) { + terminate_connection(c, c->status.active); continue; } - - if(subnet->expires == 1) { - send_del_subnet(everyone, 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(everyone, subnet); - - if(subnet->owner->status.reachable) { - subnet_update(subnet->owner, subnet, true); - } - } - } - } else { /* Only read our own subnets back in */ - for splay_each(subnet_t, subnet, myself->subnet_tree) - if(!subnet->expires) { - subnet->expires = 1; - } - - config_t *cfg = lookup_config(config_tree, "Subnet"); - - while(cfg) { - subnet_t *subnet, *s2; - - if(!get_config_subnet(cfg, &subnet)) { - continue; - } - - if((s2 = lookup_subnet(myself, subnet))) { - if(s2->expires == 1) { - s2->expires = 0; - } - - free_subnet(subnet); - } else { - subnet_add(myself, subnet); - send_add_subnet(everyone, subnet); - subnet_update(myself, subnet, true); - } - - cfg = lookup_config_next(config_tree, cfg); - } - - for splay_each(subnet_t, subnet, myself->subnet_tree) { - if(subnet->expires == 1) { - send_del_subnet(everyone, subnet); - subnet_update(myself, subnet, false); - subnet_del(myself, subnet); - } } } - /* Try to make outgoing connections */ - - try_outgoing_connections(); - - /* Close connections to hosts that have a changed or deleted host config file */ - - for list_each(connection_t, c, connection_list) { - if(c->status.control) { - continue; + for(i = 0; i < listen_sockets; i++) { + if(FD_ISSET(listen_socket[i].udp, readset)) { + handle_incoming_vpn_data(i); } - snprintf(fname, sizeof(fname), "%s" SLASH "hosts" SLASH "%s", confbase, c->name); - struct stat s; - - if(stat(fname, &s) || s.st_mtime > last_config_check) { - logger(DEBUG_CONNECTIONS, LOG_INFO, "Host config file of %s has been changed", c->name); - terminate_connection(c, c->edge); + if(FD_ISSET(listen_socket[i].tcp, readset)) { + handle_new_meta_connection(listen_socket[i].tcp); } } - - last_config_check = now.tv_sec; - - return 0; -} - -void retry(void) { - /* Reset the reconnection timers for all outgoing connections */ - for list_each(outgoing_t, outgoing, outgoing_list) { - outgoing->timeout = 0; - - if(outgoing->ev.cb) - timeout_set(&outgoing->ev, &(struct timeval) { - 0, 0 - }); - } - - /* Check for outgoing connections that are in progress, and reset their ping timers */ - for list_each(connection_t, c, connection_list) { - if(c->outgoing && !c->node) { - c->last_ping_time = 0; - } - } - - /* Kick the ping timeout handler */ - timeout_set(&pingtimer, &(struct timeval) { - 0, 0 - }); } /* this is where it all happens... */ int main_loop(void) { - last_periodic_run_time = now; - timeout_add(&pingtimer, timeout_handler, &pingtimer, &(struct timeval) { - pingtimeout, rand() % 100000 - }); - timeout_add(&periodictimer, periodic_handler, &periodictimer, &(struct timeval) { - 0, 0 - }); - -#ifndef HAVE_MINGW - signal_t sighup = {0}; - signal_t sigterm = {0}; - signal_t sigquit = {0}; - signal_t sigint = {0}; - signal_t sigalrm = {0}; - - signal_add(&sighup, sighup_handler, &sighup, SIGHUP); - signal_add(&sigterm, sigterm_handler, &sigterm, SIGTERM); - signal_add(&sigquit, sigterm_handler, &sigquit, SIGQUIT); - signal_add(&sigint, sigterm_handler, &sigint, SIGINT); - signal_add(&sigalrm, sigalrm_handler, &sigalrm, SIGALRM); + fd_set readset, writeset; +#ifdef HAVE_PSELECT + struct timespec tv; + sigset_t omask, block_mask; + time_t next_event; +#else + struct timeval tv; #endif + int r, maxfd; + time_t last_ping_check, last_config_check, last_graph_dump; + event_t *event; - if(!event_loop()) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error while waiting for input: %s", sockstrerror(sockerrno)); - return 1; + last_ping_check = now; + last_config_check = now; + last_graph_dump = now; + + srand(now); + +#ifdef HAVE_PSELECT + + if(lookup_config(config_tree, "GraphDumpFile")) { + graph_dump = true; } -#ifndef HAVE_MINGW - signal_del(&sighup); - signal_del(&sigterm); - signal_del(&sigquit); - signal_del(&sigint); - signal_del(&sigalrm); + /* Block SIGHUP & SIGALRM */ + sigemptyset(&block_mask); + sigaddset(&block_mask, SIGHUP); + sigaddset(&block_mask, SIGALRM); + sigprocmask(SIG_BLOCK, &block_mask, &omask); #endif - timeout_del(&periodictimer); - timeout_del(&pingtimer); + running = true; + + while(running) { +#ifdef HAVE_PSELECT + next_event = last_ping_check + pingtimeout; + + if(graph_dump && next_event > last_graph_dump + 60) { + next_event = last_graph_dump + 60; + } + + if((event = peek_next_event()) && next_event > event->time) { + next_event = event->time; + } + + if(next_event <= now) { + tv.tv_sec = 0; + } else { + tv.tv_sec = next_event - now; + } + + tv.tv_nsec = 0; +#else + tv.tv_sec = 1; + tv.tv_usec = 0; +#endif + + maxfd = build_fdset(&readset, &writeset); + +#ifdef HAVE_MINGW + LeaveCriticalSection(&mutex); +#endif +#ifdef HAVE_PSELECT + r = pselect(maxfd + 1, &readset, &writeset, NULL, &tv, &omask); +#else + r = select(maxfd + 1, &readset, &writeset, NULL, &tv); +#endif + now = time(NULL); +#ifdef HAVE_MINGW + EnterCriticalSection(&mutex); +#endif + + if(r < 0) { + if(!sockwouldblock(sockerrno)) { + logger(LOG_ERR, "Error while waiting for input: %s", sockstrerror(sockerrno)); + dump_connections(); + return 1; + } + } + + if(r > 0) { + check_network_activity(&readset, &writeset); + } + + if(do_purge) { + purge(); + do_purge = false; + } + + /* Let's check if everybody is still alive */ + + if(last_ping_check + pingtimeout <= now) { + check_dead_connections(); + last_ping_check = now; + + if(routing_mode == RMODE_SWITCH) { + age_subnets(); + } + + age_past_requests(); + + /* Should we regenerate our key? */ + + if(keyexpires <= now) { + avl_node_t *node; + node_t *n; + + ifdebug(STATUS) logger(LOG_INFO, "Expiring symmetric keys"); + + for(node = node_tree->head; node; node = node->next) { + n = node->data; + + if(n->inkey) { + free(n->inkey); + n->inkey = NULL; + } + } + + send_key_changed(); + keyexpires = now + keylifetime; + } + + /* Detect ADD_EDGE/DEL_EDGE storms that are caused when + * two tinc daemons with the same name are on the VPN. + * If so, sleep a while. If this happens multiple times + * in a row, sleep longer. */ + + if(contradicting_del_edge > 100 && contradicting_add_edge > 100) { + logger(LOG_WARNING, "Possible node with same Name as us! Sleeping %d seconds.", sleeptime); + usleep(sleeptime * 1000000LL); + sleeptime *= 2; + + if(sleeptime < 0) { + sleeptime = 3600; + } + } else { + sleeptime /= 2; + + if(sleeptime < 10) { + sleeptime = 10; + } + } + + contradicting_add_edge = 0; + contradicting_del_edge = 0; + } + + 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; + + if(c->status.active) { + send_ping(c); + } + } + + sigalrm = false; + } + + while((event = get_expired_event())) { + event->handler(event->data); + free_event(event); + } + + if(sighup) { + connection_t *c; + avl_node_t *node, *next; + char *fname; + struct stat s; + + sighup = false; + + reopenlogger(); + + /* Reread our own configuration file */ + + exit_configuration(&config_tree); + init_configuration(&config_tree); + + if(!read_server_config()) { + logger(LOG_ERR, "Unable to reread configuration file, exitting."); + return 1; + } + + /* Cancel non-active outgoing connections */ + + for(node = connection_tree->head; node; node = next) { + next = node->next; + c = node->data; + + c->outgoing = NULL; + + if(c->status.connecting) { + terminate_connection(c, false); + connection_del(c); + } + } + + /* Wipe list of outgoing connections */ + + for(list_node_t *node = outgoing_list->head; node; node = node->next) { + outgoing_t *outgoing = node->data; + + if(outgoing->event) { + event_del(outgoing->event); + } + } + + list_delete_list(outgoing_list); + + /* Close connections to hosts that have a changed or deleted host config file */ + + for(node = connection_tree->head; node; node = node->next) { + c = node->data; + + xasprintf(&fname, "%s/hosts/%s", confbase, c->name); + + if(stat(fname, &s) || s.st_mtime > last_config_check) { + terminate_connection(c, c->status.active); + } + + free(fname); + } + + 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(everyone, 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(everyone, subnet); + + if(subnet->owner->status.reachable) { + subnet_update(subnet->owner, subnet, true); + } + } + } + } + + /* Try to make outgoing connections */ + + try_outgoing_connections(); + } + + /* Dump graph if wanted every 60 seconds*/ + + if(last_graph_dump + 60 <= now) { + dump_graph(); + last_graph_dump = now; + } + } + +#ifdef HAVE_PSELECT + /* Restore SIGHUP & SIGALARM mask */ + sigprocmask(SIG_SETMASK, &omask, NULL); +#endif return 0; } diff --git a/src/net.h b/src/net.h index 8a74d85..a9becb6 100644 --- a/src/net.h +++ b/src/net.h @@ -4,7 +4,7 @@ /* net.h -- header for net.c Copyright (C) 1998-2005 Ivo Timmermans - 2000-2016 Guus Sliepen + 2000-2015 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 @@ -21,10 +21,9 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +#include + #include "ipv6.h" -#include "cipher.h" -#include "digest.h" -#include "event.h" #ifdef ENABLE_JUMBOGRAMS #define MTU 9018 /* 9000 bytes payload + 14 bytes ethernet header + 4 bytes VLAN tag */ @@ -32,13 +31,10 @@ #define MTU 1518 /* 1500 bytes payload + 14 bytes ethernet header + 4 bytes VLAN tag */ #endif -/* MAXSIZE is the maximum size of an encapsulated packet: MTU + seqno + srcid + dstid + padding + HMAC + compressor overhead */ -#define MAXSIZE (MTU + 4 + sizeof(node_id_t) + sizeof(node_id_t) + CIPHER_MAX_BLOCK_SIZE + DIGEST_MAX_SIZE + MTU/64 + 20) +#define MAXSIZE (MTU + 4 + EVP_MAX_BLOCK_LENGTH + EVP_MAX_MD_SIZE + MTU/64 + 20) /* MTU + seqno + padding + HMAC + compressor overhead */ +#define MAXBUFSIZE ((MAXSIZE > 2048 ? MAXSIZE : 2048) + 128) /* Enough room for a request with a MAXSIZEd packet or a 8192 bits RSA key */ -/* MAXBUFSIZE is the maximum size of a request: enough for a MAXSIZEd packet or a 8192 bits RSA key */ -#define MAXBUFSIZE ((MAXSIZE > 2048 ? MAXSIZE : 2048) + 128) - -#define MAXSOCKETS 8 /* Probably overkill... */ +#define MAXSOCKETS 128 /* Overkill... */ typedef struct mac_t { uint8_t x[6]; @@ -52,12 +48,7 @@ typedef struct ipv6_t { uint16_t x[8]; } ipv6_t; -typedef struct node_id_t { - uint8_t x[6]; -} node_id_t; - typedef uint16_t length_t; -typedef uint32_t seqno_t; #define AF_UNKNOWN 255 @@ -74,6 +65,9 @@ typedef union sockaddr_t { struct sockaddr_in in; struct sockaddr_in6 in6; struct sockaddr_unknown unknown; +#ifdef HAVE_STRUCT_SOCKADDR_STORAGE + struct sockaddr_storage storage; +#endif } sockaddr_t; #ifdef SA_LEN @@ -82,36 +76,17 @@ typedef union sockaddr_t { #define SALEN(s) (s.sa_family==AF_INET?sizeof(struct sockaddr_in):sizeof(struct sockaddr_in6)) #endif -#define SEQNO(x) ((x)->data + (x)->offset - 4) -#define SRCID(x) ((node_id_t *)((x)->data + (x)->offset - 6)) -#define DSTID(x) ((node_id_t *)((x)->data + (x)->offset - 12)) -#define DATA(x) ((x)->data + (x)->offset) -#define DEFAULT_PACKET_OFFSET 12 - typedef struct vpn_packet_t { - length_t len; /* The actual number of valid bytes in the `data' field (including seqno or dstid/srcid) */ - length_t offset; /* Offset in the buffer where the packet data starts (righter after seqno or dstid/srcid) */ + length_t len; /* the actual number of bytes in the `data' field */ int priority; /* priority or TOS */ + uint32_t seqno; /* 32 bits sequence number (network byte order of course) */ uint8_t data[MAXSIZE]; } vpn_packet_t; -/* Packet types when using SPTPS */ - -#define PKT_COMPRESSED 1 -#define PKT_MAC 2 -#define PKT_PROBE 4 - -typedef enum packet_type_t { - PACKET_NORMAL, - PACKET_COMPRESSED, - PACKET_PROBE -} packet_type_t; - typedef struct listen_socket_t { - io_t tcp; - io_t udp; + int tcp; + int udp; sockaddr_t sa; - bool bindto; int priority; } listen_socket_t; @@ -119,10 +94,12 @@ typedef struct listen_socket_t { #include "list.h" typedef struct outgoing_t { - struct node_t *node; + char *name; int timeout; - struct address_cache_t *address_cache; - timeout_t ev; + struct config_t *cfg; + struct addrinfo *ai; + struct addrinfo *aip; + struct event *event; } outgoing_t; extern list_t *outgoing_list; @@ -133,91 +110,52 @@ extern int addressfamily; extern unsigned replaywin; extern bool localdiscovery; -extern bool udp_discovery; -extern int udp_discovery_keepalive_interval; -extern int udp_discovery_interval; -extern int udp_discovery_timeout; - -extern int mtu_info_interval; -extern int udp_info_interval; - extern listen_socket_t listen_socket[MAXSOCKETS]; extern int listen_sockets; -extern io_t unix_socket; +extern int keyexpires; extern int keylifetime; extern int udp_rcvbuf; extern int udp_sndbuf; -extern int max_connection_burst; -extern int fwmark; extern bool do_prune; +extern bool do_purge; extern char *myport; -extern bool device_standby; -extern bool autoconnect; -extern bool disablebuggypeers; +extern time_t now; extern int contradicting_add_edge; extern int contradicting_del_edge; -extern time_t last_config_check; -extern char *proxyhost; -extern char *proxyport; -extern char *proxyuser; -extern char *proxypass; -typedef enum proxytype_t { - PROXY_NONE = 0, - PROXY_SOCKS4, - PROXY_SOCKS4A, - PROXY_SOCKS5, - PROXY_HTTP, - PROXY_EXEC, -} proxytype_t; -extern proxytype_t proxytype; - -extern char *scriptinterpreter; -extern char *scriptextension; +extern volatile bool running; /* Yes, very strange placement indeed, but otherwise the typedefs get all tangled up */ #include "connection.h" #include "node.h" extern void retry_outgoing(outgoing_t *outgoing); -extern void handle_incoming_vpn_data(void *data, int flags); +extern void handle_incoming_vpn_data(int sock); extern void finish_connecting(struct connection_t *c); -extern bool do_outgoing_connection(struct outgoing_t *outgoing); -extern void handle_new_meta_connection(void *data, int flags); -extern void handle_new_unix_connection(void *data, int flags); +extern void do_outgoing_connection(struct connection_t *c); +extern bool handle_new_meta_connection(int sock); extern int setup_listen_socket(const sockaddr_t *sa); extern int setup_vpn_in_socket(const sockaddr_t *sa); -extern bool send_sptps_data(node_t *to, node_t *from, int type, const void *data, size_t len); -extern bool receive_sptps_record(void *handle, uint8_t type, const void *data, uint16_t len); -extern void send_packet(struct node_t *n, vpn_packet_t *packet); -extern void receive_tcppacket(struct connection_t *c, const char *buffer, size_t length); -extern bool receive_tcppacket_sptps(struct connection_t *c, const char *buffer, size_t length); -extern void broadcast_packet(const struct node_t *n, vpn_packet_t *packet); +extern void send_packet(const struct node_t *n, vpn_packet_t *packet); +extern void receive_tcppacket(struct connection_t *c, const char *buffer, length_t len); +extern void broadcast_packet(const struct node_t *, vpn_packet_t *packet); extern char *get_name(void); -extern void device_enable(void); -extern void device_disable(void); -extern bool setup_myself_reloadable(void); extern bool setup_network(void); -extern void setup_outgoing_connection(struct outgoing_t *outgoing, bool verbose); +extern void setup_outgoing_connection(struct outgoing_t *outgoing); extern void try_outgoing_connections(void); extern void close_network_connections(void); extern int main_loop(void); extern void terminate_connection(struct connection_t *c, bool report); -extern bool node_read_ecdsa_public_key(struct node_t *n); -extern bool read_ecdsa_public_key(struct connection_t *c); +extern void flush_queue(struct node_t *n); extern bool read_rsa_public_key(struct connection_t *c); -extern void handle_device_data(void *data, int flags); -extern void handle_meta_connection_data(struct connection_t *c); -extern void regenerate_key(void); -extern void purge(void); -extern void retry(void); -extern int reload_configuration(void); -extern void load_all_nodes(void); -extern void try_tx(struct node_t *n, bool mtu); +extern void send_mtu_probe(struct node_t *n); +extern void load_all_subnets(void); extern void tarpit(int fd); #ifndef HAVE_MINGW #define closesocket(s) close(s) +#else +extern CRITICAL_SECTION mutex; #endif #endif diff --git a/src/net_packet.c b/src/net_packet.c index 6b40f2a..938b3b6 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-2017 Guus Sliepen + 2000-2016 Guus Sliepen 2010 Timothy Redaelli 2010 Brandon Black @@ -22,8 +22,13 @@ #include "system.h" +#include +#include +#include +#include +#include + #ifdef HAVE_ZLIB -#define ZLIB_CONST #include #endif @@ -31,56 +36,84 @@ #include LZO1X_H #endif -#include "address_cache.h" -#include "cipher.h" +#include "avl_tree.h" #include "conf.h" #include "connection.h" -#include "crypto.h" -#include "digest.h" #include "device.h" #include "ethernet.h" -#include "ipv4.h" -#include "ipv6.h" +#include "event.h" #include "graph.h" #include "logger.h" #include "net.h" #include "netutl.h" #include "protocol.h" +#include "process.h" #include "route.h" #include "utils.h" #include "xalloc.h" -#ifndef MAX -#define MAX(a, b) ((a) > (b) ? (a) : (b)) -#endif - -/* The minimum size of a probe is 14 bytes, but since we normally use CBC mode - encryption, we can add a few extra random bytes without increasing the - resulting packet size. */ -#define MIN_PROBE_SIZE 18 - 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 *); -unsigned replaywin = 32; -bool localdiscovery = true; -bool udp_discovery = true; -int udp_discovery_keepalive_interval = 10; -int udp_discovery_interval = 2; -int udp_discovery_timeout = 30; +unsigned replaywin = 16; +bool localdiscovery = false; #define MAX_SEQNO 1073741824 -static void try_fix_mtu(node_t *n) { - if(n->mtuprobes < 0) { +/* mtuprobes == 1..30: initial discovery, send bursts with 1 second interval + mtuprobes == 31: sleep pinginterval seconds + mtuprobes == 32: send 1 burst, sleep pingtimeout second + mtuprobes == 33: no response from other side, restart PMTU discovery process + + Probes are sent in batches of at least three, with random sizes between the + lower and upper boundaries for the MTU thus far discovered. + + After the initial discovery, a fourth packet is added to each batch with a + size larger than the currently known PMTU, to test if the PMTU has increased. + + In case local discovery is enabled, another packet is added to each batch, + which will be broadcast to the local network. + +*/ + +void send_mtu_probe(node_t *n) { + vpn_packet_t packet; + int len, i; + int timeout = 1; + + n->mtuprobes++; + n->mtuevent = NULL; + + if(!n->status.reachable || !n->status.validkey) { + ifdebug(TRAFFIC) logger(LOG_INFO, "Trying to send MTU probe to unreachable or rekeying node %s (%s)", n->name, n->hostname); + n->mtuprobes = 0; return; } - if(n->mtuprobes == 20 || n->minmtu >= n->maxmtu) { + if(n->mtuprobes > 32) { + if(!n->minmtu) { + n->mtuprobes = 31; + timeout = pinginterval; + goto end; + } + + ifdebug(TRAFFIC) logger(LOG_INFO, "%s (%s) did not respond to UDP ping, restarting PMTU discovery", n->name, n->hostname); + n->mtuprobes = 1; + n->minmtu = 0; + n->maxmtu = MTU; + } + + if(n->mtuprobes >= 10 && n->mtuprobes < 32 && !n->minmtu) { + ifdebug(TRAFFIC) logger(LOG_INFO, "No response to MTU probes from %s (%s)", n->name, n->hostname); + n->mtuprobes = 31; + } + + if(n->mtuprobes == 30 || (n->mtuprobes < 30 && n->minmtu >= n->maxmtu)) { if(n->minmtu > n->maxmtu) { n->minmtu = n->maxmtu; } else { @@ -88,121 +121,86 @@ static void try_fix_mtu(node_t *n) { } n->mtu = n->minmtu; - logger(DEBUG_TRAFFIC, LOG_INFO, "Fixing MTU of %s (%s) to %d after %d probes", n->name, n->hostname, n->mtu, n->mtuprobes); - n->mtuprobes = -1; - } -} - -static void udp_probe_timeout_handler(void *data) { - node_t *n = data; - - if(!n->status.udp_confirmed) { - return; + ifdebug(TRAFFIC) logger(LOG_INFO, "Fixing MTU of %s (%s) to %d after %d probes", n->name, n->hostname, n->mtu, n->mtuprobes); + n->mtuprobes = 31; } - logger(DEBUG_TRAFFIC, LOG_INFO, "Too much time has elapsed since last UDP ping response from %s (%s), stopping UDP communication", n->name, n->hostname); - n->status.udp_confirmed = false; - n->udp_ping_rtt = -1; - n->maxrecentlen = 0; - n->mtuprobes = 0; - n->minmtu = 0; - n->maxmtu = MTU; -} - -static void send_udp_probe_reply(node_t *n, vpn_packet_t *packet, length_t len) { - if(!n->status.sptps && !n->status.validkey) { - logger(DEBUG_TRAFFIC, LOG_INFO, "Trying to send UDP probe reply to %s (%s) but we don't have his key yet", n->name, n->hostname); - return; + if(n->mtuprobes == 31) { + timeout = pinginterval; + goto end; + } else if(n->mtuprobes == 32) { + timeout = pingtimeout; } - /* Type 2 probe replies were introduced in protocol 17.3 */ - if((n->options >> 24) >= 3) { - DATA(packet)[0] = 2; - uint16_t len16 = htons(len); - memcpy(DATA(packet) + 1, &len16, 2); - packet->len = MIN_PROBE_SIZE; - logger(DEBUG_TRAFFIC, LOG_INFO, "Sending type 2 probe reply length %u to %s (%s)", len, n->name, n->hostname); + for(i = 0; i < 4 + localdiscovery; i++) { + if(i == 0) { + if(n->mtuprobes < 30 || n->maxmtu + 8 >= MTU) { + continue; + } - } else { - /* Legacy protocol: n won't understand type 2 probe replies. */ - DATA(packet)[0] = 1; - logger(DEBUG_TRAFFIC, LOG_INFO, "Sending type 1 probe reply length %u to %s (%s)", len, n->name, n->hostname); - } - - /* Temporarily set udp_confirmed, so that the reply is sent - back exactly the way it came in. */ - - bool udp_confirmed = n->status.udp_confirmed; - n->status.udp_confirmed = true; - send_udppacket(n, packet); - n->status.udp_confirmed = udp_confirmed; -} - -static void udp_probe_h(node_t *n, vpn_packet_t *packet, length_t len) { - if(!DATA(packet)[0]) { - logger(DEBUG_TRAFFIC, LOG_INFO, "Got UDP probe request %d from %s (%s)", packet->len, n->name, n->hostname); - send_udp_probe_reply(n, packet, len); - return; - } - - if(DATA(packet)[0] == 2) { - // It's a type 2 probe reply, use the length field inside the packet - uint16_t len16; - memcpy(&len16, DATA(packet) + 1, 2); - len = ntohs(len16); - } - - if(n->udp_ping_sent.tv_sec != 0) { // a probe in flight - gettimeofday(&now, NULL); - struct timeval rtt; - timersub(&now, &n->udp_ping_sent, &rtt); - n->udp_ping_rtt = rtt.tv_sec * 1000000 + rtt.tv_usec; - logger(DEBUG_TRAFFIC, LOG_INFO, "Got type %d UDP probe reply %d from %s (%s) rtt=%d.%03d", DATA(packet)[0], len, n->name, n->hostname, n->udp_ping_rtt / 1000, n->udp_ping_rtt % 1000); - } else { - logger(DEBUG_TRAFFIC, LOG_INFO, "Got type %d UDP probe reply %d from %s (%s)", DATA(packet)[0], len, n->name, n->hostname); - } - - /* It's a valid reply: now we know bidirectional communication - is possible using the address and socket that the reply - packet used. */ - if(!n->status.udp_confirmed) { - n->status.udp_confirmed = true; - - if(!n->address_cache) { - n->address_cache = open_address_cache(n); + len = n->maxmtu + 8; + } else if(n->maxmtu <= n->minmtu) { + len = n->maxmtu; + } else { + len = n->minmtu + 1 + rand() % (n->maxmtu - n->minmtu); } - reset_address_cache(n->address_cache, &n->address); + if(len < 64) { + len = 64; + } + + memset(packet.data, 0, 14); + RAND_bytes(packet.data + 14, len - 14); + packet.len = len; + + if(i >= 4 && n->mtuprobes <= 10) { + packet.priority = -1; + } else { + packet.priority = 0; + } + + ifdebug(TRAFFIC) logger(LOG_INFO, "Sending MTU probe length %d to %s (%s)", len, n->name, n->hostname); + + send_udppacket(n, &packet); } - // Reset the UDP ping timer. (no probe in flight) - n->udp_ping_sent.tv_sec = 0; +end: + n->mtuevent = new_event(); + n->mtuevent->handler = (event_handler_t)send_mtu_probe; + n->mtuevent->data = n; + n->mtuevent->time = now + timeout; + event_add(n->mtuevent); +} - if(udp_discovery) { - timeout_del(&n->udp_ping_timeout); - timeout_add(&n->udp_ping_timeout, &udp_probe_timeout_handler, n, &(struct timeval) { - udp_discovery_timeout, 0 - }); - } +void mtu_probe_h(node_t *n, vpn_packet_t *packet, length_t len) { + ifdebug(TRAFFIC) logger(LOG_INFO, "Got MTU probe length %d from %s (%s)", packet->len, n->name, n->hostname); - if(len > n->maxmtu) { - logger(DEBUG_TRAFFIC, LOG_INFO, "Increase in PMTU to %s (%s) detected, restarting PMTU discovery", n->name, n->hostname); - n->minmtu = len; - n->maxmtu = MTU; - /* Set mtuprobes to 1 so that try_mtu() doesn't reset maxmtu */ - n->mtuprobes = 1; - return; - } else if(n->mtuprobes < 0 && len == n->maxmtu) { - /* We got a maxmtu sized packet, confirming the PMTU is still valid. */ - n->mtuprobes = -1; - n->mtu_ping_sent = now; - } + if(!packet->data[0]) { + packet->data[0] = 1; + send_udppacket(n, packet); + } else { + if(n->mtuprobes > 30) { + if(len == n->maxmtu + 8) { + ifdebug(TRAFFIC) logger(LOG_INFO, "Increase in PMTU to %s (%s) detected, restarting PMTU discovery", n->name, n->hostname); + n->maxmtu = MTU; + n->mtuprobes = 10; + return; + } - /* If applicable, raise the minimum supported MTU */ + if(n->minmtu) { + n->mtuprobes = 30; + } else { + n->mtuprobes = 1; + } + } - if(n->minmtu < len) { - n->minmtu = len; - try_fix_mtu(n); + if(len > n->maxmtu) { + len = n->maxmtu; + } + + if(n->minmtu < len) { + n->minmtu = len; + } } } @@ -258,22 +256,9 @@ static length_t uncompress_packet(uint8_t *dest, const uint8_t *source, length_t #ifdef HAVE_ZLIB else { unsigned long destlen = MAXSIZE; - static z_stream stream; - if(stream.next_in) { - inflateReset(&stream); - } else { - inflateInit(&stream); - } - - stream.next_in = source; - stream.avail_in = len; - stream.next_out = dest; - stream.avail_out = destlen; - stream.total_out = 0; - - if(inflate(&stream, Z_FINISH) == Z_STREAM_END) { - return stream.total_out; + if(uncompress(dest, &destlen, source, len) == Z_OK) { + return destlen; } else { return 0; } @@ -281,169 +266,124 @@ static length_t uncompress_packet(uint8_t *dest, const uint8_t *source, length_t #endif - return 0; + return -1; } /* VPN packet I/O */ static void receive_packet(node_t *n, vpn_packet_t *packet) { - logger(DEBUG_TRAFFIC, LOG_DEBUG, "Received packet of %d bytes from %s (%s)", - packet->len, n->name, n->hostname); - - n->in_packets++; - n->in_bytes += packet->len; + ifdebug(TRAFFIC) logger(LOG_DEBUG, "Received packet of %d bytes from %s (%s)", + packet->len, n->name, n->hostname); route(n, packet); } -static bool try_mac(node_t *n, const vpn_packet_t *inpkt) { - if(n->status.sptps) { - return sptps_verify_datagram(&n->sptps, DATA(inpkt), inpkt->len); - } +static bool try_mac(const node_t *n, const vpn_packet_t *inpkt) { + unsigned char hmac[EVP_MAX_MD_SIZE]; -#ifdef DISABLE_LEGACY - return false; -#else - - if(!n->status.validkey_in || !digest_active(n->indigest) || (size_t)inpkt->len < sizeof(seqno_t) + digest_length(n->indigest)) { + if(!n->indigest || !n->inmaclength || !n->inkey || inpkt->len < sizeof(inpkt->seqno) + n->inmaclength) { return false; } - return digest_verify(n->indigest, inpkt->data, inpkt->len - digest_length(n->indigest), inpkt->data + inpkt->len - digest_length(n->indigest)); -#endif + HMAC(n->indigest, n->inkey, n->inkeylength, (unsigned char *) &inpkt->seqno, inpkt->len - n->inmaclength, (unsigned char *)hmac, NULL); + + return !memcmp_constant_time(hmac, (char *) &inpkt->seqno + inpkt->len - n->inmaclength, n->inmaclength); } -static bool receive_udppacket(node_t *n, vpn_packet_t *inpkt) { +static void receive_udppacket(node_t *n, vpn_packet_t *inpkt) { vpn_packet_t pkt1, pkt2; vpn_packet_t *pkt[] = { &pkt1, &pkt2, &pkt1, &pkt2 }; int nextpkt = 0; - size_t outlen; - pkt1.offset = DEFAULT_PACKET_OFFSET; - pkt2.offset = DEFAULT_PACKET_OFFSET; + vpn_packet_t *outpkt; + int outlen, outpad; + unsigned char hmac[EVP_MAX_MD_SIZE]; - if(n->status.sptps) { - if(!n->sptps.state) { - if(!n->status.waitingforkey) { - logger(DEBUG_TRAFFIC, LOG_DEBUG, "Got packet from %s (%s) but we haven't exchanged keys yet", n->name, n->hostname); - send_req_key(n); - } else { - logger(DEBUG_TRAFFIC, LOG_DEBUG, "Got packet from %s (%s) but he hasn't got our key yet", n->name, n->hostname); - } - - return false; - } - - n->status.udppacket = true; - bool result = sptps_receive_data(&n->sptps, DATA(inpkt), inpkt->len); - n->status.udppacket = false; - - if(!result) { - /* Uh-oh. It might be that the tunnel is stuck in some corrupted state, - so let's restart SPTPS in case that helps. But don't do that too often - to prevent storms, and because that would make life a little too easy - for external attackers trying to DoS us. */ - if(n->last_req_key < now.tv_sec - 10) { - logger(DEBUG_PROTOCOL, LOG_ERR, "Failed to decode raw TCP packet from %s (%s), restarting SPTPS", n->name, n->hostname); - send_req_key(n); - } - - return false; - } - - return true; - } - -#ifdef DISABLE_LEGACY - return false; -#else - - if(!n->status.validkey_in) { - logger(DEBUG_TRAFFIC, LOG_DEBUG, "Got packet from %s (%s) but he hasn't got our key yet", n->name, n->hostname); - return false; + if(!n->inkey) { + ifdebug(TRAFFIC) logger(LOG_DEBUG, "Got packet from %s (%s) but he hasn't got our key yet", + n->name, n->hostname); + return; } /* Check packet length */ - if((size_t)inpkt->len < sizeof(seqno_t) + digest_length(n->indigest)) { - logger(DEBUG_TRAFFIC, LOG_DEBUG, "Got too short packet from %s (%s)", - n->name, n->hostname); - return false; + if(inpkt->len < sizeof(inpkt->seqno) + n->inmaclength) { + ifdebug(TRAFFIC) logger(LOG_DEBUG, "Got too short packet from %s (%s)", + n->name, n->hostname); + return; } - /* It's a legacy UDP packet, the data starts after the seqno */ - - inpkt->offset += sizeof(seqno_t); - /* Check the message authentication code */ - if(digest_active(n->indigest)) { - inpkt->len -= digest_length(n->indigest); + if(n->indigest && n->inmaclength) { + inpkt->len -= n->inmaclength; + HMAC(n->indigest, n->inkey, n->inkeylength, + (unsigned char *) &inpkt->seqno, inpkt->len, (unsigned char *)hmac, NULL); - if(!digest_verify(n->indigest, SEQNO(inpkt), inpkt->len, SEQNO(inpkt) + inpkt->len)) { - logger(DEBUG_TRAFFIC, LOG_DEBUG, "Got unauthenticated packet from %s (%s)", n->name, n->hostname); - return false; + if(memcmp_constant_time(hmac, (char *) &inpkt->seqno + inpkt->len, n->inmaclength)) { + ifdebug(TRAFFIC) logger(LOG_DEBUG, "Got unauthenticated packet from %s (%s)", + n->name, n->hostname); + return; } } /* Decrypt the packet */ - if(cipher_active(n->incipher)) { - vpn_packet_t *outpkt = pkt[nextpkt++]; - outlen = MAXSIZE; + if(n->incipher) { + outpkt = pkt[nextpkt++]; - if(!cipher_decrypt(n->incipher, SEQNO(inpkt), inpkt->len, SEQNO(outpkt), &outlen, true)) { - logger(DEBUG_TRAFFIC, LOG_DEBUG, "Error decrypting packet from %s (%s)", n->name, n->hostname); - return false; + if(!EVP_DecryptInit_ex(n->inctx, NULL, NULL, NULL, NULL) + || !EVP_DecryptUpdate(n->inctx, (unsigned char *) &outpkt->seqno, &outlen, + (unsigned char *) &inpkt->seqno, inpkt->len) + || !EVP_DecryptFinal_ex(n->inctx, (unsigned char *) &outpkt->seqno + outlen, &outpad)) { + ifdebug(TRAFFIC) logger(LOG_DEBUG, "Error decrypting packet from %s (%s): %s", + n->name, n->hostname, ERR_error_string(ERR_get_error(), NULL)); + return; } - outpkt->len = outlen; + outpkt->len = outlen + outpad; inpkt = outpkt; } /* Check the sequence number */ - seqno_t seqno; - memcpy(&seqno, SEQNO(inpkt), sizeof(seqno)); - seqno = ntohl(seqno); - inpkt->len -= sizeof(seqno); + inpkt->len -= sizeof(inpkt->seqno); + inpkt->seqno = ntohl(inpkt->seqno); if(replaywin) { - if(seqno != n->received_seqno + 1) { - if(seqno >= n->received_seqno + replaywin * 8) { + if(inpkt->seqno != n->received_seqno + 1) { + if(inpkt->seqno >= n->received_seqno + replaywin * 8) { if(n->farfuture++ < replaywin >> 2) { - logger(DEBUG_TRAFFIC, LOG_WARNING, "Packet from %s (%s) is %d seqs in the future, dropped (%u)", - n->name, n->hostname, seqno - n->received_seqno - 1, n->farfuture); - return false; + ifdebug(TRAFFIC) logger(LOG_WARNING, "Packet from %s (%s) is %d seqs in the future, dropped (%u)", + n->name, n->hostname, inpkt->seqno - n->received_seqno - 1, n->farfuture); + return; } - logger(DEBUG_TRAFFIC, LOG_WARNING, "Lost %d packets from %s (%s)", - seqno - n->received_seqno - 1, n->name, n->hostname); + ifdebug(TRAFFIC) logger(LOG_WARNING, "Lost %d packets from %s (%s)", + inpkt->seqno - n->received_seqno - 1, n->name, n->hostname); memset(n->late, 0, replaywin); - } else if(seqno <= n->received_seqno) { - if((n->received_seqno >= replaywin * 8 && seqno <= n->received_seqno - replaywin * 8) || !(n->late[(seqno / 8) % replaywin] & (1 << seqno % 8))) { - logger(DEBUG_TRAFFIC, LOG_WARNING, "Got late or replayed packet from %s (%s), seqno %d, last received %d", - n->name, n->hostname, seqno, n->received_seqno); - return false; + } else if(inpkt->seqno <= n->received_seqno) { + if((n->received_seqno >= replaywin * 8 && inpkt->seqno <= n->received_seqno - replaywin * 8) || !(n->late[(inpkt->seqno / 8) % replaywin] & (1 << inpkt->seqno % 8))) { + ifdebug(TRAFFIC) logger(LOG_WARNING, "Got late or replayed packet from %s (%s), seqno %d, last received %d", + n->name, n->hostname, inpkt->seqno, n->received_seqno); + return; } } else { - for(seqno_t i = n->received_seqno + 1; i < seqno; i++) { + for(uint32_t i = n->received_seqno + 1; i < inpkt->seqno; i++) { n->late[(i / 8) % replaywin] |= 1 << i % 8; } } } n->farfuture = 0; - n->late[(seqno / 8) % replaywin] &= ~(1 << seqno % 8); + n->late[(inpkt->seqno / 8) % replaywin] &= ~(1 << inpkt->seqno % 8); } - if(seqno > n->received_seqno) { - n->received_seqno = seqno; + if(inpkt->seqno > n->received_seqno) { + n->received_seqno = inpkt->seqno; } - n->received++; - if(n->received_seqno > MAX_SEQNO) { - regenerate_key(); + keyexpires = 0; } /* Decompress the packet */ @@ -451,44 +391,32 @@ static bool receive_udppacket(node_t *n, vpn_packet_t *inpkt) { length_t origlen = inpkt->len; if(n->incompression) { - vpn_packet_t *outpkt = pkt[nextpkt++]; + outpkt = pkt[nextpkt++]; - if(!(outpkt->len = uncompress_packet(DATA(outpkt), DATA(inpkt), inpkt->len, n->incompression))) { - logger(DEBUG_TRAFFIC, LOG_ERR, "Error while uncompressing packet from %s (%s)", - n->name, n->hostname); - return false; + if(!(outpkt->len = uncompress_packet(outpkt->data, inpkt->data, inpkt->len, n->incompression))) { + ifdebug(TRAFFIC) logger(LOG_ERR, "Error while uncompressing packet from %s (%s)", + n->name, n->hostname); + return; } inpkt = outpkt; - if(origlen > MTU / 64 + 20) { - origlen -= MTU / 64 + 20; - } else { - origlen = 0; - } - } - - if(inpkt->len > n->maxrecentlen) { - n->maxrecentlen = inpkt->len; + origlen -= MTU / 64 + 20; } inpkt->priority = 0; - if(!DATA(inpkt)[12] && !DATA(inpkt)[13]) { - udp_probe_h(n, inpkt, origlen); + if(!inpkt->data[12] && !inpkt->data[13]) { + mtu_probe_h(n, inpkt, origlen); } else { receive_packet(n, inpkt); } - - return true; -#endif } -void receive_tcppacket(connection_t *c, const char *buffer, size_t len) { +void receive_tcppacket(connection_t *c, const char *buffer, length_t len) { vpn_packet_t outpkt; - outpkt.offset = DEFAULT_PACKET_OFFSET; - if(len > sizeof(outpkt.data) - outpkt.offset) { + if(len > sizeof(outpkt.data)) { return; } @@ -500,244 +428,47 @@ void receive_tcppacket(connection_t *c, const char *buffer, size_t len) { outpkt.priority = -1; } - memcpy(DATA(&outpkt), buffer, len); + memcpy(outpkt.data, buffer, len); receive_packet(c->node, &outpkt); } -bool receive_tcppacket_sptps(connection_t *c, const char *data, size_t len) { - if(len < sizeof(node_id_t) + sizeof(node_id_t)) { - logger(DEBUG_PROTOCOL, LOG_ERR, "Got too short TCP SPTPS packet from %s (%s)", c->name, c->hostname); - return false; - } - - node_t *to = lookup_node_id((node_id_t *)data); - data += sizeof(node_id_t); - len -= sizeof(node_id_t); - - if(!to) { - logger(DEBUG_PROTOCOL, LOG_ERR, "Got TCP SPTPS packet from %s (%s) with unknown destination ID", c->name, c->hostname); - return true; - } - - node_t *from = lookup_node_id((node_id_t *)data); - data += sizeof(node_id_t); - len -= sizeof(node_id_t); - - if(!from) { - logger(DEBUG_PROTOCOL, LOG_ERR, "Got TCP SPTPS packet from %s (%s) with unknown source ID", c->name, c->hostname); - return true; - } - - if(!to->status.reachable) { - /* This can happen in the form of a race condition - if the node just became unreachable. */ - logger(DEBUG_TRAFFIC, LOG_WARNING, "Cannot relay TCP packet from %s (%s) because the destination, %s (%s), is unreachable", from->name, from->hostname, to->name, to->hostname); - return true; - } - - /* Help the sender reach us over UDP. - Note that we only do this if we're the destination or the static relay; - otherwise every hop would initiate its own UDP info message, resulting in elevated chatter. */ - if(to->via == myself) { - send_udp_info(myself, from); - } - - /* If we're not the final recipient, relay the packet. */ - - if(to != myself) { - send_sptps_data(to, from, 0, data, len); - try_tx(to, true); - return true; - } - - /* The packet is for us */ - - if(!sptps_receive_data(&from->sptps, data, len)) { - /* Uh-oh. It might be that the tunnel is stuck in some corrupted state, - so let's restart SPTPS in case that helps. But don't do that too often - to prevent storms. */ - if(from->last_req_key < now.tv_sec - 10) { - logger(DEBUG_PROTOCOL, LOG_ERR, "Failed to decode raw TCP packet from %s (%s), restarting SPTPS", from->name, from->hostname); - send_req_key(from); - } - - return true; - } - - send_mtu_info(myself, from, MTU); - return true; -} - -static void send_sptps_packet(node_t *n, vpn_packet_t *origpkt) { - if(!n->status.validkey && !n->connection) { - return; - } - - uint8_t type = 0; - int offset = 0; - - if((!(DATA(origpkt)[12] | DATA(origpkt)[13])) && (n->sptps.outstate)) { - sptps_send_record(&n->sptps, PKT_PROBE, (char *)DATA(origpkt), origpkt->len); - return; - } - - if(routing_mode == RMODE_ROUTER) { - offset = 14; - } else { - type = PKT_MAC; - } - - if(origpkt->len < offset) { - return; - } - - vpn_packet_t outpkt; - - if(n->outcompression) { - outpkt.offset = 0; - length_t len = compress_packet(DATA(&outpkt) + offset, DATA(origpkt) + offset, origpkt->len - offset, n->outcompression); - - if(!len) { - logger(DEBUG_TRAFFIC, LOG_ERR, "Error while compressing packet to %s (%s)", n->name, n->hostname); - } else if(len < origpkt->len - offset) { - outpkt.len = len + offset; - origpkt = &outpkt; - type |= PKT_COMPRESSED; - } - } - - /* If we have a direct metaconnection to n, and we can't use UDP, then - don't bother with SPTPS and just use a "plaintext" PACKET message. - We don't really care about end-to-end security since we're not - sending the message through any intermediate nodes. */ - if(n->connection && origpkt->len > n->minmtu) { - send_tcppacket(n->connection, origpkt); - } else { - sptps_send_record(&n->sptps, type, DATA(origpkt) + offset, origpkt->len - offset); - } - - return; -} - -static void adapt_socket(const sockaddr_t *sa, int *sock) { - /* Make sure we have a suitable socket for the chosen address */ - if(listen_socket[*sock].sa.sa.sa_family != sa->sa.sa_family) { - for(int i = 0; i < listen_sockets; i++) { - if(listen_socket[i].sa.sa.sa_family == sa->sa.sa_family) { - *sock = i; - break; - } - } - } -} - -static void choose_udp_address(const node_t *n, const sockaddr_t **sa, int *sock) { - /* Latest guess */ - *sa = &n->address; - *sock = n->sock; - - /* If the UDP address is confirmed, use it. */ - if(n->status.udp_confirmed) { - return; - } - - /* Send every third packet to n->address; that could be set - to the node's reflexive UDP address discovered during key - exchange. */ - - static int x = 0; - - if(++x >= 3) { - x = 0; - return; - } - - /* Otherwise, address are found in edges to this node. - So we pick a random edge and a random socket. */ - - int i = 0; - int j = rand() % n->edge_tree->count; - edge_t *candidate = NULL; - - for splay_each(edge_t, e, n->edge_tree) { - if(i++ == j) { - candidate = e->reverse; - break; - } - } - - if(candidate) { - *sa = &candidate->address; - *sock = rand() % listen_sockets; - } - - adapt_socket(*sa, sock); -} - -static void choose_local_address(const node_t *n, const sockaddr_t **sa, int *sock) { - *sa = NULL; - - /* Pick one of the edges from this node at random, then use its local address. */ - - int i = 0; - int j = rand() % n->edge_tree->count; - edge_t *candidate = NULL; - - for splay_each(edge_t, e, n->edge_tree) { - if(i++ == j) { - candidate = e; - break; - } - } - - if(candidate && candidate->local_address.sa.sa_family) { - *sa = &candidate->local_address; - *sock = rand() % listen_sockets; - adapt_socket(*sa, sock); - } -} - static void send_udppacket(node_t *n, vpn_packet_t *origpkt) { vpn_packet_t pkt1, pkt2; vpn_packet_t *pkt[] = { &pkt1, &pkt2, &pkt1, &pkt2 }; vpn_packet_t *inpkt = origpkt; int nextpkt = 0; vpn_packet_t *outpkt; - int origlen = origpkt->len; - size_t outlen; - int origpriority = origpkt->priority; - - pkt1.offset = DEFAULT_PACKET_OFFSET; - pkt2.offset = DEFAULT_PACKET_OFFSET; + int origlen; + int outlen, outpad; + int origpriority; if(!n->status.reachable) { - logger(DEBUG_TRAFFIC, LOG_INFO, "Trying to send UDP packet to unreachable node %s (%s)", n->name, n->hostname); + ifdebug(TRAFFIC) logger(LOG_INFO, "Trying to send UDP packet to unreachable node %s (%s)", n->name, n->hostname); return; } - if(n->status.sptps) { - send_sptps_packet(n, origpkt); - return; - } - -#ifdef DISABLE_LEGACY - return; -#else /* Make sure we have a valid key */ if(!n->status.validkey) { - logger(DEBUG_TRAFFIC, LOG_INFO, - "No valid key known yet for %s (%s), forwarding via TCP", - n->name, n->hostname); + ifdebug(TRAFFIC) logger(LOG_INFO, + "No valid key known yet for %s (%s), forwarding via TCP", + n->name, n->hostname); + + if(n->last_req_key + 10 <= now) { + send_req_key(n); + n->last_req_key = now; + } + send_tcppacket(n->nexthop->connection, origpkt); + return; } - if(n->options & OPTION_PMTU_DISCOVERY && inpkt->len > n->minmtu && (DATA(inpkt)[12] | DATA(inpkt)[13])) { - logger(DEBUG_TRAFFIC, LOG_INFO, - "Packet for %s (%s) larger than minimum MTU, forwarding via %s", - n->name, n->hostname, n != n->nexthop ? n->nexthop->name : "TCP"); + if(n->options & OPTION_PMTU_DISCOVERY && inpkt->len > n->minmtu && (inpkt->data[12] | inpkt->data[13])) { + ifdebug(TRAFFIC) logger(LOG_INFO, + "Packet for %s (%s) larger than minimum MTU, forwarding via %s", + n->name, n->hostname, n != n->nexthop ? n->nexthop->name : "TCP"); if(n != n->nexthop) { send_packet(n->nexthop, origpkt); @@ -748,14 +479,17 @@ static void send_udppacket(node_t *n, vpn_packet_t *origpkt) { return; } + origlen = inpkt->len; + origpriority = inpkt->priority; + /* Compress the packet */ if(n->outcompression) { outpkt = pkt[nextpkt++]; - if(!(outpkt->len = compress_packet(DATA(outpkt), DATA(inpkt), inpkt->len, n->outcompression))) { - logger(DEBUG_TRAFFIC, LOG_ERR, "Error while compressing packet to %s (%s)", - n->name, n->hostname); + if(!(outpkt->len = compress_packet(outpkt->data, inpkt->data, inpkt->len, n->outcompression))) { + ifdebug(TRAFFIC) logger(LOG_ERR, "Error while compressing packet to %s (%s)", + n->name, n->hostname); return; } @@ -764,60 +498,95 @@ static void send_udppacket(node_t *n, vpn_packet_t *origpkt) { /* Add sequence number */ - seqno_t seqno = htonl(++(n->sent_seqno)); - memcpy(SEQNO(inpkt), &seqno, sizeof(seqno)); - inpkt->len += sizeof(seqno); + inpkt->seqno = htonl(++(n->sent_seqno)); + inpkt->len += sizeof(inpkt->seqno); /* Encrypt the packet */ - if(cipher_active(n->outcipher)) { + if(n->outcipher) { outpkt = pkt[nextpkt++]; - outlen = MAXSIZE; - if(!cipher_encrypt(n->outcipher, SEQNO(inpkt), inpkt->len, SEQNO(outpkt), &outlen, true)) { - logger(DEBUG_TRAFFIC, LOG_ERR, "Error while encrypting packet to %s (%s)", n->name, n->hostname); + if(!EVP_EncryptInit_ex(n->outctx, NULL, NULL, NULL, NULL) + || !EVP_EncryptUpdate(n->outctx, (unsigned char *) &outpkt->seqno, &outlen, + (unsigned char *) &inpkt->seqno, inpkt->len) + || !EVP_EncryptFinal_ex(n->outctx, (unsigned char *) &outpkt->seqno + outlen, &outpad)) { + ifdebug(TRAFFIC) logger(LOG_ERR, "Error while encrypting packet to %s (%s): %s", + n->name, n->hostname, ERR_error_string(ERR_get_error(), NULL)); goto end; } - outpkt->len = outlen; + outpkt->len = outlen + outpad; inpkt = outpkt; } /* Add the message authentication code */ - if(digest_active(n->outdigest)) { - if(!digest_create(n->outdigest, SEQNO(inpkt), inpkt->len, SEQNO(inpkt) + inpkt->len)) { - logger(DEBUG_TRAFFIC, LOG_ERR, "Error while encrypting packet to %s (%s)", n->name, n->hostname); - goto end; - } + if(n->outdigest && n->outmaclength) { + HMAC(n->outdigest, n->outkey, n->outkeylength, (unsigned char *) &inpkt->seqno, + inpkt->len, (unsigned char *) &inpkt->seqno + inpkt->len, NULL); + inpkt->len += n->outmaclength; + } - inpkt->len += digest_length(n->outdigest); + /* Determine which socket we have to use */ + + if(n->address.sa.sa_family != listen_socket[n->sock].sa.sa.sa_family) { + for(int sock = 0; sock < listen_sockets; sock++) { + if(n->address.sa.sa_family == listen_socket[sock].sa.sa.sa_family) { + n->sock = sock; + break; + } + } } /* Send the packet */ - const sockaddr_t *sa = NULL; + struct sockaddr *sa; + socklen_t sl; int sock; + sockaddr_t broadcast; - if(n->status.send_locally) { - choose_local_address(n, &sa, &sock); + /* Overloaded use of priority field: -1 means local broadcast */ + + if(origpriority == -1 && n->prevedge) { + sock = rand() % listen_sockets; + memset(&broadcast, 0, sizeof(broadcast)); + + if(listen_socket[sock].sa.sa.sa_family == AF_INET6) { + broadcast.in6.sin6_family = AF_INET6; + broadcast.in6.sin6_addr.s6_addr[0x0] = 0xff; + broadcast.in6.sin6_addr.s6_addr[0x1] = 0x02; + broadcast.in6.sin6_addr.s6_addr[0xf] = 0x01; + broadcast.in6.sin6_port = n->prevedge->address.in.sin_port; + broadcast.in6.sin6_scope_id = listen_socket[sock].sa.in6.sin6_scope_id; + } else { + broadcast.in.sin_family = AF_INET; + broadcast.in.sin_addr.s_addr = -1; + broadcast.in.sin_port = n->prevedge->address.in.sin_port; + } + + sa = &broadcast.sa; + sl = SALEN(broadcast.sa); + } else { + if(origpriority == -1) { + origpriority = 0; + } + + sa = &(n->address.sa); + sl = SALEN(n->address.sa); + sock = n->sock; } - if(!sa) { - choose_udp_address(n, &sa, &sock); - } + if(priorityinheritance && origpriority != listen_socket[n->sock].priority) { + listen_socket[n->sock].priority = origpriority; - if(priorityinheritance && origpriority != listen_socket[sock].priority) { - listen_socket[sock].priority = origpriority; - - switch(sa->sa.sa_family) { + switch(listen_socket[n->sock].sa.sa.sa_family) { #if defined(IP_TOS) case AF_INET: - logger(DEBUG_TRAFFIC, LOG_DEBUG, "Setting IPv4 outgoing packet priority to %d", origpriority); + ifdebug(TRAFFIC) logger(LOG_DEBUG, "Setting IPv4 outgoing packet priority to %d", origpriority); - if(setsockopt(listen_socket[sock].udp.fd, IPPROTO_IP, IP_TOS, (void *)&origpriority, sizeof(origpriority))) { /* SO_PRIORITY doesn't seem to work */ - logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "setsockopt", sockstrerror(sockerrno)); + if(setsockopt(listen_socket[n->sock].udp, IPPROTO_IP, IP_TOS, (void *)&origpriority, sizeof(origpriority))) { /* SO_PRIORITY doesn't seem to work */ + logger(LOG_ERR, "System call `%s' failed: %s", "setsockopt", strerror(errno)); } break; @@ -825,10 +594,10 @@ static void send_udppacket(node_t *n, vpn_packet_t *origpkt) { #if defined(IPV6_TCLASS) case AF_INET6: - logger(DEBUG_TRAFFIC, LOG_DEBUG, "Setting IPv6 outgoing packet priority to %d", origpriority); + ifdebug(TRAFFIC) logger(LOG_DEBUG, "Setting IPv6 outgoing packet priority to %d", origpriority); - if(setsockopt(listen_socket[sock].udp.fd, IPPROTO_IPV6, IPV6_TCLASS, (void *)&origpriority, sizeof(origpriority))) { /* SO_PRIORITY doesn't seem to work */ - logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "setsockopt", sockstrerror(sockerrno)); + if(setsockopt(listen_socket[n->sock].udp, IPPROTO_IPV6, IPV6_TCLASS, (void *)&origpriority, sizeof(origpriority))) { + logger(LOG_ERR, "System call `%s' failed: %s", "setsockopt", strerror(errno)); } break; @@ -839,7 +608,7 @@ static void send_udppacket(node_t *n, vpn_packet_t *origpkt) { } } - if(sendto(listen_socket[sock].udp.fd, (void *)SEQNO(inpkt), inpkt->len, 0, &sa->sa, SALEN(sa->sa)) < 0 && !sockwouldblock(sockerrno)) { + if(sendto(listen_socket[sock].udp, (char *) &inpkt->seqno, inpkt->len, 0, sa, sl) < 0 && !sockwouldblock(sockerrno)) { if(sockmsgsize(sockerrno)) { if(n->maxmtu >= origlen) { n->maxmtu = origlen - 1; @@ -848,663 +617,61 @@ static void send_udppacket(node_t *n, vpn_packet_t *origpkt) { if(n->mtu >= origlen) { n->mtu = origlen - 1; } - - try_fix_mtu(n); } else { - logger(DEBUG_TRAFFIC, LOG_WARNING, "Error sending packet to %s (%s): %s", n->name, n->hostname, sockstrerror(sockerrno)); + ifdebug(TRAFFIC) logger(LOG_WARNING, "Error sending packet to %s (%s): %s", n->name, n->hostname, sockstrerror(sockerrno)); } } end: origpkt->len = origlen; -#endif } -bool send_sptps_data(node_t *to, node_t *from, int type, const void *data, size_t len) { - node_t *relay = (to->via != myself && (type == PKT_PROBE || (len - SPTPS_DATAGRAM_OVERHEAD) <= to->via->minmtu)) ? to->via : to->nexthop; - bool direct = from == myself && to == relay; - bool relay_supported = (relay->options >> 24) >= 4; - bool tcponly = (myself->options | relay->options) & OPTION_TCPONLY; - - /* Send it via TCP if it is a handshake packet, TCPOnly is in use, this is a relay packet that the other node cannot understand, or this packet is larger than the MTU. */ - - if(type == SPTPS_HANDSHAKE || tcponly || (!direct && !relay_supported) || (type != PKT_PROBE && (len - SPTPS_DATAGRAM_OVERHEAD) > relay->minmtu)) { - if(type != SPTPS_HANDSHAKE && (to->nexthop->connection->options >> 24) >= 7) { - char buf[len + sizeof(to->id) + sizeof(from->id)]; - char *buf_ptr = buf; - memcpy(buf_ptr, &to->id, sizeof(to->id)); - buf_ptr += sizeof(to->id); - memcpy(buf_ptr, &from->id, sizeof(from->id)); - buf_ptr += sizeof(from->id); - memcpy(buf_ptr, data, len); - logger(DEBUG_TRAFFIC, LOG_INFO, "Sending packet from %s (%s) to %s (%s) via %s (%s) (TCP)", from->name, from->hostname, to->name, to->hostname, to->nexthop->name, to->nexthop->hostname); - return send_sptps_tcppacket(to->nexthop->connection, buf, sizeof(buf)); - } - - char buf[len * 4 / 3 + 5]; - b64encode(data, buf, len); - - /* If this is a handshake packet, use ANS_KEY instead of REQ_KEY, for two reasons: - - We don't want intermediate nodes to switch to UDP to relay these packets; - - ANS_KEY allows us to learn the reflexive UDP address. */ - if(type == SPTPS_HANDSHAKE) { - to->incompression = myself->incompression; - return send_request(to->nexthop->connection, "%d %s %s %s -1 -1 -1 %d", ANS_KEY, from->name, to->name, buf, to->incompression); - } else { - return send_request(to->nexthop->connection, "%d %s %s %d %s", REQ_KEY, from->name, to->name, SPTPS_PACKET, buf); - } - } - - size_t overhead = 0; - - if(relay_supported) { - overhead += sizeof(to->id) + sizeof(from->id); - } - - char buf[len + overhead]; - char *buf_ptr = buf; - - if(relay_supported) { - if(direct) { - /* Inform the recipient that this packet was sent directly. */ - node_id_t nullid = {0}; - memcpy(buf_ptr, &nullid, sizeof(nullid)); - buf_ptr += sizeof(nullid); - } else { - memcpy(buf_ptr, &to->id, sizeof(to->id)); - buf_ptr += sizeof(to->id); - } - - memcpy(buf_ptr, &from->id, sizeof(from->id)); - buf_ptr += sizeof(from->id); - - } - - /* TODO: if this copy turns out to be a performance concern, change sptps_send_record() to add some "pre-padding" to the buffer and use that instead */ - memcpy(buf_ptr, data, len); - buf_ptr += len; - - const sockaddr_t *sa = NULL; - int sock; - - if(relay->status.send_locally) { - choose_local_address(relay, &sa, &sock); - } - - if(!sa) { - choose_udp_address(relay, &sa, &sock); - } - - logger(DEBUG_TRAFFIC, LOG_INFO, "Sending packet from %s (%s) to %s (%s) via %s (%s) (UDP)", from->name, from->hostname, to->name, to->hostname, relay->name, relay->hostname); - - if(sendto(listen_socket[sock].udp.fd, buf, buf_ptr - buf, 0, &sa->sa, SALEN(sa->sa)) < 0 && !sockwouldblock(sockerrno)) { - if(sockmsgsize(sockerrno)) { - // Compensate for SPTPS overhead - len -= SPTPS_DATAGRAM_OVERHEAD; - - if(relay->maxmtu >= len) { - relay->maxmtu = len - 1; - } - - if(relay->mtu >= len) { - relay->mtu = len - 1; - } - - try_fix_mtu(relay); - } else { - logger(DEBUG_TRAFFIC, LOG_WARNING, "Error sending UDP SPTPS packet to %s (%s): %s", relay->name, relay->hostname, sockstrerror(sockerrno)); - return false; - } - } - - return true; -} - -bool receive_sptps_record(void *handle, uint8_t type, const void *data, uint16_t len) { - node_t *from = handle; - - if(type == SPTPS_HANDSHAKE) { - if(!from->status.validkey) { - from->status.validkey = true; - from->status.waitingforkey = false; - logger(DEBUG_META, LOG_INFO, "SPTPS key exchange with %s (%s) successful", from->name, from->hostname); - } - - return true; - } - - if(len > MTU) { - logger(DEBUG_ALWAYS, LOG_ERR, "Packet from %s (%s) larger than maximum supported size (%d > %d)", from->name, from->hostname, len, MTU); - return false; - } - - vpn_packet_t inpkt; - inpkt.offset = DEFAULT_PACKET_OFFSET; - inpkt.priority = 0; - - if(type == PKT_PROBE) { - if(!from->status.udppacket) { - logger(DEBUG_ALWAYS, LOG_ERR, "Got SPTPS PROBE packet from %s (%s) via TCP", from->name, from->hostname); - return false; - } - - inpkt.len = len; - memcpy(DATA(&inpkt), data, len); - - if(inpkt.len > from->maxrecentlen) { - from->maxrecentlen = inpkt.len; - } - - udp_probe_h(from, &inpkt, len); - return true; - } - - if(type & ~(PKT_COMPRESSED | PKT_MAC)) { - logger(DEBUG_ALWAYS, LOG_ERR, "Unexpected SPTPS record type %d len %d from %s (%s)", type, len, from->name, from->hostname); - return false; - } - - /* Check if we have the headers we need */ - if(routing_mode != RMODE_ROUTER && !(type & PKT_MAC)) { - logger(DEBUG_TRAFFIC, LOG_ERR, "Received packet from %s (%s) without MAC header (maybe Mode is not set correctly)", from->name, from->hostname); - return false; - } else if(routing_mode == RMODE_ROUTER && (type & PKT_MAC)) { - logger(DEBUG_TRAFFIC, LOG_WARNING, "Received packet from %s (%s) with MAC header (maybe Mode is not set correctly)", from->name, from->hostname); - } - - int offset = (type & PKT_MAC) ? 0 : 14; - - if(type & PKT_COMPRESSED) { - length_t ulen = uncompress_packet(DATA(&inpkt) + offset, (const uint8_t *)data, len, from->incompression); - - if(!ulen) { - return false; - } else { - inpkt.len = ulen + offset; - } - - if(inpkt.len > MAXSIZE) { - abort(); - } - } else { - memcpy(DATA(&inpkt) + offset, data, len); - inpkt.len = len + offset; - } - - /* Generate the Ethernet packet type if necessary */ - if(offset) { - switch(DATA(&inpkt)[14] >> 4) { - case 4: - DATA(&inpkt)[12] = 0x08; - DATA(&inpkt)[13] = 0x00; - break; - - case 6: - DATA(&inpkt)[12] = 0x86; - DATA(&inpkt)[13] = 0xDD; - break; - - default: - logger(DEBUG_TRAFFIC, LOG_ERR, - "Unknown IP version %d while reading packet from %s (%s)", - DATA(&inpkt)[14] >> 4, from->name, from->hostname); - return false; - } - } - - if(from->status.udppacket && inpkt.len > from->maxrecentlen) { - from->maxrecentlen = inpkt.len; - } - - receive_packet(from, &inpkt); - return true; -} - -// This function tries to get SPTPS keys, if they aren't already known. -// This function makes no guarantees - it is up to the caller to check the node's state to figure out if the keys are available. -static void try_sptps(node_t *n) { - if(n->status.validkey) { - return; - } - - logger(DEBUG_TRAFFIC, LOG_INFO, "No valid key known yet for %s (%s)", n->name, n->hostname); - - if(!n->status.waitingforkey) { - send_req_key(n); - } else if(n->last_req_key + 10 < now.tv_sec) { - logger(DEBUG_ALWAYS, LOG_DEBUG, "No key from %s after 10 seconds, restarting SPTPS", n->name); - sptps_stop(&n->sptps); - n->status.waitingforkey = false; - send_req_key(n); - } - - return; -} - -static void send_udp_probe_packet(node_t *n, int len) { - vpn_packet_t packet; - packet.offset = DEFAULT_PACKET_OFFSET; - memset(DATA(&packet), 0, 14); - randomize(DATA(&packet) + 14, len - 14); - packet.len = len; - packet.priority = 0; - - logger(DEBUG_TRAFFIC, LOG_INFO, "Sending UDP probe length %d to %s (%s)", len, n->name, n->hostname); - - send_udppacket(n, &packet); -} - -// This function tries to establish a UDP tunnel to a node so that packets can be sent. -// If a tunnel is already established, it makes sure it stays up. -// This function makes no guarantees - it is up to the caller to check the node's state to figure out if UDP is usable. -static void try_udp(node_t *n) { - if(!udp_discovery) { - return; - } - - /* Send gratuitous probe replies to 1.1 nodes. */ - - if((n->options >> 24) >= 3 && n->status.udp_confirmed) { - struct timeval ping_tx_elapsed; - timersub(&now, &n->udp_reply_sent, &ping_tx_elapsed); - - if(ping_tx_elapsed.tv_sec >= udp_discovery_keepalive_interval - 1) { - n->udp_reply_sent = now; - - if(n->maxrecentlen) { - vpn_packet_t pkt; - pkt.len = n->maxrecentlen; - pkt.offset = DEFAULT_PACKET_OFFSET; - memset(DATA(&pkt), 0, 14); - randomize(DATA(&pkt) + 14, MIN_PROBE_SIZE - 14); - send_udp_probe_reply(n, &pkt, pkt.len); - n->maxrecentlen = 0; - } - } - } - - /* Probe request */ - - struct timeval ping_tx_elapsed; - timersub(&now, &n->udp_ping_sent, &ping_tx_elapsed); - - int interval = n->status.udp_confirmed ? udp_discovery_keepalive_interval : udp_discovery_interval; - - if(ping_tx_elapsed.tv_sec >= interval) { - gettimeofday(&now, NULL); - n->udp_ping_sent = now; // a probe in flight - send_udp_probe_packet(n, MIN_PROBE_SIZE); - - if(localdiscovery && !n->status.udp_confirmed && n->prevedge) { - n->status.send_locally = true; - send_udp_probe_packet(n, MIN_PROBE_SIZE); - n->status.send_locally = false; - } - } -} - -static length_t choose_initial_maxmtu(node_t *n) { -#ifdef IP_MTU - - int sock = -1; - - const sockaddr_t *sa = NULL; - int sockindex; - choose_udp_address(n, &sa, &sockindex); - - if(!sa) { - return MTU; - } - - sock = socket(sa->sa.sa_family, SOCK_DGRAM, IPPROTO_UDP); - - if(sock < 0) { - logger(DEBUG_TRAFFIC, LOG_ERR, "Creating MTU assessment socket for %s (%s) failed: %s", n->name, n->hostname, sockstrerror(sockerrno)); - return MTU; - } - - if(connect(sock, &sa->sa, SALEN(sa->sa))) { - logger(DEBUG_TRAFFIC, LOG_ERR, "Connecting MTU assessment socket for %s (%s) failed: %s", n->name, n->hostname, sockstrerror(sockerrno)); - close(sock); - return MTU; - } - - int ip_mtu; - socklen_t ip_mtu_len = sizeof(ip_mtu); - - if(getsockopt(sock, IPPROTO_IP, IP_MTU, &ip_mtu, &ip_mtu_len)) { - logger(DEBUG_TRAFFIC, LOG_ERR, "getsockopt(IP_MTU) on %s (%s) failed: %s", n->name, n->hostname, sockstrerror(sockerrno)); - close(sock); - return MTU; - } - - close(sock); - - /* getsockopt(IP_MTU) returns the MTU of the physical interface. - We need to remove various overheads to get to the tinc MTU. */ - length_t mtu = ip_mtu; - mtu -= (sa->sa.sa_family == AF_INET6) ? sizeof(struct ip6_hdr) : sizeof(struct ip); - mtu -= 8; /* UDP */ - - if(n->status.sptps) { - mtu -= SPTPS_DATAGRAM_OVERHEAD; - - if((n->options >> 24) >= 4) { - mtu -= sizeof(node_id_t) + sizeof(node_id_t); - } - -#ifndef DISABLE_LEGACY - } else { - mtu -= digest_length(n->outdigest); - - /* Now it's tricky. We use CBC mode, so the length of the - encrypted payload must be a multiple of the blocksize. The - sequence number is also part of the encrypted payload, so we - must account for it after correcting for the blocksize. - Furthermore, the padding in the last block must be at least - 1 byte. */ - - length_t blocksize = cipher_blocksize(n->outcipher); - - if(blocksize > 1) { - mtu /= blocksize; - mtu *= blocksize; - mtu--; - } - - mtu -= 4; // seqno -#endif - } - - if(mtu < 512) { - logger(DEBUG_TRAFFIC, LOG_ERR, "getsockopt(IP_MTU) on %s (%s) returned absurdly small value: %d", n->name, n->hostname, ip_mtu); - return MTU; - } - - if(mtu > MTU) { - return MTU; - } - - logger(DEBUG_TRAFFIC, LOG_INFO, "Using system-provided maximum tinc MTU for %s (%s): %hd", n->name, n->hostname, mtu); - return mtu; - -#else - - return MTU; - -#endif -} - -/* This function tries to determines the MTU of a node. - By calling this function repeatedly, n->minmtu will be progressively - increased, and at some point, n->mtu will be fixed to n->minmtu. If the MTU - is already fixed, this function checks if it can be increased. +/* + send a packet to the given vpn ip. */ - -static void try_mtu(node_t *n) { - if(!(n->options & OPTION_PMTU_DISCOVERY)) { - return; - } - - if(udp_discovery && !n->status.udp_confirmed) { - n->maxrecentlen = 0; - n->mtuprobes = 0; - n->minmtu = 0; - n->maxmtu = MTU; - return; - } - - /* mtuprobes == 0..19: initial discovery, send bursts with 1 second interval, mtuprobes++ - mtuprobes == 20: fix MTU, and go to -1 - mtuprobes == -1: send one maxmtu and one maxmtu+1 probe every pinginterval - mtuprobes ==-2..-3: send one maxmtu probe every second - mtuprobes == -4: maxmtu no longer valid, reset minmtu and maxmtu and go to 0 */ - - struct timeval elapsed; - timersub(&now, &n->mtu_ping_sent, &elapsed); - - if(n->mtuprobes >= 0) { - if(n->mtuprobes != 0 && elapsed.tv_sec == 0 && elapsed.tv_usec < 333333) { - return; - } - } else { - if(n->mtuprobes < -1) { - if(elapsed.tv_sec < 1) { - return; - } - } else { - if(elapsed.tv_sec < pinginterval) { - return; - } - } - } - - n->mtu_ping_sent = now; - - try_fix_mtu(n); - - if(n->mtuprobes < -3) { - /* We lost three MTU probes, restart discovery */ - logger(DEBUG_TRAFFIC, LOG_INFO, "Decrease in PMTU to %s (%s) detected, restarting PMTU discovery", n->name, n->hostname); - n->mtuprobes = 0; - n->minmtu = 0; - } - - if(n->mtuprobes < 0) { - /* After the initial discovery, we only send one maxmtu and one - maxmtu+1 probe to detect PMTU increases. */ - send_udp_probe_packet(n, n->maxmtu); - - if(n->mtuprobes == -1 && n->maxmtu + 1 < MTU) { - send_udp_probe_packet(n, n->maxmtu + 1); - } - - n->mtuprobes--; - } else { - /* Before initial discovery begins, set maxmtu to the most likely value. - If it's underestimated, we will correct it after initial discovery. */ - if(n->mtuprobes == 0) { - n->maxmtu = choose_initial_maxmtu(n); - } - - for(;;) { - /* Decreasing the number of probes per cycle might make the algorithm react faster to lost packets, - but it will typically increase convergence time in the no-loss case. */ - const length_t probes_per_cycle = 8; - - /* This magic value was determined using math simulations. - It will result in a 1329-byte first probe, followed (if there was a reply) by a 1407-byte probe. - Since 1407 is just below the range of tinc MTUs over typical networks, - this fine-tuning allows tinc to cover a lot of ground very quickly. - This fine-tuning is only valid for maxmtu = MTU; if maxmtu is smaller, - then it's better to use a multiplier of 1. Indeed, this leads to an interesting scenario - if choose_initial_maxmtu() returns the actual MTU value - it will get confirmed with one single probe. */ - const float multiplier = (n->maxmtu == MTU) ? 0.97 : 1; - - const float cycle_position = probes_per_cycle - (n->mtuprobes % probes_per_cycle) - 1; - const length_t minmtu = MAX(n->minmtu, 512); - const float interval = n->maxmtu - minmtu; - - /* The core of the discovery algorithm is this exponential. - It produces very large probes early in the cycle, and then it very quickly decreases the probe size. - This reflects the fact that in the most difficult cases, we don't get any feedback for probes that - are too large, and therefore we need to concentrate on small offsets so that we can quickly converge - on the precise MTU as we are approaching it. - The last probe of the cycle is always 1 byte in size - this is to make sure we'll get at least one - reply per cycle so that we can make progress. */ - const length_t offset = powf(interval, multiplier * cycle_position / (probes_per_cycle - 1)); - - length_t maxmtu = n->maxmtu; - send_udp_probe_packet(n, minmtu + offset); - - /* If maxmtu changed, it means the probe was rejected by the system because it was too large. - In that case, we recalculate with the new maxmtu and try again. */ - if(n->mtuprobes < 0 || maxmtu == n->maxmtu) { - break; - } - } - - if(n->mtuprobes >= 0) { - n->mtuprobes++; - } - } -} - -/* These functions try to establish a tunnel to a node (or its relay) so that - packets can be sent (e.g. exchange keys). - If a tunnel is already established, it tries to improve it (e.g. by trying - to establish a UDP tunnel instead of TCP). This function makes no - guarantees - it is up to the caller to check the node's state to figure out - if TCP and/or UDP is usable. By calling this function repeatedly, the - tunnel is gradually improved until we hit the wall imposed by the underlying - network environment. It is recommended to call this function every time a - packet is sent (or intended to be sent) to a node, so that the tunnel keeps - improving as packets flow, and then gracefully downgrades itself as it goes - idle. -*/ - -static void try_tx_sptps(node_t *n, bool mtu) { - /* If n is a TCP-only neighbor, we'll only use "cleartext" PACKET - messages anyway, so there's no need for SPTPS at all. */ - - if(n->connection && ((myself->options | n->options) & OPTION_TCPONLY)) { - return; - } - - /* Otherwise, try to do SPTPS authentication with n if necessary. */ - - try_sptps(n); - - /* Do we need to statically relay packets? */ - - node_t *via = (n->via == myself) ? n->nexthop : n->via; - - /* If we do have a static relay, try everything with that one instead, if it supports relaying. */ - - if(via != n) { - if((via->options >> 24) < 4) { - return; - } - - try_tx(via, mtu); - return; - } - - /* Otherwise, try to establish UDP connectivity. */ - - try_udp(n); - - if(mtu) { - try_mtu(n); - } - - /* If we don't have UDP connectivity (yet), we need to use a dynamic relay (nexthop) - while we try to establish direct connectivity. */ - - if(!n->status.udp_confirmed && n != n->nexthop && (n->nexthop->options >> 24) >= 4) { - try_tx(n->nexthop, mtu); - } -} - -static void try_tx_legacy(node_t *n, bool mtu) { - /* Does he have our key? If not, send one. */ - - if(!n->status.validkey_in) { - send_ans_key(n); - } - - /* Check if we already have a key, or request one. */ - - if(!n->status.validkey) { - if(n->last_req_key + 10 <= now.tv_sec) { - send_req_key(n); - n->last_req_key = now.tv_sec; - } - - return; - } - - try_udp(n); - - if(mtu) { - try_mtu(n); - } -} - -void try_tx(node_t *n, bool mtu) { - if(!n->status.reachable) { - return; - } - - if(n->status.sptps) { - try_tx_sptps(n, mtu); - } else { - try_tx_legacy(n, mtu); - } -} - -void send_packet(node_t *n, vpn_packet_t *packet) { - // If it's for myself, write it to the tun/tap device. +void send_packet(const node_t *n, vpn_packet_t *packet) { + node_t *via; if(n == myself) { if(overwrite_mac) { - memcpy(DATA(packet), mymac.x, ETH_ALEN); - // Use an arbitrary fake source address. - memcpy(DATA(packet) + ETH_ALEN, DATA(packet), ETH_ALEN); - DATA(packet)[ETH_ALEN * 2 - 1] ^= 0xFF; + memcpy(packet->data, mymac.x, ETH_ALEN); } - n->out_packets++; - n->out_bytes += packet->len; devops.write(packet); return; } - logger(DEBUG_TRAFFIC, LOG_ERR, "Sending packet of %d bytes to %s (%s)", packet->len, n->name, n->hostname); - - // If the node is not reachable, drop it. + ifdebug(TRAFFIC) logger(LOG_ERR, "Sending packet of %d bytes to %s (%s)", + packet->len, n->name, n->hostname); if(!n->status.reachable) { - logger(DEBUG_TRAFFIC, LOG_INFO, "Node %s (%s) is not reachable", n->name, n->hostname); + ifdebug(TRAFFIC) logger(LOG_INFO, "Node %s (%s) is not reachable", + n->name, n->hostname); return; } - // Keep track of packet statistics. + via = (packet->priority == -1 || n->via == myself) ? n->nexthop : n->via; - n->out_packets++; - n->out_bytes += packet->len; - - // Check if it should be sent as an SPTPS packet. - - if(n->status.sptps) { - send_sptps_packet(n, packet); - try_tx(n, true); - return; - } - - // Determine which node to actually send it to. - - node_t *via = (packet->priority == -1 || n->via == myself) ? n->nexthop : n->via; - - if(via != n) { - logger(DEBUG_TRAFFIC, LOG_INFO, "Sending packet to %s via %s (%s)", n->name, via->name, n->via->hostname); - } - - // Try to send via UDP, unless TCP is forced. + if(via != n) + ifdebug(TRAFFIC) logger(LOG_INFO, "Sending packet to %s via %s (%s)", + n->name, via->name, n->via->hostname); if(packet->priority == -1 || ((myself->options | via->options) & OPTION_TCPONLY)) { if(!send_tcppacket(via->connection, packet)) { terminate_connection(via->connection, true); } - - return; + } else { + send_udppacket(via, packet); } - - send_udppacket(via, packet); - try_tx(via, true); } +/* Broadcast a packet using the minimum spanning tree */ + void broadcast_packet(const node_t *from, vpn_packet_t *packet) { + avl_node_t *node; + connection_t *c; + node_t *n; + // Always give ourself a copy of the packet. if(from != myself) { send_packet(myself, packet); @@ -1516,18 +683,21 @@ void broadcast_packet(const node_t *from, vpn_packet_t *packet) { return; } - logger(DEBUG_TRAFFIC, LOG_INFO, "Broadcasting packet of %d bytes from %s (%s)", - packet->len, from->name, from->hostname); + ifdebug(TRAFFIC) logger(LOG_INFO, "Broadcasting packet of %d bytes from %s (%s)", + packet->len, from->name, from->hostname); switch(broadcast_mode) { // In MST mode, broadcast packets travel via the Minimum Spanning Tree. // This guarantees all nodes receive the broadcast packet, and // usually distributes the sending of broadcast packets over all nodes. case BMODE_MST: - for list_each(connection_t, c, connection_list) - if(c->edge && c->status.mst && c != from->nexthop->connection) { + for(node = connection_tree->head; node; node = node->next) { + c = node->data; + + if(c->status.active && c->status.mst && c != from->nexthop->connection) { send_packet(c->node, packet); } + } break; @@ -1539,10 +709,13 @@ void broadcast_packet(const node_t *from, vpn_packet_t *packet) { break; } - for splay_each(node_t, n, node_tree) + for(node = node_udp_tree->head; node; node = node->next) { + n = node->data; + if(n->status.reachable && n != myself && ((n->via == myself && n->nexthop == n) || n->via == n)) { send_packet(n, packet); } + } break; @@ -1551,271 +724,75 @@ void broadcast_packet(const node_t *from, vpn_packet_t *packet) { } } -/* We got a packet from some IP address, but we don't know who sent it. Try to - verify the message authentication code against all active session keys. - Since this is actually an expensive operation, we only do a full check once - a minute, the rest of the time we only check against nodes for which we know - an IP address that matches the one from the packet. */ - static node_t *try_harder(const sockaddr_t *from, const vpn_packet_t *pkt) { - node_t *match = NULL; - bool hard = false; + avl_node_t *node; + edge_t *e; + node_t *n = NULL; static time_t last_hard_try = 0; - for splay_each(node_t, n, node_tree) { - if(!n->status.reachable || n == myself) { + for(node = edge_weight_tree->head; node; node = node->next) { + e = node->data; + + if(e->to == myself) { continue; } - if(!n->status.validkey_in && !(n->status.sptps && n->sptps.instate)) { + if(last_hard_try == now && sockaddrcmp_noport(from, &e->address)) { continue; } - bool soft = false; - - for splay_each(edge_t, e, n->edge_tree) { - if(!e->reverse) { - continue; - } - - if(!sockaddrcmp_noport(from, &e->reverse->address)) { - soft = true; - break; - } - } - - if(!soft) { - if(last_hard_try == now.tv_sec) { - continue; - } - - hard = true; - } - - if(!try_mac(n, pkt)) { + if(!try_mac(e->to, pkt)) { continue; } - match = n; + n = e->to; break; } - if(hard) { - last_hard_try = now.tv_sec; - } - - return match; + last_hard_try = now; + return n; } -static void handle_incoming_vpn_packet(listen_socket_t *ls, vpn_packet_t *pkt, sockaddr_t *addr) { - char *hostname; - node_id_t nullid = {0}; - node_t *from, *to; - bool direct = false; - - sockaddrunmap(addr); /* Some braindead IPv6 implementations do stupid things. */ - - // Try to figure out who sent this packet. - - node_t *n = lookup_node_udp(addr); - - if(n && !n->status.udp_confirmed) { - n = NULL; // Don't believe it if we don't have confirmation yet. - } - - if(!n) { - // It might be from a 1.1 node, which might have a source ID in the packet. - pkt->offset = 2 * sizeof(node_id_t); - from = lookup_node_id(SRCID(pkt)); - - if(from && !memcmp(DSTID(pkt), &nullid, sizeof(nullid)) && from->status.sptps) { - if(sptps_verify_datagram(&from->sptps, DATA(pkt), pkt->len - 2 * sizeof(node_id_t))) { - n = from; - } else { - goto skip_harder; - } - } - } - - if(!n) { - pkt->offset = 0; - n = try_harder(addr, pkt); - } - -skip_harder: - - if(!n) { - if(debug_level >= DEBUG_PROTOCOL) { - hostname = sockaddr2hostname(addr); - logger(DEBUG_PROTOCOL, LOG_WARNING, "Received UDP packet from unknown source %s", hostname); - free(hostname); - } - - return; - } - - pkt->offset = 0; - - if(n->status.sptps) { - bool relay_enabled = (n->options >> 24) >= 4; - - if(relay_enabled) { - pkt->offset = 2 * sizeof(node_id_t); - pkt->len -= pkt->offset; - } - - if(!memcmp(DSTID(pkt), &nullid, sizeof(nullid)) || !relay_enabled) { - direct = true; - from = n; - to = myself; - } else { - from = lookup_node_id(SRCID(pkt)); - to = lookup_node_id(DSTID(pkt)); - } - - if(!from || !to) { - logger(DEBUG_PROTOCOL, LOG_WARNING, "Received UDP packet from %s (%s) with unknown source and/or destination ID", n->name, n->hostname); - return; - } - - if(!to->status.reachable) { - /* This can happen in the form of a race condition - if the node just became unreachable. */ - logger(DEBUG_TRAFFIC, LOG_WARNING, "Cannot relay packet from %s (%s) because the destination, %s (%s), is unreachable", from->name, from->hostname, to->name, to->hostname); - return; - } - - /* The packet is supposed to come from the originator or its static relay - (i.e. with no dynamic relays in between). - If it did not, "help" the static relay by sending it UDP info. - Note that we only do this if we're the destination or the static relay; - otherwise every hop would initiate its own UDP info message, resulting in elevated chatter. */ - - if(n != from->via && to->via == myself) { - send_udp_info(myself, from); - } - - /* If we're not the final recipient, relay the packet. */ - - if(to != myself) { - send_sptps_data(to, from, 0, DATA(pkt), pkt->len); - try_tx(to, true); - return; - } - } else { - direct = true; - from = n; - } - - if(!receive_udppacket(from, pkt)) { - return; - } - - n->sock = ls - listen_socket; - - if(direct && sockaddrcmp(addr, &n->address)) { - update_node_udp(n, addr); - } - - /* If the packet went through a relay, help the sender find the appropriate MTU - through the relay path. */ - - if(!direct) { - send_mtu_info(myself, n, MTU); - } -} - -void handle_incoming_vpn_data(void *data, int flags) { - (void)data; - (void)flags; - listen_socket_t *ls = data; - -#ifdef HAVE_RECVMMSG -#define MAX_MSG 64 - static int num = MAX_MSG; - static vpn_packet_t pkt[MAX_MSG]; - static sockaddr_t addr[MAX_MSG]; - static struct mmsghdr msg[MAX_MSG]; - static struct iovec iov[MAX_MSG]; - - for(int i = 0; i < num; i++) { - pkt[i].offset = 0; - - iov[i] = (struct iovec) { - .iov_base = DATA(&pkt[i]), - .iov_len = MAXSIZE, - }; - - msg[i].msg_hdr = (struct msghdr) { - .msg_name = &addr[i].sa, - .msg_namelen = sizeof(addr)[i], - .msg_iov = &iov[i], - .msg_iovlen = 1, - }; - } - - num = recvmmsg(ls->udp.fd, msg, MAX_MSG, MSG_DONTWAIT, NULL); - - if(num < 0) { - if(!sockwouldblock(sockerrno)) { - logger(DEBUG_ALWAYS, LOG_ERR, "Receiving packet failed: %s", sockstrerror(sockerrno)); - } - - return; - } - - for(int i = 0; i < num; i++) { - pkt[i].len = msg[i].msg_len; - - if(pkt[i].len <= 0 || pkt[i].len > MAXSIZE) { - continue; - } - - handle_incoming_vpn_packet(ls, &pkt[i], &addr[i]); - } - -#else +void handle_incoming_vpn_data(int sock) { vpn_packet_t pkt; - sockaddr_t addr = {}; - socklen_t addrlen = sizeof(addr); + char *hostname; + sockaddr_t from; + socklen_t fromlen = sizeof(from); + node_t *n; - pkt.offset = 0; - int len = recvfrom(ls->udp.fd, (void *)DATA(&pkt), MAXSIZE, 0, &addr.sa, &addrlen); + ssize_t len = recvfrom(listen_socket[sock].udp, (char *) &pkt.seqno, MAXSIZE, 0, &from.sa, &fromlen); - if(len <= 0 || len > MAXSIZE) { - if(!sockwouldblock(sockerrno)) { - logger(DEBUG_ALWAYS, LOG_ERR, "Receiving packet failed: %s", sockstrerror(sockerrno)); + if(len <= 0 || len > UINT16_MAX) { + if(len >= 0) { + logger(LOG_ERR, "Receiving packet with invalid size"); + } else if(!sockwouldblock(sockerrno)) { + logger(LOG_ERR, "Receiving packet failed: %s", sockstrerror(sockerrno)); } return; } pkt.len = len; + sockaddrunmap(&from); /* Some braindead IPv6 implementations do stupid things. */ - handle_incoming_vpn_packet(ls, &pkt, &addr); -#endif -} + n = lookup_node_udp(&from); -void handle_device_data(void *data, int flags) { - (void)data; - (void)flags; - vpn_packet_t packet; - packet.offset = DEFAULT_PACKET_OFFSET; - packet.priority = 0; - static int errors = 0; + if(!n) { + n = try_harder(&from, &pkt); - if(devops.read(&packet)) { - errors = 0; - myself->in_packets++; - myself->in_bytes += packet.len; - route(myself, &packet); - } else { - usleep(errors * 50000); - errors++; - - if(errors > 10) { - logger(DEBUG_ALWAYS, LOG_ERR, "Too many errors from %s, exiting!", device); - event_exit(); + if(n) { + update_node_udp(n, &from); + } else ifdebug(PROTOCOL) { + hostname = sockaddr2hostname(&from); + logger(LOG_WARNING, "Received UDP packet from unknown source %s", hostname); + free(hostname); + return; + } else { + return; } } + + n->sock = sock; + + receive_udppacket(n, &pkt); } diff --git a/src/net_setup.c b/src/net_setup.c index ed69808..f26007b 100644 --- a/src/net_setup.c +++ b/src/net_setup.c @@ -22,294 +22,220 @@ #include "system.h" -#include "cipher.h" +#include +#include +#include +#include +#include +#include + +#include "avl_tree.h" #include "conf.h" #include "connection.h" -#include "control.h" #include "device.h" -#include "digest.h" -#include "ecdsa.h" +#include "event.h" #include "graph.h" #include "logger.h" -#include "names.h" #include "net.h" #include "netutl.h" #include "process.h" #include "protocol.h" +#include "proxy.h" #include "route.h" -#include "rsa.h" -#include "script.h" #include "subnet.h" #include "utils.h" #include "xalloc.h" -#ifdef HAVE_MINIUPNPC -#include "upnp.h" +char *myport; +devops_t devops; + +#ifndef HAVE_RSA_SET0_KEY +int RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d) { + BN_free(r->n); + r->n = n; + BN_free(r->e); + r->e = e; + BN_free(r->d); + r->d = d; + return 1; +} #endif -char *myport; -static io_t device_io; -devops_t devops; -bool device_standby = false; - -char *proxyhost; -char *proxyport; -char *proxyuser; -char *proxypass; -proxytype_t proxytype; -bool autoconnect; -bool disablebuggypeers; - -char *scriptinterpreter; -char *scriptextension; - -bool node_read_ecdsa_public_key(node_t *n) { - if(ecdsa_active(n->ecdsa)) { - return true; - } - - splay_tree_t *config_tree; - FILE *fp; - char *pubname = NULL; - char *p; - - init_configuration(&config_tree); - - if(!read_host_config(config_tree, n->name, true)) { - goto exit; - } - - /* First, check for simple Ed25519PublicKey statement */ - - if(get_config_string(lookup_config(config_tree, "Ed25519PublicKey"), &p)) { - n->ecdsa = ecdsa_set_base64_public_key(p); - free(p); - goto exit; - } - - /* Else, check for Ed25519PublicKeyFile statement and read it */ - - if(!get_config_string(lookup_config(config_tree, "Ed25519PublicKeyFile"), &pubname)) { - xasprintf(&pubname, "%s" SLASH "hosts" SLASH "%s", confbase, n->name); - } - - fp = fopen(pubname, "r"); - - if(!fp) { - goto exit; - } - - n->ecdsa = ecdsa_read_pem_public_key(fp); - fclose(fp); - -exit: - exit_configuration(&config_tree); - free(pubname); - return n->ecdsa; -} - -bool read_ecdsa_public_key(connection_t *c) { - if(ecdsa_active(c->ecdsa)) { - return true; - } - - FILE *fp; - char *fname; - char *p; - - if(!c->config_tree) { - init_configuration(&c->config_tree); - - if(!read_host_config(c->config_tree, c->name, true)) { - return false; - } - } - - /* First, check for simple Ed25519PublicKey statement */ - - if(get_config_string(lookup_config(c->config_tree, "Ed25519PublicKey"), &p)) { - c->ecdsa = ecdsa_set_base64_public_key(p); - free(p); - return c->ecdsa; - } - - /* Else, check for Ed25519PublicKeyFile statement and read it */ - - if(!get_config_string(lookup_config(c->config_tree, "Ed25519PublicKeyFile"), &fname)) { - xasprintf(&fname, "%s" SLASH "hosts" SLASH "%s", confbase, c->name); - } - - fp = fopen(fname, "r"); - - if(!fp) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error reading Ed25519 public key file `%s': %s", - fname, strerror(errno)); - free(fname); - return false; - } - - c->ecdsa = ecdsa_read_pem_public_key(fp); - - if(!c->ecdsa && errno != ENOENT) { - logger(DEBUG_ALWAYS, LOG_ERR, "Parsing Ed25519 public key file `%s' failed.", fname); - } - - fclose(fp); - free(fname); - return c->ecdsa; -} - -#ifndef DISABLE_LEGACY bool read_rsa_public_key(connection_t *c) { FILE *fp; - char *fname; - char *n; + char *pubname; + char *hcfname; + char *key; + BIGNUM *n = NULL; + BIGNUM *e = NULL; + + if(!c->rsa_key) { + c->rsa_key = RSA_new(); +// RSA_blinding_on(c->rsa_key, NULL); + } /* First, check for simple PublicKey statement */ - if(get_config_string(lookup_config(c->config_tree, "PublicKey"), &n)) { - c->rsa = rsa_set_hex_public_key(n, "FFFF"); - free(n); - return c->rsa; + if(get_config_string(lookup_config(c->config_tree, "PublicKey"), &key)) { + if((size_t)BN_hex2bn(&n, key) != strlen(key)) { + free(key); + logger(LOG_ERR, "Invalid PublicKey for %s!", c->name); + return false; + } + + free(key); + BN_hex2bn(&e, "FFFF"); + + if(!n || !e || RSA_set0_key(c->rsa_key, n, e, NULL) != 1) { + BN_free(e); + BN_free(n); + logger(LOG_ERR, "RSA_set0_key() failed with PublicKey for %s!", c->name); + return false; + } + + return true; } /* Else, check for PublicKeyFile statement and read it */ - if(!get_config_string(lookup_config(c->config_tree, "PublicKeyFile"), &fname)) { - xasprintf(&fname, "%s" SLASH "hosts" SLASH "%s", confbase, c->name); - } + if(get_config_string(lookup_config(c->config_tree, "PublicKeyFile"), &pubname)) { + fp = fopen(pubname, "r"); - fp = fopen(fname, "r"); - - if(!fp) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error reading RSA public key file `%s': %s", fname, strerror(errno)); - free(fname); - return false; - } - - c->rsa = rsa_read_pem_public_key(fp); - fclose(fp); - - if(!c->rsa) { - logger(DEBUG_ALWAYS, LOG_ERR, "Reading RSA public key file `%s' failed: %s", fname, strerror(errno)); - } - - free(fname); - return c->rsa; -} -#endif - -static bool read_ecdsa_private_key(void) { - FILE *fp; - char *fname; - - /* Check for PrivateKeyFile statement and read it */ - - if(!get_config_string(lookup_config(config_tree, "Ed25519PrivateKeyFile"), &fname)) { - xasprintf(&fname, "%s" SLASH "ed25519_key.priv", confbase); - } - - fp = fopen(fname, "r"); - - if(!fp) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error reading Ed25519 private key file `%s': %s", fname, strerror(errno)); - - if(errno == ENOENT) { - logger(DEBUG_ALWAYS, LOG_INFO, "Create an Ed25519 keypair with `tinc -n %s generate-ed25519-keys'.", netname ? netname : "."); - } - - free(fname); - return false; - } - -#if !defined(HAVE_MINGW) && !defined(HAVE_CYGWIN) - struct stat s; - - if(fstat(fileno(fp), &s)) { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not stat Ed25519 private key file `%s': %s'", fname, strerror(errno)); - free(fname); - return false; - } - - if(s.st_mode & ~0100700) { - logger(DEBUG_ALWAYS, LOG_WARNING, "Warning: insecure file permissions for Ed25519 private key file `%s'!", fname); - } - -#endif - - myself->connection->ecdsa = ecdsa_read_pem_private_key(fp); - fclose(fp); - - if(!myself->connection->ecdsa) { - logger(DEBUG_ALWAYS, LOG_ERR, "Reading Ed25519 private key file `%s' failed", fname); - } - - free(fname); - return myself->connection->ecdsa; -} - -static bool read_invitation_key(void) { - FILE *fp; - char fname[PATH_MAX]; - - if(invitation_key) { - ecdsa_free(invitation_key); - invitation_key = NULL; - } - - snprintf(fname, sizeof(fname), "%s" SLASH "invitations" SLASH "ed25519_key.priv", confbase); - - fp = fopen(fname, "r"); - - if(fp) { - invitation_key = ecdsa_read_pem_private_key(fp); - fclose(fp); - - if(!invitation_key) { - logger(DEBUG_ALWAYS, LOG_ERR, "Reading Ed25519 private key file `%s' failed", fname); - } - } - - return invitation_key; -} - -#ifndef DISABLE_LEGACY -static bool read_rsa_private_key(void) { - FILE *fp; - char *fname; - char *n, *d; - - /* First, check for simple PrivateKey statement */ - - if(get_config_string(lookup_config(config_tree, "PrivateKey"), &d)) { - if(!get_config_string(lookup_config(config_tree, "PublicKey"), &n)) { - logger(DEBUG_ALWAYS, LOG_ERR, "PrivateKey used but no PublicKey found!"); - free(d); + if(!fp) { + logger(LOG_ERR, "Error reading RSA public key file `%s': %s", pubname, strerror(errno)); + free(pubname); return false; } - myself->connection->rsa = rsa_set_hex_private_key(n, "FFFF", d); - free(n); - free(d); - return myself->connection->rsa; + c->rsa_key = PEM_read_RSAPublicKey(fp, &c->rsa_key, NULL, NULL); + fclose(fp); + + if(c->rsa_key) { + free(pubname); + return true; /* Woohoo. */ + } + + /* If it fails, try PEM_read_RSA_PUBKEY. */ + fp = fopen(pubname, "r"); + + if(!fp) { + logger(LOG_ERR, "Error reading RSA public key file `%s': %s", pubname, strerror(errno)); + free(pubname); + return false; + } + + c->rsa_key = PEM_read_RSA_PUBKEY(fp, &c->rsa_key, NULL, NULL); + fclose(fp); + + if(c->rsa_key) { +// RSA_blinding_on(c->rsa_key, NULL); + free(pubname); + return true; + } + + logger(LOG_ERR, "Reading RSA public key file `%s' failed: %s", pubname, strerror(errno)); + free(pubname); + return false; } - /* Else, check for PrivateKeyFile statement and read it */ + /* Else, check if a harnessed public key is in the config file */ + + xasprintf(&hcfname, "%s/hosts/%s", confbase, c->name); + fp = fopen(hcfname, "r"); + + if(!fp) { + logger(LOG_ERR, "Error reading RSA public key file `%s': %s", hcfname, strerror(errno)); + free(hcfname); + return false; + } + + c->rsa_key = PEM_read_RSAPublicKey(fp, &c->rsa_key, NULL, NULL); + fclose(fp); + + if(c->rsa_key) { + free(hcfname); + return true; + } + + /* Try again with PEM_read_RSA_PUBKEY. */ + + fp = fopen(hcfname, "r"); + + if(!fp) { + logger(LOG_ERR, "Error reading RSA public key file `%s': %s", hcfname, strerror(errno)); + free(hcfname); + return false; + } + + free(hcfname); + c->rsa_key = PEM_read_RSA_PUBKEY(fp, &c->rsa_key, NULL, NULL); +// RSA_blinding_on(c->rsa_key, NULL); + fclose(fp); + + if(c->rsa_key) { + return true; + } + + logger(LOG_ERR, "No public key for %s specified!", c->name); + + return false; +} + +static bool read_rsa_private_key(void) { + FILE *fp; + char *fname, *key, *pubkey; + BIGNUM *n = NULL; + BIGNUM *e = NULL; + BIGNUM *d = NULL; + + if(get_config_string(lookup_config(config_tree, "PrivateKey"), &key)) { + myself->connection->rsa_key = RSA_new(); + +// RSA_blinding_on(myself->connection->rsa_key, NULL); + if((size_t)BN_hex2bn(&d, key) != strlen(key)) { + logger(LOG_ERR, "Invalid PrivateKey for myself!"); + free(key); + return false; + } + + free(key); + + if(!get_config_string(lookup_config(config_tree, "PublicKey"), &pubkey)) { + BN_free(d); + logger(LOG_ERR, "PrivateKey used but no PublicKey found!"); + return false; + } + + if((size_t)BN_hex2bn(&n, pubkey) != strlen(pubkey)) { + free(pubkey); + BN_free(d); + logger(LOG_ERR, "Invalid PublicKey for myself!"); + return false; + } + + free(pubkey); + BN_hex2bn(&e, "FFFF"); + + if(!n || !e || !d || RSA_set0_key(myself->connection->rsa_key, n, e, d) != 1) { + BN_free(d); + BN_free(e); + BN_free(n); + logger(LOG_ERR, "RSA_set0_key() failed with PrivateKey for myself!"); + return false; + } + + return true; + } if(!get_config_string(lookup_config(config_tree, "PrivateKeyFile"), &fname)) { - xasprintf(&fname, "%s" SLASH "rsa_key.priv", confbase); + xasprintf(&fname, "%s/rsa_key.priv", confbase); } fp = fopen(fname, "r"); if(!fp) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error reading RSA private key file `%s': %s", + logger(LOG_ERR, "Error reading RSA private key file `%s': %s", fname, strerror(errno)); - - if(errno == ENOENT) { - logger(DEBUG_ALWAYS, LOG_INFO, "Create an RSA keypair with `tinc -n %s generate-rsa-keys'.", netname ? netname : "."); - } - free(fname); return false; } @@ -317,58 +243,49 @@ static bool read_rsa_private_key(void) { #if !defined(HAVE_MINGW) && !defined(HAVE_CYGWIN) struct stat s; - if(fstat(fileno(fp), &s)) { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not stat RSA private key file `%s': %s'", fname, strerror(errno)); + if(!fstat(fileno(fp), &s)) { + if(s.st_mode & ~0100700) { + logger(LOG_WARNING, "Warning: insecure file permissions for RSA private key file `%s'!", fname); + } + } else { + logger(LOG_WARNING, "Could not stat RSA private key file `%s': %s'", fname, strerror(errno)); + } + +#endif + + myself->connection->rsa_key = PEM_read_RSAPrivateKey(fp, NULL, NULL, NULL); + fclose(fp); + + if(!myself->connection->rsa_key) { + logger(LOG_ERR, "Reading RSA private key file `%s' failed: %s", + fname, strerror(errno)); free(fname); return false; } - if(s.st_mode & ~0100700) { - logger(DEBUG_ALWAYS, LOG_WARNING, "Warning: insecure file permissions for RSA private key file `%s'!", fname); - } - -#endif - - myself->connection->rsa = rsa_read_pem_private_key(fp); - fclose(fp); - - if(!myself->connection->rsa) { - logger(DEBUG_ALWAYS, LOG_ERR, "Reading RSA private key file `%s' failed: %s", fname, strerror(errno)); - } - free(fname); - return myself->connection->rsa; -} -#endif - -static timeout_t keyexpire_timeout; - -static void keyexpire_handler(void *data) { - regenerate_key(); - timeout_set(data, &(struct timeval) { - keylifetime, rand() % 100000 - }); + return true; } -void regenerate_key(void) { - logger(DEBUG_STATUS, LOG_INFO, "Expiring symmetric keys"); - send_key_changed(); - - for splay_each(node_t, n, node_tree) { - n->status.validkey_in = false; - } -} - -void load_all_nodes(void) { +/* + Read Subnets from all host config files +*/ +void load_all_subnets(void) { DIR *dir; struct dirent *ent; - char dname[PATH_MAX]; + char *dname; + char *fname; + avl_tree_t *config_tree; + config_t *cfg; + subnet_t *s, *s2; + node_t *n; - snprintf(dname, sizeof(dname), "%s" SLASH "hosts", confbase); + xasprintf(&dname, "%s/hosts", confbase); dir = opendir(dname); if(!dir) { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not open %s: %s", dname, strerror(errno)); + logger(LOG_ERR, "Could not open %s: %s", dname, strerror(errno)); + free(dname); return; } @@ -377,12 +294,17 @@ void load_all_nodes(void) { continue; } - node_t *n = lookup_node(ent->d_name); + n = lookup_node(ent->d_name); +#ifdef _DIRENT_HAVE_D_TYPE + //if(ent->d_type != DT_REG) + // continue; +#endif - splay_tree_t *config_tree; + xasprintf(&fname, "%s/hosts/%s", confbase, ent->d_name); init_configuration(&config_tree); read_config_options(config_tree, ent->d_name); - read_host_config(config_tree, ent->d_name, true); + read_config_file(config_tree, fname); + free(fname); if(!n) { n = new_node(); @@ -390,25 +312,16 @@ void load_all_nodes(void) { node_add(n); } - if(strictsubnets) { - for(config_t *cfg = lookup_config(config_tree, "Subnet"); cfg; cfg = lookup_config_next(config_tree, cfg)) { - subnet_t *s, *s2; - - if(!get_config_subnet(cfg, &s)) { - continue; - } - - if((s2 = lookup_subnet(n, s))) { - s2->expires = -1; - free(s); - } else { - subnet_add(n, s); - } + for(cfg = lookup_config(config_tree, "Subnet"); cfg; cfg = lookup_config_next(config_tree, cfg)) { + if(!get_config_subnet(cfg, &s)) { + continue; } - } - if(lookup_config(config_tree, "Address")) { - n->status.has_address = true; + if((s2 = lookup_subnet(n, s))) { + s2->expires = -1; + } else { + subnet_add(n, s); + } } exit_configuration(&config_tree); @@ -419,7 +332,6 @@ void load_all_nodes(void) { char *get_name(void) { char *name = NULL; - char *returned_name; get_config_string(lookup_config(config_tree, "Name"), &name); @@ -427,34 +339,112 @@ char *get_name(void) { return NULL; } - returned_name = replace_name(name); - free(name); - return returned_name; -} + if(*name == '$') { + char *envname = getenv(name + 1); + char hostname[32] = ""; -bool setup_myself_reloadable(void) { - char *proxy = NULL; - char *rmode = NULL; - char *fmode = NULL; - char *bmode = NULL; - char *afname = NULL; - char *space; - bool choice; + if(!envname) { + if(strcmp(name + 1, "HOST")) { + fprintf(stderr, "Invalid Name: environment variable %s does not exist\n", name + 1); + free(name); + return false; + } - free(scriptinterpreter); - scriptinterpreter = NULL; - get_config_string(lookup_config(config_tree, "ScriptsInterpreter"), &scriptinterpreter); + if(gethostname(hostname, sizeof(hostname)) || !*hostname) { + fprintf(stderr, "Could not get hostname: %s\n", strerror(errno)); + free(name); + return false; + } + hostname[31] = 0; + envname = hostname; + } - free(scriptextension); + free(name); + name = xstrdup(envname); - if(!get_config_string(lookup_config(config_tree, "ScriptsExtension"), &scriptextension)) { - scriptextension = xstrdup(""); + for(char *c = name; *c; c++) + if(!isalnum(*c)) { + *c = '_'; + } } - get_config_string(lookup_config(config_tree, "Proxy"), &proxy); + if(!check_id(name)) { + logger(LOG_ERR, "Invalid name for myself!"); + free(name); + return false; + } - if(proxy) { + return name; +} + +/* + Configure node_t myself and set up the local sockets (listen only) +*/ +static bool setup_myself(void) { + config_t *cfg; + subnet_t *subnet; + char *name, *hostname, *mode, *afname, *cipher, *digest, *type; + char *fname = NULL; + char *address = NULL; + char *proxy = NULL; + char *space; + char *envp[5] = {0}; + struct addrinfo *ai, *aip, hint = {0}; + bool choice; + int i, err; + int replaywin_int; + bool port_specified = false; + + myself = new_node(); + myself->connection = new_connection(); + + myself->hostname = xstrdup("MYSELF"); + myself->connection->hostname = xstrdup("MYSELF"); + + myself->connection->options = 0; + myself->connection->protocol_version = PROT_CURRENT; + + if(!(name = get_name())) { + logger(LOG_ERR, "Name for tinc daemon required!"); + return false; + } + + /* Read tinc.conf and our own host config file */ + + myself->name = name; + myself->connection->name = xstrdup(name); + xasprintf(&fname, "%s/hosts/%s", confbase, name); + read_config_options(config_tree, name); + read_config_file(config_tree, fname); + free(fname); + + if(!read_rsa_private_key()) { + return false; + } + + if(!get_config_string(lookup_config(config_tree, "Port"), &myport)) { + myport = xstrdup("655"); + } else { + port_specified = true; + } + + /* Ensure myport is numeric */ + + 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); + } + + if(get_config_string(lookup_config(config_tree, "Proxy"), &proxy)) { if((space = strchr(proxy, ' '))) { *space++ = 0; } @@ -472,7 +462,8 @@ bool setup_myself_reloadable(void) { } else if(!strcasecmp(proxy, "exec")) { proxytype = PROXY_EXEC; } else { - logger(DEBUG_ALWAYS, LOG_ERR, "Unknown proxy type %s!", proxy); + logger(LOG_ERR, "Unknown proxy type %s!", proxy); + free(proxy); return false; } @@ -483,7 +474,8 @@ bool setup_myself_reloadable(void) { case PROXY_EXEC: if(!space || !*space) { - logger(DEBUG_ALWAYS, LOG_ERR, "Argument expected for proxy type exec!"); + logger(LOG_ERR, "Argument expected for proxy type exec!"); + free(proxy); return false; } @@ -509,7 +501,8 @@ bool setup_myself_reloadable(void) { } if(!proxyhost || !*proxyhost || !proxyport || !*proxyport) { - logger(DEBUG_ALWAYS, LOG_ERR, "Host and port argument expected for proxy!"); + logger(LOG_ERR, "Host and port argument expected for proxy!"); + free(proxy); return false; } @@ -530,6 +523,22 @@ bool setup_myself_reloadable(void) { free(proxy); } + /* Read in all the subnets specified in the host configuration file */ + + cfg = lookup_config(config_tree, "Subnet"); + + while(cfg) { + if(!get_config_subnet(cfg, &subnet)) { + return false; + } + + subnet_add(myself, subnet); + + cfg = lookup_config_next(config_tree, cfg); + } + + /* Check some options */ + if(get_config_bool(lookup_config(config_tree, "IndirectData"), &choice) && choice) { myself->options |= OPTION_INDIRECT; } @@ -542,45 +551,42 @@ bool setup_myself_reloadable(void) { myself->options |= OPTION_INDIRECT; } - get_config_bool(lookup_config(config_tree, "UDPDiscovery"), &udp_discovery); - get_config_int(lookup_config(config_tree, "UDPDiscoveryKeepaliveInterval"), &udp_discovery_keepalive_interval); - get_config_int(lookup_config(config_tree, "UDPDiscoveryInterval"), &udp_discovery_interval); - get_config_int(lookup_config(config_tree, "UDPDiscoveryTimeout"), &udp_discovery_timeout); - - get_config_int(lookup_config(config_tree, "MTUInfoInterval"), &mtu_info_interval); - get_config_int(lookup_config(config_tree, "UDPInfoInterval"), &udp_info_interval); - 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); get_config_bool(lookup_config(config_tree, "LocalDiscovery"), &localdiscovery); + strictsubnets |= tunnelserver; - if(get_config_string(lookup_config(config_tree, "Mode"), &rmode)) { - if(!strcasecmp(rmode, "router")) { + if(get_config_string(lookup_config(config_tree, "Mode"), &mode)) { + if(!strcasecmp(mode, "router")) { routing_mode = RMODE_ROUTER; - } else if(!strcasecmp(rmode, "switch")) { + } else if(!strcasecmp(mode, "switch")) { routing_mode = RMODE_SWITCH; - } else if(!strcasecmp(rmode, "hub")) { + } else if(!strcasecmp(mode, "hub")) { routing_mode = RMODE_HUB; } else { - logger(DEBUG_ALWAYS, LOG_ERR, "Invalid routing mode!"); + logger(LOG_ERR, "Invalid routing mode!"); + free(mode); return false; } - free(rmode); + free(mode); } - if(get_config_string(lookup_config(config_tree, "Forwarding"), &fmode)) { - if(!strcasecmp(fmode, "off")) { + if(get_config_string(lookup_config(config_tree, "Forwarding"), &mode)) { + if(!strcasecmp(mode, "off")) { forwarding_mode = FMODE_OFF; - } else if(!strcasecmp(fmode, "internal")) { + } else if(!strcasecmp(mode, "internal")) { forwarding_mode = FMODE_INTERNAL; - } else if(!strcasecmp(fmode, "kernel")) { + } else if(!strcasecmp(mode, "kernel")) { forwarding_mode = FMODE_KERNEL; } else { - logger(DEBUG_ALWAYS, LOG_ERR, "Invalid forwarding mode!"); + logger(LOG_ERR, "Invalid forwarding mode!"); + free(mode); return false; } - free(fmode); + free(mode); } choice = !(myself->options & OPTION_TCPONLY); @@ -600,55 +606,34 @@ bool setup_myself_reloadable(void) { get_config_bool(lookup_config(config_tree, "PriorityInheritance"), &priorityinheritance); get_config_bool(lookup_config(config_tree, "DecrementTTL"), &decrement_ttl); - if(get_config_string(lookup_config(config_tree, "Broadcast"), &bmode)) { - if(!strcasecmp(bmode, "no")) { + if(get_config_string(lookup_config(config_tree, "Broadcast"), &mode)) { + if(!strcasecmp(mode, "no")) { broadcast_mode = BMODE_NONE; - } else if(!strcasecmp(bmode, "yes") || !strcasecmp(bmode, "mst")) { + } else if(!strcasecmp(mode, "yes") || !strcasecmp(mode, "mst")) { broadcast_mode = BMODE_MST; - } else if(!strcasecmp(bmode, "direct")) { + } else if(!strcasecmp(mode, "direct")) { broadcast_mode = BMODE_DIRECT; } else { - logger(DEBUG_ALWAYS, LOG_ERR, "Invalid broadcast mode!"); + logger(LOG_ERR, "Invalid broadcast mode!"); + free(mode); return false; } - free(bmode); + free(mode); } - const char *const DEFAULT_BROADCAST_SUBNETS[] = { "ff:ff:ff:ff:ff:ff", "255.255.255.255", "224.0.0.0/4", "ff00::/8" }; - - for(size_t i = 0; i < sizeof(DEFAULT_BROADCAST_SUBNETS) / sizeof(*DEFAULT_BROADCAST_SUBNETS); i++) { - subnet_t *s = new_subnet(); - - if(!str2net(s, DEFAULT_BROADCAST_SUBNETS[i])) { - abort(); - } - - subnet_add(NULL, s); - } - - for(config_t *cfg = lookup_config(config_tree, "BroadcastSubnet"); cfg; cfg = lookup_config_next(config_tree, cfg)) { - subnet_t *s; - - if(!get_config_subnet(cfg, &s)) { - continue; - } - - subnet_add(NULL, s); - } - -#if !defined(IP_TOS) +#if !defined(SOL_IP) || !defined(IP_TOS) if(priorityinheritance) { - logger(DEBUG_ALWAYS, LOG_WARNING, "%s not supported on this platform for IPv4 connections", "PriorityInheritance"); + logger(LOG_WARNING, "%s not supported on this platform for IPv4 connection", "PriorityInheritance"); } #endif -#if !defined(IPV6_TCLASS) +#if !defined(IPPROTO_IPV6) || !defined(IPV6_TCLASS) if(priorityinheritance) { - logger(DEBUG_ALWAYS, LOG_WARNING, "%s not supported on this platform for IPv6 connections", "PriorityInheritance"); + logger(LOG_WARNING, "%s not supported on this platform for IPv6 connection", "PriorityInheritance"); } #endif @@ -659,13 +644,50 @@ bool setup_myself_reloadable(void) { if(get_config_int(lookup_config(config_tree, "MaxTimeout"), &maxtimeout)) { if(maxtimeout <= 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Bogus maximum timeout!"); + logger(LOG_ERR, "Bogus maximum timeout!"); return false; } } else { maxtimeout = 900; } + if(get_config_int(lookup_config(config_tree, "MinTimeout"), &mintimeout)) { + if(mintimeout < 0) { + logger(LOG_ERR, "Bogus minimum timeout!"); + return false; + } + + if(mintimeout > maxtimeout) { + logger(LOG_WARNING, "Minimum timeout (%d s) cannot be larger than maximum timeout (%d s). Correcting !", mintimeout, maxtimeout); + mintimeout = maxtimeout; + } + } else { + mintimeout = 0; + } + + if(get_config_int(lookup_config(config_tree, "UDPRcvBuf"), &udp_rcvbuf)) { + if(udp_rcvbuf <= 0) { + logger(LOG_ERR, "UDPRcvBuf cannot be negative!"); + return false; + } + } + + if(get_config_int(lookup_config(config_tree, "UDPSndBuf"), &udp_sndbuf)) { + if(udp_sndbuf <= 0) { + logger(LOG_ERR, "UDPSndBuf cannot be negative!"); + return false; + } + } + + if(get_config_int(lookup_config(config_tree, "ReplayWindow"), &replaywin_int)) { + if(replaywin_int < 0) { + logger(LOG_ERR, "ReplayWindow cannot be negative!"); + return false; + } + + replaywin = (unsigned)replaywin_int; + } + if(get_config_string(lookup_config(config_tree, "AddressFamily"), &afname)) { if(!strcasecmp(afname, "IPv4")) { addressfamily = AF_INET; @@ -674,7 +696,8 @@ bool setup_myself_reloadable(void) { } else if(!strcasecmp(afname, "any")) { addressfamily = AF_UNSPEC; } else { - logger(DEBUG_ALWAYS, LOG_ERR, "Invalid address family!"); + logger(LOG_ERR, "Invalid address family!"); + free(afname); return false; } @@ -683,338 +706,99 @@ bool setup_myself_reloadable(void) { get_config_bool(lookup_config(config_tree, "Hostnames"), &hostnames); + /* Generate packet encryption key */ + + if(get_config_string(lookup_config(config_tree, "Cipher"), &cipher)) { + if(!strcasecmp(cipher, "none")) { + myself->incipher = NULL; + } else { + myself->incipher = EVP_get_cipherbyname(cipher); + + if(!myself->incipher) { + logger(LOG_ERR, "Unrecognized cipher type!"); + free(cipher); + return false; + } + } + + free(cipher); + } else { + myself->incipher = EVP_aes_256_cbc(); + } + + if(myself->incipher) { + myself->inkeylength = EVP_CIPHER_key_length(myself->incipher) + EVP_CIPHER_iv_length(myself->incipher); + } else { + myself->inkeylength = 1; + } + + /* We need to use a stream mode for the meta protocol. Use AES for this, + but try to match the key size with the one from the cipher selected + by Cipher. + + If Cipher is set to none, still use a low level of encryption for the + meta protocol. + */ + + int keylen = myself->incipher ? EVP_CIPHER_key_length(myself->incipher) : 0; + + if(keylen <= 16) { + myself->connection->outcipher = EVP_aes_128_cfb(); + } else if(keylen <= 24) { + myself->connection->outcipher = EVP_aes_192_cfb(); + } else { + myself->connection->outcipher = EVP_aes_256_cfb(); + } + if(!get_config_int(lookup_config(config_tree, "KeyExpire"), &keylifetime)) { keylifetime = 3600; } - if(!get_config_bool(lookup_config(config_tree, "AutoConnect"), &autoconnect)) { - autoconnect = true; - } - - get_config_bool(lookup_config(config_tree, "DisableBuggyPeers"), &disablebuggypeers); - - if(!get_config_int(lookup_config(config_tree, "InvitationExpire"), &invitation_lifetime)) { - invitation_lifetime = 604800; // 1 week - } - - read_invitation_key(); - - return true; -} - -/* - Add listening sockets. -*/ -static bool add_listen_address(char *address, bool bindto) { - char *port = myport; - - if(address) { - char *space = strchr(address, ' '); - - if(space) { - *space++ = 0; - port = space; - } - - if(!strcmp(address, "*")) { - *address = 0; - } - } - - struct addrinfo *ai, hint = {0}; - - hint.ai_family = addressfamily; - - hint.ai_socktype = SOCK_STREAM; - - hint.ai_protocol = IPPROTO_TCP; - - hint.ai_flags = AI_PASSIVE; - -#if HAVE_DECL_RES_INIT - res_init(); - -#endif - int err = getaddrinfo(address && *address ? address : NULL, port, &hint, &ai); - - free(address); - - if(err || !ai) { - logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "getaddrinfo", err == EAI_SYSTEM ? strerror(err) : gai_strerror(err)); - return false; - } - - for(struct addrinfo *aip = ai; aip; aip = aip->ai_next) { - // Ignore duplicate addresses - bool found = false; - - for(int i = 0; i < listen_sockets; i++) - if(!memcmp(&listen_socket[i].sa, aip->ai_addr, aip->ai_addrlen)) { - found = true; - break; - } - - if(found) { - continue; - } - - if(listen_sockets >= MAXSOCKETS) { - logger(DEBUG_ALWAYS, LOG_ERR, "Too many listening sockets"); - return false; - } - - int tcp_fd = setup_listen_socket((sockaddr_t *) aip->ai_addr); - - if(tcp_fd < 0) { - continue; - } - - int udp_fd = setup_vpn_in_socket((sockaddr_t *) aip->ai_addr); - - if(udp_fd < 0) { - close(tcp_fd); - continue; - } - - io_add(&listen_socket[listen_sockets].tcp, handle_new_meta_connection, &listen_socket[listen_sockets], tcp_fd, IO_READ); - io_add(&listen_socket[listen_sockets].udp, handle_incoming_vpn_data, &listen_socket[listen_sockets], udp_fd, IO_READ); - - if(debug_level >= DEBUG_CONNECTIONS) { - char *hostname = sockaddr2hostname((sockaddr_t *) aip->ai_addr); - logger(DEBUG_CONNECTIONS, LOG_NOTICE, "Listening on %s", hostname); - free(hostname); - } - - listen_socket[listen_sockets].bindto = bindto; - memcpy(&listen_socket[listen_sockets].sa, aip->ai_addr, aip->ai_addrlen); - listen_sockets++; - } - - freeaddrinfo(ai); - return true; -} - -void device_enable(void) { - if(devops.enable) { - devops.enable(); - } - - /* Run tinc-up script to further initialize the tap interface */ - - environment_t env; - environment_init(&env); - execute_script("tinc-up", &env); - environment_exit(&env); -} - -void device_disable(void) { - environment_t env; - environment_init(&env); - execute_script("tinc-down", &env); - environment_exit(&env); - - if(devops.disable) { - devops.disable(); - } -} - -/* - Configure node_t myself and set up the local sockets (listen only) -*/ -static bool setup_myself(void) { - char *name, *hostname, *cipher, *digest, *type; - char *address = NULL; - bool port_specified = false; - - if(!(name = get_name())) { - logger(DEBUG_ALWAYS, LOG_ERR, "Name for tinc daemon required!"); - return false; - } - - myname = xstrdup(name); - myself = new_node(); - myself->connection = new_connection(); - myself->name = name; - myself->connection->name = xstrdup(name); - read_host_config(config_tree, name, true); - - if(!get_config_string(lookup_config(config_tree, "Port"), &myport)) { - myport = xstrdup("655"); - } else { - port_specified = true; - } - - myself->connection->options = 0; - myself->connection->protocol_major = PROT_MAJOR; - myself->connection->protocol_minor = PROT_MINOR; - - myself->options |= PROT_MINOR << 24; - -#ifdef DISABLE_LEGACY - experimental = read_ecdsa_private_key(); - - if(!experimental) { - logger(DEBUG_ALWAYS, LOG_ERR, "No private key available, cannot start tinc!"); - return false; - } - -#else - - if(!get_config_bool(lookup_config(config_tree, "ExperimentalProtocol"), &experimental)) { - experimental = read_ecdsa_private_key(); - - if(!experimental) { - logger(DEBUG_ALWAYS, LOG_WARNING, "Support for SPTPS disabled."); - } - } else { - if(experimental && !read_ecdsa_private_key()) { - return false; - } - } - - if(!read_rsa_private_key()) { - if(experimental) { - logger(DEBUG_ALWAYS, LOG_WARNING, "Support for legacy protocol disabled."); - } else { - logger(DEBUG_ALWAYS, LOG_ERR, "No private keys available, cannot start tinc!"); - return false; - } - } - -#endif - - /* Ensure myport is numeric */ - - 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); - freeaddrinfo(ai); - sockaddr2str(&sa, NULL, &myport); - } - - /* Read in all the subnets specified in the host configuration file */ - - for(config_t *cfg = lookup_config(config_tree, "Subnet"); cfg; cfg = lookup_config_next(config_tree, cfg)) { - subnet_t *subnet; - - if(!get_config_subnet(cfg, &subnet)) { - return false; - } - - subnet_add(myself, subnet); - } - - /* Check some options */ - - if(!setup_myself_reloadable()) { - return false; - } - - get_config_bool(lookup_config(config_tree, "StrictSubnets"), &strictsubnets); - get_config_bool(lookup_config(config_tree, "TunnelServer"), &tunnelserver); - strictsubnets |= tunnelserver; - - if(get_config_int(lookup_config(config_tree, "MaxConnectionBurst"), &max_connection_burst)) { - if(max_connection_burst <= 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "MaxConnectionBurst cannot be negative!"); - return false; - } - } - - if(get_config_int(lookup_config(config_tree, "UDPRcvBuf"), &udp_rcvbuf)) { - if(udp_rcvbuf < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "UDPRcvBuf cannot be negative!"); - return false; - } - } - - if(get_config_int(lookup_config(config_tree, "UDPSndBuf"), &udp_sndbuf)) { - if(udp_sndbuf < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "UDPSndBuf cannot be negative!"); - return false; - } - } - - get_config_int(lookup_config(config_tree, "FWMark"), &fwmark); -#ifndef SO_MARK - - if(fwmark) { - logger(DEBUG_ALWAYS, LOG_ERR, "FWMark not supported on this platform!"); - return false; - } - -#endif - - int replaywin_int; - - if(get_config_int(lookup_config(config_tree, "ReplayWindow"), &replaywin_int)) { - if(replaywin_int < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "ReplayWindow cannot be negative!"); - return false; - } - - replaywin = (unsigned)replaywin_int; - sptps_replaywin = replaywin; - } - -#ifndef DISABLE_LEGACY - /* Generate packet encryption key */ - - if(!get_config_string(lookup_config(config_tree, "Cipher"), &cipher)) { - cipher = xstrdup("aes-256-cbc"); - } - - if(!strcasecmp(cipher, "none")) { - myself->incipher = NULL; - } else if(!(myself->incipher = cipher_open_by_name(cipher))) { - logger(DEBUG_ALWAYS, LOG_ERR, "Unrecognized cipher type!"); - free(cipher); - return false; - } - - free(cipher); - - timeout_add(&keyexpire_timeout, keyexpire_handler, &keyexpire_timeout, &(struct timeval) { - keylifetime, rand() % 100000 - }); + keyexpires = now + keylifetime; /* Check if we want to use message authentication codes... */ - int maclength = 4; - get_config_int(lookup_config(config_tree, "MACLength"), &maclength); + if(get_config_string(lookup_config(config_tree, "Digest"), &digest)) { + if(!strcasecmp(digest, "none")) { + myself->indigest = NULL; + } else { + myself->indigest = EVP_get_digestbyname(digest); - if(maclength < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Bogus MAC length!"); - return false; - } + if(!myself->indigest) { + logger(LOG_ERR, "Unrecognized digest type!"); + free(digest); + return false; + } + } - if(!get_config_string(lookup_config(config_tree, "Digest"), &digest)) { - digest = xstrdup("sha256"); - } - - if(!strcasecmp(digest, "none")) { - myself->indigest = NULL; - } else if(!(myself->indigest = digest_open_by_name(digest, maclength))) { - logger(DEBUG_ALWAYS, LOG_ERR, "Unrecognized digest type!"); free(digest); - return false; + } else { + myself->indigest = EVP_sha256(); } - free(digest); -#endif + myself->connection->outdigest = EVP_sha256(); + + if(get_config_int(lookup_config(config_tree, "MACLength"), &myself->inmaclength)) { + if(myself->indigest) { + if(myself->inmaclength > EVP_MD_size(myself->indigest)) { + logger(LOG_ERR, "MAC length exceeds size of digest!"); + return false; + } else if(myself->inmaclength < 0) { + logger(LOG_ERR, "Bogus MAC length!"); + return false; + } + } + } else { + myself->inmaclength = 4; + } + + myself->connection->outmaclength = 0; /* Compression */ if(get_config_int(lookup_config(config_tree, "Compression"), &myself->incompression)) { if(myself->incompression < 0 || myself->incompression > 11) { - logger(DEBUG_ALWAYS, LOG_ERR, "Bogus compression level!"); + logger(LOG_ERR, "Bogus compression level!"); return false; } } else { @@ -1028,13 +812,13 @@ static bool setup_myself(void) { myself->nexthop = myself; myself->via = myself; myself->status.reachable = true; - myself->last_state_change = now.tv_sec; - myself->status.sptps = experimental; node_add(myself); graph(); - load_all_nodes(); + if(strictsubnets) { + load_all_subnets(); + } /* Open device */ @@ -1047,8 +831,6 @@ static bool setup_myself(void) { devops = raw_socket_devops; } else if(!strcasecmp(type, "multicast")) { devops = multicast_devops; - } else if(!strcasecmp(type, "fd")) { - devops = fd_devops; } #ifdef ENABLE_UML @@ -1066,16 +848,32 @@ static bool setup_myself(void) { free(type); } - get_config_bool(lookup_config(config_tree, "DeviceStandby"), &device_standby); - if(!devops.setup()) { return false; } - if(device_fd >= 0) { - io_add(&device_io, handle_device_data, NULL, device_fd, IO_READ); + /* Run tinc-up script to further initialize the tap interface */ + xasprintf(&envp[0], "NETNAME=%s", netname ? netname : ""); + xasprintf(&envp[1], "DEVICE=%s", device ? device : ""); + xasprintf(&envp[2], "INTERFACE=%s", iface ? iface : ""); + xasprintf(&envp[3], "NAME=%s", myself->name); + +#ifdef HAVE_MINGW + Sleep(1000); +#endif +#ifdef HAVE_CYGWIN + sleep(1); +#endif + execute_script("tinc-up", envp); + + for(i = 0; i < 4; i++) { + free(envp[i]); } + /* Run subnet-up scripts for our own subnets */ + + subnet_update(myself, NULL, true); + /* Open sockets */ if(!do_detach && getenv("LISTEN_FDS")) { @@ -1088,34 +886,33 @@ static bool setup_myself(void) { #endif if(listen_sockets > MAXSOCKETS) { - logger(DEBUG_ALWAYS, LOG_ERR, "Too many listening sockets"); + logger(LOG_ERR, "Too many listening sockets"); return false; } - for(int i = 0; i < listen_sockets; i++) { + for(i = 0; i < listen_sockets; i++) { salen = sizeof(sa); if(getsockname(i + 3, &sa.sa, &salen) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not get address of listen fd %d: %s", i + 3, sockstrerror(sockerrno)); + logger(LOG_ERR, "Could not get address of listen fd %d: %s", i + 3, sockstrerror(errno)); return false; } + listen_socket[i].tcp = i + 3; + #ifdef FD_CLOEXEC fcntl(i + 3, F_SETFD, FD_CLOEXEC); #endif - int udp_fd = setup_vpn_in_socket(&sa); + listen_socket[i].udp = setup_vpn_in_socket(&sa); - if(udp_fd < 0) { + if(listen_socket[i].udp < 0) { return false; } - io_add(&listen_socket[i].tcp, (io_cb_t)handle_new_meta_connection, &listen_socket[i], i + 3, IO_READ); - io_add(&listen_socket[i].udp, (io_cb_t)handle_incoming_vpn_data, &listen_socket[i], udp_fd, IO_READ); - - if(debug_level >= DEBUG_CONNECTIONS) { + ifdebug(CONNECTIONS) { hostname = sockaddr2hostname(&sa); - logger(DEBUG_CONNECTIONS, LOG_NOTICE, "Listening on %s", hostname); + logger(LOG_NOTICE, "Listening on %s", hostname); free(hostname); } @@ -1123,44 +920,94 @@ static bool setup_myself(void) { } } else { listen_sockets = 0; - int cfgs = 0; + cfg = lookup_config(config_tree, "BindToAddress"); - for(config_t *cfg = lookup_config(config_tree, "BindToAddress"); cfg; cfg = lookup_config_next(config_tree, cfg)) { - cfgs++; + do { get_config_string(cfg, &address); - if(!add_listen_address(address, true)) { + if(cfg) { + cfg = lookup_config_next(config_tree, cfg); + } + + char *port = myport; + + if(address) { + char *space = strchr(address, ' '); + + if(space) { + *space++ = 0; + port = space; + } + + if(!strcmp(address, "*")) { + *address = 0; + } + } + + hint.ai_family = addressfamily; + hint.ai_socktype = SOCK_STREAM; + hint.ai_protocol = IPPROTO_TCP; + hint.ai_flags = AI_PASSIVE; + +#if HAVE_DECL_RES_INIT + // ensure glibc reloads /etc/resolv.conf. + res_init(); +#endif + err = getaddrinfo(address && *address ? address : NULL, port, &hint, &ai); + free(address); + + if(err || !ai) { + logger(LOG_ERR, "System call `%s' failed: %s", "getaddrinfo", + gai_strerror(err)); return false; } - } - for(config_t *cfg = lookup_config(config_tree, "ListenAddress"); cfg; cfg = lookup_config_next(config_tree, cfg)) { - cfgs++; - get_config_string(cfg, &address); + for(aip = ai; aip; aip = aip->ai_next) { + if(listen_sockets >= MAXSOCKETS) { + logger(LOG_ERR, "Too many listening sockets"); + return false; + } - if(!add_listen_address(address, false)) { - return false; + listen_socket[listen_sockets].tcp = + setup_listen_socket((sockaddr_t *) aip->ai_addr); + + if(listen_socket[listen_sockets].tcp < 0) { + continue; + } + + listen_socket[listen_sockets].udp = + setup_vpn_in_socket((sockaddr_t *) aip->ai_addr); + + if(listen_socket[listen_sockets].udp < 0) { + continue; + } + + ifdebug(CONNECTIONS) { + hostname = sockaddr2hostname((sockaddr_t *) aip->ai_addr); + logger(LOG_NOTICE, "Listening on %s", hostname); + free(hostname); + } + + memcpy(&listen_socket[listen_sockets].sa, aip->ai_addr, aip->ai_addrlen); + listen_sockets++; } - } - if(!cfgs) - if(!add_listen_address(address, NULL)) { - return false; - } + freeaddrinfo(ai); + } while(cfg); } if(!listen_sockets) { - logger(DEBUG_ALWAYS, LOG_ERR, "Unable to create any listening socket!"); + logger(LOG_ERR, "Unable to create any listening socket!"); return false; } /* If no Port option was specified, set myport to the port used by the first listening socket. */ - if(!port_specified || atoi(myport) == 0) { + if(!port_specified) { sockaddr_t sa; socklen_t salen = sizeof(sa); - if(!getsockname(listen_socket[0].udp.fd, &sa.sa, &salen)) { + if(!getsockname(listen_socket[0].udp, &sa.sa, &salen)) { free(myport); sockaddr2str(&sa, NULL, &myport); @@ -1170,36 +1017,9 @@ static bool setup_myself(void) { } } - xasprintf(&myself->hostname, "MYSELF port %s", myport); - myself->connection->hostname = xstrdup(myself->hostname); - - char *upnp = NULL; - get_config_string(lookup_config(config_tree, "UPnP"), &upnp); - bool upnp_tcp = false; - bool upnp_udp = false; - - if(upnp) { - if(!strcasecmp(upnp, "yes")) { - upnp_tcp = upnp_udp = true; - } else if(!strcasecmp(upnp, "udponly")) { - upnp_udp = true; - } - - free(upnp); - } - - if(upnp_tcp || upnp_udp) { -#ifdef HAVE_MINIUPNPC - upnp_init(upnp_tcp, upnp_udp); -#else - logger(DEBUG_ALWAYS, LOG_WARNING, "UPnP was requested, but tinc isn't built with miniupnpc support!"); -#endif - } - /* Done. */ - last_config_check = now.tv_sec; - + logger(LOG_NOTICE, "Ready"); return true; } @@ -1207,6 +1027,9 @@ static bool setup_myself(void) { initialize network */ bool setup_network(void) { + now = time(NULL); + + init_events(); init_connections(); init_subnets(); init_nodes(); @@ -1237,18 +1060,6 @@ bool setup_network(void) { return false; } - if(!init_control()) { - return false; - } - - if(!device_standby) { - device_enable(); - } - - /* Run subnet-up scripts for our own subnets */ - - subnet_update(myself, NULL, true); - return true; } @@ -1256,59 +1067,62 @@ bool setup_network(void) { close all open network connections */ void close_network_connections(void) { - for(list_node_t *node = connection_list->head, *next; node; node = next) { + avl_node_t *node, *next; + connection_t *c; + char *envp[5] = {0}; + int i; + + for(node = connection_tree->head; node; node = next) { next = node->next; - connection_t *c = node->data; - - /* Keep control connections open until the end, so they know when we really terminated */ - if(c->status.control) { - c->socket = -1; - } - + c = node->data; c->outgoing = NULL; terminate_connection(c, false); } - if(outgoing_list) { - list_delete_list(outgoing_list); + for(list_node_t *node = outgoing_list->head; node; node = node->next) { + outgoing_t *outgoing = node->data; + + if(outgoing->event) { + event_del(outgoing->event); + } } + list_delete_list(outgoing_list); + if(myself && myself->connection) { subnet_update(myself, NULL, false); - connection_del(myself->connection); + terminate_connection(myself->connection, false); + free_connection(myself->connection); } - for(int i = 0; i < listen_sockets; i++) { - io_del(&listen_socket[i].tcp); - io_del(&listen_socket[i].udp); - close(listen_socket[i].tcp.fd); - close(listen_socket[i].udp.fd); + for(i = 0; i < listen_sockets; i++) { + close(listen_socket[i].tcp); + close(listen_socket[i].udp); } + xasprintf(&envp[0], "NETNAME=%s", netname ? netname : ""); + xasprintf(&envp[1], "DEVICE=%s", device ? device : ""); + xasprintf(&envp[2], "INTERFACE=%s", iface ? iface : ""); + xasprintf(&envp[3], "NAME=%s", myself->name); + exit_requests(); exit_edges(); exit_subnets(); exit_nodes(); exit_connections(); + exit_events(); - if(!device_standby) { - device_disable(); + execute_script("tinc-down", envp); + + if(myport) { + free(myport); } - free(myport); - - if(device_fd >= 0) { - io_del(&device_io); + for(i = 0; i < 4; i++) { + free(envp[i]); } - if(devops.close) { - devops.close(); - } - - exit_control(); - - free(scriptextension); - free(scriptinterpreter); + devops.close(); return; } diff --git a/src/net_socket.c b/src/net_socket.c index dcf8372..6195c16 100644 --- a/src/net_socket.c +++ b/src/net_socket.c @@ -22,33 +22,33 @@ #include "system.h" -#include "address_cache.h" +#include "avl_tree.h" #include "conf.h" #include "connection.h" -#include "control_common.h" -#include "list.h" +#include "event.h" #include "logger.h" #include "meta.h" -#include "names.h" #include "net.h" #include "netutl.h" #include "protocol.h" +#include "proxy.h" #include "utils.h" #include "xalloc.h" +/* Needed on Mac OS/X */ +#ifndef SOL_TCP +#define SOL_TCP IPPROTO_TCP +#endif + int addressfamily = AF_UNSPEC; +int mintimeout = 0; int maxtimeout = 900; int seconds_till_retry = 5; -int udp_rcvbuf = 1024 * 1024; -int udp_sndbuf = 1024 * 1024; -int max_connection_burst = 10; -int fwmark; +int udp_rcvbuf = 0; +int udp_sndbuf = 0; listen_socket_t listen_socket[MAXSOCKETS]; int listen_sockets; -#ifndef HAVE_MINGW -io_t unix_socket; -#endif list_t *outgoing_list = NULL; /* Setup sockets */ @@ -60,21 +60,21 @@ static void configure_tcp(connection_t *c) { int flags = fcntl(c->socket, F_GETFL); if(fcntl(c->socket, F_SETFL, flags | O_NONBLOCK) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "fcntl for %s fd %d: %s", c->hostname, c->socket, strerror(errno)); + logger(LOG_ERR, "fcntl for %s: %s", c->hostname, strerror(errno)); } #elif defined(WIN32) unsigned long arg = 1; if(ioctlsocket(c->socket, FIONBIO, &arg) != 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "ioctlsocket for %s fd %d: %s", c->hostname, c->socket, sockstrerror(sockerrno)); + logger(LOG_ERR, "ioctlsocket for %s: %s", c->hostname, sockstrerror(sockerrno)); } #endif -#if defined(TCP_NODELAY) +#if defined(SOL_TCP) && defined(TCP_NODELAY) option = 1; - setsockopt(c->socket, IPPROTO_TCP, TCP_NODELAY, (void *)&option, sizeof(option)); + setsockopt(c->socket, SOL_TCP, TCP_NODELAY, (void *)&option, sizeof(option)); #endif #if defined(IP_TOS) && defined(IPTOS_LOWDELAY) @@ -86,14 +86,6 @@ static void configure_tcp(connection_t *c) { option = IPTOS_LOWDELAY; setsockopt(c->socket, IPPROTO_IPV6, IPV6_TCLASS, (void *)&option, sizeof(option)); #endif - -#if defined(SO_MARK) - - if(fwmark) { - setsockopt(c->socket, SOL_SOCKET, SO_MARK, (void *)&fwmark, sizeof(fwmark)); - } - -#endif } static bool bind_to_interface(int sd) { @@ -112,57 +104,22 @@ static bool bind_to_interface(int sd) { memset(&ifr, 0, sizeof(ifr)); strncpy(ifr.ifr_ifrn.ifrn_name, iface, IFNAMSIZ); ifr.ifr_ifrn.ifrn_name[IFNAMSIZ - 1] = 0; + free(iface); status = setsockopt(sd, SOL_SOCKET, SO_BINDTODEVICE, (void *)&ifr, sizeof(ifr)); if(status) { - logger(DEBUG_ALWAYS, LOG_ERR, "Can't bind to interface %s: %s", iface, - sockstrerror(sockerrno)); + logger(LOG_ERR, "Can't bind to interface %s: %s", ifr.ifr_ifrn.ifrn_name, strerror(errno)); return false; } #else /* if !defined(SOL_SOCKET) || !defined(SO_BINDTODEVICE) */ - logger(DEBUG_ALWAYS, LOG_WARNING, "%s not supported on this platform", "BindToInterface"); + logger(LOG_WARNING, "%s not supported on this platform", "BindToInterface"); #endif return true; } -static bool bind_to_address(connection_t *c) { - int s = -1; - - for(int i = 0; i < listen_sockets && listen_socket[i].bindto; i++) { - if(listen_socket[i].sa.sa.sa_family != c->address.sa.sa_family) { - continue; - } - - if(s >= 0) { - return false; - } - - s = i; - } - - if(s < 0) { - return false; - } - - sockaddr_t sa = listen_socket[s].sa; - - if(sa.sa.sa_family == AF_INET) { - sa.in.sin_port = 0; - } else if(sa.sa.sa_family == AF_INET6) { - sa.in6.sin6_port = 0; - } - - if(bind(c->socket, &sa.sa, SALEN(sa.sa))) { - logger(DEBUG_CONNECTIONS, LOG_WARNING, "Can't bind outgoing socket: %s", sockstrerror(sockerrno)); - return false; - } - - return true; -} - int setup_listen_socket(const sockaddr_t *sa) { int nfd; char *addrstr; @@ -172,7 +129,7 @@ int setup_listen_socket(const sockaddr_t *sa) { nfd = socket(sa->sa.sa_family, SOCK_STREAM, IPPROTO_TCP); if(nfd < 0) { - logger(DEBUG_STATUS, LOG_ERR, "Creating metasocket failed: %s", sockstrerror(sockerrno)); + ifdebug(STATUS) logger(LOG_ERR, "Creating metasocket failed: %s", sockstrerror(sockerrno)); return -1; } @@ -195,46 +152,37 @@ int setup_listen_socket(const sockaddr_t *sa) { #warning IPV6_V6ONLY not defined #endif -#if defined(SO_MARK) - - if(fwmark) { - setsockopt(nfd, SOL_SOCKET, SO_MARK, (void *)&fwmark, sizeof(fwmark)); - } - -#endif - - if(get_config_string - (lookup_config(config_tree, "BindToInterface"), &iface)) { + if(get_config_string(lookup_config(config_tree, "BindToInterface"), &iface)) { #if defined(SOL_SOCKET) && defined(SO_BINDTODEVICE) struct ifreq ifr; memset(&ifr, 0, sizeof(ifr)); strncpy(ifr.ifr_ifrn.ifrn_name, iface, IFNAMSIZ); ifr.ifr_ifrn.ifrn_name[IFNAMSIZ - 1] = 0; + free(iface); if(setsockopt(nfd, SOL_SOCKET, SO_BINDTODEVICE, (void *)&ifr, sizeof(ifr))) { closesocket(nfd); - logger(DEBUG_ALWAYS, LOG_ERR, "Can't bind to interface %s: %s", iface, - sockstrerror(sockerrno)); + logger(LOG_ERR, "Can't bind to interface %s: %s", ifr.ifr_ifrn.ifrn_name, strerror(sockerrno)); return -1; } #else - logger(DEBUG_ALWAYS, LOG_WARNING, "%s not supported on this platform", "BindToInterface"); + logger(LOG_WARNING, "%s not supported on this platform", "BindToInterface"); #endif } if(bind(nfd, &sa->sa, SALEN(sa->sa))) { closesocket(nfd); addrstr = sockaddr2hostname(sa); - logger(DEBUG_ALWAYS, LOG_ERR, "Can't bind to %s/tcp: %s", addrstr, sockstrerror(sockerrno)); + logger(LOG_ERR, "Can't bind to %s/tcp: %s", addrstr, sockstrerror(sockerrno)); free(addrstr); return -1; } if(listen(nfd, 3)) { closesocket(nfd); - logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "listen", sockstrerror(sockerrno)); + logger(LOG_ERR, "System call `%s' failed: %s", "listen", sockstrerror(sockerrno)); return -1; } @@ -249,7 +197,7 @@ int setup_vpn_in_socket(const sockaddr_t *sa) { nfd = socket(sa->sa.sa_family, SOCK_DGRAM, IPPROTO_UDP); if(nfd < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Creating UDP socket failed: %s", sockstrerror(sockerrno)); + logger(LOG_ERR, "Creating UDP socket failed: %s", sockstrerror(sockerrno)); return -1; } @@ -263,7 +211,7 @@ int setup_vpn_in_socket(const sockaddr_t *sa) { if(fcntl(nfd, F_SETFL, flags | O_NONBLOCK) < 0) { closesocket(nfd); - logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "fcntl", + logger(LOG_ERR, "System call `%s' failed: %s", "fcntl", strerror(errno)); return -1; } @@ -274,7 +222,7 @@ int setup_vpn_in_socket(const sockaddr_t *sa) { if(ioctlsocket(nfd, FIONBIO, &arg) != 0) { closesocket(nfd); - logger(DEBUG_ALWAYS, LOG_ERR, "Call to `%s' failed: %s", "ioctlsocket", sockstrerror(sockerrno)); + logger(LOG_ERR, "Call to `%s' failed: %s", "ioctlsocket", sockstrerror(sockerrno)); return -1; } } @@ -285,11 +233,11 @@ int setup_vpn_in_socket(const sockaddr_t *sa) { setsockopt(nfd, SOL_SOCKET, SO_BROADCAST, (void *)&option, sizeof(option)); if(udp_rcvbuf && setsockopt(nfd, SOL_SOCKET, SO_RCVBUF, (void *)&udp_rcvbuf, sizeof(udp_rcvbuf))) { - logger(DEBUG_ALWAYS, LOG_WARNING, "Can't set UDP SO_RCVBUF to %i: %s", udp_rcvbuf, sockstrerror(sockerrno)); + logger(LOG_WARNING, "Can't set UDP SO_RCVBUF to %i: %s", udp_rcvbuf, strerror(errno)); } if(udp_sndbuf && setsockopt(nfd, SOL_SOCKET, SO_SNDBUF, (void *)&udp_sndbuf, sizeof(udp_sndbuf))) { - logger(DEBUG_ALWAYS, LOG_WARNING, "Can't set UDP SO_SNDBUF to %i: %s", udp_sndbuf, sockstrerror(sockerrno)); + logger(LOG_WARNING, "Can't set UDP SO_SNDBUF to %i: %s", udp_sndbuf, strerror(errno)); } #if defined(IPV6_V6ONLY) @@ -334,14 +282,6 @@ int setup_vpn_in_socket(const sockaddr_t *sa) { setsockopt(nfd, IPPROTO_IPV6, IPV6_DONTFRAG, (void *)&option, sizeof(option)); } -#endif - -#if defined(SO_MARK) - - if(fwmark) { - setsockopt(nfd, SOL_SOCKET, SO_MARK, (void *)&fwmark, sizeof(fwmark)); - } - #endif if(!bind_to_interface(nfd)) { @@ -352,7 +292,7 @@ int setup_vpn_in_socket(const sockaddr_t *sa) { if(bind(nfd, &sa->sa, SALEN(sa->sa))) { closesocket(nfd); addrstr = sockaddr2hostname(sa); - logger(DEBUG_ALWAYS, LOG_ERR, "Can't bind to %s/udp: %s", addrstr, sockstrerror(sockerrno)); + logger(LOG_ERR, "Can't bind to %s/udp: %s", addrstr, sockstrerror(sockerrno)); free(addrstr); return -1; } @@ -360,29 +300,36 @@ int setup_vpn_in_socket(const sockaddr_t *sa) { return nfd; } /* int setup_vpn_in_socket */ -static void retry_outgoing_handler(void *data) { - setup_outgoing_connection(data, true); -} - void retry_outgoing(outgoing_t *outgoing) { outgoing->timeout += 5; + if(outgoing->timeout < mintimeout) { + outgoing->timeout = mintimeout; + } + if(outgoing->timeout > maxtimeout) { outgoing->timeout = maxtimeout; } - timeout_add(&outgoing->ev, retry_outgoing_handler, outgoing, &(struct timeval) { - outgoing->timeout, rand() % 100000 - }); + if(outgoing->event) { + event_del(outgoing->event); + } - logger(DEBUG_CONNECTIONS, LOG_NOTICE, "Trying to re-establish outgoing connection in %d seconds", outgoing->timeout); + outgoing->event = new_event(); + outgoing->event->handler = (event_handler_t) setup_outgoing_connection; + outgoing->event->time = now + outgoing->timeout; + outgoing->event->data = outgoing; + event_add(outgoing->event); + + ifdebug(CONNECTIONS) logger(LOG_NOTICE, + "Trying to re-establish outgoing connection in %d seconds", + outgoing->timeout); } void finish_connecting(connection_t *c) { - logger(DEBUG_CONNECTIONS, LOG_INFO, "Connected to %s (%s)", c->name, c->hostname); + ifdebug(CONNECTIONS) logger(LOG_INFO, "Connected to %s (%s)", c->name, c->hostname); - c->last_ping_time = now.tv_sec; - c->status.connecting = false; + c->last_ping_time = now; send_id(c); } @@ -392,14 +339,14 @@ static void do_outgoing_pipe(connection_t *c, char *command) { int fd[2]; if(socketpair(AF_UNIX, SOCK_STREAM, 0, fd)) { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not create socketpair: %s", sockstrerror(sockerrno)); + logger(LOG_ERR, "Could not create socketpair: %s\n", strerror(errno)); return; } if(fork()) { c->socket = fd[0]; close(fd[1]); - logger(DEBUG_CONNECTIONS, LOG_DEBUG, "Using proxy %s", command); + ifdebug(CONNECTIONS) logger(LOG_DEBUG, "Using proxy %s", command); return; } @@ -428,141 +375,137 @@ static void do_outgoing_pipe(connection_t *c, char *command) { int result = system(command); if(result < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not execute %s: %s", command, strerror(errno)); + logger(LOG_ERR, "Could not execute %s: %s\n", command, strerror(errno)); } else if(result) { - logger(DEBUG_ALWAYS, LOG_ERR, "%s exited with non-zero status %d", command, result); + logger(LOG_ERR, "%s exited with non-zero status %d", command, result); } exit(result); #else - logger(DEBUG_ALWAYS, LOG_ERR, "Proxy type exec not supported on this platform!"); + logger(LOG_ERR, "Proxy type exec not supported on this platform!"); return; #endif } -static void handle_meta_write(connection_t *c) { - if(c->outbuf.len <= c->outbuf.offset) { - return; - } - - ssize_t outlen = send(c->socket, c->outbuf.data + c->outbuf.offset, c->outbuf.len - c->outbuf.offset, 0); - - if(outlen <= 0) { - if(!sockerrno || sockerrno == EPIPE) { - logger(DEBUG_CONNECTIONS, LOG_NOTICE, "Connection closed by %s (%s)", c->name, c->hostname); - } else if(sockwouldblock(sockerrno)) { - logger(DEBUG_META, LOG_DEBUG, "Sending %d bytes to %s (%s) would block", c->outbuf.len - c->outbuf.offset, c->name, c->hostname); - return; - } else { - logger(DEBUG_CONNECTIONS, LOG_ERR, "Could not send %d bytes of data to %s (%s): %s", c->outbuf.len - c->outbuf.offset, c->name, c->hostname, sockstrerror(sockerrno)); +static bool is_valid_host_port(const char *host, const char *port) { + for(const char *p = host; *p; p++) + if(!isalnum(*p) && *p != '-' && *p != '.') { + return false; } - terminate_connection(c, c->edge); - return; - } - - buffer_read(&c->outbuf, outlen); - - if(!c->outbuf.len) { - io_set(&c->io, IO_READ); - } -} - -static void handle_meta_io(void *data, int flags) { - connection_t *c = data; - - if(c->status.connecting) { - /* - The event loop does not protect against spurious events. Verify that we are actually connected - by issuing an empty send() call. - - Note that the behavior of send() on potentially unconnected sockets differ between platforms: - +------------+-----------+-------------+-----------+ - | Event | POSIX | Linux | Windows | - +------------+-----------+-------------+-----------+ - | Spurious | ENOTCONN | EWOULDBLOCK | ENOTCONN | - | Failed | ENOTCONN | (cause) | ENOTCONN | - | Successful | (success) | (success) | (success) | - +------------+-----------+-------------+-----------+ - */ - if(send(c->socket, NULL, 0, 0) != 0) { - if(sockwouldblock(sockerrno)) { - return; - } - - int socket_error; - - if(!socknotconn(sockerrno)) { - socket_error = sockerrno; - } else { - socklen_t len = sizeof(socket_error); - getsockopt(c->socket, SOL_SOCKET, SO_ERROR, (void *)&socket_error, &len); - } - - if(socket_error) { - logger(DEBUG_CONNECTIONS, LOG_DEBUG, "Error while connecting to %s (%s): %s", c->name, c->hostname, sockstrerror(socket_error)); - terminate_connection(c, false); - } - - return; + for(const char *p = port; *p; p++) + if(!isalnum(*p)) { + return false; } - c->status.connecting = false; - finish_connecting(c); - } - - if(flags & IO_WRITE) { - handle_meta_write(c); - } else { - handle_meta_connection_data(c); - } + return true; } -bool do_outgoing_connection(outgoing_t *outgoing) { - const sockaddr_t *sa; +void do_outgoing_connection(connection_t *c) { struct addrinfo *proxyai = NULL; int result; -begin: - sa = get_recent_address(outgoing->address_cache); - - if(!sa) { - logger(DEBUG_CONNECTIONS, LOG_ERR, "Could not set up a meta connection to %s", outgoing->node->name); - retry_outgoing(outgoing); - return false; + if(!c->outgoing) { + logger(LOG_ERR, "do_outgoing_connection() for %s called without c->outgoing", c->name); + abort(); + } + +begin: + + if(!c->outgoing->ai) { + if(!c->outgoing->cfg) { + ifdebug(CONNECTIONS) logger(LOG_ERR, "Could not set up a meta connection to %s", + c->name); + c->status.remove = true; + retry_outgoing(c->outgoing); + c->outgoing = NULL; + return; + } + + char *address, *port, *space; + + get_config_string(c->outgoing->cfg, &address); + + 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); + + // If we cannot resolve the address, maybe we are using a proxy that can? + if(!c->outgoing->ai && proxytype != PROXY_NONE && is_valid_host_port(address, port)) { + memset(&c->address, 0, sizeof(c->address)); + c->address.sa.sa_family = AF_UNKNOWN; + c->address.unknown.address = address; + c->address.unknown.port = port; + } else { + free(address); + free(port); + } + + c->outgoing->aip = c->outgoing->ai; + c->outgoing->cfg = lookup_config_next(c->config_tree, c->outgoing->cfg); + + if(!c->outgoing->ai && proxytype != PROXY_NONE) { + goto connect; + } + } + + if(!c->outgoing->aip) { + if(c->outgoing->ai) { + freeaddrinfo(c->outgoing->ai); + } + + c->outgoing->ai = NULL; + goto begin; + } + + memcpy(&c->address, c->outgoing->aip->ai_addr, c->outgoing->aip->ai_addrlen); + c->outgoing->aip = c->outgoing->aip->ai_next; + +connect: + + if(c->hostname) { + free(c->hostname); } - connection_t *c = new_connection(); - c->outgoing = outgoing; - memcpy(&c->address, sa, SALEN(sa->sa)); c->hostname = sockaddr2hostname(&c->address); - logger(DEBUG_CONNECTIONS, LOG_INFO, "Trying to connect to %s (%s)", outgoing->node->name, c->hostname); + ifdebug(CONNECTIONS) logger(LOG_INFO, "Trying to connect to %s (%s)", c->name, + c->hostname); if(!proxytype) { c->socket = socket(c->address.sa.sa_family, SOCK_STREAM, IPPROTO_TCP); - configure_tcp(c); } else if(proxytype == PROXY_EXEC) { + c->status.proxy_passed = true; do_outgoing_pipe(c, proxyhost); } else { proxyai = str2addrinfo(proxyhost, proxyport, SOCK_STREAM); if(!proxyai) { - free_connection(c); goto begin; } - logger(DEBUG_CONNECTIONS, LOG_INFO, "Using proxy at %s port %s", proxyhost, proxyport); + ifdebug(CONNECTIONS) logger(LOG_INFO, "Using proxy at %s port %s", proxyhost, proxyport); c->socket = socket(proxyai->ai_family, SOCK_STREAM, IPPROTO_TCP); - configure_tcp(c); } if(c->socket == -1) { - logger(DEBUG_CONNECTIONS, LOG_ERR, "Creating socket for %s failed: %s", c->hostname, sockstrerror(sockerrno)); - free_connection(c); + ifdebug(CONNECTIONS) logger(LOG_ERR, "Creating socket for %s failed: %s", c->hostname, sockstrerror(sockerrno)); goto begin; } + if(proxytype != PROXY_EXEC) { + configure_tcp(c); + } + #ifdef FD_CLOEXEC fcntl(c->socket, F_SETFD, FD_CLOEXEC); #endif @@ -578,7 +521,35 @@ begin: #endif bind_to_interface(c->socket); - bind_to_address(c); + + int b = -1; + + for(int i = 0; i < listen_sockets; i++) { + if(listen_socket[i].sa.sa.sa_family == c->address.sa.sa_family) { + if(b == -1) { + b = i; + } else { + b = -1; + break; + } + } + } + + if(b != -1) { + sockaddr_t sa = listen_socket[b].sa; + + if(sa.sa.sa_family == AF_INET) { + sa.in.sin_port = 0; + } else if(sa.sa.sa_family == AF_INET6) { + sa.in6.sin6_port = 0; + } + + if(bind(c->socket, &sa.sa, SALEN(sa.sa))) { + char *addrstr = sockaddr2hostname(&sa); + logger(LOG_ERR, "Can't bind to %s/tcp: %s", addrstr, sockstrerror(sockerrno)); + free(addrstr); + } + } } /* Connect */ @@ -588,280 +559,175 @@ begin: } else if(proxytype == PROXY_EXEC) { result = 0; } else { - if(!proxyai) { - abort(); - } - result = connect(c->socket, proxyai->ai_addr, proxyai->ai_addrlen); freeaddrinfo(proxyai); } - if(result == -1 && !sockinprogress(sockerrno)) { - logger(DEBUG_CONNECTIONS, LOG_ERR, "Could not connect to %s (%s): %s", outgoing->node->name, c->hostname, sockstrerror(sockerrno)); - free_connection(c); + now = time(NULL); + + if(result == -1) { + if(sockinprogress(sockerrno)) { + c->last_ping_time = now; + c->status.connecting = true; + return; + } + + closesocket(c->socket); + + ifdebug(CONNECTIONS) logger(LOG_ERR, "%s: %s", c->hostname, sockstrerror(sockerrno)); goto begin; } - /* Now that there is a working socket, fill in the rest and register this connection. */ + finish_connecting(c); - c->last_ping_time = time(NULL); - c->status.connecting = true; - c->name = xstrdup(outgoing->node->name); -#ifndef DISABLE_LEGACY + return; +} + +void setup_outgoing_connection(outgoing_t *outgoing) { + connection_t *c; + node_t *n; + + outgoing->event = NULL; + + n = lookup_node(outgoing->name); + + if(n) + if(n->connection) { + ifdebug(CONNECTIONS) logger(LOG_INFO, "Already connected to %s", outgoing->name); + + n->connection->outgoing = outgoing; + return; + } + + c = new_connection(); + c->name = xstrdup(outgoing->name); c->outcipher = myself->connection->outcipher; c->outdigest = myself->connection->outdigest; -#endif c->outmaclength = myself->connection->outmaclength; c->outcompression = myself->connection->outcompression; - c->last_ping_time = now.tv_sec; + + init_configuration(&c->config_tree); + + if(!read_connection_config(c)) { + free_connection(c); + outgoing->timeout = maxtimeout; + retry_outgoing(outgoing); + return; + } + + outgoing->cfg = lookup_config(c->config_tree, "Address"); + + if(!outgoing->cfg) { + logger(LOG_ERR, "No address specified for %s", c->name); + free_connection(c); + outgoing->timeout = maxtimeout; + retry_outgoing(outgoing); + return; + } + + c->outgoing = outgoing; + c->last_ping_time = now; connection_add(c); - io_add(&c->io, handle_meta_io, c, c->socket, IO_READ | IO_WRITE); - - return true; -} - -void setup_outgoing_connection(outgoing_t *outgoing, bool verbose) { - (void)verbose; - timeout_del(&outgoing->ev); - - node_t *n = outgoing->node; - - if(n->connection) { - logger(DEBUG_CONNECTIONS, LOG_INFO, "Already connected to %s", n->name); - - if(!n->connection->outgoing) { - n->connection->outgoing = outgoing; - return; - } else { - goto remove; - } - } - - if(!outgoing->address_cache) { - outgoing->address_cache = open_address_cache(n); - } - - do_outgoing_connection(outgoing); - return; - -remove: - list_delete(outgoing_list, outgoing); + do_outgoing_connection(c); } /* accept a new tcp connect and create a new connection */ -void handle_new_meta_connection(void *data, int flags) { - (void)flags; - listen_socket_t *l = data; +bool handle_new_meta_connection(int sock) { + static const int max_accept_burst = 10; + static int last_accept_burst; + static int last_accept_time; connection_t *c; sockaddr_t sa; int fd; socklen_t len = sizeof(sa); - fd = accept(l->tcp.fd, &sa.sa, &len); + fd = accept(sock, &sa.sa, &len); if(fd < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Accepting a new connection failed: %s", sockstrerror(sockerrno)); - return; + logger(LOG_ERR, "Accepting a new connection failed: %s", sockstrerror(sockerrno)); + return false; + } + + if(last_accept_time == now) { + last_accept_burst++; + + if(last_accept_burst >= max_accept_burst) { + if(last_accept_burst == max_accept_burst) { + ifdebug(CONNECTIONS) logger(LOG_WARNING, "Throttling incoming connections"); + } + + tarpit(fd); + return false; + } + } else { + last_accept_burst = 0; + last_accept_time = now; } sockaddrunmap(&sa); - // Check if we get many connections from the same host - - static sockaddr_t prev_sa; - - if(!sockaddrcmp_noport(&sa, &prev_sa)) { - static int samehost_burst; - static int samehost_burst_time; - - if(now.tv_sec - samehost_burst_time > samehost_burst) { - samehost_burst = 0; - } else { - samehost_burst -= now.tv_sec - samehost_burst_time; - } - - samehost_burst_time = now.tv_sec; - samehost_burst++; - - if(samehost_burst > max_connection_burst) { - tarpit(fd); - return; - } - } - - memcpy(&prev_sa, &sa, sizeof(sa)); - - // Check if we get many connections from different hosts - - static int connection_burst; - static int connection_burst_time; - - if(now.tv_sec - connection_burst_time > connection_burst) { - connection_burst = 0; - } else { - connection_burst -= now.tv_sec - connection_burst_time; - } - - connection_burst_time = now.tv_sec; - connection_burst++; - - if(connection_burst >= max_connection_burst) { - connection_burst = max_connection_burst; - tarpit(fd); - return; - } - - // Accept the new connection - c = new_connection(); c->name = xstrdup(""); -#ifndef DISABLE_LEGACY c->outcipher = myself->connection->outcipher; c->outdigest = myself->connection->outdigest; -#endif c->outmaclength = myself->connection->outmaclength; c->outcompression = myself->connection->outcompression; c->address = sa; c->hostname = sockaddr2hostname(&sa); c->socket = fd; - c->last_ping_time = now.tv_sec; + c->last_ping_time = now; - logger(DEBUG_CONNECTIONS, LOG_NOTICE, "Connection from %s", c->hostname); - - io_add(&c->io, handle_meta_io, c, c->socket, IO_READ); + ifdebug(CONNECTIONS) logger(LOG_NOTICE, "Connection from %s", c->hostname); configure_tcp(c); connection_add(c); c->allow_request = ID; + + return true; } -#ifndef HAVE_MINGW -/* - accept a new UNIX socket connection -*/ -void handle_new_unix_connection(void *data, int flags) { - (void)flags; - io_t *io = data; - connection_t *c; - sockaddr_t sa; - int fd; - socklen_t len = sizeof(sa); - - fd = accept(io->fd, &sa.sa, &len); - - if(fd < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Accepting a new connection failed: %s", sockstrerror(sockerrno)); - return; - } - - sockaddrunmap(&sa); - - c = new_connection(); - c->name = xstrdup(""); - c->address = sa; - c->hostname = xstrdup("localhost port unix"); - c->socket = fd; - c->last_ping_time = now.tv_sec; - - logger(DEBUG_CONNECTIONS, LOG_NOTICE, "Connection from %s", c->hostname); - - io_add(&c->io, handle_meta_io, c, c->socket, IO_READ); - - connection_add(c); - - c->allow_request = ID; -} -#endif - static void free_outgoing(outgoing_t *outgoing) { - timeout_del(&outgoing->ev); + if(outgoing->ai) { + freeaddrinfo(outgoing->ai); + } - if(outgoing->address_cache) { - close_address_cache(outgoing->address_cache); + if(outgoing->name) { + free(outgoing->name); } free(outgoing); } void try_outgoing_connections(void) { - /* If there is no outgoing list yet, create one. Otherwise, mark all outgoings as deleted. */ + static config_t *cfg = NULL; + char *name; + outgoing_t *outgoing; - if(!outgoing_list) { - outgoing_list = list_alloc((list_action_t)free_outgoing); - } else { - for list_each(outgoing_t, outgoing, outgoing_list) { - outgoing->timeout = -1; - } - } + outgoing_list = list_alloc((list_action_t)free_outgoing); - /* Make sure there is one outgoing_t in the list for each ConnectTo. */ - - for(config_t *cfg = lookup_config(config_tree, "ConnectTo"); cfg; cfg = lookup_config_next(config_tree, cfg)) { - char *name; + for(cfg = lookup_config(config_tree, "ConnectTo"); cfg; cfg = lookup_config_next(config_tree, cfg)) { get_config_string(cfg, &name); if(!check_id(name)) { - logger(DEBUG_ALWAYS, LOG_ERR, + logger(LOG_ERR, "Invalid name for outgoing connection in %s line %d", cfg->file, cfg->line); free(name); continue; } - if(!strcmp(name, myself->name)) { - free(name); - continue; - } - - bool found = false; - - for list_each(outgoing_t, outgoing, outgoing_list) { - if(!strcmp(outgoing->node->name, name)) { - found = true; - outgoing->timeout = 0; - break; - } - } - - if(!found) { - outgoing_t *outgoing = xzalloc(sizeof(*outgoing)); - node_t *n = lookup_node(name); - - if(!n) { - n = new_node(); - n->name = xstrdup(name); - node_add(n); - } - - outgoing->node = n; - list_insert_tail(outgoing_list, outgoing); - setup_outgoing_connection(outgoing, true); - } + outgoing = xmalloc_and_zero(sizeof(*outgoing)); + outgoing->name = name; + list_insert_tail(outgoing_list, outgoing); + setup_outgoing_connection(outgoing); } - - /* Terminate any connections whose outgoing_t is to be deleted. */ - - for list_each(connection_t, c, connection_list) { - if(c->outgoing && c->outgoing->timeout == -1) { - c->outgoing = NULL; - logger(DEBUG_CONNECTIONS, LOG_INFO, "No more outgoing connection to %s", c->name); - terminate_connection(c, c->edge); - } - } - - /* Delete outgoing_ts for which there is no ConnectTo. */ - - for list_each(outgoing_t, outgoing, outgoing_list) - if(outgoing->timeout == -1) { - list_delete_node(outgoing_list, node); - } } diff --git a/src/netutl.c b/src/netutl.c index 2916e9a..abe3d87 100644 --- a/src/netutl.c +++ b/src/netutl.c @@ -1,7 +1,7 @@ /* netutl.c -- some supporting network utility code Copyright (C) 1998-2005 Ivo Timmermans - 2000-2013 Guus Sliepen + 2000-2016 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 @@ -33,19 +33,21 @@ bool hostnames = false; Return NULL on failure. */ struct addrinfo *str2addrinfo(const char *address, const char *service, int socktype) { - struct addrinfo *ai, hint = {0}; + struct addrinfo *ai = NULL, hint = {0}; int err; hint.ai_family = addressfamily; hint.ai_socktype = socktype; #if HAVE_DECL_RES_INIT + // ensure glibc reloads /etc/resolv.conf. res_init(); #endif err = getaddrinfo(address, service, &hint, &ai); if(err) { - logger(DEBUG_ALWAYS, LOG_WARNING, "Error looking up %s port %s: %s", address, service, err == EAI_SYSTEM ? strerror(errno) : gai_strerror(err)); + logger(LOG_WARNING, "Error looking up %s port %s: %s", address, + service, gai_strerror(err)); return NULL; } @@ -53,8 +55,8 @@ struct addrinfo *str2addrinfo(const char *address, const char *service, int sock } sockaddr_t str2sockaddr(const char *address, const char *port) { - struct addrinfo *ai, hint = {0}; - sockaddr_t result = {0}; + struct addrinfo *ai = NULL, hint = {0}; + sockaddr_t result; int err; hint.ai_family = AF_UNSPEC; @@ -64,7 +66,8 @@ sockaddr_t str2sockaddr(const char *address, const char *port) { err = getaddrinfo(address, port, &hint, &ai); if(err || !ai) { - logger(DEBUG_SCARY_THINGS, LOG_DEBUG, "Unknown type address %s port %s", address, port); + ifdebug(SCARY_THINGS) + logger(LOG_DEBUG, "Unknown type address %s port %s", address, port); result.sa.sa_family = AF_UNKNOWN; result.unknown.address = xstrdup(address); result.unknown.port = xstrdup(port); @@ -83,17 +86,7 @@ void sockaddr2str(const sockaddr_t *sa, char **addrstr, char **portstr) { char *scopeid; int err; - if(sa->sa.sa_family == AF_UNSPEC) { - if(addrstr) { - *addrstr = xstrdup("unspec"); - } - - if(portstr) { - *portstr = xstrdup("unspec"); - } - - return; - } else if(sa->sa.sa_family == AF_UNKNOWN) { + if(sa->sa.sa_family == AF_UNKNOWN) { if(addrstr) { *addrstr = xstrdup(sa->unknown.address); } @@ -108,7 +101,8 @@ void sockaddr2str(const sockaddr_t *sa, char **addrstr, char **portstr) { err = getnameinfo(&sa->sa, SALEN(sa->sa), address, sizeof(address), port, sizeof(port), NI_NUMERICHOST | NI_NUMERICSERV); if(err) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error while translating addresses: %s", err == EAI_SYSTEM ? strerror(errno) : gai_strerror(err)); + logger(LOG_ERR, "Error while translating addresses: %s", + gai_strerror(err)); abort(); } @@ -133,10 +127,7 @@ char *sockaddr2hostname(const sockaddr_t *sa) { char port[NI_MAXSERV] = "unknown"; int err; - if(sa->sa.sa_family == AF_UNSPEC) { - xasprintf(&str, "unspec port unspec"); - return str; - } else if(sa->sa.sa_family == AF_UNKNOWN) { + if(sa->sa.sa_family == AF_UNKNOWN) { xasprintf(&str, "%s port %s", sa->unknown.address, sa->unknown.port); return str; } @@ -145,7 +136,8 @@ char *sockaddr2hostname(const sockaddr_t *sa) { hostnames ? 0 : (NI_NUMERICHOST | NI_NUMERICSERV)); if(err) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error while looking up hostname: %s", err == EAI_SYSTEM ? strerror(errno) : gai_strerror(err)); + logger(LOG_ERR, "Error while looking up hostname: %s", + gai_strerror(err)); } xasprintf(&str, "%s port %s", address, port); @@ -176,7 +168,7 @@ int sockaddrcmp_noport(const sockaddr_t *a, const sockaddr_t *b) { return memcmp(&a->in6.sin6_addr, &b->in6.sin6_addr, sizeof(a->in6.sin6_addr)); default: - logger(DEBUG_ALWAYS, LOG_ERR, "sockaddrcmp() was called with unknown address family %d, exitting!", + logger(LOG_ERR, "sockaddrcmp() was called with unknown address family %d, exitting!", a->sa.sa_family); abort(); } @@ -223,7 +215,7 @@ int sockaddrcmp(const sockaddr_t *a, const sockaddr_t *b) { return memcmp(&a->in6.sin6_port, &b->in6.sin6_port, sizeof(a->in6.sin6_port)); default: - logger(DEBUG_ALWAYS, LOG_ERR, "sockaddrcmp() was called with unknown address family %d, exitting!", + logger(LOG_ERR, "sockaddrcmp() was called with unknown address family %d, exitting!", a->sa.sa_family); abort(); } @@ -277,3 +269,79 @@ void sockaddr_setport(sockaddr_t *sa, const char *port) { return; } } + +/* Subnet mask handling */ + +int maskcmp(const void *va, const void *vb, int masklen) { + int i, m, result; + const char *a = va; + const char *b = vb; + + for(m = masklen, i = 0; m >= 8; m -= 8, i++) { + result = a[i] - b[i]; + + if(result) { + return result; + } + } + + if(m) + return (a[i] & (0x100 - (1 << (8 - m)))) - + (b[i] & (0x100 - (1 << (8 - m)))); + + return 0; +} + +void mask(void *va, int masklen, int len) { + int i; + char *a = va; + + i = masklen / 8; + masklen %= 8; + + if(masklen) { + a[i++] &= (0x100 - (1 << (8 - masklen))); + } + + for(; i < len; i++) { + a[i] = 0; + } +} + +void maskcpy(void *va, const void *vb, int masklen, int len) { + int i, m; + char *a = va; + const char *b = vb; + + for(m = masklen, i = 0; m >= 8; m -= 8, i++) { + a[i] = b[i]; + } + + if(m) { + a[i] = b[i] & (0x100 - (1 << (8 - m))); + i++; + } + + for(; i < len; i++) { + a[i] = 0; + } +} + +bool maskcheck(const void *va, int masklen, int len) { + int i; + const char *a = va; + + i = masklen / 8; + masklen %= 8; + + if(masklen && a[i++] & (0xff >> masklen)) { + return false; + } + + for(; i < len; i++) + if(a[i] != 0) { + return false; + } + + return true; +} diff --git a/src/netutl.h b/src/netutl.h index 4aa1542..cc3ccab 100644 --- a/src/netutl.h +++ b/src/netutl.h @@ -4,7 +4,7 @@ /* netutl.h -- header file for netutl.c Copyright (C) 1998-2005 Ivo Timmermans - 2000-2013 Guus Sliepen + 2000-2016 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 @@ -25,15 +25,19 @@ extern bool hostnames; -extern struct addrinfo *str2addrinfo(const char *address, const char *service, int socktype) __attribute__((__malloc__)); +extern struct addrinfo *str2addrinfo(const char *address, const char *service, int socktype); extern sockaddr_t str2sockaddr(const char *address, const char *port); -extern void sockaddr2str(const sockaddr_t *sa, char **address, char **port); -extern char *sockaddr2hostname(const sockaddr_t *sa) __attribute__((__malloc__)); +extern void sockaddr2str(const sockaddr_t *sa, char **addrstr, char **portstr); +extern char *sockaddr2hostname(const sockaddr_t *sa); extern int sockaddrcmp(const sockaddr_t *a, const sockaddr_t *b); extern int sockaddrcmp_noport(const sockaddr_t *a, const sockaddr_t *b); extern void sockaddrunmap(sockaddr_t *sa); extern void sockaddrfree(sockaddr_t *sa); extern void sockaddrcpy(sockaddr_t *dest, const sockaddr_t *src); extern void sockaddr_setport(sockaddr_t *sa, const char *port); +extern int maskcmp(const void *a, const void *b, int masklen); +extern void maskcpy(void *dest, const void *src, int masklen, int len); +extern void mask(void *mask, int masklen, int len); +extern bool maskcheck(const void *mask, int masklen, int len); #endif diff --git a/src/node.c b/src/node.c index 8f4b6ee..03be21c 100644 --- a/src/node.c +++ b/src/node.c @@ -1,6 +1,6 @@ /* node.c -- node tree management - Copyright (C) 2001-2013 Guus Sliepen , + Copyright (C) 2001-2016 Guus Sliepen , 2001-2005 Ivo Timmermans This program is free software; you can redistribute it and/or modify @@ -20,22 +20,16 @@ #include "system.h" -#include "address_cache.h" -#include "control_common.h" -#include "hash.h" +#include "avl_tree.h" #include "logger.h" #include "net.h" #include "netutl.h" #include "node.h" -#include "splay_tree.h" #include "utils.h" #include "xalloc.h" -#include "ed25519/sha512.h" - -splay_tree_t *node_tree; -static splay_tree_t *node_id_tree; -static splay_tree_t *node_udp_tree; +avl_tree_t *node_tree; /* Known nodes, sorted by name */ +avl_tree_t *node_udp_tree; /* Known nodes, sorted by address and port */ node_t *myself; @@ -43,49 +37,51 @@ static int node_compare(const node_t *a, const node_t *b) { return strcmp(a->name, b->name); } -static int node_id_compare(const node_t *a, const node_t *b) { - return memcmp(&a->id, &b->id, sizeof(node_id_t)); -} - static int node_udp_compare(const node_t *a, const node_t *b) { - int result = sockaddrcmp(&a->address, &b->address); - - if(result) { - return result; - } - - return (a->name && b->name) ? strcmp(a->name, b->name) : 0; + return sockaddrcmp(&a->address, &b->address); } void init_nodes(void) { - node_tree = splay_alloc_tree((splay_compare_t) node_compare, (splay_action_t) free_node); - node_id_tree = splay_alloc_tree((splay_compare_t) node_id_compare, NULL); - node_udp_tree = splay_alloc_tree((splay_compare_t) node_udp_compare, NULL); + node_tree = avl_alloc_tree((avl_compare_t) node_compare, (avl_action_t) free_node); + node_udp_tree = avl_alloc_tree((avl_compare_t) node_udp_compare, NULL); } void exit_nodes(void) { - splay_delete_tree(node_udp_tree); - splay_delete_tree(node_id_tree); - splay_delete_tree(node_tree); + avl_delete_tree(node_udp_tree); + avl_delete_tree(node_tree); } node_t *new_node(void) { - node_t *n = xzalloc(sizeof(*n)); + node_t *n = xmalloc_and_zero(sizeof(*n)); if(replaywin) { - n->late = xzalloc(replaywin); + n->late = xmalloc_and_zero(replaywin); } n->subnet_tree = new_subnet_tree(); n->edge_tree = new_edge_tree(); + n->inctx = EVP_CIPHER_CTX_new(); + n->outctx = EVP_CIPHER_CTX_new(); + + if(!n->inctx || !n->outctx) { + abort(); + } + n->mtu = MTU; n->maxmtu = MTU; - n->udp_ping_rtt = -1; return n; } void free_node(node_t *n) { + if(n->inkey) { + free(n->inkey); + } + + if(n->outkey) { + free(n->outkey); + } + if(n->subnet_tree) { free_subnet_tree(n->subnet_tree); } @@ -96,51 +92,51 @@ void free_node(node_t *n) { sockaddrfree(&n->address); -#ifndef DISABLE_LEGACY - cipher_close(n->incipher); - digest_close(n->indigest); - cipher_close(n->outcipher); - digest_close(n->outdigest); -#endif + EVP_CIPHER_CTX_free(n->outctx); + EVP_CIPHER_CTX_free(n->inctx); - ecdsa_free(n->ecdsa); - sptps_stop(&n->sptps); + if(n->mtuevent) { + event_del(n->mtuevent); + } - timeout_del(&n->udp_ping_timeout); + if(n->hostname) { + free(n->hostname); + } - free(n->hostname); - free(n->name); - free(n->late); + if(n->name) { + free(n->name); + } - if(n->address_cache) { - close_address_cache(n->address_cache); + if(n->late) { + free(n->late); } free(n); } void node_add(node_t *n) { - unsigned char buf[64]; - sha512(n->name, strlen(n->name), buf); - memcpy(&n->id, buf, sizeof(n->id)); - - splay_insert(node_tree, n); - splay_insert(node_id_tree, n); + avl_insert(node_tree, n); } void node_del(node_t *n) { - splay_delete(node_udp_tree, n); + avl_node_t *node, *next; + edge_t *e; + subnet_t *s; - for splay_each(subnet_t, s, n->subnet_tree) { + for(node = n->subnet_tree->head; node; node = next) { + next = node->next; + s = node->data; subnet_del(n, s); } - for splay_each(edge_t, e, n->edge_tree) { + for(node = n->edge_tree->head; node; node = next) { + next = node->next; + e = node->data; edge_del(e); } - splay_delete(node_id_tree, n); - splay_delete(node_tree, n); + avl_delete(node_udp_tree, n); + avl_delete(node_tree, n); } node_t *lookup_node(char *name) { @@ -148,82 +144,56 @@ node_t *lookup_node(char *name) { n.name = name; - return splay_search(node_tree, &n); -} - -node_t *lookup_node_id(const node_id_t *id) { - node_t n = {.id = *id}; - return splay_search(node_id_tree, &n); + return avl_search(node_tree, &n); } node_t *lookup_node_udp(const sockaddr_t *sa) { - node_t tmp = {.address = *sa}; - return splay_search(node_udp_tree, &tmp); + node_t n = {0}; + + n.address = *sa; + n.name = NULL; + + return avl_search(node_udp_tree, &n); } void update_node_udp(node_t *n, const sockaddr_t *sa) { if(n == myself) { - logger(DEBUG_ALWAYS, LOG_WARNING, "Trying to update UDP address of myself!"); + logger(LOG_WARNING, "Trying to update UDP address of myself!"); return; } - splay_delete(node_udp_tree, n); + avl_delete(node_udp_tree, n); + + if(n->hostname) { + free(n->hostname); + } if(sa) { n->address = *sa; - n->sock = 0; - - for(int i = 0; i < listen_sockets; i++) { - if(listen_socket[i].sa.sa.sa_family == sa->sa.sa_family) { - n->sock = i; - break; - } - } - - splay_insert(node_udp_tree, n); - free(n->hostname); n->hostname = sockaddr2hostname(&n->address); - logger(DEBUG_PROTOCOL, LOG_DEBUG, "UDP address of %s set to %s", n->name, n->hostname); + avl_insert(node_udp_tree, n); + ifdebug(PROTOCOL) logger(LOG_DEBUG, "UDP address of %s set to %s", n->name, n->hostname); + } else { + memset(&n->address, 0, sizeof(n->address)); + n->hostname = NULL; + ifdebug(PROTOCOL) logger(LOG_DEBUG, "UDP address of %s cleared", n->name); + } +} + +void dump_nodes(void) { + avl_node_t *node; + node_t *n; + + logger(LOG_DEBUG, "Nodes:"); + + for(node = node_tree->head; node; node = node->next) { + n = node->data; + logger(LOG_DEBUG, " %s at %s cipher %d digest %d maclength %d compression %d options %x status %04x nexthop %s via %s pmtu %d (min %d max %d)", + n->name, n->hostname, n->outcipher ? EVP_CIPHER_nid(n->outcipher) : 0, + n->outdigest ? EVP_MD_type(n->outdigest) : 0, n->outmaclength, n->outcompression, + n->options, bitfield_to_int(&n->status, sizeof(n->status)), n->nexthop ? n->nexthop->name : "-", + n->via ? n->via->name : "-", n->mtu, n->minmtu, n->maxmtu); } - /* invalidate UDP information - note that this is a security feature as well to make sure - we can't be tricked into flooding any random address with UDP packets */ - n->status.udp_confirmed = false; - n->maxrecentlen = 0; - n->mtuprobes = 0; - n->minmtu = 0; - n->maxmtu = MTU; -} - -bool dump_nodes(connection_t *c) { - for splay_each(node_t, n, node_tree) { - char id[2 * sizeof(n->id) + 1]; - - for(size_t c = 0; c < sizeof(n->id); ++c) { - snprintf(id + 2 * c, 3, "%02x", n->id.x[c]); - } - - id[sizeof(id) - 1] = 0; - send_request(c, "%d %d %s %s %s %d %d %d %d %x %x %s %s %d %d %d %d %ld %d %"PRIu64" %"PRIu64" %"PRIu64" %"PRIu64, CONTROL, REQ_DUMP_NODES, - n->name, id, n->hostname ? n->hostname : "unknown port unknown", -#ifdef DISABLE_LEGACY - 0, 0, 0, -#else - cipher_get_nid(n->outcipher), digest_get_nid(n->outdigest), (int)digest_length(n->outdigest), -#endif - n->outcompression, n->options, bitfield_to_int(&n->status, sizeof(n->status)), - n->nexthop ? n->nexthop->name : "-", n->via && n->via->name ? n->via->name : "-", n->distance, - n->mtu, n->minmtu, n->maxmtu, (long)n->last_state_change, n->udp_ping_rtt, - n->in_packets, n->in_bytes, n->out_packets, n->out_bytes); - } - - return send_request(c, "%d %d", CONTROL, REQ_DUMP_NODES); -} - -bool dump_traffic(connection_t *c) { - for splay_each(node_t, n, node_tree) - send_request(c, "%d %d %s %"PRIu64" %"PRIu64" %"PRIu64" %"PRIu64, CONTROL, REQ_DUMP_TRAFFIC, - n->name, n->in_packets, n->in_bytes, n->out_packets, n->out_bytes); - - return send_request(c, "%d %d", CONTROL, REQ_DUMP_TRAFFIC); + logger(LOG_DEBUG, "End of nodes."); } diff --git a/src/node.h b/src/node.h index 3daffd4..b360fe5 100644 --- a/src/node.h +++ b/src/node.h @@ -3,7 +3,7 @@ /* node.h -- header for node.c - Copyright (C) 2001-2013 Guus Sliepen , + Copyright (C) 2001-2016 Guus Sliepen , 2001-2005 Ivo Timmermans This program is free software; you can redistribute it and/or modify @@ -21,102 +21,76 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#include "splay_tree.h" -#include "cipher.h" +#include "avl_tree.h" #include "connection.h" -#include "digest.h" #include "event.h" #include "subnet.h" typedef struct node_status_t { unsigned int unused_active: 1; /* 1 if active (not used for nodes) */ unsigned int validkey: 1; /* 1 if we currently have a valid key for him */ - unsigned int waitingforkey: 1; /* 1 if we already sent out a request */ + unsigned int unused_waitingforkey: 1; /* 1 if we already sent out a request */ unsigned int visited: 1; /* 1 if this node has been visited by one of the graph algorithms */ unsigned int reachable: 1; /* 1 if this node is reachable in the graph */ unsigned int indirect: 1; /* 1 if this node is not directly reachable by us */ - unsigned int sptps: 1; /* 1 if this node supports SPTPS */ - unsigned int udp_confirmed: 1; /* 1 if the address is one that we received UDP traffic on */ - unsigned int send_locally: 1; /* 1 if the next UDP packet should be sent on the local network */ - unsigned int udppacket: 1; /* 1 if the most recently received packet was UDP */ - unsigned int validkey_in: 1; /* 1 if we have sent a valid key to him */ - unsigned int has_address: 1; /* 1 if we know an external address for this node */ - unsigned int unused: 20; + unsigned int unused: 26; } node_status_t; typedef struct node_t { char *name; /* name of this node */ - char *hostname; /* the hostname of its real ip */ - node_id_t id; /* unique node ID (name hash) */ uint32_t options; /* options turned on for this node */ int sock; /* Socket to use for outgoing UDP packets */ sockaddr_t address; /* his real (internet) ip to send UDP packets to */ + char *hostname; /* the hostname of its real ip */ node_status_t status; - time_t last_state_change; time_t last_req_key; - ecdsa_t *ecdsa; /* His public ECDSA key */ - sptps_t sptps; + const EVP_CIPHER *incipher; /* Cipher type for UDP packets received from him */ + char *inkey; /* Cipher key and iv */ + int inkeylength; /* Cipher key and iv length */ + EVP_CIPHER_CTX *inctx; /* Cipher context */ -#ifndef DISABLE_LEGACY - cipher_t *incipher; /* Cipher for UDP packets */ - digest_t *indigest; /* Digest for UDP packets */ + const EVP_CIPHER *outcipher; /* Cipher type for UDP packets sent to him*/ + char *outkey; /* Cipher key and iv */ + int outkeylength; /* Cipher key and iv length */ + EVP_CIPHER_CTX *outctx; /* Cipher context */ - cipher_t *outcipher; /* Cipher for UDP packets */ - digest_t *outdigest; /* Digest for UDP packets */ -#endif + const EVP_MD *indigest; /* Digest type for MAC of packets received from him */ + int inmaclength; /* Length of MAC */ + + const EVP_MD *outdigest; /* Digest type for MAC of packets sent to him*/ + int outmaclength; /* Length of MAC */ int incompression; /* Compressionlevel, 0 = no compression */ int outcompression; /* Compressionlevel, 0 = no compression */ - int distance; struct node_t *nexthop; /* nearest node from us to him */ struct edge_t *prevedge; /* nearest node from him to us */ struct node_t *via; /* next hop for UDP packets */ - splay_tree_t *subnet_tree; /* Pointer to a tree of subnets belonging to this node */ + avl_tree_t *subnet_tree; /* Pointer to a tree of subnets belonging to this node */ - splay_tree_t *edge_tree; /* Edges with this node as one of the endpoints */ + avl_tree_t *edge_tree; /* Edges with this node as one of the endpoints */ struct connection_t *connection; /* Connection associated with this node (if a direct connection exists) */ uint32_t sent_seqno; /* Sequence number last sent to this node */ uint32_t received_seqno; /* Sequence number last received from this node */ - uint32_t received; /* Total valid packets received from this node */ - uint32_t prev_received_seqno; - uint32_t prev_received; uint32_t farfuture; /* Packets in a row that have arrived from the far future */ unsigned char *late; /* Bitfield marking late packets */ - struct timeval udp_reply_sent; /* Last time a (gratuitous) UDP probe reply was sent */ - struct timeval udp_ping_sent; /* Last time a UDP probe was sent */ - int udp_ping_rtt; /* Round trip time of UDP ping (in microseconds; or -1 if !status.udp_confirmed) */ - timeout_t udp_ping_timeout; /* Ping timeout event */ - - struct timeval mtu_ping_sent; /* Last time a MTU probe was sent */ - - struct timeval mtu_info_sent; /* Last time a MTU_INFO message was sent */ - struct timeval udp_info_sent; /* Last time a UDP_INFO message was sent */ - - length_t maxrecentlen; /* Maximum size of recently received packets */ - length_t mtu; /* Maximum size of packets to send to this node */ length_t minmtu; /* Probed minimum MTU */ length_t maxmtu; /* Probed maximum MTU */ int mtuprobes; /* Number of probes */ - - uint64_t in_packets; - uint64_t in_bytes; - uint64_t out_packets; - uint64_t out_bytes; - - struct address_cache_t *address_cache; + event_t *mtuevent; /* Probe event */ } node_t; extern struct node_t *myself; -extern splay_tree_t *node_tree; +extern avl_tree_t *node_tree; +extern avl_tree_t *node_udp_tree; extern void init_nodes(void); extern void exit_nodes(void); @@ -125,10 +99,8 @@ extern void free_node(node_t *n); extern void node_add(node_t *n); extern void node_del(node_t *n); extern node_t *lookup_node(char *name); -extern node_t *lookup_node_id(const node_id_t *id); extern node_t *lookup_node_udp(const sockaddr_t *sa); -extern bool dump_nodes(struct connection_t *c); -extern bool dump_traffic(struct connection_t *c); extern void update_node_udp(node_t *n, const sockaddr_t *sa); +extern void dump_nodes(void); #endif diff --git a/src/nolegacy/crypto.c b/src/nolegacy/crypto.c deleted file mode 100644 index 44692fd..0000000 --- a/src/nolegacy/crypto.c +++ /dev/null @@ -1,94 +0,0 @@ -/* - crypto.c -- Cryptographic miscellaneous functions and initialisation - Copyright (C) 2007-2014 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 - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include "../system.h" - -#include "../crypto.h" - -#ifndef HAVE_MINGW - -static int random_fd = -1; - -static void random_init(void) { - random_fd = open("/dev/urandom", O_RDONLY); - - if(random_fd < 0) { - random_fd = open("/dev/random", O_RDONLY); - } - - if(random_fd < 0) { - fprintf(stderr, "Could not open source of random numbers: %s\n", strerror(errno)); - abort(); - } -} - -static void random_exit(void) { - close(random_fd); -} - -void randomize(void *out, size_t outlen) { - while(outlen) { - size_t len = read(random_fd, out, outlen); - - if(len <= 0) { - if(errno == EAGAIN || errno == EINTR) { - continue; - } - - fprintf(stderr, "Could not read random numbers: %s\n", strerror(errno)); - abort(); - } - - out += len; - outlen -= len; - } -} - -#else - -#include -HCRYPTPROV prov; - -void random_init(void) { - if(!CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) { - fprintf(stderr, "CryptAcquireContext() failed!\n"); - abort(); - } -} - -void random_exit(void) { - CryptReleaseContext(prov, 0); -} - -void randomize(void *out, size_t outlen) { - if(!CryptGenRandom(prov, outlen, out)) { - fprintf(stderr, "CryptGenRandom() failed\n"); - abort(); - } -} - -#endif - -void crypto_init(void) { - random_init(); -} - -void crypto_exit(void) { - random_exit(); -} diff --git a/src/nolegacy/prf.c b/src/nolegacy/prf.c deleted file mode 100644 index ce80f8c..0000000 --- a/src/nolegacy/prf.c +++ /dev/null @@ -1,121 +0,0 @@ -/* - prf.c -- Pseudo-Random Function for key material generation - Copyright (C) 2011-2013 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 - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include "../system.h" - -#include "../prf.h" -#include "../ed25519/sha512.h" - -static void memxor(char *buf, char c, size_t len) { - for(size_t i = 0; i < len; i++) { - buf[i] ^= c; - } -} - -static const size_t mdlen = 64; -static const size_t blklen = 128; - -static bool hmac_sha512(const char *key, size_t keylen, const char *msg, size_t msglen, char *out) { - char tmp[blklen + mdlen]; - sha512_context md; - - if(keylen <= blklen) { - memcpy(tmp, key, keylen); - memset(tmp + keylen, 0, blklen - keylen); - } else { - if(sha512(key, keylen, tmp) != 0) { - return false; - } - - memset(tmp + mdlen, 0, blklen - mdlen); - } - - if(sha512_init(&md) != 0) { - return false; - } - - // ipad - memxor(tmp, 0x36, blklen); - - if(sha512_update(&md, tmp, blklen) != 0) { - return false; - } - - // message - if(sha512_update(&md, msg, msglen) != 0) { - return false; - } - - if(sha512_final(&md, tmp + blklen) != 0) { - return false; - } - - // opad - memxor(tmp, 0x36 ^ 0x5c, blklen); - - if(sha512(tmp, sizeof(tmp), out) != 0) { - return false; - } - - return true; -} - - -/* Generate key material from a master secret and a seed, based on RFC 4346 section 5. - We use SHA512 instead of MD5 and SHA1. - */ - -bool prf(const char *secret, size_t secretlen, char *seed, size_t seedlen, char *out, size_t outlen) { - /* Data is what the "inner" HMAC function processes. - It consists of the previous HMAC result plus the seed. - */ - - char data[mdlen + seedlen]; - memset(data, 0, mdlen); - memcpy(data + mdlen, seed, seedlen); - - char hash[mdlen]; - - while(outlen > 0) { - /* Inner HMAC */ - if(!hmac_sha512(secret, secretlen, data, sizeof(data), data)) { - return false; - } - - /* Outer HMAC */ - if(outlen >= mdlen) { - if(!hmac_sha512(secret, secretlen, data, sizeof(data), out)) { - return false; - } - - out += mdlen; - outlen -= mdlen; - } else { - if(!hmac_sha512(secret, secretlen, data, sizeof(data), hash)) { - return false; - } - - memcpy(out, hash, outlen); - out += outlen; - outlen = 0; - } - } - - return true; -} diff --git a/src/openssl/cipher.c b/src/openssl/cipher.c deleted file mode 100644 index d51ec0d..0000000 --- a/src/openssl/cipher.c +++ /dev/null @@ -1,215 +0,0 @@ -/* - cipher.c -- Symmetric block cipher handling - Copyright (C) 2007-2017 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 - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include "../system.h" - -#include -#include -#include - -#include "../cipher.h" -#include "../logger.h" -#include "../xalloc.h" - -struct cipher { - EVP_CIPHER_CTX *ctx; - const EVP_CIPHER *cipher; -}; - -static cipher_t *cipher_open(const EVP_CIPHER *evp_cipher) { - cipher_t *cipher = xzalloc(sizeof(*cipher)); - cipher->cipher = evp_cipher; - cipher->ctx = EVP_CIPHER_CTX_new(); - - if(!cipher->ctx) { - abort(); - } - - return cipher; -} - -cipher_t *cipher_open_by_name(const char *name) { - const EVP_CIPHER *evp_cipher = EVP_get_cipherbyname(name); - - if(!evp_cipher) { - logger(DEBUG_ALWAYS, LOG_ERR, "Unknown cipher name '%s'!", name); - return NULL; - } - - return cipher_open(evp_cipher); -} - -cipher_t *cipher_open_by_nid(int nid) { - const EVP_CIPHER *evp_cipher = EVP_get_cipherbynid(nid); - - if(!evp_cipher) { - logger(DEBUG_ALWAYS, LOG_ERR, "Unknown cipher nid %d!", nid); - return NULL; - } - - return cipher_open(evp_cipher); -} - -void cipher_close(cipher_t *cipher) { - if(!cipher) { - return; - } - - EVP_CIPHER_CTX_free(cipher->ctx); - free(cipher); -} - -size_t cipher_keylength(const cipher_t *cipher) { - if(!cipher || !cipher->cipher) { - return 0; - } - - return EVP_CIPHER_key_length(cipher->cipher) + EVP_CIPHER_iv_length(cipher->cipher); -} - -uint64_t cipher_budget(const cipher_t *cipher) { - /* Hopefully some failsafe way to calculate the maximum amount of bytes to - send/receive with a given cipher before we might run into birthday paradox - attacks. Because we might use different modes, the block size of the mode - might be 1 byte. In that case, use the IV length. Ensure the whole thing - is limited to what can be represented with a 64 bits integer. - */ - - if(!cipher || !cipher->cipher) { - return UINT64_MAX; // NULL cipher - } - - int ivlen = EVP_CIPHER_iv_length(cipher->cipher); - int blklen = EVP_CIPHER_block_size(cipher->cipher); - int len = blklen > 1 ? blklen : ivlen > 1 ? ivlen : 8; - int bits = len * 4 - 1; - return bits < 64 ? UINT64_C(1) << bits : UINT64_MAX; -} - -size_t cipher_blocksize(const cipher_t *cipher) { - if(!cipher || !cipher->cipher) { - return 1; - } - - return EVP_CIPHER_block_size(cipher->cipher); -} - -bool cipher_set_key(cipher_t *cipher, void *key, bool encrypt) { - bool result; - - if(encrypt) { - result = EVP_EncryptInit_ex(cipher->ctx, cipher->cipher, NULL, (unsigned char *)key, (unsigned char *)key + EVP_CIPHER_key_length(cipher->cipher)); - } else { - result = EVP_DecryptInit_ex(cipher->ctx, cipher->cipher, NULL, (unsigned char *)key, (unsigned char *)key + EVP_CIPHER_key_length(cipher->cipher)); - } - - if(result) { - return true; - } - - logger(DEBUG_ALWAYS, LOG_ERR, "Error while setting key: %s", ERR_error_string(ERR_get_error(), NULL)); - return false; -} - -bool cipher_set_key_from_rsa(cipher_t *cipher, void *key, size_t len, bool encrypt) { - bool result; - - if(encrypt) { - result = EVP_EncryptInit_ex(cipher->ctx, cipher->cipher, NULL, (unsigned char *)key + len - EVP_CIPHER_key_length(cipher->cipher), (unsigned char *)key + len - EVP_CIPHER_iv_length(cipher->cipher) - EVP_CIPHER_key_length(cipher->cipher)); - } else { - result = EVP_DecryptInit_ex(cipher->ctx, cipher->cipher, NULL, (unsigned char *)key + len - EVP_CIPHER_key_length(cipher->cipher), (unsigned char *)key + len - EVP_CIPHER_iv_length(cipher->cipher) - EVP_CIPHER_key_length(cipher->cipher)); - } - - if(result) { - return true; - } - - logger(DEBUG_ALWAYS, LOG_ERR, "Error while setting key: %s", ERR_error_string(ERR_get_error(), NULL)); - return false; -} - -bool cipher_encrypt(cipher_t *cipher, const void *indata, size_t inlen, void *outdata, size_t *outlen, bool oneshot) { - if(oneshot) { - int len, pad; - - if(EVP_EncryptInit_ex(cipher->ctx, NULL, NULL, NULL, NULL) - && EVP_EncryptUpdate(cipher->ctx, (unsigned char *)outdata, &len, indata, inlen) - && EVP_EncryptFinal_ex(cipher->ctx, (unsigned char *)outdata + len, &pad)) { - if(outlen) { - *outlen = len + pad; - } - - return true; - } - } else { - int len; - - if(EVP_EncryptUpdate(cipher->ctx, outdata, &len, indata, inlen)) { - if(outlen) { - *outlen = len; - } - - return true; - } - } - - logger(DEBUG_ALWAYS, LOG_ERR, "Error while encrypting: %s", ERR_error_string(ERR_get_error(), NULL)); - return false; -} - -bool cipher_decrypt(cipher_t *cipher, const void *indata, size_t inlen, void *outdata, size_t *outlen, bool oneshot) { - if(oneshot) { - int len, pad; - - if(EVP_DecryptInit_ex(cipher->ctx, NULL, NULL, NULL, NULL) - && EVP_DecryptUpdate(cipher->ctx, (unsigned char *)outdata, &len, indata, inlen) - && EVP_DecryptFinal_ex(cipher->ctx, (unsigned char *)outdata + len, &pad)) { - if(outlen) { - *outlen = len + pad; - } - - return true; - } - } else { - int len; - - if(EVP_EncryptUpdate(cipher->ctx, outdata, &len, indata, inlen)) { - if(outlen) { - *outlen = len; - } - - return true; - } - } - - logger(DEBUG_ALWAYS, LOG_ERR, "Error while decrypting: %s", ERR_error_string(ERR_get_error(), NULL)); - return false; -} - -int cipher_get_nid(const cipher_t *cipher) { - if(!cipher || !cipher->cipher) { - return 0; - } - - return EVP_CIPHER_nid(cipher->cipher); -} - -bool cipher_active(const cipher_t *cipher) { - return cipher && cipher->cipher && EVP_CIPHER_nid(cipher->cipher) != 0; -} diff --git a/src/openssl/crypto.c b/src/openssl/crypto.c deleted file mode 100644 index e594e73..0000000 --- a/src/openssl/crypto.c +++ /dev/null @@ -1,114 +0,0 @@ -/* - crypto.c -- Cryptographic miscellaneous functions and initialisation - Copyright (C) 2007-2014 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 - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include "../system.h" - -#include -#include -#include - -#include "../crypto.h" - -#ifndef HAVE_MINGW - -static int random_fd = -1; - -static void random_init(void) { - random_fd = open("/dev/urandom", O_RDONLY); - - if(random_fd < 0) { - random_fd = open("/dev/random", O_RDONLY); - } - - if(random_fd < 0) { - fprintf(stderr, "Could not open source of random numbers: %s\n", strerror(errno)); - abort(); - } -} - -static void random_exit(void) { - close(random_fd); -} - -void randomize(void *vout, size_t outlen) { - char *out = vout; - - while(outlen) { - size_t len = read(random_fd, out, outlen); - - if(len <= 0) { - if(errno == EAGAIN || errno == EINTR) { - continue; - } - - fprintf(stderr, "Could not read random numbers: %s\n", strerror(errno)); - abort(); - } - - out += len; - outlen -= len; - } -} - -#else - -#include -HCRYPTPROV prov; - -void random_init(void) { - if(!CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) { - fprintf(stderr, "CryptAcquireContext() failed!\n"); - abort(); - } -} - -void random_exit(void) { - CryptReleaseContext(prov, 0); -} - -void randomize(void *out, size_t outlen) { - if(!CryptGenRandom(prov, outlen, out)) { - fprintf(stderr, "CryptGenRandom() failed\n"); - abort(); - } -} - -#endif - -void crypto_init(void) { - random_init(); - - ENGINE_load_builtin_engines(); - ENGINE_register_all_complete(); - - ERR_load_crypto_strings(); - OpenSSL_add_all_algorithms(); - - if(!RAND_status()) { - fprintf(stderr, "Not enough entropy for the PRNG!\n"); - abort(); - } -} - -void crypto_exit(void) { - EVP_cleanup(); - ERR_free_strings(); - ENGINE_cleanup(); - random_exit(); -} diff --git a/src/openssl/digest.c b/src/openssl/digest.c deleted file mode 100644 index 9569f3c..0000000 --- a/src/openssl/digest.c +++ /dev/null @@ -1,171 +0,0 @@ -/* - digest.c -- Digest handling - Copyright (C) 2007-2016 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 - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include "../system.h" -#include "../utils.h" -#include "../xalloc.h" - -#include -#include - -#include "digest.h" -#include "../digest.h" -#include "../logger.h" - -static digest_t *digest_open(const EVP_MD *evp_md, int maclength) { - digest_t *digest = xzalloc(sizeof(*digest)); - digest->digest = evp_md; - - int digestlen = EVP_MD_size(digest->digest); - - if(maclength > digestlen || maclength < 0) { - digest->maclength = digestlen; - } else { - digest->maclength = maclength; - } - - return digest; -} - -digest_t *digest_open_by_name(const char *name, int maclength) { - const EVP_MD *evp_md = EVP_get_digestbyname(name); - - if(!evp_md) { - logger(DEBUG_ALWAYS, LOG_DEBUG, "Unknown digest name '%s'!", name); - return false; - } - - return digest_open(evp_md, maclength); -} - -digest_t *digest_open_by_nid(int nid, int maclength) { - const EVP_MD *evp_md = EVP_get_digestbynid(nid); - - if(!evp_md) { - logger(DEBUG_ALWAYS, LOG_DEBUG, "Unknown digest nid %d!", nid); - return false; - } - - return digest_open(evp_md, maclength); -} - -bool digest_set_key(digest_t *digest, const void *key, size_t len) { -#ifdef HAVE_HMAC_CTX_NEW - digest->hmac_ctx = HMAC_CTX_new(); - HMAC_Init_ex(digest->hmac_ctx, key, len, digest->digest, NULL); -#else - digest->hmac_ctx = xzalloc(sizeof(*digest->hmac_ctx)); - HMAC_Init(digest->hmac_ctx, key, len, digest->digest); -#endif - - if(!digest->hmac_ctx) { - abort(); - } - - return true; -} - -void digest_close(digest_t *digest) { - if(!digest) { - return; - } - - if(digest->md_ctx) { - EVP_MD_CTX_destroy(digest->md_ctx); - } - -#ifdef HAVE_HMAC_CTX_NEW - - if(digest->hmac_ctx) { - HMAC_CTX_free(digest->hmac_ctx); - } - -#else - free(digest->hmac_ctx); -#endif - - free(digest); -} - -bool digest_create(digest_t *digest, const void *indata, size_t inlen, void *outdata) { - size_t len = EVP_MD_size(digest->digest); - unsigned char tmpdata[len]; - - if(digest->hmac_ctx) { - if(!HMAC_Init_ex(digest->hmac_ctx, NULL, 0, NULL, NULL) - || !HMAC_Update(digest->hmac_ctx, indata, inlen) - || !HMAC_Final(digest->hmac_ctx, tmpdata, NULL)) { - logger(DEBUG_ALWAYS, LOG_DEBUG, "Error creating digest: %s", ERR_error_string(ERR_get_error(), NULL)); - return false; - } - } else { - if(!digest->md_ctx) { - digest->md_ctx = EVP_MD_CTX_create(); - } - - if(!digest->md_ctx) { - abort(); - } - - if(!EVP_DigestInit(digest->md_ctx, digest->digest) - || !EVP_DigestUpdate(digest->md_ctx, indata, inlen) - || !EVP_DigestFinal(digest->md_ctx, tmpdata, NULL)) { - logger(DEBUG_ALWAYS, LOG_DEBUG, "Error creating digest: %s", ERR_error_string(ERR_get_error(), NULL)); - return false; - } - } - - memcpy(outdata, tmpdata, digest->maclength); - return true; -} - -bool digest_verify(digest_t *digest, const void *indata, size_t inlen, const void *cmpdata) { - size_t len = digest->maclength; - unsigned char outdata[len]; - - return digest_create(digest, indata, inlen, outdata) && !memcmp(cmpdata, outdata, digest->maclength); -} - -int digest_get_nid(const digest_t *digest) { - if(!digest || !digest->digest) { - return 0; - } - - return EVP_MD_type(digest->digest); -} - -size_t digest_keylength(const digest_t *digest) { - if(!digest || !digest->digest) { - return 0; - } - - return EVP_MD_size(digest->digest); -} - -size_t digest_length(const digest_t *digest) { - if(!digest) { - return 0; - } - - return digest->maclength; -} - -bool digest_active(const digest_t *digest) { - return digest && digest->digest && EVP_MD_type(digest->digest) != 0; -} diff --git a/src/openssl/digest.h b/src/openssl/digest.h deleted file mode 100644 index 420b11e..0000000 --- a/src/openssl/digest.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef TINC_OPENSSL_DIGEST_H -#define TINC_OPENSSL_DIGEST_H - -/* - digest.h -- header file digest.c - Copyright (C) 2013 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 - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include -#include - -struct digest { - const EVP_MD *digest; - HMAC_CTX *hmac_ctx; - EVP_MD_CTX *md_ctx; - int maclength; -}; - -#endif diff --git a/src/openssl/prf.c b/src/openssl/prf.c deleted file mode 100644 index 37af2ef..0000000 --- a/src/openssl/prf.c +++ /dev/null @@ -1,86 +0,0 @@ -/* - prf.c -- Pseudo-Random Function for key material generation - Copyright (C) 2011-2013 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 - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include "../system.h" - -#include - -#include "digest.h" -#include "../digest.h" -#include "../prf.h" - -/* Generate key material from a master secret and a seed, based on RFC 4346 section 5. - We use SHA512 instead of MD5 and SHA1. - */ - -static bool prf_xor(int nid, const char *secret, size_t secretlen, char *seed, size_t seedlen, char *out, size_t outlen) { - digest_t *digest = digest_open_by_nid(nid, -1); - - if(!digest) { - return false; - } - - if(!digest_set_key(digest, secret, secretlen)) { - digest_close(digest); - return false; - } - - size_t len = digest_length(digest); - - /* Data is what the "inner" HMAC function processes. - It consists of the previous HMAC result plus the seed. - */ - - char data[len + seedlen]; - memset(data, 0, len); - memcpy(data + len, seed, seedlen); - - char hash[len]; - - while(outlen > 0) { - /* Inner HMAC */ - if(!digest_create(digest, data, len + seedlen, data)) { - digest_close(digest); - return false; - } - - /* Outer HMAC */ - if(!digest_create(digest, data, len + seedlen, hash)) { - digest_close(digest); - return false; - } - - /* XOR the results of the outer HMAC into the out buffer */ - for(size_t i = 0; i < len && i < outlen; i++) { - *out++ ^= hash[i]; - } - - outlen -= len; - } - - digest_close(digest); - return true; -} - -bool prf(const char *secret, size_t secretlen, char *seed, size_t seedlen, char *out, size_t outlen) { - /* This construction allows us to easily switch back to a scheme where the PRF is calculated using two different digest algorithms. */ - memset(out, 0, outlen); - - return prf_xor(NID_sha512, secret, secretlen, seed, seedlen, out, outlen); -} diff --git a/src/openssl/rsa.c b/src/openssl/rsa.c deleted file mode 100644 index 0e81172..0000000 --- a/src/openssl/rsa.c +++ /dev/null @@ -1,146 +0,0 @@ -/* - rsa.c -- RSA key handling - Copyright (C) 2007-2013 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 - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include "../system.h" - -#include -#include - -#define TINC_RSA_INTERNAL -typedef RSA rsa_t; - -#include "../logger.h" -#include "../rsa.h" - -// Set RSA keys - -#ifndef HAVE_RSA_SET0_KEY -int RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d) { - BN_free(r->n); - r->n = n; - BN_free(r->e); - r->e = e; - BN_free(r->d); - r->d = d; - return 1; -} -#endif - -rsa_t *rsa_set_hex_public_key(char *n, char *e) { - BIGNUM *bn_n = NULL; - BIGNUM *bn_e = NULL; - - if((size_t)BN_hex2bn(&bn_n, n) != strlen(n) || (size_t)BN_hex2bn(&bn_e, e) != strlen(e)) { - BN_free(bn_e); - BN_free(bn_n); - return false; - } - - rsa_t *rsa = RSA_new(); - - if(!rsa) { - return NULL; - } - - RSA_set0_key(rsa, bn_n, bn_e, NULL); - - return rsa; -} - -rsa_t *rsa_set_hex_private_key(char *n, char *e, char *d) { - BIGNUM *bn_n = NULL; - BIGNUM *bn_e = NULL; - BIGNUM *bn_d = NULL; - - if((size_t)BN_hex2bn(&bn_n, n) != strlen(n) || (size_t)BN_hex2bn(&bn_e, e) != strlen(e) || (size_t)BN_hex2bn(&bn_d, d) != strlen(d)) { - BN_free(bn_d); - BN_free(bn_e); - BN_free(bn_n); - return false; - } - - rsa_t *rsa = RSA_new(); - - if(!rsa) { - return NULL; - } - - RSA_set0_key(rsa, bn_n, bn_e, bn_d); - - return rsa; -} - -// Read PEM RSA keys - -rsa_t *rsa_read_pem_public_key(FILE *fp) { - rsa_t *rsa = PEM_read_RSAPublicKey(fp, NULL, NULL, NULL); - - if(!rsa) { - rewind(fp); - rsa = PEM_read_RSA_PUBKEY(fp, NULL, NULL, NULL); - } - - if(!rsa) { - logger(DEBUG_ALWAYS, LOG_ERR, "Unable to read RSA public key: %s", ERR_error_string(ERR_get_error(), NULL)); - } - - return rsa; -} - -rsa_t *rsa_read_pem_private_key(FILE *fp) { - rsa_t *rsa = PEM_read_RSAPrivateKey(fp, NULL, NULL, NULL); - - if(!rsa) { - logger(DEBUG_ALWAYS, LOG_ERR, "Unable to read RSA private key: %s", ERR_error_string(ERR_get_error(), NULL)); - } - - return rsa; -} - -size_t rsa_size(rsa_t *rsa) { - return RSA_size(rsa); -} - -bool rsa_public_encrypt(rsa_t *rsa, void *in, size_t len, void *out) { - if((size_t)RSA_public_encrypt(len, in, out, rsa, RSA_NO_PADDING) == len) { - return true; - } - - logger(DEBUG_ALWAYS, LOG_ERR, "Unable to perform RSA encryption: %s", ERR_error_string(ERR_get_error(), NULL)); - return false; -} - -bool rsa_private_decrypt(rsa_t *rsa, void *in, size_t len, void *out) { - if((size_t)RSA_private_decrypt(len, in, out, rsa, RSA_NO_PADDING) == len) { - return true; - } - - logger(DEBUG_ALWAYS, LOG_ERR, "Unable to perform RSA decryption: %s", ERR_error_string(ERR_get_error(), NULL)); - return false; -} - -bool rsa_active(rsa_t *rsa) { - return rsa; -} - -void rsa_free(rsa_t *rsa) { - if(rsa) { - RSA_free(rsa); - } -} diff --git a/src/openssl/rsagen.c b/src/openssl/rsagen.c deleted file mode 100644 index 79127f6..0000000 --- a/src/openssl/rsagen.c +++ /dev/null @@ -1,119 +0,0 @@ -/* - rsagen.c -- RSA key generation and export - Copyright (C) 2008-2013 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 - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include "../system.h" - -#include -#include - -#define TINC_RSA_INTERNAL -typedef RSA rsa_t; - -#include "../logger.h" -#include "../rsagen.h" -#include "../xalloc.h" - -/* This function prettyprints the key generation process */ - -static int indicator(int a, int b, BN_GENCB *cb) { - (void)cb; - - switch(a) { - case 0: - fprintf(stderr, "."); - break; - - case 1: - fprintf(stderr, "+"); - break; - - case 2: - fprintf(stderr, "-"); - break; - - case 3: - switch(b) { - case 0: - fprintf(stderr, " p\n"); - break; - - case 1: - fprintf(stderr, " q\n"); - break; - - default: - fprintf(stderr, "?"); - } - - break; - - default: - fprintf(stderr, "?"); - } - - return 1; -} - -// Generate RSA key - -#ifndef HAVE_BN_GENCB_NEW -BN_GENCB *BN_GENCB_new(void) { - return xzalloc(sizeof(BN_GENCB)); -} - -void BN_GENCB_free(BN_GENCB *cb) { - free(cb); -} -#endif - -rsa_t *rsa_generate(size_t bits, unsigned long exponent) { - BIGNUM *bn_e = BN_new(); - rsa_t *rsa = RSA_new(); - BN_GENCB *cb = BN_GENCB_new(); - - if(!bn_e || !rsa || !cb) { - abort(); - } - - BN_set_word(bn_e, exponent); - BN_GENCB_set(cb, indicator, NULL); - - int result = RSA_generate_key_ex(rsa, bits, bn_e, cb); - - BN_GENCB_free(cb); - BN_free(bn_e); - - if(!result) { - fprintf(stderr, "Error during key generation!\n"); - RSA_free(rsa); - return NULL; - } - - return rsa; -} - -// Write PEM RSA keys - -bool rsa_write_pem_public_key(rsa_t *rsa, FILE *fp) { - return PEM_write_RSAPublicKey(fp, rsa); -} - -bool rsa_write_pem_private_key(rsa_t *rsa, FILE *fp) { - return PEM_write_RSAPrivateKey(fp, rsa, NULL, NULL, 0, NULL, NULL); -} diff --git a/src/pidfile.c b/src/pidfile.c new file mode 100644 index 0000000..dd17267 --- /dev/null +++ b/src/pidfile.c @@ -0,0 +1,142 @@ +/* + pidfile.c - interact with pidfiles + Copyright (c) 1995 Martin Schulze + + This file is part of the sysklogd package, a kernel and system log daemon. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +/* left unaltered for tinc -- Ivo Timmermans */ +/* + * Sat Aug 19 13:24:33 MET DST 1995: Martin Schulze + * First version (v0.2) released + */ + +#include "system.h" + +#include "pidfile.h" + +#ifndef HAVE_MINGW +/* read_pid + * + * Reads the specified pidfile and returns the read pid. + * 0 is returned if either there's no pidfile, it's empty + * or no pid can be read. + */ +pid_t read_pid(const char *pidfile) { + FILE *f; + long pid; + + if(!(f = fopen(pidfile, "r"))) { + return 0; + } + + if(fscanf(f, "%20ld", &pid) != 1) { + pid = 0; + } + + fclose(f); + return (pid_t)pid; +} + +/* check_pid + * + * Reads the pid using read_pid and looks up the pid in the process + * table (using /proc) to determine if the process already exists. If + * so the pid is returned, otherwise 0. + */ +pid_t check_pid(const char *pidfile) { + pid_t pid = read_pid(pidfile); + + /* Amazing ! _I_ am already holding the pid file... */ + if((!pid) || (pid == getpid())) { + return 0; + } + + /* + * The 'standard' method of doing this is to try and do a 'fake' kill + * of the process. If an ESRCH error is returned the process cannot + * be found -- GW + */ + /* But... errno is usually changed only on error.. */ + errno = 0; + + if(kill(pid, 0) && errno == ESRCH) { + return 0; + } + + return pid; +} + +/* write_pid + * + * Writes the pid to the specified file. If that fails 0 is + * returned, otherwise the pid. + */ +pid_t write_pid(const char *pidfile) { + FILE *f; + int fd; + pid_t pid; + + if((fd = open(pidfile, O_RDWR | O_CREAT, 0644)) == -1) { + return 0; + } + + if((f = fdopen(fd, "r+")) == NULL) { + close(fd); + return 0; + } + +#ifdef HAVE_FLOCK + + if(flock(fd, LOCK_EX | LOCK_NB) == -1) { + fclose(f); + return 0; + } + +#endif + + pid = getpid(); + + if(!fprintf(f, "%ld\n", (long)pid)) { + fclose(f); + return 0; + } + + fflush(f); + +#ifdef HAVE_FLOCK + + if(flock(fd, LOCK_UN) == -1) { + fclose(f); + return 0; + } + +#endif + fclose(f); + + return pid; +} + +/* remove_pid + * + * Remove the the specified file. The result from unlink(2) + * is returned + */ +int remove_pid(const char *pidfile) { + return unlink(pidfile); +} +#endif diff --git a/src/pidfile.h b/src/pidfile.h new file mode 100644 index 0000000..7d71cc2 --- /dev/null +++ b/src/pidfile.h @@ -0,0 +1,57 @@ +#ifndef TINC_PIDFILE_H +#define TINC_PIDFILE_H + +/* + pidfile.h - interact with pidfiles + Copyright (c) 1995 Martin Schulze + + This file is part of the sysklogd package, a kernel and system log daemon. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#ifndef HAVE_MINGW +/* read_pid + * + * Reads the specified pidfile and returns the read pid. + * 0 is returned if either there's no pidfile, it's empty + * or no pid can be read. + */ +extern pid_t read_pid(const char *pidfile); + +/* check_pid + * + * Reads the pid using read_pid and looks up the pid in the process + * table (using /proc) to determine if the process already exists. If + * so 1 is returned, otherwise 0. + */ +extern pid_t check_pid(const char *pidfile); + +/* write_pid + * + * Writes the pid to the specified file. If that fails 0 is + * returned, otherwise the pid. + */ +extern pid_t write_pid(const char *pidfile); + +/* remove_pid + * + * Remove the the specified file. The result from unlink(2) + * is returned + */ +extern int remove_pid(const char *pidfile); +#endif + +#endif diff --git a/src/prf.h b/src/prf.h deleted file mode 100644 index 9e64989..0000000 --- a/src/prf.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef TINC_PRF_H -#define TINC_PRF_H - -/* - prf.h -- header file for prf.c - Copyright (C) 2011-2013 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 - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -extern bool prf(const char *secret, size_t secretlen, char *seed, size_t seedlen, char *out, size_t outlen) __attribute__((__warn_unused_result__)); - -#endif diff --git a/src/process.c b/src/process.c index c6cb536..13d1007 100644 --- a/src/process.c +++ b/src/process.c @@ -1,7 +1,7 @@ /* process.c -- process management functions Copyright (C) 1999-2005 Ivo Timmermans, - 2000-2013 Guus Sliepen + 2000-2015 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 @@ -22,55 +22,67 @@ #include "conf.h" #include "connection.h" -#include "control.h" #include "device.h" #include "edge.h" -#include "event.h" #include "logger.h" -#include "names.h" #include "net.h" #include "node.h" +#include "pidfile.h" #include "process.h" #include "subnet.h" #include "utils.h" #include "xalloc.h" -#include "version.h" /* If zero, don't detach from the terminal. */ bool do_detach = true; +bool sighup = false; bool sigalrm = false; +extern char *identname; +extern char *pidfilename; extern char **g_argv; extern bool use_logfile; -extern bool use_syslog; + +#ifndef HAVE_MINGW +static sigset_t emptysigset; +#endif /* Some functions the less gifted operating systems might lack... */ #ifdef HAVE_MINGW +extern char *identname; +extern char *program_name; +extern char **g_argv; + static SC_HANDLE manager = NULL; static SC_HANDLE service = NULL; static SERVICE_STATUS status = {0}; static SERVICE_STATUS_HANDLE statushandle = 0; -static bool install_service(void) { +bool install_service(void) { char command[4096] = "\""; + char **argp; + bool space; SERVICE_DESCRIPTION description = {"Virtual Private Network daemon"}; manager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); if(!manager) { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not open service manager: %s", winerror(GetLastError())); + logger(LOG_ERR, "Could not open service manager: %s", winerror(GetLastError())); return false; } - HMODULE module = GetModuleHandle(NULL); - GetModuleFileName(module, command + 1, sizeof(command) - 1); - command[sizeof(command) - 1] = 0; + if(!strchr(program_name, '\\')) { + GetCurrentDirectory(sizeof(command) - 1, command + 1); + strncat(command, "\\", sizeof(command) - strlen(command)); + } + + strncat(command, program_name, sizeof(command) - strlen(command)); strncat(command, "\"", sizeof(command) - strlen(command)); - for(char **argp = g_argv + 1; *argp; argp++) { - char *space = strchr(*argp, ' '); + for(argp = g_argv + 1; *argp; argp++) { + space = strchr(*argp, ' '); strncat(command, " ", sizeof(command) - strlen(command)); if(space) { @@ -90,7 +102,7 @@ static bool install_service(void) { if(!service) { DWORD lasterror = GetLastError(); - logger(DEBUG_ALWAYS, LOG_ERR, "Could not create %s service: %s", identname, winerror(lasterror)); + logger(LOG_ERR, "Could not create %s service: %s", identname, winerror(lasterror)); if(lasterror != ERROR_SERVICE_EXISTS) { return false; @@ -99,21 +111,50 @@ static bool install_service(void) { if(service) { ChangeServiceConfig2(service, SERVICE_CONFIG_DESCRIPTION, &description); - logger(DEBUG_ALWAYS, LOG_INFO, "%s service installed", identname); + logger(LOG_INFO, "%s service installed", identname); } else { service = OpenService(manager, identname, SERVICE_ALL_ACCESS); } if(!StartService(service, 0, NULL)) { - logger(DEBUG_ALWAYS, LOG_WARNING, "Could not start %s service: %s", identname, winerror(GetLastError())); + logger(LOG_WARNING, "Could not start %s service: %s", identname, winerror(GetLastError())); } else { - logger(DEBUG_ALWAYS, LOG_INFO, "%s service started", identname); + logger(LOG_INFO, "%s service started", identname); } return true; } -io_t stop_io; +bool remove_service(void) { + manager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); + + if(!manager) { + logger(LOG_ERR, "Could not open service manager: %s", winerror(GetLastError())); + return false; + } + + service = OpenService(manager, identname, SERVICE_ALL_ACCESS); + + if(!service) { + logger(LOG_ERR, "Could not open %s service: %s", identname, winerror(GetLastError())); + return false; + } + + if(!ControlService(service, SERVICE_CONTROL_STOP, &status)) { + logger(LOG_ERR, "Could not stop %s service: %s", identname, winerror(GetLastError())); + } else { + logger(LOG_INFO, "%s service stopped", identname); + } + + if(!DeleteService(service)) { + logger(LOG_ERR, "Could not remove %s service: %s", identname, winerror(GetLastError())); + return false; + } + + logger(LOG_INFO, "%s service removed", identname); + + return true; +} DWORD WINAPI controlhandler(DWORD request, DWORD type, LPVOID boe, LPVOID bah) { switch(request) { @@ -122,27 +163,31 @@ DWORD WINAPI controlhandler(DWORD request, DWORD type, LPVOID boe, LPVOID bah) { return NO_ERROR; case SERVICE_CONTROL_STOP: - logger(DEBUG_ALWAYS, LOG_NOTICE, "Got %s request", "SERVICE_CONTROL_STOP"); + logger(LOG_NOTICE, "Got %s request", "SERVICE_CONTROL_STOP"); break; case SERVICE_CONTROL_SHUTDOWN: - logger(DEBUG_ALWAYS, LOG_NOTICE, "Got %s request", "SERVICE_CONTROL_SHUTDOWN"); + logger(LOG_NOTICE, "Got %s request", "SERVICE_CONTROL_SHUTDOWN"); break; default: - logger(DEBUG_ALWAYS, LOG_WARNING, "Got unexpected request %d", (int)request); + logger(LOG_WARNING, "Got unexpected request %d", (int)request); return ERROR_CALL_NOT_IMPLEMENTED; } - status.dwWaitHint = 1000; - status.dwCurrentState = SERVICE_STOP_PENDING; - SetServiceStatus(statushandle, &status); - - if(WSASetEvent(stop_io.event) == FALSE) { - abort(); + if(running) { + running = false; + status.dwWaitHint = 30000; + status.dwCurrentState = SERVICE_STOP_PENDING; + SetServiceStatus(statushandle, &status); + return NO_ERROR; + } else { + status.dwWaitHint = 0; + status.dwCurrentState = SERVICE_STOPPED; + SetServiceStatus(statushandle, &status); + exit(1); } - return NO_ERROR; } VOID WINAPI run_service(DWORD argc, LPTSTR *argv) { @@ -157,7 +202,7 @@ VOID WINAPI run_service(DWORD argc, LPTSTR *argv) { statushandle = RegisterServiceCtrlHandlerEx(identname, controlhandler, NULL); if(!statushandle) { - logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "RegisterServiceCtrlHandlerEx", winerror(GetLastError())); + logger(LOG_ERR, "System call `%s' failed: %s", "RegisterServiceCtrlHandlerEx", winerror(GetLastError())); } else { status.dwWaitHint = 30000; status.dwCurrentState = SERVICE_START_PENDING; @@ -187,7 +232,7 @@ bool init_service(void) { if(GetLastError() == ERROR_FAILED_SERVICE_CONTROLLER_CONNECT) { return false; } else { - logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "StartServiceCtrlDispatcher", winerror(GetLastError())); + logger(LOG_ERR, "System call `%s' failed: %s", "StartServiceCtrlDispatcher", winerror(GetLastError())); } } @@ -195,17 +240,92 @@ bool init_service(void) { } #endif +#ifndef HAVE_MINGW +/* + check for an existing tinc for this net, and write pid to pidfile +*/ +static bool write_pidfile(void) { + pid_t pid; + + pid = check_pid(pidfilename); + + if(pid) { + if(netname) + fprintf(stderr, "A tincd is already running for net `%s' with pid %ld.\n", + netname, (long)pid); + else { + fprintf(stderr, "A tincd is already running with pid %ld.\n", (long)pid); + } + + return false; + } + + /* if it's locked, write-protected, or whatever */ + if(!write_pid(pidfilename)) { + fprintf(stderr, "Couldn't write pid file %s: %s\n", pidfilename, strerror(errno)); + return false; + } + + return true; +} +#endif + /* - Detach from current terminal + kill older tincd for this net +*/ +bool kill_other(int signal) { +#ifndef HAVE_MINGW + pid_t pid; + + pid = read_pid(pidfilename); + + if(!pid) { + if(netname) + fprintf(stderr, "No other tincd is running for net `%s'.\n", + netname); + else { + fprintf(stderr, "No other tincd is running.\n"); + } + + return false; + } + + errno = 0; /* No error, sometimes errno is only changed on error */ + + /* ESRCH is returned when no process with that pid is found */ + if(kill(pid, signal) && errno == ESRCH) { + if(netname) + fprintf(stderr, "The tincd for net `%s' is no longer running. ", + netname); + else { + fprintf(stderr, "The tincd is no longer running. "); + } + + fprintf(stderr, "Removing stale lock file.\n"); + remove_pid(pidfilename); + } + + return true; +#else + return remove_service(); +#endif +} + +/* + Detach from current terminal, write pidfile, kill parent */ bool detach(void) { - logmode_t logmode; + setup_signals(); + + /* First check if we can open a fresh new pidfile */ #ifndef HAVE_MINGW - signal(SIGPIPE, SIG_IGN); - signal(SIGUSR1, SIG_IGN); - signal(SIGUSR2, SIG_IGN); - signal(SIGWINCH, SIG_IGN); + + if(!write_pidfile()) { + return false; + } + + /* If we succeeded in doing that, detach */ closelogger(); #endif @@ -213,32 +333,346 @@ bool detach(void) { if(do_detach) { #ifndef HAVE_MINGW - if(daemon(1, 0)) { - logger(DEBUG_ALWAYS, LOG_ERR, "Couldn't detach from terminal: %s", strerror(errno)); + if(daemon(0, 0)) { + fprintf(stderr, "Couldn't detach from terminal: %s", + strerror(errno)); + return false; + } + + /* Now UPDATE the pid in the pidfile, because we changed it... */ + + if(!write_pid(pidfilename)) { + fprintf(stderr, "Could not write pid file %s: %s\n", pidfilename, strerror(errno)); return false; } #else if(!statushandle) { - exit(!install_service()); + exit(install_service()); } #endif } - if(use_logfile) { - logmode = LOGMODE_FILE; - } else if(use_syslog || do_detach) { - logmode = LOGMODE_SYSLOG; - } else { - logmode = LOGMODE_STDERR; - } + openlogger(identname, use_logfile ? LOGMODE_FILE : (do_detach ? LOGMODE_SYSLOG : LOGMODE_STDERR)); - openlogger(identname, logmode); - - logger(DEBUG_ALWAYS, LOG_NOTICE, "tincd %s (%s %s) starting, debug level %d", - BUILD_VERSION, BUILD_DATE, BUILD_TIME, debug_level); + logger(LOG_NOTICE, "tincd %s starting, debug level %d", + VERSION, debug_level); return true; } + +#ifdef HAVE_PUTENV +void unputenv(char *p) { + char *e = strchr(p, '='); + + if(!e) { + return; + } + + int len = e - p; +#ifndef HAVE_UNSETENV +#ifdef HAVE_MINGW + // Windows requires putenv("FOO=") to unset %FOO% + len++; +#endif +#endif + char var[len + 1]; + memcpy(var, p, len); + var[len] = 0; +#ifdef HAVE_UNSETENV + unsetenv(var); +#else + // We must keep what we putenv() around in memory. + // To do this without memory leaks, keep things in a list and reuse if possible. + static list_t list = {}; + + for(list_node_t *node = list.head; node; node = node->next) { + char *data = node->data; + + if(!strcmp(data, var)) { + putenv(data); + return; + } + } + + char *data = xstrdup(var); + list_insert_tail(&list, data); + putenv(data); +#endif +} +#else +void putenv(const char *p) {} +void unputenv(const char *p) {} +#endif + +bool execute_script(const char *name, char **envp) { +#ifdef HAVE_SYSTEM + char *scriptname; + char *interpreter = NULL; + config_t *cfg_interpreter; + int status, len, i; + + cfg_interpreter = lookup_config(config_tree, "ScriptsInterpreter"); +#ifndef HAVE_MINGW + len = xasprintf(&scriptname, "\"%s/%s\"", confbase, name); +#else + + if(cfg_interpreter) { + len = xasprintf(&scriptname, "\"%s/%s\"", confbase, name); + } else { + len = xasprintf(&scriptname, "\"%s/%s.bat\"", confbase, name); + } + +#endif + + if(len < 0) { + return false; + } + + scriptname[len - 1] = '\0'; + + /* First check if there is a script */ + if(access(scriptname + 1, F_OK)) { + free(scriptname); + return true; + } + + // Custom scripts interpreter + if(get_config_string(cfg_interpreter, &interpreter)) { + // Force custom scripts interpreter allowing execution of scripts on android without execution flag (such as on /sdcard) + free(scriptname); + len = xasprintf(&scriptname, "%s \"%s/%s\"", interpreter, confbase, name); + free(interpreter); + + if(len < 0) { + return false; + } + } + + ifdebug(STATUS) logger(LOG_INFO, "Executing script %s", name); + + /* Set environment */ + + for(i = 0; envp[i]; i++) { + putenv(envp[i]); + } + + scriptname[len - 1] = '\"'; + status = system(scriptname); + + free(scriptname); + + /* Unset environment */ + + for(i = 0; envp[i]; i++) { + unputenv(envp[i]); + } + + if(status != -1) { +#ifdef WEXITSTATUS + + if(WIFEXITED(status)) { /* Child exited by itself */ + if(WEXITSTATUS(status)) { + logger(LOG_ERR, "Script %s exited with non-zero status %d", + name, WEXITSTATUS(status)); + return false; + } + } else if(WIFSIGNALED(status)) { /* Child was killed by a signal */ + logger(LOG_ERR, "Script %s was killed by signal %d (%s)", + name, WTERMSIG(status), strsignal(WTERMSIG(status))); + return false; + } else { /* Something strange happened */ + logger(LOG_ERR, "Script %s terminated abnormally", name); + return false; + } + +#endif + } else { + logger(LOG_ERR, "System call `%s' failed: %s", "system", strerror(errno)); + return false; + } + +#endif + return true; +} + + +/* + Signal handlers. +*/ + +#ifndef HAVE_MINGW +static RETSIGTYPE sigterm_handler(int a) { + (void)a; + logger(LOG_NOTICE, "Got %s signal", "TERM"); + + if(running) { + running = false; + } else { + exit(1); + } +} + +static RETSIGTYPE sigquit_handler(int a) { + (void)a; + logger(LOG_NOTICE, "Got %s signal", "QUIT"); + + if(running) { + running = false; + } else { + exit(1); + } +} + +static RETSIGTYPE fatal_signal_square(int a) { + logger(LOG_ERR, "Got another fatal signal %d (%s): not restarting.", a, + strsignal(a)); + exit(1); +} + +static RETSIGTYPE fatal_signal_handler(int a) { + struct sigaction act; + logger(LOG_ERR, "Got fatal signal %d (%s)", a, strsignal(a)); + + if(do_detach) { + logger(LOG_NOTICE, "Trying to re-execute in 5 seconds..."); + + act.sa_handler = fatal_signal_square; + act.sa_mask = emptysigset; + act.sa_flags = 0; + sigaction(SIGSEGV, &act, NULL); + + close_network_connections(); + sleep(5); + remove_pid(pidfilename); + execvp(g_argv[0], g_argv); + } else { + logger(LOG_NOTICE, "Not restarting."); + exit(1); + } +} + +static RETSIGTYPE sighup_handler(int a) { + (void)a; + logger(LOG_NOTICE, "Got %s signal", "HUP"); + sighup = true; +} + +static RETSIGTYPE sigint_handler(int a) { + (void)a; + static int saved_debug_level = -1; + + logger(LOG_NOTICE, "Got %s signal", "INT"); + + if(saved_debug_level != -1) { + logger(LOG_NOTICE, "Reverting to old debug level (%d)", + saved_debug_level); + debug_level = saved_debug_level; + saved_debug_level = -1; + } else { + logger(LOG_NOTICE, + "Temporarily setting debug level to 5. Kill me with SIGINT again to go back to level %d.", + debug_level); + saved_debug_level = debug_level; + debug_level = 5; + } +} + +static RETSIGTYPE sigalrm_handler(int a) { + (void)a; + logger(LOG_NOTICE, "Got %s signal", "ALRM"); + sigalrm = true; +} + +static RETSIGTYPE sigusr1_handler(int a) { + (void)a; + dump_connections(); +} + +static RETSIGTYPE sigusr2_handler(int a) { + (void)a; + devops.dump_stats(); + dump_nodes(); + dump_edges(); + dump_subnets(); +} + +static RETSIGTYPE sigwinch_handler(int a) { + (void)a; + do_purge = true; +} + +static RETSIGTYPE unexpected_signal_handler(int a) { + (void)a; + logger(LOG_WARNING, "Got unexpected signal %d (%s)", a, strsignal(a)); +} + +static RETSIGTYPE ignore_signal_handler(int a) { + (void)a; + ifdebug(SCARY_THINGS) logger(LOG_DEBUG, "Ignored signal %d (%s)", a, strsignal(a)); +} + +static struct { + int signal; + void (*handler)(int); +} sighandlers[] = { + {SIGHUP, sighup_handler}, + {SIGTERM, sigterm_handler}, + {SIGQUIT, sigquit_handler}, + {SIGSEGV, fatal_signal_handler}, + {SIGBUS, fatal_signal_handler}, + {SIGILL, fatal_signal_handler}, + {SIGPIPE, ignore_signal_handler}, + {SIGINT, sigint_handler}, + {SIGUSR1, sigusr1_handler}, + {SIGUSR2, sigusr2_handler}, + {SIGCHLD, ignore_signal_handler}, + {SIGALRM, sigalrm_handler}, + {SIGWINCH, sigwinch_handler}, + {SIGABRT, SIG_DFL}, + {0, NULL} +}; +#endif + +void setup_signals(void) { +#ifndef HAVE_MINGW + int i; + struct sigaction act; + + sigemptyset(&emptysigset); + act.sa_handler = NULL; + act.sa_mask = emptysigset; + act.sa_flags = 0; + + /* Set a default signal handler for every signal, errors will be + ignored. */ + for(i = 1; i < NSIG; i++) { + if(!do_detach) { + act.sa_handler = SIG_DFL; + } else { + act.sa_handler = unexpected_signal_handler; + } + + sigaction(i, &act, NULL); + } + + /* If we didn't detach, allow coredumps */ + if(!do_detach) { + sighandlers[3].handler = SIG_DFL; + } + + /* Then, for each known signal that we want to catch, assign a + handler to the signal, with error checking this time. */ + for(i = 0; sighandlers[i].signal; i++) { + act.sa_handler = sighandlers[i].handler; + + if(sigaction(sighandlers[i].signal, &act, NULL) < 0) + fprintf(stderr, "Installing signal handler for signal %d (%s) failed: %s\n", + sighandlers[i].signal, strsignal(sighandlers[i].signal), + strerror(errno)); + } + +#endif +} diff --git a/src/process.h b/src/process.h index 93ef5e9..e775ac3 100644 --- a/src/process.h +++ b/src/process.h @@ -4,7 +4,7 @@ /* process.h -- header file for process.c Copyright (C) 1999-2005 Ivo Timmermans, - 2000-2013 Guus Sliepen + 2000-2006 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 @@ -22,14 +22,15 @@ */ extern bool do_detach; +extern bool sighup; extern bool sigalrm; extern void setup_signals(void); +extern bool execute_script(const char *name, char **envp); extern bool detach(void); -extern bool kill_other(int); +extern bool kill_other(int signal); #ifdef HAVE_MINGW -extern io_t stop_io; extern bool init_service(void); #endif diff --git a/src/protocol.c b/src/protocol.c index d8b8867..4f74d3b 100644 --- a/src/protocol.c +++ b/src/protocol.c @@ -1,7 +1,7 @@ /* protocol.c -- handle the meta-protocol, basic functions Copyright (C) 1999-2005 Ivo Timmermans, - 2000-2013 Guus Sliepen + 2000-2016 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 @@ -30,20 +30,16 @@ bool tunnelserver = false; bool strictsubnets = false; -bool experimental = true; /* Jumptable for the request handlers */ -static bool (*request_handlers[])(connection_t *, const char *) = { +static bool (*request_handlers[])(connection_t *) = { id_h, metakey_h, challenge_h, chal_reply_h, ack_h, - NULL, NULL, termreq_h, + NULL, NULL, NULL, ping_h, pong_h, add_subnet_h, del_subnet_h, add_edge_h, del_edge_h, - key_changed_h, req_key_h, ans_key_h, tcppacket_h, control_h, - NULL, NULL, /* Not "real" requests (yet) */ - sptps_tcppacket_h, - udp_info_h, mtu_info_h, + key_changed_h, req_key_h, ans_key_h, tcppacket_h, }; /* Request names */ @@ -53,107 +49,123 @@ static char (*request_name[]) = { "STATUS", "ERROR", "TERMREQ", "PING", "PONG", "ADD_SUBNET", "DEL_SUBNET", - "ADD_EDGE", "DEL_EDGE", "KEY_CHANGED", "REQ_KEY", "ANS_KEY", "PACKET", "CONTROL", - "REQ_PUBKEY", "ANS_PUBKEY", "SPTPS_PACKET", "UDP_INFO", "MTU_INFO", + "ADD_EDGE", "DEL_EDGE", "KEY_CHANGED", "REQ_KEY", "ANS_KEY", "PACKET", }; -static splay_tree_t *past_request_tree; +static avl_tree_t *past_request_tree; + +bool check_id(const char *id) { + for(; *id; id++) + if(!isalnum(*id) && *id != '_') { + return false; + } + + return true; +} /* Generic request routines - takes care of logging and error detection as well */ bool send_request(connection_t *c, const char *format, ...) { va_list args; - char request[MAXBUFSIZE]; - int len; + char buffer[MAXBUFSIZE]; + int len, request = 0; /* Use vsnprintf instead of vxasprintf: faster, no memory fragmentation, cleanup is automatic, and there is a limit on the input buffer anyway */ va_start(args, format); - len = vsnprintf(request, sizeof(request), format, args); - request[sizeof(request) - 1] = 0; + len = vsnprintf(buffer, sizeof(buffer), format, args); + buffer[sizeof(buffer) - 1] = 0; va_end(args); - if(len < 0 || (size_t)len > sizeof(request) - 1) { - logger(DEBUG_ALWAYS, LOG_ERR, "Output buffer overflow while sending request to %s (%s)", + if(len < 0 || (size_t)len > sizeof(buffer) - 1) { + logger(LOG_ERR, "Output buffer overflow while sending request to %s (%s)", c->name, c->hostname); return false; } - int id = atoi(request); - logger(DEBUG_META, LOG_DEBUG, "Sending %s to %s (%s): %s", request_name[id], c->name, c->hostname, request); + ifdebug(PROTOCOL) { + sscanf(buffer, "%d", &request); + ifdebug(META) + logger(LOG_DEBUG, "Sending %s to %s (%s): %s", + request_name[request], c->name, c->hostname, buffer); + else + logger(LOG_DEBUG, "Sending %s to %s (%s)", request_name[request], + c->name, c->hostname); + } - request[len++] = '\n'; + buffer[len++] = '\n'; if(c == everyone) { - broadcast_meta(NULL, request, len); + broadcast_meta(NULL, buffer, len); return true; } else { - if(id) { - return send_meta(c, request, len); - } else { - send_meta_raw(c, request, len); - return true; - } + return send_meta(c, buffer, len); } } -void forward_request(connection_t *from, const char *request) { - logger(DEBUG_META, LOG_DEBUG, "Forwarding %s from %s (%s): %s", request_name[atoi(request)], from->name, from->hostname, request); +void forward_request(connection_t *from) { + int request; - // Create a temporary newline-terminated copy of the request - int len = strlen(request); - char tmp[len + 1]; - memcpy(tmp, request, len); - tmp[len] = '\n'; - broadcast_meta(from, tmp, sizeof(tmp)); + ifdebug(PROTOCOL) { + sscanf(from->buffer, "%d", &request); + ifdebug(META) + logger(LOG_DEBUG, "Forwarding %s from %s (%s): %s", + request_name[request], from->name, from->hostname, + from->buffer); + else + logger(LOG_DEBUG, "Forwarding %s from %s (%s)", + request_name[request], from->name, from->hostname); + } + + from->buffer[from->reqlen - 1] = '\n'; + + broadcast_meta(from, from->buffer, from->reqlen); } -bool receive_request(connection_t *c, const char *request) { - if(c->outgoing && proxytype == PROXY_HTTP && c->allow_request == ID) { - if(!request[0] || request[0] == '\r') { - return true; - } +bool receive_request(connection_t *c) { + int request; - if(!strncasecmp(request, "HTTP/1.1 ", 9)) { - if(!strncmp(request + 9, "200", 3)) { - logger(DEBUG_CONNECTIONS, LOG_DEBUG, "Proxy request granted"); - return true; - } else { - logger(DEBUG_ALWAYS, LOG_DEBUG, "Proxy request rejected: %s", request + 9); - return false; + if(sscanf(c->buffer, "%d", &request) == 1) { + if((request < 0) || (request >= LAST) || !request_handlers[request]) { + ifdebug(META) + logger(LOG_DEBUG, "Unknown request from %s (%s): %s", + c->name, c->hostname, c->buffer); + else + logger(LOG_ERR, "Unknown request from %s (%s)", + c->name, c->hostname); + + return false; + } else { + ifdebug(PROTOCOL) { + ifdebug(META) + logger(LOG_DEBUG, "Got %s from %s (%s): %s", + request_name[request], c->name, c->hostname, + c->buffer); + else + logger(LOG_DEBUG, "Got %s from %s (%s)", + request_name[request], c->name, c->hostname); } } - } - int reqno = atoi(request); - - if(reqno || *request == '0') { - if((reqno < 0) || (reqno >= LAST) || !request_handlers[reqno]) { - logger(DEBUG_META, LOG_DEBUG, "Unknown request from %s (%s): %s", c->name, c->hostname, request); - return false; - } else { - logger(DEBUG_META, LOG_DEBUG, "Got %s from %s (%s): %s", request_name[reqno], c->name, c->hostname, request); - } - - if((c->allow_request != ALL) && (c->allow_request != reqno)) { - logger(DEBUG_ALWAYS, LOG_ERR, "Unauthorized request from %s (%s)", c->name, c->hostname); + if((c->allow_request != ALL) && (c->allow_request != request)) { + logger(LOG_ERR, "Unauthorized request from %s (%s)", c->name, + c->hostname); return false; } - if(!request_handlers[reqno](c, request)) { + if(!request_handlers[request](c)) { /* Something went wrong. Probably scriptkiddies. Terminate. */ - if(reqno != TERMREQ) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error while processing %s from %s (%s)", request_name[reqno], c->name, c->hostname); - } - + logger(LOG_ERR, "Error while processing %s from %s (%s)", + request_name[request], c->name, c->hostname); return false; } } else { - logger(DEBUG_ALWAYS, LOG_ERR, "Bogus data received from %s (%s)", c->name, c->hostname); + logger(LOG_ERR, "Bogus data received from %s (%s)", + c->name, c->hostname); return false; } @@ -165,60 +177,55 @@ static int past_request_compare(const past_request_t *a, const past_request_t *b } static void free_past_request(past_request_t *r) { - free((char *)r->request); + if(r->request) { + free(r->request); + } + free(r); } -static timeout_t past_request_timeout; +void init_requests(void) { + past_request_tree = avl_alloc_tree((avl_compare_t) past_request_compare, (avl_action_t) free_past_request); +} -static void age_past_requests(void *data) { - (void)data; +void exit_requests(void) { + avl_delete_tree(past_request_tree); +} + +bool seen_request(char *request) { + past_request_t *new, p = {0}; + + p.request = request; + + if(avl_search(past_request_tree, &p)) { + ifdebug(SCARY_THINGS) logger(LOG_DEBUG, "Already seen request"); + return true; + } else { + new = xmalloc(sizeof(*new)); + new->request = xstrdup(request); + new->firstseen = now; + avl_insert(past_request_tree, new); + return false; + } +} + +void age_past_requests(void) { + avl_node_t *node, *next; + past_request_t *p; int left = 0, deleted = 0; - for splay_each(past_request_t, p, past_request_tree) { - if(p->firstseen + pinginterval <= now.tv_sec) { - splay_delete_node(past_request_tree, node), deleted++; + for(node = past_request_tree->head; node; node = next) { + next = node->next; + p = node->data; + + if(p->firstseen + pinginterval <= now) { + avl_delete_node(past_request_tree, node), deleted++; } else { left++; } } - if(left || deleted) { - logger(DEBUG_SCARY_THINGS, LOG_DEBUG, "Aging past requests: deleted %d, left %d", deleted, left); - } - - if(left) - timeout_set(&past_request_timeout, &(struct timeval) { - 10, rand() % 100000 - }); -} - -bool seen_request(const char *request) { - past_request_t *new, p = {0}; - - p.request = request; - - if(splay_search(past_request_tree, &p)) { - logger(DEBUG_SCARY_THINGS, LOG_DEBUG, "Already seen request"); - return true; - } else { - new = xmalloc(sizeof(*new)); - new->request = xstrdup(request); - new->firstseen = now.tv_sec; - splay_insert(past_request_tree, new); - timeout_add(&past_request_timeout, age_past_requests, NULL, &(struct timeval) { - 10, rand() % 100000 - }); - return false; - } -} - -void init_requests(void) { - past_request_tree = splay_alloc_tree((splay_compare_t) past_request_compare, (splay_action_t) free_past_request); -} - -void exit_requests(void) { - splay_delete_tree(past_request_tree); - - timeout_del(&past_request_timeout); + if(left || deleted) + ifdebug(SCARY_THINGS) logger(LOG_DEBUG, "Aging past requests: deleted %d, left %d", + deleted, left); } diff --git a/src/protocol.h b/src/protocol.h index 42981cc..a055f28 100644 --- a/src/protocol.h +++ b/src/protocol.h @@ -4,7 +4,7 @@ /* protocol.h -- header for protocol.c Copyright (C) 1999-2005 Ivo Timmermans, - 2000-2017 Guus Sliepen + 2000-2015 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 @@ -21,12 +21,11 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#include "ecdsa.h" +/* Protocol version. Different versions are incompatible, + incompatible version have different protocols. + */ -/* Protocol version. Different major versions are incompatible. */ - -#define PROT_MAJOR 17 -#define PROT_MINOR 7 /* Should not exceed 255! */ +#define PROT_CURRENT 17 /* Silly Windows */ @@ -37,6 +36,7 @@ /* Request numbers */ typedef enum request_t { + PROXY = -2, ALL = -1, /* Guardian for allow_request */ ID = 0, METAKEY, CHALLENGE, CHAL_REPLY, ACK, STATUS, ERROR, TERMREQ, @@ -45,25 +45,16 @@ typedef enum request_t { ADD_EDGE, DEL_EDGE, KEY_CHANGED, REQ_KEY, ANS_KEY, PACKET, - /* Tinc 1.1 requests */ - CONTROL, - REQ_PUBKEY, ANS_PUBKEY, - SPTPS_PACKET, - UDP_INFO, MTU_INFO, LAST /* Guardian for the highest request number */ } request_t; typedef struct past_request_t { - const char *request; + char *request; time_t firstseen; } past_request_t; extern bool tunnelserver; extern bool strictsubnets; -extern bool experimental; - -extern int invitation_lifetime; -extern ecdsa_t *invitation_key; /* Maximum size of strings in a request. * scanf terminates %2048s with a NUL character, @@ -81,22 +72,22 @@ extern ecdsa_t *invitation_key; /* Basic functions */ extern bool send_request(struct connection_t *c, const char *format, ...) __attribute__((__format__(printf, 2, 3))); -extern void forward_request(struct connection_t *c, const char *request); -extern bool receive_request(struct connection_t *c, const char *request); +extern void forward_request(struct connection_t *c); +extern bool receive_request(struct connection_t *c); +extern bool check_id(const char *name); extern void init_requests(void); extern void exit_requests(void); -extern bool seen_request(const char *request); +extern bool seen_request(char *request); +extern void age_past_requests(void); /* Requests */ extern bool send_id(struct connection_t *c); extern bool send_metakey(struct connection_t *c); -extern bool send_metakey_ec(struct connection_t *c); extern bool send_challenge(struct connection_t *c); extern bool send_chal_reply(struct connection_t *c); extern bool send_ack(struct connection_t *c); -extern bool send_termreq(struct connection_t *c); extern bool send_ping(struct connection_t *c); extern bool send_pong(struct connection_t *c); extern bool send_add_subnet(struct connection_t *c, const struct subnet_t *subnet); @@ -104,36 +95,26 @@ extern bool send_del_subnet(struct connection_t *c, const struct subnet_t *subne extern bool send_add_edge(struct connection_t *c, const struct edge_t *e); extern bool send_del_edge(struct connection_t *c, const struct edge_t *e); extern void send_key_changed(void); -extern bool send_req_key(struct node_t *to); -extern bool send_ans_key(struct node_t *to); +extern bool send_req_key(struct node_t *n); +extern bool send_ans_key(struct node_t *n); extern bool send_tcppacket(struct connection_t *c, const struct vpn_packet_t *packet); -extern bool send_sptps_tcppacket(struct connection_t *c, const char *packet, int len); -extern bool send_udp_info(struct node_t *from, struct node_t *to); -extern bool send_mtu_info(struct node_t *from, struct node_t *to, int mtu); /* Request handlers */ -extern bool id_h(struct connection_t *c, const char *request); -extern bool metakey_h(struct connection_t *c, const char *request); -extern bool challenge_h(struct connection_t *c, const char *request); -extern bool chal_reply_h(struct connection_t *c, const char *request); -extern bool ack_h(struct connection_t *c, const char *request); -extern bool status_h(struct connection_t *c, const char *request); -extern bool error_h(struct connection_t *c, const char *request); -extern bool termreq_h(struct connection_t *c, const char *request); -extern bool ping_h(struct connection_t *c, const char *request); -extern bool pong_h(struct connection_t *c, const char *request); -extern bool add_subnet_h(struct connection_t *c, const char *request); -extern bool del_subnet_h(struct connection_t *c, const char *request); -extern bool add_edge_h(struct connection_t *c, const char *request); -extern bool del_edge_h(struct connection_t *c, const char *request); -extern bool key_changed_h(struct connection_t *c, const char *request); -extern bool req_key_h(struct connection_t *c, const char *request); -extern bool ans_key_h(struct connection_t *c, const char *request); -extern bool tcppacket_h(struct connection_t *c, const char *request); -extern bool sptps_tcppacket_h(struct connection_t *c, const char *request); -extern bool control_h(struct connection_t *c, const char *request); -extern bool udp_info_h(struct connection_t *c, const char *request); -extern bool mtu_info_h(struct connection_t *c, const char *request); +extern bool id_h(struct connection_t *c); +extern bool metakey_h(struct connection_t *c); +extern bool challenge_h(struct connection_t *c); +extern bool chal_reply_h(struct connection_t *c); +extern bool ack_h(struct connection_t *c); +extern bool ping_h(struct connection_t *c); +extern bool pong_h(struct connection_t *c); +extern bool add_subnet_h(struct connection_t *c); +extern bool del_subnet_h(struct connection_t *c); +extern bool add_edge_h(struct connection_t *c); +extern bool del_edge_h(struct connection_t *c); +extern bool key_changed_h(struct connection_t *c); +extern bool req_key_h(struct connection_t *c); +extern bool ans_key_h(struct connection_t *c); +extern bool tcppacket_h(struct connection_t *c); #endif diff --git a/src/protocol_auth.c b/src/protocol_auth.c index 3a84c22..15807c3 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-2017 Guus Sliepen + 2000-2016 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 @@ -20,380 +20,48 @@ #include "system.h" +#include +#include +#include +#include + +#include "avl_tree.h" #include "conf.h" #include "connection.h" -#include "control.h" -#include "control_common.h" -#include "cipher.h" -#include "crypto.h" -#include "device.h" -#include "digest.h" -#include "ecdsa.h" #include "edge.h" #include "graph.h" #include "logger.h" #include "meta.h" -#include "names.h" #include "net.h" #include "netutl.h" #include "node.h" -#include "prf.h" #include "protocol.h" -#include "rsa.h" -#include "script.h" -#include "sptps.h" +#include "proxy.h" #include "utils.h" #include "xalloc.h" -#include "ed25519/sha512.h" - -int invitation_lifetime; -ecdsa_t *invitation_key = NULL; - -static bool send_proxyrequest(connection_t *c) { - switch(proxytype) { - case PROXY_HTTP: { - char *host; - char *port; - - sockaddr2str(&c->address, &host, &port); - send_request(c, "CONNECT %s:%s HTTP/1.1\r\n\r", host, port); - free(host); - free(port); - return true; - } - - case PROXY_SOCKS4: { - if(c->address.sa.sa_family != AF_INET) { - logger(DEBUG_ALWAYS, LOG_ERR, "Cannot connect to an IPv6 host through a SOCKS 4 proxy!"); - return false; - } - - char s4req[9 + (proxyuser ? strlen(proxyuser) : 0)]; - s4req[0] = 4; - s4req[1] = 1; - memcpy(s4req + 2, &c->address.in.sin_port, 2); - memcpy(s4req + 4, &c->address.in.sin_addr, 4); - - if(proxyuser) { - memcpy(s4req + 8, proxyuser, strlen(proxyuser)); - } - - s4req[sizeof(s4req) - 1] = 0; - c->tcplen = 8; - return send_meta(c, s4req, sizeof(s4req)); - } - - case PROXY_SOCKS5: { - int len = 3 + 6 + (c->address.sa.sa_family == AF_INET ? 4 : 16); - c->tcplen = 2; - - if(proxypass) { - len += 3 + strlen(proxyuser) + strlen(proxypass); - } - - char s5req[len]; - int i = 0; - s5req[i++] = 5; - s5req[i++] = 1; - - if(proxypass) { - s5req[i++] = 2; - s5req[i++] = 1; - s5req[i++] = strlen(proxyuser); - memcpy(s5req + i, proxyuser, strlen(proxyuser)); - i += strlen(proxyuser); - s5req[i++] = strlen(proxypass); - memcpy(s5req + i, proxypass, strlen(proxypass)); - i += strlen(proxypass); - c->tcplen += 2; - } else { - s5req[i++] = 0; - } - - s5req[i++] = 5; - s5req[i++] = 1; - s5req[i++] = 0; - - if(c->address.sa.sa_family == AF_INET) { - s5req[i++] = 1; - memcpy(s5req + i, &c->address.in.sin_addr, 4); - i += 4; - memcpy(s5req + i, &c->address.in.sin_port, 2); - i += 2; - c->tcplen += 10; - } else if(c->address.sa.sa_family == AF_INET6) { - s5req[i++] = 3; - memcpy(s5req + i, &c->address.in6.sin6_addr, 16); - i += 16; - memcpy(s5req + i, &c->address.in6.sin6_port, 2); - i += 2; - c->tcplen += 22; - } else { - logger(DEBUG_ALWAYS, LOG_ERR, "Address family %x not supported for SOCKS 5 proxies!", c->address.sa.sa_family); - return false; - } - - if(i > len) { - abort(); - } - - return send_meta(c, s5req, sizeof(s5req)); - } - - case PROXY_SOCKS4A: - logger(DEBUG_ALWAYS, LOG_ERR, "Proxy type not implemented yet"); - return false; - - case PROXY_EXEC: - return true; - - default: - logger(DEBUG_ALWAYS, LOG_ERR, "Unknown proxy type"); - return false; - } -} - bool send_id(connection_t *c) { - gettimeofday(&c->start, NULL); - - int minor = 0; - - if(experimental) { - if(c->outgoing && !read_ecdsa_public_key(c)) { - minor = 1; - } else { - minor = myself->connection->protocol_minor; - } + if(proxytype && c->outgoing && !c->status.proxy_passed) { + return send_proxyrequest(c); } - if(proxytype && c->outgoing) - if(!send_proxyrequest(c)) { - return false; - } - - return send_request(c, "%d %s %d.%d", ID, myself->connection->name, myself->connection->protocol_major, minor); + return send_request(c, "%d %s %d", ID, myself->connection->name, + myself->connection->protocol_version); } -static bool finalize_invitation(connection_t *c, const char *data, uint16_t len) { - (void)len; - - if(strchr(data, '\n')) { - logger(DEBUG_ALWAYS, LOG_ERR, "Received invalid key from invited node %s (%s)!\n", c->name, c->hostname); - return false; - } - - // Create a new host config file - char filename[PATH_MAX]; - snprintf(filename, sizeof(filename), "%s" SLASH "hosts" SLASH "%s", confbase, c->name); - - if(!access(filename, F_OK)) { - logger(DEBUG_ALWAYS, LOG_ERR, "Host config file for %s (%s) already exists!\n", c->name, c->hostname); - return false; - } - - FILE *f = fopen(filename, "w"); - - if(!f) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error trying to create %s: %s\n", filename, strerror(errno)); - return false; - } - - fprintf(f, "Ed25519PublicKey = %s\n", data); - fclose(f); - - logger(DEBUG_CONNECTIONS, LOG_INFO, "Key successfully received from %s (%s)", c->name, c->hostname); - - // Call invitation-accepted script - environment_t env; - char *address, *port; - - environment_init(&env); - environment_add(&env, "NODE=%s", c->name); - sockaddr2str(&c->address, &address, &port); - environment_add(&env, "REMOTEADDRESS=%s", address); - environment_add(&env, "NAME=%s", myself->name); - - execute_script("invitation-accepted", &env); - - environment_exit(&env); - - sptps_send_record(&c->sptps, 2, data, 0); - return true; -} - -static bool receive_invitation_sptps(void *handle, uint8_t type, const void *data, uint16_t len) { - connection_t *c = handle; - - if(type == 128) { - return true; - } - - if(type == 1 && c->status.invitation_used) { - return finalize_invitation(c, data, len); - } - - if(type != 0 || len != 18 || c->status.invitation_used) { - return false; - } - - // Recover the filename from the cookie and the key - char *fingerprint = ecdsa_get_base64_public_key(invitation_key); - char hashbuf[18 + strlen(fingerprint)]; - char cookie[64]; - memcpy(hashbuf, data, 18); - memcpy(hashbuf + 18, fingerprint, sizeof(hashbuf) - 18); - sha512(hashbuf, sizeof(hashbuf), cookie); - b64encode_urlsafe(cookie, cookie, 18); - free(fingerprint); - - char filename[PATH_MAX], usedname[PATH_MAX]; - snprintf(filename, sizeof(filename), "%s" SLASH "invitations" SLASH "%s", confbase, cookie); - snprintf(usedname, sizeof(usedname), "%s" SLASH "invitations" SLASH "%s.used", confbase, cookie); - - // Atomically rename the invitation file - if(rename(filename, usedname)) { - if(errno == ENOENT) { - logger(DEBUG_ALWAYS, LOG_ERR, "Peer %s tried to use non-existing invitation %s\n", c->hostname, cookie); - } else { - logger(DEBUG_ALWAYS, LOG_ERR, "Error trying to rename invitation %s\n", cookie); - } - - return false; - } - - // Check the timestamp of the invitation - struct stat st; - - if(stat(usedname, &st)) { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not stat %s", usedname); - return false; - } - - if(st.st_mtime + invitation_lifetime < now.tv_sec) { - logger(DEBUG_ALWAYS, LOG_ERR, "Peer %s tried to use expired invitation %s", c->hostname, cookie); - return false; - } - - // Open the renamed file - FILE *f = fopen(usedname, "r"); - - if(!f) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error trying to open invitation %s\n", cookie); - return false; - } - - // Read the new node's Name from the file - char buf[1024]; - fgets(buf, sizeof(buf), f); - - if(*buf) { - buf[strlen(buf) - 1] = 0; - } - - len = strcspn(buf, " \t="); - char *name = buf + len; - name += strspn(name, " \t"); - - if(*name == '=') { - name++; - name += strspn(name, " \t"); - } - - buf[len] = 0; - - if(!*buf || !*name || strcasecmp(buf, "Name") || !check_id(name) || !strcmp(name, myself->name)) { - logger(DEBUG_ALWAYS, LOG_ERR, "Invalid invitation file %s\n", cookie); - fclose(f); - return false; - } - - free(c->name); - c->name = xstrdup(name); - - // Send the node the contents of the invitation file - rewind(f); - size_t result; - - while((result = fread(buf, 1, sizeof(buf), f))) { - sptps_send_record(&c->sptps, 0, buf, result); - } - - sptps_send_record(&c->sptps, 1, buf, 0); - fclose(f); - unlink(usedname); - - c->status.invitation_used = true; - - logger(DEBUG_CONNECTIONS, LOG_INFO, "Invitation %s successfully sent to %s (%s)", cookie, c->name, c->hostname); - return true; -} - -bool id_h(connection_t *c, const char *request) { +bool id_h(connection_t *c) { char name[MAX_STRING_SIZE]; - if(sscanf(request, "%*d " MAX_STRING " %2d.%3d", name, &c->protocol_major, &c->protocol_minor) < 2) { - logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "ID", c->name, + if(sscanf(c->buffer, "%*d " MAX_STRING " %d", name, &c->protocol_version) != 2) { + logger(LOG_ERR, "Got bad %s from %s (%s)", "ID", c->name, c->hostname); return false; } - /* Check if this is a control connection */ - - if(name[0] == '^' && !strcmp(name + 1, controlcookie)) { - c->status.control = true; - c->allow_request = CONTROL; - c->last_ping_time = now.tv_sec + 3600; - - free(c->name); - c->name = xstrdup(""); - - if(!c->outgoing) { - send_id(c); - } - - return send_request(c, "%d %d %d", ACK, TINC_CTL_VERSION_CURRENT, getpid()); - } - - if(name[0] == '?') { - if(!invitation_key) { - logger(DEBUG_ALWAYS, LOG_ERR, "Got invitation from %s but we don't have an invitation key", c->hostname); - return false; - } - - c->ecdsa = ecdsa_set_base64_public_key(name + 1); - - if(!c->ecdsa) { - logger(DEBUG_ALWAYS, LOG_ERR, "Got bad invitation from %s", c->hostname); - return false; - } - - c->status.invitation = true; - char *mykey = ecdsa_get_base64_public_key(invitation_key); - - if(!mykey) { - return false; - } - - if(!c->outgoing) { - send_id(c); - } - - if(!send_request(c, "%d %s", ACK, mykey)) { - return false; - } - - free(mykey); - - c->protocol_minor = 2; - - return sptps_start(&c->sptps, c, false, false, invitation_key, c->ecdsa, "tinc invitation", 15, send_meta_sptps, receive_invitation_sptps); - } - /* Check if identity is a valid name */ if(!check_id(name) || !strcmp(name, myself->name)) { - logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s): %s", "ID", c->name, + logger(LOG_ERR, "Got bad %s from %s (%s): %s", "ID", c->name, c->hostname, "invalid name"); return false; } @@ -402,20 +70,23 @@ bool id_h(connection_t *c, const char *request) { if(c->outgoing) { if(strcmp(c->name, name)) { - logger(DEBUG_ALWAYS, LOG_ERR, "Peer %s is %s instead of %s", c->hostname, name, + logger(LOG_ERR, "Peer %s is %s instead of %s", c->hostname, name, c->name); return false; } } else { - free(c->name); + if(c->name) { + free(c->name); + } + c->name = xstrdup(name); } /* Check if version matches */ - if(c->protocol_major != myself->connection->protocol_major) { - logger(DEBUG_ALWAYS, LOG_ERR, "Peer %s (%s) uses incompatible version %d.%d", - c->name, c->hostname, c->protocol_major, c->protocol_minor); + if(c->protocol_version != myself->connection->protocol_version) { + logger(LOG_ERR, "Peer %s (%s) uses incompatible version %d", + c->name, c->hostname, c->protocol_version); return false; } @@ -433,34 +104,17 @@ bool id_h(connection_t *c, const char *request) { return send_ack(c); } - if(!experimental) { - c->protocol_minor = 0; - } - if(!c->config_tree) { init_configuration(&c->config_tree); - if(!read_host_config(c->config_tree, c->name, false)) { - logger(DEBUG_ALWAYS, LOG_ERR, "Peer %s had unknown identity (%s)", c->hostname, c->name); + if(!read_connection_config(c)) { + logger(LOG_ERR, "Peer %s had unknown identity (%s)", c->hostname, + c->name); return false; } - - if(experimental) { - read_ecdsa_public_key(c); - } - - /* Ignore failures if no key known yet */ } - if(c->protocol_minor && !ecdsa_active(c->ecdsa)) { - c->protocol_minor = 1; - } - - /* Forbid version rollback for nodes whose Ed25519 key we know */ - - if(ecdsa_active(c->ecdsa) && c->protocol_minor < 1) { - logger(DEBUG_ALWAYS, LOG_ERR, "Peer %s (%s) tries to roll back protocol version to %d.%d", - c->name, c->hostname, c->protocol_major, c->protocol_minor); + if(!read_rsa_public_key(c)) { return false; } @@ -470,69 +124,51 @@ bool id_h(connection_t *c, const char *request) { send_id(c); } - if(c->protocol_minor >= 2) { - c->allow_request = ACK; - char label[25 + strlen(myself->name) + strlen(c->name)]; + return send_metakey(c); +} - if(c->outgoing) { - snprintf(label, sizeof(label), "tinc TCP key expansion %s %s", myself->name, c->name); - } else { - snprintf(label, sizeof(label), "tinc TCP key expansion %s %s", c->name, myself->name); - } +static uint64_t byte_budget(const EVP_CIPHER *cipher) { + /* Hopefully some failsafe way to calculate the maximum amount of bytes to + send/receive with a given cipher before we might run into birthday paradox + attacks. Because we might use different modes, the block size of the mode + might be 1 byte. In that case, use the IV length. Ensure the whole thing + is limited to what can be represented with a 64 bits integer. + */ - return sptps_start(&c->sptps, c, c->outgoing, false, myself->connection->ecdsa, c->ecdsa, label, sizeof(label), send_meta_sptps, receive_meta_sptps); - } else { - return send_metakey(c); - } + int ivlen = EVP_CIPHER_iv_length(cipher); + int blklen = EVP_CIPHER_block_size(cipher); + int len = blklen > 1 ? blklen : ivlen > 1 ? ivlen : 8; + int bits = len * 4 - 1; + return bits < 64 ? UINT64_C(1) << bits : UINT64_MAX; } bool send_metakey(connection_t *c) { -#ifdef DISABLE_LEGACY - return false; -#else + bool x; - if(!myself->connection->rsa) { - logger(DEBUG_CONNECTIONS, LOG_ERR, "Peer %s (%s) uses legacy protocol which we don't support", c->name, c->hostname); + int len = RSA_size(c->rsa_key); + + /* Allocate buffers for the meta key */ + + char buffer[2 * len + 1]; + + c->outkey = xrealloc(c->outkey, len); + + if(!c->outctx) { + c->outctx = EVP_CIPHER_CTX_new(); + + if(!c->outctx) { + abort(); + } + } + + /* Copy random data to the buffer */ + + if(1 != RAND_bytes((unsigned char *)c->outkey, len)) { + int err = ERR_get_error(); + logger(LOG_ERR, "Failed to generate meta key (%s)", ERR_error_string(err, NULL)); return false; } - if(!read_rsa_public_key(c)) { - return false; - } - - /* We need to use a stream mode for the meta protocol. Use AES for this, - but try to match the key size with the one from the cipher selected - by Cipher. - */ - - int keylen = cipher_keylength(myself->incipher); - - if(keylen <= 16) { - c->outcipher = cipher_open_by_name("aes-128-cfb"); - } else if(keylen <= 24) { - c->outcipher = cipher_open_by_name("aes-192-cfb"); - } else { - c->outcipher = cipher_open_by_name("aes-256-cfb"); - } - - if(!c) { - return false; - } - - c->outbudget = cipher_budget(c->outcipher); - - if(!(c->outdigest = digest_open_by_name("sha256", -1))) { - return false; - } - - const size_t len = rsa_size(c->rsa); - char key[len]; - char enckey[len]; - char hexkey[2 * len + 1]; - - /* Create a random key */ - - randomize(key, len); /* The message we send must be smaller than the modulus of the RSA key. By definition, for a key of k bits, the following formula holds: @@ -544,15 +180,13 @@ bool send_metakey(connection_t *c) { This can be done by setting the most significant bit to zero. */ - key[0] &= 0x7F; + c->outkey[0] &= 0x7F; - if(!cipher_set_key_from_rsa(c->outcipher, key, len, true)) { - return false; - } - - if(debug_level >= DEBUG_SCARY_THINGS) { - bin2hex(key, hexkey, len); - logger(DEBUG_SCARY_THINGS, LOG_DEBUG, "Generated random meta key (unencrypted): %s", hexkey); + ifdebug(SCARY_THINGS) { + bin2hex(c->outkey, buffer, len); + buffer[len * 2] = '\0'; + logger(LOG_DEBUG, "Generated random meta key (unencrypted): %s", + buffer); } /* Encrypt the random data @@ -562,219 +196,311 @@ bool send_metakey(connection_t *c) { with a length equal to that of the modulus of the RSA key. */ - if(!rsa_public_encrypt(c->rsa, key, len, enckey)) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error during encryption of meta key for %s (%s)", c->name, c->hostname); + if(RSA_public_encrypt(len, (unsigned char *)c->outkey, (unsigned char *)buffer, c->rsa_key, RSA_NO_PADDING) != len) { + logger(LOG_ERR, "Error during encryption of meta key for %s (%s): %s", + c->name, c->hostname, ERR_error_string(ERR_get_error(), NULL)); return false; } /* Convert the encrypted random data to a hexadecimal formatted string */ - bin2hex(enckey, hexkey, len); + bin2hex(buffer, buffer, len); + buffer[len * 2] = '\0'; /* Send the meta key */ - bool result = send_request(c, "%d %d %d %d %d %s", METAKEY, - cipher_get_nid(c->outcipher), - digest_get_nid(c->outdigest), c->outmaclength, - c->outcompression, hexkey); + x = send_request(c, "%d %d %d %d %d %s", METAKEY, + c->outcipher ? EVP_CIPHER_nid(c->outcipher) : 0, + c->outdigest ? EVP_MD_type(c->outdigest) : 0, c->outmaclength, + c->outcompression, buffer); - c->status.encryptout = true; - return result; -#endif + /* Further outgoing requests are encrypted with the key we just generated */ + + if(c->outcipher) { + if(!EVP_EncryptInit(c->outctx, c->outcipher, + (unsigned char *)c->outkey + len - EVP_CIPHER_key_length(c->outcipher), + (unsigned char *)c->outkey + len - EVP_CIPHER_key_length(c->outcipher) - + EVP_CIPHER_iv_length(c->outcipher))) { + logger(LOG_ERR, "Error during initialisation of cipher for %s (%s): %s", + c->name, c->hostname, ERR_error_string(ERR_get_error(), NULL)); + return false; + } + + c->outbudget = byte_budget(c->outcipher); + c->status.encryptout = true; + } + + return x; } -bool metakey_h(connection_t *c, const char *request) { -#ifdef DISABLE_LEGACY - return false; -#else +bool metakey_h(connection_t *c) { + char buffer[MAX_STRING_SIZE]; + int cipher, digest, maclength, compression; + int len; - if(!myself->connection->rsa) { + if(sscanf(c->buffer, "%*d %d %d %d %d " MAX_STRING, &cipher, &digest, &maclength, &compression, buffer) != 5) { + logger(LOG_ERR, "Got bad %s from %s (%s)", "METAKEY", c->name, + c->hostname); return false; } - char hexkey[MAX_STRING_SIZE]; - int cipher, digest, maclength, compression; - const size_t len = rsa_size(myself->connection->rsa); - char enckey[len]; - char key[len]; + len = RSA_size(myself->connection->rsa_key); - if(sscanf(request, "%*d %d %d %d %d " MAX_STRING, &cipher, &digest, &maclength, &compression, hexkey) != 5) { - logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "METAKEY", c->name, c->hostname); + /* Check if the length of the meta key is all right */ + + if(strlen(buffer) != (size_t)len * 2) { + logger(LOG_ERR, "Possible intruder %s (%s): %s", c->name, c->hostname, "wrong keylength"); return false; } + /* Allocate buffers for the meta key */ + + c->inkey = xrealloc(c->inkey, len); + + if(!c->inctx) { + c->inctx = EVP_CIPHER_CTX_new(); + + if(!c->inctx) { + abort(); + } + } + /* Convert the challenge from hexadecimal back to binary */ - size_t inlen = hex2bin(hexkey, enckey, sizeof(enckey)); - - /* Check if the length of the meta key is all right */ - - if(inlen != len) { - logger(DEBUG_ALWAYS, LOG_ERR, "Possible intruder %s (%s): %s", c->name, c->hostname, "wrong keylength"); + if(!hex2bin(buffer, buffer, len)) { + logger(LOG_ERR, "Got bad %s from %s(%s): %s", "METAKEY", c->name, c->hostname, "invalid key"); return false; } /* Decrypt the meta key */ - if(!rsa_private_decrypt(myself->connection->rsa, enckey, len, key)) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error during decryption of meta key for %s (%s)", c->name, c->hostname); + if(RSA_private_decrypt(len, (unsigned char *)buffer, (unsigned char *)c->inkey, myself->connection->rsa_key, RSA_NO_PADDING) != len) { /* See challenge() */ + logger(LOG_ERR, "Error during decryption of meta key for %s (%s): %s", + c->name, c->hostname, ERR_error_string(ERR_get_error(), NULL)); return false; } - if(debug_level >= DEBUG_SCARY_THINGS) { - bin2hex(key, hexkey, len); - logger(DEBUG_SCARY_THINGS, LOG_DEBUG, "Received random meta key (unencrypted): %s", hexkey); + ifdebug(SCARY_THINGS) { + bin2hex(c->inkey, buffer, len); + buffer[len * 2] = '\0'; + logger(LOG_DEBUG, "Received random meta key (unencrypted): %s", buffer); } + /* All incoming requests will now be encrypted. */ + /* Check and lookup cipher and digest algorithms */ if(cipher) { - if(!(c->incipher = cipher_open_by_nid(cipher)) || !cipher_set_key_from_rsa(c->incipher, key, len, false)) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error during initialisation of cipher from %s (%s)", c->name, c->hostname); + c->incipher = EVP_get_cipherbynid(cipher); + + if(!c->incipher) { + logger(LOG_ERR, "%s (%s) uses unknown cipher!", c->name, c->hostname); return false; } + + if(!EVP_DecryptInit(c->inctx, c->incipher, + (unsigned char *)c->inkey + len - EVP_CIPHER_key_length(c->incipher), + (unsigned char *)c->inkey + len - EVP_CIPHER_key_length(c->incipher) - + EVP_CIPHER_iv_length(c->incipher))) { + logger(LOG_ERR, "Error during initialisation of cipher from %s (%s): %s", + c->name, c->hostname, ERR_error_string(ERR_get_error(), NULL)); + return false; + } + + c->inbudget = byte_budget(c->incipher); + c->status.decryptin = true; } else { - logger(DEBUG_ALWAYS, LOG_ERR, "Possible intruder %s (%s): %s", c->name, c->hostname, "null cipher"); + logger(LOG_ERR, "%s (%s) uses null cipher!", c->name, c->hostname); return false; } - c->inbudget = cipher_budget(c->incipher); + c->inmaclength = maclength; if(digest) { - if(!(c->indigest = digest_open_by_nid(digest, -1))) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error during initialisation of digest from %s (%s)", c->name, c->hostname); + c->indigest = EVP_get_digestbynid(digest); + + if(!c->indigest) { + logger(LOG_ERR, "Node %s (%s) uses unknown digest!", c->name, c->hostname); + return false; + } + + if(c->inmaclength > EVP_MD_size(c->indigest) || c->inmaclength < 0) { + logger(LOG_ERR, "%s (%s) uses bogus MAC length!", c->name, c->hostname); return false; } } else { - logger(DEBUG_ALWAYS, LOG_ERR, "Possible intruder %s (%s): %s", c->name, c->hostname, "null digest"); + logger(LOG_ERR, "%s (%s) uses null digest!", c->name, c->hostname); return false; } - c->status.decryptin = true; + c->incompression = compression; c->allow_request = CHALLENGE; return send_challenge(c); -#endif } bool send_challenge(connection_t *c) { -#ifdef DISABLE_LEGACY - return false; -#else - const size_t len = rsa_size(c->rsa); - char buffer[len * 2 + 1]; + /* CHECKME: what is most reasonable value for len? */ + + int len = RSA_size(c->rsa_key); + + /* Allocate buffers for the challenge */ + + char buffer[2 * len + 1]; c->hischallenge = xrealloc(c->hischallenge, len); /* Copy random data to the buffer */ - randomize(c->hischallenge, len); + if(1 != RAND_bytes((unsigned char *)c->hischallenge, len)) { + int err = ERR_get_error(); + logger(LOG_ERR, "Failed to generate challenge (%s)", ERR_error_string(err, NULL)); + return false; // Do not send predictable challenges, let connection attempt fail. + } /* Convert to hex */ bin2hex(c->hischallenge, buffer, len); + buffer[len * 2] = '\0'; /* Send the challenge */ return send_request(c, "%d %s", CHALLENGE, buffer); -#endif } -bool challenge_h(connection_t *c, const char *request) { -#ifdef DISABLE_LEGACY - return false; -#else - - if(!myself->connection->rsa) { - return false; - } - +bool challenge_h(connection_t *c) { char buffer[MAX_STRING_SIZE]; - const size_t len = rsa_size(myself->connection->rsa); + int len; - if(sscanf(request, "%*d " MAX_STRING, buffer) != 1) { - logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "CHALLENGE", c->name, c->hostname); + if(sscanf(c->buffer, "%*d " MAX_STRING, buffer) != 1) { + logger(LOG_ERR, "Got bad %s from %s (%s)", "CHALLENGE", c->name, + c->hostname); return false; } + len = RSA_size(myself->connection->rsa_key); + /* Check if the length of the challenge is all right */ if(strlen(buffer) != (size_t)len * 2) { - logger(DEBUG_ALWAYS, LOG_ERR, "Possible intruder %s (%s): %s", c->name, c->hostname, "wrong challenge length"); + logger(LOG_ERR, "Possible intruder %s (%s): %s", c->name, + c->hostname, "wrong challenge length"); return false; } + /* Allocate buffers for the challenge */ + c->mychallenge = xrealloc(c->mychallenge, len); /* Convert the challenge from hexadecimal back to binary */ - hex2bin(buffer, c->mychallenge, len); - - /* The rest is done by send_chal_reply() */ + if(!hex2bin(buffer, c->mychallenge, len)) { + logger(LOG_ERR, "Got bad %s from %s(%s): %s", "CHALLENGE", c->name, c->hostname, "invalid challenge"); + return false; + } c->allow_request = CHAL_REPLY; + /* Rest is done by send_chal_reply() */ + if(c->outgoing) { return send_chal_reply(c); } else { return true; } - -#endif } bool send_chal_reply(connection_t *c) { - const size_t len = rsa_size(myself->connection->rsa); - size_t digestlen = digest_length(c->indigest); - char digest[digestlen * 2 + 1]; + char hash[EVP_MAX_MD_SIZE * 2 + 1]; + EVP_MD_CTX *ctx; /* Calculate the hash from the challenge we received */ - if(!digest_create(c->indigest, c->mychallenge, len, digest)) { + ctx = EVP_MD_CTX_create(); + + if(!ctx) { + abort(); + } + + if(!EVP_DigestInit(ctx, c->indigest) + || !EVP_DigestUpdate(ctx, c->mychallenge, RSA_size(myself->connection->rsa_key)) + || !EVP_DigestFinal(ctx, (unsigned char *)hash, NULL)) { + EVP_MD_CTX_destroy(ctx); + logger(LOG_ERR, "Error during calculation of response for %s (%s): %s", + c->name, c->hostname, ERR_error_string(ERR_get_error(), NULL)); return false; } - free(c->mychallenge); - c->mychallenge = NULL; + EVP_MD_CTX_destroy(ctx); /* Convert the hash to a hexadecimal formatted string */ - bin2hex(digest, digest, digestlen); + bin2hex(hash, hash, EVP_MD_size(c->indigest)); + hash[EVP_MD_size(c->indigest) * 2] = '\0'; /* Send the reply */ - return send_request(c, "%d %s", CHAL_REPLY, digest); + return send_request(c, "%d %s", CHAL_REPLY, hash); } -bool chal_reply_h(connection_t *c, const char *request) { -#ifdef DISABLE_LEGACY - return false; -#else +bool chal_reply_h(connection_t *c) { char hishash[MAX_STRING_SIZE]; + char myhash[EVP_MAX_MD_SIZE]; + EVP_MD_CTX *ctx; - if(sscanf(request, "%*d " MAX_STRING, hishash) != 1) { - logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "CHAL_REPLY", c->name, + if(sscanf(c->buffer, "%*d " MAX_STRING, hishash) != 1) { + logger(LOG_ERR, "Got bad %s from %s (%s)", "CHAL_REPLY", c->name, c->hostname); return false; } + /* Check if the length of the hash is all right */ + + if(strlen(hishash) != (size_t)EVP_MD_size(c->outdigest) * 2) { + logger(LOG_ERR, "Possible intruder %s (%s): %s", c->name, + c->hostname, "wrong challenge reply length"); + return false; + } + /* Convert the hash to binary format */ - size_t inlen = hex2bin(hishash, hishash, sizeof(hishash)); - - /* Check if the length of the hash is all right */ - - if(inlen != digest_length(c->outdigest)) { - logger(DEBUG_ALWAYS, LOG_ERR, "Possible intruder %s (%s): %s", c->name, c->hostname, "wrong challenge reply length"); + if(!hex2bin(hishash, hishash, EVP_MD_size(c->outdigest))) { + logger(LOG_ERR, "Got bad %s from %s(%s): %s", "CHAL_REPLY", c->name, c->hostname, "invalid hash"); return false; } + /* Calculate the hash from the challenge we sent */ - /* Verify the hash */ + ctx = EVP_MD_CTX_create(); + + if(!ctx) { + abort(); + } + + if(!EVP_DigestInit(ctx, c->outdigest) + || !EVP_DigestUpdate(ctx, c->hischallenge, RSA_size(c->rsa_key)) + || !EVP_DigestFinal(ctx, (unsigned char *)myhash, NULL)) { + EVP_MD_CTX_destroy(ctx); + logger(LOG_ERR, "Error during calculation of response from %s (%s): %s", + c->name, c->hostname, ERR_error_string(ERR_get_error(), NULL)); + return false; + } + + EVP_MD_CTX_destroy(ctx); + + /* Verify the incoming hash with the calculated hash */ + + if(memcmp(hishash, myhash, EVP_MD_size(c->outdigest))) { + logger(LOG_ERR, "Possible intruder %s (%s): %s", c->name, + c->hostname, "wrong challenge reply"); + + ifdebug(SCARY_THINGS) { + bin2hex(myhash, hishash, SHA_DIGEST_LENGTH); + hishash[SHA_DIGEST_LENGTH * 2] = '\0'; + logger(LOG_DEBUG, "Expected challenge reply: %s", hishash); + } - if(!digest_verify(c->outdigest, c->hischallenge, rsa_size(c->rsa), hishash)) { - logger(DEBUG_ALWAYS, LOG_ERR, "Possible intruder %s (%s): %s", c->name, c->hostname, "wrong challenge reply"); return false; } @@ -782,8 +508,6 @@ bool chal_reply_h(connection_t *c, const char *request) { Send an acknowledgement with the rest of the information needed. */ - free(c->hischallenge); - c->hischallenge = NULL; c->allow_request = ACK; if(!c->outgoing) { @@ -791,33 +515,9 @@ bool chal_reply_h(connection_t *c, const char *request) { } return send_ack(c); -#endif -} - -static bool send_upgrade(connection_t *c) { -#ifdef DISABLE_LEGACY - return false; -#else - /* Special case when protocol_minor is 1: the other end is Ed25519 capable, - * but doesn't know our key yet. So send it now. */ - - char *pubkey = ecdsa_get_base64_public_key(myself->connection->ecdsa); - - if(!pubkey) { - return false; - } - - bool result = send_request(c, "%d %s", ACK, pubkey); - free(pubkey); - return result; -#endif } bool send_ack(connection_t *c) { - if(c->protocol_minor == 1) { - return send_upgrade(c); - } - /* ACK message contains rest of the information the other end needs to create node_t and edge_t structures. */ @@ -850,100 +550,52 @@ bool send_ack(connection_t *c) { c->options |= OPTION_CLAMP_MSS; } - if(!get_config_int(lookup_config(c->config_tree, "Weight"), &c->estimated_weight)) { - get_config_int(lookup_config(config_tree, "Weight"), &c->estimated_weight); - } + 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 & 0xffffff) | (experimental ? (PROT_MINOR << 24) : 0)); + return send_request(c, "%d %s %d %x", ACK, myport, c->estimated_weight, c->options); } static void send_everything(connection_t *c) { + avl_node_t *node, *node2; + node_t *n; + subnet_t *s; + edge_t *e; + /* Send all known subnets and edges */ - if(disablebuggypeers) { - static struct { - vpn_packet_t pkt; - char pad[MAXBUFSIZE - MAXSIZE]; - } zeropkt; - - memset(&zeropkt, 0, sizeof(zeropkt)); - zeropkt.pkt.len = MAXBUFSIZE; - send_tcppacket(c, &zeropkt.pkt); - } - if(tunnelserver) { - for splay_each(subnet_t, s, myself->subnet_tree) { + for(node = myself->subnet_tree->head; node; node = node->next) { + s = node->data; send_add_subnet(c, s); } return; } - for splay_each(node_t, n, node_tree) { - for splay_each(subnet_t, s, n->subnet_tree) { + for(node = node_tree->head; node; node = node->next) { + n = node->data; + + for(node2 = n->subnet_tree->head; node2; node2 = node2->next) { + s = node2->data; send_add_subnet(c, s); } - for splay_each(edge_t, e, n->edge_tree) { + for(node2 = n->edge_tree->head; node2; node2 = node2->next) { + e = node2->data; send_add_edge(c, e); } } } -static bool upgrade_h(connection_t *c, const char *request) { - char pubkey[MAX_STRING_SIZE]; - - if(sscanf(request, "%*d " MAX_STRING, pubkey) != 1) { - logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "ACK", c->name, c->hostname); - return false; - } - - if(ecdsa_active(c->ecdsa) || read_ecdsa_public_key(c)) { - char *knownkey = ecdsa_get_base64_public_key(c->ecdsa); - bool different = strcmp(knownkey, pubkey); - free(knownkey); - - if(different) { - logger(DEBUG_ALWAYS, LOG_ERR, "Already have an Ed25519 public key from %s (%s) which is different from the one presented now!", c->name, c->hostname); - return false; - } - - logger(DEBUG_ALWAYS, LOG_INFO, "Already have Ed25519 public key from %s (%s), ignoring.", c->name, c->hostname); - c->allow_request = TERMREQ; - return send_termreq(c); - } - - c->ecdsa = ecdsa_set_base64_public_key(pubkey); - - if(!c->ecdsa) { - logger(DEBUG_ALWAYS, LOG_INFO, "Got bad Ed25519 public key from %s (%s), not upgrading.", c->name, c->hostname); - return false; - } - - logger(DEBUG_ALWAYS, LOG_INFO, "Got Ed25519 public key from %s (%s), upgrading!", c->name, c->hostname); - append_config_file(c->name, "Ed25519PublicKey", pubkey); - c->allow_request = TERMREQ; - - if(c->outgoing) { - c->outgoing->timeout = 0; - } - - return send_termreq(c); -} - -bool ack_h(connection_t *c, const char *request) { - if(c->protocol_minor == 1) { - return upgrade_h(c, request); - } - +bool ack_h(connection_t *c) { char hisport[MAX_STRING_SIZE]; int weight, mtu; uint32_t options; node_t *n; bool choice; - if(sscanf(request, "%*d " MAX_STRING " %d %x", hisport, &weight, &options) != 3) { - logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "ACK", c->name, + 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, c->hostname); return false; } @@ -959,18 +611,8 @@ bool ack_h(connection_t *c, const char *request) { } else { if(n->connection) { /* Oh dear, we already have a connection to this node. */ - logger(DEBUG_CONNECTIONS, LOG_DEBUG, "Established a second connection with %s (%s), closing old connection", n->connection->name, n->connection->hostname); - - if(n->connection->outgoing) { - if(c->outgoing) { - logger(DEBUG_ALWAYS, LOG_WARNING, "Two outgoing connections to the same node!"); - } else { - c->outgoing = n->connection->outgoing; - } - - n->connection->outgoing = NULL; - } - + ifdebug(CONNECTIONS) logger(LOG_DEBUG, "Established a second connection with %s (%s), closing old connection", + n->name, n->hostname); terminate_connection(n->connection, false); /* Run graph algorithm to purge key and make sure up/down scripts are rerun with new IP addresses and stuff */ graph(); @@ -1006,9 +648,10 @@ bool ack_h(connection_t *c, const char *request) { /* Activate this connection */ c->allow_request = ALL; + c->status.active = true; - logger(DEBUG_CONNECTIONS, LOG_NOTICE, "Connection with %s (%s) activated", c->name, - c->hostname); + ifdebug(CONNECTIONS) logger(LOG_NOTICE, "Connection with %s (%s) activated", c->name, + c->hostname); /* Send him everything we know */ @@ -1021,16 +664,6 @@ bool ack_h(connection_t *c, const char *request) { c->edge->to = n; sockaddrcpy(&c->edge->address, &c->address); sockaddr_setport(&c->edge->address, hisport); - sockaddr_t local_sa; - socklen_t local_salen = sizeof(local_sa); - - if(getsockname(c->socket, &local_sa.sa, &local_salen) < 0) { - logger(DEBUG_ALWAYS, LOG_WARNING, "Could not get local socket address for connection with %s", c->name); - } else { - sockaddr_setport(&local_sa, myport); - c->edge->local_address = local_sa; - } - c->edge->weight = (weight + c->estimated_weight) / 2; c->edge->connection = c; c->edge->options = c->options; diff --git a/src/protocol_edge.c b/src/protocol_edge.c index d650c36..a1cf640 100644 --- a/src/protocol_edge.c +++ b/src/protocol_edge.c @@ -1,7 +1,7 @@ /* protocol_edge.c -- handle the meta-protocol, edges Copyright (C) 1999-2005 Ivo Timmermans, - 2000-2012 Guus Sliepen + 2000-2016 Guus Sliepen 2009 Michael Tokarev This program is free software; you can redistribute it and/or modify @@ -21,6 +21,7 @@ #include "system.h" +#include "avl_tree.h" #include "conf.h" #include "connection.h" #include "edge.h" @@ -40,45 +41,29 @@ bool send_add_edge(connection_t *c, const edge_t *e) { sockaddr2str(&e->address, &address, &port); - if(e->local_address.sa.sa_family) { - char *local_address, *local_port; - sockaddr2str(&e->local_address, &local_address, &local_port); - - x = send_request(c, "%d %x %s %s %s %s %x %d %s %s", ADD_EDGE, rand(), - e->from->name, e->to->name, address, port, - e->options, e->weight, local_address, local_port); - free(local_address); - free(local_port); - } else { - x = send_request(c, "%d %x %s %s %s %s %x %d", ADD_EDGE, rand(), - e->from->name, e->to->name, address, port, - e->options, e->weight); - } - + x = send_request(c, "%d %x %s %s %s %s %x %d", ADD_EDGE, rand(), + e->from->name, e->to->name, address, port, + e->options, e->weight); free(address); free(port); return x; } -bool add_edge_h(connection_t *c, const char *request) { +bool add_edge_h(connection_t *c) { edge_t *e; node_t *from, *to; char from_name[MAX_STRING_SIZE]; char to_name[MAX_STRING_SIZE]; char to_address[MAX_STRING_SIZE]; char to_port[MAX_STRING_SIZE]; - char address_local[MAX_STRING_SIZE]; - char port_local[MAX_STRING_SIZE]; - sockaddr_t address, local_address = {0}; + sockaddr_t address; uint32_t options; int weight; - int parameter_count = sscanf(request, "%*d %*x "MAX_STRING" "MAX_STRING" "MAX_STRING" "MAX_STRING" %x %d "MAX_STRING" "MAX_STRING, - from_name, to_name, to_address, to_port, &options, &weight, address_local, port_local); - - if(parameter_count != 6 && parameter_count != 8) { - logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "ADD_EDGE", c->name, + if(sscanf(c->buffer, "%*d %*x "MAX_STRING" "MAX_STRING" "MAX_STRING" "MAX_STRING" %x %d", + from_name, to_name, to_address, to_port, &options, &weight) != 6) { + logger(LOG_ERR, "Got bad %s from %s (%s)", "ADD_EDGE", c->name, c->hostname); return false; } @@ -86,12 +71,12 @@ bool add_edge_h(connection_t *c, const char *request) { /* Check if names are valid */ if(!check_id(from_name) || !check_id(to_name) || !strcmp(from_name, to_name)) { - logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s): %s", "ADD_EDGE", c->name, + logger(LOG_ERR, "Got bad %s from %s (%s): %s", "ADD_EDGE", c->name, c->hostname, "invalid name"); return false; } - if(seen_request(request)) { + if(seen_request(c->buffer)) { return true; } @@ -104,9 +89,9 @@ bool add_edge_h(connection_t *c, const char *request) { from != myself && from != c->node && to != myself && to != c->node) { /* ignore indirect edge registrations for tunnelserver */ - logger(DEBUG_PROTOCOL, LOG_WARNING, - "Ignoring indirect %s from %s (%s)", - "ADD_EDGE", c->name, c->hostname); + ifdebug(PROTOCOL) logger(LOG_WARNING, + "Ignoring indirect %s from %s (%s)", + "ADD_EDGE", c->name, c->hostname); return true; } @@ -127,88 +112,63 @@ bool add_edge_h(connection_t *c, const char *request) { address = str2sockaddr(to_address, to_port); - if(parameter_count >= 8) { - local_address = str2sockaddr(address_local, port_local); - } - /* Check if edge already exists */ e = lookup_edge(from, to); if(e) { - bool new_address = sockaddrcmp(&e->address, &address); - // local_address.sa.sa_family will be 0 if we got it from older tinc versions - // local_address.sa.sa_family will be 255 (AF_UNKNOWN) if we got it from newer versions - // but for edge which does not have local_address - bool new_local_address = local_address.sa.sa_family && local_address.sa.sa_family != AF_UNKNOWN && - sockaddrcmp(&e->local_address, &local_address); + if(e->weight != weight || e->options != options || sockaddrcmp(&e->address, &address)) { + if(from == myself) { + ifdebug(PROTOCOL) logger(LOG_WARNING, "Got %s from %s (%s) for ourself which does not match existing entry", + "ADD_EDGE", c->name, c->hostname); + send_add_edge(c, e); + return true; + } else { + ifdebug(PROTOCOL) logger(LOG_WARNING, "Got %s from %s (%s) which does not match existing entry", + "ADD_EDGE", c->name, c->hostname); + e->options = options; - if(e->weight == weight && e->options == options && !new_address && !new_local_address) { - sockaddrfree(&address); - sockaddrfree(&local_address); - return true; - } + if(sockaddrcmp(&e->address, &address)) { + sockaddrfree(&e->address); + e->address = address; + } - if(from == myself) { - logger(DEBUG_PROTOCOL, LOG_WARNING, "Got %s from %s (%s) for ourself which does not match existing entry", - "ADD_EDGE", c->name, c->hostname); - send_add_edge(c, e); - sockaddrfree(&address); - sockaddrfree(&local_address); - return true; - } + if(e->weight != weight) { + avl_node_t *node = avl_unlink(edge_weight_tree, e); + e->weight = weight; + avl_insert_node(edge_weight_tree, node); + } - logger(DEBUG_PROTOCOL, LOG_WARNING, "Got %s from %s (%s) which does not match existing entry", - "ADD_EDGE", c->name, c->hostname); - - e->options = options; - - if(new_address) { - sockaddrfree(&e->address); - e->address = address; + goto done; + } } else { - sockaddrfree(&address); - } - - if(new_local_address) { - sockaddrfree(&e->local_address); - e->local_address = local_address; - } else { - sockaddrfree(&local_address); - } - - if(e->weight != weight) { - splay_node_t *node = splay_unlink(edge_weight_tree, e); - e->weight = weight; - splay_insert_node(edge_weight_tree, node); + return true; } } else if(from == myself) { - logger(DEBUG_PROTOCOL, LOG_WARNING, "Got %s from %s (%s) for ourself which does not exist", - "ADD_EDGE", c->name, c->hostname); + ifdebug(PROTOCOL) logger(LOG_WARNING, "Got %s from %s (%s) for ourself which does not exist", + "ADD_EDGE", c->name, c->hostname); contradicting_add_edge++; e = new_edge(); e->from = from; e->to = to; send_del_edge(c, e); free_edge(e); - sockaddrfree(&address); - sockaddrfree(&local_address); return true; - } else { - e = new_edge(); - e->from = from; - e->to = to; - e->address = address; - e->local_address = local_address; - e->options = options; - e->weight = weight; - edge_add(e); } + e = new_edge(); + e->from = from; + e->to = to; + e->address = address; + e->options = options; + e->weight = weight; + edge_add(e); + +done: /* Tell the rest about the new edge */ if(!tunnelserver) { - forward_request(c, request); + forward_request(c); } /* Run MST before or after we tell the rest? */ @@ -223,14 +183,14 @@ bool send_del_edge(connection_t *c, const edge_t *e) { e->from->name, e->to->name); } -bool del_edge_h(connection_t *c, const char *request) { +bool del_edge_h(connection_t *c) { edge_t *e; char from_name[MAX_STRING_SIZE]; char to_name[MAX_STRING_SIZE]; node_t *from, *to; - if(sscanf(request, "%*d %*x "MAX_STRING" "MAX_STRING, from_name, to_name) != 2) { - logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "DEL_EDGE", c->name, + if(sscanf(c->buffer, "%*d %*x "MAX_STRING" "MAX_STRING, from_name, to_name) != 2) { + logger(LOG_ERR, "Got bad %s from %s (%s)", "DEL_EDGE", c->name, c->hostname); return false; } @@ -238,12 +198,12 @@ bool del_edge_h(connection_t *c, const char *request) { /* Check if names are valid */ if(!check_id(from_name) || !check_id(to_name) || !strcmp(from_name, to_name)) { - logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s): %s", "DEL_EDGE", c->name, + logger(LOG_ERR, "Got bad %s from %s (%s): %s", "DEL_EDGE", c->name, c->hostname, "invalid name"); return false; } - if(seen_request(request)) { + if(seen_request(c->buffer)) { return true; } @@ -256,21 +216,21 @@ bool del_edge_h(connection_t *c, const char *request) { from != myself && from != c->node && to != myself && to != c->node) { /* ignore indirect edge registrations for tunnelserver */ - logger(DEBUG_PROTOCOL, LOG_WARNING, - "Ignoring indirect %s from %s (%s)", - "DEL_EDGE", c->name, c->hostname); + ifdebug(PROTOCOL) logger(LOG_WARNING, + "Ignoring indirect %s from %s (%s)", + "DEL_EDGE", c->name, c->hostname); return true; } if(!from) { - logger(DEBUG_PROTOCOL, LOG_ERR, "Got %s from %s (%s) which does not appear in the edge tree", - "DEL_EDGE", c->name, c->hostname); + ifdebug(PROTOCOL) logger(LOG_ERR, "Got %s from %s (%s) which does not appear in the edge tree", + "DEL_EDGE", c->name, c->hostname); return true; } if(!to) { - logger(DEBUG_PROTOCOL, LOG_ERR, "Got %s from %s (%s) which does not appear in the edge tree", - "DEL_EDGE", c->name, c->hostname); + ifdebug(PROTOCOL) logger(LOG_ERR, "Got %s from %s (%s) which does not appear in the edge tree", + "DEL_EDGE", c->name, c->hostname); return true; } @@ -279,14 +239,14 @@ bool del_edge_h(connection_t *c, const char *request) { e = lookup_edge(from, to); if(!e) { - logger(DEBUG_PROTOCOL, LOG_WARNING, "Got %s from %s (%s) which does not appear in the edge tree", - "DEL_EDGE", c->name, c->hostname); + ifdebug(PROTOCOL) logger(LOG_WARNING, "Got %s from %s (%s) which does not appear in the edge tree", + "DEL_EDGE", c->name, c->hostname); return true; } if(e->from == myself) { - logger(DEBUG_PROTOCOL, LOG_WARNING, "Got %s from %s (%s) for ourself", - "DEL_EDGE", c->name, c->hostname); + ifdebug(PROTOCOL) logger(LOG_WARNING, "Got %s from %s (%s) for ourself", + "DEL_EDGE", c->name, c->hostname); contradicting_del_edge++; send_add_edge(c, e); /* Send back a correction */ return true; @@ -295,7 +255,7 @@ bool del_edge_h(connection_t *c, const char *request) { /* Tell the rest about the deleted edge */ if(!tunnelserver) { - forward_request(c, request); + forward_request(c); } /* Delete the edge */ diff --git a/src/protocol_key.c b/src/protocol_key.c index 58a3bd2..6140a53 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-2017 Guus Sliepen + 2000-2016 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 @@ -20,264 +20,102 @@ #include "system.h" -#include "cipher.h" +#include +#include +#include + +#include "avl_tree.h" #include "connection.h" -#include "crypto.h" #include "logger.h" #include "net.h" #include "netutl.h" #include "node.h" -#include "prf.h" #include "protocol.h" -#include "route.h" -#include "sptps.h" #include "utils.h" #include "xalloc.h" static bool mykeyused = false; void send_key_changed(void) { -#ifndef DISABLE_LEGACY + avl_node_t *node; + connection_t *c; + send_request(everyone, "%d %x %s", KEY_CHANGED, rand(), myself->name); /* Immediately send new keys to directly connected nodes to keep UDP mappings alive */ - for list_each(connection_t, c, connection_list) - if(c->edge && c->node && c->node->status.reachable && !c->node->status.sptps) { + 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); } - -#endif - - /* Force key exchange for connections using SPTPS */ - - if(experimental) { - for splay_each(node_t, n, node_tree) - if(n->status.reachable && n->status.validkey && n->status.sptps) { - sptps_force_kex(&n->sptps); - } } } -bool key_changed_h(connection_t *c, const char *request) { +bool key_changed_h(connection_t *c) { char name[MAX_STRING_SIZE]; node_t *n; - if(sscanf(request, "%*d %*x " MAX_STRING, name) != 1) { - logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "KEY_CHANGED", + if(sscanf(c->buffer, "%*d %*x " MAX_STRING, name) != 1) { + logger(LOG_ERR, "Got bad %s from %s (%s)", "KEY_CHANGED", c->name, c->hostname); return false; } - if(seen_request(request)) { + 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; } n = lookup_node(name); if(!n) { - logger(DEBUG_ALWAYS, LOG_ERR, "Got %s from %s (%s) origin %s which does not exist", + logger(LOG_ERR, "Got %s from %s (%s) origin %s which does not exist", "KEY_CHANGED", c->name, c->hostname, name); return true; } - if(!n->status.sptps) { - n->status.validkey = false; - n->last_req_key = 0; - } + n->status.validkey = false; + n->last_req_key = 0; /* Tell the others */ if(!tunnelserver) { - forward_request(c, request); + forward_request(c); } return true; } -static bool send_sptps_data_myself(void *handle, uint8_t type, const void *data, size_t len) { - return send_sptps_data(handle, myself, type, data, len); -} - -static bool send_initial_sptps_data(void *handle, uint8_t type, const void *data, size_t len) { - (void)type; - node_t *to = handle; - to->sptps.send_data = send_sptps_data_myself; - char buf[len * 4 / 3 + 5]; - - b64encode(data, buf, len); - - return send_request(to->nexthop->connection, "%d %s %s %d %s", REQ_KEY, myself->name, to->name, REQ_KEY, buf); -} - bool send_req_key(node_t *to) { - if(to->status.sptps) { - if(!node_read_ecdsa_public_key(to)) { - logger(DEBUG_PROTOCOL, LOG_DEBUG, "No Ed25519 key known for %s (%s)", to->name, to->hostname); - send_request(to->nexthop->connection, "%d %s %s %d", REQ_KEY, myself->name, to->name, REQ_PUBKEY); - return true; - } - - char label[25 + strlen(myself->name) + strlen(to->name)]; - snprintf(label, sizeof(label), "tinc UDP key expansion %s %s", myself->name, to->name); - sptps_stop(&to->sptps); - to->status.validkey = false; - to->status.waitingforkey = true; - to->last_req_key = now.tv_sec; - to->incompression = myself->incompression; - return sptps_start(&to->sptps, to, true, true, myself->connection->ecdsa, to->ecdsa, label, sizeof(label), send_initial_sptps_data, receive_sptps_record); - } - return send_request(to->nexthop->connection, "%d %s %s", REQ_KEY, myself->name, to->name); } -/* REQ_KEY is overloaded to allow arbitrary requests to be routed between two nodes. */ - -static bool req_key_ext_h(connection_t *c, const char *request, node_t *from, node_t *to, int reqno) { - (void)c; - - /* If this is a SPTPS packet, see if sending UDP info helps. - Note that we only do this if we're the destination or the static relay; - otherwise every hop would initiate its own UDP info message, resulting in elevated chatter. */ - if((reqno == REQ_KEY || reqno == SPTPS_PACKET) && to->via == myself) { - send_udp_info(myself, from); - } - - if(reqno == SPTPS_PACKET) { - /* This is a SPTPS data packet. */ - - char buf[MAX_STRING_SIZE]; - int len; - - if(sscanf(request, "%*d %*s %*s %*d " MAX_STRING, buf) != 1 || !(len = b64decode(buf, buf, strlen(buf)))) { - logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s) to %s (%s): %s", "SPTPS_PACKET", from->name, from->hostname, to->name, to->hostname, "invalid SPTPS data"); - return true; - } - - if(to != myself) { - /* We don't just forward the request, because we want to use UDP if it's available. */ - if(forwarding_mode == FMODE_INTERNAL) { - send_sptps_data(to, from, 0, buf, len); - try_tx(to, true); - } - } else { - /* The packet is for us */ - if(!sptps_receive_data(&from->sptps, buf, len)) { - /* Uh-oh. It might be that the tunnel is stuck in some corrupted state, - so let's restart SPTPS in case that helps. But don't do that too often - to prevent storms. */ - if(from->last_req_key < now.tv_sec - 10) { - logger(DEBUG_PROTOCOL, LOG_ERR, "Failed to decode TCP packet from %s (%s), restarting SPTPS", from->name, from->hostname); - send_req_key(from); - } - - return true; - } - - send_mtu_info(myself, from, MTU); - } - - return true; - } - - /* Requests that are not SPTPS data packets are forwarded as-is. */ - - if(to != myself) { - return send_request(to->nexthop->connection, "%s", request); - } - - /* The request is for us */ - - switch(reqno) { - case REQ_PUBKEY: { - if(!node_read_ecdsa_public_key(from)) { - /* Request their key *before* we send our key back. Otherwise the first SPTPS packet from them will get dropped. */ - logger(DEBUG_PROTOCOL, LOG_DEBUG, "Preemptively requesting Ed25519 key for %s (%s)", from->name, from->hostname); - send_request(from->nexthop->connection, "%d %s %s %d", REQ_KEY, myself->name, from->name, REQ_PUBKEY); - } - - char *pubkey = ecdsa_get_base64_public_key(myself->connection->ecdsa); - send_request(from->nexthop->connection, "%d %s %s %d %s", REQ_KEY, myself->name, from->name, ANS_PUBKEY, pubkey); - free(pubkey); - return true; - } - - case ANS_PUBKEY: { - if(node_read_ecdsa_public_key(from)) { - logger(DEBUG_PROTOCOL, LOG_WARNING, "Got ANS_PUBKEY from %s (%s) even though we already have his pubkey", from->name, from->hostname); - return true; - } - - char pubkey[MAX_STRING_SIZE]; - - if(sscanf(request, "%*d %*s %*s %*d " MAX_STRING, pubkey) != 1 || !(from->ecdsa = ecdsa_set_base64_public_key(pubkey))) { - logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s): %s", "ANS_PUBKEY", from->name, from->hostname, "invalid pubkey"); - return true; - } - - logger(DEBUG_PROTOCOL, LOG_INFO, "Learned Ed25519 public key from %s (%s)", from->name, from->hostname); - append_config_file(from->name, "Ed25519PublicKey", pubkey); - return true; - } - - case REQ_KEY: { - if(!node_read_ecdsa_public_key(from)) { - logger(DEBUG_PROTOCOL, LOG_DEBUG, "No Ed25519 key known for %s (%s)", from->name, from->hostname); - send_request(from->nexthop->connection, "%d %s %s %d", REQ_KEY, myself->name, from->name, REQ_PUBKEY); - return true; - } - - if(from->sptps.label) { - logger(DEBUG_ALWAYS, LOG_DEBUG, "Got REQ_KEY from %s while we already started a SPTPS session!", from->name); - } - - char buf[MAX_STRING_SIZE]; - size_t len; - - if(sscanf(request, "%*d %*s %*s %*d " MAX_STRING, buf) != 1 || !(len = b64decode(buf, buf, strlen(buf)))) { - logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s): %s", "REQ_SPTPS_START", from->name, from->hostname, "invalid SPTPS data"); - return true; - } - - char label[25 + strlen(from->name) + strlen(myself->name)]; - snprintf(label, sizeof(label), "tinc UDP key expansion %s %s", from->name, myself->name); - sptps_stop(&from->sptps); - from->status.validkey = false; - from->status.waitingforkey = true; - from->last_req_key = now.tv_sec; - sptps_start(&from->sptps, from, false, true, myself->connection->ecdsa, from->ecdsa, label, sizeof(label), send_sptps_data_myself, receive_sptps_record); - sptps_receive_data(&from->sptps, buf, len); - send_mtu_info(myself, from, MTU); - return true; - } - - default: - logger(DEBUG_ALWAYS, LOG_ERR, "Unknown extended REQ_KEY request from %s (%s): %s", from->name, from->hostname, request); - return true; - } -} - -bool req_key_h(connection_t *c, const char *request) { +bool req_key_h(connection_t *c) { char from_name[MAX_STRING_SIZE]; char to_name[MAX_STRING_SIZE]; node_t *from, *to; - int reqno = 0; - if(sscanf(request, "%*d " MAX_STRING " " MAX_STRING " %d", from_name, to_name, &reqno) < 2) { - logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "REQ_KEY", c->name, + if(sscanf(c->buffer, "%*d " MAX_STRING " " MAX_STRING, from_name, to_name) != 2) { + logger(LOG_ERR, "Got bad %s from %s (%s)", "REQ_KEY", c->name, c->hostname); return false; } if(!check_id(from_name) || !check_id(to_name)) { - logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s): %s", "REQ_KEY", c->name, c->hostname, "invalid 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(DEBUG_ALWAYS, LOG_ERR, "Got %s from %s (%s) origin %s which does not exist in our connection list", + 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 true; } @@ -285,108 +123,77 @@ bool req_key_h(connection_t *c, const char *request) { to = lookup_node(to_name); if(!to) { - logger(DEBUG_ALWAYS, LOG_ERR, "Got %s from %s (%s) destination %s which does not exist in our connection list", + 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 true; } /* Check if this key request is for us */ - if(to == myself) { /* Yes */ - /* Is this an extended REQ_KEY message? */ - if(experimental && reqno) { - return req_key_ext_h(c, request, from, to, reqno); + if(to == myself) { /* Yes, send our own key back */ + if(!send_ans_key(from)) { + return false; } - - /* No, just send our key back */ - send_ans_key(from); } else { if(tunnelserver) { return true; } if(!to->status.reachable) { - logger(DEBUG_PROTOCOL, LOG_WARNING, "Got %s from %s (%s) destination %s which is not reachable", + logger(LOG_WARNING, "Got %s from %s (%s) destination %s which is not reachable", "REQ_KEY", c->name, c->hostname, to_name); return true; } - /* Is this an extended REQ_KEY message? */ - if(experimental && reqno) { - return req_key_ext_h(c, request, from, to, reqno); - } - - send_request(to->nexthop->connection, "%s", request); + send_request(to->nexthop->connection, "%s", c->buffer); } return true; } bool send_ans_key(node_t *to) { - if(to->status.sptps) { - abort(); - } - -#ifdef DISABLE_LEGACY - return false; -#else - size_t keylen = myself->incipher ? cipher_keylength(myself->incipher) : 1; - char key[keylen * 2 + 1]; - - randomize(key, keylen); - - cipher_close(to->incipher); - digest_close(to->indigest); - - if(myself->incipher) { - to->incipher = cipher_open_by_nid(cipher_get_nid(myself->incipher)); - - if(!to->incipher) { - abort(); - } - - if(!cipher_set_key(to->incipher, key, false)) { - abort(); - } - } - - if(myself->indigest) { - to->indigest = digest_open_by_nid(digest_get_nid(myself->indigest), digest_length(myself->indigest)); - - if(!to->indigest) { - abort(); - } - - if(!digest_set_key(to->indigest, key, keylen)) { - abort(); - } - } - + // Set key parameters + to->incipher = myself->incipher; + to->inkeylength = myself->inkeylength; + to->indigest = myself->indigest; + to->inmaclength = myself->inmaclength; to->incompression = myself->incompression; - bin2hex(key, key, keylen); + // Allocate memory for key + to->inkey = xrealloc(to->inkey, to->inkeylength); + + // Create a new key + if(1 != RAND_bytes((unsigned char *)to->inkey, to->inkeylength)) { + int err = ERR_get_error(); + logger(LOG_ERR, "Failed to generate random for key (%s)", ERR_error_string(err, NULL)); + return false; // Do not send insecure keys, let connection attempt fail. + } + + if(to->incipher) { + EVP_DecryptInit_ex(to->inctx, to->incipher, NULL, (unsigned char *)to->inkey, (unsigned char *)to->inkey + EVP_CIPHER_key_length(to->incipher)); + } // Reset sequence number and late packet window mykeyused = true; to->received_seqno = 0; - to->received = 0; if(replaywin) { memset(to->late, 0, replaywin); } - to->status.validkey_in = true; + // Convert to hexadecimal and send + char key[2 * to->inkeylength + 1]; + bin2hex(to->inkey, key, to->inkeylength); + key[to->inkeylength * 2] = '\0'; return send_request(to->nexthop->connection, "%d %s %s %s %d %d %d %d", ANS_KEY, myself->name, to->name, key, - cipher_get_nid(to->incipher), - digest_get_nid(to->indigest), - (int)digest_length(to->indigest), + to->incipher ? EVP_CIPHER_nid(to->incipher) : 0, + to->indigest ? EVP_MD_type(to->indigest) : 0, to->inmaclength, to->incompression); -#endif } -bool ans_key_h(connection_t *c, const char *request) { +bool ans_key_h(connection_t *c) { char from_name[MAX_STRING_SIZE]; char to_name[MAX_STRING_SIZE]; char key[MAX_STRING_SIZE]; @@ -395,23 +202,23 @@ bool ans_key_h(connection_t *c, const char *request) { int cipher, digest, maclength, compression; node_t *from, *to; - if(sscanf(request, "%*d "MAX_STRING" "MAX_STRING" "MAX_STRING" %d %d %d %d "MAX_STRING" "MAX_STRING, + 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, address, port) < 7) { - logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "ANS_KEY", c->name, + 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(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s): %s", "ANS_KEY", c->name, c->hostname, "invalid 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(DEBUG_ALWAYS, LOG_ERR, "Got %s from %s (%s) origin %s which does not exist in our connection list", + 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 true; } @@ -419,7 +226,7 @@ bool ans_key_h(connection_t *c, const char *request) { to = lookup_node(to_name); if(!to) { - logger(DEBUG_ALWAYS, LOG_ERR, "Got %s from %s (%s) destination %s which does not exist in our connection list", + 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 true; } @@ -432,131 +239,107 @@ bool ans_key_h(connection_t *c, const char *request) { } if(!to->status.reachable) { - logger(DEBUG_ALWAYS, LOG_WARNING, "Got %s from %s (%s) destination %s which is not reachable", + logger(LOG_WARNING, "Got %s from %s (%s) destination %s which is not reachable", "ANS_KEY", c->name, c->hostname, to_name); return true; } if(!*address && from->address.sa.sa_family != AF_UNSPEC && to->minmtu) { char *address, *port; - logger(DEBUG_PROTOCOL, LOG_DEBUG, "Appending reflexive UDP address to ANS_KEY from %s to %s", from->name, to->name); + 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", request, 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", request); + return send_request(to->nexthop->connection, "%s", c->buffer); } -#ifndef DISABLE_LEGACY /* Don't use key material until every check has passed. */ - cipher_close(from->outcipher); - digest_close(from->outdigest); -#endif + from->status.validkey = false; - if(!from->status.sptps) { - from->status.validkey = false; - } + /* Update our copy of the origin's packet key */ + from->outkey = xrealloc(from->outkey, strlen(key) / 2); + from->outkeylength = strlen(key) / 2; - if(compression < 0 || compression > 11) { - logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses bogus compression level!", from->name, from->hostname); + if(!hex2bin(key, from->outkey, from->outkeylength)) { + logger(LOG_ERR, "Got bad %s from %s(%s): %s", "ANS_KEY", from->name, from->hostname, "invalid key"); return true; } - from->outcompression = compression; - - /* SPTPS or old-style key exchange? */ - - if(from->status.sptps) { - char buf[strlen(key)]; - size_t len = b64decode(key, buf, strlen(key)); - - if(!len || !sptps_receive_data(&from->sptps, buf, len)) { - /* Uh-oh. It might be that the tunnel is stuck in some corrupted state, - so let's restart SPTPS in case that helps. But don't do that too often - to prevent storms. - Note that simply relying on handshake timeout is not enough, because - that doesn't apply to key regeneration. */ - if(from->last_req_key < now.tv_sec - 10) { - logger(DEBUG_PROTOCOL, LOG_ERR, "Failed to decode handshake TCP packet from %s (%s), restarting SPTPS", from->name, from->hostname); - send_req_key(from); - } - - return true; - } - - if(from->status.validkey) { - if(*address && *port) { - logger(DEBUG_PROTOCOL, 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); - } - } - - send_mtu_info(myself, from, MTU); - - return true; - } - -#ifdef DISABLE_LEGACY - logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses legacy protocol!", from->name, from->hostname); - return false; -#else /* Check and lookup cipher and digest algorithms */ if(cipher) { - if(!(from->outcipher = cipher_open_by_nid(cipher))) { - logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses unknown cipher!", from->name, from->hostname); - return false; + from->outcipher = EVP_get_cipherbynid(cipher); + + if(!from->outcipher) { + logger(LOG_ERR, "Node %s (%s) uses unknown cipher!", from->name, + from->hostname); + return true; + } + + if(from->outkeylength != EVP_CIPHER_key_length(from->outcipher) + EVP_CIPHER_iv_length(from->outcipher)) { + logger(LOG_ERR, "Node %s (%s) uses wrong keylength!", from->name, + from->hostname); + return true; } } else { + if(from->outkeylength != 1) { + logger(LOG_ERR, "Node %s (%s) uses wrong keylength!", from->name, from->hostname); + return true; + } + from->outcipher = NULL; } + from->outmaclength = maclength; + if(digest) { - if(!(from->outdigest = digest_open_by_nid(digest, maclength))) { - logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses unknown digest!", from->name, from->hostname); - return false; + from->outdigest = EVP_get_digestbynid(digest); + + if(!from->outdigest) { + logger(LOG_ERR, "Node %s (%s) uses unknown digest!", from->name, + from->hostname); + return true; + } + + if(from->outmaclength > EVP_MD_size(from->outdigest) || from->outmaclength < 0) { + logger(LOG_ERR, "Node %s (%s) uses bogus MAC length!", + from->name, from->hostname); + return true; } } else { from->outdigest = NULL; } - if((size_t)maclength != digest_length(from->outdigest)) { - logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses bogus MAC length!", from->name, from->hostname); - return false; - } - - /* Process key */ - - size_t keylen = hex2bin(key, key, sizeof(key)); - - if(keylen != (from->outcipher ? cipher_keylength(from->outcipher) : 1)) { - logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses wrong keylength!", from->name, from->hostname); + if(compression < 0 || compression > 11) { + logger(LOG_ERR, "Node %s (%s) uses bogus compression level!", from->name, from->hostname); return true; } - /* Update our copy of the origin's packet key */ + from->outcompression = compression; - if(from->outcipher && !cipher_set_key(from->outcipher, key, true)) { - return false; - } - - if(from->outdigest && !digest_set_key(from->outdigest, key, keylen)) { - return false; - } + if(from->outcipher) + if(!EVP_EncryptInit_ex(from->outctx, from->outcipher, NULL, (unsigned char *)from->outkey, (unsigned char *)from->outkey + EVP_CIPHER_key_length(from->outcipher))) { + logger(LOG_ERR, "Error during initialisation of key from %s (%s): %s", + from->name, from->hostname, ERR_error_string(ERR_get_error(), NULL)); + return true; + } from->status.validkey = true; from->sent_seqno = 0; if(*address && *port) { - logger(DEBUG_PROTOCOL, LOG_DEBUG, "Using reflexive UDP address from %s: %s port %s", from->name, 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->mtuevent) { + send_mtu_probe(from); + } + return true; -#endif } diff --git a/src/protocol_misc.c b/src/protocol_misc.c index a4fcd6f..904ac3f 100644 --- a/src/protocol_misc.c +++ b/src/protocol_misc.c @@ -1,7 +1,7 @@ /* protocol_misc.c -- handle the meta-protocol, miscellaneous functions Copyright (C) 1999-2005 Ivo Timmermans, - 2000-2013 Guus Sliepen + 2000-2012 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 @@ -20,7 +20,6 @@ #include "system.h" -#include "address_cache.h" #include "conf.h" #include "connection.h" #include "logger.h" @@ -29,35 +28,17 @@ #include "netutl.h" #include "protocol.h" #include "utils.h" -#include "xalloc.h" - -#ifndef MIN -#define MIN(x, y) (((x)<(y))?(x):(y)) -#endif int maxoutbufsize = 0; -int mtu_info_interval = 5; -int udp_info_interval = 5; - -bool send_termreq(connection_t *c) { - return send_request(c, "%d", TERMREQ); -} - -bool termreq_h(connection_t *c, const char *request) { - (void)c; - (void)request; - return false; -} bool send_ping(connection_t *c) { c->status.pinged = true; - c->last_ping_time = now.tv_sec; + c->last_ping_time = now; return send_request(c, "%d", PING); } -bool ping_h(connection_t *c, const char *request) { - (void)request; +bool ping_h(connection_t *c) { return send_pong(c); } @@ -65,15 +46,21 @@ bool send_pong(connection_t *c) { return send_request(c, "%d", PONG); } -bool pong_h(connection_t *c, const char *request) { - (void)request; +bool pong_h(connection_t *c) { c->status.pinged = false; /* Successful connection, reset timeout if this is an outgoing connection. */ if(c->outgoing) { c->outgoing->timeout = 0; - reset_address_cache(c->outgoing->address_cache, &c->address); + c->outgoing->cfg = NULL; + + if(c->outgoing->ai) { + freeaddrinfo(c->outgoing->ai); + } + + c->outgoing->ai = NULL; + c->outgoing->aip = NULL; } return true; @@ -85,22 +72,22 @@ bool send_tcppacket(connection_t *c, const vpn_packet_t *packet) { /* If there already is a lot of data in the outbuf buffer, discard this packet. We use a very simple Random Early Drop algorithm. */ - if(2.0 * c->outbuf.len / (float)maxoutbufsize - 1 > (float)rand() / (float)RAND_MAX) { + if(2.0 * c->outbuflen / (float)maxoutbufsize - 1 > (float)rand() / (float)RAND_MAX) { return true; } - if(!send_request(c, "%d %d", PACKET, packet->len)) { + if(!send_request(c, "%d %hd", PACKET, packet->len)) { return false; } - return send_meta(c, (char *)DATA(packet), packet->len); + return send_meta(c, (char *)packet->data, packet->len) && flush_meta(c); } -bool tcppacket_h(connection_t *c, const char *request) { - short int len; +bool tcppacket_h(connection_t *c) { + length_t len; - if(sscanf(request, "%*d %hd", &len) != 1) { - logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "PACKET", c->name, + if(sscanf(c->buffer, "%*d %hu", &len) != 1) { + logger(LOG_ERR, "Got bad %s from %s (%s)", "PACKET", c->name, c->hostname); return false; } @@ -111,260 +98,3 @@ bool tcppacket_h(connection_t *c, const char *request) { return true; } - -bool send_sptps_tcppacket(connection_t *c, const char *packet, int len) { - /* If there already is a lot of data in the outbuf buffer, discard this packet. - We use a very simple Random Early Drop algorithm. */ - - if(2.0 * c->outbuf.len / (float)maxoutbufsize - 1 > (float)rand() / (float)RAND_MAX) { - return true; - } - - if(!send_request(c, "%d %d", SPTPS_PACKET, len)) { - return false; - } - - send_meta_raw(c, packet, len); - return true; -} - -bool sptps_tcppacket_h(connection_t *c, const char *request) { - short int len; - - if(sscanf(request, "%*d %hd", &len) != 1) { - logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "SPTPS_PACKET", c->name, - c->hostname); - return false; - } - - /* Set sptpslen to len, this will tell receive_meta() that a SPTPS packet is coming. */ - - c->sptpslen = len; - - return true; -} - -/* Transmitting UDP information */ - -bool send_udp_info(node_t *from, node_t *to) { - /* If there's a static relay in the path, there's no point in sending the message - farther than the static relay. */ - to = (to->via == myself) ? to->nexthop : to->via; - - if(to == NULL) { - logger(DEBUG_ALWAYS, LOG_ERR, "Something went wrong when selecting relay - possible fake UDP_INFO"); - return false; - } - - /* Skip cases where sending UDP info messages doesn't make sense. - This is done here in order to avoid repeating the same logic in multiple callsites. */ - - if(to == myself) { - return true; - } - - if(!to->status.reachable) { - return true; - } - - if(from == myself) { - if(to->connection) { - return true; - } - - struct timeval elapsed; - - timersub(&now, &to->udp_info_sent, &elapsed); - - if(elapsed.tv_sec < udp_info_interval) { - return true; - } - } - - if((myself->options | from->options | to->options) & OPTION_TCPONLY) { - return true; - } - - if((to->nexthop->options >> 24) < 5) { - return true; - } - - char *from_address, *from_port; - /* If we're the originator, the address we use is irrelevant - because the first intermediate node will ignore it. - We use our local address as it somewhat makes sense - and it's simpler than introducing an encoding for "null" addresses anyway. */ - sockaddr2str((from != myself) ? &from->address : &to->nexthop->connection->edge->local_address, &from_address, &from_port); - - bool x = send_request(to->nexthop->connection, "%d %s %s %s %s", UDP_INFO, from->name, to->name, from_address, from_port); - - free(from_address); - free(from_port); - - if(from == myself) { - to->udp_info_sent = now; - } - - return x; -} - -bool udp_info_h(connection_t *c, const char *request) { - char from_name[MAX_STRING_SIZE]; - char to_name[MAX_STRING_SIZE]; - char from_address[MAX_STRING_SIZE]; - char from_port[MAX_STRING_SIZE]; - - if(sscanf(request, "%*d "MAX_STRING" "MAX_STRING" "MAX_STRING" "MAX_STRING, from_name, to_name, from_address, from_port) != 4) { - logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "UDP_INFO", c->name, c->hostname); - return false; - } - - if(!check_id(from_name) || !check_id(to_name)) { - logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s): %s", "UDP_INFO", c->name, c->hostname, "invalid name"); - return false; - } - - node_t *from = lookup_node(from_name); - - if(!from) { - logger(DEBUG_ALWAYS, LOG_ERR, "Got %s from %s (%s) origin %s which does not exist in our connection list", "UDP_INFO", c->name, c->hostname, from_name); - return true; - } - - if(from != from->via) { - /* Not supposed to happen, as it means the message wandered past a static relay */ - logger(DEBUG_PROTOCOL, LOG_WARNING, "Got UDP info message from %s (%s) which we can't reach directly", from->name, from->hostname); - return true; - } - - /* If we have a direct edge to "from", we are in a better position - to guess its address than it is itself. */ - if(!from->connection && !from->status.udp_confirmed) { - sockaddr_t from_addr = str2sockaddr(from_address, from_port); - - if(sockaddrcmp(&from_addr, &from->address)) { - update_node_udp(from, &from_addr); - } - } - - node_t *to = lookup_node(to_name); - - if(!to) { - logger(DEBUG_ALWAYS, LOG_ERR, "Got %s from %s (%s) destination %s which does not exist in our connection list", "UDP_INFO", c->name, c->hostname, to_name); - return true; - } - - /* Send our own data (which could be what we just received) up the chain. */ - - return send_udp_info(from, to); -} - -/* Transmitting MTU information */ - -bool send_mtu_info(node_t *from, node_t *to, int mtu) { - /* Skip cases where sending MTU info messages doesn't make sense. - This is done here in order to avoid repeating the same logic in multiple callsites. */ - - if(to == myself) { - return true; - } - - if(!to->status.reachable) { - return true; - } - - if(from == myself) { - if(to->connection) { - return true; - } - - struct timeval elapsed; - - timersub(&now, &to->mtu_info_sent, &elapsed); - - if(elapsed.tv_sec < mtu_info_interval) { - return true; - } - } - - if((to->nexthop->options >> 24) < 6) { - return true; - } - - /* We will send the passed-in MTU value, unless we believe ours is better. */ - - node_t *via = (from->via == myself) ? from->nexthop : from->via; - - if(from->minmtu == from->maxmtu && from->via == myself) { - /* We have a direct measurement. Override the value entirely. - Note that we only do that if we are sitting as a static relay in the path; - otherwise, we can't guarantee packets will flow through us, and increasing - MTU could therefore end up being too optimistic. */ - mtu = from->minmtu; - } else if(via->minmtu == via->maxmtu) { - /* Static relay. Ensure packets will make it through the entire relay path. */ - mtu = MIN(mtu, via->minmtu); - } else if(via->nexthop->minmtu == via->nexthop->maxmtu) { - /* Dynamic relay. Ensure packets will make it through the entire relay path. */ - mtu = MIN(mtu, via->nexthop->minmtu); - } - - if(from == myself) { - to->mtu_info_sent = now; - } - - /* If none of the conditions above match in the steady state, it means we're using TCP, - so the MTU is irrelevant. That said, it is still important to honor the MTU that was passed in, - because other parts of the relay path might be able to use UDP, which means they care about the MTU. */ - - return send_request(to->nexthop->connection, "%d %s %s %d", MTU_INFO, from->name, to->name, mtu); -} - -bool mtu_info_h(connection_t *c, const char *request) { - char from_name[MAX_STRING_SIZE]; - char to_name[MAX_STRING_SIZE]; - int mtu; - - if(sscanf(request, "%*d "MAX_STRING" "MAX_STRING" %d", from_name, to_name, &mtu) != 3) { - logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "MTU_INFO", c->name, c->hostname); - return false; - } - - if(mtu < 512) { - logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s): %s", "MTU_INFO", c->name, c->hostname, "invalid MTU"); - return false; - } - - mtu = MIN(mtu, MTU); - - if(!check_id(from_name) || !check_id(to_name)) { - logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s): %s", "MTU_INFO", c->name, c->hostname, "invalid name"); - return false; - } - - node_t *from = lookup_node(from_name); - - if(!from) { - logger(DEBUG_ALWAYS, LOG_ERR, "Got %s from %s (%s) origin %s which does not exist in our connection list", "MTU_INFO", c->name, c->hostname, from_name); - return true; - } - - /* If we don't know the current MTU for that node, use the one we received. - Even if we're about to make our own measurements, the value we got from downstream nodes should be pretty close - so it's a good idea to use it in the mean time. */ - if(from->mtu != mtu && from->minmtu != from->maxmtu) { - logger(DEBUG_TRAFFIC, LOG_INFO, "Using provisional MTU %d for node %s (%s)", mtu, from->name, from->hostname); - from->mtu = mtu; - } - - node_t *to = lookup_node(to_name); - - if(!to) { - logger(DEBUG_ALWAYS, LOG_ERR, "Got %s from %s (%s) destination %s which does not exist in our connection list", "MTU_INFO", c->name, c->hostname, to_name); - return true; - } - - /* Continue passing the MTU value (or a better one if we have it) up the chain. */ - - return send_mtu_info(from, to, mtu); -} diff --git a/src/protocol_subnet.c b/src/protocol_subnet.c index 53afb8a..2c4d08f 100644 --- a/src/protocol_subnet.c +++ b/src/protocol_subnet.c @@ -1,7 +1,7 @@ /* protocol_subnet.c -- handle the meta-protocol, subnets Copyright (C) 1999-2005 Ivo Timmermans, - 2000-2012 Guus Sliepen + 2000-2009 Guus Sliepen 2009 Michael Tokarev This program is free software; you can redistribute it and/or modify @@ -42,14 +42,14 @@ bool send_add_subnet(connection_t *c, const subnet_t *subnet) { return send_request(c, "%d %x %s %s", ADD_SUBNET, rand(), subnet->owner->name, netstr); } -bool add_subnet_h(connection_t *c, const char *request) { +bool add_subnet_h(connection_t *c) { char subnetstr[MAX_STRING_SIZE]; char name[MAX_STRING_SIZE]; node_t *owner; subnet_t s = {0}, *new, *old; - if(sscanf(request, "%*d %*x " MAX_STRING " " MAX_STRING, name, subnetstr) != 2) { - logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "ADD_SUBNET", c->name, + if(sscanf(c->buffer, "%*d %*x " MAX_STRING " " MAX_STRING, name, subnetstr) != 2) { + logger(LOG_ERR, "Got bad %s from %s (%s)", "ADD_SUBNET", c->name, c->hostname); return false; } @@ -57,7 +57,7 @@ bool add_subnet_h(connection_t *c, const char *request) { /* Check if owner name is valid */ if(!check_id(name)) { - logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s): %s", "ADD_SUBNET", c->name, + logger(LOG_ERR, "Got bad %s from %s (%s): %s", "ADD_SUBNET", c->name, c->hostname, "invalid name"); return false; } @@ -65,12 +65,12 @@ bool add_subnet_h(connection_t *c, const char *request) { /* Check if subnet string is valid */ if(!str2net(&s, subnetstr)) { - logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s): %s", "ADD_SUBNET", c->name, + logger(LOG_ERR, "Got bad %s from %s (%s): %s", "ADD_SUBNET", c->name, c->hostname, "invalid subnet string"); return false; } - if(seen_request(request)) { + if(seen_request(c->buffer)) { return true; } @@ -80,8 +80,8 @@ bool add_subnet_h(connection_t *c, const char *request) { if(tunnelserver && owner != myself && owner != c->node) { /* in case of tunnelserver, ignore indirect subnet registrations */ - logger(DEBUG_PROTOCOL, LOG_WARNING, "Ignoring indirect %s from %s (%s) for %s", - "ADD_SUBNET", c->name, c->hostname, subnetstr); + ifdebug(PROTOCOL) logger(LOG_WARNING, "Ignoring indirect %s from %s (%s) for %s", + "ADD_SUBNET", c->name, c->hostname, subnetstr); return true; } @@ -100,8 +100,8 @@ bool add_subnet_h(connection_t *c, const char *request) { /* If we don't know this subnet, but we are the owner, retaliate with a DEL_SUBNET */ if(owner == myself) { - logger(DEBUG_PROTOCOL, LOG_WARNING, "Got %s from %s (%s) for ourself", - "ADD_SUBNET", c->name, c->hostname); + ifdebug(PROTOCOL) logger(LOG_WARNING, "Got %s from %s (%s) for ourself", + "ADD_SUBNET", c->name, c->hostname); s.owner = myself; send_del_subnet(c, &s); return true; @@ -110,7 +110,7 @@ bool add_subnet_h(connection_t *c, const char *request) { /* In tunnel server mode, we should already know all allowed subnets */ if(tunnelserver) { - logger(DEBUG_ALWAYS, LOG_WARNING, "Ignoring unauthorized %s from %s (%s): %s", + logger(LOG_WARNING, "Ignoring unauthorized %s from %s (%s): %s", "ADD_SUBNET", c->name, c->hostname, subnetstr); return true; } @@ -118,9 +118,9 @@ bool add_subnet_h(connection_t *c, const char *request) { /* Ignore if strictsubnets is true, but forward it to others */ if(strictsubnets) { - logger(DEBUG_ALWAYS, LOG_WARNING, "Ignoring unauthorized %s from %s (%s): %s", + logger(LOG_WARNING, "Ignoring unauthorized %s from %s (%s): %s", "ADD_SUBNET", c->name, c->hostname, subnetstr); - forward_request(c, request); + forward_request(c); return true; } @@ -135,14 +135,12 @@ bool add_subnet_h(connection_t *c, const char *request) { /* Tell the rest */ - if(!tunnelserver) { - forward_request(c, request); - } + forward_request(c); /* Fast handoff of roaming MAC addresses */ if(s.type == SUBNET_MAC && owner != myself && (old = lookup_subnet(myself, &s)) && old->expires) { - old->expires = 1; + old->expires = now; } return true; @@ -158,14 +156,14 @@ bool send_del_subnet(connection_t *c, const subnet_t *s) { return send_request(c, "%d %x %s %s", DEL_SUBNET, rand(), s->owner->name, netstr); } -bool del_subnet_h(connection_t *c, const char *request) { +bool del_subnet_h(connection_t *c) { char subnetstr[MAX_STRING_SIZE]; char name[MAX_STRING_SIZE]; node_t *owner; subnet_t s = {0}, *find; - if(sscanf(request, "%*d %*x " MAX_STRING " " MAX_STRING, name, subnetstr) != 2) { - logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "DEL_SUBNET", c->name, + if(sscanf(c->buffer, "%*d %*x " MAX_STRING " " MAX_STRING, name, subnetstr) != 2) { + logger(LOG_ERR, "Got bad %s from %s (%s)", "DEL_SUBNET", c->name, c->hostname); return false; } @@ -173,7 +171,7 @@ bool del_subnet_h(connection_t *c, const char *request) { /* Check if owner name is valid */ if(!check_id(name)) { - logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s): %s", "DEL_SUBNET", c->name, + logger(LOG_ERR, "Got bad %s from %s (%s): %s", "DEL_SUBNET", c->name, c->hostname, "invalid name"); return false; } @@ -181,12 +179,12 @@ bool del_subnet_h(connection_t *c, const char *request) { /* Check if subnet string is valid */ if(!str2net(&s, subnetstr)) { - logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s): %s", "DEL_SUBNET", c->name, + logger(LOG_ERR, "Got bad %s from %s (%s): %s", "DEL_SUBNET", c->name, c->hostname, "invalid subnet string"); return false; } - if(seen_request(request)) { + if(seen_request(c->buffer)) { return true; } @@ -196,14 +194,14 @@ bool del_subnet_h(connection_t *c, const char *request) { if(tunnelserver && owner != myself && owner != c->node) { /* in case of tunnelserver, ignore indirect subnet deletion */ - logger(DEBUG_PROTOCOL, LOG_WARNING, "Ignoring indirect %s from %s (%s) for %s", - "DEL_SUBNET", c->name, c->hostname, subnetstr); + ifdebug(PROTOCOL) logger(LOG_WARNING, "Ignoring indirect %s from %s (%s) for %s", + "DEL_SUBNET", c->name, c->hostname, subnetstr); return true; } if(!owner) { - logger(DEBUG_PROTOCOL, LOG_WARNING, "Got %s from %s (%s) for %s which is not in our node tree", - "DEL_SUBNET", c->name, c->hostname, name); + ifdebug(PROTOCOL) logger(LOG_WARNING, "Got %s from %s (%s) for %s which is not in our node tree", + "DEL_SUBNET", c->name, c->hostname, name); return true; } @@ -214,11 +212,11 @@ bool del_subnet_h(connection_t *c, const char *request) { find = lookup_subnet(owner, &s); if(!find) { - logger(DEBUG_PROTOCOL, LOG_WARNING, "Got %s from %s (%s) for %s which does not appear in his subnet tree", - "DEL_SUBNET", c->name, c->hostname, name); + 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, request); + forward_request(c); } return true; @@ -227,8 +225,8 @@ bool del_subnet_h(connection_t *c, const char *request) { /* If we are the owner of this subnet, retaliate with an ADD_SUBNET */ if(owner == myself) { - logger(DEBUG_PROTOCOL, LOG_WARNING, "Got %s from %s (%s) for ourself", - "DEL_SUBNET", c->name, c->hostname); + ifdebug(PROTOCOL) logger(LOG_WARNING, "Got %s from %s (%s) for ourself", + "DEL_SUBNET", c->name, c->hostname); send_add_subnet(c, find); return true; } @@ -239,9 +237,7 @@ bool del_subnet_h(connection_t *c, const char *request) { /* Tell the rest */ - if(!tunnelserver) { - forward_request(c, request); - } + forward_request(c); if(strictsubnets) { return true; diff --git a/src/proxy.c b/src/proxy.c new file mode 100644 index 0000000..979626c --- /dev/null +++ b/src/proxy.c @@ -0,0 +1,366 @@ +/* + proxy.c -- Proxy handling functions. + Copyright (C) 2015-2017 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "system.h" + +#include "connection.h" +#include "logger.h" +#include "meta.h" +#include "netutl.h" +#include "protocol.h" +#include "proxy.h" +#include "utils.h" // + +proxytype_t proxytype; +char *proxyhost; +char *proxyport; +char *proxyuser; +char *proxypass; + +static void update_address_ipv4(connection_t *c, void *address, void *port) { + sockaddrfree(&c->address); + memset(&c->address, 0, sizeof(c->address)); + c->address.sa.sa_family = AF_INET; + + if(address) { + memcpy(&c->address.in.sin_addr, address, sizeof(ipv4_t)); + } + + if(port) { + memcpy(&c->address.in.sin_port, port, sizeof(uint16_t)); + } + + // OpenSSH -D returns all zero address, set it to 0.0.0.1 to prevent spamming ourselves. + if(!memcmp(&c->address.in.sin_addr, "\0\0\0\0", 4)) { + memcpy(&c->address.in.sin_addr, "\0\0\0\01", 4); + } +} + +static void update_address_ipv6(connection_t *c, void *address, void *port) { + sockaddrfree(&c->address); + memset(&c->address, 0, sizeof(c->address)); + c->address.sa.sa_family = AF_INET6; + + if(address) { + memcpy(&c->address.in6.sin6_addr, address, sizeof(ipv6_t)); + } + + if(port) { + memcpy(&c->address.in6.sin6_port, port, sizeof(uint16_t)); + } + + // OpenSSH -D returns all zero address, set it to 0100:: to prevent spamming ourselves. + if(!memcmp(&c->address.in6.sin6_addr, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 16)) { + memcpy(&c->address.in6.sin6_addr, "\01\0\0\0\0\0\0\0", 8); + } +} + +bool send_proxyrequest(connection_t *c) { + switch(proxytype) { + case PROXY_SOCKS4: + if(c->address.sa.sa_family != AF_INET) { + logger(LOG_ERR, "Can only connect to numeric IPv4 addresses through a SOCKS 4 proxy!"); + return false; + } + + // fallthrough + case PROXY_SOCKS4A: { + if(c->address.sa.sa_family != AF_INET && c->address.sa.sa_family != AF_UNKNOWN) { + logger(LOG_ERR, "Can only connect to IPv4 addresses or hostnames through a SOCKS 4a proxy!"); + return false; + } + + int len = 9; + + if(proxyuser) { + len += strlen(proxyuser); + } + + if(c->address.sa.sa_family == AF_UNKNOWN) { + len += 1 + strlen(c->address.unknown.address); + } + + char s4req[len]; + s4req[0] = 4; + s4req[1] = 1; + + if(c->address.sa.sa_family == AF_INET) { + memcpy(s4req + 2, &c->address.in.sin_port, 2); + memcpy(s4req + 4, &c->address.in.sin_addr, 4); + } else { + uint16_t port = htons(atoi(c->address.unknown.port)); + memcpy(s4req + 2, &port, 2); + memcpy(s4req + 4, "\0\0\0\1", 4); + strcpy(s4req + (9 + (proxyuser ? strlen(proxyuser) : 0)), c->address.unknown.address); + } + + if(proxyuser) { + strcpy(s4req + 8, proxyuser); + } else { + s4req[8] = 0; + } + + s4req[sizeof(s4req) - 1] = 0; + c->allow_request = PROXY; + return send_meta(c, s4req, sizeof(s4req)); + } + + case PROXY_SOCKS5: { + int len = 3 + 6; + + if(c->address.sa.sa_family == AF_INET) { + len += 4; + } else if(c->address.sa.sa_family == AF_INET6) { + len += 16; + } else if(c->address.sa.sa_family == AF_UNKNOWN) { + len += 1 + strlen(c->address.unknown.address); + } else { + logger(LOG_ERR, "Address family %x not supported for SOCKS 5 proxies!", c->address.sa.sa_family); + return false; + } + + if(proxypass) { + len += 3 + strlen(proxyuser) + strlen(proxypass); + } + + char s5req[len]; + int i = 0; + s5req[i++] = 5; + s5req[i++] = 1; + + if(proxypass) { + s5req[i++] = 2; + s5req[i++] = 1; + s5req[i++] = strlen(proxyuser); + strcpy(s5req + i, proxyuser); + i += strlen(proxyuser); + s5req[i++] = strlen(proxypass); + strcpy(s5req + i, proxypass); + i += strlen(proxypass); + } else { + s5req[i++] = 0; + } + + s5req[i++] = 5; + s5req[i++] = 1; + s5req[i++] = 0; + + if(c->address.sa.sa_family == AF_INET) { + s5req[i++] = 1; + memcpy(s5req + i, &c->address.in.sin_addr, 4); + i += 4; + memcpy(s5req + i, &c->address.in.sin_port, 2); + i += 2; + } else if(c->address.sa.sa_family == AF_INET6) { + s5req[i++] = 4; + memcpy(s5req + i, &c->address.in6.sin6_addr, 16); + i += 16; + memcpy(s5req + i, &c->address.in6.sin6_port, 2); + i += 2; + } else if(c->address.sa.sa_family == AF_UNKNOWN) { + s5req[i++] = 3; + int len = strlen(c->address.unknown.address); + s5req[i++] = len; + memcpy(s5req + i, c->address.unknown.address, len); + i += len; + uint16_t port = htons(atoi(c->address.unknown.port)); + memcpy(s5req + i, &port, 2); + i += 2; + } else { + logger(LOG_ERR, "Unknown address family while trying to connect to SOCKS5 proxy"); + return false; + } + + if(i > len) { + abort(); + } + + c->allow_request = PROXY; + return send_meta(c, s5req, sizeof(s5req)); + } + + case PROXY_HTTP: { + char *host; + char *port; + + sockaddr2str(&c->address, &host, &port); + send_request(c, "CONNECT %s:%s HTTP/1.1\r\n\r", host, port); + free(host); + free(port); + c->allow_request = PROXY; + return true; + } + + case PROXY_EXEC: + abort(); + + default: + logger(LOG_ERR, "Unknown proxy type"); + return false; + } +} + +int receive_proxy_meta(connection_t *c) { + switch(proxytype) { + case PROXY_SOCKS4: + case PROXY_SOCKS4A: + if(c->buflen < 8) { + return 0; + } + + if(c->buffer[0] == 0 && c->buffer[1] == 0x5a) { + if(c->address.sa.sa_family == AF_UNKNOWN) { + update_address_ipv4(c, c->buffer + 4, c->buffer + 2); + } + + ifdebug(CONNECTIONS) logger(LOG_DEBUG, "Proxy request granted"); + c->allow_request = ID; + c->status.proxy_passed = true; + send_id(c); + return 8; + } else { + logger(LOG_ERR, "Proxy request rejected"); + return -1; + } + + case PROXY_SOCKS5: + if(c->buflen < 2) { + return 0; + } + + if(c->buffer[0] != 0x05 || c->buffer[1] == (char)0xff) { + logger(LOG_ERR, "Proxy authentication method rejected"); + return -1; + } + + int offset = 2; + + if(c->buffer[1] == 0x02) { + if(c->buflen < 4) { + return 0; + } + + if(c->buffer[2] != 0x05 || c->buffer[3] != 0x00) { + logger(LOG_ERR, "Proxy username/password rejected"); + return -1; + } + + offset += 2; + } + + if(c->buflen - offset < 7) { + return 0; + } + + if(c->buffer[offset] != 0x05 || c->buffer[offset + 1] != 0x00) { + logger(LOG_ERR, "Proxy request rejected"); + return -1; + } + + int replen = offset + 6; + + switch(c->buffer[offset + 3]) { + case 0x01: // IPv4 + if(c->address.sa.sa_family == AF_UNKNOWN) { + update_address_ipv4(c, c->buffer + offset + 4, c->buffer + offset + 8); + } + + replen += 4; + break; + + case 0x03: // Hostname + if(c->address.sa.sa_family == AF_UNKNOWN) { + update_address_ipv4(c, "\0\0\0\1", "\0\0"); + } + + replen += ((uint8_t *)c->buffer)[offset + 4]; + break; + + case 0x04: // IPv6 + if(c->address.sa.sa_family == AF_UNKNOWN) { + update_address_ipv6(c, c->buffer + offset + 4, c->buffer + offset + 20); + } + + replen += 16; + break; + + default: + logger(LOG_ERR, "Proxy reply malformed"); + return -1; + } + + if(c->buflen < replen) { + return 0; + } else { + ifdebug(CONNECTIONS) logger(LOG_DEBUG, "Proxy request granted"); + c->allow_request = ID; + c->status.proxy_passed = true; + send_id(c); + return replen; + } + + case PROXY_HTTP: { + char *p = memchr(c->buffer, '\n', c->buflen); + + if(!p || p - c->buffer >= c->buflen) { + return 0; + } + + while((p = memchr(p + 1, '\n', c->buflen - (p + 1 - c->buffer)))) { + if(p > c->buffer + 3 && !memcmp(p - 3, "\r\n\r\n", 4)) { + break; + } + } + + if(!p) { + return 0; + } + + if(c->buflen < 9) { + return 0; + } + + if(!strncasecmp(c->buffer, "HTTP/1.1 ", 9)) { + if(!strncmp(c->buffer + 9, "200", 3)) { + if(c->address.sa.sa_family == AF_UNKNOWN) { + update_address_ipv4(c, "\0\0\0\1", "\0\0"); + } + + logger(LOG_DEBUG, "Proxy request granted"); + replen = p + 1 - c->buffer; + c->allow_request = ID; + c->status.proxy_passed = true; + send_id(c); + return replen; + } else { + p = memchr(c->buffer, '\n', c->buflen); + p[-1] = 0; + logger(LOG_ERR, "Proxy request rejected: %s", c->buffer + 9); + return false; + } + } else { + logger(LOG_ERR, "Proxy reply malformed"); + return -1; + } + } + + default: + abort(); + } +} diff --git a/src/upnp.h b/src/proxy.h similarity index 62% rename from src/upnp.h rename to src/proxy.h index b611bc1..a96fc3d 100644 --- a/src/upnp.h +++ b/src/proxy.h @@ -1,8 +1,8 @@ -#ifndef TINC_UPNP_H -#define TINC_UPNP_H +#ifndef TINC_PROXY_H +#define TINC_PROXY_H /* - upnp.h -- UPnP-IGD client + proxy.h -- header for proxy.c Copyright (C) 2015 Guus Sliepen This program is free software; you can redistribute it and/or modify @@ -20,8 +20,24 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#include "system.h" +#include "connection.h" -extern void upnp_init(bool tcp, bool udp); +typedef enum proxytype_t { + PROXY_NONE = 0, + PROXY_SOCKS4, + PROXY_SOCKS4A, + PROXY_SOCKS5, + PROXY_HTTP, + PROXY_EXEC, +} proxytype_t; + +extern proxytype_t proxytype; +extern char *proxyhost; +extern char *proxyport; +extern char *proxyuser; +extern char *proxypass; + +extern bool send_proxyrequest(struct connection_t *c); +extern int receive_proxy_meta(struct connection_t *c); #endif diff --git a/src/raw_socket_device.c b/src/raw_socket_device.c index 02f6afa..f4ed694 100644 --- a/src/raw_socket_device.c +++ b/src/raw_socket_device.c @@ -1,7 +1,7 @@ /* device.c -- raw socket Copyright (C) 2002-2005 Ivo Timmermans, - 2002-2012 Guus Sliepen + 2002-2014 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 @@ -35,6 +35,9 @@ #if defined(PF_PACKET) && defined(ETH_P_ALL) && defined(AF_PACKET) && defined(SIOCGIFINDEX) static const char *device_info = "raw_socket"; +static uint64_t device_total_in = 0; +static uint64_t device_total_out = 0; + static bool setup_device(void) { struct ifreq ifr; struct sockaddr_ll sa; @@ -48,94 +51,99 @@ static bool setup_device(void) { } if((device_fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL))) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not open %s: %s", device_info, + logger(LOG_ERR, "Could not open %s: %s", device_info, strerror(errno)); return false; } - memset(&ifr, 0, sizeof(ifr)); - #ifdef FD_CLOEXEC fcntl(device_fd, F_SETFD, FD_CLOEXEC); #endif + memset(&ifr, 0, sizeof(ifr)); strncpy(ifr.ifr_ifrn.ifrn_name, iface, IFNAMSIZ); ifr.ifr_ifrn.ifrn_name[IFNAMSIZ - 1] = 0; if(ioctl(device_fd, SIOCGIFINDEX, &ifr)) { close(device_fd); - logger(DEBUG_ALWAYS, LOG_ERR, "Can't find interface %s: %s", iface, - strerror(errno)); + logger(LOG_ERR, "Can't find interface %s: %s", ifr.ifr_ifrn.ifrn_name, strerror(errno)); return false; } - memset(&sa, '0', sizeof(sa)); + memset(&sa, 0, sizeof(sa)); sa.sll_family = AF_PACKET; sa.sll_protocol = htons(ETH_P_ALL); sa.sll_ifindex = ifr.ifr_ifindex; if(bind(device_fd, (struct sockaddr *) &sa, (socklen_t) sizeof(sa))) { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not bind %s to %s: %s", device, iface, strerror(errno)); + logger(LOG_ERR, "Could not bind %s to %s: %s", device, ifr.ifr_ifrn.ifrn_name, strerror(errno)); return false; } - logger(DEBUG_ALWAYS, LOG_INFO, "%s is a %s", device, device_info); + logger(LOG_INFO, "%s is a %s", device, device_info); return true; } static void close_device(void) { close(device_fd); - device_fd = -1; free(device); - device = NULL; free(iface); - iface = NULL; - device_info = NULL; } static bool read_packet(vpn_packet_t *packet) { - int inlen; + int lenin; - if((inlen = read(device_fd, DATA(packet), MTU)) <= 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info, + if((lenin = read(device_fd, packet->data, MTU)) <= 0) { + logger(LOG_ERR, "Error while reading from %s %s: %s", device_info, device, strerror(errno)); return false; } - packet->len = inlen; + packet->len = lenin; - logger(DEBUG_TRAFFIC, LOG_DEBUG, "Read packet of %d bytes from %s", packet->len, - device_info); + device_total_in += packet->len; + + ifdebug(TRAFFIC) logger(LOG_DEBUG, "Read packet of %d bytes from %s", packet->len, + device_info); return true; } static bool write_packet(vpn_packet_t *packet) { - logger(DEBUG_TRAFFIC, LOG_DEBUG, "Writing packet of %d bytes to %s", - packet->len, device_info); + ifdebug(TRAFFIC) logger(LOG_DEBUG, "Writing packet of %d bytes to %s", + packet->len, device_info); - if(write(device_fd, DATA(packet), packet->len) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Can't write to %s %s: %s", device_info, device, + if(write(device_fd, packet->data, packet->len) < 0) { + logger(LOG_ERR, "Can't write to %s %s: %s", device_info, device, strerror(errno)); return false; } + device_total_out += packet->len; + return true; } +static void dump_device_stats(void) { + logger(LOG_DEBUG, "Statistics for %s %s:", device_info, device); + logger(LOG_DEBUG, " total bytes in: %10"PRIu64, device_total_in); + logger(LOG_DEBUG, " total bytes out: %10"PRIu64, device_total_out); +} + const devops_t raw_socket_devops = { .setup = setup_device, .close = close_device, .read = read_packet, .write = write_packet, + .dump_stats = dump_device_stats, }; #else static bool not_supported(void) { - logger(DEBUG_ALWAYS, LOG_ERR, "Raw socket device not supported on this platform"); + logger(LOG_ERR, "Raw socket device not supported on this platform"); return false; } @@ -144,5 +152,6 @@ const devops_t raw_socket_devops = { .close = NULL, .read = NULL, .write = NULL, + .dump_stats = NULL, }; #endif diff --git a/src/route.c b/src/route.c index dcc6f3c..f8b11bb 100644 --- a/src/route.c +++ b/src/route.c @@ -1,7 +1,8 @@ /* route.c -- routing Copyright (C) 2000-2005 Ivo Timmermans, - 2000-2013 Guus Sliepen + 2000-2017 Guus Sliepen + 2015-2016 Vittorio Gambaletta 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 @@ -20,13 +21,12 @@ #include "system.h" +#include "avl_tree.h" #include "connection.h" -#include "control_common.h" #include "ethernet.h" #include "ipv4.h" #include "ipv6.h" #include "logger.h" -#include "meta.h" #include "net.h" #include "protocol.h" #include "route.h" @@ -42,7 +42,6 @@ bool priorityinheritance = false; int macexpire = 600; bool overwrite_mac = false; mac_t mymac = {{0xFE, 0xFD, 0, 0, 0, 0}}; -bool pcap = false; /* Sizes of various headers */ @@ -59,9 +58,6 @@ static const size_t opt_size = sizeof(struct nd_opt_hdr); #define MAX(a, b) ((a) > (b) ? (a) : (b)) #endif -volatile int dummy; -static timeout_t age_subnets_timeout; - /* RFC 1071 */ static uint16_t inet_checksum(void *data, int len, uint16_t prevsum) { @@ -81,11 +77,6 @@ static uint16_t inet_checksum(void *data, int len, uint16_t prevsum) { checksum = (checksum & 0xFFFF) + (checksum >> 16); } - // Work around a compiler optimization bug. - if(checksum) { - dummy = 1; - } - return ~checksum; } @@ -93,12 +84,12 @@ static bool ratelimit(int frequency) { static time_t lasttime = 0; static int count = 0; - if(lasttime == now.tv_sec) { + if(lasttime == now) { if(count >= frequency) { return true; } } else { - lasttime = now.tv_sec; + lasttime = now; count = 0; } @@ -108,7 +99,7 @@ static bool ratelimit(int frequency) { static bool checklength(node_t *source, vpn_packet_t *packet, length_t length) { if(packet->len < length) { - logger(DEBUG_TRAFFIC, LOG_WARNING, "Got too short packet from %s (%s)", source->name, source->hostname); + ifdebug(TRAFFIC) logger(LOG_WARNING, "Got too short packet from %s (%s)", source->name, source->hostname); return false; } else { return true; @@ -117,9 +108,9 @@ static bool checklength(node_t *source, vpn_packet_t *packet, length_t length) { static void swap_mac_addresses(vpn_packet_t *packet) { mac_t tmp; - memcpy(&tmp, &DATA(packet)[0], sizeof(tmp)); - memcpy(&DATA(packet)[0], &DATA(packet)[6], sizeof(tmp)); - memcpy(&DATA(packet)[6], &tmp, sizeof(tmp)); + memcpy(&tmp, &packet->data[0], sizeof(tmp)); + memcpy(&packet->data[0], &packet->data[6], sizeof(tmp)); + memcpy(&packet->data[6], &tmp, sizeof(tmp)); } /* RFC 792 */ @@ -142,7 +133,7 @@ static void route_ipv4_unreachable(node_t *source, vpn_packet_t *packet, length_ /* Copy headers from packet into properly aligned structs on the stack */ - memcpy(&ip, DATA(packet) + ether_size, ip_size); + memcpy(&ip, packet->data + ether_size, ip_size); /* Remember original source and destination */ @@ -186,7 +177,7 @@ static void route_ipv4_unreachable(node_t *source, vpn_packet_t *packet, length_ /* Copy first part of original contents to ICMP message */ - memmove(DATA(packet) + ether_size + ip_size + icmp_size, DATA(packet) + ether_size, oldlen); + memmove(packet->data + ether_size + ip_size + icmp_size, packet->data + ether_size, oldlen); /* Fill in IPv4 header */ @@ -211,12 +202,12 @@ static void route_ipv4_unreachable(node_t *source, vpn_packet_t *packet, length_ icmp.icmp_cksum = 0; icmp.icmp_cksum = inet_checksum(&icmp, icmp_size, ~0); - icmp.icmp_cksum = inet_checksum(DATA(packet) + ether_size + ip_size + icmp_size, oldlen, icmp.icmp_cksum); + icmp.icmp_cksum = inet_checksum(packet->data + ether_size + ip_size + icmp_size, oldlen, icmp.icmp_cksum); /* Copy structs on stack back to packet */ - memcpy(DATA(packet) + ether_size, &ip, ip_size); - memcpy(DATA(packet) + ether_size + ip_size, &icmp, icmp_size); + memcpy(packet->data + ether_size, &ip, ip_size); + memcpy(packet->data + ether_size + ip_size, &icmp, icmp_size); packet->len = ether_size + ip_size + icmp_size + oldlen; @@ -247,7 +238,7 @@ static void route_ipv6_unreachable(node_t *source, vpn_packet_t *packet, length_ /* Copy headers from packet to structs on the stack */ - memcpy(&ip6, DATA(packet) + ether_size, ip6_size); + memcpy(&ip6, packet->data + ether_size, ip6_size); /* Remember original source and destination */ @@ -291,7 +282,7 @@ static void route_ipv6_unreachable(node_t *source, vpn_packet_t *packet, length_ /* Copy first part of original contents to ICMP message */ - memmove(DATA(packet) + ether_size + ip6_size + icmp6_size, DATA(packet) + ether_size, pseudo.length); + memmove(packet->data + ether_size + ip6_size + icmp6_size, packet->data + ether_size, pseudo.length); /* Fill in IPv6 header */ @@ -317,14 +308,14 @@ static void route_ipv6_unreachable(node_t *source, vpn_packet_t *packet, length_ checksum = inet_checksum(&pseudo, sizeof(pseudo), ~0); checksum = inet_checksum(&icmp6, icmp6_size, checksum); - checksum = inet_checksum(DATA(packet) + ether_size + ip6_size + icmp6_size, ntohl(pseudo.length) - icmp6_size, checksum); + checksum = inet_checksum(packet->data + ether_size + ip6_size + icmp6_size, ntohl(pseudo.length) - icmp6_size, checksum); icmp6.icmp6_cksum = checksum; /* Copy structs on stack back to packet */ - memcpy(DATA(packet) + ether_size, &ip6, ip6_size); - memcpy(DATA(packet) + ether_size + ip6_size, &icmp6, icmp6_size); + memcpy(packet->data + ether_size, &ip6, ip6_size); + memcpy(packet->data + ether_size + ip6_size, &icmp6, icmp6_size); packet->len = ether_size + ip6_size + ntohl(pseudo.length); @@ -332,11 +323,11 @@ static void route_ipv6_unreachable(node_t *source, vpn_packet_t *packet, length_ } static bool do_decrement_ttl(node_t *source, vpn_packet_t *packet) { - uint16_t type = DATA(packet)[12] << 8 | DATA(packet)[13]; + uint16_t type = packet->data[12] << 8 | packet->data[13]; length_t ethlen = ether_size; if(type == ETH_P_8021Q) { - type = DATA(packet)[16] << 8 | DATA(packet)[17]; + type = packet->data[16] << 8 | packet->data[17]; ethlen += 4; } @@ -346,27 +337,27 @@ static bool do_decrement_ttl(node_t *source, vpn_packet_t *packet) { return false; } - if(DATA(packet)[ethlen + 8] <= 1) { - if(DATA(packet)[ethlen + 11] != IPPROTO_ICMP || DATA(packet)[ethlen + 32] != ICMP_TIME_EXCEEDED) { + if(packet->data[ethlen + 8] <= 1) { + if(packet->data[ethlen + 11] != IPPROTO_ICMP || packet->data[ethlen + 32] != ICMP_TIME_EXCEEDED) { route_ipv4_unreachable(source, packet, ethlen, ICMP_TIME_EXCEEDED, ICMP_EXC_TTL); } return false; } - uint16_t old = DATA(packet)[ethlen + 8] << 8 | DATA(packet)[ethlen + 9]; - DATA(packet)[ethlen + 8]--; - uint16_t new = DATA(packet)[ethlen + 8] << 8 | DATA(packet)[ethlen + 9]; + uint16_t old = packet->data[ethlen + 8] << 8 | packet->data[ethlen + 9]; + packet->data[ethlen + 8]--; + uint16_t new = packet->data[ethlen + 8] << 8 | packet->data[ethlen + 9]; - uint32_t checksum = DATA(packet)[ethlen + 10] << 8 | DATA(packet)[ethlen + 11]; + uint32_t checksum = packet->data[ethlen + 10] << 8 | packet->data[ethlen + 11]; checksum += old + (~new & 0xFFFF); while(checksum >> 16) { checksum = (checksum & 0xFFFF) + (checksum >> 16); } - DATA(packet)[ethlen + 10] = checksum >> 8; - DATA(packet)[ethlen + 11] = checksum & 0xff; + packet->data[ethlen + 10] = checksum >> 8; + packet->data[ethlen + 11] = checksum & 0xff; return true; @@ -375,15 +366,15 @@ static bool do_decrement_ttl(node_t *source, vpn_packet_t *packet) { return false; } - if(DATA(packet)[ethlen + 7] <= 1) { - if(DATA(packet)[ethlen + 6] != IPPROTO_ICMPV6 || DATA(packet)[ethlen + 40] != ICMP6_TIME_EXCEEDED) { + if(packet->data[ethlen + 7] <= 1) { + if(packet->data[ethlen + 6] != IPPROTO_ICMPV6 || packet->data[ethlen + 40] != ICMP6_TIME_EXCEEDED) { route_ipv6_unreachable(source, packet, ethlen, ICMP6_TIME_EXCEEDED, ICMP6_TIME_EXCEED_TRANSIT); } return false; } - DATA(packet)[ethlen + 7]--; + packet->data[ethlen + 7]--; return true; @@ -405,25 +396,16 @@ static void clamp_mss(const node_t *source, const node_t *via, vpn_packet_t *pac /* Find TCP header */ int start = ether_size; - uint16_t type = DATA(packet)[12] << 8 | DATA(packet)[13]; + uint16_t type = packet->data[12] << 8 | packet->data[13]; if(type == ETH_P_8021Q) { start += 4; - type = DATA(packet)[16] << 8 | DATA(packet)[17]; + type = packet->data[16] << 8 | packet->data[17]; } - /* IP in IP (RFC 2003) packet */ - if(type == ETH_P_IP && DATA(packet)[start + 9] == 4) { - start += 20; - } - - if(packet->len <= start + 20) { - return; - } - - if(type == ETH_P_IP && DATA(packet)[start + 9] == 6) { - start += (DATA(packet)[start] & 0xf) * 4; - } else if(type == ETH_P_IPV6 && DATA(packet)[start + 6] == 6) { + if(type == ETH_P_IP && packet->data[start + 9] == 6) { + start += (packet->data[start] & 0xf) * 4; + } else if(type == ETH_P_IPV6 && packet->data[start + 6] == 6) { start += 40; } else { return; @@ -434,7 +416,7 @@ static void clamp_mss(const node_t *source, const node_t *via, vpn_packet_t *pac } /* Use data offset field to calculate length of options field */ - int len = ((DATA(packet)[start + 12] >> 4) - 5) * 4; + int len = ((packet->data[start + 12] >> 4) - 5) * 4; if(packet->len < start + 20 + len) { return; @@ -442,104 +424,75 @@ static void clamp_mss(const node_t *source, const node_t *via, vpn_packet_t *pac /* Search for MSS option header */ for(int i = 0; i < len;) { - if(DATA(packet)[start + 20 + i] == 0) { + if(packet->data[start + 20 + i] == 0) { break; } - if(DATA(packet)[start + 20 + i] == 1) { + if(packet->data[start + 20 + i] == 1) { i++; continue; } - if(i > len - 2 || i > len - DATA(packet)[start + 21 + i]) { + if(i > len - 2 || i > len - packet->data[start + 21 + i]) { break; } - if(DATA(packet)[start + 20 + i] != 2) { - if(DATA(packet)[start + 21 + i] < 2) { + if(packet->data[start + 20 + i] != 2) { + if(packet->data[start + 21 + i] < 2) { break; } - i += DATA(packet)[start + 21 + i]; + i += packet->data[start + 21 + i]; continue; } - if(DATA(packet)[start + 21] != 4) { + if(packet->data[start + 21] != 4) { break; } /* Found it */ - uint16_t oldmss = DATA(packet)[start + 22 + i] << 8 | DATA(packet)[start + 23 + i]; + uint16_t oldmss = packet->data[start + 22 + i] << 8 | packet->data[start + 23 + i]; uint16_t newmss = mtu - start - 20; - uint32_t csum = DATA(packet)[start + 16] << 8 | DATA(packet)[start + 17]; + uint32_t csum = packet->data[start + 16] << 8 | packet->data[start + 17]; if(oldmss <= newmss) { break; } - logger(DEBUG_TRAFFIC, LOG_INFO, "Clamping MSS of packet from %s to %s to %d", source->name, via->name, newmss); + 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 */ - DATA(packet)[start + 22 + i] = newmss >> 8; - DATA(packet)[start + 23 + i] = newmss & 0xff; + packet->data[start + 22 + i] = newmss >> 8; + packet->data[start + 23 + i] = newmss & 0xff; csum ^= 0xffff; csum += oldmss ^ 0xffff; csum += newmss; csum = (csum & 0xffff) + (csum >> 16); csum += csum >> 16; csum ^= 0xffff; - DATA(packet)[start + 16] = csum >> 8; - DATA(packet)[start + 17] = csum; + packet->data[start + 16] = csum >> 8; + packet->data[start + 17] = csum; break; } } -static void age_subnets(void *data) { - (void)data; - bool left = false; - - for splay_each(subnet_t, s, myself->subnet_tree) { - if(s->expires && s->expires < now.tv_sec) { - if(debug_level >= DEBUG_TRAFFIC) { - char netstr[MAXNETSTR]; - - if(net2str(netstr, sizeof(netstr), s)) { - logger(DEBUG_TRAFFIC, LOG_INFO, "Subnet %s expired", netstr); - } - } - - for list_each(connection_t, c, connection_list) - if(c->edge) { - send_del_subnet(c, s); - } - - subnet_del(myself, s); - } else { - if(s->expires) { - left = true; - } - } - } - - if(left) - timeout_set(&age_subnets_timeout, &(struct timeval) { - 10, rand() % 100000 - }); -} - static void learn_mac(mac_t *address) { - subnet_t *subnet = lookup_subnet_mac(myself, address); + subnet_t *subnet; + avl_node_t *node; + connection_t *c; + + subnet = lookup_subnet_mac(myself, address); /* If we don't know this MAC address yet, store it */ if(!subnet) { - logger(DEBUG_TRAFFIC, LOG_INFO, "Learned new MAC address %x:%x:%x:%x:%x:%x", - address->x[0], address->x[1], address->x[2], address->x[3], - address->x[4], address->x[5]); + ifdebug(TRAFFIC) logger(LOG_INFO, "Learned new MAC address %x:%x:%x:%x:%x:%x", + address->x[0], address->x[1], address->x[2], address->x[3], + address->x[4], address->x[5]); subnet = new_subnet(); subnet->type = SUBNET_MAC; - subnet->expires = now.tv_sec + macexpire; + subnet->expires = now + macexpire; subnet->net.mac.address = *address; subnet->weight = 10; subnet_add(myself, subnet); @@ -547,17 +500,48 @@ static void learn_mac(mac_t *address) { /* And tell all other tinc daemons it's our MAC */ - for list_each(connection_t, c, connection_list) - if(c->edge) { + for(node = connection_tree->head; node; node = node->next) { + c = node->data; + + if(c->status.active) { send_add_subnet(c, subnet); } + } + } - timeout_add(&age_subnets_timeout, age_subnets, NULL, &(struct timeval) { - 10, rand() % 100000 - }); - } else { - if(subnet->expires) { - subnet->expires = now.tv_sec + macexpire; + if(subnet->expires) { + subnet->expires = now + macexpire; + } +} + +void age_subnets(void) { + subnet_t *s; + connection_t *c; + avl_node_t *node, *next, *node2; + + for(node = myself->subnet_tree->head; node; node = next) { + next = node->next; + s = node->data; + + if(s->expires && s->expires <= now) { + ifdebug(TRAFFIC) { + char netstr[MAXNETSTR]; + + if(net2str(netstr, sizeof(netstr), s)) { + logger(LOG_INFO, "Subnet %s expired", netstr); + } + } + + for(node2 = connection_tree->head; node2; node2 = node2->next) { + c = node2->data; + + if(c->status.active) { + send_del_subnet(c, s); + } + } + + subnet_update(myself, s, false); + subnet_del(myself, s); } } } @@ -576,13 +560,12 @@ static void route_broadcast(node_t *source, vpn_packet_t *packet) { static void fragment_ipv4_packet(node_t *dest, vpn_packet_t *packet, length_t ether_size) { struct ip ip; vpn_packet_t fragment; - int maxlen, todo; + int len, maxlen, todo; uint8_t *offset; uint16_t ip_off, origf; - memcpy(&ip, DATA(packet) + ether_size, ip_size); + memcpy(&ip, packet->data + ether_size, ip_size); fragment.priority = packet->priority; - fragment.offset = DEFAULT_PACKET_OFFSET; if(ip.ip_hl != ip_size / 4) { return; @@ -591,21 +574,21 @@ static void fragment_ipv4_packet(node_t *dest, vpn_packet_t *packet, length_t et todo = ntohs(ip.ip_len) - ip_size; if(ether_size + ip_size + todo != packet->len) { - logger(DEBUG_TRAFFIC, LOG_WARNING, "Length of packet (%d) doesn't match length in IPv4 header (%d)", packet->len, (int)(ether_size + ip_size + todo)); + ifdebug(TRAFFIC) logger(LOG_WARNING, "Length of packet (%d) doesn't match length in IPv4 header (%d)", packet->len, (int)(ether_size + ip_size + todo)); return; } - logger(DEBUG_TRAFFIC, LOG_INFO, "Fragmenting packet of %d bytes to %s (%s)", packet->len, dest->name, dest->hostname); + ifdebug(TRAFFIC) logger(LOG_INFO, "Fragmenting packet of %d bytes to %s (%s)", packet->len, dest->name, dest->hostname); - offset = DATA(packet) + ether_size + ip_size; - maxlen = (dest->mtu - ether_size - ip_size) & ~0x7; + offset = packet->data + ether_size + ip_size; + maxlen = (MAX(dest->mtu, 590) - ether_size - ip_size) & ~0x7; ip_off = ntohs(ip.ip_off); origf = ip_off & ~IP_OFFMASK; ip_off &= IP_OFFMASK; while(todo) { - int len = todo > maxlen ? maxlen : todo; - memcpy(DATA(&fragment) + ether_size + ip_size, offset, len); + len = todo > maxlen ? maxlen : todo; + memcpy(fragment.data + ether_size + ip_size, offset, len); todo -= len; offset += len; @@ -613,8 +596,8 @@ static void fragment_ipv4_packet(node_t *dest, vpn_packet_t *packet, length_t et ip.ip_off = htons(ip_off | origf | (todo ? IP_MF : 0)); ip.ip_sum = 0; ip.ip_sum = inet_checksum(&ip, ip_size, ~0); - memcpy(DATA(&fragment), DATA(packet), ether_size); - memcpy(DATA(&fragment) + ether_size, &ip, ip_size); + memcpy(fragment.data, packet->data, ether_size); + memcpy(fragment.data + ether_size, &ip, ip_size); fragment.len = ether_size + ip_size + len; send_packet(dest, &fragment); @@ -623,37 +606,28 @@ static void fragment_ipv4_packet(node_t *dest, vpn_packet_t *packet, length_t et } } -static void route_ipv4(node_t *source, vpn_packet_t *packet) { - if(!checklength(source, packet, ether_size + ip_size)) { - return; - } - +static void route_ipv4_unicast(node_t *source, vpn_packet_t *packet) { subnet_t *subnet; node_t *via; ipv4_t dest; - memcpy(&dest, &DATA(packet)[30], sizeof(dest)); + memcpy(&dest, &packet->data[30], sizeof(dest)); subnet = lookup_subnet_ipv4(&dest); if(!subnet) { - logger(DEBUG_TRAFFIC, LOG_WARNING, "Cannot route packet from %s (%s): unknown IPv4 destination address %d.%d.%d.%d", - source->name, source->hostname, - dest.x[0], - dest.x[1], - dest.x[2], - dest.x[3]); + ifdebug(TRAFFIC) logger(LOG_WARNING, "Cannot route packet from %s (%s): unknown IPv4 destination address %d.%d.%d.%d", + source->name, source->hostname, + dest.x[0], + dest.x[1], + dest.x[2], + dest.x[3]); route_ipv4_unreachable(source, packet, ether_size, ICMP_DEST_UNREACH, ICMP_NET_UNKNOWN); return; } - if(!subnet->owner) { - route_broadcast(source, packet); - return; - } - if(subnet->owner == source) { - logger(DEBUG_TRAFFIC, LOG_WARNING, "Packet looping back to %s (%s)!", source->name, source->hostname); + ifdebug(TRAFFIC) logger(LOG_WARNING, "Packet looping back to %s (%s)!", source->name, source->hostname); return; } @@ -673,13 +647,13 @@ static void route_ipv4(node_t *source, vpn_packet_t *packet) { } if(priorityinheritance) { - packet->priority = DATA(packet)[15]; + packet->priority = packet->data[15]; } via = (subnet->owner->via == myself) ? subnet->owner->nexthop : subnet->owner->via; if(via == source) { - logger(DEBUG_TRAFFIC, LOG_ERR, "Routing loop for packet from %s (%s)!", source->name, source->hostname); + ifdebug(TRAFFIC) logger(LOG_ERR, "Routing loop for packet from %s (%s)!", source->name, source->hostname); return; } @@ -689,9 +663,9 @@ static void route_ipv4(node_t *source, vpn_packet_t *packet) { } if(via && packet->len > MAX(via->mtu, 590) && via != myself) { - logger(DEBUG_TRAFFIC, LOG_INFO, "Packet for %s (%s) length %d larger than MTU %d", subnet->owner->name, subnet->owner->hostname, packet->len, via->mtu); + 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(DATA(packet)[20] & 0x40) { + if(packet->data[20] & 0x40) { packet->len = MAX(via->mtu, 590); route_ipv4_unreachable(source, packet, ether_size, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED); } else { @@ -706,48 +680,48 @@ static void route_ipv4(node_t *source, vpn_packet_t *packet) { send_packet(subnet->owner, packet); } -static void route_neighborsol(node_t *source, vpn_packet_t *packet); - -static void route_ipv6(node_t *source, vpn_packet_t *packet) { - if(!checklength(source, packet, ether_size + ip6_size)) { +static void route_ipv4(node_t *source, vpn_packet_t *packet) { + if(!checklength(source, packet, ether_size + ip_size)) { return; } - if(DATA(packet)[20] == IPPROTO_ICMPV6 && checklength(source, packet, ether_size + ip6_size + icmp6_size) && DATA(packet)[54] == ND_NEIGHBOR_SOLICIT) { - route_neighborsol(source, packet); - return; + if(broadcast_mode && (((packet->data[30] & 0xf0) == 0xe0) || ( + packet->data[30] == 255 && + packet->data[31] == 255 && + packet->data[32] == 255 && + packet->data[33] == 255))) { + route_broadcast(source, packet); + } else { + route_ipv4_unicast(source, packet); } +} +static void route_ipv6_unicast(node_t *source, vpn_packet_t *packet) { subnet_t *subnet; node_t *via; ipv6_t dest; - memcpy(&dest, &DATA(packet)[38], sizeof(dest)); + memcpy(&dest, &packet->data[38], sizeof(dest)); subnet = lookup_subnet_ipv6(&dest); if(!subnet) { - logger(DEBUG_TRAFFIC, LOG_WARNING, "Cannot route packet from %s (%s): unknown IPv6 destination address %hx:%hx:%hx:%hx:%hx:%hx:%hx:%hx", - source->name, source->hostname, - ntohs(dest.x[0]), - ntohs(dest.x[1]), - ntohs(dest.x[2]), - ntohs(dest.x[3]), - ntohs(dest.x[4]), - ntohs(dest.x[5]), - ntohs(dest.x[6]), - ntohs(dest.x[7])); + ifdebug(TRAFFIC) logger(LOG_WARNING, "Cannot route packet from %s (%s): unknown IPv6 destination address %hx:%hx:%hx:%hx:%hx:%hx:%hx:%hx", + source->name, source->hostname, + ntohs(dest.x[0]), + ntohs(dest.x[1]), + ntohs(dest.x[2]), + ntohs(dest.x[3]), + ntohs(dest.x[4]), + ntohs(dest.x[5]), + ntohs(dest.x[6]), + ntohs(dest.x[7])); route_ipv6_unreachable(source, packet, ether_size, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_ADDR); return; } - if(!subnet->owner) { - route_broadcast(source, packet); - return; - } - if(subnet->owner == source) { - logger(DEBUG_TRAFFIC, LOG_WARNING, "Packet looping back to %s (%s)!", source->name, source->hostname); + ifdebug(TRAFFIC) logger(LOG_WARNING, "Packet looping back to %s (%s)!", source->name, source->hostname); return; } @@ -761,19 +735,20 @@ static void route_ipv6(node_t *source, vpn_packet_t *packet) { return; } - if(decrement_ttl && source != myself && subnet->owner != myself) + if(decrement_ttl && source != myself && subnet->owner != myself) { if(!do_decrement_ttl(source, packet)) { return; } + } if(priorityinheritance) { - packet->priority = ((DATA(packet)[14] & 0x0f) << 4) | (DATA(packet)[15] >> 4); + packet->priority = ((packet->data[14] & 0x0f) << 4) | (packet->data[15] >> 4); } via = (subnet->owner->via == myself) ? subnet->owner->nexthop : subnet->owner->via; if(via == source) { - logger(DEBUG_TRAFFIC, LOG_ERR, "Routing loop for packet from %s (%s)!", source->name, source->hostname); + ifdebug(TRAFFIC) logger(LOG_ERR, "Routing loop for packet from %s (%s)!", source->name, source->hostname); return; } @@ -783,7 +758,7 @@ static void route_ipv6(node_t *source, vpn_packet_t *packet) { } if(via && packet->len > MAX(via->mtu, 1294) && via != myself) { - logger(DEBUG_TRAFFIC, LOG_INFO, "Packet for %s (%s) length %d larger than MTU %d", subnet->owner->name, subnet->owner->hostname, packet->len, via->mtu); + 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); route_ipv6_unreachable(source, packet, ether_size, ICMP6_PACKET_TOO_BIG, 0); return; @@ -805,8 +780,8 @@ static void route_neighborsol(node_t *source, vpn_packet_t *packet) { bool has_opt; struct { - struct in6_addr ip6_src; - struct in6_addr ip6_dst; + struct in6_addr ip6_src; /* source address */ + struct in6_addr ip6_dst; /* destination address */ uint32_t length; uint32_t next; } pseudo; @@ -818,30 +793,30 @@ static void route_neighborsol(node_t *source, vpn_packet_t *packet) { has_opt = packet->len >= ether_size + ip6_size + ns_size + opt_size + ETH_ALEN; if(source != myself) { - logger(DEBUG_TRAFFIC, LOG_WARNING, "Got neighbor solicitation request from %s (%s) while in router mode!", source->name, source->hostname); + ifdebug(TRAFFIC) logger(LOG_WARNING, "Got neighbor solicitation request from %s (%s) while in router mode!", source->name, source->hostname); return; } /* Copy headers from packet to structs on the stack */ - memcpy(&ip6, DATA(packet) + ether_size, ip6_size); - memcpy(&ns, DATA(packet) + ether_size + ip6_size, ns_size); + memcpy(&ip6, packet->data + ether_size, ip6_size); + memcpy(&ns, packet->data + ether_size + ip6_size, ns_size); if(has_opt) { - memcpy(&opt, DATA(packet) + ether_size + ip6_size + ns_size, opt_size); + memcpy(&opt, packet->data + ether_size + ip6_size + ns_size, opt_size); } /* First, snatch the source address from the neighbor solicitation packet */ if(overwrite_mac) { - memcpy(mymac.x, DATA(packet) + ETH_ALEN, ETH_ALEN); + memcpy(mymac.x, packet->data + ETH_ALEN, ETH_ALEN); } /* Check if this is a valid neighbor solicitation request */ if(ns.nd_ns_hdr.icmp6_type != ND_NEIGHBOR_SOLICIT || (has_opt && opt.nd_opt_type != ND_OPT_SOURCE_LINKADDR)) { - logger(DEBUG_TRAFFIC, LOG_WARNING, "Cannot route packet: received unknown type neighbor solicitation request"); + ifdebug(TRAFFIC) logger(LOG_WARNING, "Cannot route packet: received unknown type neighbor solicitation request"); return; } @@ -865,11 +840,11 @@ static void route_neighborsol(node_t *source, vpn_packet_t *packet) { if(has_opt) { checksum = inet_checksum(&opt, opt_size, checksum); - checksum = inet_checksum(DATA(packet) + ether_size + ip6_size + ns_size + opt_size, ETH_ALEN, checksum); + checksum = inet_checksum(packet->data + ether_size + ip6_size + ns_size + opt_size, ETH_ALEN, checksum); } if(checksum) { - logger(DEBUG_TRAFFIC, LOG_WARNING, "Cannot route packet: checksum error for neighbor solicitation request"); + ifdebug(TRAFFIC) logger(LOG_WARNING, "Cannot route packet: checksum error for neighbor solicitation request"); return; } @@ -878,15 +853,15 @@ static void route_neighborsol(node_t *source, vpn_packet_t *packet) { subnet = lookup_subnet_ipv6((ipv6_t *) &ns.nd_ns_target); if(!subnet) { - logger(DEBUG_TRAFFIC, LOG_WARNING, "Cannot route packet: neighbor solicitation request for unknown address %hx:%hx:%hx:%hx:%hx:%hx:%hx:%hx", - ntohs(((uint16_t *) &ns.nd_ns_target)[0]), - ntohs(((uint16_t *) &ns.nd_ns_target)[1]), - ntohs(((uint16_t *) &ns.nd_ns_target)[2]), - ntohs(((uint16_t *) &ns.nd_ns_target)[3]), - ntohs(((uint16_t *) &ns.nd_ns_target)[4]), - ntohs(((uint16_t *) &ns.nd_ns_target)[5]), - ntohs(((uint16_t *) &ns.nd_ns_target)[6]), - ntohs(((uint16_t *) &ns.nd_ns_target)[7])); + ifdebug(TRAFFIC) logger(LOG_WARNING, "Cannot route packet: neighbor solicitation request for unknown address %hx:%hx:%hx:%hx:%hx:%hx:%hx:%hx", + ntohs(((uint16_t *) &ns.nd_ns_target)[0]), + ntohs(((uint16_t *) &ns.nd_ns_target)[1]), + ntohs(((uint16_t *) &ns.nd_ns_target)[2]), + ntohs(((uint16_t *) &ns.nd_ns_target)[3]), + ntohs(((uint16_t *) &ns.nd_ns_target)[4]), + ntohs(((uint16_t *) &ns.nd_ns_target)[5]), + ntohs(((uint16_t *) &ns.nd_ns_target)[6]), + ntohs(((uint16_t *) &ns.nd_ns_target)[7])); return; } @@ -904,19 +879,19 @@ static void route_neighborsol(node_t *source, vpn_packet_t *packet) { /* Create neighbor advertation reply */ - memcpy(DATA(packet), DATA(packet) + ETH_ALEN, ETH_ALEN); /* copy destination address */ - DATA(packet)[ETH_ALEN * 2 - 1] ^= 0xFF; /* mangle source address so it looks like it's not from us */ + memcpy(packet->data, packet->data + ETH_ALEN, ETH_ALEN); /* copy destination address */ + packet->data[ETH_ALEN * 2 - 1] ^= 0xFF; /* mangle source address so it looks like it's not from us */ - ip6.ip6_dst = ip6.ip6_src; /* swap destination and source protocol address */ + ip6.ip6_dst = ip6.ip6_src; /* swap destination and source protocol address */ ip6.ip6_src = ns.nd_ns_target; if(has_opt) { - memcpy(DATA(packet) + ether_size + ip6_size + ns_size + opt_size, DATA(packet) + ETH_ALEN, ETH_ALEN); /* add fake source hard addr */ + memcpy(packet->data + ether_size + ip6_size + ns_size + opt_size, packet->data + ETH_ALEN, ETH_ALEN); /* add fake source hard addr */ } ns.nd_ns_cksum = 0; ns.nd_ns_type = ND_NEIGHBOR_ADVERT; - ns.nd_ns_reserved = htonl(0x40000000UL); /* Set solicited flag */ + ns.nd_ns_reserved = htonl(0x40000000UL); /* Set solicited flag */ opt.nd_opt_type = ND_OPT_TARGET_LINKADDR; /* Create pseudo header */ @@ -939,23 +914,40 @@ static void route_neighborsol(node_t *source, vpn_packet_t *packet) { if(has_opt) { checksum = inet_checksum(&opt, opt_size, checksum); - checksum = inet_checksum(DATA(packet) + ether_size + ip6_size + ns_size + opt_size, ETH_ALEN, checksum); + checksum = inet_checksum(packet->data + ether_size + ip6_size + ns_size + opt_size, ETH_ALEN, checksum); } ns.nd_ns_hdr.icmp6_cksum = checksum; /* Copy structs on stack back to packet */ - memcpy(DATA(packet) + ether_size, &ip6, ip6_size); - memcpy(DATA(packet) + ether_size + ip6_size, &ns, ns_size); + memcpy(packet->data + ether_size, &ip6, ip6_size); + memcpy(packet->data + ether_size + ip6_size, &ns, ns_size); if(has_opt) { - memcpy(DATA(packet) + ether_size + ip6_size + ns_size, &opt, opt_size); + memcpy(packet->data + ether_size + ip6_size + ns_size, &opt, opt_size); } send_packet(source, packet); } +static void route_ipv6(node_t *source, vpn_packet_t *packet) { + if(!checklength(source, packet, ether_size + ip6_size)) { + return; + } + + if(packet->data[20] == IPPROTO_ICMPV6 && checklength(source, packet, ether_size + ip6_size + icmp6_size) && packet->data[54] == ND_NEIGHBOR_SOLICIT) { + route_neighborsol(source, packet); + return; + } + + if(broadcast_mode && packet->data[38] == 255) { + route_broadcast(source, packet); + } else { + route_ipv6_unicast(source, packet); + } +} + /* RFC 826 */ static void route_arp(node_t *source, vpn_packet_t *packet) { @@ -968,25 +960,25 @@ static void route_arp(node_t *source, vpn_packet_t *packet) { } if(source != myself) { - logger(DEBUG_TRAFFIC, LOG_WARNING, "Got ARP request from %s (%s) while in router mode!", source->name, source->hostname); + ifdebug(TRAFFIC) logger(LOG_WARNING, "Got ARP request from %s (%s) while in router mode!", source->name, source->hostname); return; } /* First, snatch the source address from the ARP packet */ if(overwrite_mac) { - memcpy(mymac.x, DATA(packet) + ETH_ALEN, ETH_ALEN); + memcpy(mymac.x, packet->data + ETH_ALEN, ETH_ALEN); } /* Copy headers from packet to structs on the stack */ - memcpy(&arp, DATA(packet) + ether_size, arp_size); + memcpy(&arp, packet->data + ether_size, arp_size); /* Check if this is a valid ARP request */ if(ntohs(arp.arp_hrd) != ARPHRD_ETHER || ntohs(arp.arp_pro) != ETH_P_IP || arp.arp_hln != ETH_ALEN || arp.arp_pln != sizeof(addr) || ntohs(arp.arp_op) != ARPOP_REQUEST) { - logger(DEBUG_TRAFFIC, LOG_WARNING, "Cannot route packet: received unknown type ARP request"); + ifdebug(TRAFFIC) logger(LOG_WARNING, "Cannot route packet: received unknown type ARP request"); return; } @@ -995,9 +987,9 @@ static void route_arp(node_t *source, vpn_packet_t *packet) { subnet = lookup_subnet_ipv4((ipv4_t *) &arp.arp_tpa); if(!subnet) { - logger(DEBUG_TRAFFIC, LOG_WARNING, "Cannot route packet: ARP request for unknown address %d.%d.%d.%d", - arp.arp_tpa[0], arp.arp_tpa[1], arp.arp_tpa[2], - arp.arp_tpa[3]); + ifdebug(TRAFFIC) logger(LOG_WARNING, "Cannot route packet: ARP request for unknown address %d.%d.%d.%d", + arp.arp_tpa[0], arp.arp_tpa[1], arp.arp_tpa[2], + arp.arp_tpa[3]); return; } @@ -1012,18 +1004,20 @@ static void route_arp(node_t *source, vpn_packet_t *packet) { return; } - memcpy(&addr, arp.arp_tpa, sizeof(addr)); /* save protocol addr */ - memcpy(arp.arp_tpa, arp.arp_spa, sizeof(addr)); /* swap destination and source protocol address */ - memcpy(arp.arp_spa, &addr, sizeof(addr)); /* ... */ + memcpy(packet->data, packet->data + ETH_ALEN, ETH_ALEN); /* copy destination address */ + packet->data[ETH_ALEN * 2 - 1] ^= 0xFF; /* mangle source address so it looks like it's not from us */ - memcpy(arp.arp_tha, arp.arp_sha, ETH_ALEN); /* set target hard/proto addr */ - memcpy(arp.arp_sha, DATA(packet) + ETH_ALEN, ETH_ALEN); /* set source hard/proto addr */ - arp.arp_sha[ETH_ALEN - 1] ^= 0xFF; /* for consistency with route_packet() */ + memcpy(&addr, arp.arp_tpa, sizeof(addr)); /* save protocol addr */ + memcpy(arp.arp_tpa, arp.arp_spa, sizeof(addr)); /* swap destination and source protocol address */ + memcpy(arp.arp_spa, &addr, sizeof(addr)); /* ... */ + + memcpy(arp.arp_tha, arp.arp_sha, ETH_ALEN); /* set target hard/proto addr */ + memcpy(arp.arp_sha, packet->data + ETH_ALEN, ETH_ALEN); /* add fake source hard addr */ arp.arp_op = htons(ARPOP_REPLY); /* Copy structs on stack back to packet */ - memcpy(DATA(packet) + ether_size, &arp, arp_size); + memcpy(packet->data + ether_size, &arp, arp_size); send_packet(source, packet); } @@ -1036,22 +1030,22 @@ static void route_mac(node_t *source, vpn_packet_t *packet) { if(source == myself) { mac_t src; - memcpy(&src, &DATA(packet)[6], sizeof(src)); + memcpy(&src, &packet->data[6], sizeof(src)); learn_mac(&src); } /* Lookup destination address */ - memcpy(&dest, &DATA(packet)[0], sizeof(dest)); + memcpy(&dest, &packet->data[0], sizeof(dest)); subnet = lookup_subnet_mac(NULL, &dest); - if(!subnet || !subnet->owner) { + if(!subnet) { route_broadcast(source, packet); return; } if(subnet->owner == source) { - logger(DEBUG_TRAFFIC, LOG_WARNING, "Packet looping back to %s (%s)!", source->name, source->hostname); + ifdebug(TRAFFIC) logger(LOG_WARNING, "Packet looping back to %s (%s)!", source->name, source->hostname); return; } @@ -1064,13 +1058,13 @@ static void route_mac(node_t *source, vpn_packet_t *packet) { return; } - uint16_t type = DATA(packet)[12] << 8 | DATA(packet)[13]; + uint16_t type = packet->data[12] << 8 | packet->data[13]; if(priorityinheritance) { if(type == ETH_P_IP && packet->len >= ether_size + ip_size) { - packet->priority = DATA(packet)[15]; + packet->priority = packet->data[15]; } else if(type == ETH_P_IPV6 && packet->len >= ether_size + ip6_size) { - packet->priority = ((DATA(packet)[14] & 0x0f) << 4) | (DATA(packet)[15] >> 4); + packet->priority = ((packet->data[14] & 0x0f) << 4) | (packet->data[15] >> 4); } } @@ -1083,16 +1077,16 @@ static void route_mac(node_t *source, vpn_packet_t *packet) { } if(via && packet->len > via->mtu && via != myself) { - logger(DEBUG_TRAFFIC, LOG_INFO, "Packet for %s (%s) length %d larger than MTU %d", subnet->owner->name, subnet->owner->hostname, packet->len, via->mtu); + 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); length_t ethlen = 14; if(type == ETH_P_8021Q) { - type = DATA(packet)[16] << 8 | DATA(packet)[17]; + type = packet->data[16] << 8 | packet->data[17]; ethlen += 4; } if(type == ETH_P_IP && packet->len > 576 + ethlen) { - if(DATA(packet)[6 + ethlen] & 0x40) { + if(packet->data[6 + ethlen] & 0x40) { packet->len = via->mtu; route_ipv4_unreachable(source, packet, ethlen, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED); } else { @@ -1112,32 +1106,7 @@ static void route_mac(node_t *source, vpn_packet_t *packet) { send_packet(subnet->owner, packet); } -static void send_pcap(vpn_packet_t *packet) { - pcap = false; - - for list_each(connection_t, c, connection_list) { - if(!c->status.pcap) { - continue; - } - - pcap = true; - int len = packet->len; - - if(c->outmaclength && c->outmaclength < len) { - len = c->outmaclength; - } - - if(send_request(c, "%d %d %d", CONTROL, REQ_PCAP, len)) { - send_meta(c, (char *)DATA(packet), len); - } - } -} - void route(node_t *source, vpn_packet_t *packet) { - if(pcap) { - send_pcap(packet); - } - if(forwarding_mode == FMODE_KERNEL && source != myself) { send_packet(myself, packet); return; @@ -1147,10 +1116,10 @@ void route(node_t *source, vpn_packet_t *packet) { return; } - uint16_t type = DATA(packet)[12] << 8 | DATA(packet)[13]; - switch(routing_mode) { - case RMODE_ROUTER: + case RMODE_ROUTER: { + uint16_t type = packet->data[12] << 8 | packet->data[13]; + switch(type) { case ETH_P_ARP: route_arp(source, packet); @@ -1165,11 +1134,11 @@ void route(node_t *source, vpn_packet_t *packet) { break; default: - logger(DEBUG_TRAFFIC, LOG_WARNING, "Cannot route packet from %s (%s): unknown type %hx", source->name, source->hostname, type); + ifdebug(TRAFFIC) logger(LOG_WARNING, "Cannot route packet from %s (%s): unknown type %hx", source->name, source->hostname, type); break; } - - break; + } + break; case RMODE_SWITCH: route_mac(source, packet); diff --git a/src/route.h b/src/route.h index 095448a..5b9e808 100644 --- a/src/route.h +++ b/src/route.h @@ -50,10 +50,10 @@ extern bool directonly; extern bool overwrite_mac; extern bool priorityinheritance; extern int macexpire; -extern bool pcap; extern mac_t mymac; +extern void age_subnets(void); extern void route(struct node_t *source, struct vpn_packet_t *packet); #endif diff --git a/src/rsa.h b/src/rsa.h deleted file mode 100644 index a31ec24..0000000 --- a/src/rsa.h +++ /dev/null @@ -1,36 +0,0 @@ -#ifndef TINC_RSA_H -#define TINC_RSA_H - -/* - rsa.h -- RSA key handling - Copyright (C) 2007-2013 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 - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#ifndef TINC_RSA_INTERNAL -typedef struct rsa rsa_t; -#endif - -extern void rsa_free(rsa_t *rsa); -extern rsa_t *rsa_set_hex_public_key(char *n, char *e) __attribute__((__malloc__)); -extern rsa_t *rsa_set_hex_private_key(char *n, char *e, char *d) __attribute__((__malloc__)); -extern rsa_t *rsa_read_pem_public_key(FILE *fp) __attribute__((__malloc__)); -extern rsa_t *rsa_read_pem_private_key(FILE *fp) __attribute__((__malloc__)); -extern size_t rsa_size(rsa_t *rsa); -extern bool rsa_public_encrypt(rsa_t *rsa, void *in, size_t len, void *out) __attribute__((__warn_unused_result__)); -extern bool rsa_private_decrypt(rsa_t *rsa, void *in, size_t len, void *out) __attribute__((__warn_unused_result__)); - -#endif diff --git a/src/rsagen.h b/src/rsagen.h deleted file mode 100644 index a661607..0000000 --- a/src/rsagen.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef TINC_RSAGEN_H -#define TINC_RSAGEN_H - -/* - rsagen.h -- RSA key generation and export - Copyright (C) 2008-2013 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 - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include "rsa.h" - -extern rsa_t *rsa_generate(size_t bits, unsigned long exponent) __attribute__((__malloc__)); -extern bool rsa_write_pem_public_key(rsa_t *rsa, FILE *fp) __attribute__((__warn_unused_result__)); -extern bool rsa_write_pem_private_key(rsa_t *rsa, FILE *fp) __attribute__((__warn_unused_result__)); - -#endif diff --git a/src/script.c b/src/script.c deleted file mode 100644 index 81216a3..0000000 --- a/src/script.c +++ /dev/null @@ -1,232 +0,0 @@ -/* - script.c -- call an external script - Copyright (C) 1999-2005 Ivo Timmermans, - 2000-2017 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 - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include "system.h" - -#include "conf.h" -#include "device.h" -#include "logger.h" -#include "names.h" -#include "script.h" -#include "xalloc.h" - -#ifdef HAVE_PUTENV -static void unputenv(const char *p) { - const char *e = strchr(p, '='); - - if(!e) { - return; - } - - int len = e - p; -#ifndef HAVE_UNSETENV -#ifdef HAVE_MINGW - // Windows requires putenv("FOO=") to unset %FOO% - len++; -#endif -#endif - char var[len + 1]; - strncpy(var, p, len); - var[len] = 0; -#ifdef HAVE_UNSETENV - unsetenv(var); -#else - // We must keep what we putenv() around in memory. - // To do this without memory leaks, keep things in a list and reuse if possible. - static list_t list = {}; - - for list_each(char, data, &list) { - if(!strcmp(data, var)) { - putenv(data); - return; - } - } - - char *data = xstrdup(var); - list_insert_tail(&list, data); - putenv(data); -#endif -} -#else -static void putenv(const char *p) {} -static void unputenv(const char *p) {} -#endif - -static const int min_env_size = 10; - -int environment_add(environment_t *env, const char *format, ...) { - if(env->n >= env->size) { - env->size = env->n ? env->n * 2 : min_env_size; - env->entries = xrealloc(env->entries, env->size * sizeof(*env->entries)); - } - - if(format) { - va_list ap; - va_start(ap, format); - vasprintf(&env->entries[env->n], format, ap); - va_end(ap); - } else { - env->entries[env->n] = NULL; - } - - return env->n++; -} - -void environment_update(environment_t *env, int pos, const char *format, ...) { - free(env->entries[pos]); - va_list ap; - va_start(ap, format); - vasprintf(&env->entries[pos], format, ap); - va_end(ap); -} - -void environment_init(environment_t *env) { - env->n = 0; - env->size = min_env_size; - env->entries = xzalloc(env->size * sizeof(*env->entries)); - - if(netname) { - environment_add(env, "NETNAME=%s", netname); - } - - if(myname) { - environment_add(env, "NAME=%s", myname); - } - - if(device) { - environment_add(env, "DEVICE=%s", device); - } - - if(iface) { - environment_add(env, "INTERFACE=%s", iface); - } - - if(debug_level >= 0) { - environment_add(env, "DEBUG=%d", debug_level); - } -} - -void environment_exit(environment_t *env) { - for(int i = 0; i < env->n; i++) { - free(env->entries[i]); - } - - free(env->entries); -} - -bool execute_script(const char *name, environment_t *env) { - char scriptname[PATH_MAX]; - char *command; - - snprintf(scriptname, sizeof(scriptname), "%s" SLASH "%s%s", confbase, name, scriptextension); - - /* First check if there is a script */ - -#ifdef HAVE_MINGW - - if(!*scriptextension) { - const char *pathext = getenv("PATHEXT") ? : ".COM;.EXE;.BAT;.CMD"; - size_t pathlen = strlen(pathext); - size_t scriptlen = strlen(scriptname); - char fullname[scriptlen + pathlen + 1]; - char *ext = fullname + scriptlen; - strncpy(fullname, scriptname, sizeof(fullname)); - - const char *p = pathext; - bool found = false; - - while(p && *p) { - const char *q = strchr(p, ';'); - - if(q) { - memcpy(ext, p, q - p); - ext[q - p] = 0; - q++; - } else { - strncpy(ext, p, pathlen + 1); - } - - if((found = !access(fullname, F_OK))) { - break; - } - - p = q; - } - - if(!found) { - return true; - } - } else -#endif - - if(access(scriptname, F_OK)) { - return true; - } - - logger(DEBUG_STATUS, LOG_INFO, "Executing script %s", name); - - /* Set environment */ - - for(int i = 0; i < env->n; i++) { - putenv(env->entries[i]); - } - - if(scriptinterpreter) { - xasprintf(&command, "%s \"%s\"", scriptinterpreter, scriptname); - } else { - xasprintf(&command, "\"%s\"", scriptname); - } - - int status = system(command); - - free(command); - - /* Unset environment */ - - for(int i = 0; i < env->n; i++) { - unputenv(env->entries[i]); - } - - if(status != -1) { -#ifdef WEXITSTATUS - - if(WIFEXITED(status)) { /* Child exited by itself */ - if(WEXITSTATUS(status)) { - logger(DEBUG_ALWAYS, LOG_ERR, "Script %s exited with non-zero status %d", - name, WEXITSTATUS(status)); - return false; - } - } else if(WIFSIGNALED(status)) { /* Child was killed by a signal */ - logger(DEBUG_ALWAYS, LOG_ERR, "Script %s was killed by signal %d (%s)", - name, WTERMSIG(status), strsignal(WTERMSIG(status))); - return false; - } else { /* Something strange happened */ - logger(DEBUG_ALWAYS, LOG_ERR, "Script %s terminated abnormally", name); - return false; - } - -#endif - } else { - logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "system", strerror(errno)); - return false; - } - - return true; -} diff --git a/src/script.h b/src/script.h deleted file mode 100644 index 5172034..0000000 --- a/src/script.h +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef TINC_SCRIPT_H -#define TINC_SCRIPT_H - -/* - script.h -- header file for script.c - Copyright (C) 1999-2005 Ivo Timmermans, - 2000-2017 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 - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -typedef struct environment { - int n; - int size; - char **entries; -} environment_t; - -extern int environment_add(environment_t *env, const char *format, ...); -extern int environment_placeholder(environment_t *env); -extern void environment_update(environment_t *env, int pos, const char *format, ...); -extern void environment_init(environment_t *env); -extern void environment_exit(environment_t *env); - -extern bool execute_script(const char *name, environment_t *env); - -#endif diff --git a/src/solaris/device.c b/src/solaris/device.c index f27954b..fa2e6e6 100644 --- a/src/solaris/device.c +++ b/src/solaris/device.c @@ -2,7 +2,7 @@ device.c -- Interaction with Solaris tun device Copyright (C) 2001-2005 Ivo Timmermans, 2002-2010 OpenVPN Technologies, Inc. - 2001-2014 Guus Sliepen + 2001-2017 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 @@ -29,7 +29,6 @@ #include "../conf.h" #include "../device.h" #include "../logger.h" -#include "../names.h" #include "../net.h" #include "../route.h" #include "../utils.h" @@ -50,11 +49,15 @@ static enum { } device_type = DEVICE_TYPE_TUN; int device_fd = -1; +static int if_fd = -1; static int ip_fd = -1; char *device = NULL; char *iface = NULL; static const char *device_info = NULL; +uint64_t device_total_in = 0; +uint64_t device_total_out = 0; + static bool setup_device(void) { char *type; @@ -72,7 +75,7 @@ static bool setup_device(void) { else if(!strcasecmp(type, "tap")) { device_type = DEVICE_TYPE_TAP; } else { - logger(DEBUG_ALWAYS, LOG_ERR, "Unknown device type %s!", type); + logger(LOG_ERR, "Unknown device type %s!", type); return false; } } else { @@ -87,15 +90,19 @@ static bool setup_device(void) { device_info = "Solaris tap device"; } + if(device_type == DEVICE_TYPE_TAP && routing_mode == RMODE_ROUTER) { + overwrite_mac = true; + } + /* The following is black magic copied from OpenVPN. */ if((ip_fd = open(IP_DEVICE, O_RDWR, 0)) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not open %s: %s\n", IP_DEVICE, strerror(errno)); + logger(LOG_ERR, "Could not open %s: %s\n", IP_DEVICE, strerror(errno)); return false; } if((device_fd = open(device, O_RDWR, 0)) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not open %s: %s\n", device, strerror(errno)); + logger(LOG_ERR, "Could not open %s: %s\n", device, strerror(errno)); return false; } @@ -134,25 +141,23 @@ static bool setup_device(void) { } if(!found) { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not find free PPA for %s %s!", device_info, device); + logger(LOG_ERR, "Could not find free PPA for %s %s!", device_info, device); return false; } } else { /* try this particular one */ if((ppa = ioctl(device_fd, I_STR, &strioc_ppa)) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not assign PPA %d for %s %s!", ppa, device_info, device); + logger(LOG_ERR, "Could not assign PPA %d for %s %s!", ppa, device_info, device); return false; } } - int if_fd; - if((if_fd = open(device, O_RDWR, 0)) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not open %s: %s\n", device, strerror(errno)); + logger(LOG_ERR, "Could not open %s: %s\n", device, strerror(errno)); return false; } if(ioctl(if_fd, I_PUSH, "ip") < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not push IP module onto %s %s!", device_info, device); + logger(LOG_ERR, "Could not push IP module onto %s %s!", device_info, device); return false; } @@ -174,7 +179,7 @@ static bool setup_device(void) { if(device_type == DEVICE_TYPE_TUN) { /* Assign ppa according to the unit number returned by tun device */ if(ioctl(if_fd, IF_UNITSEL, (char *)&ppa) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not set PPA %d on %s %s!", ppa, device_info, device); + logger(LOG_ERR, "Could not set PPA %d on %s %s!", ppa, device_info, device); return false; } } @@ -185,7 +190,7 @@ static bool setup_device(void) { struct lifreq ifr = {}; if(ioctl(if_fd, SIOCGLIFFLAGS, &ifr) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not set flags on %s %s!", device_info, device); + logger(LOG_ERR, "Could not set flags on %s %s!", device_info, device); return false; } @@ -194,18 +199,18 @@ static bool setup_device(void) { /* Assign ppa according to the unit number returned by tun device */ if(ioctl(if_fd, SIOCSLIFNAME, &ifr) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not set PPA %d on %s %s!", ppa, device_info, device); + logger(LOG_ERR, "Could not set PPA %d on %s %s!", ppa, device_info, device); return false; } if(ioctl(if_fd, SIOCGLIFFLAGS, &ifr) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not set flags on %s %s!", device_info, device); + logger(LOG_ERR, "Could not set flags on %s %s!", device_info, device); return false; } /* Push arp module to if_fd */ if(ioctl(if_fd, I_PUSH, "arp") < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not push ARP module onto %s %s!", device_info, device); + logger(LOG_ERR, "Could not push ARP module onto %s %s!", device_info, device); return false; } @@ -218,19 +223,19 @@ static bool setup_device(void) { /* Push arp module to ip_fd */ if(ioctl(ip_fd, I_PUSH, "arp") < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not push ARP module onto %s!", IP_DEVICE); + logger(LOG_ERR, "Could not push ARP module onto %s!", IP_DEVICE); return false; } /* Open arp_fd */ if((arp_fd = open(device, O_RDWR, 0)) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not open %s: %s\n", device, strerror(errno)); + logger(LOG_ERR, "Could not open %s: %s\n", device, strerror(errno)); return false; } /* Push arp module to arp_fd */ if(ioctl(arp_fd, I_PUSH, "arp") < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not push ARP module onto %s %s!", device_info, device); + logger(LOG_ERR, "Could not push ARP module onto %s %s!", device_info, device); return false; } @@ -242,7 +247,7 @@ static bool setup_device(void) { }; if(ioctl(arp_fd, I_STR, &strioc_if) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not set ifname to %s %s", device_info, device); + logger(LOG_ERR, "Could not set ifname to %s %s", device_info, device); return false; } } @@ -250,13 +255,13 @@ static bool setup_device(void) { int ip_muxid, arp_muxid; if((ip_muxid = ioctl(ip_fd, I_PLINK, if_fd)) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not link %s %s to IP", device_info, device); + logger(LOG_ERR, "Could not link %s %s to IP", device_info, device); return false; } if(device_type == DEVICE_TYPE_TAP) { if((arp_muxid = ioctl(ip_fd, I_PLINK, arp_fd)) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not link %s %s to ARP", device_info, device); + logger(LOG_ERR, "Could not link %s %s to ARP", device_info, device); return false; } @@ -279,7 +284,7 @@ static bool setup_device(void) { } ioctl(ip_fd, I_PUNLINK, ip_muxid); - logger(DEBUG_ALWAYS, LOG_ERR, "Could not set multiplexor id for %s %s", device_info, device); + logger(LOG_ERR, "Could not set multiplexor id for %s %s", device_info, device); return false; } @@ -290,7 +295,7 @@ static bool setup_device(void) { fcntl(ip_fd, F_SETFD, FD_CLOEXEC); #endif - logger(DEBUG_ALWAYS, LOG_INFO, "%s is a %s", device, device_info); + logger(LOG_INFO, "%s is a %s", device, device_info); return true; } @@ -309,14 +314,10 @@ static void close_device(void) { } close(ip_fd); - ip_fd = -1; close(device_fd); - device_fd = -1; free(device); - device = NULL; free(iface); - iface = NULL; } static bool read_packet(vpn_packet_t *packet) { @@ -327,36 +328,36 @@ static bool read_packet(vpn_packet_t *packet) { switch(device_type) { case DEVICE_TYPE_TUN: sbuf.maxlen = MTU - 14; - sbuf.buf = (char *)DATA(packet) + 14; + sbuf.buf = (char *)packet->data + 14; if((result = getmsg(device_fd, NULL, &sbuf, &f)) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info, device, strerror(errno)); + logger(LOG_ERR, "Error while reading from %s %s: %s", device_info, device, strerror(errno)); return false; } - switch(DATA(packet)[14] >> 4) { + switch(packet->data[14] >> 4) { case 4: - DATA(packet)[12] = 0x08; - DATA(packet)[13] = 0x00; + packet->data[12] = 0x08; + packet->data[13] = 0x00; break; case 6: - DATA(packet)[12] = 0x86; - DATA(packet)[13] = 0xDD; + packet->data[12] = 0x86; + packet->data[13] = 0xDD; break; default: - logger(DEBUG_TRAFFIC, LOG_ERR, "Unknown IP version %d while reading packet from %s %s", DATA(packet)[14] >> 4, device_info, device); + ifdebug(TRAFFIC) logger(LOG_ERR, "Unknown IP version %d while reading packet from %s %s", packet->data[14] >> 4, device_info, device); return false; } - memset(DATA(packet), 0, 12); + memset(packet->data, 0, 12); packet->len = sbuf.len + 14; break; case DEVICE_TYPE_TAP: sbuf.maxlen = MTU; - sbuf.buf = (char *)DATA(packet); + sbuf.buf = (char *)packet->data; if((result = getmsg(device_fd, NULL, &sbuf, &f)) < 0) { logger(LOG_ERR, "Error while reading from %s %s: %s", device_info, device, strerror(errno)); @@ -370,20 +371,22 @@ static bool read_packet(vpn_packet_t *packet) { abort(); } - logger(DEBUG_TRAFFIC, LOG_DEBUG, "Read packet of %d bytes from %s", packet->len, device_info); + device_total_in += packet->len; + + ifdebug(TRAFFIC) logger(LOG_DEBUG, "Read packet of %d bytes from %s", packet->len, device_info); return true; } static bool write_packet(vpn_packet_t *packet) { - logger(DEBUG_TRAFFIC, LOG_DEBUG, "Writing packet of %d bytes to %s", packet->len, device_info); + ifdebug(TRAFFIC) logger(LOG_DEBUG, "Writing packet of %d bytes to %s", packet->len, device_info); struct strbuf sbuf; switch(device_type) { case DEVICE_TYPE_TUN: sbuf.len = packet->len - 14; - sbuf.buf = (char *)DATA(packet) + 14; + sbuf.buf = (char *)packet->data + 14; if(putmsg(device_fd, NULL, &sbuf, 0) < 0) { logger(LOG_ERR, "Can't write to %s %s: %s", device_info, device, strerror(errno)); @@ -394,7 +397,7 @@ static bool write_packet(vpn_packet_t *packet) { case DEVICE_TYPE_TAP: sbuf.len = packet->len; - sbuf.buf = (char *)DATA(packet); + sbuf.buf = (char *)packet->data; if(putmsg(device_fd, NULL, &sbuf, 0) < 0) { logger(LOG_ERR, "Can't write to %s %s: %s", device_info, device, strerror(errno)); @@ -407,12 +410,21 @@ static bool write_packet(vpn_packet_t *packet) { abort(); } + device_total_out += packet->len; + return true; } +static void dump_device_stats(void) { + logger(LOG_DEBUG, "Statistics for %s %s:", device_info, device); + logger(LOG_DEBUG, " total bytes in: %10"PRIu64, device_total_in); + logger(LOG_DEBUG, " total bytes out: %10"PRIu64, device_total_out); +} + const devops_t os_devops = { .setup = setup_device, .close = close_device, .read = read_packet, .write = write_packet, + .dump_stats = dump_device_stats, }; diff --git a/src/splay_tree.c b/src/splay_tree.c deleted file mode 100644 index 4d97373..0000000 --- a/src/splay_tree.c +++ /dev/null @@ -1,630 +0,0 @@ -/* - splay_tree.c -- splay tree and linked list convenience - Copyright (C) 2004-2013 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 - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include "system.h" - -#include "splay_tree.h" -#include "xalloc.h" - -/* Splay operation */ - -static splay_node_t *splay_top_down(splay_tree_t *tree, const void *data, int *result) { - splay_node_t left = {0}, right = {0}; - splay_node_t *leftbottom = &left, *rightbottom = &right, *child, *grandchild; - splay_node_t *root = tree->root; - int c; - - if(!root) { - if(result) { - *result = 0; - } - - return NULL; - } - - while((c = tree->compare(data, root->data))) { - if(c < 0 && (child = root->left)) { - c = tree->compare(data, child->data); - - if(c < 0 && (grandchild = child->left)) { - rightbottom->left = child; - child->parent = rightbottom; - rightbottom = child; - - if((root->left = child->right)) { - child->right->parent = root; - } - - child->right = root; - root->parent = child; - - child->left = NULL; - grandchild->parent = NULL; - - root = grandchild; - } else if(c > 0 && (grandchild = child->right)) { - leftbottom->right = child; - child->parent = leftbottom; - leftbottom = child; - - child->right = NULL; - grandchild->parent = NULL; - - rightbottom->left = root; - root->parent = rightbottom; - rightbottom = root; - - root->left = NULL; - - root = grandchild; - } else { - rightbottom->left = root; - root->parent = rightbottom; - rightbottom = root; - - root->left = NULL; - child->parent = NULL; - - root = child; - break; - } - } else if(c > 0 && (child = root->right)) { - c = tree->compare(data, child->data); - - if(c > 0 && (grandchild = child->right)) { - leftbottom->right = child; - child->parent = leftbottom; - leftbottom = child; - - if((root->right = child->left)) { - child->left->parent = root; - } - - child->left = root; - root->parent = child; - - child->right = NULL; - grandchild->parent = NULL; - - root = grandchild; - } else if(c < 0 && (grandchild = child->left)) { - rightbottom->left = child; - child->parent = rightbottom; - rightbottom = child; - - child->left = NULL; - grandchild->parent = NULL; - - leftbottom->right = root; - root->parent = leftbottom; - leftbottom = root; - - root->right = NULL; - - root = grandchild; - } else { - leftbottom->right = root; - root->parent = leftbottom; - leftbottom = root; - - root->right = NULL; - child->parent = NULL; - - root = child; - break; - } - } else { - break; - } - } - - /* Merge trees */ - - if(left.right) { - if(root->left) { - leftbottom->right = root->left; - root->left->parent = leftbottom; - } - - root->left = left.right; - left.right->parent = root; - } - - if(right.left) { - if(root->right) { - rightbottom->left = root->right; - root->right->parent = rightbottom; - } - - root->right = right.left; - right.left->parent = root; - } - - /* Return result */ - - tree->root = root; - - if(result) { - *result = c; - } - - return tree->root; -} - -static void splay_bottom_up(splay_tree_t *tree, splay_node_t *node) { - splay_node_t *parent, *grandparent, *greatgrandparent; - - while((parent = node->parent)) { - if(!(grandparent = parent->parent)) { /* zig */ - if(node == parent->left) { - if((parent->left = node->right)) { - parent->left->parent = parent; - } - - node->right = parent; - } else { - if((parent->right = node->left)) { - parent->right->parent = parent; - } - - node->left = parent; - } - - parent->parent = node; - node->parent = NULL; - } else { - greatgrandparent = grandparent->parent; - - if(node == parent->left && parent == grandparent->left) { /* left zig-zig */ - if((grandparent->left = parent->right)) { - grandparent->left->parent = grandparent; - } - - parent->right = grandparent; - grandparent->parent = parent; - - if((parent->left = node->right)) { - parent->left->parent = parent; - } - - node->right = parent; - parent->parent = node; - } else if(node == parent->right && parent == grandparent->right) { /* right zig-zig */ - if((grandparent->right = parent->left)) { - grandparent->right->parent = grandparent; - } - - parent->left = grandparent; - grandparent->parent = parent; - - if((parent->right = node->left)) { - parent->right->parent = parent; - } - - node->left = parent; - parent->parent = node; - } else if(node == parent->right && parent == grandparent->left) { /* left-right zig-zag */ - if((parent->right = node->left)) { - parent->right->parent = parent; - } - - node->left = parent; - parent->parent = node; - - if((grandparent->left = node->right)) { - grandparent->left->parent = grandparent; - } - - node->right = grandparent; - grandparent->parent = node; - } else { /* right-left zig-zag */ - if((parent->left = node->right)) { - parent->left->parent = parent; - } - - node->right = parent; - parent->parent = node; - - if((grandparent->right = node->left)) { - grandparent->right->parent = grandparent; - } - - node->left = grandparent; - grandparent->parent = node; - } - - if((node->parent = greatgrandparent)) { - if(grandparent == greatgrandparent->left) { - greatgrandparent->left = node; - } else { - greatgrandparent->right = node; - } - } - } - } - - tree->root = node; -} - -/* (De)constructors */ - -splay_tree_t *splay_alloc_tree(splay_compare_t compare, splay_action_t delete) { - splay_tree_t *tree; - - tree = xzalloc(sizeof(splay_tree_t)); - tree->compare = compare; - tree->delete = delete; - - return tree; -} - -void splay_free_tree(splay_tree_t *tree) { - free(tree); -} - -splay_node_t *splay_alloc_node(void) { - return xzalloc(sizeof(splay_node_t)); -} - -void splay_free_node(splay_tree_t *tree, splay_node_t *node) { - if(node->data && tree->delete) { - tree->delete(node->data); - } - - free(node); -} - -/* Searching */ - -void *splay_search(splay_tree_t *tree, const void *data) { - splay_node_t *node; - - node = splay_search_node(tree, data); - - return node ? node->data : NULL; -} - -void *splay_search_closest(splay_tree_t *tree, const void *data, int *result) { - splay_node_t *node; - - node = splay_search_closest_node(tree, data, result); - - return node ? node->data : NULL; -} - -void *splay_search_closest_smaller(splay_tree_t *tree, const void *data) { - splay_node_t *node; - - node = splay_search_closest_smaller_node(tree, data); - - return node ? node->data : NULL; -} - -void *splay_search_closest_greater(splay_tree_t *tree, const void *data) { - splay_node_t *node; - - node = splay_search_closest_greater_node(tree, data); - - return node ? node->data : NULL; -} - -splay_node_t *splay_search_node(splay_tree_t *tree, const void *data) { - splay_node_t *node; - int result; - - node = splay_search_closest_node(tree, data, &result); - - return result ? NULL : node; -} - -splay_node_t *splay_search_closest_node_nosplay(const splay_tree_t *tree, const void *data, int *result) { - splay_node_t *node; - int c; - - node = tree->root; - - if(!node) { - if(result) { - *result = 0; - } - - return NULL; - } - - for(;;) { - c = tree->compare(data, node->data); - - if(c < 0) { - if(node->left) { - node = node->left; - } else { - break; - } - } else if(c > 0) { - if(node->right) { - node = node->right; - } else { - break; - } - } else { - break; - } - } - - if(result) { - *result = c; - } - - return node; -} - -splay_node_t *splay_search_closest_node(splay_tree_t *tree, const void *data, int *result) { - return splay_top_down(tree, data, result); -} - -splay_node_t *splay_search_closest_smaller_node(splay_tree_t *tree, const void *data) { - splay_node_t *node; - int result; - - node = splay_search_closest_node(tree, data, &result); - - if(result < 0) { - node = node->prev; - } - - return node; -} - -splay_node_t *splay_search_closest_greater_node(splay_tree_t *tree, const void *data) { - splay_node_t *node; - int result; - - node = splay_search_closest_node(tree, data, &result); - - if(result > 0) { - node = node->next; - } - - return node; -} - -/* Insertion and deletion */ - -splay_node_t *splay_insert(splay_tree_t *tree, void *data) { - splay_node_t *closest, *new; - int result; - - if(!tree->root) { - new = splay_alloc_node(); - new->data = data; - splay_insert_top(tree, new); - } else { - closest = splay_search_closest_node(tree, data, &result); - - if(!result) { - return NULL; - } - - new = splay_alloc_node(); - new->data = data; - - if(result < 0) { - splay_insert_before(tree, closest, new); - } else { - splay_insert_after(tree, closest, new); - } - } - - return new; -} - -splay_node_t *splay_insert_node(splay_tree_t *tree, splay_node_t *node) { - splay_node_t *closest; - int result; - - node->left = node->right = node->parent = node->next = node->prev = NULL; - - if(!tree->root) { - splay_insert_top(tree, node); - } else { - closest = splay_search_closest_node(tree, node->data, &result); - - if(!result) { - return NULL; - } - - if(result < 0) { - splay_insert_before(tree, closest, node); - } else { - splay_insert_after(tree, closest, node); - } - } - - return node; -} - -void splay_insert_top(splay_tree_t *tree, splay_node_t *node) { - node->prev = node->next = node->left = node->right = node->parent = NULL; - tree->head = tree->tail = tree->root = node; - tree->count++; - tree->generation++; -} - -void splay_insert_before(splay_tree_t *tree, splay_node_t *before, splay_node_t *node) { - if(!before) { - if(tree->tail) { - splay_insert_after(tree, tree->tail, node); - } else { - splay_insert_top(tree, node); - } - - return; - } - - node->next = before; - - if((node->prev = before->prev)) { - before->prev->next = node; - } else { - tree->head = node; - } - - before->prev = node; - - splay_bottom_up(tree, before); - - node->right = before; - before->parent = node; - - if((node->left = before->left)) { - before->left->parent = node; - } - - before->left = NULL; - - node->parent = NULL; - tree->root = node; - tree->count++; - tree->generation++; -} - -void splay_insert_after(splay_tree_t *tree, splay_node_t *after, splay_node_t *node) { - if(!after) { - if(tree->head) { - splay_insert_before(tree, tree->head, node); - } else { - splay_insert_top(tree, node); - } - - return; - } - - node->prev = after; - - if((node->next = after->next)) { - after->next->prev = node; - } else { - tree->tail = node; - } - - after->next = node; - - splay_bottom_up(tree, after); - - node->left = after; - after->parent = node; - - if((node->right = after->right)) { - after->right->parent = node; - } - - after->right = NULL; - - node->parent = NULL; - tree->root = node; - tree->count++; - tree->generation++; -} - -splay_node_t *splay_unlink(splay_tree_t *tree, void *data) { - splay_node_t *node; - - node = splay_search_node(tree, data); - - if(node) { - splay_unlink_node(tree, node); - } - - return node; -} - -void splay_unlink_node(splay_tree_t *tree, splay_node_t *node) { - if(node->prev) { - node->prev->next = node->next; - } else { - tree->head = node->next; - } - - if(node->next) { - node->next->prev = node->prev; - } else { - tree->tail = node->prev; - } - - splay_bottom_up(tree, node); - - if(node->prev) { - node->left->parent = NULL; - tree->root = node->left; - - if((node->prev->right = node->right)) { - node->right->parent = node->prev; - } - } else if(node->next) { - tree->root = node->right; - node->right->parent = NULL; - } else { - tree->root = NULL; - } - - tree->count--; - tree->generation++; -} - -void splay_delete_node(splay_tree_t *tree, splay_node_t *node) { - splay_unlink_node(tree, node); - splay_free_node(tree, node); -} - -void splay_delete(splay_tree_t *tree, void *data) { - splay_node_t *node; - - node = splay_search_node(tree, data); - - if(node) { - splay_delete_node(tree, node); - } -} - -/* Fast tree cleanup */ - -void splay_delete_tree(splay_tree_t *tree) { - for(splay_node_t *node = tree->head, *next; node; node = next) { - next = node->next; - splay_free_node(tree, node); - } - - splay_free_tree(tree); -} - -/* Tree walking */ - -void splay_foreach(const splay_tree_t *tree, splay_action_t action) { - for(splay_node_t *node = tree->head, *next; node; node = next) { - next = node->next; - action(node->data); - } -} - -void splay_foreach_node(const splay_tree_t *tree, splay_action_t action) { - for(splay_node_t *node = tree->head, *next; node; node = next) { - next = node->next; - action(node); - } -} diff --git a/src/splay_tree.h b/src/splay_tree.h deleted file mode 100644 index d5ab742..0000000 --- a/src/splay_tree.h +++ /dev/null @@ -1,117 +0,0 @@ -#ifndef TINC_SPLAY_TREE_H -#define TINC_SPLAY_TREE_H - -/* - splay_tree.h -- header file for splay_tree.c - Copyright (C) 2004-2013 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 - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -typedef struct splay_node_t { - - /* Linked list part */ - - struct splay_node_t *next; - struct splay_node_t *prev; - - /* Tree part */ - - struct splay_node_t *parent; - struct splay_node_t *left; - struct splay_node_t *right; - - /* Payload */ - - void *data; - -} splay_node_t; - -typedef int (*splay_compare_t)(const void *data1, const void *data2); -typedef void (*splay_action_t)(const void *data); -typedef void (*splay_action_node_t)(const splay_node_t *node); - -typedef struct splay_tree_t { - - /* Linked list part */ - - splay_node_t *head; - splay_node_t *tail; - - /* Tree part */ - - splay_node_t *root; - - splay_compare_t compare; - splay_action_t delete; - - unsigned int count; - unsigned int generation; - -} splay_tree_t; - -/* (De)constructors */ - -extern splay_tree_t *splay_alloc_tree(splay_compare_t compare, splay_action_t delete) __attribute__((__malloc__)); -extern void splay_free_tree(splay_tree_t *tree); - -extern splay_node_t *splay_alloc_node(void) __attribute__((__malloc__)); -extern void splay_free_node(splay_tree_t *tree, splay_node_t *node); - -/* Insertion and deletion */ - -extern splay_node_t *splay_insert(splay_tree_t *tree, void *data); -extern splay_node_t *splay_insert_node(splay_tree_t *tree, splay_node_t *node); - -extern void splay_insert_top(splay_tree_t *tree, splay_node_t *node); -extern void splay_insert_before(splay_tree_t *tree, splay_node_t *before, splay_node_t *node); -extern void splay_insert_after(splay_tree_t *tree, splay_node_t *after, splay_node_t *node); - -extern splay_node_t *splay_unlink(splay_tree_t *tree, void *data); -extern void splay_unlink_node(splay_tree_t *tree, splay_node_t *node); -extern void splay_delete(splay_tree_t *tree, void *data); -extern void splay_delete_node(splay_tree_t *tree, splay_node_t *node); - -/* Fast tree cleanup */ - -extern void splay_delete_tree(splay_tree_t *tree); - -/* Searching */ - -extern void *splay_search(splay_tree_t *tree, const void *data); -extern void *splay_search_closest(splay_tree_t *tree, const void *data, int *result); -extern void *splay_search_closest_smaller(splay_tree_t *tree, const void *data); -extern void *splay_search_closest_greater(splay_tree_t *tree, const void *data); - -extern splay_node_t *splay_search_node(splay_tree_t *tree, const void *data); -extern splay_node_t *splay_search_closest_node(splay_tree_t *tree, const void *data, int *result); -extern splay_node_t *splay_search_closest_node_nosplay(const splay_tree_t *tree, const void *data, int *result); -extern splay_node_t *splay_search_closest_smaller_node(splay_tree_t *tree, const void *data); -extern splay_node_t *splay_search_closest_greater_node(splay_tree_t *tree, const void *data); - -/* Tree walking */ - -extern void splay_foreach(const splay_tree_t *tree, splay_action_t action); -extern void splay_foreach_node(const splay_tree_t *tree, splay_action_t action); - -/* - Iterates over a tree. - - CAUTION: while this construct supports deleting the current item, - it does *not* support deleting *other* nodes while iterating on the tree. - */ -#define splay_each(type, item, tree) (type *item = (type *)1; item; item = NULL) for(splay_node_t *node = (tree)->head, *next; item = node ? node->data : NULL, next = node ? node->next : NULL, node; node = next) - -#endif diff --git a/src/sptps.c b/src/sptps.c deleted file mode 100644 index eeaf833..0000000 --- a/src/sptps.c +++ /dev/null @@ -1,767 +0,0 @@ -/* - sptps.c -- Simple Peer-to-Peer Security - Copyright (C) 2011-2015 Guus Sliepen , - 2010 Brandon L. Black - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include "system.h" - -#include "chacha-poly1305/chacha-poly1305.h" -#include "crypto.h" -#include "ecdh.h" -#include "ecdsa.h" -#include "logger.h" -#include "prf.h" -#include "sptps.h" - -unsigned int sptps_replaywin = 16; - -/* - Nonce MUST be exchanged first (done) - Signatures MUST be done over both nonces, to guarantee the signature is fresh - Otherwise: if ECDHE key of one side is compromised, it can be reused! - - Add explicit tag to beginning of structure to distinguish the client and server when signing. (done) - - Sign all handshake messages up to ECDHE kex with long-term public keys. (done) - - HMACed KEX finished message to prevent downgrade attacks and prove you have the right key material (done by virtue of Ed25519 over the whole ECDHE exchange?) - - Explicit close message needs to be added. - - Maybe do add some alert messages to give helpful error messages? Not more than TLS sends. - - Use counter mode instead of OFB. (done) - - Make sure ECC operations are fixed time (aka prevent side-channel attacks). -*/ - -void sptps_log_quiet(sptps_t *s, int s_errno, const char *format, va_list ap) { - (void)s; - (void)s_errno; - (void)format; - (void)ap; -} - -void sptps_log_stderr(sptps_t *s, int s_errno, const char *format, va_list ap) { - (void)s; - (void)s_errno; - - vfprintf(stderr, format, ap); - fputc('\n', stderr); -} - -void (*sptps_log)(sptps_t *s, int s_errno, const char *format, va_list ap) = sptps_log_stderr; - -// Log an error message. -static bool error(sptps_t *s, int s_errno, const char *format, ...) { - (void)s; - (void)s_errno; - - if(format) { - va_list ap; - va_start(ap, format); - sptps_log(s, s_errno, format, ap); - va_end(ap); - } - - errno = s_errno; - return false; -} - -static void warning(sptps_t *s, const char *format, ...) { - va_list ap; - va_start(ap, format); - sptps_log(s, 0, format, ap); - va_end(ap); -} - -// Send a record (datagram version, accepts all record types, handles encryption and authentication). -static bool send_record_priv_datagram(sptps_t *s, uint8_t type, const void *data, uint16_t len) { - char buffer[len + 21UL]; - - // Create header with sequence number, length and record type - uint32_t seqno = s->outseqno++; - uint32_t netseqno = ntohl(seqno); - - memcpy(buffer, &netseqno, 4); - buffer[4] = type; - memcpy(buffer + 5, data, len); - - if(s->outstate) { - // If first handshake has finished, encrypt and HMAC - chacha_poly1305_encrypt(s->outcipher, seqno, buffer + 4, len + 1, buffer + 4, NULL); - return s->send_data(s->handle, type, buffer, len + 21UL); - } else { - // Otherwise send as plaintext - return s->send_data(s->handle, type, buffer, len + 5UL); - } -} -// Send a record (private version, accepts all record types, handles encryption and authentication). -static bool send_record_priv(sptps_t *s, uint8_t type, const void *data, uint16_t len) { - if(s->datagram) { - return send_record_priv_datagram(s, type, data, len); - } - - char buffer[len + 19UL]; - - // Create header with sequence number, length and record type - uint32_t seqno = s->outseqno++; - uint16_t netlen = htons(len); - - memcpy(buffer, &netlen, 2); - buffer[2] = type; - memcpy(buffer + 3, data, len); - - if(s->outstate) { - // If first handshake has finished, encrypt and HMAC - chacha_poly1305_encrypt(s->outcipher, seqno, buffer + 2, len + 1, buffer + 2, NULL); - return s->send_data(s->handle, type, buffer, len + 19UL); - } else { - // Otherwise send as plaintext - return s->send_data(s->handle, type, buffer, len + 3UL); - } -} - -// Send an application record. -bool sptps_send_record(sptps_t *s, uint8_t type, const void *data, uint16_t len) { - // Sanity checks: application cannot send data before handshake is finished, - // and only record types 0..127 are allowed. - if(!s->outstate) { - return error(s, EINVAL, "Handshake phase not finished yet"); - } - - if(type >= SPTPS_HANDSHAKE) { - return error(s, EINVAL, "Invalid application record type"); - } - - return send_record_priv(s, type, data, len); -} - -// Send a Key EXchange record, containing a random nonce and an ECDHE public key. -static bool send_kex(sptps_t *s) { - size_t keylen = ECDH_SIZE; - - // Make room for our KEX message, which we will keep around since send_sig() needs it. - if(s->mykex) { - return false; - } - - s->mykex = realloc(s->mykex, 1 + 32 + keylen); - - if(!s->mykex) { - return error(s, errno, strerror(errno)); - } - - // Set version byte to zero. - s->mykex[0] = SPTPS_VERSION; - - // Create a random nonce. - randomize(s->mykex + 1, 32); - - // Create a new ECDH public key. - if(!(s->ecdh = ecdh_generate_public(s->mykex + 1 + 32))) { - return error(s, EINVAL, "Failed to generate ECDH public key"); - } - - return send_record_priv(s, SPTPS_HANDSHAKE, s->mykex, 1 + 32 + keylen); -} - -// Send a SIGnature record, containing an Ed25519 signature over both KEX records. -static bool send_sig(sptps_t *s) { - size_t keylen = ECDH_SIZE; - size_t siglen = ecdsa_size(s->mykey); - - // Concatenate both KEX messages, plus tag indicating if it is from the connection originator, plus label - char msg[(1 + 32 + keylen) * 2 + 1 + s->labellen]; - char sig[siglen]; - - msg[0] = s->initiator; - memcpy(msg + 1, s->mykex, 1 + 32 + keylen); - memcpy(msg + 1 + 33 + keylen, s->hiskex, 1 + 32 + keylen); - memcpy(msg + 1 + 2 * (33 + keylen), s->label, s->labellen); - - // Sign the result. - if(!ecdsa_sign(s->mykey, msg, sizeof(msg), sig)) { - return error(s, EINVAL, "Failed to sign SIG record"); - } - - // Send the SIG exchange record. - return send_record_priv(s, SPTPS_HANDSHAKE, sig, sizeof(sig)); -} - -// Generate key material from the shared secret created from the ECDHE key exchange. -static bool generate_key_material(sptps_t *s, const char *shared, size_t len) { - // Initialise cipher and digest structures if necessary - if(!s->outstate) { - s->incipher = chacha_poly1305_init(); - s->outcipher = chacha_poly1305_init(); - - if(!s->incipher || !s->outcipher) { - return error(s, EINVAL, "Failed to open cipher"); - } - } - - // Allocate memory for key material - size_t keylen = 2 * CHACHA_POLY1305_KEYLEN; - - s->key = realloc(s->key, keylen); - - if(!s->key) { - return error(s, errno, strerror(errno)); - } - - // Create the HMAC seed, which is "key expansion" + session label + server nonce + client nonce - char seed[s->labellen + 64 + 13]; - memcpy(seed, "key expansion", 13); - - if(s->initiator) { - memcpy(seed + 13, s->mykex + 1, 32); - memcpy(seed + 45, s->hiskex + 1, 32); - } else { - memcpy(seed + 13, s->hiskex + 1, 32); - memcpy(seed + 45, s->mykex + 1, 32); - } - - memcpy(seed + 77, s->label, s->labellen); - - // Use PRF to generate the key material - if(!prf(shared, len, seed, s->labellen + 64 + 13, s->key, keylen)) { - return error(s, EINVAL, "Failed to generate key material"); - } - - return true; -} - -// Send an ACKnowledgement record. -static bool send_ack(sptps_t *s) { - return send_record_priv(s, SPTPS_HANDSHAKE, "", 0); -} - -// Receive an ACKnowledgement record. -static bool receive_ack(sptps_t *s, const char *data, uint16_t len) { - (void)data; - - if(len) { - return error(s, EIO, "Invalid ACK record length"); - } - - if(s->initiator) { - if(!chacha_poly1305_set_key(s->incipher, s->key)) { - return error(s, EINVAL, "Failed to set counter"); - } - } else { - if(!chacha_poly1305_set_key(s->incipher, s->key + CHACHA_POLY1305_KEYLEN)) { - return error(s, EINVAL, "Failed to set counter"); - } - } - - free(s->key); - s->key = NULL; - s->instate = true; - - return true; -} - -// Receive a Key EXchange record, respond by sending a SIG record. -static bool receive_kex(sptps_t *s, const char *data, uint16_t len) { - // Verify length of the HELLO record - if(len != 1 + 32 + ECDH_SIZE) { - return error(s, EIO, "Invalid KEX record length"); - } - - // Ignore version number for now. - - // Make a copy of the KEX message, send_sig() and receive_sig() need it - if(s->hiskex) { - return error(s, EINVAL, "Received a second KEX message before first has been processed"); - } - - s->hiskex = realloc(s->hiskex, len); - - if(!s->hiskex) { - return error(s, errno, strerror(errno)); - } - - memcpy(s->hiskex, data, len); - - if(s->initiator) { - return send_sig(s); - } else { - return true; - } -} - -// Receive a SIGnature record, verify it, if it passed, compute the shared secret and calculate the session keys. -static bool receive_sig(sptps_t *s, const char *data, uint16_t len) { - size_t keylen = ECDH_SIZE; - size_t siglen = ecdsa_size(s->hiskey); - - // Verify length of KEX record. - if(len != siglen) { - return error(s, EIO, "Invalid KEX record length"); - } - - // Concatenate both KEX messages, plus tag indicating if it is from the connection originator - char msg[(1 + 32 + keylen) * 2 + 1 + s->labellen]; - - msg[0] = !s->initiator; - memcpy(msg + 1, s->hiskex, 1 + 32 + keylen); - memcpy(msg + 1 + 33 + keylen, s->mykex, 1 + 32 + keylen); - memcpy(msg + 1 + 2 * (33 + keylen), s->label, s->labellen); - - // Verify signature. - if(!ecdsa_verify(s->hiskey, msg, sizeof(msg), data)) { - return error(s, EIO, "Failed to verify SIG record"); - } - - // Compute shared secret. - char shared[ECDH_SHARED_SIZE]; - - if(!ecdh_compute_shared(s->ecdh, s->hiskex + 1 + 32, shared)) { - return error(s, EINVAL, "Failed to compute ECDH shared secret"); - } - - s->ecdh = NULL; - - // Generate key material from shared secret. - if(!generate_key_material(s, shared, sizeof(shared))) { - return false; - } - - if(!s->initiator && !send_sig(s)) { - return false; - } - - free(s->mykex); - free(s->hiskex); - - s->mykex = NULL; - s->hiskex = NULL; - - // Send cipher change record - if(s->outstate && !send_ack(s)) { - return false; - } - - // TODO: only set new keys after ACK has been set/received - if(s->initiator) { - if(!chacha_poly1305_set_key(s->outcipher, s->key + CHACHA_POLY1305_KEYLEN)) { - return error(s, EINVAL, "Failed to set key"); - } - } else { - if(!chacha_poly1305_set_key(s->outcipher, s->key)) { - return error(s, EINVAL, "Failed to set key"); - } - } - - return true; -} - -// Force another Key EXchange (for testing purposes). -bool sptps_force_kex(sptps_t *s) { - if(!s->outstate || s->state != SPTPS_SECONDARY_KEX) { - return error(s, EINVAL, "Cannot force KEX in current state"); - } - - s->state = SPTPS_KEX; - return send_kex(s); -} - -// Receive a handshake record. -static bool receive_handshake(sptps_t *s, const char *data, uint16_t len) { - // Only a few states to deal with handshaking. - switch(s->state) { - case SPTPS_SECONDARY_KEX: - - // We receive a secondary KEX request, first respond by sending our own. - if(!send_kex(s)) { - return false; - } - - // Fall through - case SPTPS_KEX: - - // We have sent our KEX request, we expect our peer to sent one as well. - if(!receive_kex(s, data, len)) { - return false; - } - - s->state = SPTPS_SIG; - return true; - - case SPTPS_SIG: - - // If we already sent our secondary public ECDH key, we expect the peer to send his. - if(!receive_sig(s, data, len)) { - return false; - } - - if(s->outstate) { - s->state = SPTPS_ACK; - } else { - s->outstate = true; - - if(!receive_ack(s, NULL, 0)) { - return false; - } - - s->receive_record(s->handle, SPTPS_HANDSHAKE, NULL, 0); - s->state = SPTPS_SECONDARY_KEX; - } - - return true; - - case SPTPS_ACK: - - // We expect a handshake message to indicate transition to the new keys. - if(!receive_ack(s, data, len)) { - return false; - } - - s->receive_record(s->handle, SPTPS_HANDSHAKE, NULL, 0); - s->state = SPTPS_SECONDARY_KEX; - return true; - - // TODO: split ACK into a VERify and ACK? - default: - return error(s, EIO, "Invalid session state %d", s->state); - } -} - -static bool sptps_check_seqno(sptps_t *s, uint32_t seqno, bool update_state) { - // Replay protection using a sliding window of configurable size. - // s->inseqno is expected sequence number - // seqno is received sequence number - // s->late[] is a circular buffer, a 1 bit means a packet has not been received yet - // The circular buffer contains bits for sequence numbers from s->inseqno - s->replaywin * 8 to (but excluding) s->inseqno. - if(s->replaywin) { - if(seqno != s->inseqno) { - if(seqno >= s->inseqno + s->replaywin * 8) { - // Prevent packets that jump far ahead of the queue from causing many others to be dropped. - bool farfuture = s->farfuture < s->replaywin >> 2; - - if(update_state) { - s->farfuture++; - } - - if(farfuture) { - return update_state ? error(s, EIO, "Packet is %d seqs in the future, dropped (%u)\n", seqno - s->inseqno, s->farfuture) : false; - } - - // Unless we have seen lots of them, in which case we consider the others lost. - if(update_state) { - warning(s, "Lost %d packets\n", seqno - s->inseqno); - } - - if(update_state) { - // Mark all packets in the replay window as being late. - memset(s->late, 255, s->replaywin); - } - } else if(seqno < s->inseqno) { - // If the sequence number is farther in the past than the bitmap goes, or if the packet was already received, drop it. - if((s->inseqno >= s->replaywin * 8 && seqno < s->inseqno - s->replaywin * 8) || !(s->late[(seqno / 8) % s->replaywin] & (1 << seqno % 8))) { - return update_state ? error(s, EIO, "Received late or replayed packet, seqno %d, last received %d\n", seqno, s->inseqno) : false; - } - } else if(update_state) { - // We missed some packets. Mark them in the bitmap as being late. - for(uint32_t i = s->inseqno; i < seqno; i++) { - s->late[(i / 8) % s->replaywin] |= 1 << i % 8; - } - } - } - - if(update_state) { - // Mark the current packet as not being late. - s->late[(seqno / 8) % s->replaywin] &= ~(1 << seqno % 8); - s->farfuture = 0; - } - } - - if(update_state) { - if(seqno >= s->inseqno) { - s->inseqno = seqno + 1; - } - - if(!s->inseqno) { - s->received = 0; - } else { - s->received++; - } - } - - return true; -} - -// Check datagram for valid HMAC -bool sptps_verify_datagram(sptps_t *s, const void *vdata, size_t len) { - if(!s->instate || len < 21) { - return error(s, EIO, "Received short packet"); - } - - const char *data = vdata; - uint32_t seqno; - memcpy(&seqno, data, 4); - seqno = ntohl(seqno); - - if(!sptps_check_seqno(s, seqno, false)) { - return false; - } - - char buffer[len]; - size_t outlen; - return chacha_poly1305_decrypt(s->incipher, seqno, data + 4, len - 4, buffer, &outlen); -} - -// Receive incoming data, datagram version. -static bool sptps_receive_data_datagram(sptps_t *s, const char *data, size_t len) { - if(len < (s->instate ? 21 : 5)) { - return error(s, EIO, "Received short packet"); - } - - uint32_t seqno; - memcpy(&seqno, data, 4); - seqno = ntohl(seqno); - data += 4; - len -= 4; - - if(!s->instate) { - if(seqno != s->inseqno) { - return error(s, EIO, "Invalid packet seqno: %d != %d", seqno, s->inseqno); - } - - s->inseqno = seqno + 1; - - uint8_t type = *(data++); - len--; - - if(type != SPTPS_HANDSHAKE) { - return error(s, EIO, "Application record received before handshake finished"); - } - - return receive_handshake(s, data, len); - } - - // Decrypt - - char buffer[len]; - size_t outlen; - - if(!chacha_poly1305_decrypt(s->incipher, seqno, data, len, buffer, &outlen)) { - return error(s, EIO, "Failed to decrypt and verify packet"); - } - - if(!sptps_check_seqno(s, seqno, true)) { - return false; - } - - // Append a NULL byte for safety. - buffer[outlen] = 0; - - data = buffer; - len = outlen; - - uint8_t type = *(data++); - len--; - - if(type < SPTPS_HANDSHAKE) { - if(!s->instate) { - return error(s, EIO, "Application record received before handshake finished"); - } - - if(!s->receive_record(s->handle, type, data, len)) { - return false; - } - } else if(type == SPTPS_HANDSHAKE) { - if(!receive_handshake(s, data, len)) { - return false; - } - } else { - return error(s, EIO, "Invalid record type %d", type); - } - - return true; -} - -// Receive incoming data. Check if it contains a complete record, if so, handle it. -size_t sptps_receive_data(sptps_t *s, const void *vdata, size_t len) { - const char *data = vdata; - size_t total_read = 0; - - if(!s->state) { - return error(s, EIO, "Invalid session state zero"); - } - - if(s->datagram) { - return sptps_receive_data_datagram(s, data, len) ? len : false; - } - - // First read the 2 length bytes. - if(s->buflen < 2) { - size_t toread = 2 - s->buflen; - - if(toread > len) { - toread = len; - } - - memcpy(s->inbuf + s->buflen, data, toread); - - total_read += toread; - s->buflen += toread; - len -= toread; - data += toread; - - // Exit early if we don't have the full length. - if(s->buflen < 2) { - return total_read; - } - - // Get the length bytes - - memcpy(&s->reclen, s->inbuf, 2); - s->reclen = ntohs(s->reclen); - - // If we have the length bytes, ensure our buffer can hold the whole request. - s->inbuf = realloc(s->inbuf, s->reclen + 19UL); - - if(!s->inbuf) { - return error(s, errno, strerror(errno)); - } - - // Exit early if we have no more data to process. - if(!len) { - return total_read; - } - } - - // Read up to the end of the record. - size_t toread = s->reclen + (s->instate ? 19UL : 3UL) - s->buflen; - - if(toread > len) { - toread = len; - } - - memcpy(s->inbuf + s->buflen, data, toread); - total_read += toread; - s->buflen += toread; - - // If we don't have a whole record, exit. - if(s->buflen < s->reclen + (s->instate ? 19UL : 3UL)) { - return total_read; - } - - // Update sequence number. - - uint32_t seqno = s->inseqno++; - - // Check HMAC and decrypt. - if(s->instate) { - if(!chacha_poly1305_decrypt(s->incipher, seqno, s->inbuf + 2UL, s->reclen + 17UL, s->inbuf + 2UL, NULL)) { - return error(s, EINVAL, "Failed to decrypt and verify record"); - } - } - - // Append a NULL byte for safety. - s->inbuf[s->reclen + 3UL] = 0; - - uint8_t type = s->inbuf[2]; - - if(type < SPTPS_HANDSHAKE) { - if(!s->instate) { - return error(s, EIO, "Application record received before handshake finished"); - } - - if(!s->receive_record(s->handle, type, s->inbuf + 3, s->reclen)) { - return false; - } - } else if(type == SPTPS_HANDSHAKE) { - if(!receive_handshake(s, s->inbuf + 3, s->reclen)) { - return false; - } - } else { - return error(s, EIO, "Invalid record type %d", type); - } - - s->buflen = 0; - - return total_read; -} - -// Start a SPTPS session. -bool sptps_start(sptps_t *s, void *handle, bool initiator, bool datagram, ecdsa_t *mykey, ecdsa_t *hiskey, const void *label, size_t labellen, send_data_t send_data, receive_record_t receive_record) { - // Initialise struct sptps - memset(s, 0, sizeof(*s)); - - s->handle = handle; - s->initiator = initiator; - s->datagram = datagram; - s->mykey = mykey; - s->hiskey = hiskey; - s->replaywin = sptps_replaywin; - - if(s->replaywin) { - s->late = malloc(s->replaywin); - - if(!s->late) { - return error(s, errno, strerror(errno)); - } - - memset(s->late, 0, s->replaywin); - } - - s->label = malloc(labellen); - - if(!s->label) { - return error(s, errno, strerror(errno)); - } - - if(!datagram) { - s->inbuf = malloc(7); - - if(!s->inbuf) { - return error(s, errno, strerror(errno)); - } - - s->buflen = 0; - } - - memcpy(s->label, label, labellen); - s->labellen = labellen; - - s->send_data = send_data; - s->receive_record = receive_record; - - // Do first KEX immediately - s->state = SPTPS_KEX; - return send_kex(s); -} - -// Stop a SPTPS session. -bool sptps_stop(sptps_t *s) { - // Clean up any resources. - chacha_poly1305_exit(s->incipher); - chacha_poly1305_exit(s->outcipher); - ecdh_free(s->ecdh); - free(s->inbuf); - free(s->mykex); - free(s->hiskex); - free(s->key); - free(s->label); - free(s->late); - memset(s, 0, sizeof(*s)); - return true; -} diff --git a/src/sptps.h b/src/sptps.h deleted file mode 100644 index f5686f4..0000000 --- a/src/sptps.h +++ /dev/null @@ -1,95 +0,0 @@ -#ifndef TINC_SPTPS_H -#define TINC_SPTPS_H - -/* - sptps.h -- Simple Peer-to-Peer Security - Copyright (C) 2011-2014 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 - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include "system.h" - -#include "chacha-poly1305/chacha-poly1305.h" -#include "ecdh.h" -#include "ecdsa.h" - -#define SPTPS_VERSION 0 - -// Record types -#define SPTPS_HANDSHAKE 128 // Key exchange and authentication -#define SPTPS_ALERT 129 // Warning or error messages -#define SPTPS_CLOSE 130 // Application closed the connection - -// Key exchange states -#define SPTPS_KEX 1 // Waiting for the first Key EXchange record -#define SPTPS_SECONDARY_KEX 2 // Ready to receive a secondary Key EXchange record -#define SPTPS_SIG 3 // Waiting for a SIGnature record -#define SPTPS_ACK 4 // Waiting for an ACKnowledgement record - -// Overhead for datagrams -#define SPTPS_DATAGRAM_OVERHEAD 21 - -typedef bool (*send_data_t)(void *handle, uint8_t type, const void *data, size_t len); -typedef bool (*receive_record_t)(void *handle, uint8_t type, const void *data, uint16_t len); - -typedef struct sptps { - bool initiator; - bool datagram; - int state; - - char *inbuf; - size_t buflen; - uint16_t reclen; - - bool instate; - chacha_poly1305_ctx_t *incipher; - uint32_t inseqno; - uint32_t received; - unsigned int replaywin; - unsigned int farfuture; - char *late; - - bool outstate; - chacha_poly1305_ctx_t *outcipher; - uint32_t outseqno; - - ecdsa_t *mykey; - ecdsa_t *hiskey; - ecdh_t *ecdh; - - char *mykex; - char *hiskex; - char *key; - char *label; - size_t labellen; - - void *handle; - send_data_t send_data; - receive_record_t receive_record; -} sptps_t; - -extern unsigned int sptps_replaywin; -extern void sptps_log_quiet(sptps_t *s, int s_errno, const char *format, va_list ap); -extern void sptps_log_stderr(sptps_t *s, int s_errno, const char *format, va_list ap); -extern void (*sptps_log)(sptps_t *s, int s_errno, const char *format, va_list ap); -extern bool sptps_start(sptps_t *s, void *handle, bool initiator, bool datagram, ecdsa_t *mykey, ecdsa_t *hiskey, const void *label, size_t labellen, send_data_t send_data, receive_record_t receive_record); -extern bool sptps_stop(sptps_t *s); -extern bool sptps_send_record(sptps_t *s, uint8_t type, const void *data, uint16_t len); -extern size_t sptps_receive_data(sptps_t *s, const void *data, size_t len); -extern bool sptps_force_kex(sptps_t *s); -extern bool sptps_verify_datagram(sptps_t *s, const void *data, size_t len); - -#endif diff --git a/src/sptps_keypair.c b/src/sptps_keypair.c deleted file mode 100644 index 51a94ee..0000000 --- a/src/sptps_keypair.c +++ /dev/null @@ -1,123 +0,0 @@ -/* - sptps_test.c -- Simple Peer-to-Peer Security test program - Copyright (C) 2011-2013 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 - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include "system.h" - -#include - -#include "crypto.h" -#include "ecdsagen.h" -#include "utils.h" - -static char *program_name; - -void logger(int level, int priority, const char *format, ...) { - (void)level; - (void)priority; - va_list ap; - - va_start(ap, format); - vfprintf(stderr, format, ap); - va_end(ap); - - fputc('\n', stderr); -} - -static void usage() { - fprintf(stderr, "Usage: %s [options] private_key_file public_key_file\n\n", program_name); - fprintf(stderr, "Valid options are:\n" - " --help Display this help and exit.\n" - "\n"); - fprintf(stderr, "Report bugs to tinc@tinc-vpn.org.\n"); -} - -static struct option const long_options[] = { - {"help", no_argument, NULL, 1}, - {NULL, 0, NULL, 0} -}; - -int main(int argc, char *argv[]) { - program_name = argv[0]; - int r; - int option_index = 0; - - while((r = getopt_long(argc, argv, "", long_options, &option_index)) != EOF) { - switch(r) { - case 0: /* long option */ - break; - - case '?': /* wrong options */ - usage(); - return 1; - - case 1: /* help */ - usage(); - return 0; - - default: - break; - } - } - - argc -= optind - 1; - argv += optind - 1; - - if(argc != 3) { - fprintf(stderr, "Wrong number of arguments.\n"); - usage(); - return 1; - } - - crypto_init(); - - ecdsa_t *key = ecdsa_generate(); - - if(!key) { - return 1; - } - - FILE *fp = fopen(argv[1], "w"); - - if(fp) { - if(!ecdsa_write_pem_private_key(key, fp)) { - fprintf(stderr, "Could not write ECDSA private key\n"); - return 1; - } - - fclose(fp); - } else { - fprintf(stderr, "Could not open '%s' for writing: %s\n", argv[1], strerror(errno)); - return 1; - } - - fp = fopen(argv[2], "w"); - - if(fp) { - if(!ecdsa_write_pem_public_key(key, fp)) { - fprintf(stderr, "Could not write ECDSA public key\n"); - } - - fclose(fp); - } else { - fprintf(stderr, "Could not open '%s' for writing: %s\n", argv[2], strerror(errno)); - return 1; - } - - return 0; -} diff --git a/src/sptps_speed.c b/src/sptps_speed.c deleted file mode 100644 index db7314e..0000000 --- a/src/sptps_speed.c +++ /dev/null @@ -1,308 +0,0 @@ -/* - sptps_speed.c -- SPTPS benchmark - Copyright (C) 2013-2014 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 - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include "system.h" -#include "utils.h" - -#include - -#include "crypto.h" -#include "ecdh.h" -#include "ecdsa.h" -#include "ecdsagen.h" -#include "sptps.h" - -// Symbols necessary to link with logger.o -bool send_request(void *c, const char *msg, ...) { - return false; -} -struct list_t *connection_list = NULL; -bool send_meta(void *c, const char *msg, int len) { - return false; -} -char *logfilename = NULL; -bool do_detach = false; -struct timeval now; - -static bool send_data(void *handle, uint8_t type, const void *data, size_t len) { - int fd = *(int *)handle; - send(fd, data, len, 0); - return true; -} - -static bool receive_record(void *handle, uint8_t type, const void *data, uint16_t len) { - return true; -} - -static void receive_data(sptps_t *sptps) { - char buf[4096], *bufp = buf; - int fd = *(int *)sptps->handle; - size_t len = recv(fd, buf, sizeof(buf), 0); - - while(len) { - size_t done = sptps_receive_data(sptps, bufp, len); - - if(!done) { - abort(); - } - - bufp += done; - len -= done; - } -} - -struct timespec start; -struct timespec end; -double elapsed; -double rate; -unsigned int count; - -static void clock_start() { - count = 0; - clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &start); -} - -static bool clock_countto(double seconds) { - clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &end); - elapsed = end.tv_sec + end.tv_nsec * 1e-9 - start.tv_sec - start.tv_nsec * 1e-9; - - if(elapsed < seconds) { - return ++count; - } - - rate = count / elapsed; - return false; -} - -int main(int argc, char *argv[]) { - ecdsa_t *key1, *key2; - ecdh_t *ecdh1, *ecdh2; - sptps_t sptps1, sptps2; - char buf1[4096], buf2[4096], buf3[4096]; - double duration = argc > 1 ? atof(argv[1]) : 10; - - crypto_init(); - - randomize(buf1, sizeof(buf1)); - randomize(buf2, sizeof(buf2)); - randomize(buf3, sizeof(buf3)); - - // Key generation - - fprintf(stderr, "Generating keys for %lg seconds: ", duration); - - for(clock_start(); clock_countto(duration);) { - ecdsa_free(ecdsa_generate()); - } - - fprintf(stderr, "%17.2lf op/s\n", rate); - - key1 = ecdsa_generate(); - key2 = ecdsa_generate(); - - // Ed25519 signatures - - fprintf(stderr, "Ed25519 sign for %lg seconds: ", duration); - - for(clock_start(); clock_countto(duration);) - if(!ecdsa_sign(key1, buf1, 256, buf2)) { - return 1; - } - - fprintf(stderr, "%20.2lf op/s\n", rate); - - fprintf(stderr, "Ed25519 verify for %lg seconds: ", duration); - - for(clock_start(); clock_countto(duration);) - if(!ecdsa_verify(key1, buf1, 256, buf2)) { - fprintf(stderr, "Signature verification failed\n"); - return 1; - } - - fprintf(stderr, "%18.2lf op/s\n", rate); - - ecdh1 = ecdh_generate_public(buf1); - fprintf(stderr, "ECDH for %lg seconds: ", duration); - - for(clock_start(); clock_countto(duration);) { - ecdh2 = ecdh_generate_public(buf2); - - if(!ecdh2) { - return 1; - } - - if(!ecdh_compute_shared(ecdh2, buf1, buf3)) { - return 1; - } - } - - fprintf(stderr, "%28.2lf op/s\n", rate); - ecdh_free(ecdh1); - - // SPTPS authentication phase - - int fd[2]; - - if(socketpair(AF_UNIX, SOCK_STREAM, 0, fd)) { - fprintf(stderr, "Could not create a UNIX socket pair: %s\n", sockstrerror(sockerrno)); - return 1; - } - - struct pollfd pfd[2] = {{fd[0], POLLIN}, {fd[1], POLLIN}}; - - fprintf(stderr, "SPTPS/TCP authenticate for %lg seconds: ", duration); - - for(clock_start(); clock_countto(duration);) { - sptps_start(&sptps1, fd + 0, true, false, key1, key2, "sptps_speed", 11, send_data, receive_record); - sptps_start(&sptps2, fd + 1, false, false, key2, key1, "sptps_speed", 11, send_data, receive_record); - - while(poll(pfd, 2, 0)) { - if(pfd[0].revents) { - receive_data(&sptps1); - } - - if(pfd[1].revents) { - receive_data(&sptps2); - } - } - - sptps_stop(&sptps1); - sptps_stop(&sptps2); - } - - fprintf(stderr, "%10.2lf op/s\n", rate * 2); - - // SPTPS data - - sptps_start(&sptps1, fd + 0, true, false, key1, key2, "sptps_speed", 11, send_data, receive_record); - sptps_start(&sptps2, fd + 1, false, false, key2, key1, "sptps_speed", 11, send_data, receive_record); - - while(poll(pfd, 2, 0)) { - if(pfd[0].revents) { - receive_data(&sptps1); - } - - if(pfd[1].revents) { - receive_data(&sptps2); - } - } - - fprintf(stderr, "SPTPS/TCP transmit for %lg seconds: ", duration); - - for(clock_start(); clock_countto(duration);) { - if(!sptps_send_record(&sptps1, 0, buf1, 1451)) { - abort(); - } - - receive_data(&sptps2); - } - - rate *= 2 * 1451 * 8; - - if(rate > 1e9) { - fprintf(stderr, "%14.2lf Gbit/s\n", rate / 1e9); - } else if(rate > 1e6) { - fprintf(stderr, "%14.2lf Mbit/s\n", rate / 1e6); - } else if(rate > 1e3) { - fprintf(stderr, "%14.2lf kbit/s\n", rate / 1e3); - } - - sptps_stop(&sptps1); - sptps_stop(&sptps2); - - // SPTPS datagram authentication phase - - close(fd[0]); - close(fd[1]); - - if(socketpair(AF_UNIX, SOCK_DGRAM, 0, fd)) { - fprintf(stderr, "Could not create a UNIX socket pair: %s\n", sockstrerror(sockerrno)); - return 1; - } - - fprintf(stderr, "SPTPS/UDP authenticate for %lg seconds: ", duration); - - for(clock_start(); clock_countto(duration);) { - sptps_start(&sptps1, fd + 0, true, true, key1, key2, "sptps_speed", 11, send_data, receive_record); - sptps_start(&sptps2, fd + 1, false, true, key2, key1, "sptps_speed", 11, send_data, receive_record); - - while(poll(pfd, 2, 0)) { - if(pfd[0].revents) { - receive_data(&sptps1); - } - - if(pfd[1].revents) { - receive_data(&sptps2); - } - } - - sptps_stop(&sptps1); - sptps_stop(&sptps2); - } - - fprintf(stderr, "%10.2lf op/s\n", rate * 2); - - // SPTPS datagram data - - sptps_start(&sptps1, fd + 0, true, true, key1, key2, "sptps_speed", 11, send_data, receive_record); - sptps_start(&sptps2, fd + 1, false, true, key2, key1, "sptps_speed", 11, send_data, receive_record); - - while(poll(pfd, 2, 0)) { - if(pfd[0].revents) { - receive_data(&sptps1); - } - - if(pfd[1].revents) { - receive_data(&sptps2); - } - } - - fprintf(stderr, "SPTPS/UDP transmit for %lg seconds: ", duration); - - for(clock_start(); clock_countto(duration);) { - if(!sptps_send_record(&sptps1, 0, buf1, 1451)) { - abort(); - } - - receive_data(&sptps2); - } - - rate *= 2 * 1451 * 8; - - if(rate > 1e9) { - fprintf(stderr, "%14.2lf Gbit/s\n", rate / 1e9); - } else if(rate > 1e6) { - fprintf(stderr, "%14.2lf Mbit/s\n", rate / 1e6); - } else if(rate > 1e3) { - fprintf(stderr, "%14.2lf kbit/s\n", rate / 1e3); - } - - sptps_stop(&sptps1); - sptps_stop(&sptps2); - - // Clean up - - close(fd[0]); - close(fd[1]); - ecdsa_free(key1); - ecdsa_free(key2); - crypto_exit(); - - return 0; -} diff --git a/src/sptps_test.c b/src/sptps_test.c deleted file mode 100644 index 4ff701e..0000000 --- a/src/sptps_test.c +++ /dev/null @@ -1,471 +0,0 @@ -/* - sptps_test.c -- Simple Peer-to-Peer Security test program - Copyright (C) 2011-2014 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 - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include "system.h" - -#ifdef HAVE_LINUX -#include -#endif - -#include - -#include "crypto.h" -#include "ecdsa.h" -#include "sptps.h" -#include "utils.h" - -// Symbols necessary to link with logger.o -bool send_request(void *c, const char *msg, ...) { - (void)c; - (void)msg; - return false; -} - -struct list_t *connection_list = NULL; - -bool send_meta(void *c, const char *msg, int len) { - (void)c; - (void)msg; - (void)len; - return false; -} - -char *logfilename = NULL; -bool do_detach = false; -struct timeval now; - -static bool special; -static bool verbose; -static bool readonly; -static bool writeonly; -static int in = 0; -static int out = 1; -static int addressfamily = AF_UNSPEC; - -static bool send_data(void *handle, uint8_t type, const void *data, size_t len) { - (void)type; - char hex[len * 2 + 1]; - bin2hex(data, hex, len); - - if(verbose) { - fprintf(stderr, "Sending %d bytes of data:\n%s\n", (int)len, hex); - } - - const int *sock = handle; - - if((size_t)send(*sock, data, len, 0) != len) { - return false; - } - - return true; -} - -static bool receive_record(void *handle, uint8_t type, const void *data, uint16_t len) { - (void)handle; - if(verbose) { - fprintf(stderr, "Received type %d record of %u bytes:\n", type, len); - } - - if(!writeonly) { - write(out, data, len); - } - - return true; -} - -static struct option const long_options[] = { - {"datagram", no_argument, NULL, 'd'}, - {"quit", no_argument, NULL, 'q'}, - {"readonly", no_argument, NULL, 'r'}, - {"writeonly", no_argument, NULL, 'w'}, - {"packet-loss", required_argument, NULL, 'L'}, - {"replay-window", required_argument, NULL, 'W'}, - {"special", no_argument, NULL, 's'}, - {"verbose", required_argument, NULL, 'v'}, - {"help", no_argument, NULL, 1}, - {NULL, 0, NULL, 0} -}; - -const char *program_name; - -static void usage() { - fprintf(stderr, "Usage: %s [options] my_ed25519_key_file his_ed25519_key_file [host] port\n\n", program_name); - fprintf(stderr, "Valid options are:\n" - " -d, --datagram Enable datagram mode.\n" - " -q, --quit Quit when EOF occurs on stdin.\n" - " -r, --readonly Only send data from the socket to stdout.\n" -#ifdef HAVE_LINUX - " -t, --tun Use a tun device instead of stdio.\n" -#endif - " -w, --writeonly Only send data from stdin to the socket.\n" - " -L, --packet-loss RATE Fake packet loss of RATE percent.\n" - " -R, --replay-window N Set replay window to N bytes.\n" - " -s, --special Enable special handling of lines starting with #, ^ and $.\n" - " -v, --verbose Display debug messages.\n" - " -4 Use IPv4.\n" - " -6 Use IPv6.\n" - "\n"); - fprintf(stderr, "Report bugs to tinc@tinc-vpn.org.\n"); -} - -int main(int argc, char *argv[]) { - program_name = argv[0]; - bool initiator = false; - bool datagram = false; -#ifdef HAVE_LINUX - bool tun = false; -#endif - int packetloss = 0; - int r; - int option_index = 0; - ecdsa_t *mykey = NULL, *hiskey = NULL; - bool quit = false; - - while((r = getopt_long(argc, argv, "dqrstwL:W:v46", long_options, &option_index)) != EOF) { - switch(r) { - case 0: /* long option */ - break; - - case 'd': /* datagram mode */ - datagram = true; - break; - - case 'q': /* close connection on EOF from stdin */ - quit = true; - break; - - case 'r': /* read only */ - readonly = true; - break; - - case 't': /* read only */ -#ifdef HAVE_LINUX - tun = true; -#else - fprintf(stderr, "--tun is only supported on Linux.\n"); - usage(); - return 1; -#endif - break; - - case 'w': /* write only */ - writeonly = true; - break; - - case 'L': /* packet loss rate */ - packetloss = atoi(optarg); - break; - - case 'W': /* replay window size */ - sptps_replaywin = atoi(optarg); - break; - - case 'v': /* be verbose */ - verbose = true; - break; - - case 's': /* special character handling */ - special = true; - break; - - case '?': /* wrong options */ - usage(); - return 1; - - case '4': /* IPv4 */ - addressfamily = AF_INET; - break; - - case '6': /* IPv6 */ - addressfamily = AF_INET6; - break; - - case 1: /* help */ - usage(); - return 0; - - default: - break; - } - } - - argc -= optind - 1; - argv += optind - 1; - - if(argc < 4 || argc > 5) { - fprintf(stderr, "Wrong number of arguments.\n"); - usage(); - return 1; - } - - if(argc > 4) { - initiator = true; - } - - srand(time(NULL)); - -#ifdef HAVE_LINUX - - if(tun) { - in = out = open("/dev/net/tun", O_RDWR | O_NONBLOCK); - - if(in < 0) { - fprintf(stderr, "Could not open tun device: %s\n", strerror(errno)); - return 1; - } - - struct ifreq ifr = { - .ifr_flags = IFF_TUN - }; - - if(ioctl(in, TUNSETIFF, &ifr)) { - fprintf(stderr, "Could not configure tun interface: %s\n", strerror(errno)); - return 1; - } - - ifr.ifr_name[IFNAMSIZ - 1] = 0; - fprintf(stderr, "Using tun interface %s\n", ifr.ifr_name); - } - -#endif - -#ifdef HAVE_MINGW - static struct WSAData wsa_state; - - if(WSAStartup(MAKEWORD(2, 2), &wsa_state)) { - return 1; - } - -#endif - - struct addrinfo *ai, hint; - memset(&hint, 0, sizeof(hint)); - - hint.ai_family = addressfamily; - hint.ai_socktype = datagram ? SOCK_DGRAM : SOCK_STREAM; - hint.ai_protocol = datagram ? IPPROTO_UDP : IPPROTO_TCP; - hint.ai_flags = initiator ? 0 : AI_PASSIVE; - - if(getaddrinfo(initiator ? argv[3] : NULL, initiator ? argv[4] : argv[3], &hint, &ai) || !ai) { - fprintf(stderr, "getaddrinfo() failed: %s\n", sockstrerror(sockerrno)); - return 1; - } - - int sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); - - if(sock < 0) { - fprintf(stderr, "Could not create socket: %s\n", sockstrerror(sockerrno)); - return 1; - } - - int one = 1; - setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void *)&one, sizeof(one)); - - if(initiator) { - if(connect(sock, ai->ai_addr, ai->ai_addrlen)) { - fprintf(stderr, "Could not connect to peer: %s\n", sockstrerror(sockerrno)); - return 1; - } - - fprintf(stderr, "Connected\n"); - } else { - if(bind(sock, ai->ai_addr, ai->ai_addrlen)) { - fprintf(stderr, "Could not bind socket: %s\n", sockstrerror(sockerrno)); - return 1; - } - - if(!datagram) { - if(listen(sock, 1)) { - fprintf(stderr, "Could not listen on socket: %s\n", sockstrerror(sockerrno)); - return 1; - } - - fprintf(stderr, "Listening...\n"); - - sock = accept(sock, NULL, NULL); - - if(sock < 0) { - fprintf(stderr, "Could not accept connection: %s\n", sockstrerror(sockerrno)); - return 1; - } - } else { - fprintf(stderr, "Listening...\n"); - - char buf[65536]; - struct sockaddr addr; - socklen_t addrlen = sizeof(addr); - - if(recvfrom(sock, buf, sizeof(buf), MSG_PEEK, &addr, &addrlen) <= 0) { - fprintf(stderr, "Could not read from socket: %s\n", sockstrerror(sockerrno)); - return 1; - } - - if(connect(sock, &addr, addrlen)) { - fprintf(stderr, "Could not accept connection: %s\n", sockstrerror(sockerrno)); - return 1; - } - } - - fprintf(stderr, "Connected\n"); - } - - crypto_init(); - - FILE *fp = fopen(argv[1], "r"); - - if(!fp) { - fprintf(stderr, "Could not open %s: %s\n", argv[1], strerror(errno)); - return 1; - } - - if(!(mykey = ecdsa_read_pem_private_key(fp))) { - return 1; - } - - fclose(fp); - - fp = fopen(argv[2], "r"); - - if(!fp) { - fprintf(stderr, "Could not open %s: %s\n", argv[2], strerror(errno)); - return 1; - } - - if(!(hiskey = ecdsa_read_pem_public_key(fp))) { - return 1; - } - - fclose(fp); - - if(verbose) { - fprintf(stderr, "Keys loaded\n"); - } - - sptps_t s; - - if(!sptps_start(&s, &sock, initiator, datagram, mykey, hiskey, "sptps_test", 10, send_data, receive_record)) { - return 1; - } - - while(true) { - if(writeonly && readonly) { - break; - } - - char buf[65535] = ""; - - fd_set fds; - FD_ZERO(&fds); -#ifndef HAVE_MINGW - - if(!readonly && s.instate) { - FD_SET(in, &fds); - } - -#endif - FD_SET(sock, &fds); - - if(select(sock + 1, &fds, NULL, NULL, NULL) <= 0) { - return 1; - } - - if(FD_ISSET(in, &fds)) { - ssize_t len = read(in, buf, sizeof(buf)); - - if(len < 0) { - fprintf(stderr, "Could not read from stdin: %s\n", strerror(errno)); - return 1; - } - - if(len == 0) { - if(quit) { - break; - } - - readonly = true; - continue; - } - - if(special && buf[0] == '#') { - s.outseqno = atoi(buf + 1); - } - - if(special && buf[0] == '^') { - sptps_send_record(&s, SPTPS_HANDSHAKE, NULL, 0); - } else if(special && buf[0] == '$') { - sptps_force_kex(&s); - - if(len > 1) { - sptps_send_record(&s, 0, buf, len); - } - } else if(!sptps_send_record(&s, buf[0] == '!' ? 1 : 0, buf, (len == 1 && buf[0] == '\n') ? 0 : buf[0] == '*' ? sizeof(buf) : (size_t)len)) { - return 1; - } - } - - if(FD_ISSET(sock, &fds)) { - ssize_t len = recv(sock, buf, sizeof(buf), 0); - - if(len < 0) { - fprintf(stderr, "Could not read from socket: %s\n", sockstrerror(sockerrno)); - return 1; - } - - if(len == 0) { - fprintf(stderr, "Connection terminated by peer.\n"); - break; - } - - if(verbose) { - char hex[len * 2 + 1]; - bin2hex(buf, hex, len); - fprintf(stderr, "Received %d bytes of data:\n%s\n", (int)len, hex); - } - - if(packetloss && (rand() % 100) < packetloss) { - if(verbose) { - fprintf(stderr, "Dropped.\n"); - } - - continue; - } - - char *bufp = buf; - - while(len) { - size_t done = sptps_receive_data(&s, bufp, len); - - if(!done) { - if(!datagram) { - return 1; - } - } - - bufp += done; - len -= done; - } - } - } - - if(!sptps_stop(&s)) { - return 1; - } - - return 0; -} diff --git a/src/subnet.c b/src/subnet.c index 4fefda6..154fd80 100644 --- a/src/subnet.c +++ b/src/subnet.c @@ -1,6 +1,6 @@ /* subnet.c -- handle subnet lookups and lists - Copyright (C) 2000-2017 Guus Sliepen , + Copyright (C) 2000-2019 Guus Sliepen , 2000-2005 Ivo Timmermans This program is free software; you can redistribute it and/or modify @@ -20,66 +20,164 @@ #include "system.h" -#include "splay_tree.h" -#include "control_common.h" +#include "avl_tree.h" #include "device.h" -#include "hash.h" #include "logger.h" -#include "names.h" #include "net.h" #include "netutl.h" #include "node.h" -#include "script.h" +#include "process.h" #include "subnet.h" #include "utils.h" #include "xalloc.h" /* lists type of subnet */ -splay_tree_t *subnet_tree; +avl_tree_t *subnet_tree; /* Subnet lookup cache */ -static hash_t *ipv4_cache; -static hash_t *ipv6_cache; -static hash_t *mac_cache; +static ipv4_t cache_ipv4_address[2]; +static subnet_t *cache_ipv4_subnet[2]; +static bool cache_ipv4_valid[2]; +static int cache_ipv4_slot; + +static ipv6_t cache_ipv6_address[2]; +static subnet_t *cache_ipv6_subnet[2]; +static bool cache_ipv6_valid[2]; +static int cache_ipv6_slot; + +static mac_t cache_mac_address[2]; +static subnet_t *cache_mac_subnet[2]; +static bool cache_mac_valid[2]; +static int cache_mac_slot; void subnet_cache_flush(void) { - hash_clear(ipv4_cache); - hash_clear(ipv6_cache); - hash_clear(mac_cache); + cache_ipv4_valid[0] = cache_ipv4_valid[1] = false; + cache_ipv6_valid[0] = cache_ipv6_valid[1] = false; + cache_mac_valid[0] = cache_mac_valid[1] = false; +} + +/* Subnet comparison */ + +static int subnet_compare_mac(const subnet_t *a, const subnet_t *b) { + int result; + + result = memcmp(&a->net.mac.address, &b->net.mac.address, sizeof(mac_t)); + + if(result) { + return result; + } + + result = a->weight - b->weight; + + if(result || !a->owner || !b->owner) { + return result; + } + + return strcmp(a->owner->name, b->owner->name); +} + +static int subnet_compare_ipv4(const subnet_t *a, const subnet_t *b) { + int result; + + result = b->net.ipv4.prefixlength - a->net.ipv4.prefixlength; + + if(result) { + return result; + } + + result = memcmp(&a->net.ipv4.address, &b->net.ipv4.address, sizeof(ipv4_t)); + + if(result) { + return result; + } + + result = a->weight - b->weight; + + if(result || !a->owner || !b->owner) { + return result; + } + + return strcmp(a->owner->name, b->owner->name); +} + +static int subnet_compare_ipv6(const subnet_t *a, const subnet_t *b) { + int result; + + result = b->net.ipv6.prefixlength - a->net.ipv6.prefixlength; + + if(result) { + return result; + } + + result = memcmp(&a->net.ipv6.address, &b->net.ipv6.address, sizeof(ipv6_t)); + + if(result) { + return result; + } + + result = a->weight - b->weight; + + if(result || !a->owner || !b->owner) { + return result; + } + + return strcmp(a->owner->name, b->owner->name); +} + +int subnet_compare(const subnet_t *a, const subnet_t *b) { + int result; + + result = a->type - b->type; + + if(result) { + return result; + } + + switch(a->type) { + case SUBNET_MAC: + return subnet_compare_mac(a, b); + + case SUBNET_IPV4: + return subnet_compare_ipv4(a, b); + + case SUBNET_IPV6: + return subnet_compare_ipv6(a, b); + + default: + logger(LOG_ERR, "subnet_compare() was called with unknown subnet type %d, exitting!", + a->type); + exit(0); + } + + return 0; } /* Initialising trees */ void init_subnets(void) { - subnet_tree = splay_alloc_tree((splay_compare_t) subnet_compare, (splay_action_t) free_subnet); + subnet_tree = avl_alloc_tree((avl_compare_t) subnet_compare, (avl_action_t) free_subnet); - ipv4_cache = hash_alloc(0x100, sizeof(ipv4_t)); - ipv6_cache = hash_alloc(0x100, sizeof(ipv6_t)); - mac_cache = hash_alloc(0x100, sizeof(mac_t)); + subnet_cache_flush(); } void exit_subnets(void) { - splay_delete_tree(subnet_tree); - - hash_free(ipv4_cache); - hash_free(ipv6_cache); - hash_free(mac_cache); + avl_delete_tree(subnet_tree); } -splay_tree_t *new_subnet_tree(void) { - return splay_alloc_tree((splay_compare_t) subnet_compare, NULL); +avl_tree_t *new_subnet_tree(void) { + return avl_alloc_tree((avl_compare_t) subnet_compare, NULL); } -void free_subnet_tree(splay_tree_t *subnet_tree) { - splay_delete_tree(subnet_tree); +void free_subnet_tree(avl_tree_t *subnet_tree) { + avl_delete_tree(subnet_tree); } /* Allocating and freeing space for subnets */ subnet_t *new_subnet(void) { - return xzalloc(sizeof(subnet_t)); + return xmalloc_and_zero(sizeof(subnet_t)); } void free_subnet(subnet_t *subnet) { @@ -91,43 +189,271 @@ void free_subnet(subnet_t *subnet) { void subnet_add(node_t *n, subnet_t *subnet) { subnet->owner = n; - splay_insert(subnet_tree, subnet); - - if(n) { - splay_insert(n->subnet_tree, subnet); - } + avl_insert(subnet_tree, subnet); + avl_insert(n->subnet_tree, subnet); subnet_cache_flush(); } void subnet_del(node_t *n, subnet_t *subnet) { - if(n) { - splay_delete(n->subnet_tree, subnet); - } - - splay_delete(subnet_tree, subnet); + avl_delete(n->subnet_tree, subnet); + avl_delete(subnet_tree, subnet); subnet_cache_flush(); } +/* Ascii representation of subnets */ + +bool str2net(subnet_t *subnet, const char *subnetstr) { + char str[1024]; + strncpy(str, subnetstr, sizeof(str)); + str[sizeof(str) - 1] = 0; + int consumed; + + int weight = 10; + char *weight_separator = strchr(str, '#'); + + if(weight_separator) { + char *weight_str = weight_separator + 1; + + if(sscanf(weight_str, "%d%n", &weight, &consumed) < 1) { + return false; + } + + if(weight_str[consumed]) { + return false; + } + + *weight_separator = 0; + } + + int prefixlength = -1; + char *prefixlength_separator = strchr(str, '/'); + + if(prefixlength_separator) { + char *prefixlength_str = prefixlength_separator + 1; + + if(sscanf(prefixlength_str, "%d%n", &prefixlength, &consumed) < 1) { + return false; + } + + if(prefixlength_str[consumed]) { + return false; + } + + *prefixlength_separator = 0; + + if(prefixlength < 0) { + return false; + } + } + + uint16_t x[8]; + + if(sscanf(str, "%hx:%hx:%hx:%hx:%hx:%hx%n", &x[0], &x[1], &x[2], &x[3], &x[4], &x[5], &consumed) >= 6 && !str[consumed]) { + /* + Normally we should check that each part has two digits to prevent ambiguities. + However, in old tinc versions net2str() will aggressively return MAC addresses with one-digit parts, + so we have to accept them otherwise we would be unable to parse ADD_SUBNET messages. + */ + if(prefixlength >= 0) { + return false; + } + + subnet->type = SUBNET_MAC; + subnet->weight = weight; + + for(int i = 0; i < 6; i++) { + subnet->net.mac.address.x[i] = x[i]; + } + + return true; + } + + if(sscanf(str, "%hu.%hu.%hu.%hu%n", &x[0], &x[1], &x[2], &x[3], &consumed) >= 4 && !str[consumed]) { + if(prefixlength == -1) { + prefixlength = 32; + } + + if(prefixlength > 32) { + return false; + } + + subnet->type = SUBNET_IPV4; + subnet->net.ipv4.prefixlength = prefixlength; + subnet->weight = weight; + + for(int i = 0; i < 4; i++) { + if(x[i] > 255) { + return false; + } + + subnet->net.ipv4.address.x[i] = x[i]; + } + + return true; + } + + /* IPv6 */ + + char *last_colon = strrchr(str, ':'); + + if(last_colon && sscanf(last_colon, ":%hu.%hu.%hu.%hu%n", &x[0], &x[1], &x[2], &x[3], &consumed) >= 4 && !last_colon[consumed]) { + /* Dotted quad suffix notation, convert to standard IPv6 notation */ + for(int i = 0; i < 4; i++) + if(x[i] > 255) { + return false; + } + + snprintf(last_colon, sizeof(str) - (last_colon - str), ":%02x%02x:%02x%02x", x[0], x[1], x[2], x[3]); + } + + char *double_colon = strstr(str, "::"); + + if(double_colon) { + /* Figure out how many zero groups we need to expand */ + int zero_group_count = 8; + + for(const char *cur = str; *cur; cur++) + if(*cur != ':') { + zero_group_count--; + + while(cur[1] && cur[1] != ':') { + cur++; + } + } + + if(zero_group_count < 1) { + return false; + } + + /* Split the double colon in the middle to make room for zero groups */ + double_colon++; + memmove(double_colon + (zero_group_count * 2 - 1), double_colon, strlen(double_colon) + 1); + + /* Write zero groups in the resulting gap, overwriting the second colon */ + for(int i = 0; i < zero_group_count; i++) { + memcpy(&double_colon[i * 2], "0:", 2); + } + + /* Remove any leading or trailing colons */ + if(str[0] == ':') { + memmove(&str[0], &str[1], strlen(&str[1]) + 1); + } + + if(str[strlen(str) - 1] == ':') { + str[strlen(str) - 1] = 0; + } + } + + if(sscanf(str, "%hx:%hx:%hx:%hx:%hx:%hx:%hx:%hx%n", + &x[0], &x[1], &x[2], &x[3], &x[4], &x[5], &x[6], &x[7], &consumed) >= 8 && !str[consumed]) { + if(prefixlength == -1) { + prefixlength = 128; + } + + if(prefixlength > 128) { + return false; + } + + subnet->type = SUBNET_IPV6; + subnet->net.ipv6.prefixlength = prefixlength; + subnet->weight = weight; + + for(int i = 0; i < 8; i++) { + subnet->net.ipv6.address.x[i] = htons(x[i]); + } + + return true; + } + + return false; +} + +bool net2str(char *netstr, int len, const subnet_t *subnet) { + if(!netstr || !subnet) { + logger(LOG_ERR, "net2str() was called with netstr=%p, subnet=%p!", (void *)netstr, (void *)subnet); + return false; + } + + switch(subnet->type) { + case SUBNET_MAC: + snprintf(netstr, len, "%x:%x:%x:%x:%x:%x#%d", + subnet->net.mac.address.x[0], + subnet->net.mac.address.x[1], + subnet->net.mac.address.x[2], + subnet->net.mac.address.x[3], + subnet->net.mac.address.x[4], + subnet->net.mac.address.x[5], + subnet->weight); + break; + + case SUBNET_IPV4: + snprintf(netstr, len, "%u.%u.%u.%u/%d#%d", + subnet->net.ipv4.address.x[0], + subnet->net.ipv4.address.x[1], + subnet->net.ipv4.address.x[2], + subnet->net.ipv4.address.x[3], + subnet->net.ipv4.prefixlength, + subnet->weight); + break; + + case SUBNET_IPV6: + snprintf(netstr, len, "%x:%x:%x:%x:%x:%x:%x:%x/%d#%d", + ntohs(subnet->net.ipv6.address.x[0]), + ntohs(subnet->net.ipv6.address.x[1]), + ntohs(subnet->net.ipv6.address.x[2]), + ntohs(subnet->net.ipv6.address.x[3]), + ntohs(subnet->net.ipv6.address.x[4]), + ntohs(subnet->net.ipv6.address.x[5]), + ntohs(subnet->net.ipv6.address.x[6]), + ntohs(subnet->net.ipv6.address.x[7]), + subnet->net.ipv6.prefixlength, + subnet->weight); + break; + + default: + logger(LOG_ERR, + "net2str() was called with unknown subnet type %d, exiting!", + subnet->type); + exit(0); + } + + return true; +} + /* Subnet lookup routines */ subnet_t *lookup_subnet(const node_t *owner, const subnet_t *subnet) { - return splay_search(owner->subnet_tree, subnet); + return avl_search(owner->subnet_tree, subnet); } subnet_t *lookup_subnet_mac(const node_t *owner, const mac_t *address) { - subnet_t *r = NULL; + subnet_t *p, *r = NULL; + avl_node_t *n; + int i; // Check if this address is cached - if((r = hash_search(mac_cache, address))) { - return r; + 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 - for splay_each(subnet_t, p, owner ? owner->subnet_tree : subnet_tree) { + for(n = owner ? owner->subnet_tree->head : subnet_tree->head; n; n = n->next) { + p = n->data; + if(!p || p->type != SUBNET_MAC) { continue; } @@ -135,7 +461,7 @@ subnet_t *lookup_subnet_mac(const node_t *owner, const mac_t *address) { if(!memcmp(address, &p->net.mac.address, sizeof(*address))) { r = p; - if(!p->owner || p->owner->status.reachable) { + if(p->owner->status.reachable) { break; } } @@ -143,25 +469,36 @@ subnet_t *lookup_subnet_mac(const node_t *owner, const mac_t *address) { // Cache the result - if(r) { - hash_insert(mac_cache, address, r); - } + cache_mac_slot = !cache_mac_slot; + memcpy(&cache_mac_address[cache_mac_slot], address, sizeof(*address)); + cache_mac_subnet[cache_mac_slot] = r; + cache_mac_valid[cache_mac_slot] = true; return r; } subnet_t *lookup_subnet_ipv4(const ipv4_t *address) { - subnet_t *r = NULL; + subnet_t *p, *r = NULL; + avl_node_t *n; + int i; // Check if this address is cached - if((r = hash_search(ipv4_cache, address))) { - return r; + for(i = 0; i < 2; i++) { + if(!cache_ipv4_valid[i]) { + continue; + } + + if(!memcmp(address, &cache_ipv4_address[i], sizeof(*address))) { + return cache_ipv4_subnet[i]; + } } // Search all subnets for a matching one - for splay_each(subnet_t, p, subnet_tree) { + for(n = subnet_tree->head; n; n = n->next) { + p = n->data; + if(!p || p->type != SUBNET_IPV4) { continue; } @@ -169,7 +506,7 @@ subnet_t *lookup_subnet_ipv4(const ipv4_t *address) { if(!maskcmp(address, &p->net.ipv4.address, p->net.ipv4.prefixlength)) { r = p; - if(!p->owner || p->owner->status.reachable) { + if(p->owner->status.reachable) { break; } } @@ -177,25 +514,36 @@ subnet_t *lookup_subnet_ipv4(const ipv4_t *address) { // Cache the result - if(r) { - hash_insert(ipv4_cache, address, r); - } + cache_ipv4_slot = !cache_ipv4_slot; + memcpy(&cache_ipv4_address[cache_ipv4_slot], address, sizeof(*address)); + cache_ipv4_subnet[cache_ipv4_slot] = r; + cache_ipv4_valid[cache_ipv4_slot] = true; return r; } subnet_t *lookup_subnet_ipv6(const ipv6_t *address) { - subnet_t *r = NULL; + subnet_t *p, *r = NULL; + avl_node_t *n; + int i; // Check if this address is cached - if((r = hash_search(ipv6_cache, address))) { - return r; + for(i = 0; i < 2; i++) { + if(!cache_ipv6_valid[i]) { + continue; + } + + if(!memcmp(address, &cache_ipv6_address[i], sizeof(*address))) { + return cache_ipv6_subnet[i]; + } } // Search all subnets for a matching one - for splay_each(subnet_t, p, subnet_tree) { + for(n = subnet_tree->head; n; n = n->next) { + p = n->data; + if(!p || p->type != SUBNET_IPV6) { continue; } @@ -203,7 +551,7 @@ subnet_t *lookup_subnet_ipv6(const ipv6_t *address) { if(!maskcmp(address, &p->net.ipv6.address, p->net.ipv6.prefixlength)) { r = p; - if(!p->owner || p->owner->status.reachable) { + if(p->owner->status.reachable) { break; } } @@ -211,39 +559,45 @@ subnet_t *lookup_subnet_ipv6(const ipv6_t *address) { // Cache the result - if(r) { - hash_insert(ipv6_cache, address, r); - } + cache_ipv6_slot = !cache_ipv6_slot; + memcpy(&cache_ipv6_address[cache_ipv6_slot], address, sizeof(*address)); + cache_ipv6_subnet[cache_ipv6_slot] = r; + cache_ipv6_valid[cache_ipv6_slot] = true; return r; } void subnet_update(node_t *owner, subnet_t *subnet, bool up) { + avl_node_t *node; + int i; + char *envp[10] = {NULL}; char netstr[MAXNETSTR]; char *name, *address, *port; char empty[] = ""; // Prepare environment variables to be passed to the script - environment_t env; - environment_init(&env); - environment_add(&env, "NODE=%s", owner->name); + xasprintf(&envp[0], "NETNAME=%s", netname ? netname : ""); + xasprintf(&envp[1], "DEVICE=%s", device ? device : ""); + xasprintf(&envp[2], "INTERFACE=%s", iface ? iface : ""); + xasprintf(&envp[3], "NODE=%s", owner->name); + xasprintf(&envp[4], "NAME=%s", myself->name); if(owner != myself) { sockaddr2str(&owner->address, &address, &port); - environment_add(&env, "REMOTEADDRESS=%s", address); - environment_add(&env, "REMOTEPORT=%s", port); + // 5 and 6 are reserved for SUBNET and WEIGHT + xasprintf(&envp[7], "REMOTEADDRESS=%s", address); + xasprintf(&envp[8], "REMOTEPORT=%s", port); free(port); free(address); } - int env_subnet = environment_add(&env, NULL); - int env_weight = environment_add(&env, NULL); - name = up ? "subnet-up" : "subnet-down"; if(!subnet) { - for splay_each(subnet_t, subnet, owner->subnet_tree) { + for(node = owner->subnet_tree->head; node; node = node->next) { + subnet = node->data; + if(!net2str(netstr, sizeof(netstr), subnet)) { continue; } @@ -258,10 +612,13 @@ void subnet_update(node_t *owner, subnet_t *subnet, bool up) { } // Prepare the SUBNET and WEIGHT variables - environment_update(&env, env_subnet, "SUBNET=%s", netstr); - environment_update(&env, env_weight, "WEIGHT=%s", weight); + free(envp[5]); + free(envp[6]); - execute_script(name, &env); + xasprintf(&envp[5], "SUBNET=%s", netstr); + xasprintf(&envp[6], "WEIGHT=%s", weight); + + execute_script(name, envp); } } else { if(net2str(netstr, sizeof(netstr), subnet)) { @@ -275,28 +632,34 @@ void subnet_update(node_t *owner, subnet_t *subnet, bool up) { } // Prepare the SUBNET and WEIGHT variables - environment_update(&env, env_subnet, "SUBNET=%s", netstr); - environment_update(&env, env_weight, "WEIGHT=%s", weight); + xasprintf(&envp[5], "SUBNET=%s", netstr); + xasprintf(&envp[6], "WEIGHT=%s", weight); - execute_script(name, &env); + execute_script(name, envp); } } - environment_exit(&env); + for(i = 0; i < 9; i++) { + free(envp[i]); + } } -bool dump_subnets(connection_t *c) { - for splay_each(subnet_t, subnet, subnet_tree) { - char netstr[MAXNETSTR]; +void dump_subnets(void) { + char netstr[MAXNETSTR]; + subnet_t *subnet; + avl_node_t *node; + + logger(LOG_DEBUG, "Subnet list:"); + + for(node = subnet_tree->head; node; node = node->next) { + subnet = node->data; if(!net2str(netstr, sizeof(netstr), subnet)) { continue; } - send_request(c, "%d %d %s %s", - CONTROL, REQ_DUMP_SUBNETS, - netstr, subnet->owner ? subnet->owner->name : "(broadcast)"); + logger(LOG_DEBUG, " %s owner %s", netstr, subnet->owner->name); } - return send_request(c, "%d %d", CONTROL, REQ_DUMP_SUBNETS); + logger(LOG_DEBUG, "End of subnet list."); } diff --git a/src/subnet.h b/src/subnet.h index cfdf2d0..6fecca3 100644 --- a/src/subnet.h +++ b/src/subnet.h @@ -3,7 +3,7 @@ /* subnet.h -- header for subnet.c - Copyright (C) 2000-2012 Guus Sliepen , + Copyright (C) 2000-2009 Guus Sliepen , 2000-2005 Ivo Timmermans This program is free software; you can redistribute it and/or modify @@ -22,13 +22,12 @@ */ #include "net.h" -#include "node.h" typedef enum subnet_type_t { SUBNET_MAC = 0, SUBNET_IPV4, SUBNET_IPV6, - SUBNET_TYPES /* Guardian */ + SUBNET_TYPES, /* Guardian */ } subnet_type_t; typedef struct subnet_mac_t { @@ -45,12 +44,14 @@ typedef struct subnet_ipv6_t { int prefixlength; } subnet_ipv6_t; -typedef struct subnet_t { - struct node_t *owner; /* the owner of this subnet */ +#include "node.h" - subnet_type_t type; /* subnet type (IPv4? IPv6? MAC? something even weirder?) */ - time_t expires; /* expiry time */ - int weight; /* weight (higher value is higher priority) */ +typedef struct subnet_t { + struct node_t *owner; /* the owner of this subnet */ + + subnet_type_t type; /* subnet type (IPv4? IPv6? MAC? something even weirder?) */ + time_t expires; /* expiry time */ + int weight; /* weight (higher value is higher priority) */ /* And now for the actual subnet: */ @@ -63,29 +64,24 @@ typedef struct subnet_t { #define MAXNETSTR 64 -extern splay_tree_t *subnet_tree; +extern avl_tree_t *subnet_tree; -extern int subnet_compare(const struct subnet_t *a, const struct subnet_t *b); extern subnet_t *new_subnet(void) __attribute__((__malloc__)); extern void free_subnet(subnet_t *subnet); extern void init_subnets(void); extern void exit_subnets(void); -extern splay_tree_t *new_subnet_tree(void) __attribute__((__malloc__)); -extern void free_subnet_tree(splay_tree_t *); +extern avl_tree_t *new_subnet_tree(void) __attribute__((__malloc__)); +extern void free_subnet_tree(avl_tree_t *subnet_tree); extern void subnet_add(struct node_t *owner, subnet_t *subnet); extern void subnet_del(struct node_t *owner, subnet_t *subnet); extern void subnet_update(struct node_t *owner, subnet_t *subnet, bool up); -extern int maskcmp(const void *a, const void *b, int masklen); -extern void maskcpy(void *dest, const void *src, int masklen, int len); -extern void mask(void *mask, int masklen, int len); -extern bool maskcheck(const void *mask, int masklen, int len); extern bool net2str(char *netstr, int len, const subnet_t *subnet); extern bool str2net(subnet_t *subnet, const char *netstr); extern subnet_t *lookup_subnet(const struct node_t *owner, const subnet_t *subnet); extern subnet_t *lookup_subnet_mac(const struct node_t *owner, const mac_t *address); extern subnet_t *lookup_subnet_ipv4(const ipv4_t *address); extern subnet_t *lookup_subnet_ipv6(const ipv6_t *address); -extern bool dump_subnets(struct connection_t *c); +extern void dump_subnets(void); extern void subnet_cache_flush(void); #endif diff --git a/src/subnet_parse.c b/src/subnet_parse.c deleted file mode 100644 index d5b84eb..0000000 --- a/src/subnet_parse.c +++ /dev/null @@ -1,490 +0,0 @@ -/* - subnet_parse.c -- handle subnet parsing - Copyright (C) 2000-2012 Guus Sliepen , - 2000-2005 Ivo Timmermans - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include "system.h" - -#include "logger.h" -#include "net.h" -#include "netutl.h" -#include "subnet.h" -#include "utils.h" -#include "xalloc.h" - -/* Changing this default will affect ADD_SUBNET messages - beware of inconsistencies between versions */ -static const int DEFAULT_WEIGHT = 10; - -/* Subnet mask handling */ - -int maskcmp(const void *va, const void *vb, int masklen) { - int i, m, result; - const char *a = va; - const char *b = vb; - - for(m = masklen, i = 0; m >= 8; m -= 8, i++) { - result = a[i] - b[i]; - - if(result) { - return result; - } - } - - if(m) - return (a[i] & (0x100 - (1 << (8 - m)))) - - (b[i] & (0x100 - (1 << (8 - m)))); - - return 0; -} - -void mask(void *va, int masklen, int len) { - int i; - char *a = va; - - i = masklen / 8; - masklen %= 8; - - if(masklen) { - a[i++] &= (0x100 - (1 << (8 - masklen))); - } - - for(; i < len; i++) { - a[i] = 0; - } -} - -void maskcpy(void *va, const void *vb, int masklen, int len) { - int i, m; - char *a = va; - const char *b = vb; - - for(m = masklen, i = 0; m >= 8; m -= 8, i++) { - a[i] = b[i]; - } - - if(m) { - a[i] = b[i] & (0x100 - (1 << (8 - m))); - i++; - } - - for(; i < len; i++) { - a[i] = 0; - } -} - -bool maskcheck(const void *va, int masklen, int len) { - int i; - const char *a = va; - - i = masklen / 8; - masklen %= 8; - - if(masklen && a[i++] & (0xff >> masklen)) { - return false; - } - - for(; i < len; i++) - if(a[i] != 0) { - return false; - } - - return true; -} - -/* Subnet comparison */ - -static int subnet_compare_mac(const subnet_t *a, const subnet_t *b) { - int result; - - result = memcmp(&a->net.mac.address, &b->net.mac.address, sizeof(a->net.mac.address)); - - if(result) { - return result; - } - - result = a->weight - b->weight; - - if(result || !a->owner || !b->owner) { - return result; - } - - return strcmp(a->owner->name, b->owner->name); -} - -static int subnet_compare_ipv4(const subnet_t *a, const subnet_t *b) { - int result; - - result = b->net.ipv4.prefixlength - a->net.ipv4.prefixlength; - - if(result) { - return result; - } - - result = memcmp(&a->net.ipv4.address, &b->net.ipv4.address, sizeof(ipv4_t)); - - if(result) { - return result; - } - - result = a->weight - b->weight; - - if(result || !a->owner || !b->owner) { - return result; - } - - return strcmp(a->owner->name, b->owner->name); -} - -static int subnet_compare_ipv6(const subnet_t *a, const subnet_t *b) { - int result; - - result = b->net.ipv6.prefixlength - a->net.ipv6.prefixlength; - - if(result) { - return result; - } - - result = memcmp(&a->net.ipv6.address, &b->net.ipv6.address, sizeof(ipv6_t)); - - if(result) { - return result; - } - - result = a->weight - b->weight; - - if(result || !a->owner || !b->owner) { - return result; - } - - return strcmp(a->owner->name, b->owner->name); -} - -int subnet_compare(const subnet_t *a, const subnet_t *b) { - int result; - - result = a->type - b->type; - - if(result) { - return result; - } - - switch(a->type) { - case SUBNET_MAC: - return subnet_compare_mac(a, b); - - case SUBNET_IPV4: - return subnet_compare_ipv4(a, b); - - case SUBNET_IPV6: - return subnet_compare_ipv6(a, b); - - default: - logger(DEBUG_ALWAYS, LOG_ERR, "subnet_compare() was called with unknown subnet type %d, exitting!", a->type); - exit(1); - } - - return 0; -} - -/* Ascii representation of subnets */ - -bool str2net(subnet_t *subnet, const char *subnetstr) { - char str[1024]; - strncpy(str, subnetstr, sizeof(str)); - str[sizeof(str) - 1] = 0; - int consumed; - - int weight = DEFAULT_WEIGHT; - char *weight_separator = strchr(str, '#'); - - if(weight_separator) { - char *weight_str = weight_separator + 1; - - if(sscanf(weight_str, "%d%n", &weight, &consumed) < 1) { - return false; - } - - if(weight_str[consumed]) { - return false; - } - - *weight_separator = 0; - } - - int prefixlength = -1; - char *prefixlength_separator = strchr(str, '/'); - - if(prefixlength_separator) { - char *prefixlength_str = prefixlength_separator + 1; - - if(sscanf(prefixlength_str, "%d%n", &prefixlength, &consumed) < 1) { - return false; - } - - if(prefixlength_str[consumed]) { - return false; - } - - *prefixlength_separator = 0; - - if(prefixlength < 0) { - return false; - } - } - - uint16_t x[8]; - - if(sscanf(str, "%hx:%hx:%hx:%hx:%hx:%hx%n", &x[0], &x[1], &x[2], &x[3], &x[4], &x[5], &consumed) >= 6 && !str[consumed]) { - /* - Normally we should check that each part has two digits to prevent ambiguities. - However, in old tinc versions net2str() will aggressively return MAC addresses with one-digit parts, - so we have to accept them otherwise we would be unable to parse ADD_SUBNET messages. - */ - if(prefixlength >= 0) { - return false; - } - - subnet->type = SUBNET_MAC; - subnet->weight = weight; - - for(int i = 0; i < 6; i++) { - subnet->net.mac.address.x[i] = x[i]; - } - - return true; - } - - if(sscanf(str, "%hu.%hu.%hu.%hu%n", &x[0], &x[1], &x[2], &x[3], &consumed) >= 4 && !str[consumed]) { - if(prefixlength == -1) { - prefixlength = 32; - } - - if(prefixlength > 32) { - return false; - } - - subnet->type = SUBNET_IPV4; - subnet->net.ipv4.prefixlength = prefixlength; - subnet->weight = weight; - - for(int i = 0; i < 4; i++) { - if(x[i] > 255) { - return false; - } - - subnet->net.ipv4.address.x[i] = x[i]; - } - - return true; - } - - /* IPv6 */ - - char *last_colon = strrchr(str, ':'); - - if(last_colon && sscanf(last_colon, ":%hu.%hu.%hu.%hu%n", &x[0], &x[1], &x[2], &x[3], &consumed) >= 4 && !last_colon[consumed]) { - /* Dotted quad suffix notation, convert to standard IPv6 notation */ - for(int i = 0; i < 4; i++) - if(x[i] > 255) { - return false; - } - - snprintf(last_colon, sizeof(str) - (last_colon - str), ":%02x%02x:%02x%02x", x[0], x[1], x[2], x[3]); - } - - char *double_colon = strstr(str, "::"); - - if(double_colon) { - /* Figure out how many zero groups we need to expand */ - int zero_group_count = 8; - - for(const char *cur = str; *cur; cur++) - if(*cur != ':') { - zero_group_count--; - - while(cur[1] && cur[1] != ':') { - cur++; - } - } - - if(zero_group_count < 1) { - return false; - } - - /* Split the double colon in the middle to make room for zero groups */ - double_colon++; - memmove(double_colon + (zero_group_count * 2 - 1), double_colon, strlen(double_colon) + 1); - - /* Write zero groups in the resulting gap, overwriting the second colon */ - for(int i = 0; i < zero_group_count; i++) { - memcpy(&double_colon[i * 2], "0:", 2); - } - - /* Remove any leading or trailing colons */ - if(str[0] == ':') { - memmove(&str[0], &str[1], strlen(&str[1]) + 1); - } - - if(str[strlen(str) - 1] == ':') { - str[strlen(str) - 1] = 0; - } - } - - if(sscanf(str, "%hx:%hx:%hx:%hx:%hx:%hx:%hx:%hx%n", - &x[0], &x[1], &x[2], &x[3], &x[4], &x[5], &x[6], &x[7], &consumed) >= 8 && !str[consumed]) { - if(prefixlength == -1) { - prefixlength = 128; - } - - if(prefixlength > 128) { - return false; - } - - subnet->type = SUBNET_IPV6; - subnet->net.ipv6.prefixlength = prefixlength; - subnet->weight = weight; - - for(int i = 0; i < 8; i++) { - subnet->net.ipv6.address.x[i] = htons(x[i]); - } - - return true; - } - - return false; -} - -bool net2str(char *netstr, int len, const subnet_t *subnet) { - if(!netstr || !subnet) { - logger(DEBUG_ALWAYS, LOG_ERR, "net2str() was called with netstr=%p, subnet=%p!", (void *)netstr, (void *)subnet); - return false; - } - - int result; - int prefixlength = -1; - - switch(subnet->type) { - case SUBNET_MAC: - result = snprintf(netstr, len, "%02x:%02x:%02x:%02x:%02x:%02x", - subnet->net.mac.address.x[0], - subnet->net.mac.address.x[1], - subnet->net.mac.address.x[2], - subnet->net.mac.address.x[3], - subnet->net.mac.address.x[4], - subnet->net.mac.address.x[5]); - netstr += result; - len -= result; - break; - - case SUBNET_IPV4: - result = snprintf(netstr, len, "%u.%u.%u.%u", - subnet->net.ipv4.address.x[0], - subnet->net.ipv4.address.x[1], - subnet->net.ipv4.address.x[2], - subnet->net.ipv4.address.x[3]); - netstr += result; - len -= result; - prefixlength = subnet->net.ipv4.prefixlength; - - if(prefixlength == 32) { - prefixlength = -1; - } - - break; - - case SUBNET_IPV6: { - /* Find the longest sequence of consecutive zeroes */ - int max_zero_length = 0; - int max_zero_length_index = 0; - int current_zero_length = 0; - int current_zero_length_index = 0; - - for(int i = 0; i < 8; i++) { - if(subnet->net.ipv6.address.x[i] != 0) { - current_zero_length = 0; - } else { - if(current_zero_length == 0) { - current_zero_length_index = i; - } - - current_zero_length++; - - if(current_zero_length > max_zero_length) { - max_zero_length = current_zero_length; - max_zero_length_index = current_zero_length_index; - } - } - } - - /* Print the address */ - for(int i = 0; i < 8;) { - if(max_zero_length > 1 && max_zero_length_index == i) { - /* Shorten the representation as per RFC 5952 */ - const char *const FORMATS[] = { "%.1s", "%.2s", "%.3s" }; - const char *const *format = &FORMATS[0]; - - if(i == 0) { - format++; - } - - if(i + max_zero_length == 8) { - format++; - } - - result = snprintf(netstr, len, *format, ":::"); - i += max_zero_length; - } else { - result = snprintf(netstr, len, "%x:", ntohs(subnet->net.ipv6.address.x[i])); - i++; - } - - netstr += result; - len -= result; - } - - /* Remove the trailing colon */ - netstr--; - len++; - *netstr = 0; - - prefixlength = subnet->net.ipv6.prefixlength; - - if(prefixlength == 128) { - prefixlength = -1; - } - - break; - } - - default: - logger(DEBUG_ALWAYS, LOG_ERR, "net2str() was called with unknown subnet type %d, exiting!", subnet->type); - exit(1); - } - - if(prefixlength >= 0) { - result = snprintf(netstr, len, "/%d", prefixlength); - netstr += result; - len -= result; - } - - if(subnet->weight != DEFAULT_WEIGHT) { - snprintf(netstr, len, "#%d", subnet->weight); - } - - return true; -} diff --git a/src/system.h b/src/system.h index f9675f9..14db7f5 100644 --- a/src/system.h +++ b/src/system.h @@ -4,7 +4,7 @@ /* system.h -- system headers Copyright (C) 1998-2005 Ivo Timmermans - 2003-2016 Guus Sliepen + 2003-2006 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 @@ -21,7 +21,7 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#include "../config.h" +#include "config.h" #include "have.h" @@ -33,4 +33,8 @@ #include "dropin.h" +#ifndef HAVE_SOCKLEN_T +typedef int socklen_t; +#endif + #endif diff --git a/src/tincctl.c b/src/tincctl.c deleted file mode 100644 index dccd49d..0000000 --- a/src/tincctl.c +++ /dev/null @@ -1,3352 +0,0 @@ -/* - tincctl.c -- Controlling a running tincd - Copyright (C) 2007-2018 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 - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include "system.h" - -#include - -#ifdef HAVE_READLINE -#include "readline/readline.h" -#include "readline/history.h" -#endif - -#include "xalloc.h" -#include "protocol.h" -#include "control_common.h" -#include "crypto.h" -#include "ecdsagen.h" -#include "fsck.h" -#include "info.h" -#include "invitation.h" -#include "names.h" -#include "rsagen.h" -#include "utils.h" -#include "tincctl.h" -#include "top.h" -#include "version.h" - -#ifndef MSG_NOSIGNAL -#define MSG_NOSIGNAL 0 -#endif - -static char **orig_argv; -static int orig_argc; - -/* If nonzero, display usage information and exit. */ -static bool show_help = false; - -/* If nonzero, print the version on standard output and exit. */ -static bool show_version = false; - -static char *name = NULL; -static char controlcookie[1025]; -char *tinc_conf = NULL; -char *hosts_dir = NULL; -struct timeval now; - -// Horrible global variables... -static int pid = 0; -int fd = -1; -char line[4096]; -static int code; -static int req; -static int result; -bool force = false; -bool tty = true; -bool confbasegiven = false; -bool netnamegiven = false; -char *scriptinterpreter = NULL; -char *scriptextension = ""; -static char *prompt; -char *device = NULL; -char *iface = NULL; -int debug_level = -1; - -static struct option const long_options[] = { - {"batch", no_argument, NULL, 'b'}, - {"config", required_argument, NULL, 'c'}, - {"net", required_argument, NULL, 'n'}, - {"help", no_argument, NULL, 1}, - {"version", no_argument, NULL, 2}, - {"pidfile", required_argument, NULL, 3}, - {"force", no_argument, NULL, 4}, - {NULL, 0, NULL, 0} -}; - -static void version(void) { - printf("%s version %s (built %s %s, protocol %d.%d)\n", PACKAGE, - BUILD_VERSION, BUILD_DATE, BUILD_TIME, PROT_MAJOR, PROT_MINOR); - printf("Copyright (C) 1998-2018 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" - "see the file COPYING for details.\n"); -} - -static void usage(bool status) { - if(status) { - fprintf(stderr, "Try `%s --help\' for more information.\n", program_name); - } else { - printf("Usage: %s [options] command\n\n", program_name); - printf("Valid options are:\n" - " -b, --batch Don't ask for anything (non-interactive mode).\n" - " -c, --config=DIR Read configuration options from DIR.\n" - " -n, --net=NETNAME Connect to net NETNAME.\n" - " --pidfile=FILENAME Read control cookie from FILENAME.\n" - " --force Force some commands to work despite warnings.\n" - " --help Display this help and exit.\n" - " --version Output version information and exit.\n" - "\n" - "Valid commands are:\n" - " init [name] Create initial configuration files.\n" - " get VARIABLE Print current value of VARIABLE\n" - " set VARIABLE VALUE Set VARIABLE to VALUE\n" - " add VARIABLE VALUE Add VARIABLE with the given VALUE\n" - " del VARIABLE [VALUE] Remove VARIABLE [only ones with watching VALUE]\n" - " start [tincd options] Start tincd.\n" - " stop Stop tincd.\n" - " restart [tincd options] Restart tincd.\n" - " reload Partially reload configuration of running tincd.\n" - " pid Show PID of currently running tincd.\n" -#ifdef DISABLE_LEGACY - " generate-keys Generate a new Ed25519 public/private keypair.\n" -#else - " generate-keys [bits] Generate new RSA and Ed25519 public/private keypairs.\n" - " generate-rsa-keys [bits] Generate a new RSA public/private keypair.\n" -#endif - " generate-ed25519-keys Generate a new Ed25519 public/private keypair.\n" - " dump Dump a list of one of the following things:\n" - " [reachable] nodes - all known nodes in the VPN\n" - " edges - all known connections in the VPN\n" - " subnets - all known subnets in the VPN\n" - " connections - all meta connections with ourself\n" - " [di]graph - graph of the VPN in dotty format\n" - " invitations - outstanding invitations\n" - " info NODE|SUBNET|ADDRESS Give information about a particular NODE, SUBNET or ADDRESS.\n" - " purge Purge unreachable nodes\n" - " debug N Set debug level\n" - " retry Retry all outgoing connections\n" - " disconnect NODE Close meta connection with NODE\n" -#ifdef HAVE_CURSES - " top Show real-time statistics\n" -#endif - " pcap [snaplen] Dump traffic in pcap format [up to snaplen bytes per packet]\n" - " log [level] Dump log output [up to the specified level]\n" - " export Export host configuration of local node to standard output\n" - " export-all Export all host configuration files to standard output\n" - " import Import host configuration file(s) from standard input\n" - " exchange Same as export followed by import\n" - " exchange-all Same as export-all followed by import\n" - " invite NODE [...] Generate an invitation for NODE\n" - " join INVITATION Join a VPN using an INVITATION\n" - " network [NETNAME] List all known networks, or switch to the one named NETNAME.\n" - " fsck Check the configuration files for problems.\n" - " sign [FILE] Generate a signed version of a file.\n" - " verify NODE [FILE] Verify that a file was signed by the given NODE.\n" - "\n"); - printf("Report bugs to tinc@tinc-vpn.org.\n"); - } -} - -static bool parse_options(int argc, char **argv) { - int r; - int option_index = 0; - - while((r = getopt_long(argc, argv, "+bc:n:", long_options, &option_index)) != EOF) { - switch(r) { - case 0: /* long option */ - break; - - case 'b': - tty = false; - break; - - case 'c': /* config file */ - confbase = xstrdup(optarg); - confbasegiven = true; - break; - - case 'n': /* net name given */ - netname = xstrdup(optarg); - break; - - case 1: /* show help */ - show_help = true; - break; - - case 2: /* show version */ - show_version = true; - break; - - case 3: /* open control socket here */ - pidfilename = xstrdup(optarg); - break; - - case 4: /* force */ - force = true; - break; - - case '?': /* wrong options */ - usage(true); - return false; - - default: - break; - } - } - - if(!netname && (netname = getenv("NETNAME"))) { - netname = xstrdup(netname); - } - - /* netname "." is special: a "top-level name" */ - - if(netname && (!*netname || !strcmp(netname, "."))) { - free(netname); - netname = NULL; - } - - if(netname && (strpbrk(netname, "\\/") || *netname == '.')) { - fprintf(stderr, "Invalid character in netname!\n"); - return false; - } - - return true; -} - -/* Open a file with the desired permissions, minus the umask. - Also, if we want to create an executable file, we call fchmod() - to set the executable bits. */ - -FILE *fopenmask(const char *filename, const char *mode, mode_t perms) { - mode_t mask = umask(0); - perms &= ~mask; - umask(~perms); - FILE *f = fopen(filename, mode); - - if(!f) { - fprintf(stderr, "Could not open %s: %s\n", filename, strerror(errno)); - return NULL; - } - -#ifdef HAVE_FCHMOD - - if((perms & 0444) && f) { - fchmod(fileno(f), perms); - } - -#endif - umask(mask); - return f; -} - -static void disable_old_keys(const char *filename, const char *what) { - char tmpfile[PATH_MAX] = ""; - char buf[1024]; - bool disabled = false; - bool block = false; - bool error = false; - FILE *r, *w; - - r = fopen(filename, "r"); - - if(!r) { - return; - } - - snprintf(tmpfile, sizeof(tmpfile), "%s.tmp", filename); - - struct stat st = {.st_mode = 0600}; - fstat(fileno(r), &st); - w = fopenmask(tmpfile, "w", st.st_mode); - - while(fgets(buf, sizeof(buf), r)) { - if(!block && !strncmp(buf, "-----BEGIN ", 11)) { - if((strstr(buf, " ED25519 ") && strstr(what, "Ed25519")) || (strstr(buf, " RSA ") && strstr(what, "RSA"))) { - disabled = true; - block = true; - } - } - - bool ed25519pubkey = !strncasecmp(buf, "Ed25519PublicKey", 16) && strchr(" \t=", buf[16]) && strstr(what, "Ed25519"); - - if(ed25519pubkey) { - disabled = true; - } - - if(w) { - if(block || ed25519pubkey) { - fputc('#', w); - } - - if(fputs(buf, w) < 0) { - error = true; - break; - } - } - - if(block && !strncmp(buf, "-----END ", 9)) { - block = false; - } - } - - if(w) - if(fclose(w) < 0) { - error = true; - } - - if(ferror(r) || fclose(r) < 0) { - error = true; - } - - if(disabled) { - if(!w || error) { - fprintf(stderr, "Warning: old key(s) found, remove them by hand!\n"); - - if(w) { - unlink(tmpfile); - } - - return; - } - -#ifdef HAVE_MINGW - // We cannot atomically replace files on Windows. - char bakfile[PATH_MAX] = ""; - snprintf(bakfile, sizeof(bakfile), "%s.bak", filename); - - if(rename(filename, bakfile) || rename(tmpfile, filename)) { - rename(bakfile, filename); -#else - - if(rename(tmpfile, filename)) { -#endif - fprintf(stderr, "Warning: old key(s) found, remove them by hand!\n"); - } else { -#ifdef HAVE_MINGW - unlink(bakfile); -#endif - fprintf(stderr, "Warning: old key(s) found and disabled.\n"); - } - } - - unlink(tmpfile); -} - -static FILE *ask_and_open(const char *filename, const char *what, const char *mode, bool ask, mode_t perms) { - FILE *r; - char directory[PATH_MAX] = "."; - char buf[PATH_MAX]; - char buf2[PATH_MAX]; - -ask_filename: - - /* Check stdin and stdout */ - if(ask && tty) { - /* Ask for a file and/or directory name. */ - fprintf(stderr, "Please enter a file to save %s to [%s]: ", what, filename); - - if(fgets(buf, sizeof(buf), stdin) == NULL) { - fprintf(stderr, "Error while reading stdin: %s\n", strerror(errno)); - return NULL; - } - - size_t len = strlen(buf); - - if(len) { - buf[--len] = 0; - } - - if(len) { - filename = buf; - } - } - -#ifdef HAVE_MINGW - - if(filename[0] != '\\' && filename[0] != '/' && !strchr(filename, ':')) { -#else - - if(filename[0] != '/') { -#endif - /* The directory is a relative path or a filename. */ - getcwd(directory, sizeof(directory)); - - if((size_t)snprintf(buf2, sizeof(buf2), "%s" SLASH "%s", directory, filename) >= sizeof(buf2)) { - fprintf(stderr, "Filename too long: %s" SLASH "%s\n", directory, filename); - - if(ask && tty) { - goto ask_filename; - } else { - return NULL; - } - } - - filename = buf2; - } - - disable_old_keys(filename, what); - - /* Open it first to keep the inode busy */ - - r = fopenmask(filename, mode, perms); - - if(!r) { - fprintf(stderr, "Error opening file `%s': %s\n", filename, strerror(errno)); - return NULL; - } - - return r; -} - -/* - Generate a public/private Ed25519 keypair, and ask for a file to store - them in. -*/ -static bool ed25519_keygen(bool ask) { - ecdsa_t *key; - FILE *f; - char fname[PATH_MAX]; - - fprintf(stderr, "Generating Ed25519 keypair:\n"); - - if(!(key = ecdsa_generate())) { - fprintf(stderr, "Error during key generation!\n"); - return false; - } else { - fprintf(stderr, "Done.\n"); - } - - snprintf(fname, sizeof(fname), "%s" SLASH "ed25519_key.priv", confbase); - f = ask_and_open(fname, "private Ed25519 key", "a", ask, 0600); - - if(!f) { - goto error; - } - - if(!ecdsa_write_pem_private_key(key, f)) { - fprintf(stderr, "Error writing private key!\n"); - goto error; - } - - fclose(f); - - if(name) { - snprintf(fname, sizeof(fname), "%s" SLASH "hosts" SLASH "%s", confbase, name); - } else { - snprintf(fname, sizeof(fname), "%s" SLASH "ed25519_key.pub", confbase); - } - - f = ask_and_open(fname, "public Ed25519 key", "a", ask, 0666); - - if(!f) { - return false; - } - - char *pubkey = ecdsa_get_base64_public_key(key); - fprintf(f, "Ed25519PublicKey = %s\n", pubkey); - free(pubkey); - - fclose(f); - ecdsa_free(key); - - return true; - -error: - - if(f) { - fclose(f); - } - - ecdsa_free(key); - return false; -} - -#ifndef DISABLE_LEGACY -/* - Generate a public/private RSA keypair, and ask for a file to store - them in. -*/ -static bool rsa_keygen(int bits, bool ask) { - rsa_t *key; - FILE *f; - char fname[PATH_MAX]; - - // Make sure the key size is a multiple of 8 bits. - bits &= ~0x7; - - // Make sure that a valid key size is used. - if(bits < 1024 || bits > 8192) { - fprintf(stderr, "Invalid key size %d specified! It should be between 1024 and 8192 bits.\n", bits); - return false; - } else if(bits < 2048) { - fprintf(stderr, "WARNING: generating a weak %d bits RSA key! 2048 or more bits are recommended.\n", bits); - } - - fprintf(stderr, "Generating %d bits keys:\n", bits); - - if(!(key = rsa_generate(bits, 0x10001))) { - fprintf(stderr, "Error during key generation!\n"); - return false; - } else { - fprintf(stderr, "Done.\n"); - } - - snprintf(fname, sizeof(fname), "%s" SLASH "rsa_key.priv", confbase); - f = ask_and_open(fname, "private RSA key", "a", ask, 0600); - - if(!f) { - goto error; - } - - if(!rsa_write_pem_private_key(key, f)) { - fprintf(stderr, "Error writing private key!\n"); - goto error; - } - - fclose(f); - - if(name) { - snprintf(fname, sizeof(fname), "%s" SLASH "hosts" SLASH "%s", confbase, name); - } else { - snprintf(fname, sizeof(fname), "%s" SLASH "rsa_key.pub", confbase); - } - - f = ask_and_open(fname, "public RSA key", "a", ask, 0666); - - if(!f) { - goto error; - } - - if(!rsa_write_pem_public_key(key, f)) { - fprintf(stderr, "Error writing public key!\n"); - goto error; - } - - fclose(f); - rsa_free(key); - - return true; - -error: - - if(f) { - fclose(f); - } - - rsa_free(key); - return false; -} -#endif - -char buffer[4096]; -size_t blen = 0; - -bool recvline(int fd, char *line, size_t len) { - char *newline = NULL; - - if(!fd) { - return false; - } - - while(!(newline = memchr(buffer, '\n', blen))) { - int result = recv(fd, buffer + blen, sizeof(buffer) - blen, 0); - - if(result == -1 && sockerrno == EINTR) { - continue; - } else if(result <= 0) { - return false; - } - - blen += result; - } - - if((size_t)(newline - buffer) >= len) { - return false; - } - - len = newline - buffer; - - memcpy(line, buffer, len); - line[len] = 0; - memmove(buffer, newline + 1, blen - len - 1); - blen -= len + 1; - - return true; -} - -static bool recvdata(int fd, char *data, size_t len) { - while(blen < len) { - int result = recv(fd, buffer + blen, sizeof(buffer) - blen, 0); - - if(result == -1 && sockerrno == EINTR) { - continue; - } else if(result <= 0) { - return false; - } - - blen += result; - } - - memcpy(data, buffer, len); - memmove(buffer, buffer + len, blen - len); - blen -= len; - - return true; -} - -bool sendline(int fd, char *format, ...) { - static char buffer[4096]; - char *p = buffer; - int blen; - va_list ap; - - va_start(ap, format); - blen = vsnprintf(buffer, sizeof(buffer), format, ap); - buffer[sizeof(buffer) - 1] = 0; - va_end(ap); - - if(blen < 1 || (size_t)blen >= sizeof(buffer)) { - return false; - } - - buffer[blen] = '\n'; - blen++; - - while(blen) { - int result = send(fd, p, blen, MSG_NOSIGNAL); - - if(result == -1 && sockerrno == EINTR) { - continue; - } else if(result <= 0) { - return false; - } - - p += result; - blen -= result; - } - - return true; -} - -static void pcap(int fd, FILE *out, uint32_t snaplen) { - sendline(fd, "%d %d %d", CONTROL, REQ_PCAP, snaplen); - char data[9018]; - - struct { - uint32_t magic; - uint16_t major; - uint16_t minor; - uint32_t tz_offset; - uint32_t tz_accuracy; - uint32_t snaplen; - uint32_t ll_type; - } header = { - 0xa1b2c3d4, - 2, 4, - 0, 0, - snaplen ? snaplen : sizeof(data), - 1, - }; - - struct { - uint32_t tv_sec; - uint32_t tv_usec; - uint32_t len; - uint32_t origlen; - } packet; - - struct timeval tv; - - fwrite(&header, sizeof(header), 1, out); - fflush(out); - - char line[32]; - - while(recvline(fd, line, sizeof(line))) { - int code, req, len; - int n = sscanf(line, "%d %d %d", &code, &req, &len); - gettimeofday(&tv, NULL); - - if(n != 3 || code != CONTROL || req != REQ_PCAP || len < 0 || (size_t)len > sizeof(data)) { - break; - } - - if(!recvdata(fd, data, len)) { - break; - } - - packet.tv_sec = tv.tv_sec; - packet.tv_usec = tv.tv_usec; - packet.len = len; - packet.origlen = len; - fwrite(&packet, sizeof(packet), 1, out); - fwrite(data, len, 1, out); - fflush(out); - } -} - -static void logcontrol(int fd, FILE *out, int level) { - sendline(fd, "%d %d %d", CONTROL, REQ_LOG, level); - char data[1024]; - char line[32]; - - while(recvline(fd, line, sizeof(line))) { - int code, req, len; - int n = sscanf(line, "%d %d %d", &code, &req, &len); - - if(n != 3 || code != CONTROL || req != REQ_LOG || len < 0 || (size_t)len > sizeof(data)) { - break; - } - - if(!recvdata(fd, data, len)) { - break; - } - - fwrite(data, len, 1, out); - fputc('\n', out); - fflush(out); - } -} - -#ifdef HAVE_MINGW -static bool remove_service(void) { - SC_HANDLE manager = NULL; - SC_HANDLE service = NULL; - SERVICE_STATUS status = {0}; - bool success = false; - - manager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); - - if(!manager) { - fprintf(stderr, "Could not open service manager: %s\n", winerror(GetLastError())); - goto exit; - } - - service = OpenService(manager, identname, SERVICE_ALL_ACCESS); - - if(!service) { - fprintf(stderr, "Could not open %s service: %s\n", identname, winerror(GetLastError())); - goto exit; - } - - if(!ControlService(service, SERVICE_CONTROL_STOP, &status)) { - fprintf(stderr, "Could not stop %s service: %s\n", identname, winerror(GetLastError())); - } else { - fprintf(stderr, "%s service stopped\n", identname); - } - - if(!DeleteService(service)) { - fprintf(stderr, "Could not remove %s service: %s\n", identname, winerror(GetLastError())); - goto exit; - } - - success = true; - -exit: - - if(service) { - CloseServiceHandle(service); - } - - if(manager) { - CloseServiceHandle(manager); - } - - if(success) { - fprintf(stderr, "%s service removed\n", identname); - } - - return success; -} -#endif - -bool connect_tincd(bool verbose) { - if(fd >= 0) { - fd_set r; - FD_ZERO(&r); - FD_SET(fd, &r); - struct timeval tv = {0, 0}; - - if(select(fd + 1, &r, NULL, NULL, &tv)) { - fprintf(stderr, "Previous connection to tincd lost, reconnecting.\n"); - close(fd); - fd = -1; - } else { - return true; - } - } - - FILE *f = fopen(pidfilename, "r"); - - if(!f) { - if(verbose) { - fprintf(stderr, "Could not open pid file %s: %s\n", pidfilename, strerror(errno)); - } - - return false; - } - - char host[129]; - char port[129]; - - if(fscanf(f, "%20d %1024s %128s port %128s", &pid, controlcookie, host, port) != 4) { - if(verbose) { - fprintf(stderr, "Could not parse pid file %s\n", pidfilename); - } - - fclose(f); - return false; - } - - fclose(f); - -#ifndef HAVE_MINGW - - if((pid == 0) || (kill(pid, 0) && (errno == ESRCH))) { - fprintf(stderr, "Could not find tincd running at pid %d\n", pid); - /* clean up the stale socket and pid file */ - unlink(pidfilename); - unlink(unixsocketname); - return false; - } - - struct sockaddr_un sa; - - sa.sun_family = AF_UNIX; - - strncpy(sa.sun_path, unixsocketname, sizeof(sa.sun_path)); - - sa.sun_path[sizeof(sa.sun_path) - 1] = 0; - - fd = socket(AF_UNIX, SOCK_STREAM, 0); - - if(fd < 0) { - if(verbose) { - fprintf(stderr, "Cannot create UNIX socket: %s\n", sockstrerror(sockerrno)); - } - - return false; - } - - if(connect(fd, (struct sockaddr *)&sa, sizeof(sa)) < 0) { - if(verbose) { - fprintf(stderr, "Cannot connect to UNIX socket %s: %s\n", unixsocketname, sockstrerror(sockerrno)); - } - - close(fd); - fd = -1; - return false; - } - -#else - struct addrinfo hints = { - .ai_family = AF_UNSPEC, - .ai_socktype = SOCK_STREAM, - .ai_protocol = IPPROTO_TCP, - .ai_flags = 0, - }; - - struct addrinfo *res = NULL; - - if(getaddrinfo(host, port, &hints, &res) || !res) { - if(verbose) { - fprintf(stderr, "Cannot resolve %s port %s: %s\n", host, port, sockstrerror(sockerrno)); - } - - return false; - } - - fd = socket(res->ai_family, SOCK_STREAM, IPPROTO_TCP); - - if(fd < 0) { - if(verbose) { - fprintf(stderr, "Cannot create TCP socket: %s\n", sockstrerror(sockerrno)); - } - - return false; - } - -#ifdef HAVE_MINGW - unsigned long arg = 0; - - if(ioctlsocket(fd, FIONBIO, &arg) != 0) { - if(verbose) { - fprintf(stderr, "System call `%s' failed: %s\n", "ioctlsocket", sockstrerror(sockerrno)); - } - } - -#endif - - if(connect(fd, res->ai_addr, res->ai_addrlen) < 0) { - if(verbose) { - fprintf(stderr, "Cannot connect to %s port %s: %s\n", host, port, sockstrerror(sockerrno)); - } - - close(fd); - fd = -1; - return false; - } - - freeaddrinfo(res); -#endif - -#ifdef SO_NOSIGPIPE - static const int one = 1; - setsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, (void *)&one, sizeof(one)); -#endif - - sendline(fd, "%d ^%s %d", ID, controlcookie, TINC_CTL_VERSION_CURRENT); - - char data[4096]; - int version; - - if(!recvline(fd, line, sizeof(line)) || sscanf(line, "%d %4095s %d", &code, data, &version) != 3 || code != 0) { - if(verbose) { - fprintf(stderr, "Cannot read greeting from control socket: %s\n", sockstrerror(sockerrno)); - } - - close(fd); - fd = -1; - return false; - } - - if(!recvline(fd, line, sizeof(line)) || sscanf(line, "%d %d %d", &code, &version, &pid) != 3 || code != 4 || version != TINC_CTL_VERSION_CURRENT) { - if(verbose) { - fprintf(stderr, "Could not fully establish control socket connection\n"); - } - - close(fd); - fd = -1; - return false; - } - - return true; -} - - -static int cmd_start(int argc, char *argv[]) { - if(connect_tincd(false)) { - if(netname) { - fprintf(stderr, "A tincd is already running for net `%s' with pid %d.\n", netname, pid); - } else { - fprintf(stderr, "A tincd is already running with pid %d.\n", pid); - } - - return 0; - } - - char *c; - char *slash = strrchr(program_name, '/'); - -#ifdef HAVE_MINGW - - if((c = strrchr(program_name, '\\')) > slash) { - slash = c; - } - -#endif - - if(slash++) { - xasprintf(&c, "%.*stincd", (int)(slash - program_name), program_name); - } else { - c = "tincd"; - } - - int nargc = 0; - char **nargv = xzalloc((optind + argc) * sizeof(*nargv)); - - char *arg0 = c; -#ifdef HAVE_MINGW - /* - Windows has no real concept of an "argv array". A command line is just one string. - The CRT of the new process will decode the command line string to generate argv before calling main(), and (by convention) - it uses quotes to handle spaces in arguments. - Therefore we need to quote all arguments that might contain spaces. No, execvp() won't do that for us (see MSDN). - If we don't do that, then execvp() will run fine but any spaces in the filename contained in arg0 will bleed - into the next arguments when the spawned process' CRT parses its command line, resulting in chaos. - */ - xasprintf(&arg0, "\"%s\"", arg0); -#endif - nargv[nargc++] = arg0; - - for(int i = 1; i < optind; i++) { - nargv[nargc++] = orig_argv[i]; - } - - for(int i = 1; i < argc; i++) { - nargv[nargc++] = argv[i]; - } - -#ifdef HAVE_MINGW - int status = spawnvp(_P_WAIT, c, nargv); - - if(status == -1) { - fprintf(stderr, "Error starting %s: %s\n", c, strerror(errno)); - return 1; - } - - return status; -#else - int pfd[2] = {-1, -1}; - - if(socketpair(AF_UNIX, SOCK_STREAM, 0, pfd)) { - fprintf(stderr, "Could not create umbilical socket: %s\n", strerror(errno)); - free(nargv); - return 1; - } - - pid_t pid = fork(); - - if(pid == -1) { - fprintf(stderr, "Could not fork: %s\n", strerror(errno)); - free(nargv); - return 1; - } - - if(!pid) { - close(pfd[0]); - char buf[100]; - snprintf(buf, sizeof(buf), "%d", pfd[1]); - setenv("TINC_UMBILICAL", buf, true); - exit(execvp(c, nargv)); - } else { - close(pfd[1]); - } - - free(nargv); - - int status = -1, result; -#ifdef SIGINT - signal(SIGINT, SIG_IGN); -#endif - - // Pass all log messages from the umbilical to stderr. - // A nul-byte right before closure means tincd started successfully. - bool failure = true; - char buf[1024]; - ssize_t len; - - while((len = read(pfd[0], buf, sizeof(buf))) > 0) { - failure = buf[len - 1]; - - if(!failure) { - len--; - } - - write(2, buf, len); - } - - if(len) { - failure = true; - } - - close(pfd[0]); - - // Make sure the child process is really gone. - result = waitpid(pid, &status, 0); - -#ifdef SIGINT - signal(SIGINT, SIG_DFL); -#endif - - if(failure || result != pid || !WIFEXITED(status) || WEXITSTATUS(status)) { - fprintf(stderr, "Error starting %s\n", c); - return 1; - } - - return 0; -#endif -} - -static int cmd_stop(int argc, char *argv[]) { - (void)argv; - - if(argc > 1) { - fprintf(stderr, "Too many arguments!\n"); - return 1; - } - -#ifndef HAVE_MINGW - - if(!connect_tincd(true)) { - if(pid) { - if(kill(pid, SIGTERM)) { - fprintf(stderr, "Could not send TERM signal to process with PID %d: %s\n", pid, strerror(errno)); - return 1; - } - - fprintf(stderr, "Sent TERM signal to process with PID %d.\n", pid); - waitpid(pid, NULL, 0); - return 0; - } - - return 1; - } - - sendline(fd, "%d %d", CONTROL, REQ_STOP); - - while(recvline(fd, line, sizeof(line))) { - // Wait for tincd to close the connection... - } - -#else - - if(!remove_service()) { - return 1; - } - -#endif - close(fd); - pid = 0; - fd = -1; - - return 0; -} - -static int cmd_restart(int argc, char *argv[]) { - cmd_stop(1, argv); - return cmd_start(argc, argv); -} - -static int cmd_reload(int argc, char *argv[]) { - (void)argv; - - if(argc > 1) { - fprintf(stderr, "Too many arguments!\n"); - return 1; - } - - if(!connect_tincd(true)) { - return 1; - } - - sendline(fd, "%d %d", CONTROL, REQ_RELOAD); - - if(!recvline(fd, line, sizeof(line)) || sscanf(line, "%d %d %d", &code, &req, &result) != 3 || code != CONTROL || req != REQ_RELOAD || result) { - fprintf(stderr, "Could not reload configuration.\n"); - return 1; - } - - return 0; - -} - -static int dump_invitations(void) { - char dname[PATH_MAX]; - snprintf(dname, sizeof(dname), "%s" SLASH "invitations", confbase); - DIR *dir = opendir(dname); - - if(!dir) { - if(errno == ENOENT) { - fprintf(stderr, "No outstanding invitations.\n"); - return 0; - } - - fprintf(stderr, "Cannot not read directory %s: %s\n", dname, strerror(errno)); - return 1; - } - - struct dirent *ent; - - bool found = false; - - while((ent = readdir(dir))) { - char buf[MAX_STRING_SIZE]; - - if(b64decode(ent->d_name, buf, 24) != 18) { - continue; - } - - char fname[PATH_MAX]; - - if((size_t)snprintf(fname, sizeof(fname), "%s" SLASH "%s", dname, ent->d_name) >= sizeof(fname)) { - fprintf(stderr, "Filename too long: %s" SLASH "%s\n", dname, ent->d_name); - continue; - } - - FILE *f = fopen(fname, "r"); - - if(!f) { - fprintf(stderr, "Cannot open %s: %s\n", fname, strerror(errno)); - continue; - } - - buf[0] = 0; - - if(!fgets(buf, sizeof(buf), f)) { - fprintf(stderr, "Invalid invitation file %s\n", fname); - fclose(f); - continue; - } - - fclose(f); - - char *eol = buf + strlen(buf); - - while(strchr("\t \r\n", *--eol)) { - *eol = 0; - } - - if(strncmp(buf, "Name = ", 7) || !check_id(buf + 7)) { - fprintf(stderr, "Invalid invitation file %s\n", fname); - continue; - } - - found = true; - printf("%s %s\n", ent->d_name, buf + 7); - } - - closedir(dir); - - if(!found) { - fprintf(stderr, "No outstanding invitations.\n"); - } - - return 0; -} - -static int cmd_dump(int argc, char *argv[]) { - bool only_reachable = false; - - if(argc > 2 && !strcasecmp(argv[1], "reachable")) { - if(strcasecmp(argv[2], "nodes")) { - fprintf(stderr, "`reachable' only supported for nodes.\n"); - usage(true); - return 1; - } - - only_reachable = true; - argv++; - argc--; - } - - if(argc != 2) { - fprintf(stderr, "Invalid number of arguments.\n"); - usage(true); - return 1; - } - - if(!strcasecmp(argv[1], "invitations")) { - return dump_invitations(); - } - - if(!connect_tincd(true)) { - return 1; - } - - int do_graph = 0; - - if(!strcasecmp(argv[1], "nodes")) { - sendline(fd, "%d %d", CONTROL, REQ_DUMP_NODES); - } else if(!strcasecmp(argv[1], "edges")) { - sendline(fd, "%d %d", CONTROL, REQ_DUMP_EDGES); - } else if(!strcasecmp(argv[1], "subnets")) { - sendline(fd, "%d %d", CONTROL, REQ_DUMP_SUBNETS); - } else if(!strcasecmp(argv[1], "connections")) { - sendline(fd, "%d %d", CONTROL, REQ_DUMP_CONNECTIONS); - } else if(!strcasecmp(argv[1], "graph")) { - sendline(fd, "%d %d", CONTROL, REQ_DUMP_NODES); - sendline(fd, "%d %d", CONTROL, REQ_DUMP_EDGES); - do_graph = 1; - } else if(!strcasecmp(argv[1], "digraph")) { - sendline(fd, "%d %d", CONTROL, REQ_DUMP_NODES); - sendline(fd, "%d %d", CONTROL, REQ_DUMP_EDGES); - do_graph = 2; - } else { - fprintf(stderr, "Unknown dump type '%s'.\n", argv[1]); - usage(true); - return 1; - } - - if(do_graph == 1) { - printf("graph {\n"); - } else if(do_graph == 2) { - printf("digraph {\n"); - } - - while(recvline(fd, line, sizeof(line))) { - char node1[4096], node2[4096]; - int n = sscanf(line, "%d %d %4095s %4095s", &code, &req, node1, node2); - - if(n == 2) { - if(do_graph && req == REQ_DUMP_NODES) { - continue; - } else { - if(do_graph) { - printf("}\n"); - } - - return 0; - } - } - - if(n < 2) { - break; - } - - char node[4096]; - char id[4096]; - char from[4096]; - char to[4096]; - char subnet[4096]; - char host[4096]; - char port[4096]; - char local_host[4096]; - char local_port[4096]; - char via[4096]; - char nexthop[4096]; - int cipher, digest, maclength, compression, distance, socket, weight; - short int pmtu, minmtu, maxmtu; - unsigned int options, status_int; - node_status_t status; - long int last_state_change; - int udp_ping_rtt; - uint64_t in_packets, in_bytes, out_packets, out_bytes; - - switch(req) { - case REQ_DUMP_NODES: { - int n = sscanf(line, "%*d %*d %4095s %4095s %4095s port %4095s %d %d %d %d %x %x %4095s %4095s %d %hd %hd %hd %ld %d %"PRIu64" %"PRIu64" %"PRIu64" %"PRIu64, node, id, host, port, &cipher, &digest, &maclength, &compression, &options, &status_int, nexthop, via, &distance, &pmtu, &minmtu, &maxmtu, &last_state_change, &udp_ping_rtt, &in_packets, &in_bytes, &out_packets, &out_bytes); - - if(n != 22) { - fprintf(stderr, "Unable to parse node dump from tincd: %s\n", line); - return 1; - } - - memcpy(&status, &status_int, sizeof(status)); - - if(do_graph) { - const char *color = "black"; - - if(!strcmp(host, "MYSELF")) { - color = "green"; - } else if(!status.reachable) { - color = "red"; - } else if(strcmp(via, node)) { - color = "orange"; - } else if(!status.validkey) { - color = "black"; - } else if(minmtu > 0) { - color = "green"; - } - - printf(" %s [label = \"%s\", color = \"%s\"%s];\n", node, node, color, strcmp(host, "MYSELF") ? "" : ", style = \"filled\""); - } else { - if(only_reachable && !status.reachable) { - continue; - } - - printf("%s id %s at %s port %s cipher %d digest %d maclength %d compression %d options %x status %04x nexthop %s via %s distance %d pmtu %d (min %d max %d) rx %"PRIu64" %"PRIu64" tx %"PRIu64" %"PRIu64, - node, id, host, port, cipher, digest, maclength, compression, options, status_int, nexthop, via, distance, pmtu, minmtu, maxmtu, in_packets, in_bytes, out_packets, out_bytes); - - if(udp_ping_rtt != -1) { - printf(" rtt %d.%03d", udp_ping_rtt / 1000, udp_ping_rtt % 1000); - } - - printf("\n"); - } - } - break; - - case REQ_DUMP_EDGES: { - int n = sscanf(line, "%*d %*d %4095s %4095s %4095s port %4095s %4095s port %4095s %x %d", from, to, host, port, local_host, local_port, &options, &weight); - - if(n != 8) { - fprintf(stderr, "Unable to parse edge dump from tincd.\n"); - return 1; - } - - if(do_graph) { - float w = 1 + 65536.0 / weight; - - if(do_graph == 1 && strcmp(node1, node2) > 0) { - printf(" %s -- %s [w = %f, weight = %f];\n", node1, node2, w, w); - } else if(do_graph == 2) { - printf(" %s -> %s [w = %f, weight = %f];\n", node1, node2, w, w); - } - } else { - printf("%s to %s at %s port %s local %s port %s options %x weight %d\n", from, to, host, port, local_host, local_port, options, weight); - } - } - break; - - case REQ_DUMP_SUBNETS: { - int n = sscanf(line, "%*d %*d %4095s %4095s", subnet, node); - - if(n != 2) { - fprintf(stderr, "Unable to parse subnet dump from tincd.\n"); - return 1; - } - - printf("%s owner %s\n", strip_weight(subnet), node); - } - break; - - case REQ_DUMP_CONNECTIONS: { - int n = sscanf(line, "%*d %*d %4095s %4095s port %4095s %x %d %x", node, host, port, &options, &socket, &status_int); - - if(n != 6) { - fprintf(stderr, "Unable to parse connection dump from tincd.\n"); - return 1; - } - - printf("%s at %s port %s options %x socket %d status %x\n", node, host, port, options, socket, status_int); - } - break; - - default: - fprintf(stderr, "Unable to parse dump from tincd.\n"); - return 1; - } - } - - fprintf(stderr, "Error receiving dump.\n"); - return 1; -} - -static int cmd_purge(int argc, char *argv[]) { - (void)argv; - - if(argc > 1) { - fprintf(stderr, "Too many arguments!\n"); - return 1; - } - - if(!connect_tincd(true)) { - return 1; - } - - sendline(fd, "%d %d", CONTROL, REQ_PURGE); - - if(!recvline(fd, line, sizeof(line)) || sscanf(line, "%d %d %d", &code, &req, &result) != 3 || code != CONTROL || req != REQ_PURGE || result) { - fprintf(stderr, "Could not purge old information.\n"); - return 1; - } - - return 0; -} - -static int cmd_debug(int argc, char *argv[]) { - if(argc != 2) { - fprintf(stderr, "Invalid number of arguments.\n"); - return 1; - } - - if(!connect_tincd(true)) { - return 1; - } - - int debuglevel = atoi(argv[1]); - int origlevel; - - sendline(fd, "%d %d %d", CONTROL, REQ_SET_DEBUG, debuglevel); - - if(!recvline(fd, line, sizeof(line)) || sscanf(line, "%d %d %d", &code, &req, &origlevel) != 3 || code != CONTROL || req != REQ_SET_DEBUG) { - fprintf(stderr, "Could not set debug level.\n"); - return 1; - } - - fprintf(stderr, "Old level %d, new level %d.\n", origlevel, debuglevel); - return 0; -} - -static int cmd_retry(int argc, char *argv[]) { - (void)argv; - - if(argc > 1) { - fprintf(stderr, "Too many arguments!\n"); - return 1; - } - - if(!connect_tincd(true)) { - return 1; - } - - sendline(fd, "%d %d", CONTROL, REQ_RETRY); - - if(!recvline(fd, line, sizeof(line)) || sscanf(line, "%d %d %d", &code, &req, &result) != 3 || code != CONTROL || req != REQ_RETRY || result) { - fprintf(stderr, "Could not retry outgoing connections.\n"); - return 1; - } - - return 0; -} - -static int cmd_connect(int argc, char *argv[]) { - if(argc != 2) { - fprintf(stderr, "Invalid number of arguments.\n"); - return 1; - } - - if(!check_id(argv[1])) { - fprintf(stderr, "Invalid name for node.\n"); - return 1; - } - - if(!connect_tincd(true)) { - return 1; - } - - sendline(fd, "%d %d %s", CONTROL, REQ_CONNECT, argv[1]); - - if(!recvline(fd, line, sizeof(line)) || sscanf(line, "%d %d %d", &code, &req, &result) != 3 || code != CONTROL || req != REQ_CONNECT || result) { - fprintf(stderr, "Could not connect to %s.\n", argv[1]); - return 1; - } - - return 0; -} - -static int cmd_disconnect(int argc, char *argv[]) { - if(argc != 2) { - fprintf(stderr, "Invalid number of arguments.\n"); - return 1; - } - - if(!check_id(argv[1])) { - fprintf(stderr, "Invalid name for node.\n"); - return 1; - } - - if(!connect_tincd(true)) { - return 1; - } - - sendline(fd, "%d %d %s", CONTROL, REQ_DISCONNECT, argv[1]); - - if(!recvline(fd, line, sizeof(line)) || sscanf(line, "%d %d %d", &code, &req, &result) != 3 || code != CONTROL || req != REQ_DISCONNECT || result) { - fprintf(stderr, "Could not disconnect %s.\n", argv[1]); - return 1; - } - - return 0; -} - -static int cmd_top(int argc, char *argv[]) { - (void)argv; - - if(argc > 1) { - fprintf(stderr, "Too many arguments!\n"); - return 1; - } - -#ifdef HAVE_CURSES - - if(!connect_tincd(true)) { - return 1; - } - - top(fd); - return 0; -#else - fprintf(stderr, "This version of tinc was compiled without support for the curses library.\n"); - return 1; -#endif -} - -static int cmd_pcap(int argc, char *argv[]) { - if(argc > 2) { - fprintf(stderr, "Too many arguments!\n"); - return 1; - } - - if(!connect_tincd(true)) { - return 1; - } - - pcap(fd, stdout, argc > 1 ? atoi(argv[1]) : 0); - return 0; -} - -#ifdef SIGINT -static void sigint_handler(int sig) { - (void)sig; - - fprintf(stderr, "\n"); - shutdown(fd, SHUT_RDWR); -} -#endif - -static int cmd_log(int argc, char *argv[]) { - if(argc > 2) { - fprintf(stderr, "Too many arguments!\n"); - return 1; - } - - if(!connect_tincd(true)) { - return 1; - } - -#ifdef SIGINT - signal(SIGINT, sigint_handler); -#endif - - logcontrol(fd, stdout, argc > 1 ? atoi(argv[1]) : -1); - -#ifdef SIGINT - signal(SIGINT, SIG_DFL); -#endif - - close(fd); - fd = -1; - return 0; -} - -static int cmd_pid(int argc, char *argv[]) { - (void)argv; - - if(argc > 1) { - fprintf(stderr, "Too many arguments!\n"); - return 1; - } - - if(!connect_tincd(true) || !pid) { - return 1; - } - - printf("%d\n", pid); - return 0; -} - -int rstrip(char *value) { - int len = strlen(value); - - while(len && strchr("\t\r\n ", value[len - 1])) { - value[--len] = 0; - } - - return len; -} - -char *get_my_name(bool verbose) { - FILE *f = fopen(tinc_conf, "r"); - - if(!f) { - if(verbose) { - fprintf(stderr, "Could not open %s: %s\n", tinc_conf, strerror(errno)); - } - - return NULL; - } - - char buf[4096]; - char *value; - - while(fgets(buf, sizeof(buf), f)) { - int len = strcspn(buf, "\t ="); - value = buf + len; - value += strspn(value, "\t "); - - if(*value == '=') { - value++; - value += strspn(value, "\t "); - } - - if(!rstrip(value)) { - continue; - } - - buf[len] = 0; - - if(strcasecmp(buf, "Name")) { - continue; - } - - if(*value) { - fclose(f); - return replace_name(value); - } - } - - fclose(f); - - if(verbose) { - fprintf(stderr, "Could not find Name in %s.\n", tinc_conf); - } - - return NULL; -} - -ecdsa_t *get_pubkey(FILE *f) { - char buf[4096]; - char *value; - - while(fgets(buf, sizeof(buf), f)) { - int len = strcspn(buf, "\t ="); - value = buf + len; - value += strspn(value, "\t "); - - if(*value == '=') { - value++; - value += strspn(value, "\t "); - } - - if(!rstrip(value)) { - continue; - } - - buf[len] = 0; - - if(strcasecmp(buf, "Ed25519PublicKey")) { - continue; - } - - if(*value) { - return ecdsa_set_base64_public_key(value); - } - } - - return NULL; -} - -const var_t variables[] = { - /* Server configuration */ - {"AddressFamily", VAR_SERVER}, - {"AutoConnect", VAR_SERVER | VAR_SAFE}, - {"BindToAddress", VAR_SERVER | VAR_MULTIPLE}, - {"BindToInterface", VAR_SERVER}, - {"Broadcast", VAR_SERVER | VAR_SAFE}, - {"BroadcastSubnet", VAR_SERVER | VAR_MULTIPLE | VAR_SAFE}, - {"ConnectTo", VAR_SERVER | VAR_MULTIPLE | VAR_SAFE}, - {"DecrementTTL", VAR_SERVER}, - {"Device", VAR_SERVER}, - {"DeviceStandby", VAR_SERVER}, - {"DeviceType", VAR_SERVER}, - {"DirectOnly", VAR_SERVER}, - {"Ed25519PrivateKeyFile", VAR_SERVER}, - {"ExperimentalProtocol", VAR_SERVER}, - {"Forwarding", VAR_SERVER}, - {"FWMark", VAR_SERVER}, - {"GraphDumpFile", VAR_SERVER | VAR_OBSOLETE}, - {"Hostnames", VAR_SERVER}, - {"IffOneQueue", VAR_SERVER}, - {"Interface", VAR_SERVER}, - {"InvitationExpire", VAR_SERVER}, - {"KeyExpire", VAR_SERVER}, - {"ListenAddress", VAR_SERVER | VAR_MULTIPLE}, - {"LocalDiscovery", VAR_SERVER}, - {"LogLevel", VAR_SERVER}, - {"MACExpire", VAR_SERVER}, - {"MaxConnectionBurst", VAR_SERVER}, - {"MaxOutputBufferSize", VAR_SERVER}, - {"MaxTimeout", VAR_SERVER}, - {"Mode", VAR_SERVER | VAR_SAFE}, - {"Name", VAR_SERVER}, - {"PingInterval", VAR_SERVER}, - {"PingTimeout", VAR_SERVER}, - {"PriorityInheritance", VAR_SERVER}, - {"PrivateKey", VAR_SERVER | VAR_OBSOLETE}, - {"PrivateKeyFile", VAR_SERVER}, - {"ProcessPriority", VAR_SERVER}, - {"Proxy", VAR_SERVER}, - {"ReplayWindow", VAR_SERVER}, - {"ScriptsExtension", VAR_SERVER}, - {"ScriptsInterpreter", VAR_SERVER}, - {"StrictSubnets", VAR_SERVER}, - {"TunnelServer", VAR_SERVER}, - {"UDPDiscovery", VAR_SERVER}, - {"UDPDiscoveryKeepaliveInterval", VAR_SERVER}, - {"UDPDiscoveryInterval", VAR_SERVER}, - {"UDPDiscoveryTimeout", VAR_SERVER}, - {"MTUInfoInterval", VAR_SERVER}, - {"UDPInfoInterval", VAR_SERVER}, - {"UDPRcvBuf", VAR_SERVER}, - {"UDPSndBuf", VAR_SERVER}, - {"UPnP", VAR_SERVER}, - {"UPnPDiscoverWait", VAR_SERVER}, - {"UPnPRefreshPeriod", VAR_SERVER}, - {"VDEGroup", VAR_SERVER}, - {"VDEPort", VAR_SERVER}, - /* Host configuration */ - {"Address", VAR_HOST | VAR_MULTIPLE}, - {"Cipher", VAR_SERVER | VAR_HOST}, - {"ClampMSS", VAR_SERVER | VAR_HOST}, - {"Compression", VAR_SERVER | VAR_HOST}, - {"Digest", VAR_SERVER | VAR_HOST}, - {"Ed25519PublicKey", VAR_HOST}, - {"Ed25519PublicKeyFile", VAR_SERVER | VAR_HOST}, - {"IndirectData", VAR_SERVER | VAR_HOST}, - {"MACLength", VAR_SERVER | VAR_HOST}, - {"PMTU", VAR_SERVER | VAR_HOST}, - {"PMTUDiscovery", VAR_SERVER | VAR_HOST}, - {"Port", VAR_HOST}, - {"PublicKey", VAR_HOST | VAR_OBSOLETE}, - {"PublicKeyFile", VAR_SERVER | VAR_HOST | VAR_OBSOLETE}, - {"Subnet", VAR_HOST | VAR_MULTIPLE | VAR_SAFE}, - {"TCPOnly", VAR_SERVER | VAR_HOST}, - {"Weight", VAR_HOST | VAR_SAFE}, - {NULL, 0} -}; - -static int cmd_config(int argc, char *argv[]) { - if(argc < 2) { - fprintf(stderr, "Invalid number of arguments.\n"); - return 1; - } - - if(strcasecmp(argv[0], "config")) { - argv--, argc++; - } - - int action = -2; - - if(!strcasecmp(argv[1], "get")) { - argv++, argc--; - } else if(!strcasecmp(argv[1], "add")) { - argv++, argc--, action = 1; - } else if(!strcasecmp(argv[1], "del")) { - argv++, argc--, action = -1; - } else if(!strcasecmp(argv[1], "replace") || !strcasecmp(argv[1], "set") || !strcasecmp(argv[1], "change")) { - argv++, argc--, action = 0; - } - - if(argc < 2) { - fprintf(stderr, "Invalid number of arguments.\n"); - return 1; - } - - // Concatenate the rest of the command line - strncpy(line, argv[1], sizeof(line) - 1); - - for(int i = 2; i < argc; i++) { - strncat(line, " ", sizeof(line) - 1 - strlen(line)); - strncat(line, argv[i], sizeof(line) - 1 - strlen(line)); - } - - // Liberal parsing into node name, variable name and value. - char *node = NULL; - char *variable; - char *value; - int len; - - len = strcspn(line, "\t ="); - value = line + len; - value += strspn(value, "\t "); - - if(*value == '=') { - value++; - value += strspn(value, "\t "); - } - - line[len] = '\0'; - variable = strchr(line, '.'); - - if(variable) { - node = line; - *variable++ = 0; - } else { - variable = line; - } - - if(!*variable) { - fprintf(stderr, "No variable given.\n"); - return 1; - } - - if(action >= 0 && !*value) { - fprintf(stderr, "No value for variable given.\n"); - return 1; - } - - if(action < -1 && *value) { - action = 0; - } - - /* Some simple checks. */ - bool found = false; - bool warnonremove = false; - - for(int i = 0; variables[i].name; i++) { - if(strcasecmp(variables[i].name, variable)) { - continue; - } - - found = true; - variable = (char *)variables[i].name; - - /* Discourage use of obsolete variables. */ - - if(variables[i].type & VAR_OBSOLETE && action >= 0) { - if(force) { - fprintf(stderr, "Warning: %s is an obsolete variable!\n", variable); - } else { - fprintf(stderr, "%s is an obsolete variable! Use --force to use it anyway.\n", variable); - return 1; - } - } - - /* Don't put server variables in host config files */ - - if(node && !(variables[i].type & VAR_HOST) && action >= 0) { - if(force) { - fprintf(stderr, "Warning: %s is not a host configuration variable!\n", variable); - } else { - fprintf(stderr, "%s is not a host configuration variable! Use --force to use it anyway.\n", variable); - return 1; - } - } - - /* Should this go into our own host config file? */ - - if(!node && !(variables[i].type & VAR_SERVER)) { - node = get_my_name(true); - - if(!node) { - return 1; - } - } - - /* Change "add" into "set" for variables that do not allow multiple occurrences. - Turn on warnings when it seems variables might be removed unintentionally. */ - - if(action == 1 && !(variables[i].type & VAR_MULTIPLE)) { - warnonremove = true; - action = 0; - } else if(action == 0 && (variables[i].type & VAR_MULTIPLE)) { - warnonremove = true; - } - - break; - } - - if(node && !check_id(node)) { - fprintf(stderr, "Invalid name for node.\n"); - return 1; - } - - if(!found) { - if(force || action < 0) { - fprintf(stderr, "Warning: %s is not a known configuration variable!\n", variable); - } else { - fprintf(stderr, "%s: is not a known configuration variable! Use --force to use it anyway.\n", variable); - return 1; - } - } - - // Open the right configuration file. - char filename[PATH_MAX]; - - if(node) { - snprintf(filename, sizeof(filename), "%s" SLASH "%s", hosts_dir, node); - } else { - snprintf(filename, sizeof(filename), "%s", tinc_conf); - } - - FILE *f = fopen(filename, "r"); - - if(!f) { - fprintf(stderr, "Could not open configuration file %s: %s\n", filename, strerror(errno)); - return 1; - } - - char tmpfile[PATH_MAX]; - FILE *tf = NULL; - - if(action >= -1) { - if((size_t)snprintf(tmpfile, sizeof(tmpfile), "%s.config.tmp", filename) >= sizeof(tmpfile)) { - fprintf(stderr, "Filename too long: %s.config.tmp\n", filename); - return 1; - } - - tf = fopen(tmpfile, "w"); - - if(!tf) { - fprintf(stderr, "Could not open temporary file %s: %s\n", tmpfile, strerror(errno)); - fclose(f); - return 1; - } - } - - // Copy the file, making modifications on the fly, unless we are just getting a value. - char buf1[4096]; - char buf2[4096]; - bool set = false; - bool removed = false; - found = false; - - while(fgets(buf1, sizeof(buf1), f)) { - buf1[sizeof(buf1) - 1] = 0; - strncpy(buf2, buf1, sizeof(buf2)); - - // Parse line in a simple way - char *bvalue; - int len; - - len = strcspn(buf2, "\t ="); - bvalue = buf2 + len; - bvalue += strspn(bvalue, "\t "); - - if(*bvalue == '=') { - bvalue++; - bvalue += strspn(bvalue, "\t "); - } - - rstrip(bvalue); - buf2[len] = '\0'; - - // Did it match? - if(!strcasecmp(buf2, variable)) { - // Get - if(action < -1) { - found = true; - printf("%s\n", bvalue); - // Del - } else if(action == -1) { - if(!*value || !strcasecmp(bvalue, value)) { - removed = true; - continue; - } - - // Set - } else if(action == 0) { - // Warn if "set" was used for variables that can occur multiple times - if(warnonremove && strcasecmp(bvalue, value)) { - fprintf(stderr, "Warning: removing %s = %s\n", variable, bvalue); - } - - // Already set? Delete the rest... - if(set) { - continue; - } - - // Otherwise, replace. - if(fprintf(tf, "%s = %s\n", variable, value) < 0) { - fprintf(stderr, "Error writing to temporary file %s: %s\n", tmpfile, strerror(errno)); - return 1; - } - - set = true; - continue; - // Add - } else if(action > 0) { - // Check if we've already seen this variable with the same value - if(!strcasecmp(bvalue, value)) { - found = true; - } - } - } - - if(action >= -1) { - // Copy original line... - if(fputs(buf1, tf) < 0) { - fprintf(stderr, "Error writing to temporary file %s: %s\n", tmpfile, strerror(errno)); - return 1; - } - - // Add newline if it is missing... - if(*buf1 && buf1[strlen(buf1) - 1] != '\n') { - if(fputc('\n', tf) < 0) { - fprintf(stderr, "Error writing to temporary file %s: %s\n", tmpfile, strerror(errno)); - return 1; - } - } - } - } - - // Make sure we read everything... - if(ferror(f) || !feof(f)) { - fprintf(stderr, "Error while reading from configuration file %s: %s\n", filename, strerror(errno)); - return 1; - } - - if(fclose(f)) { - fprintf(stderr, "Error closing configuration file %s: %s\n", filename, strerror(errno)); - return 1; - } - - // Add new variable if necessary. - if((action > 0 && !found) || (action == 0 && !set)) { - if(fprintf(tf, "%s = %s\n", variable, value) < 0) { - fprintf(stderr, "Error writing to temporary file %s: %s\n", tmpfile, strerror(errno)); - return 1; - } - } - - if(action < -1) { - if(found) { - return 0; - } else { - fprintf(stderr, "No matching configuration variables found.\n"); - return 1; - } - } - - // Make sure we wrote everything... - if(fclose(tf)) { - fprintf(stderr, "Error closing temporary file %s: %s\n", tmpfile, strerror(errno)); - return 1; - } - - // Could we find what we had to remove? - if(action < 0 && !removed) { - remove(tmpfile); - fprintf(stderr, "No configuration variables deleted.\n"); - return 1; - } - - // Replace the configuration file with the new one -#ifdef HAVE_MINGW - - if(remove(filename)) { - fprintf(stderr, "Error replacing file %s: %s\n", filename, strerror(errno)); - return 1; - } - -#endif - - if(rename(tmpfile, filename)) { - fprintf(stderr, "Error renaming temporary file %s to configuration file %s: %s\n", tmpfile, filename, strerror(errno)); - return 1; - } - - // Silently try notifying a running tincd of changes. - if(connect_tincd(false)) { - sendline(fd, "%d %d", CONTROL, REQ_RELOAD); - } - - return 0; -} - -static bool try_bind(int port) { - struct addrinfo *ai = NULL, *aip; - struct addrinfo hint = { - .ai_flags = AI_PASSIVE, - .ai_family = AF_UNSPEC, - .ai_socktype = SOCK_STREAM, - .ai_protocol = IPPROTO_TCP, - }; - - bool success = true; - char portstr[16]; - snprintf(portstr, sizeof(portstr), "%d", port); - - if(getaddrinfo(NULL, portstr, &hint, &ai) || !ai) { - return false; - } - - for(aip = ai; aip; aip = aip->ai_next) { - int fd = socket(ai->ai_family, SOCK_STREAM, IPPROTO_TCP); - - if(!fd) { - success = false; - break; - } - - int result = bind(fd, ai->ai_addr, ai->ai_addrlen); - closesocket(fd); - - if(result) { - success = false; - break; - } - } - - freeaddrinfo(ai); - return success; -} - -int check_port(const char *name) { - if(try_bind(655)) { - return 655; - } - - fprintf(stderr, "Warning: could not bind to port 655. "); - - for(int i = 0; i < 100; i++) { - int port = 0x1000 + (rand() & 0x7fff); - - if(try_bind(port)) { - char filename[PATH_MAX]; - snprintf(filename, sizeof(filename), "%s" SLASH "hosts" SLASH "%s", confbase, name); - FILE *f = fopen(filename, "a"); - - if(!f) { - fprintf(stderr, "Could not open %s: %s\n", filename, strerror(errno)); - fprintf(stderr, "Please change tinc's Port manually.\n"); - return 0; - } - - fprintf(f, "Port = %d\n", port); - fclose(f); - fprintf(stderr, "Tinc will instead listen on port %d.\n", port); - return port; - } - } - - fprintf(stderr, "Please change tinc's Port manually.\n"); - return 0; -} - -static int cmd_init(int argc, char *argv[]) { - if(!access(tinc_conf, F_OK)) { - fprintf(stderr, "Configuration file %s already exists!\n", tinc_conf); - return 1; - } - - if(argc > 2) { - fprintf(stderr, "Too many arguments!\n"); - return 1; - } else if(argc < 2) { - if(tty) { - char buf[1024]; - fprintf(stderr, "Enter the Name you want your tinc node to have: "); - - if(!fgets(buf, sizeof(buf), stdin)) { - fprintf(stderr, "Error while reading stdin: %s\n", strerror(errno)); - return 1; - } - - int len = rstrip(buf); - - if(!len) { - fprintf(stderr, "No name given!\n"); - return 1; - } - - name = strdup(buf); - } else { - fprintf(stderr, "No Name given!\n"); - return 1; - } - } else { - name = strdup(argv[1]); - - if(!*name) { - fprintf(stderr, "No Name given!\n"); - return 1; - } - } - - if(!check_id(name)) { - fprintf(stderr, "Invalid Name! Only a-z, A-Z, 0-9 and _ are allowed characters.\n"); - return 1; - } - - if(!confbase_given && mkdir(confdir, 0755) && errno != EEXIST) { - fprintf(stderr, "Could not create directory %s: %s\n", confdir, strerror(errno)); - return 1; - } - - if(mkdir(confbase, 0777) && errno != EEXIST) { - fprintf(stderr, "Could not create directory %s: %s\n", confbase, strerror(errno)); - return 1; - } - - if(mkdir(hosts_dir, 0777) && errno != EEXIST) { - fprintf(stderr, "Could not create directory %s: %s\n", hosts_dir, strerror(errno)); - return 1; - } - - FILE *f = fopen(tinc_conf, "w"); - - if(!f) { - fprintf(stderr, "Could not create file %s: %s\n", tinc_conf, strerror(errno)); - return 1; - } - - fprintf(f, "Name = %s\n", name); - fclose(f); - -#ifndef DISABLE_LEGACY - - if(!rsa_keygen(2048, false)) { - return 1; - } - -#endif - - if(!ed25519_keygen(false)) { - return 1; - } - - check_port(name); - -#ifndef HAVE_MINGW - char filename[PATH_MAX]; - snprintf(filename, sizeof(filename), "%s" SLASH "tinc-up", confbase); - - if(access(filename, F_OK)) { - FILE *f = fopenmask(filename, "w", 0777); - - if(!f) { - fprintf(stderr, "Could not create file %s: %s\n", filename, strerror(errno)); - return 1; - } - - fprintf(f, "#!/bin/sh\n\necho 'Unconfigured tinc-up script, please edit '$0'!'\n\n#ifconfig $INTERFACE netmask \n"); - fclose(f); - } - -#endif - - return 0; - -} - -static int cmd_generate_keys(int argc, char *argv[]) { -#ifdef DISABLE_LEGACY - - if(argc > 1) { -#else - - if(argc > 2) { -#endif - fprintf(stderr, "Too many arguments!\n"); - return 1; - } - - if(!name) { - name = get_my_name(false); - } - -#ifndef DISABLE_LEGACY - - if(!rsa_keygen(argc > 1 ? atoi(argv[1]) : 2048, true)) { - return 1; - } - -#endif - - if(!ed25519_keygen(true)) { - return 1; - } - - return 0; -} - -#ifndef DISABLE_LEGACY -static int cmd_generate_rsa_keys(int argc, char *argv[]) { - if(argc > 2) { - fprintf(stderr, "Too many arguments!\n"); - return 1; - } - - if(!name) { - name = get_my_name(false); - } - - return !rsa_keygen(argc > 1 ? atoi(argv[1]) : 2048, true); -} -#endif - -static int cmd_generate_ed25519_keys(int argc, char *argv[]) { - (void)argv; - - if(argc > 1) { - fprintf(stderr, "Too many arguments!\n"); - return 1; - } - - if(!name) { - name = get_my_name(false); - } - - return !ed25519_keygen(true); -} - -static int cmd_help(int argc, char *argv[]) { - (void)argc; - (void)argv; - - usage(false); - return 0; -} - -static int cmd_version(int argc, char *argv[]) { - (void)argv; - - if(argc > 1) { - fprintf(stderr, "Too many arguments!\n"); - return 1; - } - - version(); - return 0; -} - -static int cmd_info(int argc, char *argv[]) { - if(argc != 2) { - fprintf(stderr, "Invalid number of arguments.\n"); - return 1; - } - - if(!connect_tincd(true)) { - return 1; - } - - return info(fd, argv[1]); -} - -static const char *conffiles[] = { - "tinc.conf", - "tinc-up", - "tinc-down", - "subnet-up", - "subnet-down", - "host-up", - "host-down", - NULL, -}; - -static int cmd_edit(int argc, char *argv[]) { - if(argc != 2) { - fprintf(stderr, "Invalid number of arguments.\n"); - return 1; - } - - char filename[PATH_MAX] = ""; - - if(strncmp(argv[1], "hosts" SLASH, 6)) { - for(int i = 0; conffiles[i]; i++) { - if(!strcmp(argv[1], conffiles[i])) { - snprintf(filename, sizeof(filename), "%s" SLASH "%s", confbase, argv[1]); - break; - } - } - } else { - argv[1] += 6; - } - - if(!*filename) { - snprintf(filename, sizeof(filename), "%s" SLASH "%s", hosts_dir, argv[1]); - char *dash = strchr(argv[1], '-'); - - if(dash) { - *dash++ = 0; - - if((strcmp(dash, "up") && strcmp(dash, "down")) || !check_id(argv[1])) { - fprintf(stderr, "Invalid configuration filename.\n"); - return 1; - } - } - } - - char *command; -#ifndef HAVE_MINGW - const char *editor = getenv("VISUAL"); - if (!editor) - editor = getenv("EDITOR"); - if (!editor) - editor = "vi"; - - xasprintf(&command, "\"%s\" \"%s\"", editor, filename); -#else - xasprintf(&command, "edit \"%s\"", filename); -#endif - int result = system(command); - free(command); - - if(result) { - return result; - } - - // Silently try notifying a running tincd of changes. - if(connect_tincd(false)) { - sendline(fd, "%d %d", CONTROL, REQ_RELOAD); - } - - return 0; -} - -static int export(const char *name, FILE *out) { - char filename[PATH_MAX]; - snprintf(filename, sizeof(filename), "%s" SLASH "%s", hosts_dir, name); - FILE *in = fopen(filename, "r"); - - if(!in) { - fprintf(stderr, "Could not open configuration file %s: %s\n", filename, strerror(errno)); - return 1; - } - - fprintf(out, "Name = %s\n", name); - char buf[4096]; - - while(fgets(buf, sizeof(buf), in)) { - if(strcspn(buf, "\t =") != 4 || strncasecmp(buf, "Name", 4)) { - fputs(buf, out); - } - } - - if(ferror(in)) { - fprintf(stderr, "Error while reading configuration file %s: %s\n", filename, strerror(errno)); - fclose(in); - return 1; - } - - fclose(in); - return 0; -} - -static int cmd_export(int argc, char *argv[]) { - (void)argv; - - if(argc > 1) { - fprintf(stderr, "Too many arguments!\n"); - return 1; - } - - char *name = get_my_name(true); - - if(!name) { - return 1; - } - - int result = export(name, stdout); - - if(!tty) { - fclose(stdout); - } - - free(name); - return result; -} - -static int cmd_export_all(int argc, char *argv[]) { - (void)argv; - - if(argc > 1) { - fprintf(stderr, "Too many arguments!\n"); - return 1; - } - - DIR *dir = opendir(hosts_dir); - - if(!dir) { - fprintf(stderr, "Could not open host configuration directory %s: %s\n", hosts_dir, strerror(errno)); - return 1; - } - - bool first = true; - int result = 0; - struct dirent *ent; - - while((ent = readdir(dir))) { - if(!check_id(ent->d_name)) { - continue; - } - - if(first) { - first = false; - } else { - printf("#---------------------------------------------------------------#\n"); - } - - result |= export(ent->d_name, stdout); - } - - closedir(dir); - - if(!tty) { - fclose(stdout); - } - - return result; -} - -static int cmd_import(int argc, char *argv[]) { - (void)argv; - - if(argc > 1) { - fprintf(stderr, "Too many arguments!\n"); - return 1; - } - - FILE *in = stdin; - FILE *out = NULL; - - char buf[4096]; - char name[4096]; - char filename[PATH_MAX] = ""; - int count = 0; - bool firstline = true; - - while(fgets(buf, sizeof(buf), in)) { - if(sscanf(buf, "Name = %4095s", name) == 1) { - firstline = false; - - if(!check_id(name)) { - fprintf(stderr, "Invalid Name in input!\n"); - return 1; - } - - if(out) { - fclose(out); - } - - if((size_t)snprintf(filename, sizeof(filename), "%s" SLASH "%s", hosts_dir, name) >= sizeof(filename)) { - fprintf(stderr, "Filename too long: %s" SLASH "%s\n", hosts_dir, name); - return 1; - } - - if(!force && !access(filename, F_OK)) { - fprintf(stderr, "Host configuration file %s already exists, skipping.\n", filename); - out = NULL; - continue; - } - - out = fopen(filename, "w"); - - if(!out) { - fprintf(stderr, "Error creating configuration file %s: %s\n", filename, strerror(errno)); - return 1; - } - - count++; - continue; - } else if(firstline) { - fprintf(stderr, "Junk at the beginning of the input, ignoring.\n"); - firstline = false; - } - - - if(!strcmp(buf, "#---------------------------------------------------------------#\n")) { - continue; - } - - if(out) { - if(fputs(buf, out) < 0) { - fprintf(stderr, "Error writing to host configuration file %s: %s\n", filename, strerror(errno)); - return 1; - } - } - } - - if(out) { - fclose(out); - } - - if(count) { - fprintf(stderr, "Imported %d host configuration files.\n", count); - return 0; - } else { - fprintf(stderr, "No host configuration files imported.\n"); - return 1; - } -} - -static int cmd_exchange(int argc, char *argv[]) { - return cmd_export(argc, argv) ? 1 : cmd_import(argc, argv); -} - -static int cmd_exchange_all(int argc, char *argv[]) { - return cmd_export_all(argc, argv) ? 1 : cmd_import(argc, argv); -} - -static int switch_network(char *name) { - if(strcmp(name, ".")) { - if(!check_netname(name, false)) { - fprintf(stderr, "Invalid character in netname!\n"); - return 1; - } - - if(!check_netname(name, true)) { - fprintf(stderr, "Warning: unsafe character in netname!\n"); - } - } - - if(fd >= 0) { - close(fd); - fd = -1; - } - - free_names(); - netname = strcmp(name, ".") ? xstrdup(name) : NULL; - make_names(false); - - free(tinc_conf); - free(hosts_dir); - free(prompt); - - xasprintf(&tinc_conf, "%s" SLASH "tinc.conf", confbase); - xasprintf(&hosts_dir, "%s" SLASH "hosts", confbase); - xasprintf(&prompt, "%s> ", identname); - - return 0; -} - -static int cmd_network(int argc, char *argv[]) { - if(argc > 2) { - fprintf(stderr, "Too many arguments!\n"); - return 1; - } - - if(argc == 2) { - return switch_network(argv[1]); - } - - DIR *dir = opendir(confdir); - - if(!dir) { - fprintf(stderr, "Could not read directory %s: %s\n", confdir, strerror(errno)); - return 1; - } - - struct dirent *ent; - - while((ent = readdir(dir))) { - if(*ent->d_name == '.') { - continue; - } - - if(!strcmp(ent->d_name, "tinc.conf")) { - printf(".\n"); - continue; - } - - char fname[PATH_MAX]; - snprintf(fname, sizeof(fname), "%s/%s/tinc.conf", confdir, ent->d_name); - - if(!access(fname, R_OK)) { - printf("%s\n", ent->d_name); - } - } - - closedir(dir); - - return 0; -} - -static int cmd_fsck(int argc, char *argv[]) { - (void)argv; - - if(argc > 1) { - fprintf(stderr, "Too many arguments!\n"); - return 1; - } - - return fsck(orig_argv[0]); -} - -static void *readfile(FILE *in, size_t *len) { - size_t count = 0; - size_t bufsize = 4096; - char *buf = xmalloc(bufsize); - - while(!feof(in)) { - size_t read = fread(buf + count, 1, bufsize - count, in); - - if(!read) { - break; - } - - count += read; - - if(count >= bufsize) { - bufsize *= 2; - buf = xrealloc(buf, bufsize); - } - } - - if(len) { - *len = count; - } - - return buf; -} - -static int cmd_sign(int argc, char *argv[]) { - if(argc > 2) { - fprintf(stderr, "Too many arguments!\n"); - return 1; - } - - if(!name) { - name = get_my_name(true); - - if(!name) { - return 1; - } - } - - char fname[PATH_MAX]; - snprintf(fname, sizeof(fname), "%s" SLASH "ed25519_key.priv", confbase); - FILE *fp = fopen(fname, "r"); - - if(!fp) { - fprintf(stderr, "Could not open %s: %s\n", fname, strerror(errno)); - return 1; - } - - ecdsa_t *key = ecdsa_read_pem_private_key(fp); - - if(!key) { - fprintf(stderr, "Could not read private key from %s\n", fname); - fclose(fp); - return 1; - } - - fclose(fp); - - FILE *in; - - if(argc == 2) { - in = fopen(argv[1], "rb"); - - if(!in) { - fprintf(stderr, "Could not open %s: %s\n", argv[1], strerror(errno)); - ecdsa_free(key); - return 1; - } - } else { - in = stdin; - } - - size_t len; - char *data = readfile(in, &len); - - if(in != stdin) { - fclose(in); - } - - if(!data) { - fprintf(stderr, "Error reading %s: %s\n", argv[1], strerror(errno)); - ecdsa_free(key); - return 1; - } - - // Ensure we sign our name and current time as well - long t = time(NULL); - char *trailer; - xasprintf(&trailer, " %s %ld", name, t); - int trailer_len = strlen(trailer); - - data = xrealloc(data, len + trailer_len); - memcpy(data + len, trailer, trailer_len); - free(trailer); - - char sig[87]; - - if(!ecdsa_sign(key, data, len + trailer_len, sig)) { - fprintf(stderr, "Error generating signature\n"); - free(data); - ecdsa_free(key); - return 1; - } - - b64encode(sig, sig, 64); - ecdsa_free(key); - - fprintf(stdout, "Signature = %s %ld %s\n", name, t, sig); - fwrite(data, len, 1, stdout); - - free(data); - return 0; -} - -static int cmd_verify(int argc, char *argv[]) { - if(argc < 2) { - fprintf(stderr, "Not enough arguments!\n"); - return 1; - } - - if(argc > 3) { - fprintf(stderr, "Too many arguments!\n"); - return 1; - } - - char *node = argv[1]; - - if(!strcmp(node, ".")) { - if(!name) { - name = get_my_name(true); - - if(!name) { - return 1; - } - } - - node = name; - } else if(!strcmp(node, "*")) { - node = NULL; - } else { - if(!check_id(node)) { - fprintf(stderr, "Invalid node name\n"); - return 1; - } - } - - FILE *in; - - if(argc == 3) { - in = fopen(argv[2], "rb"); - - if(!in) { - fprintf(stderr, "Could not open %s: %s\n", argv[2], strerror(errno)); - return 1; - } - } else { - in = stdin; - } - - size_t len; - char *data = readfile(in, &len); - - if(in != stdin) { - fclose(in); - } - - if(!data) { - fprintf(stderr, "Error reading %s: %s\n", argv[1], strerror(errno)); - return 1; - } - - char *newline = memchr(data, '\n', len); - - if(!newline || (newline - data > MAX_STRING_SIZE - 1)) { - fprintf(stderr, "Invalid input\n"); - free(data); - return 1; - } - - *newline++ = '\0'; - size_t skip = newline - data; - - char signer[MAX_STRING_SIZE] = ""; - char sig[MAX_STRING_SIZE] = ""; - long t = 0; - - if(sscanf(data, "Signature = %s %ld %s", signer, &t, sig) != 3 || strlen(sig) != 86 || !t || !check_id(signer)) { - fprintf(stderr, "Invalid input\n"); - free(data); - return 1; - } - - if(node && strcmp(node, signer)) { - fprintf(stderr, "Signature is not made by %s\n", node); - free(data); - return 1; - } - - if(!node) { - node = signer; - } - - char *trailer; - xasprintf(&trailer, " %s %ld", signer, t); - int trailer_len = strlen(trailer); - - data = xrealloc(data, len + trailer_len); - memcpy(data + len, trailer, trailer_len); - free(trailer); - - newline = data + skip; - - char fname[PATH_MAX]; - snprintf(fname, sizeof(fname), "%s" SLASH "hosts" SLASH "%s", confbase, node); - FILE *fp = fopen(fname, "r"); - - if(!fp) { - fprintf(stderr, "Could not open %s: %s\n", fname, strerror(errno)); - free(data); - return 1; - } - - ecdsa_t *key = get_pubkey(fp); - - if(!key) { - rewind(fp); - key = ecdsa_read_pem_public_key(fp); - } - - if(!key) { - fprintf(stderr, "Could not read public key from %s\n", fname); - fclose(fp); - free(data); - return 1; - } - - fclose(fp); - - if(b64decode(sig, sig, 86) != 64 || !ecdsa_verify(key, newline, len + trailer_len - (newline - data), sig)) { - fprintf(stderr, "Invalid signature\n"); - free(data); - ecdsa_free(key); - return 1; - } - - ecdsa_free(key); - - fwrite(newline, len - (newline - data), 1, stdout); - - free(data); - return 0; -} - -static const struct { - const char *command; - int (*function)(int argc, char *argv[]); - bool hidden; -} commands[] = { - {"start", cmd_start, false}, - {"stop", cmd_stop, false}, - {"restart", cmd_restart, false}, - {"reload", cmd_reload, false}, - {"dump", cmd_dump, false}, - {"list", cmd_dump, false}, - {"purge", cmd_purge, false}, - {"debug", cmd_debug, false}, - {"retry", cmd_retry, false}, - {"connect", cmd_connect, false}, - {"disconnect", cmd_disconnect, false}, - {"top", cmd_top, false}, - {"pcap", cmd_pcap, false}, - {"log", cmd_log, false}, - {"pid", cmd_pid, false}, - {"config", cmd_config, true}, - {"add", cmd_config, false}, - {"del", cmd_config, false}, - {"get", cmd_config, false}, - {"set", cmd_config, false}, - {"init", cmd_init, false}, - {"generate-keys", cmd_generate_keys, false}, -#ifndef DISABLE_LEGACY - {"generate-rsa-keys", cmd_generate_rsa_keys, false}, -#endif - {"generate-ed25519-keys", cmd_generate_ed25519_keys, false}, - {"help", cmd_help, false}, - {"version", cmd_version, false}, - {"info", cmd_info, false}, - {"edit", cmd_edit, false}, - {"export", cmd_export, false}, - {"export-all", cmd_export_all, false}, - {"import", cmd_import, false}, - {"exchange", cmd_exchange, false}, - {"exchange-all", cmd_exchange_all, false}, - {"invite", cmd_invite, false}, - {"join", cmd_join, false}, - {"network", cmd_network, false}, - {"fsck", cmd_fsck, false}, - {"sign", cmd_sign, false}, - {"verify", cmd_verify, false}, - {NULL, NULL, false}, -}; - -#ifdef HAVE_READLINE -static char *complete_command(const char *text, int state) { - static int i; - - if(!state) { - i = 0; - } else { - i++; - } - - while(commands[i].command) { - if(!commands[i].hidden && !strncasecmp(commands[i].command, text, strlen(text))) { - return xstrdup(commands[i].command); - } - - i++; - } - - return NULL; -} - -static char *complete_dump(const char *text, int state) { - const char *matches[] = {"reachable", "nodes", "edges", "subnets", "connections", "graph", NULL}; - static int i; - - if(!state) { - i = 0; - } else { - i++; - } - - while(matches[i]) { - if(!strncasecmp(matches[i], text, strlen(text))) { - return xstrdup(matches[i]); - } - - i++; - } - - return NULL; -} - -static char *complete_config(const char *text, int state) { - static int i; - - if(!state) { - i = 0; - } else { - i++; - } - - while(variables[i].name) { - char *dot = strchr(text, '.'); - - if(dot) { - if((variables[i].type & VAR_HOST) && !strncasecmp(variables[i].name, dot + 1, strlen(dot + 1))) { - char *match; - xasprintf(&match, "%.*s.%s", (int)(dot - text), text, variables[i].name); - return match; - } - } else { - if(!strncasecmp(variables[i].name, text, strlen(text))) { - return xstrdup(variables[i].name); - } - } - - i++; - } - - return NULL; -} - -static char *complete_info(const char *text, int state) { - static int i; - - if(!state) { - i = 0; - - if(!connect_tincd(false)) { - return NULL; - } - - // Check the list of nodes - sendline(fd, "%d %d", CONTROL, REQ_DUMP_NODES); - sendline(fd, "%d %d", CONTROL, REQ_DUMP_SUBNETS); - } - - while(recvline(fd, line, sizeof(line))) { - char item[4096]; - int n = sscanf(line, "%d %d %4095s", &code, &req, item); - - if(n == 2) { - i++; - - if(i >= 2) { - break; - } else { - continue; - } - } - - if(n != 3) { - fprintf(stderr, "Unable to parse dump from tincd, n = %d, i = %d.\n", n, i); - break; - } - - if(!strncmp(item, text, strlen(text))) { - return xstrdup(strip_weight(item)); - } - } - - return NULL; -} - -static char *complete_nothing(const char *text, int state) { - (void)text; - (void)state; - return NULL; -} - -static char **completion(const char *text, int start, int end) { - (void)end; - char **matches = NULL; - - if(!start) { - matches = rl_completion_matches(text, complete_command); - } else if(!strncasecmp(rl_line_buffer, "dump ", 5)) { - matches = rl_completion_matches(text, complete_dump); - } else if(!strncasecmp(rl_line_buffer, "add ", 4)) { - matches = rl_completion_matches(text, complete_config); - } else if(!strncasecmp(rl_line_buffer, "del ", 4)) { - matches = rl_completion_matches(text, complete_config); - } else if(!strncasecmp(rl_line_buffer, "get ", 4)) { - matches = rl_completion_matches(text, complete_config); - } else if(!strncasecmp(rl_line_buffer, "set ", 4)) { - matches = rl_completion_matches(text, complete_config); - } else if(!strncasecmp(rl_line_buffer, "info ", 5)) { - matches = rl_completion_matches(text, complete_info); - } - - return matches; -} -#endif - -static int cmd_shell(int argc, char *argv[]) { - xasprintf(&prompt, "%s> ", identname); - int result = 0; - char buf[4096]; - char *line = NULL; - int maxargs = argc + 16; - char **nargv = xmalloc(maxargs * sizeof(*nargv)); - - for(int i = 0; i < argc; i++) { - nargv[i] = argv[i]; - } - -#ifdef HAVE_READLINE - rl_readline_name = "tinc"; - rl_completion_entry_function = complete_nothing; - rl_attempted_completion_function = completion; - rl_filename_completion_desired = 0; - char *copy = NULL; -#endif - - while(true) { -#ifdef HAVE_READLINE - - if(tty) { - free(copy); - free(line); - rl_basic_word_break_characters = "\t\n "; - line = readline(prompt); - copy = line ? xstrdup(line) : NULL; - } else { - line = fgets(buf, sizeof(buf), stdin); - } - -#else - - if(tty) { - fputs(prompt, stdout); - } - - line = fgets(buf, sizeof(buf), stdin); -#endif - - if(!line) { - break; - } - - /* Ignore comments */ - - if(*line == '#') { - continue; - } - - /* Split */ - - int nargc = argc; - char *p = line + strspn(line, " \t\n"); - char *next = strtok(p, " \t\n"); - - while(p && *p) { - if(nargc >= maxargs) { - maxargs *= 2; - nargv = xrealloc(nargv, maxargs * sizeof(*nargv)); - } - - nargv[nargc++] = p; - p = next; - next = strtok(NULL, " \t\n"); - } - - if(nargc == argc) { - continue; - } - - if(!strcasecmp(nargv[argc], "exit") || !strcasecmp(nargv[argc], "quit")) { -#ifdef HAVE_READLINE - free(copy); -#endif - free(nargv); - return result; - } - - bool found = false; - - for(int i = 0; commands[i].command; i++) { - if(!strcasecmp(nargv[argc], commands[i].command)) { - result |= commands[i].function(nargc - argc - 1, nargv + argc + 1); - found = true; - break; - } - } - -#ifdef HAVE_READLINE - - if(tty && found) { - add_history(copy); - } - -#endif - - if(!found) { - fprintf(stderr, "Unknown command `%s'.\n", nargv[argc]); - result |= 1; - } - } - -#ifdef HAVE_READLINE - free(copy); -#endif - free(nargv); - - if(tty) { - printf("\n"); - } - - return result; -} - - -int main(int argc, char *argv[]) { - program_name = argv[0]; - orig_argv = argv; - orig_argc = argc; - tty = isatty(0) && isatty(1); - - if(!parse_options(argc, argv)) { - return 1; - } - - make_names(false); - xasprintf(&tinc_conf, "%s" SLASH "tinc.conf", confbase); - xasprintf(&hosts_dir, "%s" SLASH "hosts", confbase); - - if(show_version) { - version(); - return 0; - } - - if(show_help) { - usage(false); - return 0; - } - -#ifdef HAVE_MINGW - static struct WSAData wsa_state; - - if(WSAStartup(MAKEWORD(2, 2), &wsa_state)) { - fprintf(stderr, "System call `%s' failed: %s\n", "WSAStartup", winerror(GetLastError())); - return false; - } - -#endif - - srand(time(NULL)); - crypto_init(); - - if(optind >= argc) { - return cmd_shell(argc, argv); - } - - for(int i = 0; commands[i].command; i++) { - if(!strcasecmp(argv[optind], commands[i].command)) { - return commands[i].function(argc - optind, argv + optind); - } - } - - fprintf(stderr, "Unknown command `%s'.\n", argv[optind]); - usage(true); - return 1; -} diff --git a/src/tincctl.h b/src/tincctl.h deleted file mode 100644 index 3f7d003..0000000 --- a/src/tincctl.h +++ /dev/null @@ -1,55 +0,0 @@ -#ifndef TINC_TINCCTL_H -#define TINC_TINCCTL_H - -/* - tincctl.h -- header for tincctl.c. - Copyright (C) 2011-2016 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 - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -extern bool tty; -extern bool force; -extern char line[4096]; -extern int fd; -extern char buffer[4096]; -extern size_t blen; -extern bool confbasegiven; -extern char *tinc_conf; -extern char *hosts_dir; - -#define VAR_SERVER 1 /* Should be in tinc.conf */ -#define VAR_HOST 2 /* Can be in host config file */ -#define VAR_MULTIPLE 4 /* Multiple statements allowed */ -#define VAR_OBSOLETE 8 /* Should not be used anymore */ -#define VAR_SAFE 16 /* Variable is safe when accepting invitations */ - -typedef struct { - const char *name; - int type; -} var_t; - -extern const var_t variables[]; - -extern int rstrip(char *value); -extern char *get_my_name(bool verbose); -extern bool connect_tincd(bool verbose); -extern bool sendline(int fd, char *format, ...); -extern bool recvline(int fd, char *line, size_t len); -extern int check_port(const char *name); -extern FILE *fopenmask(const char *filename, const char *mode, mode_t perms); -extern ecdsa_t *get_pubkey(FILE *f); - -#endif diff --git a/src/tincd.c b/src/tincd.c index dbf6bc8..066ad9c 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-2018 Guus Sliepen + 2000-2019 Guus Sliepen 2008 Max Rijevski 2009 Michael Tokarev 2010 Julien Muchembled @@ -33,6 +33,15 @@ #include #endif +#include +#include +#include +#include +#ifndef OPENSSL_NO_ENGINE +#include +#endif +#include + #ifdef HAVE_LZO #include LZO1X_H #endif @@ -43,66 +52,75 @@ #include #endif +#ifdef HAVE_GETOPT_LONG +#include +#else +#include "getopt.h" +#endif + +#include "pidfile.h" + #include "conf.h" -#include "control.h" -#include "crypto.h" #include "device.h" -#include "event.h" #include "logger.h" -#include "names.h" #include "net.h" #include "netutl.h" #include "process.h" #include "protocol.h" #include "utils.h" #include "xalloc.h" -#include "version.h" + +/* The name this program was run with. */ +char *program_name = NULL; /* If nonzero, display usage information and exit. */ -static bool show_help = false; +bool show_help = false; /* If nonzero, print the version on standard output and exit. */ -static bool show_version = false; +bool show_version = false; + +/* If nonzero, it will attempt to kill a running tincd and exit. */ +int kill_tincd = 0; + +/* If nonzero, generate public/private keypair for this host/net. */ +int generate_keys = 0; /* If nonzero, use null ciphers and skip all key exchanges. */ bool bypass_security = false; -#ifdef HAVE_MLOCKALL /* If nonzero, disable swapping for this process. */ -static bool do_mlock = false; -#endif +bool do_mlock = false; -#ifndef HAVE_MINGW /* If nonzero, chroot to netdir after startup. */ static bool do_chroot = false; /* If !NULL, do setuid to given user after startup */ static const char *switchuser = NULL; -#endif /* If nonzero, write log entries to a separate file. */ bool use_logfile = false; -/* If nonzero, use syslog instead of stderr in no-detach mode. */ -bool use_syslog = false; - -char **g_argv; /* a copy of the cmdline arguments */ +char *identname = NULL; /* program name for syslog */ +char *pidfilename = NULL; /* pid file location */ +char *logfilename = NULL; /* log file location */ +char **g_argv; /* a copy of the cmdline arguments */ static int status = 1; static struct option const long_options[] = { {"config", required_argument, NULL, 'c'}, + {"kill", optional_argument, NULL, 'k'}, {"net", required_argument, NULL, 'n'}, {"help", no_argument, NULL, 1}, {"version", no_argument, NULL, 2}, {"no-detach", no_argument, NULL, 'D'}, + {"generate-keys", optional_argument, NULL, 'K'}, {"debug", optional_argument, NULL, 'd'}, {"bypass-security", no_argument, NULL, 3}, {"mlock", no_argument, NULL, 'L'}, {"chroot", no_argument, NULL, 'R'}, {"user", required_argument, NULL, 'U'}, {"logfile", optional_argument, NULL, 4}, - {"syslog", no_argument, NULL, 's'}, {"pidfile", required_argument, NULL, 5}, {"option", required_argument, NULL, 'o'}, {NULL, 0, NULL, 0} @@ -110,6 +128,7 @@ static struct option const long_options[] = { #ifdef HAVE_MINGW static struct WSAData wsa_state; +CRITICAL_SECTION mutex; int main2(int argc, char **argv); #endif @@ -119,24 +138,20 @@ static void usage(bool status) { program_name); else { printf("Usage: %s [option]...\n\n", program_name); - printf(" -c, --config=DIR Read configuration options from DIR.\n" - " -D, --no-detach Don't fork and detach.\n" - " -d, --debug[=LEVEL] Increase debug level or set it to LEVEL.\n" - " -n, --net=NETNAME Connect to net NETNAME.\n" -#ifdef HAVE_MLOCKALL - " -L, --mlock Lock tinc into main memory.\n" -#endif - " --logfile[=FILENAME] Write log entries to a logfile.\n" - " -s --syslog Use syslog instead of stderr with --no-detach.\n" - " --pidfile=FILENAME Write PID and control socket cookie to FILENAME.\n" - " --bypass-security Disables meta protocol security, for debugging.\n" - " -o, --option[HOST.]KEY=VALUE Set global/host configuration value.\n" -#ifndef HAVE_MINGW - " -R, --chroot chroot to NET dir at startup.\n" - " -U, --user=USER setuid to given USER at startup.\n" -#endif - " --help Display this help and exit.\n" - " --version Output version information and exit.\n\n"); + printf(" -c, --config=DIR Read configuration options from DIR.\n" + " -D, --no-detach Don't fork and detach.\n" + " -d, --debug[=LEVEL] Increase debug level or set it to LEVEL.\n" + " -k, --kill[=SIGNAL] Attempt to kill a running tincd and exit.\n" + " -n, --net=NETNAME Connect to net NETNAME.\n" + " -K, --generate-keys[=BITS] Generate public/private RSA keypair.\n" + " -L, --mlock Lock tinc into main memory.\n" + " --logfile[=FILENAME] Write log entries to a logfile.\n" + " --pidfile=FILENAME Write PID to FILENAME.\n" + " -o, --option=[HOST.]KEY=VALUE Set global/host configuration value.\n" + " -R, --chroot chroot to NET dir at startup.\n" + " -U, --user=USER setuid to given USER at startup.\n" + " --help Display this help and exit.\n" + " --version Output version information and exit.\n\n"); printf("Report bugs to tinc@tinc-vpn.org.\n"); } } @@ -149,29 +164,35 @@ static bool parse_options(int argc, char **argv) { cmdline_conf = list_alloc((list_action_t)free_config); - while((r = getopt_long(argc, argv, "c:DLd::n:so:RU:", long_options, &option_index)) != EOF) { + while((r = getopt_long(argc, argv, "c:DLd::k::n:o:K::RU:", long_options, &option_index)) != EOF) { switch(r) { - case 0: /* long option */ + case 0: /* long option */ break; - case 'c': /* config file */ + case 'c': /* config file */ + if(confbase) { + fprintf(stderr, "Only one configuration directory can be given.\n"); + usage(true); + return false; + } + confbase = xstrdup(optarg); break; - case 'D': /* no detach */ + case 'D': /* no detach */ do_detach = false; break; - case 'L': /* no detach */ + case 'L': /* no detach */ #ifndef HAVE_MLOCKALL - logger(DEBUG_ALWAYS, LOG_ERR, "The %s option is not supported on this platform.", argv[optind - 1]); + logger(LOG_ERR, "%s not supported on this platform", "mlockall()"); return false; #else do_mlock = true; break; #endif - case 'd': /* increase debug level */ + case 'd': /* increase debug level */ if(!optarg && optind < argc && *argv[optind] != '-') { optarg = argv[optind++]; } @@ -184,16 +205,66 @@ static bool parse_options(int argc, char **argv) { break; - case 'n': /* net name given */ - netname = xstrdup(optarg); + case 'k': /* kill old tincds */ +#ifndef HAVE_MINGW + if(!optarg && optind < argc && *argv[optind] != '-') { + optarg = argv[optind++]; + } + + if(optarg) { + if(!strcasecmp(optarg, "HUP")) { + kill_tincd = SIGHUP; + } else if(!strcasecmp(optarg, "TERM")) { + kill_tincd = SIGTERM; + } else if(!strcasecmp(optarg, "KILL")) { + kill_tincd = SIGKILL; + } else if(!strcasecmp(optarg, "USR1")) { + kill_tincd = SIGUSR1; + } else if(!strcasecmp(optarg, "USR2")) { + kill_tincd = SIGUSR2; + } else if(!strcasecmp(optarg, "WINCH")) { + kill_tincd = SIGWINCH; + } else if(!strcasecmp(optarg, "INT")) { + kill_tincd = SIGINT; + } else if(!strcasecmp(optarg, "ALRM")) { + kill_tincd = SIGALRM; + } else if(!strcasecmp(optarg, "ABRT")) { + kill_tincd = SIGABRT; + } else { + kill_tincd = atoi(optarg); + + if(!kill_tincd) { + fprintf(stderr, "Invalid argument `%s'; SIGNAL must be a number or one of HUP, TERM, KILL, USR1, USR2, WINCH, INT or ALRM.\n", + optarg); + usage(true); + return false; + } + } + } else { + kill_tincd = SIGTERM; + } + +#else + kill_tincd = 1; +#endif break; - case 's': /* syslog */ - use_logfile = false; - use_syslog = true; + case 'n': /* net name given */ + + /* netname "." is special: a "top-level name" */ + if(netname) { + fprintf(stderr, "Only one netname can be given.\n"); + usage(true); + return false; + } + + if(optarg && strcmp(optarg, ".")) { + netname = xstrdup(optarg); + } + break; - case 'o': /* option */ + case 'o': /* option */ cfg = parse_config_line(optarg, NULL, ++lineno); if(!cfg) { @@ -203,37 +274,49 @@ static bool parse_options(int argc, char **argv) { list_insert_tail(cmdline_conf, cfg); break; -#ifdef HAVE_MINGW + case 'K': /* generate public/private keypair */ + if(!optarg && optind < argc && *argv[optind] != '-') { + optarg = argv[optind++]; + } - case 'R': - case 'U': - logger(DEBUG_ALWAYS, LOG_ERR, "The %s option is not supported on this platform.", argv[optind - 1]); - return false; -#else + if(optarg) { + generate_keys = atoi(optarg); - case 'R': /* chroot to NETNAME dir */ + if(generate_keys < 512) { + fprintf(stderr, "Invalid argument `%s'; BITS must be a number equal to or greater than 512.\n", + optarg); + usage(true); + return false; + } + + generate_keys &= ~7; /* Round it to bytes */ + } else { + generate_keys = 2048; + } + + break; + + case 'R': /* chroot to NETNAME dir */ do_chroot = true; break; - case 'U': /* setuid to USER */ + case 'U': /* setuid to USER */ switchuser = optarg; break; -#endif - case 1: /* show help */ + case 1: /* show help */ show_help = true; break; - case 2: /* show version */ + case 2: /* show version */ show_version = true; break; - case 3: /* bypass security */ + case 3: /* bypass security */ bypass_security = true; break; - case 4: /* write log entries to a file */ - use_syslog = false; + case 4: /* write log entries to a file */ use_logfile = true; if(!optarg && optind < argc && *argv[optind] != '-') { @@ -241,16 +324,28 @@ static bool parse_options(int argc, char **argv) { } if(optarg) { + if(logfilename) { + fprintf(stderr, "Only one logfile can be given.\n"); + usage(true); + return false; + } + logfilename = xstrdup(optarg); } break; - case 5: /* open control socket here */ + case 5: /* write PID to a file */ + if(pidfilename) { + fprintf(stderr, "Only one pidfile can be given.\n"); + usage(true); + return false; + } + pidfilename = xstrdup(optarg); break; - case '?': /* wrong options */ + case '?': usage(true); return false; @@ -265,38 +360,239 @@ static bool parse_options(int argc, char **argv) { return false; } - if(!netname && (netname = getenv("NETNAME"))) { - netname = xstrdup(netname); + return true; +} + +/* This function prettyprints the key generation process */ + +static int indicator(int a, int b, BN_GENCB *cb) { + (void)cb; + + switch(a) { + case 0: + fprintf(stderr, "."); + break; + + case 1: + fprintf(stderr, "+"); + break; + + case 2: + fprintf(stderr, "-"); + break; + + case 3: + switch(b) { + case 0: + fprintf(stderr, " p\n"); + break; + + case 1: + fprintf(stderr, " q\n"); + break; + + default: + fprintf(stderr, "?"); + } + + break; + + default: + fprintf(stderr, "?"); } - /* netname "." is special: a "top-level name" */ + return 1; +} - if(netname && (!*netname || !strcmp(netname, "."))) { - free(netname); - netname = NULL; +#ifndef HAVE_BN_GENCB_NEW +BN_GENCB *BN_GENCB_new(void) { + return xmalloc_and_zero(sizeof(BN_GENCB)); +} + +void BN_GENCB_free(BN_GENCB *cb) { + free(cb); +} +#endif + +/* + Generate a public/private RSA keypair, and ask for a file to store + them in. +*/ +static bool keygen(int bits) { + BIGNUM *e = NULL; + RSA *rsa_key; + FILE *f; + char filename[PATH_MAX]; + BN_GENCB *cb; + int result; + + fprintf(stderr, "Generating %d bits keys:\n", bits); + + cb = BN_GENCB_new(); + + if(!cb) { + abort(); } - if(netname && !check_netname(netname, false)) { - fprintf(stderr, "Invalid character in netname!\n"); + BN_GENCB_set(cb, indicator, NULL); + + rsa_key = RSA_new(); + + if(BN_hex2bn(&e, "10001") == 0) { + abort(); + } + + if(!rsa_key || !e) { + abort(); + } + + result = RSA_generate_key_ex(rsa_key, bits, e, cb); + + BN_free(e); + BN_GENCB_free(cb); + + if(!result) { + fprintf(stderr, "Error during key generation!\n"); + RSA_free(rsa_key); + return false; + } else { + fprintf(stderr, "Done.\n"); + } + + snprintf(filename, sizeof(filename), "%s/rsa_key.priv", confbase); + f = ask_and_open(filename, "private RSA key"); + + if(!f) { + RSA_free(rsa_key); return false; } - if(netname && !check_netname(netname, true)) { - fprintf(stderr, "Warning: unsafe character in netname!\n"); +#ifdef HAVE_FCHMOD + /* Make it unreadable for others. */ + fchmod(fileno(f), 0600); +#endif + + fputc('\n', f); + PEM_write_RSAPrivateKey(f, rsa_key, NULL, NULL, 0, NULL, NULL); + fclose(f); + + char *name = get_name(); + + if(name) { + snprintf(filename, sizeof(filename), "%s/hosts/%s", confbase, name); + free(name); + } else { + snprintf(filename, sizeof(filename), "%s/rsa_key.pub", confbase); } + f = ask_and_open(filename, "public RSA key"); + + if(!f) { + RSA_free(rsa_key); + return false; + } + + fputc('\n', f); + PEM_write_RSAPublicKey(f, rsa_key); + fclose(f); + + RSA_free(rsa_key); + return true; } -static bool drop_privs(void) { -#ifndef HAVE_MINGW +/* + Set all files and paths according to netname +*/ +static void make_names(void) { +#ifdef HAVE_MINGW + HKEY key; + char installdir[1024] = ""; + DWORD len = sizeof(installdir); +#endif + + if(netname) { + xasprintf(&identname, "tinc.%s", netname); + } else { + identname = xstrdup("tinc"); + } + +#ifdef HAVE_MINGW + + if(!RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\tinc", 0, KEY_READ, &key)) { + if(!RegQueryValueEx(key, NULL, 0, 0, (LPBYTE)installdir, &len)) { + if(!confbase) { + if(netname) { + xasprintf(&confbase, "%s/%s", installdir, netname); + } else { + xasprintf(&confbase, "%s", installdir); + } + } + + if(!logfilename) { + xasprintf(&logfilename, "%s/tinc.log", confbase); + } + } + + RegCloseKey(key); + + if(*installdir) { + return; + } + } + +#endif + + if(!pidfilename) { + xasprintf(&pidfilename, RUNSTATEDIR "/%s.pid", identname); + } + + if(!logfilename) { + xasprintf(&logfilename, LOCALSTATEDIR "/log/%s.log", identname); + } + + if(netname) { + if(!confbase) { + xasprintf(&confbase, CONFDIR "/tinc/%s", netname); + } else { + logger(LOG_INFO, "Both netname and configuration directory given, using the latter..."); + } + } else { + if(!confbase) { + xasprintf(&confbase, CONFDIR "/tinc"); + } + } +} + +static void free_names() { + free(identname); + free(netname); + free(pidfilename); + free(logfilename); + free(confbase); +} + +static bool drop_privs() { +#ifdef HAVE_MINGW + + if(switchuser) { + logger(LOG_ERR, "%s not supported on this platform", "-U"); + return false; + } + + if(do_chroot) { + logger(LOG_ERR, "%s not supported on this platform", "-R"); + return false; + } + +#else uid_t uid = 0; if(switchuser) { struct passwd *pw = getpwnam(switchuser); if(!pw) { - logger(DEBUG_ALWAYS, LOG_ERR, "unknown user `%s'", switchuser); + logger(LOG_ERR, "unknown user `%s'", switchuser); return false; } @@ -304,12 +600,12 @@ static bool drop_privs(void) { if(initgroups(switchuser, pw->pw_gid) != 0 || setgid(pw->pw_gid) != 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", + logger(LOG_ERR, "System call `%s' failed: %s", "initgroups", strerror(errno)); return false; } -#ifndef __ANDROID__ +#ifndef ANDROID // Not supported in android NDK endgrent(); endpwent(); @@ -320,7 +616,7 @@ static bool drop_privs(void) { tzset(); /* for proper timestamps in logs */ if(chroot(confbase) != 0 || chdir("/") != 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", + logger(LOG_ERR, "System call `%s' failed: %s", "chroot", strerror(errno)); return false; } @@ -331,7 +627,7 @@ static bool drop_privs(void) { if(switchuser) if(setuid(uid) != 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", + logger(LOG_ERR, "System call `%s' failed: %s", "setuid", strerror(errno)); return false; } @@ -342,20 +638,6 @@ static bool drop_privs(void) { #ifdef HAVE_MINGW # define setpriority(level) !SetPriorityClass(GetCurrentProcess(), (level)) - -static void stop_handler(void *data, int flags) { - event_exit(); -} - -static BOOL WINAPI console_ctrl_handler(DWORD type) { - logger(DEBUG_ALWAYS, LOG_NOTICE, "Got console shutdown request"); - - if(WSASetEvent(stop_io.event) == FALSE) { - abort(); - } - - return TRUE; -} #else # define NORMAL_PRIORITY_CLASS 0 # define BELOW_NORMAL_PRIORITY_CLASS 10 @@ -371,9 +653,8 @@ int main(int argc, char **argv) { } if(show_version) { - printf("%s version %s (built %s %s, protocol %d.%d)\n", PACKAGE, - BUILD_VERSION, BUILD_DATE, BUILD_TIME, PROT_MAJOR, PROT_MINOR); - printf("Copyright (C) 1998-2018 Ivo Timmermans, Guus Sliepen and others.\n" + printf("%s version %s\n", PACKAGE, VERSION); + printf("Copyright (C) 1998-2019 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" @@ -387,38 +668,12 @@ int main(int argc, char **argv) { return 0; } - make_names(true); - chdir(confbase); + make_names(); -#ifdef HAVE_MINGW - - if(WSAStartup(MAKEWORD(2, 2), &wsa_state)) { - logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "WSAStartup", winerror(GetLastError())); - return 1; + if(kill_tincd) { + return !kill_other(kill_tincd); } -#else - // Check if we got an umbilical fd from the process that started us - char *umbstr = getenv("TINC_UMBILICAL"); - - if(umbstr) { - umbilical = atoi(umbstr); - - if(fcntl(umbilical, F_GETFL) < 0) { - umbilical = 0; - } - -#ifdef FD_CLOEXEC - - if(umbilical) { - fcntl(umbilical, F_SETFD, FD_CLOEXEC); - } - -#endif - } - -#endif - openlogger("tinc", use_logfile ? LOGMODE_FILE : LOGMODE_STDERR); g_argv = argv; @@ -433,54 +688,50 @@ int main(int argc, char **argv) { init_configuration(&config_tree); - /* Slllluuuuuuurrrrp! */ +#ifndef OPENSSL_NO_ENGINE + ENGINE_load_builtin_engines(); + ENGINE_register_all_complete(); +#endif - gettimeofday(&now, NULL); - srand(now.tv_sec + now.tv_usec); - crypto_init(); +#if OPENSSL_VERSION_NUMBER < 0x10100000L + OpenSSL_add_all_algorithms(); +#endif + + if(generate_keys) { + read_server_config(); + return !keygen(generate_keys); + } if(!read_server_config()) { return 1; } - if(!debug_level) { - get_config_int(lookup_config(config_tree, "LogLevel"), &debug_level); - } - #ifdef HAVE_LZO if(lzo_init() != LZO_E_OK) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error initializing LZO compressor!"); + logger(LOG_ERR, "Error initializing LZO compressor!"); return 1; } #endif #ifdef HAVE_MINGW - io_add_event(&stop_io, stop_handler, NULL, WSACreateEvent()); - if(stop_io.event == FALSE) { - abort(); + if(WSAStartup(MAKEWORD(2, 2), &wsa_state)) { + logger(LOG_ERR, "System call `%s' failed: %s", "WSAStartup", winerror(GetLastError())); + return 1; } - int result; - if(!do_detach || !init_service()) { - SetConsoleCtrlHandler(console_ctrl_handler, TRUE); - result = main2(argc, argv); + return main2(argc, argv); } else { - result = 1; + return 1; } - - if(WSACloseEvent(stop_io.event) == FALSE) { - abort(); - } - - io_del(&stop_io); - return result; } int main2(int argc, char **argv) { + InitializeCriticalSection(&mutex); + EnterCriticalSection(&mutex); #endif char *priority = NULL; @@ -494,7 +745,7 @@ int main2(int argc, char **argv) { * This has to be done after daemon()/fork() so it works for child. * No need to do that in parent as it's very short-lived. */ if(do_mlock && mlockall(MCL_CURRENT | MCL_FUTURE) != 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "mlockall", + logger(LOG_ERR, "System call `%s' failed: %s", "mlockall", strerror(errno)); return 1; } @@ -507,26 +758,33 @@ int main2(int argc, char **argv) { goto end; } + /* Initiate all outgoing connections. */ + + try_outgoing_connections(); + /* Change process priority */ if(get_config_string(lookup_config(config_tree, "ProcessPriority"), &priority)) { if(!strcasecmp(priority, "Normal")) { if(setpriority(NORMAL_PRIORITY_CLASS) != 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "setpriority", strerror(errno)); + logger(LOG_ERR, "System call `%s' failed: %s", + "setpriority", strerror(errno)); goto end; } } else if(!strcasecmp(priority, "Low")) { if(setpriority(BELOW_NORMAL_PRIORITY_CLASS) != 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "setpriority", strerror(errno)); + logger(LOG_ERR, "System call `%s' failed: %s", + "setpriority", strerror(errno)); goto end; } } else if(!strcasecmp(priority, "High")) { if(setpriority(HIGH_PRIORITY_CLASS) != 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "setpriority", strerror(errno)); + logger(LOG_ERR, "System call `%s' failed: %s", + "setpriority", strerror(errno)); goto end; } } else { - logger(DEBUG_ALWAYS, LOG_ERR, "Invalid priority `%s`!", priority); + logger(LOG_ERR, "Invalid priority `%s`!", priority); goto end; } } @@ -538,31 +796,34 @@ int main2(int argc, char **argv) { /* Start main loop. It only exits when tinc is killed. */ - logger(DEBUG_ALWAYS, LOG_NOTICE, "Ready"); - - if(umbilical) { // snip! - write(umbilical, "", 1); - close(umbilical); - umbilical = 0; - } - - try_outgoing_connections(); - status = main_loop(); /* Shutdown properly. */ -end: + ifdebug(CONNECTIONS) + devops.dump_stats(); + close_network_connections(); - logger(DEBUG_ALWAYS, LOG_NOTICE, "Terminating"); +end: + logger(LOG_NOTICE, "Terminating"); + +#ifndef HAVE_MINGW + remove_pid(pidfilename); +#endif free(priority); - crypto_exit(); +#if OPENSSL_VERSION_NUMBER < 0x10100000L + EVP_cleanup(); + ERR_free_strings(); +#ifndef OPENSSL_NO_ENGINE + ENGINE_cleanup(); +#endif +#endif exit_configuration(&config_tree); - free(cmdline_conf); + list_delete_list(cmdline_conf); free_names(); return status; diff --git a/src/top.c b/src/top.c deleted file mode 100644 index ab14619..0000000 --- a/src/top.c +++ /dev/null @@ -1,396 +0,0 @@ -/* - top.c -- Show real-time statistics from a running tincd - Copyright (C) 2011-2013 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 - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include "system.h" - -#ifdef HAVE_CURSES - -#undef KEY_EVENT /* There are conflicting declarations for KEY_EVENT in Windows wincon.h and curses.h. */ -#include - -#include "control_common.h" -#include "list.h" -#include "names.h" -#include "tincctl.h" -#include "top.h" -#include "xalloc.h" - -typedef struct nodestats_t { - char *name; - int i; - uint64_t in_packets; - uint64_t in_bytes; - uint64_t out_packets; - uint64_t out_bytes; - float in_packets_rate; - float in_bytes_rate; - float out_packets_rate; - float out_bytes_rate; - bool known; -} nodestats_t; - -static const char *const sortname[] = { - "name", - "in pkts", - "in bytes", - "out pkts", - "out bytes", - "tot pkts", - "tot bytes", -}; - -static int sortmode = 0; -static bool cumulative = false; - -static list_t node_list; -static struct timeval cur, prev, diff; -static int delay = 1000; -static bool changed = true; -static const char *bunit = "bytes"; -static float bscale = 1; -static const char *punit = "pkts"; -static float pscale = 1; - -static bool update(int fd) { - if(!sendline(fd, "%d %d", CONTROL, REQ_DUMP_TRAFFIC)) { - return false; - } - - gettimeofday(&cur, NULL); - - timersub(&cur, &prev, &diff); - prev = cur; - float interval = diff.tv_sec + diff.tv_usec * 1e-6; - - char line[4096]; - char name[4096]; - int code; - int req; - uint64_t in_packets; - uint64_t in_bytes; - uint64_t out_packets; - uint64_t out_bytes; - - for list_each(nodestats_t, ns, &node_list) { - ns->known = false; - } - - while(recvline(fd, line, sizeof(line))) { - int n = sscanf(line, "%d %d %4095s %"PRIu64" %"PRIu64" %"PRIu64" %"PRIu64, &code, &req, name, &in_packets, &in_bytes, &out_packets, &out_bytes); - - if(n == 2) { - return true; - } - - if(n != 7) { - return false; - } - - nodestats_t *found = NULL; - - for list_each(nodestats_t, ns, &node_list) { - int result = strcmp(name, ns->name); - - if(result > 0) { - continue; - } - - if(result == 0) { - found = ns; - break; - } else { - found = xzalloc(sizeof(*found)); - found->name = xstrdup(name); - list_insert_before(&node_list, node, found); - changed = true; - break; - } - } - - if(!found) { - found = xzalloc(sizeof(*found)); - found->name = xstrdup(name); - list_insert_tail(&node_list, found); - changed = true; - } - - found->known = true; - found->in_packets_rate = (in_packets - found->in_packets) / interval; - found->in_bytes_rate = (in_bytes - found->in_bytes) / interval; - found->out_packets_rate = (out_packets - found->out_packets) / interval; - found->out_bytes_rate = (out_bytes - found->out_bytes) / interval; - found->in_packets = in_packets; - found->in_bytes = in_bytes; - found->out_packets = out_packets; - found->out_bytes = out_bytes; - } - - return false; -} - -static int cmpfloat(float a, float b) { - if(a < b) { - return -1; - } else if(a > b) { - return 1; - } else { - return 0; - } -} - -static int cmpu64(uint64_t a, uint64_t b) { - if(a < b) { - return -1; - } else if(a > b) { - return 1; - } else { - return 0; - } -} - -static int sortfunc(const void *a, const void *b) { - const nodestats_t *na = *(const nodestats_t **)a; - const nodestats_t *nb = *(const nodestats_t **)b; - int result; - - switch(sortmode) { - case 1: - if(cumulative) { - result = -cmpu64(na->in_packets, nb->in_packets); - } else { - result = -cmpfloat(na->in_packets_rate, nb->in_packets_rate); - } - - break; - - case 2: - if(cumulative) { - result = -cmpu64(na->in_bytes, nb->in_bytes); - } else { - result = -cmpfloat(na->in_bytes_rate, nb->in_bytes_rate); - } - - break; - - case 3: - if(cumulative) { - result = -cmpu64(na->out_packets, nb->out_packets); - } else { - result = -cmpfloat(na->out_packets_rate, nb->out_packets_rate); - } - - break; - - case 4: - if(cumulative) { - result = -cmpu64(na->out_bytes, nb->out_bytes); - } else { - result = -cmpfloat(na->out_bytes_rate, nb->out_bytes_rate); - } - - break; - - case 5: - if(cumulative) { - result = -cmpu64(na->in_packets + na->out_packets, nb->in_packets + nb->out_packets); - } else { - result = -cmpfloat(na->in_packets_rate + na->out_packets_rate, nb->in_packets_rate + nb->out_packets_rate); - } - - break; - - case 6: - if(cumulative) { - result = -cmpu64(na->in_bytes + na->out_bytes, nb->in_bytes + nb->out_bytes); - } else { - result = -cmpfloat(na->in_bytes_rate + na->out_bytes_rate, nb->in_bytes_rate + nb->out_bytes_rate); - } - - break; - - default: - result = strcmp(na->name, nb->name); - break; - } - - if(result) { - return result; - } else { - return na->i - nb->i; - } -} - -static void redraw(void) { - erase(); - - mvprintw(0, 0, "Tinc %-16s Nodes: %4d Sort: %-10s %s", netname ? netname : "", node_list.count, sortname[sortmode], cumulative ? "Cumulative" : "Current"); - attrset(A_REVERSE); - mvprintw(2, 0, "Node IN %s IN %s OUT %s OUT %s", punit, bunit, punit, bunit); - chgat(-1, A_REVERSE, 0, NULL); - - static nodestats_t **sorted = 0; - static int n = 0; - - if(changed) { - n = 0; - sorted = xrealloc(sorted, node_list.count * sizeof(*sorted)); - - for list_each(nodestats_t, ns, &node_list) { - sorted[n++] = ns; - } - - changed = false; - } - - for(int i = 0; i < n; i++) { - sorted[i]->i = i; - } - - if(sorted) { - qsort(sorted, n, sizeof(*sorted), sortfunc); - } - - for(int i = 0, row = 3; i < n; i++, row++) { - nodestats_t *node = sorted[i]; - - if(node->known) - if(node->in_packets_rate || node->out_packets_rate) { - attrset(A_BOLD); - } else { - attrset(A_NORMAL); - } else { - attrset(A_DIM); - } - - if(cumulative) - mvprintw(row, 0, "%-16s %10.0f %10.0f %10.0f %10.0f", - node->name, node->in_packets * pscale, node->in_bytes * bscale, node->out_packets * pscale, node->out_bytes * bscale); - else - mvprintw(row, 0, "%-16s %10.0f %10.0f %10.0f %10.0f", - node->name, node->in_packets_rate * pscale, node->in_bytes_rate * bscale, node->out_packets_rate * pscale, node->out_bytes_rate * bscale); - } - - attrset(A_NORMAL); - move(1, 0); - - refresh(); -} - -void top(int fd) { - initscr(); - timeout(delay); - bool running = true; - - while(running) { - if(!update(fd)) { - break; - } - - redraw(); - - switch(getch()) { - case 's': { - timeout(-1); - float input = delay * 1e-3; - mvprintw(1, 0, "Change delay from %.1fs to: ", input); - scanw("%f", &input); - - if(input < 0.1) { - input = 0.1; - } - - delay = input * 1e3; - timeout(delay); - break; - } - - case 'c': - cumulative = !cumulative; - break; - - case 'n': - sortmode = 0; - break; - - case 'i': - sortmode = 2; - break; - - case 'I': - sortmode = 1; - break; - - case 'o': - sortmode = 4; - break; - - case 'O': - sortmode = 3; - break; - - case 't': - sortmode = 6; - break; - - case 'T': - sortmode = 5; - break; - - case 'b': - bunit = "bytes"; - bscale = 1; - punit = "pkts"; - pscale = 1; - break; - - case 'k': - bunit = "kbyte"; - bscale = 1e-3; - punit = "pkts"; - pscale = 1; - break; - - case 'M': - bunit = "Mbyte"; - bscale = 1e-6; - punit = "kpkt"; - pscale = 1e-3; - break; - - case 'G': - bunit = "Gbyte"; - bscale = 1e-9; - punit = "Mpkt"; - pscale = 1e-6; - break; - - case 'q': - case KEY_BREAK: - running = false; - break; - - default: - break; - } - } - - endwin(); -} - -#endif diff --git a/src/top.h b/src/top.h deleted file mode 100644 index 612d0d8..0000000 --- a/src/top.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef TINC_TOP_H -#define TINC_TOP_H - -/* - top.h -- header for top.c. - Copyright (C) 2011 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 - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -extern void top(int fd); - -#endif diff --git a/src/uml_device.c b/src/uml_device.c index a675b62..66de431 100644 --- a/src/uml_device.c +++ b/src/uml_device.c @@ -1,7 +1,7 @@ /* device.c -- UML network socket Copyright (C) 2002-2005 Ivo Timmermans, - 2002-2017 Guus Sliepen + 2002-2012 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 @@ -24,7 +24,6 @@ #include "conf.h" #include "device.h" -#include "names.h" #include "net.h" #include "logger.h" #include "utils.h" @@ -38,6 +37,12 @@ static int write_fd = -1; static int state = 0; static const char *device_info = "UML network socket"; +extern char *identname; +extern volatile bool running; + +static uint64_t device_total_in = 0; +static uint64_t device_total_out = 0; + enum request_type { REQ_NEW_CONTROL }; static struct request { @@ -66,8 +71,8 @@ static bool setup_device(void) { get_config_string(lookup_config(config_tree, "Interface"), &iface); if((write_fd = socket(PF_UNIX, SOCK_DGRAM, 0)) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not open write %s: %s", device_info, strerror(errno)); - event_exit(); + logger(LOG_ERR, "Could not open write %s: %s", device_info, strerror(errno)); + running = false; return false; } @@ -78,14 +83,14 @@ static bool setup_device(void) { setsockopt(write_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)); if(fcntl(write_fd, F_SETFL, O_NONBLOCK) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "fcntl", strerror(errno)); - event_exit(); + logger(LOG_ERR, "System call `%s' failed: %s", "fcntl", strerror(errno)); + running = false; return false; } if((data_fd = socket(PF_UNIX, SOCK_DGRAM, 0)) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not open data %s: %s", device_info, strerror(errno)); - event_exit(); + logger(LOG_ERR, "Could not open data %s: %s", device_info, strerror(errno)); + running = false; return false; } @@ -96,8 +101,8 @@ static bool setup_device(void) { setsockopt(data_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)); if(fcntl(data_fd, F_SETFL, O_NONBLOCK) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "fcntl", strerror(errno)); - event_exit(); + logger(LOG_ERR, "System call `%s' failed: %s", "fcntl", strerror(errno)); + running = false; return false; } @@ -109,13 +114,13 @@ static bool setup_device(void) { memcpy(&data_sun.sun_path, &name, sizeof(name)); if(bind(data_fd, (struct sockaddr *)&data_sun, sizeof(data_sun)) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not bind data %s: %s", device_info, strerror(errno)); - event_exit(); + logger(LOG_ERR, "Could not bind data %s: %s", device_info, strerror(errno)); + running = false; return false; } if((listen_fd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not open %s: %s", device_info, + logger(LOG_ERR, "Could not open %s: %s", device_info, strerror(errno)); return false; } @@ -127,28 +132,27 @@ static bool setup_device(void) { setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)); if(fcntl(listen_fd, F_SETFL, O_NONBLOCK) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "fcntl", strerror(errno)); + logger(LOG_ERR, "System call `%s' failed: %s", "fcntl", strerror(errno)); return false; } listen_sun.sun_family = AF_UNIX; strncpy(listen_sun.sun_path, device, sizeof(listen_sun.sun_path)); - listen_sun.sun_path[sizeof(listen_sun.sun_path) - 1] = 0; if(bind(listen_fd, (struct sockaddr *)&listen_sun, sizeof(listen_sun)) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not bind %s to %s: %s", device_info, device, strerror(errno)); + logger(LOG_ERR, "Could not bind %s to %s: %s", device_info, device, strerror(errno)); return false; } if(listen(listen_fd, 1) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not listen on %s %s: %s", device_info, device, strerror(errno)); + logger(LOG_ERR, "Could not listen on %s %s: %s", device_info, device, strerror(errno)); return false; } device_fd = listen_fd; state = 0; - logger(DEBUG_ALWAYS, LOG_INFO, "%s is a %s", device, device_info); + logger(LOG_INFO, "%s is a %s", device, device_info); if(routing_mode == RMODE_ROUTER) { overwrite_mac = true; @@ -160,37 +164,28 @@ static bool setup_device(void) { void close_device(void) { if(listen_fd >= 0) { close(listen_fd); - listen_fd = -1; } if(request_fd >= 0) { close(request_fd); - request_fd = -1; } if(data_fd >= 0) { close(data_fd); - data_fd = -1; } if(write_fd >= 0) { close(write_fd); - write_fd = -1; } unlink(device); free(device); - device = NULL; - free(iface); - iface = NULL; - - device_info = NULL; } static bool read_packet(vpn_packet_t *packet) { - int inlen; + int lenin; switch(state) { case 0: { @@ -200,7 +195,7 @@ static bool read_packet(vpn_packet_t *packet) { request_fd = accept(listen_fd, &sa, &salen); if(request_fd < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not accept connection to %s %s: %s", device_info, device, strerror(errno)); + logger(LOG_ERR, "Could not accept connection to %s %s: %s", device_info, device, strerror(errno)); return false; } @@ -209,8 +204,8 @@ static bool read_packet(vpn_packet_t *packet) { #endif if(fcntl(listen_fd, F_SETFL, O_NONBLOCK) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "fcntl", strerror(errno)); - event_exit(); + logger(LOG_ERR, "System call `%s' failed: %s", "fcntl", strerror(errno)); + running = false; return false; } @@ -223,82 +218,93 @@ static bool read_packet(vpn_packet_t *packet) { } case 1: { - if((inlen = read(request_fd, &request, sizeof(request))) != sizeof(request)) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading request from %s %s: %s", device_info, + if((lenin = read(request_fd, &request, sizeof(request))) != sizeof request) { + logger(LOG_ERR, "Error while reading request from %s %s: %s", device_info, device, strerror(errno)); - event_exit(); + running = false; return false; } if(request.magic != 0xfeedface || request.version != 3 || request.type != REQ_NEW_CONTROL) { - logger(DEBUG_ALWAYS, LOG_ERR, "Unknown magic %x, version %d, request type %d from %s %s", + logger(LOG_ERR, "Unknown magic %x, version %d, request type %d from %s %s", request.magic, request.version, request.type, device_info, device); - event_exit(); + running = false; return false; } - if(connect(write_fd, (const struct sockaddr *)&request.sock, sizeof(request.sock)) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not bind write %s: %s", device_info, strerror(errno)); - event_exit(); + if(connect(write_fd, (struct sockaddr *)&request.sock, sizeof(request.sock)) < 0) { + logger(LOG_ERR, "Could not bind write %s: %s", device_info, strerror(errno)); + running = false; return false; } write(request_fd, &data_sun, sizeof(data_sun)); device_fd = data_fd; - logger(DEBUG_ALWAYS, LOG_INFO, "Connection with UML established"); + logger(LOG_INFO, "Connection with UML established"); state = 2; return false; } case 2: { - if((inlen = read(data_fd, DATA(packet), MTU)) <= 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info, + if((lenin = read(data_fd, packet->data, MTU)) <= 0) { + logger(LOG_ERR, "Error while reading from %s %s: %s", device_info, device, strerror(errno)); - event_exit(); + running = false; return false; } - packet->len = inlen; + packet->len = lenin; - logger(DEBUG_TRAFFIC, LOG_DEBUG, "Read packet of %d bytes from %s", packet->len, - device_info); + device_total_in += packet->len; + + ifdebug(TRAFFIC) logger(LOG_DEBUG, "Read packet of %d bytes from %s", packet->len, + device_info); return true; } default: - logger(DEBUG_ALWAYS, LOG_ERR, "Invalid value for state variable in " __FILE__); + logger(LOG_ERR, "Invalid value for state variable in " __FILE__); abort(); } } static bool write_packet(vpn_packet_t *packet) { if(state != 2) { - logger(DEBUG_TRAFFIC, LOG_DEBUG, "Dropping packet of %d bytes to %s: not connected to UML yet", - packet->len, device_info); + ifdebug(TRAFFIC) logger(LOG_DEBUG, "Dropping packet of %d bytes to %s: not connected to UML yet", + packet->len, device_info); return false; } - logger(DEBUG_TRAFFIC, LOG_DEBUG, "Writing packet of %d bytes to %s", - packet->len, device_info); + ifdebug(TRAFFIC) logger(LOG_DEBUG, "Writing packet of %d bytes to %s", + packet->len, device_info); - if(write(write_fd, DATA(packet), packet->len) < 0) { + if(write(write_fd, packet->data, packet->len) < 0) { if(errno != EINTR && errno != EAGAIN) { - logger(DEBUG_ALWAYS, LOG_ERR, "Can't write to %s %s: %s", device_info, device, strerror(errno)); - event_exit(); + logger(LOG_ERR, "Can't write to %s %s: %s", device_info, device, strerror(errno)); + running = false; } return false; } + device_total_out += packet->len; + return true; } +static void dump_device_stats(void) { + logger(LOG_DEBUG, "Statistics for %s %s:", device_info, device); + logger(LOG_DEBUG, " total bytes in: %10"PRIu64, device_total_in); + logger(LOG_DEBUG, " total bytes out: %10"PRIu64, device_total_out); +} + const devops_t uml_devops = { .setup = setup_device, .close = close_device, .read = read_packet, .write = write_packet, + .dump_stats = dump_device_stats, }; diff --git a/src/upnp.c b/src/upnp.c deleted file mode 100644 index 5e41d1b..0000000 --- a/src/upnp.c +++ /dev/null @@ -1,185 +0,0 @@ -/* - upnp.c -- UPnP-IGD client - Copyright (C) 2015 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 - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include "upnp.h" - -#include - -#include "miniupnpc/miniupnpc.h" -#include "miniupnpc/upnpcommands.h" -#include "miniupnpc/upnperrors.h" - -#include "system.h" -#include "logger.h" -#include "names.h" -#include "net.h" -#include "netutl.h" -#include "utils.h" - -static bool upnp_tcp; -static bool upnp_udp; -static int upnp_discover_wait = 5; -static int upnp_refresh_period = 60; - -// Unfortunately, libminiupnpc devs don't seem to care about API compatibility, -// and there are slight changes to function signatures between library versions. -// Well, at least they publish a "MINIUPNPC_API_VERSION" constant, so we got that going for us, which is nice. -// Differences between API versions are documented in "apiversions.txt" in the libminiupnpc distribution. - -#ifndef MINIUPNPC_API_VERSION -#define MINIUPNPC_API_VERSION 0 -#endif - -static struct UPNPDev *upnp_discover(int delay, int *error) { -#if MINIUPNPC_API_VERSION <= 13 - -#if MINIUPNPC_API_VERSION < 8 -#warning "The version of libminiupnpc you're building against seems to be too old. Expect trouble." -#endif - - return upnpDiscover(delay, NULL, NULL, false, false, error); - -#elif MINIUPNPC_API_VERSION <= 14 - - return upnpDiscover(delay, NULL, NULL, false, false, 2, error); - -#else - -#if MINIUPNPC_API_VERSION > 17 -#warning "The version of libminiupnpc you're building against seems to be too recent. Expect trouble." -#endif - - return upnpDiscover(delay, NULL, NULL, UPNP_LOCAL_PORT_ANY, false, 2, error); - -#endif -} - -static void upnp_add_mapping(struct UPNPUrls *urls, struct IGDdatas *data, const char *myaddr, int socket, const char *proto) { - // Extract the port from the listening socket. - // Note that we can't simply use listen_socket[].sa because this won't have the port - // if we're running with Port=0 (dynamically assigned port). - sockaddr_t sa; - socklen_t salen = sizeof(sa); - - if(getsockname(socket, &sa.sa, &salen)) { - logger(DEBUG_PROTOCOL, LOG_ERR, "[upnp] Unable to get socket address: [%d] %s", sockerrno, sockstrerror(sockerrno)); - return; - } - - char *port; - sockaddr2str(&sa, NULL, &port); - - if(!port) { - logger(DEBUG_PROTOCOL, LOG_ERR, "[upnp] Unable to get socket port"); - return; - } - - // Use a lease twice as long as the refresh period so that the mapping won't expire before we refresh. - char lease_duration[16]; - snprintf(lease_duration, sizeof(lease_duration), "%d", upnp_refresh_period * 2); - - int error = UPNP_AddPortMapping(urls->controlURL, data->first.servicetype, port, port, myaddr, identname, proto, NULL, lease_duration); - - if(error == 0) { - logger(DEBUG_PROTOCOL, LOG_INFO, "[upnp] Successfully set port mapping (%s:%s %s for %s seconds)", myaddr, port, proto, lease_duration); - } else { - logger(DEBUG_PROTOCOL, LOG_ERR, "[upnp] Failed to set port mapping (%s:%s %s for %s seconds): [%d] %s", myaddr, port, proto, lease_duration, error, strupnperror(error)); - } - - free(port); -} - -static void upnp_refresh() { - logger(DEBUG_PROTOCOL, LOG_INFO, "[upnp] Discovering IGD devices"); - - int error; - struct UPNPDev *devices = upnp_discover(upnp_discover_wait * 1000, &error); - - if(!devices) { - logger(DEBUG_PROTOCOL, LOG_WARNING, "[upnp] Unable to find IGD devices: [%d] %s", error, strupnperror(error)); - freeUPNPDevlist(devices); - return; - } - - struct UPNPUrls urls; - - struct IGDdatas data; - - char myaddr[64]; - - int result = UPNP_GetValidIGD(devices, &urls, &data, myaddr, sizeof(myaddr)); - - if(result <= 0) { - logger(DEBUG_PROTOCOL, LOG_WARNING, "[upnp] No IGD found"); - freeUPNPDevlist(devices); - return; - } - - logger(DEBUG_PROTOCOL, LOG_INFO, "[upnp] IGD found: [%d] %s (local address: %s, service type: %s)", result, urls.controlURL, myaddr, data.first.servicetype); - - for(int i = 0; i < listen_sockets; i++) { - if(upnp_tcp) { - upnp_add_mapping(&urls, &data, myaddr, listen_socket[i].tcp.fd, "TCP"); - } - - if(upnp_udp) { - upnp_add_mapping(&urls, &data, myaddr, listen_socket[i].udp.fd, "UDP"); - } - } - - FreeUPNPUrls(&urls); - freeUPNPDevlist(devices); -} - -static void *upnp_thread(void *data) { - (void)data; - - while(true) { - time_t start = time(NULL); - upnp_refresh(); - - // Make sure we'll stick to the refresh period no matter how long upnp_refresh() takes. - time_t refresh_time = start + upnp_refresh_period; - time_t now = time(NULL); - - if(now < refresh_time) { - sleep(refresh_time - now); - } - } - - // TODO: we don't have a clean thread shutdown procedure, so we can't remove the mapping. - // this is probably not a concern as long as the UPnP device honors the lease duration, - // but considering how bug-riddled these devices often are, that's a big "if". - return NULL; -} - -void upnp_init(bool tcp, bool udp) { - upnp_tcp = tcp; - upnp_udp = udp; - - get_config_int(lookup_config(config_tree, "UPnPDiscoverWait"), &upnp_discover_wait); - get_config_int(lookup_config(config_tree, "UPnPRefreshPeriod"), &upnp_refresh_period); - - pthread_t thread; - int error = pthread_create(&thread, NULL, upnp_thread, NULL); - - if(error) { - logger(DEBUG_ALWAYS, LOG_ERR, "Unable to start UPnP-IGD client thread: [%d] %s", error, strerror(error)); - } -} diff --git a/src/utils.c b/src/utils.c index 857d47e..70a5c99 100644 --- a/src/utils.c +++ b/src/utils.c @@ -1,7 +1,7 @@ /* utils.c -- gathering of some stupid small functions Copyright (C) 1999-2005 Ivo Timmermans - 2000-2013 Guus Sliepen + 2000-2014 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 @@ -18,32 +18,12 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#include "logger.h" #include "system.h" + +#include "../src/logger.h" #include "utils.h" -#include "xalloc.h" static const char hexadecimals[] = "0123456789ABCDEF"; -static const char base64_original[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; -static const char base64_urlsafe[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"; -static const char base64_decode[256] = { - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, 62, -1, 63, - 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, - -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, 63, - -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, - 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - }; static int charhex2bin(char c) { if(isdigit(c)) { @@ -53,124 +33,25 @@ static int charhex2bin(char c) { } } -size_t hex2bin(const char *src, void *vdst, size_t length) { - char *dst = vdst; - size_t i; +bool hex2bin(char *src, char *dst, int length) { + for(int i = 0; i < length; i++) { + if(!isxdigit(src[i * 2]) || !isxdigit(src[i * 2 + 1])) { + return false; + } - for(i = 0; i < length && isxdigit(src[i * 2]) && isxdigit(src[i * 2 + 1]); i++) { dst[i] = charhex2bin(src[i * 2]) * 16 + charhex2bin(src[i * 2 + 1]); } - return i; + return true; } -size_t bin2hex(const void *vsrc, char *dst, size_t length) { - const char *src = vsrc; +void bin2hex(char *src, char *dst, int length) { + int i; - for(size_t i = length; i-- > 0;) { + for(i = length - 1; i >= 0; i--) { dst[i * 2 + 1] = hexadecimals[(unsigned char) src[i] & 15]; dst[i * 2] = hexadecimals[(unsigned char) src[i] >> 4]; } - - dst[length * 2] = 0; - return length * 2; -} - -size_t b64decode(const char *src, void *dst, size_t length) { - size_t i; - uint32_t triplet = 0; - unsigned char *udst = (unsigned char *)dst; - - for(i = 0; i < length && src[i]; i++) { - triplet |= base64_decode[src[i] & 0xff] << (6 * (i & 3)); - - if((i & 3) == 3) { - if(triplet & 0xff000000U) { - return 0; - } - - udst[0] = triplet & 0xff; - triplet >>= 8; - udst[1] = triplet & 0xff; - triplet >>= 8; - udst[2] = triplet; - triplet = 0; - udst += 3; - } - } - - if(triplet & 0xff000000U) { - return 0; - } - - if((i & 3) == 3) { - udst[0] = triplet & 0xff; - triplet >>= 8; - udst[1] = triplet & 0xff; - return i / 4 * 3 + 2; - } else if((i & 3) == 2) { - udst[0] = triplet & 0xff; - return i / 4 * 3 + 1; - } else { - return i / 4 * 3; - } -} - -static size_t b64encode_internal(const void *src, char *dst, size_t length, const char *alphabet) { - uint32_t triplet; - const unsigned char *usrc = (unsigned char *)src; - size_t si = length / 3 * 3; - size_t di = length / 3 * 4; - - switch(length % 3) { - case 2: - triplet = usrc[si] | usrc[si + 1] << 8; - dst[di] = alphabet[triplet & 63]; - triplet >>= 6; - dst[di + 1] = alphabet[triplet & 63]; - triplet >>= 6; - dst[di + 2] = alphabet[triplet]; - dst[di + 3] = 0; - length = di + 3; - break; - - case 1: - triplet = usrc[si]; - dst[di] = alphabet[triplet & 63]; - triplet >>= 6; - dst[di + 1] = alphabet[triplet]; - dst[di + 2] = 0; - length = di + 2; - break; - - default: - dst[di] = 0; - length = di; - break; - } - - while(si > 0) { - di -= 4; - si -= 3; - triplet = usrc[si] | usrc[si + 1] << 8 | usrc[si + 2] << 16; - dst[di] = alphabet[triplet & 63]; - triplet >>= 6; - dst[di + 1] = alphabet[triplet & 63]; - triplet >>= 6; - dst[di + 2] = alphabet[triplet & 63]; - triplet >>= 6; - dst[di + 3] = alphabet[triplet]; - } - - return length; -} - -size_t b64encode(const void *src, char *dst, size_t length) { - return b64encode_internal(src, dst, length, base64_original); -} - -size_t b64encode_urlsafe(const void *src, char *dst, size_t length) { - return b64encode_internal(src, dst, length, base64_urlsafe); } #if defined(HAVE_MINGW) || defined(HAVE_CYGWIN) @@ -181,11 +62,11 @@ size_t b64encode_urlsafe(const void *src, char *dst, size_t length) { const char *winerror(int err) { static char buf[1024], *ptr; - ptr = buf + snprintf(buf, sizeof(buf), "(%d) ", err); + ptr = buf + sprintf(buf, "(%d) ", err); if(!FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), ptr, sizeof(buf) - (ptr - buf), NULL)) { - strncpy(buf, "(unable to format errormessage)", sizeof(buf)); + NULL, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), ptr, sizeof(buf) - (ptr - buf), NULL)) { + strcpy(ptr, "(unable to format errormessage)"); }; if((ptr = strchr(buf, '\r'))) { @@ -207,83 +88,18 @@ unsigned int bitfield_to_int(const void *bitfield, size_t size) { return value; } -bool check_id(const char *id) { - if(!id || !*id) { - return false; +/** + * As memcmp(), but constant-time. + * Returns 0 when data is equal, non-zero otherwise. + */ +int memcmp_constant_time(const void *a, const void *b, size_t size) { + const uint8_t *a1 = a, *b1 = b; + int ret = 0; + size_t i; + + for(i = 0; i < size; i++) { + ret |= *a1++ ^ *b1++; } - for(; *id; id++) - if(!isalnum(*id) && *id != '_') { - return false; - } - - return true; -} - -bool check_netname(const char *netname, bool strict) { - if(!netname || !*netname || *netname == '.') { - return false; - } - - for(const char *c = netname; *c; c++) { - if(iscntrl(*c)) { - return false; - } - - if(*c == '/' || *c == '\\') { - return false; - } - - if(strict && strchr(" $%<>:`\"|?*", *c)) { - return false; - } - } - - return true; -} - -/* Windows doesn't define HOST_NAME_MAX. */ -#ifndef HOST_NAME_MAX -#define HOST_NAME_MAX 255 -#endif - -char *replace_name(const char *name) { - char *ret_name; - - if(name[0] == '$') { - char *envname = getenv(name + 1); - char hostname[HOST_NAME_MAX + 1]; - - if(!envname) { - if(strcmp(name + 1, "HOST")) { - logger(DEBUG_ALWAYS, LOG_ERR, "Invalid Name: environment variable %s does not exist\n", name + 1); - return NULL; - } - - if(gethostname(hostname, sizeof(hostname)) || !*hostname) { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not get hostname: %s\n", sockstrerror(sockerrno)); - return NULL; - } - - hostname[HOST_NAME_MAX] = 0; - envname = hostname; - } - - ret_name = xstrdup(envname); - - for(char *c = ret_name; *c; c++) - if(!isalnum(*c)) { - *c = '_'; - } - } else { - ret_name = xstrdup(name); - } - - if(!check_id(ret_name)) { - logger(DEBUG_ALWAYS, LOG_ERR, "Invalid name for myself!"); - free(ret_name); - return NULL; - } - - return ret_name; + return ret; } diff --git a/src/utils.h b/src/utils.h index 4285150..7952025 100644 --- a/src/utils.h +++ b/src/utils.h @@ -4,7 +4,7 @@ /* utils.h -- header file for utils.c Copyright (C) 1999-2005 Ivo Timmermans - 2000-2013 Guus Sliepen + 2000-2014 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 @@ -21,37 +21,30 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -extern size_t hex2bin(const char *src, void *dst, size_t length); -extern size_t bin2hex(const void *src, char *dst, size_t length); +extern bool hex2bin(char *src, char *dst, int length); +extern void bin2hex(char *src, char *dst, int length); -extern size_t b64encode(const void *src, char *dst, size_t length); -extern size_t b64encode_urlsafe(const void *src, char *dst, size_t length); -extern size_t b64decode(const char *src, void *dst, size_t length); +#if defined(HAVE_MINGW) || defined(HAVE_CYGWIN) +extern const char *winerror(int); +#endif #ifdef HAVE_MINGW -extern const char *winerror(int); #define strerror(x) ((x)>0?strerror(x):winerror(GetLastError())) #define sockerrno WSAGetLastError() #define sockstrerror(x) winerror(x) #define sockwouldblock(x) ((x) == WSAEWOULDBLOCK || (x) == WSAEINTR) #define sockmsgsize(x) ((x) == WSAEMSGSIZE) #define sockinprogress(x) ((x) == WSAEINPROGRESS || (x) == WSAEWOULDBLOCK) -#define sockinuse(x) ((x) == WSAEADDRINUSE) -#define socknotconn(x) ((x) == WSAENOTCONN) #else #define sockerrno errno #define sockstrerror(x) strerror(x) #define sockwouldblock(x) ((x) == EWOULDBLOCK || (x) == EINTR) #define sockmsgsize(x) ((x) == EMSGSIZE) #define sockinprogress(x) ((x) == EINPROGRESS) -#define sockinuse(x) ((x) == EADDRINUSE) -#define socknotconn(x) ((x) == ENOTCONN) #endif extern unsigned int bitfield_to_int(const void *bitfield, size_t size); -extern bool check_id(const char *id); -extern bool check_netname(const char *netname, bool strict); -char *replace_name(const char *name); +int memcmp_constant_time(const void *a, const void *b, size_t size); #endif diff --git a/src/vde_device.c b/src/vde_device.c index 0170af3..6d854a6 100644 --- a/src/vde_device.c +++ b/src/vde_device.c @@ -1,6 +1,6 @@ /* device.c -- VDE plug - Copyright (C) 2013 Guus Sliepen + Copyright (C) 2012 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 @@ -23,7 +23,6 @@ #include "conf.h" #include "device.h" -#include "names.h" #include "net.h" #include "logger.h" #include "utils.h" @@ -36,11 +35,17 @@ static int port = 0; static char *group = NULL; static const char *device_info = "VDE socket"; +extern char *identname; +extern volatile bool running; + +static uint64_t device_total_in = 0; +static uint64_t device_total_out = 0; + static bool setup_device(void) { libvdeplug_dynopen(plug); if(!plug.dl_handle) { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not open libvdeplug library!"); + logger(LOG_ERR, "Could not open libvdeplug library!"); return false; } @@ -63,7 +68,7 @@ static bool setup_device(void) { conn = plug.vde_open(device, identname, &args); if(!conn) { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not open VDE socket %s", device); + logger(LOG_ERR, "Could not open VDE socket %s", device); return false; } @@ -73,7 +78,7 @@ static bool setup_device(void) { fcntl(device_fd, F_SETFD, FD_CLOEXEC); #endif - logger(DEBUG_ALWAYS, LOG_INFO, "%s is a %s", device, device_info); + logger(LOG_INFO, "%s is a %s", device, device_info); if(routing_mode == RMODE_ROUTER) { overwrite_mac = true; @@ -85,7 +90,6 @@ static bool setup_device(void) { static void close_device(void) { if(conn) { plug.vde_close(conn); - conn = NULL; } if(plug.dl_handle) { @@ -93,46 +97,51 @@ static void close_device(void) { } free(device); - device = NULL; free(iface); - iface = NULL; - - device_info = NULL; } static bool read_packet(vpn_packet_t *packet) { - int lenin = (ssize_t)plug.vde_recv(conn, DATA(packet), MTU, 0); + int lenin = (ssize_t)plug.vde_recv(conn, packet->data, MTU, 0); if(lenin <= 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info, device, strerror(errno)); - event_exit(); + logger(LOG_ERR, "Error while reading from %s %s: %s", device_info, device, strerror(errno)); + running = false; return false; } packet->len = lenin; - - logger(DEBUG_TRAFFIC, LOG_DEBUG, "Read packet of %d bytes from %s", packet->len, device_info); + device_total_in += packet->len; + ifdebug(TRAFFIC) logger(LOG_DEBUG, "Read packet of %d bytes from %s", packet->len, device_info); return true; } static bool write_packet(vpn_packet_t *packet) { - if((ssize_t)plug.vde_send(conn, DATA(packet), packet->len, 0) < 0) { + if((ssize_t)plug.vde_send(conn, packet->data, packet->len, 0) < 0) { if(errno != EINTR && errno != EAGAIN) { - logger(DEBUG_ALWAYS, LOG_ERR, "Can't write to %s %s: %s", device_info, device, strerror(errno)); - event_exit(); + logger(LOG_ERR, "Can't write to %s %s: %s", device_info, device, strerror(errno)); + running = false; } return false; } + device_total_out += packet->len; + return true; } +static void dump_device_stats(void) { + logger(LOG_DEBUG, "Statistics for %s %s:", device_info, device); + logger(LOG_DEBUG, " total bytes in: %10"PRIu64, device_total_in); + logger(LOG_DEBUG, " total bytes out: %10"PRIu64, device_total_out); +} + const devops_t vde_devops = { .setup = setup_device, .close = close_device, .read = read_packet, .write = write_packet, + .dump_stats = dump_device_stats, }; diff --git a/src/version.c b/src/version.c deleted file mode 100644 index d0af1cc..0000000 --- a/src/version.c +++ /dev/null @@ -1,31 +0,0 @@ -/* - version.c -- version information - Copyright (C) 2014 Etienne Dechamps - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include "version.h" -#include "version_git.h" -#include "../config.h" - -/* This file is always rebuilt (even if there are no changes) so that the following is updated */ -const char *const BUILD_DATE = __DATE__; -const char *const BUILD_TIME = __TIME__; -#ifdef GIT_DESCRIPTION -const char *const BUILD_VERSION = GIT_DESCRIPTION; -#else -const char *const BUILD_VERSION = VERSION; -#endif diff --git a/src/version.h b/src/version.h deleted file mode 100644 index a4cf0a7..0000000 --- a/src/version.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef TINC_VERSION_H -#define TINC_VERSION_H - -/* - version.h -- header for version.c - Copyright (C) 2014 Etienne Dechamps - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -extern const char *const BUILD_DATE; -extern const char *const BUILD_TIME; -extern const char *const BUILD_VERSION; - -#endif diff --git a/src/xalloc.h b/src/xalloc.h index d9877a8..cda0871 100644 --- a/src/xalloc.h +++ b/src/xalloc.h @@ -4,7 +4,7 @@ /* xalloc.h -- malloc and related functions with out of memory checking Copyright (C) 1990, 91, 92, 93, 94, 95, 96, 97 Free Software Foundation, Inc. - Copyright (C) 2011-2013 Guus Sliepen + Copyright (C) 2011-2017 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 @@ -32,8 +32,8 @@ static inline void *xmalloc(size_t n) { return p; } -static inline void *xzalloc(size_t n) __attribute__((__malloc__)); -static inline void *xzalloc(size_t n) { +static inline void *xmalloc_and_zero(size_t n) __attribute__((__malloc__)); +static inline void *xmalloc_and_zero(size_t n) { void *p = calloc(1, n); if(!p) { @@ -53,7 +53,7 @@ static inline void *xrealloc(void *p, size_t n) { return p; } -static inline char *xstrdup(const char *s) __attribute__((__malloc__, __nonnull__)); +static inline char *xstrdup(const char *s) __attribute__((__malloc__)); static inline char *xstrdup(const char *s) { char *p = strdup(s); diff --git a/systemd/Makefile.in b/systemd/Makefile.in index ef4ed4e..376a668 100644 --- a/systemd/Makefile.in +++ b/systemd/Makefile.in @@ -95,12 +95,9 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \ $(top_srcdir)/m4/ax_cflags_warn_all.m4 \ $(top_srcdir)/m4/ax_check_compile_flag.m4 \ $(top_srcdir)/m4/ax_check_link_flag.m4 \ - $(top_srcdir)/m4/ax_code_coverage.m4 \ - $(top_srcdir)/m4/ax_require_defined.m4 \ - $(top_srcdir)/m4/curses.m4 $(top_srcdir)/m4/libgcrypt.m4 \ - $(top_srcdir)/m4/lzo.m4 $(top_srcdir)/m4/miniupnpc.m4 \ - $(top_srcdir)/m4/openssl.m4 $(top_srcdir)/m4/readline.m4 \ - $(top_srcdir)/m4/zlib.m4 $(top_srcdir)/configure.ac + $(top_srcdir)/m4/ax_require_defined.m4 $(top_srcdir)/m4/lzo.m4 \ + $(top_srcdir)/m4/openssl.m4 $(top_srcdir)/m4/zlib.m4 \ + $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) @@ -169,15 +166,8 @@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ -CODE_COVERAGE_CFLAGS = @CODE_COVERAGE_CFLAGS@ -CODE_COVERAGE_CPPFLAGS = @CODE_COVERAGE_CPPFLAGS@ -CODE_COVERAGE_CXXFLAGS = @CODE_COVERAGE_CXXFLAGS@ -CODE_COVERAGE_ENABLED = @CODE_COVERAGE_ENABLED@ -CODE_COVERAGE_LDFLAGS = @CODE_COVERAGE_LDFLAGS@ -CODE_COVERAGE_LIBS = @CODE_COVERAGE_LIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ -CURSES_LIBS = @CURSES_LIBS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ @@ -186,21 +176,17 @@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ -GCOV = @GCOV@ -GENHTML = @GENHTML@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -LCOV = @LCOV@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ -MINIUPNPC_LIBS = @MINIUPNPC_LIBS@ MKDIR_P = @MKDIR_P@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ @@ -211,8 +197,6 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ -READLINE_LIBS = @READLINE_LIBS@ -SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ diff --git a/systemd/tinc@.service.in b/systemd/tinc@.service.in index 2d695ca..8fbf551 100644 --- a/systemd/tinc@.service.in +++ b/systemd/tinc@.service.in @@ -10,7 +10,7 @@ ReloadPropagatedFrom=tinc.service Type=simple WorkingDirectory=@sysconfdir@/tinc/%i ExecStart=@sbindir@/tincd -n %i -D -ExecReload=@sbindir@/tinc -n %i reload +ExecReload=@sbindir@/tincd -n %i -kHUP KillMode=mixed Restart=on-failure RestartSec=5 diff --git a/test-driver b/test-driver deleted file mode 100755 index b8521a4..0000000 --- a/test-driver +++ /dev/null @@ -1,148 +0,0 @@ -#! /bin/sh -# test-driver - basic testsuite driver script. - -scriptversion=2018-03-07.03; # UTC - -# Copyright (C) 2011-2018 Free Software Foundation, Inc. -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - -# This file is maintained in Automake, please report -# bugs to or send patches to -# . - -# Make unconditional expansion of undefined variables an error. This -# helps a lot in preventing typo-related bugs. -set -u - -usage_error () -{ - echo "$0: $*" >&2 - print_usage >&2 - exit 2 -} - -print_usage () -{ - cat <$log_file 2>&1 -estatus=$? - -if test $enable_hard_errors = no && test $estatus -eq 99; then - tweaked_estatus=1 -else - tweaked_estatus=$estatus -fi - -case $tweaked_estatus:$expect_failure in - 0:yes) col=$red res=XPASS recheck=yes gcopy=yes;; - 0:*) col=$grn res=PASS recheck=no gcopy=no;; - 77:*) col=$blu res=SKIP recheck=no gcopy=yes;; - 99:*) col=$mgn res=ERROR recheck=yes gcopy=yes;; - *:yes) col=$lgn res=XFAIL recheck=no gcopy=yes;; - *:*) col=$red res=FAIL recheck=yes gcopy=yes;; -esac - -# Report the test outcome and exit status in the logs, so that one can -# know whether the test passed or failed simply by looking at the '.log' -# file, without the need of also peaking into the corresponding '.trs' -# file (automake bug#11814). -echo "$res $test_name (exit status: $estatus)" >>$log_file - -# Report outcome to console. -echo "${col}${res}${std}: $test_name" - -# Register the test result, and other relevant metadata. -echo ":test-result: $res" > $trs_file -echo ":global-test-result: $res" >> $trs_file -echo ":recheck: $recheck" >> $trs_file -echo ":copy-in-global-log: $gcopy" >> $trs_file - -# Local Variables: -# mode: shell-script -# sh-indentation: 2 -# eval: (add-hook 'before-save-hook 'time-stamp) -# time-stamp-start: "scriptversion=" -# time-stamp-format: "%:y-%02m-%02d.%02H" -# time-stamp-time-zone: "UTC0" -# time-stamp-end: "; # UTC" -# End: diff --git a/test/Makefile.am b/test/Makefile.am deleted file mode 100644 index 32b2e30..0000000 --- a/test/Makefile.am +++ /dev/null @@ -1,30 +0,0 @@ -TESTS = \ - basic.test \ - commandline.test \ - executables.test \ - import-export.test \ - invite-join.test \ - invite-offline.test \ - invite-tinc-up.test \ - legacy-protocol.test \ - ns-ping.test \ - scripts.test \ - security.test \ - sptps-basic.test \ - variables.test - -dist_check_SCRIPTS = $(TESTS) - -EXTRA_DIST = testlib.sh - -AM_CFLAGS = -iquote. - -check_PROGRAMS = \ - splice - -splice_SOURCES = splice.c - -clean-local: - -for pid in *.test.?/pid; do ../src/tinc --pidfile="$$pid" stop; done - -killall ../src/sptps_test - -rm -rf *.test.? diff --git a/test/Makefile.in b/test/Makefile.in deleted file mode 100644 index a5f0487..0000000 --- a/test/Makefile.in +++ /dev/null @@ -1,951 +0,0 @@ -# Makefile.in generated by automake 1.16.1 from Makefile.am. -# @configure_input@ - -# Copyright (C) 1994-2018 Free Software Foundation, Inc. - -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -@SET_MAKE@ -VPATH = @srcdir@ -am__is_gnu_make = { \ - if test -z '$(MAKELEVEL)'; then \ - false; \ - elif test -n '$(MAKE_HOST)'; then \ - true; \ - elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ - true; \ - else \ - false; \ - fi; \ -} -am__make_running_with_option = \ - case $${target_option-} in \ - ?) ;; \ - *) echo "am__make_running_with_option: internal error: invalid" \ - "target option '$${target_option-}' specified" >&2; \ - exit 1;; \ - esac; \ - has_opt=no; \ - sane_makeflags=$$MAKEFLAGS; \ - if $(am__is_gnu_make); then \ - sane_makeflags=$$MFLAGS; \ - else \ - case $$MAKEFLAGS in \ - *\\[\ \ ]*) \ - bs=\\; \ - sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ - | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ - esac; \ - fi; \ - skip_next=no; \ - strip_trailopt () \ - { \ - flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ - }; \ - for flg in $$sane_makeflags; do \ - test $$skip_next = yes && { skip_next=no; continue; }; \ - case $$flg in \ - *=*|--*) continue;; \ - -*I) strip_trailopt 'I'; skip_next=yes;; \ - -*I?*) strip_trailopt 'I';; \ - -*O) strip_trailopt 'O'; skip_next=yes;; \ - -*O?*) strip_trailopt 'O';; \ - -*l) strip_trailopt 'l'; skip_next=yes;; \ - -*l?*) strip_trailopt 'l';; \ - -[dEDm]) skip_next=yes;; \ - -[JT]) skip_next=yes;; \ - esac; \ - case $$flg in \ - *$$target_option*) has_opt=yes; break;; \ - esac; \ - done; \ - test $$has_opt = yes -am__make_dryrun = (target_option=n; $(am__make_running_with_option)) -am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) -pkgdatadir = $(datadir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkglibexecdir = $(libexecdir)/@PACKAGE@ -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -install_sh_DATA = $(install_sh) -c -m 644 -install_sh_PROGRAM = $(install_sh) -c -install_sh_SCRIPT = $(install_sh) -c -INSTALL_HEADER = $(INSTALL_DATA) -transform = $(program_transform_name) -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -build_triplet = @build@ -host_triplet = @host@ -check_PROGRAMS = splice$(EXEEXT) -subdir = test -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \ - $(top_srcdir)/m4/ax_append_flag.m4 \ - $(top_srcdir)/m4/ax_cflags_warn_all.m4 \ - $(top_srcdir)/m4/ax_check_compile_flag.m4 \ - $(top_srcdir)/m4/ax_check_link_flag.m4 \ - $(top_srcdir)/m4/ax_code_coverage.m4 \ - $(top_srcdir)/m4/ax_require_defined.m4 \ - $(top_srcdir)/m4/curses.m4 $(top_srcdir)/m4/libgcrypt.m4 \ - $(top_srcdir)/m4/lzo.m4 $(top_srcdir)/m4/miniupnpc.m4 \ - $(top_srcdir)/m4/openssl.m4 $(top_srcdir)/m4/readline.m4 \ - $(top_srcdir)/m4/zlib.m4 $(top_srcdir)/configure.ac -am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ - $(ACLOCAL_M4) -DIST_COMMON = $(srcdir)/Makefile.am $(dist_check_SCRIPTS) \ - $(am__DIST_COMMON) -mkinstalldirs = $(install_sh) -d -CONFIG_HEADER = $(top_builddir)/config.h -CONFIG_CLEAN_FILES = -CONFIG_CLEAN_VPATH_FILES = -am_splice_OBJECTS = splice.$(OBJEXT) -splice_OBJECTS = $(am_splice_OBJECTS) -splice_LDADD = $(LDADD) -AM_V_P = $(am__v_P_@AM_V@) -am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) -am__v_P_0 = false -am__v_P_1 = : -AM_V_GEN = $(am__v_GEN_@AM_V@) -am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) -am__v_GEN_0 = @echo " GEN " $@; -am__v_GEN_1 = -AM_V_at = $(am__v_at_@AM_V@) -am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) -am__v_at_0 = @ -am__v_at_1 = -DEFAULT_INCLUDES = -depcomp = $(SHELL) $(top_srcdir)/depcomp -am__maybe_remake_depfiles = depfiles -am__depfiles_remade = ./$(DEPDIR)/splice.Po -am__mv = mv -f -COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ - $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -AM_V_CC = $(am__v_CC_@AM_V@) -am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) -am__v_CC_0 = @echo " CC " $@; -am__v_CC_1 = -CCLD = $(CC) -LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ -AM_V_CCLD = $(am__v_CCLD_@AM_V@) -am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) -am__v_CCLD_0 = @echo " CCLD " $@; -am__v_CCLD_1 = -SOURCES = $(splice_SOURCES) -DIST_SOURCES = $(splice_SOURCES) -am__can_run_installinfo = \ - case $$AM_UPDATE_INFO_DIR in \ - n|no|NO) false;; \ - *) (install-info --version) >/dev/null 2>&1;; \ - esac -am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) -# Read a list of newline-separated strings from the standard input, -# and print each of them once, without duplicates. Input order is -# *not* preserved. -am__uniquify_input = $(AWK) '\ - BEGIN { nonempty = 0; } \ - { items[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in items) print i; }; } \ -' -# Make sure the list of sources is unique. This is necessary because, -# e.g., the same source file might be shared among _SOURCES variables -# for different programs/libraries. -am__define_uniq_tagged_files = \ - list='$(am__tagged_files)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | $(am__uniquify_input)` -ETAGS = etags -CTAGS = ctags -am__tty_colors_dummy = \ - mgn= red= grn= lgn= blu= brg= std=; \ - am__color_tests=no -am__tty_colors = { \ - $(am__tty_colors_dummy); \ - if test "X$(AM_COLOR_TESTS)" = Xno; then \ - am__color_tests=no; \ - elif test "X$(AM_COLOR_TESTS)" = Xalways; then \ - am__color_tests=yes; \ - elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \ - am__color_tests=yes; \ - fi; \ - if test $$am__color_tests = yes; then \ - red=''; \ - grn=''; \ - lgn=''; \ - blu=''; \ - mgn=''; \ - brg=''; \ - std=''; \ - fi; \ -} -am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; -am__vpath_adj = case $$p in \ - $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ - *) f=$$p;; \ - esac; -am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; -am__install_max = 40 -am__nobase_strip_setup = \ - srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` -am__nobase_strip = \ - for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" -am__nobase_list = $(am__nobase_strip_setup); \ - for p in $$list; do echo "$$p $$p"; done | \ - sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ - $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ - if (++n[$$2] == $(am__install_max)) \ - { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ - END { for (dir in files) print dir, files[dir] }' -am__base_list = \ - sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ - sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' -am__uninstall_files_from_dir = { \ - test -z "$$files" \ - || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ - || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ - $(am__cd) "$$dir" && rm -f $$files; }; \ - } -am__recheck_rx = ^[ ]*:recheck:[ ]* -am__global_test_result_rx = ^[ ]*:global-test-result:[ ]* -am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]* -# A command that, given a newline-separated list of test names on the -# standard input, print the name of the tests that are to be re-run -# upon "make recheck". -am__list_recheck_tests = $(AWK) '{ \ - recheck = 1; \ - while ((rc = (getline line < ($$0 ".trs"))) != 0) \ - { \ - if (rc < 0) \ - { \ - if ((getline line2 < ($$0 ".log")) < 0) \ - recheck = 0; \ - break; \ - } \ - else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \ - { \ - recheck = 0; \ - break; \ - } \ - else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \ - { \ - break; \ - } \ - }; \ - if (recheck) \ - print $$0; \ - close ($$0 ".trs"); \ - close ($$0 ".log"); \ -}' -# A command that, given a newline-separated list of test names on the -# standard input, create the global log from their .trs and .log files. -am__create_global_log = $(AWK) ' \ -function fatal(msg) \ -{ \ - print "fatal: making $@: " msg | "cat >&2"; \ - exit 1; \ -} \ -function rst_section(header) \ -{ \ - print header; \ - len = length(header); \ - for (i = 1; i <= len; i = i + 1) \ - printf "="; \ - printf "\n\n"; \ -} \ -{ \ - copy_in_global_log = 1; \ - global_test_result = "RUN"; \ - while ((rc = (getline line < ($$0 ".trs"))) != 0) \ - { \ - if (rc < 0) \ - fatal("failed to read from " $$0 ".trs"); \ - if (line ~ /$(am__global_test_result_rx)/) \ - { \ - sub("$(am__global_test_result_rx)", "", line); \ - sub("[ ]*$$", "", line); \ - global_test_result = line; \ - } \ - else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \ - copy_in_global_log = 0; \ - }; \ - if (copy_in_global_log) \ - { \ - rst_section(global_test_result ": " $$0); \ - while ((rc = (getline line < ($$0 ".log"))) != 0) \ - { \ - if (rc < 0) \ - fatal("failed to read from " $$0 ".log"); \ - print line; \ - }; \ - printf "\n"; \ - }; \ - close ($$0 ".trs"); \ - close ($$0 ".log"); \ -}' -# Restructured Text title. -am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; } -# Solaris 10 'make', and several other traditional 'make' implementations, -# pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it -# by disabling -e (using the XSI extension "set +e") if it's set. -am__sh_e_setup = case $$- in *e*) set +e;; esac -# Default flags passed to test drivers. -am__common_driver_flags = \ - --color-tests "$$am__color_tests" \ - --enable-hard-errors "$$am__enable_hard_errors" \ - --expect-failure "$$am__expect_failure" -# To be inserted before the command running the test. Creates the -# directory for the log if needed. Stores in $dir the directory -# containing $f, in $tst the test, in $log the log. Executes the -# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and -# passes TESTS_ENVIRONMENT. Set up options for the wrapper that -# will run the test scripts (or their associated LOG_COMPILER, if -# thy have one). -am__check_pre = \ -$(am__sh_e_setup); \ -$(am__vpath_adj_setup) $(am__vpath_adj) \ -$(am__tty_colors); \ -srcdir=$(srcdir); export srcdir; \ -case "$@" in \ - */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \ - *) am__odir=.;; \ -esac; \ -test "x$$am__odir" = x"." || test -d "$$am__odir" \ - || $(MKDIR_P) "$$am__odir" || exit $$?; \ -if test -f "./$$f"; then dir=./; \ -elif test -f "$$f"; then dir=; \ -else dir="$(srcdir)/"; fi; \ -tst=$$dir$$f; log='$@'; \ -if test -n '$(DISABLE_HARD_ERRORS)'; then \ - am__enable_hard_errors=no; \ -else \ - am__enable_hard_errors=yes; \ -fi; \ -case " $(XFAIL_TESTS) " in \ - *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \ - am__expect_failure=yes;; \ - *) \ - am__expect_failure=no;; \ -esac; \ -$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT) -# A shell command to get the names of the tests scripts with any registered -# extension removed (i.e., equivalently, the names of the test logs, with -# the '.log' extension removed). The result is saved in the shell variable -# '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly, -# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)", -# since that might cause problem with VPATH rewrites for suffix-less tests. -# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'. -am__set_TESTS_bases = \ - bases='$(TEST_LOGS)'; \ - bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \ - bases=`echo $$bases` -RECHECK_LOGS = $(TEST_LOGS) -AM_RECURSIVE_TARGETS = check recheck -TEST_SUITE_LOG = test-suite.log -TEST_EXTENSIONS = @EXEEXT@ .test -am__test_logs1 = $(TESTS:=.log) -am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log) -TEST_LOGS = $(am__test_logs2:.test.log=.log) -TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver -TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \ - $(TEST_LOG_FLAGS) -am__set_b = \ - case '$@' in \ - */*) \ - case '$*' in \ - */*) b='$*';; \ - *) b=`echo '$@' | sed 's/\.log$$//'`; \ - esac;; \ - *) \ - b='$*';; \ - esac -am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp \ - $(top_srcdir)/test-driver -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) -ACLOCAL = @ACLOCAL@ -AMTAR = @AMTAR@ -AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ -AUTOCONF = @AUTOCONF@ -AUTOHEADER = @AUTOHEADER@ -AUTOMAKE = @AUTOMAKE@ -AWK = @AWK@ -CC = @CC@ -CCDEPMODE = @CCDEPMODE@ -CFLAGS = @CFLAGS@ -CODE_COVERAGE_CFLAGS = @CODE_COVERAGE_CFLAGS@ -CODE_COVERAGE_CPPFLAGS = @CODE_COVERAGE_CPPFLAGS@ -CODE_COVERAGE_CXXFLAGS = @CODE_COVERAGE_CXXFLAGS@ -CODE_COVERAGE_ENABLED = @CODE_COVERAGE_ENABLED@ -CODE_COVERAGE_LDFLAGS = @CODE_COVERAGE_LDFLAGS@ -CODE_COVERAGE_LIBS = @CODE_COVERAGE_LIBS@ -CPP = @CPP@ -CPPFLAGS = @CPPFLAGS@ -CURSES_LIBS = @CURSES_LIBS@ -CYGPATH_W = @CYGPATH_W@ -DEFS = @DEFS@ -DEPDIR = @DEPDIR@ -ECHO_C = @ECHO_C@ -ECHO_N = @ECHO_N@ -ECHO_T = @ECHO_T@ -EGREP = @EGREP@ -EXEEXT = @EXEEXT@ -GCOV = @GCOV@ -GENHTML = @GENHTML@ -GREP = @GREP@ -INSTALL = @INSTALL@ -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -LCOV = @LCOV@ -LDFLAGS = @LDFLAGS@ -LIBOBJS = @LIBOBJS@ -LIBS = @LIBS@ -LTLIBOBJS = @LTLIBOBJS@ -MAKEINFO = @MAKEINFO@ -MINIUPNPC_LIBS = @MINIUPNPC_LIBS@ -MKDIR_P = @MKDIR_P@ -OBJEXT = @OBJEXT@ -PACKAGE = @PACKAGE@ -PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ -PACKAGE_NAME = @PACKAGE_NAME@ -PACKAGE_STRING = @PACKAGE_STRING@ -PACKAGE_TARNAME = @PACKAGE_TARNAME@ -PACKAGE_URL = @PACKAGE_URL@ -PACKAGE_VERSION = @PACKAGE_VERSION@ -PATH_SEPARATOR = @PATH_SEPARATOR@ -READLINE_LIBS = @READLINE_LIBS@ -SED = @SED@ -SET_MAKE = @SET_MAKE@ -SHELL = @SHELL@ -STRIP = @STRIP@ -VERSION = @VERSION@ -abs_builddir = @abs_builddir@ -abs_srcdir = @abs_srcdir@ -abs_top_builddir = @abs_top_builddir@ -abs_top_srcdir = @abs_top_srcdir@ -ac_ct_CC = @ac_ct_CC@ -am__include = @am__include@ -am__leading_dot = @am__leading_dot@ -am__quote = @am__quote@ -am__tar = @am__tar@ -am__untar = @am__untar@ -bindir = @bindir@ -build = @build@ -build_alias = @build_alias@ -build_cpu = @build_cpu@ -build_os = @build_os@ -build_vendor = @build_vendor@ -builddir = @builddir@ -datadir = @datadir@ -datarootdir = @datarootdir@ -docdir = @docdir@ -dvidir = @dvidir@ -exec_prefix = @exec_prefix@ -host = @host@ -host_alias = @host_alias@ -host_cpu = @host_cpu@ -host_os = @host_os@ -host_vendor = @host_vendor@ -htmldir = @htmldir@ -includedir = @includedir@ -infodir = @infodir@ -install_sh = @install_sh@ -libdir = @libdir@ -libexecdir = @libexecdir@ -localedir = @localedir@ -localstatedir = @localstatedir@ -mandir = @mandir@ -mkdir_p = @mkdir_p@ -oldincludedir = @oldincludedir@ -pdfdir = @pdfdir@ -prefix = @prefix@ -program_transform_name = @program_transform_name@ -psdir = @psdir@ -runstatedir = @runstatedir@ -sbindir = @sbindir@ -sharedstatedir = @sharedstatedir@ -srcdir = @srcdir@ -sysconfdir = @sysconfdir@ -systemd_path = @systemd_path@ -target_alias = @target_alias@ -top_build_prefix = @top_build_prefix@ -top_builddir = @top_builddir@ -top_srcdir = @top_srcdir@ -TESTS = \ - basic.test \ - commandline.test \ - executables.test \ - import-export.test \ - invite-join.test \ - invite-offline.test \ - invite-tinc-up.test \ - legacy-protocol.test \ - ns-ping.test \ - scripts.test \ - security.test \ - sptps-basic.test \ - variables.test - -dist_check_SCRIPTS = $(TESTS) -EXTRA_DIST = testlib.sh -AM_CFLAGS = -iquote. -splice_SOURCES = splice.c -all: all-am - -.SUFFIXES: -.SUFFIXES: .c .log .o .obj .test .test$(EXEEXT) .trs -$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) - @for dep in $?; do \ - case '$(am__configure_deps)' in \ - *$$dep*) \ - ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ - && { if test -f $@; then exit 0; else break; fi; }; \ - exit 1;; \ - esac; \ - done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu test/Makefile'; \ - $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --gnu test/Makefile -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - @case '$?' in \ - *config.status*) \ - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ - *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ - esac; - -$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh - -$(top_srcdir)/configure: $(am__configure_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(ACLOCAL_M4): $(am__aclocal_m4_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(am__aclocal_m4_deps): - -clean-checkPROGRAMS: - -test -z "$(check_PROGRAMS)" || rm -f $(check_PROGRAMS) - -splice$(EXEEXT): $(splice_OBJECTS) $(splice_DEPENDENCIES) $(EXTRA_splice_DEPENDENCIES) - @rm -f splice$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(splice_OBJECTS) $(splice_LDADD) $(LIBS) - -mostlyclean-compile: - -rm -f *.$(OBJEXT) - -distclean-compile: - -rm -f *.tab.c - -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/splice.Po@am__quote@ # am--include-marker - -$(am__depfiles_remade): - @$(MKDIR_P) $(@D) - @echo '# dummy' >$@-t && $(am__mv) $@-t $@ - -am--depfiles: $(am__depfiles_remade) - -.c.o: -@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ -@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< - -.c.obj: -@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ -@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` - -ID: $(am__tagged_files) - $(am__define_uniq_tagged_files); mkid -fID $$unique -tags: tags-am -TAGS: tags - -tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - set x; \ - here=`pwd`; \ - $(am__define_uniq_tagged_files); \ - shift; \ - if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ - test -n "$$unique" || unique=$$empty_fix; \ - if test $$# -gt 0; then \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - "$$@" $$unique; \ - else \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - $$unique; \ - fi; \ - fi -ctags: ctags-am - -CTAGS: ctags -ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - $(am__define_uniq_tagged_files); \ - test -z "$(CTAGS_ARGS)$$unique" \ - || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ - $$unique - -GTAGS: - here=`$(am__cd) $(top_builddir) && pwd` \ - && $(am__cd) $(top_srcdir) \ - && gtags -i $(GTAGS_ARGS) "$$here" -cscopelist: cscopelist-am - -cscopelist-am: $(am__tagged_files) - list='$(am__tagged_files)'; \ - case "$(srcdir)" in \ - [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ - *) sdir=$(subdir)/$(srcdir) ;; \ - esac; \ - for i in $$list; do \ - if test -f "$$i"; then \ - echo "$(subdir)/$$i"; \ - else \ - echo "$$sdir/$$i"; \ - fi; \ - done >> $(top_builddir)/cscope.files - -distclean-tags: - -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags - -# Recover from deleted '.trs' file; this should ensure that -# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create -# both 'foo.log' and 'foo.trs'. Break the recipe in two subshells -# to avoid problems with "make -n". -.log.trs: - rm -f $< $@ - $(MAKE) $(AM_MAKEFLAGS) $< - -# Leading 'am--fnord' is there to ensure the list of targets does not -# expand to empty, as could happen e.g. with make check TESTS=''. -am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck) -am--force-recheck: - @: - -$(TEST_SUITE_LOG): $(TEST_LOGS) - @$(am__set_TESTS_bases); \ - am__f_ok () { test -f "$$1" && test -r "$$1"; }; \ - redo_bases=`for i in $$bases; do \ - am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \ - done`; \ - if test -n "$$redo_bases"; then \ - redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \ - redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \ - if $(am__make_dryrun); then :; else \ - rm -f $$redo_logs && rm -f $$redo_results || exit 1; \ - fi; \ - fi; \ - if test -n "$$am__remaking_logs"; then \ - echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \ - "recursion detected" >&2; \ - elif test -n "$$redo_logs"; then \ - am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \ - fi; \ - if $(am__make_dryrun); then :; else \ - st=0; \ - errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \ - for i in $$redo_bases; do \ - test -f $$i.trs && test -r $$i.trs \ - || { echo "$$errmsg $$i.trs" >&2; st=1; }; \ - test -f $$i.log && test -r $$i.log \ - || { echo "$$errmsg $$i.log" >&2; st=1; }; \ - done; \ - test $$st -eq 0 || exit 1; \ - fi - @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \ - ws='[ ]'; \ - results=`for b in $$bases; do echo $$b.trs; done`; \ - test -n "$$results" || results=/dev/null; \ - all=` grep "^$$ws*:test-result:" $$results | wc -l`; \ - pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \ - fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \ - skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \ - xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \ - xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \ - error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \ - if test `expr $$fail + $$xpass + $$error` -eq 0; then \ - success=true; \ - else \ - success=false; \ - fi; \ - br='==================='; br=$$br$$br$$br$$br; \ - result_count () \ - { \ - if test x"$$1" = x"--maybe-color"; then \ - maybe_colorize=yes; \ - elif test x"$$1" = x"--no-color"; then \ - maybe_colorize=no; \ - else \ - echo "$@: invalid 'result_count' usage" >&2; exit 4; \ - fi; \ - shift; \ - desc=$$1 count=$$2; \ - if test $$maybe_colorize = yes && test $$count -gt 0; then \ - color_start=$$3 color_end=$$std; \ - else \ - color_start= color_end=; \ - fi; \ - echo "$${color_start}# $$desc $$count$${color_end}"; \ - }; \ - create_testsuite_report () \ - { \ - result_count $$1 "TOTAL:" $$all "$$brg"; \ - result_count $$1 "PASS: " $$pass "$$grn"; \ - result_count $$1 "SKIP: " $$skip "$$blu"; \ - result_count $$1 "XFAIL:" $$xfail "$$lgn"; \ - result_count $$1 "FAIL: " $$fail "$$red"; \ - result_count $$1 "XPASS:" $$xpass "$$red"; \ - result_count $$1 "ERROR:" $$error "$$mgn"; \ - }; \ - { \ - echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \ - $(am__rst_title); \ - create_testsuite_report --no-color; \ - echo; \ - echo ".. contents:: :depth: 2"; \ - echo; \ - for b in $$bases; do echo $$b; done \ - | $(am__create_global_log); \ - } >$(TEST_SUITE_LOG).tmp || exit 1; \ - mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \ - if $$success; then \ - col="$$grn"; \ - else \ - col="$$red"; \ - test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \ - fi; \ - echo "$${col}$$br$${std}"; \ - echo "$${col}Testsuite summary for $(PACKAGE_STRING)$${std}"; \ - echo "$${col}$$br$${std}"; \ - create_testsuite_report --maybe-color; \ - echo "$$col$$br$$std"; \ - if $$success; then :; else \ - echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \ - if test -n "$(PACKAGE_BUGREPORT)"; then \ - echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \ - fi; \ - echo "$$col$$br$$std"; \ - fi; \ - $$success || exit 1 - -check-TESTS: $(check_PROGRAMS) $(dist_check_SCRIPTS) - @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list - @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list - @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) - @set +e; $(am__set_TESTS_bases); \ - log_list=`for i in $$bases; do echo $$i.log; done`; \ - trs_list=`for i in $$bases; do echo $$i.trs; done`; \ - log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \ - $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \ - exit $$?; -recheck: all $(check_PROGRAMS) $(dist_check_SCRIPTS) - @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) - @set +e; $(am__set_TESTS_bases); \ - bases=`for i in $$bases; do echo $$i; done \ - | $(am__list_recheck_tests)` || exit 1; \ - log_list=`for i in $$bases; do echo $$i.log; done`; \ - log_list=`echo $$log_list`; \ - $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \ - am__force_recheck=am--force-recheck \ - TEST_LOGS="$$log_list"; \ - exit $$? -.test.log: - @p='$<'; \ - $(am__set_b); \ - $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ - --log-file $$b.log --trs-file $$b.trs \ - $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ - "$$tst" $(AM_TESTS_FD_REDIRECT) -@am__EXEEXT_TRUE@.test$(EXEEXT).log: -@am__EXEEXT_TRUE@ @p='$<'; \ -@am__EXEEXT_TRUE@ $(am__set_b); \ -@am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ -@am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \ -@am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ -@am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT) - -distdir: $(BUILT_SOURCES) - $(MAKE) $(AM_MAKEFLAGS) distdir-am - -distdir-am: $(DISTFILES) - @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - list='$(DISTFILES)'; \ - dist_files=`for file in $$list; do echo $$file; done | \ - sed -e "s|^$$srcdirstrip/||;t" \ - -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ - case $$dist_files in \ - */*) $(MKDIR_P) `echo "$$dist_files" | \ - sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ - sort -u` ;; \ - esac; \ - for file in $$dist_files; do \ - if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - if test -d $$d/$$file; then \ - dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test -d "$(distdir)/$$file"; then \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ - else \ - test -f "$(distdir)/$$file" \ - || cp -p $$d/$$file "$(distdir)/$$file" \ - || exit 1; \ - fi; \ - done -check-am: all-am - $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) \ - $(dist_check_SCRIPTS) - $(MAKE) $(AM_MAKEFLAGS) check-TESTS -check: check-am -all-am: Makefile -installdirs: -install: install-am -install-exec: install-exec-am -install-data: install-data-am -uninstall: uninstall-am - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am - -installcheck: installcheck-am -install-strip: - if test -z '$(STRIP)'; then \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - install; \ - else \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ - fi -mostlyclean-generic: - -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS) - -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs) - -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) - -clean-generic: - -distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) - -maintainer-clean-generic: - @echo "This command is intended for maintainers to use" - @echo "it deletes files that may require special tools to rebuild." -clean: clean-am - -clean-am: clean-checkPROGRAMS clean-generic clean-local mostlyclean-am - -distclean: distclean-am - -rm -f ./$(DEPDIR)/splice.Po - -rm -f Makefile -distclean-am: clean-am distclean-compile distclean-generic \ - distclean-tags - -dvi: dvi-am - -dvi-am: - -html: html-am - -html-am: - -info: info-am - -info-am: - -install-data-am: - -install-dvi: install-dvi-am - -install-dvi-am: - -install-exec-am: - -install-html: install-html-am - -install-html-am: - -install-info: install-info-am - -install-info-am: - -install-man: - -install-pdf: install-pdf-am - -install-pdf-am: - -install-ps: install-ps-am - -install-ps-am: - -installcheck-am: - -maintainer-clean: maintainer-clean-am - -rm -f ./$(DEPDIR)/splice.Po - -rm -f Makefile -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-am - -mostlyclean-am: mostlyclean-compile mostlyclean-generic - -pdf: pdf-am - -pdf-am: - -ps: ps-am - -ps-am: - -uninstall-am: - -.MAKE: check-am install-am install-strip - -.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-TESTS \ - check-am clean clean-checkPROGRAMS clean-generic clean-local \ - cscopelist-am ctags ctags-am distclean distclean-compile \ - distclean-generic distclean-tags distdir dvi dvi-am html \ - html-am info info-am install install-am install-data \ - install-data-am install-dvi install-dvi-am install-exec \ - install-exec-am install-html install-html-am install-info \ - install-info-am install-man install-pdf install-pdf-am \ - install-ps install-ps-am install-strip installcheck \ - installcheck-am installdirs maintainer-clean \ - maintainer-clean-generic mostlyclean mostlyclean-compile \ - mostlyclean-generic pdf pdf-am ps ps-am recheck tags tags-am \ - uninstall uninstall-am - -.PRECIOUS: Makefile - - -clean-local: - -for pid in *.test.?/pid; do ../src/tinc --pidfile="$$pid" stop; done - -killall ../src/sptps_test - -rm -rf *.test.? - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/test/basic.test b/test/basic.test deleted file mode 100755 index c377202..0000000 --- a/test/basic.test +++ /dev/null @@ -1,20 +0,0 @@ -#!/bin/sh - -. "${0%/*}/testlib.sh" - -# Initialize and test one node - -$tinc $c1 init foo -$tinc $c1 set DeviceType dummy -$tinc $c1 set Port 0 - -# Test running in the foreground - -(sleep 1; $tinc $c1 stop) & -$tinc $c1 start $r1 -D - -# Test running tinc in the background - -$tinc $c1 start $r1 -sleep 1 -$tinc $c1 stop diff --git a/test/commandline.test b/test/commandline.test deleted file mode 100755 index 44d651a..0000000 --- a/test/commandline.test +++ /dev/null @@ -1,50 +0,0 @@ -#!/bin/sh - -. "${0%/*}/testlib.sh" - -# Initialize one node - -$tinc $c1 <$d1/tinc-up <$d1/invitation-created <\$INVITATION_FILE -echo Ifconfig = 93.184.216.34/24 >>\$INVITATION_FILE -echo Route = 2606:2800:220:1::/64 2606:2800:220:1:248:1893:25c8:1946 >>\$INVITATION_FILE -echo Route = 1.2.3.4 1234:: >>\$INVITATION_FILE -$tinc $c1 export >>\$INVITATION_FILE -EOF - -chmod u+x $d1/invitation-created - -$tinc $c1 invite bar | $tinc $c2 --batch join - -# Test equivalence of host config files - -cmp $d1/hosts/foo $d2/hosts/foo -test "`grep ^Ed25519PublicKey $d1/hosts/bar`" = "`grep ^Ed25519PublicKey $d2/hosts/bar`" - -# Check if the tinc-up.invitation file is created and contains the right commands - -test -f $d2/tinc-up.invitation - -fgrep -q "93.184.216.34/24" $d2/tinc-up.invitation -fgrep -q "2606:2800:220:1::/64" $d2/tinc-up.invitation -fgrep -q "2606:2800:220:1:248:1893:25c8:1946" $d2/tinc-up.invitation -fgrep -q "1234::" $d2/tinc-up.invitation && exit 1 - -# Check that no tinc-up is created and that tinc-up.invitation is not executable - -test -x $d2/tinc-up.invitation && exit 1 -test -f $d2/tinc-up && exit 1 - -$tinc $c1 stop diff --git a/test/legacy-protocol.test b/test/legacy-protocol.test deleted file mode 100755 index ce8e614..0000000 --- a/test/legacy-protocol.test +++ /dev/null @@ -1,79 +0,0 @@ -#!/bin/sh - -. "${0%/*}/testlib.sh" - -# Initialize two nodes - -$tinc $c1 <$d1/tinc-up <$d2/tinc-up <$d1/$script << EOF -#!/bin/sh -echo $script \$NETNAME,\$NAME,\$DEVICE,\$IFACE,\$NODE,\$REMOTEADDRESS,\$REMOTEPORT,\$SUBNET,\$WEIGHT,\$INVITATION_FILE,\$INVITATION_URL,\$DEBUG >>$OUT -EOF -chmod u+x $d1/$script -done - -# Start server node - -$tinc -n netname $c1 start $r1 - -echo foo-started >>$OUT - -# Invite client node - -url=`$tinc -n netname2 $c1 invite bar` -file=`cd $d1/invitations; ls | grep -v ed25519_key.priv` -echo bar-invited >>$OUT -$tinc -n netname3 $c2 join $url -echo bar-joined >>$OUT - -# Start and stop client node - -$tinc $c2 << EOF -set DeviceType dummy -set Port 32760 -add Subnet 10.0.0.2 -add Subnet fec0::/64#5 -start $r2 -EOF - -sleep 1 - -echo bar-started >>$OUT - -$tinc $c1 debug 4 -$tinc $c2 stop - -sleep 1 - -echo bar-stopped >>$OUT - -$tinc $c1 debug 5 -$tinc $c2 start $r2 - -sleep 1 - -echo bar-started >>$OUT - -# Stop server node - -$tinc $c1 stop -sleep 1 -$tinc $c2 stop - -# Check if the script output is what is expected - -cat >$OUT.expected << EOF -tinc-up netname,foo,dummy,,,,,,,,,5 -subnet-up netname,foo,dummy,,foo,,,10.0.0.1,,,,5 -subnet-up netname,foo,dummy,,foo,,,fec0::/64,,,,5 -foo-started -invitation-created netname2,foo,,,bar,,,,,$d1/invitations/$file,$url, -bar-invited -invitation-accepted netname,foo,dummy,,bar,127.0.0.1,,,,,,5 -bar-joined -host-up netname,foo,dummy,,bar,127.0.0.1,32760,,,,,5 -hosts/bar-up netname,foo,dummy,,bar,127.0.0.1,32760,,,,,5 -subnet-up netname,foo,dummy,,bar,127.0.0.1,32760,10.0.0.2,,,,5 -subnet-up netname,foo,dummy,,bar,127.0.0.1,32760,fec0::/64,5,,,5 -bar-started -host-down netname,foo,dummy,,bar,127.0.0.1,32760,,,,,4 -hosts/bar-down netname,foo,dummy,,bar,127.0.0.1,32760,,,,,4 -subnet-down netname,foo,dummy,,bar,127.0.0.1,32760,10.0.0.2,,,,4 -subnet-down netname,foo,dummy,,bar,127.0.0.1,32760,fec0::/64,5,,,4 -bar-stopped -host-up netname,foo,dummy,,bar,127.0.0.1,32760,,,,,5 -hosts/bar-up netname,foo,dummy,,bar,127.0.0.1,32760,,,,,5 -subnet-up netname,foo,dummy,,bar,127.0.0.1,32760,10.0.0.2,,,,5 -subnet-up netname,foo,dummy,,bar,127.0.0.1,32760,fec0::/64,5,,,5 -bar-started -host-down netname,foo,dummy,,bar,127.0.0.1,32760,,,,,5 -hosts/bar-down netname,foo,dummy,,bar,127.0.0.1,32760,,,,,5 -subnet-down netname,foo,dummy,,bar,127.0.0.1,32760,10.0.0.2,,,,5 -subnet-down netname,foo,dummy,,bar,127.0.0.1,32760,fec0::/64,5,,,5 -subnet-down netname,foo,dummy,,foo,,,10.0.0.1,,,,5 -subnet-down netname,foo,dummy,,foo,,,fec0::/64,,,,5 -tinc-down netname,foo,dummy,,,,,,,,,5 -EOF - -cmp $OUT $OUT.expected diff --git a/test/security.test b/test/security.test deleted file mode 100755 index 91d29e2..0000000 --- a/test/security.test +++ /dev/null @@ -1,98 +0,0 @@ -#!/bin/sh - -. "${0%/*}/testlib.sh" - -# Skip this test if tools are missing - -which socket >/dev/null || exit 77 -which timeout >/dev/null || exit 77 - -# Initialize two nodes - -$tinc $c1 < - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include -#include -#include -#include -#include -#include -#include - -#ifdef HAVE_MINGW -extern const char *winerror(int); -#define strerror(x) ((x)>0?strerror(x):winerror(GetLastError())) -#define sockerrno WSAGetLastError() -#define sockstrerror(x) winerror(x) -#else -#define sockerrno errno -#define sockstrerror(x) strerror(x) -#endif - -int main(int argc, char *argv[]) { - if(argc < 7) { - fprintf(stderr, "Usage: %s name1 host1 port1 name2 host2 port2 [protocol]\n", argv[0]); - return 1; - } - - const char *protocol; - - if(argc >= 8) { - protocol = argv[7]; - } else { - protocol = "17.7"; - } - -#ifdef HAVE_MINGW - static struct WSAData wsa_state; - - if(WSAStartup(MAKEWORD(2, 2), &wsa_state)) { - return 1; - } - -#endif - int sock[2]; - char buf[1024]; - - struct addrinfo *ai, hint; - memset(&hint, 0, sizeof(hint)); - - hint.ai_family = AF_UNSPEC; - hint.ai_socktype = SOCK_STREAM; - hint.ai_protocol = IPPROTO_TCP; - hint.ai_flags = 0; - - for (int i = 0; i < 2; i++) { - if(getaddrinfo(argv[2 + 3 * i], argv[3 + 3 * i], &hint, &ai) || !ai) { - fprintf(stderr, "getaddrinfo() failed: %s\n", sockstrerror(sockerrno)); - return 1; - } - - sock[i] = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); - - if(sock[i] == -1) { - fprintf(stderr, "Could not create socket: %s\n", sockstrerror(sockerrno)); - return 1; - } - - if(connect(sock[i], ai->ai_addr, ai->ai_addrlen)) { - fprintf(stderr, "Could not connect to %s: %s\n", argv[i + 3 * i], sockstrerror(sockerrno)); - return 1; - } - - fprintf(stderr, "Connected to %s\n", argv[1 + 3 * i]); - - /* Pretend to be the other one */ - int len = snprintf(buf, sizeof buf, "0 %s %s\n", argv[4 - 3 * i], protocol); - if (send(sock[i], buf, len, 0) != len) { - fprintf(stderr, "Error sending data to %s: %s\n", argv[1 + 3 * i], sockstrerror(sockerrno)); - return 1; - } - - /* Ignore the response */ - do { - if (recv(sock[i], buf, 1, 0) != 1) { - fprintf(stderr, "Error reading data from %s: %s\n", argv[1 + 3 * i], sockstrerror(sockerrno)); - return 1; - } - } while(*buf != '\n'); - } - - fprintf(stderr, "Splicing...\n"); - - int nfds = (sock[0] > sock[1] ? sock[0] : sock[1]) + 1; - - while(true) { - fd_set fds; - FD_ZERO(&fds); - FD_SET(sock[0], &fds); - FD_SET(sock[1], &fds); - - if(select(nfds, &fds, NULL, NULL, NULL) <= 0) { - return 1; - } - - for(int i = 0; i < 2; i++ ) { - if(FD_ISSET(sock[i], &fds)) { - ssize_t len = recv(sock[i], buf, sizeof buf, 0); - - if(len < 0) { - fprintf(stderr, "Error while reading from %s: %s\n", argv[1 + i * 3], sockstrerror(sockerrno)); - return 1; - } - - if(len == 0) { - fprintf(stderr, "Connection closed by %s\n", argv[1 + i * 3]); - return 0; - } - - if(send(sock[i ^ 1], buf, len, 0) != len) { - fprintf(stderr, "Error while writing to %s: %s\n", argv[4 - i * 3], sockstrerror(sockerrno)); - return 1; - } - } - } - } - - return 0; -} diff --git a/test/sptps-basic.test b/test/sptps-basic.test deleted file mode 100755 index b6d081f..0000000 --- a/test/sptps-basic.test +++ /dev/null @@ -1,32 +0,0 @@ -#!/bin/sh - -. "${0%/*}/testlib.sh" - -# Skip this test if we did not compile sptps_test - -test -e $sptps_test -a -e $sptps_keypair || exit 77 - -# Generate keys - -mkdir -p $d1 - -$sptps_keypair $d1/server.priv $d1/server.pub -$sptps_keypair $d1/client.priv $d1/client.pub - -# Test transfer of a simple file. - -(sleep 1; $sptps_test -4 -q $d1/client.priv $d1/server.pub localhost 32750 $d1/out1 -cmp $d1/out1 Makefile - -$sptps_test -4 -q $d1/server.priv $d1/client.pub 32750 $d1/out2 -cmp $d1/out2 Makefile - -# Datagram mode - -$sptps_test -4 -dq $d1/server.priv $d1/client.pub 32750 $d1/out3 -cmp $d1/out3 Makefile diff --git a/test/testlib.sh b/test/testlib.sh deleted file mode 100644 index 75b60a7..0000000 --- a/test/testlib.sh +++ /dev/null @@ -1,41 +0,0 @@ -#!/bin/sh - -# Paths to executables - -tincd=../src/tincd -tinc=../src/tinc -sptps_test=../src/sptps_test -sptps_keypair=../src/sptps_keypair - -# Test directories - -scriptname=`basename $0` -d1=$PWD/$scriptname.1 -d2=$PWD/$scriptname.2 -d3=$PWD/$scriptname.3 - -# Default arguments for both tinc and tincd - -c1="--config=$d1 --pidfile=$d1/pid" -c2="--config=$d2 --pidfile=$d2/pid" -c3="--config=$d3 --pidfile=$d3/pid" - -# Arguments when running tincd - -r1="--logfile=$d1/log -d5" -r2="--logfile=$d2/log -d5" -r3="--logfile=$d3/log -d5" - -# Check for leftover tinc daemons - -[ -f $d1/pid ] && $tinc $c1 stop -[ -f $d2/pid ] && $tinc $c2 stop -[ -f $d3/pid ] && $tinc $c3 stop - -# Remove test directories - -rm -rf $d1 $d2 $d3 - -# Exit on errors, log all commands being executed - -set -ex diff --git a/test/variables.test b/test/variables.test deleted file mode 100755 index f8656c9..0000000 --- a/test/variables.test +++ /dev/null @@ -1,86 +0,0 @@ -#!/bin/sh - -. "${0%/*}/testlib.sh" - -# Initialize one node - -$tinc $c1 init foo -test "`$tinc $c1 get Name`" = "foo" - -# Test case sensitivity - -$tinc $c1 set Mode switch -test "`$tinc $c1 get Mode`" = "switch" -test "`$tinc $c1 get mode`" = "switch" -$tinc $c1 set mode router -test "`$tinc $c1 get Mode`" = "router" -test "`$tinc $c1 get mode`" = "router" -$tinc $c1 set Mode Switch -test "`$tinc $c1 get Mode`" = "Switch" - -# Test deletion - -$tinc $c1 del Mode hub && exit 1 || true -$tinc $c1 del Mode switch -test -z "`$tinc $c1 get Mode`" - -# There can only be one Mode variable - -$tinc $c1 add Mode switch -$tinc $c1 add Mode hub -test "`$tinc $c1 get Mode`" = "hub" - -# Test addition/deletion of multivalued variables - -$tinc $c1 add Subnet 1 -$tinc $c1 add Subnet 2 -$tinc $c1 add Subnet 2 -$tinc $c1 add Subnet 3 -test "`$tinc $c1 get Subnet`" = "1 -2 -3" -$tinc $c1 del Subnet 2 -test "`$tinc $c1 get Subnet`" = "1 -3" -$tinc $c1 del Subnet -test -z "`$tinc $c1 get Subnet`" - -# We should not be able to get/set server variables using node.variable syntax - -test -z "`$tinc $c1 get foo.Name`" -$tinc $c1 set foo.Name bar && exit 1 || true - -# Test getting/setting host variables for other nodes - -touch $d1/hosts/bar - -$tinc $c1 add bar.PMTU 1 -$tinc $c1 add bar.PMTU 2 -test "`$tinc $c1 get bar.PMTU`" = "2" - -$tinc $c1 add bar.Subnet 1 -$tinc $c1 add bar.Subnet 2 -$tinc $c1 add bar.Subnet 2 -$tinc $c1 add bar.Subnet 3 -test "`$tinc $c1 get bar.Subnet`" = "1 -2 -3" -$tinc $c1 del bar.Subnet 2 -test "`$tinc $c1 get bar.Subnet`" = "1 -3" -$tinc $c1 del bar.Subnet -test -z "`$tinc $c1 get bar.Subnet`" - -# We should not be able to get/set for nodes with invalid names - -touch $d1/hosts/qu-ux - -$tinc $c1 set qu-ux.Subnet 1 && exit 1 || true - -# We should not be able to set obsolete variables unless forced - -$tinc $c1 set PrivateKey 12345 && exit 1 || true -$tinc $c1 --force set PrivateKey 12345 -test "`$tinc $c1 get PrivateKey`" = "12345" -$tinc $c1 del PrivateKey -test -z "`$tinc $c1 get PrivateKey`"